@shbernal/ts-pptx 3.5.0 → 3.7.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 (67) hide show
  1. package/README.md +8 -0
  2. package/dist/{autopage-BYlTzX-l.js → autopage-DkjYZUFD.js} +3 -3
  3. package/dist/{autopage-BYlTzX-l.js.map → autopage-DkjYZUFD.js.map} +1 -1
  4. package/dist/browser.d.ts +5 -5
  5. package/dist/browser.js +4 -4
  6. package/dist/browser.js.map +1 -1
  7. package/dist/{diagnostics-BDuR8UkG.d.ts → diagnostics-DfBdDHre.d.ts} +20 -5
  8. package/dist/diagnostics-DfBdDHre.d.ts.map +1 -0
  9. package/dist/{errors-CgnueTYL.d.ts → errors-PflMPWBn.d.ts} +2 -2
  10. package/dist/{errors-CgnueTYL.d.ts.map → errors-PflMPWBn.d.ts.map} +1 -1
  11. package/dist/{fit-TjpNbMru.js → fit-BKs0zxMI.js} +3 -3
  12. package/dist/{fit-TjpNbMru.js.map → fit-BKs0zxMI.js.map} +1 -1
  13. package/dist/{html-dom-yUSdCExA.js → html-dom-B0I0QSbU.js} +4 -4
  14. package/dist/{html-dom-yUSdCExA.js.map → html-dom-B0I0QSbU.js.map} +1 -1
  15. package/dist/html.d.ts +3 -3
  16. package/dist/html.js +1 -1
  17. package/dist/index.d.ts +5 -5
  18. package/dist/index.js +3 -3
  19. package/dist/inspect.d.ts +1 -1
  20. package/dist/inspect.js +4 -5
  21. package/dist/inspect.js.map +1 -1
  22. package/dist/math.d.ts +1 -1
  23. package/dist/measure.d.ts +2 -2
  24. package/dist/measure.js +1 -1
  25. package/dist/{namespaces-CcKuzeuE.js → namespaces-BVnNu7sg.js} +74 -3
  26. package/dist/namespaces-BVnNu7sg.js.map +1 -0
  27. package/dist/node.d.ts +5 -5
  28. package/dist/node.js +3 -3
  29. package/dist/{notes-DNqAggXx.js → notes-CJFJaG6M.js} +310 -313
  30. package/dist/notes-CJFJaG6M.js.map +1 -0
  31. package/dist/{pres-Dybf7ZUl.d.ts → pres-BcBR3CSM.d.ts} +2 -2
  32. package/dist/{pres-Dybf7ZUl.d.ts.map → pres-BcBR3CSM.d.ts.map} +1 -1
  33. package/dist/{presentation-VfJ_FT7E.js → presentation-DrJtj3-C.js} +414 -515
  34. package/dist/presentation-DrJtj3-C.js.map +1 -0
  35. package/dist/{presentation-types-CpkTx9Xa.d.ts → presentation-types-CDjScsev.d.ts} +351 -274
  36. package/dist/presentation-types-CDjScsev.d.ts.map +1 -0
  37. package/dist/read.d.ts +31 -48
  38. package/dist/read.d.ts.map +1 -1
  39. package/dist/read.js +3 -3
  40. package/dist/script.d.ts +2 -2
  41. package/dist/script.d.ts.map +1 -1
  42. package/dist/script.js +18 -47
  43. package/dist/script.js.map +1 -1
  44. package/dist/{shapes-Kt51vry6.js → shapes-BemroU-z.js} +625 -265
  45. package/dist/shapes-BemroU-z.js.map +1 -0
  46. package/dist/{slide-B_aInw3N.d.ts → slide-ZqAdVvHV.d.ts} +1135 -1058
  47. package/dist/slide-ZqAdVvHV.d.ts.map +1 -0
  48. package/dist/{text-D04NUMvA.js → text-B8SLEaZx.js} +2089 -1418
  49. package/dist/text-B8SLEaZx.js.map +1 -0
  50. package/dist/units-1kRzYShk.js +231 -0
  51. package/dist/units-1kRzYShk.js.map +1 -0
  52. package/dist/units-internal-Dg95w_YD.js +753 -0
  53. package/dist/units-internal-Dg95w_YD.js.map +1 -0
  54. package/dist/zip.d.ts +1 -1
  55. package/package.json +2 -1
  56. package/dist/diagnostics-BDuR8UkG.d.ts.map +0 -1
  57. package/dist/diagnostics-CPVADSL1.js +0 -90
  58. package/dist/diagnostics-CPVADSL1.js.map +0 -1
  59. package/dist/namespaces-CcKuzeuE.js.map +0 -1
  60. package/dist/notes-DNqAggXx.js.map +0 -1
  61. package/dist/presentation-VfJ_FT7E.js.map +0 -1
  62. package/dist/presentation-types-CpkTx9Xa.d.ts.map +0 -1
  63. package/dist/shapes-Kt51vry6.js.map +0 -1
  64. package/dist/slide-B_aInw3N.d.ts.map +0 -1
  65. package/dist/text-D04NUMvA.js.map +0 -1
  66. package/dist/units-internal-DNvK2I6o.js +0 -896
  67. package/dist/units-internal-DNvK2I6o.js.map +0 -1
@@ -174,342 +174,695 @@ interface ShapeProps extends PositionProps, ObjectNameProps {
174
174
  shadow?: ShadowProps;
175
175
  }
176
176
  //#endregion
