pptx-svelte-viewer 0.7.0 → 0.8.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 (36) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/README.md +1 -1
  3. package/dist/{component-BkXbcmvL.js → component-rAnX8oL7.js} +35385 -26035
  4. package/dist/i18n.js +1 -1
  5. package/dist/index.d.ts +4677 -135
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +17 -15
  8. package/dist/{translator-BTU8751A.js → translator-CbbaZk-L.js} +7 -0
  9. package/dist/viewer/collab/components/share-helpers.d.ts +3 -1
  10. package/dist/viewer/collab/components/share-helpers.d.ts.map +1 -1
  11. package/dist/viewer/components/ribbon/ribbon-tabs.d.ts +1 -1
  12. package/dist/viewer/components/ribbon/ribbon-tabs.d.ts.map +1 -1
  13. package/dist/viewer/components/ribbon/ribbon-types.d.ts +2 -0
  14. package/dist/viewer/components/ribbon/ribbon-types.d.ts.map +1 -1
  15. package/dist/viewer/editor/editor-document-state.d.ts +12 -0
  16. package/dist/viewer/editor/editor-document-state.d.ts.map +1 -0
  17. package/dist/viewer/editor/editor-master-controller.d.ts +7 -1
  18. package/dist/viewer/editor/editor-master-controller.d.ts.map +1 -1
  19. package/dist/viewer/editor/editor-state.svelte.d.ts +4 -2
  20. package/dist/viewer/editor/editor-state.svelte.d.ts.map +1 -1
  21. package/dist/viewer/index.d.ts +551 -118
  22. package/dist/viewer/index.js +1 -1
  23. package/dist/viewer/presentation/index.d.ts +1 -0
  24. package/dist/viewer/presentation/index.d.ts.map +1 -1
  25. package/dist/viewer/presentation/presenter-session.svelte.d.ts +27 -0
  26. package/dist/viewer/presentation/presenter-session.svelte.d.ts.map +1 -0
  27. package/dist/viewer/state/autosave.svelte.d.ts +3 -1
  28. package/dist/viewer/state/autosave.svelte.d.ts.map +1 -1
  29. package/dist/viewer/state/presentation-loader.svelte.d.ts +4 -1
  30. package/dist/viewer/state/presentation-loader.svelte.d.ts.map +1 -1
  31. package/dist/viewer/state/viewer-effects.svelte.d.ts.map +1 -1
  32. package/dist/viewer/state/zoom-navigation-context.d.ts +15 -0
  33. package/dist/viewer/state/zoom-navigation-context.d.ts.map +1 -0
  34. package/dist/viewer/types.d.ts +13 -2
  35. package/dist/viewer/types.d.ts.map +1 -1
  36. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -125,173 +125,4586 @@ declare const vermilionLightTheme: ViewerTheme;
125
125
  /** Dark vermilion theme, ready for the viewer's `theme` prop. */
126
126
  declare const vermilionDarkTheme: ViewerTheme;
127
127
 
