@pixerate/editor 0.46.0 → 0.47.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/THIRD_PARTY_NOTICES.md +20 -0
  2. package/dist/agent/index.cjs +20 -19
  3. package/dist/agent/index.cjs.map +1 -1
  4. package/dist/agent/index.d.cts +2 -2
  5. package/dist/agent/index.d.ts +2 -2
  6. package/dist/agent/index.js +4 -3
  7. package/dist/agent/index.js.map +1 -1
  8. package/dist/{builtins-DghNQbT-.d.ts → builtins-D2nMtw2W.d.ts} +1 -1
  9. package/dist/{builtins-CZW-aYKS.d.cts → builtins-xs7rK6ys.d.cts} +1 -1
  10. package/dist/chart/index.cjs +3965 -821
  11. package/dist/chart/index.cjs.map +1 -1
  12. package/dist/chart/index.d.cts +964 -240
  13. package/dist/chart/index.d.ts +964 -240
  14. package/dist/chart/index.js +3922 -778
  15. package/dist/chart/index.js.map +1 -1
  16. package/dist/{chunk-PQM5W7ZN.js → chunk-4FX5ACVG.js} +29 -2
  17. package/dist/{chunk-PQM5W7ZN.js.map → chunk-4FX5ACVG.js.map} +1 -1
  18. package/dist/{chunk-3RPOW4CS.js → chunk-5VXI5GED.js} +12 -10
  19. package/dist/{chunk-3RPOW4CS.js.map → chunk-5VXI5GED.js.map} +1 -1
  20. package/dist/{chunk-HHQ4XJWT.js → chunk-AMWXSYCI.js} +2 -2
  21. package/dist/{chunk-U7VGDSNY.cjs → chunk-BBRK6MOI.cjs} +101 -99
  22. package/dist/chunk-BBRK6MOI.cjs.map +1 -0
  23. package/dist/chunk-C3NWJE3K.js +1182 -0
  24. package/dist/chunk-C3NWJE3K.js.map +1 -0
  25. package/dist/{chunk-N4MLNJPO.cjs → chunk-H4PICYNL.cjs} +59 -12
  26. package/dist/chunk-H4PICYNL.cjs.map +1 -0
  27. package/dist/chunk-LYGEEDNR.cjs +1895 -0
  28. package/dist/chunk-LYGEEDNR.cjs.map +1 -0
  29. package/dist/chunk-NEOO6QJD.cjs +1182 -0
  30. package/dist/chunk-NEOO6QJD.cjs.map +1 -0
  31. package/dist/{chunk-Q25ZS4F7.js → chunk-PQFAHT5O.js} +53 -6
  32. package/dist/chunk-PQFAHT5O.js.map +1 -0
  33. package/dist/{chunk-ZRNHGAQT.js → chunk-REAGGLXS.js} +43 -1891
  34. package/dist/chunk-REAGGLXS.js.map +1 -0
  35. package/dist/{chunk-EFDCLENW.cjs → chunk-RIWPYSKU.cjs} +29 -2
  36. package/dist/chunk-RIWPYSKU.cjs.map +1 -0
  37. package/dist/{chunk-EWCOFSCQ.cjs → chunk-SQC26VQV.cjs} +252 -2100
  38. package/dist/chunk-SQC26VQV.cjs.map +1 -0
  39. package/dist/{chunk-K2LVZ4FA.cjs → chunk-XFYUFVAX.cjs} +3 -3
  40. package/dist/{chunk-K2LVZ4FA.cjs.map → chunk-XFYUFVAX.cjs.map} +1 -1
  41. package/dist/chunk-ZFBBVGCI.js +1895 -0
  42. package/dist/chunk-ZFBBVGCI.js.map +1 -0
  43. package/dist/commands/index.cjs +93 -11
  44. package/dist/commands/index.cjs.map +1 -1
  45. package/dist/commands/index.d.cts +9 -7
  46. package/dist/commands/index.d.ts +9 -7
  47. package/dist/commands/index.js +92 -10
  48. package/dist/commands/index.js.map +1 -1
  49. package/dist/extensions/index.cjs +3 -2
  50. package/dist/extensions/index.cjs.map +1 -1
  51. package/dist/extensions/index.d.cts +3 -2
  52. package/dist/extensions/index.d.ts +3 -2
  53. package/dist/extensions/index.js +2 -1
  54. package/dist/generation/index.cjs +2 -2
  55. package/dist/generation/index.js +1 -1
  56. package/dist/{index-jwJ_onWf.d.ts → index-CSUCQYAH.d.ts} +23 -2
  57. package/dist/{index-CfOQf70b.d.cts → index-QrqMmZ75.d.cts} +23 -2
  58. package/dist/index.cjs +12 -9
  59. package/dist/index.cjs.map +1 -1
  60. package/dist/index.d.cts +9 -3
  61. package/dist/index.d.ts +9 -3
  62. package/dist/index.js +26 -23
  63. package/dist/index.js.map +1 -1
  64. package/dist/parameters/index.d.cts +1 -1
  65. package/dist/parameters/index.d.ts +1 -1
  66. package/dist/{registry-vz6HOiiy.d.cts → registry-CaR7LC6W.d.cts} +2 -0
  67. package/dist/{registry-BfVD-vVg.d.ts → registry-rVtFJjRM.d.ts} +2 -0
  68. package/dist/spreadsheet/index.cjs +5 -3
  69. package/dist/spreadsheet/index.cjs.map +1 -1
  70. package/dist/spreadsheet/index.js +24 -22
  71. package/dist/tools/index.cjs +3 -3
  72. package/dist/tools/index.js +2 -2
  73. package/dist/types-BVqWm3d1.d.cts +320 -0
  74. package/dist/types-BVqWm3d1.d.ts +320 -0
  75. package/dist/vector/index.d.cts +1 -1
  76. package/dist/vector/index.d.ts +1 -1
  77. package/package.json +3 -2
  78. package/dist/chunk-EFDCLENW.cjs.map +0 -1
  79. package/dist/chunk-EWCOFSCQ.cjs.map +0 -1
  80. package/dist/chunk-N4MLNJPO.cjs.map +0 -1
  81. package/dist/chunk-Q25ZS4F7.js.map +0 -1
  82. package/dist/chunk-U7VGDSNY.cjs.map +0 -1
  83. package/dist/chunk-ZRNHGAQT.js.map +0 -1
  84. /package/dist/{chunk-HHQ4XJWT.js.map → chunk-AMWXSYCI.js.map} +0 -0
@@ -1,3 +1,33 @@
1
+ import {
2
+ FORMULA_ERRORS,
3
+ cleanFloat,
4
+ colNameToIndex,
5
+ compareValues,
6
+ dateToSerial,
7
+ daysBetween,
8
+ formatIsoDate,
9
+ formatIsoDateTime,
10
+ formatTextFunction,
11
+ isBlank,
12
+ isFormulaError,
13
+ isoDateHasTime,
14
+ normalizeValue,
15
+ numericValue,
16
+ parseCellInput,
17
+ parseIsoDate,
18
+ parseNumberText,
19
+ rangeGet,
20
+ roundHalfAwayFromZero,
21
+ serialToDate,
22
+ sliceRange,
23
+ toBoolean,
24
+ toDate,
25
+ toFormulaRange,
26
+ toNumber,
27
+ toText,
28
+ withRangeShape
29
+ } from "./chunk-ZFBBVGCI.js";
30
+
1
31
  // src/spreadsheet/formula/lexer.ts
2
32
  var MAX_QUOTED_SHEET_LENGTH = 2 * 31 + 2;
3
33
  var isWordStart = (char) => /[A-Za-z_$\\]/.test(char) || char > "\x7F" && /\p{L}/u.test(char);
@@ -507,518 +537,6 @@ function lookupEnvironment(env, name) {
507
537
  return null;
508
538
  }
509
539
 
