@alosha/xlsx 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3663 @@
1
+ import { zipSync, unzipSync } from 'fflate';
2
+
3
+ // src/errors.ts
4
+ var AloshaXlsxError = class extends Error {
5
+ constructor(message) {
6
+ super(message);
7
+ this.name = new.target.name;
8
+ Object.setPrototypeOf(this, new.target.prototype);
9
+ }
10
+ };
11
+ function isAloshaXlsxError(e) {
12
+ return e instanceof AloshaXlsxError;
13
+ }
14
+ var InvalidAddressError = class extends AloshaXlsxError {
15
+ constructor(address) {
16
+ super(`Invalid cell address: ${JSON.stringify(address)}`);
17
+ this.address = address;
18
+ }
19
+ address;
20
+ code = "INVALID_ADDRESS";
21
+ };
22
+ var InvalidRangeError = class extends AloshaXlsxError {
23
+ constructor(range) {
24
+ super(`Invalid range: ${JSON.stringify(range)}`);
25
+ this.range = range;
26
+ }
27
+ range;
28
+ code = "INVALID_RANGE";
29
+ };
30
+ var InvalidWorksheetNameError = class _InvalidWorksheetNameError extends AloshaXlsxError {
31
+ constructor(worksheetName, reason) {
32
+ super(_InvalidWorksheetNameError.messageFor(worksheetName, reason));
33
+ this.worksheetName = worksheetName;
34
+ this.reason = reason;
35
+ }
36
+ worksheetName;
37
+ reason;
38
+ code = "INVALID_WORKSHEET_NAME";
39
+ static messageFor(name, reason) {
40
+ switch (reason) {
41
+ case "empty":
42
+ return "Worksheet name cannot be empty.";
43
+ case "edge-quote":
44
+ return `Worksheet name cannot start or end with a single quote: ${JSON.stringify(name)}`;
45
+ case "illegal-characters":
46
+ return `Worksheet name ${JSON.stringify(name)} cannot include any of: * ? : \\ / [ ]`;
47
+ }
48
+ }
49
+ };
50
+ var ReservedWorksheetNameError = class extends AloshaXlsxError {
51
+ constructor(worksheetName) {
52
+ super(`Worksheet name is reserved and cannot be used: ${JSON.stringify(worksheetName)}`);
53
+ this.worksheetName = worksheetName;
54
+ }
55
+ worksheetName;
56
+ code = "RESERVED_WORKSHEET_NAME";
57
+ };
58
+ var DuplicateWorksheetNameError = class extends AloshaXlsxError {
59
+ constructor(worksheetName) {
60
+ super(`Worksheet name already exists: ${JSON.stringify(worksheetName)}`);
61
+ this.worksheetName = worksheetName;
62
+ }
63
+ worksheetName;
64
+ code = "DUPLICATE_WORKSHEET_NAME";
65
+ };
66
+ var WorksheetNameTooLongError = class _WorksheetNameTooLongError extends AloshaXlsxError {
67
+ constructor(worksheetName, maxLength = _WorksheetNameTooLongError.MAX_LENGTH) {
68
+ super(
69
+ `Worksheet name exceeds ${maxLength} characters (got ${worksheetName.length}): ${JSON.stringify(worksheetName)}`
70
+ );
71
+ this.worksheetName = worksheetName;
72
+ this.maxLength = maxLength;
73
+ }
74
+ worksheetName;
75
+ maxLength;
76
+ code = "WORKSHEET_NAME_TOO_LONG";
77
+ /** Excel's hard cap on sheet-name length. */
78
+ static MAX_LENGTH = 31;
79
+ };
80
+ var MergeConflictError = class extends AloshaXlsxError {
81
+ constructor(range) {
82
+ super(`Cannot merge cells: range ${JSON.stringify(range)} overlaps an existing merge.`);
83
+ this.range = range;
84
+ }
85
+ range;
86
+ code = "MERGE_CONFLICT";
87
+ };
88
+ var InvalidRowNumberError = class extends AloshaXlsxError {
89
+ constructor(expected, actual) {
90
+ super(`Invalid row number in model: expected ${expected}, got ${actual}.`);
91
+ this.expected = expected;
92
+ this.actual = actual;
93
+ }
94
+ expected;
95
+ actual;
96
+ code = "INVALID_ROW_NUMBER";
97
+ };
98
+ var InvalidCellValueError = class _InvalidCellValueError extends AloshaXlsxError {
99
+ constructor(value) {
100
+ super(`Unsupported cell value: ${_InvalidCellValueError.describe(value)}`);
101
+ this.value = value;
102
+ }
103
+ value;
104
+ code = "INVALID_CELL_VALUE";
105
+ static describe(value) {
106
+ const t = value === null ? "null" : typeof value;
107
+ return t === "object" ? `object ${Object.prototype.toString.call(value)}` : `${t} (${String(value)})`;
108
+ }
109
+ };
110
+ var UnsupportedFeatureError = class extends AloshaXlsxError {
111
+ constructor(feature, detail) {
112
+ super(
113
+ detail === void 0 ? `Feature not yet supported in @alosha/xlsx: ${feature}` : `${feature}: ${detail}`
114
+ );
115
+ this.feature = feature;
116
+ this.detail = detail;
117
+ }
118
+ feature;
119
+ detail;
120
+ code = "UNSUPPORTED_FEATURE";
121
+ };
122
+ var InvalidPackageError = class extends AloshaXlsxError {
123
+ constructor(reason) {
124
+ super(`Invalid .xlsx package: ${reason}`);
125
+ this.reason = reason;
126
+ }
127
+ reason;
128
+ code = "INVALID_PACKAGE";
129
+ };
130
+
131
+ // src/model/enums.ts
132
+ var CellType = /* @__PURE__ */ ((CellType2) => {
133
+ CellType2[CellType2["Null"] = 0] = "Null";
134
+ CellType2[CellType2["Number"] = 1] = "Number";
135
+ CellType2[CellType2["String"] = 2] = "String";
136
+ CellType2[CellType2["Boolean"] = 3] = "Boolean";
137
+ CellType2[CellType2["Date"] = 4] = "Date";
138
+ CellType2[CellType2["Error"] = 5] = "Error";
139
+ CellType2[CellType2["RichText"] = 6] = "RichText";
140
+ CellType2[CellType2["Hyperlink"] = 7] = "Hyperlink";
141
+ CellType2[CellType2["Formula"] = 8] = "Formula";
142
+ CellType2[CellType2["Merge"] = 9] = "Merge";
143
+ CellType2[CellType2["SharedString"] = 10] = "SharedString";
144
+ return CellType2;
145
+ })(CellType || {});
146
+ var FormulaType = /* @__PURE__ */ ((FormulaType2) => {
147
+ FormulaType2[FormulaType2["None"] = 0] = "None";
148
+ FormulaType2[FormulaType2["Master"] = 1] = "Master";
149
+ FormulaType2[FormulaType2["Shared"] = 2] = "Shared";
150
+ return FormulaType2;
151
+ })(FormulaType || {});
152
+
153
+ // src/model/cell-value.ts
154
+ function detectType(v) {
155
+ if (v === null) return 0 /* Null */;
156
+ if (typeof v === "string") return 2 /* String */;
157
+ if (typeof v === "number") return 1 /* Number */;
158
+ if (typeof v === "boolean") return 3 /* Boolean */;
159
+ if (v instanceof Date) return 4 /* Date */;
160
+ if ("text" in v && "hyperlink" in v) return 7 /* Hyperlink */;
161
+ if ("formula" in v || "sharedFormula" in v) return 8 /* Formula */;
162
+ if ("richText" in v) return 6 /* RichText */;
163
+ if ("error" in v) return 5 /* Error */;
164
+ throw new InvalidCellValueError(v);
165
+ }
166
+ function toStored(v) {
167
+ switch (detectType(v)) {
168
+ case 0 /* Null */:
169
+ return { type: 0 /* Null */ };
170
+ case 2 /* String */:
171
+ return { type: 2 /* String */, value: v };
172
+ case 1 /* Number */:
173
+ return { type: 1 /* Number */, value: v };
174
+ case 3 /* Boolean */:
175
+ return { type: 3 /* Boolean */, value: v };
176
+ case 4 /* Date */:
177
+ return { type: 4 /* Date */, value: v };
178
+ case 7 /* Hyperlink */:
179
+ return { type: 7 /* Hyperlink */, value: v };
180
+ case 8 /* Formula */:
181
+ return { type: 8 /* Formula */, value: v };
182
+ case 6 /* RichText */:
183
+ return { type: 6 /* RichText */, value: v };
184
+ case 5 /* Error */:
185
+ return { type: 5 /* Error */, value: v };
186
+ default:
187
+ throw new InvalidCellValueError(v);
188
+ }
189
+ }
190
+ function fromStored(s) {
191
+ switch (s.type) {
192
+ case 0 /* Null */:
193
+ case 9 /* Merge */:
194
+ case 10 /* SharedString */:
195
+ return null;
196
+ case 1 /* Number */:
197
+ case 2 /* String */:
198
+ case 3 /* Boolean */:
199
+ case 4 /* Date */:
200
+ case 5 /* Error */:
201
+ case 6 /* RichText */:
202
+ case 7 /* Hyperlink */:
203
+ case 8 /* Formula */:
204
+ return s.value;
205
+ }
206
+ }
207
+ function effectiveType(s) {
208
+ if (s.type !== 8 /* Formula */) return s.type;
209
+ const { result } = s.value;
210
+ if (result === void 0) return 0 /* Null */;
211
+ if (typeof result === "number") return 1 /* Number */;
212
+ if (typeof result === "string") return 2 /* String */;
213
+ if (typeof result === "boolean") return 3 /* Boolean */;
214
+ if (result instanceof Date) return 4 /* Date */;
215
+ return 5 /* Error */;
216
+ }
217
+ function primitiveToText(value) {
218
+ if (typeof value === "number") return String(value);
219
+ if (typeof value === "string") return value;
220
+ if (typeof value === "boolean") return value ? "TRUE" : "FALSE";
221
+ if (value instanceof Date) return value.toISOString();
222
+ return value.error;
223
+ }
224
+ function toText(s) {
225
+ switch (s.type) {
226
+ case 0 /* Null */:
227
+ case 9 /* Merge */:
228
+ case 10 /* SharedString */:
229
+ return "";
230
+ case 1 /* Number */:
231
+ case 2 /* String */:
232
+ case 3 /* Boolean */:
233
+ case 4 /* Date */:
234
+ case 5 /* Error */:
235
+ return primitiveToText(s.value);
236
+ case 6 /* RichText */:
237
+ return s.value.richText.map((run) => run.text).join("");
238
+ case 7 /* Hyperlink */:
239
+ return s.value.text;
240
+ case 8 /* Formula */: {
241
+ const { result } = s.value;
242
+ return result === void 0 ? "" : primitiveToText(result);
243
+ }
244
+ }
245
+ }
246
+ var CSV_SPECIAL_RE = /["\n\r,]/;
247
+ function toCsv(s) {
248
+ const text = toText(s);
249
+ if (!CSV_SPECIAL_RE.test(text)) return text;
250
+ return `"${text.replace(/"/g, '""')}"`;
251
+ }
252
+
253
+ // src/model/style.ts
254
+ function mergeField(colField, rowField, cellField) {
255
+ if (colField === void 0 && rowField === void 0 && cellField === void 0) {
256
+ return void 0;
257
+ }
258
+ return { ...colField, ...rowField, ...cellField };
259
+ }
260
+ function resolveCellStyle(rowStyle, colStyle, cellStyle) {
261
+ const result = {};
262
+ const numFmt = cellStyle?.numFmt ?? rowStyle?.numFmt ?? colStyle?.numFmt;
263
+ if (numFmt !== void 0) result.numFmt = numFmt;
264
+ const font = mergeField(colStyle?.font, rowStyle?.font, cellStyle?.font);
265
+ if (font !== void 0) result.font = font;
266
+ const alignment = mergeField(colStyle?.alignment, rowStyle?.alignment, cellStyle?.alignment);
267
+ if (alignment !== void 0) result.alignment = alignment;
268
+ const protection = mergeField(colStyle?.protection, rowStyle?.protection, cellStyle?.protection);
269
+ if (protection !== void 0) result.protection = protection;
270
+ const border = mergeField(colStyle?.border, rowStyle?.border, cellStyle?.border);
271
+ if (border !== void 0) result.border = border;
272
+ const fill = cellStyle?.fill ?? rowStyle?.fill ?? colStyle?.fill;
273
+ if (fill !== void 0) result.fill = fill;
274
+ return result;
275
+ }
276
+
277
+ // src/model/cell.ts
278
+ var Cell = class {
279
+ constructor(rowRef, columnRef, address) {
280
+ this.rowRef = rowRef;
281
+ this.columnRef = columnRef;
282
+ this.address = address;
283
+ this._master = this;
284
+ this._style = resolveCellStyle(rowRef.style, columnRef.style);
285
+ }
286
+ rowRef;
287
+ columnRef;
288
+ address;
289
+ _stored = { type: 0 /* Null */ };
290
+ _style;
291
+ _master;
292
+ get row() {
293
+ return this.rowRef.number;
294
+ }
295
+ get col() {
296
+ return this.columnRef.number;
297
+ }
298
+ get $col$row() {
299
+ return `$${this.columnRef.letter}$${this.rowRef.number}`;
300
+ }
301
+ /** The stored value this cell resolves through: itself, or (if merged) its master. */
302
+ get resolvedStored() {
303
+ return this.isMerged ? this._master.resolvedStored : this._stored;
304
+ }
305
+ get value() {
306
+ return fromStored(this.resolvedStored);
307
+ }
308
+ set value(v) {
309
+ if (this.isMerged) {
310
+ this._master.value = v;
311
+ return;
312
+ }
313
+ this._stored = toStored(v);
314
+ }
315
+ /** This cell's own marker type — `Merge` for a slave, even though `value`/`text` delegate. */
316
+ get type() {
317
+ return this._stored.type;
318
+ }
319
+ get effectiveType() {
320
+ return effectiveType(this.resolvedStored);
321
+ }
322
+ get text() {
323
+ return toText(this.resolvedStored);
324
+ }
325
+ toString() {
326
+ return this.text;
327
+ }
328
+ toCsvString() {
329
+ return toCsv(this.resolvedStored);
330
+ }
331
+ get isMerged() {
332
+ return this._master !== this;
333
+ }
334
+ /** The master cell of this cell's merge region; itself if unmerged. */
335
+ get master() {
336
+ return this._master;
337
+ }
338
+ merge(master, ignoreStyle = false) {
339
+ this._master = master;
340
+ this._stored = { type: 9 /* Merge */, master: master.address };
341
+ if (!ignoreStyle) this._style = master.style;
342
+ }
343
+ unmerge() {
344
+ this._master = this;
345
+ this._stored = { type: 0 /* Null */ };
346
+ }
347
+ get formula() {
348
+ const s = this.resolvedStored;
349
+ return s.type === 8 /* Formula */ ? s.value.formula : void 0;
350
+ }
351
+ get result() {
352
+ const s = this.resolvedStored;
353
+ return s.type === 8 /* Formula */ ? s.value.result : void 0;
354
+ }
355
+ get formulaType() {
356
+ const s = this.resolvedStored;
357
+ if (s.type !== 8 /* Formula */) return 0 /* None */;
358
+ return s.value.sharedFormula !== void 0 ? 2 /* Shared */ : 1 /* Master */;
359
+ }
360
+ get style() {
361
+ return this._style;
362
+ }
363
+ set style(s) {
364
+ this._style = s;
365
+ }
366
+ get numFmt() {
367
+ return this._style.numFmt;
368
+ }
369
+ set numFmt(v) {
370
+ this._style = { ...this._style, numFmt: v };
371
+ }
372
+ get font() {
373
+ return this._style.font;
374
+ }
375
+ set font(v) {
376
+ this._style = { ...this._style, font: v };
377
+ }
378
+ get alignment() {
379
+ return this._style.alignment;
380
+ }
381
+ set alignment(v) {
382
+ this._style = { ...this._style, alignment: v };
383
+ }
384
+ get border() {
385
+ return this._style.border;
386
+ }
387
+ set border(v) {
388
+ this._style = { ...this._style, border: v };
389
+ }
390
+ get fill() {
391
+ return this._style.fill;
392
+ }
393
+ set fill(v) {
394
+ this._style = { ...this._style, fill: v };
395
+ }
396
+ get protection() {
397
+ return this._style.protection;
398
+ }
399
+ set protection(v) {
400
+ this._style = { ...this._style, protection: v };
401
+ }
402
+ get model() {
403
+ const m = { address: this.address, type: this.type };
404
+ switch (this._stored.type) {
405
+ case 0 /* Null */:
406
+ case 9 /* Merge */:
407
+ break;
408
+ case 8 /* Formula */:
409
+ if (this._stored.value.formula !== void 0) m.formula = this._stored.value.formula;
410
+ if (this._stored.value.result !== void 0) m.result = this._stored.value.result;
411
+ break;
412
+ default:
413
+ m.value = fromStored(this._stored);
414
+ }
415
+ if (Object.keys(this._style).length > 0) m.style = this._style;
416
+ return m;
417
+ }
418
+ set model(m) {
419
+ this._master = this;
420
+ switch (m.type) {
421
+ case 9 /* Merge */:
422
+ this._stored = { type: 9 /* Merge */, master: this.address };
423
+ break;
424
+ case 8 /* Formula */:
425
+ this._stored = toStored({
426
+ formula: m.formula,
427
+ result: m.result
428
+ });
429
+ break;
430
+ case 0 /* Null */:
431
+ this._stored = { type: 0 /* Null */ };
432
+ break;
433
+ default:
434
+ this.value = m.value;
435
+ }
436
+ this._style = m.style ?? {};
437
+ }
438
+ };
439
+
440
+ // src/address/col-cache.ts
441
+ var MAX_ROW = 1048576;
442
+ var MAX_COL = 16384;
443
+ var LETTER_RE = /^[A-Za-z]+$/;
444
+ var ADDRESS_RE = /^([A-Za-z]+)(\d+)$/;
445
+ var SHEET_PREFIX_RE = /^(?:'([^']*)'|([^'!]+))!/;
446
+ var CELL_REF_RE = /^\$?([A-Za-z]+)\$?(\d+)$/;
447
+ var colLetterToNumberCache = /* @__PURE__ */ new Map();
448
+ var colNumberToLetterCache = /* @__PURE__ */ new Map();
449
+ var decodeAddressCache = /* @__PURE__ */ new Map();
450
+ function colLetterToNumber(letter) {
451
+ const cached = colLetterToNumberCache.get(letter);
452
+ if (cached !== void 0) return cached;
453
+ if (!LETTER_RE.test(letter)) {
454
+ throw new InvalidAddressError(letter);
455
+ }
456
+ const upper = letter.toUpperCase();
457
+ let col = 0;
458
+ for (let i = 0; i < upper.length; i++) {
459
+ col = col * 26 + (upper.charCodeAt(i) - 64);
460
+ }
461
+ colLetterToNumberCache.set(letter, col);
462
+ return col;
463
+ }
464
+ function colNumberToLetter(col) {
465
+ const cached = colNumberToLetterCache.get(col);
466
+ if (cached !== void 0) return cached;
467
+ if (!Number.isInteger(col) || col < 1) {
468
+ throw new InvalidAddressError(String(col));
469
+ }
470
+ let n = col;
471
+ let letters = "";
472
+ while (n > 0) {
473
+ const rem = (n - 1) % 26;
474
+ letters = String.fromCharCode(65 + rem) + letters;
475
+ n = Math.floor((n - 1) / 26);
476
+ }
477
+ colNumberToLetterCache.set(col, letters);
478
+ return letters;
479
+ }
480
+ function encodeAddress(row, col) {
481
+ return `${colNumberToLetter(col)}${row}`;
482
+ }
483
+ function decodeAddress(address) {
484
+ const cached = decodeAddressCache.get(address);
485
+ if (cached !== void 0) return cached;
486
+ const match = ADDRESS_RE.exec(address);
487
+ if (!match) {
488
+ throw new InvalidAddressError(address);
489
+ }
490
+ const [, letters, digits] = match;
491
+ const col = colLetterToNumber(letters);
492
+ const row = Number.parseInt(digits, 10);
493
+ if (row < 1 || row > MAX_ROW || col < 1 || col > MAX_COL) {
494
+ throw new InvalidAddressError(address);
495
+ }
496
+ const decoded = { row, col, address: `${letters.toUpperCase()}${row}` };
497
+ decodeAddressCache.set(address, decoded);
498
+ return decoded;
499
+ }
500
+ function decodeEx(address) {
501
+ let sheetName;
502
+ let rest = address;
503
+ const sheetMatch = SHEET_PREFIX_RE.exec(address);
504
+ if (sheetMatch) {
505
+ sheetName = sheetMatch[1] ?? sheetMatch[2];
506
+ rest = address.slice(sheetMatch[0].length);
507
+ }
508
+ const cellMatch = CELL_REF_RE.exec(rest);
509
+ if (!cellMatch) {
510
+ throw new InvalidAddressError(address);
511
+ }
512
+ const [, letters, digits] = cellMatch;
513
+ const decoded = decodeAddress(`${letters}${digits}`);
514
+ return {
515
+ ...decoded,
516
+ $col$row: `$${colNumberToLetter(decoded.col)}$${decoded.row}`,
517
+ ...sheetName !== void 0 ? { sheetName } : {}
518
+ };
519
+ }
520
+ function validateAddress(address) {
521
+ decodeAddress(address);
522
+ }
523
+
524
+ // src/address/range.ts
525
+ function isDecodedLike(value) {
526
+ return typeof value === "object" && value !== null && !(value instanceof Range) && typeof value.row === "number" && typeof value.col === "number" && typeof value.address === "string";
527
+ }
528
+ function assertValidBox(box, source) {
529
+ for (const n of [box.top, box.left, box.bottom, box.right]) {
530
+ if (!Number.isInteger(n) || n < 1) {
531
+ throw new InvalidRangeError(source);
532
+ }
533
+ }
534
+ }
535
+ function decodeTwoRefs(a, b, source) {
536
+ try {
537
+ const d1 = decodeEx(a);
538
+ const d2 = decodeEx(b);
539
+ return {
540
+ top: d1.row,
541
+ left: d1.col,
542
+ bottom: d2.row,
543
+ right: d2.col,
544
+ sheetName: d1.sheetName ?? d2.sheetName
545
+ };
546
+ } catch {
547
+ throw new InvalidRangeError(source);
548
+ }
549
+ }
550
+ function parseRangeString(source) {
551
+ const parts = source.split(":");
552
+ if (parts.length === 1) {
553
+ return decodeTwoRefs(parts[0], parts[0], source);
554
+ }
555
+ if (parts.length === 2) {
556
+ const [p0, p1] = parts;
557
+ if (p0 === "" || p1 === "") throw new InvalidRangeError(source);
558
+ return decodeTwoRefs(p0, p1, source);
559
+ }
560
+ throw new InvalidRangeError(source);
561
+ }
562
+ function resolveSource(source) {
563
+ if (source instanceof Range) {
564
+ return {
565
+ top: source.top,
566
+ left: source.left,
567
+ bottom: source.bottom,
568
+ right: source.right,
569
+ sheetName: source.sheetName
570
+ };
571
+ }
572
+ if (typeof source === "string") {
573
+ return parseRangeString(source);
574
+ }
575
+ if (Array.isArray(source)) {
576
+ if (source.length === 4 && source.every((n) => typeof n === "number")) {
577
+ const [top, left, bottom, right] = source;
578
+ return { top, left, bottom, right };
579
+ }
580
+ if (source.length === 2 && source.every((s) => typeof s === "string")) {
581
+ const [a, b] = source;
582
+ return decodeTwoRefs(a, b, source);
583
+ }
584
+ throw new InvalidRangeError(source);
585
+ }
586
+ if (isDecodedLike(source)) {
587
+ return { top: source.row, left: source.col, bottom: source.row, right: source.col };
588
+ }
589
+ throw new InvalidRangeError(source);
590
+ }
591
+ var Range = class {
592
+ top;
593
+ left;
594
+ bottom;
595
+ right;
596
+ sheetName;
597
+ constructor(sourceOrTop, left, bottom, right) {
598
+ let box;
599
+ if (sourceOrTop === void 0) {
600
+ box = { top: 1, left: 1, bottom: 1, right: 1 };
601
+ } else if (typeof sourceOrTop === "number") {
602
+ if (left === void 0 || bottom === void 0 || right === void 0) {
603
+ throw new InvalidRangeError([sourceOrTop, left, bottom, right]);
604
+ }
605
+ box = { top: sourceOrTop, left, bottom, right };
606
+ assertValidBox(box, [sourceOrTop, left, bottom, right]);
607
+ } else {
608
+ box = resolveSource(sourceOrTop);
609
+ assertValidBox(box, sourceOrTop);
610
+ }
611
+ this.top = Math.min(box.top, box.bottom);
612
+ this.bottom = Math.max(box.top, box.bottom);
613
+ this.left = Math.min(box.left, box.right);
614
+ this.right = Math.max(box.left, box.right);
615
+ if (box.sheetName !== void 0) this.sheetName = box.sheetName;
616
+ }
617
+ /** Top-left address, e.g. 'A1'. */
618
+ get tl() {
619
+ return encodeAddress(this.top, this.left);
620
+ }
621
+ /** Bottom-right address, e.g. 'B2'. */
622
+ get br() {
623
+ return encodeAddress(this.bottom, this.right);
624
+ }
625
+ /** 'A1:B2'. */
626
+ get range() {
627
+ return `${this.tl}:${this.br}`;
628
+ }
629
+ /** Total cell count covered by the box. */
630
+ get count() {
631
+ return (this.bottom - this.top + 1) * (this.right - this.left + 1);
632
+ }
633
+ /** Grows the box to include the given box (union of bounds). */
634
+ expand(top, left, bottom, right) {
635
+ this.top = Math.min(this.top, top);
636
+ this.left = Math.min(this.left, left);
637
+ this.bottom = Math.max(this.bottom, bottom);
638
+ this.right = Math.max(this.right, right);
639
+ }
640
+ /** Whether the given address falls within this box. */
641
+ contains(address) {
642
+ const d = decodeEx(address);
643
+ return d.row >= this.top && d.row <= this.bottom && d.col >= this.left && d.col <= this.right;
644
+ }
645
+ /** Whether this box overlaps another box. */
646
+ intersects(other) {
647
+ return this.left <= other.right && other.left <= this.right && this.top <= other.bottom && other.top <= this.bottom;
648
+ }
649
+ /** Visits every address in the box, row-major (row-by-row, left-to-right within a row). */
650
+ forEachAddress(cb) {
651
+ for (let row = this.top; row <= this.bottom; row++) {
652
+ for (let col = this.left; col <= this.right; col++) {
653
+ cb(encodeAddress(row, col), row, col);
654
+ }
655
+ }
656
+ }
657
+ };
658
+
659
+ // src/model/column.ts
660
+ var DEFAULT_COLUMN_WIDTH = 9;
661
+ function deepEqual(a, b) {
662
+ if (a === b) return true;
663
+ if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) return false;
664
+ const aKeys = Object.keys(a);
665
+ const bKeys = Object.keys(b);
666
+ if (aKeys.length !== bKeys.length) return false;
667
+ return aKeys.every(
668
+ (key) => deepEqual(a[key], b[key])
669
+ );
670
+ }
671
+ var Column = class _Column {
672
+ constructor(host, number, defn) {
673
+ this.host = host;
674
+ this.number = number;
675
+ if (defn) {
676
+ if (defn.key !== void 0) this.key = defn.key;
677
+ if (defn.width !== void 0) this.width = defn.width;
678
+ if (defn.hidden !== void 0) this.hidden = defn.hidden;
679
+ if (defn.outlineLevel !== void 0) this.outlineLevel = defn.outlineLevel;
680
+ if (defn.style !== void 0) this._style = defn.style;
681
+ if (defn.header !== void 0) this.header = defn.header;
682
+ }
683
+ }
684
+ host;
685
+ number;
686
+ key;
687
+ width;
688
+ hidden = false;
689
+ outlineLevel = 0;
690
+ _header;
691
+ _style = {};
692
+ get letter() {
693
+ return colNumberToLetter(this.number);
694
+ }
695
+ get collapsed() {
696
+ return this.outlineLevel > this.host.properties.outlineLevelCol;
697
+ }
698
+ get isCustomWidth() {
699
+ return this.width !== void 0 && this.width !== DEFAULT_COLUMN_WIDTH;
700
+ }
701
+ get isDefault() {
702
+ return !this.isCustomWidth && !this.hidden && this.outlineLevel === 0 && this.key === void 0 && this._header === void 0 && Object.keys(this._style).length === 0;
703
+ }
704
+ get header() {
705
+ return this._header;
706
+ }
707
+ /** Writes the header text(s) into this column's top cell(s): row 1 for a string, rows 1..N
708
+ * for a string array (SPEC §6 — "header assignment writes the top row cells' values"). */
709
+ set header(h) {
710
+ this._header = h;
711
+ if (h === void 0) return;
712
+ const lines = Array.isArray(h) ? h : [h];
713
+ lines.forEach((text, i) => {
714
+ this.host.getRow(i + 1).getCell(this.number).value = text;
715
+ });
716
+ }
717
+ get values() {
718
+ const result = [];
719
+ this.host.eachRow((row, n) => {
720
+ const cell = row.findCell(this.number);
721
+ if (cell) result[n] = cell.value;
722
+ });
723
+ return result;
724
+ }
725
+ set values(vals) {
726
+ vals.forEach((val, i) => {
727
+ if (i === 0 || val === void 0) return;
728
+ this.host.getRow(i).getCell(this.number).value = val;
729
+ });
730
+ }
731
+ eachCell(optsOrCb, maybeCb) {
732
+ const includeEmpty = typeof optsOrCb === "object" ? optsOrCb.includeEmpty : false;
733
+ const cb = typeof optsOrCb === "function" ? optsOrCb : maybeCb;
734
+ this.host.eachRow({ includeEmpty }, (row, n) => {
735
+ const cell = includeEmpty ? row.getCell(this.number) : row.findCell(this.number);
736
+ if (cell) cb(cell, n);
737
+ });
738
+ }
739
+ applyToCells(fn) {
740
+ this.eachCell(fn);
741
+ }
742
+ get style() {
743
+ return this._style;
744
+ }
745
+ set style(s) {
746
+ this._style = s;
747
+ this.applyToCells((cell) => {
748
+ cell.style = s;
749
+ });
750
+ }
751
+ get numFmt() {
752
+ return this._style.numFmt;
753
+ }
754
+ set numFmt(v) {
755
+ this._style = { ...this._style, numFmt: v };
756
+ this.applyToCells((cell) => {
757
+ cell.numFmt = v;
758
+ });
759
+ }
760
+ get font() {
761
+ return this._style.font;
762
+ }
763
+ set font(v) {
764
+ this._style = { ...this._style, font: v };
765
+ this.applyToCells((cell) => {
766
+ cell.font = v;
767
+ });
768
+ }
769
+ get alignment() {
770
+ return this._style.alignment;
771
+ }
772
+ set alignment(v) {
773
+ this._style = { ...this._style, alignment: v };
774
+ this.applyToCells((cell) => {
775
+ cell.alignment = v;
776
+ });
777
+ }
778
+ get border() {
779
+ return this._style.border;
780
+ }
781
+ set border(v) {
782
+ this._style = { ...this._style, border: v };
783
+ this.applyToCells((cell) => {
784
+ cell.border = v;
785
+ });
786
+ }
787
+ get fill() {
788
+ return this._style.fill;
789
+ }
790
+ set fill(v) {
791
+ this._style = { ...this._style, fill: v };
792
+ this.applyToCells((cell) => {
793
+ cell.fill = v;
794
+ });
795
+ }
796
+ get protection() {
797
+ return this._style.protection;
798
+ }
799
+ set protection(v) {
800
+ this._style = { ...this._style, protection: v };
801
+ this.applyToCells((cell) => {
802
+ cell.protection = v;
803
+ });
804
+ }
805
+ get defn() {
806
+ const d = {};
807
+ if (this.key !== void 0) d.key = this.key;
808
+ if (this._header !== void 0) d.header = this._header;
809
+ if (this.width !== void 0) d.width = this.width;
810
+ if (this.hidden) d.hidden = true;
811
+ if (this.outlineLevel !== 0) d.outlineLevel = this.outlineLevel;
812
+ if (Object.keys(this._style).length > 0) d.style = this._style;
813
+ return d;
814
+ }
815
+ set defn(d) {
816
+ this.key = d.key;
817
+ this.width = d.width;
818
+ this.hidden = d.hidden ?? false;
819
+ this.outlineLevel = d.outlineLevel ?? 0;
820
+ this._style = d.style ?? {};
821
+ this.header = d.header;
822
+ }
823
+ /** Whether two columns share the same OOXML-relevant attributes (used to compress runs). */
824
+ equivalentTo(other) {
825
+ return this.width === other.width && this.hidden === other.hidden && this.outlineLevel === other.outlineLevel && deepEqual(this._style, other._style);
826
+ }
827
+ static rangeOf(start, end) {
828
+ const range = { min: start.number, max: end.number };
829
+ if (start.width !== void 0) range.width = start.width;
830
+ if (start.hidden) range.hidden = true;
831
+ if (start.outlineLevel !== 0) range.outlineLevel = start.outlineLevel;
832
+ if (Object.keys(start._style).length > 0) range.style = start._style;
833
+ return range;
834
+ }
835
+ /** Run-length compress an array of Columns into `<col min max>` ranges. */
836
+ static toModel(columns) {
837
+ if (columns.length === 0) return void 0;
838
+ const sorted = [...columns].sort((a, b) => a.number - b.number);
839
+ const ranges = [];
840
+ let start = sorted[0];
841
+ let prev = start;
842
+ for (let i = 1; i < sorted.length; i++) {
843
+ const col = sorted[i];
844
+ if (col.number === prev.number + 1 && col.equivalentTo(prev)) {
845
+ prev = col;
846
+ continue;
847
+ }
848
+ ranges.push(_Column.rangeOf(start, prev));
849
+ start = col;
850
+ prev = col;
851
+ }
852
+ ranges.push(_Column.rangeOf(start, prev));
853
+ return ranges;
854
+ }
855
+ /** Expands `<col min max>` ranges back into individual Columns. */
856
+ static fromModel(host, cols) {
857
+ if (cols.length === 0) return null;
858
+ const columns = [];
859
+ for (const range of cols) {
860
+ for (let n = range.min; n <= range.max; n++) {
861
+ columns.push(
862
+ new _Column(host, n, {
863
+ width: range.width,
864
+ hidden: range.hidden,
865
+ outlineLevel: range.outlineLevel,
866
+ style: range.style
867
+ })
868
+ );
869
+ }
870
+ }
871
+ return columns;
872
+ }
873
+ };
874
+
875
+ // src/model/row.ts
876
+ var Row = class {
877
+ constructor(worksheet, number) {
878
+ this.worksheet = worksheet;
879
+ this.number = number;
880
+ }
881
+ worksheet;
882
+ number;
883
+ height;
884
+ hidden = false;
885
+ outlineLevel = 0;
886
+ /** Sparse, 1-indexed by column number; index 0 is never assigned. */
887
+ _cells = [];
888
+ _style = {};
889
+ get collapsed() {
890
+ return this.outlineLevel > this.worksheet.properties.outlineLevelRow;
891
+ }
892
+ resolveColNumber(col) {
893
+ if (typeof col === "number") return col;
894
+ const byKey = this.worksheet.getColumnKey(col);
895
+ if (byKey) return byKey.number;
896
+ return colLetterToNumber(col);
897
+ }
898
+ getCell(col) {
899
+ const colNumber = this.resolveColNumber(col);
900
+ const existing = this._cells[colNumber];
901
+ if (existing) return existing;
902
+ const column = this.worksheet.getColumn(colNumber);
903
+ const cell = new Cell(this, column, encodeAddress(this.number, colNumber));
904
+ this._cells[colNumber] = cell;
905
+ return cell;
906
+ }
907
+ findCell(col) {
908
+ return this._cells[col];
909
+ }
910
+ eachCell(optsOrCb, maybeCb) {
911
+ const includeEmpty = typeof optsOrCb === "object" ? optsOrCb.includeEmpty : false;
912
+ const cb = typeof optsOrCb === "function" ? optsOrCb : maybeCb;
913
+ if (includeEmpty) {
914
+ const max = this._cells.length - 1;
915
+ for (let col = 1; col <= max; col++) {
916
+ cb(this.getCell(col), col);
917
+ }
918
+ } else {
919
+ this._cells.forEach((cell, col) => {
920
+ cb(cell, col);
921
+ });
922
+ }
923
+ }
924
+ get hasValues() {
925
+ return this._cells.some((cell) => cell !== void 0 && cell.type !== 0 /* Null */);
926
+ }
927
+ get cellCount() {
928
+ return Math.max(this._cells.length - 1, 0);
929
+ }
930
+ get actualCellCount() {
931
+ let count = 0;
932
+ for (const cell of this._cells) if (cell !== void 0) count++;
933
+ return count;
934
+ }
935
+ get dimensions() {
936
+ let min = Number.POSITIVE_INFINITY;
937
+ let max = Number.NEGATIVE_INFINITY;
938
+ this._cells.forEach((_cell, col) => {
939
+ if (col < min) min = col;
940
+ if (col > max) max = col;
941
+ });
942
+ return min === Number.POSITIVE_INFINITY ? null : { min, max };
943
+ }
944
+ get values() {
945
+ const arr = [];
946
+ this._cells.forEach((cell, col) => {
947
+ arr[col] = cell.value;
948
+ });
949
+ return arr;
950
+ }
951
+ set values(v) {
952
+ this._cells = [];
953
+ if (v === void 0 || v === null) return;
954
+ if (Array.isArray(v)) {
955
+ const offset = v[0] !== void 0 ? 1 : 0;
956
+ v.forEach((val, index) => {
957
+ if (val === void 0) return;
958
+ const col = index + offset;
959
+ if (col < 1) return;
960
+ this.getCell(col).value = val;
961
+ });
962
+ return;
963
+ }
964
+ for (const [key, val] of Object.entries(v)) {
965
+ this.getCell(key).value = val;
966
+ }
967
+ }
968
+ splice(start, count, ...inserts) {
969
+ const currentMax = this._cells.length - 1;
970
+ const insertCount = inserts.length;
971
+ const tail = [];
972
+ for (let col = start + count; col <= currentMax; col++) {
973
+ const cell = this._cells[col];
974
+ tail[col - (start + count)] = cell ? { value: cell.value, style: cell.style } : void 0;
975
+ }
976
+ this._cells.length = Math.min(this._cells.length, start);
977
+ inserts.forEach((val, i) => {
978
+ this.getCell(start + i).value = val;
979
+ });
980
+ tail.forEach((entry, i) => {
981
+ if (!entry) return;
982
+ const cell = this.getCell(start + insertCount + i);
983
+ cell.value = entry.value;
984
+ cell.style = entry.style;
985
+ });
986
+ }
987
+ applyToCells(fn) {
988
+ this._cells.forEach((cell) => {
989
+ fn(cell);
990
+ });
991
+ }
992
+ get style() {
993
+ return this._style;
994
+ }
995
+ set style(s) {
996
+ this._style = s;
997
+ this.applyToCells((cell) => {
998
+ cell.style = s;
999
+ });
1000
+ }
1001
+ get numFmt() {
1002
+ return this._style.numFmt;
1003
+ }
1004
+ set numFmt(v) {
1005
+ this._style = { ...this._style, numFmt: v };
1006
+ this.applyToCells((cell) => {
1007
+ cell.numFmt = v;
1008
+ });
1009
+ }
1010
+ get font() {
1011
+ return this._style.font;
1012
+ }
1013
+ set font(v) {
1014
+ this._style = { ...this._style, font: v };
1015
+ this.applyToCells((cell) => {
1016
+ cell.font = v;
1017
+ });
1018
+ }
1019
+ get alignment() {
1020
+ return this._style.alignment;
1021
+ }
1022
+ set alignment(v) {
1023
+ this._style = { ...this._style, alignment: v };
1024
+ this.applyToCells((cell) => {
1025
+ cell.alignment = v;
1026
+ });
1027
+ }
1028
+ get border() {
1029
+ return this._style.border;
1030
+ }
1031
+ set border(v) {
1032
+ this._style = { ...this._style, border: v };
1033
+ this.applyToCells((cell) => {
1034
+ cell.border = v;
1035
+ });
1036
+ }
1037
+ get fill() {
1038
+ return this._style.fill;
1039
+ }
1040
+ set fill(v) {
1041
+ this._style = { ...this._style, fill: v };
1042
+ this.applyToCells((cell) => {
1043
+ cell.fill = v;
1044
+ });
1045
+ }
1046
+ get protection() {
1047
+ return this._style.protection;
1048
+ }
1049
+ set protection(v) {
1050
+ this._style = { ...this._style, protection: v };
1051
+ this.applyToCells((cell) => {
1052
+ cell.protection = v;
1053
+ });
1054
+ }
1055
+ get model() {
1056
+ const cells = [];
1057
+ this._cells.forEach((cell) => {
1058
+ cells.push(cell.model);
1059
+ });
1060
+ const m = { number: this.number, cells };
1061
+ if (this.height !== void 0) m.height = this.height;
1062
+ if (this.hidden) m.hidden = true;
1063
+ if (this.outlineLevel !== 0) m.outlineLevel = this.outlineLevel;
1064
+ if (Object.keys(this._style).length > 0) m.style = this._style;
1065
+ return m;
1066
+ }
1067
+ set model(m) {
1068
+ if (m.number !== this.number) {
1069
+ throw new InvalidRowNumberError(this.number, m.number);
1070
+ }
1071
+ this._cells = [];
1072
+ this.height = m.height;
1073
+ this.hidden = m.hidden ?? false;
1074
+ this.outlineLevel = m.outlineLevel ?? 0;
1075
+ this._style = m.style ?? {};
1076
+ for (const cellModel of m.cells) {
1077
+ const col = decodeAddress(cellModel.address).col;
1078
+ this.getCell(col).model = cellModel;
1079
+ }
1080
+ }
1081
+ };
1082
+
1083
+ // src/model/worksheet.ts
1084
+ var ILLEGAL_NAME_CHARS = /[*?:\\/[\]]/;
1085
+ function validateWorksheetNameFormat(name) {
1086
+ if (name.length === 0) throw new InvalidWorksheetNameError(name, "empty");
1087
+ if (name.length > WorksheetNameTooLongError.MAX_LENGTH) throw new WorksheetNameTooLongError(name);
1088
+ if (ILLEGAL_NAME_CHARS.test(name))
1089
+ throw new InvalidWorksheetNameError(name, "illegal-characters");
1090
+ if (name.startsWith("'") || name.endsWith("'")) {
1091
+ throw new InvalidWorksheetNameError(name, "edge-quote");
1092
+ }
1093
+ if (name.toLowerCase() === "history") throw new ReservedWorksheetNameError(name);
1094
+ }
1095
+ function normalizeMergeArgs(cells) {
1096
+ if (cells.length === 1) return new Range(cells[0]);
1097
+ if (cells.length === 2 && typeof cells[0] === "string" && typeof cells[1] === "string") {
1098
+ return new Range([cells[0], cells[1]]);
1099
+ }
1100
+ if (cells.length === 4 && cells.every((c) => typeof c === "number")) {
1101
+ return new Range(
1102
+ cells[0],
1103
+ cells[1],
1104
+ cells[2],
1105
+ cells[3]
1106
+ );
1107
+ }
1108
+ throw new InvalidRangeError(cells);
1109
+ }
1110
+ var Worksheet = class {
1111
+ orderNo;
1112
+ state = "visible";
1113
+ workbook;
1114
+ properties;
1115
+ views = [];
1116
+ pageSetup;
1117
+ headerFooter;
1118
+ _id;
1119
+ _name;
1120
+ _rows = /* @__PURE__ */ new Map();
1121
+ _columns = /* @__PURE__ */ new Map();
1122
+ _columnsByKey = /* @__PURE__ */ new Map();
1123
+ /** Active merge regions keyed by their master (top-left) cell address. */
1124
+ _merges = /* @__PURE__ */ new Map();
1125
+ constructor(workbook, id, name, orderNo) {
1126
+ this.workbook = workbook;
1127
+ this._id = id;
1128
+ this._name = name;
1129
+ this.orderNo = orderNo;
1130
+ this.properties = {
1131
+ outlineLevelCol: 0,
1132
+ outlineLevelRow: 0,
1133
+ defaultRowHeight: 15,
1134
+ dyDescent: 55
1135
+ };
1136
+ }
1137
+ // --- identity ---------------------------------------------------------------------------------
1138
+ get id() {
1139
+ return this._id;
1140
+ }
1141
+ get name() {
1142
+ return this._name;
1143
+ }
1144
+ set name(value) {
1145
+ validateWorksheetNameFormat(value);
1146
+ const lower = value.toLowerCase();
1147
+ for (const ws of this.workbook.worksheets) {
1148
+ if (ws !== this && ws.name.toLowerCase() === lower) {
1149
+ throw new DuplicateWorksheetNameError(value);
1150
+ }
1151
+ }
1152
+ this._name = value;
1153
+ }
1154
+ // --- rows -------------------------------------------------------------------------------------
1155
+ getRow(row) {
1156
+ let r = this._rows.get(row);
1157
+ if (!r) {
1158
+ r = new Row(this, row);
1159
+ this._rows.set(row, r);
1160
+ }
1161
+ return r;
1162
+ }
1163
+ getRows(start, length) {
1164
+ if (length < 1) return void 0;
1165
+ const rows = [];
1166
+ for (let i = 0; i < length; i++) rows.push(this.getRow(start + i));
1167
+ return rows;
1168
+ }
1169
+ findRow(row) {
1170
+ return this._rows.get(row);
1171
+ }
1172
+ addRow(data, options) {
1173
+ const row = this.getRow(this.rowCount + 1);
1174
+ row.values = data;
1175
+ this.applyInheritance(row, options);
1176
+ return row;
1177
+ }
1178
+ addRows(rows, options) {
1179
+ return rows.map((data) => this.addRow(data, options));
1180
+ }
1181
+ insertRow(pos, value, options) {
1182
+ this.spliceRows(pos, 0, value);
1183
+ const row = this.getRow(pos);
1184
+ this.applyInheritance(row, options);
1185
+ return row;
1186
+ }
1187
+ applyInheritance(row, options) {
1188
+ if (!options?.inheritFrom) return;
1189
+ const sourceNumber = options.inheritFrom === "above" ? row.number - 1 : row.number + 1;
1190
+ const source = this._rows.get(sourceNumber);
1191
+ if (!source) return;
1192
+ row.style = source.style;
1193
+ source.eachCell({ includeEmpty: options.includeEmpty ?? false }, (cell, col) => {
1194
+ row.getCell(col).style = cell.style;
1195
+ });
1196
+ }
1197
+ duplicateRow(rowNum, count, insert = false) {
1198
+ const snapshot = this.snapshotRow(this.getRow(rowNum));
1199
+ if (insert) {
1200
+ const blanks = Array.from({ length: count }, () => []);
1201
+ this.spliceRows(rowNum + 1, 0, ...blanks);
1202
+ }
1203
+ for (let i = 1; i <= count; i++) this.restoreRow(rowNum + i, snapshot);
1204
+ }
1205
+ spliceRows(start, count, ...inserts) {
1206
+ const delta = inserts.length - count;
1207
+ const oldMerges = [...this._merges.values()].map((r) => ({
1208
+ top: r.top,
1209
+ left: r.left,
1210
+ bottom: r.bottom,
1211
+ right: r.right
1212
+ }));
1213
+ const snapshots = /* @__PURE__ */ new Map();
1214
+ for (const [num2, row] of this._rows) snapshots.set(num2, this.snapshotRow(row));
1215
+ this._rows.clear();
1216
+ this._merges.clear();
1217
+ for (const [num2, snap] of snapshots) {
1218
+ if (num2 < start) {
1219
+ this.restoreRow(num2, snap);
1220
+ } else if (num2 >= start + count) {
1221
+ this.restoreRow(num2 + delta, snap);
1222
+ }
1223
+ }
1224
+ inserts.forEach((values, i) => {
1225
+ this.getRow(start + i).values = values;
1226
+ });
1227
+ for (const m of oldMerges) {
1228
+ if (m.top >= start + count) {
1229
+ this.applyMerge(new Range(m.top + delta, m.left, m.bottom + delta, m.right));
1230
+ } else if (m.bottom < start) {
1231
+ this.applyMerge(new Range(m.top, m.left, m.bottom, m.right));
1232
+ }
1233
+ }
1234
+ }
1235
+ snapshotRow(row) {
1236
+ const cells = [];
1237
+ row.eachCell((cell, col) => {
1238
+ cells.push({ col, value: cell.value, style: cell.style });
1239
+ });
1240
+ return {
1241
+ height: row.height,
1242
+ hidden: row.hidden,
1243
+ outlineLevel: row.outlineLevel,
1244
+ style: row.style,
1245
+ cells
1246
+ };
1247
+ }
1248
+ restoreRow(num2, snap) {
1249
+ const row = this.getRow(num2);
1250
+ row.height = snap.height;
1251
+ row.hidden = snap.hidden;
1252
+ row.outlineLevel = snap.outlineLevel;
1253
+ row.style = snap.style;
1254
+ for (const c of snap.cells) {
1255
+ const cell = row.getCell(c.col);
1256
+ cell.value = c.value;
1257
+ cell.style = c.style;
1258
+ }
1259
+ }
1260
+ eachRow(optsOrCb, maybeCb) {
1261
+ const includeEmpty = typeof optsOrCb === "object" ? optsOrCb.includeEmpty : false;
1262
+ const cb = typeof optsOrCb === "function" ? optsOrCb : maybeCb;
1263
+ if (includeEmpty) {
1264
+ const max = this.rowCount;
1265
+ for (let n = 1; n <= max; n++) cb(this.getRow(n), n);
1266
+ } else {
1267
+ const sorted = [...this._rows.entries()].sort((a, b) => a[0] - b[0]);
1268
+ for (const [n, row] of sorted) cb(row, n);
1269
+ }
1270
+ }
1271
+ getSheetValues() {
1272
+ const result = [];
1273
+ this.eachRow((row, n) => {
1274
+ result[n] = row.values;
1275
+ });
1276
+ return result;
1277
+ }
1278
+ get rowCount() {
1279
+ let max = 0;
1280
+ for (const n of this._rows.keys()) if (n > max) max = n;
1281
+ return max;
1282
+ }
1283
+ get actualRowCount() {
1284
+ let count = 0;
1285
+ for (const row of this._rows.values()) if (row.hasValues) count++;
1286
+ return count;
1287
+ }
1288
+ get lastRow() {
1289
+ const rc = this.rowCount;
1290
+ return rc >= 1 ? this._rows.get(rc) : void 0;
1291
+ }
1292
+ // --- columns ----------------------------------------------------------------------------------
1293
+ get columns() {
1294
+ const count = this.columnCount;
1295
+ const arr = [];
1296
+ for (let n = 1; n <= count; n++) arr.push(this.getColumn(n));
1297
+ return arr;
1298
+ }
1299
+ set columns(defns) {
1300
+ defns.forEach((defn, i) => {
1301
+ const col = this.getColumn(i + 1);
1302
+ col.defn = { ...col.defn, ...defn };
1303
+ if (defn.key !== void 0) this._columnsByKey.set(defn.key, col);
1304
+ });
1305
+ }
1306
+ getColumn(idOrKey) {
1307
+ if (typeof idOrKey === "number") return this.getOrCreateColumn(idOrKey);
1308
+ const byKey = this._columnsByKey.get(idOrKey);
1309
+ if (byKey) return byKey;
1310
+ return this.getOrCreateColumn(colLetterToNumber(idOrKey));
1311
+ }
1312
+ getOrCreateColumn(n) {
1313
+ let c = this._columns.get(n);
1314
+ if (!c) {
1315
+ c = new Column(this, n);
1316
+ this._columns.set(n, c);
1317
+ }
1318
+ return c;
1319
+ }
1320
+ get columnCount() {
1321
+ let max = 0;
1322
+ for (const n of this._columns.keys()) if (n > max) max = n;
1323
+ this.eachRow((row) => {
1324
+ const d = row.dimensions;
1325
+ if (d && d.max > max) max = d.max;
1326
+ });
1327
+ return max;
1328
+ }
1329
+ get actualColumnCount() {
1330
+ const cols = /* @__PURE__ */ new Set();
1331
+ this.eachRow((row) => {
1332
+ row.eachCell((cell, col) => {
1333
+ if (cell.type !== 0 /* Null */) cols.add(col);
1334
+ });
1335
+ });
1336
+ return cols.size;
1337
+ }
1338
+ get lastColumn() {
1339
+ const cc = this.columnCount;
1340
+ return cc >= 1 ? this.getColumn(cc) : void 0;
1341
+ }
1342
+ spliceColumns(start, count, ...inserts) {
1343
+ const delta = inserts.length - count;
1344
+ this.eachRow((row) => {
1345
+ const rowInserts = inserts.map((colVals) => colVals[row.number] ?? null);
1346
+ row.splice(start, count, ...rowInserts);
1347
+ });
1348
+ const oldColumns = [...this._columns.entries()];
1349
+ this._columns.clear();
1350
+ this._columnsByKey.clear();
1351
+ for (const [n, col] of oldColumns) {
1352
+ let newNumber;
1353
+ if (n < start) newNumber = n;
1354
+ else if (n >= start + count) newNumber = n + delta;
1355
+ else continue;
1356
+ const moved = new Column(this, newNumber, col.defn);
1357
+ this._columns.set(newNumber, moved);
1358
+ if (moved.key !== void 0) this._columnsByKey.set(moved.key, moved);
1359
+ }
1360
+ const oldMerges = [...this._merges.values()].map((r) => ({
1361
+ top: r.top,
1362
+ left: r.left,
1363
+ bottom: r.bottom,
1364
+ right: r.right
1365
+ }));
1366
+ this._merges.clear();
1367
+ for (const m of oldMerges) {
1368
+ if (m.left >= start + count) {
1369
+ this.applyMerge(new Range(m.top, m.left + delta, m.bottom, m.right + delta));
1370
+ } else if (m.right < start) {
1371
+ this.applyMerge(new Range(m.top, m.left, m.bottom, m.right));
1372
+ }
1373
+ }
1374
+ }
1375
+ // --- column keys ------------------------------------------------------------------------------
1376
+ getColumnKey(key) {
1377
+ return this._columnsByKey.get(key);
1378
+ }
1379
+ setColumnKey(key, column) {
1380
+ column.key = key;
1381
+ this._columnsByKey.set(key, column);
1382
+ }
1383
+ deleteColumnKey(key) {
1384
+ const col = this._columnsByKey.get(key);
1385
+ if (col) col.key = void 0;
1386
+ this._columnsByKey.delete(key);
1387
+ }
1388
+ eachColumnKey(cb) {
1389
+ for (const [key, col] of this._columnsByKey) cb(col, key);
1390
+ }
1391
+ // --- cells ------------------------------------------------------------------------------------
1392
+ getCell(r, c) {
1393
+ if (c === void 0) {
1394
+ const d = decodeAddress(r);
1395
+ return this.getRow(d.row).getCell(d.col);
1396
+ }
1397
+ return this.getRow(r).getCell(c);
1398
+ }
1399
+ findCell(r, c) {
1400
+ let rowNum;
1401
+ let colNum;
1402
+ if (c === void 0) {
1403
+ const d = decodeAddress(r);
1404
+ rowNum = d.row;
1405
+ colNum = d.col;
1406
+ } else {
1407
+ rowNum = r;
1408
+ colNum = this.toColNumber(c);
1409
+ }
1410
+ const row = this._rows.get(rowNum);
1411
+ return row?.findCell(colNum);
1412
+ }
1413
+ toColNumber(col) {
1414
+ if (typeof col === "number") return col;
1415
+ const byKey = this._columnsByKey.get(col);
1416
+ if (byKey) return byKey.number;
1417
+ return colLetterToNumber(col);
1418
+ }
1419
+ // --- merges -----------------------------------------------------------------------------------
1420
+ mergeCells(...cells) {
1421
+ const range = normalizeMergeArgs(cells);
1422
+ for (const existing of this._merges.values()) {
1423
+ if (range.intersects(existing)) throw new MergeConflictError(range.range);
1424
+ }
1425
+ this.applyMerge(range);
1426
+ }
1427
+ unMergeCells(...cells) {
1428
+ const range = normalizeMergeArgs(cells);
1429
+ for (const [key, existing] of [...this._merges.entries()]) {
1430
+ if (!range.intersects(existing)) continue;
1431
+ existing.forEachAddress((_addr, row, col) => {
1432
+ if (row === existing.top && col === existing.left) return;
1433
+ this.getRow(row).getCell(col).unmerge();
1434
+ });
1435
+ this._merges.delete(key);
1436
+ }
1437
+ }
1438
+ /** Links the slave cells of `range` to its top-left master and records the region. */
1439
+ applyMerge(range) {
1440
+ const master = this.getCell(range.top, range.left);
1441
+ range.forEachAddress((_addr, row, col) => {
1442
+ if (row === range.top && col === range.left) return;
1443
+ this.getRow(row).getCell(col).merge(master);
1444
+ });
1445
+ this._merges.set(master.address, range);
1446
+ }
1447
+ get hasMerges() {
1448
+ return this._merges.size > 0;
1449
+ }
1450
+ get dimensions() {
1451
+ let top = Number.POSITIVE_INFINITY;
1452
+ let left = Number.POSITIVE_INFINITY;
1453
+ let bottom = Number.NEGATIVE_INFINITY;
1454
+ let right = Number.NEGATIVE_INFINITY;
1455
+ this.eachRow((row, n) => {
1456
+ const d = row.dimensions;
1457
+ if (!d) return;
1458
+ if (n < top) top = n;
1459
+ if (n > bottom) bottom = n;
1460
+ if (d.min < left) left = d.min;
1461
+ if (d.max > right) right = d.max;
1462
+ });
1463
+ if (top === Number.POSITIVE_INFINITY) return new Range(1, 1, 1, 1);
1464
+ return new Range(top, left, bottom, right);
1465
+ }
1466
+ // --- model ------------------------------------------------------------------------------------
1467
+ get model() {
1468
+ const rows = [...this._rows.entries()].sort((a, b) => a[0] - b[0]).map(([, row]) => row.model);
1469
+ const columns = Column.toModel([...this._columns.values()]);
1470
+ const m = {
1471
+ id: this._id,
1472
+ name: this._name,
1473
+ orderNo: this.orderNo,
1474
+ state: this.state,
1475
+ properties: { ...this.properties },
1476
+ views: this.views.map((v) => ({ ...v })),
1477
+ rows,
1478
+ merges: [...this._merges.values()].map((r) => r.range)
1479
+ };
1480
+ if (columns) m.columns = columns;
1481
+ if (this.pageSetup !== void 0) m.pageSetup = this.pageSetup;
1482
+ if (this.headerFooter !== void 0) m.headerFooter = this.headerFooter;
1483
+ return m;
1484
+ }
1485
+ set model(m) {
1486
+ this._id = m.id;
1487
+ this._name = m.name;
1488
+ this.orderNo = m.orderNo;
1489
+ this.state = m.state;
1490
+ this.properties = { ...m.properties };
1491
+ this.views = m.views.map((v) => ({ ...v }));
1492
+ this.pageSetup = m.pageSetup;
1493
+ this.headerFooter = m.headerFooter;
1494
+ this._rows.clear();
1495
+ this._columns.clear();
1496
+ this._columnsByKey.clear();
1497
+ this._merges.clear();
1498
+ if (m.columns) {
1499
+ const cols = Column.fromModel(this, m.columns) ?? [];
1500
+ for (const col of cols) {
1501
+ this._columns.set(col.number, col);
1502
+ if (col.key !== void 0) this._columnsByKey.set(col.key, col);
1503
+ }
1504
+ }
1505
+ for (const rowModel of m.rows) {
1506
+ this.getRow(rowModel.number).model = rowModel;
1507
+ }
1508
+ for (const mergeStr of m.merges) this.applyMerge(new Range(mergeStr));
1509
+ }
1510
+ };
1511
+
1512
+ // src/model/workbook.ts
1513
+ var Workbook = class {
1514
+ creator;
1515
+ lastModifiedBy;
1516
+ created;
1517
+ modified;
1518
+ lastPrinted;
1519
+ title;
1520
+ subject;
1521
+ keywords;
1522
+ category;
1523
+ description;
1524
+ company;
1525
+ manager;
1526
+ properties = {};
1527
+ calcProperties = {};
1528
+ views = [];
1529
+ _byId = /* @__PURE__ */ new Map();
1530
+ _sheets = [];
1531
+ _nextId = 1;
1532
+ constructor() {
1533
+ const now = /* @__PURE__ */ new Date();
1534
+ this.created = now;
1535
+ this.modified = now;
1536
+ }
1537
+ /** Ordered, O(n). A fresh copy so callers cannot mutate the backing order. */
1538
+ get worksheets() {
1539
+ return [...this._sheets];
1540
+ }
1541
+ addWorksheet(name, options) {
1542
+ const resolvedName = name ?? this.uniqueSheetName();
1543
+ validateWorksheetNameFormat(resolvedName);
1544
+ const lower = resolvedName.toLowerCase();
1545
+ for (const ws2 of this._sheets) {
1546
+ if (ws2.name.toLowerCase() === lower) throw new DuplicateWorksheetNameError(resolvedName);
1547
+ }
1548
+ const id = this._nextId++;
1549
+ const ws = new Worksheet(this, id, resolvedName, this._sheets.length);
1550
+ if (options) {
1551
+ if (options.state) ws.state = options.state;
1552
+ if (options.properties) ws.properties = { ...ws.properties, ...options.properties };
1553
+ if (options.views) ws.views = options.views;
1554
+ if (options.pageSetup !== void 0) ws.pageSetup = options.pageSetup;
1555
+ if (options.headerFooter !== void 0) ws.headerFooter = options.headerFooter;
1556
+ }
1557
+ this._byId.set(id, ws);
1558
+ this._sheets.push(ws);
1559
+ return ws;
1560
+ }
1561
+ uniqueSheetName() {
1562
+ const taken = new Set(this._sheets.map((w) => w.name.toLowerCase()));
1563
+ let n = this._sheets.length + 1;
1564
+ let candidate = `Sheet${n}`;
1565
+ while (taken.has(candidate.toLowerCase())) {
1566
+ n++;
1567
+ candidate = `Sheet${n}`;
1568
+ }
1569
+ return candidate;
1570
+ }
1571
+ getWorksheet(idOrName) {
1572
+ if (idOrName === void 0) return this._sheets[0];
1573
+ if (typeof idOrName === "number") return this._byId.get(idOrName);
1574
+ return this._sheets.find((w) => w.name === idOrName);
1575
+ }
1576
+ removeWorksheet(idOrName) {
1577
+ const ws = typeof idOrName === "number" ? this._byId.get(idOrName) : this._sheets.find((w) => w.name === idOrName);
1578
+ if (!ws) return;
1579
+ this._byId.delete(ws.id);
1580
+ this._sheets = this._sheets.filter((w) => w !== ws);
1581
+ this.reindex();
1582
+ }
1583
+ /** Keeps `orderNo` equal to array position after a removal. */
1584
+ reindex() {
1585
+ this._sheets.forEach((w, i) => {
1586
+ w.orderNo = i;
1587
+ });
1588
+ }
1589
+ eachSheet(cb) {
1590
+ for (const ws of this._sheets) cb(ws, ws.id);
1591
+ }
1592
+ // --- model ------------------------------------------------------------------------------------
1593
+ get model() {
1594
+ const m = {
1595
+ created: this.created,
1596
+ modified: this.modified,
1597
+ properties: { ...this.properties },
1598
+ calcProperties: { ...this.calcProperties },
1599
+ views: this.views.map((v) => ({ ...v })),
1600
+ sheets: this._sheets.map((w) => w.model),
1601
+ nextId: this._nextId
1602
+ };
1603
+ if (this.creator !== void 0) m.creator = this.creator;
1604
+ if (this.lastModifiedBy !== void 0) m.lastModifiedBy = this.lastModifiedBy;
1605
+ if (this.lastPrinted !== void 0) m.lastPrinted = this.lastPrinted;
1606
+ if (this.title !== void 0) m.title = this.title;
1607
+ if (this.subject !== void 0) m.subject = this.subject;
1608
+ if (this.keywords !== void 0) m.keywords = this.keywords;
1609
+ if (this.category !== void 0) m.category = this.category;
1610
+ if (this.description !== void 0) m.description = this.description;
1611
+ if (this.company !== void 0) m.company = this.company;
1612
+ if (this.manager !== void 0) m.manager = this.manager;
1613
+ return m;
1614
+ }
1615
+ set model(m) {
1616
+ this.creator = m.creator;
1617
+ this.lastModifiedBy = m.lastModifiedBy;
1618
+ this.created = m.created;
1619
+ this.modified = m.modified;
1620
+ this.lastPrinted = m.lastPrinted;
1621
+ this.title = m.title;
1622
+ this.subject = m.subject;
1623
+ this.keywords = m.keywords;
1624
+ this.category = m.category;
1625
+ this.description = m.description;
1626
+ this.company = m.company;
1627
+ this.manager = m.manager;
1628
+ this.properties = { ...m.properties };
1629
+ this.calcProperties = { ...m.calcProperties };
1630
+ this.views = m.views.map((v) => ({ ...v }));
1631
+ this._byId.clear();
1632
+ this._sheets = [];
1633
+ for (const sheetModel of m.sheets) {
1634
+ const ws = new Worksheet(this, sheetModel.id, sheetModel.name, sheetModel.orderNo);
1635
+ ws.model = sheetModel;
1636
+ this._byId.set(ws.id, ws);
1637
+ this._sheets.push(ws);
1638
+ }
1639
+ this._nextId = m.nextId;
1640
+ }
1641
+ };
1642
+
1643
+ // src/xlsx/date.ts
1644
+ var MS_PER_DAY = 864e5;
1645
+ var EPOCH_1900 = Date.UTC(1899, 11, 31);
1646
+ var EPOCH_1904 = Date.UTC(1904, 0, 1);
1647
+ var LEAP_BUG_SERIAL = 60;
1648
+ function dateToSerial(d, date1904 = false) {
1649
+ if (date1904) {
1650
+ return (d.getTime() - EPOCH_1904) / MS_PER_DAY;
1651
+ }
1652
+ const raw = (d.getTime() - EPOCH_1900) / MS_PER_DAY;
1653
+ return raw >= LEAP_BUG_SERIAL ? raw + 1 : raw;
1654
+ }
1655
+ function serialToDate(serial, date1904 = false) {
1656
+ if (date1904) {
1657
+ return new Date(EPOCH_1904 + serial * MS_PER_DAY);
1658
+ }
1659
+ const adjusted = serial > LEAP_BUG_SERIAL ? serial - 1 : serial;
1660
+ return new Date(EPOCH_1900 + adjusted * MS_PER_DAY);
1661
+ }
1662
+
1663
+ // src/xlsx/parts/constants.ts
1664
+ var NS = {
1665
+ spreadsheetml: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
1666
+ relationships: "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
1667
+ contentTypes: "http://schemas.openxmlformats.org/package/2006/content-types",
1668
+ packageRels: "http://schemas.openxmlformats.org/package/2006/relationships",
1669
+ coreProps: "http://schemas.openxmlformats.org/package/2006/metadata/core-properties",
1670
+ extProps: "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties",
1671
+ docPropsVt: "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes",
1672
+ dc: "http://purl.org/dc/elements/1.1/",
1673
+ dcterms: "http://purl.org/dc/terms/",
1674
+ dcmitype: "http://purl.org/dc/dcmitype/",
1675
+ xsi: "http://www.w3.org/2001/XMLSchema-instance"
1676
+ };
1677
+ var CONTENT_TYPE = {
1678
+ rels: "application/vnd.openxmlformats-package.relationships+xml",
1679
+ xml: "application/xml",
1680
+ workbook: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml",
1681
+ worksheet: "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml",
1682
+ styles: "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
1683
+ sharedStrings: "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml",
1684
+ theme: "application/vnd.openxmlformats-officedocument.theme+xml",
1685
+ coreProps: "application/vnd.openxmlformats-package.core-properties+xml",
1686
+ extProps: "application/vnd.openxmlformats-officedocument.extended-properties+xml"
1687
+ };
1688
+ var REL_TYPE = {
1689
+ officeDocument: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
1690
+ coreProps: "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties",
1691
+ extProps: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties",
1692
+ worksheet: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet",
1693
+ styles: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles",
1694
+ sharedStrings: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings",
1695
+ theme: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme"
1696
+ };
1697
+ var PART_PATH = {
1698
+ contentTypes: "[Content_Types].xml",
1699
+ rootRels: "_rels/.rels",
1700
+ coreProps: "docProps/core.xml",
1701
+ appProps: "docProps/app.xml",
1702
+ workbook: "xl/workbook.xml",
1703
+ workbookRels: "xl/_rels/workbook.xml.rels",
1704
+ styles: "xl/styles.xml",
1705
+ sharedStrings: "xl/sharedStrings.xml",
1706
+ theme: "xl/theme/theme1.xml"
1707
+ };
1708
+
1709
+ // src/xml/xml-reader.ts
1710
+ var NAMED_ENTITIES = {
1711
+ amp: "&",
1712
+ lt: "<",
1713
+ gt: ">",
1714
+ quot: '"',
1715
+ apos: "'"
1716
+ };
1717
+ var ENTITY_RE = /&(#x[0-9a-fA-F]+|#[0-9]+|[a-zA-Z][a-zA-Z0-9]*);/g;
1718
+ function decodeEntities(s) {
1719
+ if (!s.includes("&")) return s;
1720
+ return s.replace(ENTITY_RE, (match, ent) => {
1721
+ if (ent.startsWith("#x") || ent.startsWith("#X")) {
1722
+ const code = Number.parseInt(ent.slice(2), 16);
1723
+ return Number.isFinite(code) ? String.fromCodePoint(code) : match;
1724
+ }
1725
+ if (ent.startsWith("#")) {
1726
+ const code = Number.parseInt(ent.slice(1), 10);
1727
+ return Number.isFinite(code) ? String.fromCodePoint(code) : match;
1728
+ }
1729
+ const named = NAMED_ENTITIES[ent];
1730
+ return named !== void 0 ? named : match;
1731
+ });
1732
+ }
1733
+ function isSpace(c) {
1734
+ return c === " " || c === " " || c === "\n" || c === "\r";
1735
+ }
1736
+ function findTagEnd(xml, start) {
1737
+ let i = start;
1738
+ let quote;
1739
+ while (i < xml.length) {
1740
+ const c = xml[i];
1741
+ if (quote) {
1742
+ if (c === quote) quote = void 0;
1743
+ } else if (c === '"' || c === "'") {
1744
+ quote = c;
1745
+ } else if (c === ">") {
1746
+ return i;
1747
+ }
1748
+ i++;
1749
+ }
1750
+ return xml.length;
1751
+ }
1752
+ function parseOpenTag(inner) {
1753
+ const len = inner.length;
1754
+ let i = 0;
1755
+ while (i < len && !isSpace(inner[i])) i++;
1756
+ const name = inner.slice(0, i);
1757
+ const attrs = {};
1758
+ while (i < len) {
1759
+ while (i < len && isSpace(inner[i])) i++;
1760
+ if (i >= len) break;
1761
+ let j = i;
1762
+ while (j < len && inner[j] !== "=" && !isSpace(inner[j])) j++;
1763
+ const attrName = inner.slice(i, j);
1764
+ if (!attrName) break;
1765
+ while (j < len && isSpace(inner[j])) j++;
1766
+ if (inner[j] === "=") {
1767
+ j++;
1768
+ while (j < len && isSpace(inner[j])) j++;
1769
+ const quote = inner[j];
1770
+ j++;
1771
+ const valStart = j;
1772
+ while (j < len && inner[j] !== quote) j++;
1773
+ attrs[attrName] = decodeEntities(inner.slice(valStart, j));
1774
+ j++;
1775
+ i = j;
1776
+ } else {
1777
+ attrs[attrName] = "";
1778
+ i = j;
1779
+ }
1780
+ }
1781
+ return { name, attrs };
1782
+ }
1783
+ function* parseXml(xml) {
1784
+ const len = xml.length;
1785
+ let i = 0;
1786
+ while (i < len) {
1787
+ if (xml[i] === "<") {
1788
+ if (xml.startsWith("<?", i)) {
1789
+ const end = xml.indexOf("?>", i + 2);
1790
+ i = end === -1 ? len : end + 2;
1791
+ continue;
1792
+ }
1793
+ if (xml.startsWith("<!--", i)) {
1794
+ const end = xml.indexOf("-->", i + 4);
1795
+ i = end === -1 ? len : end + 3;
1796
+ continue;
1797
+ }
1798
+ if (xml.startsWith("<![CDATA[", i)) {
1799
+ const end = xml.indexOf("]]>", i + 9);
1800
+ const text = end === -1 ? xml.slice(i + 9) : xml.slice(i + 9, end);
1801
+ i = end === -1 ? len : end + 3;
1802
+ if (text.length > 0) yield { kind: "text", text };
1803
+ continue;
1804
+ }
1805
+ if (xml.startsWith("<!", i)) {
1806
+ const end = xml.indexOf(">", i + 2);
1807
+ i = end === -1 ? len : end + 1;
1808
+ continue;
1809
+ }
1810
+ if (xml[i + 1] === "/") {
1811
+ const end = xml.indexOf(">", i + 2);
1812
+ const name2 = xml.slice(i + 2, end === -1 ? len : end).trim();
1813
+ i = end === -1 ? len : end + 1;
1814
+ yield { kind: "close", name: name2 };
1815
+ continue;
1816
+ }
1817
+ const tagEnd = findTagEnd(xml, i + 1);
1818
+ const selfClosing = xml[tagEnd - 1] === "/";
1819
+ const inner = xml.slice(i + 1, selfClosing ? tagEnd - 1 : tagEnd);
1820
+ const { name, attrs } = parseOpenTag(inner);
1821
+ i = tagEnd === len ? len : tagEnd + 1;
1822
+ yield { kind: "open", name, attrs, selfClosing };
1823
+ continue;
1824
+ }
1825
+ const next = xml.indexOf("<", i);
1826
+ const raw = next === -1 ? xml.slice(i) : xml.slice(i, next);
1827
+ i = next === -1 ? len : next;
1828
+ if (raw.length > 0) yield { kind: "text", text: decodeEntities(raw) };
1829
+ }
1830
+ }
1831
+ function localName(name) {
1832
+ const idx = name.indexOf(":");
1833
+ return idx === -1 ? name : name.slice(idx + 1);
1834
+ }
1835
+ function cursor(xml) {
1836
+ const gen = parseXml(xml);
1837
+ let lookahead;
1838
+ let hasLookahead = false;
1839
+ function pull() {
1840
+ const result = gen.next();
1841
+ return result.done ? void 0 : result.value;
1842
+ }
1843
+ function next() {
1844
+ if (hasLookahead) {
1845
+ hasLookahead = false;
1846
+ const ev = lookahead;
1847
+ lookahead = void 0;
1848
+ return ev;
1849
+ }
1850
+ return pull();
1851
+ }
1852
+ function peek() {
1853
+ if (!hasLookahead) {
1854
+ lookahead = pull();
1855
+ hasLookahead = true;
1856
+ }
1857
+ return lookahead;
1858
+ }
1859
+ function textUntilClose(name) {
1860
+ let text = "";
1861
+ let depth = 1;
1862
+ for (let ev = next(); ev; ev = next()) {
1863
+ if (ev.kind === "text") {
1864
+ text += ev.text;
1865
+ } else if (ev.kind === "open") {
1866
+ if (ev.name === name && !ev.selfClosing) depth++;
1867
+ } else if (ev.kind === "close" && ev.name === name) {
1868
+ depth--;
1869
+ if (depth === 0) break;
1870
+ }
1871
+ }
1872
+ return text;
1873
+ }
1874
+ function eachChild(name, onOpen) {
1875
+ for (let ev = next(); ev; ev = next()) {
1876
+ if (ev.kind === "close" && ev.name === name) break;
1877
+ if (ev.kind === "open") onOpen(ev);
1878
+ }
1879
+ }
1880
+ return { next, peek, textUntilClose, eachChild };
1881
+ }
1882
+
1883
+ // src/xml/xml-writer.ts
1884
+ var XML_DECLARATION = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>';
1885
+ function escapeXmlText(s) {
1886
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
1887
+ }
1888
+ function escapeXmlAttr(s) {
1889
+ return escapeXmlText(s).replace(/"/g, "&quot;").replace(/'/g, "&apos;");
1890
+ }
1891
+ function needsWhitespacePreserve(s) {
1892
+ return /^\s|\s$/.test(s);
1893
+ }
1894
+ var XmlWriter = class {
1895
+ buffer = "";
1896
+ constructor(opts) {
1897
+ if (opts?.declaration !== false) {
1898
+ this.buffer = XML_DECLARATION;
1899
+ }
1900
+ }
1901
+ /** Serialize an attribute record, omitting `undefined`/`null` and rendering booleans as `1`/`0`. */
1902
+ renderAttrs(attrs) {
1903
+ if (!attrs) return "";
1904
+ let out = "";
1905
+ for (const key of Object.keys(attrs)) {
1906
+ const value = attrs[key];
1907
+ if (value === void 0 || value === null) continue;
1908
+ const raw = typeof value === "boolean" ? value ? "1" : "0" : String(value);
1909
+ out += ` ${key}="${escapeXmlAttr(raw)}"`;
1910
+ }
1911
+ return out;
1912
+ }
1913
+ /** Open an element: `<tag …>`. */
1914
+ open(tag, attrs) {
1915
+ this.buffer += `<${tag}${this.renderAttrs(attrs)}>`;
1916
+ return this;
1917
+ }
1918
+ /** Self-closing element with attributes only: `<tag …/>`. */
1919
+ leaf(tag, attrs) {
1920
+ this.buffer += `<${tag}${this.renderAttrs(attrs)}/>`;
1921
+ return this;
1922
+ }
1923
+ /** Element with escaped text content: `<tag …>text</tag>`. A `<t>` whose text has leading/trailing
1924
+ * whitespace automatically gains `xml:space="preserve"` (explicit attrs win if they set it). */
1925
+ el(tag, text, attrs) {
1926
+ const finalAttrs = tag === "t" && needsWhitespacePreserve(text) ? { "xml:space": "preserve", ...attrs } : attrs;
1927
+ this.buffer += `<${tag}${this.renderAttrs(finalAttrs)}>${escapeXmlText(text)}</${tag}>`;
1928
+ return this;
1929
+ }
1930
+ /** Append escaped text content at the current position. */
1931
+ text(value) {
1932
+ this.buffer += escapeXmlText(value);
1933
+ return this;
1934
+ }
1935
+ /** Append already-serialized markup verbatim (escape hatch for composing sub-builders). */
1936
+ raw(xml) {
1937
+ this.buffer += xml;
1938
+ return this;
1939
+ }
1940
+ /** Close an element: `</tag>`. */
1941
+ close(tag) {
1942
+ this.buffer += `</${tag}>`;
1943
+ return this;
1944
+ }
1945
+ toString() {
1946
+ return this.buffer;
1947
+ }
1948
+ toBytes() {
1949
+ return new TextEncoder().encode(this.buffer);
1950
+ }
1951
+ };
1952
+ function readZipArchive(data) {
1953
+ const unzipped = unzipSync(data);
1954
+ return new Map(Object.entries(unzipped));
1955
+ }
1956
+ function writeZipArchive(entries) {
1957
+ return zipSync(Object.fromEntries(entries));
1958
+ }
1959
+
1960
+ // src/xlsx/read/package.ts
1961
+ var decoder = new TextDecoder();
1962
+ function openPackage(bytes) {
1963
+ const zip = readZip(bytes);
1964
+ const entry = (path) => zip.get(path);
1965
+ const text = (path) => {
1966
+ const raw = zip.get(path);
1967
+ return raw === void 0 ? void 0 : decoder.decode(raw);
1968
+ };
1969
+ const rootRelsXml = text(PART_PATH.rootRels);
1970
+ if (rootRelsXml === void 0) {
1971
+ throw new InvalidPackageError(`missing ${PART_PATH.rootRels}`);
1972
+ }
1973
+ const officeDocRel = parseRels(rootRelsXml).find((r) => r.type === REL_TYPE.officeDocument);
1974
+ if (!officeDocRel) {
1975
+ throw new InvalidPackageError(`${PART_PATH.rootRels} has no officeDocument relationship`);
1976
+ }
1977
+ const workbookPath = resolveRelTarget("", officeDocRel.target);
1978
+ const contentTypesXml = text(PART_PATH.contentTypes);
1979
+ if (contentTypesXml === void 0) {
1980
+ throw new UnsupportedFeatureError(
1981
+ `package is missing ${PART_PATH.contentTypes}; not a recognizable OOXML package`
1982
+ );
1983
+ }
1984
+ assertSpreadsheetPackage(contentTypesXml, workbookPath);
1985
+ if (entry(workbookPath) === void 0) {
1986
+ throw new InvalidPackageError(`workbook part not found at ${workbookPath}`);
1987
+ }
1988
+ const workbookDir = dirname(workbookPath);
1989
+ const workbookRelsXml = text(relsPathFor(workbookPath));
1990
+ const relsMap = /* @__PURE__ */ new Map();
1991
+ if (workbookRelsXml !== void 0) {
1992
+ for (const rel of parseRels(workbookRelsXml)) {
1993
+ relsMap.set(rel.id, { type: rel.type, target: resolveRelTarget(workbookDir, rel.target) });
1994
+ }
1995
+ }
1996
+ return {
1997
+ entry,
1998
+ text,
1999
+ workbookRels: () => relsMap,
2000
+ workbookPath: () => workbookPath
2001
+ };
2002
+ }
2003
+ function readZip(bytes) {
2004
+ try {
2005
+ return readZipArchive(bytes);
2006
+ } catch (e) {
2007
+ throw new InvalidPackageError(`could not read zip archive: ${e.message}`);
2008
+ }
2009
+ }
2010
+ function parseRels(xml) {
2011
+ const c = cursor(xml);
2012
+ let ev = c.next();
2013
+ while (ev && !(ev.kind === "open" && ev.name === "Relationships")) ev = c.next();
2014
+ if (ev?.kind !== "open") return [];
2015
+ const rels = [];
2016
+ if (!ev.selfClosing) {
2017
+ c.eachChild(ev.name, (child) => {
2018
+ if (child.name !== "Relationship") return;
2019
+ rels.push({
2020
+ id: child.attrs.Id ?? "",
2021
+ type: child.attrs.Type ?? "",
2022
+ target: child.attrs.Target ?? ""
2023
+ });
2024
+ });
2025
+ }
2026
+ return rels;
2027
+ }
2028
+ function assertSpreadsheetPackage(contentTypesXml, workbookPath) {
2029
+ const c = cursor(contentTypesXml);
2030
+ let ev = c.next();
2031
+ while (ev && !(ev.kind === "open" && ev.name === "Types")) ev = c.next();
2032
+ if (ev?.kind !== "open") {
2033
+ throw new UnsupportedFeatureError(
2034
+ `${PART_PATH.contentTypes} has no <Types> root; not a recognizable OOXML package`
2035
+ );
2036
+ }
2037
+ let isSpreadsheet = false;
2038
+ if (!ev.selfClosing) {
2039
+ c.eachChild(ev.name, (child) => {
2040
+ if (child.name !== "Override") return;
2041
+ const partName = child.attrs.PartName?.replace(/^\//, "");
2042
+ if (partName === workbookPath && child.attrs.ContentType === CONTENT_TYPE.workbook) {
2043
+ isSpreadsheet = true;
2044
+ }
2045
+ });
2046
+ }
2047
+ if (!isSpreadsheet) {
2048
+ throw new UnsupportedFeatureError(
2049
+ `package does not declare ${workbookPath} as a spreadsheet workbook in ${PART_PATH.contentTypes}`
2050
+ );
2051
+ }
2052
+ }
2053
+ function dirname(path) {
2054
+ const idx = path.lastIndexOf("/");
2055
+ return idx === -1 ? "" : path.slice(0, idx);
2056
+ }
2057
+ function relsPathFor(partPath) {
2058
+ const dir = dirname(partPath);
2059
+ const base = dir ? partPath.slice(dir.length + 1) : partPath;
2060
+ return dir ? `${dir}/_rels/${base}.rels` : `_rels/${base}.rels`;
2061
+ }
2062
+ function resolveRelTarget(baseDir, target) {
2063
+ if (target.startsWith("/")) return target.slice(1);
2064
+ const parts = baseDir ? baseDir.split("/") : [];
2065
+ for (const seg of target.split("/")) {
2066
+ if (seg === "" || seg === ".") continue;
2067
+ if (seg === "..") parts.pop();
2068
+ else parts.push(seg);
2069
+ }
2070
+ return parts.join("/");
2071
+ }
2072
+
2073
+ // src/xlsx/read/props.ts
2074
+ function fromW3CDTF(text) {
2075
+ return new Date(text);
2076
+ }
2077
+ function applyCoreProps(wb, xml) {
2078
+ const c = cursor(xml);
2079
+ let ev = c.next();
2080
+ while (ev && !(ev.kind === "open" && localName(ev.name) === "coreProperties")) ev = c.next();
2081
+ if (ev?.kind !== "open" || ev.selfClosing) return;
2082
+ c.eachChild(ev.name, (child) => {
2083
+ const name = localName(child.name);
2084
+ const text = child.selfClosing ? "" : c.textUntilClose(child.name);
2085
+ switch (name) {
2086
+ case "creator":
2087
+ wb.creator = text;
2088
+ break;
2089
+ case "title":
2090
+ wb.title = text;
2091
+ break;
2092
+ case "subject":
2093
+ wb.subject = text;
2094
+ break;
2095
+ case "description":
2096
+ wb.description = text;
2097
+ break;
2098
+ case "keywords":
2099
+ wb.keywords = text;
2100
+ break;
2101
+ case "category":
2102
+ wb.category = text;
2103
+ break;
2104
+ case "lastModifiedBy":
2105
+ wb.lastModifiedBy = text;
2106
+ break;
2107
+ case "created":
2108
+ wb.created = fromW3CDTF(text);
2109
+ break;
2110
+ case "modified":
2111
+ wb.modified = fromW3CDTF(text);
2112
+ break;
2113
+ }
2114
+ });
2115
+ }
2116
+ function applyAppProps(wb, xml) {
2117
+ const c = cursor(xml);
2118
+ let ev = c.next();
2119
+ while (ev && !(ev.kind === "open" && localName(ev.name) === "Properties")) ev = c.next();
2120
+ if (ev?.kind !== "open" || ev.selfClosing) return;
2121
+ c.eachChild(ev.name, (child) => {
2122
+ const name = localName(child.name);
2123
+ const text = child.selfClosing ? "" : c.textUntilClose(child.name);
2124
+ if (name === "Company") wb.company = text;
2125
+ else if (name === "Manager") wb.manager = text;
2126
+ });
2127
+ }
2128
+
2129
+ // src/xlsx/read/shared-strings.ts
2130
+ function parseSharedStrings(xml) {
2131
+ const c = cursor(xml);
2132
+ let ev = c.next();
2133
+ while (ev && !(ev.kind === "open" && localName(ev.name) === "sst")) ev = c.next();
2134
+ if (ev?.kind !== "open" || ev.selfClosing) return [];
2135
+ const entries = [];
2136
+ c.eachChild(ev.name, (child) => {
2137
+ if (localName(child.name) !== "si") return;
2138
+ entries.push(child.selfClosing ? "" : parseRichString(c, child.name));
2139
+ });
2140
+ return entries;
2141
+ }
2142
+ function parseRichString(c, container) {
2143
+ let text;
2144
+ const runs = [];
2145
+ c.eachChild(container, (child) => {
2146
+ const name = localName(child.name);
2147
+ if (name === "t") {
2148
+ text = child.selfClosing ? "" : c.textUntilClose(child.name);
2149
+ } else if (name === "r") {
2150
+ runs.push(child.selfClosing ? { text: "" } : parseRun(c, child.name));
2151
+ } else if (!child.selfClosing) {
2152
+ c.textUntilClose(child.name);
2153
+ }
2154
+ });
2155
+ return runs.length > 0 ? { richText: runs } : text ?? "";
2156
+ }
2157
+ function parseRun(c, rName) {
2158
+ let text = "";
2159
+ let font;
2160
+ c.eachChild(rName, (child) => {
2161
+ const name = localName(child.name);
2162
+ if (name === "t") {
2163
+ text = child.selfClosing ? "" : c.textUntilClose(child.name);
2164
+ } else if (name === "rPr") {
2165
+ font = child.selfClosing ? {} : parseRunProps(c, child.name);
2166
+ } else if (!child.selfClosing) {
2167
+ c.textUntilClose(child.name);
2168
+ }
2169
+ });
2170
+ return font ? { text, font } : { text };
2171
+ }
2172
+ function parseRunProps(c, rPrName) {
2173
+ const font = {};
2174
+ c.eachChild(rPrName, (child) => {
2175
+ const name = localName(child.name);
2176
+ switch (name) {
2177
+ case "rFont":
2178
+ font.name = child.attrs.val;
2179
+ break;
2180
+ case "charset":
2181
+ font.charset = Number(child.attrs.val);
2182
+ break;
2183
+ case "family":
2184
+ font.family = Number(child.attrs.val);
2185
+ break;
2186
+ case "b":
2187
+ font.bold = readBool(child.attrs.val);
2188
+ break;
2189
+ case "i":
2190
+ font.italic = readBool(child.attrs.val);
2191
+ break;
2192
+ case "strike":
2193
+ font.strike = readBool(child.attrs.val);
2194
+ break;
2195
+ case "outline":
2196
+ font.outline = readBool(child.attrs.val);
2197
+ break;
2198
+ case "color":
2199
+ font.color = parseColor(child.attrs);
2200
+ break;
2201
+ case "sz":
2202
+ font.size = Number(child.attrs.val);
2203
+ break;
2204
+ case "u":
2205
+ font.underline = child.attrs.val ?? true;
2206
+ break;
2207
+ case "vertAlign":
2208
+ font.vertAlign = child.attrs.val;
2209
+ break;
2210
+ case "scheme":
2211
+ font.scheme = child.attrs.val;
2212
+ break;
2213
+ }
2214
+ if (!child.selfClosing) c.textUntilClose(child.name);
2215
+ });
2216
+ return font;
2217
+ }
2218
+ function parseColor(attrs) {
2219
+ if (attrs.rgb !== void 0) return { argb: attrs.rgb };
2220
+ if (attrs.theme !== void 0) return { theme: Number(attrs.theme) };
2221
+ if (attrs.indexed !== void 0) return { indexed: Number(attrs.indexed) };
2222
+ return void 0;
2223
+ }
2224
+ function readBool(val) {
2225
+ return val === void 0 || val !== "0" && val !== "false";
2226
+ }
2227
+
2228
+ // src/xlsx/styles.ts
2229
+ var SPREADSHEETML_NS = "http://schemas.openxmlformats.org/spreadsheetml/2006/main";
2230
+ var FIRST_CUSTOM_NUMFMT_ID = 164;
2231
+ var DEFAULT_FONT = {
2232
+ size: 11,
2233
+ color: { theme: 1 },
2234
+ name: "Calibri",
2235
+ family: 2,
2236
+ scheme: "minor"
2237
+ };
2238
+ var DEFAULT_CELL_STYLE_XF = '<xf numFmtId="0" fontId="0" fillId="0" borderId="0"/>';
2239
+ var BUILTIN_NUMFMT_BY_CODE = /* @__PURE__ */ new Map([
2240
+ ["General", 0],
2241
+ ["0", 1],
2242
+ ["0.00", 2],
2243
+ ["#,##0", 3],
2244
+ ["#,##0.00", 4],
2245
+ ["0%", 9],
2246
+ ["0.00%", 10],
2247
+ ["0.00E+00", 11],
2248
+ ["# ?/?", 12],
2249
+ ["# ??/??", 13],
2250
+ ["mm-dd-yy", 14],
2251
+ ["d-mmm-yy", 15],
2252
+ ["d-mmm", 16],
2253
+ ["mmm-yy", 17],
2254
+ ["h:mm AM/PM", 18],
2255
+ ["h:mm:ss AM/PM", 19],
2256
+ ["h:mm", 20],
2257
+ ["h:mm:ss", 21],
2258
+ ["m/d/yy h:mm", 22],
2259
+ ["#,##0 ;(#,##0)", 37],
2260
+ ["#,##0 ;[Red](#,##0)", 38],
2261
+ ["#,##0.00;(#,##0.00)", 39],
2262
+ ["#,##0.00;[Red](#,##0.00)", 40],
2263
+ ["mm:ss", 45],
2264
+ ["[h]:mm:ss", 46],
2265
+ ["mmss.0", 47],
2266
+ ["##0.0E+0", 48],
2267
+ ["@", 49]
2268
+ ]);
2269
+ function createStyles() {
2270
+ return new StylesBuilder();
2271
+ }
2272
+ var InternPool = class {
2273
+ ids = /* @__PURE__ */ new Map();
2274
+ xml = [];
2275
+ constructor(seeds) {
2276
+ for (const seed of seeds) this.intern(seed);
2277
+ }
2278
+ intern(rendered) {
2279
+ const existing = this.ids.get(rendered);
2280
+ if (existing !== void 0) return existing;
2281
+ const id = this.xml.length;
2282
+ this.ids.set(rendered, id);
2283
+ this.xml.push(rendered);
2284
+ return id;
2285
+ }
2286
+ get count() {
2287
+ return this.xml.length;
2288
+ }
2289
+ };
2290
+ var StylesBuilder = class {
2291
+ fonts = new InternPool([renderFont(DEFAULT_FONT)]);
2292
+ fills = new InternPool([
2293
+ renderFill({ type: "pattern", pattern: "none" }),
2294
+ renderFill({ type: "pattern", pattern: "gray125" })
2295
+ ]);
2296
+ borders = new InternPool([renderBorder(void 0)]);
2297
+ cellXfs = new InternPool([
2298
+ renderXf({ numFmtId: 0, fontId: 0, fillId: 0, borderId: 0 })
2299
+ ]);
2300
+ /** Custom number-format code → allocated id (≥ 164), and the `<numFmt>` fragments in id order. */
2301
+ customNumFmtIds = /* @__PURE__ */ new Map();
2302
+ numFmtXml = [];
2303
+ nextNumFmtId = FIRST_CUSTOM_NUMFMT_ID;
2304
+ /** Fast path for the common case of one Style object shared across many cells. */
2305
+ cache = /* @__PURE__ */ new WeakMap();
2306
+ addStyle(style) {
2307
+ if (style === void 0) return 0;
2308
+ const cached = this.cache.get(style);
2309
+ if (cached !== void 0) return cached;
2310
+ const numFmtId = this.internNumFmt(style.numFmt);
2311
+ const fontId = style.font ? this.fonts.intern(renderFont(style.font)) : 0;
2312
+ const fillId = style.fill ? this.fills.intern(renderFill(style.fill)) : 0;
2313
+ const borderId = style.border ? this.borders.intern(renderBorder(style.border)) : 0;
2314
+ const id = this.cellXfs.intern(
2315
+ renderXf({
2316
+ numFmtId,
2317
+ fontId,
2318
+ fillId,
2319
+ borderId,
2320
+ alignment: style.alignment,
2321
+ protection: style.protection
2322
+ })
2323
+ );
2324
+ this.cache.set(style, id);
2325
+ return id;
2326
+ }
2327
+ internNumFmt(code) {
2328
+ if (code === void 0) return 0;
2329
+ const builtin = BUILTIN_NUMFMT_BY_CODE.get(code);
2330
+ if (builtin !== void 0) return builtin;
2331
+ const existing = this.customNumFmtIds.get(code);
2332
+ if (existing !== void 0) return existing;
2333
+ const id = this.nextNumFmtId++;
2334
+ this.customNumFmtIds.set(code, id);
2335
+ this.numFmtXml.push(renderNumFmt(id, code));
2336
+ return id;
2337
+ }
2338
+ toXml() {
2339
+ const w = new XmlWriter();
2340
+ w.open("styleSheet", { xmlns: SPREADSHEETML_NS });
2341
+ if (this.numFmtXml.length > 0) {
2342
+ w.open("numFmts", { count: this.numFmtXml.length });
2343
+ for (const x of this.numFmtXml) w.raw(x);
2344
+ w.close("numFmts");
2345
+ }
2346
+ w.open("fonts", { count: this.fonts.count });
2347
+ for (const x of this.fonts.xml) w.raw(x);
2348
+ w.close("fonts");
2349
+ w.open("fills", { count: this.fills.count });
2350
+ for (const x of this.fills.xml) w.raw(x);
2351
+ w.close("fills");
2352
+ w.open("borders", { count: this.borders.count });
2353
+ for (const x of this.borders.xml) w.raw(x);
2354
+ w.close("borders");
2355
+ w.open("cellStyleXfs", { count: 1 });
2356
+ w.raw(DEFAULT_CELL_STYLE_XF);
2357
+ w.close("cellStyleXfs");
2358
+ w.open("cellXfs", { count: this.cellXfs.count });
2359
+ for (const x of this.cellXfs.xml) w.raw(x);
2360
+ w.close("cellXfs");
2361
+ w.open("cellStyles", { count: 1 });
2362
+ w.leaf("cellStyle", { name: "Normal", xfId: 0, builtinId: 0 });
2363
+ w.close("cellStyles");
2364
+ w.leaf("dxfs", { count: 0 });
2365
+ w.leaf("tableStyles", {
2366
+ count: 0,
2367
+ defaultTableStyle: "TableStyleMedium2",
2368
+ defaultPivotStyle: "PivotStyleLight16"
2369
+ });
2370
+ w.close("styleSheet");
2371
+ return w.toString();
2372
+ }
2373
+ };
2374
+ function renderFont(font) {
2375
+ const w = new XmlWriter({ declaration: false });
2376
+ w.open("font");
2377
+ if (font.bold) w.leaf("b");
2378
+ if (font.italic) w.leaf("i");
2379
+ if (font.strike) w.leaf("strike");
2380
+ if (font.outline) w.leaf("outline");
2381
+ renderUnderline(w, font.underline);
2382
+ if (font.vertAlign) w.leaf("vertAlign", { val: font.vertAlign });
2383
+ if (font.size !== void 0) w.leaf("sz", { val: font.size });
2384
+ if (font.color) renderColor(w, "color", font.color);
2385
+ if (font.name !== void 0) w.leaf("name", { val: font.name });
2386
+ if (font.family !== void 0) w.leaf("family", { val: font.family });
2387
+ if (font.charset !== void 0) w.leaf("charset", { val: font.charset });
2388
+ if (font.scheme) w.leaf("scheme", { val: font.scheme });
2389
+ w.close("font");
2390
+ return w.toString();
2391
+ }
2392
+ function renderFill(fill) {
2393
+ const w = new XmlWriter({ declaration: false });
2394
+ w.open("fill");
2395
+ if (fill.type === "pattern") {
2396
+ if (fill.fgColor || fill.bgColor) {
2397
+ w.open("patternFill", { patternType: fill.pattern });
2398
+ if (fill.fgColor) renderColor(w, "fgColor", fill.fgColor);
2399
+ if (fill.bgColor) renderColor(w, "bgColor", fill.bgColor);
2400
+ w.close("patternFill");
2401
+ } else {
2402
+ w.leaf("patternFill", { patternType: fill.pattern });
2403
+ }
2404
+ } else if (fill.gradient === "angle") {
2405
+ w.open("gradientFill", { degree: fill.degree });
2406
+ renderStops(w, fill.stops);
2407
+ w.close("gradientFill");
2408
+ } else {
2409
+ w.open("gradientFill", {
2410
+ type: "path",
2411
+ left: fill.center.left,
2412
+ right: fill.center.left,
2413
+ top: fill.center.top,
2414
+ bottom: fill.center.top
2415
+ });
2416
+ renderStops(w, fill.stops);
2417
+ w.close("gradientFill");
2418
+ }
2419
+ w.close("fill");
2420
+ return w.toString();
2421
+ }
2422
+ function renderStops(w, stops) {
2423
+ for (const stop of stops) {
2424
+ w.open("stop", { position: stop.position });
2425
+ renderColor(w, "color", stop.color);
2426
+ w.close("stop");
2427
+ }
2428
+ }
2429
+ function renderBorder(borders) {
2430
+ const w = new XmlWriter({ declaration: false });
2431
+ w.open("border", {
2432
+ diagonalUp: borders?.diagonal?.up || void 0,
2433
+ diagonalDown: borders?.diagonal?.down || void 0
2434
+ });
2435
+ renderBorderSide(w, "left", borders?.left);
2436
+ renderBorderSide(w, "right", borders?.right);
2437
+ renderBorderSide(w, "top", borders?.top);
2438
+ renderBorderSide(w, "bottom", borders?.bottom);
2439
+ renderBorderSide(w, "diagonal", borders?.diagonal);
2440
+ w.close("border");
2441
+ return w.toString();
2442
+ }
2443
+ function renderBorderSide(w, tag, side) {
2444
+ if (!side || side.style === void 0) {
2445
+ w.leaf(tag);
2446
+ return;
2447
+ }
2448
+ if (!side.color) {
2449
+ w.leaf(tag, { style: side.style });
2450
+ return;
2451
+ }
2452
+ w.open(tag, { style: side.style });
2453
+ renderColor(w, "color", side.color);
2454
+ w.close(tag);
2455
+ }
2456
+ function renderNumFmt(id, code) {
2457
+ const w = new XmlWriter({ declaration: false });
2458
+ w.leaf("numFmt", { numFmtId: id, formatCode: code });
2459
+ return w.toString();
2460
+ }
2461
+ function renderXf(xf) {
2462
+ const alignmentXml = xf.alignment ? renderAlignment(xf.alignment) : "";
2463
+ const protectionXml = xf.protection ? renderProtection(xf.protection) : "";
2464
+ const attrs = {
2465
+ numFmtId: xf.numFmtId,
2466
+ fontId: xf.fontId,
2467
+ fillId: xf.fillId,
2468
+ borderId: xf.borderId,
2469
+ xfId: 0,
2470
+ applyNumberFormat: xf.numFmtId !== 0 || void 0,
2471
+ applyFont: xf.fontId !== 0 || void 0,
2472
+ applyFill: xf.fillId !== 0 || void 0,
2473
+ applyBorder: xf.borderId !== 0 || void 0,
2474
+ applyAlignment: alignmentXml !== "" || void 0,
2475
+ applyProtection: protectionXml !== "" || void 0
2476
+ };
2477
+ const w = new XmlWriter({ declaration: false });
2478
+ if (alignmentXml === "" && protectionXml === "") {
2479
+ w.leaf("xf", attrs);
2480
+ } else {
2481
+ w.open("xf", attrs);
2482
+ if (alignmentXml) w.raw(alignmentXml);
2483
+ if (protectionXml) w.raw(protectionXml);
2484
+ w.close("xf");
2485
+ }
2486
+ return w.toString();
2487
+ }
2488
+ function renderAlignment(a) {
2489
+ const attrs = {
2490
+ horizontal: a.horizontal,
2491
+ vertical: a.vertical,
2492
+ textRotation: convertTextRotation(a.textRotation),
2493
+ wrapText: a.wrapText || void 0,
2494
+ indent: a.indent,
2495
+ shrinkToFit: a.shrinkToFit || void 0,
2496
+ readingOrder: convertReadingOrder(a.readingOrder)
2497
+ };
2498
+ if (!hasDefinedValue(attrs)) return "";
2499
+ const w = new XmlWriter({ declaration: false });
2500
+ w.leaf("alignment", attrs);
2501
+ return w.toString();
2502
+ }
2503
+ function renderProtection(p) {
2504
+ const attrs = { locked: p.locked, hidden: p.hidden };
2505
+ if (!hasDefinedValue(attrs)) return "";
2506
+ const w = new XmlWriter({ declaration: false });
2507
+ w.leaf("protection", attrs);
2508
+ return w.toString();
2509
+ }
2510
+ function renderColor(w, tag, color) {
2511
+ if (color.argb !== void 0) w.leaf(tag, { rgb: color.argb });
2512
+ else if (color.theme !== void 0) w.leaf(tag, { theme: color.theme });
2513
+ else if (color.indexed !== void 0) w.leaf(tag, { indexed: color.indexed });
2514
+ }
2515
+ function renderUnderline(w, underline) {
2516
+ if (underline === void 0 || underline === false || underline === "none") return;
2517
+ if (underline === true) {
2518
+ w.leaf("u");
2519
+ return;
2520
+ }
2521
+ w.leaf("u", { val: underline });
2522
+ }
2523
+ function convertTextRotation(textRotation) {
2524
+ if (textRotation === void 0) return void 0;
2525
+ if (textRotation === "vertical") return 255;
2526
+ const r = Math.round(textRotation);
2527
+ if (r >= 0 && r <= 90) return r;
2528
+ if (r < 0 && r >= -90) return 90 - r;
2529
+ return void 0;
2530
+ }
2531
+ function convertReadingOrder(readingOrder) {
2532
+ if (readingOrder === "ltr") return 1;
2533
+ if (readingOrder === "rtl") return 2;
2534
+ return void 0;
2535
+ }
2536
+ function hasDefinedValue(attrs) {
2537
+ for (const key of Object.keys(attrs)) {
2538
+ if (attrs[key] !== void 0) return true;
2539
+ }
2540
+ return false;
2541
+ }
2542
+
2543
+ // src/xlsx/read/styles.ts
2544
+ var BUILTIN_NUMFMT_BY_ID = /* @__PURE__ */ new Map();
2545
+ for (const [code, id] of BUILTIN_NUMFMT_BY_CODE) BUILTIN_NUMFMT_BY_ID.set(id, code);
2546
+ function parseStyles(xml) {
2547
+ if (xml === void 0) return EMPTY_TABLE;
2548
+ const root = parseTree(xml);
2549
+ if (root === void 0) return EMPTY_TABLE;
2550
+ const customNumFmts = parseNumFmts(findChild(root, "numFmts"));
2551
+ const fonts = mapChildren(findChild(root, "fonts"), "font", parseFont);
2552
+ const fills = mapChildren(findChild(root, "fills"), "fill", parseFill);
2553
+ const borders = mapChildren(findChild(root, "borders"), "border", parseBorder);
2554
+ const xfs = mapChildren(findChild(root, "cellXfs"), "xf", parseXf);
2555
+ const numFmtCode = (id) => customNumFmts.get(id) ?? BUILTIN_NUMFMT_BY_ID.get(id);
2556
+ const styleFor = (index) => {
2557
+ if (!Number.isInteger(index) || index <= 0 || index >= xfs.length) return {};
2558
+ const xf = xfs[index];
2559
+ if (xf === void 0) return {};
2560
+ const style = {};
2561
+ if (xf.numFmtId !== 0 || xf.applyNumberFormat) {
2562
+ const code = numFmtCode(xf.numFmtId);
2563
+ if (code !== void 0 && code !== "General") style.numFmt = code;
2564
+ }
2565
+ if (xf.fontId !== 0 || xf.applyFont) {
2566
+ const font = fonts[xf.fontId];
2567
+ if (font !== void 0 && hasKeys(font)) style.font = font;
2568
+ }
2569
+ if (xf.fillId !== 0 || xf.applyFill) {
2570
+ const fill = fills[xf.fillId];
2571
+ if (fill !== void 0) style.fill = fill;
2572
+ }
2573
+ if (xf.borderId !== 0 || xf.applyBorder) {
2574
+ const border = borders[xf.borderId];
2575
+ if (border !== void 0 && hasKeys(border)) style.border = border;
2576
+ }
2577
+ if (xf.alignment !== void 0 && hasKeys(xf.alignment)) style.alignment = xf.alignment;
2578
+ if (xf.protection !== void 0 && hasKeys(xf.protection)) style.protection = xf.protection;
2579
+ return style;
2580
+ };
2581
+ const isDateStyle = (index) => {
2582
+ if (!Number.isInteger(index) || index < 0 || index >= xfs.length) return false;
2583
+ const xf = xfs[index];
2584
+ if (xf === void 0) return false;
2585
+ const id = xf.numFmtId;
2586
+ if (id >= 14 && id <= 22 || id >= 45 && id <= 47) return true;
2587
+ const code = numFmtCode(id);
2588
+ return code !== void 0 && isDateFormatCode(code);
2589
+ };
2590
+ return { styleFor, isDateStyle };
2591
+ }
2592
+ var EMPTY_TABLE = {
2593
+ styleFor: () => ({}),
2594
+ isDateStyle: () => false
2595
+ };
2596
+ function isDateFormatCode(code) {
2597
+ const n = code.length;
2598
+ let i = 0;
2599
+ while (i < n) {
2600
+ const ch = code[i];
2601
+ if (ch === void 0) break;
2602
+ if (ch === "\\") {
2603
+ i += 2;
2604
+ continue;
2605
+ }
2606
+ if (ch === '"') {
2607
+ i++;
2608
+ while (i < n && code[i] !== '"') i++;
2609
+ i++;
2610
+ continue;
2611
+ }
2612
+ if (ch === "[") {
2613
+ const close = code.indexOf("]", i);
2614
+ const first = code[i + 1];
2615
+ if (first !== void 0 && "hHmMsS".includes(first)) return true;
2616
+ i = close === -1 ? n : close + 1;
2617
+ continue;
2618
+ }
2619
+ if ("yYmMdDhHsS".includes(ch)) return true;
2620
+ i++;
2621
+ }
2622
+ return false;
2623
+ }
2624
+ function parseXf(el) {
2625
+ const xf = {
2626
+ numFmtId: numAttr(el, "numFmtId", 0),
2627
+ fontId: numAttr(el, "fontId", 0),
2628
+ fillId: numAttr(el, "fillId", 0),
2629
+ borderId: numAttr(el, "borderId", 0),
2630
+ applyNumberFormat: attrTrue(el.attrs.applyNumberFormat),
2631
+ applyFont: attrTrue(el.attrs.applyFont),
2632
+ applyFill: attrTrue(el.attrs.applyFill),
2633
+ applyBorder: attrTrue(el.attrs.applyBorder)
2634
+ };
2635
+ const alignmentEl = findChild(el, "alignment");
2636
+ if (alignmentEl !== void 0) xf.alignment = parseAlignment(alignmentEl);
2637
+ const protectionEl = findChild(el, "protection");
2638
+ if (protectionEl !== void 0) xf.protection = parseProtection(protectionEl);
2639
+ return xf;
2640
+ }
2641
+ function parseAlignment(el) {
2642
+ const a = {};
2643
+ if (el.attrs.horizontal !== void 0)
2644
+ a.horizontal = el.attrs.horizontal;
2645
+ if (el.attrs.vertical !== void 0) a.vertical = el.attrs.vertical;
2646
+ if (el.attrs.textRotation !== void 0) {
2647
+ const rotation = inverseTextRotation(Number(el.attrs.textRotation));
2648
+ if (rotation !== void 0) a.textRotation = rotation;
2649
+ }
2650
+ if (attrTrue(el.attrs.wrapText)) a.wrapText = true;
2651
+ if (el.attrs.indent !== void 0) a.indent = Number(el.attrs.indent);
2652
+ if (attrTrue(el.attrs.shrinkToFit)) a.shrinkToFit = true;
2653
+ if (el.attrs.readingOrder === "1") a.readingOrder = "ltr";
2654
+ else if (el.attrs.readingOrder === "2") a.readingOrder = "rtl";
2655
+ return a;
2656
+ }
2657
+ function inverseTextRotation(val) {
2658
+ if (val === 255) return "vertical";
2659
+ if (val >= 0 && val <= 90) return val;
2660
+ if (val > 90 && val <= 180) return 90 - val;
2661
+ return void 0;
2662
+ }
2663
+ function parseProtection(el) {
2664
+ const p = {};
2665
+ if (el.attrs.locked !== void 0) p.locked = attrTrue(el.attrs.locked);
2666
+ if (el.attrs.hidden !== void 0) p.hidden = attrTrue(el.attrs.hidden);
2667
+ return p;
2668
+ }
2669
+ function parseFont(el) {
2670
+ const font = {};
2671
+ for (const c of el.children) {
2672
+ switch (c.name) {
2673
+ case "b":
2674
+ if (elementOn(c.attrs.val)) font.bold = true;
2675
+ break;
2676
+ case "i":
2677
+ if (elementOn(c.attrs.val)) font.italic = true;
2678
+ break;
2679
+ case "strike":
2680
+ if (elementOn(c.attrs.val)) font.strike = true;
2681
+ break;
2682
+ case "outline":
2683
+ if (elementOn(c.attrs.val)) font.outline = true;
2684
+ break;
2685
+ case "u":
2686
+ font.underline = c.attrs.val === void 0 ? true : c.attrs.val;
2687
+ break;
2688
+ case "vertAlign":
2689
+ if (c.attrs.val !== void 0) font.vertAlign = c.attrs.val;
2690
+ break;
2691
+ case "sz":
2692
+ if (c.attrs.val !== void 0) font.size = Number(c.attrs.val);
2693
+ break;
2694
+ case "color": {
2695
+ const color = parseColor2(c);
2696
+ if (color !== void 0) font.color = color;
2697
+ break;
2698
+ }
2699
+ case "name":
2700
+ if (c.attrs.val !== void 0) font.name = c.attrs.val;
2701
+ break;
2702
+ case "family":
2703
+ if (c.attrs.val !== void 0) font.family = Number(c.attrs.val);
2704
+ break;
2705
+ case "charset":
2706
+ if (c.attrs.val !== void 0) font.charset = Number(c.attrs.val);
2707
+ break;
2708
+ case "scheme":
2709
+ if (c.attrs.val !== void 0) font.scheme = c.attrs.val;
2710
+ break;
2711
+ }
2712
+ }
2713
+ return font;
2714
+ }
2715
+ function parseFill(el) {
2716
+ const patternFill = findChild(el, "patternFill");
2717
+ if (patternFill !== void 0) {
2718
+ const fill = {
2719
+ type: "pattern",
2720
+ pattern: patternFill.attrs.patternType ?? "none"
2721
+ };
2722
+ const fg = findChild(patternFill, "fgColor");
2723
+ if (fg !== void 0) {
2724
+ const color = parseColor2(fg);
2725
+ if (color !== void 0) fill.fgColor = color;
2726
+ }
2727
+ const bg = findChild(patternFill, "bgColor");
2728
+ if (bg !== void 0) {
2729
+ const color = parseColor2(bg);
2730
+ if (color !== void 0) fill.bgColor = color;
2731
+ }
2732
+ return fill;
2733
+ }
2734
+ const gradientFill = findChild(el, "gradientFill");
2735
+ if (gradientFill !== void 0) {
2736
+ const stops = findChildren(gradientFill, "stop").map((stop) => {
2737
+ const colorEl = findChild(stop, "color");
2738
+ return {
2739
+ position: Number(stop.attrs.position ?? 0),
2740
+ color: (colorEl !== void 0 ? parseColor2(colorEl) : void 0) ?? {}
2741
+ };
2742
+ });
2743
+ if (gradientFill.attrs.type === "path") {
2744
+ return {
2745
+ type: "gradient",
2746
+ gradient: "path",
2747
+ center: {
2748
+ left: Number(gradientFill.attrs.left ?? 0),
2749
+ top: Number(gradientFill.attrs.top ?? 0)
2750
+ },
2751
+ stops
2752
+ };
2753
+ }
2754
+ return {
2755
+ type: "gradient",
2756
+ gradient: "angle",
2757
+ degree: Number(gradientFill.attrs.degree ?? 0),
2758
+ stops
2759
+ };
2760
+ }
2761
+ return { type: "pattern", pattern: "none" };
2762
+ }
2763
+ function parseBorder(el) {
2764
+ const borders = {};
2765
+ const left = parseBorderSide(findChild(el, "left"));
2766
+ if (left !== void 0) borders.left = left;
2767
+ const right = parseBorderSide(findChild(el, "right"));
2768
+ if (right !== void 0) borders.right = right;
2769
+ const top = parseBorderSide(findChild(el, "top"));
2770
+ if (top !== void 0) borders.top = top;
2771
+ const bottom = parseBorderSide(findChild(el, "bottom"));
2772
+ if (bottom !== void 0) borders.bottom = bottom;
2773
+ const diagonalSide = parseBorderSide(findChild(el, "diagonal"));
2774
+ const up = attrTrue(el.attrs.diagonalUp);
2775
+ const down = attrTrue(el.attrs.diagonalDown);
2776
+ if (diagonalSide !== void 0 || up || down) {
2777
+ const diagonal = { ...diagonalSide };
2778
+ if (up) diagonal.up = true;
2779
+ if (down) diagonal.down = true;
2780
+ borders.diagonal = diagonal;
2781
+ }
2782
+ return borders;
2783
+ }
2784
+ function parseBorderSide(el) {
2785
+ if (el === void 0 || el.attrs.style === void 0) return void 0;
2786
+ const border = { style: el.attrs.style };
2787
+ const colorEl = findChild(el, "color");
2788
+ if (colorEl !== void 0) {
2789
+ const color = parseColor2(colorEl);
2790
+ if (color !== void 0) border.color = color;
2791
+ }
2792
+ return border;
2793
+ }
2794
+ function parseColor2(el) {
2795
+ if (el.attrs.rgb !== void 0) return { argb: el.attrs.rgb };
2796
+ if (el.attrs.theme !== void 0) return { theme: Number(el.attrs.theme) };
2797
+ if (el.attrs.indexed !== void 0) return { indexed: Number(el.attrs.indexed) };
2798
+ return void 0;
2799
+ }
2800
+ function parseNumFmts(el) {
2801
+ const map = /* @__PURE__ */ new Map();
2802
+ if (el === void 0) return map;
2803
+ for (const c of findChildren(el, "numFmt")) {
2804
+ const id = c.attrs.numFmtId;
2805
+ const code = c.attrs.formatCode;
2806
+ if (id !== void 0 && code !== void 0) map.set(Number(id), code);
2807
+ }
2808
+ return map;
2809
+ }
2810
+ function parseTree(xml) {
2811
+ const root = { name: "#root", attrs: {}, children: [] };
2812
+ const stack = [root];
2813
+ for (const ev of parseXml(xml)) {
2814
+ const top = stack[stack.length - 1];
2815
+ if (top === void 0) break;
2816
+ if (ev.kind === "open") {
2817
+ const el = { name: ev.name, attrs: ev.attrs, children: [] };
2818
+ top.children.push(el);
2819
+ if (!ev.selfClosing) stack.push(el);
2820
+ } else if (ev.kind === "close" && stack.length > 1) {
2821
+ stack.pop();
2822
+ }
2823
+ }
2824
+ return root.children[0];
2825
+ }
2826
+ function findChild(el, name) {
2827
+ return el.children.find((c) => c.name === name);
2828
+ }
2829
+ function findChildren(el, name) {
2830
+ return el.children.filter((c) => c.name === name);
2831
+ }
2832
+ function mapChildren(el, name, fn) {
2833
+ if (el === void 0) return [];
2834
+ return findChildren(el, name).map(fn);
2835
+ }
2836
+ function numAttr(el, name, fallback) {
2837
+ const raw = el.attrs[name];
2838
+ return raw === void 0 ? fallback : Number(raw);
2839
+ }
2840
+ function elementOn(val) {
2841
+ return val !== "0" && val !== "false" && val !== "off";
2842
+ }
2843
+ function attrTrue(val) {
2844
+ return val === "1" || val === "true" || val === "on";
2845
+ }
2846
+ function hasKeys(obj) {
2847
+ for (const _ in obj) return true;
2848
+ return false;
2849
+ }
2850
+
2851
+ // src/xlsx/read/workbook.ts
2852
+ function parseWorkbook(xml) {
2853
+ const header = { sheets: [], date1904: false };
2854
+ const c = cursor(xml);
2855
+ let ev = c.next();
2856
+ while (ev && !(ev.kind === "open" && localName(ev.name) === "workbook")) ev = c.next();
2857
+ if (ev?.kind !== "open" || ev.selfClosing) return header;
2858
+ c.eachChild(ev.name, (child) => {
2859
+ switch (localName(child.name)) {
2860
+ case "workbookPr":
2861
+ if (truthy(child.attrs.date1904)) header.date1904 = true;
2862
+ break;
2863
+ case "bookViews":
2864
+ if (!child.selfClosing) parseBookViews(c, child.name, header);
2865
+ break;
2866
+ case "sheets":
2867
+ if (!child.selfClosing) parseSheets(c, child.name, header);
2868
+ break;
2869
+ default:
2870
+ if (!child.selfClosing) c.textUntilClose(child.name);
2871
+ }
2872
+ });
2873
+ return header;
2874
+ }
2875
+ function parseBookViews(c, container, header) {
2876
+ c.eachChild(container, (child) => {
2877
+ if (localName(child.name) === "workbookView") {
2878
+ const activeTab = child.attrs.activeTab;
2879
+ if (activeTab !== void 0) {
2880
+ const n = Number(activeTab);
2881
+ if (Number.isFinite(n)) header.activeTab = n;
2882
+ }
2883
+ } else if (!child.selfClosing) {
2884
+ c.textUntilClose(child.name);
2885
+ }
2886
+ });
2887
+ }
2888
+ function parseSheets(c, container, header) {
2889
+ c.eachChild(container, (child) => {
2890
+ if (localName(child.name) !== "sheet") {
2891
+ if (!child.selfClosing) c.textUntilClose(child.name);
2892
+ return;
2893
+ }
2894
+ header.sheets.push({
2895
+ name: child.attrs.name ?? "",
2896
+ sheetId: Number(child.attrs.sheetId ?? 0),
2897
+ state: normalizeState(child.attrs.state),
2898
+ rId: relId(child)
2899
+ });
2900
+ });
2901
+ }
2902
+ function relId(sheet) {
2903
+ const direct = sheet.attrs["r:id"];
2904
+ if (direct !== void 0) return direct;
2905
+ for (const key of Object.keys(sheet.attrs)) {
2906
+ if (localName(key) === "id") return sheet.attrs[key] ?? "";
2907
+ }
2908
+ return "";
2909
+ }
2910
+ function normalizeState(state) {
2911
+ if (state === "hidden") return "hidden";
2912
+ if (state === "veryHidden") return "veryHidden";
2913
+ return "visible";
2914
+ }
2915
+ function truthy(val) {
2916
+ return val === "1" || val === "true";
2917
+ }
2918
+
2919
+ // src/xlsx/read/worksheet.ts
2920
+ function parseWorksheet(ws, xml, ctx) {
2921
+ const c = cursor(xml);
2922
+ let ev = c.next();
2923
+ while (ev && !(ev.kind === "open" && localName(ev.name) === "worksheet")) ev = c.next();
2924
+ if (ev?.kind !== "open" || ev.selfClosing) return;
2925
+ const merges = [];
2926
+ c.eachChild(ev.name, (child) => {
2927
+ switch (localName(child.name)) {
2928
+ case "cols":
2929
+ if (!child.selfClosing) parseCols(c, child.name, ws, ctx);
2930
+ break;
2931
+ case "sheetData":
2932
+ if (!child.selfClosing) parseSheetData(c, child.name, ws, ctx);
2933
+ break;
2934
+ case "mergeCells":
2935
+ if (!child.selfClosing) collectMerges(c, child.name, merges);
2936
+ break;
2937
+ default:
2938
+ if (!child.selfClosing) c.textUntilClose(child.name);
2939
+ }
2940
+ });
2941
+ for (const ref of merges) ws.mergeCells(ref);
2942
+ }
2943
+ function parseCols(c, container, ws, ctx) {
2944
+ c.eachChild(container, (col) => {
2945
+ if (localName(col.name) !== "col") {
2946
+ if (!col.selfClosing) c.textUntilClose(col.name);
2947
+ return;
2948
+ }
2949
+ const min = num(col.attrs.min);
2950
+ const max = num(col.attrs.max);
2951
+ if (min === void 0 || max === void 0) return;
2952
+ const width = num(col.attrs.width);
2953
+ const hidden = truthy2(col.attrs.hidden);
2954
+ const outline = num(col.attrs.outlineLevel);
2955
+ const styleIdx = num(col.attrs.style);
2956
+ const style = styleIdx ? ctx.styles.styleFor(styleIdx) : void 0;
2957
+ for (let n = min; n <= max; n++) {
2958
+ const column = ws.getColumn(n);
2959
+ if (width !== void 0) column.width = width;
2960
+ if (hidden) column.hidden = true;
2961
+ if (outline) column.outlineLevel = outline;
2962
+ if (style) column.style = style;
2963
+ }
2964
+ });
2965
+ }
2966
+ function parseSheetData(c, container, ws, ctx) {
2967
+ let expectedRow = 0;
2968
+ c.eachChild(container, (rowEl) => {
2969
+ if (localName(rowEl.name) !== "row") {
2970
+ if (!rowEl.selfClosing) c.textUntilClose(rowEl.name);
2971
+ return;
2972
+ }
2973
+ expectedRow = num(rowEl.attrs.r) ?? expectedRow + 1;
2974
+ parseRow(c, rowEl, expectedRow, ws, ctx);
2975
+ });
2976
+ }
2977
+ function parseRow(c, rowEl, rowNumber, ws, ctx) {
2978
+ const row = ws.getRow(rowNumber);
2979
+ const height = num(rowEl.attrs.ht);
2980
+ if (height !== void 0) row.height = height;
2981
+ if (truthy2(rowEl.attrs.hidden)) row.hidden = true;
2982
+ const outline = num(rowEl.attrs.outlineLevel);
2983
+ if (outline) row.outlineLevel = outline;
2984
+ const rowStyleIdx = num(rowEl.attrs.s);
2985
+ if (rowStyleIdx) row.style = ctx.styles.styleFor(rowStyleIdx);
2986
+ if (rowEl.selfClosing) return;
2987
+ let expectedCol = 0;
2988
+ c.eachChild(rowEl.name, (cellEl) => {
2989
+ if (localName(cellEl.name) !== "c") {
2990
+ if (!cellEl.selfClosing) c.textUntilClose(cellEl.name);
2991
+ return;
2992
+ }
2993
+ expectedCol = parseCell(c, cellEl, expectedCol + 1, row, ctx);
2994
+ });
2995
+ }
2996
+ function parseCell(c, cellEl, fallbackCol, row, ctx) {
2997
+ const col = cellEl.attrs.r !== void 0 ? decodeAddress(cellEl.attrs.r).col : fallbackCol;
2998
+ const styleIdx = num(cellEl.attrs.s) ?? 0;
2999
+ const t = cellEl.attrs.t;
3000
+ let vText;
3001
+ let inlineValue;
3002
+ let formulaExpr;
3003
+ let hasFormula = false;
3004
+ if (!cellEl.selfClosing) {
3005
+ c.eachChild(cellEl.name, (child) => {
3006
+ switch (localName(child.name)) {
3007
+ case "v":
3008
+ vText = child.selfClosing ? "" : c.textUntilClose(child.name);
3009
+ break;
3010
+ case "f":
3011
+ hasFormula = true;
3012
+ formulaExpr = child.selfClosing ? "" : c.textUntilClose(child.name);
3013
+ break;
3014
+ case "is":
3015
+ inlineValue = child.selfClosing ? "" : parseRichString(c, child.name);
3016
+ break;
3017
+ default:
3018
+ if (!child.selfClosing) c.textUntilClose(child.name);
3019
+ }
3020
+ });
3021
+ }
3022
+ const value = hasFormula ? buildFormula(formulaExpr ?? "", t, vText, styleIdx, ctx) : decodeValue(t, vText, inlineValue, styleIdx, ctx);
3023
+ if (value === null && styleIdx === 0 && !hasFormula) return col;
3024
+ const cell = row.getCell(col);
3025
+ if (value !== null) cell.value = value;
3026
+ if (styleIdx !== 0) cell.style = ctx.styles.styleFor(styleIdx);
3027
+ return col;
3028
+ }
3029
+ function decodeValue(t, vText, inlineValue, styleIdx, ctx) {
3030
+ switch (t) {
3031
+ case "s": {
3032
+ if (vText === void 0) return null;
3033
+ return ctx.sharedStrings[Number(vText)] ?? "";
3034
+ }
3035
+ case "inlineStr":
3036
+ return inlineValue ?? "";
3037
+ case "str":
3038
+ return vText ?? "";
3039
+ case "b":
3040
+ return vText === void 0 ? null : decodeBool(vText);
3041
+ case "e":
3042
+ return vText === void 0 ? null : { error: vText };
3043
+ default: {
3044
+ if (vText === void 0) return null;
3045
+ const n = Number(vText);
3046
+ return ctx.styles.isDateStyle(styleIdx) ? serialToDate(n, ctx.date1904) : n;
3047
+ }
3048
+ }
3049
+ }
3050
+ function buildFormula(expr, t, vText, styleIdx, ctx) {
3051
+ const result = vText === void 0 ? void 0 : decodeScalar(t, vText, styleIdx, ctx);
3052
+ return result === void 0 ? { formula: expr } : { formula: expr, result };
3053
+ }
3054
+ function decodeScalar(t, vText, styleIdx, ctx) {
3055
+ switch (t) {
3056
+ case "b":
3057
+ return decodeBool(vText);
3058
+ case "e":
3059
+ return { error: vText };
3060
+ case "str":
3061
+ return vText;
3062
+ case "s": {
3063
+ const entry = ctx.sharedStrings[Number(vText)];
3064
+ if (entry === void 0) return "";
3065
+ return typeof entry === "string" ? entry : entry.richText.map((run) => run.text).join("");
3066
+ }
3067
+ default: {
3068
+ const n = Number(vText);
3069
+ return ctx.styles.isDateStyle(styleIdx) ? serialToDate(n, ctx.date1904) : n;
3070
+ }
3071
+ }
3072
+ }
3073
+ function collectMerges(c, container, merges) {
3074
+ c.eachChild(container, (mergeCell) => {
3075
+ if (localName(mergeCell.name) === "mergeCell" && mergeCell.attrs.ref !== void 0) {
3076
+ merges.push(mergeCell.attrs.ref);
3077
+ } else if (!mergeCell.selfClosing) {
3078
+ c.textUntilClose(mergeCell.name);
3079
+ }
3080
+ });
3081
+ }
3082
+ function decodeBool(raw) {
3083
+ if (raw === "1" || raw === "true" || raw === "TRUE") return true;
3084
+ if (raw === "0" || raw === "false" || raw === "FALSE") return false;
3085
+ throw new InvalidCellValueError(raw);
3086
+ }
3087
+ function num(val) {
3088
+ if (val === void 0) return void 0;
3089
+ const n = Number(val);
3090
+ return Number.isFinite(n) ? n : void 0;
3091
+ }
3092
+ function truthy2(val) {
3093
+ return val === "1" || val === "true";
3094
+ }
3095
+
3096
+ // src/xlsx/read-workbook.ts
3097
+ function readWorkbookBuffer(bytes, _options) {
3098
+ const pkg = openPackage(bytes);
3099
+ const rels = pkg.workbookRels();
3100
+ let stylesXml;
3101
+ let sharedStringsXml;
3102
+ for (const { type, target } of rels.values()) {
3103
+ if (type === REL_TYPE.styles) stylesXml = pkg.text(target);
3104
+ else if (type === REL_TYPE.sharedStrings) sharedStringsXml = pkg.text(target);
3105
+ }
3106
+ const styles = parseStyles(stylesXml);
3107
+ const sharedStrings = sharedStringsXml !== void 0 ? parseSharedStrings(sharedStringsXml) : [];
3108
+ const workbookXml = pkg.text(pkg.workbookPath()) ?? "";
3109
+ const header = parseWorkbook(workbookXml);
3110
+ const wb = new Workbook();
3111
+ if (header.date1904) wb.properties.date1904 = true;
3112
+ if (header.activeTab !== void 0) wb.views = [{ activeTab: header.activeTab }];
3113
+ const ctx = { sharedStrings, styles, date1904: header.date1904 };
3114
+ for (const sheet of header.sheets) {
3115
+ const ws = wb.addWorksheet(sheet.name, { state: sheet.state });
3116
+ const target = rels.get(sheet.rId)?.target;
3117
+ if (target === void 0) continue;
3118
+ const sheetXml = pkg.text(target);
3119
+ if (sheetXml !== void 0) parseWorksheet(ws, sheetXml, ctx);
3120
+ }
3121
+ const coreXml = pkg.text(PART_PATH.coreProps);
3122
+ if (coreXml !== void 0) applyCoreProps(wb, coreXml);
3123
+ const appXml = pkg.text(PART_PATH.appProps);
3124
+ if (appXml !== void 0) applyAppProps(wb, appXml);
3125
+ return wb;
3126
+ }
3127
+ async function readWorkbookFile(path, options) {
3128
+ const { readFile } = await import('fs/promises');
3129
+ const bytes = await readFile(path);
3130
+ return readWorkbookBuffer(bytes);
3131
+ }
3132
+
3133
+ // src/xlsx/shared-strings.ts
3134
+ var SPREADSHEETML_NS2 = "http://schemas.openxmlformats.org/spreadsheetml/2006/main";
3135
+ function createSharedStrings() {
3136
+ return new SharedStringsPool();
3137
+ }
3138
+ var SharedStringsPool = class {
3139
+ index = /* @__PURE__ */ new Map();
3140
+ entries = [];
3141
+ references = 0;
3142
+ add(value) {
3143
+ this.references += 1;
3144
+ const key = keyFor(value);
3145
+ const existing = this.index.get(key);
3146
+ if (existing !== void 0) return existing;
3147
+ const idx = this.entries.length;
3148
+ this.index.set(key, idx);
3149
+ this.entries.push(value);
3150
+ return idx;
3151
+ }
3152
+ get count() {
3153
+ return this.references;
3154
+ }
3155
+ get uniqueCount() {
3156
+ return this.entries.length;
3157
+ }
3158
+ toXml() {
3159
+ if (this.entries.length === 0) return void 0;
3160
+ const w = new XmlWriter();
3161
+ w.open("sst", {
3162
+ xmlns: SPREADSHEETML_NS2,
3163
+ count: this.references,
3164
+ uniqueCount: this.entries.length
3165
+ });
3166
+ for (const entry of this.entries) {
3167
+ w.open("si");
3168
+ if (typeof entry === "string") {
3169
+ w.el("t", entry);
3170
+ } else {
3171
+ for (const run of entry.richText) {
3172
+ w.open("r");
3173
+ const props = renderRunProps(run.font);
3174
+ if (props) w.raw(props);
3175
+ w.el("t", run.text);
3176
+ w.close("r");
3177
+ }
3178
+ }
3179
+ w.close("si");
3180
+ }
3181
+ w.close("sst");
3182
+ return w.toString();
3183
+ }
3184
+ };
3185
+ function keyFor(value) {
3186
+ return typeof value === "string" ? `s:${value}` : `r:${stableStringify(value.richText)}`;
3187
+ }
3188
+ function stableStringify(value) {
3189
+ if (value === null || typeof value !== "object") {
3190
+ return JSON.stringify(value);
3191
+ }
3192
+ if (Array.isArray(value)) {
3193
+ return `[${value.map(stableStringify).join(",")}]`;
3194
+ }
3195
+ const obj = value;
3196
+ const keys = Object.keys(obj).filter((k) => obj[k] !== void 0).sort();
3197
+ return `{${keys.map((k) => `${JSON.stringify(k)}:${stableStringify(obj[k])}`).join(",")}}`;
3198
+ }
3199
+ function renderRunProps(font) {
3200
+ if (!font) return "";
3201
+ const w = new XmlWriter({ declaration: false });
3202
+ if (font.name !== void 0) w.leaf("rFont", { val: font.name });
3203
+ if (font.charset !== void 0) w.leaf("charset", { val: font.charset });
3204
+ if (font.family !== void 0) w.leaf("family", { val: font.family });
3205
+ if (font.bold) w.leaf("b");
3206
+ if (font.italic) w.leaf("i");
3207
+ if (font.strike) w.leaf("strike");
3208
+ if (font.outline) w.leaf("outline");
3209
+ if (font.color) renderColor2(w, font.color);
3210
+ if (font.size !== void 0) w.leaf("sz", { val: font.size });
3211
+ renderUnderline2(w, font.underline);
3212
+ if (font.vertAlign) w.leaf("vertAlign", { val: font.vertAlign });
3213
+ if (font.scheme) w.leaf("scheme", { val: font.scheme });
3214
+ const inner = w.toString();
3215
+ return inner === "" ? "" : `<rPr>${inner}</rPr>`;
3216
+ }
3217
+ function renderColor2(w, color) {
3218
+ if (color.argb !== void 0) w.leaf("color", { rgb: color.argb });
3219
+ else if (color.theme !== void 0) w.leaf("color", { theme: color.theme });
3220
+ else if (color.indexed !== void 0) w.leaf("color", { indexed: color.indexed });
3221
+ }
3222
+ function renderUnderline2(w, underline) {
3223
+ if (underline === void 0 || underline === false || underline === "none") return;
3224
+ if (underline === true) {
3225
+ w.leaf("u");
3226
+ return;
3227
+ }
3228
+ w.leaf("u", { val: underline });
3229
+ }
3230
+
3231
+ // src/xlsx/parts/app-props.ts
3232
+ function renderAppProps(wb, sheetNames) {
3233
+ const w = new XmlWriter();
3234
+ w.open("Properties", { xmlns: NS.extProps, "xmlns:vt": NS.docPropsVt });
3235
+ w.el("Application", "Microsoft Excel");
3236
+ w.el("DocSecurity", "0");
3237
+ w.el("ScaleCrop", "false");
3238
+ w.open("HeadingPairs");
3239
+ w.open("vt:vector", { size: 2, baseType: "variant" });
3240
+ w.open("vt:variant");
3241
+ w.el("vt:lpstr", "Worksheets");
3242
+ w.close("vt:variant");
3243
+ w.open("vt:variant");
3244
+ w.el("vt:i4", String(sheetNames.length));
3245
+ w.close("vt:variant");
3246
+ w.close("vt:vector");
3247
+ w.close("HeadingPairs");
3248
+ w.open("TitlesOfParts");
3249
+ w.open("vt:vector", { size: sheetNames.length, baseType: "lpstr" });
3250
+ for (const name of sheetNames) w.el("vt:lpstr", name);
3251
+ w.close("vt:vector");
3252
+ w.close("TitlesOfParts");
3253
+ if (wb.company !== void 0) w.el("Company", wb.company);
3254
+ if (wb.manager !== void 0) w.el("Manager", wb.manager);
3255
+ w.el("LinksUpToDate", "false");
3256
+ w.el("SharedDoc", "false");
3257
+ w.el("HyperlinksChanged", "false");
3258
+ w.el("AppVersion", "1.0000");
3259
+ w.close("Properties");
3260
+ return w.toString();
3261
+ }
3262
+
3263
+ // src/xlsx/parts/content-types.ts
3264
+ function renderContentTypes(input) {
3265
+ const w = new XmlWriter();
3266
+ w.open("Types", { xmlns: NS.contentTypes });
3267
+ w.leaf("Default", { Extension: "rels", ContentType: CONTENT_TYPE.rels });
3268
+ w.leaf("Default", { Extension: "xml", ContentType: CONTENT_TYPE.xml });
3269
+ w.leaf("Override", { PartName: `/${PART_PATH.workbook}`, ContentType: CONTENT_TYPE.workbook });
3270
+ for (const file of input.worksheetFiles) {
3271
+ w.leaf("Override", {
3272
+ PartName: `/xl/worksheets/${file}`,
3273
+ ContentType: CONTENT_TYPE.worksheet
3274
+ });
3275
+ }
3276
+ w.leaf("Override", { PartName: `/${PART_PATH.styles}`, ContentType: CONTENT_TYPE.styles });
3277
+ if (input.hasSharedStrings) {
3278
+ w.leaf("Override", {
3279
+ PartName: `/${PART_PATH.sharedStrings}`,
3280
+ ContentType: CONTENT_TYPE.sharedStrings
3281
+ });
3282
+ }
3283
+ w.leaf("Override", { PartName: `/${PART_PATH.theme}`, ContentType: CONTENT_TYPE.theme });
3284
+ w.leaf("Override", { PartName: `/${PART_PATH.coreProps}`, ContentType: CONTENT_TYPE.coreProps });
3285
+ w.leaf("Override", { PartName: `/${PART_PATH.appProps}`, ContentType: CONTENT_TYPE.extProps });
3286
+ w.close("Types");
3287
+ return w.toString();
3288
+ }
3289
+
3290
+ // src/xlsx/parts/core-props.ts
3291
+ function toW3CDTF(date) {
3292
+ return `${date.toISOString().replace(/\.\d{3}Z$/, "Z")}`;
3293
+ }
3294
+ function renderCoreProps(wb) {
3295
+ const w = new XmlWriter();
3296
+ w.open("cp:coreProperties", {
3297
+ "xmlns:cp": NS.coreProps,
3298
+ "xmlns:dc": NS.dc,
3299
+ "xmlns:dcterms": NS.dcterms,
3300
+ "xmlns:dcmitype": NS.dcmitype,
3301
+ "xmlns:xsi": NS.xsi
3302
+ });
3303
+ if (wb.creator !== void 0) w.el("dc:creator", wb.creator);
3304
+ if (wb.title !== void 0) w.el("dc:title", wb.title);
3305
+ if (wb.subject !== void 0) w.el("dc:subject", wb.subject);
3306
+ if (wb.description !== void 0) w.el("dc:description", wb.description);
3307
+ if (wb.keywords !== void 0) w.el("cp:keywords", wb.keywords);
3308
+ if (wb.category !== void 0) w.el("cp:category", wb.category);
3309
+ if (wb.lastModifiedBy !== void 0) w.el("cp:lastModifiedBy", wb.lastModifiedBy);
3310
+ w.el("dcterms:created", toW3CDTF(wb.created), { "xsi:type": "dcterms:W3CDTF" });
3311
+ w.el("dcterms:modified", toW3CDTF(wb.modified), { "xsi:type": "dcterms:W3CDTF" });
3312
+ w.close("cp:coreProperties");
3313
+ return w.toString();
3314
+ }
3315
+
3316
+ // src/xlsx/parts/root-rels.ts
3317
+ function renderRootRels() {
3318
+ const w = new XmlWriter();
3319
+ w.open("Relationships", { xmlns: NS.packageRels });
3320
+ w.leaf("Relationship", {
3321
+ Id: "rId1",
3322
+ Type: REL_TYPE.officeDocument,
3323
+ Target: PART_PATH.workbook
3324
+ });
3325
+ w.leaf("Relationship", {
3326
+ Id: "rId2",
3327
+ Type: REL_TYPE.coreProps,
3328
+ Target: PART_PATH.coreProps
3329
+ });
3330
+ w.leaf("Relationship", {
3331
+ Id: "rId3",
3332
+ Type: REL_TYPE.extProps,
3333
+ Target: PART_PATH.appProps
3334
+ });
3335
+ w.close("Relationships");
3336
+ return w.toString();
3337
+ }
3338
+
3339
+ // src/xlsx/parts/theme.ts
3340
+ var THEME1_XML = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
3341
+ <a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="Office Theme"><a:themeElements><a:clrScheme name="Office"><a:dk1><a:sysClr val="windowText" lastClr="000000"/></a:dk1><a:lt1><a:sysClr val="window" lastClr="FFFFFF"/></a:lt1><a:dk2><a:srgbClr val="44546A"/></a:dk2><a:lt2><a:srgbClr val="E7E6E6"/></a:lt2><a:accent1><a:srgbClr val="4472C4"/></a:accent1><a:accent2><a:srgbClr val="ED7D31"/></a:accent2><a:accent3><a:srgbClr val="A5A5A5"/></a:accent3><a:accent4><a:srgbClr val="FFC000"/></a:accent4><a:accent5><a:srgbClr val="5B9BD5"/></a:accent5><a:accent6><a:srgbClr val="70AD47"/></a:accent6><a:hlink><a:srgbClr val="0563C1"/></a:hlink><a:folHlink><a:srgbClr val="954F72"/></a:folHlink></a:clrScheme><a:fontScheme name="Office"><a:majorFont><a:latin typeface="Calibri Light" panose="020F0302020204030204"/><a:ea typeface=""/><a:cs typeface=""/></a:majorFont><a:minorFont><a:latin typeface="Calibri" panose="020F0502020204030204"/><a:ea typeface=""/><a:cs typeface=""/></a:minorFont></a:fontScheme><a:fmtScheme name="Office"><a:fillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:lumMod val="110000"/><a:satMod val="105000"/><a:tint val="67000"/></a:schemeClr></a:gs><a:gs pos="50000"><a:schemeClr val="phClr"><a:lumMod val="105000"/><a:satMod val="103000"/><a:tint val="73000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:lumMod val="105000"/><a:satMod val="109000"/><a:tint val="81000"/></a:schemeClr></a:gs></a:gsLst><a:lin ang="5400000" scaled="0"/></a:gradFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:satMod val="103000"/><a:lumMod val="102000"/><a:tint val="94000"/></a:schemeClr></a:gs><a:gs pos="50000"><a:schemeClr val="phClr"><a:satMod val="110000"/><a:lumMod val="100000"/><a:shade val="100000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:lumMod val="99000"/><a:satMod val="120000"/><a:shade val="78000"/></a:schemeClr></a:gs></a:gsLst><a:lin ang="5400000" scaled="0"/></a:gradFill></a:fillStyleLst><a:lnStyleLst><a:ln w="6350" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/><a:miter lim="800000"/></a:ln><a:ln w="12700" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/><a:miter lim="800000"/></a:ln><a:ln w="19050" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/><a:miter lim="800000"/></a:ln></a:lnStyleLst><a:effectStyleLst><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst><a:outerShdw blurRad="57150" dist="19050" dir="5400000" rotWithShape="0"><a:srgbClr val="000000"><a:alpha val="63000"/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle></a:effectStyleLst><a:bgFillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"><a:tint val="95000"/><a:satMod val="170000"/></a:schemeClr></a:solidFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="93000"/><a:satMod val="150000"/><a:shade val="98000"/><a:lumMod val="102000"/></a:schemeClr></a:gs><a:gs pos="50000"><a:schemeClr val="phClr"><a:tint val="98000"/><a:satMod val="130000"/><a:shade val="90000"/><a:lumMod val="103000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:shade val="63000"/><a:satMod val="120000"/></a:schemeClr></a:gs></a:gsLst><a:lin ang="5400000" scaled="0"/></a:gradFill></a:bgFillStyleLst></a:fmtScheme></a:themeElements><a:objectDefaults/><a:extraClrSchemeLst/></a:theme>`;
3342
+ function renderTheme() {
3343
+ return THEME1_XML;
3344
+ }
3345
+
3346
+ // src/xlsx/parts/workbook.ts
3347
+ function renderWorkbook(wb, sheets) {
3348
+ const w = new XmlWriter();
3349
+ w.open("workbook", { xmlns: NS.spreadsheetml, "xmlns:r": NS.relationships });
3350
+ if (wb.properties.date1904) {
3351
+ w.leaf("workbookPr", { date1904: true });
3352
+ }
3353
+ const activeTab = typeof wb.views[0]?.activeTab === "number" ? wb.views[0].activeTab : void 0;
3354
+ w.open("bookViews");
3355
+ w.leaf("workbookView", { activeTab });
3356
+ w.close("bookViews");
3357
+ w.open("sheets");
3358
+ for (const sheet of sheets) {
3359
+ w.leaf("sheet", {
3360
+ name: sheet.name,
3361
+ sheetId: sheet.sheetId,
3362
+ state: sheet.state === "visible" ? void 0 : sheet.state,
3363
+ "r:id": sheet.rId
3364
+ });
3365
+ }
3366
+ w.close("sheets");
3367
+ if (wb.calcProperties.fullCalcOnLoad) {
3368
+ w.leaf("calcPr", { calcId: 0, fullCalcOnLoad: true });
3369
+ }
3370
+ w.close("workbook");
3371
+ return w.toString();
3372
+ }
3373
+
3374
+ // src/xlsx/parts/workbook-rels.ts
3375
+ function renderWorkbookRels(rels) {
3376
+ const w = new XmlWriter();
3377
+ w.open("Relationships", { xmlns: NS.packageRels });
3378
+ for (const rel of rels) {
3379
+ w.leaf("Relationship", { Id: rel.rId, Type: rel.type, Target: rel.target });
3380
+ }
3381
+ w.close("Relationships");
3382
+ return w.toString();
3383
+ }
3384
+
3385
+ // src/xlsx/parts/worksheet.ts
3386
+ var DEFAULT_DATE_NUMFMT = "mm-dd-yy";
3387
+ function renderWorksheet(ws, ctx) {
3388
+ const model = ws.model;
3389
+ const w = new XmlWriter();
3390
+ w.open("worksheet", { xmlns: NS.spreadsheetml, "xmlns:r": NS.relationships });
3391
+ w.leaf("dimension", { ref: ws.dimensions.range });
3392
+ w.open("sheetViews");
3393
+ w.leaf("sheetView", {
3394
+ workbookViewId: 0,
3395
+ showGridLines: model.properties.showGridLines === false ? false : void 0
3396
+ });
3397
+ w.close("sheetViews");
3398
+ w.leaf("sheetFormatPr", {
3399
+ defaultRowHeight: model.properties.defaultRowHeight ?? 15,
3400
+ defaultColWidth: model.properties.defaultColWidth
3401
+ });
3402
+ renderCols(w, model.columns, ctx);
3403
+ renderSheetData(w, model.rows, ctx);
3404
+ renderMergeCells(w, model.merges);
3405
+ w.close("worksheet");
3406
+ return w.toString();
3407
+ }
3408
+ function renderCols(w, columns, ctx) {
3409
+ if (!columns || columns.length === 0) return;
3410
+ const fragments = [];
3411
+ for (const range of columns) {
3412
+ const styleId = range.style ? ctx.styles.addStyle(range.style) : 0;
3413
+ const hasWidth = range.width !== void 0;
3414
+ if (!hasWidth && !range.hidden && !range.outlineLevel && styleId === 0) continue;
3415
+ const col = new XmlWriter({ declaration: false });
3416
+ col.leaf("col", {
3417
+ min: range.min,
3418
+ max: range.max,
3419
+ width: range.width,
3420
+ customWidth: hasWidth ? true : void 0,
3421
+ style: styleId !== 0 ? styleId : void 0,
3422
+ hidden: range.hidden || void 0,
3423
+ outlineLevel: range.outlineLevel || void 0
3424
+ });
3425
+ fragments.push(col.toString());
3426
+ }
3427
+ if (fragments.length === 0) return;
3428
+ w.open("cols");
3429
+ for (const f of fragments) w.raw(f);
3430
+ w.close("cols");
3431
+ }
3432
+ function renderSheetData(w, rows, ctx) {
3433
+ w.open("sheetData");
3434
+ for (const row of rows) {
3435
+ const styleId = row.style ? ctx.styles.addStyle(row.style) : 0;
3436
+ let cellsXml = "";
3437
+ for (const cell of row.cells) {
3438
+ cellsXml += renderCell(cell, ctx);
3439
+ }
3440
+ const hasAttrs = row.height !== void 0 || row.hidden || (row.outlineLevel ?? 0) !== 0 || styleId !== 0;
3441
+ if (cellsXml === "" && !hasAttrs) continue;
3442
+ w.open("row", {
3443
+ r: row.number,
3444
+ ht: row.height,
3445
+ customHeight: row.height !== void 0 ? true : void 0,
3446
+ hidden: row.hidden || void 0,
3447
+ outlineLevel: row.outlineLevel || void 0,
3448
+ s: styleId !== 0 ? styleId : void 0,
3449
+ customFormat: styleId !== 0 ? true : void 0
3450
+ });
3451
+ w.raw(cellsXml);
3452
+ w.close("row");
3453
+ }
3454
+ w.close("sheetData");
3455
+ }
3456
+ function renderCell(cell, ctx) {
3457
+ const styleId = cell.style ? ctx.styles.addStyle(cell.style) : 0;
3458
+ const r = cell.address;
3459
+ switch (cell.type) {
3460
+ case 0 /* Null */:
3461
+ case 9 /* Merge */:
3462
+ return styleId !== 0 ? leafCell(r, styleId) : "";
3463
+ case 1 /* Number */:
3464
+ return valueCell(r, styleId, void 0, String(cell.value));
3465
+ case 3 /* Boolean */:
3466
+ return valueCell(r, styleId, "b", cell.value ? "1" : "0");
3467
+ case 4 /* Date */: {
3468
+ const s = cell.style?.numFmt ? styleId : ctx.styles.addStyle({ ...cell.style, numFmt: DEFAULT_DATE_NUMFMT });
3469
+ return valueCell(r, s, void 0, String(dateToSerial(cell.value, ctx.date1904)));
3470
+ }
3471
+ case 5 /* Error */:
3472
+ return valueCell(r, styleId, "e", cell.value.error);
3473
+ case 2 /* String */:
3474
+ return stringCell(r, styleId, cell.value, ctx);
3475
+ case 7 /* Hyperlink */:
3476
+ return stringCell(r, styleId, cell.value.text, ctx);
3477
+ case 6 /* RichText */:
3478
+ return richTextCell(r, styleId, cell.value, ctx);
3479
+ case 8 /* Formula */:
3480
+ return formulaCell(r, styleId, cell, ctx);
3481
+ default:
3482
+ return styleId !== 0 ? leafCell(r, styleId) : "";
3483
+ }
3484
+ }
3485
+ function valueCell(r, s, t, raw) {
3486
+ const w = new XmlWriter({ declaration: false });
3487
+ w.open("c", { r, s: s !== 0 ? s : void 0, t });
3488
+ w.el("v", raw);
3489
+ w.close("c");
3490
+ return w.toString();
3491
+ }
3492
+ function leafCell(r, s) {
3493
+ const w = new XmlWriter({ declaration: false });
3494
+ w.leaf("c", { r, s });
3495
+ return w.toString();
3496
+ }
3497
+ function stringCell(r, s, value, ctx) {
3498
+ if (ctx.useSharedStrings) {
3499
+ return valueCell(r, s, "s", String(ctx.sharedStrings.add(value)));
3500
+ }
3501
+ const w = new XmlWriter({ declaration: false });
3502
+ w.open("c", { r, s: s !== 0 ? s : void 0, t: "inlineStr" });
3503
+ w.open("is");
3504
+ w.el("t", value);
3505
+ w.close("is");
3506
+ w.close("c");
3507
+ return w.toString();
3508
+ }
3509
+ function richTextCell(r, s, value, ctx) {
3510
+ if (ctx.useSharedStrings) {
3511
+ return valueCell(r, s, "s", String(ctx.sharedStrings.add(value)));
3512
+ }
3513
+ const text = value.richText.map((run) => run.text).join("");
3514
+ return stringCell(r, s, text, { ...ctx, useSharedStrings: false });
3515
+ }
3516
+ function formulaCell(r, s, cell, ctx) {
3517
+ const expr = (cell.formula ?? "").replace(/^=/, "");
3518
+ const result = cell.result;
3519
+ let t;
3520
+ let cachedV;
3521
+ if (result === void 0) {
3522
+ cachedV = void 0;
3523
+ } else if (typeof result === "number") {
3524
+ cachedV = String(result);
3525
+ } else if (typeof result === "boolean") {
3526
+ t = "b";
3527
+ cachedV = result ? "1" : "0";
3528
+ } else if (result instanceof Date) {
3529
+ cachedV = String(dateToSerial(result, ctx.date1904));
3530
+ } else if (typeof result === "object" && result !== null && "error" in result) {
3531
+ t = "e";
3532
+ cachedV = result.error;
3533
+ } else {
3534
+ t = "str";
3535
+ cachedV = String(result);
3536
+ }
3537
+ const w = new XmlWriter({ declaration: false });
3538
+ w.open("c", { r, s: s !== 0 ? s : void 0, t });
3539
+ w.el("f", expr);
3540
+ if (cachedV !== void 0) w.el("v", cachedV);
3541
+ w.close("c");
3542
+ return w.toString();
3543
+ }
3544
+ function renderMergeCells(w, merges) {
3545
+ if (merges.length === 0) return;
3546
+ w.open("mergeCells", { count: merges.length });
3547
+ for (const ref of merges) w.leaf("mergeCell", { ref });
3548
+ w.close("mergeCells");
3549
+ }
3550
+
3551
+ // src/xlsx/write-workbook.ts
3552
+ function writeWorkbookBuffer(wb, options) {
3553
+ const useSharedStrings = options?.useSharedStrings !== false;
3554
+ const useStyles = options?.useStyles !== false;
3555
+ const date1904 = wb.properties.date1904 === true;
3556
+ const worksheets = wb.worksheets;
3557
+ const sheetRels = worksheets.map((ws, i) => ({
3558
+ rId: `rId${i + 1}`,
3559
+ fileName: `sheet${i + 1}.xml`,
3560
+ sheetId: ws.id,
3561
+ name: ws.name,
3562
+ state: ws.state
3563
+ }));
3564
+ const sharedStrings = createSharedStrings();
3565
+ const styles = createStyles();
3566
+ const cellStyles = useStyles ? styles : { addStyle: () => 0, toXml: styles.toXml.bind(styles) };
3567
+ const ctx = { styles: cellStyles, sharedStrings, useSharedStrings, date1904 };
3568
+ const worksheetXml = /* @__PURE__ */ new Map();
3569
+ worksheets.forEach((ws, i) => {
3570
+ worksheetXml.set(sheetRels[i].fileName, renderWorksheet(ws, ctx));
3571
+ });
3572
+ const sharedStringsXml = useSharedStrings ? sharedStrings.toXml() : void 0;
3573
+ const hasSharedStrings = sharedStringsXml !== void 0;
3574
+ let counter = worksheets.length;
3575
+ const stylesRId = `rId${++counter}`;
3576
+ const sharedRId = hasSharedStrings ? `rId${++counter}` : void 0;
3577
+ const themeRId = `rId${++counter}`;
3578
+ const workbookRels = sheetRels.map((s) => ({
3579
+ rId: s.rId,
3580
+ type: REL_TYPE.worksheet,
3581
+ target: `worksheets/${s.fileName}`
3582
+ }));
3583
+ workbookRels.push({ rId: stylesRId, type: REL_TYPE.styles, target: "styles.xml" });
3584
+ if (sharedRId) {
3585
+ workbookRels.push({
3586
+ rId: sharedRId,
3587
+ type: REL_TYPE.sharedStrings,
3588
+ target: "sharedStrings.xml"
3589
+ });
3590
+ }
3591
+ workbookRels.push({ rId: themeRId, type: REL_TYPE.theme, target: "theme/theme1.xml" });
3592
+ const enc = new TextEncoder();
3593
+ const entries = /* @__PURE__ */ new Map();
3594
+ const put = (path, xml) => entries.set(path, enc.encode(xml));
3595
+ put(
3596
+ PART_PATH.contentTypes,
3597
+ renderContentTypes({ worksheetFiles: sheetRels.map((s) => s.fileName), hasSharedStrings })
3598
+ );
3599
+ put(PART_PATH.rootRels, renderRootRels());
3600
+ put(PART_PATH.coreProps, renderCoreProps(wb));
3601
+ put(
3602
+ PART_PATH.appProps,
3603
+ renderAppProps(
3604
+ wb,
3605
+ sheetRels.map((s) => s.name)
3606
+ )
3607
+ );
3608
+ put(PART_PATH.workbook, renderWorkbook(wb, sheetRels));
3609
+ put(PART_PATH.workbookRels, renderWorkbookRels(workbookRels));
3610
+ put(PART_PATH.styles, styles.toXml());
3611
+ if (sharedStringsXml !== void 0) put(PART_PATH.sharedStrings, sharedStringsXml);
3612
+ put(PART_PATH.theme, renderTheme());
3613
+ for (const [file, xml] of worksheetXml) put(`xl/worksheets/${file}`, xml);
3614
+ return writeZipArchive(entries);
3615
+ }
3616
+ async function writeWorkbookFile(wb, path, options) {
3617
+ const bytes = writeWorkbookBuffer(wb, options);
3618
+ const { writeFile } = await import('fs/promises');
3619
+ await writeFile(path, bytes);
3620
+ }
3621
+
3622
+ // src/index.ts
3623
+ async function drainStream(stream) {
3624
+ const chunks = [];
3625
+ let total = 0;
3626
+ for await (const chunk of stream) {
3627
+ chunks.push(chunk);
3628
+ total += chunk.length;
3629
+ }
3630
+ const out = new Uint8Array(total);
3631
+ let offset = 0;
3632
+ for (const chunk of chunks) {
3633
+ out.set(chunk, offset);
3634
+ offset += chunk.length;
3635
+ }
3636
+ return out;
3637
+ }
3638
+ Object.defineProperty(Workbook.prototype, "xlsx", {
3639
+ configurable: true,
3640
+ get() {
3641
+ return {
3642
+ writeBuffer: (options) => Promise.resolve(writeWorkbookBuffer(this, options)),
3643
+ writeFile: (path, options) => writeWorkbookFile(this, path, options),
3644
+ load: (data, options) => {
3645
+ this.model = readWorkbookBuffer(data).model;
3646
+ return Promise.resolve(this);
3647
+ },
3648
+ readFile: async (path, options) => {
3649
+ this.model = (await readWorkbookFile(path)).model;
3650
+ return this;
3651
+ },
3652
+ read: async (stream, options) => {
3653
+ this.model = readWorkbookBuffer(await drainStream(stream)).model;
3654
+ return this;
3655
+ }
3656
+ };
3657
+ }
3658
+ });
3659
+ var version = "0.0.0";
3660
+
3661
+ export { AloshaXlsxError, Cell, CellType, Column, DEFAULT_COLUMN_WIDTH, DuplicateWorksheetNameError, FormulaType, InvalidAddressError, InvalidCellValueError, InvalidPackageError, InvalidRangeError, InvalidRowNumberError, InvalidWorksheetNameError, MergeConflictError, Range, ReservedWorksheetNameError, Row, UnsupportedFeatureError, Workbook, Worksheet, WorksheetNameTooLongError, colLetterToNumber, colNumberToLetter, createSharedStrings, createStyles, dateToSerial, decodeAddress, decodeEx, detectType, effectiveType, encodeAddress, fromStored, isAloshaXlsxError, readWorkbookBuffer, readWorkbookFile, resolveCellStyle, serialToDate, toCsv, toStored, toText, validateAddress, version, writeWorkbookBuffer, writeWorkbookFile };
3662
+ //# sourceMappingURL=chunk-6XXKAKLS.js.map
3663
+ //# sourceMappingURL=chunk-6XXKAKLS.js.map