128
+ /**
129
+ * Action types: hyperlinks, slide jumps, macros, and action buttons.
130
+ *
131
+ * @module pptx-types/actions
132
+ */
133
+ /**
134
+ * A parsed shape-level action from `a:hlinkClick` or `a:hlinkHover`.
135
+ *
136
+ * @example
137
+ * ```ts
138
+ * const link: PptxAction = {
139
+ * url: "https://example.com",
140
+ * tooltip: "Visit Example",
141
+ * highlightClick: true,
142
+ * };
143
+ *
144
+ * const slideJump: PptxAction = {
145
+ * action: "ppaction://hlinksldjump",
146
+ * targetSlideIndex: 3,
147
+ * };
148
+ * // => satisfies PptxAction
149
+ * ```
150
+ */
151
+ interface PptxAction {
152
+ /** Relationship ID referencing the action target. */
153
+ rId?: string;
154
+ /** OOXML action string (e.g. `ppaction://hlinksldjump`). */
155
+ action?: string;
156
+ /** Tooltip text shown on hover. */
157
+ tooltip?: string;
158
+ /** Whether the shape should highlight on click. */
159
+ highlightClick?: boolean;
160
+ /** Resolved URL or file path from the slide relationship map. */
161
+ url?: string;
162
+ /** Zero-based index into the slides array for internal slide jumps. */
163
+ targetSlideIndex?: number;
164
+ /** Relationship ID of an optional click sound (`a:snd/@r:embed`). */
165
+ soundRId?: string;
166
+ /** Resolved media target path for the optional click sound. */
167
+ soundPath?: string;
168
+ }
169
+
170
+ /**
171
+ * Shared value types used across the entire PPTX editor type system.
172
+ *
173
+ * Contains primitive enums, small interfaces, and the XML object alias
174
+ * that almost every other type file imports.
175
+ *
176
+ * @module pptx-types/common
177
+ */
178
+ /**
179
+ * Underline style tokens from OOXML `a:rPr/@u`.
180
+ *
181
+ * These map directly to the OpenXML `ST_TextUnderlineType` simple type.
182
+ *
183
+ * @example
184
+ * ```ts
185
+ * const style: UnderlineStyle = "wavy";
186
+ * // => "wavy" — one of: sng | dbl | heavy | dotted | dash | wavy | none | ...
187
+ * ```
188
+ */
189
+ type UnderlineStyle = 'sng' | 'dbl' | 'heavy' | 'dotted' | 'dottedHeavy' | 'dash' | 'dashHeavy' | 'dashLong' | 'dashLongHeavy' | 'dotDash' | 'dotDashHeavy' | 'dotDotDash' | 'dotDotDashHeavy' | 'wavy' | 'wavyHeavy' | 'wavyDbl' | 'none';
190
+ /**
191
+ * Connector connection point reference — links a connector endpoint to a
192
+ * specific shape on the slide.
193
+ *
194
+ * When both `shapeId` and `connectionSiteIndex` are set, the connector
195
+ * end snaps to that shapes’s connection site and “follows” the shape when
196
+ * it is moved.
197
+ *
198
+ * @example
199
+ * ```ts
200
+ * const start: ConnectorConnectionPoint = {
201
+ * shapeId: "shape_1",
202
+ * connectionSiteIndex: 2,
203
+ * };
204
+ * // => { shapeId: "shape_1", connectionSiteIndex: 2 } satisfies ConnectorConnectionPoint
205
+ * ```
206
+ */
207
+ interface ConnectorConnectionPoint {
208
+ /** ID of the shape this connector endpoint is attached to. */
209
+ shapeId?: string;
210
+ /** Connection site index on the target shape (0-based). */
211
+ connectionSiteIndex?: number;
212
+ }
213
+ /**
214
+ * Arrow head types for connector start/end.
215
+ *
216
+ * Maps to `a:headEnd/@type` and `a:tailEnd/@type` in OOXML.
217
+ *
218
+ * @example
219
+ * ```ts
220
+ * const arrow: ConnectorArrowType = "triangle";
221
+ * // => "triangle" — one of: none | triangle | stealth | diamond | oval | arrow
222
+ * ```
223
+ */
224
+ type ConnectorArrowType = 'none' | 'triangle' | 'stealth' | 'diamond' | 'oval' | 'arrow';
225
+ /**
226
+ * Stroke dash pattern types for lines and shape outlines.
227
+ *
228
+ * Maps to `a:ln/a:prstDash/@val` in OOXML. Use `"custom"` for
229
+ * user-defined dash/space arrays.
230
+ *
231
+ * @example
232
+ * ```ts
233
+ * const dash: StrokeDashType = "dashDot";
234
+ * // => "dashDot" — one of: solid | dot | dash | lgDash | dashDot | custom | ...
235
+ * ```
236
+ */
237
+ type StrokeDashType = 'solid' | 'dot' | 'dash' | 'lgDash' | 'dashDot' | 'lgDashDot' | 'lgDashDotDot' | 'sysDot' | 'sysDash' | 'sysDashDot' | 'sysDashDotDot' | 'custom';
238
+ /**
239
+ * Shadow effect properties for a single shadow layer.
240
+ *
241
+ * Represents parsed values from an `<a:outerShdw>` node. Multiple instances
242
+ * can be stored in {@link ShapeStyle.shadows} for compound shadow effects.
243
+ *
244
+ * @example
245
+ * ```ts
246
+ * const shadow: ShadowEffect = {
247
+ * color: "#000000",
248
+ * opacity: 0.4,
249
+ * blur: 6,
250
+ * angle: 315,
251
+ * distance: 4,
252
+ * };
253
+ * // => { color: "#000000", opacity: 0.4, blur: 6, angle: 315, distance: 4 } satisfies ShadowEffect
254
+ * ```
255
+ */
256
+ interface ShadowEffect {
257
+ /** Shadow color as hex string. */
258
+ color: string;
259
+ /** Shadow opacity (0-1). */
260
+ opacity: number;
261
+ /** Blur radius in pixels. */
262
+ blur: number;
263
+ /** Shadow angle in degrees (0-360). */
264
+ angle: number;
265
+ /** Shadow distance in pixels. */
266
+ distance: number;
267
+ /** Whether shadow rotates with shape. */
268
+ rotateWithShape?: boolean;
269
+ }
128
270
  /**
129
271
  * Strongly-typed parsed XML node from fast-xml-parser.
130
272
  *
131
- * The parser is configured with `attributeNamePrefix: '@_'`,
132
- * `parseAttributeValue: false`, and `parseTagValue: false`, so attribute and
133
- * text values are always strings at runtime. This type encodes that:
273
+ * The parser is configured with `attributeNamePrefix: '@_'`,
274
+ * `parseAttributeValue: false`, and `parseTagValue: false`, so attribute and
275
+ * text values are always strings at runtime. This type encodes that:
276
+ *
277
+ * - **Attributes** — keys matching `` `@_${string}` `` return
278
+ * `string | undefined` directly.
279
+ * - **Text content** — `#text` returns `string | undefined`.
280
+ * - **Child elements** — any other string key returns
281
+ * `XmlObject | XmlObject[] | string | undefined`. The union reflects that
282
+ * fast-xml-parser may emit an object (single child), an array (repeated
283
+ * children), or a bare string (text-only element collapsed by the parser).
284
+ *
285
+ * For traversal, prefer the helpers in {@link ./../utils/xml-access} —
286
+ * `xmlChild` / `xmlChildren` / `xmlAttr` / `xmlText` / `xmlPath` — which
287
+ * narrow the union and normalize the single-vs-array duality. Direct
288
+ * indexing works for attributes (typed as string) but chained child access
289
+ * (`obj['p:spPr']?.['a:xfrm']`) requires the helpers or a narrowing cast
290
+ * because TypeScript cannot index into the `XmlObject[] | string` part of
291
+ * the union.
292
+ */
293
+ interface XmlObject {
294
+ /** Attributes (`@_`-prefixed keys) are always strings at runtime. */
295
+ [attr: `@_${string}`]: string | undefined;
296
+ /** Element text content surfaces under `#text` when present. */
297
+ '#text'?: string;
298
+ /**
299
+ * Child elements keyed by their (namespaced) tag name. fast-xml-parser
300
+ * emits a single object for unique elements, an array for repeated ones,
301
+ * and a bare string for elements collapsed to their text content. Use
302
+ * the helpers in `utils/xml-access` to narrow this union.
303
+ */
304
+ [child: string]: XmlObject | XmlObject[] | string | undefined;
305
+ }
306
+ /**
307
+ * Shape lock attributes from `p:cNvSpPr / a:spLocks`.
308
+ *
309
+ * When a flag is `true` the corresponding user interaction is disabled
310
+ * in the editor (e.g. `noRotation` prevents free rotation of the shape).
311
+ *
312
+ * @example
313
+ * ```ts
314
+ * const locks: PptxShapeLocks = { noMove: true, noResize: true };
315
+ * // => { noMove: true, noResize: true } satisfies PptxShapeLocks
316
+ * ```
317
+ */
318
+ interface PptxShapeLocks {
319
+ noGrouping?: boolean;
320
+ noRotation?: boolean;
321
+ noMove?: boolean;
322
+ noResize?: boolean;
323
+ noTextEdit?: boolean;
324
+ noSelect?: boolean;
325
+ noChangeAspect?: boolean;
326
+ noEditPoints?: boolean;
327
+ noAdjustHandles?: boolean;
328
+ noChangeArrowheads?: boolean;
329
+ noChangeShapeType?: boolean;
330
+ }
331
+ /**
332
+ * A drawing guide parsed from OOXML extension lists.
333
+ *
334
+ * Slide-level and presentation-level guides are shown as thin coloured
335
+ * lines that help users align elements.
336
+ *
337
+ * @example
338
+ * ```ts
339
+ * const guide: PptxDrawingGuide = {
340
+ * id: "g1",
341
+ * orientation: "horz",
342
+ * positionEmu: 457200,
343
+ * color: "#FF0000",
344
+ * };
345
+ * // => { id: "g1", orientation: "horz", positionEmu: 457200, color: "#FF0000" } satisfies PptxDrawingGuide
346
+ * ```
347
+ */
348
+ interface PptxDrawingGuide {
349
+ /** Unique identifier (from `@_id` attribute or generated). */
350
+ id: string;
351
+ /** Orientation: horizontal or vertical. */
352
+ orientation: 'horz' | 'vert';
353
+ /** Position in EMU (converted from pos attribute). */
354
+ positionEmu: number;
355
+ /** Optional guide colour as hex string (e.g. "#FF0000"). */
356
+ color?: string;
357
+ }
358
+
359
+ /**
360
+ * Geometry types: adjustment handles, custom geometry points, segments,
361
+ * paths, and custom path properties.
362
+ *
363
+ * @module pptx-types/geometry
364
+ */
365
+ /**
366
+ * Defines an adjustment handle position for a shape geometry.
367
+ *
368
+ * Adjustment handles allow users to interactively reshape preset shapes
369
+ * (e.g. rounding a rectangle corner or adjusting arrow head width).
370
+ *
371
+ * @example
372
+ * ```ts
373
+ * const handle: GeometryAdjustmentHandle = {
374
+ * guideName: "adj",
375
+ * xFraction: 0.25,
376
+ * minValue: 0,
377
+ * maxValue: 50000,
378
+ * };
379
+ * // => satisfies GeometryAdjustmentHandle
380
+ * ```
381
+ */
382
+ interface GeometryAdjustmentHandle {
383
+ /** Name of the adjustment guide this handle controls (e.g. "adj", "adj1"). */
384
+ guideName: string;
385
+ /** X position as a fraction of shape width (0..1), or undefined if the handle only moves vertically. */
386
+ xFraction?: number;
387
+ /** Y position as a fraction of shape height (0..1), or undefined if the handle only moves horizontally. */
388
+ yFraction?: number;
389
+ /** Minimum allowed value for the adjustment guide. */
390
+ minValue?: number;
391
+ /** Maximum allowed value for the adjustment guide. */
392
+ maxValue?: number;
393
+ }
394
+ /**
395
+ * A single point in a custom geometry path.
396
+ *
397
+ * @example
398
+ * ```ts
399
+ * const pt: CustomGeometryPoint = { x: 100, y: 200 };
400
+ * // => satisfies CustomGeometryPoint
401
+ * ```
402
+ */
403
+ interface CustomGeometryPoint {
404
+ x: number;
405
+ y: number;
406
+ }
407
+ /**
408
+ * A segment within a custom geometry path.
409
+ *
410
+ * Discriminated union over `type` — can be a moveTo, lineTo,
411
+ * cubic Bézier, quadratic Bézier, or close command.
412
+ *
413
+ * @example
414
+ * ```ts
415
+ * const segments: CustomGeometrySegment[] = [
416
+ * { type: "moveTo", pt: { x: 0, y: 0 } },
417
+ * { type: "lineTo", pt: { x: 100, y: 0 } },
418
+ * { type: "lineTo", pt: { x: 100, y: 100 } },
419
+ * { type: "close" },
420
+ * ];
421
+ * // => satisfies CustomGeometrySegment[]
422
+ * ```
423
+ */
424
+ type CustomGeometrySegment = {
425
+ type: 'moveTo';
426
+ pt: CustomGeometryPoint;
427
+ } | {
428
+ type: 'lineTo';
429
+ pt: CustomGeometryPoint;
430
+ } | {
431
+ type: 'cubicBezTo';
432
+ pts: [CustomGeometryPoint, CustomGeometryPoint, CustomGeometryPoint];
433
+ } | {
434
+ type: 'quadBezTo';
435
+ pts: [CustomGeometryPoint, CustomGeometryPoint];
436
+ } | {
437
+ type: 'arcTo';
438
+ /** Horizontal radius of the ellipse. */
439
+ wR: number;
440
+ /** Vertical radius of the ellipse. */
441
+ hR: number;
442
+ /** Start angle in 60000ths of a degree. */
443
+ stAng: number;
444
+ /** Sweep angle in 60000ths of a degree. */
445
+ swAng: number;
446
+ } | {
447
+ type: 'close';
448
+ };
449
+ /**
450
+ * A single sub-path in a custom geometry definition (maps to one `a:path`).
451
+ *
452
+ * @example
453
+ * ```ts
454
+ * const path: CustomGeometryPath = {
455
+ * width: 100,
456
+ * height: 100,
457
+ * segments: [
458
+ * { type: "moveTo", pt: { x: 0, y: 0 } },
459
+ * { type: "lineTo", pt: { x: 100, y: 100 } },
460
+ * ],
461
+ * };
462
+ * // => satisfies CustomGeometryPath
463
+ * ```
464
+ */
465
+ interface CustomGeometryPath {
466
+ /** Coordinate-space width for this sub-path. */
467
+ width: number;
468
+ /** Coordinate-space height for this sub-path. */
469
+ height: number;
470
+ /** Ordered list of drawing segments. */
471
+ segments: CustomGeometrySegment[];
472
+ /** Path fill mode (`a:path/@fill`): norm, lighten, lightenLess, darken, darkenLess, none. */
473
+ fillMode?: 'norm' | 'lighten' | 'lightenLess' | 'darken' | 'darkenLess' | 'none';
474
+ /** Whether the path is stroked (`a:path/@stroke`). */
475
+ stroke?: boolean;
476
+ /** 3D extrusion compatibility (`a:path/@extrusionOk`). */
477
+ extrusionOk?: boolean;
478
+ }
479
+ /**
480
+ * Auxiliary raw XML preserved from `a:custGeom` for round-trip serialization.
481
+ * These are stored opaquely so adjustment guides, handles, connection sites,
482
+ * and the text rectangle are not lost when a custGeom is edited and saved.
483
+ */
484
+ interface CustomGeometryRawData {
485
+ /** Raw `a:gdLst` XML content (guide list). */
486
+ gdLstXml?: unknown;
487
+ /** Raw `a:ahLst` XML content (adjustment handles). */
488
+ ahLstXml?: unknown;
489
+ /** Raw `a:cxnLst` XML content (connection sites). */
490
+ cxnLstXml?: unknown;
491
+ /** Raw `a:rect` XML content (text rectangle). */
492
+ rectXml?: unknown;
493
+ }
494
+ /**
495
+ * XY-style adjustment handle (`a:ahXY`) on a custom geometry.
496
+ *
497
+ * Allows interactive editing of one or two guide values constrained to a
498
+ * rectangular range. Coordinates are formula references (e.g. `"adj1"`,
499
+ * `"w/2"`, `"0"`) preserved verbatim so they can re-emit unchanged.
500
+ *
501
+ * @example
502
+ * ```ts
503
+ * const handle: AdjustHandleXY = {
504
+ * gdRefX: "adj1",
505
+ * minX: "0",
506
+ * maxX: "w",
507
+ * posX: "adj1",
508
+ * posY: "h/2",
509
+ * };
510
+ * // => satisfies AdjustHandleXY
511
+ * ```
512
+ */
513
+ interface AdjustHandleXY {
514
+ /** Guide reference for the X axis (`@_gdRefX`). */
515
+ gdRefX?: string;
516
+ /** Guide reference for the Y axis (`@_gdRefY`). */
517
+ gdRefY?: string;
518
+ /** Minimum X value, as a formula reference (`@_minX`). */
519
+ minX?: string;
520
+ /** Maximum X value (`@_maxX`). */
521
+ maxX?: string;
522
+ /** Minimum Y value (`@_minY`). */
523
+ minY?: string;
524
+ /** Maximum Y value (`@_maxY`). */
525
+ maxY?: string;
526
+ /** Handle position X (formula or literal) from `a:pos/@_x`. */
527
+ posX?: string;
528
+ /** Handle position Y from `a:pos/@_y`. */
529
+ posY?: string;
530
+ }
531
+ /**
532
+ * Polar-style adjustment handle (`a:ahPolar`) on a custom geometry.
533
+ *
534
+ * Drives a guide via radial distance and angle rather than XY coordinates.
535
+ *
536
+ * @example
537
+ * ```ts
538
+ * const handle: AdjustHandlePolar = {
539
+ * gdRefR: "adj1",
540
+ * gdRefAng: "adj2",
541
+ * posX: "wd2",
542
+ * posY: "hd2",
543
+ * };
544
+ * // => satisfies AdjustHandlePolar
545
+ * ```
546
+ */
547
+ interface AdjustHandlePolar {
548
+ /** Guide reference for the radial distance (`@_gdRefR`). */
549
+ gdRefR?: string;
550
+ /** Guide reference for the angle (`@_gdRefAng`). */
551
+ gdRefAng?: string;
552
+ /** Minimum radial value (`@_minR`). */
553
+ minR?: string;
554
+ /** Maximum radial value (`@_maxR`). */
555
+ maxR?: string;
556
+ /** Minimum angle (`@_minAng`). */
557
+ minAng?: string;
558
+ /** Maximum angle (`@_maxAng`). */
559
+ maxAng?: string;
560
+ /** Handle position X from `a:pos/@_x`. */
561
+ posX?: string;
562
+ /** Handle position Y from `a:pos/@_y`. */
563
+ posY?: string;
564
+ }
565
+ /**
566
+ * Connection site (`a:cxn`) on a custom geometry.
567
+ *
568
+ * Defines a point on a custom shape that connectors may snap to.
569
+ *
570
+ * @example
571
+ * ```ts
572
+ * const cxn: ConnectionSite = { ang: "0", posX: "0", posY: "hd2" };
573
+ * // => satisfies ConnectionSite
574
+ * ```
575
+ */
576
+ interface ConnectionSite {
577
+ /** Approach angle (`@_ang`) — formula or literal degree-1/60000 value. */
578
+ ang?: string;
579
+ /** Site position X from `a:pos/@_x`. */
580
+ posX?: string;
581
+ /** Site position Y from `a:pos/@_y`. */
582
+ posY?: string;
583
+ }
584
+ /**
585
+ * Typed text rectangle (`a:rect`) on a custom geometry.
586
+ *
587
+ * Each edge is the formula or literal string preserved from the source XML
588
+ * (`"l"`, `"t"`, `"r"`, `"b"`, or any guide name / formula).
589
+ */
590
+ interface CustomGeometryTextRect {
591
+ /** Left edge formula reference (`@_l`). */
592
+ l?: string;
593
+ /** Top edge (`@_t`). */
594
+ t?: string;
595
+ /** Right edge (`@_r`). */
596
+ r?: string;
597
+ /** Bottom edge (`@_b`). */
598
+ b?: string;
599
+ }
600
+ /**
601
+ * Custom (non-preset) geometry path — only on shapes and pictures.
602
+ *
603
+ * Contains SVG path data and/or structured custom geometry paths
604
+ * parsed from `a:custGeom/a:pathLst`.
605
+ *
606
+ * @example
607
+ * ```ts
608
+ * const custom: PptxCustomPathProperties = {
609
+ * pathData: "M 0 0 L 100 0 L 100 100 Z",
610
+ * pathWidth: 100,
611
+ * pathHeight: 100,
612
+ * };
613
+ * // => satisfies PptxCustomPathProperties
614
+ * ```
615
+ */
616
+ interface PptxCustomPathProperties {
617
+ /** SVG path data for custom shapes. */
618
+ pathData?: string;
619
+ /** Coordinate-space width for the custom path. */
620
+ pathWidth?: number;
621
+ /** Coordinate-space height for the custom path. */
622
+ pathHeight?: number;
623
+ /** Structured custom geometry paths for editing (maps to a:custGeom/a:pathLst). */
624
+ customGeometryPaths?: CustomGeometryPath[];
625
+ /** Raw a:gdLst/a:ahLst/a:cxnLst/a:rect XML preserved for round-trip serialization. */
626
+ customGeometryRawData?: CustomGeometryRawData;
627
+ /**
628
+ * Typed XY adjustment handles parsed from `a:custGeom/a:ahLst/a:ahXY`.
629
+ * SDK-built shapes can populate this and the writer will emit `<a:ahXY>` entries
630
+ * even when no raw XML was preserved.
631
+ */
632
+ customGeometryAdjustHandlesXY?: AdjustHandleXY[];
633
+ /**
634
+ * Typed polar adjustment handles parsed from `a:custGeom/a:ahLst/a:ahPolar`.
635
+ */
636
+ customGeometryAdjustHandlesPolar?: AdjustHandlePolar[];
637
+ /**
638
+ * Typed connection sites parsed from `a:custGeom/a:cxnLst/a:cxn`.
639
+ */
640
+ customGeometryConnectionSites?: ConnectionSite[];
641
+ /**
642
+ * Typed text rectangle parsed from `a:custGeom/a:rect`. When present this is
643
+ * preferred over {@link customGeometryRawData}'s `rectXml` on save.
644
+ */
645
+ customGeometryTextRect?: CustomGeometryTextRect;
646
+ }
647
+
648
+ /**
649
+ * 3-D effect properties, text warp (WordArt) presets, and scene/shape bevel
650
+ * definitions parsed from OOXML `a:sp3d`, `a:scene3d`, and `a:bodyPr/a:prstTxWarp`.
651
+ *
652
+ * @module pptx-types/three-d
653
+ */
654
+ /**
655
+ * Bevel preset type tokens from OOXML `a:bevelT/@prst` / `a:bevelB/@prst`.
656
+ *
657
+ * @example
658
+ * ```ts
659
+ * const bevel: BevelPresetType = "circle";
660
+ * // => "circle" — one of: "circle" | "relaxedInset" | "cross" | "coolSlant" | "angle" | …
661
+ * ```
662
+ */
663
+ type BevelPresetType = 'circle' | 'relaxedInset' | 'cross' | 'coolSlant' | 'angle' | 'softRound' | 'convex' | 'slope' | 'divot' | 'riblet' | 'hardEdge' | 'artDeco' | 'none';
664
+ /**
665
+ * Material preset type tokens from OOXML `a:sp3d/@prstMaterial`.
666
+ *
667
+ * @example
668
+ * ```ts
669
+ * const mat: MaterialPresetType = "plastic";
670
+ * // => "plastic" — one of: "matte" | "warmMatte" | "plastic" | "metal" | "dkEdge" | …
671
+ * ```
672
+ */
673
+ type MaterialPresetType = 'matte' | 'warmMatte' | 'plastic' | 'metal' | 'dkEdge' | 'softEdge' | 'flat' | 'softmetal' | 'clear' | 'powder' | 'translucentPowder' | 'legacyMatte' | 'legacyPlastic' | 'legacyMetal' | 'legacyWireframe';
674
+ /**
675
+ * 3D text body extrusion/bevel from `a:bodyPr/a:sp3d`.
676
+ *
677
+ * @example
678
+ * ```ts
679
+ * const text3d: Text3DStyle = {
680
+ * extrusionHeight: 57150,
681
+ * presetMaterial: "plastic",
682
+ * bevelTopType: "circle",
683
+ * bevelTopWidth: 25400,
684
+ * bevelTopHeight: 25400,
685
+ * };
686
+ * // => satisfies Text3DStyle
687
+ * ```
688
+ */
689
+ interface Text3DStyle {
690
+ /** Extrusion height (depth) in EMU. */
691
+ extrusionHeight?: number;
692
+ /** Extrusion colour as hex string. */
693
+ extrusionColor?: string;
694
+ /** Preset material, e.g. "matte", "plastic", "metal". */
695
+ presetMaterial?: MaterialPresetType;
696
+ /** Top bevel preset type. */
697
+ bevelTopType?: BevelPresetType;
698
+ /** Top bevel width in EMU. */
699
+ bevelTopWidth?: number;
700
+ /** Top bevel height in EMU. */
701
+ bevelTopHeight?: number;
702
+ /** Bottom bevel preset type. */
703
+ bevelBottomType?: BevelPresetType;
704
+ /** Bottom bevel width in EMU. */
705
+ bevelBottomWidth?: number;
706
+ /** Bottom bevel height in EMU. */
707
+ bevelBottomHeight?: number;
708
+ }
709
+ /**
710
+ * 3D scene/camera properties from `a:scene3d`.
711
+ *
712
+ * @example
713
+ * ```ts
714
+ * const scene: Pptx3DScene = {
715
+ * cameraPreset: "perspectiveFront",
716
+ * lightRigType: "threePt",
717
+ * lightRigDirection: "t",
718
+ * };
719
+ * // => satisfies Pptx3DScene
720
+ * ```
721
+ */
722
+ interface Pptx3DScene {
723
+ /** Camera preset type, e.g. "orthographicFront", "perspectiveFront". */
724
+ cameraPreset?: string;
725
+ /** Camera field of view in 1/60000 degrees (`a:camera/@fov`). */
726
+ cameraFieldOfView?: number;
727
+ /** Camera zoom as an OOXML percentage fraction (`a:camera/@zoom`, 1 = 100%). */
728
+ cameraZoom?: number;
729
+ /** Camera rotation around X axis in 1/60000 degrees. */
730
+ cameraRotX?: number;
731
+ /** Camera rotation around Y axis in 1/60000 degrees. */
732
+ cameraRotY?: number;
733
+ /** Camera rotation around Z axis in 1/60000 degrees. */
734
+ cameraRotZ?: number;
735
+ /** Light rig type, e.g. "threePt", "balanced", "harsh". */
736
+ lightRigType?: string;
737
+ /** Light rig direction, e.g. "t", "b", "l", "r", "tl". */
738
+ lightRigDirection?: string;
739
+ /** Light-rig rotation latitude in 1/60000 degrees. */
740
+ lightRigRotX?: number;
741
+ /** Light-rig rotation longitude in 1/60000 degrees. */
742
+ lightRigRotY?: number;
743
+ /** Light-rig rotation revolution in 1/60000 degrees. */
744
+ lightRigRotZ?: number;
745
+ /** Whether a 3D backdrop plane is present (`a:backdrop`). */
746
+ hasBackdrop?: boolean;
747
+ /** Backdrop plane anchor X in EMU. */
748
+ backdropAnchorX?: number;
749
+ /** Backdrop plane anchor Y in EMU. */
750
+ backdropAnchorY?: number;
751
+ /** Backdrop plane anchor Z in EMU. */
752
+ backdropAnchorZ?: number;
753
+ /** Backdrop normal vector X component. */
754
+ backdropNormalX?: number;
755
+ /** Backdrop normal vector Y component. */
756
+ backdropNormalY?: number;
757
+ /** Backdrop normal vector Z component. */
758
+ backdropNormalZ?: number;
759
+ /** Backdrop up vector X component. */
760
+ backdropUpX?: number;
761
+ /** Backdrop up vector Y component. */
762
+ backdropUpY?: number;
763
+ /** Backdrop up vector Z component. */
764
+ backdropUpZ?: number;
765
+ }
766
+ /**
767
+ * 3D shape extrusion/bevel from `a:sp3d`.
768
+ *
769
+ * @example
770
+ * ```ts
771
+ * const shape3d: Pptx3DShape = {
772
+ * extrusionHeight: 76200,
773
+ * extrusionColor: "#4F81BD",
774
+ * presetMaterial: "metal",
775
+ * bevelTopType: "circle",
776
+ * bevelTopWidth: 12700,
777
+ * bevelTopHeight: 12700,
778
+ * };
779
+ * // => satisfies Pptx3DShape
780
+ * ```
781
+ */
782
+ interface Pptx3DShape {
783
+ /** Extrusion height in EMU. */
784
+ extrusionHeight?: number;
785
+ /** Extrusion colour. */
786
+ extrusionColor?: string;
787
+ /** Contour width in EMU. */
788
+ contourWidth?: number;
789
+ /** Contour colour. */
790
+ contourColor?: string;
791
+ /** Preset material, e.g. "matte", "warmMatte", "metal". */
792
+ presetMaterial?: string;
793
+ /** Top bevel type, e.g. "circle", "relaxedInset". */
794
+ bevelTopType?: string;
795
+ /** Top bevel width in EMU. */
796
+ bevelTopWidth?: number;
797
+ /** Top bevel height in EMU. */
798
+ bevelTopHeight?: number;
799
+ /** Bottom bevel type, e.g. "circle", "relaxedInset". */
800
+ bevelBottomType?: string;
801
+ /** Bottom bevel width in EMU. */
802
+ bevelBottomWidth?: number;
803
+ /** Bottom bevel height in EMU. */
804
+ bevelBottomHeight?: number;
805
+ }
806
+ /**
807
+ * Known OOXML preset text warp types (WordArt transforms).
808
+ *
809
+ * Falls back to `string` for unknown presets not yet catalogued.
810
+ *
811
+ * @example
812
+ * ```ts
813
+ * const warp: PptxTextWarpPreset = "textArchUp";
814
+ * // => "textArchUp" — one of: "textNoShape" | "textPlain" | "textStop" | "textArchUp" | …
815
+ * ```
816
+ */
817
+ type PptxTextWarpPreset = 'textNoShape' | 'textPlain' | 'textStop' | 'textTriangle' | 'textTriangleInverted' | 'textChevron' | 'textChevronInverted' | 'textRingInside' | 'textRingOutside' | 'textArchUp' | 'textArchDown' | 'textCircle' | 'textButton' | 'textArchUpPour' | 'textArchDownPour' | 'textCirclePour' | 'textButtonPour' | 'textCurveUp' | 'textCurveDown' | 'textCanUp' | 'textCanDown' | 'textWave1' | 'textWave2' | 'textWave4' | 'textDoubleWave1' | 'textInflate' | 'textDeflate' | 'textInflateBottom' | 'textDeflateBottom' | 'textInflateTop' | 'textDeflateTop' | 'textFadeRight' | 'textFadeLeft' | 'textFadeUp' | 'textFadeDown' | 'textSlantUp' | 'textSlantDown' | 'textCascadeUp' | 'textCascadeDown' | 'textDeflateInflate' | 'textDeflateInflateDeflate' | string;
818
+
819
+ /**
820
+ * Shape visual styling types: fill, stroke, effects, and connectors.
821
+ *
822
+ * {@link ShapeStyle} is the main type attached to any element that has
823
+ * visible geometry (shapes, connectors, images). It covers:
824
+ * - **Fill**: solid, gradient, pattern, image, and theme fills
825
+ * - **Stroke**: colour, width, dash pattern, line join/cap
826
+ * - **Effects**: shadow, glow, soft-edge, reflection, blur
827
+ * - **Connectors**: arrow-head types and connection points
828
+ * - **3-D**: scene camera and shape extrusion/bevel
829
+ *
830
+ * All spatial values are stored in **pixels** (pre-converted from EMU).
831
+ * Opacity values are normalised to the 0–1 range.
832
+ *
833
+ * @module pptx-types/shape-style
834
+ */
835
+
836
+ /**
837
+ * Comprehensive visual style for a shape, connector, or image element.
838
+ *
839
+ * All fields are optional. When absent, the element inherits from theme
840
+ * or layout defaults. The interface models both simple styling (solid fill +
841
+ * basic stroke) and advanced effects (multiple shadow layers, gradient
842
+ * fills, 3-D extrusion).
843
+ *
844
+ * @example
845
+ * ```ts
846
+ * // Simple blue filled shape with a thin black outline:
847
+ * const simple: ShapeStyle = {
848
+ * fillColor: "#0055AA",
849
+ * fillMode: "solid",
850
+ * strokeColor: "#000000",
851
+ * strokeWidth: 1,
852
+ * };
853
+ *
854
+ * // Gradient fill with a soft shadow:
855
+ * const fancy: ShapeStyle = {
856
+ * fillMode: "gradient",
857
+ * fillGradientType: "linear",
858
+ * fillGradientAngle: 135,
859
+ * fillGradientStops: [
860
+ * { color: "#FF6B6B", position: 0 },
861
+ * { color: "#556270", position: 1 },
862
+ * ],
863
+ * shadowColor: "#000000",
864
+ * shadowBlur: 10,
865
+ * shadowOffsetX: 4,
866
+ * shadowOffsetY: 4,
867
+ * shadowOpacity: 0.3,
868
+ * };
869
+ * // => both satisfy the ShapeStyle interface
870
+ * ```
871
+ */
872
+ interface ShapeStyle {
873
+ fillColor?: string;
874
+ /**
875
+ * Raw XML colour-choice node preserved from `a:solidFill` for round-trip
876
+ * serialisation. Captures `a:schemeClr` / `a:sysClr` / `a:prstClr` /
877
+ * `a:srgbClr` plus colour transforms (`lumMod`, `lumOff`, `tint`,
878
+ * `shade`, `satMod`, `alpha`, …). On save we re-emit verbatim when the
879
+ * resolved {@link fillColor} still matches this node, otherwise we fall
880
+ * back to canonical `<a:srgbClr>`.
881
+ */
882
+ fillColorXml?: XmlObject;
883
+ fillGradient?: string;
884
+ /** Original `gradFill` XML retained for unknown-child and extension round-tripping. */
885
+ fillGradientXml?: XmlObject;
886
+ fillMode?: 'solid' | 'gradient' | 'pattern' | 'none' | 'image' | 'theme' | 'group';
887
+ fillPatternPreset?: string;
888
+ fillPatternBackgroundColor?: string;
889
+ /** Original `pattFill` XML retained for unknown-child round-tripping. */
890
+ fillPatternXml?: XmlObject;
891
+ /** Raw XML node for pattern fill foreground colour (preserves color transforms). */
892
+ fillPatternFgClrXml?: XmlObject;
893
+ /** Raw XML node for pattern fill background colour (preserves color transforms). */
894
+ fillPatternBgClrXml?: XmlObject;
895
+ /** Data-URI or URL for image fill (when fillMode === "image"). */
896
+ fillImageUrl?: string;
897
+ /** How the image is sized within the shape: stretch to fill, or tile/repeat. */
898
+ fillImageMode?: 'stretch' | 'tile';
899
+ fillGradientStops?: Array<{
900
+ color: string;
901
+ position: number;
902
+ opacity?: number;
903
+ /** Raw XML colour node preserved for round-trip (e.g. a:schemeClr with transforms). */
904
+ originalColorXml?: XmlObject;
905
+ }>;
906
+ fillGradientAngle?: number;
907
+ fillGradientType?: 'linear' | 'radial';
908
+ /** Path gradient sub-type from `a:path/@path` (e.g. "circle", "rect", "shape"). */
909
+ fillGradientPathType?: 'circle' | 'rect' | 'shape';
910
+ /** Focal point for path (radial) gradients, derived from `a:fillToRect`.
911
+ * Values are 0..1 fractions relative to shape bounds. */
912
+ fillGradientFocalPoint?: {
913
+ x: number;
914
+ y: number;
915
+ };
916
+ /** Raw fillToRect LTRB values (0..1 fractions) from `a:fillToRect`.
917
+ * Defines the inner rectangle where the gradient reaches its final stop.
918
+ * l/t are insets from left/top edges; r/b are insets from right/bottom edges. */
919
+ fillGradientFillToRect?: {
920
+ l: number;
921
+ t: number;
922
+ r: number;
923
+ b: number;
924
+ };
925
+ /** Gradient tile flip mode (`a:gradFill/@flip`).
926
+ * `none` = no tiling flip (default), `x|y|xy` = mirror in the named axis. */
927
+ fillGradientFlip?: 'none' | 'x' | 'y' | 'xy';
928
+ /** Whether the gradient rotates with the shape (`a:gradFill/@rotWithShape`).
929
+ * Defaults to true per the schema; preserved for round-trip when the source
930
+ * authored the attribute explicitly. */
931
+ fillGradientRotWithShape?: boolean;
932
+ /** Whether the linear gradient is scaled to the shape (`a:lin/@scaled`).
933
+ * Defaults to true per the schema; preserved for round-trip. */
934
+ fillGradientScaled?: boolean;
935
+ fillOpacity?: number;
936
+ strokeColor?: string;
937
+ /**
938
+ * Raw XML colour-choice node preserved from `a:ln/a:solidFill` for
939
+ * round-trip serialisation. See {@link fillColorXml} for the rationale.
940
+ */
941
+ strokeColorXml?: XmlObject;
942
+ strokeWidth?: number;
943
+ strokeOpacity?: number;
944
+ strokeDash?: StrokeDashType;
945
+ /** Line join style (`a:ln/@join`): round, bevel, or miter. */
946
+ lineJoin?: 'round' | 'bevel' | 'miter';
947
+ /** Miter limit (`a:miter/@lim`) in EMU-percent units (default 800000 = 8.0). Only meaningful when lineJoin is 'miter'. */
948
+ miterLimit?: number;
949
+ /** Line cap style (`a:ln/@cap`): flat, rnd, or sq. */
950
+ lineCap?: 'flat' | 'rnd' | 'sq';
951
+ /** Compound line type (`a:ln/@cmpd`). */
952
+ compoundLine?: 'sng' | 'dbl' | 'thickThin' | 'thinThick' | 'tri';
953
+ /** Pen line alignment (`a:ln/@algn`): `ctr` (centre, default) or `in` (inside). */
954
+ lineAlignment?: 'ctr' | 'in';
955
+ shadowColor?: string;
956
+ /** Preserved source `a:effectLst`, including unknown effects and extensions. */
957
+ effectListXml?: XmlObject;
958
+ /** Original outer-shadow node used for lossless surgical updates. */
959
+ outerShadowXml?: XmlObject;
960
+ /** Resolved source shadow colour used to detect colour edits. */
961
+ outerShadowOriginalColor?: string;
962
+ /** Source shadow opacity used to detect alpha edits. */
963
+ outerShadowOriginalOpacity?: number;
964
+ shadowBlur?: number;
965
+ shadowOffsetX?: number;
966
+ shadowOffsetY?: number;
967
+ shadowOpacity?: number;
968
+ /** Preset shadow name from `a:prstShdw/@prst` (e.g. "shdw1"..."shdw20"). */
969
+ presetShadowName?: string;
970
+ /** Shadow angle in degrees (0-360). Parsed from `@_dir` (60000ths of a degree). */
971
+ shadowAngle?: number;
972
+ /** Shadow distance in pixels. Parsed from `@_dist` (EMUs). */
973
+ shadowDistance?: number;
974
+ /** Whether shadow rotates with shape. Parsed from `@_rotWithShape`. */
975
+ shadowRotateWithShape?: boolean;
976
+ /** Outer-shadow horizontal scaling (`a:outerShdw/@sx`) in 1000ths of a percent (default 100000 = 100%). */
977
+ shadowScaleX?: number;
978
+ /** Outer-shadow vertical scaling (`a:outerShdw/@sy`). */
979
+ shadowScaleY?: number;
980
+ /** Outer-shadow horizontal skew (`a:outerShdw/@kx`) in 60000ths of a degree. */
981
+ shadowSkewX?: number;
982
+ /** Outer-shadow vertical skew (`a:outerShdw/@ky`). */
983
+ shadowSkewY?: number;
984
+ /** Outer-shadow alignment (`a:outerShdw/@algn`). */
985
+ shadowAlignment?: 'tl' | 't' | 'tr' | 'l' | 'ctr' | 'r' | 'bl' | 'b' | 'br';
986
+ /** Inner-shadow rotateWithShape (`a:innerShdw/@rotWithShape`). */
987
+ innerShadowRotateWithShape?: boolean;
988
+ /** Reflection fade direction (`a:reflection/@fadeDir`) in 60000ths of a degree. */
989
+ reflectionFadeDirection?: number;
990
+ /** Reflection horizontal scaling (`a:reflection/@sx`). */
991
+ reflectionScaleX?: number;
992
+ /** Reflection vertical scaling (`a:reflection/@sy`). */
993
+ reflectionScaleY?: number;
994
+ /** Reflection horizontal skew (`a:reflection/@kx`). */
995
+ reflectionSkewX?: number;
996
+ /** Reflection vertical skew (`a:reflection/@ky`). */
997
+ reflectionSkewY?: number;
998
+ /** Reflection alignment (`a:reflection/@algn`). */
999
+ reflectionAlignment?: 'tl' | 't' | 'tr' | 'l' | 'ctr' | 'r' | 'bl' | 'b' | 'br';
1000
+ /** Reflection rotateWithShape (`a:reflection/@rotWithShape`). */
1001
+ reflectionRotateWithShape?: boolean;
1002
+ /** Reflection start position (`a:reflection/@stPos`) as 0-1 fraction. */
1003
+ reflectionStartPosition?: number;
1004
+ /** Multiple shadow layers (for advanced effects). */
1005
+ shadows?: ShadowEffect[];
1006
+ glowColor?: string;
1007
+ /** Original glow node used for lossless surgical updates. */
1008
+ glowXml?: XmlObject;
1009
+ /** Resolved source glow colour used to detect colour edits. */
1010
+ glowOriginalColor?: string;
1011
+ /** Source glow opacity used to detect alpha edits. */
1012
+ glowOriginalOpacity?: number;
1013
+ glowRadius?: number;
1014
+ glowOpacity?: number;
1015
+ softEdgeRadius?: number;
1016
+ /** Inner shadow colour (`a:innerShdw`). */
1017
+ innerShadowColor?: string;
1018
+ /** Original inner-shadow node used for lossless surgical updates. */
1019
+ innerShadowXml?: XmlObject;
1020
+ /** Resolved source inner-shadow colour used to detect colour edits. */
1021
+ innerShadowOriginalColor?: string;
1022
+ /** Source inner-shadow opacity used to detect alpha edits. */
1023
+ innerShadowOriginalOpacity?: number;
1024
+ /** Inner shadow opacity (0-1). */
1025
+ innerShadowOpacity?: number;
1026
+ /** Inner shadow blur radius in px. */
1027
+ innerShadowBlur?: number;
1028
+ /** Inner shadow horizontal offset in px. */
1029
+ innerShadowOffsetX?: number;
1030
+ /** Inner shadow vertical offset in px. */
1031
+ innerShadowOffsetY?: number;
1032
+ /** Original soft-edge node, including vendor attributes and extensions. */
1033
+ softEdgeXml?: XmlObject;
1034
+ /** Reflection effect — distance from shape bottom in px. */
1035
+ reflectionBlurRadius?: number;
1036
+ /** Original reflection node, including vendor attributes and extensions. */
1037
+ reflectionXml?: XmlObject;
1038
+ /** Reflection start opacity (0-1). */
1039
+ reflectionStartOpacity?: number;
1040
+ /** Reflection end opacity (0-1). */
1041
+ reflectionEndOpacity?: number;
1042
+ /** Reflection end position (0-1 fraction of shape height). */
1043
+ reflectionEndPosition?: number;
1044
+ /** Reflection direction in degrees. */
1045
+ reflectionDirection?: number;
1046
+ /** Reflection rotation in degrees (`a:reflection/@rot` in 60000ths). */
1047
+ reflectionRotation?: number;
1048
+ /** Reflection distance in px. */
1049
+ reflectionDistance?: number;
1050
+ /** Standalone blur effect radius in px (`a:effectLst > a:blur`). */
1051
+ blurRadius?: number;
1052
+ /** Whether the blur effect grows the bounds of the shape (`a:blur/@grow`). */
1053
+ blurGrow?: boolean;
1054
+ connectorStartArrow?: ConnectorArrowType;
1055
+ /** Start arrow width size ('sm' | 'med' | 'lg'). */
1056
+ connectorStartArrowWidth?: 'sm' | 'med' | 'lg';
1057
+ /** Start arrow length size ('sm' | 'med' | 'lg'). */
1058
+ connectorStartArrowLength?: 'sm' | 'med' | 'lg';
1059
+ connectorEndArrow?: ConnectorArrowType;
1060
+ /** End arrow width size ('sm' | 'med' | 'lg'). */
1061
+ connectorEndArrowWidth?: 'sm' | 'med' | 'lg';
1062
+ /** End arrow length size ('sm' | 'med' | 'lg'). */
1063
+ connectorEndArrowLength?: 'sm' | 'med' | 'lg';
1064
+ /** Connection point for the start of a connector. */
1065
+ connectorStartConnection?: ConnectorConnectionPoint;
1066
+ /** Connection point for the end of a connector. */
1067
+ connectorEndConnection?: ConnectorConnectionPoint;
1068
+ /** Custom dash segments array (`a:custDash/a:ds`). Each entry has dash length and space length in EMU. */
1069
+ customDashSegments?: Array<{
1070
+ dash: number;
1071
+ space: number;
1072
+ }>;
1073
+ /** 3D scene/camera settings from `a:scene3d`. */
1074
+ scene3d?: Pptx3DScene;
1075
+ /** 3D shape extrusion/bevel from `a:sp3d`. */
1076
+ shape3d?: Pptx3DShape;
1077
+ /** Line-level shadow colour from `a:ln/a:effectLst/a:outerShdw`. */
1078
+ lineShadowColor?: string;
1079
+ /** Line-level shadow opacity (0-1). */
1080
+ lineShadowOpacity?: number;
1081
+ /** Line-level shadow blur radius in px. */
1082
+ lineShadowBlur?: number;
1083
+ /** Line-level shadow horizontal offset in px. */
1084
+ lineShadowOffsetX?: number;
1085
+ /** Line-level shadow vertical offset in px. */
1086
+ lineShadowOffsetY?: number;
1087
+ /** Line-level glow colour from `a:ln/a:effectLst/a:glow`. */
1088
+ lineGlowColor?: string;
1089
+ /** Line-level glow radius in px. */
1090
+ lineGlowRadius?: number;
1091
+ /** Line-level glow opacity (0-1). */
1092
+ lineGlowOpacity?: number;
1093
+ /** Raw `a:effectDag` XML node preserved for round-trip serialisation. */
1094
+ effectDagXml?: XmlObject;
1095
+ /** Grayscale flag from effectDag `a:grayscl`. */
1096
+ dagGrayscale?: boolean;
1097
+ /** Bi-level threshold (0-100) from effectDag `a:biLevel`. */
1098
+ dagBiLevel?: number;
1099
+ /** Brightness adjustment (-100 to 100) from effectDag `a:lum/@bright`. */
1100
+ dagLumBrightness?: number;
1101
+ /** Contrast adjustment (-100 to 100) from effectDag `a:lum/@contrast`. */
1102
+ dagLumContrast?: number;
1103
+ /** Hue rotation in degrees (0-360) from effectDag `a:hsl/@hue`. */
1104
+ dagHslHue?: number;
1105
+ /** Saturation adjustment from effectDag `a:hsl/@sat`. */
1106
+ dagHslSaturation?: number;
1107
+ /** Luminance adjustment from effectDag `a:hsl/@lum`. */
1108
+ dagHslLuminance?: number;
1109
+ /** Alpha modulation fixed (0-100) from effectDag `a:alphaModFix`. */
1110
+ dagAlphaModFix?: number;
1111
+ /** Tint hue in degrees from effectDag `a:tint/@hue`. */
1112
+ dagTintHue?: number;
1113
+ /** Tint amount (0-100) from effectDag `a:tint/@amt`. */
1114
+ dagTintAmount?: number;
1115
+ /** Duotone colour pair from effectDag `a:duotone`. */
1116
+ dagDuotone?: {
1117
+ color1: string;
1118
+ color2: string;
1119
+ };
1120
+ /** Fill overlay blend mode from effectDag `a:fillOverlay/@blend`. */
1121
+ dagFillOverlayBlend?: 'over' | 'mult' | 'screen' | 'darken' | 'lighten';
1122
+ /** `<a:lnRef @idx>` — 1-based index into the theme's lnStyleLst. */
1123
+ lnRefIdx?: number;
1124
+ /** Raw XML colour child of `<a:lnRef>` (e.g. `<a:schemeClr>` with transforms). */
1125
+ lnRefColorXml?: XmlObject;
1126
+ /** `<a:fillRef @idx>` — 1-based index into fillStyleLst (1-3) or bgFillStyleLst (1001-1003). */
1127
+ fillRefIdx?: number;
1128
+ /** Raw XML colour child of `<a:fillRef>`. */
1129
+ fillRefColorXml?: XmlObject;
1130
+ /** `<a:effectRef @idx>` — 1-based index into the theme's effectStyleLst. */
1131
+ effectRefIdx?: number;
1132
+ /** Raw XML colour child of `<a:effectRef>`. */
1133
+ effectRefColorXml?: XmlObject;
1134
+ /** `<a:fontRef @idx>` — typically `major`, `minor`, or `none`. */
1135
+ fontRefIdx?: string;
1136
+ /** Raw XML colour child of `<a:fontRef>`. */
1137
+ fontRefColorXml?: XmlObject;
1138
+ }
1139
+
1140
+ /**
1141
+ * Text-related types: rich text styles, bullet metadata, and text segments.
1142
+ *
1143
+ * These types model the contents of `<a:r>`, `<a:rPr>`, `<a:pPr>`,
1144
+ * and `<a:bodyPr>` nodes from the OpenXML Drawing namespace.
1145
+ *
1146
+ * @module pptx-types/text
1147
+ */
1148
+
1149
+ /**
1150
+ * Rich text style properties for a text run or paragraph.
1151
+ *
1152
+ * Combines character-level formatting (font, bold, colour …),
1153
+ * paragraph-level controls (alignment, spacing, indentation), and
1154
+ * body-level properties (autofit, insets, text direction). All
1155
+ * fields are optional — unset properties inherit from layout/master
1156
+ * placeholders or theme defaults.
1157
+ *
1158
+ * @remarks
1159
+ * Font sizes are stored in **points**. Spatial measurements (insets,
1160
+ * margins) are in **pixels** (pre-converted from EMU during parsing).
1161
+ *
1162
+ * @example
1163
+ * ```ts
1164
+ * const heading: TextStyle = {
1165
+ * fontFamily: "Montserrat",
1166
+ * fontSize: 36,
1167
+ * bold: true,
1168
+ * color: "#1A1A2E",
1169
+ * align: "center",
1170
+ * lineSpacing: 1.15,
1171
+ * };
1172
+ *
1173
+ * const body: TextStyle = {
1174
+ * fontFamily: "Open Sans",
1175
+ * fontSize: 14,
1176
+ * color: "#444444",
1177
+ * align: "left",
1178
+ * paragraphSpacingAfter: 8,
1179
+ * };
1180
+ * // => both satisfy the TextStyle interface
1181
+ * ```
1182
+ */
1183
+ interface TextStyle {
1184
+ fontFamily?: string;
1185
+ fontSize?: number;
1186
+ /** When true, renderer should shrink text to fit the shape bounds. */
1187
+ autoFit?: boolean;
1188
+ /** Explicit autofit mode from OOXML body properties.
1189
+ * - 'shrink': `a:spAutoFit` — shrink text on overflow
1190
+ * - 'normal': `a:normAutofit` — normal auto-fit (with optional fontScale)
1191
+ * - 'none': `a:noAutofit` — explicitly no auto-fit (text overflows)
1192
+ * - undefined: no autofit element present (inherit from layout/master)
1193
+ */
1194
+ autoFitMode?: 'shrink' | 'normal' | 'none';
1195
+ /** Font scale percentage for normAutofit (e.g. 0.9 = 90%). Only meaningful when autoFit is true. */
1196
+ autoFitFontScale?: number;
1197
+ /** Line spacing reduction for normAutofit (e.g. 0.2 = reduce by 20%). Only meaningful when autoFit is true. */
1198
+ autoFitLineSpacingReduction?: number;
1199
+ bold?: boolean;
1200
+ italic?: boolean;
1201
+ underline?: boolean;
1202
+ /** Specific underline style (e.g. "sng", "dbl", "wavy"). Falls back to "sng" when `underline` is true. */
1203
+ underlineStyle?: UnderlineStyle;
1204
+ /** Underline colour as hex string (`a:uFill` / `a:uLn`). When absent, inherits text colour. */
1205
+ underlineColor?: string;
1206
+ /**
1207
+ * When true, the source authored `<a:u val="none"/>` to explicitly suppress
1208
+ * underline (rather than omitting the attribute entirely). Preserved so the
1209
+ * writer can re-emit the explicit `none` token instead of dropping it.
1210
+ */
1211
+ underlineExplicitNone?: boolean;
1212
+ /**
1213
+ * Underline line properties parsed from `<a:rPr><a:uLn>` — width, dash
1214
+ * preset, and end caps. Captured as a typed object so the writer can
1215
+ * round-trip the line styling that previously was dropped (only the
1216
+ * solidFill colour was carried before).
1217
+ */
1218
+ underlineLine?: {
1219
+ /** Line width in EMU (raw OOXML) for `a:uLn/@w`. */
1220
+ widthEmu?: number;
1221
+ /** Compound line type (`a:uLn/@cmpd`). */
1222
+ compound?: string;
1223
+ /** Cap style (`a:uLn/@cap`). */
1224
+ cap?: string;
1225
+ /** Pen alignment (`a:uLn/@algn`). */
1226
+ algn?: string;
1227
+ /** Preset dash value (`a:uLn/a:prstDash/@val`). */
1228
+ prstDash?: string;
1229
+ /** Raw `a:uLn/a:headEnd` XML preserved verbatim. */
1230
+ headEndXml?: XmlObject;
1231
+ /** Raw `a:uLn/a:tailEnd` XML preserved verbatim. */
1232
+ tailEndXml?: XmlObject;
1233
+ };
1234
+ /** When `<a:uLnTx/>` is present — underline line follows the text run line. */
1235
+ underlineLineFollowsText?: boolean;
1236
+ /** When `<a:uFillTx/>` is present — underline fill follows the text run fill. */
1237
+ underlineFillFollowsText?: boolean;
1238
+ strikethrough?: boolean;
1239
+ /** Specific strike type: single or double from `a:rPr/@strike`. */
1240
+ strikeType?: 'sngStrike' | 'dblStrike';
1241
+ /** Text outline width in px (`a:rPr > a:ln/@w` in EMU). */
1242
+ textOutlineWidth?: number;
1243
+ /** Text outline colour as hex string (`a:rPr > a:ln > a:solidFill`). */
1244
+ textOutlineColor?: string;
1245
+ /** When true, the text body has no fill (`a:rPr > a:noFill`), producing hollow/outline-only text. */
1246
+ textFillNone?: boolean;
1247
+ /** Superscript/subscript baseline shift as percentage (`a:rPr/@baseline`). Positive = super, negative = sub. */
1248
+ baseline?: number;
1249
+ /** Character spacing in hundredths of a point (`a:rPr/@spc`). */
1250
+ characterSpacing?: number;
1251
+ /** Kerning threshold in hundredths of a point (`a:rPr/@kern`). 0 = none. */
1252
+ kerning?: number;
1253
+ /** Text highlight colour as hex string (`a:highlight`). */
1254
+ highlightColor?: string;
1255
+ /** Text-level gradient fill CSS string (from `a:rPr > a:gradFill`). */
1256
+ textFillGradient?: string;
1257
+ /** Structured gradient stops for text fill round-trip serialization. */
1258
+ textFillGradientStops?: Array<{
1259
+ color: string;
1260
+ position: number;
1261
+ opacity?: number;
1262
+ }>;
1263
+ /** Gradient angle in degrees for text fill round-trip. */
1264
+ textFillGradientAngle?: number;
1265
+ /** Gradient type for text fill round-trip ('linear' | 'radial'). */
1266
+ textFillGradientType?: 'linear' | 'radial';
1267
+ /** Text-level pattern fill preset (from `a:rPr > a:pattFill`). */
1268
+ textFillPattern?: string;
1269
+ /** Text-level pattern foreground colour. */
1270
+ textFillPatternForeground?: string;
1271
+ /** Text-level pattern background colour. */
1272
+ textFillPatternBackground?: string;
1273
+ hyperlink?: string;
1274
+ /** Relationship ID for the hyperlink (`a:hlinkClick/@r:id`) — preserved for round-trip serialization. */
1275
+ hyperlinkRId?: string;
1276
+ /** Hyperlink tooltip text (`a:hlinkClick/@tooltip`). */
1277
+ hyperlinkTooltip?: string;
1278
+ /** Hyperlink action type (`a:hlinkClick/@action`). */
1279
+ hyperlinkAction?: string;
1280
+ /** Whether the hyperlink target is an internal slide jump (targetSlideIndex style). */
1281
+ hyperlinkTargetSlideIndex?: number;
1282
+ color?: string;
1283
+ /**
1284
+ * Raw XML colour-choice node preserved from `a:rPr/a:solidFill` for
1285
+ * round-trip serialisation. Captures `a:schemeClr` / `a:sysClr` /
1286
+ * `a:prstClr` / `a:srgbClr` plus colour transforms. On save we re-emit
1287
+ * verbatim when the resolved {@link color} still matches this node.
1288
+ */
1289
+ colorXml?: XmlObject;
1290
+ align?: 'left' | 'center' | 'right' | 'justify' | 'justLow' | 'dist' | 'thaiDist';
1291
+ vAlign?: 'top' | 'middle' | 'bottom';
1292
+ /** Right-to-left paragraph/run direction (`a:pPr/@rtl`, `a:rPr/@rtl`). */
1293
+ rtl?: boolean;
1294
+ /** Body text direction (`a:bodyPr/@vert`).
1295
+ *
1296
+ * Values map to OOXML `a:bodyPr/@vert` attribute values:
1297
+ * - `"horizontal"` — default horizontal text (`horz`)
1298
+ * - `"vertical"` — standard vertical text, right-to-left columns (`vert`)
1299
+ * - `"vertical270"` — text rotated 270 degrees (`vert270`)
1300
+ * - `"eaVert"` — East Asian vertical text with CJK glyphs upright (`eaVert`)
1301
+ * - `"wordArtVert"` — WordArt vertical, each character upright stacked (`wordArtVert`)
1302
+ * - `"wordArtVertRtl"` — WordArt vertical, right-to-left direction (`wordArtVertRtl`)
1303
+ * - `"mongolianVert"` — Mongolian vertical text, left-to-right columns (`mongolianVert`)
1304
+ */
1305
+ textDirection?: 'horizontal' | 'vertical' | 'vertical270' | 'eaVert' | 'wordArtVert' | 'wordArtVertRtl' | 'mongolianVert';
1306
+ /** Body column count (`a:bodyPr/@numCol`). */
1307
+ columnCount?: number;
1308
+ /** Column spacing in px (`a:bodyPr/@spcCol` in EMU). */
1309
+ columnSpacing?: number;
1310
+ /** Horizontal overflow mode from `a:bodyPr/@hOverflow`. */
1311
+ hOverflow?: 'overflow' | 'clip';
1312
+ /** Vertical overflow mode from `a:bodyPr/@vertOverflow`. */
1313
+ vertOverflow?: 'overflow' | 'clip' | 'ellipsis';
1314
+ /** Body text left inset in px (`a:bodyPr/@lIns` in EMU). */
1315
+ bodyInsetLeft?: number;
1316
+ /** Body text top inset in px (`a:bodyPr/@tIns` in EMU). */
1317
+ bodyInsetTop?: number;
1318
+ /** Body text right inset in px (`a:bodyPr/@rIns` in EMU). */
1319
+ bodyInsetRight?: number;
1320
+ /** Body text bottom inset in px (`a:bodyPr/@bIns` in EMU). */
1321
+ bodyInsetBottom?: number;
1322
+ /** Paragraph spacing before in px. */
1323
+ paragraphSpacingBefore?: number;
1324
+ /** Paragraph spacing after in px. */
1325
+ paragraphSpacingAfter?: number;
1326
+ /** Line spacing multiplier (e.g. 1.2 = 120%). Used when mode is proportional (spcPct). */
1327
+ lineSpacing?: number;
1328
+ /** Exact line spacing in points (from `a:lnSpc > a:spcPts`). Takes priority over `lineSpacing` when set. */
1329
+ lineSpacingExactPt?: number;
1330
+ /** Paragraph left margin in px (`a:pPr/@marL` in EMU). */
1331
+ paragraphMarginLeft?: number;
1332
+ /** Paragraph right margin in px (`a:pPr/@marR` in EMU). */
1333
+ paragraphMarginRight?: number;
1334
+ /** Paragraph first-line indent in px (`a:pPr/@indent` in EMU). */
1335
+ paragraphIndent?: number;
1336
+ /** Tab stop positions and alignments (`a:pPr/a:tabLst/a:tab`). */
1337
+ tabStops?: Array<{
1338
+ position: number;
1339
+ align: 'l' | 'ctr' | 'r' | 'dec';
1340
+ leader?: 'none' | 'dot' | 'hyphen' | 'underscore';
1341
+ }>;
1342
+ /** Body text wrapping mode from `a:bodyPr/@wrap`. */
1343
+ textWrap?: 'square' | 'none';
1344
+ /** Preset text warp type from `a:bodyPr/a:prstTxWarp`. */
1345
+ textWarpPreset?: PptxTextWarpPreset;
1346
+ /** Primary adjustment value for text warp (from `a:prstTxWarp/a:avLst/a:gd` with name "adj").
1347
+ * Stored as raw OOXML 1/60000th units (e.g. 50000 = default for many presets). */
1348
+ textWarpAdj?: number;
1349
+ /** Secondary adjustment value for text warp (from `a:prstTxWarp/a:avLst/a:gd` with name "adj2").
1350
+ * Stored as raw OOXML 1/60000th units. */
1351
+ textWarpAdj2?: number;
1352
+ /** Text capitalization style from `a:rPr/@cap`. */
1353
+ textCaps?: 'all' | 'small' | 'none';
1354
+ /**
1355
+ * When true, the source authored `<a:rPr cap="none"/>` explicitly. This
1356
+ * differs from {@link textCaps} = `"none"` only because the writer must
1357
+ * preserve the explicit token rather than collapse it to omission.
1358
+ */
1359
+ textCapsExplicitNone?: boolean;
1360
+ /** Symbol font family from `a:sym`. */
1361
+ symbolFont?: string;
1362
+ /** East Asian font family from `a:ea`. */
1363
+ eastAsiaFont?: string;
1364
+ /** Complex Script font family from `a:cs`. */
1365
+ complexScriptFont?: string;
1366
+ /** Text language from `a:rPr/@lang`. */
1367
+ language?: string;
1368
+ /** Hyperlink mouse-over target from `a:hlinkMouseOver`. */
1369
+ hyperlinkMouseOver?: string;
1370
+ /** Hyperlink invalidUrl attribute (`a:hlinkClick/@invalidUrl`). */
1371
+ hyperlinkInvalidUrl?: string;
1372
+ /** Hyperlink target frame (`a:hlinkClick/@tgtFrame`). */
1373
+ hyperlinkTargetFrame?: string;
1374
+ /** Whether hyperlink history is tracked (`a:hlinkClick/@history`). */
1375
+ hyperlinkHistory?: boolean;
1376
+ /** Whether hyperlink uses highlight-click effect (`a:hlinkClick/@highlightClick`). */
1377
+ hyperlinkHighlightClick?: boolean;
1378
+ /** Whether hyperlink ends a sound (`a:hlinkClick/@endSnd`). */
1379
+ hyperlinkEndSound?: boolean;
1380
+ /** Kumimoji (ideographic text combining) flag for vertical CJK text (`a:rPr/@kumimoji`). */
1381
+ kumimoji?: boolean;
1382
+ /** Normalize height flag (`a:rPr/@normalizeH`). */
1383
+ normalizeHeight?: boolean;
1384
+ /** No proofing flag (`a:rPr/@noProof`). */
1385
+ noProof?: boolean;
1386
+ /** Dirty flag indicating run has been edited (`a:rPr/@dirty`). */
1387
+ dirty?: boolean;
1388
+ /** Error flag indicating spelling error (`a:rPr/@err`). */
1389
+ spellingError?: boolean;
1390
+ /** Smart tag clean flag (`a:rPr/@smtClean`). */
1391
+ smartTagClean?: boolean;
1392
+ /** Bookmark link target (`a:rPr/@bmk`). */
1393
+ bookmark?: string;
1394
+ /** Alternative language for the run (`a:rPr/@altLang`). Populated for runs
1395
+ * authored in mixed-script documents (e.g. Asian/Latin combined). */
1396
+ altLanguage?: string;
1397
+ /** SmartTag (Office grammar tag) GUID id (`a:rPr/@smtId`). Round-tripped
1398
+ * verbatim — the engine doesn't interpret it. */
1399
+ smartTagId?: number;
1400
+ /** Latin font PANOSE classification string from `a:rPr > a:latin/@panose`. */
1401
+ latinFontPanose?: string;
1402
+ /** Latin font pitch + family flag from `a:rPr > a:latin/@pitchFamily`. */
1403
+ latinFontPitchFamily?: number;
1404
+ /** Latin font character set id from `a:rPr > a:latin/@charset`. */
1405
+ latinFontCharset?: number;
1406
+ /** East-Asian font PANOSE from `a:rPr > a:ea/@panose`. */
1407
+ eastAsiaFontPanose?: string;
1408
+ /** East-Asian font pitch + family flag from `a:rPr > a:ea/@pitchFamily`. */
1409
+ eastAsiaFontPitchFamily?: number;
1410
+ /** East-Asian font character set id from `a:rPr > a:ea/@charset`. */
1411
+ eastAsiaFontCharset?: number;
1412
+ /** Complex-script font PANOSE from `a:rPr > a:cs/@panose`. */
1413
+ complexScriptFontPanose?: string;
1414
+ /** Complex-script font pitch + family flag from `a:rPr > a:cs/@pitchFamily`. */
1415
+ complexScriptFontPitchFamily?: number;
1416
+ /** Complex-script font character set id from `a:rPr > a:cs/@charset`. */
1417
+ complexScriptFontCharset?: number;
1418
+ /** Symbol-font PANOSE from `a:rPr > a:sym/@panose`. */
1419
+ symbolFontPanose?: string;
1420
+ /** Symbol-font pitch + family flag from `a:rPr > a:sym/@pitchFamily`. */
1421
+ symbolFontPitchFamily?: number;
1422
+ /** Symbol-font character set id from `a:rPr > a:sym/@charset`. */
1423
+ symbolFontCharset?: number;
1424
+ /** Paragraph list type for toggling bullet / numbered lists via the toolbar.
1425
+ * - `'bullet'` — character bullet (default "•")
1426
+ * - `'numbered'` — auto-numbered list (arabicPeriod)
1427
+ * - `'none'` — explicitly no list
1428
+ */
1429
+ listType?: 'bullet' | 'numbered' | 'none';
1430
+ /** Default tab size in px (`a:pPr/@defTabSz` in EMU). */
1431
+ defaultTabSize?: number;
1432
+ /** East Asian line break flag (`a:pPr/@eaLnBrk`). */
1433
+ eaLineBreak?: boolean;
1434
+ /** Latin line break flag (`a:pPr/@latinLnBrk`). */
1435
+ latinLineBreak?: boolean;
1436
+ /** Font alignment (`a:pPr/@fontAlgn`): 'auto' | 'base' | 'ctr' | 't' | 'b'. */
1437
+ fontAlignment?: string;
1438
+ /** Hanging punctuation flag (`a:pPr/@hangingPunct`). */
1439
+ hangingPunctuation?: boolean;
1440
+ /** Whether to space first and last paragraph from body edges (`a:bodyPr/@spcFirstLastPara`). */
1441
+ spaceFirstLastParagraph?: boolean;
1442
+ /** Right-to-left column flow (`a:bodyPr/@rtlCol`). */
1443
+ rtlColumns?: boolean;
1444
+ /** Whether text originates from WordArt (`a:bodyPr/@fromWordArt`). */
1445
+ fromWordArt?: boolean;
1446
+ /** Whether text anchoring is centered (`a:bodyPr/@anchorCtr`). */
1447
+ anchorCenter?: boolean;
1448
+ /** Force anti-aliasing (`a:bodyPr/@forceAA`). */
1449
+ forceAntiAlias?: boolean;
1450
+ /** Upright text in 3D views (`a:bodyPr/@upright`). */
1451
+ upright?: boolean;
1452
+ /** Compatible line spacing flag (`a:bodyPr/@compatLnSpc`). */
1453
+ compatibleLineSpacing?: boolean;
1454
+ /**
1455
+ * Text body rotation in **degrees** (`a:bodyPr/@rot`).
1456
+ *
1457
+ * OOXML stores the value as 60000ths of a degree. Positive values rotate
1458
+ * the body clockwise. When undefined, the attribute is omitted on save
1459
+ * (PowerPoint treats absent `rot` as inherit/none).
1460
+ */
1461
+ textBodyRotation?: number;
1462
+ /** Text shadow colour as hex string (`a:outerShdw`). */
1463
+ textShadowColor?: string;
1464
+ /** Text shadow blur radius in px. */
1465
+ textShadowBlur?: number;
1466
+ /** Text shadow horizontal offset in px. */
1467
+ textShadowOffsetX?: number;
1468
+ /** Text shadow vertical offset in px. */
1469
+ textShadowOffsetY?: number;
1470
+ /** Text shadow opacity (0-1). */
1471
+ textShadowOpacity?: number;
1472
+ /** Text inner shadow colour (`a:innerShdw`). */
1473
+ textInnerShadowColor?: string;
1474
+ /** Text inner shadow opacity (0-1). */
1475
+ textInnerShadowOpacity?: number;
1476
+ /** Text inner shadow blur radius in px. */
1477
+ textInnerShadowBlur?: number;
1478
+ /** Text inner shadow horizontal offset in px. */
1479
+ textInnerShadowOffsetX?: number;
1480
+ /** Text inner shadow vertical offset in px. */
1481
+ textInnerShadowOffsetY?: number;
1482
+ /** Preset shadow type from `a:prstShdw/@prst` (e.g. "shdw1"..."shdw20"). */
1483
+ textPresetShadowName?: string;
1484
+ /** Preset shadow colour as hex string. */
1485
+ textPresetShadowColor?: string;
1486
+ /** Preset shadow opacity (0-1). */
1487
+ textPresetShadowOpacity?: number;
1488
+ /** Preset shadow distance in px. */
1489
+ textPresetShadowDistance?: number;
1490
+ /** Preset shadow direction in degrees. */
1491
+ textPresetShadowDirection?: number;
1492
+ /** Text blur effect radius in px (`a:blur`). */
1493
+ textBlurRadius?: number;
1494
+ /** Text alpha modulation fixed (0-100) from `a:alphaModFix`. */
1495
+ textAlphaModFix?: number;
1496
+ /** Text alpha modulation from `a:alphaMod` (0-100 percentage). */
1497
+ textAlphaMod?: number;
1498
+ /** Text hue shift in degrees from `a:hsl/@hue`. */
1499
+ textHslHue?: number;
1500
+ /** Text saturation adjustment from `a:hsl/@sat`. */
1501
+ textHslSaturation?: number;
1502
+ /** Text luminance adjustment from `a:hsl/@lum`. */
1503
+ textHslLuminance?: number;
1504
+ /** Text colour change from colour as hex string (`a:clrChange`). */
1505
+ textClrChangeFrom?: string;
1506
+ /** Text colour change to colour as hex string. */
1507
+ textClrChangeTo?: string;
1508
+ /** Text duotone colour pair (`a:duotone`). */
1509
+ textDuotone?: {
1510
+ color1: string;
1511
+ color2: string;
1512
+ };
1513
+ /** Text glow colour as hex string (`a:glow`). */
1514
+ textGlowColor?: string;
1515
+ /** Text glow radius in px. */
1516
+ textGlowRadius?: number;
1517
+ /** Text glow opacity (0-1). */
1518
+ textGlowOpacity?: number;
1519
+ /** Text reflection enabled flag. */
1520
+ textReflection?: boolean;
1521
+ /** Text reflection blur radius in px. */
1522
+ textReflectionBlur?: number;
1523
+ /** Text reflection start opacity (0-1). */
1524
+ textReflectionStartOpacity?: number;
1525
+ /** Text reflection end opacity (0-1). */
1526
+ textReflectionEndOpacity?: number;
1527
+ /** Text reflection offset distance in px. */
1528
+ textReflectionOffset?: number;
1529
+ /** 3D extrusion/bevel settings on the text body. */
1530
+ text3d?: Text3DStyle;
1531
+ /** 3D scene (camera + light rig) settings on the text body (`a:bodyPr/a:scene3d`). */
1532
+ textBodyScene3d?: Pptx3DScene;
1533
+ /** Raw `a:scene3d` subtree used to preserve extensions and unmodelled children. */
1534
+ textBodyScene3dXml?: XmlObject;
1535
+ /**
1536
+ * Raw `<a:extLst>` subtree captured from `<a:bodyPr>`. Preserved verbatim so
1537
+ * authored extensions (e.g. content placeholders, custom application data)
1538
+ * survive a round-trip even though the engine doesn't interpret them.
1539
+ */
1540
+ bodyPropertiesExtLstXml?: XmlObject;
1541
+ /**
1542
+ * Raw `<a:extLst>` subtree captured from `<a:pPr>`. Only meaningful on the
1543
+ * paragraph-level style (paragraphs propagate this via the first segment).
1544
+ */
1545
+ paragraphPropertiesExtLstXml?: XmlObject;
1546
+ /**
1547
+ * Raw `<a:extLst>` subtree captured from `<a:rPr>`. Persisted verbatim on
1548
+ * save when present — covers run-level extensions the typed model doesn't
1549
+ * model (e.g. `a14:hiddenFill` and similar).
1550
+ */
1551
+ runPropertiesExtLstXml?: XmlObject;
1552
+ /**
1553
+ * Raw `<a:defRPr>` XML node captured from `<a:pPr>`. The schema permits
1554
+ * `defRPr` directly inside `pPr` so that paragraph defaults can specify the
1555
+ * end-paragraph run formatting; previously this was dropped on save. We
1556
+ * persist the parsed XML object so it round-trips verbatim.
1557
+ *
1558
+ * Only meaningful on the *first* segment of each paragraph (matches the
1559
+ * convention used for {@link bulletInfo} / {@link endParaRunProperties}).
1560
+ */
1561
+ paragraphDefaultRunPropertiesXml?: XmlObject;
1562
+ }
1563
+ /**
1564
+ * Structured bullet metadata attached to the first {@link TextSegment}
1565
+ * of each paragraph.
1566
+ *
1567
+ * Describes how the paragraph bullet should render: character bullets
1568
+ * (`char`), auto-numbered lists (`autoNumType`), or picture bullets
1569
+ * (`imageRelId` / `imageDataUrl`). Set `none: true` when `a:buNone`
1570
+ * explicitly suppresses the bullet.
1571
+ *
1572
+ * @example
1573
+ * ```ts
1574
+ * // Simple character bullet:
1575
+ * const bullet: BulletInfo = { char: "•", color: "#333333" };
1576
+ *
1577
+ * // Auto-numbered list starting at 1:
1578
+ * const numbered: BulletInfo = {
1579
+ * autoNumType: "arabicPeriod",
1580
+ * autoNumStartAt: 1,
1581
+ * };
1582
+ * // => { char: "•", color: "#333333" } and { autoNumType: "arabicPeriod", autoNumStartAt: 1 }
1583
+ * ```
1584
+ */
1585
+ interface BulletInfo {
1586
+ /** Bullet character (e.g. "•", "-", "»") from `a:buChar`. */
1587
+ char?: string;
1588
+ /** Auto-numbering type (e.g. "arabicPeriod", "romanUcPeriod") from `a:buAutoNum`. */
1589
+ autoNumType?: string;
1590
+ /** Auto-numbering start value. */
1591
+ autoNumStartAt?: number;
1592
+ /** Zero-based paragraph index within the text body (for auto-numbering). */
1593
+ paragraphIndex?: number;
1594
+ /** Bullet font family from `a:buFont`. */
1595
+ fontFamily?: string;
1596
+ /** Bullet size as percentage of text font size from `a:buSzPct`. */
1597
+ sizePercent?: number;
1598
+ /** Bullet size in points from `a:buSzPts`. */
1599
+ sizePts?: number;
1600
+ /** Bullet color as hex string from `a:buClr`. */
1601
+ color?: string;
1602
+ /**
1603
+ * Raw colour-choice XML captured from `<a:buClr>` so that themed bullets
1604
+ * (`a:schemeClr`, `a:sysClr`, `a:prstClr`) round-trip with their original
1605
+ * identity rather than being flattened to `<a:srgbClr/>` on save.
1606
+ */
1607
+ colorXml?: XmlObject;
1608
+ /** True when `a:buNone` explicitly suppresses bullets. */
1609
+ none?: boolean;
1610
+ /** Picture bullet: relationship ID from `a:buBlip` → `a:blip[@r:embed]`. */
1611
+ imageRelId?: string;
1612
+ /** Picture bullet: data URL of the embedded image. */
1613
+ imageDataUrl?: string;
1614
+ /**
1615
+ * Raw `<a:buBlip>` XML captured at parse time. Carries the full blipFill
1616
+ * subtree (`a:tile`, `a:stretch`, `a:srcRect`, `a:blip > a:extLst`) so the
1617
+ * writer can emit the complete original definition rather than the bare
1618
+ * `a:blip[@r:embed]` mapping. When set, the writer prefers it over
1619
+ * {@link imageRelId} for emission.
1620
+ */
1621
+ imageBlipFillXml?: XmlObject;
1622
+ /** When true, `<a:buFontTx/>` was specified — inherit the bullet font from
1623
+ * the run text, not from a buFont declaration. */
1624
+ fontInherit?: boolean;
1625
+ /** When true, `<a:buClrTx/>` was specified — inherit the bullet colour from
1626
+ * the run text. */
1627
+ colorInherit?: boolean;
1628
+ /** When true, `<a:buSzTx/>` was specified — inherit the bullet size from
1629
+ * the run text font size. */
1630
+ sizeInherit?: boolean;
1631
+ }
1632
+ /**
1633
+ * A single text run within a paragraph.
1634
+ *
1635
+ * A text body is decomposed into an array of `TextSegment` objects,
1636
+ * each with its own style. Paragraph breaks are represented as
1637
+ * segments with `isParagraphBreak: true`.
1638
+ *
1639
+ * @example
1640
+ * ```ts
1641
+ * const segments: TextSegment[] = [
1642
+ * { text: "Bold intro ", style: { bold: true, fontSize: 16 } },
1643
+ * { text: "and normal text.", style: { fontSize: 16 } },
1644
+ * { text: "", style: {}, isParagraphBreak: true },
1645
+ * { text: "Second paragraph.", style: { fontSize: 14 } },
1646
+ * ];
1647
+ * // => 4 segments: 2 styled runs, 1 paragraph break, 1 normal run
1648
+ * ```
1649
+ */
1650
+ interface TextSegment {
1651
+ text: string;
1652
+ style: TextStyle;
1653
+ /** When this segment originated from an `a:fld` element, stores the field type (e.g. "slidenum", "datetime"). */
1654
+ fieldType?: string;
1655
+ /** When this segment originated from an `a:fld` element, stores the field GUID. */
1656
+ fieldGuid?: string;
1657
+ /**
1658
+ * Original attribute name used to author the field GUID — `'uuid'` for the
1659
+ * `a:fld/@uuid` form authored by some legacy producers, `'id'` for the
1660
+ * canonical `a:fld/@id` form. Preserved so the writer round-trips whichever
1661
+ * spelling the source used (PowerPoint accepts both). Defaults to `'id'`
1662
+ * on save when undefined.
1663
+ */
1664
+ fieldGuidAttr?: 'uuid' | 'id';
1665
+ /**
1666
+ * Raw per-field paragraph properties (`a:fld > a:pPr`). The schema permits
1667
+ * `pPr` inside an `a:fld` so the field can carry its own paragraph-level
1668
+ * formatting; preserved verbatim on save when present.
1669
+ */
1670
+ fieldParagraphPropertiesXml?: XmlObject;
1671
+ /** Raw OMML XML node for equation segments (from `a14:m` / `m:oMathPara`). */
1672
+ equationXml?: Record<string, unknown>;
1673
+ /**
1674
+ * Optional equation number for numbered equations (e.g. "(1)", "(2.3)").
1675
+ * When present, the equation is rendered centered with the number right-aligned.
1676
+ */
1677
+ equationNumber?: string;
1678
+ /** Whether this segment represents a paragraph break rather than renderable text. */
1679
+ isParagraphBreak?: boolean;
1680
+ /**
1681
+ * Whether this segment represents a soft line break (`a:br`) rather than
1682
+ * a paragraph terminator. Soft line breaks remain inside the same paragraph
1683
+ * but force a line wrap and may carry their own run properties.
1684
+ *
1685
+ * The renderer should treat the segment text as `"\n"` when present.
1686
+ */
1687
+ isLineBreak?: true;
1688
+ /**
1689
+ * Raw `a:rPr` XML for an `a:br` (soft line break) segment, captured verbatim
1690
+ * during parse so the writer can re-emit attributes/colours/fonts that the
1691
+ * typed model doesn't represent. Only meaningful when {@link isLineBreak}
1692
+ * is `true`.
1693
+ */
1694
+ breakRunProperties?: Record<string, unknown>;
1695
+ /** Structured bullet info for the first segment of a paragraph. */
1696
+ bulletInfo?: BulletInfo;
1697
+ /**
1698
+ * Outline level for the paragraph this segment starts (`a:p/@lvl`).
1699
+ *
1700
+ * Only meaningful on the first segment of a paragraph (matching the
1701
+ * convention used for {@link bulletInfo}). Stored as the raw OOXML
1702
+ * value (0 = top level, 1-8 = nested) and serialised back when non-zero.
1703
+ */
1704
+ paragraphLevel?: number;
1705
+ /**
1706
+ * Raw `a:endParaRPr` XML node for the paragraph this segment starts.
1707
+ *
1708
+ * Captured verbatim on parse so attributes and child colours/fonts that
1709
+ * the typed model doesn't represent survive a round-trip. Only meaningful
1710
+ * on the first segment of a paragraph.
1711
+ */
1712
+ endParaRunProperties?: Record<string, unknown>;
1713
+ /**
1714
+ * Phonetic annotation text from `a:ruby > a:rt` (e.g. furigana, pinyin).
1715
+ * When present, the renderer should wrap the base text with an HTML `<ruby>` tag.
1716
+ */
1717
+ rubyText?: string;
1718
+ /**
1719
+ * Ruby text alignment from `a:rubyPr > @val` attribute.
1720
+ * Values: "ctr" (center), "l" (left), "r" (right), "dist" (distribute), "distCat", "distLetter".
1721
+ * @default "ctr"
1722
+ */
1723
+ rubyAlignment?: string;
1724
+ /**
1725
+ * Ruby text font size as a percentage of the base text font size
1726
+ * from `a:rubyPr/@hps` (half-point size) or inferred from rt run font size.
1727
+ * Stored in **points** for consistency with `TextStyle.fontSize`.
1728
+ */
1729
+ rubyFontSize?: number;
1730
+ /**
1731
+ * Style for the ruby (phonetic) text run, parsed from `a:rt > a:r > a:rPr`.
1732
+ * Used by the renderer to apply font family, colour, etc. to the `<rt>` element.
1733
+ */
1734
+ rubyStyle?: TextStyle;
1735
+ }
1736
+
1737
+ /**
1738
+ * Base and mixin interfaces for all PPTX slide elements, plus
1739
+ * placeholder inheritance types.
1740
+ *
1741
+ * Every concrete element variant (text, shape, image …) extends
1742
+ * {@link PptxElementBase}. Text-bearing elements also mix in
1743
+ * {@link PptxTextProperties}, and shapes / connectors / images add
1744
+ * {@link PptxShapeProperties}.
1745
+ *
1746
+ * @module pptx-types/element-base
1747
+ */
1748
+
1749
+ /**
1750
+ * Properties shared by **every** element on a slide.
1751
+ *
1752
+ * Position and size are in pixels (converted from EMU at parse time).
1753
+ * Optional properties apply to subsets of elements or may be absent in
1754
+ * the original OOXML.
1755
+ *
1756
+ * @example
1757
+ * ```ts
1758
+ * const base: PptxElementBase = {
1759
+ * id: "el_001",
1760
+ * x: 100, y: 50,
1761
+ * width: 400, height: 200,
1762
+ * rotation: 15,
1763
+ * opacity: 0.9,
1764
+ * };
1765
+ * // => satisfies PptxElementBase
1766
+ * ```
1767
+ */
1768
+ interface PptxElementBase {
1769
+ id: string;
1770
+ /**
1771
+ * The shape's native OOXML id from `p:cNvPr/@id` (an unsigned integer, as a
1772
+ * string), captured on load. Distinct from {@link id}, which is a synthetic
1773
+ * positional identity (`${slidePath}-shape-${index}`) the loader assigns for
1774
+ * selection / undo / template tracking. Animations target shapes by this
1775
+ * native id (`p:spTgt/@spid`), so it is the stable key used to reconcile an
1776
+ * animation to the element it animates across a save/reload round trip.
1777
+ * Absent on SDK-created elements until one is minted at save time.
1778
+ */
1779
+ shapeId?: string;
1780
+ /** Element name from `cNvPr/@name`. Used for morph transition matching via the `!!` naming convention. */
1781
+ name?: string;
1782
+ x: number;
1783
+ y: number;
1784
+ width: number;
1785
+ height: number;
1786
+ rotation?: number;
1787
+ /** Skew along the X axis in degrees (parsed from `@_skewX` in 1/60000ths of a degree). */
1788
+ skewX?: number;
1789
+ /** Skew along the Y axis in degrees (parsed from `@_skewY` in 1/60000ths of a degree). */
1790
+ skewY?: number;
1791
+ flipHorizontal?: boolean;
1792
+ flipVertical?: boolean;
1793
+ /** Whether this element is hidden (used by the Elements Panel visibility toggle). */
1794
+ hidden?: boolean;
1795
+ /** Element-level opacity (0-1). */
1796
+ opacity?: number;
1797
+ rawXml?: XmlObject;
1798
+ /** Shape-level click action (from `a:hlinkClick` on `p:cNvPr`). */
1799
+ actionClick?: PptxAction;
1800
+ /** Shape-level hover action (from `a:hlinkHover` on `p:cNvPr`). */
1801
+ actionHover?: PptxAction;
1802
+ /** Shape lock attributes parsed from `p:cNvSpPr/a:spLocks`. */
1803
+ locks?: PptxShapeLocks;
1804
+ /**
1805
+ * Opaque `<a:ext>` children captured from the shape's `<a:extLst>` whose
1806
+ * URI is not recognised by a typed extractor (hidden fill/line, image
1807
+ * effects, …). Preserved verbatim and re-emitted on save so unknown
1808
+ * vendor extensions survive a round-trip.
1809
+ *
1810
+ * Mirrors the existing `effectDagXml` / `endParaRunProperties` raw-XML
1811
+ * preservation pattern.
1812
+ */
1813
+ extLstXml?: XmlObject[];
1814
+ }
1815
+ /**
1816
+ * Text content mixin — present on text boxes and shapes.
1817
+ *
1818
+ * Shapes can contain text overlaid on the shape geometry, so both
1819
+ * `TextPptxElement` and `ShapePptxElement` extend this interface.
1820
+ *
1821
+ * @example
1822
+ * ```ts
1823
+ * const props: PptxTextProperties = {
1824
+ * text: "Hello World",
1825
+ * textStyle: { fontSize: 24, bold: true, color: "#333333" },
1826
+ * };
1827
+ * // => satisfies PptxTextProperties
1828
+ * ```
1829
+ */
1830
+ interface PptxTextProperties {
1831
+ text?: string;
1832
+ textStyle?: TextStyle;
1833
+ /** Rich text segments with individual styling. */
1834
+ textSegments?: TextSegment[];
1835
+ /** Per-paragraph indentation (marginLeft, indent) for multi-level bullet support. */
1836
+ paragraphIndents?: Array<{
1837
+ marginLeft?: number;
1838
+ indent?: number;
1839
+ }>;
1840
+ /** Placeholder prompt text inherited from layout/master (e.g. "Click to add title"). Shown as a greyed-out hint when the shape has no user-entered text. */
1841
+ promptText?: string;
1842
+ /** Linked text box chain ID from `a:bodyPr > a:linkedTxbx/@id` or `a:txbx > a:linkedTxbx/@id`. Text overflows from one linked frame to the next. */
1843
+ linkedTxbxId?: number;
1844
+ /** Sequence number within a linked text box chain (0-based). */
1845
+ linkedTxbxSeq?: number;
1846
+ }
1847
+ /**
1848
+ * Shape styling & geometry mixin — present on shapes, connectors, and images.
1849
+ *
1850
+ * @example
1851
+ * ```ts
1852
+ * const props: PptxShapeProperties = {
1853
+ * shapeType: "roundRect",
1854
+ * shapeStyle: { fillColor: "#0055AA", strokeWidth: 2 },
1855
+ * shapeAdjustments: { adj: 16667 },
1856
+ * };
1857
+ * // => satisfies PptxShapeProperties
1858
+ * ```
1859
+ */
1860
+ interface PptxShapeProperties {
1861
+ shapeStyle?: ShapeStyle;
1862
+ /** Preset geometry name, e.g. "rect", "ellipse", "roundRect". */
1863
+ shapeType?: string;
1864
+ /** Geometry adjustment values, e.g. `{ adj: 16667 }`. */
1865
+ shapeAdjustments?: Record<string, number>;
1866
+ /** Adjustment handles for interactive shape modification (yellow diamond handles). */
1867
+ adjustmentHandles?: GeometryAdjustmentHandle[];
1868
+ }
1869
+
1870
+ /** Tick-mark placement from ChartML `ST_TickMark`. */
1871
+ type PptxChartTickMark = 'cross' | 'in' | 'none' | 'out';
1872
+ /** Typed axis tick and category/date label controls. */
1873
+ interface PptxChartAxisLabelFormatting {
1874
+ /** Primary and secondary tick-mark placement. */
1875
+ majorTickMark?: PptxChartTickMark;
1876
+ minorTickMark?: PptxChartTickMark;
1877
+ /** Tick-label position from ChartML `ST_TickLblPos`. */
1878
+ tickLblPos?: 'high' | 'low' | 'nextTo' | 'none';
1879
+ /** Automatic category/date axis behavior (`c:auto`). */
1880
+ auto?: boolean;
1881
+ /** Category-axis label alignment (`c:lblAlgn`). */
1882
+ labelAlignment?: 'ctr' | 'l' | 'r';
1883
+ /** Category/date label distance, from 0 through 1000 percent. */
1884
+ labelOffset?: number;
1885
+ /** Suppress multi-level category labels (`c:noMultiLvlLbl`). */
1886
+ noMultiLevelLabels?: boolean;
1887
+ }
1888
+
1889
+ /**
1890
+ * Chart types: chart categories, series data, style metadata, data tables,
1891
+ * trendlines, error bars, and the composite `PptxChartData`.
1892
+ *
1893
+ * @module pptx-types/chart
1894
+ */
1895
+
1896
+ /**
1897
+ * Supported chart type discriminators.
1898
+ *
1899
+ * @example
1900
+ * ```ts
1901
+ * const type: PptxChartType = "bar";
1902
+ * // => "bar" — one of: "bar" | "line" | "pie" | "doughnut" | "area" | "scatter" | …
1903
+ * ```
1904
+ */
1905
+ type PptxChartType = 'bar' | 'line' | 'pie' | 'ofPie' | 'doughnut' | 'area' | 'scatter' | 'bubble' | 'radar' | 'stock' | 'bar3D' | 'line3D' | 'pie3D' | 'area3D' | 'surface' | 'histogram' | 'waterfall' | 'funnel' | 'treemap' | 'sunburst' | 'boxWhisker' | 'regionMap' | 'combo' | 'unknown';
1906
+ /**
1907
+ * Supported trendline regression types.
1908
+ *
1909
+ * @example
1910
+ * ```ts
1911
+ * const type: PptxChartTrendlineType = "linear";
1912
+ * // => "linear" — one of: "linear" | "exponential" | "logarithmic" | "polynomial" | "power" | "movingAvg"
1913
+ * ```
1914
+ */
1915
+ type PptxChartTrendlineType = 'linear' | 'exponential' | 'logarithmic' | 'polynomial' | 'power' | 'movingAvg';
1916
+ /**
1917
+ * Configuration for a chart trendline (regression line).
1918
+ *
1919
+ * @example
1920
+ * ```ts
1921
+ * const trendline: PptxChartTrendline = {
1922
+ * trendlineType: "linear",
1923
+ * displayEq: true,
1924
+ * displayRSq: true,
1925
+ * color: "#FF0000",
1926
+ * };
1927
+ * // => satisfies PptxChartTrendline
1928
+ * ```
1929
+ */
1930
+ interface PptxChartTrendline {
1931
+ trendlineType: PptxChartTrendlineType;
1932
+ name?: string;
1933
+ order?: number;
1934
+ period?: number;
1935
+ forward?: number;
1936
+ backward?: number;
1937
+ intercept?: number;
1938
+ displayRSq?: boolean;
1939
+ displayEq?: boolean;
1940
+ color?: string;
1941
+ label?: PptxChartTrendlineLabel | null;
1942
+ }
1943
+ /** Typed, commonly edited properties of `c:trendlineLbl`. */
1944
+ interface PptxChartTrendlineLabel {
1945
+ layout?: PptxChartManualLayout;
1946
+ numberFormatCode?: string;
1947
+ sourceLinked?: boolean;
1948
+ }
1949
+ /** Error-bar direction axis. */
1950
+ type PptxChartErrBarDir = 'x' | 'y';
1951
+ /** Error-bar display type (both sides, negative only, or positive only). */
1952
+ type PptxChartErrBarType = 'both' | 'minus' | 'plus';
1953
+ /**
1954
+ * How the error-bar value is calculated.
1955
+ *
1956
+ * @example
1957
+ * ```ts
1958
+ * const valType: PptxChartErrValType = "percentage";
1959
+ * // => "percentage" — one of: "cust" | "fixedVal" | "percentage" | "stdDev" | "stdErr"
1960
+ * ```
1961
+ */
1962
+ type PptxChartErrValType = 'cust' | 'fixedVal' | 'percentage' | 'stdDev' | 'stdErr';
1963
+ /**
1964
+ * Error bars for a chart series.
1965
+ *
1966
+ * @example
1967
+ * ```ts
1968
+ * const bars: PptxChartErrBars = {
1969
+ * direction: "y",
1970
+ * barType: "both",
1971
+ * valType: "percentage",
1972
+ * val: 5,
1973
+ * };
1974
+ * // => satisfies PptxChartErrBars
1975
+ * ```
1976
+ */
1977
+ interface PptxChartErrBars {
1978
+ direction: PptxChartErrBarDir;
1979
+ barType: PptxChartErrBarType;
1980
+ valType: PptxChartErrValType;
1981
+ val?: number;
1982
+ customPlus?: number[];
1983
+ customMinus?: number[];
1984
+ noEndCap?: boolean;
1985
+ color?: string;
1986
+ }
1987
+ /**
1988
+ * Visibility flags for the chart data table (axes + legend keys).
1989
+ *
1990
+ * @example
1991
+ * ```ts
1992
+ * const dt: PptxChartDataTable = {
1993
+ * showHorzBorder: true,
1994
+ * showVertBorder: true,
1995
+ * showOutline: true,
1996
+ * showKeys: true,
1997
+ * };
1998
+ * // => satisfies PptxChartDataTable
1999
+ * ```
2000
+ */
2001
+ interface PptxChartDataTable {
2002
+ showHorzBorder?: boolean;
2003
+ showVertBorder?: boolean;
2004
+ showOutline?: boolean;
2005
+ showKeys?: boolean;
2006
+ }
2007
+ /**
2008
+ * Line appearance for chart helper lines (drop lines, hi-low lines).
2009
+ *
2010
+ * @example
2011
+ * ```ts
2012
+ * const style: PptxChartLineStyle = {
2013
+ * color: "#AAAAAA",
2014
+ * width: 1,
2015
+ * dashStyle: "dash",
2016
+ * };
2017
+ * // => satisfies PptxChartLineStyle
2018
+ * ```
2019
+ */
2020
+ interface PptxChartLineStyle {
2021
+ color?: string;
2022
+ width?: number;
2023
+ dashStyle?: string;
2024
+ }
2025
+ /** Marker symbol types for line/scatter chart data points. */
2026
+ type PptxChartMarkerSymbol = 'circle' | 'dash' | 'diamond' | 'dot' | 'none' | 'picture' | 'plus' | 'square' | 'star' | 'triangle' | 'x' | 'auto';
2027
+ /** Shape properties extracted from c:spPr for chart formatting. */
2028
+ interface PptxChartShapeProps {
2029
+ fillColor?: string;
2030
+ strokeColor?: string;
2031
+ strokeWidth?: number;
2032
+ /** Line dash style (a:prstDash/@val), e.g. 'solid', 'dash', 'dot', 'lgDash'. */
2033
+ strokeDashStyle?: string;
2034
+ }
2035
+ /** Up/down bar formatting on line and stock charts (`c:upDownBars`). */
2036
+ interface PptxChartUpDownBars {
2037
+ /** Gap between bars as a percentage, constrained to 0 through 500. */
2038
+ gapWidth?: number;
2039
+ upBars?: PptxChartShapeProps;
2040
+ downBars?: PptxChartShapeProps;
2041
+ }
2042
+ /** Marker appearance on a chart series or data point. */
2043
+ interface PptxChartMarker {
2044
+ symbol: PptxChartMarkerSymbol;
2045
+ size?: number;
2046
+ spPr?: PptxChartShapeProps;
2047
+ }
2048
+ /** Per-data-point formatting override (c:dPt). */
2049
+ interface PptxChartDataPoint {
2050
+ idx: number;
2051
+ spPr?: PptxChartShapeProps;
2052
+ explosion?: number;
2053
+ invertIfNegative?: boolean;
2054
+ marker?: PptxChartMarker;
2055
+ }
2056
+ /** Schema values accepted by `c:dLblPos`. */
2057
+ type PptxChartDataLabelPosition = 'bestFit' | 'b' | 'ctr' | 'inBase' | 'inEnd' | 'l' | 'outEnd' | 'r' | 't';
2058
+ /** Individual data label override (c:dLbl). */
2059
+ interface PptxChartDataLabel {
2060
+ idx: number;
2061
+ /** Suppress this data point's automatically generated label. */
2062
+ deleted?: boolean;
2063
+ showVal?: boolean;
2064
+ showCatName?: boolean;
2065
+ showSerName?: boolean;
2066
+ showPercent?: boolean;
2067
+ showLegendKey?: boolean;
2068
+ showBubbleSize?: boolean;
2069
+ position?: PptxChartDataLabelPosition;
2070
+ text?: string;
2071
+ separator?: string;
2072
+ showLeaderLines?: boolean;
2073
+ }
2074
+ /** Axis number format. */
2075
+ interface PptxChartAxisNumFmt {
2076
+ formatCode: string;
2077
+ sourceLinked?: boolean;
2078
+ }
2079
+ /** Typed contents of a value-axis display-unit label (`c:dispUnitsLbl`). */
2080
+ interface PptxChartDisplayUnitsLabel {
2081
+ /** Literal label text. Omit to preserve the source text subtree. */
2082
+ text?: string;
2083
+ /** Manual label placement. `null` removes only the manual layout. */
2084
+ layout?: PptxChartManualLayout | null;
2085
+ /** Label shape formatting. `null` removes `c:spPr`. */
2086
+ spPr?: PptxChartShapeProps | null;
2087
+ }
2088
+ /** Axis formatting for category, value, or date axes. */
2089
+ interface PptxChartAxisFormatting extends PptxChartAxisLabelFormatting {
2090
+ axisType: 'catAx' | 'valAx' | 'dateAx' | 'serAx';
2091
+ /** Axis position: "b" (bottom), "l" (left), "r" (right), "t" (top). */
2092
+ axPos?: 'b' | 'l' | 'r' | 't';
2093
+ /** Unique axis identifier (c:axId/@val) used to link series to axes. */
2094
+ axisId?: number;
2095
+ /** Cross-axis identifier — the axis this axis crosses. */
2096
+ crossAxisId?: number;
2097
+ numFmt?: PptxChartAxisNumFmt;
2098
+ titleText?: string;
2099
+ spPr?: PptxChartShapeProps;
2100
+ fontFamily?: string;
2101
+ fontSize?: number;
2102
+ fontBold?: boolean;
2103
+ fontColor?: string;
2104
+ /** Whether major gridlines are present (`c:majorGridlines`). */
2105
+ majorGridlines?: boolean;
2106
+ /** Whether minor gridlines are present (`c:minorGridlines`). */
2107
+ minorGridlines?: boolean;
2108
+ majorGridlinesSpPr?: PptxChartShapeProps;
2109
+ minorGridlinesSpPr?: PptxChartShapeProps;
2110
+ /** Minimum axis value override (c:min/@val). */
2111
+ min?: number;
2112
+ /** Maximum axis value override (c:max/@val). */
2113
+ max?: number;
2114
+ /** Whether the axis is deleted/hidden (c:delete/@val). */
2115
+ deleted?: boolean;
2116
+ /**
2117
+ * Display units for value axis (c:dispUnits/c:builtInUnit/@val).
2118
+ * When set to 'custom', the actual divisor is in {@link displayUnitsValue}.
2119
+ */
2120
+ displayUnits?: 'hundreds' | 'thousands' | 'tenThousands' | 'hundredThousands' | 'millions' | 'tenMillions' | 'hundredMillions' | 'billions' | 'trillions' | 'custom';
2121
+ /** Custom display unit divisor value (c:dispUnits/c:custUnit/@val). Only used when displayUnits is 'custom'. */
2122
+ displayUnitsValue?: number;
2123
+ /**
2124
+ * Display-unit label contents (`c:dispUnits/c:dispUnitsLbl`). A string is
2125
+ * retained as a compatibility shorthand for `{ text: string }`; `null`
2126
+ * explicitly removes the label.
2127
+ */
2128
+ displayUnitsLabel?: string | PptxChartDisplayUnitsLabel | null;
2129
+ /** Whether logarithmic scaling is enabled (presence of c:scaling/c:logBase). */
2130
+ logScale?: boolean;
2131
+ /** Logarithmic base value (c:scaling/c:logBase/@val), typically 10 or e. */
2132
+ logBase?: number;
2133
+ /** Major-unit interval between primary tick marks (c:majorUnit/@val). */
2134
+ majorUnit?: number;
2135
+ /** Minor-unit interval between secondary tick marks (c:minorUnit/@val). */
2136
+ minorUnit?: number;
2137
+ }
2138
+ /** 3D wall or floor element formatting. */
2139
+ interface PptxChart3DSurface {
2140
+ thickness?: number;
2141
+ spPr?: PptxChartShapeProps;
2142
+ }
2143
+ /**
2144
+ * A single data series within a chart.
2145
+ *
2146
+ * @example
2147
+ * ```ts
2148
+ * const series: PptxChartSeries = {
2149
+ * name: "Revenue",
2150
+ * values: [100, 120, 140],
2151
+ * color: "#4F81BD",
2152
+ * trendlines: [{ trendlineType: "linear" }],
2153
+ * };
2154
+ * // => satisfies PptxChartSeries
2155
+ * ```
2156
+ */
2157
+ interface PptxChartSeries {
2158
+ name: string;
2159
+ values: number[];
2160
+ color?: string;
2161
+ trendlines?: PptxChartTrendline[];
2162
+ errBars?: PptxChartErrBars[];
2163
+ dataPoints?: PptxChartDataPoint[];
2164
+ marker?: PptxChartMarker;
2165
+ dataLabels?: PptxChartDataLabel[];
2166
+ explosion?: number;
2167
+ /** Axis ID this series is plotted against (links to PptxChartAxisFormatting.axisId). */
2168
+ axisId?: number;
2169
+ /**
2170
+ * Per-series chart type, used for combo charts where individual series are
2171
+ * plotted with different chart types (e.g. a bar series and a line series in
2172
+ * the same chart). Maps to the OOXML chart-type container that holds the
2173
+ * series (`c:barChart`, `c:lineChart`, etc.). Omitted for single-type charts,
2174
+ * where the chart-level {@link PptxChartData.chartType} applies to every
2175
+ * series.
2176
+ */
2177
+ seriesChartType?: PptxChartType;
2178
+ }
2179
+ /**
2180
+ * Chart-level data-label options (`c:dLbls` directly under a chart-type
2181
+ * container, applying to every series). Mirrors the OOXML `c:show*` flags
2182
+ * and `c:dLblPos`.
2183
+ */
2184
+ interface PptxChartDataLabelOptions {
2185
+ /** Show the numeric value (`c:showVal`). */
2186
+ showValue?: boolean;
2187
+ /** Show the category name (`c:showCatName`). */
2188
+ showCategory?: boolean;
2189
+ /** Show the series name (`c:showSerName`). */
2190
+ showSeriesName?: boolean;
2191
+ /** Show the percentage (`c:showPercent`, pie/doughnut). */
2192
+ showPercent?: boolean;
2193
+ /** Show the legend key swatch (`c:showLegendKey`). */
2194
+ showLegendKey?: boolean;
2195
+ /** Show bubble size (`c:showBubbleSize`). */
2196
+ showBubbleSize?: boolean;
2197
+ /** Text placed between combined label components (`c:separator`). */
2198
+ separator?: string;
2199
+ /** Show leader lines where supported (`c:showLeaderLines`). */
2200
+ showLeaderLines?: boolean;
2201
+ /**
2202
+ * Label position (`c:dLblPos`). Valid values depend on the chart type
2203
+ * (`ctr`, `inEnd`, `inBase`, `outEnd`, `bestFit`, `l`, `r`, `t`, `b`).
2204
+ * Omit to let PowerPoint use the type default.
2205
+ */
2206
+ position?: PptxChartDataLabelPosition;
2207
+ }
2208
+ /** Typed text defaults for a single chart legend entry. */
2209
+ interface PptxChartLegendTextStyle {
2210
+ fontFamily?: string;
2211
+ fontSize?: number;
2212
+ bold?: boolean;
2213
+ italic?: boolean;
2214
+ color?: string;
2215
+ }
2216
+ /** Per-series legend entry override (`c:legendEntry`). */
2217
+ interface PptxChartLegendEntry {
2218
+ index: number;
2219
+ deleted?: boolean;
2220
+ textStyle?: PptxChartLegendTextStyle;
2221
+ }
2222
+ /**
2223
+ * Style / formatting metadata for a chart.
2224
+ *
2225
+ * @example
2226
+ * ```ts
2227
+ * const style: PptxChartStyle = {
2228
+ * styleId: 2,
2229
+ * hasLegend: true,
2230
+ * legendPosition: "b",
2231
+ * hasDataLabels: true,
2232
+ * };
2233
+ * // => satisfies PptxChartStyle
2234
+ * ```
2235
+ */
2236
+ interface PptxChartStyle {
2237
+ /** Chart style index from `c:style/@val`. */
2238
+ styleId?: number;
2239
+ /** Whether the chart has a visible legend. */
2240
+ hasLegend?: boolean;
2241
+ /** Legend position (t, b, l, r, tr). */
2242
+ legendPosition?: string;
2243
+ /** Per-series visibility and text-style overrides. */
2244
+ legendEntries?: PptxChartLegendEntry[];
2245
+ /** Whether the chart has a title. */
2246
+ hasTitle?: boolean;
2247
+ /** Whether gridlines are visible. */
2248
+ hasGridlines?: boolean;
2249
+ /** Whether data labels are shown. */
2250
+ hasDataLabels?: boolean;
2251
+ /** Chart-level data-label content/position options (when `hasDataLabels`). */
2252
+ dataLabels?: PptxChartDataLabelOptions;
2253
+ }
2254
+ /**
2255
+ * External data source reference for a chart (c:externalData).
2256
+ *
2257
+ * Charts can reference an external Excel workbook via a relationship ID
2258
+ * that points to an external file (TargetMode="External"). The
2259
+ * `autoUpdate` flag indicates whether the chart should refresh its
2260
+ * cached data from the external source on open.
2261
+ *
2262
+ * @example
2263
+ * ```ts
2264
+ * const ext: PptxExternalData = {
2265
+ * relId: "rId2",
2266
+ * targetPath: "file:///C:/Data/budget.xlsx",
2267
+ * autoUpdate: true,
2268
+ * };
2269
+ * // => satisfies PptxExternalData
2270
+ * ```
2271
+ */
2272
+ interface PptxExternalData {
2273
+ /** Relationship ID referencing the external data source in the chart .rels. */
2274
+ relId: string;
2275
+ /** Resolved external file path or URL from the relationship target. */
2276
+ targetPath?: string;
2277
+ /** Whether to auto-update data from the external source on open. */
2278
+ autoUpdate?: boolean;
2279
+ /** Raw binary data of the embedded xlsx workbook (from ppt/embeddings/). */
2280
+ embeddedWorkbookData?: Uint8Array;
2281
+ }
2282
+ /**
2283
+ * Options specific to the OOXML "Pie of Pie" / "Bar of Pie" chart
2284
+ * (`c:ofPieChart`, ECMA-376 §21.2.2.126 / CT_OfPieChart).
2285
+ *
2286
+ * The primary discriminator is {@link ofPieType}: `"pie"` produces a
2287
+ * pie-of-pie chart whose secondary plot is itself a pie, while `"bar"`
2288
+ * produces a bar-of-pie chart whose secondary plot is a horizontal bar.
2289
+ *
2290
+ * - {@link splitType} chooses the split rule.
2291
+ * - {@link splitPos} is the threshold value used by `pos`/`val`/`percent`.
2292
+ * - {@link secondPieSize} controls the secondary plot's size (5–200%).
2293
+ * - {@link serLines} toggles the leader lines connecting the plots.
2294
+ * - {@link gapWidth} is the gap between the plots in percent (0–500).
2295
+ */
2296
+ interface PptxChartOfPieOptions {
2297
+ ofPieType: 'pie' | 'bar';
2298
+ splitType?: 'auto' | 'cust' | 'percent' | 'pos' | 'val';
2299
+ splitPos?: number;
2300
+ custSplit?: number[];
2301
+ secondPieSize?: number;
2302
+ serLines?: boolean;
2303
+ gapWidth?: number;
2304
+ }
2305
+ /** Classic `c:bubbleChart` options from CT_BubbleChart. */
2306
+ interface PptxBubbleChartOptions {
2307
+ bubble3D?: boolean;
2308
+ /** Bubble diameter scale in percent, constrained to 0 through 300. */
2309
+ bubbleScale?: number;
2310
+ showNegativeBubbles?: boolean;
2311
+ sizeRepresents?: 'area' | 'w';
2312
+ }
2313
+ /**
2314
+ * 3D viewing parameters for a chart (`c:view3D`, ECMA-376 §21.2.2.228 /
2315
+ * CT_View3D).
2316
+ *
2317
+ * All fields are optional and round-trip verbatim.
2318
+ *
2319
+ * - {@link rotX} — X-axis rotation in degrees (-90…90).
2320
+ * - {@link rotY} — Y-axis rotation in degrees (0…360).
2321
+ * - {@link depthPercent} — chart depth as a percentage of base width.
2322
+ * - {@link rAngAx} — `true` if axes meet at right angles.
2323
+ * - {@link perspective} — perspective angle in degrees (0…240).
2324
+ * - {@link hPercent} — height as a percentage of chart width.
2325
+ */
2326
+ interface PptxChartView3D {
2327
+ rotX?: number;
2328
+ rotY?: number;
2329
+ depthPercent?: number;
2330
+ rAngAx?: boolean;
2331
+ perspective?: number;
2332
+ hPercent?: number;
2333
+ }
2334
+ /**
2335
+ * Chart "chrome" flags from `c:chart` that round-trip cleanly even when
2336
+ * rendering ignores them.
2337
+ *
2338
+ * - {@link autoTitleDeleted} — `c:autoTitleDeleted/@val`. Suppresses the
2339
+ * auto-generated title for single-series charts.
2340
+ * - {@link dispBlanksAs} — `c:dispBlanksAs/@val`. How blank cells
2341
+ * render: `"gap"`, `"zero"`, or `"span"`.
2342
+ * - {@link showDLblsOverMax} — `c:showDLblsOverMax/@val`. Keeps data
2343
+ * labels visible for points exceeding the value-axis maximum.
2344
+ *
2345
+ * `c:plotVisOnly` lives on {@link PptxChartData.plotVisibleOnly} and is
2346
+ * intentionally not duplicated here.
2347
+ */
2348
+ interface PptxChartChrome {
2349
+ autoTitleDeleted?: boolean;
2350
+ dispBlanksAs?: 'gap' | 'zero' | 'span';
2351
+ showDLblsOverMax?: boolean;
2352
+ }
2353
+ /** Manual chart placement from `c:layout/c:manualLayout` (CT_ManualLayout). */
2354
+ interface PptxChartManualLayout {
2355
+ layoutTarget?: 'inner' | 'outer';
2356
+ xMode?: 'edge' | 'factor';
2357
+ yMode?: 'edge' | 'factor';
2358
+ widthMode?: 'edge' | 'factor';
2359
+ heightMode?: 'edge' | 'factor';
2360
+ x?: number;
2361
+ y?: number;
2362
+ width?: number;
2363
+ height?: number;
2364
+ }
2365
+ /**
2366
+ * Typed manual layouts for chart regions that accept `c:layout`.
2367
+ * A `null` region removes its manual layout without removing extensions.
2368
+ */
2369
+ interface PptxChartLayouts {
2370
+ title?: PptxChartManualLayout | null;
2371
+ plotArea?: PptxChartManualLayout | null;
2372
+ legend?: PptxChartManualLayout | null;
2373
+ }
2374
+ /** Parsed data extracted from an embedded xlsx workbook. */
2375
+ interface PptxEmbeddedWorkbookData {
2376
+ /** Category labels from the first column/row. */
2377
+ categories: string[];
2378
+ /** Data series extracted from worksheet cells. */
2379
+ series: Array<{
2380
+ name: string;
2381
+ values: number[];
2382
+ }>;
2383
+ }
2384
+ /**
2385
+ * Complete parsed chart data for a {@link ChartPptxElement}.
2386
+ *
2387
+ * @example
2388
+ * ```ts
2389
+ * const chart: PptxChartData = {
2390
+ * title: "Q4 Sales",
2391
+ * chartType: "bar",
2392
+ * categories: ["Jan", "Feb", "Mar"],
2393
+ * series: [
2394
+ * { name: "Revenue", values: [100, 120, 140] },
2395
+ * ],
2396
+ * grouping: "clustered",
2397
+ * style: { hasLegend: true, legendPosition: "b" },
2398
+ * };
2399
+ * // => satisfies PptxChartData
2400
+ * ```
2401
+ */
2402
+ interface PptxChartData {
2403
+ title?: string;
2404
+ chartType: PptxChartType;
2405
+ categories: string[];
2406
+ series: PptxChartSeries[];
2407
+ /** Chart style/formatting metadata. */
2408
+ style?: PptxChartStyle;
2409
+ /** Grouping mode for bar/area/line charts: 'clustered' | 'stacked' | 'percentStacked' */
2410
+ grouping?: 'clustered' | 'stacked' | 'percentStacked';
2411
+ /** Internal: path to the chart XML part in the PPTX archive (for round-trip save). */
2412
+ chartPartPath?: string;
2413
+ /** Internal: relationship ID linking the graphic frame to the chart part. */
2414
+ chartRelationshipId?: string;
2415
+ /** `null` explicitly removes an existing ChartML data table. */
2416
+ dataTable?: PptxChartDataTable | null;
2417
+ dropLines?: PptxChartLineStyle;
2418
+ hiLowLines?: PptxChartLineStyle;
2419
+ /** `null` explicitly removes an existing up/down-bars container. */
2420
+ upDownBars?: PptxChartUpDownBars | null;
2421
+ axes?: PptxChartAxisFormatting[];
2422
+ floor?: PptxChart3DSurface;
2423
+ sideWall?: PptxChart3DSurface;
2424
+ backWall?: PptxChart3DSurface;
2425
+ /** External data source reference (c:externalData) linking to an external workbook. */
2426
+ externalData?: PptxExternalData;
2427
+ /**
2428
+ * Parsed data from the embedded xlsx workbook (from ppt/embeddings/).
2429
+ *
2430
+ * When a chart references an embedded Excel workbook via `c:externalData`,
2431
+ * the xlsx is parsed to extract categories and series. This data serves as
2432
+ * a fallback when the chart XML's cached series data is empty or incomplete.
2433
+ */
2434
+ embeddedWorkbookData?: PptxEmbeddedWorkbookData;
2435
+ /**
2436
+ * Pivot table data source reference (c:pivotSource).
2437
+ *
2438
+ * When present, the chart's data originates from a PivotTable.
2439
+ * The chart still renders using its cached series data; this field
2440
+ * is metadata about the data origin, preserved for round-trip fidelity.
2441
+ */
2442
+ pivotSource?: {
2443
+ /** Pivot table reference name, e.g. "[workbook.xlsx]Sheet1!PivotTable1". */
2444
+ name: string;
2445
+ /** Format identifier from c:fmtId/@val. */
2446
+ formatId?: number;
2447
+ };
2448
+ /**
2449
+ * Whether only visible cells are plotted (c:plotVisOnly).
2450
+ * When `true` (the default), hidden cells are excluded from the chart.
2451
+ * When `false`, hidden data IS plotted.
2452
+ */
2453
+ plotVisibleOnly?: boolean;
2454
+ /**
2455
+ * Color palette extracted from the chart's Office 2013+ color style part
2456
+ * (`chartColorStyle*.xml`). When present, this palette takes priority over
2457
+ * the `c:style/@val`-derived palette in `getChartStylePalette`.
2458
+ *
2459
+ * Each entry is a resolved hex colour string (e.g. `"#4472C4"`).
2460
+ */
2461
+ colorPalette?: string[];
2462
+ /**
2463
+ * Color cycling method from the chart color style part's `meth` attribute.
2464
+ *
2465
+ * - `"cycle"` — repeat the palette colours in order (default)
2466
+ * - `"withinLinear"` — gradient within each series
2467
+ * - `"acrossLinear"` — gradient across series
2468
+ */
2469
+ colorMethod?: 'cycle' | 'withinLinear' | 'acrossLinear';
2470
+ /**
2471
+ * Pie-of-pie / Bar-of-pie options (`c:ofPieChart`, CT_OfPieChart).
2472
+ *
2473
+ * Present only when {@link chartType} is `"ofPie"`. Carries the split
2474
+ * configuration, secondary plot size, and serLines flag so that an
2475
+ * `ofPieChart` element can be re-emitted on save with full fidelity.
2476
+ */
2477
+ ofPieOptions?: PptxChartOfPieOptions;
2478
+ /** Classic bubble-chart display options (`c:bubbleChart`). */
2479
+ bubbleOptions?: PptxBubbleChartOptions;
2480
+ /**
2481
+ * 3D viewing parameters (`c:view3D`, CT_View3D).
2482
+ *
2483
+ * Parsed from and emitted to `c:chart/c:view3D`. Absent when the
2484
+ * chart XML has no `c:view3D` element.
2485
+ */
2486
+ view3D?: PptxChartView3D;
2487
+ /**
2488
+ * Top-level chart chrome flags (`c:autoTitleDeleted`,
2489
+ * `c:dispBlanksAs`, `c:showDLblsOverMax`).
2490
+ *
2491
+ * Each flag is omitted from the emitted XML when absent on the
2492
+ * source data, so absence does not produce empty `<c:…/>` placeholders.
2493
+ */
2494
+ chartChrome?: PptxChartChrome;
2495
+ /** Editable manual placement for the title, plot area, and legend. */
2496
+ layouts?: PptxChartLayouts;
2497
+ /**
2498
+ * Raw `c:userShapes` XML subtree (a drawing tree) preserved verbatim.
2499
+ *
2500
+ * `c:userShapes` references a separate drawing part containing
2501
+ * shapes drawn over the chart. The reference is preserved as-is so
2502
+ * that round-trip save re-emits the original element without
2503
+ * attempting to parse the nested drawing tree.
2504
+ */
2505
+ userShapesXml?: unknown;
2506
+ /**
2507
+ * Raw `c:pivotFmts` XML subtree preserved verbatim.
2508
+ *
2509
+ * `c:pivotFmts` carries a list of `c:pivotFmt` formatting overrides
2510
+ * for charts whose data originates from a PivotTable. Preserved
2511
+ * verbatim for round-trip fidelity.
2512
+ */
2513
+ pivotFmtsXml?: unknown;
2514
+ /**
2515
+ * Color-map override (`c:clrMapOvr`) carrying 12 attributes that
2516
+ * remap theme colour roles for this chart only. Preserved as a flat
2517
+ * `attribute → value` map for round-trip fidelity.
2518
+ */
2519
+ clrMapOvr?: Record<string, string>;
2520
+ }
2521
+
2522
+ type EffectDagBlendMode = 'darken' | 'lighten' | 'mult' | 'over' | 'screen';
2523
+ type EffectDagContainerType = 'sib' | 'tree';
2524
+ type EffectDagNode = EffectDagContainer | EffectDagBlend | EffectDagXfrm | EffectDagRelOff | EffectDagBlur | EffectDagPresetShadow | EffectDagRawLeaf;
2525
+ interface EffectDagContainer {
2526
+ kind: 'cont';
2527
+ type: EffectDagContainerType;
2528
+ name?: string;
2529
+ children: EffectDagNode[];
2530
+ }
2531
+ interface EffectDagBlend {
2532
+ kind: 'blend';
2533
+ mode: EffectDagBlendMode;
2534
+ container: EffectDagContainer;
2535
+ }
2536
+ interface EffectDagXfrm {
2537
+ kind: 'xfrmEffect';
2538
+ sx?: number;
2539
+ sy?: number;
2540
+ kx?: number;
2541
+ ky?: number;
2542
+ tx?: number;
2543
+ ty?: number;
2544
+ }
2545
+ interface EffectDagRelOff {
2546
+ kind: 'relOff';
2547
+ tx?: number;
2548
+ ty?: number;
2549
+ }
2550
+ /** Typed CT_BlurEffect with its original payload retained for lossless edits. */
2551
+ interface EffectDagBlur {
2552
+ kind: 'blur';
2553
+ radiusEmu?: number;
2554
+ grow?: boolean;
2555
+ xml: XmlObject;
2556
+ }
2557
+ /** Typed CT_PresetShadowEffect with colour and extension XML retained verbatim. */
2558
+ interface EffectDagPresetShadow {
2559
+ kind: 'prstShdw';
2560
+ preset?: `shdw${number}`;
2561
+ distanceEmu?: number;
2562
+ direction?: number;
2563
+ xml: XmlObject;
2564
+ }
2565
+ interface EffectDagRawLeaf {
2566
+ kind: 'raw';
2567
+ tag: string;
2568
+ xml: Record<string, unknown>;
2569
+ }
2570
+
2571
+ /**
2572
+ * Image recolour/adjustment properties parsed from blip extensions.
2573
+ *
2574
+ * These effects are stored in the OpenXML `<a:blip>` extension list
2575
+ * and applied non-destructively to the original image data.
2576
+ *
2577
+ * @example
2578
+ * ```ts
2579
+ * const fx: PptxImageEffects = {
2580
+ * brightness: 20,
2581
+ * contrast: -10,
2582
+ * grayscale: true,
2583
+ * };
2584
+ * // => { brightness: 20, contrast: -10, grayscale: true } satisfies PptxImageEffects
2585
+ * ```
2586
+ */
2587
+ interface PptxImageEffects {
2588
+ /** Brightness adjustment (-100 to 100). */
2589
+ brightness?: number;
2590
+ /** Contrast adjustment (-100 to 100). */
2591
+ contrast?: number;
2592
+ /** Duotone colour pair. */
2593
+ duotone?: {
2594
+ color1: string;
2595
+ color2: string;
2596
+ };
2597
+ /** Grayscale flag. */
2598
+ grayscale?: boolean;
2599
+ /** Saturation adjustment (-100 to 100). */
2600
+ saturation?: number;
2601
+ /** Color wash overlay. */
2602
+ colorWash?: {
2603
+ color: string;
2604
+ opacity: number;
2605
+ };
2606
+ /** Artistic effect name (blur, pencilGrayscale, paintStrokes, etc.). */
2607
+ artisticEffect?: string;
2608
+ /** Artistic effect radius/amount. */
2609
+ artisticRadius?: number;
2610
+ /** Alpha modulation fixed — overall opacity (0-100, where 100 = fully opaque). */
2611
+ alphaModFix?: number;
2612
+ /** Bi-level threshold — converts to 1-bit black/white (0-100). */
2613
+ biLevel?: number;
2614
+ /** Colour change — swap one colour range for another (used for transparency keying). */
2615
+ clrChange?: {
2616
+ clrFrom: string;
2617
+ clrTo: string;
2618
+ /** Whether the target colour is fully transparent (alpha = 0). */
2619
+ clrToTransparent?: boolean;
2620
+ };
2621
+ /**
2622
+ * Alpha inverse effect (`a:alphaInv`). Inverts the alpha channel; an optional
2623
+ * colour child shifts the inversion baseline.
2624
+ */
2625
+ alphaInv?: {
2626
+ /** Optional baseline colour (hex). */
2627
+ color?: string;
2628
+ };
2629
+ /** Alpha ceiling (`a:alphaCeiling`) — clamps any non-zero alpha to fully opaque. Boolean flag. */
2630
+ alphaCeiling?: boolean;
2631
+ /** Alpha floor (`a:alphaFloor`) — clamps any non-fully-opaque alpha to fully transparent. Boolean flag. */
2632
+ alphaFloor?: boolean;
2633
+ /**
2634
+ * Alpha modulate (`a:alphaMod`). The schema requires a single `cont` (effect
2635
+ * container) child; we preserve the inner XML opaquely for round-trip.
2636
+ */
2637
+ alphaMod?: {
2638
+ /** Raw opaque XML for the `a:cont` child to preserve on save. */
2639
+ contRawXml?: Record<string, unknown>;
2640
+ };
2641
+ /** Alpha replace (`a:alphaRepl`) — replaces alpha with the given fixed-percent value (0..100). */
2642
+ alphaRepl?: number;
2643
+ /** Alpha bi-level (`a:alphaBiLevel`) — threshold (0..100) above which alpha becomes fully opaque. */
2644
+ alphaBiLevel?: number;
2645
+ /**
2646
+ * Colour replace (`a:clrRepl`) — replaces all colour information in an image
2647
+ * with the given solid colour. Stores the raw colour child to preserve scheme
2648
+ * colour references and modifiers.
2649
+ */
2650
+ clrRepl?: {
2651
+ /** Resolved hex colour. */
2652
+ color: string;
2653
+ /** Raw opaque colour XML for round-trip. */
2654
+ rawXml?: Record<string, unknown>;
2655
+ };
2656
+ /** Luminance modulation (`a:lum`) — bright/contrast as fixed percentages (0..100). */
2657
+ lum?: {
2658
+ bright?: number;
2659
+ contrast?: number;
2660
+ };
2661
+ /** HSL modulation (`a:hsl`) — hue (0..360 degrees), saturation/luminance (-100..100). */
2662
+ hsl?: {
2663
+ hue?: number;
2664
+ sat?: number;
2665
+ lum?: number;
2666
+ };
2667
+ /** Image-effect tint (`a:tint` inside blip) — hue (0..360), amount (-100..100). */
2668
+ tint?: {
2669
+ hue?: number;
2670
+ amt?: number;
2671
+ };
2672
+ /**
2673
+ * Fill overlay (`a:fillOverlay`) — overlays a fill on top of the blip.
2674
+ * Stores blend mode and the raw inner fill XML for round-trip.
2675
+ */
2676
+ fillOverlay?: {
2677
+ blend: 'over' | 'mult' | 'screen' | 'darken' | 'lighten';
2678
+ /** Raw opaque fill XML preserved for round-trip. */
2679
+ fillRawXml?: Record<string, unknown>;
2680
+ };
2681
+ /** Blur (`a:blur`) — radius in EMU and grow flag. */
2682
+ blur?: {
2683
+ rad?: number;
2684
+ grow?: boolean;
2685
+ };
2686
+ }
2687
+ /**
2688
+ * Shape names used for crop-to-shape (CSS `clip-path` equivalent).
2689
+ *
2690
+ * @example
2691
+ * ```ts
2692
+ * const shape: PptxCropShape = "ellipse";
2693
+ * // => "ellipse" — one of: none | ellipse | roundedRect | triangle | diamond | pentagon | hexagon | star
2694
+ * ```
2695
+ */
2696
+ type PptxCropShape = 'none' | 'ellipse' | 'roundedRect' | 'triangle' | 'diamond' | 'pentagon' | 'hexagon' | 'star';
2697
+ /**
2698
+ * Image content mixin — present on image and picture elements.
2699
+ *
2700
+ * Contains the decoded image data (base64 data URL or archive path),
2701
+ * alt text, crop insets, tiling settings, and image effects.
2702
+ *
2703
+ * @example
2704
+ * ```ts
2705
+ * const props: PptxImageProperties = {
2706
+ * imagePath: "ppt/media/image1.png",
2707
+ * altText: "Company logo",
2708
+ * cropLeft: 0.05,
2709
+ * cropRight: 0.05,
2710
+ * };
2711
+ * // => { imagePath: "ppt/media/image1.png", altText: "Company logo", cropLeft: 0.05, cropRight: 0.05 }
2712
+ * ```
2713
+ */
2714
+ interface PptxImageProperties {
2715
+ /** Base64 data-URL for the decoded image. */
2716
+ imageData?: string;
2717
+ /** Path within the PPTX ZIP archive. */
2718
+ imagePath?: string;
2719
+ /** Base64 data-URL for an SVG variant (from blip extension asvg:svgBlip). Preferred over raster when available. */
2720
+ svgData?: string;
2721
+ /** Path to the SVG file within the PPTX ZIP archive. */
2722
+ svgPath?: string;
2723
+ /** Alt text / description from `p:cNvPr/@descr`. */
2724
+ altText?: string;
2725
+ /** Crop from left edge as 0..1 fraction (OOXML `a:srcRect/@l`). */
2726
+ cropLeft?: number;
2727
+ /** Crop from top edge as 0..1 fraction (OOXML `a:srcRect/@t`). */
2728
+ cropTop?: number;
2729
+ /** Crop from right edge as 0..1 fraction (OOXML `a:srcRect/@r`). */
2730
+ cropRight?: number;
2731
+ /** Crop from bottom edge as 0..1 fraction (OOXML `a:srcRect/@b`). */
2732
+ cropBottom?: number;
2733
+ /** Image tiling offset X in px. */
2734
+ tileOffsetX?: number;
2735
+ /** Image tiling offset Y in px. */
2736
+ tileOffsetY?: number;
2737
+ /** Image tiling scale X as percentage (100 = 100%). */
2738
+ tileScaleX?: number;
2739
+ /** Image tiling scale Y as percentage (100 = 100%). */
2740
+ tileScaleY?: number;
2741
+ /** Image tiling flip mode. */
2742
+ tileFlip?: 'none' | 'x' | 'y' | 'xy';
2743
+ /** Image tiling alignment. */
2744
+ tileAlignment?: string;
2745
+ /** Image recolour/artistic effect properties. */
2746
+ imageEffects?: PptxImageEffects;
2747
+ /** Crop-to-shape — CSS clip-path shape name. */
2748
+ cropShape?: PptxCropShape;
2749
+ }
2750
+ declare module "./index" {
2751
+ interface TextStyle {
2752
+ /**
2753
+ * Raw `a:effectDag` XML node from `a:rPr`, preserved verbatim for
2754
+ * round-trip serialisation. Mirrors the shape-level
2755
+ * {@link import('./shape-style').ShapeStyle.effectDagXml} field.
2756
+ */
2757
+ textEffectDagXml?: XmlObject;
2758
+ /**
2759
+ * Typed effect graph parsed from `textEffectDagXml`. The four structural
2760
+ * container nodes (`a:cont`, `a:blend`, `a:xfrmEffect`, `a:relOff`) are
2761
+ * fully typed; any other leaf effect is captured as
2762
+ * {@link EffectDagRawLeaf} so we never have to recurse into the full
2763
+ * effect taxonomy.
2764
+ */
2765
+ textEffectDagTree?: EffectDagContainer;
2766
+ }
2767
+ }
2768
+ declare module "./index" {
2769
+ interface ShapeStyle {
2770
+ /**
2771
+ * Typed effect graph parsed from {@link ShapeStyle.effectDagXml}. The four
2772
+ * structural container nodes (`a:cont`, `a:blend`, `a:xfrmEffect`,
2773
+ * `a:relOff`) are fully typed; any other leaf effect (e.g. `a:outerShdw`,
2774
+ * `a:glow`, `a:alphaInv`) is captured as {@link EffectDagRawLeaf} so we
2775
+ * never have to recurse into the full effect taxonomy.
2776
+ */
2777
+ effectDagTree?: EffectDagContainer;
2778
+ }
2779
+ }
2780
+
2781
+ /**
2782
+ * Media types: audio/video discriminator, bookmarks, runtime metadata,
2783
+ * and caption/subtitle tracks.
2784
+ *
2785
+ * @module pptx-types/media
2786
+ */
2787
+ /**
2788
+ * Discriminator for embedded media element types.
2789
+ *
2790
+ * @example
2791
+ * ```ts
2792
+ * const kind: PptxMediaType = "video";
2793
+ * // => "video" — one of: "video" | "audio" | "unknown"
2794
+ * ```
2795
+ */
2796
+ type PptxMediaType = 'video' | 'audio' | 'unknown';
2797
+ type PptxMediaReferenceKind = 'audioCd' | 'wavAudioFile' | 'audioFile' | 'videoFile' | 'quickTimeFile';
2798
+ interface PptxAudioCdPosition {
2799
+ track: number;
2800
+ time?: number;
2801
+ }
2802
+ /**
2803
+ * A named bookmark within a media clip timeline.
2804
+ *
2805
+ * @example
2806
+ * ```ts
2807
+ * const bm: MediaBookmark = {
2808
+ * id: "bm1",
2809
+ * time: 12.5,
2810
+ * label: "Intro ends",
2811
+ * };
2812
+ * // => satisfies MediaBookmark
2813
+ * ```
2814
+ */
2815
+ interface MediaBookmark {
2816
+ id: string;
2817
+ /** Position in seconds from the start of the clip. */
2818
+ time: number;
2819
+ /** User-visible label for this bookmark. */
2820
+ label: string;
2821
+ }
2822
+ /**
2823
+ * Runtime-extracted metadata about a media clip (populated from HTMLMediaElement).
2824
+ *
2825
+ * @example
2826
+ * ```ts
2827
+ * const meta: MediaMetadata = {
2828
+ * duration: 120.5,
2829
+ * videoWidth: 1920,
2830
+ * videoHeight: 1080,
2831
+ * codecInfo: "video/mp4; codecs=\"avc1.640028\"",
2832
+ * };
2833
+ * // => satisfies MediaMetadata
2834
+ * ```
2835
+ */
2836
+ interface MediaMetadata {
2837
+ /** Duration in seconds. */
2838
+ duration?: number;
2839
+ /** Video width in pixels (video only). */
2840
+ videoWidth?: number;
2841
+ /** Video height in pixels (video only). */
2842
+ videoHeight?: number;
2843
+ /** MIME type / codec string reported by the browser. */
2844
+ codecInfo?: string;
2845
+ }
2846
+ /**
2847
+ * A closed-caption / subtitle track associated with a media element.
2848
+ *
2849
+ * @example
2850
+ * ```ts
2851
+ * const track: MediaCaptionTrack = {
2852
+ * id: "t1",
2853
+ * label: "English",
2854
+ * language: "en",
2855
+ * kind: "subtitles",
2856
+ * isDefault: true,
2857
+ * };
2858
+ * // => satisfies MediaCaptionTrack
2859
+ * ```
2860
+ */
2861
+ interface MediaCaptionTrack {
2862
+ /** Unique ID for this track. */
2863
+ id: string;
2864
+ /** Human-readable label (e.g. "English", "Spanish"). */
2865
+ label: string;
2866
+ /** BCP-47 language code (e.g. "en", "es"). */
2867
+ language: string;
2868
+ /** Track kind: subtitles, captions, or descriptions. */
2869
+ kind: 'subtitles' | 'captions' | 'descriptions';
2870
+ /** Data URL or path to the VTT/SRT content within the PPTX archive. */
2871
+ src?: string;
2872
+ /** Inline VTT content (for embedded captions). */
2873
+ content?: string;
2874
+ /** Whether this track is the default/active one. */
2875
+ isDefault?: boolean;
2876
+ }
2877
+
2878
+ /** Typed, editable metadata from a DiagramML layout-definition part. */
2879
+ interface PptxSmartArtLocalizedText {
2880
+ value: string;
2881
+ language?: string;
2882
+ }
2883
+ interface PptxSmartArtLayoutCategory {
2884
+ type: string;
2885
+ priority: number;
2886
+ }
2887
+ /** Identity and ordering metadata from DiagramML CT_LayoutNode. */
2888
+ interface PptxSmartArtLayoutNode {
2889
+ name?: string;
2890
+ styleLabel?: string;
2891
+ childOrder?: 'b' | 't';
2892
+ moveWith?: string;
2893
+ children?: PptxSmartArtLayoutNode[];
2894
+ }
2895
+ /** Metadata and root node from DiagramML CT_DiagramDefinition. */
2896
+ interface PptxSmartArtLayoutDefinition {
2897
+ uniqueId?: string;
2898
+ minimumVersion?: string;
2899
+ defaultStyle?: string;
2900
+ titles?: PptxSmartArtLocalizedText[];
2901
+ descriptions?: PptxSmartArtLocalizedText[];
2902
+ categories?: PptxSmartArtLayoutCategory[];
2903
+ rootNode: PptxSmartArtLayoutNode;
2904
+ }
2905
+
2906
+ /**
2907
+ * SmartArt node types: per-run text, per-node visual override, and the
2908
+ * data-model node itself. Split out of `smart-art.ts` to keep each type file
2909
+ * within the project's per-file line budget. Re-exported from `smart-art.ts`
2910
+ * (and thus the `types` barrel) for backward compatibility, so existing
2911
+ * imports of these symbols continue to work unchanged.
2912
+ *
2913
+ * @module pptx-types/smart-art-node
2914
+ */
2915
+ /**
2916
+ * A single run of text inside a SmartArt node, capturing the run text and the
2917
+ * raw `a:rPr` run-properties object verbatim so per-run formatting (bold,
2918
+ * colour, size, etc.) survives a load -> edit -> save round-trip instead of
2919
+ * collapsing to a single unstyled run.
2920
+ *
2921
+ * @example
2922
+ * ```ts
2923
+ * const run: PptxSmartArtTextRun = {
2924
+ * text: "Bold",
2925
+ * rPr: { "@_b": "1", "@_lang": "en-US" },
2926
+ * };
2927
+ * // => satisfies PptxSmartArtTextRun
2928
+ * ```
2929
+ */
2930
+ interface PptxSmartArtTextRun {
2931
+ /** Run text content. */
2932
+ text: string;
2933
+ /**
2934
+ * Raw parsed `a:rPr` run-properties object, preserved verbatim for
2935
+ * round-trip. Untyped XML, hence the loose record shape.
2936
+ */
2937
+ rPr?: Record<string, unknown>;
2938
+ }
2939
+ /**
2940
+ * Per-node visual override for a SmartArt node.
2941
+ *
2942
+ * Captures the individual fill / line / font colour and the bold / italic
2943
+ * emphasis a user has set on one specific node, independent of the diagram's
2944
+ * colour scheme and quick style. All colours are hex strings (e.g. "#FF0000").
2945
+ * Every field is optional: only the overridden aspects are carried, so an
2946
+ * empty object means "no per-node override".
2947
+ *
2948
+ * The parser reads these from the data point's `spPr` solid fill / line colour
2949
+ * and the first run's `rPr` (b / i / solidFill) when present, and the save path
2950
+ * writes them back so the override survives a load -> edit -> save round-trip.
2951
+ *
2952
+ * @example
2953
+ * ```ts
2954
+ * const style: PptxSmartArtNodeStyle = {
2955
+ * fillColor: "#FF0000",
2956
+ * fontColor: "#FFFFFF",
2957
+ * bold: true,
2958
+ * };
2959
+ * // => satisfies PptxSmartArtNodeStyle
2960
+ * ```
2961
+ */
2962
+ interface PptxSmartArtNodeStyle {
2963
+ /** Solid fill colour override (hex, e.g. "#4F81BD"). */
2964
+ fillColor?: string;
2965
+ /** Outline / line colour override (hex). */
2966
+ lineColor?: string;
2967
+ /** Text (font) colour override (hex). */
2968
+ fontColor?: string;
2969
+ /** Bold emphasis override for the node's runs. */
2970
+ bold?: boolean;
2971
+ /** Italic emphasis override for the node's runs. */
2972
+ italic?: boolean;
2973
+ }
2974
+ /**
2975
+ * A single node in the SmartArt data model.
2976
+ *
2977
+ * @example
2978
+ * ```ts
2979
+ * const node: PptxSmartArtNode = {
2980
+ * id: "1",
2981
+ * text: "CEO",
2982
+ * children: [
2983
+ * { id: "2", text: "VP Marketing", parentId: "1" },
2984
+ * { id: "3", text: "VP Engineering", parentId: "1" },
2985
+ * ],
2986
+ * };
2987
+ * // => satisfies PptxSmartArtNode
2988
+ * ```
2989
+ */
2990
+ interface PptxSmartArtNode {
2991
+ id: string;
2992
+ text: string;
2993
+ /** CT_Pt connection identifier, when the point references a connection. */
2994
+ connectionId?: string | null;
2995
+ parentId?: string;
2996
+ children?: PptxSmartArtNode[];
2997
+ /** Node type from `@_type` attribute (e.g. "doc", "node", "asst", "pres"). */
2998
+ nodeType?: string;
2999
+ /**
3000
+ * Per-run text + run-properties for the node's first paragraph, captured at
3001
+ * parse time. When the joined run text still equals {@link text} (the node
3002
+ * was not edited, or was edited only in ways that preserve the run split),
3003
+ * the save path rebuilds the paragraph from these runs so per-run rich text
3004
+ * is not flattened. When {@link text} diverges, the runs are ignored.
3005
+ */
3006
+ runs?: PptxSmartArtTextRun[];
3007
+ /**
3008
+ * Optional per-node visual override (fill / line / font colour, bold /
3009
+ * italic). Read at parse time from the point's `spPr` / first-run `rPr`, set
3010
+ * by the editing op, honoured by the render path, and written back on save so
3011
+ * it round-trips.
3012
+ */
3013
+ style?: PptxSmartArtNodeStyle;
3014
+ }
3015
+
3016
+ /** Editable metadata shared by DiagramML quick-style and color definitions. */
3017
+ interface PptxSmartArtDefinitionText {
3018
+ value: string;
3019
+ language?: string;
3020
+ }
3021
+ interface PptxSmartArtDefinitionCategory {
3022
+ type: string;
3023
+ priority: number;
3024
+ }
3025
+ type PptxSmartArtColorApplicationMethod = 'span' | 'cycle' | 'repeat';
3026
+ type PptxSmartArtHueDirection = 'cw' | 'ccw';
3027
+ /** CT_Colors application metadata. Color-choice children remain preserved XML. */
3028
+ interface PptxSmartArtColorListMetadata {
3029
+ method?: PptxSmartArtColorApplicationMethod;
3030
+ hueDirection?: PptxSmartArtHueDirection;
3031
+ }
3032
+ /** CT_StyleLabel metadata from a quick-style definition. */
3033
+ interface PptxSmartArtQuickStyleLabel {
3034
+ name: string;
3035
+ }
3036
+ /** CT_CTStyleLabel metadata from a color-transform definition. */
3037
+ interface PptxSmartArtColorStyleLabel {
3038
+ name: string;
3039
+ fill?: PptxSmartArtColorListMetadata;
3040
+ line?: PptxSmartArtColorListMetadata;
3041
+ effect?: PptxSmartArtColorListMetadata;
3042
+ textLine?: PptxSmartArtColorListMetadata;
3043
+ textFill?: PptxSmartArtColorListMetadata;
3044
+ textEffect?: PptxSmartArtColorListMetadata;
3045
+ }
3046
+ interface PptxSmartArtDefinitionMetadata {
3047
+ uniqueId?: string;
3048
+ minimumVersion?: string;
3049
+ titles?: PptxSmartArtDefinitionText[];
3050
+ descriptions?: PptxSmartArtDefinitionText[];
3051
+ categories?: PptxSmartArtDefinitionCategory[];
3052
+ }
3053
+ /** Typed CT_ColorTransform metadata and the resolved legacy color palette. */
3054
+ interface PptxSmartArtColorTransform extends PptxSmartArtDefinitionMetadata {
3055
+ /** Legacy resolved display name. */
3056
+ name?: string;
3057
+ /** Ordered resolved fill colors for rendering. */
3058
+ fillColors: string[];
3059
+ /** Ordered resolved line colors for rendering. */
3060
+ lineColors: string[];
3061
+ /** Ordered CT_CTStyleLabel metadata. */
3062
+ labels?: PptxSmartArtColorStyleLabel[];
3063
+ }
3064
+ /** Typed CT_StyleDefinition metadata and legacy rendering hint. */
3065
+ interface PptxSmartArtQuickStyle extends PptxSmartArtDefinitionMetadata {
3066
+ /** Legacy resolved display name. */
3067
+ name?: string;
3068
+ /** Legacy effect-intensity rendering hint. */
3069
+ effectIntensity?: string;
3070
+ /** Ordered CT_StyleLabel metadata. Complex style payload remains preserved XML. */
3071
+ labels?: PptxSmartArtQuickStyleLabel[];
3072
+ }
3073
+
3074
+ /**
3075
+ * SmartArt types: layout categories, layout presets, colour schemes,
3076
+ * data-model nodes/connections, drawing shapes, chrome, and the composite
3077
+ * `PptxSmartArtData`.
3078
+ *
3079
+ * @module pptx-types/smart-art
3080
+ */
3081
+
3082
+ /**
3083
+ * Resolved SmartArt layout category.
3084
+ *
3085
+ * @example
3086
+ * ```ts
3087
+ * const cat: SmartArtLayoutType = "hierarchy";
3088
+ * // => "hierarchy" — one of: "list" | "process" | "cycle" | "hierarchy" | "relationship" | …
3089
+ * ```
3090
+ */
3091
+ type SmartArtLayoutType = 'list' | 'process' | 'cycle' | 'hierarchy' | 'relationship' | 'matrix' | 'pyramid' | 'funnel' | 'gear' | 'target' | 'timeline' | 'venn' | 'chevron' | 'bending' | 'unknown';
3092
+ /**
3093
+ * Named SmartArt layout presets for creation (subset of PowerPoint layouts).
3094
+ *
3095
+ * @example
3096
+ * ```ts
3097
+ * const layout: SmartArtLayout = "hierarchy";
3098
+ * // => "hierarchy" — one of: "basicBlockList" | "alternatingHexagons" | "hierarchy" | …
3099
+ * ```
3100
+ */
3101
+ type SmartArtLayout = 'basicBlockList' | 'alternatingHexagons' | 'basicChevronProcess' | 'basicCycle' | 'basicPie' | 'basicRadial' | 'basicVenn' | 'continuousBlockProcess' | 'convergingRadial' | 'hierarchy' | 'horizontalBulletList' | 'linearVenn' | 'segmentedProcess' | 'stackedList' | 'tableList' | 'trapezoidList' | 'upwardArrow' | 'basicFunnel' | 'basicTarget' | 'interlockingGears' | 'basicTimeline' | 'basicMatrix' | 'basicPyramid' | 'invertedPyramid' | 'bendingProcess' | 'stepDownProcess' | 'alternatingFlow' | 'descendingProcess' | 'pictureAccentList' | 'verticalBlockList' | 'groupedList' | 'pyramidList' | 'horizontalPictureList' | 'accentProcess' | 'verticalChevronList';
3102
+ /**
3103
+ * SmartArt colour scheme presets.
3104
+ *
3105
+ * @example
3106
+ * ```ts
3107
+ * const scheme: SmartArtColorScheme = "colorful1";
3108
+ * // => "colorful1" — one of: "colorful1" | "colorful2" | "colorful3" | "monochromatic1" | "monochromatic2"
3109
+ * ```
3110
+ */
3111
+ type SmartArtColorScheme = 'colorful1' | 'colorful2' | 'colorful3' | 'monochromatic1' | 'monochromatic2';
3112
+ /**
3113
+ * SmartArt visual style intensity.
3114
+ *
3115
+ * @example
3116
+ * ```ts
3117
+ * const style: SmartArtStyle = "moderate";
3118
+ * // => "moderate" — one of: "flat" | "moderate" | "intense"
3119
+ * ```
3120
+ */
3121
+ type SmartArtStyle = 'flat' | 'moderate' | 'intense';
3122
+ /**
3123
+ * A connection between two SmartArt data-model nodes.
3124
+ *
3125
+ * @example
3126
+ * ```ts
3127
+ * const conn: PptxSmartArtConnection = {
3128
+ * sourceId: "1",
3129
+ * destId: "2",
3130
+ * type: "parOf",
3131
+ * };
3132
+ * // => satisfies PptxSmartArtConnection
3133
+ * ```
3134
+ */
3135
+ interface PptxSmartArtConnection {
3136
+ /** Stable CT_Cxn model identifier. Required when serialized. */
3137
+ modelId?: string | null;
3138
+ /** Model ID of the source node. */
3139
+ sourceId: string;
3140
+ /** Model ID of the destination node. */
3141
+ destId: string;
3142
+ /** Connection type (e.g. "parOf", "presOf", "sibTrans"). */
3143
+ type?: string;
3144
+ /** Source index for ordering sibling connections. */
3145
+ srcOrd?: number;
3146
+ /** Destination index for ordering. */
3147
+ destOrd?: number;
3148
+ /** Model ID of the parent transition point associated with this edge. */
3149
+ parentTransitionId?: string | null;
3150
+ /** Model ID of the sibling transition point associated with this edge. */
3151
+ siblingTransitionId?: string | null;
3152
+ /** Layout presentation identifier used by presentation connections. */
3153
+ presentationId?: string | null;
3154
+ }
3155
+ /**
3156
+ * A pre-computed shape from `ppt/diagrams/drawing*.xml`.
3157
+ *
3158
+ * @example
3159
+ * ```ts
3160
+ * const shape: PptxSmartArtDrawingShape = {
3161
+ * id: "s1",
3162
+ * shapeType: "roundRect",
3163
+ * x: 100, y: 50, width: 200, height: 80,
3164
+ * fillColor: "#4F81BD",
3165
+ * text: "CEO",
3166
+ * };
3167
+ * // => satisfies PptxSmartArtDrawingShape
3168
+ * ```
3169
+ */
3170
+ interface PptxSmartArtDrawingShape {
3171
+ /** Shape ID within the drawing. */
3172
+ id: string;
3173
+ /** Preset geometry type (e.g. "roundRect", "ellipse"). */
3174
+ shapeType?: string;
3175
+ /** Position and size in EMU-based pixels. */
3176
+ x: number;
3177
+ y: number;
3178
+ width: number;
3179
+ height: number;
3180
+ /** Rotation in degrees. */
3181
+ rotation?: number;
3182
+ /** Skew along the X axis in degrees. */
3183
+ skewX?: number;
3184
+ /** Skew along the Y axis in degrees. */
3185
+ skewY?: number;
3186
+ /** Solid fill colour (hex). */
3187
+ fillColor?: string;
3188
+ /** Stroke colour (hex). */
3189
+ strokeColor?: string;
3190
+ /** Stroke width in points. */
3191
+ strokeWidth?: number;
3192
+ /** Text content of the shape. */
3193
+ text?: string;
3194
+ /** Font size in points. */
3195
+ fontSize?: number;
3196
+ /** Font colour (hex). */
3197
+ fontColor?: string;
3198
+ }
3199
+ /**
3200
+ * Background / outline extracted from `dgm:bg` and `dgm:whole`.
3201
+ *
3202
+ * @example
3203
+ * ```ts
3204
+ * const chrome: PptxSmartArtChrome = {
3205
+ * backgroundColor: "#F0F0F0",
3206
+ * outlineColor: "#333333",
3207
+ * outlineWidth: 1,
3208
+ * };
3209
+ * // => satisfies PptxSmartArtChrome
3210
+ * ```
3211
+ */
3212
+ interface PptxSmartArtChrome {
3213
+ /** Background fill colour (hex). */
3214
+ backgroundColor?: string;
3215
+ /** Outline stroke colour (hex). */
3216
+ outlineColor?: string;
3217
+ /** Outline stroke width in points. */
3218
+ outlineWidth?: number;
3219
+ }
3220
+ /**
3221
+ * Complete parsed SmartArt data for a {@link SmartArtPptxElement}.
3222
+ *
3223
+ * @example
3224
+ * ```ts
3225
+ * const data: PptxSmartArtData = {
3226
+ * resolvedLayoutType: "hierarchy",
3227
+ * layout: "hierarchy",
3228
+ * colorScheme: "colorful1",
3229
+ * style: "moderate",
3230
+ * nodes: [
3231
+ * { id: "1", text: "CEO", children: [
3232
+ * { id: "2", text: "VP Marketing", parentId: "1" },
3233
+ * ]},
3234
+ * ],
3235
+ * };
3236
+ * // => satisfies PptxSmartArtData
3237
+ * ```
3238
+ */
3239
+ interface PptxSmartArtData {
3240
+ layoutType?: string;
3241
+ resolvedLayoutType?: SmartArtLayoutType;
3242
+ /** Named layout preset (used when creating new SmartArt). */
3243
+ layout?: SmartArtLayout;
3244
+ /** Colour scheme for the SmartArt graphic. */
3245
+ colorScheme?: SmartArtColorScheme;
3246
+ /** Visual style intensity. */
3247
+ style?: SmartArtStyle;
3248
+ nodes: PptxSmartArtNode[];
3249
+ /** Connections between data-model nodes. */
3250
+ connections?: PptxSmartArtConnection[];
3251
+ /** Pre-computed shapes from `ppt/diagrams/drawing*.xml`. */
3252
+ drawingShapes?: PptxSmartArtDrawingShape[];
3253
+ /** Background and outline chrome from `dgm:bg` / `dgm:whole`. */
3254
+ chrome?: PptxSmartArtChrome;
3255
+ /** Colour transform from `ppt/diagrams/colors*.xml`. */
3256
+ colorTransform?: PptxSmartArtColorTransform;
3257
+ /** Quick style from `ppt/diagrams/quickStyles*.xml`. */
3258
+ quickStyle?: PptxSmartArtQuickStyle;
3259
+ /** Editable metadata from the related DiagramML layout definition. */
3260
+ layoutDefinition?: PptxSmartArtLayoutDefinition;
3261
+ /** Relationship ID for the diagram data part (for round-trip save). */
3262
+ dataRelId?: string;
3263
+ /** Relationship ID for the diagram layout part. */
3264
+ layoutRelId?: string;
3265
+ /** Relationship ID for the drawing part. */
3266
+ drawingRelId?: string;
3267
+ /** Relationship ID for the colours part. */
3268
+ colorsRelId?: string;
3269
+ /** Relationship ID for the quick-styles part. */
3270
+ styleRelId?: string;
3271
+ /** Internal save hint: the layout definition changed in the editor. */
3272
+ layoutDirty?: boolean;
3273
+ /** Internal save hint: typed layout-definition metadata changed. */
3274
+ layoutDefinitionDirty?: boolean;
3275
+ /** Internal save hint: quick-style definition metadata changed. */
3276
+ quickStyleDirty?: boolean;
3277
+ /** Internal save hint: color-transform definition metadata changed. */
3278
+ colorTransformDirty?: boolean;
3279
+ /** Internal save hint: cached drawing geometry or text changed in the editor. */
3280
+ drawingDirty?: boolean;
3281
+ }
3282
+
3283
+ /**
3284
+ * Table types: cell styling, cell data, rows, table data, and the parsed
3285
+ * table style map from `ppt/tableStyles.xml`.
3286
+ *
3287
+ * @module pptx-types/table
3288
+ */
3289
+ /**
3290
+ * Per-cell visual style for a table cell.
3291
+ *
3292
+ * All fields are optional — unset values inherit from the table style.
3293
+ *
3294
+ * @example
3295
+ * ```ts
3296
+ * const header: PptxTableCellStyle = {
3297
+ * bold: true,
3298
+ * fontSize: 14,
3299
+ * color: "#FFFFFF",
3300
+ * backgroundColor: "#0055AA",
3301
+ * align: "center",
3302
+ * };
3303
+ * // => satisfies PptxTableCellStyle
3304
+ * ```
3305
+ */
3306
+ interface PptxTableCellStyle {
3307
+ fontSize?: number;
3308
+ bold?: boolean;
3309
+ italic?: boolean;
3310
+ underline?: boolean;
3311
+ color?: string;
3312
+ /**
3313
+ * Raw XML colour-choice node preserved from `a:tc/a:txBody/.../a:rPr/a:solidFill`
3314
+ * for round-trip serialisation. Currently unused by the cell-level writer
3315
+ * (cell text colour falls through `writeCellTextFormatting`), reserved for
3316
+ * future expansion alongside the run-properties round-trip path.
3317
+ */
3318
+ colorXml?: XmlObject;
3319
+ backgroundColor?: string;
3320
+ /**
3321
+ * Raw XML colour-choice node preserved from cell `a:tcPr/a:solidFill` for
3322
+ * round-trip serialisation. Re-emitted verbatim when the resolved
3323
+ * {@link backgroundColor} still matches the original colour.
3324
+ */
3325
+ backgroundColorXml?: XmlObject;
3326
+ borderColor?: string;
3327
+ /** Top border width in px. */
3328
+ borderTopWidth?: number;
3329
+ /** Bottom border width in px. */
3330
+ borderBottomWidth?: number;
3331
+ /** Left border width in px. */
3332
+ borderLeftWidth?: number;
3333
+ /** Right border width in px. */
3334
+ borderRightWidth?: number;
3335
+ /** Top border color as hex. */
3336
+ borderTopColor?: string;
3337
+ /** Bottom border color as hex. */
3338
+ borderBottomColor?: string;
3339
+ /** Left border color as hex. */
3340
+ borderLeftColor?: string;
3341
+ /** Right border color as hex. */
3342
+ borderRightColor?: string;
3343
+ align?: 'left' | 'center' | 'right' | 'justify';
3344
+ vAlign?: 'top' | 'middle' | 'bottom';
3345
+ /** Text direction from `a:tcPr/@vert` (spec values from CT_TextVerticalType). */
3346
+ textDirection?: 'vert' | 'vert270' | 'eaVert' | 'wordArtVert' | 'wordArtVertRtl' | 'mongolianVert';
3347
+ /** Cell left margin in px (from a:tcPr > a:tcMar > a:marL). */
3348
+ marginLeft?: number;
3349
+ /** Cell right margin in px. */
3350
+ marginRight?: number;
3351
+ /** Cell top margin in px. */
3352
+ marginTop?: number;
3353
+ /** Cell bottom margin in px. */
3354
+ marginBottom?: number;
3355
+ /** Diagonal border top-left to bottom-right color. */
3356
+ borderDiagDownColor?: string;
3357
+ /** Diagonal border top-left to bottom-right width in px. */
3358
+ borderDiagDownWidth?: number;
3359
+ /** Diagonal border bottom-left to top-right color. */
3360
+ borderDiagUpColor?: string;
3361
+ /** Diagonal border bottom-left to top-right width in px. */
3362
+ borderDiagUpWidth?: number;
3363
+ /** Table cell border dash style (legacy single value). */
3364
+ borderDash?: string;
3365
+ /** Per-edge border dash styles. */
3366
+ borderTopDash?: string;
3367
+ borderBottomDash?: string;
3368
+ borderLeftDash?: string;
3369
+ borderRightDash?: string;
3370
+ /** Cell text shadow colour. */
3371
+ textShadowColor?: string;
3372
+ /** Cell text shadow blur radius in px. */
3373
+ textShadowBlur?: number;
3374
+ /** Cell text shadow horizontal offset in px. */
3375
+ textShadowOffsetX?: number;
3376
+ /** Cell text shadow vertical offset in px. */
3377
+ textShadowOffsetY?: number;
3378
+ /** Cell text shadow opacity (0-1). */
3379
+ textShadowOpacity?: number;
3380
+ /** Cell text glow colour. */
3381
+ textGlowColor?: string;
3382
+ /** Cell text glow radius in px. */
3383
+ textGlowRadius?: number;
3384
+ /** Cell text glow opacity (0-1). */
3385
+ textGlowOpacity?: number;
3386
+ /** Cell fill mode: solid, gradient, pattern, or none. */
3387
+ fillMode?: 'solid' | 'gradient' | 'pattern' | 'none';
3388
+ /** Gradient fill stops (colours with positions). */
3389
+ gradientFillStops?: Array<{
3390
+ color: string;
3391
+ position: number;
3392
+ opacity?: number;
3393
+ }>;
3394
+ /** Gradient angle in degrees. */
3395
+ gradientFillAngle?: number;
3396
+ /** Gradient type: linear or radial. */
3397
+ gradientFillType?: 'linear' | 'radial';
3398
+ /** Path gradient sub-type. */
3399
+ gradientFillPathType?: 'circle' | 'rect' | 'shape';
3400
+ /** Focal point for radial gradients (0–1 fractions). */
3401
+ gradientFillFocalPoint?: {
3402
+ x: number;
3403
+ y: number;
3404
+ };
3405
+ /** Raw fillToRect LTRB values (0–1 fractions) for gradient sizing. */
3406
+ gradientFillFillToRect?: {
3407
+ l: number;
3408
+ t: number;
3409
+ r: number;
3410
+ b: number;
3411
+ };
3412
+ /** Pre-computed CSS gradient string for rendering. */
3413
+ gradientFillCss?: string;
3414
+ /** Pattern fill preset name (e.g. "ltDnDiag"). */
3415
+ patternFillPreset?: string;
3416
+ /** Pattern fill foreground colour. */
3417
+ patternFillForeground?: string;
3418
+ /** Pattern fill background colour. */
3419
+ patternFillBackground?: string;
3420
+ }
3421
+ /**
3422
+ * A single table cell with text content, optional style, and merge info.
3423
+ *
3424
+ * @example
3425
+ * ```ts
3426
+ * const cell: PptxTableCell = {
3427
+ * text: "$1.5M",
3428
+ * style: { bold: true, align: "right" },
3429
+ * gridSpan: 1,
3430
+ * };
3431
+ * // => satisfies PptxTableCell
3432
+ * ```
3433
+ */
3434
+ interface PptxTableCell {
3435
+ text: string;
3436
+ style?: PptxTableCellStyle;
3437
+ /** Column span (defaults to 1). */
3438
+ gridSpan?: number;
3439
+ /** Row span (defaults to 1). */
3440
+ rowSpan?: number;
3441
+ /** Whether this cell is merged vertically with the cell above. */
3442
+ vMerge?: boolean;
3443
+ /** Whether this cell is horizontally merged with the cell to the left (gridSpan continuation). */
3444
+ hMerge?: boolean;
3445
+ /**
3446
+ * Opaque round-trip storage for `a:tcPr` attributes that don't yet have
3447
+ * typed equivalents on {@link PptxTableCellStyle} (e.g. `horzOverflow`,
3448
+ * `anchorCtr`, `headers`, `hideSlicers`, `slicerCacheId`). Keys are the
3449
+ * raw XML attribute names without the `@_` prefix used by
3450
+ * fast-xml-parser. Re-emitted verbatim by the save writer when present.
3451
+ */
3452
+ extraAttributes?: Record<string, string>;
3453
+ }
3454
+ /**
3455
+ * A single table row with an optional height and an array of cells.
3456
+ *
3457
+ * @example
3458
+ * ```ts
3459
+ * const row: PptxTableRow = {
3460
+ * height: 40,
3461
+ * cells: [
3462
+ * { text: "Name" },
3463
+ * { text: "Score" },
3464
+ * ],
3465
+ * };
3466
+ * // => satisfies PptxTableRow
3467
+ * ```
3468
+ */
3469
+ interface PptxTableRow {
3470
+ /** Row height in px. */
3471
+ height?: number;
3472
+ cells: PptxTableCell[];
3473
+ }
3474
+ /**
3475
+ * Complete parsed table data for a {@link TablePptxElement}.
3476
+ *
3477
+ * Includes row/cell data, column widths, banding flags, and the applied
3478
+ * table style ID.
3479
+ *
3480
+ * @example
3481
+ * ```ts
3482
+ * const data: PptxTableData = {
3483
+ * rows: [
3484
+ * { cells: [{ text: "Product" }, { text: "Revenue" }] },
3485
+ * { cells: [{ text: "Widget A" }, { text: "$3.4M" }] },
3486
+ * ],
3487
+ * columnWidths: [0.6, 0.4],
3488
+ * firstRowHeader: true,
3489
+ * bandedRows: true,
3490
+ * };
3491
+ * // => satisfies PptxTableData
3492
+ * ```
3493
+ */
3494
+ interface PptxTableData {
3495
+ rows: PptxTableRow[];
3496
+ /** Column widths as proportion of total (summing to 1). */
3497
+ columnWidths: number[];
3498
+ /** Whether the table has banded rows. */
3499
+ bandedRows?: boolean;
3500
+ /** Whether the first row is a header. */
3501
+ firstRowHeader?: boolean;
3502
+ /** Whether banded columns are enabled. */
3503
+ bandedColumns?: boolean;
3504
+ /** Whether the last row is styled as a total row. */
3505
+ lastRow?: boolean;
3506
+ /** Whether the first column is styled as a header column. */
3507
+ firstCol?: boolean;
3508
+ /** Whether the last column is styled specially. */
3509
+ lastCol?: boolean;
3510
+ /** Table style ID from `a:tblPr/a:tblStyle@val` or `a:tblPr@tblStyle`. */
3511
+ tableStyleId?: string;
3512
+ /** Number of rows per banding group (default 1). */
3513
+ bandRowCycle?: number;
3514
+ /** Number of columns per banding group (default 1). */
3515
+ bandColCycle?: number;
3516
+ /** Right-to-left table layout from `a:tblPr/@rtl`. */
3517
+ rtl?: boolean;
3518
+ }
3519
+
3520
+ /**
3521
+ * A text box — a plain rectangle containing text, typically with no
3522
+ * visible fill or stroke.
3523
+ *
3524
+ * @example
3525
+ * ```ts
3526
+ * const title: TextPptxElement = {
3527
+ * type: "text",
3528
+ * id: "txt_1", x: 50, y: 30, width: 800, height: 60,
3529
+ * text: "Welcome",
3530
+ * textStyle: { fontSize: 36, bold: true },
3531
+ * };
3532
+ * // => satisfies TextPptxElement
3533
+ * ```
3534
+ */
3535
+ interface TextPptxElement extends PptxElementBase, PptxTextProperties, PptxShapeProperties {
3536
+ type: 'text';
3537
+ }
3538
+ /**
3539
+ * A shape — may contain text and custom geometry (preset or freeform).
3540
+ *
3541
+ * @example
3542
+ * ```ts
3543
+ * const rect: ShapePptxElement = {
3544
+ * type: "shape",
3545
+ * id: "shp_1", x: 100, y: 200, width: 300, height: 150,
3546
+ * shapeType: "roundRect",
3547
+ * shapeStyle: { fillColor: "#00AA55" },
3548
+ * text: "OK",
3549
+ * };
3550
+ * // => satisfies ShapePptxElement
3551
+ * ```
3552
+ */
3553
+ interface ShapePptxElement extends PptxElementBase, PptxTextProperties, PptxShapeProperties, PptxCustomPathProperties {
3554
+ type: 'shape';
3555
+ }
3556
+ /**
3557
+ * A connector (straight, bent, or curved line between shapes).
3558
+ *
3559
+ * Connector endpoints can snap to specific shapes via
3560
+ * `shapeStyle.connectorStartConnection` / `connectorEndConnection`.
3561
+ *
3562
+ * @example
3563
+ * ```ts
3564
+ * const line: ConnectorPptxElement = {
3565
+ * type: "connector",
3566
+ * id: "cxn_1", x: 100, y: 100, width: 200, height: 0,
3567
+ * shapeStyle: {
3568
+ * strokeColor: "#333",
3569
+ * connectorEndArrow: "triangle",
3570
+ * },
3571
+ * };
3572
+ * // => satisfies ConnectorPptxElement
3573
+ * ```
3574
+ */
3575
+ interface ConnectorPptxElement extends PptxElementBase, PptxTextProperties, PptxShapeProperties {
3576
+ type: 'connector';
3577
+ }
3578
+ /**
3579
+ * An image element from an OOXML `<p:pic>` node with `type: "image"`.
3580
+ *
3581
+ * @example
3582
+ * ```ts
3583
+ * const img: ImagePptxElement = {
3584
+ * type: "image",
3585
+ * id: "img_1", x: 0, y: 0, width: 960, height: 540,
3586
+ * imagePath: "ppt/media/image1.png",
3587
+ * altText: "Background scenery",
3588
+ * };
3589
+ * // => satisfies ImagePptxElement
3590
+ * ```
3591
+ */
3592
+ interface ImagePptxElement extends PptxElementBase, PptxShapeProperties, PptxCustomPathProperties, PptxImageProperties {
3593
+ type: 'image';
3594
+ }
3595
+ /**
3596
+ * A picture element from an OOXML `<p:pic>` node with `type: "picture"`.
3597
+ *
3598
+ * Functionally identical to {@link ImagePptxElement} but distinguished by
3599
+ * the `type` discriminant for semantic clarity.
3600
+ */
3601
+ interface PicturePptxElement extends PptxElementBase, PptxShapeProperties, PptxCustomPathProperties, PptxImageProperties {
3602
+ type: 'picture';
3603
+ }
3604
+ /**
3605
+ * A single unrecognised `<a:graphicData>/<a:extLst>/<a:ext>` extension on a
3606
+ * graphicFrame, captured verbatim so the round-trip can preserve future or
3607
+ * vendor-specific markup that the parser doesn't yet understand.
3608
+ *
3609
+ * The XML is preserved as a fast-xml-parser object tree (the same shape as
3610
+ * `rawXml` on other elements) so the save layer can re-emit it through the
3611
+ * existing builder without lossy string manipulation.
3612
+ */
3613
+ interface PptxGraphicFrameExtension {
3614
+ /** The `@_uri` attribute identifying the extension (e.g. `{C3CD43...}`). */
3615
+ uri: string;
3616
+ /** Parsed XML payload of the extension, suitable for re-serialization. */
3617
+ xml: XmlObject;
3618
+ }
3619
+ /**
3620
+ * A table embedded via a `<p:graphicFrame>`.
3621
+ *
3622
+ * @example
3623
+ * ```ts
3624
+ * const tbl: TablePptxElement = {
3625
+ * type: "table",
3626
+ * id: "tbl_1", x: 50, y: 200, width: 860, height: 300,
3627
+ * tableData: {
3628
+ * rows: [
3629
+ * { cells: [{ text: "Name" }, { text: "Score" }] },
3630
+ * { cells: [{ text: "Alice" }, { text: "95" }] },
3631
+ * ],
3632
+ * },
3633
+ * };
3634
+ * // => satisfies TablePptxElement
3635
+ * ```
3636
+ */
3637
+ interface TablePptxElement extends PptxElementBase {
3638
+ type: 'table';
3639
+ /** Parsed table cell data for editing. */
3640
+ tableData?: PptxTableData;
3641
+ /**
3642
+ * Unrecognised extensions captured from `a:graphicData/a:extLst` so they
3643
+ * round-trip losslessly. See {@link PptxGraphicFrameExtension}.
3644
+ */
3645
+ extensionXml?: PptxGraphicFrameExtension[];
3646
+ }
3647
+ /**
3648
+ * A chart embedded via a `<p:graphicFrame>`.
3649
+ *
3650
+ * Chart data is parsed from the related `chartN.xml` / `chartExN.xml`
3651
+ * parts inside the PPTX archive.
3652
+ */
3653
+ interface ChartPptxElement extends PptxElementBase {
3654
+ type: 'chart';
3655
+ chartData?: PptxChartData;
3656
+ /** Unrecognised graphicFrame extLst extensions, captured verbatim for round-trip. */
3657
+ extensionXml?: PptxGraphicFrameExtension[];
3658
+ }
3659
+ /**
3660
+ * A SmartArt diagram embedded via a `<p:graphicFrame>`.
3661
+ *
3662
+ * SmartArt data is extracted from `dgm:dataModel` parts. The editor
3663
+ * renders a simplified view; full editing is not supported.
3664
+ */
3665
+ interface SmartArtPptxElement extends PptxElementBase {
3666
+ type: 'smartArt';
3667
+ smartArtData?: PptxSmartArtData;
3668
+ /** Unrecognised graphicFrame extLst extensions, captured verbatim for round-trip. */
3669
+ extensionXml?: PptxGraphicFrameExtension[];
3670
+ }
3671
+ /**
3672
+ * Recognised OLE object application types derived from `progId` / `clsId`.
3673
+ *
3674
+ * Used to show type-specific icons and previews in the editor.
3675
+ */
3676
+ type OleObjectType = 'excel' | 'word' | 'pdf' | 'visio' | 'mathtype' | 'package' | 'unknown';
3677
+ /**
3678
+ * An OLE (Object Linking and Embedding) object.
3679
+ *
3680
+ * OLE objects can be embedded Excel sheets, Word documents, PDFs, Visio
3681
+ * diagrams, MathType equations, or generic "packages". They carry a
3682
+ * preview image for display and optional binary data for extraction.
3683
+ *
3684
+ * @example
3685
+ * ```ts
3686
+ * const ole: OlePptxElement = {
3687
+ * type: "ole",
3688
+ * id: "ole_1", x: 100, y: 200, width: 400, height: 300,
3689
+ * oleObjectType: "excel",
3690
+ * oleProgId: "Excel.Sheet.12",
3691
+ * fileName: "budget.xlsx",
3692
+ * };
3693
+ * // => satisfies OlePptxElement
3694
+ * ```
3695
+ */
3696
+ interface OlePptxElement extends PptxElementBase {
3697
+ type: 'ole';
3698
+ oleTarget?: string;
3699
+ oleProgId?: string;
3700
+ oleName?: string;
3701
+ /** CLSID of the OLE object (from `@_classid`). */
3702
+ oleClsId?: string;
3703
+ /** Detected application type (excel, word, pdf, etc.). */
3704
+ oleObjectType?: OleObjectType;
3705
+ /** File extension for the embedded binary (e.g. "xlsx", "docx"). */
3706
+ oleFileExtension?: string;
3707
+ /** Original file name when available. */
3708
+ fileName?: string;
3709
+ /** Whether this is a linked (vs. embedded) object. */
3710
+ isLinked?: boolean;
3711
+ /** External file path for linked OLE objects (TargetMode="External"). */
3712
+ externalPath?: string;
3713
+ /** Data-URL or path for the OLE preview image. */
3714
+ previewImage?: string;
3715
+ /** Decoded preview image as a data-URL. */
3716
+ previewImageData?: string;
3717
+ /** Whether the OLE object is shown as an icon (`p:oleObj/@showAsIcon`). */
3718
+ oleShowAsIcon?: boolean;
3719
+ /** Authored display width of the OLE object preview, in EMU (`@imgW`). */
3720
+ oleImgW?: number;
3721
+ /** Authored display height of the OLE object preview, in EMU (`@imgH`). */
3722
+ oleImgH?: number;
3723
+ /**
3724
+ * The recovered embedded payload as a data-URL (e.g.
3725
+ * `data:application/vnd...;base64,...`), suitable for download or
3726
+ * open-in-new-tab. For a generic "Package" OLE object this is the unwrapped
3727
+ * inner file; for a plain embedded file (e.g. `.xlsx`) it is that file
3728
+ * directly. Undefined when the embedding is missing or unreadable.
3729
+ *
3730
+ * Stored as a data-URL string to mirror how images store decoded bytes
3731
+ * ({@link ImagePptxElement.imageData}) and to stay serialization-safe.
3732
+ */
3733
+ oleEmbeddedData?: string;
3734
+ /** Original file name of the embedded payload when recoverable. */
3735
+ oleEmbeddedFileName?: string;
3736
+ /** MIME type of the embedded payload, derived from its extension/ProgID. */
3737
+ oleEmbeddedMimeType?: string;
3738
+ /** Size of the embedded payload in bytes. */
3739
+ oleEmbeddedByteSize?: number;
3740
+ /** Unrecognised graphicFrame extLst extensions, captured verbatim for round-trip. */
3741
+ extensionXml?: PptxGraphicFrameExtension[];
3742
+ }
3743
+ /**
3744
+ * An audio or video media element.
3745
+ *
3746
+ * Media elements reference files inside the PPTX archive
3747
+ * (`mediaPath`) and may include trim points, poster frames, and
3748
+ * playback settings for presentation mode.
3749
+ *
3750
+ * @example
3751
+ * ```ts
3752
+ * const video: MediaPptxElement = {
3753
+ * type: "media",
3754
+ * id: "vid_1", x: 50, y: 100, width: 640, height: 360,
3755
+ * mediaType: "video",
3756
+ * mediaPath: "ppt/media/media1.mp4",
3757
+ * autoPlay: true,
3758
+ * volume: 0.8,
3759
+ * };
3760
+ * // => satisfies MediaPptxElement
3761
+ * ```
3762
+ */
3763
+ interface MediaPptxElement extends PptxElementBase {
3764
+ type: 'media';
3765
+ mediaType?: PptxMediaType;
3766
+ mediaPath?: string;
3767
+ mediaData?: string;
3768
+ mediaMimeType?: string;
3769
+ mediaReferenceKind?: PptxMediaReferenceKind;
3770
+ mediaReferenceName?: string;
3771
+ audioCdStart?: PptxAudioCdPosition;
3772
+ audioCdEnd?: PptxAudioCdPosition;
3773
+ rawMediaReferenceXml?: XmlObject;
3774
+ /** Trim start in milliseconds (from p:cMediaNode p:cTn @st). */
3775
+ trimStartMs?: number;
3776
+ /** Trim end in milliseconds (from p:cMediaNode p:cTn @end). */
3777
+ trimEndMs?: number;
3778
+ /** Path to the poster/preview image inside the ZIP. */
3779
+ posterFramePath?: string;
3780
+ /** Base64 data-URL for the poster frame image. */
3781
+ posterFrameData?: string;
3782
+ /** Whether media should play full-screen during presentation. */
3783
+ fullScreen?: boolean;
3784
+ /** Whether media should loop continuously. */
3785
+ loop?: boolean;
3786
+ /** Fade-in duration in seconds. */
3787
+ fadeInDuration?: number;
3788
+ /** Fade-out duration in seconds. */
3789
+ fadeOutDuration?: number;
3790
+ /** Playback volume (0 to 1). */
3791
+ volume?: number;
3792
+ /** Whether media auto-plays on slide entry. */
3793
+ autoPlay?: boolean;
3794
+ /** Whether audio continues playing across slide transitions (presentation mode). */
3795
+ playAcrossSlides?: boolean;
3796
+ /** Hide the element when media is not actively playing. */
3797
+ hideWhenNotPlaying?: boolean;
3798
+ /** Named time bookmarks within the clip. */
3799
+ bookmarks?: MediaBookmark[];
3800
+ /** Playback speed multiplier (1 = normal, 2 = double, 0.5 = half). */
3801
+ playbackSpeed?: number;
3802
+ /** Runtime-extracted metadata (duration, resolution, codec). */
3803
+ metadata?: MediaMetadata;
3804
+ /** Closed caption / subtitle tracks. */
3805
+ captionTracks?: MediaCaptionTrack[];
3806
+ /** Whether the media source is missing/broken (file not found in archive). */
3807
+ mediaMissing?: boolean;
3808
+ /**
3809
+ * Whether the media is linked (external `r:link`) rather than embedded
3810
+ * (`r:embed`). Defaults to embedded when undefined.
3811
+ */
3812
+ isLinked?: boolean;
3813
+ /** Unrecognised graphicFrame extLst extensions, captured verbatim for round-trip. */
3814
+ extensionXml?: PptxGraphicFrameExtension[];
3815
+ }
3816
+ /**
3817
+ * A group container that holds child elements.
3818
+ *
3819
+ * Children inherit the group’s transform, so moving/resizing the group
3820
+ * affects all children proportionally.
3821
+ *
3822
+ * @example
3823
+ * ```ts
3824
+ * const group: GroupPptxElement = {
3825
+ * type: "group",
3826
+ * id: "grp_1", x: 0, y: 0, width: 960, height: 540,
3827
+ * children: [textEl, shapeEl],
3828
+ * };
3829
+ * // => satisfies GroupPptxElement
3830
+ * ```
3831
+ */
3832
+ interface GroupPptxElement extends PptxElementBase {
3833
+ type: 'group';
3834
+ /** Child elements contained within this group. */
3835
+ children: PptxElement[];
3836
+ /** Fill style extracted from the group's `p:grpSpPr`, used for `a:grpFill` inheritance. */
3837
+ groupFill?: ShapeStyle;
3838
+ }
3839
+ /**
3840
+ * A freehand ink / drawing stroke captured with a stylus or mouse.
3841
+ *
3842
+ * Ink strokes are stored as SVG path data strings. Each path may
3843
+ * have independent colour, width, and opacity.
3844
+ */
3845
+ interface InkPptxElement extends PptxElementBase {
3846
+ type: 'ink';
3847
+ /** SVG path data for ink strokes. */
3848
+ inkPaths: string[];
3849
+ /** Per-path stroke colours. */
3850
+ inkColors?: string[];
3851
+ /** Per-path stroke widths. */
3852
+ inkWidths?: number[];
3853
+ /** Per-path opacities (0-1). */
3854
+ inkOpacities?: number[];
3855
+ /** Drawing tool used: pen, highlighter, or eraser. */
3856
+ inkTool?: 'pen' | 'highlighter' | 'eraser';
3857
+ /**
3858
+ * Per-path arrays of per-point pressure values (0-1).
3859
+ *
3860
+ * Each entry corresponds to the path at the same index in `inkPaths`.
3861
+ * Each inner array contains one pressure value per sampled point along
3862
+ * the stroke. When present, the renderer uses these values to produce
3863
+ * variable-width strokes that reflect stylus/pen pressure.
3864
+ */
3865
+ inkPointPressures?: number[][];
3866
+ /** Unrecognised graphicFrame extLst extensions, captured verbatim for round-trip. */
3867
+ extensionXml?: PptxGraphicFrameExtension[];
3868
+ }
3869
+ /**
3870
+ * A single ink stroke within a {@link ContentPartPptxElement}.
3871
+ */
3872
+ interface ContentPartInkStroke {
3873
+ path: string;
3874
+ color: string;
3875
+ width: number;
3876
+ opacity: number;
3877
+ /**
3878
+ * Per-point pressure values (0-1) for this stroke.
3879
+ *
3880
+ * When present, the renderer uses these values to produce
3881
+ * variable-width strokes that reflect stylus/pen pressure.
3882
+ */
3883
+ pressures?: number[];
3884
+ }
3885
+ /**
3886
+ * A content-part element wrapped in `mc:AlternateContent`.
3887
+ *
3888
+ * Typically contains ink strokes from modern PowerPoint pen/highlighter.
3889
+ */
3890
+ interface ContentPartPptxElement extends PptxElementBase {
3891
+ type: 'contentPart';
3892
+ /** Ink strokes contained in this content part. */
3893
+ inkStrokes?: ContentPartInkStroke[];
3894
+ }
3895
+ /**
3896
+ * A Slide Zoom or Section Zoom element (PowerPoint Zoom Object).
134
3897
  *
135
- * - **Attributes** keys matching `` `@_${string}` `` return
136
- * `string | undefined` directly.
137
- * - **Text content** — `#text` returns `string | undefined`.
138
- * - **Child elements** — any other string key returns
139
- * `XmlObject | XmlObject[] | string | undefined`. The union reflects that
140
- * fast-xml-parser may emit an object (single child), an array (repeated
141
- * children), or a bare string (text-only element collapsed by the parser).
3898
+ * Zoom elements display a live thumbnail of the target slide and
3899
+ * navigate to it on click during presentation mode.
142
3900
  *
143
- * For traversal, prefer the helpers in {@link ./../utils/xml-access} —
144
- * `xmlChild` / `xmlChildren` / `xmlAttr` / `xmlText` / `xmlPath` — which
145
- * narrow the union and normalize the single-vs-array duality. Direct
146
- * indexing works for attributes (typed as string) but chained child access
147
- * (`obj['p:spPr']?.['a:xfrm']`) requires the helpers or a narrowing cast
148
- * because TypeScript cannot index into the `XmlObject[] | string` part of
149
- * the union.
3901
+ * @example
3902
+ * ```ts
3903
+ * const zoom: ZoomPptxElement = {
3904
+ * type: "zoom",
3905
+ * id: "zm_1", x: 300, y: 200, width: 200, height: 120,
3906
+ * zoomType: "slide",
3907
+ * targetSlideIndex: 5,
3908
+ * };
3909
+ * // => satisfies ZoomPptxElement
3910
+ * ```
150
3911
  */