510
- // src/spreadsheet/formula/values.ts
511
- var FORMULA_ERRORS = /* @__PURE__ */ new Set([
512
- "#DIV/0!",
513
- "#VALUE!",
514
- "#REF!",
515
- "#NAME?",
516
- "#N/A",
517
- "#NUM!",
518
- "#CYCLE!",
519
- "#ERROR!",
520
- "#SPILL!",
521
- "#CALC!"
522
- ]);
523
- function isFormulaError(value) {
524
- return typeof value === "string" && FORMULA_ERRORS.has(value);
525
- }
526
- var isBlank = (value) => value === "" || value === null || value === void 0;
527
- function toNumber(value) {
528
- if (isFormulaError(value)) return value;
529
- if (isBlank(value)) return 0;
530
- if (typeof value === "boolean") return value ? 1 : 0;
531
- if (typeof value === "number") return value;
532
- return parseNumberText(String(value)) ?? "#VALUE!";
533
- }
534
- function toBoolean(value) {
535
- if (isFormulaError(value)) return value;
536
- if (isBlank(value)) return false;
537
- if (typeof value === "boolean") return value;
538
- if (typeof value === "number") return value !== 0;
539
- const upper = String(value).trim().toUpperCase();
540
- if (upper === "TRUE") return true;
541
- if (upper === "FALSE") return false;
542
- return "#VALUE!";
543
- }
544
- var toText = (value) => isBlank(value) ? "" : typeof value === "boolean" ? value ? "TRUE" : "FALSE" : typeof value === "number" ? numberToText(value) : String(value);
545
- function numberToText(n) {
546
- if (n === 0 || !Number.isFinite(n)) return "0";
547
- const a = Math.abs(n);
548
- if ((a < 1e-9 || a >= 1e15) && Math.round(a) !== a || a >= 1e15) return sciText(n, 15);
549
- let mag = Math.floor(Math.log10(a));
550
- if (a >= Math.pow(10, mag + 1)) mag++;
551
- const decimals = Math.min(Math.max(14 - mag, 0), 30);
552
- return trimDecimal(n.toFixed(decimals));
553
- }
554
- function trimDecimal(s) {
555
- if (!s.includes(".")) return s;
556
- const t = s.replace(/0+$/, "").replace(/\.$/, "");
557
- return t === "-0" ? "0" : t;
558
- }
559
- function sciText(n, sig) {
560
- const [mantissa, exp] = n.toExponential(Math.max(sig - 1, 0)).split("e");
561
- const e = Number(exp);
562
- return `${trimDecimal(mantissa)}E${e < 0 ? "-" : "+"}${String(Math.abs(e)).padStart(2, "0")}`;
563
- }
564
- function numericValue(value) {
565
- if (typeof value === "number") return Number.isFinite(value) ? value : null;
566
- if (typeof value !== "string" || FORMULA_ERRORS.has(value)) return null;
567
- const trimmed = value.trim();
568
- if (trimmed === "") return null;
569
- const num = Number(trimmed);
570
- return Number.isFinite(num) ? num : null;
571
- }
572
- function normalizeValue(value) {
573
- const num = typeof value === "string" ? numericValue(value) : null;
574
- return num === null ? value : num;
575
- }
576
- var ERROR_ORDER = ["#NULL!", "#DIV/0!", "#VALUE!", "#REF!", "#NAME?", "#NUM!", "#N/A", "#SPILL!", "#CALC!", "#CYCLE!", "#ERROR!"];
577
- function valueRank(value) {
578
- if (isBlank(value)) return 4;
579
- if (typeof value === "number") return 0;
580
- if (typeof value === "boolean") return 2;
581
- if (typeof value === "string" && FORMULA_ERRORS.has(value)) return 3;
582
- return 1;
583
- }
584
- function compareNumbers(a, b) {
585
- if (a === b) return 0;
586
- if (Math.abs(a - b) > Math.max(Math.abs(a), Math.abs(b)) * 1e-13) return a < b ? -1 : 1;
587
- const round15 = (x2) => !Number.isFinite(x2) || x2 === 0 ? x2 : Number(x2.toExponential(14));
588
- const x = round15(a);
589
- const y = round15(b);
590
- return x < y ? -1 : x > y ? 1 : 0;
591
- }
592
- function compareText(a, b) {
593
- const x = a.toLowerCase();
594
- const y = b.toLowerCase();
595
- return x < y ? -1 : x > y ? 1 : 0;
596
- }
597
- function compareValues(left, right) {
598
- const lRank = valueRank(left);
599
- const rRank = valueRank(right);
600
- if (lRank === 4 || rRank === 4) {
601
- if (lRank === rRank) return 0;
602
- const blankFirst = lRank === 4;
603
- const other = blankFirst ? right : left;
604
- const otherRank = blankFirst ? rRank : lRank;
605
- let cmp;
606
- if (otherRank === 0) cmp = compareNumbers(0, other);
607
- else if (otherRank === 1) cmp = String(other) === "" ? 0 : -1;
608
- else if (otherRank === 2) cmp = other ? -1 : 0;
609
- else return lRank - rRank;
610
- return blankFirst ? cmp : -cmp;
611
- }
612
- if (lRank === 1 && rRank === 1) {
613
- const a = String(left);
614
- const b = String(right);
615
- const ta = isoDateTime(a);
616
- const tb = ta === null ? null : isoDateTime(b);
617
- if (ta !== null && tb !== null) return Math.sign(ta - tb);
618
- return compareText(a, b);
619
- }
620
- if (lRank === 0 && rRank === 1 || lRank === 1 && rRank === 0) {
621
- const date = parseIsoDate(lRank === 1 ? left : right);
622
- if (date) {
623
- const serial = dateToSerial(date);
624
- return lRank === 0 ? compareNumbers(left, serial) : compareNumbers(serial, right);
625
- }
626
- }
627
- if (lRank !== rRank) return lRank - rRank;
628
- if (lRank === 0) return compareNumbers(left, right);
629
- if (lRank === 2) return Number(left) - Number(right);
630
- return Math.sign(ERROR_ORDER.indexOf(left) - ERROR_ORDER.indexOf(right));
631
- }
632
- function sortCompareValues(left, right) {
633
- const lBlank = isBlank(left);
634
- const rBlank = isBlank(right);
635
- if (lBlank || rBlank) return lBlank === rBlank ? 0 : lBlank ? 1 : -1;
636
- if (isFormulaError(left) && isFormulaError(right)) return 0;
637
- return compareValues(left, right);
638
- }
639
- function roundHalfAwayFromZero(value, decimals) {
640
- const factor = Math.pow(10, decimals);
641
- const scaled = Number((Math.abs(value) * factor).toPrecision(15));
642
- return Math.sign(value) * Math.round(scaled) / factor;
643
- }
644
- var cleanFloat = (value) => Number(value.toPrecision(15));
645
- function colNameToIndex(col) {
646
- let index = 0;
647
- const upper = col.toUpperCase();
648
- for (let i = 0; i < upper.length; i++) {
649
- index = index * 26 + (upper.charCodeAt(i) - 65 + 1);
650
- }
651
- return index - 1;
652
- }
653
- function indexToColName(index) {
654
- let num = index + 1;
655
- let name = "";
656
- while (num > 0) {
657
- const mod = (num - 1) % 26;
658
- name = String.fromCharCode(65 + mod) + name;
659
- num = Math.floor((num - mod) / 26);
660
- }
661
- return name;
662
- }
663
- var rangeShapes = /* @__PURE__ */ new WeakMap();
664
- function withRangeShape(values, rows, cols) {
665
- rangeShapes.set(values, { rows, cols });
666
- return values;
667
- }
668
- function toFormulaRange(values) {
669
- const shape = rangeShapes.get(values);
670
- if (shape && shape.rows * shape.cols === values.length) return { ...shape, values };
671
- return { rows: values.length, cols: 1, values };
672
- }
673
- var rangeGet = (range, row, col) => row < range.rows && col < range.cols ? range.values[col * range.rows + row] : "";
674
- function sliceRange(range, rowStart, rowCount, colStart, colCount) {
675
- const out = [];
676
- for (let c = colStart; c < colStart + colCount; c++) {
677
- for (let r = rowStart; r < rowStart + rowCount; r++) out.push(rangeGet(range, r, c));
678
- }
679
- return withRangeShape(out, rowCount, colCount);
680
- }
681
- var MS_PER_DAY = 24 * 60 * 60 * 1e3;
682
- var pad = (n, width = 2) => String(n).padStart(width, "0");
683
- function toDate(value) {
684
- if (value instanceof Date) return isNaN(value.getTime()) ? null : value;
685
- if (typeof value === "number") return serialToDate(value);
686
- if (typeof value !== "string" || FORMULA_ERRORS.has(value)) return null;
687
- const text = value.trim();
688
- if (text === "") return null;
689
- const iso = /^(\d{4})-(\d{1,2})-(\d{1,2})(?:[ T](\d{1,2}):(\d{2})(?::(\d{2}))?)?$/.exec(text);
690
- if (iso) {
691
- const [, y, m, d, hh = "0", mm = "0", ss = "0"] = iso;
692
- const date = new Date(Number(y), Number(m) - 1, Number(d), Number(hh), Number(mm), Number(ss));
693
- return date.getMonth() === Number(m) - 1 ? date : null;
694
- }
695
- const serial = numericValue(text);
696
- if (serial !== null) return serialToDate(serial);
697
- if (/[a-z/]/i.test(text)) {
698
- const parsed = Date.parse(text);
699
- return isNaN(parsed) ? null : new Date(parsed);
700
- }
701
- return null;
702
- }
703
- var ISO_DATE = /^(\d{4})-(\d{1,2})-(\d{1,2})(?:[ T](\d{1,2}):(\d{2})(?::(\d{2}))?)?$/;
704
- function parseIsoDate(value) {
705
- if (typeof value !== "string" || value.length < 8 || value.length > 19) return null;
706
- const iso = ISO_DATE.exec(value.trim());
707
- if (!iso) return null;
708
- const [, y, m, d, hh = "0", mm = "0", ss = "0"] = iso;
709
- const date = new Date(Number(y), Number(m) - 1, Number(d), Number(hh), Number(mm), Number(ss));
710
- return date.getMonth() === Number(m) - 1 && date.getDate() === Number(d) ? date : null;
711
- }
712
- var isoDateHasTime = (value) => /[ T]\d/.test(value.trim());
713
- function isoDateTime(value) {
714
- if (value.length < 8 || value.charCodeAt(4) !== 45) return null;
715
- return parseIsoDate(value)?.getTime() ?? null;
716
- }
717
- function dateToSerial(date) {
718
- const utc = Date.UTC(
719
- date.getFullYear(),
720
- date.getMonth(),
721
- date.getDate(),
722
- date.getHours(),
723
- date.getMinutes(),
724
- date.getSeconds()
725
- );
726
- return cleanFloat((utc - Date.UTC(1899, 11, 30)) / MS_PER_DAY);
727
- }
728
- function serialToDate(serial) {
729
- if (!Number.isFinite(serial)) return null;
730
- const utc = new Date(Date.UTC(1899, 11, 30) + Math.round(serial * MS_PER_DAY));
731
- return new Date(
732
- utc.getUTCFullYear(),
733
- utc.getUTCMonth(),
734
- utc.getUTCDate(),
735
- utc.getUTCHours(),
736
- utc.getUTCMinutes(),
737
- utc.getUTCSeconds()
738
- );
739
- }
740
- var formatIsoDate = (date) => `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
741
- var formatIsoDateTime = (date) => `${formatIsoDate(date)} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
742
- var daysBetween = (start, end) => Math.round(
743
- (Date.UTC(end.getFullYear(), end.getMonth(), end.getDate()) - Date.UTC(start.getFullYear(), start.getMonth(), start.getDate())) / MS_PER_DAY
744
- );
745
-
746
- // src/spreadsheet/formula/parse-input.ts
747
- var MONTH_NAMES = [
748
- "January",
749
- "February",
750
- "March",
751
- "April",
752
- "May",
753
- "June",
754
- "July",
755
- "August",
756
- "September",
757
- "October",
758
- "November",
759
- "December"
760
- ];
761
- function daysFromCivil(year, month, day) {
762
- const y = month <= 2 ? year - 1 : year;
763
- const era = Math.floor((y >= 0 ? y : y - 399) / 400);
764
- const yoe = y - era * 400;
765
- const doy = Math.floor((153 * (month > 2 ? month - 3 : month + 9) + 2) / 5) + day - 1;
766
- const doe = yoe * 365 + Math.floor(yoe / 4) - Math.floor(yoe / 100) + doy;
767
- return era * 146097 + doe - 719468;
768
- }
769
- var isLeapYear = (y) => y % 4 === 0 && y % 100 !== 0 || y % 400 === 0;
770
- function daysInMonth(year, month) {
771
- if (month === 2) return isLeapYear(year) ? 29 : 28;
772
- if ([4, 6, 9, 11].includes(month)) return 30;
773
- return month >= 1 && month <= 12 ? 31 : 0;
774
- }
775
- var daysInMonth1900 = (year, month) => year === 1900 && month === 2 ? 29 : daysInMonth(year, month);
776
- var UNIX_1899_12_30 = -25569;
777
- var MAX_SERIAL_1900 = 2958465;
778
- function serialFromYmd(year, month, day) {
779
- if (![year, month, day].every(Number.isSafeInteger)) return null;
780
- let y = year >= 0 && year < 1900 ? year + 1900 : year;
781
- const m0 = month - 1;
782
- y += Math.floor(m0 / 12);
783
- const m = (m0 % 12 + 12) % 12 + 1;
784
- if (y < 1900 || y > 9999) return null;
785
- const first = daysFromCivil(y, m, 1) - UNIX_1899_12_30 - (y === 1900 && m <= 2 ? 1 : 0);
786
- const serial = first + day - 1;
787
- return serial >= 0 && serial <= MAX_SERIAL_1900 ? serial : null;
788
- }
789
- var timeFraction = (h, m, s) => (h * 3600 + m * 60 + s) / 86400;
790
- var currentYear = () => (/* @__PURE__ */ new Date()).getFullYear();
791
- function parseCellInput(input) {
792
- if (input === "") return { value: "", type: "empty" };
793
- if (input.startsWith("'")) return { value: input.slice(1), type: "text" };
794
- const t = input.trim();
795
- const upper = t.toUpperCase();
796
- if (upper === "TRUE") return { value: true, type: "boolean" };
797
- if (upper === "FALSE") return { value: false, type: "boolean" };
798
- if (FORMULA_ERRORS.has(upper)) return { value: upper, type: "error" };
799
- const numeric = parseNumeric(t);
800
- if (numeric) {
801
- if (numeric.kind === "date") {
802
- const iso = isoText(numeric.date);
803
- if (iso !== null) {
804
- return { value: iso, type: "date", numberFormat: numeric.format, formatKind: "date", cellFormat: "date" };
805
- }
806
- } else {
807
- const formatKind = numeric.kind === "time" ? "time" : formatKindOf(numeric.format);
808
- return {
809
- value: normalizeZero(numeric.value),
810
- type: "number",
811
- ...numeric.format ? { numberFormat: numeric.format } : {},
812
- ...formatKind ? { formatKind } : {},
813
- ...formatKind && formatKind !== "time" ? { cellFormat: formatKind } : {}
814
- };
815
- }
816
- }
817
- return { value: input, type: "text" };
818
- }
819
- function parseNumberText(text) {
820
- const numeric = parseNumeric(text.trim());
821
- if (!numeric) return null;
822
- if (numeric.kind !== "date") return normalizeZero(numeric.value);
823
- const { year, month, day, time = 0 } = numeric.date;
824
- const serial = serialFromYmd(year, month, day);
825
- return serial === null ? null : serial + time;
826
- }
827
- var normalizeZero = (n) => n === 0 ? 0 : n;
828
- function formatKindOf(format) {
829
- if (!format) return void 0;
830
- if (format.includes("$")) return "currency";
831
- if (format.includes("%")) return "percentage";
832
- return "number";
833
- }
834
- var pad2 = (n, width = 2) => String(n).padStart(width, "0");
835
- function isoText({ year, month, day, time }) {
836
- if (day > daysInMonth(year, month)) return null;
837
- const date = `${pad2(year, 4)}-${pad2(month)}-${pad2(day)}`;
838
- if (time === void 0) return date;
839
- let seconds = Math.round(time * 86400);
840
- if (seconds >= 86400) seconds = 86399;
841
- return `${date} ${pad2(Math.floor(seconds / 3600))}:${pad2(Math.floor(seconds / 60) % 60)}:${pad2(seconds % 60)}`;
842
- }
843
- function parseNumeric(t) {
844
- if (t === "") return null;
845
- if (t.startsWith("(") && t.endsWith(")") && t.length >= 2) {
846
- const inner = parseNumeric(t.slice(1, -1).trim());
847
- if (!inner || inner.kind === "date") return null;
848
- return { ...inner, value: -inner.value };
849
- }
850
- const plain = parsePlain(t);
851
- if (plain) return plain;
852
- const fraction = parseFraction(t);
853
- if (fraction !== null) return { kind: "number", value: fraction, format: "# ?/?" };
854
- return parseDateTime(t);
855
- }
856
- var startsWithDigitOrDot = (s) => /^[0-9.]/.test(s);
857
- function parsePlain(t) {
858
- let s = t;
859
- let neg = false;
860
- let currency = false;
861
- let percent = false;
862
- if (s.startsWith("-")) {
863
- neg = true;
864
- s = s.slice(1).trimStart();
865
- } else if (s.startsWith("+")) {
866
- s = s.slice(1).trimStart();
867
- }
868
- if (s.startsWith("$")) {
869
- currency = true;
870
- s = s.slice(1).trimStart();
871
- if (!neg && s.startsWith("-")) {
872
- neg = true;
873
- s = s.slice(1);
874
- }
875
- }
876
- if (s.endsWith("%")) {
877
- percent = true;
878
- s = s.slice(0, -1).trimEnd();
879
- }
880
- if (s === "") return null;
881
- const hasSep = s.includes(",");
882
- let digits;
883
- if (hasSep) {
884
- const dot = s.indexOf(".");
885
- const int = dot === -1 ? s : s.slice(0, dot);
886
- const frac = dot === -1 ? null : s.slice(dot + 1);
887
- const groups = int.split(",");
888
- const first = groups[0];
889
- if (first === "" || first.length > 3 || groups.slice(1).some((g) => g.length !== 3)) return null;
890
- digits = groups.join("") + (frac !== null ? `.${frac}` : "");
891
- } else {
892
- digits = s;
893
- }
894
- if (!/^[0-9.eE+-]+$/.test(digits) || !startsWithDigitOrDot(digits)) return null;
895
- if (!/^(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?$/.test(digits)) return null;
896
- let n = Number(digits);
897
- if (!Number.isFinite(n)) return null;
898
- const sci = /[eE]/.test(digits);
899
- if (percent) n /= 100;
900
- if (neg) n = -n;
901
- const hasDot = digits.includes(".");
902
- const format = currency ? hasDot ? '"$"#,##0.00' : '"$"#,##0' : percent ? hasDot ? "0.00%" : "0%" : sci ? "0.00E+00" : hasSep ? hasDot ? "#,##0.00" : "#,##0" : void 0;
903
- return { kind: "number", value: n, ...format ? { format } : {} };
904
- }
905
- var parseDecimal = (s) => /^[+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?$/.test(s) ? Number(s) : null;
906
- function parseFraction(t) {
907
- const space = t.indexOf(" ");
908
- if (space === -1) return null;
909
- const whole = t.slice(0, space);
910
- const frac = t.slice(space + 1).trim();
911
- const neg = whole.startsWith("-");
912
- const w = parseDecimal(whole.replace(/^-+/, ""));
913
- const slash = frac.indexOf("/");
914
- if (w === null || slash === -1) return null;
915
- const a = parseDecimal(frac.slice(0, slash));
916
- const b = parseDecimal(frac.slice(slash + 1));
917
- if (a === null || b === null || b === 0 || !Number.isFinite(w)) return null;
918
- const v = w + a / b;
919
- return neg ? -v : v;
920
- }
921
- function monthFromName(s) {
922
- const l = s.toLowerCase();
923
- if (l.length < 3) return null;
924
- const index = MONTH_NAMES.findIndex((m) => m.toLowerCase().startsWith(l));
925
- return index === -1 ? null : index + 1;
926
- }
927
- function parseTime(input) {
928
- const lower = input.trim().toLowerCase();
929
- let body = lower;
930
- let pm = null;
931
- for (const [suffix, isPm] of [["am", false], ["a", false], ["pm", true], ["p", true]]) {
932
- if (lower.endsWith(suffix)) {
933
- body = lower.slice(0, -suffix.length).trim();
934
- pm = isPm;
935
- break;
936
- }
937
- }
938
- const parts = body.split(":");
939
- if (parts.length === 1 && pm === null) return null;
940
- if (parts.length > 3 || parts.some((p) => p === "")) return null;
941
- const num = (p) => p === void 0 ? 0 : parseDecimal(p);
942
- let h = num(parts[0]);
943
- const m = num(parts[1]);
944
- const s = num(parts[2]);
945
- if (h === null || m === null || s === null) return null;
946
- if (m >= 60 || s >= 60 || h < 0 || m < 0 || s < 0) return null;
947
- if (pm !== null) {
948
- if (h > 12) return null;
949
- if (h === 12) h = 0;
950
- if (pm) h += 12;
951
- } else if (h >= 1e4) {
952
- return null;
953
- }
954
- return { fraction: timeFraction(h, m, s), seconds: parts.length === 3, ampm: pm !== null };
955
- }
956
- var expandYear = (text, y) => text.length <= 2 ? y < 30 ? 2e3 + y : 1900 + y : y;
957
- function validYmd(year, month, day) {
958
- if (month < 1 || month > 12 || day < 1 || year < 1900 || year > 9999) return null;
959
- if (day > daysInMonth1900(year, month)) return null;
960
- return { year, month, day };
961
- }
962
- function parseDate(input) {
963
- const t = input.trim().replace(/,+$/, "");
964
- const num = (s) => /^[+-]?\d+$/.test(s.trim()) ? Number(s.trim()) : null;
965
- const withFormat = (date, format) => date ? { date, format } : null;
966
- const parts = t.split(/[/.-]/);
967
- if (parts.length === 3) {
968
- const [a, b, c] = parts.map((p) => p.trim());
969
- if (a.length === 4) {
970
- const [y2, m2, d2] = [num(a), num(b), num(c)];
971
- if (y2 !== null && m2 !== null && d2 !== null) return withFormat(validYmd(y2, m2, d2), "yyyy-mm-dd");
972
- }
973
- {
974
- const [m2, d2, y2] = [num(a), num(b), num(c)];
975
- if (m2 !== null && d2 !== null && y2 !== null) return withFormat(validYmd(expandYear(c, y2), m2, d2), "m/d/yyyy");
976
- }
977
- const [d, m, y] = [num(a), monthFromName(b), num(c)];
978
- if (d !== null && m !== null && y !== null) return withFormat(validYmd(expandYear(c, y), m, d), "d-mmm-yy");
979
- }
980
- if (parts.length === 2) {
981
- const [a, b] = parts.map((p) => p.trim());
982
- const [x, y] = [num(a), num(b)];
983
- if (x !== null && y !== null) {
984
- if (x >= 1 && x <= 12 && y >= 1 && y <= 31) return withFormat(validYmd(currentYear(), x, y), "d-mmm");
985
- if (x >= 1 && x <= 12 && b.length === 4) return withFormat(validYmd(y, x, 1), "mmm-yy");
986
- }
987
- const dayA = num(a);
988
- const monthB = monthFromName(b);
989
- if (dayA !== null && monthB !== null) return withFormat(validYmd(currentYear(), monthB, dayA), "d-mmm");
990
- const monthA = monthFromName(a);
991
- const yearB = num(b);
992
- if (monthA !== null && yearB !== null) return withFormat(validYmd(expandYear(b, yearB), monthA, 1), "mmm-yy");
993
- }
994
- const words = t.split(/[ ,]/).filter((w) => w !== "");
995
- if (words.length === 3) {
996
- const [w0, w1, w2] = words;
997
- let [m, d, y] = [monthFromName(w0), num(w1), num(w2)];
998
- if (m !== null && d !== null && y !== null) return withFormat(validYmd(expandYear(w2, y), m, d), "d-mmm-yy");
999
- [d, m, y] = [num(w0), monthFromName(w1), num(w2)];
1000
- if (d !== null && m !== null && y !== null) return withFormat(validYmd(expandYear(w2, y), m, d), "d-mmm-yy");
1001
- }
1002
- return null;
1003
- }
1004
- function parseDateTime(t) {
1005
- const time = parseTime(t);
1006
- if (time) {
1007
- const format = time.fraction >= 1 ? "[h]:mm:ss" : time.seconds ? time.ampm ? "h:mm:ss AM/PM" : "h:mm:ss" : time.ampm ? "h:mm AM/PM" : "h:mm";
1008
- return { kind: "time", value: time.fraction, format };
1009
- }
1010
- const date = parseDate(t);
1011
- if (date) return { kind: "date", date: date.date, format: date.format };
1012
- for (let i = t.indexOf(" "); i !== -1; i = t.indexOf(" ", i + 1)) {
1013
- const d = parseDate(t.slice(0, i));
1014
- const tm = d ? parseTime(t.slice(i + 1)) : null;
1015
- if (d && tm && tm.fraction < 1) {
1016
- return { kind: "date", date: { ...d.date, time: tm.fraction }, format: "m/d/yyyy h:mm" };
1017
- }
1018
- }
1019
- return null;
1020
- }
1021
-
1022
540
  // src/spreadsheet/formula/criteria.ts
1023
541
  function wildcardToRegExp(pattern) {
1024
542
  let source = "";
@@ -1097,1345 +615,6 @@ function parseCriteria(criterion) {
1097
615
  };
1098
616
  }
1099
617
 
1100
- // src/spreadsheet/numfmt/decimal.ts
1101
- var MAX_DECIMALS = 400;
1102
- function significantDigits(a, n) {
1103
- const s = a.toExponential(Math.max(0, Math.min(100, n - 1)));
1104
- const e = s.indexOf("e");
1105
- const digits = [];
1106
- for (let i = 0; i < e; i++) {
1107
- const c = s.charCodeAt(i);
1108
- if (c >= 48 && c <= 57) digits.push(c - 48);
1109
- }
1110
- return { digits, exp: Number(s.slice(e + 1)) };
1111
- }
1112
- function exactDigits(a) {
1113
- const view = new DataView(new ArrayBuffer(8));
1114
- view.setFloat64(0, a);
1115
- const hi = view.getUint32(0);
1116
- const lo = view.getUint32(4);
1117
- const biased = hi >>> 20 & 2047;
1118
- let mantissa = BigInt(hi & 1048575) << 32n | BigInt(lo);
1119
- let exp2;
1120
- if (biased === 0) {
1121
- exp2 = -1074;
1122
- } else {
1123
- mantissa |= 1n << 52n;
1124
- exp2 = biased - 1075;
1125
- }
1126
- const digits = exp2 >= 0 ? (mantissa << BigInt(exp2)).toString() : (mantissa * 5n ** BigInt(-exp2)).toString();
1127
- return digits.replace(/0+$/, "");
1128
- }
1129
- function isExactTie(a) {
1130
- const isTie = (ds) => ds.length >= 16 && ds[15] === "5" && /^0*$/.test(ds.slice(16));
1131
- return isTie(significantDigits(a, 30).digits.join("")) && isTie(exactDigits(a).padEnd(16, "0"));
1132
- }
1133
- function decimalDigits(a) {
1134
- if (!Number.isFinite(a) || a <= 0) return { digits: new Array(15).fill(0), exp: 0 };
1135
- const { digits: d16, exp } = significantDigits(a, 16);
1136
- const digits = d16.slice(0, 15);
1137
- while (digits.length < 15) digits.push(0);
1138
- const sixteenth = d16[15] ?? 0;
1139
- if (sixteenth <= 4) return { digits, exp };
1140
- if (sixteenth === 5) {
1141
- if (isExactTie(a)) return { digits, exp };
1142
- const r = significantDigits(a, 15);
1143
- while (r.digits.length < 15) r.digits.push(0);
1144
- return r;
1145
- }
1146
- let e = exp;
1147
- let carry = true;
1148
- for (let i = 14; i >= 0; i--) {
1149
- if (digits[i] === 9) {
1150
- digits[i] = 0;
1151
- } else {
1152
- digits[i] += 1;
1153
- carry = false;
1154
- break;
1155
- }
1156
- }
1157
- if (carry) {
1158
- digits.fill(0);
1159
- digits[0] = 1;
1160
- e += 1;
1161
- }
1162
- return { digits, exp: e };
1163
- }
1164
- function fixedFromDigits(digits, exp, decimals) {
1165
- const decimalsCalc = Math.min(decimals, MAX_DECIMALS);
1166
- const keep = exp + decimalsCalc + 1;
1167
- let m;
1168
- if (keep <= 0) {
1169
- m = keep === 0 && (digits[0] ?? 0) >= 5 ? [1] : [];
1170
- } else if (keep >= digits.length) {
1171
- m = digits.slice();
1172
- while (m.length < keep) m.push(0);
1173
- } else {
1174
- m = digits.slice(0, keep);
1175
- if ((digits[keep] ?? 0) >= 5) {
1176
- let carry = true;
1177
- for (let i = m.length - 1; i >= 0; i--) {
1178
- if (m[i] === 9) {
1179
- m[i] = 0;
1180
- } else {
1181
- m[i] += 1;
1182
- carry = false;
1183
- break;
1184
- }
1185
- }
1186
- if (carry) m.unshift(1);
1187
- }
1188
- }
1189
- let lead = 0;
1190
- while (lead < m.length && m[lead] === 0) lead++;
1191
- m = m.slice(lead);
1192
- const toS = (ds) => ds.join("");
1193
- let int;
1194
- let frac;
1195
- if (m.length <= decimalsCalc) {
1196
- int = "";
1197
- frac = "0".repeat(decimalsCalc - m.length) + toS(m);
1198
- } else {
1199
- const split = m.length - decimalsCalc;
1200
- int = toS(m.slice(0, split));
1201
- frac = toS(m.slice(split));
1202
- }
1203
- if (decimals > decimalsCalc) frac += "0".repeat(decimals - decimalsCalc);
1204
- return [int, frac];
1205
- }
1206
- function fixed(a, decimals) {
1207
- if (!Number.isFinite(a) || a <= 0) return ["", "0".repeat(Math.min(decimals, MAX_DECIMALS * 4))];
1208
- const { digits, exp } = decimalDigits(a);
1209
- return fixedFromDigits(digits, exp, decimals);
1210
- }
1211
- var charCount = (s) => Array.from(s).length;
1212
- function formatGeneralFit(n, maxChars) {
1213
- if (!Number.isFinite(n)) return null;
1214
- if (n === 0) return maxChars >= 1 ? "0" : null;
1215
- const sign = n < 0 ? "-" : "";
1216
- const { digits, exp: x } = decimalDigits(Math.abs(n));
1217
- const intLen = sign.length + Math.max(x, 0) + 1;
1218
- if (x >= -4 && intLen <= maxChars) {
1219
- const avail = maxChars - intLen;
1220
- let decimals = avail >= 2 ? avail - 1 : 0;
1221
- for (; ; ) {
1222
- const [i, f0] = fixedFromDigits(digits, x, decimals);
1223
- const f = f0.replace(/0+$/, "");
1224
- if (i === "" && f === "") break;
1225
- let s = sign + (i === "" ? "0" : i);
1226
- if (f !== "") s += `.${f}`;
1227
- if (charCount(s) <= maxChars) return s;
1228
- if (decimals === 0) break;
1229
- decimals -= 1;
1230
- }
1231
- }
1232
- for (let md = Math.min(maxChars, 14); md >= 0; md--) {
1233
- let e = x;
1234
- let [mi, mf] = fixedFromDigits(digits, 0, md);
1235
- if (mi.length > 1) {
1236
- e += 1;
1237
- [mi, mf] = fixedFromDigits(digits, -1, md);
1238
- }
1239
- mf = mf.replace(/0+$/, "");
1240
- let s = sign + (mi === "" ? "0" : mi);
1241
- if (mf !== "") s += `.${mf}`;
1242
- s += `E${e < 0 ? "-" : "+"}${String(Math.abs(e)).padStart(2, "0")}`;
1243
- if (charCount(s) <= maxChars) return s;
1244
- }
1245
- return null;
1246
- }
1247
-
1248
- // src/spreadsheet/numfmt/builtin.ts
1249
- var BUILTINS = [
1250
- [0, "General"],
1251
- [1, "0"],
1252
- [2, "0.00"],
1253
- [3, "#,##0"],
1254
- [4, "#,##0.00"],
1255
- [5, '"$"#,##0_);\\("$"#,##0\\)'],
1256
- [6, '"$"#,##0_);[Red]\\("$"#,##0\\)'],
1257
- [7, '"$"#,##0.00_);\\("$"#,##0.00\\)'],
1258
- [8, '"$"#,##0.00_);[Red]\\("$"#,##0.00\\)'],
1259
- [9, "0%"],
1260
- [10, "0.00%"],
1261
- [11, "0.00E+00"],
1262
- [12, "# ?/?"],
1263
- [13, "# ??/??"],
1264
- [14, "m/d/yyyy"],
1265
- [15, "d-mmm-yy"],
1266
- [16, "d-mmm"],
1267
- [17, "mmm-yy"],
1268
- [18, "h:mm AM/PM"],
1269
- [19, "h:mm:ss AM/PM"],
1270
- [20, "h:mm"],
1271
- [21, "h:mm:ss"],
1272
- [22, "m/d/yyyy h:mm"],
1273
- [37, "#,##0 ;(#,##0)"],
1274
- [38, "#,##0 ;[Red](#,##0)"],
1275
- [39, "#,##0.00;(#,##0.00)"],
1276
- [40, "#,##0.00;[Red](#,##0.00)"],
1277
- [41, '_(* #,##0_);_(* \\(#,##0\\);_(* "-"_);_(@_)'],
1278
- [42, '_("$"* #,##0_);_("$"* \\(#,##0\\);_("$"* "-"_);_(@_)'],
1279
- [43, '_(* #,##0.00_);_(* \\(#,##0.00\\);_(* "-"??_);_(@_)'],
1280
- [44, '_("$"* #,##0.00_);_("$"* \\(#,##0.00\\);_("$"* "-"??_);_(@_)'],
1281
- [45, "mm:ss"],
1282
- [46, "[h]:mm:ss"],
1283
- [47, "mmss.0"],
1284
- [48, "##0.0E+0"],
1285
- [49, "@"]
1286
- ];
1287
- function builtinNumberFormat(id) {
1288
- return BUILTINS.find(([i]) => i === id)?.[1];
1289
- }
1290
- function builtinNumberFormatId(code) {
1291
- const exact = BUILTINS.find(([, c]) => c === code);
1292
- if (exact) return exact[0];
1293
- const norm = (s) => s.replace(/\\/g, "").toLowerCase();
1294
- const n = norm(code);
1295
- return BUILTINS.find(([, c]) => norm(c) === n)?.[0];
1296
- }
1297
-
1298
- // src/spreadsheet/numfmt/parse.ts
1299
- var MAX_SECTIONS = 4;
1300
- var isCalendarPart = (d) => d.k === "year" || d.k === "month" || d.k === "day";
1301
- function literalText(tok) {
1302
- switch (tok.t) {
1303
- case "lit":
1304
- case "denom":
1305
- return tok.s;
1306
- case "digit":
1307
- return tok.c;
1308
- case "point":
1309
- return ".";
1310
- case "comma":
1311
- return ",";
1312
- case "percent":
1313
- return "%";
1314
- case "exp":
1315
- return `${tok.upper ? "E" : "e"}${tok.plus ? "+" : "-"}`;
1316
- case "slash":
1317
- return "/";
1318
- default:
1319
- return "";
1320
- }
1321
- }
1322
- function testCond(c, v) {
1323
- switch (c.op) {
1324
- case "=":
1325
- return v === c.value;
1326
- case "<>":
1327
- return v !== c.value;
1328
- case "<":
1329
- return v < c.value;
1330
- case "<=":
1331
- return v <= c.value;
1332
- case ">":
1333
- return v > c.value;
1334
- case ">=":
1335
- return v >= c.value;
1336
- }
1337
- }
1338
- var isDigitTok = (t, c) => t?.t === "digit" && (c === void 0 || t.c === c);
1339
- function splitSections(code) {
1340
- const cs = Array.from(code);
1341
- const lastClose = cs.lastIndexOf("]");
1342
- const out = [""];
1343
- let quoted = false;
1344
- let escape = false;
1345
- let i = 0;
1346
- while (i < cs.length) {
1347
- const c = cs[i];
1348
- i += 1;
1349
- const cur = out.length - 1;
1350
- if (escape) {
1351
- out[cur] += c;
1352
- escape = false;
1353
- continue;
1354
- }
1355
- if (c === '"') {
1356
- quoted = !quoted;
1357
- out[cur] += c;
1358
- } else if ((c === "\\" || c === "_" || c === "*") && !quoted) {
1359
- escape = true;
1360
- out[cur] += c;
1361
- } else if (c === "[" && !quoted && lastClose >= i) {
1362
- let s = c;
1363
- while (i < cs.length) {
1364
- const d = cs[i];
1365
- i += 1;
1366
- s += d;
1367
- if (d === "]") break;
1368
- }
1369
- out[cur] += s;
1370
- } else if (c === ";" && !quoted) {
1371
- if (out.length >= MAX_SECTIONS) break;
1372
- out.push("");
1373
- } else {
1374
- out[cur] += c;
1375
- }
1376
- }
1377
- return out;
1378
- }
1379
- var lowerAscii = (c) => c >= "A" && c <= "Z" ? c.toLowerCase() : c;
1380
- function startsWithCi(cs, i, pat) {
1381
- for (let k = 0; k < pat.length; k++) {
1382
- const c = cs[i + k];
1383
- if (c === void 0 || lowerAscii(c) !== pat[k]) return false;
1384
- }
1385
- return true;
1386
- }
1387
- function pushLit(toks, s) {
1388
- if (s === "") return;
1389
- const last = toks[toks.length - 1];
1390
- if (last?.t === "lit") last.s += s;
1391
- else toks.push({ t: "lit", s });
1392
- }
1393
- var CURRENCY_CHARS = /* @__PURE__ */ new Set(["$", "\u20AC", "\xA3", "\xA5", "\u20B9", "\u20A9", "\u20BD", "\xA2", "\u20AA", "\u20AB", "\u0E3F"]);
1394
- var isCurrencyChar = (c) => CURRENCY_CHARS.has(c);
1395
- var NAMED_COLORS = /* @__PURE__ */ new Set(["black", "blue", "cyan", "green", "magenta", "red", "white", "yellow"]);
1396
- function parseColor(lc) {
1397
- if (NAMED_COLORS.has(lc)) return lc;
1398
- if (!lc.startsWith("color")) return void 0;
1399
- const rest = lc.slice(5).trim();
1400
- if (!/^\+?\d{1,3}$/.test(rest)) return void 0;
1401
- const n = Number(rest);
1402
- return n >= 1 && n <= 56 ? `color${n}` : void 0;
1403
- }
1404
- function parseCond(s) {
1405
- const t = s.trim();
1406
- let op;
1407
- let rest;
1408
- if (t.startsWith("<=")) [op, rest] = ["<=", t.slice(2)];
1409
- else if (t.startsWith(">=")) [op, rest] = [">=", t.slice(2)];
1410
- else if (t.startsWith("<>")) [op, rest] = ["<>", t.slice(2)];
1411
- else if (t.startsWith("<")) [op, rest] = ["<", t.slice(1)];
1412
- else if (t.startsWith(">")) [op, rest] = [">", t.slice(1)];
1413
- else if (t.startsWith("=")) [op, rest] = ["=", t.slice(1)];
1414
- else return void 0;
1415
- const r = rest.trim();
1416
- if (!/^[+-]?(\d+\.?\d*|\.\d+)(e[+-]?\d+)?$/i.test(r)) return void 0;
1417
- const value = Number(r);
1418
- return Number.isFinite(value) ? { op, value } : void 0;
1419
- }
1420
- function bracket(raw, content) {
1421
- const lc = content.trim().toLowerCase();
1422
- const color = parseColor(lc);
1423
- if (color) {
1424
- raw.color = color;
1425
- return;
1426
- }
1427
- if (lc.startsWith("<") || lc.startsWith(">") || lc.startsWith("=")) {
1428
- const c = parseCond(lc);
1429
- if (c) raw.cond = c;
1430
- return;
1431
- }
1432
- if (content.startsWith("$")) {
1433
- const sym = content.slice(1).split("-")[0];
1434
- if (sym !== "") {
1435
- raw.currency = true;
1436
- pushLit(raw.toks, sym);
1437
- }
1438
- return;
1439
- }
1440
- const first = lc[0];
1441
- if ((first === "h" || first === "m" || first === "s") && Array.from(lc).every((c) => c === first)) {
1442
- const n = Math.min(Array.from(lc).length, 255);
1443
- raw.toks.push({ t: "date", d: { k: first === "h" ? "eh" : first === "m" ? "em" : "es", n } });
1444
- }
1445
- }
1446
- function tokenize(src) {
1447
- const cs = Array.from(src);
1448
- const raw = { toks: [], currency: false };
1449
- const toks = raw.toks;
1450
- const lastClose = cs.lastIndexOf("]");
1451
- let i = 0;
1452
- while (i < cs.length) {
1453
- const c = cs[i];
1454
- if (c === '"') {
1455
- let s = "";
1456
- i += 1;
1457
- while (i < cs.length) {
1458
- const d = cs[i];
1459
- i += 1;
1460
- if (d === '"') break;
1461
- s += d;
1462
- }
1463
- if (Array.from(s).some(isCurrencyChar)) raw.currency = true;
1464
- pushLit(toks, s);
1465
- continue;
1466
- }
1467
- if (c === "\\") {
1468
- const d = cs[i + 1];
1469
- if (d !== void 0) {
1470
- if (isCurrencyChar(d)) raw.currency = true;
1471
- pushLit(toks, d);
1472
- }
1473
- i += 2;
1474
- continue;
1475
- }
1476
- if (c === "_") {
1477
- if (cs[i + 1] !== void 0) pushLit(toks, " ");
1478
- i += 2;
1479
- continue;
1480
- }
1481
- if (c === "*") {
1482
- const d = cs[i + 1];
1483
- if (d !== void 0) toks.push({ t: "fill", c: d });
1484
- i += 2;
1485
- continue;
1486
- }
1487
- if (c === "[") {
1488
- const close = lastClose > i ? cs.indexOf("]", i + 1) : -1;
1489
- if (close !== -1) {
1490
- bracket(raw, cs.slice(i + 1, close).join(""));
1491
- i = close + 1;
1492
- } else {
1493
- pushLit(toks, "[");
1494
- i += 1;
1495
- }
1496
- continue;
1497
- }
1498
- if (c === "0" || c === "#" || c === "?") toks.push({ t: "digit", c });
1499
- else if (c === ".") toks.push({ t: "point" });
1500
- else if (c === ",") toks.push({ t: "comma" });
1501
- else if (c === "%") toks.push({ t: "percent" });
1502
- else if (c === "@") toks.push({ t: "at" });
1503
- else if (c === "/") {
1504
- toks.push({ t: "slash" });
1505
- i += 1;
1506
- if (cs[i] !== void 0 && cs[i] >= "1" && cs[i] <= "9") {
1507
- let s = "";
1508
- while (i < cs.length && cs[i] >= "0" && cs[i] <= "9") {
1509
- s += cs[i];
1510
- i += 1;
1511
- }
1512
- toks.push({ t: "denom", s });
1513
- }
1514
- continue;
1515
- } else if ((c === "e" || c === "E") && (cs[i + 1] === "+" || cs[i + 1] === "-")) {
1516
- toks.push({ t: "exp", upper: c === "E", plus: cs[i + 1] === "+" });
1517
- i += 2;
1518
- continue;
1519
- } else if ((c === "G" || c === "g") && startsWithCi(cs, i, "general")) {
1520
- toks.push({ t: "general" });
1521
- i += 7;
1522
- continue;
1523
- } else if ((c === "A" || c === "a") && startsWithCi(cs, i, "am/pm")) {
1524
- toks.push({ t: "date", d: { k: "ampm" } });
1525
- i += 5;
1526
- continue;
1527
- } else if ((c === "A" || c === "a") && startsWithCi(cs, i, "a/p")) {
1528
- toks.push({ t: "date", d: { k: "ap", a: c, p: cs[i + 2] ?? "P" } });
1529
- i += 3;
1530
- continue;
1531
- } else if ("yYmMdDhHsSeE".includes(c)) {
1532
- const lc = lowerAscii(c);
1533
- let n = 0;
1534
- while (cs[i + n] !== void 0 && lowerAscii(cs[i + n]) === lc) n += 1;
1535
- const n8 = Math.min(n, 255);
1536
- const d = lc === "y" ? { k: "year", n: n8 } : lc === "e" ? { k: "year", n: 4 } : lc === "m" ? { k: "month", n: n8 } : lc === "d" ? { k: "day", n: n8 } : lc === "h" ? { k: "hour", n: n8 } : { k: "second", n: n8 };
1537
- toks.push({ t: "date", d });
1538
- i += Math.max(n, 1);
1539
- continue;
1540
- } else {
1541
- if (isCurrencyChar(c)) raw.currency = true;
1542
- pushLit(toks, c);
1543
- }
1544
- i += 1;
1545
- }
1546
- return raw;
1547
- }
1548
- var datePartOf = (t) => t?.t === "date" ? t.d : void 0;
1549
- function analyze(raw) {
1550
- const toks = raw.toks;
1551
- const isDate = toks.some((t) => t.t === "date");
1552
- const hasGeneral = toks.some((t) => t.t === "general");
1553
- const sec = {
1554
- toks: [],
1555
- color: raw.color,
1556
- cond: raw.cond,
1557
- kind: "number",
1558
- thousands: false,
1559
- scale: 0,
1560
- percent: 0,
1561
- hasAt: toks.some((t) => t.t === "at"),
1562
- hasDigits: false,
1563
- exp: false,
1564
- fraction: false,
1565
- currency: raw.currency,
1566
- fill: toks.some((t) => t.t === "fill")
1567
- };
1568
- if (isDate) {
1569
- sec.kind = "date";
1570
- const prevPart = [];
1571
- let last;
1572
- for (let i2 = 0; i2 < toks.length; i2++) {
1573
- prevPart.push(last);
1574
- const d = datePartOf(toks[i2]);
1575
- if (d) last = d;
1576
- }
1577
- const nextPart = new Array(toks.length);
1578
- let next;
1579
- for (let i2 = toks.length - 1; i2 >= 0; i2--) {
1580
- nextPart[i2] = next;
1581
- const d = datePartOf(toks[i2]);
1582
- if (d) next = d;
1583
- }
1584
- for (let i2 = 0; i2 < toks.length; i2++) {
1585
- const t = toks[i2];
1586
- if (t.t !== "date" || t.d.k !== "month" || t.d.n > 2) continue;
1587
- const prev = prevPart[i2];
1588
- const nxt = nextPart[i2];
1589
- const afterH = prev?.k === "hour" || prev?.k === "eh";
1590
- const beforeS = nxt?.k === "second" || nxt?.k === "es";
1591
- if (afterH || beforeS) toks[i2] = { t: "date", d: { k: "minute", n: t.d.n } };
1592
- }
1593
- const out2 = [];
1594
- let i = 0;
1595
- while (i < toks.length) {
1596
- const t = toks[i];
1597
- if (t.t === "point" && isDigitTok(toks[i + 1], "0")) {
1598
- let n = 0;
1599
- while (isDigitTok(toks[i + 1 + n], "0")) n += 1;
1600
- out2.push({ t: "date", d: { k: "subsec", n: Math.min(n, 255) } });
1601
- i += 1 + n;
1602
- continue;
1603
- }
1604
- if (t.t === "date" || t.t === "fill") out2.push(t);
1605
- else pushLit(out2, literalText(t));
1606
- i += 1;
1607
- }
1608
- sec.toks = out2;
1609
- return sec;
1610
- }
1611
- if (hasGeneral) {
1612
- sec.kind = "general";
1613
- const out2 = [];
1614
- for (const t of toks) {
1615
- if (t.t === "general" || t.t === "fill") out2.push(t);
1616
- else pushLit(out2, literalText(t));
1617
- }
1618
- sec.toks = out2;
1619
- return sec;
1620
- }
1621
- sec.hasDigits = toks.some((t) => t.t === "digit");
1622
- if (sec.hasAt && !sec.hasDigits) {
1623
- sec.kind = "text";
1624
- const out2 = [];
1625
- for (const t of toks) {
1626
- if (t.t === "at" || t.t === "fill") out2.push(t);
1627
- else pushLit(out2, literalText(t));
1628
- }
1629
- sec.toks = out2;
1630
- return sec;
1631
- }
1632
- let seenPoint = false;
1633
- let seenExp = false;
1634
- let seenDigit = false;
1635
- let fractionSlash = false;
1636
- const digitAfterCommas = new Array(toks.length).fill(false);
1637
- const firstNonLitAfter = new Array(toks.length);
1638
- let after = false;
1639
- let nonLit;
1640
- for (let j = toks.length - 1; j >= 0; j--) {
1641
- digitAfterCommas[j] = after;
1642
- firstNonLitAfter[j] = nonLit;
1643
- const t = toks[j];
1644
- if (t.t !== "comma") after = t.t === "digit";
1645
- if (t.t !== "lit") nonLit = t;
1646
- }
1647
- let lastExp = -1;
1648
- for (let j = toks.length - 1; j >= 0; j--) {
1649
- if (toks[j].t === "exp") {
1650
- lastExp = j;
1651
- break;
1652
- }
1653
- }
1654
- const firstDigit = toks.findIndex((t) => t.t === "digit");
1655
- const scientific = firstDigit !== -1 && toks.slice(firstDigit).some((t) => t.t === "exp");
1656
- for (let i = 0; i < toks.length; i++) {
1657
- const t = toks[i];
1658
- let replace;
1659
- switch (t.t) {
1660
- case "digit":
1661
- seenDigit = true;
1662
- break;
1663
- case "point":
1664
- if (seenPoint || seenExp) replace = { t: "lit", s: "." };
1665
- else seenPoint = true;
1666
- break;
1667
- case "percent":
1668
- sec.percent += 1;
1669
- break;
1670
- case "exp":
1671
- if (seenExp || !seenDigit) replace = { t: "lit", s: literalText(t) };
1672
- else {
1673
- seenExp = true;
1674
- sec.exp = true;
1675
- }
1676
- break;
1677
- case "comma": {
1678
- const nextDigit = digitAfterCommas[i];
1679
- if (seenDigit && nextDigit && !seenPoint && !seenExp) {
1680
- sec.thousands = true;
1681
- replace = { t: "lit", s: "" };
1682
- } else if (seenDigit && scientific) {
1683
- replace = { t: "lit", s: "" };
1684
- } else if (seenDigit && !nextDigit) {
1685
- sec.scale += 1;
1686
- replace = { t: "lit", s: "" };
1687
- } else {
1688
- replace = { t: "lit", s: "," };
1689
- }
1690
- break;
1691
- }
1692
- case "slash": {
1693
- const nextOk = toks[i + 1]?.t === "denom" || firstNonLitAfter[i]?.t === "digit";
1694
- const hasExp = seenExp || lastExp > i;
1695
- if (!fractionSlash && seenDigit && nextOk && !seenPoint && !hasExp) {
1696
- fractionSlash = true;
1697
- sec.fraction = true;
1698
- } else {
1699
- replace = { t: "lit", s: "/" };
1700
- }
1701
- break;
1702
- }
1703
- case "denom":
1704
- if (!(toks[i - 1]?.t === "slash" && sec.fraction)) replace = { t: "lit", s: t.s };
1705
- break;
1706
- default:
1707
- break;
1708
- }
1709
- if (replace) toks[i] = replace;
1710
- }
1711
- if (sec.fraction) {
1712
- for (let i = 0; i < toks.length; i++) if (toks[i].t === "point") toks[i] = { t: "lit", s: "." };
1713
- }
1714
- const out = [];
1715
- for (const t of toks) {
1716
- if (t.t === "lit") pushLit(out, t.s);
1717
- else out.push(t);
1718
- }
1719
- sec.toks = out;
1720
- return sec;
1721
- }
1722
- function parseSections(code) {
1723
- return splitSections(code).map((s) => analyze(tokenize(s)));
1724
- }
1725
-
1726
- // src/spreadsheet/numfmt/render.ts
1727
- var MAX_DATE_SERIAL = 2958465;
1728
- var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
1729
- var WEEKDAYS = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
1730
- var UNIX_1899_12_302 = -25569;
1731
- function civilFromDays(z0) {
1732
- const z = z0 + 719468;
1733
- const era = Math.floor(z / 146097);
1734
- const doe = z - era * 146097;
1735
- const yoe = Math.floor((doe - Math.floor(doe / 1460) + Math.floor(doe / 36524) - Math.floor(doe / 146096)) / 365);
1736
- const doy = doe - (365 * yoe + Math.floor(yoe / 4) - Math.floor(yoe / 100));
1737
- const mp = Math.floor((5 * doy + 2) / 153);
1738
- const d = doy - Math.floor((153 * mp + 2) / 5) + 1;
1739
- const m = mp < 10 ? mp + 3 : mp - 9;
1740
- return { y: yoe + era * 400 + (m <= 2 ? 1 : 0), m, d };
1741
- }
1742
- function dateFromSerial(day) {
1743
- const weekday = ((day + 6) % 7 + 7) % 7;
1744
- if (day === 60) return { year: 1900, month: 2, day: 29, weekday };
1745
- if (day === 0) return { year: 1900, month: 1, day: 0, weekday };
1746
- const real = day < 60 ? day + 1 : day;
1747
- const { y, m, d } = civilFromDays(real + UNIX_1899_12_302);
1748
- return { year: y, month: m, day: d, weekday };
1749
- }
1750
- var Out = class {
1751
- text = "";
1752
- fill;
1753
- /** True when every digit shown is zero (a number section that rounded to zero). */
1754
- zero = false;
1755
- push(s) {
1756
- this.text += s;
1757
- }
1758
- setFill(c) {
1759
- if (!this.fill) this.fill = { char: c, index: this.text.length };
1760
- }
1761
- prepend(s) {
1762
- this.text = s + this.text;
1763
- if (this.fill) this.fill.index += s.length;
1764
- }
1765
- };
1766
- function renderText(sec, text) {
1767
- const out = new Out();
1768
- for (const t of sec.toks) {
1769
- if (t.t === "at") out.push(text);
1770
- else if (t.t === "fill") out.setFill(t.c);
1771
- else out.push(literalText(t));
1772
- }
1773
- return out;
1774
- }
1775
- function renderGeneral(sec, v, width) {
1776
- const out = new Out();
1777
- for (const t of sec.toks) {
1778
- if (t.t === "general") out.push(formatGeneralFit(v, width) ?? "#".repeat(Math.min(Math.max(width, 1), 11)));
1779
- else if (t.t === "fill") out.setFill(t.c);
1780
- else out.push(literalText(t));
1781
- }
1782
- return out;
1783
- }
1784
- var padNum = (n, w) => w >= 2 ? String(n).padStart(Math.min(w, 20), "0") : String(n);
1785
- function renderDate(sec, v) {
1786
- if (!Number.isFinite(v) || v < 0 || v >= MAX_DATE_SERIAL + 1) return null;
1787
- let subDigits = 0;
1788
- for (const t of sec.toks) if (t.t === "date" && t.d.k === "subsec") subDigits = Math.max(subDigits, t.d.n);
1789
- subDigits = Math.min(subDigits, 3);
1790
- const unit = 10 ** (3 - subDigits);
1791
- let day = Math.floor(v);
1792
- let ms = Math.round((v - Math.floor(v)) * 864e5 / unit) * unit;
1793
- if (ms >= 864e5) {
1794
- ms -= 864e5;
1795
- day += 1;
1796
- }
1797
- const totalMs = day * 864e5 + ms;
1798
- const needsDate = sec.toks.some((t) => t.t === "date" && isCalendarPart(t.d));
1799
- if (needsDate && day > MAX_DATE_SERIAL) return null;
1800
- const dt = needsDate ? dateFromSerial(day) : dateFromSerial(0);
1801
- const ampm = sec.toks.some((t) => t.t === "date" && (t.d.k === "ampm" || t.d.k === "ap"));
1802
- const hour = Math.floor(ms / 36e5);
1803
- const minute = Math.floor(ms / 6e4) % 60;
1804
- const second = Math.floor(ms / 1e3) % 60;
1805
- const milli = ms % 1e3;
1806
- const monthName = MONTHS[dt.month - 1] ?? "";
1807
- const dayName = WEEKDAYS[dt.weekday] ?? "";
1808
- const out = new Out();
1809
- for (const t of sec.toks) {
1810
- if (t.t === "fill") {
1811
- out.setFill(t.c);
1812
- continue;
1813
- }
1814
- if (t.t !== "date") {
1815
- out.push(literalText(t));
1816
- continue;
1817
- }
1818
- const d = t.d;
1819
- let s;
1820
- switch (d.k) {
1821
- case "year":
1822
- s = d.n <= 2 ? String((dt.year % 100 + 100) % 100).padStart(2, "0") : String(dt.year).padStart(4, "0");
1823
- break;
1824
- case "month":
1825
- s = d.n <= 2 ? padNum(dt.month, d.n) : d.n === 3 ? monthName.slice(0, 3) : d.n === 5 ? monthName.slice(0, 1) : monthName;
1826
- break;
1827
- case "day":
1828
- s = d.n <= 2 ? padNum(dt.day, d.n) : d.n === 3 ? dayName.slice(0, 3) : dayName;
1829
- break;
1830
- case "hour":
1831
- s = padNum(ampm ? hour % 12 || 12 : hour, d.n);
1832
- break;
1833
- case "minute":
1834
- s = padNum(minute, d.n);
1835
- break;
1836
- case "second":
1837
- s = padNum(second, d.n);
1838
- break;
1839
- case "subsec": {
1840
- s = `.${String(milli).padStart(3, "0")}`.slice(0, 1 + Math.min(d.n, 3));
1841
- if (d.n > 3) s += "0".repeat(d.n - 3);
1842
- break;
1843
- }
1844
- case "eh":
1845
- s = padNum(Math.floor(totalMs / 36e5), d.n);
1846
- break;
1847
- case "em":
1848
- s = padNum(Math.floor(totalMs / 6e4), d.n);
1849
- break;
1850
- case "es":
1851
- s = padNum(Math.floor(totalMs / 1e3), d.n);
1852
- break;
1853
- case "ampm":
1854
- s = hour >= 12 ? "PM" : "AM";
1855
- break;
1856
- case "ap":
1857
- s = hour >= 12 ? d.p : d.a;
1858
- break;
1859
- }
1860
- out.push(s);
1861
- }
1862
- return out;
1863
- }
1864
- var digitChar = (toks, i) => {
1865
- const t = toks[i];
1866
- return t?.t === "digit" ? t.c : "0";
1867
- };
1868
- function fillInt(toks, idxs, digits, thousands, forceZero, pieces) {
1869
- let rem = digits.length;
1870
- let pos = 0;
1871
- const count = idxs.length;
1872
- for (let k = 0; k < count; k++) {
1873
- const ti = idxs[count - 1 - k];
1874
- const leftmost = k + 1 === count;
1875
- const ph = digitChar(toks, ti);
1876
- const rev = [];
1877
- const pushDigit = (c) => {
1878
- if (thousands && pos > 0 && pos % 3 === 0) rev.push(",");
1879
- rev.push(c);
1880
- pos += 1;
1881
- };
1882
- const take = leftmost ? rem : Math.min(rem, 1);
1883
- if (take === 0) {
1884
- if (ph === "0") pushDigit("0");
1885
- else if (forceZero && k === 0) pushDigit("0");
1886
- else if (ph === "?") {
1887
- if (thousands && pos > 0 && pos % 3 === 0) rev.push(" ");
1888
- rev.push(" ");
1889
- pos += 1;
1890
- }
1891
- } else {
1892
- for (let n = 0; n < take; n++) {
1893
- rem -= 1;
1894
- pushDigit(digits[rem] ?? "0");
1895
- }
1896
- }
1897
- pieces[ti] = rev.reverse().join("");
1898
- }
1899
- }
1900
- function withCommas(digits, thousands) {
1901
- if (!thousands) return digits;
1902
- const n = digits.length;
1903
- let s = "";
1904
- for (let i = 0; i < n; i++) {
1905
- if (i > 0 && (n - i) % 3 === 0) s += ",";
1906
- s += digits[i];
1907
- }
1908
- return s;
1909
- }
1910
- function fillFrac(toks, idxs, frac, pieces) {
1911
- let lastSig = -1;
1912
- for (let i = frac.length - 1; i >= 0; i--) {
1913
- if (frac[i] !== "0") {
1914
- lastSig = i;
1915
- break;
1916
- }
1917
- }
1918
- idxs.forEach((ti, i) => {
1919
- const ph = digitChar(toks, ti);
1920
- pieces[ti] = i <= lastSig ? frac[i] ?? "0" : ph === "0" ? "0" : ph === "?" ? " " : "";
1921
- });
1922
- }
1923
- function digitIndices(toks, start, end) {
1924
- const out = [];
1925
- for (let i = start; i < end; i++) if (toks[i]?.t === "digit") out.push(i);
1926
- return out;
1927
- }
1928
- function renderNumber(sec, v) {
1929
- let x = Math.abs(v);
1930
- if (sec.percent > 0 && !sec.exp) x *= 100 ** Math.min(sec.percent, 20);
1931
- if (sec.scale > 0) x /= 1e3 ** Math.min(sec.scale, 110);
1932
- if (!Number.isFinite(x)) x = Number.MAX_VALUE;
1933
- const toks = sec.toks;
1934
- const n = toks.length;
1935
- const pieces = new Array(n).fill("");
1936
- const before = new Array(n + 1).fill("");
1937
- const lits = new Array(n);
1938
- let zero = false;
1939
- if (sec.fraction) {
1940
- renderFraction(sec, x, pieces, lits);
1941
- } else {
1942
- const pointIdx = toks.findIndex((t) => t.t === "point");
1943
- const expIdx = toks.findIndex((t) => t.t === "exp");
1944
- const point = pointIdx === -1 ? void 0 : pointIdx;
1945
- const exp = expIdx === -1 ? void 0 : expIdx;
1946
- const intEnd = point ?? exp ?? n;
1947
- const fracEnd = exp ?? n;
1948
- const intIdx = digitIndices(toks, 0, intEnd);
1949
- const fracIdx = point === void 0 ? [] : digitIndices(toks, point + 1, fracEnd);
1950
- let intS;
1951
- let fracS;
1952
- if (exp !== void 0) {
1953
- const expDigitIdx = digitIndices(toks, exp + 1, n);
1954
- const step = Math.max(intIdx.length, 1);
1955
- let e;
1956
- if (x === 0) {
1957
- e = 0;
1958
- intS = "0".repeat(intIdx.length);
1959
- fracS = "0".repeat(fracIdx.length);
1960
- } else {
1961
- const { digits, exp: xe } = decimalDigits(x);
1962
- e = xe - (xe % step + step) % step;
1963
- [intS, fracS] = fixedFromDigits(digits, xe - e, fracIdx.length);
1964
- if (intS.length > step) {
1965
- e += step;
1966
- [intS, fracS] = fixedFromDigits(digits, xe - e, fracIdx.length);
1967
- }
1968
- }
1969
- const et = toks[exp];
1970
- const upper = et.t === "exp" ? et.upper : true;
1971
- const plus = et.t === "exp" ? et.plus : true;
1972
- if (intS === "" && /^0*$/.test(fracS)) e = 0;
1973
- const head = upper ? "E" : "e";
1974
- const sign = e < 0 ? "-" : plus ? "+" : "";
1975
- const expDigits = String(Math.abs(e));
1976
- if (expDigitIdx.length > 0) {
1977
- pieces[exp] = head;
1978
- before[expDigitIdx[0]] = sign;
1979
- fillInt(toks, expDigitIdx, expDigits, false, false, pieces);
1980
- } else {
1981
- pieces[exp] = `${head}${sign}${expDigits}`;
1982
- }
1983
- } else {
1984
- [intS, fracS] = fixed(x, fracIdx.length);
1985
- }
1986
- zero = /^0*$/.test(intS + fracS);
1987
- fillInt(toks, intIdx, intS, sec.thousands, false, pieces);
1988
- const anchor = point ?? exp;
1989
- if (intIdx.length === 0 && intS !== "" && anchor !== void 0) before[anchor] = withCommas(intS, sec.thousands);
1990
- fillFrac(toks, fracIdx, fracS, pieces);
1991
- if (point !== void 0) pieces[point] = ".";
1992
- }
1993
- const out = new Out();
1994
- for (let i = 0; i < n; i++) {
1995
- out.push(before[i]);
1996
- const t = toks[i];
1997
- if (t.t === "lit") out.push(lits[i] ?? t.s);
1998
- else if (t.t === "percent") out.push("%");
1999
- else if (t.t === "fill") out.setFill(t.c);
2000
- else if (t.t === "at" || t.t === "general" || t.t === "date" || t.t === "comma") continue;
2001
- else out.push(pieces[i]);
2002
- }
2003
- out.zero = zero;
2004
- return out;
2005
- }
2006
- function approximate(x, maxDen) {
2007
- if (Number.isNaN(x) || x <= 0 || !Number.isFinite(x)) return [0, 1];
2008
- if (x >= 1e15) return [Math.round(x), 1];
2009
- let [p0, q0, p1, q1] = [0, 1, 1, 0];
2010
- let r = x;
2011
- for (let iter = 0; iter < 64; iter++) {
2012
- const aF = Math.floor(r);
2013
- if (aF > 1e15) break;
2014
- const q2 = aF * q1 + q0;
2015
- if (q2 > maxDen) break;
2016
- const p2 = aF * p1 + p0;
2017
- [p0, q0, p1, q1] = [p1, q1, p2, q2];
2018
- const frac = r - aF;
2019
- if (frac < 1e-12) break;
2020
- r = 1 / frac;
2021
- }
2022
- if (q1 === 0) return [Math.round(x), 1];
2023
- const k = Math.floor((maxDen - q0) / q1);
2024
- const pb = p0 + k * p1;
2025
- const qb = q0 + k * q1;
2026
- const errA = Math.abs(p1 / q1 - x);
2027
- const errB = qb > 0 ? Math.abs(pb / qb - x) : Infinity;
2028
- return errB < errA ? [pb, qb] : [p1, q1];
2029
- }
2030
- function shownWidth(t) {
2031
- if (t.t === "lit" || t.t === "denom") return Array.from(t.s).length;
2032
- return t.t === "digit" || t.t === "slash" ? 1 : 0;
2033
- }
2034
- function blankRange(toks, start, end, spaces, pieces, lits) {
2035
- for (let i = start; i < end && i < toks.length; i++) {
2036
- const t = toks[i];
2037
- const s = spaces ? " ".repeat(shownWidth(t)) : "";
2038
- if (t.t === "lit") lits[i] = s;
2039
- else if (t.t === "digit" || t.t === "slash" || t.t === "denom") pieces[i] = s;
2040
- }
2041
- }
2042
- function renderFraction(sec, x, pieces, lits) {
2043
- const toks = sec.toks;
2044
- const isDigit = (i) => toks[i]?.t === "digit";
2045
- const slash = toks.findIndex((t) => t.t === "slash");
2046
- if (slash === -1) return;
2047
- let numLast = -1;
2048
- for (let i = slash - 1; i >= 0; i--) {
2049
- if (isDigit(i)) {
2050
- numLast = i;
2051
- break;
2052
- }
2053
- }
2054
- if (numLast === -1) return;
2055
- let numStart = numLast;
2056
- while (numStart > 0 && isDigit(numStart - 1)) numStart -= 1;
2057
- const wholeIdx = digitIndices(toks, 0, numStart);
2058
- const numIdx = digitIndices(toks, numStart, numLast + 1);
2059
- const sepStart = wholeIdx.length > 0 ? wholeIdx[wholeIdx.length - 1] + 1 : numStart;
2060
- let fixedDen;
2061
- let denStart;
2062
- const afterSlash = toks[slash + 1];
2063
- if (afterSlash?.t === "denom") {
2064
- const parsed = Number(afterSlash.s);
2065
- fixedDen = Math.min(Math.max(Number.isFinite(parsed) ? parsed : 1e9, 1), 1e9);
2066
- denStart = slash + 1;
2067
- } else {
2068
- denStart = slash + 1;
2069
- while (toks[denStart]?.t === "lit") denStart += 1;
2070
- }
2071
- let denEnd = denStart;
2072
- if (fixedDen !== void 0) denEnd += 1;
2073
- else while (isDigit(denEnd)) denEnd += 1;
2074
- const denIdx = digitIndices(toks, denStart, denEnd);
2075
- const hasQ = (idx) => idx.some((i) => isDigitTok2(toks[i], "?"));
2076
- const hasWhole = wholeIdx.length > 0;
2077
- let whole = hasWhole ? Math.floor(x) : 0;
2078
- const f = hasWhole ? x - Math.floor(x) : x;
2079
- let num;
2080
- let den;
2081
- if (fixedDen !== void 0) {
2082
- num = Math.round(f * fixedDen);
2083
- den = fixedDen;
2084
- } else {
2085
- const digits = Math.min(Math.max(denIdx.length, 1), 7);
2086
- [num, den] = approximate(f, 10 ** digits - 1);
2087
- }
2088
- if (hasWhole && num >= den && den > 0) {
2089
- whole += Math.floor(num / den);
2090
- num %= den;
2091
- }
2092
- const wholeS = whole >= 1 ? fixed(whole, 0)[0] : "";
2093
- const numZeroPh = numIdx.some((i) => isDigitTok2(toks[i], "0"));
2094
- if (hasWhole && num === 0 && !numZeroPh) {
2095
- fillInt(toks, wholeIdx, wholeS, sec.thousands, true, pieces);
2096
- const spaces = hasQ(wholeIdx) || hasQ(numIdx) || hasQ(denIdx);
2097
- blankRange(toks, sepStart, denEnd, spaces, pieces, lits);
2098
- return;
2099
- }
2100
- if (hasWhole) {
2101
- const unitsHash = isDigitTok2(toks[wholeIdx[wholeIdx.length - 1]], "#");
2102
- const force = wholeS === "" && num === 0 && !unitsHash;
2103
- fillInt(toks, wholeIdx, wholeS, sec.thousands, force, pieces);
2104
- const wholeShown = wholeIdx.some((i) => /[0-9]/.test(pieces[i] ?? ""));
2105
- if (!wholeShown) {
2106
- const spaces = hasQ(wholeIdx) || hasQ(numIdx);
2107
- blankRange(toks, sepStart, numStart, spaces, pieces, lits);
2108
- }
2109
- }
2110
- fillInt(toks, numIdx, fixed(num, 0)[0] || "0", false, true, pieces);
2111
- pieces[slash] = "/";
2112
- const denS = fixed(den, 0)[0] || "0";
2113
- if (fixedDen !== void 0) {
2114
- pieces[denStart] = denS;
2115
- } else {
2116
- const zeros = denIdx.filter((i) => isDigitTok2(toks[i], "0")).length;
2117
- const padded = "0".repeat(Math.max(zeros - denS.length, 0)) + denS;
2118
- const count = denIdx.length;
2119
- denIdx.forEach((ti, k) => {
2120
- let s = k + 1 === count ? padded.slice(k) : padded[k] ?? "";
2121
- if (s === "") s = isDigitTok2(toks[ti], "?") ? " " : isDigitTok2(toks[ti], "0") ? "0" : "";
2122
- pieces[ti] = s;
2123
- });
2124
- }
2125
- }
2126
- function isDigitTok2(t, c) {
2127
- return t?.t === "digit" && t.c === c;
2128
- }
2129
-
2130
- // src/spreadsheet/numfmt/index.ts
2131
- var GENERAL_WIDTH = 11;
2132
- var OVERFLOW = "########";
2133
- var MAX_NUMBER_FORMAT_CODE_CHARS = 255;
2134
- function tooLong(code) {
2135
- return code.length > MAX_NUMBER_FORMAT_CODE_CHARS && Array.from(code).length > MAX_NUMBER_FORMAT_CODE_CHARS;
2136
- }
2137
- var SPECIAL_CODES = ["00000", "00000-0000", "[<=9999999]###-####;(###) ###-####", "000-00-0000"];
2138
- var NumberFormat = class _NumberFormat {
2139
- code;
2140
- general;
2141
- sections;
2142
- /** Sections that apply to numbers (a trailing text section is excluded). */
2143
- numSections;
2144
- /** Index of the section that applies to text, if any. */
2145
- textSection;
2146
- constructor(code, uncapped) {
2147
- this.code = code;
2148
- const trimmed = code.trim();
2149
- if (trimmed === "" || trimmed.toLowerCase() === "general" || trimmed === "checkbox" || !uncapped && tooLong(code)) {
2150
- this.general = true;
2151
- this.sections = [];
2152
- this.numSections = 0;
2153
- this.textSection = void 0;
2154
- return;
2155
- }
2156
- this.general = false;
2157
- this.sections = parseSections(code);
2158
- const len = this.sections.length;
2159
- const lastIsText = this.sections[len - 1]?.kind === "text";
2160
- this.textSection = len >= 4 ? 3 : lastIsText ? len - 1 : void 0;
2161
- this.numSections = len >= 4 ? 3 : lastIsText ? len - 1 : len;
2162
- }
2163
- /**
2164
- * Parses a format code. Never throws: unknown or malformed parts degrade to
2165
- * literal text, and a code longer than 255 characters degrades to General.
2166
- */
2167
- static parse(code) {
2168
- return new _NumberFormat(code, false);
2169
- }
2170
- /** `parse` without the 255-character cap (for tests that reach renderer edge cases). */
2171
- static parseUncapped(code) {
2172
- return new _NumberFormat(code, true);
2173
- }
2174
- /** Like `parse`, but remembers recently parsed codes (bounded), so formatting many values parses a code once. */
2175
- static parseCached(code) {
2176
- if (code.length > CACHE_MAX_CODE_LENGTH) return _NumberFormat.parse(code);
2177
- let fmt = parseCache.get(code);
2178
- if (!fmt) {
2179
- fmt = _NumberFormat.parse(code);
2180
- if (parseCache.size >= CACHE_CAPACITY) parseCache.clear();
2181
- parseCache.set(code, fmt);
2182
- }
2183
- return fmt;
2184
- }
2185
- static general() {
2186
- return _NumberFormat.parse("General");
2187
- }
2188
- isGeneral() {
2189
- return this.general;
2190
- }
2191
- numberSections() {
2192
- return this.sections.slice(0, this.numSections);
2193
- }
2194
- /** True when the code contains date or time tokens. */
2195
- isDate() {
2196
- return this.numberSections().some((s) => s.kind === "date");
2197
- }
2198
- isPercent() {
2199
- return this.numberSections().some((s) => s.kind === "number" && s.percent > 0);
2200
- }
2201
- /** True for a pure text format such as `@`. */
2202
- isText() {
2203
- return this.numSections === 0 && this.textSection !== void 0;
2204
- }
2205
- /** Best guess at the format category. */
2206
- kind() {
2207
- if (this.general) return "general";
2208
- if (this.isText()) return "text";
2209
- if (SPECIAL_CODES.includes(this.code)) return "special";
2210
- const s = this.sections[0];
2211
- if (!s) return "custom";
2212
- if (s.kind === "general") return "general";
2213
- if (s.kind === "text") return "text";
2214
- if (s.kind === "date") {
2215
- const calendar = s.toks.some((t) => t.t === "date" && (t.d.k === "year" || t.d.k === "month" || t.d.k === "day"));
2216
- return calendar ? "date" : "time";
2217
- }
2218
- if (s.fraction) return "fraction";
2219
- if (s.exp) return "scientific";
2220
- if (s.percent > 0) return "percentage";
2221
- if (s.fill && s.hasDigits) return "accounting";
2222
- if (s.currency && s.hasDigits) return "currency";
2223
- if (s.hasDigits) return "number";
2224
- return "custom";
2225
- }
2226
- /**
2227
- * Picks the number section for `v`, and whether the minus sign is dropped
2228
- * (a negative section shows the absolute value). Null means General.
2229
- */
2230
- select(v) {
2231
- const secs = this.numberSections();
2232
- const k = secs.length;
2233
- const s0 = secs[0];
2234
- if (!s0) return null;
2235
- const c0 = s0.cond;
2236
- const c1 = secs[1]?.cond;
2237
- if (c0 || c1) {
2238
- let idx;
2239
- if (c0 && testCond(c0, v)) idx = 0;
2240
- else if (c1 && testCond(c1, v)) idx = 1;
2241
- else if (c0 && c1) idx = 2;
2242
- else if (!c0) idx = 0;
2243
- else idx = 1;
2244
- const sec = secs[idx];
2245
- return sec ? { sec, dropSign: k >= 2 } : null;
2246
- }
2247
- if (v < 0 && k >= 2) return { sec: secs[1], dropSign: true };
2248
- if (v === 0 && k >= 3) return { sec: secs[2], dropSign: false };
2249
- return { sec: s0, dropSign: false };
2250
- }
2251
- /**
2252
- * Formats a number. `overflow` is true when the value can't be shown (a
2253
- * date out of range, painted as `########`).
2254
- */
2255
- formatNumber(n) {
2256
- const general = () => ({
2257
- text: formatGeneralFit(n, GENERAL_WIDTH) ?? OVERFLOW,
2258
- numeric: true,
2259
- overflow: false
2260
- });
2261
- if (!Number.isFinite(n)) return { text: "#NUM!", numeric: false, overflow: true };
2262
- if (this.general) return general();
2263
- const picked = this.select(n);
2264
- if (!picked) return general();
2265
- const { sec, dropSign } = picked;
2266
- const minus = n < 0 && !dropSign;
2267
- let out;
2268
- switch (sec.kind) {
2269
- case "text":
2270
- out = renderText(sec, formatGeneralFit(n, GENERAL_WIDTH) ?? "");
2271
- break;
2272
- case "general":
2273
- out = renderGeneral(sec, Math.abs(n), minus ? GENERAL_WIDTH - 1 : GENERAL_WIDTH);
2274
- break;
2275
- case "date":
2276
- out = minus ? null : renderDate(sec, Math.abs(n));
2277
- break;
2278
- default:
2279
- out = renderNumber(sec, Math.abs(n));
2280
- }
2281
- if (!out) return withColor({ text: OVERFLOW, numeric: true, overflow: true }, sec.color);
2282
- if (minus && sec.kind !== "text" && !out.zero) out.prepend("-");
2283
- return withColor({ text: out.text, numeric: true, overflow: false, ...out.fill ? { fill: out.fill } : {} }, sec.color);
2284
- }
2285
- /** Formats text through the text section (`@`), or returns it unchanged. */
2286
- formatText(text) {
2287
- const sec = this.textSection === void 0 ? void 0 : this.sections[this.textSection];
2288
- if (!sec) return { text, numeric: false };
2289
- const out = renderText(sec, text);
2290
- return withColor({ text: out.text, numeric: false, ...out.fill ? { fill: out.fill } : {} }, sec.color);
2291
- }
2292
- /**
2293
- * Formats a cell value: numbers through the number sections, ISO date text
2294
- * (`2026-03-04`, `2026-03-04 18:00:00`) and `Date`s as serial numbers, other
2295
- * text through the text section; booleans show TRUE/FALSE and error values
2296
- * themselves.
2297
- */
2298
- format(value) {
2299
- if (value === "" || value === null || value === void 0) return { text: "", numeric: false };
2300
- if (typeof value === "boolean") return { text: value ? "TRUE" : "FALSE", numeric: false };
2301
- if (typeof value === "number") {
2302
- const { overflow: _overflow, ...rest } = this.formatNumber(value);
2303
- return rest;
2304
- }
2305
- if (typeof value === "string" && FORMULA_ERRORS.has(value)) return { text: value, numeric: false };
2306
- const serial = dateValueToSerial(value);
2307
- if (serial !== null) {
2308
- const { overflow: _overflow, ...rest } = this.formatNumber(serial);
2309
- return rest;
2310
- }
2311
- return this.formatText(String(value));
2312
- }
2313
- };
2314
- function withColor(value, color) {
2315
- if (color) value.color = color;
2316
- return value;
2317
- }
2318
- var CACHE_CAPACITY = 64;
2319
- var CACHE_MAX_CODE_LENGTH = 256;
2320
- var parseCache = /* @__PURE__ */ new Map();
2321
- function clearNumberFormatCache() {
2322
- parseCache.clear();
2323
- }
2324
- var ISO_DATE_TIME = /^(\d{4})-(\d{1,2})-(\d{1,2})(?:[ T](\d{1,2}):(\d{2})(?::(\d{2}(?:\.\d+)?))?)?$/;
2325
- function dateValueToSerial(value) {
2326
- if (value instanceof Date) {
2327
- if (isNaN(value.getTime())) return null;
2328
- const serial2 = serialFromYmd(value.getFullYear(), value.getMonth() + 1, value.getDate());
2329
- return serial2 === null ? null : serial2 + timeFraction(value.getHours(), value.getMinutes(), value.getSeconds() + value.getMilliseconds() / 1e3);
2330
- }
2331
- if (typeof value !== "string" || value.length < 8 || value.length > 30) return null;
2332
- const m = ISO_DATE_TIME.exec(value.trim());
2333
- if (!m) return null;
2334
- const [y, mo, d] = [Number(m[1]), Number(m[2]), Number(m[3])];
2335
- if (mo < 1 || mo > 12 || d < 1 || d > daysInMonth(y, mo)) return null;
2336
- const serial = serialFromYmd(y, mo, d);
2337
- if (serial === null) return null;
2338
- if (m[4] === void 0) return serial;
2339
- const [hh, mm, ss] = [Number(m[4]), Number(m[5]), Number(m[6] ?? 0)];
2340
- if (hh > 23 || mm > 59 || ss >= 60) return null;
2341
- return serial + timeFraction(hh, mm, ss);
2342
- }
2343
- function formatNumberFormatValue(value, code) {
2344
- return NumberFormat.parseCached(code).format(value);
2345
- }
2346
- function formatTextFunction(value, code) {
2347
- if (typeof value === "string" && FORMULA_ERRORS.has(value)) return { error: value };
2348
- if (code === "") return { text: "" };
2349
- if (tooLong(code)) return { error: "#VALUE!" };
2350
- const fmt = NumberFormat.parseCached(code);
2351
- let n;
2352
- if (value === "" || value === null || value === void 0) n = 0;
2353
- else if (typeof value === "number") n = value;
2354
- else if (typeof value === "boolean") return { text: fmt.formatText(value ? "TRUE" : "FALSE").text };
2355
- else {
2356
- const serial = dateValueToSerial(value);
2357
- const parsed = serial ?? (typeof value === "string" ? parseNumberText(value) : null);
2358
- if (parsed === null) return { text: fmt.formatText(String(value)).text };
2359
- n = parsed;
2360
- }
2361
- if (!Number.isFinite(n)) return { error: "#NUM!" };
2362
- const f = fmt.formatNumber(n);
2363
- return f.overflow ? { error: "#VALUE!" } : { text: f.text };
2364
- }
2365
- var INDEXED_COLORS = [
2366
- "#000000",
2367
- "#FFFFFF",
2368
- "#FF0000",
2369
- "#00FF00",
2370
- "#0000FF",
2371
- "#FFFF00",
2372
- "#FF00FF",
2373
- "#00FFFF",
2374
- "#800000",
2375
- "#008000",
2376
- "#000080",
2377
- "#808000",
2378
- "#800080",
2379
- "#008080",
2380
- "#C0C0C0",
2381
- "#808080",
2382
- "#9999FF",
2383
- "#993366",
2384
- "#FFFFCC",
2385
- "#CCFFFF",
2386
- "#660066",
2387
- "#FF8080",
2388
- "#0066CC",
2389
- "#CCCCFF",
2390
- "#000080",
2391
- "#FF00FF",
2392
- "#FFFF00",
2393
- "#00FFFF",
2394
- "#800080",
2395
- "#800000",
2396
- "#008080",
2397
- "#0000FF",
2398
- "#00CCFF",
2399
- "#CCFFFF",
2400
- "#CCFFCC",
2401
- "#FFFF99",
2402
- "#99CCFF",
2403
- "#FF99CC",
2404
- "#CC99FF",
2405
- "#FFCC99",
2406
- "#3366FF",
2407
- "#33CCCC",
2408
- "#99CC00",
2409
- "#FFCC00",
2410
- "#FF9900",
2411
- "#FF6600",
2412
- "#666699",
2413
- "#969696",
2414
- "#003366",
2415
- "#339966",
2416
- "#003300",
2417
- "#333300",
2418
- "#993300",
2419
- "#993366",
2420
- "#333399",
2421
- "#333333"
2422
- ];
2423
- var NAMED_CSS = {
2424
- black: "#000000",
2425
- blue: "#0000FF",
2426
- cyan: "#00FFFF",
2427
- green: "#00FF00",
2428
- magenta: "#FF00FF",
2429
- red: "#FF0000",
2430
- white: "#FFFFFF",
2431
- yellow: "#FFFF00"
2432
- };
2433
- function numberFormatColorToCss(color) {
2434
- const named = NAMED_CSS[color];
2435
- if (named) return named;
2436
- return INDEXED_COLORS[Number(color.slice(5)) - 1] ?? "#000000";
2437
- }
2438
-
2439
618
  // src/spreadsheet/formula/functions/helpers.ts
2440
619
  var arg = (name, description, type = "any", extra = {}) => ({ name, description, type, ...extra });
2441
620
  var optional = (name, description, type = "any") => arg(name, description, type, { optional: true });
@@ -3523,15 +1702,15 @@ function tableLookup(ctx, vertical) {
3523
1702
  if (failed(table)) return table;
3524
1703
  const index = ctx.integer(2);
3525
1704
  if (failed(index)) return index;
3526
- const approximate2 = ctx.boolean(3, true);
3527
- if (failed(approximate2)) return approximate2;
1705
+ const approximate = ctx.boolean(3, true);
1706
+ if (failed(approximate)) return approximate;
3528
1707
  const span = vertical ? table.cols : table.rows;
3529
1708
  if (index < 1) return ctx.argError(2, "#VALUE!", "must be 1 or more.");
3530
1709
  if (index > span) {
3531
1710
  return ctx.argError(2, "#REF!", `is larger than the number of ${vertical ? "columns" : "rows"} in the table (${span}).`);
3532
1711
  }
3533
1712
  const keys = vertical ? sliceRange(table, 0, table.rows, 0, 1) : sliceRange(table, 0, 1, 0, table.cols);
3534
- const position = lookupIndex(keys, target, approximate2 ? "sorted-asc" : "wildcard");
1713
+ const position = lookupIndex(keys, target, approximate ? "sorted-asc" : "wildcard");
3535
1714
  if (position === -1) return notFound(ctx, target);
3536
1715
  return vertical ? rangeGet(table, position, index - 1) : rangeGet(table, index - 1, position);
3537
1716
  }
@@ -4380,17 +2559,17 @@ function layoutOf(def) {
4380
2559
  return { fixed: def.args.slice(0, groupStart), group: def.args.slice(groupStart), groupStart };
4381
2560
  }
4382
2561
  function getFormulaArgumentSpecIndex(def, argIndex) {
4383
- const { fixed: fixed2, group, groupStart } = layoutOf(def);
4384
- if (argIndex < fixed2.length) return argIndex;
2562
+ const { fixed, group, groupStart } = layoutOf(def);
2563
+ if (argIndex < fixed.length) return argIndex;
4385
2564
  if (group.length === 0) return -1;
4386
2565
  return groupStart + (argIndex - groupStart) % group.length;
4387
2566
  }
4388
2567
  function checkFormulaArgumentCount(def, count) {
4389
- const { fixed: fixed2, group } = layoutOf(def);
4390
- const requiredFixed = fixed2.filter((arg2) => !arg2.optional).length;
2568
+ const { fixed, group } = layoutOf(def);
2569
+ const requiredFixed = fixed.filter((arg2) => !arg2.optional).length;
4391
2570
  const groupRequired = group.length > 0 && !group[0].optional;
4392
2571
  const min2 = requiredFixed + (groupRequired ? group.length : 0);
4393
- const max2 = group.length > 0 ? Infinity : fixed2.length;
2572
+ const max2 = group.length > 0 ? Infinity : fixed.length;
4394
2573
  const given = `${count} ${count === 1 ? "was" : "were"} given`;
4395
2574
  const plural = (n) => `${n} argument${n === 1 ? "" : "s"}`;
4396
2575
  if (count < min2) {
@@ -4401,8 +2580,8 @@ function checkFormulaArgumentCount(def, count) {
4401
2580
  const expected = min2 === max2 ? plural(max2) : `at most ${plural(max2)}`;
4402
2581
  return max2 === 0 ? `${def.name} takes no arguments, but ${given}.` : `${def.name} takes ${expected}, but ${given}.`;
4403
2582
  }
4404
- if (group.length > 1 && count > fixed2.length) {
4405
- const extra = (count - fixed2.length) % group.length;
2583
+ if (group.length > 1 && count > fixed.length) {
2584
+ const extra = (count - fixed.length) % group.length;
4406
2585
  if (extra !== 0 && !(def.allowTrailingArgument && extra === 1)) {
4407
2586
  const names = group.map((arg2) => arg2.name).join(", ");
4408
2587
  return `${def.name} expects its repeating arguments (${names}) in complete groups.`;
@@ -4413,7 +2592,7 @@ function checkFormulaArgumentCount(def, count) {
4413
2592
  function getFormulaSignatureParts(nameOrDef, activeArgIndex) {
4414
2593
  const def = typeof nameOrDef === "string" ? getFormulaFunction(nameOrDef) : nameOrDef;
4415
2594
  if (!def) return [];
4416
- const { fixed: fixed2, group, groupStart } = layoutOf(def);
2595
+ const { fixed, group, groupStart } = layoutOf(def);
4417
2596
  let activeSpec = -1;
4418
2597
  let activeRepeat = 0;
4419
2598
  if (activeArgIndex !== void 0 && activeArgIndex !== null && activeArgIndex >= 0) {
@@ -4427,7 +2606,7 @@ function getFormulaSignatureParts(nameOrDef, activeArgIndex) {
4427
2606
  if (parts.length > 1) parts.push({ text: ", ", specIndex: null, active: false });
4428
2607
  parts.push({ text, specIndex, active: specIndex === activeSpec && repeat === activeRepeat });
4429
2608
  };
4430
- fixed2.forEach((arg2, i) => pushArg(arg2.optional ? `[${arg2.name}]` : arg2.name, i));
2609
+ fixed.forEach((arg2, i) => pushArg(arg2.optional ? `[${arg2.name}]` : arg2.name, i));
4431
2610
  if (group.length > 0) {
4432
2611
  const groupOptional = !!group[0].optional;
4433
2612
  group.forEach((arg2, i) => {
@@ -5311,35 +3490,8 @@ export {
5311
3490
  FormulaLambda,
5312
3491
  isFormulaLambda,
5313
3492
  MAX_LAMBDA_DEPTH,
5314
- serialFromYmd,
5315
- parseCellInput,
5316
- parseNumberText,
5317
- FORMULA_ERRORS,
5318
- isFormulaError,
5319
- isBlank,
5320
- toBoolean,
5321
- toText,
5322
- numberToText,
5323
- numericValue,
5324
- compareNumbers,
5325
- compareValues,
5326
- sortCompareValues,
5327
- colNameToIndex,
5328
- indexToColName,
5329
- parseIsoDate,
5330
- serialToDate,
5331
3493
  wildcardToRegExp,
5332
3494
  parseCriteria,
5333
- formatGeneralFit,
5334
- builtinNumberFormat,
5335
- builtinNumberFormatId,
5336
- MAX_NUMBER_FORMAT_CODE_CHARS,
5337
- NumberFormat,
5338
- clearNumberFormatCache,
5339
- dateValueToSerial,
5340
- formatNumberFormatValue,
5341
- formatTextFunction,
5342
- numberFormatColorToCss,
5343
3495
  registerFormulaFunction,
5344
3496
  unregisterFormulaFunction,
5345
3497
  getFormulaFunction,
@@ -5353,4 +3505,4 @@ export {
5353
3505
  MAX_FORMULA_ARRAY_SIZE,
5354
3506
  FormulaEvaluator
5355
3507
  };
5356
- //# sourceMappingURL=chunk-ZRNHGAQT.js.map
3508
+ //# sourceMappingURL=chunk-REAGGLXS.js.map