pptx-react-viewer 2.16.10 → 2.18.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 (136) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/README.md +14 -14
  3. package/dist/{AiChatPanel-XHKYPYPH.mjs → AiChatPanel-SSSBERWJ.mjs} +4 -4
  4. package/dist/AiChatPanel-SSSBERWJ.mjs.br +0 -0
  5. package/dist/AiChatPanel-SSSBERWJ.mjs.gz +0 -0
  6. package/dist/{AiChatPanel-EPMBL6EA.js → AiChatPanel-UN5DHPZY.js} +24 -24
  7. package/dist/AiChatPanel-UN5DHPZY.js.br +0 -0
  8. package/dist/AiChatPanel-UN5DHPZY.js.gz +0 -0
  9. package/dist/{Model3DScene-DUJOZA2B.js → Model3DScene-4RPYKC2I.js} +2 -2
  10. package/dist/Model3DScene-4RPYKC2I.js.br +0 -0
  11. package/dist/Model3DScene-4RPYKC2I.js.gz +0 -0
  12. package/dist/{Model3DScene-YMIAGRPG.mjs → Model3DScene-LYEESYAI.mjs} +1 -1
  13. package/dist/Model3DScene-LYEESYAI.mjs.br +0 -0
  14. package/dist/Model3DScene-LYEESYAI.mjs.gz +0 -0
  15. package/dist/{PowerPointViewer-Du7u4INi.d.ts → PowerPointViewer-Cf4YHjdF.d.ts} +2 -2
  16. package/dist/PowerPointViewer-Cf4YHjdF.d.ts.map +1 -0
  17. package/dist/{SurfaceChart3DScene-TNCHWQAK.js → SurfaceChart3DScene-ACPKCWLJ.js} +2 -2
  18. package/dist/SurfaceChart3DScene-ACPKCWLJ.js.br +0 -0
  19. package/dist/SurfaceChart3DScene-ACPKCWLJ.js.gz +0 -0
  20. package/dist/{SurfaceChart3DScene-Q47OEJXS.mjs → SurfaceChart3DScene-JR62SOYO.mjs} +1 -1
  21. package/dist/SurfaceChart3DScene-JR62SOYO.mjs.br +0 -0
  22. package/dist/SurfaceChart3DScene-JR62SOYO.mjs.gz +0 -0
  23. package/dist/{audience-content-store-BvqKy7Hf.d.ts → audience-content-store-CyS0oP6t.d.ts} +2 -2
  24. package/dist/{audience-content-store-BvqKy7Hf.d.ts.map → audience-content-store-CyS0oP6t.d.ts.map} +1 -1
  25. package/dist/{chunk-WK22Z7PK.js → chunk-4LWGAVAP.js} +526 -928
  26. package/dist/chunk-4LWGAVAP.js.br +0 -0
  27. package/dist/chunk-4LWGAVAP.js.gz +0 -0
  28. package/dist/{chunk-EL2YF26P.mjs → chunk-7XF6S4AM.mjs} +1 -1
  29. package/dist/chunk-7XF6S4AM.mjs.br +0 -0
  30. package/dist/chunk-7XF6S4AM.mjs.gz +0 -0
  31. package/dist/{chunk-FSVE6WUY.js → chunk-ASKYZ5ZY.js} +728 -523
  32. package/dist/chunk-ASKYZ5ZY.js.br +0 -0
  33. package/dist/chunk-ASKYZ5ZY.js.gz +0 -0
  34. package/dist/{chunk-VHME5BE6.mjs → chunk-BZOL6FXF.mjs} +326 -728
  35. package/dist/chunk-BZOL6FXF.mjs.br +0 -0
  36. package/dist/chunk-BZOL6FXF.mjs.gz +0 -0
  37. package/dist/{chunk-YWKUIUQX.mjs → chunk-GODW6RNR.mjs} +87648 -78804
  38. package/dist/chunk-GODW6RNR.mjs.br +0 -0
  39. package/dist/chunk-GODW6RNR.mjs.gz +0 -0
  40. package/dist/{chunk-ESC6IB2F.js → chunk-ICZDMFF2.js} +2147 -3399
  41. package/dist/chunk-ICZDMFF2.js.br +0 -0
  42. package/dist/chunk-ICZDMFF2.js.gz +0 -0
  43. package/dist/{chunk-PI5SFTDC.js → chunk-MAVLV56S.js} +3 -3
  44. package/dist/chunk-MAVLV56S.js.br +0 -0
  45. package/dist/chunk-MAVLV56S.js.gz +0 -0
  46. package/dist/{chunk-G3VAE7ZF.mjs → chunk-O7FTUUXP.mjs} +1212 -2464
  47. package/dist/chunk-O7FTUUXP.mjs.br +0 -0
  48. package/dist/chunk-O7FTUUXP.mjs.gz +0 -0
  49. package/dist/{chunk-J7EFC3GS.mjs → chunk-QUB5OSKY.mjs} +394 -189
  50. package/dist/chunk-QUB5OSKY.mjs.br +0 -0
  51. package/dist/chunk-QUB5OSKY.mjs.gz +0 -0
  52. package/dist/{chunk-DVZF4ARG.js → chunk-RTUGI4HQ.js} +49 -4
  53. package/dist/chunk-RTUGI4HQ.js.br +0 -0
  54. package/dist/chunk-RTUGI4HQ.js.gz +0 -0
  55. package/dist/{chunk-5IUEPQTK.mjs → chunk-SNL6LBRX.mjs} +49 -4
  56. package/dist/chunk-SNL6LBRX.mjs.br +0 -0
  57. package/dist/chunk-SNL6LBRX.mjs.gz +0 -0
  58. package/dist/{chunk-Y2KIB3QH.js → chunk-WVDM36ZM.js} +87730 -78843
  59. package/dist/chunk-WVDM36ZM.js.br +0 -0
  60. package/dist/chunk-WVDM36ZM.js.gz +0 -0
  61. package/dist/i18n.js +4 -4
  62. package/dist/i18n.js.br +0 -0
  63. package/dist/i18n.js.gz +0 -0
  64. package/dist/i18n.mjs +1 -1
  65. package/dist/i18n.mjs.br +0 -0
  66. package/dist/i18n.mjs.gz +0 -0
  67. package/dist/index.d.ts +702 -37
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +65 -41
  70. package/dist/index.js.br +0 -0
  71. package/dist/index.js.gz +0 -0
  72. package/dist/index.mjs +6 -6
  73. package/dist/index.mjs.br +0 -0
  74. package/dist/index.mjs.gz +0 -0
  75. package/dist/internals.d.ts +923 -54
  76. package/dist/internals.d.ts.map +1 -1
  77. package/dist/internals.js +79 -79
  78. package/dist/internals.js.br +0 -0
  79. package/dist/internals.js.gz +0 -0
  80. package/dist/internals.mjs +4 -4
  81. package/dist/internals.mjs.br +0 -0
  82. package/dist/internals.mjs.gz +0 -0
  83. package/dist/pptx-viewer.css +1 -1
  84. package/dist/pptx-viewer.css.br +0 -0
  85. package/dist/pptx-viewer.css.gz +0 -0
  86. package/dist/{types-DU35aAJK.d.ts → types-C_CTI-QE.d.ts} +3 -31
  87. package/dist/types-C_CTI-QE.d.ts.map +1 -0
  88. package/dist/{useViewerBuildingBlocks-Xddn6SFj.d.ts → useViewerBuildingBlocks-DItilDbP.d.ts} +47 -8
  89. package/dist/useViewerBuildingBlocks-DItilDbP.d.ts.map +1 -0
  90. package/dist/viewer/index.d.ts +593 -56
  91. package/dist/viewer/index.js +27 -27
  92. package/dist/viewer/index.js.br +0 -0
  93. package/dist/viewer/index.js.gz +0 -0
  94. package/dist/viewer/index.mjs +6 -6
  95. package/dist/viewer/index.mjs.br +0 -0
  96. package/dist/viewer/index.mjs.gz +0 -0
  97. package/package.json +2 -2
  98. package/dist/AiChatPanel-EPMBL6EA.js.br +0 -0
  99. package/dist/AiChatPanel-EPMBL6EA.js.gz +0 -0
  100. package/dist/AiChatPanel-XHKYPYPH.mjs.br +0 -0
  101. package/dist/AiChatPanel-XHKYPYPH.mjs.gz +0 -0
  102. package/dist/Model3DScene-DUJOZA2B.js.br +0 -0
  103. package/dist/Model3DScene-DUJOZA2B.js.gz +0 -0
  104. package/dist/Model3DScene-YMIAGRPG.mjs.br +0 -0
  105. package/dist/Model3DScene-YMIAGRPG.mjs.gz +0 -0
  106. package/dist/PowerPointViewer-Du7u4INi.d.ts.map +0 -1
  107. package/dist/SurfaceChart3DScene-Q47OEJXS.mjs.br +0 -0
  108. package/dist/SurfaceChart3DScene-Q47OEJXS.mjs.gz +0 -0
  109. package/dist/SurfaceChart3DScene-TNCHWQAK.js.br +0 -0
  110. package/dist/SurfaceChart3DScene-TNCHWQAK.js.gz +0 -0
  111. package/dist/chunk-5IUEPQTK.mjs.br +0 -0
  112. package/dist/chunk-5IUEPQTK.mjs.gz +0 -0
  113. package/dist/chunk-DVZF4ARG.js.br +0 -0
  114. package/dist/chunk-DVZF4ARG.js.gz +0 -0
  115. package/dist/chunk-EL2YF26P.mjs.br +0 -0
  116. package/dist/chunk-EL2YF26P.mjs.gz +0 -0
  117. package/dist/chunk-ESC6IB2F.js.br +0 -0
  118. package/dist/chunk-ESC6IB2F.js.gz +0 -0
  119. package/dist/chunk-FSVE6WUY.js.br +0 -0
  120. package/dist/chunk-FSVE6WUY.js.gz +0 -0
  121. package/dist/chunk-G3VAE7ZF.mjs.br +0 -0
  122. package/dist/chunk-G3VAE7ZF.mjs.gz +0 -0
  123. package/dist/chunk-J7EFC3GS.mjs.br +0 -0
  124. package/dist/chunk-J7EFC3GS.mjs.gz +0 -0
  125. package/dist/chunk-PI5SFTDC.js.br +0 -0
  126. package/dist/chunk-PI5SFTDC.js.gz +0 -0
  127. package/dist/chunk-VHME5BE6.mjs.br +0 -0
  128. package/dist/chunk-VHME5BE6.mjs.gz +0 -0
  129. package/dist/chunk-WK22Z7PK.js.br +0 -0
  130. package/dist/chunk-WK22Z7PK.js.gz +0 -0
  131. package/dist/chunk-Y2KIB3QH.js.br +0 -0
  132. package/dist/chunk-Y2KIB3QH.js.gz +0 -0
  133. package/dist/chunk-YWKUIUQX.mjs.br +0 -0
  134. package/dist/chunk-YWKUIUQX.mjs.gz +0 -0
  135. package/dist/types-DU35aAJK.d.ts.map +0 -1
  136. package/dist/useViewerBuildingBlocks-Xddn6SFj.d.ts.map +0 -1
