@office-kit/xlsx 0.8.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{cell-D9CaNKnU.mjs → cell-BucgGwl3.mjs} +2 -2
- package/dist/{cell-D9CaNKnU.mjs.map → cell-BucgGwl3.mjs.map} +1 -1
- package/dist/{cell-style-BEDjMX1y.mjs → cell-style-CN9JXOwm.mjs} +8 -6
- package/dist/cell-style-CN9JXOwm.mjs.map +1 -0
- package/dist/cell.mjs +1 -1
- package/dist/coordinate-96Ecci4d.mjs.map +1 -1
- package/dist/datetime-B2ySVlXt.mjs.map +1 -1
- package/dist/{differential-D4dg-qtZ.mjs → differential-YEjxNScf.mjs} +2 -2
- package/dist/{differential-D4dg-qtZ.mjs.map → differential-YEjxNScf.mjs.map} +1 -1
- package/dist/drawing-BxzLuryn.mjs.map +1 -1
- package/dist/escape-DFTE7ZJc.mjs.map +1 -1
- package/dist/{inference-B3ES3KEJ.mjs → inference-BrI9uIY4.mjs} +2 -2
- package/dist/{inference-B3ES3KEJ.mjs.map → inference-BrI9uIY4.mjs.map} +1 -1
- package/dist/io.mjs +4 -4
- package/dist/io.mjs.map +1 -1
- package/dist/{load-D5cbhoGx.mjs → load-DeAQKGQN.mjs} +64 -28
- package/dist/load-DeAQKGQN.mjs.map +1 -0
- package/dist/{manifest-Dps1-OpP.mjs → manifest-CVL1_t0O.mjs} +7 -5
- package/dist/{manifest-Dps1-OpP.mjs.map → manifest-CVL1_t0O.mjs.map} +1 -1
- package/dist/node.mjs +3 -3
- package/dist/node.mjs.map +1 -1
- package/dist/packaging.mjs +1 -1
- package/dist/{parser-DuLejQy1.mjs → parser-nk0Lqmcb.mjs} +3 -2
- package/dist/{parser-DuLejQy1.mjs.map → parser-nk0Lqmcb.mjs.map} +1 -1
- package/dist/{reader-D1fNW9k1.mjs → reader-BNaUTVCy.mjs} +3 -2
- package/dist/{reader-D1fNW9k1.mjs.map → reader-BNaUTVCy.mjs.map} +1 -1
- package/dist/{save-RohQtgEZ.mjs → save-OTuS72yI.mjs} +23 -9
- package/dist/save-OTuS72yI.mjs.map +1 -0
- package/dist/{serializer-BwbgHYJV.mjs → serializer-DQzTTNOS.mjs} +2 -2
- package/dist/{serializer-BwbgHYJV.mjs.map → serializer-DQzTTNOS.mjs.map} +1 -1
- package/dist/streaming.mjs +13 -11
- package/dist/streaming.mjs.map +1 -1
- package/dist/styles/borders.d.ts +1 -1
- package/dist/styles.mjs +3 -3
- package/dist/{stylesheet-writer-C2eRmn22.mjs → stylesheet-writer-P1Hxoqzm.mjs} +32 -26
- package/dist/{stylesheet-writer-C2eRmn22.mjs.map → stylesheet-writer-P1Hxoqzm.mjs.map} +1 -1
- package/dist/{table-DkX6UniA.mjs → table-BifavDVW.mjs} +2 -2
- package/dist/{table-DkX6UniA.mjs.map → table-BifavDVW.mjs.map} +1 -1
- package/dist/utf8-D91g1XTG.mjs.map +1 -1
- package/dist/utils.mjs +1 -1
- package/dist/utils.mjs.map +1 -1
- package/dist/workbook/workbook.d.ts +7 -0
- package/dist/{workbook-HGYNRBlV.mjs → workbook-T1Y3lstQ.mjs} +5 -5
- package/dist/workbook-T1Y3lstQ.mjs.map +1 -0
- package/dist/workbook.mjs +1 -1
- package/dist/{worksheet-CmCNoIgD.mjs → worksheet-C6CWgvP5.mjs} +2 -2
- package/dist/{worksheet-CmCNoIgD.mjs.map → worksheet-C6CWgvP5.mjs.map} +1 -1
- package/dist/worksheet.mjs +2 -2
- package/dist/{writer-DspzfkNA.mjs → writer-IyFccCRJ.mjs} +3 -3
- package/dist/{writer-DspzfkNA.mjs.map → writer-IyFccCRJ.mjs.map} +1 -1
- package/dist/xml.mjs +2 -2
- package/dist/zip.mjs +2 -2
- package/package.json +23 -31
- package/dist/cell-style-BEDjMX1y.mjs.map +0 -1
- package/dist/load-D5cbhoGx.mjs.map +0 -1
- package/dist/save-RohQtgEZ.mjs.map +0 -1
- package/dist/workbook-HGYNRBlV.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"load-D5cbhoGx.mjs","names":[],"sources":["../src/styles/stylesheet-reader.ts","../src/io/load.ts"],"sourcesContent":["// xl/styles.xml → Stylesheet reader.\n//\n// The reader preserves slot ordering exactly — cellXfs[3] in the source xlsx\n// must come back as cellXfs[3] in the loaded Workbook because every `<c s=\"3\">`\n// reference depends on the index, not on the value's identity. That rules out\n// the `addFont` / `addCellXf` dedup helpers (which collapse equal values);\n// instead we push raw entries and rebuild the `_*IdByKey` maps at the end so\n// subsequent edits go back through dedup.\n\nimport { fromTree } from '../schema/serialize';\nimport { OpenXmlSchemaError } from '../utils/exceptions';\nimport { stableStringify } from '../utils/stable-stringify';\nimport { qname, SHEET_MAIN_NS } from '../xml/namespaces';\nimport { parseXml } from '../xml/parser';\nimport { findChild, findChildren, type XmlNode } from '../xml/tree';\nimport { AlignmentSchema } from './alignment.schema';\nimport type { Border } from './borders';\nimport { BorderSchema } from './borders.schema';\nimport type { DifferentialStyle, StylesheetWithDxfs } from './differential';\nimport type { Fill } from './fills';\nimport { fillFromTree } from './fills.schema';\nimport type { Font } from './fonts';\nimport { FontSchema } from './fonts.schema';\nimport type { StylesheetNamedStyle } from './named-styles';\nimport type { NumberFormat } from './numbers';\nimport { NumberFormatSchema } from './numbers.schema';\nimport { ProtectionSchema } from './protection.schema';\nimport { type CellXf, makeStylesheet, type Stylesheet } from './stylesheet';\n\nconst STYLESHEET_TAG = qname(SHEET_MAIN_NS, 'styleSheet');\nconst FONTS_TAG = qname(SHEET_MAIN_NS, 'fonts');\nconst FILLS_TAG = qname(SHEET_MAIN_NS, 'fills');\nconst BORDERS_TAG = qname(SHEET_MAIN_NS, 'borders');\nconst NUMFMTS_TAG = qname(SHEET_MAIN_NS, 'numFmts');\nconst NUMFMT_TAG = qname(SHEET_MAIN_NS, 'numFmt');\nconst CELLXFS_TAG = qname(SHEET_MAIN_NS, 'cellXfs');\nconst CELLSTYLEXFS_TAG = qname(SHEET_MAIN_NS, 'cellStyleXfs');\nconst CELLSTYLES_TAG = qname(SHEET_MAIN_NS, 'cellStyles');\nconst CELLSTYLE_TAG = qname(SHEET_MAIN_NS, 'cellStyle');\nconst DXFS_TAG = qname(SHEET_MAIN_NS, 'dxfs');\nconst DXF_TAG = qname(SHEET_MAIN_NS, 'dxf');\nconst XF_TAG = qname(SHEET_MAIN_NS, 'xf');\nconst FONT_TAG = qname(SHEET_MAIN_NS, 'font');\nconst FILL_TAG = qname(SHEET_MAIN_NS, 'fill');\nconst BORDER_TAG = qname(SHEET_MAIN_NS, 'border');\nconst NUMFMT_INNER_TAG = qname(SHEET_MAIN_NS, 'numFmt');\nconst ALIGNMENT_TAG = qname(SHEET_MAIN_NS, 'alignment');\nconst PROTECTION_TAG = qname(SHEET_MAIN_NS, 'protection');\n\n/**\n * Parse `xl/styles.xml` and return a fully-populated {@link Stylesheet}. Slot\n * ordering is preserved verbatim; the dedup index Maps are rebuilt after the\n * fact so future `addFont` / `addCellXf` calls keep working.\n */\nexport function parseStylesheetXml(bytes: Uint8Array | string): Stylesheet {\n const root = parseXml(bytes);\n if (root.name !== STYLESHEET_TAG) {\n throw new OpenXmlSchemaError(`parseStylesheetXml: root is \"${root.name}\", expected styleSheet`);\n }\n\n // Start from a Stylesheet whose default-pool entries we'll wholesale replace\n // with the XML's actual contents.\n const ss = makeStylesheet();\n ss.fonts.length = 0;\n ss.fills.length = 0;\n ss.borders.length = 0;\n\n for (const fontEl of findInSection(root, FONTS_TAG, FONT_TAG)) {\n ss.fonts.push(fromTree(fontEl, FontSchema));\n }\n for (const fillEl of findInSection(root, FILLS_TAG, FILL_TAG)) {\n ss.fills.push(fillFromTree(fillEl));\n }\n for (const borderEl of findInSection(root, BORDERS_TAG, BORDER_TAG)) {\n ss.borders.push(fromTree(borderEl, BorderSchema));\n }\n\n // numFmts is a Map<id, code>; id is on the element so a sparse Map works.\n for (const numFmtEl of findInSection(root, NUMFMTS_TAG, NUMFMT_TAG)) {\n const nf = parseNumFmt(numFmtEl);\n ss.numFmts.set(nf.numFmtId, nf.formatCode);\n }\n\n for (const xfEl of findInSection(root, CELLSTYLEXFS_TAG, XF_TAG)) {\n ss.cellStyleXfs.push(parseCellXf(xfEl));\n }\n for (const xfEl of findInSection(root, CELLXFS_TAG, XF_TAG)) {\n ss.cellXfs.push(parseCellXf(xfEl));\n }\n\n // cellStyles → ss.namedStyles\n const cellStylesEl = findChild(root, CELLSTYLES_TAG);\n if (cellStylesEl) {\n const named: StylesheetNamedStyle[] = [];\n for (const cs of findChildren(cellStylesEl, CELLSTYLE_TAG)) {\n const name = cs.attrs['name'];\n const xfId = parseIntAttr(cs.attrs['xfId'], 'xfId');\n if (name === undefined || xfId === undefined) continue;\n const entry: StylesheetNamedStyle = {\n name,\n xfId,\n ...(cs.attrs['builtinId'] !== undefined ? { builtinId: parseIntAttr(cs.attrs['builtinId'], 'builtinId') ?? 0 } : {}),\n ...(cs.attrs['iLevel'] !== undefined ? { iLevel: parseIntAttr(cs.attrs['iLevel'], 'iLevel') ?? 0 } : {}),\n ...(parseBoolAttr(cs.attrs['hidden']) === true ? { hidden: true } : {}),\n ...(parseBoolAttr(cs.attrs['customBuiltin']) === true ? { customBuiltin: true } : {}),\n };\n named.push(entry);\n }\n if (named.length > 0) {\n ss.namedStyles = named;\n ss._namedStyleByName = new Map(named.map((n) => [n.name, n]));\n }\n }\n\n // dxfs → ss.dxfs\n const dxfsEl = findChild(root, DXFS_TAG);\n if (dxfsEl) {\n const dxfs: DifferentialStyle[] = [];\n for (const dxfEl of findChildren(dxfsEl, DXF_TAG)) {\n const fontEl = findChild(dxfEl, FONT_TAG);\n const numFmtEl = findChild(dxfEl, NUMFMT_INNER_TAG);\n const fillEl = findChild(dxfEl, FILL_TAG);\n const alignmentEl = findChild(dxfEl, ALIGNMENT_TAG);\n const borderEl = findChild(dxfEl, BORDER_TAG);\n const protectionEl = findChild(dxfEl, PROTECTION_TAG);\n const dxf: DifferentialStyle = {\n ...(fontEl ? { font: fromTree(fontEl, FontSchema) } : {}),\n ...(numFmtEl ? { numFmt: fromTree(numFmtEl, NumberFormatSchema) } : {}),\n ...(fillEl ? { fill: fillFromTree(fillEl) } : {}),\n ...(alignmentEl ? { alignment: fromTree(alignmentEl, AlignmentSchema) } : {}),\n ...(borderEl ? { border: fromTree(borderEl, BorderSchema) } : {}),\n ...(protectionEl ? { protection: fromTree(protectionEl, ProtectionSchema) } : {}),\n };\n dxfs.push(Object.freeze(dxf));\n }\n if (dxfs.length > 0) {\n const w = ss as StylesheetWithDxfs;\n w.dxfs = dxfs;\n w._dxfIdByKey = new Map(dxfs.map((d, i) => [stableStringify(d), i]));\n }\n }\n\n rebuildIndexes(ss);\n return ss;\n}\n\n/** Drill from `<styleSheet>` into a numbered section and yield every matching child. */\nfunction findInSection(root: XmlNode, sectionTag: string, itemTag: string): XmlNode[] {\n const section = findChild(root, sectionTag);\n if (!section) return [];\n return findChildren(section, itemTag);\n}\n\nconst parseNumFmt = (node: XmlNode): NumberFormat => {\n const idAttr = node.attrs['numFmtId'];\n const code = node.attrs['formatCode'];\n if (idAttr === undefined) {\n throw new OpenXmlSchemaError('styles: <numFmt> missing @numFmtId');\n }\n if (code === undefined) {\n throw new OpenXmlSchemaError(`styles: <numFmt numFmtId=\"${idAttr}\"> missing @formatCode`);\n }\n const numFmtId = Number.parseInt(idAttr, 10);\n if (!Number.isInteger(numFmtId) || numFmtId < 0) {\n throw new OpenXmlSchemaError(`styles: <numFmt numFmtId=\"${idAttr}\"> is not a non-negative integer`);\n }\n return { numFmtId, formatCode: code };\n};\n\nconst parseIntAttr = (raw: string | undefined, label: string): number | undefined => {\n if (raw === undefined) return undefined;\n const n = Number.parseInt(raw, 10);\n if (!Number.isInteger(n) || n < 0) {\n throw new OpenXmlSchemaError(`styles: <xf ${label}=\"${raw}\"> is not a non-negative integer`);\n }\n return n;\n};\n\nconst parseBoolAttr = (raw: string | undefined): boolean | undefined => {\n if (raw === undefined) return undefined;\n if (raw === '1' || raw === 'true') return true;\n if (raw === '0' || raw === 'false') return false;\n return undefined;\n};\n\nconst parseCellXf = (node: XmlNode): CellXf => {\n const fontId = parseIntAttr(node.attrs['fontId'], 'fontId') ?? 0;\n const fillId = parseIntAttr(node.attrs['fillId'], 'fillId') ?? 0;\n const borderId = parseIntAttr(node.attrs['borderId'], 'borderId') ?? 0;\n const numFmtId = parseIntAttr(node.attrs['numFmtId'], 'numFmtId') ?? 0;\n const xfId = parseIntAttr(node.attrs['xfId'], 'xfId');\n\n const applyFont = parseBoolAttr(node.attrs['applyFont']);\n const applyFill = parseBoolAttr(node.attrs['applyFill']);\n const applyBorder = parseBoolAttr(node.attrs['applyBorder']);\n const applyNumberFormat = parseBoolAttr(node.attrs['applyNumberFormat']);\n const applyAlignment = parseBoolAttr(node.attrs['applyAlignment']);\n const applyProtection = parseBoolAttr(node.attrs['applyProtection']);\n const pivotButton = parseBoolAttr(node.attrs['pivotButton']);\n const quotePrefix = parseBoolAttr(node.attrs['quotePrefix']);\n\n const alignmentEl = findChild(node, ALIGNMENT_TAG);\n const protectionEl = findChild(node, PROTECTION_TAG);\n\n return {\n fontId,\n fillId,\n borderId,\n numFmtId,\n ...(xfId !== undefined ? { xfId } : {}),\n ...(alignmentEl ? { alignment: fromTree(alignmentEl, AlignmentSchema) } : {}),\n ...(protectionEl ? { protection: fromTree(protectionEl, ProtectionSchema) } : {}),\n ...(applyFont !== undefined ? { applyFont } : {}),\n ...(applyFill !== undefined ? { applyFill } : {}),\n ...(applyBorder !== undefined ? { applyBorder } : {}),\n ...(applyNumberFormat !== undefined ? { applyNumberFormat } : {}),\n ...(applyAlignment !== undefined ? { applyAlignment } : {}),\n ...(applyProtection !== undefined ? { applyProtection } : {}),\n ...(pivotButton !== undefined ? { pivotButton } : {}),\n ...(quotePrefix !== undefined ? { quotePrefix } : {}),\n };\n};\n\n/** Repopulate the `_*IdByKey` maps from the freshly-loaded pool entries. */\nfunction rebuildIndexes(ss: Stylesheet): void {\n ss._fontIdByKey = buildKeyIndex<Font>(ss.fonts);\n ss._fillIdByKey = buildKeyIndex<Fill>(ss.fills);\n ss._borderIdByKey = buildKeyIndex<Border>(ss.borders);\n ss._xfIdByKey = buildKeyIndex<CellXf>(ss.cellXfs);\n ss._styleXfIdByKey = buildKeyIndex<CellXf>(ss.cellStyleXfs);\n ss._numFmtIdByCode = new Map();\n for (const [id, code] of ss.numFmts) ss._numFmtIdByCode.set(code, id);\n}\n\nconst buildKeyIndex = <T>(arr: ReadonlyArray<T>): Map<string, number> => {\n const m = new Map<string, number>();\n for (let i = 0; i < arr.length; i++) {\n const key = stableStringify(arr[i] as T);\n if (!m.has(key)) m.set(key, i);\n }\n return m;\n};\n","// Public `loadWorkbook` entry point.\n//\n// **This is the minimum-skeleton stage**: open zip → parse manifest → resolve\n// workbook part path → parse the `<sheets>` list → for each sheet, allocate an\n// empty Worksheet (title + sheetId + state). Reading the actual cell content /\n// styles / sharedStrings / theme / docProps happens in the next iterations of\n// the loop.\n//\n// The skeleton is enough to round-trip through openpyxl's `genuine/empty.xlsx`\n// fixture (3 empty sheets) and to give the rest of phase 3 a stable scaffolding\n// to layer onto.\n\nimport { findUserShapesRId, parseChartXml } from '../chart/chart-xml';\nimport { isChartExBytes, parseChartExXml } from '../chart/cx/chartex-xml';\nimport { parseUserShapesXml } from '../chart/user-shapes-xml';\nimport { parseChartsheetXml } from '../chartsheet/chartsheet-xml';\nimport { parseDrawingXml } from '../drawing/drawing-xml';\nimport { loadImage } from '../drawing/image';\nimport type { XlsxSource } from '../io/source';\nimport { corePropsFromBytes } from '../packaging/core';\nimport { customPropsFromBytes } from '../packaging/custom';\nimport { extendedPropsFromBytes } from '../packaging/extended';\nimport { manifestFromBytes } from '../packaging/manifest';\nimport { findById, indexRelsById, relsFromBytes } from '../packaging/relationships';\nimport { parseStylesheetXml } from '../styles/stylesheet-reader';\nimport { OpenXmlSchemaError } from '../utils/exceptions';\nimport type { DefinedName } from '../workbook/defined-names';\nimport { makeDefinedName } from '../workbook/defined-names';\nimport { parseSharedStringsXml, type SharedStringsTable } from '../workbook/shared-strings';\nimport { createWorkbook, type SheetRef, type SheetState, type Workbook } from '../workbook/workbook';\nimport { parseCommentsXml } from '../worksheet/comments-xml';\nimport { parseWorksheetXml } from '../worksheet/reader';\nimport { parseTableXml } from '../worksheet/table-xml';\nimport {\n ARC_APP,\n ARC_CONTENT_TYPES,\n ARC_CORE,\n ARC_CUSTOM,\n ARC_ROOT_RELS,\n ARC_SHARED_STRINGS,\n ARC_STYLE,\n ARC_THEME,\n ARC_WORKBOOK,\n parseQName,\n REL_NS,\n SHEET_MAIN_NS,\n} from '../xml/namespaces';\nimport { parseXml } from '../xml/parser';\nimport { findChild, findChildren, type XmlNode } from '../xml/tree';\nimport type { DecompressionLimits } from '../zip/decompression-guard';\nimport { openZip, type ZipArchive } from '../zip/reader';\n\n/**\n * Options for {@link loadWorkbook}. Earlier drafts exposed `readOnly` /\n * `keepLinks` / `keepVba` / `dataOnly` / `richText` placeholders that the\n * loader silently ignored; those were removed to keep the surface honest.\n * Future toggles land here once their behavior is implemented.\n */\nexport interface LoadOptions {\n /**\n * Decompression-bomb safeguards applied while inflating zip entries.\n * Defaults to limits that fit any legitimate xlsx; pass `false` to disable\n * (only safe for fully trusted sources). See\n * {@link DecompressionLimits} for the individual knobs.\n */\n decompressionLimits?: DecompressionLimits | false;\n}\n\n/** Office Document relationship type — the package-root pointer to `xl/workbook.xml`. */\nconst OFFICE_DOC_REL_TYPE = `${REL_NS}/officeDocument`;\n\n/**\n * Resolve an OPC relationship target against its source part path.\n *\n * - Targets starting with `/` are package-absolute.\n * - Otherwise the target is relative to the source part's parent directory.\n * - `..` segments collapse normally.\n */\nexport function resolveRelTarget(sourcePartPath: string, target: string): string {\n if (target.startsWith('/')) return target.slice(1);\n const lastSlash = sourcePartPath.lastIndexOf('/');\n const parentDir = lastSlash >= 0 ? sourcePartPath.slice(0, lastSlash + 1) : '';\n const joined = parentDir + target;\n return normalizePath(joined);\n}\n\nfunction normalizePath(path: string): string {\n const segments = path.split('/');\n const out: string[] = [];\n for (const seg of segments) {\n if (seg === '' || seg === '.') continue;\n if (seg === '..') {\n // Pop the last accumulated segment when one exists; when `out` is\n // empty (a relative target with more `..` than ancestors) the pop is\n // a no-op so the climb is silently absorbed at the package root. The\n // archive.has() check on the resolved path catches any escape attempt\n // because the entry simply won't exist outside the package — there's\n // no filesystem traversal to worry about, only a missing-entry error.\n out.pop();\n continue;\n }\n out.push(seg);\n }\n return out.join('/');\n}\n\n/** Sibling rels-part path for a given part. `xl/workbook.xml` → `xl/_rels/workbook.xml.rels`. */\nfunction relsPathFor(partPath: string): string {\n const i = partPath.lastIndexOf('/');\n if (i < 0) return `_rels/${partPath}.rels`;\n return `${partPath.slice(0, i)}/_rels/${partPath.slice(i + 1)}.rels`;\n}\n\ninterface SheetEntry {\n /** Display name (`sheet/@name`). */\n name: string;\n /** Workbook-scope sheetId (`sheet/@sheetId`). */\n sheetId: number;\n /** Workbook rels Id (`sheet/@r:id`). */\n rId: string;\n /** Visibility state — defaults to `'visible'` when the attribute is absent. */\n state: SheetState;\n}\n\nconst SHEET_TAG = `{${SHEET_MAIN_NS}}sheet`;\nconst SHEETS_TAG = `{${SHEET_MAIN_NS}}sheets`;\nconst DEFINED_NAMES_TAG = `{${SHEET_MAIN_NS}}definedNames`;\nconst DEFINED_NAME_TAG = `{${SHEET_MAIN_NS}}definedName`;\nconst RID_ATTR = `{${REL_NS}}id`;\n\n/** Extract the `<definedNames>/<definedName>` entries from a parsed `xl/workbook.xml`. */\nfunction parseDefinedNames(workbookRoot: XmlNode): DefinedName[] {\n const wrapper = findChild(workbookRoot, DEFINED_NAMES_TAG);\n if (!wrapper) return [];\n const out: DefinedName[] = [];\n for (const node of findChildren(wrapper, DEFINED_NAME_TAG)) {\n const name = node.attrs['name'];\n if (!name) throw new OpenXmlSchemaError(\"workbook.xml: <definedName> is missing 'name'\");\n const value = node.text ?? '';\n const opts: Partial<DefinedName> & { name: string; value: string } = { name, value };\n const scopeAttr = node.attrs['localSheetId'];\n if (scopeAttr !== undefined) {\n const scope = Number.parseInt(scopeAttr, 10);\n if (Number.isInteger(scope) && scope >= 0) opts.scope = scope;\n }\n if (node.attrs['hidden'] === '1' || node.attrs['hidden'] === 'true') opts.hidden = true;\n if (node.attrs['comment'] !== undefined) opts.comment = node.attrs['comment'];\n out.push(makeDefinedName(opts));\n }\n return out;\n}\n\nconst WORKBOOK_PR_TAG = `{${SHEET_MAIN_NS}}workbookPr`;\nconst WORKBOOK_PROTECTION_TAG = `{${SHEET_MAIN_NS}}workbookProtection`;\nconst BOOK_VIEWS_TAG = `{${SHEET_MAIN_NS}}bookViews`;\nconst WORKBOOK_VIEW_TAG = `{${SHEET_MAIN_NS}}workbookView`;\nconst CUSTOM_WORKBOOK_VIEWS_TAG = `{${SHEET_MAIN_NS}}customWorkbookViews`;\nconst CUSTOM_WORKBOOK_VIEW_TAG = `{${SHEET_MAIN_NS}}customWorkbookView`;\nconst CALC_PR_TAG = `{${SHEET_MAIN_NS}}calcPr`;\nconst FILE_VERSION_TAG = `{${SHEET_MAIN_NS}}fileVersion`;\nconst FILE_SHARING_TAG = `{${SHEET_MAIN_NS}}fileSharing`;\nconst OLE_SIZE_TAG = `{${SHEET_MAIN_NS}}oleSize`;\nconst FILE_RECOVERY_PR_TAG = `{${SHEET_MAIN_NS}}fileRecoveryPr`;\nconst PIVOT_CACHES_TAG = `{${SHEET_MAIN_NS}}pivotCaches`;\nconst PIVOT_CACHE_TAG = `{${SHEET_MAIN_NS}}pivotCache`;\nconst EXTERNAL_REFERENCES_TAG = `{${SHEET_MAIN_NS}}externalReferences`;\nconst EXTERNAL_REFERENCE_TAG = `{${SHEET_MAIN_NS}}externalReference`;\nconst SMART_TAG_PR_TAG = `{${SHEET_MAIN_NS}}smartTagPr`;\nconst SMART_TAG_TYPES_TAG = `{${SHEET_MAIN_NS}}smartTagTypes`;\nconst SMART_TAG_TYPE_TAG = `{${SHEET_MAIN_NS}}smartTagType`;\nconst FUNCTION_GROUPS_TAG = `{${SHEET_MAIN_NS}}functionGroups`;\nconst FUNCTION_GROUP_TAG = `{${SHEET_MAIN_NS}}functionGroup`;\n\n/**\n * Parse the `<workbookPr date1904>` flag. Mac-origin workbooks set\n * `date1904=\"true\"`; everything else uses the Windows 1900 epoch. The value\n * drives Date / Duration cell serial conversion in worksheet/writer.ts and\n * reader.ts.\n */\nfunction parseDate1904(workbookRoot: XmlNode): boolean {\n const pr = findChild(workbookRoot, WORKBOOK_PR_TAG);\n if (!pr) return false;\n const v = pr.attrs['date1904'];\n return v === '1' || v === 'true';\n}\n\n/** Extract the `<sheets>/<sheet>` entries from a parsed `xl/workbook.xml`. */\nexport function parseSheetEntries(workbookRoot: XmlNode): SheetEntry[] {\n const sheets = findChild(workbookRoot, SHEETS_TAG);\n if (!sheets) return [];\n const out: SheetEntry[] = [];\n for (const node of findChildren(sheets, SHEET_TAG)) {\n const name = node.attrs['name'];\n const sheetIdAttr = node.attrs['sheetId'];\n const rId = node.attrs[RID_ATTR];\n if (!name) throw new OpenXmlSchemaError(\"workbook.xml: <sheet> is missing 'name'\");\n if (!sheetIdAttr) throw new OpenXmlSchemaError(`workbook.xml: <sheet name=\"${name}\"> is missing 'sheetId'`);\n if (!rId) throw new OpenXmlSchemaError(`workbook.xml: <sheet name=\"${name}\"> is missing 'r:id'`);\n const sheetId = Number.parseInt(sheetIdAttr, 10);\n if (!Number.isInteger(sheetId) || sheetId < 1) {\n throw new OpenXmlSchemaError(\n `workbook.xml: <sheet name=\"${name}\"> sheetId \"${sheetIdAttr}\" is not a positive integer`,\n );\n }\n const stateAttr = node.attrs['state'];\n let state: SheetState = 'visible';\n if (stateAttr === 'hidden' || stateAttr === 'veryHidden') state = stateAttr;\n out.push({ name, sheetId, rId, state });\n }\n return out;\n}\n\n/**\n * Load a workbook from any {@link XlsxSource}. Currently produces a scaffold\n * Workbook: each Worksheet is empty (no cells / styles / shared strings / theme\n * yet). The next phase-3 iterations layer those in atop the same skeleton.\n */\nexport async function loadWorkbook(source: XlsxSource, opts: LoadOptions = {}): Promise<Workbook> {\n const archive = await openZip(\n source,\n opts.decompressionLimits === undefined ? {} : { decompressionLimits: opts.decompressionLimits },\n );\n try {\n return loadWorkbookFromArchive(archive);\n } finally {\n archive.close();\n }\n}\n\n/** Internal: same as {@link loadWorkbook} but operating on an already-opened archive. */\nfunction loadWorkbookFromArchive(archive: ZipArchive): Workbook {\n // 1. Manifest — resolves which override entries the package declares.\n if (!archive.has(ARC_CONTENT_TYPES)) {\n throw new OpenXmlSchemaError(`loadWorkbook: missing \"${ARC_CONTENT_TYPES}\"`);\n }\n const manifest = manifestFromBytes(archive.read(ARC_CONTENT_TYPES));\n\n // 2. Root rels → resolve the office-document relationship to the workbook part path.\n if (!archive.has(ARC_ROOT_RELS)) {\n throw new OpenXmlSchemaError(`loadWorkbook: missing \"${ARC_ROOT_RELS}\"`);\n }\n const rootRels = relsFromBytes(archive.read(ARC_ROOT_RELS));\n const officeRel = rootRels.rels.find((r) => r.type === OFFICE_DOC_REL_TYPE);\n if (!officeRel) {\n throw new OpenXmlSchemaError('loadWorkbook: root rels missing officeDocument relationship');\n }\n const workbookPath = resolveRelTarget('', officeRel.target);\n if (workbookPath !== ARC_WORKBOOK) {\n // Most xlsx files put the workbook at xl/workbook.xml. We accept any path\n // the rels point at as long as the archive holds it.\n if (!archive.has(workbookPath)) {\n throw new OpenXmlSchemaError(`loadWorkbook: workbook part \"${workbookPath}\" not found in archive`);\n }\n }\n\n // 3. workbook.xml — parse to extract sheet metadata only.\n const wbRoot = parseXml(archive.read(workbookPath));\n if (parseQName(wbRoot.name).local !== 'workbook') {\n throw new OpenXmlSchemaError(`loadWorkbook: ${workbookPath} root is \"${wbRoot.name}\", expected workbook`);\n }\n const sheetEntries = parseSheetEntries(wbRoot);\n const definedNamesFromXml = parseDefinedNames(wbRoot);\n\n // 4. workbook.xml.rels — needed to resolve each sheet's rId to a part path.\n const wbRelsPath = relsPathFor(workbookPath);\n // openpyxl tolerates a missing workbook.xml.rels (it implies no sheets); in\n // practice every Excel file has one. We require it so a malformed package\n // surfaces as an OpenXmlSchemaError, not a silently-empty workbook.\n if (sheetEntries.length > 0 && !archive.has(wbRelsPath)) {\n throw new OpenXmlSchemaError(`loadWorkbook: workbook has sheets but rels part \"${wbRelsPath}\" is missing`);\n }\n const wbRels = archive.has(wbRelsPath) ? relsFromBytes(archive.read(wbRelsPath)) : { rels: [] };\n\n // 4b. sharedStrings.xml — optional. The workbook rels can also point at a\n // non-default location; for the minimum-skeleton stage we look at the\n // canonical `xl/sharedStrings.xml` path first, then fall back to the rels\n // entry if present.\n let sharedStrings: SharedStringsTable | undefined;\n if (archive.has(ARC_SHARED_STRINGS)) {\n sharedStrings = parseSharedStringsXml(archive.read(ARC_SHARED_STRINGS));\n } else {\n const sstRel = wbRels.rels.find((r) => r.type === `${REL_NS}/sharedStrings`);\n if (sstRel) {\n const sstPath = resolveRelTarget(workbookPath, sstRel.target);\n if (archive.has(sstPath)) {\n sharedStrings = parseSharedStringsXml(archive.read(sstPath));\n }\n }\n }\n // The worksheet reader takes plain strings; rich-text SST entries are\n // flattened to their concatenated text body so cell values stay simple.\n // (Rich-text fidelity round-trip on read needs a sst entry → cell-value\n // bridge that produces a rich-text cell; for now Excel re-write still works\n // because we only flatten on read, not on write.)\n const sst: ReadonlyArray<string> = (sharedStrings?.entries ?? []).map((e) =>\n typeof e === 'string' ? e : e.runs.map((r) => r.text).join(''),\n );\n\n // 4c. styles.xml — optional. Same default-or-rels lookup as sst.\n let styles: ReturnType<typeof parseStylesheetXml> | undefined;\n if (archive.has(ARC_STYLE)) {\n styles = parseStylesheetXml(archive.read(ARC_STYLE));\n } else {\n const stylesRel = wbRels.rels.find((r) => r.type === `${REL_NS}/styles`);\n if (stylesRel) {\n const stylesPath = resolveRelTarget(workbookPath, stylesRel.target);\n if (archive.has(stylesPath)) {\n styles = parseStylesheetXml(archive.read(stylesPath));\n }\n }\n }\n\n // 4d. docProps/{core,app,custom}.xml — package-level metadata. Each part is\n // optional; absent ones leave the matching Workbook field undefined. We walk\n // both the canonical path and the root rels so non-default layouts (rare but\n // legal) still resolve.\n const properties = archive.has(ARC_CORE) ? corePropsFromBytes(archive.read(ARC_CORE)) : undefined;\n const appProperties = archive.has(ARC_APP) ? extendedPropsFromBytes(archive.read(ARC_APP)) : undefined;\n const customProperties = archive.has(ARC_CUSTOM) ? customPropsFromBytes(archive.read(ARC_CUSTOM)) : undefined;\n\n // 4e. xl/theme/theme1.xml — kept verbatim. Excel renders with this exact\n // payload; round-tripping the bytes avoids drift.\n const themeXml: Uint8Array | undefined = (() => {\n if (archive.has(ARC_THEME)) return archive.read(ARC_THEME);\n const themeRel = wbRels.rels.find((r) => r.type === `${REL_NS}/theme`);\n if (themeRel) {\n const themePath = resolveRelTarget(workbookPath, themeRel.target);\n if (archive.has(themePath)) return archive.read(themePath);\n }\n return undefined;\n })();\n\n // 5. Build the Workbook. We bypass `addWorksheet` because that allocates\n // sheetIds via `allocateSheetId`; load preserves the IDs from XML.\n const wb = createWorkbook({ date1904: parseDate1904(wbRoot) });\n if (styles) wb.styles = styles;\n if (properties) wb.properties = properties;\n if (appProperties) wb.appProperties = appProperties;\n if (customProperties) wb.customProperties = customProperties;\n if (themeXml) wb.themeXml = themeXml;\n if (definedNamesFromXml.length > 0) wb.definedNames = definedNamesFromXml;\n const seenTitles = new Set<string>();\n for (const entry of sheetEntries) {\n if (seenTitles.has(entry.name)) {\n throw new OpenXmlSchemaError(`loadWorkbook: duplicate sheet name \"${entry.name}\"`);\n }\n seenTitles.add(entry.name);\n const rel = findById(wbRels, entry.rId);\n if (!rel) {\n throw new OpenXmlSchemaError(`loadWorkbook: sheet \"${entry.name}\" rId \"${entry.rId}\" has no matching rels entry`);\n }\n const sheetPath = resolveRelTarget(workbookPath, rel.target);\n if (!archive.has(sheetPath)) {\n throw new OpenXmlSchemaError(`loadWorkbook: sheet part \"${sheetPath}\" not found in archive`);\n }\n const sheetRelsPath = relsPathFor(sheetPath);\n const sheetRels = archive.has(sheetRelsPath) ? relsFromBytes(archive.read(sheetRelsPath)) : undefined;\n // Build an id → rel index once; the loadTable / loadComments / loadDrawing\n // callbacks are invoked once per cross-reference in the worksheet body and\n // a linear find() inside each would be O(rels × refs). Sheets with many\n // hyperlinks / tables / drawings (e.g. dashboard workbooks) make that\n // accumulation visible.\n const sheetRelsById = sheetRels ? indexRelsById(sheetRels) : undefined;\n const loadTable = sheetRelsById\n ? (relId: string) => {\n const tRel = sheetRelsById.get(relId);\n if (!tRel) return undefined;\n const tablePath = resolveRelTarget(sheetPath, tRel.target);\n if (!archive.has(tablePath)) return undefined;\n return parseTableXml(archive.read(tablePath));\n }\n : undefined;\n const loadComments = sheetRelsById\n ? (relId: string) => {\n const cRel = sheetRelsById.get(relId);\n if (!cRel) return undefined;\n const cPath = resolveRelTarget(sheetPath, cRel.target);\n if (!archive.has(cPath)) return undefined;\n return parseCommentsXml(archive.read(cPath));\n }\n : undefined;\n const loadDrawing = sheetRelsById\n ? (relId: string) => {\n const dRel = sheetRelsById.get(relId);\n if (!dRel) return undefined;\n const dPath = resolveRelTarget(sheetPath, dRel.target);\n if (!archive.has(dPath)) return undefined;\n const drawing = parseDrawingXml(archive.read(dPath));\n // Phase-2: resolve drawing-rels to populate chart payloads.\n const dRelsPath = relsPathFor(dPath);\n if (archive.has(dRelsPath)) {\n const dRels = relsFromBytes(archive.read(dRelsPath));\n const dRelsById = indexRelsById(dRels);\n for (const item of drawing.items) {\n if (item.content.kind === 'chart') {\n const chartRId = item.content.chart.rId;\n if (!chartRId) continue;\n const chartRel = dRelsById.get(chartRId);\n if (!chartRel) continue;\n const chartPath = resolveRelTarget(dPath, chartRel.target);\n if (archive.has(chartPath)) {\n const chartBytes = archive.read(chartPath);\n if (isChartExBytes(chartBytes)) {\n item.content.chart.cxSpace = parseChartExXml(chartBytes);\n } else {\n const space = parseChartXml(chartBytes);\n // Resolve <c:userShapes r:id=\"...\"> via the chart's own\n // rels file (xl/charts/_rels/chartN.xml.rels).\n const userShapesRId = findUserShapesRId(chartBytes);\n if (userShapesRId) {\n const chartRelsPath = relsPathFor(chartPath);\n if (archive.has(chartRelsPath)) {\n const chartRelsObj = relsFromBytes(archive.read(chartRelsPath));\n const usRel = indexRelsById(chartRelsObj).get(userShapesRId);\n if (usRel) {\n const usPath = resolveRelTarget(chartPath, usRel.target);\n if (archive.has(usPath)) {\n try {\n space.userShapes = parseUserShapesXml(archive.read(usPath));\n } catch {\n // Tolerate parse failures (Excel sometimes emits\n // chartDrawing parts with namespaces / shapes\n // outside our model).\n }\n }\n }\n }\n }\n item.content.chart.space = space;\n }\n }\n } else if (item.content.kind === 'picture') {\n const picRId = item.content.picture.rId;\n if (!picRId) continue;\n const picRel = dRelsById.get(picRId);\n if (!picRel) continue;\n const imgPath = resolveRelTarget(dPath, picRel.target);\n if (archive.has(imgPath)) {\n try {\n item.content.picture.image = loadImage(archive.read(imgPath));\n } catch {\n // Unknown / unsupported format — leave bytes-less; callers\n // can read via the rId + archive directly if they need the\n // raw payload.\n }\n }\n }\n }\n }\n return drawing;\n }\n : undefined;\n // Distinguish worksheet vs chartsheet by inspecting the workbook-rels\n // entry's relationship type.\n const isChartsheet = rel.type === `${REL_NS}/chartsheet`;\n if (isChartsheet) {\n const chartsheet = parseChartsheetXml(archive.read(sheetPath), entry.name);\n // Inline drawing reference from the chartsheet XML.\n if (sheetRels) {\n // Find the drawing rel and resolve it the same way worksheets do.\n const drawingRel = sheetRels.rels.find((r) => r.type === `${REL_NS}/drawing`);\n if (drawingRel && loadDrawing) {\n const d = loadDrawing(drawingRel.id);\n if (d) chartsheet.drawing = d;\n }\n }\n const ref: SheetRef = {\n kind: 'chartsheet',\n sheet: chartsheet,\n sheetId: entry.sheetId,\n state: entry.state,\n rId: entry.rId,\n };\n wb.sheets.push(ref);\n continue;\n }\n const ws = parseWorksheetXml(archive.read(sheetPath), entry.name, {\n sharedStrings: sst,\n ...(sheetRels ? { rels: sheetRels } : {}),\n ...(loadTable ? { loadTable } : {}),\n ...(loadComments ? { loadComments } : {}),\n ...(loadDrawing ? { loadDrawing } : {}),\n });\n if (sheetRels) {\n const extras = captureSheetRelsExtras(sheetRels);\n if (extras.length > 0) ws.relsExtras = extras;\n }\n const ref: SheetRef = {\n kind: 'worksheet',\n sheet: ws,\n sheetId: entry.sheetId,\n state: entry.state,\n rId: entry.rId,\n };\n wb.sheets.push(ref);\n }\n\n captureWorkbookXmlExtras(wbRoot, wb);\n captureWorkbookRelsExtras(wbRels, wb);\n\n // Pass-through: capture parts we don't model (VBA / pivot / activeX / OLE /\n // customUI / customXml / etc.) so re-saving doesn't drop them.\n capturePassthrough(archive, manifest, wb);\n return wb;\n}\n\nconst SHEET_MODELED_REL_TYPES: ReadonlySet<string> = new Set([\n `${REL_NS}/hyperlink`,\n `${REL_NS}/table`,\n `${REL_NS}/comments`,\n `${REL_NS}/vmlDrawing`,\n `${REL_NS}/drawing`,\n]);\n\n/**\n * Capture per-sheet rels entries that don't match a modeled type. The writer\n * re-emits these verbatim alongside the freshly allocated modeled rels so\n * captured passthrough parts (pivotTable / queryTable / slicer /\n * printerSettings / oleObject / customProperty / threadedComment) remain\n * reachable from the worksheet after a round-trip.\n */\nfunction captureSheetRelsExtras(\n sheetRels: import('../packaging/relationships').Relationships,\n): Array<{ id: string; type: string; target: string }> {\n const extras: Array<{ id: string; type: string; target: string }> = [];\n for (const rel of sheetRels.rels) {\n if (SHEET_MODELED_REL_TYPES.has(rel.type)) continue;\n extras.push({ id: rel.id, type: rel.type, target: rel.target });\n }\n return extras;\n}\n\n/**\n * Walk top-level children of `<workbook>` and split anything that isn't\n * `<sheets>` or `<definedNames>` into the before/after halves the writer\n * inserts around the modeled elements. Order is preserved within each half so\n * things like `<fileVersion>`, `<workbookPr>`, `<bookViews>`, `<calcPr>`,\n * `<pivotCaches>`, `<extLst>` round-trip in document order.\n */\nfunction captureWorkbookXmlExtras(wbRoot: XmlNode, wb: Workbook): void {\n const beforeSheets: XmlNode[] = [];\n const afterSheets: XmlNode[] = [];\n let seenSheets = false;\n for (const child of wbRoot.children) {\n if (child.name === SHEETS_TAG) {\n seenSheets = true;\n continue;\n }\n if (child.name === DEFINED_NAMES_TAG) continue;\n // Lift <workbookProtection> into the typed workbook field instead of\n // stashing it as a passthrough XmlNode (B5 partial).\n if (child.name === WORKBOOK_PROTECTION_TAG) {\n wb.workbookProtection = parseWorkbookProtection(child);\n continue;\n }\n // Lift <workbookPr> into the typed workbook field. The date1904 attribute\n // is already mirrored onto wb.date1904; everything else stops leaking into\n // bodyExtras.\n if (child.name === WORKBOOK_PR_TAG) {\n const wp = parseWorkbookProperties(child);\n if (wp) wb.workbookProperties = wp;\n continue;\n }\n // Lift <fileSharing> into the typed workbook field.\n if (child.name === FILE_SHARING_TAG) {\n const fs: import('../workbook/file-sharing').FileSharing = {};\n const a = child.attrs;\n const flag = (raw: string | undefined): boolean | undefined => {\n if (raw === '1' || raw === 'true') return true;\n if (raw === '0' || raw === 'false') return false;\n return undefined;\n };\n const ror = flag(a['readOnlyRecommended']);\n if (ror !== undefined) fs.readOnlyRecommended = ror;\n if (a['userName'] !== undefined) fs.userName = a['userName'];\n if (a['reservationPassword'] !== undefined) fs.reservationPassword = a['reservationPassword'];\n if (a['algorithmName'] !== undefined) fs.algorithmName = a['algorithmName'];\n if (a['hashValue'] !== undefined) fs.hashValue = a['hashValue'];\n if (a['saltValue'] !== undefined) fs.saltValue = a['saltValue'];\n if (a['spinCount'] !== undefined) {\n const n = Number.parseInt(a['spinCount'], 10);\n if (Number.isInteger(n)) fs.spinCount = n;\n }\n if (Object.keys(fs).length > 0) wb.fileSharing = fs;\n continue;\n }\n // Lift <fileVersion> into the typed workbook field.\n if (child.name === FILE_VERSION_TAG) {\n const fv: import('../workbook/file-version').FileVersion = {};\n if (child.attrs['appName'] !== undefined) fv.appName = child.attrs['appName'];\n if (child.attrs['lastEdited'] !== undefined) fv.lastEdited = child.attrs['lastEdited'];\n if (child.attrs['lowestEdited'] !== undefined) fv.lowestEdited = child.attrs['lowestEdited'];\n if (child.attrs['rupBuild'] !== undefined) fv.rupBuild = child.attrs['rupBuild'];\n if (child.attrs['codeName'] !== undefined) fv.codeName = child.attrs['codeName'];\n if (Object.keys(fv).length > 0) wb.fileVersion = fv;\n continue;\n }\n // Lift <bookViews> into the typed workbook field.\n if (child.name === BOOK_VIEWS_TAG) {\n const views: import('../workbook/views').WorkbookView[] = [];\n for (const v of findChildren(child, WORKBOOK_VIEW_TAG)) views.push(parseWorkbookView(v));\n if (views.length > 0) wb.bookViews = views;\n continue;\n }\n // Lift <customWorkbookViews> into the typed workbook field.\n if (child.name === CUSTOM_WORKBOOK_VIEWS_TAG) {\n const cws: import('../workbook/views').CustomWorkbookView[] = [];\n for (const v of findChildren(child, CUSTOM_WORKBOOK_VIEW_TAG)) {\n const parsed = parseCustomWorkbookView(v);\n if (parsed) cws.push(parsed);\n }\n if (cws.length > 0) wb.customWorkbookViews = cws;\n continue;\n }\n // Lift <calcPr> into the typed workbook field.\n if (child.name === CALC_PR_TAG) {\n const cp = parseCalcProperties(child);\n if (cp) wb.calcProperties = cp;\n continue;\n }\n // Lift <oleSize ref=\"…\"/> as a single typed string attribute.\n if (child.name === OLE_SIZE_TAG) {\n const ref = child.attrs['ref'];\n if (ref) wb.oleSize = ref;\n continue;\n }\n // Lift <smartTagPr embed=\"1\" show=\"all\"/>.\n if (child.name === SMART_TAG_PR_TAG) {\n const out: import('../workbook/smart-tags').SmartTagProperties = {};\n const a = child.attrs;\n if (a['embed'] === '1' || a['embed'] === 'true') out.embed = true;\n else if (a['embed'] === '0' || a['embed'] === 'false') out.embed = false;\n if (a['show'] === 'all' || a['show'] === 'noIndicator') out.show = a['show'];\n if (Object.keys(out).length > 0) wb.smartTagPr = out;\n continue;\n }\n // Lift <smartTagTypes><smartTagType .../></smartTagTypes>.\n if (child.name === SMART_TAG_TYPES_TAG) {\n const tags: import('../workbook/smart-tags').SmartTagType[] = [];\n for (const t of findChildren(child, SMART_TAG_TYPE_TAG)) {\n const entry: import('../workbook/smart-tags').SmartTagType = {};\n if (t.attrs['namespaceUri'] !== undefined) entry.namespaceUri = t.attrs['namespaceUri'];\n if (t.attrs['name'] !== undefined) entry.name = t.attrs['name'];\n if (t.attrs['url'] !== undefined) entry.url = t.attrs['url'];\n if (Object.keys(entry).length > 0) tags.push(entry);\n }\n if (tags.length > 0) wb.smartTagTypes = tags;\n continue;\n }\n // Lift <functionGroups builtInGroupCount=…><functionGroup\n // name=…/></functionGroups>.\n if (child.name === FUNCTION_GROUPS_TAG) {\n const fg: import('../workbook/function-groups').FunctionGroups = { groups: [] };\n const bicgRaw = child.attrs['builtInGroupCount'];\n if (bicgRaw !== undefined) {\n const n = Number.parseInt(bicgRaw, 10);\n if (Number.isInteger(n)) fg.builtInGroupCount = n;\n }\n for (const g of findChildren(child, FUNCTION_GROUP_TAG)) {\n const name = g.attrs['name'];\n if (name) fg.groups.push({ name });\n }\n if (fg.groups.length > 0 || fg.builtInGroupCount !== undefined) wb.functionGroups = fg;\n continue;\n }\n // Lift <externalReferences><externalReference\n // r:id=…/></externalReferences>.\n if (child.name === EXTERNAL_REFERENCES_TAG) {\n const refs: Array<{ rId: string }> = [];\n for (const er of findChildren(child, EXTERNAL_REFERENCE_TAG)) {\n const rId = er.attrs[`{${REL_NS}}id`];\n if (rId) refs.push({ rId });\n }\n if (refs.length > 0) wb.externalReferences = refs;\n continue;\n }\n // Lift <pivotCaches><pivotCache cacheId=… r:id=…/></pivotCaches>.\n if (child.name === PIVOT_CACHES_TAG) {\n const caches: Array<{ cacheId: number; rId: string }> = [];\n for (const pc of findChildren(child, PIVOT_CACHE_TAG)) {\n const cacheIdAttr = pc.attrs['cacheId'];\n const rId = pc.attrs[`{${REL_NS}}id`];\n if (cacheIdAttr === undefined || !rId) continue;\n const cacheId = Number.parseInt(cacheIdAttr, 10);\n if (!Number.isInteger(cacheId)) continue;\n caches.push({ cacheId, rId });\n }\n if (caches.length > 0) wb.pivotCaches = caches;\n continue;\n }\n // Lift <fileRecoveryPr> into the typed workbook field.\n if (child.name === FILE_RECOVERY_PR_TAG) {\n const fp: import('../workbook/file-recovery').FileRecoveryProperties = {};\n const a = child.attrs;\n const flag = (raw: string | undefined): boolean | undefined => {\n if (raw === '1' || raw === 'true') return true;\n if (raw === '0' || raw === 'false') return false;\n return undefined;\n };\n const ar = flag(a['autoRecover']);\n if (ar !== undefined) fp.autoRecover = ar;\n const cs = flag(a['crashSave']);\n if (cs !== undefined) fp.crashSave = cs;\n const del = flag(a['dataExtractLoad']);\n if (del !== undefined) fp.dataExtractLoad = del;\n const rl = flag(a['repairLoad']);\n if (rl !== undefined) fp.repairLoad = rl;\n if (Object.keys(fp).length > 0) wb.fileRecoveryPr = fp;\n continue;\n }\n if (seenSheets) afterSheets.push(child);\n else beforeSheets.push(child);\n }\n if (beforeSheets.length > 0 || afterSheets.length > 0) {\n wb.workbookXmlExtras = { beforeSheets, afterSheets };\n }\n}\n\nconst SHOW_OBJECTS_MODES: ReadonlyArray<import('../workbook/workbook-properties').ShowObjectsMode> = [\n 'all',\n 'placeholders',\n 'none',\n];\nconst UPDATE_LINKS_MODES: ReadonlyArray<import('../workbook/workbook-properties').UpdateLinksMode> = [\n 'userSet',\n 'never',\n 'always',\n];\n\nconst parseWorkbookProperties = (\n node: XmlNode,\n): import('../workbook/workbook-properties').WorkbookProperties | undefined => {\n const out: import('../workbook/workbook-properties').WorkbookProperties = {};\n const a = node.attrs;\n const flag = (raw: string | undefined): boolean | undefined => {\n if (raw === '1' || raw === 'true') return true;\n if (raw === '0' || raw === 'false') return false;\n return undefined;\n };\n const intAttr = (k: string): number | undefined => {\n if (a[k] === undefined) return undefined;\n const n = Number.parseInt(a[k], 10);\n return Number.isInteger(n) ? n : undefined;\n };\n\n const bools = [\n 'date1904',\n 'dateCompatibility',\n 'showBorderUnselectedTables',\n 'filterPrivacy',\n 'promptedSolutions',\n 'showInkAnnotation',\n 'backupFile',\n 'saveExternalLinkValues',\n 'hidePivotFieldList',\n 'showPivotChartFilter',\n 'allowRefreshQuery',\n 'publishItems',\n 'checkCompatibility',\n 'autoCompressPictures',\n 'refreshAllConnections',\n ] as const satisfies ReadonlyArray<keyof import('../workbook/workbook-properties').WorkbookProperties>;\n for (const k of bools) {\n const v = flag(a[k]);\n if (v !== undefined) out[k] = v;\n }\n\n const showObjects = a['showObjects'];\n if (showObjects && SHOW_OBJECTS_MODES.includes(showObjects as import('../workbook/workbook-properties').ShowObjectsMode)) {\n out.showObjects = showObjects as import('../workbook/workbook-properties').ShowObjectsMode;\n }\n const updateLinks = a['updateLinks'];\n if (updateLinks && UPDATE_LINKS_MODES.includes(updateLinks as import('../workbook/workbook-properties').UpdateLinksMode)) {\n out.updateLinks = updateLinks as import('../workbook/workbook-properties').UpdateLinksMode;\n }\n if (a['codeName'] !== undefined) out.codeName = a['codeName'];\n const dtv = intAttr('defaultThemeVersion');\n if (dtv !== undefined) out.defaultThemeVersion = dtv;\n\n return Object.keys(out).length > 0 ? out : undefined;\n};\n\nconst CALC_MODES: ReadonlyArray<import('../workbook/calc-properties').CalcMode> = [\n 'manual',\n 'auto',\n 'autoNoTable',\n];\nconst REF_MODES: ReadonlyArray<import('../workbook/calc-properties').RefMode> = ['A1', 'R1C1'];\n\nconst parseCalcProperties = (\n node: XmlNode,\n): import('../workbook/calc-properties').CalcProperties | undefined => {\n const out: import('../workbook/calc-properties').CalcProperties = {};\n const a = node.attrs;\n const flag = (raw: string | undefined): boolean | undefined => {\n if (raw === '1' || raw === 'true') return true;\n if (raw === '0' || raw === 'false') return false;\n return undefined;\n };\n const intAttr = (k: string): number | undefined => {\n if (a[k] === undefined) return undefined;\n const n = Number.parseInt(a[k], 10);\n return Number.isInteger(n) ? n : undefined;\n };\n const floatAttr = (k: string): number | undefined => {\n if (a[k] === undefined) return undefined;\n const n = Number.parseFloat(a[k]);\n return Number.isFinite(n) ? n : undefined;\n };\n\n const calcId = intAttr('calcId');\n if (calcId !== undefined) out.calcId = calcId;\n const calcMode = a['calcMode'];\n if (calcMode && CALC_MODES.includes(calcMode as import('../workbook/calc-properties').CalcMode)) {\n out.calcMode = calcMode as import('../workbook/calc-properties').CalcMode;\n }\n const fcol = flag(a['fullCalcOnLoad']);\n if (fcol !== undefined) out.fullCalcOnLoad = fcol;\n const refMode = a['refMode'];\n if (refMode && REF_MODES.includes(refMode as import('../workbook/calc-properties').RefMode)) {\n out.refMode = refMode as import('../workbook/calc-properties').RefMode;\n }\n const iterate = flag(a['iterate']);\n if (iterate !== undefined) out.iterate = iterate;\n const iterateCount = intAttr('iterateCount');\n if (iterateCount !== undefined) out.iterateCount = iterateCount;\n const iterateDelta = floatAttr('iterateDelta');\n if (iterateDelta !== undefined) out.iterateDelta = iterateDelta;\n const fullPrecision = flag(a['fullPrecision']);\n if (fullPrecision !== undefined) out.fullPrecision = fullPrecision;\n const calcCompleted = flag(a['calcCompleted']);\n if (calcCompleted !== undefined) out.calcCompleted = calcCompleted;\n const calcOnSave = flag(a['calcOnSave']);\n if (calcOnSave !== undefined) out.calcOnSave = calcOnSave;\n const concurrentCalc = flag(a['concurrentCalc']);\n if (concurrentCalc !== undefined) out.concurrentCalc = concurrentCalc;\n const concurrentManualCount = intAttr('concurrentManualCount');\n if (concurrentManualCount !== undefined) out.concurrentManualCount = concurrentManualCount;\n const forceFullCalc = flag(a['forceFullCalc']);\n if (forceFullCalc !== undefined) out.forceFullCalc = forceFullCalc;\n\n return Object.keys(out).length > 0 ? out : undefined;\n};\n\nconst SHOW_COMMENTS_MODES: ReadonlyArray<import('../workbook/views').CustomViewShowComments> = [\n 'commNone',\n 'commIndicator',\n 'commIndAndComment',\n];\nconst SHOW_OBJECTS_CV_MODES: ReadonlyArray<import('../workbook/views').CustomViewShowObjects> = [\n 'all',\n 'placeholders',\n 'none',\n];\n\nconst parseCustomWorkbookView = (\n node: XmlNode,\n): import('../workbook/views').CustomWorkbookView | undefined => {\n const a = node.attrs;\n const name = a['name'];\n const guid = a['guid'];\n if (!name || !guid) return undefined;\n const flag = (raw: string | undefined): boolean | undefined => {\n if (raw === '1' || raw === 'true') return true;\n if (raw === '0' || raw === 'false') return false;\n return undefined;\n };\n const intAttr = (k: string): number | undefined => {\n if (a[k] === undefined) return undefined;\n const n = Number.parseInt(a[k], 10);\n return Number.isInteger(n) ? n : undefined;\n };\n const ww = intAttr('windowWidth') ?? 0;\n const wh = intAttr('windowHeight') ?? 0;\n const asid = intAttr('activeSheetId') ?? 0;\n const out: import('../workbook/views').CustomWorkbookView = {\n name,\n guid,\n windowWidth: ww,\n windowHeight: wh,\n activeSheetId: asid,\n };\n\n const boolKeys = [\n 'autoUpdate',\n 'changesSavedWin',\n 'onlySync',\n 'personalView',\n 'includePrintSettings',\n 'includeHiddenRowCol',\n 'maximized',\n 'minimized',\n 'showHorizontalScroll',\n 'showVerticalScroll',\n 'showSheetTabs',\n 'showFormulaBar',\n 'showStatusbar',\n ] as const satisfies ReadonlyArray<keyof import('../workbook/views').CustomWorkbookView>;\n for (const k of boolKeys) {\n const v = flag(a[k]);\n if (v !== undefined) out[k] = v;\n }\n const intKeys = [\n 'mergeInterval',\n 'xWindow',\n 'yWindow',\n 'tabRatio',\n ] as const satisfies ReadonlyArray<keyof import('../workbook/views').CustomWorkbookView>;\n for (const k of intKeys) {\n const v = intAttr(k);\n if (v !== undefined) out[k] = v;\n }\n\n const sc = a['showComments'];\n if (sc && SHOW_COMMENTS_MODES.includes(sc as import('../workbook/views').CustomViewShowComments)) {\n out.showComments = sc as import('../workbook/views').CustomViewShowComments;\n }\n const so = a['showObjects'];\n if (so && SHOW_OBJECTS_CV_MODES.includes(so as import('../workbook/views').CustomViewShowObjects)) {\n out.showObjects = so as import('../workbook/views').CustomViewShowObjects;\n }\n return out;\n};\n\nconst VISIBILITIES: ReadonlyArray<import('../workbook/views').WorkbookViewVisibility> = [\n 'visible',\n 'hidden',\n 'veryHidden',\n];\n\nconst parseWorkbookView = (node: XmlNode): import('../workbook/views').WorkbookView => {\n const out: import('../workbook/views').WorkbookView = {};\n const a = node.attrs;\n const flag = (raw: string | undefined): boolean | undefined => {\n if (raw === '1' || raw === 'true') return true;\n if (raw === '0' || raw === 'false') return false;\n return undefined;\n };\n const intAttr = (k: string): number | undefined => {\n if (a[k] === undefined) return undefined;\n const n = Number.parseInt(a[k], 10);\n return Number.isInteger(n) ? n : undefined;\n };\n\n const visibility = a['visibility'];\n if (visibility && VISIBILITIES.includes(visibility as import('../workbook/views').WorkbookViewVisibility)) {\n out.visibility = visibility as import('../workbook/views').WorkbookViewVisibility;\n }\n const minimized = flag(a['minimized']);\n if (minimized !== undefined) out.minimized = minimized;\n const shScroll = flag(a['showHorizontalScroll']);\n if (shScroll !== undefined) out.showHorizontalScroll = shScroll;\n const svScroll = flag(a['showVerticalScroll']);\n if (svScroll !== undefined) out.showVerticalScroll = svScroll;\n const sst = flag(a['showSheetTabs']);\n if (sst !== undefined) out.showSheetTabs = sst;\n const xWindow = intAttr('xWindow');\n if (xWindow !== undefined) out.xWindow = xWindow;\n const yWindow = intAttr('yWindow');\n if (yWindow !== undefined) out.yWindow = yWindow;\n const ww = intAttr('windowWidth');\n if (ww !== undefined) out.windowWidth = ww;\n const wh = intAttr('windowHeight');\n if (wh !== undefined) out.windowHeight = wh;\n const tr = intAttr('tabRatio');\n if (tr !== undefined) out.tabRatio = tr;\n const fs = intAttr('firstSheet');\n if (fs !== undefined) out.firstSheet = fs;\n const at = intAttr('activeTab');\n if (at !== undefined) out.activeTab = at;\n const adg = flag(a['autoFilterDateGrouping']);\n if (adg !== undefined) out.autoFilterDateGrouping = adg;\n return out;\n};\n\nconst parseWorkbookProtection = (node: XmlNode): import('../workbook/protection').WorkbookProtection => {\n const out: import('../workbook/protection').WorkbookProtection = {};\n const a = node.attrs;\n const flag = (raw: string | undefined): boolean | undefined => {\n if (raw === '1' || raw === 'true') return true;\n if (raw === '0' || raw === 'false') return false;\n return undefined;\n };\n if (a['workbookPassword'] !== undefined) out.workbookPassword = a['workbookPassword'];\n if (a['workbookPasswordCharacterSet'] !== undefined)\n out.workbookPasswordCharacterSet = a['workbookPasswordCharacterSet'];\n if (a['workbookAlgorithmName'] !== undefined) out.workbookAlgorithmName = a['workbookAlgorithmName'];\n if (a['workbookHashValue'] !== undefined) out.workbookHashValue = a['workbookHashValue'];\n if (a['workbookSaltValue'] !== undefined) out.workbookSaltValue = a['workbookSaltValue'];\n if (a['workbookSpinCount'] !== undefined) {\n const n = Number.parseInt(a['workbookSpinCount'], 10);\n if (Number.isInteger(n)) out.workbookSpinCount = n;\n }\n if (a['revisionsPassword'] !== undefined) out.revisionsPassword = a['revisionsPassword'];\n if (a['revisionsPasswordCharacterSet'] !== undefined)\n out.revisionsPasswordCharacterSet = a['revisionsPasswordCharacterSet'];\n if (a['revisionsAlgorithmName'] !== undefined) out.revisionsAlgorithmName = a['revisionsAlgorithmName'];\n if (a['revisionsHashValue'] !== undefined) out.revisionsHashValue = a['revisionsHashValue'];\n if (a['revisionsSaltValue'] !== undefined) out.revisionsSaltValue = a['revisionsSaltValue'];\n if (a['revisionsSpinCount'] !== undefined) {\n const n = Number.parseInt(a['revisionsSpinCount'], 10);\n if (Number.isInteger(n)) out.revisionsSpinCount = n;\n }\n const ls = flag(a['lockStructure']);\n if (ls !== undefined) out.lockStructure = ls;\n const lw = flag(a['lockWindows']);\n if (lw !== undefined) out.lockWindows = lw;\n const lr = flag(a['lockRevision']);\n if (lr !== undefined) out.lockRevision = lr;\n return out;\n};\n\n/**\n * Capture workbook-rels entries that don't match a modeled type so the writer\n * can re-emit them with their original Id (and any captured `<pivotCaches\n * r:id=\"…\"/>` etc. still resolves after a round-trip). Modeled non-sheet rels\n * (sst / styles / theme / vbaProject) keep their original Id via\n * `wb.workbookRelOriginalIds` so the writer can prefer those over freshly\n * allocated ones.\n */\nfunction captureWorkbookRelsExtras(\n wbRels: import('../packaging/relationships').Relationships,\n wb: Workbook,\n): void {\n const SHEET_RELS = new Set([`${REL_NS}/worksheet`, `${REL_NS}/chartsheet`]);\n const original: NonNullable<Workbook['workbookRelOriginalIds']> = {};\n const extras: Array<{ id: string; type: string; target: string }> = [];\n for (const rel of wbRels.rels) {\n if (SHEET_RELS.has(rel.type)) continue;\n if (rel.type === `${REL_NS}/sharedStrings`) {\n original.sharedStrings = rel.id;\n continue;\n }\n if (rel.type === `${REL_NS}/styles`) {\n original.styles = rel.id;\n continue;\n }\n if (rel.type === `${REL_NS}/theme`) {\n original.theme = rel.id;\n continue;\n }\n if (rel.type === `${REL_NS}/vbaProject`) {\n original.vbaProject = rel.id;\n continue;\n }\n extras.push({ id: rel.id, type: rel.type, target: rel.target });\n }\n if (Object.keys(original).length > 0) wb.workbookRelOriginalIds = original;\n if (extras.length > 0) wb.workbookRelsExtras = extras;\n}\n\nconst PASSTHROUGH_PREFIXES: ReadonlyArray<string> = [\n 'xl/activeX/',\n 'xl/ctrlProps/',\n 'xl/embeddings/',\n 'xl/externalLinks/',\n // xl/model/ — Power Pivot data model (`xl/model/item.data` etc.).\n 'xl/model/',\n 'xl/persons/',\n 'xl/pivotCache/',\n 'xl/pivotTables/',\n 'xl/printerSettings/',\n 'xl/queryTables/',\n 'xl/richData/',\n 'xl/slicerCaches/',\n 'xl/slicers/',\n 'xl/threadedComments/',\n 'xl/timelineCaches/',\n 'xl/timelines/',\n 'xl/workbookCache/',\n 'customUI/',\n 'customXml/',\n];\n\n/**\n * Excel emits both form-control VMLs and comment VMLs at\n * `xl/drawings/vmlDrawingN.vml`. Filename alone can't tell them apart, but\n * ECMA-376 §17.18.51 requires comment shapes to carry `<x:ClientData\n * ObjectType=\"Note\">`, so a byte-search for that marker decides which path the\n * file belongs on:\n *\n * - With marker → comment VML; the comments writer regenerates\n * these from `Worksheet.legacyComments`, so we must not capture them as\n * passthrough (would duplicate the entry on save).\n * - Without marker → control / OLE / shape VML; capture as\n * passthrough so form controls survive load → save → load.\n */\nconst COMMENT_VML_MARKER = 'ObjectType=\"Note\"';\n// Latin-1 is a 1-to-1 byte-to-character mapping for the 0–255 range, so a\n// String.indexOf scan on the decoded view returns the same answer as a byte\n// search but takes advantage of V8's native StringPrototypeIndexOf — orders\n// of magnitude faster than the JS loop the previous implementation used on\n// multi-megabyte VML drawings.\nconst LATIN1_DECODER = new TextDecoder('latin1');\n\nconst isVmlDrawing = (path: string): boolean =>\n path.startsWith('xl/drawings/') && path.endsWith('.vml');\n\nconst containsCommentMarker = (bytes: Uint8Array): boolean =>\n LATIN1_DECODER.decode(bytes).includes(COMMENT_VML_MARKER);\n\n/**\n * Top-level xl/*.xml files that aren't modeled but Excel relies on (or\n * harmlessly preserves). Captured by exact path; their content types come\n * through the manifest Override map.\n *\n * - `xl/calcChain.xml` — calculation order hint (Excel rebuilds\n * it on first open if missing, but losing it forces a full recalc).\n * - `xl/connections.xml` — external data connection metadata.\n * - `xl/persons/` — threaded-comment author registry\n * (Excel 365). Captured under the prefix list below.\n * - `xl/metadata.xml` — Excel 365 dynamic-array cell metadata.\n * - `xl/SheetMetadata.xml` — variant casing of the same.\n */\nconst PASSTHROUGH_EXACT_PATHS: ReadonlySet<string> = new Set([\n 'xl/calcChain.xml',\n 'xl/connections.xml',\n 'xl/metadata.xml',\n 'xl/SheetMetadata.xml',\n // docProps/thumbnail.jpeg — workbook preview image Excel renders in the OS\n // file browser. JPEG by default; some files use PNG.\n 'docProps/thumbnail.jpeg',\n 'docProps/thumbnail.jpg',\n 'docProps/thumbnail.png',\n 'docProps/thumbnail.wmf',\n 'docProps/thumbnail.emf',\n]);\n\nconst isPassthroughPath = (path: string, bytes?: Uint8Array): boolean => {\n if (PASSTHROUGH_EXACT_PATHS.has(path)) return true;\n if (PASSTHROUGH_PREFIXES.some((p) => path.startsWith(p))) return true;\n if (isVmlDrawing(path) && bytes) {\n // Comment VML is regenerated; control / shape VML passes through.\n return !containsCommentMarker(bytes);\n }\n return false;\n};\n\n/**\n * Walk the archive after the modeled parts are loaded and capture any remaining\n * content into `wb.passthrough`. The dedicated VBA project binaries land on\n * their own slots so the writer can promote the workbook content type to xlsm.\n */\nfunction capturePassthrough(\n archive: ZipArchive,\n manifest: import('../packaging/manifest').Manifest,\n wb: Workbook,\n): void {\n const overrides = new Map<string, string>();\n for (const o of manifest.overrides) {\n // Manifest paths are package-absolute (`/xl/...`); strip the leading slash.\n overrides.set(o.partName.replace(/^\\//, ''), o.contentType);\n }\n for (const path of archive.list()) {\n if (path === 'xl/vbaProject.bin') {\n wb.vbaProject = archive.read(path);\n continue;\n }\n if (path === 'xl/vbaProjectSignature.bin') {\n wb.vbaSignature = archive.read(path);\n continue;\n }\n // VML drawings need a content peek to distinguish comment-VML (regenerated\n // from ws.legacyComments) from form-control / shape VML (passthrough). Read\n // once and reuse for the actual capture.\n let cached: Uint8Array | undefined;\n if (isVmlDrawing(path)) cached = archive.read(path);\n if (!isPassthroughPath(path, cached)) continue;\n if (!wb.passthrough) wb.passthrough = new Map();\n wb.passthrough.set(path, cached ?? archive.read(path));\n const ct = overrides.get(path);\n if (ct !== undefined) {\n if (!wb.passthroughContentTypes) wb.passthroughContentTypes = new Map();\n wb.passthroughContentTypes.set(path, ct);\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"save-RohQtgEZ.mjs","names":["serializeXmlNode"],"sources":["../src/io/save.ts"],"sourcesContent":["// Public `saveWorkbook` entry point.\n//\n// **Stage 1 minimum**: emits the bare set of parts a Workbook needs to\n// round-trip through `loadWorkbook`:\n//\n// [Content_Types].xml\n// _rels/.rels\n// xl/workbook.xml\n// xl/_rels/workbook.xml.rels\n// xl/worksheets/sheetN.xml ...\n// xl/styles.xml\n// xl/sharedStrings.xml (only when sst is non-empty)\n//\n// docProps / theme / VBA / drawings / charts are reserved for later iterations\n// — load tolerates their absence.\n\nimport { escapeXmlAttr, escapeXmlText } from '../utils/escape';\nimport { chartToBytes } from '../chart/chart-xml';\nimport { chartExToBytes } from '../chart/cx/chartex-xml';\nimport { userShapesToBytes } from '../chart/user-shapes-xml';\nimport { chartsheetToBytes } from '../chartsheet/chartsheet-xml';\nimport type { Drawing, DrawingItem } from '../drawing/drawing';\nimport { drawingToBytes } from '../drawing/drawing-xml';\nimport { IMAGE_FORMAT_EXTENSION, IMAGE_FORMAT_MIME, type XlsxImageFormat } from '../drawing/image';\nimport type { XlsxSink } from '../io/sink';\nimport { OpenXmlIoError, OpenXmlSchemaError } from '../utils/exceptions';\nimport { corePropsToBytes } from '../packaging/core';\nimport { customPropsToBytes } from '../packaging/custom';\nimport { extendedPropsToBytes } from '../packaging/extended';\nimport { addDefault, addOverride, makeManifest, manifestToBytes } from '../packaging/manifest';\nimport { makeRelationships, type Relationships, relsToBytes } from '../packaging/relationships';\nimport { stylesheetToBytes } from '../styles/stylesheet-writer';\nimport { makeSharedStrings, sharedStringsToBytes } from '../workbook/shared-strings';\nimport { type Workbook, validateSheetTitle } from '../workbook/workbook';\nimport type { LegacyComment } from '../worksheet/comments';\nimport { commentsToBytes, placeholderVmlDrawing } from '../worksheet/comments-xml';\nimport type { TableDefinition } from '../worksheet/table';\nimport { tableToBytes } from '../worksheet/table-xml';\nimport { worksheetToBytes } from '../worksheet/writer';\nimport { serializeXml as serializeXmlNode } from '../xml/serializer';\nimport {\n ARC_APP,\n ARC_CONTENT_TYPES,\n ARC_CORE,\n ARC_CUSTOM,\n ARC_ROOT_RELS,\n ARC_SHARED_STRINGS,\n ARC_STYLE,\n ARC_THEME,\n ARC_WORKBOOK,\n ARC_WORKBOOK_RELS,\n CHARTEX_TYPE,\n CPROPS_TYPE,\n PKG_REL_NS,\n REL_NS,\n SHARED_STRINGS_TYPE,\n SHEET_MAIN_NS,\n STYLES_TYPE,\n THEME_TYPE,\n WORKSHEET_TYPE,\n XLSX_TYPE,\n} from '../xml/namespaces';\nimport { createZipWriter } from '../zip/writer';\n\nconst CORE_PROPS_TYPE = 'application/vnd.openxmlformats-package.core-properties+xml';\nconst EXT_PROPS_TYPE = 'application/vnd.openxmlformats-officedocument.extended-properties+xml';\nconst CORE_PROPS_REL = `${PKG_REL_NS}/metadata/core-properties`;\nconst EXT_PROPS_REL = `${REL_NS}/extended-properties`;\nconst CUSTOM_PROPS_REL = `${REL_NS}/custom-properties`;\nconst THEME_REL = `${REL_NS}/theme`;\nconst TABLE_REL = `${REL_NS}/table`;\nconst TABLE_TYPE = 'application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml';\nconst COMMENTS_REL = `${REL_NS}/comments`;\nconst VML_DRAWING_REL = `${REL_NS}/vmlDrawing`;\nconst COMMENTS_TYPE = 'application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml';\nconst VML_DRAWING_TYPE = 'application/vnd.openxmlformats-officedocument.vmlDrawing';\nconst DRAWING_REL = `${REL_NS}/drawing`;\nconst DRAWING_TYPE = 'application/vnd.openxmlformats-officedocument.drawing+xml';\nconst CHART_REL = `${REL_NS}/chart`;\nconst CHARTEX_REL = 'http://schemas.microsoft.com/office/2014/relationships/chartEx';\nconst CHART_TYPE = 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml';\nconst IMAGE_REL = `${REL_NS}/image`;\nconst CHARTSHEET_REL = `${REL_NS}/chartsheet`;\nconst CHARTSHEET_TYPE = 'application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml';\nconst CHART_USER_SHAPES_REL = `${REL_NS}/chartUserShapes`;\n\nexport interface SaveOptions {\n /** Reserved — passes through to the underlying ZIP writer when implemented. */\n compressionLevel?: number;\n}\n\n/** Convenience: serialise a Workbook to an in-memory `Uint8Array` xlsx.\n *\n * Browser-safe: this path uses an in-memory `Uint8Array` sink and never\n * touches Node's `Buffer` global, so it works unchanged in browser bundles.\n */\nexport async function workbookToBytes(wb: Workbook, opts: SaveOptions = {}): Promise<Uint8Array> {\n const sink = toUint8ArraySink();\n await saveWorkbook(wb, sink, opts);\n return sink.result();\n}\n\nconst toUint8ArraySink = (): XlsxSink & { result(): Uint8Array } => {\n const chunks: Uint8Array[] = [];\n let finalised: Uint8Array | undefined;\n const finalise = (): Uint8Array => {\n if (finalised !== undefined) return finalised;\n let total = 0;\n for (const c of chunks) total += c.byteLength;\n const out = new Uint8Array(total);\n let off = 0;\n for (const c of chunks) {\n out.set(c, off);\n off += c.byteLength;\n }\n finalised = out;\n chunks.length = 0;\n return out;\n };\n return {\n toBytes() {\n return {\n write(chunk: Uint8Array): void {\n if (finalised !== undefined) {\n throw new OpenXmlIoError('workbookToBytes sink: write after finish');\n }\n if (!(chunk instanceof Uint8Array)) {\n throw new OpenXmlIoError('workbookToBytes sink: chunk is not a Uint8Array');\n }\n chunks.push(chunk);\n },\n async finish(): Promise<Uint8Array> {\n return finalise();\n },\n abort(): void {\n if (finalised !== undefined) return;\n finalised = new Uint8Array(0);\n chunks.length = 0;\n },\n };\n },\n result(): Uint8Array {\n return finalise();\n },\n };\n};\n\n/**\n * Validate every sheet title against Excel's character + length rules and\n * confirm titles are unique within the workbook. Catches bad state introduced\n * via direct mutation (`ws.title = ...`) that bypassed the public mutators.\n *\n * Without this gate, a workbook with an invalid sheet name would round-trip to\n * an xlsx Excel rejects with a generic \"file is corrupt\" dialog on open —\n * making it hard to diagnose. Raising at save time keeps the bad state\n * recoverable: callers can `renameSheet` and retry.\n */\nconst validateSheetTitles = (wb: Workbook): void => {\n const seen = new Map<string, number>();\n for (let i = 0; i < wb.sheets.length; i++) {\n const ref = wb.sheets[i];\n if (!ref) continue;\n const title = ref.sheet.title;\n const reason = validateSheetTitle(title);\n if (reason) {\n throw new OpenXmlSchemaError(`saveWorkbook: sheet[${i}] title \"${title}\": ${reason}`);\n }\n const lower = title.toLowerCase();\n const prior = seen.get(lower);\n if (prior !== undefined) {\n throw new OpenXmlSchemaError(\n `saveWorkbook: sheet[${i}] title \"${title}\" collides with sheet[${prior}]` +\n ` (Excel treats sheet names case-insensitively for uniqueness).`,\n );\n }\n seen.set(lower, i);\n }\n};\n\n/** Save a workbook through the given sink. Returns once `finalize()` resolves. */\nexport async function saveWorkbook(wb: Workbook, sink: XlsxSink, _opts: SaveOptions = {}): Promise<void> {\n validateSheetTitles(wb);\n const writer = createZipWriter(sink);\n try {\n await saveWorkbookImpl(wb, writer);\n } catch (err) {\n // Release the sink so streaming destinations (`toFile` / `toWritable`)\n // don't leave a half-written file looking valid. abort() is idempotent so\n // a successful finalize() above is a no-op here.\n writer.abort(err);\n throw err;\n }\n}\n\nasync function saveWorkbookImpl(wb: Workbook, writer: ReturnType<typeof createZipWriter>): Promise<void> {\n // ---- 1. assemble the per-sheet rels + serialise each worksheet ----------\n const sst = makeSharedStrings();\n interface SheetEmit {\n id: string;\n target: string;\n bytes: Uint8Array;\n /** OOXML relationship type used in workbook.xml.rels. */\n relType: string;\n /** ZIP archive path the bytes are written to. */\n archivePath: string;\n /** Override content type for [Content_Types].xml. */\n contentType: string;\n /** Per-sheet rels — populated only if the sheet has hyperlinks / drawings / etc. */\n rels?: Relationships;\n }\n const sheetEmits: SheetEmit[] = [];\n // Workbook-global table counter so xl/tables/tableN.xml ids stay unique.\n const tableEmits: Array<{ id: number; bytes: Uint8Array }> = [];\n let nextTableId = 1;\n // Same counter pattern for comments parts. The comments part and the VML\n // drawing share their N because Excel always emits them paired.\n interface CommentEmit {\n id: number;\n commentsBytes: Uint8Array;\n vmlBytes: Uint8Array;\n }\n const commentEmits: CommentEmit[] = [];\n let nextCommentsId = 1;\n // Drawings: workbook-global drawingN counter for xl/drawings/drawingN.xml +\n // matching drawing-rels file (when chart items are present).\n interface DrawingEmit {\n id: number;\n bytes: Uint8Array;\n /** Drawing rels — when non-empty we also emit the rels file. */\n rels?: Relationships;\n }\n const drawingEmits: DrawingEmit[] = [];\n let nextDrawingId = 1;\n // Chart parts share a workbook-global counter so xl/charts/chartN.xml ids\n // stay unique.\n const chartEmits: Array<{\n id: number;\n bytes: Uint8Array;\n isCx: boolean;\n /** Per-chart rels file (only emitted when chart.userShapes is set). */\n rels?: Relationships;\n }> = [];\n let nextChartId = 1;\n // Workbook-global counter for chartDrawing parts. Each chart with userShapes\n // set produces one xl/drawings/chartDrawingN.xml entry.\n const userShapeEmits: Array<{ id: number; bytes: Uint8Array }> = [];\n let nextUserShapesId = 1;\n // Workbook-global counter for image media parts. Excel uses\n // xl/media/imageN.{ext} where N is shared across the package.\n interface ImageEmit {\n id: number;\n /** File extension (without the dot) — also drives the manifest Default. */\n ext: string;\n bytes: Uint8Array;\n }\n const imageEmits: ImageEmit[] = [];\n const imageExts = new Set<string>();\n let nextImageId = 1;\n // Track separate counters so worksheet / chartsheet IDs do not collide (Excel\n // uses xl/worksheets/sheetN.xml and xl/chartsheets/sheetM.xml independently\n // of one another).\n let nextWorksheetId = 1;\n let nextChartsheetId = 1;\n // Pre-claim every original rId so freshly allocated ones (sheets without a\n // captured rId, plus modeled non-sheet rels) avoid collision with captured\n // workbookRelsExtras and the modeled non-sheet original ids.\n const claimedRIds = new Set<string>();\n for (const ref of wb.sheets) {\n if (ref.rId !== undefined) claimedRIds.add(ref.rId);\n }\n if (wb.workbookRelOriginalIds) {\n for (const v of Object.values(wb.workbookRelOriginalIds)) {\n if (typeof v === 'string') claimedRIds.add(v);\n }\n }\n if (wb.workbookRelsExtras) {\n for (const e of wb.workbookRelsExtras) claimedRIds.add(e.id);\n }\n let nextRIdCursor = 1;\n const allocateRId = (): string => {\n let id = `rId${nextRIdCursor}`;\n while (claimedRIds.has(id)) {\n nextRIdCursor++;\n id = `rId${nextRIdCursor}`;\n }\n claimedRIds.add(id);\n nextRIdCursor++;\n return id;\n };\n wb.sheets.forEach((ref, _i) => {\n const isChartsheet = ref.kind === 'chartsheet';\n const target = isChartsheet ? `chartsheets/sheet${nextChartsheetId}.xml` : `worksheets/sheet${nextWorksheetId}.xml`;\n const archivePath = isChartsheet\n ? `xl/chartsheets/sheet${nextChartsheetId}.xml`\n : `xl/worksheets/sheet${nextWorksheetId}.xml`;\n if (isChartsheet) nextChartsheetId++;\n else nextWorksheetId++;\n const sheetRels = makeRelationships();\n // Pre-claim every captured relsExtras rId so freshly allocated modeled rels\n // never clash. The extras themselves are appended to sheetRels at the end\n // so any rId already used inside the worksheet body (drawing / hyperlink\n // refs) keeps pointing at our newly emitted rel.\n const sheetRelsClaimed = new Set<string>();\n const sheetRelsExtras = ref.kind === 'worksheet' ? (ref.sheet.relsExtras ?? []) : [];\n for (const e of sheetRelsExtras) sheetRelsClaimed.add(e.id);\n let sheetRIdCursor = 1;\n const allocateSheetRId = (): string => {\n let id = `rId${sheetRIdCursor}`;\n while (sheetRelsClaimed.has(id) || sheetRels.rels.some((r) => r.id === id)) {\n sheetRIdCursor++;\n id = `rId${sheetRIdCursor}`;\n }\n sheetRIdCursor++;\n return id;\n };\n const registerTable = (table: TableDefinition): { rId: string } => {\n const tableId = nextTableId++;\n const rId = allocateSheetRId();\n sheetRels.rels.push({\n id: rId,\n type: TABLE_REL,\n target: `../tables/table${tableId}.xml`,\n });\n // Emit the table part with its workbook-global id baked in.\n const xmlTable: TableDefinition = { ...table, id: tableId };\n tableEmits.push({ id: tableId, bytes: tableToBytes(xmlTable) });\n return { rId };\n };\n const registerComments = (comments: ReadonlyArray<LegacyComment>): { vmlRelId: string } => {\n const id = nextCommentsId++;\n const commentsRelId = allocateSheetRId();\n sheetRels.rels.push({\n id: commentsRelId,\n type: COMMENTS_REL,\n target: `../comments${id}.xml`,\n });\n const vmlRelId = allocateSheetRId();\n sheetRels.rels.push({\n id: vmlRelId,\n type: VML_DRAWING_REL,\n target: `../drawings/vmlDrawing${id}.vml`,\n });\n commentEmits.push({\n id,\n commentsBytes: commentsToBytes(comments),\n vmlBytes: placeholderVmlDrawing(comments),\n });\n return { vmlRelId };\n };\n const registerDrawing = (drawing: Drawing): { rId: string } => {\n const id = nextDrawingId++;\n const rId = allocateSheetRId();\n sheetRels.rels.push({\n id: rId,\n type: DRAWING_REL,\n target: `../drawings/drawing${id}.xml`,\n });\n // Walk drawing items: for each chart with a payload, allocate a\n // workbook-global chartN id and a per-drawing rId. Emit the chart part +\n // collect a drawing-rels entry so drawing.xml's <c:chart r:id> resolves.\n const drawingRels = makeRelationships();\n const itemsForXml: DrawingItem[] = [];\n for (const item of drawing.items) {\n if (item.content.kind === 'chart' && (item.content.chart.space || item.content.chart.cxSpace)) {\n const chartId = nextChartId++;\n const chartRId = `rId${drawingRels.rels.length + 1}`;\n // chartex parts use a different relationship Type than the legacy\n // ECMA-376 charts. Excel rejects the workbook when the drawing rels\n // claim a `relationships/chart` target that actually contains a\n // `cx:chartSpace` root.\n const isCxChart = item.content.chart.cxSpace !== undefined;\n drawingRels.rels.push({\n id: chartRId,\n type: isCxChart ? CHARTEX_REL : CHART_REL,\n target: `../charts/chart${chartId}.xml`,\n });\n if (item.content.chart.cxSpace) {\n chartEmits.push({\n id: chartId,\n bytes: chartExToBytes(item.content.chart.cxSpace),\n isCx: true,\n });\n } else if (item.content.chart.space) {\n const space = item.content.chart.space;\n // If the chart carries user shapes, allocate the chartDrawingN part\n // + a per-chart rels file referencing it, then bake the resulting\n // r:id into the chart's <c:userShapes> element.\n let userShapesRId: string | undefined;\n let chartRelsFile: Relationships | undefined;\n if (space.userShapes && space.userShapes.shapes.length > 0) {\n const userShapesId = nextUserShapesId++;\n userShapesRId = 'rId1';\n chartRelsFile = makeRelationships();\n chartRelsFile.rels.push({\n id: userShapesRId,\n type: CHART_USER_SHAPES_REL,\n target: `../drawings/chartDrawing${userShapesId}.xml`,\n });\n userShapeEmits.push({\n id: userShapesId,\n bytes: userShapesToBytes(space.userShapes),\n });\n }\n const chartEmit: typeof chartEmits[number] = {\n id: chartId,\n bytes: chartToBytes(space, userShapesRId !== undefined ? { userShapesRId } : {}),\n isCx: false,\n };\n if (chartRelsFile) chartEmit.rels = chartRelsFile;\n chartEmits.push(chartEmit);\n }\n itemsForXml.push({\n anchor: item.anchor,\n content: {\n kind: 'chart',\n chart: {\n rId: chartRId,\n ...(item.content.chart.cxSpace ? { isCx: true } : {}),\n },\n },\n });\n } else if (item.content.kind === 'picture' && item.content.picture.image) {\n const img = item.content.picture.image;\n const ext = IMAGE_FORMAT_EXTENSION[img.format];\n const imageId = nextImageId++;\n const picRId = `rId${drawingRels.rels.length + 1}`;\n drawingRels.rels.push({\n id: picRId,\n type: IMAGE_REL,\n target: `../media/image${imageId}.${ext}`,\n });\n imageEmits.push({ id: imageId, ext, bytes: img.bytes });\n imageExts.add(ext);\n itemsForXml.push({\n anchor: item.anchor,\n content: {\n kind: 'picture',\n picture: {\n rId: picRId,\n ...(item.content.picture.name !== undefined ? { name: item.content.picture.name } : {}),\n ...(item.content.picture.descr !== undefined ? { descr: item.content.picture.descr } : {}),\n ...(item.content.picture.hidden !== undefined ? { hidden: item.content.picture.hidden } : {}),\n ...(item.content.picture.spPr ? { spPr: item.content.picture.spPr } : {}),\n },\n },\n });\n } else {\n itemsForXml.push(item);\n }\n }\n const emit: DrawingEmit = { id, bytes: drawingToBytes({ items: itemsForXml }) };\n if (drawingRels.rels.length > 0) emit.rels = drawingRels;\n drawingEmits.push(emit);\n return { rId };\n };\n let bytes: Uint8Array;\n if (ref.kind === 'worksheet') {\n bytes = worksheetToBytes(ref.sheet, {\n sharedStrings: sst,\n date1904: wb.date1904,\n rels: sheetRels,\n registerTable,\n registerComments,\n registerDrawing,\n });\n } else {\n // Chartsheet: register the drawing (if any), then emit the chartsheet\n // part with the resulting r:id baked in.\n let drawingRId: string | undefined;\n if (ref.sheet.drawing) drawingRId = registerDrawing(ref.sheet.drawing).rId;\n bytes = chartsheetToBytes(ref.sheet, drawingRId !== undefined ? { drawingRId } : {});\n }\n // Append captured per-sheet rels passthrough (pivotTable / queryTable /\n // printerSettings / oleObject / customProperty / threadedComment …)\n // verbatim. Their original rIds were pre-claimed so the modeled allocations\n // above never collide with them.\n for (const e of sheetRelsExtras) {\n sheetRels.rels.push({ id: e.id, type: e.type, target: e.target });\n }\n const sheetRId = ref.rId ?? allocateRId();\n const emit: SheetEmit = {\n id: sheetRId,\n target,\n bytes,\n relType: isChartsheet ? CHARTSHEET_REL : `${REL_NS}/worksheet`,\n archivePath,\n contentType: isChartsheet ? CHARTSHEET_TYPE : WORKSHEET_TYPE,\n };\n if (sheetRels.rels.length > 0) emit.rels = sheetRels;\n sheetEmits.push(emit);\n });\n\n // ---- 2. workbook rels -- sheets first, then sst (if any), then styles, then\n // theme / vbaProject, then any captured workbookRelsExtras (e.g.\n // pivotCacheDefinition rels referenced by `<pivotCaches>`). Modeled non-sheet\n // rels prefer the rId captured at load time so any captured extras XML using\n // that Id still resolves after the round-trip.\n const wbRels = makeRelationships();\n wbRels.rels = sheetEmits.map((e) => ({\n id: e.id,\n type: e.relType,\n target: e.target,\n }));\n const orig = wb.workbookRelOriginalIds;\n if (sst.entries.length > 0) {\n wbRels.rels.push({\n id: orig?.sharedStrings ?? allocateRId(),\n type: `${REL_NS}/sharedStrings`,\n target: 'sharedStrings.xml',\n });\n }\n wbRels.rels.push({\n id: orig?.styles ?? allocateRId(),\n type: `${REL_NS}/styles`,\n target: 'styles.xml',\n });\n if (wb.themeXml) {\n wbRels.rels.push({\n id: orig?.theme ?? allocateRId(),\n type: THEME_REL,\n target: 'theme/theme1.xml',\n });\n }\n if (wb.vbaProject) {\n wbRels.rels.push({\n id: orig?.vbaProject ?? allocateRId(),\n type: `${REL_NS}/vbaProject`,\n target: 'vbaProject.bin',\n });\n }\n if (wb.workbookRelsExtras) {\n for (const e of wb.workbookRelsExtras) {\n wbRels.rels.push({ id: e.id, type: e.type, target: e.target });\n }\n }\n\n // ---- 3. workbook.xml ----------------------------------------------------\n const workbookXml = serializeWorkbookXml(\n wb,\n sheetEmits.map((e) => e.id),\n );\n await writer.addEntry(ARC_WORKBOOK, new TextEncoder().encode(workbookXml));\n await writer.addEntry(ARC_WORKBOOK_RELS, relsToBytes(wbRels));\n\n // ---- 4. each worksheet / chartsheet (and its rels file when present) --\n for (const e of sheetEmits) {\n await writer.addEntry(e.archivePath, e.bytes);\n if (e.rels) {\n // The rels file sits alongside its part: `xl/<dir>/_rels/<file>.rels`.\n const slash = e.archivePath.lastIndexOf('/');\n const dir = e.archivePath.slice(0, slash);\n const file = e.archivePath.slice(slash + 1);\n await writer.addEntry(`${dir}/_rels/${file}.rels`, relsToBytes(e.rels));\n }\n }\n\n // ---- 4b. table parts ----------------------------------------------------\n for (const t of tableEmits) {\n await writer.addEntry(`xl/tables/table${t.id}.xml`, t.bytes);\n }\n\n // ---- 4c. comments parts + matching VML drawings ------------------------\n for (const c of commentEmits) {\n await writer.addEntry(`xl/comments${c.id}.xml`, c.commentsBytes);\n await writer.addEntry(`xl/drawings/vmlDrawing${c.id}.vml`, c.vmlBytes);\n }\n\n // ---- 4d. drawings + their rels (when charts are embedded) -------------\n for (const d of drawingEmits) {\n await writer.addEntry(`xl/drawings/drawing${d.id}.xml`, d.bytes);\n if (d.rels) {\n await writer.addEntry(`xl/drawings/_rels/drawing${d.id}.xml.rels`, relsToBytes(d.rels));\n }\n }\n\n // ---- 4e. chart parts (and per-chart rels when user shapes attach) -----\n for (const c of chartEmits) {\n await writer.addEntry(`xl/charts/chart${c.id}.xml`, c.bytes);\n if (c.rels) {\n await writer.addEntry(`xl/charts/_rels/chart${c.id}.xml.rels`, relsToBytes(c.rels));\n }\n }\n\n // ---- 4f. user-shape drawings (xl/drawings/chartDrawingN.xml) ----------\n for (const us of userShapeEmits) {\n await writer.addEntry(`xl/drawings/chartDrawing${us.id}.xml`, us.bytes);\n }\n\n // ---- 4g. embedded images (xl/media/imageN.{ext}) ----------------------\n for (const img of imageEmits) {\n await writer.addEntry(`xl/media/image${img.id}.${img.ext}`, img.bytes);\n }\n\n // ---- 5. styles.xml + sharedStrings.xml (if any) -------------------------\n await writer.addEntry(ARC_STYLE, stylesheetToBytes(wb.styles));\n if (sst.entries.length > 0) {\n await writer.addEntry(ARC_SHARED_STRINGS, sharedStringsToBytes(sst));\n }\n\n // ---- 5b. theme1.xml (passthrough) — only when wb carries one. The theme rel\n // was already added to wbRels above so workbook.xml.rels references it.\n if (wb.themeXml) await writer.addEntry(ARC_THEME, wb.themeXml);\n\n // ---- 5c. docProps/{core,app,custom}.xml (when present) ------------------\n if (wb.properties) await writer.addEntry(ARC_CORE, corePropsToBytes(wb.properties));\n if (wb.appProperties) await writer.addEntry(ARC_APP, extendedPropsToBytes(wb.appProperties));\n if (wb.customProperties) await writer.addEntry(ARC_CUSTOM, customPropsToBytes(wb.customProperties));\n\n // ---- 5d. VBA project + signature (when present) -------------------------\n if (wb.vbaProject) await writer.addEntry('xl/vbaProject.bin', wb.vbaProject);\n if (wb.vbaSignature) await writer.addEntry('xl/vbaProjectSignature.bin', wb.vbaSignature);\n\n // ---- 5e. Pass-through bytes (pivot / activeX / customXml / etc.) -------\n if (wb.passthrough) {\n for (const [path, bytes] of wb.passthrough) await writer.addEntry(path, bytes);\n }\n\n // ---- 6. root rels -------------------------------------------------------\n const rootRels: Relationships = { rels: [] };\n rootRels.rels.push({\n id: 'rId1',\n type: `${REL_NS}/officeDocument`,\n target: 'xl/workbook.xml',\n });\n if (wb.properties) {\n rootRels.rels.push({\n id: `rId${rootRels.rels.length + 1}`,\n type: CORE_PROPS_REL,\n target: 'docProps/core.xml',\n });\n }\n if (wb.appProperties) {\n rootRels.rels.push({\n id: `rId${rootRels.rels.length + 1}`,\n type: EXT_PROPS_REL,\n target: 'docProps/app.xml',\n });\n }\n if (wb.customProperties) {\n rootRels.rels.push({\n id: `rId${rootRels.rels.length + 1}`,\n type: CUSTOM_PROPS_REL,\n target: 'docProps/custom.xml',\n });\n }\n await writer.addEntry(ARC_ROOT_RELS, relsToBytes(rootRels));\n\n // ---- 7. [Content_Types].xml --------------------------------------------\n const manifest = makeManifest();\n addDefault(manifest, 'rels', 'application/vnd.openxmlformats-package.relationships+xml');\n addDefault(manifest, 'xml', 'application/xml');\n // VBA-bearing workbooks promote the workbook content type to xlsm.\n const workbookContentType = wb.vbaProject\n ? 'application/vnd.ms-excel.sheet.macroEnabled.main+xml'\n : XLSX_TYPE;\n addOverride(manifest, `/${ARC_WORKBOOK}`, workbookContentType);\n for (const e of sheetEmits) {\n addOverride(manifest, `/${e.archivePath}`, e.contentType);\n }\n addOverride(manifest, `/${ARC_STYLE}`, STYLES_TYPE);\n if (sst.entries.length > 0) {\n addOverride(manifest, `/${ARC_SHARED_STRINGS}`, SHARED_STRINGS_TYPE);\n }\n if (wb.themeXml) addOverride(manifest, `/${ARC_THEME}`, THEME_TYPE);\n for (const t of tableEmits) {\n addOverride(manifest, `/xl/tables/table${t.id}.xml`, TABLE_TYPE);\n }\n if (commentEmits.length > 0) {\n addDefault(manifest, 'vml', VML_DRAWING_TYPE);\n }\n for (const c of commentEmits) {\n addOverride(manifest, `/xl/comments${c.id}.xml`, COMMENTS_TYPE);\n }\n for (const d of drawingEmits) {\n addOverride(manifest, `/xl/drawings/drawing${d.id}.xml`, DRAWING_TYPE);\n }\n for (const c of chartEmits) {\n addOverride(manifest, `/xl/charts/chart${c.id}.xml`, c.isCx ? CHARTEX_TYPE : CHART_TYPE);\n }\n for (const us of userShapeEmits) {\n addOverride(manifest, `/xl/drawings/chartDrawing${us.id}.xml`, DRAWING_TYPE);\n }\n if (wb.vbaProject) {\n addDefault(manifest, 'bin', 'application/vnd.ms-office.vbaProject');\n }\n if (wb.passthrough) {\n for (const path of wb.passthrough.keys()) {\n const ct = wb.passthroughContentTypes?.get(path);\n if (ct !== undefined) addOverride(manifest, `/${path}`, ct);\n }\n }\n // Each unique image extension gets a Default entry (`<Default Extension=\"png\"\n // ContentType=\"image/png\"/>`).\n for (const ext of imageExts) {\n const fmt = (Object.entries(IMAGE_FORMAT_EXTENSION).find(([, e]) => e === ext) ?? [])[0] as\n | XlsxImageFormat\n | undefined;\n if (fmt) addDefault(manifest, ext, IMAGE_FORMAT_MIME[fmt]);\n }\n if (wb.properties) addOverride(manifest, `/${ARC_CORE}`, CORE_PROPS_TYPE);\n if (wb.appProperties) addOverride(manifest, `/${ARC_APP}`, EXT_PROPS_TYPE);\n if (wb.customProperties) addOverride(manifest, `/${ARC_CUSTOM}`, CPROPS_TYPE);\n await writer.addEntry(ARC_CONTENT_TYPES, manifestToBytes(manifest));\n\n // ---- 8. close ----------------------------------------------------------\n await writer.finalize();\n}\n\n/** Serialise the minimum `<workbook><sheets/></workbook>` Excel needs to load a sheet list. */\nfunction serializeWorkbookXml(wb: Workbook, sheetRIds: ReadonlyArray<string>): string {\n const parts: string[] = [\n '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>',\n `<workbook xmlns=\"${SHEET_MAIN_NS}\" xmlns:r=\"${REL_NS}\">`,\n ];\n if (wb.fileVersion) {\n const fv = serializeFileVersion(wb.fileVersion);\n if (fv) parts.push(fv);\n }\n if (wb.fileSharing) {\n const fs = serializeFileSharing(wb.fileSharing);\n if (fs) parts.push(fs);\n }\n if (wb.workbookXmlExtras?.beforeSheets) {\n for (const node of wb.workbookXmlExtras.beforeSheets) parts.push(serializeChildNode(node));\n }\n // Emit <workbookPr> from the typed model; fall back to a minimal {date1904:\n // true} synthesis so a fresh workbook (no load history) still round-trips\n // through Excel with the right epoch.\n const effectiveWp = effectiveWorkbookProperties(wb);\n if (effectiveWp) {\n const wp = serializeWorkbookProperties(effectiveWp);\n if (wp) parts.push(wp);\n }\n if (wb.workbookProtection) {\n const wp = serializeWorkbookProtection(wb.workbookProtection);\n if (wp) parts.push(wp);\n }\n if (wb.bookViews && wb.bookViews.length > 0) parts.push(serializeBookViews(wb.bookViews));\n parts.push('<sheets>');\n wb.sheets.forEach((ref, i) => {\n const stateAttr = ref.state === 'visible' ? '' : ` state=\"${ref.state}\"`;\n const rId = sheetRIds[i] ?? `rId${i + 1}`;\n parts.push(`<sheet name=\"${escapeAttr(ref.sheet.title)}\" sheetId=\"${ref.sheetId}\"${stateAttr} r:id=\"${rId}\"/>`);\n });\n parts.push('</sheets>');\n if (wb.definedNames.length > 0) {\n parts.push('<definedNames>');\n for (const dn of wb.definedNames) {\n let attrs = ` name=\"${escapeAttr(dn.name)}\"`;\n if (dn.scope !== undefined) attrs += ` localSheetId=\"${dn.scope}\"`;\n if (dn.hidden) attrs += ' hidden=\"1\"';\n if (dn.comment !== undefined) attrs += ` comment=\"${escapeAttr(dn.comment)}\"`;\n parts.push(`<definedName${attrs}>${escapeText(dn.value)}</definedName>`);\n }\n parts.push('</definedNames>');\n }\n if (wb.functionGroups) {\n const fg = serializeFunctionGroups(wb.functionGroups);\n if (fg) parts.push(fg);\n }\n if (wb.externalReferences && wb.externalReferences.length > 0) {\n const inner: string[] = ['<externalReferences>'];\n for (const er of wb.externalReferences) {\n inner.push(`<externalReference r:id=\"${escapeAttr(er.rId)}\"/>`);\n }\n inner.push('</externalReferences>');\n parts.push(inner.join(''));\n }\n if (wb.pivotCaches && wb.pivotCaches.length > 0) {\n const inner: string[] = ['<pivotCaches>'];\n for (const pc of wb.pivotCaches) {\n inner.push(`<pivotCache cacheId=\"${pc.cacheId}\" r:id=\"${escapeAttr(pc.rId)}\"/>`);\n }\n inner.push('</pivotCaches>');\n parts.push(inner.join(''));\n }\n if (wb.calcProperties) {\n const cp = serializeCalcProperties(wb.calcProperties);\n if (cp) parts.push(cp);\n }\n // No default `<calcPr>` — Excel handles its absence by inserting one on save.\n // Hand-rolled `calcId` values (especially the modern 191029) made Excel\n // reject workbooks whose future-function formulas (LET / LAMBDA / FILTER…)\n // couldn't be evaluated against the declared engine.\n if (wb.oleSize !== undefined) {\n parts.push(`<oleSize ref=\"${escapeAttr(wb.oleSize)}\"/>`);\n }\n if (wb.customWorkbookViews && wb.customWorkbookViews.length > 0) {\n parts.push(serializeCustomWorkbookViews(wb.customWorkbookViews));\n }\n if (wb.smartTagPr) {\n const stp = serializeSmartTagPr(wb.smartTagPr);\n if (stp) parts.push(stp);\n }\n if (wb.smartTagTypes && wb.smartTagTypes.length > 0) {\n parts.push(serializeSmartTagTypes(wb.smartTagTypes));\n }\n if (wb.workbookXmlExtras?.afterSheets) {\n for (const node of wb.workbookXmlExtras.afterSheets) parts.push(serializeChildNode(node));\n }\n if (wb.fileRecoveryPr) {\n const fp = serializeFileRecoveryPr(wb.fileRecoveryPr);\n if (fp) parts.push(fp);\n }\n parts.push('</workbook>');\n return parts.join('');\n}\n\nfunction serializeCalcProperties(\n cp: import('../workbook/calc-properties').CalcProperties,\n): string | undefined {\n let attrs = '';\n if (cp.calcId !== undefined) attrs += ` calcId=\"${cp.calcId}\"`;\n if (cp.calcMode !== undefined) attrs += ` calcMode=\"${cp.calcMode}\"`;\n if (cp.fullCalcOnLoad !== undefined) attrs += ` fullCalcOnLoad=\"${cp.fullCalcOnLoad ? '1' : '0'}\"`;\n if (cp.refMode !== undefined) attrs += ` refMode=\"${cp.refMode}\"`;\n if (cp.iterate !== undefined) attrs += ` iterate=\"${cp.iterate ? '1' : '0'}\"`;\n if (cp.iterateCount !== undefined) attrs += ` iterateCount=\"${cp.iterateCount}\"`;\n if (cp.iterateDelta !== undefined) attrs += ` iterateDelta=\"${cp.iterateDelta}\"`;\n if (cp.fullPrecision !== undefined) attrs += ` fullPrecision=\"${cp.fullPrecision ? '1' : '0'}\"`;\n if (cp.calcCompleted !== undefined) attrs += ` calcCompleted=\"${cp.calcCompleted ? '1' : '0'}\"`;\n if (cp.calcOnSave !== undefined) attrs += ` calcOnSave=\"${cp.calcOnSave ? '1' : '0'}\"`;\n if (cp.concurrentCalc !== undefined) attrs += ` concurrentCalc=\"${cp.concurrentCalc ? '1' : '0'}\"`;\n if (cp.concurrentManualCount !== undefined) attrs += ` concurrentManualCount=\"${cp.concurrentManualCount}\"`;\n if (cp.forceFullCalc !== undefined) attrs += ` forceFullCalc=\"${cp.forceFullCalc ? '1' : '0'}\"`;\n if (attrs.length === 0) return undefined;\n return `<calcPr${attrs}/>`;\n}\n\nfunction serializeFunctionGroups(\n fg: import('../workbook/function-groups').FunctionGroups,\n): string | undefined {\n let attrs = '';\n if (fg.builtInGroupCount !== undefined) attrs += ` builtInGroupCount=\"${fg.builtInGroupCount}\"`;\n if (fg.groups.length === 0 && attrs.length === 0) return undefined;\n if (fg.groups.length === 0) return `<functionGroups${attrs}/>`;\n const inner: string[] = [`<functionGroups${attrs}>`];\n for (const g of fg.groups) inner.push(`<functionGroup name=\"${escapeAttr(g.name)}\"/>`);\n inner.push('</functionGroups>');\n return inner.join('');\n}\n\nfunction serializeSmartTagPr(\n stp: import('../workbook/smart-tags').SmartTagProperties,\n): string | undefined {\n let attrs = '';\n if (stp.embed !== undefined) attrs += ` embed=\"${stp.embed ? '1' : '0'}\"`;\n if (stp.show !== undefined) attrs += ` show=\"${stp.show}\"`;\n if (attrs.length === 0) return undefined;\n return `<smartTagPr${attrs}/>`;\n}\n\nfunction serializeSmartTagTypes(\n tags: ReadonlyArray<import('../workbook/smart-tags').SmartTagType>,\n): string {\n const inner: string[] = ['<smartTagTypes>'];\n for (const t of tags) {\n let attrs = '';\n if (t.namespaceUri !== undefined) attrs += ` namespaceUri=\"${escapeAttr(t.namespaceUri)}\"`;\n if (t.name !== undefined) attrs += ` name=\"${escapeAttr(t.name)}\"`;\n if (t.url !== undefined) attrs += ` url=\"${escapeAttr(t.url)}\"`;\n inner.push(`<smartTagType${attrs}/>`);\n }\n inner.push('</smartTagTypes>');\n return inner.join('');\n}\n\nfunction serializeFileRecoveryPr(\n fp: import('../workbook/file-recovery').FileRecoveryProperties,\n): string | undefined {\n let attrs = '';\n if (fp.autoRecover !== undefined) attrs += ` autoRecover=\"${fp.autoRecover ? '1' : '0'}\"`;\n if (fp.crashSave !== undefined) attrs += ` crashSave=\"${fp.crashSave ? '1' : '0'}\"`;\n if (fp.dataExtractLoad !== undefined) attrs += ` dataExtractLoad=\"${fp.dataExtractLoad ? '1' : '0'}\"`;\n if (fp.repairLoad !== undefined) attrs += ` repairLoad=\"${fp.repairLoad ? '1' : '0'}\"`;\n if (attrs.length === 0) return undefined;\n return `<fileRecoveryPr${attrs}/>`;\n}\n\nfunction serializeFileSharing(\n fs: import('../workbook/file-sharing').FileSharing,\n): string | undefined {\n let attrs = '';\n if (fs.readOnlyRecommended !== undefined)\n attrs += ` readOnlyRecommended=\"${fs.readOnlyRecommended ? '1' : '0'}\"`;\n if (fs.userName !== undefined) attrs += ` userName=\"${escapeAttr(fs.userName)}\"`;\n if (fs.reservationPassword !== undefined)\n attrs += ` reservationPassword=\"${escapeAttr(fs.reservationPassword)}\"`;\n if (fs.algorithmName !== undefined) attrs += ` algorithmName=\"${escapeAttr(fs.algorithmName)}\"`;\n if (fs.hashValue !== undefined) attrs += ` hashValue=\"${escapeAttr(fs.hashValue)}\"`;\n if (fs.saltValue !== undefined) attrs += ` saltValue=\"${escapeAttr(fs.saltValue)}\"`;\n if (fs.spinCount !== undefined) attrs += ` spinCount=\"${fs.spinCount}\"`;\n if (attrs.length === 0) return undefined;\n return `<fileSharing${attrs}/>`;\n}\n\nfunction serializeFileVersion(\n fv: import('../workbook/file-version').FileVersion,\n): string | undefined {\n let attrs = '';\n if (fv.appName !== undefined) attrs += ` appName=\"${escapeAttr(fv.appName)}\"`;\n if (fv.lastEdited !== undefined) attrs += ` lastEdited=\"${escapeAttr(fv.lastEdited)}\"`;\n if (fv.lowestEdited !== undefined) attrs += ` lowestEdited=\"${escapeAttr(fv.lowestEdited)}\"`;\n if (fv.rupBuild !== undefined) attrs += ` rupBuild=\"${escapeAttr(fv.rupBuild)}\"`;\n if (fv.codeName !== undefined) attrs += ` codeName=\"${escapeAttr(fv.codeName)}\"`;\n if (attrs.length === 0) return undefined;\n return `<fileVersion${attrs}/>`;\n}\n\nfunction effectiveWorkbookProperties(\n wb: Workbook,\n): import('../workbook/workbook-properties').WorkbookProperties | undefined {\n const explicit = wb.workbookProperties;\n if (explicit) {\n // Mirror the canonical date1904 flag if the typed model omits it.\n if (wb.date1904 && explicit.date1904 === undefined) {\n return { ...explicit, date1904: true };\n }\n return explicit;\n }\n if (wb.date1904) return { date1904: true };\n return undefined;\n}\n\nfunction serializeWorkbookProperties(\n wp: import('../workbook/workbook-properties').WorkbookProperties,\n): string | undefined {\n let attrs = '';\n const boolKeys: ReadonlyArray<keyof import('../workbook/workbook-properties').WorkbookProperties> = [\n 'date1904',\n 'dateCompatibility',\n 'showBorderUnselectedTables',\n 'filterPrivacy',\n 'promptedSolutions',\n 'showInkAnnotation',\n 'backupFile',\n 'saveExternalLinkValues',\n 'hidePivotFieldList',\n 'showPivotChartFilter',\n 'allowRefreshQuery',\n 'publishItems',\n 'checkCompatibility',\n 'autoCompressPictures',\n 'refreshAllConnections',\n ];\n for (const k of boolKeys) {\n const v = wp[k];\n if (v !== undefined) attrs += ` ${k}=\"${v ? '1' : '0'}\"`;\n }\n if (wp.showObjects !== undefined) attrs += ` showObjects=\"${wp.showObjects}\"`;\n if (wp.updateLinks !== undefined) attrs += ` updateLinks=\"${wp.updateLinks}\"`;\n if (wp.codeName !== undefined) attrs += ` codeName=\"${escapeAttr(wp.codeName)}\"`;\n if (wp.defaultThemeVersion !== undefined) attrs += ` defaultThemeVersion=\"${wp.defaultThemeVersion}\"`;\n if (attrs.length === 0) return undefined;\n return `<workbookPr${attrs}/>`;\n}\n\nfunction serializeCustomWorkbookViews(\n views: ReadonlyArray<import('../workbook/views').CustomWorkbookView>,\n): string {\n const parts: string[] = ['<customWorkbookViews>'];\n for (const v of views) {\n let attrs = ` name=\"${escapeAttr(v.name)}\" guid=\"${escapeAttr(v.guid)}\"`;\n if (v.autoUpdate !== undefined) attrs += ` autoUpdate=\"${v.autoUpdate ? '1' : '0'}\"`;\n if (v.mergeInterval !== undefined) attrs += ` mergeInterval=\"${v.mergeInterval}\"`;\n if (v.changesSavedWin !== undefined) attrs += ` changesSavedWin=\"${v.changesSavedWin ? '1' : '0'}\"`;\n if (v.onlySync !== undefined) attrs += ` onlySync=\"${v.onlySync ? '1' : '0'}\"`;\n if (v.personalView !== undefined) attrs += ` personalView=\"${v.personalView ? '1' : '0'}\"`;\n if (v.includePrintSettings !== undefined)\n attrs += ` includePrintSettings=\"${v.includePrintSettings ? '1' : '0'}\"`;\n if (v.includeHiddenRowCol !== undefined)\n attrs += ` includeHiddenRowCol=\"${v.includeHiddenRowCol ? '1' : '0'}\"`;\n if (v.maximized !== undefined) attrs += ` maximized=\"${v.maximized ? '1' : '0'}\"`;\n if (v.minimized !== undefined) attrs += ` minimized=\"${v.minimized ? '1' : '0'}\"`;\n if (v.showHorizontalScroll !== undefined)\n attrs += ` showHorizontalScroll=\"${v.showHorizontalScroll ? '1' : '0'}\"`;\n if (v.showVerticalScroll !== undefined)\n attrs += ` showVerticalScroll=\"${v.showVerticalScroll ? '1' : '0'}\"`;\n if (v.showSheetTabs !== undefined) attrs += ` showSheetTabs=\"${v.showSheetTabs ? '1' : '0'}\"`;\n if (v.xWindow !== undefined) attrs += ` xWindow=\"${v.xWindow}\"`;\n if (v.yWindow !== undefined) attrs += ` yWindow=\"${v.yWindow}\"`;\n attrs += ` windowWidth=\"${v.windowWidth}\" windowHeight=\"${v.windowHeight}\"`;\n if (v.tabRatio !== undefined) attrs += ` tabRatio=\"${v.tabRatio}\"`;\n attrs += ` activeSheetId=\"${v.activeSheetId}\"`;\n if (v.showFormulaBar !== undefined) attrs += ` showFormulaBar=\"${v.showFormulaBar ? '1' : '0'}\"`;\n if (v.showStatusbar !== undefined) attrs += ` showStatusbar=\"${v.showStatusbar ? '1' : '0'}\"`;\n if (v.showComments !== undefined) attrs += ` showComments=\"${v.showComments}\"`;\n if (v.showObjects !== undefined) attrs += ` showObjects=\"${v.showObjects}\"`;\n parts.push(`<customWorkbookView${attrs}/>`);\n }\n parts.push('</customWorkbookViews>');\n return parts.join('');\n}\n\nfunction serializeBookViews(views: ReadonlyArray<import('../workbook/views').WorkbookView>): string {\n const parts: string[] = ['<bookViews>'];\n for (const v of views) {\n let attrs = '';\n if (v.visibility !== undefined) attrs += ` visibility=\"${v.visibility}\"`;\n if (v.minimized !== undefined) attrs += ` minimized=\"${v.minimized ? '1' : '0'}\"`;\n if (v.showHorizontalScroll !== undefined)\n attrs += ` showHorizontalScroll=\"${v.showHorizontalScroll ? '1' : '0'}\"`;\n if (v.showVerticalScroll !== undefined)\n attrs += ` showVerticalScroll=\"${v.showVerticalScroll ? '1' : '0'}\"`;\n if (v.showSheetTabs !== undefined) attrs += ` showSheetTabs=\"${v.showSheetTabs ? '1' : '0'}\"`;\n if (v.xWindow !== undefined) attrs += ` xWindow=\"${v.xWindow}\"`;\n if (v.yWindow !== undefined) attrs += ` yWindow=\"${v.yWindow}\"`;\n if (v.windowWidth !== undefined) attrs += ` windowWidth=\"${v.windowWidth}\"`;\n if (v.windowHeight !== undefined) attrs += ` windowHeight=\"${v.windowHeight}\"`;\n if (v.tabRatio !== undefined) attrs += ` tabRatio=\"${v.tabRatio}\"`;\n if (v.firstSheet !== undefined) attrs += ` firstSheet=\"${v.firstSheet}\"`;\n if (v.activeTab !== undefined) attrs += ` activeTab=\"${v.activeTab}\"`;\n if (v.autoFilterDateGrouping !== undefined)\n attrs += ` autoFilterDateGrouping=\"${v.autoFilterDateGrouping ? '1' : '0'}\"`;\n parts.push(`<workbookView${attrs}/>`);\n }\n parts.push('</bookViews>');\n return parts.join('');\n}\n\nfunction serializeWorkbookProtection(\n wp: import('../workbook/protection').WorkbookProtection,\n): string | undefined {\n let attrs = '';\n const strAttrs = [\n 'workbookPassword',\n 'workbookPasswordCharacterSet',\n 'workbookAlgorithmName',\n 'workbookHashValue',\n 'workbookSaltValue',\n 'revisionsPassword',\n 'revisionsPasswordCharacterSet',\n 'revisionsAlgorithmName',\n 'revisionsHashValue',\n 'revisionsSaltValue',\n ] as const;\n for (const k of strAttrs) {\n const v = wp[k];\n if (v !== undefined) attrs += ` ${k}=\"${escapeAttr(v)}\"`;\n }\n if (wp.workbookSpinCount !== undefined) attrs += ` workbookSpinCount=\"${wp.workbookSpinCount}\"`;\n if (wp.revisionsSpinCount !== undefined) attrs += ` revisionsSpinCount=\"${wp.revisionsSpinCount}\"`;\n if (wp.lockStructure !== undefined) attrs += ` lockStructure=\"${wp.lockStructure ? '1' : '0'}\"`;\n if (wp.lockWindows !== undefined) attrs += ` lockWindows=\"${wp.lockWindows ? '1' : '0'}\"`;\n if (wp.lockRevision !== undefined) attrs += ` lockRevision=\"${wp.lockRevision ? '1' : '0'}\"`;\n if (attrs.length === 0) return undefined;\n return `<workbookProtection${attrs}/>`;\n}\n\n// Local aliases keep the dense call sites below readable. Canonical\n// implementations live in utils/escape.ts so all three writers (this file,\n// xml/serializer, xml/stream-writer) agree on how `>` / whitespace are\n// handled.\nconst escapeText = escapeXmlText;\nconst escapeAttr = escapeXmlAttr;\n\n/**\n * Serialise an XmlNode child of `<workbook>` for inline injection back into the\n * workbook XML stream. Reuses serializeXml then strips the declaration.\n * Captured nodes carry Clark-notation names so namespace prefixes get\n * reallocated by serializeXml — Excel tolerates the extra `xmlns=\"…\"`\n * declarations on each captured root.\n */\nfunction serializeChildNode(node: import('../xml/tree').XmlNode): string {\n const bytes = serializeXmlNode(node, { xmlDeclaration: false });\n return new TextDecoder().decode(bytes);\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"workbook-HGYNRBlV.mjs","names":[],"sources":["../src/workbook/shared-strings.ts","../src/workbook/workbook.ts"],"sourcesContent":["// Shared-strings table read/write.\n//\n// Excel pulls every plain-string cell out of the sheet bodies and into\n// `xl/sharedStrings.xml` so duplicates compress well. The format is a flat list\n// of `<si>` entries, each holding either a single `<t>` (plain text) or a\n// sequence of `<r><rPr/>?<t/></r>` runs (rich text).\n//\n// Rich-text entries are kept as their full `RichText` runs so per-run fonts\n// (bold / italic / colour / size / …) survive the round-trip. Plain strings\n// still dedup against literal text; rich text is kept distinct per-cell\n// (Excel's writer doesn't dedupe rich-text either — formatting equality is\n// rarely worth comparing).\n\nimport type { RichText } from '../cell/rich-text';\nimport { type Color, colorToHex } from '../styles/colors';\nimport { escapeCellString, escapeXmlAttr, escapeXmlText, unescapeCellString } from '../utils/escape';\nimport { OpenXmlSchemaError } from '../utils/exceptions';\nimport { qname, SHEET_MAIN_NS } from '../xml/namespaces';\nimport { parseXml } from '../xml/parser';\nimport { findChild, findChildren, type XmlNode } from '../xml/tree';\n\nconst SST_TAG = `{${SHEET_MAIN_NS}}sst`;\nconst SI_TAG = `{${SHEET_MAIN_NS}}si`;\nconst T_TAG = `{${SHEET_MAIN_NS}}t`;\nconst R_TAG = `{${SHEET_MAIN_NS}}r`;\n\n/** A single SST entry: either a plain string or a rich-text run array. */\nexport type SharedStringEntry = string | { kind: 'rich-text'; runs: RichText };\n\n/**\n * Mutable shared-strings accumulator + lookup table. The same shape is used\n * during read (just populate `entries`) and write (call `addSharedString` from\n * the worksheet writer; emit to bytes at the end).\n */\nexport interface SharedStringsTable {\n /** Insertion-ordered list of unique entries. */\n entries: SharedStringEntry[];\n /** Reverse lookup keyed by literal text — rich-text entries skip this map. */\n index: Map<string, number>;\n}\n\nexport function makeSharedStrings(): SharedStringsTable {\n return { entries: [], index: new Map() };\n}\n\n/**\n * Insert a string and return its index. Idempotent: calling with the same value\n * twice gives the same index. Empty strings are deduped just like everything\n * else.\n */\nexport function addSharedString(table: SharedStringsTable, value: string): number {\n const cached = table.index.get(value);\n if (cached !== undefined) return cached;\n const id = table.entries.length;\n table.entries.push(value);\n table.index.set(value, id);\n return id;\n}\n\n/** Look up a shared-string index by its literal text. Returns `undefined` for unknown values. */\nexport function getSharedStringIndex(table: SharedStringsTable, value: string): number | undefined {\n return table.index.get(value);\n}\n\n/**\n * Read a shared-string by its 0-based index. Returns `undefined` for\n * out-of-range. Rich-text entries surface their concatenated plain text so\n * callers that want only the textual body don't need to know about the\n * discriminated union.\n */\nexport function getSharedStringAt(table: SharedStringsTable, index: number): string | undefined {\n const entry = table.entries[index];\n if (entry === undefined) return undefined;\n if (typeof entry === 'string') return entry;\n return entry.runs.map((r) => r.text).join('');\n}\n\n/** Number of unique entries in the SST. */\nexport function sharedStringCount(table: SharedStringsTable): number {\n return table.entries.length;\n}\n\n// ---- read ------------------------------------------------------------------\n\n/** Concatenate every `<t>` text node found inside an arbitrary XmlNode tree. */\nconst collectText = (node: XmlNode): string => {\n // Most common case: a direct `<si><t>x</t></si>` — bypass the recursion.\n if (node.children.length === 1) {\n const only = node.children[0];\n if (only && only.name === T_TAG) return unescapeCellString(only.text ?? '');\n }\n let out = '';\n for (const child of node.children) {\n if (child.name === T_TAG) {\n out += child.text ?? '';\n } else if (child.name === R_TAG) {\n const t = findChild(child, T_TAG);\n if (t?.text) out += t.text;\n }\n }\n return unescapeCellString(out);\n};\n\n/**\n * Parse a `xl/sharedStrings.xml` payload. Returns the table directly (rather\n * than just the array) so the worksheet writer can keep appending to it without\n * rebuilding the index.\n *\n * Rich-text runs are preserved as their full per-run formatting so\n * round-tripping a file with rich text doesn't drop the styling.\n */\nexport function parseSharedStringsXml(bytes: Uint8Array | string): SharedStringsTable {\n const root = parseXml(bytes);\n if (root.name !== SST_TAG) {\n throw new OpenXmlSchemaError(`parseSharedStringsXml: root is \"${root.name}\", expected sst`);\n }\n const table = makeSharedStrings();\n for (const si of findChildren(root, SI_TAG)) {\n const entry = parseSi(si);\n // Don't dedup — Excel preserves duplicate `<si>` entries by index, and the\n // worksheet `t=\"s\"` references depend on slot, not on text equality.\n const id = table.entries.length;\n table.entries.push(entry);\n if (typeof entry === 'string' && !table.index.has(entry)) table.index.set(entry, id);\n }\n return table;\n}\n\nconst parseSi = (si: XmlNode): SharedStringEntry => {\n // Rich-text si has one or more <r> children. Plain si has a single <t>.\n const runEls = findChildren(si, R_TAG);\n if (runEls.length > 0) {\n const runs: Array<{ text: string; font?: import('../cell/rich-text').InlineFont }> = [];\n for (const rEl of runEls) {\n const tEl = findChild(rEl, T_TAG);\n const text = unescapeCellString(tEl?.text ?? '');\n const rPrEl = findChild(rEl, qname(SHEET_MAIN_NS, 'rPr'));\n const font = rPrEl ? parseRunPr(rPrEl) : undefined;\n runs.push(font !== undefined ? { text, font } : { text });\n }\n return { kind: 'rich-text', runs: Object.freeze(runs) };\n }\n return collectText(si);\n};\n\nconst parseRunPr = (rPr: XmlNode): import('../cell/rich-text').InlineFont | undefined => {\n type InlineFontMutable = {\n -readonly [K in keyof import('../cell/rich-text').InlineFont]: import('../cell/rich-text').InlineFont[K];\n };\n const f: InlineFontMutable = {};\n for (const child of rPr.children) {\n const local = child.name.replace(/^\\{[^}]+\\}/, '');\n const valAttr = child.attrs['val'];\n switch (local) {\n case 'rFont':\n case 'name':\n if (valAttr !== undefined) f.name = valAttr;\n break;\n case 'sz':\n if (valAttr !== undefined) f.sz = Number.parseFloat(valAttr);\n break;\n case 'b':\n f.b = valAttr === undefined ? true : valAttr !== '0' && valAttr !== 'false';\n break;\n case 'i':\n f.i = valAttr === undefined ? true : valAttr !== '0' && valAttr !== 'false';\n break;\n case 'u': {\n const v = (valAttr ?? 'single') as import('../cell/rich-text').InlineUnderline;\n f.u = v;\n break;\n }\n case 'strike':\n f.strike = valAttr === undefined ? true : valAttr !== '0' && valAttr !== 'false';\n break;\n case 'vertAlign':\n if (valAttr !== undefined) f.vertAlign = valAttr as import('../cell/rich-text').InlineVertAlign;\n break;\n case 'family':\n if (valAttr !== undefined) f.family = Number.parseInt(valAttr, 10);\n break;\n case 'charset':\n if (valAttr !== undefined) f.charset = Number.parseInt(valAttr, 10);\n break;\n case 'scheme':\n if (valAttr !== undefined) f.scheme = valAttr as 'major' | 'minor';\n break;\n case 'color': {\n const c: { rgb?: string; theme?: number; indexed?: number; tint?: number; auto?: boolean } = {};\n if (child.attrs['rgb'] !== undefined) c.rgb = child.attrs['rgb'];\n if (child.attrs['theme'] !== undefined) c.theme = Number.parseInt(child.attrs['theme'], 10);\n if (child.attrs['indexed'] !== undefined) c.indexed = Number.parseInt(child.attrs['indexed'], 10);\n if (child.attrs['tint'] !== undefined) c.tint = Number.parseFloat(child.attrs['tint']);\n if (child.attrs['auto'] !== undefined) c.auto = child.attrs['auto'] === '1' || child.attrs['auto'] === 'true';\n f.color = c as Color;\n break;\n }\n }\n }\n return Object.keys(f).length === 0 ? undefined : Object.freeze(f as import('../cell/rich-text').InlineFont);\n};\n\n// ---- write -----------------------------------------------------------------\n\nconst XML_HEADER = '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>';\n\n/**\n * Serialise a SharedStringsTable to its OOXML bytes. The `count` attribute\n * tracks total references (we don't know that here so we report the same as\n * `uniqueCount` — readers tolerate the discrepancy and Excel ignores `count` in\n * practice). `uniqueCount` always matches `entries.length`.\n */\nexport function sharedStringsToBytes(table: SharedStringsTable): Uint8Array {\n return new TextEncoder().encode(serializeSharedStrings(table));\n}\n\nexport function serializeSharedStrings(table: SharedStringsTable): string {\n const total = table.entries.length;\n const parts: string[] = [XML_HEADER, `<sst xmlns=\"${SHEET_MAIN_NS}\" count=\"${total}\" uniqueCount=\"${total}\">`];\n for (const value of table.entries) {\n parts.push(serializeSi(value));\n }\n parts.push('</sst>');\n return parts.join('');\n}\n\nconst serializeSi = (value: SharedStringEntry): string => {\n if (typeof value === 'string') {\n // Whitespace at either end needs xml:space=\"preserve\" so Excel doesn't\n // collapse it. Mirrors openpyxl's emitter.\n const preserve = value.length > 0 && (value[0] === ' ' || value[value.length - 1] === ' ' || /[\\t\\n]/.test(value));\n const tAttr = preserve ? ' xml:space=\"preserve\"' : '';\n return `<si><t${tAttr}>${escapeXmlText(escapeCellString(value))}</t></si>`;\n }\n return `<si>${serializeRichTextRuns(value.runs)}</si>`;\n};\n\n/**\n * Serialise a sequence of `<r>...<r>` runs — shared by the SST `<si>` writer\n * and the worksheet's inline-string (`t=\"inlineStr\"`) cell writer.\n */\nexport function serializeRichTextRuns(runs: import('../cell/rich-text').RichText): string {\n const parts: string[] = [];\n for (const run of runs) {\n parts.push('<r>');\n if (run.font) parts.push(serializeInlineFont(run.font));\n const text = run.text;\n const preserve = text.length > 0 && (text[0] === ' ' || text[text.length - 1] === ' ' || /[\\t\\n]/.test(text));\n const tAttr = preserve ? ' xml:space=\"preserve\"' : '';\n parts.push(`<t${tAttr}>${escapeXmlText(escapeCellString(text))}</t>`);\n parts.push('</r>');\n }\n return parts.join('');\n}\n\nconst serializeInlineFont = (f: import('../cell/rich-text').InlineFont): string => {\n // Element order per ECMA-376 §17.4.4.10 (CT_RPrElt). Excel's parser is\n // sensitive to ordering — out-of-order children make the run silently fall\n // back to the cell's font.\n const parts: string[] = ['<rPr>'];\n if (f.name !== undefined) parts.push(`<rFont val=\"${escapeXmlAttr(f.name)}\"/>`);\n if (f.charset !== undefined) parts.push(`<charset val=\"${f.charset}\"/>`);\n if (f.family !== undefined) parts.push(`<family val=\"${f.family}\"/>`);\n if (f.b) parts.push('<b/>');\n if (f.i) parts.push('<i/>');\n if (f.strike) parts.push('<strike/>');\n if (f.outline) parts.push('<outline/>');\n if (f.shadow) parts.push('<shadow/>');\n if (f.condense) parts.push('<condense/>');\n if (f.extend) parts.push('<extend/>');\n if (f.color) parts.push(serializeRunColor(f.color));\n if (f.sz !== undefined) parts.push(`<sz val=\"${f.sz}\"/>`);\n if (f.u) parts.push(`<u val=\"${f.u}\"/>`);\n if (f.vertAlign) parts.push(`<vertAlign val=\"${f.vertAlign}\"/>`);\n if (f.scheme) parts.push(`<scheme val=\"${f.scheme}\"/>`);\n parts.push('</rPr>');\n return parts.join('');\n};\n\nconst serializeRunColor = (c: Color): string => {\n const attrs: string[] = [];\n if (c.rgb !== undefined) attrs.push(`rgb=\"${escapeXmlAttr(c.rgb)}\"`);\n else if (c.theme !== undefined) attrs.push(`theme=\"${c.theme}\"`);\n else if (c.indexed !== undefined) attrs.push(`indexed=\"${c.indexed}\"`);\n else if (c.auto !== undefined) attrs.push(`auto=\"${c.auto ? '1' : '0'}\"`);\n if (c.tint !== undefined) attrs.push(`tint=\"${c.tint}\"`);\n // Fallback to colorToHex if nothing was set above (shouldn't happen, but\n // safe).\n if (attrs.length === 0) {\n const hex = colorToHex(c);\n if (hex !== undefined) attrs.push(`rgb=\"${hex}\"`);\n }\n return `<color${attrs.length > 0 ? ` ${attrs.join(' ')}` : ''}/>`;\n};\n","// Workbook root model. / §4.2 / the Workbook is a plain mutable object the user\n// composes via free functions. The Stylesheet pool is held inline so styling\n// operations don't need a side channel.\n\nimport type { Chartsheet } from '../chartsheet/chartsheet';\nimport { makeChartsheet } from '../chartsheet/chartsheet';\nimport { makeAbsoluteAnchor } from '../drawing/anchor';\nimport { type ChartReference, makeChartDrawingItem, makeDrawing } from '../drawing/drawing';\nimport type { CoreProperties } from '../packaging/core';\nimport type { CustomProperties } from '../packaging/custom';\nimport type { ExtendedProperties } from '../packaging/extended';\nimport {\n getCellAlignment,\n getCellBorder,\n getCellFill,\n getCellFont,\n getCellNumberFormat,\n getCellProtection,\n} from '../styles/cell-style';\nimport type { Stylesheet } from '../styles/stylesheet';\nimport { makeStylesheet } from '../styles/stylesheet';\nimport { OpenXmlSchemaError } from '../utils/exceptions';\nimport { type CellValue, isFormulaValue } from '../cell/cell';\nimport type { Alignment } from '../styles/alignment';\nimport type { Border } from '../styles/borders';\nimport type { Fill } from '../styles/fills';\nimport type { Font } from '../styles/fonts';\nimport type { Protection } from '../styles/protection';\nimport { coordinateToTuple, parseSheetRange } from '../utils/coordinate';\nimport { multiCellRangeContainsCell, parseRange, rangeContainsCell, rangeToString } from '../worksheet/cell-range';\nimport type { LegacyComment } from '../worksheet/comments';\nimport type { Hyperlink } from '../worksheet/hyperlinks';\nimport type { CellsByKindCounts, Worksheet } from '../worksheet/worksheet';\nimport {\n classifyCellValue,\n countCellsByKind,\n getCell,\n getCellComment,\n getCellHyperlink,\n getMergedRangeAt,\n isWorksheetEmpty,\n makeWorksheet,\n setCellByCoord,\n} from '../worksheet/worksheet';\n\nexport type SheetState = 'visible' | 'hidden' | 'veryHidden';\n\n/**\n * Discriminated union over the two kinds of sheet a workbook can host. Both\n * variants share `title` (via `sheet.title`) plus the OOXML `sheetId` and\n * `state` attributes; consumers narrow on `kind` to reach the worksheet- vs\n * chartsheet-specific data.\n */\nexport type SheetRef =\n | { kind: 'worksheet'; sheet: Worksheet; sheetId: number; state: SheetState; rId?: string }\n | { kind: 'chartsheet'; sheet: Chartsheet; sheetId: number; state: SheetState; rId?: string };\n\nexport interface Workbook {\n sheets: SheetRef[];\n /** Index into `sheets` of the sheet shown when Excel opens the file. */\n activeSheetIndex: number;\n /** Style pool; cells reference its cellXfs by index. */\n styles: Stylesheet;\n /** Date1904 mode toggles between Excel's two epoch systems. */\n date1904: boolean;\n /** Document properties (docProps/core.xml), typically auto-filled on save. */\n properties?: CoreProperties;\n appProperties?: ExtendedProperties;\n customProperties?: CustomProperties;\n /** Author display names, shared between threaded comments. */\n authors: string[];\n /** Workbook + sheet-scope defined names (named ranges, print areas etc). */\n definedNames: import('./defined-names').DefinedName[];\n /**\n * Raw `xl/theme/theme1.xml` payload kept verbatim across read → write. The\n * theme XML is large and seldom edited by writers; we just shuttle it.\n */\n themeXml?: Uint8Array;\n /**\n * `xl/vbaProject.bin` payload (macro-enabled workbooks). Round-tripped\n * byte-identical when present; the writer also promotes the workbook Override\n * to `vnd.ms-excel.sheet.macroEnabled.main+xml`.\n */\n vbaProject?: Uint8Array;\n /** `xl/vbaProjectSignature.bin` payload, when the macros are signed. */\n vbaSignature?: Uint8Array;\n /**\n * Pass-through bytes for parts we don't model (pivot tables, ActiveX\n * controls, OLE embeddings, customUI ribbons, customXml items …). Keys are\n * archive-relative paths; values are the raw bytes the loader pulled out of\n * the zip and the writer pushes back in unchanged.\n */\n passthrough?: Map<string, Uint8Array>;\n /**\n * Override content type per pass-through path. Excel uses these in\n * `[Content_Types].xml` so manifest validation stays intact across\n * round-trips. Paths without an explicit override fall back to the archive\n * Default extension.\n */\n passthroughContentTypes?: Map<string, string>;\n /**\n * Top-level `<workbook>` children that aren't `<sheets>` or `<definedNames>`\n * (e.g. `<fileVersion>`, `<workbookPr>`, `<bookViews>`, `<calcPr>`,\n * `<pivotCaches>`, `<extLst>`). Captured verbatim so re-saving keeps\n * Excel-rendering fidelity for things we don't model. Split into the two\n * halves the writer needs: anything before `<sheets>` is emitted ahead of the\n * `<sheets>` element, the rest after `<definedNames>`.\n */\n workbookXmlExtras?: {\n beforeSheets: import('../xml/tree').XmlNode[];\n afterSheets: import('../xml/tree').XmlNode[];\n };\n /**\n * `<workbookProtection>` — locks structure / window / revision tracking with\n * the modern hash quad or the legacy 16-bit hash. Round-tripped verbatim;\n * password hashing helpers come later.\n */\n workbookProtection?: import('./protection').WorkbookProtection;\n /**\n * `<bookViews>` — the workbook's window/tab-strip presets. Most workbooks\n * have a single entry whose `firstSheet` / `activeTab` drive the tab the user\n * sees first. Stored as an array because Excel allows multiple views (rare).\n */\n bookViews?: import('./views').WorkbookView[];\n /**\n * `<customWorkbookViews>` — saved per-user view presets used by the\n * deprecated \"Shared Workbook\" feature. Each entry carries its own window\n * position, active sheet, and visibility toggles.\n */\n customWorkbookViews?: import('./views').CustomWorkbookView[];\n /** `<calcPr>` — calculation engine settings (calcMode / iterate / fullPrecision etc.). */\n calcProperties?: import('./calc-properties').CalcProperties;\n /** `<fileVersion>` — Office app/version metadata Excel records on save. */\n fileVersion?: import('./file-version').FileVersion;\n /** `<fileSharing>` — read-only-recommended toggle + write-protection password. */\n fileSharing?: import('./file-sharing').FileSharing;\n /**\n * `<oleSize ref=\"…\">` — bounding range Excel uses when the workbook is\n * embedded as an OLE object inside another Office document.\n */\n oleSize?: string;\n /** `<fileRecoveryPr>` — autoRecover-style flags Excel writes after a recovery save. */\n fileRecoveryPr?: import('./file-recovery').FileRecoveryProperties;\n /**\n * `<pivotCaches>` — links from workbook root to xl/pivotCache parts. The\n * underlying parts survive via the passthrough archive; this typed array\n * preserves the cacheId ↔ rId mapping for consumers that want to introspect\n * the pivot links.\n */\n pivotCaches?: ReadonlyArray<{ cacheId: number; rId: string }>;\n /**\n * `<externalReferences>` — links from workbook root to xl/externalLinks\n * parts. The numeric token in cross-workbook formulas like `[1]Sheet!A1` is\n * the 1-based index into this array. Underlying parts continue via\n * passthrough archive.\n */\n externalReferences?: ReadonlyArray<{ rId: string }>;\n /** `<smartTagPr>` — Excel 2003 smart-tag persistence flags. */\n smartTagPr?: import('./smart-tags').SmartTagProperties;\n /** `<smartTagTypes>` — Excel 2003 smart-tag type registrations. */\n smartTagTypes?: ReadonlyArray<import('./smart-tags').SmartTagType>;\n /** `<functionGroups>` — built-in + user-defined XLL function groups. */\n functionGroups?: import('./function-groups').FunctionGroups;\n /**\n * `<workbookPr>` — VBA codeName, defaultThemeVersion, link-update prompt\n * mode, etc. `date1904` is mirrored here for completeness but the canonical\n * source remains `wb.date1904`.\n */\n workbookProperties?: import('./workbook-properties').WorkbookProperties;\n /**\n * Workbook-level rels that don't match a modeled type. Re-emitted with their\n * original Id so captured `<pivotCaches r:id=\"…\"/>` etc. still resolve after\n * a round-trip.\n */\n workbookRelsExtras?: ReadonlyArray<{ id: string; type: string; target: string }>;\n /**\n * Original rIds for the modeled non-sheet workbook rels so a captured extras\n * XML referencing one of them still resolves after re-save.\n */\n workbookRelOriginalIds?: {\n sharedStrings?: string;\n styles?: string;\n theme?: string;\n vbaProject?: string;\n };\n}\n\n/** Build an empty Workbook ready to host worksheets. */\nexport function createWorkbook(opts?: { date1904?: boolean }): Workbook {\n return {\n sheets: [],\n activeSheetIndex: 0,\n styles: makeStylesheet(),\n date1904: opts?.date1904 ?? false,\n authors: [],\n definedNames: [],\n };\n}\n\n/**\n * Validate a sheet title against Excel's character + length rules. Returns the\n * reason string when the title is rejected; `undefined` when valid. The same\n * rules apply to worksheets and chartsheets.\n *\n * Rules:\n * - Type must be `string`; non-empty; length ≤ 31.\n * - May not contain any of `:`, `\\`, `/`, `?`, `*`, `[`, `]`.\n * - May not start or end with an apostrophe `'`.\n * - May not be the literal `\"History\"` (case-insensitive — Excel\n * reserves that name for the change-tracking sheet).\n *\n * Uniqueness is **not** checked here; pass through `addWorksheet` /\n * `renameSheet` for the workbook-aware duplicate check.\n */\nexport function validateSheetTitle(title: unknown): string | undefined {\n if (typeof title !== 'string') return 'must be a string';\n if (title.length === 0) return 'must be 1..31 chars';\n if (title.length > 31) return 'must be 1..31 chars';\n if (/[:\\\\/?*[\\]]/.test(title)) return 'must not contain : \\\\ / ? * [ ]';\n if (title.startsWith(\"'\") || title.endsWith(\"'\")) return 'must not start or end with an apostrophe';\n if (title.toLowerCase() === 'history') return '\"History\" is reserved by Excel';\n return undefined;\n}\n\n/** Boolean form of {@link validateSheetTitle}. */\nexport const isValidSheetTitle = (title: unknown): title is string => validateSheetTitle(title) === undefined;\n\n/**\n * Pick a unique sheet title based on `base`. If `base` itself is available,\n * it's returned verbatim. Otherwise the helper appends ` (2)`, ` (3)`, … until\n * it finds a free slot. The returned title always satisfies {@link\n * validateSheetTitle} — if the base+suffix would exceed 31 chars, the base is\n * truncated to fit.\n *\n * Excel treats sheet names as case-insensitive for uniqueness, so `Data` and\n * `data` collide; the helper applies the same rule.\n *\n * Useful for \"duplicate sheet\" / \"import\" flows where you want Excel-like\n * automatic uniqueification (\"Sheet1 (2)\").\n */\nexport function pickUniqueSheetTitle(wb: Workbook, base: string): string {\n const reason = validateSheetTitle(base);\n if (reason) {\n throw new OpenXmlSchemaError(`pickUniqueSheetTitle: base \"${base}\" is not a valid sheet title (${reason})`);\n }\n const used = new Set<string>();\n for (const s of wb.sheets) used.add(s.sheet.title.toLowerCase());\n if (!used.has(base.toLowerCase())) return base;\n for (let n = 2; n < 1000; n++) {\n const suffix = ` (${n})`;\n const room = 31 - suffix.length;\n const truncatedBase = base.length > room ? base.slice(0, room) : base;\n const candidate = `${truncatedBase}${suffix}`;\n if (!used.has(candidate.toLowerCase())) return candidate;\n }\n throw new OpenXmlSchemaError(`pickUniqueSheetTitle: exhausted candidates for \"${base}\"`);\n}\n\n// Excel treats sheet names as case-insensitive for uniqueness — \"Data\" and\n// \"data\" cannot co-exist in the same workbook. `ignoreIndex` lets renameSheet\n// pass its own slot so a case-only rename (\"Data\" → \"data\") still succeeds.\nconst validateUniqueTitle = (wb: Workbook, title: string, ignoreIndex?: number): void => {\n const reason = validateSheetTitle(title);\n if (reason) {\n throw new OpenXmlSchemaError(`Worksheet title \"${title}\": ${reason}`);\n }\n const lower = title.toLowerCase();\n for (let i = 0; i < wb.sheets.length; i++) {\n if (i === ignoreIndex) continue;\n const s = wb.sheets[i];\n if (s && s.sheet.title.toLowerCase() === lower) {\n throw new OpenXmlSchemaError(`Worksheet title \"${title}\" is already in use`);\n }\n }\n};\n\nconst allocateSheetId = (wb: Workbook): number => {\n // sheetId is 1-based and unique. Allocate the smallest unused integer.\n const used = new Set<number>();\n for (const s of wb.sheets) used.add(s.sheetId);\n let n = 1;\n while (used.has(n)) n++;\n return n;\n};\n\n/** Add a Worksheet to the Workbook. Returns the sheet for further population. */\nexport function addWorksheet(wb: Workbook, title: string, opts?: { index?: number; state?: SheetState }): Worksheet {\n validateUniqueTitle(wb, title);\n const sheet = makeWorksheet(title);\n const ref: SheetRef = {\n kind: 'worksheet',\n sheet,\n sheetId: allocateSheetId(wb),\n state: opts?.state ?? 'visible',\n };\n if (opts?.index === undefined) {\n wb.sheets.push(ref);\n } else {\n if (opts.index < 0 || opts.index > wb.sheets.length) {\n throw new OpenXmlSchemaError(`addWorksheet: index ${opts.index} out of range`);\n }\n wb.sheets.splice(opts.index, 0, ref);\n }\n return sheet;\n}\n\n/**\n * 0-based tab-strip index of the sheet (worksheet *or* chartsheet) with the\n * given title, or `-1` when not present. Useful when the caller wants to act on\n * the index for `setActiveSheet` / `swapSheets` / similar operations without\n * manually scanning `wb.sheets`.\n */\nexport function getSheetIndex(wb: Workbook, title: string): number {\n for (let i = 0; i < wb.sheets.length; i++) {\n const ref = wb.sheets[i];\n if (ref && ref.sheet.title === title) return i;\n }\n return -1;\n}\n\n/**\n * True iff the workbook has a sheet (worksheet *or* chartsheet) with the given\n * title. Thin shortcut over {@link getSheetIndex}.\n */\nexport function hasSheet(wb: Workbook, title: string): boolean {\n return getSheetIndex(wb, title) >= 0;\n}\n\n/**\n * Count sheets in the workbook, with optional kind/state filters. Mirrors the\n * filter shape of {@link getSheetTitles} but skips the array allocation when\n * the caller only needs the count.\n */\nexport function countSheets(\n wb: Workbook,\n opts: { kind?: 'worksheet' | 'chartsheet'; state?: SheetState } = {},\n): number {\n let n = 0;\n for (const ref of wb.sheets) {\n if (opts.kind !== undefined && ref.kind !== opts.kind) continue;\n if (opts.state !== undefined && ref.state !== opts.state) continue;\n n++;\n }\n return n;\n}\n\n/**\n * Sheet titles in tab-strip order. By default returns titles for every sheet\n * (worksheets + chartsheets). Optional filters narrow to one kind\n * (`'worksheet'` / `'chartsheet'`) or one state (`'visible' | 'hidden' |\n * 'veryHidden'`).\n */\nexport function getSheetTitles(\n wb: Workbook,\n opts: { kind?: 'worksheet' | 'chartsheet'; state?: SheetState } = {},\n): string[] {\n const out: string[] = [];\n for (const ref of wb.sheets) {\n if (opts.kind !== undefined && ref.kind !== opts.kind) continue;\n if (opts.state !== undefined && ref.state !== opts.state) continue;\n out.push(ref.sheet.title);\n }\n return out;\n}\n\n/**\n * True iff the workbook has a **worksheet** (not a chartsheet) with the given\n * title. Distinct from {@link hasSheet} (matches either kind) and {@link\n * hasChartsheet} (chartsheets only).\n */\nexport function hasWorksheet(wb: Workbook, title: string): boolean {\n return getSheet(wb, title) !== undefined;\n}\n\n/**\n * True iff the workbook has a **chartsheet** (not a worksheet) with the given\n * title. Distinct from {@link hasSheet}, which matches either kind. Use this\n * when the caller needs to discriminate before calling chartsheet-only\n * operations.\n */\nexport function hasChartsheet(wb: Workbook, title: string): boolean {\n for (const ref of wb.sheets) {\n if (ref.kind === 'chartsheet' && ref.sheet.title === title) return true;\n }\n return false;\n}\n\n/** Look up a Worksheet by title. Returns undefined for missing names or chartsheets. */\nexport function getSheet(wb: Workbook, title: string): Worksheet | undefined {\n for (const s of wb.sheets) {\n if (s.kind === 'worksheet' && s.sheet.title === title) return s.sheet;\n }\n return undefined;\n}\n\n/** Look up a Worksheet by index in the sheets array. Returns undefined for chartsheet slots. */\nexport function getSheetByIndex(wb: Workbook, idx: number): Worksheet | undefined {\n const ref = wb.sheets[idx];\n return ref?.kind === 'worksheet' ? ref.sheet : undefined;\n}\n\n/** Look up a Chartsheet by title. Returns undefined for missing names or worksheets. */\nexport function getChartsheet(wb: Workbook, title: string): Chartsheet | undefined {\n for (const s of wb.sheets) {\n if (s.kind === 'chartsheet' && s.sheet.title === title) return s.sheet;\n }\n return undefined;\n}\n\n/** Add a Chartsheet to the Workbook. Returns the chartsheet for further population. */\nexport function addChartsheet(\n wb: Workbook,\n title: string,\n opts?: { index?: number; state?: SheetState; chart?: ChartReference },\n): Chartsheet {\n validateUniqueTitle(wb, title);\n const cs = makeChartsheet(title);\n // When the caller supplies a ChartReference, wrap it in a single-anchor\n // drawing so the writer emits xl/drawings/drawingN.xml + chart part.\n if (opts?.chart) {\n // The drawing wraps the chart in a single absoluteAnchor sized to a\n // standard A4-landscape page (Excel re-flows on open if needed).\n cs.drawing = makeDrawing([\n makeChartDrawingItem(makeAbsoluteAnchor({ x: 0, y: 0, cx: 9144000, cy: 6858000 }), opts.chart),\n ]);\n }\n const ref: SheetRef = {\n kind: 'chartsheet',\n sheet: cs,\n sheetId: allocateSheetId(wb),\n state: opts?.state ?? 'visible',\n };\n if (opts?.index === undefined) {\n wb.sheets.push(ref);\n } else {\n if (opts.index < 0 || opts.index > wb.sheets.length) {\n throw new OpenXmlSchemaError(`addChartsheet: index ${opts.index} out of range`);\n }\n wb.sheets.splice(opts.index, 0, ref);\n }\n return cs;\n}\n\n/** All worksheet titles, in display order. */\nexport function sheetNames(wb: Workbook): string[] {\n return wb.sheets.map((s) => s.sheet.title);\n}\n\n/** Remove a sheet by title. No-op if the title is not registered. */\nexport function removeSheet(wb: Workbook, title: string): void {\n const i = wb.sheets.findIndex((s) => s.sheet.title === title);\n if (i < 0) return;\n wb.sheets.splice(i, 1);\n // Clamp activeSheetIndex within bounds.\n if (wb.activeSheetIndex >= wb.sheets.length) {\n wb.activeSheetIndex = Math.max(0, wb.sheets.length - 1);\n }\n}\n\n/** Set the active sheet by title; throws on unknown title. */\nexport function setActiveSheet(wb: Workbook, title: string): void {\n const i = wb.sheets.findIndex((s) => s.sheet.title === title);\n if (i < 0) throw new OpenXmlSchemaError(`setActiveSheet: no sheet named \"${title}\"`);\n wb.activeSheetIndex = i;\n}\n\n/**\n * Rename a sheet from `oldTitle` to `newTitle`. Throws if no sheet matches\n * `oldTitle`, or if `newTitle` collides with an existing sheet (Excel requires\n * sheet names to be unique within a workbook).\n */\nexport function renameSheet(wb: Workbook, oldTitle: string, newTitle: string): void {\n const i = wb.sheets.findIndex((s) => s.sheet.title === oldTitle);\n if (i < 0) throw new OpenXmlSchemaError(`renameSheet: no sheet named \"${oldTitle}\"`);\n if (oldTitle === newTitle) return;\n // Excel allows case-only renames (\"Data\" → \"data\"); ignore the current slot\n // when checking uniqueness so the rename validates against everything else.\n validateUniqueTitle(wb, newTitle, i);\n const ref = wb.sheets[i];\n if (ref) ref.sheet.title = newTitle;\n}\n\n/**\n * Set the visibility state on a sheet by title. Throws on unknown title.\n * Refuses to hide the last visible sheet: an .xlsx with every sheet hidden\n * fails to open in Excel (\"Excel cannot use the object linking and embedding\n * features because no sheet is visible\"). Catching it here keeps the\n * workbook recoverable instead of producing a save Excel will reject.\n */\nexport function setSheetState(wb: Workbook, title: string, state: SheetState): void {\n const ref = wb.sheets.find((s) => s.sheet.title === title);\n if (!ref) throw new OpenXmlSchemaError(`setSheetState: no sheet named \"${title}\"`);\n if (ref.state === state) return;\n if (state !== 'visible' && ref.state === 'visible') {\n let otherVisible = false;\n for (const candidate of wb.sheets) {\n if (candidate !== ref && candidate.state === 'visible') {\n otherVisible = true;\n break;\n }\n }\n if (!otherVisible) {\n throw new OpenXmlSchemaError(\n `setSheetState: cannot hide \"${title}\" — it's the last visible sheet,` +\n ' and Excel refuses to open a workbook with every sheet hidden. Make another sheet' +\n ' visible first (or call showSheet()).',\n );\n }\n }\n ref.state = state;\n}\n\n/** Look up the current visibility state. Throws on unknown title. */\nexport function getSheetState(wb: Workbook, title: string): SheetState {\n const ref = wb.sheets.find((s) => s.sheet.title === title);\n if (!ref) throw new OpenXmlSchemaError(`getSheetState: no sheet named \"${title}\"`);\n return ref.state;\n}\n\n/**\n * Hide a sheet (`state: 'hidden'`). Equivalent to right-click → Hide in Excel —\n * the user can re-show it via the Unhide dialog.\n */\nexport function hideSheet(wb: Workbook, title: string): void {\n setSheetState(wb, title, 'hidden');\n}\n\n/**\n * Mark a sheet as very-hidden (`state: 'veryHidden'`). Excel won't surface it\n * in the Unhide dialog — only reachable via VBA / API.\n */\nexport function veryHideSheet(wb: Workbook, title: string): void {\n setSheetState(wb, title, 'veryHidden');\n}\n\n/** Make a hidden / veryHidden sheet visible. */\nexport function showSheet(wb: Workbook, title: string): void {\n setSheetState(wb, title, 'visible');\n}\n\n/**\n * Bulk-update visibility state for many sheets in one call. `entries` is a\n * `Record<title, state>` map; missing titles throw via the underlying\n * `setSheetState`.\n */\nexport function setSheetStates(wb: Workbook, entries: Record<string, SheetState>): void {\n for (const [title, state] of Object.entries(entries)) {\n setSheetState(wb, title, state);\n }\n}\n\n/**\n * Show every hidden / veryHidden worksheet. Returns the count unhidden. Useful\n * for spreadsheet-wide auditing.\n */\nexport function showAllSheets(wb: Workbook): number {\n let n = 0;\n for (const ref of wb.sheets) {\n if (ref.state !== 'visible') {\n ref.state = 'visible';\n n++;\n }\n }\n return n;\n}\n\n/**\n * Move a sheet to a new tab-strip position. `toIndex` is clamped to `[0,\n * sheets.length - 1]`. Adjusts `activeSheetIndex` so the same sheet stays\n * active across the move.\n */\nexport function moveSheet(wb: Workbook, title: string, toIndex: number): void {\n const from = wb.sheets.findIndex((s) => s.sheet.title === title);\n if (from < 0) throw new OpenXmlSchemaError(`moveSheet: no sheet named \"${title}\"`);\n if (!Number.isInteger(toIndex)) {\n throw new OpenXmlSchemaError(`moveSheet: toIndex must be an integer; got ${toIndex}`);\n }\n const dest = Math.max(0, Math.min(wb.sheets.length - 1, toIndex));\n if (from === dest) return;\n const wasActive = wb.activeSheetIndex === from;\n const [moved] = wb.sheets.splice(from, 1);\n if (moved) wb.sheets.splice(dest, 0, moved);\n if (wasActive) {\n wb.activeSheetIndex = dest;\n } else {\n // Re-index activeSheetIndex if the move shifted it.\n let cur = wb.activeSheetIndex;\n if (from < cur) cur -= 1;\n if (dest <= cur) cur += 1;\n wb.activeSheetIndex = Math.max(0, Math.min(wb.sheets.length - 1, cur));\n }\n}\n\n/**\n * Swap the tab-strip positions of two sheets by title. Both titles must exist;\n * throws otherwise. `activeSheetIndex` follows the moved sheet so the same\n * sheet stays active across the swap.\n */\nexport function swapSheets(wb: Workbook, titleA: string, titleB: string): void {\n const i = wb.sheets.findIndex((s) => s.sheet.title === titleA);\n const j = wb.sheets.findIndex((s) => s.sheet.title === titleB);\n if (i < 0) throw new OpenXmlSchemaError(`swapSheets: no sheet named \"${titleA}\"`);\n if (j < 0) throw new OpenXmlSchemaError(`swapSheets: no sheet named \"${titleB}\"`);\n if (i === j) return;\n const a = wb.sheets[i];\n const b = wb.sheets[j];\n if (!a || !b) return;\n wb.sheets[i] = b;\n wb.sheets[j] = a;\n if (wb.activeSheetIndex === i) wb.activeSheetIndex = j;\n else if (wb.activeSheetIndex === j) wb.activeSheetIndex = i;\n}\n\n/**\n * Duplicate a worksheet end-to-end and append it as `newTitle`. Mirrors Excel's\n * \"Move or Copy → Create a copy\" command. Cells, dimensions, styles (via shared\n * cellXf ids), comments, hyperlinks, conditional formatting, page setup, etc.\n * all carry over verbatim — only fields that must stay workbook-unique get\n * rewritten:\n *\n * - sheet `title` → `newTitle`\n * - sheet `sheetId` → freshly allocated\n * - each table's `id` → max(workbook table ids) + 1\n * - each table's `displayName` → suffixed with `opts.tableSuffix`\n * (default `\"_2\"`) so it doesn't collide with the original\n *\n * The new sheet is inserted at the optional `index` (default: appended).\n */\nexport function duplicateSheet(\n wb: Workbook,\n sourceTitle: string,\n newTitle: string,\n opts: { index?: number; state?: SheetState; tableSuffix?: string } = {},\n): Worksheet {\n validateUniqueTitle(wb, newTitle);\n const sourceRef = wb.sheets.find((s) => s.kind === 'worksheet' && s.sheet.title === sourceTitle);\n if (!sourceRef || sourceRef.kind !== 'worksheet') {\n throw new OpenXmlSchemaError(`duplicateSheet: no worksheet named \"${sourceTitle}\"`);\n }\n const cloned = structuredClone(sourceRef.sheet);\n cloned.title = newTitle;\n\n // Table id + displayName must stay workbook-unique. Walk every other sheet to\n // find the next free id and renumber/rename in place.\n const suffix = opts.tableSuffix ?? '_2';\n let nextTableId = 0;\n const usedDisplayNames = new Set<string>();\n for (const s of wb.sheets) {\n if (s.kind !== 'worksheet') continue;\n for (const t of s.sheet.tables) {\n if (t.id > nextTableId) nextTableId = t.id;\n usedDisplayNames.add(t.displayName);\n }\n }\n for (const t of cloned.tables) {\n nextTableId += 1;\n t.id = nextTableId;\n let candidate = `${t.displayName}${suffix}`;\n let n = 2;\n while (usedDisplayNames.has(candidate)) {\n candidate = `${t.displayName}${suffix}${n}`;\n n += 1;\n }\n t.displayName = candidate;\n if (t.name === undefined) t.name = candidate;\n usedDisplayNames.add(candidate);\n }\n\n const ref: SheetRef = {\n kind: 'worksheet',\n sheet: cloned,\n sheetId: allocateSheetId(wb),\n state: opts.state ?? 'visible',\n };\n if (opts.index === undefined) {\n wb.sheets.push(ref);\n } else {\n if (opts.index < 0 || opts.index > wb.sheets.length) {\n throw new OpenXmlSchemaError(`duplicateSheet: index ${opts.index} out of range`);\n }\n wb.sheets.splice(opts.index, 0, ref);\n }\n return cloned;\n}\n\n/**\n * Aggregate counts about a workbook's content. Useful for quick QA after large\n * mutations or for surfacing a \"what's in this file\" banner. All counts walk\n * the typed model — they do **not** save the workbook to bytes — so the cost is\n * O(workbook content).\n */\nexport interface WorkbookStats {\n /** Total worksheets (excludes chartsheets). */\n worksheetCount: number;\n /** Total chartsheets. */\n chartsheetCount: number;\n /** Sum of populated cells across every worksheet. */\n cellCount: number;\n /** Sum of formula cells. */\n formulaCount: number;\n /** Sum of legacyComments across every worksheet. */\n commentCount: number;\n /** Sum of hyperlinks across every worksheet. */\n hyperlinkCount: number;\n /** Sum of mergedCells ranges. */\n mergedRangeCount: number;\n /** Sum of Excel tables. */\n tableCount: number;\n /** Workbook-level defined names. */\n definedNameCount: number;\n /** Custom-property entry count, 0 when no docProps/custom.xml. */\n customPropertyCount: number;\n}\n\nexport function getWorkbookStats(wb: Workbook): WorkbookStats {\n let worksheetCount = 0;\n let chartsheetCount = 0;\n let cellCount = 0;\n let formulaCount = 0;\n let commentCount = 0;\n let hyperlinkCount = 0;\n let mergedRangeCount = 0;\n let tableCount = 0;\n for (const ref of wb.sheets) {\n if (ref.kind === 'worksheet') {\n worksheetCount++;\n const ws = ref.sheet;\n for (const rowMap of ws.rows.values()) {\n for (const cell of rowMap.values()) {\n cellCount++;\n if (isFormulaValue(cell.value)) formulaCount++;\n }\n }\n commentCount += ws.legacyComments.length;\n hyperlinkCount += ws.hyperlinks.length;\n mergedRangeCount += ws.mergedCells.length;\n tableCount += ws.tables.length;\n } else {\n chartsheetCount++;\n }\n }\n return {\n worksheetCount,\n chartsheetCount,\n cellCount,\n formulaCount,\n commentCount,\n hyperlinkCount,\n mergedRangeCount,\n tableCount,\n definedNameCount: wb.definedNames.length,\n customPropertyCount: wb.customProperties?.properties.length ?? 0,\n };\n}\n\n/**\n * Workbook-wide value-kind histogram. Sums {@link countCellsByKind} across\n * every Worksheet (chartsheets contribute no cells). Buckets have the same\n * shape as the per-worksheet result; an empty workbook returns all-zero counts.\n */\nexport function getWorkbookCellsByKind(wb: Workbook): CellsByKindCounts {\n const out: CellsByKindCounts = {\n null: 0,\n string: 0,\n number: 0,\n boolean: 0,\n date: 0,\n duration: 0,\n error: 0,\n 'rich-text': 0,\n formula: 0,\n };\n for (const ws of iterWorksheets(wb)) {\n const partial = countCellsByKind(ws);\n out.null += partial.null;\n out.string += partial.string;\n out.number += partial.number;\n out.boolean += partial.boolean;\n out.date += partial.date;\n out.duration += partial.duration;\n out.error += partial.error;\n out['rich-text'] += partial['rich-text'];\n out.formula += partial.formula;\n }\n return out;\n}\n\n/**\n * Resolve a sheet-qualified A1 address (`'Sheet1!A1'`) to its Cell, or\n * `undefined` when the cell isn't materialised. Throws on malformed addresses,\n * missing sheets, or range inputs.\n */\nexport function getCellAtAddress(wb: Workbook, address: string): import('../cell/cell').Cell | undefined {\n const { sheet: sheetTitle, range } = parseSheetRange(address);\n if (range.includes(':')) {\n throw new OpenXmlSchemaError(\n `getCellAtAddress: address \"${address}\" refers to a range, not a single cell`,\n );\n }\n const ws = getSheet(wb, sheetTitle);\n if (!ws) {\n throw new OpenXmlSchemaError(`getCellAtAddress: sheet \"${sheetTitle}\" not found`);\n }\n const { col, row } = coordinateToTuple(range);\n return getCell(ws, row, col);\n}\n\n/**\n * Set a single cell by sheet-qualified A1 address. Throws on malformed\n * addresses, missing sheets, or range inputs.\n */\nexport function setCellAtAddress(\n wb: Workbook,\n address: string,\n value: CellValue,\n): import('../cell/cell').Cell {\n const { sheet: sheetTitle, range } = parseSheetRange(address);\n if (range.includes(':')) {\n throw new OpenXmlSchemaError(\n `setCellAtAddress: address \"${address}\" refers to a range, not a single cell`,\n );\n }\n const ws = getSheet(wb, sheetTitle);\n if (!ws) {\n throw new OpenXmlSchemaError(`setCellAtAddress: sheet \"${sheetTitle}\" not found`);\n }\n return setCellByCoord(ws, range, value);\n}\n\n/**\n * True iff every Worksheet in the workbook is empty (per {@link\n * isWorksheetEmpty}). Chartsheets carry no cells so they never affect the\n * result. A workbook with zero worksheets is also empty by this definition.\n *\n * Short-circuits on the first non-empty worksheet.\n */\nexport function isWorkbookEmpty(wb: Workbook): boolean {\n for (const ws of iterWorksheets(wb)) {\n if (!isWorksheetEmpty(ws)) return false;\n }\n return true;\n}\n\n/**\n * Per-sheet entry inside {@link WorkbookOverview}. Holds enough metadata to\n * make a \"what's in this workbook\" panel useful without forcing the caller to\n * walk every worksheet themselves.\n */\nexport interface WorkbookSheetOverview {\n title: string;\n kind: 'worksheet' | 'chartsheet';\n state: SheetState;\n /** Populated cells in the sheet (0 for chartsheets). */\n cellCount: number;\n /** Populated formula cells (0 for chartsheets). */\n formulaCount: number;\n /** Tables registered on the sheet. */\n tableCount: number;\n /** Drawing items (charts + pictures) on the sheet. */\n drawingItemCount: number;\n}\n\n/**\n * High-level \"what's in this workbook\" snapshot. Combines the aggregate counts\n * from {@link getWorkbookStats} and value-kind histogram from {@link\n * getWorkbookCellsByKind} with per-sheet metadata. JSON-serialisable; suitable\n * for a UI banner / debug dump.\n */\nexport interface WorkbookOverview {\n worksheetCount: number;\n chartsheetCount: number;\n cellCount: number;\n formulaCount: number;\n commentCount: number;\n hyperlinkCount: number;\n mergedRangeCount: number;\n tableCount: number;\n definedNameCount: number;\n customPropertyCount: number;\n cellsByKind: CellsByKindCounts;\n sheets: WorkbookSheetOverview[];\n}\n\nexport function describeWorkbook(wb: Workbook): WorkbookOverview {\n // Single-pass aggregation: a cell-by-cell walk dominates this function's\n // cost on million-cell workbooks, so we compute the workbook stats, the\n // value-kind histogram, AND each sheet's cell/formula counts in one sweep\n // instead of triple-scanning.\n let worksheetCount = 0;\n let chartsheetCount = 0;\n let cellCount = 0;\n let formulaCount = 0;\n let commentCount = 0;\n let hyperlinkCount = 0;\n let mergedRangeCount = 0;\n let tableCount = 0;\n const cellsByKind: CellsByKindCounts = {\n null: 0,\n string: 0,\n number: 0,\n boolean: 0,\n date: 0,\n duration: 0,\n error: 0,\n 'rich-text': 0,\n formula: 0,\n };\n const sheets: WorkbookSheetOverview[] = wb.sheets.map((ref) => {\n if (ref.kind === 'chartsheet') {\n chartsheetCount++;\n return {\n title: ref.sheet.title,\n kind: 'chartsheet',\n state: ref.state,\n cellCount: 0,\n formulaCount: 0,\n tableCount: 0,\n drawingItemCount: ref.sheet.drawing?.items.length ?? 0,\n };\n }\n worksheetCount++;\n const ws = ref.sheet;\n let sheetCellCount = 0;\n let sheetFormulaCount = 0;\n for (const rowMap of ws.rows.values()) {\n for (const cell of rowMap.values()) {\n sheetCellCount++;\n const bucket = classifyCellValue(cell.value);\n cellsByKind[bucket]++;\n if (isFormulaValue(cell.value)) sheetFormulaCount++;\n }\n }\n cellCount += sheetCellCount;\n formulaCount += sheetFormulaCount;\n commentCount += ws.legacyComments.length;\n hyperlinkCount += ws.hyperlinks.length;\n mergedRangeCount += ws.mergedCells.length;\n tableCount += ws.tables.length;\n return {\n title: ws.title,\n kind: 'worksheet',\n state: ref.state,\n cellCount: sheetCellCount,\n formulaCount: sheetFormulaCount,\n tableCount: ws.tables.length,\n drawingItemCount: ws.drawing?.items.length ?? 0,\n };\n });\n return {\n worksheetCount,\n chartsheetCount,\n cellCount,\n formulaCount,\n commentCount,\n hyperlinkCount,\n mergedRangeCount,\n tableCount,\n definedNameCount: wb.definedNames.length,\n customPropertyCount: wb.customProperties?.properties.length ?? 0,\n cellsByKind,\n sheets,\n };\n}\n\n/**\n * Debug-friendly snapshot of everything resolved for a single cell: its value,\n * the full style chain (font / fill / border / alignment / protection /\n * numberFormat), the applied hyperlink + comment, the merged range it sits\n * inside (if any), and the names of any tables / the count of CF / DV blocks\n * that target it.\n *\n * Designed for `console.log`-style introspection — JSON-serialisable and stable\n * in shape regardless of which axes are populated.\n *\n * Throws when `sheetTitle` doesn't resolve. When `ref` is a valid A1 coordinate\n * but no cell exists there, `exists` is `false` and the style chain reflects\n * the workbook defaults.\n */\nexport interface CellSummary {\n ref: string;\n sheet: string;\n exists: boolean;\n value: CellValue | undefined;\n styleId: number;\n font: Font;\n fill: Fill;\n border: Border;\n alignment: Alignment;\n protection: Protection;\n numberFormat: string;\n hyperlink: Hyperlink | undefined;\n comment: LegacyComment | undefined;\n mergedRange: string | undefined;\n inTables: string[];\n inDataValidations: number;\n inConditionalFormatting: number;\n}\n\nexport function getCellSummary(wb: Workbook, sheetTitle: string, ref: string): CellSummary {\n const ws = getSheet(wb, sheetTitle);\n if (!ws) throw new OpenXmlSchemaError(`getCellSummary: sheet \"${sheetTitle}\" not found`);\n const { col, row } = coordinateToTuple(ref);\n const cell = getCell(ws, row, col);\n // Synthesize a placeholder cell so getCell* helpers can resolve defaults even\n // for unmaterialised coordinates.\n const probe = cell ?? { row, col, value: null, styleId: 0 };\n const merged = getMergedRangeAt(ws, row, col);\n const inTables: string[] = [];\n for (const t of ws.tables) {\n if (rangeContainsCell(parseRange(t.ref), row, col)) inTables.push(t.displayName);\n }\n let inDv = 0;\n for (const dv of ws.dataValidations) {\n if (multiCellRangeContainsCell(dv.sqref, row, col)) inDv++;\n }\n let inCf = 0;\n for (const cf of ws.conditionalFormatting) {\n if (multiCellRangeContainsCell(cf.sqref, row, col)) inCf++;\n }\n return {\n ref,\n sheet: sheetTitle,\n exists: cell !== undefined,\n value: cell?.value,\n styleId: probe.styleId,\n font: getCellFont(wb, probe),\n fill: getCellFill(wb, probe),\n border: getCellBorder(wb, probe),\n alignment: getCellAlignment(wb, probe),\n protection: getCellProtection(wb, probe),\n numberFormat: getCellNumberFormat(wb, probe),\n hyperlink: cell ? getCellHyperlink(ws, cell) : undefined,\n comment: cell ? getCellComment(ws, cell) : undefined,\n mergedRange: merged ? rangeToString(merged) : undefined,\n inTables,\n inDataValidations: inDv,\n inConditionalFormatting: inCf,\n };\n}\n\n/**\n * Iterate over every Worksheet in the workbook (skips chartsheets). Yields each\n * worksheet in tab-strip order.\n */\nexport function* iterWorksheets(wb: Workbook): IterableIterator<Worksheet> {\n for (const ref of wb.sheets) {\n if (ref.kind === 'worksheet') yield ref.sheet;\n }\n}\n\n/**\n * Iterate only over Worksheets whose tab-strip state is `'visible'`. Hidden /\n * veryHidden sheets are skipped. Useful for reports that should ignore\n * back-office sheets the author has hidden.\n */\nexport function* iterVisibleWorksheets(wb: Workbook): IterableIterator<Worksheet> {\n for (const ref of wb.sheets) {\n if (ref.kind === 'worksheet' && ref.state === 'visible') yield ref.sheet;\n }\n}\n\n/**\n * Iterate Worksheets matching the supplied state. Pass `'hidden'` to skim\n * back-office sheets, `'veryHidden'` to find sheets only accessible via VBA,\n * etc.\n */\nexport function* iterWorksheetsByState(\n wb: Workbook,\n state: SheetState,\n): IterableIterator<Worksheet> {\n for (const ref of wb.sheets) {\n if (ref.kind === 'worksheet' && ref.state === state) yield ref.sheet;\n }\n}\n\n/**\n * Iterate every cell across every worksheet in the workbook. Yields `{ sheet,\n * cell }` pairs in tab-strip order, then row-then-column within each sheet.\n * Useful for workbook-wide audits / find-and-replace passes.\n */\nexport function* iterAllCells(\n wb: Workbook,\n): IterableIterator<{ sheet: Worksheet; cell: import('../cell/cell').Cell }> {\n for (const sheet of iterWorksheets(wb)) {\n const rowKeys = [...sheet.rows.keys()].sort((a, b) => a - b);\n for (const r of rowKeys) {\n const rowMap = sheet.rows.get(r);\n if (!rowMap) continue;\n const cols = [...rowMap.keys()].sort((a, b) => a - b);\n for (const c of cols) {\n const cell = rowMap.get(c);\n if (cell !== undefined) yield { sheet, cell };\n }\n }\n }\n}\n\n/**\n * Collect every merged range across every worksheet. Each entry carries the\n * merge bounds plus a back-reference to the owning sheet, in tab-strip order.\n * Equivalent to walking `iterWorksheets` and concatenating each sheet's\n * `mergedCells`.\n */\nexport function getAllMergedRanges(\n wb: Workbook,\n): ReadonlyArray<{ sheet: Worksheet; range: import('../worksheet/cell-range').CellRange }> {\n const out: Array<{ sheet: Worksheet; range: import('../worksheet/cell-range').CellRange }> = [];\n for (const sheet of iterWorksheets(wb)) {\n for (const range of sheet.mergedCells) out.push({ sheet, range });\n }\n return out;\n}\n\n/**\n * Collect every hyperlink across every worksheet. Each entry pairs the\n * hyperlink with a back-reference to the owning sheet, in tab-strip order.\n */\nexport function getAllHyperlinks(\n wb: Workbook,\n): ReadonlyArray<{ sheet: Worksheet; hyperlink: import('../worksheet/hyperlinks').Hyperlink }> {\n const out: Array<{ sheet: Worksheet; hyperlink: import('../worksheet/hyperlinks').Hyperlink }> = [];\n for (const sheet of iterWorksheets(wb)) {\n for (const h of sheet.hyperlinks) out.push({ sheet, hyperlink: h });\n }\n return out;\n}\n\n/**\n * Collect every legacy comment across every worksheet. Each entry pairs the\n * comment with a back-reference to the owning sheet, in tab-strip order.\n */\nexport function getAllComments(\n wb: Workbook,\n): ReadonlyArray<{ sheet: Worksheet; comment: import('../worksheet/comments').LegacyComment }> {\n const out: Array<{ sheet: Worksheet; comment: import('../worksheet/comments').LegacyComment }> = [];\n for (const sheet of iterWorksheets(wb)) {\n for (const c of sheet.legacyComments) out.push({ sheet, comment: c });\n }\n return out;\n}\n\n/**\n * Collect every Excel table across every worksheet. Each entry pairs the\n * TableDefinition with a back-reference to the owning sheet, in tab-strip\n * order.\n */\nexport function getAllTables(\n wb: Workbook,\n): ReadonlyArray<{ sheet: Worksheet; table: import('../worksheet/table').TableDefinition }> {\n const out: Array<{ sheet: Worksheet; table: import('../worksheet/table').TableDefinition }> = [];\n for (const sheet of iterWorksheets(wb)) {\n for (const t of sheet.tables) out.push({ sheet, table: t });\n }\n return out;\n}\n\n/**\n * Locate an Excel table by `displayName` across the whole workbook. Excel\n * enforces uniqueness at the workbook level, so the first match wins. Returns\n * the owning sheet + the table itself, or `undefined` when nothing matches.\n */\nexport function findTable(\n wb: Workbook,\n displayName: string,\n): { sheet: Worksheet; table: import('../worksheet/table').TableDefinition } | undefined {\n for (const sheet of iterWorksheets(wb)) {\n for (const t of sheet.tables) {\n if (t.displayName === displayName) return { sheet, table: t };\n }\n }\n return undefined;\n}\n\n/**\n * First cell across the workbook satisfying `predicate`. Walks every worksheet\n * in tab-strip order, then row-then-column within each sheet (same order as\n * {@link iterAllCells}). Returns `{ sheet, cell }` for the match, or\n * `undefined` when nothing matches.\n */\nexport function findCellInWorkbook(\n wb: Workbook,\n predicate: (cell: import('../cell/cell').Cell, sheet: Worksheet) => boolean,\n): { sheet: Worksheet; cell: import('../cell/cell').Cell } | undefined {\n for (const { sheet, cell } of iterAllCells(wb)) {\n if (predicate(cell, sheet)) return { sheet, cell };\n }\n return undefined;\n}\n\n/**\n * Every cell across the workbook satisfying `predicate`. Same iteration order\n * as {@link iterAllCells}. Returns an array of `{ sheet, cell }` matches.\n */\nexport function findCellsInWorkbook(\n wb: Workbook,\n predicate: (cell: import('../cell/cell').Cell, sheet: Worksheet) => boolean,\n): ReadonlyArray<{ sheet: Worksheet; cell: import('../cell/cell').Cell }> {\n const out: Array<{ sheet: Worksheet; cell: import('../cell/cell').Cell }> = [];\n for (const { sheet, cell } of iterAllCells(wb)) {\n if (predicate(cell, sheet)) out.push({ sheet, cell });\n }\n return out;\n}\n\n/**\n * Workbook-wide find-and-replace. Same matching rule as `replaceCellValues` but\n * walks every worksheet via {@link iterAllCells}. `search` is either an\n * exact-string match (string-valued cells only) or a predicate `(value, cell,\n * sheet) → boolean`. `replacement` is the new `CellValue`. Returns the count of\n * cells changed across all sheets.\n */\nexport function replaceCellValuesInWorkbook(\n wb: Workbook,\n search:\n | string\n | ((value: import('../cell/cell').CellValue, cell: import('../cell/cell').Cell, sheet: Worksheet) => boolean),\n replacement: import('../cell/cell').CellValue,\n): number {\n let n = 0;\n const matchFn =\n typeof search === 'string'\n ? (v: import('../cell/cell').CellValue) => typeof v === 'string' && v === search\n : (v: import('../cell/cell').CellValue, c: import('../cell/cell').Cell, s: Worksheet) => search(v, c, s);\n for (const { sheet, cell } of iterAllCells(wb)) {\n if (matchFn(cell.value, cell, sheet)) {\n cell.value = replacement;\n n++;\n }\n }\n return n;\n}\n\n/**\n * Collect every data-validation block across every worksheet. Each entry pairs\n * the validation with a back-reference to the owning sheet, in tab-strip order.\n */\nexport function getAllDataValidations(\n wb: Workbook,\n): ReadonlyArray<{ sheet: Worksheet; validation: import('../worksheet/data-validations').DataValidation }> {\n const out: Array<{\n sheet: Worksheet;\n validation: import('../worksheet/data-validations').DataValidation;\n }> = [];\n for (const sheet of iterWorksheets(wb)) {\n for (const v of sheet.dataValidations) out.push({ sheet, validation: v });\n }\n return out;\n}\n\n/**\n * Collect every image (picture) DrawingItem across every worksheet, each paired\n * with its owning sheet in tab-strip order.\n */\nexport function getAllImages(\n wb: Workbook,\n): ReadonlyArray<{ sheet: Worksheet; item: import('../drawing/drawing').DrawingItem }> {\n const out: Array<{ sheet: Worksheet; item: import('../drawing/drawing').DrawingItem }> = [];\n for (const sheet of iterWorksheets(wb)) {\n if (!sheet.drawing) continue;\n for (const item of sheet.drawing.items) {\n if (item.content.kind === 'picture') out.push({ sheet, item });\n }\n }\n return out;\n}\n\n/**\n * Collect every chart DrawingItem across every worksheet, each paired with its\n * owning sheet in tab-strip order.\n */\nexport function getAllCharts(\n wb: Workbook,\n): ReadonlyArray<{ sheet: Worksheet; item: import('../drawing/drawing').DrawingItem }> {\n const out: Array<{ sheet: Worksheet; item: import('../drawing/drawing').DrawingItem }> = [];\n for (const sheet of iterWorksheets(wb)) {\n if (!sheet.drawing) continue;\n for (const item of sheet.drawing.items) {\n if (item.content.kind === 'chart') out.push({ sheet, item });\n }\n }\n return out;\n}\n\n/**\n * Collect every conditional-formatting block across every worksheet. Each entry\n * pairs the CF block with a back-reference to the owning sheet, in tab-strip\n * order.\n */\nexport function getAllConditionalFormatting(\n wb: Workbook,\n): ReadonlyArray<{\n sheet: Worksheet;\n formatting: import('../worksheet/conditional-formatting').ConditionalFormatting;\n}> {\n const out: Array<{\n sheet: Worksheet;\n formatting: import('../worksheet/conditional-formatting').ConditionalFormatting;\n }> = [];\n for (const sheet of iterWorksheets(wb)) {\n for (const cf of sheet.conditionalFormatting) out.push({ sheet, formatting: cf });\n }\n return out;\n}\n\n/**\n * Iterate over every Chartsheet in the workbook. Yields in tab-strip order,\n * skipping regular worksheets.\n */\nexport function* iterChartsheets(wb: Workbook): IterableIterator<Chartsheet> {\n for (const ref of wb.sheets) {\n if (ref.kind === 'chartsheet') yield ref.sheet;\n }\n}\n\n/** Convenience: array of every Worksheet in tab-strip order. */\nexport function listWorksheets(wb: Workbook): Worksheet[] {\n return [...iterWorksheets(wb)];\n}\n\n/** Convenience: array of every Chartsheet in tab-strip order. */\nexport function listChartsheets(wb: Workbook): Chartsheet[] {\n return [...iterChartsheets(wb)];\n}\n\n/** Currently active sheet (worksheet only), or undefined if the active slot is empty or a chartsheet. */\nexport function getActiveSheet(wb: Workbook): Worksheet | undefined {\n const ref = wb.sheets[wb.activeSheetIndex];\n return ref?.kind === 'worksheet' ? ref.sheet : undefined;\n}\n\n/**\n * Title of whichever sheet (worksheet *or* chartsheet) is currently marked\n * active via `wb.activeSheetIndex`. Returns `undefined` for an empty workbook\n * or an out-of-range index.\n *\n * Distinct from {@link getActiveSheet} (which only returns worksheets and\n * yields `undefined` when the active slot is a chartsheet) — this matches\n * `wb.activeSheetIndex` regardless of kind.\n */\nexport function getActiveSheetTitle(wb: Workbook): string | undefined {\n return wb.sheets[wb.activeSheetIndex]?.sheet.title;\n}\n\n/**\n * True iff `title` matches the workbook's currently active sheet (any kind).\n * Empty workbook returns `false` (no active sheet).\n */\nexport function isActiveSheet(wb: Workbook, title: string): boolean {\n return getActiveSheetTitle(wb) === title;\n}\n\n/** Read-only view onto the customXml/* pass-through parts. */\nexport function listCustomXmlParts(wb: Workbook): Array<{ path: string; content: Uint8Array }> {\n if (!wb.passthrough) return [];\n const out: Array<{ path: string; content: Uint8Array }> = [];\n for (const [path, content] of wb.passthrough) {\n if (path.startsWith('customXml/')) out.push({ path, content });\n }\n return out;\n}\n\n/**\n * JSON.stringify replacer that drops the Stylesheet's internal dedup Maps. Use\n * as `JSON.stringify(workbook, jsonReplacer)` when the workbook needs to\n * round-trip through plain JSON (tests, debug dumps). The dedup maps are\n * reconstructed lazily on first add.\n */\nexport function jsonReplacer(_key: string, value: unknown): unknown {\n if (value instanceof Map) {\n return { __map__: [...value.entries()] };\n }\n return value;\n}\n\n/** Companion reviver for {@link jsonReplacer}. */\nexport function jsonReviver(_key: string, value: unknown): unknown {\n if (typeof value === 'object' && value !== null && Array.isArray((value as { __map__?: unknown[] }).__map__)) {\n return new Map((value as { __map__: Array<[unknown, unknown]> }).__map__);\n }\n return value;\n}\n"],"mappings":"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"}
|