pptx-ts 0.0.1 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/README.md +116 -269
  2. package/dist/autopage-odPz7zZO.js +536 -0
  3. package/dist/autopage-odPz7zZO.js.map +1 -0
  4. package/dist/binary-string-CKVAYI3M.js +24 -0
  5. package/dist/binary-string-CKVAYI3M.js.map +1 -0
  6. package/dist/body-insets-Dw_BeWD_.js +54 -0
  7. package/dist/body-insets-Dw_BeWD_.js.map +1 -0
  8. package/dist/browser.d.ts +29 -9
  9. package/dist/browser.d.ts.map +1 -1
  10. package/dist/browser.js +41 -14
  11. package/dist/browser.js.map +1 -1
  12. package/dist/clip-Bl01BPcN.d.ts +67 -0
  13. package/dist/clip-Bl01BPcN.d.ts.map +1 -0
  14. package/dist/diagnostics-D8ot4Ei7.d.ts +244 -0
  15. package/dist/diagnostics-D8ot4Ei7.d.ts.map +1 -0
  16. package/dist/embedded-fonts-DarT9aoa.d.ts +20 -0
  17. package/dist/embedded-fonts-DarT9aoa.d.ts.map +1 -0
  18. package/dist/entry-compose-DCnvBZz2.d.ts +1046 -0
  19. package/dist/entry-compose-DCnvBZz2.d.ts.map +1 -0
  20. package/dist/{enums-CvRYniUA.d.ts → enums-BUKTUB6V.d.ts} +21 -13
  21. package/dist/{enums-CvRYniUA.d.ts.map → enums-BUKTUB6V.d.ts.map} +1 -1
  22. package/dist/{errors-Bvln0H-7.js → errors-C4oENPcu.js} +92 -2
  23. package/dist/errors-C4oENPcu.js.map +1 -0
  24. package/dist/families.d.ts +260 -0
  25. package/dist/families.d.ts.map +1 -0
  26. package/dist/families.js +57 -0
  27. package/dist/families.js.map +1 -0
  28. package/dist/{fit-BKs0zxMI.js → fit-Cb7naFj6.js} +249 -167
  29. package/dist/fit-Cb7naFj6.js.map +1 -0
  30. package/dist/font-metrics-v5fn7s7e.d.ts +613 -0
  31. package/dist/font-metrics-v5fn7s7e.d.ts.map +1 -0
  32. package/dist/grid-DikTjFey.js +187 -0
  33. package/dist/grid-DikTjFey.js.map +1 -0
  34. package/dist/{html-dom-B0I0QSbU.js → html-dom-Iuog2wdK.js} +121 -91
  35. package/dist/html-dom-Iuog2wdK.js.map +1 -0
  36. package/dist/html.d.ts +6 -6
  37. package/dist/html.d.ts.map +1 -1
  38. package/dist/html.js +7 -6
  39. package/dist/html.js.map +1 -1
  40. package/dist/image-size-CvN2iCA4.js +1611 -0
  41. package/dist/image-size-CvN2iCA4.js.map +1 -0
  42. package/dist/index.d.ts +24 -10
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +31 -11
  45. package/dist/index.js.map +1 -1
  46. package/dist/inspect.d.ts +40 -31
  47. package/dist/inspect.d.ts.map +1 -1
  48. package/dist/inspect.js +40 -48
  49. package/dist/inspect.js.map +1 -1
  50. package/dist/math.d.ts +7 -5
  51. package/dist/math.d.ts.map +1 -1
  52. package/dist/math.js +16 -7
  53. package/dist/math.js.map +1 -1
  54. package/dist/measure.d.ts +12 -225
  55. package/dist/measure.d.ts.map +1 -1
  56. package/dist/measure.js +3 -3
  57. package/dist/node.d.ts +22 -8
  58. package/dist/node.d.ts.map +1 -1
  59. package/dist/node.js +27 -7
  60. package/dist/node.js.map +1 -1
  61. package/dist/notes-Dh12JAbn.js +3264 -0
  62. package/dist/notes-Dh12JAbn.js.map +1 -0
  63. package/dist/options-internal-WqgMf720.js +43 -0
  64. package/dist/options-internal-WqgMf720.js.map +1 -0
  65. package/dist/{package-CaOLXSNi.d.ts → package-J49Ck6S2.d.ts} +27 -12
  66. package/dist/package-J49Ck6S2.d.ts.map +1 -0
  67. package/dist/playbtn-CUqQdoDf.js +22 -0
  68. package/dist/playbtn-CUqQdoDf.js.map +1 -0
  69. package/dist/{slide-js0QpRV-.d.ts → pres-C6qgOFAa.d.ts} +1021 -1370
  70. package/dist/pres-C6qgOFAa.d.ts.map +1 -0
  71. package/dist/{presentation-Cp7vzlAw.js → presentation-DGYlAWhl.js} +3208 -2727
  72. package/dist/presentation-DGYlAWhl.js.map +1 -0
  73. package/dist/{presentation-types-DP_8jog7.d.ts → presentation-types-8jLQHI4M.d.ts} +1070 -683
  74. package/dist/presentation-types-8jLQHI4M.d.ts.map +1 -0
  75. package/dist/read.d.ts +9 -9
  76. package/dist/read.d.ts.map +1 -1
  77. package/dist/read.js +4 -4
  78. package/dist/script.d.ts +80 -66
  79. package/dist/script.d.ts.map +1 -1
  80. package/dist/script.js +2399 -1139
  81. package/dist/script.js.map +1 -1
  82. package/dist/{shapes-BemroU-z.js → shapes-re0KyQk_.js} +2807 -1609
  83. package/dist/shapes-re0KyQk_.js.map +1 -0
  84. package/dist/slide-Dx2ZeVZ6.d.ts +1256 -0
  85. package/dist/slide-Dx2ZeVZ6.d.ts.map +1 -0
  86. package/dist/slide-size-BalTjFuv.js +88 -0
  87. package/dist/slide-size-BalTjFuv.js.map +1 -0
  88. package/dist/{units-internal-Dg95w_YD.js → table-cell-margins-EVg0EwxT.js} +235 -273
  89. package/dist/table-cell-margins-EVg0EwxT.js.map +1 -0
  90. package/dist/table-dom-BTDP3lEP.js +21 -0
  91. package/dist/table-dom-BTDP3lEP.js.map +1 -0
  92. package/dist/text-KnLOtEEu.js +3980 -0
  93. package/dist/text-KnLOtEEu.js.map +1 -0
  94. package/dist/text-anchor-CrYXAfUu.js +176 -0
  95. package/dist/text-anchor-CrYXAfUu.js.map +1 -0
  96. package/dist/transition-speed-kUEWDWTx.js +14 -0
  97. package/dist/transition-speed-kUEWDWTx.js.map +1 -0
  98. package/dist/units-internal-XJlf-hOl.js +649 -0
  99. package/dist/units-internal-XJlf-hOl.js.map +1 -0
  100. package/dist/zip-C0leZZMj.d.ts +67 -0
  101. package/dist/zip-C0leZZMj.d.ts.map +1 -0
  102. package/dist/zip-CKd8ihcf.js +177 -0
  103. package/dist/zip-CKd8ihcf.js.map +1 -0
  104. package/dist/zip.d.ts +3 -68
  105. package/dist/zip.js +3 -163
  106. package/dist/zoom-cX9sllpH.js +8865 -0
  107. package/dist/zoom-cX9sllpH.js.map +1 -0
  108. package/package.json +106 -19
  109. package/skills/ts-pptx-upstream/SKILL.md +58 -57
  110. package/dist/autopage-DkjYZUFD.js +0 -423
  111. package/dist/autopage-DkjYZUFD.js.map +0 -1
  112. package/dist/diagnostics-Du_s75MT.d.ts +0 -829
  113. package/dist/diagnostics-Du_s75MT.d.ts.map +0 -1
  114. package/dist/errors-Bvln0H-7.js.map +0 -1
  115. package/dist/errors-PflMPWBn.d.ts +0 -182
  116. package/dist/errors-PflMPWBn.d.ts.map +0 -1
  117. package/dist/fit-BKs0zxMI.js.map +0 -1
  118. package/dist/html-dom-B0I0QSbU.js.map +0 -1
  119. package/dist/namespaces-BVnNu7sg.js +0 -666
  120. package/dist/namespaces-BVnNu7sg.js.map +0 -1
  121. package/dist/notes-RLCwdlTE.js +0 -1703
  122. package/dist/notes-RLCwdlTE.js.map +0 -1
  123. package/dist/package-CaOLXSNi.d.ts.map +0 -1
  124. package/dist/pres-C5__xkDh.d.ts +0 -202
  125. package/dist/pres-C5__xkDh.d.ts.map +0 -1
  126. package/dist/presentation-Cp7vzlAw.js.map +0 -1
  127. package/dist/presentation-types-DP_8jog7.d.ts.map +0 -1
  128. package/dist/shapes-BemroU-z.js.map +0 -1
  129. package/dist/slide-js0QpRV-.d.ts.map +0 -1
  130. package/dist/text-CyetbF6p.js +0 -11278
  131. package/dist/text-CyetbF6p.js.map +0 -1
  132. package/dist/units-1kRzYShk.js +0 -231
  133. package/dist/units-1kRzYShk.js.map +0 -1
  134. package/dist/units-internal-Dg95w_YD.js.map +0 -1
  135. package/dist/zip.d.ts.map +0 -1
  136. package/dist/zip.js.map +0 -1
