@shbernal/ts-pptx 4.1.0 → 4.2.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 (139) hide show
  1. package/README.md +11 -11
  2. package/dist/anim-presets-Qbgh8uut.js +55 -0
  3. package/dist/anim-presets-Qbgh8uut.js.map +1 -0
  4. package/dist/{autopage-D4kyVp11.js → autopage-DqZ37VpL.js} +11 -12
  5. package/dist/autopage-DqZ37VpL.js.map +1 -0
  6. package/dist/{binary-string-CKVAYI3M.js → binary-string-Ba8VM3b9.js} +3 -4
  7. package/dist/binary-string-Ba8VM3b9.js.map +1 -0
  8. package/dist/{body-insets-kVHmjGc6.js → body-insets-BDHymJvz.js} +7 -9
  9. package/dist/body-insets-BDHymJvz.js.map +1 -0
  10. package/dist/browser.d.ts +24 -16
  11. package/dist/browser.d.ts.map +1 -1
  12. package/dist/browser.js +19 -19
  13. package/dist/browser.js.map +1 -1
  14. package/dist/{image-size-DwDbakcl.js → chart-metadata-CwiTTcJq.js} +576 -538
  15. package/dist/chart-metadata-CwiTTcJq.js.map +1 -0
  16. package/dist/{clip-DHDlnHUq.d.ts → clip-ISfCMtWA.d.ts} +6 -10
  17. package/dist/clip-ISfCMtWA.d.ts.map +1 -0
  18. package/dist/{notes-BcT571R4.js → comments-CKIZYRbZ.js} +517 -389
  19. package/dist/comments-CKIZYRbZ.js.map +1 -0
  20. package/dist/{diagnostics-DiMmBU8P.d.ts → diagnostics-MoA4MBq5.d.ts} +52 -50
  21. package/dist/diagnostics-MoA4MBq5.d.ts.map +1 -0
  22. package/dist/{embedded-fonts-CI_YGW2d.d.ts → embedded-fonts-U7HIIhPO.d.ts} +4 -6
  23. package/dist/embedded-fonts-U7HIIhPO.d.ts.map +1 -0
  24. package/dist/{entry-compose-6hF9aTmT.d.ts → entry-compose-CiakSt-f.d.ts} +53 -74
  25. package/dist/entry-compose-CiakSt-f.d.ts.map +1 -0
  26. package/dist/{errors-Da2nXCJm.js → entry-errors-JMthgJ2g.js} +41 -25
  27. package/dist/entry-errors-JMthgJ2g.js.map +1 -0
  28. package/dist/{table-cell-margins-PDshga8T.js → enums-BP9wsb9Q.js} +42 -45
  29. package/dist/enums-BP9wsb9Q.js.map +1 -0
  30. package/dist/{enums-DQRpVOLh.d.ts → enums-PcXr3o3J.d.ts} +11 -12
  31. package/dist/{enums-DQRpVOLh.d.ts.map → enums-PcXr3o3J.d.ts.map} +1 -1
  32. package/dist/families.d.ts +24 -26
  33. package/dist/families.d.ts.map +1 -1
  34. package/dist/families.js +3 -4
  35. package/dist/{fit-CcXbg__l.js → fit-Bpmzep6O.js} +60 -52
  36. package/dist/fit-Bpmzep6O.js.map +1 -0
  37. package/dist/{font-metrics-CBGmhLo0.d.ts → font-metrics-DTppw4t3.d.ts} +61 -37
  38. package/dist/font-metrics-DTppw4t3.d.ts.map +1 -0
  39. package/dist/{grid-9B2w5EaY.js → grid-DUIMxjfl.js} +23 -26
  40. package/dist/grid-DUIMxjfl.js.map +1 -0
  41. package/dist/{html-dom-DvJmuHt2.js → html-dom-LZCgntnJ.js} +42 -43
  42. package/dist/html-dom-LZCgntnJ.js.map +1 -0
  43. package/dist/html.d.ts +53 -9
  44. package/dist/html.d.ts.map +1 -1
  45. package/dist/html.js +12 -13
  46. package/dist/html.js.map +1 -1
  47. package/dist/index.d.ts +21 -13
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +15 -15
  50. package/dist/index.js.map +1 -1
  51. package/dist/inspect.d.ts +14 -16
  52. package/dist/inspect.d.ts.map +1 -1
  53. package/dist/inspect.js +18 -19
  54. package/dist/inspect.js.map +1 -1
  55. package/dist/{text-anchor-BgLPbwbL.js → lock-attrs-CSQnFDHP.js} +62 -12
  56. package/dist/lock-attrs-CSQnFDHP.js.map +1 -0
  57. package/dist/math.d.ts +2 -4
  58. package/dist/math.d.ts.map +1 -1
  59. package/dist/math.js +12 -13
  60. package/dist/math.js.map +1 -1
  61. package/dist/measure.d.ts +23 -12
  62. package/dist/measure.d.ts.map +1 -1
  63. package/dist/measure.js +3 -3
  64. package/dist/node.d.ts +21 -13
  65. package/dist/node.d.ts.map +1 -1
  66. package/dist/node.js +12 -12
  67. package/dist/node.js.map +1 -1
  68. package/dist/{options-internal-WqgMf720.js → options-internal-BWgmLPdx.js} +4 -5
  69. package/dist/options-internal-BWgmLPdx.js.map +1 -0
  70. package/dist/{package-KoEgVwII.d.ts → package-CANBWuSm.d.ts} +4 -12
  71. package/dist/package-CANBWuSm.d.ts.map +1 -0
  72. package/dist/{playbtn-CUqQdoDf.js → playbtn-BQZFJir9.js} +4 -5
  73. package/dist/playbtn-BQZFJir9.js.map +1 -0
  74. package/dist/{pres-BA9_lJbY.d.ts → pres-BkEkUAEM.d.ts} +383 -230
  75. package/dist/pres-BkEkUAEM.d.ts.map +1 -0
  76. package/dist/{presentation-Cyl74rq2.js → presentation-4Ggq0_Xa.js} +408 -288
  77. package/dist/presentation-4Ggq0_Xa.js.map +1 -0
  78. package/dist/{presentation-types-B3VQH4Bz.d.ts → presentation-types-BgnZR-0a.d.ts} +1104 -457
  79. package/dist/presentation-types-BgnZR-0a.d.ts.map +1 -0
  80. package/dist/read.d.ts +18 -13
  81. package/dist/read.d.ts.map +1 -1
  82. package/dist/read.js +4 -4
  83. package/dist/script.d.ts +116 -65
  84. package/dist/script.d.ts.map +1 -1
  85. package/dist/script.js +2697 -777
  86. package/dist/script.js.map +1 -1
  87. package/dist/{shapes-BcyFdZpp.js → shapes-CAPOjU0Q.js} +1556 -487
  88. package/dist/shapes-CAPOjU0Q.js.map +1 -0
  89. package/dist/{slide-BqPtyKmb.d.ts → slide-BmT4kMoO.d.ts} +94 -86
  90. package/dist/slide-BmT4kMoO.d.ts.map +1 -0
  91. package/dist/{slide-size-BalTjFuv.js → slide-size-SkScz1ig.js} +2 -3
  92. package/dist/{slide-size-BalTjFuv.js.map → slide-size-SkScz1ig.js.map} +1 -1
  93. package/dist/{table-dom-CVbvUfgh.js → table-dom-BYga4FYY.js} +3 -4
  94. package/dist/{table-dom-CVbvUfgh.js.map → table-dom-BYga4FYY.js.map} +1 -1
  95. package/dist/{text-BvFFMMFQ.js → text-CU08xJGs.js} +365 -318
  96. package/dist/text-CU08xJGs.js.map +1 -0
  97. package/dist/{transition-speed-kUEWDWTx.js → transition-speed-CNJ0fSpQ.js} +2 -3
  98. package/dist/{transition-speed-kUEWDWTx.js.map → transition-speed-CNJ0fSpQ.js.map} +1 -1
  99. package/dist/{units-internal-DFcUYjh3.js → units-internal-BR3a4cIi.js} +26 -29
  100. package/dist/units-internal-BR3a4cIi.js.map +1 -0
  101. package/dist/{zip-CYZ0F6BV.js → zip-7JTh61LX.js} +8 -10
  102. package/dist/zip-7JTh61LX.js.map +1 -0
  103. package/dist/{zip-CTll_dr0.d.ts → zip-uUjs9Cqx.d.ts} +4 -6
  104. package/dist/zip-uUjs9Cqx.d.ts.map +1 -0
  105. package/dist/zip.d.ts +3 -3
  106. package/dist/zip.js +3 -3
  107. package/dist/{zoom-BoNyOlPm.js → zoom-CSSeOwM8.js} +1153 -583
  108. package/dist/zoom-CSSeOwM8.js.map +1 -0
  109. package/package.json +20 -21
  110. package/skills/{ts-pptx-upstream → pptx-ts-upstream}/SKILL.md +27 -74
  111. package/dist/autopage-D4kyVp11.js.map +0 -1
  112. package/dist/binary-string-CKVAYI3M.js.map +0 -1
  113. package/dist/body-insets-kVHmjGc6.js.map +0 -1
  114. package/dist/clip-DHDlnHUq.d.ts.map +0 -1
  115. package/dist/diagnostics-DiMmBU8P.d.ts.map +0 -1
  116. package/dist/embedded-fonts-CI_YGW2d.d.ts.map +0 -1
  117. package/dist/entry-compose-6hF9aTmT.d.ts.map +0 -1
  118. package/dist/errors-Da2nXCJm.js.map +0 -1
  119. package/dist/fit-CcXbg__l.js.map +0 -1
  120. package/dist/font-metrics-CBGmhLo0.d.ts.map +0 -1
  121. package/dist/grid-9B2w5EaY.js.map +0 -1
  122. package/dist/html-dom-DvJmuHt2.js.map +0 -1
  123. package/dist/image-size-DwDbakcl.js.map +0 -1
  124. package/dist/notes-BcT571R4.js.map +0 -1
  125. package/dist/options-internal-WqgMf720.js.map +0 -1
  126. package/dist/package-KoEgVwII.d.ts.map +0 -1
  127. package/dist/playbtn-CUqQdoDf.js.map +0 -1
  128. package/dist/pres-BA9_lJbY.d.ts.map +0 -1
  129. package/dist/presentation-Cyl74rq2.js.map +0 -1
  130. package/dist/presentation-types-B3VQH4Bz.d.ts.map +0 -1
  131. package/dist/shapes-BcyFdZpp.js.map +0 -1
  132. package/dist/slide-BqPtyKmb.d.ts.map +0 -1
  133. package/dist/table-cell-margins-PDshga8T.js.map +0 -1
  134. package/dist/text-BvFFMMFQ.js.map +0 -1
  135. package/dist/text-anchor-BgLPbwbL.js.map +0 -1
  136. package/dist/units-internal-DFcUYjh3.js.map +0 -1
  137. package/dist/zip-CTll_dr0.d.ts.map +0 -1
  138. package/dist/zip-CYZ0F6BV.js.map +0 -1
  139. package/dist/zoom-BoNyOlPm.js.map +0 -1