package/dist/index.d.ts CHANGED
@@ -1165,6 +1165,22 @@ interface ShapeStyle {
1165
1165
  fontRefIdx?: string;
1166
1166
  /** Raw XML colour child of `<a:fontRef>`. */
1167
1167
  fontRefColorXml?: XmlObject;
1168
+ /**
1169
+ * The fill `<a:fillRef>` resolved to, recorded ONLY when the shape's own
1170
+ * `spPr` authored no fill at all, so the reference is what paints it.
1171
+ *
1172
+ * Its absence therefore means "the fill is the shape's own", and its
1173
+ * presence plus an unchanged flat fill means "still purely inherited": see
1174
+ * `authored-shape-style.ts`, the shape-scope twin of `TextStyle`'s
1175
+ * `inheritedRunStyle`.
1176
+ */
1177
+ inheritedFillStyle?: ShapeStyle;
1178
+ /**
1179
+ * The outline `<a:lnRef>` resolved to, recorded before `spPr/a:ln` was
1180
+ * layered on top. A property that still equals this baseline was never
1181
+ * authored on the shape and must not be written back as if it were.
1182
+ */
1183
+ inheritedLineStyle?: ShapeStyle;
1168
1184
  }
1169
1185
  //#endregion
1170
1186
  //#region src/core/types/text.d.ts