@@ -1,666 +0,0 @@
1
- import { S as warnOnce } from "./units-1kRzYShk.js";
2
- import { n as InvalidOptionError } from "./errors-Bvln0H-7.js";
3
- //#region src/ooxml/check-enum.ts
4
- /**
5
- * Check a value against its `ST_` union, reporting and dropping it when outside (the write-path
6
- * policy — see the module note).
7
- *
8
- * `undefined`/`null` returns `null` without reporting: an unset option is not an invalid one, and
9
- * it is by far the common case.
10
- *
11
- * The offending value is interpolated into the message deliberately. {@link warnOnce} dedups on
12
- * code **and** message, so keeping the value in the text is what lets a second, *different* bad
13
- * value under the same code still get reported.
14
- * @param value - the value the caller supplied, if any
15
- * @param valid - the enum's members
16
- * @param code - the condition to report
17
- * @param label - how to name the offending option in the message, e.g. ``'table cell: cell3D `preset`'``
18
- * @param detail - extra structured context to merge into the diagnostic's `detail`
19
- * @returns the value when legal, else `null`
20
- */
21
- function checkEnumOrWarn(value, valid, code, label, detail) {
22
- if (value === void 0 || value === null) return null;
23
- if (valid.includes(value)) return value;
24
- warnOnce(code, `${label} value \`${String(value)}\` is not valid and is ignored — use one of ${valid.join(", ")}.`, {
25
- received: value,
26
- valid,
27
- ...detail
28
- });
29
- return null;
30
- }
31
- /**
32
- * Check a value against its `ST_` union, throwing when outside (the read/edit-path policy — see
33
- * the module note).
34
- * @param value - the value the caller asked for
35
- * @param valid - the enum's members
36
- * @param attribute - the attribute's name, for the message
37
- * @param code - the condition to report
38
- * @returns `value`, when it is legal
39
- */
40
- function checkEnumOrThrow(value, valid, attribute, code) {
41
- if (valid.includes(value)) return value;
42
- throw new InvalidOptionError(code, `Invalid ${attribute}: ${JSON.stringify(value)}. Expected one of: ${valid.join(", ")}.`);
43
- }
44
- //#endregion
45
- //#region src/ooxml/st-enums.ts
46
- /**
47
- * `ST_` simple-type enumerations from ECMA-376, declared once as the single source of both the
48
- * TypeScript union a caller is checked against and the runtime list a value is validated against.
49
- *
50
- * **The problem this solves.** Each of these used to exist twice: a hand-written string union in
51
- * `src/types/` (what the compiler enforces) and a hand-written array in `src/gen/` or `src/read/`
52
- * (what the validator checks at run time). Nothing tied the two together, so adding a member to
53
- * one and not the other produced either a value TypeScript accepts and the validator drops, or a
54
- * value the validator passes and the type rejects. Two of them had already diverged in *order*,
55
- * which is harmless, but nothing would have caught a divergence in *content*.
56
- *
57
- * **The shape.** Every entry is a `readonly` tuple declared `as const`, with its union derived via
58
- * `(typeof X)[number]`. Widening the tuple widens the union in the same edit — they cannot drift.
59
- * This is the idiom already used for `EMBEDDED_FONT_SLOTS` and `EXTRA_SHAPE_PRESETS`; this module
60
- * brings the stragglers onto it.
61
- *
62
- * **Why this module is neither `gen/` nor `read/`.** `src/types/` needs the unions for the public
63
- * write API, `src/gen/` needs the tuples to vet a value before emitting it, and `src/read/` needs
64
- * them to vet a value before writing it into a loaded part. It is a fact about the schema, so it
65
- * belongs to none of the three.
66
- *
67
- * Values are listed in **schema declaration order**, which is the order the diagnostics print
68
- * when they tell a caller what is legal.
69
- */
70
- /**
71
- * `ST_BevelPresetType` — the bevel profile applied to a 3-D edge.
72
- * @see ECMA-376 Part 1 §20.1.10.9
73
- */
74
- const BEVEL_PRESETS = [
75
- "relaxedInset",
76
- "circle",
77
- "slope",
78
- "cross",
79
- "angle",
80
- "softRound",
81
- "convex",
82
- "coolSlant",
83
- "divot",
84
- "riblet",
85
- "hardEdge",
86
- "artDeco"
87
- ];
88
- /**
89
- * `ST_PresetMaterialType` — how a 3-D surface responds to light.
90
- * @see ECMA-376 Part 1 §20.1.10.50
91
- */
92
- const PRESET_MATERIALS = [
93
- "legacyMatte",
94
- "legacyPlastic",
95
- "legacyMetal",
96
- "legacyWireframe",
97
- "matte",
98
- "plastic",
99
- "metal",
100
- "warmMatte",
101
- "translucentPowder",
102
- "powder",
103
- "dkEdge",
104
- "softEdge",
105
- "clear",
106
- "flat",
107
- "softmetal"
108
- ];
109
- /**
110
- * `ST_LightRigType` — the preset lighting scene.
111
- * @see ECMA-376 Part 1 §20.1.10.35
112
- */
113
- const LIGHT_RIGS = [
114
- "legacyFlat1",
115
- "legacyFlat2",
116
- "legacyFlat3",
117
- "legacyFlat4",
118
- "legacyNormal1",
119
- "legacyNormal2",
120
- "legacyNormal3",
121
- "legacyNormal4",
122
- "legacyHarsh1",
123
- "legacyHarsh2",
124
- "legacyHarsh3",
125
- "legacyHarsh4",
126
- "threePt",
127
- "balanced",
128
- "soft",
129
- "harsh",
130
- "flood",
131
- "contrasting",
132
- "morning",
133
- "sunrise",
134
- "sunset",
135
- "chilly",
136
- "freezing",
137
- "flat",
138
- "twoPt",
139
- "glow",
140
- "brightRoom"
141
- ];
142
- /**
143
- * `ST_LightRigDirection` — where the light rig sits relative to the scene.
144
- * @see ECMA-376 Part 1 §20.1.10.33
145
- */
146
- const LIGHT_RIG_DIRECTIONS = [
147
- "tl",
148
- "t",
149
- "tr",
150
- "l",
151
- "r",
152
- "bl",
153
- "b",
154
- "br"
155
- ];
156
- /**
157
- * `ST_TextHorzOverflowType` — `a:bodyPr/@horzOverflow` and `a:tcPr/@horzOverflow`.
158
- * @see ECMA-376 Part 1 §20.1.10.68
159
- */
160
- const TEXT_HORZ_OVERFLOW = ["clip", "overflow"];
161
- /**
162
- * `ST_TextAnchoringType` — `a:bodyPr/@anchor` and `a:tcPr/@anchor`.
163
- * @see ECMA-376 Part 1 §20.1.10.60
164
- */
165
- const TEXT_ANCHORS = [
166
- "t",
167
- "ctr",
168
- "b",
169
- "just",
170
- "dist"
171
- ];
172
- /**
173
- * `ST_TextVerticalType` — `a:bodyPr/@vert` and `a:tcPr/@vert`.
174
- * @see ECMA-376 Part 1 §20.1.10.83
175
- */
176
- const TEXT_VERTICAL = [
177
- "horz",
178
- "vert",
179
- "vert270",
180
- "wordArtVert",
181
- "eaVert",
182
- "mongolianVert",
183
- "wordArtVertRtl"
184
- ];
185
- /**
186
- * `ST_PresetLineDashVal` — the dash pattern of a line or border (`a:prstDash/@val`).
187
- *
188
- * The `sys*` members are the "system" dashes whose exact dot/gap ratio the renderer picks; the
189
- * rest are defined by the spec. Both `BorderProps.dashType` and `ShapeLineProps.dashType` accept
190
- * this whole set, so a caller who knows one knows the other.
191
- * @see ECMA-376 Part 1 §20.1.10.49
192
- */
193
- const PRESET_LINE_DASHES = [
194
- "solid",
195
- "dot",
196
- "dash",
197
- "lgDash",
198
- "dashDot",
199
- "lgDashDot",
200
- "lgDashDotDot",
201
- "sysDash",
202
- "sysDot",
203
- "sysDashDot",
204
- "sysDashDotDot"
205
- ];
206
- /**
207
- * The twelve theme colour slots (`a:clrScheme` children) a `p:clrMap` token can point at.
208
- *
209
- * Not an `ST_` type — these are element names inside `a:CT_ColorScheme`, which the schema
210
- * declares as a fixed sequence rather than an enumeration. The effect is the same: a closed,
211
- * ordered set of twelve names, in the order the scheme declares them.
212
- * @see ECMA-376 Part 1 §20.1.6.2
213
- */
214
- const THEME_COLOR_SLOTS = [
215
- "dk1",
216
- "lt1",
217
- "dk2",
218
- "lt2",
219
- "accent1",
220
- "accent2",
221
- "accent3",
222
- "accent4",
223
- "accent5",
224
- "accent6",
225
- "hlink",
226
- "folHlink"
227
- ];
228
- /**
229
- * The twelve colour-map tokens (`p:clrMap` attributes), in schema attribute order.
230
- *
231
- * A slide's `schemeClr val="tx1"` names a *token*, not a slot: the master's `p:clrMap` is the
232
- * indirection that sends it to a {@link ThemeColorSlot}. Which is why the two lists look alike
233
- * and are not the same list — `bg1`/`tx1` are tokens, `lt1`/`dk1` are slots.
234
- * @see ECMA-376 Part 1 §19.3.1.6
235
- */
236
- const COLOR_MAP_TOKENS = [
237
- "bg1",
238
- "tx1",
239
- "bg2",
240
- "tx2",
241
- "accent1",
242
- "accent2",
243
- "accent3",
244
- "accent4",
245
- "accent5",
246
- "accent6",
247
- "hlink",
248
- "folHlink"
249
- ];
250
- /**
251
- * The identity colour map: the `p:clrMap` this library emits on every master and notes master,
252
- * and the one the script printer recognises so it can skip printing a map that is the default.
253
- *
254
- * "Identity" up to the light/dark naming: each token points at the slot of the same name, with
255
- * `bg`/`tx` reading as light/dark. A deck that maps them anywhere else — swapping the light and
256
- * dark slots is the usual case — resolves every `schemeClr` in the deck differently.
257
- *
258
- * Typed `Record<ColorMapToken, ThemeColorSlot>` so a token added to {@link COLOR_MAP_TOKENS}
259
- * without a mapping, or a slot misspelled, is a compile error rather than a theme that opens
260
- * fine and paints one script in the wrong colour. Declared in the same order as the tokens,
261
- * because it is emitted by iterating this object and the attribute order is part of the bytes.
262
- */
263
- const DEFAULT_COLOR_MAP = {
264
- bg1: "lt1",
265
- tx1: "dk1",
266
- bg2: "lt2",
267
- tx2: "dk2",
268
- accent1: "accent1",
269
- accent2: "accent2",
270
- accent3: "accent3",
271
- accent4: "accent4",
272
- accent5: "accent5",
273
- accent6: "accent6",
274
- hlink: "hlink",
275
- folHlink: "folHlink"
276
- };
277
- //#endregion
278
- //#region src/media/base64.ts
279
- /**
280
- * Base64 payload handling for media parts — isomorphic across Node and browsers
281
- * (`TextEncoder`/`atob`/`btoa` only, no `Buffer`).
282
- */
283
- /**
284
- * Encode raw SVG markup as a base64 `image/svg+xml` data URI.
285
- * - lets callers pass inline SVG to `addImage({ svg })` without hand-rolling base64
286
- * - isomorphic and UTF-8 safe: uses the global `TextEncoder`/`btoa` (Node and browsers)
287
- * @param {string} svg - SVG markup, e.g. `'<svg ...>...</svg>'`
288
- * @returns {string} a `data:image/svg+xml;base64,...` URI
289
- */
290
- function svgMarkupToDataUri(svg) {
291
- return `data:image/svg+xml;base64,${bytesToBase64(new TextEncoder().encode(svg))}`;
292
- }
293
- /**
294
- * Encode raw bytes as base64 (no `data:` prefix) using only `btoa`, so the result is the same
295
- * on Node, in a browser, and in a runtime that has neither `Buffer` nor `FileReader`.
296
- *
297
- * Chunked because `String.fromCharCode(...spread)` blows the argument-count limit on a payload
298
- * of any real size — a multi-megabyte video rel would throw rather than encode.
299
- * @param {Uint8Array} bytes - the payload
300
- * @returns {string} base64 text
301
- */
302
- function bytesToBase64(bytes) {
303
- const CHUNK = 32768;
304
- let binary = "";
305
- for (let i = 0; i < bytes.length; i += CHUNK) binary += String.fromCharCode(...bytes.subarray(i, i + CHUNK));
306
- return btoa(binary);
307
- }
308
- /**
309
- * Present a freshly loaded media payload as a `data:` URI.
310
- *
311
- * A {@link RuntimeAdapter.loadMedia} implementation returns whichever encoding its host
312
- * makes cheap — the browser adapter a full URI, because `FileReader.readAsDataURL` is what
313
- * decodes a blob without blocking; Node and the neutral adapter raw base64, because neither
314
- * has a `FileReader`. This is where the two become one, so nothing downstream of the load
315
- * has to ask which it got.
316
- *
317
- * The mime label is documentary: {@link decodeBase64ToBytes} ignores it, and the one consumer
318
- * that needs a real URI (`image.src`, in the browser adapter's SVG preview) is handed the
319
- * adapter's own. It is taken from the rel anyway rather than hard-coded, so an already-correct
320
- * label is not overwritten with a wrong one.
321
- * @param {string} payload - what the adapter returned: raw base64, or an already-formed URI
322
- * @param {string} contentType - the rel's content type, e.g. `image/png`
323
- * @returns {string} a `data:` URI
324
- */
325
- function toMediaDataUri(payload, contentType) {
326
- return payload.startsWith("data:") ? payload : `data:${contentType};base64,${payload}`;
327
- }
328
- /**
329
- * Decode a base64 image payload (raw base64 or a `data:` URI) to bytes.
330
- * - tolerant of the `data:[mime];base64,` prefix and of whitespace in the payload
331
- * @param {string} b64 - base64 string or data URI
332
- * @returns {Uint8Array | null} decoded bytes, or `null` when the payload is empty/undecodable
333
- */
334
- function decodeBase64ToBytes(b64) {
335
- if (!b64) return null;
336
- const comma = b64.indexOf("base64,");
337
- const payload = (comma >= 0 ? b64.slice(comma + 7) : b64).replace(/\s/g, "");
338
- if (!payload) return null;
339
- try {
340
- const binary = atob(payload);
341
- const bytes = new Uint8Array(binary.length);
342
- for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
343
- return bytes;
344
- } catch {
345
- return null;
346
- }
347
- }
348
- //#endregion
349
- //#region src/media/image-size.ts
350
- /**
351
- * Intrinsic image geometry: reading a natural pixel size out of header bytes, and the
352
- * `<a:srcRect>` crop math that fits that natural size into a display box.
353
- *
354
- * Shared by both sides of the library — the write path (`addImage({ sizing })`) and the read
355
- * API's `Picture.setImage({ fit })` — which is why it lives outside `gen/` and `read/`.
356
- * Everything here is synchronous and pure: headers only, never pixel decoding.
357
- */
358
- /**
359
- * Read the intrinsic dimensions of an image from its header bytes.
360
- * - synchronous: parses only file-format headers, never decodes pixels
361
- * - raster: PNG, JPEG, GIF, BMP, and WebP (VP8 / VP8L / VP8X) — natural pixels
362
- * - vector: SVG — intrinsic size from the root `<svg>` width/height or viewBox
363
- * - unrecognized formats return `null` (no measurable intrinsic size)
364
- *
365
- * Used by image `sizing: 'cover' | 'contain'` to compute an aspect-correct
366
- * `<a:srcRect>` crop from the *natural* image ratio rather than the displayed box.
367
- * @param {string} dataB64 - base64 image payload or `data:` URI
368
- * @returns {{ w: number, h: number } | null} natural size, or `null` when unmeasurable
369
- */
370
- function getImageSizeFromBase64(dataB64) {
371
- const b = decodeBase64ToBytes(dataB64);
372
- return b ? getImageSizeFromBytes(b) : null;
373
- }
374
- /**
375
- * Read the intrinsic dimensions of an image from raw header bytes — the
376
- * byte-level core shared by {@link getImageSizeFromBase64} and the read API's
377
- * `Picture.setImage({ fit })`, which already holds the media bytes.
378
- * @param {Uint8Array} b - image bytes
379
- * @returns {{ w: number, h: number } | null} natural size, or `null` when unmeasurable
380
- */
381
- function getImageSizeFromBytes(b) {
382
- if (!b || b.length < 24) return null;
383
- const u = (n) => b[n] ?? 0;
384
- if (b[0] === 137 && b[1] === 80 && b[2] === 78 && b[3] === 71) {
385
- const w = u(16) << 24 | u(17) << 16 | u(18) << 8 | u(19);
386
- const h = u(20) << 24 | u(21) << 16 | u(22) << 8 | u(23);
387
- return w > 0 && h > 0 ? {
388
- w,
389
- h
390
- } : null;
391
- }
392
- if (b[0] === 71 && b[1] === 73 && b[2] === 70) {
393
- const w = u(6) | u(7) << 8;
394
- const h = u(8) | u(9) << 8;
395
- return w > 0 && h > 0 ? {
396
- w,
397
- h
398
- } : null;
399
- }
400
- if (b[0] === 66 && b[1] === 77) {
401
- const w = u(18) | u(19) << 8 | u(20) << 16 | u(21) << 24;
402
- const h = u(22) | u(23) << 8 | u(24) << 16 | u(25) << 24;
403
- const aw = Math.abs(w);
404
- const ah = Math.abs(h);
405
- return aw > 0 && ah > 0 ? {
406
- w: aw,
407
- h: ah
408
- } : null;
409
- }
410
- if (b[0] === 82 && b[1] === 73 && b[2] === 70 && b[3] === 70 && b[8] === 87 && b[9] === 69 && b[10] === 66 && b[11] === 80) {
411
- const fourCC = String.fromCharCode(u(12), u(13), u(14), u(15));
412
- if (fourCC === "VP8 " && b.length >= 30) {
413
- const w = (u(26) | u(27) << 8) & 16383;
414
- const h = (u(28) | u(29) << 8) & 16383;
415
- return w > 0 && h > 0 ? {
416
- w,
417
- h
418
- } : null;
419
- }
420
- if (fourCC === "VP8L" && b.length >= 25) {
421
- const bits = u(21) | u(22) << 8 | u(23) << 16 | u(24) << 24;
422
- const w = (bits & 16383) + 1;
423
- const h = (bits >> 14 & 16383) + 1;
424
- return w > 0 && h > 0 ? {
425
- w,
426
- h
427
- } : null;
428
- }
429
- if (fourCC === "VP8X" && b.length >= 30) {
430
- const w = (u(24) | u(25) << 8 | u(26) << 16) + 1;
431
- const h = (u(27) | u(28) << 8 | u(29) << 16) + 1;
432
- return w > 0 && h > 0 ? {
433
- w,
434
- h
435
- } : null;
436
- }
437
- return null;
438
- }
439
- if (b[0] === 255 && b[1] === 216) {
440
- let i = 2;
441
- while (i + 9 < b.length) {
442
- if (b[i] !== 255) {
443
- i++;
444
- continue;
445
- }
446
- const marker = u(i + 1);
447
- if (marker >= 192 && marker <= 207 && marker !== 196 && marker !== 200 && marker !== 204) {
448
- const h = u(i + 5) << 8 | u(i + 6);
449
- const w = u(i + 7) << 8 | u(i + 8);
450
- return w > 0 && h > 0 ? {
451
- w,
452
- h
453
- } : null;
454
- }
455
- if (marker >= 208 && marker <= 217 || marker === 1) {
456
- i += 2;
457
- continue;
458
- }
459
- const segLen = u(i + 2) << 8 | u(i + 3);
460
- if (segLen < 2) break;
461
- i += 2 + segLen;
462
- }
463
- return null;
464
- }
465
- const text = utf8Decode(b);
466
- if (/<svg[\s>]/i.test(text)) return getSvgSizeFromMarkup(text);
467
- return null;
468
- }
469
- /**
470
- * Compute the `<a:srcRect>` crop percentages (each in 1/1000 of a percent, the
471
- * OOXML unit) for fitting an image of natural size `img` into a display `box`,
472
- * assuming the cropped region is then stretched to fill the box (`<a:stretch>`).
473
- *
474
- * - `cover`: fill the box, cropping the overflowing axis (positive l/r or t/b)
475
- * - `contain`: fit inside the box, letterboxing the short axis (negative l/r or t/b)
476
- *
477
- * Single source of truth for the crop math shared by the write side
478
- * (`ImageSizingXml`) and the read API's `Picture.setImage({ fit })`. `l`/`r` and
479
- * `t`/`b` are symmetric (centered crop).
480
- * @param {'cover' | 'contain'} type - fit mode
481
- * @param {{ w: number, h: number }} img - natural image pixel size
482
- * @param {{ w: number, h: number }} box - displayed frame size (any consistent unit)
483
- * @returns {{ l: number, r: number, t: number, b: number }} srcRect percentages
484
- */
485
- function fitSrcRectPercents(type, img, box) {
486
- const imgRatio = img.h / img.w;
487
- const boxRatio = box.h / box.w;
488
- let width;
489
- let height;
490
- if (type === "cover") {
491
- const isBoxBased = boxRatio > imgRatio;
492
- width = isBoxBased ? box.h / imgRatio : box.w;
493
- height = isBoxBased ? box.h : box.w * imgRatio;
494
- } else {
495
- const widthBased = boxRatio > imgRatio;
496
- width = widthBased ? box.w : box.h / imgRatio;
497
- height = widthBased ? box.w * imgRatio : box.h;
498
- }
499
- const hz = Math.round(5e4 * (1 - box.w / width));
500
- const vz = Math.round(5e4 * (1 - box.h / height));
501
- return {
502
- l: hz,
503
- r: hz,
504
- t: vz,
505
- b: vz
506
- };
507
- }
508
- /**
509
- * Read the intrinsic size of an SVG document from its root `<svg>` element.
510
- * Follows the SVG sizing model: an explicit absolute `width`/`height` pair wins;
511
- * otherwise the `viewBox` width/height defines the size (and thus aspect ratio).
512
- * Percentage or missing `width`/`height` fall through to `viewBox`.
513
- * @param {string} svg - SVG markup
514
- * @returns {{ w: number, h: number } | null} intrinsic size, or `null` when undeterminable
515
- */
516
- function getSvgSizeFromMarkup(svg) {
517
- const openTag = /<svg\b[^>]*>/i.exec(svg)?.[0];
518
- if (!openTag) return null;
519
- const attr = (name) => new RegExp(`\\b${name}\\s*=\\s*["']([^"']*)["']`, "i").exec(openTag)?.[1] ?? null;
520
- const absLength = (val) => {
521
- if (val == null || /%\s*$/.test(val)) return NaN;
522
- const m = /^\s*\+?(\d*\.?\d+)/.exec(val);
523
- return m ? parseFloat(m[1] ?? "") : NaN;
524
- };
525
- let w = absLength(attr("width"));
526
- let h = absLength(attr("height"));
527
- if (!(w > 0 && h > 0)) {
528
- const vb = attr("viewBox");
529
- const p = vb ? vb.trim().split(/[\s,]+/).map(Number) : [];
530
- const vw = p[2];
531
- const vh = p[3];
532
- if (p.length === 4 && vw != null && vh != null && vw > 0 && vh > 0) {
533
- w = vw;
534
- h = vh;
535
- }
536
- }
537
- return w > 0 && h > 0 ? {
538
- w,
539
- h
540
- } : null;
541
- }
542
- /** Decode UTF-8 bytes to a string, isomorphic across Node and browsers. */
543
- function utf8Decode(bytes) {
544
- return new TextDecoder().decode(bytes);
545
- }
546
- //#endregion
547
- //#region src/ooxml/rel-types.ts
548
- /**
549
- * OPC relationship type URIs and part content types, and the schema-URI bases they are built from.
550
- *
551
- * These are long, near-identical strings that differ in one path segment, which makes a typo
552
- * both easy to write and invisible on review — a wrong URI does not throw, it silently matches
553
- * nothing on the read side and produces a part PowerPoint ignores or rejects on the write side.
554
- *
555
- * **Why this module is neither `gen/` nor `read/`.** Both halves need the same URIs, and for a
556
- * while each kept its own copy (`gen/oxml/schema-uris.ts`, `read/api/rel-types.ts`), with a note
557
- * in both saying a shared home was "a separate decision". It is this module: a rel type is a fact
558
- * about the OOXML package format, not about writing or reading one, so neither side should own it.
559
- * A divergence between the two copies would mean the writer emitting a rel the reader cannot find
560
- * — a round-trip bug with no compile-time signal.
561
- *
562
- * Only types used by more than one module live here. A rel type exactly one module cares about
563
- * (`chart`, `hyperlink`, `tags`, the two comments parts, `oleObject`, the MS media rels, …) stays
564
- * declared next to the code that reads or emits it — hoisting those would trade a definition you
565
- * can see for one you have to go and find, and buy nothing.
566
- *
567
- * The same reasoning covers **part content types**, which are the same kind of fact and fail the
568
- * same silent way. The write side is the exception at the bottom of this file: `[Content_Types].xml`
569
- * spells its entries out locally so each one stays greppable by its suffix next to the part it
570
- * declares.
571
- */
572
- /** Root of every ECMA-376 schema URI. Private: callers want one of the prefixes below. */
573
- const SCHEMA_BASE = "http://schemas.openxmlformats.org/";
574
- /**
575
- * Prefix for `.rels` `Type` URIs — append the type name (`slide`, `image`, `theme`, …).
576
- * Exported for the write side, which builds one-off rel types at their call sites.
577
- */
578
- const OFFICE_REL = SCHEMA_BASE + "officeDocument/2006/relationships/";
579
- /** `xmlns` of every `<Relationships>` part. Also the prefix of the package-scoped rel types. */
580
- const PACKAGE_REL_NS = SCHEMA_BASE + "package/2006/relationships";
581
- /** `p:sldIdLst` → a slide part. */
582
- const SLIDE_REL = OFFICE_REL + "slide";
583
- /** A slide → its layout; a master → each of its layouts. */
584
- const SLIDE_LAYOUT_REL = OFFICE_REL + "slideLayout";
585
- /** A layout → its master; the presentation → each master. */
586
- const SLIDE_MASTER_REL = OFFICE_REL + "slideMaster";
587
- /** A slide → its notes slide. */
588
- const NOTES_SLIDE_REL = OFFICE_REL + "notesSlide";
589
- /** A notes slide → the notes master; the presentation → the notes master. */
590
- const NOTES_MASTER_REL = OFFICE_REL + "notesMaster";
591
- /** A master or notes master → its theme. Layouts and slides inherit it rather than holding one. */
592
- const THEME_REL = OFFICE_REL + "theme";
593
- /** The package root → `ppt/presentation.xml`. The entry point to everything above. */
594
- const OFFICE_DOCUMENT_REL = OFFICE_REL + "officeDocument";
595
- /** Any part → an image in `ppt/media/`. */
596
- const IMAGE_REL = OFFICE_REL + "image";
597
- /** Root of the ECMA-376 content types. Private: callers want one of the constants below. */
598
- const OD_CONTENT = "application/vnd.openxmlformats-officedocument.";
599
- /** `ppt/slides/slideN.xml`. */
600
- const SLIDE_CONTENT_TYPE = OD_CONTENT + "presentationml.slide+xml";
601
- /** `ppt/slideMasters/slideMasterN.xml`. */
602
- const SLIDE_MASTER_CONTENT_TYPE = OD_CONTENT + "presentationml.slideMaster+xml";
603
- /** `ppt/slideLayouts/slideLayoutN.xml`. */
604
- const SLIDE_LAYOUT_CONTENT_TYPE = OD_CONTENT + "presentationml.slideLayout+xml";
605
- /** `ppt/notesSlides/notesSlideN.xml`. */
606
- const NOTES_SLIDE_CONTENT_TYPE = OD_CONTENT + "presentationml.notesSlide+xml";
607
- /** `ppt/notesMasters/notesMasterN.xml`. */
608
- const NOTES_MASTER_CONTENT_TYPE = OD_CONTENT + "presentationml.notesMaster+xml";
609
- /** `ppt/theme/themeN.xml`. Not `presentationml.`: a theme is a DrawingML part. */
610
- const THEME_CONTENT_TYPE = OD_CONTENT + "theme+xml";
611
- //#endregion
612
- //#region src/ooxml/namespaces.ts
613
- /**
614
- * OOXML namespace URIs, by their canonical prefix.
615
- *
616
- * A namespace URI is a fact about the format, not about reading or writing one, so it belongs
617
- * here rather than on either side — the same reasoning `rel-types.ts` states at length, and for
618
- * the same failure mode: these are long, near-identical strings, and a typo does not throw. It
619
- * silently matches nothing on the read side and produces a part PowerPoint ignores on the write
620
- * side.
621
- *
622
- * The table lived in `read/oxml/dom.ts` and could not be reached from `gen/`, because that
623
- * module imports `@xmldom/xmldom` at module scope and pulling an XML DOM into the write-only
624
- * bundle is a real cost. So the write side hand-wrote the URIs instead: three separate `A_NS`
625
- * constants and seven copies of the same `xmlns:a`/`xmlns:r`/`xmlns:p` triple. This module has
626
- * **no runtime imports** — like `rel-types.ts`, `st-enums.ts` and `sequence.ts` beside it — so
627
- * both sides can reach it and neither pays for the other's dependencies. `read/oxml/dom.ts`
628
- * re-exports it, so no read-side import path changed.
629
- */
630
- /** Canonical OOXML prefix → namespace URI registry. */
631
- const OOXML_NS = Object.freeze({
632
- a: "http://schemas.openxmlformats.org/drawingml/2006/main",
633
- c: "http://schemas.openxmlformats.org/drawingml/2006/chart",
634
- cp: "http://schemas.openxmlformats.org/package/2006/metadata/core-properties",
635
- ct: "http://schemas.openxmlformats.org/package/2006/content-types",
636
- cx: "http://schemas.microsoft.com/office/drawing/2014/chartex",
637
- dc: "http://purl.org/dc/elements/1.1/",
638
- dcterms: "http://purl.org/dc/terms/",
639
- dgm: "http://schemas.openxmlformats.org/drawingml/2006/diagram",
640
- dsp: "http://schemas.microsoft.com/office/drawing/2008/diagram",
641
- ep: "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties",
642
- mc: "http://schemas.openxmlformats.org/markup-compatibility/2006",
643
- p: "http://schemas.openxmlformats.org/presentationml/2006/main",
644
- p14: "http://schemas.microsoft.com/office/powerpoint/2010/main",
645
- p188: "http://schemas.microsoft.com/office/powerpoint/2018/8/main",
646
- pr: "http://schemas.openxmlformats.org/package/2006/relationships",
647
- r: "http://schemas.openxmlformats.org/officeDocument/2006/relationships"
648
- });
649
- /**
650
- * The `xmlns` declarations every PresentationML part root carries, in the order the emitters
651
- * have always written them.
652
- *
653
- * Spread this **first** in a root element's attribute map: `el()` serializes attributes in
654
- * object-key order, so the three keys have to keep the positions the literals occupied or the
655
- * emitted bytes move. A root with extra attributes (`show` on `p:sld`, `def` on `a:tblStyleLst`)
656
- * lists them after the spread, which is where they already were.
657
- */
658
- const PML_ROOT_NS = Object.freeze({
659
- "xmlns:a": OOXML_NS.a,
660
- "xmlns:r": OOXML_NS.r,
661
- "xmlns:p": OOXML_NS.p
662
- });
663
- //#endregion
664
- export { LIGHT_RIG_DIRECTIONS as A, decodeBase64ToBytes as C, COLOR_MAP_TOKENS as D, BEVEL_PRESETS as E, TEXT_VERTICAL as F, THEME_COLOR_SLOTS as I, checkEnumOrThrow as L, PRESET_MATERIALS as M, TEXT_ANCHORS as N, DEFAULT_COLOR_MAP as O, TEXT_HORZ_OVERFLOW as P, checkEnumOrWarn as R, bytesToBase64 as S, toMediaDataUri as T, THEME_CONTENT_TYPE as _, NOTES_MASTER_REL as a, getImageSizeFromBase64 as b, OFFICE_DOCUMENT_REL as c, SLIDE_CONTENT_TYPE as d, SLIDE_LAYOUT_CONTENT_TYPE as f, SLIDE_REL as g, SLIDE_MASTER_REL as h, NOTES_MASTER_CONTENT_TYPE as i, PRESET_LINE_DASHES as j, LIGHT_RIGS as k, OFFICE_REL as l, SLIDE_MASTER_CONTENT_TYPE as m, PML_ROOT_NS as n, NOTES_SLIDE_CONTENT_TYPE as o, SLIDE_LAYOUT_REL as p, IMAGE_REL as r, NOTES_SLIDE_REL as s, OOXML_NS as t, PACKAGE_REL_NS as u, THEME_REL as v, svgMarkupToDataUri as w, getImageSizeFromBytes as x, fitSrcRectPercents as y };
665
-
666
- //# sourceMappingURL=namespaces-BVnNu7sg.js.map