@@ -1,16 +1,15 @@
1
- import { c as PLACEHOLDER_TYPE, d as SHAPE_NAME, g as TextAnchor, i as CHART_NAME, m as SlideObjectType, o as ChartType, t as AlignH } from "./enums-DQRpVOLh.js";
2
- import { $ as ChartOpts, E as Margin, Ht as TextProps, Jt as MediaProps, Pt as SlideComment, Q as ChartMulti, Sn as TextShapeType, St as OptsChartData, Ut as TextPropsOptions, Yt as MediaType, a as PresentationProps, i as PresLayout, j as TextVertType, o as SectionProps, p as BackgroundOption, q as ChartErrorBarOptions, z as HyperlinkProps } from "./pres-BA9_lJbY.js";
3
- import { O as TableCell, S as AnimationProps, _ as MasterTextStyleProps, a as Slide, i as ObjectOptions, o as SlideLayout, x as SlideNumberProps } from "./slide-BqPtyKmb.js";
4
- import { t as EmbeddedFont } from "./embedded-fonts-CI_YGW2d.js";
5
- //#region src/types/internal.d.ts
1
+ import { c as PLACEHOLDER_TYPE, d as SHAPE_NAME, g as TextAnchor, i as CHART_NAME, m as SlideObjectType, o as ChartType, t as AlignH } from "./enums-PcXr3o3J.js";
2
+ import { An as TextShapeType, Cn as PlaceholderXmlType, Dt as OptsChartData, E as Margin, H as HyperlinkProps, M as TextVertType, Q as ChartErrorBarOptions, Vt as SlideComment, Xt as TextPropsOptions, Yt as TextProps, a as PresentationProps, i as PresLayout, it as ChartOpts, nn as MediaType, o as SectionProps, p as BackgroundOption, rt as ChartMulti, tn as MediaProps } from "./pres-BkEkUAEM.js";
3
+ import { O as TableCell, S as AnimationProps, _ as MasterTextStyleProps, a as Slide, i as ObjectOptions, o as SlideLayout, x as SlideNumberProps } from "./slide-BmT4kMoO.js";
4
+ import { t as EmbeddedFont } from "./embedded-fonts-U7HIIhPO.js";
6
5
  /** The keys of `T` that are declared optional. */
