@shbernal/ts-pptx 0.0.1 → 2.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 (53) hide show
  1. package/README.md +3 -1
  2. package/dist/browser.d.ts +5 -5
  3. package/dist/browser.js +2 -2
  4. package/dist/{diagnostics-DzY9Tyfm.d.ts → diagnostics-CQ0JWc9m.d.ts} +4 -21
  5. package/dist/{diagnostics-DzY9Tyfm.d.ts.map → diagnostics-CQ0JWc9m.d.ts.map} +1 -1
  6. package/dist/{errors-DRLpOpgQ.d.ts → errors-B22h8Qd0.d.ts} +3 -3
  7. package/dist/{errors-DRLpOpgQ.d.ts.map → errors-B22h8Qd0.d.ts.map} +1 -1
  8. package/dist/errors-DGE9zh3U.js.map +1 -1
  9. package/dist/{fit-CbxyHN69.js → fit-BSWY0AYt.js} +0 -0
  10. package/dist/{fit-CbxyHN69.js.map → fit-BSWY0AYt.js.map} +1 -1
  11. package/dist/{html-dom-wVa3TiG7.js → html-dom-BQLUntho.js} +2 -2
  12. package/dist/html-dom-BQLUntho.js.map +1 -0
  13. package/dist/html.d.ts +3 -3
  14. package/dist/html.js +1 -1
  15. package/dist/{image-size-C5Z1sKof.js → image-size-C8uYE8GJ.js} +3 -3
  16. package/dist/{image-size-C5Z1sKof.js.map → image-size-C8uYE8GJ.js.map} +1 -1
  17. package/dist/index.d.ts +5 -5
  18. package/dist/index.js +2 -2
  19. package/dist/inspect.d.ts +1 -1
  20. package/dist/inspect.js +2 -2
  21. package/dist/math.d.ts +1 -1
  22. package/dist/math.js +2 -1
  23. package/dist/math.js.map +1 -1
  24. package/dist/measure.d.ts +2 -2
  25. package/dist/measure.js +1 -1
  26. package/dist/node.d.ts +5 -5
  27. package/dist/node.js +1 -1
  28. package/dist/{pres-5x1bjCzk.d.ts → pres-GU-jjBEx.d.ts} +2 -2
  29. package/dist/{pres-5x1bjCzk.d.ts.map → pres-GU-jjBEx.d.ts.map} +1 -1
  30. package/dist/{presentation-RGOiun5P.d.ts → presentation-CVaTZw1V.d.ts} +316 -18
  31. package/dist/presentation-CVaTZw1V.d.ts.map +1 -0
  32. package/dist/{presentation-B0JWdTN1.js → presentation-MJe9WDi4.js} +21 -27
  33. package/dist/presentation-MJe9WDi4.js.map +1 -0
  34. package/dist/read.d.ts +4 -4
  35. package/dist/read.js +2 -2
  36. package/dist/script.d.ts +2 -2
  37. package/dist/script.d.ts.map +1 -1
  38. package/dist/script.js +0 -0
  39. package/dist/script.js.map +1 -1
  40. package/dist/{shapes-BZU8UTW2.js → shapes-CaOgR0i1.js} +910 -22
  41. package/dist/shapes-CaOgR0i1.js.map +1 -0
  42. package/dist/{slide-B6mDaM-P.d.ts → slide-BBlElWr9.d.ts} +223 -92
  43. package/dist/slide-BBlElWr9.d.ts.map +1 -0
  44. package/dist/{text-WRUbOy2r.js → text-B1ZrPEeK.js} +441 -186
  45. package/dist/text-B1ZrPEeK.js.map +1 -0
  46. package/dist/zip.d.ts +1 -1
  47. package/package.json +9 -20
  48. package/dist/html-dom-wVa3TiG7.js.map +0 -1
  49. package/dist/presentation-B0JWdTN1.js.map +0 -1
  50. package/dist/presentation-RGOiun5P.d.ts.map +0 -1
  51. package/dist/shapes-BZU8UTW2.js.map +0 -1
  52. package/dist/slide-B6mDaM-P.d.ts.map +0 -1
  53. package/dist/text-WRUbOy2r.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"script.js","names":["#seen","#notes","ANCHOR","positionOfFrame","#byPartName","#assets","#counts","PACKAGE_NAME","printSlides"],"sources":["../src/script/fidelity.ts","../src/script/from-read/detect.ts","../src/script/from-read/values.ts","../src/script/from-read/chrome.ts","../src/script/from-read/picture-fill.ts","../src/script/from-read/text.ts","../src/script/from-read/table.ts","../src/script/from-read/chart.ts","../src/script/from-read/shape.ts","../src/script/from-read/transition.ts","../src/script/from-read/deck.ts","../src/script/ir.ts","../src/script/print/literal.ts","../src/script/print/common.ts","../src/script/print/script.ts","../src/script/print/standalone.ts","../src/script/verify/canonical.ts","../src/script/verify/diff.ts"],"sourcesContent":["/**\n * Fidelity notes — the declared, machine-checkable list of what a deck loses on the way\n * to a script.\n *\n * A converter that warns about losses to a log has no way to be tested: the warnings are\n * prose, nothing consumes them, and a missing one looks exactly like a clean run. Making\n * the notes part of the IR inverts that. A note says \"field X of shape Y will not come\n * back\", so a round-trip check can exclude precisely those fields and treat **any**\n * remaining difference as a defect. Both directions then have teeth:\n *\n * - an *undeclared* loss fails the round-trip, because nothing excluded it;\n * - a *declared* loss that actually survives is a stale note, and the check can say so.\n *\n * That is the whole reason notes are first-class rather than a side channel. It also\n * means {@link FidelityNote.construct} is an identifier, not a sentence: it has to be\n * matchable against a field path, so it is a stable dotted key and the human explanation\n * lives in {@link FidelityNote.detail}.\n */\n\n/** What happened to the construct. */\nexport type Disposition =\n\t/** Gone: nothing in the output carries it. */\n\t| 'dropped'\n\t/**\n\t * Present but structurally simplified — a value survives while the structure around\n\t * it does not (threaded comment replies flattened into separate comments, a per-script\n\t * font scheme reduced to latin, a placeholder demoted to a plain shape).\n\t */\n\t| 'flattened'\n\t/**\n\t * Present and structurally intact, but not the same value — a re-encoding that a\n\t * viewer may or may not be able to tell apart (a modern transition mapped to the\n\t * nearest named one, a chart rebuilt from cached points rather than its workbook).\n\t */\n\t| 'approximated'\n\n/**\n * Which side of the library is responsible. Recording this is what makes the notes\n * actionable rather than merely honest: `unread` and `unwritable` are bugs waiting to be\n * fixed in a specific subsystem, while `unsupported` is a property of OOXML or of the\n * chosen output tier and will not be fixed by more converter work.\n */\nexport type Cause =\n\t/** The read API exposes no accessor for it, so the converter never saw it. */\n\t| 'unread'\n\t/** Read fine, but the write API has no option that expresses it. */\n\t| 'unwritable'\n\t/** Both sides can handle it; this output tier structurally cannot carry it. */\n\t| 'unsupported'\n\n/** One declared loss. */\nexport interface FidelityNote {\n\t/** 1-based source slide, or `null` for a deck-level loss. */\n\tslideNumber: number | null\n\t/** Source shape name (`p:cNvPr/@name`), or `null` when the loss is not shape-scoped. */\n\tshapeName: string | null\n\t/**\n\t * Stable dotted identifier for the lost construct — `line.width`, `text.tabStops`,\n\t * `chart.workbook`. Matched mechanically by the round-trip check, so it must name a\n\t * field path rather than describe one. Reuse an existing key for the same construct\n\t * instead of coining a synonym.\n\t */\n\tconstruct: string\n\tdisposition: Disposition\n\tcause: Cause\n\t/** Why, in a sentence, for a human reading the emitted script's header. */\n\tdetail: string\n}\n\n/**\n * Accumulates notes while a deck is walked, so the walk itself stays a plain\n * read-model → IR mapping and does not thread a growing array through every function.\n *\n * Deduplicates on the full note identity. Without that, a construct that is lost on every\n * run of a 400-run text body would produce 400 identical notes and bury the one-off losses\n * that actually need reading.\n */\nexport class NoteCollector {\n\treadonly #seen = new Set<string>()\n\treadonly #notes: FidelityNote[] = []\n\n\t/** Record a loss. A repeat of an identical note is ignored. */\n\tadd(note: FidelityNote): void {\n\t\tconst key = `${note.slideNumber}\u0000${note.shapeName}\u0000${note.construct}\u0000${note.disposition}\u0000${note.cause}\u0000${note.detail}`\n\t\tif (this.#seen.has(key)) return\n\t\tthis.#seen.add(key)\n\t\tthis.#notes.push(note)\n\t}\n\n\t/**\n\t * The notes, in the order first recorded — which is deck order, since the walk is\n\t * ordered, so a reader meets them the way they meet the slides.\n\t */\n\tget notes(): FidelityNote[] {\n\t\treturn this.#notes\n\t}\n}\n\n/**\n * A {@link NoteCollector} bound to one slide and shape, so a mapping function can record\n * a loss without knowing where in the deck it sits. Obtained via {@link scopeNotes}.\n */\nexport interface NoteScope {\n\t/** Record a loss at this scope. */\n\tnote(construct: string, disposition: Disposition, cause: Cause, detail: string): void\n\t/** Re-scope to a shape within the same slide. */\n\tforShape(shapeName: string | null): NoteScope\n}\n\n/** Bind a collector to a slide (and optionally a shape). */\nexport function scopeNotes(\n\tcollector: NoteCollector,\n\tslideNumber: number | null,\n\tshapeName: string | null = null\n): NoteScope {\n\treturn {\n\t\tnote(construct, disposition, cause, detail) {\n\t\t\tcollector.add({ slideNumber, shapeName, construct, disposition, cause, detail })\n\t\t},\n\t\tforShape(name) {\n\t\t\treturn scopeNotes(collector, slideNumber, name)\n\t\t},\n\t}\n}\n","/**\n * Presence checks for constructs the read model has no accessor for.\n *\n * These reach through the documented raw hatch (`element_`) rather than through a typed\n * accessor, which needs justifying. The rule they follow: **detect, never decode.** Each\n * function answers only \"is this here?\", so the answer can become a {@link FidelityNote}.\n * Nothing here interprets a value or feeds one into a call — that would be building a\n * private read path alongside the public one, and it would rot the moment the element's\n * meaning changed.\n *\n * The alternative is worse than the coupling. Without these checks, a deck with an embedded\n * video converts to a static poster image and a deck with an equation converts to an empty\n * box, both silently and both with a clean round-trip, because a diff cannot see what\n * neither side read. A loss you can name is a bug report; a loss nothing observes is a\n * defect that ships.\n *\n * Each check here is a standing argument for a real accessor. When one lands, the\n * corresponding function should be deleted, not kept in sync.\n */\n\n/** DrawingML main namespace — hosts `a:videoFile` / `a:audioFile` under `p:nvPr`. */\nconst A_NS = 'http://schemas.openxmlformats.org/drawingml/2006/main'\n\n/** Office MathML namespace — the equation body itself, wrapped by `a14:m` in a text run. */\nconst MATH_NS = 'http://schemas.openxmlformats.org/officeDocument/2006/math'\n\n/** PresentationML main namespace — `p:grpSpPr`, `p:txStyles`, `p:spTree`. */\nconst P_NS = 'http://schemas.openxmlformats.org/presentationml/2006/main'\n\n/** Shape-tree children that carry drawing content, as opposed to the tree's own properties. */\nconst SHAPE_ELEMENTS = new Set(['sp', 'pic', 'graphicFrame', 'grpSp', 'cxnSp'])\n\n/** A minimal structural view of a DOM element, so this module needs no DOM lib types. */\ninterface ElementLike {\n\tnamespaceURI: string | null\n\tlocalName: string | null\n\tfirstChild: NodeLike | null\n\tgetAttribute(name: string): string | null\n\tgetElementsByTagNameNS(namespaceURI: string, localName: string): { length: number }\n}\n\ninterface NodeLike {\n\tnodeType: number\n\tnextSibling: NodeLike | null\n}\n\nconst ELEMENT_NODE = 1\n\nfunction has(element: unknown, namespaceURI: string, localName: string): boolean {\n\tconst el = element as ElementLike | null\n\tif (!el || typeof el.getElementsByTagNameNS !== 'function') return false\n\treturn el.getElementsByTagNameNS(namespaceURI, localName).length > 0\n}\n\n/**\n * The first *direct* child with this name.\n *\n * A subtree search is wrong for structural lookups, in two ways that both bite here.\n * `a:ext` names two unrelated elements — a shape extent (`@cx`/`@cy`) and an extension-list\n * entry (`@uri`) — so a subtree search finds whichever comes first in document order. And on\n * a group it descends into the group's own children, so a nested group's transform answers\n * for its parent's.\n */\nfunction child(element: ElementLike | null, namespaceURI: string, localName: string): ElementLike | null {\n\tif (!element) return null\n\tfor (let node = element.firstChild; node; node = node.nextSibling) {\n\t\tif (node.nodeType !== ELEMENT_NODE) continue\n\t\tconst el = node as unknown as ElementLike\n\t\tif (el.namespaceURI === namespaceURI && el.localName === localName) return el\n\t}\n\treturn null\n}\n\n/** Every direct element child, as {@link ElementLike}s. */\nfunction children(element: ElementLike | null): ElementLike[] {\n\tif (!element) return []\n\tconst out: ElementLike[] = []\n\tfor (let node = element.firstChild; node; node = node.nextSibling) {\n\t\tif (node.nodeType === ELEMENT_NODE) out.push(node as unknown as ElementLike)\n\t}\n\treturn out\n}\n\n/**\n * `true` when this shape is an embedded audio or video rather than a still picture.\n *\n * PowerPoint authors media as a `p:pic` whose `p:nvPr` carries an `a:videoFile` or\n * `a:audioFile`, with the poster frame as the picture's own blip. The read model reports\n * only the poster — `mediaKind` distinguishes raster from SVG, not still from moving — so\n * without this check a video converts to a static image that looks deliberate.\n */\nexport function isAudioVideo(element: unknown): boolean {\n\treturn has(element, A_NS, 'videoFile') || has(element, A_NS, 'audioFile')\n}\n\n/**\n * `true` when this shape's text body contains an OMML equation.\n *\n * An equation lives in `m:oMath` inside an `a14:m` run, which contributes nothing to\n * `TextFrame.text`, so an equation-only shape reads as an empty text frame. The write API\n * *can* author one (`TextProps.math`, plus the `ts-pptx/math` subpath for LaTeX/MathML\n * input), which makes this a read-side gap rather than a hard limit.\n */\nexport function hasEquation(element: unknown): boolean {\n\treturn has(element, MATH_NS, 'oMath')\n}\n\n/**\n * `true` when this `p:sp` is a text box rather than an auto shape.\n *\n * The discriminator is one attribute, `p:cNvSpPr/@txBox`, and nothing reads it. The\n * tempting substitute — \"it has no preset geometry\" — is wrong for the common case:\n * PowerPoint gives every text box an explicit `<a:prstGeom prst=\"rect\"/>`, so that test\n * calls every real text box an auto shape. The difference is not cosmetic. PowerPoint\n * autofits, wraps and resizes a text box by different rules, and offers a different\n * right-click menu for it.\n *\n * Direct child rather than a subtree search: `p:cNvSpPr` sits under `p:nvSpPr`, and a group\n * would otherwise answer for its first child.\n */\nexport function isTextBox(element: unknown): boolean {\n\tconst nvSpPr = child(element as ElementLike | null, P_NS, 'nvSpPr')\n\treturn child(nvSpPr, P_NS, 'cNvSpPr')?.getAttribute('txBox') === '1'\n}\n\n/**\n * `true` when a group's child coordinate space equals its own frame, so its children are\n * already in slide-absolute units.\n *\n * `addGroup` always emits an identity child space; a source group whose `a:chOff`/`a:chExt`\n * differ scales or shifts its contents, and that behaviour cannot be reproduced. The read\n * model has no accessor for the child space — `absoluteFrame` deliberately composes it away,\n * which is right for locating a shape and wrong for spotting this difference.\n *\n * A group with no explicit transform inherits an identity one, so a missing `a:xfrm` is\n * `true` rather than unknown.\n */\nexport function hasIdentityChildSpace(element: unknown): boolean {\n\tconst xfrm = child(child(element as ElementLike | null, P_NS, 'grpSpPr'), A_NS, 'xfrm')\n\tif (!xfrm) return true\n\n\tconst off = child(xfrm, A_NS, 'off')\n\tconst ext = child(xfrm, A_NS, 'ext')\n\tconst chOff = child(xfrm, A_NS, 'chOff')\n\tconst chExt = child(xfrm, A_NS, 'chExt')\n\tif (!off || !ext || !chOff || !chExt) return true\n\n\treturn (\n\t\toff.getAttribute('x') === chOff.getAttribute('x') &&\n\t\toff.getAttribute('y') === chOff.getAttribute('y') &&\n\t\text.getAttribute('cx') === chExt.getAttribute('cx') &&\n\t\text.getAttribute('cy') === chExt.getAttribute('cy')\n\t)\n}\n\n/**\n * `true` when this theme declares an `a:fmtScheme`.\n *\n * The format scheme holds the three fill, three line and three effect style lists a shape's\n * `p:style` indexes into. Neither half of the library touches it: nothing reads it, and the\n * write path emits a hardcoded Office one. So a deck whose theme carries a custom format\n * scheme is repainted with Office's, and this is the only way to notice.\n */\nexport function hasFormatScheme(element: unknown): boolean {\n\treturn has(element, A_NS, 'fmtScheme')\n}\n\n/**\n * `true` when this slide master declares per-level text styles (`p:txStyles`) with content.\n *\n * `SlideMasterProps.textStyles` can author them, so this is purely a read-side gap — the\n * default size, face, colour and bullet of every placeholder level is invisible to the\n * converter and comes back as PowerPoint's built-in default.\n */\nexport function hasTextStyles(element: unknown): boolean {\n\tconst txStyles = child(element as ElementLike | null, P_NS, 'txStyles')\n\treturn children(txStyles).some((group) => children(group).length > 0)\n}\n\n/**\n * `true` when this master or layout carries a shape that is not a placeholder — a logo, a\n * rule, a background image, a footer graphic.\n *\n * The read model is explicit that it decodes master/layout *placeholders* only, leaving\n * decoration to the byte-for-byte import paths. An output that rebuilds the chrome from the\n * read model therefore loses every one of these, and a deck that has none loses nothing —\n * which is why this is a count rather than a blanket note.\n */\nexport function hasDecorativeShapes(element: unknown): boolean {\n\tconst spTree = child(child(element as ElementLike | null, P_NS, 'cSld'), P_NS, 'spTree')\n\treturn children(spTree).some(\n\t\t(shape) => shape.namespaceURI === P_NS && SHAPE_ELEMENTS.has(shape.localName ?? '') && !has(shape, P_NS, 'ph')\n\t)\n}\n","/**\n * Value-level conversions shared by every mapper: geometry, colour, and the small\n * discipline that keeps an IR diffable.\n *\n * The precision rules here are not style choices, they are the measured boundary of what\n * the write API can carry, and each is pinned by a regression test:\n *\n * - A `Coord`-typed option accepts `` `${n}emu` ``, so EMU passes through untouched and\n * the source geometry is reproduced exactly. That covers every position and size.\n * - `colW`, `rowH`, and `margin` are number/`Margin`-typed **inches** and reject a raw-EMU\n * string, so they are where exactness stops. `defineLayout`'s `width`/`height` are a\n * fourth, reached only by a printer: there the imprecision does not degrade quietly but\n * *throws*, since `appendSlides` compares the two decks' EMU sizes for equality after\n * converting the declared inches back. Six decimal places is the minimum\n * at which `Math.round(printed × 914400)` provably returns the original EMU, bounding the\n * drift at 0.4572 EMU — about half a millionth of an inch. Rounding shorter to suppress\n * `0.5000000001`-style noise trades a cosmetic problem for a real geometry loss.\n */\nimport type { IrValue } from '../ir.js'\n\n/** EMU per inch (ECMA-376 §20.1.2.1). */\nconst EMU_PER_INCH = 914400\n\n/**\n * Decimal places used for the inch-typed options. See the module header: this is the\n * proven minimum for an EMU-exact round-trip, not a formatting preference.\n */\nconst INCH_DECIMALS = 6\n\n/** Geometry as a `Coord` the write API takes verbatim, preserving the exact EMU. */\nexport function emu(value: number): string {\n\treturn `${Math.round(value)}emu`\n}\n\n/**\n * Geometry as inches, for the three options that reject a raw-EMU string. Rounded to\n * {@link INCH_DECIMALS}, which is EMU-exact on the way back.\n */\nexport function inches(emuValue: number): number {\n\treturn Number((emuValue / EMU_PER_INCH).toFixed(INCH_DECIMALS))\n}\n\n/** EMU → points, the unit the write API uses for line widths and font sizes. */\nexport function points(emuValue: number): number {\n\treturn emuValue / 12700\n}\n\n/**\n * Points → inches, at the same proven precision as {@link inches}. Needed because the read\n * model reports text-body insets in points while the write API's `margin` takes inches —\n * and warns on a value `>= 1`, on the assumption that it is a points value passed by\n * mistake, so handing it points would both mis-scale the text and produce a warning.\n */\nexport function pointsToInches(pt: number): number {\n\treturn Number((pt / 72).toFixed(INCH_DECIMALS))\n}\n\n/**\n * A colour for a write-API `color` field. The read model splits a colour into a raw\n * `schemeClr` token and a resolved literal hex; this prefers the token, because a token\n * re-resolves against the destination theme and so keeps the deck recolourable, which is\n * the whole reason a theme colour was authored.\n *\n * Only the ten tokens the write path's `clrMap` covers survive as tokens — the other\n * seven `ST_SchemeColorVal` values degrade to a hex literal there anyway, so passing them\n * through would produce a silently different colour. Callers hand those to\n * {@link literalColor} instead after recording a note.\n */\nconst WRITABLE_SCHEME_TOKENS = new Set([\n\t'accent1',\n\t'accent2',\n\t'accent3',\n\t'accent4',\n\t'accent5',\n\t'accent6',\n\t'bg1',\n\t'bg2',\n\t'tx1',\n\t'tx2',\n])\n\n/** `true` when a `schemeClr` token survives as a token rather than degrading to hex. */\nexport function isWritableSchemeToken(token: string | null): boolean {\n\treturn token !== null && WRITABLE_SCHEME_TOKENS.has(token)\n}\n\n/** Normalize a hex to the bare 6-digit uppercase form the write API expects. */\nexport function literalColor(hex: string): string {\n\treturn hex.replace(/^#/, '').toUpperCase()\n}\n\n/**\n * Build an IR object from possibly-absent parts, dropping every `undefined`.\n *\n * Every mapper funnels through this. An IR must spell \"absent\" exactly one way — a\n * missing key — or two IRs describing the same deck compare unequal because one wrote\n * `{ bold: undefined }` and the other wrote `{}`. That would surface as phantom\n * round-trip failures, so the invariant is enforced in one place rather than trusted to\n * every call site.\n *\n * Returns `undefined` when nothing survived, so a caller can drop the whole option object\n * rather than emit an empty one.\n */\nexport function compact(source: Record<string, IrValue | undefined>): Record<string, IrValue> | undefined {\n\tconst out: Record<string, IrValue> = {}\n\tlet any = false\n\tfor (const key of Object.keys(source).sort()) {\n\t\tconst value = source[key]\n\t\tif (value === undefined) continue\n\t\tout[key] = value\n\t\tany = true\n\t}\n\treturn any ? out : undefined\n}\n\n/** {@link compact}, but always an object — for a required options argument. */\nexport function compactRequired(source: Record<string, IrValue | undefined>): Record<string, IrValue> {\n\treturn compact(source) ?? {}\n}\n\n/** Drop a value that is `null`, so the read model's \"unset\" becomes an absent IR key. */\nexport function orUndefined<T>(value: T | null): T | undefined {\n\treturn value === null ? undefined : value\n}\n\n/**\n * A 0–1 opacity as the write API's 0–100 transparency; `undefined` when unset.\n *\n * Fully opaque is *not* `0` here — a caller that means \"no transparency at all\" passes\n * `undefined`, because emitting `transparency: 0` for an `a:alphaModFix amt=\"100000\"`\n * would produce a key the output cannot have: the write path emits no `a:alphaModFix` for\n * a zero transparency, so the re-read deck reports no alpha and the round trip sees a\n * difference where there is no visible one.\n */\nexport function alphaToTransparency(alpha: number | null | undefined): number | undefined {\n\tif (alpha === undefined || alpha === null) return undefined\n\treturn Math.round((1 - alpha) * 100)\n}\n","/**\n * The deck's shared chrome → {@link ChromeIr}: theme colours and fonts, plus one\n * `defineSlideMaster` descriptor per source layout.\n *\n * **Only a standalone output needs any of this,** and it is the part of a deck that survives\n * a conversion worst. A template-anchored output reuses the source package, so its masters,\n * layouts and theme are the originals byte for byte; everything below is the approximation\n * that replaces them when there is no template to inherit from. The notes it records are\n * therefore tier-scoped: real for a standalone script, and suppressed by the template-anchored\n * printer because they do not describe its output.\n *\n * **Three ceilings meet here, and none of them moves by working harder on this file:**\n *\n * 1. `a:fmtScheme` is unreachable from *both* directions — no read accessor, and the write\n * path emits a hardcoded Office one. A shape whose look comes from `p:style` is repainted.\n * 2. `p:txStyles` has a write counterpart (`SlideMasterProps.textStyles`) and no reader, so\n * the per-level placeholder defaults are invisible.\n * 3. Master and layout *decoration* — anything that is not a placeholder — is documented as\n * out of the read model's scope (`src/read/api/chrome.ts` header); the import paths carry\n * it byte-for-byte instead. A logo on a layout cannot be seen, let alone re-authored.\n *\n * **Layout placeholders are deliberately not emitted, and that is a write-path finding rather\n * than a read-path one.** `addPlaceholdersToSlideLayouts` seeds *every* slide with each layout\n * placeholder the slide did not populate, as an empty text shape\n * (`src/gen/define/placeholder.ts`). Since this converter transcribes every source shape as\n * concrete absolute-positioned content and never binds one to a placeholder, reproducing the\n * layout's placeholders would add a ghost shape to every slide for each of them — shapes the\n * source deck does not have. Dropping them costs an editing affordance; emitting them would\n * cost the output's shape tree.\n */\nimport type { Presentation } from '../../read/api/presentation.js'\nimport type { SlideMaster, Theme } from '../../read/api/chrome.js'\nimport type { SlideBackground } from '../../read/api/slide-background.js'\nimport type { ChromeIr, IrValue, MasterIr, ThemeIr } from '../ir.js'\nimport type { NoteScope } from '../fidelity.js'\nimport type { AssetResolver } from './shape.js'\nimport { hasDecorativeShapes, hasFormatScheme, hasTextStyles } from './detect.js'\nimport { compact, literalColor, orUndefined } from './values.js'\n\n/**\n * The `p:clrMap` the write path always emits (`src/gen/slide/master.ts`). A source master\n * that maps a token elsewhere — a deck whose light and dark slots are swapped, the usual\n * case — resolves every `schemeClr` in the deck differently, and there is no setter for it.\n */\nconst DEFAULT_COLOR_MAP: Record<string, string> = {\n\tbg1: 'lt1',\n\ttx1: 'dk1',\n\tbg2: 'lt2',\n\ttx2: 'dk2',\n\taccent1: 'accent1',\n\taccent2: 'accent2',\n\taccent3: 'accent3',\n\taccent4: 'accent4',\n\taccent5: 'accent5',\n\taccent6: 'accent6',\n\thlink: 'hlink',\n\tfolHlink: 'folHlink',\n}\n\n/** Build the chrome IR for a deck. */\nexport function chromeToIr(pres: Presentation, notes: NoteScope, assets: AssetResolver): ChromeIr {\n\tconst masters = pres.masters()\n\n\tif (masters.length > 1) {\n\t\tnotes.note(\n\t\t\t'master.multiple',\n\t\t\t'flattened',\n\t\t\t'unsupported',\n\t\t\t`this deck has ${masters.length} slide masters; the write API models a deck as one shared master with many layouts, so every layout is rebuilt under a single master and only the first master's theme and colour map survive`\n\t\t)\n\t}\n\n\tconst first = masters[0]\n\tconst theme = first?.theme ?? null\n\trecordMasterLosses(masters, theme, notes)\n\n\treturn { theme: themeToIr(theme), masters: layoutsToIr(masters, notes, assets) }\n}\n\n/** The theme's colour scheme and font faces, in `ThemeProps` spelling. */\nfunction themeToIr(theme: Theme | null): ThemeIr {\n\tif (!theme) return {}\n\n\tconst scheme = theme.colorScheme\n\tconst colors: Record<string, string> = {}\n\tfor (const [slot, hex] of Object.entries(scheme)) {\n\t\tif (hex !== null) colors[slot] = literalColor(hex)\n\t}\n\n\tconst fonts = theme.fontScheme\n\treturn compact({\n\t\theadFontFace: orUndefined(fonts?.major.latin ?? null),\n\t\tbodyFontFace: orUndefined(fonts?.minor.latin ?? null),\n\t\theadFontFaceEA: orUndefined(fonts?.major.ea ?? null),\n\t\tbodyFontFaceEA: orUndefined(fonts?.minor.ea ?? null),\n\t\theadFontFaceCS: orUndefined(fonts?.major.cs ?? null),\n\t\tbodyFontFaceCS: orUndefined(fonts?.minor.cs ?? null),\n\t\tcolorScheme: Object.keys(colors).length > 0 ? colors : undefined,\n\t}) as ThemeIr\n}\n\n/** The losses that belong to the master/theme tier as a whole rather than to one layout. */\nfunction recordMasterLosses(masters: SlideMaster[], theme: Theme | null, notes: NoteScope): void {\n\tif (theme && hasFormatScheme(theme.element_)) {\n\t\tnotes.note(\n\t\t\t'theme.fmtScheme',\n\t\t\t'approximated',\n\t\t\t'unread',\n\t\t\t\"the theme's format scheme (a:fmtScheme — the three fill, line and effect style lists a shape's p:style indexes into) has no read accessor and no write-API option, so the output carries Office's default; a shape whose fill or outline came from the theme rather than from its own a:ln keeps its colour but not its width, dash or effect\"\n\t\t)\n\t}\n\n\tfor (const master of masters) {\n\t\tconst root = master.part.dom.documentElement\n\t\tif (hasTextStyles(root)) {\n\t\t\tnotes.note(\n\t\t\t\t'master.txStyles',\n\t\t\t\t'dropped',\n\t\t\t\t'unread',\n\t\t\t\t\"the master's per-level text styles (p:txStyles — the default size, face, colour, indent and bullet of each of the nine list levels) have no read accessor, so placeholder text falls back to PowerPoint's built-in defaults; SlideMasterProps.textStyles could author them if they could be seen\"\n\t\t\t)\n\t\t}\n\t\tif (hasDecorativeShapes(root)) {\n\t\t\tnotes.note(\n\t\t\t\t'master.decoration',\n\t\t\t\t'dropped',\n\t\t\t\t'unread',\n\t\t\t\t'this slide master carries shapes that are not placeholders (a logo, a rule, a background graphic); the read model decodes master and layout placeholders only, so they cannot be re-authored'\n\t\t\t)\n\t\t}\n\n\t\tconst map = master.colorMap\n\t\tconst remapped = Object.entries(DEFAULT_COLOR_MAP).filter(\n\t\t\t([token, slot]) => map[token as keyof typeof map] !== slot\n\t\t)\n\t\tif (remapped.length > 0) {\n\t\t\tnotes.note(\n\t\t\t\t'master.colorMap',\n\t\t\t\t'dropped',\n\t\t\t\t'unwritable',\n\t\t\t\t`this master remaps ${remapped.map(([token]) => token).join(', ')} to a different theme slot and the write path always emits the identity map, so every scheme colour that passes through as a token resolves to a different hex than it did in the source`\n\t\t\t)\n\t\t}\n\t}\n}\n\n/**\n * One `defineSlideMaster` descriptor per source layout, in the same gallery order\n * `Presentation.layouts()` reports — which is what lets a slide bind by index.\n *\n * Titles are made unique because they are the lookup key `addSlide({ masterTitle })` matches\n * on, and `p:cSld@name` is not unique: a multi-master deck routinely carries several layouts\n * called \"Title and Content\", and two `defineSlideMaster` calls sharing a title would make\n * every slide bind to whichever won.\n */\nfunction layoutsToIr(masters: SlideMaster[], notes: NoteScope, assets: AssetResolver): MasterIr[] {\n\tconst out: MasterIr[] = []\n\tconst used = new Set<string>()\n\t// Rolled up rather than noted per layout: a 12-layout deck loses decoration and placeholder\n\t// definitions on most of them, and twelve near-identical paragraphs at the top of the\n\t// emitted script bury the per-shape notes underneath that a reader can actually act on.\n\tconst decorated: string[] = []\n\tlet placeholderCount = 0\n\tlet placeholderLayouts = 0\n\n\tconst renamed: string[] = []\n\tconst collided: string[] = []\n\n\tfor (const master of masters) {\n\t\tfor (const layout of master.layouts) {\n\t\t\tconst index = out.length\n\t\t\tconst flattened = flattenAttributeValue(layout.name)\n\t\t\tif (flattened !== layout.name) renamed.push(`${JSON.stringify(layout.name)} → ${JSON.stringify(flattened)}`)\n\t\t\tconst base = flattened || `Layout ${index + 1}`\n\t\t\tlet title = base\n\t\t\tfor (let suffix = 2; used.has(title); suffix++) title = `${base} (${suffix})`\n\t\t\tif (title !== base) collided.push(`${JSON.stringify(base)} → ${JSON.stringify(title)}`)\n\t\t\tused.add(title)\n\n\t\t\tif (hasDecorativeShapes(layout.part.dom.documentElement)) decorated.push(title)\n\t\t\tconst placeholders = layout.placeholders.length\n\t\t\tif (placeholders > 0) {\n\t\t\t\tplaceholderCount += placeholders\n\t\t\t\tplaceholderLayouts++\n\t\t\t}\n\n\t\t\t// The layout's own background if it has one, else the master's — which is what a slide\n\t\t\t// bound to that layout actually shows, and the only tier the write API can set it at.\n\t\t\tconst background = backgroundProps(layout.background ?? master.background, notes, assets)\n\t\t\tout.push({ layoutIndex: index, props: compact({ title, background }) as Record<string, IrValue> })\n\t\t}\n\t}\n\n\tif (collided.length > 0) {\n\t\tnotes.note(\n\t\t\t'master.nameCollision',\n\t\t\t'approximated',\n\t\t\t'unsupported',\n\t\t\t`${collided.length} layout name(s) are not unique in the source — normally because the deck has several masters, each with its own \"Title and Content\" — and a layout title here is also the key addSlide({ masterTitle }) binds on, so duplicates cannot both exist. The later ones are suffixed and the slides bound to them follow: ${collided.join('; ')}`\n\t\t)\n\t}\n\tif (renamed.length > 0) {\n\t\tnotes.note(\n\t\t\t'master.name',\n\t\t\t'flattened',\n\t\t\t'unwritable',\n\t\t\t`${renamed.length} layout name(s) contain a line break or tab, which cannot survive as a layout title: the write path emits the name as a literal XML attribute value rather than a character reference, and XML normalises whitespace in an attribute to spaces. Collapsed here so the emitted script says what the output will contain — ${renamed.join('; ')}`\n\t\t)\n\t}\n\tif (decorated.length > 0) {\n\t\tnotes.note(\n\t\t\t'master.decoration',\n\t\t\t'dropped',\n\t\t\t'unread',\n\t\t\t`${decorated.length} slide layout(s) carry shapes that are not placeholders — ${decorated.join(', ')} — and the read model decodes layout placeholders only, so that decoration cannot be re-authored`\n\t\t)\n\t}\n\tif (placeholderCount > 0) {\n\t\tnotes.note(\n\t\t\t'master.placeholders',\n\t\t\t'dropped',\n\t\t\t'unsupported',\n\t\t\t`the ${placeholderCount} placeholder definition(s) across ${placeholderLayouts} slide layout(s) are not reproduced: the write path seeds every slide with each layout placeholder the slide did not populate, and since every source shape is authored here as concrete content rather than into a placeholder, re-declaring them would add an empty shape to every slide rather than a prompt`\n\t\t)\n\t}\n\n\treturn out\n}\n\n/**\n * Collapse the whitespace an XML attribute value cannot carry.\n *\n * Not a style choice: XML normalises a literal tab, carriage return or line feed inside an\n * attribute value to a space (XML 1.0 §3.3.3), and the write path emits a layout title as a\n * literal rather than as a `&#10;` character reference. So a PowerPoint layout named across\n * two lines — \"Abschnitts-⏎überschrift\" is a real one, in the German built-in set — comes back\n * with a space either way. Doing it here rather than leaving it to the serializer means the\n * emitted script states the title the output will actually have, and the round trip compares\n * two decks that agree instead of reporting a rename it cannot act on.\n */\nfunction flattenAttributeValue(value: string): string {\n\treturn value.replace(/[\\t\\r\\n]+/g, ' ')\n}\n\n/** A master/layout background reduced to what `BackgroundProps` accepts. */\nfunction backgroundProps(\n\tbackground: SlideBackground | null,\n\tnotes: NoteScope,\n\tassets: AssetResolver\n): IrValue | undefined {\n\tif (!background || background.type === 'none') return undefined\n\n\tswitch (background.type) {\n\t\tcase 'solid':\n\t\t\treturn background.color ? { color: literalColor(background.color.effectiveHex) } : undefined\n\t\tcase 'image': {\n\t\t\tconst asset = background.partName === null ? null : assets.assetFor(background.partName)\n\t\t\treturn asset ? { data: asset } : undefined\n\t\t}\n\t\tcase 'themeRef': {\n\t\t\t// `p:bgRef` indexes the theme's background fill list, which the write path cannot\n\t\t\t// author. The read model resolves it, so the flat colour survives even though the\n\t\t\t// reference — and therefore its response to a theme change — does not.\n\t\t\tconst fill = background.resolvedFill\n\t\t\tif (fill?.type === 'solid' && fill.color) {\n\t\t\t\tnotes.note(\n\t\t\t\t\t'master.background',\n\t\t\t\t\t'flattened',\n\t\t\t\t\t'unwritable',\n\t\t\t\t\t\"this layout's background is a theme reference (p:bgRef into the theme's background fill list), which has no write-API option; the colour it currently resolves to is baked in and stops following the theme\"\n\t\t\t\t)\n\t\t\t\treturn { color: literalColor(fill.color.effectiveHex) }\n\t\t\t}\n\t\t\tnotes.note(\n\t\t\t\t'master.background',\n\t\t\t\t'dropped',\n\t\t\t\t'unwritable',\n\t\t\t\t\"this layout's background is a theme reference to a non-solid fill, which has no write-API option; the layout is emitted with no background\"\n\t\t\t)\n\t\t\treturn undefined\n\t\t}\n\t\tdefault:\n\t\t\tnotes.note(\n\t\t\t\t'master.background',\n\t\t\t\t'dropped',\n\t\t\t\t'unsupported',\n\t\t\t\t`a ${background.type} layout background is not expressible through the write API's background option, so the layout is emitted with no background`\n\t\t\t)\n\t\t\treturn undefined\n\t}\n}\n","/**\n * `a:blipFill` on a *surface* → the write API's `fill: { type: 'image', image: { data } }`.\n *\n * Shared by a shape's fill and a table cell's, which are the same construct read from two\n * containers: `TableCellProps.fill` and `ShapeProps.fill` are both `ShapeFillProps`, so\n * the mapping is identical and only the note wording differs. Keeping one implementation\n * is what stops the two drifting into different answers for the same `a:blipFill`.\n *\n * The bytes and the blip's opacity carry. Nothing else does, and that is a property of the\n * write path rather than of this mapper: `genXmlImageFill` emits every picture fill as\n * `<a:blipFill dpi=\"0\" rotWithShape=\"1\">…<a:srcRect/><a:stretch><a:fillRect/></a:stretch>`,\n * so a tiled fill comes back stretched and a cropped one comes back whole. That is a\n * visible change, so it is noted when — and only when — the source actually uses it.\n */\nimport type { FillRect, PictureFill } from '../../read/api/picture-fill.js'\nimport type { NoteScope } from '../fidelity.js'\nimport type { AssetRef, IrValue } from '../ir.js'\nimport type { AssetResolver } from './shape.js'\nimport { alphaToTransparency, compactRequired } from './values.js'\n\n/** How a note names the surface it is about; the mapping itself does not vary. */\nexport interface PictureFillSubject {\n\t/** Note construct for a fill whose bytes cannot be carried at all. */\n\tconstruct: string\n\t/** The surface as a note's detail names it — \"this shape's surface\", \"this table cell\". */\n\tsubject: string\n\t/** Where the fill sits in the source XML, for a note's detail. */\n\telement: string\n}\n\n/**\n * A picture fill as `ShapeFillProps`, or `undefined` when its bytes cannot be carried —\n * in which case a `dropped` note has been recorded and the surface comes out unfilled.\n */\nexport function pictureFillOption(\n\tpicture: PictureFill,\n\tassets: AssetResolver,\n\tnotes: NoteScope,\n\tsubject: PictureFillSubject\n): IrValue | undefined {\n\tconst asset = pictureAsset(picture, assets, notes, subject)\n\tif (!asset) return undefined\n\n\tnoteUncarriedGeometry(picture, notes, subject)\n\n\treturn compactRequired({\n\t\ttype: 'image',\n\t\timage: { data: asset },\n\t\t// Fully opaque passes as `undefined` rather than `0`; see `alphaToTransparency`.\n\t\ttransparency: picture.alpha === 1 ? undefined : alphaToTransparency(picture.alpha),\n\t})\n}\n\n/** The fill's image as an asset, or `null` with a note saying why it could not be one. */\nfunction pictureAsset(\n\tpicture: PictureFill,\n\tassets: AssetResolver,\n\tnotes: NoteScope,\n\tsubject: PictureFillSubject\n): AssetRef | null {\n\tconst partName = picture.partName\n\tif (partName === null) {\n\t\tnotes.note(\n\t\t\tsubject.construct,\n\t\t\t'dropped',\n\t\t\t'unsupported',\n\t\t\t`${subject.subject} is filled with an image (${subject.element}) that embeds no image part — an external or linked blip — so there are no bytes to carry and it comes out unfilled`\n\t\t)\n\t\treturn null\n\t}\n\n\t// The write path refuses an SVG picture fill outright (`src/gen/define/image.ts` warns\n\t// and falls back to `type: 'none'`), so emitting one would produce a script that paints\n\t// nothing while claiming a fill. Checked *before* `assetFor`, which would otherwise\n\t// register bytes that no call ends up referencing.\n\tif (assets.contentTypeOf(partName) === 'image/svg+xml') {\n\t\tnotes.note(\n\t\t\tsubject.construct,\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t`${subject.subject} is filled with an SVG image (${subject.element} → ${partName}); a picture fill accepts raster bytes only on the write side, so it comes out unfilled`\n\t\t)\n\t\treturn null\n\t}\n\n\tconst asset = assets.assetFor(partName)\n\tif (!asset) {\n\t\tnotes.note(\n\t\t\tsubject.construct,\n\t\t\t'dropped',\n\t\t\t'unsupported',\n\t\t\t`the image filling ${subject.subject} (${subject.element} → ${partName}) is not present in the package, so there are no bytes to carry`\n\t\t)\n\t\treturn null\n\t}\n\treturn asset\n}\n\n/** `true` when a rect actually insets an edge; an explicit but empty rect reports zeros. */\nfunction isRectSet(rect: FillRect | null): boolean {\n\treturn rect !== null && (rect.left !== 0 || rect.top !== 0 || rect.right !== 0 || rect.bottom !== 0)\n}\n\n/**\n * Note the parts of the fill's geometry the write path's fixed stretch cannot express.\n *\n * Only the ones the source actually uses: a note on every picture fill would say nothing,\n * and the round-trip check reads an unmatched note as a candidate for review.\n */\nfunction noteUncarriedGeometry(picture: PictureFill, notes: NoteScope, subject: PictureFillSubject): void {\n\tconst lost: string[] = []\n\tif (picture.mode === 'tile' || picture.tile !== null) lost.push('tiling (a:tile)')\n\tif (isRectSet(picture.srcRect)) lost.push('the source crop (a:srcRect)')\n\tif (isRectSet(picture.fillRect)) lost.push('the destination inset (a:stretch/a:fillRect)')\n\tif (picture.dpi !== null && picture.dpi !== 0) lost.push(`the render resolution (@dpi=\"${picture.dpi}\")`)\n\t// Only the explicit `0`. Unset means \"whatever the application defaults to\", which is\n\t// not a claim this note can make about a difference.\n\tif (picture.rotWithShape === false) lost.push('not rotating with the shape (@rotWithShape=\"0\")')\n\tif (lost.length === 0) return\n\n\tnotes.note(\n\t\t`${subject.construct}.geometry`,\n\t\t'approximated',\n\t\t'unwritable',\n\t\t`the image filling ${subject.subject} is re-embedded, but the write path emits every picture fill as a plain stretched blip (dpi=\"0\" rotWithShape=\"1\", <a:srcRect/><a:stretch><a:fillRect/></a:stretch>), so ${lost.join(', ')} ${lost.length === 1 ? 'does' : 'do'} not carry`\n\t)\n}\n","/**\n * `TextFrame` → `addText(TextProps[], TextPropsOptions)`.\n *\n * Two structural mismatches shape this mapper, and both are why the conversion is not a\n * field-by-field copy:\n *\n * 1. **The read model is a tree; `addText` takes a flat list.** OOXML nests runs inside\n * paragraphs; `TextProps[]` is one flat array where a paragraph boundary is a\n * `breakLine` flag on the item that *precedes* it. So the last run of each paragraph\n * carries the break, and a paragraph's own properties are replicated onto each of its\n * runs — the write path reads alignment and spacing off whichever run starts a line.\n *\n * 2. **Vocabularies differ on both sides of the same concept.** OOXML spells alignment\n * `l`/`ctr`/`r`/`just`, the write API spells it `left`/`center`/`right`/`justify`; two\n * of the six `@algn` values have no write spelling at all. Every such translation is a\n * table here rather than a pass-through, so an unmappable token produces a note instead\n * of an invalid option.\n *\n * Run-level reads prefer the *explicit* value over the resolved one, but only where leaving\n * the option out really does leave the value inherited. That is the part worth checking\n * rather than assuming: the round-trip harness found that an omitted run colour and an\n * omitted vertical anchor are both filled in by the write path — black, and centred — so\n * \"stay quiet and let it inherit\" was silently repainting text and re-anchoring bodies. Both\n * now emit the *resolved* value with a note, which freezes it against a later theme edit and\n * renders correctly, in preference to staying faithful in the IR and wrong on the slide.\n */\nimport type { BodyProperties, Paragraph, Run, TextFrame } from '../../read/api/text.js'\nimport type { NoteScope } from '../fidelity.js'\nimport type { IrValue } from '../ir.js'\nimport { compact, isWritableSchemeToken, literalColor, orUndefined, pointsToInches } from './values.js'\n\n/**\n * `a:pPr/@algn` → `HAlign`. `dist` and `thaiDist` (distributed justification) are\n * deliberately absent: the write API has no spelling for them, and mapping them onto\n * `justify` would be a silent visual change rather than a declared loss.\n */\nconst ALIGN: Record<string, string> = { l: 'left', ctr: 'center', r: 'right', just: 'justify' }\n\n/** `a:bodyPr/@anchor` → `VAlign`. */\nconst ANCHOR: Record<string, string> = { t: 'top', ctr: 'middle', b: 'bottom' }\n\n/** `AutofitMode` → the write API's `fit`. */\nconst FIT: Record<string, string> = { none: 'none', normAutofit: 'shrink', spAutoFit: 'resize' }\n\n/** `a:bodyPr/@vert` values the write API's `vert` accepts (`TextVertType`). */\nconst WRITABLE_VERT = new Set(['eaVert', 'horz', 'mongolianVert', 'vert', 'vert270', 'wordArtVert', 'wordArtVertRtl'])\n\n/**\n * `a:buAutoNum/@type` values, used to tell a numbered bullet from a character bullet.\n * The read model reports both as a single string — the character for `a:buChar`, the\n * `@type` token for `a:buAutoNum` — so membership here is the only discriminator.\n */\nconst AUTO_NUMBER_TYPES = new Set([\n\t'alphaLcParenBoth',\n\t'alphaLcParenR',\n\t'alphaLcPeriod',\n\t'alphaUcParenBoth',\n\t'alphaUcParenR',\n\t'alphaUcPeriod',\n\t'arabicParenBoth',\n\t'arabicParenR',\n\t'arabicPeriod',\n\t'arabicPlain',\n\t'romanLcParenBoth',\n\t'romanLcParenR',\n\t'romanLcPeriod',\n\t'romanUcParenBoth',\n\t'romanUcParenR',\n\t'romanUcPeriod',\n])\n\n/**\n * `Paragraph.bullet` → the write API's `bullet` option.\n *\n * The read model reports a **tagged** string — `'none'`, `'char:<glyph>'` or\n * `'autoNum:<type>'` — not a bare glyph, and the first version of this function read it as\n * one. The result was silent and universal: a paragraph that explicitly suppressed its\n * bullet (`a:buNone`, which is most of them) came back with a literal `n` bullet, because\n * `'none'.codePointAt(0)` is `n`; a real character bullet came back as `c`, from the `char:`\n * tag; and a numbered list came back as `a`. Every converted deck was affected and nothing\n * failed, which is why the round-trip check exists.\n */\nfunction bulletOption(bullet: string, notes: NoteScope): IrValue {\n\t// Explicit suppression, and it must stay explicit: an omitted `bullet` lets the\n\t// destination list style put one back.\n\tif (bullet === 'none') return false\n\n\tnotes.note(\n\t\t'text.bullet.style',\n\t\t'flattened',\n\t\t'unread',\n\t\t\"a bullet's own font, size and colour have no accessor (a:buFont / a:buSzPct / a:buClr), so it renders in the body font and colour\"\n\t)\n\n\tif (bullet.startsWith('autoNum:')) {\n\t\tconst scheme = bullet.slice('autoNum:'.length)\n\t\tnotes.note(\n\t\t\t'text.bullet.numberStartAt',\n\t\t\t'dropped',\n\t\t\t'unread',\n\t\t\t'a numbered bullet restarts at 1: nothing reads a:buAutoNum/@startAt, though addText accepts numberStartAt'\n\t\t)\n\t\tif (!AUTO_NUMBER_TYPES.has(scheme)) {\n\t\t\tnotes.note(\n\t\t\t\t'text.bullet.numberType',\n\t\t\t\t'approximated',\n\t\t\t\t'unwritable',\n\t\t\t\t`numbering scheme \"${scheme}\" is outside the set the write API names, so the list falls back to the default scheme`\n\t\t\t)\n\t\t\treturn { type: 'number' }\n\t\t}\n\t\treturn { type: 'number', numberType: scheme }\n\t}\n\n\t// Zero-padded to four digits, and that is load-bearing rather than cosmetic: the write\n\t// path tests `characterCode` against /^[0-9A-Fa-f]{4}$/ and, on a miss, warns to the\n\t// console and substitutes its own default glyph. So \"6E\" — a perfectly good code point —\n\t// silently became a different bullet character, visible only in the rendered slide.\n\tconst glyph = bullet.startsWith('char:') ? bullet.slice('char:'.length) : bullet\n\tconst code = glyph.codePointAt(0) ?? 0x2022\n\tif (code > 0xffff) {\n\t\tnotes.note(\n\t\t\t'text.bullet.glyph',\n\t\t\t'approximated',\n\t\t\t'unwritable',\n\t\t\t`bullet glyph U+${code.toString(16).toUpperCase()} is outside the Basic Multilingual Plane and characterCode takes a four-digit code, so the bullet falls back to the write path's default glyph`\n\t\t)\n\t}\n\treturn { characterCode: code.toString(16).toUpperCase().padStart(4, '0') }\n}\n\n/** Per-run character formatting, shared by shape text and table-cell text. */\nexport function runOptions(run: Run, notes: NoteScope): Record<string, IrValue> | undefined {\n\tconst underline = run.underline\n\tconst strike = run.strike\n\tconst caps = run.caps\n\n\treturn compact({\n\t\tbold: orUndefined(run.bold),\n\t\titalic: orUndefined(run.italic),\n\t\tunderline: underline === null || underline === 'none' ? undefined : { style: underline },\n\t\tstrike: strike === null || strike === 'noStrike' ? undefined : strike,\n\t\tfontSize: orUndefined(run.fontSizePt),\n\t\tfontFace: orUndefined(run.fontName),\n\t\tcolor: runColor(run, notes),\n\t\thighlight: run.highlight ? literalColor(run.highlight.effectiveHex) : undefined,\n\t\tcaps: caps === null || caps === 'none' ? undefined : caps,\n\t\t// The write API spells baseline shift as a percentage, the same unit the read\n\t\t// model reports, so superscript/subscript survive without a preset round-trip.\n\t\tbaseline: orUndefined(run.baselinePct),\n\t\thyperlink: hyperlinkOption(run),\n\t})\n}\n\n/**\n * A run's colour, preferring the raw `schemeClr` token over the resolved literal so the\n * text keeps tracking the destination theme. Only the ten tokens the write path's `clrMap`\n * covers survive as tokens; the other seven degrade to a literal hex there anyway, so\n * passing one through unchanged would produce a silently different colour.\n */\nfunction runColor(run: Run, notes: NoteScope): string | undefined {\n\tconst scheme = run.schemeColor\n\tif (isWritableSchemeToken(scheme)) return scheme as string\n\tif (scheme !== null) {\n\t\tnotes.note(\n\t\t\t'text.color.schemeToken',\n\t\t\t'approximated',\n\t\t\t'unwritable',\n\t\t\t`scheme colour \"${scheme}\" is outside the ten tokens the write path maps, so it is baked to a literal hex and stops tracking the theme`\n\t\t)\n\t\tconst resolved = run.resolvedColor\n\t\treturn resolved ? literalColor(resolved.effectiveHex) : undefined\n\t}\n\tif (run.color !== null) return literalColor(run.color)\n\n\t// A run with no colour of its own inherits one, and leaving the option out does *not* pass\n\t// that inheritance along: `addText` fills an uncoloured non-placeholder run with\n\t// DEF_FONT_COLOR, so omitting it repaints the text black. That makes this a loss either\n\t// way, and which loss depends on whether the inherited colour can be resolved — so the two\n\t// outcomes are declared separately rather than under one note that would overstate one and\n\t// understate the other.\n\tconst inherited = run.resolvedColor\n\tif (!inherited) {\n\t\tnotes.note(\n\t\t\t'text.color.default',\n\t\t\t'approximated',\n\t\t\t'unread',\n\t\t\t'this run inherits its colour and nothing resolves what it inherits (a table style tier, or a list style the read model does not walk), so the write path paints it black — the one case where the output colour is not merely frozen but possibly wrong'\n\t\t)\n\t\treturn undefined\n\t}\n\tnotes.note(\n\t\t'text.color.inherited',\n\t\t'flattened',\n\t\t'unsupported',\n\t\t'this run inherits its colour from the placeholder, master or theme; the write path paints an uncoloured run black instead of leaving it to inherit, so the inherited colour is resolved and baked in and no longer tracks a theme change'\n\t)\n\treturn literalColor(inherited.effectiveHex)\n}\n\n/**\n * A run's hyperlink. Only external links map: the read model reports an internal jump as a\n * target part name, while the write API takes a slide *number*, which the deck-level walk\n * resolves — so a slide link is handled there, not here.\n */\nfunction hyperlinkOption(run: Run): IrValue | undefined {\n\tconst link = run.hyperlink\n\tif (!link?.url) return undefined\n\treturn compact({ url: link.url, tooltip: link.tooltip ?? undefined })\n}\n\n/** Paragraph-level properties, replicated onto each of the paragraph's runs. */\nfunction paragraphOptions(paragraph: Paragraph, notes: NoteScope): Record<string, IrValue> {\n\tconst spacing = paragraph.lineSpacing\n\tconst bullet = paragraph.bullet\n\tconst align = paragraph.align\n\n\tif (align !== null && !(align in ALIGN)) {\n\t\tnotes.note(\n\t\t\t'text.align',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t`distributed alignment \"${align}\" has no write-API spelling, so the paragraph falls back to its inherited alignment`\n\t\t)\n\t}\n\tif (paragraph.spaceBeforePt === 0 || paragraph.spaceAfterPt === 0) {\n\t\tnotes.note(\n\t\t\t'text.paraSpaceZero',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t'this paragraph explicitly sets zero space before or after (a:spcBef / a:spcAft of 0), which suppresses the spacing its list style would otherwise apply; the write path treats 0 as \"unset\" and emits nothing, so the inherited spacing comes back'\n\t\t)\n\t}\n\tif (paragraph.marginLeftPt !== null || paragraph.indentPt !== null) {\n\t\tnotes.note(\n\t\t\t'text.indent',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t\"a paragraph's own indent (a:pPr/@marL, @indent) is not expressible; only the discrete indentLevel is, so hanging indents flatten to the level default\"\n\t\t)\n\t}\n\n\treturn (\n\t\tcompact({\n\t\t\talign: align === null ? undefined : ALIGN[align],\n\t\t\tindentLevel: paragraph.level === 0 ? undefined : paragraph.level,\n\t\t\tparaSpaceBefore: orUndefined(paragraph.spaceBeforePt),\n\t\t\tparaSpaceAfter: orUndefined(paragraph.spaceAfterPt),\n\t\t\tlineSpacing: spacing?.type === 'points' ? spacing.valuePt : undefined,\n\t\t\tlineSpacingMultiple: spacing?.type === 'percent' ? spacing.percent / 100 : undefined,\n\t\t\tbullet: bullet === null ? undefined : bulletOption(bullet, notes),\n\t\t}) ?? {}\n\t)\n}\n\n/**\n * Record the one bullet loss that has no expression at all, once per shape.\n *\n * A paragraph with no bullet child of its own inherits whatever the layout's or master's\n * list style says. There is no way to say \"inherit\" through the write API — an omitted\n * `bullet` makes it emit an explicit `a:buNone` — so an inherited bullet is suppressed. The\n * read side cannot see the inherited value either (`a:lvl1pPr` list styles are unread), so\n * the converter can neither reproduce it nor tell whether there was one, which is why this\n * is stated as a possibility rather than a fact.\n */\nfunction noteInheritedBullets(paragraphs: readonly Paragraph[], notes: NoteScope): void {\n\tif (!paragraphs.some((paragraph) => paragraph.bullet === null)) return\n\tnotes.note(\n\t\t'text.bullet.inherited',\n\t\t'dropped',\n\t\t'unread',\n\t\t'at least one paragraph sets no bullet of its own and inherits one from the layout or master list style; the write path cannot express \"inherit\" and emits an explicit a:buNone, so any inherited bullet is suppressed — a no-op where the inherited style had none, and a visible change where it did not'\n\t)\n}\n\n/**\n * Flatten a text frame into the `TextProps[]` first argument of `addText`.\n *\n * An empty paragraph becomes an item with empty text and a `breakLine`, which is how a\n * blank line survives — dropping it would silently close up vertical space the author put\n * there deliberately.\n */\nexport function textRuns(frame: TextFrame, notes: NoteScope): IrValue[] {\n\tconst paragraphs = frame.paragraphs\n\tconst items: IrValue[] = []\n\tnoteInheritedBullets(paragraphs, notes)\n\n\tparagraphs.forEach((paragraph, paragraphIndex) => {\n\t\tconst paraOpts = paragraphOptions(paragraph, notes)\n\t\tconst runs = paragraph.runs\n\t\t// The paragraph break rides on the last run of every paragraph but the final one;\n\t\t// a trailing break would add an empty line the frame never had.\n\t\tconst breaks = paragraphIndex < paragraphs.length - 1\n\n\t\tif (runs.length === 0) {\n\t\t\titems.push({ text: '', options: compact({ ...paraOpts, breakLine: breaks }) ?? {} })\n\t\t\treturn\n\t\t}\n\n\t\truns.forEach((run, runIndex) => {\n\t\t\tconst isLastRun = runIndex === runs.length - 1\n\t\t\t// `bullet` goes on the first run only, unlike the other paragraph properties. The\n\t\t\t// write path treats a bullet on a run that is *not* starting a line as a request for\n\t\t\t// a new paragraph — and clears that run's `breakLine` while it is at it — so\n\t\t\t// replicating the bullet split every bulleted paragraph that had more than one run.\n\t\t\t// It reads paragraph properties off whichever run opens the line, so once is enough.\n\t\t\tconst continuation = { ...paraOpts }\n\t\t\tdelete continuation['bullet']\n\t\t\tconst options = compact({\n\t\t\t\t...(runIndex === 0 ? paraOpts : continuation),\n\t\t\t\t...runOptions(run, notes),\n\t\t\t\t...(isLastRun && breaks ? { breakLine: true } : {}),\n\t\t\t})\n\t\t\titems.push(compact({ text: run.text, options }) ?? { text: run.text })\n\t\t})\n\t})\n\n\treturn items\n}\n\n/**\n * Frame-level layout for the `TextPropsOptions` second argument — everything that belongs\n * to the body as a whole rather than to any paragraph.\n *\n * `resolvedAnchor` is the one place a *resolved* read is the right one: vertical anchoring\n * has no per-run fallback, so an unset `a:bodyPr/@anchor` genuinely means \"whatever the\n * placeholder says\", and an appended shape does not inherit that.\n */\nexport function textFrameOptions(frame: TextFrame, notes: NoteScope): Record<string, IrValue> {\n\tconst body = frame.bodyProperties\n\tconst autofit = frame.autofit\n\tconst anchor = frame.resolvedAnchor\n\tconst vert = body?.vert ?? null\n\n\tif (vert !== null && !WRITABLE_VERT.has(vert)) {\n\t\tnotes.note(\n\t\t\t'text.vert',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t`text direction \"${vert}\" is outside TextVertType, so the body falls back to horizontal`\n\t\t)\n\t}\n\n\treturn (\n\t\tcompact({\n\t\t\t// Spelled out even when nothing in the source set it. `resolvedAnchor` returning\n\t\t\t// null means PowerPoint would default the body to top — but `addText` defaults a\n\t\t\t// non-placeholder body to *centre*, so leaving the option out re-anchors the text.\n\t\t\tvalign: anchor === null ? 'top' : ANCHOR[anchor],\n\t\t\t// `@wrap` is `square`/`none` in OOXML and a boolean in the write API.\n\t\t\twrap: body?.wrap === null || body?.wrap === undefined ? undefined : body.wrap !== 'none',\n\t\t\tvert: vert !== null && WRITABLE_VERT.has(vert) ? vert : undefined,\n\t\t\tfit: autofit === null ? undefined : FIT[autofit],\n\t\t\tmargin: marginOption(body),\n\t\t}) ?? {}\n\t)\n}\n\n/**\n * `a:bodyPr` insets as the write API's `margin`.\n *\n * A unit change, not just a copy: the read model reports insets in points, `margin` takes\n * **inches**, and it warns on any value `>= 1` on the assumption it is a stray points\n * value. Passing points straight through would therefore both inset the text by roughly\n * 72× too much and trip that warning.\n *\n * Emitted as the four-tuple whenever any inset is set, since a partial tuple is not\n * expressible; an unset side takes PowerPoint's own default rather than zero, so those are\n * spelled out — defaulting them to 0 would visibly reflow every body that sets one side.\n */\nconst DEFAULT_INSETS_PT = { left: 7.2, right: 7.2, top: 3.6, bottom: 3.6 }\n\nfunction marginOption(body: BodyProperties | null): IrValue | undefined {\n\tconst insets = body?.insetsPt\n\tif (!insets) return undefined\n\tconst { left, right, top, bottom } = insets\n\tif (left === undefined && right === undefined && top === undefined && bottom === undefined) return undefined\n\treturn [\n\t\tpointsToInches(top ?? DEFAULT_INSETS_PT.top),\n\t\tpointsToInches(right ?? DEFAULT_INSETS_PT.right),\n\t\tpointsToInches(bottom ?? DEFAULT_INSETS_PT.bottom),\n\t\tpointsToInches(left ?? DEFAULT_INSETS_PT.left),\n\t]\n}\n","/**\n * `Table` → `addTable(TableRow[], TableProps)`.\n *\n * Tables are the one place the exact-EMU rule stops. `colW` and `rowH` are number-typed\n * (inches) rather than `Coord`-typed, so they cannot take a raw-EMU string the way every\n * position and size can. They print at six decimal places, which is the measured minimum\n * at which `Math.round(inches × 914400)` returns the original EMU — the drift is bounded\n * at 0.4572 EMU, roughly half a millionth of an inch, and rounding shorter to make the\n * numbers look tidy would turn a cosmetic problem into a real geometry loss.\n *\n * Table *style* is the opposite story, and better than it looks. A style is a GUID into\n * the deck's `ppt/tableStyles.xml`, and a template-anchored output keeps that part intact,\n * so passing the source GUID through reproduces the banding, header shading, and borders\n * exactly rather than approximately. That is why per-cell fills read off the style graph\n * are deliberately *not* baked into each cell here: doing so would freeze the appearance\n * and stop the table responding to its own style.\n */\nimport type { Table, TableCell } from '../../read/api/table.js'\nimport type { GraphicFrame } from '../../read/api/shapes.js'\nimport type { NoteScope } from '../fidelity.js'\nimport type { CallIr, IrValue } from '../ir.js'\nimport type { AssetResolver } from './shape.js'\nimport { compact, emu, inches, literalColor, orUndefined } from './values.js'\nimport { pictureFillOption, type PictureFillSubject } from './picture-fill.js'\nimport { runOptions, textRuns } from './text.js'\n\n/** How {@link pictureFillOption}'s notes name a cell. */\nconst CELL_PICTURE_FILL: PictureFillSubject = {\n\tconstruct: 'table.cell.fill.picture',\n\tsubject: 'this table cell',\n\telement: 'a:tcPr/a:blipFill',\n}\n\n/** `a:tcPr/@anchor` → the write API's `valign`. */\nconst ANCHOR: Record<string, string> = { t: 'top', ctr: 'middle', b: 'bottom' }\n\nexport function tableCall(frame: GraphicFrame, table: Table, notes: NoteScope, assets: AssetResolver): CallIr {\n\tconst styleId = table.styleId\n\tconst hasStyle = table.resolvedStyle !== null\n\tconst rows: IrValue[] = []\n\tconst rowHeights: number[] = []\n\n\tfor (const row of table.rows) {\n\t\tconst cells: IrValue[] = []\n\t\tfor (const cell of row.cells) {\n\t\t\t// A merge continuation is the covered half of a span: it carries no content and\n\t\t\t// exists only so the grid stays rectangular. The write path derives those from\n\t\t\t// colspan/rowspan, so emitting them would double-count the span.\n\t\t\tif (cell.isMergeContinuation) continue\n\t\t\tcells.push(cellIr(cell, hasStyle, notes, assets))\n\t\t}\n\t\trows.push(cells)\n\t\trowHeights.push(row.heightEmu ?? 0)\n\t}\n\n\t// A row of height 0 is PowerPoint's \"auto — as tall as its content needs\", not a\n\t// zero-height row. The write path takes it literally and then lets the row grow anyway,\n\t// so the output reports whatever height the content forced. Nothing is visibly wrong;\n\t// the row simply stops being auto and is pinned to that measurement.\n\tif (rowHeights.some((height) => height === 0) && !rowHeights.every((height) => height === 0)) {\n\t\tnotes.note(\n\t\t\t'table.rowAuto',\n\t\t\t'approximated',\n\t\t\t'unsupported',\n\t\t\t'at least one row is auto-height (a:tr/@h of 0) while others are not; rowH must be given for every row or none, so the auto rows are emitted as 0 and come back pinned to the height their content produced'\n\t\t)\n\t}\n\n\tif (styleId === null) {\n\t\tnotes.note(\n\t\t\t'table.style',\n\t\t\t'dropped',\n\t\t\t'unsupported',\n\t\t\t\"this table names no a:tableStyleId, so it takes the generated deck's default table style\"\n\t\t)\n\t}\n\n\tconst columnWidths = table.columnWidths\n\tconst options = compact({\n\t\t...positionOfFrame(frame),\n\t\tobjectName: frame.name || undefined,\n\t\t// The source GUID resolves against the destination's own tableStyles.xml, which a\n\t\t// template-anchored output carries over intact.\n\t\ttableStyle: orUndefined(styleId),\n\t\thasHeader: table.firstRowHeader ? true : undefined,\n\t\thasBandedRows: table.bandedRows ? true : undefined,\n\t\tcolW: columnWidths.every((w) => w === null) ? undefined : columnWidths.map((w) => inches(w ?? 0)),\n\t\trowH: rowHeights.every((h) => h === 0) ? undefined : rowHeights.map(inches),\n\t})\n\n\treturn { method: 'addTable', args: [rows, options ?? {}], ...(frame.name ? { sourceName: frame.name } : {}) }\n}\n\n/** A graphic frame's position; identical to a shape's, but frames never rotate or flip. */\nfunction positionOfFrame(frame: GraphicFrame): Record<string, IrValue> {\n\tconst box = frame.absoluteFrame\n\tif (!box) return {}\n\treturn { x: emu(box.left), y: emu(box.top), w: emu(box.width), h: emu(box.height) }\n}\n\n/**\n * One cell as a `TableCell`.\n *\n * Cell text reuses the shape text mapper, so a per-run format inside a cell behaves\n * identically to one on a shape — the read model already shares `TextFrame` between the\n * two, and diverging here would be a difference with no cause.\n */\nfunction cellIr(cell: TableCell, hasStyle: boolean, notes: NoteScope, assets: AssetResolver): IrValue {\n\tconst frame = cell.textFrame\n\tconst anchor = cell.anchor\n\tconst margins = cell.marginsEmu\n\n\tif (cell.verticalText !== null) {\n\t\tnotes.note(\n\t\t\t'table.cell.vert',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t'a vertically-written table cell (a:tcPr/@vert) has no write-API option, so its text lands horizontal'\n\t\t)\n\t}\n\n\tconst options = compact({\n\t\tfill: cellFill(cell, hasStyle, notes, assets),\n\t\tborder: cellBorders(cell, notes),\n\t\tvalign: anchor === null ? undefined : ANCHOR[anchor],\n\t\tcolspan: cell.gridSpan > 1 ? cell.gridSpan : undefined,\n\t\trowspan: cell.rowSpan > 1 ? cell.rowSpan : undefined,\n\t\t// `margin` takes inches, and the read model reports the insets in EMU.\n\t\tmargin: margins\n\t\t\t? [inches(margins.top ?? 0), inches(margins.right ?? 0), inches(margins.bottom ?? 0), inches(margins.left ?? 0)]\n\t\t\t: undefined,\n\t\t// A cell's own runs may each carry formatting; the first run's options double as the\n\t\t// cell default, which is how the write path applies cell-level character formatting.\n\t\t...(frame?.paragraphs[0]?.runs[0] ? (runOptions(frame.paragraphs[0].runs[0], notes) ?? {}) : {}),\n\t})\n\n\treturn compact({ text: frame ? textRuns(frame, notes) : cell.text, options }) ?? { text: '' }\n}\n\n/**\n * A cell's fill, and the one place this mapper deliberately emits *less* than it can read.\n *\n * `resolvedFill` folds two different things together: the cell's own `a:solidFill`, and the\n * colour it merely inherits from the table style's header/banding rules. There is no\n * accessor that returns the first without the second. So when the table has a resolvable\n * style, writing `resolvedFill` back would turn every banded cell into an explicitly-filled\n * one — the table would look right until someone changed its style, and then nothing would\n * move. The style GUID reproduces those colours anyway, so only a scheme token (which can\n * only come from the cell itself) is emitted, and the ambiguity is noted.\n *\n * With no style in play, `resolvedFill` can only be the cell's own, so it is safe to use.\n */\nfunction cellFill(cell: TableCell, hasStyle: boolean, notes: NoteScope, assets: AssetResolver): IrValue | undefined {\n\t// A cell's fill is `ShapeFillProps`, the same type a shape's is, so an image-filled cell\n\t// re-embeds its bytes exactly as an image-filled shape does. First, because a cell whose\n\t// `a:tcPr` holds a `a:blipFill` holds no `a:solidFill` for the colour legs to find — and\n\t// `resolvedFill` would answer with the table style's banding colour, painting over the\n\t// image with something the source never showed.\n\tconst picture = cell.pictureFill\n\tif (picture) return pictureFillOption(picture, assets, notes, CELL_PICTURE_FILL)\n\n\tconst scheme = cell.fillSchemeColor\n\tif (scheme !== null) return { color: scheme }\n\n\tconst resolved = cell.resolvedFill\n\tif (!resolved) return undefined\n\tif (hasStyle) {\n\t\tnotes.note(\n\t\t\t'table.cell.fill',\n\t\t\t'dropped',\n\t\t\t'unread',\n\t\t\t\"a cell's own literal fill is not separable from the one it inherits from the table style (only resolvedFill exists, and it folds in banding), so it is left to the style rather than baked in\"\n\t\t)\n\t\treturn undefined\n\t}\n\treturn { color: literalColor(resolved.effectiveHex) }\n}\n\n/**\n * The four edge borders as the write API's `[top, right, bottom, left]` tuple.\n *\n * The read model decodes six edges; the two diagonals have no write-API counterpart. A\n * suppressed edge (`a:noFill`) becomes `type: 'none'`, which is distinct from an absent\n * one — the first means \"deliberately no rule here\", the second means \"inherit\".\n */\nfunction cellBorders(cell: TableCell, notes: NoteScope): IrValue | undefined {\n\tconst borders = cell.borders\n\tif (!borders) return undefined\n\n\tif (borders.tlToBr || borders.blToTr) {\n\t\tnotes.note(\n\t\t\t'table.cell.borders.diagonal',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t'diagonal cell borders (a:lnTlToBr / a:lnBlToTr) have no write-API option; the four edges carry'\n\t\t)\n\t}\n\n\tconst edges = [borders.top, borders.right, borders.bottom, borders.left]\n\tif (edges.every((edge) => edge === null)) return undefined\n\n\treturn edges.map((edge) => {\n\t\tif (!edge) return {}\n\t\tif (edge.noFill) return { type: 'none' }\n\t\treturn (\n\t\t\tcompact({\n\t\t\t\t// `BorderProps.type` admits only solid/dash/none, so every dash variant the read\n\t\t\t\t// model reports collapses onto `dash`.\n\t\t\t\ttype: edge.dash === null || edge.dash === 'solid' ? 'solid' : 'dash',\n\t\t\t\tcolor: edge.schemeColor ?? (edge.color === null ? undefined : literalColor(edge.color)),\n\t\t\t\twidth: orUndefined(edge.widthPt),\n\t\t\t}) ?? {}\n\t\t)\n\t})\n}\n","/**\n * `Chart` → `addChart(OptsChartData[], ChartOpts)`.\n *\n * The open question this mapper settles is where the data comes from. A `.pptx` chart\n * carries its numbers twice: once in an embedded `.xlsx` workbook, and once as *cached*\n * values inside the chart XML itself (`c:tx`, `c:cat`, `c:val`) so a viewer can render\n * without opening the workbook. Probing the fixtures showed the cache is complete for\n * every chart the write API can express, so the workbook never needs cracking — which\n * removes a whole spreadsheet parser from this project's dependency surface.\n *\n * The one seam is blanks. The read model reports `(number | null)[]`, since a cached point\n * may legitimately be empty, while `OptsChartData.values` is `number[]`. A blank becomes\n * `0`, which is a visible change on a line chart — a gap turns into a dip to the axis — so\n * it is noted rather than quietly coerced.\n *\n * A rebuilt chart also gets a *regenerated* workbook rather than the source one, so\n * double-clicking it in PowerPoint opens data that matches the plot but has lost the source\n * sheet's formulas, extra columns, and formatting.\n */\nimport type { Chart } from '../../read/api/chart.js'\nimport type { GraphicFrame } from '../../read/api/shapes.js'\nimport type { NoteScope } from '../fidelity.js'\nimport type { CallIr, IrValue } from '../ir.js'\nimport { compact, emu, literalColor, orUndefined } from './values.js'\n\n/**\n * Read chart-group token → `CHART_NAME`. The read model strips the `Chart` suffix from the\n * plot-area element name, so `c:barChart` arrives as `bar`. A 3-D group maps onto the\n * matching flat type where one exists; anything absent from this table has no write-API\n * chart type and is reported rather than guessed at.\n */\nconst CHART_TYPE: Record<string, string> = {\n\tarea: 'area',\n\tarea3D: 'area',\n\tbar: 'bar',\n\tbar3D: 'bar3D',\n\tbubble: 'bubble',\n\tbubble3D: 'bubble3D',\n\tdoughnut: 'doughnut',\n\tline: 'line',\n\tline3D: 'line',\n\tpie: 'pie',\n\tpie3D: 'pie',\n\tradar: 'radar',\n\tscatter: 'scatter',\n\tstock: 'stock',\n\tsurface: 'surface',\n\tsurface3D: 'surface',\n}\n\n/** `c:legendPos/@val` → the write API's `legendPos`. */\nconst LEGEND_POS: Record<string, string> = { r: 'r', l: 'l', t: 't', b: 'b', tr: 'tr' }\n\nexport function chartCall(frame: GraphicFrame, chart: Chart, notes: NoteScope): CallIr | null {\n\tconst sourceType = chart.chartType\n\tconst type = sourceType === null ? undefined : CHART_TYPE[sourceType]\n\tif (!type) {\n\t\tnotes.note(\n\t\t\t'chart.type',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t`chart type \"${sourceType ?? 'none'}\" has no write-API counterpart, so the chart is omitted`\n\t\t)\n\t\treturn null\n\t}\n\n\tif (chart.chartTypes.length > 1) {\n\t\tnotes.note(\n\t\t\t'chart.combo',\n\t\t\t'flattened',\n\t\t\t'unsupported',\n\t\t\t`a combo chart (${chart.chartTypes.join(' + ')}) is emitted as a single ${type} chart; addChart's multi-type form needs a per-series type the read model does not report`\n\t\t)\n\t}\n\n\tnotes.note(\n\t\t'chart.workbook',\n\t\t'approximated',\n\t\t'unsupported',\n\t\t\"the chart is rebuilt from its cached plot values, so its embedded workbook is regenerated: the plotted numbers match, but the source sheet's formulas, extra columns and formatting are gone\"\n\t)\n\n\tconst data = seriesData(chart, notes)\n\tif (data.length === 0) {\n\t\tnotes.note('chart.data', 'dropped', 'unsupported', 'this chart caches no plottable series values')\n\t\treturn null\n\t}\n\n\t// `type` is an *option*, not a positional argument: the signature is\n\t// `addChart(data, options & { type })`. Passing it separately produces a call that\n\t// typechecks nowhere and throws \"a chart `type` is required\" at run time.\n\tconst options = compact({\n\t\ttype,\n\t\t...positionOfFrame(frame),\n\t\tobjectName: frame.name || undefined,\n\t\t...titleOptions(chart),\n\t\t...legendOptions(chart),\n\t\t...labelOptions(chart),\n\t\t...axisOptions(chart),\n\t\tchartColors: seriesColors(chart),\n\t})\n\n\treturn {\n\t\tmethod: 'addChart',\n\t\targs: [data, options ?? { type }],\n\t\t...(frame.name ? { sourceName: frame.name } : {}),\n\t}\n}\n\n/** A graphic frame's position; frames never rotate or flip. */\nfunction positionOfFrame(frame: GraphicFrame): Record<string, IrValue> {\n\tconst box = frame.absoluteFrame\n\tif (!box) return {}\n\treturn { x: emu(box.left), y: emu(box.top), w: emu(box.width), h: emu(box.height) }\n}\n\n/**\n * Series as `OptsChartData[]`. Category labels ride on the first series, which is the shape\n * `addChart` expects; the read model reports them per-series but they are shared in\n * practice.\n */\nfunction seriesData(chart: Chart, notes: NoteScope): IrValue[] {\n\tconst categories = chart.categories.map((label) => label ?? '')\n\tlet sawBlank = false\n\n\tconst data = chart.series.map((series, index) => {\n\t\tconst values = series.values.map((value) => {\n\t\t\tif (value === null) sawBlank = true\n\t\t\treturn value ?? 0\n\t\t})\n\t\treturn (\n\t\t\tcompact({\n\t\t\t\tname: orUndefined(series.name),\n\t\t\t\tvalues,\n\t\t\t\t// Only the first series carries labels, matching how addChart reads them.\n\t\t\t\tlabels: index === 0 && categories.length > 0 ? categories : undefined,\n\t\t\t}) ?? { values }\n\t\t)\n\t})\n\n\tif (sawBlank) {\n\t\tnotes.note(\n\t\t\t'chart.blanks',\n\t\t\t'approximated',\n\t\t\t'unwritable',\n\t\t\t'a blank cached data point becomes 0, because OptsChartData.values is number[] and has no spelling for a gap; on a line chart this draws a dip to the axis where the source showed a break'\n\t\t)\n\t}\n\treturn data\n}\n\nfunction titleOptions(chart: Chart): Record<string, IrValue | undefined> {\n\tconst title = chart.title\n\treturn title === null ? {} : { showTitle: true, title }\n}\n\nfunction legendOptions(chart: Chart): Record<string, IrValue | undefined> {\n\tconst legend = chart.legend\n\tif (!legend) return { showLegend: false }\n\treturn {\n\t\tshowLegend: true,\n\t\tlegendPos: legend.position === null ? undefined : LEGEND_POS[legend.position],\n\t}\n}\n\nfunction labelOptions(chart: Chart): Record<string, IrValue | undefined> {\n\tconst labels = chart.dataLabels\n\tif (!labels) return {}\n\treturn {\n\t\tshowValue: labels.showValue ?? undefined,\n\t\tshowSerName: labels.showSeriesName ?? undefined,\n\t\tshowCatName: labels.showCategoryName ?? undefined,\n\t\tshowPercent: labels.showPercent ?? undefined,\n\t\tshowLegendKey: labels.showLegendKey ?? undefined,\n\t\tshowLeaderLines: labels.showLeaderLines ?? undefined,\n\t\tdataLabelPosition: orUndefined(labels.position),\n\t\tdataLabelFormatCode: labels.numberFormat?.formatCode ?? undefined,\n\t}\n}\n\n/**\n * Axis bounds, titles and gridlines. The write API spells these as a flat `catAxis*` /\n * `valAxis*` prefix set rather than an axis object, so each side is unpacked by hand.\n */\nfunction axisOptions(chart: Chart): Record<string, IrValue | undefined> {\n\tconst cat = chart.categoryAxis\n\tconst val = chart.valueAxis\n\treturn {\n\t\tcatAxisHidden: cat?.hidden ? true : undefined,\n\t\tcatAxisTitle: cat?.title ?? undefined,\n\t\tvalAxisHidden: val?.hidden ? true : undefined,\n\t\tvalAxisTitle: val?.title ?? undefined,\n\t\tvalAxisMinVal: val?.min ?? undefined,\n\t\tvalAxisMaxVal: val?.max ?? undefined,\n\t\tvalAxisMajorUnit: val?.majorUnit ?? undefined,\n\t\tvalAxisLabelFormatCode: val?.numberFormat?.formatCode ?? undefined,\n\t}\n}\n\n/**\n * Per-series fill colours as `chartColors`, which is positional — entry `n` colours series\n * `n`. A series with no explicit fill takes the theme's accent for its position, which the\n * read model does not resolve, so the whole option is dropped unless every series names a\n * colour; a partial list would silently recolour the unnamed ones.\n */\nfunction seriesColors(chart: Chart): IrValue | undefined {\n\tconst series = chart.series\n\tif (series.length === 0) return undefined\n\tconst colors: string[] = []\n\tfor (const one of series) {\n\t\tconst fill = one.fill\n\t\tconst hex = fill?.color\n\t\tif (!hex) return undefined\n\t\tcolors.push(literalColor(hex))\n\t}\n\treturn colors\n}\n","/**\n * `AnyShape` → one {@link CallIr}.\n *\n * The dispatch is on what the shape *is*, not on what it looks like: an `AutoShape` with a\n * text frame and no geometry is an `addText`, one with geometry is an `addShape` that may\n * also carry text, a `Picture` is an `addImage`, and a `GraphicFrame` delegates to the\n * table or chart mapper. A `GroupShape` recurses.\n *\n * The single most important thing this module does is record what it cannot carry.\n * Measurement against the fixture corpus found the binding constraint is the *read* side,\n * not the write side — several constructs the write API can express have no accessor at\n * all — so a converter that mapped only what it could see would produce clean-looking\n * output with silent visual losses. The clearest is theme-referenced line styling: a shape\n * whose outline comes from `p:style/a:lnRef` reports a colour through `resolvedLine` but\n * reports `null` for width and dash, because there is a resolved-colour path and no\n * resolved-width path. In the corpus that was every such shape, 25 of 25, so a themed 2pt\n * border silently becomes a 1pt default. Each one is noted here rather than quietly thinned.\n */\nimport type {\n\tAnyShape,\n\tAutoShape,\n\tConnector,\n\tCustomGeometry,\n\tGraphicFrame,\n\tGroupShape,\n\tPicture,\n} from '../../read/api/shapes.js'\nimport { isAutoShape, isConnector, isGraphicFrame, isGroupShape, isPicture } from '../../read/api/shapes.js'\nimport type { GradientFill } from '../../read/api/gradient.js'\nimport type { NoteScope } from '../fidelity.js'\nimport type { AssetRef, CallIr, IrValue } from '../ir.js'\nimport { alphaToTransparency, compact, emu, isWritableSchemeToken, literalColor, orUndefined } from './values.js'\nimport { pictureFillOption, type PictureFillSubject } from './picture-fill.js'\nimport { hasEquation, hasIdentityChildSpace, isAudioVideo, isTextBox } from './detect.js'\nimport { textFrameOptions, textRuns } from './text.js'\nimport { tableCall } from './table.js'\nimport { chartCall } from './chart.js'\n\n/** Resolves an image/media part name to bytes the deck-level walk has registered. */\nexport interface AssetResolver {\n\t/** Register a part's bytes and hand back the reference that stands in for them. */\n\tassetFor(partName: string): AssetRef | null\n\t/**\n\t * The part's content type, or `null` when it is not in the package.\n\t *\n\t * Separate from {@link assetFor} because it has to be answerable *without* registering\n\t * anything: a caller that rejects a part on its type (a picture fill's SVG blip, which\n\t * the write path refuses) would otherwise leave bytes in the asset list that no call\n\t * references, and those bytes are emitted as a file next to the script.\n\t */\n\tcontentTypeOf(partName: string): string | null\n}\n\n/** How {@link pictureFillOption}'s notes name a shape's surface. */\nconst SHAPE_PICTURE_FILL: PictureFillSubject = {\n\tconstruct: 'fill.picture',\n\tsubject: \"this shape's surface\",\n\telement: 'a:blipFill',\n}\n\n/** Arrowhead types `ShapeLineProps` accepts; `a:headEnd/@type` uses the same tokens. */\nconst WRITABLE_ARROWS = new Set(['none', 'arrow', 'diamond', 'oval', 'stealth', 'triangle'])\n\n/** Dash tokens `ShapeLineProps.dashType` accepts. */\nconst WRITABLE_DASHES = new Set([\n\t'solid',\n\t'dash',\n\t'dashDot',\n\t'lgDash',\n\t'lgDashDot',\n\t'lgDashDotDot',\n\t'sysDash',\n\t'sysDot',\n])\n\n/**\n * Map one shape. Returns `null` when the shape produces no call at all — a note is always\n * recorded in that case, so a dropped shape is never silent.\n */\nexport function shapeCall(shape: AnyShape, notes: NoteScope, assets: AssetResolver): CallIr | null {\n\tconst scoped = notes.forShape(shape.name || null)\n\n\tif (shape.hidden) {\n\t\t// `p:cNvPr/@hidden` has no write-API counterpart, so a hidden shape would come back\n\t\t// visible. Omitting it preserves what the deck looks like, which is the lesser loss.\n\t\tscoped.note(\n\t\t\t'shape.hidden',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t'a hidden shape has no write-API expression; it is omitted rather than emitted visible'\n\t\t)\n\t\treturn null\n\t}\n\n\tif (isGroupShape(shape)) return groupCall(shape, scoped, assets)\n\tif (isPicture(shape)) return pictureCall(shape, scoped, assets)\n\tif (isConnector(shape)) return connectorCall(shape, scoped)\n\tif (isGraphicFrame(shape)) return graphicFrameCall(shape, scoped, assets)\n\tif (isAutoShape(shape)) return autoShapeCall(shape, scoped, assets)\n\n\t// Unreachable: the five guards above exhaust `AnyShape`, which is why `shape` narrows to\n\t// `never` here. Left as a floor so a sixth shape kind fails to compile at the call sites\n\t// that assume a call, rather than silently falling through to a silent drop.\n\treturn null\n}\n\n/* ===== position, fill, line, effects — shared by every shape kind ===== */\n\n/**\n * Position as `Coord`-typed EMU strings, so the source geometry survives exactly.\n *\n * `absoluteFrame` rather than the raw `left`/`top`: a shape inside a group is positioned in\n * its group's child coordinate space, which a flattened call list cannot express, so the\n * group transform has to be composed in here. For a top-level shape the two are identical.\n */\nfunction positionOptions(shape: AnyShape, notes?: NoteScope): Record<string, IrValue> {\n\tconst frame = shape.absoluteFrame\n\tif (frame) return { x: emu(frame.left), y: emu(frame.top), w: emu(frame.width), h: emu(frame.height) }\n\n\t// No transform of its own — a placeholder taking its geometry from the layout or master.\n\t// `resolvedFrame` walks that chain, and using it is not optional: omitting the geometry\n\t// does *not* leave it to be inherited, because a regenerated slide's placeholder inherits\n\t// nothing. It produces `x=0 y=0 w=<slide width> h=0` — a zero-height box in the corner,\n\t// which is broken output rather than lossy output.\n\tconst resolved = shape.resolvedFrame\n\tif (!resolved) return {}\n\tnotes?.note(\n\t\t'shape.frameInherited',\n\t\t'flattened',\n\t\t'unsupported',\n\t\t`this shape has no transform of its own and takes its geometry from the ${resolved.source}; a regenerated slide inherits nothing, so the resolved position is baked in and stops tracking later edits to that ${resolved.source}`\n\t)\n\treturn { x: emu(resolved.left), y: emu(resolved.top), w: emu(resolved.width), h: emu(resolved.height) }\n}\n\n/**\n * Rotation and flips. Taken from `absoluteFrame`, which composes enclosing group rotations\n * and XOR-composes group flips — the same reason position is absolute.\n */\nfunction transformOptions(shape: AnyShape): Record<string, IrValue | undefined> {\n\tconst frame = shape.absoluteFrame\n\tconst rotate = frame ? frame.rotation : (shape.rotation ?? 0)\n\treturn {\n\t\trotate: rotate === 0 ? undefined : rotate,\n\t\tflipH: (frame?.flipH ?? shape.flipH) ? true : undefined,\n\t\tflipV: (frame?.flipV ?? shape.flipV) ? true : undefined,\n\t}\n}\n\n/**\n * A shape's fill as `ShapeFillProps`.\n *\n * Prefers the raw scheme token over `resolvedFill` for the same reason run colour does: a\n * token keeps tracking the destination theme. `resolvedFill` is the fallback because it is\n * the only accessor that sees a `p:style/a:fillRef` — a shape styled entirely from the\n * theme has no `a:solidFill` of its own, so without it the shape would come out unfilled.\n */\nfunction fillOption(shape: AnyShape, notes: NoteScope, assets: AssetResolver): IrValue | undefined {\n\tconst gradient = shape.gradientFill\n\tif (gradient) {\n\t\tconst stops = gradientStops(gradient, notes, 'fill')\n\t\tif (stops) return { type: 'gradient', gradient: stops }\n\t}\n\n\tconst pattern = shape.patternFill\n\tif (pattern?.preset) {\n\t\treturn {\n\t\t\ttype: 'pattern',\n\t\t\tpattern: compact({\n\t\t\t\tpreset: pattern.preset,\n\t\t\t\tfgColor: pattern.foreground ? literalColor(pattern.foreground.effectiveHex) : undefined,\n\t\t\t\tbgColor: pattern.background ? literalColor(pattern.background.effectiveHex) : undefined,\n\t\t\t}) ?? { preset: pattern.preset },\n\t\t}\n\t}\n\n\t// An image-filled *surface* is not a picture object — it is `ShapeFillProps.image`, so\n\t// the bytes are re-embedded through the same asset resolver an `addImage` uses. Before\n\t// the fill option itself, since a shape carrying a `a:blipFill` has no `a:solidFill` for\n\t// the colour legs below to find.\n\tconst picture = shape.pictureFill\n\tif (picture) return pictureFillOption(picture, assets, notes, SHAPE_PICTURE_FILL)\n\n\tconst scheme = shape.fillSchemeColor\n\tif (isWritableSchemeToken(scheme)) return { color: scheme as string }\n\tif (shape.fillColor !== null) return { color: literalColor(shape.fillColor) }\n\n\tconst resolved = shape.resolvedFill\n\tif (!resolved) return undefined\n\tif (scheme !== null) {\n\t\tnotes.note(\n\t\t\t'fill.schemeToken',\n\t\t\t'approximated',\n\t\t\t'unwritable',\n\t\t\t`fill scheme colour \"${scheme}\" is outside the ten tokens the write path maps, so it is baked to a literal hex and stops tracking the theme`\n\t\t)\n\t}\n\treturn compact({\n\t\tcolor: literalColor(resolved.effectiveHex),\n\t\ttransparency: alphaToTransparency(resolved.alpha),\n\t})\n}\n\n/**\n * A shape's outline as `ShapeLineProps`.\n *\n * This is where the measured silent loss lives. When a shape takes its outline from\n * `p:style/a:lnRef`, `resolvedLine` supplies the colour but `lineWidthPt` and `lineDash`\n * both report `null` — the theme's `a:lnStyleLst` entry, where the width and dash actually\n * live, has no accessor. Emitting the colour and noting the rest is the honest outcome;\n * inventing a width would be worse, because it would look deliberate.\n */\nfunction lineOption(shape: AnyShape, notes: NoteScope): Record<string, IrValue> | undefined {\n\tif (shape.lineNoFill) return { type: 'none' }\n\n\tconst gradient = shape.lineGradient\n\tif (gradient) {\n\t\tconst stops = gradientStops(gradient, notes, 'line')\n\t\tif (stops) return { type: 'gradient', gradient: stops }\n\t}\n\n\tconst widthPt = shape.lineWidthPt\n\tconst dash = shape.lineDash\n\tconst scheme = shape.lineSchemeColor\n\tconst resolved = shape.resolvedLine\n\n\tlet color: string | undefined\n\tif (isWritableSchemeToken(scheme)) color = scheme as string\n\telse if (shape.lineColor !== null) color = literalColor(shape.lineColor)\n\telse if (resolved) color = literalColor(resolved.effectiveHex)\n\n\t// A colour only `resolvedLine` could supply means the stroke came from the theme style\n\t// list, whose width and dash are unreadable.\n\tif (resolved !== null && shape.lineColor === null && scheme === null && widthPt === null) {\n\t\tnotes.note(\n\t\t\t'line.width',\n\t\t\t'dropped',\n\t\t\t'unread',\n\t\t\t'this outline comes from the theme style list (p:style/a:lnRef); its width and dash live in the theme fmtScheme a:lnStyleLst, which has no accessor, so only the colour carries'\n\t\t)\n\t}\n\tif (dash !== null && !WRITABLE_DASHES.has(dash)) {\n\t\tnotes.note(\n\t\t\t'line.dash',\n\t\t\t'approximated',\n\t\t\t'unwritable',\n\t\t\t`dash style \"${dash}\" is outside the eight the write API accepts, so the outline falls back to solid`\n\t\t)\n\t}\n\n\tconst options = compact({\n\t\tcolor,\n\t\twidth: orUndefined(widthPt),\n\t\tdashType: dash !== null && WRITABLE_DASHES.has(dash) ? dash : undefined,\n\t\ttransparency: alphaToTransparency(resolved?.alpha),\n\t\t...arrowOptions(shape, notes),\n\t})\n\treturn options\n}\n\n/** Arrowheads. Types map directly; the `sm`/`med`/`lg` size classes have no option. */\nfunction arrowOptions(shape: AnyShape, notes: NoteScope): Record<string, IrValue | undefined> {\n\tconst ends = shape.lineEnds\n\tif (!ends) return {}\n\tconst sized = [ends.head, ends.tail].some((end) => end && (end.width !== null || end.length !== null))\n\tif (sized) {\n\t\tnotes.note(\n\t\t\t'line.arrowSize',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t'arrowhead width and length classes (@w / @len) have no write-API option, so arrowheads render at the default size'\n\t\t)\n\t}\n\treturn {\n\t\tbeginArrowType: ends.head && WRITABLE_ARROWS.has(ends.head.type) ? ends.head.type : undefined,\n\t\tendArrowType: ends.tail && WRITABLE_ARROWS.has(ends.tail.type) ? ends.tail.type : undefined,\n\t}\n}\n\n/**\n * A read gradient as `GradientFillProps`. Stop positions convert from the read model's\n * 0–1 fraction to the write API's 0–100 percentage; the angle needs no conversion, since\n * both sides use OOXML degrees (clockwise from 3 o'clock).\n */\nfunction gradientStops(gradient: GradientFill, notes: NoteScope, where: 'fill' | 'line'): IrValue | undefined {\n\tconst stops = gradient.stops\n\t\t.map((stop) => {\n\t\t\tconst color = isWritableSchemeToken(stop.schemeColor)\n\t\t\t\t? (stop.schemeColor as string)\n\t\t\t\t: stop.effectiveHex === null\n\t\t\t\t\t? null\n\t\t\t\t\t: literalColor(stop.effectiveHex)\n\t\t\tif (color === null) return null\n\t\t\treturn compact({\n\t\t\t\tcolor,\n\t\t\t\tposition: Math.round((stop.position ?? 0) * 100),\n\t\t\t\ttransparency: alphaToTransparency(stop.alpha),\n\t\t\t}) as IrValue\n\t\t})\n\t\t.filter((stop): stop is IrValue => stop !== null)\n\n\tif (stops.length < 2) {\n\t\tnotes.note(\n\t\t\t`${where}.gradient`,\n\t\t\t'dropped',\n\t\t\t'unsupported',\n\t\t\t'a gradient with fewer than two resolvable stops cannot be expressed, so this falls back to no gradient'\n\t\t)\n\t\treturn undefined\n\t}\n\n\tif (gradient.kind === 'path') {\n\t\t// `a:path` covers circle/rect/shape; the write API models only the radial case, so\n\t\t// a rectangular or shape-following gradient becomes a circular one.\n\t\tif (gradient.path !== null && gradient.path !== 'circle') {\n\t\t\tnotes.note(\n\t\t\t\t`${where}.gradient.path`,\n\t\t\t\t'approximated',\n\t\t\t\t'unwritable',\n\t\t\t\t`a \"${gradient.path}\" path gradient is emitted as a radial one; the write API models no other path shape`\n\t\t\t)\n\t\t}\n\t\treturn { kind: 'radial', stops }\n\t}\n\treturn compact({ kind: 'linear', angle: gradient.angleDeg ?? 0, stops })\n}\n\n/** Outer shadow as `ShadowProps`; an inner shadow uses the same option with `type: 'inner'`. */\nfunction shadowOption(shape: AnyShape, notes: NoteScope): IrValue | undefined {\n\tif (shape.reflection || shape.softEdge) {\n\t\tnotes.note(\n\t\t\t'shape.effects',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t'a:reflection and a:softEdge are read but have no write-API emitter, so those effects are lost'\n\t\t)\n\t}\n\n\tconst outer = shape.shadow\n\tconst source = outer ?? shape.innerShadow\n\tif (!source) return undefined\n\n\treturn compact({\n\t\ttype: outer ? 'outer' : 'inner',\n\t\tcolor: source.color === null ? undefined : literalColor(source.color),\n\t\tblur: source.blurPt,\n\t\toffset: source.offsetPt,\n\t\tangle: source.angleDeg,\n\t\ttransparency: alphaToTransparency(source.alpha),\n\t})\n}\n\n/** Glow. The read model reports opacity as a 0–1 alpha, which is the write API's unit too. */\nfunction glowOption(shape: AnyShape): IrValue | undefined {\n\tconst glow = shape.glow\n\tif (!glow) return undefined\n\treturn compact({\n\t\tsize: glow.radiusPt,\n\t\tcolor: glow.color === null ? undefined : literalColor(glow.color),\n\t\topacity: glow.alpha,\n\t})\n}\n\n/** The style block every shape kind shares. */\nfunction styleOptions(shape: AnyShape, notes: NoteScope, assets: AssetResolver): Record<string, IrValue | undefined> {\n\treturn {\n\t\tfill: fillOption(shape, notes, assets),\n\t\tline: lineOption(shape, notes),\n\t\tshadow: shadowOption(shape, notes),\n\t\tglow: glowOption(shape),\n\t}\n}\n\n/* ===== per-kind mappers ===== */\n\n/**\n * An `AutoShape` becomes an `addShape` when it is bare geometry and an `addText` when it\n * carries text. A shape with both takes the `addText` form, because `addShape` has no text\n * argument while `addText` accepts a `shape` option — so only that form expresses both.\n */\nfunction autoShapeCall(shape: AutoShape, notes: NoteScope, assets: AssetResolver): CallIr | null {\n\tconst preset = shape.presetGeometry\n\tconst custom = shape.customGeometry\n\tconst frame = shape.hasTextFrame ? shape.textFrame : null\n\n\t// \"Has text\" means text this converter can author, which is *runs*. `TextFrame.text` also\n\t// counts `a:fld` field text — a slide number, date or footer placeholder — and there is no\n\t// run behind it, so measuring by `text` made every field placeholder emit an `addText`\n\t// carrying a single empty string: an invisible empty box where a number used to be.\n\tconst runText = frame === null ? '' : frame.paragraphs.flatMap((p) => p.runs.map((run) => run.text)).join('')\n\tconst hasText = runText.length > 0\n\n\t// Run text is a subsequence of the frame's text, so anything longer came from a field.\n\tif (frame !== null && frame.text.replaceAll('\\n', '').length > runText.length) {\n\t\tnotes.note(\n\t\t\t'text.field',\n\t\t\t'dropped',\n\t\t\t'unread',\n\t\t\t'this shape holds an automatic field (a:fld — a slide number, date or footer), which has no accessor and no addText expression, so its text is not reproduced'\n\t\t)\n\t}\n\n\t// An OMML equation contributes nothing to `TextFrame.text`, so an equation-only shape\n\t// looks like an empty box and would otherwise emit as bare geometry.\n\tif (frame !== null && hasEquation(shape.element_)) {\n\t\tnotes.note(\n\t\t\t'text.equation',\n\t\t\t'dropped',\n\t\t\t'unread',\n\t\t\t'this shape holds an OMML equation, which no accessor exposes, so the shape is emitted without it — even though TextProps.math (and the ts-pptx/math subpath) could author one'\n\t\t)\n\t}\n\n\tif (shape.placeholder) {\n\t\tnotes.note(\n\t\t\t'shape.placeholder',\n\t\t\t'flattened',\n\t\t\t'unsupported',\n\t\t\t'a placeholder is emitted as a plain shape with its inherited geometry and styling baked in, so it no longer follows its layout'\n\t\t)\n\t}\n\n\tconst common = {\n\t\t...positionOptions(shape, notes),\n\t\t...transformOptions(shape),\n\t\t...styleOptions(shape, notes, assets),\n\t\tobjectName: shape.name || undefined,\n\t}\n\n\tif (custom) {\n\t\tnotes.note(\n\t\t\t'shape.custGeom.guides',\n\t\t\t'dropped',\n\t\t\t'unread',\n\t\t\t'custGeom guides, adjust handles and connection sites (a:gdLst / a:ahLst / a:cxnLst) have no accessor, so only the path outline carries'\n\t\t)\n\t\tconst options = compact({ ...common, points: customGeometryPoints(shape, custom) })\n\t\treturn { method: 'addShape', args: ['custGeom', options ?? {}], ...nameOf(shape) }\n\t}\n\n\tif (hasText && frame !== null) {\n\t\t// `isTextBox` and `shape` are independent, not alternatives: a PowerPoint text box\n\t\t// carries `txBox=\"1\"` *and* an explicit `prstGeom rect`, so reading text-box-ness off\n\t\t// the absence of geometry misclassified every one of them as an auto shape.\n\t\tconst options = compact({\n\t\t\t...common,\n\t\t\t...textFrameOptions(frame, notes),\n\t\t\t...(isTextBox(shape.element_) ? { isTextBox: true } : {}),\n\t\t\t...(preset === null ? {} : { shape: preset, ...adjustOptions(shape) }),\n\t\t})\n\t\treturn { method: 'addText', args: [textRuns(frame, notes), options ?? {}], ...nameOf(shape) }\n\t}\n\n\t// No text and no geometry of its own: an empty placeholder, whose shape comes from the\n\t// layout it inherits. `addShape` needs a preset name and `addText` would author an\n\t// invisible empty box, so the shape is dropped — which matches how it renders in a\n\t// slideshow, where an unfilled placeholder shows nothing. It is still a loss in the\n\t// editor, so it is declared rather than assumed harmless.\n\tif (preset === null) {\n\t\tnotes.note(\n\t\t\t'shape.empty',\n\t\t\t'dropped',\n\t\t\t'unsupported',\n\t\t\t'this shape carries no text and no geometry of its own (an unfilled placeholder drawing its outline from the layout), so there is no addShape preset to name and it is omitted'\n\t\t)\n\t\treturn null\n\t}\n\tconst options = compact({ ...common, ...adjustOptions(shape) })\n\treturn { method: 'addShape', args: [preset, options ?? {}], ...nameOf(shape) }\n}\n\n/**\n * Preset-geometry adjust handles (`a:avLst`) as `shapeAdjust`.\n *\n * The read model reports each guide's raw formula string; a preset's adjust values are\n * `val <n>` where `<n>` is in 1000ths of a percent, and the write API takes the same handle\n * as a `0.0–1.0` fraction. Anything that is not a plain `val` is a computed guide, which\n * has no write-API expression, so it is skipped rather than mis-scaled.\n */\nfunction adjustOptions(shape: AutoShape): Record<string, IrValue | undefined> {\n\tconst values = shape.adjustValues\n\tconst guides: IrValue[] = []\n\tfor (const name of Object.keys(values).sort()) {\n\t\tconst match = /^val\\s+(-?\\d+)$/.exec((values[name] ?? '').trim())\n\t\tif (!match?.[1]) continue\n\t\tguides.push({ name, value: Number(match[1]) / 100000 })\n\t}\n\treturn guides.length ? { shapeAdjust: guides } : {}\n}\n\n/**\n * `custGeom` path commands as the write API's `points` array.\n *\n * Path coordinates are integers in the path's own `0..w`/`0..h` viewport, not EMU, so each\n * is scaled onto the shape's box before being printed as EMU. A path that declares no\n * viewport (`@w`/`@h` of 0) is already in the shape's own space and passes through.\n */\nfunction customGeometryPoints(shape: AutoShape, custom: CustomGeometry): IrValue {\n\tconst frame = shape.absoluteFrame\n\tconst points: IrValue[] = []\n\n\tfor (const path of custom.paths) {\n\t\tconst sx = path.w > 0 && frame ? frame.width / path.w : 1\n\t\tconst sy = path.h > 0 && frame ? frame.height / path.h : 1\n\t\tconst px = (v: number): string => emu(v * sx)\n\t\tconst py = (v: number): string => emu(v * sy)\n\n\t\tfor (const command of path.commands) {\n\t\t\tswitch (command.cmd) {\n\t\t\t\tcase 'moveTo':\n\t\t\t\t\tpoints.push({ x: px(command.x), y: py(command.y), moveTo: true })\n\t\t\t\t\tbreak\n\t\t\t\tcase 'lnTo':\n\t\t\t\t\tpoints.push({ x: px(command.x), y: py(command.y) })\n\t\t\t\t\tbreak\n\t\t\t\tcase 'cubicBezTo':\n\t\t\t\t\tpoints.push({\n\t\t\t\t\t\tx: px(command.x),\n\t\t\t\t\t\ty: py(command.y),\n\t\t\t\t\t\tcurve: { type: 'cubic', x1: px(command.x1), y1: py(command.y1), x2: px(command.x2), y2: py(command.y2) },\n\t\t\t\t\t})\n\t\t\t\t\tbreak\n\t\t\t\tcase 'quadBezTo':\n\t\t\t\t\tpoints.push({\n\t\t\t\t\t\tx: px(command.x),\n\t\t\t\t\t\ty: py(command.y),\n\t\t\t\t\t\tcurve: { type: 'quadratic', x1: px(command.x1), y1: py(command.y1) },\n\t\t\t\t\t})\n\t\t\t\t\tbreak\n\t\t\t\tcase 'arcTo':\n\t\t\t\t\t// An arcTo carries no end point on either side — the renderer derives it from\n\t\t\t\t\t// the pen position, radii and swept angle — so this maps one-to-one.\n\t\t\t\t\tpoints.push({\n\t\t\t\t\t\tcurve: { type: 'arc', wR: px(command.wR), hR: py(command.hR), stAng: command.stAng, swAng: command.swAng },\n\t\t\t\t\t})\n\t\t\t\t\tbreak\n\t\t\t\tcase 'close':\n\t\t\t\t\tpoints.push({ close: true })\n\t\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\treturn points\n}\n\n/**\n * A `Picture` becomes `addImage`, with its bytes carried as an asset.\n *\n * PowerPoint authors embedded audio and video as a picture too — the poster frame is the\n * blip, and the media itself hangs off `p:nvPr` as `a:videoFile`/`a:audioFile`. The read\n * model surfaces only the poster (`mediaKind` separates raster from SVG, not still from\n * moving), so a video would otherwise convert to a static image with nothing to show it had\n * ever moved. The write API has `addMedia`, so this is a read-side gap, and it is declared\n * rather than silently flattened.\n */\nfunction pictureCall(shape: Picture, notes: NoteScope, assets: AssetResolver): CallIr | null {\n\tif (isAudioVideo(shape.element_)) {\n\t\tnotes.note(\n\t\t\t'media.audioVideo',\n\t\t\t'flattened',\n\t\t\t'unread',\n\t\t\t'this is embedded audio or video: no accessor reports the media part or its kind, only the poster frame, so it is emitted as a still image even though addMedia could author it'\n\t\t)\n\t}\n\n\t// The vector part wins when there is one. A PowerPoint SVG picture is an `asvg:svgBlip`\n\t// extension over a raster fallback, and the fallback is the lossy copy — taking it would\n\t// throw away the vector for no reason, since `addImage` accepts SVG bytes directly and\n\t// regenerates a fallback of its own.\n\tconst partName = shape.svgPartName ?? shape.imagePartName\n\tif (!partName) {\n\t\tnotes.note(\n\t\t\t'image.data',\n\t\t\t'dropped',\n\t\t\t'unsupported',\n\t\t\t'this picture references no embedded image part (an external or linked image), so there are no bytes to carry'\n\t\t)\n\t\treturn null\n\t}\n\tconst asset = assets.assetFor(partName)\n\tif (!asset) {\n\t\tnotes.note('image.data', 'dropped', 'unsupported', `image part ${partName} is not present in the package`)\n\t\treturn null\n\t}\n\n\tif (shape.svgPartName && shape.imagePartName) {\n\t\tnotes.note(\n\t\t\t'image.svg',\n\t\t\t'approximated',\n\t\t\t'unsupported',\n\t\t\t\"the vector part of this SVG picture is carried and the source's own raster fallback is not; the write path generates a fresh fallback, so a renderer that cannot draw SVG shows a different image from the one the source deck shipped\"\n\t\t)\n\t}\n\tif (shape.recolor) {\n\t\tnotes.note(\n\t\t\t'image.recolor',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t'a picture recolour (a:duotone / a:clrChange / a:grayscl) is read but has no write-API option'\n\t\t)\n\t}\n\n\tconst crop = shape.crop\n\tconst options = compact({\n\t\t...positionOptions(shape, notes),\n\t\t...transformOptions(shape),\n\t\tobjectName: shape.name || undefined,\n\t\t// `crop`, not `sizing`. Both exist and they are not interchangeable: `crop` is\n\t\t// `a:srcRect` emitted verbatim as percentage edge insets — the exact model the read\n\t\t// model reports — while `sizing: 'crop'` cuts a window in *displayed inches* against\n\t\t// the image's measured natural size. Feeding fractions to `sizing` read them as\n\t\t// inches, which shrank every cropped picture to a fraction of its box.\n\t\tcrop:\n\t\t\tcrop === null ? undefined : { l: crop.left * 100, t: crop.top * 100, r: crop.right * 100, b: crop.bottom * 100 },\n\t})\n\treturn { method: 'addImage', args: [{ ...(options ?? {}), data: asset }], ...nameOf(shape) }\n}\n\n/**\n * `ConnectorProps` keys that {@link lineOption} can produce. A connector styles its stroke\n * with *flat* options rather than the nested `line` object every other shape takes, and it\n * accepts a strict subset: no `transparency`, no gradient stroke, and its own `type` names\n * the routing (`straight`/`elbow`/`curved`), not a fill kind — so spreading a line option\n * object into it wholesale would both drop silently and collide.\n */\nconst CONNECTOR_LINE_KEYS = ['color', 'width', 'dashType', 'beginArrowType', 'endArrowType'] as const\n\n/**\n * A `Connector` becomes `addConnector`.\n *\n * The endpoints are the one real translation here. OOXML gives a connector a bounding box\n * plus flip flags; `addConnector` takes two points. `a:flipH`/`a:flipV` are what say which\n * diagonal of the box the line runs along, so dropping them would silently mirror every\n * connector that runs up or leftward.\n *\n * The *bindings* (`a:stCxn`/`a:endCxn`) reference source shape ids that have no counterpart\n * in the output, so a connector lands unbound and stops following its shapes when they move.\n */\nfunction connectorCall(shape: Connector, notes: NoteScope): CallIr | null {\n\tconst frame = shape.absoluteFrame\n\tif (!frame) return null\n\n\tif (shape.startConnection || shape.endConnection) {\n\t\tnotes.note(\n\t\t\t'connector.binding',\n\t\t\t'dropped',\n\t\t\t'unsupported',\n\t\t\t'connector endpoint bindings reference source shape ids with no counterpart in the output, so the connector lands unbound and no longer follows its shapes'\n\t\t)\n\t}\n\tif (shape.rotation) {\n\t\tnotes.note(\n\t\t\t'connector.rotation',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t'addConnector takes two endpoints and no rotation, so a rotated connector lands along the unrotated diagonal of its box'\n\t\t)\n\t}\n\n\tconst line = lineOption(shape, notes) ?? {}\n\tconst stroke: Record<string, IrValue> = {}\n\tfor (const key of CONNECTOR_LINE_KEYS) {\n\t\tconst value = line[key]\n\t\tif (value !== undefined) stroke[key] = value\n\t}\n\tif (line['type'] === 'gradient' || line['transparency'] !== undefined) {\n\t\tnotes.note(\n\t\t\t'connector.line',\n\t\t\t'flattened',\n\t\t\t'unwritable',\n\t\t\t'a connector styles its stroke with flat colour/width options, which cannot express a gradient stroke or a stroke transparency, so those fall back to a plain line'\n\t\t)\n\t}\n\n\tconst right = frame.left + frame.width\n\tconst bottom = frame.top + frame.height\n\treturn {\n\t\tmethod: 'addConnector',\n\t\targs: [\n\t\t\tcompact({\n\t\t\t\t// Routing is not readable — `presetGeometry` names the connector preset but the\n\t\t\t\t// bend count it implies is not exposed — so every connector emits straight.\n\t\t\t\ttype: 'straight',\n\t\t\t\tx1: emu(shape.flipH ? right : frame.left),\n\t\t\t\ty1: emu(shape.flipV ? bottom : frame.top),\n\t\t\t\tx2: emu(shape.flipH ? frame.left : right),\n\t\t\t\ty2: emu(shape.flipV ? frame.top : bottom),\n\t\t\t\tobjectName: shape.name || undefined,\n\t\t\t\t...stroke,\n\t\t\t}) ?? {},\n\t\t],\n\t\t...nameOf(shape),\n\t}\n}\n\n/** A `GraphicFrame` hosts a table or a chart; both have their own mapper. */\nfunction graphicFrameCall(shape: GraphicFrame, notes: NoteScope, assets: AssetResolver): CallIr | null {\n\tconst table = shape.table\n\tif (table) return tableCall(shape, table, notes, assets)\n\n\tconst chart = shape.chart\n\tif (chart) return chartCall(shape, chart, notes)\n\n\tif (shape.hasChartEx) {\n\t\t// Reached only if the deck-level walk did not already mark the slide `carried`.\n\t\tnotes.note(\n\t\t\t'chartEx.all',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t'an extended chart (waterfall, funnel, box-and-whisker, …) has a full reader but no write-API counterpart'\n\t\t)\n\t\treturn null\n\t}\n\n\tnotes.note(\n\t\t'graphicFrame.unknown',\n\t\t'dropped',\n\t\t'unread',\n\t\t'this graphic frame hosts neither a table nor a chart (SmartArt or an OLE object), which the read model does not decode'\n\t)\n\treturn null\n}\n\n/**\n * A `GroupShape` becomes `addGroup`, with each child mapped and re-tagged into the\n * key-tagged `GroupChildProps` shape the write API expects.\n *\n * Children keep slide-absolute coordinates, which is not a compromise here: `addGroup`\n * holds an identity child coordinate space (`chOff/chExt == off/ext`) at every depth\n * precisely so they can. Nested groups therefore nest rather than flatten. What does not\n * survive is a source group with a *non*-identity child space — that group scales its\n * contents when resized and the emitted one will not — so that case, and only that case,\n * is noted.\n *\n * Charts, tables, media and placeholders are excluded from groups by the write API, so a\n * group holding one loses that child.\n */\nfunction groupCall(shape: GroupShape, notes: NoteScope, assets: AssetResolver): CallIr | null {\n\tconst children: IrValue[] = []\n\tfor (const child of shape.shapes) {\n\t\tconst call = shapeCall(child, notes, assets)\n\t\tif (!call) continue\n\t\tconst tagged = asGroupChild(call)\n\t\tif (!tagged) {\n\t\t\tnotes.note(\n\t\t\t\t'group.child',\n\t\t\t\t'dropped',\n\t\t\t\t'unsupported',\n\t\t\t\t`addGroup accepts no ${call.method.replace(/^add/, '').toLowerCase()} child (charts, tables and media are excluded by design), so this child is omitted from the group`\n\t\t\t)\n\t\t\tcontinue\n\t\t}\n\t\tchildren.push(tagged)\n\t}\n\tif (children.length === 0) {\n\t\tnotes.note(\n\t\t\t'group.empty',\n\t\t\t'dropped',\n\t\t\t'unsupported',\n\t\t\t'no child of this group produced a call, and addGroup rejects an empty child list, so the group itself is omitted too'\n\t\t)\n\t\treturn null\n\t}\n\n\tif (!hasIdentityChildSpace(shape.element_)) {\n\t\tnotes.note(\n\t\t\t'group.childSpace',\n\t\t\t'flattened',\n\t\t\t'unsupported',\n\t\t\t\"this group scales its contents (its a:chOff/a:chExt differ from its a:off/a:ext); addGroup's child space is always identity, so the children are emitted pre-scaled and resizing the group no longer rescales them\"\n\t\t)\n\t}\n\n\t// The group's own rotation and flips are deliberately NOT emitted here. `absoluteFrame`\n\t// composes them into every child, and the children above were built from it, so the\n\t// transform is already baked in at slide-absolute coordinates. Emitting it on the group\n\t// as well would apply it a second time — measured: a group rotated 30° came back at 60°\n\t// with its children walked off their positions, and a flipped group came back unflipped\n\t// because the double flip cancelled. The group's frame is a bounding box and nothing else.\n\tif (shape.rotation !== 0 || shape.flipH || shape.flipV) {\n\t\tnotes.note(\n\t\t\t'group.transform',\n\t\t\t'flattened',\n\t\t\t'unsupported',\n\t\t\t\"the group's own rotation and flips are baked into its children's coordinates rather than kept on the group, because addGroup would otherwise apply them twice; the shapes render identically but rotating or resetting the group no longer moves them together\"\n\t\t)\n\t}\n\n\treturn {\n\t\tmethod: 'addGroup',\n\t\targs: [children, compact({ ...positionOptions(shape, notes), objectName: shape.name || undefined }) ?? {}],\n\t\t...nameOf(shape),\n\t}\n}\n\n/**\n * Re-tag a call as a `GroupChildProps` entry, or `null` when the content type is one\n * `addGroup` excludes. The tagged form is a single-key object, not a `{ type, args }` pair.\n */\nfunction asGroupChild(call: CallIr): IrValue | null {\n\tconst [first, second] = call.args\n\tswitch (call.method) {\n\t\tcase 'addText':\n\t\t\treturn { text: compact({ text: first, options: second }) ?? {} }\n\t\tcase 'addShape':\n\t\t\treturn { shape: compact({ type: first, options: second }) ?? {} }\n\t\tcase 'addImage':\n\t\t\treturn { image: first ?? {} }\n\t\tcase 'addGroup':\n\t\t\treturn { group: compact({ children: first, options: second }) ?? {} }\n\t\tdefault:\n\t\t\t// Charts, tables, connectors and media have no GroupChildProps variant.\n\t\t\treturn null\n\t}\n}\n\n/** Attach the source name to a call, when the shape had one. */\nfunction nameOf(shape: AnyShape): { sourceName?: string } {\n\treturn shape.name ? { sourceName: shape.name } : {}\n}\n","/**\n * A slide's show transition (`p:transition`) → the write API's `TransitionProps`.\n *\n * **The whole difficulty is one type mismatch.** `TransitionInfo.type` is an *open string*,\n * because the read model decodes PowerPoint's modern effects (Morph, Vortex, Ripple, …)\n * alongside the base ECMA-376 ones and tells them apart by namespace rather than by name.\n * The write API's `TransitionType` is a closed union of 21 base names. Passing the read\n * model's string straight through would therefore produce a script that does not compile\n * for exactly the decks a converter is most likely to meet — a modern transition is what\n * PowerPoint's own UI offers first. So {@link WRITABLE_TYPES} is the filter, and a name that\n * does not survive it becomes a fidelity note rather than a compile error.\n *\n * **Why `speed` is always emitted.** `spd` is absent from most PowerPoint-authored\n * transitions (its schema default is `fast`) and the read model reports the default rather\n * than the absence, so there is nothing to distinguish \"absent\" from \"explicitly fast\". That\n * is harmless on its own — both read back as `fast`. What is *not* harmless is omitting it\n * when a duration is present: the write path then derives the bucket from `durationMs`\n * (`transitionSpeedForDuration`), and PowerPoint's own pairing does not always agree with\n * that formula — the sound fixture carries `spd=\"slow\"` with `p14:dur=\"2000\"`, which the\n * derivation happens to reproduce, while a 600ms `fast` transition would come back `med`.\n * Emitting the read value verbatim removes the derivation from the path entirely, which is\n * the same discipline the rest of the IR follows: state what was read, never recompute it.\n */\nimport type { Slide } from '../../read/api/slide.js'\nimport type { TransitionInfo } from '../../read/api/transition.js'\nimport type { TransitionType } from '../../types/animation.js'\nimport type { NoteScope } from '../fidelity.js'\nimport type { TransitionIr, TransitionSoundIr } from '../ir.js'\nimport type { AssetResolver } from './shape.js'\n\n/**\n * The transitions the write API can author, as a lookup.\n *\n * Spelled as a `Record` keyed by `TransitionType` rather than as an array of strings so the\n * compiler polices it in *both* directions: a name the union does not have is rejected here,\n * and a name the union gains without being added here fails to satisfy the record. A plain\n * `Set<string>` would silently drift out of date, and the symptom would be a printed script\n * that does not compile — found by whoever runs it, not by this repository's test suite.\n */\nconst WRITABLE_TYPES: Record<TransitionType, true> = {\n\tblinds: true,\n\tchecker: true,\n\tcircle: true,\n\tcomb: true,\n\tcover: true,\n\tcut: true,\n\tdiamond: true,\n\tdissolve: true,\n\tfade: true,\n\tnewsflash: true,\n\tplus: true,\n\tpull: true,\n\tpush: true,\n\trandom: true,\n\trandomBar: true,\n\tsplit: true,\n\tstrips: true,\n\twedge: true,\n\twheel: true,\n\twipe: true,\n\tzoom: true,\n}\n\n/**\n * `true` when the write API has a name for this transition.\n *\n * The namespace check does no work on PowerPoint's own output and is kept anyway. Every one\n * of the 21 modern effect names in the probed table (`conveyor`, `morph`, `vortex`, …) is\n * distinct from every base name, so today the name lookup alone would reach the same verdict\n * — measured, not assumed. But \"is this a base ECMA-376 transition\" is a question about the\n * *namespace*, and answering it by name would be relying on that disjointness holding for\n * every namespace Microsoft ever adds. The write path emits `p:${type}` unconditionally, so\n * the cost of being wrong is a modern effect silently rewritten as a base one with the same\n * name and no note — a conversion that reports itself as faithful. `script-ir.test.js`\n * authors a `p14:fade` to keep this branch honest, since no fixture can.\n */\nfunction isWritable(info: TransitionInfo): boolean {\n\treturn info.namespace === 'p' && Object.hasOwn(WRITABLE_TYPES, info.type)\n}\n\n/**\n * Map a slide's transition, recording a note for anything that does not survive.\n *\n * Returns `undefined` both when the slide has no transition and when it has one this\n * library cannot author — the difference between those two is what the note carries.\n */\nexport function transitionToIr(slide: Slide, notes: NoteScope, assets: AssetResolver): TransitionIr | undefined {\n\tconst info = slide.transition\n\tif (!info) return undefined\n\n\tif (!isWritable(info)) {\n\t\tnotes.note(\n\t\t\t'slide.transition',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t`this slide's ${info.namespace === 'p' ? '' : `${info.namespace} `}${info.type} transition is not one of the 21 base ECMA-376 transitions the write API can author${\n\t\t\t\tinfo.namespace === 'p' ? '' : \" — it is one of PowerPoint's modern effects, which have no write-API vocabulary\"\n\t\t\t}, so the regenerated slide advances with no effect`\n\t\t)\n\t\treturn undefined\n\t}\n\n\t// Each optional key is spread in only when the source carried it, so an absent attribute\n\t// stays absent rather than becoming an explicit default the source never wrote.\n\tconst sound = soundToIr(slide, info, notes, assets)\n\treturn {\n\t\ttype: info.type,\n\t\tspeed: info.speed,\n\t\t...(info.durationMs === null ? {} : { durationMs: info.durationMs }),\n\t\t// Both are omitted at their OOXML default, so the emitted script says only what the\n\t\t// source said: `advClick` defaults to true and `advTm` to unset.\n\t\t...(info.advanceOnClick ? {} : { advanceOnClick: false }),\n\t\t...(info.advanceAfterMs === null ? {} : { advanceAfterMs: info.advanceAfterMs }),\n\t\t...(Object.keys(info.variant).length > 0 ? { variant: { ...info.variant } } : {}),\n\t\t...(sound ? { sound } : {}),\n\t}\n}\n\n/**\n * The transition's sound (`p:sndAc`), in the two forms OOXML gives it.\n *\n * The stop-previous form is pure structure — no relationship, no media part — so it maps\n * unconditionally. A start sound is an embedded WAV reached through the slide's own\n * relationships, which is the only place in this converter that resolves an `r:embed` by\n * hand: every other media reference arrives already resolved to a partname by the read\n * model's shape accessors, and a transition sound has no shape to hang off.\n */\nfunction soundToIr(\n\tslide: Slide,\n\tinfo: TransitionInfo,\n\tnotes: NoteScope,\n\tassets: AssetResolver\n): TransitionSoundIr | undefined {\n\tconst sound = info.sound\n\tif (!sound) return undefined\n\tif (sound.form === 'stop') return { stopPrevious: true }\n\n\tconst partName = soundPartName(slide, sound.embedRid)\n\tconst asset = partName === null ? null : assets.assetFor(partName)\n\tif (!asset) {\n\t\tnotes.note(\n\t\t\t'slide.transitionSound',\n\t\t\t'dropped',\n\t\t\t'unsupported',\n\t\t\t`this transition's start sound (${sound.embedRid ?? 'no r:embed'}) does not resolve to an audio part in the package, so the regenerated transition is silent`\n\t\t)\n\t\treturn undefined\n\t}\n\n\treturn {\n\t\tdata: asset,\n\t\t...(sound.name === null ? {} : { name: sound.name }),\n\t\t// Omitted at its default, like `advanceOnClick`: `p:stSnd@loop` defaults to false.\n\t\t...(sound.loop ? { loop: true } : {}),\n\t}\n}\n\n/** Resolve `p:snd@r:embed` to the audio part it names, or `null` when it does not resolve. */\nfunction soundPartName(slide: Slide, embedRid: string | null): string | null {\n\tif (!embedRid) return null\n\tconst relationship = slide.relationships.get(embedRid)\n\t// An External audio rel has no partname to read bytes from; `resolveTarget` throws on\n\t// both cases, so they are screened here rather than caught.\n\tif (!relationship || relationship.targetMode === 'External') return null\n\treturn slide.relationships.resolveTarget(embedRid)\n}\n","/**\n * `Presentation` → {@link DeckIr}. The entry point of the read half.\n *\n * Pure in the sense that matters: it reads a loaded package and returns data, touching no\n * filesystem and mutating nothing. Given the same bytes it returns the same IR, so a\n * round-trip check can compare two runs directly.\n *\n * The one judgement made at this level rather than per-shape is {@link SlideSource}. A\n * slide holding a construct the write API cannot express *at all* — an extended chart is\n * the clear case, with a complete reader and no emitter — cannot be honestly transcribed,\n * because the output would silently differ from the source. Such a slide is marked\n * `carried` so the printer copies it instead. That decision has to be made here, before\n * any shape is mapped, since it is a property of the slide as a whole.\n */\nimport type { Presentation } from '../../read/api/presentation.js'\nimport type { Slide } from '../../read/api/slide.js'\nimport type { AnyShape } from '../../read/api/shapes.js'\nimport { isGraphicFrame, isGroupShape } from '../../read/api/shapes.js'\nimport { NoteCollector, scopeNotes, type NoteScope } from '../fidelity.js'\nimport type { AssetIr, AssetRef, BackgroundIr, CallIr, DeckIr, DeckPropsIr, SlideIr, SlideLayoutIr } from '../ir.js'\nimport type { AssetResolver } from './shape.js'\nimport { chromeToIr } from './chrome.js'\nimport { shapeCall } from './shape.js'\nimport { transitionToIr } from './transition.js'\nimport { compact } from './values.js'\n\n/** Default slide size (10\" × 7.5\") for a deck whose `presentation.xml` declares none. */\nconst DEFAULT_SLIDE_SIZE = { widthEmu: 9144000, heightEmu: 6858000 }\n\n/** Extensions by content type, so an emitted asset filename is one a viewer recognises. */\nconst ASSET_EXTENSIONS: Record<string, string> = {\n\t'image/png': 'png',\n\t'image/jpeg': 'jpg',\n\t'image/gif': 'gif',\n\t'image/bmp': 'bmp',\n\t'image/webp': 'webp',\n\t'image/tiff': 'tif',\n\t'image/x-emf': 'emf',\n\t'image/x-wmf': 'wmf',\n\t'image/svg+xml': 'svg',\n\t// PowerPoint authors the `x-` form for an embedded transition sound; both spellings\n\t// appear in the wild and neither has `wav` as its trailing path component.\n\t'audio/x-wav': 'wav',\n\t'audio/wav': 'wav',\n\t'audio/mpeg': 'mp3',\n}\n\n/**\n * Collects media as shapes reference it, assigning each part a stable sequential name.\n *\n * Names are assigned in first-reference order rather than derived from the source part\n * name, so the output is deterministic for a given deck and does not leak whatever the\n * source package happened to call its files. A part referenced twice resolves to one asset.\n *\n * Numbering runs per *kind* (`image1.png`, `image2.png`, `audio1.wav`) rather than over one\n * shared counter. Not cosmetics: the asset name becomes a `const` identifier in the emitted\n * script and a filename in its asset directory, and a transition sound bound to `image7`\n * reads as a bug in the generated source every time anyone opens it.\n */\nclass Assets implements AssetResolver {\n\treadonly #byPartName = new Map<string, AssetRef>()\n\treadonly #assets: AssetIr[] = []\n\treadonly #counts = new Map<string, number>()\n\n\tconstructor(private readonly pres: Presentation) {}\n\n\tassetFor(partName: string): AssetRef | null {\n\t\tconst existing = this.#byPartName.get(partName)\n\t\tif (existing) return existing\n\n\t\tconst part = this.pres.opc.part(partName)\n\t\tif (!part) return null\n\n\t\tconst extension = ASSET_EXTENSIONS[part.contentType] ?? partName.split('.').pop() ?? 'bin'\n\t\tconst kind = part.contentType.startsWith('audio/') ? 'audio' : 'image'\n\t\tconst index = (this.#counts.get(kind) ?? 0) + 1\n\t\tthis.#counts.set(kind, index)\n\t\tconst name = `${kind}${index}.${extension}`\n\t\tconst ref: AssetRef = { $asset: name }\n\t\tthis.#byPartName.set(partName, ref)\n\t\tthis.#assets.push({ name, contentType: part.contentType, bytes: part.bytes })\n\t\treturn ref\n\t}\n\n\tcontentTypeOf(partName: string): string | null {\n\t\treturn this.pres.opc.part(partName)?.contentType ?? null\n\t}\n\n\tget assets(): AssetIr[] {\n\t\treturn this.#assets\n\t}\n}\n\n/** Convert a loaded deck into its IR. */\nexport function readModelToIr(pres: Presentation): DeckIr {\n\tconst collector = new NoteCollector()\n\tconst assets = new Assets(pres)\n\tconst size = pres.slideSize\n\tconst deckScope = scopeNotes(collector, null)\n\n\tif (!size) {\n\t\tdeckScope.note(\n\t\t\t'deck.slideSize',\n\t\t\t'approximated',\n\t\t\t'unsupported',\n\t\t\t`this deck declares no slide size, so the output uses the ${DEFAULT_SLIDE_SIZE.widthEmu / 914400}in × ${DEFAULT_SLIDE_SIZE.heightEmu / 914400}in default`\n\t\t)\n\t}\n\n\tconst layouts = layoutGallery(pres)\n\t// Before the slides, so the chrome's deck-level notes lead the list the way the chrome\n\t// leads the deck. Assets are shared: a layout background image and a slide image that are\n\t// the same part resolve to one asset.\n\tconst chrome = chromeToIr(pres, deckScope, assets)\n\tconst slides = pres.slides.map((slide, index) => slideToIr(slide, index + 1, collector, assets, layouts))\n\n\treturn {\n\t\tslideSize: size ? { widthEmu: size.widthEmu, heightEmu: size.heightEmu } : DEFAULT_SLIDE_SIZE,\n\t\tprops: deckProps(pres, deckScope),\n\t\tchrome,\n\t\tslides,\n\t\tassets: assets.assets,\n\t\tfidelity: collector.notes,\n\t}\n}\n\n/**\n * Deck properties, reduced to the five `docProps` fields the write API sets. The other\n * seven the read model exposes have no setter — they survive anyway in a template-anchored\n * output, since the source deck itself becomes the template, so this is only a loss for a\n * standalone one.\n */\nfunction deckProps(pres: Presentation, notes: NoteScope): DeckPropsIr {\n\tconst core = pres.coreProperties\n\tconst carried = ['keywords', 'description', 'category', 'contentStatus', 'lastModifiedBy'] as const\n\tif (carried.some((key) => core[key] !== undefined)) {\n\t\tnotes.note(\n\t\t\t'deck.docProps',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t'only title, author, company, subject and revision have write-API setters; keywords, description, category, content status and last-modified-by have none'\n\t\t)\n\t}\n\treturn (\n\t\tcompact({\n\t\t\ttitle: core.title,\n\t\t\tauthor: core.creator,\n\t\t\tsubject: core.subject,\n\t\t\trevision: core.revision,\n\t\t}) ?? {}\n\t)\n}\n\n/**\n * The deck's layouts keyed by partname, each resolved to what a printer needs to bind to\n * it: its gallery position and whether its name identifies it on its own.\n *\n * Built once per deck rather than per slide — `layouts()` walks every master's layout list,\n * and the uniqueness question is about the gallery as a whole, so asking it per slide would\n * be both quadratic and unable to see layouts no slide happens to use.\n */\nfunction layoutGallery(pres: Presentation): Map<string, SlideLayoutIr> {\n\tconst handles = pres.layouts()\n\tconst nameCounts = new Map<string, number>()\n\tfor (const handle of handles) nameCounts.set(handle.name, (nameCounts.get(handle.name) ?? 0) + 1)\n\n\treturn new Map(\n\t\thandles.map((handle, index) => [\n\t\t\thandle.partName,\n\t\t\t{ name: handle.name, index, nameIsUnique: (nameCounts.get(handle.name) ?? 0) === 1 },\n\t\t])\n\t)\n}\n\nfunction slideToIr(\n\tslide: Slide,\n\tnumber: number,\n\tcollector: NoteCollector,\n\tassets: Assets,\n\tlayouts: Map<string, SlideLayoutIr>\n): SlideIr {\n\tconst notes = scopeNotes(collector, number)\n\tconst layoutPartName = slide.layout?.partName\n\tconst base = {\n\t\tnumber,\n\t\tlayout: (layoutPartName === undefined ? undefined : layouts.get(layoutPartName)) ?? null,\n\t\thidden: slide.hidden,\n\t\t...(slide.name ? { name: slide.name } : {}),\n\t\t...backgroundOf(slide, notes),\n\t\t...notesOf(slide, notes),\n\t}\n\n\tconst transition = transitionToIr(slide, notes, assets)\n\tconst carried = hasUnwritableContent(slide)\n\tif (carried) {\n\t\tnotes.note(\n\t\t\t'slide.carried',\n\t\t\t'flattened',\n\t\t\t'unwritable',\n\t\t\t'this slide holds an extended chart (waterfall, funnel, box-and-whisker, …), which has a full reader but no write-API emitter; a printer that can copy the source slide does so instead of transcribing it, so it renders correctly but the emitted script does not describe its contents'\n\t\t)\n\t}\n\n\t// Mapped even for a carried slide: a printer with no source package to copy from prints\n\t// these and loses only the unwritable construct, rather than the whole slide. Each shape\n\t// records its own note, so the extended chart's loss is declared either way.\n\tconst calls: CallIr[] = []\n\tfor (const shape of slide.shapes) {\n\t\tconst call = shapeCall(shape, notes, assets)\n\t\tif (call) calls.push(call)\n\t}\n\n\t// Build animations are recorded once per slide rather than per shape, since they live in a\n\t// slide-scoped element with no shape to attribute them to.\n\trecordAnimationLoss(slide, notes)\n\n\treturn {\n\t\t...base,\n\t\t...(transition ? { transition } : {}),\n\t\tsource: carried ? 'carried' : 'authored',\n\t\tcalls,\n\t}\n}\n\n/**\n * `true` when the slide holds something with no write-API expression at all, forcing a\n * carried slide. Descends into groups, since a group can host a graphic frame.\n */\nfunction hasUnwritableContent(slide: Slide): boolean {\n\tconst check = (shapes: AnyShape[]): boolean =>\n\t\tshapes.some((shape) => {\n\t\t\tif (isGroupShape(shape)) return check(shape.shapes)\n\t\t\treturn isGraphicFrame(shape) && shape.hasChartEx\n\t\t})\n\treturn check(slide.shapes)\n}\n\nfunction backgroundOf(slide: Slide, notes: NoteScope): { background?: BackgroundIr } {\n\tconst background = slide.background\n\t// An inherited background comes with the layout, so re-authoring it onto the slide would\n\t// pin a colour that should keep following the layout.\n\tif (!background || background.source !== 'slide') return {}\n\n\tswitch (background.type) {\n\t\tcase 'solid':\n\t\t\treturn background.color\n\t\t\t\t? { background: compact({ color: background.color.effectiveHex.replace(/^#/, '').toUpperCase() }) }\n\t\t\t\t: {}\n\t\tcase 'none':\n\t\t\treturn {}\n\t\tdefault:\n\t\t\tnotes.note(\n\t\t\t\t'slide.background',\n\t\t\t\t'dropped',\n\t\t\t\t'unsupported',\n\t\t\t\t`a ${background.type} slide background is not expressible through the write API's background option, so the slide takes its layout's background`\n\t\t\t)\n\t\t\treturn {}\n\t}\n}\n\nfunction notesOf(slide: Slide, notes: NoteScope): { notesText?: string } {\n\tconst text = slide.notesText\n\tif (!text) return {}\n\tconst frame = slide.notesTextFrame\n\tif (frame && frame.paragraphs.some((paragraph) => paragraph.runs.some((run) => run.bold || run.italic))) {\n\t\tnotes.note(\n\t\t\t'notes.formatting',\n\t\t\t'flattened',\n\t\t\t'unsupported',\n\t\t\t\"speaker notes carry as plain text; per-run formatting and the notes slide's own placeholder geometry do not\"\n\t\t)\n\t}\n\treturn { notesText: text }\n}\n\n/**\n * Build animations, which live in a slide-scoped `p:timing` element rather than in any\n * shape's subtree.\n *\n * The transition next door used to be recorded here for the same reason and is now mapped\n * instead (`from-read/transition.ts`), which leaves this the one genuinely slide-scoped\n * loss: there is no structural reader for `p:timing` at all, only spid manipulation for the\n * deck-to-deck import path, so a build sequence is invisible to this converter.\n */\nfunction recordAnimationLoss(slide: Slide, notes: NoteScope): void {\n\tif (slide.hasAnimations) {\n\t\tnotes.note(\n\t\t\t'slide.animation',\n\t\t\t'dropped',\n\t\t\t'unread',\n\t\t\t'build animations have no structural reader (p:timing is only manipulated by spid for the deck-to-deck import path), so every shape on this slide lands static'\n\t\t)\n\t}\n}\n","/**\n * The deck IR — a serializable description of a deck as a sequence of write-API calls.\n *\n * This is the seam between reading a `.pptx` and printing TypeScript for it. Everything\n * upstream of the IR knows about OOXML and the read model; everything downstream knows\n * only about strings. Neither half can see the other, which is the point: the decision\n * \"this `a:ln` becomes `line: { width: 2 }`\" is made once, here, and is testable without\n * a printer, while \"how a number is spelled in source text\" is a printer concern that\n * cannot silently change what the deck means.\n *\n * Two rules keep that seam honest, and both are load-bearing:\n *\n * 1. **The IR is data, not objects.** No DOM nodes, no read-model instances, no\n * functions — `structuredClone` and `JSON.stringify` both round-trip it. A round-trip\n * test can therefore compare two IRs directly (see {@link FidelityNote}), and an IR\n * can be cached or shipped without dragging a whole `Presentation` along.\n * 2. **`args` are literal write-API option objects.** A {@link CallIr} is exactly what\n * the emitted source will pass, so the printer never invents, reshapes, or defaults a\n * value — it spells out what is already there. If the printer had to interpret, the\n * same construct could mean two things depending on which half you asked.\n *\n * Media is the one thing that cannot be a literal, since bytes are not source text. It\n * is referenced by {@link AssetRef} and carried out-of-band in {@link DeckIr.assets}, so\n * the IR itself stays serializable and the printer decides between a file path and an\n * inline base64 literal.\n */\nimport type { FidelityNote } from './fidelity.js'\n\n/**\n * A reference to bytes held in {@link DeckIr.assets}, standing where a write-API option\n * wants image/media data. Printed as a `path` or an inline `data:` literal depending on\n * the print options — an IR-level decision would bake one choice into the IR and force a\n * re-read to change it.\n *\n * The `$asset` sigil is deliberate: no write-API option object has a `$`-prefixed key,\n * so a value carrying one is unambiguously a reference rather than user data.\n */\nexport interface AssetRef {\n\t$asset: string\n}\n\n/** `true` when `value` is an {@link AssetRef} rather than a plain IR object. */\nexport function isAssetRef(value: unknown): value is AssetRef {\n\treturn typeof value === 'object' && value !== null && typeof (value as AssetRef).$asset === 'string'\n}\n\n/**\n * Any value an IR may hold. Deliberately narrower than `unknown`: it excludes `undefined`\n * so that \"absent\" has exactly one spelling (a missing key), which is what makes two IRs\n * comparable field-by-field in a round-trip diff. `readModelToIr` never writes an\n * `undefined` value.\n */\nexport type IrValue = null | boolean | number | string | AssetRef | IrValue[] | { [key: string]: IrValue }\n\n/**\n * Widen one of the typed IR records below to {@link IrValue}, for the printer and the\n * canonicaliser, which walk the IR generically.\n *\n * A cast, and unavoidably so. An optional key on an interface types as `T | undefined`,\n * while `IrValue` deliberately excludes `undefined` so that \"absent\" has exactly one\n * spelling — which makes the two mutually unassignable even though every value a mapper\n * actually produces satisfies both. The invariant that closes the gap is enforced at the\n * source (`compact` and the conditional spreads in `from-read/`, pinned by the \"no value is\n * `undefined`\" corpus test) rather than by the type system, so it is stated once here\n * instead of re-argued at each call site.\n */\nexport function asIrValue(value: object): IrValue {\n\treturn value as unknown as IrValue\n}\n\n/** Bytes referenced by an {@link AssetRef}, plus what a printer needs to name and type them. */\nexport interface AssetIr {\n\t/** Stable key an {@link AssetRef} resolves against; also the emitted filename. */\n\tname: string\n\t/** MIME type from the source package's content types, for an inline `data:` URI. */\n\tcontentType: string\n\tbytes: Uint8Array\n}\n\n/**\n * One write-API call on a slide, in the order it must be made. `method` names a real\n * method on the authored slide and `args` are its positional arguments — so a printer is\n * a formatter, and `readModelToIr` owns every semantic choice.\n *\n * Ordering is z-order: OOXML paints a slide's shape tree front-to-back in document order,\n * and so does the write path, so preserving call order preserves overlap.\n */\nexport interface CallIr {\n\tmethod: 'addText' | 'addShape' | 'addImage' | 'addTable' | 'addChart' | 'addConnector' | 'addGroup' | 'addNotes'\n\targs: IrValue[]\n\t/**\n\t * The source shape's name (`p:cNvPr/@name`), when it had one. Not an argument —\n\t * carried so a printer can comment the call and a fidelity note can point at it.\n\t */\n\tsourceName?: string\n}\n\n/**\n * How a slide's content gets into the output deck.\n *\n * `authored` — every shape is transcribed into {@link CallIr}s and regenerated through\n * the write API. This is the goal: the emitted source is editable, and a reader can see\n * what the deck contains.\n *\n * `carried` — the slide holds at least one construct the write API cannot express at all\n * (`chartEx` is the clear case: a full reader, no emitter), so transcribing it would\n * silently produce a different deck. A printer that *can* copy the slide from the source\n * package should do so: fidelity is higher than transcription, though the emitted source then\n * says nothing about what is on the slide, which is a real cost and always carries a\n * {@link FidelityNote}.\n *\n * This is a recommendation, not an erasure. {@link SlideIr.calls} is populated either way, so\n * a printer with no source package to copy from prints them and loses only the unwritable\n * construct rather than the whole slide.\n */\nexport type SlideSource = 'authored' | 'carried'\n\n/**\n * A slide's background, already reduced to what the write API's `background` accepts.\n *\n * `data` rather than `image`, because `BackgroundProps` is `DataOrPathProps & ShapeFillProps`\n * and `data` is the key it actually reads — an `image` key would print, typecheck against\n * `IrValue`, and be ignored at run time.\n */\nexport interface BackgroundIr {\n\tcolor?: string\n\ttransparency?: number\n\tdata?: AssetRef\n}\n\n/**\n * A transition's sound (`p:sndAc`), reduced to what `TransitionSoundProps` accepts.\n *\n * `data` rather than `path`, for the same reason a background image uses `data`: the bytes\n * are the thing the IR carries, and a path would bind the script to a file layout the IR\n * knows nothing about. The stop-previous form has no bytes at all — it silences a sound\n * still playing from the previous slide — so it is the one shape here with no {@link AssetRef}.\n */\nexport interface TransitionSoundIr {\n\t/** Bytes of the embedded WAV, for a start sound. Absent for {@link stopPrevious}. */\n\tdata?: AssetRef\n\t/** `p:snd@name`, the display name PowerPoint shows for the sound. */\n\tname?: string\n\t/** `p:stSnd@loop` — repeat until the next sound starts. Omitted when false, its default. */\n\tloop?: boolean\n\t/** The `p:endSnd` form: stop the previous slide's sound rather than start one. */\n\tstopPrevious?: boolean\n}\n\n/**\n * A slide's show transition (`p:transition`), as a literal `TransitionProps`.\n *\n * Only the base ECMA-376 transitions reach this type. The read model reports\n * {@link TransitionInfo.type} as an *open string*, because PowerPoint's modern effects\n * (Morph, Vortex, …) live in the `p14`/`p15`/`p159` namespaces and it decodes those too —\n * but the write path names 21 base ones and nothing else, so `from-read/transition.ts`\n * filters against that vocabulary and notes what it drops. Anything that survives is a name\n * the write API's own `TransitionType` union accepts, which is what keeps a printed script\n * compiling.\n */\nexport interface TransitionIr {\n\t/** The transition-type element's local name, guaranteed to be a writable one. */\n\ttype: string\n\t/** `p:transition@spd`. Always present — see `from-read/transition.ts` for why it is not omitted. */\n\tspeed: 'slow' | 'med' | 'fast'\n\t/** `p14:dur` in milliseconds, when the source carried an exact duration. */\n\tdurationMs?: number\n\t/** `advClick`. Omitted when true, its default. */\n\tadvanceOnClick?: boolean\n\t/** `advTm` in milliseconds, when the slide auto-advances. */\n\tadvanceAfterMs?: number\n\t/** Type-specific attributes on the type element (`{ dir: 'd' }`, `{ spokes: '2' }`, …). */\n\tvariant?: { [key: string]: string }\n\tsound?: TransitionSoundIr\n}\n\n/**\n * The layout a slide should be bound to in the destination deck, identified two ways\n * because neither alone is sufficient.\n *\n * The **name** is the portable identity: it is what lets a script built from one deck be\n * re-pointed at a different template whose layouts happen to be named the same, and it is\n * what a reader recognises. But `p:cSld@name` is not unique — a deck with several masters\n * routinely carries several \"Title and Content\" layouts, and binding by an ambiguous name\n * is an error, not a coin flip. The **index** into the deck's layout gallery always\n * resolves, so it is the fallback, and {@link nameIsUnique} says which to trust.\n */\nexport interface SlideLayoutIr {\n\t/** `p:cSld@name` of the source layout (`''` when the layout is unnamed). */\n\tname: string\n\t/** Zero-based position in the source deck's layout gallery, in master-then-layout order. */\n\tindex: number\n\t/** `false` when another layout in that gallery shares {@link name}. */\n\tnameIsUnique: boolean\n}\n\n/** One slide of the deck. */\nexport interface SlideIr {\n\t/** 1-based index in the source deck; the identity a {@link FidelityNote} points at. */\n\tnumber: number\n\tsource: SlideSource\n\t/** The layout to bind to, or `null` when the source slide resolves none. */\n\tlayout: SlideLayoutIr | null\n\t/** `p:sld/@show=\"0\"` — a slide hidden from presentation but present in the deck. */\n\thidden: boolean\n\t/** `p:cSld/@name`, when the source slide had one. */\n\tname?: string\n\tbackground?: BackgroundIr\n\t/** Speaker notes as plain text. Notes-slide geometry and placeholders do not survive. */\n\tnotesText?: string\n\t/**\n\t * The show transition, when the source has one the write API can name. Slide-scoped\n\t * rather than a {@link CallIr} because the write API models it as a property assignment\n\t * on the slide, not a method — the IR's `method` union names real methods only.\n\t */\n\ttransition?: TransitionIr\n\t/**\n\t * Write-API calls in z-order.\n\t *\n\t * Populated for every slide, **including a `carried` one**. A printer that can copy the\n\t * source slide ignores these; one that cannot — a standalone output has no source package\n\t * to copy from — prints them and is left with only the unwritable construct missing rather\n\t * than the whole slide. Marking a slide `carried` is a recommendation, not an erasure.\n\t */\n\tcalls: CallIr[]\n}\n\n/**\n * A deck's theme, reduced to what `ThemeProps` accepts — the 12 `a:clrScheme` slots and the\n * major/minor Latin, East-Asian and complex-script faces.\n *\n * What is *not* here is the point of the tier split. `a:fmtScheme` — the three fill, three\n * line and three effect style lists a shape's `p:style` references — has no write-API\n * counterpart and no read accessor, so a theme cannot be reproduced, only approximated.\n */\nexport interface ThemeIr {\n\theadFontFace?: string\n\tbodyFontFace?: string\n\theadFontFaceEA?: string\n\tbodyFontFaceEA?: string\n\theadFontFaceCS?: string\n\tbodyFontFaceCS?: string\n\t/** The 12 `a:clrScheme` slots as bare 6-digit hex, omitting any the theme leaves unset. */\n\tcolorScheme?: { [slot: string]: string }\n}\n\n/**\n * One source slide layout approximated as a `defineSlideMaster` call.\n *\n * The naming is the write API's, not OOXML's: `defineSlideMaster` creates a *layout* under\n * the single shared master, which is exactly the granularity a source layout needs. A source\n * deck's masters have no counterpart at all — hence {@link ChromeIr}'s multi-master note.\n */\nexport interface MasterIr {\n\t/**\n\t * Gallery position of the source layout, matching {@link SlideLayoutIr.index}, so a slide\n\t * finds the master it should bind to without re-deriving a name.\n\t */\n\tlayoutIndex: number\n\t/**\n\t * A `SlideMasterProps` literal. `props.title` is made unique across the deck, because it\n\t * doubles as the key `addSlide({ masterTitle })` matches against and source layout names\n\t * are not unique.\n\t */\n\tprops: { [key: string]: IrValue }\n}\n\n/**\n * The deck's shared chrome, approximated for an output that has no template to inherit it\n * from. A template-anchored printer ignores this entirely — the source deck *is* the chrome.\n */\nexport interface ChromeIr {\n\ttheme: ThemeIr\n\t/** One entry per source layout, in gallery order. */\n\tmasters: MasterIr[]\n}\n\n/** Deck-level properties, reduced to the five `docProps` fields the write API sets. */\nexport interface DeckPropsIr {\n\ttitle?: string\n\tauthor?: string\n\tcompany?: string\n\tsubject?: string\n\trevision?: string\n}\n\n/**\n * A whole deck, ready to print.\n *\n * `widthEmu`/`heightEmu` are raw EMU rather than inches because that is what the read\n * model reports and what the write API's `Coord` accepts verbatim; converting here would\n * introduce a rounding decision at the wrong layer.\n */\nexport interface DeckIr {\n\tslideSize: { widthEmu: number; heightEmu: number }\n\tprops: DeckPropsIr\n\t/**\n\t * Theme and layouts, approximated. Only a standalone printer reads this; a\n\t * template-anchored one gets all of it byte-identical from the source deck instead.\n\t */\n\tchrome: ChromeIr\n\tslides: SlideIr[]\n\tassets: AssetIr[]\n\t/**\n\t * Every construct that did not survive into {@link slides} intact. This is a\n\t * *contract*, not a log: a round-trip check excludes exactly these fields from its\n\t * diff, so an unnoted difference is a bug and a note nothing else corroborates is a\n\t * stale claim. See {@link FidelityNote}.\n\t */\n\tfidelity: FidelityNote[]\n}\n","/**\n * {@link IrValue} → TypeScript source text.\n *\n * This module is deliberately the dumbest part of the subsystem. It knows nothing about\n * decks, shapes, or units — only how a value is spelled. Every semantic decision was made\n * upstream in the read half, which is what lets the printed text be checked by comparing\n * IRs rather than by reading source: if this file were allowed to interpret, the same\n * construct could mean two things depending on which half you asked.\n *\n * Two consequences worth stating, because they are easy to erode later:\n *\n * - **Numbers are printed, not reformatted.** The IR already holds geometry either as a\n * `` `${n}emu` `` string (exact) or as a six-decimal inch number (the proven minimum for\n * an EMU-exact round-trip). Rounding here to suppress `0.5000000001`-style noise would\n * turn a cosmetic problem into a real geometry loss, so `printNumber` only refuses\n * values JavaScript cannot spell back.\n * - **Layout is a function of the value alone.** Whether an object prints on one line or\n * several depends only on its rendered width, never on where it came from, so the same\n * deck prints byte-identical text every time.\n */\nimport type { AssetRef, IrValue } from '../ir.js'\nimport { isAssetRef } from '../ir.js'\nimport { InvalidOptionError } from '../../errors.js'\n\n/** Matches `.prettierrc`: `printWidth: 120`. */\nconst MAX_WIDTH = 120\n\n/**\n * Columns a tab is assumed to occupy when measuring against {@link MAX_WIDTH}. Prettier's\n * default `tabWidth`, since the repo sets `useTabs` but not `tabWidth`.\n */\nconst TAB_COLUMNS = 2\n\n/** A bare object key needs no quotes only if it is a plain identifier. */\nconst IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/\n\n/**\n * Resolves an {@link AssetRef} to the source text that stands in for it — a `const`\n * identifier when assets are written as files, an inline `data:` literal otherwise. The\n * printer takes this as a callback rather than deciding itself, because the choice belongs\n * to the caller's output layout, not to how a value is spelled.\n */\nexport type AssetPrinter = (ref: AssetRef) => string\n\n/**\n * A string literal in the repo's style (`singleQuote: true`).\n *\n * Deck text is arbitrary user content, so every case below is reachable in practice: a\n * quote, a backslash, a hard line break inside a run. `JSON.stringify` would handle those\n * correctly — it is avoided here for the quote style, not for correctness.\n */\nexport function printString(value: string): string {\n\tlet out = \"'\"\n\tfor (const char of value) {\n\t\tswitch (char) {\n\t\t\tcase '\\\\':\n\t\t\t\tout += '\\\\\\\\'\n\t\t\t\tbreak\n\t\t\tcase \"'\":\n\t\t\t\tout += \"\\\\'\"\n\t\t\t\tbreak\n\t\t\tcase '\\n':\n\t\t\t\tout += '\\\\n'\n\t\t\t\tbreak\n\t\t\tcase '\\r':\n\t\t\t\tout += '\\\\r'\n\t\t\t\tbreak\n\t\t\tcase '\\t':\n\t\t\t\tout += '\\\\t'\n\t\t\t\tbreak\n\t\t\tdefault: {\n\t\t\t\tconst code = char.codePointAt(0) ?? 0\n\t\t\t\t// C0/C1 controls have no visible spelling, so a raw one is invisible corruption.\n\t\t\t\t// U+2028/U+2029 have been legal inside a string literal since ES2019 and do not\n\t\t\t\t// strictly need escaping for a modern engine — they are escaped anyway because\n\t\t\t\t// they remain line terminators everywhere *else* in the grammar, and a file that\n\t\t\t\t// depends on that distinction is a poor thing to hand to an unknown toolchain.\n\t\t\t\t// Everything else rides through, so the script stays readable in the deck's language.\n\t\t\t\tconst escape = code < 0x20 || (code >= 0x7f && code <= 0x9f) || code === 0x2028 || code === 0x2029\n\t\t\t\tout += escape ? '\\\\u' + code.toString(16).padStart(4, '0') : char\n\t\t\t}\n\t\t}\n\t}\n\treturn `${out}'`\n}\n\n/**\n * A number literal. `String` gives the shortest text that reads back as the same double,\n * which is exactly the guarantee needed: the printed script must produce the same value the\n * IR held. Non-finite values cannot satisfy that (`NaN` and `Infinity` are identifiers, not\n * literals) and never reach here from a well-formed IR, so they throw rather than emit\n * source that would not run.\n */\nexport function printNumber(value: number): string {\n\tif (!Number.isFinite(value))\n\t\tthrow new InvalidOptionError('script/non-finite-literal', `Cannot print a non-finite number: ${value}`)\n\treturn String(value)\n}\n\n/** An object key, bare when it is a plain identifier and quoted when it is not. */\nfunction printKey(key: string): string {\n\treturn IDENTIFIER.test(key) ? key : printString(key)\n}\n\n/** The value on a single line, however long that line comes out. */\nfunction inline(value: IrValue, asset: AssetPrinter): string {\n\tif (value === null) return 'null'\n\tif (typeof value === 'boolean') return String(value)\n\tif (typeof value === 'number') return printNumber(value)\n\tif (typeof value === 'string') return printString(value)\n\tif (isAssetRef(value)) return asset(value)\n\tif (Array.isArray(value)) return `[${value.map((item) => inline(item, asset)).join(', ')}]`\n\n\tconst keys = Object.keys(value)\n\tif (keys.length === 0) return '{}'\n\treturn `{ ${keys.map((key) => `${printKey(key)}: ${inline(value[key] as IrValue, asset)}`).join(', ')} }`\n}\n\n/**\n * The value as source text, broken across lines only where it would otherwise overflow\n * {@link MAX_WIDTH}.\n *\n * `indentLevel` is the depth the value *starts* at, so a caller that has already written a\n * prefix (`slide1.addText(`) passes the level its closing brace should line up with.\n */\nexport function printValue(value: IrValue, indentLevel: number, asset: AssetPrinter): string {\n\tconst flat = inline(value, asset)\n\tif (indentLevel * TAB_COLUMNS + flat.length <= MAX_WIDTH) return flat\n\n\t// Only containers can be broken up; a single long string or number stays long.\n\tconst pad = '\\t'.repeat(indentLevel)\n\tconst inner = '\\t'.repeat(indentLevel + 1)\n\n\tif (Array.isArray(value)) {\n\t\tif (value.length === 0) return '[]'\n\t\tconst items = value.map((item) => `${inner}${printValue(item, indentLevel + 1, asset)},`)\n\t\treturn `[\\n${items.join('\\n')}\\n${pad}]`\n\t}\n\n\tif (typeof value === 'object' && value !== null && !isAssetRef(value)) {\n\t\tconst keys = Object.keys(value)\n\t\tif (keys.length === 0) return '{}'\n\t\tconst entries = keys.map(\n\t\t\t(key) => `${inner}${printKey(key)}: ${printValue(value[key] as IrValue, indentLevel + 1, asset)},`\n\t\t)\n\t\treturn `{\\n${entries.join('\\n')}\\n${pad}}`\n\t}\n\n\treturn flat\n}\n\n/**\n * A call's argument list, either inline after `prefix` or one argument per line.\n *\n * The decision is made on the *whole* call rather than per argument, so a call either reads\n * as one line or as a list — never as a short first argument followed by a hanging brace,\n * which is what a per-argument rule produces.\n */\nexport function printArguments(prefix: string, args: IrValue[], indentLevel: number, asset: AssetPrinter): string {\n\tconst pad = '\\t'.repeat(indentLevel)\n\tconst flat = `${pad}${prefix}(${args.map((arg) => inline(arg, asset)).join(', ')})`\n\tif (indentLevel * TAB_COLUMNS + flat.length - pad.length <= MAX_WIDTH) return flat\n\n\t// No trailing comma after the final argument: `trailingComma: 'es5'` adds them inside\n\t// objects and arrays but not to an argument list, so one here would be reformatted away.\n\tconst inner = '\\t'.repeat(indentLevel + 1)\n\tconst printed = args.map((arg) => `${inner}${printValue(arg, indentLevel + 1, asset)}`)\n\treturn `${pad}${prefix}(\\n${printed.join(',\\n')}\\n${pad})`\n}\n","/**\n * The parts of printing a script that do not depend on which tier is being printed.\n *\n * Two printers target the same IR — one anchored to the source deck as a template, one\n * standalone — and they differ only in how a deck and its chrome are set up. Everything after\n * that is identical: a slide's statements, how image bytes reach the script, and how the\n * fidelity notes are rendered into the banner. Keeping that here is not tidiness. A slide body\n * printed two slightly different ways would mean the round-trip oracle certifies one tier and\n * only resembles a check on the other, and the drift would be invisible in review.\n */\nimport type { AssetRef, DeckIr, IrValue, SlideIr } from '../ir.js'\nimport { asIrValue } from '../ir.js'\nimport type { FidelityNote } from '../fidelity.js'\nimport { type NoteCollector, scopeNotes } from '../fidelity.js'\nimport { printArguments, printString, printValue, type AssetPrinter } from './literal.js'\nimport { InvalidOptionError } from '../../errors.js'\n\n/** How image bytes reach the emitted script. */\nexport type AssetMode =\n\t/** Written beside the script and read at run time. Keeps the script readable. */\n\t| 'file'\n\t/** Inlined as `data:` literals. One self-contained file, at roughly 4/3 the byte size. */\n\t| 'inline'\n\nexport interface PrintedScript {\n\t/** The TypeScript module source. */\n\tcode: string\n\t/**\n\t * Image bytes the script expects to find in its asset directory, keyed by filename.\n\t * Empty when the print options asked for `'inline'`, since the bytes are then in\n\t * {@link code}.\n\t */\n\tassets: Map<string, Uint8Array>\n\t/**\n\t * The losses that apply to **this** output: the IR's own notes, minus any this tier\n\t * rescues, plus the ones this tier causes. Reproduced as a comment block at the top of\n\t * {@link code}, so the artifact carries its own caveats.\n\t */\n\tnotes: FidelityNote[]\n}\n\n/** Width the header comment's prose wraps at, leaving room for the ` * ` prefix. */\nconst COMMENT_WIDTH = 110\n\n/**\n * A stable JavaScript identifier per asset.\n *\n * Derived from the asset's own name rather than its index, so a reader can match a `const`\n * in the script against a file in the asset directory. The dedupe suffix is defensive: the\n * read half currently names assets `image1.png`, `image2.jpg`, … which cannot collide after\n * the extension is stripped, but nothing in the IR contract promises that.\n */\nexport function assetIdentifiers(ir: DeckIr): Map<string, string> {\n\tconst out = new Map<string, string>()\n\tconst used = new Set<string>()\n\tfor (const asset of ir.assets) {\n\t\tconst base = asset.name.replace(/\\.[^.]*$/, '').replace(/[^A-Za-z0-9_$]/g, '_')\n\t\tlet identifier = /^[A-Za-z_$]/.test(base) ? base : `_${base}`\n\t\tlet suffix = 2\n\t\twhile (used.has(identifier)) identifier = `${base}_${suffix++}`\n\t\tused.add(identifier)\n\t\tout.set(asset.name, identifier)\n\t}\n\treturn out\n}\n\n/** Resolve an {@link AssetRef} to the `const` identifier standing for its bytes. */\nexport function assetPrinter(identifiers: Map<string, string>): AssetPrinter {\n\treturn (ref: AssetRef): string => {\n\t\tconst identifier = identifiers.get(ref.$asset)\n\t\tif (!identifier)\n\t\t\tthrow new InvalidOptionError(\n\t\t\t\t'script/unresolved-asset-reference',\n\t\t\t\t`Asset reference ${ref.$asset} has no entry in DeckIr.assets`\n\t\t\t)\n\t\treturn identifier\n\t}\n}\n\n/**\n * One `const` per asset, each holding a complete `data:` URI.\n *\n * Both modes bind the same *kind* of value — a data URI string — so the call sites are\n * identical and `addImage`'s `data` option is used either way. Only where the bytes come\n * from changes. Rewriting the option key to `path` in file mode would have the printer\n * reshaping an argument, which is precisely the thing that keeps the IR checkable.\n */\nexport function printAssetBindings(\n\tir: DeckIr,\n\tidentifiers: Map<string, string>,\n\tassetDir: string,\n\tmode: AssetMode,\n\tinlineComment = '// Media bytes, inlined so this script needs no files but its template.'\n): string[] {\n\tif (ir.assets.length === 0) return []\n\n\tconst lines =\n\t\tmode === 'file' ? ['// Media bytes, loaded from the asset directory beside this script.'] : [inlineComment]\n\n\tfor (const asset of ir.assets) {\n\t\tconst identifier = identifiers.get(asset.name)\n\t\tif (!identifier) continue\n\t\tif (mode === 'file') {\n\t\t\tconst path = printString(`${assetDir}/${asset.name}`)\n\t\t\tlines.push(\n\t\t\t\t`const ${identifier} = \\`data:${asset.contentType};base64,\\${(await readFile(here(${path}))).toString('base64')}\\``\n\t\t\t)\n\t\t} else {\n\t\t\tlines.push(`const ${identifier} = ${printString(`data:${asset.contentType};base64,${toBase64(asset.bytes)}`)}`)\n\t\t}\n\t}\n\treturn lines\n}\n\n/** Base64 without `Buffer`, matching the rest of the library's isomorphic media handling. */\nfunction toBase64(bytes: Uint8Array): string {\n\tlet binary = ''\n\t// Chunked because String.fromCharCode is applied to the whole slice at once, and a\n\t// megabyte-sized spread overflows the argument limit.\n\tconst CHUNK = 0x8000\n\tfor (let i = 0; i < bytes.length; i += CHUNK) {\n\t\tbinary += String.fromCharCode(...bytes.subarray(i, i + CHUNK))\n\t}\n\treturn btoa(binary)\n}\n\n/**\n * One slide: a comment, the statement that creates it, then its slide-level properties and\n * its calls in z-order.\n *\n * `comment` and `construction` are the tier's business — one binds a layout by name at append\n * time, the other names a master up front — and everything after them is not.\n */\nexport function printSlide(\n\tslide: SlideIr,\n\tparts: { comment: string; construction: string },\n\tcollector: NoteCollector,\n\tprintAsset: AssetPrinter\n): string[] {\n\tconst notes = scopeNotes(collector, slide.number)\n\tconst identifier = `slide${slide.number}`\n\tconst lines = ['', `// ${parts.comment}`, `const ${identifier} = ${parts.construction}`]\n\n\tif (slide.name !== undefined) {\n\t\tnotes.note(\n\t\t\t'slide.name',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t`the slide's own name (p:cSld@name, here ${JSON.stringify(slide.name)}) has no public write-API setter, so the generated slide is unnamed`\n\t\t)\n\t}\n\n\tif (slide.hidden) lines.push(`${identifier}.hidden = true`)\n\tif (slide.background) {\n\t\tlines.push(`${identifier}.background = ${printValue(slide.background as IrValue, 0, printAsset)}`)\n\t}\n\tif (slide.transition) {\n\t\tlines.push(`${identifier}.transition = ${printValue(asIrValue(slide.transition), 0, printAsset)}`)\n\t}\n\tif (slide.notesText !== undefined) {\n\t\tlines.push(printArguments(`${identifier}.addNotes`, [slide.notesText], 0, printAsset))\n\t}\n\n\tfor (const call of slide.calls) {\n\t\t// The source shape name makes a fidelity note navigable: a note carries the same\n\t\t// name, and without it a reader has no way to find the call it refers to.\n\t\tif (call.sourceName) lines.push(`// ${call.sourceName.replace(/\\s+/g, ' ')}`)\n\t\tlines.push(printArguments(`${identifier}.${call.method}`, call.args, 0, printAsset))\n\t}\n\n\treturn lines\n}\n\n/** The banner comment: `prose` as written, then every loss that applies to this output. */\nexport function header(prose: string[], notes: FidelityNote[]): string {\n\tconst lines = [...prose, '']\n\n\tif (notes.length === 0) {\n\t\tlines.push('FIDELITY: nothing was lost that this converter can detect.')\n\t} else {\n\t\tlines.push(\n\t\t\t`FIDELITY: ${notes.length} declared loss(es). Everything not listed here is expected to`,\n\t\t\t'survive unchanged; a difference that is not in this list is a defect, not a caveat.',\n\t\t\t''\n\t\t)\n\t\tfor (const [scope, group] of groupNotes(notes)) {\n\t\t\tlines.push(`${scope}:`)\n\t\t\tfor (const note of group) {\n\t\t\t\tconst where = note.shapeName ? ` (${note.shapeName})` : ''\n\t\t\t\tlines.push(\n\t\t\t\t\t...wrap(\n\t\t\t\t\t\t`- ${note.construct}${where} [${note.disposition}, ${note.cause}] — ${note.detail}`,\n\t\t\t\t\t\tCOMMENT_WIDTH,\n\t\t\t\t\t\t' '\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn ['/*', ...lines.map((line) => (line ? ` * ${line}` : ' *')), ' */'].join('\\n')\n}\n\n/** Notes bucketed by slide, in deck order, so a reader meets them the way they meet the deck. */\nfunction groupNotes(notes: FidelityNote[]): Array<[string, FidelityNote[]]> {\n\tconst deckLevel = notes.filter((note) => note.slideNumber === null)\n\tconst bySlide = new Map<number, FidelityNote[]>()\n\tfor (const note of notes) {\n\t\tif (note.slideNumber === null) continue\n\t\tconst existing = bySlide.get(note.slideNumber)\n\t\tif (existing) existing.push(note)\n\t\telse bySlide.set(note.slideNumber, [note])\n\t}\n\n\tconst out: Array<[string, FidelityNote[]]> = []\n\tif (deckLevel.length > 0) out.push(['Deck', deckLevel])\n\tfor (const number of [...bySlide.keys()].sort((a, b) => a - b)) {\n\t\tout.push([`Slide ${number}`, bySlide.get(number) ?? []])\n\t}\n\treturn out\n}\n\n/** Wrap prose to `width`, indenting every line after the first by `continuation`. */\nfunction wrap(text: string, width: number, continuation: string): string[] {\n\tconst words = text.split(/\\s+/).filter(Boolean)\n\tconst lines: string[] = []\n\tlet current = ''\n\tfor (const word of words) {\n\t\tconst candidate = current ? `${current} ${word}` : `${continuation}${word}`\n\t\tif (current && candidate.length > width) {\n\t\t\tlines.push(current)\n\t\t\tcurrent = `${continuation}${word}`\n\t\t} else {\n\t\t\tcurrent = current ? candidate : word\n\t\t}\n\t}\n\tif (current) lines.push(current)\n\treturn lines\n}\n","/**\n * {@link DeckIr} → a runnable TypeScript module, template-anchored. **Tier B.**\n *\n * **The tier.** The emitted script reuses the *source deck itself* as its template:\n * `Presentation.fromTemplate` strips a package's slides while leaving its masters, layouts,\n * theme, and document properties byte-identical, so the chrome is never regenerated — it is\n * the original. Only the slides are rebuilt, through the public write API, and grafted back\n * with `appendSlides`. That is why this tier's fidelity note list is short: everything the\n * converter cannot see or cannot write is confined to slide content, and the whole of the\n * deck's design survives because nothing ever tried to reproduce it.\n *\n * It also means the plan's \"strip the source slides\" step needs no helper. `fromTemplate`\n * already does exactly that, and does it without pruning shared parts, so the template\n * asset and the source deck are the same file.\n *\n * **Order is not rearranged.** Slides are emitted in source order and every operation\n * appends, so `p:sldIdLst` comes out in the original order without any position arithmetic.\n * Contiguous slides sharing a layout share one generator, because `appendSlides` binds\n * every slide in one call to a single layout — the batching is forced by that signature,\n * not chosen for tidiness.\n *\n * **This module may add fidelity notes.** A loss can belong to the *tier* rather than to\n * the conversion — a slide's `p:cSld@name` is read fine and would survive a byte copy, but\n * has no public write-API setter, so it dies here and nowhere else. {@link PrintedScript}\n * therefore returns the notes that actually apply to *this* output, which is also the set a\n * round-trip check should exclude from its diff.\n *\n * The standalone counterpart is `printStandaloneScript` (Tier A), which prints the same IR\n * with no template at all and pays for it in the note list.\n */\nimport type { DeckIr, SlideIr } from '../ir.js'\nimport { NoteCollector, scopeNotes } from '../fidelity.js'\nimport { inches } from '../from-read/values.js'\nimport { printString, type AssetPrinter } from './literal.js'\nimport {\n\tassetIdentifiers,\n\tassetPrinter,\n\theader,\n\tprintAssetBindings,\n\tprintSlide,\n\ttype AssetMode,\n\ttype PrintedScript,\n} from './common.js'\n\nexport type { AssetMode, PrintedScript } from './common.js'\n\nexport interface PrintScriptOptions {\n\t/**\n\t * Path the emitted script loads its template from, resolved against the script's own\n\t * location. This is the **source deck unchanged** — `fromTemplate` strips its slides.\n\t * @default './template.pptx'\n\t */\n\ttemplatePath?: string\n\t/** Path the emitted script writes to, resolved against the script's own location. @default './output.pptx' */\n\toutputPath?: string\n\t/** Directory the emitted script reads image assets from, when {@link assets} is `'file'`. @default './assets' */\n\tassetDir?: string\n\t/** @default 'file' */\n\tassets?: AssetMode\n\t/**\n\t * Import specifier the emitted script uses, with `/read` appended for the read half.\n\t * Defaults to this package's own published name; override it to point a generated\n\t * script at a local build or a fork.\n\t * @default '@shbernal/ts-pptx'\n\t */\n\tpackageName?: string\n}\n\n/**\n * Constructs the IR declares lost that a template-anchored output keeps anyway.\n *\n * Document properties are the obvious case: the read half notes that only five of the twelve\n * have write-API setters, which is true and matters for a standalone output — but this tier\n * never authors them at all. They ride in the template, untouched, all twelve of them.\n *\n * The whole of the chrome is the same story on a larger scale. The theme's format scheme, the\n * master's text styles and colour map, the layouts' decoration and placeholder definitions —\n * every one of them is a genuine loss for a script that has to rebuild the deck's design, and\n * none of them is touched here, because the design *is* the template. A caveat that does not\n * apply to the output in front of you is worse than no caveat: it teaches the reader to skim\n * the ones that do.\n */\nconst TEMPLATE_CARRIED_CONSTRUCTS = new Set([\n\t'deck.docProps',\n\t'master.background',\n\t'master.colorMap',\n\t'master.decoration',\n\t'master.multiple',\n\t// Both are about a layout *title* the standalone tier has to invent — deduplicated because\n\t// it doubles as a lookup key, whitespace-collapsed because the write path emits it as a raw\n\t// XML attribute value. Here the layout keeps its own `p:cSld@name`, untouched.\n\t'master.name',\n\t'master.nameCollision',\n\t'master.placeholders',\n\t'master.txStyles',\n\t'theme.fmtScheme',\n])\n\n/**\n * Default import specifier for the emitted script — this package's *published* name, which\n * is not its directory name. Getting it wrong produces a script that prints and typechecks\n * and then fails at `import`, so it is pinned by a test rather than left to a literal here.\n */\nconst PACKAGE_NAME = '@shbernal/ts-pptx'\n\n/** Turn a deck IR into a runnable, template-anchored TypeScript module. */\nexport function printScript(ir: DeckIr, options: PrintScriptOptions = {}): PrintedScript {\n\tconst templatePath = options.templatePath ?? './template.pptx'\n\tconst outputPath = options.outputPath ?? './output.pptx'\n\tconst assetDir = (options.assetDir ?? './assets').replace(/\\/$/, '')\n\tconst assetMode = options.assets ?? 'file'\n\tconst packageName = options.packageName ?? PACKAGE_NAME\n\n\tconst collector = new NoteCollector()\n\tconst assetNames = assetIdentifiers(ir)\n\tconst printAsset = assetPrinter(assetNames)\n\n\tconst body = printSlides(ir, collector, printAsset)\n\tconst needsSource = ir.slides.some((slide) => slide.source === 'carried')\n\tconst needsFallbackLayout = ir.slides.some((slide) => slide.source === 'authored' && slide.layout === null)\n\n\t// Built last: the tier's own notes are only known once the slides have been walked.\n\tconst notes = [...ir.fidelity.filter((note) => !TEMPLATE_CARRIED_CONSTRUCTS.has(note.construct)), ...collector.notes]\n\n\tconst lines: string[] = [\n\t\theader(\n\t\t\t[\n\t\t\t\t'Generated from a .pptx by ts-pptx/script.',\n\t\t\t\t'',\n\t\t\t\t'Template-anchored: the source deck is reused as the template, so its slide masters,',\n\t\t\t\t'layouts, theme and document properties are the originals, byte for byte. Only the',\n\t\t\t\t'slide content below was rebuilt through the public write API.',\n\t\t\t\t'',\n\t\t\t\t`Expects ${templatePath} (the source deck, unmodified) beside this file${\n\t\t\t\t\tassetMode === 'file' && ir.assets.length > 0 ? `, plus ${ir.assets.length} media file(s) in ${assetDir}` : ''\n\t\t\t\t}.`,\n\t\t\t\t`Writes ${outputPath}. Needs an ESM context — it uses top-level await.`,\n\t\t\t],\n\t\t\tnotes\n\t\t),\n\t\t'',\n\t\t\"import { readFile, writeFile } from 'node:fs/promises'\",\n\t\t\"import { fileURLToPath } from 'node:url'\",\n\t\t`import TsPptx from ${printString(packageName)}`,\n\t\t`import { Presentation } from ${printString(`${packageName}/read`)}`,\n\t\t'',\n\t\t'/** Resolve a path against this script rather than against the working directory. */',\n\t\t'const here = (name: string): string => fileURLToPath(new URL(name, import.meta.url))',\n\t\t'',\n\t\t'// The source deck is the template: fromTemplate strips its slides and leaves its masters,',\n\t\t'// layouts, theme and document properties exactly as they were.',\n\t\t`const deck = await Presentation.fromTemplate(here(${printString(templatePath)}))`,\n\t]\n\n\tif (needsSource) {\n\t\tlines.push(\n\t\t\t'',\n\t\t\t'// A second, unstripped handle on the same file, for the slides copied verbatim.',\n\t\t\t`const source = await Presentation.load(here(${printString(templatePath)}))`\n\t\t)\n\t}\n\n\tif (needsFallbackLayout) {\n\t\tlines.push(\n\t\t\t'',\n\t\t\t'// Some source slides resolved no layout of their own; they bind to the first one.',\n\t\t\t'const fallbackLayout = deck.layouts()[0]',\n\t\t\t\"if (!fallbackLayout) throw new Error('the template declares no slide layouts to bind to')\"\n\t\t)\n\t}\n\n\tconst assetLines = printAssetBindings(ir, assetNames, assetDir, assetMode)\n\tif (assetLines.length > 0) lines.push('', ...assetLines)\n\n\tlines.push(\n\t\t'',\n\t\t'/**',\n\t\t' * A generator sized to the template. appendSlides compares slide sizes exactly and',\n\t\t' * throws when they differ, so the inches here must round-trip to the source EMU.',\n\t\t' */',\n\t\t'function generator(): TsPptx {',\n\t\t'\\tconst pptx = new TsPptx()',\n\t\t`\\tpptx.defineLayout({ name: 'source', width: ${inches(ir.slideSize.widthEmu)}, height: ${inches(ir.slideSize.heightEmu)} })`,\n\t\t\"\\tpptx.layout = 'source'\",\n\t\t'\\treturn pptx',\n\t\t'}',\n\t\t...body,\n\t\t'',\n\t\t`await writeFile(here(${printString(outputPath)}), await deck.save())`,\n\t\t''\n\t)\n\n\treturn {\n\t\tcode: lines.join('\\n'),\n\t\tassets: new Map(\n\t\t\tassetMode === 'file' ? ir.assets.map((asset): [string, Uint8Array] => [asset.name, asset.bytes]) : []\n\t\t),\n\t\tnotes,\n\t}\n}\n\n/**\n * The slide statements, batched into generators.\n *\n * A batch ends when the layout changes or a carried slide interrupts, because\n * `appendSlides` binds one layout per call and a carried slide is not authored at all.\n */\nfunction printSlides(ir: DeckIr, collector: NoteCollector, printAsset: AssetPrinter): string[] {\n\tconst lines: string[] = []\n\tlet batch: SlideIr[] = []\n\tlet generatorIndex = 0\n\t// Two non-contiguous batches can share one layout, so its `const` must be emitted once.\n\tconst declaredLayouts = new Set<number>()\n\n\tconst flush = (): void => {\n\t\tif (batch.length === 0) return\n\t\tconst first = batch[0]\n\t\tif (!first) return\n\t\tconst name = `gen${++generatorIndex}`\n\t\tlines.push('', `const ${name} = generator()`)\n\t\tfor (const slide of batch) lines.push(...printAuthoredSlide(slide, name, collector, printAsset))\n\t\tlines.push('', ...printAppend(name, first, collector, declaredLayouts))\n\t\tbatch = []\n\t}\n\n\tfor (const slide of ir.slides) {\n\t\tif (slide.source === 'carried') {\n\t\t\tflush()\n\t\t\tlines.push(\n\t\t\t\t'',\n\t\t\t\t`// Slide ${slide.number} — copied from the source deck rather than rebuilt; see the fidelity notes.`,\n\t\t\t\t`deck.importSlide(source, ${slide.number - 1})`\n\t\t\t)\n\t\t\tcontinue\n\t\t}\n\t\t// A batch is one appendSlides call, which binds every slide in it to one layout.\n\t\tconst previous = batch[0]\n\t\tif (previous && previous.layout?.index !== slide.layout?.index) flush()\n\t\tbatch.push(slide)\n\t}\n\tflush()\n\n\treturn lines\n}\n\n/**\n * The `appendSlides` call closing a batch, binding by layout name where that is\n * unambiguous and by gallery position where it is not.\n *\n * Binding by name is preferred because it survives being re-pointed at a different\n * template and because it is legible. But `appendSlides` *throws* on an ambiguous name\n * rather than picking one, and a multi-master deck routinely repeats layout names, so the\n * positional form is the only thing that resolves there.\n */\nfunction printAppend(generatorName: string, first: SlideIr, collector: NoteCollector, declared: Set<number>): string[] {\n\tconst layout = first.layout\n\tif (!layout) return [`await deck.appendSlides(${generatorName}, { layout: fallbackLayout })`]\n\tif (layout.nameIsUnique) {\n\t\treturn [`await deck.appendSlides(${generatorName}, { layout: ${printString(layout.name)} })`]\n\t}\n\n\tscopeNotes(collector, first.number).note(\n\t\t'slide.layout',\n\t\t'approximated',\n\t\t'unsupported',\n\t\t`more than one layout in the source deck is named ${JSON.stringify(layout.name)}, so this slide binds to gallery position ${layout.index} instead; re-pointing the script at a different template will not track the name`\n\t)\n\tconst identifier = `layout${layout.index}`\n\tconst append = `await deck.appendSlides(${generatorName}, { layout: ${identifier} })`\n\tif (declared.has(layout.index)) return [append]\n\tdeclared.add(layout.index)\n\treturn [\n\t\t`const ${identifier} = deck.layouts()[${layout.index}] // ${JSON.stringify(layout.name)}`,\n\t\t`if (!${identifier}) throw new Error('the template has no layout at position ${layout.index}')`,\n\t\tappend,\n\t]\n}\n\n/** One authored slide, plus the layout-binding note this tier is responsible for. */\nfunction printAuthoredSlide(\n\tslide: SlideIr,\n\tgeneratorName: string,\n\tcollector: NoteCollector,\n\tprintAsset: AssetPrinter\n): string[] {\n\tif (slide.layout === null) {\n\t\tscopeNotes(collector, slide.number).note(\n\t\t\t'slide.layout',\n\t\t\t'approximated',\n\t\t\t'unsupported',\n\t\t\t\"this slide resolves no layout of its own, so it binds to the template's first layout; that governs theme and clrMap resolution, which may differ from the source\"\n\t\t)\n\t}\n\n\t// A tier loss, and a narrow one: a transition's *stop-previous* form needs no relationship\n\t// and rides across fine, while an embedded start sound needs an audio part wired to the\n\t// appended slide. `extractSlides` never runs the registration pass that assigns it a\n\t// relationship id (`registerTransitionSounds` belongs to the package-assembly path), so the\n\t// emitter finds no `_sndRId` and writes no `p:sndAc` at all. That is a silent drop rather\n\t// than a dangling reference — which is the safe failure of the two, and still a loss the\n\t// reader has to be told about. The standalone tier writes a real package and keeps it.\n\tif (slide.transition?.sound?.data !== undefined) {\n\t\tscopeNotes(collector, slide.number).note(\n\t\t\t'slide.transitionSound',\n\t\t\t'dropped',\n\t\t\t'unsupported',\n\t\t\t\"this transition's start sound is dropped: the append path this tier rides does not register a transition's embedded audio part, so the sound does not reach the template. The assignment below still spells it out, and the WAV still ships beside the script, because both describe the source deck faithfully and would take effect the day the append path carries them — but this output is silent. Print the standalone variant to keep the sound\"\n\t\t)\n\t}\n\n\tconst layout = slide.layout === null ? 'no layout' : `layout ${JSON.stringify(slide.layout.name)}`\n\treturn printSlide(\n\t\tslide,\n\t\t{ comment: `Slide ${slide.number} — ${layout}`, construction: `${generatorName}.addSlide()` },\n\t\tcollector,\n\t\tprintAsset\n\t)\n}\n","/**\n * {@link DeckIr} → a runnable TypeScript module that depends on nothing but this package.\n * **Tier A.**\n *\n * **The trade, stated once.** The template-anchored printer (`printScript`) reuses the source\n * `.pptx` and gets the deck's entire design back byte for byte, at the cost of shipping that\n * file alongside the script and of leaving the design uneditable. This one ships a single\n * `.ts` file. Everything the source deck's chrome contained has to be *re-authored* from what\n * the read model exposes, and the read model deliberately exposes the property tiers a slide\n * inherits — colours, fonts, placeholder geometry — not the parts a slide merely sits on top\n * of. So the output is a deck that renders its slides faithfully and wears a different suit.\n *\n * **The ceiling is measured, not estimated, and no amount of printer work moves it.** Three\n * constructs are unreachable from *both* directions: `a:fmtScheme` (nothing reads it, and the\n * write path emits a hardcoded Office one), `p:txStyles` (no reader, though\n * `SlideMasterProps.textStyles` could author it), and master/layout decoration (documented as\n * out of the read model's scope, carried byte-for-byte by the import paths instead). A fourth,\n * `p:clrMap`, is readable and has no setter. Each is a fidelity note here and a `pass` in the\n * other tier, which is the whole reason the other tier shipped first.\n *\n * **One structural difference beyond the chrome.** A slide marked `carried` has no source\n * package to be carried from here, so it is transcribed like any other and loses only the\n * construct that made it uncarryable — which each shape has already declared for itself. That\n * is why {@link DeckIr}'s calls are populated even for a carried slide.\n */\nimport type { DeckIr, IrValue, MasterIr } from '../ir.js'\nimport { NoteCollector, scopeNotes } from '../fidelity.js'\nimport { inches } from '../from-read/values.js'\nimport { printArguments, printString, printValue, type AssetPrinter } from './literal.js'\nimport {\n\tassetIdentifiers,\n\tassetPrinter,\n\theader,\n\tprintAssetBindings,\n\tprintSlide,\n\ttype AssetMode,\n\ttype PrintedScript,\n} from './common.js'\n\nexport interface PrintStandaloneScriptOptions {\n\t/** Path the emitted script writes to, resolved against the script's own location. @default './output.pptx' */\n\toutputPath?: string\n\t/** Directory the emitted script reads image assets from, when {@link assets} is `'file'`. @default './assets' */\n\tassetDir?: string\n\t/** @default 'file' */\n\tassets?: AssetMode\n\t/**\n\t * Import specifier the emitted script uses. Defaults to this package's own published\n\t * name; override it to point a generated script at a local build or a fork.\n\t * @default '@shbernal/ts-pptx'\n\t */\n\tpackageName?: string\n}\n\n/**\n * Notes the IR declares that do not describe *this* output.\n *\n * Only one, and it is the mirror of the other tier's list. `slide.carried` says a slide will\n * be copied from the source package rather than transcribed; there is no source package here,\n * so the slide is transcribed and the construct that made it uncarryable has already recorded\n * its own note. Reporting both would double-count one loss and describe a behaviour this\n * script does not have.\n */\nconst NOT_APPLICABLE = new Set(['slide.carried'])\n\n/** See `printScript` — the published name is not the directory name, and a test pins it. */\nconst PACKAGE_NAME = '@shbernal/ts-pptx'\n\n/** Turn a deck IR into a runnable TypeScript module that needs no template. */\nexport function printStandaloneScript(ir: DeckIr, options: PrintStandaloneScriptOptions = {}): PrintedScript {\n\tconst outputPath = options.outputPath ?? './output.pptx'\n\tconst assetDir = (options.assetDir ?? './assets').replace(/\\/$/, '')\n\tconst assetMode = options.assets ?? 'file'\n\tconst packageName = options.packageName ?? PACKAGE_NAME\n\n\tconst collector = new NoteCollector()\n\tconst assetNames = assetIdentifiers(ir)\n\tconst printAsset = assetPrinter(assetNames)\n\n\t// Walked before the header is built: this tier's own notes are only known afterwards.\n\tconst masters = printMasters(ir, collector, printAsset)\n\tconst body = printSlides(ir, collector, printAsset)\n\tconst notes = [...ir.fidelity.filter((note) => !NOT_APPLICABLE.has(note.construct)), ...collector.notes]\n\n\tconst needsReadFile = assetMode === 'file' && ir.assets.length > 0\n\tconst lines: string[] = [\n\t\theader(\n\t\t\t[\n\t\t\t\t'Generated from a .pptx by ts-pptx/script.',\n\t\t\t\t'',\n\t\t\t\t`Standalone: this script needs nothing but ${packageName}${\n\t\t\t\t\tneedsReadFile ? ` and ${ir.assets.length} media file(s) in ${assetDir}` : ''\n\t\t\t\t}.`,\n\t\t\t\t\"The deck's theme, layouts and slide content are all re-authored through the public write\",\n\t\t\t\t'API, so every one of them is editable here — and the parts of the original design the read',\n\t\t\t\t'model cannot see are gone. They are listed below. For a byte-identical design at the cost',\n\t\t\t\t'of shipping the source deck alongside the script, print the template-anchored variant',\n\t\t\t\t'instead.',\n\t\t\t\t'',\n\t\t\t\t`Writes ${outputPath}. Needs an ESM context — it uses top-level await.`,\n\t\t\t],\n\t\t\tnotes\n\t\t),\n\t\t'',\n\t\t...(needsReadFile ? [\"import { readFile } from 'node:fs/promises'\"] : []),\n\t\t\"import { fileURLToPath } from 'node:url'\",\n\t\t`import TsPptx from ${printString(packageName)}`,\n\t\t'',\n\t\t'/** Resolve a path against this script rather than against the working directory. */',\n\t\t'const here = (name: string): string => fileURLToPath(new URL(name, import.meta.url))',\n\t\t'',\n\t\t'const pptx = new TsPptx()',\n\t\t`pptx.defineLayout({ name: 'source', width: ${inches(ir.slideSize.widthEmu)}, height: ${inches(ir.slideSize.heightEmu)} })`,\n\t\t\"pptx.layout = 'source'\",\n\t]\n\n\tconst theme = ir.chrome.theme as IrValue\n\tif (Object.keys(ir.chrome.theme).length > 0) {\n\t\tlines.push(\n\t\t\t'',\n\t\t\t\"// The theme's colour scheme and font faces. Its format scheme — the fill, line and effect\",\n\t\t\t'// style lists a shape references through p:style — has no counterpart on either side of the',\n\t\t\t\"// library, so the output carries Office's.\",\n\t\t\t`pptx.theme = ${printValue(theme, 0, printAsset)}`\n\t\t)\n\t}\n\n\tconst props = printDocProps(ir, collector)\n\tif (props.length > 0) lines.push('', ...props)\n\n\tconst assetLines = printAssetBindings(\n\t\tir,\n\t\tassetNames,\n\t\tassetDir,\n\t\tassetMode,\n\t\t'// Media bytes, inlined so this script is a single self-contained file.'\n\t)\n\tif (assetLines.length > 0) lines.push('', ...assetLines)\n\n\tif (masters.length > 0) lines.push('', ...masters)\n\tlines.push(...body, '', `await pptx.writeFile({ fileName: here(${printString(outputPath)}) })`, '')\n\n\treturn {\n\t\tcode: lines.join('\\n'),\n\t\tassets: new Map(\n\t\t\tassetMode === 'file' ? ir.assets.map((asset): [string, Uint8Array] => [asset.name, asset.bytes]) : []\n\t\t),\n\t\tnotes,\n\t}\n}\n\n/**\n * The document properties the write API can set.\n *\n * Four of the twelve the read model exposes, which is the loss `deck.docProps` already\n * declares — and unlike the template-anchored tier, here it is a real one, because nothing\n * else carries them.\n */\nfunction printDocProps(ir: DeckIr, collector: NoteCollector): string[] {\n\tconst entries = Object.entries(ir.props).filter(([, value]) => typeof value === 'string')\n\n\t// A deck built through the write API is stamped with the library's own author, company,\n\t// subject, title and revision in the constructor, and a property cannot be unset — writing\n\t// `''` emits an empty element rather than removing it. So whatever the source left blank\n\t// comes back filled in, which is a change to the deck rather than a formatting detail.\n\tconst stamped = ['title', 'author', 'company', 'subject', 'revision'].filter((key) => !(key in ir.props))\n\tif (stamped.length > 0) {\n\t\tscopeNotes(collector, null).note(\n\t\t\t'deck.docPropsDefault',\n\t\t\t'approximated',\n\t\t\t'unwritable',\n\t\t\t`the source deck declares no ${stamped.join(', ')}, and a deck built through the write API is stamped with the library's own value for each in its constructor with no way to unset it, so the output declares ${stamped.length === 1 ? 'one' : 'these'} the source did not`\n\t\t)\n\t}\n\n\tif (entries.length === 0) return []\n\treturn [\n\t\t'// Document properties. Only these have write-API setters; see the fidelity notes.',\n\t\t...entries.map(([key, value]) => `pptx.${key} = ${printString(value as string)}`),\n\t]\n}\n\n/**\n * One `defineSlideMaster` per source layout.\n *\n * The naming is the write API's rather than OOXML's: a `defineSlideMaster` call creates a\n * *layout* under the single shared master, which is the right granularity for a source layout.\n * What it carries is thin by measurement, not by choice — a layout's decoration and its\n * placeholder definitions are both out of reach (see `from-read/chrome.ts`), leaving the name\n * and the background. The name still earns its place: it is what `addSlide({ masterTitle })`\n * binds on, so the deck keeps a layout gallery a reader recognises.\n */\nfunction printMasters(ir: DeckIr, collector: NoteCollector, printAsset: AssetPrinter): string[] {\n\t// Recorded before the early return, because the extra layout is there either way: it is\n\t// seeded in the constructor, not by anything printed below. Scoped to that layout's own\n\t// title rather than deck-wide, because the round trip matches a note's `shapeName` against\n\t// the identity of what differed, and an unscoped note would declare *any* extra layout.\n\tscopeNotes(collector, null, 'DEFAULT').note(\n\t\t'master.default',\n\t\t'approximated',\n\t\t'unsupported',\n\t\t\"the write path seeds every presentation with a blank layout of its own named DEFAULT, and there is no way to remove it, so the output deck's layout gallery carries one extra entry ahead of the source's layouts; nothing binds to it, but it is visible in PowerPoint's layout picker\"\n\t)\n\tif (ir.chrome.masters.length === 0) return []\n\treturn [\n\t\t'// One master per source layout. A layout that carried decoration or placeholder',\n\t\t'// definitions has lost them — the read model decodes neither; see the fidelity notes.',\n\t\t...ir.chrome.masters.map((master) => printArguments('pptx.defineSlideMaster', [master.props], 0, printAsset)),\n\t]\n}\n\n/** Every slide, in source order, each bound to the master its source layout became. */\nfunction printSlides(ir: DeckIr, collector: NoteCollector, printAsset: AssetPrinter): string[] {\n\tconst byLayout = new Map<number, MasterIr>()\n\tfor (const master of ir.chrome.masters) byLayout.set(master.layoutIndex, master)\n\n\tconst lines: string[] = []\n\tfor (const slide of ir.slides) {\n\t\tconst master = slide.layout === null ? undefined : byLayout.get(slide.layout.index)\n\t\tconst title = typeof master?.props['title'] === 'string' ? master.props['title'] : null\n\n\t\tif (title === null) {\n\t\t\tscopeNotes(collector, slide.number).note(\n\t\t\t\t'slide.layout',\n\t\t\t\t'approximated',\n\t\t\t\t'unsupported',\n\t\t\t\tslide.layout === null\n\t\t\t\t\t? \"this slide resolves no layout of its own, so it binds to the write path's default blank layout\"\n\t\t\t\t\t: `this slide's source layout (gallery position ${slide.layout.index}) produced no master to bind to, so it binds to the write path's default blank layout`\n\t\t\t)\n\t\t}\n\n\t\tlines.push(\n\t\t\t...printSlide(\n\t\t\t\tslide,\n\t\t\t\t{\n\t\t\t\t\tcomment: `Slide ${slide.number} — ${title === null ? 'no master' : `master ${JSON.stringify(title)}`}`,\n\t\t\t\t\tconstruction: title === null ? 'pptx.addSlide()' : `pptx.addSlide({ masterTitle: ${printString(title)} })`,\n\t\t\t\t},\n\t\t\t\tcollector,\n\t\t\t\tprintAsset\n\t\t\t)\n\t\t)\n\t}\n\treturn lines\n}\n","/**\n * A {@link DeckIr} reduced to the form a round-trip diff can compare.\n *\n * The round trip is `source → IR₁ → script → deck → IR₂`. Comparing those two IRs raw\n * produces thousands of differences, almost none of which are losses: the write path\n * spells out defaults that OOXML leaves implicit, and PowerPoint spells out defaults the\n * write path leaves implicit. Both directions are noise, and drowning the real losses in\n * it is the same as not checking at all.\n *\n * **Every rule here must be an equivalence, not a convenience.** A rule that merely makes\n * the report shorter hides a defect permanently and silently — the exact failure mode this\n * subsystem exists to catch. So each one below cites the OOXML default that makes the\n * explicit and the absent spelling mean the same thing, and none of them drops a value that\n * a viewer could render differently. When in doubt the value stays in and the difference is\n * reported: a noisy report is recoverable, a quiet one is not.\n *\n * Canonicalising is deliberately *symmetric* — it runs over both IRs, so it cannot favour\n * the output. A rule that only made sense in one direction would be an exclusion dressed up\n * as a normalisation.\n */\nimport type { AssetIr, DeckIr, IrValue, SlideIr } from '../ir.js'\nimport { asIrValue, isAssetRef } from '../ir.js'\n\n/** One write-API call, with the source shape name lifted out as an address rather than data. */\nexport interface CanonicalCall {\n\tmethod: string\n\t/** `p:cNvPr/@name` of the shape this call came from, used to point a difference at it. */\n\tshapeName: string | null\n\t/**\n\t * Every `objectName` appearing anywhere inside {@link args}, which for `addGroup` is the\n\t * group's children.\n\t *\n\t * A fidelity note about a group's child is scoped to that child's name, but the child is\n\t * not a call of its own — it is an argument to the group's. Without this the note and the\n\t * difference it predicted would carry different names and never match, and a declared loss\n\t * would be reported as a defect.\n\t */\n\tcontainedNames: string[]\n\targs: IrValue[]\n}\n\nexport interface CanonicalSlide {\n\tnumber: number\n\thidden: boolean\n\t/**\n\t * The name of the layout this slide binds to, which is the only part of the binding that\n\t * is portable — a gallery *index* shifts whenever the output's gallery differs from the\n\t * source's, which it always does for a standalone output.\n\t *\n\t * Here because the binding is otherwise invisible: a printer that bound every slide to the\n\t * wrong layout, or to none, would produce identical calls and compare clean. The layout\n\t * governs theme and colour-map resolution, so that is not a cosmetic difference.\n\t */\n\tlayoutName: string | null\n\tbackground: IrValue | null\n\tnotesText: string | null\n\t/**\n\t * The show transition, or `null`.\n\t *\n\t * Here for the same reason {@link layoutName} is: a printer that stopped emitting\n\t * transitions altogether would produce identical *calls* and compare clean, so the\n\t * projection has to carry the slide-level properties the write API sets by assignment\n\t * rather than by method. It is compared structurally (key by key), not as one opaque\n\t * value, so a note can declare the loss of a transition's *sound* without also excusing a\n\t * wrong transition *type*.\n\t */\n\ttransition: IrValue | null\n\tcalls: CanonicalCall[]\n}\n\n/**\n * The deck's chrome, reduced the same way its slides are.\n *\n * Included for one reason: without it the diff cannot see the standalone tier's whole job.\n * That tier re-authors the theme and one master per source layout, and a projection that\n * covers only slides would report a printer emitting *neither* as a clean round trip — the\n * same shape of hole mutation testing found in `added` differences, one level up. A\n * template-anchored output compares equal here by construction, which is the claim that tier\n * makes and is worth checking rather than assuming.\n */\nexport interface CanonicalChrome {\n\ttheme: IrValue\n\t/** Each master's `defineSlideMaster` props, in gallery order. */\n\tmasters: IrValue[]\n}\n\nexport interface CanonicalDeck {\n\tslideSize: { widthEmu: number; heightEmu: number }\n\t/** The `docProps` the write API can set. Absent from the projection, a printer that set none would compare clean. */\n\tprops: IrValue\n\tchrome: CanonicalChrome\n\tslides: CanonicalSlide[]\n}\n\n/**\n * Option values that mean exactly what their absence means.\n *\n * Keyed by option name because the IR's argument objects are the write API's own option\n * objects, where a name identifies a construct uniquely — there is no `bold` that means\n * something other than `a:rPr/@b`.\n *\n * Each entry is an OOXML default:\n *\n * - `bold`, `italic` — `a:rPr/@b` / `@i` are `ST_OnOff`, default `false`.\n * - `baseline` — `a:rPr/@baseline` is a percentage, default `0` (no super/subscript).\n * - `breakLine` — not OOXML but the IR's own flat encoding: a run that does not end its\n * paragraph. The final run of a text frame never carries one, so absent and `false` are\n * the same statement.\n * - `wrap` — `a:bodyPr/@wrap` defaults to `square`, which the write API spells `true`.\n * - `rotate` — `a:xfrm/@rot` defaults to `0`.\n * - `flipH`, `flipV` — `a:xfrm/@flipH` / `@flipV` default to `false`.\n * - `transparency` — an alpha of 0% removed, i.e. fully opaque, which is also the default\n * when no `a:alpha` transform is present.\n * - `indentLevel` — `a:p/@lvl` defaults to `0`.\n * - `dashType` — `a:ln`'s dash defaults to `solid` when no `a:prstDash` is present.\n *\n * Line width is deliberately **absent**: `a:ln/@w` defaults to 0 (hairline) while the write\n * path defaults it to 1pt, so those two are not the same line and the difference is real.\n */\nconst IMPLIED_DEFAULTS: Record<string, IrValue> = {\n\tbold: false,\n\titalic: false,\n\tbaseline: 0,\n\tbreakLine: false,\n\twrap: true,\n\trotate: 0,\n\tflipH: false,\n\tflipV: false,\n\ttransparency: 0,\n\tindentLevel: 0,\n\tdashType: 'solid',\n}\n\n/**\n * `a:bodyPr`'s default insets in inches, in the write API's `[top, right, bottom, left]`\n * order: 45720 EMU (0.05in, 3.6pt) top and bottom, 91440 EMU (0.1in, 7.2pt) left and right.\n * A body that spells them out is inset exactly as one that omits them.\n */\nconst DEFAULT_MARGIN: readonly number[] = [0.05, 0.1, 0.05, 0.1]\n\n/** Reduce a deck IR to the comparable form. */\nexport function canonicalDeckIr(ir: DeckIr): CanonicalDeck {\n\tconst digests = assetDigests(ir.assets)\n\treturn {\n\t\tslideSize: ir.slideSize,\n\t\tprops: canonicalValue(ir.props as IrValue, digests),\n\t\tchrome: {\n\t\t\ttheme: canonicalValue(ir.chrome.theme as IrValue, digests),\n\t\t\tmasters: ir.chrome.masters.map((master) => canonicalValue(master.props, digests)),\n\t\t},\n\t\tslides: ir.slides.map((slide) => canonicalSlide(slide, digests)),\n\t}\n}\n\nfunction canonicalSlide(slide: SlideIr, digests: Map<string, string>): CanonicalSlide {\n\treturn {\n\t\tnumber: slide.number,\n\t\thidden: slide.hidden,\n\t\tlayoutName: slide.layout?.name ?? null,\n\t\tbackground: slide.background === undefined ? null : canonicalValue(slide.background as IrValue, digests),\n\t\tnotesText: slide.notesText ?? null,\n\t\ttransition: slide.transition === undefined ? null : canonicalValue(asIrValue(slide.transition), digests),\n\t\tcalls: slide.calls.map((call) => {\n\t\t\tconst args = call.args.map((arg) => canonicalValue(arg, digests))\n\t\t\treturn {\n\t\t\t\tmethod: call.method,\n\t\t\t\tshapeName: call.sourceName ?? null,\n\t\t\t\tcontainedNames: [...collectObjectNames(args, new Set())],\n\t\t\t\targs,\n\t\t\t}\n\t\t}),\n\t}\n}\n\n/** Every `objectName` value reachable in `value`, at any depth. */\nfunction collectObjectNames(value: IrValue, out: Set<string>): Set<string> {\n\tif (Array.isArray(value)) {\n\t\tfor (const item of value) collectObjectNames(item, out)\n\t\treturn out\n\t}\n\tif (value === null || typeof value !== 'object') return out\n\tfor (const [key, item] of Object.entries(value)) {\n\t\tif (key === 'objectName' && typeof item === 'string') out.add(item)\n\t\telse collectObjectNames(item as IrValue, out)\n\t}\n\treturn out\n}\n\n/**\n * Recursively drop implied defaults and resolve asset references to a content digest.\n *\n * The digest matters more than it looks: assets are named `image1.png`, `image2.png`, … in\n * the order the walk meets them, and the output deck can meet the same bytes in a different\n * order or under a different extension. Comparing names would report a swap that did not\n * happen and, worse, would *miss* one where two images traded places.\n */\nfunction canonicalValue(value: IrValue, digests: Map<string, string>): IrValue {\n\tif (isAssetRef(value)) return { $asset: digests.get(value.$asset) ?? `unknown:${value.$asset}` }\n\tif (Array.isArray(value)) return value.map((item) => canonicalValue(item, digests))\n\tif (value === null || typeof value !== 'object') return value\n\n\t// A run with no characters has no colour anyone can see, and the write path gives every\n\t// run it emits an explicit one. Narrowed to `color` deliberately: a size or a bullet on an\n\t// empty paragraph still affects line height and still draws a glyph, so those stay.\n\tconst blankRun = value['text'] === '' && typeof value['options'] === 'object' && value['options'] !== null\n\n\tconst out: Record<string, IrValue> = {}\n\tfor (const [key, item] of Object.entries(value)) {\n\t\tif (key in IMPLIED_DEFAULTS && item === IMPLIED_DEFAULTS[key]) continue\n\t\tif (key === 'margin' && isDefaultMargin(item)) continue\n\t\tif (blankRun && key === 'options') {\n\t\t\tconst visible = { ...(item as Record<string, IrValue>) }\n\t\t\tdelete visible['color']\n\t\t\tout[key] = canonicalValue(visible, digests)\n\t\t\tcontinue\n\t\t}\n\t\tout[key] = canonicalValue(item, digests)\n\t}\n\treturn out\n}\n\nfunction isDefaultMargin(value: IrValue): boolean {\n\treturn (\n\t\tArray.isArray(value) &&\n\t\tvalue.length === DEFAULT_MARGIN.length &&\n\t\tvalue.every((item, index) => item === DEFAULT_MARGIN[index])\n\t)\n}\n\n/**\n * Content digests keyed by asset name, so the same bytes compare equal under any name.\n *\n * FNV-1a rather than a real hash: this identifies bytes for a comparison both sides of\n * which are in hand, so collision resistance against an adversary is not a property it\n * needs, and the library stays free of `node:crypto` and of the isomorphism problem\n * importing it would create.\n */\nfunction assetDigests(assets: AssetIr[]): Map<string, string> {\n\tconst out = new Map<string, string>()\n\tfor (const asset of assets) {\n\t\tlet hash = 0x811c9dc5\n\t\tfor (const byte of asset.bytes) {\n\t\t\thash ^= byte\n\t\t\thash = Math.imul(hash, 0x01000193) >>> 0\n\t\t}\n\t\tout.set(asset.name, `${asset.bytes.length}:${hash.toString(16)}`)\n\t}\n\treturn out\n}\n","/**\n * The round-trip oracle: does the deck a printed script builds match the deck it was read\n * from, everywhere the fidelity notes did not say it would not?\n *\n * **Why a projection diff and not byte identity.** The output package is not the input\n * package and never will be — different rel ids, different shape ids, a regenerated shape\n * tree, `dirty=\"0\"` on every run. Comparing bytes would report a total mismatch for every\n * deck and prove nothing. So the comparison happens one level up, on the IR: run the same\n * `readModelToIr` over the source deck and over the deck the script produced, and compare\n * those. Two decks that produce the same IR make the same write-API calls, which is exactly\n * the claim a generated script makes.\n *\n * **What a note is worth here.** A {@link FidelityNote} says a named construct will not\n * survive. That makes it an *exclusion with a signature*: the difference it predicts is\n * allowed, and every other difference is a defect. Without the notes there would be no way\n * to tell a known cost from a regression, and the check could only ever be a snapshot.\n *\n * **Two blind spots, both stated plainly, because a clean report is worth exactly what its\n * limits allow.**\n *\n * 1. *The reader is shared.* Both IRs come from `readModelToIr`, so a construct the read\n * model cannot see is missing from both and compares equal. This check cannot certify\n * anything the read path does not read; `pnpm run read:census` measures that surface, and\n * the two are complementary rather than overlapping.\n * 2. *The converter need not be injective.* Two different source constructs can map to the\n * same call, and then the round trip agrees while the deck has changed. Measured, not\n * hypothetical: the mapper once read an explicit `a:buNone` as the glyph `n`, so a\n * bulletless paragraph gained a bullet — and because the output's real `n` bullet read\n * back through the same wrong mapping, the diff was clean. Mutation testing is what\n * catches that class, and a mutation that survives here is a statement about this\n * check's reach rather than a mistake in it.\n *\n * A clean report means \"nothing the converter can distinguish was lost\", never \"nothing was\n * lost\".\n */\nimport type { FidelityNote } from '../fidelity.js'\nimport type { CanonicalCall, CanonicalChrome, CanonicalDeck, CanonicalSlide } from './canonical.js'\nimport type { IrValue } from '../ir.js'\n\n/**\n * Which way a difference points.\n *\n * `lost` and `changed` are the ones the fidelity contract governs — the source said\n * something the output does not, or says differently. `added` is the write path being\n * explicit where the source was implicit, which is *usually* harmless and is reported\n * separately for a reason worth stating: this diff cannot tell whether the value the write\n * path chose is the one the source was inheriting. An `added` `color` is benign if the\n * shape was inheriting that colour and a silent repaint if it was not.\n */\nexport type DifferenceKind = 'lost' | 'added' | 'changed'\n\n/**\n * Options the write path materialises that the source deck left implicit, with the reason\n * each is not judgeable from here.\n *\n * This list exists because `added` differences cannot simply be waved through. Mutation\n * testing settled that: dropping the converter's explicit `valign` left the write path to\n * centre every text body, which showed up as an `added` and nothing failed. So `added` is\n * held to the same standard as the rest — a note must declare it, or its field must appear\n * here with a reason.\n *\n * Every entry names a write-path default whose *correctness* the round trip has no way to\n * assess, because the source's counterpart was inherited and the read model cannot resolve\n * what it was inheriting. That is an honest \"unknown\", not an \"ignore\" — each one is a\n * candidate for the read-side backlog, and closing any of them turns its entry into a real\n * comparison.\n */\nconst WRITER_DEFAULTS: Record<string, string> = {\n\t// The write path copies the object-level and first-run character properties onto every\n\t// run it emits. The source's bare runs inherited theirs from the list style, which is\n\t// unread, so there is nothing to compare the copied value against.\n\tfontSize: 'runs inherit size from an unread list style; the write path copies the shape size onto each run',\n\toptions: 'a run or cell that carried no options at all in the source now carries the ones below',\n\t// `a:tcBdr` borders come from the table style graph, which `resolvedFill`/`borders` fold\n\t// together rather than separating; the write path spells out an explicit border per edge.\n\tborder:\n\t\t'table cell borders are resolved through the style graph, which the read model cannot separate from the cell’s own',\n\t// `a:ln/@w` defaults to a hairline in OOXML and to 1pt here, and a source outline with no\n\t// explicit width is exactly the theme-`lnRef` case `line.width` already declares unread.\n\twidth:\n\t\t'an outline with no explicit width takes the write path’s 1pt default; the source’s came from the unread theme line style',\n\t// A shape with no geometry of its own — an unfilled placeholder — has no preset to name.\n\tshape: 'a shape that inherits its geometry from a layout is emitted as a plain rectangle',\n\ttype: 'a fill or line with no explicit kind takes the write path’s solid default',\n\t// Chart options the write path always emits; the read side reports only what the chart\n\t// part contains, and these are defaults rather than authored values.\n\tchartColors: 'the write path assigns a series palette; the source’s came from the theme',\n\tdataLabelFormatCode: 'a data label with no explicit number format takes the write path’s default',\n\tshowLeaderLines: 'leader lines are on by default in the write path',\n\t// The five docProps the write path seeds in its constructor ('ts-pptx',\n\t// 'ts-pptx Presentation', '1'). A source deck that declared none of a given property gets\n\t// the library's, and there is no way to unset one — assigning `''` writes an empty element\n\t// rather than removing it. Unlike the entries above, this is a *write*-side candidate, not\n\t// a read-side one: the fix is a way to author a deck with a property genuinely absent.\n\t// Restricted to `added` by construction, so a printer that stopped writing docProps still\n\t// fails: the source's own values become `changed`, which nothing here excuses.\n\ttitle: 'a deck that declares no title gets the write path’s own',\n\tauthor: 'a deck that declares no author gets the write path’s own',\n\tsubject: 'a deck that declares no subject gets the write path’s own',\n\tcompany: 'a deck that declares no company gets the write path’s own',\n\trevision: 'a deck that declares no revision gets the write path’s own',\n}\n\nexport interface IrDifference {\n\t/** 1-based source slide. */\n\tslideNumber: number\n\t/** Source shape name, when the difference sits inside a call that has one. */\n\tshapeName: string | null\n\t/**\n\t * Shape names nested inside the same call — a group's children. A note scoped to one of\n\t * these also declares differences reported against the call that carries it.\n\t */\n\tnestedNames: string[]\n\t/** Where in the slide's projection, e.g. `calls[4].args[1].line.width`. */\n\tpath: string\n\t/**\n\t * The option name the difference is about — the last object key on {@link path}, or\n\t * `'*'` when a whole call is present on one side only. This is what a note's `construct`\n\t * is matched against, which is why `construct` has to name a field path rather than\n\t * describe one.\n\t */\n\tfield: string\n\tkind: DifferenceKind\n\t/** The source value, JSON-encoded and truncated for reporting. `'—'` when absent. */\n\texpected: string\n\t/** The output value, likewise. */\n\tactual: string\n\t/** The note that declares this difference, when one does. */\n\tdeclaredBy: FidelityNote | null\n}\n\nexport interface RoundTripReport {\n\tslideCount: number\n\t/** Every difference found, in deck order. */\n\tdifferences: IrDifference[]\n\t/**\n\t * Differences neither a note nor a known write-path default accounts for.\n\t * **These are the defects**, and the number this check gates on.\n\t */\n\tundeclared: IrDifference[]\n\t/** Differences a note declared. The contract working. */\n\tdeclared: IrDifference[]\n\t/** `added` differences: the write path spelling out what the source left implicit. */\n\tadded: IrDifference[]\n\t/**\n\t * Notes that matched no difference.\n\t *\n\t * **Not a defect signal, despite the obvious reading.** Most notes name constructs the\n\t * read model cannot see at all — a bullet's `a:buFont`, a shape's theme `effectRef` —\n\t * so they are absent from *both* IRs and there is nothing for them to match. A note\n\t * here is a candidate for review, not a stale claim.\n\t */\n\tunmatchedNotes: FidelityNote[]\n}\n\n/**\n * Option names each note construct is a promise about.\n *\n * This table is the fidelity catalogue made mechanical. A note claims a construct will not\n * survive; without a mapping from that claim to the fields it covers, the claim cannot\n * exclude anything and the round trip degenerates into a snapshot.\n *\n * `'*'` covers every difference inside the call it is scoped to — correct only where the\n * note says the whole shape is gone or was copied wholesale, never as a shortcut for a\n * construct whose fields are merely tedious to enumerate.\n *\n * An empty list is meaningful and common: the construct is invisible to the IR on both\n * sides (a slide's build animations, a paragraph's `a:pPr/@marL`, a connector's shape\n * binding), so the note is a caveat for a human and there is nothing here to exclude. Saying\n * so explicitly is what keeps it from looking like an oversight. A construct can leave that\n * state — `slide.transition` was an empty entry until the converter learned to transcribe\n * transitions, and the IR gaining a field is exactly when its note gains a mapping.\n */\nconst NOTE_FIELDS: Record<string, readonly string[]> = {\n\t'chart.blanks': ['values'],\n\t'chart.combo': ['type'],\n\t'chart.type': ['type'],\n\t'chart.workbook': ['*'],\n\t'chartEx.all': ['*'],\n\t'connector.binding': [],\n\t'connector.line': ['color', 'width', 'dashType', 'beginArrowType', 'endArrowType'],\n\t'connector.rotation': ['rotate'],\n\t// Empty, and the temptation to list title/author/subject/revision here has to be\n\t// resisted: this note is about the *other* seven docProps, which have no setter and are\n\t// absent from the IR. Listing the four that do have setters would excuse a printer that\n\t// stopped writing them — measured, by exactly that mutation.\n\t'deck.docProps': [],\n\t// Nothing to exclude: the differences it predicts are `added`, which WRITER_DEFAULTS covers\n\t// by kind. The note exists so a reader of the emitted script learns the deck gained them.\n\t'deck.docPropsDefault': [],\n\t'deck.slideSize': ['widthEmu', 'heightEmu'],\n\t'fill.gradient.path': ['gradient', 'fill'],\n\t// Recorded only when an image-filled surface cannot carry its *bytes* — a linked blip, an\n\t// SVG the write path refuses, a part missing from the package. The fill option is then\n\t// absent from the output entirely, which is the same two keys `fill.schemeToken` covers.\n\t'fill.picture': ['fill', 'color'],\n\t// Empty, and deliberately so: this note declares that a picture fill's tiling, crop, DPI\n\t// and rotWithShape do not survive, and *none of them is in the IR on either side* — the\n\t// write API expresses a picture fill as bytes plus transparency, so the converter never\n\t// emits them. Widening this to `fill` would be the mistake it looks like a fix for: it\n\t// would excuse an image fill that failed to come back at all, which is the thing the\n\t// round trip is here to catch.\n\t'fill.picture.geometry': [],\n\t'fill.schemeToken': ['fill', 'color'],\n\t'graphicFrame.unknown': ['*'],\n\t'group.child': ['*'],\n\t'group.childSpace': ['x', 'y', 'w', 'h', 'rotate', 'flipH', 'flipV'],\n\t'group.empty': ['*'],\n\t'group.transform': ['rotate', 'flipH', 'flipV'],\n\t'image.data': ['data', '$asset'],\n\t'image.recolor': ['duotone', 'grayscale', 'biLevel', 'clrChange'],\n\t// Covers the picture's bytes, not just an `svg` option: an SVG picture's raster fallback\n\t// is regenerated rather than carried, so the blip the round trip compares is a different\n\t// image from the source's — which is precisely the loss this note is about.\n\t'image.svg': ['svg', 'data', '$asset'],\n\t'line.arrowSize': ['beginArrowType', 'endArrowType'],\n\t// The chrome notes. Most are empty for the reason stated above and it is the common case\n\t// here rather than the exception: `a:fmtScheme`, `p:txStyles`, master/layout decoration and\n\t// layout placeholder definitions are all absent from the IR on *both* sides — nothing reads\n\t// them — so there is nothing for a note to exclude and the note exists for a human.\n\t// `p:clrMap` is the subtle one: a remapped token changes what every scheme colour in the\n\t// deck resolves to, and the round trip still cannot see it, because the IR reports the token\n\t// verbatim rather than its resolved hex. That is exactly the blind spot this file's header\n\t// describes, and writing `[]` is the honest spelling of it.\n\t'master.background': ['background', 'color', 'data', 'master'],\n\t'master.colorMap': [],\n\t'master.decoration': [],\n\t'master.default': ['master'],\n\t'master.multiple': [],\n\t'master.name': ['title', 'layoutName'],\n\t'master.nameCollision': ['title', 'layoutName'],\n\t'master.placeholders': [],\n\t'master.txStyles': [],\n\t'theme.fmtScheme': [],\n\t'line.dash': ['dashType'],\n\t'line.width': ['width'],\n\t'media.audioVideo': ['*'],\n\t'notes.formatting': ['notesText'],\n\t'shape.custGeom.guides': ['points'],\n\t'shape.effects': ['shadow', 'glow'],\n\t'shape.empty': ['*'],\n\t'shape.frameInherited': ['x', 'y', 'w', 'h'],\n\t'shape.hidden': ['*'],\n\t'shape.placeholder': ['placeholder'],\n\t'slide.animation': [],\n\t'slide.background': ['background', 'color', 'transparency', 'image'],\n\t'slide.carried': ['*'],\n\t'slide.layout': ['layoutName'],\n\t'slide.name': [],\n\t// A transition the write vocabulary cannot name is dropped whole, so the difference lands\n\t// on the slide's `transition` key itself. Deliberately *not* widened to the keys inside it:\n\t// this note is only ever recorded when the whole transition is gone.\n\t'slide.transition': ['transition'],\n\t// The sound alone, one level down. Scoped to `sound` so it cannot also excuse a transition\n\t// whose type or timing came back wrong — the loss it declares is exactly the missing\n\t// `p:sndAc`, and `data`/`$asset` cover the case where the sound survives with other bytes.\n\t'slide.transitionSound': ['sound', 'data', '$asset'],\n\t'table.cell.borders.diagonal': ['border'],\n\t'table.cell.fill': ['fill'],\n\t// The cell-side twins of `fill.picture` / `fill.picture.geometry`, and mapped for the\n\t// same reasons.\n\t'table.cell.fill.picture': ['fill'],\n\t'table.cell.fill.picture.geometry': [],\n\t'table.cell.vert': ['vert'],\n\t'table.rowAuto': ['rowH'],\n\t'table.style': ['tableStyle'],\n\t'text.align': ['align'],\n\t'text.bullet.numberStartAt': ['bullet'],\n\t'text.bullet.numberType': ['bullet'],\n\t'text.bullet.style': ['bullet'],\n\t'text.color.default': ['color'],\n\t'text.color.inherited': ['color'],\n\t'text.color.schemeToken': ['color'],\n\t'text.equation': ['*'],\n\t'text.field': ['*'],\n\t'text.bullet.glyph': ['bullet'],\n\t'text.bullet.inherited': ['bullet'],\n\t'text.indent': [],\n\t'text.paraSpaceZero': ['paraSpaceBefore', 'paraSpaceAfter'],\n\t'text.vert': ['vert'],\n}\n\n/** Every note construct this table knows how to match, for a test to check against. */\nexport function knownNoteConstructs(): string[] {\n\treturn Object.keys(NOTE_FIELDS).sort()\n}\n\n/**\n * Compare the deck a script was generated from against the deck it produced.\n *\n * `notes` must be the set that actually applies to the printed output — `printScript`'s\n * returned `notes`, not `DeckIr.fidelity`. The two differ in both directions: the printer\n * suppresses notes its tier rescues and adds ones its tier causes, so diffing against the\n * IR's own list would both over- and under-exclude.\n */\nexport function diffDeckIr(expected: CanonicalDeck, actual: CanonicalDeck, notes: FidelityNote[]): RoundTripReport {\n\tconst differences: IrDifference[] = []\n\n\tif (expected.slideSize.widthEmu !== actual.slideSize.widthEmu) {\n\t\tdifferences.push(scalarDifference(0, null, [], 'slideSize.widthEmu', 'widthEmu', expected.slideSize.widthEmu, actual.slideSize.widthEmu)) // prettier-ignore\n\t}\n\tif (expected.slideSize.heightEmu !== actual.slideSize.heightEmu) {\n\t\tdifferences.push(scalarDifference(0, null, [], 'slideSize.heightEmu', 'heightEmu', expected.slideSize.heightEmu, actual.slideSize.heightEmu)) // prettier-ignore\n\t}\n\n\tdiffValue(expected.props, actual.props, 'props', 'props', 0, null, [], differences)\n\tdiffChrome(expected.chrome, actual.chrome, differences)\n\n\tconst slideCount = Math.max(expected.slides.length, actual.slides.length)\n\tfor (let index = 0; index < slideCount; index++) {\n\t\tconst before = expected.slides[index]\n\t\tconst after = actual.slides[index]\n\t\tconst number = before?.number ?? after?.number ?? index + 1\n\t\tif (!before || !after) {\n\t\t\tdifferences.push({\n\t\t\t\tslideNumber: number,\n\t\t\t\tshapeName: null,\n\t\t\t\tnestedNames: [],\n\t\t\t\tpath: `slides[${index}]`,\n\t\t\t\tfield: '*',\n\t\t\t\tkind: before ? 'lost' : 'added',\n\t\t\t\texpected: before ? 'slide' : '—',\n\t\t\t\tactual: after ? 'slide' : '—',\n\t\t\t\tdeclaredBy: null,\n\t\t\t})\n\t\t\tcontinue\n\t\t}\n\t\tdiffSlide(before, after, differences)\n\t}\n\n\tfor (const difference of differences) difference.declaredBy = declaringNote(difference, notes)\n\tconst matched = new Set(differences.map((difference) => difference.declaredBy).filter(Boolean))\n\tconst accounted = (difference: IrDifference): boolean =>\n\t\tdifference.declaredBy !== null || (difference.kind === 'added' && difference.field in WRITER_DEFAULTS)\n\n\treturn {\n\t\tslideCount: expected.slides.length,\n\t\tdifferences,\n\t\tundeclared: differences.filter((difference) => !accounted(difference)),\n\t\tdeclared: differences.filter((difference) => difference.declaredBy !== null),\n\t\tadded: differences.filter((difference) => difference.kind === 'added'),\n\t\tunmatchedNotes: notes.filter((note) => !matched.has(note)),\n\t}\n}\n\n/**\n * The theme and the layout gallery.\n *\n * Reported at `slideNumber: 0`, the same deck-level bucket the slide size uses, so a\n * deck-scoped note (which carries `slideNumber: null` and matches any slide) can declare one.\n * Masters align by **title**, not by position, for the same reason calls align by shape name:\n * the write path always emits a blank layout of its own at gallery position 0, so positional\n * alignment reports every layout in the deck as renamed and buries the one real difference —\n * that extra layout — under a shift.\n *\n * And, exactly as with shape names, a title is only usable as a key where it is *unique on\n * both sides*. Uniqueness is supposed to be an invariant here — the converter deduplicates\n * titles because a title is also what `addSlide({ masterTitle })` binds on — but keying on it\n * unconditionally makes the check assume the thing it should be testing: a mutation that\n * removed the deduplication left two layouts sharing a title, both expected entries matched\n * the same actual one, and the round trip came back clean. Falling back to position when the\n * key repeats costs nothing when the invariant holds and catches it when it does not.\n */\nfunction diffChrome(expected: CanonicalChrome, actual: CanonicalChrome, out: IrDifference[]): void {\n\tdiffValue(expected.theme, actual.theme, 'chrome.theme', 'theme', 0, null, [], out)\n\n\t// A whole master appearing or disappearing is reported *scoped to its title*, using the\n\t// same `shapeName` channel a shape-scoped note uses. Without that, one note declaring the\n\t// blank layout the write path always adds would carry `field: 'master'` and excuse every\n\t// added layout — which is what a mutation that stopped deduplicating layout titles proved.\n\tconst report = (\n\t\tpath: string,\n\t\tkind: DifferenceKind,\n\t\tbefore: IrValue | undefined,\n\t\tafter: IrValue | undefined\n\t): void => {\n\t\tout.push({\n\t\t\tslideNumber: 0,\n\t\t\tshapeName: titleOf(before ?? after ?? null),\n\t\t\tnestedNames: [],\n\t\t\tpath,\n\t\t\tfield: 'master',\n\t\t\tkind,\n\t\t\texpected: brief(before),\n\t\t\tactual: brief(after),\n\t\t\tdeclaredBy: null,\n\t\t})\n\t}\n\n\tconst byTitle = uniqueByTitle(actual.masters)\n\tconst expectedTitles = uniqueByTitle(expected.masters)\n\tconst claimed = new Set<IrValue>()\n\tlet cursor = 0\n\tconst nextUnclaimed = (): IrValue | undefined => {\n\t\twhile (cursor < actual.masters.length) {\n\t\t\tconst candidate = actual.masters[cursor++]\n\t\t\tif (candidate !== undefined && !claimed.has(candidate)) return candidate\n\t\t}\n\t\treturn undefined\n\t}\n\n\texpected.masters.forEach((before, index) => {\n\t\tconst title = titleOf(before)\n\t\t// Usable only where the title identifies exactly one master on each side.\n\t\tconst named = title !== null && expectedTitles.has(title) ? byTitle.get(title) : undefined\n\t\tconst after = named !== undefined && !claimed.has(named) ? named : nextUnclaimed()\n\t\tif (after === undefined) {\n\t\t\treport(`chrome.masters[${index}]`, 'lost', before, undefined)\n\t\t\treturn\n\t\t}\n\t\tclaimed.add(after)\n\t\tdiffValue(before, after, `chrome.masters[${index}]`, 'master', 0, null, [], out)\n\t})\n\n\tactual.masters.forEach((after, index) => {\n\t\tif (!claimed.has(after)) report(`chrome.masters[${index}]`, 'added', undefined, after)\n\t})\n}\n\n/** Masters keyed by title, keeping only titles that identify exactly one of them. */\nfunction uniqueByTitle(masters: IrValue[]): Map<string, IrValue> {\n\tconst counts = new Map<string, number>()\n\tfor (const master of masters) {\n\t\tconst title = titleOf(master)\n\t\tif (title !== null) counts.set(title, (counts.get(title) ?? 0) + 1)\n\t}\n\tconst out = new Map<string, IrValue>()\n\tfor (const master of masters) {\n\t\tconst title = titleOf(master)\n\t\tif (title !== null && counts.get(title) === 1) out.set(title, master)\n\t}\n\treturn out\n}\n\n/** A canonical master's `title`, which is its identity across the round trip. */\nfunction titleOf(master: IrValue): string | null {\n\tif (master === null || typeof master !== 'object' || Array.isArray(master)) return null\n\tconst title = (master as Record<string, IrValue>)['title']\n\treturn typeof title === 'string' ? title : null\n}\n\nfunction diffSlide(expected: CanonicalSlide, actual: CanonicalSlide, out: IrDifference[]): void {\n\tconst number = expected.number\n\tconst at = (path: string, field: string, a: IrValue, b: IrValue): void => {\n\t\tif (JSON.stringify(a) !== JSON.stringify(b)) out.push(scalarDifference(number, null, [], path, field, a, b))\n\t}\n\tat('hidden', 'hidden', expected.hidden, actual.hidden)\n\tat('layoutName', 'layoutName', expected.layoutName, actual.layoutName)\n\tat('background', 'background', expected.background, actual.background)\n\tat('notesText', 'notesText', expected.notesText, actual.notesText)\n\t// Structural rather than whole-value, unlike the four above: a transition is a small object\n\t// whose parts are lost independently — the append path drops an embedded sound while\n\t// keeping the effect — and a whole-value compare would force the note that declares the\n\t// sound to carry `field: 'transition'`, which would then excuse a wrong type or duration too.\n\tdiffValue(expected.transition, actual.transition, 'transition', 'transition', number, null, [], out)\n\n\tfor (const [before, after] of alignCalls(expected.calls, actual.calls)) {\n\t\tconst name = before?.shapeName ?? after?.shapeName ?? null\n\t\t// Union of both sides: a child that dropped out is named only by the source's call.\n\t\tconst nested = [...new Set([...(before?.containedNames ?? []), ...(after?.containedNames ?? [])])]\n\t\tconst path = `calls[${before ? expected.calls.indexOf(before) : actual.calls.indexOf(after as CanonicalCall)}]`\n\t\tif (!before || !after) {\n\t\t\tout.push({\n\t\t\t\tslideNumber: number,\n\t\t\t\tshapeName: name,\n\t\t\t\tnestedNames: nested,\n\t\t\t\tpath,\n\t\t\t\tfield: '*',\n\t\t\t\tkind: before ? 'lost' : 'added',\n\t\t\t\texpected: before ? before.method : '—',\n\t\t\t\tactual: after ? after.method : '—',\n\t\t\t\tdeclaredBy: null,\n\t\t\t})\n\t\t\tcontinue\n\t\t}\n\t\tif (before.method !== after.method) {\n\t\t\tout.push(scalarDifference(number, name, nested, `${path}.method`, 'method', before.method, after.method))\n\t\t}\n\t\tdiffValue(before.args, after.args, `${path}.args`, 'args', number, name, nested, out)\n\t}\n}\n\n/**\n * Pair up the two slides' calls.\n *\n * Position alone is wrong the moment one shape drops out: every later call shifts by one\n * and the report fills with mismatches that are really one missing shape. Shape names\n * survive the round trip (the converter passes `objectName` through), so they are the\n * alignment key wherever they are present and unambiguous, with position as the fallback\n * for unnamed or duplicate-named shapes.\n */\nfunction alignCalls(\n\texpected: CanonicalCall[],\n\tactual: CanonicalCall[]\n): Array<[CanonicalCall | null, CanonicalCall | null]> {\n\tconst usable = (calls: CanonicalCall[]): Map<string, CanonicalCall> => {\n\t\tconst counts = new Map<string, number>()\n\t\tfor (const call of calls) {\n\t\t\tif (call.shapeName === null) continue\n\t\t\tcounts.set(call.shapeName, (counts.get(call.shapeName) ?? 0) + 1)\n\t\t}\n\t\tconst out = new Map<string, CanonicalCall>()\n\t\tfor (const call of calls) {\n\t\t\tif (call.shapeName !== null && counts.get(call.shapeName) === 1) out.set(call.shapeName, call)\n\t\t}\n\t\treturn out\n\t}\n\n\tconst byName = usable(actual)\n\tconst claimed = new Set<CanonicalCall>()\n\tconst pairs: Array<[CanonicalCall | null, CanonicalCall | null]> = []\n\t// Positional cursor for calls that names cannot align, advanced only past claimed calls\n\t// so a named match does not consume an unnamed call's slot.\n\tlet cursor = 0\n\tconst nextUnclaimed = (): CanonicalCall | null => {\n\t\twhile (cursor < actual.length) {\n\t\t\tconst candidate = actual[cursor++]\n\t\t\tif (candidate && !claimed.has(candidate)) return candidate\n\t\t}\n\t\treturn null\n\t}\n\n\tfor (const call of expected) {\n\t\tconst named = call.shapeName === null ? undefined : byName.get(call.shapeName)\n\t\tif (named && !claimed.has(named)) {\n\t\t\tclaimed.add(named)\n\t\t\tpairs.push([call, named])\n\t\t\tcontinue\n\t\t}\n\t\tconst positional = nextUnclaimed()\n\t\tif (positional) claimed.add(positional)\n\t\tpairs.push([call, positional])\n\t}\n\tfor (const call of actual) if (!claimed.has(call)) pairs.push([null, call])\n\treturn pairs\n}\n\nfunction diffValue(\n\texpected: IrValue,\n\tactual: IrValue,\n\tpath: string,\n\tfield: string,\n\tslideNumber: number,\n\tshapeName: string | null,\n\tnestedNames: string[],\n\tout: IrDifference[]\n): void {\n\tif (expected === actual) return\n\tconst kindOf = (value: IrValue): string => (value === null ? 'null' : Array.isArray(value) ? 'array' : typeof value)\n\tif (kindOf(expected) !== kindOf(actual)) {\n\t\tout.push(scalarDifference(slideNumber, shapeName, nestedNames, path, field, expected, actual))\n\t\treturn\n\t}\n\n\tif (Array.isArray(expected) && Array.isArray(actual)) {\n\t\tconst length = Math.max(expected.length, actual.length)\n\t\tfor (let index = 0; index < length; index++) {\n\t\t\tconst before = expected[index]\n\t\t\tconst after = actual[index]\n\t\t\tif (before === undefined || after === undefined) {\n\t\t\t\tout.push({\n\t\t\t\t\tslideNumber,\n\t\t\t\t\tshapeName,\n\t\t\t\t\tnestedNames,\n\t\t\t\t\tpath: `${path}[${index}]`,\n\t\t\t\t\tfield,\n\t\t\t\t\tkind: before === undefined ? 'added' : 'lost',\n\t\t\t\t\texpected: brief(before),\n\t\t\t\t\tactual: brief(after),\n\t\t\t\t\tdeclaredBy: null,\n\t\t\t\t})\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tdiffValue(before, after, `${path}[${index}]`, field, slideNumber, shapeName, nestedNames, out)\n\t\t}\n\t\treturn\n\t}\n\n\tif (expected !== null && typeof expected === 'object' && actual !== null && typeof actual === 'object') {\n\t\tconst record = expected as Record<string, IrValue>\n\t\tconst other = actual as Record<string, IrValue>\n\t\tfor (const key of new Set([...Object.keys(record), ...Object.keys(other)])) {\n\t\t\tconst before = record[key]\n\t\t\tconst after = other[key]\n\t\t\tif (before === undefined || after === undefined) {\n\t\t\t\tout.push({\n\t\t\t\t\tslideNumber,\n\t\t\t\t\tshapeName,\n\t\t\t\t\tnestedNames,\n\t\t\t\t\tpath: `${path}.${key}`,\n\t\t\t\t\tfield: key,\n\t\t\t\t\tkind: before === undefined ? 'added' : 'lost',\n\t\t\t\t\texpected: brief(before),\n\t\t\t\t\tactual: brief(after),\n\t\t\t\t\tdeclaredBy: null,\n\t\t\t\t})\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tdiffValue(before, after, `${path}.${key}`, key, slideNumber, shapeName, nestedNames, out)\n\t\t}\n\t\treturn\n\t}\n\n\tout.push(scalarDifference(slideNumber, shapeName, nestedNames, path, field, expected, actual))\n}\n\nfunction scalarDifference(\n\tslideNumber: number,\n\tshapeName: string | null,\n\tnestedNames: string[],\n\tpath: string,\n\tfield: string,\n\texpected: IrValue,\n\tactual: IrValue\n): IrDifference {\n\treturn {\n\t\tslideNumber,\n\t\tshapeName,\n\t\tnestedNames,\n\t\tpath,\n\t\tfield,\n\t\tkind: 'changed',\n\t\texpected: brief(expected),\n\t\tactual: brief(actual),\n\t\tdeclaredBy: null,\n\t}\n}\n\n/** The first note that covers this difference, or `null` if none does. */\nfunction declaringNote(difference: IrDifference, notes: FidelityNote[]): FidelityNote | null {\n\tfor (const note of notes) {\n\t\tif (note.slideNumber !== null && note.slideNumber !== difference.slideNumber) continue\n\t\t// A shape-scoped note covers only that shape; a slide- or deck-scoped one covers any.\n\t\tif (\n\t\t\tnote.shapeName !== null &&\n\t\t\tnote.shapeName !== difference.shapeName &&\n\t\t\t!difference.nestedNames.includes(note.shapeName)\n\t\t) {\n\t\t\tcontinue\n\t\t}\n\t\tconst fields = NOTE_FIELDS[note.construct]\n\t\tif (!fields) continue\n\t\tif (fields.includes('*') || fields.includes(difference.field)) return note\n\t}\n\treturn null\n}\n\nfunction brief(value: IrValue | undefined): string {\n\tif (value === undefined) return '—'\n\tconst text = JSON.stringify(value)\n\treturn text.length > 80 ? `${text.slice(0, 80)}…` : text\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"script.js","names":["#seen","#notes","ANCHOR","positionOfFrame","WRITABLE_DASHES","#byPartName","#assets","#counts","PACKAGE_NAME","printSlides"],"sources":["../src/script/fidelity.ts","../src/script/from-read/detect.ts","../src/script/from-read/values.ts","../src/script/from-read/chrome.ts","../src/script/from-read/surface-fill.ts","../src/script/from-read/picture-fill.ts","../src/script/from-read/text.ts","../src/script/from-read/table.ts","../src/script/from-read/chart.ts","../src/script/from-read/shape.ts","../src/script/from-read/transition.ts","../src/script/from-read/deck.ts","../src/script/ir.ts","../src/script/print/literal.ts","../src/script/print/common.ts","../src/script/print/script.ts","../src/script/print/standalone.ts","../src/script/verify/canonical.ts","../src/script/verify/diff.ts"],"sourcesContent":["/**\n * Fidelity notes — the declared, machine-checkable list of what a deck loses on the way\n * to a script.\n *\n * A converter that warns about losses to a log has no way to be tested: the warnings are\n * prose, nothing consumes them, and a missing one looks exactly like a clean run. Making\n * the notes part of the IR inverts that. A note says \"field X of shape Y will not come\n * back\", so a round-trip check can exclude precisely those fields and treat **any**\n * remaining difference as a defect. Both directions then have teeth:\n *\n * - an *undeclared* loss fails the round-trip, because nothing excluded it;\n * - a *declared* loss that actually survives is a stale note, and the check can say so.\n *\n * That is the whole reason notes are first-class rather than a side channel. It also\n * means {@link FidelityNote.construct} is an identifier, not a sentence: it has to be\n * matchable against a field path, so it is a stable dotted key and the human explanation\n * lives in {@link FidelityNote.detail}.\n */\n\n/** What happened to the construct. */\nexport type Disposition =\n\t/** Gone: nothing in the output carries it. */\n\t| 'dropped'\n\t/**\n\t * Present but structurally simplified — a value survives while the structure around\n\t * it does not (threaded comment replies flattened into separate comments, a per-script\n\t * font scheme reduced to latin, a placeholder demoted to a plain shape).\n\t */\n\t| 'flattened'\n\t/**\n\t * Present and structurally intact, but not the same value — a re-encoding that a\n\t * viewer may or may not be able to tell apart (a modern transition mapped to the\n\t * nearest named one, a chart rebuilt from cached points rather than its workbook).\n\t */\n\t| 'approximated'\n\n/**\n * Which side of the library is responsible. Recording this is what makes the notes\n * actionable rather than merely honest: `unread` and `unwritable` are bugs waiting to be\n * fixed in a specific subsystem, while `unsupported` is a property of OOXML or of the\n * chosen output tier and will not be fixed by more converter work.\n */\nexport type Cause =\n\t/** The read API exposes no accessor for it, so the converter never saw it. */\n\t| 'unread'\n\t/** Read fine, but the write API has no option that expresses it. */\n\t| 'unwritable'\n\t/** Both sides can handle it; this output tier structurally cannot carry it. */\n\t| 'unsupported'\n\n/** One declared loss. */\nexport interface FidelityNote {\n\t/** 1-based source slide, or `null` for a deck-level loss. */\n\tslideNumber: number | null\n\t/** Source shape name (`p:cNvPr/@name`), or `null` when the loss is not shape-scoped. */\n\tshapeName: string | null\n\t/**\n\t * Stable dotted identifier for the lost construct — `line.width`, `text.tabStops`,\n\t * `chart.workbook`. Matched mechanically by the round-trip check, so it must name a\n\t * field path rather than describe one. Reuse an existing key for the same construct\n\t * instead of coining a synonym.\n\t */\n\tconstruct: string\n\tdisposition: Disposition\n\tcause: Cause\n\t/** Why, in a sentence, for a human reading the emitted script's header. */\n\tdetail: string\n}\n\n/**\n * Accumulates notes while a deck is walked, so the walk itself stays a plain\n * read-model → IR mapping and does not thread a growing array through every function.\n *\n * Deduplicates on the full note identity. Without that, a construct that is lost on every\n * run of a 400-run text body would produce 400 identical notes and bury the one-off losses\n * that actually need reading.\n */\nexport class NoteCollector {\n\treadonly #seen = new Set<string>()\n\treadonly #notes: FidelityNote[] = []\n\n\t/** Record a loss. A repeat of an identical note is ignored. */\n\tadd(note: FidelityNote): void {\n\t\tconst key = `${note.slideNumber}\u0000${note.shapeName}\u0000${note.construct}\u0000${note.disposition}\u0000${note.cause}\u0000${note.detail}`\n\t\tif (this.#seen.has(key)) return\n\t\tthis.#seen.add(key)\n\t\tthis.#notes.push(note)\n\t}\n\n\t/**\n\t * The notes, in the order first recorded — which is deck order, since the walk is\n\t * ordered, so a reader meets them the way they meet the slides.\n\t */\n\tget notes(): FidelityNote[] {\n\t\treturn this.#notes\n\t}\n}\n\n/**\n * A {@link NoteCollector} bound to one slide and shape, so a mapping function can record\n * a loss without knowing where in the deck it sits. Obtained via {@link scopeNotes}.\n */\nexport interface NoteScope {\n\t/** Record a loss at this scope. */\n\tnote(construct: string, disposition: Disposition, cause: Cause, detail: string): void\n\t/** Re-scope to a shape within the same slide. */\n\tforShape(shapeName: string | null): NoteScope\n}\n\n/** Bind a collector to a slide (and optionally a shape). */\nexport function scopeNotes(\n\tcollector: NoteCollector,\n\tslideNumber: number | null,\n\tshapeName: string | null = null\n): NoteScope {\n\treturn {\n\t\tnote(construct, disposition, cause, detail) {\n\t\t\tcollector.add({ slideNumber, shapeName, construct, disposition, cause, detail })\n\t\t},\n\t\tforShape(name) {\n\t\t\treturn scopeNotes(collector, slideNumber, name)\n\t\t},\n\t}\n}\n","/**\n * Presence checks for constructs the read model has no accessor for.\n *\n * These reach through the documented raw hatch (`element_`) rather than through a typed\n * accessor, which needs justifying. The rule they follow: **detect, never decode.** Each\n * function answers only \"is this here?\", so the answer can become a {@link FidelityNote}.\n * Nothing here interprets a value or feeds one into a call — that would be building a\n * private read path alongside the public one, and it would rot the moment the element's\n * meaning changed.\n *\n * The alternative is worse than the coupling. Without these checks, a deck with an embedded\n * video converts to a static poster image and a deck with an equation converts to an empty\n * box, both silently and both with a clean round-trip, because a diff cannot see what\n * neither side read. A loss you can name is a bug report; a loss nothing observes is a\n * defect that ships.\n *\n * Each check here is a standing argument for a real accessor. When one lands, the\n * corresponding function should be deleted, not kept in sync.\n */\n\n/** DrawingML main namespace — hosts `a:videoFile` / `a:audioFile` under `p:nvPr`. */\nconst A_NS = 'http://schemas.openxmlformats.org/drawingml/2006/main'\n\n/** Office MathML namespace — the equation body itself, wrapped by `a14:m` in a text run. */\nconst MATH_NS = 'http://schemas.openxmlformats.org/officeDocument/2006/math'\n\n/** PresentationML main namespace — `p:grpSpPr`, `p:txStyles`, `p:spTree`. */\nconst P_NS = 'http://schemas.openxmlformats.org/presentationml/2006/main'\n\n/** Shape-tree children that carry drawing content, as opposed to the tree's own properties. */\nconst SHAPE_ELEMENTS = new Set(['sp', 'pic', 'graphicFrame', 'grpSp', 'cxnSp'])\n\n/** A minimal structural view of a DOM element, so this module needs no DOM lib types. */\ninterface ElementLike {\n\tnamespaceURI: string | null\n\tlocalName: string | null\n\tfirstChild: NodeLike | null\n\tgetAttribute(name: string): string | null\n\tgetElementsByTagNameNS(namespaceURI: string, localName: string): { length: number }\n}\n\ninterface NodeLike {\n\tnodeType: number\n\tnextSibling: NodeLike | null\n}\n\nconst ELEMENT_NODE = 1\n\nfunction has(element: unknown, namespaceURI: string, localName: string): boolean {\n\tconst el = element as ElementLike | null\n\tif (!el || typeof el.getElementsByTagNameNS !== 'function') return false\n\treturn el.getElementsByTagNameNS(namespaceURI, localName).length > 0\n}\n\n/**\n * The first *direct* child with this name.\n *\n * A subtree search is wrong for structural lookups, in two ways that both bite here.\n * `a:ext` names two unrelated elements — a shape extent (`@cx`/`@cy`) and an extension-list\n * entry (`@uri`) — so a subtree search finds whichever comes first in document order. And on\n * a group it descends into the group's own children, so a nested group's transform answers\n * for its parent's.\n */\nfunction child(element: ElementLike | null, namespaceURI: string, localName: string): ElementLike | null {\n\tif (!element) return null\n\tfor (let node = element.firstChild; node; node = node.nextSibling) {\n\t\tif (node.nodeType !== ELEMENT_NODE) continue\n\t\tconst el = node as unknown as ElementLike\n\t\tif (el.namespaceURI === namespaceURI && el.localName === localName) return el\n\t}\n\treturn null\n}\n\n/** Every direct element child, as {@link ElementLike}s. */\nfunction children(element: ElementLike | null): ElementLike[] {\n\tif (!element) return []\n\tconst out: ElementLike[] = []\n\tfor (let node = element.firstChild; node; node = node.nextSibling) {\n\t\tif (node.nodeType === ELEMENT_NODE) out.push(node as unknown as ElementLike)\n\t}\n\treturn out\n}\n\n/**\n * `true` when this shape is an embedded audio or video rather than a still picture.\n *\n * PowerPoint authors media as a `p:pic` whose `p:nvPr` carries an `a:videoFile` or\n * `a:audioFile`, with the poster frame as the picture's own blip. The read model reports\n * only the poster — `mediaKind` distinguishes raster from SVG, not still from moving — so\n * without this check a video converts to a static image that looks deliberate.\n */\nexport function isAudioVideo(element: unknown): boolean {\n\treturn has(element, A_NS, 'videoFile') || has(element, A_NS, 'audioFile')\n}\n\n/**\n * `true` when this shape's text body contains an OMML equation.\n *\n * An equation lives in `m:oMath` inside an `a14:m` run, which contributes nothing to\n * `TextFrame.text`, so an equation-only shape reads as an empty text frame. The write API\n * *can* author one (`TextProps.math`, plus the `ts-pptx/math` subpath for LaTeX/MathML\n * input), which makes this a read-side gap rather than a hard limit.\n */\nexport function hasEquation(element: unknown): boolean {\n\treturn has(element, MATH_NS, 'oMath')\n}\n\n/**\n * `true` when this `p:sp` is a text box rather than an auto shape.\n *\n * The discriminator is one attribute, `p:cNvSpPr/@txBox`, and nothing reads it. The\n * tempting substitute — \"it has no preset geometry\" — is wrong for the common case:\n * PowerPoint gives every text box an explicit `<a:prstGeom prst=\"rect\"/>`, so that test\n * calls every real text box an auto shape. The difference is not cosmetic. PowerPoint\n * autofits, wraps and resizes a text box by different rules, and offers a different\n * right-click menu for it.\n *\n * Direct child rather than a subtree search: `p:cNvSpPr` sits under `p:nvSpPr`, and a group\n * would otherwise answer for its first child.\n */\nexport function isTextBox(element: unknown): boolean {\n\tconst nvSpPr = child(element as ElementLike | null, P_NS, 'nvSpPr')\n\treturn child(nvSpPr, P_NS, 'cNvSpPr')?.getAttribute('txBox') === '1'\n}\n\n/**\n * `true` when a group's child coordinate space equals its own frame, so its children are\n * already in slide-absolute units.\n *\n * `addGroup` always emits an identity child space; a source group whose `a:chOff`/`a:chExt`\n * differ scales or shifts its contents, and that behaviour cannot be reproduced. The read\n * model has no accessor for the child space — `absoluteFrame` deliberately composes it away,\n * which is right for locating a shape and wrong for spotting this difference.\n *\n * A group with no explicit transform inherits an identity one, so a missing `a:xfrm` is\n * `true` rather than unknown.\n */\nexport function hasIdentityChildSpace(element: unknown): boolean {\n\tconst xfrm = child(child(element as ElementLike | null, P_NS, 'grpSpPr'), A_NS, 'xfrm')\n\tif (!xfrm) return true\n\n\tconst off = child(xfrm, A_NS, 'off')\n\tconst ext = child(xfrm, A_NS, 'ext')\n\tconst chOff = child(xfrm, A_NS, 'chOff')\n\tconst chExt = child(xfrm, A_NS, 'chExt')\n\tif (!off || !ext || !chOff || !chExt) return true\n\n\treturn (\n\t\toff.getAttribute('x') === chOff.getAttribute('x') &&\n\t\toff.getAttribute('y') === chOff.getAttribute('y') &&\n\t\text.getAttribute('cx') === chExt.getAttribute('cx') &&\n\t\text.getAttribute('cy') === chExt.getAttribute('cy')\n\t)\n}\n\n/**\n * `true` when this theme declares an `a:fmtScheme`.\n *\n * The format scheme holds the three fill, three line and three effect style lists a shape's\n * `p:style` indexes into. Neither half of the library touches it: nothing reads it, and the\n * write path emits a hardcoded Office one. So a deck whose theme carries a custom format\n * scheme is repainted with Office's, and this is the only way to notice.\n */\nexport function hasFormatScheme(element: unknown): boolean {\n\treturn has(element, A_NS, 'fmtScheme')\n}\n\n/**\n * `true` when this slide master declares per-level text styles (`p:txStyles`) with content.\n *\n * `SlideMasterProps.textStyles` can author them, so this is purely a read-side gap — the\n * default size, face, colour and bullet of every placeholder level is invisible to the\n * converter and comes back as PowerPoint's built-in default.\n */\nexport function hasTextStyles(element: unknown): boolean {\n\tconst txStyles = child(element as ElementLike | null, P_NS, 'txStyles')\n\treturn children(txStyles).some((group) => children(group).length > 0)\n}\n\n/**\n * `true` when this master or layout carries a shape that is not a placeholder — a logo, a\n * rule, a background image, a footer graphic.\n *\n * The read model is explicit that it decodes master/layout *placeholders* only, leaving\n * decoration to the byte-for-byte import paths. An output that rebuilds the chrome from the\n * read model therefore loses every one of these, and a deck that has none loses nothing —\n * which is why this is a count rather than a blanket note.\n */\nexport function hasDecorativeShapes(element: unknown): boolean {\n\tconst spTree = child(child(element as ElementLike | null, P_NS, 'cSld'), P_NS, 'spTree')\n\treturn children(spTree).some(\n\t\t(shape) => shape.namespaceURI === P_NS && SHAPE_ELEMENTS.has(shape.localName ?? '') && !has(shape, P_NS, 'ph')\n\t)\n}\n","/**\n * Value-level conversions shared by every mapper: geometry, colour, and the small\n * discipline that keeps an IR diffable.\n *\n * The precision rules here are not style choices, they are the measured boundary of what\n * the write API can carry, and each is pinned by a regression test:\n *\n * - A `Coord`-typed option accepts `` `${n}emu` ``, so EMU passes through untouched and\n * the source geometry is reproduced exactly. That covers every position and size.\n * - `colW`, `rowH`, and `margin` are number/`Margin`-typed **inches** and reject a raw-EMU\n * string, so they are where exactness stops. `defineLayout`'s `width`/`height` are a\n * fourth, reached only by a printer: there the imprecision does not degrade quietly but\n * *throws*, since `appendSlides` compares the two decks' EMU sizes for equality after\n * converting the declared inches back. Six decimal places is the minimum\n * at which `Math.round(printed × 914400)` provably returns the original EMU, bounding the\n * drift at 0.4572 EMU — about half a millionth of an inch. Rounding shorter to suppress\n * `0.5000000001`-style noise trades a cosmetic problem for a real geometry loss.\n */\nimport type { IrValue } from '../ir.js'\n\n/** EMU per inch (ECMA-376 §20.1.2.1). */\nconst EMU_PER_INCH = 914400\n\n/**\n * Decimal places used for the inch-typed options. See the module header: this is the\n * proven minimum for an EMU-exact round-trip, not a formatting preference.\n */\nconst INCH_DECIMALS = 6\n\n/** Geometry as a `Coord` the write API takes verbatim, preserving the exact EMU. */\nexport function emu(value: number): string {\n\treturn `${Math.round(value)}emu`\n}\n\n/**\n * Geometry as inches, for the three options that reject a raw-EMU string. Rounded to\n * {@link INCH_DECIMALS}, which is EMU-exact on the way back.\n */\nexport function inches(emuValue: number): number {\n\treturn Number((emuValue / EMU_PER_INCH).toFixed(INCH_DECIMALS))\n}\n\n/** EMU → points, the unit the write API uses for line widths and font sizes. */\nexport function points(emuValue: number): number {\n\treturn emuValue / 12700\n}\n\n/**\n * Points → inches, at the same proven precision as {@link inches}. Needed because the read\n * model reports text-body insets in points while the write API's `margin` takes inches —\n * and warns on a value `>= 1`, on the assumption that it is a points value passed by\n * mistake, so handing it points would both mis-scale the text and produce a warning.\n */\nexport function pointsToInches(pt: number): number {\n\treturn Number((pt / 72).toFixed(INCH_DECIMALS))\n}\n\n/**\n * A colour for a write-API `color` field. The read model splits a colour into a raw\n * `schemeClr` token and a resolved literal hex; this prefers the token, because a token\n * re-resolves against the destination theme and so keeps the deck recolourable, which is\n * the whole reason a theme colour was authored.\n *\n * Only the ten tokens the write path's `clrMap` covers survive as tokens — the other\n * seven `ST_SchemeColorVal` values degrade to a hex literal there anyway, so passing them\n * through would produce a silently different colour. Callers hand those to\n * {@link literalColor} instead after recording a note.\n */\nconst WRITABLE_SCHEME_TOKENS = new Set([\n\t'accent1',\n\t'accent2',\n\t'accent3',\n\t'accent4',\n\t'accent5',\n\t'accent6',\n\t'bg1',\n\t'bg2',\n\t'tx1',\n\t'tx2',\n])\n\n/** `true` when a `schemeClr` token survives as a token rather than degrading to hex. */\nexport function isWritableSchemeToken(token: string | null): boolean {\n\treturn token !== null && WRITABLE_SCHEME_TOKENS.has(token)\n}\n\n/** Normalize a hex to the bare 6-digit uppercase form the write API expects. */\nexport function literalColor(hex: string): string {\n\treturn hex.replace(/^#/, '').toUpperCase()\n}\n\n/**\n * Build an IR object from possibly-absent parts, dropping every `undefined`.\n *\n * Every mapper funnels through this. An IR must spell \"absent\" exactly one way — a\n * missing key — or two IRs describing the same deck compare unequal because one wrote\n * `{ bold: undefined }` and the other wrote `{}`. That would surface as phantom\n * round-trip failures, so the invariant is enforced in one place rather than trusted to\n * every call site.\n *\n * Returns `undefined` when nothing survived, so a caller can drop the whole option object\n * rather than emit an empty one.\n */\nexport function compact(source: Record<string, IrValue | undefined>): Record<string, IrValue> | undefined {\n\tconst out: Record<string, IrValue> = {}\n\tlet any = false\n\tfor (const key of Object.keys(source).sort()) {\n\t\tconst value = source[key]\n\t\tif (value === undefined) continue\n\t\tout[key] = value\n\t\tany = true\n\t}\n\treturn any ? out : undefined\n}\n\n/** {@link compact}, but always an object — for a required options argument. */\nexport function compactRequired(source: Record<string, IrValue | undefined>): Record<string, IrValue> {\n\treturn compact(source) ?? {}\n}\n\n/** Drop a value that is `null`, so the read model's \"unset\" becomes an absent IR key. */\nexport function orUndefined<T>(value: T | null): T | undefined {\n\treturn value === null ? undefined : value\n}\n\n/**\n * A 0–1 opacity as the write API's 0–100 transparency; `undefined` when unset.\n *\n * Fully opaque is *not* `0` here — a caller that means \"no transparency at all\" passes\n * `undefined`, because emitting `transparency: 0` for an `a:alphaModFix amt=\"100000\"`\n * would produce a key the output cannot have: the write path emits no `a:alphaModFix` for\n * a zero transparency, so the re-read deck reports no alpha and the round trip sees a\n * difference where there is no visible one.\n */\nexport function alphaToTransparency(alpha: number | null | undefined): number | undefined {\n\tif (alpha === undefined || alpha === null) return undefined\n\treturn Math.round((1 - alpha) * 100)\n}\n","/**\n * The deck's shared chrome → {@link ChromeIr}: theme colours and fonts, plus one\n * `defineSlideMaster` descriptor per source layout.\n *\n * **Only a standalone output needs any of this,** and it is the part of a deck that survives\n * a conversion worst. A template-anchored output reuses the source package, so its masters,\n * layouts and theme are the originals byte for byte; everything below is the approximation\n * that replaces them when there is no template to inherit from. The notes it records are\n * therefore tier-scoped: real for a standalone script, and suppressed by the template-anchored\n * printer because they do not describe its output.\n *\n * **Three ceilings meet here, and none of them moves by working harder on this file:**\n *\n * 1. `a:fmtScheme` is unreachable from *both* directions — no read accessor, and the write\n * path emits a hardcoded Office one. A shape whose look comes from `p:style` is repainted.\n * 2. `p:txStyles` has a write counterpart (`SlideMasterProps.textStyles`) and no reader, so\n * the per-level placeholder defaults are invisible.\n * 3. Master and layout *decoration* — anything that is not a placeholder — is documented as\n * out of the read model's scope (`src/read/api/chrome.ts` header); the import paths carry\n * it byte-for-byte instead. A logo on a layout cannot be seen, let alone re-authored.\n *\n * **Layout placeholders are deliberately not emitted, and that is a write-path finding rather\n * than a read-path one.** `addPlaceholdersToSlideLayouts` seeds *every* slide with each layout\n * placeholder the slide did not populate, as an empty text shape\n * (`src/gen/define/placeholder.ts`). Since this converter transcribes every source shape as\n * concrete absolute-positioned content and never binds one to a placeholder, reproducing the\n * layout's placeholders would add a ghost shape to every slide for each of them — shapes the\n * source deck does not have. Dropping them costs an editing affordance; emitting them would\n * cost the output's shape tree.\n */\nimport type { Presentation } from '../../read/api/presentation.js'\nimport type { SlideMaster, Theme } from '../../read/api/chrome.js'\nimport type { SlideBackground } from '../../read/api/slide-background.js'\nimport type { ChromeIr, IrValue, MasterIr, ThemeIr } from '../ir.js'\nimport type { NoteScope } from '../fidelity.js'\nimport type { AssetResolver } from './shape.js'\nimport { hasDecorativeShapes, hasFormatScheme, hasTextStyles } from './detect.js'\nimport { compact, literalColor, orUndefined } from './values.js'\n\n/**\n * The `p:clrMap` the write path always emits (`src/gen/slide/master.ts`). A source master\n * that maps a token elsewhere — a deck whose light and dark slots are swapped, the usual\n * case — resolves every `schemeClr` in the deck differently, and there is no setter for it.\n */\nconst DEFAULT_COLOR_MAP: Record<string, string> = {\n\tbg1: 'lt1',\n\ttx1: 'dk1',\n\tbg2: 'lt2',\n\ttx2: 'dk2',\n\taccent1: 'accent1',\n\taccent2: 'accent2',\n\taccent3: 'accent3',\n\taccent4: 'accent4',\n\taccent5: 'accent5',\n\taccent6: 'accent6',\n\thlink: 'hlink',\n\tfolHlink: 'folHlink',\n}\n\n/** Build the chrome IR for a deck. */\nexport function chromeToIr(pres: Presentation, notes: NoteScope, assets: AssetResolver): ChromeIr {\n\tconst masters = pres.masters()\n\n\tif (masters.length > 1) {\n\t\tnotes.note(\n\t\t\t'master.multiple',\n\t\t\t'flattened',\n\t\t\t'unsupported',\n\t\t\t`this deck has ${masters.length} slide masters; the write API models a deck as one shared master with many layouts, so every layout is rebuilt under a single master and only the first master's theme and colour map survive`\n\t\t)\n\t}\n\n\tconst first = masters[0]\n\tconst theme = first?.theme ?? null\n\trecordMasterLosses(masters, theme, notes)\n\n\treturn { theme: themeToIr(theme), masters: layoutsToIr(masters, notes, assets) }\n}\n\n/** The theme's colour scheme and font faces, in `ThemeProps` spelling. */\nfunction themeToIr(theme: Theme | null): ThemeIr {\n\tif (!theme) return {}\n\n\tconst scheme = theme.colorScheme\n\tconst colors: Record<string, string> = {}\n\tfor (const [slot, hex] of Object.entries(scheme)) {\n\t\tif (hex !== null) colors[slot] = literalColor(hex)\n\t}\n\n\tconst fonts = theme.fontScheme\n\treturn compact({\n\t\theadFontFace: orUndefined(fonts?.major.latin ?? null),\n\t\tbodyFontFace: orUndefined(fonts?.minor.latin ?? null),\n\t\theadFontFaceEA: orUndefined(fonts?.major.ea ?? null),\n\t\tbodyFontFaceEA: orUndefined(fonts?.minor.ea ?? null),\n\t\theadFontFaceCS: orUndefined(fonts?.major.cs ?? null),\n\t\tbodyFontFaceCS: orUndefined(fonts?.minor.cs ?? null),\n\t\tcolorScheme: Object.keys(colors).length > 0 ? colors : undefined,\n\t}) as ThemeIr\n}\n\n/** The losses that belong to the master/theme tier as a whole rather than to one layout. */\nfunction recordMasterLosses(masters: SlideMaster[], theme: Theme | null, notes: NoteScope): void {\n\tif (theme && hasFormatScheme(theme.element_)) {\n\t\tnotes.note(\n\t\t\t'theme.fmtScheme',\n\t\t\t'approximated',\n\t\t\t'unread',\n\t\t\t\"the theme's format scheme (a:fmtScheme — the three fill, line and effect style lists a shape's p:style indexes into) has no read accessor and no write-API option, so the output carries Office's default; a shape whose fill or outline came from the theme rather than from its own a:ln keeps its colour but not its width, dash or effect\"\n\t\t)\n\t}\n\n\tfor (const master of masters) {\n\t\tconst root = master.part.dom.documentElement\n\t\tif (hasTextStyles(root)) {\n\t\t\tnotes.note(\n\t\t\t\t'master.txStyles',\n\t\t\t\t'dropped',\n\t\t\t\t'unread',\n\t\t\t\t\"the master's per-level text styles (p:txStyles — the default size, face, colour, indent and bullet of each of the nine list levels) have no read accessor, so placeholder text falls back to PowerPoint's built-in defaults; SlideMasterProps.textStyles could author them if they could be seen\"\n\t\t\t)\n\t\t}\n\t\tif (hasDecorativeShapes(root)) {\n\t\t\tnotes.note(\n\t\t\t\t'master.decoration',\n\t\t\t\t'dropped',\n\t\t\t\t'unread',\n\t\t\t\t'this slide master carries shapes that are not placeholders (a logo, a rule, a background graphic); the read model decodes master and layout placeholders only, so they cannot be re-authored'\n\t\t\t)\n\t\t}\n\n\t\tconst map = master.colorMap\n\t\tconst remapped = Object.entries(DEFAULT_COLOR_MAP).filter(\n\t\t\t([token, slot]) => map[token as keyof typeof map] !== slot\n\t\t)\n\t\tif (remapped.length > 0) {\n\t\t\tnotes.note(\n\t\t\t\t'master.colorMap',\n\t\t\t\t'dropped',\n\t\t\t\t'unwritable',\n\t\t\t\t`this master remaps ${remapped.map(([token]) => token).join(', ')} to a different theme slot and the write path always emits the identity map, so every scheme colour that passes through as a token resolves to a different hex than it did in the source`\n\t\t\t)\n\t\t}\n\t}\n}\n\n/**\n * One `defineSlideMaster` descriptor per source layout, in the same gallery order\n * `Presentation.layouts()` reports — which is what lets a slide bind by index.\n *\n * Titles are made unique because they are the lookup key `addSlide({ masterTitle })` matches\n * on, and `p:cSld@name` is not unique: a multi-master deck routinely carries several layouts\n * called \"Title and Content\", and two `defineSlideMaster` calls sharing a title would make\n * every slide bind to whichever won.\n */\nfunction layoutsToIr(masters: SlideMaster[], notes: NoteScope, assets: AssetResolver): MasterIr[] {\n\tconst out: MasterIr[] = []\n\tconst used = new Set<string>()\n\t// Rolled up rather than noted per layout: a 12-layout deck loses decoration and placeholder\n\t// definitions on most of them, and twelve near-identical paragraphs at the top of the\n\t// emitted script bury the per-shape notes underneath that a reader can actually act on.\n\tconst decorated: string[] = []\n\tlet placeholderCount = 0\n\tlet placeholderLayouts = 0\n\n\tconst renamed: string[] = []\n\tconst collided: string[] = []\n\n\tfor (const master of masters) {\n\t\tfor (const layout of master.layouts) {\n\t\t\tconst index = out.length\n\t\t\tconst flattened = flattenAttributeValue(layout.name)\n\t\t\tif (flattened !== layout.name) renamed.push(`${JSON.stringify(layout.name)} → ${JSON.stringify(flattened)}`)\n\t\t\tconst base = flattened || `Layout ${index + 1}`\n\t\t\tlet title = base\n\t\t\tfor (let suffix = 2; used.has(title); suffix++) title = `${base} (${suffix})`\n\t\t\tif (title !== base) collided.push(`${JSON.stringify(base)} → ${JSON.stringify(title)}`)\n\t\t\tused.add(title)\n\n\t\t\tif (hasDecorativeShapes(layout.part.dom.documentElement)) decorated.push(title)\n\t\t\tconst placeholders = layout.placeholders.length\n\t\t\tif (placeholders > 0) {\n\t\t\t\tplaceholderCount += placeholders\n\t\t\t\tplaceholderLayouts++\n\t\t\t}\n\n\t\t\t// The layout's own background if it has one, else the master's — which is what a slide\n\t\t\t// bound to that layout actually shows, and the only tier the write API can set it at.\n\t\t\tconst background = backgroundProps(layout.background ?? master.background, notes, assets)\n\t\t\tout.push({ layoutIndex: index, props: compact({ title, background }) as Record<string, IrValue> })\n\t\t}\n\t}\n\n\tif (collided.length > 0) {\n\t\tnotes.note(\n\t\t\t'master.nameCollision',\n\t\t\t'approximated',\n\t\t\t'unsupported',\n\t\t\t`${collided.length} layout name(s) are not unique in the source — normally because the deck has several masters, each with its own \"Title and Content\" — and a layout title here is also the key addSlide({ masterTitle }) binds on, so duplicates cannot both exist. The later ones are suffixed and the slides bound to them follow: ${collided.join('; ')}`\n\t\t)\n\t}\n\tif (renamed.length > 0) {\n\t\tnotes.note(\n\t\t\t'master.name',\n\t\t\t'flattened',\n\t\t\t'unwritable',\n\t\t\t`${renamed.length} layout name(s) contain a line break or tab, which cannot survive as a layout title: the write path emits the name as a literal XML attribute value rather than a character reference, and XML normalises whitespace in an attribute to spaces. Collapsed here so the emitted script says what the output will contain — ${renamed.join('; ')}`\n\t\t)\n\t}\n\tif (decorated.length > 0) {\n\t\tnotes.note(\n\t\t\t'master.decoration',\n\t\t\t'dropped',\n\t\t\t'unread',\n\t\t\t`${decorated.length} slide layout(s) carry shapes that are not placeholders — ${decorated.join(', ')} — and the read model decodes layout placeholders only, so that decoration cannot be re-authored`\n\t\t)\n\t}\n\tif (placeholderCount > 0) {\n\t\tnotes.note(\n\t\t\t'master.placeholders',\n\t\t\t'dropped',\n\t\t\t'unsupported',\n\t\t\t`the ${placeholderCount} placeholder definition(s) across ${placeholderLayouts} slide layout(s) are not reproduced: the write path seeds every slide with each layout placeholder the slide did not populate, and since every source shape is authored here as concrete content rather than into a placeholder, re-declaring them would add an empty shape to every slide rather than a prompt`\n\t\t)\n\t}\n\n\treturn out\n}\n\n/**\n * Collapse the whitespace an XML attribute value cannot carry.\n *\n * Not a style choice: XML normalises a literal tab, carriage return or line feed inside an\n * attribute value to a space (XML 1.0 §3.3.3), and the write path emits a layout title as a\n * literal rather than as a `&#10;` character reference. So a PowerPoint layout named across\n * two lines — \"Abschnitts-⏎überschrift\" is a real one, in the German built-in set — comes back\n * with a space either way. Doing it here rather than leaving it to the serializer means the\n * emitted script states the title the output will actually have, and the round trip compares\n * two decks that agree instead of reporting a rename it cannot act on.\n */\nfunction flattenAttributeValue(value: string): string {\n\treturn value.replace(/[\\t\\r\\n]+/g, ' ')\n}\n\n/** A master/layout background reduced to what `BackgroundProps` accepts. */\nfunction backgroundProps(\n\tbackground: SlideBackground | null,\n\tnotes: NoteScope,\n\tassets: AssetResolver\n): IrValue | undefined {\n\tif (!background || background.type === 'none') return undefined\n\n\tswitch (background.type) {\n\t\tcase 'solid':\n\t\t\treturn background.color ? { color: literalColor(background.color.effectiveHex) } : undefined\n\t\tcase 'image': {\n\t\t\tconst asset = background.partName === null ? null : assets.assetFor(background.partName)\n\t\t\treturn asset ? { data: asset } : undefined\n\t\t}\n\t\tcase 'themeRef': {\n\t\t\t// `p:bgRef` indexes the theme's background fill list, which the write path cannot\n\t\t\t// author. The read model resolves it, so the flat colour survives even though the\n\t\t\t// reference — and therefore its response to a theme change — does not.\n\t\t\tconst fill = background.resolvedFill\n\t\t\tif (fill?.type === 'solid' && fill.color) {\n\t\t\t\tnotes.note(\n\t\t\t\t\t'master.background',\n\t\t\t\t\t'flattened',\n\t\t\t\t\t'unwritable',\n\t\t\t\t\t\"this layout's background is a theme reference (p:bgRef into the theme's background fill list), which has no write-API option; the colour it currently resolves to is baked in and stops following the theme\"\n\t\t\t\t)\n\t\t\t\treturn { color: literalColor(fill.color.effectiveHex) }\n\t\t\t}\n\t\t\tnotes.note(\n\t\t\t\t'master.background',\n\t\t\t\t'dropped',\n\t\t\t\t'unwritable',\n\t\t\t\t\"this layout's background is a theme reference to a non-solid fill, which has no write-API option; the layout is emitted with no background\"\n\t\t\t)\n\t\t\treturn undefined\n\t\t}\n\t\tdefault:\n\t\t\tnotes.note(\n\t\t\t\t'master.background',\n\t\t\t\t'dropped',\n\t\t\t\t'unsupported',\n\t\t\t\t`a ${background.type} layout background is not expressible through the write API's background option, so the layout is emitted with no background`\n\t\t\t)\n\t\t\treturn undefined\n\t}\n}\n","/**\n * The non-solid halves of a surface's fill — `a:gradFill` and `a:pattFill` — as\n * `ShapeFillProps`.\n *\n * Shared by a shape's fill, a table's background, and a table cell's, which are the same\n * two elements read from three containers. `ShapeProps.fill`, `TableProps.tableFill` and\n * `TableCellProps.fill` are all `ShapeFillProps`, so the mapping is identical and only the\n * note's `where` prefix differs — the same reasoning that keeps `pictureFillOption` in one\n * place rather than one copy per surface.\n */\nimport type { GradientFill } from '../../read/api/gradient.js'\nimport type { PatternFill } from '../../read/api/pattern-fill.js'\nimport type { NoteScope } from '../fidelity.js'\nimport type { IrValue } from '../ir.js'\nimport { alphaToTransparency, compact, isWritableSchemeToken, literalColor } from './values.js'\n\n/** How a note names the surface a gradient sits on: `fill.gradient`, `table.fill.gradient`, … */\nexport type FillNoteScope = 'fill' | 'line' | 'table.fill' | 'table.cell.fill'\n\n/**\n * A read gradient as `GradientFillProps`. Stop positions convert from the read model's\n * 0–1 fraction to the write API's 0–100 percentage; the angle needs no conversion, since\n * both sides use OOXML degrees (clockwise from 3 o'clock).\n */\nexport function gradientStops(gradient: GradientFill, notes: NoteScope, where: FillNoteScope): IrValue | undefined {\n\tconst stops = gradient.stops\n\t\t.map((stop) => {\n\t\t\tconst color = isWritableSchemeToken(stop.schemeColor)\n\t\t\t\t? (stop.schemeColor as string)\n\t\t\t\t: stop.effectiveHex === null\n\t\t\t\t\t? null\n\t\t\t\t\t: literalColor(stop.effectiveHex)\n\t\t\tif (color === null) return null\n\t\t\treturn compact({\n\t\t\t\tcolor,\n\t\t\t\tposition: Math.round((stop.position ?? 0) * 100),\n\t\t\t\ttransparency: alphaToTransparency(stop.alpha),\n\t\t\t}) as IrValue\n\t\t})\n\t\t.filter((stop): stop is IrValue => stop !== null)\n\n\tif (stops.length < 2) {\n\t\tnotes.note(\n\t\t\t`${where}.gradient`,\n\t\t\t'dropped',\n\t\t\t'unsupported',\n\t\t\t'a gradient with fewer than two resolvable stops cannot be expressed, so this falls back to no gradient'\n\t\t)\n\t\treturn undefined\n\t}\n\n\tif (gradient.kind === 'path') {\n\t\t// `a:path` covers circle/rect/shape; the write API models only the radial case, so\n\t\t// a rectangular or shape-following gradient becomes a circular one.\n\t\tif (gradient.path !== null && gradient.path !== 'circle') {\n\t\t\tnotes.note(\n\t\t\t\t`${where}.gradient.path`,\n\t\t\t\t'approximated',\n\t\t\t\t'unwritable',\n\t\t\t\t`a \"${gradient.path}\" path gradient is emitted as a radial one; the write API models no other path shape`\n\t\t\t)\n\t\t}\n\t\treturn { kind: 'radial', stops }\n\t}\n\treturn compact({ kind: 'linear', angle: gradient.angleDeg ?? 0, stops })\n}\n\n/**\n * A read hatch as `ShapeFillProps` with `type: 'pattern'`, or `undefined` when the pattern\n * names no preset — `a:pattFill/@prst` is what selects the hatch, so without it there is\n * nothing to reproduce.\n *\n * Both colours are emitted as literals rather than scheme tokens: `PatternFillProps` types\n * `fgColor`/`bgColor` as hex, so a token would not survive the write side anyway.\n */\nexport function patternOption(pattern: PatternFill | null): IrValue | undefined {\n\tif (!pattern?.preset) return undefined\n\treturn {\n\t\ttype: 'pattern',\n\t\tpattern: compact({\n\t\t\tpreset: pattern.preset,\n\t\t\tfgColor: pattern.foreground ? literalColor(pattern.foreground.effectiveHex) : undefined,\n\t\t\tbgColor: pattern.background ? literalColor(pattern.background.effectiveHex) : undefined,\n\t\t}) ?? { preset: pattern.preset },\n\t}\n}\n","/**\n * `a:blipFill` on a *surface* → the write API's `fill: { type: 'image', image: { data } }`.\n *\n * Shared by a shape's fill and a table cell's, which are the same construct read from two\n * containers: `TableCellProps.fill` and `ShapeProps.fill` are both `ShapeFillProps`, so\n * the mapping is identical and only the note wording differs. Keeping one implementation\n * is what stops the two drifting into different answers for the same `a:blipFill`.\n *\n * The bytes and the blip's opacity carry. Nothing else does, and that is a property of the\n * write path rather than of this mapper: `genXmlImageFill` emits every picture fill as\n * `<a:blipFill dpi=\"0\" rotWithShape=\"1\">…<a:srcRect/><a:stretch><a:fillRect/></a:stretch>`,\n * so a tiled fill comes back stretched and a cropped one comes back whole. That is a\n * visible change, so it is noted when — and only when — the source actually uses it.\n */\nimport type { FillRect, PictureFill } from '../../read/api/picture-fill.js'\nimport type { NoteScope } from '../fidelity.js'\nimport type { AssetRef, IrValue } from '../ir.js'\nimport type { AssetResolver } from './shape.js'\nimport { alphaToTransparency, compactRequired } from './values.js'\n\n/** How a note names the surface it is about; the mapping itself does not vary. */\nexport interface PictureFillSubject {\n\t/** Note construct for a fill whose bytes cannot be carried at all. */\n\tconstruct: string\n\t/** The surface as a note's detail names it — \"this shape's surface\", \"this table cell\". */\n\tsubject: string\n\t/** Where the fill sits in the source XML, for a note's detail. */\n\telement: string\n}\n\n/**\n * A picture fill as `ShapeFillProps`, or `undefined` when its bytes cannot be carried —\n * in which case a `dropped` note has been recorded and the surface comes out unfilled.\n */\nexport function pictureFillOption(\n\tpicture: PictureFill,\n\tassets: AssetResolver,\n\tnotes: NoteScope,\n\tsubject: PictureFillSubject\n): IrValue | undefined {\n\tconst asset = pictureAsset(picture, assets, notes, subject)\n\tif (!asset) return undefined\n\n\tnoteUncarriedGeometry(picture, notes, subject)\n\n\treturn compactRequired({\n\t\ttype: 'image',\n\t\timage: { data: asset },\n\t\t// Fully opaque passes as `undefined` rather than `0`; see `alphaToTransparency`.\n\t\ttransparency: picture.alpha === 1 ? undefined : alphaToTransparency(picture.alpha),\n\t})\n}\n\n/** The fill's image as an asset, or `null` with a note saying why it could not be one. */\nfunction pictureAsset(\n\tpicture: PictureFill,\n\tassets: AssetResolver,\n\tnotes: NoteScope,\n\tsubject: PictureFillSubject\n): AssetRef | null {\n\tconst partName = picture.partName\n\tif (partName === null) {\n\t\tnotes.note(\n\t\t\tsubject.construct,\n\t\t\t'dropped',\n\t\t\t'unsupported',\n\t\t\t`${subject.subject} is filled with an image (${subject.element}) that embeds no image part — an external or linked blip — so there are no bytes to carry and it comes out unfilled`\n\t\t)\n\t\treturn null\n\t}\n\n\t// The write path refuses an SVG picture fill outright (`src/gen/define/image.ts` warns\n\t// and falls back to `type: 'none'`), so emitting one would produce a script that paints\n\t// nothing while claiming a fill. Checked *before* `assetFor`, which would otherwise\n\t// register bytes that no call ends up referencing.\n\tif (assets.contentTypeOf(partName) === 'image/svg+xml') {\n\t\tnotes.note(\n\t\t\tsubject.construct,\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t`${subject.subject} is filled with an SVG image (${subject.element} → ${partName}); a picture fill accepts raster bytes only on the write side, so it comes out unfilled`\n\t\t)\n\t\treturn null\n\t}\n\n\tconst asset = assets.assetFor(partName)\n\tif (!asset) {\n\t\tnotes.note(\n\t\t\tsubject.construct,\n\t\t\t'dropped',\n\t\t\t'unsupported',\n\t\t\t`the image filling ${subject.subject} (${subject.element} → ${partName}) is not present in the package, so there are no bytes to carry`\n\t\t)\n\t\treturn null\n\t}\n\treturn asset\n}\n\n/** `true` when a rect actually insets an edge; an explicit but empty rect reports zeros. */\nfunction isRectSet(rect: FillRect | null): boolean {\n\treturn rect !== null && (rect.left !== 0 || rect.top !== 0 || rect.right !== 0 || rect.bottom !== 0)\n}\n\n/**\n * Note the parts of the fill's geometry the write path's fixed stretch cannot express.\n *\n * Only the ones the source actually uses: a note on every picture fill would say nothing,\n * and the round-trip check reads an unmatched note as a candidate for review.\n */\nfunction noteUncarriedGeometry(picture: PictureFill, notes: NoteScope, subject: PictureFillSubject): void {\n\tconst lost: string[] = []\n\tif (picture.mode === 'tile' || picture.tile !== null) lost.push('tiling (a:tile)')\n\tif (isRectSet(picture.srcRect)) lost.push('the source crop (a:srcRect)')\n\tif (isRectSet(picture.fillRect)) lost.push('the destination inset (a:stretch/a:fillRect)')\n\tif (picture.dpi !== null && picture.dpi !== 0) lost.push(`the render resolution (@dpi=\"${picture.dpi}\")`)\n\t// Only the explicit `0`. Unset means \"whatever the application defaults to\", which is\n\t// not a claim this note can make about a difference.\n\tif (picture.rotWithShape === false) lost.push('not rotating with the shape (@rotWithShape=\"0\")')\n\tif (lost.length === 0) return\n\n\tnotes.note(\n\t\t`${subject.construct}.geometry`,\n\t\t'approximated',\n\t\t'unwritable',\n\t\t`the image filling ${subject.subject} is re-embedded, but the write path emits every picture fill as a plain stretched blip (dpi=\"0\" rotWithShape=\"1\", <a:srcRect/><a:stretch><a:fillRect/></a:stretch>), so ${lost.join(', ')} ${lost.length === 1 ? 'does' : 'do'} not carry`\n\t)\n}\n","/**\n * `TextFrame` → `addText(TextProps[], TextPropsOptions)`.\n *\n * Two structural mismatches shape this mapper, and both are why the conversion is not a\n * field-by-field copy:\n *\n * 1. **The read model is a tree; `addText` takes a flat list.** OOXML nests runs inside\n * paragraphs; `TextProps[]` is one flat array where a paragraph boundary is a\n * `breakLine` flag on the item that *precedes* it. So the last run of each paragraph\n * carries the break, and a paragraph's own properties are replicated onto each of its\n * runs — the write path reads alignment and spacing off whichever run starts a line.\n *\n * 2. **Vocabularies differ on both sides of the same concept.** OOXML spells alignment\n * `l`/`ctr`/`r`/`just`, the write API spells it `left`/`center`/`right`/`justify`; two\n * of the six `@algn` values have no write spelling at all. Every such translation is a\n * table here rather than a pass-through, so an unmappable token produces a note instead\n * of an invalid option.\n *\n * Run-level reads prefer the *explicit* value over the resolved one, but only where leaving\n * the option out really does leave the value inherited. That is the part worth checking\n * rather than assuming: the round-trip harness found that an omitted run colour and an\n * omitted vertical anchor are both filled in by the write path — black, and centred — so\n * \"stay quiet and let it inherit\" was silently repainting text and re-anchoring bodies. Both\n * now emit the *resolved* value with a note, which freezes it against a later theme edit and\n * renders correctly, in preference to staying faithful in the IR and wrong on the slide.\n */\nimport type { BodyProperties, Paragraph, Run, TextFrame } from '../../read/api/text.js'\nimport type { NoteScope } from '../fidelity.js'\nimport type { IrValue } from '../ir.js'\nimport { compact, isWritableSchemeToken, literalColor, orUndefined, pointsToInches } from './values.js'\n\n/**\n * `a:pPr/@algn` → `HAlign`. `dist` and `thaiDist` (distributed justification) are\n * deliberately absent: the write API has no spelling for them, and mapping them onto\n * `justify` would be a silent visual change rather than a declared loss.\n */\nconst ALIGN: Record<string, string> = { l: 'left', ctr: 'center', r: 'right', just: 'justify' }\n\n/** `a:bodyPr/@anchor` → `VAlign`. */\nconst ANCHOR: Record<string, string> = { t: 'top', ctr: 'middle', b: 'bottom' }\n\n/** `AutofitMode` → the write API's `fit`. */\nconst FIT: Record<string, string> = { none: 'none', normAutofit: 'shrink', spAutoFit: 'resize' }\n\n/** `a:bodyPr/@vert` values the write API's `vert` accepts (`TextVertType`). */\nconst WRITABLE_VERT = new Set(['eaVert', 'horz', 'mongolianVert', 'vert', 'vert270', 'wordArtVert', 'wordArtVertRtl'])\n\n/**\n * `a:buAutoNum/@type` values, used to tell a numbered bullet from a character bullet.\n * The read model reports both as a single string — the character for `a:buChar`, the\n * `@type` token for `a:buAutoNum` — so membership here is the only discriminator.\n */\nconst AUTO_NUMBER_TYPES = new Set([\n\t'alphaLcParenBoth',\n\t'alphaLcParenR',\n\t'alphaLcPeriod',\n\t'alphaUcParenBoth',\n\t'alphaUcParenR',\n\t'alphaUcPeriod',\n\t'arabicParenBoth',\n\t'arabicParenR',\n\t'arabicPeriod',\n\t'arabicPlain',\n\t'romanLcParenBoth',\n\t'romanLcParenR',\n\t'romanLcPeriod',\n\t'romanUcParenBoth',\n\t'romanUcParenR',\n\t'romanUcPeriod',\n])\n\n/**\n * `Paragraph.bullet` → the write API's `bullet` option.\n *\n * The read model reports a **tagged** string — `'none'`, `'char:<glyph>'` or\n * `'autoNum:<type>'` — not a bare glyph, and the first version of this function read it as\n * one. The result was silent and universal: a paragraph that explicitly suppressed its\n * bullet (`a:buNone`, which is most of them) came back with a literal `n` bullet, because\n * `'none'.codePointAt(0)` is `n`; a real character bullet came back as `c`, from the `char:`\n * tag; and a numbered list came back as `a`. Every converted deck was affected and nothing\n * failed, which is why the round-trip check exists.\n */\nfunction bulletOption(bullet: string, notes: NoteScope): IrValue {\n\t// Explicit suppression, and it must stay explicit: an omitted `bullet` lets the\n\t// destination list style put one back.\n\tif (bullet === 'none') return false\n\n\tnotes.note(\n\t\t'text.bullet.style',\n\t\t'flattened',\n\t\t'unread',\n\t\t\"a bullet's own font, size and colour have no accessor (a:buFont / a:buSzPct / a:buClr), so it renders in the body font and colour\"\n\t)\n\n\tif (bullet.startsWith('autoNum:')) {\n\t\tconst scheme = bullet.slice('autoNum:'.length)\n\t\tnotes.note(\n\t\t\t'text.bullet.numberStartAt',\n\t\t\t'dropped',\n\t\t\t'unread',\n\t\t\t'a numbered bullet restarts at 1: nothing reads a:buAutoNum/@startAt, though addText accepts numberStartAt'\n\t\t)\n\t\tif (!AUTO_NUMBER_TYPES.has(scheme)) {\n\t\t\tnotes.note(\n\t\t\t\t'text.bullet.numberType',\n\t\t\t\t'approximated',\n\t\t\t\t'unwritable',\n\t\t\t\t`numbering scheme \"${scheme}\" is outside the set the write API names, so the list falls back to the default scheme`\n\t\t\t)\n\t\t\treturn { type: 'number' }\n\t\t}\n\t\treturn { type: 'number', numberType: scheme }\n\t}\n\n\t// Zero-padded to four digits, and that is load-bearing rather than cosmetic: the write\n\t// path tests `characterCode` against /^[0-9A-Fa-f]{4}$/ and, on a miss, warns to the\n\t// console and substitutes its own default glyph. So \"6E\" — a perfectly good code point —\n\t// silently became a different bullet character, visible only in the rendered slide.\n\tconst glyph = bullet.startsWith('char:') ? bullet.slice('char:'.length) : bullet\n\tconst code = glyph.codePointAt(0) ?? 0x2022\n\tif (code > 0xffff) {\n\t\tnotes.note(\n\t\t\t'text.bullet.glyph',\n\t\t\t'approximated',\n\t\t\t'unwritable',\n\t\t\t`bullet glyph U+${code.toString(16).toUpperCase()} is outside the Basic Multilingual Plane and characterCode takes a four-digit code, so the bullet falls back to the write path's default glyph`\n\t\t)\n\t}\n\treturn { characterCode: code.toString(16).toUpperCase().padStart(4, '0') }\n}\n\n/** Per-run character formatting, shared by shape text and table-cell text. */\nexport function runOptions(run: Run, notes: NoteScope): Record<string, IrValue> | undefined {\n\tconst underline = run.underline\n\tconst strike = run.strike\n\tconst caps = run.caps\n\n\treturn compact({\n\t\tbold: orUndefined(run.bold),\n\t\titalic: orUndefined(run.italic),\n\t\tunderline: underline === null || underline === 'none' ? undefined : { style: underline },\n\t\tstrike: strike === null || strike === 'noStrike' ? undefined : strike,\n\t\tfontSize: orUndefined(run.fontSizePt),\n\t\tfontFace: orUndefined(run.fontName),\n\t\tcolor: runColor(run, notes),\n\t\thighlight: run.highlight ? literalColor(run.highlight.effectiveHex) : undefined,\n\t\tcaps: caps === null || caps === 'none' ? undefined : caps,\n\t\t// The write API spells baseline shift as a percentage, the same unit the read\n\t\t// model reports, so superscript/subscript survive without a preset round-trip.\n\t\tbaseline: orUndefined(run.baselinePct),\n\t\thyperlink: hyperlinkOption(run),\n\t})\n}\n\n/**\n * A run's colour, preferring the raw `schemeClr` token over the resolved literal so the\n * text keeps tracking the destination theme. Only the ten tokens the write path's `clrMap`\n * covers survive as tokens; the other seven degrade to a literal hex there anyway, so\n * passing one through unchanged would produce a silently different colour.\n */\nfunction runColor(run: Run, notes: NoteScope): string | undefined {\n\tconst scheme = run.schemeColor\n\tif (isWritableSchemeToken(scheme)) return scheme as string\n\tif (scheme !== null) {\n\t\tnotes.note(\n\t\t\t'text.color.schemeToken',\n\t\t\t'approximated',\n\t\t\t'unwritable',\n\t\t\t`scheme colour \"${scheme}\" is outside the ten tokens the write path maps, so it is baked to a literal hex and stops tracking the theme`\n\t\t)\n\t\tconst resolved = run.resolvedColor\n\t\treturn resolved ? literalColor(resolved.effectiveHex) : undefined\n\t}\n\tif (run.color !== null) return literalColor(run.color)\n\n\t// A run with no colour of its own inherits one, and leaving the option out does *not* pass\n\t// that inheritance along: `addText` fills an uncoloured non-placeholder run with\n\t// DEF_FONT_COLOR, so omitting it repaints the text black. That makes this a loss either\n\t// way, and which loss depends on whether the inherited colour can be resolved — so the two\n\t// outcomes are declared separately rather than under one note that would overstate one and\n\t// understate the other.\n\tconst inherited = run.resolvedColor\n\tif (!inherited) {\n\t\tnotes.note(\n\t\t\t'text.color.default',\n\t\t\t'approximated',\n\t\t\t'unread',\n\t\t\t'this run inherits its colour and nothing resolves what it inherits (a table style tier, or a list style the read model does not walk), so the write path paints it black — the one case where the output colour is not merely frozen but possibly wrong'\n\t\t)\n\t\treturn undefined\n\t}\n\tnotes.note(\n\t\t'text.color.inherited',\n\t\t'flattened',\n\t\t'unsupported',\n\t\t'this run inherits its colour from the placeholder, master or theme; the write path paints an uncoloured run black instead of leaving it to inherit, so the inherited colour is resolved and baked in and no longer tracks a theme change'\n\t)\n\treturn literalColor(inherited.effectiveHex)\n}\n\n/**\n * A run's hyperlink. Only external links map: the read model reports an internal jump as a\n * target part name, while the write API takes a slide *number*, which the deck-level walk\n * resolves — so a slide link is handled there, not here.\n */\nfunction hyperlinkOption(run: Run): IrValue | undefined {\n\tconst link = run.hyperlink\n\tif (!link?.url) return undefined\n\treturn compact({ url: link.url, tooltip: link.tooltip ?? undefined })\n}\n\n/** Paragraph-level properties, replicated onto each of the paragraph's runs. */\nfunction paragraphOptions(paragraph: Paragraph, notes: NoteScope): Record<string, IrValue> {\n\tconst spacing = paragraph.lineSpacing\n\tconst bullet = paragraph.bullet\n\tconst align = paragraph.align\n\n\tif (align !== null && !(align in ALIGN)) {\n\t\tnotes.note(\n\t\t\t'text.align',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t`distributed alignment \"${align}\" has no write-API spelling, so the paragraph falls back to its inherited alignment`\n\t\t)\n\t}\n\tif (paragraph.spaceBeforePt === 0 || paragraph.spaceAfterPt === 0) {\n\t\tnotes.note(\n\t\t\t'text.paraSpaceZero',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t'this paragraph explicitly sets zero space before or after (a:spcBef / a:spcAft of 0), which suppresses the spacing its list style would otherwise apply; the write path treats 0 as \"unset\" and emits nothing, so the inherited spacing comes back'\n\t\t)\n\t}\n\tif (paragraph.marginLeftPt !== null || paragraph.indentPt !== null) {\n\t\tnotes.note(\n\t\t\t'text.indent',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t\"a paragraph's own indent (a:pPr/@marL, @indent) is not expressible; only the discrete indentLevel is, so hanging indents flatten to the level default\"\n\t\t)\n\t}\n\n\treturn (\n\t\tcompact({\n\t\t\talign: align === null ? undefined : ALIGN[align],\n\t\t\tindentLevel: paragraph.level === 0 ? undefined : paragraph.level,\n\t\t\tparaSpaceBefore: orUndefined(paragraph.spaceBeforePt),\n\t\t\tparaSpaceAfter: orUndefined(paragraph.spaceAfterPt),\n\t\t\tlineSpacing: spacing?.type === 'points' ? spacing.valuePt : undefined,\n\t\t\tlineSpacingMultiple: spacing?.type === 'percent' ? spacing.percent / 100 : undefined,\n\t\t\tbullet: bullet === null ? undefined : bulletOption(bullet, notes),\n\t\t}) ?? {}\n\t)\n}\n\n/**\n * Record the one bullet loss that has no expression at all, once per shape.\n *\n * A paragraph with no bullet child of its own inherits whatever the layout's or master's\n * list style says. There is no way to say \"inherit\" through the write API — an omitted\n * `bullet` makes it emit an explicit `a:buNone` — so an inherited bullet is suppressed. The\n * read side cannot see the inherited value either (`a:lvl1pPr` list styles are unread), so\n * the converter can neither reproduce it nor tell whether there was one, which is why this\n * is stated as a possibility rather than a fact.\n */\nfunction noteInheritedBullets(paragraphs: readonly Paragraph[], notes: NoteScope): void {\n\tif (!paragraphs.some((paragraph) => paragraph.bullet === null)) return\n\tnotes.note(\n\t\t'text.bullet.inherited',\n\t\t'dropped',\n\t\t'unread',\n\t\t'at least one paragraph sets no bullet of its own and inherits one from the layout or master list style; the write path cannot express \"inherit\" and emits an explicit a:buNone, so any inherited bullet is suppressed — a no-op where the inherited style had none, and a visible change where it did not'\n\t)\n}\n\n/**\n * Flatten a text frame into the `TextProps[]` first argument of `addText`.\n *\n * An empty paragraph becomes an item with empty text and a `breakLine`, which is how a\n * blank line survives — dropping it would silently close up vertical space the author put\n * there deliberately.\n */\nexport function textRuns(frame: TextFrame, notes: NoteScope): IrValue[] {\n\tconst paragraphs = frame.paragraphs\n\tconst items: IrValue[] = []\n\tnoteInheritedBullets(paragraphs, notes)\n\n\tparagraphs.forEach((paragraph, paragraphIndex) => {\n\t\tconst paraOpts = paragraphOptions(paragraph, notes)\n\t\tconst runs = paragraph.runs\n\t\t// The paragraph break rides on the last run of every paragraph but the final one;\n\t\t// a trailing break would add an empty line the frame never had.\n\t\tconst breaks = paragraphIndex < paragraphs.length - 1\n\n\t\tif (runs.length === 0) {\n\t\t\titems.push({ text: '', options: compact({ ...paraOpts, breakLine: breaks }) ?? {} })\n\t\t\treturn\n\t\t}\n\n\t\truns.forEach((run, runIndex) => {\n\t\t\tconst isLastRun = runIndex === runs.length - 1\n\t\t\t// `bullet` goes on the first run only, unlike the other paragraph properties. The\n\t\t\t// write path treats a bullet on a run that is *not* starting a line as a request for\n\t\t\t// a new paragraph — and clears that run's `breakLine` while it is at it — so\n\t\t\t// replicating the bullet split every bulleted paragraph that had more than one run.\n\t\t\t// It reads paragraph properties off whichever run opens the line, so once is enough.\n\t\t\tconst continuation = { ...paraOpts }\n\t\t\tdelete continuation['bullet']\n\t\t\tconst options = compact({\n\t\t\t\t...(runIndex === 0 ? paraOpts : continuation),\n\t\t\t\t...runOptions(run, notes),\n\t\t\t\t...(isLastRun && breaks ? { breakLine: true } : {}),\n\t\t\t})\n\t\t\titems.push(compact({ text: run.text, options }) ?? { text: run.text })\n\t\t})\n\t})\n\n\treturn items\n}\n\n/**\n * Frame-level layout for the `TextPropsOptions` second argument — everything that belongs\n * to the body as a whole rather than to any paragraph.\n *\n * `resolvedAnchor` is the one place a *resolved* read is the right one: vertical anchoring\n * has no per-run fallback, so an unset `a:bodyPr/@anchor` genuinely means \"whatever the\n * placeholder says\", and an appended shape does not inherit that.\n */\nexport function textFrameOptions(frame: TextFrame, notes: NoteScope): Record<string, IrValue> {\n\tconst body = frame.bodyProperties\n\tconst autofit = frame.autofit\n\tconst anchor = frame.resolvedAnchor\n\tconst vert = body?.vert ?? null\n\n\tif (vert !== null && !WRITABLE_VERT.has(vert)) {\n\t\tnotes.note(\n\t\t\t'text.vert',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t`text direction \"${vert}\" is outside TextVertType, so the body falls back to horizontal`\n\t\t)\n\t}\n\n\treturn (\n\t\tcompact({\n\t\t\t// Spelled out even when nothing in the source set it. `resolvedAnchor` returning\n\t\t\t// null means PowerPoint would default the body to top — but `addText` defaults a\n\t\t\t// non-placeholder body to *centre*, so leaving the option out re-anchors the text.\n\t\t\tvalign: anchor === null ? 'top' : ANCHOR[anchor],\n\t\t\t// `@wrap` is `square`/`none` in OOXML and a boolean in the write API.\n\t\t\twrap: body?.wrap === null || body?.wrap === undefined ? undefined : body.wrap !== 'none',\n\t\t\tvert: vert !== null && WRITABLE_VERT.has(vert) ? vert : undefined,\n\t\t\tfit: autofit === null ? undefined : FIT[autofit],\n\t\t\tmargin: marginOption(body),\n\t\t}) ?? {}\n\t)\n}\n\n/**\n * `a:bodyPr` insets as the write API's `margin`.\n *\n * A unit change, not just a copy: the read model reports insets in points, `margin` takes\n * **inches**, and it warns on any value `>= 1` on the assumption it is a stray points\n * value. Passing points straight through would therefore both inset the text by roughly\n * 72× too much and trip that warning.\n *\n * Emitted as the four-tuple whenever any inset is set, since a partial tuple is not\n * expressible; an unset side takes PowerPoint's own default rather than zero, so those are\n * spelled out — defaulting them to 0 would visibly reflow every body that sets one side.\n */\nconst DEFAULT_INSETS_PT = { left: 7.2, right: 7.2, top: 3.6, bottom: 3.6 }\n\nfunction marginOption(body: BodyProperties | null): IrValue | undefined {\n\tconst insets = body?.insetsPt\n\tif (!insets) return undefined\n\tconst { left, right, top, bottom } = insets\n\tif (left === undefined && right === undefined && top === undefined && bottom === undefined) return undefined\n\treturn [\n\t\tpointsToInches(top ?? DEFAULT_INSETS_PT.top),\n\t\tpointsToInches(right ?? DEFAULT_INSETS_PT.right),\n\t\tpointsToInches(bottom ?? DEFAULT_INSETS_PT.bottom),\n\t\tpointsToInches(left ?? DEFAULT_INSETS_PT.left),\n\t]\n}\n","/**\n * `Table` → `addTable(TableRow[], TableProps)`.\n *\n * Tables are the one place the exact-EMU rule stops. `colW` and `rowH` are number-typed\n * (inches) rather than `Coord`-typed, so they cannot take a raw-EMU string the way every\n * position and size can. They print at six decimal places, which is the measured minimum\n * at which `Math.round(inches × 914400)` returns the original EMU — the drift is bounded\n * at 0.4572 EMU, roughly half a millionth of an inch, and rounding shorter to make the\n * numbers look tidy would turn a cosmetic problem into a real geometry loss.\n *\n * Table *style* is the opposite story, and better than it looks. A style is a GUID into\n * the deck's `ppt/tableStyles.xml`, and a template-anchored output keeps that part intact,\n * so passing the source GUID through reproduces the banding, header shading, and borders\n * exactly rather than approximately. That is why per-cell fills read off the style graph\n * are deliberately *not* baked into each cell here: doing so would freeze the appearance\n * and stop the table responding to its own style.\n */\nimport type { CellBorder, Table, TableCell } from '../../read/api/table.js'\nimport type { GraphicFrame } from '../../read/api/shapes.js'\nimport type { NoteScope } from '../fidelity.js'\nimport type { CallIr, IrValue } from '../ir.js'\nimport type { AssetResolver } from './shape.js'\nimport { compact, emu, inches, literalColor, orUndefined } from './values.js'\nimport { pictureFillOption, type PictureFillSubject } from './picture-fill.js'\nimport { gradientStops, patternOption } from './surface-fill.js'\nimport { runOptions, textRuns } from './text.js'\n\n/** How {@link pictureFillOption}'s notes name a cell. */\nconst CELL_PICTURE_FILL: PictureFillSubject = {\n\tconstruct: 'table.cell.fill.picture',\n\tsubject: 'this table cell',\n\telement: 'a:tcPr/a:blipFill',\n}\n\n/** How {@link pictureFillOption}'s notes name the table's own background. */\nconst TABLE_PICTURE_FILL: PictureFillSubject = {\n\tconstruct: 'table.fill.picture',\n\tsubject: 'this table',\n\telement: 'a:tblPr/a:blipFill',\n}\n\n/** `a:tcPr/@anchor` → the write API's `valign`. */\nconst ANCHOR: Record<string, string> = { t: 'top', ctr: 'middle', b: 'bottom' }\n\nexport function tableCall(frame: GraphicFrame, table: Table, notes: NoteScope, assets: AssetResolver): CallIr {\n\tconst styleId = table.styleId\n\tconst hasStyle = table.resolvedStyle !== null\n\tconst rows: IrValue[] = []\n\tconst rowHeights: number[] = []\n\n\tfor (const row of table.rows) {\n\t\tconst cells: IrValue[] = []\n\t\tfor (const cell of row.cells) {\n\t\t\t// A merge continuation is the covered half of a span: it carries no content and\n\t\t\t// exists only so the grid stays rectangular. The write path derives those from\n\t\t\t// colspan/rowspan, so emitting them would double-count the span.\n\t\t\tif (cell.isMergeContinuation) continue\n\t\t\tcells.push(cellIr(cell, hasStyle, notes, assets))\n\t\t}\n\t\trows.push(cells)\n\t\trowHeights.push(row.heightEmu ?? 0)\n\t}\n\n\t// A row of height 0 is PowerPoint's \"auto — as tall as its content needs\", not a\n\t// zero-height row. The write path takes it literally and then lets the row grow anyway,\n\t// so the output reports whatever height the content forced. Nothing is visibly wrong;\n\t// the row simply stops being auto and is pinned to that measurement.\n\tif (rowHeights.some((height) => height === 0) && !rowHeights.every((height) => height === 0)) {\n\t\tnotes.note(\n\t\t\t'table.rowAuto',\n\t\t\t'approximated',\n\t\t\t'unsupported',\n\t\t\t'at least one row is auto-height (a:tr/@h of 0) while others are not; rowH must be given for every row or none, so the auto rows are emitted as 0 and come back pinned to the height their content produced'\n\t\t)\n\t}\n\n\tif (styleId === null) {\n\t\tnotes.note(\n\t\t\t'table.style',\n\t\t\t'dropped',\n\t\t\t'unsupported',\n\t\t\t\"this table names no a:tableStyleId, so it takes the generated deck's default table style\"\n\t\t)\n\t}\n\n\tconst columnWidths = table.columnWidths\n\tconst options = compact({\n\t\t...positionOfFrame(frame),\n\t\tobjectName: frame.name || undefined,\n\t\t// The source GUID resolves against the destination's own tableStyles.xml, which a\n\t\t// template-anchored output carries over intact.\n\t\ttableStyle: orUndefined(styleId),\n\t\t// `tableFill`, not `fill`: the source has one fill on `a:tblPr`, and `fill` would\n\t\t// flatten it into a copy on every cell, which is a different package for the same\n\t\t// picture. See `TableProps.tableFill`.\n\t\ttableFill: tableFill(table, notes, assets),\n\t\thasHeader: table.firstRowHeader ? true : undefined,\n\t\thasBandedRows: table.bandedRows ? true : undefined,\n\t\tcolW: columnWidths.every((w) => w === null) ? undefined : columnWidths.map((w) => inches(w ?? 0)),\n\t\trowH: rowHeights.every((h) => h === 0) ? undefined : rowHeights.map(inches),\n\t})\n\n\treturn { method: 'addTable', args: [rows, options ?? {}], ...(frame.name ? { sourceName: frame.name } : {}) }\n}\n\n/**\n * The table's own background (`a:tblPr` fill).\n *\n * Simpler than {@link cellFill}, and for one reason: a `a:tblPr` fill can only be the\n * table's own. There is no style graph feeding into it, so there is no\n * own-versus-inherited ambiguity to be careful about and the resolved colour can be used\n * directly. A scheme token still wins over the literal when there is one, so the replica\n * keeps tracking its theme.\n */\nfunction tableFill(table: Table, notes: NoteScope, assets: AssetResolver): IrValue | undefined {\n\tconst gradient = table.gradientFill\n\tif (gradient) {\n\t\tconst stops = gradientStops(gradient, notes, 'table.fill')\n\t\tif (stops) return { type: 'gradient', gradient: stops }\n\t}\n\n\tconst pattern = patternOption(table.patternFill)\n\tif (pattern) return pattern\n\n\tconst picture = table.pictureFill\n\tif (picture) return pictureFillOption(picture, assets, notes, TABLE_PICTURE_FILL)\n\n\tconst scheme = table.fillSchemeColor\n\tif (scheme !== null) return { color: scheme }\n\n\tconst resolved = table.resolvedFill\n\treturn resolved ? { color: literalColor(resolved.effectiveHex) } : undefined\n}\n\n/** A graphic frame's position; identical to a shape's, but frames never rotate or flip. */\nfunction positionOfFrame(frame: GraphicFrame): Record<string, IrValue> {\n\tconst box = frame.absoluteFrame\n\tif (!box) return {}\n\treturn { x: emu(box.left), y: emu(box.top), w: emu(box.width), h: emu(box.height) }\n}\n\n/**\n * One cell as a `TableCell`.\n *\n * Cell text reuses the shape text mapper, so a per-run format inside a cell behaves\n * identically to one on a shape — the read model already shares `TextFrame` between the\n * two, and diverging here would be a difference with no cause.\n */\nfunction cellIr(cell: TableCell, hasStyle: boolean, notes: NoteScope, assets: AssetResolver): IrValue {\n\tconst frame = cell.textFrame\n\tconst anchor = cell.anchor\n\tconst margins = cell.marginsEmu\n\n\t// `a:tc/@id` and `a:tcPr/a:headers` are the one pair here that is *deliberately* not\n\t// mapped. PowerPoint strips both on save (probe:\n\t// `test/read/fixtures/authoring/probe-table-cell-a11y-and-3d.ps1`), so there is no write\n\t// option to map them to and adding one would ship a feature that dies on the first save.\n\t// A source deck from another producer can still carry them, so the loss is recorded.\n\tif (cell.id !== null || cell.headerIds.length > 0) {\n\t\tnotes.note(\n\t\t\t'table.cell.headers',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t'this cell carries a screen-reader header association (a:tc/@id / a:tcPr/a:headers); PowerPoint strips both on save, so there is no write option and the association is lost — hasHeader (a:tblPr/@firstRow) is the marker that survives'\n\t\t)\n\t}\n\n\tconst options = compact({\n\t\tfill: cellFill(cell, hasStyle, notes, assets),\n\t\tborder: cellBorders(cell, notes),\n\t\tdiagonal: cellDiagonals(cell, notes),\n\t\tanchorCtr: cell.anchorCtr ? true : undefined,\n\t\tcell3D: cellThreeD(cell),\n\t\tvalign: anchor === null ? undefined : ANCHOR[anchor],\n\t\t// `textDirection` reaches `a:tcPr/@vert` through the same table-cell inheritance list every\n\t\t// other cell option uses, so a vertical label survives the round trip. Anything outside the\n\t\t// option's own union would be written back out verbatim as an invalid attribute.\n\t\ttextDirection: cellTextDirection(cell, notes),\n\t\t// Only the two values the write option accepts survive; anything else in the source\n\t\t// deck would be written straight back out as an invalid attribute.\n\t\thorzOverflow: cell.horzOverflow === 'clip' || cell.horzOverflow === 'overflow' ? cell.horzOverflow : undefined,\n\t\tcolspan: cell.gridSpan > 1 ? cell.gridSpan : undefined,\n\t\trowspan: cell.rowSpan > 1 ? cell.rowSpan : undefined,\n\t\t// `margin` takes inches, and the read model reports the insets in EMU.\n\t\tmargin: margins\n\t\t\t? [inches(margins.top ?? 0), inches(margins.right ?? 0), inches(margins.bottom ?? 0), inches(margins.left ?? 0)]\n\t\t\t: undefined,\n\t\t// A cell's own runs may each carry formatting; the first run's options double as the\n\t\t// cell default, which is how the write path applies cell-level character formatting.\n\t\t...(frame?.paragraphs[0]?.runs[0] ? (runOptions(frame.paragraphs[0].runs[0], notes) ?? {}) : {}),\n\t})\n\n\treturn compact({ text: frame ? textRuns(frame, notes) : cell.text, options }) ?? { text: '' }\n}\n\n/**\n * The two corner-to-corner rules as `TableCellProps.diagonal`.\n *\n * Kept out of {@link cellBorders}' tuple for the same reason the write option is: they are\n * not edges. Every dash and colour a diagonal can carry is one an edge can, so they share\n * {@link borderIr} — including its out-of-enum dash note.\n */\nfunction cellDiagonals(cell: TableCell, notes: NoteScope): IrValue | undefined {\n\tconst borders = cell.borders\n\tif (!borders || (!borders.tlToBr && !borders.blToTr)) return undefined\n\treturn compact({\n\t\ttlToBr: borders.tlToBr ? borderIr(borders.tlToBr, notes) : undefined,\n\t\tblToTr: borders.blToTr ? borderIr(borders.blToTr, notes) : undefined,\n\t})\n}\n\n/**\n * A cell's `a:cell3D` as `TableCellProps.cell3D`.\n *\n * Every field is passed through as read: the write path vets each against its `ST_` union\n * before emission, so a value from a source deck that somehow falls outside one is caught\n * there rather than being screened twice with two chances to disagree. Sizes are already in\n * points on both sides.\n */\nfunction cellThreeD(cell: TableCell): IrValue | undefined {\n\tconst cell3D = cell.cell3D\n\tif (!cell3D) return undefined\n\tconst rig = cell3D.lightRig\n\treturn (\n\t\tcompact({\n\t\t\tpreset: orUndefined(cell3D.bevel.preset),\n\t\t\twidth: orUndefined(cell3D.bevel.widthPt),\n\t\t\theight: orUndefined(cell3D.bevel.heightPt),\n\t\t\tmaterial: orUndefined(cell3D.material),\n\t\t\t// CT_LightRig requires both, so a half-specified one from a source deck is dropped\n\t\t\t// rather than passed on for the emitter to reject.\n\t\t\tlightRig: rig?.rig && rig.dir ? { rig: rig.rig, dir: rig.dir } : undefined,\n\t\t}) ?? {}\n\t)\n}\n\n/** The `ST_TextVerticalType` values `TextBaseProps.textDirection` accepts. */\nconst WRITABLE_TEXT_DIRECTIONS = new Set(['horz', 'vert', 'vert270', 'wordArtVert'])\n\n/**\n * A cell's `a:tcPr/@vert` as the write API's `textDirection`.\n *\n * `ST_TextVerticalType` has nine values and the write option covers four. The rest\n * (`eaVert`, `mongolianVert`, the WordArt right-to-left variants) are East-Asian layout\n * modes with no `TextBaseProps` spelling, so they are noted rather than written — passing\n * one straight through would put a value the option does not admit into the attribute.\n */\nfunction cellTextDirection(cell: TableCell, notes: NoteScope): IrValue | undefined {\n\tconst vert = cell.verticalText\n\tif (vert === null || vert === 'horz') return undefined\n\tif (WRITABLE_TEXT_DIRECTIONS.has(vert)) return vert\n\tnotes.note(\n\t\t'table.cell.vert',\n\t\t'dropped',\n\t\t'unwritable',\n\t\t`this cell's a:tcPr/@vert is \\`${vert}\\`, which textDirection does not spell (it covers horz/vert/vert270/wordArtVert), so its text lands horizontal`\n\t)\n\treturn undefined\n}\n\n/**\n * A cell's fill.\n *\n * The question here is not \"what colour is this cell\" but \"what did the *source* say\", and\n * the two differ for a styled table: `resolvedFill` answers the first, folding the cell's\n * own `a:solidFill` together with the colour it merely inherits from the style's\n * header/banding rules. Writing an inherited colour back would turn every banded cell into\n * an explicitly-filled one — the copy looks right until someone changes its table style, and\n * then nothing moves.\n *\n * {@link TableCell.hasOwnFill} separates them: an `a:tcPr` either carries an\n * `EG_FillProperties` child or it does not. So a cell's own fill is emitted (in whatever\n * form it took), and a cell with none is left to the style GUID, which reproduces the\n * banding exactly rather than approximately. Neither case loses anything, which is why\n * neither records a note.\n */\nfunction cellFill(cell: TableCell, hasStyle: boolean, notes: NoteScope, assets: AssetResolver): IrValue | undefined {\n\t// Every non-solid choice comes first, and for one shared reason: a cell whose `a:tcPr`\n\t// holds a `a:gradFill`/`a:pattFill`/`a:blipFill` holds no `a:solidFill` for the colour\n\t// legs below to find, so `resolvedFill` would answer with the table style's banding\n\t// colour and paint over the cell with something the source never showed.\n\tconst gradient = cell.gradientFill\n\tif (gradient) {\n\t\tconst stops = gradientStops(gradient, notes, 'table.cell.fill')\n\t\tif (stops) return { type: 'gradient', gradient: stops }\n\t}\n\n\tconst pattern = patternOption(cell.patternFill)\n\tif (pattern) return pattern\n\n\tconst picture = cell.pictureFill\n\tif (picture) return pictureFillOption(picture, assets, notes, CELL_PICTURE_FILL)\n\n\tconst scheme = cell.fillSchemeColor\n\tif (scheme !== null) return { color: scheme }\n\n\t// A styled cell with no fill of its own takes the style's banding, and the style GUID\n\t// travels with the table — so emitting nothing here is not a loss, it is what keeps the\n\t// copy responsive to its own style.\n\tif (hasStyle && !cell.hasOwnFill) return undefined\n\n\tconst resolved = cell.resolvedFill\n\tif (!resolved) return undefined\n\t// Reached only when the cell's fill IS its own: either there is no style to inherit from,\n\t// or `hasOwnFill` said so. The literal is exact for a `srgbClr`, and for the rarer colour\n\t// models (`a:sysClr`, `a:prstClr`, `a:hslClr`, …) it is the colour they resolve to, which\n\t// is the closest the write API's hex option can come.\n\treturn { color: literalColor(resolved.effectiveHex) }\n}\n\n/**\n * The four edge borders as the write API's `[top, right, bottom, left]` tuple.\n *\n * A suppressed edge (`a:noFill`) becomes `type: 'none'`, which is distinct from an absent\n * one — the first means \"deliberately no rule here\", the second means \"inherit\". The two\n * diagonals the read model also decodes are carried separately, by {@link cellDiagonals}.\n */\nfunction cellBorders(cell: TableCell, notes: NoteScope): IrValue | undefined {\n\tconst borders = cell.borders\n\tif (!borders) return undefined\n\n\tconst edges = [borders.top, borders.right, borders.bottom, borders.left]\n\tif (edges.every((edge) => edge === null)) return undefined\n\n\treturn edges.map((edge) => borderIr(edge, notes))\n}\n\n/** The `ST_PresetLineDashVal` tokens `BorderProps.dashType` accepts. */\nconst WRITABLE_DASHES = new Set([\n\t'solid',\n\t'dot',\n\t'dash',\n\t'lgDash',\n\t'dashDot',\n\t'lgDashDot',\n\t'lgDashDotDot',\n\t'sysDash',\n\t'sysDot',\n\t'sysDashDot',\n\t'sysDashDotDot',\n])\n\n/**\n * One decoded edge (or diagonal) as `BorderProps`.\n *\n * `type` stays the coarse on/off switch and `dashType` carries the exact preset, so a\n * `lgDashDot` rule comes back as itself rather than as the generic `sysDash` every dash\n * used to collapse onto. A dash outside `ST_PresetLineDashVal` cannot have come from a\n * conformant deck, so it is dropped to a plain dashed rule and noted.\n */\nfunction borderIr(edge: CellBorder | null, notes: NoteScope): IrValue {\n\tif (!edge) return {}\n\tif (edge.noFill) return { type: 'none' }\n\tconst dash = edge.dash\n\tconst known = dash === null || WRITABLE_DASHES.has(dash)\n\tif (!known) {\n\t\tnotes.note(\n\t\t\t'table.cell.borders.dash',\n\t\t\t'approximated',\n\t\t\t'unsupported',\n\t\t\t`a cell border's a:prstDash/@val is \\`${dash}\\`, which is outside ST_PresetLineDashVal; it is written as a plain dashed rule`\n\t\t)\n\t}\n\treturn (\n\t\tcompact({\n\t\t\ttype: dash === null || dash === 'solid' ? 'solid' : 'dash',\n\t\t\t// `solid` is what an absent/solid dash already implies, so emitting it would be noise.\n\t\t\tdashType: known && dash !== null && dash !== 'solid' ? dash : undefined,\n\t\t\tcolor: edge.schemeColor ?? (edge.color === null ? undefined : literalColor(edge.color)),\n\t\t\twidth: orUndefined(edge.widthPt),\n\t\t}) ?? {}\n\t)\n}\n","/**\n * `Chart` → `addChart(OptsChartData[], ChartOpts)`.\n *\n * The open question this mapper settles is where the data comes from. A `.pptx` chart\n * carries its numbers twice: once in an embedded `.xlsx` workbook, and once as *cached*\n * values inside the chart XML itself (`c:tx`, `c:cat`, `c:val`) so a viewer can render\n * without opening the workbook. Probing the fixtures showed the cache is complete for\n * every chart the write API can express, so the workbook never needs cracking — which\n * removes a whole spreadsheet parser from this project's dependency surface.\n *\n * The one seam is blanks. The read model reports `(number | null)[]`, since a cached point\n * may legitimately be empty, while `OptsChartData.values` is `number[]`. A blank becomes\n * `0`, which is a visible change on a line chart — a gap turns into a dip to the axis — so\n * it is noted rather than quietly coerced.\n *\n * A rebuilt chart also gets a *regenerated* workbook rather than the source one, so\n * double-clicking it in PowerPoint opens data that matches the plot but has lost the source\n * sheet's formulas, extra columns, and formatting.\n */\nimport type { Chart } from '../../read/api/chart.js'\nimport type { GraphicFrame } from '../../read/api/shapes.js'\nimport type { NoteScope } from '../fidelity.js'\nimport type { CallIr, IrValue } from '../ir.js'\nimport { compact, emu, literalColor, orUndefined } from './values.js'\n\n/**\n * Read chart-group token → `CHART_NAME`. The read model strips the `Chart` suffix from the\n * plot-area element name, so `c:barChart` arrives as `bar`. A 3-D group maps onto the\n * matching flat type where one exists; anything absent from this table has no write-API\n * chart type and is reported rather than guessed at.\n */\nconst CHART_TYPE: Record<string, string> = {\n\tarea: 'area',\n\tarea3D: 'area',\n\tbar: 'bar',\n\tbar3D: 'bar3D',\n\tbubble: 'bubble',\n\tbubble3D: 'bubble3D',\n\tdoughnut: 'doughnut',\n\tline: 'line',\n\tline3D: 'line',\n\tpie: 'pie',\n\tpie3D: 'pie',\n\tradar: 'radar',\n\tscatter: 'scatter',\n\tstock: 'stock',\n\tsurface: 'surface',\n\tsurface3D: 'surface',\n}\n\n/** `c:legendPos/@val` → the write API's `legendPos`. */\nconst LEGEND_POS: Record<string, string> = { r: 'r', l: 'l', t: 't', b: 'b', tr: 'tr' }\n\nexport function chartCall(frame: GraphicFrame, chart: Chart, notes: NoteScope): CallIr | null {\n\tconst sourceType = chart.chartType\n\tconst type = sourceType === null ? undefined : CHART_TYPE[sourceType]\n\tif (!type) {\n\t\tnotes.note(\n\t\t\t'chart.type',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t`chart type \"${sourceType ?? 'none'}\" has no write-API counterpart, so the chart is omitted`\n\t\t)\n\t\treturn null\n\t}\n\n\tif (chart.chartTypes.length > 1) {\n\t\tnotes.note(\n\t\t\t'chart.combo',\n\t\t\t'flattened',\n\t\t\t'unsupported',\n\t\t\t`a combo chart (${chart.chartTypes.join(' + ')}) is emitted as a single ${type} chart; addChart's multi-type form needs a per-series type the read model does not report`\n\t\t)\n\t}\n\n\tnotes.note(\n\t\t'chart.workbook',\n\t\t'approximated',\n\t\t'unsupported',\n\t\t\"the chart is rebuilt from its cached plot values, so its embedded workbook is regenerated: the plotted numbers match, but the source sheet's formulas, extra columns and formatting are gone\"\n\t)\n\n\tconst data = seriesData(chart, notes)\n\tif (data.length === 0) {\n\t\tnotes.note('chart.data', 'dropped', 'unsupported', 'this chart caches no plottable series values')\n\t\treturn null\n\t}\n\n\t// `type` is an *option*, not a positional argument: the signature is\n\t// `addChart(data, options & { type })`. Passing it separately produces a call that\n\t// typechecks nowhere and throws \"a chart `type` is required\" at run time.\n\tconst options = compact({\n\t\ttype,\n\t\t...positionOfFrame(frame),\n\t\tobjectName: frame.name || undefined,\n\t\t...titleOptions(chart),\n\t\t...legendOptions(chart),\n\t\t...labelOptions(chart),\n\t\t...axisOptions(chart),\n\t\tchartColors: seriesColors(chart),\n\t})\n\n\treturn {\n\t\tmethod: 'addChart',\n\t\targs: [data, options ?? { type }],\n\t\t...(frame.name ? { sourceName: frame.name } : {}),\n\t}\n}\n\n/** A graphic frame's position; frames never rotate or flip. */\nfunction positionOfFrame(frame: GraphicFrame): Record<string, IrValue> {\n\tconst box = frame.absoluteFrame\n\tif (!box) return {}\n\treturn { x: emu(box.left), y: emu(box.top), w: emu(box.width), h: emu(box.height) }\n}\n\n/**\n * Series as `OptsChartData[]`. Category labels ride on the first series, which is the shape\n * `addChart` expects; the read model reports them per-series but they are shared in\n * practice.\n */\nfunction seriesData(chart: Chart, notes: NoteScope): IrValue[] {\n\tconst categories = chart.categories.map((label) => label ?? '')\n\tlet sawBlank = false\n\n\tconst data = chart.series.map((series, index) => {\n\t\tconst values = series.values.map((value) => {\n\t\t\tif (value === null) sawBlank = true\n\t\t\treturn value ?? 0\n\t\t})\n\t\treturn (\n\t\t\tcompact({\n\t\t\t\tname: orUndefined(series.name),\n\t\t\t\tvalues,\n\t\t\t\t// Only the first series carries labels, matching how addChart reads them.\n\t\t\t\tlabels: index === 0 && categories.length > 0 ? categories : undefined,\n\t\t\t}) ?? { values }\n\t\t)\n\t})\n\n\tif (sawBlank) {\n\t\tnotes.note(\n\t\t\t'chart.blanks',\n\t\t\t'approximated',\n\t\t\t'unwritable',\n\t\t\t'a blank cached data point becomes 0, because OptsChartData.values is number[] and has no spelling for a gap; on a line chart this draws a dip to the axis where the source showed a break'\n\t\t)\n\t}\n\treturn data\n}\n\nfunction titleOptions(chart: Chart): Record<string, IrValue | undefined> {\n\tconst title = chart.title\n\treturn title === null ? {} : { showTitle: true, title }\n}\n\nfunction legendOptions(chart: Chart): Record<string, IrValue | undefined> {\n\tconst legend = chart.legend\n\tif (!legend) return { showLegend: false }\n\treturn {\n\t\tshowLegend: true,\n\t\tlegendPos: legend.position === null ? undefined : LEGEND_POS[legend.position],\n\t}\n}\n\nfunction labelOptions(chart: Chart): Record<string, IrValue | undefined> {\n\tconst labels = chart.dataLabels\n\tif (!labels) return {}\n\treturn {\n\t\tshowValue: labels.showValue ?? undefined,\n\t\tshowSerName: labels.showSeriesName ?? undefined,\n\t\tshowCatName: labels.showCategoryName ?? undefined,\n\t\tshowPercent: labels.showPercent ?? undefined,\n\t\tshowLegendKey: labels.showLegendKey ?? undefined,\n\t\tshowLeaderLines: labels.showLeaderLines ?? undefined,\n\t\tdataLabelPosition: orUndefined(labels.position),\n\t\tdataLabelFormatCode: labels.numberFormat?.formatCode ?? undefined,\n\t}\n}\n\n/**\n * Axis bounds, titles and gridlines. The write API spells these as a flat `catAxis*` /\n * `valAxis*` prefix set rather than an axis object, so each side is unpacked by hand.\n */\nfunction axisOptions(chart: Chart): Record<string, IrValue | undefined> {\n\tconst cat = chart.categoryAxis\n\tconst val = chart.valueAxis\n\treturn {\n\t\tcatAxisHidden: cat?.hidden ? true : undefined,\n\t\tcatAxisTitle: cat?.title ?? undefined,\n\t\tvalAxisHidden: val?.hidden ? true : undefined,\n\t\tvalAxisTitle: val?.title ?? undefined,\n\t\tvalAxisMinVal: val?.min ?? undefined,\n\t\tvalAxisMaxVal: val?.max ?? undefined,\n\t\tvalAxisMajorUnit: val?.majorUnit ?? undefined,\n\t\tvalAxisLabelFormatCode: val?.numberFormat?.formatCode ?? undefined,\n\t}\n}\n\n/**\n * Per-series fill colours as `chartColors`, which is positional — entry `n` colours series\n * `n`. A series with no explicit fill takes the theme's accent for its position, which the\n * read model does not resolve, so the whole option is dropped unless every series names a\n * colour; a partial list would silently recolour the unnamed ones.\n */\nfunction seriesColors(chart: Chart): IrValue | undefined {\n\tconst series = chart.series\n\tif (series.length === 0) return undefined\n\tconst colors: string[] = []\n\tfor (const one of series) {\n\t\tconst fill = one.fill\n\t\tconst hex = fill?.color\n\t\tif (!hex) return undefined\n\t\tcolors.push(literalColor(hex))\n\t}\n\treturn colors\n}\n","/**\n * `AnyShape` → one {@link CallIr}.\n *\n * The dispatch is on what the shape *is*, not on what it looks like: an `AutoShape` with a\n * text frame and no geometry is an `addText`, one with geometry is an `addShape` that may\n * also carry text, a `Picture` is an `addImage`, and a `GraphicFrame` delegates to the\n * table or chart mapper. A `GroupShape` recurses.\n *\n * The single most important thing this module does is record what it cannot carry.\n * Measurement against the fixture corpus found the binding constraint is the *read* side,\n * not the write side — several constructs the write API can express have no accessor at\n * all — so a converter that mapped only what it could see would produce clean-looking\n * output with silent visual losses. The clearest is theme-referenced line styling: a shape\n * whose outline comes from `p:style/a:lnRef` reports a colour through `resolvedLine` but\n * reports `null` for width and dash, because there is a resolved-colour path and no\n * resolved-width path. In the corpus that was every such shape, 25 of 25, so a themed 2pt\n * border silently becomes a 1pt default. Each one is noted here rather than quietly thinned.\n */\nimport type {\n\tAnyShape,\n\tAutoShape,\n\tConnector,\n\tCustomGeometry,\n\tGraphicFrame,\n\tGroupShape,\n\tPicture,\n} from '../../read/api/shapes.js'\nimport { isAutoShape, isConnector, isGraphicFrame, isGroupShape, isPicture } from '../../read/api/shapes.js'\nimport type { NoteScope } from '../fidelity.js'\nimport type { AssetRef, CallIr, IrValue } from '../ir.js'\nimport { alphaToTransparency, compact, emu, isWritableSchemeToken, literalColor, orUndefined } from './values.js'\nimport { gradientStops, patternOption } from './surface-fill.js'\nimport { pictureFillOption, type PictureFillSubject } from './picture-fill.js'\nimport { hasEquation, hasIdentityChildSpace, isAudioVideo, isTextBox } from './detect.js'\nimport { textFrameOptions, textRuns } from './text.js'\nimport { tableCall } from './table.js'\nimport { chartCall } from './chart.js'\n\n/** Resolves an image/media part name to bytes the deck-level walk has registered. */\nexport interface AssetResolver {\n\t/** Register a part's bytes and hand back the reference that stands in for them. */\n\tassetFor(partName: string): AssetRef | null\n\t/**\n\t * The part's content type, or `null` when it is not in the package.\n\t *\n\t * Separate from {@link assetFor} because it has to be answerable *without* registering\n\t * anything: a caller that rejects a part on its type (a picture fill's SVG blip, which\n\t * the write path refuses) would otherwise leave bytes in the asset list that no call\n\t * references, and those bytes are emitted as a file next to the script.\n\t */\n\tcontentTypeOf(partName: string): string | null\n}\n\n/** How {@link pictureFillOption}'s notes name a shape's surface. */\nconst SHAPE_PICTURE_FILL: PictureFillSubject = {\n\tconstruct: 'fill.picture',\n\tsubject: \"this shape's surface\",\n\telement: 'a:blipFill',\n}\n\n/** Arrowhead types `ShapeLineProps` accepts; `a:headEnd/@type` uses the same tokens. */\nconst WRITABLE_ARROWS = new Set(['none', 'arrow', 'diamond', 'oval', 'stealth', 'triangle'])\n\n/** Dash tokens `ShapeLineProps.dashType` accepts — the whole `ST_PresetLineDashVal` set. */\nconst WRITABLE_DASHES = new Set([\n\t'solid',\n\t'dot',\n\t'dash',\n\t'lgDash',\n\t'dashDot',\n\t'lgDashDot',\n\t'lgDashDotDot',\n\t'sysDash',\n\t'sysDot',\n\t'sysDashDot',\n\t'sysDashDotDot',\n])\n\n/**\n * Map one shape. Returns `null` when the shape produces no call at all — a note is always\n * recorded in that case, so a dropped shape is never silent.\n */\nexport function shapeCall(shape: AnyShape, notes: NoteScope, assets: AssetResolver): CallIr | null {\n\tconst scoped = notes.forShape(shape.name || null)\n\n\tif (shape.hidden) {\n\t\t// `p:cNvPr/@hidden` has no write-API counterpart, so a hidden shape would come back\n\t\t// visible. Omitting it preserves what the deck looks like, which is the lesser loss.\n\t\tscoped.note(\n\t\t\t'shape.hidden',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t'a hidden shape has no write-API expression; it is omitted rather than emitted visible'\n\t\t)\n\t\treturn null\n\t}\n\n\tif (isGroupShape(shape)) return groupCall(shape, scoped, assets)\n\tif (isPicture(shape)) return pictureCall(shape, scoped, assets)\n\tif (isConnector(shape)) return connectorCall(shape, scoped)\n\tif (isGraphicFrame(shape)) return graphicFrameCall(shape, scoped, assets)\n\tif (isAutoShape(shape)) return autoShapeCall(shape, scoped, assets)\n\n\t// Unreachable: the five guards above exhaust `AnyShape`, which is why `shape` narrows to\n\t// `never` here. Left as a floor so a sixth shape kind fails to compile at the call sites\n\t// that assume a call, rather than silently falling through to a silent drop.\n\treturn null\n}\n\n/* ===== position, fill, line, effects — shared by every shape kind ===== */\n\n/**\n * Position as `Coord`-typed EMU strings, so the source geometry survives exactly.\n *\n * `absoluteFrame` rather than the raw `left`/`top`: a shape inside a group is positioned in\n * its group's child coordinate space, which a flattened call list cannot express, so the\n * group transform has to be composed in here. For a top-level shape the two are identical.\n */\nfunction positionOptions(shape: AnyShape, notes?: NoteScope): Record<string, IrValue> {\n\tconst frame = shape.absoluteFrame\n\tif (frame) return { x: emu(frame.left), y: emu(frame.top), w: emu(frame.width), h: emu(frame.height) }\n\n\t// No transform of its own — a placeholder taking its geometry from the layout or master.\n\t// `resolvedFrame` walks that chain, and using it is not optional: omitting the geometry\n\t// does *not* leave it to be inherited, because a regenerated slide's placeholder inherits\n\t// nothing. It produces `x=0 y=0 w=<slide width> h=0` — a zero-height box in the corner,\n\t// which is broken output rather than lossy output.\n\tconst resolved = shape.resolvedFrame\n\tif (!resolved) return {}\n\tnotes?.note(\n\t\t'shape.frameInherited',\n\t\t'flattened',\n\t\t'unsupported',\n\t\t`this shape has no transform of its own and takes its geometry from the ${resolved.source}; a regenerated slide inherits nothing, so the resolved position is baked in and stops tracking later edits to that ${resolved.source}`\n\t)\n\treturn { x: emu(resolved.left), y: emu(resolved.top), w: emu(resolved.width), h: emu(resolved.height) }\n}\n\n/**\n * Rotation and flips. Taken from `absoluteFrame`, which composes enclosing group rotations\n * and XOR-composes group flips — the same reason position is absolute.\n */\nfunction transformOptions(shape: AnyShape): Record<string, IrValue | undefined> {\n\tconst frame = shape.absoluteFrame\n\tconst rotate = frame ? frame.rotation : (shape.rotation ?? 0)\n\treturn {\n\t\trotate: rotate === 0 ? undefined : rotate,\n\t\tflipH: (frame?.flipH ?? shape.flipH) ? true : undefined,\n\t\tflipV: (frame?.flipV ?? shape.flipV) ? true : undefined,\n\t}\n}\n\n/**\n * A shape's fill as `ShapeFillProps`.\n *\n * Prefers the raw scheme token over `resolvedFill` for the same reason run colour does: a\n * token keeps tracking the destination theme. `resolvedFill` is the fallback because it is\n * the only accessor that sees a `p:style/a:fillRef` — a shape styled entirely from the\n * theme has no `a:solidFill` of its own, so without it the shape would come out unfilled.\n */\nfunction fillOption(shape: AnyShape, notes: NoteScope, assets: AssetResolver): IrValue | undefined {\n\tconst gradient = shape.gradientFill\n\tif (gradient) {\n\t\tconst stops = gradientStops(gradient, notes, 'fill')\n\t\tif (stops) return { type: 'gradient', gradient: stops }\n\t}\n\n\tconst pattern = patternOption(shape.patternFill)\n\tif (pattern) return pattern\n\n\t// An image-filled *surface* is not a picture object — it is `ShapeFillProps.image`, so\n\t// the bytes are re-embedded through the same asset resolver an `addImage` uses. Before\n\t// the fill option itself, since a shape carrying a `a:blipFill` has no `a:solidFill` for\n\t// the colour legs below to find.\n\tconst picture = shape.pictureFill\n\tif (picture) return pictureFillOption(picture, assets, notes, SHAPE_PICTURE_FILL)\n\n\tconst scheme = shape.fillSchemeColor\n\tif (isWritableSchemeToken(scheme)) return { color: scheme as string }\n\tif (shape.fillColor !== null) return { color: literalColor(shape.fillColor) }\n\n\tconst resolved = shape.resolvedFill\n\tif (!resolved) return undefined\n\tif (scheme !== null) {\n\t\tnotes.note(\n\t\t\t'fill.schemeToken',\n\t\t\t'approximated',\n\t\t\t'unwritable',\n\t\t\t`fill scheme colour \"${scheme}\" is outside the ten tokens the write path maps, so it is baked to a literal hex and stops tracking the theme`\n\t\t)\n\t}\n\treturn compact({\n\t\tcolor: literalColor(resolved.effectiveHex),\n\t\ttransparency: alphaToTransparency(resolved.alpha),\n\t})\n}\n\n/**\n * A shape's outline as `ShapeLineProps`.\n *\n * This is where the measured silent loss lives. When a shape takes its outline from\n * `p:style/a:lnRef`, `resolvedLine` supplies the colour but `lineWidthPt` and `lineDash`\n * both report `null` — the theme's `a:lnStyleLst` entry, where the width and dash actually\n * live, has no accessor. Emitting the colour and noting the rest is the honest outcome;\n * inventing a width would be worse, because it would look deliberate.\n */\nfunction lineOption(shape: AnyShape, notes: NoteScope): Record<string, IrValue> | undefined {\n\tif (shape.lineNoFill) return { type: 'none' }\n\n\tconst gradient = shape.lineGradient\n\tif (gradient) {\n\t\tconst stops = gradientStops(gradient, notes, 'line')\n\t\tif (stops) return { type: 'gradient', gradient: stops }\n\t}\n\n\tconst widthPt = shape.lineWidthPt\n\tconst dash = shape.lineDash\n\tconst scheme = shape.lineSchemeColor\n\tconst resolved = shape.resolvedLine\n\n\tlet color: string | undefined\n\tif (isWritableSchemeToken(scheme)) color = scheme as string\n\telse if (shape.lineColor !== null) color = literalColor(shape.lineColor)\n\telse if (resolved) color = literalColor(resolved.effectiveHex)\n\n\t// A colour only `resolvedLine` could supply means the stroke came from the theme style\n\t// list, whose width and dash are unreadable.\n\tif (resolved !== null && shape.lineColor === null && scheme === null && widthPt === null) {\n\t\tnotes.note(\n\t\t\t'line.width',\n\t\t\t'dropped',\n\t\t\t'unread',\n\t\t\t'this outline comes from the theme style list (p:style/a:lnRef); its width and dash live in the theme fmtScheme a:lnStyleLst, which has no accessor, so only the colour carries'\n\t\t)\n\t}\n\tif (dash !== null && !WRITABLE_DASHES.has(dash)) {\n\t\tnotes.note(\n\t\t\t'line.dash',\n\t\t\t'approximated',\n\t\t\t'unwritable',\n\t\t\t`dash style \"${dash}\" is outside the eight the write API accepts, so the outline falls back to solid`\n\t\t)\n\t}\n\n\tconst options = compact({\n\t\tcolor,\n\t\twidth: orUndefined(widthPt),\n\t\tdashType: dash !== null && WRITABLE_DASHES.has(dash) ? dash : undefined,\n\t\ttransparency: alphaToTransparency(resolved?.alpha),\n\t\t...arrowOptions(shape, notes),\n\t})\n\treturn options\n}\n\n/** Arrowheads. Types map directly; the `sm`/`med`/`lg` size classes have no option. */\nfunction arrowOptions(shape: AnyShape, notes: NoteScope): Record<string, IrValue | undefined> {\n\tconst ends = shape.lineEnds\n\tif (!ends) return {}\n\tconst sized = [ends.head, ends.tail].some((end) => end && (end.width !== null || end.length !== null))\n\tif (sized) {\n\t\tnotes.note(\n\t\t\t'line.arrowSize',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t'arrowhead width and length classes (@w / @len) have no write-API option, so arrowheads render at the default size'\n\t\t)\n\t}\n\treturn {\n\t\tbeginArrowType: ends.head && WRITABLE_ARROWS.has(ends.head.type) ? ends.head.type : undefined,\n\t\tendArrowType: ends.tail && WRITABLE_ARROWS.has(ends.tail.type) ? ends.tail.type : undefined,\n\t}\n}\n\n/** Outer shadow as `ShadowProps`; an inner shadow uses the same option with `type: 'inner'`. */\nfunction shadowOption(shape: AnyShape, notes: NoteScope): IrValue | undefined {\n\tif (shape.reflection || shape.softEdge) {\n\t\tnotes.note(\n\t\t\t'shape.effects',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t'a:reflection and a:softEdge are read but have no write-API emitter, so those effects are lost'\n\t\t)\n\t}\n\n\tconst outer = shape.shadow\n\tconst source = outer ?? shape.innerShadow\n\tif (!source) return undefined\n\n\treturn compact({\n\t\ttype: outer ? 'outer' : 'inner',\n\t\tcolor: source.color === null ? undefined : literalColor(source.color),\n\t\tblur: source.blurPt,\n\t\toffset: source.offsetPt,\n\t\tangle: source.angleDeg,\n\t\ttransparency: alphaToTransparency(source.alpha),\n\t})\n}\n\n/** Glow. The read model reports opacity as a 0–1 alpha, which is the write API's unit too. */\nfunction glowOption(shape: AnyShape): IrValue | undefined {\n\tconst glow = shape.glow\n\tif (!glow) return undefined\n\treturn compact({\n\t\tsize: glow.radiusPt,\n\t\tcolor: glow.color === null ? undefined : literalColor(glow.color),\n\t\topacity: glow.alpha,\n\t})\n}\n\n/** The style block every shape kind shares. */\nfunction styleOptions(shape: AnyShape, notes: NoteScope, assets: AssetResolver): Record<string, IrValue | undefined> {\n\treturn {\n\t\tfill: fillOption(shape, notes, assets),\n\t\tline: lineOption(shape, notes),\n\t\tshadow: shadowOption(shape, notes),\n\t\tglow: glowOption(shape),\n\t}\n}\n\n/* ===== per-kind mappers ===== */\n\n/**\n * An `AutoShape` becomes an `addShape` when it is bare geometry and an `addText` when it\n * carries text. A shape with both takes the `addText` form, because `addShape` has no text\n * argument while `addText` accepts a `shape` option — so only that form expresses both.\n */\nfunction autoShapeCall(shape: AutoShape, notes: NoteScope, assets: AssetResolver): CallIr | null {\n\tconst preset = shape.presetGeometry\n\tconst custom = shape.customGeometry\n\tconst frame = shape.hasTextFrame ? shape.textFrame : null\n\n\t// \"Has text\" means text this converter can author, which is *runs*. `TextFrame.text` also\n\t// counts `a:fld` field text — a slide number, date or footer placeholder — and there is no\n\t// run behind it, so measuring by `text` made every field placeholder emit an `addText`\n\t// carrying a single empty string: an invisible empty box where a number used to be.\n\tconst runText = frame === null ? '' : frame.paragraphs.flatMap((p) => p.runs.map((run) => run.text)).join('')\n\tconst hasText = runText.length > 0\n\n\t// Run text is a subsequence of the frame's text, so anything longer came from a field.\n\tif (frame !== null && frame.text.replaceAll('\\n', '').length > runText.length) {\n\t\tnotes.note(\n\t\t\t'text.field',\n\t\t\t'dropped',\n\t\t\t'unread',\n\t\t\t'this shape holds an automatic field (a:fld — a slide number, date or footer), which has no accessor and no addText expression, so its text is not reproduced'\n\t\t)\n\t}\n\n\t// An OMML equation contributes nothing to `TextFrame.text`, so an equation-only shape\n\t// looks like an empty box and would otherwise emit as bare geometry.\n\tif (frame !== null && hasEquation(shape.element_)) {\n\t\tnotes.note(\n\t\t\t'text.equation',\n\t\t\t'dropped',\n\t\t\t'unread',\n\t\t\t'this shape holds an OMML equation, which no accessor exposes, so the shape is emitted without it — even though TextProps.math (and the ts-pptx/math subpath) could author one'\n\t\t)\n\t}\n\n\tif (shape.placeholder) {\n\t\tnotes.note(\n\t\t\t'shape.placeholder',\n\t\t\t'flattened',\n\t\t\t'unsupported',\n\t\t\t'a placeholder is emitted as a plain shape with its inherited geometry and styling baked in, so it no longer follows its layout'\n\t\t)\n\t}\n\n\tconst common = {\n\t\t...positionOptions(shape, notes),\n\t\t...transformOptions(shape),\n\t\t...styleOptions(shape, notes, assets),\n\t\tobjectName: shape.name || undefined,\n\t}\n\n\tif (custom) {\n\t\tnotes.note(\n\t\t\t'shape.custGeom.guides',\n\t\t\t'dropped',\n\t\t\t'unread',\n\t\t\t'custGeom guides, adjust handles and connection sites (a:gdLst / a:ahLst / a:cxnLst) have no accessor, so only the path outline carries'\n\t\t)\n\t\tconst options = compact({ ...common, points: customGeometryPoints(shape, custom) })\n\t\treturn { method: 'addShape', args: ['custGeom', options ?? {}], ...nameOf(shape) }\n\t}\n\n\tif (hasText && frame !== null) {\n\t\t// `isTextBox` and `shape` are independent, not alternatives: a PowerPoint text box\n\t\t// carries `txBox=\"1\"` *and* an explicit `prstGeom rect`, so reading text-box-ness off\n\t\t// the absence of geometry misclassified every one of them as an auto shape.\n\t\tconst options = compact({\n\t\t\t...common,\n\t\t\t...textFrameOptions(frame, notes),\n\t\t\t...(isTextBox(shape.element_) ? { isTextBox: true } : {}),\n\t\t\t...(preset === null ? {} : { shape: preset, ...adjustOptions(shape) }),\n\t\t})\n\t\treturn { method: 'addText', args: [textRuns(frame, notes), options ?? {}], ...nameOf(shape) }\n\t}\n\n\t// No text and no geometry of its own: an empty placeholder, whose shape comes from the\n\t// layout it inherits. `addShape` needs a preset name and `addText` would author an\n\t// invisible empty box, so the shape is dropped — which matches how it renders in a\n\t// slideshow, where an unfilled placeholder shows nothing. It is still a loss in the\n\t// editor, so it is declared rather than assumed harmless.\n\tif (preset === null) {\n\t\tnotes.note(\n\t\t\t'shape.empty',\n\t\t\t'dropped',\n\t\t\t'unsupported',\n\t\t\t'this shape carries no text and no geometry of its own (an unfilled placeholder drawing its outline from the layout), so there is no addShape preset to name and it is omitted'\n\t\t)\n\t\treturn null\n\t}\n\tconst options = compact({ ...common, ...adjustOptions(shape) })\n\treturn { method: 'addShape', args: [preset, options ?? {}], ...nameOf(shape) }\n}\n\n/**\n * Preset-geometry adjust handles (`a:avLst`) as `shapeAdjust`.\n *\n * The read model reports each guide's raw formula string; a preset's adjust values are\n * `val <n>` where `<n>` is in 1000ths of a percent, and the write API takes the same handle\n * as a `0.0–1.0` fraction. Anything that is not a plain `val` is a computed guide, which\n * has no write-API expression, so it is skipped rather than mis-scaled.\n */\nfunction adjustOptions(shape: AutoShape): Record<string, IrValue | undefined> {\n\tconst values = shape.adjustValues\n\tconst guides: IrValue[] = []\n\tfor (const name of Object.keys(values).sort()) {\n\t\tconst match = /^val\\s+(-?\\d+)$/.exec((values[name] ?? '').trim())\n\t\tif (!match?.[1]) continue\n\t\tguides.push({ name, value: Number(match[1]) / 100000 })\n\t}\n\treturn guides.length ? { shapeAdjust: guides } : {}\n}\n\n/**\n * `custGeom` path commands as the write API's `points` array.\n *\n * Path coordinates are integers in the path's own `0..w`/`0..h` viewport, not EMU, so each\n * is scaled onto the shape's box before being printed as EMU. A path that declares no\n * viewport (`@w`/`@h` of 0) is already in the shape's own space and passes through.\n */\nfunction customGeometryPoints(shape: AutoShape, custom: CustomGeometry): IrValue {\n\tconst frame = shape.absoluteFrame\n\tconst points: IrValue[] = []\n\n\tfor (const path of custom.paths) {\n\t\tconst sx = path.w > 0 && frame ? frame.width / path.w : 1\n\t\tconst sy = path.h > 0 && frame ? frame.height / path.h : 1\n\t\tconst px = (v: number): string => emu(v * sx)\n\t\tconst py = (v: number): string => emu(v * sy)\n\n\t\tfor (const command of path.commands) {\n\t\t\tswitch (command.cmd) {\n\t\t\t\tcase 'moveTo':\n\t\t\t\t\tpoints.push({ x: px(command.x), y: py(command.y), moveTo: true })\n\t\t\t\t\tbreak\n\t\t\t\tcase 'lnTo':\n\t\t\t\t\tpoints.push({ x: px(command.x), y: py(command.y) })\n\t\t\t\t\tbreak\n\t\t\t\tcase 'cubicBezTo':\n\t\t\t\t\tpoints.push({\n\t\t\t\t\t\tx: px(command.x),\n\t\t\t\t\t\ty: py(command.y),\n\t\t\t\t\t\tcurve: { type: 'cubic', x1: px(command.x1), y1: py(command.y1), x2: px(command.x2), y2: py(command.y2) },\n\t\t\t\t\t})\n\t\t\t\t\tbreak\n\t\t\t\tcase 'quadBezTo':\n\t\t\t\t\tpoints.push({\n\t\t\t\t\t\tx: px(command.x),\n\t\t\t\t\t\ty: py(command.y),\n\t\t\t\t\t\tcurve: { type: 'quadratic', x1: px(command.x1), y1: py(command.y1) },\n\t\t\t\t\t})\n\t\t\t\t\tbreak\n\t\t\t\tcase 'arcTo':\n\t\t\t\t\t// An arcTo carries no end point on either side — the renderer derives it from\n\t\t\t\t\t// the pen position, radii and swept angle — so this maps one-to-one.\n\t\t\t\t\tpoints.push({\n\t\t\t\t\t\tcurve: { type: 'arc', wR: px(command.wR), hR: py(command.hR), stAng: command.stAng, swAng: command.swAng },\n\t\t\t\t\t})\n\t\t\t\t\tbreak\n\t\t\t\tcase 'close':\n\t\t\t\t\tpoints.push({ close: true })\n\t\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\treturn points\n}\n\n/**\n * A `Picture` becomes `addImage`, with its bytes carried as an asset.\n *\n * PowerPoint authors embedded audio and video as a picture too — the poster frame is the\n * blip, and the media itself hangs off `p:nvPr` as `a:videoFile`/`a:audioFile`. The read\n * model surfaces only the poster (`mediaKind` separates raster from SVG, not still from\n * moving), so a video would otherwise convert to a static image with nothing to show it had\n * ever moved. The write API has `addMedia`, so this is a read-side gap, and it is declared\n * rather than silently flattened.\n */\nfunction pictureCall(shape: Picture, notes: NoteScope, assets: AssetResolver): CallIr | null {\n\tif (isAudioVideo(shape.element_)) {\n\t\tnotes.note(\n\t\t\t'media.audioVideo',\n\t\t\t'flattened',\n\t\t\t'unread',\n\t\t\t'this is embedded audio or video: no accessor reports the media part or its kind, only the poster frame, so it is emitted as a still image even though addMedia could author it'\n\t\t)\n\t}\n\n\t// The vector part wins when there is one. A PowerPoint SVG picture is an `asvg:svgBlip`\n\t// extension over a raster fallback, and the fallback is the lossy copy — taking it would\n\t// throw away the vector for no reason, since `addImage` accepts SVG bytes directly and\n\t// regenerates a fallback of its own.\n\tconst partName = shape.svgPartName ?? shape.imagePartName\n\tif (!partName) {\n\t\tnotes.note(\n\t\t\t'image.data',\n\t\t\t'dropped',\n\t\t\t'unsupported',\n\t\t\t'this picture references no embedded image part (an external or linked image), so there are no bytes to carry'\n\t\t)\n\t\treturn null\n\t}\n\tconst asset = assets.assetFor(partName)\n\tif (!asset) {\n\t\tnotes.note('image.data', 'dropped', 'unsupported', `image part ${partName} is not present in the package`)\n\t\treturn null\n\t}\n\n\tif (shape.svgPartName && shape.imagePartName) {\n\t\tnotes.note(\n\t\t\t'image.svg',\n\t\t\t'approximated',\n\t\t\t'unsupported',\n\t\t\t\"the vector part of this SVG picture is carried and the source's own raster fallback is not; the write path generates a fresh fallback, so a renderer that cannot draw SVG shows a different image from the one the source deck shipped\"\n\t\t)\n\t}\n\tif (shape.recolor) {\n\t\tnotes.note(\n\t\t\t'image.recolor',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t'a picture recolour (a:duotone / a:clrChange / a:grayscl) is read but has no write-API option'\n\t\t)\n\t}\n\n\tconst crop = shape.crop\n\tconst options = compact({\n\t\t...positionOptions(shape, notes),\n\t\t...transformOptions(shape),\n\t\tobjectName: shape.name || undefined,\n\t\t// `crop`, not `sizing`. Both exist and they are not interchangeable: `crop` is\n\t\t// `a:srcRect` emitted verbatim as percentage edge insets — the exact model the read\n\t\t// model reports — while `sizing: 'crop'` cuts a window in *displayed inches* against\n\t\t// the image's measured natural size. Feeding fractions to `sizing` read them as\n\t\t// inches, which shrank every cropped picture to a fraction of its box.\n\t\tcrop:\n\t\t\tcrop === null ? undefined : { l: crop.left * 100, t: crop.top * 100, r: crop.right * 100, b: crop.bottom * 100 },\n\t})\n\treturn { method: 'addImage', args: [{ ...(options ?? {}), data: asset }], ...nameOf(shape) }\n}\n\n/**\n * `ConnectorProps` keys that {@link lineOption} can produce. A connector styles its stroke\n * with *flat* options rather than the nested `line` object every other shape takes, and it\n * accepts a strict subset: no `transparency`, no gradient stroke, and its own `type` names\n * the routing (`straight`/`elbow`/`curved`), not a fill kind — so spreading a line option\n * object into it wholesale would both drop silently and collide.\n */\nconst CONNECTOR_LINE_KEYS = ['color', 'width', 'dashType', 'beginArrowType', 'endArrowType'] as const\n\n/**\n * A `Connector` becomes `addConnector`.\n *\n * The endpoints are the one real translation here. OOXML gives a connector a bounding box\n * plus flip flags; `addConnector` takes two points. `a:flipH`/`a:flipV` are what say which\n * diagonal of the box the line runs along, so dropping them would silently mirror every\n * connector that runs up or leftward.\n *\n * The *bindings* (`a:stCxn`/`a:endCxn`) reference source shape ids that have no counterpart\n * in the output, so a connector lands unbound and stops following its shapes when they move.\n */\nfunction connectorCall(shape: Connector, notes: NoteScope): CallIr | null {\n\tconst frame = shape.absoluteFrame\n\tif (!frame) return null\n\n\tif (shape.startConnection || shape.endConnection) {\n\t\tnotes.note(\n\t\t\t'connector.binding',\n\t\t\t'dropped',\n\t\t\t'unsupported',\n\t\t\t'connector endpoint bindings reference source shape ids with no counterpart in the output, so the connector lands unbound and no longer follows its shapes'\n\t\t)\n\t}\n\tif (shape.rotation) {\n\t\tnotes.note(\n\t\t\t'connector.rotation',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t'addConnector takes two endpoints and no rotation, so a rotated connector lands along the unrotated diagonal of its box'\n\t\t)\n\t}\n\n\tconst line = lineOption(shape, notes) ?? {}\n\tconst stroke: Record<string, IrValue> = {}\n\tfor (const key of CONNECTOR_LINE_KEYS) {\n\t\tconst value = line[key]\n\t\tif (value !== undefined) stroke[key] = value\n\t}\n\tif (line['type'] === 'gradient' || line['transparency'] !== undefined) {\n\t\tnotes.note(\n\t\t\t'connector.line',\n\t\t\t'flattened',\n\t\t\t'unwritable',\n\t\t\t'a connector styles its stroke with flat colour/width options, which cannot express a gradient stroke or a stroke transparency, so those fall back to a plain line'\n\t\t)\n\t}\n\n\tconst right = frame.left + frame.width\n\tconst bottom = frame.top + frame.height\n\treturn {\n\t\tmethod: 'addConnector',\n\t\targs: [\n\t\t\tcompact({\n\t\t\t\t// Routing is not readable — `presetGeometry` names the connector preset but the\n\t\t\t\t// bend count it implies is not exposed — so every connector emits straight.\n\t\t\t\ttype: 'straight',\n\t\t\t\tx1: emu(shape.flipH ? right : frame.left),\n\t\t\t\ty1: emu(shape.flipV ? bottom : frame.top),\n\t\t\t\tx2: emu(shape.flipH ? frame.left : right),\n\t\t\t\ty2: emu(shape.flipV ? frame.top : bottom),\n\t\t\t\tobjectName: shape.name || undefined,\n\t\t\t\t...stroke,\n\t\t\t}) ?? {},\n\t\t],\n\t\t...nameOf(shape),\n\t}\n}\n\n/** A `GraphicFrame` hosts a table or a chart; both have their own mapper. */\nfunction graphicFrameCall(shape: GraphicFrame, notes: NoteScope, assets: AssetResolver): CallIr | null {\n\tconst table = shape.table\n\tif (table) return tableCall(shape, table, notes, assets)\n\n\tconst chart = shape.chart\n\tif (chart) return chartCall(shape, chart, notes)\n\n\tif (shape.hasChartEx) {\n\t\t// Reached only if the deck-level walk did not already mark the slide `carried`.\n\t\tnotes.note(\n\t\t\t'chartEx.all',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t'an extended chart (waterfall, funnel, box-and-whisker, …) has a full reader but no write-API counterpart'\n\t\t)\n\t\treturn null\n\t}\n\n\tnotes.note(\n\t\t'graphicFrame.unknown',\n\t\t'dropped',\n\t\t'unread',\n\t\t'this graphic frame hosts neither a table nor a chart (SmartArt or an OLE object), which the read model does not decode'\n\t)\n\treturn null\n}\n\n/**\n * A `GroupShape` becomes `addGroup`, with each child mapped and re-tagged into the\n * key-tagged `GroupChildProps` shape the write API expects.\n *\n * Children keep slide-absolute coordinates, which is not a compromise here: `addGroup`\n * holds an identity child coordinate space (`chOff/chExt == off/ext`) at every depth\n * precisely so they can. Nested groups therefore nest rather than flatten. What does not\n * survive is a source group with a *non*-identity child space — that group scales its\n * contents when resized and the emitted one will not — so that case, and only that case,\n * is noted.\n *\n * Charts, tables, media and placeholders are excluded from groups by the write API, so a\n * group holding one loses that child.\n */\nfunction groupCall(shape: GroupShape, notes: NoteScope, assets: AssetResolver): CallIr | null {\n\tconst children: IrValue[] = []\n\tfor (const child of shape.shapes) {\n\t\tconst call = shapeCall(child, notes, assets)\n\t\tif (!call) continue\n\t\tconst tagged = asGroupChild(call)\n\t\tif (!tagged) {\n\t\t\tnotes.note(\n\t\t\t\t'group.child',\n\t\t\t\t'dropped',\n\t\t\t\t'unsupported',\n\t\t\t\t`addGroup accepts no ${call.method.replace(/^add/, '').toLowerCase()} child (charts, tables and media are excluded by design), so this child is omitted from the group`\n\t\t\t)\n\t\t\tcontinue\n\t\t}\n\t\tchildren.push(tagged)\n\t}\n\tif (children.length === 0) {\n\t\tnotes.note(\n\t\t\t'group.empty',\n\t\t\t'dropped',\n\t\t\t'unsupported',\n\t\t\t'no child of this group produced a call, and addGroup rejects an empty child list, so the group itself is omitted too'\n\t\t)\n\t\treturn null\n\t}\n\n\tif (!hasIdentityChildSpace(shape.element_)) {\n\t\tnotes.note(\n\t\t\t'group.childSpace',\n\t\t\t'flattened',\n\t\t\t'unsupported',\n\t\t\t\"this group scales its contents (its a:chOff/a:chExt differ from its a:off/a:ext); addGroup's child space is always identity, so the children are emitted pre-scaled and resizing the group no longer rescales them\"\n\t\t)\n\t}\n\n\t// The group's own rotation and flips are deliberately NOT emitted here. `absoluteFrame`\n\t// composes them into every child, and the children above were built from it, so the\n\t// transform is already baked in at slide-absolute coordinates. Emitting it on the group\n\t// as well would apply it a second time — measured: a group rotated 30° came back at 60°\n\t// with its children walked off their positions, and a flipped group came back unflipped\n\t// because the double flip cancelled. The group's frame is a bounding box and nothing else.\n\tif (shape.rotation !== 0 || shape.flipH || shape.flipV) {\n\t\tnotes.note(\n\t\t\t'group.transform',\n\t\t\t'flattened',\n\t\t\t'unsupported',\n\t\t\t\"the group's own rotation and flips are baked into its children's coordinates rather than kept on the group, because addGroup would otherwise apply them twice; the shapes render identically but rotating or resetting the group no longer moves them together\"\n\t\t)\n\t}\n\n\treturn {\n\t\tmethod: 'addGroup',\n\t\targs: [children, compact({ ...positionOptions(shape, notes), objectName: shape.name || undefined }) ?? {}],\n\t\t...nameOf(shape),\n\t}\n}\n\n/**\n * Re-tag a call as a `GroupChildProps` entry, or `null` when the content type is one\n * `addGroup` excludes. The tagged form is a single-key object, not a `{ type, args }` pair.\n */\nfunction asGroupChild(call: CallIr): IrValue | null {\n\tconst [first, second] = call.args\n\tswitch (call.method) {\n\t\tcase 'addText':\n\t\t\treturn { text: compact({ text: first, options: second }) ?? {} }\n\t\tcase 'addShape':\n\t\t\treturn { shape: compact({ type: first, options: second }) ?? {} }\n\t\tcase 'addImage':\n\t\t\treturn { image: first ?? {} }\n\t\tcase 'addGroup':\n\t\t\treturn { group: compact({ children: first, options: second }) ?? {} }\n\t\tdefault:\n\t\t\t// Charts, tables, connectors and media have no GroupChildProps variant.\n\t\t\treturn null\n\t}\n}\n\n/** Attach the source name to a call, when the shape had one. */\nfunction nameOf(shape: AnyShape): { sourceName?: string } {\n\treturn shape.name ? { sourceName: shape.name } : {}\n}\n","/**\n * A slide's show transition (`p:transition`) → the write API's `TransitionProps`.\n *\n * **The whole difficulty is one type mismatch.** `TransitionInfo.type` is an *open string*,\n * because the read model decodes PowerPoint's modern effects (Morph, Vortex, Ripple, …)\n * alongside the base ECMA-376 ones and tells them apart by namespace rather than by name.\n * The write API's `TransitionType` is a closed union of 21 base names. Passing the read\n * model's string straight through would therefore produce a script that does not compile\n * for exactly the decks a converter is most likely to meet — a modern transition is what\n * PowerPoint's own UI offers first. So {@link WRITABLE_TYPES} is the filter, and a name that\n * does not survive it becomes a fidelity note rather than a compile error.\n *\n * **Why `speed` is always emitted.** `spd` is absent from most PowerPoint-authored\n * transitions (its schema default is `fast`) and the read model reports the default rather\n * than the absence, so there is nothing to distinguish \"absent\" from \"explicitly fast\". That\n * is harmless on its own — both read back as `fast`. What is *not* harmless is omitting it\n * when a duration is present: the write path then derives the bucket from `durationMs`\n * (`transitionSpeedForDuration`), and PowerPoint's own pairing does not always agree with\n * that formula — the sound fixture carries `spd=\"slow\"` with `p14:dur=\"2000\"`, which the\n * derivation happens to reproduce, while a 600ms `fast` transition would come back `med`.\n * Emitting the read value verbatim removes the derivation from the path entirely, which is\n * the same discipline the rest of the IR follows: state what was read, never recompute it.\n */\nimport type { Slide } from '../../read/api/slide.js'\nimport type { TransitionInfo } from '../../read/api/transition.js'\nimport type { TransitionType } from '../../types/animation.js'\nimport type { NoteScope } from '../fidelity.js'\nimport type { TransitionIr, TransitionSoundIr } from '../ir.js'\nimport type { AssetResolver } from './shape.js'\n\n/**\n * The transitions the write API can author, as a lookup.\n *\n * Spelled as a `Record` keyed by `TransitionType` rather than as an array of strings so the\n * compiler polices it in *both* directions: a name the union does not have is rejected here,\n * and a name the union gains without being added here fails to satisfy the record. A plain\n * `Set<string>` would silently drift out of date, and the symptom would be a printed script\n * that does not compile — found by whoever runs it, not by this repository's test suite.\n */\nconst WRITABLE_TYPES: Record<TransitionType, true> = {\n\tblinds: true,\n\tchecker: true,\n\tcircle: true,\n\tcomb: true,\n\tcover: true,\n\tcut: true,\n\tdiamond: true,\n\tdissolve: true,\n\tfade: true,\n\tnewsflash: true,\n\tplus: true,\n\tpull: true,\n\tpush: true,\n\trandom: true,\n\trandomBar: true,\n\tsplit: true,\n\tstrips: true,\n\twedge: true,\n\twheel: true,\n\twipe: true,\n\tzoom: true,\n}\n\n/**\n * `true` when the write API has a name for this transition.\n *\n * The namespace check does no work on PowerPoint's own output and is kept anyway. Every one\n * of the 21 modern effect names in the probed table (`conveyor`, `morph`, `vortex`, …) is\n * distinct from every base name, so today the name lookup alone would reach the same verdict\n * — measured, not assumed. But \"is this a base ECMA-376 transition\" is a question about the\n * *namespace*, and answering it by name would be relying on that disjointness holding for\n * every namespace Microsoft ever adds. The write path emits `p:${type}` unconditionally, so\n * the cost of being wrong is a modern effect silently rewritten as a base one with the same\n * name and no note — a conversion that reports itself as faithful. `script-ir.test.js`\n * authors a `p14:fade` to keep this branch honest, since no fixture can.\n */\nfunction isWritable(info: TransitionInfo): boolean {\n\treturn info.namespace === 'p' && Object.hasOwn(WRITABLE_TYPES, info.type)\n}\n\n/**\n * Map a slide's transition, recording a note for anything that does not survive.\n *\n * Returns `undefined` both when the slide has no transition and when it has one this\n * library cannot author — the difference between those two is what the note carries.\n */\nexport function transitionToIr(slide: Slide, notes: NoteScope, assets: AssetResolver): TransitionIr | undefined {\n\tconst info = slide.transition\n\tif (!info) return undefined\n\n\tif (!isWritable(info)) {\n\t\tnotes.note(\n\t\t\t'slide.transition',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t`this slide's ${info.namespace === 'p' ? '' : `${info.namespace} `}${info.type} transition is not one of the 21 base ECMA-376 transitions the write API can author${\n\t\t\t\tinfo.namespace === 'p' ? '' : \" — it is one of PowerPoint's modern effects, which have no write-API vocabulary\"\n\t\t\t}, so the regenerated slide advances with no effect`\n\t\t)\n\t\treturn undefined\n\t}\n\n\t// Each optional key is spread in only when the source carried it, so an absent attribute\n\t// stays absent rather than becoming an explicit default the source never wrote.\n\tconst sound = soundToIr(slide, info, notes, assets)\n\treturn {\n\t\ttype: info.type,\n\t\tspeed: info.speed,\n\t\t...(info.durationMs === null ? {} : { durationMs: info.durationMs }),\n\t\t// Both are omitted at their OOXML default, so the emitted script says only what the\n\t\t// source said: `advClick` defaults to true and `advTm` to unset.\n\t\t...(info.advanceOnClick ? {} : { advanceOnClick: false }),\n\t\t...(info.advanceAfterMs === null ? {} : { advanceAfterMs: info.advanceAfterMs }),\n\t\t...(Object.keys(info.variant).length > 0 ? { variant: { ...info.variant } } : {}),\n\t\t...(sound ? { sound } : {}),\n\t}\n}\n\n/**\n * The transition's sound (`p:sndAc`), in the two forms OOXML gives it.\n *\n * The stop-previous form is pure structure — no relationship, no media part — so it maps\n * unconditionally. A start sound is an embedded WAV reached through the slide's own\n * relationships, which is the only place in this converter that resolves an `r:embed` by\n * hand: every other media reference arrives already resolved to a partname by the read\n * model's shape accessors, and a transition sound has no shape to hang off.\n */\nfunction soundToIr(\n\tslide: Slide,\n\tinfo: TransitionInfo,\n\tnotes: NoteScope,\n\tassets: AssetResolver\n): TransitionSoundIr | undefined {\n\tconst sound = info.sound\n\tif (!sound) return undefined\n\tif (sound.form === 'stop') return { stopPrevious: true }\n\n\tconst partName = soundPartName(slide, sound.embedRid)\n\tconst asset = partName === null ? null : assets.assetFor(partName)\n\tif (!asset) {\n\t\tnotes.note(\n\t\t\t'slide.transitionSound',\n\t\t\t'dropped',\n\t\t\t'unsupported',\n\t\t\t`this transition's start sound (${sound.embedRid ?? 'no r:embed'}) does not resolve to an audio part in the package, so the regenerated transition is silent`\n\t\t)\n\t\treturn undefined\n\t}\n\n\treturn {\n\t\tdata: asset,\n\t\t...(sound.name === null ? {} : { name: sound.name }),\n\t\t// Omitted at its default, like `advanceOnClick`: `p:stSnd@loop` defaults to false.\n\t\t...(sound.loop ? { loop: true } : {}),\n\t}\n}\n\n/** Resolve `p:snd@r:embed` to the audio part it names, or `null` when it does not resolve. */\nfunction soundPartName(slide: Slide, embedRid: string | null): string | null {\n\tif (!embedRid) return null\n\tconst relationship = slide.relationships.get(embedRid)\n\t// An External audio rel has no partname to read bytes from; `resolveTarget` throws on\n\t// both cases, so they are screened here rather than caught.\n\tif (!relationship || relationship.targetMode === 'External') return null\n\treturn slide.relationships.resolveTarget(embedRid)\n}\n","/**\n * `Presentation` → {@link DeckIr}. The entry point of the read half.\n *\n * Pure in the sense that matters: it reads a loaded package and returns data, touching no\n * filesystem and mutating nothing. Given the same bytes it returns the same IR, so a\n * round-trip check can compare two runs directly.\n *\n * The one judgement made at this level rather than per-shape is {@link SlideSource}. A\n * slide holding a construct the write API cannot express *at all* — an extended chart is\n * the clear case, with a complete reader and no emitter — cannot be honestly transcribed,\n * because the output would silently differ from the source. Such a slide is marked\n * `carried` so the printer copies it instead. That decision has to be made here, before\n * any shape is mapped, since it is a property of the slide as a whole.\n */\nimport type { Presentation } from '../../read/api/presentation.js'\nimport type { Slide } from '../../read/api/slide.js'\nimport type { AnyShape } from '../../read/api/shapes.js'\nimport { isGraphicFrame, isGroupShape } from '../../read/api/shapes.js'\nimport { NoteCollector, scopeNotes, type NoteScope } from '../fidelity.js'\nimport type { AssetIr, AssetRef, BackgroundIr, CallIr, DeckIr, DeckPropsIr, SlideIr, SlideLayoutIr } from '../ir.js'\nimport type { AssetResolver } from './shape.js'\nimport { chromeToIr } from './chrome.js'\nimport { shapeCall } from './shape.js'\nimport { transitionToIr } from './transition.js'\nimport { compact } from './values.js'\n\n/** Default slide size (10\" × 7.5\") for a deck whose `presentation.xml` declares none. */\nconst DEFAULT_SLIDE_SIZE = { widthEmu: 9144000, heightEmu: 6858000 }\n\n/** Extensions by content type, so an emitted asset filename is one a viewer recognises. */\nconst ASSET_EXTENSIONS: Record<string, string> = {\n\t'image/png': 'png',\n\t'image/jpeg': 'jpg',\n\t'image/gif': 'gif',\n\t'image/bmp': 'bmp',\n\t'image/webp': 'webp',\n\t'image/tiff': 'tif',\n\t'image/x-emf': 'emf',\n\t'image/x-wmf': 'wmf',\n\t'image/svg+xml': 'svg',\n\t// PowerPoint authors the `x-` form for an embedded transition sound; both spellings\n\t// appear in the wild and neither has `wav` as its trailing path component.\n\t'audio/x-wav': 'wav',\n\t'audio/wav': 'wav',\n\t'audio/mpeg': 'mp3',\n}\n\n/**\n * Collects media as shapes reference it, assigning each part a stable sequential name.\n *\n * Names are assigned in first-reference order rather than derived from the source part\n * name, so the output is deterministic for a given deck and does not leak whatever the\n * source package happened to call its files. A part referenced twice resolves to one asset.\n *\n * Numbering runs per *kind* (`image1.png`, `image2.png`, `audio1.wav`) rather than over one\n * shared counter. Not cosmetics: the asset name becomes a `const` identifier in the emitted\n * script and a filename in its asset directory, and a transition sound bound to `image7`\n * reads as a bug in the generated source every time anyone opens it.\n */\nclass Assets implements AssetResolver {\n\treadonly #byPartName = new Map<string, AssetRef>()\n\treadonly #assets: AssetIr[] = []\n\treadonly #counts = new Map<string, number>()\n\n\tconstructor(private readonly pres: Presentation) {}\n\n\tassetFor(partName: string): AssetRef | null {\n\t\tconst existing = this.#byPartName.get(partName)\n\t\tif (existing) return existing\n\n\t\tconst part = this.pres.opc.part(partName)\n\t\tif (!part) return null\n\n\t\tconst extension = ASSET_EXTENSIONS[part.contentType] ?? partName.split('.').pop() ?? 'bin'\n\t\tconst kind = part.contentType.startsWith('audio/') ? 'audio' : 'image'\n\t\tconst index = (this.#counts.get(kind) ?? 0) + 1\n\t\tthis.#counts.set(kind, index)\n\t\tconst name = `${kind}${index}.${extension}`\n\t\tconst ref: AssetRef = { $asset: name }\n\t\tthis.#byPartName.set(partName, ref)\n\t\tthis.#assets.push({ name, contentType: part.contentType, bytes: part.bytes })\n\t\treturn ref\n\t}\n\n\tcontentTypeOf(partName: string): string | null {\n\t\treturn this.pres.opc.part(partName)?.contentType ?? null\n\t}\n\n\tget assets(): AssetIr[] {\n\t\treturn this.#assets\n\t}\n}\n\n/** Convert a loaded deck into its IR. */\nexport function readModelToIr(pres: Presentation): DeckIr {\n\tconst collector = new NoteCollector()\n\tconst assets = new Assets(pres)\n\tconst size = pres.slideSize\n\tconst deckScope = scopeNotes(collector, null)\n\n\tif (!size) {\n\t\tdeckScope.note(\n\t\t\t'deck.slideSize',\n\t\t\t'approximated',\n\t\t\t'unsupported',\n\t\t\t`this deck declares no slide size, so the output uses the ${DEFAULT_SLIDE_SIZE.widthEmu / 914400}in × ${DEFAULT_SLIDE_SIZE.heightEmu / 914400}in default`\n\t\t)\n\t}\n\n\tconst layouts = layoutGallery(pres)\n\t// Before the slides, so the chrome's deck-level notes lead the list the way the chrome\n\t// leads the deck. Assets are shared: a layout background image and a slide image that are\n\t// the same part resolve to one asset.\n\tconst chrome = chromeToIr(pres, deckScope, assets)\n\tconst slides = pres.slides.map((slide, index) => slideToIr(slide, index + 1, collector, assets, layouts))\n\n\treturn {\n\t\tslideSize: size ? { widthEmu: size.widthEmu, heightEmu: size.heightEmu } : DEFAULT_SLIDE_SIZE,\n\t\tprops: deckProps(pres, deckScope),\n\t\tchrome,\n\t\tslides,\n\t\tassets: assets.assets,\n\t\tfidelity: collector.notes,\n\t}\n}\n\n/**\n * Deck properties, reduced to the five `docProps` fields the write API sets. The other\n * seven the read model exposes have no setter — they survive anyway in a template-anchored\n * output, since the source deck itself becomes the template, so this is only a loss for a\n * standalone one.\n */\nfunction deckProps(pres: Presentation, notes: NoteScope): DeckPropsIr {\n\tconst core = pres.coreProperties\n\tconst carried = ['keywords', 'description', 'category', 'contentStatus', 'lastModifiedBy'] as const\n\tif (carried.some((key) => core[key] !== undefined)) {\n\t\tnotes.note(\n\t\t\t'deck.docProps',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t'only title, author, company, subject and revision have write-API setters; keywords, description, category, content status and last-modified-by have none'\n\t\t)\n\t}\n\treturn (\n\t\tcompact({\n\t\t\ttitle: core.title,\n\t\t\tauthor: core.creator,\n\t\t\tsubject: core.subject,\n\t\t\trevision: core.revision,\n\t\t}) ?? {}\n\t)\n}\n\n/**\n * The deck's layouts keyed by partname, each resolved to what a printer needs to bind to\n * it: its gallery position and whether its name identifies it on its own.\n *\n * Built once per deck rather than per slide — `layouts()` walks every master's layout list,\n * and the uniqueness question is about the gallery as a whole, so asking it per slide would\n * be both quadratic and unable to see layouts no slide happens to use.\n */\nfunction layoutGallery(pres: Presentation): Map<string, SlideLayoutIr> {\n\tconst handles = pres.layouts()\n\tconst nameCounts = new Map<string, number>()\n\tfor (const handle of handles) nameCounts.set(handle.name, (nameCounts.get(handle.name) ?? 0) + 1)\n\n\treturn new Map(\n\t\thandles.map((handle, index) => [\n\t\t\thandle.partName,\n\t\t\t{ name: handle.name, index, nameIsUnique: (nameCounts.get(handle.name) ?? 0) === 1 },\n\t\t])\n\t)\n}\n\nfunction slideToIr(\n\tslide: Slide,\n\tnumber: number,\n\tcollector: NoteCollector,\n\tassets: Assets,\n\tlayouts: Map<string, SlideLayoutIr>\n): SlideIr {\n\tconst notes = scopeNotes(collector, number)\n\tconst layoutPartName = slide.layout?.partName\n\tconst base = {\n\t\tnumber,\n\t\tlayout: (layoutPartName === undefined ? undefined : layouts.get(layoutPartName)) ?? null,\n\t\thidden: slide.hidden,\n\t\t...(slide.name ? { name: slide.name } : {}),\n\t\t...backgroundOf(slide, notes),\n\t\t...notesOf(slide, notes),\n\t}\n\n\tconst transition = transitionToIr(slide, notes, assets)\n\tconst carried = hasUnwritableContent(slide)\n\tif (carried) {\n\t\tnotes.note(\n\t\t\t'slide.carried',\n\t\t\t'flattened',\n\t\t\t'unwritable',\n\t\t\t'this slide holds an extended chart (waterfall, funnel, box-and-whisker, …), which has a full reader but no write-API emitter; a printer that can copy the source slide does so instead of transcribing it, so it renders correctly but the emitted script does not describe its contents'\n\t\t)\n\t}\n\n\t// Mapped even for a carried slide: a printer with no source package to copy from prints\n\t// these and loses only the unwritable construct, rather than the whole slide. Each shape\n\t// records its own note, so the extended chart's loss is declared either way.\n\tconst calls: CallIr[] = []\n\tfor (const shape of slide.shapes) {\n\t\tconst call = shapeCall(shape, notes, assets)\n\t\tif (call) calls.push(call)\n\t}\n\n\t// Build animations are recorded once per slide rather than per shape, since they live in a\n\t// slide-scoped element with no shape to attribute them to.\n\trecordAnimationLoss(slide, notes)\n\n\treturn {\n\t\t...base,\n\t\t...(transition ? { transition } : {}),\n\t\tsource: carried ? 'carried' : 'authored',\n\t\tcalls,\n\t}\n}\n\n/**\n * `true` when the slide holds something with no write-API expression at all, forcing a\n * carried slide. Descends into groups, since a group can host a graphic frame.\n */\nfunction hasUnwritableContent(slide: Slide): boolean {\n\tconst check = (shapes: AnyShape[]): boolean =>\n\t\tshapes.some((shape) => {\n\t\t\tif (isGroupShape(shape)) return check(shape.shapes)\n\t\t\treturn isGraphicFrame(shape) && shape.hasChartEx\n\t\t})\n\treturn check(slide.shapes)\n}\n\nfunction backgroundOf(slide: Slide, notes: NoteScope): { background?: BackgroundIr } {\n\tconst background = slide.background\n\t// An inherited background comes with the layout, so re-authoring it onto the slide would\n\t// pin a colour that should keep following the layout.\n\tif (!background || background.source !== 'slide') return {}\n\n\tswitch (background.type) {\n\t\tcase 'solid':\n\t\t\treturn background.color\n\t\t\t\t? { background: compact({ color: background.color.effectiveHex.replace(/^#/, '').toUpperCase() }) }\n\t\t\t\t: {}\n\t\tcase 'none':\n\t\t\treturn {}\n\t\tdefault:\n\t\t\tnotes.note(\n\t\t\t\t'slide.background',\n\t\t\t\t'dropped',\n\t\t\t\t'unsupported',\n\t\t\t\t`a ${background.type} slide background is not expressible through the write API's background option, so the slide takes its layout's background`\n\t\t\t)\n\t\t\treturn {}\n\t}\n}\n\nfunction notesOf(slide: Slide, notes: NoteScope): { notesText?: string } {\n\tconst text = slide.notesText\n\tif (!text) return {}\n\tconst frame = slide.notesTextFrame\n\tif (frame && frame.paragraphs.some((paragraph) => paragraph.runs.some((run) => run.bold || run.italic))) {\n\t\tnotes.note(\n\t\t\t'notes.formatting',\n\t\t\t'flattened',\n\t\t\t'unsupported',\n\t\t\t\"speaker notes carry as plain text; per-run formatting and the notes slide's own placeholder geometry do not\"\n\t\t)\n\t}\n\treturn { notesText: text }\n}\n\n/**\n * Build animations, which live in a slide-scoped `p:timing` element rather than in any\n * shape's subtree.\n *\n * The transition next door used to be recorded here for the same reason and is now mapped\n * instead (`from-read/transition.ts`), which leaves this the one genuinely slide-scoped\n * loss: there is no structural reader for `p:timing` at all, only spid manipulation for the\n * deck-to-deck import path, so a build sequence is invisible to this converter.\n */\nfunction recordAnimationLoss(slide: Slide, notes: NoteScope): void {\n\tif (slide.hasAnimations) {\n\t\tnotes.note(\n\t\t\t'slide.animation',\n\t\t\t'dropped',\n\t\t\t'unread',\n\t\t\t'build animations have no structural reader (p:timing is only manipulated by spid for the deck-to-deck import path), so every shape on this slide lands static'\n\t\t)\n\t}\n}\n","/**\n * The deck IR — a serializable description of a deck as a sequence of write-API calls.\n *\n * This is the seam between reading a `.pptx` and printing TypeScript for it. Everything\n * upstream of the IR knows about OOXML and the read model; everything downstream knows\n * only about strings. Neither half can see the other, which is the point: the decision\n * \"this `a:ln` becomes `line: { width: 2 }`\" is made once, here, and is testable without\n * a printer, while \"how a number is spelled in source text\" is a printer concern that\n * cannot silently change what the deck means.\n *\n * Two rules keep that seam honest, and both are load-bearing:\n *\n * 1. **The IR is data, not objects.** No DOM nodes, no read-model instances, no\n * functions — `structuredClone` and `JSON.stringify` both round-trip it. A round-trip\n * test can therefore compare two IRs directly (see {@link FidelityNote}), and an IR\n * can be cached or shipped without dragging a whole `Presentation` along.\n * 2. **`args` are literal write-API option objects.** A {@link CallIr} is exactly what\n * the emitted source will pass, so the printer never invents, reshapes, or defaults a\n * value — it spells out what is already there. If the printer had to interpret, the\n * same construct could mean two things depending on which half you asked.\n *\n * Media is the one thing that cannot be a literal, since bytes are not source text. It\n * is referenced by {@link AssetRef} and carried out-of-band in {@link DeckIr.assets}, so\n * the IR itself stays serializable and the printer decides between a file path and an\n * inline base64 literal.\n */\nimport type { FidelityNote } from './fidelity.js'\n\n/**\n * A reference to bytes held in {@link DeckIr.assets}, standing where a write-API option\n * wants image/media data. Printed as a `path` or an inline `data:` literal depending on\n * the print options — an IR-level decision would bake one choice into the IR and force a\n * re-read to change it.\n *\n * The `$asset` sigil is deliberate: no write-API option object has a `$`-prefixed key,\n * so a value carrying one is unambiguously a reference rather than user data.\n */\nexport interface AssetRef {\n\t$asset: string\n}\n\n/** `true` when `value` is an {@link AssetRef} rather than a plain IR object. */\nexport function isAssetRef(value: unknown): value is AssetRef {\n\treturn typeof value === 'object' && value !== null && typeof (value as AssetRef).$asset === 'string'\n}\n\n/**\n * Any value an IR may hold. Deliberately narrower than `unknown`: it excludes `undefined`\n * so that \"absent\" has exactly one spelling (a missing key), which is what makes two IRs\n * comparable field-by-field in a round-trip diff. `readModelToIr` never writes an\n * `undefined` value.\n */\nexport type IrValue = null | boolean | number | string | AssetRef | IrValue[] | { [key: string]: IrValue }\n\n/**\n * Widen one of the typed IR records below to {@link IrValue}, for the printer and the\n * canonicaliser, which walk the IR generically.\n *\n * A cast, and unavoidably so. An optional key on an interface types as `T | undefined`,\n * while `IrValue` deliberately excludes `undefined` so that \"absent\" has exactly one\n * spelling — which makes the two mutually unassignable even though every value a mapper\n * actually produces satisfies both. The invariant that closes the gap is enforced at the\n * source (`compact` and the conditional spreads in `from-read/`, pinned by the \"no value is\n * `undefined`\" corpus test) rather than by the type system, so it is stated once here\n * instead of re-argued at each call site.\n */\nexport function asIrValue(value: object): IrValue {\n\treturn value as unknown as IrValue\n}\n\n/** Bytes referenced by an {@link AssetRef}, plus what a printer needs to name and type them. */\nexport interface AssetIr {\n\t/** Stable key an {@link AssetRef} resolves against; also the emitted filename. */\n\tname: string\n\t/** MIME type from the source package's content types, for an inline `data:` URI. */\n\tcontentType: string\n\tbytes: Uint8Array\n}\n\n/**\n * One write-API call on a slide, in the order it must be made. `method` names a real\n * method on the authored slide and `args` are its positional arguments — so a printer is\n * a formatter, and `readModelToIr` owns every semantic choice.\n *\n * Ordering is z-order: OOXML paints a slide's shape tree front-to-back in document order,\n * and so does the write path, so preserving call order preserves overlap.\n */\nexport interface CallIr {\n\tmethod: 'addText' | 'addShape' | 'addImage' | 'addTable' | 'addChart' | 'addConnector' | 'addGroup' | 'addNotes'\n\targs: IrValue[]\n\t/**\n\t * The source shape's name (`p:cNvPr/@name`), when it had one. Not an argument —\n\t * carried so a printer can comment the call and a fidelity note can point at it.\n\t */\n\tsourceName?: string\n}\n\n/**\n * How a slide's content gets into the output deck.\n *\n * `authored` — every shape is transcribed into {@link CallIr}s and regenerated through\n * the write API. This is the goal: the emitted source is editable, and a reader can see\n * what the deck contains.\n *\n * `carried` — the slide holds at least one construct the write API cannot express at all\n * (`chartEx` is the clear case: a full reader, no emitter), so transcribing it would\n * silently produce a different deck. A printer that *can* copy the slide from the source\n * package should do so: fidelity is higher than transcription, though the emitted source then\n * says nothing about what is on the slide, which is a real cost and always carries a\n * {@link FidelityNote}.\n *\n * This is a recommendation, not an erasure. {@link SlideIr.calls} is populated either way, so\n * a printer with no source package to copy from prints them and loses only the unwritable\n * construct rather than the whole slide.\n */\nexport type SlideSource = 'authored' | 'carried'\n\n/**\n * A slide's background, already reduced to what the write API's `background` accepts.\n *\n * `data` rather than `image`, because `BackgroundProps` is `DataOrPathProps & ShapeFillProps`\n * and `data` is the key it actually reads — an `image` key would print, typecheck against\n * `IrValue`, and be ignored at run time.\n */\nexport interface BackgroundIr {\n\tcolor?: string\n\ttransparency?: number\n\tdata?: AssetRef\n}\n\n/**\n * A transition's sound (`p:sndAc`), reduced to what `TransitionSoundProps` accepts.\n *\n * `data` rather than `path`, for the same reason a background image uses `data`: the bytes\n * are the thing the IR carries, and a path would bind the script to a file layout the IR\n * knows nothing about. The stop-previous form has no bytes at all — it silences a sound\n * still playing from the previous slide — so it is the one shape here with no {@link AssetRef}.\n */\nexport interface TransitionSoundIr {\n\t/** Bytes of the embedded WAV, for a start sound. Absent for {@link stopPrevious}. */\n\tdata?: AssetRef\n\t/** `p:snd@name`, the display name PowerPoint shows for the sound. */\n\tname?: string\n\t/** `p:stSnd@loop` — repeat until the next sound starts. Omitted when false, its default. */\n\tloop?: boolean\n\t/** The `p:endSnd` form: stop the previous slide's sound rather than start one. */\n\tstopPrevious?: boolean\n}\n\n/**\n * A slide's show transition (`p:transition`), as a literal `TransitionProps`.\n *\n * Only the base ECMA-376 transitions reach this type. The read model reports\n * {@link TransitionInfo.type} as an *open string*, because PowerPoint's modern effects\n * (Morph, Vortex, …) live in the `p14`/`p15`/`p159` namespaces and it decodes those too —\n * but the write path names 21 base ones and nothing else, so `from-read/transition.ts`\n * filters against that vocabulary and notes what it drops. Anything that survives is a name\n * the write API's own `TransitionType` union accepts, which is what keeps a printed script\n * compiling.\n */\nexport interface TransitionIr {\n\t/** The transition-type element's local name, guaranteed to be a writable one. */\n\ttype: string\n\t/** `p:transition@spd`. Always present — see `from-read/transition.ts` for why it is not omitted. */\n\tspeed: 'slow' | 'med' | 'fast'\n\t/** `p14:dur` in milliseconds, when the source carried an exact duration. */\n\tdurationMs?: number\n\t/** `advClick`. Omitted when true, its default. */\n\tadvanceOnClick?: boolean\n\t/** `advTm` in milliseconds, when the slide auto-advances. */\n\tadvanceAfterMs?: number\n\t/** Type-specific attributes on the type element (`{ dir: 'd' }`, `{ spokes: '2' }`, …). */\n\tvariant?: { [key: string]: string }\n\tsound?: TransitionSoundIr\n}\n\n/**\n * The layout a slide should be bound to in the destination deck, identified two ways\n * because neither alone is sufficient.\n *\n * The **name** is the portable identity: it is what lets a script built from one deck be\n * re-pointed at a different template whose layouts happen to be named the same, and it is\n * what a reader recognises. But `p:cSld@name` is not unique — a deck with several masters\n * routinely carries several \"Title and Content\" layouts, and binding by an ambiguous name\n * is an error, not a coin flip. The **index** into the deck's layout gallery always\n * resolves, so it is the fallback, and {@link nameIsUnique} says which to trust.\n */\nexport interface SlideLayoutIr {\n\t/** `p:cSld@name` of the source layout (`''` when the layout is unnamed). */\n\tname: string\n\t/** Zero-based position in the source deck's layout gallery, in master-then-layout order. */\n\tindex: number\n\t/** `false` when another layout in that gallery shares {@link name}. */\n\tnameIsUnique: boolean\n}\n\n/** One slide of the deck. */\nexport interface SlideIr {\n\t/** 1-based index in the source deck; the identity a {@link FidelityNote} points at. */\n\tnumber: number\n\tsource: SlideSource\n\t/** The layout to bind to, or `null` when the source slide resolves none. */\n\tlayout: SlideLayoutIr | null\n\t/** `p:sld/@show=\"0\"` — a slide hidden from presentation but present in the deck. */\n\thidden: boolean\n\t/** `p:cSld/@name`, when the source slide had one. */\n\tname?: string\n\tbackground?: BackgroundIr\n\t/** Speaker notes as plain text. Notes-slide geometry and placeholders do not survive. */\n\tnotesText?: string\n\t/**\n\t * The show transition, when the source has one the write API can name. Slide-scoped\n\t * rather than a {@link CallIr} because the write API models it as a property assignment\n\t * on the slide, not a method — the IR's `method` union names real methods only.\n\t */\n\ttransition?: TransitionIr\n\t/**\n\t * Write-API calls in z-order.\n\t *\n\t * Populated for every slide, **including a `carried` one**. A printer that can copy the\n\t * source slide ignores these; one that cannot — a standalone output has no source package\n\t * to copy from — prints them and is left with only the unwritable construct missing rather\n\t * than the whole slide. Marking a slide `carried` is a recommendation, not an erasure.\n\t */\n\tcalls: CallIr[]\n}\n\n/**\n * A deck's theme, reduced to what `ThemeProps` accepts — the 12 `a:clrScheme` slots and the\n * major/minor Latin, East-Asian and complex-script faces.\n *\n * What is *not* here is the point of the tier split. `a:fmtScheme` — the three fill, three\n * line and three effect style lists a shape's `p:style` references — has no write-API\n * counterpart and no read accessor, so a theme cannot be reproduced, only approximated.\n */\nexport interface ThemeIr {\n\theadFontFace?: string\n\tbodyFontFace?: string\n\theadFontFaceEA?: string\n\tbodyFontFaceEA?: string\n\theadFontFaceCS?: string\n\tbodyFontFaceCS?: string\n\t/** The 12 `a:clrScheme` slots as bare 6-digit hex, omitting any the theme leaves unset. */\n\tcolorScheme?: { [slot: string]: string }\n}\n\n/**\n * One source slide layout approximated as a `defineSlideMaster` call.\n *\n * The naming is the write API's, not OOXML's: `defineSlideMaster` creates a *layout* under\n * the single shared master, which is exactly the granularity a source layout needs. A source\n * deck's masters have no counterpart at all — hence {@link ChromeIr}'s multi-master note.\n */\nexport interface MasterIr {\n\t/**\n\t * Gallery position of the source layout, matching {@link SlideLayoutIr.index}, so a slide\n\t * finds the master it should bind to without re-deriving a name.\n\t */\n\tlayoutIndex: number\n\t/**\n\t * A `SlideMasterProps` literal. `props.title` is made unique across the deck, because it\n\t * doubles as the key `addSlide({ masterTitle })` matches against and source layout names\n\t * are not unique.\n\t */\n\tprops: { [key: string]: IrValue }\n}\n\n/**\n * The deck's shared chrome, approximated for an output that has no template to inherit it\n * from. A template-anchored printer ignores this entirely — the source deck *is* the chrome.\n */\nexport interface ChromeIr {\n\ttheme: ThemeIr\n\t/** One entry per source layout, in gallery order. */\n\tmasters: MasterIr[]\n}\n\n/** Deck-level properties, reduced to the five `docProps` fields the write API sets. */\nexport interface DeckPropsIr {\n\ttitle?: string\n\tauthor?: string\n\tcompany?: string\n\tsubject?: string\n\trevision?: string\n}\n\n/**\n * A whole deck, ready to print.\n *\n * `widthEmu`/`heightEmu` are raw EMU rather than inches because that is what the read\n * model reports and what the write API's `Coord` accepts verbatim; converting here would\n * introduce a rounding decision at the wrong layer.\n */\nexport interface DeckIr {\n\tslideSize: { widthEmu: number; heightEmu: number }\n\tprops: DeckPropsIr\n\t/**\n\t * Theme and layouts, approximated. Only a standalone printer reads this; a\n\t * template-anchored one gets all of it byte-identical from the source deck instead.\n\t */\n\tchrome: ChromeIr\n\tslides: SlideIr[]\n\tassets: AssetIr[]\n\t/**\n\t * Every construct that did not survive into {@link slides} intact. This is a\n\t * *contract*, not a log: a round-trip check excludes exactly these fields from its\n\t * diff, so an unnoted difference is a bug and a note nothing else corroborates is a\n\t * stale claim. See {@link FidelityNote}.\n\t */\n\tfidelity: FidelityNote[]\n}\n","/**\n * {@link IrValue} → TypeScript source text.\n *\n * This module is deliberately the dumbest part of the subsystem. It knows nothing about\n * decks, shapes, or units — only how a value is spelled. Every semantic decision was made\n * upstream in the read half, which is what lets the printed text be checked by comparing\n * IRs rather than by reading source: if this file were allowed to interpret, the same\n * construct could mean two things depending on which half you asked.\n *\n * Two consequences worth stating, because they are easy to erode later:\n *\n * - **Numbers are printed, not reformatted.** The IR already holds geometry either as a\n * `` `${n}emu` `` string (exact) or as a six-decimal inch number (the proven minimum for\n * an EMU-exact round-trip). Rounding here to suppress `0.5000000001`-style noise would\n * turn a cosmetic problem into a real geometry loss, so `printNumber` only refuses\n * values JavaScript cannot spell back.\n * - **Layout is a function of the value alone.** Whether an object prints on one line or\n * several depends only on its rendered width, never on where it came from, so the same\n * deck prints byte-identical text every time.\n */\nimport type { AssetRef, IrValue } from '../ir.js'\nimport { isAssetRef } from '../ir.js'\nimport { InvalidOptionError } from '../../errors.js'\n\n/** Matches `.prettierrc`: `printWidth: 120`. */\nconst MAX_WIDTH = 120\n\n/**\n * Columns a tab is assumed to occupy when measuring against {@link MAX_WIDTH}. Prettier's\n * default `tabWidth`, since the repo sets `useTabs` but not `tabWidth`.\n */\nconst TAB_COLUMNS = 2\n\n/** A bare object key needs no quotes only if it is a plain identifier. */\nconst IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/\n\n/**\n * Resolves an {@link AssetRef} to the source text that stands in for it — a `const`\n * identifier when assets are written as files, an inline `data:` literal otherwise. The\n * printer takes this as a callback rather than deciding itself, because the choice belongs\n * to the caller's output layout, not to how a value is spelled.\n */\nexport type AssetPrinter = (ref: AssetRef) => string\n\n/**\n * A string literal in the repo's style (`singleQuote: true`).\n *\n * Deck text is arbitrary user content, so every case below is reachable in practice: a\n * quote, a backslash, a hard line break inside a run. `JSON.stringify` would handle those\n * correctly — it is avoided here for the quote style, not for correctness.\n */\nexport function printString(value: string): string {\n\tlet out = \"'\"\n\tfor (const char of value) {\n\t\tswitch (char) {\n\t\t\tcase '\\\\':\n\t\t\t\tout += '\\\\\\\\'\n\t\t\t\tbreak\n\t\t\tcase \"'\":\n\t\t\t\tout += \"\\\\'\"\n\t\t\t\tbreak\n\t\t\tcase '\\n':\n\t\t\t\tout += '\\\\n'\n\t\t\t\tbreak\n\t\t\tcase '\\r':\n\t\t\t\tout += '\\\\r'\n\t\t\t\tbreak\n\t\t\tcase '\\t':\n\t\t\t\tout += '\\\\t'\n\t\t\t\tbreak\n\t\t\tdefault: {\n\t\t\t\tconst code = char.codePointAt(0) ?? 0\n\t\t\t\t// C0/C1 controls have no visible spelling, so a raw one is invisible corruption.\n\t\t\t\t// U+2028/U+2029 have been legal inside a string literal since ES2019 and do not\n\t\t\t\t// strictly need escaping for a modern engine — they are escaped anyway because\n\t\t\t\t// they remain line terminators everywhere *else* in the grammar, and a file that\n\t\t\t\t// depends on that distinction is a poor thing to hand to an unknown toolchain.\n\t\t\t\t// Everything else rides through, so the script stays readable in the deck's language.\n\t\t\t\tconst escape = code < 0x20 || (code >= 0x7f && code <= 0x9f) || code === 0x2028 || code === 0x2029\n\t\t\t\tout += escape ? '\\\\u' + code.toString(16).padStart(4, '0') : char\n\t\t\t}\n\t\t}\n\t}\n\treturn `${out}'`\n}\n\n/**\n * A number literal. `String` gives the shortest text that reads back as the same double,\n * which is exactly the guarantee needed: the printed script must produce the same value the\n * IR held. Non-finite values cannot satisfy that (`NaN` and `Infinity` are identifiers, not\n * literals) and never reach here from a well-formed IR, so they throw rather than emit\n * source that would not run.\n */\nexport function printNumber(value: number): string {\n\tif (!Number.isFinite(value))\n\t\tthrow new InvalidOptionError('script/non-finite-literal', `Cannot print a non-finite number: ${value}`)\n\treturn String(value)\n}\n\n/** An object key, bare when it is a plain identifier and quoted when it is not. */\nfunction printKey(key: string): string {\n\treturn IDENTIFIER.test(key) ? key : printString(key)\n}\n\n/** The value on a single line, however long that line comes out. */\nfunction inline(value: IrValue, asset: AssetPrinter): string {\n\tif (value === null) return 'null'\n\tif (typeof value === 'boolean') return String(value)\n\tif (typeof value === 'number') return printNumber(value)\n\tif (typeof value === 'string') return printString(value)\n\tif (isAssetRef(value)) return asset(value)\n\tif (Array.isArray(value)) return `[${value.map((item) => inline(item, asset)).join(', ')}]`\n\n\tconst keys = Object.keys(value)\n\tif (keys.length === 0) return '{}'\n\treturn `{ ${keys.map((key) => `${printKey(key)}: ${inline(value[key] as IrValue, asset)}`).join(', ')} }`\n}\n\n/**\n * The value as source text, broken across lines only where it would otherwise overflow\n * {@link MAX_WIDTH}.\n *\n * `indentLevel` is the depth the value *starts* at, so a caller that has already written a\n * prefix (`slide1.addText(`) passes the level its closing brace should line up with.\n */\nexport function printValue(value: IrValue, indentLevel: number, asset: AssetPrinter): string {\n\tconst flat = inline(value, asset)\n\tif (indentLevel * TAB_COLUMNS + flat.length <= MAX_WIDTH) return flat\n\n\t// Only containers can be broken up; a single long string or number stays long.\n\tconst pad = '\\t'.repeat(indentLevel)\n\tconst inner = '\\t'.repeat(indentLevel + 1)\n\n\tif (Array.isArray(value)) {\n\t\tif (value.length === 0) return '[]'\n\t\tconst items = value.map((item) => `${inner}${printValue(item, indentLevel + 1, asset)},`)\n\t\treturn `[\\n${items.join('\\n')}\\n${pad}]`\n\t}\n\n\tif (typeof value === 'object' && value !== null && !isAssetRef(value)) {\n\t\tconst keys = Object.keys(value)\n\t\tif (keys.length === 0) return '{}'\n\t\tconst entries = keys.map(\n\t\t\t(key) => `${inner}${printKey(key)}: ${printValue(value[key] as IrValue, indentLevel + 1, asset)},`\n\t\t)\n\t\treturn `{\\n${entries.join('\\n')}\\n${pad}}`\n\t}\n\n\treturn flat\n}\n\n/**\n * A call's argument list, either inline after `prefix` or one argument per line.\n *\n * The decision is made on the *whole* call rather than per argument, so a call either reads\n * as one line or as a list — never as a short first argument followed by a hanging brace,\n * which is what a per-argument rule produces.\n */\nexport function printArguments(prefix: string, args: IrValue[], indentLevel: number, asset: AssetPrinter): string {\n\tconst pad = '\\t'.repeat(indentLevel)\n\tconst flat = `${pad}${prefix}(${args.map((arg) => inline(arg, asset)).join(', ')})`\n\tif (indentLevel * TAB_COLUMNS + flat.length - pad.length <= MAX_WIDTH) return flat\n\n\t// No trailing comma after the final argument: `trailingComma: 'es5'` adds them inside\n\t// objects and arrays but not to an argument list, so one here would be reformatted away.\n\tconst inner = '\\t'.repeat(indentLevel + 1)\n\tconst printed = args.map((arg) => `${inner}${printValue(arg, indentLevel + 1, asset)}`)\n\treturn `${pad}${prefix}(\\n${printed.join(',\\n')}\\n${pad})`\n}\n","/**\n * The parts of printing a script that do not depend on which tier is being printed.\n *\n * Two printers target the same IR — one anchored to the source deck as a template, one\n * standalone — and they differ only in how a deck and its chrome are set up. Everything after\n * that is identical: a slide's statements, how image bytes reach the script, and how the\n * fidelity notes are rendered into the banner. Keeping that here is not tidiness. A slide body\n * printed two slightly different ways would mean the round-trip oracle certifies one tier and\n * only resembles a check on the other, and the drift would be invisible in review.\n */\nimport type { AssetRef, DeckIr, IrValue, SlideIr } from '../ir.js'\nimport { asIrValue } from '../ir.js'\nimport type { FidelityNote } from '../fidelity.js'\nimport { type NoteCollector, scopeNotes } from '../fidelity.js'\nimport { printArguments, printString, printValue, type AssetPrinter } from './literal.js'\nimport { InvalidOptionError } from '../../errors.js'\n\n/** How image bytes reach the emitted script. */\nexport type AssetMode =\n\t/** Written beside the script and read at run time. Keeps the script readable. */\n\t| 'file'\n\t/** Inlined as `data:` literals. One self-contained file, at roughly 4/3 the byte size. */\n\t| 'inline'\n\nexport interface PrintedScript {\n\t/** The TypeScript module source. */\n\tcode: string\n\t/**\n\t * Image bytes the script expects to find in its asset directory, keyed by filename.\n\t * Empty when the print options asked for `'inline'`, since the bytes are then in\n\t * {@link code}.\n\t */\n\tassets: Map<string, Uint8Array>\n\t/**\n\t * The losses that apply to **this** output: the IR's own notes, minus any this tier\n\t * rescues, plus the ones this tier causes. Reproduced as a comment block at the top of\n\t * {@link code}, so the artifact carries its own caveats.\n\t */\n\tnotes: FidelityNote[]\n}\n\n/** Width the header comment's prose wraps at, leaving room for the ` * ` prefix. */\nconst COMMENT_WIDTH = 110\n\n/**\n * A stable JavaScript identifier per asset.\n *\n * Derived from the asset's own name rather than its index, so a reader can match a `const`\n * in the script against a file in the asset directory. The dedupe suffix is defensive: the\n * read half currently names assets `image1.png`, `image2.jpg`, … which cannot collide after\n * the extension is stripped, but nothing in the IR contract promises that.\n */\nexport function assetIdentifiers(ir: DeckIr): Map<string, string> {\n\tconst out = new Map<string, string>()\n\tconst used = new Set<string>()\n\tfor (const asset of ir.assets) {\n\t\tconst base = asset.name.replace(/\\.[^.]*$/, '').replace(/[^A-Za-z0-9_$]/g, '_')\n\t\tlet identifier = /^[A-Za-z_$]/.test(base) ? base : `_${base}`\n\t\tlet suffix = 2\n\t\twhile (used.has(identifier)) identifier = `${base}_${suffix++}`\n\t\tused.add(identifier)\n\t\tout.set(asset.name, identifier)\n\t}\n\treturn out\n}\n\n/** Resolve an {@link AssetRef} to the `const` identifier standing for its bytes. */\nexport function assetPrinter(identifiers: Map<string, string>): AssetPrinter {\n\treturn (ref: AssetRef): string => {\n\t\tconst identifier = identifiers.get(ref.$asset)\n\t\tif (!identifier)\n\t\t\tthrow new InvalidOptionError(\n\t\t\t\t'script/unresolved-asset-reference',\n\t\t\t\t`Asset reference ${ref.$asset} has no entry in DeckIr.assets`\n\t\t\t)\n\t\treturn identifier\n\t}\n}\n\n/**\n * One `const` per asset, each holding a complete `data:` URI.\n *\n * Both modes bind the same *kind* of value — a data URI string — so the call sites are\n * identical and `addImage`'s `data` option is used either way. Only where the bytes come\n * from changes. Rewriting the option key to `path` in file mode would have the printer\n * reshaping an argument, which is precisely the thing that keeps the IR checkable.\n */\nexport function printAssetBindings(\n\tir: DeckIr,\n\tidentifiers: Map<string, string>,\n\tassetDir: string,\n\tmode: AssetMode,\n\tinlineComment = '// Media bytes, inlined so this script needs no files but its template.'\n): string[] {\n\tif (ir.assets.length === 0) return []\n\n\tconst lines =\n\t\tmode === 'file' ? ['// Media bytes, loaded from the asset directory beside this script.'] : [inlineComment]\n\n\tfor (const asset of ir.assets) {\n\t\tconst identifier = identifiers.get(asset.name)\n\t\tif (!identifier) continue\n\t\tif (mode === 'file') {\n\t\t\tconst path = printString(`${assetDir}/${asset.name}`)\n\t\t\tlines.push(\n\t\t\t\t`const ${identifier} = \\`data:${asset.contentType};base64,\\${(await readFile(here(${path}))).toString('base64')}\\``\n\t\t\t)\n\t\t} else {\n\t\t\tlines.push(`const ${identifier} = ${printString(`data:${asset.contentType};base64,${toBase64(asset.bytes)}`)}`)\n\t\t}\n\t}\n\treturn lines\n}\n\n/** Base64 without `Buffer`, matching the rest of the library's isomorphic media handling. */\nfunction toBase64(bytes: Uint8Array): string {\n\tlet binary = ''\n\t// Chunked because String.fromCharCode is applied to the whole slice at once, and a\n\t// megabyte-sized spread overflows the argument limit.\n\tconst CHUNK = 0x8000\n\tfor (let i = 0; i < bytes.length; i += CHUNK) {\n\t\tbinary += String.fromCharCode(...bytes.subarray(i, i + CHUNK))\n\t}\n\treturn btoa(binary)\n}\n\n/**\n * One slide: a comment, the statement that creates it, then its slide-level properties and\n * its calls in z-order.\n *\n * `comment` and `construction` are the tier's business — one binds a layout by name at append\n * time, the other names a master up front — and everything after them is not.\n */\nexport function printSlide(\n\tslide: SlideIr,\n\tparts: { comment: string; construction: string },\n\tcollector: NoteCollector,\n\tprintAsset: AssetPrinter\n): string[] {\n\tconst notes = scopeNotes(collector, slide.number)\n\tconst identifier = `slide${slide.number}`\n\tconst lines = ['', `// ${parts.comment}`, `const ${identifier} = ${parts.construction}`]\n\n\tif (slide.name !== undefined) {\n\t\tnotes.note(\n\t\t\t'slide.name',\n\t\t\t'dropped',\n\t\t\t'unwritable',\n\t\t\t`the slide's own name (p:cSld@name, here ${JSON.stringify(slide.name)}) has no public write-API setter, so the generated slide is unnamed`\n\t\t)\n\t}\n\n\tif (slide.hidden) lines.push(`${identifier}.hidden = true`)\n\tif (slide.background) {\n\t\tlines.push(`${identifier}.background = ${printValue(slide.background as IrValue, 0, printAsset)}`)\n\t}\n\tif (slide.transition) {\n\t\tlines.push(`${identifier}.transition = ${printValue(asIrValue(slide.transition), 0, printAsset)}`)\n\t}\n\tif (slide.notesText !== undefined) {\n\t\tlines.push(printArguments(`${identifier}.addNotes`, [slide.notesText], 0, printAsset))\n\t}\n\n\tfor (const call of slide.calls) {\n\t\t// The source shape name makes a fidelity note navigable: a note carries the same\n\t\t// name, and without it a reader has no way to find the call it refers to.\n\t\tif (call.sourceName) lines.push(`// ${call.sourceName.replace(/\\s+/g, ' ')}`)\n\t\tlines.push(printArguments(`${identifier}.${call.method}`, call.args, 0, printAsset))\n\t}\n\n\treturn lines\n}\n\n/** The banner comment: `prose` as written, then every loss that applies to this output. */\nexport function header(prose: string[], notes: FidelityNote[]): string {\n\tconst lines = [...prose, '']\n\n\tif (notes.length === 0) {\n\t\tlines.push('FIDELITY: nothing was lost that this converter can detect.')\n\t} else {\n\t\tlines.push(\n\t\t\t`FIDELITY: ${notes.length} declared loss(es). Everything not listed here is expected to`,\n\t\t\t'survive unchanged; a difference that is not in this list is a defect, not a caveat.',\n\t\t\t''\n\t\t)\n\t\tfor (const [scope, group] of groupNotes(notes)) {\n\t\t\tlines.push(`${scope}:`)\n\t\t\tfor (const note of group) {\n\t\t\t\tconst where = note.shapeName ? ` (${note.shapeName})` : ''\n\t\t\t\tlines.push(\n\t\t\t\t\t...wrap(\n\t\t\t\t\t\t`- ${note.construct}${where} [${note.disposition}, ${note.cause}] — ${note.detail}`,\n\t\t\t\t\t\tCOMMENT_WIDTH,\n\t\t\t\t\t\t' '\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn ['/*', ...lines.map((line) => (line ? ` * ${line}` : ' *')), ' */'].join('\\n')\n}\n\n/** Notes bucketed by slide, in deck order, so a reader meets them the way they meet the deck. */\nfunction groupNotes(notes: FidelityNote[]): Array<[string, FidelityNote[]]> {\n\tconst deckLevel = notes.filter((note) => note.slideNumber === null)\n\tconst bySlide = new Map<number, FidelityNote[]>()\n\tfor (const note of notes) {\n\t\tif (note.slideNumber === null) continue\n\t\tconst existing = bySlide.get(note.slideNumber)\n\t\tif (existing) existing.push(note)\n\t\telse bySlide.set(note.slideNumber, [note])\n\t}\n\n\tconst out: Array<[string, FidelityNote[]]> = []\n\tif (deckLevel.length > 0) out.push(['Deck', deckLevel])\n\tfor (const number of [...bySlide.keys()].sort((a, b) => a - b)) {\n\t\tout.push([`Slide ${number}`, bySlide.get(number) ?? []])\n\t}\n\treturn out\n}\n\n/** Wrap prose to `width`, indenting every line after the first by `continuation`. */\nfunction wrap(text: string, width: number, continuation: string): string[] {\n\tconst words = text.split(/\\s+/).filter(Boolean)\n\tconst lines: string[] = []\n\tlet current = ''\n\tfor (const word of words) {\n\t\tconst candidate = current ? `${current} ${word}` : `${continuation}${word}`\n\t\tif (current && candidate.length > width) {\n\t\t\tlines.push(current)\n\t\t\tcurrent = `${continuation}${word}`\n\t\t} else {\n\t\t\tcurrent = current ? candidate : word\n\t\t}\n\t}\n\tif (current) lines.push(current)\n\treturn lines\n}\n","/**\n * {@link DeckIr} → a runnable TypeScript module, template-anchored. **Tier B.**\n *\n * **The tier.** The emitted script reuses the *source deck itself* as its template:\n * `Presentation.fromTemplate` strips a package's slides while leaving its masters, layouts,\n * theme, and document properties byte-identical, so the chrome is never regenerated — it is\n * the original. Only the slides are rebuilt, through the public write API, and grafted back\n * with `appendSlides`. That is why this tier's fidelity note list is short: everything the\n * converter cannot see or cannot write is confined to slide content, and the whole of the\n * deck's design survives because nothing ever tried to reproduce it.\n *\n * It also means the plan's \"strip the source slides\" step needs no helper. `fromTemplate`\n * already does exactly that, and does it without pruning shared parts, so the template\n * asset and the source deck are the same file.\n *\n * **Order is not rearranged.** Slides are emitted in source order and every operation\n * appends, so `p:sldIdLst` comes out in the original order without any position arithmetic.\n * Contiguous slides sharing a layout share one generator, because `appendSlides` binds\n * every slide in one call to a single layout — the batching is forced by that signature,\n * not chosen for tidiness.\n *\n * **This module may add fidelity notes.** A loss can belong to the *tier* rather than to\n * the conversion — a slide's `p:cSld@name` is read fine and would survive a byte copy, but\n * has no public write-API setter, so it dies here and nowhere else. {@link PrintedScript}\n * therefore returns the notes that actually apply to *this* output, which is also the set a\n * round-trip check should exclude from its diff.\n *\n * The standalone counterpart is `printStandaloneScript` (Tier A), which prints the same IR\n * with no template at all and pays for it in the note list.\n */\nimport type { DeckIr, SlideIr } from '../ir.js'\nimport { NoteCollector, scopeNotes } from '../fidelity.js'\nimport { inches } from '../from-read/values.js'\nimport { printString, type AssetPrinter } from './literal.js'\nimport {\n\tassetIdentifiers,\n\tassetPrinter,\n\theader,\n\tprintAssetBindings,\n\tprintSlide,\n\ttype AssetMode,\n\ttype PrintedScript,\n} from './common.js'\n\nexport type { AssetMode, PrintedScript } from './common.js'\n\nexport interface PrintScriptOptions {\n\t/**\n\t * Path the emitted script loads its template from, resolved against the script's own\n\t * location. This is the **source deck unchanged** — `fromTemplate` strips its slides.\n\t * @default './template.pptx'\n\t */\n\ttemplatePath?: string\n\t/** Path the emitted script writes to, resolved against the script's own location. @default './output.pptx' */\n\toutputPath?: string\n\t/** Directory the emitted script reads image assets from, when {@link assets} is `'file'`. @default './assets' */\n\tassetDir?: string\n\t/** @default 'file' */\n\tassets?: AssetMode\n\t/**\n\t * Import specifier the emitted script uses, with `/read` appended for the read half.\n\t * Defaults to this package's own published name; override it to point a generated\n\t * script at a local build or a fork.\n\t * @default '@shbernal/ts-pptx'\n\t */\n\tpackageName?: string\n}\n\n/**\n * Constructs the IR declares lost that a template-anchored output keeps anyway.\n *\n * Document properties are the obvious case: the read half notes that only five of the twelve\n * have write-API setters, which is true and matters for a standalone output — but this tier\n * never authors them at all. They ride in the template, untouched, all twelve of them.\n *\n * The whole of the chrome is the same story on a larger scale. The theme's format scheme, the\n * master's text styles and colour map, the layouts' decoration and placeholder definitions —\n * every one of them is a genuine loss for a script that has to rebuild the deck's design, and\n * none of them is touched here, because the design *is* the template. A caveat that does not\n * apply to the output in front of you is worse than no caveat: it teaches the reader to skim\n * the ones that do.\n */\nconst TEMPLATE_CARRIED_CONSTRUCTS = new Set([\n\t'deck.docProps',\n\t'master.background',\n\t'master.colorMap',\n\t'master.decoration',\n\t'master.multiple',\n\t// Both are about a layout *title* the standalone tier has to invent — deduplicated because\n\t// it doubles as a lookup key, whitespace-collapsed because the write path emits it as a raw\n\t// XML attribute value. Here the layout keeps its own `p:cSld@name`, untouched.\n\t'master.name',\n\t'master.nameCollision',\n\t'master.placeholders',\n\t'master.txStyles',\n\t'theme.fmtScheme',\n])\n\n/**\n * Default import specifier for the emitted script — this package's *published* name, which\n * is not its directory name. Getting it wrong produces a script that prints and typechecks\n * and then fails at `import`, so it is pinned by a test rather than left to a literal here.\n */\nconst PACKAGE_NAME = '@shbernal/ts-pptx'\n\n/** Turn a deck IR into a runnable, template-anchored TypeScript module. */\nexport function printScript(ir: DeckIr, options: PrintScriptOptions = {}): PrintedScript {\n\tconst templatePath = options.templatePath ?? './template.pptx'\n\tconst outputPath = options.outputPath ?? './output.pptx'\n\tconst assetDir = (options.assetDir ?? './assets').replace(/\\/$/, '')\n\tconst assetMode = options.assets ?? 'file'\n\tconst packageName = options.packageName ?? PACKAGE_NAME\n\n\tconst collector = new NoteCollector()\n\tconst assetNames = assetIdentifiers(ir)\n\tconst printAsset = assetPrinter(assetNames)\n\n\tconst body = printSlides(ir, collector, printAsset)\n\tconst needsSource = ir.slides.some((slide) => slide.source === 'carried')\n\tconst needsFallbackLayout = ir.slides.some((slide) => slide.source === 'authored' && slide.layout === null)\n\n\t// Built last: the tier's own notes are only known once the slides have been walked.\n\tconst notes = [...ir.fidelity.filter((note) => !TEMPLATE_CARRIED_CONSTRUCTS.has(note.construct)), ...collector.notes]\n\n\tconst lines: string[] = [\n\t\theader(\n\t\t\t[\n\t\t\t\t'Generated from a .pptx by ts-pptx/script.',\n\t\t\t\t'',\n\t\t\t\t'Template-anchored: the source deck is reused as the template, so its slide masters,',\n\t\t\t\t'layouts, theme and document properties are the originals, byte for byte. Only the',\n\t\t\t\t'slide content below was rebuilt through the public write API.',\n\t\t\t\t'',\n\t\t\t\t`Expects ${templatePath} (the source deck, unmodified) beside this file${\n\t\t\t\t\tassetMode === 'file' && ir.assets.length > 0 ? `, plus ${ir.assets.length} media file(s) in ${assetDir}` : ''\n\t\t\t\t}.`,\n\t\t\t\t`Writes ${outputPath}. Needs an ESM context — it uses top-level await.`,\n\t\t\t],\n\t\t\tnotes\n\t\t),\n\t\t'',\n\t\t\"import { readFile, writeFile } from 'node:fs/promises'\",\n\t\t\"import { fileURLToPath } from 'node:url'\",\n\t\t`import TsPptx from ${printString(packageName)}`,\n\t\t`import { Presentation } from ${printString(`${packageName}/read`)}`,\n\t\t'',\n\t\t'/** Resolve a path against this script rather than against the working directory. */',\n\t\t'const here = (name: string): string => fileURLToPath(new URL(name, import.meta.url))',\n\t\t'',\n\t\t'// The source deck is the template: fromTemplate strips its slides and leaves its masters,',\n\t\t'// layouts, theme and document properties exactly as they were.',\n\t\t`const deck = await Presentation.fromTemplate(here(${printString(templatePath)}))`,\n\t]\n\n\tif (needsSource) {\n\t\tlines.push(\n\t\t\t'',\n\t\t\t'// A second, unstripped handle on the same file, for the slides copied verbatim.',\n\t\t\t`const source = await Presentation.load(here(${printString(templatePath)}))`\n\t\t)\n\t}\n\n\tif (needsFallbackLayout) {\n\t\tlines.push(\n\t\t\t'',\n\t\t\t'// Some source slides resolved no layout of their own; they bind to the first one.',\n\t\t\t'const fallbackLayout = deck.layouts()[0]',\n\t\t\t\"if (!fallbackLayout) throw new Error('the template declares no slide layouts to bind to')\"\n\t\t)\n\t}\n\n\tconst assetLines = printAssetBindings(ir, assetNames, assetDir, assetMode)\n\tif (assetLines.length > 0) lines.push('', ...assetLines)\n\n\tlines.push(\n\t\t'',\n\t\t'/**',\n\t\t' * A generator sized to the template. appendSlides compares slide sizes exactly and',\n\t\t' * throws when they differ, so the inches here must round-trip to the source EMU.',\n\t\t' */',\n\t\t'function generator(): TsPptx {',\n\t\t'\\tconst pptx = new TsPptx()',\n\t\t`\\tpptx.defineLayout({ name: 'source', width: ${inches(ir.slideSize.widthEmu)}, height: ${inches(ir.slideSize.heightEmu)} })`,\n\t\t\"\\tpptx.layout = 'source'\",\n\t\t'\\treturn pptx',\n\t\t'}',\n\t\t...body,\n\t\t'',\n\t\t`await writeFile(here(${printString(outputPath)}), await deck.save())`,\n\t\t''\n\t)\n\n\treturn {\n\t\tcode: lines.join('\\n'),\n\t\tassets: new Map(\n\t\t\tassetMode === 'file' ? ir.assets.map((asset): [string, Uint8Array] => [asset.name, asset.bytes]) : []\n\t\t),\n\t\tnotes,\n\t}\n}\n\n/**\n * The slide statements, batched into generators.\n *\n * A batch ends when the layout changes or a carried slide interrupts, because\n * `appendSlides` binds one layout per call and a carried slide is not authored at all.\n */\nfunction printSlides(ir: DeckIr, collector: NoteCollector, printAsset: AssetPrinter): string[] {\n\tconst lines: string[] = []\n\tlet batch: SlideIr[] = []\n\tlet generatorIndex = 0\n\t// Two non-contiguous batches can share one layout, so its `const` must be emitted once.\n\tconst declaredLayouts = new Set<number>()\n\n\tconst flush = (): void => {\n\t\tif (batch.length === 0) return\n\t\tconst first = batch[0]\n\t\tif (!first) return\n\t\tconst name = `gen${++generatorIndex}`\n\t\tlines.push('', `const ${name} = generator()`)\n\t\tfor (const slide of batch) lines.push(...printAuthoredSlide(slide, name, collector, printAsset))\n\t\tlines.push('', ...printAppend(name, first, collector, declaredLayouts))\n\t\tbatch = []\n\t}\n\n\tfor (const slide of ir.slides) {\n\t\tif (slide.source === 'carried') {\n\t\t\tflush()\n\t\t\tlines.push(\n\t\t\t\t'',\n\t\t\t\t`// Slide ${slide.number} — copied from the source deck rather than rebuilt; see the fidelity notes.`,\n\t\t\t\t`deck.importSlide(source, ${slide.number - 1})`\n\t\t\t)\n\t\t\tcontinue\n\t\t}\n\t\t// A batch is one appendSlides call, which binds every slide in it to one layout.\n\t\tconst previous = batch[0]\n\t\tif (previous && previous.layout?.index !== slide.layout?.index) flush()\n\t\tbatch.push(slide)\n\t}\n\tflush()\n\n\treturn lines\n}\n\n/**\n * The `appendSlides` call closing a batch, binding by layout name where that is\n * unambiguous and by gallery position where it is not.\n *\n * Binding by name is preferred because it survives being re-pointed at a different\n * template and because it is legible. But `appendSlides` *throws* on an ambiguous name\n * rather than picking one, and a multi-master deck routinely repeats layout names, so the\n * positional form is the only thing that resolves there.\n */\nfunction printAppend(generatorName: string, first: SlideIr, collector: NoteCollector, declared: Set<number>): string[] {\n\tconst layout = first.layout\n\tif (!layout) return [`await deck.appendSlides(${generatorName}, { layout: fallbackLayout })`]\n\tif (layout.nameIsUnique) {\n\t\treturn [`await deck.appendSlides(${generatorName}, { layout: ${printString(layout.name)} })`]\n\t}\n\n\tscopeNotes(collector, first.number).note(\n\t\t'slide.layout',\n\t\t'approximated',\n\t\t'unsupported',\n\t\t`more than one layout in the source deck is named ${JSON.stringify(layout.name)}, so this slide binds to gallery position ${layout.index} instead; re-pointing the script at a different template will not track the name`\n\t)\n\tconst identifier = `layout${layout.index}`\n\tconst append = `await deck.appendSlides(${generatorName}, { layout: ${identifier} })`\n\tif (declared.has(layout.index)) return [append]\n\tdeclared.add(layout.index)\n\treturn [\n\t\t`const ${identifier} = deck.layouts()[${layout.index}] // ${JSON.stringify(layout.name)}`,\n\t\t`if (!${identifier}) throw new Error('the template has no layout at position ${layout.index}')`,\n\t\tappend,\n\t]\n}\n\n/** One authored slide, plus the layout-binding note this tier is responsible for. */\nfunction printAuthoredSlide(\n\tslide: SlideIr,\n\tgeneratorName: string,\n\tcollector: NoteCollector,\n\tprintAsset: AssetPrinter\n): string[] {\n\tif (slide.layout === null) {\n\t\tscopeNotes(collector, slide.number).note(\n\t\t\t'slide.layout',\n\t\t\t'approximated',\n\t\t\t'unsupported',\n\t\t\t\"this slide resolves no layout of its own, so it binds to the template's first layout; that governs theme and clrMap resolution, which may differ from the source\"\n\t\t)\n\t}\n\n\t// A tier loss, and a narrow one: a transition's *stop-previous* form needs no relationship\n\t// and rides across fine, while an embedded start sound needs an audio part wired to the\n\t// appended slide. `extractSlides` never runs the registration pass that assigns it a\n\t// relationship id (`registerTransitionSounds` belongs to the package-assembly path), so the\n\t// emitter finds no `_sndRId` and writes no `p:sndAc` at all. That is a silent drop rather\n\t// than a dangling reference — which is the safe failure of the two, and still a loss the\n\t// reader has to be told about. The standalone tier writes a real package and keeps it.\n\tif (slide.transition?.sound?.data !== undefined) {\n\t\tscopeNotes(collector, slide.number).note(\n\t\t\t'slide.transitionSound',\n\t\t\t'dropped',\n\t\t\t'unsupported',\n\t\t\t\"this transition's start sound is dropped: the append path this tier rides does not register a transition's embedded audio part, so the sound does not reach the template. The assignment below still spells it out, and the WAV still ships beside the script, because both describe the source deck faithfully and would take effect the day the append path carries them — but this output is silent. Print the standalone variant to keep the sound\"\n\t\t)\n\t}\n\n\tconst layout = slide.layout === null ? 'no layout' : `layout ${JSON.stringify(slide.layout.name)}`\n\treturn printSlide(\n\t\tslide,\n\t\t{ comment: `Slide ${slide.number} — ${layout}`, construction: `${generatorName}.addSlide()` },\n\t\tcollector,\n\t\tprintAsset\n\t)\n}\n","/**\n * {@link DeckIr} → a runnable TypeScript module that depends on nothing but this package.\n * **Tier A.**\n *\n * **The trade, stated once.** The template-anchored printer (`printScript`) reuses the source\n * `.pptx` and gets the deck's entire design back byte for byte, at the cost of shipping that\n * file alongside the script and of leaving the design uneditable. This one ships a single\n * `.ts` file. Everything the source deck's chrome contained has to be *re-authored* from what\n * the read model exposes, and the read model deliberately exposes the property tiers a slide\n * inherits — colours, fonts, placeholder geometry — not the parts a slide merely sits on top\n * of. So the output is a deck that renders its slides faithfully and wears a different suit.\n *\n * **The ceiling is measured, not estimated, and no amount of printer work moves it.** Three\n * constructs are unreachable from *both* directions: `a:fmtScheme` (nothing reads it, and the\n * write path emits a hardcoded Office one), `p:txStyles` (no reader, though\n * `SlideMasterProps.textStyles` could author it), and master/layout decoration (documented as\n * out of the read model's scope, carried byte-for-byte by the import paths instead). A fourth,\n * `p:clrMap`, is readable and has no setter. Each is a fidelity note here and a `pass` in the\n * other tier, which is the whole reason the other tier shipped first.\n *\n * **One structural difference beyond the chrome.** A slide marked `carried` has no source\n * package to be carried from here, so it is transcribed like any other and loses only the\n * construct that made it uncarryable — which each shape has already declared for itself. That\n * is why {@link DeckIr}'s calls are populated even for a carried slide.\n */\nimport type { DeckIr, IrValue, MasterIr } from '../ir.js'\nimport { NoteCollector, scopeNotes } from '../fidelity.js'\nimport { inches } from '../from-read/values.js'\nimport { printArguments, printString, printValue, type AssetPrinter } from './literal.js'\nimport {\n\tassetIdentifiers,\n\tassetPrinter,\n\theader,\n\tprintAssetBindings,\n\tprintSlide,\n\ttype AssetMode,\n\ttype PrintedScript,\n} from './common.js'\n\nexport interface PrintStandaloneScriptOptions {\n\t/** Path the emitted script writes to, resolved against the script's own location. @default './output.pptx' */\n\toutputPath?: string\n\t/** Directory the emitted script reads image assets from, when {@link assets} is `'file'`. @default './assets' */\n\tassetDir?: string\n\t/** @default 'file' */\n\tassets?: AssetMode\n\t/**\n\t * Import specifier the emitted script uses. Defaults to this package's own published\n\t * name; override it to point a generated script at a local build or a fork.\n\t * @default '@shbernal/ts-pptx'\n\t */\n\tpackageName?: string\n}\n\n/**\n * Notes the IR declares that do not describe *this* output.\n *\n * Only one, and it is the mirror of the other tier's list. `slide.carried` says a slide will\n * be copied from the source package rather than transcribed; there is no source package here,\n * so the slide is transcribed and the construct that made it uncarryable has already recorded\n * its own note. Reporting both would double-count one loss and describe a behaviour this\n * script does not have.\n */\nconst NOT_APPLICABLE = new Set(['slide.carried'])\n\n/** See `printScript` — the published name is not the directory name, and a test pins it. */\nconst PACKAGE_NAME = '@shbernal/ts-pptx'\n\n/** Turn a deck IR into a runnable TypeScript module that needs no template. */\nexport function printStandaloneScript(ir: DeckIr, options: PrintStandaloneScriptOptions = {}): PrintedScript {\n\tconst outputPath = options.outputPath ?? './output.pptx'\n\tconst assetDir = (options.assetDir ?? './assets').replace(/\\/$/, '')\n\tconst assetMode = options.assets ?? 'file'\n\tconst packageName = options.packageName ?? PACKAGE_NAME\n\n\tconst collector = new NoteCollector()\n\tconst assetNames = assetIdentifiers(ir)\n\tconst printAsset = assetPrinter(assetNames)\n\n\t// Walked before the header is built: this tier's own notes are only known afterwards.\n\tconst masters = printMasters(ir, collector, printAsset)\n\tconst body = printSlides(ir, collector, printAsset)\n\tconst notes = [...ir.fidelity.filter((note) => !NOT_APPLICABLE.has(note.construct)), ...collector.notes]\n\n\tconst needsReadFile = assetMode === 'file' && ir.assets.length > 0\n\tconst lines: string[] = [\n\t\theader(\n\t\t\t[\n\t\t\t\t'Generated from a .pptx by ts-pptx/script.',\n\t\t\t\t'',\n\t\t\t\t`Standalone: this script needs nothing but ${packageName}${\n\t\t\t\t\tneedsReadFile ? ` and ${ir.assets.length} media file(s) in ${assetDir}` : ''\n\t\t\t\t}.`,\n\t\t\t\t\"The deck's theme, layouts and slide content are all re-authored through the public write\",\n\t\t\t\t'API, so every one of them is editable here — and the parts of the original design the read',\n\t\t\t\t'model cannot see are gone. They are listed below. For a byte-identical design at the cost',\n\t\t\t\t'of shipping the source deck alongside the script, print the template-anchored variant',\n\t\t\t\t'instead.',\n\t\t\t\t'',\n\t\t\t\t`Writes ${outputPath}. Needs an ESM context — it uses top-level await.`,\n\t\t\t],\n\t\t\tnotes\n\t\t),\n\t\t'',\n\t\t...(needsReadFile ? [\"import { readFile } from 'node:fs/promises'\"] : []),\n\t\t\"import { fileURLToPath } from 'node:url'\",\n\t\t`import TsPptx from ${printString(packageName)}`,\n\t\t'',\n\t\t'/** Resolve a path against this script rather than against the working directory. */',\n\t\t'const here = (name: string): string => fileURLToPath(new URL(name, import.meta.url))',\n\t\t'',\n\t\t'const pptx = new TsPptx()',\n\t\t`pptx.defineLayout({ name: 'source', width: ${inches(ir.slideSize.widthEmu)}, height: ${inches(ir.slideSize.heightEmu)} })`,\n\t\t\"pptx.layout = 'source'\",\n\t]\n\n\tconst theme = ir.chrome.theme as IrValue\n\tif (Object.keys(ir.chrome.theme).length > 0) {\n\t\tlines.push(\n\t\t\t'',\n\t\t\t\"// The theme's colour scheme and font faces. Its format scheme — the fill, line and effect\",\n\t\t\t'// style lists a shape references through p:style — has no counterpart on either side of the',\n\t\t\t\"// library, so the output carries Office's.\",\n\t\t\t`pptx.theme = ${printValue(theme, 0, printAsset)}`\n\t\t)\n\t}\n\n\tconst props = printDocProps(ir, collector)\n\tif (props.length > 0) lines.push('', ...props)\n\n\tconst assetLines = printAssetBindings(\n\t\tir,\n\t\tassetNames,\n\t\tassetDir,\n\t\tassetMode,\n\t\t'// Media bytes, inlined so this script is a single self-contained file.'\n\t)\n\tif (assetLines.length > 0) lines.push('', ...assetLines)\n\n\tif (masters.length > 0) lines.push('', ...masters)\n\tlines.push(...body, '', `await pptx.writeFile({ fileName: here(${printString(outputPath)}) })`, '')\n\n\treturn {\n\t\tcode: lines.join('\\n'),\n\t\tassets: new Map(\n\t\t\tassetMode === 'file' ? ir.assets.map((asset): [string, Uint8Array] => [asset.name, asset.bytes]) : []\n\t\t),\n\t\tnotes,\n\t}\n}\n\n/**\n * The document properties the write API can set.\n *\n * Four of the twelve the read model exposes, which is the loss `deck.docProps` already\n * declares — and unlike the template-anchored tier, here it is a real one, because nothing\n * else carries them.\n */\nfunction printDocProps(ir: DeckIr, collector: NoteCollector): string[] {\n\tconst entries = Object.entries(ir.props).filter(([, value]) => typeof value === 'string')\n\n\t// A deck built through the write API is stamped with the library's own author, company,\n\t// subject, title and revision in the constructor, and a property cannot be unset — writing\n\t// `''` emits an empty element rather than removing it. So whatever the source left blank\n\t// comes back filled in, which is a change to the deck rather than a formatting detail.\n\tconst stamped = ['title', 'author', 'company', 'subject', 'revision'].filter((key) => !(key in ir.props))\n\tif (stamped.length > 0) {\n\t\tscopeNotes(collector, null).note(\n\t\t\t'deck.docPropsDefault',\n\t\t\t'approximated',\n\t\t\t'unwritable',\n\t\t\t`the source deck declares no ${stamped.join(', ')}, and a deck built through the write API is stamped with the library's own value for each in its constructor with no way to unset it, so the output declares ${stamped.length === 1 ? 'one' : 'these'} the source did not`\n\t\t)\n\t}\n\n\tif (entries.length === 0) return []\n\treturn [\n\t\t'// Document properties. Only these have write-API setters; see the fidelity notes.',\n\t\t...entries.map(([key, value]) => `pptx.${key} = ${printString(value as string)}`),\n\t]\n}\n\n/**\n * One `defineSlideMaster` per source layout.\n *\n * The naming is the write API's rather than OOXML's: a `defineSlideMaster` call creates a\n * *layout* under the single shared master, which is the right granularity for a source layout.\n * What it carries is thin by measurement, not by choice — a layout's decoration and its\n * placeholder definitions are both out of reach (see `from-read/chrome.ts`), leaving the name\n * and the background. The name still earns its place: it is what `addSlide({ masterTitle })`\n * binds on, so the deck keeps a layout gallery a reader recognises.\n */\nfunction printMasters(ir: DeckIr, collector: NoteCollector, printAsset: AssetPrinter): string[] {\n\t// Recorded before the early return, because the extra layout is there either way: it is\n\t// seeded in the constructor, not by anything printed below. Scoped to that layout's own\n\t// title rather than deck-wide, because the round trip matches a note's `shapeName` against\n\t// the identity of what differed, and an unscoped note would declare *any* extra layout.\n\tscopeNotes(collector, null, 'DEFAULT').note(\n\t\t'master.default',\n\t\t'approximated',\n\t\t'unsupported',\n\t\t\"the write path seeds every presentation with a blank layout of its own named DEFAULT, and there is no way to remove it, so the output deck's layout gallery carries one extra entry ahead of the source's layouts; nothing binds to it, but it is visible in PowerPoint's layout picker\"\n\t)\n\tif (ir.chrome.masters.length === 0) return []\n\treturn [\n\t\t'// One master per source layout. A layout that carried decoration or placeholder',\n\t\t'// definitions has lost them — the read model decodes neither; see the fidelity notes.',\n\t\t...ir.chrome.masters.map((master) => printArguments('pptx.defineSlideMaster', [master.props], 0, printAsset)),\n\t]\n}\n\n/** Every slide, in source order, each bound to the master its source layout became. */\nfunction printSlides(ir: DeckIr, collector: NoteCollector, printAsset: AssetPrinter): string[] {\n\tconst byLayout = new Map<number, MasterIr>()\n\tfor (const master of ir.chrome.masters) byLayout.set(master.layoutIndex, master)\n\n\tconst lines: string[] = []\n\tfor (const slide of ir.slides) {\n\t\tconst master = slide.layout === null ? undefined : byLayout.get(slide.layout.index)\n\t\tconst title = typeof master?.props['title'] === 'string' ? master.props['title'] : null\n\n\t\tif (title === null) {\n\t\t\tscopeNotes(collector, slide.number).note(\n\t\t\t\t'slide.layout',\n\t\t\t\t'approximated',\n\t\t\t\t'unsupported',\n\t\t\t\tslide.layout === null\n\t\t\t\t\t? \"this slide resolves no layout of its own, so it binds to the write path's default blank layout\"\n\t\t\t\t\t: `this slide's source layout (gallery position ${slide.layout.index}) produced no master to bind to, so it binds to the write path's default blank layout`\n\t\t\t)\n\t\t}\n\n\t\tlines.push(\n\t\t\t...printSlide(\n\t\t\t\tslide,\n\t\t\t\t{\n\t\t\t\t\tcomment: `Slide ${slide.number} — ${title === null ? 'no master' : `master ${JSON.stringify(title)}`}`,\n\t\t\t\t\tconstruction: title === null ? 'pptx.addSlide()' : `pptx.addSlide({ masterTitle: ${printString(title)} })`,\n\t\t\t\t},\n\t\t\t\tcollector,\n\t\t\t\tprintAsset\n\t\t\t)\n\t\t)\n\t}\n\treturn lines\n}\n","/**\n * A {@link DeckIr} reduced to the form a round-trip diff can compare.\n *\n * The round trip is `source → IR₁ → script → deck → IR₂`. Comparing those two IRs raw\n * produces thousands of differences, almost none of which are losses: the write path\n * spells out defaults that OOXML leaves implicit, and PowerPoint spells out defaults the\n * write path leaves implicit. Both directions are noise, and drowning the real losses in\n * it is the same as not checking at all.\n *\n * **Every rule here must be an equivalence, not a convenience.** A rule that merely makes\n * the report shorter hides a defect permanently and silently — the exact failure mode this\n * subsystem exists to catch. So each one below cites the OOXML default that makes the\n * explicit and the absent spelling mean the same thing, and none of them drops a value that\n * a viewer could render differently. When in doubt the value stays in and the difference is\n * reported: a noisy report is recoverable, a quiet one is not.\n *\n * Canonicalising is deliberately *symmetric* — it runs over both IRs, so it cannot favour\n * the output. A rule that only made sense in one direction would be an exclusion dressed up\n * as a normalisation.\n */\nimport type { AssetIr, DeckIr, IrValue, SlideIr } from '../ir.js'\nimport { asIrValue, isAssetRef } from '../ir.js'\n\n/** One write-API call, with the source shape name lifted out as an address rather than data. */\nexport interface CanonicalCall {\n\tmethod: string\n\t/** `p:cNvPr/@name` of the shape this call came from, used to point a difference at it. */\n\tshapeName: string | null\n\t/**\n\t * Every `objectName` appearing anywhere inside {@link args}, which for `addGroup` is the\n\t * group's children.\n\t *\n\t * A fidelity note about a group's child is scoped to that child's name, but the child is\n\t * not a call of its own — it is an argument to the group's. Without this the note and the\n\t * difference it predicted would carry different names and never match, and a declared loss\n\t * would be reported as a defect.\n\t */\n\tcontainedNames: string[]\n\targs: IrValue[]\n}\n\nexport interface CanonicalSlide {\n\tnumber: number\n\thidden: boolean\n\t/**\n\t * The name of the layout this slide binds to, which is the only part of the binding that\n\t * is portable — a gallery *index* shifts whenever the output's gallery differs from the\n\t * source's, which it always does for a standalone output.\n\t *\n\t * Here because the binding is otherwise invisible: a printer that bound every slide to the\n\t * wrong layout, or to none, would produce identical calls and compare clean. The layout\n\t * governs theme and colour-map resolution, so that is not a cosmetic difference.\n\t */\n\tlayoutName: string | null\n\tbackground: IrValue | null\n\tnotesText: string | null\n\t/**\n\t * The show transition, or `null`.\n\t *\n\t * Here for the same reason {@link layoutName} is: a printer that stopped emitting\n\t * transitions altogether would produce identical *calls* and compare clean, so the\n\t * projection has to carry the slide-level properties the write API sets by assignment\n\t * rather than by method. It is compared structurally (key by key), not as one opaque\n\t * value, so a note can declare the loss of a transition's *sound* without also excusing a\n\t * wrong transition *type*.\n\t */\n\ttransition: IrValue | null\n\tcalls: CanonicalCall[]\n}\n\n/**\n * The deck's chrome, reduced the same way its slides are.\n *\n * Included for one reason: without it the diff cannot see the standalone tier's whole job.\n * That tier re-authors the theme and one master per source layout, and a projection that\n * covers only slides would report a printer emitting *neither* as a clean round trip — the\n * same shape of hole mutation testing found in `added` differences, one level up. A\n * template-anchored output compares equal here by construction, which is the claim that tier\n * makes and is worth checking rather than assuming.\n */\nexport interface CanonicalChrome {\n\ttheme: IrValue\n\t/** Each master's `defineSlideMaster` props, in gallery order. */\n\tmasters: IrValue[]\n}\n\nexport interface CanonicalDeck {\n\tslideSize: { widthEmu: number; heightEmu: number }\n\t/** The `docProps` the write API can set. Absent from the projection, a printer that set none would compare clean. */\n\tprops: IrValue\n\tchrome: CanonicalChrome\n\tslides: CanonicalSlide[]\n}\n\n/**\n * Option values that mean exactly what their absence means.\n *\n * Keyed by option name because the IR's argument objects are the write API's own option\n * objects, where a name identifies a construct uniquely — there is no `bold` that means\n * something other than `a:rPr/@b`.\n *\n * Each entry is an OOXML default:\n *\n * - `bold`, `italic` — `a:rPr/@b` / `@i` are `ST_OnOff`, default `false`.\n * - `baseline` — `a:rPr/@baseline` is a percentage, default `0` (no super/subscript).\n * - `breakLine` — not OOXML but the IR's own flat encoding: a run that does not end its\n * paragraph. The final run of a text frame never carries one, so absent and `false` are\n * the same statement.\n * - `wrap` — `a:bodyPr/@wrap` defaults to `square`, which the write API spells `true`.\n * - `rotate` — `a:xfrm/@rot` defaults to `0`.\n * - `flipH`, `flipV` — `a:xfrm/@flipH` / `@flipV` default to `false`.\n * - `transparency` — an alpha of 0% removed, i.e. fully opaque, which is also the default\n * when no `a:alpha` transform is present.\n * - `indentLevel` — `a:p/@lvl` defaults to `0`.\n * - `dashType` — `a:ln`'s dash defaults to `solid` when no `a:prstDash` is present.\n * - `textDirection` — `a:bodyPr/@vert` and `a:tcPr/@vert` both default to `horz`.\n *\n * Line width is deliberately **absent**: `a:ln/@w` defaults to 0 (hairline) while the write\n * path defaults it to 1pt, so those two are not the same line and the difference is real.\n */\nconst IMPLIED_DEFAULTS: Record<string, IrValue> = {\n\tbold: false,\n\titalic: false,\n\tbaseline: 0,\n\tbreakLine: false,\n\twrap: true,\n\trotate: 0,\n\tflipH: false,\n\tflipV: false,\n\ttransparency: 0,\n\tindentLevel: 0,\n\tdashType: 'solid',\n\ttextDirection: 'horz',\n}\n\n/**\n * `a:bodyPr`'s default insets in inches, in the write API's `[top, right, bottom, left]`\n * order: 45720 EMU (0.05in, 3.6pt) top and bottom, 91440 EMU (0.1in, 7.2pt) left and right.\n * A body that spells them out is inset exactly as one that omits them.\n */\nconst DEFAULT_MARGIN: readonly number[] = [0.05, 0.1, 0.05, 0.1]\n\n/** Reduce a deck IR to the comparable form. */\nexport function canonicalDeckIr(ir: DeckIr): CanonicalDeck {\n\tconst digests = assetDigests(ir.assets)\n\treturn {\n\t\tslideSize: ir.slideSize,\n\t\tprops: canonicalValue(ir.props as IrValue, digests),\n\t\tchrome: {\n\t\t\ttheme: canonicalValue(ir.chrome.theme as IrValue, digests),\n\t\t\tmasters: ir.chrome.masters.map((master) => canonicalValue(master.props, digests)),\n\t\t},\n\t\tslides: ir.slides.map((slide) => canonicalSlide(slide, digests)),\n\t}\n}\n\nfunction canonicalSlide(slide: SlideIr, digests: Map<string, string>): CanonicalSlide {\n\treturn {\n\t\tnumber: slide.number,\n\t\thidden: slide.hidden,\n\t\tlayoutName: slide.layout?.name ?? null,\n\t\tbackground: slide.background === undefined ? null : canonicalValue(slide.background as IrValue, digests),\n\t\tnotesText: slide.notesText ?? null,\n\t\ttransition: slide.transition === undefined ? null : canonicalValue(asIrValue(slide.transition), digests),\n\t\tcalls: slide.calls.map((call) => {\n\t\t\tconst args = call.args.map((arg) => canonicalValue(arg, digests))\n\t\t\treturn {\n\t\t\t\tmethod: call.method,\n\t\t\t\tshapeName: call.sourceName ?? null,\n\t\t\t\tcontainedNames: [...collectObjectNames(args, new Set())],\n\t\t\t\targs,\n\t\t\t}\n\t\t}),\n\t}\n}\n\n/** Every `objectName` value reachable in `value`, at any depth. */\nfunction collectObjectNames(value: IrValue, out: Set<string>): Set<string> {\n\tif (Array.isArray(value)) {\n\t\tfor (const item of value) collectObjectNames(item, out)\n\t\treturn out\n\t}\n\tif (value === null || typeof value !== 'object') return out\n\tfor (const [key, item] of Object.entries(value)) {\n\t\tif (key === 'objectName' && typeof item === 'string') out.add(item)\n\t\telse collectObjectNames(item as IrValue, out)\n\t}\n\treturn out\n}\n\n/**\n * Recursively drop implied defaults and resolve asset references to a content digest.\n *\n * The digest matters more than it looks: assets are named `image1.png`, `image2.png`, … in\n * the order the walk meets them, and the output deck can meet the same bytes in a different\n * order or under a different extension. Comparing names would report a swap that did not\n * happen and, worse, would *miss* one where two images traded places.\n */\nfunction canonicalValue(value: IrValue, digests: Map<string, string>): IrValue {\n\tif (isAssetRef(value)) return { $asset: digests.get(value.$asset) ?? `unknown:${value.$asset}` }\n\tif (Array.isArray(value)) return value.map((item) => canonicalValue(item, digests))\n\tif (value === null || typeof value !== 'object') return value\n\n\t// A run with no characters has no colour anyone can see, and the write path gives every\n\t// run it emits an explicit one. Narrowed to `color` deliberately: a size or a bullet on an\n\t// empty paragraph still affects line height and still draws a glyph, so those stay.\n\tconst blankRun = value['text'] === '' && typeof value['options'] === 'object' && value['options'] !== null\n\n\tconst out: Record<string, IrValue> = {}\n\tfor (const [key, item] of Object.entries(value)) {\n\t\tif (key in IMPLIED_DEFAULTS && item === IMPLIED_DEFAULTS[key]) continue\n\t\tif (key === 'margin' && isDefaultMargin(item)) continue\n\t\tif (blankRun && key === 'options') {\n\t\t\tconst visible = { ...(item as Record<string, IrValue>) }\n\t\t\tdelete visible['color']\n\t\t\tout[key] = canonicalValue(visible, digests)\n\t\t\tcontinue\n\t\t}\n\t\tout[key] = canonicalValue(item, digests)\n\t}\n\treturn out\n}\n\nfunction isDefaultMargin(value: IrValue): boolean {\n\treturn (\n\t\tArray.isArray(value) &&\n\t\tvalue.length === DEFAULT_MARGIN.length &&\n\t\tvalue.every((item, index) => item === DEFAULT_MARGIN[index])\n\t)\n}\n\n/**\n * Content digests keyed by asset name, so the same bytes compare equal under any name.\n *\n * FNV-1a rather than a real hash: this identifies bytes for a comparison both sides of\n * which are in hand, so collision resistance against an adversary is not a property it\n * needs, and the library stays free of `node:crypto` and of the isomorphism problem\n * importing it would create.\n */\nfunction assetDigests(assets: AssetIr[]): Map<string, string> {\n\tconst out = new Map<string, string>()\n\tfor (const asset of assets) {\n\t\tlet hash = 0x811c9dc5\n\t\tfor (const byte of asset.bytes) {\n\t\t\thash ^= byte\n\t\t\thash = Math.imul(hash, 0x01000193) >>> 0\n\t\t}\n\t\tout.set(asset.name, `${asset.bytes.length}:${hash.toString(16)}`)\n\t}\n\treturn out\n}\n","/**\n * The round-trip oracle: does the deck a printed script builds match the deck it was read\n * from, everywhere the fidelity notes did not say it would not?\n *\n * **Why a projection diff and not byte identity.** The output package is not the input\n * package and never will be — different rel ids, different shape ids, a regenerated shape\n * tree, `dirty=\"0\"` on every run. Comparing bytes would report a total mismatch for every\n * deck and prove nothing. So the comparison happens one level up, on the IR: run the same\n * `readModelToIr` over the source deck and over the deck the script produced, and compare\n * those. Two decks that produce the same IR make the same write-API calls, which is exactly\n * the claim a generated script makes.\n *\n * **What a note is worth here.** A {@link FidelityNote} says a named construct will not\n * survive. That makes it an *exclusion with a signature*: the difference it predicts is\n * allowed, and every other difference is a defect. Without the notes there would be no way\n * to tell a known cost from a regression, and the check could only ever be a snapshot.\n *\n * **Two blind spots, both stated plainly, because a clean report is worth exactly what its\n * limits allow.**\n *\n * 1. *The reader is shared.* Both IRs come from `readModelToIr`, so a construct the read\n * model cannot see is missing from both and compares equal. This check cannot certify\n * anything the read path does not read; `pnpm run read:census` measures that surface, and\n * the two are complementary rather than overlapping.\n * 2. *The converter need not be injective.* Two different source constructs can map to the\n * same call, and then the round trip agrees while the deck has changed. Measured, not\n * hypothetical: the mapper once read an explicit `a:buNone` as the glyph `n`, so a\n * bulletless paragraph gained a bullet — and because the output's real `n` bullet read\n * back through the same wrong mapping, the diff was clean. Mutation testing is what\n * catches that class, and a mutation that survives here is a statement about this\n * check's reach rather than a mistake in it.\n *\n * A clean report means \"nothing the converter can distinguish was lost\", never \"nothing was\n * lost\".\n */\nimport type { FidelityNote } from '../fidelity.js'\nimport type { CanonicalCall, CanonicalChrome, CanonicalDeck, CanonicalSlide } from './canonical.js'\nimport type { IrValue } from '../ir.js'\n\n/**\n * Which way a difference points.\n *\n * `lost` and `changed` are the ones the fidelity contract governs — the source said\n * something the output does not, or says differently. `added` is the write path being\n * explicit where the source was implicit, which is *usually* harmless and is reported\n * separately for a reason worth stating: this diff cannot tell whether the value the write\n * path chose is the one the source was inheriting. An `added` `color` is benign if the\n * shape was inheriting that colour and a silent repaint if it was not.\n */\nexport type DifferenceKind = 'lost' | 'added' | 'changed'\n\n/**\n * Options the write path materialises that the source deck left implicit, with the reason\n * each is not judgeable from here.\n *\n * This list exists because `added` differences cannot simply be waved through. Mutation\n * testing settled that: dropping the converter's explicit `valign` left the write path to\n * centre every text body, which showed up as an `added` and nothing failed. So `added` is\n * held to the same standard as the rest — a note must declare it, or its field must appear\n * here with a reason.\n *\n * Every entry names a write-path default whose *correctness* the round trip has no way to\n * assess, because the source's counterpart was inherited and the read model cannot resolve\n * what it was inheriting. That is an honest \"unknown\", not an \"ignore\" — each one is a\n * candidate for the read-side backlog, and closing any of them turns its entry into a real\n * comparison.\n */\nconst WRITER_DEFAULTS: Record<string, string> = {\n\t// The write path copies the object-level and first-run character properties onto every\n\t// run it emits. The source's bare runs inherited theirs from the list style, which is\n\t// unread, so there is nothing to compare the copied value against.\n\tfontSize: 'runs inherit size from an unread list style; the write path copies the shape size onto each run',\n\toptions: 'a run or cell that carried no options at all in the source now carries the ones below',\n\t// `a:tcBdr` borders come from the table style graph, which `resolvedFill`/`borders` fold\n\t// together rather than separating; the write path spells out an explicit border per edge.\n\tborder:\n\t\t'table cell borders are resolved through the style graph, which the read model cannot separate from the cell’s own',\n\t// `a:ln/@w` defaults to a hairline in OOXML and to 1pt here, and a source outline with no\n\t// explicit width is exactly the theme-`lnRef` case `line.width` already declares unread.\n\twidth:\n\t\t'an outline with no explicit width takes the write path’s 1pt default; the source’s came from the unread theme line style',\n\t// A shape with no geometry of its own — an unfilled placeholder — has no preset to name.\n\tshape: 'a shape that inherits its geometry from a layout is emitted as a plain rectangle',\n\ttype: 'a fill or line with no explicit kind takes the write path’s solid default',\n\t// Chart options the write path always emits; the read side reports only what the chart\n\t// part contains, and these are defaults rather than authored values.\n\tchartColors: 'the write path assigns a series palette; the source’s came from the theme',\n\tdataLabelFormatCode: 'a data label with no explicit number format takes the write path’s default',\n\tshowLeaderLines: 'leader lines are on by default in the write path',\n\t// The five docProps the write path seeds in its constructor ('ts-pptx',\n\t// 'ts-pptx Presentation', '1'). A source deck that declared none of a given property gets\n\t// the library's, and there is no way to unset one — assigning `''` writes an empty element\n\t// rather than removing it. Unlike the entries above, this is a *write*-side candidate, not\n\t// a read-side one: the fix is a way to author a deck with a property genuinely absent.\n\t// Restricted to `added` by construction, so a printer that stopped writing docProps still\n\t// fails: the source's own values become `changed`, which nothing here excuses.\n\ttitle: 'a deck that declares no title gets the write path’s own',\n\tauthor: 'a deck that declares no author gets the write path’s own',\n\tsubject: 'a deck that declares no subject gets the write path’s own',\n\tcompany: 'a deck that declares no company gets the write path’s own',\n\trevision: 'a deck that declares no revision gets the write path’s own',\n}\n\nexport interface IrDifference {\n\t/** 1-based source slide. */\n\tslideNumber: number\n\t/** Source shape name, when the difference sits inside a call that has one. */\n\tshapeName: string | null\n\t/**\n\t * Shape names nested inside the same call — a group's children. A note scoped to one of\n\t * these also declares differences reported against the call that carries it.\n\t */\n\tnestedNames: string[]\n\t/** Where in the slide's projection, e.g. `calls[4].args[1].line.width`. */\n\tpath: string\n\t/**\n\t * The option name the difference is about — the last object key on {@link path}, or\n\t * `'*'` when a whole call is present on one side only. This is what a note's `construct`\n\t * is matched against, which is why `construct` has to name a field path rather than\n\t * describe one.\n\t */\n\tfield: string\n\tkind: DifferenceKind\n\t/** The source value, JSON-encoded and truncated for reporting. `'—'` when absent. */\n\texpected: string\n\t/** The output value, likewise. */\n\tactual: string\n\t/** The note that declares this difference, when one does. */\n\tdeclaredBy: FidelityNote | null\n}\n\nexport interface RoundTripReport {\n\tslideCount: number\n\t/** Every difference found, in deck order. */\n\tdifferences: IrDifference[]\n\t/**\n\t * Differences neither a note nor a known write-path default accounts for.\n\t * **These are the defects**, and the number this check gates on.\n\t */\n\tundeclared: IrDifference[]\n\t/** Differences a note declared. The contract working. */\n\tdeclared: IrDifference[]\n\t/** `added` differences: the write path spelling out what the source left implicit. */\n\tadded: IrDifference[]\n\t/**\n\t * Notes that matched no difference.\n\t *\n\t * **Not a defect signal, despite the obvious reading.** Most notes name constructs the\n\t * read model cannot see at all — a bullet's `a:buFont`, a shape's theme `effectRef` —\n\t * so they are absent from *both* IRs and there is nothing for them to match. A note\n\t * here is a candidate for review, not a stale claim.\n\t */\n\tunmatchedNotes: FidelityNote[]\n}\n\n/**\n * Option names each note construct is a promise about.\n *\n * This table is the fidelity catalogue made mechanical. A note claims a construct will not\n * survive; without a mapping from that claim to the fields it covers, the claim cannot\n * exclude anything and the round trip degenerates into a snapshot.\n *\n * `'*'` covers every difference inside the call it is scoped to — correct only where the\n * note says the whole shape is gone or was copied wholesale, never as a shortcut for a\n * construct whose fields are merely tedious to enumerate.\n *\n * An empty list is meaningful and common: the construct is invisible to the IR on both\n * sides (a slide's build animations, a paragraph's `a:pPr/@marL`, a connector's shape\n * binding), so the note is a caveat for a human and there is nothing here to exclude. Saying\n * so explicitly is what keeps it from looking like an oversight. A construct can leave that\n * state — `slide.transition` was an empty entry until the converter learned to transcribe\n * transitions, and the IR gaining a field is exactly when its note gains a mapping.\n */\nconst NOTE_FIELDS: Record<string, readonly string[]> = {\n\t'chart.blanks': ['values'],\n\t'chart.combo': ['type'],\n\t'chart.type': ['type'],\n\t'chart.workbook': ['*'],\n\t'chartEx.all': ['*'],\n\t'connector.binding': [],\n\t'connector.line': ['color', 'width', 'dashType', 'beginArrowType', 'endArrowType'],\n\t'connector.rotation': ['rotate'],\n\t// Empty, and the temptation to list title/author/subject/revision here has to be\n\t// resisted: this note is about the *other* seven docProps, which have no setter and are\n\t// absent from the IR. Listing the four that do have setters would excuse a printer that\n\t// stopped writing them — measured, by exactly that mutation.\n\t'deck.docProps': [],\n\t// Nothing to exclude: the differences it predicts are `added`, which WRITER_DEFAULTS covers\n\t// by kind. The note exists so a reader of the emitted script learns the deck gained them.\n\t'deck.docPropsDefault': [],\n\t'deck.slideSize': ['widthEmu', 'heightEmu'],\n\t'fill.gradient.path': ['gradient', 'fill'],\n\t// Recorded only when an image-filled surface cannot carry its *bytes* — a linked blip, an\n\t// SVG the write path refuses, a part missing from the package. The fill option is then\n\t// absent from the output entirely, which is the same two keys `fill.schemeToken` covers.\n\t'fill.picture': ['fill', 'color'],\n\t// Empty, and deliberately so: this note declares that a picture fill's tiling, crop, DPI\n\t// and rotWithShape do not survive, and *none of them is in the IR on either side* — the\n\t// write API expresses a picture fill as bytes plus transparency, so the converter never\n\t// emits them. Widening this to `fill` would be the mistake it looks like a fix for: it\n\t// would excuse an image fill that failed to come back at all, which is the thing the\n\t// round trip is here to catch.\n\t'fill.picture.geometry': [],\n\t'fill.schemeToken': ['fill', 'color'],\n\t'graphicFrame.unknown': ['*'],\n\t'group.child': ['*'],\n\t'group.childSpace': ['x', 'y', 'w', 'h', 'rotate', 'flipH', 'flipV'],\n\t'group.empty': ['*'],\n\t'group.transform': ['rotate', 'flipH', 'flipV'],\n\t'image.data': ['data', '$asset'],\n\t'image.recolor': ['duotone', 'grayscale', 'biLevel', 'clrChange'],\n\t// Covers the picture's bytes, not just an `svg` option: an SVG picture's raster fallback\n\t// is regenerated rather than carried, so the blip the round trip compares is a different\n\t// image from the source's — which is precisely the loss this note is about.\n\t'image.svg': ['svg', 'data', '$asset'],\n\t'line.arrowSize': ['beginArrowType', 'endArrowType'],\n\t// The chrome notes. Most are empty for the reason stated above and it is the common case\n\t// here rather than the exception: `a:fmtScheme`, `p:txStyles`, master/layout decoration and\n\t// layout placeholder definitions are all absent from the IR on *both* sides — nothing reads\n\t// them — so there is nothing for a note to exclude and the note exists for a human.\n\t// `p:clrMap` is the subtle one: a remapped token changes what every scheme colour in the\n\t// deck resolves to, and the round trip still cannot see it, because the IR reports the token\n\t// verbatim rather than its resolved hex. That is exactly the blind spot this file's header\n\t// describes, and writing `[]` is the honest spelling of it.\n\t'master.background': ['background', 'color', 'data', 'master'],\n\t'master.colorMap': [],\n\t'master.decoration': [],\n\t'master.default': ['master'],\n\t'master.multiple': [],\n\t'master.name': ['title', 'layoutName'],\n\t'master.nameCollision': ['title', 'layoutName'],\n\t'master.placeholders': [],\n\t'master.txStyles': [],\n\t'theme.fmtScheme': [],\n\t'line.dash': ['dashType'],\n\t'line.width': ['width'],\n\t'media.audioVideo': ['*'],\n\t'notes.formatting': ['notesText'],\n\t'shape.custGeom.guides': ['points'],\n\t'shape.effects': ['shadow', 'glow'],\n\t'shape.empty': ['*'],\n\t'shape.frameInherited': ['x', 'y', 'w', 'h'],\n\t'shape.hidden': ['*'],\n\t'shape.placeholder': ['placeholder'],\n\t'slide.animation': [],\n\t'slide.background': ['background', 'color', 'transparency', 'image'],\n\t'slide.carried': ['*'],\n\t'slide.layout': ['layoutName'],\n\t'slide.name': [],\n\t// A transition the write vocabulary cannot name is dropped whole, so the difference lands\n\t// on the slide's `transition` key itself. Deliberately *not* widened to the keys inside it:\n\t// this note is only ever recorded when the whole transition is gone.\n\t'slide.transition': ['transition'],\n\t// The sound alone, one level down. Scoped to `sound` so it cannot also excuse a transition\n\t// whose type or timing came back wrong — the loss it declares is exactly the missing\n\t// `p:sndAc`, and `data`/`$asset` cover the case where the sound survives with other bytes.\n\t'slide.transitionSound': ['sound', 'data', '$asset'],\n\t// A dash outside `ST_PresetLineDashVal` cannot be written back, so the edge comes out as\n\t// a plain dashed rule. Scoped to `border`, which is where that difference lands.\n\t'table.cell.borders.dash': ['border', 'diagonal'],\n\t// `table.cell.fill` used to live here, for a cell whose own fill could not be told apart\n\t// from the one it inherited from the table style. `TableCell.hasOwnFill` tells them apart,\n\t// so the mapper emits the right one and records nothing — the note is gone rather than\n\t// unmapped. Its `.gradient` / `.picture` children below are separate constructs and stay.\n\t// Empty, and correctly so: `a:tc/@id` and `a:tcPr/a:headers` have no write option — the\n\t// IR has nowhere to put them on either side, so there is nothing to exclude. The note\n\t// exists so a reader of the emitted script learns the association was there and is gone.\n\t'table.cell.headers': [],\n\t// The cell-side twins of `fill.picture` / `fill.picture.geometry`, and mapped for the\n\t// same reasons.\n\t'table.cell.fill.picture': ['fill'],\n\t'table.cell.fill.picture.geometry': [],\n\t// The table-background twins. Scoped to `tableFill` rather than `fill`, because those are\n\t// two different options: one lands on `a:tblPr`, the other is stamped onto every cell.\n\t'table.fill.picture': ['tableFill'],\n\t'table.fill.picture.geometry': [],\n\t// A gradient that cannot be expressed falls back to no gradient, so the difference lands\n\t// on the fill option itself — `tableFill` for the background, `fill` for a cell.\n\t'table.fill.gradient': ['tableFill'],\n\t'table.fill.gradient.path': ['tableFill'],\n\t'table.cell.fill.gradient': ['fill'],\n\t'table.cell.fill.gradient.path': ['fill'],\n\t// Narrowed to the East-Asian `ST_TextVerticalType` modes `textDirection` cannot spell —\n\t// the four it can now round-trip, so this no longer excuses every vertical cell.\n\t'table.cell.vert': ['textDirection', 'vert'],\n\t'table.rowAuto': ['rowH'],\n\t'table.style': ['tableStyle'],\n\t'text.align': ['align'],\n\t'text.bullet.numberStartAt': ['bullet'],\n\t'text.bullet.numberType': ['bullet'],\n\t'text.bullet.style': ['bullet'],\n\t'text.color.default': ['color'],\n\t'text.color.inherited': ['color'],\n\t'text.color.schemeToken': ['color'],\n\t'text.equation': ['*'],\n\t'text.field': ['*'],\n\t'text.bullet.glyph': ['bullet'],\n\t'text.bullet.inherited': ['bullet'],\n\t'text.indent': [],\n\t'text.paraSpaceZero': ['paraSpaceBefore', 'paraSpaceAfter'],\n\t'text.vert': ['vert'],\n}\n\n/** Every note construct this table knows how to match, for a test to check against. */\nexport function knownNoteConstructs(): string[] {\n\treturn Object.keys(NOTE_FIELDS).sort()\n}\n\n/**\n * Compare the deck a script was generated from against the deck it produced.\n *\n * `notes` must be the set that actually applies to the printed output — `printScript`'s\n * returned `notes`, not `DeckIr.fidelity`. The two differ in both directions: the printer\n * suppresses notes its tier rescues and adds ones its tier causes, so diffing against the\n * IR's own list would both over- and under-exclude.\n */\nexport function diffDeckIr(expected: CanonicalDeck, actual: CanonicalDeck, notes: FidelityNote[]): RoundTripReport {\n\tconst differences: IrDifference[] = []\n\n\tif (expected.slideSize.widthEmu !== actual.slideSize.widthEmu) {\n\t\tdifferences.push(scalarDifference(0, null, [], 'slideSize.widthEmu', 'widthEmu', expected.slideSize.widthEmu, actual.slideSize.widthEmu)) // prettier-ignore\n\t}\n\tif (expected.slideSize.heightEmu !== actual.slideSize.heightEmu) {\n\t\tdifferences.push(scalarDifference(0, null, [], 'slideSize.heightEmu', 'heightEmu', expected.slideSize.heightEmu, actual.slideSize.heightEmu)) // prettier-ignore\n\t}\n\n\tdiffValue(expected.props, actual.props, 'props', 'props', 0, null, [], differences)\n\tdiffChrome(expected.chrome, actual.chrome, differences)\n\n\tconst slideCount = Math.max(expected.slides.length, actual.slides.length)\n\tfor (let index = 0; index < slideCount; index++) {\n\t\tconst before = expected.slides[index]\n\t\tconst after = actual.slides[index]\n\t\tconst number = before?.number ?? after?.number ?? index + 1\n\t\tif (!before || !after) {\n\t\t\tdifferences.push({\n\t\t\t\tslideNumber: number,\n\t\t\t\tshapeName: null,\n\t\t\t\tnestedNames: [],\n\t\t\t\tpath: `slides[${index}]`,\n\t\t\t\tfield: '*',\n\t\t\t\tkind: before ? 'lost' : 'added',\n\t\t\t\texpected: before ? 'slide' : '—',\n\t\t\t\tactual: after ? 'slide' : '—',\n\t\t\t\tdeclaredBy: null,\n\t\t\t})\n\t\t\tcontinue\n\t\t}\n\t\tdiffSlide(before, after, differences)\n\t}\n\n\tfor (const difference of differences) difference.declaredBy = declaringNote(difference, notes)\n\tconst matched = new Set(differences.map((difference) => difference.declaredBy).filter(Boolean))\n\tconst accounted = (difference: IrDifference): boolean =>\n\t\tdifference.declaredBy !== null || (difference.kind === 'added' && difference.field in WRITER_DEFAULTS)\n\n\treturn {\n\t\tslideCount: expected.slides.length,\n\t\tdifferences,\n\t\tundeclared: differences.filter((difference) => !accounted(difference)),\n\t\tdeclared: differences.filter((difference) => difference.declaredBy !== null),\n\t\tadded: differences.filter((difference) => difference.kind === 'added'),\n\t\tunmatchedNotes: notes.filter((note) => !matched.has(note)),\n\t}\n}\n\n/**\n * The theme and the layout gallery.\n *\n * Reported at `slideNumber: 0`, the same deck-level bucket the slide size uses, so a\n * deck-scoped note (which carries `slideNumber: null` and matches any slide) can declare one.\n * Masters align by **title**, not by position, for the same reason calls align by shape name:\n * the write path always emits a blank layout of its own at gallery position 0, so positional\n * alignment reports every layout in the deck as renamed and buries the one real difference —\n * that extra layout — under a shift.\n *\n * And, exactly as with shape names, a title is only usable as a key where it is *unique on\n * both sides*. Uniqueness is supposed to be an invariant here — the converter deduplicates\n * titles because a title is also what `addSlide({ masterTitle })` binds on — but keying on it\n * unconditionally makes the check assume the thing it should be testing: a mutation that\n * removed the deduplication left two layouts sharing a title, both expected entries matched\n * the same actual one, and the round trip came back clean. Falling back to position when the\n * key repeats costs nothing when the invariant holds and catches it when it does not.\n */\nfunction diffChrome(expected: CanonicalChrome, actual: CanonicalChrome, out: IrDifference[]): void {\n\tdiffValue(expected.theme, actual.theme, 'chrome.theme', 'theme', 0, null, [], out)\n\n\t// A whole master appearing or disappearing is reported *scoped to its title*, using the\n\t// same `shapeName` channel a shape-scoped note uses. Without that, one note declaring the\n\t// blank layout the write path always adds would carry `field: 'master'` and excuse every\n\t// added layout — which is what a mutation that stopped deduplicating layout titles proved.\n\tconst report = (\n\t\tpath: string,\n\t\tkind: DifferenceKind,\n\t\tbefore: IrValue | undefined,\n\t\tafter: IrValue | undefined\n\t): void => {\n\t\tout.push({\n\t\t\tslideNumber: 0,\n\t\t\tshapeName: titleOf(before ?? after ?? null),\n\t\t\tnestedNames: [],\n\t\t\tpath,\n\t\t\tfield: 'master',\n\t\t\tkind,\n\t\t\texpected: brief(before),\n\t\t\tactual: brief(after),\n\t\t\tdeclaredBy: null,\n\t\t})\n\t}\n\n\tconst byTitle = uniqueByTitle(actual.masters)\n\tconst expectedTitles = uniqueByTitle(expected.masters)\n\tconst claimed = new Set<IrValue>()\n\tlet cursor = 0\n\tconst nextUnclaimed = (): IrValue | undefined => {\n\t\twhile (cursor < actual.masters.length) {\n\t\t\tconst candidate = actual.masters[cursor++]\n\t\t\tif (candidate !== undefined && !claimed.has(candidate)) return candidate\n\t\t}\n\t\treturn undefined\n\t}\n\n\texpected.masters.forEach((before, index) => {\n\t\tconst title = titleOf(before)\n\t\t// Usable only where the title identifies exactly one master on each side.\n\t\tconst named = title !== null && expectedTitles.has(title) ? byTitle.get(title) : undefined\n\t\tconst after = named !== undefined && !claimed.has(named) ? named : nextUnclaimed()\n\t\tif (after === undefined) {\n\t\t\treport(`chrome.masters[${index}]`, 'lost', before, undefined)\n\t\t\treturn\n\t\t}\n\t\tclaimed.add(after)\n\t\tdiffValue(before, after, `chrome.masters[${index}]`, 'master', 0, null, [], out)\n\t})\n\n\tactual.masters.forEach((after, index) => {\n\t\tif (!claimed.has(after)) report(`chrome.masters[${index}]`, 'added', undefined, after)\n\t})\n}\n\n/** Masters keyed by title, keeping only titles that identify exactly one of them. */\nfunction uniqueByTitle(masters: IrValue[]): Map<string, IrValue> {\n\tconst counts = new Map<string, number>()\n\tfor (const master of masters) {\n\t\tconst title = titleOf(master)\n\t\tif (title !== null) counts.set(title, (counts.get(title) ?? 0) + 1)\n\t}\n\tconst out = new Map<string, IrValue>()\n\tfor (const master of masters) {\n\t\tconst title = titleOf(master)\n\t\tif (title !== null && counts.get(title) === 1) out.set(title, master)\n\t}\n\treturn out\n}\n\n/** A canonical master's `title`, which is its identity across the round trip. */\nfunction titleOf(master: IrValue): string | null {\n\tif (master === null || typeof master !== 'object' || Array.isArray(master)) return null\n\tconst title = (master as Record<string, IrValue>)['title']\n\treturn typeof title === 'string' ? title : null\n}\n\nfunction diffSlide(expected: CanonicalSlide, actual: CanonicalSlide, out: IrDifference[]): void {\n\tconst number = expected.number\n\tconst at = (path: string, field: string, a: IrValue, b: IrValue): void => {\n\t\tif (JSON.stringify(a) !== JSON.stringify(b)) out.push(scalarDifference(number, null, [], path, field, a, b))\n\t}\n\tat('hidden', 'hidden', expected.hidden, actual.hidden)\n\tat('layoutName', 'layoutName', expected.layoutName, actual.layoutName)\n\tat('background', 'background', expected.background, actual.background)\n\tat('notesText', 'notesText', expected.notesText, actual.notesText)\n\t// Structural rather than whole-value, unlike the four above: a transition is a small object\n\t// whose parts are lost independently — the append path drops an embedded sound while\n\t// keeping the effect — and a whole-value compare would force the note that declares the\n\t// sound to carry `field: 'transition'`, which would then excuse a wrong type or duration too.\n\tdiffValue(expected.transition, actual.transition, 'transition', 'transition', number, null, [], out)\n\n\tfor (const [before, after] of alignCalls(expected.calls, actual.calls)) {\n\t\tconst name = before?.shapeName ?? after?.shapeName ?? null\n\t\t// Union of both sides: a child that dropped out is named only by the source's call.\n\t\tconst nested = [...new Set([...(before?.containedNames ?? []), ...(after?.containedNames ?? [])])]\n\t\tconst path = `calls[${before ? expected.calls.indexOf(before) : actual.calls.indexOf(after as CanonicalCall)}]`\n\t\tif (!before || !after) {\n\t\t\tout.push({\n\t\t\t\tslideNumber: number,\n\t\t\t\tshapeName: name,\n\t\t\t\tnestedNames: nested,\n\t\t\t\tpath,\n\t\t\t\tfield: '*',\n\t\t\t\tkind: before ? 'lost' : 'added',\n\t\t\t\texpected: before ? before.method : '—',\n\t\t\t\tactual: after ? after.method : '—',\n\t\t\t\tdeclaredBy: null,\n\t\t\t})\n\t\t\tcontinue\n\t\t}\n\t\tif (before.method !== after.method) {\n\t\t\tout.push(scalarDifference(number, name, nested, `${path}.method`, 'method', before.method, after.method))\n\t\t}\n\t\tdiffValue(before.args, after.args, `${path}.args`, 'args', number, name, nested, out)\n\t}\n}\n\n/**\n * Pair up the two slides' calls.\n *\n * Position alone is wrong the moment one shape drops out: every later call shifts by one\n * and the report fills with mismatches that are really one missing shape. Shape names\n * survive the round trip (the converter passes `objectName` through), so they are the\n * alignment key wherever they are present and unambiguous, with position as the fallback\n * for unnamed or duplicate-named shapes.\n */\nfunction alignCalls(\n\texpected: CanonicalCall[],\n\tactual: CanonicalCall[]\n): Array<[CanonicalCall | null, CanonicalCall | null]> {\n\tconst usable = (calls: CanonicalCall[]): Map<string, CanonicalCall> => {\n\t\tconst counts = new Map<string, number>()\n\t\tfor (const call of calls) {\n\t\t\tif (call.shapeName === null) continue\n\t\t\tcounts.set(call.shapeName, (counts.get(call.shapeName) ?? 0) + 1)\n\t\t}\n\t\tconst out = new Map<string, CanonicalCall>()\n\t\tfor (const call of calls) {\n\t\t\tif (call.shapeName !== null && counts.get(call.shapeName) === 1) out.set(call.shapeName, call)\n\t\t}\n\t\treturn out\n\t}\n\n\tconst byName = usable(actual)\n\tconst claimed = new Set<CanonicalCall>()\n\tconst pairs: Array<[CanonicalCall | null, CanonicalCall | null]> = []\n\t// Positional cursor for calls that names cannot align, advanced only past claimed calls\n\t// so a named match does not consume an unnamed call's slot.\n\tlet cursor = 0\n\tconst nextUnclaimed = (): CanonicalCall | null => {\n\t\twhile (cursor < actual.length) {\n\t\t\tconst candidate = actual[cursor++]\n\t\t\tif (candidate && !claimed.has(candidate)) return candidate\n\t\t}\n\t\treturn null\n\t}\n\n\tfor (const call of expected) {\n\t\tconst named = call.shapeName === null ? undefined : byName.get(call.shapeName)\n\t\tif (named && !claimed.has(named)) {\n\t\t\tclaimed.add(named)\n\t\t\tpairs.push([call, named])\n\t\t\tcontinue\n\t\t}\n\t\tconst positional = nextUnclaimed()\n\t\tif (positional) claimed.add(positional)\n\t\tpairs.push([call, positional])\n\t}\n\tfor (const call of actual) if (!claimed.has(call)) pairs.push([null, call])\n\treturn pairs\n}\n\nfunction diffValue(\n\texpected: IrValue,\n\tactual: IrValue,\n\tpath: string,\n\tfield: string,\n\tslideNumber: number,\n\tshapeName: string | null,\n\tnestedNames: string[],\n\tout: IrDifference[]\n): void {\n\tif (expected === actual) return\n\tconst kindOf = (value: IrValue): string => (value === null ? 'null' : Array.isArray(value) ? 'array' : typeof value)\n\tif (kindOf(expected) !== kindOf(actual)) {\n\t\tout.push(scalarDifference(slideNumber, shapeName, nestedNames, path, field, expected, actual))\n\t\treturn\n\t}\n\n\tif (Array.isArray(expected) && Array.isArray(actual)) {\n\t\tconst length = Math.max(expected.length, actual.length)\n\t\tfor (let index = 0; index < length; index++) {\n\t\t\tconst before = expected[index]\n\t\t\tconst after = actual[index]\n\t\t\tif (before === undefined || after === undefined) {\n\t\t\t\tout.push({\n\t\t\t\t\tslideNumber,\n\t\t\t\t\tshapeName,\n\t\t\t\t\tnestedNames,\n\t\t\t\t\tpath: `${path}[${index}]`,\n\t\t\t\t\tfield,\n\t\t\t\t\tkind: before === undefined ? 'added' : 'lost',\n\t\t\t\t\texpected: brief(before),\n\t\t\t\t\tactual: brief(after),\n\t\t\t\t\tdeclaredBy: null,\n\t\t\t\t})\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tdiffValue(before, after, `${path}[${index}]`, field, slideNumber, shapeName, nestedNames, out)\n\t\t}\n\t\treturn\n\t}\n\n\tif (expected !== null && typeof expected === 'object' && actual !== null && typeof actual === 'object') {\n\t\tconst record = expected as Record<string, IrValue>\n\t\tconst other = actual as Record<string, IrValue>\n\t\tfor (const key of new Set([...Object.keys(record), ...Object.keys(other)])) {\n\t\t\tconst before = record[key]\n\t\t\tconst after = other[key]\n\t\t\tif (before === undefined || after === undefined) {\n\t\t\t\tout.push({\n\t\t\t\t\tslideNumber,\n\t\t\t\t\tshapeName,\n\t\t\t\t\tnestedNames,\n\t\t\t\t\tpath: `${path}.${key}`,\n\t\t\t\t\tfield: key,\n\t\t\t\t\tkind: before === undefined ? 'added' : 'lost',\n\t\t\t\t\texpected: brief(before),\n\t\t\t\t\tactual: brief(after),\n\t\t\t\t\tdeclaredBy: null,\n\t\t\t\t})\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tdiffValue(before, after, `${path}.${key}`, key, slideNumber, shapeName, nestedNames, out)\n\t\t}\n\t\treturn\n\t}\n\n\tout.push(scalarDifference(slideNumber, shapeName, nestedNames, path, field, expected, actual))\n}\n\nfunction scalarDifference(\n\tslideNumber: number,\n\tshapeName: string | null,\n\tnestedNames: string[],\n\tpath: string,\n\tfield: string,\n\texpected: IrValue,\n\tactual: IrValue\n): IrDifference {\n\treturn {\n\t\tslideNumber,\n\t\tshapeName,\n\t\tnestedNames,\n\t\tpath,\n\t\tfield,\n\t\tkind: 'changed',\n\t\texpected: brief(expected),\n\t\tactual: brief(actual),\n\t\tdeclaredBy: null,\n\t}\n}\n\n/** The first note that covers this difference, or `null` if none does. */\nfunction declaringNote(difference: IrDifference, notes: FidelityNote[]): FidelityNote | null {\n\tfor (const note of notes) {\n\t\tif (note.slideNumber !== null && note.slideNumber !== difference.slideNumber) continue\n\t\t// A shape-scoped note covers only that shape; a slide- or deck-scoped one covers any.\n\t\tif (\n\t\t\tnote.shapeName !== null &&\n\t\t\tnote.shapeName !== difference.shapeName &&\n\t\t\t!difference.nestedNames.includes(note.shapeName)\n\t\t) {\n\t\t\tcontinue\n\t\t}\n\t\tconst fields = NOTE_FIELDS[note.construct]\n\t\tif (!fields) continue\n\t\tif (fields.includes('*') || fields.includes(difference.field)) return note\n\t}\n\treturn null\n}\n\nfunction brief(value: IrValue | undefined): string {\n\tif (value === undefined) return '—'\n\tconst text = JSON.stringify(value)\n\treturn text.length > 80 ? `${text.slice(0, 80)}…` : text\n}\n"],"mappings":"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"}