@shbernal/ts-pptx 0.0.1

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 (81) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +238 -0
  3. package/dist/autopage-tmfjRzL4.js +420 -0
  4. package/dist/autopage-tmfjRzL4.js.map +1 -0
  5. package/dist/browser.d.ts +23 -0
  6. package/dist/browser.d.ts.map +1 -0
  7. package/dist/browser.js +103 -0
  8. package/dist/browser.js.map +1 -0
  9. package/dist/diagnostics-DYQC7xLV.js +0 -0
  10. package/dist/diagnostics-DYQC7xLV.js.map +1 -0
  11. package/dist/diagnostics-DzY9Tyfm.d.ts +693 -0
  12. package/dist/diagnostics-DzY9Tyfm.d.ts.map +1 -0
  13. package/dist/embedded-fonts-MaynAHa9.js +94 -0
  14. package/dist/embedded-fonts-MaynAHa9.js.map +1 -0
  15. package/dist/enums-D3aF4QGb.d.ts +452 -0
  16. package/dist/enums-D3aF4QGb.d.ts.map +1 -0
  17. package/dist/errors-DGE9zh3U.js +93 -0
  18. package/dist/errors-DGE9zh3U.js.map +1 -0
  19. package/dist/errors-DRLpOpgQ.d.ts +160 -0
  20. package/dist/errors-DRLpOpgQ.d.ts.map +1 -0
  21. package/dist/fit-CbxyHN69.js +0 -0
  22. package/dist/fit-CbxyHN69.js.map +1 -0
  23. package/dist/html-dom-wVa3TiG7.js +666 -0
  24. package/dist/html-dom-wVa3TiG7.js.map +1 -0
  25. package/dist/html.d.ts +26 -0
  26. package/dist/html.d.ts.map +1 -0
  27. package/dist/html.js +60 -0
  28. package/dist/html.js.map +1 -0
  29. package/dist/image-size-C5Z1sKof.js +252 -0
  30. package/dist/image-size-C5Z1sKof.js.map +1 -0
  31. package/dist/index.d.ts +24 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +75 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/inspect.d.ts +173 -0
  36. package/dist/inspect.d.ts.map +1 -0
  37. package/dist/inspect.js +285 -0
  38. package/dist/inspect.js.map +1 -0
  39. package/dist/math.d.ts +37 -0
  40. package/dist/math.d.ts.map +1 -0
  41. package/dist/math.js +106 -0
  42. package/dist/math.js.map +1 -0
  43. package/dist/measure.d.ts +223 -0
  44. package/dist/measure.d.ts.map +1 -0
  45. package/dist/measure.js +3 -0
  46. package/dist/node.d.ts +12 -0
  47. package/dist/node.d.ts.map +1 -0
  48. package/dist/node.js +60 -0
  49. package/dist/node.js.map +1 -0
  50. package/dist/package-CaOLXSNi.d.ts +193 -0
  51. package/dist/package-CaOLXSNi.d.ts.map +1 -0
  52. package/dist/pres-5x1bjCzk.d.ts +202 -0
  53. package/dist/pres-5x1bjCzk.d.ts.map +1 -0
  54. package/dist/presentation-B0JWdTN1.js +4286 -0
  55. package/dist/presentation-B0JWdTN1.js.map +1 -0
  56. package/dist/presentation-RGOiun5P.d.ts +3249 -0
  57. package/dist/presentation-RGOiun5P.d.ts.map +1 -0
  58. package/dist/presentation-types-BVw0EknS.d.ts +538 -0
  59. package/dist/presentation-types-BVw0EknS.d.ts.map +1 -0
  60. package/dist/read.d.ts +73 -0
  61. package/dist/read.d.ts.map +1 -0
  62. package/dist/read.js +4 -0
  63. package/dist/script.d.ts +553 -0
  64. package/dist/script.d.ts.map +1 -0
  65. package/dist/script.js +0 -0
  66. package/dist/script.js.map +1 -0
  67. package/dist/shapes-BZU8UTW2.js +5365 -0
  68. package/dist/shapes-BZU8UTW2.js.map +1 -0
  69. package/dist/slide-B6mDaM-P.d.ts +3396 -0
  70. package/dist/slide-B6mDaM-P.d.ts.map +1 -0
  71. package/dist/text-WRUbOy2r.js +11238 -0
  72. package/dist/text-WRUbOy2r.js.map +1 -0
  73. package/dist/units-B-JUKwCS.js +144 -0
  74. package/dist/units-B-JUKwCS.js.map +1 -0
  75. package/dist/units-internal-7JcMfYti.js +723 -0
  76. package/dist/units-internal-7JcMfYti.js.map +1 -0
  77. package/dist/zip.d.ts +68 -0
  78. package/dist/zip.d.ts.map +1 -0
  79. package/dist/zip.js +163 -0
  80. package/dist/zip.js.map +1 -0
  81. package/package.json +214 -0