7
6
  type OptionalKeysOf<T> = { [K in keyof T]-?: {} extends Pick<T, K> ? K : never; }[keyof T];
8
7
  /**
9
8
  * `T`, but every *optional* property may also be spelled as a present `undefined`.
10
9
  *
11
10
  * Under `exactOptionalPropertyTypes` a `foo?: T` says the key is either absent or holds a `T`.
12
- * That distinction is real for a bag that is **stored, spread or enumerated** — `{ ...defaults,
13
- * ...options }` inherits from an absent key and is overridden by a present `undefined` — and
11
+ * That distinction is real for a bag that is **stored, spread or enumerated** (`{ ...defaults,
12
+ * ...options }` inherits from an absent key and is overridden by a present `undefined`), and
14
13
  * those bags keep the strict declaration, with `delete` as their one spelling of absent (the
15
14
  * write-side twin of `compact()` in `script/from-read/values.ts`).
16
15
  *
@@ -26,7 +25,7 @@ type MaybeUndefined<T> = Omit<T, OptionalKeysOf<T>> & { [K in OptionalKeysOf<T>]
26
25
  * Text options carrying the two members the emitters write onto them.
27
26
  *
28
27
  * `_bodyProp` is the normalized `a:bodyPr` the definer builds out of the caller's `align`,
29
- * `valign`, `margin`, `columns`, `textDirection` and `textWarp` — a *derived* shape, not an
28
+ * `valign`, `margin`, `columns`, `textDirection` and `textWarp`: a *derived* shape, not an
30
29
  * input, which is what made its presence on the public interface a de-facto API nobody
31
30
  * intended. `_lineIdx` is the paragraph index the run emitter stamps while walking an array
32
31
  * of runs.
@@ -53,6 +52,18 @@ interface TextPropsOptionsInternal extends TextPropsOptions {
53
52
  prstTxWarp?: TextShapeType;
54
53
  };
55
54
  _lineIdx?: number;
55
+ /**
56
+ * Set by the definer on text that would otherwise be written black: no colour of its own, none
57
+ * on its shape, not a placeholder, not a link. The emitter paints it in the slide's
58
+ * {@link Slide.color}, else black. It is a flag rather than the colour because the slide's
59
+ * colour is read when the slide is written, not when the text is added (#88).
60
+ */
61
+ _slideColor?: true;
62
+ /**
63
+ * Set by the emitter on a run whose `hyperlink` it took from the shape, so the run writes no
64
+ * show jump of its own: the shape's lives on its `p:cNvPr`.
65
+ */
66
+ _shapeHyperlink?: true;
56
67
  }
57
68
  /**
58
69
  * A slide object's options carrying the six members the definers and emitters write onto them.
@@ -66,7 +77,7 @@ interface TextPropsOptionsInternal extends TextPropsOptions {
66
77
  */
