pptx-react-viewer 2.16.10 → 2.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/dist/{AiChatPanel-EPMBL6EA.js → AiChatPanel-HCHCVQN2.js} +24 -24
  3. package/dist/AiChatPanel-HCHCVQN2.js.br +0 -0
  4. package/dist/AiChatPanel-HCHCVQN2.js.gz +0 -0
  5. package/dist/{AiChatPanel-XHKYPYPH.mjs → AiChatPanel-RZ4A7P4H.mjs} +4 -4
  6. package/dist/AiChatPanel-RZ4A7P4H.mjs.br +0 -0
  7. package/dist/AiChatPanel-RZ4A7P4H.mjs.gz +0 -0
  8. package/dist/{Model3DScene-YMIAGRPG.mjs → Model3DScene-I7FR74AD.mjs} +1 -1
  9. package/dist/Model3DScene-I7FR74AD.mjs.br +0 -0
  10. package/dist/Model3DScene-I7FR74AD.mjs.gz +0 -0
  11. package/dist/{Model3DScene-DUJOZA2B.js → Model3DScene-LK7LSQNH.js} +2 -2
  12. package/dist/Model3DScene-LK7LSQNH.js.br +0 -0
  13. package/dist/Model3DScene-LK7LSQNH.js.gz +0 -0
  14. package/dist/PowerPointViewer-Du7u4INi.d.ts.map +1 -1
  15. package/dist/{SurfaceChart3DScene-Q47OEJXS.mjs → SurfaceChart3DScene-DEQP5O3U.mjs} +1 -1
  16. package/dist/SurfaceChart3DScene-DEQP5O3U.mjs.br +0 -0
  17. package/dist/SurfaceChart3DScene-DEQP5O3U.mjs.gz +0 -0
  18. package/dist/{SurfaceChart3DScene-TNCHWQAK.js → SurfaceChart3DScene-ODQY77SZ.js} +2 -2
  19. package/dist/SurfaceChart3DScene-ODQY77SZ.js.br +0 -0
  20. package/dist/SurfaceChart3DScene-ODQY77SZ.js.gz +0 -0
  21. package/dist/{chunk-G3VAE7ZF.mjs → chunk-422DF424.mjs} +729 -2294
  22. package/dist/chunk-422DF424.mjs.br +0 -0
  23. package/dist/chunk-422DF424.mjs.gz +0 -0
  24. package/dist/{chunk-WK22Z7PK.js → chunk-5BXATG54.js} +520 -868
  25. package/dist/chunk-5BXATG54.js.br +0 -0
  26. package/dist/chunk-5BXATG54.js.gz +0 -0
  27. package/dist/{chunk-Y2KIB3QH.js → chunk-7JPLVECA.js} +44829 -39322
  28. package/dist/chunk-7JPLVECA.js.br +0 -0
  29. package/dist/chunk-7JPLVECA.js.gz +0 -0
  30. package/dist/{chunk-DVZF4ARG.js → chunk-AONFHTTJ.js} +22 -0
  31. package/dist/chunk-AONFHTTJ.js.br +0 -0
  32. package/dist/chunk-AONFHTTJ.js.gz +0 -0
  33. package/dist/{chunk-PI5SFTDC.js → chunk-ATOUVRRQ.js} +3 -3
  34. package/dist/chunk-ATOUVRRQ.js.br +0 -0
  35. package/dist/chunk-ATOUVRRQ.js.gz +0 -0
  36. package/dist/{chunk-EL2YF26P.mjs → chunk-FXJOTEPO.mjs} +1 -1
  37. package/dist/chunk-FXJOTEPO.mjs.br +0 -0
  38. package/dist/chunk-FXJOTEPO.mjs.gz +0 -0
  39. package/dist/{chunk-YWKUIUQX.mjs → chunk-K2QU73KB.mjs} +44784 -39286
  40. package/dist/chunk-K2QU73KB.mjs.br +0 -0
  41. package/dist/chunk-K2QU73KB.mjs.gz +0 -0
  42. package/dist/{chunk-VHME5BE6.mjs → chunk-MQHC5TXI.mjs} +318 -665
  43. package/dist/chunk-MQHC5TXI.mjs.br +0 -0
  44. package/dist/chunk-MQHC5TXI.mjs.gz +0 -0
  45. package/dist/{chunk-ESC6IB2F.js → chunk-NQJPPIVH.js} +1668 -3233
  46. package/dist/chunk-NQJPPIVH.js.br +0 -0
  47. package/dist/chunk-NQJPPIVH.js.gz +0 -0
  48. package/dist/{chunk-5IUEPQTK.mjs → chunk-S64T7C4V.mjs} +22 -0
  49. package/dist/chunk-S64T7C4V.mjs.br +0 -0
  50. package/dist/chunk-S64T7C4V.mjs.gz +0 -0
  51. package/dist/{chunk-FSVE6WUY.js → chunk-TCGXGD6E.js} +550 -463
  52. package/dist/chunk-TCGXGD6E.js.br +0 -0
  53. package/dist/chunk-TCGXGD6E.js.gz +0 -0
  54. package/dist/{chunk-J7EFC3GS.mjs → chunk-ZA5JONCW.mjs} +210 -123
  55. package/dist/chunk-ZA5JONCW.mjs.br +0 -0
  56. package/dist/chunk-ZA5JONCW.mjs.gz +0 -0
  57. package/dist/i18n.js +4 -4
  58. package/dist/i18n.js.br +0 -0
  59. package/dist/i18n.js.gz +0 -0
  60. package/dist/i18n.mjs +1 -1
  61. package/dist/i18n.mjs.br +0 -0
  62. package/dist/i18n.mjs.gz +0 -0
  63. package/dist/index.d.ts +205 -21
  64. package/dist/index.js +41 -41
  65. package/dist/index.js.br +0 -0
  66. package/dist/index.js.gz +0 -0
  67. package/dist/index.mjs +6 -6
  68. package/dist/index.mjs.br +0 -0
  69. package/dist/index.mjs.gz +0 -0
  70. package/dist/internals.d.ts +380 -22
  71. package/dist/internals.d.ts.map +1 -1
  72. package/dist/internals.js +79 -79
  73. package/dist/internals.js.br +0 -0
  74. package/dist/internals.js.gz +0 -0
  75. package/dist/internals.mjs +4 -4
  76. package/dist/internals.mjs.br +0 -0
  77. package/dist/internals.mjs.gz +0 -0
  78. package/dist/pptx-viewer.css +1 -1
  79. package/dist/pptx-viewer.css.br +0 -0
  80. package/dist/pptx-viewer.css.gz +0 -0
  81. package/dist/{useViewerBuildingBlocks-Xddn6SFj.d.ts → useViewerBuildingBlocks-C9-prKYB.d.ts} +32 -6
  82. package/dist/useViewerBuildingBlocks-C9-prKYB.d.ts.map +1 -0
  83. package/dist/viewer/index.d.ts +166 -17
  84. package/dist/viewer/index.js +27 -27
  85. package/dist/viewer/index.js.br +0 -0
  86. package/dist/viewer/index.js.gz +0 -0
  87. package/dist/viewer/index.mjs +6 -6
  88. package/dist/viewer/index.mjs.br +0 -0
  89. package/dist/viewer/index.mjs.gz +0 -0
  90. package/package.json +1 -1
  91. package/dist/AiChatPanel-EPMBL6EA.js.br +0 -0
  92. package/dist/AiChatPanel-EPMBL6EA.js.gz +0 -0
  93. package/dist/AiChatPanel-XHKYPYPH.mjs.br +0 -0
  94. package/dist/AiChatPanel-XHKYPYPH.mjs.gz +0 -0
  95. package/dist/Model3DScene-DUJOZA2B.js.br +0 -0
  96. package/dist/Model3DScene-DUJOZA2B.js.gz +0 -0
  97. package/dist/Model3DScene-YMIAGRPG.mjs.br +0 -0
  98. package/dist/Model3DScene-YMIAGRPG.mjs.gz +0 -0
  99. package/dist/SurfaceChart3DScene-Q47OEJXS.mjs.br +0 -0
  100. package/dist/SurfaceChart3DScene-Q47OEJXS.mjs.gz +0 -0
  101. package/dist/SurfaceChart3DScene-TNCHWQAK.js.br +0 -0
  102. package/dist/SurfaceChart3DScene-TNCHWQAK.js.gz +0 -0
  103. package/dist/chunk-5IUEPQTK.mjs.br +0 -0
  104. package/dist/chunk-5IUEPQTK.mjs.gz +0 -0
  105. package/dist/chunk-DVZF4ARG.js.br +0 -0
  106. package/dist/chunk-DVZF4ARG.js.gz +0 -0
  107. package/dist/chunk-EL2YF26P.mjs.br +0 -0
  108. package/dist/chunk-EL2YF26P.mjs.gz +0 -0
  109. package/dist/chunk-ESC6IB2F.js.br +0 -0
  110. package/dist/chunk-ESC6IB2F.js.gz +0 -0
  111. package/dist/chunk-FSVE6WUY.js.br +0 -0
  112. package/dist/chunk-FSVE6WUY.js.gz +0 -0
  113. package/dist/chunk-G3VAE7ZF.mjs.br +0 -0
  114. package/dist/chunk-G3VAE7ZF.mjs.gz +0 -0
  115. package/dist/chunk-J7EFC3GS.mjs.br +0 -0
  116. package/dist/chunk-J7EFC3GS.mjs.gz +0 -0
  117. package/dist/chunk-PI5SFTDC.js.br +0 -0
  118. package/dist/chunk-PI5SFTDC.js.gz +0 -0
  119. package/dist/chunk-VHME5BE6.mjs.br +0 -0
  120. package/dist/chunk-VHME5BE6.mjs.gz +0 -0
  121. package/dist/chunk-WK22Z7PK.js.br +0 -0
  122. package/dist/chunk-WK22Z7PK.js.gz +0 -0
  123. package/dist/chunk-Y2KIB3QH.js.br +0 -0
  124. package/dist/chunk-Y2KIB3QH.js.gz +0 -0
  125. package/dist/chunk-YWKUIUQX.mjs.br +0 -0
  126. package/dist/chunk-YWKUIUQX.mjs.gz +0 -0
  127. package/dist/useViewerBuildingBlocks-Xddn6SFj.d.ts.map +0 -1
