ooxml-core 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{PptxHandler-SJTINPU4.mjs → PptxHandler-ZPJNHEZZ.mjs} +2 -2
- package/dist/automation/index.cjs +3294 -661
- package/dist/automation/index.mjs +3294 -661
- package/dist/chart/bar-cluster-geometry.d.ts +6 -0
- package/dist/chart/bar-cluster-geometry.d.ts.map +1 -1
- package/dist/chart/index.cjs +5 -2
- package/dist/chart/index.mjs +5 -3
- package/dist/chart/render/chart-spacing.d.ts.map +1 -1
- package/dist/{chunk-TEOAOAIF.mjs → chunk-BB55ASTX.mjs} +3 -3
- package/dist/{chunk-CQQAPUAG.mjs → chunk-H4TPDZV4.mjs} +11 -9
- package/dist/{chunk-VYTA2OUN.mjs → chunk-IVDC75E5.mjs} +1 -1
- package/dist/{chunk-FI4RSJ24.mjs → chunk-QPQDLSJQ.mjs} +1 -1
- package/dist/{chunk-XCZ7U3GZ.mjs → chunk-XGLKW3JJ.mjs} +13 -9
- package/dist/docx/index.cjs +4 -2
- package/dist/docx/index.mjs +4 -2
- package/dist/docx/layout/index.cjs +4 -2
- package/dist/docx/layout/index.mjs +4 -2
- package/dist/docx/ui/index.cjs +4 -2
- package/dist/docx/ui/index.mjs +4 -2
- package/dist/index.cjs +5 -2
- package/dist/index.mjs +5 -2
- package/dist/pptx/automation/index.cjs +29 -17
- package/dist/pptx/automation/index.mjs +5 -5
- package/dist/pptx/chunks/index-EZJZ7USt.d.ts.map +1 -1
- package/dist/pptx/cli/index.cjs +29 -17
- package/dist/pptx/cli/index.mjs +4 -4
- package/dist/pptx/converter/index.mjs +2 -2
- package/dist/pptx/index.cjs +29 -17
- package/dist/pptx/index.mjs +5 -5
- package/dist/teams/index.cjs +176 -92
- package/dist/teams/index.mjs +176 -92
- package/dist/visio/clipboard-resources.d.ts +11 -0
- package/dist/visio/clipboard-resources.d.ts.map +1 -0
- package/dist/visio/clipboard-types.d.ts +26 -0
- package/dist/visio/clipboard-types.d.ts.map +1 -0
- package/dist/visio/clipboard-xml.d.ts +8 -0
- package/dist/visio/clipboard-xml.d.ts.map +1 -0
- package/dist/visio/clipboard.d.ts +7 -0
- package/dist/visio/clipboard.d.ts.map +1 -0
- package/dist/visio/create-document.d.ts +8 -0
- package/dist/visio/create-document.d.ts.map +1 -0
- package/dist/visio/edit-commands.d.ts +19 -2
- package/dist/visio/edit-commands.d.ts.map +1 -1
- package/dist/visio/edit-delete.d.ts +9 -0
- package/dist/visio/edit-delete.d.ts.map +1 -0
- package/dist/visio/edit-duplicate-commands.d.ts +14 -0
- package/dist/visio/edit-duplicate-commands.d.ts.map +1 -0
- package/dist/visio/edit-duplicate-scope.d.ts +4 -0
- package/dist/visio/edit-duplicate-scope.d.ts.map +1 -0
- package/dist/visio/edit-duplicate.d.ts +10 -0
- package/dist/visio/edit-duplicate.d.ts.map +1 -0
- package/dist/visio/edit-formatting-cell-admission.d.ts +3 -0
- package/dist/visio/edit-formatting-cell-admission.d.ts.map +1 -0
- package/dist/visio/edit-formatting-commands.d.ts +46 -0
- package/dist/visio/edit-formatting-commands.d.ts.map +1 -0
- package/dist/visio/edit-formatting-font.d.ts +6 -0
- package/dist/visio/edit-formatting-font.d.ts.map +1 -0
- package/dist/visio/edit-formatting-paint-scope.d.ts +6 -0
- package/dist/visio/edit-formatting-paint-scope.d.ts.map +1 -0
- package/dist/visio/edit-formatting-paint.d.ts +6 -0
- package/dist/visio/edit-formatting-paint.d.ts.map +1 -0
- package/dist/visio/edit-formatting-rows.d.ts +14 -0
- package/dist/visio/edit-formatting-rows.d.ts.map +1 -0
- package/dist/visio/edit-formatting-scope.d.ts +6 -0
- package/dist/visio/edit-formatting-scope.d.ts.map +1 -0
- package/dist/visio/edit-formatting-text.d.ts +8 -0
- package/dist/visio/edit-formatting-text.d.ts.map +1 -0
- package/dist/visio/edit-formatting.d.ts +12 -0
- package/dist/visio/edit-formatting.d.ts.map +1 -0
- package/dist/visio/edit-geometry.d.ts.map +1 -1
- package/dist/visio/edit-paste-commands.d.ts +15 -0
- package/dist/visio/edit-paste-commands.d.ts.map +1 -0
- package/dist/visio/edit-paste.d.ts +5 -0
- package/dist/visio/edit-paste.d.ts.map +1 -0
- package/dist/visio/edit-recalculate.d.ts +3 -1
- package/dist/visio/edit-recalculate.d.ts.map +1 -1
- package/dist/visio/edit-resize-anchor.d.ts +8 -0
- package/dist/visio/edit-resize-anchor.d.ts.map +1 -0
- package/dist/visio/edit-scope.d.ts.map +1 -1
- package/dist/visio/edit-shape-create.d.ts +1 -1
- package/dist/visio/edit-shape-create.d.ts.map +1 -1
- package/dist/visio/edit-shape-order.d.ts +7 -0
- package/dist/visio/edit-shape-order.d.ts.map +1 -0
- package/dist/visio/edit-style-admission.d.ts +17 -0
- package/dist/visio/edit-style-admission.d.ts.map +1 -0
- package/dist/visio/edit-text-scope.d.ts +7 -0
- package/dist/visio/edit-text-scope.d.ts.map +1 -0
- package/dist/visio/edit-text.d.ts +1 -1
- package/dist/visio/edit-text.d.ts.map +1 -1
- package/dist/visio/edit.d.ts +1 -1
- package/dist/visio/edit.d.ts.map +1 -1
- package/dist/visio/index.cjs +3245 -1077
- package/dist/visio/index.d.ts +3 -1
- package/dist/visio/index.d.ts.map +1 -1
- package/dist/visio/index.mjs +3241 -1079
- package/dist/visio/line-pattern.d.ts +1 -1
- package/dist/visio/line-pattern.d.ts.map +1 -1
- package/dist/visio/line-style.d.ts.map +1 -1
- package/dist/visio/model.d.ts +23 -3
- package/dist/visio/model.d.ts.map +1 -1
- package/dist/visio/parser.d.ts.map +1 -1
- package/dist/visio/plain-text.d.ts +5 -0
- package/dist/visio/plain-text.d.ts.map +1 -0
- package/dist/visio/resize-anchor.d.ts +27 -0
- package/dist/visio/resize-anchor.d.ts.map +1 -0
- package/dist/visio/source-paint.d.ts +5 -0
- package/dist/visio/source-paint.d.ts.map +1 -0
- package/dist/visio/style.d.ts.map +1 -1
- package/dist/visio/theme-root.d.ts.map +1 -1
- package/dist/visio/ui/contract.d.ts +10 -6
- package/dist/visio/ui/contract.d.ts.map +1 -1
- package/dist/visio/ui/draw-plan.d.ts +32 -0
- package/dist/visio/ui/draw-plan.d.ts.map +1 -0
- package/dist/visio/ui/edit-commands.d.ts.map +1 -1
- package/dist/visio/ui/formatting.d.ts +28 -0
- package/dist/visio/ui/formatting.d.ts.map +1 -0
- package/dist/visio/ui/index.cjs +1305 -15
- package/dist/visio/ui/index.d.ts +15 -0
- package/dist/visio/ui/index.d.ts.map +1 -1
- package/dist/visio/ui/index.mjs +1261 -16
- package/dist/visio/ui/line-dash.d.ts +4 -0
- package/dist/visio/ui/line-dash.d.ts.map +1 -0
- package/dist/visio/ui/marquee.d.ts +15 -0
- package/dist/visio/ui/marquee.d.ts.map +1 -0
- package/dist/visio/ui/page-edit.d.ts.map +1 -1
- package/dist/visio/ui/scene-validation.d.ts.map +1 -1
- package/dist/visio/ui/selection.d.ts +12 -0
- package/dist/visio/ui/selection.d.ts.map +1 -0
- package/dist/visio/ui/shape-arrange.d.ts +17 -0
- package/dist/visio/ui/shape-arrange.d.ts.map +1 -0
- package/dist/visio/ui/shape-clipboard.d.ts +10 -0
- package/dist/visio/ui/shape-clipboard.d.ts.map +1 -0
- package/dist/visio/ui/shape-duplicate.d.ts +5 -0
- package/dist/visio/ui/shape-duplicate.d.ts.map +1 -0
- package/dist/visio/ui/shape-formatting.d.ts +14 -0
- package/dist/visio/ui/shape-formatting.d.ts.map +1 -0
- package/dist/visio/ui/shape-move.d.ts +14 -0
- package/dist/visio/ui/shape-move.d.ts.map +1 -0
- package/dist/visio/ui/shape-order.d.ts +4 -0
- package/dist/visio/ui/shape-order.d.ts.map +1 -0
- package/dist/visio/ui/shape-resize.d.ts +61 -0
- package/dist/visio/ui/shape-resize.d.ts.map +1 -0
- package/dist/visio/ui/size-position.d.ts +19 -0
- package/dist/visio/ui/size-position.d.ts.map +1 -0
- package/dist/visio/ui/snapshot-scene.d.ts.map +1 -1
- package/dist/visio/ui/svg-stroke.d.ts +8 -0
- package/dist/visio/ui/svg-stroke.d.ts.map +1 -0
- package/dist/visio/ui/text-replace-selection.d.ts +9 -0
- package/dist/visio/ui/text-replace-selection.d.ts.map +1 -0
- package/dist/visio/ui/text-replace-snapshot.d.ts +14 -0
- package/dist/visio/ui/text-replace-snapshot.d.ts.map +1 -0
- package/dist/visio/ui/text-replace-types.d.ts +48 -0
- package/dist/visio/ui/text-replace-types.d.ts.map +1 -0
- package/dist/visio/ui/text-replace.d.ts +18 -0
- package/dist/visio/ui/text-replace.d.ts.map +1 -0
- package/dist/xlsx/edit/context.d.ts +3 -1
- package/dist/xlsx/edit/context.d.ts.map +1 -1
- package/dist/xlsx/edit/history.d.ts +18 -0
- package/dist/xlsx/edit/history.d.ts.map +1 -1
- package/dist/xlsx/edit/session-calc.d.ts +30 -8
- package/dist/xlsx/edit/session-calc.d.ts.map +1 -1
- package/dist/xlsx/edit/session.d.ts.map +1 -1
- package/dist/xlsx/edit/sheets.d.ts.map +1 -1
- package/dist/xlsx/edit/types.d.ts +23 -3
- package/dist/xlsx/edit/types.d.ts.map +1 -1
- package/dist/xlsx/formula/engine-core.d.ts.map +1 -1
- package/dist/xlsx/formula/engine-host.d.ts +6 -2
- package/dist/xlsx/formula/engine-host.d.ts.map +1 -1
- package/dist/xlsx/formula/engine-prepare.d.ts +33 -0
- package/dist/xlsx/formula/engine-prepare.d.ts.map +1 -0
- package/dist/xlsx/formula/engine-structure.d.ts +40 -0
- package/dist/xlsx/formula/engine-structure.d.ts.map +1 -0
- package/dist/xlsx/formula/engine-types.d.ts +26 -0
- package/dist/xlsx/formula/engine-types.d.ts.map +1 -1
- package/dist/xlsx/formula/engine.d.ts.map +1 -1
- package/dist/xlsx/formula/formula-shape.d.ts +28 -0
- package/dist/xlsx/formula/formula-shape.d.ts.map +1 -0
- package/dist/xlsx/formula/graph-index.d.ts +3 -1
- package/dist/xlsx/formula/graph-index.d.ts.map +1 -1
- package/dist/xlsx/formula/graph.d.ts +5 -0
- package/dist/xlsx/formula/graph.d.ts.map +1 -1
- package/dist/xlsx/formula/lexemes.d.ts.map +1 -1
- package/dist/xlsx/formula/parse-cache.d.ts +9 -0
- package/dist/xlsx/formula/parse-cache.d.ts.map +1 -0
- package/dist/xlsx/formula/parser.d.ts +3 -0
- package/dist/xlsx/formula/parser.d.ts.map +1 -1
- package/dist/xlsx/formula/ref-text.d.ts +14 -0
- package/dist/xlsx/formula/ref-text.d.ts.map +1 -0
- package/dist/xlsx/formula/references.d.ts.map +1 -1
- package/dist/xlsx/formula/shift-formula.d.ts +19 -0
- package/dist/xlsx/formula/shift-formula.d.ts.map +1 -0
- package/dist/xlsx/formula/shift-graph.d.ts +42 -0
- package/dist/xlsx/formula/shift-graph.d.ts.map +1 -0
- package/dist/xlsx/formula/transform.d.ts +2 -23
- package/dist/xlsx/formula/transform.d.ts.map +1 -1
- package/dist/xlsx/index.cjs +1087 -338
- package/dist/xlsx/index.mjs +1087 -339
- package/dist/xlsx/layout/index.d.ts +1 -1
- package/dist/xlsx/layout/index.d.ts.map +1 -1
- package/dist/xlsx/layout/sheet-queries.d.ts +7 -0
- package/dist/xlsx/layout/sheet-queries.d.ts.map +1 -1
- package/dist/xlsx/load/index.cjs +170 -99
- package/dist/xlsx/load/index.mjs +170 -99
- package/dist/xlsx/ui/index.cjs +1072 -332
- package/dist/xlsx/ui/index.mjs +1072 -332
- package/package.json +1 -1
package/dist/xlsx/index.mjs
CHANGED
|
@@ -2102,7 +2102,7 @@ var NAME_RE = /^[A-Za-z_\\\u00A1-\uFFFF][A-Za-z0-9_.?\\\u00A1-\uFFFF]*/;
|
|
|
2102
2102
|
var CELL_RE = /^(\$?)([A-Za-z]{1,3})(\$?)(\d{1,7})/;
|
|
2103
2103
|
var COLS_RE = /^(\$?)([A-Za-z]{1,3}):(\$?)([A-Za-z]{1,3})/;
|
|
2104
2104
|
var ROWS_RE = /^(\$?)(\d{1,7}):(\$?)(\d{1,7})/;
|
|
2105
|
-
var NUMBER_RE2 = /^(?:\d
|
|
2105
|
+
var NUMBER_RE2 = /^(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?/;
|
|
2106
2106
|
var sticky = (re) => new RegExp(re.source.replace(/^\^/, ""), "y");
|
|
2107
2107
|
var CELL_AT = sticky(CELL_RE);
|
|
2108
2108
|
var COLS_AT = sticky(COLS_RE);
|
|
@@ -2262,14 +2262,13 @@ function splitSheets(text3) {
|
|
|
2262
2262
|
if (book !== void 0) out.book = book;
|
|
2263
2263
|
return out;
|
|
2264
2264
|
}
|
|
2265
|
-
var PREFIX_AT = /(\[\d+\])?([A-Za-z0-9_.\u00A1-\uFFFF]+)(?::([A-Za-z0-9_.\u00A1-\uFFFF]+))?!/y;
|
|
2266
2265
|
function readPrefix(source2, at) {
|
|
2267
2266
|
const ch = source2[at];
|
|
2268
2267
|
if (ch === "'") {
|
|
2269
2268
|
const quoted = readQuoted(source2, at);
|
|
2270
2269
|
if (source2[at + quoted.length] !== "!") return void 0;
|
|
2271
|
-
const
|
|
2272
|
-
return { prefix: { text: source2.slice(at, at +
|
|
2270
|
+
const length2 = quoted.length + 1;
|
|
2271
|
+
return { prefix: { text: source2.slice(at, at + length2), ...splitSheets(quoted.name) }, length: length2 };
|
|
2273
2272
|
}
|
|
2274
2273
|
let i2 = at;
|
|
2275
2274
|
if (ch === "[") {
|
|
@@ -2278,13 +2277,23 @@ function readPrefix(source2, at) {
|
|
|
2278
2277
|
if (i2 === at + 1 || source2[i2] !== "]") return void 0;
|
|
2279
2278
|
i2++;
|
|
2280
2279
|
}
|
|
2280
|
+
const sheetFrom = i2;
|
|
2281
2281
|
while (i2 < source2.length && isSheetCharCode(source2.charCodeAt(i2))) i2++;
|
|
2282
|
-
if (
|
|
2283
|
-
|
|
2284
|
-
if (
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2282
|
+
if (i2 === sheetFrom) return void 0;
|
|
2283
|
+
let lastFrom = -1;
|
|
2284
|
+
if (source2[i2] === ":") {
|
|
2285
|
+
lastFrom = i2 + 1;
|
|
2286
|
+
i2 = lastFrom;
|
|
2287
|
+
while (i2 < source2.length && isSheetCharCode(source2.charCodeAt(i2))) i2++;
|
|
2288
|
+
if (i2 === lastFrom) return void 0;
|
|
2289
|
+
}
|
|
2290
|
+
if (source2[i2] !== "!") return void 0;
|
|
2291
|
+
if (ch !== "[" && lastFrom < 0 && isDigitCode(source2.charCodeAt(sheetFrom))) return void 0;
|
|
2292
|
+
const length = i2 + 1 - at;
|
|
2293
|
+
return {
|
|
2294
|
+
prefix: { text: source2.slice(at, at + length), ...splitSheets(source2.slice(at, i2)) },
|
|
2295
|
+
length
|
|
2296
|
+
};
|
|
2288
2297
|
}
|
|
2289
2298
|
function numberLiteral(text3) {
|
|
2290
2299
|
if (text3.length <= 15) return Number(text3);
|
|
@@ -2474,7 +2483,9 @@ var PREC_INTERSECT = 9;
|
|
|
2474
2483
|
var PREC_RANGE = 10;
|
|
2475
2484
|
var OPERAND_START = /* @__PURE__ */ new Set(["ref", "name", "func", "open", "structured"]);
|
|
2476
2485
|
function parseFormula(formula) {
|
|
2477
|
-
|
|
2486
|
+
return parseTokens(tokenize(formula));
|
|
2487
|
+
}
|
|
2488
|
+
function parseTokens(all2) {
|
|
2478
2489
|
const tokens2 = [];
|
|
2479
2490
|
const wsBefore = [];
|
|
2480
2491
|
let sawWs = false;
|
|
@@ -2759,6 +2770,222 @@ function localDateToSerial(date, date1904 = date1904Mode) {
|
|
|
2759
2770
|
return base + (utc - dayStart) / DAY_MS;
|
|
2760
2771
|
}
|
|
2761
2772
|
|
|
2773
|
+
// xlsx/formula/area-index.ts
|
|
2774
|
+
var BUCKET_WIDTH = 64;
|
|
2775
|
+
var CHUNK_SHIFT = 6;
|
|
2776
|
+
var CHUNKS = 64;
|
|
2777
|
+
function push(map, key, value) {
|
|
2778
|
+
const list = map.get(key);
|
|
2779
|
+
if (list) list.push(value);
|
|
2780
|
+
else map.set(key, [value]);
|
|
2781
|
+
}
|
|
2782
|
+
function inner(map, sheet) {
|
|
2783
|
+
let found = map.get(sheet);
|
|
2784
|
+
if (!found) map.set(sheet, found = /* @__PURE__ */ new Map());
|
|
2785
|
+
return found;
|
|
2786
|
+
}
|
|
2787
|
+
var AreaIndex = class {
|
|
2788
|
+
cells = /* @__PURE__ */ new Map();
|
|
2789
|
+
chunked = /* @__PURE__ */ new Map();
|
|
2790
|
+
tall = /* @__PURE__ */ new Map();
|
|
2791
|
+
wide = /* @__PURE__ */ new Map();
|
|
2792
|
+
add(area, node) {
|
|
2793
|
+
const { start, end } = area.range;
|
|
2794
|
+
if (start.row === end.row && end.col - start.col + 1 <= BUCKET_WIDTH) {
|
|
2795
|
+
const cells = inner(this.cells, area.sheet);
|
|
2796
|
+
for (let col = start.col; col <= end.col; col++) push(cells, cellKey(start.row, col), node);
|
|
2797
|
+
return;
|
|
2798
|
+
}
|
|
2799
|
+
const entry3 = { range: area.range, node };
|
|
2800
|
+
if (end.col - start.col + 1 > BUCKET_WIDTH) {
|
|
2801
|
+
const list = this.wide.get(area.sheet);
|
|
2802
|
+
if (list) list.push(entry3);
|
|
2803
|
+
else this.wide.set(area.sheet, [entry3]);
|
|
2804
|
+
return;
|
|
2805
|
+
}
|
|
2806
|
+
const first2 = start.row >> CHUNK_SHIFT;
|
|
2807
|
+
const last = end.row >> CHUNK_SHIFT;
|
|
2808
|
+
if (last - first2 + 1 > CHUNKS) {
|
|
2809
|
+
const cols2 = inner(this.tall, area.sheet);
|
|
2810
|
+
for (let c2 = start.col; c2 <= end.col; c2++) push(cols2, c2, entry3);
|
|
2811
|
+
return;
|
|
2812
|
+
}
|
|
2813
|
+
const cols = inner(this.chunked, area.sheet);
|
|
2814
|
+
for (let c2 = start.col; c2 <= end.col; c2++) {
|
|
2815
|
+
let chunks = cols.get(c2);
|
|
2816
|
+
if (!chunks) cols.set(c2, chunks = /* @__PURE__ */ new Map());
|
|
2817
|
+
for (let k = first2; k <= last; k++) push(chunks, k, entry3);
|
|
2818
|
+
}
|
|
2819
|
+
}
|
|
2820
|
+
/** Items whose areas intersect `range` on `sheet` (each once). */
|
|
2821
|
+
dependents(sheet, range, out) {
|
|
2822
|
+
const found = out instanceof Set ? out : /* @__PURE__ */ new Set();
|
|
2823
|
+
this.collect(sheet, range, found);
|
|
2824
|
+
if (Array.isArray(out)) for (const node of found) out.push(node);
|
|
2825
|
+
}
|
|
2826
|
+
collect(sheet, range, out) {
|
|
2827
|
+
const { start, end } = range;
|
|
2828
|
+
const check3 = (list) => {
|
|
2829
|
+
if (list) {
|
|
2830
|
+
for (const entry3 of list) if (rangesIntersect(entry3.range, range)) out.add(entry3.node);
|
|
2831
|
+
}
|
|
2832
|
+
};
|
|
2833
|
+
const cells = this.cells.get(sheet);
|
|
2834
|
+
if (cells) {
|
|
2835
|
+
const size = (end.row - start.row + 1) * (end.col - start.col + 1);
|
|
2836
|
+
if (size <= 4096) {
|
|
2837
|
+
for (let r = start.row; r <= end.row; r++) {
|
|
2838
|
+
for (let c2 = start.col; c2 <= end.col; c2++) {
|
|
2839
|
+
const list = cells.get(cellKey(r, c2));
|
|
2840
|
+
if (list) for (const node of list) out.add(node);
|
|
2841
|
+
}
|
|
2842
|
+
}
|
|
2843
|
+
} else {
|
|
2844
|
+
for (const [key, list] of cells) {
|
|
2845
|
+
const { row: row2, col } = keyToAddress(key);
|
|
2846
|
+
if (row2 >= start.row && row2 <= end.row && col >= start.col && col <= end.col)
|
|
2847
|
+
for (const node of list) out.add(node);
|
|
2848
|
+
}
|
|
2849
|
+
}
|
|
2850
|
+
}
|
|
2851
|
+
const columns = (map, visit2) => {
|
|
2852
|
+
if (!map) return;
|
|
2853
|
+
if (end.col - start.col + 1 <= map.size) {
|
|
2854
|
+
for (let c2 = start.col; c2 <= end.col; c2++) if (map.has(c2)) visit2(c2);
|
|
2855
|
+
} else for (const c2 of map.keys()) if (c2 >= start.col && c2 <= end.col) visit2(c2);
|
|
2856
|
+
};
|
|
2857
|
+
const chunked = this.chunked.get(sheet);
|
|
2858
|
+
const first2 = start.row >> CHUNK_SHIFT;
|
|
2859
|
+
const last = end.row >> CHUNK_SHIFT;
|
|
2860
|
+
columns(chunked, (c2) => {
|
|
2861
|
+
const chunks = chunked?.get(c2);
|
|
2862
|
+
if (last - first2 + 1 <= chunks.size) {
|
|
2863
|
+
for (let k = first2; k <= last; k++) check3(chunks.get(k));
|
|
2864
|
+
} else for (const [k, list] of chunks) if (k >= first2 && k <= last) check3(list);
|
|
2865
|
+
});
|
|
2866
|
+
const tall = this.tall.get(sheet);
|
|
2867
|
+
columns(tall, (c2) => check3(tall?.get(c2)));
|
|
2868
|
+
check3(this.wide.get(sheet));
|
|
2869
|
+
}
|
|
2870
|
+
};
|
|
2871
|
+
|
|
2872
|
+
// xlsx/formula/graph-index.ts
|
|
2873
|
+
var ColumnIndex = class {
|
|
2874
|
+
sheets = /* @__PURE__ */ new Map();
|
|
2875
|
+
constructor(nodes) {
|
|
2876
|
+
for (const node of nodes) {
|
|
2877
|
+
let cols = this.sheets.get(node.sheet);
|
|
2878
|
+
if (!cols) this.sheets.set(node.sheet, cols = /* @__PURE__ */ new Map());
|
|
2879
|
+
let list = cols.get(node.col);
|
|
2880
|
+
if (!list) cols.set(node.col, list = []);
|
|
2881
|
+
list.push(node);
|
|
2882
|
+
}
|
|
2883
|
+
for (const cols of this.sheets.values())
|
|
2884
|
+
for (const list of cols.values()) list.sort((a2, b) => a2.row - b.row);
|
|
2885
|
+
}
|
|
2886
|
+
nodesIn(area, out) {
|
|
2887
|
+
const cols = this.sheets.get(area.sheet);
|
|
2888
|
+
if (!cols) return;
|
|
2889
|
+
const { start, end } = area.range;
|
|
2890
|
+
const width = end.col - start.col + 1;
|
|
2891
|
+
const scan4 = (list) => {
|
|
2892
|
+
let lo = 0;
|
|
2893
|
+
let hi = list.length;
|
|
2894
|
+
while (lo < hi) {
|
|
2895
|
+
const mid = lo + hi >> 1;
|
|
2896
|
+
if (list[mid].row < start.row) lo = mid + 1;
|
|
2897
|
+
else hi = mid;
|
|
2898
|
+
}
|
|
2899
|
+
for (let i2 = lo; i2 < list.length; i2++) {
|
|
2900
|
+
const node = list[i2];
|
|
2901
|
+
if (node.row > end.row) break;
|
|
2902
|
+
out.push(node);
|
|
2903
|
+
}
|
|
2904
|
+
};
|
|
2905
|
+
if (width <= cols.size) {
|
|
2906
|
+
for (let c2 = start.col; c2 <= end.col; c2++) {
|
|
2907
|
+
const list = cols.get(c2);
|
|
2908
|
+
if (list) scan4(list);
|
|
2909
|
+
}
|
|
2910
|
+
} else {
|
|
2911
|
+
for (const [c2, list] of cols) if (c2 >= start.col && c2 <= end.col) scan4(list);
|
|
2912
|
+
}
|
|
2913
|
+
}
|
|
2914
|
+
};
|
|
2915
|
+
var ReverseIndex = class extends AreaIndex {
|
|
2916
|
+
constructor(nodes = []) {
|
|
2917
|
+
super();
|
|
2918
|
+
for (const node of nodes) this.addNode(node);
|
|
2919
|
+
}
|
|
2920
|
+
/** Indexes one more formula's precedents. */
|
|
2921
|
+
addNode(node) {
|
|
2922
|
+
for (const dep of node.deps) this.add(dep, node);
|
|
2923
|
+
for (const dep of node.dynamicDeps) this.add(dep, node);
|
|
2924
|
+
}
|
|
2925
|
+
};
|
|
2926
|
+
|
|
2927
|
+
// xlsx/formula/engine-prepare.ts
|
|
2928
|
+
var CHECK_EVERY = 32;
|
|
2929
|
+
var GraphPreparation = class {
|
|
2930
|
+
constructor(workbook, create) {
|
|
2931
|
+
this.workbook = workbook;
|
|
2932
|
+
this.create = create;
|
|
2933
|
+
}
|
|
2934
|
+
workbook;
|
|
2935
|
+
create;
|
|
2936
|
+
reverse = new ReverseIndex();
|
|
2937
|
+
formulas = { dynamic: [], unvalued: [] };
|
|
2938
|
+
sheet = 0;
|
|
2939
|
+
rows;
|
|
2940
|
+
row = 0;
|
|
2941
|
+
cells;
|
|
2942
|
+
finished = false;
|
|
2943
|
+
/**
|
|
2944
|
+
* Adds formulas to the graph until `timeRemaining` (milliseconds, as an idle deadline reports
|
|
2945
|
+
* them) reaches zero, or until every formula is in. Returns true when the graph is complete.
|
|
2946
|
+
*/
|
|
2947
|
+
run(timeRemaining) {
|
|
2948
|
+
let visited = 0;
|
|
2949
|
+
while (!this.finished) {
|
|
2950
|
+
const cells = this.cells ?? this.nextRow();
|
|
2951
|
+
if (!cells) continue;
|
|
2952
|
+
const next = cells.next();
|
|
2953
|
+
if (next.done) {
|
|
2954
|
+
this.cells = void 0;
|
|
2955
|
+
continue;
|
|
2956
|
+
}
|
|
2957
|
+
const [col, cell] = next.value;
|
|
2958
|
+
if (cell.formula) this.add(this.create(this.sheet, this.row, col, cell), cell);
|
|
2959
|
+
if (timeRemaining && ++visited % CHECK_EVERY === 0 && timeRemaining() <= 0) break;
|
|
2960
|
+
}
|
|
2961
|
+
return this.finished;
|
|
2962
|
+
}
|
|
2963
|
+
add(node, cell) {
|
|
2964
|
+
this.reverse.addNode(node);
|
|
2965
|
+
if (!node.legacy && !node.arrayRange) this.formulas.dynamic.push(node);
|
|
2966
|
+
if (cell.value === null && !node.keepCached) this.formulas.unvalued.push(node);
|
|
2967
|
+
}
|
|
2968
|
+
/** Moves to the next stored row (and sheet), or marks the walk finished. */
|
|
2969
|
+
nextRow() {
|
|
2970
|
+
for (; ; ) {
|
|
2971
|
+
const sheet = this.workbook.sheets[this.sheet];
|
|
2972
|
+
if (!sheet) {
|
|
2973
|
+
this.finished = true;
|
|
2974
|
+
return void 0;
|
|
2975
|
+
}
|
|
2976
|
+
this.rows ??= sheet.rows.entries();
|
|
2977
|
+
const next = this.rows.next();
|
|
2978
|
+
if (!next.done) {
|
|
2979
|
+
this.row = next.value[0];
|
|
2980
|
+
this.cells = next.value[1].entries();
|
|
2981
|
+
return this.cells;
|
|
2982
|
+
}
|
|
2983
|
+
this.rows = void 0;
|
|
2984
|
+
this.sheet++;
|
|
2985
|
+
}
|
|
2986
|
+
}
|
|
2987
|
+
};
|
|
2988
|
+
|
|
2762
2989
|
// xlsx/formula/text-number.ts
|
|
2763
2990
|
var MONTHS2 = [
|
|
2764
2991
|
"jan",
|
|
@@ -5893,8 +6120,10 @@ var FINANCIAL_FUNCTIONS = [
|
|
|
5893
6120
|
|
|
5894
6121
|
// xlsx/formula/references.ts
|
|
5895
6122
|
function sheetIndex(host, name) {
|
|
6123
|
+
const sheets = host.workbook.sheets;
|
|
6124
|
+
for (let i2 = 0; i2 < sheets.length; i2++) if (sheets[i2]?.name === name) return i2;
|
|
5896
6125
|
const lower2 = name.toLowerCase();
|
|
5897
|
-
return
|
|
6126
|
+
return sheets.findIndex((sheet) => sheet.name.toLowerCase() === lower2);
|
|
5898
6127
|
}
|
|
5899
6128
|
function prefixSheets(host, prefix, current) {
|
|
5900
6129
|
if (!prefix) return [current];
|
|
@@ -7464,9 +7693,9 @@ function readBlock(ctx, area, rows, cols) {
|
|
|
7464
7693
|
if (host.readBlock) return host.readBlock(area.sheet, range);
|
|
7465
7694
|
return Matrix.build(rows, cols, (r, c2) => ctx.readCell(area.sheet, row2 + r, col + c2));
|
|
7466
7695
|
}
|
|
7467
|
-
function shapedMatrices(ctx, values2,
|
|
7696
|
+
function shapedMatrices(ctx, values2, sameShape2) {
|
|
7468
7697
|
let { rows, cols } = shapeOf(values2[0] ?? null);
|
|
7469
|
-
if (
|
|
7698
|
+
if (sameShape2) {
|
|
7470
7699
|
for (const value of values2) {
|
|
7471
7700
|
const shape2 = shapeOf(value);
|
|
7472
7701
|
if (shape2.rows !== rows || shape2.cols !== cols) fail(ERR.VALUE);
|
|
@@ -7492,12 +7721,12 @@ function shapedMatrices(ctx, values2, sameShape) {
|
|
|
7492
7721
|
});
|
|
7493
7722
|
return { matrices, total: total2, block: rows * cols };
|
|
7494
7723
|
}
|
|
7495
|
-
function matchingCells(ctx, pairs, target,
|
|
7724
|
+
function matchingCells(ctx, pairs, target, sameShape2) {
|
|
7496
7725
|
const ranges = pairs.map((p) => p.range);
|
|
7497
7726
|
const { matrices, total: total2, block } = shapedMatrices(
|
|
7498
7727
|
ctx,
|
|
7499
7728
|
target === void 0 ? ranges : [...ranges, target],
|
|
7500
|
-
|
|
7729
|
+
sameShape2
|
|
7501
7730
|
);
|
|
7502
7731
|
const tests = pairs.map((p) => makeCriteria(scalar(p.criteria)));
|
|
7503
7732
|
const values2 = matrices[matrices.length - 1];
|
|
@@ -7536,7 +7765,7 @@ function indexedCandidates(pairs, matrices) {
|
|
|
7536
7765
|
}
|
|
7537
7766
|
return void 0;
|
|
7538
7767
|
}
|
|
7539
|
-
var matchingValues = (ctx, pairs, target,
|
|
7768
|
+
var matchingValues = (ctx, pairs, target, sameShape2) => matchingCells(ctx, pairs, target, sameShape2).values;
|
|
7540
7769
|
function criteriaPairs(args, from) {
|
|
7541
7770
|
if ((args.length - from) % 2 !== 0) fail(ERR.VALUE);
|
|
7542
7771
|
const pairs = [];
|
|
@@ -11430,7 +11659,7 @@ var REFERENCE_ARGUMENT = /* @__PURE__ */ new Set([
|
|
|
11430
11659
|
"AREAS",
|
|
11431
11660
|
"ISREF"
|
|
11432
11661
|
]);
|
|
11433
|
-
var
|
|
11662
|
+
var push2 = (c2, area) => {
|
|
11434
11663
|
(c2.dynamic > 0 ? c2.dynamicDeps : c2.deps).push(area);
|
|
11435
11664
|
};
|
|
11436
11665
|
function spans(areas) {
|
|
@@ -11456,7 +11685,7 @@ function visit(node, c2) {
|
|
|
11456
11685
|
if (!sheets) return;
|
|
11457
11686
|
const range = specRange(node.ref);
|
|
11458
11687
|
const target = node.spill ? { start: range.start, end: { ...range.start } } : range;
|
|
11459
|
-
for (const sheet of sheets)
|
|
11688
|
+
for (const sheet of sheets) push2(c2, { sheet, range: target });
|
|
11460
11689
|
return;
|
|
11461
11690
|
}
|
|
11462
11691
|
case "name": {
|
|
@@ -11530,7 +11759,7 @@ function visitBinary(node, c2) {
|
|
|
11530
11759
|
const list = c2.dynamic > 0 ? c2.dynamicDeps : c2.deps;
|
|
11531
11760
|
const l = list[list.length - 2];
|
|
11532
11761
|
const r = list[list.length - 1];
|
|
11533
|
-
if (l && r && l.sheet === r.sheet)
|
|
11762
|
+
if (l && r && l.sheet === r.sheet) push2(c2, spans([l, r])[0]);
|
|
11534
11763
|
continue;
|
|
11535
11764
|
}
|
|
11536
11765
|
const mentioned = [...c2.deps.slice(staticStart), ...c2.dynamicDeps.slice(dynamicStart)];
|
|
@@ -11546,7 +11775,7 @@ function addStructured(ref, c2) {
|
|
|
11546
11775
|
sheet: c2.sheet,
|
|
11547
11776
|
row: c2.row,
|
|
11548
11777
|
col: c2.col});
|
|
11549
|
-
if (value instanceof RefValue) for (const area of value.areas)
|
|
11778
|
+
if (value instanceof RefValue) for (const area of value.areas) push2(c2, area);
|
|
11550
11779
|
}
|
|
11551
11780
|
function analyze(ast, host, sheet, row2, col) {
|
|
11552
11781
|
const c2 = {
|
|
@@ -11570,155 +11799,191 @@ function analyze(ast, host, sheet, row2, col) {
|
|
|
11570
11799
|
};
|
|
11571
11800
|
}
|
|
11572
11801
|
|
|
11573
|
-
// xlsx/formula/
|
|
11574
|
-
var
|
|
11575
|
-
|
|
11576
|
-
|
|
11577
|
-
|
|
11578
|
-
|
|
11579
|
-
|
|
11580
|
-
|
|
11802
|
+
// xlsx/formula/formula-shape.ts
|
|
11803
|
+
var isDigit4 = (code) => code >= 48 && code <= 57;
|
|
11804
|
+
function formulaShape(formula) {
|
|
11805
|
+
const starts = [];
|
|
11806
|
+
const ends = [];
|
|
11807
|
+
let hash = 2166136261;
|
|
11808
|
+
for (let i2 = 0; i2 < formula.length; i2++) {
|
|
11809
|
+
let code = formula.charCodeAt(i2);
|
|
11810
|
+
if (isDigit4(code)) {
|
|
11811
|
+
let j = i2 + 1;
|
|
11812
|
+
while (j < formula.length && isDigit4(formula.charCodeAt(j))) j++;
|
|
11813
|
+
starts.push(i2);
|
|
11814
|
+
ends.push(j);
|
|
11815
|
+
i2 = j - 1;
|
|
11816
|
+
code = 0;
|
|
11817
|
+
}
|
|
11818
|
+
hash = Math.imul(hash ^ code, 16777619);
|
|
11819
|
+
}
|
|
11820
|
+
return { hash: hash >>> 0, starts, ends };
|
|
11581
11821
|
}
|
|
11582
|
-
function
|
|
11583
|
-
let
|
|
11584
|
-
|
|
11585
|
-
return
|
|
11822
|
+
function sameText(a2, from, b, at, length) {
|
|
11823
|
+
for (let k = 0; k < length; k++)
|
|
11824
|
+
if (a2.charCodeAt(from + k) !== b.charCodeAt(at + k)) return false;
|
|
11825
|
+
return true;
|
|
11586
11826
|
}
|
|
11587
|
-
|
|
11588
|
-
|
|
11589
|
-
|
|
11590
|
-
|
|
11591
|
-
|
|
11592
|
-
|
|
11593
|
-
const
|
|
11594
|
-
|
|
11595
|
-
|
|
11596
|
-
|
|
11597
|
-
|
|
11827
|
+
function sameShape(a2, as, b, bs) {
|
|
11828
|
+
const runs = as.starts.length;
|
|
11829
|
+
if (runs !== bs.starts.length) return false;
|
|
11830
|
+
let fromA = 0;
|
|
11831
|
+
let fromB = 0;
|
|
11832
|
+
for (let i2 = 0; i2 <= runs; i2++) {
|
|
11833
|
+
const toA = i2 < runs ? as.starts[i2] : a2.length;
|
|
11834
|
+
const toB = i2 < runs ? bs.starts[i2] : b.length;
|
|
11835
|
+
if (toA - fromA !== toB - fromB || !sameText(a2, fromA, b, fromB, toA - fromA)) return false;
|
|
11836
|
+
fromA = as.ends[i2] ?? 0;
|
|
11837
|
+
fromB = bs.ends[i2] ?? 0;
|
|
11838
|
+
}
|
|
11839
|
+
return true;
|
|
11840
|
+
}
|
|
11841
|
+
function makeTemplate(formula, shape2) {
|
|
11842
|
+
let tokens2;
|
|
11843
|
+
let ast;
|
|
11844
|
+
try {
|
|
11845
|
+
tokens2 = tokenize(formula);
|
|
11846
|
+
ast = parseTokens(tokens2);
|
|
11847
|
+
} catch (e) {
|
|
11848
|
+
if (e instanceof RangeError) return new FormulaError(e.message, -1, "#VALUE!");
|
|
11849
|
+
if (e instanceof FormulaError) return e;
|
|
11850
|
+
throw e;
|
|
11851
|
+
}
|
|
11852
|
+
const { starts } = shape2;
|
|
11853
|
+
const slotted = starts.map(() => false);
|
|
11854
|
+
const refs = /* @__PURE__ */ new Map();
|
|
11855
|
+
let run2 = 0;
|
|
11856
|
+
for (const token of tokens2) {
|
|
11857
|
+
const end = token.start + token.text.length;
|
|
11858
|
+
const first2 = run2;
|
|
11859
|
+
while (run2 < starts.length && starts[run2] < end) run2++;
|
|
11860
|
+
const ref = token.kind === "ref" ? token.ref : void 0;
|
|
11861
|
+
if (!ref || ref.kind === "cols") continue;
|
|
11862
|
+
const count2 = ref.kind === "cell" ? 1 : 2;
|
|
11863
|
+
if (run2 - first2 < count2) continue;
|
|
11864
|
+
const at = run2 - count2;
|
|
11865
|
+
const indexes2 = count2 === 1 ? [at] : [at, at + 1];
|
|
11866
|
+
if (indexes2.some((i2) => formula.charCodeAt(starts[i2]) === 48)) continue;
|
|
11867
|
+
for (const i2 of indexes2) slotted[i2] = true;
|
|
11868
|
+
refs.set(ref, count2 === 1 ? { start: at } : { start: at, end: at + 1 });
|
|
11869
|
+
}
|
|
11870
|
+
return { formula, shape: shape2, ast, slotted, refs };
|
|
11871
|
+
}
|
|
11872
|
+
function rowsFor(t, formula, shape2) {
|
|
11873
|
+
if (!sameShape(t.formula, t.shape, formula, shape2)) return void 0;
|
|
11874
|
+
const rows = [];
|
|
11875
|
+
for (let i2 = 0; i2 < shape2.starts.length; i2++) {
|
|
11876
|
+
const start = shape2.starts[i2];
|
|
11877
|
+
const length = shape2.ends[i2] - start;
|
|
11878
|
+
if (!t.slotted[i2]) {
|
|
11879
|
+
const own = t.shape.starts[i2];
|
|
11880
|
+
if (t.shape.ends[i2] - own !== length) return void 0;
|
|
11881
|
+
if (!sameText(t.formula, own, formula, start, length)) return void 0;
|
|
11882
|
+
rows.push(-1);
|
|
11883
|
+
continue;
|
|
11598
11884
|
}
|
|
11599
|
-
|
|
11600
|
-
|
|
11601
|
-
|
|
11602
|
-
|
|
11603
|
-
|
|
11604
|
-
|
|
11885
|
+
if (length > 7 || formula.charCodeAt(start) === 48) return void 0;
|
|
11886
|
+
let row2 = 0;
|
|
11887
|
+
for (let k = start; k < start + length; k++) row2 = row2 * 10 + formula.charCodeAt(k) - 48;
|
|
11888
|
+
if (row2 < 1 || row2 > MAX_ROW + 1) return void 0;
|
|
11889
|
+
rows.push(row2 - 1);
|
|
11890
|
+
}
|
|
11891
|
+
return rows;
|
|
11892
|
+
}
|
|
11893
|
+
function shiftSpec(spec2, slots, rows) {
|
|
11894
|
+
const startRow = rows[slots.start];
|
|
11895
|
+
const endRow = slots.end === void 0 ? startRow : rows[slots.end];
|
|
11896
|
+
if (startRow === spec2.start.row && endRow === spec2.end.row) return spec2;
|
|
11897
|
+
const { start: from, end: to } = spec2;
|
|
11898
|
+
const start = { row: startRow, col: from.col, rowAbs: from.rowAbs, colAbs: from.colAbs };
|
|
11899
|
+
if (slots.end === void 0) return { kind: spec2.kind, start, end: start };
|
|
11900
|
+
const end = { row: endRow, col: to.col, rowAbs: to.rowAbs, colAbs: to.colAbs };
|
|
11901
|
+
return { kind: spec2.kind, start, end };
|
|
11902
|
+
}
|
|
11903
|
+
function copyTree(node, t, rows) {
|
|
11904
|
+
switch (node.type) {
|
|
11905
|
+
case "ref": {
|
|
11906
|
+
const slots = node.ref ? t.refs.get(node.ref) : void 0;
|
|
11907
|
+
if (!slots || !node.ref) return node;
|
|
11908
|
+
const ref = shiftSpec(node.ref, slots, rows);
|
|
11909
|
+
if (ref === node.ref) return node;
|
|
11910
|
+
const copy = { type: "ref" };
|
|
11911
|
+
if (node.prefix) copy.prefix = node.prefix;
|
|
11912
|
+
copy.ref = ref;
|
|
11913
|
+
if (node.spill) copy.spill = true;
|
|
11914
|
+
return copy;
|
|
11605
11915
|
}
|
|
11606
|
-
|
|
11607
|
-
|
|
11608
|
-
|
|
11609
|
-
|
|
11610
|
-
|
|
11611
|
-
return;
|
|
11916
|
+
case "unary":
|
|
11917
|
+
case "percent": {
|
|
11918
|
+
const operand4 = copyTree(node.operand, t, rows);
|
|
11919
|
+
if (operand4 === node.operand) return node;
|
|
11920
|
+
return node.type === "unary" ? { type: "unary", op: node.op, operand: operand4 } : { type: "percent", operand: operand4 };
|
|
11612
11921
|
}
|
|
11613
|
-
|
|
11614
|
-
|
|
11615
|
-
|
|
11616
|
-
if (
|
|
11617
|
-
|
|
11922
|
+
case "binary": {
|
|
11923
|
+
const left2 = copyTree(node.left, t, rows);
|
|
11924
|
+
const right2 = copyTree(node.right, t, rows);
|
|
11925
|
+
if (left2 === node.left && right2 === node.right) return node;
|
|
11926
|
+
return { type: "binary", op: node.op, left: left2, right: right2 };
|
|
11618
11927
|
}
|
|
11619
|
-
|
|
11620
|
-
|
|
11621
|
-
|
|
11622
|
-
|
|
11623
|
-
this.collect(sheet, range, found);
|
|
11624
|
-
if (Array.isArray(out)) for (const node of found) out.push(node);
|
|
11625
|
-
}
|
|
11626
|
-
collect(sheet, range, out) {
|
|
11627
|
-
const { start, end } = range;
|
|
11628
|
-
const check3 = (list) => {
|
|
11629
|
-
if (list) {
|
|
11630
|
-
for (const entry3 of list) if (rangesIntersect(entry3.range, range)) out.add(entry3.node);
|
|
11631
|
-
}
|
|
11632
|
-
};
|
|
11633
|
-
const cells = this.cells.get(sheet);
|
|
11634
|
-
if (cells) {
|
|
11635
|
-
const size = (end.row - start.row + 1) * (end.col - start.col + 1);
|
|
11636
|
-
if (size <= 4096) {
|
|
11637
|
-
for (let r = start.row; r <= end.row; r++) {
|
|
11638
|
-
for (let c2 = start.col; c2 <= end.col; c2++) {
|
|
11639
|
-
const list = cells.get(cellKey(r, c2));
|
|
11640
|
-
if (list) for (const node of list) out.add(node);
|
|
11641
|
-
}
|
|
11642
|
-
}
|
|
11643
|
-
} else {
|
|
11644
|
-
for (const [key, list] of cells) {
|
|
11645
|
-
const { row: row2, col } = keyToAddress(key);
|
|
11646
|
-
if (row2 >= start.row && row2 <= end.row && col >= start.col && col <= end.col)
|
|
11647
|
-
for (const node of list) out.add(node);
|
|
11648
|
-
}
|
|
11649
|
-
}
|
|
11928
|
+
case "call": {
|
|
11929
|
+
const args = copyAll(node.args, t, rows);
|
|
11930
|
+
if (args === node.args) return node;
|
|
11931
|
+
return { type: "call", name: node.name, rawName: node.rawName, args };
|
|
11650
11932
|
}
|
|
11651
|
-
|
|
11652
|
-
|
|
11653
|
-
|
|
11654
|
-
|
|
11655
|
-
|
|
11656
|
-
};
|
|
11657
|
-
const chunked = this.chunked.get(sheet);
|
|
11658
|
-
const first2 = start.row >> CHUNK_SHIFT;
|
|
11659
|
-
const last = end.row >> CHUNK_SHIFT;
|
|
11660
|
-
columns(chunked, (c2) => {
|
|
11661
|
-
const chunks = chunked?.get(c2);
|
|
11662
|
-
if (last - first2 + 1 <= chunks.size) {
|
|
11663
|
-
for (let k = first2; k <= last; k++) check3(chunks.get(k));
|
|
11664
|
-
} else for (const [k, list] of chunks) if (k >= first2 && k <= last) check3(list);
|
|
11665
|
-
});
|
|
11666
|
-
const tall = this.tall.get(sheet);
|
|
11667
|
-
columns(tall, (c2) => check3(tall?.get(c2)));
|
|
11668
|
-
check3(this.wide.get(sheet));
|
|
11669
|
-
}
|
|
11670
|
-
};
|
|
11671
|
-
|
|
11672
|
-
// xlsx/formula/graph-index.ts
|
|
11673
|
-
var ColumnIndex = class {
|
|
11674
|
-
sheets = /* @__PURE__ */ new Map();
|
|
11675
|
-
constructor(nodes) {
|
|
11676
|
-
for (const node of nodes) {
|
|
11677
|
-
let cols = this.sheets.get(node.sheet);
|
|
11678
|
-
if (!cols) this.sheets.set(node.sheet, cols = /* @__PURE__ */ new Map());
|
|
11679
|
-
let list = cols.get(node.col);
|
|
11680
|
-
if (!list) cols.set(node.col, list = []);
|
|
11681
|
-
list.push(node);
|
|
11933
|
+
case "invoke": {
|
|
11934
|
+
const callee = copyTree(node.callee, t, rows);
|
|
11935
|
+
const args = copyAll(node.args, t, rows);
|
|
11936
|
+
if (callee === node.callee && args === node.args) return node;
|
|
11937
|
+
return { type: "invoke", callee, args };
|
|
11682
11938
|
}
|
|
11683
|
-
|
|
11684
|
-
|
|
11939
|
+
default:
|
|
11940
|
+
return node;
|
|
11685
11941
|
}
|
|
11686
|
-
|
|
11687
|
-
|
|
11688
|
-
|
|
11689
|
-
|
|
11690
|
-
const
|
|
11691
|
-
const
|
|
11692
|
-
|
|
11693
|
-
|
|
11694
|
-
|
|
11695
|
-
|
|
11696
|
-
|
|
11697
|
-
|
|
11698
|
-
|
|
11699
|
-
|
|
11700
|
-
|
|
11701
|
-
|
|
11702
|
-
|
|
11703
|
-
|
|
11704
|
-
|
|
11705
|
-
|
|
11706
|
-
|
|
11707
|
-
|
|
11708
|
-
|
|
11709
|
-
|
|
11710
|
-
|
|
11711
|
-
|
|
11712
|
-
|
|
11942
|
+
}
|
|
11943
|
+
function copyAll(nodes, t, rows) {
|
|
11944
|
+
let out;
|
|
11945
|
+
for (let i2 = 0; i2 < nodes.length; i2++) {
|
|
11946
|
+
const node = nodes[i2];
|
|
11947
|
+
const copy = copyTree(node, t, rows);
|
|
11948
|
+
if (copy !== node && !out) out = nodes.slice(0, i2);
|
|
11949
|
+
out?.push(copy);
|
|
11950
|
+
}
|
|
11951
|
+
return out ?? nodes;
|
|
11952
|
+
}
|
|
11953
|
+
function fromTemplate(t, formula, shape2) {
|
|
11954
|
+
const rows = rowsFor(t, formula, shape2);
|
|
11955
|
+
return rows ? copyTree(t.ast, t, rows) : void 0;
|
|
11956
|
+
}
|
|
11957
|
+
|
|
11958
|
+
// xlsx/formula/parse-cache.ts
|
|
11959
|
+
var MAX_TEMPLATE_LENGTH = 2048;
|
|
11960
|
+
var MAX_ENTRIES = 1e5;
|
|
11961
|
+
var MAX_TEMPLATES = 1e4;
|
|
11962
|
+
var NO_RUNS = { hash: 0, starts: [], ends: [] };
|
|
11963
|
+
var treeOf = (made) => "ast" in made ? made.ast : made;
|
|
11964
|
+
var ParseCache = class {
|
|
11965
|
+
byText = /* @__PURE__ */ new Map();
|
|
11966
|
+
templates = /* @__PURE__ */ new Map();
|
|
11967
|
+
parse(formula) {
|
|
11968
|
+
let ast = this.byText.get(formula);
|
|
11969
|
+
if (ast) return ast;
|
|
11970
|
+
ast = this.parseNew(formula);
|
|
11971
|
+
if (this.byText.size > MAX_ENTRIES) this.byText.clear();
|
|
11972
|
+
this.byText.set(formula, ast);
|
|
11973
|
+
return ast;
|
|
11713
11974
|
}
|
|
11714
|
-
|
|
11715
|
-
|
|
11716
|
-
|
|
11717
|
-
|
|
11718
|
-
|
|
11719
|
-
|
|
11720
|
-
|
|
11975
|
+
parseNew(formula) {
|
|
11976
|
+
if (formula.length > MAX_TEMPLATE_LENGTH) return treeOf(makeTemplate(formula, NO_RUNS));
|
|
11977
|
+
const shape2 = formulaShape(formula);
|
|
11978
|
+
const template = this.templates.get(shape2.hash);
|
|
11979
|
+
const reused = template && fromTemplate(template, formula, shape2);
|
|
11980
|
+
if (reused) return reused;
|
|
11981
|
+
const made = makeTemplate(formula, shape2);
|
|
11982
|
+
if (!template && "ast" in made) {
|
|
11983
|
+
if (this.templates.size > MAX_TEMPLATES) this.templates.clear();
|
|
11984
|
+
this.templates.set(shape2.hash, made);
|
|
11721
11985
|
}
|
|
11986
|
+
return treeOf(made);
|
|
11722
11987
|
}
|
|
11723
11988
|
};
|
|
11724
11989
|
|
|
@@ -11859,7 +12124,7 @@ var EngineHost = class {
|
|
|
11859
12124
|
options;
|
|
11860
12125
|
nodes = /* @__PURE__ */ new Map();
|
|
11861
12126
|
footprints = /* @__PURE__ */ new Set();
|
|
11862
|
-
|
|
12127
|
+
parsed = new ParseCache();
|
|
11863
12128
|
boundsCache = /* @__PURE__ */ new Map();
|
|
11864
12129
|
inProgress = /* @__PURE__ */ new Set();
|
|
11865
12130
|
cycles = /* @__PURE__ */ new Set();
|
|
@@ -11883,6 +12148,8 @@ var EngineHost = class {
|
|
|
11883
12148
|
evaluations = 0;
|
|
11884
12149
|
built = false;
|
|
11885
12150
|
needsFull = false;
|
|
12151
|
+
/** No recalculation has run since the workbook was opened: stored values may stand. */
|
|
12152
|
+
fresh = true;
|
|
11886
12153
|
// ---- EvalHost ----
|
|
11887
12154
|
readCell(sheet, row2, col) {
|
|
11888
12155
|
const cell = this.workbook.sheets[sheet]?.rows.get(row2)?.get(col);
|
|
@@ -11971,41 +12238,15 @@ var EngineHost = class {
|
|
|
11971
12238
|
return this.workbook.sheets[sheet]?.rows.get(row2)?.get(col)?.formula;
|
|
11972
12239
|
}
|
|
11973
12240
|
parse(formula) {
|
|
11974
|
-
|
|
11975
|
-
if (!ast) {
|
|
11976
|
-
try {
|
|
11977
|
-
ast = parseFormula(formula);
|
|
11978
|
-
} catch (e) {
|
|
11979
|
-
if (e instanceof RangeError) ast = new FormulaError(e.message, -1, "#VALUE!");
|
|
11980
|
-
else if (!(e instanceof FormulaError)) throw e;
|
|
11981
|
-
else ast = e;
|
|
11982
|
-
}
|
|
11983
|
-
if (this.astCache.size > 1e5) this.astCache.clear();
|
|
11984
|
-
this.astCache.set(formula, ast);
|
|
11985
|
-
}
|
|
11986
|
-
return ast;
|
|
12241
|
+
return this.parsed.parse(formula);
|
|
11987
12242
|
}
|
|
11988
12243
|
now() {
|
|
11989
12244
|
return this.options.now ? this.options.now() : /* @__PURE__ */ new Date();
|
|
11990
12245
|
}
|
|
11991
|
-
random() {
|
|
11992
|
-
return this.options.random ? this.options.random() : Math.random();
|
|
11993
|
-
}
|
|
11994
|
-
// ---- graph ----
|
|
11995
|
-
build() {
|
|
11996
|
-
this.nodes.clear();
|
|
11997
|
-
this.footprints.clear();
|
|
11998
|
-
this.footprintIndex = void 0;
|
|
11999
|
-
this.workbook.sheets.forEach((sheet, s) => {
|
|
12000
|
-
for (const [row2, cells] of sheet.rows) {
|
|
12001
|
-
for (const [col, cell] of cells) {
|
|
12002
|
-
if (cell.formula) this.createNode(s, row2, col, cell, true);
|
|
12003
|
-
}
|
|
12004
|
-
}
|
|
12005
|
-
});
|
|
12006
|
-
this.built = true;
|
|
12007
|
-
this.graphChanged();
|
|
12008
|
-
}
|
|
12246
|
+
random() {
|
|
12247
|
+
return this.options.random ? this.options.random() : Math.random();
|
|
12248
|
+
}
|
|
12249
|
+
// ---- graph ----
|
|
12009
12250
|
createNode(sheet, row2, col, cell, initial) {
|
|
12010
12251
|
const formula = cell.formula ?? "";
|
|
12011
12252
|
const parsed = this.parse(formula);
|
|
@@ -12034,6 +12275,14 @@ var EngineHost = class {
|
|
|
12034
12275
|
map.set(cellKey(row2, col), node);
|
|
12035
12276
|
return node;
|
|
12036
12277
|
}
|
|
12278
|
+
/** Parses a node's text again after a structural edit rewrote it (see `FormulaNode.stale`). */
|
|
12279
|
+
refreshAst(node) {
|
|
12280
|
+
const parsed = this.parse(node.formula);
|
|
12281
|
+
delete node.stale;
|
|
12282
|
+
delete node.parseError;
|
|
12283
|
+
node.ast = parsed instanceof FormulaError ? void 0 : parsed;
|
|
12284
|
+
if (parsed instanceof FormulaError && parsed.code) node.parseError = err(parsed.code);
|
|
12285
|
+
}
|
|
12037
12286
|
removeNode(node, changed) {
|
|
12038
12287
|
const sheet = this.workbook.sheets[node.sheet];
|
|
12039
12288
|
if (node.spill && sheet) {
|
|
@@ -12464,6 +12713,7 @@ var EngineCore = class extends EngineHost {
|
|
|
12464
12713
|
return { host: this, sheet, row: row2, col, scope: void 0, depth: 0, root, legacy };
|
|
12465
12714
|
}
|
|
12466
12715
|
evaluateFormula(node) {
|
|
12716
|
+
if (node.stale) this.refreshAst(node);
|
|
12467
12717
|
if (!node.ast) return node.parseError ?? ERR.NAME;
|
|
12468
12718
|
const ast = node.ast;
|
|
12469
12719
|
const frame = this.frameFor(node.sheet, node.row, node.col, ast, node.legacy);
|
|
@@ -12481,20 +12731,363 @@ var EngineCore = class extends EngineHost {
|
|
|
12481
12731
|
}
|
|
12482
12732
|
};
|
|
12483
12733
|
|
|
12734
|
+
// xlsx/formula/shift-graph.ts
|
|
12735
|
+
var POSITIONAL = /* @__PURE__ */ new Set(["ROW", "COLUMN"]);
|
|
12736
|
+
var DESCRIPTIVE = /* @__PURE__ */ new Set(["FORMULATEXT", "CELL", "SHEET"]);
|
|
12737
|
+
var traitsCache = /* @__PURE__ */ new WeakMap();
|
|
12738
|
+
function astTraits(ast) {
|
|
12739
|
+
const cached = traitsCache.get(ast);
|
|
12740
|
+
if (cached) return cached;
|
|
12741
|
+
const sheets = /* @__PURE__ */ new Set();
|
|
12742
|
+
const traits = { complex: false, opaque: false, positional: false, descriptive: false, sheets };
|
|
12743
|
+
const stack2 = [ast];
|
|
12744
|
+
while (stack2.length) {
|
|
12745
|
+
const node = stack2.pop();
|
|
12746
|
+
switch (node.type) {
|
|
12747
|
+
case "ref":
|
|
12748
|
+
if (node.prefix) {
|
|
12749
|
+
sheets.add(node.prefix.sheet.toLowerCase());
|
|
12750
|
+
if (node.prefix.sheet2 !== void 0) {
|
|
12751
|
+
sheets.add(node.prefix.sheet2.toLowerCase());
|
|
12752
|
+
traits.complex = true;
|
|
12753
|
+
}
|
|
12754
|
+
}
|
|
12755
|
+
break;
|
|
12756
|
+
case "name":
|
|
12757
|
+
if (node.prefix) sheets.add(node.prefix.sheet.toLowerCase());
|
|
12758
|
+
traits.complex = true;
|
|
12759
|
+
break;
|
|
12760
|
+
case "structured":
|
|
12761
|
+
traits.complex = true;
|
|
12762
|
+
break;
|
|
12763
|
+
case "unary":
|
|
12764
|
+
case "percent":
|
|
12765
|
+
stack2.push(node.operand);
|
|
12766
|
+
break;
|
|
12767
|
+
case "binary":
|
|
12768
|
+
stack2.push(node.left, node.right);
|
|
12769
|
+
break;
|
|
12770
|
+
case "call":
|
|
12771
|
+
if (POSITIONAL.has(node.name)) traits.positional = true;
|
|
12772
|
+
if (DESCRIPTIVE.has(node.name)) traits.descriptive = true;
|
|
12773
|
+
if (!getFunction(node.name)) traits.complex = traits.opaque = true;
|
|
12774
|
+
stack2.push(...node.args);
|
|
12775
|
+
break;
|
|
12776
|
+
case "invoke":
|
|
12777
|
+
stack2.push(node.callee, ...node.args);
|
|
12778
|
+
break;
|
|
12779
|
+
}
|
|
12780
|
+
}
|
|
12781
|
+
traitsCache.set(ast, traits);
|
|
12782
|
+
return traits;
|
|
12783
|
+
}
|
|
12784
|
+
function intervalDelta(a2, b, shift2) {
|
|
12785
|
+
const { at, count: count2 } = shift2;
|
|
12786
|
+
if (count2 > 0) {
|
|
12787
|
+
if (b < at) return 0;
|
|
12788
|
+
if (a2 < at) return void 0;
|
|
12789
|
+
return b + count2 > (shift2.axis === "row" ? MAX_ROW : MAX_COL) ? void 0 : count2;
|
|
12790
|
+
}
|
|
12791
|
+
const last = at - count2 - 1;
|
|
12792
|
+
if (b < at) return 0;
|
|
12793
|
+
if (a2 > last) return count2;
|
|
12794
|
+
return void 0;
|
|
12795
|
+
}
|
|
12796
|
+
function areaDelta(area, sheet, shift2) {
|
|
12797
|
+
if (area.sheet !== sheet) return 0;
|
|
12798
|
+
const { start, end } = area.range;
|
|
12799
|
+
return shift2.axis === "row" ? intervalDelta(start.row, end.row, shift2) : intervalDelta(start.col, end.col, shift2);
|
|
12800
|
+
}
|
|
12801
|
+
function movedRange(range, axis, delta) {
|
|
12802
|
+
if (delta === 0) return range;
|
|
12803
|
+
return axis === "row" ? {
|
|
12804
|
+
start: { row: range.start.row + delta, col: range.start.col },
|
|
12805
|
+
end: { row: range.end.row + delta, col: range.end.col }
|
|
12806
|
+
} : {
|
|
12807
|
+
start: { row: range.start.row, col: range.start.col + delta },
|
|
12808
|
+
end: { row: range.end.row, col: range.end.col + delta }
|
|
12809
|
+
};
|
|
12810
|
+
}
|
|
12811
|
+
function reachesEdit(areas, sheet, shift2) {
|
|
12812
|
+
for (const area of areas) {
|
|
12813
|
+
if (area.sheet !== sheet) continue;
|
|
12814
|
+
if ((shift2.axis === "row" ? area.range.end.row : area.range.end.col) >= shift2.at) return true;
|
|
12815
|
+
}
|
|
12816
|
+
return false;
|
|
12817
|
+
}
|
|
12818
|
+
function intersectionMoves(area, delta, pos, nodeDelta, axis) {
|
|
12819
|
+
if (delta === nodeDelta) return false;
|
|
12820
|
+
const { start, end } = area.range;
|
|
12821
|
+
const a2 = axis === "row" ? start.row : start.col;
|
|
12822
|
+
const b = axis === "row" ? end.row : end.col;
|
|
12823
|
+
if (a2 === b) return false;
|
|
12824
|
+
return pos >= a2 && pos <= b || pos + nodeDelta >= a2 + delta && pos + nodeDelta <= b + delta;
|
|
12825
|
+
}
|
|
12826
|
+
|
|
12827
|
+
// xlsx/formula/engine-structure.ts
|
|
12828
|
+
var sameAreas = (a2, b) => a2.length === b.length && a2.every((x, i2) => {
|
|
12829
|
+
const y = b[i2];
|
|
12830
|
+
return x.sheet === y.sheet && sameRange(x.range, y.range);
|
|
12831
|
+
});
|
|
12832
|
+
var EngineStructure = class extends EngineCore {
|
|
12833
|
+
/** Formulas a structural edit left to recalculate (with their dependents) on the next pass. */
|
|
12834
|
+
structuralSeeds = /* @__PURE__ */ new Set();
|
|
12835
|
+
/** Whether the graph describes the workbook as it was before the edit just reported. */
|
|
12836
|
+
graphReady() {
|
|
12837
|
+
return this.built && !this.needsFull;
|
|
12838
|
+
}
|
|
12839
|
+
/** Parses a node's current text again and recomputes its precedents. */
|
|
12840
|
+
reanalyze(node) {
|
|
12841
|
+
const parsed = this.parse(node.formula);
|
|
12842
|
+
delete node.stale;
|
|
12843
|
+
delete node.parseError;
|
|
12844
|
+
if (parsed instanceof FormulaError) {
|
|
12845
|
+
node.ast = void 0;
|
|
12846
|
+
if (parsed.code) node.parseError = err(parsed.code);
|
|
12847
|
+
node.deps = [];
|
|
12848
|
+
node.dynamicDeps = [];
|
|
12849
|
+
return;
|
|
12850
|
+
}
|
|
12851
|
+
node.ast = parsed;
|
|
12852
|
+
const found = analyze(parsed, this, node.sheet, node.row, node.col);
|
|
12853
|
+
node.deps = found.deps;
|
|
12854
|
+
node.dynamicDeps = found.dynamicDeps;
|
|
12855
|
+
node.volatile = found.volatile;
|
|
12856
|
+
node.unsupported = found.unsupported;
|
|
12857
|
+
}
|
|
12858
|
+
/**
|
|
12859
|
+
* Moves the graph for rows or columns inserted or deleted on `sheet`, after the workbook was
|
|
12860
|
+
* changed (cells moved, formulas rewritten). Spills on the sheet, array formulas the edit cuts
|
|
12861
|
+
* and anything unexpected fall back to a rebuild on the next recalculation.
|
|
12862
|
+
*/
|
|
12863
|
+
shiftCells(sheet, shift2) {
|
|
12864
|
+
if (!this.graphReady() || !this.shiftable(sheet, shift2)) {
|
|
12865
|
+
this.invalidate();
|
|
12866
|
+
return;
|
|
12867
|
+
}
|
|
12868
|
+
const ws = this.workbook.sheets[sheet];
|
|
12869
|
+
const own = this.nodes.get(sheet);
|
|
12870
|
+
if (!ws) return;
|
|
12871
|
+
const moved = /* @__PURE__ */ new Map();
|
|
12872
|
+
if (own) {
|
|
12873
|
+
const next = /* @__PURE__ */ new Map();
|
|
12874
|
+
for (const node of own.values()) {
|
|
12875
|
+
const pos = shift2.axis === "row" ? node.row : node.col;
|
|
12876
|
+
const delta = intervalDelta(pos, pos, shift2);
|
|
12877
|
+
if (delta === void 0) {
|
|
12878
|
+
this.dropNode(node);
|
|
12879
|
+
continue;
|
|
12880
|
+
}
|
|
12881
|
+
if (delta !== 0) {
|
|
12882
|
+
moved.set(node, delta);
|
|
12883
|
+
if (shift2.axis === "row") node.row += delta;
|
|
12884
|
+
else node.col += delta;
|
|
12885
|
+
}
|
|
12886
|
+
next.set(cellKey(node.row, node.col), node);
|
|
12887
|
+
}
|
|
12888
|
+
this.nodes.set(sheet, next);
|
|
12889
|
+
}
|
|
12890
|
+
for (const map of this.nodes.values())
|
|
12891
|
+
for (const node of map.values()) {
|
|
12892
|
+
if (!this.shiftNode(node, sheet, shift2, moved.get(node) ?? 0)) {
|
|
12893
|
+
this.invalidate();
|
|
12894
|
+
return;
|
|
12895
|
+
}
|
|
12896
|
+
}
|
|
12897
|
+
this.boundsCache.clear();
|
|
12898
|
+
this.graphChanged();
|
|
12899
|
+
}
|
|
12900
|
+
/** No spill or stale spilled value on the sheet, and no array formula the edit cuts. */
|
|
12901
|
+
shiftable(sheet, shift2) {
|
|
12902
|
+
for (const node of this.footprints) {
|
|
12903
|
+
if (node.sheet !== sheet) continue;
|
|
12904
|
+
if (node.spill || node.blockedSpill) return false;
|
|
12905
|
+
if (node.arrayRange && areaDelta({ sheet, range: node.arrayRange }, sheet, shift2) === void 0)
|
|
12906
|
+
return false;
|
|
12907
|
+
}
|
|
12908
|
+
const ws = this.workbook.sheets[sheet];
|
|
12909
|
+
let spilled = false;
|
|
12910
|
+
ws?.rows.forEach((cells) => {
|
|
12911
|
+
if (!spilled) cells.forEach((cell) => spilled ||= isSpilledCell(cell));
|
|
12912
|
+
});
|
|
12913
|
+
return !spilled;
|
|
12914
|
+
}
|
|
12915
|
+
dropNode(node) {
|
|
12916
|
+
this.structuralSeeds.delete(node);
|
|
12917
|
+
this.cycles.delete(node);
|
|
12918
|
+
this.footprints.delete(node);
|
|
12919
|
+
}
|
|
12920
|
+
/** Updates one formula for the edit; false when the graph cannot follow it. */
|
|
12921
|
+
shiftNode(node, sheet, shift2, nodeDelta) {
|
|
12922
|
+
const cell = this.workbook.sheets[node.sheet]?.rows.get(node.row)?.get(node.col);
|
|
12923
|
+
if (cell?.formula === void 0) return false;
|
|
12924
|
+
if (node.arrayRange) {
|
|
12925
|
+
const delta = areaDelta({ sheet: node.sheet, range: node.arrayRange }, sheet, shift2);
|
|
12926
|
+
if (delta === void 0) return false;
|
|
12927
|
+
node.arrayRange = movedRange(node.arrayRange, shift2.axis, delta);
|
|
12928
|
+
if (!cell.arrayRange || !sameRange(node.arrayRange, normalizeRange(cell.arrayRange)))
|
|
12929
|
+
return false;
|
|
12930
|
+
}
|
|
12931
|
+
const changed = cell.formula !== node.formula;
|
|
12932
|
+
const traits = node.ast && astTraits(node.ast);
|
|
12933
|
+
const reached = reachesEdit(node.deps, sheet, shift2) || reachesEdit(node.dynamicDeps, sheet, shift2);
|
|
12934
|
+
if (!changed && !reached && nodeDelta === 0 && !traits?.descriptive && !traits?.opaque)
|
|
12935
|
+
return true;
|
|
12936
|
+
if (traits?.complex) {
|
|
12937
|
+
node.formula = cell.formula;
|
|
12938
|
+
this.reanalyze(node);
|
|
12939
|
+
this.structuralSeeds.add(node);
|
|
12940
|
+
return true;
|
|
12941
|
+
}
|
|
12942
|
+
const pos = shift2.axis === "row" ? node.row - nodeDelta : node.col - nodeDelta;
|
|
12943
|
+
const moves = { seed: !!traits?.descriptive, moved: false, cut: false };
|
|
12944
|
+
const deps = this.moveAreas(node.deps, sheet, shift2, pos, nodeDelta, moves);
|
|
12945
|
+
const dynamicDeps = this.moveAreas(node.dynamicDeps, sheet, shift2, pos, nodeDelta, moves);
|
|
12946
|
+
const { cut, moved: anyMoved } = moves;
|
|
12947
|
+
let seed = moves.seed;
|
|
12948
|
+
if (cut || changed !== anyMoved) {
|
|
12949
|
+
node.formula = cell.formula;
|
|
12950
|
+
this.reanalyze(node);
|
|
12951
|
+
this.structuralSeeds.add(node);
|
|
12952
|
+
return true;
|
|
12953
|
+
}
|
|
12954
|
+
if (traits?.positional && (anyMoved || nodeDelta !== 0)) seed = true;
|
|
12955
|
+
node.deps = deps;
|
|
12956
|
+
node.dynamicDeps = dynamicDeps;
|
|
12957
|
+
if (changed) {
|
|
12958
|
+
node.formula = cell.formula;
|
|
12959
|
+
node.stale = true;
|
|
12960
|
+
}
|
|
12961
|
+
if (seed) this.structuralSeeds.add(node);
|
|
12962
|
+
return true;
|
|
12963
|
+
}
|
|
12964
|
+
/**
|
|
12965
|
+
* Areas moved for the edit (the same list when none moves). Records in `moves` whether one
|
|
12966
|
+
* moved, one was cut (deleted, widened, pushed off the grid) and whether implicit intersection
|
|
12967
|
+
* with one can now pick another cell.
|
|
12968
|
+
*/
|
|
12969
|
+
moveAreas(list, sheet, shift2, pos, nodeDelta, moves) {
|
|
12970
|
+
let out;
|
|
12971
|
+
for (let i2 = 0; i2 < list.length; i2++) {
|
|
12972
|
+
const area = list[i2];
|
|
12973
|
+
const delta = areaDelta(area, sheet, shift2);
|
|
12974
|
+
if (delta === void 0) {
|
|
12975
|
+
moves.cut = true;
|
|
12976
|
+
continue;
|
|
12977
|
+
}
|
|
12978
|
+
if (intersectionMoves(area, delta, pos, nodeDelta, shift2.axis)) moves.seed = true;
|
|
12979
|
+
if (delta === 0) continue;
|
|
12980
|
+
moves.moved = true;
|
|
12981
|
+
out ??= list.slice();
|
|
12982
|
+
out[i2] = { sheet: area.sheet, range: movedRange(area.range, shift2.axis, delta) };
|
|
12983
|
+
}
|
|
12984
|
+
return out ?? list;
|
|
12985
|
+
}
|
|
12986
|
+
/**
|
|
12987
|
+
* Follows a sheet rename (`from` to `to`, formulas already rewritten): precedents are kept by
|
|
12988
|
+
* sheet index, so only rewritten formulas need their text parsed again, and only formulas that
|
|
12989
|
+
* name the new sheet without having been rewritten (previously unresolved), describe sheets
|
|
12990
|
+
* (CELL, SHEET, FORMULATEXT) or read defined names whose areas changed are recalculated.
|
|
12991
|
+
*/
|
|
12992
|
+
renameSheet(from, to) {
|
|
12993
|
+
if (!this.graphReady()) {
|
|
12994
|
+
this.invalidate();
|
|
12995
|
+
return;
|
|
12996
|
+
}
|
|
12997
|
+
const target = to.toLowerCase();
|
|
12998
|
+
let depsChanged = false;
|
|
12999
|
+
for (const map of this.nodes.values())
|
|
13000
|
+
for (const node of map.values()) {
|
|
13001
|
+
const cell = this.workbook.sheets[node.sheet]?.rows.get(node.row)?.get(node.col);
|
|
13002
|
+
if (cell?.formula === void 0) {
|
|
13003
|
+
this.invalidate();
|
|
13004
|
+
return;
|
|
13005
|
+
}
|
|
13006
|
+
const changed = cell.formula !== node.formula;
|
|
13007
|
+
const traits = node.ast && astTraits(node.ast);
|
|
13008
|
+
node.formula = cell.formula;
|
|
13009
|
+
if (traits?.complex || !changed && traits?.sheets.has(target)) {
|
|
13010
|
+
const deps = node.deps;
|
|
13011
|
+
const dynamicDeps = node.dynamicDeps;
|
|
13012
|
+
this.reanalyze(node);
|
|
13013
|
+
const same4 = sameAreas(deps, node.deps) && sameAreas(dynamicDeps, node.dynamicDeps);
|
|
13014
|
+
if (!same4) depsChanged = true;
|
|
13015
|
+
if (!same4 || !traits?.complex) this.structuralSeeds.add(node);
|
|
13016
|
+
} else if (changed) node.stale = true;
|
|
13017
|
+
if (traits?.descriptive || traits?.opaque) this.structuralSeeds.add(node);
|
|
13018
|
+
}
|
|
13019
|
+
if (depsChanged) this.graphChanged();
|
|
13020
|
+
}
|
|
13021
|
+
/** Takes the formulas queued by structural edits. */
|
|
13022
|
+
takeStructuralSeeds(into) {
|
|
13023
|
+
for (const node of this.structuralSeeds)
|
|
13024
|
+
if (this.nodes.get(node.sheet)?.get(cellKey(node.row, node.col)) === node) into.add(node);
|
|
13025
|
+
this.structuralSeeds.clear();
|
|
13026
|
+
}
|
|
13027
|
+
};
|
|
13028
|
+
|
|
12484
13029
|
// xlsx/formula/engine.ts
|
|
12485
|
-
var Engine = class extends
|
|
13030
|
+
var Engine = class extends EngineStructure {
|
|
13031
|
+
preparation;
|
|
13032
|
+
/** The prepared formulas the first recalculation checks (see `trustsStoredValues`). */
|
|
13033
|
+
prepared;
|
|
13034
|
+
// ---- the graph ----
|
|
13035
|
+
prepare(timeRemaining) {
|
|
13036
|
+
if (this.built || this.needsFull) return true;
|
|
13037
|
+
this.preparation ??= this.startPreparation();
|
|
13038
|
+
if (!this.preparation.run(timeRemaining)) return false;
|
|
13039
|
+
this.finishPreparation(this.preparation);
|
|
13040
|
+
return true;
|
|
13041
|
+
}
|
|
13042
|
+
discardPreparation() {
|
|
13043
|
+
if (!this.fresh || this.needsFull) return;
|
|
13044
|
+
this.preparation = void 0;
|
|
13045
|
+
this.prepared = void 0;
|
|
13046
|
+
this.structuralSeeds.clear();
|
|
13047
|
+
this.nodes.clear();
|
|
13048
|
+
this.footprints.clear();
|
|
13049
|
+
this.graphChanged();
|
|
13050
|
+
this.built = false;
|
|
13051
|
+
}
|
|
13052
|
+
/** Completes the graph, continuing a preparation that is under way. */
|
|
13053
|
+
build() {
|
|
13054
|
+
const preparation = this.preparation ?? this.startPreparation();
|
|
13055
|
+
preparation.run();
|
|
13056
|
+
this.finishPreparation(preparation);
|
|
13057
|
+
}
|
|
13058
|
+
startPreparation() {
|
|
13059
|
+
this.nodes.clear();
|
|
13060
|
+
this.footprints.clear();
|
|
13061
|
+
this.footprintIndex = void 0;
|
|
13062
|
+
this.prepared = void 0;
|
|
13063
|
+
return new GraphPreparation(
|
|
13064
|
+
this.workbook,
|
|
13065
|
+
(s, row2, col, cell) => this.createNode(s, row2, col, cell, true)
|
|
13066
|
+
);
|
|
13067
|
+
}
|
|
13068
|
+
finishPreparation(preparation) {
|
|
13069
|
+
this.preparation = void 0;
|
|
13070
|
+
this.built = true;
|
|
13071
|
+
this.graphChanged();
|
|
13072
|
+
this.reverseIndex = preparation.reverse;
|
|
13073
|
+
this.prepared = preparation.formulas;
|
|
13074
|
+
}
|
|
12486
13075
|
// ---- recalculation ----
|
|
12487
13076
|
recalculateAll() {
|
|
13077
|
+
this.fresh = false;
|
|
13078
|
+
this.prepared = void 0;
|
|
12488
13079
|
if (this.needsFull) this.releaseAllSpills();
|
|
12489
13080
|
if (!this.built || this.needsFull) this.build();
|
|
12490
13081
|
this.needsFull = false;
|
|
13082
|
+
this.structuralSeeds.clear();
|
|
12491
13083
|
this.cycles = /* @__PURE__ */ new Set();
|
|
12492
13084
|
this.run(new Set(this.allNodes()), true);
|
|
12493
13085
|
}
|
|
12494
13086
|
recalculateFrom(changes) {
|
|
12495
13087
|
const seeds = /* @__PURE__ */ new Set();
|
|
12496
|
-
if (
|
|
12497
|
-
this.
|
|
13088
|
+
if (this.fresh && !this.needsFull) {
|
|
13089
|
+
this.fresh = false;
|
|
13090
|
+
if (!this.built) this.build();
|
|
12498
13091
|
if (!this.trustsStoredValues(changes, seeds)) {
|
|
12499
13092
|
this.recalculateAll();
|
|
12500
13093
|
return;
|
|
@@ -12538,6 +13131,7 @@ var Engine = class extends EngineCore {
|
|
|
12538
13131
|
}
|
|
12539
13132
|
}
|
|
12540
13133
|
if (structural) this.graphChanged();
|
|
13134
|
+
this.takeStructuralSeeds(seeds);
|
|
12541
13135
|
const reverse2 = this.reverse();
|
|
12542
13136
|
for (const area of changed) reverse2.dependents(area.sheet, area.range, seeds);
|
|
12543
13137
|
for (const node of this.allNodes()) if (node.volatile) seeds.add(node);
|
|
@@ -12549,13 +13143,18 @@ var Engine = class extends EngineCore {
|
|
|
12549
13143
|
* without a value into `missing`.
|
|
12550
13144
|
*/
|
|
12551
13145
|
trustsStoredValues(changes, missing) {
|
|
13146
|
+
const prepared = this.prepared;
|
|
13147
|
+
this.prepared = void 0;
|
|
13148
|
+
if (!prepared) return false;
|
|
12552
13149
|
const changed = new Set(changes.map((c2) => `${c2.sheet}:${cellKey(c2.row, c2.col)}`));
|
|
12553
|
-
|
|
12554
|
-
|
|
12555
|
-
if (
|
|
13150
|
+
const current = (node) => this.nodes.get(node.sheet)?.get(cellKey(node.row, node.col)) === node;
|
|
13151
|
+
for (const node of prepared.dynamic) {
|
|
13152
|
+
if (current(node) && !changed.has(`${node.sheet}:${cellKey(node.row, node.col)}`))
|
|
12556
13153
|
return false;
|
|
13154
|
+
}
|
|
13155
|
+
for (const node of prepared.unvalued) {
|
|
12557
13156
|
const cell = this.workbook.sheets[node.sheet]?.rows.get(node.row)?.get(node.col);
|
|
12558
|
-
if (cell && cell.value === null
|
|
13157
|
+
if (current(node) && cell && cell.value === null) missing.add(node);
|
|
12559
13158
|
}
|
|
12560
13159
|
return true;
|
|
12561
13160
|
}
|
|
@@ -12569,7 +13168,10 @@ var Engine = class extends EngineCore {
|
|
|
12569
13168
|
return !!anchor?.spill && rangeHas(anchor.spill, row2, col);
|
|
12570
13169
|
}
|
|
12571
13170
|
invalidate() {
|
|
13171
|
+
this.structuralSeeds.clear();
|
|
12572
13172
|
this.releaseAllSpills();
|
|
13173
|
+
this.preparation = void 0;
|
|
13174
|
+
this.prepared = void 0;
|
|
12573
13175
|
this.nodes.clear();
|
|
12574
13176
|
this.footprints.clear();
|
|
12575
13177
|
this.graphChanged();
|
|
@@ -12614,7 +13216,7 @@ function createCalcEngine(workbook, options = {}) {
|
|
|
12614
13216
|
return new Engine(workbook, options);
|
|
12615
13217
|
}
|
|
12616
13218
|
|
|
12617
|
-
// xlsx/formula/
|
|
13219
|
+
// xlsx/formula/ref-text.ts
|
|
12618
13220
|
function safeTokens(formula) {
|
|
12619
13221
|
try {
|
|
12620
13222
|
return tokenize(formula);
|
|
@@ -12633,50 +13235,26 @@ function formatRefSpec(spec2) {
|
|
|
12633
13235
|
if (spec2.kind === "cell") return a2;
|
|
12634
13236
|
return `${a2}:${cornerText(spec2.end, spec2.kind)}`;
|
|
12635
13237
|
}
|
|
12636
|
-
function
|
|
13238
|
+
function rewriteRef(token, ref) {
|
|
12637
13239
|
const prefix = token.prefix?.text ?? "";
|
|
12638
13240
|
if (!ref) return `${prefix}#REF!`;
|
|
12639
13241
|
return `${prefix}${formatRefSpec(ref)}${token.spill ? "#" : ""}`;
|
|
12640
13242
|
}
|
|
12641
13243
|
var sameSpec = (a2, b) => a2.kind === b.kind && a2.start.row === b.start.row && a2.start.col === b.start.col && a2.end.row === b.end.row && a2.end.col === b.end.col;
|
|
12642
|
-
|
|
12643
|
-
|
|
12644
|
-
|
|
12645
|
-
|
|
12646
|
-
|
|
12647
|
-
|
|
12648
|
-
const move = (c2) => {
|
|
12649
|
-
const row2 = spec2.kind === "cols" || c2.rowAbs ? c2.row : c2.row + dRow;
|
|
12650
|
-
const col = spec2.kind === "rows" || c2.colAbs ? c2.col : c2.col + dCol;
|
|
12651
|
-
if (row2 < 0 || row2 > MAX_ROW || col < 0 || col > MAX_COL) return void 0;
|
|
12652
|
-
return { ...c2, row: row2, col };
|
|
12653
|
-
};
|
|
12654
|
-
const start = move(spec2.start);
|
|
12655
|
-
const end = move(spec2.end);
|
|
12656
|
-
const next = start && end ? { kind: spec2.kind, start, end } : void 0;
|
|
12657
|
-
if (next && sameSpec(next, spec2)) continue;
|
|
12658
|
-
token.text = rewrite(token, next);
|
|
12659
|
-
}
|
|
12660
|
-
return joinTokens(tokens2);
|
|
13244
|
+
var needsQuote = (name) => !/^[A-Za-z_¡-][A-Za-z0-9_.¡-]*$/.test(name) || /^[A-Za-z]{1,3}\d+$/.test(name) || /^(?:R\d*C?\d*|C\d*)$/i.test(name) || /^(?:TRUE|FALSE)$/i.test(name);
|
|
13245
|
+
function prefixText(prefix) {
|
|
13246
|
+
const sheets = prefix.sheet2 !== void 0 ? `${prefix.sheet}:${prefix.sheet2}` : prefix.sheet;
|
|
13247
|
+
const book = prefix.book !== void 0 ? `[${prefix.book}]` : "";
|
|
13248
|
+
const quote2 = needsQuote(prefix.sheet) || prefix.sheet2 !== void 0 && needsQuote(prefix.sheet2);
|
|
13249
|
+
return quote2 ? `'${(book + sheets).replace(/'/g, "''")}'!` : `${book}${sheets}!`;
|
|
12661
13250
|
}
|
|
12662
|
-
|
|
12663
|
-
|
|
12664
|
-
|
|
12665
|
-
|
|
12666
|
-
|
|
12667
|
-
|
|
12668
|
-
|
|
12669
|
-
const na2 = a2 >= at ? a2 + count2 : a2;
|
|
12670
|
-
const nb2 = b >= at ? b + count2 : b;
|
|
12671
|
-
if (nb2 > max) return na2 > max ? void 0 : [na2, max];
|
|
12672
|
-
return [na2, nb2];
|
|
12673
|
-
}
|
|
12674
|
-
const n2 = -count2;
|
|
12675
|
-
const last = at + n2 - 1;
|
|
12676
|
-
if (a2 >= at && b <= last) return void 0;
|
|
12677
|
-
const na = a2 < at ? a2 : a2 <= last ? at : a2 - n2;
|
|
12678
|
-
const nb = b < at ? b : b <= last ? at - 1 : b - n2;
|
|
12679
|
-
return [na, nb];
|
|
13251
|
+
|
|
13252
|
+
// xlsx/formula/shift-formula.ts
|
|
13253
|
+
var templates = /* @__PURE__ */ new Map();
|
|
13254
|
+
var MAX_TEMPLATES2 = 2e5;
|
|
13255
|
+
function remember(text3, template) {
|
|
13256
|
+
if (templates.size >= MAX_TEMPLATES2) templates.clear();
|
|
13257
|
+
templates.set(text3, template);
|
|
12680
13258
|
}
|
|
12681
13259
|
function mergeSpacedAreas(tokens2) {
|
|
12682
13260
|
const out = [];
|
|
@@ -12703,63 +13281,145 @@ function mergeSpacedAreas(tokens2) {
|
|
|
12703
13281
|
}
|
|
12704
13282
|
return out;
|
|
12705
13283
|
}
|
|
12706
|
-
function
|
|
12707
|
-
|
|
13284
|
+
function templateOf(formula) {
|
|
13285
|
+
const cached = templates.get(formula);
|
|
13286
|
+
if (cached !== void 0) return cached;
|
|
12708
13287
|
const raw2 = safeTokens(formula);
|
|
12709
|
-
|
|
12710
|
-
|
|
12711
|
-
|
|
12712
|
-
|
|
12713
|
-
|
|
12714
|
-
|
|
12715
|
-
|
|
12716
|
-
|
|
12717
|
-
|
|
12718
|
-
|
|
12719
|
-
|
|
12720
|
-
|
|
12721
|
-
|
|
12722
|
-
|
|
12723
|
-
|
|
12724
|
-
|
|
12725
|
-
|
|
12726
|
-
|
|
12727
|
-
|
|
12728
|
-
if (shifted2) {
|
|
12729
|
-
const [a2, b] = shifted2;
|
|
12730
|
-
const nlo = isRow ? { ...lo, row: a2 } : { ...lo, col: a2 };
|
|
12731
|
-
const nhi = isRow ? { ...hi, row: b } : { ...hi, col: b };
|
|
12732
|
-
next = { kind: ref.kind, start: startFirst ? nlo : nhi, end: startFirst ? nhi : nlo };
|
|
12733
|
-
if (ref.kind === "cell") next.end = next.start;
|
|
13288
|
+
let template = null;
|
|
13289
|
+
if (raw2) {
|
|
13290
|
+
template = [];
|
|
13291
|
+
let literal2 = "";
|
|
13292
|
+
for (const token of mergeSpacedAreas(raw2)) {
|
|
13293
|
+
if (token.kind !== "ref" && !(token.kind === "name" && token.prefix)) {
|
|
13294
|
+
literal2 += token.text;
|
|
13295
|
+
continue;
|
|
13296
|
+
}
|
|
13297
|
+
if (literal2) template.push(literal2);
|
|
13298
|
+
literal2 = "";
|
|
13299
|
+
const part = { kind: token.kind, text: token.text };
|
|
13300
|
+
if (token.prefix) {
|
|
13301
|
+
part.prefix = token.prefix;
|
|
13302
|
+
if (token.prefix.book === void 0) part.sheet = token.prefix.sheet.toLowerCase();
|
|
13303
|
+
}
|
|
13304
|
+
if (token.ref) part.ref = token.ref;
|
|
13305
|
+
if (token.spill) part.spill = true;
|
|
13306
|
+
template.push(part);
|
|
12734
13307
|
}
|
|
12735
|
-
if (
|
|
12736
|
-
token.text = rewrite(token, next);
|
|
13308
|
+
if (literal2) template.push(literal2);
|
|
12737
13309
|
}
|
|
12738
|
-
|
|
13310
|
+
remember(formula, template);
|
|
13311
|
+
return template;
|
|
12739
13312
|
}
|
|
12740
|
-
|
|
12741
|
-
|
|
12742
|
-
|
|
12743
|
-
|
|
12744
|
-
|
|
12745
|
-
|
|
13313
|
+
function rewriteTemplate(formula, rewrite2) {
|
|
13314
|
+
const template = templateOf(formula);
|
|
13315
|
+
if (!template) return formula;
|
|
13316
|
+
let next;
|
|
13317
|
+
for (let i2 = 0; i2 < template.length; i2++) {
|
|
13318
|
+
const part = template[i2];
|
|
13319
|
+
if (typeof part === "string") continue;
|
|
13320
|
+
const changed = rewrite2(part);
|
|
13321
|
+
if (!changed) continue;
|
|
13322
|
+
next ??= template.slice();
|
|
13323
|
+
next[i2] = changed;
|
|
13324
|
+
}
|
|
13325
|
+
if (!next) return formula;
|
|
13326
|
+
const text3 = next.map((part) => typeof part === "string" ? part : part.text).join("");
|
|
13327
|
+
remember(text3, next);
|
|
13328
|
+
return text3;
|
|
13329
|
+
}
|
|
13330
|
+
function shiftInterval(a2, b, at, count2, max) {
|
|
13331
|
+
if (count2 > 0) {
|
|
13332
|
+
const na2 = a2 >= at ? a2 + count2 : a2;
|
|
13333
|
+
const nb2 = b >= at ? b + count2 : b;
|
|
13334
|
+
if (nb2 > max) return na2 > max ? void 0 : [na2, max];
|
|
13335
|
+
return [na2, nb2];
|
|
13336
|
+
}
|
|
13337
|
+
const n2 = -count2;
|
|
13338
|
+
const last = at + n2 - 1;
|
|
13339
|
+
if (a2 >= at && b <= last) return void 0;
|
|
13340
|
+
const na = a2 < at ? a2 : a2 <= last ? at : a2 - n2;
|
|
13341
|
+
const nb = b < at ? b : b <= last ? at - 1 : b - n2;
|
|
13342
|
+
return [na, nb];
|
|
13343
|
+
}
|
|
13344
|
+
function shiftRef(ref, spec2) {
|
|
13345
|
+
const isRow = spec2.axis === "row";
|
|
13346
|
+
if (isRow && ref.kind === "cols" || !isRow && ref.kind === "rows") return ref;
|
|
13347
|
+
const startFirst = isRow ? ref.start.row <= ref.end.row : ref.start.col <= ref.end.col;
|
|
13348
|
+
const lo = startFirst ? ref.start : ref.end;
|
|
13349
|
+
const hi = startFirst ? ref.end : ref.start;
|
|
13350
|
+
const shifted2 = shiftInterval(
|
|
13351
|
+
isRow ? lo.row : lo.col,
|
|
13352
|
+
isRow ? hi.row : hi.col,
|
|
13353
|
+
spec2.at,
|
|
13354
|
+
spec2.count,
|
|
13355
|
+
isRow ? MAX_ROW : MAX_COL
|
|
13356
|
+
);
|
|
13357
|
+
if (!shifted2) return void 0;
|
|
13358
|
+
const [a2, b] = shifted2;
|
|
13359
|
+
const nlo = isRow ? { ...lo, row: a2 } : { ...lo, col: a2 };
|
|
13360
|
+
const nhi = isRow ? { ...hi, row: b } : { ...hi, col: b };
|
|
13361
|
+
const next = {
|
|
13362
|
+
kind: ref.kind,
|
|
13363
|
+
start: startFirst ? nlo : nhi,
|
|
13364
|
+
end: startFirst ? nhi : nlo
|
|
13365
|
+
};
|
|
13366
|
+
if (ref.kind === "cell") next.end = next.start;
|
|
13367
|
+
return sameSpec(next, ref) ? ref : next;
|
|
13368
|
+
}
|
|
13369
|
+
function shiftFormula(formula, formulaSheet, spec2) {
|
|
13370
|
+
if (spec2.count === 0) return formula;
|
|
13371
|
+
const sheet = spec2.sheet.toLowerCase();
|
|
13372
|
+
const own = formulaSheet.toLowerCase() === sheet;
|
|
13373
|
+
return rewriteTemplate(formula, (part) => {
|
|
13374
|
+
if (part.kind !== "ref" || !part.ref || (part.prefix ? part.sheet !== sheet : !own))
|
|
13375
|
+
return void 0;
|
|
13376
|
+
const next = shiftRef(part.ref, spec2);
|
|
13377
|
+
if (next === part.ref) return void 0;
|
|
13378
|
+
const out = { kind: "ref", text: rewriteRef(part, next) };
|
|
13379
|
+
if (part.prefix) out.prefix = part.prefix;
|
|
13380
|
+
if (part.sheet !== void 0) out.sheet = part.sheet;
|
|
13381
|
+
if (next) out.ref = next;
|
|
13382
|
+
if (part.spill) out.spill = true;
|
|
13383
|
+
return out;
|
|
13384
|
+
});
|
|
12746
13385
|
}
|
|
12747
13386
|
function renameSheetInFormula(formula, oldName, newName) {
|
|
12748
|
-
const tokens2 = safeTokens(formula);
|
|
12749
|
-
if (!tokens2) return formula;
|
|
12750
13387
|
const lower2 = oldName.toLowerCase();
|
|
12751
|
-
|
|
12752
|
-
const prefix =
|
|
12753
|
-
if (!prefix ||
|
|
12754
|
-
const first2 =
|
|
13388
|
+
return rewriteTemplate(formula, (part) => {
|
|
13389
|
+
const prefix = part.prefix;
|
|
13390
|
+
if (!prefix || part.sheet === void 0) return void 0;
|
|
13391
|
+
const first2 = part.sheet === lower2;
|
|
12755
13392
|
const second = prefix.sheet2?.toLowerCase() === lower2;
|
|
12756
|
-
if (!first2 && !second)
|
|
13393
|
+
if (!first2 && !second) return void 0;
|
|
12757
13394
|
const renamed = { ...prefix, sheet: first2 ? newName : prefix.sheet };
|
|
12758
13395
|
if (prefix.sheet2 !== void 0) renamed.sheet2 = second ? newName : prefix.sheet2;
|
|
12759
13396
|
const text3 = prefixText(renamed);
|
|
12760
|
-
token.text = text3 + token.text.slice(prefix.text.length);
|
|
12761
13397
|
renamed.text = text3;
|
|
12762
|
-
|
|
13398
|
+
const out = { ...part, text: text3 + part.text.slice(prefix.text.length) };
|
|
13399
|
+
out.prefix = renamed;
|
|
13400
|
+
out.sheet = renamed.sheet.toLowerCase();
|
|
13401
|
+
return out;
|
|
13402
|
+
});
|
|
13403
|
+
}
|
|
13404
|
+
|
|
13405
|
+
// xlsx/formula/transform.ts
|
|
13406
|
+
function translateFormula(formula, dRow, dCol) {
|
|
13407
|
+
const tokens2 = safeTokens(formula);
|
|
13408
|
+
if (!tokens2) return formula;
|
|
13409
|
+
for (const token of tokens2) {
|
|
13410
|
+
if (token.kind !== "ref" || !token.ref) continue;
|
|
13411
|
+
const spec2 = token.ref;
|
|
13412
|
+
const move = (c2) => {
|
|
13413
|
+
const row2 = spec2.kind === "cols" || c2.rowAbs ? c2.row : c2.row + dRow;
|
|
13414
|
+
const col = spec2.kind === "rows" || c2.colAbs ? c2.col : c2.col + dCol;
|
|
13415
|
+
if (row2 < 0 || row2 > MAX_ROW || col < 0 || col > MAX_COL) return void 0;
|
|
13416
|
+
return { ...c2, row: row2, col };
|
|
13417
|
+
};
|
|
13418
|
+
const start = move(spec2.start);
|
|
13419
|
+
const end = move(spec2.end);
|
|
13420
|
+
const next = start && end ? { kind: spec2.kind, start, end } : void 0;
|
|
13421
|
+
if (next && sameSpec(next, spec2)) continue;
|
|
13422
|
+
token.text = rewriteRef(token, next);
|
|
12763
13423
|
}
|
|
12764
13424
|
return joinTokens(tokens2);
|
|
12765
13425
|
}
|
|
@@ -15586,7 +16246,7 @@ var FUTURE_FUNCTIONS = new Set(
|
|
|
15586
16246
|
"AGGREGATE BETA.DIST BETA.INV BINOM.DIST BINOM.INV CEILING.PRECISE CHISQ.DIST CHISQ.DIST.RT CHISQ.INV CHISQ.INV.RT CHISQ.TEST CONFIDENCE.NORM CONFIDENCE.T COVARIANCE.P COVARIANCE.S ERF.PRECISE ERFC.PRECISE EXPON.DIST F.DIST F.DIST.RT F.INV F.INV.RT F.TEST FLOOR.PRECISE GAMMA.DIST GAMMA.INV GAMMALN.PRECISE HYPGEOM.DIST LOGNORM.DIST LOGNORM.INV MODE.MULT MODE.SNGL NEGBINOM.DIST NETWORKDAYS.INTL NORM.DIST NORM.INV NORM.S.DIST NORM.S.INV PERCENTILE.EXC PERCENTILE.INC PERCENTRANK.EXC PERCENTRANK.INC POISSON.DIST QUARTILE.EXC QUARTILE.INC RANK.AVG RANK.EQ STDEV.P STDEV.S T.DIST T.DIST.2T T.DIST.RT T.INV T.INV.2T T.TEST VAR.P VAR.S WEIBULL.DIST WORKDAY.INTL ACOT ACOTH ARABIC BASE BINOM.DIST.RANGE BITAND BITLSHIFT BITOR BITRSHIFT BITXOR CEILING.MATH COMBINA COT COTH CSC CSCH DAYS DECIMAL ENCODEURL FILTERXML FLOOR.MATH FORMULATEXT GAMMA GAUSS IFNA IMCOSH IMCOT IMCSC IMCSCH IMSEC IMSECH IMSINH IMTAN ISFORMULA ISOWEEKNUM MUNIT NUMBERVALUE PDURATION PERMUTATIONA PHI RRI SEC SECH SHEET SHEETS SKEW.P UNICHAR UNICODE WEBSERVICE XOR CONCAT FORECAST.ETS FORECAST.ETS.CONFINT FORECAST.ETS.SEASONALITY FORECAST.ETS.STAT FORECAST.LINEAR IFS MAXIFS MINIFS SWITCH TEXTJOIN XLOOKUP XMATCH FILTER SORT SORTBY UNIQUE SEQUENCE RANDARRAY LET LAMBDA TEXTBEFORE TEXTAFTER TEXTSPLIT VSTACK HSTACK TAKE DROP CHOOSEROWS CHOOSECOLS TOCOL TOROW WRAPROWS WRAPCOLS EXPAND ARRAYTOTEXT VALUETOTEXT ISOMITTED BYROW BYCOL MAP REDUCE SCAN MAKEARRAY IMAGE GROUPBY PIVOTBY PERCENTOF REGEXTEST REGEXEXTRACT REGEXREPLACE TRIMRANGE ANCHORARRAY SINGLE STOCKHISTORY FIELDVALUE".split(" ")
|
|
15587
16247
|
);
|
|
15588
16248
|
var WORKSHEET_PREFIXED = /* @__PURE__ */ new Set(["FILTER", "SORT"]);
|
|
15589
|
-
function
|
|
16249
|
+
function rewrite(formula, visit2) {
|
|
15590
16250
|
const out = [];
|
|
15591
16251
|
let i2 = 0;
|
|
15592
16252
|
while (i2 < formula.length) {
|
|
@@ -15629,7 +16289,7 @@ function rewrite2(formula, visit2) {
|
|
|
15629
16289
|
}
|
|
15630
16290
|
function stripFuturePrefixes(formula) {
|
|
15631
16291
|
if (!formula.includes("_xl")) return formula;
|
|
15632
|
-
const plain2 =
|
|
16292
|
+
const plain2 = rewrite(formula, (token, next, out) => {
|
|
15633
16293
|
if (!next.startsWith("(")) return false;
|
|
15634
16294
|
const stripped = token.replace(/^(_xlfn\.)?(_xlws\.)?/i, "");
|
|
15635
16295
|
if (stripped === token) return false;
|
|
@@ -15639,7 +16299,7 @@ function stripFuturePrefixes(formula) {
|
|
|
15639
16299
|
return fromStoredSyntax(plain2);
|
|
15640
16300
|
}
|
|
15641
16301
|
function addFuturePrefixes(formula) {
|
|
15642
|
-
return
|
|
16302
|
+
return rewrite(toStoredSyntax(formula), (token, next, out) => {
|
|
15643
16303
|
if (!next.startsWith("(")) return false;
|
|
15644
16304
|
const upper2 = token.toUpperCase();
|
|
15645
16305
|
if (!FUTURE_FUNCTIONS.has(upper2)) return false;
|
|
@@ -17721,13 +18381,13 @@ function dataBarLengths(rule, node) {
|
|
|
17721
18381
|
maxLength: rule.maxLength ?? numAttr(bar, "maxLength") ?? 90
|
|
17722
18382
|
};
|
|
17723
18383
|
}
|
|
17724
|
-
function rewriteConditionalExtension(rule,
|
|
18384
|
+
function rewriteConditionalExtension(rule, rewrite2) {
|
|
17725
18385
|
if (!rule.extensionXml) return;
|
|
17726
18386
|
const doc = parseXml(rule.extensionXml);
|
|
17727
18387
|
let changed = false;
|
|
17728
18388
|
for (const formula of descendants(doc.documentElement, "f", XM)) {
|
|
17729
18389
|
const before = formula.textContent ?? "";
|
|
17730
|
-
const next =
|
|
18390
|
+
const next = rewrite2(before);
|
|
17731
18391
|
if (before !== next) {
|
|
17732
18392
|
formula.textContent = next;
|
|
17733
18393
|
changed = true;
|
|
@@ -19870,6 +20530,7 @@ Reply:
|
|
|
19870
20530
|
}
|
|
19871
20531
|
|
|
19872
20532
|
// chart/bar-cluster-geometry.ts
|
|
20533
|
+
var DEFAULT_BAR_GAP_WIDTH = 150;
|
|
19873
20534
|
function assertBarClusterOptions(options) {
|
|
19874
20535
|
for (const [field, min, max] of [
|
|
19875
20536
|
["barGapWidth", 0, 500],
|
|
@@ -19883,7 +20544,8 @@ function assertBarClusterOptions(options) {
|
|
|
19883
20544
|
function clusteredBarGeometry(barGroupWidth, seriesCount, chartData) {
|
|
19884
20545
|
const overlap = chartData.barOverlap ?? 0;
|
|
19885
20546
|
const overlapSpan = 1 + (seriesCount - 1) * (1 - overlap / 100);
|
|
19886
|
-
const
|
|
20547
|
+
const gapWidth = chartData.barGapWidth ?? DEFAULT_BAR_GAP_WIDTH;
|
|
20548
|
+
const singleBarWidth = barGroupWidth / (overlapSpan + Math.max(gapWidth, 0) / 100);
|
|
19887
20549
|
const step2 = singleBarWidth * (1 - overlap / 100);
|
|
19888
20550
|
return { singleBarWidth, step: step2, clusterWidth: singleBarWidth + step2 * (seriesCount - 1) };
|
|
19889
20551
|
}
|
|
@@ -24375,13 +25037,13 @@ function linearTrend(values2) {
|
|
|
24375
25037
|
const slope = den ? num3 / den : 0;
|
|
24376
25038
|
return (k) => Number((meanY + slope * (k - meanX)).toPrecision(15));
|
|
24377
25039
|
}
|
|
24378
|
-
var
|
|
25040
|
+
var isDigit5 = (ch) => ch !== void 0 && ch >= "0" && ch <= "9";
|
|
24379
25041
|
function matchTextNumber(text3) {
|
|
24380
25042
|
let end = text3.length;
|
|
24381
|
-
while (end > 0 && !
|
|
25043
|
+
while (end > 0 && !isDigit5(text3[end - 1])) end--;
|
|
24382
25044
|
if (end === 0) return null;
|
|
24383
25045
|
let start = end;
|
|
24384
|
-
while (start > 0 &&
|
|
25046
|
+
while (start > 0 && isDigit5(text3[start - 1])) start--;
|
|
24385
25047
|
return [text3, text3.slice(0, start), text3.slice(start, end), text3.slice(end)];
|
|
24386
25048
|
}
|
|
24387
25049
|
var QUARTER = /^(q|qtr|quarter)(\s?)([1-4])$/i;
|
|
@@ -24564,10 +25226,10 @@ function removeValidationArea(rules, area) {
|
|
|
24564
25226
|
}
|
|
24565
25227
|
|
|
24566
25228
|
// xlsx/edit/conditional-formulas.ts
|
|
24567
|
-
function rewriteConditionalRule(rule,
|
|
25229
|
+
function rewriteConditionalRule(rule, rewrite2) {
|
|
24568
25230
|
const safe2 = (formula) => {
|
|
24569
25231
|
try {
|
|
24570
|
-
return
|
|
25232
|
+
return rewrite2(formula);
|
|
24571
25233
|
} catch {
|
|
24572
25234
|
return formula;
|
|
24573
25235
|
}
|
|
@@ -25086,7 +25748,7 @@ function shiftPreservedXml(sheet, shift2, moveRange, banded) {
|
|
|
25086
25748
|
(xml) => xml.includes("sqref")
|
|
25087
25749
|
);
|
|
25088
25750
|
}
|
|
25089
|
-
function rewritePreservedFormulas(sheet,
|
|
25751
|
+
function rewritePreservedFormulas(sheet, rewrite2) {
|
|
25090
25752
|
editEntries(
|
|
25091
25753
|
sheet,
|
|
25092
25754
|
"extLst",
|
|
@@ -25096,7 +25758,7 @@ function rewritePreservedFormulas(sheet, rewrite3) {
|
|
|
25096
25758
|
const text3 = f6.textContent ?? "";
|
|
25097
25759
|
let next = text3;
|
|
25098
25760
|
try {
|
|
25099
|
-
next =
|
|
25761
|
+
next = rewrite2(text3, sheet.name);
|
|
25100
25762
|
} catch {
|
|
25101
25763
|
next = text3;
|
|
25102
25764
|
}
|
|
@@ -25111,46 +25773,46 @@ function rewritePreservedFormulas(sheet, rewrite3) {
|
|
|
25111
25773
|
}
|
|
25112
25774
|
|
|
25113
25775
|
// xlsx/edit/shift-formulas.ts
|
|
25114
|
-
function safe(
|
|
25776
|
+
function safe(rewrite2, formula, formulaSheet) {
|
|
25115
25777
|
try {
|
|
25116
|
-
return
|
|
25778
|
+
return rewrite2(formula, formulaSheet);
|
|
25117
25779
|
} catch {
|
|
25118
25780
|
return formula;
|
|
25119
25781
|
}
|
|
25120
25782
|
}
|
|
25121
|
-
function rewriteFormulas(workbook,
|
|
25122
|
-
for (const sheet of workbook.sheets) rewriteSheetFormulas(sheet,
|
|
25783
|
+
function rewriteFormulas(workbook, rewrite2) {
|
|
25784
|
+
for (const sheet of workbook.sheets) rewriteSheetFormulas(sheet, rewrite2);
|
|
25123
25785
|
for (const definedName of workbook.definedNames) {
|
|
25124
25786
|
const local = definedName.localSheet === void 0 ? void 0 : workbook.sheets[definedName.localSheet];
|
|
25125
|
-
definedName.formula = safe(
|
|
25787
|
+
definedName.formula = safe(rewrite2, definedName.formula, local?.name ?? "");
|
|
25126
25788
|
}
|
|
25127
25789
|
}
|
|
25128
|
-
function rewriteSheetFormulas(sheet,
|
|
25129
|
-
rewritePreservedFormulas(sheet,
|
|
25790
|
+
function rewriteSheetFormulas(sheet, rewrite2) {
|
|
25791
|
+
rewritePreservedFormulas(sheet, rewrite2);
|
|
25130
25792
|
{
|
|
25131
25793
|
const name = sheet.name;
|
|
25132
25794
|
for (const table2 of sheet.tables)
|
|
25133
25795
|
for (const column of table2.columns)
|
|
25134
25796
|
if (column.calculatedColumnFormula !== void 0)
|
|
25135
|
-
column.calculatedColumnFormula = safe(
|
|
25797
|
+
column.calculatedColumnFormula = safe(rewrite2, column.calculatedColumnFormula, name);
|
|
25136
25798
|
for (const cells of sheet.rows.values())
|
|
25137
25799
|
for (const cell of cells.values())
|
|
25138
|
-
if (cell.formula !== void 0) cell.formula = safe(
|
|
25800
|
+
if (cell.formula !== void 0) cell.formula = safe(rewrite2, cell.formula, name);
|
|
25139
25801
|
for (const cf of sheet.conditionalFormats)
|
|
25140
|
-
for (const rule of cf.rules) rewriteConditionalRule(rule, (f6) =>
|
|
25802
|
+
for (const rule of cf.rules) rewriteConditionalRule(rule, (f6) => rewrite2(f6, name));
|
|
25141
25803
|
for (const dv of sheet.dataValidations) {
|
|
25142
|
-
if (dv.formula1 !== void 0) dv.formula1 = safe(
|
|
25143
|
-
if (dv.formula2 !== void 0) dv.formula2 = safe(
|
|
25804
|
+
if (dv.formula1 !== void 0) dv.formula1 = safe(rewrite2, dv.formula1, name);
|
|
25805
|
+
if (dv.formula2 !== void 0) dv.formula2 = safe(rewrite2, dv.formula2, name);
|
|
25144
25806
|
}
|
|
25145
25807
|
for (const link of sheet.hyperlinks)
|
|
25146
25808
|
if (link.location && /![A-Za-z$]/.test(link.location))
|
|
25147
|
-
link.location = safe(
|
|
25809
|
+
link.location = safe(rewrite2, link.location, name);
|
|
25148
25810
|
for (const drawing of sheet.drawings) {
|
|
25149
25811
|
if (drawing.kind !== "chart") continue;
|
|
25150
25812
|
for (const series of drawing.series) {
|
|
25151
|
-
if (series.nameRef) series.nameRef = safe(
|
|
25152
|
-
if (series.categoriesRef) series.categoriesRef = safe(
|
|
25153
|
-
if (series.valuesRef) series.valuesRef = safe(
|
|
25813
|
+
if (series.nameRef) series.nameRef = safe(rewrite2, series.nameRef, name);
|
|
25814
|
+
if (series.categoriesRef) series.categoriesRef = safe(rewrite2, series.categoriesRef, name);
|
|
25815
|
+
if (series.valuesRef) series.valuesRef = safe(rewrite2, series.valuesRef, name);
|
|
25154
25816
|
}
|
|
25155
25817
|
}
|
|
25156
25818
|
}
|
|
@@ -25337,7 +25999,7 @@ function shiftAxis(ctx, s, axis, at, count2, insert) {
|
|
|
25337
25999
|
applyAxisShift(ctx, sheet, shift2);
|
|
25338
26000
|
if (insert) inheritFormats(sheet, axis, at, count2);
|
|
25339
26001
|
},
|
|
25340
|
-
{ sheet: s, structural: true }
|
|
26002
|
+
{ sheet: s, structural: true, calc: { kind: "shift", sheet: s, shift: shift2 } }
|
|
25341
26003
|
);
|
|
25342
26004
|
}
|
|
25343
26005
|
var insertRows = (ctx, s, at, count2) => shiftAxis(ctx, s, "row", at, count2, true);
|
|
@@ -27155,6 +27817,14 @@ function setCalcMode(ctx, mode) {
|
|
|
27155
27817
|
|
|
27156
27818
|
// xlsx/edit/session-calc.ts
|
|
27157
27819
|
var isStructural = (step2) => step2.structural || step2.entries.some((entry3) => entry3.before.kind !== "cells");
|
|
27820
|
+
function hintFor(step2, mode) {
|
|
27821
|
+
const hint = step2.calc;
|
|
27822
|
+
if (!hint) return void 0;
|
|
27823
|
+
if (hint.kind === "rename")
|
|
27824
|
+
return mode === "undo" ? { kind: "rename", from: hint.to, to: hint.from } : hint;
|
|
27825
|
+
return mode === "undo" ? void 0 : hint;
|
|
27826
|
+
}
|
|
27827
|
+
var settingsOf = (workbook) => `${workbook.iterate ? `${workbook.iterate.count}:${workbook.iterate.delta}` : ""}|${workbook.date1904}`;
|
|
27158
27828
|
var SessionCalculator = class {
|
|
27159
27829
|
constructor(workbook, calc, enabled) {
|
|
27160
27830
|
this.workbook = workbook;
|
|
@@ -27164,43 +27834,113 @@ var SessionCalculator = class {
|
|
|
27164
27834
|
workbook;
|
|
27165
27835
|
calc;
|
|
27166
27836
|
enabled;
|
|
27167
|
-
/** Structural edits
|
|
27837
|
+
/** Structural edits the engine could not follow leave the dependency graph stale (manual mode). */
|
|
27168
27838
|
staleGraph = false;
|
|
27839
|
+
/** Cells changed in manual mode since the last calculation. */
|
|
27840
|
+
dirty = [];
|
|
27841
|
+
/** The settings at the last calculation; undefined before the first. */
|
|
27842
|
+
calculated;
|
|
27169
27843
|
/** Recalculates after an applied, undone or redone step (failures become warnings). */
|
|
27170
|
-
afterStep(step2) {
|
|
27171
|
-
if (!this.enabled)
|
|
27844
|
+
afterStep(step2, mode = "apply") {
|
|
27845
|
+
if (!this.enabled) {
|
|
27846
|
+
this.calc.discardPreparation();
|
|
27847
|
+
return;
|
|
27848
|
+
}
|
|
27849
|
+
const structural = isStructural(step2);
|
|
27850
|
+
const hint = structural ? hintFor(step2, mode) : void 0;
|
|
27172
27851
|
if (calcModeOf(this.workbook) === "manual") {
|
|
27173
|
-
if (
|
|
27852
|
+
if (hint && !this.staleGraph && !this.dirty.length) {
|
|
27853
|
+
this.guard(() => this.follow(hint));
|
|
27854
|
+
return;
|
|
27855
|
+
}
|
|
27856
|
+
this.calc.discardPreparation();
|
|
27857
|
+
if (structural) this.staleGraph = true;
|
|
27858
|
+
else this.dirty.push(...touchedCells(step2));
|
|
27859
|
+
return;
|
|
27860
|
+
}
|
|
27861
|
+
if (hint && !this.staleGraph) {
|
|
27862
|
+
this.guard(() => {
|
|
27863
|
+
this.follow(hint);
|
|
27864
|
+
this.calc.recalculateFrom(touchedCells(step2));
|
|
27865
|
+
this.calculated = settingsOf(this.workbook);
|
|
27866
|
+
});
|
|
27174
27867
|
return;
|
|
27175
27868
|
}
|
|
27176
|
-
this.recalc(
|
|
27869
|
+
this.recalc(structural, () => touchedCells(step2));
|
|
27177
27870
|
}
|
|
27178
27871
|
/** Recalculates after a change applied outside the history (a collaborator's edit). */
|
|
27179
27872
|
afterExternal(structural, cells) {
|
|
27180
|
-
if (!this.enabled)
|
|
27181
|
-
|
|
27873
|
+
if (!this.enabled || calcModeOf(this.workbook) === "manual") {
|
|
27874
|
+
this.calc.discardPreparation();
|
|
27875
|
+
if (!this.enabled) return;
|
|
27182
27876
|
if (structural) this.staleGraph = true;
|
|
27877
|
+
else this.dirty.push(...cells);
|
|
27183
27878
|
return;
|
|
27184
27879
|
}
|
|
27185
27880
|
this.recalc(structural, () => cells);
|
|
27186
27881
|
}
|
|
27187
|
-
|
|
27882
|
+
follow(hint) {
|
|
27883
|
+
if (hint.kind === "shift") this.calc.shiftCells(hint.sheet, hint.shift);
|
|
27884
|
+
else this.calc.renameSheet(hint.from, hint.to);
|
|
27885
|
+
}
|
|
27886
|
+
guard(run2) {
|
|
27887
|
+
try {
|
|
27888
|
+
run2();
|
|
27889
|
+
} catch (error) {
|
|
27890
|
+
const message = `Recalculation failed: ${error instanceof Error ? error.message : String(error)}`;
|
|
27891
|
+
if (!this.workbook.warnings.includes(message)) this.workbook.warnings.push(message);
|
|
27892
|
+
}
|
|
27893
|
+
}
|
|
27894
|
+
/** Builds the dependency graph ahead of the first edit (see `EditSession.prepareCalculation`). */
|
|
27895
|
+
prepare(timeRemaining) {
|
|
27896
|
+
if (!this.enabled || calcModeOf(this.workbook) === "manual" || this.staleGraph) return true;
|
|
27188
27897
|
try {
|
|
27898
|
+
return this.calc.prepare(timeRemaining);
|
|
27899
|
+
} catch {
|
|
27900
|
+
this.calc.discardPreparation();
|
|
27901
|
+
return true;
|
|
27902
|
+
}
|
|
27903
|
+
}
|
|
27904
|
+
/**
|
|
27905
|
+
* Before a structural edit the graph can follow in place: finishes a graph being prepared (or
|
|
27906
|
+
* builds it) while it still matches the workbook, so the edit moves it instead of rebuilding.
|
|
27907
|
+
*/
|
|
27908
|
+
beforeStructural() {
|
|
27909
|
+
if (!this.enabled || calcModeOf(this.workbook) === "manual" || this.staleGraph) return;
|
|
27910
|
+
this.prepare();
|
|
27911
|
+
}
|
|
27912
|
+
recalc(structural, cells) {
|
|
27913
|
+
this.guard(() => {
|
|
27189
27914
|
if (this.staleGraph || structural) this.full();
|
|
27190
27915
|
else {
|
|
27191
27916
|
const changed = cells();
|
|
27192
27917
|
if (changed.length) this.calc.recalculateFrom(changed);
|
|
27918
|
+
this.calculated = settingsOf(this.workbook);
|
|
27193
27919
|
}
|
|
27194
|
-
}
|
|
27195
|
-
const message = `Recalculation failed: ${error instanceof Error ? error.message : String(error)}`;
|
|
27196
|
-
if (!this.workbook.warnings.includes(message)) this.workbook.warnings.push(message);
|
|
27197
|
-
}
|
|
27920
|
+
});
|
|
27198
27921
|
}
|
|
27199
|
-
/** Rebuilds the dependency graph and recalculates every formula (F9). */
|
|
27922
|
+
/** Rebuilds the dependency graph and recalculates every formula (Ctrl+Alt+F9). */
|
|
27200
27923
|
full() {
|
|
27201
27924
|
this.staleGraph = false;
|
|
27925
|
+
this.dirty = [];
|
|
27202
27926
|
this.calc.invalidate();
|
|
27203
27927
|
this.calc.recalculateAll();
|
|
27928
|
+
this.calculated = settingsOf(this.workbook);
|
|
27929
|
+
}
|
|
27930
|
+
/**
|
|
27931
|
+
* Calculate Now (F9): the cells changed since the last calculation, the formulas structural
|
|
27932
|
+
* edits queued, their dependents and the volatile functions. Everything when `full`, before
|
|
27933
|
+
* the session's first calculation, after the iteration settings changed or while the graph
|
|
27934
|
+
* is stale.
|
|
27935
|
+
*/
|
|
27936
|
+
now(full) {
|
|
27937
|
+
if (full || this.staleGraph || this.calculated !== settingsOf(this.workbook)) {
|
|
27938
|
+
this.full();
|
|
27939
|
+
return;
|
|
27940
|
+
}
|
|
27941
|
+
const changed = this.dirty;
|
|
27942
|
+
this.dirty = [];
|
|
27943
|
+
this.calc.recalculateFrom(changed);
|
|
27204
27944
|
}
|
|
27205
27945
|
/**
|
|
27206
27946
|
* Recalculates one sheet's formulas and their dependents (Shift+F9); after structural edits
|
|
@@ -30971,12 +31711,12 @@ function renameSheet(ctx, index2, name) {
|
|
|
30971
31711
|
ctx.run(
|
|
30972
31712
|
"Rename sheet",
|
|
30973
31713
|
"sheets",
|
|
30974
|
-
[{ kind: "
|
|
31714
|
+
[{ kind: "refs" }],
|
|
30975
31715
|
() => {
|
|
30976
31716
|
rewriteFormulas(workbook, (formula) => renameSheetInFormula(formula, old, name));
|
|
30977
31717
|
sheet.name = name;
|
|
30978
31718
|
},
|
|
30979
|
-
{ sheet: index2, structural: true }
|
|
31719
|
+
{ sheet: index2, structural: true, calc: { kind: "rename", from: old, to: name } }
|
|
30980
31720
|
);
|
|
30981
31721
|
}
|
|
30982
31722
|
function moveSheet(ctx, from, to) {
|
|
@@ -31366,13 +32106,12 @@ function createEditSession(workbook, options = {}) {
|
|
|
31366
32106
|
for (const listener of [...listeners]) listener(change);
|
|
31367
32107
|
};
|
|
31368
32108
|
const calculator = new SessionCalculator(workbook, calc, autoRecalc);
|
|
31369
|
-
const recalc = (step2) => calculator.afterStep(step2);
|
|
31370
|
-
const begin = (label2, kind, info) =>
|
|
31371
|
-
|
|
31372
|
-
|
|
31373
|
-
sheet: info.sheet,
|
|
31374
|
-
|
|
31375
|
-
});
|
|
32109
|
+
const recalc = (step2, mode = "apply") => calculator.afterStep(step2, mode);
|
|
32110
|
+
const begin = (label2, kind, info) => {
|
|
32111
|
+
const step2 = { label: label2, entries: [], structural: info.structural ?? false };
|
|
32112
|
+
if (info.calc) step2.calc = info.calc;
|
|
32113
|
+
return { step: step2, kind, sheet: info.sheet, ranges: [...info.ranges ?? []] };
|
|
32114
|
+
};
|
|
31376
32115
|
const finish = (current) => {
|
|
31377
32116
|
if (!current.step.entries.length) return;
|
|
31378
32117
|
history.push(current.step);
|
|
@@ -31397,10 +32136,12 @@ function createEditSession(workbook, options = {}) {
|
|
|
31397
32136
|
const outer = !open;
|
|
31398
32137
|
const current = open ?? begin(label2, kind, info);
|
|
31399
32138
|
if (!outer) {
|
|
32139
|
+
delete current.step.calc;
|
|
31400
32140
|
if (info.structural) current.step.structural = true;
|
|
31401
32141
|
if (current.sheet === void 0 && info.sheet !== void 0) current.sheet = info.sheet;
|
|
31402
32142
|
current.ranges.push(...info.ranges ?? []);
|
|
31403
32143
|
}
|
|
32144
|
+
if (outer && info.calc) calculator.beforeStructural();
|
|
31404
32145
|
open = current;
|
|
31405
32146
|
const mark = current.step.entries.length;
|
|
31406
32147
|
const befores = scopes.map((scope) => captureScope(workbook, scope));
|
|
@@ -31448,7 +32189,7 @@ function createEditSession(workbook, options = {}) {
|
|
|
31448
32189
|
if (open) throw new Error(`Cannot ${kind} inside a batch`);
|
|
31449
32190
|
const step2 = kind === "undo" ? history.undo(workbook) : history.redo(workbook);
|
|
31450
32191
|
if (!step2) return false;
|
|
31451
|
-
recalc(step2);
|
|
32192
|
+
recalc(step2, kind);
|
|
31452
32193
|
emit({ kind, label: step2.label, structural: step2.structural });
|
|
31453
32194
|
return true;
|
|
31454
32195
|
};
|
|
@@ -31527,10 +32268,11 @@ function createEditSession(workbook, options = {}) {
|
|
|
31527
32268
|
setDocumentProperties: (patch2) => setDocumentProperties(ctx, patch2),
|
|
31528
32269
|
setAutoRecalc: (enabled) => setCalcMode(ctx, enabled ? "auto" : "manual"),
|
|
31529
32270
|
autoRecalc: () => autoRecalc && calcModeOf(workbook) === "auto",
|
|
31530
|
-
calculateNow() {
|
|
31531
|
-
calculator.full
|
|
32271
|
+
calculateNow(options2) {
|
|
32272
|
+
calculator.now(options2?.full ?? false);
|
|
31532
32273
|
emit({ kind: "cells", label: "Calculate now", structural: false });
|
|
31533
32274
|
},
|
|
32275
|
+
prepareCalculation: (opts) => calculator.prepare(opts?.timeRemaining),
|
|
31534
32276
|
calculateSheet(s) {
|
|
31535
32277
|
calculator.sheet(s);
|
|
31536
32278
|
emit({ kind: "cells", label: "Calculate sheet", sheet: s, structural: false });
|
|
@@ -32185,6 +32927,7 @@ function selectionStats(workbook, sheet, ranges) {
|
|
|
32185
32927
|
const seen = /* @__PURE__ */ new Set();
|
|
32186
32928
|
let min = Infinity;
|
|
32187
32929
|
let max = -Infinity;
|
|
32930
|
+
let numFmt;
|
|
32188
32931
|
for (const range of ranges)
|
|
32189
32932
|
forEachCellInRange(ws, range, (cell, row2, col) => {
|
|
32190
32933
|
if (ranges.length > 1) {
|
|
@@ -32197,6 +32940,7 @@ function selectionStats(workbook, sheet, ranges) {
|
|
|
32197
32940
|
out.count++;
|
|
32198
32941
|
if (typeof value === "number" && Number.isFinite(value)) {
|
|
32199
32942
|
out.numericCount++;
|
|
32943
|
+
numFmt ??= styleAt(workbook, effectiveStyleId(ws, row2, col)).numFmt || "General";
|
|
32200
32944
|
out.sum += value;
|
|
32201
32945
|
min = Math.min(min, value);
|
|
32202
32946
|
max = Math.max(max, value);
|
|
@@ -32206,9 +32950,13 @@ function selectionStats(workbook, sheet, ranges) {
|
|
|
32206
32950
|
out.average = out.sum / out.numericCount;
|
|
32207
32951
|
out.min = min;
|
|
32208
32952
|
out.max = max;
|
|
32953
|
+
out.numFmt = numFmt ?? "General";
|
|
32209
32954
|
}
|
|
32210
32955
|
return out;
|
|
32211
32956
|
}
|
|
32957
|
+
function formatSelectionStat(workbook, stats, value) {
|
|
32958
|
+
return formatValue(value, stats.numFmt ?? "General", { date1904: workbook.date1904 }).text;
|
|
32959
|
+
}
|
|
32212
32960
|
function isOverflowTarget(sheet, row2, col) {
|
|
32213
32961
|
const cell = getCell(sheet, row2, col);
|
|
32214
32962
|
if (cell && (cell.value !== null && cell.value !== "" || cell.formula)) return false;
|
|
@@ -33093,7 +33841,7 @@ function chartAreaRect(model, part, area) {
|
|
|
33093
33841
|
function chartBarSpacing(chart) {
|
|
33094
33842
|
const stacked = chart.grouping === "stacked" || chart.grouping === "percentStacked";
|
|
33095
33843
|
return {
|
|
33096
|
-
barGapWidth: chart.barGapWidth ??
|
|
33844
|
+
barGapWidth: chart.barGapWidth ?? DEFAULT_BAR_GAP_WIDTH,
|
|
33097
33845
|
barOverlap: chart.barOverlap ?? (stacked ? 100 : 0)
|
|
33098
33846
|
};
|
|
33099
33847
|
}
|
|
@@ -33930,4 +34678,4 @@ function createRefEvaluator(workbook, calc, options = {}) {
|
|
|
33930
34678
|
};
|
|
33931
34679
|
}
|
|
33932
34680
|
|
|
33933
|
-
export { AxisMetrics, BORDER_STYLES, BUILTIN_CELL_STYLES, BUILTIN_NUMBER_FORMATS, CHART_FILL_PARTS, CIRCULAR_REFERENCE_WARNING, COLUMN_PADDING_PX, DEFAULT_ANCHOR_EXTENT_EMU, DEFAULT_BASE_COL_WIDTH, DEFAULT_COL_WIDTH, DEFAULT_MAX_DIGIT_WIDTH, DEFAULT_ROW_HEIGHT, DEFAULT_THEME, DEFAULT_VALIDATION_MESSAGE, ERROR_CODES, FORMAT_PRESETS, FUNCTION_CATALOG, FormulaError, IMAGE_EXTENSIONS, INDENT_PX_PER_LEVEL, INDEXED_COLORS, MAX_COL, MAX_DATE_SERIAL, MAX_OUTLINE_LEVEL, MAX_ROW, MIN_TWO_CELL_PIXELS, OVERFLOW_TEXT, PERCENT_SCALE, REFERENCE_COLORS, THEME_SLOTS, TIME_PERIODS, acceptsReference, activeParam, addFuturePrefixes, anchorKind, anchorToPixelBox, applyBuiltinStyle, applyStylePatch, applyTint, approximateMeasure, autoFitColumnWidth, autoFitRowHeight, autoGrowRows, autoSeriesColor, bordersView, builtinCellStyle, builtinFormatId, calcModeOf, callAtCaret, categoryTotals, cellError, cellInputText, cellKey, cellView, cellsFromText, charactersToColumnWidth, charactersToPixels, chartBarSpacing, chartColorPalettePatch, chartColorScheme, chartDrawingColor, chartElementFill, chartElementFillPatch, chartElementGradientPatch, chartElementSolidFillPatch, chartElementTransparency, chartElementTransparencyPatch, chartGradientStopTransparency, chartSeriesFillPatch, chartSeriesGradientPatch, chartSeriesSolidColor, chartSeriesSolidFillPatch, chartSeriesTransparency, chartSeriesTransparencyPatch, chartView, chartWithElementFills, closeParens, coloredReferences, columnIndex, columnLabel, columnWidthToPixels, compareCellValues, compareValues, createCalcEngine, createConditionalFormatEvaluator, createEditSession, createGridMetrics, createRefEvaluator, createWorkbook, createWorksheet, currentRegion, dateToSerial, defaultCellStyle, defaultColumnPixels, deleteCell, deleteSheetInFormula, detectSeries, edgeView, effectiveStyleId, fillView, fontView, forEachCell, forEachCellInRange, formatAddress, formatAxisValue, formatGeneral, formatRange, formatRefSpec, formatValue, formulaBarText, functionMatches, generalAlignment, getCell, getCellAt, getValue, hasSparklineAt, hls240ToRgb, inTimePeriod, insideString, internStyle, isCellError, isDateFormat, isEmptyCell, isErrorCode, isFormulaText, isOverflowTarget, isSpilledCell, keyToAddress, layoutRemoteSelections, legacyPasswordHash, lineHeightPoints, listValidationOptions, loadXlsx, mergeAt, mergeFont, mergeView, mergeWouldDiscard, mixColors, modernPasswordHash, modulateLuminance, moveReferencesInFormula, nameAtCaret, navigate, needsArrayEvaluation, newMediaPart, nextSheetId, nextSheetName, niceScale, normalizeRange, numberInputText, numberToText, overflowExtent, parseAddress, parseCellInput, parseFormula, parseHex, parseHtmlTable, parseNumberText, parseR1C1Range, parseRange, parseTsv, patchStyle, percentile, pictureAnchorAt, pixelBoxToAnchor, pixelSizeToExtent, pixelsToCharacters, pixelsToColumnWidth, pixelsToPoints, pointsToPixels, presetEdges, putCell, queryPattern, quoteSheetName, rangeContains, rangeSize, rangesIntersect, readSparklineGroup, readSparklineGroups, readSparklineValues, referenceSpans, referenceTarget, referencedRanges, renameSheetInFormula, renameTableInFormula, renderChartSvg, replaceText, resolveColor, resolvePasteOptions, resolveSparklineRange, rgbToHls240, rotationDegrees, rowsToRefit, sameChartColor, saveXlsx, scaleColor, selectionStats, serialToDate, sheetByName, sheetSparklineGroups, shiftFormula, shiftRange, shiftSpan, sparklineScale, sparklineValues, sparklineView, sparklineViewAt, spillAnchorOf, splice, stepDecimals, stripFuturePrefixes, structuredToA1, styleAt, styleKey, subtractRange, syntaxParams, themeColor, timePeriodFormula, toHexColor, toHtml, toTsv, toggleAbsolute, tokenize, translateFormula, translateReferences, uniqueHeaders, usedRange, validateCellInput, validateDefinedName, validateSheetName, validateTableName, validationAt, verifySheetPassword, verifySheetPasswordAsync, verifyWorkbookPassword, visibleCells, wrappedLineCount, zoomPercent };
|
|
34681
|
+
export { AxisMetrics, BORDER_STYLES, BUILTIN_CELL_STYLES, BUILTIN_NUMBER_FORMATS, CHART_FILL_PARTS, CIRCULAR_REFERENCE_WARNING, COLUMN_PADDING_PX, DEFAULT_ANCHOR_EXTENT_EMU, DEFAULT_BASE_COL_WIDTH, DEFAULT_COL_WIDTH, DEFAULT_MAX_DIGIT_WIDTH, DEFAULT_ROW_HEIGHT, DEFAULT_THEME, DEFAULT_VALIDATION_MESSAGE, ERROR_CODES, FORMAT_PRESETS, FUNCTION_CATALOG, FormulaError, IMAGE_EXTENSIONS, INDENT_PX_PER_LEVEL, INDEXED_COLORS, MAX_COL, MAX_DATE_SERIAL, MAX_OUTLINE_LEVEL, MAX_ROW, MIN_TWO_CELL_PIXELS, OVERFLOW_TEXT, PERCENT_SCALE, REFERENCE_COLORS, THEME_SLOTS, TIME_PERIODS, acceptsReference, activeParam, addFuturePrefixes, anchorKind, anchorToPixelBox, applyBuiltinStyle, applyStylePatch, applyTint, approximateMeasure, autoFitColumnWidth, autoFitRowHeight, autoGrowRows, autoSeriesColor, bordersView, builtinCellStyle, builtinFormatId, calcModeOf, callAtCaret, categoryTotals, cellError, cellInputText, cellKey, cellView, cellsFromText, charactersToColumnWidth, charactersToPixels, chartBarSpacing, chartColorPalettePatch, chartColorScheme, chartDrawingColor, chartElementFill, chartElementFillPatch, chartElementGradientPatch, chartElementSolidFillPatch, chartElementTransparency, chartElementTransparencyPatch, chartGradientStopTransparency, chartSeriesFillPatch, chartSeriesGradientPatch, chartSeriesSolidColor, chartSeriesSolidFillPatch, chartSeriesTransparency, chartSeriesTransparencyPatch, chartView, chartWithElementFills, closeParens, coloredReferences, columnIndex, columnLabel, columnWidthToPixels, compareCellValues, compareValues, createCalcEngine, createConditionalFormatEvaluator, createEditSession, createGridMetrics, createRefEvaluator, createWorkbook, createWorksheet, currentRegion, dateToSerial, defaultCellStyle, defaultColumnPixels, deleteCell, deleteSheetInFormula, detectSeries, edgeView, effectiveStyleId, fillView, fontView, forEachCell, forEachCellInRange, formatAddress, formatAxisValue, formatGeneral, formatRange, formatRefSpec, formatSelectionStat, formatValue, formulaBarText, functionMatches, generalAlignment, getCell, getCellAt, getValue, hasSparklineAt, hls240ToRgb, inTimePeriod, insideString, internStyle, isCellError, isDateFormat, isEmptyCell, isErrorCode, isFormulaText, isOverflowTarget, isSpilledCell, keyToAddress, layoutRemoteSelections, legacyPasswordHash, lineHeightPoints, listValidationOptions, loadXlsx, mergeAt, mergeFont, mergeView, mergeWouldDiscard, mixColors, modernPasswordHash, modulateLuminance, moveReferencesInFormula, nameAtCaret, navigate, needsArrayEvaluation, newMediaPart, nextSheetId, nextSheetName, niceScale, normalizeRange, numberInputText, numberToText, overflowExtent, parseAddress, parseCellInput, parseFormula, parseHex, parseHtmlTable, parseNumberText, parseR1C1Range, parseRange, parseTsv, patchStyle, percentile, pictureAnchorAt, pixelBoxToAnchor, pixelSizeToExtent, pixelsToCharacters, pixelsToColumnWidth, pixelsToPoints, pointsToPixels, presetEdges, putCell, queryPattern, quoteSheetName, rangeContains, rangeSize, rangesIntersect, readSparklineGroup, readSparklineGroups, readSparklineValues, referenceSpans, referenceTarget, referencedRanges, renameSheetInFormula, renameTableInFormula, renderChartSvg, replaceText, resolveColor, resolvePasteOptions, resolveSparklineRange, rgbToHls240, rotationDegrees, rowsToRefit, sameChartColor, saveXlsx, scaleColor, selectionStats, serialToDate, sheetByName, sheetSparklineGroups, shiftFormula, shiftRange, shiftSpan, sparklineScale, sparklineValues, sparklineView, sparklineViewAt, spillAnchorOf, splice, stepDecimals, stripFuturePrefixes, structuredToA1, styleAt, styleKey, subtractRange, syntaxParams, themeColor, timePeriodFormula, toHexColor, toHtml, toTsv, toggleAbsolute, tokenize, translateFormula, translateReferences, uniqueHeaders, usedRange, validateCellInput, validateDefinedName, validateSheetName, validateTableName, validationAt, verifySheetPassword, verifySheetPasswordAsync, verifyWorkbookPassword, visibleCells, wrappedLineCount, zoomPercent };
|