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
@@ -1147,6 +1147,22 @@ interface ShapeStyle {
1147
1147
  fontRefIdx?: string;
1148
1148
  /** Raw XML colour child of `<a:fontRef>`. */
1149
1149
  fontRefColorXml?: XmlObject;
1150
+ /**
1151
+ * The fill `<a:fillRef>` resolved to, recorded ONLY when the shape's own
1152
+ * `spPr` authored no fill at all, so the reference is what paints it.
1153
+ *
1154
+ * Its absence therefore means "the fill is the shape's own", and its
1155
+ * presence plus an unchanged flat fill means "still purely inherited": see
1156
+ * `authored-shape-style.ts`, the shape-scope twin of `TextStyle`'s
1157
+ * `inheritedRunStyle`.
1158
+ */
1159
+ inheritedFillStyle?: ShapeStyle;
1160
+ /**
1161
+ * The outline `<a:lnRef>` resolved to, recorded before `spPr/a:ln` was
1162
+ * layered on top. A property that still equals this baseline was never
1163
+ * authored on the shape and must not be written back as if it were.
1164
+ */
1165
+ inheritedLineStyle?: ShapeStyle;
1150
1166
  }
1151
1167
  //#endregion
1152
1168
  //#region src/core/types/text.d.ts
@@ -1187,6 +1203,60 @@ interface ShapeStyle {
1187
1203
  interface TextStyle {
1188
1204
  /** Original `a:rPr` XML retained by projections that share the shape-text model. */
1189
1205
  runPropertiesXml?: XmlObject;
1206
+ /**
1207
+ * The properties this run's OWN `a:rPr` authored, and nothing else.
1208
+ *
1209
+ * A run style is assembled as
1210
+ * `{...inheritedRunStyle, ...authoredRunStyle}`, so the flat style is a
1211
+ * fully RESOLVED view: it cannot say whether `fontSize: 60` came from the
1212
+ * run, from the shape's `a:lstStyle`, from the layout placeholder, from the
1213
+ * master `p:txStyles` or from the theme. Omission is meaningful in OOXML
1214
+ * (§21.1.2.3), so a writer that re-emits the resolved view converts every
1215
+ * inherited value into an authored one and the deck stops being
1216
+ * theme-driven after one save.
1217
+ *
1218
+ * This is the run-scope twin of {@link TextSegment.paragraphProperties},
1219
+ * which is parsed strictly from the paragraph's own `a:pPr` for the same
1220
+ * reason. Present only for runs that came from a parsed deck; absent for
1221
+ * SDK-built text, where the flat style IS the only description and must be
1222
+ * written out in full.
1223
+ */
1224
+ authoredRunStyle?: TextStyle;
1225
+ /**
1226
+ * The resolved inheritance baseline {@link authoredRunStyle} was layered
1227
+ * on top of (shape `a:lstStyle` -> placeholder -> layout -> master
1228
+ * `p:txStyles` -> theme -> `p:defaultTextStyle`).
1229
+ *
1230
+ * Kept alongside the authored half because the two answer different
1231
+ * questions. The authored half says "the source pinned this"; the baseline
1232
+ * says "this value is what inheritance already produces", which is how an
1233
+ * EDIT is told apart from an inherited value: an editor mutates the flat
1234
+ * style without knowing about either field, so a property that now differs
1235
+ * from the baseline was either authored or edited and must be written,
1236
+ * while one that still matches can be left to inherit.
1237
+ *
1238
+ * Holds a reference to the per-paragraph baseline object rather than a
1239
+ * copy, so carrying it costs one pointer per run.
1240
+ */
1241
+ inheritedRunStyle?: TextStyle;
1242
+ /**
1243
+ * Snapshot of the ELEMENT-scope paragraph geometry (alignment, margins,
1244
+ * indent, line and paragraph spacing, tab stops, rtl, line-break flags) as
1245
+ * the load pipeline resolved it.
1246
+ *
1247
+ * Present only on an `element.textStyle` that came from a parsed deck, and
1248
+ * populated only with the geometry keys. It exists so the save path can
1249
+ * answer one question it otherwise cannot: has the user CHANGED the body's
1250
+ * alignment or indent, or is the value simply what the shape's
1251
+ * `a:lstStyle`, its layout placeholder and the master already produce?
1252
+ * Element-level text panels (`textAdvancedPatch`, `alignPatch` and friends
1253
+ * in `pptx-viewer-shared`) write `element.textStyle` and never touch
1254
+ * `segment.paragraphProperties`, so a diff against this snapshot is the
1255
+ * only way to tell an edit from an inheritance artefact.
1256
+ *
1257
+ * @see element-paragraph-geometry.ts
1258
+ */
1259
+ resolvedParagraphGeometry?: TextStyle;
1190
1260
  fontFamily?: string;
1191
1261
  fontSize?: number;
1192
1262
  /** When true, renderer should shrink text to fit the shape bounds. */
@@ -1642,7 +1712,28 @@ interface BulletInfo {
1642
1712
  autoNumType?: string;
1643
1713
  /** Auto-numbering start value. */
1644
1714
  autoNumStartAt?: number;
1645
- /** Zero-based paragraph index within the text body (for auto-numbering). */
1715
+ /**
1716
+ * Auto-numbering ORDINAL OFFSET: the zero-based distance of this paragraph
1717
+ * within its own numbered list, such that
1718
+ * `autoNumStartAt + paragraphIndex` is the ordinal to render. Despite the
1719
+ * name it is NOT the paragraph's position in the text body; the two agree
1720
+ * only for a list that starts at the first paragraph and is never
1721
+ * interrupted.
1722
+ *
1723
+ * It has to be the offset rather than the raw position because every
1724
+ * consumer that re-derives a marker from `BulletInfo` alone (the renderer's
1725
+ * `resolveParagraphBullet`, the Markdown converter's `resolveListMarker`)
1726
+ * computes `autoNumStartAt + paragraphIndex`. The load path resolves the
1727
+ * real sequence itself, restarting the count after any paragraph that
1728
+ * interrupts the list, and publishes the offset here so those consumers
1729
+ * land on the same number. With the raw position they did not, and BOTH
1730
+ * markers were painted ("3.1. Item"), because the paragraph builder drops
1731
+ * the parsed marker segment only when the two strings agree.
1732
+ *
1733
+ * Runtime-only: derived at parse time and never serialized. OOXML has no
1734
+ * counterpart (`a:buAutoNum` carries only `@type` and `@startAt`), so the
1735
+ * writer neither reads nor emits it.
1736
+ */
1646
1737
  paragraphIndex?: number;
1647
1738
  /** Bullet font family from `a:buFont`. */
1648
1739
  fontFamily?: string;
@@ -1830,6 +1921,15 @@ interface PptxElementBase {
1830
1921
  shapeId?: string;
1831
1922
  /** Element name from `cNvPr/@name`. Used for morph transition matching via the `!!` naming convention. */
1832
1923
  name?: string;
1924
+ /**
1925
+ * `p:nvSpPr/p:nvPr/p:ph/@type` (lower-cased) when the shape is a placeholder:
1926
+ * `title`, `ctrtitle`, `body`, `subtitle`, `ftr`, `dt`, `sldnum`, ...
1927
+ *
1928
+ * Captured on load so consumers can tell a footer placeholder from a text box
1929
+ * without re-walking `rawXml`. Absent on non-placeholder shapes and on
1930
+ * SDK-created elements.
1931
+ */
1932
+ placeholderType?: string;
1833
1933
  x: number;
1834
1934
  y: number;
1835
1935
  width: number;
@@ -1890,6 +1990,19 @@ interface PptxTextProperties {
1890
1990
  }>;
1891
1991
  /** 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. */
1892
1992
  promptText?: string;
1993
+ /**
1994
+ * The string {@link text} was INHERITED from, when this is a header / footer /
1995
+ * date / slide-number placeholder whose own body the file leaves empty.
1996
+ *
1997
+ * PowerPoint keeps the footer string on the slide master and writes each
1998
+ * slide's copy of the `ftr` placeholder empty, so the empty body means
1999
+ * "render the master's footer here". Rendering needs the resolved string, but
2000
+ * SAVING it into the slide would pin that slide to today's master text and
2001
+ * silently detach it from the Header & Footer dialog. The save writer
2002
+ * therefore leaves the authored empty body alone while `text` still equals
2003
+ * this value, and writes a genuine per-slide override once it does not.
2004
+ */
2005
+ inheritedPlaceholderText?: string;
1893
2006
  /** 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. */
1894
2007
  linkedTxbxId?: number;
1895
2008
  /** Sequence number within a linked text box chain (0-based). */
@@ -2300,6 +2413,12 @@ interface PptxChartLineStyle {
2300
2413
  }
2301
2414
  /** Marker symbol types for line/scatter chart data points. */
2302
2415
  type PptxChartMarkerSymbol = 'circle' | 'dash' | 'diamond' | 'dot' | 'none' | 'picture' | 'plus' | 'square' | 'star' | 'triangle' | 'x' | 'auto';
2416
+ /**
2417
+ * `ST_ScatterStyle` (ECMA-376 §21.2.3.40): how a scatter chart joins its points.
2418
+ * `line`/`lineMarker` connect them with straight segments, `smooth`/
2419
+ * `smoothMarker` with a bezier, `marker`/`none` not at all.
2420
+ */
2421
+ type PptxChartScatterStyle = 'none' | 'line' | 'lineMarker' | 'marker' | 'smooth' | 'smoothMarker';
2303
2422
  /** Shape properties extracted from c:spPr for chart formatting. */
2304
2423
  interface PptxChartShapeProps {
2305
2424
  fillColor?: string;
@@ -2501,6 +2620,42 @@ interface PptxChartTreemapOptions {
2501
2620
  interface PptxChartSeries {
2502
2621
  name: string;
2503
2622
  values: number[];
2623
+ /**
2624
+ * Per-series x values from `c:ser/c:xVal` (scatter and bubble series only).
2625
+ *
2626
+ * Every `CT_ScatterSer` / `CT_BubbleSer` carries its OWN `c:xVal`, so two
2627
+ * series in one scatter chart routinely plot against different x ranges (the
2628
+ * normal case for measurement data). Reading the x values off the first
2629
+ * series and reusing them everywhere plotted every series against series 1's
2630
+ * x axis. Absent for category-axis chart kinds, where
2631
+ * {@link PptxChartData.categories} is the x axis.
2632
+ */
2633
+ xValues?: number[];
2634
+ /**
2635
+ * Per-series bubble sizes from `c:ser/c:bubbleSize` (bubble series only),
2636
+ * aligned index-for-index with {@link values}.
2637
+ *
2638
+ * `CT_BubbleSer` carries x, y AND size, so a one-series bubble chart is fully
2639
+ * specified. Absent when the source omits `c:bubbleSize`.
2640
+ */
2641
+ bubbleSizes?: number[];
2642
+ /**
2643
+ * Series-level data-label content flags from `c:ser/c:dLbls`.
2644
+ *
2645
+ * PowerPoint writes the flags a user picks in "Format Data Labels" onto the
2646
+ * SERIES, and leaves the chart-type-level `c:dLbls` all-zero, so reading only
2647
+ * the chart-level group reports "show nothing" for a chart that visibly shows
2648
+ * percentages. These override {@link PptxChartStyle.dataLabels}.
2649
+ */
2650
+ dataLabelOptions?: PptxChartDataLabelOptions;
2651
+ /**
2652
+ * Whether the series line is explicitly suppressed
2653
+ * (`c:ser/c:spPr/a:ln/a:noFill`). Line-drawn kinds (line, scatter, radar)
2654
+ * use this to decide whether to draw a connecting line at all; a marker-only
2655
+ * scatter is authored as `scatterStyle="lineMarker"` PLUS this flag, never by
2656
+ * changing the scatter style.
2657
+ */
2658
+ lineNoFill?: boolean;
2504
2659
  /**
2505
2660
  * Blank-value mask aligned index-for-index with {@link values}: `true` marks
2506
2661
  * a category whose numeric cache point (`c:numCache/c:pt`) was absent or
@@ -2844,6 +2999,17 @@ interface PptxChartData {
2844
2999
  * default), so only horizontal bar charts need to carry the field.
2845
3000
  */
2846
3001
  barDirection?: PptxChartBarDirection;
3002
+ /**
3003
+ * Scatter presentation mode (`c:scatterChart/c:scatterStyle/@val`).
3004
+ *
3005
+ * `lineMarker` (PowerPoint's own default for every scatter it writes) and
3006
+ * `smoothMarker` draw a connecting line; `marker` and `none` do not. Whether
3007
+ * the MARKERS appear is decided separately by `c:marker/c:symbol`, and
3008
+ * whether the LINE appears is further gated by
3009
+ * {@link PptxChartSeries.lineNoFill} - PowerPoint expresses "markers only" as
3010
+ * `lineMarker` plus an `a:ln/a:noFill`, not as `marker`.
3011
+ */
3012
+ scatterStyle?: PptxChartScatterStyle;
2847
3013
  /**
2848
3014
  * Bar/column gap between category clusters as a percentage of bar width
2849
3015
  * (`c:gapWidth/@val`, 0 through 500). Absent uses the renderer default.
@@ -2997,6 +3163,53 @@ interface PptxChartData {
2997
3163
  * // => { brightness: 20, contrast: -10, grayscale: true } satisfies PptxImageEffects
2998
3164
  * ```
2999
3165
  */
3166
+ /**
3167
+ * One `a14:foregroundMark` / `a14:backgroundMark` polyline hint recorded while
3168
+ * the user painted over the picture in PowerPoint's "Remove Background" mode.
3169
+ * Coordinates are 0..1 fractions of the image.
3170
+ */
3171
+ interface PptxBackgroundRemovalMark {
3172
+ x1: number;
3173
+ y1: number;
3174
+ x2: number;
3175
+ y2: number;
3176
+ }
3177
+ /**
3178
+ * PowerPoint "Remove Background" state (`a14:backgroundRemoval`).
3179
+ *
3180
+ * The four edges are the RETAINED rectangle as 0..1 fractions of the image
3181
+ * (OOXML stores them as per-100000 relative units), and the mark lists are the
3182
+ * segmentation hints the user painted.
3183
+ *
3184
+ * **This is edit-time metadata, not a render instruction.** PowerPoint bakes the
3185
+ * removal into the bitmap referenced by the main `a:blip/@r:embed` and keeps the
3186
+ * pristine original in `a14:imgLayer/@r:embed`. Verified against PowerPoint COM:
3187
+ * a slide exported with and without this element is byte-identical. A renderer
3188
+ * that clips to the retained rectangle would clip an image whose background has
3189
+ * already been removed.
3190
+ *
3191
+ * @example
3192
+ * ```ts
3193
+ * const removal: PptxBackgroundRemoval = { top: 0.12, bottom: 0.88, left: 0.07, right: 0.93 };
3194
+ * // => retains the middle of the image; the marks list stays empty
3195
+ * ```
3196
+ */
3197
+ interface PptxBackgroundRemoval {
3198
+ /** Top edge of the retained rectangle (0..1 fraction of the image height). */
3199
+ top: number;
3200
+ /** Bottom edge of the retained rectangle (0..1 fraction of the image height). */
3201
+ bottom: number;
3202
+ /** Left edge of the retained rectangle (0..1 fraction of the image width). */
3203
+ left: number;
3204
+ /** Right edge of the retained rectangle (0..1 fraction of the image width). */
3205
+ right: number;
3206
+ /** Strokes marking regions the user forced to be foreground. */
3207
+ foregroundMarks?: PptxBackgroundRemovalMark[];
3208
+ /** Strokes marking regions the user forced to be background. */
3209
+ backgroundMarks?: PptxBackgroundRemovalMark[];
3210
+ /** Original effect XML, retained for lossless re-emission. */
3211
+ rawXml?: XmlObject;
3212
+ }
3000
3213
  interface PptxImageEffects {
3001
3214
  /** Brightness adjustment (-100 to 100). */
3002
3215
  brightness?: number;
@@ -3020,8 +3233,38 @@ interface PptxImageEffects {
3020
3233
  };
3021
3234
  /** Artistic effect name (blur, pencilGrayscale, paintStrokes, etc.). */
3022
3235
  artisticEffect?: string;
3023
- /** Artistic effect radius/amount. */
3236
+ /** Artistic effect radius/amount, normalised to 0..100. */
3024
3237
  artisticRadius?: number;
3238
+ /**
3239
+ * Every numeric attribute of the source `a14:artistic*` element, raw and
3240
+ * un-normalised (`trans`, `pencilSize`, `crackSpacing`, …). The attribute set
3241
+ * differs per effect, so this is the lossless companion to the single
3242
+ * {@link PptxImageEffects.artisticRadius} number.
3243
+ */
3244
+ artisticParams?: Record<string, number>;
3245
+ /**
3246
+ * Name of the artistic effect ALREADY baked into the image data, which a
3247
+ * renderer must not apply a second time. Set from the `a14` blip extension,
3248
+ * which PowerPoint writes alongside a pre-rendered bitmap (see
3249
+ * {@link PptxBackgroundRemoval}), and normally equal to
3250
+ * {@link PptxImageEffects.artisticEffect}.
3251
+ *
3252
+ * It records the NAME rather than a boolean so that picking a different
3253
+ * effect in this library's inspector (which patches `artisticEffect` alone)
3254
+ * still renders: the two names then differ.
3255
+ */
3256
+ artisticPrerenderedEffect?: string;
3257
+ /**
3258
+ * PowerPoint "Remove Background" state (`a14:backgroundRemoval`). Edit-time
3259
+ * metadata: the removal is already baked into the image data.
3260
+ */
3261
+ backgroundRemoval?: PptxBackgroundRemoval;
3262
+ /**
3263
+ * `a14:imgLayer/@r:embed` — relationship id of the PRISTINE original image
3264
+ * the baked effects were derived from (PowerPoint stores it as an HD Photo
3265
+ * `.wdp` part, which browsers cannot decode).
3266
+ */
3267
+ originalImageRelId?: string;
3025
3268
  /** Alpha modulation fixed: non-negative percentage (100 means unchanged opacity). */
3026
3269
  alphaModFix?: number;
3027
3270
  /** Original alpha modulation fixed node, including foreign attributes. */
@@ -3937,6 +4180,11 @@ interface PptxTableCellStyle {
3937
4180
  italic?: boolean;
3938
4181
  underline?: boolean;
3939
4182
  color?: string;
4183
+ /**
4184
+ * Font family from the first run's `a:rPr/a:latin@typeface` (falling back to
4185
+ * `a:ea` / `a:cs`). Per-run families live on {@link PptxTableCellTextRun}.
4186
+ */
4187
+ fontFamily?: string;
3940
4188
  /**
3941
4189
  * Raw XML colour-choice node preserved from `a:tc/a:txBody/.../a:rPr/a:solidFill`
3942
4190
  * for round-trip serialisation. Currently unused by the cell-level writer
@@ -4092,6 +4340,45 @@ interface PptxTableCell3D {
4092
4340
  /** Light rig direction (`a:lightRig@dir`, e.g. `tl`, `t`, `tr`). */
4093
4341
  lightRigDirection?: string;
4094
4342
  }
4343
+ /**
4344
+ * One styled text run inside a table cell's `a:txBody`.
4345
+ *
4346
+ * `PptxTableCell.text` is a flat string and `PptxTableCell.style` describes
4347
+ * only the FIRST run, so a cell mixing formats ("Revenue **grew 42%** last
4348
+ * year") cannot be represented by those two alone. {@link PptxTableCell.runs}
4349
+ * carries the full sequence, with paragraph and line breaks as marker entries
4350
+ * so a renderer can walk it linearly.
4351
+ *
4352
+ * Structurally identical to `pptx-viewer-shared`'s `CellTextRun`, which every
4353
+ * binding's table renderer already consumes.
4354
+ *
4355
+ * @example
4356
+ * ```ts
4357
+ * const runs: PptxTableCellTextRun[] = [
4358
+ * { text: "Revenue " },
4359
+ * { text: "grew 42%", bold: true, color: "#C00000" },
4360
+ * ];
4361
+ * // => satisfies PptxTableCellTextRun[]
4362
+ * ```
4363
+ */
4364
+ interface PptxTableCellTextRun {
4365
+ /** Run text. Empty for the break markers below. */
4366
+ text: string;
4367
+ /** This entry starts a new paragraph (`a:p` boundary) rather than carrying text. */
4368
+ isParagraphBreak?: boolean;
4369
+ /** This entry is a soft line break (`a:br`) rather than carrying text. */
4370
+ isLineBreak?: boolean;
4371
+ bold?: boolean;
4372
+ italic?: boolean;
4373
+ underline?: boolean;
4374
+ strikethrough?: boolean;
4375
+ /** Resolved run colour as a CSS colour string. */
4376
+ color?: string;
4377
+ /** Run font size in points (`a:rPr@sz` / 100). */
4378
+ fontSize?: number;
4379
+ /** Run font family from `a:rPr/a:latin@typeface` (or `a:ea` / `a:cs`). */
4380
+ fontFamily?: string;
4381
+ }
4095
4382
  /**
4096
4383
  * A single table cell with text content, optional style, and merge info.
4097
4384
  *
@@ -4108,6 +4395,15 @@ interface PptxTableCell3D {
4108
4395
  interface PptxTableCell {
4109
4396
  text: string;
4110
4397
  style?: PptxTableCellStyle;
4398
+ /**
4399
+ * Per-run formatting for the cell's text, when it has any beyond what
4400
+ * {@link style} can express. Present only for cells whose `a:txBody`
4401
+ * actually carries runs; renderers fall back to {@link text} when absent.
4402
+ *
4403
+ * Editing a cell's text invalidates these (the editor produces a plain
4404
+ * string), so an edit path must clear them alongside setting `text`.
4405
+ */
4406
+ textRuns?: PptxTableCellTextRun[];
4111
4407
  /** Column span (defaults to 1). */
4112
4408
  gridSpan?: number;
4113
4409
  /** Row span (defaults to 1). */
@@ -4880,13 +5176,42 @@ interface UnknownPptxElement extends PptxElementBase {
4880
5176
  /**
4881
5177
  * A single element on a PPTX slide.
4882
5178
  *
4883
- * This is a **discriminated union** narrow on `element.type` to access
5179
+ * This is a **discriminated union**: narrow on `element.type` to access
4884
5180
  * variant-specific properties like `imageData` (image/picture), `pathData`
4885
5181
  * (shape), or `textSegments` (text/shape).
4886
5182
  */
4887
5183
  type PptxElement = TextPptxElement | ShapePptxElement | ConnectorPptxElement | ImagePptxElement | PicturePptxElement | TablePptxElement | ChartPptxElement | SmartArtPptxElement | OlePptxElement | MediaPptxElement | GroupPptxElement | InkPptxElement | ContentPartPptxElement | ZoomPptxElement | Model3DPptxElement | UnknownPptxElement;
4888
5184
  //#endregion
4889
5185
  //#region src/core/types/masters.d.ts
5186
+ /**
5187
+ * A placeholder slot declared on a master or layout.
5188
+ *
5189
+ * The geometry fields are in CSS pixels (EMU / {@link EMU_PER_PX}) and are only
5190
+ * present when the shape carried an explicit `a:xfrm`. Placeholders that
5191
+ * inherit their frame from the master leave them undefined, so consumers that
5192
+ * draw placeholder outlines (the layout gallery) must skip those entries
5193
+ * rather than assume a zero-sized box at the origin.
5194
+ *
5195
+ * @example
5196
+ * ```ts
5197
+ * const frame: PptxPlaceholderFrame = { type: "body", idx: "1", x: 63, y: 130 };
5198
+ * // => satisfies PptxPlaceholderFrame
5199
+ * ```
5200
+ */
5201
+ interface PptxPlaceholderFrame {
5202
+ /** `p:ph/@type`, lower-cased by the parser; defaults to `body` when omitted. */
5203
+ type: string;
5204
+ /** `p:ph/@idx`, when present. */
5205
+ idx?: string;
5206
+ /** Left offset in CSS pixels, when the shape declares `a:off`. */
5207
+ x?: number;
5208
+ /** Top offset in CSS pixels, when the shape declares `a:off`. */
5209
+ y?: number;
5210
+ /** Width in CSS pixels, when the shape declares `a:ext`. */
5211
+ width?: number;
5212
+ /** Height in CSS pixels, when the shape declares `a:ext`. */
5213
+ height?: number;
5214
+ }
4890
5215
  /**
4891
5216
  * Parsed notes master from `ppt/notesMasters/notesMaster1.xml`.
4892
5217
  *
@@ -4908,10 +5233,7 @@ interface PptxNotesMaster {
4908
5233
  /** Background image data URL. */
4909
5234
  backgroundImage?: string;
4910
5235
  /** Placeholder shapes found on the notes master. */
4911
- placeholders?: Array<{
4912
- type: string;
4913
- idx?: string;
4914
- }>;
5236
+ placeholders?: PptxPlaceholderFrame[];
4915
5237
  /** Editable elements on the notes master (header, footer, date, page number, slide image, notes body). */
4916
5238
  elements?: PptxElement[];
4917
5239
  /** Header/footer flags from `<p:hf>` on the notes master (P-H3). */
@@ -4939,10 +5261,7 @@ interface PptxHandoutMaster {
4939
5261
  /** Background image data URL. */
4940
5262
  backgroundImage?: string;
4941
5263
  /** Placeholder shapes found on the handout master. */
4942
- placeholders?: Array<{
4943
- type: string;
4944
- idx?: string;
4945
- }>;
5264
+ placeholders?: PptxPlaceholderFrame[];
4946
5265
  /** Editable elements on the handout master (header, footer, date, page number, slide placeholders). */
4947
5266
  elements?: PptxElement[];
4948
5267
  /** Number of slides per page for handout print layout (1, 2, 3, 4, 6, or 9). */
@@ -4980,10 +5299,7 @@ interface PptxSlideMaster {
4980
5299
  /** Layout paths associated with this master. */
4981
5300
  layoutPaths?: string[];
4982
5301
  /** Placeholder shapes on the master. */
4983
- placeholders?: Array<{
4984
- type: string;
4985
- idx?: string;
4986
- }>;
5302
+ placeholders?: PptxPlaceholderFrame[];
4987
5303
  /** Parsed element shapes on the master slide (for master view rendering). */
4988
5304
  elements?: PptxElement[];
4989
5305
  /** Parsed slide layout objects associated with this master. */
@@ -5055,10 +5371,7 @@ interface PptxSlideLayout {
5055
5371
  /** Parsed element shapes on the layout. */
5056
5372
  elements?: PptxElement[];
5057
5373
  /** Placeholder shapes on the layout. */
5058
- placeholders?: Array<{
5059
- type: string;
5060
- idx?: string;
5061
- }>;
5374
+ placeholders?: PptxPlaceholderFrame[];
5062
5375
  /** Matching name attribute for layout identification (`@matchingName`). */
5063
5376
  matchingName?: string;
5064
5377
  /** Whether the layout is marked as preserved (prevent deletion, `@preserve`). */
@@ -5072,6 +5385,42 @@ interface PptxSlideLayout {
5072
5385
  /** Header/footer flags from `<p:hf>` on this layout (P-H3). */
5073
5386
  headerFooter?: PptxHeaderFooterFlags;
5074
5387
  }
5388
+ /**
5389
+ * Rendered content of a single layout, used to draw gallery thumbnails.
5390
+ *
5391
+ * Produced on demand rather than during load: materialising every layout's
5392
+ * artwork (and decoding its images) up front costs a noticeable amount of time
5393
+ * on decks with many masters, and most sessions never open the layout gallery
5394
+ * at all.
5395
+ *
5396
+ * @example
5397
+ * ```ts
5398
+ * const preview: PptxLayoutPreview = {
5399
+ * path: "ppt/slideLayouts/slideLayout2.xml",
5400
+ * width: 960,
5401
+ * height: 540,
5402
+ * elements: [],
5403
+ * placeholders: [{ type: "title" }],
5404
+ * };
5405
+ * // => satisfies PptxLayoutPreview
5406
+ * ```
5407
+ */
5408
+ interface PptxLayoutPreview {
5409
+ /** ZIP path of the layout this preview belongs to. */
5410
+ path: string;
5411
+ /** Slide width in CSS pixels, so a thumbnail can compute its own scale. */
5412
+ width: number;
5413
+ /** Slide height in CSS pixels. */
5414
+ height: number;
5415
+ /** Background resolved from the layout, falling back to its master's. */
5416
+ backgroundColor?: string;
5417
+ /** Background image data URL, when the layout or master declares one. */
5418
+ backgroundImage?: string;
5419
+ /** The layout's own artwork (pictures, shapes and static text). */
5420
+ elements: PptxElement[];
5421
+ /** Placeholder slots, drawn as outlined frames in the gallery. */
5422
+ placeholders: PptxPlaceholderFrame[];
5423
+ }
5075
5424
  /**
5076
5425
  * A theme part available in the presentation package.
5077
5426
  *
@@ -5560,6 +5909,54 @@ interface PptxEmbeddedFontList {
5560
5909
  rawXml?: XmlObject;
5561
5910
  }
5562
5911
  //#endregion
5912
+ //#region src/core/types/comment-mentions.d.ts
5913
+ /**
5914
+ * A single `@`-mention inside a modern comment body.
5915
+ *
5916
+ * Offsets index into the comment's FLATTENED plain text: every `a:t` value
5917
+ * below `p188:txBody` concatenated, with paragraphs joined by `\n`. That is the
5918
+ * same string `PptxComment.text` carries, so an edit to `text` invalidates
5919
+ * every offset after the edit point and the serializer re-bases them.
5920
+ *
5921
+ * The markup Office uses for a mention is `CT_Mention` (documented for the
5922
+ * SpreadsheetML `2018/threadedcomments` part): `mentionpersonId`, `mentionId`,
5923
+ * `startIndex` and `length`. The PowerPoint `2018/8/main` schema does not
5924
+ * publish a mention element at all, so `rawXml` is retained and re-emitted
5925
+ * attribute-for-attribute: a producer that spells the attributes differently
5926
+ * still round-trips.
5927
+ *
5928
+ * @example
5929
+ * ```ts
5930
+ * const mention: PptxCommentMention = {
5931
+ * personId: "{2CB2E9D0-D392-EB21-5D46-FBA34C1295E6}",
5932
+ * authorName: "Bob Example",
5933
+ * startIndex: 3,
5934
+ * length: 11,
5935
+ * };
5936
+ * // => "Hi Bob Example can you check this".slice(3, 14) === "Bob Example"
5937
+ * ```
5938
+ */
5939
+ interface PptxCommentMention {
5940
+ /** `mentionId`: GUID identifying this mention instance. */
5941
+ id?: string;
5942
+ /** `mentionpersonId`: the `p188:author` id of the mentioned person. */
5943
+ personId: string;
5944
+ /** Display name resolved from the author list at parse time, when known. */
5945
+ authorName?: string;
5946
+ /** Character offset of the mentioned span in the flattened plain text. */
5947
+ startIndex: number;
5948
+ /** Character length of the mentioned span. */
5949
+ length: number;
5950
+ /**
5951
+ * `uri` of the `p188:ext` this mention list was read from. Undefined means
5952
+ * the list is a direct child of `p188:cm`, which is where it is written for
5953
+ * newly authored mentions.
5954
+ */
5955
+ containerUri?: string;
5956
+ /** Original `p188:mention` node, retained for unknown-attribute preservation. */
5957
+ rawXml?: XmlObject;
5958
+ }
5959
+ //#endregion
5563
5960
  //#region src/core/types/metadata.d.ts
5564
5961
  /**
5565
5962
  * A slide comment — may be a legacy positional comment or a modern
@@ -5606,6 +6003,8 @@ interface PptxComment {
5606
6003
  title?: string;
5607
6004
  /** Modern threaded comment support (p15:threadingInfo). */
5608
6005
  threadId?: string;
6006
+ /** `@`-mentions, indexed into `text` (see {@link PptxCommentMention}). */
6007
+ mentions?: PptxCommentMention[];
5609
6008
  /** Replies to this comment (for modern threaded comments). */
5610
6009
  replies?: PptxComment[];
5611
6010
  /** ID of the element this comment is associated with (if any). */
@@ -6125,7 +6524,7 @@ interface PptxTheme {
6125
6524
  * // => "morph" — one of 40+ transition effects
6126
6525
  * ```
6127
6526
  */
6128
- 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';
6527
+ 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';
6129
6528
  /** Split orientation from OOXML `@_orient`. */
6130
6529
  type PptxSplitOrientation = 'horz' | 'vert';
6131
6530
  /** Schema-defined `ST_TransitionSpeed` values. */
@@ -6420,6 +6819,18 @@ interface PptxSlideBackgroundPattern {
6420
6819
  interface PptxSlide {
6421
6820
  id: string;
6422
6821
  rId: string;
6822
+ /**
6823
+ * `p:sldIdLst/p:sldId/@id` (ST_SlideId, 256..2147483647): the numeric key
6824
+ * that sections (`p14:sldIdLst/p14:sldId/@id`) and section/summary zooms
6825
+ * name slides by.
6826
+ *
6827
+ * It lives in `presentation.xml`, NOT in the slide part, so it cannot be
6828
+ * recovered from `rawXml`. Without it on the model, code that writes a
6829
+ * section's membership has nothing correct to write and falls back to the
6830
+ * slide NUMBER, which is 1-based and therefore never matches a real deck's
6831
+ * ids: the section reloads with no slides in it.
6832
+ */
6833
+ slideId?: string;
6423
6834
  sourceSlideId?: string;
6424
6835
  /** Optional author-supplied slide name (set via `SlideBuilder.setName`). */
6425
6836
  name?: string;
@@ -6622,6 +7033,26 @@ interface PptxPresentationProperties {
6622
7033
  /** Kiosk auto-restart interval in milliseconds (from `p:kiosk/@restart`). Only meaningful when showType is "kiosk". */
6623
7034
  kioskRestartTime?: number;
6624
7035
  }
7036
+ /**
7037
+ * Slide dimensions from `p:sldSz` (CT_SlideSize, ECMA-376 §19.2.1.39).
7038
+ *
7039
+ * @example
7040
+ * ```ts
7041
+ * const size: PptxSlideSize = { widthEmu: 9144000, heightEmu: 6858000, type: 'screen4x3' };
7042
+ * // => satisfies PptxSlideSize
7043
+ * ```
7044
+ */
7045
+ interface PptxSlideSize {
7046
+ /** `@cx` in EMU. Omitted or non-positive values leave the loaded width alone. */
7047
+ widthEmu?: number;
7048
+ /** `@cy` in EMU. Omitted or non-positive values leave the loaded height alone. */
7049
+ heightEmu?: number;
7050
+ /**
7051
+ * `@type` (ST_SlideSizeType). The schema default is `custom`, which is
7052
+ * why PowerPoint omits the attribute for a non-preset size.
7053
+ */
7054
+ type?: string;
7055
+ }
6625
7056
  /**
6626
7057
  * A named custom slide show (`p:custShowLst / p:custShow`).
6627
7058
  *
@@ -7636,6 +8067,19 @@ interface PptxHandlerSaveOptions {
7636
8067
  customerData?: PptxCustomerData[];
7637
8068
  /** Photo album metadata to save back to `p:photoAlbum`. */
7638
8069
  photoAlbum?: PptxPhotoAlbum;
8070
+ /**
8071
+ * Slide dimensions to write back to `p:sldSz`.
8072
+ *
8073
+ * Omitting the option preserves the load-time dimensions verbatim, which
8074
+ * is why an edit made through a viewer's Slide Size control has to reach
8075
+ * the save call: nothing else in the pipeline can observe it.
8076
+ *
8077
+ * PowerPoint derives `Presentation.PageSetup.SlideSize` from `@cx`/`@cy`
8078
+ * alone (verified by COM: an A4-typed `p:sldSz` carrying 4:3 dimensions
8079
+ * still reports `ppSlideSizeCustom`), so `type` is written for fidelity
8080
+ * but the dimensions are what actually decide the reported preset.
8081
+ */
8082
+ slideSize?: PptxSlideSize;
7639
8083
  /** East Asian line-break settings to save back to `p:kinsoku`. */
7640
8084
  kinsoku?: PptxKinsoku | null;
7641
8085
  /** Write-protection verifier. Set to `null` to remove, `undefined` to preserve existing. */
@@ -7691,6 +8135,8 @@ interface IPptxHandlerRuntime {
7691
8135
  revokeBlobUrls(): void;
7692
8136
  getCompatibilityWarnings(): PptxCompatibilityWarning[];
7693
8137
  getLayoutOptions(): PptxLayoutOption[];
8138
+ getLayoutPreview(layoutPath: string): Promise<PptxLayoutPreview | null>;
8139
+ getLayoutPreviews(layoutPaths?: readonly string[]): Promise<PptxLayoutPreview[]>;
7694
8140
  createXmlBuilder(data: PptxData): PptxXmlBuilder;
7695
8141
  Builder(data: PptxData): PptxXmlBuilder;
7696
8142
  setTemplateBackground(path: string, backgroundColor: string | undefined): void;
@@ -7879,6 +8325,26 @@ declare class PptxHandlerCore {
7879
8325
  * @returns Array of {@link PptxLayoutOption} entries.
7880
8326
  */
7881
8327
  getLayoutOptions(): PptxLayoutOption[];
8328
+ /**
8329
+ * Build the artwork thumbnails backing the New Slide / Layout galleries.
8330
+ *
8331
+ * Parsing happens on first request and is memoised afterwards, so opening
8332
+ * the gallery costs one pass over the layout parts and reopening it costs
8333
+ * nothing. Callers that only need one entry should prefer
8334
+ * {@link getLayoutPreview}.
8335
+ *
8336
+ * @param layoutPaths - Restrict the result to these layouts; defaults to
8337
+ * every layout in the presentation.
8338
+ * @returns One {@link PptxLayoutPreview} per resolvable layout.
8339
+ */
8340
+ getLayoutPreviews(layoutPaths?: readonly string[]): Promise<PptxLayoutPreview[]>;
8341
+ /**
8342
+ * Build the artwork thumbnail for a single layout.
8343
+ *
8344
+ * @param layoutPath - Archive path of the `p:sldLayout` part.
8345
+ * @returns The preview, or `null` when the presentation has no such layout.
8346
+ */
8347
+ getLayoutPreview(layoutPath: string): Promise<PptxLayoutPreview | null>;
7882
8348
  /**
7883
8349
  * Create a fluent XML builder scoped to the given presentation data.
7884
8350
  *
@@ -8205,24 +8671,38 @@ declare class PptxHandlerCore {
8205
8671
  name?: string;
8206
8672
  }>>;
8207
8673
  /**
8208
- * Export selected slides as individual PPTX files.
8674
+ * Export selected slides to a vector or raster format, keyed by slide index.
8675
+ *
8676
+ * **This does not produce PPTX files.** The previous version of this comment
8677
+ * said each entry was "a standalone PPTX with only that slide", named the
8678
+ * option `slideIndexes` (the real field is `slideIndices`), and wrote the
8679
+ * bytes to `slide_N.pptx`. None of that was ever true: the runtime has
8680
+ * always taken a `format` of `svg` / `png` / `pdf`. Per-slide PPTX
8681
+ * extraction is a different operation and is not implemented here.
8209
8682
  *
8210
- * Each entry in the returned map is keyed by slide index and contains a
8211
- * standalone `Uint8Array` PPTX with only that slide.
8683
+ * Only `svg` works without a host-supplied backend, and it works fully:
8684
+ * the headless {@link SvgExporter} renders it with no DOM. `png` and `pdf`
8685
+ * THROW, because this package carries no rasteriser; use a viewer binding's
8686
+ * browser export pipeline, or override `exportSlides` on the runtime with
8687
+ * your own backend.
8212
8688
  *
8213
8689
  * @param slides - Full slide array.
8214
- * @param options - Export options (slide indexes, format, etc.).
8215
- * @returns A `Map<slideIndex, Uint8Array>` of exported files.
8690
+ * @param options - Export options (`format`, `slideIndices`, `width`, ...).
8691
+ * @returns A `Map<slideIndex, Uint8Array>` of exported files. Hidden slides
8692
+ * are omitted unless `options.includeHidden` is set, so the map can be
8693
+ * smaller than `options.slideIndices`.
8694
+ * @throws {Error} when `options.format` is `png` or `pdf`.
8216
8695
  *
8217
8696
  * @example
8218
8697
  * ```ts
8219
8698
  * const exports = await handler.exportSlides(data.slides, {
8220
- * slideIndexes: [0, 2],
8699
+ * format: 'svg',
8700
+ * slideIndices: [0, 2],
8221
8701
  * });
8222
8702
  * for (const [idx, bytes] of exports) {
8223
- * await fs.writeFile(`slide_${idx}.pptx`, Buffer.from(bytes));
8703
+ * await fs.writeFile(`slide_${idx}.svg`, Buffer.from(bytes));
8224
8704
  * }
8225
- * // => Map<number, Uint8Array> one standalone .pptx per exported slide
8705
+ * // => Map<number, Uint8Array>: one SVG document per exported slide
8226
8706
  * ```
8227
8707
  */
8228
8708
  exportSlides(slides: PptxSlide[], options: PptxExportOptions): Promise<Map<number, Uint8Array>>;
@@ -8572,6 +9052,91 @@ interface CollaborationConfig {
8572
9052
  */
8573
9053
  writeBackDebounceMs?: number;
8574
9054
  }
9055
+ //#endregion
9056
+ //#region src/render/shape-adjustment-model.d.ts
9057
+ /**
9058
+ * `shape-adjustment-model`: the vocabulary the adjust-handle modules share.
9059
+ *
9060
+ * The `a:ahLst` work is split three ways for the repo's file-size budget:
9061
+ * `shape-adjustment-probe` measures the geometry, `shape-adjustment-handles`
9062
+ * derives the handles from those measurements, and `shape-adjustment-solver`
9063
+ * turns a pointer position back into guide values. All three need these types
9064
+ * and the one rule that operates purely on them, so they live here and the
9065
+ * dependency graph stays a DAG rather than a cycle.
9066
+ *
9067
+ * @module render/shape-adjustment-model
9068
+ */
9069
+ /**
9070
+ * How a pointer position becomes a guide value, captured once when the gesture
9071
+ * starts so `pointermove` stays pure arithmetic.
9072
+ */
9073
+ interface ShapeAdjustmentSolver {
9074
+ /** `linear`: the handle slides. `angular`: it swings about {@link centerX}. */
9075
+ kind: 'linear' | 'angular';
9076
+ /** Handle position in element-local px at {@link startValue}. */
9077
+ anchorX: number;
9078
+ anchorY: number;
9079
+ /** Element-local px the handle travels per ONE unit of guide value. */
9080
+ dirX: number;
9081
+ dirY: number;
9082
+ /** Pivot for an angular handle (the shape centre). */
9083
+ centerX: number;
9084
+ centerY: number;
9085
+ /** The guide value the anchor was measured at. */
9086
+ startValue: number;
9087
+ /** Guide-space bounds, taken from the preset's own `pin` clamp. */
9088
+ min: number;
9089
+ max: number;
9090
+ }
9091
+ /** One guide a handle drives. */
9092
+ interface AdjustmentAxisSolver {
9093
+ key: string;
9094
+ solver: ShapeAdjustmentSolver;
9095
+ }
9096
+ /** Descriptor for one draggable adjustment handle (the amber diamond). */
9097
+ interface ShapeAdjustmentHandleDescriptor {
9098
+ /** The `a:avLst` guide name this handle writes (`adj`, `adj1`, ...). */
9099
+ key: string;
9100
+ /** Handle x offset in element-local px (origin = element top-left). */
9101
+ left: number;
9102
+ /** Handle y offset in element-local px. */
9103
+ top: number;
9104
+ /**
9105
+ * Current adjustment value in GUIDE units, not a 0-1 fraction. Most presets
9106
+ * range 0..50000 or 0..100000 and the angular ones run to 21,600,000.
9107
+ */
9108
+ value: number;
9109
+ cursor: string;
9110
+ /**
9111
+ * How this handle's drag resolves, measured off the preset geometry: one
9112
+ * entry per `a:avLst` guide it drives (callouts drive two). Absent only for
9113
+ * a caller that built a descriptor by hand.
9114
+ */
9115
+ solvers?: AdjustmentAxisSolver[];
9116
+ }
9117
+ /** Live drag state captured when an adjustment gesture starts. */
9118
+ interface ShapeAdjustmentDragState {
9119
+ elementId: string;
9120
+ key: string;
9121
+ shapeType: string;
9122
+ startClientX: number;
9123
+ startClientY: number;
9124
+ startAdjustment: number;
9125
+ startWidth: number;
9126
+ startHeight: number;
9127
+ moved: boolean;
9128
+ /** Copied from the descriptor the gesture started on. */
9129
+ solvers?: AdjustmentAxisSolver[];
9130
+ /**
9131
+ * The element's whole `a:avLst` map at gesture start.
9132
+ *
9133
+ * A binding writes `shapeAdjustments` as one object, so a drag that sent
9134
+ * only the guide it changed would DELETE every other authored adjustment on
9135
+ * a multi-adjust preset (a `quadArrow` would lose two of its three the first
9136
+ * time one was touched).
9137
+ */
9138
+ startAdjustments?: Record<string, number>;
9139
+ }
8575
9140
  /**
8576
9141
  * A font supplied by the host application. The package never ships fonts:
8577
9142
  * applications provide a licensed URL, data URL, or blob URL for their users.
@@ -8793,34 +9358,6 @@ interface ResizeState {
8793
9358
  lastWidth: number;
8794
9359
  lastHeight: number;
8795
9360
  }
8796
- /**
8797
- * Describes the position and value of a shape adjustment handle (yellow diamond).
8798
- * Adjustment handles allow users to modify shape parameters like corner radius,
8799
- * arrow width, etc. without a full resize.
8800
- */
8801
- interface ShapeAdjustmentHandleDescriptor {
8802
- key: string;
8803
- left: number;
8804
- top: number;
8805
- value: number;
8806
- cursor: string;
8807
- }
8808
- /**
8809
- * Tracks the state of an ongoing shape adjustment handle drag.
8810
- * Used when the user drags the yellow diamond handle to alter
8811
- * shape-specific parameters (e.g. corner radius on a rounded rectangle).
8812
- */
8813
- interface ShapeAdjustmentDragState {
8814
- elementId: string;
8815
- key: string;
8816
- shapeType: string;
8817
- startClientX: number;
8818
- startClientY: number;
8819
- startAdjustment: number;
8820
- startWidth: number;
8821
- startHeight: number;
8822
- moved: boolean;
8823
- }
8824
9361
  /**
8825
9362
  * A snapshot of editor state captured for undo/redo history.
8826
9363
  * Contains the full slide deck state at a point in time so that