67
78
  interface ObjectOptionsInternal extends ObjectOptions, TextPropsOptionsInternal {
68
79
  _placeholderIdx?: number;
69
- _placeholderType?: PLACEHOLDER_TYPE;
80
+ _placeholderType?: PLACEHOLDER_TYPE | PlaceholderXmlType;
70
81
  /** Connector adjust-guide values (OOXML 1000ths-of-a-percent), one per bend; emitted as `<a:gd name="adjN">` */
71
82
  _connectorAdj?: number[];
72
83
  /** Connector start-point binding: target shape `objectName` (raw, as the caller spelled it) + connection-site index; resolved to `<a:stCxn>` at serialize time */
@@ -110,7 +121,7 @@ interface ChartOptsInternal extends ChartOpts {
110
121
  _type?: ChartType | ChartMultiInternal[];
111
122
  }
112
123
  /**
113
- * A combo subchart's option overrides after `addChartDefinition` vetted them — the one bag in the
124
+ * A combo subchart's option overrides after `addChartDefinition` vetted them: the one bag in the
114
125
  * generator where a key may be *present* and hold `undefined`.
115
126
  *
116
127
  * Everywhere else "unset" has exactly one spelling, an absent key: `compact()` enforces it on the
@@ -119,7 +130,7 @@ interface ChartOptsInternal extends ChartOpts {
119
130
  * chart-level options at emit time (`{ ...rel.opts, ...type.options }` in `gen/chart/chart-xml.ts`),
120
131
  * where a present `undefined` suppresses the chart-level value and an absent key inherits it.
121
132
  * Suppressing is the intent: the subchart supplied an override the schema rejects, and the
122
- * chart-level value is one it never asked for — inheriting it would be a different chart than
133
+ * chart-level value is one it never asked for. Inheriting it would be a different chart than
123
134
  * either party described. For a combo chart the chart-level pass cannot vet these itself, since
124
135
  * `_type` is an array there and every type-keyed correction matches no branch.
125
136
  */
@@ -148,6 +159,15 @@ interface SlideRelChart extends OptsChartData {
148
159
  * via `<mc:AlternateContent>`. Set at define time from {@link isChartExType}.
149
160
  */
150
161
  isChartEx?: boolean;
162
+ /**
163
+ * The pictures the chart part references (a chart or plot area's picture fill), each under the
164
+ * relationship id the chart part gives it. The media rel is the slide's, marked
165
+ * {@link SlideRelMedia.chartOwned}, so its `Target` is read at write time, after media dedupe.
166
+ */
167
+ media?: Array<{
168
+ rId: number;
169
+ rel: SlideRelMedia;
170
+ }>;
151
171
  }
152
172
  interface SlideRel {
153
173
  type: SlideObjectType;
@@ -155,7 +175,7 @@ interface SlideRel {
155
175
  * Relationship target, stored **unescaped**. Every emitter escapes it on the way out
156
176
  * (`gen/slide/object.ts`, `gen/slide/notes.ts`, and `read/opc/relationships.ts` for the
157
177
  * append path). Escaping at definition time instead would double-escape on append,
158
- * where the serializer escapes again — so `&` in a hyperlink or online-video URL must
178
+ * where the serializer escapes again, so `&` in a hyperlink or online-video URL must
159
179
  * arrive here verbatim.
160
180
  */
161
181
  Target: string;
@@ -171,12 +191,12 @@ interface SlideRelMedia {
171
191
  type: string;
172
192
  opts?: MediaProps;
173
193
  path?: string;
174
- extn?: string;
175
- data?: string | ArrayBuffer;
194
+ extn: string;
195
+ data: string;
176
196
  /**
177
197
  * An `addMedia` poster frame the caller supplied no `cover` for, so it takes the library's
178
- * default play-button artwork. `addMediaDefinition` pushes the rel with this flag and no
179
- * `data`; `encodeSlideMediaRels` fills the bytes in during the async media pass, behind the
198
+ * default play-button artwork. `addMediaDefinition` pushes the rel with this flag and an
199
+ * empty `data`; `encodeSlideMediaRels` fills the bytes in during the async media pass, behind the
180
200
  * dynamic import that keeps the artwork out of every consumer's entry chunk. Every rel
181
201
  * carrying it has its `data` resolved before any part is emitted.
182
202
  */
@@ -189,7 +209,7 @@ interface SlideRelMedia {
189
209
  h: number;
190
210
  };
191
211
  /**
192
- * Embedded OLE object part (`addOleObject`): the `.rels` `Type` URI to emit — `.../package` for
212
+ * Embedded OLE object part (`addOleObject`): the `.rels` `Type` URI to emit: `.../package` for
193
213
  * an embedded OPC package (xlsx/docx/pptx, themselves zips) or `.../oleObject` for a generic OLE
194
214
  * server blob (ECMA-376 Part 1 §15.2.10). Present only on OLE payload rels, where it takes
195
215
  * precedence over the image/audio/video branch in `slideObjectRelationsToXml` and `type` carries
@@ -198,7 +218,7 @@ interface SlideRelMedia {
198
218
  */
199
219
  oleRelType?: string;
200
220
  /**
201
- * Embedded 3D model part (`addModel3d`): the `.rels` `Type` URI to emit — the Microsoft
221
+ * Embedded 3D model part (`addModel3d`): the `.rels` `Type` URI to emit: the Microsoft
202
222
  * `…/office/2017/06/relationships/model3d` type, which no `includes('image'|'audio'|'video')`
203
223
  * sniff would ever reach. Present only on the `.glb` payload rel, where it takes precedence
204
224
  * over the image/audio/video branch in `slideObjectRelationsToXml` and `type` carries the
@@ -206,8 +226,14 @@ interface SlideRelMedia {
206
226
  * separate, perfectly ordinary image rel. Same escape hatch as {@link oleRelType}.
207
227
  */
208
228
  model3dRelType?: string;
229
+ /**
230
+ * The picture of a chart's area fill, registered on the slide so the media pass loads, dedupes and
231
+ * writes its part like any other picture. The chart part references it (see
232
+ * {@link SlideRelChart.media}); the slide does not, so the slide's `.rels` leaves it out.
233
+ */
234
+ chartOwned?: true;
209
235
  rId: number;
210
- /** Unescaped — see {@link SlideRel.Target}. Doubles as the zip entry name for embedded media. */
236
+ /** Unescaped; see {@link SlideRel.Target}. Doubles as the zip entry name for embedded media. */
211
237
  Target: string;
212
238
  }
213
239
  interface SlideObject {
@@ -229,6 +255,7 @@ interface SlideObject {
229
255
  zoom?: ZoomInternal;
230
256
  ole?: OleInternal;
231
257
  model3d?: Model3dInternal;
258
+ _seeded?: boolean;
232
259
  }
233
260
  /**
234
261
  * Resolved 3D-model payload carried on a {@link SlideObject} until `gen/slide/objects/model3d.ts`
@@ -239,7 +266,7 @@ interface SlideObject {
239
266
  interface Model3dInternal {
240
267
  /** rId of the embedded `.glb` part rel (see {@link SlideRelMedia.model3dRelType}). */
241
268
  modelRid: number;
242
- /** rId of the preview picture's image rel — shared by `am3d:blip` and the `mc:Fallback` `p:pic`. */
269
+ /** rId of the preview picture's image rel, shared by `am3d:blip` and the `mc:Fallback` `p:pic`. */
243
270
  previewRid: number;
244
271
  /** `am3d:camera/am3d:pos` (`@x`/`@y`/`@z`). */
245
272
  pos: {
@@ -270,9 +297,9 @@ interface OleInternal {
270
297
  objectRid: number;
271
298
  /** rId of the preview picture's image rel (`p:pic > a:blip@r:embed`). */
272
299
  previewRid: number;
273
- /** `p:oleObj@progId` — the OLE server PowerPoint launches on double-click. */
300
+ /** `p:oleObj@progId`: the OLE server PowerPoint launches on double-click. */
274
301
  progId: string;
275
- /** `p:oleObj@name` — the object's kind as PowerPoint labels it (`Worksheet`, `Document`, …). */
302
+ /** `p:oleObj@name`: the object's kind as PowerPoint labels it (`Worksheet`, `Document`, …). */
276
303
  name: string;
277
304
  /** `p:oleObj@showAsIcon`; omitted when false, matching PowerPoint. */
278
305
  showAsIcon: boolean;
@@ -349,6 +376,8 @@ interface PresSlideInternal extends SlideBaseProps, Slide {
349
376
  _rId: number;
350
377
  _slideLayout: SlideLayoutInternal | null;
351
378
  _slideId: number;
379
+ /** Review comments; a slide always has the list, empty until `addComment` pushes one. */
380
+ _comments: SlideComment[];
352
381
  /** Preset build animations on this slide, in play order (see {@link Slide.addAnimation}). */
353
382
  _animations: AnimationProps[];
354
383
  }
@@ -372,11 +401,9 @@ interface PresentationPropsInternal extends PresentationProps {
372
401
  sections: SectionInternalProps[];
373
402
  slideLayouts: SlideLayoutInternal[];
374
403
  slides: PresSlideInternal[];
375
- /** Author-side embedded fonts (see {@link TsPptx.embedFont}); empty when none. */
404
+ /** Author-side embedded fonts (see {@link PptxTs.embedFont}); empty when none. */
376
405
  embeddedFonts: EmbeddedFont[];
377
406
  }
378
- //#endregion
379
- //#region src/measure/text-fit.d.ts
380
407
  /**
381
408
  * PowerPoint single-spacing line pitch as a multiple of font size.
382
409
  *
@@ -395,7 +422,7 @@ declare const MIN_FONT_SCALE_PCT = 25;
395
422
  * Conservative safety factors applied by the shrink solver (not by the pure
396
423
  * `measureHeightPt`). Raw `hmtx` advances summed without shaping still pack a line
397
424
  * a little tighter than PowerPoint, which lays text out at a device DPI and rounds
398
- * each glyph advance up — so PowerPoint wraps marginally earlier and its fitted
425
+ * each glyph advance up, so PowerPoint wraps marginally earlier and its fitted
399
426
  * box is marginally taller. Inflating measured width and height by these factors
400
427
  * makes the computed `fontScale` ≤ PowerPoint's across the calibration oracle
401
428
  * (`test/read/autofit-calibration-oracle.test.ts`: 0 violations over the Aptos
@@ -420,7 +447,7 @@ interface FitRun {
420
447
  * generator's option bags follow (`options-internal.ts`): these are measurement records, built in
421
448
  * one place by `paragraphs.ts` and read in one place by the solver below, with `??` and
422
449
  * truthiness. Nothing spreads or enumerates them, so a key holding `undefined` cannot mean
423
- * anything different from an absent one — and the builder does produce every key on every run.
450
+ * anything different from an absent one, and the builder does produce every key on every run.
424
451
  * Saying so is more honest than making the builder omit keys nothing distinguishes.
425
452
  */
426
453
  interface FitParagraph {
@@ -440,7 +467,7 @@ interface FitBox {
440
467
  * `false` when the frame does not wrap (`wrap:false` / `wrap="none"`): text lays
441
468
  * out as one line per paragraph (no width-wrapping), and the shrink solver must
442
469
  * additionally keep the widest line within `innerWidthPt`. A too-wide line
443
- * overflows HORIZONTALLY — `normAutofit`'s vertical shrink never catches it, so
470
+ * overflows HORIZONTALLY. `normAutofit`'s vertical shrink never catches it, so
444
471
  * without this check a non-wrapping line is never shrunk and spills out of the box
445
472
  * in PowerPoint. Defaults to wrapping (`true`), so table cells and `measureText`
446
473
  * are unaffected.
@@ -494,10 +521,10 @@ type ResizeOutcome = {
494
521
  neededInnerHeightPt: number;
495
522
  };
496
523
  /**
497
- * Inner height (points) the text needs at full size — the value to bake into the
524
+ * Inner height (points) the text needs at full size: the value to bake into the
498
525
  * shape's `a:ext/@cy` for `fit: 'resize'` (`spAutoFit`). Unlike shrink, resize has
499
526
  * **no safety net**: an under-estimate overflows (there is no text scaling
500
- * fallback), so this errs **tall** — width is inflated (earlier wrap ⇒ more lines)
527
+ * fallback), so this errs **tall**. Width is inflated (earlier wrap ⇒ more lines)
501
528
  * and the laid-out height by the calibrated height factor, so the computed `cy` is
502
529
  * ≥ PowerPoint's and ≥ the LibreOffice-rendered height across the resize oracle.
503
530
  */
@@ -507,14 +534,12 @@ declare function solveResize(paragraphs: FitParagraph[], box: FitBox, resolve: M
507
534
  * Width and height both re-measured per scale. Conservative: because the model
508
535
  * over-estimates, the returned scale is ≤ PowerPoint's and the text never overflows.
509
536
  *
510
- * `lnSpcReduction` is left at 0 — dropping `fontScale` alone is provably
537
+ * `lnSpcReduction` is left at 0: dropping `fontScale` alone is provably
511
538
  * conservative (PowerPoint trades line-spacing reduction to keep the font *larger*,
512
539
  * so a reduction-free fit is always ≤ PowerPoint's scale). The reduction ramp
513
540
  * PowerPoint applies is recorded in `docs/contributing/design/text-fit.md`.
514
541
  */
515
542
  declare function solveShrink(paragraphs: FitParagraph[], box: FitBox, resolve: MetricsResolver): ShrinkOutcome;
516
- //#endregion
517
- //#region src/measure/font-metrics.d.ts
518
543
  /** Per-(face,bold,italic) advance-width source backed by a parsed font file. */
519
544
  interface FontMetrics {
520
545
  /** Font design units per em (advances are in these units). */
@@ -536,7 +561,7 @@ interface FontMetrics {
536
561
  /**
537
562
  * Shared, font-independent `FontMetrics` used when a named face has no registered
538
563
  * metrics but the deck has opted into measured fit (some other face is registered).
539
- * Approximate but conservative — see `heuristicCharRatio`. A deck with no
564
+ * Approximate but conservative; see `heuristicCharRatio`. A deck with no
540
565
  * registered metrics at all does not engage measured fit, so this never fires there.
541
566
  */
542
567
  declare function getHeuristicFontMetrics(): FontMetrics;
@@ -587,7 +612,7 @@ declare class FontMetricsRegistry {
587
612
  * Coverage of code point `cp` for `face`, read from the registered font's cmap:
588
613
  * `true`/`false` when a variant of `face` is registered (see {@link get} for the
589
614
  * exact→regular→any-variant fallback), or `undefined` when the face has **no**
590
- * registered metrics — "unknown", deliberately distinct from a `false`
615
+ * registered metrics: "unknown", deliberately distinct from a `false`
591
616
  * "registered but not covered". A coverage audit must not treat an unregistered
592
617
  * face as fully covered, so callers get `undefined` here rather than the per-face
593
618
  * {@link FontMetrics.hasCodepoint} boolean (which, for the heuristic fallback,
@@ -608,6 +633,5 @@ declare class FontMetricsRegistry {
608
633
  * no `fontFace` at all resolves to `undefined`, which the callers treat as unmeasurable.
609
634
  */
610
635
  declare function makeRegistryResolver(registry: FontMetricsRegistry, onHeuristic?: (face: string) => void): MetricsResolver;
611
- //#endregion
612
636
  export { SlideObject as A, solveShrink as C, SectionInternalProps as D, PresentationPropsInternal as E, SlideRelChart as M, SlideRelMedia as N, SlideLayoutInternal as O, solveResize as S, PresSlideInternal as T, ShrinkOutcome as _, makeRegistryResolver as a, measureHeightPt as b, FitBox as c, HEIGHT_SAFETY_FACTOR as d, LayoutResult as f, SINGLE_LINE_PITCH as g, ResizeOutcome as h, getHeuristicFontMetrics as i, SlideRel as j, SlideMasterInternal as k, FitParagraph as l, MetricsResolver as m, FontMetricsRegistry as n, parseFontMetrics as o, MIN_FONT_SCALE_PCT as p, ParseFontMetricsOptions as r, FONT_SCALE_STEP_PCT as s, FontMetrics as t, FitRun as u, ShrinkResult as v, ObjectOptionsInternal as w, measureLayout as x, WIDTH_SAFETY_FACTOR as y };
613
- //# sourceMappingURL=font-metrics-CBGmhLo0.d.ts.map
637
+ //# sourceMappingURL=font-metrics-DTppw4t3.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"font-metrics-DTppw4t3.d.ts","names":[],"sources":["../src/types/internal.ts","../src/measure/text-fit.ts","../src/measure/font-metrics.ts"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { l as warn } from "./errors-Da2nXCJm.js";
2
- //#region src/gen/table/spans.ts
1
+ import { u as warn } from "./entry-errors-JMthgJ2g.js";
2
+ // src/gen/table/spans.ts
3
3
  /**
4
4
  * The largest `colspan`/`rowspan` this library will honour.
5
5
  *
@@ -14,14 +14,14 @@ const MAX_TABLE_SPAN = 1e3;
14
14
  * Validate one cell's `colspan`/`rowspan`, warning and falling back to `1` when it is not a whole
15
15
  * number in `1..MAX_TABLE_SPAN`.
16
16
  *
17
- * `undefined` is the common case and means "no span" — it warns about nothing and returns `1`.
17
+ * `undefined` is the common case and means "no span": it warns about nothing and returns `1`.
18
18
  * Everything else is caller error: `NaN`, a negative, a fraction and a span past the ceiling all
19
19
  * describe a table that cannot be built (a fractional span silently truncates, a negative one
20
20
  * shifts every column after it, an enormous one is the allocation above).
21
21
  *
22
22
  * The parameter is typed `unknown` because this is also **the** reading of a span for the six
23
23
  * sites that consume one after {@link withCheckedSpans} has run. Those had six different
24
- * coercions — `Number(x) ? … : 1`, `Math.max(1, Number(x) || 1)`, `x ?? 1` — which agreed only
24
+ * coercions (`Number(x) ? … : 1`, `Math.max(1, Number(x) || 1)`, `x ?? 1`), which agreed only
25
25
  * on the values that were already valid, and one of them let a non-numeric span reach a grid
26
26
  * column count as `NaN`. Reading a span through one function is what stops them drifting apart
27
27
  * again if the up-front check is ever moved.
@@ -45,7 +45,7 @@ function resolveSpan(value, kind) {
45
45
  * Re-clone `rows` with every out-of-range `colspan`/`rowspan` corrected to `1`.
46
46
  *
47
47
  * Runs once, up front, so the column count, the `_hmerge`/`_vmerge` dummies, the auto-pager's
48
- * grid and the emitted `gridSpan`/`rowSpan` attributes all read the same number — checking at
48
+ * grid and the emitted `gridSpan`/`rowSpan` attributes all read the same number. Checking at
49
49
  * each of those sites instead would warn several times per bad cell and could still disagree.
50
50
  *
51
51
  * A cell whose spans are fine is passed through by identity, not copied: `_spanOrigin` links the
@@ -74,27 +74,25 @@ function withCheckedSpans(rows) {
74
74
  }));
75
75
  }
76
76
  /**
77
- * Whether any cell in the grid carries a hyperlink — on the cell itself, or on any run of a
78
- * cell whose `text` is a run array.
77
+ * Whether a cell carries a hyperlink, on the cell itself or on any run of its `text` when that
78
+ * is a run array.
79
79
  *
80
- * `addTable` uses this to decide whether to stand its black text default down: the default is
81
- * direct formatting on the table, so it would paint the words *after* a link black rather than
82
- * letting them follow the link colour. The test used to be
83
- * `JSON.stringify({ arrRows }).includes('hyperlink')`, which matched the literal word anywhere
84
- * in the grid's *content* — a cell reading "see the hyperlink docs" suppressed the default for
85
- * the whole table — and serialized every cell on every `addTable` to ask.
86
- * @param rows - the table's rows
80
+ * The table's black text default is direct formatting on the cell's runs, so on a linked cell it
81
+ * would paint the words *after* the link black rather than letting them follow the link colour.
82
+ * The emitter stands the default down for such a cell, and only for it: the test used to be
83
+ * table-wide, so one link stripped the default from every cell in the grid and a cell's output
84
+ * depended on its neighbours (#101). Before that it was
85
+ * `JSON.stringify({ arrRows }).includes('hyperlink')`, which matched the literal word anywhere in
86
+ * the grid's *content*.
87
+ * @param cell - the cell, or a hole in the grid
87
88
  */
88
- function tableHasHyperlink(rows) {
89
- return rows.some((cells) => cells.some((cell) => {
90
- if (!cell) return false;
91
- if (cell.options?.hyperlink) return true;
92
- if (!Array.isArray(cell.text)) return false;
93
- return cell.text.some((run) => !!run?.options?.hyperlink);
94
- }));
89
+ function cellHasHyperlink(cell) {
90
+ if (!cell) return false;
91
+ if (cell.options?.hyperlink) return true;
92
+ if (!Array.isArray(cell.text)) return false;
93
+ return cell.text.some((run) => !!run?.options?.hyperlink);
95
94
  }
96
- //#endregion
97
- //#region src/gen/table/grid.ts
95
+ // src/gen/table/grid.ts
98
96
  /**
99
97
  * How many grid columns a table has: the sum of the first row's colspans.
100
98
  *
@@ -181,7 +179,6 @@ function* walkTableGrid(rows, numCols) {
181
179
  occupancy.endRow();
182
180
  }
183
181
  }
184
- //#endregion
185
- export { resolveSpan as a, MAX_TABLE_SPAN as i, tableColCount as n, tableHasHyperlink as o, walkTableGrid as r, withCheckedSpans as s, createRowSpanOccupancy as t };
182
+ export { cellHasHyperlink as a, MAX_TABLE_SPAN as i, tableColCount as n, resolveSpan as o, walkTableGrid as r, withCheckedSpans as s, createRowSpanOccupancy as t };
186
183
 
187
- //# sourceMappingURL=grid-9B2w5EaY.js.map
184
+ //# sourceMappingURL=grid-DUIMxjfl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grid-DUIMxjfl.js","names":[],"sources":["../src/gen/table/spans.ts","../src/gen/table/grid.ts"],"sourcesContent":["/**\n * pptx-ts: table `colspan`/`rowspan` range checking.\n *\n * The spans decide two allocations, on two different paths, and both used to trust the caller:\n * the merge grid's `new Array(colspan - 1)` in `gen/slide/objects/table.ts`, and the auto-pager's\n * per-column depth array, sized from a column count that is a sum of colspans\n * (`gen/table/autopage.ts`). `new Array(4294967294).fill(undefined)` is not a slow path: V8\n * aborts on the allocation and there is no exception to catch. So a table built with\n * `autoPage: true` and one without needed the same guard, which is why it lives here rather than\n * in either of them.\n *\n * This is the write side, so the bad number comes from the calling program rather than from a\n * hostile file, which makes it far less serious than the read-side twin in the chart point caches\n * (`read/oxml/point-cache.ts`, the model this copies). It is still the project's stated line: warn\n * on out-of-range input rather than emit a degenerate result.\n */\n\nimport type { TableCellInternal } from '../../types/internal.js'\nimport { warn } from '../../diagnostics.js'\n\n/**\n * The largest `colspan`/`rowspan` this library will honour.\n *\n * Unlike the read side's point-cache ceiling there is no format number to borrow: `a:tc@gridSpan`\n * is a bare `xsd:int`. So this is a sanity bound rather than a schema one, and it is set an order\n * of magnitude past PowerPoint's own maximum table (its Insert Table dialog stops at 75 columns\n * and 75 rows), which is what makes it something no authored table can reach. What it stops is\n * the other end, where the allocation takes the host process with it.\n */\nexport const MAX_TABLE_SPAN = 1000\n\n/**\n * Validate one cell's `colspan`/`rowspan`, warning and falling back to `1` when it is not a whole\n * number in `1..MAX_TABLE_SPAN`.\n *\n * `undefined` is the common case and means \"no span\": it warns about nothing and returns `1`.\n * Everything else is caller error: `NaN`, a negative, a fraction and a span past the ceiling all\n * describe a table that cannot be built (a fractional span silently truncates, a negative one\n * shifts every column after it, an enormous one is the allocation above).\n *\n * The parameter is typed `unknown` because this is also **the** reading of a span for the six\n * sites that consume one after {@link withCheckedSpans} has run. Those had six different\n * coercions (`Number(x) ? … : 1`, `Math.max(1, Number(x) || 1)`, `x ?? 1`), which agreed only\n * on the values that were already valid, and one of them let a non-numeric span reach a grid\n * column count as `NaN`. Reading a span through one function is what stops them drifting apart\n * again if the up-front check is ever moved.\n * @param value - the raw option value, as the caller wrote it\n * @param kind - `'colspan'` or `'rowspan'`, for the diagnostic\n * @returns the span to use, at least 1\n */\nexport function resolveSpan(value: unknown, kind: 'colspan' | 'rowspan'): number {\n\tif (value === undefined || value === null || value === '') return 1\n\tif (typeof value !== 'number') {\n\t\twarn(\n\t\t\t'table/span-out-of-range',\n\t\t\t`table cell: ${kind} must be a whole number between 1 and ${MAX_TABLE_SPAN}; got ${String(value)}. Using 1.`\n\t\t)\n\t\treturn 1\n\t}\n\tif (!Number.isInteger(value) || value < 1 || value > MAX_TABLE_SPAN) {\n\t\twarn(\n\t\t\t'table/span-out-of-range',\n\t\t\t`table cell: ${kind} must be a whole number between 1 and ${MAX_TABLE_SPAN}; got ${String(value)}. Using 1.`\n\t\t)\n\t\treturn 1\n\t}\n\treturn value\n}\n\n/**\n * Re-clone `rows` with every out-of-range `colspan`/`rowspan` corrected to `1`.\n *\n * Runs once, up front, so the column count, the `_hmerge`/`_vmerge` dummies, the auto-pager's\n * grid and the emitted `gridSpan`/`rowSpan` attributes all read the same number. Checking at\n * each of those sites instead would warn several times per bad cell and could still disagree.\n *\n * A cell whose spans are fine is passed through by identity, not copied: `_spanOrigin` links the\n * merge dummies back to the origin *object*, and the all-valid path is every real table, which\n * must stay allocation-free and byte-identical.\n * @param rows - the rows to check; row arrays are never mutated\n * @returns the same rows with only the offending cells replaced\n */\nexport function withCheckedSpans(rows: TableCellInternal[][]): TableCellInternal[][] {\n\treturn rows.map((cells) =>\n\t\tcells.map((cell) => {\n\t\t\tconst opts = cell?.options\n\t\t\tif (!opts) return cell\n\t\t\tconst colspan = resolveSpan(opts.colspan, 'colspan')\n\t\t\tconst rowspan = resolveSpan(opts.rowspan, 'rowspan')\n\t\t\tconst colspanOk = opts.colspan === undefined || opts.colspan === colspan\n\t\t\tconst rowspanOk = opts.rowspan === undefined || opts.rowspan === rowspan\n\t\t\tif (colspanOk && rowspanOk) return cell\n\t\t\treturn {\n\t\t\t\t...cell,\n\t\t\t\toptions: {\n\t\t\t\t\t...opts,\n\t\t\t\t\t...(opts.colspan === undefined ? {} : { colspan }),\n\t\t\t\t\t...(opts.rowspan === undefined ? {} : { rowspan }),\n\t\t\t\t},\n\t\t\t}\n\t\t})\n\t)\n}\n\n/**\n * Whether a cell carries a hyperlink, on the cell itself or on any run of its `text` when that\n * is a run array.\n *\n * The table's black text default is direct formatting on the cell's runs, so on a linked cell it\n * would paint the words *after* the link black rather than letting them follow the link colour.\n * The emitter stands the default down for such a cell, and only for it: the test used to be\n * table-wide, so one link stripped the default from every cell in the grid and a cell's output\n * depended on its neighbours (#101). Before that it was\n * `JSON.stringify({ arrRows }).includes('hyperlink')`, which matched the literal word anywhere in\n * the grid's *content*.\n * @param cell - the cell, or a hole in the grid\n */\nexport function cellHasHyperlink(cell: TableCellInternal | undefined): boolean {\n\tif (!cell) return false\n\tif (cell.options?.hyperlink) return true\n\tif (!Array.isArray(cell.text)) return false\n\treturn cell.text.some((run) => !!run?.options?.hyperlink)\n}\n","/**\n * pptx-ts: a table's cell grid.\n *\n * Rows arrive lopsided -- `row1: [A, B, C]`, `row2: [D]` when the first two columns are held by\n * a rowspan from above -- so a cell's position in its row array is not its column. Four places\n * needed to know where a cell actually lands (the auto-pager, twice, in one function; the\n * measured-fit pass; the table emitter) and each walked the grid itself, tracking rowspan\n * occupancy in its own array with its own off-by-one convention.\n *\n * This is that traversal, once. It lives beside {@link resolveSpan} rather than in `measure/`\n * because the grid is a fact about the authored table, not a measurement of it -- the pager and\n * the emitter want it as much as the fitter does, and `measure/table-fit.ts` was already\n * reaching into `gen/table/` for the span reader it is built on.\n */\n\nimport type { TableCellInternal } from '../../types/internal.js'\nimport { resolveSpan } from './spans.js'\n\n/**\n * How many grid columns a table has: the sum of the first row's colspans.\n *\n * The count cannot come from `rows[0].length` -- a colspan makes one cell occupy several\n * columns -- and it is read off the first row alone, which is the writer's standing rule: a\n * later row wider than the first is ragged input, and the grid it is measured, paged and\n * emitted against is the one `a:tblGrid` declares.\n */\nexport function tableColCount(rows: TableCellInternal[][]): number {\n\tconst first = rows[0]\n\treturn first ? first.reduce((n, c) => n + resolveSpan(c?.options?.colspan, 'colspan'), 0) : 0\n}\n\n/** The bookkeeping a row-major grid walk needs to route around rowspans; see {@link createRowSpanOccupancy}. */\ninterface RowSpanOccupancy {\n\t/** The first column at or after `col` that no rowspan from above is holding. */\n\tnextFree: (col: number) => number\n\t/** Record that `colSpan` columns from `col` are held for `rowSpan` rows, this one included. */\n\thold: (col: number, colSpan: number, rowSpan: number) => void\n\t/** Close the current row: every held column has one fewer row left to hold. */\n\tendRow: () => void\n}\n\n/**\n * The rowspan-occupancy rule, stated once.\n *\n * A row states only the cells it *starts*: a column held by a `rowspan` from above is filled\n * without the row mentioning it, so a cell's position in its row array is not its column. Tracking\n * that is three operations -- skip what is held, mark what this cell holds, age the holds by a row\n * -- and getting the ageing off by one silently shifts every column below.\n *\n * It has two callers asking different questions on different input. {@link walkTableGrid} places\n * authored `TableCell`s into a grid whose width `a:tblGrid` already declares; `measureGridColumns`\n * (`gen/table/html-dom.ts`) measures how wide an imported HTML table's grid *is*, reading spans off\n * HTML attributes, with no width known up front. Neither can be expressed as the other without\n * giving one of them a mode it does not want -- but the rule underneath is the same rule, and it is\n * here rather than in both.\n *\n * The array is sparse and unbounded on purpose: a caller that knows its width clamps what it\n * `hold`s, and then nothing past that width is ever held, so an unbounded `nextFree` returns the\n * same answer a bounded one would.\n */\nexport function createRowSpanOccupancy(): RowSpanOccupancy {\n\t// held[c] = rows still covered by a rowspan started at or above the current row.\n\tconst held: number[] = []\n\treturn {\n\t\tnextFree(col) {\n\t\t\tlet free = col\n\t\t\twhile ((held[free] ?? 0) > 0) free++\n\t\t\treturn free\n\t\t},\n\t\thold(col, colSpan, rowSpan) {\n\t\t\tfor (let idx = 0; idx < colSpan; idx++) held[col + idx] = rowSpan\n\t\t},\n\t\tendRow() {\n\t\t\tfor (let idx = 0; idx < held.length; idx++) {\n\t\t\t\tconst rows = held[idx] ?? 0\n\t\t\t\tif (rows > 0) held[idx] = rows - 1\n\t\t\t}\n\t\t},\n\t}\n}\n\n/** A placed (non-merged origin) cell yielded by {@link walkTableGrid}. */\nexport interface GridPlacement {\n\tcell: TableCellInternal\n\t/** Zero-based grid row of the cell's top-left origin. */\n\trow: number\n\t/** Zero-based grid column of the cell's top-left origin. */\n\tcol: number\n\t/** Rows spanned, clamped to the available rows. */\n\trowSpan: number\n\t/** Columns spanned, clamped to the grid width. */\n\tcolSpan: number\n}\n\n/**\n * Walk a table's cell grid in row-major order, resolving each authored cell to its\n * grid origin (`row`/`col`) and clamped colspan/rowspan. Tracks rowspan occupancy so\n * a cell never lands beneath one spanned from above. This is the single traversal the\n * auto-pager, the measured-fit shrink pass, {@link computeTableLayout} and the table emitter's\n * merge grid all read, so the table that is paged and measured is the table that is written.\n *\n * A cell that starts past the last grid column is not yielded: a row longer than the first is\n * ragged input, and the grid is the one `a:tblGrid` declares.\n */\nexport function* walkTableGrid(rows: TableCellInternal[][], numCols: number): Generator<GridPlacement> {\n\tconst occupancy = createRowSpanOccupancy()\n\tfor (let r = 0; r < rows.length; r++) {\n\t\tconst row = rows[r]\n\t\tif (!row) continue\n\t\tlet col = 0\n\t\tfor (const cell of row) {\n\t\t\tcol = occupancy.nextFree(col)\n\t\t\tif (col >= numCols) break\n\t\t\tconst colspan = resolveSpan(cell?.options?.colspan, 'colspan')\n\t\t\tconst rowspan = Math.min(resolveSpan(cell?.options?.rowspan, 'rowspan'), rows.length - r)\n\t\t\tconst colStart = col\n\t\t\t// Clamped to the declared width, which is also what keeps `nextFree` unbounded and still\n\t\t\t// correct: nothing past `numCols` is ever held, so it never has a reason to walk past it.\n\t\t\tconst colEnd = Math.min(colStart + colspan, numCols)\n\t\t\toccupancy.hold(colStart, colEnd - colStart, rowspan)\n\t\t\tcol = colEnd\n\t\t\tyield { cell, row: r, col: colStart, rowSpan: rowspan, colSpan: colEnd - colStart }\n\t\t}\n\t\toccupancy.endRow()\n\t}\n}\n"],"mappings":"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"}