@office-kit/xlsx 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +319 -0
- package/THIRD_PARTY_NOTICES.md +56 -0
- package/dist/cell/cell.d.ts +234 -0
- package/dist/cell/index.d.ts +4 -0
- package/dist/cell/rich-text.d.ts +37 -0
- package/dist/cell-D9CaNKnU.mjs +320 -0
- package/dist/cell-D9CaNKnU.mjs.map +1 -0
- package/dist/cell-style-BEDjMX1y.mjs +1579 -0
- package/dist/cell-style-BEDjMX1y.mjs.map +1 -0
- package/dist/cell.mjs +2 -0
- package/dist/chart/chart-xml.d.ts +16 -0
- package/dist/chart/chart.d.ts +735 -0
- package/dist/chart/cx/chartex-xml.d.ts +6 -0
- package/dist/chart/cx/chartex.d.ts +279 -0
- package/dist/chart/index.d.ts +6 -0
- package/dist/chart/user-shapes-xml.d.ts +4 -0
- package/dist/chart/user-shapes.d.ts +61 -0
- package/dist/chart.mjs +232 -0
- package/dist/chart.mjs.map +1 -0
- package/dist/chartsheet/chartsheet-xml.d.ts +17 -0
- package/dist/chartsheet/chartsheet.d.ts +121 -0
- package/dist/chartsheet/index.d.ts +2 -0
- package/dist/chartsheet-C3-tqkPy.mjs +23 -0
- package/dist/chartsheet-C3-tqkPy.mjs.map +1 -0
- package/dist/chartsheet.mjs +2 -0
- package/dist/colors-ovWAwnZI.mjs +67 -0
- package/dist/colors-ovWAwnZI.mjs.map +1 -0
- package/dist/compat/numbers.d.ts +14 -0
- package/dist/coordinate-96Ecci4d.mjs +276 -0
- package/dist/coordinate-96Ecci4d.mjs.map +1 -0
- package/dist/datetime-B2ySVlXt.mjs +71 -0
- package/dist/datetime-B2ySVlXt.mjs.map +1 -0
- package/dist/defined-names-CviWmtQg.mjs +89 -0
- package/dist/defined-names-CviWmtQg.mjs.map +1 -0
- package/dist/differential-D4dg-qtZ.mjs +37 -0
- package/dist/differential-D4dg-qtZ.mjs.map +1 -0
- package/dist/drawing/anchor.d.ts +63 -0
- package/dist/drawing/dml/colors.d.ts +109 -0
- package/dist/drawing/dml/dml-xml.d.ts +35 -0
- package/dist/drawing/dml/effect.d.ts +92 -0
- package/dist/drawing/dml/fill.d.ts +115 -0
- package/dist/drawing/dml/geometry.d.ts +113 -0
- package/dist/drawing/dml/line.d.ts +41 -0
- package/dist/drawing/dml/shape-properties.d.ts +33 -0
- package/dist/drawing/dml/text.d.ts +218 -0
- package/dist/drawing/drawing-xml.d.ts +5 -0
- package/dist/drawing/drawing.d.ts +117 -0
- package/dist/drawing/image.d.ts +40 -0
- package/dist/drawing/index.d.ts +14 -0
- package/dist/drawing-BxzLuryn.mjs +415 -0
- package/dist/drawing-BxzLuryn.mjs.map +1 -0
- package/dist/drawing.mjs +119 -0
- package/dist/drawing.mjs.map +1 -0
- package/dist/escape-DFTE7ZJc.mjs +51 -0
- package/dist/escape-DFTE7ZJc.mjs.map +1 -0
- package/dist/exceptions-D-CFwxgm.mjs +37 -0
- package/dist/exceptions-D-CFwxgm.mjs.map +1 -0
- package/dist/formula/tokenizer.d.ts +61 -0
- package/dist/formula/translate.d.ts +67 -0
- package/dist/inference-B3ES3KEJ.mjs +42 -0
- package/dist/inference-B3ES3KEJ.mjs.map +1 -0
- package/dist/io/browser.d.ts +41 -0
- package/dist/io/index.d.ts +7 -0
- package/dist/io/load.d.ts +46 -0
- package/dist/io/node-fs.d.ts +62 -0
- package/dist/io/node-save.d.ts +3 -0
- package/dist/io/node.d.ts +17 -0
- package/dist/io/save.d.ts +14 -0
- package/dist/io/sink.d.ts +54 -0
- package/dist/io/source.d.ts +14 -0
- package/dist/io.mjs +212 -0
- package/dist/io.mjs.map +1 -0
- package/dist/load-D5cbhoGx.mjs +1069 -0
- package/dist/load-D5cbhoGx.mjs.map +1 -0
- package/dist/manifest-Dps1-OpP.mjs +801 -0
- package/dist/manifest-Dps1-OpP.mjs.map +1 -0
- package/dist/node.d.ts +3 -0
- package/dist/node.mjs +308 -0
- package/dist/node.mjs.map +1 -0
- package/dist/packaging/core.d.ts +45 -0
- package/dist/packaging/custom.d.ts +62 -0
- package/dist/packaging/extended.d.ts +45 -0
- package/dist/packaging/index.d.ts +10 -0
- package/dist/packaging/manifest.d.ts +24 -0
- package/dist/packaging/relationships.d.ts +30 -0
- package/dist/packaging.mjs +2 -0
- package/dist/parser-DuLejQy1.mjs +156 -0
- package/dist/parser-DuLejQy1.mjs.map +1 -0
- package/dist/reader-D1fNW9k1.mjs +534 -0
- package/dist/reader-D1fNW9k1.mjs.map +1 -0
- package/dist/save-RohQtgEZ.mjs +745 -0
- package/dist/save-RohQtgEZ.mjs.map +1 -0
- package/dist/schema/core.d.ts +133 -0
- package/dist/schema/index.d.ts +3 -0
- package/dist/schema/serialize.d.ts +6 -0
- package/dist/schema.mjs +2 -0
- package/dist/serialize-55EnT30e.mjs +254 -0
- package/dist/serialize-55EnT30e.mjs.map +1 -0
- package/dist/serializer-BwbgHYJV.mjs +116 -0
- package/dist/serializer-BwbgHYJV.mjs.map +1 -0
- package/dist/streaming/index.d.ts +2 -0
- package/dist/streaming/read-only.d.ts +38 -0
- package/dist/streaming/write-only.d.ts +47 -0
- package/dist/streaming.mjs +612 -0
- package/dist/streaming.mjs.map +1 -0
- package/dist/styles/alignment.d.ts +33 -0
- package/dist/styles/alignment.schema.d.ts +3 -0
- package/dist/styles/borders.d.ts +40 -0
- package/dist/styles/borders.schema.d.ts +4 -0
- package/dist/styles/cell-style.d.ts +270 -0
- package/dist/styles/colors.d.ts +128 -0
- package/dist/styles/colors.schema.d.ts +3 -0
- package/dist/styles/differential.d.ts +41 -0
- package/dist/styles/fills.d.ts +54 -0
- package/dist/styles/fills.schema.d.ts +6 -0
- package/dist/styles/fonts.d.ts +44 -0
- package/dist/styles/fonts.schema.d.ts +3 -0
- package/dist/styles/index.d.ts +21 -0
- package/dist/styles/named-styles.d.ts +52 -0
- package/dist/styles/numbers.d.ts +39 -0
- package/dist/styles/numbers.schema.d.ts +3 -0
- package/dist/styles/protection.d.ts +9 -0
- package/dist/styles/protection.schema.d.ts +3 -0
- package/dist/styles/stylesheet-reader.d.ts +7 -0
- package/dist/styles/stylesheet-writer.d.ts +3 -0
- package/dist/styles/stylesheet.d.ts +95 -0
- package/dist/styles.mjs +4 -0
- package/dist/stylesheet-writer-C2eRmn22.mjs +8624 -0
- package/dist/stylesheet-writer-C2eRmn22.mjs.map +1 -0
- package/dist/table-DkX6UniA.mjs +113 -0
- package/dist/table-DkX6UniA.mjs.map +1 -0
- package/dist/tree-Bbs1C8Rc.mjs +192 -0
- package/dist/tree-Bbs1C8Rc.mjs.map +1 -0
- package/dist/units-rOMQqXh2.mjs +41 -0
- package/dist/units-rOMQqXh2.mjs.map +1 -0
- package/dist/user-shapes-DfmCGKB0.mjs +252 -0
- package/dist/user-shapes-DfmCGKB0.mjs.map +1 -0
- package/dist/utf8-D91g1XTG.mjs +143 -0
- package/dist/utf8-D91g1XTG.mjs.map +1 -0
- package/dist/utils/coordinate.d.ts +103 -0
- package/dist/utils/css.d.ts +18 -0
- package/dist/utils/datetime.d.ts +38 -0
- package/dist/utils/escape.d.ts +34 -0
- package/dist/utils/exceptions.d.ts +34 -0
- package/dist/utils/index.d.ts +11 -0
- package/dist/utils/inference.d.ts +24 -0
- package/dist/utils/stable-stringify.d.ts +7 -0
- package/dist/utils/units.d.ts +14 -0
- package/dist/utils/utf8.d.ts +1 -0
- package/dist/utils.mjs +39 -0
- package/dist/utils.mjs.map +1 -0
- package/dist/workbook/calc-properties.d.ts +47 -0
- package/dist/workbook/defined-names.d.ts +121 -0
- package/dist/workbook/file-recovery.d.ts +11 -0
- package/dist/workbook/file-sharing.d.ts +14 -0
- package/dist/workbook/file-version.d.ts +13 -0
- package/dist/workbook/function-groups.d.ts +10 -0
- package/dist/workbook/index.d.ts +24 -0
- package/dist/workbook/protection.d.ts +35 -0
- package/dist/workbook/shared-strings.d.ts +57 -0
- package/dist/workbook/smart-tags.d.ts +13 -0
- package/dist/workbook/views.d.ts +89 -0
- package/dist/workbook/workbook-properties.d.ts +57 -0
- package/dist/workbook/workbook.d.ts +643 -0
- package/dist/workbook-HGYNRBlV.mjs +636 -0
- package/dist/workbook-HGYNRBlV.mjs.map +1 -0
- package/dist/workbook.mjs +58 -0
- package/dist/workbook.mjs.map +1 -0
- package/dist/worksheet/auto-filter.d.ts +34 -0
- package/dist/worksheet/cell-range.d.ts +121 -0
- package/dist/worksheet/comments-xml.d.ts +24 -0
- package/dist/worksheet/comments.d.ts +13 -0
- package/dist/worksheet/conditional-formatting.d.ts +150 -0
- package/dist/worksheet/custom-sheet-views.d.ts +43 -0
- package/dist/worksheet/data-consolidate.d.ts +29 -0
- package/dist/worksheet/data-validations.d.ts +72 -0
- package/dist/worksheet/dimensions.d.ts +40 -0
- package/dist/worksheet/errors.d.ts +40 -0
- package/dist/worksheet/hyperlinks.d.ts +42 -0
- package/dist/worksheet/index.d.ts +46 -0
- package/dist/worksheet/ole-objects.d.ts +37 -0
- package/dist/worksheet/page-setup.d.ts +173 -0
- package/dist/worksheet/phonetic.d.ts +11 -0
- package/dist/worksheet/properties.d.ts +34 -0
- package/dist/worksheet/protected-ranges.d.ts +19 -0
- package/dist/worksheet/protection.d.ts +44 -0
- package/dist/worksheet/reader.d.ts +38 -0
- package/dist/worksheet/scenarios.d.ts +36 -0
- package/dist/worksheet/smart-tags.d.ts +23 -0
- package/dist/worksheet/sort-state.d.ts +28 -0
- package/dist/worksheet/table-xml.d.ts +5 -0
- package/dist/worksheet/table.d.ts +80 -0
- package/dist/worksheet/views.d.ts +47 -0
- package/dist/worksheet/web-publish.d.ts +21 -0
- package/dist/worksheet/worksheet.d.ts +935 -0
- package/dist/worksheet/writer.d.ts +72 -0
- package/dist/worksheet-CmCNoIgD.mjs +1726 -0
- package/dist/worksheet-CmCNoIgD.mjs.map +1 -0
- package/dist/worksheet.mjs +247 -0
- package/dist/worksheet.mjs.map +1 -0
- package/dist/writer-DspzfkNA.mjs +221 -0
- package/dist/writer-DspzfkNA.mjs.map +1 -0
- package/dist/xml/index.d.ts +10 -0
- package/dist/xml/iterparse.d.ts +22 -0
- package/dist/xml/namespaces.d.ts +91 -0
- package/dist/xml/parser.d.ts +7 -0
- package/dist/xml/serializer.d.ts +14 -0
- package/dist/xml/stream-writer.d.ts +39 -0
- package/dist/xml/tree.d.ts +37 -0
- package/dist/xml.mjs +140 -0
- package/dist/xml.mjs.map +1 -0
- package/dist/zip/decompression-guard.d.ts +70 -0
- package/dist/zip/index.d.ts +6 -0
- package/dist/zip/random-access-reader.d.ts +16 -0
- package/dist/zip/reader.d.ts +45 -0
- package/dist/zip/writer.d.ts +65 -0
- package/dist/zip/zip64-patch.d.ts +12 -0
- package/dist/zip.mjs +3 -0
- package/package.json +147 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worksheet-CmCNoIgD.mjs","names":[],"sources":["../src/worksheet/cell-range.ts","../src/styles/colors.ts","../src/worksheet/dimensions.ts","../src/worksheet/hyperlinks.ts","../src/worksheet/views.ts","../src/worksheet/comments.ts","../src/worksheet/properties.ts","../src/worksheet/worksheet.ts"],"sourcesContent":["// Cell-range value object + set operations.\n//\n// The struct is the same `CellRangeBoundaries` we already use across the\n// coordinate parser; this module adds the worksheet-level operations\n// (containment, shift, union, intersection, iteration) and a `MultiCellRange`\n// lite wrapper for sqref-style attributes.\n\nimport type { Cell } from '../cell/cell';\nimport {\n boundariesToRangeString,\n type CellRangeBoundaries,\n coordinateToTuple,\n MAX_COL,\n MAX_ROW,\n rangeBoundaries,\n tupleToCoordinate,\n} from '../utils/coordinate';\nimport { OpenXmlSchemaError } from '../utils/exceptions';\n\n/** Re-export under the plan's canonical name. */\nexport type CellRange = CellRangeBoundaries;\n\n/** Build a CellRange from explicit 1-based bounds. */\nexport function makeCellRange(minRow: number, minCol: number, maxRow: number, maxCol: number): CellRange {\n if (\n !Number.isInteger(minRow) ||\n !Number.isInteger(minCol) ||\n !Number.isInteger(maxRow) ||\n !Number.isInteger(maxCol)\n ) {\n throw new OpenXmlSchemaError('CellRange bounds must be integers');\n }\n if (minRow < 1 || maxRow < 1 || minRow > MAX_ROW || maxRow > MAX_ROW) {\n throw new OpenXmlSchemaError(`CellRange row bounds must be in [1, ${MAX_ROW}]`);\n }\n if (minCol < 1 || maxCol < 1 || minCol > MAX_COL || maxCol > MAX_COL) {\n throw new OpenXmlSchemaError(`CellRange col bounds must be in [1, ${MAX_COL}]`);\n }\n return {\n minRow: Math.min(minRow, maxRow),\n minCol: Math.min(minCol, maxCol),\n maxRow: Math.max(minRow, maxRow),\n maxCol: Math.max(minCol, maxCol),\n };\n}\n\n/** Parse a range expression — wraps {@link rangeBoundaries}. */\nexport function parseRange(input: string): CellRange {\n return rangeBoundaries(input);\n}\n\n/** Format a CellRange back into the canonical OOXML string. */\nexport function rangeToString(r: CellRange): string {\n return boundariesToRangeString(r);\n}\n\n/**\n * Compute the bounding A1-style range string for a list of cells. Walks the\n * input once to find min/max row+col. A single-cell input returns a single-cell\n * ref (`\"A1\"`); two or more cells (even collinear) return the `\"A1:B5\"` form.\n *\n * Throws when the array is empty — there's no meaningful zero-cell range, and\n * silently returning `\"\"` would defeat downstream `parseRange` consumers.\n */\nexport function cellRangeFromCells(cells: ReadonlyArray<Pick<Cell, 'row' | 'col'>>): string {\n if (cells.length === 0) {\n throw new OpenXmlSchemaError('cellRangeFromCells: cells array must be non-empty');\n }\n let minRow = Number.POSITIVE_INFINITY;\n let maxRow = Number.NEGATIVE_INFINITY;\n let minCol = Number.POSITIVE_INFINITY;\n let maxCol = Number.NEGATIVE_INFINITY;\n for (const c of cells) {\n if (c.row < minRow) minRow = c.row;\n if (c.row > maxRow) maxRow = c.row;\n if (c.col < minCol) minCol = c.col;\n if (c.col > maxCol) maxCol = c.col;\n }\n if (minRow === maxRow && minCol === maxCol) {\n return tupleToCoordinate(minCol, minRow);\n }\n return boundariesToRangeString({ minRow, minCol, maxRow, maxCol });\n}\n\n/** Inclusive containment of a single (row, col) within a range. */\nexport function rangeContainsCell(r: CellRange, row: number, col: number): boolean {\n return row >= r.minRow && row <= r.maxRow && col >= r.minCol && col <= r.maxCol;\n}\n\n/**\n * A1-string convenience for {@link rangeContainsCell}. Parses `cellRef` (e.g.\n * `\"B3\"`) and `rangeRef` (e.g. `\"A1:C5\"`) and returns `true` iff the cell sits\n * inside the range (boundary-inclusive). Throws when either input is malformed.\n */\nexport function isCellInRange(cellRef: string, rangeRef: string): boolean {\n const { col, row } = coordinateToTuple(cellRef);\n return rangeContainsCell(parseRange(rangeRef), row, col);\n}\n\n/**\n * A1-string convenience for {@link rangeContainsRange}. Returns `true` iff the\n * `inner` range is wholly contained by `outer` (boundary-inclusive).\n * Single-cell refs are accepted on either side via parseRange. Throws on\n * malformed input.\n */\nexport function isRangeInRange(inner: string, outer: string): boolean {\n return rangeContainsRange(parseRange(outer), parseRange(inner));\n}\n\n/**\n * A1-string convenience for {@link rangesOverlap}. Returns `true` iff the two\n * ranges share at least one cell. Boundary-inclusive (a 1-row gap = no\n * overlap). Single-cell refs are accepted via parseRange. Throws on malformed\n * input.\n */\nexport function rangesOverlapStr(a: string, b: string): boolean {\n return rangesOverlap(parseRange(a), parseRange(b));\n}\n\n/**\n * A1-string convenience for {@link unionRange}. Returns the smallest A1 range\n * that contains both inputs (always non-null; ranges that don't overlap still\n * get a valid bounding box).\n */\nexport function unionRangeStr(a: string, b: string): string {\n return rangeToString(unionRange(parseRange(a), parseRange(b)));\n}\n\n/**\n * A1-string convenience for {@link intersectionRange}. Returns the shared\n * rectangular sub-range as A1 string, or `undefined` when the inputs are\n * disjoint.\n */\nexport function intersectionRangeStr(a: string, b: string): string | undefined {\n const r = intersectionRange(parseRange(a), parseRange(b));\n return r === null ? undefined : rangeToString(r);\n}\n\n/**\n * A1-string convenience for {@link shiftRange}. Translates the range by `(dr,\n * dc)` integer offsets and re-serialises. Negative offsets shift up/left.\n * Throws when the resulting bounds fall outside the OOXML grid (rows\n * 1..1048576, cols 1..16384).\n */\nexport function shiftRangeStr(range: string, dr: number, dc: number): string {\n return rangeToString(shiftRange(parseRange(range), dr, dc));\n}\n\n/**\n * A1-string convenience for {@link rangeArea}. Returns the inclusive cell count\n * covered by the range (rows × cols). Single-cell refs return 1.\n */\nexport function rangeAreaStr(range: string): number {\n return rangeArea(parseRange(range));\n}\n\n/**\n * A1-string range dimensions: how many rows and columns the range spans\n * (inclusive). Distinct from {@link rangeAreaStr} which returns the product.\n * Single-cell refs return `{ rows: 1, cols: 1 }`.\n */\nexport function rangeDimensionsStr(range: string): { rows: number; cols: number } {\n const r = parseRange(range);\n return { rows: r.maxRow - r.minRow + 1, cols: r.maxCol - r.minCol + 1 };\n}\n\n/**\n * Expand (or shrink) an A1 range by adding `deltaRows` to its bottom edge and\n * `deltaCols` to its right edge. The top-left corner is preserved. Negative\n * deltas shrink the range; the result must still have at least 1 row and 1\n * column (otherwise throws).\n *\n * Useful for \"this is the data range — also reserve room for a totals row\" or\n * \"include one more column to the right\" patterns.\n */\nexport function expandRangeStr(range: string, deltaRows: number, deltaCols: number): string {\n if (!Number.isInteger(deltaRows) || !Number.isInteger(deltaCols)) {\n throw new OpenXmlSchemaError('expandRangeStr: deltas must be integers');\n }\n const r = parseRange(range);\n return rangeToString(makeCellRange(r.minRow, r.minCol, r.maxRow + deltaRows, r.maxCol + deltaCols));\n}\n\n/** Inclusive containment of `inner` within `outer`. */\nexport function rangeContainsRange(outer: CellRange, inner: CellRange): boolean {\n return (\n inner.minRow >= outer.minRow &&\n inner.maxRow <= outer.maxRow &&\n inner.minCol >= outer.minCol &&\n inner.maxCol <= outer.maxCol\n );\n}\n\n/**\n * Shift a range by (dr, dc) integer offsets. The returned range is clamped to\n * the OOXML grid; callers that want hard bounds should pass values that keep\n * the result inside the spec.\n */\nexport function shiftRange(r: CellRange, dr: number, dc: number): CellRange {\n if (!Number.isInteger(dr) || !Number.isInteger(dc)) {\n throw new OpenXmlSchemaError('shiftRange: dr / dc must be integers');\n }\n return makeCellRange(r.minRow + dr, r.minCol + dc, r.maxRow + dr, r.maxCol + dc);\n}\n\n/** Bounding-box union of two ranges. Always non-null. */\nexport function unionRange(a: CellRange, b: CellRange): CellRange {\n return {\n minRow: Math.min(a.minRow, b.minRow),\n minCol: Math.min(a.minCol, b.minCol),\n maxRow: Math.max(a.maxRow, b.maxRow),\n maxCol: Math.max(a.maxCol, b.maxCol),\n };\n}\n\n/** Returns the rectangular intersection of two ranges, or `null` when disjoint. */\nexport function intersectionRange(a: CellRange, b: CellRange): CellRange | null {\n const minRow = Math.max(a.minRow, b.minRow);\n const minCol = Math.max(a.minCol, b.minCol);\n const maxRow = Math.min(a.maxRow, b.maxRow);\n const maxCol = Math.min(a.maxCol, b.maxCol);\n if (minRow > maxRow || minCol > maxCol) return null;\n return { minRow, minCol, maxRow, maxCol };\n}\n\n/** True iff two ranges share at least one cell. */\nexport function rangesOverlap(a: CellRange, b: CellRange): boolean {\n return intersectionRange(a, b) !== null;\n}\n\n/** Inclusive cell count covered by a range. */\nexport function rangeArea(r: CellRange): number {\n return (r.maxRow - r.minRow + 1) * (r.maxCol - r.minCol + 1);\n}\n\n/** Yield every (row, col) coordinate in the range, row-major. */\nexport function* iterRangeCoordinates(r: CellRange): IterableIterator<{ row: number; col: number }> {\n for (let row = r.minRow; row <= r.maxRow; row++) {\n for (let col = r.minCol; col <= r.maxCol; col++) {\n yield { row, col };\n }\n }\n}\n\n// ---- MultiCellRange --------------------------------------------------------\n\n/**\n * Excel's `sqref` attribute: a space-separated list of CellRanges. Used by data\n * validations, conditional formatting, hyperlinks etc.\n */\nexport interface MultiCellRange {\n ranges: CellRange[];\n}\n\nexport function makeMultiCellRange(ranges: ReadonlyArray<CellRange> = []): MultiCellRange {\n return { ranges: ranges.slice() };\n}\n\n/** Parse an sqref string: `\"A1:B2 D5 E10:F20\"`. Whitespace-delimited. */\nexport function parseMultiCellRange(input: string): MultiCellRange {\n const ranges: CellRange[] = [];\n for (const piece of input.split(/\\s+/)) {\n if (piece.length === 0) continue;\n ranges.push(parseRange(piece));\n }\n return { ranges };\n}\n\n/** Format a MultiCellRange back into an sqref string. */\nexport function multiCellRangeToString(m: MultiCellRange): string {\n return m.ranges.map(rangeToString).join(' ');\n}\n\n/** Total cell count across all ranges (no de-duplication of overlaps). */\nexport function multiCellRangeArea(m: MultiCellRange): number {\n let n = 0;\n for (const r of m.ranges) n += rangeArea(r);\n return n;\n}\n\n/** True iff any contained range covers (row, col). */\nexport function multiCellRangeContainsCell(m: MultiCellRange, row: number, col: number): boolean {\n for (const r of m.ranges) if (rangeContainsCell(r, row, col)) return true;\n return false;\n}\n","// Color value object. Mirrors openpyxl/openpyxl/styles/colors.py.\n//\n// Excel exposes four mutually-exclusive ways to specify a colour:\n// * rgb — explicit aRGB hex (\"AARRGGBB\"); 6-hex inputs auto-pad to 00..\n// * indexed — 0-63 index into the legacy COLOR_INDEX palette (plus 64/65\n// reserved for the system fg/bg).\n// * theme — 0-N index into the workbook's theme colour scheme.\n// * auto — boolean \"use system default\".\n//\n// These are plain readonly objects; `makeColor` freezes its result so the\n// Stylesheet pool can dedupe by reference equality.\n\nimport { OpenXmlSchemaError } from '../utils/exceptions';\n\n/**\n * Colour reference. All fields are optional but Excel expects exactly one of\n * {rgb, indexed, theme, auto} to be set; if none is, the cell inherits the\n * parent style's colour.\n *\n * `tint` modulates the resolved colour; -1 = full black, +1 = full white.\n */\nexport interface Color {\n /** \"AARRGGBB\" hex (uppercase). 6-hex inputs are auto-padded with `00` alpha. */\n readonly rgb?: string;\n /** 0..63 → COLOR_INDEX entry. 64 = system foreground, 65 = system background. */\n readonly indexed?: number;\n /** Theme colour index. */\n readonly theme?: number;\n /** \"Auto\" / system default. */\n readonly auto?: boolean;\n /** Lightness modulation in [-1, 1]. */\n readonly tint?: number;\n}\n\n/**\n * Legacy 64-entry palette indexed colours fall back to. Verbatim from\n * openpyxl/openpyxl/styles/colors.py — must not be reordered.\n */\nexport const COLOR_INDEX: readonly string[] = Object.freeze([\n '00000000',\n '00FFFFFF',\n '00FF0000',\n '0000FF00',\n '000000FF', // 0-4\n '00FFFF00',\n '00FF00FF',\n '0000FFFF',\n '00000000',\n '00FFFFFF', // 5-9\n '00FF0000',\n '0000FF00',\n '000000FF',\n '00FFFF00',\n '00FF00FF', // 10-14\n '0000FFFF',\n '00800000',\n '00008000',\n '00000080',\n '00808000', // 15-19\n '00800080',\n '00008080',\n '00C0C0C0',\n '00808080',\n '009999FF', // 20-24\n '00993366',\n '00FFFFCC',\n '00CCFFFF',\n '00660066',\n '00FF8080', // 25-29\n '000066CC',\n '00CCCCFF',\n '00000080',\n '00FF00FF',\n '00FFFF00', // 30-34\n '0000FFFF',\n '00800080',\n '00800000',\n '00008080',\n '000000FF', // 35-39\n '0000CCFF',\n '00CCFFFF',\n '00CCFFCC',\n '00FFFF99',\n '0099CCFF', // 40-44\n '00FF99CC',\n '00CC99FF',\n '00FFCC99',\n '003366FF',\n '0033CCCC', // 45-49\n '0099CC00',\n '00FFCC00',\n '00FF9900',\n '00FF6600',\n '00666699', // 50-54\n '00969696',\n '00003366',\n '00339966',\n '00003300',\n '00333300', // 55-59\n '00993300',\n '00993366',\n '00333399',\n '00333333', // 60-63\n]);\n\n/**\n * Convenience constants — match openpyxl's exports. Inlined rather than indexed\n * off COLOR_INDEX to keep the type system from widening to `string | undefined`\n * on tuple lookup.\n */\nexport const BLACK = '00000000';\nexport const WHITE = '00FFFFFF';\nexport const BLUE = '000000FF';\n\nconst ARGB_RE = /^([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6})$/;\n\n/**\n * Normalise an aRGB hex string. Accepts either 6 or 8 hex digits; 6-digit input\n * is padded to 8 by prefixing `00` (alpha=0 = fully opaque per Excel\n * convention). Returns the canonical uppercase form.\n */\nexport function normaliseRgb(value: string): string {\n if (typeof value !== 'string' || !ARGB_RE.test(value)) {\n throw new OpenXmlSchemaError(`Color rgb must be 6 or 8 hex digits; got \"${value}\"`);\n }\n return (value.length === 6 ? `00${value}` : value).toUpperCase();\n}\n\n/**\n * Build an immutable {@link Color}. Validates ranges (indexed in [0, 65], tint\n * in [-1, 1]) and normalises rgb hex.\n */\nexport function makeColor(opts: Partial<Color> = {}): Color {\n const out: Mutable<Color> = {};\n if (opts.rgb !== undefined) out.rgb = normaliseRgb(opts.rgb);\n if (opts.indexed !== undefined) {\n if (!Number.isInteger(opts.indexed) || opts.indexed < 0 || opts.indexed > 65) {\n throw new OpenXmlSchemaError(`Color indexed must be in [0, 65]; got ${opts.indexed}`);\n }\n out.indexed = opts.indexed;\n }\n if (opts.theme !== undefined) {\n if (!Number.isInteger(opts.theme) || opts.theme < 0) {\n throw new OpenXmlSchemaError(`Color theme must be a non-negative integer; got ${opts.theme}`);\n }\n out.theme = opts.theme;\n }\n if (opts.auto !== undefined) out.auto = opts.auto;\n if (opts.tint !== undefined) {\n if (!Number.isFinite(opts.tint) || opts.tint < -1 || opts.tint > 1) {\n throw new OpenXmlSchemaError(`Color tint must be in [-1, 1]; got ${opts.tint}`);\n }\n out.tint = opts.tint;\n }\n return Object.freeze(out);\n}\n\n/**\n * Resolve `indexed` references against {@link COLOR_INDEX}. Returns undefined\n * for 64/65 (system fg/bg, not in the palette) or out-of-range.\n */\nexport function resolveIndexedColor(idx: number): string | undefined {\n return COLOR_INDEX[idx];\n}\n\n/** Shortcut for the common opaque solid colour. */\nexport function rgbColor(hex: string): Color {\n return makeColor({ rgb: hex });\n}\n\n/**\n * Read a {@link Color} value-object back to a normalised ARGB hex. Resolution\n * order: explicit `rgb` → `indexed` palette lookup. Returns `undefined` for\n * `theme` / `auto` / empty inputs (unresolvable without a theme), so callers\n * can fall back to a default.\n */\nexport function colorToHex(color: Color | undefined): string | undefined {\n if (!color) return undefined;\n if (color.rgb !== undefined) return normaliseRgb(color.rgb);\n if (color.indexed !== undefined) {\n const rgb = resolveIndexedColor(color.indexed);\n if (rgb) return rgb.toUpperCase();\n }\n return undefined;\n}\n\n/**\n * Compute the relative luminance of an ARGB / RGB hex string per the WCAG 2.x\n * formula. Returns a value in `[0, 1]` where 0 is black and 1 is white. The\n * alpha channel (if present) is ignored.\n */\nexport function luminance(hex: string): number {\n const rgb = normaliseRgb(hex); // 8-char AARRGGBB upper-case\n const r = Number.parseInt(rgb.slice(2, 4), 16) / 255;\n const g = Number.parseInt(rgb.slice(4, 6), 16) / 255;\n const b = Number.parseInt(rgb.slice(6, 8), 16) / 255;\n const lin = (c: number): number => (c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4);\n return 0.2126 * lin(r) + 0.7152 * lin(g) + 0.0722 * lin(b);\n}\n\n/**\n * WCAG contrast ratio between two ARGB hex colors. Returns a value in `[1,\n * 21]`; 1 = identical luminance, 21 = pure black on pure white. The order of\n * arguments doesn't matter.\n */\nexport function contrastRatio(hexA: string, hexB: string): number {\n const lA = luminance(hexA);\n const lB = luminance(hexB);\n const [hi, lo] = lA >= lB ? [lA, lB] : [lB, lA];\n return (hi + 0.05) / (lo + 0.05);\n}\n\n/**\n * Pick the higher-contrast text color (`'FF000000'` black or `'FFFFFFFF'`\n * white) for a background hex. Useful when applying a solid fill and wanting\n * the cell text to stay readable.\n */\nexport function pickReadableTextColor(backgroundHex: string): 'FF000000' | 'FFFFFFFF' {\n // WCAG midpoint of 0.179 splits \"near-black bg → white text\" from \"lighter bg\n // → black text\".\n return luminance(backgroundHex) < 0.179 ? 'FFFFFFFF' : 'FF000000';\n}\n\nconst splitArgb = (hex: string): { a: number; r: number; g: number; b: number } => {\n const rgb = normaliseRgb(hex);\n return {\n a: Number.parseInt(rgb.slice(0, 2), 16),\n r: Number.parseInt(rgb.slice(2, 4), 16),\n g: Number.parseInt(rgb.slice(4, 6), 16),\n b: Number.parseInt(rgb.slice(6, 8), 16),\n };\n};\n\nconst toHexByte = (n: number): string => {\n const v = Math.max(0, Math.min(255, Math.round(n)));\n return v.toString(16).padStart(2, '0').toUpperCase();\n};\n\nconst clampUnit = (x: number): number => Math.max(0, Math.min(1, x));\n\n/**\n * Lighten a color by mixing it with white. `amount` is in `[0, 1]`: 0 returns\n * the input unchanged, 1 returns pure white. Alpha channel is preserved.\n * Equivalent to `mixColors(hex, 'FFFFFFFF', amount)`.\n */\nexport function lighten(hex: string, amount: number): string {\n const t = clampUnit(amount);\n const { a, r, g, b } = splitArgb(hex);\n return `${toHexByte(a)}${toHexByte(r + (255 - r) * t)}${toHexByte(g + (255 - g) * t)}${toHexByte(b + (255 - b) * t)}`;\n}\n\n/**\n * Darken a color by mixing it with black. `amount` is in `[0, 1]`: 0 returns\n * the input unchanged, 1 returns pure black (preserving the alpha channel).\n */\nexport function darken(hex: string, amount: number): string {\n const t = clampUnit(amount);\n const { a, r, g, b } = splitArgb(hex);\n return `${toHexByte(a)}${toHexByte(r * (1 - t))}${toHexByte(g * (1 - t))}${toHexByte(b * (1 - t))}`;\n}\n\n/**\n * Linearly interpolate between two ARGB colors. `t = 0` returns `hexA`; `t = 1`\n * returns `hexB`; intermediate values mix per channel (including alpha).\n */\nexport function mixColors(hexA: string, hexB: string, t: number): string {\n const k = clampUnit(t);\n const a = splitArgb(hexA);\n const b = splitArgb(hexB);\n return `${toHexByte(a.a + (b.a - a.a) * k)}${toHexByte(a.r + (b.r - a.r) * k)}${toHexByte(a.g + (b.g - a.g) * k)}${toHexByte(a.b + (b.b - a.b) * k)}`;\n}\n\n/**\n * Convert an ARGB / RGB hex to its HSL representation. Returns `{ h, s, l, a }`\n * with `h ∈ [0, 360)`, `s ∈ [0, 1]`, `l ∈ [0, 1]`, `a ∈ [0, 255]` (alpha as the\n * original byte). Useful for theme tweaking (rotate hue, desaturate, etc.)\n * before round-tripping through {@link hslToHex}.\n */\nexport function hexToHsl(hex: string): { h: number; s: number; l: number; a: number } {\n const { a, r: rb, g: gb, b: bb } = splitArgb(hex);\n const r = rb / 255;\n const g = gb / 255;\n const b = bb / 255;\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const l = (max + min) / 2;\n let h = 0;\n let s = 0;\n if (max !== min) {\n const d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n if (max === r) h = ((g - b) / d + (g < b ? 6 : 0)) * 60;\n else if (max === g) h = ((b - r) / d + 2) * 60;\n else h = ((r - g) / d + 4) * 60;\n }\n return { h, s, l, a };\n}\n\n/**\n * Rotate the hue of a color by `degrees` (positive = clockwise). Saturation and\n * lightness are preserved; alpha is preserved. Equivalent to `hexToHsl` →\n * adjust `h` → `hslToHex`.\n */\nexport function rotateHue(hex: string, degrees: number): string {\n const { h, s, l, a } = hexToHsl(hex);\n return hslToHex(h + degrees, s, l, a);\n}\n\n/**\n * Adjust the saturation of a color by `delta` (added directly to the `[0, 1]`\n * saturation channel and clamped). Positive = more vivid, negative = closer to\n * gray. Hue, lightness, and alpha are preserved.\n */\nexport function adjustSaturation(hex: string, delta: number): string {\n const { h, s, l, a } = hexToHsl(hex);\n return hslToHex(h, s + delta, l, a);\n}\n\n/**\n * Adjust the lightness of a color by `delta` (added directly to the `[0, 1]`\n * lightness channel and clamped). Positive = lighter, negative = darker.\n * Distinct from {@link lighten} / {@link darken} which mix toward white/black\n * in RGB space.\n */\nexport function adjustLightness(hex: string, delta: number): string {\n const { h, s, l, a } = hexToHsl(hex);\n return hslToHex(h, s, l + delta, a);\n}\n\n/**\n * Convert HSL components back to an ARGB hex string. `h` wraps mod-360, `s` and\n * `l` clamp to `[0, 1]`. `alpha` is the byte (default 255 = opaque), placed in\n * the high byte of the result.\n */\nexport function hslToHex(h: number, s: number, l: number, alpha = 255): string {\n const hh = ((h % 360) + 360) % 360;\n const ss = clampUnit(s);\n const ll = clampUnit(l);\n const c = (1 - Math.abs(2 * ll - 1)) * ss;\n const x = c * (1 - Math.abs(((hh / 60) % 2) - 1));\n const m = ll - c / 2;\n let rp = 0;\n let gp = 0;\n let bp = 0;\n if (hh < 60) {\n rp = c;\n gp = x;\n } else if (hh < 120) {\n rp = x;\n gp = c;\n } else if (hh < 180) {\n gp = c;\n bp = x;\n } else if (hh < 240) {\n gp = x;\n bp = c;\n } else if (hh < 300) {\n rp = x;\n bp = c;\n } else {\n rp = c;\n bp = x;\n }\n const a = Math.max(0, Math.min(255, Math.round(alpha)));\n return `${toHexByte(a)}${toHexByte((rp + m) * 255)}${toHexByte((gp + m) * 255)}${toHexByte((bp + m) * 255)}`;\n}\n\n// Internal mutable mirror used inside `make*` constructors. Never leaks.\ntype Mutable<T> = { -readonly [P in keyof T]: T[P] };\n","// Column / row dimension metadata. (`columnDimensions` / `rowDimensions` Maps +\n// `defaultColumnWidth` / `defaultRowHeight`) and the openpyxl reference at\n// `worksheet/dimensions.py`.\n//\n// **Stage 1**: width / height / hidden / customWidth / customHeight / bestFit /\n// outlineLevel + style fall-back. Multi-`<col>` runs collapse per-column\n// entries when adjacent equal entries are persisted (writer side) — read keeps\n// each column its own entry so user mutations don't surprise neighbours.\n\n/**\n * Single-column-or-range dimension entry. Mirrors the OOXML `<col>` element.\n * The `min`/`max` pair always covers a contiguous run; the worksheet's\n * `columnDimensions` Map keys by `min` so per-column edits stay O(log n).\n */\nexport interface ColumnDimension {\n /** 1-based first column the entry covers (inclusive). */\n min: number;\n /** 1-based last column the entry covers (inclusive). */\n max: number;\n /** Width in Excel character units. */\n width?: number;\n /** Excel records `customWidth=1` whenever the user touched the slider. */\n customWidth?: boolean;\n /** Hidden columns get `hidden=\"1\"`. */\n hidden?: boolean;\n /** \"Best fit\" auto-shrink semantics — Excel sets it for narrow columns. */\n bestFit?: boolean;\n /** Outline-level for grouping (0 = ungrouped). */\n outlineLevel?: number;\n /** Default cell xfId applied to empty cells in the column. */\n style?: number;\n /** Whether the column's outline is collapsed. */\n collapsed?: boolean;\n}\n\n/** Per-row metadata. Mirrors the OOXML `<row>` element's attributes. */\nexport interface RowDimension {\n /** Row height in points. */\n height?: number;\n /** Mirrors Excel's `customHeight=\"1\"` flag. */\n customHeight?: boolean;\n hidden?: boolean;\n outlineLevel?: number;\n collapsed?: boolean;\n /** Default cell xfId applied to empty cells in the row. */\n style?: number;\n}\n\n/** Build a single-column ColumnDimension entry covering `col`. */\nexport function makeColumnDimension(\n col: number,\n opts: Partial<Omit<ColumnDimension, 'min' | 'max'>> = {},\n): ColumnDimension {\n return {\n min: col,\n max: col,\n ...(opts.width !== undefined ? { width: opts.width } : {}),\n ...(opts.customWidth !== undefined ? { customWidth: opts.customWidth } : {}),\n ...(opts.hidden !== undefined ? { hidden: opts.hidden } : {}),\n ...(opts.bestFit !== undefined ? { bestFit: opts.bestFit } : {}),\n ...(opts.outlineLevel !== undefined ? { outlineLevel: opts.outlineLevel } : {}),\n ...(opts.style !== undefined ? { style: opts.style } : {}),\n ...(opts.collapsed !== undefined ? { collapsed: opts.collapsed } : {}),\n };\n}\n\nexport function makeRowDimension(opts: Partial<RowDimension> = {}): RowDimension {\n return {\n ...(opts.height !== undefined ? { height: opts.height } : {}),\n ...(opts.customHeight !== undefined ? { customHeight: opts.customHeight } : {}),\n ...(opts.hidden !== undefined ? { hidden: opts.hidden } : {}),\n ...(opts.outlineLevel !== undefined ? { outlineLevel: opts.outlineLevel } : {}),\n ...(opts.collapsed !== undefined ? { collapsed: opts.collapsed } : {}),\n ...(opts.style !== undefined ? { style: opts.style } : {}),\n };\n}\n","// Worksheet hyperlinks.\n//\n// External URLs land in `xl/worksheets/_rels/sheetN.xml.rels` (one rel per\n// Hyperlink entry, type \"...relationships/hyperlink\", TargetMode=\"External\").\n// Internal jumps (`#'Sheet 2'!A1`) live entirely in the `<hyperlink\n// location=\"...\"/>` attribute and don't need a rel.\n\nimport { OpenXmlSchemaError } from '../utils/exceptions';\n\nexport interface Hyperlink {\n /** Cell or range the hyperlink covers — \"A1\" or \"A1:B5\". */\n ref: string;\n /** External URL or relative target path. Mutually exclusive with `location`-only links. */\n target?: string;\n /** Anchor inside the workbook (e.g. `'Sheet 2'!A1`). */\n location?: string;\n /** Tooltip shown on hover. */\n tooltip?: string;\n /** Visible link text — typically falls back to the referenced cell value. */\n display?: string;\n /** Worksheet-rels rId. Populated on read; assigned by the writer when missing. */\n rId?: string;\n}\n\nexport function makeHyperlink(opts: Partial<Hyperlink> & { ref: string }): Hyperlink {\n if (opts.ref === undefined || opts.ref.length === 0) {\n throw new OpenXmlSchemaError('Hyperlink: ref is required');\n }\n return {\n ref: opts.ref,\n ...(opts.target !== undefined ? { target: opts.target } : {}),\n ...(opts.location !== undefined ? { location: opts.location } : {}),\n ...(opts.tooltip !== undefined ? { tooltip: opts.tooltip } : {}),\n ...(opts.display !== undefined ? { display: opts.display } : {}),\n ...(opts.rId !== undefined ? { rId: opts.rId } : {}),\n };\n}\n\n// ---- Worksheet ergonomic helpers ----------------------------------------\n\nimport type { Worksheet } from './worksheet';\n\nconst replaceHyperlink = (ws: Worksheet, hl: Hyperlink): Hyperlink => {\n const idx = ws.hyperlinks.findIndex((h) => h.ref === hl.ref);\n if (idx >= 0) ws.hyperlinks[idx] = hl;\n else ws.hyperlinks.push(hl);\n return hl;\n};\n\n/**\n * Add an external URL hyperlink to a cell or range. The URL goes into the\n * worksheet rels as a hyperlink relationship; the writer generates an rId on\n * save.\n */\nexport const addUrlHyperlink = (\n ws: Worksheet,\n ref: string,\n url: string,\n opts: { tooltip?: string; display?: string } = {},\n): Hyperlink => {\n return replaceHyperlink(\n ws,\n makeHyperlink({\n ref,\n target: url,\n ...(opts.tooltip !== undefined ? { tooltip: opts.tooltip } : {}),\n ...(opts.display !== undefined ? { display: opts.display } : {}),\n }),\n );\n};\n\n/**\n * Add an in-workbook jump hyperlink (e.g. to `'Sheet2'!A1` or a defined-name).\n * No rels entry is written — the location is inline in the `<hyperlink\n * location=\"…\"/>` attribute.\n */\nexport const addInternalHyperlink = (\n ws: Worksheet,\n ref: string,\n location: string,\n opts: { tooltip?: string; display?: string } = {},\n): Hyperlink => {\n return replaceHyperlink(\n ws,\n makeHyperlink({\n ref,\n location,\n ...(opts.tooltip !== undefined ? { tooltip: opts.tooltip } : {}),\n ...(opts.display !== undefined ? { display: opts.display } : {}),\n }),\n );\n};\n\n/** `mailto:` shortcut. */\nexport const addMailtoHyperlink = (\n ws: Worksheet,\n ref: string,\n email: string,\n opts: { subject?: string; tooltip?: string; display?: string } = {},\n): Hyperlink => {\n const url = opts.subject\n ? `mailto:${email}?subject=${encodeURIComponent(opts.subject)}`\n : `mailto:${email}`;\n return addUrlHyperlink(ws, ref, url, {\n ...(opts.tooltip !== undefined ? { tooltip: opts.tooltip } : {}),\n ...(opts.display !== undefined ? { display: opts.display } : {}),\n });\n};\n","// SheetView / Pane / Selection. (`Worksheet.views`) + the openpyxl reference at\n// `worksheet/views.py`.\n//\n// **Stage 1**: SheetView with the most-used field subset (tabSelected, view,\n// workbookViewId, showGridLines, zoomScale, topLeftCell, pane, selection).\n// Reader / writer cover the round-trip; `setFreezePanes` builds the pane from\n// an \"A1\"-style top-left ref. Per-pane multi-selection blocks aren't widespread\n// in real-world fixtures, so stage-1 stores a single Selection.\n\nimport { coordinateToTuple, tupleToCoordinate } from '../utils/coordinate';\nimport { OpenXmlSchemaError } from '../utils/exceptions';\n\nexport type PaneType = 'bottomRight' | 'topRight' | 'bottomLeft' | 'topLeft';\nexport type PaneState = 'split' | 'frozen' | 'frozenSplit';\nexport type SheetViewMode = 'normal' | 'pageBreakPreview' | 'pageLayout';\n\nexport interface Pane {\n /** Column-axis split. Number of columns frozen on the left. */\n xSplit?: number;\n /** Row-axis split. Number of rows frozen on top. */\n ySplit?: number;\n /** First visible cell of the bottom-right pane. */\n topLeftCell?: string;\n /** Which pane is active when the sheet is opened. Defaults to `bottomRight` for full freezes. */\n activePane?: PaneType;\n state: PaneState;\n}\n\nexport interface Selection {\n pane?: PaneType;\n activeCell?: string;\n sqref?: string;\n}\n\nexport interface SheetView {\n /** Index into the parent workbook's bookViews list. Defaults to 0. */\n workbookViewId: number;\n tabSelected?: boolean;\n showGridLines?: boolean;\n showRowColHeaders?: boolean;\n showFormulas?: boolean;\n showZeros?: boolean;\n rightToLeft?: boolean;\n view?: SheetViewMode;\n topLeftCell?: string;\n zoomScale?: number;\n zoomScaleNormal?: number;\n pane?: Pane;\n selection?: Selection;\n}\n\n/** Build a SheetView with sensible defaults. */\nexport function makeSheetView(opts: Partial<SheetView> = {}): SheetView {\n return {\n workbookViewId: opts.workbookViewId ?? 0,\n ...(opts.tabSelected !== undefined ? { tabSelected: opts.tabSelected } : {}),\n ...(opts.showGridLines !== undefined ? { showGridLines: opts.showGridLines } : {}),\n ...(opts.showRowColHeaders !== undefined ? { showRowColHeaders: opts.showRowColHeaders } : {}),\n ...(opts.showFormulas !== undefined ? { showFormulas: opts.showFormulas } : {}),\n ...(opts.showZeros !== undefined ? { showZeros: opts.showZeros } : {}),\n ...(opts.rightToLeft !== undefined ? { rightToLeft: opts.rightToLeft } : {}),\n ...(opts.view !== undefined ? { view: opts.view } : {}),\n ...(opts.topLeftCell !== undefined ? { topLeftCell: opts.topLeftCell } : {}),\n ...(opts.zoomScale !== undefined ? { zoomScale: opts.zoomScale } : {}),\n ...(opts.zoomScaleNormal !== undefined ? { zoomScaleNormal: opts.zoomScaleNormal } : {}),\n ...(opts.pane ? { pane: opts.pane } : {}),\n ...(opts.selection ? { selection: opts.selection } : {}),\n };\n}\n\n/**\n * Build a frozen Pane from a top-left coordinate. Per Excel semantics:\n * - \"B2\" → freeze 1 row + 1 col → xSplit=1, ySplit=1, activePane='bottomRight'\n * - \"A2\" → freeze 1 row only → ySplit=1, activePane='bottomLeft'\n * - \"B1\" → freeze 1 col only → xSplit=1, activePane='topRight'\n * - \"A1\" → no freeze; throws (caller should clear `ws.views[].pane`).\n */\nexport function makeFreezePane(topLeftRef: string): Pane {\n const { col, row } = coordinateToTuple(topLeftRef);\n if (col === 1 && row === 1) {\n throw new OpenXmlSchemaError('makeFreezePane: \"A1\" is not a valid freeze ref (no rows or columns to freeze)');\n }\n const xSplit = col - 1;\n const ySplit = row - 1;\n let activePane: PaneType;\n if (xSplit > 0 && ySplit > 0) activePane = 'bottomRight';\n else if (ySplit > 0) activePane = 'bottomLeft';\n else activePane = 'topRight';\n const pane: Pane = {\n state: 'frozen',\n topLeftCell: topLeftRef,\n activePane,\n };\n if (xSplit > 0) pane.xSplit = xSplit;\n if (ySplit > 0) pane.ySplit = ySplit;\n return pane;\n}\n\n/** Inverse of {@link makeFreezePane}. Returns the top-left ref of the bottomRight pane, or undefined. */\nexport function freezePaneRef(view: SheetView): string | undefined {\n const pane = view.pane;\n if (!pane || pane.state !== 'frozen') return undefined;\n if (pane.topLeftCell) return pane.topLeftCell;\n const xSplit = pane.xSplit ?? 0;\n const ySplit = pane.ySplit ?? 0;\n return tupleToCoordinate(xSplit + 1, ySplit + 1);\n}\n","// Legacy comments.\n//\n// Legacy comments live in `xl/commentsN.xml` (typed comment list + authors\n// index) plus a VML drawing part for the popup balloon shape. Stage-1 covers\n// plain-text comments + author dedup; rich-text + VML shape preservation are\n// reserved for later iterations (we emit a minimal placeholder VML so Excel can\n// re-render).\n\nexport interface LegacyComment {\n /** Cell reference — typically a single cell (\"A1\") but Excel allows ranges. */\n ref: string;\n /** Display name of the comment author. */\n author: string;\n /** Plain-text body. Stage-1 doesn't preserve rich-text formatting. */\n text: string;\n}\n\nexport function makeLegacyComment(opts: { ref: string; author: string; text: string }): LegacyComment {\n return { ref: opts.ref, author: opts.author, text: opts.text };\n}\n","// Worksheet `<sheetPr>` properties. (sheet view 拡張). Mirrors\n// openpyxl/openpyxl/worksheet/properties.py.\n//\n// Promoting sheetPr out of `bodyExtras.beforeSheetData` gives consumers a typed\n// handle for the most common fields (`tabColor`, `codeName`) and for the two\n// child elements that drive Excel's outline / page-setup behaviour. The full\n// set is modeled so a load → save round-trip preserves the element verbatim —\n// niche sync* / transition* attrs included.\n\nimport type { Color } from '../styles/colors';\n\nexport interface OutlineProperties {\n applyStyles?: boolean;\n /** \"Summary rows below detail\" — Excel default true. */\n summaryBelow?: boolean;\n /** \"Summary columns to right of detail\" — Excel default true. */\n summaryRight?: boolean;\n showOutlineSymbols?: boolean;\n}\n\nexport interface PageSetupProperties {\n autoPageBreaks?: boolean;\n fitToPage?: boolean;\n}\n\nexport interface SheetProperties {\n /** VBA codeName for the sheet (\"Sheet1\" by default but localizable). */\n codeName?: string;\n enableFormatConditionsCalculation?: boolean;\n /** Whether the sheet has an active filter set up. */\n filterMode?: boolean;\n /** Whether the sheet is published to a SharePoint Excel Services list. */\n published?: boolean;\n /** Sync* attrs control multi-sheet scroll synchronisation. */\n syncHorizontal?: boolean;\n syncRef?: string;\n syncVertical?: boolean;\n /** \"Lotus 1-2-3 transition\" toggles — almost never seen in modern files. */\n transitionEvaluation?: boolean;\n transitionEntry?: boolean;\n /** Tab strip colour for this sheet (the coloured stripe at the bottom). */\n tabColor?: Color;\n outlinePr?: OutlineProperties;\n pageSetUpPr?: PageSetupProperties;\n}\n\nexport const makeSheetProperties = (opts: SheetProperties = {}): SheetProperties => {\n const out: SheetProperties = {};\n if (opts.codeName !== undefined) out.codeName = opts.codeName;\n if (opts.enableFormatConditionsCalculation !== undefined)\n out.enableFormatConditionsCalculation = opts.enableFormatConditionsCalculation;\n if (opts.filterMode !== undefined) out.filterMode = opts.filterMode;\n if (opts.published !== undefined) out.published = opts.published;\n if (opts.syncHorizontal !== undefined) out.syncHorizontal = opts.syncHorizontal;\n if (opts.syncRef !== undefined) out.syncRef = opts.syncRef;\n if (opts.syncVertical !== undefined) out.syncVertical = opts.syncVertical;\n if (opts.transitionEvaluation !== undefined) out.transitionEvaluation = opts.transitionEvaluation;\n if (opts.transitionEntry !== undefined) out.transitionEntry = opts.transitionEntry;\n if (opts.tabColor !== undefined) out.tabColor = opts.tabColor;\n if (opts.outlinePr !== undefined) out.outlinePr = opts.outlinePr;\n if (opts.pageSetUpPr !== undefined) out.pageSetUpPr = opts.pageSetUpPr;\n return out;\n};\n","// Worksheet data model.\n//\n// Cells live in a sparse two-level Map (row → col → Cell). The choice is\n// deliberate: a workbook with 1 M cells in 1 column shouldn't allocate 1 M\n// empty rows, and JSON.stringify with `Map` round-trips cleanly via the\n// workbook's `jsonReplacer`. Worksheets are mutable for hot-path performance.\n\nimport type { CellValue } from '../cell/cell';\nimport { type Cell, cellValueAsString, makeCell, setArrayFormula, setFormula } from '../cell/cell';\nimport { type InlineFont, makeRichText, type TextRun } from '../cell/rich-text';\nimport type { Drawing } from '../drawing/drawing';\nimport { type Color, makeColor } from '../styles/colors';\nimport {\n columnIndexFromLetter,\n columnLetterFromIndex,\n coordinateToTuple,\n formatSheetQualifiedRef,\n MAX_COL,\n MAX_ROW,\n tupleToCoordinate,\n} from '../utils/coordinate';\nimport { OpenXmlSchemaError } from '../utils/exceptions';\nimport type { AutoFilter } from './auto-filter';\nimport { type CellRange, parseRange, rangeContainsCell, rangesOverlap, rangeToString } from './cell-range';\nimport type { LegacyComment } from './comments';\nimport { makeLegacyComment } from './comments';\nimport type { ConditionalFormatting } from './conditional-formatting';\nimport type { DataValidation } from './data-validations';\nimport { type ColumnDimension, makeColumnDimension, makeRowDimension, type RowDimension } from './dimensions';\nimport type { DataConsolidate } from './data-consolidate';\nimport type { ScenarioList } from './scenarios';\nimport type { CellWatch, IgnoredError } from './errors';\nimport type { HeaderFooter, PageBreak, PageMargins, PageSetup, PrintOptions } from './page-setup';\nimport type { WorksheetPhoneticProperties } from './phonetic';\nimport { makeSheetProperties, type SheetProperties } from './properties';\nimport type { SheetProtection } from './protection';\nimport type { ProtectedRange } from './protected-ranges';\nimport type { SortState } from './sort-state';\nimport type { WebPublishItem, WorksheetCustomProperty } from './web-publish';\nimport { type Hyperlink, makeHyperlink } from './hyperlinks';\nimport type { TableDefinition } from './table';\nimport { freezePaneRef, makeFreezePane, makeSheetView, type SheetView } from './views';\n\nexport interface Worksheet {\n title: string;\n /** Sparse store: row index → (col index → Cell). */\n rows: Map<number, Map<number, Cell>>;\n /**\n * Highest row index touched by `appendRow`; used to keep appendRow O(1)\n * without re-scanning the row map. Direct setCell / deleteCell may move the\n * actual maximum elsewhere.\n */\n _appendRowCursor: number;\n /**\n * Merged cell ranges. The top-left cell holds the value; the rest are mostly\n * invisible to Excel until unmerge restores them. We persist the list as\n * plain CellRange[] so mergeCells / unmergeCells can mutate it without\n * rebuilding any helper structures.\n */\n mergedCells: CellRange[];\n /**\n * Per-bookView display settings. Most workbooks have exactly one view. The\n * list stays empty until something — read or API — populates it; a lone\n * default view doesn't earn its keep on the wire.\n */\n views: SheetView[];\n /**\n * Per-column metadata keyed by the entry's `min` index. The value's\n * `min`/`max` may cover a multi-column run; iteration over the map yields one\n * entry per run, in `min`-ascending order.\n */\n columnDimensions: Map<number, ColumnDimension>;\n /** Per-row metadata keyed by 1-based row index. */\n rowDimensions: Map<number, RowDimension>;\n /** Default column width (characters) when not overridden by a column dimension. */\n defaultColumnWidth?: number;\n /** Default row height (points) when not overridden by a row dimension. */\n defaultRowHeight?: number;\n /**\n * Highest outline depth used among `rowDimensions`. Excel uses this to size\n * the outline button strip on the left of the row numbers. Auto-computed by\n * the writer when undefined — set explicitly to override.\n */\n outlineLevelRow?: number;\n /** Highest outline depth used among `columnDimensions`. Auto-computed by the writer when undefined. */\n outlineLevelCol?: number;\n /** \"Custom row heights present\" hint — Excel uses this to skip default-height rendering. */\n customHeight?: boolean;\n /** \"Show rows of zero height as one row\" — for hidden rows the outline collapse uses this. */\n zeroHeight?: boolean;\n /** Apply a thick top border to every row by default. */\n thickTop?: boolean;\n /** Apply a thick bottom border to every row by default. */\n thickBottom?: boolean;\n /** Excel's \"base column width\" (characters) — defaults to 8 when unset. */\n baseColWidth?: number;\n /** Hyperlinks. External URLs round-trip via worksheet rels; internal jumps stay inline. */\n hyperlinks: Hyperlink[];\n /** Data validation entries. */\n dataValidations: DataValidation[];\n /** AutoFilter — at most one per sheet. Excel reuses the `_xlnm._FilterDatabase` defined name. */\n autoFilter?: AutoFilter;\n /** Excel Table objects. Each lives in its own xl/tables/tableN.xml part. */\n tables: TableDefinition[];\n /** Legacy comments. Persisted as `xl/commentsN.xml` + a placeholder VML drawing. */\n legacyComments: LegacyComment[];\n /** Conditional formatting blocks. */\n conditionalFormatting: ConditionalFormatting[];\n /**\n * `<sheetPr>` properties — VBA codeName, tab strip color, outline /\n * page-setup defaults, etc. Top-level `<sheetPr>` lives just before\n * `<dimension>` per ECMA-376 ordering.\n */\n sheetProperties?: SheetProperties;\n /**\n * Sheet-protection state. When `sheet=true` Excel locks the sheet against\n * edits (subject to the per-action allow flags here). Password hashing\n * helpers come later — for now `saltValue` / `spinCount` / `algorithmName` /\n * `hashValue` round-trip verbatim.\n */\n sheetProtection?: SheetProtection;\n /**\n * `<protectedRanges>` — per-range edit-allowance overrides used when the\n * sheet is otherwise protected (Review → Allow Edit Ranges).\n */\n protectedRanges: ProtectedRange[];\n /**\n * `<sortState>` — last-applied sort criteria. Excel persists this so the rows\n * come back in the same order after a save/load cycle.\n */\n sortState?: SortState;\n /**\n * `<picture r:id=\"…\"/>` — sheet background image (Page Layout → Background).\n * The rId points at a media part registered in the worksheet rels (preserved\n * via the existing relsExtras machinery).\n */\n backgroundPictureRId?: string;\n /**\n * `<legacyDrawingHF r:id=\"…\"/>` — VML drawing used for header/footer\n * background images on print. Parallel to legacyDrawing (which carries\n * comment markers); the rels link rides relsExtras.\n */\n legacyDrawingHFRId?: string;\n /**\n * `<smartTags>` — per-cell smart-tag annotations (Excel 2003 era). Pairs with\n * the workbook-level smartTagTypes registry.\n */\n smartTags: import('./smart-tags').CellSmartTags[];\n /**\n * `<customSheetViews>` — saved per-user view presets for this worksheet\n * (Excel's \"Custom Views\" feature). Each entry snapshots zoom / gridline /\n * formula / heading toggles plus its own page-setup block and break list.\n */\n customSheetViews: import('./custom-sheet-views').CustomSheetView[];\n /**\n * `<oleObjects>` — embedded OLE objects (linked Word documents, Equation\n * editor formulas, etc.). The objectPr child is round-tripped verbatim as an\n * XmlNode.\n */\n oleObjects: import('./ole-objects').OleObject[];\n /**\n * `<controls>` — form controls (checkboxes / list boxes / spin buttons placed\n * via the Developer tab). The controlPr child is round-tripped verbatim.\n */\n controls: import('./ole-objects').FormControl[];\n /** `<printOptions>` — gridlines, headings, horizontal/vertical centering on the printed page. */\n printOptions?: PrintOptions;\n /** `<pageMargins>` — six required margins in inches. */\n pageMargins?: PageMargins;\n /** `<pageSetup>` — paper size / orientation / scale / fitToPage / DPI etc. */\n pageSetup?: PageSetup;\n /** `<headerFooter>` — odd/even/first header + footer mini-format strings + flags. */\n headerFooter?: HeaderFooter;\n /** Manual horizontal page breaks (`<rowBreaks>`). Each entry's `id` is the row above which a new page begins. */\n rowBreaks: PageBreak[];\n /** Manual vertical page breaks (`<colBreaks>`). Each entry's `id` is the column to the left of which a new page begins. */\n colBreaks: PageBreak[];\n /**\n * Worksheet-level `<customProperties>` — per-sheet user metadata that\n * SharePoint workflows attach (separate from the workbook-level\n * `docProps/custom.xml` part). The `rId` points at a Custom XML part\n * registered in the worksheet rels (already preserved via `relsExtras`).\n */\n customProperties: WorksheetCustomProperty[];\n /** `<webPublishItems>` — Excel 2007's \"Publish to web\" entries. Almost always empty in modern files. */\n webPublishItems: WebPublishItem[];\n /**\n * `<phoneticPr>` — East-Asian furigana rendering hints (font index + IME\n * conversion mode + alignment). Common in Japanese workbooks.\n */\n phoneticPr?: WorksheetPhoneticProperties;\n /**\n * `<dataConsolidate>` — config for Data → Consolidate. Carries the\n * aggregation function and the source-range list.\n */\n dataConsolidate?: DataConsolidate;\n /** `<scenarios>` — the Scenario Manager's saved input-cell overrides. */\n scenarios?: ScenarioList;\n /** Cells pinned in Excel's Watch Window (`<cellWatches><cellWatch r=\"…\"/></cellWatches>`). */\n cellWatches: CellWatch[];\n /**\n * Per-region \"ignore this error class\" rules (`<ignoredErrors>`). Suppresses\n * the small green-triangle warning for the listed checks.\n */\n ignoredErrors: IgnoredError[];\n /**\n * Spreadsheet drawing — at most one per worksheet. Hosts charts / pictures /\n * shapes. Persisted as `xl/drawings/drawingN.xml` plus a worksheet-rels\n * entry; on the wire the worksheet body emits `<drawing r:id>`.\n */\n drawing?: Drawing;\n /**\n * Per-sheet rels entries we don't model (pivotTable / queryTable / slicer /\n * printerSettings / customProperty / oleObject etc.). Re-emitted verbatim so\n * Excel still resolves the captured passthrough parts after a round-trip.\n */\n relsExtras?: ReadonlyArray<{ id: string; type: string; target: string }>;\n /**\n * Top-level `<worksheet>` children we don't model — `<sheetPr>`,\n * `<printOptions>`, `<pageMargins>`, `<pageSetup>`, `<headerFooter>`,\n * `<rowBreaks>`, `<colBreaks>`, `<oleObjects>`, `<controls>`, `<picture>`,\n * `<extLst>`, etc. Captured as XmlNodes; the writer emits them in two\n * anchored slots so common ECMA-376 ordering survives a round-trip even\n * though we don't track every position individually:\n * - `beforeSheetData` → emitted before our `<dimension>` (typical for\n * `<sheetPr>`).\n * - `afterSheetData` → emitted between our `<hyperlinks>` and\n * `<drawing>` block, which lands page setup / extLst / oleObjects in roughly\n * the right place. Excel reads back regardless of strict ECMA position;\n * openpyxl-emitted files round-trip cleanly.\n */\n bodyExtras?: {\n beforeSheetData: import('../xml/tree').XmlNode[];\n afterSheetData: import('../xml/tree').XmlNode[];\n };\n}\n\n/** Build a Worksheet shell. */\nexport function makeWorksheet(title: string): Worksheet {\n if (typeof title !== 'string' || title.length === 0) {\n throw new OpenXmlSchemaError('Worksheet title must be a non-empty string');\n }\n return {\n title,\n rows: new Map(),\n _appendRowCursor: 0,\n mergedCells: [],\n views: [],\n columnDimensions: new Map(),\n rowDimensions: new Map(),\n hyperlinks: [],\n dataValidations: [],\n tables: [],\n legacyComments: [],\n conditionalFormatting: [],\n cellWatches: [],\n ignoredErrors: [],\n rowBreaks: [],\n colBreaks: [],\n customProperties: [],\n webPublishItems: [],\n protectedRanges: [],\n smartTags: [],\n customSheetViews: [],\n oleObjects: [],\n controls: [],\n };\n}\n\nconst validateRowCol = (row: number, col: number): void => {\n if (!Number.isInteger(row) || row < 1 || row > MAX_ROW) {\n throw new OpenXmlSchemaError(`Worksheet row ${row} out of range [1, ${MAX_ROW}]`);\n }\n if (!Number.isInteger(col) || col < 1 || col > MAX_COL) {\n throw new OpenXmlSchemaError(`Worksheet col ${col} out of range [1, ${MAX_COL}]`);\n }\n};\n\n/** Resolve a 1-based or \"A1\" coordinate; returns the populated Cell or undefined. */\nexport function getCell(ws: Worksheet, row: number, col: number): Cell | undefined {\n return ws.rows.get(row)?.get(col);\n}\n\n/**\n * Create or update a Cell at (row, col). Existing cells keep their styleId /\n * hyperlinkId / commentId unless explicitly overridden.\n */\nexport function setCell(ws: Worksheet, row: number, col: number, value: CellValue = null, styleId?: number): Cell {\n let rowMap = ws.rows.get(row);\n let cell = rowMap?.get(col);\n if (cell === undefined) {\n // makeCell validates (row, col); no need for a second worksheet-level\n // validateRowCol on the hot path.\n cell = makeCell(row, col, value, styleId ?? 0);\n if (rowMap === undefined) {\n rowMap = new Map<number, Cell>();\n ws.rows.set(row, rowMap);\n }\n rowMap.set(col, cell);\n } else {\n cell.value = value;\n if (styleId !== undefined) cell.styleId = styleId;\n }\n if (row > ws._appendRowCursor) ws._appendRowCursor = row;\n return cell;\n}\n\n/** Delete a single cell from the sheet. Empty rows are pruned. */\nexport function deleteCell(ws: Worksheet, row: number, col: number): void {\n const rowMap = ws.rows.get(row);\n if (rowMap === undefined) return;\n rowMap.delete(col);\n if (rowMap.size === 0) ws.rows.delete(row);\n}\n\n/**\n * Delete every populated cell inside a range. Returns the number of cells\n * removed. Row maps that go empty are pruned. Column / row dimensions, merges,\n * comments etc. are left untouched.\n */\nexport function clearRange(ws: Worksheet, range: string): number {\n const { minRow, maxRow, minCol, maxCol } = parseRange(range);\n let n = 0;\n for (let r = minRow; r <= maxRow; r++) {\n const rowMap = ws.rows.get(r);\n if (!rowMap) continue;\n for (let c = minCol; c <= maxCol; c++) {\n if (rowMap.delete(c)) n++;\n }\n if (rowMap.size === 0) ws.rows.delete(r);\n }\n return n;\n}\n\n/**\n * Wipe every populated cell on the worksheet, leaving styles, dimensions,\n * merges, comments, hyperlinks etc. intact. Returns the count of cells removed.\n * Useful when a sheet should be re-filled from scratch but its formatting kept.\n */\nexport function clearAllCells(ws: Worksheet): number {\n let n = 0;\n for (const rowMap of ws.rows.values()) n += rowMap.size;\n ws.rows.clear();\n ws._appendRowCursor = 0;\n return n;\n}\n\n/**\n * Append a row of values starting at the next empty row. Returns the row index\n * (1-based). Mirrors openpyxl's `Worksheet.append`. `null` / `undefined`\n * entries leave the cell empty.\n */\nexport function appendRow(ws: Worksheet, values: ReadonlyArray<CellValue | undefined>): number {\n const row = ws._appendRowCursor + 1;\n for (let i = 0; i < values.length; i++) {\n const value = values[i];\n if (value === undefined || value === null) continue;\n setCell(ws, row, i + 1, value);\n }\n // Even if every value is empty, advance the cursor so the next call doesn't\n // overwrite this row's would-be position.\n ws._appendRowCursor = row;\n return row;\n}\n\n/**\n * Bulk version of {@link appendRow}: append a 2D array of values one row at a\n * time. Returns `{firstRow, lastRow}` — both 1-based, inclusive. An empty input\n * returns `{firstRow, lastRow: firstRow - 1}` so callers can detect the no-op\n * without throwing.\n *\n * Common usage: `appendRows(ws, csvParsedRows)` for fast import.\n */\nexport function appendRows(\n ws: Worksheet,\n rows: ReadonlyArray<ReadonlyArray<CellValue | undefined>>,\n): { firstRow: number; lastRow: number } {\n const firstRow = ws._appendRowCursor + 1;\n if (rows.length === 0) {\n return { firstRow, lastRow: firstRow - 1 };\n }\n let lastRow = firstRow - 1;\n for (const row of rows) {\n lastRow = appendRow(ws, row);\n }\n return { firstRow, lastRow };\n}\n\n/**\n * Write a 2D array of values to the sheet starting at the given A1 anchor cell.\n * Distinct from {@link appendRows} (which always writes past\n * `_appendRowCursor`) — this lets you place a block at an arbitrary location,\n * e.g. mid-sheet table updates.\n *\n * `null` / `undefined` entries leave the corresponding cell **untouched**\n * (existing cell + style are preserved). Pre-existing cells inside the written\n * rectangle are overwritten in place, so their `styleId` survives the write.\n *\n * Returns the bounding-box of the written area as 1-based inclusive\n * coordinates. An empty rows array returns `undefined` rather than an invalid\n * zero-area range.\n */\nexport function writeRange(\n ws: Worksheet,\n startRef: string,\n values: ReadonlyArray<ReadonlyArray<CellValue | undefined>>,\n): { minRow: number; maxRow: number; minCol: number; maxCol: number } | undefined {\n if (values.length === 0) return undefined;\n const { col: startCol, row: startRow } = coordinateToTuple(startRef);\n let maxRow = startRow;\n let maxCol = startCol;\n for (let i = 0; i < values.length; i++) {\n const row = values[i];\n if (row === undefined) continue;\n const r = startRow + i;\n for (let j = 0; j < row.length; j++) {\n const v = row[j];\n if (v === undefined || v === null) continue;\n const c = startCol + j;\n setCell(ws, r, c, v);\n if (c > maxCol) maxCol = c;\n }\n if (r > maxRow) maxRow = r;\n }\n return { minRow: startRow, maxRow, minCol: startCol, maxCol };\n}\n\nexport interface IterRowsOptions {\n minRow?: number;\n maxRow?: number;\n minCol?: number;\n maxCol?: number;\n}\n\n/**\n * Iterate the worksheet rows rectangularly. Yields one row per row in\n * `[minRow, maxRow]` — including entirely empty rows — and each yielded row\n * has length `maxCol - minCol + 1`. Missing cell positions are `undefined`\n * (no placeholder Cell allocations).\n *\n * Defaults: `minRow=1`, `maxRow=getMaxRow(ws)`, `minCol=1`,\n * `maxCol=getMaxCol(ws)`. The default extent is the populated bounding box,\n * not the 1M × 16K sheet limit, so the rectangular default doesn't iterate\n * the whole grid for a small sheet.\n *\n * To iterate populated rows only, filter:\n * `[...iterRows(ws)].filter(row => row.some((c) => c !== undefined))`. To\n * iterate populated cells without row boundaries, use {@link iterCells}.\n */\nexport function* iterRows(ws: Worksheet, opts: IterRowsOptions = {}): IterableIterator<(Cell | undefined)[]> {\n const { minRow = 1, maxRow = getMaxRow(ws), minCol = 1, maxCol = getMaxCol(ws) } = opts;\n if (maxRow < minRow || maxCol < minCol) return;\n const width = maxCol - minCol + 1;\n for (let r = minRow; r <= maxRow; r++) {\n const rowMap = ws.rows.get(r);\n // Fill explicitly so the array isn't sparse — `.map` callbacks would skip\n // empty slots and surprise the caller.\n const out: (Cell | undefined)[] = new Array(width).fill(undefined);\n if (rowMap !== undefined) {\n for (let c = minCol; c <= maxCol; c++) {\n const cell = rowMap.get(c);\n if (cell !== undefined) out[c - minCol] = cell;\n }\n }\n yield out;\n }\n}\n\n/**\n * Same rectangular iteration as {@link iterRows}, but yields each cell's\n * `.value`. Missing cell positions become `null` — already the canonical empty\n * marker in `CellValue`.\n */\nexport function* iterValues(ws: Worksheet, opts: IterRowsOptions = {}): IterableIterator<CellValue[]> {\n for (const row of iterRows(ws, opts)) {\n yield row.map((c) => (c === undefined ? null : c.value));\n }\n}\n\n/**\n * Yield every populated cell in the worksheet as a flat stream (row-major,\n * columns ascending). Distinct from {@link iterRows} which yields one row\n * per row in the bounding box — use this when the caller wants only the\n * populated cells without row boundaries or rectangular padding.\n */\nexport function* iterCells(ws: Worksheet, opts: IterRowsOptions = {}): IterableIterator<Cell> {\n for (const row of iterRows(ws, opts)) {\n for (const cell of row) {\n if (cell !== undefined) yield cell;\n }\n }\n}\n\n/** Effective max row index based on populated cells (0 when empty). */\nexport function getMaxRow(ws: Worksheet): number {\n let m = 0;\n for (const r of ws.rows.keys()) if (r > m) m = r;\n return m;\n}\n\n/** Effective max column index based on populated cells (0 when empty). */\nexport function getMaxCol(ws: Worksheet): number {\n let m = 0;\n for (const rowMap of ws.rows.values()) {\n for (const c of rowMap.keys()) if (c > m) m = c;\n }\n return m;\n}\n\n/**\n * Sorted list of every row index that holds at least one populated cell.\n * Returns `[]` for an empty worksheet. Useful when a caller wants to iterate\n * only the rows the user actually populated, without walking 1..maxRow in dense\n * fashion.\n */\nexport function getPopulatedRowIndices(ws: Worksheet): number[] {\n const out: number[] = [];\n for (const [r, rowMap] of ws.rows) {\n if (rowMap.size > 0) out.push(r);\n }\n return out.sort((a, b) => a - b);\n}\n\n/**\n * Sorted list of every column index that holds at least one populated cell\n * anywhere on the sheet. Distinct columns only; returns `[]` for an empty\n * worksheet.\n */\nexport function getPopulatedColumnIndices(ws: Worksheet): number[] {\n const seen = new Set<number>();\n for (const rowMap of ws.rows.values()) {\n for (const c of rowMap.keys()) seen.add(c);\n }\n return [...seen].sort((a, b) => a - b);\n}\n\n/**\n * Tally populated cells by value kind. Useful for stats / debugging dashboards\n * that want a quick \"this sheet has N strings, M formulas, K dates\" snapshot.\n *\n * Buckets:\n * - `null`: empty cells (cell exists but value is null)\n * - `string`: plain strings\n * - `number`: numeric primitives\n * - `boolean`: TRUE / FALSE\n * - `date`: native `Date` instances\n * - `duration`: `{ kind: 'duration', ms }` values\n * - `error`: `#REF!` / `#VALUE!` / etc. error values\n * - `rich-text`: `{ kind: 'rich-text', runs }` values\n * - `formula`: `FormulaValue` (regardless of cached value type)\n */\nexport interface CellsByKindCounts {\n null: number;\n string: number;\n number: number;\n boolean: number;\n date: number;\n duration: number;\n error: number;\n 'rich-text': number;\n formula: number;\n}\n\n/**\n * Bucket a single CellValue into one of the {@link CellsByKindCounts} keys.\n * Shared between {@link countCellsByKind} and the workbook-wide overview so\n * the two never drift in how they classify (e.g. `Date` vs `duration`).\n */\nexport function classifyCellValue(v: import('../cell/cell').CellValue): keyof CellsByKindCounts {\n if (v === null) return 'null';\n if (typeof v === 'string') return 'string';\n if (typeof v === 'number') return 'number';\n if (typeof v === 'boolean') return 'boolean';\n if (v instanceof Date) return 'date';\n const kind = (v as { kind?: string }).kind;\n if (kind === 'duration') return 'duration';\n if (kind === 'error') return 'error';\n if (kind === 'rich-text') return 'rich-text';\n // Remaining shape is FormulaValue (kind === 'formula').\n return 'formula';\n}\n\nexport function countCellsByKind(ws: Worksheet): 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 cell of iterCells(ws)) {\n out[classifyCellValue(cell.value)]++;\n }\n return out;\n}\n\n/**\n * Sheet-qualified A1 address for a cell — `'Sheet1!A1'` for plain titles,\n * `'\\'Quarter 1\\'!A1'` for titles needing quoting (spaces, apostrophes,\n * punctuation, leading-digit). Round-trips with {@link parseSheetRange}.\n *\n * Useful when constructing formulas / defined-names that reference a specific\n * cell across sheets without hand-rolling the quote logic.\n */\nexport function getCellAddress(ws: Worksheet, c: Cell): string {\n return formatSheetQualifiedRef(ws.title, tupleToCoordinate(c.col, c.row));\n}\n\n/**\n * Sheet-qualified A1 range address — `'Sheet1!A1:B5'` for plain titles,\n * `'\\'Quarter 1\\'!A1:B5'` for titles needing quoting. Pass any A1-style range\n * string (single cell `'A1'`, rectangle `'A1:B5'`, row span `'1:5'`, column\n * span `'A:E'`); the helper does no validation on `range` itself — that's the\n * caller's responsibility.\n */\nexport function getRangeAddress(ws: Worksheet, range: string): string {\n return formatSheetQualifiedRef(ws.title, range);\n}\n\n/**\n * True iff the worksheet has zero non-empty cells. Equivalent to\n * `getNonEmptyCellCount(ws) === 0` but short-circuits on the first non-null\n * value found, so the cost is O(first non-empty cell) rather than O(populated\n * cells).\n */\nexport function isWorksheetEmpty(ws: Worksheet): boolean {\n for (const cell of iterCells(ws)) {\n if (cell.value !== null) return false;\n }\n return true;\n}\n\n/**\n * Count non-empty cells. Distinct from {@link countCells} which counts every\n * materialised cell (including ones whose `value === null`): this skips cells\n * with a `null` value, plus optionally formulas / rich-text per the opts.\n *\n * Useful for \"how many real values does this sheet contain\" stats vs the\n * materialised footprint.\n */\nexport function getNonEmptyCellCount(\n ws: Worksheet,\n opts: { includeFormulas?: boolean; includeRichText?: boolean } = {},\n): number {\n const includeFormulas = opts.includeFormulas ?? true;\n const includeRichText = opts.includeRichText ?? true;\n let n = 0;\n for (const cell of iterCells(ws)) {\n const v = cell.value;\n if (v === null) continue;\n if (typeof v === 'object' && v !== null) {\n const kind = (v as { kind?: string }).kind;\n if (kind === 'formula' && !includeFormulas) continue;\n if (kind === 'rich-text' && !includeRichText) continue;\n }\n n++;\n }\n return n;\n}\n\n/** Total populated cell count. */\nexport function countCells(ws: Worksheet): number {\n let n = 0;\n for (const rowMap of ws.rows.values()) n += rowMap.size;\n return n;\n}\n\n/**\n * Bounding-box of the populated cells: `{ minRow, maxRow, minCol, maxCol }`\n * covering every cell in `ws.rows`. Returns `undefined` when the sheet is\n * empty. Walks the sparse store once.\n */\nexport function getDataExtent(\n ws: Worksheet,\n): { minRow: number; maxRow: number; minCol: number; maxCol: number } | undefined {\n let minRow = Number.POSITIVE_INFINITY;\n let maxRow = 0;\n let minCol = Number.POSITIVE_INFINITY;\n let maxCol = 0;\n let touched = false;\n for (const [r, rowMap] of ws.rows) {\n if (rowMap.size === 0) continue;\n if (r < minRow) minRow = r;\n if (r > maxRow) maxRow = r;\n for (const c of rowMap.keys()) {\n if (c < minCol) minCol = c;\n if (c > maxCol) maxCol = c;\n }\n touched = true;\n }\n if (!touched) return undefined;\n return { minRow, maxRow, minCol, maxCol };\n}\n\n/**\n * Same as {@link getDataExtent} but returns the canonical `\"A1:E10\"` range\n * string for the bounding box, or `undefined` when the sheet is empty.\n */\nexport function getDataExtentRef(ws: Worksheet): string | undefined {\n const ext = getDataExtent(ws);\n if (!ext) return undefined;\n return rangeToString({\n minRow: ext.minRow,\n maxRow: ext.maxRow,\n minCol: ext.minCol,\n maxCol: ext.maxCol,\n });\n}\n\n/**\n * Iterate every populated cell, yielding those for which `predicate` returns\n * true. Iteration order is row-then-column ascending. Cells whose `.value ===\n * null` (empty placeholders carrying only style or comment metadata) are still\n * visited.\n */\nexport function* findCells(\n ws: Worksheet,\n predicate: (c: Cell) => boolean,\n): IterableIterator<Cell> {\n const rowKeys = [...ws.rows.keys()].sort((a, b) => a - b);\n for (const r of rowKeys) {\n const rowMap = ws.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 && predicate(cell)) yield cell;\n }\n }\n}\n\n/** First populated cell satisfying `predicate`, or `undefined`. */\nexport function findFirstCell(\n ws: Worksheet,\n predicate: (c: Cell) => boolean,\n): Cell | undefined {\n for (const cell of findCells(ws, predicate)) return cell;\n return undefined;\n}\n\n/**\n * Find-and-replace across populated string cells. `search` matches either an\n * exact-string equal (when given a string) or every cell whose value satisfies\n * the predicate (when given a function). `replacement` is the new value for\n * each match. Returns the count of cells changed. Non-string-valued cells are\n * skipped when `search` is a string; predicate-based searches see every cell.\n */\nexport function replaceCellValues(\n ws: Worksheet,\n search: string | ((value: CellValue, cell: Cell) => boolean),\n replacement: CellValue,\n): number {\n let n = 0;\n const matchFn =\n typeof search === 'string'\n ? (v: CellValue) => typeof v === 'string' && v === search\n : (v: CellValue, c: Cell) => search(v, c);\n for (const rowMap of ws.rows.values()) {\n for (const cell of rowMap.values()) {\n if (matchFn(cell.value, cell)) {\n cell.value = replacement;\n n++;\n }\n }\n }\n return n;\n}\n\n/**\n * Range-scoped find-and-replace. Same matching rules as {@link\n * replaceCellValues} (string → exact-equal on string-valued cells; function →\n * predicate over every populated cell), but only cells inside the rectangular\n * `range` are visited. Returns the count changed.\n */\nexport function replaceInRange(\n ws: Worksheet,\n range: string,\n search: string | ((value: CellValue, cell: Cell) => boolean),\n replacement: CellValue,\n): number {\n let n = 0;\n const matchFn =\n typeof search === 'string'\n ? (v: CellValue) => typeof v === 'string' && v === search\n : (v: CellValue, c: Cell) => search(v, c);\n for (const cell of getCellsInRange(ws, range)) {\n if (matchFn(cell.value, cell)) {\n cell.value = replacement;\n n++;\n }\n }\n return n;\n}\n\n/**\n * Iterate the populated cells inside a rectangular range. Cells that don't\n * exist in the sparse store are skipped (no auto-allocate). Use {@link\n * applyToRange} when you need every coordinate visited regardless of\n * population.\n */\nexport function* getCellsInRange(ws: Worksheet, range: string): IterableIterator<Cell> {\n const { minRow, maxRow, minCol, maxCol } = parseRange(range);\n for (let r = minRow; r <= maxRow; r++) {\n const rowMap = ws.rows.get(r);\n if (!rowMap) continue;\n for (let col = minCol; col <= maxCol; col++) {\n const cell = rowMap.get(col);\n if (cell !== undefined) yield cell;\n }\n }\n}\n\n/**\n * Set a cell's value to a rich-text run array. Accepts either a pre-built\n * `RichText` (frozen array of TextRun) or a fresh `Array<{ text, font? }>`\n * shape — `makeRichText` normalises and freezes the runs in either case.\n * Returns the cell.\n */\nexport function setCellRichText(\n ws: Worksheet,\n row: number,\n col: number,\n runs: ReadonlyArray<TextRun | { text: string; font?: InlineFont }>,\n styleId?: number,\n): Cell {\n return setCell(ws, row, col, { kind: 'rich-text', runs: makeRichText(runs) }, styleId);\n}\n\n/**\n * Set a cell's value to a normal Excel formula. Combines `setCell` with\n * `setFormula`. The leading `=` is stripped if present so callers can pass\n * `'=A1+1'` or `'A1+1'` interchangeably.\n */\nexport function setCellFormula(\n ws: Worksheet,\n row: number,\n col: number,\n formula: string,\n opts?: { cachedValue?: number | string | boolean; styleId?: number },\n): Cell {\n const expr = formula.startsWith('=') ? formula.slice(1) : formula;\n const cell = setCell(ws, row, col, undefined, opts?.styleId);\n setFormula(cell, expr, opts?.cachedValue !== undefined ? { cachedValue: opts.cachedValue } : undefined);\n return cell;\n}\n\n/**\n * Set a cell's value to an array (CSE) formula spanning `ref`. Lands the\n * formula on the top-left cell of the range — Excel reads the `ref` attribute\n * to know how far the result spreads. Equivalent to `setCell` +\n * `setArrayFormula`. Leading `=` is stripped.\n */\nexport function setCellArrayFormula(\n ws: Worksheet,\n row: number,\n col: number,\n ref: string,\n formula: string,\n opts?: { cachedValue?: number | string | boolean; styleId?: number },\n): Cell {\n const expr = formula.startsWith('=') ? formula.slice(1) : formula;\n const cell = setCell(ws, row, col, undefined, opts?.styleId);\n setArrayFormula(cell, ref, expr, opts?.cachedValue !== undefined ? { cachedValue: opts.cachedValue } : undefined);\n return cell;\n}\n\n/** Resolve an \"A1\" coordinate to a numeric (col, row) pair on the sheet. */\nexport function setCellByCoord(ws: Worksheet, coord: string, value?: CellValue, styleId?: number): Cell {\n const m = /^([A-Za-z]{1,3})([1-9][0-9]*)$/.exec(coord);\n if (m === null || m[1] === undefined || m[2] === undefined) {\n throw new OpenXmlSchemaError(`setCellByCoord: invalid coordinate \"${coord}\"`);\n }\n const col = columnIndexFromLetter(m[1]);\n const row = Number.parseInt(m[2], 10);\n return setCell(ws, row, col, value, styleId);\n}\n\n/** Convenience getter accepting an \"A1\" coordinate. */\nexport function getCellByCoord(ws: Worksheet, coord: string): Cell | undefined {\n const m = /^([A-Za-z]{1,3})([1-9][0-9]*)$/.exec(coord);\n if (m === null || m[1] === undefined || m[2] === undefined) return undefined;\n const col = columnIndexFromLetter(m[1]);\n const row = Number.parseInt(m[2], 10);\n return getCell(ws, row, col);\n}\n\n// ---- merged cells ---------------------------------------------------------\n\nconst toCellRange = (refOrRange: string | CellRange): CellRange =>\n typeof refOrRange === 'string' ? parseRange(refOrRange) : refOrRange;\n\n/**\n * Merge a range. The top-left cell keeps its value; every other cell in the\n * range is dropped from `ws.rows` so the on-wire `<sheetData>` won't carry\n * phantom cells underneath the merge. Mirrors openpyxl's\n * `MergedCellRange.format()`. Idempotent for an identical range, throws when\n * the range overlaps an existing merge.\n */\nexport function mergeCells(ws: Worksheet, refOrRange: string | CellRange): CellRange {\n const range = toCellRange(refOrRange);\n for (const existing of ws.mergedCells) {\n if (rangeToString(existing) === rangeToString(range)) return existing;\n if (rangesOverlap(existing, range)) {\n throw new OpenXmlSchemaError(\n `mergeCells: range ${rangeToString(range)} overlaps existing merged range ${rangeToString(existing)}`,\n );\n }\n }\n // Drop every cell except the top-left from the sparse store.\n for (let r = range.minRow; r <= range.maxRow; r++) {\n for (let c = range.minCol; c <= range.maxCol; c++) {\n if (r === range.minRow && c === range.minCol) continue;\n ws.rows.get(r)?.delete(c);\n const row = ws.rows.get(r);\n if (row && row.size === 0) ws.rows.delete(r);\n }\n }\n ws.mergedCells.push(range);\n return range;\n}\n\n/** Drop a previously-merged range. No-op if the range isn't registered. */\nexport function unmergeCells(ws: Worksheet, refOrRange: string | CellRange): boolean {\n const target = rangeToString(toCellRange(refOrRange));\n const idx = ws.mergedCells.findIndex((r) => rangeToString(r) === target);\n if (idx < 0) return false;\n ws.mergedCells.splice(idx, 1);\n return true;\n}\n\n/** Read-only iterator over the worksheet's merged ranges. */\nexport function getMergedCells(ws: Worksheet): ReadonlyArray<CellRange> {\n return ws.mergedCells;\n}\n\n/** True iff (row, col) sits inside any merged range — top-left included. */\nexport function isMergedCell(ws: Worksheet, row: number, col: number): boolean {\n for (const range of ws.mergedCells) {\n if (rangeContainsCell(range, row, col)) return true;\n }\n return false;\n}\n\n/**\n * Look up the merged range covering (row, col), or `undefined` if the\n * coordinate isn't inside any merge. Lets callers introspect a merge without\n * iterating `getMergedCells` themselves.\n */\nexport function getMergedRangeAt(ws: Worksheet, row: number, col: number): CellRange | undefined {\n for (const range of ws.mergedCells) {\n if (rangeContainsCell(range, row, col)) return range;\n }\n return undefined;\n}\n\n/**\n * Drop the merge that contains (row, col), if any. Returns `true` when a merge\n * was unregistered. Useful when callers know a cell coordinate but not the\n * original merge bounds.\n */\nexport function unmergeCellsAt(ws: Worksheet, row: number, col: number): boolean {\n for (let i = 0; i < ws.mergedCells.length; i++) {\n const r = ws.mergedCells[i];\n if (r && rangeContainsCell(r, row, col)) {\n ws.mergedCells.splice(i, 1);\n return true;\n }\n }\n return false;\n}\n\n/**\n * Drop every merged range on the worksheet. Returns the count of merges\n * removed. Cells that were inside the merges keep their values — only the merge\n * metadata is gone.\n */\nexport function removeAllMergedRanges(ws: Worksheet): number {\n const n = ws.mergedCells.length;\n ws.mergedCells = [];\n return n;\n}\n\n// ---- views / freezePanes --------------------------------------------------\n\n/** Lazily get-or-create the primary SheetView so view-mutating helpers don't have to branch. */\nconst ensurePrimaryView = (ws: Worksheet): SheetView => {\n let view = ws.views[0];\n if (!view) {\n view = makeSheetView();\n ws.views.push(view);\n }\n return view;\n};\n\n/**\n * Freeze rows / columns above + left of `topLeftRef` (\"B2\" → 1 row + 1 col).\n * Pass `undefined` to clear any existing freeze. Targets the workbook's primary\n * SheetView (`ws.views[0]`); creates one if absent.\n */\nexport function setFreezePanes(ws: Worksheet, topLeftRef: string | undefined): void {\n if (topLeftRef === undefined) {\n if (ws.views[0]) delete ws.views[0].pane;\n return;\n }\n const view = ensurePrimaryView(ws);\n view.pane = makeFreezePane(topLeftRef);\n}\n\n/** Inverse of {@link setFreezePanes}; returns the top-left ref or undefined when no freeze is active. */\nexport function getFreezePanes(ws: Worksheet): string | undefined {\n const view = ws.views[0];\n if (!view) return undefined;\n return freezePaneRef(view);\n}\n\n/**\n * Freeze the top `count` rows. Equivalent to `setFreezePanes(ws, \"A${count +\n * 1}\")` — Excel's \"Freeze Top Row\" is `freezeRows(ws, 1)`.\n */\nexport function freezeRows(ws: Worksheet, count: number): void {\n if (!Number.isInteger(count) || count < 1) {\n throw new OpenXmlSchemaError(`freezeRows: count must be a positive integer; got ${count}`);\n }\n setFreezePanes(ws, `A${count + 1}`);\n}\n\n/**\n * Freeze the leftmost `count` columns. Equivalent to `setFreezePanes(ws,\n * \"${columnLetter(count + 1)}1\")` — Excel's \"Freeze First Column\" is\n * `freezeColumns(ws, 1)`.\n */\nexport function freezeColumns(ws: Worksheet, count: number): void {\n if (!Number.isInteger(count) || count < 1) {\n throw new OpenXmlSchemaError(`freezeColumns: count must be a positive integer; got ${count}`);\n }\n setFreezePanes(ws, `${columnLetterFromIndex(count + 1)}1`);\n}\n\n/** Freeze both top `rows` rows AND left `cols` columns. */\nexport function freezePanes(ws: Worksheet, rows: number, cols: number): void {\n if (!Number.isInteger(rows) || rows < 1) {\n throw new OpenXmlSchemaError(`freezePanes: rows must be a positive integer; got ${rows}`);\n }\n if (!Number.isInteger(cols) || cols < 1) {\n throw new OpenXmlSchemaError(`freezePanes: cols must be a positive integer; got ${cols}`);\n }\n setFreezePanes(ws, `${columnLetterFromIndex(cols + 1)}${rows + 1}`);\n}\n\n/** Drop the freeze pane on the primary view. */\nexport const unfreezePanes = (ws: Worksheet): void => {\n setFreezePanes(ws, undefined);\n};\n\n/**\n * Freeze the header row (row 1) so it stays visible while scrolling. Equivalent\n * to Excel's \"View → Freeze Top Row\". Shortcut for `freezeRows(ws, 1)`.\n */\nexport const freezeFirstRow = (ws: Worksheet): void => freezeRows(ws, 1);\n\n/**\n * Freeze the leftmost column (column A) so it stays visible while scrolling\n * horizontally. Equivalent to Excel's \"View → Freeze First Column\". Shortcut\n * for `freezeColumns(ws, 1)`.\n */\nexport const freezeFirstColumn = (ws: Worksheet): void => freezeColumns(ws, 1);\n\n/**\n * Freeze both row 1 and column A so the header row + label column stay visible.\n * Equivalent to selecting B2 and \"View → Freeze Panes\". Shortcut for\n * `freezePanes(ws, 1, 1)`.\n */\nexport const freezeFirstRowAndColumn = (ws: Worksheet): void => freezePanes(ws, 1, 1);\n\n// ---- sheet view display helpers -------------------------------------------\n\n/** Lazily get-or-create `ws.sheetProperties` so tab-color helpers don't have to branch. */\nconst ensureSheetProperties = (ws: Worksheet): SheetProperties => {\n if (!ws.sheetProperties) ws.sheetProperties = makeSheetProperties();\n return ws.sheetProperties;\n};\n\nconst colorFrom = (input: string | Partial<Color>): Color =>\n typeof input === 'string' ? makeColor({ rgb: input }) : makeColor(input);\n\n/**\n * Set the sheet tab strip colour. Accepts either a hex string (`\"FF0070C0\"`) or\n * a partial `Color` object (`{ theme: 4, tint: 0.4 }`).\n */\nexport function setSheetTabColor(ws: Worksheet, color: string | Partial<Color>): Color {\n const c = colorFrom(color);\n ensureSheetProperties(ws).tabColor = c;\n return c;\n}\n\n/** Drop the sheet tab strip colour. */\nexport function removeSheetTabColor(ws: Worksheet): void {\n if (!ws.sheetProperties) return;\n delete (ws.sheetProperties as { tabColor?: Color }).tabColor;\n}\n\n/** Toggle gridline display on the primary SheetView. */\nexport function setShowGridLines(ws: Worksheet, show: boolean): void {\n ensurePrimaryView(ws).showGridLines = show;\n}\n\n/** Toggle row + column header display on the primary SheetView. */\nexport function setShowRowColHeaders(ws: Worksheet, show: boolean): void {\n ensurePrimaryView(ws).showRowColHeaders = show;\n}\n\n/** Toggle \"Show Formulas\" mode on the primary SheetView. */\nexport function setShowFormulas(ws: Worksheet, show: boolean): void {\n ensurePrimaryView(ws).showFormulas = show;\n}\n\n/** Toggle \"Show a zero in cells that have a zero value\" on the primary SheetView. */\nexport function setShowZeros(ws: Worksheet, show: boolean): void {\n ensurePrimaryView(ws).showZeros = show;\n}\n\n/** Toggle right-to-left layout on the primary SheetView. */\nexport function setRightToLeft(ws: Worksheet, rtl: boolean): void {\n ensurePrimaryView(ws).rightToLeft = rtl;\n}\n\n/**\n * Set the zoom scale (percent) on the primary SheetView. Excel accepts integer\n * percentages in `[10, 400]`.\n */\nexport function setSheetZoom(ws: Worksheet, scale: number): void {\n if (!Number.isInteger(scale) || scale < 10 || scale > 400) {\n throw new OpenXmlSchemaError(`setSheetZoom: scale must be an integer in [10, 400]; got ${scale}`);\n }\n ensurePrimaryView(ws).zoomScale = scale;\n}\n\n/** Switch the sheet view between Excel's \"Normal\" / \"Page Break Preview\" / \"Page Layout\" modes. */\nexport function setSheetViewMode(ws: Worksheet, mode: 'normal' | 'pageBreakPreview' | 'pageLayout'): void {\n ensurePrimaryView(ws).view = mode;\n}\n\n/**\n * Set the active cell on the primary SheetView. The active cell is the one\n * Excel highlights with the dark border when the sheet is opened. Updates the\n * existing Selection; creates one if missing. Pass an \"A1\"-style ref.\n */\nexport function setActiveCell(ws: Worksheet, ref: string): void {\n const view = ensurePrimaryView(ws);\n const selection = view.selection ?? {};\n // Excel typically also sets sqref to the same cell when a single cell is the\n // active one. Only override sqref if it's missing or tracked the previous\n // activeCell, so explicit selections survive.\n const prevActive = selection.activeCell;\n if (selection.sqref === undefined || selection.sqref === prevActive) {\n selection.sqref = ref;\n }\n selection.activeCell = ref;\n view.selection = selection;\n}\n\n/**\n * Set the selected range (sqref) on the primary SheetView. Accepts a single\n * cell (\"A1\"), a single range (\"A1:B5\"), or a multi-cell range string (\"A1\n * C3:D4\"). Leaves activeCell untouched unless absent — in which case it's set\n * to the first ref of `sqref`.\n */\nexport function setSelectedRange(ws: Worksheet, sqref: string): void {\n const view = ensurePrimaryView(ws);\n const selection = view.selection ?? {};\n selection.sqref = sqref;\n if (selection.activeCell === undefined) {\n const first = sqref.split(/\\s+/)[0]?.split(':')[0];\n if (first) selection.activeCell = first;\n }\n view.selection = selection;\n}\n\n/**\n * Set values across a rectangular range from a 2-D array. `rows[0]` is laid\n * down starting at the top-left of `range`; subsequent rows follow. `null` /\n * `undefined` entries skip the cell. Useful for dropping a header + data block\n * in one call.\n */\nexport function setRangeValues(\n ws: Worksheet,\n range: string,\n rows: ReadonlyArray<ReadonlyArray<CellValue | null | undefined>>,\n): void {\n const { minRow, minCol } = parseRange(range);\n for (let i = 0; i < rows.length; i++) {\n const row = rows[i];\n if (!row) continue;\n for (let j = 0; j < row.length; j++) {\n const v = row[j];\n if (v === null || v === undefined) continue;\n setCell(ws, minRow + i, minCol + j, v);\n }\n }\n}\n\n/**\n * Iterate over every cell coordinate in a range, calling `visit` once per (row,\n * col). Allocates the cell on first touch so callers can mutate it freely.\n */\nexport function applyToRange(\n ws: Worksheet,\n range: string,\n visit: (cell: Cell, row: number, col: number) => void,\n): void {\n const { minRow, maxRow, minCol, maxCol } = parseRange(range);\n for (let r = minRow; r <= maxRow; r++) {\n for (let c = minCol; c <= maxCol; c++) {\n let cell = ws.rows.get(r)?.get(c);\n if (!cell) cell = setCell(ws, r, c);\n visit(cell, r, c);\n }\n }\n}\n\n/**\n * Read a rectangular range as a dense 2-D array of values. Empty cells yield\n * `null`. The shape is `[maxRow - minRow + 1] × [maxCol - minCol + 1]`. Inverse\n * of {@link setRangeValues}.\n */\nexport function getRangeValues(ws: Worksheet, range: string): (CellValue | null)[][] {\n const { minRow, maxRow, minCol, maxCol } = parseRange(range);\n const rowsOut: (CellValue | null)[][] = [];\n for (let r = minRow; r <= maxRow; r++) {\n const rowMap = ws.rows.get(r);\n const row: (CellValue | null)[] = [];\n for (let c = minCol; c <= maxCol; c++) {\n const cell = rowMap?.get(c);\n row.push(cell ? cell.value : null);\n }\n rowsOut.push(row);\n }\n return rowsOut;\n}\n\n/**\n * Copy every populated cell from `source` to `target` (within the same\n * worksheet, or across worksheets via `targetWs`). Cells are shallow-cloned:\n * `value` and `styleId` carry over but `row`/`col` are rewritten. The target's\n * existing cells in the destination extent are overwritten; cells outside are\n * untouched.\n *\n * The source and target ranges define the top-left corner — their dimensions\n * need not match. If the target range is smaller than the source, only the\n * cells that fit within the target's extent are copied; if larger, only the\n * source's extent is filled.\n *\n * Returns the number of cells copied.\n */\nexport function copyRange(\n ws: Worksheet,\n source: string,\n target: string,\n opts: { targetWs?: Worksheet } = {},\n): number {\n const dest = opts.targetWs ?? ws;\n const sameSheet = dest === ws;\n const src = parseRange(source);\n const dst = parseRange(target);\n const dr = dst.minRow - src.minRow;\n const dc = dst.minCol - src.minCol;\n const maxRowOffset = Math.min(src.maxRow - src.minRow, dst.maxRow - dst.minRow);\n const maxColOffset = Math.min(src.maxCol - src.minCol, dst.maxCol - dst.minCol);\n let n = 0;\n for (let i = 0; i <= maxRowOffset; i++) {\n const srcRow = ws.rows.get(src.minRow + i);\n if (!srcRow) continue;\n for (let j = 0; j <= maxColOffset; j++) {\n const srcCell = srcRow.get(src.minCol + j);\n if (!srcCell) continue;\n const dstRow = src.minRow + i + dr;\n const dstCol = src.minCol + j + dc;\n const newCell = setCell(dest, dstRow, dstCol, srcCell.value, srcCell.styleId);\n // hyperlinkId / commentId index into the *source* worksheet's\n // `hyperlinks` / `legacyComments` arrays. Carrying them across sheets\n // would point at unrelated entries on the destination (or a missing\n // slot), so we keep them only on a same-sheet copy. The actual link /\n // comment records aren't part of the copied range — callers needing\n // cross-sheet link semantics should re-issue setHyperlink on the dest.\n if (sameSheet) {\n if (srcCell.hyperlinkId !== undefined) newCell.hyperlinkId = srcCell.hyperlinkId;\n if (srcCell.commentId !== undefined) newCell.commentId = srcCell.commentId;\n }\n n++;\n }\n }\n return n;\n}\n\n/**\n * Move every populated cell from `source` to `target`. Equivalent to\n * `copyRange` followed by clearing the source. When the ranges overlap on the\n * same sheet, the copy walks in the direction that preserves data — high-to-low\n * along any axis where the move shifts forward, low-to-high otherwise — so\n * cells aren't overwritten before they've been read. Returns the number of\n * cells moved.\n */\nexport function moveRange(\n ws: Worksheet,\n source: string,\n target: string,\n opts: { targetWs?: Worksheet } = {},\n): number {\n const dest = opts.targetWs ?? ws;\n const sameSheet = dest === ws;\n const src = parseRange(source);\n const dst = parseRange(target);\n const dr = dst.minRow - src.minRow;\n const dc = dst.minCol - src.minCol;\n const maxRowOffset = Math.min(src.maxRow - src.minRow, dst.maxRow - dst.minRow);\n const maxColOffset = Math.min(src.maxCol - src.minCol, dst.maxCol - dst.minCol);\n // Snapshot the source cells so overlapping moves on the same sheet don't read\n // post-write values during the copy.\n const snap: Array<{ row: number; col: number; cell: Cell }> = [];\n for (let i = 0; i <= maxRowOffset; i++) {\n const srcRow = ws.rows.get(src.minRow + i);\n if (!srcRow) continue;\n for (let j = 0; j <= maxColOffset; j++) {\n const srcCell = srcRow.get(src.minCol + j);\n if (!srcCell) continue;\n snap.push({ row: src.minRow + i, col: src.minCol + j, cell: srcCell });\n }\n }\n // Clear the entire source band on the source sheet first so the pre-existing\n // source cells are gone before we land copies on top.\n for (let i = 0; i <= maxRowOffset; i++) {\n const rowIdx = src.minRow + i;\n const srcRow = ws.rows.get(rowIdx);\n if (!srcRow) continue;\n for (let j = 0; j <= maxColOffset; j++) srcRow.delete(src.minCol + j);\n if (srcRow.size === 0) ws.rows.delete(rowIdx);\n }\n // Replay the snapshot into the destination — value, styleId, and (only on\n // a same-sheet move) hyperlinkId / commentId. See copyRange for the\n // cross-sheet rationale: those indexes are scoped to the source sheet's\n // own hyperlink / comment arrays and don't translate.\n for (const entry of snap) {\n const { row, col, cell } = entry;\n const dstRow = row + dr;\n const dstCol = col + dc;\n const newCell = setCell(dest, dstRow, dstCol, cell.value, cell.styleId);\n if (sameSheet) {\n if (cell.hyperlinkId !== undefined) newCell.hyperlinkId = cell.hyperlinkId;\n if (cell.commentId !== undefined) newCell.commentId = cell.commentId;\n }\n }\n return snap.length;\n}\n\n/**\n * Read all populated values in a single column. Returns one `(CellValue |\n * null)` per row in `[minRow, maxRow]` (defaults to row 1 .. `getMaxRow(ws)`).\n * Empty cells yield `null`. Returns `[]` when the worksheet is empty.\n */\nexport function getColumnValues(\n ws: Worksheet,\n col: number,\n opts: { minRow?: number; maxRow?: number } = {},\n): (CellValue | null)[] {\n const max = getMaxRow(ws);\n if (max < 1) return [];\n const minRow = opts.minRow ?? 1;\n const maxRow = opts.maxRow ?? max;\n const out: (CellValue | null)[] = [];\n for (let r = minRow; r <= maxRow; r++) {\n const cell = ws.rows.get(r)?.get(col);\n out.push(cell ? cell.value : null);\n }\n return out;\n}\n\n/**\n * Read all populated values in a single row. Returns one `(CellValue | null)`\n * per column in `[minCol, maxCol]` (defaults to col 1 .. `getMaxCol(ws)` when\n * the row exists, otherwise `[]`).\n */\nexport function getRowValues(\n ws: Worksheet,\n row: number,\n opts: { minCol?: number; maxCol?: number } = {},\n): (CellValue | null)[] {\n const rowMap = ws.rows.get(row);\n if (!rowMap || rowMap.size === 0) {\n if (opts.minCol === undefined && opts.maxCol === undefined) return [];\n }\n const minCol = opts.minCol ?? 1;\n // Manual scan avoids `Math.max(...rowMap.keys())`. Spread into a builtin is\n // limited by the engine's argument-count cap (~125 k on V8), and `getRowValues`\n // is documented to handle every column up to MAX_COL (16384). For sparse\n // rows the spread is fine in practice; for dense rows it would silently\n // throw a stack overflow — surface the cost in a single linear scan instead.\n let derivedMax = 0;\n if (rowMap && opts.maxCol === undefined) {\n for (const c of rowMap.keys()) {\n if (c > derivedMax) derivedMax = c;\n }\n }\n const maxCol = opts.maxCol ?? derivedMax;\n if (maxCol < minCol) return [];\n const out: (CellValue | null)[] = [];\n for (let c = minCol; c <= maxCol; c++) {\n const cell = rowMap?.get(c);\n out.push(cell ? cell.value : null);\n }\n return out;\n}\n\n/**\n * Enumerate the populated cells of a row in column order. Unlike {@link\n * getRowValues}, this skips empty columns and yields the cell objects (not just\n * their values). Returns `[]` when the row is absent or empty.\n */\nexport function getCellsInRow(ws: Worksheet, row: number): Cell[] {\n const rowMap = ws.rows.get(row);\n if (!rowMap || rowMap.size === 0) return [];\n const sortedCols = [...rowMap.keys()].sort((a, b) => a - b);\n const out: Cell[] = [];\n for (const col of sortedCols) {\n const cell = rowMap.get(col);\n if (cell) out.push(cell);\n }\n return out;\n}\n\n/**\n * Enumerate the populated cells of a column in row order. Walks the row map and\n * collects whichever rows carry the column. Returns `[]` when the worksheet has\n * no cell in that column.\n */\nexport function getCellsInColumn(ws: Worksheet, col: number): Cell[] {\n const sortedRows = [...ws.rows.keys()].sort((a, b) => a - b);\n const out: Cell[] = [];\n for (const r of sortedRows) {\n const cell = ws.rows.get(r)?.get(col);\n if (cell) out.push(cell);\n }\n return out;\n}\n\n// ---- column / row dimensions ----------------------------------------------\n\n/**\n * Look up the ColumnDimension covering `col`. The search walks every registered\n * entry's `min..max` range; that's fine for the typical spreadsheet (a handful\n * of column entries) and stays simple.\n */\nexport function getColumnDimension(ws: Worksheet, col: number): ColumnDimension | undefined {\n for (const dim of ws.columnDimensions.values()) {\n if (col >= dim.min && col <= dim.max) return dim;\n }\n return undefined;\n}\n\n/**\n * Set a single-column ColumnDimension entry covering `col`. Shadows any\n * existing run that overlaps — runs are not split for now (callers that need\n * range-spanning entries can write directly into `ws.columnDimensions`).\n */\nexport function setColumnDimension(\n ws: Worksheet,\n col: number,\n opts: Partial<Omit<ColumnDimension, 'min' | 'max'>>,\n): ColumnDimension {\n validateRowCol(1, col);\n // Strip any existing entry that covers this column. Multi-col runs that\n // straddle `col` are dropped wholesale — phase-5 minimum scope.\n for (const [key, dim] of ws.columnDimensions) {\n if (col >= dim.min && col <= dim.max) ws.columnDimensions.delete(key);\n }\n const entry = makeColumnDimension(col, opts);\n ws.columnDimensions.set(col, entry);\n return entry;\n}\n\n/** Convenience: set a column's width, leaving other fields untouched. */\nexport function setColumnWidth(ws: Worksheet, col: number, width: number): ColumnDimension {\n const existing = getColumnDimension(ws, col);\n return setColumnDimension(ws, col, { ...existing, width, customWidth: true });\n}\n\n/** Convenience: hide a column. */\nexport function hideColumn(ws: Worksheet, col: number): ColumnDimension {\n const existing = getColumnDimension(ws, col);\n return setColumnDimension(ws, col, { ...existing, hidden: true });\n}\n\n/**\n * Convenience: unhide a column. Drops the `hidden` flag from the column's\n * dimension entry (and removes the entry altogether when no other fields\n * remain).\n */\nexport function unhideColumn(ws: Worksheet, col: number): void {\n const existing = getColumnDimension(ws, col);\n if (!existing) return;\n const { hidden: _drop, ...rest } = existing;\n const { min: _min, max: _max, ...passthrough } = rest;\n if (Object.keys(passthrough).length === 0) {\n ws.columnDimensions.delete(existing.min);\n } else {\n setColumnDimension(ws, col, passthrough);\n }\n}\n\n/** Bulk-hide every column in `[fromCol, toCol]`. */\nexport function hideColumns(ws: Worksheet, fromCol: number, toCol: number): void {\n if (!Number.isInteger(fromCol) || !Number.isInteger(toCol) || fromCol < 1 || toCol < fromCol) {\n throw new OpenXmlSchemaError(`hideColumns: invalid column range [${fromCol}, ${toCol}]`);\n }\n for (let c = fromCol; c <= toCol; c++) hideColumn(ws, c);\n}\n\n/** Bulk-unhide every column in `[fromCol, toCol]`. */\nexport function unhideColumns(ws: Worksheet, fromCol: number, toCol: number): void {\n if (!Number.isInteger(fromCol) || !Number.isInteger(toCol) || fromCol < 1 || toCol < fromCol) {\n throw new OpenXmlSchemaError(`unhideColumns: invalid column range [${fromCol}, ${toCol}]`);\n }\n for (let c = fromCol; c <= toCol; c++) unhideColumn(ws, c);\n}\n\n/**\n * Set the default column width (characters) for cells without an explicit\n * ColumnDimension entry. Mirrors Excel's \"Default Width\" dialog. Pass\n * `undefined` to clear.\n */\nexport function setDefaultColumnWidth(ws: Worksheet, width: number | undefined): void {\n if (width === undefined) {\n delete (ws as { defaultColumnWidth?: number }).defaultColumnWidth;\n return;\n }\n if (!Number.isFinite(width) || width < 0) {\n throw new OpenXmlSchemaError(`setDefaultColumnWidth: width must be a non-negative number; got ${width}`);\n }\n ws.defaultColumnWidth = width;\n}\n\n/**\n * Set the default row height (points) for rows without an explicit RowDimension\n * entry. Mirrors Excel's \"Default Row Height\" dialog. Pass `undefined` to\n * clear.\n */\nexport function setDefaultRowHeight(ws: Worksheet, height: number | undefined): void {\n if (height === undefined) {\n delete (ws as { defaultRowHeight?: number }).defaultRowHeight;\n return;\n }\n if (!Number.isFinite(height) || height < 0) {\n throw new OpenXmlSchemaError(`setDefaultRowHeight: height must be a non-negative number; got ${height}`);\n }\n ws.defaultRowHeight = height;\n}\n\nconst validateOutlineLevel = (level: number): void => {\n // Excel outline depth is bounded at 7 levels (Data → Group nesting cap).\n if (!Number.isInteger(level) || level < 1 || level > 7) {\n throw new OpenXmlSchemaError(`outlineLevel must be an integer in [1, 7]; got ${level}`);\n }\n};\n\n/**\n * Mirror Excel's \"Data → Group → Rows\" by stamping every row in `[fromRow,\n * toRow]` with an outline depth of `level` (default 1). Allocates a\n * RowDimension for each row that doesn't already have one. Ungroup with {@link\n * ungroupRows}.\n */\nexport function groupRows(ws: Worksheet, fromRow: number, toRow: number, level = 1): void {\n validateOutlineLevel(level);\n if (!Number.isInteger(fromRow) || !Number.isInteger(toRow) || fromRow < 1 || toRow < fromRow) {\n throw new OpenXmlSchemaError(`groupRows: invalid row range [${fromRow}, ${toRow}]`);\n }\n for (let r = fromRow; r <= toRow; r++) {\n const existing = getRowDimension(ws, r) ?? {};\n setRowDimension(ws, r, { ...existing, outlineLevel: level });\n }\n}\n\n/**\n * Drop the outline grouping for every row in `[fromRow, toRow]`. Removes the\n * `outlineLevel` field from each affected RowDimension.\n */\nexport function ungroupRows(ws: Worksheet, fromRow: number, toRow: number): void {\n if (!Number.isInteger(fromRow) || !Number.isInteger(toRow) || fromRow < 1 || toRow < fromRow) {\n throw new OpenXmlSchemaError(`ungroupRows: invalid row range [${fromRow}, ${toRow}]`);\n }\n for (let r = fromRow; r <= toRow; r++) {\n const existing = ws.rowDimensions.get(r);\n if (!existing) continue;\n const { outlineLevel: _drop, ...rest } = existing;\n if (Object.keys(rest).length === 0) ws.rowDimensions.delete(r);\n else ws.rowDimensions.set(r, rest);\n }\n}\n\n/**\n * Mirror Excel's \"Data → Group → Columns\" by stamping every column in\n * `[fromCol, toCol]` with an outline depth of `level` (default 1).\n */\nexport function groupColumns(ws: Worksheet, fromCol: number, toCol: number, level = 1): void {\n validateOutlineLevel(level);\n if (!Number.isInteger(fromCol) || !Number.isInteger(toCol) || fromCol < 1 || toCol < fromCol) {\n throw new OpenXmlSchemaError(`groupColumns: invalid column range [${fromCol}, ${toCol}]`);\n }\n for (let c = fromCol; c <= toCol; c++) {\n const existing = getColumnDimension(ws, c);\n setColumnDimension(ws, c, { ...existing, outlineLevel: level });\n }\n}\n\n/**\n * Drop the outline grouping for every column in `[fromCol, toCol]`. Removes the\n * `outlineLevel` field from each affected ColumnDimension.\n */\nexport function ungroupColumns(ws: Worksheet, fromCol: number, toCol: number): void {\n if (!Number.isInteger(fromCol) || !Number.isInteger(toCol) || fromCol < 1 || toCol < fromCol) {\n throw new OpenXmlSchemaError(`ungroupColumns: invalid column range [${fromCol}, ${toCol}]`);\n }\n for (let c = fromCol; c <= toCol; c++) {\n const existing = getColumnDimension(ws, c);\n if (!existing) continue;\n const { outlineLevel: _drop, ...rest } = existing;\n // setColumnDimension expects the partial-without-min-max shape.\n const { min: _min, max: _max, ...passthrough } = rest;\n if (Object.keys(passthrough).length === 0) {\n // Pure outline-only entry — drop it entirely.\n ws.columnDimensions.delete(existing.min);\n } else {\n setColumnDimension(ws, c, passthrough);\n }\n }\n}\n\n/**\n * Collapse a row outline group: hide every row in `[fromRow, toRow]` and mark\n * them `collapsed: true`. Mirrors Excel's `−` button on a grouped row strip.\n * Rows must already carry an `outlineLevel` from {@link groupRows} for the\n * collapse to render correctly.\n */\nexport function collapseRowGroup(ws: Worksheet, fromRow: number, toRow: number): void {\n if (!Number.isInteger(fromRow) || !Number.isInteger(toRow) || fromRow < 1 || toRow < fromRow) {\n throw new OpenXmlSchemaError(`collapseRowGroup: invalid row range [${fromRow}, ${toRow}]`);\n }\n for (let r = fromRow; r <= toRow; r++) {\n const existing = getRowDimension(ws, r) ?? {};\n setRowDimension(ws, r, { ...existing, hidden: true, collapsed: true });\n }\n}\n\n/**\n * Expand a row outline group: drop the `hidden` and `collapsed` flags on every\n * row in `[fromRow, toRow]`. Leaves `outlineLevel` and other dimensions intact.\n */\nexport function expandRowGroup(ws: Worksheet, fromRow: number, toRow: number): void {\n if (!Number.isInteger(fromRow) || !Number.isInteger(toRow) || fromRow < 1 || toRow < fromRow) {\n throw new OpenXmlSchemaError(`expandRowGroup: invalid row range [${fromRow}, ${toRow}]`);\n }\n for (let r = fromRow; r <= toRow; r++) {\n const existing = ws.rowDimensions.get(r);\n if (!existing) continue;\n const { hidden: _h, collapsed: _c, ...rest } = existing;\n if (Object.keys(rest).length === 0) ws.rowDimensions.delete(r);\n else ws.rowDimensions.set(r, rest);\n }\n}\n\n/**\n * Collapse a column outline group: hide + mark `collapsed: true` for every\n * column in `[fromCol, toCol]`. Columns must already carry an `outlineLevel`\n * from {@link groupColumns} for the collapse to render correctly.\n */\nexport function collapseColumnGroup(ws: Worksheet, fromCol: number, toCol: number): void {\n if (!Number.isInteger(fromCol) || !Number.isInteger(toCol) || fromCol < 1 || toCol < fromCol) {\n throw new OpenXmlSchemaError(`collapseColumnGroup: invalid column range [${fromCol}, ${toCol}]`);\n }\n for (let c = fromCol; c <= toCol; c++) {\n const existing = getColumnDimension(ws, c);\n setColumnDimension(ws, c, { ...existing, hidden: true, collapsed: true });\n }\n}\n\n/**\n * Expand a column outline group: drop `hidden` and `collapsed` from every\n * column in `[fromCol, toCol]`. Leaves `outlineLevel` intact.\n */\nexport function expandColumnGroup(ws: Worksheet, fromCol: number, toCol: number): void {\n if (!Number.isInteger(fromCol) || !Number.isInteger(toCol) || fromCol < 1 || toCol < fromCol) {\n throw new OpenXmlSchemaError(`expandColumnGroup: invalid column range [${fromCol}, ${toCol}]`);\n }\n for (let c = fromCol; c <= toCol; c++) {\n const existing = getColumnDimension(ws, c);\n if (!existing) continue;\n const { hidden: _h, collapsed: _coll, ...rest } = existing;\n const { min: _min, max: _max, ...passthrough } = rest;\n if (Object.keys(passthrough).length === 0) {\n ws.columnDimensions.delete(existing.min);\n } else {\n setColumnDimension(ws, c, passthrough);\n }\n }\n}\n\n/**\n * Per-cell effective string length, optionally scaled by the cell's font size\n * relative to Excel's default 11pt baseline.\n */\nconst effectiveLength = (cell: Cell, wb: { styles: { cellXfs: ReadonlyArray<{ fontId: number }>; fonts: ReadonlyArray<{ size?: number }> } } | undefined): number => {\n const len = cellValueAsString(cell.value).length;\n if (!wb) return len;\n const xf = wb.styles.cellXfs[cell.styleId];\n const fontId = xf?.fontId ?? 0;\n const font = wb.styles.fonts[fontId];\n const size = font?.size ?? 11;\n // Linear scale: 11pt → 1.0; 22pt → 2.0; etc. Excel's actual character width\n // grows roughly linearly with point size.\n return len * (size / 11);\n};\n\n/**\n * Approximate autofit for a column. Scans every populated cell in `col` (or in\n * `[opts.minRow, opts.maxRow]`), measures `cellValueAsString` length, and sets\n * the column width to `max(length) + padding`, clamped to `[opts.min ?? 4,\n * opts.max ?? 80]` and bounded above by Excel's hard limit of 255.\n *\n * Note: this is a string-length approximation — Excel sizes columns with the\n * font's actual character-width metrics. For plain ASCII in the default Calibri\n * 11 face the result is usually within ±1 width unit; CJK / wide glyphs need\n * extra padding.\n *\n * Pass `opts.workbook` (or use the `Wb` variant via `autofitColumns`) to enable\n * font-aware scaling — each cell's length is scaled by `(cellFont.size / 11)`\n * so 22pt headings get roughly 2× width.\n */\nexport function autofitColumn(\n ws: Worksheet,\n col: number,\n opts: {\n minRow?: number;\n maxRow?: number;\n padding?: number;\n min?: number;\n max?: number;\n workbook?: { styles: { cellXfs: ReadonlyArray<{ fontId: number }>; fonts: ReadonlyArray<{ size?: number }> } };\n } = {},\n): ColumnDimension | undefined {\n const padding = opts.padding ?? 2;\n const minWidth = opts.min ?? 4;\n const maxWidth = Math.min(opts.max ?? 80, 255);\n const minRow = opts.minRow ?? 1;\n const maxRow = opts.maxRow ?? getMaxRow(ws);\n if (maxRow < minRow) return undefined;\n let widest = 0;\n for (let r = minRow; r <= maxRow; r++) {\n const cell = ws.rows.get(r)?.get(col);\n if (!cell) continue;\n const len = effectiveLength(cell, opts.workbook);\n if (len > widest) widest = len;\n }\n if (widest === 0) return undefined;\n const width = Math.max(minWidth, Math.min(maxWidth, widest + padding));\n return setColumnWidth(ws, col, width);\n}\n\n/**\n * Approximate autofit for every column with at least one populated cell. Walks\n * the worksheet once collecting per-column widest-length + applies {@link\n * autofitColumn} per column. `opts.workbook` enables font-size-aware scaling;\n * without it the helper falls back to plain string length.\n */\nexport function autofitColumns(\n ws: Worksheet,\n opts: {\n padding?: number;\n min?: number;\n max?: number;\n workbook?: { styles: { cellXfs: ReadonlyArray<{ fontId: number }>; fonts: ReadonlyArray<{ size?: number }> } };\n } = {},\n): void {\n const padding = opts.padding ?? 2;\n const minWidth = opts.min ?? 4;\n const maxWidth = Math.min(opts.max ?? 80, 255);\n const widest = new Map<number, number>();\n for (const rowMap of ws.rows.values()) {\n for (const [col, cell] of rowMap) {\n const len = effectiveLength(cell, opts.workbook);\n const cur = widest.get(col) ?? 0;\n if (len > cur) widest.set(col, len);\n }\n }\n for (const [col, w] of widest) {\n if (w === 0) continue;\n setColumnWidth(ws, col, Math.max(minWidth, Math.min(maxWidth, w + padding)));\n }\n}\n\n/**\n * Set widths for many columns in one call. `widths` maps either:\n * - an array `[12, 16, 20]` interpreted positionally starting at\n * column `startCol` (default 1), or\n * - a `Record<number, number>` keyed by 1-based column index.\n * Each entry sets `customWidth: true`.\n */\nexport function setColumnWidths(\n ws: Worksheet,\n widths: ReadonlyArray<number> | Record<number, number>,\n startCol = 1,\n): void {\n if (Array.isArray(widths)) {\n for (let i = 0; i < widths.length; i++) {\n const w = widths[i];\n if (typeof w !== 'number' || !Number.isFinite(w)) continue;\n setColumnWidth(ws, startCol + i, w);\n }\n } else {\n for (const [k, w] of Object.entries(widths as Record<number, number>)) {\n const col = Number.parseInt(k, 10);\n if (!Number.isInteger(col) || col < 1) continue;\n if (typeof w !== 'number' || !Number.isFinite(w)) continue;\n setColumnWidth(ws, col, w);\n }\n }\n}\n\n/** Look up a row's dimension entry. */\nexport function getRowDimension(ws: Worksheet, row: number): RowDimension | undefined {\n return ws.rowDimensions.get(row);\n}\n\nexport function setRowDimension(ws: Worksheet, row: number, opts: Partial<RowDimension>): RowDimension {\n validateRowCol(row, 1);\n const entry = makeRowDimension(opts);\n ws.rowDimensions.set(row, entry);\n return entry;\n}\n\n/** Convenience: set a row's height, marking customHeight=true. */\nexport function setRowHeight(ws: Worksheet, row: number, height: number): RowDimension {\n const existing = getRowDimension(ws, row);\n return setRowDimension(ws, row, { ...existing, height, customHeight: true });\n}\n\n/**\n * Set heights for many rows in one call. `heights` accepts an array (positional\n * from `startRow`, default 1) or a `Record<number, number>` keyed by 1-based\n * row index. Each entry sets `customHeight: true`.\n */\nexport function setRowHeights(\n ws: Worksheet,\n heights: ReadonlyArray<number> | Record<number, number>,\n startRow = 1,\n): void {\n if (Array.isArray(heights)) {\n for (let i = 0; i < heights.length; i++) {\n const h = heights[i];\n if (typeof h !== 'number' || !Number.isFinite(h)) continue;\n setRowHeight(ws, startRow + i, h);\n }\n } else {\n for (const [k, h] of Object.entries(heights as Record<number, number>)) {\n const row = Number.parseInt(k, 10);\n if (!Number.isInteger(row) || row < 1) continue;\n if (typeof h !== 'number' || !Number.isFinite(h)) continue;\n setRowHeight(ws, row, h);\n }\n }\n}\n\n/** Convenience: hide a row. */\nexport function hideRow(ws: Worksheet, row: number): RowDimension {\n const existing = getRowDimension(ws, row);\n return setRowDimension(ws, row, { ...existing, hidden: true });\n}\n\n/**\n * Convenience: unhide a row. Drops the `hidden` flag from the row's dimension\n * entry (and removes the entry altogether when no other fields remain).\n */\nexport function unhideRow(ws: Worksheet, row: number): void {\n const existing = ws.rowDimensions.get(row);\n if (!existing) return;\n const { hidden: _drop, ...rest } = existing;\n if (Object.keys(rest).length === 0) ws.rowDimensions.delete(row);\n else ws.rowDimensions.set(row, rest);\n}\n\n/** Bulk-hide every row in `[fromRow, toRow]`. */\nexport function hideRows(ws: Worksheet, fromRow: number, toRow: number): void {\n if (!Number.isInteger(fromRow) || !Number.isInteger(toRow) || fromRow < 1 || toRow < fromRow) {\n throw new OpenXmlSchemaError(`hideRows: invalid row range [${fromRow}, ${toRow}]`);\n }\n for (let r = fromRow; r <= toRow; r++) hideRow(ws, r);\n}\n\n/** Bulk-unhide every row in `[fromRow, toRow]`. */\nexport function unhideRows(ws: Worksheet, fromRow: number, toRow: number): void {\n if (!Number.isInteger(fromRow) || !Number.isInteger(toRow) || fromRow < 1 || toRow < fromRow) {\n throw new OpenXmlSchemaError(`unhideRows: invalid row range [${fromRow}, ${toRow}]`);\n }\n for (let r = fromRow; r <= toRow; r++) unhideRow(ws, r);\n}\n\n// ---- hyperlinks -----------------------------------------------------------\n\n/**\n * Replace any prior hyperlink on the same `ref` with the given options. Pass `{\n * target }` for an external URL, `{ location }` for an internal jump, or both.\n * Returns the resulting Hyperlink record.\n */\nexport function setHyperlink(\n ws: Worksheet,\n ref: string,\n opts: { target?: string; location?: string; display?: string; tooltip?: string },\n): Hyperlink {\n if (opts.target === undefined && opts.location === undefined) {\n throw new OpenXmlSchemaError('setHyperlink: one of target / location is required');\n }\n removeHyperlink(ws, ref);\n const hl = makeHyperlink({ ref, ...opts });\n ws.hyperlinks.push(hl);\n return hl;\n}\n\n/** Remove the hyperlink registered against `ref`. Returns true if anything was removed. */\nexport function removeHyperlink(ws: Worksheet, ref: string): boolean {\n const i = ws.hyperlinks.findIndex((h) => h.ref === ref);\n if (i < 0) return false;\n ws.hyperlinks.splice(i, 1);\n return true;\n}\n\n/** Drop every hyperlink on the worksheet. Returns the count removed. */\nexport function removeAllHyperlinks(ws: Worksheet): number {\n const n = ws.hyperlinks.length;\n ws.hyperlinks = [];\n return n;\n}\n\n/** Look up a hyperlink by its ref. */\nexport function getHyperlink(ws: Worksheet, ref: string): Hyperlink | undefined {\n return ws.hyperlinks.find((h) => h.ref === ref);\n}\n\n/** Read-only snapshot of every hyperlink on the sheet. */\nexport function listHyperlinks(ws: Worksheet): ReadonlyArray<Hyperlink> {\n return ws.hyperlinks;\n}\n\n/**\n * Resolve a cell to its hyperlink (if any). Walks every hyperlink entry on the\n * worksheet and returns the first whose `ref` (a single cell `\"A1\"` or a range\n * `\"A1:B5\"`) covers the cell's coordinate. Returns `undefined` when no entry\n * matches.\n */\nexport function getCellHyperlink(ws: Worksheet, c: Cell): Hyperlink | undefined {\n for (const h of ws.hyperlinks) {\n const range = parseRange(h.ref);\n if (rangeContainsCell(range, c.row, c.col)) return h;\n }\n return undefined;\n}\n\n/**\n * Resolve a cell to its legacy comment (if any). Same matching rule as {@link\n * getCellHyperlink} — the comment's `ref` may be a single cell or a range, and\n * the first containing entry wins.\n */\nexport function getCellComment(ws: Worksheet, c: Cell): LegacyComment | undefined {\n for (const cm of ws.legacyComments) {\n const range = parseRange(cm.ref);\n if (rangeContainsCell(range, c.row, c.col)) return cm;\n }\n return undefined;\n}\n\n// ---- data validations ----------------------------------------------------\n\n/** Append a DataValidation entry. */\nexport function addDataValidation(ws: Worksheet, dv: DataValidation): DataValidation {\n ws.dataValidations.push(dv);\n return dv;\n}\n\n/** Drop every validation whose sqref overlaps `ref` (string parse). Returns count removed. */\nexport function removeDataValidations(ws: Worksheet, predicate: (dv: DataValidation) => boolean): number {\n const before = ws.dataValidations.length;\n ws.dataValidations = ws.dataValidations.filter((dv) => !predicate(dv));\n return before - ws.dataValidations.length;\n}\n\n/** Read-only snapshot of every data validation block on the sheet. */\nexport function listDataValidations(ws: Worksheet): ReadonlyArray<DataValidation> {\n return ws.dataValidations;\n}\n\n/** Drop every data validation block on the worksheet. Returns the count removed. */\nexport function removeAllDataValidations(ws: Worksheet): number {\n const n = ws.dataValidations.length;\n ws.dataValidations = [];\n return n;\n}\n\n// ---- autoFilter ----------------------------------------------------------\n\n/** Set or replace the worksheet's AutoFilter. Pass `undefined` to clear. */\nexport function setAutoFilter(ws: Worksheet, filter: AutoFilter | undefined): void {\n if (filter === undefined) {\n delete ws.autoFilter;\n return;\n }\n ws.autoFilter = filter;\n}\n\n/** Read the current AutoFilter, if any. */\nexport function getAutoFilter(ws: Worksheet): AutoFilter | undefined {\n return ws.autoFilter;\n}\n\n// ---- tables --------------------------------------------------------------\n\n/** Append a table. The id and displayName must be workbook-unique — the caller is responsible. */\nexport function addTable(ws: Worksheet, table: TableDefinition): TableDefinition {\n ws.tables.push(table);\n return table;\n}\n\n/** Look up a table by displayName. */\nexport function getTable(ws: Worksheet, displayName: string): TableDefinition | undefined {\n return ws.tables.find((t) => t.displayName === displayName);\n}\n\n/** Read-only snapshot of every Excel table defined on the sheet. */\nexport function listTables(ws: Worksheet): ReadonlyArray<TableDefinition> {\n return ws.tables;\n}\n\n/** Drop a table by displayName. Returns true when something was removed. */\nexport function removeTable(ws: Worksheet, displayName: string): boolean {\n const i = ws.tables.findIndex((t) => t.displayName === displayName);\n if (i < 0) return false;\n ws.tables.splice(i, 1);\n return true;\n}\n\n/** Drop every Excel table on the worksheet. Returns the count removed. */\nexport function removeAllTables(ws: Worksheet): number {\n const n = ws.tables.length;\n ws.tables = [];\n return n;\n}\n\n// ---- legacy comments -----------------------------------------------------\n\n/** Add or replace the comment at `ref`. */\nexport function setComment(ws: Worksheet, opts: { ref: string; author: string; text: string }): LegacyComment {\n const i = ws.legacyComments.findIndex((c) => c.ref === opts.ref);\n const c = makeLegacyComment(opts);\n if (i < 0) ws.legacyComments.push(c);\n else ws.legacyComments[i] = c;\n return c;\n}\n\nexport function getComment(ws: Worksheet, ref: string): LegacyComment | undefined {\n return ws.legacyComments.find((c) => c.ref === ref);\n}\n\nexport function removeComment(ws: Worksheet, ref: string): boolean {\n const i = ws.legacyComments.findIndex((c) => c.ref === ref);\n if (i < 0) return false;\n ws.legacyComments.splice(i, 1);\n return true;\n}\n\n/** Read-only snapshot of every legacy comment on the sheet. */\nexport function listComments(ws: Worksheet): ReadonlyArray<LegacyComment> {\n return ws.legacyComments;\n}\n\n/** Drop every legacy comment on the worksheet. Returns the count removed. */\nexport function removeAllComments(ws: Worksheet): number {\n const n = ws.legacyComments.length;\n ws.legacyComments = [];\n return n;\n}\n\n/**\n * Replace just the text of an existing comment, leaving its ref and author\n * untouched. Returns `true` when the comment was found.\n */\nexport function editCommentText(ws: Worksheet, ref: string, newText: string): boolean {\n const i = ws.legacyComments.findIndex((c) => c.ref === ref);\n if (i < 0) return false;\n const c = ws.legacyComments[i];\n if (!c) return false;\n ws.legacyComments[i] = makeLegacyComment({ ref: c.ref, author: c.author, text: newText });\n return true;\n}\n\n/**\n * Replace just the author of an existing comment, leaving its ref and text\n * untouched. Returns `true` when the comment was found.\n */\nexport function editCommentAuthor(ws: Worksheet, ref: string, newAuthor: string): boolean {\n const i = ws.legacyComments.findIndex((c) => c.ref === ref);\n if (i < 0) return false;\n const c = ws.legacyComments[i];\n if (!c) return false;\n ws.legacyComments[i] = makeLegacyComment({ ref: c.ref, author: newAuthor, text: c.text });\n return true;\n}\n\n/**\n * Rename every comment authored by `oldName` to `newName`. Returns the number\n * of comments updated. Useful when consolidating comments after a team handoff\n * (Excel's commentsN.xml dedups authors at save time, so a single rename\n * collapses cleanly).\n */\nexport function renameCommentAuthor(ws: Worksheet, oldName: string, newName: string): number {\n let n = 0;\n for (let i = 0; i < ws.legacyComments.length; i++) {\n const c = ws.legacyComments[i];\n if (c && c.author === oldName) {\n ws.legacyComments[i] = makeLegacyComment({ ref: c.ref, author: newName, text: c.text });\n n++;\n }\n }\n return n;\n}\n\n/** Filter every legacy comment by author. */\nexport function findCommentsByAuthor(ws: Worksheet, author: string): ReadonlyArray<LegacyComment> {\n return ws.legacyComments.filter((c) => c.author === author);\n}\n\n// ---- conditional formatting ----------------------------------------------\n\n/** Append a conditional formatting block. */\nexport function addConditionalFormatting(ws: Worksheet, cf: ConditionalFormatting): ConditionalFormatting {\n ws.conditionalFormatting.push(cf);\n return cf;\n}\n\n/** All conditional formatting blocks (read-only view). */\nexport function getConditionalFormatting(ws: Worksheet): ReadonlyArray<ConditionalFormatting> {\n return ws.conditionalFormatting;\n}\n\n/** Drop every conditional-formatting block on the worksheet. Returns the count removed. */\nexport function removeAllConditionalFormatting(ws: Worksheet): number {\n const n = ws.conditionalFormatting.length;\n ws.conditionalFormatting = [];\n return n;\n}\n\n// ---- cell watches / ignored errors --------------------------------------\n\n/** Pin a cell to the Watch Window. Returns the pushed entry. */\nexport function addCellWatch(ws: Worksheet, watch: CellWatch): CellWatch {\n ws.cellWatches.push(watch);\n return watch;\n}\n\n/** Remove cell watches matching `predicate`. Returns the count removed. */\nexport function removeCellWatches(ws: Worksheet, predicate: (w: CellWatch) => boolean): number {\n const before = ws.cellWatches.length;\n ws.cellWatches = ws.cellWatches.filter((w) => !predicate(w));\n return before - ws.cellWatches.length;\n}\n\n/** Append an ignored-error region. */\nexport function addIgnoredError(ws: Worksheet, ie: IgnoredError): IgnoredError {\n ws.ignoredErrors.push(ie);\n return ie;\n}\n\n/** Remove ignored-error entries matching `predicate`. Returns the count removed. */\nexport function removeIgnoredErrors(ws: Worksheet, predicate: (ie: IgnoredError) => boolean): number {\n const before = ws.ignoredErrors.length;\n ws.ignoredErrors = ws.ignoredErrors.filter((ie) => !predicate(ie));\n return before - ws.ignoredErrors.length;\n}\n"],"mappings":"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"}
|