177
- //#region src/types/text.d.ts
178
- interface TextBaseProps {
177
+ //#region src/types/media.d.ts
178
+ type MediaType = 'audio' | 'online' | 'video';
179
+ interface ImageBaseProps extends PositionProps, ObjectNameProps {
179
180
  /**
180
- * Horizontal alignment
181
- *
182
- * When a shape's text is an array of runs, set this on **every run** of a paragraph.
183
- * {@link breakLine} is not the only paragraph boundary: two adjacent runs whose `align`
184
- * differs start a new one, so stating it on the opening run alone splits the paragraph in
185
- * two. That is the mirror of {@link bullet}, {@link paraMarginLeft} and {@link paraIndent},
186
- * which are read from the opening run only. Neither mistake changes the run count — the
187
- * only symptom is a differently shaped paragraph, with no error.
188
- * @default 'left'
181
+ * Sizing note (`w`/`h` inherited from {@link PositionProps}):
182
+ * - When a `data` (base64) image is supplied and `w`/`h` are omitted, the natural pixel
183
+ * size is read from the image header (PNG/JPEG/GIF/BMP/WebP) and used at 96 DPI
184
+ * (natural pixels / 96 = inches).
185
+ * - When only one of `w`/`h` is given, the other is derived from the natural aspect ratio —
186
+ * for an SVG too, from its `width`/`height` or `viewBox`.
187
+ * - A `path` image is measured at export time (its bytes are not available synchronously);
188
+ * an omitted dimension falls back to 1 inch if it stays unmeasurable.
189
+ * - An SVG with *neither* dimension given also falls back to 1 inch: its user units carry a
190
+ * dependable aspect ratio but only a conventional magnitude, so a 24-unit icon is not
191
+ * treated as a quarter-inch object.
192
+ * - A vector source placed in a box whose ratio differs from its own is letterboxed, not
193
+ * stretched; see {@link sizing} to override.
189
194
  */
190
- align?: HAlign;
191
195
  /**
192
- * Bold style
193
- * @default false
196
+ * Alt Text value ("How would you describe this object and its contents to someone who is blind?")
197
+ * - PowerPoint: [right-click on an image] > "Edit Alt Text..."
194
198
  */
195
- bold?: boolean;
199
+ altText?: string;
196
200
  /**
197
- * Add a line-break
201
+ * Flip horizontally?
198
202
  * @default false
199
203
  */
200
- breakLine?: boolean;
201
- /**
202
- * Preset text warp / WordArt shape (`<a:bodyPr><a:prstTxWarp prst="..">`), which
203
- * bends the text along a preset path (arch, circle, wave, …). The value is an
204
- * OOXML `ST_TextShapeType` preset name.
205
- * @example 'textArchUp' // bend text along an upward arch (e.g. a label following a ring/arc)
206
- * @example 'textCircle'
207
- */
208
- textWarp?: string;
204
+ flipH?: boolean;
209
205
  /**
210
- * Add standard or custom bullet
211
- * - use `true` for standard bullet
212
- * - pass object options for custom bullet
213
- * - `false` (and omitting the option) is the *explicit off*: it writes `<a:buNone/>`
214
- * plus `marL="0" indent="0"`, which overrides whatever bullet the layout's or
215
- * master's list style sets for this level
216
- * - `'inherit'` states nothing at all — no bullet child and no margin attributes — so
217
- * the list style keeps reaching the paragraph. This is the one state omission
218
- * cannot spell, because omitting the option means `false` here for compatibility
219
- *
220
- * The margins are only a *default* of the bullet state: {@link paraMarginLeft} and
221
- * {@link paraIndent} state `@marL`/`@indent` independently in any of the three, including
222
- * an inherited margin under a drawn bullet.
223
- *
224
- * When a shape's text is an array of runs, state this on the **opening run only**. A run
225
- * that draws a bullet starts a new paragraph by itself, so repeating it — the placement
226
- * that {@link align} requires — turns one three-run paragraph into three one-run
227
- * paragraphs. A paragraph takes its properties from its first run.
206
+ * Flip vertical?
228
207
  * @default false
229
208
  */
230
- bullet?: boolean | 'inherit' | {
231
- /**
232
- * Bullet type
233
- * @default bullet
234
- */
235
- type?: 'bullet' | 'number';
236
- /**
237
- * Bullet character code (unicode)
238
- * @example '25BA' // 'BLACK RIGHT-POINTING POINTER' (U+25BA)
239
- */
240
- characterCode?: string;
241
- /**
242
- * Bullet glyph font typeface (`<a:buFont/>`), e.g. for symbol-font bullets
243
- * @example 'Wingdings' // render `characterCode` using the Wingdings font
244
- */
245
- fontFace?: string;
246
- /**
247
- * Bullet glyph size as a percentage of the run's text size (25–400)
248
- * @default 100
249
- * @example 80 // bullet glyph is 80% of the text size
250
- */
251
- size?: number;
252
- /**
253
- * Indentation (space between bullet and text) (points)
254
- * @default 27 // DEF_BULLET_MARGIN
255
- * @example 10 // Indents text 10 points from bullet
256
- */
257
- indent?: number;
258
- /**
259
- * Number type
260
- * @example 'romanLcParenR' // roman numerals lower-case with paranthesis right
261
- */
262
- numberType?: 'alphaLcParenBoth' | 'alphaLcParenR' | 'alphaLcPeriod' | 'alphaUcParenBoth' | 'alphaUcParenR' | 'alphaUcPeriod' | 'arabicParenBoth' | 'arabicParenR' | 'arabicPeriod' | 'arabicPlain' | 'romanLcParenBoth' | 'romanLcParenR' | 'romanLcPeriod' | 'romanUcParenBoth' | 'romanUcParenR' | 'romanUcPeriod';
263
- /**
264
- * Number bullets start at
265
- * @default 1
266
- * @example 10 // numbered bullets start with 10
267
- */
268
- numberStartAt?: number;
269
- /**
270
- * Image to use as the bullet glyph ("picture bullet", `<a:buBlip>`)
271
- * - supply an image `path` (filesystem/URL) or base64 `data` (same forms as `addImage()`)
272
- * - raster formats (PNG/JPG/GIF) and SVG are supported; use `size` to scale relative to the text height
273
- * - SVG bullets embed a PNG preview plus the SVG (the same dual-rel handling as `addImage()`)
274
- * - takes precedence over `type`/`characterCode` when set
275
- * @example image: { path: 'images/star.png' }
276
- * @example image: { data: 'image/png;base64,iVBOR...' }
277
- * @example image: { path: 'images/star.svg' }
278
- */
279
- image?: {
280
- path?: string;
281
- data?: string;
282
- };
283
- /**
284
- * Relationship id assigned to a picture-bullet image (`<a:blip r:embed>`)
285
- * - for SVG bullets this is the PNG-preview rel; the SVG rel is `_rIdSvg`
286
- * @internal populated by `addText()`; do not set directly
287
- */
288
- _rId?: number;
289
- /**
290
- * Relationship id of the SVG image for an SVG picture bullet (`<asvg:svgBlip r:embed>`)
291
- * @internal populated by `addText()`; do not set directly
292
- */
293
- _rIdSvg?: number;
294
- /**
295
- * Bullet glyph color (separate from the text run color)
296
- * @example 'FF0000' // red bullet
297
- */
298
- color?: HexColor;
299
- };
209
+ flipV?: boolean;
210
+ hyperlink?: HyperlinkProps;
300
211
  /**
301
- * Text capitalization (`a:rPr/@cap`, `ST_TextCapsType`)
302
- * - `'all'` = ALL CAPS
303
- * - `'small'` = Small Caps
304
- * - `'none'` = the *explicit off*: it writes `cap="none"`, which overrides a capitalization
305
- * the run would otherwise inherit. Omitting the option states nothing and lets that
306
- * inheritance stand
307
- * - PowerPoint: Font > Effects > All Caps / Small Caps
308
- * @default (unset) inherit
212
+ * Border line (`<a:ln>` outline) drawn around the image
213
+ * - same options as a shape outline; a picture supports a single outline, not per-side borders
214
+ * - MS-PPT: Format Picture > Line
215
+ * @example { color: '0088CC', width: 2 } // 2pt blue border
216
+ * @example { color: '666666', width: 1, dashType: 'dash' } // dashed gray border
309
217
  */
310
- caps?: 'none' | 'small' | 'all';
218
+ line?: ShapeLineProps;
311
219
  /**
312
- * Text color
313
- * - `HexColor` or `ThemeColor`
314
- * - MS-PPT > Format Shape > Text Options > Text Fill & Outline > Text Fill > Color
315
- * @example 'FF0000' // hex color (red)
316
- * @example SchemeColor.text1 // Theme color (Text1)
220
+ * Name of a picture placeholder defined on the slide layout/master to populate
221
+ * - when it matches a layout/master placeholder, the image inherits that placeholder's
222
+ * position and size for any of `x`/`y`/`w`/`h` not supplied explicitly;
223
+ * explicit values always win
224
+ * @example 'picph'
225
+ * @see https://docs.microsoft.com/en-us/office/vba/api/powerpoint.ppplaceholdertype
317
226
  */
318
- color?: Color;
227
+ placeholder?: string;
319
228
  /**
320
- * Font face name
321
- *
322
- * Applied to the Latin (`<a:latin>`) and complex-script (`<a:cs>`) font slots, matching
323
- * how PowerPoint writes a font picked from the UI. The East Asian slot (`<a:ea>`) is left
324
- * to inherit from the theme unless `fontFaceEA` is set — forcing a Latin-only face into the
325
- * East Asian slot duplicates/ghosts text in Office 365.
326
- * @example 'Arial' // Arial font
229
+ * Image rotation (degrees)
230
+ * - range: -360 to 360
231
+ * @default 0
232
+ * @example 180 // rotate image 180 degrees
327
233
  */
328
- fontFace?: string;
234
+ rotate?: number;
329
235
  /**
330
- * East Asian font face name (`<a:ea>` slot), used to render CJK (Chinese/Japanese/Korean) glyphs
331
- *
332
- * Set this when the East Asian font differs from `fontFace`. When omitted, `<a:ea>` inherits the
333
- * theme East Asian font, which is what PowerPoint does for Latin fonts.
334
- * @example '微軟正黑體' // render East Asian glyphs with Microsoft JhengHei
236
+ * Enable image rounding (clips the image to a circle/ellipse)
237
+ * - shorthand for `shape: 'ellipse'`; `shape` takes precedence when both are set
238
+ * @default false
335
239
  */
336
- fontFaceEA?: string;
240
+ rounding?: boolean;
337
241
  /**
338
- * Font size
339
- * @example 12 // Font size 12
242
+ * Clip the image to a preset shape geometry ("fit image into shape")
243
+ * - accepts any PowerPoint preset geometry name, e.g. `'roundRect'`, `'hexagon'`, `'ellipse'`
244
+ * - combine with `sizing: { type: 'cover', ... }` for an aspect-correct fill of the shape box
245
+ * - use `rectRadius` to set the corner radius for `'roundRect'`
246
+ * @example 'roundRect' // rounded-rectangle avatar
247
+ * @example 'hexagon' // hexagonal photo
340
248
  */
341
- fontSize?: number;
249
+ shape?: SHAPE_NAME;
342
250
  /**
343
- * Text highlight color (hex format)
344
- * @example 'FFFF00' // yellow
251
+ * Clip the image to an arbitrary freeform path (`custGeom`)
252
+ * - takes precedence over `shape` / `rounding` when present
253
+ * - coordinates are authored in the image's own inch/EMU space (0..w, 0..h), not slide-relative and not normalized
254
+ * - supports the same path DSL as freeform shapes: `moveTo` / `lnTo` / `cubicBezTo` / `quadBezTo` / `arcTo` / `close`
255
+ * @example [{ x: 1, y: 0 }, { x: 2, y: 2 }, { x: 0, y: 2 }, { close: true }] // triangular photo clip
345
256
  */
346
- highlight?: HexColor;
257
+ points?: GeometryPoint[];
347
258
  /**
348
- * italic style
349
- * @default false
259
+ * Rounded rectangle corner radius (inches) when `shape: 'roundRect'`
260
+ * - values: 0.0 to 1.0
261
+ * @default 0
350
262
  */
351
- italic?: boolean;
263
+ rectRadius?: number;
352
264
  /**
353
- * language
354
- * - ISO 639-1 standard language code
355
- * @default 'en-US' // english US
356
- * @example 'fr-CA' // french Canadian
265
+ * Preset-geometry adjustment handles (`<a:avLst>` guides) for the clip `shape`.
266
+ * - tune adjustment handles that lack a dedicated option, e.g. chevron point depth
267
+ * - accepts a single guide or an array; each `value` is a `0.0–1.0` fraction (see {@link ShapeAdjustValue})
268
+ * @example { name: 'adj', value: 0.25 }
357
269
  */
358
- lang?: string;
270
+ shapeAdjust?: ShapeAdjustValue | ShapeAdjustValue[];
359
271
  /**
360
- * First-line indent (points) — `a:pPr/@indent`, the offset of the paragraph's FIRST line
361
- * from {@link paraMarginLeft}. Negative hangs the first line to the left of the body, which
362
- * is what a bulleted paragraph does; positive indents it to the right, the "first line
363
- * indented" prose form. PowerPoint: Paragraph > Indentation > Special.
364
- * - `'inherit'` writes no `@indent` at all, so the paragraph takes whatever its list style
365
- * (`a:lstStyle` → placeholder → layout → master) sets — the same third state
366
- * {@link bullet} spells, on the attribute beside it
367
- * - omitting the option keeps the bullet-derived default: a drawn bullet hangs the first
368
- * line by its margin, `bullet: false` writes `indent="0"`, `bullet: 'inherit'` writes
369
- * nothing
370
- * - a value here overrides all of those, in every bullet state
371
- * @example -18 // hang the first line 18pt left of the body text
372
- * @example 18 // indent the first line 18pt, prose style
373
- * @example 'inherit' // keep the list style's indent, even on a bulleted paragraph
374
- * @remarks Read from the **opening run** of a paragraph, like {@link bullet} and unlike
375
- * {@link align}; a value on a continuation run is ignored.
272
+ * Shadow Props
273
+ * - MS-PPT > Format Picture > Shadow
274
+ * @example
275
+ * { type: 'outer', color: '000000', transparency: 50, blur: 20, offset: 20, angle: 270 }
376
276
  */
377
- paraIndent?: number | 'inherit';
277
+ shadow?: ShadowProps;
378
278
  /**
379
- * Left margin of the paragraph (points) — `a:pPr/@marL`, where the paragraph's body text
380
- * starts. This is the paragraph's own margin, not the text frame's internal padding
381
- * (`margin`) and not the discrete outline level (`indentLevel`, which writes `a:p/@lvl`).
382
- * PowerPoint: Paragraph > Indentation > Before text.
383
- * - `'inherit'` writes no `@marL` at all, so the paragraph takes whatever its list style
384
- * (`a:lstStyle` → placeholder → layout → master) sets — the third state that omission
385
- * cannot spell, since omitting it writes the bullet-derived default
386
- * - omitting the option keeps that default: a drawn bullet writes its own margin (see
387
- * `bullet.indent`), `bullet: false` writes `marL="0"`, `bullet: 'inherit'` writes nothing
388
- * - a value here overrides all of those, in every bullet state
389
- * @example 36 // body text starts 36pt (0.5in) from the frame's text edge
390
- * @example 'inherit' // keep the list style's margin, even on a bulleted paragraph
391
- * @remarks Read from the **opening run** of a paragraph, like {@link bullet} and unlike
392
- * {@link align}; a value on a continuation run is ignored.
393
- */
394
- paraMarginLeft?: number | 'inherit';
395
- /**
396
- * Add a soft line-break (shift+enter) before line text content
397
- * @default false
398
- */
399
- softBreakBefore?: boolean;
400
- /**
401
- * tab stops
402
- * - PowerPoint: Paragraph > Tabs > Tab stop position
403
- * @example [{ position:1 }, { position:3 }] // Set first tab stop to 1 inch, set second tab stop to 3 inches
279
+ * Crop the source image to a sub-region by percentage edge insets, emitted verbatim
280
+ * as OOXML `<a:srcRect>`.
281
+ * - each value is the percent (0–100) trimmed off that edge of the *source* image, the
282
+ * same model PowerPoint's Picture Format > Crop uses; `l`+`r` and `t`+`b` must each be < 100
283
+ * - the remaining sub-region is stretched to fill the picture's displayed `w`×`h` box, so this
284
+ * is the faithful way to reproduce a deck that maps several icons out of one composite raster
285
+ * - operates on the source image directly (independent of natural-pixel measurement), so unlike
286
+ * `sizing: 'crop'` (which crops in *displayed inches*) it works for SVG and unmeasurable formats
287
+ * - mutually exclusive with {@link sizing}; if both are set `crop` wins and `sizing` is ignored
288
+ * @example { l: 0, t: 0, r: 50, b: 50 } // keep the top-left quadrant of the source image
404
289
  */
405
- tabStops?: Array<{
406
- position: number;
407
- alignment?: 'l' | 'r' | 'ctr' | 'dec';
408
- }>;
290
+ crop?: {
291
+ /** Percent (0–100) trimmed from the left edge of the source image. @default 0 */
292
+ l?: number;
293
+ /** Percent (0–100) trimmed from the top edge of the source image. @default 0 */
294
+ t?: number;
295
+ /** Percent (0–100) trimmed from the right edge of the source image. @default 0 */
296
+ r?: number;
297
+ /** Percent (0–100) trimmed from the bottom edge of the source image. @default 0 */
298
+ b?: number;
299
+ };
409
300
  /**
410
- * text direction
411
- * `horz` = horizontal
412
- * `vert` = rotate 90^
413
- * `vert270` = rotate 270^
414
- * `wordArtVert` = stacked
415
- * @default 'horz'
301
+ * Image sizing options
302
+ * - omit entirely for the default: a raster fills the `w`×`h` box, a vector (SVG) source is
303
+ * letterboxed to its own aspect ratio inside that box
416
304
  */
417
- textDirection?: 'horz' | 'vert' | 'vert270' | 'wordArtVert';
305
+ sizing?: {
306
+ /**
307
+ * Sizing type
308
+ * - `cover` / `contain` fit the image into the `w`×`h` box using the image's *natural*
309
+ * aspect ratio — read from the embedded PNG/JPEG/GIF/BMP/WebP header, or from an SVG's
310
+ * `width`/`height` or `viewBox`. If the natural size cannot be determined (an
311
+ * unrecognized format, or an SVG carrying neither) the displayed `w`/`h` ratio is used
312
+ * as a fallback and a warning is logged.
313
+ * - `crop` cuts a window out of the displayed image using the `x`/`y`/`w`/`h` offsets.
314
+ * - `stretch` fills the box regardless of aspect ratio. This is what a raster does
315
+ * anyway; name it explicitly to opt a vector source out of its aspect-correct default.
316
+ */
317
+ type: 'contain' | 'cover' | 'crop' | 'stretch';
318
+ /**
319
+ * Image width
320
+ * - inches or percentage
321
+ * - defaults to the picture's own `w`, which is what `cover`/`contain` almost always want
322
+ * @example 10.25 // position in inches
323
+ * @example '75%' // position as percentage of slide size
324
+ */
325
+ w?: Coord;
326
+ /**
327
+ * Image height
328
+ * - inches or percentage
329
+ * - defaults to the picture's own `h`
330
+ * @example 10.25 // position in inches
331
+ * @example '75%' // position as percentage of slide size
332
+ */
333
+ h?: Coord;
334
+ /**
335
+ * Offset from left to crop image
336
+ * - `crop` only
337
+ * - inches or percentage
338
+ * @example 10.25 // position in inches
339
+ * @example '75%' // position as percentage of slide size
340
+ */
341
+ x?: Coord;
342
+ /**
343
+ * Offset from top to crop image
344
+ * - `crop` only
345
+ * - inches or percentage
346
+ * @example 10.25 // position in inches
347
+ * @example '75%' // position as percentage of slide size
348
+ */
349
+ y?: Coord;
350
+ };
418
351
  /**
419
352
  * Transparency (percent)
420
- * - MS-PPT > Format Shape > Text Options > Text Fill & Outline > Text Fill > Transparency
353
+ * - MS-PPT > Format Picture > Picture > Picture Transparency > Transparency
421
354
  * - range: 0-100
422
355
  * @default 0
356
+ * @example 25 // 25% transparent
423
357
  */
424
358
  transparency?: number;
425
359
  /**
426
- * underline properties
427
- * - PowerPoint: Font > Color & Underline > Underline Style/Underline Color
428
- * - `style` is the full `ST_TextUnderlineType` enumeration (ECMA-376 §20.1.10.81)
429
- * - `'none'` is the *explicit off*: it writes `a:rPr/@u="none"`, which overrides an
430
- * underline the run would otherwise inherit from its list style, placeholder, layout or
431
- * master. Omitting the option instead states nothing and lets that inheritance stand —
432
- * the two are different facts, not two spellings of one.
433
- * @default (unset) inherit
360
+ * Recolor the image as a two-tone (duotone) effect
361
+ * - maps the image's shadows to `shadow` and its highlights to `highlight`
362
+ * - serializes `<a:duotone>` inside the picture's `<a:blip>` (MS-PPT > Format Picture > Picture Color > Recolor)
363
+ * - colors accept `HexColor` or `ThemeColor`, same as fills
364
+ * - the classic brand treatment: tint stock photography into a single brand hue
365
+ * @example { shadow: '250F6B', highlight: 'FFFFFF' } // deep-blue duotone
434
366
  */
435
- underline?: {
436
- style?: 'dash' | 'dashHeavy' | 'dashLong' | 'dashLongHeavy' | 'dbl' | 'dotDash' | 'dotDashHeavy' | 'dotDotDash' | 'dotDotDashHeavy' | 'dotted' | 'dottedHeavy' | 'heavy' | 'none' | 'sng' | 'wavy' | 'wavyDbl' | 'wavyHeavy' | 'words';
437
- color?: Color;
367
+ duotone?: {
368
+ /** Color mapped to the image's dark/shadow tones. */
369
+ shadow: Color;
370
+ /** Color mapped to the image's light/highlight tones. */
371
+ highlight: Color;
438
372
  };
439
373
  /**
440
- * vertical alignment
441
- * @default 'top'
374
+ * Recolor the image to grayscale (`<a:grayscl/>`)
375
+ * - maps every pixel to its luminance grey (MS-PPT > Format Picture > Picture Color > Recolor > Grayscale)
376
+ * - the cheapest recolour: no payload
377
+ * - mutually exclusive with the other recolour modes (`duotone`/`biLevel`/`clrChange`); if several are set,
378
+ * the first present in document order wins on read-back
379
+ * @default false
380
+ * @example true // desaturate the image
442
381
  */
443
- valign?: VAlign;
444
- }
445
- interface TextGlowProps {
382
+ grayscale?: boolean;
446
383
  /**
447
- * Border color (hex format)
448
- * @example 'FF3399'
384
+ * Recolor the image to two-level black & white (`<a:biLevel thresh="…"/>`)
385
+ * - every pixel at/above the luminance threshold becomes white, everything below it black
386
+ * (MS-PPT > Format Picture > Picture Color > Recolor > Black and White …%)
387
+ * @example { threshold: 0.5 } // split at 50% luminance
449
388
  */
450
- color?: HexColor;
389
+ biLevel?: {
390
+ /** Luminance split point as a `0.0–1.0` fraction (serialized to `thresh`, the 0–1 fraction ×100000). */
391
+ threshold: number;
392
+ };
451
393
  /**
452
- * opacity (0.0 - 1.0)
453
- * @example 0.5
454
- * 50% opaque
394
+ * Recolor the image by mapping one source color to another (`<a:clrChange>`)
395
+ * - every pixel matching `from` is repainted `to` — the classic "swap the flat background out" recolour
396
+ * (MS-PPT > Format Picture > Picture Color > Set Transparent Color is the single-colour sibling)
397
+ * - colors accept `HexColor` or `ThemeColor`, same as fills / `duotone`
398
+ * @example { from: '000000', to: 'FF0000' } // turn black pixels red
455
399
  */
456
- opacity?: number;
400
+ clrChange?: {
401
+ /** Source color to replace (`<a:clrFrom>`). */
402
+ from: Color;
403
+ /** Replacement color (`<a:clrTo>`). */
404
+ to: Color;
405
+ };
457
406
  /**
458
- * size (points)
407
+ * Raw SVG markup to embed as the image source
408
+ * - convenience for `data: 'data:image/svg+xml;base64,...'`; ts-pptx encodes it for you
409
+ * - ignored when `data` or `path` is also provided
410
+ * @example '<svg viewBox="0 0 24 24">...</svg>'
459
411
  */
460
- size: number;
412
+ svg?: string;
461
413
  }
462
- interface TextFitShrinkProps {
414
+ type ImageProps = ImageBaseProps & (DataOrPathRequiredProps | (DataOrPathProps & {
415
+ svg: string;
416
+ }));
417
+ /**
418
+ * Add media (audio/video) to slide
419
+ * Requires either `data` or `path`; online media requires `link`.
420
+ */
421
+ interface MediaBaseProps extends PositionProps, ObjectNameProps {
463
422
  /**
464
- * Shrink text on overflow (`<a:normAutofit>`)
423
+ * Cover image
424
+ * @default "play button" image, gray background
465
425
  */
466
- type: 'shrink';
426
+ cover?: string;
467
427
  /**
468
- * Font scale as a percent (0-100), mapped to `<a:normAutofit fontScale="..">`.
469
- *
470
- * PowerPoint normally calculates this dynamically when text overflows; set it
471
- * explicitly to bake the scale into the generated file.
472
- * @example 85 // render text at 85% of its nominal size
473
- * @default undefined // attribute omitted (PowerPoint defaults to 100%)
428
+ * media file extension
429
+ * - use when the media file path does not already have an extension, ex: "/folder/SomeSong"
430
+ * @default extension from file provided
474
431
  */
475
- fontScale?: number;
432
+ extn?: string;
476
433
  /**
477
- * Line-space reduction as a percent (0-100), mapped to `<a:normAutofit lnSpcReduction="..">`.
478
- * @example 20 // reduce line spacing by 20%
479
- * @default undefined // attribute omitted (PowerPoint defaults to 0%)
434
+ * Loop playback indefinitely (PowerPoint "Playback > Loop until Stopped")
435
+ * - emits a slide timing tree so the embedded audio/video repeats when played
436
+ * - not supported for `type: 'online'` (e.g. YouTube) embeds
437
+ * @default false
480
438
  */
481
- lnSpcReduction?: number;
439
+ loop?: boolean;
440
+ /**
441
+ * Total number of times to play the media (a finite loop), ex: `3` plays it three times
442
+ * - ignored when `loop` is `true` (which repeats forever)
443
+ * - not supported for `type: 'online'` (e.g. YouTube) embeds
444
+ */
445
+ loopCount?: number;
482
446
  }
483
- interface TextPropsOptions extends PositionProps, DataOrPathProps, TextBaseProps, ObjectNameProps {
447
+ /**
448
+ * Add an embedded OLE object (PowerPoint's Insert ▸ Object ▸ Create from File) to a slide.
449
+ *
450
+ * The payload's bytes travel inside the `.pptx` (in `ppt/embeddings/`), so double-clicking the
451
+ * object in PowerPoint opens the source document in place. Requires either `data` or `path`.
452
+ * Linked objects (`<p:link>` to a file outside the package) are not supported.
453
+ */
454
+ interface OleObjectBaseProps extends PositionProps, ObjectNameProps {
484
455
  /**
485
- * Preset-geometry start/end angles for text frames (`shape` + these build `<a:prstGeom>`
486
- * adjustment guides through the shared emitter — `genXmlPresetGeom` reads them whether
487
- * the object is a shape or a styled text frame).
456
+ * Picture of the embedded document shown on the slide — a raster image `path` (Node/local)
457
+ * or base64 `data:` URI.
458
+ * - the library is Node-first and cannot render an Office document, so when this is omitted a
459
+ * neutral gray placeholder is embedded; PowerPoint draws the live object over it, but every
460
+ * other consumer (and PowerPoint's own `mc:Fallback` path) shows exactly what is supplied here
461
+ * - supply a real screenshot whenever the deck is meant to read correctly outside PowerPoint
462
+ * @example { path: 'assets/budget-preview.png' }
488
463
  */
489
- angleRange?: [number, number];
490
- /** Preset-geometry block-arc thickness for text frames. */
491
- arcThicknessRatio?: number;
492
- /** Custom geometry points when a text frame uses a custom geometry shape. */
493
- points?: GeometryPoint[];
494
- /** Preset-geometry adjustment guides for text frames. */
495
- shapeAdjust?: ShapeAdjustValue | ShapeAdjustValue[];
496
- _bodyProp?: {
497
- align?: AlignH;
498
- anchor?: TextAnchor;
499
- lIns?: number;
500
- rIns?: number;
501
- tIns?: number;
502
- bIns?: number;
503
- numCol?: number;
504
- spcCol?: number;
505
- vert?: TextVertType;
506
- wrap?: boolean;
507
- prstTxWarp?: string;
464
+ cover?: {
465
+ path?: string;
466
+ data?: string;
508
467
  };
509
- _lineIdx?: number;
510
- baseline?: number;
511
468
  /**
512
- * Character spacing
469
+ * Payload file extension, used to name the embedded part and to pick the content type,
470
+ * relationship type, and default `progId`.
471
+ * - inferred from `data`'s MIME, else `path`'s extension, else `progId`
472
+ * - anything that is not a known Office package extension (`xlsx`/`xlsm`/`docx`/`docm`/`pptx`/`pptm`)
473
+ * is embedded as a generic OLE blob part named `.bin`
474
+ * @example 'xlsx'
475
+ */
476
+ extn?: string;
477
+ /**
478
+ * OLE server ProgID — what PowerPoint launches on double-click.
479
+ * - defaults from the resolved extension (`xlsx` → `Excel.Sheet.12`, `docx` → `Word.Document.12`,
480
+ * `pptx` → `PowerPoint.Show.12`, anything else → `Package`)
481
+ * @example 'Excel.Sheet.12'
482
+ */
483
+ progId?: string;
484
+ /**
485
+ * Display the object as its application icon instead of a document preview (`showAsIcon`).
486
+ * - the `cover` image is still what gets drawn, so supply an icon-looking preview to match
487
+ * @default false
488
+ */
489
+ showAsIcon?: boolean;
490
+ /**
491
+ * Native size of the preview image in EMU (`imgW`/`imgH`), which PowerPoint uses to keep the
492
+ * object's aspect ratio when it re-renders the embedded document.
493
+ * - defaults to the object's own `w`/`h` converted to EMU
494
+ */
495
+ imgW?: number;
496
+ /** @see {@link imgW} */
497
+ imgH?: number;
498
+ }
499
+ /**
500
+ * Options for `slide.addOleObject()`. Requires either `data` (base64, with or without a
501
+ * `data:...;base64,` header) or `path` (a local/remote file read at export time).
502
+ *
503
+ * Sizing note: `w`/`h` default to 4 × 3 inches rather than being measured, since the library
504
+ * does not open the embedded document.
505
+ */
506
+ type OleObjectProps = OleObjectBaseProps & DataOrPathRequiredProps;
507
+ type MediaProps = MediaBaseProps & ((DataOrPathRequiredProps & {
508
+ /**
509
+ * Media type
510
+ */
511
+ type: Exclude<MediaType, 'online'>;
512
+ /**
513
+ * Optional video embed link metadata.
514
+ */
515
+ link?: string;
516
+ }) | (DataOrPathProps & {
517
+ /**
518
+ * Use 'online' to embed a YouTube video (only supported in recent versions of PowerPoint)
519
+ */
520
+ type: 'online';
521
+ /**
522
+ * video embed link
523
+ * - works with YouTube
524
+ * - other sites may not show correctly in PowerPoint
525
+ * @example 'https://www.youtube.com/embed/Dph6ynRVyUc' // embed a youtube video
526
+ */
527
+ link: string;
528
+ }));
529
+ //#endregion
530
+ //#region src/types/text.d.ts
531
+ interface TextBaseProps {
532
+ /**
533
+ * Horizontal alignment
534
+ *
535
+ * When a shape's text is an array of runs, set this on **every run** of a paragraph.
536
+ * {@link breakLine} is not the only paragraph boundary: two adjacent runs whose `align`
537
+ * differs start a new one, so stating it on the opening run alone splits the paragraph in
538
+ * two. That is the mirror of {@link bullet}, {@link paraMarginLeft} and {@link paraIndent},
539
+ * which are read from the opening run only. Neither mistake changes the run count — the
540
+ * only symptom is a differently shaped paragraph, with no error.
541
+ * @default 'left'
542
+ */
543
+ align?: HAlign;
544
+ /**
545
+ * Bold style
546
+ * @default false
547
+ */
548
+ bold?: boolean;
549
+ /**
550
+ * Add a line-break
551
+ * @default false
552
+ */
553
+ breakLine?: boolean;
554
+ /**
555
+ * Preset text warp / WordArt shape (`<a:bodyPr><a:prstTxWarp prst="..">`), which
556
+ * bends the text along a preset path (arch, circle, wave, …). The value is an
557
+ * OOXML `ST_TextShapeType` preset name.
558
+ * @example 'textArchUp' // bend text along an upward arch (e.g. a label following a ring/arc)
559
+ * @example 'textCircle'
560
+ */
561
+ textWarp?: string;
562
+ /**
563
+ * Add standard or custom bullet
564
+ * - use `true` for standard bullet
565
+ * - pass object options for custom bullet
566
+ * - `false` (and omitting the option) is the *explicit off*: it writes `<a:buNone/>`
567
+ * plus `marL="0" indent="0"`, which overrides whatever bullet the layout's or
568
+ * master's list style sets for this level
569
+ * - `'inherit'` states nothing at all — no bullet child and no margin attributes — so
570
+ * the list style keeps reaching the paragraph. This is the one state omission
571
+ * cannot spell, because omitting the option means `false` here for compatibility
572
+ *
573
+ * The margins are only a *default* of the bullet state: {@link paraMarginLeft} and
574
+ * {@link paraIndent} state `@marL`/`@indent` independently in any of the three, including
575
+ * an inherited margin under a drawn bullet.
576
+ *
577
+ * When a shape's text is an array of runs, state this on the **opening run only**. A run
578
+ * that draws a bullet starts a new paragraph by itself, so repeating it — the placement
579
+ * that {@link align} requires — turns one three-run paragraph into three one-run
580
+ * paragraphs. A paragraph takes its properties from its first run.
581
+ * @default false
582
+ */
583
+ bullet?: boolean | 'inherit' | {
584
+ /**
585
+ * Bullet type
586
+ * @default bullet
587
+ */
588
+ type?: 'bullet' | 'number';
589
+ /**
590
+ * Bullet character code (unicode)
591
+ * @example '25BA' // 'BLACK RIGHT-POINTING POINTER' (U+25BA)
592
+ */
593
+ characterCode?: string;
594
+ /**
595
+ * Bullet glyph font typeface (`<a:buFont/>`), e.g. for symbol-font bullets
596
+ * @example 'Wingdings' // render `characterCode` using the Wingdings font
597
+ */
598
+ fontFace?: string;
599
+ /**
600
+ * Bullet glyph size as a percentage of the run's text size (25–400)
601
+ * @default 100
602
+ * @example 80 // bullet glyph is 80% of the text size
603
+ */
604
+ size?: number;
605
+ /**
606
+ * Indentation (space between bullet and text) (points)
607
+ * @default 27 // DEF_BULLET_MARGIN
608
+ * @example 10 // Indents text 10 points from bullet
609
+ */
610
+ indent?: number;
611
+ /**
612
+ * Number type
613
+ * @example 'romanLcParenR' // roman numerals lower-case with paranthesis right
614
+ */
615
+ numberType?: 'alphaLcParenBoth' | 'alphaLcParenR' | 'alphaLcPeriod' | 'alphaUcParenBoth' | 'alphaUcParenR' | 'alphaUcPeriod' | 'arabicParenBoth' | 'arabicParenR' | 'arabicPeriod' | 'arabicPlain' | 'romanLcParenBoth' | 'romanLcParenR' | 'romanLcPeriod' | 'romanUcParenBoth' | 'romanUcParenR' | 'romanUcPeriod';
616
+ /**
617
+ * Number bullets start at
618
+ * @default 1
619
+ * @example 10 // numbered bullets start with 10
620
+ */
621
+ numberStartAt?: number;
622
+ /**
623
+ * Image to use as the bullet glyph ("picture bullet", `<a:buBlip>`)
624
+ * - supply an image `path` (filesystem/URL) or base64 `data` (same forms as `addImage()`)
625
+ * - raster formats (PNG/JPG/GIF) and SVG are supported; use `size` to scale relative to the text height
626
+ * - SVG bullets embed a PNG preview plus the SVG (the same dual-rel handling as `addImage()`)
627
+ * - takes precedence over `type`/`characterCode` when set
628
+ * @example image: { path: 'images/star.png' }
629
+ * @example image: { data: 'image/png;base64,iVBOR...' }
630
+ * @example image: { path: 'images/star.svg' }
631
+ */
632
+ image?: {
633
+ path?: string;
634
+ data?: string;
635
+ };
636
+ /**
637
+ * Relationship id assigned to a picture-bullet image (`<a:blip r:embed>`)
638
+ * - for SVG bullets this is the PNG-preview rel; the SVG rel is `_rIdSvg`
639
+ * @internal populated by `addText()`; do not set directly
640
+ */
641
+ _rId?: number;
642
+ /**
643
+ * Relationship id of the SVG image for an SVG picture bullet (`<asvg:svgBlip r:embed>`)
644
+ * @internal populated by `addText()`; do not set directly
645
+ */
646
+ _rIdSvg?: number;
647
+ /**
648
+ * Bullet glyph color (separate from the text run color)
649
+ * @example 'FF0000' // red bullet
650
+ */
651
+ color?: HexColor;
652
+ };
653
+ /**
654
+ * Text capitalization (`a:rPr/@cap`, `ST_TextCapsType`)
655
+ * - `'all'` = ALL CAPS
656
+ * - `'small'` = Small Caps
657
+ * - `'none'` = the *explicit off*: it writes `cap="none"`, which overrides a capitalization
658
+ * the run would otherwise inherit. Omitting the option states nothing and lets that
659
+ * inheritance stand
660
+ * - PowerPoint: Font > Effects > All Caps / Small Caps
661
+ * @default (unset) inherit
662
+ */
663
+ caps?: 'none' | 'small' | 'all';
664
+ /**
665
+ * Text color
666
+ * - `HexColor` or `ThemeColor`
667
+ * - MS-PPT > Format Shape > Text Options > Text Fill & Outline > Text Fill > Color
668
+ * @example 'FF0000' // hex color (red)
669
+ * @example SchemeColor.text1 // Theme color (Text1)
670
+ */
671
+ color?: Color;
672
+ /**
673
+ * Font face name
674
+ *
675
+ * Applied to the Latin (`<a:latin>`) and complex-script (`<a:cs>`) font slots, matching
676
+ * how PowerPoint writes a font picked from the UI. The East Asian slot (`<a:ea>`) is left
677
+ * to inherit from the theme unless `fontFaceEA` is set — forcing a Latin-only face into the
678
+ * East Asian slot duplicates/ghosts text in Office 365.
679
+ * @example 'Arial' // Arial font
680
+ */
681
+ fontFace?: string;
682
+ /**
683
+ * East Asian font face name (`<a:ea>` slot), used to render CJK (Chinese/Japanese/Korean) glyphs
684
+ *
685
+ * Set this when the East Asian font differs from `fontFace`. When omitted, `<a:ea>` inherits the
686
+ * theme East Asian font, which is what PowerPoint does for Latin fonts.
687
+ * @example '微軟正黑體' // render East Asian glyphs with Microsoft JhengHei
688
+ */
689
+ fontFaceEA?: string;
690
+ /**
691
+ * Font size
692
+ * @example 12 // Font size 12
693
+ */
694
+ fontSize?: number;
695
+ /**
696
+ * Text highlight color (hex format)
697
+ * @example 'FFFF00' // yellow
698
+ */
699
+ highlight?: HexColor;
700
+ /**
701
+ * italic style
702
+ * @default false
703
+ */
704
+ italic?: boolean;
705
+ /**
706
+ * language
707
+ * - ISO 639-1 standard language code
708
+ * @default 'en-US' // english US
709
+ * @example 'fr-CA' // french Canadian
710
+ */
711
+ lang?: string;
712
+ /**
713
+ * First-line indent (points) — `a:pPr/@indent`, the offset of the paragraph's FIRST line
714
+ * from {@link paraMarginLeft}. Negative hangs the first line to the left of the body, which
715
+ * is what a bulleted paragraph does; positive indents it to the right, the "first line
716
+ * indented" prose form. PowerPoint: Paragraph > Indentation > Special.
717
+ * - `'inherit'` writes no `@indent` at all, so the paragraph takes whatever its list style
718
+ * (`a:lstStyle` → placeholder → layout → master) sets — the same third state
719
+ * {@link bullet} spells, on the attribute beside it
720
+ * - omitting the option keeps the bullet-derived default: a drawn bullet hangs the first
721
+ * line by its margin, `bullet: false` writes `indent="0"`, `bullet: 'inherit'` writes
722
+ * nothing
723
+ * - a value here overrides all of those, in every bullet state
724
+ * @example -18 // hang the first line 18pt left of the body text
725
+ * @example 18 // indent the first line 18pt, prose style
726
+ * @example 'inherit' // keep the list style's indent, even on a bulleted paragraph
727
+ * @remarks Read from the **opening run** of a paragraph, like {@link bullet} and unlike
728
+ * {@link align}; a value on a continuation run is ignored.
729
+ */
730
+ paraIndent?: number | 'inherit';
731
+ /**
732
+ * Left margin of the paragraph (points) — `a:pPr/@marL`, where the paragraph's body text
733
+ * starts. This is the paragraph's own margin, not the text frame's internal padding
734
+ * (`margin`) and not the discrete outline level (`indentLevel`, which writes `a:p/@lvl`).
735
+ * PowerPoint: Paragraph > Indentation > Before text.
736
+ * - `'inherit'` writes no `@marL` at all, so the paragraph takes whatever its list style
737
+ * (`a:lstStyle` → placeholder → layout → master) sets — the third state that omission
738
+ * cannot spell, since omitting it writes the bullet-derived default
739
+ * - omitting the option keeps that default: a drawn bullet writes its own margin (see
740
+ * `bullet.indent`), `bullet: false` writes `marL="0"`, `bullet: 'inherit'` writes nothing
741
+ * - a value here overrides all of those, in every bullet state
742
+ * @example 36 // body text starts 36pt (0.5in) from the frame's text edge
743
+ * @example 'inherit' // keep the list style's margin, even on a bulleted paragraph
744
+ * @remarks Read from the **opening run** of a paragraph, like {@link bullet} and unlike
745
+ * {@link align}; a value on a continuation run is ignored.
746
+ */
747
+ paraMarginLeft?: number | 'inherit';
748
+ /**
749
+ * Add a soft line-break (shift+enter) before line text content
750
+ * @default false
751
+ */
752
+ softBreakBefore?: boolean;
753
+ /**
754
+ * tab stops
755
+ * - PowerPoint: Paragraph > Tabs > Tab stop position
756
+ * @example [{ position:1 }, { position:3 }] // Set first tab stop to 1 inch, set second tab stop to 3 inches
757
+ */
758
+ tabStops?: Array<{
759
+ position: number;
760
+ alignment?: 'l' | 'r' | 'ctr' | 'dec';
761
+ }>;
762
+ /**
763
+ * text direction
764
+ * `horz` = horizontal
765
+ * `vert` = rotate 90^
766
+ * `vert270` = rotate 270^
767
+ * `wordArtVert` = stacked
768
+ * @default 'horz'
769
+ */
770
+ textDirection?: 'horz' | 'vert' | 'vert270' | 'wordArtVert';
771
+ /**
772
+ * Transparency (percent)
773
+ * - MS-PPT > Format Shape > Text Options > Text Fill & Outline > Text Fill > Transparency
774
+ * - range: 0-100
775
+ * @default 0
776
+ */
777
+ transparency?: number;
778
+ /**
779
+ * underline properties
780
+ * - PowerPoint: Font > Color & Underline > Underline Style/Underline Color
781
+ * - `style` is the full `ST_TextUnderlineType` enumeration (ECMA-376 §20.1.10.81)
782
+ * - `'none'` is the *explicit off*: it writes `a:rPr/@u="none"`, which overrides an
783
+ * underline the run would otherwise inherit from its list style, placeholder, layout or
784
+ * master. Omitting the option instead states nothing and lets that inheritance stand —
785
+ * the two are different facts, not two spellings of one.
786
+ * @default (unset) inherit
787
+ */
788
+ underline?: {
789
+ style?: 'dash' | 'dashHeavy' | 'dashLong' | 'dashLongHeavy' | 'dbl' | 'dotDash' | 'dotDashHeavy' | 'dotDotDash' | 'dotDotDashHeavy' | 'dotted' | 'dottedHeavy' | 'heavy' | 'none' | 'sng' | 'wavy' | 'wavyDbl' | 'wavyHeavy' | 'words';
790
+ color?: Color;
791
+ };
792
+ /**
793
+ * vertical alignment
794
+ * @default 'top'
795
+ */
796
+ valign?: VAlign;
797
+ }
798
+ interface TextGlowProps {
799
+ /**
800
+ * Border color (hex format)
801
+ * @example 'FF3399'
802
+ */
803
+ color?: HexColor;
804
+ /**
805
+ * opacity (0.0 - 1.0)
806
+ * @example 0.5
807
+ * 50% opaque
808
+ */
809
+ opacity?: number;
810
+ /**
811
+ * size (points)
812
+ */
813
+ size: number;
814
+ }
815
+ interface TextFitShrinkProps {
816
+ /**
817
+ * Shrink text on overflow (`<a:normAutofit>`)
818
+ */
819
+ type: 'shrink';
820
+ /**
821
+ * Font scale as a percent (0-100), mapped to `<a:normAutofit fontScale="..">`.
822
+ *
823
+ * PowerPoint normally calculates this dynamically when text overflows; set it
824
+ * explicitly to bake the scale into the generated file.
825
+ * @example 85 // render text at 85% of its nominal size
826
+ * @default undefined // attribute omitted (PowerPoint defaults to 100%)
827
+ */
828
+ fontScale?: number;
829
+ /**
830
+ * Line-space reduction as a percent (0-100), mapped to `<a:normAutofit lnSpcReduction="..">`.
831
+ * @example 20 // reduce line spacing by 20%
832
+ * @default undefined // attribute omitted (PowerPoint defaults to 0%)
833
+ */
834
+ lnSpcReduction?: number;
835
+ }
836
+ interface TextPropsOptions extends PositionProps, DataOrPathProps, TextBaseProps, ObjectNameProps {
837
+ /**
838
+ * Preset-geometry start/end angles for text frames (`shape` + these build `<a:prstGeom>`
839
+ * adjustment guides through the shared emitter — `genXmlPresetGeom` reads them whether
840
+ * the object is a shape or a styled text frame).
841
+ */
842
+ angleRange?: [number, number];
843
+ /** Preset-geometry block-arc thickness for text frames. */
844
+ arcThicknessRatio?: number;
845
+ /** Custom geometry points when a text frame uses a custom geometry shape. */
846
+ points?: GeometryPoint[];
847
+ /** Preset-geometry adjustment guides for text frames. */
848
+ shapeAdjust?: ShapeAdjustValue | ShapeAdjustValue[];
849
+ _bodyProp?: {
850
+ align?: AlignH;
851
+ anchor?: TextAnchor;
852
+ lIns?: number;
853
+ rIns?: number;
854
+ tIns?: number;
855
+ bIns?: number;
856
+ numCol?: number;
857
+ spcCol?: number;
858
+ vert?: TextVertType;
859
+ wrap?: boolean;
860
+ prstTxWarp?: string;
861
+ };
862
+ _lineIdx?: number;
863
+ baseline?: number;
864
+ /**
865
+ * Character spacing
513
866
  */
514
867
  charSpacing?: number;
515
868
  /**
@@ -965,6 +1318,47 @@ interface ObjectLockProps {
965
1318
  /** Disallow drilling down into the graphical object (e.g. chart data). (tables) */
966
1319
  noDrilldown?: boolean;
967
1320
  }
1321
+ /**
1322
+ * The object descriptors a slide master and a group child both accept.
1323
+ *
1324
+ * Both surfaces take a key-tagged descriptor — one key naming the object kind, its value the
1325
+ * options for that kind — and both accepted the same six. They were written out twice, and the
1326
+ * doc on `GroupChildProps` said as much in as many words: "Uses the same key-tagged descriptor
1327
+ * shape as `SlideMasterObject`". That coupling was real and maintained by hand, which meant a
1328
+ * seventh descriptor added to one was silently missing from the other.
1329
+ *
1330
+ * Each union is now this plus what is genuinely its own — a master adds `chart` and
1331
+ * `placeholder`, a group child adds `group` — so the difference between them is the part you
1332
+ * read, and the shared vocabulary is stated once.
1333
+ */
1334
+ type CommonObjectDescriptor = {
1335
+ image: ImageProps;
1336
+ } | {
1337
+ line: ShapeProps;
1338
+ } | {
1339
+ rect: ShapeProps;
1340
+ } | {
1341
+ roundRect: ShapeProps;
1342
+ } |
1343
+ /**
1344
+ * Any preset shape, addressed by `SHAPE_NAME` (e.g. `ShapeType.ellipse`).
1345
+ * Generalizes the `line`/`rect`/`roundRect` shortcuts to every preset the
1346
+ * `addShape()` serializer supports (ellipse, triangle, chevron, …).
1347
+ *
1348
+ * A union member's comment cannot carry block tags, so this stands in for `@example`:
1349
+ * `{ shape: { type: 'ellipse', options: { x: 1, y: 1, w: 2, h: 2, fill: { color: 'FF0000' } } } }`
1350
+ */
1351
+ {
1352
+ shape: {
1353
+ type: SHAPE_NAME;
1354
+ options?: ShapeProps;
1355
+ };
1356
+ } | {
1357
+ text: {
1358
+ text: string | number | TextProps[];
1359
+ options?: TextPropsOptions;
1360
+ };
1361
+ };
968
1362
  //#endregion
969
1363
  //#region src/types/chart.d.ts
970
1364
  type ChartAxisTickMark = 'none' | 'inside' | 'outside' | 'cross';
@@ -1840,6 +2234,26 @@ type TextVerticalType = (typeof TEXT_VERTICAL)[number];
1840
2234
  */
1841
2235
  declare const PRESET_LINE_DASHES: readonly ['solid', 'dot', 'dash', 'lgDash', 'dashDot', 'lgDashDot', 'lgDashDotDot', 'sysDash', 'sysDot', 'sysDashDot', 'sysDashDotDot'];
1842
2236
  type PresetLineDashVal = (typeof PRESET_LINE_DASHES)[number];
2237
+ /**
2238
+ * The twelve theme colour slots (`a:clrScheme` children) a `p:clrMap` token can point at.
2239
+ *
2240
+ * Not an `ST_` type — these are element names inside `a:CT_ColorScheme`, which the schema
2241
+ * declares as a fixed sequence rather than an enumeration. The effect is the same: a closed,
2242
+ * ordered set of twelve names, in the order the scheme declares them.
2243
+ * @see ECMA-376 Part 1 §20.1.6.2
2244
+ */
2245
+ declare const THEME_COLOR_SLOTS: readonly ['dk1', 'lt1', 'dk2', 'lt2', 'accent1', 'accent2', 'accent3', 'accent4', 'accent5', 'accent6', 'hlink', 'folHlink'];
2246
+ type ThemeColorSlot = (typeof THEME_COLOR_SLOTS)[number];
2247
+ /**
2248
+ * The twelve colour-map tokens (`p:clrMap` attributes), in schema attribute order.
2249
+ *
2250
+ * A slide's `schemeClr val="tx1"` names a *token*, not a slot: the master's `p:clrMap` is the
2251
+ * indirection that sends it to a {@link ThemeColorSlot}. Which is why the two lists look alike
2252
+ * and are not the same list — `bg1`/`tx1` are tokens, `lt1`/`dk1` are slots.
2253
+ * @see ECMA-376 Part 1 §19.3.1.6
2254
+ */
2255
+ declare const COLOR_MAP_TOKENS: readonly ['bg1', 'tx1', 'bg2', 'tx2', 'accent1', 'accent2', 'accent3', 'accent4', 'accent5', 'accent6', 'hlink', 'folHlink'];
2256
+ type ColorMapToken = (typeof COLOR_MAP_TOKENS)[number];
1843
2257
  //#endregion
1844
2258
  //#region src/types/style.d.ts
1845
2259
  interface BorderProps {
@@ -1850,868 +2264,515 @@ interface BorderProps {
1850
2264
  type?: 'none' | 'dash' | 'solid';
1851
2265
  /**
1852
2266
  * Dash pattern, using the same vocabulary as {@link ShapeLineProps.dashType}.
1853
- *
1854
- * `type` is only a coarse three-way switch, so every dashed border it can express
1855
- * collapses onto `sysDash`. Set this to pick the exact `a:prstDash` preset instead:
1856
- * `dashType: 'lgDashDot'` emits `<a:prstDash val="lgDashDot"/>`.
1857
- *
1858
- * **Precedence.** When both are set, `dashType` wins over `type` for the dash pattern —
1859
- * `{ type: 'solid', dashType: 'sysDot' }` draws a dotted rule. The one exception is
1860
- * `type: 'none'`, which suppresses the border entirely and is decided before any dash
1861
- * pattern is chosen. An unrecognized value warns and falls back to what `type` implies.
1862
- * @default (derived from `type`: `sysDash` for `'dash'`, else `solid`)
1863
- * @example { type: 'solid', color: '999999', dashType: 'lgDash' }
1864
- */
1865
- dashType?: ShapeLineProps['dashType'];
1866
- /**
1867
- * Border color (hex)
1868
- * @example 'FF3399'
1869
- * @default '666666'
1870
- */
1871
- color?: HexColor;
1872
- /**
1873
- * Border width (points)
1874
- * - MS-PPT > Format Shape > Fill & Line > Line > Width
1875
- * @default 1
1876
- */
1877
- width?: number;
1878
- /**
1879
- * Border transparency (percent)
1880
- * - MS-PPT > Format Shape > Fill & Line > Line > Transparency
1881
- * - range: 0-100
1882
- * @default 0
1883
- */
1884
- transparency?: number;
1885
- /**
1886
- * Line end cap style
1887
- * @default 'flat'
1888
- */
1889
- cap?: LineCap;
1890
- }
1891
- /**
1892
- * Slide-show navigation action for action-button shapes. Each value maps 1:1 onto
1893
- * `ppaction://hlinkshowjump?jump=<value>`. A specific numbered slide is reached via
1894
- * `HyperlinkProps.slide` instead (which emits `ppaction://hlinksldjump`).
1895
- */
1896
- type HyperlinkActionJump = 'firstslide' | 'previousslide' | 'nextslide' | 'lastslide' | 'lastslideviewed' | 'endshow';
1897
- interface HyperlinkProps {
1898
- _rId?: number;
1899
- /**
1900
- * Slide number to link to
1901
- */
1902
- slide?: number;
1903
- /**
1904
- * Url to link to
1905
- */
1906
- url?: string;
1907
- /**
1908
- * Hyperlink Tooltip
1909
- */
1910
- tooltip?: string;
1911
- /**
1912
- * Slide-show navigation action for action-button shapes. Emits a relationship-less
1913
- * `<a:hlinkClick action="ppaction://hlinkshowjump?jump=…"/>` on the shape.
1914
- * @example hyperlink: { action: 'nextslide' }
1915
- */
1916
- action?: HyperlinkActionJump;
1917
- }
1918
- interface ShadowProps {
1919
- /**
1920
- * shadow type
1921
- * @default 'none'
1922
- */
1923
- type: 'outer' | 'inner' | 'none';
1924
- /**
1925
- * shadow transparency (percent)
1926
- * - MS-PPT > Format Shape > Effects > Shadow > Transparency
1927
- * - range: 0-100 (0 = fully opaque, 100 = fully transparent)
1928
- * @example 25 // 25% transparent
1929
- */
1930
- transparency?: number;
1931
- /**
1932
- * blur (points)
1933
- * - range: 0-100
1934
- * @default 0
1935
- */
1936
- blur?: number;
1937
- /**
1938
- * angle (degrees)
1939
- * - range: 0-359
1940
- * @default 0
1941
- */
1942
- angle?: number;
1943
- /**
1944
- * shadow offset (points)
1945
- * - range: 0-200
1946
- * @default 0
1947
- */
1948
- offset?: number;
1949
- /**
1950
- * shadow color (hex format)
1951
- * @example 'FF3399'
1952
- */
1953
- color?: HexColor;
1954
- /**
1955
- * whether to rotate shadow with shape
1956
- * @default false
1957
- */
1958
- rotateWithShape?: boolean;
1959
- }
1960
- interface ShapeFillProps {
1961
- /**
1962
- * Fill color
1963
- * - `HexColor` or `ThemeColor`
1964
- * @example 'FF0000' // hex color (red)
1965
- * @example SchemeColor.text1 // Theme color (Text1)
1966
- */
1967
- color?: Color;
1968
- /**
1969
- * Transparency (percent)
1970
- * - MS-PPT > Format Shape > Fill & Line > Fill > Transparency
1971
- * - range: 0-100
1972
- * @default 0
1973
- */
1974
- transparency?: number;
1975
- /**
1976
- * Fill type
1977
- *
1978
- * `'none'` and `'inherit'` are different states, and both have to be spelled out
1979
- * because omitting `fill` is not one of them: the shape/text-box emitter defaults a
1980
- * missing `fill` to `<a:noFill/>`.
1981
- * - `'none'` emits `<a:noFill/>` — an explicit transparent interior.
1982
- * - `'inherit'` emits no fill child at all, leaving the interior to
1983
- * `p:style/a:fillRef` or the placeholder. This is the only way to author that
1984
- * state from `addShape`/`addText`.
1985
- *
1986
- * On a table cell (`TableCellProps.fill`) and a slide background the two spellings
1987
- * differ the same way, except that *omitting* the option there already means
1988
- * inherit, so `'inherit'` is merely the explicit form of the default.
1989
- * @default 'solid'
1990
- */
1991
- type?: 'none' | 'inherit' | 'solid' | 'gradient' | 'pattern' | 'image';
1992
- /**
1993
- * Native PPTX gradient fill options.
1994
- */
1995
- gradient?: GradientFillProps;
1996
- /**
1997
- * Native PPTX pattern fill options.
1998
- */
1999
- pattern?: PatternFillProps;
2000
- /**
2001
- * Native PPTX picture fill options. Setting this (or `type: 'image'`) fills the
2002
- * shape interior with a stretched bitmap instead of a color.
2267
+ *
2268
+ * `type` is only a coarse three-way switch, so every dashed border it can express
2269
+ * collapses onto `sysDash`. Set this to pick the exact `a:prstDash` preset instead:
2270
+ * `dashType: 'lgDashDot'` emits `<a:prstDash val="lgDashDot"/>`.
2271
+ *
2272
+ * **Precedence.** When both are set, `dashType` wins over `type` for the dash pattern —
2273
+ * `{ type: 'solid', dashType: 'sysDot' }` draws a dotted rule. The one exception is
2274
+ * `type: 'none'`, which suppresses the border entirely and is decided before any dash
2275
+ * pattern is chosen. An unrecognized value warns and falls back to what `type` implies.
2276
+ * @default (derived from `type`: `sysDash` for `'dash'`, else `solid`)
2277
+ * @example { type: 'solid', color: '999999', dashType: 'lgDash' }
2003
2278
  */
2004
- image?: ImageFillProps;
2279
+ dashType?: ShapeLineProps['dashType'];
2005
2280
  /**
2006
- * Resolved media relationship id for an image fill, assigned at add-time.
2007
- * @internal
2281
+ * Border color (hex)
2282
+ * @example 'FF3399'
2283
+ * @default '666666'
2008
2284
  */
2009
- _imgRid?: number;
2010
- }
2011
- /**
2012
- * Line (stroke) options.
2013
- *
2014
- * A stroke is painted like a fill: in addition to a solid `color`, it accepts the
2015
- * inherited `gradient`/`pattern`/`image` fill options (DrawingML allows the same
2016
- * fill group inside `<a:ln>`). Setting `gradient` (or `type: 'gradient'`) paints a
2017
- * gradient stroke, e.g. `line: { width: 1, gradient: { kind: 'linear', angle: 0,
2018
- * stops: [{ position: 0, color: 'accent3' }, { position: 100, color: 'accent4' }] } }`.
2019
- */
2020
- interface ShapeLineProps extends ShapeFillProps {
2285
+ color?: HexColor;
2021
2286
  /**
2022
- * Line width (pt)
2287
+ * Border width (points)
2288
+ * - MS-PPT > Format Shape > Fill & Line > Line > Width
2023
2289
  * @default 1
2024
2290
  */
2025
2291
  width?: number;
2026
2292
  /**
2027
- * Dash type — the full `ST_PresetLineDashVal` set, so any dash a source deck can
2028
- * carry can also be authored and replicated.
2029
- * @default 'solid'
2293
+ * Border transparency (percent)
2294
+ * - MS-PPT > Format Shape > Fill & Line > Line > Transparency
2295
+ * - range: 0-100
2296
+ * @default 0
2030
2297
  */
2031
- dashType?: PresetLineDashVal;
2298
+ transparency?: number;
2032
2299
  /**
2033
2300
  * Line end cap style
2034
2301
  * @default 'flat'
2035
2302
  */
2036
2303
  cap?: LineCap;
2037
- /**
2038
- * Begin arrow type
2039
- */
2040
- beginArrowType?: 'none' | 'arrow' | 'diamond' | 'oval' | 'stealth' | 'triangle';
2041
- /**
2042
- * End arrow type
2043
- */
2044
- endArrowType?: 'none' | 'arrow' | 'diamond' | 'oval' | 'stealth' | 'triangle';
2045
2304
  }
2046
2305
  /**
2047
- * Connector routing style. Maps to a connector preset geometry. The exact preset
2048
- * also depends on `bends` (number of jogs):
2049
- * `straight`→`straightConnector1`; `elbow`→`bentConnector{3,4,5}`;
2050
- * `curved`→`curvedConnector{3,4,5}`.
2051
- */
2052
- type ConnectorType = 'straight' | 'elbow' | 'curved';
2053
- /**
2054
- * A connector is a line drawn between two points, emitted as a PowerPoint connector
2055
- * (`<p:cxnSp>`) so the app treats it as a connector (selectable/reroutable) rather than a
2056
- * plain line shape. Endpoints are given directly; the bounding box and flip flags are derived.
2306
+ * Slide-show navigation action for action-button shapes. Each value maps 1:1 onto
2307
+ * `ppaction://hlinkshowjump?jump=<value>`. A specific numbered slide is reached via
2308
+ * `HyperlinkProps.slide` instead (which emits `ppaction://hlinksldjump`).
2057
2309
  */
2058
- interface ConnectorProps {
2059
- /**
2060
- * Routing style
2061
- * @default 'straight'
2062
- */
2063
- type?: ConnectorType;
2064
- /**
2065
- * Number of adjustable bends (jogs) for an `elbow` / `curved` connector. Selects the
2066
- * preset variant and how many `adj` values it accepts:
2067
- * - `1` → `bentConnector3` / `curvedConnector3` (one jog) — the default
2068
- * - `2` → `bentConnector4` / `curvedConnector4` (two jogs)
2069
- * - `3` → `bentConnector5` / `curvedConnector5` (three jogs)
2070
- *
2071
- * Ignored for `type: 'straight'` (a straight connector has no bends).
2072
- * @default 1
2073
- */
2074
- bends?: 1 | 2 | 3;
2075
- /**
2076
- * Bend position(s) as a percent of the connector box (`0`–`100`), one value per bend.
2077
- * A single number sets the sole jog of a one-bend `elbow` / `curved`; an array sets each
2078
- * jog of a multi-bend connector and its length must equal `bends`. Values outside `0`–`100`
2079
- * are allowed (they place the bend beyond the endpoint box, as PowerPoint itself does when
2080
- * endpoints flip). When omitted, PowerPoint uses the preset default (50%).
2081
- *
2082
- * Emitted as `<a:gd name="adj1…" fmla="val …"/>` adjust guides (OOXML 1000ths-of-a-percent).
2083
- */
2084
- adj?: number | number[];
2085
- /**
2086
- * Bind the connector's start point to a shape on the **same slide**, referenced by that
2087
- * shape's `objectName`. Emits `<a:stCxn id=… idx=…>`, so PowerPoint treats the endpoint as
2088
- * attached: it reroutes when the shape moves and its elbow auto-router can engage.
2089
- * The shape's `objectName` must be set and unique on the slide. `x1`/`y1` remain the static
2090
- * fallback geometry (and are used if the name can't be resolved).
2091
- *
2092
- * A shape inside a group is a valid target — group children are named on the same slide — though
2093
- * the connector itself cannot be a group child (see {@link Slide.addGroup}).
2094
- */
2095
- startShape?: string;
2310
+ type HyperlinkActionJump = 'firstslide' | 'previousslide' | 'nextslide' | 'lastslide' | 'lastslideviewed' | 'endshow';
2311
+ interface HyperlinkProps {
2312
+ _rId?: number;
2096
2313
  /**
2097
- * Connection-site index on `startShape` (0-based; the valid range is preset-dependent — a
2098
- * shape's `<a:cxnLst>` enumerates its sites). Ignored without `startShape`.
2099
- * @default 0
2314
+ * Slide number to link to
2100
2315
  */
2101
- startShapeIdx?: number;
2102
- /** Bind the connector's end point to a shape on the same slide (by `objectName`). Emits `<a:endCxn>`. See {@link startShape}. */
2103
- endShape?: string;
2316
+ slide?: number;
2104
2317
  /**
2105
- * Connection-site index on `endShape`. Ignored without `endShape`.
2106
- * @default 0
2318
+ * Url to link to
2107
2319
  */
2108
- endShapeIdx?: number;
2109
- /** Start point X — inches, or a `Coord` such as `'50%'` / `'2in'` */
2110
- x1: Coord;
2111
- /** Start point Y */
2112
- y1: Coord;
2113
- /** End point X */
2114
- x2: Coord;
2115
- /** End point Y */
2116
- y2: Coord;
2320
+ url?: string;
2117
2321
  /**
2118
- * Line color (6-digit hex, no `#`)
2119
- * @default '000000'
2322
+ * Hyperlink Tooltip
2120
2323
  */
2121
- color?: HexColor;
2324
+ tooltip?: string;
2122
2325
  /**
2123
- * Line width (pt)
2124
- * @default 1
2326
+ * Slide-show navigation action for action-button shapes. Emits a relationship-less
2327
+ * `<a:hlinkClick action="ppaction://hlinkshowjump?jump=…"/>` on the shape.
2328
+ * @example hyperlink: { action: 'nextslide' }
2125
2329
  */
2126
- width?: number;
2127
- /** Dash style */
2128
- dashType?: ShapeLineProps['dashType'];
2129
- /** Arrowhead at the start point */
2130
- beginArrowType?: ShapeLineProps['beginArrowType'];
2131
- /** Arrowhead at the end point */
2132
- endArrowType?: ShapeLineProps['endArrowType'];
2133
- /** Selection Pane object name */
2134
- objectName?: string;
2135
- /** Accessibility alt text */
2136
- altText?: string;
2330
+ action?: HyperlinkActionJump;
2137
2331
  }
2138
- //#endregion
2139
- //#region src/types/core.d.ts
2140
- /**
2141
- * Coordinate value. A bare `number` is **always inches** — there is no magnitude-based unit
2142
- * guessing. For other units use an explicit string suffix:
2143
- * - `number` → inches (e.g. `10.25`)
2144
- * - `"<n>%"` → percentage of the slide axis (e.g. `"75%"`)
2145
- * - `"<n>in"` → inches (e.g. `"10.25in"`)
2146
- * - `"<n>pt"` → points (e.g. `"72pt"` = 1 inch)
2147
- * - `"<n>px"` → CSS reference pixels at 96 px/inch (e.g. `"96px"` = 1 inch), for authoring against
2148
- * a known web/source canvas size
2149
- * - `"<n>emu"` → raw EMU, the escape hatch for exact OOXML units (e.g. `"914400emu"` = 1 inch)
2150
- *
2151
- * @example 10.25 // inches
2152
- * @example '75%' // percentage of slide size
2153
- * @example '72pt' // points
2154
- * @example '960px' // pixels at 96 DPI = 10 inches
2155
- * @example '914400emu' // raw EMU
2156
- */
2157
- type Coord = number | `${number}%` | `${number}in` | `${number}pt` | `${number}px` | `${number}emu`;
2158
- interface PositionProps {
2332
+ interface ShadowProps {
2159
2333
  /**
2160
- * Horizontal position
2161
- * - inches or percentage
2162
- * @example 10.25 // position in inches
2163
- * @example '75%' // position as percentage of slide size
2334
+ * shadow type
2335
+ * @default 'none'
2164
2336
  */
2165
- x?: Coord;
2337
+ type: 'outer' | 'inner' | 'none';
2166
2338
  /**
2167
- * Vertical position
2168
- * - inches or percentage
2169
- * @example 10.25 // position in inches
2170
- * @example '75%' // position as percentage of slide size
2339
+ * shadow transparency (percent)
2340
+ * - MS-PPT > Format Shape > Effects > Shadow > Transparency
2341
+ * - range: 0-100 (0 = fully opaque, 100 = fully transparent)
2342
+ * @example 25 // 25% transparent
2171
2343
  */
2172
- y?: Coord;
2344
+ transparency?: number;
2173
2345
  /**
2174
- * Height
2175
- * - inches or percentage
2176
- * @example 10.25 // height in inches
2177
- * @example '75%' // height as percentage of slide size
2346
+ * blur (points)
2347
+ * - range: 0-100
2348
+ * @default 0
2178
2349
  */
2179
- h?: Coord;
2350
+ blur?: number;
2180
2351
  /**
2181
- * Width
2182
- * - inches or percentage
2183
- * @example 10.25 // width in inches
2184
- * @example '75%' // width as percentage of slide size
2352
+ * angle (degrees)
2353
+ * - range: 0-359
2354
+ * @default 0
2185
2355
  */
2186
- w?: Coord;
2187
- }
2188
- /**
2189
- * Reusable optional data/path fields.
2190
- * Use `DataOrPathRequiredProps` for APIs that require at least one source.
2191
- */
2192
- interface DataOrPathProps {
2356
+ angle?: number;
2193
2357
  /**
2194
- * URL or relative path
2195
- *
2196
- * @example 'https://onedrives.com/myimg.png` // retrieve image via URL
2197
- * @example '/home/user/images/myimg.png` // retrieve image via local path
2358
+ * shadow offset (points)
2359
+ * - range: 0-200
2360
+ * @default 0
2198
2361
  */
2199
- path?: string;
2362
+ offset?: number;
2200
2363
  /**
2201
- * base64-encoded string
2202
- * - Useful for avoiding potential path/server issues
2203
- *
2204
- * @example 'image/png;base64,iVtDafDrBF[...]=' // pre-encoded image in base-64
2364
+ * shadow color (hex format)
2365
+ * @example 'FF3399'
2205
2366
  */
2206
- data?: string;
2207
- }
2208
- type DataOrPathRequiredProps = (DataOrPathProps & {
2209
- data: string;
2210
- }) | (DataOrPathProps & {
2211
- path: string;
2212
- });
2213
- interface BackgroundProps extends DataOrPathProps, ShapeFillProps {}
2214
- /**
2215
- * Color in Hex format
2216
- * @example 'FF3399'
2217
- */
2218
- type HexColor = string;
2219
- type ThemeColor = 'tx1' | 'tx2' | 'bg1' | 'bg2' | 'accent1' | 'accent2' | 'accent3' | 'accent4' | 'accent5' | 'accent6';
2220
- type Color = HexColor | ThemeColor;
2221
- interface GradientStopProps {
2367
+ color?: HexColor;
2222
2368
  /**
2223
- * Stop position as a percentage.
2224
- * - range: 0-100
2369
+ * whether to rotate shadow with shape
2370
+ * @default false
2225
2371
  */
2226
- position: number;
2372
+ rotateWithShape?: boolean;
2373
+ }
2374
+ interface ShapeFillProps {
2227
2375
  /**
2228
- * Stop color.
2376
+ * Fill color
2229
2377
  * - `HexColor` or `ThemeColor`
2378
+ * @example 'FF0000' // hex color (red)
2379
+ * @example SchemeColor.text1 // Theme color (Text1)
2230
2380
  */
2231
- color: Color;
2381
+ color?: Color;
2232
2382
  /**
2233
2383
  * Transparency (percent)
2384
+ * - MS-PPT > Format Shape > Fill & Line > Fill > Transparency
2234
2385
  * - range: 0-100
2235
2386
  * @default 0
2236
2387
  */
2237
2388
  transparency?: number;
2238
- }
2239
- interface LinearGradientFillProps {
2240
- /**
2241
- * Gradient type.
2242
- */
2243
- kind: 'linear';
2244
- /**
2245
- * Gradient angle in degrees. Values are normalized into 0-359.999...
2246
- * @default 0
2247
- */
2248
- angle?: number;
2249
- /**
2250
- * Whether the gradient angle scales with the fill region.
2251
- */
2252
- scaled?: boolean;
2253
- /**
2254
- * Whether the fill rotates with the shape.
2255
- * @default true
2256
- */
2257
- rotateWithShape?: boolean;
2258
2389
  /**
2259
- * Gradient stops. Stops are serialized in ascending `position` order.
2390
+ * Fill type
2391
+ *
2392
+ * `'none'` and `'inherit'` are different states, and both have to be spelled out
2393
+ * because omitting `fill` is not one of them: the shape/text-box emitter defaults a
2394
+ * missing `fill` to `<a:noFill/>`.
2395
+ * - `'none'` emits `<a:noFill/>` — an explicit transparent interior.
2396
+ * - `'inherit'` emits no fill child at all, leaving the interior to
2397
+ * `p:style/a:fillRef` or the placeholder. This is the only way to author that
2398
+ * state from `addShape`/`addText`.
2399
+ *
2400
+ * On a table cell (`TableCellProps.fill`) and a slide background the two spellings
2401
+ * differ the same way, except that *omitting* the option there already means
2402
+ * inherit, so `'inherit'` is merely the explicit form of the default.
2403
+ * @default 'solid'
2260
2404
  */
2261
- stops: GradientStopProps[];
2262
- }
2263
- interface RadialGradientFillProps {
2405
+ type?: 'none' | 'inherit' | 'solid' | 'gradient' | 'pattern' | 'image';
2264
2406
  /**
2265
- * Gradient type. A circular gradient radiating from a focus point: the stop at
2266
- * `position: 0` sits at the center and later stops fan outward to the edges.
2407
+ * Native PPTX gradient fill options.
2267
2408
  */
2268
- kind: 'radial';
2409
+ gradient?: GradientFillProps;
2269
2410
  /**
2270
- * Focus point of the radial gradient as percentages of the fill box, where
2271
- * `{ x: 50, y: 50 }` (the default) centers it. Lower/higher values push the
2272
- * bright center toward an edge.
2273
- * @default { x: 50, y: 50 }
2411
+ * Native PPTX pattern fill options.
2274
2412
  */
2275
- center?: {
2276
- x: number;
2277
- y: number;
2278
- };
2413
+ pattern?: PatternFillProps;
2279
2414
  /**
2280
- * Whether the fill rotates with the shape.
2281
- * @default true
2415
+ * Native PPTX picture fill options. Setting this (or `type: 'image'`) fills the
2416
+ * shape interior with a stretched bitmap instead of a color.
2282
2417
  */
2283
- rotateWithShape?: boolean;
2418
+ image?: ImageFillProps;
2284
2419
  /**
2285
- * Gradient stops. Stops are serialized in ascending `position` order; the
2286
- * first (`position: 0`) is the center color.
2420
+ * Resolved media relationship id for an image fill, assigned at add-time.
2421
+ * @internal
2287
2422
  */
2288
- stops: GradientStopProps[];
2289
- }
2290
- type GradientFillProps = LinearGradientFillProps | RadialGradientFillProps;
2291
- /** OOXML ST_PresetPatternVal — preset pattern names for `<a:pattFill prst="...">` */
2292
- type PatternPreset = 'pct5' | 'pct10' | 'pct20' | 'pct25' | 'pct30' | 'pct40' | 'pct50' | 'pct60' | 'pct70' | 'pct75' | 'pct80' | 'pct90' | 'horz' | 'vert' | 'ltHorz' | 'ltVert' | 'dkHorz' | 'dkVert' | 'narHorz' | 'narVert' | 'dashHorz' | 'dashVert' | 'cross' | 'dnDiag' | 'upDiag' | 'ltDnDiag' | 'ltUpDiag' | 'dkDnDiag' | 'dkUpDiag' | 'wdDnDiag' | 'wdUpDiag' | 'dashDnDiag' | 'dashUpDiag' | 'diagCross' | 'smCheck' | 'lgCheck' | 'smGrid' | 'lgGrid' | 'dotGrid' | 'smConfetti' | 'lgConfetti' | 'horzBrick' | 'diagBrick' | 'solidDmnd' | 'openDmnd' | 'dotDmnd' | 'plaid' | 'sphere' | 'weave' | 'divot' | 'shingle' | 'wave' | 'trellis' | 'zigZag';
2293
- interface PatternFillProps {
2294
- /** OOXML preset pattern (`prst` attribute on `<a:pattFill>`). */
2295
- preset: PatternPreset;
2296
- /** Foreground color. Defaults to black (`000000`) if omitted. */
2297
- fgColor?: Color;
2298
- /** Background color. Defaults to white (`FFFFFF`) if omitted. */
2299
- bgColor?: Color;
2300
- }
2301
- /**
2302
- * Native PPTX picture (image) fill — fills a shape's interior with a bitmap
2303
- * (`<a:blipFill>`). Provide exactly one of `path` or `data`; raster formats only
2304
- * (PNG/JPEG/GIF/BMP/WebP). SVG is not yet supported as a fill source.
2305
- */
2306
- interface ImageFillProps {
2307
- /** Image file path (Node filesystem path or URL). */
2308
- path?: string;
2309
- /** Pre-encoded base64 data URI, e.g. `'image/png;base64,iVBOR...'`. */
2310
- data?: string;
2423
+ _imgRid?: number;
2311
2424
  }
2312
- type Margin = number | [number, number, number, number];
2313
- type HAlign = 'left' | 'center' | 'right' | 'justify';
2314
- type VAlign = 'top' | 'middle' | 'bottom';
2315
- /**
2316
- * Text body `vert` attribute — flow/rotation direction of the text within its box.
2317
- * Maps to `<a:bodyPr vert="…">` (ECMA-376 `ST_TextVerticalType`).
2318
- */
2319
- type TextVertType = TextVerticalType;
2320
2425
  /**
2321
- * A single node of a freeform (`custGeom`) path.
2322
- * - coordinates are authored in the object's own inch/EMU space (0..width, 0..height), not slide-relative and not normalized
2323
- * - used by shapes (`ShapeType.custGeom`) and by images (clips the picture to the path)
2426
+ * Line (stroke) options.
2324
2427
  *
2325
- * The `arc` node carries no `x`/`y`: an `<a:arcTo>` has no explicit end point. The renderer
2326
- * derives it from the current pen position, the radii and the swept angle, so an end point
2327
- * authored here would be discarded (a warning is emitted if one is supplied).
2428
+ * A stroke is painted like a fill: in addition to a solid `color`, it accepts the
2429
+ * inherited `gradient`/`pattern`/`image` fill options (DrawingML allows the same
2430
+ * fill group inside `<a:ln>`). Setting `gradient` (or `type: 'gradient'`) paints a
2431
+ * gradient stroke, e.g. `line: { width: 1, gradient: { kind: 'linear', angle: 0,
2432
+ * stops: [{ position: 0, color: 'accent3' }, { position: 100, color: 'accent4' }] } }`.
2328
2433
  */
2329
- type GeometryPoint = {
2330
- x: Coord;
2331
- y: Coord;
2332
- moveTo?: boolean;
2333
- } | {
2334
- curve: {
2335
- type: 'arc';
2336
- hR: Coord;
2337
- wR: Coord;
2338
- stAng: number;
2339
- swAng: number;
2340
- };
2341
- } | {
2342
- x: Coord;
2343
- y: Coord;
2344
- curve: {
2345
- type: 'cubic';
2346
- x1: Coord;
2347
- y1: Coord;
2348
- x2: Coord;
2349
- y2: Coord;
2350
- };
2351
- } | {
2352
- x: Coord;
2353
- y: Coord;
2354
- curve: {
2355
- type: 'quadratic';
2356
- x1: Coord;
2357
- y1: Coord;
2358
- };
2359
- } | {
2360
- close: true;
2361
- };
2362
- //#endregion
2363
- //#region src/types/media.d.ts
2364
- type MediaType = 'audio' | 'online' | 'video';
2365
- interface ImageBaseProps extends PositionProps, ObjectNameProps {
2366
- /**
2367
- * Sizing note (`w`/`h` inherited from {@link PositionProps}):
2368
- * - When a `data` (base64) image is supplied and `w`/`h` are omitted, the natural pixel
2369
- * size is read from the image header (PNG/JPEG/GIF/BMP/WebP) and used at 96 DPI
2370
- * (natural pixels / 96 = inches).
2371
- * - When only one of `w`/`h` is given, the other is derived from the natural aspect ratio —
2372
- * for an SVG too, from its `width`/`height` or `viewBox`.
2373
- * - A `path` image is measured at export time (its bytes are not available synchronously);
2374
- * an omitted dimension falls back to 1 inch if it stays unmeasurable.
2375
- * - An SVG with *neither* dimension given also falls back to 1 inch: its user units carry a
2376
- * dependable aspect ratio but only a conventional magnitude, so a 24-unit icon is not
2377
- * treated as a quarter-inch object.
2378
- * - A vector source placed in a box whose ratio differs from its own is letterboxed, not
2379
- * stretched; see {@link sizing} to override.
2380
- */
2381
- /**
2382
- * Alt Text value ("How would you describe this object and its contents to someone who is blind?")
2383
- * - PowerPoint: [right-click on an image] > "Edit Alt Text..."
2384
- */
2385
- altText?: string;
2386
- /**
2387
- * Flip horizontally?
2388
- * @default false
2389
- */
2390
- flipH?: boolean;
2391
- /**
2392
- * Flip vertical?
2393
- * @default false
2394
- */
2395
- flipV?: boolean;
2396
- hyperlink?: HyperlinkProps;
2434
+ interface ShapeLineProps extends ShapeFillProps {
2397
2435
  /**
2398
- * Border line (`<a:ln>` outline) drawn around the image
2399
- * - same options as a shape outline; a picture supports a single outline, not per-side borders
2400
- * - MS-PPT: Format Picture > Line
2401
- * @example { color: '0088CC', width: 2 } // 2pt blue border
2402
- * @example { color: '666666', width: 1, dashType: 'dash' } // dashed gray border
2436
+ * Line width (pt)
2437
+ * @default 1
2403
2438
  */
2404
- line?: ShapeLineProps;
2439
+ width?: number;
2405
2440
  /**
2406
- * Name of a picture placeholder defined on the slide layout/master to populate
2407
- * - when it matches a layout/master placeholder, the image inherits that placeholder's
2408
- * position and size for any of `x`/`y`/`w`/`h` not supplied explicitly;
2409
- * explicit values always win
2410
- * @example 'picph'
2411
- * @see https://docs.microsoft.com/en-us/office/vba/api/powerpoint.ppplaceholdertype
2441
+ * Dash type — the full `ST_PresetLineDashVal` set, so any dash a source deck can
2442
+ * carry can also be authored and replicated.
2443
+ * @default 'solid'
2412
2444
  */
2413
- placeholder?: string;
2445
+ dashType?: PresetLineDashVal;
2414
2446
  /**
2415
- * Image rotation (degrees)
2416
- * - range: -360 to 360
2417
- * @default 0
2418
- * @example 180 // rotate image 180 degrees
2447
+ * Line end cap style
2448
+ * @default 'flat'
2419
2449
  */
2420
- rotate?: number;
2450
+ cap?: LineCap;
2421
2451
  /**
2422
- * Enable image rounding (clips the image to a circle/ellipse)
2423
- * - shorthand for `shape: 'ellipse'`; `shape` takes precedence when both are set
2424
- * @default false
2452
+ * Begin arrow type
2425
2453
  */
2426
- rounding?: boolean;
2454
+ beginArrowType?: 'none' | 'arrow' | 'diamond' | 'oval' | 'stealth' | 'triangle';
2427
2455
  /**
2428
- * Clip the image to a preset shape geometry ("fit image into shape")
2429
- * - accepts any PowerPoint preset geometry name, e.g. `'roundRect'`, `'hexagon'`, `'ellipse'`
2430
- * - combine with `sizing: { type: 'cover', ... }` for an aspect-correct fill of the shape box
2431
- * - use `rectRadius` to set the corner radius for `'roundRect'`
2432
- * @example 'roundRect' // rounded-rectangle avatar
2433
- * @example 'hexagon' // hexagonal photo
2456
+ * End arrow type
2434
2457
  */
2435
- shape?: SHAPE_NAME;
2458
+ endArrowType?: 'none' | 'arrow' | 'diamond' | 'oval' | 'stealth' | 'triangle';
2459
+ }
2460
+ /**
2461
+ * Connector routing style. Maps to a connector preset geometry. The exact preset
2462
+ * also depends on `bends` (number of jogs):
2463
+ * `straight`→`straightConnector1`; `elbow`→`bentConnector{3,4,5}`;
2464
+ * `curved`→`curvedConnector{3,4,5}`.
2465
+ */
2466
+ type ConnectorType = 'straight' | 'elbow' | 'curved';
2467
+ /**
2468
+ * A connector is a line drawn between two points, emitted as a PowerPoint connector
2469
+ * (`<p:cxnSp>`) so the app treats it as a connector (selectable/reroutable) rather than a
2470
+ * plain line shape. Endpoints are given directly; the bounding box and flip flags are derived.
2471
+ */
2472
+ interface ConnectorProps {
2436
2473
  /**
2437
- * Clip the image to an arbitrary freeform path (`custGeom`)
2438
- * - takes precedence over `shape` / `rounding` when present
2439
- * - coordinates are authored in the image's own inch/EMU space (0..w, 0..h), not slide-relative and not normalized
2440
- * - supports the same path DSL as freeform shapes: `moveTo` / `lnTo` / `cubicBezTo` / `quadBezTo` / `arcTo` / `close`
2441
- * @example [{ x: 1, y: 0 }, { x: 2, y: 2 }, { x: 0, y: 2 }, { close: true }] // triangular photo clip
2474
+ * Routing style
2475
+ * @default 'straight'
2442
2476
  */
2443
- points?: GeometryPoint[];
2477
+ type?: ConnectorType;
2444
2478
  /**
2445
- * Rounded rectangle corner radius (inches) when `shape: 'roundRect'`
2446
- * - values: 0.0 to 1.0
2447
- * @default 0
2479
+ * Number of adjustable bends (jogs) for an `elbow` / `curved` connector. Selects the
2480
+ * preset variant and how many `adj` values it accepts:
2481
+ * - `1` → `bentConnector3` / `curvedConnector3` (one jog) — the default
2482
+ * - `2` → `bentConnector4` / `curvedConnector4` (two jogs)
2483
+ * - `3` → `bentConnector5` / `curvedConnector5` (three jogs)
2484
+ *
2485
+ * Ignored for `type: 'straight'` (a straight connector has no bends).
2486
+ * @default 1
2448
2487
  */
2449
- rectRadius?: number;
2488
+ bends?: 1 | 2 | 3;
2450
2489
  /**
2451
- * Preset-geometry adjustment handles (`<a:avLst>` guides) for the clip `shape`.
2452
- * - tune adjustment handles that lack a dedicated option, e.g. chevron point depth
2453
- * - accepts a single guide or an array; each `value` is a `0.0–1.0` fraction (see {@link ShapeAdjustValue})
2454
- * @example { name: 'adj', value: 0.25 }
2490
+ * Bend position(s) as a percent of the connector box (`0`–`100`), one value per bend.
2491
+ * A single number sets the sole jog of a one-bend `elbow` / `curved`; an array sets each
2492
+ * jog of a multi-bend connector and its length must equal `bends`. Values outside `0`–`100`
2493
+ * are allowed (they place the bend beyond the endpoint box, as PowerPoint itself does when
2494
+ * endpoints flip). When omitted, PowerPoint uses the preset default (50%).
2495
+ *
2496
+ * Emitted as `<a:gd name="adj1…" fmla="val …"/>` adjust guides (OOXML 1000ths-of-a-percent).
2455
2497
  */
2456
- shapeAdjust?: ShapeAdjustValue | ShapeAdjustValue[];
2498
+ adj?: number | number[];
2457
2499
  /**
2458
- * Shadow Props
2459
- * - MS-PPT > Format Picture > Shadow
2460
- * @example
2461
- * { type: 'outer', color: '000000', transparency: 50, blur: 20, offset: 20, angle: 270 }
2500
+ * Bind the connector's start point to a shape on the **same slide**, referenced by that
2501
+ * shape's `objectName`. Emits `<a:stCxn id=… idx=…>`, so PowerPoint treats the endpoint as
2502
+ * attached: it reroutes when the shape moves and its elbow auto-router can engage.
2503
+ * The shape's `objectName` must be set and unique on the slide. `x1`/`y1` remain the static
2504
+ * fallback geometry (and are used if the name can't be resolved).
2505
+ *
2506
+ * A shape inside a group is a valid target — group children are named on the same slide — though
2507
+ * the connector itself cannot be a group child (see {@link Slide.addGroup}).
2462
2508
  */
2463
- shadow?: ShadowProps;
2509
+ startShape?: string;
2464
2510
  /**
2465
- * Crop the source image to a sub-region by percentage edge insets, emitted verbatim
2466
- * as OOXML `<a:srcRect>`.
2467
- * - each value is the percent (0–100) trimmed off that edge of the *source* image, the
2468
- * same model PowerPoint's Picture Format > Crop uses; `l`+`r` and `t`+`b` must each be < 100
2469
- * - the remaining sub-region is stretched to fill the picture's displayed `w`×`h` box, so this
2470
- * is the faithful way to reproduce a deck that maps several icons out of one composite raster
2471
- * - operates on the source image directly (independent of natural-pixel measurement), so unlike
2472
- * `sizing: 'crop'` (which crops in *displayed inches*) it works for SVG and unmeasurable formats
2473
- * - mutually exclusive with {@link sizing}; if both are set `crop` wins and `sizing` is ignored
2474
- * @example { l: 0, t: 0, r: 50, b: 50 } // keep the top-left quadrant of the source image
2511
+ * Connection-site index on `startShape` (0-based; the valid range is preset-dependent — a
2512
+ * shape's `<a:cxnLst>` enumerates its sites). Ignored without `startShape`.
2513
+ * @default 0
2475
2514
  */
2476
- crop?: {
2477
- /** Percent (0–100) trimmed from the left edge of the source image. @default 0 */
2478
- l?: number;
2479
- /** Percent (0–100) trimmed from the top edge of the source image. @default 0 */
2480
- t?: number;
2481
- /** Percent (0–100) trimmed from the right edge of the source image. @default 0 */
2482
- r?: number;
2483
- /** Percent (0–100) trimmed from the bottom edge of the source image. @default 0 */
2484
- b?: number;
2485
- };
2515
+ startShapeIdx?: number;
2516
+ /** Bind the connector's end point to a shape on the same slide (by `objectName`). Emits `<a:endCxn>`. See {@link startShape}. */
2517
+ endShape?: string;
2486
2518
  /**
2487
- * Image sizing options
2488
- * - omit entirely for the default: a raster fills the `w`×`h` box, a vector (SVG) source is
2489
- * letterboxed to its own aspect ratio inside that box
2519
+ * Connection-site index on `endShape`. Ignored without `endShape`.
2520
+ * @default 0
2490
2521
  */
2491
- sizing?: {
2492
- /**
2493
- * Sizing type
2494
- * - `cover` / `contain` fit the image into the `w`×`h` box using the image's *natural*
2495
- * aspect ratio — read from the embedded PNG/JPEG/GIF/BMP/WebP header, or from an SVG's
2496
- * `width`/`height` or `viewBox`. If the natural size cannot be determined (an
2497
- * unrecognized format, or an SVG carrying neither) the displayed `w`/`h` ratio is used
2498
- * as a fallback and a warning is logged.
2499
- * - `crop` cuts a window out of the displayed image using the `x`/`y`/`w`/`h` offsets.
2500
- * - `stretch` fills the box regardless of aspect ratio. This is what a raster does
2501
- * anyway; name it explicitly to opt a vector source out of its aspect-correct default.
2502
- */
2503
- type: 'contain' | 'cover' | 'crop' | 'stretch';
2504
- /**
2505
- * Image width
2506
- * - inches or percentage
2507
- * - defaults to the picture's own `w`, which is what `cover`/`contain` almost always want
2508
- * @example 10.25 // position in inches
2509
- * @example '75%' // position as percentage of slide size
2510
- */
2511
- w?: Coord;
2512
- /**
2513
- * Image height
2514
- * - inches or percentage
2515
- * - defaults to the picture's own `h`
2516
- * @example 10.25 // position in inches
2517
- * @example '75%' // position as percentage of slide size
2518
- */
2519
- h?: Coord;
2520
- /**
2521
- * Offset from left to crop image
2522
- * - `crop` only
2523
- * - inches or percentage
2524
- * @example 10.25 // position in inches
2525
- * @example '75%' // position as percentage of slide size
2526
- */
2527
- x?: Coord;
2528
- /**
2529
- * Offset from top to crop image
2530
- * - `crop` only
2531
- * - inches or percentage
2532
- * @example 10.25 // position in inches
2533
- * @example '75%' // position as percentage of slide size
2534
- */
2535
- y?: Coord;
2536
- };
2522
+ endShapeIdx?: number;
2523
+ /** Start point X — inches, or a `Coord` such as `'50%'` / `'2in'` */
2524
+ x1: Coord;
2525
+ /** Start point Y */
2526
+ y1: Coord;
2527
+ /** End point X */
2528
+ x2: Coord;
2529
+ /** End point Y */
2530
+ y2: Coord;
2537
2531
  /**
2538
- * Transparency (percent)
2539
- * - MS-PPT > Format Picture > Picture > Picture Transparency > Transparency
2540
- * - range: 0-100
2541
- * @default 0
2542
- * @example 25 // 25% transparent
2532
+ * Line color (6-digit hex, no `#`)
2533
+ * @default '000000'
2543
2534
  */
2544
- transparency?: number;
2535
+ color?: HexColor;
2545
2536
  /**
2546
- * Recolor the image as a two-tone (duotone) effect
2547
- * - maps the image's shadows to `shadow` and its highlights to `highlight`
2548
- * - serializes `<a:duotone>` inside the picture's `<a:blip>` (MS-PPT > Format Picture > Picture Color > Recolor)
2549
- * - colors accept `HexColor` or `ThemeColor`, same as fills
2550
- * - the classic brand treatment: tint stock photography into a single brand hue
2551
- * @example { shadow: '250F6B', highlight: 'FFFFFF' } // deep-blue duotone
2537
+ * Line width (pt)
2538
+ * @default 1
2552
2539
  */
2553
- duotone?: {
2554
- /** Color mapped to the image's dark/shadow tones. */
2555
- shadow: Color;
2556
- /** Color mapped to the image's light/highlight tones. */
2557
- highlight: Color;
2558
- };
2540
+ width?: number;
2541
+ /** Dash style */
2542
+ dashType?: ShapeLineProps['dashType'];
2543
+ /** Arrowhead at the start point */
2544
+ beginArrowType?: ShapeLineProps['beginArrowType'];
2545
+ /** Arrowhead at the end point */
2546
+ endArrowType?: ShapeLineProps['endArrowType'];
2547
+ /** Selection Pane object name */
2548
+ objectName?: string;
2549
+ /** Accessibility alt text */
2550
+ altText?: string;
2551
+ }
2552
+ //#endregion
2553
+ //#region src/types/core.d.ts
2554
+ /**
2555
+ * Coordinate value. A bare `number` is **always inches** — there is no magnitude-based unit
2556
+ * guessing. For other units use an explicit string suffix:
2557
+ * - `number` → inches (e.g. `10.25`)
2558
+ * - `"<n>%"` → percentage of the slide axis (e.g. `"75%"`)
2559
+ * - `"<n>in"` → inches (e.g. `"10.25in"`)
2560
+ * - `"<n>pt"` → points (e.g. `"72pt"` = 1 inch)
2561
+ * - `"<n>px"` → CSS reference pixels at 96 px/inch (e.g. `"96px"` = 1 inch), for authoring against
2562
+ * a known web/source canvas size
2563
+ * - `"<n>emu"` → raw EMU, the escape hatch for exact OOXML units (e.g. `"914400emu"` = 1 inch)
2564
+ *
2565
+ * @example 10.25 // inches
2566
+ * @example '75%' // percentage of slide size
2567
+ * @example '72pt' // points
2568
+ * @example '960px' // pixels at 96 DPI = 10 inches
2569
+ * @example '914400emu' // raw EMU
2570
+ */
2571
+ type Coord = number | `${number}%` | `${number}in` | `${number}pt` | `${number}px` | `${number}emu`;
2572
+ interface PositionProps {
2559
2573
  /**
2560
- * Recolor the image to grayscale (`<a:grayscl/>`)
2561
- * - maps every pixel to its luminance grey (MS-PPT > Format Picture > Picture Color > Recolor > Grayscale)
2562
- * - the cheapest recolour: no payload
2563
- * - mutually exclusive with the other recolour modes (`duotone`/`biLevel`/`clrChange`); if several are set,
2564
- * the first present in document order wins on read-back
2565
- * @default false
2566
- * @example true // desaturate the image
2574
+ * Horizontal position
2575
+ * - inches or percentage
2576
+ * @example 10.25 // position in inches
2577
+ * @example '75%' // position as percentage of slide size
2567
2578
  */
2568
- grayscale?: boolean;
2579
+ x?: Coord;
2569
2580
  /**
2570
- * Recolor the image to two-level black & white (`<a:biLevel thresh="…"/>`)
2571
- * - every pixel at/above the luminance threshold becomes white, everything below it black
2572
- * (MS-PPT > Format Picture > Picture Color > Recolor > Black and White …%)
2573
- * @example { threshold: 0.5 } // split at 50% luminance
2581
+ * Vertical position
2582
+ * - inches or percentage
2583
+ * @example 10.25 // position in inches
2584
+ * @example '75%' // position as percentage of slide size
2574
2585
  */
2575
- biLevel?: {
2576
- /** Luminance split point as a `0.0–1.0` fraction (serialized to `thresh`, the 0–1 fraction ×100000). */
2577
- threshold: number;
2578
- };
2586
+ y?: Coord;
2579
2587
  /**
2580
- * Recolor the image by mapping one source color to another (`<a:clrChange>`)
2581
- * - every pixel matching `from` is repainted `to` — the classic "swap the flat background out" recolour
2582
- * (MS-PPT > Format Picture > Picture Color > Set Transparent Color is the single-colour sibling)
2583
- * - colors accept `HexColor` or `ThemeColor`, same as fills / `duotone`
2584
- * @example { from: '000000', to: 'FF0000' } // turn black pixels red
2588
+ * Height
2589
+ * - inches or percentage
2590
+ * @example 10.25 // height in inches
2591
+ * @example '75%' // height as percentage of slide size
2585
2592
  */
2586
- clrChange?: {
2587
- /** Source color to replace (`<a:clrFrom>`). */
2588
- from: Color;
2589
- /** Replacement color (`<a:clrTo>`). */
2590
- to: Color;
2591
- };
2593
+ h?: Coord;
2592
2594
  /**
2593
- * Raw SVG markup to embed as the image source
2594
- * - convenience for `data: 'data:image/svg+xml;base64,...'`; ts-pptx encodes it for you
2595
- * - ignored when `data` or `path` is also provided
2596
- * @example '<svg viewBox="0 0 24 24">...</svg>'
2595
+ * Width
2596
+ * - inches or percentage
2597
+ * @example 10.25 // width in inches
2598
+ * @example '75%' // width as percentage of slide size
2597
2599
  */
2598
- svg?: string;
2600
+ w?: Coord;
2599
2601
  }
2600
- type ImageProps = ImageBaseProps & (DataOrPathRequiredProps | (DataOrPathProps & {
2601
- svg: string;
2602
- }));
2603
2602
  /**
2604
- * Add media (audio/video) to slide
2605
- * Requires either `data` or `path`; online media requires `link`.
2603
+ * Reusable optional data/path fields.
2604
+ * Use `DataOrPathRequiredProps` for APIs that require at least one source.
2606
2605
  */
2607
- interface MediaBaseProps extends PositionProps, ObjectNameProps {
2606
+ interface DataOrPathProps {
2608
2607
  /**
2609
- * Cover image
2610
- * @default "play button" image, gray background
2608
+ * URL or relative path
2609
+ *
2610
+ * @example 'https://onedrives.com/myimg.png` // retrieve image via URL
2611
+ * @example '/home/user/images/myimg.png` // retrieve image via local path
2611
2612
  */
2612
- cover?: string;
2613
+ path?: string;
2614
+ /**
2615
+ * base64-encoded string
2616
+ * - Useful for avoiding potential path/server issues
2617
+ *
2618
+ * @example 'image/png;base64,iVtDafDrBF[...]=' // pre-encoded image in base-64
2619
+ */
2620
+ data?: string;
2621
+ }
2622
+ type DataOrPathRequiredProps = (DataOrPathProps & {
2623
+ data: string;
2624
+ }) | (DataOrPathProps & {
2625
+ path: string;
2626
+ });
2627
+ interface BackgroundProps extends DataOrPathProps, ShapeFillProps {}
2628
+ /**
2629
+ * Color in Hex format
2630
+ * @example 'FF3399'
2631
+ */
2632
+ type HexColor = string;
2633
+ type ThemeColor = 'tx1' | 'tx2' | 'bg1' | 'bg2' | 'accent1' | 'accent2' | 'accent3' | 'accent4' | 'accent5' | 'accent6';
2634
+ type Color = HexColor | ThemeColor;
2635
+ interface GradientStopProps {
2613
2636
  /**
2614
- * media file extension
2615
- * - use when the media file path does not already have an extension, ex: "/folder/SomeSong"
2616
- * @default extension from file provided
2637
+ * Stop position as a percentage.
2638
+ * - range: 0-100
2617
2639
  */
2618
- extn?: string;
2640
+ position: number;
2619
2641
  /**
2620
- * Loop playback indefinitely (PowerPoint "Playback > Loop until Stopped")
2621
- * - emits a slide timing tree so the embedded audio/video repeats when played
2622
- * - not supported for `type: 'online'` (e.g. YouTube) embeds
2623
- * @default false
2642
+ * Stop color.
2643
+ * - `HexColor` or `ThemeColor`
2624
2644
  */
2625
- loop?: boolean;
2645
+ color: Color;
2626
2646
  /**
2627
- * Total number of times to play the media (a finite loop), ex: `3` plays it three times
2628
- * - ignored when `loop` is `true` (which repeats forever)
2629
- * - not supported for `type: 'online'` (e.g. YouTube) embeds
2647
+ * Transparency (percent)
2648
+ * - range: 0-100
2649
+ * @default 0
2630
2650
  */
2631
- loopCount?: number;
2651
+ transparency?: number;
2632
2652
  }
2633
- /**
2634
- * Add an embedded OLE object (PowerPoint's Insert ▸ Object ▸ Create from File) to a slide.
2635
- *
2636
- * The payload's bytes travel inside the `.pptx` (in `ppt/embeddings/`), so double-clicking the
2637
- * object in PowerPoint opens the source document in place. Requires either `data` or `path`.
2638
- * Linked objects (`<p:link>` to a file outside the package) are not supported.
2639
- */
2640
- interface OleObjectBaseProps extends PositionProps, ObjectNameProps {
2653
+ interface LinearGradientFillProps {
2641
2654
  /**
2642
- * Picture of the embedded document shown on the slide — a raster image `path` (Node/local)
2643
- * or base64 `data:` URI.
2644
- * - the library is Node-first and cannot render an Office document, so when this is omitted a
2645
- * neutral gray placeholder is embedded; PowerPoint draws the live object over it, but every
2646
- * other consumer (and PowerPoint's own `mc:Fallback` path) shows exactly what is supplied here
2647
- * - supply a real screenshot whenever the deck is meant to read correctly outside PowerPoint
2648
- * @example { path: 'assets/budget-preview.png' }
2655
+ * Gradient type.
2649
2656
  */
2650
- cover?: {
2651
- path?: string;
2652
- data?: string;
2653
- };
2657
+ kind: 'linear';
2654
2658
  /**
2655
- * Payload file extension, used to name the embedded part and to pick the content type,
2656
- * relationship type, and default `progId`.
2657
- * - inferred from `data`'s MIME, else `path`'s extension, else `progId`
2658
- * - anything that is not a known Office package extension (`xlsx`/`xlsm`/`docx`/`docm`/`pptx`/`pptm`)
2659
- * is embedded as a generic OLE blob part named `.bin`
2660
- * @example 'xlsx'
2659
+ * Gradient angle in degrees. Values are normalized into 0-359.999...
2660
+ * @default 0
2661
2661
  */
2662
- extn?: string;
2662
+ angle?: number;
2663
2663
  /**
2664
- * OLE server ProgID — what PowerPoint launches on double-click.
2665
- * - defaults from the resolved extension (`xlsx` → `Excel.Sheet.12`, `docx` → `Word.Document.12`,
2666
- * `pptx` → `PowerPoint.Show.12`, anything else → `Package`)
2667
- * @example 'Excel.Sheet.12'
2664
+ * Whether the gradient angle scales with the fill region.
2668
2665
  */
2669
- progId?: string;
2666
+ scaled?: boolean;
2670
2667
  /**
2671
- * Display the object as its application icon instead of a document preview (`showAsIcon`).
2672
- * - the `cover` image is still what gets drawn, so supply an icon-looking preview to match
2673
- * @default false
2668
+ * Whether the fill rotates with the shape.
2669
+ * @default true
2674
2670
  */
2675
- showAsIcon?: boolean;
2671
+ rotateWithShape?: boolean;
2676
2672
  /**
2677
- * Native size of the preview image in EMU (`imgW`/`imgH`), which PowerPoint uses to keep the
2678
- * object's aspect ratio when it re-renders the embedded document.
2679
- * - defaults to the object's own `w`/`h` converted to EMU
2673
+ * Gradient stops. Stops are serialized in ascending `position` order.
2680
2674
  */
2681
- imgW?: number;
2682
- /** @see {@link imgW} */
2683
- imgH?: number;
2675
+ stops: GradientStopProps[];
2684
2676
  }
2685
- /**
2686
- * Options for `slide.addOleObject()`. Requires either `data` (base64, with or without a
2687
- * `data:...;base64,` header) or `path` (a local/remote file read at export time).
2688
- *
2689
- * Sizing note: `w`/`h` default to 4 × 3 inches rather than being measured, since the library
2690
- * does not open the embedded document.
2691
- */
2692
- type OleObjectProps = OleObjectBaseProps & DataOrPathRequiredProps;
2693
- type MediaProps = MediaBaseProps & ((DataOrPathRequiredProps & {
2677
+ interface RadialGradientFillProps {
2694
2678
  /**
2695
- * Media type
2679
+ * Gradient type. A circular gradient radiating from a focus point: the stop at
2680
+ * `position: 0` sits at the center and later stops fan outward to the edges.
2696
2681
  */
2697
- type: Exclude<MediaType, 'online'>;
2682
+ kind: 'radial';
2698
2683
  /**
2699
- * Optional video embed link metadata.
2684
+ * Focus point of the radial gradient as percentages of the fill box, where
2685
+ * `{ x: 50, y: 50 }` (the default) centers it. Lower/higher values push the
2686
+ * bright center toward an edge.
2687
+ * @default { x: 50, y: 50 }
2700
2688
  */
2701
- link?: string;
2702
- }) | (DataOrPathProps & {
2689
+ center?: {
2690
+ x: number;
2691
+ y: number;
2692
+ };
2703
2693
  /**
2704
- * Use 'online' to embed a YouTube video (only supported in recent versions of PowerPoint)
2694
+ * Whether the fill rotates with the shape.
2695
+ * @default true
2705
2696
  */
2706
- type: 'online';
2697
+ rotateWithShape?: boolean;
2707
2698
  /**
2708
- * video embed link
2709
- * - works with YouTube
2710
- * - other sites may not show correctly in PowerPoint
2711
- * @example 'https://www.youtube.com/embed/Dph6ynRVyUc' // embed a youtube video
2699
+ * Gradient stops. Stops are serialized in ascending `position` order; the
2700
+ * first (`position: 0`) is the center color.
2712
2701
  */
2713
- link: string;
2714
- }));
2702
+ stops: GradientStopProps[];
2703
+ }
2704
+ type GradientFillProps = LinearGradientFillProps | RadialGradientFillProps;
2705
+ /** OOXML ST_PresetPatternVal — preset pattern names for `<a:pattFill prst="...">` */
2706
+ type PatternPreset = 'pct5' | 'pct10' | 'pct20' | 'pct25' | 'pct30' | 'pct40' | 'pct50' | 'pct60' | 'pct70' | 'pct75' | 'pct80' | 'pct90' | 'horz' | 'vert' | 'ltHorz' | 'ltVert' | 'dkHorz' | 'dkVert' | 'narHorz' | 'narVert' | 'dashHorz' | 'dashVert' | 'cross' | 'dnDiag' | 'upDiag' | 'ltDnDiag' | 'ltUpDiag' | 'dkDnDiag' | 'dkUpDiag' | 'wdDnDiag' | 'wdUpDiag' | 'dashDnDiag' | 'dashUpDiag' | 'diagCross' | 'smCheck' | 'lgCheck' | 'smGrid' | 'lgGrid' | 'dotGrid' | 'smConfetti' | 'lgConfetti' | 'horzBrick' | 'diagBrick' | 'solidDmnd' | 'openDmnd' | 'dotDmnd' | 'plaid' | 'sphere' | 'weave' | 'divot' | 'shingle' | 'wave' | 'trellis' | 'zigZag';
2707
+ interface PatternFillProps {
2708
+ /** OOXML preset pattern (`prst` attribute on `<a:pattFill>`). */
2709
+ preset: PatternPreset;
2710
+ /** Foreground color. Defaults to black (`000000`) if omitted. */
2711
+ fgColor?: Color;
2712
+ /** Background color. Defaults to white (`FFFFFF`) if omitted. */
2713
+ bgColor?: Color;
2714
+ }
2715
+ /**
2716
+ * Native PPTX picture (image) fill — fills a shape's interior with a bitmap
2717
+ * (`<a:blipFill>`). Provide exactly one of `path` or `data`; raster formats only
2718
+ * (PNG/JPEG/GIF/BMP/WebP). SVG is not yet supported as a fill source.
2719
+ */
2720
+ interface ImageFillProps {
2721
+ /** Image file path (Node filesystem path or URL). */
2722
+ path?: string;
2723
+ /** Pre-encoded base64 data URI, e.g. `'image/png;base64,iVBOR...'`. */
2724
+ data?: string;
2725
+ }
2726
+ type Margin = number | [number, number, number, number];
2727
+ type HAlign = 'left' | 'center' | 'right' | 'justify';
2728
+ type VAlign = 'top' | 'middle' | 'bottom';
2729
+ /**
2730
+ * Text body `vert` attribute — flow/rotation direction of the text within its box.
2731
+ * Maps to `<a:bodyPr vert="…">` (ECMA-376 `ST_TextVerticalType`).
2732
+ */
2733
+ type TextVertType = TextVerticalType;
2734
+ /**
2735
+ * A single node of a freeform (`custGeom`) path.
2736
+ * - coordinates are authored in the object's own inch/EMU space (0..width, 0..height), not slide-relative and not normalized
2737
+ * - used by shapes (`ShapeType.custGeom`) and by images (clips the picture to the path)
2738
+ *
2739
+ * The `arc` node carries no `x`/`y`: an `<a:arcTo>` has no explicit end point. The renderer
2740
+ * derives it from the current pen position, the radii and the swept angle, so an end point
2741
+ * authored here would be discarded (a warning is emitted if one is supplied).
2742
+ */
2743
+ type GeometryPoint = {
2744
+ x: Coord;
2745
+ y: Coord;
2746
+ moveTo?: boolean;
2747
+ } | {
2748
+ curve: {
2749
+ type: 'arc';
2750
+ hR: Coord;
2751
+ wR: Coord;
2752
+ stAng: number;
2753
+ swAng: number;
2754
+ };
2755
+ } | {
2756
+ x: Coord;
2757
+ y: Coord;
2758
+ curve: {
2759
+ type: 'cubic';
2760
+ x1: Coord;
2761
+ y1: Coord;
2762
+ x2: Coord;
2763
+ y2: Coord;
2764
+ };
2765
+ } | {
2766
+ x: Coord;
2767
+ y: Coord;
2768
+ curve: {
2769
+ type: 'quadratic';
2770
+ x1: Coord;
2771
+ y1: Coord;
2772
+ };
2773
+ } | {
2774
+ close: true;
2775
+ };
2715
2776
  //#endregion
2716
2777
  //#region src/types/table.d.ts
2717
2778
  /**
@@ -3456,35 +3517,15 @@ interface SlideMasterChartProps {
3456
3517
  options?: ChartOpts;
3457
3518
  opts?: ChartOpts;
3458
3519
  }
3459
- type SlideMasterObject = {
3460
- chart: SlideMasterChartProps;
3461
- } | {
3462
- image: ImageProps;
3463
- } | {
3464
- line: ShapeProps;
3465
- } | {
3466
- rect: ShapeProps;
3467
- } | {
3468
- roundRect: ShapeProps;
3469
- } |
3470
3520
  /**
3471
- * Any preset shape, addressed by `SHAPE_NAME` (e.g. `ShapeType.ellipse`).
3472
- * Generalizes the `line`/`rect`/`roundRect` shortcuts to every preset the
3473
- * `addShape()` serializer supports (ellipse, triangle, chevron, …).
3521
+ * One object on a slide master, as a key-tagged descriptor.
3474
3522
  *
3475
- * A union member's comment cannot carry block tags, so this stands in for `@example`:
3476
- * `{ shape: { type: 'ellipse', options: { x: 1, y: 1, w: 2, h: 2, fill: { color: 'FF0000' } } } }`
3523
+ * The six descriptors it shares with a group child are {@link CommonObjectDescriptor}; the two
3524
+ * below are the master's own — a chart, which a group cannot hold, and a placeholder, which is
3525
+ * the whole point of a master.
3477
3526
  */
3478
- {
3479
- shape: {
3480
- type: SHAPE_NAME;
3481
- options?: ShapeProps;
3482
- };
3483
- } | {
3484
- text: {
3485
- text: string | number | TextProps[];
3486
- options?: TextPropsOptions;
3487
- };
3527
+ type SlideMasterObject = CommonObjectDescriptor | {
3528
+ chart: SlideMasterChartProps;
3488
3529
  } | {
3489
3530
  placeholder: {
3490
3531
  options: PlaceholderProps;
@@ -3675,31 +3716,14 @@ type Model3dProps = Model3dBaseProps & DataOrPathRequiredProps;
3675
3716
  /**
3676
3717
  * A child object that can be placed inside a group via `slide.addGroup()`.
3677
3718
  *
3678
- * Uses the same key-tagged descriptor shape as `SlideMasterObject`, but limited to the
3679
- * object types `addGroup` supports. A `group` child nests another group (an identity child
3719
+ * The six descriptors it shares with `SlideMasterObject` are {@link CommonObjectDescriptor};
3720
+ * `group` is the group's own, and the master's `chart` and `placeholder` are deliberately not
3721
+ * here. A `group` child nests another group (an identity child
3680
3722
  * coordinate space is kept at every depth, so descendants keep their slide-absolute
3681
3723
  * coordinates). Charts, media, tables, and placeholders are intentionally excluded (see
3682
3724
  * `addGroup`); passing one logs a warning and skips it.
3683
3725
  */
3684
- type GroupChildProps = {
3685
- image: ImageProps;
3686
- } | {
3687
- line: ShapeProps;
3688
- } | {
3689
- rect: ShapeProps;
3690
- } | {
3691
- roundRect: ShapeProps;
3692
- } | {
3693
- shape: {
3694
- type: SHAPE_NAME;
3695
- options?: ShapeProps;
3696
- };
3697
- } | {
3698
- text: {
3699
- text: string | number | TextProps[];
3700
- options?: TextPropsOptions;
3701
- };
3702
- } | {
3726
+ type GroupChildProps = CommonObjectDescriptor | {
3703
3727
  group: {
3704
3728
  children: GroupChildProps[];
3705
3729
  options?: GroupProps;
@@ -3776,6 +3800,47 @@ interface ObjectOptions extends ImageBaseProps, PositionProps, ShapeProps, Table
3776
3800
  interface SlideLayout {
3777
3801
  background?: BackgroundProps;
3778
3802
  }
3803
+ /**
3804
+ * One authored object on a slide, as {@link Slide.objects} reports it: what it is and how it is
3805
+ * addressed, not how it is drawn. It is a snapshot taken when the getter ran, not a live handle —
3806
+ * nothing on it writes back, and a later `addShape`/`groupObjects` leaves it describing the slide
3807
+ * as it was.
3808
+ *
3809
+ * The point of it is composition. A slide assembled by independent renderers arrives with objects
3810
+ * whose descriptors nobody kept, and the only durable handle on them is the `objectName` each one
3811
+ * was authored with; without a way to enumerate those, a consumer that wants to act on what is
3812
+ * already there has to either make every renderer surrender its internals or keep a parallel
3813
+ * ledger of what it added — and a ledger is wrong the moment a renderer adds an object it did not
3814
+ * announce.
3815
+ */
3816
+ interface SlideObjectInfo {
3817
+ /** What kind of object this is — the same value the object was authored as. */
3818
+ readonly type: SlideObjectType;
3819
+ /**
3820
+ * Selection Pane name, in the spelling the caller passed to `objectName`, so it can be handed
3821
+ * straight back to `groupObjects()` or to an animation or connector reference.
3822
+ *
3823
+ * Always a string: an object authored without a name still gets the generated `Shape 3` /
3824
+ * `Text 1` / `Group 2` identity PowerPoint shows in the Selection Pane, and that name addresses
3825
+ * it just as well. The two are indistinguishable here on purpose — nothing downstream of
3826
+ * authoring records which is which, and a consumer that cares can tell them apart by the
3827
+ * naming convention it chose for its own objects.
3828
+ */
3829
+ readonly objectName: string;
3830
+ /** True when the object occupies a layout placeholder, which grouping refuses on top of kind. */
3831
+ readonly isPlaceholder: boolean;
3832
+ /**
3833
+ * Whether `groupObjects()` would accept this object on kind alone. It cannot speak for the
3834
+ * *selection* — an unresolved, duplicated or ambiguous name still throws — so it answers "is
3835
+ * this object groupable", never "will this call succeed".
3836
+ */
3837
+ readonly canGroup: boolean;
3838
+ /**
3839
+ * Children, when `type` is `group`; empty otherwise. Ordered bottom-to-top like
3840
+ * {@link Slide.objects} itself, and nested to whatever depth the groups nest.
3841
+ */
3842
+ readonly children: readonly SlideObjectInfo[];
3843
+ }
3779
3844
  interface Slide {
3780
3845
  addChart(data: OptsChartData[], options: ChartOpts & {
3781
3846
  type: CHART_NAME;
@@ -3798,6 +3863,18 @@ interface Slide {
3798
3863
  addGroup: (children: GroupChildProps[], options?: GroupProps) => Slide;
3799
3864
  /** Group objects already on this slide, addressed by their `objectName`, into a single group. */
3800
3865
  groupObjects: (objectNames: string[], options?: GroupProps) => Slide;
3866
+ /**
3867
+ * The objects authored on this slide so far, bottom-to-top in z-order — the read-back half of
3868
+ * `groupObjects()`, which addresses those same objects by name but until now gave no way to
3869
+ * learn the names.
3870
+ *
3871
+ * A fresh snapshot on every access, and inert: it describes the slide, and writing to it does
3872
+ * nothing. To act on what it reports, call the authoring API with the names it hands you.
3873
+ * @example
3874
+ * const cards = slide.objects.filter((o) => o.canGroup && o.objectName?.startsWith('card:'))
3875
+ * slide.groupObjects(cards.map((o) => o.objectName), { objectName: 'Cards' })
3876
+ */
3877
+ readonly objects: readonly SlideObjectInfo[];
3801
3878
  readonly newAutoPagedSlides?: Slide[];
3802
3879
  /**
3803
3880
  * Slide-show transition played when advancing to this slide (`p:transition`).
@@ -3845,5 +3922,5 @@ interface AddSlideProps {
3845
3922
  sectionTitle?: string;
3846
3923
  }
3847
3924
  //#endregion
3848
- export { PositionProps as $, CommentProps as $t, TableToSlidesDocument as A, ChartPropsChartBar as At, Coord as B, ChartPropsChartWaterfall as Bt, TableCell as C, ChartLineDash as Ct, TableProps as D, ChartPropsAxisSer as Dt, TableCellProps as E, ChartPropsAxisCat as Et, MediaProps as F, ChartPropsChartPie as Ft, GradientStopProps as G, ChartPropsTitle as Gt, DataOrPathRequiredProps as H, ChartPropsDataTable as Ht, MediaType as I, ChartPropsChartRadar as It, ImageFillProps as J, OptsChartData as Jt, HAlign as K, ChartSeriesOpts as Kt, OleObjectProps as L, ChartPropsChartRegionMap as Lt, TableToSlidesProps as M, ChartPropsChartDoughnut as Mt, ImageBaseProps as N, ChartPropsChartHistogram as Nt, TableRow as O, ChartPropsAxisVal as Ot, ImageProps as P, ChartPropsChartLine as Pt, PatternPreset as Q, PlaceholderProps as Qt, BackgroundProps as R, ChartPropsChartStock as Rt, TransitionType as S, ShapeProps as Sn, ChartExStatistics as St, TableCellDiagonals as T, ChartOpts as Tt, GeometryPoint as U, ChartPropsFillLine as Ut, DataOrPathProps as V, ChartPropsDataLabel as Vt, GradientFillProps as W, ChartPropsLegend as Wt, Margin as X, ObjectLockProps as Xt, LinearGradientFillProps as Y, OptsChartGridLine as Yt, PatternFillProps as Z, ObjectNameProps as Zt, AnimationProps as _, ShapeAdjustHandlePolar as _n, ChartAxisTickMark as _t, Slide as a, SlideComment as an, ConnectorProps as at, TransitionProps as b, ShapeConnectionSite as bn, ChartExBinning as bt, Model3dPoint as c, TextBaseProps as cn, HyperlinkProps as ct, MasterTextStyleLevel as d, TextMeasurement as dn, ShapeLineProps as dt, MeasureTextOptions as en, RadialGradientFillProps as et, MasterTextStyleProps as f, TextProps as fn, BevelPresetType as ft, SlideNumberProps as g, ShapeAdjustHandle as gn, ChartAreaProps as gt, SlideMasterProps as h, textRuns as hn, PresetMaterialType as ht, ObjectOptions as i, ResolvedCommentAuthor as in, BorderProps as it, TableToSlidesElement as j, ChartPropsChartBoxWhisker as jt, TableRowSlide as k, ChartPropsBase as kt, Model3dProps as l, TextFitShrinkProps as ln, ShadowProps as lt, SlideMasterObject as m, textRun as mn, LightRigType as mt, GroupChildProps as n, NotesTextOptions as nn, ThemeColor as nt, SlideLayout as o, TableCellLayout as on, ConnectorType as ot, SlideMasterChartProps as p, TextPropsOptions as pn, LightRigDirection as pt, HexColor as q, LineCap as qt, GroupProps as r, OverflowBoxOptions as rn, VAlign as rt, Model3dCameraProps as s, TableLayoutResult as sn, HyperlinkActionJump as st, AddSlideProps as t, NotesProps as tn, TextVertType as tt, MasterBulletProps as u, TextGlowProps as un, ShapeFillProps as ut, AnimationTrigger as v, ShapeAdjustHandleXY as vn, ChartDataPointStyle as vt, TableCell3DProps as w, ChartMulti as wt, TransitionSoundProps as x, ShapeGuide as xn, ChartExGeography as xt, PresetEffect as y, ShapeAdjustValue as yn, ChartErrorBarOptions as yt, Color as z, ChartPropsChartSurface as zt };
3849
- //# sourceMappingURL=slide-B_aInw3N.d.ts.map
3925
+ export { VAlign as $, MeasureTextOptions as $t, TableRowSlide as A, ChartPropsChartDoughnut as At, GradientFillProps as B, ChartPropsDataTable as Bt, TransitionType as C, ShapeAdjustValue as Cn, ChartOpts as Ct, TableCellProps as D, ChartPropsBase as Dt, TableCellDiagonals as E, ShapeProps as En, ChartPropsAxisVal as Et, Color as F, ChartPropsChartRegionMap as Ft, LinearGradientFillProps as G, LineCap as Gt, HAlign as H, ChartPropsLegend as Ht, Coord as I, ChartPropsChartStock as It, PatternPreset as J, CommonObjectDescriptor as Jt, Margin as K, OptsChartData as Kt, DataOrPathProps as L, ChartPropsChartSurface as Lt, TableToSlidesElement as M, ChartPropsChartLine as Mt, TableToSlidesProps as N, ChartPropsChartPie as Nt, TableProps as O, ChartPropsChartBar as Ot, BackgroundProps as P, ChartPropsChartRadar as Pt, ThemeColor as Q, CommentProps as Qt, DataOrPathRequiredProps as R, ChartPropsChartWaterfall as Rt, TransitionSoundProps as S, ShapeAdjustHandleXY as Sn, ChartMulti as St, TableCell3DProps as T, ShapeGuide as Tn, ChartPropsAxisSer as Tt, HexColor as U, ChartPropsTitle as Ut, GradientStopProps as V, ChartPropsFillLine as Vt, ImageFillProps as W, ChartSeriesOpts as Wt, RadialGradientFillProps as X, ObjectNameProps as Xt, PositionProps as Y, ObjectLockProps as Yt, TextVertType as Z, PlaceholderProps as Zt, SlideNumberProps as _, MediaProps as _n, ChartErrorBarOptions as _t, Slide as a, TableCellLayout as an, ShadowProps as at, PresetEffect as b, ShapeAdjustHandle as bn, ChartExStatistics as bt, Model3dCameraProps as c, TextFitShrinkProps as cn, BevelPresetType as ct, MasterBulletProps as d, TextProps as dn, LightRigType as dt, NotesProps as en, BorderProps as et, MasterTextStyleLevel as f, TextPropsOptions as fn, PresetMaterialType as ft, SlideMasterProps as g, ImageProps as gn, ChartDataPointStyle as gt, SlideMasterObject as h, ImageBaseProps as hn, ChartAxisTickMark as ht, ObjectOptions as i, SlideComment as in, HyperlinkProps as it, TableToSlidesDocument as j, ChartPropsChartHistogram as jt, TableRow as k, ChartPropsChartBoxWhisker as kt, Model3dPoint as l, TextGlowProps as ln, ColorMapToken as lt, SlideMasterChartProps as m, textRuns as mn, ChartAreaProps as mt, GroupChildProps as n, OverflowBoxOptions as nn, ConnectorType as nt, SlideLayout as o, TableLayoutResult as on, ShapeFillProps as ot, MasterTextStyleProps as p, textRun as pn, ThemeColorSlot as pt, PatternFillProps as q, OptsChartGridLine as qt, GroupProps as r, ResolvedCommentAuthor as rn, HyperlinkActionJump as rt, SlideObjectInfo as s, TextBaseProps as sn, ShapeLineProps as st, AddSlideProps as t, NotesTextOptions as tn, ConnectorProps as tt, Model3dProps as u, TextMeasurement as un, LightRigDirection as ut, AnimationProps as v, MediaType as vn, ChartExBinning as vt, TableCell as w, ShapeConnectionSite as wn, ChartPropsAxisCat as wt, TransitionProps as x, ShapeAdjustHandlePolar as xn, ChartLineDash as xt, AnimationTrigger as y, OleObjectProps as yn, ChartExGeography as yt, GeometryPoint as z, ChartPropsDataLabel as zt };
3926
+ //# sourceMappingURL=slide-ZqAdVvHV.d.ts.map