151
- interface XmlObject {
152
- /** Attributes (`@_`-prefixed keys) are always strings at runtime. */
153
- [attr: `@_${string}`]: string | undefined;
154
- /** Element text content surfaces under `#text` when present. */
155
- '#text'?: string;
3912
+ interface ZoomPptxElement extends PptxElementBase, PptxImageProperties {
3913
+ type: 'zoom';
3914
+ /** Type of zoom: slide-level or section-level. */
3915
+ zoomType: 'slide' | 'section';
3916
+ /** Zero-based index of the target slide. */
3917
+ targetSlideIndex: number;
3918
+ /** Section ID for section zoom. */
3919
+ targetSectionId?: string;
3920
+ }
3921
+ /**
3922
+ * A 3D model object embedded via `p16:model3D` inside an
3923
+ * `mc:AlternateContent` block (PowerPoint 365+).
3924
+ *
3925
+ * The element carries the path to the `.glb`/`.gltf` binary inside
3926
+ * the ZIP and a poster/fallback image for rendering in viewers that
3927
+ * do not support interactive 3D.
3928
+ */
3929
+ interface Model3DPptxElement extends PptxElementBase, PptxImageProperties {
3930
+ type: 'model3d';
3931
+ /** Path to the 3D model file inside the ZIP. */
3932
+ modelPath?: string;
3933
+ /** Base64 data URL of the 3D model binary. */
3934
+ modelData?: string;
3935
+ /** MIME type of the model (e.g. "model/gltf-binary"). */
3936
+ modelMimeType?: string;
3937
+ /** Poster/preview image shown when 3D rendering is unavailable. */
3938
+ posterImage?: string;
3939
+ /** Unrecognised graphicFrame extLst extensions, captured verbatim for round-trip. */
3940
+ extensionXml?: PptxGraphicFrameExtension[];
3941
+ }
3942
+ /** An element whose type is not recognised by the parser. */
3943
+ interface UnknownPptxElement extends PptxElementBase {
3944
+ type: 'unknown';
3945
+ /** Unrecognised graphicFrame extLst extensions, captured verbatim for round-trip. */
3946
+ extensionXml?: PptxGraphicFrameExtension[];
3947
+ }
3948
+ /**
3949
+ * A single element on a PPTX slide.
3950
+ *
3951
+ * This is a **discriminated union** — narrow on `element.type` to access
3952
+ * variant-specific properties like `imageData` (image/picture), `pathData`
3953
+ * (shape), or `textSegments` (text/shape).
3954
+ */
3955
+ type PptxElement = TextPptxElement | ShapePptxElement | ConnectorPptxElement | ImagePptxElement | PicturePptxElement | TablePptxElement | ChartPptxElement | SmartArtPptxElement | OlePptxElement | MediaPptxElement | GroupPptxElement | InkPptxElement | ContentPartPptxElement | ZoomPptxElement | Model3DPptxElement | UnknownPptxElement;
3956
+ /**
3957
+ * Per-part header/footer flags from `<p:hf>` (CT_HeaderFooter, ECMA-376
3958
+ * §19.3.1.21). Defaults are "all true" — fields are only set on the typed
3959
+ * model when they were explicitly read, so callers can distinguish "unset"
3960
+ * (preserve original XML) from "false" (override).
3961
+ */
3962
+ interface PptxHeaderFooterFlags {
3963
+ /** `@hdr` — show header placeholder. Spec default: `true`. */
3964
+ hasHeader?: boolean;
3965
+ /** `@ftr` — show footer placeholder. Spec default: `true`. */
3966
+ hasFooter?: boolean;
3967
+ /** `@dt` — show date/time placeholder. Spec default: `true`. */
3968
+ hasDateTime?: boolean;
3969
+ /** `@sldNum` — show slide-number placeholder. Spec default: `true`. */
3970
+ hasSlideNumber?: boolean;
3971
+ }
3972
+
3973
+ /**
3974
+ * Animation types: presets, triggers, timing, native parsed animation data,
3975
+ * and the high-level {@link PptxElementAnimation} associated with each element.
3976
+ *
3977
+ * @module pptx-types/animation
3978
+ */
3979
+
3980
+ /**
3981
+ * Built-in animation preset names used for entrance, exit, and emphasis effects.
3982
+ *
3983
+ * @example
3984
+ * ```ts
3985
+ * const preset: PptxAnimationPreset = "fadeIn";
3986
+ * // => "fadeIn" — one of: none | fadeIn | flyIn | zoomIn | fadeOut | flyOut | zoomOut | spin | pulse | ...
3987
+ * ```
3988
+ */
3989
+ type PptxAnimationPreset = 'none' | 'appear' | 'fadeIn' | 'flyIn' | 'zoomIn' | 'bounceIn' | 'wipeIn' | 'splitIn' | 'dissolveIn' | 'wheelIn' | 'blindsIn' | 'boxIn' | 'floatIn' | 'riseUp' | 'swivel' | 'expandIn' | 'checkerboardIn' | 'flashIn' | 'peekIn' | 'randomBarsIn' | 'spinnerIn' | 'growTurnIn' | 'fadeOut' | 'flyOut' | 'zoomOut' | 'bounceOut' | 'wipeOut' | 'shrinkOut' | 'dissolveOut' | 'disappear' | 'spin' | 'pulse' | 'colorWave' | 'bounce' | 'flash' | 'growShrink' | 'teeter' | 'transparency' | 'boldFlash' | 'wave';
3990
+ /** Animation timing curve. */
3991
+ type PptxAnimationTimingCurve = 'ease' | 'ease-in' | 'ease-out' | 'linear';
3992
+ /** Repeat mode for animations. */
3993
+ type PptxAnimationRepeatMode = 'untilNextClick' | 'untilEndOfSlide';
3994
+ /** Animation trigger type from OOXML `p:cTn`. */
3995
+ type PptxAnimationTrigger = 'onClick' | 'onShapeClick' | 'onHover' | 'afterPrevious' | 'withPrevious' | 'afterDelay';
3996
+ /**
3997
+ * Native animation kind. The historic shape-targeted preset animations are
3998
+ * implicitly the default kind (`undefined`). Media animations (`p:audio`,
3999
+ * `p:video`) emit dedicated entries so playback order on the slide timeline
4000
+ * is preserved alongside other animations.
4001
+ */
4002
+ type PptxNativeAnimationKind = 'media';
4003
+ /** A target selected by `p:tgtEl` in the PresentationML timing model. */
4004
+ type PptxAnimationTarget = {
4005
+ type: 'shape';
4006
+ shapeId: string;
4007
+ rawXml?: XmlObject;
4008
+ } | {
4009
+ type: 'slide';
4010
+ rawXml?: XmlObject;
4011
+ } | {
4012
+ type: 'sound';
4013
+ relationshipId: string;
4014
+ name?: string;
4015
+ rawXml?: XmlObject;
4016
+ } | {
4017
+ type: 'ink';
4018
+ shapeId: string;
4019
+ rawXml?: XmlObject;
4020
+ } | {
4021
+ type: 'unknown';
4022
+ rawXml: XmlObject;
4023
+ };
4024
+ /** Nested build choice carried by `p:bldGraphic`. */
4025
+ type PptxGraphicBuild = {
4026
+ mode: 'asOne';
4027
+ rawXml?: XmlObject;
4028
+ } | {
4029
+ mode: 'sub';
4030
+ kind: 'diagram';
4031
+ build: string;
4032
+ reverse: boolean;
4033
+ rawXml?: XmlObject;
4034
+ } | {
4035
+ mode: 'sub';
4036
+ kind: 'chart';
4037
+ build: string;
4038
+ animateBackground: boolean;
4039
+ rawXml?: XmlObject;
4040
+ };
4041
+ /**
4042
+ * Parsed native animation record from `p:timing / p:tnLst`.
4043
+ *
4044
+ * Represents a single animation node in the OOXML timing tree,
4045
+ * including motion paths, scale transforms, and text build settings.
4046
+ *
4047
+ * @example
4048
+ * ```ts
4049
+ * const anim: PptxNativeAnimation = {
4050
+ * targetId: "shape_1",
4051
+ * presetClass: "entr",
4052
+ * presetId: 10,
4053
+ * trigger: "afterPrevious",
4054
+ * durationMs: 500,
4055
+ * };
4056
+ * // => { targetId: "shape_1", presetClass: "entr", presetId: 10, trigger: "afterPrevious", durationMs: 500 }
4057
+ * ```
4058
+ */
4059
+ interface PptxNativeAnimation {
4060
+ /** Target element/shape ID. */
4061
+ targetId?: string;
4062
+ /** Full timing target, including sound and ink target variants. */
4063
+ target?: PptxAnimationTarget;
4064
+ /** Trigger type. */
4065
+ trigger?: PptxAnimationTrigger;
4066
+ /** Shape ID that triggers this animation when clicked (interactive sequence). */
4067
+ triggerShapeId?: string;
4068
+ /** Effect preset class (entr, exit, emph, path). */
4069
+ presetClass?: 'entr' | 'exit' | 'emph' | 'path';
4070
+ /** Effect preset sub-type identifier. */
4071
+ presetId?: number;
4072
+ /** Duration in milliseconds. */
4073
+ durationMs?: number;
4074
+ /** Delay in milliseconds. */
4075
+ delayMs?: number;
4076
+ /** Trigger delay in milliseconds (for afterDelay). */
4077
+ triggerDelayMs?: number;
4078
+ /** SVG path string for motion path animations (`p:animMotion/@path`). */
4079
+ motionPath?: string;
4080
+ /** Motion origin: "layout" or "parent". */
4081
+ motionOrigin?: string;
4082
+ /** Whether the element auto-rotates to follow the motion path tangent (`p:animMotion/@rAng` = "0"). */
4083
+ motionPathRotateAuto?: boolean;
4084
+ /** Path edit mode from `p:animMotion/@pathEditMode` (e.g. "relative", "fixed"). */
4085
+ motionPathEditMode?: string;
4086
+ /** Comma-separated point-types string from `p:animMotion/@ptsTypes`. */
4087
+ motionPtsTypes?: string;
4088
+ /** Rotation angle in degrees for `p:animRot/@by` (converted from 60000ths). */
4089
+ rotationBy?: number;
4090
+ /** Starting rotation angle in degrees for `p:animRot/@from` (converted from 60000ths). */
4091
+ rotationFrom?: number;
4092
+ /** Ending rotation angle in degrees for `p:animRot/@to` (converted from 60000ths). */
4093
+ rotationTo?: number;
4094
+ /** X scale factor (percentage / 100) for `p:animScale/p:by/@x`. */
4095
+ scaleByX?: number;
4096
+ /** Y scale factor (percentage / 100) for `p:animScale/p:by/@y`. */
4097
+ scaleByY?: number;
4098
+ /** Starting X scale factor for `p:animScale/p:from/@x`. */
4099
+ scaleFromX?: number;
4100
+ /** Starting Y scale factor for `p:animScale/p:from/@y`. */
4101
+ scaleFromY?: number;
4102
+ /** Ending X scale factor for `p:animScale/p:to/@x`. */
4103
+ scaleToX?: number;
4104
+ /** Ending Y scale factor for `p:animScale/p:to/@y`. */
4105
+ scaleToY?: number;
4106
+ /** Whether `p:animScale/@zoomContents` was set ("1"/"true"). */
4107
+ scaleZoomContents?: boolean;
4108
+ /** Parsed `p:tav` keyframes from `p:tavLst` (CT_TLAnimVariantList). */
4109
+ keyframes?: PptxAnimationKeyframe[];
4110
+ /** Repeat count (e.g. `2`, `Infinity` for indefinite). */
4111
+ repeatCount?: number;
4112
+ /** Whether the animation plays in reverse after completion. */
4113
+ autoReverse?: boolean;
4114
+ /** Text build type from `p:bldP/@build` in `p:bldLst`. */
4115
+ buildType?: PptxTextBuildType;
4116
+ /** Build level for multi-level lists from `p:bldP/@bldLvl`. */
4117
+ buildLevel?: number;
4118
+ /** Group ID linking a `p:bldP` entry to its timing animation node. */
4119
+ groupId?: string;
4120
+ /** Sound relationship ID to play when animation triggers (`p:stSnd`). */
4121
+ soundRId?: string;
4122
+ /** Resolved sound file path from relationship. */
4123
+ soundPath?: string;
4124
+ /** Whether to stop any currently playing sound (`p:endSnd`). */
4125
+ stopSound?: boolean;
4126
+ /** Structured start conditions parsed from `p:stCondLst`. */
4127
+ startConditions?: AnimationCondition[];
4128
+ /** Structured end conditions parsed from `p:endCondLst`. */
4129
+ endConditions?: AnimationCondition[];
4130
+ /** Preserved raw `p:endCondLst` XML node for lossless round-trip. */
4131
+ rawEndCondLst?: XmlObject;
4132
+ /** Color animation data from `p:animClr`. */
4133
+ colorAnimation?: PptxColorAnimation;
4134
+ /** Text-level target: character range or paragraph range from `p:txEl`. */
4135
+ textTarget?: PptxTextAnimationTarget;
4136
+ /** Whether this animation is inside an exclusive container (`p:excl`). */
4137
+ exclusive?: boolean;
4138
+ /** Command type from `p:cmd` (@_type: call/evt/verb). */
4139
+ commandType?: string;
4140
+ /** Command string from `p:cmd` (@_cmd). */
4141
+ commandString?: string;
4142
+ /** Iteration configuration from `p:iterate`. */
4143
+ iterate?: PptxAnimationIterate;
156
4144
  /**
157
- * Child elements keyed by their (namespaced) tag name. fast-xml-parser
158
- * emits a single object for unique elements, an array for repeated ones,
159
- * and a bare string for elements collapsed to their text content. Use
160
- * the helpers in `utils/xml-access` to narrow this union.
4145
+ * Discriminator for non-preset animation kinds. When `undefined`, the
4146
+ * entry represents the default shape-effect animation. The `'media'`
4147
+ * kind represents a `p:audio` / `p:video` timing node, captured here so
4148
+ * playback order in the timeline is preserved alongside other animations.
161
4149
  */
162
- [child: string]: XmlObject | XmlObject[] | string | undefined;
4150
+ kind?: PptxNativeAnimationKind;
4151
+ /**
4152
+ * For `kind === 'media'`, identifies whether this is an audio or video
4153
+ * media node so writers know which OOXML element to re-emit.
4154
+ */
4155
+ mediaType?: 'audio' | 'video';
4156
+ /**
4157
+ * SmartArt build attribute (`p:bldDgm/@bld`) when this animation is
4158
+ * associated with a SmartArt diagram build. Common values include
4159
+ * `whole`, `one`, `lvlOne`, `lvlAtOnce`.
4160
+ */
4161
+ smartArtBuild?: string;
4162
+ /**
4163
+ * Graphic-frame build attribute (`p:bldGraphic/@bld`) when this animation
4164
+ * is associated with a generic graphic frame build (charts, tables, etc.
4165
+ * that aren't OLE charts).
4166
+ */
4167
+ graphicBuild?: string;
4168
+ /** Schema-accurate `p:bldGraphic/p:bldAsOne|p:bldSub` representation. */
4169
+ graphicBuildProperties?: PptxGraphicBuild;
4170
+ /**
4171
+ * Opaque map of `p:cTn` attributes that don't have a typed home on this
4172
+ * interface but must round-trip through parse → save. Keys are stored
4173
+ * verbatim including the `@_` prefix used by the underlying XML parser
4174
+ * (e.g. `@_evtFilter`, `@_display`, `@_masterRel`, `@_nodePh`,
4175
+ * `@_endSync`, `@_progress`). The `subTnLst` child element is also
4176
+ * preserved here under the literal key `p:subTnLst`. The `afterEffect`
4177
+ * attribute is surfaced separately as a typed boolean ({@link afterEffect})
4178
+ * because it changes write semantics for subsequent timing nodes.
4179
+ */
4180
+ cTnAttributes?: Record<string, unknown>;
4181
+ /**
4182
+ * Whether the OOXML `p:cTn/@afterEffect` flag is set. Indicates this node
4183
+ * runs after the parent effect's main body has completed; affects how
4184
+ * subsequent peer nodes are sequenced when serialised back to OOXML.
4185
+ */
4186
+ afterEffect?: boolean;
4187
+ }
4188
+ /**
4189
+ * Single keyframe parsed from a `p:tav` element (CT_TLTimeAnimateValue).
4190
+ *
4191
+ * Each entry in a `p:tavLst` has a time fraction (`@_tm`, in 1000ths of the
4192
+ * total duration; or the literal "indefinite" / "large") and a typed value
4193
+ * child under `p:val/p:strVal|p:boolVal|p:intVal|p:fltVal|p:clrVal`.
4194
+ *
4195
+ * @see ECMA-376 §19.5.30 CT_TLAnimVariantList / §19.5.92 CT_TLTimeAnimateValue
4196
+ */
4197
+ interface PptxAnimationKeyframe {
4198
+ /**
4199
+ * Time fraction. A finite number is the OOXML `@_tm` integer (0–100000
4200
+ * for percentage, where 100000 = 100% of duration). A string preserves
4201
+ * special tokens ("indefinite", "large").
4202
+ */
4203
+ tm: number | string;
4204
+ /** Decoded keyframe value. */
4205
+ value: string | boolean | number;
4206
+ /** Discriminant indicating which `p:val` child carried the value. */
4207
+ valueType: 'str' | 'bool' | 'int' | 'flt' | 'clr';
4208
+ /**
4209
+ * Optional formula carried on `p:tav/@_fmla`. Preserved for round-trip
4210
+ * fidelity; consumers may use it to drive computed animation values.
4211
+ */
4212
+ fmla?: string;
4213
+ }
4214
+ /** Color animation data parsed from `p:animClr`. */
4215
+ interface PptxColorAnimation {
4216
+ /** Color interpolation space: "hsl" or "rgb". */
4217
+ colorSpace: 'hsl' | 'rgb';
4218
+ /** Direction for HSL interpolation: "cw" (clockwise) or "ccw". */
4219
+ direction?: 'cw' | 'ccw';
4220
+ /**
4221
+ * Optional `p:animClr/@path` value preserved for round-trip. When set,
4222
+ * the colour sweep follows a path-based interpolation rather than the
4223
+ * straight cw/ccw arc. ECMA-376 §19.5.13 documents this attribute as a
4224
+ * companion to `@dir` for HSL colour-space animations.
4225
+ */
4226
+ path?: string;
4227
+ /** Starting color as hex string. */
4228
+ fromColor?: string;
4229
+ /** Ending color as hex string. */
4230
+ toColor?: string;
4231
+ /**
4232
+ * Color delta (for "by" animations) as hex string. For HSL colour-space
4233
+ * animations the value encodes a delta over hue/sat/lum and is preserved
4234
+ * verbatim from the source.
4235
+ */
4236
+ byColor?: string;
4237
+ /**
4238
+ * Target attribute from `p:attrNameLst` (e.g. "fillcolor", "style.color",
4239
+ * "stroke.color"). Used to determine which CSS property to animate.
4240
+ */
4241
+ targetAttribute?: string;
4242
+ }
4243
+ /** Text-level animation target from `p:txEl`. */
4244
+ interface PptxTextAnimationTarget {
4245
+ /** Target type: character range or paragraph range. */
4246
+ type: 'charRg' | 'pRg';
4247
+ /** Start index (0-based). */
4248
+ start: number;
4249
+ /** End index (exclusive). */
4250
+ end: number;
4251
+ }
4252
+ /**
4253
+ * Event types for animation conditions from `p:cond/@evt`.
4254
+ *
4255
+ * These map directly to OOXML condition event attribute values
4256
+ * (ISO/IEC 29500-1 S19.5.28 CT_TLTimeCondition).
4257
+ */
4258
+ type AnimationConditionEvent = 'onBegin' | 'onEnd' | 'begin' | 'end' | 'onClick' | 'onMouseOver' | 'onMouseOut' | 'onNext' | 'onPrev' | 'onStopAudio';
4259
+ /**
4260
+ * Structured representation of a single OOXML animation condition
4261
+ * from `p:cond` elements inside `p:stCondLst` or `p:endCondLst`.
4262
+ *
4263
+ * Conditions control when an animation starts or ends, and can reference
4264
+ * events, time delays, and target time node IDs.
4265
+ *
4266
+ * @example
4267
+ * ```ts
4268
+ * const cond: AnimationCondition = {
4269
+ * event: "onClick",
4270
+ * delay: 0,
4271
+ * targetShapeId: "shape_5",
4272
+ * };
4273
+ * ```
4274
+ */
4275
+ interface AnimationCondition {
4276
+ /** Event that triggers the condition. */
4277
+ event?: AnimationConditionEvent;
4278
+ /** Delay in milliseconds (from `@_delay`). "indefinite" is represented as -1. */
4279
+ delay?: number;
4280
+ /** Target time node ID reference (from `@_tn`). */
4281
+ targetTimeNodeId?: number;
4282
+ /** Target shape ID from `p:tgtEl/p:spTgt/@spid`. */
4283
+ targetShapeId?: string;
4284
+ /** Whether the condition targets a slide (from `p:tgtEl/p:sldTgt`). */
4285
+ targetSlide?: boolean;
4286
+ /** Full target choice, including `p:sndTgt` and `p:inkTgt`. */
4287
+ target?: PptxAnimationTarget;
4288
+ }
4289
+ /** Iteration configuration from `p:iterate`. */
4290
+ interface PptxAnimationIterate {
4291
+ /** Iteration type: el (element), lt (letter), wd (word). */
4292
+ type: 'el' | 'lt' | 'wd';
4293
+ /** Whether to iterate backwards. */
4294
+ backwards?: boolean;
4295
+ /** Timing interval (percentage of total duration, in 1000ths). */
4296
+ tmPct?: number;
4297
+ /** Absolute timing interval in ms. */
4298
+ tmAbs?: number;
4299
+ }
4300
+ /** Build type for text build (paragraph/word/letter) animations from `p:bldP/@build`. */
4301
+ type PptxTextBuildType = 'allAtOnce' | 'byParagraph' | 'byWord' | 'byChar';
4302
+ /** Direction for fly-in / fly-out / wipe effects. */
4303
+ type PptxAnimationDirection = 'fromLeft' | 'fromRight' | 'fromTop' | 'fromBottom' | 'fromTopLeft' | 'fromTopRight' | 'fromBottomLeft' | 'fromBottomRight';
4304
+ /** Sequence mode for paragraph-level animations. */
4305
+ type PptxAnimationSequence = 'asOne' | 'byParagraph' | 'byWord' | 'byLetter';
4306
+ /** Behavior after animation finishes. */
4307
+ type PptxAfterAnimationAction = 'none' | 'hideOnNextClick' | 'hideAfterAnimation' | 'dimToColor';
4308
+ /**
4309
+ * High-level animation data associated with a slide element.
4310
+ *
4311
+ * Combines entrance, exit, and emphasis presets with timing and
4312
+ * trigger configuration. Used by the editor’s animation panel
4313
+ * and the `setPptxElementAnimation` tool.
4314
+ *
4315
+ * @example
4316
+ * ```ts
4317
+ * const anim: PptxElementAnimation = {
4318
+ * elementId: "title_1",
4319
+ * entrance: "fadeIn",
4320
+ * durationMs: 600,
4321
+ * order: 1,
4322
+ * trigger: "afterPrevious",
4323
+ * };
4324
+ * // => { elementId: "title_1", entrance: "fadeIn", durationMs: 600, order: 1, trigger: "afterPrevious" }
4325
+ * ```
4326
+ */
4327
+ interface PptxElementAnimation {
4328
+ elementId: string;
4329
+ entrance?: PptxAnimationPreset;
4330
+ exit?: PptxAnimationPreset;
4331
+ emphasis?: PptxAnimationPreset;
4332
+ durationMs?: number;
4333
+ delayMs?: number;
4334
+ order?: number;
4335
+ trigger?: PptxAnimationTrigger;
4336
+ /** Shape ID that triggers this animation when clicked (interactive sequence). */
4337
+ triggerShapeId?: string;
4338
+ timingCurve?: PptxAnimationTimingCurve;
4339
+ repeatCount?: number;
4340
+ repeatMode?: PptxAnimationRepeatMode;
4341
+ /** Direction for directional effects (fly in/out, wipe, etc.). */
4342
+ direction?: PptxAnimationDirection;
4343
+ /** Sequence mode — animate as one object or by paragraph/word/letter. */
4344
+ sequence?: PptxAnimationSequence;
4345
+ /** What happens after the animation finishes playing. */
4346
+ afterAnimation?: PptxAfterAnimationAction;
4347
+ /** Dim-to color hex (used when afterAnimation is "dimToColor"). */
4348
+ afterAnimationColor?: string;
4349
+ /** SVG motion path string for custom motion path animations. */
4350
+ motionPath?: string;
4351
+ /**
4352
+ * Path edit mode for `p:animMotion/@pathEditMode`. Defaults to "relative"
4353
+ * when emitted without an explicit value.
4354
+ */
4355
+ motionPathEditMode?: string;
4356
+ /** Comma-separated point-types string for `p:animMotion/@ptsTypes`. */
4357
+ motionPtsTypes?: string;
4358
+ /** Sound relationship ID to play when animation triggers (`p:stSnd`). */
4359
+ soundRId?: string;
4360
+ /** Resolved sound file path from relationship. */
4361
+ soundPath?: string;
4362
+ /** Whether to stop any currently playing sound (`p:endSnd`). */
4363
+ stopSound?: boolean;
163
4364
  }
164
4365
 
165
4366
  /**
166
- * Image types: effects, crop shapes, and properties shared by image/picture
167
- * elements.
4367
+ * Metadata types: slide comments, compatibility warnings, tags,
4368
+ * custom properties, core/app document properties.
168
4369
  *
169
- * @module pptx-types/image
4370
+ * @module pptx-types/metadata
170
4371
  */
4372
+
171
4373
  /**
172
- * Blend mode for `a:blend` container nodes inside an `a:effectDag` (CT_BlendEffect).
4374
+ * A slide comment — may be a legacy positional comment or a modern
4375
+ * threaded comment with replies.
173
4376
  *
174
- * Per ECMA-376 §20.1.8.10, valid values are: `darken`, `lighten`, `mult`,
175
- * `over`, `screen`.
4377
+ * @example
4378
+ * ```ts
4379
+ * const comment: PptxComment = {
4380
+ * id: "c1",
4381
+ * text: "Please update this chart.",
4382
+ * author: "Alice",
4383
+ * createdAt: "2024-06-01T10:00:00Z",
4384
+ * resolved: false,
4385
+ * };
4386
+ * // => satisfies PptxComment
4387
+ * ```
176
4388
  */
177
- type EffectDagBlendMode = 'darken' | 'lighten' | 'mult' | 'over' | 'screen';
4389
+ interface PptxComment {
4390
+ id: string;
4391
+ text: string;
4392
+ /** Storage vocabulary used by this comment. Omitted means legacy PresentationML. */
4393
+ format?: 'legacy' | 'modern';
4394
+ /** Stable GUID author identifier used by Office 2021 modern comments. */
4395
+ authorId?: string;
4396
+ /** Optional parent comment id for reply threading metadata. */
4397
+ parentId?: string;
4398
+ author?: string;
4399
+ createdAt?: string;
4400
+ x?: number;
4401
+ y?: number;
4402
+ /** Whether this comment has been resolved/marked done. */
4403
+ resolved?: boolean;
4404
+ /** Native p188 status token. */
4405
+ status?: 'active' | 'resolved' | 'closed';
4406
+ /** Modern comment classification tags and author IDs that liked the comment. */
4407
+ tags?: string[];
4408
+ likes?: string[];
4409
+ startDate?: string;
4410
+ dueDate?: string;
4411
+ assignedTo?: string[];
4412
+ /** Task completion in thousandths of a percent, from 0 through 100000. */
4413
+ complete?: number;
4414
+ priority?: number;
4415
+ title?: string;
4416
+ /** Modern threaded comment support (p15:threadingInfo). */
4417
+ threadId?: string;
4418
+ /** Replies to this comment (for modern threaded comments). */
4419
+ replies?: PptxComment[];
4420
+ /** ID of the element this comment is associated with (if any). */
4421
+ elementId?: string;
4422
+ /** Original `p:cm` subtree, retained for unknown child and extension preservation. */
4423
+ rawXml?: XmlObject;
4424
+ }
178
4425
  /**
179
- * Container node kind inside an `a:effectDag` (CT_EffectContainer @type).
4426
+ * A compatibility warning generated during parse or save when the
4427
+ * file uses features not fully supported by the editor.
180
4428
  *
181
- * Per ECMA-376 §20.1.8.20, `sib` (sibling) draws each child independently
182
- * over the same source; `tree` (tree) chains effects so each sees the output
183
- * of its siblings.
4429
+ * @example
4430
+ * ```ts
4431
+ * const warning: PptxCompatibilityWarning = {
4432
+ * code: "UNSUPPORTED_3D",
4433
+ * message: "3D rotation effects may not render accurately.",
4434
+ * severity: "warning",
4435
+ * scope: "element",
4436
+ * slideId: "slide-1",
4437
+ * elementId: "elem-42",
4438
+ * };
4439
+ * // => satisfies PptxCompatibilityWarning
4440
+ * ```
184
4441
  */
185
- type EffectDagContainerType = 'sib' | 'tree';
4442
+ interface PptxCompatibilityWarning {
4443
+ code: string;
4444
+ message: string;
4445
+ severity: 'info' | 'warning';
4446
+ scope: 'presentation' | 'slide' | 'element' | 'save';
4447
+ slideId?: string;
4448
+ elementId?: string;
4449
+ xmlPath?: string;
4450
+ }
4451
+
186
4452
  /**
187
- * Typed model of the directed-acyclic effect graph stored in `a:effectDag`.
4453
+ * Slide transition types and the {@link PptxSlideTransition} data structure.
188
4454
  *
189
- * The four "structural" container/transform nodes are typed; any other inner
190
- * effect (e.g. `a:outerShdw`, `a:glow`, `a:alphaInv`) is preserved verbatim
191
- * as a raw XML object via the {@link EffectDagRawLeaf} variant so we never
192
- * have to recurse into the full effect taxonomy.
4455
+ * Represents the `<p:transition>` element on each slide, including
4456
+ * transition type, duration, direction, and advance timing.
4457
+ *
4458
+ * @module pptx-types/transition
4459
+ */
4460
+
4461
+ /**
4462
+ * Available slide transition effects.
4463
+ *
4464
+ * Maps to the OOXML child element names under `<p:transition>` / `<p14:transition>`.
4465
+ *
4466
+ * @example
4467
+ * ```ts
4468
+ * const t: PptxTransitionType = "morph";
4469
+ * // => "morph" — one of 40+ transition effects
4470
+ * ```
4471
+ */
4472
+ type PptxTransitionType = 'none' | 'cut' | 'fade' | 'push' | 'wipe' | 'split' | 'randomBar' | 'blinds' | 'checker' | 'circle' | 'comb' | 'cover' | 'diamond' | 'dissolve' | 'plus' | 'pull' | 'random' | 'strips' | 'uncover' | 'wedge' | 'wheel' | 'zoom' | 'newsflash' | 'morph' | 'conveyor' | 'doors' | 'ferris' | 'flash' | 'flythrough' | 'gallery' | 'glitter' | 'honeycomb' | 'pan' | 'prism' | 'reveal' | 'ripple' | 'shred' | 'switch' | 'vortex' | 'warp' | 'wheelReverse' | 'window' | 'cube' | 'flip' | 'rotate' | 'orbit';
4473
+ /** Split orientation from OOXML `@_orient`. */
4474
+ type PptxSplitOrientation = 'horz' | 'vert';
4475
+ /** Schema-defined `ST_TransitionSpeed` values. */
4476
+ type PptxTransitionSpeed = 'slow' | 'med' | 'fast';
4477
+ /**
4478
+ * Slide transition configuration.
193
4479
  *
194
4480
  * @example
195
4481
  * ```ts
196
- * // <a:effectDag>
197
- * // <a:cont type="sib">
198
- * // <a:blend blend="mult"><a:cont type="tree" /></a:blend>
199
- * // </a:cont>
200
- * // </a:effectDag>
201
- * const dag: EffectDagContainer = {
202
- * kind: "cont",
203
- * type: "sib",
204
- * children: [{
205
- * kind: "blend",
206
- * mode: "mult",
207
- * container: { kind: "cont", type: "tree", children: [] },
208
- * }],
4482
+ * const transition: PptxSlideTransition = {
4483
+ * type: "fade",
4484
+ * durationMs: 700,
4485
+ * advanceOnClick: true,
4486
+ * advanceAfterMs: 5000,
209
4487
  * };
4488
+ * // => { type: "fade", durationMs: 700, advanceOnClick: true, advanceAfterMs: 5000 }
210
4489
  * ```
211
4490
  */
212
- type EffectDagNode = EffectDagContainer | EffectDagBlend | EffectDagXfrm | EffectDagRelOff | EffectDagRawLeaf;
213
- /** `a:cont` — CT_EffectContainer. Recursive; mirrors the top-level `effectDag`. */
214
- interface EffectDagContainer {
215
- kind: 'cont';
216
- /** `@type` — `sib` or `tree`. */
217
- type: EffectDagContainerType;
218
- /** Optional `@name` attribute. */
219
- name?: string;
220
- /** Ordered children. */
221
- children: EffectDagNode[];
4491
+ interface PptxSlideTransition {
4492
+ type: PptxTransitionType;
4493
+ /** Schema-defined transition speed. Defaults to `fast` when omitted. */
4494
+ speed?: PptxTransitionSpeed;
4495
+ durationMs?: number;
4496
+ direction?: string;
4497
+ advanceOnClick?: boolean;
4498
+ advanceAfterMs?: number;
4499
+ /** Number of spokes for wheel transition (1-8). */
4500
+ spokes?: number;
4501
+ /** Pattern type for shred transition. */
4502
+ pattern?: string;
4503
+ /** Through-black flag for blinds/checker (OOXML `@_thruBlk`). */
4504
+ thruBlk?: boolean;
4505
+ /** Split orientation (horz/vert) parsed from `@_orient`. */
4506
+ orient?: PptxSplitOrientation;
4507
+ /** Relationship ID of transition sound from `p:sndAc/p:stSnd/@r:embed` when present. */
4508
+ soundRId?: string;
4509
+ /** Embedded WAV display name from `p:stSnd/p:snd/@name`. */
4510
+ soundName?: string;
4511
+ /** Whether the transition sound repeats until another sound starts. */
4512
+ soundLoop?: boolean;
4513
+ /** Resolved transition sound media path within the package. */
4514
+ soundPath?: string;
4515
+ /** Human-readable sound file name (extracted from soundPath). */
4516
+ soundFileName?: string;
4517
+ /**
4518
+ * When true, the transition stops the currently-playing sound (OOXML `p:sndAc/p:endSnd`).
4519
+ * Mutually exclusive with `soundRId`/`soundPath` (which use `p:stSnd`).
4520
+ */
4521
+ stopSound?: boolean;
4522
+ /** Preserved sound-action XML node from `p:sndAc` for lossless round-trip. */
4523
+ rawSoundAction?: XmlObject;
4524
+ /** Preserved extension-list XML node from `p:extLst` within the transition for lossless round-trip. */
4525
+ rawExtLst?: XmlObject;
4526
+ /** Original transition node, retained to preserve unknown attributes and children. */
4527
+ rawTransition?: XmlObject;
222
4528
  }
223
- /** `a:blend` — CT_BlendEffect. Always wraps a single `a:cont` child. */
224
- interface EffectDagBlend {
225
- kind: 'blend';
226
- /** `@blend` attribute. */
227
- mode: EffectDagBlendMode;
228
- /** Required child `a:cont` container. */
229
- container: EffectDagContainer;
4529
+
4530
+ /**
4531
+ * A customer data reference from `p:custDataLst / p:custData`.
4532
+ *
4533
+ * Enterprise add-ins and integrations store custom data parts in the
4534
+ * package and reference them via relationship IDs in the slide or
4535
+ * presentation XML.
4536
+ *
4537
+ * @see ECMA-376 Part 1, §19.2.1.3 (custDataLst), §19.3.1.6 (custData)
4538
+ */
4539
+ interface PptxCustomerData {
4540
+ /** Resolved part path inside the package (e.g. `ppt/customerData/item1.xml`). */
4541
+ id: string;
4542
+ /** Relationship ID referencing the custom data part. */
4543
+ relId: string;
4544
+ /** Raw string content of the custom data part (if resolvable). */
4545
+ data?: string;
230
4546
  }
231
- /** `a:xfrmEffect` — CT_TransformEffect. Affine transform with no children. */
232
- interface EffectDagXfrm {
233
- kind: 'xfrmEffect';
234
- /** Horizontal scale, percentage * 1000 (e.g. 100000 = 100%). */
235
- sx?: number;
236
- /** Vertical scale, percentage * 1000. */
237
- sy?: number;
238
- /** Horizontal skew, degrees * 60000. */
239
- kx?: number;
240
- /** Vertical skew, degrees * 60000. */
241
- ky?: number;
242
- /** Horizontal translation in EMU. */
243
- tx?: number;
244
- /** Vertical translation in EMU. */
245
- ty?: number;
4547
+ /**
4548
+ * An ActiveX control reference from `p:controls / p:control`.
4549
+ *
4550
+ * ActiveX form controls (buttons, text boxes, check boxes, combo boxes, etc.)
4551
+ * are embedded via OLE parts and referenced by relationship ID in the slide XML.
4552
+ *
4553
+ * @see ECMA-376 Part 1, §19.3.1.3 (controls), §19.3.1.2 (control)
4554
+ */
4555
+ interface PptxActiveXControl {
4556
+ /** Relationship ID referencing the ActiveX binary part. */
4557
+ relId: string;
4558
+ /** Control name from @name attribute. */
4559
+ name?: string;
4560
+ /** Shape ID this control is linked to (from @spid). */
4561
+ shapeId?: string;
4562
+ /** Raw XML for round-trip preservation. */
4563
+ rawXml?: XmlObject;
246
4564
  }
247
- /** `a:relOff` — CT_RelativeOffsetEffect. Relative offset in 1000ths of a percent. */
248
- interface EffectDagRelOff {
249
- kind: 'relOff';
250
- /** Horizontal offset, percentage * 1000. */
251
- tx?: number;
252
- /** Vertical offset, percentage * 1000. */
253
- ty?: number;
4565
+ /**
4566
+ * Pattern fill on a slide background.
4567
+ *
4568
+ * Mirrors the `<a:pattFill>` choice inside `<p:bgPr>`. Renderers should
4569
+ * draw a 2-colour preset pattern (e.g. `dkDnDiag`, `pct50`).
4570
+ *
4571
+ * ECMA-376 §20.1.8.47.
4572
+ *
4573
+ * @example
4574
+ * ```ts
4575
+ * const pattern: PptxSlideBackgroundPattern = {
4576
+ * preset: "ltDnDiag",
4577
+ * fgColor: "#4472C4",
4578
+ * bgColor: "#FFFFFF",
4579
+ * };
4580
+ * // => satisfies PptxSlideBackgroundPattern
4581
+ * ```
4582
+ */
4583
+ interface PptxSlideBackgroundPattern {
4584
+ /** DrawingML preset pattern token (`@_prst`). */
4585
+ preset: string;
4586
+ /** Foreground colour resolved to `#RRGGBB`. */
4587
+ fgColor?: string;
4588
+ /** Background colour resolved to `#RRGGBB`. */
4589
+ bgColor?: string;
254
4590
  }
255
4591
  /**
256
- * Catch-all leaf preserving any non-container effect (e.g. `a:outerShdw`,
257
- * `a:glow`, `a:alphaInv`) as raw XML. Re-emitted verbatim on save.
4592
+ * A single slide in a parsed PPTX presentation.
4593
+ *
4594
+ * Contains the element tree, background settings, notes, comments,
4595
+ * transition / animation data, and metadata like layout path and section.
4596
+ *
4597
+ * @example
4598
+ * ```ts
4599
+ * const slide: PptxSlide = {
4600
+ * id: "slide1",
4601
+ * rId: "rId2",
4602
+ * slideNumber: 1,
4603
+ * elements: [titleTextBox, subtitleTextBox],
4604
+ * backgroundColor: "#FFFFFF",
4605
+ * notes: "Remember to mention quarterly goals.",
4606
+ * };
4607
+ * // => satisfies PptxSlide
4608
+ * ```
258
4609
  */
259
- interface EffectDagRawLeaf {
260
- kind: 'raw';
261
- /** Local element name without the `a:` prefix (e.g. `outerShdw`, `glow`). */
262
- tag: string;
263
- /** Raw XML object captured at load — preserved verbatim on save. */
264
- xml: Record<string, unknown>;
4610
+ interface PptxSlide {
4611
+ id: string;
4612
+ rId: string;
4613
+ sourceSlideId?: string;
4614
+ /** Optional author-supplied slide name (set via `SlideBuilder.setName`). */
4615
+ name?: string;
4616
+ layoutPath?: string;
4617
+ layoutName?: string;
4618
+ slideNumber: number;
4619
+ hidden?: boolean;
4620
+ sectionName?: string;
4621
+ sectionId?: string;
4622
+ elements: PptxElement[];
4623
+ backgroundColor?: string;
4624
+ backgroundImage?: string;
4625
+ backgroundGradient?: string;
4626
+ /**
4627
+ * Pattern fill on the slide background (`<a:pattFill>` inside `<p:bgPr>`).
4628
+ *
4629
+ * When present, renderers should draw a real two-colour pattern using
4630
+ * the named DrawingML preset (e.g. `"ltDnDiag"`, `"pct50"`). The flat
4631
+ * `backgroundColor` field is left set to the foreground colour for
4632
+ * fallback rendering paths that don't understand patterns.
4633
+ *
4634
+ * ECMA-376 §20.1.8.47.
4635
+ */
4636
+ backgroundPattern?: PptxSlideBackgroundPattern;
4637
+ /**
4638
+ * `<p:bgPr/@shadeToTitle>` — boolean flag instructing the renderer to
4639
+ * shade the background toward the title placeholder colour. Captured
4640
+ * for lossless round-trip; the React renderer currently treats it as
4641
+ * a passthrough hint.
4642
+ *
4643
+ * ECMA-376 §19.3.1.2 (CT_BackgroundProperties).
4644
+ */
4645
+ backgroundShadeToTitle?: boolean;
4646
+ transition?: PptxSlideTransition;
4647
+ animations?: PptxElementAnimation[];
4648
+ /** Native OOXML animation data parsed from `p:timing`. */
4649
+ nativeAnimations?: PptxNativeAnimation[];
4650
+ /** Preserved raw `p:timing` XML for lossless round-trip of native animations. */
4651
+ rawTiming?: XmlObject;
4652
+ notes?: string;
4653
+ /** Rich text segments for the slide notes (preserves formatting). */
4654
+ notesSegments?: TextSegment[];
4655
+ /**
4656
+ * Parsed shapes from the notes slide's `<p:cSld>/<p:spTree>` so the full
4657
+ * notes-page shape tree can be inspected and mutated, not just the body
4658
+ * placeholder text. When undefined, the existing notes XML is left
4659
+ * untouched on save and only `notes` / `notesSegments` are written.
4660
+ */
4661
+ notesShapes?: PptxElement[];
4662
+ /**
4663
+ * Per-notes-slide colour map override parsed from `<p:notes>/<p:clrMapOvr>`.
4664
+ * Captured for lossless round-trip of the notes-slide's colour scheme.
4665
+ */
4666
+ notesClrMapOverride?: Record<string, string>;
4667
+ /** Optional `<p:cSld @name>` value of the notes slide, for round-trip. */
4668
+ notesCSldName?: string;
4669
+ comments?: PptxComment[];
4670
+ /** Source package metadata for an Office 2021 p188 comment part. */
4671
+ modernCommentPart?: PptxModernCommentPart;
4672
+ warnings?: PptxCompatibilityWarning[];
4673
+ rawXml?: XmlObject;
4674
+ /** Per-slide colour map override parsed from `p:clrMapOvr`. */
4675
+ clrMapOverride?: Record<string, string>;
4676
+ /** Whether background animations should play (`p:bg/@showAnimation`). */
4677
+ backgroundShowAnimation?: boolean;
4678
+ /** Whether master slide shapes should be shown on this slide (`p:sld/@showMasterSp`). */
4679
+ showMasterShapes?: boolean;
4680
+ /** Drawing guides parsed from slide extension list. */
4681
+ guides?: PptxDrawingGuide[];
4682
+ /** When explicitly `false`, the slide is unmodified and save can skip re-serialization. */
4683
+ isDirty?: boolean;
4684
+ /** Customer data references from `p:custDataLst` on this slide. */
4685
+ customerData?: PptxCustomerData[];
4686
+ /** ActiveX control references from `p:controls` on this slide. */
4687
+ activeXControls?: PptxActiveXControl[];
4688
+ /** Per-slide header/footer flags from `<p:hf>` (P-H3). */
4689
+ headerFooterFlags?: PptxHeaderFooterFlags;
4690
+ /** Server-backed slide synchronization metadata stored in a related OPC part. */
4691
+ slideSynchronization?: PptxSlideSyncProperties;
265
4692
  }
266
- declare module "./index" {
267
- interface TextStyle {
268
- /**
269
- * Raw `a:effectDag` XML node from `a:rPr`, preserved verbatim for
270
- * round-trip serialisation. Mirrors the shape-level
271
- * {@link import('./shape-style').ShapeStyle.effectDagXml} field.
272
- */
273
- textEffectDagXml?: XmlObject;
274
- /**
275
- * Typed effect graph parsed from `textEffectDagXml`. The four structural
276
- * container nodes (`a:cont`, `a:blend`, `a:xfrmEffect`, `a:relOff`) are
277
- * fully typed; any other leaf effect is captured as
278
- * {@link EffectDagRawLeaf} so we never have to recurse into the full
279
- * effect taxonomy.
280
- */
281
- textEffectDagTree?: EffectDagContainer;
282
- }
4693
+ interface PptxModernCommentPart {
4694
+ path: string;
4695
+ relationshipId: string;
4696
+ /** Original p188:cmLst root, including unknown attributes and extensions. */
4697
+ rawXml?: XmlObject;
283
4698
  }
284
- declare module "./index" {
285
- interface ShapeStyle {
286
- /**
287
- * Typed effect graph parsed from {@link ShapeStyle.effectDagXml}. The four
288
- * structural container nodes (`a:cont`, `a:blend`, `a:xfrmEffect`,
289
- * `a:relOff`) are fully typed; any other leaf effect (e.g. `a:outerShdw`,
290
- * `a:glow`, `a:alphaInv`) is captured as {@link EffectDagRawLeaf} so we
291
- * never have to recurse into the full effect taxonomy.
292
- */
293
- effectDagTree?: EffectDagContainer;
294
- }
4699
+ /** Metadata from a `p:sldSyncPr` slide synchronization data part. */
4700
+ interface PptxSlideSyncProperties {
4701
+ serverSlideId: string;
4702
+ serverSlideModifiedTime: string;
4703
+ clientInsertedTime: string;
4704
+ extensionList?: XmlObject;
4705
+ rawXml?: XmlObject;
4706
+ partPath?: string;
4707
+ relationshipId?: string;
295
4708
  }
296
4709
 
297
4710
  /**
@@ -307,6 +4720,102 @@ interface CanvasSize {
307
4720
  width: number;
308
4721
  height: number;
309
4722
  }
4723
+ /** Viewer interaction mode: read-only, edit, presentation, or master-view. */
4724
+ type ViewerMode = 'preview' | 'edit' | 'present' | 'master';
4725
+ /**
4726
+ * Framework-agnostic imperative API contract for the PowerPoint viewer.
4727
+ *
4728
+ * Each binding (React `forwardRef` handle, Vue `defineExpose`, Angular public
4729
+ * methods) implements this interface so consumers get a consistent progressive
4730
+ * API regardless of framework.
4731
+ */
4732
+ interface PowerPointViewerAPI {
4733
+ /** Serialise the current presentation to `.pptx` bytes. */
4734
+ getContent: () => Promise<Uint8Array>;
4735
+ /** Navigate to a specific slide by zero-based index. */
4736
+ goTo: (slideIndex: number) => void;
4737
+ /** Navigate to the previous slide. */
4738
+ goPrev: () => void;
4739
+ /** Navigate to the next slide. */
4740
+ goNext: () => void;
4741
+ /** Undo the last editing action. No-op when nothing to undo. */
4742
+ undo: () => void;
4743
+ /** Redo the last undone action. No-op when nothing to redo. */
4744
+ redo: () => void;
4745
+ /** Whether an undo action is available. */
4746
+ canUndo: () => boolean;
4747
+ /** Whether a redo action is available. */
4748
+ canRedo: () => boolean;
4749
+ /** Get the current zoom level (1 = 100%). */
4750
+ getZoom: () => number;
4751
+ /** Set the zoom level (clamped to min/max bounds). */
4752
+ setZoom: (level: number) => void;
4753
+ /** Zoom in by one step. */
4754
+ zoomIn: () => void;
4755
+ /** Zoom out by one step. */
4756
+ zoomOut: () => void;
4757
+ /** Reset zoom to 100%. */
4758
+ zoomReset: () => void;
4759
+ /** Get the current viewer mode. */
4760
+ getMode: () => ViewerMode;
4761
+ /** Switch the viewer mode (e.g. 'edit', 'preview', 'present'). */
4762
+ setMode: (mode: ViewerMode) => void;
4763
+ /** Get the zero-based active slide index. */
4764
+ getActiveSlideIndex: () => number;
4765
+ /** Set the active slide by zero-based index (alias of goTo). */
4766
+ setActiveSlideIndex: (index: number) => void;
4767
+ /** Get the total number of slides. */
4768
+ getSlideCount: () => number;
4769
+ /** Whether the document has unsaved changes. */
4770
+ isDirty: () => boolean;
4771
+ /**
4772
+ * Get the full slide array. Returns the actual `PptxSlide[]` from the
4773
+ * internal model with full type information (elements, notes, transitions,
4774
+ * animations, etc.). The returned reference is a snapshot; mutations are
4775
+ * not reflected back unless done via the manipulation methods.
4776
+ */
4777
+ getSlides: () => readonly PptxSlide[];
4778
+ /** Get a single slide by zero-based index, or undefined if out of range. */
4779
+ getSlide: (index: number) => PptxSlide | undefined;
4780
+ /** Get the currently active slide. */
4781
+ getActiveSlide: () => PptxSlide | undefined;
4782
+ /** Add a blank slide after the given index (or at end if omitted). */
4783
+ addSlide: (afterIndex?: number) => void;
4784
+ /** Delete slides at the given zero-based indexes. At least one slide is kept. */
4785
+ deleteSlides: (indexes: number[]) => void;
4786
+ /** Duplicate slides at the given zero-based indexes. */
4787
+ duplicateSlides: (indexes: number[]) => void;
4788
+ /** Move a slide from one position to another. */
4789
+ moveSlide: (fromIndex: number, toIndex: number) => void;
4790
+ /** Toggle the hidden flag on slides at the given indexes. */
4791
+ toggleHideSlides: (indexes: number[]) => void;
4792
+ /**
4793
+ * Get the elements on a slide. Defaults to the active slide when
4794
+ * `slideIndex` is omitted. Returns the full `PptxElement[]` with
4795
+ * all type-specific properties intact.
4796
+ */
4797
+ getElements: (slideIndex?: number) => readonly PptxElement[];
4798
+ /** Get a single element by ID from the active slide (or a specified slide). */
4799
+ getElementById: (elementId: string, slideIndex?: number) => PptxElement | undefined;
4800
+ /**
4801
+ * Update one or more properties of an element by ID on the active slide.
4802
+ * Accepts a `Partial<PptxElement>` patch (e.g. `{ x: 100, width: 300 }`).
4803
+ */
4804
+ updateElement: (elementId: string, updates: Partial<PptxElement>) => void;
4805
+ /** Delete elements by their IDs from the active slide. */
4806
+ deleteElements: (elementIds: string[]) => void;
4807
+ /**
4808
+ * Duplicate an element on the active slide.
4809
+ * Returns the new element's ID, or undefined if the source was not found.
4810
+ */
4811
+ duplicateElement: (elementId: string) => string | undefined;
4812
+ /** Get the IDs of currently selected elements. */
4813
+ getSelectedElementIds: () => string[];
4814
+ /** Programmatically select elements by their IDs. */
4815
+ selectElements: (ids: string[]) => void;
4816
+ /** Clear the current selection. */
4817
+ clearSelection: () => void;
4818
+ }
310
4819
  /** Collaboration role within a session. */
311
4820
  type CollaborationRole = 'owner' | 'collaborator' | 'viewer';
312
4821
  /**
@@ -319,10 +4828,12 @@ type CollaborationRole = 'owner' | 'collaborator' | 'viewer';
319
4828
  * any signaling server, which makes this mode usable from static hosting.
320
4829
  */
321
4830
  type CollaborationTransport = 'websocket' | 'webrtc';
4831
+ /** How the local user entered a collaboration session. */
4832
+ type CollaborationSessionIntent = 'create' | 'join';
322
4833
  /**
323
4834
  * Real-time collaboration configuration.
324
4835
  *
325
- * The same shape is accepted by the React, Vue, and Angular bindings.
4836
+ * The same shape is accepted by every framework binding.
326
4837
  */
327
4838
  interface CollaborationConfig {
328
4839
  /** Unique identifier for the collaboration room (alphanumeric, hyphens, underscores). */
@@ -350,6 +4861,13 @@ interface CollaborationConfig {
350
4861
  authToken?: string;
351
4862
  /** Role in the session; defaults to `'collaborator'`. */
352
4863
  role?: CollaborationRole;
4864
+ /**
4865
+ * Whether this client created the room or joined an existing room. Providers
4866
+ * do not use this value, but hosts can use it to avoid publishing local file
4867
+ * bytes when handling a join request. Omitted values retain the legacy
4868
+ * create-session behaviour.
4869
+ */
4870
+ sessionIntent?: CollaborationSessionIntent;
353
4871
  /**
354
4872
  * Elected-writer write-back callback (Area 3 of the C3 hardening plan).
355
4873
  *
@@ -367,6 +4885,19 @@ interface CollaborationConfig {
367
4885
  */
368
4886
  writeBackDebounceMs?: number;
369
4887
  }
4888
+ /**
4889
+ * A font supplied by the host application. The package never ships fonts:
4890
+ * applications provide a licensed URL, data URL, or blob URL for their users.
4891
+ */
4892
+ interface ViewerFontSource {
4893
+ family: string;
4894
+ src: string;
4895
+ format?: 'truetype' | 'opentype' | 'woff' | 'woff2';
4896
+ weight?: string | number;
4897
+ style?: 'normal' | 'italic';
4898
+ }
4899
+ declare function parsePresentationSessionId(hash: string): string | null;
4900
+ declare function loadPresentationDeck(sessionId: string): Promise<Uint8Array | null>;
370
4901
  interface AutosaveRecord {
371
4902
  key: string;
372
4903
  data: Uint8Array;
@@ -557,6 +5088,8 @@ interface ViewerLoadDetail {
557
5088
  interface PowerPointViewerProps {
558
5089
  /** PowerPoint content as `Uint8Array` (or `ArrayBuffer`). */
559
5090
  source: Uint8Array | ArrayBuffer | null | undefined;
5091
+ /** Licensed font sources supplied by the host application. */
5092
+ fonts?: ViewerFontSource[];
560
5093
  /**
561
5094
  * Theme configuration for customising the viewer's appearance. Accepts
562
5095
  * partial color overrides, a custom border-radius, and arbitrary CSS
@@ -617,6 +5150,15 @@ interface PowerPointViewerProps {
617
5150
  * to track the dirty state or mirror edits into host state.
618
5151
  */
619
5152
  onchange?: () => void;
5153
+ /** Canonical viewer contract callbacks. */
5154
+ ondirtychange?: (dirty: boolean) => void;
5155
+ oncontentchange?: (content: Uint8Array) => void;
5156
+ onmodechange?: (mode: string) => void;
5157
+ onzoomchange?: (zoom: number) => void;
5158
+ onselectionchange?: (elementIds: string[]) => void;
5159
+ onslidecountchange?: (count: number) => void;
5160
+ /** Host override for the File > Open action. */
5161
+ onopenfile?: () => void;
620
5162
  /**
621
5163
  * Enable debounced crash-recovery autosave. On each edit (when `editable`)
622
5164
  * the current slides are serialized to `.pptx` bytes and written to the
@@ -668,7 +5210,7 @@ interface PowerPointViewerProps {
668
5210
  * instance (via `bind:this`). Mirrors the vanilla binding's `EditorController`
669
5211
  * surface subset the host drives directly.
670
5212
  */
671
- interface PowerPointViewerApi {
5213
+ interface PowerPointViewerApi extends PowerPointViewerAPI {
672
5214
  /** Undo the last committed edit. */
673
5215
  undo(): void;
674
5216
  /** Redo the last undone edit. */
@@ -761,5 +5303,5 @@ declare const PowerPointViewer: Component<PowerPointViewerProps, PowerPointViewe
761
5303
  */
762
5304
  type AutosaveStatus = 'idle' | 'disabled' | 'saving' | 'saved' | 'error';
763
5305
 
764
- export { PowerPointViewer, defaultCssVars, defaultRadius, defaultThemeColors, deleteAutosaveSnapshot, getAutosaveSnapshot, listAutosaveSnapshots, registerTranslations, themeToCssVars, vermilionDarkColors, vermilionDarkTheme, vermilionLightColors, vermilionLightTheme, vermilionRadius };
5306
+ export { PowerPointViewer, defaultCssVars, defaultRadius, defaultThemeColors, deleteAutosaveSnapshot, getAutosaveSnapshot, listAutosaveSnapshots, loadPresentationDeck, parsePresentationSessionId, registerTranslations, themeToCssVars, vermilionDarkColors, vermilionDarkTheme, vermilionLightColors, vermilionLightTheme, vermilionRadius };
765
5307
  export type { AutosaveRecord, AutosaveStatus, CanvasSize, CollaborationConfig, CollaborationRole, CollaborationTransport, ExportGifOptions, ExportPdfOptions, ExportVideoOptions, PowerPointViewerApi, PowerPointViewerProps, PrintOptions, TranslationDictionary, Translator, ViewerLoadDetail, ViewerTheme, ViewerThemeColors };