{"version":3,"sources":["../src/io/ooxml-marks.ts","../src/io/ooxml-units.ts","../src/io/table-model.ts","../src/page-setup.ts","../src/io/ooxml-parser.ts","../src/theme.ts","../src/io/docx-package.ts","../src/io/save.ts","../src/io/ooxml-serializer.ts","../src/headless.ts","../src/io/template.ts","../src/extensions/builtins/watermark.ts","../src/io/pdf.ts"],"names":["n","documentXml","stylesXml","coreXml","numberingXml","commentsXml","JSZip","getJSZip","EMU_PER_PX","escapeXml","saveDocxFromJSON","__dirname","dirname","fileURLToPath","join","readFileSync","parseCoreXml"],"mappings":"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","file":"headless.cjs","sourcesContent":["/**\n * Shared mark <-> OOXML attribute tables, used by the parser, the selective\n * serializer, and the full-rebuild (`docx` library) save path.\n *\n * `ooxml-parser.ts` and `ooxml-serializer.ts` used to each carry their own\n * copy of the highlight-color table — the parser's OOXML-name-to-hex map had\n * 15 entries, the serializer's reverse hex-to-name map had only 6, so\n * highlighting a run `darkGreen` in Word and round-tripping it through a\n * selective save silently turned it `yellow` (the serializer's fallback)\n * because `#006400` wasn't in its table at all. Deriving the reverse map\n * from the same table makes the two directions structurally impossible to\n * disagree.\n */\n\n/** Canonical OOXML highlight-color name -> CSS hex color. */\nexport const HIGHLIGHT_COLORS: Record<string, string> = {\n  yellow: '#fff3a0',\n  green: '#90ee90',\n  cyan: '#87ceeb',\n  magenta: '#ffb6c1',\n  blue: '#add8e6',\n  red: '#ffb3b3',\n  darkBlue: '#00008b',\n  darkCyan: '#008b8b',\n  darkGreen: '#006400',\n  darkMagenta: '#8b008b',\n  darkRed: '#8b0000',\n  darkYellow: '#8b8b00',\n  darkGray: '#a9a9a9',\n  lightGray: '#d3d3d3',\n  black: '#000000',\n};\n\n/** Derived reverse lookup — always symmetric with `HIGHLIGHT_COLORS` above. */\nconst HEX_TO_HIGHLIGHT_NAME: Record<string, string> = Object.fromEntries(\n  Object.entries(HIGHLIGHT_COLORS).map(([name, hex]) => [hex.toLowerCase(), name]),\n);\n\n/** OOXML highlight name -> CSS hex, e.g. `\"darkGreen\"` -> `\"#006400\"`. Unknown names fall back to yellow. */\nexport function highlightNameToHex(ooxmlColor: string): string {\n  return HIGHLIGHT_COLORS[ooxmlColor] ?? HIGHLIGHT_COLORS.yellow;\n}\n\n/** CSS hex -> OOXML highlight name, e.g. `\"#006400\"` -> `\"darkGreen\"`. Unknown colors fall back to yellow. */\nexport function hexToHighlightName(hex: string): string {\n  return HEX_TO_HIGHLIGHT_NAME[(hex ?? '').toLowerCase()] ?? 'yellow';\n}\n","/**\n * Shared unit-conversion constants for OOXML <-> CSS px, used by the parser,\n * the selective serializer, and the full-rebuild (`docx` library) save path.\n *\n * Previously each of those three places carried its own copy of the\n * point/pixel ratio as a bare `1.333` literal (`ooxml-parser.ts` and\n * `ooxml-serializer.ts`), which is an approximation of the real ratio and\n * risked drifting further apart if one side's rounding were ever tweaked\n * without touching the other. Centralizing it here means parse and\n * serialize always agree exactly, since they're the same function.\n */\n\n/** CSS px per point at 96 DPI (the standard \"1 CSS px = 1/96 inch\" ratio). */\nexport const PX_PER_POINT = 96 / 72;\n\n/** OOXML expresses font sizes in half-points (`w:sz`). Convert to CSS px. */\nexport function halfPointsToPx(halfPoints: number): number {\n  return (halfPoints / 2) * PX_PER_POINT;\n}\n\n/** Convert a CSS px font size back to OOXML half-points, rounded. */\nexport function pxToHalfPoints(px: number): number {\n  return Math.round((px / PX_PER_POINT) * 2);\n}\n","/**\n * Shared table-layout model — the single source of truth both DOCX save\n * paths (`io/save.ts` via the `docx` library, and `io/ooxml-serializer.ts`\n * via raw OOXML strings) use to turn a TipTap `table` node into a real\n * grid.\n *\n * Why this exists: a TipTap/ProseMirror table only stores the cells that\n * *originate* in each row. A cell with `rowspan > 1` appears once, in its\n * top row; the positions it covers in the rows below are simply absent\n * from those rows' `content`. To emit correct OOXML (`<w:gridSpan>` for\n * horizontal merges, `<w:vMerge>` restart/continue for vertical merges,\n * and a `<w:tblGrid>` whose column count matches every row) we have to\n * reconstruct the full rectangular grid — which is exactly what both\n * serializers were missing, so column widths, merged cells, shading and\n * alignment were all being dropped on export.\n *\n * Keeping this in one module means the two export paths can't drift out of\n * sync on how they interpret `colwidth`/`colspan`/`rowspan`.\n */\n\n/** 1 CSS px @ 96dpi = 1/96 in; 1 in = 1440 twips → 15 twips per px. */\nexport const TWIPS_PER_PX = 15;\n\nexport interface TableCellModel {\n  /** The originating TipTap cell node (tableCell | tableHeader). */\n  node: any;\n  /** Whether this cell is a header cell (`tableHeader`). */\n  isHeader: boolean;\n  /** Horizontal span (OOXML `w:gridSpan`). >= 1. */\n  colspan: number;\n  /** Vertical span (drives OOXML `w:vMerge` restart). >= 1. */\n  rowspan: number;\n  /** 0-based index of this cell's first column in the reconstructed grid. */\n  gridColStart: number;\n  /** Combined width in px across the columns this cell spans, or null when\n   *  no `colwidth` info is available for any spanned column. */\n  widthPx: number | null;\n  /** Per-column background fill (hex without '#'), or null. */\n  backgroundColor: string | null;\n  /** True for the synthetic continuation cells emitted in the rows a\n   *  rowspan covers — these must render as `<w:vMerge/>` (continue) with no\n   *  content of their own. */\n  vMergeContinue: boolean;\n}\n\nexport interface TableRowModel {\n  cells: TableCellModel[];\n  /** Explicit row height in px (from the `rowHeight` attr), or null. */\n  heightPx: number | null;\n}\n\nexport interface TableModel {\n  rows: TableRowModel[];\n  /** Number of grid columns (max across all rows). */\n  columns: number;\n  /** Per-grid-column width in px. Entries are null where unknown. */\n  colWidthsPx: (number | null)[];\n  /** Table-level attributes, normalized. */\n  tableWidthPx: number | null;\n  tableWidthPercent: number | null;\n  align: 'left' | 'center' | 'right' | null;\n  borderStyle: string | null;\n  tableStyleId: string | null;\n}\n\n/** Parse a CSS length like \"120px\", \"50%\", or a bare number to px. Returns\n *  `{ px }`, `{ percent }`, or null when unresolvable. */\nfunction parseLength(value: any): { px?: number; percent?: number } | null {\n  if (value === null || value === undefined || value === '') return null;\n  const str = String(value).trim();\n  if (str.endsWith('%')) {\n    const n = parseFloat(str);\n    return isNaN(n) ? null : { percent: n };\n  }\n  const n = parseFloat(str);\n  return isNaN(n) || n <= 0 ? null : { px: Math.round(n) };\n}\n\n/** Normalize a CSS color to an OOXML hex ('RRGGBB', no '#'), or null.\n *  Supports #rgb, #rrggbb, and a small set of common names. */\nexport function cssColorToHex(value: any): string | null {\n  if (!value) return null;\n  let s = String(value).trim().toLowerCase();\n  const NAMED: Record<string, string> = {\n    white: 'FFFFFF', black: '000000', red: 'FF0000', green: '008000',\n    blue: '0000FF', yellow: 'FFFF00', gray: '808080', grey: '808080',\n    silver: 'C0C0C0', transparent: '',\n  };\n  if (s in NAMED) return NAMED[s] || null;\n  const m = /^#?([0-9a-f]{3}|[0-9a-f]{6})$/.exec(s);\n  if (!m) return null;\n  let hex = m[1];\n  if (hex.length === 3) hex = hex.split('').map((c) => c + c).join('');\n  return hex.toUpperCase();\n}\n\nfunction cellAttr(node: any, key: string): any {\n  return node?.attrs ? node.attrs[key] : undefined;\n}\n\n/**\n * Reconstruct the full rectangular grid of a TipTap `table` node,\n * resolving colspan/rowspan into explicit per-row cells (including\n * synthetic vMerge-continuation cells) and computing per-column widths.\n */\nexport function buildTableModel(tableNode: any): TableModel {\n  const rowNodes = (tableNode?.content ?? []).filter(\n    (r: any) => r?.type === 'tableRow',\n  );\n\n  // Occupancy tracker: for each grid column, how many more rows a rowspan\n  // from above still covers, plus the info needed to emit its continuation.\n  interface Pending {\n    remaining: number;\n    colspan: number;\n    isHeader: boolean;\n    widthPx: number | null;\n    backgroundColor: string | null;\n  }\n  const pending: (Pending | null)[] = [];\n  const rows: TableRowModel[] = [];\n  const colWidthsPx: (number | null)[] = [];\n\n  const noteColWidth = (gridCol: number, span: number, colwidth: any) => {\n    // `colwidth` is an array (one entry per spanned grid column) per the\n    // prosemirror-tables schema. Record each column's own width.\n    if (Array.isArray(colwidth)) {\n      for (let k = 0; k < span; k++) {\n        const w = colwidth[k];\n        if (typeof w === 'number' && w > 0 && colWidthsPx[gridCol + k] == null) {\n          colWidthsPx[gridCol + k] = Math.round(w);\n        }\n      }\n    }\n  };\n\n  for (const rowNode of rowNodes) {\n    const cellsOut: TableCellModel[] = [];\n    const rowCells = (rowNode.content ?? []).filter(\n      (c: any) => c?.type === 'tableCell' || c?.type === 'tableHeader',\n    );\n\n    let gridCol = 0;\n    let cellIdx = 0;\n\n    // Emit continuation cells for any rowspans coming from above, and place\n    // this row's real cells in the gaps between them.\n    const advancePending = () => {\n      while (pending[gridCol] && pending[gridCol]!.remaining > 0) {\n        const p = pending[gridCol]!;\n        cellsOut.push({\n          node: null,\n          isHeader: p.isHeader,\n          colspan: p.colspan,\n          rowspan: 1,\n          gridColStart: gridCol,\n          widthPx: p.widthPx,\n          backgroundColor: p.backgroundColor,\n          vMergeContinue: true,\n        });\n        p.remaining -= 1;\n        const span = p.colspan;\n        if (p.remaining <= 0) {\n          for (let k = 0; k < span; k++) pending[gridCol + k] = null;\n        }\n        gridCol += span;\n      }\n    };\n\n    while (cellIdx < rowCells.length || (pending[gridCol] && pending[gridCol]!.remaining > 0)) {\n      advancePending();\n      if (cellIdx >= rowCells.length) break;\n\n      const cell = rowCells[cellIdx++];\n      const colspan = Math.max(1, Number(cellAttr(cell, 'colspan')) || 1);\n      const rowspan = Math.max(1, Number(cellAttr(cell, 'rowspan')) || 1);\n      const isHeader = cell.type === 'tableHeader';\n      const colwidth = cellAttr(cell, 'colwidth');\n      const backgroundColor = cssColorToHex(cellAttr(cell, 'backgroundColor'));\n\n      noteColWidth(gridCol, colspan, colwidth);\n      let widthPx: number | null = null;\n      if (Array.isArray(colwidth)) {\n        const sum = colwidth\n          .slice(0, colspan)\n          .reduce((a: number, b: any) => a + (typeof b === 'number' ? b : 0), 0);\n        if (sum > 0) widthPx = Math.round(sum);\n      }\n\n      cellsOut.push({\n        node: cell,\n        isHeader,\n        colspan,\n        rowspan,\n        gridColStart: gridCol,\n        widthPx,\n        backgroundColor,\n        vMergeContinue: false,\n      });\n\n      if (rowspan > 1) {\n        for (let k = 0; k < colspan; k++) {\n          pending[gridCol + k] = {\n            remaining: rowspan - 1,\n            colspan: 1,\n            isHeader,\n            widthPx: null,\n            backgroundColor,\n          };\n        }\n        // Store the full colspan on the first covered column so the\n        // continuation renders one cell of the right span.\n        if (pending[gridCol]) pending[gridCol]!.colspan = colspan;\n        for (let k = 1; k < colspan; k++) pending[gridCol + k] = null;\n      }\n\n      gridCol += colspan;\n    }\n    // Flush any trailing rowspans that extend past the last real cell.\n    advancePending();\n\n    const heightLen = parseLength(cellAttr(rowNode, 'rowHeight'));\n    rows.push({\n      cells: cellsOut,\n      heightPx: heightLen?.px ?? null,\n    });\n  }\n\n  const columns = rows.reduce(\n    (max, r) => Math.max(max, r.cells.reduce((s, c) => s + c.colspan, 0)),\n    0,\n  );\n  // Pad width array to column count.\n  for (let i = 0; i < columns; i++) if (colWidthsPx[i] === undefined) colWidthsPx[i] = null;\n\n  const tableWidthLen = parseLength(cellAttr(tableNode, 'tableWidth'));\n  const alignRaw = cellAttr(tableNode, 'tableAlign');\n  const align =\n    alignRaw === 'center' || alignRaw === 'right' || alignRaw === 'left'\n      ? alignRaw\n      : null;\n\n  return {\n    rows,\n    columns,\n    colWidthsPx: colWidthsPx.slice(0, columns),\n    tableWidthPx: tableWidthLen?.px ?? null,\n    tableWidthPercent: tableWidthLen?.percent ?? null,\n    align,\n    borderStyle: cellAttr(tableNode, 'borderStyle') ?? null,\n    tableStyleId: cellAttr(tableNode, 'tableStyleId') ?? null,\n  };\n}\n\n/* -------------------------------------------------------------------------- */\n/* Border + table-style preset resolution                                     */\n/* -------------------------------------------------------------------------- */\n\nexport interface BorderSpec {\n  /** OOXML border value: 'single' | 'none'. */\n  val: 'single' | 'none';\n  /** Eighths of a point. */\n  sz: number;\n  /** Hex color or 'auto'. */\n  color: string;\n}\n\nexport interface TableBorders {\n  top: BorderSpec;\n  bottom: BorderSpec;\n  left: BorderSpec;\n  right: BorderSpec;\n  insideH: BorderSpec;\n  insideV: BorderSpec;\n}\n\nconst B = (val: 'single' | 'none', color = 'auto', sz = 4): BorderSpec => ({ val, sz, color });\nconst NONE: BorderSpec = { val: 'none', sz: 0, color: 'auto' };\n\n/**\n * Resolve the effective table borders from the editor's `data-border-style`\n * / `data-table-style` presets so the exported .docx matches what the CSS\n * shows on screen. Mirrors the `[data-border-style]` / `[data-table-style]`\n * rules in `editor.css`.\n */\nexport function resolveTableBorders(model: TableModel): TableBorders {\n  const all = (): TableBorders => ({\n    top: B('single', 'D0D7DE'), bottom: B('single', 'D0D7DE'),\n    left: B('single', 'D0D7DE'), right: B('single', 'D0D7DE'),\n    insideH: B('single', 'D0D7DE'), insideV: B('single', 'D0D7DE'),\n  });\n  const none = (): TableBorders => ({\n    top: NONE, bottom: NONE, left: NONE, right: NONE, insideH: NONE, insideV: NONE,\n  });\n\n  switch (model.borderStyle) {\n    case 'none':\n      return none();\n    case 'outside': {\n      const b = none();\n      const edge = B('single', '1F2328');\n      return { ...b, top: edge, bottom: edge, left: edge, right: edge };\n    }\n    case 'inside': {\n      const b = all();\n      return { ...b, top: NONE, bottom: NONE, left: NONE, right: NONE };\n    }\n    case 'top':\n      return { ...none(), top: B('single', '1F2328') };\n    case 'bottom':\n      return { ...none(), bottom: B('single', '1F2328') };\n    case 'left':\n      return { ...none(), left: B('single', '1F2328') };\n    case 'right':\n      return { ...none(), right: B('single', '1F2328') };\n    case 'all':\n      return all();\n  }\n\n  // Fall back to table-style presets when no explicit border style is set.\n  switch (model.tableStyleId) {\n    case 'medium-grid': {\n      const g = B('single', '1F2937');\n      return { top: g, bottom: g, left: g, right: g, insideH: g, insideV: g };\n    }\n    case 'plain': {\n      const g = B('single', 'ECEEF1');\n      return { top: g, bottom: g, left: g, right: g, insideH: g, insideV: g };\n    }\n    case 'light-shading': {\n      const g = B('single', 'BFDBFE');\n      return { top: g, bottom: g, left: g, right: g, insideH: g, insideV: g };\n    }\n    case 'light-shading-accent': {\n      const g = B('single', 'BBF7D0');\n      return { top: g, bottom: g, left: g, right: g, insideH: g, insideV: g };\n    }\n  }\n\n  // Default editor table styling: 1px #d0d7de all around.\n  return all();\n}\n\n/** Per-cell fill resolved from the table-style preset, for cells that have\n *  no explicit `backgroundColor`. `rowIndex` is 0-based; `isHeader` marks\n *  header cells. Returns a hex (no '#') or null. */\nexport function presetCellFill(\n  model: TableModel,\n  isHeader: boolean,\n  rowIndex: number,\n): string | null {\n  switch (model.tableStyleId) {\n    case 'light-shading':\n      if (isHeader) return 'DBEAFE';\n      return rowIndex % 2 === 1 ? 'EFF6FF' : null;\n    case 'light-shading-accent':\n      if (isHeader) return 'DCFCE7';\n      return rowIndex % 2 === 1 ? 'F0FDF4' : null;\n    case 'medium-grid':\n      if (isHeader) return '1F2937';\n      return null;\n    case 'grid-light':\n      if (isHeader) return 'F3F4F6';\n      return null;\n    case 'plain':\n      return null;\n    default:\n      // Default editor styling: header row shaded light gray.\n      return isHeader ? 'F6F8FA' : null;\n  }\n}\n","/**\n * Page setup — size presets, custom dimensions, orientation, and margins.\n *\n * Framework-agnostic (no React import): `DocxEditor.setPageSetup()` in\n * `editor.ts` needs this data/logic directly, and `packages/editor/src/react/\n * document-structure.tsx`'s `PageSetupDialog` re-exports the types/presets\n * from here rather than defining its own copy.\n *\n * Margins are `marginX`/`marginY` (horizontal / vertical), not 4 independent\n * sides — the theme/CSS-var system (`--de-page-margin-x`/`-y`) only supports\n * symmetric margins, so this matches what can actually be applied.\n */\nimport { TWIPS_PER_PX } from './io/table-model';\n\nexport type PageSizePreset =\n  | 'letter'\n  | 'a4'\n  | 'legal'\n  | 'a3'\n  | 'a5'\n  | 'b5'\n  | 'executive'\n  | 'custom';\n\nexport interface PageSetup {\n  size: PageSizePreset;\n  orientation: 'portrait' | 'landscape';\n  /** Only used when `size === 'custom'`. Millimeters. */\n  customWidthMm?: number;\n  /** Only used when `size === 'custom'`. Millimeters. */\n  customHeightMm?: number;\n  /** Horizontal margin (left + right), inches. */\n  marginX: number;\n  /** Vertical margin (top + bottom), inches. */\n  marginY: number;\n}\n\nexport const PAGE_SIZE_PRESETS: Record<\n  Exclude<PageSizePreset, 'custom'>,\n  { label: string; width: string; height: string }\n> = {\n  letter: { label: 'Letter (8.5 x 11 in)', width: '816px', height: '1056px' },\n  a4: { label: 'A4 (210 x 297mm)', width: '794px', height: '1123px' },\n  legal: { label: 'Legal (8.5 x 14 in)', width: '816px', height: '1344px' },\n  a3: { label: 'A3 (297 x 420mm)', width: '1123px', height: '1587px' },\n  a5: { label: 'A5 (148 x 210mm)', width: '559px', height: '794px' },\n  b5: { label: 'B5 (176 x 250mm)', width: '666px', height: '945px' },\n  executive: { label: 'Executive (7.25 x 10.5 in)', width: '696px', height: '1008px' },\n};\n\nexport const DEFAULT_PAGE_SETUP: PageSetup = {\n  size: 'a4',\n  orientation: 'portrait',\n  marginX: 1,\n  marginY: 1,\n};\n\nexport function mmToPx(mm: number): number {\n  return (mm / 25.4) * 96;\n}\n\nexport function pxToMm(px: number): number {\n  return (px / 96) * 25.4;\n}\n\n/** Resolve a PageSetup into concrete pixel dimensions, honoring orientation swap. */\nexport function resolvePageDimensions(setup: PageSetup): { widthPx: number; heightPx: number } {\n  let widthPx: number;\n  let heightPx: number;\n  if (setup.size === 'custom') {\n    widthPx = mmToPx(setup.customWidthMm ?? 210);\n    heightPx = mmToPx(setup.customHeightMm ?? 297);\n  } else {\n    const preset = PAGE_SIZE_PRESETS[setup.size];\n    widthPx = parseInt(preset.width, 10);\n    heightPx = parseInt(preset.height, 10);\n  }\n  if (setup.orientation === 'landscape') {\n    [widthPx, heightPx] = [heightPx, widthPx];\n  }\n  return { widthPx, heightPx };\n}\n\n/** OOXML page size/margin dimensions, in twips (DXA — 1/1440 inch). */\nexport interface PageDimensionsTwips {\n  widthTwips: number;\n  heightTwips: number;\n  marginXTwips: number;\n  marginYTwips: number;\n}\n\nconst TWIPS_PER_INCH = 1440;\n\n/**\n * Resolve a PageSetup into OOXML twips, for `<w:pgSz>`/`<w:pgMar>` — used by\n * both `.docx` export paths (`io/save.ts`'s `docx`-library rebuild and\n * `io/ooxml-serializer.ts`'s raw-XML rebuild) so an exported file's page\n * size/margins always match what's shown on screen, instead of each save\n * path hardcoding its own default (previously: both silently exported US\n * Letter with 1in margins regardless of the live page setup).\n */\nexport function resolvePageDimensionsTwips(setup: PageSetup): PageDimensionsTwips {\n  const { widthPx, heightPx } = resolvePageDimensions(setup);\n  return {\n    widthTwips: Math.round(widthPx * TWIPS_PER_PX),\n    heightTwips: Math.round(heightPx * TWIPS_PER_PX),\n    marginXTwips: Math.round(setup.marginX * TWIPS_PER_INCH),\n    marginYTwips: Math.round(setup.marginY * TWIPS_PER_INCH),\n  };\n}\n\n/**\n * Real Word documents store \"true\" ISO/ANSI paper dimensions in twips\n * (e.g. A4 = 11906x16838), which differ by a few twips (<0.5mm) from this\n * app's own px-rounded presets run back through `resolvePageDimensionsTwips`\n * (e.g. A4 = 11910x16845) — this tolerance absorbs that drift without risking\n * misclassifying a genuinely different custom size as a preset.\n */\nconst PRESET_MATCH_TOLERANCE_TWIPS = 20;\n\nfunction closeEnough(a: number, b: number): boolean {\n  return Math.abs(a - b) <= PRESET_MATCH_TOLERANCE_TWIPS;\n}\n\n/**\n * Reverse of `resolvePageDimensionsTwips()`: given a page size/margin read\n * from a loaded .docx's `<w:sectPr>`, find the matching size preset +\n * orientation, or fall back to `'custom'` with the size expressed in mm —\n * so opening an existing A4/Legal/custom-size document restores the\n * editor's on-screen page setup to match, instead of resetting to whatever\n * the app's own default/last-used preference was.\n */\nexport function pageSetupFromTwips(pd: PageDimensionsTwips): PageSetup {\n  const marginX = Math.round((pd.marginXTwips / TWIPS_PER_INCH) * 100) / 100;\n  const marginY = Math.round((pd.marginYTwips / TWIPS_PER_INCH) * 100) / 100;\n\n  for (const size of Object.keys(PAGE_SIZE_PRESETS) as Array<Exclude<PageSizePreset, 'custom'>>) {\n    const preset = PAGE_SIZE_PRESETS[size];\n    const presetWidthTwips = Math.round(parseInt(preset.width, 10) * TWIPS_PER_PX);\n    const presetHeightTwips = Math.round(parseInt(preset.height, 10) * TWIPS_PER_PX);\n    if (closeEnough(pd.widthTwips, presetWidthTwips) && closeEnough(pd.heightTwips, presetHeightTwips)) {\n      return { size, orientation: 'portrait', marginX, marginY };\n    }\n    if (closeEnough(pd.widthTwips, presetHeightTwips) && closeEnough(pd.heightTwips, presetWidthTwips)) {\n      return { size, orientation: 'landscape', marginX, marginY };\n    }\n  }\n\n  return {\n    size: 'custom',\n    orientation: 'portrait',\n    customWidthMm: Math.round((pd.widthTwips / TWIPS_PER_INCH) * 25.4),\n    customHeightMm: Math.round((pd.heightTwips / TWIPS_PER_INCH) * 25.4),\n    marginX,\n    marginY,\n  };\n}\n","/**\n * OOXML Parser — parse word/document.xml directly into TipTap JSON.\n *\n * This replaces mammoth (which converts to lossy HTML) with a direct\n * XML → JSON converter that preserves:\n *   - Paragraph styles (Heading 1-6, Normal, Quote, Code)\n *   - Character formatting (bold, italic, underline, strike, color, font size, font family)\n *   - Text alignment (left, center, right, justify)\n *   - Line spacing\n *   - Tables (with cell content, borders, widths)\n *   - Lists (bullet, numbered with indentation)\n *   - Images (inline and floating, with dimensions)\n *   - Hyperlinks (with href)\n *   - Page breaks (w:br w:type=\"page\")\n *   - Bookmarks and internal links\n *\n * The parser reads the raw XML from the .docx ZIP, so it has access to\n * ALL formatting information — not just what mammoth chooses to expose.\n */\n\nimport { highlightNameToHex } from './ooxml-marks';\nimport { halfPointsToPx } from './ooxml-units';\nimport { TWIPS_PER_PX } from './table-model';\nimport { pageSetupFromTwips, type PageSetup } from '../page-setup';\n\n// Lazy-load JSZip\nlet JSZip: any = null;\nasync function getJSZip(): Promise<any> {\n  if (JSZip) return JSZip;\n  const mod = await import('jszip');\n  JSZip = mod.default || mod;\n  return JSZip;\n}\n\n/**\n * OOXML drawing units are EMUs (English Metric Units), 914400 per inch. At\n * the standard 96dpi CSS uses, that's 9525 EMU per pixel — the same constant\n * `ooxml-serializer.ts` uses when writing `<wp:extent>`, so a load → save\n * round-trip reproduces the original size (mod rounding) instead of drifting\n * through a second, slightly different ratio.\n */\nconst EMU_PER_PX = 9525;\n\n/**\n * Maps a media part's file extension to the MIME type its bytes need to be\n * tagged with in the `data:` URI the editor's image node expects as `src`.\n * The inverse of the serializer's `IMAGE_EXT_BY_MIME` (kept as its own local\n * table since that one isn't exported) — the two lists must still agree on\n * the same formats, or an image would parse on import but fail to decode on\n * the way back out.\n */\nconst MIME_BY_EXT: Record<string, string> = {\n  png: 'image/png',\n  jpg: 'image/jpeg',\n  jpeg: 'image/jpeg',\n  gif: 'image/gif',\n  bmp: 'image/bmp',\n  webp: 'image/webp',\n  svg: 'image/svg+xml',\n  tif: 'image/tiff',\n  tiff: 'image/tiff',\n  ico: 'image/x-icon',\n};\n\n/* -------------------------------------------------------------------------- */\n/* Types                                                                       */\n/* -------------------------------------------------------------------------- */\n\nexport interface ParsedOOXML {\n  /** TipTap JSON document (ready for editor.setJSON()). */\n  json: any;\n  /** Raw document.xml string (for selective save round-trip). */\n  documentXml: string;\n  /** Styles.xml parsed as a Map<styleId, StyleDef>. */\n  styles: Map<string, StyleDef>;\n  /** Document metadata from core.xml. */\n  metadata: DocxMetadata;\n  /** Any parsing warnings. */\n  warnings: string[];\n  /** Comment threads from word/comments.xml, keyed to the `comment` mark ids\n   *  in `json`. Seed a `CommentsStorageAdapter` with these after import. */\n  commentThreads: import('../comments-types').CommentThread[];\n  /** Header/footer content as plain HTML paragraphs (default type only, v1). */\n  headerHTML?: string;\n  footerHTML?: string;\n}\n\n/**\n * Raw `<w:ind>` attribute values in twips, before conversion to the editor's\n * px-based paragraph attrs. Kept in twips at this layer — on both a style\n * and a paragraph — so `resolveStyleIndent()` can hand back a style's whole\n * declared indentation unconverted, exactly mirroring how `ownNumId`/\n * `resolveStyleNumId()` handle numbering below.\n */\ninterface IndTwips {\n  left?: number;\n  right?: number;\n  firstLine?: number;\n  hanging?: number;\n}\n\n/** Read `<w:ind>`'s twips attributes — `w:left`/`w:start`, `w:right`/`w:end`,\n *  `w:firstLine`, `w:hanging` — or `undefined` if none of them are actually\n *  set (an empty `<w:ind/>` isn't meaningfully different from no element at\n *  all for callers deciding whether to fall back to a style's indentation). */\nfunction readIndAttrs(el: Element): IndTwips | undefined {\n  const left = parseInt(el.getAttribute('w:left') || el.getAttribute('w:start') || '', 10);\n  const right = parseInt(el.getAttribute('w:right') || el.getAttribute('w:end') || '', 10);\n  const firstLine = parseInt(el.getAttribute('w:firstLine') || '', 10);\n  const hanging = parseInt(el.getAttribute('w:hanging') || '', 10);\n  const out: IndTwips = {};\n  if (!isNaN(left) && left !== 0) out.left = left;\n  if (!isNaN(right) && right !== 0) out.right = right;\n  if (!isNaN(firstLine) && firstLine !== 0) out.firstLine = firstLine;\n  if (!isNaN(hanging) && hanging !== 0) out.hanging = hanging;\n  return Object.keys(out).length > 0 ? out : undefined;\n}\n\nexport interface StyleDef {\n  styleId: string;\n  name: string;\n  type: 'paragraph' | 'character' | 'table' | 'numbering';\n  basedOn?: string;\n  headingLevel?: number;\n  alignment?: string;\n  /** `w:default=\"1\"` — Word's fallback style for runs/paragraphs of this type. */\n  isDefault?: boolean;\n  /**\n   * `w:numId` declared on this style's `<w:pPr><w:numPr>`. Word lets a\n   * paragraph style (e.g. \"List Number\") carry the numbering, so a clause\n   * paragraph states only `<w:pStyle w:val=\"ListNumber\"/>` with no direct\n   * `numPr` — common in legal documents. Resolved via `resolveStyleNumId()`.\n   */\n  ownNumId?: string;\n  /**\n   * The run formatting declared directly on this style (`<w:style><w:rPr>`),\n   * BEFORE `basedOn` inheritance is resolved. Word applies formatting through\n   * named styles at least as often as through direct run properties, so a\n   * faithful import has to read this — not just the run's own `<w:rPr>` — and\n   * fold it into the effective formatting. See `resolveStyleRunProps()`.\n   */\n  ownRunProps?: RunProps;\n  /**\n   * `w:ind` declared directly on this style's `<w:pPr>` — the indentation\n   * equivalent of `ownNumId`. A legal-document paragraph style (\"Clause\",\n   * \"Sub-Clause\") very often carries its indentation this way rather than\n   * repeating `<w:ind>` on every paragraph, so resolving only a paragraph's\n   * own direct `<w:ind>` would leave most of a template's indentation\n   * unresolved. See `resolveStyleIndent()`.\n   */\n  ownIndent?: IndTwips;\n}\n\n/**\n * A resolved set of character-formatting properties, in the editor's own\n * units (css color/px/font-stack), independent of where in the OOXML style\n * cascade they came from. Toggle properties (bold/italic/…) are tri-state:\n * `true` = on, `false` = explicitly turned off (a lower-priority \"on\" must\n * not win), `undefined` = not specified at this level (inherit).\n */\nexport interface RunProps {\n  bold?: boolean;\n  italic?: boolean;\n  underline?: boolean;\n  strike?: boolean;\n  vertAlign?: 'superscript' | 'subscript';\n  color?: string;\n  fontSizePx?: string;\n  fontFamily?: string;\n  highlight?: string;\n}\n\n/** Latin typefaces from `theme1.xml`'s font scheme, for `w:*Theme` refs. */\ninterface ThemeFonts {\n  major?: string;\n  minor?: string;\n}\n\n/**\n * Everything the paragraph/run parsers need to resolve a run's *effective*\n * formatting: the style table, numbering, the document defaults, the theme\n * fonts, and a memo cache so a style's `basedOn` chain is only walked once.\n */\ninterface ParseCtx {\n  styles: Map<string, StyleDef>;\n  numberingMap: Map<string, NumberingInfo>;\n  docDefaults: RunProps;\n  themeFonts: ThemeFonts;\n  styleRunPropsCache: Map<string, RunProps>;\n  /**\n   * `document.xml.rels` relationship id → target. A hyperlink stores only an\n   * `r:id` (e.g. \"rId7\"); the real URL lives in the rels part. Without this,\n   * links import with `href=\"rId7\"` — a dead link.\n   */\n  relations: Map<string, string>;\n  /**\n   * The `w:default=\"1\"` paragraph/character style ids. Word applies these to\n   * any paragraph/run that names no explicit `w:pStyle`/`w:rStyle`, so a\n   * template that puts its body font on the `Normal` style (rather than in\n   * `docDefaults`) still resolves correctly. See eigenpal/docx-editor's\n   * `style-cascade.ts` — the same \"defaults → bases → style → direct\" order.\n   */\n  defaultParaStyleId?: string;\n  defaultCharStyleId?: string;\n  /**\n   * `word/media/*` part contents, pre-read as `data:` URIs and keyed by the\n   * path a relationship's `Target` names (e.g. \"media/image1.png\") — see\n   * `readMediaParts()`. Images are embedded as base64 in the editor's node\n   * `src`, and the DOM-based paragraph/run parsers below are synchronous, so\n   * this has to be resolved once, up front, rather than awaited per-image\n   * deep inside `parseRun()`.\n   */\n  media: Map<string, string>;\n  /**\n   * Shared with the top-level `warnings` array `parseDocxOOXML` returns, so\n   * a run whose image can't be resolved (dangling relationship, unreadable\n   * media part) can record *why* it was dropped instead of failing silently\n   * or throwing and aborting the whole import.\n   */\n  warnings: string[];\n}\n\nexport interface DocxMetadata {\n  title?: string;\n  creator?: string;\n  created?: string;\n  modified?: string;\n  subject?: string;\n  description?: string;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Main parse function                                                         */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Parse a .docx ArrayBuffer into TipTap JSON with high fidelity.\n *\n * Unlike mammoth (which converts to HTML), this parser reads the raw\n * OOXML XML and converts directly to TipTap's ProseMirror JSON format,\n * preserving all formatting attributes.\n *\n * @param buffer - .docx file as ArrayBuffer\n * @returns Parsed document with JSON, raw XML, styles, and metadata\n */\nexport async function parseDocxOOXML(buffer: ArrayBuffer): Promise<ParsedOOXML> {\n  const zip = await getJSZip();\n  const doc = await zip.loadAsync(buffer);\n  const warnings: string[] = [];\n\n  // 1. Read document.xml\n  const documentFile = doc.file('word/document.xml');\n  if (!documentFile) throw new Error('word/document.xml not found in .docx');\n  const documentXml = await documentFile.async('string');\n\n  // 2. Read theme1.xml for the font scheme (so `w:asciiTheme=\"minorHAnsi\"`\n  //    — how Word records the ubiquitous Calibri default and heading fonts —\n  //    resolves to a real typeface instead of being dropped).\n  const themeFile = doc.file('word/theme/theme1.xml');\n  const themeXml = themeFile ? await themeFile.async('string') : '';\n  const themeFonts = parseThemeFonts(themeXml);\n\n  // 3. Read styles.xml — capturing each style's own run properties, not just\n  //    its heading level/alignment, so style-based formatting can be resolved.\n  const stylesFile = doc.file('word/styles.xml');\n  const stylesXml = stylesFile ? await stylesFile.async('string') : '';\n  const styles = parseStylesXml(stylesXml, themeFonts);\n  const docDefaults = parseDocDefaults(stylesXml, themeFonts);\n\n  // 4. Read core.xml for metadata\n  const coreFile = doc.file('docProps/core.xml');\n  const coreXml = coreFile ? await coreFile.async('string') : '';\n  const metadata = parseCoreXml(coreXml);\n\n  // 5. Read numbering.xml for list definitions\n  const numberingFile = doc.file('word/numbering.xml');\n  const numberingXml = numberingFile ? await numberingFile.async('string') : '';\n  const numberingMap = parseNumberingXml(numberingXml);\n\n  // 5b. Read document.xml.rels so hyperlink `r:id`s resolve to real URLs.\n  const relsFile = doc.file('word/_rels/document.xml.rels');\n  const relsXml = relsFile ? await relsFile.async('string') : '';\n  const relations = parseRelationships(relsXml);\n\n  // 5c. Read every `word/media/*` binary part up front into `data:` URIs,\n  // keyed by the path relationships reference them by. Images are resolved\n  // deep inside the synchronous DOM paragraph/run parsers below, so this has\n  // to happen as a batch here rather than as an async read per `<w:drawing>`.\n  const media = await readMediaParts(doc, warnings);\n\n  // 6. Parse document.xml → TipTap JSON\n  let defaultParaStyleId: string | undefined;\n  let defaultCharStyleId: string | undefined;\n  for (const s of styles.values()) {\n    // \"Last wins\" among defaults of a type, matching Word (and how duplicate\n    // style ids resolve): don't break, let a later default overwrite.\n    if (s.isDefault && s.type === 'paragraph') defaultParaStyleId = s.styleId;\n    if (s.isDefault && s.type === 'character') defaultCharStyleId = s.styleId;\n  }\n\n  const ctx: ParseCtx = {\n    styles,\n    numberingMap,\n    docDefaults,\n    themeFonts,\n    styleRunPropsCache: new Map(),\n    relations,\n    defaultParaStyleId,\n    defaultCharStyleId,\n    media,\n    warnings,\n  };\n  const json = convertDocumentXmlToJson(documentXml, ctx, warnings);\n\n  // 7. Read word/comments.xml — thread content for the `comment` marks\n  // `convertDocumentXmlToJson` already anchored via w:commentRangeStart/End.\n  const commentsFile = doc.file('word/comments.xml');\n  const commentsXml = commentsFile ? await commentsFile.async('string') : '';\n  const commentThreads = buildCommentThreads(commentsXml, json);\n\n  // 8. Read the default header/footer parts, resolved via document.xml.rels\n  // from the sectPr's headerReference/footerReference. Plain-text paragraphs\n  // only (v1) — rich formatting inside a header/footer isn't round-tripped.\n  const headerHTML = await readHeaderFooterPart(doc, documentXml, relations, 'header');\n  const footerHTML = await readHeaderFooterPart(doc, documentXml, relations, 'footer');\n\n  return { json, documentXml, styles, metadata, warnings, commentThreads, headerHTML, footerHTML };\n}\n\n/** Reads the \"default\" header or footer part referenced from `<w:sectPr>`. */\nasync function readHeaderFooterPart(\n  doc: any,\n  documentXml: string,\n  relations: Map<string, string>,\n  kind: 'header' | 'footer',\n): Promise<string | undefined> {\n  const tag = kind === 'header' ? 'headerReference' : 'footerReference';\n  const re = new RegExp(`<w:${tag}[^>]*w:type=\"default\"[^>]*r:id=\"([^\"]+)\"`);\n  const match = re.exec(documentXml) ?? new RegExp(`<w:${tag}[^>]*r:id=\"([^\"]+)\"`).exec(documentXml);\n  if (!match) return undefined;\n  const target = relations.get(match[1]);\n  if (!target) return undefined;\n  const path = target.startsWith('word/') ? target : `word/${target.replace(/^\\.\\//, '')}`;\n  const file = doc.file(path);\n  if (!file) return undefined;\n  const xml = await file.async('string');\n  return headerFooterXmlToHTML(xml);\n}\n\n/** `<w:p>` runs → `<p>text</p>`, one per paragraph. Plain text only (v1). */\nfunction headerFooterXmlToHTML(xml: string): string | undefined {\n  if (typeof DOMParser === 'undefined') return '';\n  const doc = new DOMParser().parseFromString(xml, 'text/xml');\n  const paras = Array.from(doc.getElementsByTagName('w:p'));\n  const html = paras\n    .map((p) => {\n      const texts = Array.from(p.getElementsByTagName('w:t')).map((t) => t.textContent ?? '');\n      return `<p>${escapeHtml(texts.join(''))}</p>`;\n    })\n    .join('');\n  return html || undefined;\n}\n\nfunction escapeHtml(s: string): string {\n  return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n}\n\n/** Parses `<w:comment>` elements (id, author, date, text) from comments.xml. */\nfunction parseCommentsXml(xml: string): Array<{ id: string; author?: string; date?: string; text: string }> {\n  if (!xml) return [];\n  const doc = new DOMParser().parseFromString(xml, 'text/xml');\n  const comments = doc.getElementsByTagName('w:comment');\n  const result: Array<{ id: string; author?: string; date?: string; text: string }> = [];\n  for (let i = 0; i < comments.length; i++) {\n    const el = comments[i];\n    const id = el.getAttribute('w:id');\n    if (!id) continue;\n    const tNodes = el.getElementsByTagName('w:t');\n    let text = '';\n    for (let j = 0; j < tNodes.length; j++) text += tNodes[j].textContent || '';\n    result.push({\n      id,\n      author: el.getAttribute('w:author') || undefined,\n      date: el.getAttribute('w:date') || undefined,\n      text,\n    });\n  }\n  return result;\n}\n\n/** Text anchored under each comment id, walking the parsed TipTap JSON. */\nfunction extractCommentQuotes(json: any): Map<string, string> {\n  const quotes = new Map<string, string>();\n  const walk = (node: any) => {\n    if (!node) return;\n    if (node.type === 'text' && Array.isArray(node.marks)) {\n      for (const mark of node.marks) {\n        if (mark.type === 'comment' && mark.attrs?.id) {\n          quotes.set(mark.attrs.id, (quotes.get(mark.attrs.id) ?? '') + (node.text ?? ''));\n        }\n      }\n    }\n    if (Array.isArray(node.content)) node.content.forEach(walk);\n  };\n  walk(json);\n  return quotes;\n}\n\n/** Combines comments.xml content + in-doc anchors into loadable CommentThreads. */\nfunction buildCommentThreads(commentsXml: string, json: any): import('../comments-types').CommentThread[] {\n  const quotes = extractCommentQuotes(json);\n  return parseCommentsXml(commentsXml).map((c) => {\n    const date = c.date ?? new Date().toISOString();\n    return {\n      id: c.id,\n      quote: quotes.get(c.id) ?? '',\n      resolved: false,\n      createdAt: date,\n      messages: [\n        { id: `${c.id}-0`, author: c.author ?? 'Unknown', body: c.text, mentions: [], createdAt: date },\n      ],\n    };\n  });\n}\n\n/* -------------------------------------------------------------------------- */\n/* Page setup (size/orientation/margins)                                      */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Read just the page size/orientation/margins from a .docx's `<w:sectPr>` —\n * independent of (and cheaper than) full body-content parsing, so the\n * editor's on-screen page geometry can be restored to match what a loaded\n * file actually used regardless of whether `parseDocxOOXML()` or the\n * mammoth fallback ends up handling the body content.\n *\n * Returns `null` if the file has no readable `<w:sectPr>`/`<w:pgSz>` —\n * callers should leave the current page setup untouched in that case\n * rather than resetting it to a default.\n */\nexport async function readPageSetupFromDocx(buffer: ArrayBuffer): Promise<PageSetup | null> {\n  try {\n    const zip = await getJSZip();\n    const doc = await zip.loadAsync(buffer);\n    const documentFile = doc.file('word/document.xml');\n    if (!documentFile) return null;\n    const documentXml = await documentFile.async('string');\n    return parseSectPrPageSetup(documentXml);\n  } catch {\n    return null;\n  }\n}\n\nfunction parseSectPrPageSetup(documentXml: string): PageSetup | null {\n  if (typeof DOMParser === 'undefined') return null;\n  try {\n    const doc = new DOMParser().parseFromString(documentXml, 'text/xml');\n    const body = doc.getElementsByTagName('w:body')[0];\n    if (!body) return null;\n\n    // The body's own <w:sectPr> (document-level page setup) is a direct\n    // child, conventionally the last one — distinct from a mid-document\n    // section break's <w:p><w:pPr><w:sectPr> (not handled here; a\n    // multi-section document's editor-wide page setup uses this last one).\n    let sectPr: Element | null = null;\n    for (let i = 0; i < body.children.length; i++) {\n      const el = body.children[i];\n      const tag = el.localName || el.tagName.replace(/.*:/, '');\n      if (tag === 'sectPr') sectPr = el;\n    }\n    if (!sectPr) return null;\n\n    const pgSz = sectPr.getElementsByTagName('w:pgSz')[0];\n    if (!pgSz) return null;\n    const widthTwips = parseInt(pgSz.getAttribute('w:w') || '', 10);\n    const heightTwips = parseInt(pgSz.getAttribute('w:h') || '', 10);\n    if (!widthTwips || !heightTwips) return null;\n\n    const pgMar = sectPr.getElementsByTagName('w:pgMar')[0];\n    const marginXTwips = parseInt(pgMar?.getAttribute('w:left') || '', 10) || 1440;\n    const marginYTwips = parseInt(pgMar?.getAttribute('w:top') || '', 10) || 1440;\n\n    return pageSetupFromTwips({ widthTwips, heightTwips, marginXTwips, marginYTwips });\n  } catch {\n    return null;\n  }\n}\n\n/* -------------------------------------------------------------------------- */\n/* Styles parser                                                               */\n/* -------------------------------------------------------------------------- */\n\nfunction parseStylesXml(xml: string, themeFonts: ThemeFonts): Map<string, StyleDef> {\n  const styles = new Map<string, StyleDef>();\n  if (!xml || typeof DOMParser === 'undefined') return styles;\n\n  try {\n    const doc = new DOMParser().parseFromString(xml, 'text/xml');\n    const styleEls = doc.getElementsByTagName('w:style');\n    for (let i = 0; i < styleEls.length; i++) {\n      const el = styleEls[i];\n      const styleId = el.getAttribute('w:styleId') || '';\n      if (!styleId) continue;\n\n      const type = (el.getAttribute('w:type') || 'paragraph') as StyleDef['type'];\n      const isDefault = el.getAttribute('w:default') === '1' || el.getAttribute('w:default') === 'true';\n      const nameEl = el.getElementsByTagName('w:name')[0];\n      const name = nameEl?.getAttribute('w:val') || styleId;\n      const basedOnEl = el.getElementsByTagName('w:basedOn')[0];\n      const basedOn = basedOnEl?.getAttribute('w:val');\n\n      // Check if it's a heading style\n      let headingLevel: number | undefined;\n      if (styleId.toLowerCase().includes('heading') || name.toLowerCase().includes('heading')) {\n        const match = styleId.match(/heading(\\d)/i) || name.match(/heading\\s*(\\d)/i);\n        if (match) headingLevel = parseInt(match[1]);\n      }\n\n      // Check for alignment in pPr\n      const pPr = firstDirectChild(el, 'pPr');\n      let alignment: string | undefined;\n      if (pPr) {\n        const jc = firstDirectChild(pPr, 'jc');\n        if (jc) alignment = jc.getAttribute('w:val') || undefined;\n      }\n\n      // Capture the style's own run properties (`<w:style><w:rPr>`), the piece\n      // the old parser threw away. `basedOn` inheritance is resolved lazily\n      // later (resolveStyleRunProps) so the whole map is available first.\n      const rPr = firstDirectChild(el, 'rPr');\n      const ownRunProps = rPr ? parseRunPropsEl(rPr, themeFonts) : undefined;\n\n      // Numbering declared on the style itself (`<w:pPr><w:numPr><w:numId>`).\n      let ownNumId: string | undefined;\n      const styleNumPr = pPr ? firstDirectChild(pPr, 'numPr') : undefined;\n      if (styleNumPr) ownNumId = styleNumPr.getElementsByTagName('w:numId')[0]?.getAttribute('w:val') || undefined;\n\n      // Indentation declared on the style itself (`<w:pPr><w:ind>`) — see\n      // `resolveStyleIndent()` for why this needs the same capture as `ownNumId`.\n      const styleIndEl = pPr ? firstDirectChild(pPr, 'ind') : undefined;\n      const ownIndent = styleIndEl ? readIndAttrs(styleIndEl) : undefined;\n\n      styles.set(styleId, {\n        styleId,\n        name,\n        type,\n        basedOn: basedOn ?? undefined,\n        headingLevel,\n        alignment: alignment ?? undefined,\n        isDefault,\n        ownRunProps,\n        ownNumId,\n        ownIndent,\n      });\n    }\n  } catch (e) {\n    // Ignore parse errors\n  }\n\n  return styles;\n}\n\n/**\n * Resolve a style's *effective* run properties by walking its `basedOn`\n * chain (memoized). A derived style's own props override the ones it inherits.\n * A short cycle guard keeps a malformed `basedOn` loop from recursing forever.\n */\nfunction resolveStyleRunProps(styleId: string | undefined, ctx: ParseCtx, seen?: Set<string>): RunProps {\n  if (!styleId) return {};\n  const cached = ctx.styleRunPropsCache.get(styleId);\n  if (cached) return cached;\n  const style = ctx.styles.get(styleId);\n  if (!style) return {};\n  const guard = seen ?? new Set<string>();\n  if (guard.has(styleId)) return style.ownRunProps ?? {};\n  guard.add(styleId);\n  const base = style.basedOn ? resolveStyleRunProps(style.basedOn, ctx, guard) : {};\n  const merged = mergeRunProps(base, style.ownRunProps);\n  ctx.styleRunPropsCache.set(styleId, merged);\n  return merged;\n}\n\n/**\n * The `w:numId` a paragraph style contributes, walking its `basedOn` chain\n * (nearest definition wins). Lets a \"List Number\"-style paragraph with no\n * direct `numPr` still import as a real list — how legal clause numbering is\n * usually authored.\n */\nfunction resolveStyleNumId(styleId: string | undefined, ctx: ParseCtx, seen?: Set<string>): string | undefined {\n  if (!styleId) return undefined;\n  const style = ctx.styles.get(styleId);\n  if (!style) return undefined;\n  if (style.ownNumId) return style.ownNumId;\n  const guard = seen ?? new Set<string>();\n  if (guard.has(styleId)) return undefined;\n  guard.add(styleId);\n  return style.basedOn ? resolveStyleNumId(style.basedOn, ctx, guard) : undefined;\n}\n\n/**\n * The `w:ind` a paragraph style contributes, walking its `basedOn` chain the\n * same way `resolveStyleNumId` does (nearest definition wins) — but as a\n * whole-element override rather than a field-by-field merge: a style's own\n * `<w:ind>` is returned as-is instead of combined with an ancestor's,\n * matching how Word treats a directly declared `<w:ind>` as replacing the\n * inherited one rather than patching it.\n */\nfunction resolveStyleIndent(styleId: string | undefined, ctx: ParseCtx, seen?: Set<string>): IndTwips | undefined {\n  if (!styleId) return undefined;\n  const style = ctx.styles.get(styleId);\n  if (!style) return undefined;\n  if (style.ownIndent) return style.ownIndent;\n  const guard = seen ?? new Set<string>();\n  if (guard.has(styleId)) return undefined;\n  guard.add(styleId);\n  return style.basedOn ? resolveStyleIndent(style.basedOn, ctx, guard) : undefined;\n}\n\n/**\n * Later (higher-priority) props override earlier ones. Only keys the override\n * actually declares win — an `undefined` value inherits, so a bold paragraph\n * style isn't cancelled by a run that simply doesn't mention bold.\n */\nfunction mergeRunProps(base: RunProps, over: RunProps | undefined): RunProps {\n  if (!over) return { ...base };\n  const out: RunProps = { ...base };\n  for (const key of Object.keys(over) as (keyof RunProps)[]) {\n    const v = over[key];\n    if (v !== undefined) (out as any)[key] = v;\n  }\n  return out;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Numbering parser                                                            */\n/* -------------------------------------------------------------------------- */\n\nexport interface NumberingInfo {\n  numId: string;\n  format: 'bullet' | 'decimal' | 'lowerLetter' | 'upperLetter';\n}\n\n/**\n * Parse `word/numbering.xml` into a `numId -> {numId, format}` map.\n *\n * Exported so the serializer can reuse it too: when doing a selective save,\n * resolving a bullet/ordered list's `w:numId` from the *original* document's\n * actual numbering definitions (instead of hardcoding numId 1/2, which only\n * happens to be correct by convention) requires the same parsing this\n * function already does for loading.\n */\nexport function parseNumberingXml(xml: string): Map<string, NumberingInfo> {\n  const map = new Map<string, NumberingInfo>();\n  if (!xml || typeof DOMParser === 'undefined') return map;\n\n  try {\n    const doc = new DOMParser().parseFromString(xml, 'text/xml');\n    // Parse abstractNum elements to get format\n    const abstractNums = doc.getElementsByTagName('w:abstractNum');\n    const formatMap = new Map<string, string>();\n    for (let i = 0; i < abstractNums.length; i++) {\n      const abstractId = abstractNums[i].getAttribute('w:abstractNumId') || '';\n      const lvlEls = abstractNums[i].getElementsByTagName('w:lvl');\n      if (lvlEls.length > 0) {\n        const numFmt = lvlEls[0].getElementsByTagName('w:numFmt')[0];\n        const fmt = numFmt?.getAttribute('w:val') || 'bullet';\n        formatMap.set(abstractId, fmt);\n      }\n    }\n    // Parse num elements to map numId → abstractNumId\n    const nums = doc.getElementsByTagName('w:num');\n    for (let i = 0; i < nums.length; i++) {\n      const numId = nums[i].getAttribute('w:numId') || '';\n      const abstractRef = nums[i].getElementsByTagName('w:abstractNumId')[0];\n      const abstractId = abstractRef?.getAttribute('w:val') || '';\n      const fmt = formatMap.get(abstractId) || 'bullet';\n      map.set(numId, { numId, format: fmt as any });\n    }\n  } catch (e) {\n    // Ignore\n  }\n\n  return map;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Core XML metadata parser                                                    */\n/* -------------------------------------------------------------------------- */\n\nfunction parseCoreXml(xml: string): DocxMetadata {\n  if (!xml) return {};\n  const get = (tag: string): string | undefined => {\n    const match = xml.match(new RegExp(`<(?:cp|dc|dcterms|ep):${tag}[^>]*>([^<]*)<`));\n    return match?.[1]?.trim();\n  };\n  return {\n    title: get('title'),\n    creator: get('creator'),\n    created: get('created'),\n    modified: get('modified'),\n    subject: get('subject'),\n    description: get('description'),\n  };\n}\n\n/* -------------------------------------------------------------------------- */\n/* Document XML → TipTap JSON converter                                        */\n/* -------------------------------------------------------------------------- */\n\nfunction convertDocumentXmlToJson(\n  documentXml: string,\n  ctx: ParseCtx,\n  warnings: string[],\n): any {\n  if (typeof DOMParser === 'undefined') {\n    warnings.push('DOMParser not available — cannot parse OOXML');\n    return { type: 'doc', content: [{ type: 'paragraph' }] };\n  }\n\n  const doc = new DOMParser().parseFromString(documentXml, 'text/xml');\n  const body = doc.getElementsByTagName('w:body')[0];\n  if (!body) {\n    warnings.push('No <w:body> found in document.xml');\n    return { type: 'doc', content: [{ type: 'paragraph' }] };\n  }\n\n  const blocks: any[] = [];\n\n  // Iterate over children of body (w:p, w:tbl, w:sectPr)\n  for (let i = 0; i < body.children.length; i++) {\n    const el = body.children[i];\n    const tagName = el.localName || el.tagName.replace(/.*:/, '');\n\n    if (tagName === 'p') {\n      const block = parseParagraph(el as Element, ctx);\n      if (block) blocks.push(...(Array.isArray(block) ? block : [block]));\n    } else if (tagName === 'tbl') {\n      const block = parseTable(el as Element, ctx);\n      if (block) blocks.push(block);\n    } else if (tagName === 'sectPr') {\n      // Section properties — skip for now (would need section break support)\n    }\n  }\n\n  if (blocks.length === 0) {\n    blocks.push({ type: 'paragraph' });\n  }\n\n  return { type: 'doc', content: mergeAdjacentLists(blocks) };\n}\n\n/**\n * Each list paragraph is parsed into its own one-item list node. Left as-is,\n * consecutive items render as separate lists that each restart at \"1.\" — a\n * five-item numbered list would show \"1. 1. 1. 1. 1.\" instead of \"1.\"–\"5.\".\n * Merge runs of adjacent same-type list nodes into a single list so ordered\n * numbering is continuous and bullets share one list.\n */\nfunction mergeAdjacentLists(blocks: any[]): any[] {\n  const out: any[] = [];\n  for (const block of blocks) {\n    const prev = out[out.length - 1];\n    const isList = block?.type === 'bulletList' || block?.type === 'orderedList';\n    if (isList && prev?.type === block.type && Array.isArray(prev.content) && Array.isArray(block.content)) {\n      prev.content.push(...block.content);\n    } else {\n      out.push(block);\n    }\n  }\n  return out;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Paragraph parser                                                            */\n/* -------------------------------------------------------------------------- */\n\nfunction parseParagraph(\n  el: Element,\n  ctx: ParseCtx,\n): any | any[] | null {\n  const pPr = firstDirectChild(el, 'pPr');\n\n  // Extract paragraph style\n  let styleId: string | undefined;\n  let headingLevel: number | undefined;\n  let alignment: string | undefined;\n  let lineHeight: string | undefined;\n  let listInfo: { numId: string; format: 'bullet' | 'decimal' | 'lowerLetter' | 'upperLetter' } | undefined;\n  // Indentation (see the `<w:ind>` handling below): `indent` is the\n  // left/start margin, `textIndent` the first-line offset (negative =\n  // hanging), `indentRight` the right/end margin. `indent`/`textIndent`\n  // names match exactly what `paragraphPropParts()` in ooxml-serializer.ts\n  // already reads off these same paragraph attrs, so this closes the\n  // round-trip instead of inventing a second convention. `indentRight` is\n  // the one exception: the serializer has no `w:right` support today, so it\n  // parses but won't currently re-export — kept anyway so the JSON model\n  // doesn't silently discard it.\n  let indent: number | undefined;\n  let textIndent: number | undefined;\n  let indentRight: number | undefined;\n  let tabStops: Array<{ pos: number; val: string }> | undefined;\n\n  if (pPr) {\n    // pStyle\n    const pStyle = firstDirectChild(pPr, 'pStyle');\n    if (pStyle) {\n      styleId = pStyle.getAttribute('w:val') || undefined;\n      const style = styleId ? ctx.styles.get(styleId) : undefined;\n      if (style?.headingLevel) headingLevel = style.headingLevel;\n    }\n\n    // Alignment\n    const jc = firstDirectChild(pPr, 'jc');\n    if (jc) {\n      alignment = jc.getAttribute('w:val') || undefined;\n    }\n\n    // Line spacing\n    const spacing = firstDirectChild(pPr, 'spacing');\n    if (spacing) {\n      const line = spacing.getAttribute('w:line');\n      const lineRule = spacing.getAttribute('w:lineRule');\n      if (line && lineRule !== 'exact') {\n        // Convert twips to multiplier (240 = single)\n        const multiplier = parseInt(line) / 240;\n        lineHeight = String(multiplier);\n      }\n    }\n\n    // Numbering (lists) — direct `numPr` on the paragraph wins; otherwise fall\n    // back to numbering carried by the paragraph's style (legal clause styles).\n    const numPr = firstDirectChild(pPr, 'numPr');\n    let numId: string | undefined;\n    if (numPr) numId = numPr.getElementsByTagName('w:numId')[0]?.getAttribute('w:val') || undefined;\n    if (!numId) numId = resolveStyleNumId(styleId, ctx);\n    // `numId=\"0\"` is Word's explicit \"no numbering\" override — not a list.\n    if (numId && numId !== '0' && ctx.numberingMap.has(numId)) {\n      listInfo = ctx.numberingMap.get(numId);\n    }\n\n    // Indentation — a direct paragraph `<w:ind>` always wins outright over\n    // whatever the paragraph's style declares (an explicit element replaces\n    // the inherited one rather than merging field-by-field, matching Word).\n    // Only fall back to the style's `<w:ind>` when the paragraph names none\n    // at all; legal templates lean heavily on style-level indentation for\n    // numbered/sub-numbered clauses, so skipping this fallback would leave\n    // most of a template's indentation unresolved on import.\n    const indEl = firstDirectChild(pPr, 'ind');\n    const resolvedIndent = (indEl ? readIndAttrs(indEl) : undefined) ?? resolveStyleIndent(styleId, ctx);\n    if (resolvedIndent) {\n      if (resolvedIndent.left) indent = Math.round(resolvedIndent.left / TWIPS_PER_PX);\n      if (resolvedIndent.right) indentRight = Math.round(resolvedIndent.right / TWIPS_PER_PX);\n      // `w:hanging` and `w:firstLine` are mutually exclusive in OOXML and both\n      // map to the same `textIndent` attr (positive = first-line indent,\n      // negative = hanging) — mirrors paragraphPropParts()'s logic on the way\n      // back out.\n      if (resolvedIndent.hanging) textIndent = -Math.round(resolvedIndent.hanging / TWIPS_PER_PX);\n      else if (resolvedIndent.firstLine) textIndent = Math.round(resolvedIndent.firstLine / TWIPS_PER_PX);\n    }\n\n    // Tab stops (`<w:tabs><w:tab w:val=\"left|center|right|decimal|bar\" w:pos=\"…\"/></w:tabs>`).\n    const tabsEl = firstDirectChild(pPr, 'tabs');\n    if (tabsEl) {\n      const tabEls = tabsEl.getElementsByTagName('w:tab');\n      const stops: Array<{ pos: number; val: string }> = [];\n      for (let i = 0; i < tabEls.length; i++) {\n        const val = tabEls[i].getAttribute('w:val');\n        const pos = tabEls[i].getAttribute('w:pos');\n        if (val && val !== 'clear' && pos) stops.push({ pos: Math.round(Number(pos) / TWIPS_PER_PX), val });\n      }\n      if (stops.length > 0) tabStops = stops;\n    }\n  }\n\n  // The formatting a run in this paragraph inherits before its own rPr:\n  // document defaults → paragraph style (basedOn-resolved) → the paragraph\n  // mark's own run props (<w:pPr><w:rPr>). A run's <w:rStyle>/direct <w:rPr>\n  // layer on top of this inside parseRun. A paragraph naming no pStyle still\n  // inherits the document's default (`w:default=\"1\"`) paragraph style.\n  const effStyleId = styleId ?? ctx.defaultParaStyleId;\n  let paraBase = mergeRunProps(ctx.docDefaults, resolveStyleRunProps(effStyleId, ctx));\n  const pMarkRPr = pPr ? firstDirectChild(pPr, 'rPr') : undefined;\n  if (pMarkRPr) paraBase = mergeRunProps(paraBase, parseRunPropsEl(pMarkRPr, ctx.themeFonts));\n\n  // Extract runs. A run stream can contain inline page breaks (`<w:br\n  // w:type=\"page\">`) or images (`<w:drawing>`) — TipTap's image node is\n  // block-level (`DocxImage.configure({ inline: false })`), so like a page\n  // break it can't live inside a paragraph's own inline content. Split into\n  // text segments around BOTH so a paragraph holding text alongside a\n  // break/image keeps its text (a page break used to replace the whole\n  // paragraph wholesale — silent data loss — and an image run would have hit\n  // the same fate before `w:drawing` handling existed at all).\n  const runs = parseRuns(el, ctx, paraBase);\n  const segments: any[][] = [[]];\n  const interrupts: any[] = [];\n  for (const r of runs) {\n    if (r.type === 'pageBreak' || r.type === 'image') {\n      interrupts.push(r);\n      segments.push([]);\n    } else {\n      segments[segments.length - 1].push(r);\n    }\n  }\n  const breakCount = interrupts.length;\n  const contentRuns = runs.filter((r: any) => r.type !== 'pageBreak' && r.type !== 'image');\n  const content = contentRuns.length > 0 ? contentRuns : undefined;\n  const paraAttrs = {\n    ...(alignment ? { textAlign: alignment } : {}),\n    ...(lineHeight ? { lineHeight } : {}),\n    ...(indent !== undefined ? { indent } : {}),\n    ...(textIndent !== undefined ? { textIndent } : {}),\n    ...(indentRight !== undefined ? { indentRight } : {}),\n    ...(tabStops ? { tabStops } : {}),\n  };\n  // A page break or image inside a heading/list/quote is rare; keep the\n  // block's text and place the interrupt(s) after it rather than splitting\n  // those structures apart.\n  const withTrailingBreaks = (block: any) => (breakCount > 0 ? [block, ...interrupts] : block);\n\n  // Build the block node\n  if (headingLevel) {\n    return withTrailingBreaks({\n      type: 'heading',\n      attrs: { level: headingLevel, ...paraAttrs },\n      content,\n    });\n  }\n\n  if (listInfo) {\n    // Wrap as a list item — but TipTap expects list nodes at the top level,\n    // so we return a list node containing this as a listItem\n    const listType = listInfo.format === 'bullet' ? 'bulletList' : 'orderedList';\n    return withTrailingBreaks({\n      type: listType,\n      content: [\n        {\n          type: 'listItem',\n          content: [{ type: 'paragraph', attrs: paraAttrs, content }],\n        },\n      ],\n    });\n  }\n\n  // Check for blockquote style\n  if (styleId && (styleId.toLowerCase().includes('quote') || styleId.toLowerCase().includes('blockquote'))) {\n    return withTrailingBreaks({\n      type: 'blockquote',\n      content: [{ type: 'paragraph', content }],\n    });\n  }\n\n  // Check for code style\n  if (styleId && (styleId.toLowerCase().includes('code') || styleId.toLowerCase().includes('source'))) {\n    return withTrailingBreaks({\n      type: 'codeBlock',\n      content: content || [],\n    });\n  }\n\n  // Default: paragraph. Emit one paragraph per text segment with the\n  // interrupt(s) (page breaks/images) placed in their real position\n  // (before/between/after text) rather than moved to the end.\n  if (breakCount > 0) {\n    const blocks: any[] = [];\n    segments.forEach((seg, i) => {\n      if (i > 0) blocks.push(interrupts[i - 1]);\n      if (seg.length > 0) blocks.push({ type: 'paragraph', attrs: paraAttrs, content: seg });\n    });\n    return blocks.length > 0 ? blocks : interrupts[0];\n  }\n\n  return { type: 'paragraph', attrs: paraAttrs, content };\n}\n\n/* -------------------------------------------------------------------------- */\n/* Runs parser                                                                 */\n/* -------------------------------------------------------------------------- */\n\nfunction parseRuns(\n  paragraphEl: Element,\n  ctx: ParseCtx,\n  paraBase: RunProps,\n  activeComments: Set<string> = new Set(),\n  activeBookmarks: Set<string> = new Set(),\n): any[] {\n  const nodes: any[] = [];\n\n  // Iterate over children of paragraph\n  for (let i = 0; i < paragraphEl.children.length; i++) {\n    const child = paragraphEl.children[i];\n    const tag = child.localName || child.tagName.replace(/.*:/, '');\n\n    if (tag === 'r') {\n      const runNode = parseRun(child as Element, ctx, paraBase);\n      if (runNode) nodes.push(withRangeMarks(runNode, activeComments, activeBookmarks));\n    } else if (tag === 'hyperlink') {\n      // An external link stores an `r:id` pointing into document.xml.rels; an\n      // internal link stores a `w:anchor` (a bookmark name). Resolve the r:id\n      // to its real target so the href is a usable URL, not \"rId7\".\n      const rId = child.getAttribute('r:id');\n      const anchor = child.getAttribute('w:anchor');\n      const href = rId\n        ? ctx.relations.get(rId) || ''\n        : anchor\n          ? `#${anchor}`\n          : '';\n      const linkRuns = parseRuns(child as Element, ctx, paraBase, activeComments, activeBookmarks);\n      for (const run of linkRuns) {\n        if (run.type === 'text' && href) {\n          const marks = run.marks ?? [];\n          marks.push({ type: 'link', attrs: { href } });\n          nodes.push({ ...run, marks });\n        } else {\n          nodes.push(run);\n        }\n      }\n    } else if (tag === 'ins') {\n      // Tracked insertion: keep as real content, tagged with an `insertion` mark\n      // so Suggesting mode / redlines survive the round trip.\n      const author = child.getAttribute('w:author') || undefined;\n      const date = child.getAttribute('w:date') || undefined;\n      const id = child.getAttribute('w:id') || undefined;\n      // The recursive parseRuns() call already applied comment/bookmark\n      // marks (it shares those sets), so just layer the insertion mark on top.\n      for (const run of parseRuns(child as Element, ctx, paraBase, activeComments, activeBookmarks)) {\n        nodes.push(addTrackChangeMark(run, 'insertion', { id, author, date }));\n      }\n    } else if (tag === 'del') {\n      // Tracked deletion: keep the text (via `<w:delText>`, read by parseRun)\n      // tagged with a `deletion` mark instead of dropping it.\n      const author = child.getAttribute('w:author') || undefined;\n      const date = child.getAttribute('w:date') || undefined;\n      const id = child.getAttribute('w:id') || undefined;\n      for (const run of parseRuns(child as Element, ctx, paraBase, activeComments, activeBookmarks)) {\n        nodes.push(addTrackChangeMark(run, 'deletion', { id, author, date }));\n      }\n    } else if (tag === 'sdt') {\n      // Content control: <w:sdtPr> (tag/alias/id) + <w:sdtContent> (normal\n      // run-level children). Block-level sdt (wrapping paragraphs/tables) is\n      // not handled — v1 scope is inline placeholders only.\n      const sdtPr = firstDirectChild(child as Element, 'sdtPr');\n      const sdtContent = firstDirectChild(child as Element, 'sdtContent');\n      const ccTag = sdtPr ? firstDirectChild(sdtPr, 'tag')?.getAttribute('w:val') || undefined : undefined;\n      const alias = sdtPr ? firstDirectChild(sdtPr, 'alias')?.getAttribute('w:val') || undefined : undefined;\n      const ccId = sdtPr ? firstDirectChild(sdtPr, 'id')?.getAttribute('w:val') || undefined : undefined;\n      if (sdtContent) {\n        for (const run of parseRuns(sdtContent, ctx, paraBase, activeComments, activeBookmarks)) {\n          nodes.push(addContentControlMark(run, { id: ccId, tag: ccTag, alias }));\n        }\n      }\n    } else if (tag === 'fldSimple') {\n      // Simple field (PAGE, DATE, …): keep the cached display text, tagged\n      // with the instruction so it round-trips. Not recalculated.\n      const instr = child.getAttribute('w:instr') || undefined;\n      for (const run of parseRuns(child as Element, ctx, paraBase, activeComments, activeBookmarks)) {\n        nodes.push(addFieldMark(run, instr));\n      }\n    } else if (tag === 'commentRangeStart') {\n      // Marks the start of a Word comment anchor. Scoped to one paragraph —\n      // a comment spanning multiple paragraphs won't fully round-trip (v1).\n      const id = child.getAttribute('w:id');\n      if (id) activeComments.add(id);\n    } else if (tag === 'commentRangeEnd') {\n      const id = child.getAttribute('w:id');\n      if (id) activeComments.delete(id);\n    } else if (tag === 'bookmarkStart') {\n      const name = child.getAttribute('w:name');\n      if (name) activeBookmarks.add(name);\n    } else if (tag === 'bookmarkEnd') {\n      // w:bookmarkEnd carries the matching bookmarkStart's w:id, not its\n      // name, so there's nothing to remove by. activeBookmarks is scoped\n      // per-paragraph (a fresh Set each call from parseParagraph), so\n      // leaving the name active until the paragraph ends is an acceptable\n      // v1 simplification — most bookmarks span a single paragraph anyway.\n    }\n  }\n\n  return nodes;\n}\n\n// Adds `comment`/`bookmark` marks for every range currently open at this\n// point in the paragraph (usually zero or one each, but ranges can overlap).\nfunction withRangeMarks(node: any, activeComments: Set<string>, activeBookmarks: Set<string>): any {\n  if (!node || node.type !== 'text' || (activeComments.size === 0 && activeBookmarks.size === 0)) return node;\n  const marks = node.marks ?? [];\n  const commentMarks = [...activeComments].map((id) => ({ type: 'comment', attrs: { id } }));\n  const bookmarkMarks = [...activeBookmarks].map((name) => ({ type: 'bookmark', attrs: { name } }));\n  return { ...node, marks: [...marks, ...commentMarks, ...bookmarkMarks] };\n}\n\n// Tags a parsed run/image node with a `contentControl` mark (w:sdt import).\nfunction addContentControlMark(node: any, attrs: { id?: string; tag?: string; alias?: string }): any {\n  if (!node || node.type !== 'text') return node;\n  const marks = node.marks ?? [];\n  return { ...node, marks: [...marks, { type: 'contentControl', attrs }] };\n}\n\n// Tags a parsed run/image node with a `field` mark (w:fldSimple import).\nfunction addFieldMark(node: any, instr: string | undefined): any {\n  if (!node || node.type !== 'text' || !instr) return node;\n  const marks = node.marks ?? [];\n  return { ...node, marks: [...marks, { type: 'field', attrs: { instr } }] };\n}\n\n// Tags a parsed run/image node with a track-changes mark (`insertion` or\n// `deletion`). Non-text nodes (images, page breaks) get their marks array\n// too, so an image inserted while suggesting still round-trips.\nfunction addTrackChangeMark(\n  node: any,\n  type: 'insertion' | 'deletion',\n  attrs: { id?: string; author?: string; date?: string },\n): any {\n  if (!node || node.type !== 'text') return node;\n  const marks = node.marks ?? [];\n  return { ...node, marks: [...marks, { type, attrs }] };\n}\n\nfunction parseRun(el: Element, ctx: ParseCtx, paraBase: RunProps): any | null {\n  const rPr = firstDirectChild(el, 'rPr');\n\n  // Resolve the run's *effective* formatting through the full cascade:\n  //   paragraph base (docDefaults + paragraph style)\n  //   → character style referenced by <w:rStyle>\n  //   → the run's own direct <w:rPr>.\n  // The default character style (`w:default=\"1\"`, usually DefaultParagraphFont)\n  // sits under any explicit rStyle, which sits under the run's direct rPr.\n  let effective = mergeRunProps(paraBase, resolveStyleRunProps(ctx.defaultCharStyleId, ctx));\n  if (rPr) {\n    const rStyle = firstDirectChild(rPr, 'rStyle')?.getAttribute('w:val') || undefined;\n    if (rStyle) effective = mergeRunProps(effective, resolveStyleRunProps(rStyle, ctx));\n    effective = mergeRunProps(effective, parseRunPropsEl(rPr, ctx.themeFonts));\n  }\n  const marks: any[] = runPropsToMarks(effective);\n\n  // Extract text content from <w:t>/<w:br>/<w:tab>, and any embedded image\n  // from <w:drawing>. A run holds at most one of these in practice (Word\n  // never mixes a picture and literal text in the same <w:r>), so the first\n  // <w:drawing> found wins and short-circuits below, the same way a page\n  // break already does.\n  let text = '';\n  let hasPageBreak = false;\n  let imageNode: any = null;\n\n  for (let i = 0; i < el.children.length; i++) {\n    const child = el.children[i];\n    const tag = child.localName || child.tagName.replace(/.*:/, '');\n\n    if (tag === 't' || tag === 'delText') {\n      text += child.textContent || '';\n    } else if (tag === 'br') {\n      const type = child.getAttribute('w:type');\n      if (type === 'page') {\n        hasPageBreak = true;\n      } else {\n        text += '\\n';\n      }\n    } else if (tag === 'tab') {\n      text += '\\t';\n    } else if (tag === 'drawing') {\n      imageNode = imageNode ?? parseDrawing(child as Element, ctx);\n    }\n  }\n\n  if (imageNode) {\n    return imageNode;\n  }\n\n  if (hasPageBreak) {\n    return { type: 'pageBreak' };\n  }\n\n  if (!text) return null;\n\n  return {\n    type: 'text',\n    text,\n    marks: marks.length > 0 ? marks : undefined,\n  };\n}\n\n/**\n * Parse a `<w:drawing>` run child (the OOXML wrapper for an embedded\n * picture) into an `image` node matching `DocxImage`'s attrs (`src`,\n * `width`, `height`, `alt`) — see `extensions/builtins/docx-image.ts` and\n * the serializer's `imageRunXml()`, which this mirrors exactly so a\n * load → save round-trip is lossless.\n *\n * Handles both wrapper shapes the same way: `<wp:inline>` (flows with text)\n * and `<wp:anchor>` (floating/wrapped). `<wp:extent>` and the\n * `<a:blip r:embed=\"…\">` sit at the same relative position under either, and\n * this editor's image node has no floating-position model (no page-relative\n * offset, no wrap-around-text polygon) — so an anchored image imports as an\n * ordinary inline image rather than being dropped. That loses Word's exact\n * float position for that one picture, but the picture itself — and\n * everything else in the document — survives, which silently dropping it\n * would not.\n *\n * Never throws: a `<w:drawing>` with no raster image (a shape/SmartArt/chart)\n * returns `null` quietly, while a dangling `r:embed` or an unreadable media\n * part returns `null` AND records why in `ctx.warnings`, so the caller can\n * surface it instead of the image just silently vanishing.\n */\nfunction parseDrawing(drawingEl: Element, ctx: ParseCtx): any | null {\n  const blip = drawingEl.getElementsByTagName('a:blip')[0];\n  const relId = blip?.getAttribute('r:embed');\n  if (!relId) return null;\n\n  const target = ctx.relations.get(relId);\n  if (!target) {\n    ctx.warnings.push(`Image relationship \"${relId}\" has no matching entry in document.xml.rels — image dropped.`);\n    return null;\n  }\n\n  // Targets are stored relative to word/ (e.g. \"media/image1.png\"); strip a\n  // leading \"./\" some writers emit before looking it up in the media map.\n  const normalizedTarget = target.replace(/^\\.\\//, '');\n  const src = ctx.media.get(normalizedTarget);\n  if (!src) {\n    ctx.warnings.push(\n      `Image part \"${normalizedTarget}\" (relationship \"${relId}\") could not be read — image dropped.`,\n    );\n    return null;\n  }\n\n  const extentEl = drawingEl.getElementsByTagName('wp:extent')[0];\n  const cx = parseInt(extentEl?.getAttribute('cx') || '', 10);\n  const cy = parseInt(extentEl?.getAttribute('cy') || '', 10);\n\n  const attrs: any = { src };\n  if (!isNaN(cx) && cx > 0) attrs.width = `${Math.round(cx / EMU_PER_PX)}px`;\n  if (!isNaN(cy) && cy > 0) attrs.height = `${Math.round(cy / EMU_PER_PX)}px`;\n\n  const docPr = drawingEl.getElementsByTagName('wp:docPr')[0];\n  const alt = docPr?.getAttribute('descr') || docPr?.getAttribute('name');\n  if (alt) attrs.alt = alt;\n\n  return { type: 'image', attrs };\n}\n\n/* -------------------------------------------------------------------------- */\n/* Table parser                                                                */\n/* -------------------------------------------------------------------------- */\n\nfunction parseTable(\n  el: Element,\n  ctx: ParseCtx,\n): any | null {\n  const rows: any[] = [];\n  const trEls = el.getElementsByTagName('w:tr');\n\n  // Column widths from <w:tblGrid> (twips → px), used as a fallback for\n  // cells that don't carry their own <w:tcW>.\n  const gridColPx: number[] = [];\n  const tblGrid = el.getElementsByTagName('w:tblGrid')[0];\n  if (tblGrid && tblGrid.parentElement === el) {\n    const gridColEls = tblGrid.getElementsByTagName('w:gridCol');\n    for (let g = 0; g < gridColEls.length; g++) {\n      const w = parseInt(gridColEls[g].getAttribute('w:w') || '', 10);\n      gridColPx.push(isNaN(w) ? 0 : Math.round(w / TWIPS_PER_PX));\n    }\n  }\n\n  for (let i = 0; i < trEls.length; i++) {\n    const trEl = trEls[i];\n    // Make sure this tr is a direct child of the table (not nested)\n    if (trEl.parentElement !== el) continue;\n\n    const cells: any[] = [];\n    const tcEls = trEl.getElementsByTagName('w:tc');\n\n    let gridCol = 0;\n    for (let j = 0; j < tcEls.length; j++) {\n      const tcEl = tcEls[j];\n      if (tcEl.parentElement !== trEl) continue;\n\n      const tcPr = tcEl.getElementsByTagName('w:tcPr')[0];\n\n      // gridSpan → colspan\n      const gridSpanEl = tcPr?.getElementsByTagName('w:gridSpan')[0];\n      const colspan = Math.max(1, parseInt(gridSpanEl?.getAttribute('w:val') || '1', 10) || 1);\n\n      // vMerge: a bare <w:vMerge/> (or w:val=\"continue\") is a covered cell.\n      // ProseMirror represents merges by omitting covered cells and bumping\n      // the originating cell's rowspan, so skip continuation cells here and\n      // count them onto the originating cell above.\n      const vMergeEl = tcPr?.getElementsByTagName('w:vMerge')[0];\n      const vMergeVal = vMergeEl ? vMergeEl.getAttribute('w:val') || 'continue' : null;\n      if (vMergeEl && vMergeVal !== 'restart') {\n        for (let r = rows.length - 1; r >= 0; r--) {\n          const origin = rows[r].content.find((c: any) => c.attrs?._gridColStart === gridCol);\n          if (origin && origin.attrs) {\n            origin.attrs.rowspan = (origin.attrs.rowspan || 1) + 1;\n            break;\n          }\n        }\n        gridCol += colspan;\n        continue;\n      }\n\n      // Parse cell content (paragraphs)\n      const cellBlocks: any[] = [];\n      const pEls = tcEl.getElementsByTagName('w:p');\n      for (let k = 0; k < pEls.length; k++) {\n        const pEl = pEls[k];\n        if (pEl.parentElement !== tcEl) continue;\n        const block = parseParagraph(pEl, ctx);\n        if (block) {\n          // A page break inside a table cell can't become a top-level pageBreak\n          // node; keep only the real content blocks (paragraphs) here.\n          const arr = (Array.isArray(block) ? block : [block]).filter((b) => b.type !== 'pageBreak');\n          cellBlocks.push(...arr);\n        }\n      }\n\n      // Header cell?\n      const isHeader = !!tcPr?.getElementsByTagName('w:th').length;\n\n      // Cell width: prefer <w:tcW w:type=\"dxa\">, fall back to the grid.\n      const tcW = tcPr?.getElementsByTagName('w:tcW')[0];\n      const tcWType = tcW?.getAttribute('w:type');\n      const tcWVal = parseInt(tcW?.getAttribute('w:w') || '', 10);\n      const colwidth: number[] = [];\n      for (let c = 0; c < colspan; c++) {\n        if (c === 0 && tcWType === 'dxa' && !isNaN(tcWVal) && tcWVal > 0) {\n          colwidth.push(Math.round(tcWVal / TWIPS_PER_PX));\n        } else {\n          colwidth.push(gridColPx[gridCol + c] || 0);\n        }\n      }\n      const hasWidth = colwidth.some((w) => w > 0);\n\n      // Shading → backgroundColor\n      const shd = tcPr?.getElementsByTagName('w:shd')[0];\n      const fill = shd?.getAttribute('w:fill');\n      const backgroundColor = fill && /^[0-9a-fA-F]{6}$/.test(fill) && fill.toLowerCase() !== 'auto'\n        ? `#${fill}`\n        : null;\n\n      const attrs: any = { _gridColStart: gridCol };\n      if (colspan > 1) attrs.colspan = colspan;\n      if (hasWidth) attrs.colwidth = colwidth;\n      if (backgroundColor) attrs.backgroundColor = backgroundColor;\n\n      cells.push({\n        type: isHeader ? 'tableHeader' : 'tableCell',\n        attrs,\n        content: cellBlocks.length > 0 ? cellBlocks : [{ type: 'paragraph' }],\n      });\n\n      gridCol += colspan;\n    }\n\n    rows.push({\n      type: 'tableRow',\n      content: cells,\n      tableHeader: i === 0,\n    });\n  }\n\n  if (rows.length === 0) return null;\n\n  // Strip the internal `_gridColStart` bookkeeping attr now that vMerge\n  // resolution is done, and drop any now-empty attrs objects.\n  for (const row of rows) {\n    for (const cell of row.content) {\n      if (cell.attrs) {\n        delete cell.attrs._gridColStart;\n        if (Object.keys(cell.attrs).length === 0) delete cell.attrs;\n      }\n    }\n  }\n\n  // Table-level: alignment (<w:jc>) and explicit width (<w:tblW w:type=\"dxa\">).\n  const tblPr = el.getElementsByTagName('w:tblPr')[0];\n  const tableAttrs: any = {};\n  if (tblPr && tblPr.parentElement === el) {\n    const jc = tblPr.getElementsByTagName('w:jc')[0];\n    const jcVal = jc?.getAttribute('w:val');\n    if (jcVal === 'center' || jcVal === 'right' || jcVal === 'left') tableAttrs.tableAlign = jcVal;\n    const tblW = tblPr.getElementsByTagName('w:tblW')[0];\n    if (tblW?.getAttribute('w:type') === 'dxa') {\n      const w = parseInt(tblW.getAttribute('w:w') || '', 10);\n      if (!isNaN(w) && w > 0) tableAttrs.tableWidth = `${Math.round(w / TWIPS_PER_PX)}px`;\n    }\n  }\n\n  return {\n    type: 'table',\n    ...(Object.keys(tableAttrs).length ? { attrs: tableAttrs } : {}),\n    content: rows,\n  };\n}\n\n/* -------------------------------------------------------------------------- */\n/* Run-property parsing + style cascade                                        */\n/* -------------------------------------------------------------------------- */\n\n/** First direct child of `el` with the given local name (namespace-agnostic). */\nfunction firstDirectChild(el: Element, localName: string): Element | undefined {\n  for (let i = 0; i < el.children.length; i++) {\n    const c = el.children[i];\n    const tag = c.localName || c.tagName.replace(/.*:/, '');\n    if (tag === localName) return c;\n  }\n  return undefined;\n}\n\n/** An OOXML on/off toggle element → tri-state. Absent = `undefined` (inherit). */\nfunction toggle(el: Element | undefined): boolean | undefined {\n  if (!el) return undefined;\n  const v = el.getAttribute('w:val');\n  if (v == null) return true;\n  return !(v === '0' || v === 'false' || v === 'off' || v === 'no');\n}\n\n/**\n * Parse an `<w:rPr>` element into editor-space {@link RunProps}. Used for both\n * a run's own direct formatting and a style's declared formatting, so the two\n * merge on equal footing in the cascade.\n */\nfunction parseRunPropsEl(rPr: Element, themeFonts: ThemeFonts): RunProps {\n  const props: RunProps = {};\n\n  props.bold = toggle(rPr.getElementsByTagName('w:b')[0]);\n  props.italic = toggle(rPr.getElementsByTagName('w:i')[0]);\n\n  // Underline: `w:val=\"none\"` explicitly turns it off; any other value is on.\n  const uEl = rPr.getElementsByTagName('w:u')[0];\n  if (uEl) {\n    const v = uEl.getAttribute('w:val');\n    props.underline = v !== 'none';\n  }\n\n  // Strike / double-strike both map to the single strike mark.\n  const strikeEl = rPr.getElementsByTagName('w:strike')[0];\n  const dstrikeEl = rPr.getElementsByTagName('w:dstrike')[0];\n  const strike = toggle(strikeEl);\n  const dstrike = toggle(dstrikeEl);\n  if (strike !== undefined || dstrike !== undefined) {\n    props.strike = strike === true || dstrike === true;\n  }\n\n  const vertAlign = rPr.getElementsByTagName('w:vertAlign')[0];\n  if (vertAlign) {\n    const val = vertAlign.getAttribute('w:val');\n    if (val === 'superscript' || val === 'subscript') props.vertAlign = val;\n    else if (val === 'baseline') props.vertAlign = undefined;\n  }\n\n  const colorEl = rPr.getElementsByTagName('w:color')[0];\n  if (colorEl) {\n    const color = colorEl.getAttribute('w:val');\n    if (color && color !== 'auto' && /^[0-9a-fA-F]{6}$/.test(color)) {\n      props.color = `#${color}`;\n    }\n  }\n\n  const szEl = rPr.getElementsByTagName('w:sz')[0];\n  if (szEl) {\n    const halfPoints = parseInt(szEl.getAttribute('w:val') || '0', 10);\n    if (halfPoints > 0) props.fontSizePx = `${halfPointsToPx(halfPoints)}px`;\n  }\n\n  const rFonts = rPr.getElementsByTagName('w:rFonts')[0];\n  if (rFonts) {\n    const font = resolveRFont(rFonts, themeFonts);\n    if (font) props.fontFamily = `${font}, sans-serif`;\n  }\n\n  const highlightEl = rPr.getElementsByTagName('w:highlight')[0];\n  if (highlightEl) {\n    const color = highlightEl.getAttribute('w:val');\n    if (color && color !== 'none') props.highlight = highlightNameToHex(color);\n  }\n\n  return props;\n}\n\n/**\n * A real typeface name from `<w:rFonts>`: an explicit `w:ascii` wins, else the\n * `w:asciiTheme` reference (`minor*`/`major*`) is resolved against the theme's\n * font scheme. Word records the near-universal Calibri body font and its\n * heading font only as theme refs, so without this they'd import as no font.\n */\nfunction resolveRFont(rFonts: Element, themeFonts: ThemeFonts): string | undefined {\n  const explicit = rFonts.getAttribute('w:ascii') || rFonts.getAttribute('w:hAnsi');\n  if (explicit) return explicit;\n  const theme = rFonts.getAttribute('w:asciiTheme') || rFonts.getAttribute('w:hAnsiTheme');\n  if (theme) {\n    if (theme.startsWith('major')) return themeFonts.major;\n    if (theme.startsWith('minor')) return themeFonts.minor;\n  }\n  return undefined;\n}\n\n/** {@link RunProps} → TipTap marks, mirroring the serializer's mark → OOXML. */\nfunction runPropsToMarks(props: RunProps): any[] {\n  const marks: any[] = [];\n  if (props.bold) marks.push({ type: 'bold' });\n  if (props.italic) marks.push({ type: 'italic' });\n  if (props.underline) marks.push({ type: 'underline' });\n  if (props.strike) marks.push({ type: 'strike' });\n  if (props.vertAlign === 'superscript') marks.push({ type: 'superscript' });\n  else if (props.vertAlign === 'subscript') marks.push({ type: 'subscript' });\n\n  const textStyle: any = {};\n  if (props.color) textStyle.color = props.color;\n  if (props.fontSizePx) textStyle.fontSize = props.fontSizePx;\n  if (props.fontFamily) textStyle.fontFamily = props.fontFamily;\n  if (Object.keys(textStyle).length > 0) marks.push({ type: 'textStyle', attrs: textStyle });\n\n  if (props.highlight) marks.push({ type: 'highlight', attrs: { color: props.highlight } });\n  return marks;\n}\n\n/** Parse `<w:docDefaults><w:rPrDefault>` — the root of the formatting cascade. */\nfunction parseDocDefaults(stylesXml: string, themeFonts: ThemeFonts): RunProps {\n  if (!stylesXml || typeof DOMParser === 'undefined') return {};\n  try {\n    const doc = new DOMParser().parseFromString(stylesXml, 'text/xml');\n    const rPrDefault = doc.getElementsByTagName('w:rPrDefault')[0];\n    const rPr = rPrDefault ? firstDirectChild(rPrDefault, 'rPr') : undefined;\n    return rPr ? parseRunPropsEl(rPr, themeFonts) : {};\n  } catch {\n    return {};\n  }\n}\n\n/** Parse `word/_rels/document.xml.rels` → `relationshipId -> target` map. */\nfunction parseRelationships(relsXml: string): Map<string, string> {\n  const map = new Map<string, string>();\n  if (!relsXml || typeof DOMParser === 'undefined') return map;\n  try {\n    const doc = new DOMParser().parseFromString(relsXml, 'text/xml');\n    const rels = doc.getElementsByTagName('Relationship');\n    for (let i = 0; i < rels.length; i++) {\n      const id = rels[i].getAttribute('Id');\n      const target = rels[i].getAttribute('Target');\n      if (id && target) map.set(id, target);\n    }\n  } catch {\n    // Ignore\n  }\n  return map;\n}\n\n/**\n * Read every part under `word/media/` into a `data:` URI, keyed by the path\n * relative to `word/` (e.g. \"media/image1.png\") — the same string a\n * relationship's `Target` attribute names, so resolving an `r:embed` is a\n * single map lookup. Reading these eagerly (rather than lazily per image)\n * keeps the rest of the parse synchronous, since the DOMParser-based\n * paragraph/run walk below has no natural place to `await` a per-element\n * zip read.\n *\n * An unsupported binary type (anything not in `MIME_BY_EXT` — e.g. a legacy\n * WMF/EMF vector image Word sometimes embeds) is skipped rather than guessed\n * at; the run referencing it will warn and drop, same as an unresolvable\n * relationship.\n */\nasync function readMediaParts(doc: any, warnings: string[]): Promise<Map<string, string>> {\n  const map = new Map<string, string>();\n  const files = doc.files as Record<string, any>;\n  for (const path of Object.keys(files ?? {})) {\n    const match = /^word\\/(media\\/[^/]+)$/.exec(path);\n    if (!match) continue;\n    const relPath = match[1];\n    const ext = relPath.split('.').pop()?.toLowerCase() || '';\n    const mime = MIME_BY_EXT[ext];\n    if (!mime) continue;\n    try {\n      const base64 = await files[path].async('base64');\n      map.set(relPath, `data:${mime};base64,${base64}`);\n    } catch {\n      warnings.push(`Could not read image part \"${relPath}\".`);\n    }\n  }\n  return map;\n}\n\n/** Parse the latin major/minor typefaces from `word/theme/theme1.xml`. */\nfunction parseThemeFonts(themeXml: string): ThemeFonts {\n  if (!themeXml || typeof DOMParser === 'undefined') return {};\n  try {\n    const doc = new DOMParser().parseFromString(themeXml, 'text/xml');\n    const read = (tag: string): string | undefined => {\n      const scheme = doc.getElementsByTagName(tag)[0];\n      const latin = scheme?.getElementsByTagName('a:latin')[0];\n      const face = latin?.getAttribute('typeface');\n      return face && face !== '+mn-lt' && face !== '+mj-lt' ? face : undefined;\n    };\n    return { major: read('a:majorFont'), minor: read('a:minorFont') };\n  } catch {\n    return {};\n  }\n}\n\n/* -------------------------------------------------------------------------- */\n/* Helpers                                                                     */\n/* -------------------------------------------------------------------------- */\n\n// Highlight color mapping lives in `./ooxml-marks` — shared with the\n// serializer so the two directions can't drift out of sync (see that\n// file's docstring for why this used to silently corrupt round-trips).\n","/**\n * Theme tokens for the editor. All tokens are CSS custom properties, so users\n * can override them at runtime by setting them on a parent element.\n *\n * The default values match a Word/Google-Docs style page (A4, 1\" margins,\n * 11pt body text). See `page-setup.ts` for the higher-level `PageSetup` API\n * (size presets, custom dimensions, orientation) that resolves into these\n * `pageWidth`/`pageHeight`/`pageMarginX`/`pageMarginY` fields.\n */\nexport interface DocxEditorTheme {\n  /** Page background (the gray area around the page). */\n  background?: string;\n  /** Default text color on the page. */\n  text?: string;\n  /** Accent color for selection, active toolbar button, link underline. */\n  accent?: string;\n  /** Border color for tables, blockquote borders, hr, etc. */\n  border?: string;\n  /** Font family for body text. */\n  fontFamily?: string;\n  /** Font size for body text (any CSS length, e.g. \"11pt\" or \"14px\"). */\n  fontSize?: string;\n  /** Page width (in any CSS length, e.g. \"816px\" or \"21cm\"). */\n  pageWidth?: string;\n  /** Page height (any CSS length). */\n  pageHeight?: string;\n  /** Page horizontal margin (any CSS length, e.g. \"96px\" = 1in). */\n  pageMarginX?: string;\n  /** Page vertical margin. */\n  pageMarginY?: string;\n  /** Gap between pages when multi-page. */\n  pageGap?: string;\n  /** Line height. */\n  lineHeight?: number | string;\n}\n\n/**\n * Font stacks for non-Latin script rendering (Phase 6 multi-language\n * scaffold — see `@shashimadushan/docx-editor-legal-templates`'s\n * `titleSi`/`titleTa`/`labelSi`/`labelTa` fields). Pass one of these as\n * `theme.fontFamily` when displaying/editing a Sinhala or Tamil document —\n * `fontFamily` is a plain CSS custom property, so no editor code change is\n * needed to switch scripts, only a font stack + (if the host page doesn't\n * already load the web font) a `@font-face`/Google Fonts `<link>` for\n * \"Noto Sans Sinhala\" / \"Noto Sans Tamil\".\n */\nexport const SINHALA_FONT_STACK =\n  '\"Noto Sans Sinhala\", \"Iskoola Pota\", \"Nirmala UI\", sans-serif';\nexport const TAMIL_FONT_STACK =\n  '\"Noto Sans Tamil\", \"Latha\", \"Nirmala UI\", sans-serif';\n\nexport const defaultTheme: Required<DocxEditorTheme> = {\n  background: '#f1f5f9',\n  text: '#1f2328',\n  accent: '#2563eb',\n  border: '#d0d7de',\n  fontFamily:\n    '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif',\n  fontSize: '11pt',\n  pageWidth: '794px',\n  pageHeight: '1123px',\n  pageMarginX: '96px',\n  pageMarginY: '96px',\n  pageGap: '24px',\n  lineHeight: 1.5,\n};\n\n/**\n * Convert a theme object into a `style` string of CSS custom properties\n * applied to the editor host element.\n */\nexport function themeToCSSVars(theme: DocxEditorTheme): string {\n  const t = { ...defaultTheme, ...theme };\n  const vars: string[] = [];\n  vars.push(`--de-surface: ${t.background === '#f1f5f9' ? '#fff' : t.background}`);\n  vars.push(`--de-text: ${t.text}`);\n  vars.push(`--de-accent: ${t.accent}`);\n  vars.push(`--de-border-raw: ${t.border}`);\n  vars.push(`--de-font-family: ${t.fontFamily}`);\n  vars.push(`--de-font-size: ${t.fontSize}`);\n  vars.push(`--de-line-height: ${t.lineHeight}`);\n  vars.push(`--de-page-width: ${t.pageWidth}`);\n  vars.push(`--de-page-height: ${t.pageHeight}`);\n  vars.push(`--de-page-margin-x: ${t.pageMarginX}`);\n  vars.push(`--de-page-margin-y: ${t.pageMarginY}`);\n  vars.push(`--de-page-gap: ${t.pageGap}`);\n  return vars.join('; ');\n}\n\n/**\n * Convert a CSS length (as accepted by `DocxEditorTheme.pageWidth`/\n * `pageHeight` — px, in, cm, mm, pt, pc, or a bare number treated as px)\n * into inches, for contexts that need a plain number: `@page { size: ... }`\n * can't reliably read CSS custom properties, so `DocxEditor.printToPdf()`\n * needs the page size as a literal `Nin` value instead of `var(...)`.\n */\nexport function cssLengthToInches(value: string | number): number {\n  if (typeof value === 'number') return value / 96;\n  const match = /^\\s*([\\d.]+)\\s*(px|in|cm|mm|q|pt|pc)?\\s*$/i.exec(value);\n  if (!match) return 8.5; // fallback: US Letter width\n  const num = parseFloat(match[1]);\n  const unit = (match[2] ?? 'px').toLowerCase();\n  switch (unit) {\n    case 'in':\n      return num;\n    case 'cm':\n      return num / 2.54;\n    case 'mm':\n      return num / 25.4;\n    case 'q':\n      return num / 101.6;\n    case 'pt':\n      return num / 72;\n    case 'pc':\n      return num / 6;\n    case 'px':\n    default:\n      return num / 96;\n  }\n}\n","/**\n * Builds a complete, minimal .docx package around body XML produced by\n * `serializeTipTapToOOXML`.\n *\n * Why this exists: saving a document that was *opened* from a .docx patches\n * the original package, so it keeps that file's `styles.xml`, `numbering.xml`\n * and theme. A document created in the editor has no original package, and\n * the old fallback rebuilt it with the `docx` library — which writes its own\n * defaults (Calibri 11pt body, Word's blue Calibri Light headings, no\n * numbering definitions, no notion of the editor's theme). The exported file\n * therefore looked nothing like what was on screen.\n *\n * The fix is the approach every OOXML-first editor takes (ONLYOFFICE,\n * SuperDoc, docx4js and friends): emit the document part *and* the style\n * parts yourself, generating `styles.xml` from the same typography the editor\n * renders with, so \"what you see\" and \"what Word opens\" are driven by one\n * source of truth. Word resolves formatting through `docDefaults` → named\n * style → direct formatting; the serializer already emits direct formatting\n * for anything the user explicitly set, so this file only has to make the\n * *defaults* match the editor's stylesheet.\n */\n\nimport { ImageCollector } from './ooxml-serializer';\nimport { defaultTheme, type DocxEditorTheme } from '../theme';\nimport type { CommentThread } from '../comments-types';\n\nconst XML_DECL = '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>';\nconst W_NS = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';\nconst R_NS = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships';\n\nexport interface FreshDocxPackageOptions {\n  /** `<w:body>…</w:body>` from `serializeTipTapToOOXML`. */\n  bodyXml: string;\n  /** Images/hyperlinks collected while serializing that body. */\n  collector?: ImageCollector;\n  /** The live editor theme — drives `styles.xml`'s document defaults. */\n  theme?: DocxEditorTheme;\n  title?: string;\n  creator?: string;\n  /** Comment threads to write to word/comments.xml. Only the ids referenced\n   *  by `bodyXml`'s w:commentReference runs matter; extras are harmless. */\n  commentThreads?: CommentThread[];\n  /** Header/footer HTML (plain paragraphs, v1 — see `bodyXml`'s own\n   *  `hasHeader`/`hasFooter` reference in `serializeTipTapToOOXML`). */\n  headerHTML?: string;\n  footerHTML?: string;\n}\n\n/** Build a `.docx` (as an ArrayBuffer) from serialized body XML. */\nexport async function buildFreshDocxPackage(options: FreshDocxPackageOptions): Promise<ArrayBuffer> {\n  const { bodyXml, collector, theme, title, creator, commentThreads, headerHTML, footerHTML } = options;\n  const JSZip = (await import('jszip')).default;\n  const zip = new JSZip();\n  const images = collector?.images ?? [];\n  const links = collector?.links ?? [];\n  const hasComments = !!commentThreads?.length;\n  const hasHeader = !!headerHTML;\n  const hasFooter = !!footerHTML;\n\n  zip.file(\n    '[Content_Types].xml',\n    contentTypesXml(images.map((i) => ({ ext: extOf(i.fileName), type: i.contentType })), hasComments, hasHeader, hasFooter),\n  );\n  zip.file('_rels/.rels', rootRelsXml());\n  zip.file('docProps/core.xml', coreXml(title, creator));\n  zip.file('docProps/app.xml', appXml());\n  zip.file('word/document.xml', documentXml(bodyXml));\n  zip.file('word/_rels/document.xml.rels', documentRelsXml(images, links, hasComments, hasHeader, hasFooter));\n  zip.file('word/styles.xml', stylesXml(theme));\n  zip.file('word/numbering.xml', numberingXml());\n  if (hasComments) zip.file('word/comments.xml', commentsXml(commentThreads!));\n  if (hasHeader) zip.file('word/header1.xml', headerFooterXml('hdr', headerHTML!));\n  if (hasFooter) zip.file('word/footer1.xml', headerFooterXml('ftr', footerHTML!));\n  for (const img of images) zip.file(`word/media/${img.fileName}`, img.bytes);\n\n  return zip.generateAsync({ type: 'arraybuffer', compression: 'DEFLATE', compressionOptions: { level: 6 } });\n}\n\nfunction extOf(fileName: string): string {\n  return fileName.split('.').pop() ?? 'png';\n}\n\nfunction documentXml(bodyXml: string): string {\n  // Every namespace prefix the serializer can emit is declared here, since\n  // this string is written straight into the zip with no ambient context.\n  return (\n    XML_DECL +\n    `<w:document xmlns:w=\"${W_NS}\" xmlns:r=\"${R_NS}\"` +\n    ' xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"' +\n    ' xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"' +\n    ' xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">' +\n    bodyXml +\n    '</w:document>'\n  );\n}\n\nfunction contentTypesXml(\n  imageTypes: { ext: string; type: string }[],\n  hasComments = false,\n  hasHeader = false,\n  hasFooter = false,\n): string {\n  const seen = new Set<string>();\n  const defaults = imageTypes\n    .filter((t) => (seen.has(t.ext) ? false : (seen.add(t.ext), true)))\n    .map((t) => `<Default Extension=\"${t.ext}\" ContentType=\"${t.type}\"/>`)\n    .join('');\n  const commentsOverride = hasComments\n    ? '<Override PartName=\"/word/comments.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml\"/>'\n    : '';\n  const headerOverride = hasHeader\n    ? '<Override PartName=\"/word/header1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml\"/>'\n    : '';\n  const footerOverride = hasFooter\n    ? '<Override PartName=\"/word/footer1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml\"/>'\n    : '';\n  return (\n    XML_DECL +\n    '<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">' +\n    '<Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>' +\n    '<Default Extension=\"xml\" ContentType=\"application/xml\"/>' +\n    defaults +\n    '<Override PartName=\"/word/document.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\"/>' +\n    '<Override PartName=\"/word/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml\"/>' +\n    '<Override PartName=\"/word/numbering.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml\"/>' +\n    commentsOverride +\n    headerOverride +\n    footerOverride +\n    '<Override PartName=\"/docProps/core.xml\" ContentType=\"application/vnd.openxmlformats-package.core-properties+xml\"/>' +\n    '<Override PartName=\"/docProps/app.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.extended-properties+xml\"/>' +\n    '</Types>'\n  );\n}\n\nfunction rootRelsXml(): string {\n  return (\n    XML_DECL +\n    '<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">' +\n    `<Relationship Id=\"rIdDoc\" Type=\"${R_NS}/officeDocument\" Target=\"word/document.xml\"/>` +\n    '<Relationship Id=\"rIdCore\" Type=\"http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties\" Target=\"docProps/core.xml\"/>' +\n    `<Relationship Id=\"rIdApp\" Type=\"${R_NS}/extended-properties\" Target=\"docProps/app.xml\"/>` +\n    '</Relationships>'\n  );\n}\n\nfunction documentRelsXml(\n  images: { relId: string; fileName: string }[],\n  links: { relId: string; href: string }[],\n  hasComments = false,\n  hasHeader = false,\n  hasFooter = false,\n): string {\n  // Style/numbering rel ids are prefixed so they can never collide with the\n  // numeric `rIdN` ids the collector hands out for images and hyperlinks.\n  const commentsRel = hasComments ? `<Relationship Id=\"rIdComments\" Type=\"${R_NS}/comments\" Target=\"comments.xml\"/>` : '';\n  // Fixed ids — must match the `rIdHeader`/`rIdFooter` sectPr references\n  // `serializeTipTapToOOXML` emits when `hasHeader`/`hasFooter` is set.\n  const headerRel = hasHeader ? `<Relationship Id=\"rIdHeader\" Type=\"${R_NS}/header\" Target=\"header1.xml\"/>` : '';\n  const footerRel = hasFooter ? `<Relationship Id=\"rIdFooter\" Type=\"${R_NS}/footer\" Target=\"footer1.xml\"/>` : '';\n  return (\n    XML_DECL +\n    '<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">' +\n    `<Relationship Id=\"rIdStyles\" Type=\"${R_NS}/styles\" Target=\"styles.xml\"/>` +\n    `<Relationship Id=\"rIdNumbering\" Type=\"${R_NS}/numbering\" Target=\"numbering.xml\"/>` +\n    commentsRel +\n    headerRel +\n    footerRel +\n    images.map((i) => `<Relationship Id=\"${i.relId}\" Type=\"${R_NS}/image\" Target=\"media/${i.fileName}\"/>`).join('') +\n    links\n      .map(\n        (l) =>\n          `<Relationship Id=\"${l.relId}\" Type=\"${R_NS}/hyperlink\" Target=\"${escapeXml(l.href)}\" TargetMode=\"External\"/>`,\n      )\n      .join('') +\n    '</Relationships>'\n  );\n}\n\nfunction coreXml(title?: string, creator?: string): string {\n  const now = new Date().toISOString().replace(/\\.\\d+Z$/, 'Z');\n  return (\n    XML_DECL +\n    '<cp:coreProperties xmlns:cp=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\"' +\n    ' xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:dcterms=\"http://purl.org/dc/terms/\"' +\n    ' xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">' +\n    `<dc:title>${escapeXml(title ?? 'Untitled')}</dc:title>` +\n    `<dc:creator>${escapeXml(creator ?? 'docx-editor')}</dc:creator>` +\n    `<cp:lastModifiedBy>${escapeXml(creator ?? 'docx-editor')}</cp:lastModifiedBy>` +\n    `<dcterms:created xsi:type=\"dcterms:W3CDTF\">${now}</dcterms:created>` +\n    `<dcterms:modified xsi:type=\"dcterms:W3CDTF\">${now}</dcterms:modified>` +\n    '</cp:coreProperties>'\n  );\n}\n\nfunction appXml(): string {\n  return (\n    XML_DECL +\n    '<Properties xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\"' +\n    ' xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\">' +\n    '<Application>docx-editor</Application>' +\n    '</Properties>'\n  );\n}\n\n/* -------------------------------------------------------------------------- */\n/* styles.xml — generated from the editor's own typography                     */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Heading sizes/treatment, transcribed from\n * `src/styles/editor-surface/paged-paper.css`. Keep the two in sync: these\n * are what makes an exported heading look like the heading on screen instead\n * of Word's built-in blue Calibri Light.\n */\nconst HEADINGS: { level: number; pt: number; italic?: boolean; color?: string }[] = [\n  { level: 1, pt: 24 },\n  { level: 2, pt: 18 },\n  { level: 3, pt: 14 },\n  { level: 4, pt: 12 },\n  { level: 5, pt: 11, italic: true },\n  { level: 6, pt: 11, color: '57606A' },\n];\n\nconst HEADING_TEXT_COLOR = '1F2328'; // .docx-editor-content h1..h6 { color: #1f2328 }\nconst HEADING_LINE_HEIGHT = 1.25; // …and { line-height: 1.25 }\n\nfunction stylesXml(theme?: DocxEditorTheme): string {\n  const t = { ...defaultTheme, ...theme };\n  const font = escapeXml(resolveDocxFontFamily(String(t.fontFamily)));\n  const bodyPt = cssLengthToPoints(String(t.fontSize), 11);\n  const bodyHalfPt = Math.round(bodyPt * 2);\n  const lineHeight = typeof t.lineHeight === 'number' ? t.lineHeight : parseFloat(String(t.lineHeight)) || 1.5;\n  const line = Math.round(lineHeight * 240);\n  // `p { margin: 0 0 0.6em }` in the editor's stylesheet → space after each\n  // paragraph, in twips (1pt = 20 twips).\n  const afterTwips = Math.round(bodyPt * 0.6 * 20);\n\n  const headingStyles = HEADINGS.map(({ level, pt, italic, color }) => {\n    const beforeTwips = Math.round(pt * 20); // h* { margin-top: 1em }\n    const headingAfter = Math.round(pt * 0.4 * 20); // …{ margin-bottom: 0.4em }\n    return (\n      `<w:style w:type=\"paragraph\" w:styleId=\"Heading${level}\">` +\n      `<w:name w:val=\"heading ${level}\"/><w:basedOn w:val=\"Normal\"/><w:next w:val=\"Normal\"/><w:qFormat/>` +\n      '<w:pPr>' +\n      `<w:keepNext/><w:outlineLvl w:val=\"${level - 1}\"/>` +\n      `<w:spacing w:before=\"${beforeTwips}\" w:after=\"${headingAfter}\" w:line=\"${Math.round(HEADING_LINE_HEIGHT * 240)}\" w:lineRule=\"auto\"/>` +\n      '</w:pPr>' +\n      '<w:rPr>' +\n      `<w:rFonts w:ascii=\"${font}\" w:hAnsi=\"${font}\" w:cs=\"${font}\"/>` +\n      '<w:b/><w:bCs/>' +\n      (italic ? '<w:i/><w:iCs/>' : '') +\n      `<w:color w:val=\"${color ?? HEADING_TEXT_COLOR}\"/>` +\n      `<w:sz w:val=\"${pt * 2}\"/><w:szCs w:val=\"${pt * 2}\"/>` +\n      '</w:rPr>' +\n      '</w:style>'\n    );\n  }).join('');\n\n  return (\n    XML_DECL +\n    `<w:styles xmlns:w=\"${W_NS}\">` +\n    // docDefaults is the root of Word's formatting cascade — setting the\n    // editor's font/size/line-height here is what makes an untouched\n    // paragraph open in Word looking the way it did on screen.\n    '<w:docDefaults>' +\n    '<w:rPrDefault><w:rPr>' +\n    `<w:rFonts w:ascii=\"${font}\" w:hAnsi=\"${font}\" w:eastAsia=\"${font}\" w:cs=\"${font}\"/>` +\n    `<w:sz w:val=\"${bodyHalfPt}\"/><w:szCs w:val=\"${bodyHalfPt}\"/>` +\n    `<w:color w:val=\"${String(t.text).replace('#', '').toUpperCase()}\"/>` +\n    '</w:rPr></w:rPrDefault>' +\n    '<w:pPrDefault><w:pPr>' +\n    `<w:spacing w:after=\"${afterTwips}\" w:line=\"${line}\" w:lineRule=\"auto\"/>` +\n    '</w:pPr></w:pPrDefault>' +\n    '</w:docDefaults>' +\n    '<w:style w:type=\"paragraph\" w:default=\"1\" w:styleId=\"Normal\"><w:name w:val=\"Normal\"/><w:qFormat/></w:style>' +\n    '<w:style w:type=\"character\" w:default=\"1\" w:styleId=\"DefaultParagraphFont\"><w:name w:val=\"Default Paragraph Font\"/></w:style>' +\n    headingStyles +\n    // Quote: the editor draws blockquotes indented + italic.\n    '<w:style w:type=\"paragraph\" w:styleId=\"Quote\">' +\n    '<w:name w:val=\"Quote\"/><w:basedOn w:val=\"Normal\"/><w:qFormat/>' +\n    '<w:pPr><w:ind w:left=\"720\"/></w:pPr><w:rPr><w:i/><w:iCs/></w:rPr>' +\n    '</w:style>' +\n    // Code: monospace, one step down, matching the editor's code block.\n    '<w:style w:type=\"paragraph\" w:styleId=\"Code\">' +\n    '<w:name w:val=\"Code\"/><w:basedOn w:val=\"Normal\"/>' +\n    '<w:pPr><w:spacing w:after=\"100\" w:line=\"240\" w:lineRule=\"auto\"/></w:pPr>' +\n    '<w:rPr><w:rFonts w:ascii=\"Courier New\" w:hAnsi=\"Courier New\" w:cs=\"Courier New\"/><w:sz w:val=\"20\"/><w:szCs w:val=\"20\"/></w:rPr>' +\n    '</w:style>' +\n    // ListParagraph: what Word tags list items with. `contextualSpacing`\n    // suppresses the paragraph gap *between* items, like the editor's `li`.\n    '<w:style w:type=\"paragraph\" w:styleId=\"ListParagraph\">' +\n    '<w:name w:val=\"List Paragraph\"/><w:basedOn w:val=\"Normal\"/><w:qFormat/>' +\n    '<w:pPr><w:ind w:left=\"720\"/><w:contextualSpacing/></w:pPr>' +\n    '</w:style>' +\n    '<w:style w:type=\"character\" w:styleId=\"Hyperlink\">' +\n    '<w:name w:val=\"Hyperlink\"/><w:rPr><w:color w:val=\"0563C1\"/><w:u w:val=\"single\"/></w:rPr>' +\n    '</w:style>' +\n    '</w:styles>'\n  );\n}\n\n/* -------------------------------------------------------------------------- */\n/* numbering.xml                                                               */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Bullet (`numId` 1) and decimal (`numId` 2) definitions, 9 levels each —\n * matching the ids `resolveNumId()` falls back to when there's no original\n * document to read numbering from.\n *\n * Without this part, list paragraphs reference a `w:numId` that doesn't\n * resolve and Word renders them as plain indented text with no bullets or\n * numbers at all. (The `docx`-library path sidestepped that by baking a\n * literal \"• \" / \"1. \" into the run text — which looks approximately right\n * but isn't a list: it never renumbers, and the marker is selectable text.)\n */\n/** word/comments.xml — one <w:comment> per thread, first message only (v1). */\nfunction commentsXml(threads: CommentThread[]): string {\n  const items = threads\n    .map((t) => {\n      const first = t.messages[0];\n      const author = escapeXml(first?.author ?? 'Unknown');\n      const date = first?.createdAt ?? t.createdAt;\n      const text = escapeXml(first?.body ?? '');\n      return (\n        `<w:comment w:id=\"${escapeXml(t.id)}\" w:author=\"${author}\" w:date=\"${date}\">` +\n        `<w:p><w:r><w:t xml:space=\"preserve\">${text}</w:t></w:r></w:p></w:comment>`\n      );\n    })\n    .join('');\n  return `${XML_DECL}<w:comments xmlns:w=\"${W_NS}\">${items}</w:comments>`;\n}\n\n/** word/header1.xml or word/footer1.xml — plain-text paragraphs (v1). */\nfunction headerFooterXml(tag: 'hdr' | 'ftr', html: string): string {\n  const root = tag === 'hdr' ? 'hdr' : 'ftr';\n  const paras = Array.from(html.matchAll(/<p[^>]*>([\\s\\S]*?)<\\/p>/g)).map(\n    (m) => `<w:p><w:r><w:t xml:space=\"preserve\">${escapeXml(stripTags(m[1]))}</w:t></w:r></w:p>`,\n  );\n  return `${XML_DECL}<w:${root} xmlns:w=\"${W_NS}\">${paras.join('') || '<w:p/>'}</w:${root}>`;\n}\n\nfunction stripTags(html: string): string {\n  return html.replace(/<[^>]+>/g, '');\n}\n\nfunction numberingXml(): string {\n  // Symbol/Wingdings bullet glyphs live in the PUA — the same code points\n  // Word itself writes for its default bullet list.\n  const bulletChars = ['\\uF0B7', 'o', '\\uF0A7'];\n  const bulletFonts = ['Symbol', 'Courier New', 'Wingdings'];\n\n  const bulletLevels = Array.from({ length: 9 }, (_, i) => {\n    const indent = 720 * (i + 1);\n    return (\n      `<w:lvl w:ilvl=\"${i}\"><w:start w:val=\"1\"/><w:numFmt w:val=\"bullet\"/>` +\n      `<w:lvlText w:val=\"${escapeXml(bulletChars[i % 3])}\"/><w:lvlJc w:val=\"left\"/>` +\n      `<w:pPr><w:ind w:left=\"${indent}\" w:hanging=\"360\"/></w:pPr>` +\n      `<w:rPr><w:rFonts w:ascii=\"${bulletFonts[i % 3]}\" w:hAnsi=\"${bulletFonts[i % 3]}\" w:hint=\"default\"/></w:rPr></w:lvl>`\n    );\n  }).join('');\n\n  // Word's own default cycle for ordered lists: 1. / a. / i. repeating.\n  const decimalFormats = ['decimal', 'lowerLetter', 'lowerRoman'];\n  const decimalLevels = Array.from({ length: 9 }, (_, i) => {\n    const indent = 720 * (i + 1);\n    return (\n      `<w:lvl w:ilvl=\"${i}\"><w:start w:val=\"1\"/><w:numFmt w:val=\"${decimalFormats[i % 3]}\"/>` +\n      `<w:lvlText w:val=\"%${i + 1}.\"/><w:lvlJc w:val=\"left\"/>` +\n      `<w:pPr><w:ind w:left=\"${indent}\" w:hanging=\"360\"/></w:pPr></w:lvl>`\n    );\n  }).join('');\n\n  return (\n    XML_DECL +\n    `<w:numbering xmlns:w=\"${W_NS}\">` +\n    `<w:abstractNum w:abstractNumId=\"0\"><w:multiLevelType w:val=\"hybridMultilevel\"/>${bulletLevels}</w:abstractNum>` +\n    `<w:abstractNum w:abstractNumId=\"1\"><w:multiLevelType w:val=\"hybridMultilevel\"/>${decimalLevels}</w:abstractNum>` +\n    '<w:num w:numId=\"1\"><w:abstractNumId w:val=\"0\"/></w:num>' +\n    '<w:num w:numId=\"2\"><w:abstractNumId w:val=\"1\"/></w:num>' +\n    '</w:numbering>'\n  );\n}\n\n/* -------------------------------------------------------------------------- */\n/* Helpers                                                                     */\n/* -------------------------------------------------------------------------- */\n\n/** CSS keywords that name \"whatever the OS uses\" rather than a real font\n *  file — meaningless as an OOXML `w:ascii` value, so they're skipped. */\nconst SYSTEM_FONT_KEYWORDS = new Set(['system-ui', 'ui-sans-serif', 'ui-serif', 'ui-monospace', 'blinkmacsystemfont']);\nconst GENERIC_FONT_FALLBACKS: Record<string, string> = {\n  'sans-serif': 'Arial',\n  serif: 'Times New Roman',\n  monospace: 'Courier New',\n  cursive: 'Comic Sans MS',\n  fantasy: 'Impact',\n};\n\n/**\n * Pick a real font name out of a CSS font stack for OOXML.\n *\n * The default theme stack starts with `-apple-system, BlinkMacSystemFont` —\n * naming either of those in `w:rFonts` gives Word a font it can't resolve, so\n * it silently substitutes something arbitrary. Walk the stack for the first\n * entry that names an actual typeface, and map a trailing generic family to\n * its usual Word equivalent if that's all there is.\n */\nexport function resolveDocxFontFamily(stack: string): string {\n  const entries = stack.split(',').map((e) => e.trim().replace(/^['\"]|['\"]$/g, ''));\n  for (const entry of entries) {\n    if (!entry) continue;\n    const lower = entry.toLowerCase();\n    if (entry.startsWith('-') || SYSTEM_FONT_KEYWORDS.has(lower)) continue;\n    if (GENERIC_FONT_FALLBACKS[lower]) continue;\n    return entry;\n  }\n  for (const entry of entries) {\n    const mapped = GENERIC_FONT_FALLBACKS[entry.trim().toLowerCase()];\n    if (mapped) return mapped;\n  }\n  return 'Calibri';\n}\n\n/** CSS length → points (OOXML's typographic unit). */\nexport function cssLengthToPoints(value: string, fallbackPt: number): number {\n  const match = /^\\s*([\\d.]+)\\s*(px|pt|in|cm|mm|pc|em|rem)?\\s*$/i.exec(value);\n  if (!match) return fallbackPt;\n  const num = parseFloat(match[1]);\n  if (isNaN(num) || num <= 0) return fallbackPt;\n  switch ((match[2] ?? 'px').toLowerCase()) {\n    case 'pt':\n      return num;\n    case 'in':\n      return num * 72;\n    case 'cm':\n      return num * 28.3465;\n    case 'mm':\n      return num * 2.83465;\n    case 'pc':\n      return num * 12;\n    case 'em':\n    case 'rem':\n      return num * fallbackPt;\n    default:\n      return num * 0.75; // px → pt at 96 DPI\n  }\n}\n\nfunction escapeXml(text: string): string {\n  return text\n    .replace(/&/g, '&amp;')\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;')\n    .replace(/\"/g, '&quot;')\n    .replace(/'/g, '&apos;');\n}\n","import { serializeTipTapToOOXML, ImageCollector } from './ooxml-serializer';\nimport { buildFreshDocxPackage } from './docx-package';\nimport type { PageDimensionsTwips } from '../page-setup';\nimport type { DocxEditorTheme } from '../theme';\nimport type { CommentThread } from '../comments-types';\n\n/**\n * Convert a TipTap JSON document (the format produced by `editor.getJSON()`)\n * into a .docx Blob, ready to download or save.\n *\n * This is the \"no original file to patch\" path — a document created in the\n * editor rather than opened from disk. It runs the *same* OOXML serializer\n * the selective-save path uses (`serializeTipTapToOOXML`) and wraps the result\n * in a generated package (`./docx-package`) whose `styles.xml` is derived from\n * the editor's own theme/stylesheet.\n *\n * It used to rebuild the document with the `docx` library instead, which is\n * why an exported file never matched the screen: that path had no access to\n * the editor's typography (so Word applied its own Calibri/Heading defaults),\n * dropped `fontFamily`, letter spacing, indentation and per-paragraph line\n * height, wrote lists as literal \"• \"/\"1. \" text rather than real numbering,\n * and emitted headings as Word's built-in blue heading styles. Routing both\n * save paths through one serializer means a given document exports the same\n * way whether or not it happens to have an original .docx behind it.\n *\n * Supported node types: doc, paragraph, heading, bulletList/orderedList\n * (incl. nesting), listItem, codeBlock, blockquote, horizontalRule,\n * pageBreak, table (widths/merges/shading/borders), image.\n *\n * Supported marks: bold, italic, underline, strike, superscript, subscript,\n * link (as a real external relationship), textStyle (color, fontSize,\n * fontFamily, letterSpacing, backgroundColor), textTransform (uppercase),\n * highlight.\n */\nexport interface SaveDocxOptions {\n  /** Document title (used in core properties). */\n  title?: string;\n  /** Author name (used in core properties). */\n  creator?: string;\n  /**\n   * Page size/margins in twips, from `resolvePageDimensionsTwips()`\n   * (`../page-setup`). Falls back to US Letter with 1in margins when omitted.\n   */\n  pageDimensions?: PageDimensionsTwips;\n  /**\n   * The editor's resolved theme. Drives the generated `styles.xml` document\n   * defaults (font family/size, text color, line height) so the exported file\n   * opens with the typography the document was edited in. Falls back to\n   * `defaultTheme` when omitted.\n   */\n  theme?: DocxEditorTheme;\n  /** Comment threads to write to word/comments.xml, matched to `comment`\n   *  marks in `json` by id. From a `CommentsStorageAdapter.list()` call. */\n  commentThreads?: CommentThread[];\n  /** Header/footer content as HTML paragraphs (plain text, v1) — from\n   *  `DocxEditor.getHeaderHTML()`/`getFooterHTML()`. */\n  headerHTML?: string;\n  footerHTML?: string;\n}\n\nexport async function saveDocxFromJSON(json: any, options: SaveDocxOptions = {}): Promise<Blob> {\n  // A fresh package starts with no relationships of its own, so image and\n  // hyperlink ids can safely begin at 1.\n  const collector = new ImageCollector();\n  const { bodyXml } = serializeTipTapToOOXML(json, {\n    imageCollector: collector,\n    pageDimensions: options.pageDimensions,\n    hasHeader: !!options.headerHTML,\n    hasFooter: !!options.footerHTML,\n  });\n\n  const buffer = await buildFreshDocxPackage({\n    bodyXml,\n    collector,\n    theme: options.theme,\n    title: options.title,\n    creator: options.creator,\n    commentThreads: options.commentThreads,\n    headerHTML: options.headerHTML,\n    footerHTML: options.footerHTML,\n  });\n\n  return new Blob([buffer], {\n    type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n  });\n}\n","/**\n * OOXML Serializer — convert TipTap JSON back to OOXML <w:body> XML.\n *\n * This replaces the `docx` library (which rebuilds the entire document\n * from scratch) with a serializer that generates proper <w:p>, <w:r>,\n * <w:t> elements. When used with selective save, only changed paragraphs\n * are patched into the original XML — preserving unchanged content\n * byte-for-byte for Word Compare compatibility.\n */\n\nimport { hexToHighlightName } from './ooxml-marks';\nimport { PX_PER_POINT, pxToHalfPoints } from './ooxml-units';\nimport { parseNumberingXml, type NumberingInfo } from './ooxml-parser';\nimport {\n  buildTableModel,\n  resolveTableBorders,\n  presetCellFill,\n  TWIPS_PER_PX,\n  type BorderSpec,\n} from './table-model';\nimport type { PageDimensionsTwips } from '../page-setup';\n\n// Lazy-load JSZip\nlet _JSZip: any = null;\nasync function getJSZip(): Promise<any> {\n  if (_JSZip) return _JSZip;\n  const mod = await import('jszip');\n  _JSZip = mod.default || mod;\n  return _JSZip;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Image embedding                                                             */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Real image embedding requires more than XML text: the binary bytes need\n * to land in `word/media/*`, a relationship needs to be registered in\n * `word/_rels/document.xml.rels` mapping an `rId` to that media file, and\n * `[Content_Types].xml` needs a `Default` entry for the file extension.\n * `ImageCollector` gathers that side-table while `blockToXml`/`imageToXml`\n * walk the document, so the caller can apply it to the zip in one pass\n * after serialization.\n */\nexport interface CollectedImage {\n  relId: string;\n  fileName: string;\n  contentType: string;\n  bytes: Uint8Array;\n}\n\n/** An external hyperlink target that needs an `TargetMode=\"External\"`\n *  relationship written alongside the images. */\nexport interface CollectedLink {\n  relId: string;\n  href: string;\n}\n\nexport class ImageCollector {\n  readonly images: CollectedImage[] = [];\n  /** External hyperlink targets, sharing this collector's `rId` counter so\n   *  image and link relationship ids can never collide. */\n  readonly links: CollectedLink[] = [];\n  private nextRelIdNum: number;\n  private nextMediaNum: number;\n  private linkRelIdByHref = new Map<string, string>();\n\n  constructor(startRelIdNum = 1, startMediaNum = 1) {\n    this.nextRelIdNum = startRelIdNum;\n    this.nextMediaNum = startMediaNum;\n  }\n\n  /** Register an image `src` (data URI) for embedding. Returns the `r:embed`\n   *  relationship id to reference from the drawing XML, or null if `src`\n   *  isn't something we can embed (e.g. a remote URL we can't fetch here). */\n  add(src: string): string | null {\n    const decoded = decodeDataUri(src);\n    if (!decoded) return null;\n    const relId = `rId${this.nextRelIdNum++}`;\n    const fileName = `image${this.nextMediaNum++}.${decoded.ext}`;\n    this.images.push({ relId, fileName, contentType: decoded.contentType, bytes: decoded.bytes });\n    return relId;\n  }\n\n  /**\n   * Register an external hyperlink target. Returns the `r:id` for the\n   * `<w:hyperlink>` element.\n   *\n   * `<w:hyperlink>` addresses its target by relationship id, so a link is only\n   * a link if a matching entry exists in `word/_rels/document.xml.rels`.\n   * Without this the serializer emitted a hardcoded `r:id=\"rIdLink\"` that\n   * resolved to nothing — Word treats an unresolvable relationship as a\n   * damaged part and offers to repair the file. Identical hrefs share one\n   * relationship, the way Word itself writes them.\n   */\n  addLink(href: string): string {\n    const existing = this.linkRelIdByHref.get(href);\n    if (existing) return existing;\n    const relId = `rId${this.nextRelIdNum++}`;\n    this.linkRelIdByHref.set(href, relId);\n    this.links.push({ relId, href });\n    return relId;\n  }\n}\n\nconst IMAGE_EXT_BY_MIME: Record<string, string> = {\n  'image/jpeg': 'jpg',\n  'image/jpg': 'jpg',\n  'image/png': 'png',\n  'image/gif': 'gif',\n  'image/bmp': 'bmp',\n  'image/webp': 'webp',\n  'image/svg+xml': 'svg',\n  'image/tiff': 'tiff',\n  'image/x-icon': 'ico',\n};\n\n/** Decode a `data:` URI into raw bytes + a file extension/content type. */\nfunction decodeDataUri(src: string): { bytes: Uint8Array; ext: string; contentType: string } | null {\n  const match = /^data:([^;,]+)(?:;charset=[^;,]+)?;base64,([\\s\\S]*)$/.exec(src);\n  if (!match) return null;\n  const contentType = match[1].toLowerCase();\n  const ext = IMAGE_EXT_BY_MIME[contentType] ?? contentType.split('/')[1]?.split('+')[0] ?? 'png';\n  try {\n    return { bytes: base64ToBytes(match[2]), ext, contentType };\n  } catch {\n    return null;\n  }\n}\n\n/** Base64 → bytes. Works in the browser (`atob`) and in Node (`Buffer`). */\nfunction base64ToBytes(base64: string): Uint8Array {\n  if (typeof atob === 'function') {\n    const binary = atob(base64);\n    const bytes = new Uint8Array(binary.length);\n    for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);\n    return bytes;\n  }\n  const nodeBuffer = (globalThis as any).Buffer;\n  if (nodeBuffer) {\n    const buf = nodeBuffer.from(base64, 'base64');\n    return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);\n  }\n  throw new Error('No base64 decoder available in this environment');\n}\n\nconst EMU_PER_PX = 9525; // 1px @ 96dpi, the standard OOXML drawing unit conversion\n\n/** Convert a CSS length (e.g. \"300px\") to EMUs, falling back to a default\n *  pixel size when the value is missing or is a percentage (which we can't\n *  resolve to an absolute size without knowing the page's content width). */\nfunction lengthToEmu(value: string | number | null | undefined, fallbackPx: number): number {\n  if (value === null || value === undefined || value === '') return fallbackPx * EMU_PER_PX;\n  const str = String(value).trim();\n  if (str.endsWith('%')) return fallbackPx * EMU_PER_PX;\n  const num = parseFloat(str);\n  if (isNaN(num) || num <= 0) return fallbackPx * EMU_PER_PX;\n  return Math.round(num * EMU_PER_PX);\n}\n\nconst RELS_PATH = 'word/_rels/document.xml.rels';\nconst CONTENT_TYPES_PATH = '[Content_Types].xml';\nconst IMAGE_REL_TYPE = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image';\nconst HYPERLINK_REL_TYPE = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink';\n\n/** Figure out the next free `rIdN` / `imageN` numbers so newly-added\n *  relationships/media never collide with what's already in the .docx. */\nasync function computeNextImageIds(zip: any): Promise<{ nextRelIdNum: number; nextMediaNum: number }> {\n  let nextRelIdNum = 1;\n  let nextMediaNum = 1;\n  try {\n    const relsXml = await zip.file(RELS_PATH)?.async('string');\n    if (relsXml) {\n      for (const m of relsXml.matchAll(/Id=\"rId(\\d+)\"/g)) {\n        nextRelIdNum = Math.max(nextRelIdNum, parseInt(m[1], 10) + 1);\n      }\n    }\n  } catch {\n    // ignore — start from 1\n  }\n  try {\n    for (const path of Object.keys(zip.files ?? {})) {\n      const m = /^word\\/media\\/image(\\d+)\\./.exec(path);\n      if (m) nextMediaNum = Math.max(nextMediaNum, parseInt(m[1], 10) + 1);\n    }\n  } catch {\n    // ignore — start from 1\n  }\n  return { nextRelIdNum, nextMediaNum };\n}\n\n/** Write collected images' bytes into `word/media/*`, and register them in\n *  `word/_rels/document.xml.rels` + `[Content_Types].xml` so Word can\n *  actually resolve the `r:embed` references in the body XML. */\nasync function applyImageCollectorToZip(zip: any, collector: ImageCollector): Promise<void> {\n  if (collector.images.length === 0 && collector.links.length === 0) return;\n\n  for (const img of collector.images) {\n    zip.file(`word/media/${img.fileName}`, img.bytes);\n  }\n\n  let relsXml: string | undefined = await zip.file(RELS_PATH)?.async('string');\n  if (!relsXml) {\n    relsXml =\n      '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>' +\n      '<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"></Relationships>';\n  }\n  const relEntries =\n    collector.images\n      .map((img) => `<Relationship Id=\"${img.relId}\" Type=\"${IMAGE_REL_TYPE}\" Target=\"media/${img.fileName}\"/>`)\n      .join('') +\n    collector.links\n      .map(\n        (link) =>\n          `<Relationship Id=\"${link.relId}\" Type=\"${HYPERLINK_REL_TYPE}\" Target=\"${escapeXml(link.href)}\" TargetMode=\"External\"/>`,\n      )\n      .join('');\n  relsXml = relsXml.includes('</Relationships>')\n    ? relsXml.replace('</Relationships>', `${relEntries}</Relationships>`)\n    : relsXml + relEntries;\n  zip.file(RELS_PATH, relsXml);\n\n  let typesXml: string | undefined = await zip.file(CONTENT_TYPES_PATH)?.async('string');\n  if (!typesXml) {\n    typesXml =\n      '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>' +\n      '<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\"></Types>';\n  }\n  const seenExt = new Set<string>();\n  let defaultsToAdd = '';\n  for (const img of collector.images) {\n    const ext = img.fileName.split('.').pop()!;\n    if (seenExt.has(ext)) continue;\n    seenExt.add(ext);\n    if (!new RegExp(`Extension=\"${ext}\"`, 'i').test(typesXml)) {\n      defaultsToAdd += `<Default Extension=\"${ext}\" ContentType=\"${img.contentType}\"/>`;\n    }\n  }\n  if (defaultsToAdd) {\n    typesXml = typesXml.includes('</Types>')\n      ? typesXml.replace('</Types>', `${defaultsToAdd}</Types>`)\n      : typesXml + defaultsToAdd;\n    zip.file(CONTENT_TYPES_PATH, typesXml);\n  }\n}\n\n/* -------------------------------------------------------------------------- */\n/* Types                                                                       */\n/* -------------------------------------------------------------------------- */\n\nexport interface SerializeOptions {\n  /** If provided, only serialize blocks whose indices are in this set.\n   *  Others will be left unchanged in the original XML. */\n  changedBlockIndices?: Set<number>;\n  /** Collects images encountered during serialization (bytes + assigned\n   *  relationship id) so the caller can embed them into the .docx zip.\n   *  If omitted, images are serialized as `[Image: ...]` placeholder text. */\n  imageCollector?: ImageCollector;\n  /**\n   * Numbering definitions read from the *original* document's\n   * `word/numbering.xml` (via `parseNumberingXml`). When present, bullet and\n   * ordered lists resolve their `w:numId` to a definition that actually\n   * exists in that document instead of hardcoding numId \"1\"/\"2\" — which\n   * only happens to be correct by convention and can point a list at the\n   * wrong (or a nonexistent) numbering definition otherwise.\n   */\n  numberingMap?: Map<string, NumberingInfo>;\n  /** Reference default header/footer parts in sectPr (rel ids fixed to\n   *  match docx-package.ts's buildFreshDocxPackage). */\n  hasHeader?: boolean;\n  hasFooter?: boolean;\n  /**\n   * Page size/margins in OOXML twips, from `resolvePageDimensionsTwips()`\n   * (`../page-setup`). Defaults to US Letter (12240x15840 twips) with 1in\n   * margins — matching Word's own built-in default — when omitted.\n   */\n  pageDimensions?: PageDimensionsTwips;\n}\n\nexport interface SerializeResult {\n  /** Full <w:body> XML string (for full document replacement). */\n  bodyXml: string;\n  /** Array of { index, xml } for individual changed paragraphs (for selective patching). */\n  changedParagraphs: Array<{ index: number; xml: string }>;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Main serialize function                                                     */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Convert TipTap JSON to OOXML <w:body> XML.\n *\n * @param json - TipTap document JSON\n * @param options - Serialization options\n * @returns XML string + per-paragraph XML for selective patching\n */\nexport function serializeTipTapToOOXML(\n  json: any,\n  options: SerializeOptions = {},\n): SerializeResult {\n  const blocks = json?.content ?? [];\n  const changedParagraphs: Array<{ index: number; xml: string }> = [];\n  const bodyParts: string[] = [];\n  const collector = options.imageCollector;\n  const numberingMap = options.numberingMap;\n  revisionIdCounter = 0;\n  bookmarkIdCounter = 0;\n\n  for (let i = 0; i < blocks.length; i++) {\n    const block = blocks[i];\n    const xml = blockToXml(block, collector, numberingMap);\n\n    bodyParts.push(xml);\n\n    if (options.changedBlockIndices?.has(i)) {\n      changedParagraphs.push({ index: i, xml });\n    }\n  }\n\n  const pd = options.pageDimensions ?? {\n    widthTwips: 12240,\n    heightTwips: 15840,\n    marginXTwips: 1440,\n    marginYTwips: 1440,\n  };\n  const headerRef = options.hasHeader ? '<w:headerReference w:type=\"default\" r:id=\"rIdHeader\"/>' : '';\n  const footerRef = options.hasFooter ? '<w:footerReference w:type=\"default\" r:id=\"rIdFooter\"/>' : '';\n  const bodyXml = `<w:body>${bodyParts.join('')}<w:sectPr>${headerRef}${footerRef}<w:pgSz w:w=\"${pd.widthTwips}\" w:h=\"${pd.heightTwips}\"/><w:pgMar w:top=\"${pd.marginYTwips}\" w:right=\"${pd.marginXTwips}\" w:bottom=\"${pd.marginYTwips}\" w:left=\"${pd.marginXTwips}\" w:header=\"720\" w:footer=\"720\" w:gutter=\"0\"/><w:cols w:space=\"720\"/><w:docGrid w:linePitch=\"360\"/></w:sectPr></w:body>`;\n\n  return { bodyXml, changedParagraphs };\n}\n\n/* -------------------------------------------------------------------------- */\n/* Block → XML converters                                                      */\n/* -------------------------------------------------------------------------- */\n\nfunction blockToXml(block: any, collector?: ImageCollector, numberingMap?: Map<string, NumberingInfo>): string {\n  if (!block) return '';\n\n  switch (block.type) {\n    case 'paragraph':\n      return paragraphToXml(block, collector);\n    case 'heading':\n      return headingToXml(block, collector);\n    case 'bulletList':\n      return listToXml(block, 'bullet', collector, numberingMap);\n    case 'orderedList':\n      return listToXml(block, 'decimal', collector, numberingMap);\n    case 'blockquote':\n      return blockquoteToXml(block, collector);\n    case 'codeBlock':\n      return codeBlockToXml(block);\n    case 'horizontalRule':\n      return '<w:p><w:pPr><w:pBdr><w:bottom w:val=\"single\" w:sz=\"6\" w:space=\"1\" w:color=\"auto\"/></w:pBdr></w:pPr></w:p>';\n    case 'pageBreak':\n      return '<w:p><w:r><w:br w:type=\"page\"/></w:r></w:p>';\n    case 'table':\n      return tableToXml(block, collector, numberingMap);\n    case 'image':\n      return imageToXml(block, collector);\n    default:\n      // Unknown block — try as paragraph\n      if (block.content) return paragraphToXml(block, collector);\n      return '<w:p/>';\n  }\n}\n\n/**\n * The `<w:pPr>` children shared by every paragraph-ish block (plain\n * paragraphs, headings, list items, quotes) — alignment, line spacing and\n * indentation, i.e. the paragraph properties the editor renders on screen.\n * Extracted so a list item doesn't silently lose the alignment/spacing a\n * plain paragraph keeps.\n */\nfunction paragraphPropParts(attrs: any): string[] {\n  const parts: string[] = [];\n\n  if (attrs?.textAlign) {\n    parts.push(`<w:jc w:val=\"${attrs.textAlign}\"/>`);\n  }\n\n  if (attrs?.lineHeight) {\n    const multiplier = parseFloat(attrs.lineHeight);\n    if (!isNaN(multiplier)) {\n      // `w:line` is in 240ths of a line when `w:lineRule=\"auto\"`.\n      parts.push(`<w:spacing w:line=\"${Math.round(multiplier * 240)}\" w:lineRule=\"auto\"/>`);\n    }\n  }\n\n  // Indentation (px in the editor's schema → twips). `textIndent` is the\n  // first-line indent; a negative value is a hanging indent, which OOXML\n  // spells as `w:hanging` rather than a negative `w:firstLine`.\n  const indentParts: string[] = [];\n  const indentPx = parseFloat(attrs?.indent);\n  if (!isNaN(indentPx) && indentPx !== 0) indentParts.push(`w:left=\"${Math.round(indentPx * TWIPS_PER_PX)}\"`);\n  const firstLinePx = parseFloat(attrs?.textIndent);\n  if (!isNaN(firstLinePx) && firstLinePx !== 0) {\n    indentParts.push(\n      firstLinePx > 0\n        ? `w:firstLine=\"${Math.round(firstLinePx * TWIPS_PER_PX)}\"`\n        : `w:hanging=\"${Math.round(-firstLinePx * TWIPS_PER_PX)}\"`,\n    );\n  }\n  if (indentParts.length > 0) parts.push(`<w:ind ${indentParts.join(' ')}/>`);\n\n  // Tab stops (px in the editor's schema → twips).\n  if (Array.isArray(attrs?.tabStops) && attrs.tabStops.length > 0) {\n    const tabEls = attrs.tabStops\n      .map((t: { pos: number; val: string }) => `<w:tab w:val=\"${t.val}\" w:pos=\"${Math.round(t.pos * TWIPS_PER_PX)}\"/>`)\n      .join('');\n    parts.push(`<w:tabs>${tabEls}</w:tabs>`);\n  }\n\n  return parts;\n}\n\nfunction paragraphToXml(block: any, collector?: ImageCollector): string {\n  const pPrParts = paragraphPropParts(block.attrs);\n  const pPr = pPrParts.length > 0 ? `<w:pPr>${pPrParts.join('')}</w:pPr>` : '';\n  const runs = runsToXml(block.content ?? [], collector);\n\n  return `<w:p>${pPr}${runs}</w:p>`;\n}\n\nfunction headingToXml(block: any, collector?: ImageCollector): string {\n  const level = block.attrs?.level ?? 2;\n  const styleId = `Heading${level}`;\n  const attrs = block.attrs ?? {};\n\n  const pPrParts: string[] = [`<w:pStyle w:val=\"${styleId}\"/>`, ...paragraphPropParts(attrs)];\n\n  const pPr = `<w:pPr>${pPrParts.join('')}</w:pPr>`;\n  const runs = runsToXml(block.content ?? [], collector);\n\n  return `<w:p>${pPr}${runs}</w:p>`;\n}\n\n/**\n * A bullet/ordered list → one `<w:p>` per list-item paragraph carrying a\n * `<w:numPr>`.\n *\n * `level` is the nesting depth (`w:ilvl`). A list nested inside a list item\n * used to be dropped on the floor — only direct `paragraph` children were\n * serialized — so a two-level list exported as a flat one with its sub-items\n * missing entirely. Nested lists now recurse with `level + 1`, which is also\n * how Word itself represents them (a flat run of paragraphs distinguished\n * only by `w:ilvl`, not by nesting in the XML). Levels beyond the 9 defined\n * in numbering.xml clamp to the last one, matching Word's own limit.\n */\nfunction listToXml(\n  block: any,\n  format: 'bullet' | 'decimal',\n  collector?: ImageCollector,\n  numberingMap?: Map<string, NumberingInfo>,\n  level = 0,\n): string {\n  const items = block.content ?? [];\n  const parts: string[] = [];\n  const numId = resolveNumId(format, numberingMap);\n  const ilvl = Math.min(level, 8);\n\n  for (const item of items) {\n    if (item.type !== 'listItem') continue;\n    for (const child of item.content ?? []) {\n      if (child.type === 'paragraph') {\n        const numPr = `<w:numPr><w:ilvl w:val=\"${ilvl}\"/><w:numId w:val=\"${numId}\"/></w:numPr>`;\n        // `ListParagraph` is the style Word tags list items with; without it\n        // exported items lose the list's own indentation/spacing.\n        const pPrParts = [`<w:pStyle w:val=\"ListParagraph\"/>`, numPr, ...paragraphPropParts(child.attrs)];\n        const runs = runsToXml(child.content ?? [], collector);\n        parts.push(`<w:p><w:pPr>${pPrParts.join('')}</w:pPr>${runs}</w:p>`);\n      } else if (child.type === 'bulletList' || child.type === 'orderedList') {\n        parts.push(\n          listToXml(child, child.type === 'bulletList' ? 'bullet' : 'decimal', collector, numberingMap, level + 1),\n        );\n      } else {\n        parts.push(blockToXml(child, collector, numberingMap));\n      }\n    }\n  }\n\n  return parts.join('');\n}\n\n/**\n * Resolve the `w:numId` a bullet/ordered list should reference: the first\n * definition in the *original* document's numbering.xml matching the\n * requested format, so a selective save points lists at a numbering\n * definition that actually exists rather than assuming numId \"1\" is always\n * bullets and \"2\" is always decimal.\n *\n * Falls back to that convention only when there's no numbering map to draw\n * from (no `numbering.xml` in the original .docx, or this is a full/fresh\n * save with no \"original document\" at all) — a best-effort default, not a\n * guarantee, since a document with unconventional numId assignments and no\n * matching list already in it has no existing definition to point to.\n */\nfunction resolveNumId(format: 'bullet' | 'decimal', numberingMap?: Map<string, NumberingInfo>): string {\n  if (numberingMap) {\n    for (const info of numberingMap.values()) {\n      const isBullet = info.format === 'bullet';\n      if ((format === 'bullet') === isBullet) return info.numId;\n    }\n  }\n  return format === 'bullet' ? '1' : '2';\n}\n\nfunction blockquoteToXml(block: any, collector?: ImageCollector): string {\n  const paragraphs = block.content ?? [];\n  const parts: string[] = [];\n  for (const p of paragraphs) {\n    if (p.type === 'paragraph') {\n      const pPr = '<w:pPr><w:pStyle w:val=\"Quote\"/></w:pPr>';\n      const runs = runsToXml(p.content ?? [], collector);\n      parts.push(`<w:p>${pPr}${runs}</w:p>`);\n    }\n  }\n  return parts.join('') || '<w:p><w:pPr><w:pStyle w:val=\"Quote\"/></w:pPr></w:p>';\n}\n\nfunction codeBlockToXml(block: any): string {\n  const pPr = '<w:pPr><w:pStyle w:val=\"Code\"/></w:pPr>';\n  const runs = runsToXml(block.content ?? []);\n  return `<w:p>${pPr}${runs}</w:p>`;\n}\n\n/** One `<w:*>` border element from a shared BorderSpec. */\nfunction borderXml(tag: string, spec: BorderSpec): string {\n  if (spec.val === 'none') return `<w:${tag} w:val=\"none\" w:sz=\"0\" w:space=\"0\" w:color=\"auto\"/>`;\n  return `<w:${tag} w:val=\"single\" w:sz=\"${spec.sz}\" w:space=\"0\" w:color=\"${spec.color}\"/>`;\n}\n\n/**\n * Serialize a TipTap `table` node to OOXML, preserving the full grid.\n *\n * The previous version emitted an empty `<w:tblGrid/>`, `w:type=\"auto\"`\n * cell widths and hard-coded borders — so Word re-flowed every column to\n * auto-width, dropped all merges, shading and alignment, and ignored the\n * editor's border/table-style presets. This rebuilds the real grid via\n * `buildTableModel` and emits a proper `<w:tblGrid>`, per-cell `<w:tcW>`\n * widths, `<w:gridSpan>` / `<w:vMerge>` for merged cells, `<w:shd>` fills,\n * borders resolved from the editor's presets, and table width/alignment.\n */\nfunction tableToXml(block: any, collector?: ImageCollector, numberingMap?: Map<string, NumberingInfo>): string {\n  const model = buildTableModel(block);\n  const borders = resolveTableBorders(model);\n  const trParts: string[] = [];\n\n  model.rows.forEach((rowModel, rowIndex) => {\n    const tcParts: string[] = [];\n\n    for (const cellModel of rowModel.cells) {\n      const tcPrParts: string[] = [];\n\n      // Width (twips). Known width → dxa; otherwise auto.\n      if (cellModel.widthPx != null) {\n        tcPrParts.push(`<w:tcW w:w=\"${Math.round(cellModel.widthPx * TWIPS_PER_PX)}\" w:type=\"dxa\"/>`);\n      } else {\n        tcPrParts.push('<w:tcW w:w=\"0\" w:type=\"auto\"/>');\n      }\n\n      if (cellModel.colspan > 1) tcPrParts.push(`<w:gridSpan w:val=\"${cellModel.colspan}\"/>`);\n\n      if (cellModel.vMergeContinue) {\n        tcPrParts.push('<w:vMerge/>');\n      } else if (cellModel.rowspan > 1) {\n        tcPrParts.push('<w:vMerge w:val=\"restart\"/>');\n      }\n\n      const fill = cellModel.backgroundColor ?? presetCellFill(model, cellModel.isHeader, rowIndex);\n      if (fill) tcPrParts.push(`<w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\"${fill}\"/>`);\n\n      const tcPr = `<w:tcPr>${tcPrParts.join('')}</w:tcPr>`;\n\n      // Continuation cells carry no content of their own.\n      const cellParas: string[] = [];\n      if (!cellModel.vMergeContinue) {\n        for (const p of cellModel.node?.content ?? []) {\n          if (p.type === 'paragraph') {\n            const runs = runsToXml(p.content ?? [], collector);\n            cellParas.push(`<w:p>${runs}</w:p>`);\n          } else {\n            cellParas.push(blockToXml(p, collector, numberingMap));\n          }\n        }\n      }\n\n      tcParts.push(`<w:tc>${tcPr}${cellParas.join('') || '<w:p/>'}</w:tc>`);\n    }\n\n    const trPrParts: string[] = [];\n    if (rowIndex === 0 && rowModel.cells.some((c) => c.isHeader)) trPrParts.push('<w:tblHeader/>');\n    if (rowModel.heightPx != null) {\n      trPrParts.push(`<w:trHeight w:val=\"${Math.round(rowModel.heightPx * TWIPS_PER_PX)}\" w:hRule=\"atLeast\"/>`);\n    }\n    const trPr = trPrParts.length ? `<w:trPr>${trPrParts.join('')}</w:trPr>` : '';\n    trParts.push(`<w:tr>${trPr}${tcParts.join('')}</w:tr>`);\n  });\n\n  // Table width + alignment.\n  const tblWParts: string[] = [];\n  if (model.tableWidthPercent != null) {\n    tblWParts.push(`<w:tblW w:w=\"${Math.round(model.tableWidthPercent * 50)}\" w:type=\"pct\"/>`);\n  } else if (model.tableWidthPx != null) {\n    tblWParts.push(`<w:tblW w:w=\"${Math.round(model.tableWidthPx * TWIPS_PER_PX)}\" w:type=\"dxa\"/>`);\n  } else if (model.colWidthsPx.length > 0 && model.colWidthsPx.every((w) => w != null)) {\n    const total = (model.colWidthsPx as number[]).reduce((a, b) => a + b, 0);\n    tblWParts.push(`<w:tblW w:w=\"${Math.round(total * TWIPS_PER_PX)}\" w:type=\"dxa\"/>`);\n  } else {\n    tblWParts.push('<w:tblW w:w=\"5000\" w:type=\"pct\"/>');\n  }\n  if (model.align === 'center') tblWParts.push('<w:jc w:val=\"center\"/>');\n  else if (model.align === 'right') tblWParts.push('<w:jc w:val=\"right\"/>');\n\n  const tblBorders =\n    '<w:tblBorders>' +\n    borderXml('top', borders.top) +\n    borderXml('left', borders.left) +\n    borderXml('bottom', borders.bottom) +\n    borderXml('right', borders.right) +\n    borderXml('insideH', borders.insideH) +\n    borderXml('insideV', borders.insideV) +\n    '</w:tblBorders>';\n\n  const tblPr = `<w:tblPr>${tblWParts.join('')}${tblBorders}</w:tblPr>`;\n\n  // Grid: one <w:gridCol> per column, with widths when known.\n  const gridCols = model.colWidthsPx\n    .map((w) =>\n      w != null ? `<w:gridCol w:w=\"${Math.round(w * TWIPS_PER_PX)}\"/>` : '<w:gridCol/>',\n    )\n    .join('');\n  const tblGrid = `<w:tblGrid>${gridCols}</w:tblGrid>`;\n\n  return `<w:tbl>${tblPr}${tblGrid}${trParts.join('')}</w:tbl>`;\n}\n\n/**\n * Serialize an `image` node to real OOXML DrawingML — `<w:drawing>` with a\n * `<pic:pic>` that `r:embed`s a relationship id from `collector`. The\n * namespaces used (`wp`, `a`, `pic`, `r`) are declared right on `<w:drawing>`\n * itself so this fragment is also valid if it's ever parsed standalone (as\n * `patchDocumentXml`'s selective-paragraph-patch path does).\n *\n * Falls back to a `[Image: ...]` placeholder when there's no collector (the\n * caller didn't ask for image embedding) or the source can't be decoded\n * (e.g. a remote URL we have no way to fetch synchronously here).\n */\nfunction imageToXml(block: any, collector?: ImageCollector): string {\n  // A block-level image carries its own `alignment` attr (the editor's\n  // left/center/right image control) — without this the picture always\n  // exported flush left regardless of how it was placed on the page.\n  const imgAlign = block.attrs?.alignment;\n  const imgPPr = imgAlign ? `<w:pPr><w:jc w:val=\"${imgAlign}\"/></w:pPr>` : '';\n  return `<w:p>${imgPPr}${imageRunXml(block, collector)}</w:p>`;\n}\n\n/**\n * The `<w:r>` for an image, without a surrounding paragraph.\n *\n * Kept separate from `imageToXml` because an image can appear either as a\n * block (its own paragraph) or inline among text runs. Emitting the paragraph\n * wrapper in both cases nested a `<w:p>` inside a `<w:p>`, which is not legal\n * WordprocessingML — Word reports the document as damaged.\n */\nfunction imageRunXml(block: any, collector?: ImageCollector): string {\n  const src = block.attrs?.src || '';\n  const alt = escapeXml(block.attrs?.alt || 'Image');\n\n  const relId = collector && src ? collector.add(src) : null;\n  if (relId) {\n    const cx = lengthToEmu(block.attrs?.width, 400);\n    const cy = lengthToEmu(block.attrs?.height, 300);\n    const docPrId = collector!.images.length;\n    return (\n      '<w:r><w:drawing' +\n      ' xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"' +\n      ' xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"' +\n      ' xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"' +\n      ' xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">' +\n      `<wp:inline distT=\"0\" distB=\"0\" distL=\"0\" distR=\"0\">` +\n      `<wp:extent cx=\"${cx}\" cy=\"${cy}\"/>` +\n      `<wp:docPr id=\"${docPrId}\" name=\"Picture ${docPrId}\" descr=\"${alt}\"/>` +\n      '<a:graphic><a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">' +\n      '<pic:pic>' +\n      `<pic:nvPicPr><pic:cNvPr id=\"0\" name=\"Picture ${docPrId}\"/><pic:cNvPicPr/></pic:nvPicPr>` +\n      `<pic:blipFill><a:blip r:embed=\"${relId}\"/><a:stretch><a:fillRect/></a:stretch></pic:blipFill>` +\n      `<pic:spPr><a:xfrm><a:off x=\"0\" y=\"0\"/><a:ext cx=\"${cx}\" cy=\"${cy}\"/></a:xfrm>` +\n      '<a:prstGeom prst=\"rect\"><a:avLst/></a:prstGeom></pic:spPr>' +\n      '</pic:pic></a:graphicData></a:graphic>' +\n      '</wp:inline></w:drawing></w:r>'\n    );\n  }\n\n  // No collector, or the src couldn't be embedded — best-effort placeholder\n  // so round-tripping never silently loses the fact an image was there.\n  return `<w:r><w:t>[Image: ${alt}]</w:t></w:r>`;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Runs → XML converter                                                        */\n/* -------------------------------------------------------------------------- */\n\nlet revisionIdCounter = 0;\n\nfunction trackChangeMark(node: any): { type: 'insertion' | 'deletion'; attrs: any } | undefined {\n  return (node.marks ?? []).find((m: any) => m.type === 'insertion' || m.type === 'deletion');\n}\n\n// Wraps a run's XML in `<w:ins>`/`<w:del>` when it carries a track-changes\n// mark, so suggestions round-trip as real Word redlines.\nfunction wrapTrackChange(xml: string, node: any): string {\n  const mark = trackChangeMark(node);\n  if (!mark) return xml;\n  const id = revisionIdCounter++;\n  const author = escapeXml(mark.attrs?.author || 'Unknown');\n  const date = mark.attrs?.date || new Date().toISOString();\n  const tag = mark.type === 'insertion' ? 'ins' : 'del';\n  return `<w:${tag} w:id=\"${id}\" w:author=\"${author}\" w:date=\"${date}\">${xml}</w:${tag}>`;\n}\n\nfunction nodeRunXml(node: any, collector?: ImageCollector): string {\n  if (node.type === 'text') {\n    const isDeleted = trackChangeMark(node)?.type === 'deletion';\n    return wrapTrackChange(textRunToXml(node, collector, isDeleted), node);\n  }\n  if (node.type === 'hardBreak') return '<w:r><w:br/></w:r>';\n  if (node.type === 'image') return imageRunXml(node, collector); // inline image run\n  return '';\n}\n\nfunction commentId(node: any): string | undefined {\n  return (node.marks ?? []).find((m: any) => m.type === 'comment')?.attrs?.id;\n}\n\nfunction contentControlMark(node: any): { id?: string; tag?: string; alias?: string } | undefined {\n  return (node.marks ?? []).find((m: any) => m.type === 'contentControl')?.attrs;\n}\n\nfunction bookmarkName(node: any): string | undefined {\n  return (node.marks ?? []).find((m: any) => m.type === 'bookmark')?.attrs?.name;\n}\n\nfunction fieldInstr(node: any): string | undefined {\n  return (node.marks ?? []).find((m: any) => m.type === 'field')?.attrs?.instr;\n}\n\n// Composite range key: contiguous nodes sharing the exact same comment/\n// content-control/bookmark/field combination get bracketed together in one go.\nfunction rangeKey(node: any): string | null {\n  const cc = contentControlMark(node);\n  // Group by cc's id when present, else a shared marker so id-less content\n  // controls still bracket together (not by falling through to null).\n  const key = { comment: commentId(node), cc: cc ? (cc.id ?? '\\u0000') : undefined, bookmark: bookmarkName(node), field: fieldInstr(node) };\n  if (!key.comment && !key.cc && !key.bookmark && !key.field) return null;\n  return JSON.stringify(key);\n}\n\nlet bookmarkIdCounter = 0;\n\nfunction runsToXml(content: any[], collector?: ImageCollector): string {\n  if (!content || content.length === 0) return '';\n\n  const parts: string[] = [];\n  let i = 0;\n  while (i < content.length) {\n    const key = rangeKey(content[i]);\n    if (!key) {\n      parts.push(nodeRunXml(content[i], collector));\n      i++;\n      continue;\n    }\n    // Group consecutive runs sharing the same comment/content-control/\n    // bookmark combination into one bracket, matching how Word anchors these.\n    let j = i;\n    const groupXml: string[] = [];\n    while (j < content.length && rangeKey(content[j]) === key) {\n      groupXml.push(nodeRunXml(content[j], collector));\n      j++;\n    }\n    let xml = groupXml.join('');\n\n    const cId = commentId(content[i]);\n    if (cId) {\n      const safeId = escapeXml(cId);\n      xml = `<w:commentRangeStart w:id=\"${safeId}\"/>${xml}<w:commentRangeEnd w:id=\"${safeId}\"/><w:r><w:commentReference w:id=\"${safeId}\"/></w:r>`;\n    }\n\n    const cc = contentControlMark(content[i]);\n    if (cc) {\n      const props =\n        (cc.tag ? `<w:tag w:val=\"${escapeXml(cc.tag)}\"/>` : '') +\n        (cc.alias ? `<w:alias w:val=\"${escapeXml(cc.alias)}\"/>` : '') +\n        (cc.id ? `<w:id w:val=\"${escapeXml(cc.id)}\"/>` : '');\n      xml = `<w:sdt><w:sdtPr>${props}</w:sdtPr><w:sdtContent>${xml}</w:sdtContent></w:sdt>`;\n    }\n\n    const bName = bookmarkName(content[i]);\n    if (bName) {\n      const bId = bookmarkIdCounter++;\n      const safeName = escapeXml(bName);\n      xml = `<w:bookmarkStart w:id=\"${bId}\" w:name=\"${safeName}\"/>${xml}<w:bookmarkEnd w:id=\"${bId}\"/>`;\n    }\n\n    const instr = fieldInstr(content[i]);\n    if (instr) xml = `<w:fldSimple w:instr=\"${escapeXml(instr)}\">${xml}</w:fldSimple>`;\n\n    parts.push(xml);\n    i = j;\n  }\n\n  return parts.join('');\n}\n\nfunction textRunToXml(node: any, collector?: ImageCollector, asDeleted = false): string {\n  const marks = node.marks ?? [];\n  const rPrParts: string[] = [];\n\n  for (const mark of marks) {\n    switch (mark.type) {\n      case 'bold':\n        rPrParts.push('<w:b/>');\n        break;\n      case 'italic':\n        rPrParts.push('<w:i/>');\n        break;\n      case 'underline':\n        rPrParts.push('<w:u w:val=\"single\"/>');\n        break;\n      case 'strike':\n        rPrParts.push('<w:strike/>');\n        break;\n      case 'superscript':\n        rPrParts.push('<w:vertAlign w:val=\"superscript\"/>');\n        break;\n      case 'subscript':\n        rPrParts.push('<w:vertAlign w:val=\"subscript\"/>');\n        break;\n      case 'textStyle':\n        if (mark.attrs?.color) {\n          const color = mark.attrs.color.replace('#', '');\n          rPrParts.push(`<w:color w:val=\"${color}\"/>`);\n        }\n        if (mark.attrs?.fontSize) {\n          const px = parseFloat(mark.attrs.fontSize);\n          if (!isNaN(px)) {\n            const halfPoints = pxToHalfPoints(px);\n            rPrParts.push(`<w:sz w:val=\"${halfPoints}\"/>`);\n          }\n        }\n        if (mark.attrs?.fontFamily) {\n          const font = escapeXml(mark.attrs.fontFamily.split(',')[0].trim().replace(/\"/g, ''));\n          // `w:cs` covers complex scripts (Sinhala/Tamil run through it), so a\n          // Sinhala document keeps its font in Word instead of falling back to\n          // the theme's Latin face.\n          rPrParts.push(`<w:rFonts w:ascii=\"${font}\" w:hAnsi=\"${font}\" w:cs=\"${font}\"/>`);\n        }\n        if (mark.attrs?.letterSpacing) {\n          // CSS letter-spacing (px) → OOXML `w:spacing`, which is in twentieths\n          // of a point. Negative (tightened) values are legal in both.\n          const px = parseFloat(mark.attrs.letterSpacing);\n          if (!isNaN(px)) rPrParts.push(`<w:spacing w:val=\"${Math.round((px / PX_PER_POINT) * 20)}\"/>`);\n        }\n        if (mark.attrs?.backgroundColor) {\n          const fill = String(mark.attrs.backgroundColor).replace('#', '');\n          rPrParts.push(`<w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\"${fill}\"/>`);\n        }\n        break;\n      case 'textTransform':\n        // Word has no lowercase/capitalize run property — only all-caps and\n        // small-caps — so those two are left to render as authored.\n        if (mark.attrs?.transform === 'uppercase') rPrParts.push('<w:caps/>');\n        break;\n      case 'highlight':\n        if (mark.attrs?.color) {\n          const colorName = hexToHighlightName(mark.attrs.color);\n          rPrParts.push(`<w:highlight w:val=\"${colorName}\"/>`);\n        }\n        break;\n      case 'link':\n        // Links need relationship management — skip rPr, handle at paragraph level\n        break;\n    }\n  }\n\n  const rPr = rPrParts.length > 0 ? `<w:rPr>${rPrParts.join('')}</w:rPr>` : '';\n  const text = escapeXml(node.text || '');\n  // Deleted text goes in `<w:delText>`, not `<w:t>` — Word ignores `<w:t>`\n  // inside `<w:del>`.\n  const textTag = asDeleted ? 'delText' : 't';\n\n  // Check if this run has a link mark. `Hyperlink` is a character style\n  // defined in styles.xml (blue + underlined), matching how the editor draws\n  // links on screen — Word won't style a bare hyperlink run otherwise.\n  const linkMark = marks.find((m: any) => m.type === 'link');\n  const href = linkMark?.attrs?.href;\n  // An internal link (from a `bookmark` mark's name, imported as `#name`)\n  // uses `w:anchor`, not a relationship — there's nothing to add to rels.xml.\n  if (href?.startsWith('#')) {\n    const linkRPr = `<w:rPr><w:rStyle w:val=\"Hyperlink\"/>${rPrParts.join('')}</w:rPr>`;\n    return `<w:hyperlink w:anchor=\"${escapeXml(href.slice(1))}\" w:history=\"1\"><w:r>${linkRPr}<w:${textTag} xml:space=\"preserve\">${text}</w:${textTag}></w:r></w:hyperlink>`;\n  }\n  if (href && collector) {\n    const relId = collector.addLink(String(href));\n    const linkRPr = `<w:rPr><w:rStyle w:val=\"Hyperlink\"/>${rPrParts.join('')}</w:rPr>`;\n    return `<w:hyperlink r:id=\"${relId}\" w:history=\"1\"><w:r>${linkRPr}<w:${textTag} xml:space=\"preserve\">${text}</w:${textTag}></w:r></w:hyperlink>`;\n  }\n  if (href) {\n    // No collector to register the relationship with (e.g. a caller\n    // serializing a fragment) — emit a styled run rather than a\n    // `<w:hyperlink>` pointing at an id that won't exist in the package.\n    const linkRPr = `<w:rPr><w:rStyle w:val=\"Hyperlink\"/>${rPrParts.join('')}</w:rPr>`;\n    return `<w:r>${linkRPr}<w:${textTag} xml:space=\"preserve\">${text}</w:${textTag}></w:r>`;\n  }\n\n  return `<w:r>${rPr}<w:${textTag} xml:space=\"preserve\">${text}</w:${textTag}></w:r>`;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Selective XML patch                                                         */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Patch only the changed <w:p> elements in the original document.xml.\n *\n * This finds all <w:p> and <w:tbl> elements in the original XML,\n * replaces the ones at the given indices with the new XML, and\n * preserves everything else byte-for-byte.\n *\n * @param originalXml - The original word/document.xml string\n * @param changedParagraphs - Array of { index, xml } from serializeTipTapToOOXML\n * @returns Patched document.xml string\n */\nexport function patchDocumentXml(\n  originalXml: string,\n  changedParagraphs: Array<{ index: number; xml: string }>,\n): string {\n  if (changedParagraphs.length === 0) return originalXml;\n\n  if (typeof DOMParser === 'undefined') {\n    return originalXml; // Can't patch without DOMParser\n  }\n\n  try {\n    const doc = new DOMParser().parseFromString(originalXml, 'text/xml');\n    const body = doc.getElementsByTagName('w:body')[0];\n    if (!body) return originalXml;\n\n    // Collect all top-level children of body (w:p, w:tbl, etc.)\n    const children: Element[] = [];\n    for (let i = 0; i < body.children.length; i++) {\n      const child = body.children[i];\n      const tag = child.localName || child.tagName.replace(/.*:/, '');\n      if (tag === 'p' || tag === 'tbl') {\n        children.push(child);\n      }\n    }\n\n    // Apply patches\n    const changedMap = new Map(changedParagraphs.map((p) => [p.index, p.xml]));\n    for (let i = 0; i < children.length; i++) {\n      if (changedMap.has(i)) {\n        const newXml = changedMap.get(i)!;\n        const newEl = new DOMParser().parseFromString(newXml, 'text/xml').documentElement;\n        body.replaceChild(newEl, children[i]);\n      }\n    }\n\n    // Serialize back to string\n    const serializer = new XMLSerializer();\n    return serializer.serializeToString(doc);\n  } catch (e) {\n    console.warn('[docx-editor] Selective XML patch failed:', e);\n    return originalXml;\n  }\n}\n\n/* -------------------------------------------------------------------------- */\n/* Rezip — patch files in a .docx ZIP                                         */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Patch specific files in a .docx ZIP archive without rebuilding everything.\n *\n * @param docxBuffer - Original .docx as ArrayBuffer\n * @param patches - Map of { filePath: newContent } (string or ArrayBuffer)\n * @returns New .docx ArrayBuffer with patched files\n */\nexport async function rezipDocx(\n  docxBuffer: ArrayBuffer,\n  patches: Map<string, string | ArrayBuffer>,\n): Promise<ArrayBuffer> {\n  const JSZip = await getJSZip();\n  const zip = await JSZip.loadAsync(docxBuffer);\n\n  for (const [path, content] of patches) {\n    zip.file(path, content);\n  }\n\n  return zip.generateAsync({\n    type: 'arraybuffer',\n    compression: 'DEFLATE',\n    compressionOptions: { level: 6 },\n  });\n}\n\n/* -------------------------------------------------------------------------- */\n/* Full save with selective patching                                          */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Save TipTap JSON to a .docx ArrayBuffer with selective XML patching.\n *\n * If originalBuffer is provided, only changed paragraphs are patched into\n * the original XML — preserving unchanged content byte-for-byte.\n * If originalBuffer is not provided, a full document is generated.\n *\n * @param json - TipTap document JSON\n * @param originalBuffer - Original .docx ArrayBuffer (for selective patching)\n * @param changedBlockIndices - Set of block indices that changed (for selective patching)\n * @param pageDimensions - Page size/margins in twips, from `resolvePageDimensionsTwips()`\n *   (`../page-setup`). Applied to the \"full save\" branch below (replacing\n *   `document.xml`'s `<w:sectPr>`) and to the no-`originalBuffer` fresh-build\n *   branch. Defaults to US Letter when omitted.\n * @returns .docx ArrayBuffer\n */\nexport async function saveDocxSelective(\n  json: any,\n  originalBuffer?: ArrayBuffer,\n  changedBlockIndices?: Set<number>,\n  pageDimensions?: PageDimensionsTwips,\n): Promise<ArrayBuffer> {\n  // No original document to patch into — there's no OOXML skeleton (media\n  // rels, content types, styles, etc.) to embed images into, so build a\n  // fresh .docx with the `docx` library instead. `saveDocxFromJSON`\n  // (io/save.ts) already embeds images properly via `ImageRun`, so this\n  // still produces a valid .docx with images intact.\n  if (!originalBuffer) {\n    const { saveDocxFromJSON } = await import('./save');\n    const blob = await saveDocxFromJSON(json, { pageDimensions });\n    return blob.arrayBuffer();\n  }\n\n  const JSZip = await getJSZip();\n  const zip = await JSZip.loadAsync(originalBuffer);\n\n  // Figure out where to start numbering new relationships/media files so\n  // they never collide with ones already in the original .docx.\n  const { nextRelIdNum, nextMediaNum } = await computeNextImageIds(zip);\n  const imageCollector = new ImageCollector(nextRelIdNum, nextMediaNum);\n\n  // Read the original document's numbering definitions (if any) so lists\n  // resolve to a real numId instead of an assumed one — see `resolveNumId`.\n  const numberingXml = await zip.file('word/numbering.xml')?.async('string');\n  const numberingMap = numberingXml ? parseNumberingXml(numberingXml) : undefined;\n\n  const serializeResult = serializeTipTapToOOXML(json, { changedBlockIndices, imageCollector, numberingMap, pageDimensions });\n\n  // Embed any images collected during serialization: media bytes +\n  // relationship + content-type registration. Must happen before we\n  // generate the zip, and before/regardless of which body-patch strategy\n  // below is used, since both reference the same `r:embed` ids.\n  await applyImageCollectorToZip(zip, imageCollector);\n\n  if (changedBlockIndices && changedBlockIndices.size > 0) {\n    // Selective save: patch only the changed <w:p>/<w:tbl> elements,\n    // preserving everything else in document.xml byte-for-byte.\n    const originalDocXml = await zip.file('word/document.xml')?.async('string');\n    if (originalDocXml) {\n      const patchedXml = patchDocumentXml(originalDocXml, serializeResult.changedParagraphs);\n      zip.file('word/document.xml', patchedXml);\n    }\n  } else {\n    // Full save: replace the entire document.xml body. The root element\n    // declares every namespace prefix used anywhere in the body — including\n    // `wp`/`a`/`pic` for embedded images — since this string is written\n    // directly into the zip (not re-parsed with ambient namespace context).\n    const docXml =\n      '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>' +\n      '<w:document' +\n      ' xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"' +\n      ' xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"' +\n      ' xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"' +\n      ' xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"' +\n      ' xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">' +\n      serializeResult.bodyXml +\n      '</w:document>';\n    zip.file('word/document.xml', docXml);\n  }\n\n  return zip.generateAsync({\n    type: 'arraybuffer',\n    compression: 'DEFLATE',\n    compressionOptions: { level: 6 },\n  });\n}\n\n/* -------------------------------------------------------------------------- */\n/* Helpers                                                                     */\n/* -------------------------------------------------------------------------- */\n\nfunction escapeXml(text: string): string {\n  return text\n    .replace(/&/g, '&amp;')\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;')\n    .replace(/\"/g, '&quot;')\n    .replace(/'/g, '&apos;');\n}\n\n// Highlight color mapping lives in `./ooxml-marks` (see `hexToHighlightName`)\n// — shared with the parser so both directions of the round-trip use the\n// exact same table, instead of this file keeping its own partial copy.\n","/**\n * Headless DOCX processing — server-side utilities with no DOM dependency.\n *\n * This module provides functions for processing .docx files without a browser:\n *   - parseDocx(): extract text + structure from a .docx ArrayBuffer\n *   - serializeDocx(): create a .docx from structured content\n *   - extractText(): get plain text from a .docx\n *   - extractStructure(): get block structure (headings, paragraphs, tables)\n *   - mergeDocx(): merge multiple .docx files into one\n *\n * All functions work in Node.js (server-side) without any DOM.\n *\n * Usage:\n *   import { parseDocx, extractText, processTemplate } from '@shashimadushan/docx-editor-editor/headless';\n *\n *   const buffer = fs.readFileSync('document.docx').buffer;\n *   const text = await extractText(buffer);\n *   const structure = await extractStructure(buffer);\n */\n\n// Re-export OOXML parser and serializer for headless use\nexport { parseDocxOOXML, readPageSetupFromDocx } from './io/ooxml-parser';\nexport type { ParsedOOXML, StyleDef, DocxMetadata } from './io/ooxml-parser';\nexport { serializeTipTapToOOXML, patchDocumentXml, rezipDocx, saveDocxSelective } from './io/ooxml-serializer';\nexport type { SerializeOptions, SerializeResult } from './io/ooxml-serializer';\n\n// Re-export template processing\nexport {\n  processTemplate,\n  getTemplateTags,\n  validateTemplate,\n  previewTemplate,\n  type ProcessTemplateOptions,\n  type ProcessTemplateResult,\n} from './io/template';\n\n// Re-export native PDF export (Node-only — requires `puppeteer`, an\n// optional peer dependency; see io/pdf.ts for why this can't run in-browser\n// and isn't just a call to Tiptap's paid cloud conversion service instead).\nexport { renderHtmlToPdf, type PdfRenderInput, type PdfRenderOptions } from './io/pdf';\n\n// Lazy-load dependencies\nlet JSZip: any = null;\nlet mammoth: any = null;\n\nasync function getJSZip(): Promise<any> {\n  if (JSZip) return JSZip;\n  const mod = await import('jszip');\n  JSZip = mod.default || mod;\n  return JSZip;\n}\n\nasync function getMammoth(): Promise<any> {\n  if (mammoth) return mammoth;\n  const mod = await import('mammoth');\n  mammoth = mod.default || mod;\n  return mammoth;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Types                                                                       */\n/* -------------------------------------------------------------------------- */\n\nexport interface DocxBlock {\n  type: 'heading' | 'paragraph' | 'table' | 'list' | 'image' | 'codeBlock' | 'blockquote' | 'horizontalRule' | 'unknown';\n  text?: string;\n  level?: number; // for headings (1-6)\n  listType?: 'bullet' | 'ordered'; // for lists\n  items?: string[]; // for lists\n  rows?: string[][]; // for tables (row × col)\n  imageSrc?: string; // for images (data URI)\n}\n\nexport interface ParsedDocx {\n  /** Plain text content of the document. */\n  text: string;\n  /** HTML content (from mammoth). */\n  html: string;\n  /** Structured blocks. */\n  blocks: DocxBlock[];\n  /** Document metadata (from core.xml). */\n  metadata: {\n    title?: string;\n    creator?: string;\n    created?: string;\n    modified?: string;\n    subject?: string;\n    description?: string;\n  };\n  /** Conversion warnings from mammoth. */\n  warnings: Array<{ type: string; message: string }>;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Parse functions                                                            */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Parse a .docx ArrayBuffer into text, HTML, structured blocks, and metadata.\n *\n * Works server-side (no DOM required).\n */\nexport async function parseDocx(buffer: ArrayBuffer): Promise<ParsedDocx> {\n  const [mammothMod, JSZipMod] = await Promise.all([getMammoth(), getJSZip()]);\n\n  // 1. Convert to HTML + text via mammoth\n  const mammothResult = await mammothMod.convertToHtml(\n    { buffer },\n    {\n      styleMap: [\n        \"p[style-name='Heading 1'] => h1:fresh\",\n        \"p[style-name='Heading 2'] => h2:fresh\",\n        \"p[style-name='Heading 3'] => h3:fresh\",\n        \"p[style-name='Heading 4'] => h4:fresh\",\n        \"p[style-name='Heading 5'] => h5:fresh\",\n        \"p[style-name='Heading 6'] => h6:fresh\",\n        \"p[style-name='Title'] => h1.docx-title:fresh\",\n        \"p[style-name='Quote'] => blockquote:fresh\",\n        \"p[style-name='Code'] => pre:fresh\",\n      ],\n    },\n  );\n\n  const html = mammothResult.value || '<p></p>';\n  const warnings = mammothResult.messages ?? [];\n\n  // 2. Extract plain text (strip HTML tags)\n  const text = htmlToText(html);\n\n  // 3. Extract structured blocks from HTML\n  const blocks = htmlToBlocks(html);\n\n  // 4. Extract metadata from core.xml\n  const metadata = await extractMetadata(buffer, JSZipMod);\n\n  return { text, html, blocks, metadata, warnings };\n}\n\n/**\n * Extract plain text from a .docx ArrayBuffer.\n * Server-side safe (no DOM).\n */\nexport async function extractText(buffer: ArrayBuffer): Promise<string> {\n  const mammothMod = await getMammoth();\n  const result = await mammothMod.extractRawText({ buffer });\n  return result.value || '';\n}\n\n/**\n * Extract structured blocks (headings, paragraphs, tables, lists) from a .docx.\n * Server-side safe.\n */\nexport async function extractStructure(buffer: ArrayBuffer): Promise<DocxBlock[]> {\n  const mammothMod = await getMammoth();\n  const result = await mammothMod.convertToHtml(\n    { buffer },\n    {\n      styleMap: [\n        \"p[style-name='Heading 1'] => h1:fresh\",\n        \"p[style-name='Heading 2'] => h2:fresh\",\n        \"p[style-name='Heading 3'] => h3:fresh\",\n        \"p[style-name='Heading 4'] => h4:fresh\",\n        \"p[style-name='Heading 5'] => h5:fresh\",\n        \"p[style-name='Heading 6'] => h6:fresh\",\n        \"p[style-name='Quote'] => blockquote:fresh\",\n        \"p[style-name='Code'] => pre:fresh\",\n      ],\n    },\n  );\n  return htmlToBlocks(result.value || '');\n}\n\n/**\n * Extract document metadata (title, author, dates) from core.xml.\n */\nexport async function extractMetadata(\n  buffer: ArrayBuffer,\n  zip?: any,\n): Promise<ParsedDocx['metadata']> {\n  const JSZipMod = zip || (await getJSZip());\n  const doc = await JSZipMod.loadAsync(buffer);\n\n  const coreFile = doc.file('docProps/core.xml');\n  if (!coreFile) return {};\n\n  const xml = await coreFile.async('string');\n  return parseCoreXml(xml);\n}\n\n/* -------------------------------------------------------------------------- */\n/* Serialize functions                                                        */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Create a .docx ArrayBuffer from a simple content structure.\n * Uses the `docx` library to build the document.\n *\n * Server-side safe.\n */\nexport async function serializeDocx(\n  blocks: DocxBlock[],\n  options: { title?: string; creator?: string } = {},\n): Promise<ArrayBuffer> {\n  const docxMod = await import('docx');\n  const {\n    Document, Packer, Paragraph, TextRun, HeadingLevel, Table, TableRow, TableCell,\n    WidthType, BorderStyle,\n  } = docxMod;\n\n  const children: any[] = [];\n\n  for (const block of blocks) {\n    switch (block.type) {\n      case 'heading': {\n        const level = block.level ?? 2;\n        const headingLevel = [HeadingLevel.HEADING_1, HeadingLevel.HEADING_2, HeadingLevel.HEADING_3,\n          HeadingLevel.HEADING_4, HeadingLevel.HEADING_5, HeadingLevel.HEADING_6][level - 1] ?? HeadingLevel.HEADING_2;\n        children.push(new Paragraph({ children: [new TextRun(block.text ?? '')], heading: headingLevel }));\n        break;\n      }\n      case 'paragraph':\n        children.push(new Paragraph({ children: [new TextRun(block.text ?? '')] }));\n        break;\n      case 'blockquote':\n        children.push(new Paragraph({\n          children: [new TextRun({ text: block.text ?? '', italics: true })],\n          indent: { left: 720 },\n        }));\n        break;\n      case 'codeBlock':\n        children.push(new Paragraph({\n          children: [new TextRun({ text: block.text ?? '', font: 'Courier New', size: 20 })],\n        }));\n        break;\n      case 'list': {\n        if (block.items) {\n          for (const item of block.items) {\n            children.push(new Paragraph({\n              children: [new TextRun({ text: block.listType === 'ordered' ? '• ' : '1. ' }), new TextRun(item)],\n              indent: { left: 360 },\n            }));\n          }\n        }\n        break;\n      }\n      case 'table': {\n        if (block.rows) {\n          const rows = block.rows.map((rowData) => new TableRow({\n            children: rowData.map((cellText) => new TableCell({\n              children: [new Paragraph(cellText)],\n            })),\n          }));\n          children.push(new Table({ rows, width: { size: 100, type: WidthType.PERCENTAGE } }));\n        }\n        break;\n      }\n      case 'horizontalRule':\n        children.push(new Paragraph({\n          border: { bottom: { color: '999999', style: BorderStyle.SINGLE, size: 6, space: 1 } },\n        }));\n        break;\n      default:\n        if (block.text) {\n          children.push(new Paragraph({ children: [new TextRun(block.text)] }));\n        }\n    }\n  }\n\n  const doc = new Document({\n    creator: options.creator ?? 'docx-editor-toolkit',\n    title: options.title ?? 'Untitled',\n    sections: [{ children }],\n  });\n\n  const blob = await Packer.toBlob(doc);\n  return blob.arrayBuffer();\n}\n\n/* -------------------------------------------------------------------------- */\n/* Merge functions                                                            */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Merge multiple .docx files into one.\n * Extracts text from each and creates a new combined document.\n */\nexport async function mergeDocx(buffers: ArrayBuffer[]): Promise<ArrayBuffer> {\n  const allBlocks: DocxBlock[] = [];\n  for (const buffer of buffers) {\n    const parsed = await parseDocx(buffer);\n    allBlocks.push(...parsed.blocks);\n    // Add a separator between documents\n    allBlocks.push({ type: 'horizontalRule' });\n  }\n  return serializeDocx(allBlocks);\n}\n\n/* -------------------------------------------------------------------------- */\n/* Helpers                                                                    */\n/* -------------------------------------------------------------------------- */\n\n/** Strip HTML tags to get plain text. No DOM dependency. */\nfunction htmlToText(html: string): string {\n  return html\n    .replace(/<[^>]+>/g, ' ')\n    .replace(/&nbsp;/g, ' ')\n    .replace(/&amp;/g, '&')\n    .replace(/&lt;/g, '<')\n    .replace(/&gt;/g, '>')\n    .replace(/&quot;/g, '\"')\n    .replace(/&#39;/g, \"'\")\n    .replace(/\\s+/g, ' ')\n    .trim();\n}\n\n/** Parse HTML string into structured blocks. No DOM dependency (uses regex). */\nfunction htmlToBlocks(html: string): DocxBlock[] {\n  const blocks: DocxBlock[] = [];\n  // Simple regex-based parser (not perfect but works for mammoth output)\n  const tagRegex = /<(h[1-6]|p|ul|ol|pre|blockquote|hr|table|img)[^>]*>([\\s\\S]*?)<\\/\\1>|<(hr|img)[^>]*\\/?>/gi;\n  let match: RegExpExecArray | null;\n\n  while ((match = tagRegex.exec(html)) !== null) {\n    const tag = (match[1] || match[3] || '').toLowerCase();\n    const content = match[2] || '';\n\n    switch (tag) {\n      case 'h1': case 'h2': case 'h3': case 'h4': case 'h5': case 'h6':\n        blocks.push({ type: 'heading', level: parseInt(tag[1]), text: htmlToText(content) });\n        break;\n      case 'p':\n        blocks.push({ type: 'paragraph', text: htmlToText(content) });\n        break;\n      case 'ul':\n        blocks.push({ type: 'list', listType: 'bullet', items: extractListItems(content) });\n        break;\n      case 'ol':\n        blocks.push({ type: 'list', listType: 'ordered', items: extractListItems(content) });\n        break;\n      case 'pre':\n        blocks.push({ type: 'codeBlock', text: htmlToText(content) });\n        break;\n      case 'blockquote':\n        blocks.push({ type: 'blockquote', text: htmlToText(content) });\n        break;\n      case 'hr':\n        blocks.push({ type: 'horizontalRule' });\n        break;\n      case 'table':\n        blocks.push({ type: 'table', rows: extractTableRows(content) });\n        break;\n      case 'img':\n        const srcMatch = match[0].match(/src=\"([^\"]+)\"/);\n        blocks.push({ type: 'image', imageSrc: srcMatch?.[1] });\n        break;\n    }\n  }\n\n  return blocks;\n}\n\nfunction extractListItems(html: string): string[] {\n  const items: string[] = [];\n  const regex = /<li[^>]*>([\\s\\S]*?)<\\/li>/gi;\n  let match: RegExpExecArray | null;\n  while ((match = regex.exec(html)) !== null) {\n    items.push(htmlToText(match[1]));\n  }\n  return items;\n}\n\nfunction extractTableRows(html: string): string[][] {\n  const rows: string[][] = [];\n  const rowRegex = /<tr[^>]*>([\\s\\S]*?)<\\/tr>/gi;\n  let rowMatch: RegExpExecArray | null;\n  while ((rowMatch = rowRegex.exec(html)) !== null) {\n    const cells: string[] = [];\n    const cellRegex = /<t[dh][^>]*>([\\s\\S]*?)<\\/t[dh]>/gi;\n    let cellMatch: RegExpExecArray | null;\n    while ((cellMatch = cellRegex.exec(rowMatch[1])) !== null) {\n      cells.push(htmlToText(cellMatch[1]));\n    }\n    if (cells.length > 0) rows.push(cells);\n  }\n  return rows;\n}\n\nfunction parseCoreXml(xml: string): ParsedDocx['metadata'] {\n  const get = (tag: string): string | undefined => {\n    const match = xml.match(new RegExp(`<(?:cp|dc|dcterms|ep|cp):${tag}[^>]*>([^<]*)<`));\n    return match?.[1]?.trim();\n  };\n  return {\n    title: get('title'),\n    creator: get('creator'),\n    created: get('created'),\n    modified: get('modified'),\n    subject: get('subject'),\n    description: get('description'),\n  };\n}\n","/**\n * Docxtemplater plugin — template variable substitution for .docx files.\n *\n * Supports the docxtemplater syntax:\n *   - {variable}           — simple variable substitution\n *   - {#loop}...{/loop}    — repeat content for each item in an array\n *   - {#cond}...{/cond}    — conditional inclusion (truthy = show)\n *   - {-w:image}           — image substitution (with base64 data)\n *\n * All formatting (fonts, styles, colors, tables) is preserved because\n * docxtemplater operates on the raw OOXML XML, not on rendered HTML.\n *\n * Usage:\n *   import { processTemplate } from '@shashimadushan/docx-editor-editor/headless';\n *\n *   const result = processTemplate(docxBuffer, {\n *     name: 'John Doe',\n *     date: '2026-01-15',\n *     items: [{ name: 'Item 1' }, { name: 'Item 2' }],\n *   });\n *   // result.buffer = processed .docx ArrayBuffer\n *\n * Can be used server-side (no DOM required).\n */\n\n// Lazy-load dependencies\nlet PizZip: any = null;\nlet Docxtemplater: any = null;\n\nasync function loadDeps(): Promise<void> {\n  if (PizZip && Docxtemplater) return;\n  const [pizMod, docxMod] = await Promise.all([\n    import('pizzip'),\n    import('docxtemplater'),\n  ]);\n  PizZip = pizMod.default || pizMod;\n  Docxtemplater = docxMod.default || docxMod;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Types                                                                       */\n/* -------------------------------------------------------------------------- */\n\nexport interface ProcessTemplateOptions {\n  /** How to handle undefined variables: 'keep' (leave tag as-is), 'empty' (remove), 'error' (throw). Default: 'keep'. */\n  nullGetter?: 'keep' | 'empty' | 'error';\n  /** Convert \\n in values to <w:br/> (Word line breaks). Default: true. */\n  linebreaks?: boolean;\n  /** Custom delimiters (default: { and }). */\n  delimiters?: { start?: string; end?: string };\n}\n\nexport interface ProcessTemplateResult {\n  /** The processed document buffer. */\n  buffer: ArrayBuffer;\n  /** Variables that were found and replaced. */\n  replacedVariables: string[];\n  /** Variables that were not replaced (no value provided). */\n  unreplacedVariables: string[];\n  /** Any warnings during processing. */\n  warnings: string[];\n}\n\nexport interface TemplateError {\n  message: string;\n  variable?: string;\n  type: 'parse' | 'render' | 'undefined' | 'unknown';\n  originalError?: Error;\n}\n\nexport interface TemplateValidation {\n  valid: boolean;\n  errors: TemplateError[];\n  tags: string[];\n}\n\n/* -------------------------------------------------------------------------- */\n/* Main functions                                                             */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Process a DOCX template with variable substitution.\n *\n * @param buffer - The DOCX file as ArrayBuffer\n * @param variables - Map of variable names to values (strings, arrays, or nested objects)\n * @param options - Processing options\n * @returns Processed DOCX as ArrayBuffer\n */\nexport async function processTemplate(\n  buffer: ArrayBuffer,\n  variables: Record<string, unknown>,\n  options: ProcessTemplateOptions = {},\n): Promise<ProcessTemplateResult> {\n  await loadDeps();\n  const { nullGetter = 'keep', linebreaks = true, delimiters } = options;\n\n  const warnings: string[] = [];\n  const replacedVariables: string[] = [];\n  const unreplacedVariables: string[] = [];\n\n  try {\n    const zip = new PizZip(buffer);\n    const doc = new Docxtemplater(zip, {\n      paragraphLoop: true,\n      linebreaks,\n      nullGetter: (part: { value?: string }) => {\n        const varName = part.value || '';\n        if (nullGetter === 'error') {\n          throw new Error(`Undefined variable: ${varName}`);\n        }\n        if (nullGetter === 'empty') {\n          unreplacedVariables.push(varName);\n          return '';\n        }\n        unreplacedVariables.push(varName);\n        return `{${varName}}`;\n      },\n      delimiters: delimiters\n        ? { start: delimiters.start || '{', end: delimiters.end || '}' }\n        : undefined,\n    });\n\n    Object.keys(variables).forEach((key) => {\n      if (variables[key] !== undefined && variables[key] !== null) {\n        replacedVariables.push(key);\n      }\n    });\n\n    // New API: pass data to render() directly (avoids deprecated setData)\n    doc.render(variables);\n\n    const outputBuffer = doc.getZip().generate({\n      type: 'arraybuffer',\n      compression: 'DEFLATE',\n      compressionOptions: { level: 6 },\n    });\n\n    return { buffer: outputBuffer, replacedVariables, unreplacedVariables, warnings };\n  } catch (error) {\n    throw formatTemplateError(error);\n  }\n}\n\n/**\n * Process template and return as Blob (for download).\n */\nexport async function processTemplateAsBlob(\n  buffer: ArrayBuffer,\n  variables: Record<string, unknown>,\n  options: ProcessTemplateOptions = {},\n): Promise<Blob> {\n  const result = await processTemplate(buffer, variables, options);\n  return new Blob([result.buffer], {\n    type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n  });\n}\n\n/**\n * Process template and trigger browser download.\n */\nexport async function processTemplateAndDownload(\n  buffer: ArrayBuffer,\n  variables: Record<string, unknown>,\n  filename: string = 'document',\n  options: ProcessTemplateOptions = {},\n): Promise<void> {\n  const blob = await processTemplateAsBlob(buffer, variables, options);\n  const url = URL.createObjectURL(blob);\n  const a = document.createElement('a');\n  a.href = url;\n  a.download = `${filename}.docx`;\n  document.body.appendChild(a);\n  a.click();\n  a.remove();\n  setTimeout(() => URL.revokeObjectURL(url), 1000);\n}\n\n/* -------------------------------------------------------------------------- */\n/* Validation & inspection                                                    */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Get all template tags in a document without processing.\n */\nexport async function getTemplateTags(buffer: ArrayBuffer): Promise<string[]> {\n  await loadDeps();\n  try {\n    const zip = new PizZip(buffer);\n    const doc = new Docxtemplater(zip, { paragraphLoop: true, linebreaks: true });\n    const fullText = doc.getFullText();\n    return extractTagsFromText(fullText);\n  } catch (error) {\n    throw formatTemplateError(error);\n  }\n}\n\n/**\n * Validate that a document is a valid docxtemplater template.\n */\nexport async function validateTemplate(buffer: ArrayBuffer): Promise<TemplateValidation> {\n  await loadDeps();\n  const errors: TemplateError[] = [];\n  let tags: string[] = [];\n\n  try {\n    const zip = new PizZip(buffer);\n    const doc = new Docxtemplater(zip, { paragraphLoop: true, linebreaks: true });\n    const fullText = doc.getFullText();\n    tags = extractTagsFromText(fullText);\n\n    const unclosed = findUnclosedTags(fullText);\n    for (const tag of unclosed) {\n      errors.push({ message: `Unclosed tag: ${tag}`, variable: tag, type: 'parse' });\n    }\n\n    return { valid: errors.length === 0, errors, tags };\n  } catch (error) {\n    errors.push(formatTemplateError(error));\n    return { valid: false, errors, tags };\n  }\n}\n\n/**\n * Check which required variables are missing.\n */\nexport function getMissingVariables(\n  tags: string[],\n  variables: Record<string, unknown>,\n): string[] {\n  return tags.filter(\n    (tag) => !(tag in variables) || variables[tag] === undefined || variables[tag] === null,\n  );\n}\n\n/**\n * Preview the document text with variables replaced (no formatting).\n */\nexport async function previewTemplate(\n  buffer: ArrayBuffer,\n  variables: Record<string, unknown>,\n): Promise<string> {\n  await loadDeps();\n  try {\n    const zip = new PizZip(buffer);\n    const doc = new Docxtemplater(zip, {\n      paragraphLoop: true,\n      linebreaks: true,\n      nullGetter: (part: { value?: string }) => `[${part.value || ''}]`,\n    });\n    doc.setData(variables);\n    doc.render();\n    return doc.getFullText();\n  } catch (error) {\n    throw formatTemplateError(error);\n  }\n}\n\n/* -------------------------------------------------------------------------- */\n/* Helpers                                                                    */\n/* -------------------------------------------------------------------------- */\n\nfunction extractTagsFromText(text: string): string[] {\n  const tags: string[] = [];\n  const regex = /\\{([^{}]+)\\}/g;\n  let match: RegExpExecArray | null;\n  while ((match = regex.exec(text)) !== null) {\n    const tag = match[1].trim();\n    if (tag && !tags.includes(tag)) tags.push(tag);\n  }\n  return tags.sort();\n}\n\nfunction findUnclosedTags(text: string): string[] {\n  const unclosed: string[] = [];\n  let depth = 0;\n  let currentTag = '';\n  for (const char of text) {\n    if (char === '{') { depth++; currentTag = ''; }\n    else if (char === '}') { depth--; if (depth < 0) depth = 0; }\n    else if (depth > 0) { currentTag += char; }\n  }\n  if (depth > 0 && currentTag.trim()) unclosed.push(currentTag.trim());\n  return unclosed;\n}\n\ninterface DocxTemplaterError extends Error {\n  properties?: { errors?: Array<{ message?: string; properties?: { tag?: string } }> };\n}\n\nfunction isDocxTemplaterError(error: Error): error is DocxTemplaterError {\n  return 'properties' in error && typeof (error as DocxTemplaterError).properties === 'object';\n}\n\nfunction formatTemplateError(error: unknown): TemplateError {\n  if (error instanceof Error) {\n    if (isDocxTemplaterError(error) && error.properties?.errors) {\n      const first = error.properties.errors[0];\n      return { message: first?.message || 'Template error', variable: first?.properties?.tag, type: 'render', originalError: error };\n    }\n    if (error.message.includes('undefined')) {\n      const match = error.message.match(/undefined (?:variable|tag):\\s*(\\S+)/i);\n      return { message: error.message, variable: match ? match[1] : undefined, type: 'undefined', originalError: error };\n    }\n    if (error.message.includes('parse') || error.message.includes('unclosed') || error.message.includes('syntax')) {\n      return { message: error.message, type: 'parse', originalError: error };\n    }\n    return { message: error.message, type: 'unknown', originalError: error };\n  }\n  return { message: String(error), type: 'unknown' };\n}\n","/**\n * Watermark — a repeating, tiled diagonal text overlay on the page.\n *\n * Implementation: we don't store the watermark in the document JSON (it's a\n * page-level property, not content). Instead, the DocxEditor class holds the\n * watermark state and renders it as a single absolutely-positioned overlay\n * (`inset: 0`) on the page element, whose `background-image` is a small SVG\n * tile containing one rotated instance of the watermark text, repeated via\n * `background-repeat: repeat`.\n *\n * Tiling (rather than one centered instance) is what makes this work for\n * BOTH view modes with the same code path:\n *   - 'paged': the page element's height already spans every simulated\n *     page, so the tile repeats down through all of them.\n *   - 'pageless': the page is one continuous flowing surface with no fixed\n *     height, so a single centered watermark would only ever be visible\n *     once, near the top. Tiling keeps it visible throughout.\n * The browser handles the repetition natively, so nothing needs to be\n * recomputed as the page grows (new pages added, more content typed, etc).\n *\n * This module exports:\n *   - WatermarkConfig type\n *   - Default presets (CONFIDENTIAL, DRAFT, DO NOT COPY, etc.)\n *   - createWatermarkElement — the (only) DOM builder\n */\n\nexport interface WatermarkConfig {\n  /** The text to show. */\n  text: string;\n  /** Font size in px. Default: 56. */\n  fontSize?: number;\n  /** Font family. Default: sans-serif. */\n  fontFamily?: string;\n  /** Text color (CSS). Default: 'rgba(208, 7, 7, 0.18)'. */\n  color?: string;\n  /** Rotation in degrees. Default: -30 (diagonal, bottom-left to top-right). */\n  rotation?: number;\n  /** Opacity 0-1. Default: 0.18. */\n  opacity?: number;\n}\n\nexport const DEFAULT_WATERMARK_PRESETS: Array<{ label: string; config: WatermarkConfig }> = [\n  {\n    label: 'CONFIDENTIAL',\n    config: { text: 'CONFIDENTIAL', color: 'rgba(208, 7, 7, 0.18)', fontSize: 64 },\n  },\n  {\n    label: 'DRAFT',\n    config: { text: 'DRAFT', color: 'rgba(180, 83, 9, 0.2)', fontSize: 64 },\n  },\n  {\n    label: 'DO NOT COPY',\n    config: { text: 'DO NOT COPY', color: 'rgba(208, 7, 7, 0.18)', fontSize: 56 },\n  },\n  {\n    label: 'SAMPLE',\n    config: { text: 'SAMPLE', color: 'rgba(37, 99, 235, 0.18)', fontSize: 64 },\n  },\n  {\n    label: 'URGENT',\n    config: { text: 'URGENT', color: 'rgba(180, 83, 9, 0.2)', fontSize: 64 },\n  },\n  {\n    label: 'FINAL',\n    config: { text: 'FINAL', color: 'rgba(22, 163, 74, 0.18)', fontSize: 64 },\n  },\n];\n\nexport const DEFAULT_WATERMARK: WatermarkConfig = {\n  text: '',\n  fontSize: 56,\n  fontFamily: 'sans-serif',\n  color: 'rgba(208, 7, 7, 0.18)',\n  rotation: -30,\n  opacity: 0.18,\n};\n\nfunction escapeXml(s: string): string {\n  return s\n    .replace(/&/g, '&amp;')\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;')\n    .replace(/\"/g, '&quot;');\n}\n\nexport interface WatermarkTile {\n  /** A `data:image/svg+xml;base64,...` URI — one rotated instance of the watermark text. */\n  dataUri: string;\n  tileWidth: number;\n  tileHeight: number;\n}\n\n/**\n * Build the repeating SVG tile a watermark renders as. Returns null if\n * there's no watermark text.\n *\n * Pure and DOM-free (only string/base64 work), so it's shared by both\n * `createWatermarkElement` (browser, wraps this in a DOM element) and the\n * Node-side PDF renderer (`io/pdf.ts`, which has no `document` to build an\n * element with but still needs the exact same tile — the watermark should\n * look identical on-screen and in an exported PDF, not be reimplemented\n * twice with a chance of drifting apart).\n */\nexport function buildWatermarkTile(config: WatermarkConfig | null): WatermarkTile | null {\n  if (!config || !config.text) return null;\n  const c = { ...DEFAULT_WATERMARK, ...config };\n  const fontSize = c.fontSize || 56;\n  // Tile size scales with font size so bigger text still has breathing\n  // room between repeats instead of overlapping itself.\n  const scale = fontSize / 56;\n  const tileW = Math.round(560 * scale);\n  const tileH = Math.round(340 * scale);\n  const rotation = c.rotation ?? -30;\n  const fill = c.color || 'rgba(208, 7, 7, 0.18)';\n  const opacity = c.opacity ?? 0.18;\n  const text = escapeXml(c.text.toUpperCase());\n\n  const svg = [\n    `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${tileW}\" height=\"${tileH}\">`,\n    `<text x=\"50%\" y=\"50%\" text-anchor=\"middle\" dominant-baseline=\"middle\"`,\n    ` transform=\"rotate(${rotation} ${tileW / 2} ${tileH / 2})\"`,\n    ` font-family=\"${c.fontFamily}\" font-size=\"${fontSize}\" font-weight=\"700\"`,\n    ` letter-spacing=\"${(fontSize * 0.08).toFixed(1)}\"`,\n    ` fill=\"${fill}\" fill-opacity=\"${opacity}\">${text}</text>`,\n    `</svg>`,\n  ].join('');\n\n  const base64 =\n    typeof btoa === 'function'\n      ? btoa(unescape(encodeURIComponent(svg)))\n      : Buffer.from(svg, 'utf-8').toString('base64');\n\n  return {\n    dataUri: `data:image/svg+xml;base64,${base64}`,\n    tileWidth: tileW,\n    tileHeight: tileH,\n  };\n}\n\n/**\n * Build the watermark DOM element. Returns null if no watermark text.\n *\n * The element is a single overlay covering the whole page (`inset: 0`),\n * with a repeating SVG-tile background — one rotated instance of the text\n * per tile — so the watermark reads consistently down the entire document,\n * across every page, in both paged and pageless view modes.\n */\nexport function createWatermarkElement(config: WatermarkConfig | null): HTMLElement | null {\n  const tile = buildWatermarkTile(config);\n  if (!tile) return null;\n\n  const el = document.createElement('div');\n  el.className = 'docx-watermark';\n  el.setAttribute('contenteditable', 'false');\n  el.setAttribute('aria-hidden', 'true');\n  el.style.cssText = [\n    'position: absolute',\n    'inset: 0',\n    `background-image: url(\"${tile.dataUri}\")`,\n    'background-repeat: repeat',\n    `background-size: ${tile.tileWidth}px ${tile.tileHeight}px`,\n    'pointer-events: none',\n    'user-select: none',\n    'z-index: 1',\n  ].join('; ');\n  return el;\n}\n","/**\n * Native PDF export — Node-only.\n *\n * There is no free/local \"tiptap-native\" PDF export: Tiptap's own PDF\n * extension (`@tiptap-pro/extension-export-pdf`) is a paid product that\n * serializes your document and uploads it to Tiptap's cloud conversion\n * service over the network. That's a poor fit for a toolkit where every\n * other conversion (load, save, selective patch) runs fully local — this\n * module renders PDFs locally instead, with no network call and no\n * subscription.\n *\n * How: rather than hand-rolling a second JSON→layout engine (duplicating\n * everything the OOXML serializer already does for .docx, with its own\n * chance to drift out of sync), this renders the editor's *real* HTML\n * output — the same `editor.getHTML()` a .docx save already trusts for\n * fidelity — through an actual browser engine (headless Chromium, via\n * Puppeteer) and uses that engine's own print-to-PDF. That gets real vector\n * text (selectable/searchable, not a rasterized screenshot), full-quality\n * embedded images, and pagination/margins/fonts that render exactly the way\n * a browser — the same kind of engine driving the on-screen editor — says\n * they should, which is about as accurate as HTML→PDF gets without needing\n * to reimplement text layout from scratch.\n *\n * This is Node-only: Puppeteer drives a separate headless browser process,\n * which cannot run inside the end user's own browser tab. The usual shape\n * is:\n *   1. Browser: `const snapshot = docxEditor.getExportSnapshot();`\n *   2. Send `snapshot` to your server.\n *   3. Server: `const pdfBytes = await renderHtmlToPdf(snapshot);`\n */\nimport { readFileSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\nimport type { WatermarkConfig } from '../extensions/builtins/watermark';\nimport { buildWatermarkTile } from '../extensions/builtins/watermark';\n\n// This file is only ever imported by `headless.ts` (the Node-only entry\n// point) — never by `index.ts`/`react.ts` — so top-level Node built-in\n// imports here are safe: they end up bundled only into the `headless.js`\n// output, not the browser-facing bundles.\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nexport interface PdfRenderInput {\n  /** Schema-accurate content HTML — e.g. `docxEditor.getExportSnapshot().html`. */\n  html: string;\n  /** CSS custom properties for page geometry/typography (`themeCSSVars` from `getExportSnapshot()`). */\n  themeCSSVars?: string;\n  /** Watermark config, or null/undefined for none. */\n  watermark?: WatermarkConfig | null;\n  /** Header HTML (repeats on every printed page), or '' for none. */\n  headerHTML?: string;\n  /** Footer HTML (repeats on every printed page), or '' for none. */\n  footerHTML?: string;\n}\n\nexport interface PdfRenderOptions {\n  /** Page width in inches. Default: 8.5 (US Letter, matching the editor's own default page width). */\n  pageWidthIn?: number;\n  /** Page height in inches. Default: 11 (US Letter). */\n  pageHeightIn?: number;\n  /** Extra CSS appended after the editor's stylesheet (highest priority — use for last-mile print tweaks). */\n  extraCSS?: string;\n  /** Puppeteer launch options passthrough (e.g. `{ executablePath: ... }` for a specific Chromium install). */\n  launchOptions?: Record<string, any>;\n}\n\nlet _puppeteer: any = null;\nasync function getPuppeteer(): Promise<any> {\n  if (_puppeteer) return _puppeteer;\n  try {\n    const mod = await import('puppeteer');\n    _puppeteer = mod.default || mod;\n    return _puppeteer;\n  } catch (e) {\n    throw new Error(\n      '[docx-editor] renderHtmlToPdf() requires puppeteer, which is not installed. ' +\n        'Run `npm install puppeteer` (Node-only — this never runs in the browser) and try again.',\n    );\n  }\n}\n\n/**\n * Render a document to a PDF, via headless Chromium. See the module\n * docstring for why this approach and why it's Node-only.\n */\nexport async function renderHtmlToPdf(\n  input: PdfRenderInput,\n  options: PdfRenderOptions = {},\n): Promise<Uint8Array> {\n  const puppeteer = await getPuppeteer();\n  const pageWidthIn = options.pageWidthIn ?? 8.5;\n  const pageHeightIn = options.pageHeightIn ?? 11;\n\n  const browser = await puppeteer.launch({ headless: true, ...options.launchOptions });\n  try {\n    const page = await browser.newPage();\n    const fullHtml = buildPrintDocument(input, options);\n    await page.setContent(fullHtml, { waitUntil: 'networkidle0' });\n    const pdf = await page.pdf({\n      width: `${pageWidthIn}in`,\n      height: `${pageHeightIn}in`,\n      printBackground: true,\n      margin: { top: '0', bottom: '0', left: '0', right: '0' }, // margin is handled by .docx-editor-content's own padding, so it matches the on-screen layout exactly instead of being specified twice\n    });\n    return pdf;\n  } finally {\n    await browser.close();\n  }\n}\n\n/* -------------------------------------------------------------------------- */\n/* HTML document assembly                                                     */\n/* -------------------------------------------------------------------------- */\n\nfunction buildPrintDocument(input: PdfRenderInput, options: PdfRenderOptions): string {\n  const editorCss = readEditorStylesheet();\n  const tile = buildWatermarkTile(input.watermark ?? null);\n\n  const watermarkHtml = tile\n    ? `<div class=\"docx-pdf-watermark\" style=\"position:fixed; inset:0; background-image:url('${tile.dataUri}'); background-repeat:repeat; background-size:${tile.tileWidth}px ${tile.tileHeight}px; pointer-events:none; z-index:1;\" aria-hidden=\"true\"></div>`\n    : '';\n\n  const headerHtml = input.headerHTML\n    ? `<div class=\"docx-editor-header docx-pdf-header\">${input.headerHTML}</div>`\n    : '';\n  const footerHtml = input.footerHTML\n    ? `<div class=\"docx-editor-footer docx-pdf-footer\">${input.footerHTML}</div>`\n    : '';\n\n  return `<!DOCTYPE html>\n<html>\n<head>\n<meta charset=\"utf-8\">\n<style>${editorCss}</style>\n<style>\n/* Print-specific overrides, layered after the editor's own stylesheet (see\n * PRINT_OVERRIDE_CSS docstring for why each rule exists). */\n${PRINT_OVERRIDE_CSS}\n</style>\n${options.extraCSS ? `<style>${options.extraCSS}</style>` : ''}\n</head>\n<body>\n<div class=\"docx-editor-host\" data-view-mode=\"paged\" style=\"${input.themeCSSVars ?? ''}\">\n  <div class=\"docx-editor-page\" style=\"position:relative;\">\n    ${headerHtml}\n    <div class=\"docx-editor-content\"><div class=\"ProseMirror\">${input.html}</div></div>\n    ${footerHtml}\n    ${watermarkHtml}\n  </div>\n</div>\n</body>\n</html>`;\n}\n\n/**\n * Overrides applied on top of the real editor stylesheet:\n *\n *  - The on-screen editor simulates page boundaries with JS-measured filler\n *    height (`_layoutPagination()`), because it has to keep one continuous\n *    contenteditable region. Here there's no editing to preserve, so we let\n *    Chromium do REAL pagination (`width`/`height` passed to `page.pdf()`)\n *    instead — `break-after: page` on an explicit page-break node, and\n *    natural page breaks everywhere else. That's more accurate than trying\n *    to reproduce the simulated gap sizing outside a live DOM anyway.\n *  - Header/footer/watermark switch from the app's single-page absolute\n *    positioning to `position: fixed`, which Chromium's print engine\n *    repeats on every physical page — the standard technique for\n *    print headers/footers/watermarks in an HTML→PDF pipeline.\n *  - The page chrome (drop shadow, gray surface, \"add page\" button) that\n *    only makes sense on-screen is stripped for print.\n */\nconst PRINT_OVERRIDE_CSS = `\nhtml, body { margin: 0; padding: 0; background: #fff; }\n.docx-editor-page { box-shadow: none; margin: 0; width: auto; min-height: 0; }\n.docx-editor-content { position: relative; z-index: 2; }\n.docx-page-break, .docx-editor-content .ProseMirror .docx-page-break {\n  break-after: page;\n  height: 0 !important;\n  margin: 0 !important;\n  padding: 0 !important;\n  background: none !important;\n  border: none !important;\n}\n.docx-page-break::before, .docx-page-break::after,\n.docx-editor-content .ProseMirror .docx-page-break::before,\n.docx-editor-content .ProseMirror .docx-page-break::after {\n  content: none !important;\n}\n.docx-pdf-header { top: 0; }\n.docx-pdf-footer { bottom: 0; }\n.docx-pdf-header, .docx-pdf-footer { position: fixed; left: 0; right: 0; z-index: 2; background: #fff; }\n`;\n\n/**\n * Read the editor's own compiled stylesheet (`dist/style.css`) so the PDF\n * uses the exact same typography/table/list/image rules the on-screen\n * editor does — one stylesheet, not a hand-authored print copy that can\n * drift out of sync with real editor styling changes.\n */\nlet _editorCssCache: string | null = null;\nfunction readEditorStylesheet(): string {\n  if (_editorCssCache !== null) return _editorCssCache;\n  // tsup bundles `headless.ts` (which imports this file) into a single\n  // dist/headless.js, so this module's own directory at runtime is `dist/`\n  // — the same directory `style.css` is copied into (see tsup.config.ts's\n  // onSuccess hook). The extra candidates are a safety net for other\n  // bundling layouts.\n  const candidates = [\n    join(__dirname, 'style.css'),\n    join(__dirname, '..', 'style.css'),\n    join(__dirname, '..', '..', 'dist', 'style.css'),\n  ];\n  for (const candidate of candidates) {\n    try {\n      const content: string = readFileSync(candidate, 'utf-8');\n      _editorCssCache = content;\n      return content;\n    } catch {\n      // try the next candidate\n    }\n  }\n  console.warn(\n    '[docx-editor] renderHtmlToPdf() could not locate the built style.css — ' +\n      'falling back to unstyled HTML. Make sure @shashimadushan/docx-editor-editor was built (`pnpm build`) ' +\n      'so dist/style.css exists.',\n  );\n  _editorCssCache = '';\n  return _editorCssCache;\n}\n"]}