@@ -1205,6 +1221,60 @@ interface ShapeStyle {
1205
1221
  interface TextStyle {
1206
1222
  /** Original `a:rPr` XML retained by projections that share the shape-text model. */
1207
1223
  runPropertiesXml?: XmlObject;
1224
+ /**
1225
+ * The properties this run's OWN `a:rPr` authored, and nothing else.
1226
+ *
1227
+ * A run style is assembled as
1228
+ * `{...inheritedRunStyle, ...authoredRunStyle}`, so the flat style is a
1229
+ * fully RESOLVED view: it cannot say whether `fontSize: 60` came from the
1230
+ * run, from the shape's `a:lstStyle`, from the layout placeholder, from the
1231
+ * master `p:txStyles` or from the theme. Omission is meaningful in OOXML
1232
+ * (§21.1.2.3), so a writer that re-emits the resolved view converts every
1233
+ * inherited value into an authored one and the deck stops being
1234
+ * theme-driven after one save.
1235
+ *
1236
+ * This is the run-scope twin of {@link TextSegment.paragraphProperties},
1237
+ * which is parsed strictly from the paragraph's own `a:pPr` for the same
1238
+ * reason. Present only for runs that came from a parsed deck; absent for
1239
+ * SDK-built text, where the flat style IS the only description and must be
1240
+ * written out in full.
1241
+ */
1242
+ authoredRunStyle?: TextStyle;
1243
+ /**
1244
+ * The resolved inheritance baseline {@link authoredRunStyle} was layered
1245
+ * on top of (shape `a:lstStyle` -> placeholder -> layout -> master
1246
+ * `p:txStyles` -> theme -> `p:defaultTextStyle`).
1247
+ *
1248
+ * Kept alongside the authored half because the two answer different
1249
+ * questions. The authored half says "the source pinned this"; the baseline
1250
+ * says "this value is what inheritance already produces", which is how an
1251
+ * EDIT is told apart from an inherited value: an editor mutates the flat
1252
+ * style without knowing about either field, so a property that now differs
1253
+ * from the baseline was either authored or edited and must be written,
1254
+ * while one that still matches can be left to inherit.
1255
+ *
1256
+ * Holds a reference to the per-paragraph baseline object rather than a
1257
+ * copy, so carrying it costs one pointer per run.
1258
+ */
1259
+ inheritedRunStyle?: TextStyle;
1260
+ /**
1261
+ * Snapshot of the ELEMENT-scope paragraph geometry (alignment, margins,
1262
+ * indent, line and paragraph spacing, tab stops, rtl, line-break flags) as
1263
+ * the load pipeline resolved it.
1264
+ *
1265
+ * Present only on an `element.textStyle` that came from a parsed deck, and
1266
+ * populated only with the geometry keys. It exists so the save path can
1267
+ * answer one question it otherwise cannot: has the user CHANGED the body's
1268
+ * alignment or indent, or is the value simply what the shape's
1269
+ * `a:lstStyle`, its layout placeholder and the master already produce?
1270
+ * Element-level text panels (`textAdvancedPatch`, `alignPatch` and friends
1271
+ * in `pptx-viewer-shared`) write `element.textStyle` and never touch
1272
+ * `segment.paragraphProperties`, so a diff against this snapshot is the
1273
+ * only way to tell an edit from an inheritance artefact.
1274
+ *
1275
+ * @see element-paragraph-geometry.ts
1276
+ */
1277
+ resolvedParagraphGeometry?: TextStyle;
1208
1278
  fontFamily?: string;
1209
1279
  fontSize?: number;
1210
1280
  /** When true, renderer should shrink text to fit the shape bounds. */
@@ -1660,7 +1730,28 @@ interface BulletInfo {
1660
1730
  autoNumType?: string;
1661
1731
  /** Auto-numbering start value. */
1662
1732
  autoNumStartAt?: number;
1663
- /** Zero-based paragraph index within the text body (for auto-numbering). */
1733
+ /**
1734
+ * Auto-numbering ORDINAL OFFSET: the zero-based distance of this paragraph
1735
+ * within its own numbered list, such that
1736
+ * `autoNumStartAt + paragraphIndex` is the ordinal to render. Despite the
1737
+ * name it is NOT the paragraph's position in the text body; the two agree
1738
+ * only for a list that starts at the first paragraph and is never
1739
+ * interrupted.
1740
+ *
1741
+ * It has to be the offset rather than the raw position because every
1742
+ * consumer that re-derives a marker from `BulletInfo` alone (the renderer's
1743
+ * `resolveParagraphBullet`, the Markdown converter's `resolveListMarker`)
1744
+ * computes `autoNumStartAt + paragraphIndex`. The load path resolves the
1745
+ * real sequence itself, restarting the count after any paragraph that
1746
+ * interrupts the list, and publishes the offset here so those consumers
1747
+ * land on the same number. With the raw position they did not, and BOTH
1748
+ * markers were painted ("3.1. Item"), because the paragraph builder drops
1749
+ * the parsed marker segment only when the two strings agree.
1750
+ *
1751
+ * Runtime-only: derived at parse time and never serialized. OOXML has no
1752
+ * counterpart (`a:buAutoNum` carries only `@type` and `@startAt`), so the
1753
+ * writer neither reads nor emits it.
1754
+ */
1664
1755
  paragraphIndex?: number;
1665
1756
  /** Bullet font family from `a:buFont`. */
1666
1757
  fontFamily?: string;
@@ -1848,6 +1939,15 @@ interface PptxElementBase {
1848
1939
  shapeId?: string;
1849
1940
  /** Element name from `cNvPr/@name`. Used for morph transition matching via the `!!` naming convention. */
1850
1941
  name?: string;
1942
+ /**
1943
+ * `p:nvSpPr/p:nvPr/p:ph/@type` (lower-cased) when the shape is a placeholder:
1944
+ * `title`, `ctrtitle`, `body`, `subtitle`, `ftr`, `dt`, `sldnum`, ...
1945
+ *
1946
+ * Captured on load so consumers can tell a footer placeholder from a text box
1947
+ * without re-walking `rawXml`. Absent on non-placeholder shapes and on
1948
+ * SDK-created elements.
1949
+ */
1950
+ placeholderType?: string;
1851
1951
  x: number;
1852
1952
  y: number;
1853
1953
  width: number;
@@ -1908,6 +2008,19 @@ interface PptxTextProperties {
1908
2008
  }>;
1909
2009
  /** Placeholder prompt text inherited from layout/master (e.g. "Click to add title"). Shown as a greyed-out hint when the shape has no user-entered text. */
1910
2010
  promptText?: string;
2011
+ /**
2012
+ * The string {@link text} was INHERITED from, when this is a header / footer /
2013
+ * date / slide-number placeholder whose own body the file leaves empty.
2014
+ *
2015
+ * PowerPoint keeps the footer string on the slide master and writes each
2016
+ * slide's copy of the `ftr` placeholder empty, so the empty body means
2017
+ * "render the master's footer here". Rendering needs the resolved string, but
2018
+ * SAVING it into the slide would pin that slide to today's master text and
2019
+ * silently detach it from the Header & Footer dialog. The save writer
2020
+ * therefore leaves the authored empty body alone while `text` still equals
2021
+ * this value, and writes a genuine per-slide override once it does not.
2022
+ */
2023
+ inheritedPlaceholderText?: string;
1911
2024
  /** Linked text box chain ID from `a:bodyPr > a:linkedTxbx/@id` or `a:txbx > a:linkedTxbx/@id`. Text overflows from one linked frame to the next. */
1912
2025
  linkedTxbxId?: number;
1913
2026
  /** Sequence number within a linked text box chain (0-based). */
@@ -2318,6 +2431,12 @@ interface PptxChartLineStyle {
2318
2431
  }
2319
2432
  /** Marker symbol types for line/scatter chart data points. */
2320
2433
  type PptxChartMarkerSymbol = 'circle' | 'dash' | 'diamond' | 'dot' | 'none' | 'picture' | 'plus' | 'square' | 'star' | 'triangle' | 'x' | 'auto';
2434
+ /**
2435
+ * `ST_ScatterStyle` (ECMA-376 §21.2.3.40): how a scatter chart joins its points.
2436
+ * `line`/`lineMarker` connect them with straight segments, `smooth`/
2437
+ * `smoothMarker` with a bezier, `marker`/`none` not at all.
2438
+ */
2439
+ type PptxChartScatterStyle = 'none' | 'line' | 'lineMarker' | 'marker' | 'smooth' | 'smoothMarker';
2321
2440
  /** Shape properties extracted from c:spPr for chart formatting. */
2322
2441
  interface PptxChartShapeProps {
2323
2442
  fillColor?: string;
@@ -2519,6 +2638,42 @@ interface PptxChartTreemapOptions {
2519
2638
  interface PptxChartSeries {
2520
2639
  name: string;
2521
2640
  values: number[];
2641
+ /**
2642
+ * Per-series x values from `c:ser/c:xVal` (scatter and bubble series only).
2643
+ *
2644
+ * Every `CT_ScatterSer` / `CT_BubbleSer` carries its OWN `c:xVal`, so two
2645
+ * series in one scatter chart routinely plot against different x ranges (the
2646
+ * normal case for measurement data). Reading the x values off the first
2647
+ * series and reusing them everywhere plotted every series against series 1's
2648
+ * x axis. Absent for category-axis chart kinds, where
2649
+ * {@link PptxChartData.categories} is the x axis.
2650
+ */
2651
+ xValues?: number[];
2652
+ /**
2653
+ * Per-series bubble sizes from `c:ser/c:bubbleSize` (bubble series only),
2654
+ * aligned index-for-index with {@link values}.
2655
+ *
2656
+ * `CT_BubbleSer` carries x, y AND size, so a one-series bubble chart is fully
2657
+ * specified. Absent when the source omits `c:bubbleSize`.
2658
+ */
2659
+ bubbleSizes?: number[];
2660
+ /**
2661
+ * Series-level data-label content flags from `c:ser/c:dLbls`.
2662
+ *
2663
+ * PowerPoint writes the flags a user picks in "Format Data Labels" onto the
2664
+ * SERIES, and leaves the chart-type-level `c:dLbls` all-zero, so reading only
2665
+ * the chart-level group reports "show nothing" for a chart that visibly shows
2666
+ * percentages. These override {@link PptxChartStyle.dataLabels}.
2667
+ */
2668
+ dataLabelOptions?: PptxChartDataLabelOptions;
2669
+ /**
2670
+ * Whether the series line is explicitly suppressed
2671
+ * (`c:ser/c:spPr/a:ln/a:noFill`). Line-drawn kinds (line, scatter, radar)
2672
+ * use this to decide whether to draw a connecting line at all; a marker-only
2673
+ * scatter is authored as `scatterStyle="lineMarker"` PLUS this flag, never by
2674
+ * changing the scatter style.
2675
+ */
2676
+ lineNoFill?: boolean;
2522
2677
  /**
2523
2678
  * Blank-value mask aligned index-for-index with {@link values}: `true` marks
2524
2679
  * a category whose numeric cache point (`c:numCache/c:pt`) was absent or
@@ -2862,6 +3017,17 @@ interface PptxChartData {
2862
3017
  * default), so only horizontal bar charts need to carry the field.
2863
3018
  */
2864
3019
  barDirection?: PptxChartBarDirection;
3020
+ /**
3021
+ * Scatter presentation mode (`c:scatterChart/c:scatterStyle/@val`).
3022
+ *
3023
+ * `lineMarker` (PowerPoint's own default for every scatter it writes) and
3024
+ * `smoothMarker` draw a connecting line; `marker` and `none` do not. Whether
3025
+ * the MARKERS appear is decided separately by `c:marker/c:symbol`, and
3026
+ * whether the LINE appears is further gated by
3027
+ * {@link PptxChartSeries.lineNoFill} - PowerPoint expresses "markers only" as
3028
+ * `lineMarker` plus an `a:ln/a:noFill`, not as `marker`.
3029
+ */
3030
+ scatterStyle?: PptxChartScatterStyle;
2865
3031
  /**
2866
3032
  * Bar/column gap between category clusters as a percentage of bar width
2867
3033
  * (`c:gapWidth/@val`, 0 through 500). Absent uses the renderer default.
@@ -3015,6 +3181,53 @@ interface PptxChartData {
3015
3181
  * // => { brightness: 20, contrast: -10, grayscale: true } satisfies PptxImageEffects
3016
3182
  * ```
3017
3183
  */
3184
+ /**
3185
+ * One `a14:foregroundMark` / `a14:backgroundMark` polyline hint recorded while
3186
+ * the user painted over the picture in PowerPoint's "Remove Background" mode.
3187
+ * Coordinates are 0..1 fractions of the image.
3188
+ */
3189
+ interface PptxBackgroundRemovalMark {
3190
+ x1: number;
3191
+ y1: number;
3192
+ x2: number;
3193
+ y2: number;
3194
+ }
3195
+ /**
3196
+ * PowerPoint "Remove Background" state (`a14:backgroundRemoval`).
3197
+ *
3198
+ * The four edges are the RETAINED rectangle as 0..1 fractions of the image
3199
+ * (OOXML stores them as per-100000 relative units), and the mark lists are the
3200
+ * segmentation hints the user painted.
3201
+ *
3202
+ * **This is edit-time metadata, not a render instruction.** PowerPoint bakes the
3203
+ * removal into the bitmap referenced by the main `a:blip/@r:embed` and keeps the
3204
+ * pristine original in `a14:imgLayer/@r:embed`. Verified against PowerPoint COM:
3205
+ * a slide exported with and without this element is byte-identical. A renderer
3206
+ * that clips to the retained rectangle would clip an image whose background has
3207
+ * already been removed.
3208
+ *
3209
+ * @example
3210
+ * ```ts
3211
+ * const removal: PptxBackgroundRemoval = { top: 0.12, bottom: 0.88, left: 0.07, right: 0.93 };
3212
+ * // => retains the middle of the image; the marks list stays empty
3213
+ * ```
3214
+ */
3215
+ interface PptxBackgroundRemoval {
3216
+ /** Top edge of the retained rectangle (0..1 fraction of the image height). */
3217
+ top: number;
3218
+ /** Bottom edge of the retained rectangle (0..1 fraction of the image height). */
3219
+ bottom: number;
3220
+ /** Left edge of the retained rectangle (0..1 fraction of the image width). */
3221
+ left: number;
3222
+ /** Right edge of the retained rectangle (0..1 fraction of the image width). */
3223
+ right: number;
3224
+ /** Strokes marking regions the user forced to be foreground. */
3225
+ foregroundMarks?: PptxBackgroundRemovalMark[];
3226
+ /** Strokes marking regions the user forced to be background. */
3227
+ backgroundMarks?: PptxBackgroundRemovalMark[];
3228
+ /** Original effect XML, retained for lossless re-emission. */
3229
+ rawXml?: XmlObject;
3230
+ }
3018
3231
  interface PptxImageEffects {
3019
3232
  /** Brightness adjustment (-100 to 100). */
3020
3233
  brightness?: number;
@@ -3038,8 +3251,38 @@ interface PptxImageEffects {
3038
3251
  };
3039
3252
  /** Artistic effect name (blur, pencilGrayscale, paintStrokes, etc.). */
3040
3253
  artisticEffect?: string;
3041
- /** Artistic effect radius/amount. */
3254
+ /** Artistic effect radius/amount, normalised to 0..100. */
3042
3255
  artisticRadius?: number;
3256
+ /**
3257
+ * Every numeric attribute of the source `a14:artistic*` element, raw and
3258
+ * un-normalised (`trans`, `pencilSize`, `crackSpacing`, …). The attribute set
3259
+ * differs per effect, so this is the lossless companion to the single
3260
+ * {@link PptxImageEffects.artisticRadius} number.
3261
+ */
3262
+ artisticParams?: Record<string, number>;
3263
+ /**
3264
+ * Name of the artistic effect ALREADY baked into the image data, which a
3265
+ * renderer must not apply a second time. Set from the `a14` blip extension,
3266
+ * which PowerPoint writes alongside a pre-rendered bitmap (see
3267
+ * {@link PptxBackgroundRemoval}), and normally equal to
3268
+ * {@link PptxImageEffects.artisticEffect}.
3269
+ *
3270
+ * It records the NAME rather than a boolean so that picking a different
3271
+ * effect in this library's inspector (which patches `artisticEffect` alone)
3272
+ * still renders: the two names then differ.
3273
+ */
3274
+ artisticPrerenderedEffect?: string;
3275
+ /**
3276
+ * PowerPoint "Remove Background" state (`a14:backgroundRemoval`). Edit-time
3277
+ * metadata: the removal is already baked into the image data.
3278
+ */
3279
+ backgroundRemoval?: PptxBackgroundRemoval;
3280
+ /**
3281
+ * `a14:imgLayer/@r:embed` — relationship id of the PRISTINE original image
3282
+ * the baked effects were derived from (PowerPoint stores it as an HD Photo
3283
+ * `.wdp` part, which browsers cannot decode).
3284
+ */
3285
+ originalImageRelId?: string;
3043
3286
  /** Alpha modulation fixed: non-negative percentage (100 means unchanged opacity). */
3044
3287
  alphaModFix?: number;
3045
3288
  /** Original alpha modulation fixed node, including foreign attributes. */
@@ -3955,6 +4198,11 @@ interface PptxTableCellStyle {
3955
4198
  italic?: boolean;
3956
4199
  underline?: boolean;
3957
4200
  color?: string;
4201
+ /**
4202
+ * Font family from the first run's `a:rPr/a:latin@typeface` (falling back to
4203
+ * `a:ea` / `a:cs`). Per-run families live on {@link PptxTableCellTextRun}.
4204
+ */
4205
+ fontFamily?: string;
3958
4206
  /**
3959
4207
  * Raw XML colour-choice node preserved from `a:tc/a:txBody/.../a:rPr/a:solidFill`
3960
4208
  * for round-trip serialisation. Currently unused by the cell-level writer
@@ -4110,6 +4358,45 @@ interface PptxTableCell3D {
4110
4358
  /** Light rig direction (`a:lightRig@dir`, e.g. `tl`, `t`, `tr`). */
4111
4359
  lightRigDirection?: string;
4112
4360
  }
4361
+ /**
4362
+ * One styled text run inside a table cell's `a:txBody`.
4363
+ *
4364
+ * `PptxTableCell.text` is a flat string and `PptxTableCell.style` describes
4365
+ * only the FIRST run, so a cell mixing formats ("Revenue **grew 42%** last
4366
+ * year") cannot be represented by those two alone. {@link PptxTableCell.runs}
4367
+ * carries the full sequence, with paragraph and line breaks as marker entries
4368
+ * so a renderer can walk it linearly.
4369
+ *
4370
+ * Structurally identical to `pptx-viewer-shared`'s `CellTextRun`, which every
4371
+ * binding's table renderer already consumes.
4372
+ *
4373
+ * @example
4374
+ * ```ts
4375
+ * const runs: PptxTableCellTextRun[] = [
4376
+ * { text: "Revenue " },
4377
+ * { text: "grew 42%", bold: true, color: "#C00000" },
4378
+ * ];
4379
+ * // => satisfies PptxTableCellTextRun[]
4380
+ * ```
4381
+ */
4382
+ interface PptxTableCellTextRun {
4383
+ /** Run text. Empty for the break markers below. */
4384
+ text: string;
4385
+ /** This entry starts a new paragraph (`a:p` boundary) rather than carrying text. */
4386
+ isParagraphBreak?: boolean;
4387
+ /** This entry is a soft line break (`a:br`) rather than carrying text. */
4388
+ isLineBreak?: boolean;
4389
+ bold?: boolean;
4390
+ italic?: boolean;
4391
+ underline?: boolean;
4392
+ strikethrough?: boolean;
4393
+ /** Resolved run colour as a CSS colour string. */
4394
+ color?: string;
4395
+ /** Run font size in points (`a:rPr@sz` / 100). */
4396
+ fontSize?: number;
4397
+ /** Run font family from `a:rPr/a:latin@typeface` (or `a:ea` / `a:cs`). */
4398
+ fontFamily?: string;
4399
+ }
4113
4400
  /**
4114
4401
  * A single table cell with text content, optional style, and merge info.
4115
4402
  *
@@ -4126,6 +4413,15 @@ interface PptxTableCell3D {
4126
4413
  interface PptxTableCell {
4127
4414
  text: string;
4128
4415
  style?: PptxTableCellStyle;
4416
+ /**
4417
+ * Per-run formatting for the cell's text, when it has any beyond what
4418
+ * {@link style} can express. Present only for cells whose `a:txBody`
4419
+ * actually carries runs; renderers fall back to {@link text} when absent.
4420
+ *
4421
+ * Editing a cell's text invalidates these (the editor produces a plain
4422
+ * string), so an edit path must clear them alongside setting `text`.
4423
+ */
4424
+ textRuns?: PptxTableCellTextRun[];
4129
4425
  /** Column span (defaults to 1). */
4130
4426
  gridSpan?: number;
4131
4427
  /** Row span (defaults to 1). */
@@ -4898,13 +5194,42 @@ interface UnknownPptxElement extends PptxElementBase {
4898
5194
  /**
4899
5195
  * A single element on a PPTX slide.
4900
5196
  *
4901
- * This is a **discriminated union** narrow on `element.type` to access
5197
+ * This is a **discriminated union**: narrow on `element.type` to access
4902
5198
  * variant-specific properties like `imageData` (image/picture), `pathData`
4903
5199
  * (shape), or `textSegments` (text/shape).
4904
5200
  */
4905
5201
  type PptxElement = TextPptxElement | ShapePptxElement | ConnectorPptxElement | ImagePptxElement | PicturePptxElement | TablePptxElement | ChartPptxElement | SmartArtPptxElement | OlePptxElement | MediaPptxElement | GroupPptxElement | InkPptxElement | ContentPartPptxElement | ZoomPptxElement | Model3DPptxElement | UnknownPptxElement;
4906
5202
  //#endregion
4907
5203
  //#region src/core/types/masters.d.ts
5204
+ /**
5205
+ * A placeholder slot declared on a master or layout.
5206
+ *
5207
+ * The geometry fields are in CSS pixels (EMU / {@link EMU_PER_PX}) and are only
5208
+ * present when the shape carried an explicit `a:xfrm`. Placeholders that
5209
+ * inherit their frame from the master leave them undefined, so consumers that
5210
+ * draw placeholder outlines (the layout gallery) must skip those entries
5211
+ * rather than assume a zero-sized box at the origin.
5212
+ *
5213
+ * @example
5214
+ * ```ts
5215
+ * const frame: PptxPlaceholderFrame = { type: "body", idx: "1", x: 63, y: 130 };
5216
+ * // => satisfies PptxPlaceholderFrame
5217
+ * ```
5218
+ */
5219
+ interface PptxPlaceholderFrame {
5220
+ /** `p:ph/@type`, lower-cased by the parser; defaults to `body` when omitted. */
5221
+ type: string;
5222
+ /** `p:ph/@idx`, when present. */
5223
+ idx?: string;
5224
+ /** Left offset in CSS pixels, when the shape declares `a:off`. */
5225
+ x?: number;
5226
+ /** Top offset in CSS pixels, when the shape declares `a:off`. */
5227
+ y?: number;
5228
+ /** Width in CSS pixels, when the shape declares `a:ext`. */
5229
+ width?: number;
5230
+ /** Height in CSS pixels, when the shape declares `a:ext`. */
5231
+ height?: number;
5232
+ }
4908
5233
  /**
4909
5234
  * Parsed notes master from `ppt/notesMasters/notesMaster1.xml`.
4910
5235
  *
@@ -4926,10 +5251,7 @@ interface PptxNotesMaster {
4926
5251
  /** Background image data URL. */
4927
5252
  backgroundImage?: string;
4928
5253
  /** Placeholder shapes found on the notes master. */
4929
- placeholders?: Array<{
4930
- type: string;
4931
- idx?: string;
4932
- }>;
5254
+ placeholders?: PptxPlaceholderFrame[];
4933
5255
  /** Editable elements on the notes master (header, footer, date, page number, slide image, notes body). */
4934
5256
  elements?: PptxElement[];
4935
5257
  /** Header/footer flags from `<p:hf>` on the notes master (P-H3). */
@@ -4957,10 +5279,7 @@ interface PptxHandoutMaster {
4957
5279
  /** Background image data URL. */
4958
5280
  backgroundImage?: string;
4959
5281
  /** Placeholder shapes found on the handout master. */
4960
- placeholders?: Array<{
4961
- type: string;
4962
- idx?: string;
4963
- }>;
5282
+ placeholders?: PptxPlaceholderFrame[];
4964
5283
  /** Editable elements on the handout master (header, footer, date, page number, slide placeholders). */
4965
5284
  elements?: PptxElement[];
4966
5285
  /** Number of slides per page for handout print layout (1, 2, 3, 4, 6, or 9). */
@@ -4998,10 +5317,7 @@ interface PptxSlideMaster {
4998
5317
  /** Layout paths associated with this master. */
4999
5318
  layoutPaths?: string[];
5000
5319
  /** Placeholder shapes on the master. */
5001
- placeholders?: Array<{
5002
- type: string;
5003
- idx?: string;
5004
- }>;
5320
+ placeholders?: PptxPlaceholderFrame[];
5005
5321
  /** Parsed element shapes on the master slide (for master view rendering). */
5006
5322
  elements?: PptxElement[];
5007
5323
  /** Parsed slide layout objects associated with this master. */
@@ -5073,10 +5389,7 @@ interface PptxSlideLayout {
5073
5389
  /** Parsed element shapes on the layout. */
5074
5390
  elements?: PptxElement[];
5075
5391
  /** Placeholder shapes on the layout. */
5076
- placeholders?: Array<{
5077
- type: string;
5078
- idx?: string;
5079
- }>;
5392
+ placeholders?: PptxPlaceholderFrame[];
5080
5393
  /** Matching name attribute for layout identification (`@matchingName`). */
5081
5394
  matchingName?: string;
5082
5395
  /** Whether the layout is marked as preserved (prevent deletion, `@preserve`). */
@@ -5090,6 +5403,42 @@ interface PptxSlideLayout {
5090
5403
  /** Header/footer flags from `<p:hf>` on this layout (P-H3). */
5091
5404
  headerFooter?: PptxHeaderFooterFlags;
5092
5405
  }
5406
+ /**
5407
+ * Rendered content of a single layout, used to draw gallery thumbnails.
5408
+ *
5409
+ * Produced on demand rather than during load: materialising every layout's
5410
+ * artwork (and decoding its images) up front costs a noticeable amount of time
5411
+ * on decks with many masters, and most sessions never open the layout gallery
5412
+ * at all.
5413
+ *
5414
+ * @example
5415
+ * ```ts
5416
+ * const preview: PptxLayoutPreview = {
5417
+ * path: "ppt/slideLayouts/slideLayout2.xml",
5418
+ * width: 960,
5419
+ * height: 540,
5420
+ * elements: [],
5421
+ * placeholders: [{ type: "title" }],
5422
+ * };
5423
+ * // => satisfies PptxLayoutPreview
5424
+ * ```
5425
+ */
5426
+ interface PptxLayoutPreview {
5427
+ /** ZIP path of the layout this preview belongs to. */
5428
+ path: string;
5429
+ /** Slide width in CSS pixels, so a thumbnail can compute its own scale. */
5430
+ width: number;
5431
+ /** Slide height in CSS pixels. */
5432
+ height: number;
5433
+ /** Background resolved from the layout, falling back to its master's. */
5434
+ backgroundColor?: string;
5435
+ /** Background image data URL, when the layout or master declares one. */
5436
+ backgroundImage?: string;
5437
+ /** The layout's own artwork (pictures, shapes and static text). */
5438
+ elements: PptxElement[];
5439
+ /** Placeholder slots, drawn as outlined frames in the gallery. */
5440
+ placeholders: PptxPlaceholderFrame[];
5441
+ }
5093
5442
  /**
5094
5443
  * A theme part available in the presentation package.
5095
5444
  *
@@ -5578,6 +5927,54 @@ interface PptxEmbeddedFontList {
5578
5927
  rawXml?: XmlObject;
5579
5928
  }
5580
5929
  //#endregion
5930
+ //#region src/core/types/comment-mentions.d.ts
5931
+ /**
5932
+ * A single `@`-mention inside a modern comment body.
5933
+ *
5934
+ * Offsets index into the comment's FLATTENED plain text: every `a:t` value
5935
+ * below `p188:txBody` concatenated, with paragraphs joined by `\n`. That is the
5936
+ * same string `PptxComment.text` carries, so an edit to `text` invalidates
5937
+ * every offset after the edit point and the serializer re-bases them.
5938
+ *
5939
+ * The markup Office uses for a mention is `CT_Mention` (documented for the
5940
+ * SpreadsheetML `2018/threadedcomments` part): `mentionpersonId`, `mentionId`,
5941
+ * `startIndex` and `length`. The PowerPoint `2018/8/main` schema does not
5942
+ * publish a mention element at all, so `rawXml` is retained and re-emitted
5943
+ * attribute-for-attribute: a producer that spells the attributes differently
5944
+ * still round-trips.
5945
+ *
5946
+ * @example
5947
+ * ```ts
5948
+ * const mention: PptxCommentMention = {
5949
+ * personId: "{2CB2E9D0-D392-EB21-5D46-FBA34C1295E6}",
5950
+ * authorName: "Bob Example",
5951
+ * startIndex: 3,
5952
+ * length: 11,
5953
+ * };
5954
+ * // => "Hi Bob Example can you check this".slice(3, 14) === "Bob Example"
5955
+ * ```
5956
+ */
5957
+ interface PptxCommentMention {
5958
+ /** `mentionId`: GUID identifying this mention instance. */
5959
+ id?: string;
5960
+ /** `mentionpersonId`: the `p188:author` id of the mentioned person. */
5961
+ personId: string;
5962
+ /** Display name resolved from the author list at parse time, when known. */
5963
+ authorName?: string;
5964
+ /** Character offset of the mentioned span in the flattened plain text. */
5965
+ startIndex: number;
5966
+ /** Character length of the mentioned span. */
5967
+ length: number;
5968
+ /**
5969
+ * `uri` of the `p188:ext` this mention list was read from. Undefined means
5970
+ * the list is a direct child of `p188:cm`, which is where it is written for
5971
+ * newly authored mentions.
5972
+ */
5973
+ containerUri?: string;
5974
+ /** Original `p188:mention` node, retained for unknown-attribute preservation. */
5975
+ rawXml?: XmlObject;
5976
+ }
5977
+ //#endregion
5581
5978
  //#region src/core/types/metadata.d.ts
5582
5979
  /**
5583
5980
  * A slide comment — may be a legacy positional comment or a modern
@@ -5624,6 +6021,8 @@ interface PptxComment {
5624
6021
  title?: string;
5625
6022
  /** Modern threaded comment support (p15:threadingInfo). */
5626
6023
  threadId?: string;
6024
+ /** `@`-mentions, indexed into `text` (see {@link PptxCommentMention}). */
6025
+ mentions?: PptxCommentMention[];
5627
6026
  /** Replies to this comment (for modern threaded comments). */
5628
6027
  replies?: PptxComment[];
5629
6028
  /** ID of the element this comment is associated with (if any). */
@@ -6143,7 +6542,7 @@ interface PptxTheme {
6143
6542
  * // => "morph" — one of 40+ transition effects
6144
6543
  * ```
6145
6544
  */
6146
- type PptxTransitionType = 'none' | 'cut' | 'fade' | 'push' | 'wipe' | 'split' | 'randomBar' | 'blinds' | 'checker' | 'circle' | 'comb' | 'cover' | 'diamond' | 'dissolve' | 'plus' | 'pull' | 'random' | 'strips' | 'uncover' | 'wedge' | 'wheel' | 'zoom' | 'newsflash' | 'morph' | 'conveyor' | 'doors' | 'ferris' | 'flash' | 'flythrough' | 'gallery' | 'glitter' | 'honeycomb' | 'pan' | 'prism' | 'reveal' | 'ripple' | 'shred' | 'switch' | 'vortex' | 'warp' | 'wheelReverse' | 'window' | 'cube' | 'flip' | 'rotate' | 'orbit' | 'fallOver' | 'drape' | 'curtains' | 'wind' | 'prestige' | 'fracture' | 'crush' | 'peelOff' | 'pageCurlDouble' | 'pageCurlSingle' | 'airplane' | 'origami';
6545
+ type PptxTransitionType = 'none' | 'cut' | 'fade' | 'push' | 'wipe' | 'split' | 'randomBar' | 'blinds' | 'checker' | 'circle' | 'comb' | 'cover' | 'diamond' | 'dissolve' | 'plus' | 'pull' | 'random' | 'strips' | 'uncover' | 'wedge' | 'wheel' | 'zoom' | 'newsflash' | 'morph' | 'conveyor' | 'doors' | 'ferris' | 'flash' | 'flythrough' | 'gallery' | 'glitter' | 'honeycomb' | 'pan' | 'prism' | 'reveal' | 'ripple' | 'shred' | 'switch' | 'vortex' | 'warp' | 'wheelReverse' | 'window' | 'cube' | 'flip' | 'rotate' | 'box' | 'orbit' | 'fallOver' | 'drape' | 'curtains' | 'wind' | 'prestige' | 'fracture' | 'crush' | 'peelOff' | 'pageCurlDouble' | 'pageCurlSingle' | 'airplane' | 'origami';
6147
6546
  /** Split orientation from OOXML `@_orient`. */
6148
6547
  type PptxSplitOrientation = 'horz' | 'vert';
6149
6548
  /** Schema-defined `ST_TransitionSpeed` values. */
@@ -6438,6 +6837,18 @@ interface PptxSlideBackgroundPattern {
6438
6837
  interface PptxSlide {
6439
6838
  id: string;
6440
6839
  rId: string;
6840
+ /**
6841
+ * `p:sldIdLst/p:sldId/@id` (ST_SlideId, 256..2147483647): the numeric key
6842
+ * that sections (`p14:sldIdLst/p14:sldId/@id`) and section/summary zooms
6843
+ * name slides by.
6844
+ *
6845
+ * It lives in `presentation.xml`, NOT in the slide part, so it cannot be
6846
+ * recovered from `rawXml`. Without it on the model, code that writes a
6847
+ * section's membership has nothing correct to write and falls back to the
6848
+ * slide NUMBER, which is 1-based and therefore never matches a real deck's
6849
+ * ids: the section reloads with no slides in it.
6850
+ */
6851
+ slideId?: string;
6441
6852
  sourceSlideId?: string;
6442
6853
  /** Optional author-supplied slide name (set via `SlideBuilder.setName`). */
6443
6854
  name?: string;
@@ -6640,6 +7051,26 @@ interface PptxPresentationProperties {
6640
7051
  /** Kiosk auto-restart interval in milliseconds (from `p:kiosk/@restart`). Only meaningful when showType is "kiosk". */
6641
7052
  kioskRestartTime?: number;
6642
7053
  }
7054
+ /**
7055
+ * Slide dimensions from `p:sldSz` (CT_SlideSize, ECMA-376 §19.2.1.39).
7056
+ *
7057
+ * @example
7058
+ * ```ts
7059
+ * const size: PptxSlideSize = { widthEmu: 9144000, heightEmu: 6858000, type: 'screen4x3' };
7060
+ * // => satisfies PptxSlideSize
7061
+ * ```
7062
+ */
7063
+ interface PptxSlideSize {
7064
+ /** `@cx` in EMU. Omitted or non-positive values leave the loaded width alone. */
7065
+ widthEmu?: number;
7066
+ /** `@cy` in EMU. Omitted or non-positive values leave the loaded height alone. */
7067
+ heightEmu?: number;
7068
+ /**
7069
+ * `@type` (ST_SlideSizeType). The schema default is `custom`, which is
7070
+ * why PowerPoint omits the attribute for a non-preset size.
7071
+ */
7072
+ type?: string;
7073
+ }
6643
7074
  /**
6644
7075
  * A named custom slide show (`p:custShowLst / p:custShow`).
6645
7076
  *
@@ -7654,6 +8085,19 @@ interface PptxHandlerSaveOptions {
7654
8085
  customerData?: PptxCustomerData[];
7655
8086
  /** Photo album metadata to save back to `p:photoAlbum`. */
7656
8087
  photoAlbum?: PptxPhotoAlbum;
8088
+ /**
8089
+ * Slide dimensions to write back to `p:sldSz`.
8090
+ *
8091
+ * Omitting the option preserves the load-time dimensions verbatim, which
8092
+ * is why an edit made through a viewer's Slide Size control has to reach
8093
+ * the save call: nothing else in the pipeline can observe it.
8094
+ *
8095
+ * PowerPoint derives `Presentation.PageSetup.SlideSize` from `@cx`/`@cy`
8096
+ * alone (verified by COM: an A4-typed `p:sldSz` carrying 4:3 dimensions
8097
+ * still reports `ppSlideSizeCustom`), so `type` is written for fidelity
8098
+ * but the dimensions are what actually decide the reported preset.
8099
+ */
8100
+ slideSize?: PptxSlideSize;
7657
8101
  /** East Asian line-break settings to save back to `p:kinsoku`. */
7658
8102
  kinsoku?: PptxKinsoku | null;
7659
8103
  /** Write-protection verifier. Set to `null` to remove, `undefined` to preserve existing. */
@@ -7709,6 +8153,8 @@ interface IPptxHandlerRuntime {
7709
8153
  revokeBlobUrls(): void;
7710
8154
  getCompatibilityWarnings(): PptxCompatibilityWarning[];
7711
8155
  getLayoutOptions(): PptxLayoutOption[];
8156
+ getLayoutPreview(layoutPath: string): Promise<PptxLayoutPreview | null>;
8157
+ getLayoutPreviews(layoutPaths?: readonly string[]): Promise<PptxLayoutPreview[]>;
7712
8158
  createXmlBuilder(data: PptxData): PptxXmlBuilder;
7713
8159
  Builder(data: PptxData): PptxXmlBuilder;
7714
8160
  setTemplateBackground(path: string, backgroundColor: string | undefined): void;
@@ -7897,6 +8343,26 @@ declare class PptxHandlerCore {
7897
8343
  * @returns Array of {@link PptxLayoutOption} entries.
7898
8344
  */
7899
8345
  getLayoutOptions(): PptxLayoutOption[];
8346
+ /**
8347
+ * Build the artwork thumbnails backing the New Slide / Layout galleries.
8348
+ *
8349
+ * Parsing happens on first request and is memoised afterwards, so opening
8350
+ * the gallery costs one pass over the layout parts and reopening it costs
8351
+ * nothing. Callers that only need one entry should prefer
8352
+ * {@link getLayoutPreview}.
8353
+ *
8354
+ * @param layoutPaths - Restrict the result to these layouts; defaults to
8355
+ * every layout in the presentation.
8356
+ * @returns One {@link PptxLayoutPreview} per resolvable layout.
8357
+ */
8358
+ getLayoutPreviews(layoutPaths?: readonly string[]): Promise<PptxLayoutPreview[]>;
8359
+ /**
8360
+ * Build the artwork thumbnail for a single layout.
8361
+ *
8362
+ * @param layoutPath - Archive path of the `p:sldLayout` part.
8363
+ * @returns The preview, or `null` when the presentation has no such layout.
8364
+ */
8365
+ getLayoutPreview(layoutPath: string): Promise<PptxLayoutPreview | null>;
7900
8366
  /**
7901
8367
  * Create a fluent XML builder scoped to the given presentation data.
7902
8368
  *
@@ -8223,24 +8689,38 @@ declare class PptxHandlerCore {
8223
8689
  name?: string;
8224
8690
  }>>;
8225
8691
  /**
8226
- * Export selected slides as individual PPTX files.
8692
+ * Export selected slides to a vector or raster format, keyed by slide index.
8227
8693
  *
8228
- * Each entry in the returned map is keyed by slide index and contains a
8229
- * standalone `Uint8Array` PPTX with only that slide.
8694
+ * **This does not produce PPTX files.** The previous version of this comment
8695
+ * said each entry was "a standalone PPTX with only that slide", named the
8696
+ * option `slideIndexes` (the real field is `slideIndices`), and wrote the
8697
+ * bytes to `slide_N.pptx`. None of that was ever true: the runtime has
8698
+ * always taken a `format` of `svg` / `png` / `pdf`. Per-slide PPTX
8699
+ * extraction is a different operation and is not implemented here.
8700
+ *
8701
+ * Only `svg` works without a host-supplied backend, and it works fully:
8702
+ * the headless {@link SvgExporter} renders it with no DOM. `png` and `pdf`
8703
+ * THROW, because this package carries no rasteriser; use a viewer binding's
8704
+ * browser export pipeline, or override `exportSlides` on the runtime with
8705
+ * your own backend.
8230
8706
  *
8231
8707
  * @param slides - Full slide array.
8232
- * @param options - Export options (slide indexes, format, etc.).
8233
- * @returns A `Map<slideIndex, Uint8Array>` of exported files.
8708
+ * @param options - Export options (`format`, `slideIndices`, `width`, ...).
8709
+ * @returns A `Map<slideIndex, Uint8Array>` of exported files. Hidden slides
8710
+ * are omitted unless `options.includeHidden` is set, so the map can be
8711
+ * smaller than `options.slideIndices`.
8712
+ * @throws {Error} when `options.format` is `png` or `pdf`.
8234
8713
  *
8235
8714
  * @example
8236
8715
  * ```ts
8237
8716
  * const exports = await handler.exportSlides(data.slides, {
8238
- * slideIndexes: [0, 2],
8717
+ * format: 'svg',
8718
+ * slideIndices: [0, 2],
8239
8719
  * });
8240
8720
  * for (const [idx, bytes] of exports) {
8241
- * await fs.writeFile(`slide_${idx}.pptx`, Buffer.from(bytes));
8721
+ * await fs.writeFile(`slide_${idx}.svg`, Buffer.from(bytes));
8242
8722
  * }
8243
- * // => Map<number, Uint8Array> one standalone .pptx per exported slide
8723
+ * // => Map<number, Uint8Array>: one SVG document per exported slide
8244
8724
  * ```
8245
8725
  */
8246
8726
  exportSlides(slides: PptxSlide[], options: PptxExportOptions): Promise<Map<number, Uint8Array>>;
@@ -8818,6 +9298,68 @@ interface FieldSubstitutionContext {
8818
9298
  //#endregion
8819
9299
  //#region src/render/text-case-transform.d.ts
8820
9300
  type ChangeCaseMode = 'sentence' | 'lower' | 'upper' | 'capitalize' | 'toggle';
9301
+ //#endregion
9302
+ //#region src/render/shape-adjustment-model.d.ts
9303
+ /**
9304
+ * `shape-adjustment-model`: the vocabulary the adjust-handle modules share.
9305
+ *
9306
+ * The `a:ahLst` work is split three ways for the repo's file-size budget:
9307
+ * `shape-adjustment-probe` measures the geometry, `shape-adjustment-handles`
9308
+ * derives the handles from those measurements, and `shape-adjustment-solver`
9309
+ * turns a pointer position back into guide values. All three need these types
9310
+ * and the one rule that operates purely on them, so they live here and the
9311
+ * dependency graph stays a DAG rather than a cycle.
9312
+ *
9313
+ * @module render/shape-adjustment-model
9314
+ */
9315
+ /**
9316
+ * How a pointer position becomes a guide value, captured once when the gesture
9317
+ * starts so `pointermove` stays pure arithmetic.
9318
+ */
9319
+ interface ShapeAdjustmentSolver {
9320
+ /** `linear`: the handle slides. `angular`: it swings about {@link centerX}. */
9321
+ kind: 'linear' | 'angular';
9322
+ /** Handle position in element-local px at {@link startValue}. */
9323
+ anchorX: number;
9324
+ anchorY: number;
9325
+ /** Element-local px the handle travels per ONE unit of guide value. */
9326
+ dirX: number;
9327
+ dirY: number;
9328
+ /** Pivot for an angular handle (the shape centre). */
9329
+ centerX: number;
9330
+ centerY: number;
9331
+ /** The guide value the anchor was measured at. */
9332
+ startValue: number;
9333
+ /** Guide-space bounds, taken from the preset's own `pin` clamp. */
9334
+ min: number;
9335
+ max: number;
9336
+ }
9337
+ /** One guide a handle drives. */
9338
+ interface AdjustmentAxisSolver {
9339
+ key: string;
9340
+ solver: ShapeAdjustmentSolver;
9341
+ }
9342
+ /** Descriptor for one draggable adjustment handle (the amber diamond). */
9343
+ interface ShapeAdjustmentHandleDescriptor {
9344
+ /** The `a:avLst` guide name this handle writes (`adj`, `adj1`, ...). */
9345
+ key: string;
9346
+ /** Handle x offset in element-local px (origin = element top-left). */
9347
+ left: number;
9348
+ /** Handle y offset in element-local px. */
9349
+ top: number;
9350
+ /**
9351
+ * Current adjustment value in GUIDE units, not a 0-1 fraction. Most presets
9352
+ * range 0..50000 or 0..100000 and the angular ones run to 21,600,000.
9353
+ */
9354
+ value: number;
9355
+ cursor: string;
9356
+ /**
9357
+ * How this handle's drag resolves, measured off the preset geometry: one
9358
+ * entry per `a:avLst` guide it drives (callouts drive two). Absent only for
9359
+ * a caller that built a descriptor by hand.
9360
+ */
9361
+ solvers?: AdjustmentAxisSolver[];
9362
+ }
8821
9363
  /**
8822
9364
  * A font supplied by the host application. The package never ships fonts:
8823
9365
  * applications provide a licensed URL, data URL, or blob URL for their users.
@@ -8830,6 +9372,80 @@ interface ViewerFontSource {
8830
9372
  style?: 'normal' | 'italic';
8831
9373
  }
8832
9374
  //#endregion
9375
+ //#region src/render/presentation-file-kinds.d.ts
9376
+ /**
9377
+ * presentation-file-kinds: the one place that answers "can the viewer open
9378
+ * this file?" and "what should the saved copy be called?".
9379
+ *
9380
+ * ## Why this is a shared decision and not five allow-lists
9381
+ *
9382
+ * The loader reads more formats than any single UI advertises. Legacy binary
9383
+ * `.ppt` (PowerPoint 97-2003) is the sharp example: `PptxHandler.load()` has
9384
+ * detected the OLE compound-file container and converted the binary deck
9385
+ * through the regular pptx pipeline for some time, but the product kept saying
9386
+ * it was unsupported, and a picker that filters the extension out makes a
9387
+ * working loader unreachable in practice. Whenever the loader learns a format,
9388
+ * exactly one list has to change.
9389
+ *
9390
+ * ## Read many, write one
9391
+ *
9392
+ * Input is a superset of output. We READ `.pptx`, `.ppsx`, `.pptm`, `.potx`,
9393
+ * legacy binary `.ppt` and portable `pptx-viewer-json`; we WRITE only the
9394
+ * OpenXML family. That asymmetry is deliberate (PowerPoint itself does the
9395
+ * same: open a 97-2003 deck and Save As offers `.pptx`), and it is why
9396
+ * {@link savedPresentationFileName} always REPLACES the source extension
9397
+ * rather than keeping it. A deck opened as `report.ppt` and saved as
9398
+ * `report.ppt` would be a file whose bytes and whose name disagree, which is
9399
+ * the kind of thing PowerPoint refuses to open.
9400
+ *
9401
+ * This module deliberately imports nothing, so any layer (render, export, a
9402
+ * binding, a host app) can depend on it without risking an import cycle.
9403
+ *
9404
+ * @module render/presentation-file-kinds
9405
+ */
9406
+ /**
9407
+ * Extensions the built-in file picker offers, in the order it offers them.
9408
+ *
9409
+ * `.ppt` is in the list because the loader genuinely handles it, not as a
9410
+ * courtesy: see `packages/core/src/core/ppt/` and the `ppt-import` integration
9411
+ * suite, which asserts a `.ppt` loads to the same model as the `.pptx` it was
9412
+ * exported from.
9413
+ */
9414
+ declare const PRESENTATION_OPEN_EXTENSIONS: readonly ['.pptx', '.ppsx', '.pptm', '.potx', '.ppt', '.json'];
9415
+ /** Comma-separated `accept` attribute for a presentation file input. */
9416
+ declare const PPTX_OPEN_ACCEPT: string;
9417
+ /**
9418
+ * True when a picked / dropped file's name looks like something the loader can
9419
+ * open. Use this instead of a hand-rolled `endsWith` chain: a drop handler that
9420
+ * disagrees with the picker's `accept` list is a format that is supported by
9421
+ * mouse but not by drag, which is how `.ppt` stayed invisible.
9422
+ *
9423
+ * Extension-only, by design. The real answer comes from the container sniff in
9424
+ * `PptxHandler.load()`; this is only the cheap pre-filter a drop target needs
9425
+ * before it hands bytes to the loader.
9426
+ */
9427
+ declare function isSupportedPresentationFile(name: string | null | undefined): boolean;
9428
+ /** True for the binary PowerPoint 97-2003 family, which we read but never write. */
9429
+ declare function isLegacyBinaryPresentation(name: string | null | undefined): boolean;
9430
+ /** The formats the save path can produce. Binary `.ppt` is deliberately absent. */
9431
+ type SavedPresentationFormat = 'pptx' | 'ppsx' | 'pptm';
9432
+ /**
9433
+ * The stem of a presentation file name: directories and any loadable extension
9434
+ * removed. `C:\decks\report.ppt` becomes `report`; a name with no recognised
9435
+ * extension is kept whole, so `Untitled Presentation` survives intact rather
9436
+ * than losing everything after its last dot.
9437
+ */
9438
+ declare function presentationBaseName(sourceName: string | null | undefined, fallback?: string): string;
9439
+ /**
9440
+ * The name a saved copy should be offered under: the source stem plus the
9441
+ * extension of the format actually being written.
9442
+ *
9443
+ * This is what turns `report.ppt` into `report.pptx` on Save As. Output is
9444
+ * always an OpenXML package, so keeping the source extension would mislabel
9445
+ * the bytes.
9446
+ */
9447
+ declare function savedPresentationFileName(sourceName: string | null | undefined, format?: SavedPresentationFormat): string;
9448
+ //#endregion
8833
9449
  //#region src/render/insert-chart.d.ts
8834
9450
  /**
8835
9451
  * Dropdown ids for the insert-chart menu. Distinct from `PptxChartType`
@@ -8943,6 +9559,15 @@ interface ViewerGeneralOptions {
8943
9559
  userName: string;
8944
9560
  userInitials: string;
8945
9561
  showStartScreen: boolean;
9562
+ /**
9563
+ * Lets the user hand a local font file to the viewer so decks authored
9564
+ * with a font the browser lacks render with the real face.
9565
+ *
9566
+ * Off by default. The registration reads a file the user picks and adds it
9567
+ * to the page's font set for the session, which is a capability a host
9568
+ * embedding the viewer should opt into rather than inherit.
9569
+ */
9570
+ enableCustomFontUpload: boolean;
8946
9571
  }
8947
9572
  interface ViewerProofingOptions {
8948
9573
  autoCorrectTwoInitialCapitals: boolean;
@@ -8959,13 +9584,25 @@ interface ViewerProofingOptions {
8959
9584
  checkSpellingAsYouType: boolean;
8960
9585
  hideSpellingErrors: boolean;
8961
9586
  }
9587
+ /**
9588
+ * File > Options > Save.
9589
+ *
9590
+ * Font embedding deliberately has NO entry here. It is owned by the File >
9591
+ * Fonts panel, whose toggle is the one the save path reads (see
9592
+ * `render/font-embedding`: `describeFontEmbedding` decides the toggle's start
9593
+ * position and whether it can do anything at all, `embeddedFontSaveOptions`
9594
+ * turns it into the `PptxHandler.save()` slice). This group used to carry a
9595
+ * second `embedFonts` boolean, plus an `embedAllFontCharacters` companion, and
9596
+ * neither was read by anything: the pane moved a switch that changed no saved
9597
+ * byte, while the panel next door moved the real one. Two switches for one
9598
+ * setting, one of them lying, is worse than one switch in a less
9599
+ * PowerPoint-shaped place.
9600
+ */
8962
9601
  interface ViewerSaveOptions {
8963
9602
  autoSave: boolean;
8964
9603
  autoRecoverIntervalMinutes: number;
8965
9604
  keepLastAutoRecoveredVersion: boolean;
8966
9605
  defaultExportFormat: DefaultExportFormat;
8967
- embedFonts: boolean;
8968
- embedAllFontCharacters: boolean;
8969
9606
  cacheRetentionDays: number;
8970
9607
  clearCacheOnClose: boolean;
8971
9608
  }
@@ -9708,10 +10345,20 @@ interface ToolbarProps {
9708
10345
  onTransformTextCase: (mode: ChangeCaseMode) => void;
9709
10346
  isOverflowMenuOpen: boolean;
9710
10347
  onSetOverflowMenuOpen: (open: boolean) => void;
9711
- layoutOptions: Array<{
9712
- path: string;
9713
- name: string;
9714
- }>;
10348
+ layoutOptions: PptxLayoutOption[];
10349
+ /** `layoutPath` of the active slide, marking the current gallery tile. */
10350
+ currentLayoutPath?: string;
10351
+ /** Supplies gallery artwork; without it the menus stay name-only. */
10352
+ loadLayoutPreviews?: () => Promise<PptxLayoutPreview[]>;
10353
+ /** Theme major/minor latin faces, leading the font dropdown. */
10354
+ themeFonts?: {
10355
+ heading?: string;
10356
+ body?: string;
10357
+ };
10358
+ /** Families the deck embeds, offered as their own dropdown group. */
10359
+ embeddedFontFamilies?: readonly string[];
10360
+ /** Families registered this session via File > Options > Fonts. */
10361
+ customFontFamilies?: readonly string[];
9715
10362
  onInsertSlideFromLayout: (path: string, name?: string) => void;
9716
10363
  /** Re-map the active slide onto another of its master's layouts. */
9717
10364
  onApplyLayout?: (path: string) => void;
@@ -9730,6 +10377,8 @@ interface ToolbarProps {
9730
10377
  onToggleVersionHistory?: () => void;
9731
10378
  onOpenPasswordProtection?: () => void;
9732
10379
  onOpenDocumentProperties?: () => void;
10380
+ /** Design > Slide Size: reveal the inspector card that owns the slide size. */
10381
+ onOpenSlideSize?: () => void;
9733
10382
  onOpenFontEmbedding?: () => void;
9734
10383
  onOpenDigitalSignatures?: () => void;
9735
10384
  onEnterMasterView: () => void;
@@ -9763,6 +10412,22 @@ interface ToolbarProps {
9763
10412
  activeSlide?: PptxSlide;
9764
10413
  onTransitionChange: (updates: Partial<PptxSlideTransition>) => void;
9765
10414
  onApplyTransitionToAll: () => void;
10415
+ /**
10416
+ * Home > Slides > Reset: re-apply the active slide's own layout, restoring
10417
+ * inherited placeholder geometry. Undeclared until now, which is why
10418
+ * `SlidesGroup` bound `undefined` and the button did nothing.
10419
+ */
10420
+ onResetSlide?: () => void;
10421
+ /** Home > Slides > Section: start a new section at the active slide. */
10422
+ onAddSection?: () => void;
10423
+ /** Home > Editing > Select > Select All (every element on the active slide). */
10424
+ onSelectAll?: () => void;
10425
+ /**
10426
+ * Slide Show > Options: what the four checkboxes read, and how a tick is
10427
+ * committed. See shared `ribbon-slide-show-options`.
10428
+ */
10429
+ presentationProperties?: PptxPresentationProperties;
10430
+ onPresentationPropertiesChange?: (updates: Partial<PptxPresentationProperties>) => void;
9766
10431
  /** Host-supplied list of toolbar buttons/ribbon tabs to hide. See `PowerPointViewerProps.hiddenActions`. */
9767
10432
  hiddenActions?: readonly ToolbarActionId[];
9768
10433
  /** Whether the AI assistant is available (the host passed the `ai` prop). */
@@ -9839,7 +10504,7 @@ interface SlideCanvasProps {
9839
10504
  /** Called when the user presses mouse down on empty canvas space. */
9840
10505
  onCanvasMouseDown?: (e: React$1__default.MouseEvent) => void;
9841
10506
  onResizePointerDown: (elementId: string, e: React$1__default.MouseEvent, handle: string) => void;
9842
- onAdjustmentPointerDown: (elementId: string, e: React$1__default.MouseEvent) => void;
10507
+ onAdjustmentPointerDown: (elementId: string, e: React$1__default.MouseEvent, descriptor: ShapeAdjustmentHandleDescriptor) => void;
9843
10508
  /** Commit a new rotation (degrees) when the on-canvas rotate handle is dragged. */
9844
10509
  onRotate?: (elementId: string, rotationDeg: number) => void;
9845
10510
  onInlineEditChange: (text: string) => void;
@@ -10039,5 +10704,5 @@ declare function SlideTemplatePreview({ templateId, scheme }: SlideTemplatePrevi
10039
10704
  */
10040
10705
  declare function renderToCanvas(element: HTMLElement, options?: Partial<Options>): Promise<HTMLCanvasElement>;
10041
10706
 
10042
- export { AVATAR_COLOR_SWATCHES, DEFAULT_VIEWER_PROFILE, LOCALE_CATALOG, PowerPointViewer, SLIDE_TEMPLATES, SlideCanvas, SlideTemplateGalleryDialog, SlideTemplatePreview, THEME_CATALOG, Toolbar, VIEWER_PREFS_STORAGE_KEY, ViewerThemeProvider, buildSlideTemplateContent, buildSlideTemplateSlide, clearAllLocalViewerData, clearStoredViewerPrefs, defaultCssVars, defaultRadius, defaultThemeColors, getAnimationInitialStyle, getLocalStorageUsageSummary, readStoredViewerPrefs, renderToCanvas, resolveProfileInitial, resolveThemeCatalogEntry, saveViewerProfile, themeToCssVars, useViewerBuildingBlocks, useViewerTheme, vermilionDarkColors, vermilionDarkTheme, vermilionLightColors, vermilionLightTheme, vermilionRadius, writeStoredViewerPrefs };
10043
- export type { AccountAuthConfig, LocalStorageUsageSummary, LocaleCatalogEntry, PowerPointViewerAPI, PowerPointViewerHandle, PowerPointViewerProps, PptxAiBridge, PptxAiConfig, PptxAiConnection, PptxAiContextStrategy, PptxAiToolName, PptxAiWritePolicy, SlideCanvasProps, SlideTemplateGalleryDialogProps, SlideTemplateId, SlideTemplatePreviewProps, SlideTemplateSpec, StoredViewerPrefs, ThemeCatalogEntry, ToolbarActionId, ToolbarButtonId, ToolbarProps, ToolbarTabId, UseViewerBuildingBlocksInput, ViewerBuildingBlocksResult, ViewerMode, ViewerProfile, ViewerTheme, ViewerThemeColors };
10707
+ export { AVATAR_COLOR_SWATCHES, DEFAULT_VIEWER_PROFILE, LOCALE_CATALOG, PPTX_OPEN_ACCEPT, PRESENTATION_OPEN_EXTENSIONS, PowerPointViewer, SLIDE_TEMPLATES, SlideCanvas, SlideTemplateGalleryDialog, SlideTemplatePreview, THEME_CATALOG, Toolbar, VIEWER_PREFS_STORAGE_KEY, ViewerThemeProvider, buildSlideTemplateContent, buildSlideTemplateSlide, clearAllLocalViewerData, clearStoredViewerPrefs, defaultCssVars, defaultRadius, defaultThemeColors, getAnimationInitialStyle, getLocalStorageUsageSummary, isLegacyBinaryPresentation, isSupportedPresentationFile, presentationBaseName, readStoredViewerPrefs, renderToCanvas, resolveProfileInitial, resolveThemeCatalogEntry, saveViewerProfile, savedPresentationFileName, themeToCssVars, useViewerBuildingBlocks, useViewerTheme, vermilionDarkColors, vermilionDarkTheme, vermilionLightColors, vermilionLightTheme, vermilionRadius, writeStoredViewerPrefs };
10708
+ export type { AccountAuthConfig, LocalStorageUsageSummary, LocaleCatalogEntry, PowerPointViewerAPI, PowerPointViewerHandle, PowerPointViewerProps, PptxAiBridge, PptxAiConfig, PptxAiConnection, PptxAiContextStrategy, PptxAiToolName, PptxAiWritePolicy, SavedPresentationFormat, SlideCanvasProps, SlideTemplateGalleryDialogProps, SlideTemplateId, SlideTemplatePreviewProps, SlideTemplateSpec, StoredViewerPrefs, ThemeCatalogEntry, ToolbarActionId, ToolbarButtonId, ToolbarProps, ToolbarTabId, UseViewerBuildingBlocksInput, ViewerBuildingBlocksResult, ViewerMode, ViewerProfile, ViewerTheme, ViewerThemeColors };