package/dist/index.js ADDED
@@ -0,0 +1,75 @@
1
+ import { t as setDiagnosticHandler } from "./diagnostics-DYQC7xLV.js";
2
+ import { a as TsPptxError, i as PackageReadError, n as InvalidOptionError, o as UnsupportedFeatureError, r as MediaError, t as InternalError } from "./errors-DGE9zh3U.js";
3
+ import { _ as pointsToEmu, a as FIXED_PCT_PER_PERCENT, c as POINTS_PER_INCH, d as emuToInches, f as emuToPixels, g as pixelsToEmu, h as percentToEmu, i as EMU_PER_POINT, l as STANDARD_LAYOUTS, m as inchesToEmu, n as DEFAULT_PX_PER_INCH, o as HUNDREDTHS_PER_POINT, p as emuToPoints, r as EMU_PER_INCH, s as PERCENT_SCALE, t as ANGLE_UNITS_PER_DEGREE, u as coordToEmu, v as ptToHundredths } from "./units-B-JUKwCS.js";
4
+ import { n as textRuns, r as PresentationCore, t as textRun } from "./text-WRUbOy2r.js";
5
+ import { $ as connectorPresetFor, B as AlignV, G as PlaceholderType, H as CONNECTOR_PRESETS, J as SlideObjectType, K as SchemeColor, Q as asChartType, U as ChartType, V as BulletType, W as OutputType, X as TextAnchor, Y as TableStyle, Z as VALID_SHAPE_PRESETS, et as isChartExType, j as IMG_SVG_PLACEHOLDER, q as ShapeType, z as AlignH } from "./units-internal-7JcMfYti.js";
6
+ import { i as bytesToBase64 } from "./image-size-C5Z1sKof.js";
7
+ //#region src/runtime/neutral.ts
8
+ /**
9
+ * The adapter for a runtime that is neither Node nor a browser — Deno, Bun, an edge worker,
10
+ * anything that imports the bare `@shbernal/ts-pptx` specifier without resolving the `node` or
11
+ * `browser` export condition.
12
+ *
13
+ * It implements everything that is genuinely host-neutral and refuses only what is not.
14
+ * `fetch`, `btoa` and `TextEncoder` exist in all of these runtimes, so remote media and fonts
15
+ * load here exactly as they do in a browser. What is missing is a *destination*: there is no
16
+ * `node:fs` to write to and no `document` to hand a download to, so {@link RuntimeAdapter.writeFile}
17
+ * throws a named error rather than guessing. Everything that returns bytes to the caller —
18
+ * `write`, `stream`, `toParts` — works normally, which is the shape that suits a worker anyway.
19
+ */
20
+ function createNeutralRuntime() {
21
+ return {
22
+ writeFileOutputType: null,
23
+ loadMedia,
24
+ createSvgPngPreview,
25
+ writeFile,
26
+ loadFontData
27
+ };
28
+ }
29
+ async function loadFontData(source) {
30
+ const response = await fetch(source);
31
+ if (!response.ok) throw new MediaError("font/fetch-failed", `Unable to load font (fetch): ${source}`);
32
+ return new Uint8Array(await response.arrayBuffer());
33
+ }
34
+ /**
35
+ * Fetch-only: a bare filesystem path has no meaning without a filesystem, and `fetch` rejecting
36
+ * it is reported by the caller as a load failure naming the path. Returns raw base64 rather than
37
+ * a data URI (the browser adapter's `FileReader` shape) because there is no `FileReader` here;
38
+ * package assembly accepts either form.
39
+ */
40
+ async function loadMedia(rel) {
41
+ const response = await fetch(rel.path);
42
+ if (!response.ok) throw new MediaError("media/fetch-failed", `Unable to load image (fetch): ${rel.path}`);
43
+ return bytesToBase64(new Uint8Array(await response.arrayBuffer()));
44
+ }
45
+ /** Rasterizing an SVG needs a canvas. Same fallback as Node: emit the placeholder PNG. */
46
+ async function createSvgPngPreview(rel) {
47
+ rel.data = IMG_SVG_PLACEHOLDER;
48
+ return "done";
49
+ }
50
+ async function writeFile(fileName) {
51
+ throw new UnsupportedFeatureError("runtime/file-output-unavailable", `Cannot write "${fileName}": this runtime has neither a filesystem nor a DOM. Import "@shbernal/ts-pptx/node" to write to disk or "@shbernal/ts-pptx/browser" to trigger a download; anywhere else, use write() and persist the bytes yourself.`);
52
+ }
53
+ //#endregion
54
+ //#region src/index.ts
55
+ /**
56
+ * The runtime-agnostic entry: what a consumer gets from the bare `@shbernal/ts-pptx` specifier
57
+ * when neither the `node` nor the `browser` export condition resolves — Deno, Bun, edge workers.
58
+ * Node and browser consumers reach `ts-pptx/node` and `ts-pptx/browser` through those conditions
59
+ * without naming them, and get the same class backed by an adapter that can reach their host.
60
+ *
61
+ * Authoring is identical on all three. The difference is only where the finished deck can go:
62
+ * `write`, `stream` and `toParts` hand the bytes back here as everywhere, while `writeFile`
63
+ * throws `runtime/file-output-unavailable` because there is no filesystem and no DOM to write
64
+ * to. Live-DOM `tableToSlides` is likewise absent — it is defined on the browser entry, and the
65
+ * DOM-agnostic form is the free `tableToSlides` on `ts-pptx/html`.
66
+ */
67
+ var TsPptx = class extends PresentationCore {
68
+ constructor() {
69
+ super(createNeutralRuntime());
70
+ }
71
+ };
72
+ //#endregion
73
+ export { ANGLE_UNITS_PER_DEGREE, AlignH, AlignV, BulletType, CONNECTOR_PRESETS, ChartType, DEFAULT_PX_PER_INCH, EMU_PER_INCH, EMU_PER_POINT, FIXED_PCT_PER_PERCENT, HUNDREDTHS_PER_POINT, InternalError, InvalidOptionError, MediaError, OutputType, PERCENT_SCALE, POINTS_PER_INCH, PackageReadError, PlaceholderType, STANDARD_LAYOUTS, SchemeColor, ShapeType, SlideObjectType, TableStyle, TextAnchor, TsPptx, TsPptx as default, TsPptxError, UnsupportedFeatureError, VALID_SHAPE_PRESETS, asChartType, connectorPresetFor, coordToEmu, emuToInches, emuToPixels, emuToPoints, inchesToEmu, isChartExType, percentToEmu, pixelsToEmu, pointsToEmu, ptToHundredths, setDiagnosticHandler, textRun, textRuns };
74
+
75
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/runtime/neutral.ts","../src/index.ts"],"sourcesContent":["import { IMG_SVG_PLACEHOLDER } from '../constants-internal.js'\nimport { MediaError, UnsupportedFeatureError } from '../errors.js'\nimport { bytesToBase64 } from '../media/base64.js'\nimport type { SlideRelMedia } from '../types/internal.js'\nimport type { RuntimeAdapter } from './types.js'\n\n/**\n * The adapter for a runtime that is neither Node nor a browser — Deno, Bun, an edge worker,\n * anything that imports the bare `@shbernal/ts-pptx` specifier without resolving the `node` or\n * `browser` export condition.\n *\n * It implements everything that is genuinely host-neutral and refuses only what is not.\n * `fetch`, `btoa` and `TextEncoder` exist in all of these runtimes, so remote media and fonts\n * load here exactly as they do in a browser. What is missing is a *destination*: there is no\n * `node:fs` to write to and no `document` to hand a download to, so {@link RuntimeAdapter.writeFile}\n * throws a named error rather than guessing. Everything that returns bytes to the caller —\n * `write`, `stream`, `toParts` — works normally, which is the shape that suits a worker anyway.\n */\nexport function createNeutralRuntime(): RuntimeAdapter {\n\treturn {\n\t\twriteFileOutputType: null,\n\t\tloadMedia,\n\t\tcreateSvgPngPreview,\n\t\twriteFile,\n\t\tloadFontData,\n\t}\n}\n\nasync function loadFontData(source: string): Promise<Uint8Array> {\n\tconst response = await fetch(source)\n\tif (!response.ok) throw new MediaError('font/fetch-failed', `Unable to load font (fetch): ${source}`)\n\treturn new Uint8Array(await response.arrayBuffer())\n}\n\n/**\n * Fetch-only: a bare filesystem path has no meaning without a filesystem, and `fetch` rejecting\n * it is reported by the caller as a load failure naming the path. Returns raw base64 rather than\n * a data URI (the browser adapter's `FileReader` shape) because there is no `FileReader` here;\n * package assembly accepts either form.\n */\nasync function loadMedia(rel: SlideRelMedia & { path: string }): Promise<string> {\n\tconst response = await fetch(rel.path)\n\tif (!response.ok) throw new MediaError('media/fetch-failed', `Unable to load image (fetch): ${rel.path}`)\n\treturn bytesToBase64(new Uint8Array(await response.arrayBuffer()))\n}\n\n/** Rasterizing an SVG needs a canvas. Same fallback as Node: emit the placeholder PNG. */\nasync function createSvgPngPreview(rel: SlideRelMedia): Promise<string> {\n\trel.data = IMG_SVG_PLACEHOLDER\n\treturn 'done'\n}\n\nasync function writeFile(fileName: string): Promise<string> {\n\tthrow new UnsupportedFeatureError(\n\t\t'runtime/file-output-unavailable',\n\t\t`Cannot write \"${fileName}\": this runtime has neither a filesystem nor a DOM. ` +\n\t\t\t'Import \"@shbernal/ts-pptx/node\" to write to disk or \"@shbernal/ts-pptx/browser\" to trigger a ' +\n\t\t\t'download; anywhere else, use write() and persist the bytes yourself.'\n\t)\n}\n","import PresentationCore from './presentation.js'\nimport { createNeutralRuntime } from './runtime/neutral.js'\n\n/**\n * The runtime-agnostic entry: what a consumer gets from the bare `@shbernal/ts-pptx` specifier\n * when neither the `node` nor the `browser` export condition resolves — Deno, Bun, edge workers.\n * Node and browser consumers reach `ts-pptx/node` and `ts-pptx/browser` through those conditions\n * without naming them, and get the same class backed by an adapter that can reach their host.\n *\n * Authoring is identical on all three. The difference is only where the finished deck can go:\n * `write`, `stream` and `toParts` hand the bytes back here as everywhere, while `writeFile`\n * throws `runtime/file-output-unavailable` because there is no filesystem and no DOM to write\n * to. Live-DOM `tableToSlides` is likewise absent — it is defined on the browser entry, and the\n * DOM-agnostic form is the free `tableToSlides` on `ts-pptx/html`.\n */\nexport class TsPptx extends PresentationCore {\n\tconstructor() {\n\t\tsuper(createNeutralRuntime())\n\t}\n}\n\nexport { TsPptx as default }\nexport * from './enums.js'\nexport * from './units.js'\n// Use `export *` (not `export type *`) so the value exports `textRun`/`textRuns`\n// reach this entry; `export type *` would drop them and crash any consumer that\n// imports them, while TypeScript (reading index.d.ts) stays green.\nexport * from './types/index.js'\nexport { setDiagnosticHandler, type Diagnostic, type DiagnosticCode, type DiagnosticHandler } from './diagnostics.js'\n\n// Error taxonomy — every failure the library throws. The classes and their `code` are API;\n// the message is not. Re-exported from every entry so `instanceof` works whichever subpath a\n// consumer imports — they all resolve to one shared module, so the classes are identical.\nexport {\n\tTsPptxError,\n\tInvalidOptionError,\n\tUnsupportedFeatureError,\n\tPackageReadError,\n\tMediaError,\n\tInternalError,\n\ttype TsPptxErrorOptions,\n} from './errors.js'\nexport type {\n\tErrorCode,\n\tTsPptxCode,\n\tInvalidOptionErrorCode,\n\tUnsupportedFeatureErrorCode,\n\tPackageReadErrorCode,\n\tMediaErrorCode,\n\tInternalErrorCode,\n} from './codes.js'\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAkBA,SAAgB,uBAAuC;CACtD,OAAO;EACN,qBAAqB;EACrB;EACA;EACA;EACA;CACD;AACD;AAEA,eAAe,aAAa,QAAqC;CAChE,MAAM,WAAW,MAAM,MAAM,MAAM;CACnC,IAAI,CAAC,SAAS,IAAI,MAAM,IAAI,WAAW,qBAAqB,gCAAgC,QAAQ;CACpG,OAAO,IAAI,WAAW,MAAM,SAAS,YAAY,CAAC;AACnD;;;;;;;AAQA,eAAe,UAAU,KAAwD;CAChF,MAAM,WAAW,MAAM,MAAM,IAAI,IAAI;CACrC,IAAI,CAAC,SAAS,IAAI,MAAM,IAAI,WAAW,sBAAsB,iCAAiC,IAAI,MAAM;CACxG,OAAO,cAAc,IAAI,WAAW,MAAM,SAAS,YAAY,CAAC,CAAC;AAClE;;AAGA,eAAe,oBAAoB,KAAqC;CACvE,IAAI,OAAO;CACX,OAAO;AACR;AAEA,eAAe,UAAU,UAAmC;CAC3D,MAAM,IAAI,wBACT,mCACA,iBAAiB,SAAS,sNAG3B;AACD;;;;;;;;;;;;;;;AC5CA,IAAa,SAAb,cAA4B,iBAAiB;CAC5C,cAAc;EACb,MAAM,qBAAqB,CAAC;CAC7B;AACD"}
@@ -0,0 +1,173 @@
1
+ import { a as TsPptxError, d as InvalidOptionErrorCode, f as MediaErrorCode, h as UnsupportedFeatureErrorCode, i as PackageReadError, l as ErrorCode, m as TsPptxCode, n as InvalidOptionError, o as TsPptxErrorOptions, p as PackageReadErrorCode, r as MediaError, s as UnsupportedFeatureError, t as InternalError, u as InternalErrorCode } from "./errors-DRLpOpgQ.js";
2
+ import { n as OpcPackage } from "./package-CaOLXSNi.js";
3
+ //#region src/inspect.d.ts
4
+ /**
5
+ * Input to the inspect surface. A `string` is a **filesystem path** (Node) read
6
+ * from disk; pass `Uint8Array`/`ArrayBuffer`/`Blob`/`number[]` for an in-memory
7
+ * archive. (A string is a path, not JSZip's latin1 binary content — see
8
+ * {@link ZipInput}.)
9
+ */
10
+ type PptxInspectInputValue = string | number[] | Uint8Array | ArrayBuffer | Blob;
11
+ type PptxInspectInput = PptxInspectInputValue | Promise<PptxInspectInputValue>;
12
+ interface PptxSlideSize {
13
+ widthIn: number;
14
+ heightIn: number;
15
+ }
16
+ interface PptxBox {
17
+ x: number;
18
+ y: number;
19
+ w: number;
20
+ h: number;
21
+ }
22
+ interface PptxTextRun {
23
+ text: string;
24
+ fontSizePt: number | null;
25
+ color: string | null;
26
+ /** Run font face (`a:rPr > a:latin@typeface`), or null when it inherits from the theme/placeholder. */
27
+ fontFace: string | null;
28
+ /** Bold (`a:rPr@b`). */
29
+ bold: boolean;
30
+ /** Italic (`a:rPr@i`). */
31
+ italic: boolean;
32
+ /** Strikethrough token (`a:rPr@strike`: `noStrike`/`sngStrike`/`dblStrike`), or null when unset. */
33
+ strike: string | null;
34
+ /** Highlight colour hex (`a:rPr > a:highlight`), or null when unset. A theme token is resolved against the slide's theme. */
35
+ highlight: string | null;
36
+ /** Character spacing in points (`a:rPr@spc`, authored in hundredths of a point), or null when unset. */
37
+ charSpacingPt: number | null;
38
+ }
39
+ /**
40
+ * One paragraph (`a:p`): its runs in document order. Preserves the paragraph/line
41
+ * boundaries that the flat {@link PptxSlideElement.textRuns} list discards — needed
42
+ * to measure a `wrap="none"` frame line-by-line (each paragraph is one unwrapped line).
43
+ */
44
+ interface PptxParagraph {
45
+ runs: PptxTextRun[];
46
+ }
47
+ /**
48
+ * What an element is. `'group'` is a `p:grpSp` container: it has its own identity,
49
+ * box, and fill, but no text of its own — its content is the elements that name it
50
+ * in {@link PptxSlideElement.parentZIndex}.
51
+ */
52
+ type PptxSlideElementKind = 'text' | 'image' | 'shape' | 'group';
53
+ /**
54
+ * Vertical-autofit mode of a text frame, read from the `a:bodyPr` child element:
55
+ * - `'none'`: no autofit (`a:noAutofit`, or no autofit child at all). The box has a
56
+ * fixed height the text must fit inside — a genuine overflow candidate.
57
+ * - `'normAutofit'`: shrink text to fit (`a:normAutofit`, ts-pptx `fit: 'shrink'`).
58
+ * Text is downscaled rather than overflowing.
59
+ * - `'spAutoFit'`: resize shape to fit text (`a:spAutoFit`, ts-pptx `fit: 'resize'`).
60
+ * The authored height is an output, not a constraint, so the box cannot overflow.
61
+ */
62
+ type PptxAutofitMode = 'none' | 'normAutofit' | 'spAutoFit';
63
+ /**
64
+ * Text-frame body insets in inches (`a:bodyPr` `lIns`/`tIns`/`rIns`/`bIns`), with
65
+ * PowerPoint defaults applied when an attribute is absent (0.1in left/right,
66
+ * 0.05in top/bottom). Subtract these from {@link PptxBox} to get the inner text box.
67
+ */
68
+ interface PptxBodyInsets {
69
+ left: number;
70
+ top: number;
71
+ right: number;
72
+ bottom: number;
73
+ }
74
+ interface PptxSlideElement {
75
+ id: string | number;
76
+ name: string;
77
+ kind: PptxSlideElementKind;
78
+ /**
79
+ * Paint order on the slide, `0`-based: the element's position in a depth-first
80
+ * walk of `p:spTree` in document order. A group is immediately followed by its
81
+ * own children, which is also the order PowerPoint paints them, so a higher
82
+ * `zIndex` draws on top. Unique within a slide, which is what
83
+ * {@link parentZIndex} / {@link childZIndices} key on.
84
+ */
85
+ zIndex: number;
86
+ /**
87
+ * Position and size in **slide-absolute** inches, composing every enclosing
88
+ * group transform — directly comparable across elements whether or not they are
89
+ * grouped. For a rotated element this is the unrotated placement box (the box
90
+ * PowerPoint writes after Ungroup); see {@link rotation}.
91
+ */
92
+ box: PptxBox;
93
+ /**
94
+ * Effective clockwise rotation in degrees, normalised to `[0, 360)`, after
95
+ * composing the element's own `a:xfrm@rot` with every enclosing group rotation.
96
+ */
97
+ rotation: number;
98
+ /** Effective horizontal flip, XOR-composing the element's own `@flipH` with enclosing group flips. */
99
+ flipH: boolean;
100
+ /** Effective vertical flip, XOR-composing the element's own `@flipV` with enclosing group flips. */
101
+ flipV: boolean;
102
+ /** {@link zIndex} of the enclosing `'group'` element, or `null` when the element sits at slide level. */
103
+ parentZIndex: number | null;
104
+ /** {@link zIndex} of each direct child, in document order. Empty unless {@link kind} is `'group'`. */
105
+ childZIndices: number[];
106
+ text: string;
107
+ textWrap: string | null;
108
+ autofit: PptxAutofitMode | null;
109
+ /**
110
+ * Baked shrink scale from `<a:normAutofit@fontScale>` as a percent (62.5 = 62.5%),
111
+ * or null when the frame has no `normAutofit` or bakes no scale (a bare
112
+ * `<a:normAutofit/>`, which PowerPoint draws at 100% until edited).
113
+ */
114
+ autofitFontScale: number | null;
115
+ bodyInsets: PptxBodyInsets | null;
116
+ textRuns: PptxTextRun[];
117
+ /** Runs grouped by their source paragraph (`a:p`), in document order. */
118
+ paragraphs: PptxParagraph[];
119
+ fontSizes: number[];
120
+ colors: string[];
121
+ fill: string | null;
122
+ line: string | null;
123
+ shapeType: string | null;
124
+ }
125
+ interface PptxSlideInspection {
126
+ index: number;
127
+ name: string;
128
+ path: string;
129
+ size: PptxSlideSize;
130
+ elements: PptxSlideElement[];
131
+ text: string;
132
+ wordCount: number;
133
+ }
134
+ interface PptxInspection {
135
+ slideSize: PptxSlideSize;
136
+ slides: PptxSlideInspection[];
137
+ }
138
+ type PptxBoxAxis = 'x' | 'y';
139
+ type PptxBoxAnchor = 'left' | 'center' | 'right' | 'top' | 'middle' | 'bottom';
140
+ declare const DEFAULT_INSPECT_SLIDE_SIZE: PptxSlideSize;
141
+ /**
142
+ * Load a `.pptx` as an {@link OpcPackage} — the same package model `ts-pptx/read`
143
+ * uses, so a caller that starts here can hand the result straight to
144
+ * `Presentation.fromPackage()` without re-reading the bytes.
145
+ *
146
+ * The input must be a real OPC package: a zip that merely contains some slide XML
147
+ * but no `[Content_Types].xml` is rejected with a `PackageReadError`.
148
+ */
149
+ declare function loadPptxPackage(input: PptxInspectInput): Promise<OpcPackage>;
150
+ /** Every part in the package, as zip paths (`ppt/slides/slide1.xml`), sorted. */
151
+ declare function listPptxParts(pptxPackage: OpcPackage): string[];
152
+ /** Read a package part as UTF-8 text, or `null` when the part is absent. */
153
+ declare function readPptxTextPart(pptxPackage: OpcPackage, path: string): Promise<string | null>;
154
+ /**
155
+ * Read a package part as raw bytes — the binary sibling of {@link readPptxTextPart}
156
+ * for embedded media (SVG/PNG/EMF blobs, fonts, …) that must not be UTF-8 decoded.
157
+ * Returns `null` when the part is absent. The `Uint8Array` is browser-isomorphic;
158
+ * Node consumers can wrap it with `Buffer.from(...)` if they need Buffer methods.
159
+ */
160
+ declare function readPptxBinaryPart(pptxPackage: OpcPackage, path: string): Promise<Uint8Array | null>;
161
+ declare function inspectPptx(input: PptxInspectInput): Promise<PptxInspection>;
162
+ declare function readPresentationSize(pptxPackage: OpcPackage, fallback?: PptxSlideSize): Promise<PptxSlideSize>;
163
+ /**
164
+ * Every slide in the deck, in **presentation order** (`p:sldIdLst`) — the order
165
+ * PowerPoint shows them in, which is not the order their parts are named once a
166
+ * deck has been reordered.
167
+ */
168
+ declare function extractSlides(pptxPackage: OpcPackage, size?: PptxSlideSize): Promise<PptxSlideInspection[]>;
169
+ declare function overlapArea(a: PptxBox, b: PptxBox): number;
170
+ declare function boxAnchor(box: PptxBox, anchor: PptxBoxAnchor, axis: PptxBoxAxis): number;
171
+ //#endregion
172
+ export { DEFAULT_INSPECT_SLIDE_SIZE, type ErrorCode, InternalError, type InternalErrorCode, InvalidOptionError, type InvalidOptionErrorCode, MediaError, type MediaErrorCode, PackageReadError, type PackageReadErrorCode, PptxAutofitMode, PptxBodyInsets, PptxBox, PptxBoxAnchor, PptxBoxAxis, PptxInspectInput, PptxInspection, PptxParagraph, PptxSlideElement, PptxSlideElementKind, PptxSlideInspection, PptxSlideSize, PptxTextRun, type TsPptxCode, TsPptxError, type TsPptxErrorOptions, UnsupportedFeatureError, type UnsupportedFeatureErrorCode, boxAnchor, extractSlides, inspectPptx, listPptxParts, loadPptxPackage, overlapArea, readPptxBinaryPart, readPptxTextPart, readPresentationSize };
173
+ //# sourceMappingURL=inspect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect.d.ts","names":[],"sources":["../src/inspect.ts"],"mappings":";;;;;;;;;KAqCK,4CAA4C,aAAa,cAAc;KAEhE,mBAAmB,wBAAwB,QAAQ;UAE9C;EAChB;EACA;;UAGgB;EAChB;EACA;EACA;EACA;;UAGgB;EAChB;EACA;EACA;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;;UAQgB;EAChB,MAAM;;;;;;;KAQK;;;;;;;;;;KAWA;;;;;;UAOK;EAChB;EACA;EACA;EACA;;UAGgB;EAChB;EACA;EACA,MAAM;;;;;;;;EAQN;;;;;;;EAOA,KAAK;;;;;EAKL;;EAEA;;EAEA;;EAEA;;EAEA;EACA;EACA;EACA,SAAS;;;;;;EAMT;EACA,YAAY;EACZ,UAAU;;EAEV,YAAY;EACZ;EACA;EACA;EACA;EACA;;UAGgB;EAChB;EACA;EACA;EACA,MAAM;EACN,UAAU;EACV;EACA;;UAGgB;EAChB,WAAW;EACX,QAAQ;;KAGG;KACA;cAEC,4BAA4B;;;;;;;;;iBAsBnB,gBAAgB,OAAO,mBAAmB,QAAQ;;iBAKxD,cAAc,aAAa;;iBAKrB,iBAAiB,aAAa,YAAY,eAAe;;;;;;;iBAWzD,mBAAmB,aAAa,YAAY,eAAe,QAAQ;iBAmBnE,YAAY,OAAO,mBAAmB,QAAQ;iBAO9C,qBACrB,aAAa,YACb,WAAU,gBACR,QAAQ;;;;;;iBAWW,cAAc,aAAa,YAAY,OAAO,gBAAgB,QAAQ;iBA2C5E,YAAY,GAAG,SAAS,GAAG;iBAM3B,UAAU,KAAK,SAAS,QAAQ,eAAe,MAAM"}
@@ -0,0 +1,285 @@
1
+ import { n as warn } from "./diagnostics-DYQC7xLV.js";
2
+ import { a as TsPptxError, i as PackageReadError, n as InvalidOptionError, o as UnsupportedFeatureError, r as MediaError, t as InternalError } from "./errors-DGE9zh3U.js";
3
+ import { d as emuToInches, l as STANDARD_LAYOUTS } from "./units-B-JUKwCS.js";
4
+ import { J as OOXML_NS, Y as attr, at as intValue, et as firstChild } from "./shapes-BZU8UTW2.js";
5
+ import { f as OpcPackage, t as Presentation } from "./presentation-B0JWdTN1.js";
6
+ //#region src/inspect.ts
7
+ /**
8
+ * A cheap, flat snapshot of what a `.pptx` contains: every element on every
9
+ * slide, with its slide-absolute box and the handful of text/fill properties a
10
+ * layout audit asks about.
11
+ *
12
+ * It is a **projection over `ts-pptx/read`**, not a second reader. `read` gives a
13
+ * navigable, mutable model of a package and answers questions in the shape of the
14
+ * OOXML tree; this answers one flat question — "what is on the slides, and where"
15
+ * — in the shape a linter, an overlap check, or a diffing tool wants. The two used
16
+ * to be independent implementations over two different XML parsers, which meant
17
+ * every read-side fix had to be made twice and a divergence between them was
18
+ * invisible to every test. Now the model below is the only reader, and this file
19
+ * is the flattening.
20
+ *
21
+ * What it deliberately does NOT do, and why the projection is not just
22
+ * `Presentation` re-exported:
23
+ * - **Only geometry a shape carries itself.** A placeholder that inherits its box
24
+ * from the layout is omitted rather than resolved (`absoluteFrame`, not
25
+ * `resolvedFrame`) — the snapshot reports what the slide states.
26
+ * - **No `p:graphicFrame`.** Tables, charts, and SmartArt are structures, not
27
+ * boxes with text, and flattening them here would report a shape whose content
28
+ * this surface cannot describe.
29
+ */
30
+ const DEFAULT_INSPECT_SLIDE_SIZE = Object.freeze({
31
+ widthIn: round(STANDARD_LAYOUTS.LAYOUT_WIDE.widthIn, 3),
32
+ heightIn: STANDARD_LAYOUTS.LAYOUT_WIDE.heightIn
33
+ });
34
+ /**
35
+ * Load a `.pptx` as an {@link OpcPackage} — the same package model `ts-pptx/read`
36
+ * uses, so a caller that starts here can hand the result straight to
37
+ * `Presentation.fromPackage()` without re-reading the bytes.
38
+ *
39
+ * The input must be a real OPC package: a zip that merely contains some slide XML
40
+ * but no `[Content_Types].xml` is rejected with a `PackageReadError`.
41
+ */
42
+ async function loadPptxPackage(input) {
43
+ return OpcPackage.load(await input);
44
+ }
45
+ /** Every part in the package, as zip paths (`ppt/slides/slide1.xml`), sorted. */
46
+ function listPptxParts(pptxPackage) {
47
+ return [...pptxPackage.parts.keys()].map(zipPathOf).sort();
48
+ }
49
+ /** Read a package part as UTF-8 text, or `null` when the part is absent. */
50
+ async function readPptxTextPart(pptxPackage, path) {
51
+ const bytes = await readPptxBinaryPart(pptxPackage, path);
52
+ return bytes ? textDecoder.decode(bytes) : null;
53
+ }
54
+ /**
55
+ * Read a package part as raw bytes — the binary sibling of {@link readPptxTextPart}
56
+ * for embedded media (SVG/PNG/EMF blobs, fonts, …) that must not be UTF-8 decoded.
57
+ * Returns `null` when the part is absent. The `Uint8Array` is browser-isomorphic;
58
+ * Node consumers can wrap it with `Buffer.from(...)` if they need Buffer methods.
59
+ */
60
+ async function readPptxBinaryPart(pptxPackage, path) {
61
+ return pptxPackage.part(partNameOf(path))?.bytes ?? null;
62
+ }
63
+ const textDecoder = new TextDecoder("utf-8");
64
+ /** OPC partnames are absolute (`/ppt/…`); this surface speaks zip paths (`ppt/…`). */
65
+ function zipPathOf(partName) {
66
+ return partName.startsWith("/") ? partName.slice(1) : partName;
67
+ }
68
+ function partNameOf(zipPath) {
69
+ return zipPath.startsWith("/") ? zipPath : `/${zipPath}`;
70
+ }
71
+ async function inspectPptx(input) {
72
+ const pptxPackage = await loadPptxPackage(input);
73
+ const slideSize = await readPresentationSize(pptxPackage);
74
+ return {
75
+ slideSize,
76
+ slides: await extractSlides(pptxPackage, slideSize)
77
+ };
78
+ }
79
+ async function readPresentationSize(pptxPackage, fallback = DEFAULT_INSPECT_SLIDE_SIZE) {
80
+ const size = presentationOf(pptxPackage)?.slideSize;
81
+ if (!size) return fallback;
82
+ return {
83
+ widthIn: round(size.widthIn, 3),
84
+ heightIn: round(size.heightIn, 3)
85
+ };
86
+ }
87
+ /**
88
+ * Every slide in the deck, in **presentation order** (`p:sldIdLst`) — the order
89
+ * PowerPoint shows them in, which is not the order their parts are named once a
90
+ * deck has been reordered.
91
+ */
92
+ async function extractSlides(pptxPackage, size) {
93
+ const slideSize = size || await readPresentationSize(pptxPackage);
94
+ const presentation = presentationOf(pptxPackage);
95
+ if (!presentation) return [];
96
+ return presentation.slides.map((slide, index) => {
97
+ const path = zipPathOf(slide.partName);
98
+ const harvested = [];
99
+ harvest(slide.shapes, null, harvested);
100
+ const elements = flatten(harvested, path);
101
+ const text = elements.map((el) => el.text).filter(Boolean).join(" ");
102
+ return {
103
+ index,
104
+ name: slide.name || `Slide ${index + 1}`,
105
+ path,
106
+ size: slideSize,
107
+ elements,
108
+ text,
109
+ wordCount: countWords(text)
110
+ };
111
+ });
112
+ }
113
+ /**
114
+ * The deck's `Presentation`, or `null` when the package holds no readable
115
+ * `presentation.xml`. Callers here are auditing files they did not author, so a
116
+ * package that is a valid OPC container but not a presentation reports an empty
117
+ * deck rather than throwing. `presentationPart` is the throw site: it rejects a
118
+ * package with no — or more than one — office-document relationship.
119
+ */
120
+ function presentationOf(pptxPackage) {
121
+ const presentation = Presentation.fromPackage(pptxPackage);
122
+ try {
123
+ return presentation.presentationPart.isXmlPart ? presentation : null;
124
+ } catch {
125
+ return null;
126
+ }
127
+ }
128
+ function overlapArea(a, b) {
129
+ return Math.max(0, Math.min(a.x + a.w, b.x + b.w) - Math.max(a.x, b.x)) * Math.max(0, Math.min(a.y + a.h, b.y + b.h) - Math.max(a.y, b.y));
130
+ }
131
+ function boxAnchor(box, anchor, axis) {
132
+ if (axis === "x") {
133
+ if (anchor === "left") return box.x;
134
+ if (anchor === "right") return box.x + box.w;
135
+ return box.x + box.w / 2;
136
+ }
137
+ if (anchor === "top") return box.y;
138
+ if (anchor === "bottom") return box.y + box.h;
139
+ return box.y + box.h / 2;
140
+ }
141
+ /**
142
+ * Flatten a shape list depth-first in document order: each shape is followed by
143
+ * its descendants, which is both paint order and the order the
144
+ * {@link PptxSlideElement.zIndex} contract promises. Every entry's index in `out`
145
+ * is its zIndex. Returns the zIndices assigned at this level, which is what the
146
+ * enclosing group records as its {@link PptxSlideElement.childZIndices}.
147
+ */
148
+ function harvest(shapes, parentZIndex, out) {
149
+ const zIndices = [];
150
+ for (const shape of shapes) {
151
+ if (shape.shapeType === "graphicFrame") continue;
152
+ const entry = {
153
+ shape,
154
+ parentZIndex,
155
+ childZIndices: []
156
+ };
157
+ const zIndex = out.push(entry) - 1;
158
+ zIndices.push(zIndex);
159
+ if (shape.shapeType === "group") entry.childZIndices = harvest(shape.shapes, zIndex, out);
160
+ }
161
+ return zIndices;
162
+ }
163
+ /**
164
+ * Turn harvested shapes into elements, dropping the ones with no resolvable slide
165
+ * position. A dropped shape keeps its zIndex — the numbers are positions in the
166
+ * shape tree, and renumbering them would silently repoint every `parentZIndex`.
167
+ */
168
+ function flatten(harvested, slidePath) {
169
+ return harvested.map((entry, zIndex) => toElement(entry, zIndex, slidePath)).filter((element) => Boolean(element));
170
+ }
171
+ function toElement(entry, zIndex, slidePath) {
172
+ const { shape } = entry;
173
+ const frame = shape.absoluteFrame;
174
+ if (!frame) {
175
+ reportUnresolvable(shape, zIndex, slidePath);
176
+ return null;
177
+ }
178
+ const textFrame = shape.textFrame;
179
+ const paragraphs = textFrame ? textFrame.paragraphs.map((p) => ({ runs: p.runs.map(toRun) })) : [];
180
+ const textRuns = paragraphs.flatMap((paragraph) => paragraph.runs);
181
+ const text = textRuns.map((run) => run.text).join("").replace(/\s+/g, " ").trim();
182
+ const kind = shape.shapeType === "group" ? "group" : text ? "text" : shape.shapeType === "picture" ? "image" : "shape";
183
+ return {
184
+ id: shape.id ?? zIndex + 1,
185
+ name: shape.name || `${kind} ${zIndex + 1}`,
186
+ kind,
187
+ zIndex,
188
+ box: {
189
+ x: emuToInches(frame.left),
190
+ y: emuToInches(frame.top),
191
+ w: emuToInches(frame.width),
192
+ h: emuToInches(frame.height)
193
+ },
194
+ rotation: frame.rotation,
195
+ flipH: frame.flipH,
196
+ flipV: frame.flipV,
197
+ parentZIndex: entry.parentZIndex,
198
+ childZIndices: entry.childZIndices,
199
+ text,
200
+ textWrap: textFrame?.bodyProperties?.wrap ?? null,
201
+ autofit: textFrame?.autofit ?? null,
202
+ autofitFontScale: textFrame?.autofitFontScale ?? null,
203
+ bodyInsets: readBodyInsets(textFrame),
204
+ textRuns,
205
+ paragraphs,
206
+ fontSizes: [...new Set(textRuns.map((run) => run.fontSizePt).filter((size) => size !== null))],
207
+ colors: [...new Set(textRuns.map((run) => run.color).filter((color) => Boolean(color)))],
208
+ fill: shape.fillColor,
209
+ line: shape.lineColor,
210
+ shapeType: shape.presetGeometry
211
+ };
212
+ }
213
+ /** Project one read-model {@link Run} onto the flat run shape. */
214
+ function toRun(run) {
215
+ return {
216
+ text: run.text,
217
+ fontSizePt: run.fontSizePt,
218
+ color: run.color,
219
+ fontFace: run.fontName,
220
+ bold: run.bold ?? false,
221
+ italic: run.italic ?? false,
222
+ strike: run.strike,
223
+ highlight: run.highlight?.hex ?? null,
224
+ charSpacingPt: run.charSpacingPt
225
+ };
226
+ }
227
+ const DEFAULT_INSET_LR_IN = .1;
228
+ const DEFAULT_INSET_TB_IN = .05;
229
+ const POINTS_PER_INCH = 72;
230
+ function readBodyInsets(textFrame) {
231
+ const insets = textFrame?.bodyProperties?.insetsPt;
232
+ if (!insets) return null;
233
+ const inches = (pt, fallback) => pt === void 0 ? fallback : pt / POINTS_PER_INCH;
234
+ return {
235
+ left: inches(insets.left, DEFAULT_INSET_LR_IN),
236
+ top: inches(insets.top, DEFAULT_INSET_TB_IN),
237
+ right: inches(insets.right, DEFAULT_INSET_LR_IN),
238
+ bottom: inches(insets.bottom, DEFAULT_INSET_TB_IN)
239
+ };
240
+ }
241
+ /** Warn about a shape whose slide position cannot be resolved, unless it never claimed one. */
242
+ function reportUnresolvable(shape, zIndex, slidePath) {
243
+ const element = shape.element_;
244
+ if (!hasBox(ownTransform(element), "a:off", "a:ext")) return;
245
+ const who = shape.name ? `"${shape.name}"` : `the element at zIndex ${zIndex}`;
246
+ if (enclosingGroupLacksTransform(element)) {
247
+ warn("inspect/group-transform-missing", `inspect: skipped ${who} on ${slidePath} — an enclosing group has no usable a:xfrm, so its slide position cannot be resolved.`);
248
+ return;
249
+ }
250
+ warn("inspect/group-transform-degenerate", `inspect: skipped ${who} on ${slidePath} — an enclosing group has a degenerate transform (zero a:chExt), so its slide position cannot be resolved.`);
251
+ }
252
+ /** The element's own `a:xfrm` — on `p:grpSpPr` for a group, `p:spPr` for every other kind. */
253
+ function ownTransform(element) {
254
+ const props = firstChild(element, element.localName === "grpSp" ? "p:grpSpPr" : "p:spPr");
255
+ return props && firstChild(props, "a:xfrm");
256
+ }
257
+ /** Whether any enclosing `p:grpSp` fails to state a complete child-space mapping. */
258
+ function enclosingGroupLacksTransform(element) {
259
+ for (let node = element.parentNode; node && node.nodeType === 1; node = node.parentNode) {
260
+ const parent = node;
261
+ if (parent.namespaceURI !== OOXML_NS.p || parent.localName !== "grpSp") return false;
262
+ const xfrm = ownTransform(parent);
263
+ if (!hasBox(xfrm, "a:off", "a:ext") || !hasBox(xfrm, "a:chOff", "a:chExt")) return true;
264
+ }
265
+ return false;
266
+ }
267
+ /** Whether a transform states a complete position + extent pair. */
268
+ function hasBox(xfrm, offName, extName) {
269
+ if (!xfrm) return false;
270
+ const off = firstChild(xfrm, offName);
271
+ const ext = firstChild(xfrm, extName);
272
+ if (!off || !ext) return false;
273
+ return intValue(attr(off, "x")) !== null && intValue(attr(off, "y")) !== null && intValue(attr(ext, "cx")) !== null && intValue(attr(ext, "cy")) !== null;
274
+ }
275
+ function countWords(text) {
276
+ return text.split(/\s+/).filter(Boolean).length;
277
+ }
278
+ function round(value, digits) {
279
+ const factor = 10 ** digits;
280
+ return Math.round(value * factor) / factor;
281
+ }
282
+ //#endregion
283
+ export { DEFAULT_INSPECT_SLIDE_SIZE, InternalError, InvalidOptionError, MediaError, PackageReadError, TsPptxError, UnsupportedFeatureError, boxAnchor, extractSlides, inspectPptx, listPptxParts, loadPptxPackage, overlapArea, readPptxBinaryPart, readPptxTextPart, readPresentationSize };
284
+
285
+ //# sourceMappingURL=inspect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect.js","names":[],"sources":["../src/inspect.ts"],"sourcesContent":["/**\n * A cheap, flat snapshot of what a `.pptx` contains: every element on every\n * slide, with its slide-absolute box and the handful of text/fill properties a\n * layout audit asks about.\n *\n * It is a **projection over `ts-pptx/read`**, not a second reader. `read` gives a\n * navigable, mutable model of a package and answers questions in the shape of the\n * OOXML tree; this answers one flat question — \"what is on the slides, and where\"\n * — in the shape a linter, an overlap check, or a diffing tool wants. The two used\n * to be independent implementations over two different XML parsers, which meant\n * every read-side fix had to be made twice and a divergence between them was\n * invisible to every test. Now the model below is the only reader, and this file\n * is the flattening.\n *\n * What it deliberately does NOT do, and why the projection is not just\n * `Presentation` re-exported:\n * - **Only geometry a shape carries itself.** A placeholder that inherits its box\n * from the layout is omitted rather than resolved (`absoluteFrame`, not\n * `resolvedFrame`) — the snapshot reports what the slide states.\n * - **No `p:graphicFrame`.** Tables, charts, and SmartArt are structures, not\n * boxes with text, and flattening them here would report a shape whose content\n * this surface cannot describe.\n */\nimport { warn } from './diagnostics.js'\nimport { OpcPackage } from './read/opc/package.js'\nimport { Presentation } from './read/api/presentation.js'\nimport type { AnyShape } from './read/api/shapes.js'\nimport type { Run, TextFrame } from './read/api/text.js'\nimport { ELEMENT_NODE, OOXML_NS, attr, firstChild, intValue, type Element } from './read/oxml/dom.js'\nimport { STANDARD_LAYOUTS, emuToInches } from './units.js'\n\n/**\n * Input to the inspect surface. A `string` is a **filesystem path** (Node) read\n * from disk; pass `Uint8Array`/`ArrayBuffer`/`Blob`/`number[]` for an in-memory\n * archive. (A string is a path, not JSZip's latin1 binary content — see\n * {@link ZipInput}.)\n */\ntype PptxInspectInputValue = string | number[] | Uint8Array | ArrayBuffer | Blob\n\nexport type PptxInspectInput = PptxInspectInputValue | Promise<PptxInspectInputValue>\n\nexport interface PptxSlideSize {\n\twidthIn: number\n\theightIn: number\n}\n\nexport interface PptxBox {\n\tx: number\n\ty: number\n\tw: number\n\th: number\n}\n\nexport interface PptxTextRun {\n\ttext: string\n\tfontSizePt: number | null\n\tcolor: string | null\n\t/** Run font face (`a:rPr > a:latin@typeface`), or null when it inherits from the theme/placeholder. */\n\tfontFace: string | null\n\t/** Bold (`a:rPr@b`). */\n\tbold: boolean\n\t/** Italic (`a:rPr@i`). */\n\titalic: boolean\n\t/** Strikethrough token (`a:rPr@strike`: `noStrike`/`sngStrike`/`dblStrike`), or null when unset. */\n\tstrike: string | null\n\t/** Highlight colour hex (`a:rPr > a:highlight`), or null when unset. A theme token is resolved against the slide's theme. */\n\thighlight: string | null\n\t/** Character spacing in points (`a:rPr@spc`, authored in hundredths of a point), or null when unset. */\n\tcharSpacingPt: number | null\n}\n\n/**\n * One paragraph (`a:p`): its runs in document order. Preserves the paragraph/line\n * boundaries that the flat {@link PptxSlideElement.textRuns} list discards — needed\n * to measure a `wrap=\"none\"` frame line-by-line (each paragraph is one unwrapped line).\n */\nexport interface PptxParagraph {\n\truns: PptxTextRun[]\n}\n\n/**\n * What an element is. `'group'` is a `p:grpSp` container: it has its own identity,\n * box, and fill, but no text of its own — its content is the elements that name it\n * in {@link PptxSlideElement.parentZIndex}.\n */\nexport type PptxSlideElementKind = 'text' | 'image' | 'shape' | 'group'\n\n/**\n * Vertical-autofit mode of a text frame, read from the `a:bodyPr` child element:\n * - `'none'`: no autofit (`a:noAutofit`, or no autofit child at all). The box has a\n * fixed height the text must fit inside — a genuine overflow candidate.\n * - `'normAutofit'`: shrink text to fit (`a:normAutofit`, ts-pptx `fit: 'shrink'`).\n * Text is downscaled rather than overflowing.\n * - `'spAutoFit'`: resize shape to fit text (`a:spAutoFit`, ts-pptx `fit: 'resize'`).\n * The authored height is an output, not a constraint, so the box cannot overflow.\n */\nexport type PptxAutofitMode = 'none' | 'normAutofit' | 'spAutoFit'\n\n/**\n * Text-frame body insets in inches (`a:bodyPr` `lIns`/`tIns`/`rIns`/`bIns`), with\n * PowerPoint defaults applied when an attribute is absent (0.1in left/right,\n * 0.05in top/bottom). Subtract these from {@link PptxBox} to get the inner text box.\n */\nexport interface PptxBodyInsets {\n\tleft: number\n\ttop: number\n\tright: number\n\tbottom: number\n}\n\nexport interface PptxSlideElement {\n\tid: string | number\n\tname: string\n\tkind: PptxSlideElementKind\n\t/**\n\t * Paint order on the slide, `0`-based: the element's position in a depth-first\n\t * walk of `p:spTree` in document order. A group is immediately followed by its\n\t * own children, which is also the order PowerPoint paints them, so a higher\n\t * `zIndex` draws on top. Unique within a slide, which is what\n\t * {@link parentZIndex} / {@link childZIndices} key on.\n\t */\n\tzIndex: number\n\t/**\n\t * Position and size in **slide-absolute** inches, composing every enclosing\n\t * group transform — directly comparable across elements whether or not they are\n\t * grouped. For a rotated element this is the unrotated placement box (the box\n\t * PowerPoint writes after Ungroup); see {@link rotation}.\n\t */\n\tbox: PptxBox\n\t/**\n\t * Effective clockwise rotation in degrees, normalised to `[0, 360)`, after\n\t * composing the element's own `a:xfrm@rot` with every enclosing group rotation.\n\t */\n\trotation: number\n\t/** Effective horizontal flip, XOR-composing the element's own `@flipH` with enclosing group flips. */\n\tflipH: boolean\n\t/** Effective vertical flip, XOR-composing the element's own `@flipV` with enclosing group flips. */\n\tflipV: boolean\n\t/** {@link zIndex} of the enclosing `'group'` element, or `null` when the element sits at slide level. */\n\tparentZIndex: number | null\n\t/** {@link zIndex} of each direct child, in document order. Empty unless {@link kind} is `'group'`. */\n\tchildZIndices: number[]\n\ttext: string\n\ttextWrap: string | null\n\tautofit: PptxAutofitMode | null\n\t/**\n\t * Baked shrink scale from `<a:normAutofit@fontScale>` as a percent (62.5 = 62.5%),\n\t * or null when the frame has no `normAutofit` or bakes no scale (a bare\n\t * `<a:normAutofit/>`, which PowerPoint draws at 100% until edited).\n\t */\n\tautofitFontScale: number | null\n\tbodyInsets: PptxBodyInsets | null\n\ttextRuns: PptxTextRun[]\n\t/** Runs grouped by their source paragraph (`a:p`), in document order. */\n\tparagraphs: PptxParagraph[]\n\tfontSizes: number[]\n\tcolors: string[]\n\tfill: string | null\n\tline: string | null\n\tshapeType: string | null\n}\n\nexport interface PptxSlideInspection {\n\tindex: number\n\tname: string\n\tpath: string\n\tsize: PptxSlideSize\n\telements: PptxSlideElement[]\n\ttext: string\n\twordCount: number\n}\n\nexport interface PptxInspection {\n\tslideSize: PptxSlideSize\n\tslides: PptxSlideInspection[]\n}\n\nexport type PptxBoxAxis = 'x' | 'y'\nexport type PptxBoxAnchor = 'left' | 'center' | 'right' | 'top' | 'middle' | 'bottom'\n\nexport const DEFAULT_INSPECT_SLIDE_SIZE: PptxSlideSize = Object.freeze({\n\twidthIn: round(STANDARD_LAYOUTS.LAYOUT_WIDE.widthIn, 3),\n\theightIn: STANDARD_LAYOUTS.LAYOUT_WIDE.heightIn,\n})\n\n/* ────────────────────────────────────────────────────────────────────────────\n * Package layer\n *\n * Thin conveniences over `OpcPackage`, kept because this surface speaks zip\n * paths (`ppt/slides/slide1.xml`) while OPC speaks partnames (`/ppt/...`), and\n * because reaching a part's bytes is the one thing a caller of a *flat* surface\n * still routinely needs.\n * ──────────────────────────────────────────────────────────────────────────── */\n\n/**\n * Load a `.pptx` as an {@link OpcPackage} — the same package model `ts-pptx/read`\n * uses, so a caller that starts here can hand the result straight to\n * `Presentation.fromPackage()` without re-reading the bytes.\n *\n * The input must be a real OPC package: a zip that merely contains some slide XML\n * but no `[Content_Types].xml` is rejected with a `PackageReadError`.\n */\nexport async function loadPptxPackage(input: PptxInspectInput): Promise<OpcPackage> {\n\treturn OpcPackage.load(await input)\n}\n\n/** Every part in the package, as zip paths (`ppt/slides/slide1.xml`), sorted. */\nexport function listPptxParts(pptxPackage: OpcPackage): string[] {\n\treturn [...pptxPackage.parts.keys()].map(zipPathOf).sort()\n}\n\n/** Read a package part as UTF-8 text, or `null` when the part is absent. */\nexport async function readPptxTextPart(pptxPackage: OpcPackage, path: string): Promise<string | null> {\n\tconst bytes = await readPptxBinaryPart(pptxPackage, path)\n\treturn bytes ? textDecoder.decode(bytes) : null\n}\n\n/**\n * Read a package part as raw bytes — the binary sibling of {@link readPptxTextPart}\n * for embedded media (SVG/PNG/EMF blobs, fonts, …) that must not be UTF-8 decoded.\n * Returns `null` when the part is absent. The `Uint8Array` is browser-isomorphic;\n * Node consumers can wrap it with `Buffer.from(...)` if they need Buffer methods.\n */\nexport async function readPptxBinaryPart(pptxPackage: OpcPackage, path: string): Promise<Uint8Array | null> {\n\treturn pptxPackage.part(partNameOf(path))?.bytes ?? null\n}\n\nconst textDecoder = new TextDecoder('utf-8')\n\n/** OPC partnames are absolute (`/ppt/…`); this surface speaks zip paths (`ppt/…`). */\nfunction zipPathOf(partName: string): string {\n\treturn partName.startsWith('/') ? partName.slice(1) : partName\n}\n\nfunction partNameOf(zipPath: string): string {\n\treturn zipPath.startsWith('/') ? zipPath : `/${zipPath}`\n}\n\n/* ────────────────────────────────────────────────────────────────────────────\n * The surface\n * ──────────────────────────────────────────────────────────────────────────── */\n\nexport async function inspectPptx(input: PptxInspectInput): Promise<PptxInspection> {\n\tconst pptxPackage = await loadPptxPackage(input)\n\tconst slideSize = await readPresentationSize(pptxPackage)\n\tconst slides = await extractSlides(pptxPackage, slideSize)\n\treturn { slideSize, slides }\n}\n\nexport async function readPresentationSize(\n\tpptxPackage: OpcPackage,\n\tfallback: PptxSlideSize = DEFAULT_INSPECT_SLIDE_SIZE\n): Promise<PptxSlideSize> {\n\tconst size = presentationOf(pptxPackage)?.slideSize\n\tif (!size) return fallback\n\treturn { widthIn: round(size.widthIn, 3), heightIn: round(size.heightIn, 3) }\n}\n\n/**\n * Every slide in the deck, in **presentation order** (`p:sldIdLst`) — the order\n * PowerPoint shows them in, which is not the order their parts are named once a\n * deck has been reordered.\n */\nexport async function extractSlides(pptxPackage: OpcPackage, size?: PptxSlideSize): Promise<PptxSlideInspection[]> {\n\tconst slideSize = size || (await readPresentationSize(pptxPackage))\n\tconst presentation = presentationOf(pptxPackage)\n\tif (!presentation) return []\n\n\treturn presentation.slides.map((slide, index) => {\n\t\tconst path = zipPathOf(slide.partName)\n\t\tconst harvested: HarvestedShape[] = []\n\t\tharvest(slide.shapes, null, harvested) // slide level: no enclosing group\n\t\tconst elements = flatten(harvested, path)\n\t\tconst text = elements\n\t\t\t.map((el) => el.text)\n\t\t\t.filter(Boolean)\n\t\t\t.join(' ')\n\n\t\treturn {\n\t\t\tindex,\n\t\t\tname: slide.name || `Slide ${index + 1}`,\n\t\t\tpath,\n\t\t\tsize: slideSize,\n\t\t\telements,\n\t\t\ttext,\n\t\t\twordCount: countWords(text),\n\t\t}\n\t})\n}\n\n/**\n * The deck's `Presentation`, or `null` when the package holds no readable\n * `presentation.xml`. Callers here are auditing files they did not author, so a\n * package that is a valid OPC container but not a presentation reports an empty\n * deck rather than throwing. `presentationPart` is the throw site: it rejects a\n * package with no — or more than one — office-document relationship.\n */\nfunction presentationOf(pptxPackage: OpcPackage): Presentation | null {\n\tconst presentation = Presentation.fromPackage(pptxPackage)\n\ttry {\n\t\treturn presentation.presentationPart.isXmlPart ? presentation : null\n\t} catch {\n\t\treturn null\n\t}\n}\n\nexport function overlapArea(a: PptxBox, b: PptxBox): number {\n\tconst x = Math.max(0, Math.min(a.x + a.w, b.x + b.w) - Math.max(a.x, b.x))\n\tconst y = Math.max(0, Math.min(a.y + a.h, b.y + b.h) - Math.max(a.y, b.y))\n\treturn x * y\n}\n\nexport function boxAnchor(box: PptxBox, anchor: PptxBoxAnchor, axis: PptxBoxAxis): number {\n\tif (axis === 'x') {\n\t\tif (anchor === 'left') return box.x\n\t\tif (anchor === 'right') return box.x + box.w\n\t\treturn box.x + box.w / 2\n\t}\n\tif (anchor === 'top') return box.y\n\tif (anchor === 'bottom') return box.y + box.h\n\treturn box.y + box.h / 2\n}\n\n/* ────────────────────────────────────────────────────────────────────────────\n * Shape-tree harvest\n * ──────────────────────────────────────────────────────────────────────────── */\n\n/** One harvested shape, before it is flattened into a {@link PptxSlideElement}. */\ninterface HarvestedShape {\n\tshape: AnyShape\n\tparentZIndex: number | null\n\tchildZIndices: number[]\n}\n\n/**\n * Flatten a shape list depth-first in document order: each shape is followed by\n * its descendants, which is both paint order and the order the\n * {@link PptxSlideElement.zIndex} contract promises. Every entry's index in `out`\n * is its zIndex. Returns the zIndices assigned at this level, which is what the\n * enclosing group records as its {@link PptxSlideElement.childZIndices}.\n */\nfunction harvest(shapes: AnyShape[], parentZIndex: number | null, out: HarvestedShape[]): number[] {\n\tconst zIndices: number[] = []\n\tfor (const shape of shapes) {\n\t\t// A `p:graphicFrame` hosts a table, chart, or SmartArt — a structure, not a box\n\t\t// with text. It is outside this surface entirely, so it does not consume a zIndex\n\t\t// either; use `ts-pptx/read` for what is inside one.\n\t\tif (shape.shapeType === 'graphicFrame') continue\n\t\tconst entry: HarvestedShape = { shape, parentZIndex, childZIndices: [] }\n\t\tconst zIndex = out.push(entry) - 1\n\t\tzIndices.push(zIndex)\n\t\tif (shape.shapeType === 'group') entry.childZIndices = harvest(shape.shapes, zIndex, out)\n\t}\n\treturn zIndices\n}\n\n/**\n * Turn harvested shapes into elements, dropping the ones with no resolvable slide\n * position. A dropped shape keeps its zIndex — the numbers are positions in the\n * shape tree, and renumbering them would silently repoint every `parentZIndex`.\n */\nfunction flatten(harvested: HarvestedShape[], slidePath: string): PptxSlideElement[] {\n\treturn harvested\n\t\t.map((entry, zIndex) => toElement(entry, zIndex, slidePath))\n\t\t.filter((element): element is PptxSlideElement => Boolean(element))\n}\n\nfunction toElement(entry: HarvestedShape, zIndex: number, slidePath: string): PptxSlideElement | null {\n\tconst { shape } = entry\n\tconst frame = shape.absoluteFrame\n\tif (!frame) {\n\t\treportUnresolvable(shape, zIndex, slidePath)\n\t\treturn null\n\t}\n\n\t// Only `p:sp` holds a text body, so every other kind projects as an empty frame.\n\tconst textFrame = shape.textFrame\n\tconst paragraphs = textFrame ? textFrame.paragraphs.map((p) => ({ runs: p.runs.map(toRun) })) : []\n\tconst textRuns = paragraphs.flatMap((paragraph) => paragraph.runs)\n\t// Deliberately not `TextFrame.text`: this is one whitespace-collapsed line for\n\t// matching and word-counting, not the frame's text with its line structure.\n\tconst text = textRuns\n\t\t.map((run) => run.text)\n\t\t.join('')\n\t\t.replace(/\\s+/g, ' ')\n\t\t.trim()\n\tconst kind: PptxSlideElementKind =\n\t\tshape.shapeType === 'group' ? 'group' : text ? 'text' : shape.shapeType === 'picture' ? 'image' : 'shape'\n\n\treturn {\n\t\tid: shape.id ?? zIndex + 1,\n\t\tname: shape.name || `${kind} ${zIndex + 1}`,\n\t\tkind,\n\t\tzIndex,\n\t\tbox: {\n\t\t\tx: emuToInches(frame.left),\n\t\t\ty: emuToInches(frame.top),\n\t\t\tw: emuToInches(frame.width),\n\t\t\th: emuToInches(frame.height),\n\t\t},\n\t\trotation: frame.rotation,\n\t\tflipH: frame.flipH,\n\t\tflipV: frame.flipV,\n\t\tparentZIndex: entry.parentZIndex,\n\t\tchildZIndices: entry.childZIndices,\n\t\ttext,\n\t\ttextWrap: textFrame?.bodyProperties?.wrap ?? null,\n\t\tautofit: textFrame?.autofit ?? null,\n\t\tautofitFontScale: textFrame?.autofitFontScale ?? null,\n\t\tbodyInsets: readBodyInsets(textFrame),\n\t\ttextRuns,\n\t\tparagraphs,\n\t\tfontSizes: [...new Set(textRuns.map((run) => run.fontSizePt).filter((size): size is number => size !== null))],\n\t\tcolors: [...new Set(textRuns.map((run) => run.color).filter((color): color is string => Boolean(color)))],\n\t\tfill: shape.fillColor,\n\t\tline: shape.lineColor,\n\t\tshapeType: shape.presetGeometry,\n\t}\n}\n\n/** Project one read-model {@link Run} onto the flat run shape. */\nfunction toRun(run: Run): PptxTextRun {\n\treturn {\n\t\ttext: run.text,\n\t\tfontSizePt: run.fontSizePt,\n\t\tcolor: run.color,\n\t\tfontFace: run.fontName,\n\t\t// The read model distinguishes \"explicitly not bold\" from \"unset, inherits\";\n\t\t// this surface reports what renders, so an unset flag is `false`.\n\t\tbold: run.bold ?? false,\n\t\titalic: run.italic ?? false,\n\t\tstrike: run.strike,\n\t\thighlight: run.highlight?.hex ?? null,\n\t\tcharSpacingPt: run.charSpacingPt,\n\t}\n}\n\n// PowerPoint body-inset defaults (ECMA-376 §21.1.2.1.1 prose; the XSD leaves\n// lIns/tIns/rIns/bIns optional with no schema default): 0.1in left/right,\n// 0.05in top/bottom. The read model reports only the explicitly-set sides.\nconst DEFAULT_INSET_LR_IN = 0.1\nconst DEFAULT_INSET_TB_IN = 0.05\nconst POINTS_PER_INCH = 72\n\nfunction readBodyInsets(textFrame: TextFrame | null): PptxBodyInsets | null {\n\tconst insets = textFrame?.bodyProperties?.insetsPt\n\tif (!insets) return null\n\tconst inches = (pt: number | undefined, fallback: number): number =>\n\t\tpt === undefined ? fallback : pt / POINTS_PER_INCH\n\treturn {\n\t\tleft: inches(insets.left, DEFAULT_INSET_LR_IN),\n\t\ttop: inches(insets.top, DEFAULT_INSET_TB_IN),\n\t\tright: inches(insets.right, DEFAULT_INSET_LR_IN),\n\t\tbottom: inches(insets.bottom, DEFAULT_INSET_TB_IN),\n\t}\n}\n\n/* ────────────────────────────────────────────────────────────────────────────\n * Unresolvable positions\n *\n * `absoluteFrame` reports `null` for three different situations, and only two of\n * them are worth telling the caller about. The distinction is not recoverable\n * from the `null`, so it is re-derived here from the same ancestry the read model\n * walks.\n * ──────────────────────────────────────────────────────────────────────────── */\n\n/** Warn about a shape whose slide position cannot be resolved, unless it never claimed one. */\nfunction reportUnresolvable(shape: AnyShape, zIndex: number, slidePath: string): void {\n\tconst element = shape.element_\n\t// No own `a:xfrm` at all: the shape inherits its geometry from a layout\n\t// placeholder, which this surface deliberately does not resolve. Nothing is\n\t// wrong with the deck, so nothing is reported.\n\tif (!hasBox(ownTransform(element), 'a:off', 'a:ext')) return\n\n\tconst who = shape.name ? `\"${shape.name}\"` : `the element at zIndex ${zIndex}`\n\tif (enclosingGroupLacksTransform(element)) {\n\t\twarn(\n\t\t\t'inspect/group-transform-missing',\n\t\t\t`inspect: skipped ${who} on ${slidePath} — an enclosing group has no usable a:xfrm, so its slide position cannot be resolved.`\n\t\t)\n\t\treturn\n\t}\n\twarn(\n\t\t'inspect/group-transform-degenerate',\n\t\t`inspect: skipped ${who} on ${slidePath} — an enclosing group has a degenerate transform (zero a:chExt), so its slide position cannot be resolved.`\n\t)\n}\n\n/** The element's own `a:xfrm` — on `p:grpSpPr` for a group, `p:spPr` for every other kind. */\nfunction ownTransform(element: Element): Element | null {\n\tconst props = firstChild(element, element.localName === 'grpSp' ? 'p:grpSpPr' : 'p:spPr')\n\treturn props && firstChild(props, 'a:xfrm')\n}\n\n/** Whether any enclosing `p:grpSp` fails to state a complete child-space mapping. */\nfunction enclosingGroupLacksTransform(element: Element): boolean {\n\tfor (let node = element.parentNode; node && node.nodeType === ELEMENT_NODE; node = node.parentNode) {\n\t\tconst parent = node as Element\n\t\tif (parent.namespaceURI !== OOXML_NS.p || parent.localName !== 'grpSp') return false // reached the shape tree\n\t\tconst xfrm = ownTransform(parent)\n\t\tif (!hasBox(xfrm, 'a:off', 'a:ext') || !hasBox(xfrm, 'a:chOff', 'a:chExt')) return true\n\t}\n\treturn false\n}\n\n/** Whether a transform states a complete position + extent pair. */\nfunction hasBox(xfrm: Element | null, offName: string, extName: string): boolean {\n\tif (!xfrm) return false\n\tconst off = firstChild(xfrm, offName)\n\tconst ext = firstChild(xfrm, extName)\n\tif (!off || !ext) return false\n\treturn (\n\t\tintValue(attr(off, 'x')) !== null &&\n\t\tintValue(attr(off, 'y')) !== null &&\n\t\tintValue(attr(ext, 'cx')) !== null &&\n\t\tintValue(attr(ext, 'cy')) !== null\n\t)\n}\n\nfunction countWords(text: string): number {\n\treturn text.split(/\\s+/).filter(Boolean).length\n}\n\nfunction round(value: number, digits: number): number {\n\tconst factor = 10 ** digits\n\treturn Math.round(value * factor) / factor\n}\n\n// Error taxonomy — every failure the library throws. The classes and their `code` are API;\n// the message is not. Re-exported from every entry so `instanceof` works whichever subpath a\n// consumer imports — they all resolve to one shared module, so the classes are identical.\nexport {\n\tTsPptxError,\n\tInvalidOptionError,\n\tUnsupportedFeatureError,\n\tPackageReadError,\n\tMediaError,\n\tInternalError,\n\ttype TsPptxErrorOptions,\n} from './errors.js'\nexport type {\n\tErrorCode,\n\tTsPptxCode,\n\tInvalidOptionErrorCode,\n\tUnsupportedFeatureErrorCode,\n\tPackageReadErrorCode,\n\tMediaErrorCode,\n\tInternalErrorCode,\n} from './codes.js'\n"],"mappings":"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"}