@@ -1640,7 +1640,28 @@ interface BulletInfo {
1640
1640
  autoNumType?: string;
1641
1641
  /** Auto-numbering start value. */
1642
1642
  autoNumStartAt?: number;
1643
- /** Zero-based paragraph index within the text body (for auto-numbering). */
1643
+ /**
1644
+ * Auto-numbering ORDINAL OFFSET: the zero-based distance of this paragraph
1645
+ * within its own numbered list, such that
1646
+ * `autoNumStartAt + paragraphIndex` is the ordinal to render. Despite the
1647
+ * name it is NOT the paragraph's position in the text body; the two agree
1648
+ * only for a list that starts at the first paragraph and is never
1649
+ * interrupted.
1650
+ *
1651
+ * It has to be the offset rather than the raw position because every
1652
+ * consumer that re-derives a marker from `BulletInfo` alone (the renderer's
1653
+ * `resolveParagraphBullet`, the Markdown converter's `resolveListMarker`)
1654
+ * computes `autoNumStartAt + paragraphIndex`. The load path resolves the
1655
+ * real sequence itself, restarting the count after any paragraph that
1656
+ * interrupts the list, and publishes the offset here so those consumers
1657
+ * land on the same number. With the raw position they did not, and BOTH
1658
+ * markers were painted ("3.1. Item"), because the paragraph builder drops
1659
+ * the parsed marker segment only when the two strings agree.
1660
+ *
1661
+ * Runtime-only: derived at parse time and never serialized. OOXML has no
1662
+ * counterpart (`a:buAutoNum` carries only `@type` and `@startAt`), so the
1663
+ * writer neither reads nor emits it.
1664
+ */
1644
1665
  paragraphIndex?: number;
1645
1666
  /** Bullet font family from `a:buFont`. */
1646
1667
  fontFamily?: string;
@@ -3935,6 +3956,11 @@ interface PptxTableCellStyle {
3935
3956
  italic?: boolean;
3936
3957
  underline?: boolean;
3937
3958
  color?: string;
3959
+ /**
3960
+ * Font family from the first run's `a:rPr/a:latin@typeface` (falling back to
3961
+ * `a:ea` / `a:cs`). Per-run families live on {@link PptxTableCellTextRun}.
3962
+ */
3963
+ fontFamily?: string;
3938
3964
  /**
3939
3965
  * Raw XML colour-choice node preserved from `a:tc/a:txBody/.../a:rPr/a:solidFill`
3940
3966
  * for round-trip serialisation. Currently unused by the cell-level writer
@@ -4090,6 +4116,45 @@ interface PptxTableCell3D {
4090
4116
  /** Light rig direction (`a:lightRig@dir`, e.g. `tl`, `t`, `tr`). */
4091
4117
  lightRigDirection?: string;
4092
4118
  }
4119
+ /**
4120
+ * One styled text run inside a table cell's `a:txBody`.
4121
+ *
4122
+ * `PptxTableCell.text` is a flat string and `PptxTableCell.style` describes
4123
+ * only the FIRST run, so a cell mixing formats ("Revenue **grew 42%** last
4124
+ * year") cannot be represented by those two alone. {@link PptxTableCell.runs}
4125
+ * carries the full sequence, with paragraph and line breaks as marker entries
4126
+ * so a renderer can walk it linearly.
4127
+ *
4128
+ * Structurally identical to `pptx-viewer-shared`'s `CellTextRun`, which every
4129
+ * binding's table renderer already consumes.
4130
+ *
4131
+ * @example
4132
+ * ```ts
4133
+ * const runs: PptxTableCellTextRun[] = [
4134
+ * { text: "Revenue " },
4135
+ * { text: "grew 42%", bold: true, color: "#C00000" },
4136
+ * ];
4137
+ * // => satisfies PptxTableCellTextRun[]
4138
+ * ```
4139
+ */
4140
+ interface PptxTableCellTextRun {
4141
+ /** Run text. Empty for the break markers below. */
4142
+ text: string;
4143
+ /** This entry starts a new paragraph (`a:p` boundary) rather than carrying text. */
4144
+ isParagraphBreak?: boolean;
4145
+ /** This entry is a soft line break (`a:br`) rather than carrying text. */
4146
+ isLineBreak?: boolean;
4147
+ bold?: boolean;
4148
+ italic?: boolean;
4149
+ underline?: boolean;
4150
+ strikethrough?: boolean;
4151
+ /** Resolved run colour as a CSS colour string. */
4152
+ color?: string;
4153
+ /** Run font size in points (`a:rPr@sz` / 100). */
4154
+ fontSize?: number;
4155
+ /** Run font family from `a:rPr/a:latin@typeface` (or `a:ea` / `a:cs`). */
4156
+ fontFamily?: string;
4157
+ }
4093
4158
  /**
4094
4159
  * A single table cell with text content, optional style, and merge info.
4095
4160
  *
@@ -4106,6 +4171,15 @@ interface PptxTableCell3D {
4106
4171
  interface PptxTableCell {
4107
4172
  text: string;
4108
4173
  style?: PptxTableCellStyle;
4174
+ /**
4175
+ * Per-run formatting for the cell's text, when it has any beyond what
4176
+ * {@link style} can express. Present only for cells whose `a:txBody`
4177
+ * actually carries runs; renderers fall back to {@link text} when absent.
4178
+ *
4179
+ * Editing a cell's text invalidates these (the editor produces a plain
4180
+ * string), so an edit path must clear them alongside setting `text`.
4181
+ */
4182
+ textRuns?: PptxTableCellTextRun[];
4109
4183
  /** Column span (defaults to 1). */
4110
4184
  gridSpan?: number;
4111
4185
  /** Row span (defaults to 1). */
@@ -4885,6 +4959,35 @@ interface UnknownPptxElement extends PptxElementBase {
4885
4959
  type PptxElement = TextPptxElement | ShapePptxElement | ConnectorPptxElement | ImagePptxElement | PicturePptxElement | TablePptxElement | ChartPptxElement | SmartArtPptxElement | OlePptxElement | MediaPptxElement | GroupPptxElement | InkPptxElement | ContentPartPptxElement | ZoomPptxElement | Model3DPptxElement | UnknownPptxElement;
4886
4960
  //#endregion
4887
4961
  //#region src/core/types/masters.d.ts
4962
+ /**
4963
+ * A placeholder slot declared on a master or layout.
4964
+ *
4965
+ * The geometry fields are in CSS pixels (EMU / {@link EMU_PER_PX}) and are only
4966
+ * present when the shape carried an explicit `a:xfrm`. Placeholders that
4967
+ * inherit their frame from the master leave them undefined, so consumers that
4968
+ * draw placeholder outlines (the layout gallery) must skip those entries
4969
+ * rather than assume a zero-sized box at the origin.
4970
+ *
4971
+ * @example
4972
+ * ```ts
4973
+ * const frame: PptxPlaceholderFrame = { type: "body", idx: "1", x: 63, y: 130 };
4974
+ * // => satisfies PptxPlaceholderFrame
4975
+ * ```
4976
+ */
4977
+ interface PptxPlaceholderFrame {
4978
+ /** `p:ph/@type`, lower-cased by the parser; defaults to `body` when omitted. */
4979
+ type: string;
4980
+ /** `p:ph/@idx`, when present. */
4981
+ idx?: string;
4982
+ /** Left offset in CSS pixels, when the shape declares `a:off`. */
4983
+ x?: number;
4984
+ /** Top offset in CSS pixels, when the shape declares `a:off`. */
4985
+ y?: number;
4986
+ /** Width in CSS pixels, when the shape declares `a:ext`. */
4987
+ width?: number;
4988
+ /** Height in CSS pixels, when the shape declares `a:ext`. */
4989
+ height?: number;
4990
+ }
4888
4991
  /**
4889
4992
  * Parsed notes master from `ppt/notesMasters/notesMaster1.xml`.
4890
4993
  *
@@ -4906,10 +5009,7 @@ interface PptxNotesMaster {
4906
5009
  /** Background image data URL. */
4907
5010
  backgroundImage?: string;
4908
5011
  /** Placeholder shapes found on the notes master. */
4909
- placeholders?: Array<{
4910
- type: string;
4911
- idx?: string;
4912
- }>;
5012
+ placeholders?: PptxPlaceholderFrame[];
4913
5013
  /** Editable elements on the notes master (header, footer, date, page number, slide image, notes body). */
4914
5014
  elements?: PptxElement[];
4915
5015
  /** Header/footer flags from `<p:hf>` on the notes master (P-H3). */
@@ -4937,10 +5037,7 @@ interface PptxHandoutMaster {
4937
5037
  /** Background image data URL. */
4938
5038
  backgroundImage?: string;
4939
5039
  /** Placeholder shapes found on the handout master. */
4940
- placeholders?: Array<{
4941
- type: string;
4942
- idx?: string;
4943
- }>;
5040
+ placeholders?: PptxPlaceholderFrame[];
4944
5041
  /** Editable elements on the handout master (header, footer, date, page number, slide placeholders). */
4945
5042
  elements?: PptxElement[];
4946
5043
  /** Number of slides per page for handout print layout (1, 2, 3, 4, 6, or 9). */
@@ -4988,10 +5085,7 @@ interface PptxSlideMaster {
4988
5085
  /** Layout paths associated with this master. */
4989
5086
  layoutPaths?: string[];
4990
5087
  /** Placeholder shapes on the master. */
4991
- placeholders?: Array<{
4992
- type: string;
4993
- idx?: string;
4994
- }>;
5088
+ placeholders?: PptxPlaceholderFrame[];
4995
5089
  /** Parsed element shapes on the master slide (for master view rendering). */
4996
5090
  elements?: PptxElement[];
4997
5091
  /** Parsed slide layout objects associated with this master. */
@@ -5063,10 +5157,7 @@ interface PptxSlideLayout {
5063
5157
  /** Parsed element shapes on the layout. */
5064
5158
  elements?: PptxElement[];
5065
5159
  /** Placeholder shapes on the layout. */
5066
- placeholders?: Array<{
5067
- type: string;
5068
- idx?: string;
5069
- }>;
5160
+ placeholders?: PptxPlaceholderFrame[];
5070
5161
  /** Matching name attribute for layout identification (`@matchingName`). */
5071
5162
  matchingName?: string;
5072
5163
  /** Whether the layout is marked as preserved (prevent deletion, `@preserve`). */
@@ -5080,6 +5171,42 @@ interface PptxSlideLayout {
5080
5171
  /** Header/footer flags from `<p:hf>` on this layout (P-H3). */
5081
5172
  headerFooter?: PptxHeaderFooterFlags;
5082
5173
  }
5174
+ /**
5175
+ * Rendered content of a single layout, used to draw gallery thumbnails.
5176
+ *
5177
+ * Produced on demand rather than during load: materialising every layout's
5178
+ * artwork (and decoding its images) up front costs a noticeable amount of time
5179
+ * on decks with many masters, and most sessions never open the layout gallery
5180
+ * at all.
5181
+ *
5182
+ * @example
5183
+ * ```ts
5184
+ * const preview: PptxLayoutPreview = {
5185
+ * path: "ppt/slideLayouts/slideLayout2.xml",
5186
+ * width: 960,
5187
+ * height: 540,
5188
+ * elements: [],
5189
+ * placeholders: [{ type: "title" }],
5190
+ * };
5191
+ * // => satisfies PptxLayoutPreview
5192
+ * ```
5193
+ */
5194
+ interface PptxLayoutPreview {
5195
+ /** ZIP path of the layout this preview belongs to. */
5196
+ path: string;
5197
+ /** Slide width in CSS pixels, so a thumbnail can compute its own scale. */
5198
+ width: number;
5199
+ /** Slide height in CSS pixels. */
5200
+ height: number;
5201
+ /** Background resolved from the layout, falling back to its master's. */
5202
+ backgroundColor?: string;
5203
+ /** Background image data URL, when the layout or master declares one. */
5204
+ backgroundImage?: string;
5205
+ /** The layout's own artwork (pictures, shapes and static text). */
5206
+ elements: PptxElement[];
5207
+ /** Placeholder slots, drawn as outlined frames in the gallery. */
5208
+ placeholders: PptxPlaceholderFrame[];
5209
+ }
5083
5210
  /**
5084
5211
  * A theme part available in the presentation package.
5085
5212
  *
@@ -7699,6 +7826,8 @@ interface IPptxHandlerRuntime {
7699
7826
  revokeBlobUrls(): void;
7700
7827
  getCompatibilityWarnings(): PptxCompatibilityWarning[];
7701
7828
  getLayoutOptions(): PptxLayoutOption[];
7829
+ getLayoutPreview(layoutPath: string): Promise<PptxLayoutPreview | null>;
7830
+ getLayoutPreviews(layoutPaths?: readonly string[]): Promise<PptxLayoutPreview[]>;
7702
7831
  createXmlBuilder(data: PptxData): PptxXmlBuilder;
7703
7832
  Builder(data: PptxData): PptxXmlBuilder;
7704
7833
  setTemplateBackground(path: string, backgroundColor: string | undefined): void;
@@ -7887,6 +8016,26 @@ declare class PptxHandlerCore {
7887
8016
  * @returns Array of {@link PptxLayoutOption} entries.
7888
8017
  */
7889
8018
  getLayoutOptions(): PptxLayoutOption[];
8019
+ /**
8020
+ * Build the artwork thumbnails backing the New Slide / Layout galleries.
8021
+ *
8022
+ * Parsing happens on first request and is memoised afterwards, so opening
8023
+ * the gallery costs one pass over the layout parts and reopening it costs
8024
+ * nothing. Callers that only need one entry should prefer
8025
+ * {@link getLayoutPreview}.
8026
+ *
8027
+ * @param layoutPaths - Restrict the result to these layouts; defaults to
8028
+ * every layout in the presentation.
8029
+ * @returns One {@link PptxLayoutPreview} per resolvable layout.
8030
+ */
8031
+ getLayoutPreviews(layoutPaths?: readonly string[]): Promise<PptxLayoutPreview[]>;
8032
+ /**
8033
+ * Build the artwork thumbnail for a single layout.
8034
+ *
8035
+ * @param layoutPath - Archive path of the `p:sldLayout` part.
8036
+ * @returns The preview, or `null` when the presentation has no such layout.
8037
+ */
8038
+ getLayoutPreview(layoutPath: string): Promise<PptxLayoutPreview | null>;
7890
8039
  /**
7891
8040
  * Create a fluent XML builder scoped to the given presentation data.
7892
8041
  *
@@ -8900,6 +9049,34 @@ interface ElementClipboardPayload {
8900
9049
  element: PptxElement;
8901
9050
  isTemplate: boolean;
8902
9051
  }
9052
+ /** What the "Embed fonts in the file" toggle should look like and do. */
9053
+ interface FontEmbeddingDescriptor {
9054
+ /** Distinct typeface names the loaded deck currently embeds. */
9055
+ embeddedFamilies: string[];
9056
+ /**
9057
+ * Whether the toggle accepts input. False when the deck embeds nothing,
9058
+ * because turning it on could not produce an embedded font.
9059
+ */
9060
+ interactive: boolean;
9061
+ /**
9062
+ * The position the toggle must START in so that it describes the file that
9063
+ * would be written right now. A deck that arrived with embedded fonts keeps
9064
+ * them on save, so the switch has to read "on" from the outset; the previous
9065
+ * hardcoded `false` said the opposite of what save actually did.
9066
+ */
9067
+ initialEnabled: boolean;
9068
+ /** Present only when `interactive` is false. */
9069
+ disabledReasonKey?: string;
9070
+ }
9071
+ //#endregion
9072
+ //#region src/render/master-view.d.ts
9073
+ /** Which part the master view is currently pointed at. */
9074
+ interface MasterViewTarget {
9075
+ tab: MasterViewTab;
9076
+ masterIndex: number;
9077
+ /** `null` selects the master itself rather than one of its layouts. */
9078
+ layoutIndex: number | null;
9079
+ }
8903
9080
  //#endregion
8904
9081
  //#region src/render/virtualized-list.d.ts
8905
9082
  /** Framework-neutral virtual-list range used by every thumbnail sidebar. */
@@ -8915,6 +9092,51 @@ interface VirtualizedRange {
8915
9092
  }
8916
9093
  /** Compute the rendered item window for fixed-height virtual lists. */
8917
9094
  declare function computeVirtualRange(totalItems: number, itemHeight: number, scrollTop: number, viewportHeight: number, overscan?: number): VirtualizedRange;
9095
+ /**
9096
+ * Why the deck is being serialised, which is a separate question from whether
9097
+ * the user protected it.
9098
+ *
9099
+ * - `user-file` (the default): the bytes leave the viewer as a file. Save,
9100
+ * Save As, Export, the host-facing `getContent()`. Protection applies.
9101
+ * - `recovery-snapshot`: the bytes exist only so the viewer can read them back.
9102
+ * The autosave crash-recovery snapshot in IndexedDB, and the internal
9103
+ * re-serialise-then-reload cycle behind "apply theme". Protection does NOT
9104
+ * apply: these are always written in the clear.
9105
+ *
9106
+ * ## Why a recovery snapshot must stay plaintext
9107
+ *
9108
+ * Nothing that reads a snapshot back has a password to give it.
9109
+ * `readBackstageRecentFile`, `restoreSessionDeck` and the Version History
9110
+ * panel's Restore all hand `record.data` straight to `PptxHandler.load()` with
9111
+ * no `password` option, and an encrypted package refuses to open without one
9112
+ * (`EncryptedFileError`). So an encrypted snapshot is not an inconvenience, it
9113
+ * is unreadable: the moment the user turns on protection their crash-recovery
9114
+ * data is silently destroyed, which is the exact opposite of what autosave is
9115
+ * for.
9116
+ *
9117
+ * Encrypting it "properly" is not available either. Decrypting on recovery
9118
+ * means the key has to outlive the crash the snapshot exists for, so it would
9119
+ * have to sit in the same IndexedDB / localStorage as the snapshot itself,
9120
+ * next to the ciphertext it unlocks. That is not a security boundary, it is
9121
+ * theatre. Prompting the user instead only works if they remember the password
9122
+ * of a deck they lost, which is precisely the moment they will not.
9123
+ *
9124
+ * ## The tradeoff this accepts (deliberately, not by omission)
9125
+ *
9126
+ * A password-protected deck DOES leave its content in cleartext at rest in the
9127
+ * origin's IndexedDB. Anyone with the browser profile, or any script running on
9128
+ * the origin, can read it. What limits the exposure: snapshots are scoped to
9129
+ * the origin and profile, aged out by the store, and clearable from
9130
+ * File > Account > Storage & Privacy (`clearLocalStorageData`). A user who
9131
+ * cannot accept plaintext at rest should switch AutoSave off, which stops the
9132
+ * snapshot being written at all.
9133
+ *
9134
+ * The rejected alternative was "skip autosave entirely while a password is
9135
+ * set". It removes the plaintext, but it also removes crash recovery without
9136
+ * telling anyone, so a crash loses the whole editing session. Losing data
9137
+ * quietly is the failure mode we are fixing, not a fix for it.
9138
+ */
9139
+ type DeckSavePurpose = 'user-file' | 'recovery-snapshot';
8918
9140
  //#endregion
8919
9141
  //#region src/render/toolbar-actions.d.ts
8920
9142
  /**
@@ -8970,6 +9192,15 @@ interface ViewerGeneralOptions {
8970
9192
  userName: string;
8971
9193
  userInitials: string;
8972
9194
  showStartScreen: boolean;
9195
+ /**
9196
+ * Lets the user hand a local font file to the viewer so decks authored
9197
+ * with a font the browser lacks render with the real face.
9198
+ *
9199
+ * Off by default. The registration reads a file the user picks and adds it
9200
+ * to the page's font set for the session, which is a capability a host
9201
+ * embedding the viewer should opt into rather than inherit.
9202
+ */
9203
+ enableCustomFontUpload: boolean;
8973
9204
  }
8974
9205
  interface ViewerProofingOptions {
8975
9206
  autoCorrectTwoInitialCapitals: boolean;
@@ -9497,10 +9728,20 @@ interface ToolbarProps {
9497
9728
  onTransformTextCase: (mode: ChangeCaseMode) => void;
9498
9729
  isOverflowMenuOpen: boolean;
9499
9730
  onSetOverflowMenuOpen: (open: boolean) => void;
9500
- layoutOptions: Array<{
9501
- path: string;
9502
- name: string;
9503
- }>;
9731
+ layoutOptions: PptxLayoutOption[];
9732
+ /** `layoutPath` of the active slide, marking the current gallery tile. */
9733
+ currentLayoutPath?: string;
9734
+ /** Supplies gallery artwork; without it the menus stay name-only. */
9735
+ loadLayoutPreviews?: () => Promise<PptxLayoutPreview[]>;
9736
+ /** Theme major/minor latin faces, leading the font dropdown. */
9737
+ themeFonts?: {
9738
+ heading?: string;
9739
+ body?: string;
9740
+ };
9741
+ /** Families the deck embeds, offered as their own dropdown group. */
9742
+ embeddedFontFamilies?: readonly string[];
9743
+ /** Families registered this session via File > Options > Fonts. */
9744
+ customFontFamilies?: readonly string[];
9504
9745
  onInsertSlideFromLayout: (path: string, name?: string) => void;
9505
9746
  /** Re-map the active slide onto another of its master's layouts. */
9506
9747
  onApplyLayout?: (path: string) => void;
@@ -9552,6 +9793,22 @@ interface ToolbarProps {
9552
9793
  activeSlide?: PptxSlide;
9553
9794
  onTransitionChange: (updates: Partial<PptxSlideTransition>) => void;
9554
9795
  onApplyTransitionToAll: () => void;
9796
+ /**
9797
+ * Home > Slides > Reset: re-apply the active slide's own layout, restoring
9798
+ * inherited placeholder geometry. Undeclared until now, which is why
9799
+ * `SlidesGroup` bound `undefined` and the button did nothing.
9800
+ */
9801
+ onResetSlide?: () => void;
9802
+ /** Home > Slides > Section: start a new section at the active slide. */
9803
+ onAddSection?: () => void;
9804
+ /** Home > Editing > Select > Select All (every element on the active slide). */
9805
+ onSelectAll?: () => void;
9806
+ /**
9807
+ * Slide Show > Options: what the four checkboxes read, and how a tick is
9808
+ * committed. See shared `ribbon-slide-show-options`.
9809
+ */
9810
+ presentationProperties?: PptxPresentationProperties;
9811
+ onPresentationPropertiesChange?: (updates: Partial<PptxPresentationProperties>) => void;
9555
9812
  /** Host-supplied list of toolbar buttons/ribbon tabs to hide. See `PowerPointViewerProps.hiddenActions`. */
9556
9813
  hiddenActions?: readonly ToolbarActionId[];
9557
9814
  /** Whether the AI assistant is available (the host passed the `ai` prop). */
@@ -10192,6 +10449,18 @@ interface EditorHistoryInput {
10192
10449
  maxHistoryEntries?: number;
10193
10450
  hasActivePointerInteraction: () => boolean;
10194
10451
  pointerCommitNonce: number;
10452
+ /**
10453
+ * Raised whenever a local edit is committed, i.e. exactly when this hook
10454
+ * learns the deck has diverged from what was last loaded or saved.
10455
+ *
10456
+ * This is what drives `state.isDirty`, and through it the status bar, the
10457
+ * host's `onDirtyChange` (the demos hang their "* filename" title marker off
10458
+ * it) and - critically - `useAutosave`, which short-circuits on a clean
10459
+ * document. Before this existed, `isDirty` was raised only by a few
10460
+ * master-view and document-property paths, so an element nudge, Home > New
10461
+ * Slide or a notes edit left the flag false and crash recovery never ran.
10462
+ */
10463
+ onDirty?: () => void;
10195
10464
  setSlides: (slides: PptxSlide[]) => void;
10196
10465
  setCanvasSize: (size: CanvasSize) => void;
10197
10466
  setActiveSlideIndex: (index: number) => void;
@@ -11007,6 +11276,25 @@ interface UseLoadContentResult {
11007
11276
  declare function useLoadContent({ content, clearSelection, history, setSlides, setTemplateElementsBySlideId, mediaDataUrls, setCanvasSize, setHeaderFooter, setLayoutOptions, setSlideMasters, setTheme, setTableStyleMap, setThemeOptions, setCustomShows, setSections, setPresentationProperties, setNotesMaster, setHandoutMaster, setNotesCanvasSize, setCustomProperties, setTagCollections, setCoreProperties, setAppProperties, setEmbeddedFonts, setActiveSlideIndex, setHasMacros, setHasDigitalSignatures, setDigitalSignatureCount, setGuides, setLoading, setError, setIsDirty, setIsEncrypted, onContentApplied }: UseLoadContentInput): UseLoadContentResult;
11008
11277
  //#endregion
11009
11278
  //#region src/viewer/hooks/useElementOperations.d.ts
11279
+ /**
11280
+ * View > Slide Master routing.
11281
+ *
11282
+ * The master view paints a part that is not in `slides`, so an edit made
11283
+ * there has to be written back into the master / layout / notes / handout
11284
+ * model instead. React previously keyed a pseudo-slide on the master's
11285
+ * archive path and pushed edits into `templateElementsBySlideId`, where
11286
+ * `buildSaveSlides` looks parts up by real slide id and so never found them:
11287
+ * the change showed on screen and vanished on save.
11288
+ */
11289
+ interface MasterViewRouting {
11290
+ target: MasterViewTarget | null;
11291
+ slideMasters: PptxSlideMaster[];
11292
+ notesMaster: PptxNotesMaster | undefined;
11293
+ handoutMaster: PptxHandoutMaster | undefined;
11294
+ setSlideMasters: React.Dispatch<React.SetStateAction<PptxSlideMaster[]>>;
11295
+ setNotesMaster: React.Dispatch<React.SetStateAction<PptxNotesMaster | undefined>>;
11296
+ setHandoutMaster: React.Dispatch<React.SetStateAction<PptxHandoutMaster | undefined>>;
11297
+ }
11010
11298
  interface UseElementOperationsInput {
11011
11299
  slides: PptxSlide[];
11012
11300
  activeSlide: PptxSlide | undefined;
@@ -11017,6 +11305,8 @@ interface UseElementOperationsInput {
11017
11305
  editTemplateMode: boolean;
11018
11306
  /** Template (master/layout) elements for the active slide. */
11019
11307
  templateElements: PptxElement[];
11308
+ /** Set while View > Slide Master is open; routes writes to the master part. */
11309
+ masterView?: MasterViewRouting | undefined;
11020
11310
  history: EditorHistoryResult;
11021
11311
  setSlides: React.Dispatch<React.SetStateAction<PptxSlide[]>>;
11022
11312
  setTemplateElementsBySlideId: React.Dispatch<React.SetStateAction<Record<string, PptxElement[]>>>;
@@ -11610,6 +11900,12 @@ interface UseViewerDialogsInput {
11610
11900
  isDirty: boolean;
11611
11901
  /** Editor history instance (used for markDirty on settings changes). */
11612
11902
  history: EditorHistoryResult;
11903
+ /**
11904
+ * Typeface names the loaded deck embeds (`p:embeddedFontLst`). Decides
11905
+ * whether the "Embed fonts" toggle can do anything, and which position it
11906
+ * starts in.
11907
+ */
11908
+ embeddedFontFamilies?: readonly string[];
11613
11909
  }
11614
11910
  /**
11615
11911
  * Output shape of the {@link useViewerDialogs} hook.
@@ -11656,9 +11952,15 @@ interface ViewerDialogsResult {
11656
11952
  /** OMML data for the equation currently being edited, or null. */
11657
11953
  editingEquationOmml: Record<string, unknown> | null;
11658
11954
  setEditingEquationOmml: React.Dispatch<React.SetStateAction<Record<string, unknown> | null>>;
11659
- /** Whether font embedding is enabled for save. */
11955
+ /**
11956
+ * Whether the saved file will carry the deck's embedded fonts. Read by
11957
+ * `useSerialize` via `embeddedFontSaveOptions`; false strips
11958
+ * `p:embeddedFontLst` and the `.fntdata` parts.
11959
+ */
11660
11960
  embedFontsEnabled: boolean;
11661
11961
  setEmbedFontsEnabled: React.Dispatch<React.SetStateAction<boolean>>;
11962
+ /** Whether the toggle can do anything on this deck, and why not when it cannot. */
11963
+ fontEmbedding: FontEmbeddingDescriptor;
11662
11964
  /** True when the container is narrower than 768px (triggers compact layout). */
11663
11965
  isNarrowViewport: boolean;
11664
11966
  /** Switches the viewer to master view mode, preserving the previous mode for restoration. */
@@ -11796,6 +12098,24 @@ interface UseSerializeInput {
11796
12098
  inlineEditingElementIdRef: React$1.MutableRefObject<string | null>;
11797
12099
  inlineEditingTextRef: React$1.MutableRefObject<string>;
11798
12100
  password?: string;
12101
+ /**
12102
+ * File > Fonts > "Embed fonts in the file". `false` passes
12103
+ * `embeddedFontList: null`, which strips `p:embeddedFontLst`, the `/font`
12104
+ * relationships and the `.fntdata` parts; `true` (the default) leaves core to
12105
+ * re-embed whatever the deck arrived with. Before this the toggle reached no
12106
+ * save call at all and the saved bytes were identical either way.
12107
+ */
12108
+ embedFonts?: boolean;
12109
+ /**
12110
+ * Why these bytes are being produced. Defaults to `'user-file'` (Save, Save
12111
+ * As, Export, the imperative `getContent()`), which honours `password`.
12112
+ * `'recovery-snapshot'` is for bytes the viewer reads back itself - the
12113
+ * autosave snapshot and the re-serialise-then-reload cycle - and is always
12114
+ * plaintext, because nothing on the way back in can supply the password.
12115
+ * See `deck-save-encryption` in `pptx-viewer-shared` for the full rationale
12116
+ * and the privacy tradeoff it accepts.
12117
+ */
12118
+ purpose?: DeckSavePurpose;
11799
12119
  }
11800
12120
  declare function useSerialize(input: UseSerializeInput): () => Promise<Uint8Array | null>;
11801
12121
  //#endregion
@@ -11899,6 +12219,12 @@ interface UseIOHandlersInput {
11899
12219
  };
11900
12220
  handlerRef: React$1.RefObject<PptxHandler | null>;
11901
12221
  serializeSlides: () => Promise<Uint8Array | null>;
12222
+ /**
12223
+ * Plaintext serialisation for bytes the viewer feeds straight back into its
12224
+ * own loader. "Apply theme" does exactly that, and the loader has no password
12225
+ * to offer, so it must never receive an encrypted package.
12226
+ */
12227
+ serializeForRecovery: () => Promise<Uint8Array | null>;
11902
12228
  setContent: React$1.Dispatch<React$1.SetStateAction<ArrayBuffer | Uint8Array | null>>;
11903
12229
  onContentChange: ((content: Uint8Array) => void) | undefined;
11904
12230
  password?: string;
@@ -11917,6 +12243,18 @@ interface UseContentLifecycleInput {
11917
12243
  filePath: string | undefined;
11918
12244
  /** AutoSave toggle state; when false the recovery autosave timer is off. */
11919
12245
  autosaveEnabled?: boolean;
12246
+ /**
12247
+ * AutoRecover cadence in seconds, from
12248
+ * `resolveAutosaveIntervalSeconds(File > Options > Save)`. React was the only
12249
+ * binding that never passed one (vanilla, svelte and angular all resolve it),
12250
+ * so the option's number field moved and the timer kept its 120s default.
12251
+ */
12252
+ autosaveIntervalSeconds?: number;
12253
+ /**
12254
+ * File > Fonts > "Embed fonts in the file". Forwarded to `useSerialize`, so
12255
+ * turning it off actually strips the embedded font data on the next save.
12256
+ */
12257
+ embedFonts?: boolean;
11920
12258
  slides: PptxSlide[];
11921
12259
  state: ViewerState;
11922
12260
  history: EditorHistoryResult;
@@ -11929,7 +12267,14 @@ interface UseContentLifecycleInput {
11929
12267
  }
11930
12268
  interface ContentLifecycleResult {
11931
12269
  handlerRef: React$1.RefObject<PptxHandler | null>;
12270
+ /** Serialise for the user: honours "Encrypt with Password". */
11932
12271
  serializeSlides: () => Promise<Uint8Array | null>;
12272
+ /**
12273
+ * Serialise for bytes the viewer reads back itself (autosave snapshot,
12274
+ * re-serialise-then-reload). Always plaintext, so recovery - which has no
12275
+ * password to offer - can actually open them.
12276
+ */
12277
+ serializeForRecovery: () => Promise<Uint8Array | null>;
11933
12278
  autosaveStatus: AutosaveStatus;
11934
12279
  }
11935
12280
  declare function useContentLifecycle(input: UseContentLifecycleInput): ContentLifecycleResult;
@@ -11962,6 +12307,11 @@ interface UseViewerIntegrationInput {
11962
12307
  filePath: string | undefined;
11963
12308
  /** AutoSave toggle state from the title bar. */
11964
12309
  autosaveEnabled: boolean;
12310
+ /**
12311
+ * AutoRecover cadence in seconds, resolved from File > Options > Save.
12312
+ * Optional: omitting it keeps `useAutosave`'s 120s default.
12313
+ */
12314
+ autosaveIntervalSeconds?: number;
11965
12315
  canEdit: boolean;
11966
12316
  mode: ViewerState['mode'];
11967
12317
  slides: PptxSlide[];
@@ -12101,6 +12451,14 @@ interface LayoutSwitchingResult {
12101
12451
  loadAvailableLayouts: () => Promise<void>;
12102
12452
  /** Apply a layout to the active slide by its archive path. */
12103
12453
  applyLayout: (layoutPath: string) => Promise<void>;
12454
+ /**
12455
+ * Build the artwork thumbnails the New Slide / Layout galleries draw.
12456
+ *
12457
+ * Deliberately a callback rather than state: parsing every layout is only
12458
+ * worth doing once the user opens one of those menus, and core memoises the
12459
+ * result so reopening costs nothing.
12460
+ */
12461
+ loadLayoutPreviews: () => Promise<PptxLayoutPreview[]>;
12104
12462
  /** The current slide's layout path (if known). */
12105
12463
  currentLayoutPath: string | undefined;
12106
12464
  }