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/ui/index.cjs
CHANGED
|
@@ -2042,7 +2042,7 @@ var NAME_RE = /^[A-Za-z_\\\u00A1-\uFFFF][A-Za-z0-9_.?\\\u00A1-\uFFFF]*/;
|
|
|
2042
2042
|
var CELL_RE = /^(\$?)([A-Za-z]{1,3})(\$?)(\d{1,7})/;
|
|
2043
2043
|
var COLS_RE = /^(\$?)([A-Za-z]{1,3}):(\$?)([A-Za-z]{1,3})/;
|
|
2044
2044
|
var ROWS_RE = /^(\$?)(\d{1,7}):(\$?)(\d{1,7})/;
|
|
2045
|
-
var NUMBER_RE2 = /^(?:\d
|
|
2045
|
+
var NUMBER_RE2 = /^(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?/;
|
|
2046
2046
|
var sticky = (re) => new RegExp(re.source.replace(/^\^/, ""), "y");
|
|
2047
2047
|
var CELL_AT = sticky(CELL_RE);
|
|
2048
2048
|
var COLS_AT = sticky(COLS_RE);
|
|
@@ -2202,14 +2202,13 @@ function splitSheets(text2) {
|
|
|
2202
2202
|
if (book !== void 0) out.book = book;
|
|
2203
2203
|
return out;
|
|
2204
2204
|
}
|
|
2205
|
-
var PREFIX_AT = /(\[\d+\])?([A-Za-z0-9_.\u00A1-\uFFFF]+)(?::([A-Za-z0-9_.\u00A1-\uFFFF]+))?!/y;
|
|
2206
2205
|
function readPrefix(source, at) {
|
|
2207
2206
|
const ch = source[at];
|
|
2208
2207
|
if (ch === "'") {
|
|
2209
2208
|
const quoted = readQuoted(source, at);
|
|
2210
2209
|
if (source[at + quoted.length] !== "!") return void 0;
|
|
2211
|
-
const
|
|
2212
|
-
return { prefix: { text: source.slice(at, at +
|
|
2210
|
+
const length2 = quoted.length + 1;
|
|
2211
|
+
return { prefix: { text: source.slice(at, at + length2), ...splitSheets(quoted.name) }, length: length2 };
|
|
2213
2212
|
}
|
|
2214
2213
|
let i2 = at;
|
|
2215
2214
|
if (ch === "[") {
|
|
@@ -2218,13 +2217,23 @@ function readPrefix(source, at) {
|
|
|
2218
2217
|
if (i2 === at + 1 || source[i2] !== "]") return void 0;
|
|
2219
2218
|
i2++;
|
|
2220
2219
|
}
|
|
2220
|
+
const sheetFrom = i2;
|
|
2221
2221
|
while (i2 < source.length && isSheetCharCode(source.charCodeAt(i2))) i2++;
|
|
2222
|
-
if (
|
|
2223
|
-
|
|
2224
|
-
if (
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2222
|
+
if (i2 === sheetFrom) return void 0;
|
|
2223
|
+
let lastFrom = -1;
|
|
2224
|
+
if (source[i2] === ":") {
|
|
2225
|
+
lastFrom = i2 + 1;
|
|
2226
|
+
i2 = lastFrom;
|
|
2227
|
+
while (i2 < source.length && isSheetCharCode(source.charCodeAt(i2))) i2++;
|
|
2228
|
+
if (i2 === lastFrom) return void 0;
|
|
2229
|
+
}
|
|
2230
|
+
if (source[i2] !== "!") return void 0;
|
|
2231
|
+
if (ch !== "[" && lastFrom < 0 && isDigitCode(source.charCodeAt(sheetFrom))) return void 0;
|
|
2232
|
+
const length = i2 + 1 - at;
|
|
2233
|
+
return {
|
|
2234
|
+
prefix: { text: source.slice(at, at + length), ...splitSheets(source.slice(at, i2)) },
|
|
2235
|
+
length
|
|
2236
|
+
};
|
|
2228
2237
|
}
|
|
2229
2238
|
function numberLiteral(text2) {
|
|
2230
2239
|
if (text2.length <= 15) return Number(text2);
|
|
@@ -2414,7 +2423,9 @@ var PREC_INTERSECT = 9;
|
|
|
2414
2423
|
var PREC_RANGE = 10;
|
|
2415
2424
|
var OPERAND_START = /* @__PURE__ */ new Set(["ref", "name", "func", "open", "structured"]);
|
|
2416
2425
|
function parseFormula(formula) {
|
|
2417
|
-
|
|
2426
|
+
return parseTokens(tokenize(formula));
|
|
2427
|
+
}
|
|
2428
|
+
function parseTokens(all2) {
|
|
2418
2429
|
const tokens = [];
|
|
2419
2430
|
const wsBefore = [];
|
|
2420
2431
|
let sawWs = false;
|
|
@@ -2699,6 +2710,222 @@ function localDateToSerial(date, date1904 = date1904Mode) {
|
|
|
2699
2710
|
return base + (utc - dayStart) / DAY_MS;
|
|
2700
2711
|
}
|
|
2701
2712
|
|
|
2713
|
+
// xlsx/formula/area-index.ts
|
|
2714
|
+
var BUCKET_WIDTH = 64;
|
|
2715
|
+
var CHUNK_SHIFT = 6;
|
|
2716
|
+
var CHUNKS = 64;
|
|
2717
|
+
function push(map, key, value2) {
|
|
2718
|
+
const list = map.get(key);
|
|
2719
|
+
if (list) list.push(value2);
|
|
2720
|
+
else map.set(key, [value2]);
|
|
2721
|
+
}
|
|
2722
|
+
function inner(map, sheet) {
|
|
2723
|
+
let found = map.get(sheet);
|
|
2724
|
+
if (!found) map.set(sheet, found = /* @__PURE__ */ new Map());
|
|
2725
|
+
return found;
|
|
2726
|
+
}
|
|
2727
|
+
var AreaIndex = class {
|
|
2728
|
+
cells = /* @__PURE__ */ new Map();
|
|
2729
|
+
chunked = /* @__PURE__ */ new Map();
|
|
2730
|
+
tall = /* @__PURE__ */ new Map();
|
|
2731
|
+
wide = /* @__PURE__ */ new Map();
|
|
2732
|
+
add(area, node) {
|
|
2733
|
+
const { start, end } = area.range;
|
|
2734
|
+
if (start.row === end.row && end.col - start.col + 1 <= BUCKET_WIDTH) {
|
|
2735
|
+
const cells = inner(this.cells, area.sheet);
|
|
2736
|
+
for (let col = start.col; col <= end.col; col++) push(cells, cellKey(start.row, col), node);
|
|
2737
|
+
return;
|
|
2738
|
+
}
|
|
2739
|
+
const entry = { range: area.range, node };
|
|
2740
|
+
if (end.col - start.col + 1 > BUCKET_WIDTH) {
|
|
2741
|
+
const list = this.wide.get(area.sheet);
|
|
2742
|
+
if (list) list.push(entry);
|
|
2743
|
+
else this.wide.set(area.sheet, [entry]);
|
|
2744
|
+
return;
|
|
2745
|
+
}
|
|
2746
|
+
const first2 = start.row >> CHUNK_SHIFT;
|
|
2747
|
+
const last = end.row >> CHUNK_SHIFT;
|
|
2748
|
+
if (last - first2 + 1 > CHUNKS) {
|
|
2749
|
+
const cols2 = inner(this.tall, area.sheet);
|
|
2750
|
+
for (let c = start.col; c <= end.col; c++) push(cols2, c, entry);
|
|
2751
|
+
return;
|
|
2752
|
+
}
|
|
2753
|
+
const cols = inner(this.chunked, area.sheet);
|
|
2754
|
+
for (let c = start.col; c <= end.col; c++) {
|
|
2755
|
+
let chunks = cols.get(c);
|
|
2756
|
+
if (!chunks) cols.set(c, chunks = /* @__PURE__ */ new Map());
|
|
2757
|
+
for (let k = first2; k <= last; k++) push(chunks, k, entry);
|
|
2758
|
+
}
|
|
2759
|
+
}
|
|
2760
|
+
/** Items whose areas intersect `range` on `sheet` (each once). */
|
|
2761
|
+
dependents(sheet, range2, out) {
|
|
2762
|
+
const found = out instanceof Set ? out : /* @__PURE__ */ new Set();
|
|
2763
|
+
this.collect(sheet, range2, found);
|
|
2764
|
+
if (Array.isArray(out)) for (const node of found) out.push(node);
|
|
2765
|
+
}
|
|
2766
|
+
collect(sheet, range2, out) {
|
|
2767
|
+
const { start, end } = range2;
|
|
2768
|
+
const check3 = (list) => {
|
|
2769
|
+
if (list) {
|
|
2770
|
+
for (const entry of list) if (rangesIntersect(entry.range, range2)) out.add(entry.node);
|
|
2771
|
+
}
|
|
2772
|
+
};
|
|
2773
|
+
const cells = this.cells.get(sheet);
|
|
2774
|
+
if (cells) {
|
|
2775
|
+
const size = (end.row - start.row + 1) * (end.col - start.col + 1);
|
|
2776
|
+
if (size <= 4096) {
|
|
2777
|
+
for (let r = start.row; r <= end.row; r++) {
|
|
2778
|
+
for (let c = start.col; c <= end.col; c++) {
|
|
2779
|
+
const list = cells.get(cellKey(r, c));
|
|
2780
|
+
if (list) for (const node of list) out.add(node);
|
|
2781
|
+
}
|
|
2782
|
+
}
|
|
2783
|
+
} else {
|
|
2784
|
+
for (const [key, list] of cells) {
|
|
2785
|
+
const { row: row2, col } = keyToAddress(key);
|
|
2786
|
+
if (row2 >= start.row && row2 <= end.row && col >= start.col && col <= end.col)
|
|
2787
|
+
for (const node of list) out.add(node);
|
|
2788
|
+
}
|
|
2789
|
+
}
|
|
2790
|
+
}
|
|
2791
|
+
const columns = (map, visit2) => {
|
|
2792
|
+
if (!map) return;
|
|
2793
|
+
if (end.col - start.col + 1 <= map.size) {
|
|
2794
|
+
for (let c = start.col; c <= end.col; c++) if (map.has(c)) visit2(c);
|
|
2795
|
+
} else for (const c of map.keys()) if (c >= start.col && c <= end.col) visit2(c);
|
|
2796
|
+
};
|
|
2797
|
+
const chunked = this.chunked.get(sheet);
|
|
2798
|
+
const first2 = start.row >> CHUNK_SHIFT;
|
|
2799
|
+
const last = end.row >> CHUNK_SHIFT;
|
|
2800
|
+
columns(chunked, (c) => {
|
|
2801
|
+
const chunks = chunked?.get(c);
|
|
2802
|
+
if (last - first2 + 1 <= chunks.size) {
|
|
2803
|
+
for (let k = first2; k <= last; k++) check3(chunks.get(k));
|
|
2804
|
+
} else for (const [k, list] of chunks) if (k >= first2 && k <= last) check3(list);
|
|
2805
|
+
});
|
|
2806
|
+
const tall = this.tall.get(sheet);
|
|
2807
|
+
columns(tall, (c) => check3(tall?.get(c)));
|
|
2808
|
+
check3(this.wide.get(sheet));
|
|
2809
|
+
}
|
|
2810
|
+
};
|
|
2811
|
+
|
|
2812
|
+
// xlsx/formula/graph-index.ts
|
|
2813
|
+
var ColumnIndex = class {
|
|
2814
|
+
sheets = /* @__PURE__ */ new Map();
|
|
2815
|
+
constructor(nodes) {
|
|
2816
|
+
for (const node of nodes) {
|
|
2817
|
+
let cols = this.sheets.get(node.sheet);
|
|
2818
|
+
if (!cols) this.sheets.set(node.sheet, cols = /* @__PURE__ */ new Map());
|
|
2819
|
+
let list = cols.get(node.col);
|
|
2820
|
+
if (!list) cols.set(node.col, list = []);
|
|
2821
|
+
list.push(node);
|
|
2822
|
+
}
|
|
2823
|
+
for (const cols of this.sheets.values())
|
|
2824
|
+
for (const list of cols.values()) list.sort((a, b) => a.row - b.row);
|
|
2825
|
+
}
|
|
2826
|
+
nodesIn(area, out) {
|
|
2827
|
+
const cols = this.sheets.get(area.sheet);
|
|
2828
|
+
if (!cols) return;
|
|
2829
|
+
const { start, end } = area.range;
|
|
2830
|
+
const width = end.col - start.col + 1;
|
|
2831
|
+
const scan2 = (list) => {
|
|
2832
|
+
let lo = 0;
|
|
2833
|
+
let hi = list.length;
|
|
2834
|
+
while (lo < hi) {
|
|
2835
|
+
const mid = lo + hi >> 1;
|
|
2836
|
+
if (list[mid].row < start.row) lo = mid + 1;
|
|
2837
|
+
else hi = mid;
|
|
2838
|
+
}
|
|
2839
|
+
for (let i2 = lo; i2 < list.length; i2++) {
|
|
2840
|
+
const node = list[i2];
|
|
2841
|
+
if (node.row > end.row) break;
|
|
2842
|
+
out.push(node);
|
|
2843
|
+
}
|
|
2844
|
+
};
|
|
2845
|
+
if (width <= cols.size) {
|
|
2846
|
+
for (let c = start.col; c <= end.col; c++) {
|
|
2847
|
+
const list = cols.get(c);
|
|
2848
|
+
if (list) scan2(list);
|
|
2849
|
+
}
|
|
2850
|
+
} else {
|
|
2851
|
+
for (const [c, list] of cols) if (c >= start.col && c <= end.col) scan2(list);
|
|
2852
|
+
}
|
|
2853
|
+
}
|
|
2854
|
+
};
|
|
2855
|
+
var ReverseIndex = class extends AreaIndex {
|
|
2856
|
+
constructor(nodes = []) {
|
|
2857
|
+
super();
|
|
2858
|
+
for (const node of nodes) this.addNode(node);
|
|
2859
|
+
}
|
|
2860
|
+
/** Indexes one more formula's precedents. */
|
|
2861
|
+
addNode(node) {
|
|
2862
|
+
for (const dep of node.deps) this.add(dep, node);
|
|
2863
|
+
for (const dep of node.dynamicDeps) this.add(dep, node);
|
|
2864
|
+
}
|
|
2865
|
+
};
|
|
2866
|
+
|
|
2867
|
+
// xlsx/formula/engine-prepare.ts
|
|
2868
|
+
var CHECK_EVERY = 32;
|
|
2869
|
+
var GraphPreparation = class {
|
|
2870
|
+
constructor(workbook, create) {
|
|
2871
|
+
this.workbook = workbook;
|
|
2872
|
+
this.create = create;
|
|
2873
|
+
}
|
|
2874
|
+
workbook;
|
|
2875
|
+
create;
|
|
2876
|
+
reverse = new ReverseIndex();
|
|
2877
|
+
formulas = { dynamic: [], unvalued: [] };
|
|
2878
|
+
sheet = 0;
|
|
2879
|
+
rows;
|
|
2880
|
+
row = 0;
|
|
2881
|
+
cells;
|
|
2882
|
+
finished = false;
|
|
2883
|
+
/**
|
|
2884
|
+
* Adds formulas to the graph until `timeRemaining` (milliseconds, as an idle deadline reports
|
|
2885
|
+
* them) reaches zero, or until every formula is in. Returns true when the graph is complete.
|
|
2886
|
+
*/
|
|
2887
|
+
run(timeRemaining) {
|
|
2888
|
+
let visited = 0;
|
|
2889
|
+
while (!this.finished) {
|
|
2890
|
+
const cells = this.cells ?? this.nextRow();
|
|
2891
|
+
if (!cells) continue;
|
|
2892
|
+
const next = cells.next();
|
|
2893
|
+
if (next.done) {
|
|
2894
|
+
this.cells = void 0;
|
|
2895
|
+
continue;
|
|
2896
|
+
}
|
|
2897
|
+
const [col, cell] = next.value;
|
|
2898
|
+
if (cell.formula) this.add(this.create(this.sheet, this.row, col, cell), cell);
|
|
2899
|
+
if (timeRemaining && ++visited % CHECK_EVERY === 0 && timeRemaining() <= 0) break;
|
|
2900
|
+
}
|
|
2901
|
+
return this.finished;
|
|
2902
|
+
}
|
|
2903
|
+
add(node, cell) {
|
|
2904
|
+
this.reverse.addNode(node);
|
|
2905
|
+
if (!node.legacy && !node.arrayRange) this.formulas.dynamic.push(node);
|
|
2906
|
+
if (cell.value === null && !node.keepCached) this.formulas.unvalued.push(node);
|
|
2907
|
+
}
|
|
2908
|
+
/** Moves to the next stored row (and sheet), or marks the walk finished. */
|
|
2909
|
+
nextRow() {
|
|
2910
|
+
for (; ; ) {
|
|
2911
|
+
const sheet = this.workbook.sheets[this.sheet];
|
|
2912
|
+
if (!sheet) {
|
|
2913
|
+
this.finished = true;
|
|
2914
|
+
return void 0;
|
|
2915
|
+
}
|
|
2916
|
+
this.rows ??= sheet.rows.entries();
|
|
2917
|
+
const next = this.rows.next();
|
|
2918
|
+
if (!next.done) {
|
|
2919
|
+
this.row = next.value[0];
|
|
2920
|
+
this.cells = next.value[1].entries();
|
|
2921
|
+
return this.cells;
|
|
2922
|
+
}
|
|
2923
|
+
this.rows = void 0;
|
|
2924
|
+
this.sheet++;
|
|
2925
|
+
}
|
|
2926
|
+
}
|
|
2927
|
+
};
|
|
2928
|
+
|
|
2702
2929
|
// xlsx/formula/text-number.ts
|
|
2703
2930
|
var MONTHS2 = [
|
|
2704
2931
|
"jan",
|
|
@@ -5833,8 +6060,10 @@ var FINANCIAL_FUNCTIONS = [
|
|
|
5833
6060
|
|
|
5834
6061
|
// xlsx/formula/references.ts
|
|
5835
6062
|
function sheetIndex(host, name) {
|
|
6063
|
+
const sheets = host.workbook.sheets;
|
|
6064
|
+
for (let i2 = 0; i2 < sheets.length; i2++) if (sheets[i2]?.name === name) return i2;
|
|
5836
6065
|
const lower2 = name.toLowerCase();
|
|
5837
|
-
return
|
|
6066
|
+
return sheets.findIndex((sheet) => sheet.name.toLowerCase() === lower2);
|
|
5838
6067
|
}
|
|
5839
6068
|
function prefixSheets(host, prefix, current) {
|
|
5840
6069
|
if (!prefix) return [current];
|
|
@@ -7404,9 +7633,9 @@ function readBlock(ctx, area, rows2, cols) {
|
|
|
7404
7633
|
if (host.readBlock) return host.readBlock(area.sheet, range2);
|
|
7405
7634
|
return Matrix.build(rows2, cols, (r, c) => ctx.readCell(area.sheet, row2 + r, col + c));
|
|
7406
7635
|
}
|
|
7407
|
-
function shapedMatrices(ctx, values2,
|
|
7636
|
+
function shapedMatrices(ctx, values2, sameShape2) {
|
|
7408
7637
|
let { rows: rows2, cols } = shapeOf(values2[0] ?? null);
|
|
7409
|
-
if (
|
|
7638
|
+
if (sameShape2) {
|
|
7410
7639
|
for (const value2 of values2) {
|
|
7411
7640
|
const shape2 = shapeOf(value2);
|
|
7412
7641
|
if (shape2.rows !== rows2 || shape2.cols !== cols) fail(ERR.VALUE);
|
|
@@ -7432,12 +7661,12 @@ function shapedMatrices(ctx, values2, sameShape) {
|
|
|
7432
7661
|
});
|
|
7433
7662
|
return { matrices, total: total2, block: rows2 * cols };
|
|
7434
7663
|
}
|
|
7435
|
-
function matchingCells(ctx, pairs, target2,
|
|
7664
|
+
function matchingCells(ctx, pairs, target2, sameShape2) {
|
|
7436
7665
|
const ranges = pairs.map((p) => p.range);
|
|
7437
7666
|
const { matrices, total: total2, block } = shapedMatrices(
|
|
7438
7667
|
ctx,
|
|
7439
7668
|
target2 === void 0 ? ranges : [...ranges, target2],
|
|
7440
|
-
|
|
7669
|
+
sameShape2
|
|
7441
7670
|
);
|
|
7442
7671
|
const tests = pairs.map((p) => makeCriteria(scalar(p.criteria)));
|
|
7443
7672
|
const values2 = matrices[matrices.length - 1];
|
|
@@ -7476,7 +7705,7 @@ function indexedCandidates(pairs, matrices) {
|
|
|
7476
7705
|
}
|
|
7477
7706
|
return void 0;
|
|
7478
7707
|
}
|
|
7479
|
-
var matchingValues = (ctx, pairs, target2,
|
|
7708
|
+
var matchingValues = (ctx, pairs, target2, sameShape2) => matchingCells(ctx, pairs, target2, sameShape2).values;
|
|
7480
7709
|
function criteriaPairs(args, from) {
|
|
7481
7710
|
if ((args.length - from) % 2 !== 0) fail(ERR.VALUE);
|
|
7482
7711
|
const pairs = [];
|
|
@@ -11370,7 +11599,7 @@ var REFERENCE_ARGUMENT = /* @__PURE__ */ new Set([
|
|
|
11370
11599
|
"AREAS",
|
|
11371
11600
|
"ISREF"
|
|
11372
11601
|
]);
|
|
11373
|
-
var
|
|
11602
|
+
var push2 = (c, area) => {
|
|
11374
11603
|
(c.dynamic > 0 ? c.dynamicDeps : c.deps).push(area);
|
|
11375
11604
|
};
|
|
11376
11605
|
function spans(areas) {
|
|
@@ -11396,7 +11625,7 @@ function visit(node, c) {
|
|
|
11396
11625
|
if (!sheets) return;
|
|
11397
11626
|
const range2 = specRange(node.ref);
|
|
11398
11627
|
const target2 = node.spill ? { start: range2.start, end: { ...range2.start } } : range2;
|
|
11399
|
-
for (const sheet of sheets)
|
|
11628
|
+
for (const sheet of sheets) push2(c, { sheet, range: target2 });
|
|
11400
11629
|
return;
|
|
11401
11630
|
}
|
|
11402
11631
|
case "name": {
|
|
@@ -11470,7 +11699,7 @@ function visitBinary(node, c) {
|
|
|
11470
11699
|
const list = c.dynamic > 0 ? c.dynamicDeps : c.deps;
|
|
11471
11700
|
const l = list[list.length - 2];
|
|
11472
11701
|
const r = list[list.length - 1];
|
|
11473
|
-
if (l && r && l.sheet === r.sheet)
|
|
11702
|
+
if (l && r && l.sheet === r.sheet) push2(c, spans([l, r])[0]);
|
|
11474
11703
|
continue;
|
|
11475
11704
|
}
|
|
11476
11705
|
const mentioned = [...c.deps.slice(staticStart), ...c.dynamicDeps.slice(dynamicStart)];
|
|
@@ -11486,7 +11715,7 @@ function addStructured(ref, c) {
|
|
|
11486
11715
|
sheet: c.sheet,
|
|
11487
11716
|
row: c.row,
|
|
11488
11717
|
col: c.col});
|
|
11489
|
-
if (value2 instanceof RefValue) for (const area of value2.areas)
|
|
11718
|
+
if (value2 instanceof RefValue) for (const area of value2.areas) push2(c, area);
|
|
11490
11719
|
}
|
|
11491
11720
|
function analyze(ast, host, sheet, row2, col) {
|
|
11492
11721
|
const c = {
|
|
@@ -11510,155 +11739,191 @@ function analyze(ast, host, sheet, row2, col) {
|
|
|
11510
11739
|
};
|
|
11511
11740
|
}
|
|
11512
11741
|
|
|
11513
|
-
// xlsx/formula/
|
|
11514
|
-
var
|
|
11515
|
-
|
|
11516
|
-
|
|
11517
|
-
|
|
11518
|
-
|
|
11519
|
-
|
|
11520
|
-
|
|
11742
|
+
// xlsx/formula/formula-shape.ts
|
|
11743
|
+
var isDigit4 = (code) => code >= 48 && code <= 57;
|
|
11744
|
+
function formulaShape(formula) {
|
|
11745
|
+
const starts = [];
|
|
11746
|
+
const ends = [];
|
|
11747
|
+
let hash = 2166136261;
|
|
11748
|
+
for (let i2 = 0; i2 < formula.length; i2++) {
|
|
11749
|
+
let code = formula.charCodeAt(i2);
|
|
11750
|
+
if (isDigit4(code)) {
|
|
11751
|
+
let j = i2 + 1;
|
|
11752
|
+
while (j < formula.length && isDigit4(formula.charCodeAt(j))) j++;
|
|
11753
|
+
starts.push(i2);
|
|
11754
|
+
ends.push(j);
|
|
11755
|
+
i2 = j - 1;
|
|
11756
|
+
code = 0;
|
|
11757
|
+
}
|
|
11758
|
+
hash = Math.imul(hash ^ code, 16777619);
|
|
11759
|
+
}
|
|
11760
|
+
return { hash: hash >>> 0, starts, ends };
|
|
11521
11761
|
}
|
|
11522
|
-
function
|
|
11523
|
-
let
|
|
11524
|
-
|
|
11525
|
-
return
|
|
11762
|
+
function sameText(a, from, b, at, length) {
|
|
11763
|
+
for (let k = 0; k < length; k++)
|
|
11764
|
+
if (a.charCodeAt(from + k) !== b.charCodeAt(at + k)) return false;
|
|
11765
|
+
return true;
|
|
11526
11766
|
}
|
|
11527
|
-
|
|
11528
|
-
|
|
11529
|
-
|
|
11530
|
-
|
|
11531
|
-
|
|
11532
|
-
|
|
11533
|
-
const
|
|
11534
|
-
|
|
11535
|
-
|
|
11536
|
-
|
|
11537
|
-
|
|
11767
|
+
function sameShape(a, as, b, bs) {
|
|
11768
|
+
const runs = as.starts.length;
|
|
11769
|
+
if (runs !== bs.starts.length) return false;
|
|
11770
|
+
let fromA = 0;
|
|
11771
|
+
let fromB = 0;
|
|
11772
|
+
for (let i2 = 0; i2 <= runs; i2++) {
|
|
11773
|
+
const toA = i2 < runs ? as.starts[i2] : a.length;
|
|
11774
|
+
const toB = i2 < runs ? bs.starts[i2] : b.length;
|
|
11775
|
+
if (toA - fromA !== toB - fromB || !sameText(a, fromA, b, fromB, toA - fromA)) return false;
|
|
11776
|
+
fromA = as.ends[i2] ?? 0;
|
|
11777
|
+
fromB = bs.ends[i2] ?? 0;
|
|
11778
|
+
}
|
|
11779
|
+
return true;
|
|
11780
|
+
}
|
|
11781
|
+
function makeTemplate(formula, shape2) {
|
|
11782
|
+
let tokens;
|
|
11783
|
+
let ast;
|
|
11784
|
+
try {
|
|
11785
|
+
tokens = tokenize(formula);
|
|
11786
|
+
ast = parseTokens(tokens);
|
|
11787
|
+
} catch (e) {
|
|
11788
|
+
if (e instanceof RangeError) return new FormulaError(e.message, -1, "#VALUE!");
|
|
11789
|
+
if (e instanceof FormulaError) return e;
|
|
11790
|
+
throw e;
|
|
11791
|
+
}
|
|
11792
|
+
const { starts } = shape2;
|
|
11793
|
+
const slotted = starts.map(() => false);
|
|
11794
|
+
const refs = /* @__PURE__ */ new Map();
|
|
11795
|
+
let run = 0;
|
|
11796
|
+
for (const token of tokens) {
|
|
11797
|
+
const end = token.start + token.text.length;
|
|
11798
|
+
const first2 = run;
|
|
11799
|
+
while (run < starts.length && starts[run] < end) run++;
|
|
11800
|
+
const ref = token.kind === "ref" ? token.ref : void 0;
|
|
11801
|
+
if (!ref || ref.kind === "cols") continue;
|
|
11802
|
+
const count2 = ref.kind === "cell" ? 1 : 2;
|
|
11803
|
+
if (run - first2 < count2) continue;
|
|
11804
|
+
const at = run - count2;
|
|
11805
|
+
const indexes2 = count2 === 1 ? [at] : [at, at + 1];
|
|
11806
|
+
if (indexes2.some((i2) => formula.charCodeAt(starts[i2]) === 48)) continue;
|
|
11807
|
+
for (const i2 of indexes2) slotted[i2] = true;
|
|
11808
|
+
refs.set(ref, count2 === 1 ? { start: at } : { start: at, end: at + 1 });
|
|
11809
|
+
}
|
|
11810
|
+
return { formula, shape: shape2, ast, slotted, refs };
|
|
11811
|
+
}
|
|
11812
|
+
function rowsFor(t, formula, shape2) {
|
|
11813
|
+
if (!sameShape(t.formula, t.shape, formula, shape2)) return void 0;
|
|
11814
|
+
const rows2 = [];
|
|
11815
|
+
for (let i2 = 0; i2 < shape2.starts.length; i2++) {
|
|
11816
|
+
const start = shape2.starts[i2];
|
|
11817
|
+
const length = shape2.ends[i2] - start;
|
|
11818
|
+
if (!t.slotted[i2]) {
|
|
11819
|
+
const own = t.shape.starts[i2];
|
|
11820
|
+
if (t.shape.ends[i2] - own !== length) return void 0;
|
|
11821
|
+
if (!sameText(t.formula, own, formula, start, length)) return void 0;
|
|
11822
|
+
rows2.push(-1);
|
|
11823
|
+
continue;
|
|
11538
11824
|
}
|
|
11539
|
-
|
|
11540
|
-
|
|
11541
|
-
|
|
11542
|
-
|
|
11543
|
-
|
|
11544
|
-
|
|
11825
|
+
if (length > 7 || formula.charCodeAt(start) === 48) return void 0;
|
|
11826
|
+
let row2 = 0;
|
|
11827
|
+
for (let k = start; k < start + length; k++) row2 = row2 * 10 + formula.charCodeAt(k) - 48;
|
|
11828
|
+
if (row2 < 1 || row2 > MAX_ROW + 1) return void 0;
|
|
11829
|
+
rows2.push(row2 - 1);
|
|
11830
|
+
}
|
|
11831
|
+
return rows2;
|
|
11832
|
+
}
|
|
11833
|
+
function shiftSpec(spec2, slots, rows2) {
|
|
11834
|
+
const startRow = rows2[slots.start];
|
|
11835
|
+
const endRow = slots.end === void 0 ? startRow : rows2[slots.end];
|
|
11836
|
+
if (startRow === spec2.start.row && endRow === spec2.end.row) return spec2;
|
|
11837
|
+
const { start: from, end: to } = spec2;
|
|
11838
|
+
const start = { row: startRow, col: from.col, rowAbs: from.rowAbs, colAbs: from.colAbs };
|
|
11839
|
+
if (slots.end === void 0) return { kind: spec2.kind, start, end: start };
|
|
11840
|
+
const end = { row: endRow, col: to.col, rowAbs: to.rowAbs, colAbs: to.colAbs };
|
|
11841
|
+
return { kind: spec2.kind, start, end };
|
|
11842
|
+
}
|
|
11843
|
+
function copyTree(node, t, rows2) {
|
|
11844
|
+
switch (node.type) {
|
|
11845
|
+
case "ref": {
|
|
11846
|
+
const slots = node.ref ? t.refs.get(node.ref) : void 0;
|
|
11847
|
+
if (!slots || !node.ref) return node;
|
|
11848
|
+
const ref = shiftSpec(node.ref, slots, rows2);
|
|
11849
|
+
if (ref === node.ref) return node;
|
|
11850
|
+
const copy2 = { type: "ref" };
|
|
11851
|
+
if (node.prefix) copy2.prefix = node.prefix;
|
|
11852
|
+
copy2.ref = ref;
|
|
11853
|
+
if (node.spill) copy2.spill = true;
|
|
11854
|
+
return copy2;
|
|
11545
11855
|
}
|
|
11546
|
-
|
|
11547
|
-
|
|
11548
|
-
|
|
11549
|
-
|
|
11550
|
-
|
|
11551
|
-
return;
|
|
11856
|
+
case "unary":
|
|
11857
|
+
case "percent": {
|
|
11858
|
+
const operand4 = copyTree(node.operand, t, rows2);
|
|
11859
|
+
if (operand4 === node.operand) return node;
|
|
11860
|
+
return node.type === "unary" ? { type: "unary", op: node.op, operand: operand4 } : { type: "percent", operand: operand4 };
|
|
11552
11861
|
}
|
|
11553
|
-
|
|
11554
|
-
|
|
11555
|
-
|
|
11556
|
-
if (
|
|
11557
|
-
|
|
11862
|
+
case "binary": {
|
|
11863
|
+
const left2 = copyTree(node.left, t, rows2);
|
|
11864
|
+
const right2 = copyTree(node.right, t, rows2);
|
|
11865
|
+
if (left2 === node.left && right2 === node.right) return node;
|
|
11866
|
+
return { type: "binary", op: node.op, left: left2, right: right2 };
|
|
11867
|
+
}
|
|
11868
|
+
case "call": {
|
|
11869
|
+
const args = copyAll(node.args, t, rows2);
|
|
11870
|
+
if (args === node.args) return node;
|
|
11871
|
+
return { type: "call", name: node.name, rawName: node.rawName, args };
|
|
11872
|
+
}
|
|
11873
|
+
case "invoke": {
|
|
11874
|
+
const callee = copyTree(node.callee, t, rows2);
|
|
11875
|
+
const args = copyAll(node.args, t, rows2);
|
|
11876
|
+
if (callee === node.callee && args === node.args) return node;
|
|
11877
|
+
return { type: "invoke", callee, args };
|
|
11558
11878
|
}
|
|
11879
|
+
default:
|
|
11880
|
+
return node;
|
|
11559
11881
|
}
|
|
11560
|
-
|
|
11561
|
-
|
|
11562
|
-
|
|
11563
|
-
|
|
11564
|
-
|
|
11882
|
+
}
|
|
11883
|
+
function copyAll(nodes, t, rows2) {
|
|
11884
|
+
let out;
|
|
11885
|
+
for (let i2 = 0; i2 < nodes.length; i2++) {
|
|
11886
|
+
const node = nodes[i2];
|
|
11887
|
+
const copy2 = copyTree(node, t, rows2);
|
|
11888
|
+
if (copy2 !== node && !out) out = nodes.slice(0, i2);
|
|
11889
|
+
out?.push(copy2);
|
|
11890
|
+
}
|
|
11891
|
+
return out ?? nodes;
|
|
11892
|
+
}
|
|
11893
|
+
function fromTemplate(t, formula, shape2) {
|
|
11894
|
+
const rows2 = rowsFor(t, formula, shape2);
|
|
11895
|
+
return rows2 ? copyTree(t.ast, t, rows2) : void 0;
|
|
11896
|
+
}
|
|
11897
|
+
|
|
11898
|
+
// xlsx/formula/parse-cache.ts
|
|
11899
|
+
var MAX_TEMPLATE_LENGTH = 2048;
|
|
11900
|
+
var MAX_ENTRIES = 1e5;
|
|
11901
|
+
var MAX_TEMPLATES = 1e4;
|
|
11902
|
+
var NO_RUNS = { hash: 0, starts: [], ends: [] };
|
|
11903
|
+
var treeOf = (made) => "ast" in made ? made.ast : made;
|
|
11904
|
+
var ParseCache = class {
|
|
11905
|
+
byText = /* @__PURE__ */ new Map();
|
|
11906
|
+
templates = /* @__PURE__ */ new Map();
|
|
11907
|
+
parse(formula) {
|
|
11908
|
+
let ast = this.byText.get(formula);
|
|
11909
|
+
if (ast) return ast;
|
|
11910
|
+
ast = this.parseNew(formula);
|
|
11911
|
+
if (this.byText.size > MAX_ENTRIES) this.byText.clear();
|
|
11912
|
+
this.byText.set(formula, ast);
|
|
11913
|
+
return ast;
|
|
11565
11914
|
}
|
|
11566
|
-
|
|
11567
|
-
|
|
11568
|
-
const
|
|
11569
|
-
|
|
11570
|
-
|
|
11571
|
-
|
|
11572
|
-
|
|
11573
|
-
|
|
11574
|
-
|
|
11575
|
-
|
|
11576
|
-
if (size <= 4096) {
|
|
11577
|
-
for (let r = start.row; r <= end.row; r++) {
|
|
11578
|
-
for (let c = start.col; c <= end.col; c++) {
|
|
11579
|
-
const list = cells.get(cellKey(r, c));
|
|
11580
|
-
if (list) for (const node of list) out.add(node);
|
|
11581
|
-
}
|
|
11582
|
-
}
|
|
11583
|
-
} else {
|
|
11584
|
-
for (const [key, list] of cells) {
|
|
11585
|
-
const { row: row2, col } = keyToAddress(key);
|
|
11586
|
-
if (row2 >= start.row && row2 <= end.row && col >= start.col && col <= end.col)
|
|
11587
|
-
for (const node of list) out.add(node);
|
|
11588
|
-
}
|
|
11589
|
-
}
|
|
11590
|
-
}
|
|
11591
|
-
const columns = (map, visit2) => {
|
|
11592
|
-
if (!map) return;
|
|
11593
|
-
if (end.col - start.col + 1 <= map.size) {
|
|
11594
|
-
for (let c = start.col; c <= end.col; c++) if (map.has(c)) visit2(c);
|
|
11595
|
-
} else for (const c of map.keys()) if (c >= start.col && c <= end.col) visit2(c);
|
|
11596
|
-
};
|
|
11597
|
-
const chunked = this.chunked.get(sheet);
|
|
11598
|
-
const first2 = start.row >> CHUNK_SHIFT;
|
|
11599
|
-
const last = end.row >> CHUNK_SHIFT;
|
|
11600
|
-
columns(chunked, (c) => {
|
|
11601
|
-
const chunks = chunked?.get(c);
|
|
11602
|
-
if (last - first2 + 1 <= chunks.size) {
|
|
11603
|
-
for (let k = first2; k <= last; k++) check3(chunks.get(k));
|
|
11604
|
-
} else for (const [k, list] of chunks) if (k >= first2 && k <= last) check3(list);
|
|
11605
|
-
});
|
|
11606
|
-
const tall = this.tall.get(sheet);
|
|
11607
|
-
columns(tall, (c) => check3(tall?.get(c)));
|
|
11608
|
-
check3(this.wide.get(sheet));
|
|
11609
|
-
}
|
|
11610
|
-
};
|
|
11611
|
-
|
|
11612
|
-
// xlsx/formula/graph-index.ts
|
|
11613
|
-
var ColumnIndex = class {
|
|
11614
|
-
sheets = /* @__PURE__ */ new Map();
|
|
11615
|
-
constructor(nodes) {
|
|
11616
|
-
for (const node of nodes) {
|
|
11617
|
-
let cols = this.sheets.get(node.sheet);
|
|
11618
|
-
if (!cols) this.sheets.set(node.sheet, cols = /* @__PURE__ */ new Map());
|
|
11619
|
-
let list = cols.get(node.col);
|
|
11620
|
-
if (!list) cols.set(node.col, list = []);
|
|
11621
|
-
list.push(node);
|
|
11622
|
-
}
|
|
11623
|
-
for (const cols of this.sheets.values())
|
|
11624
|
-
for (const list of cols.values()) list.sort((a, b) => a.row - b.row);
|
|
11625
|
-
}
|
|
11626
|
-
nodesIn(area, out) {
|
|
11627
|
-
const cols = this.sheets.get(area.sheet);
|
|
11628
|
-
if (!cols) return;
|
|
11629
|
-
const { start, end } = area.range;
|
|
11630
|
-
const width = end.col - start.col + 1;
|
|
11631
|
-
const scan2 = (list) => {
|
|
11632
|
-
let lo = 0;
|
|
11633
|
-
let hi = list.length;
|
|
11634
|
-
while (lo < hi) {
|
|
11635
|
-
const mid = lo + hi >> 1;
|
|
11636
|
-
if (list[mid].row < start.row) lo = mid + 1;
|
|
11637
|
-
else hi = mid;
|
|
11638
|
-
}
|
|
11639
|
-
for (let i2 = lo; i2 < list.length; i2++) {
|
|
11640
|
-
const node = list[i2];
|
|
11641
|
-
if (node.row > end.row) break;
|
|
11642
|
-
out.push(node);
|
|
11643
|
-
}
|
|
11644
|
-
};
|
|
11645
|
-
if (width <= cols.size) {
|
|
11646
|
-
for (let c = start.col; c <= end.col; c++) {
|
|
11647
|
-
const list = cols.get(c);
|
|
11648
|
-
if (list) scan2(list);
|
|
11649
|
-
}
|
|
11650
|
-
} else {
|
|
11651
|
-
for (const [c, list] of cols) if (c >= start.col && c <= end.col) scan2(list);
|
|
11652
|
-
}
|
|
11653
|
-
}
|
|
11654
|
-
};
|
|
11655
|
-
var ReverseIndex = class extends AreaIndex {
|
|
11656
|
-
constructor(nodes) {
|
|
11657
|
-
super();
|
|
11658
|
-
for (const node of nodes) {
|
|
11659
|
-
for (const dep of node.deps) this.add(dep, node);
|
|
11660
|
-
for (const dep of node.dynamicDeps) this.add(dep, node);
|
|
11915
|
+
parseNew(formula) {
|
|
11916
|
+
if (formula.length > MAX_TEMPLATE_LENGTH) return treeOf(makeTemplate(formula, NO_RUNS));
|
|
11917
|
+
const shape2 = formulaShape(formula);
|
|
11918
|
+
const template = this.templates.get(shape2.hash);
|
|
11919
|
+
const reused = template && fromTemplate(template, formula, shape2);
|
|
11920
|
+
if (reused) return reused;
|
|
11921
|
+
const made = makeTemplate(formula, shape2);
|
|
11922
|
+
if (!template && "ast" in made) {
|
|
11923
|
+
if (this.templates.size > MAX_TEMPLATES) this.templates.clear();
|
|
11924
|
+
this.templates.set(shape2.hash, made);
|
|
11661
11925
|
}
|
|
11926
|
+
return treeOf(made);
|
|
11662
11927
|
}
|
|
11663
11928
|
};
|
|
11664
11929
|
|
|
@@ -11798,7 +12063,7 @@ var EngineHost = class {
|
|
|
11798
12063
|
options;
|
|
11799
12064
|
nodes = /* @__PURE__ */ new Map();
|
|
11800
12065
|
footprints = /* @__PURE__ */ new Set();
|
|
11801
|
-
|
|
12066
|
+
parsed = new ParseCache();
|
|
11802
12067
|
boundsCache = /* @__PURE__ */ new Map();
|
|
11803
12068
|
inProgress = /* @__PURE__ */ new Set();
|
|
11804
12069
|
cycles = /* @__PURE__ */ new Set();
|
|
@@ -11822,6 +12087,8 @@ var EngineHost = class {
|
|
|
11822
12087
|
evaluations = 0;
|
|
11823
12088
|
built = false;
|
|
11824
12089
|
needsFull = false;
|
|
12090
|
+
/** No recalculation has run since the workbook was opened: stored values may stand. */
|
|
12091
|
+
fresh = true;
|
|
11825
12092
|
// ---- EvalHost ----
|
|
11826
12093
|
readCell(sheet, row2, col) {
|
|
11827
12094
|
const cell = this.workbook.sheets[sheet]?.rows.get(row2)?.get(col);
|
|
@@ -11910,19 +12177,7 @@ var EngineHost = class {
|
|
|
11910
12177
|
return this.workbook.sheets[sheet]?.rows.get(row2)?.get(col)?.formula;
|
|
11911
12178
|
}
|
|
11912
12179
|
parse(formula) {
|
|
11913
|
-
|
|
11914
|
-
if (!ast) {
|
|
11915
|
-
try {
|
|
11916
|
-
ast = parseFormula(formula);
|
|
11917
|
-
} catch (e) {
|
|
11918
|
-
if (e instanceof RangeError) ast = new FormulaError(e.message, -1, "#VALUE!");
|
|
11919
|
-
else if (!(e instanceof FormulaError)) throw e;
|
|
11920
|
-
else ast = e;
|
|
11921
|
-
}
|
|
11922
|
-
if (this.astCache.size > 1e5) this.astCache.clear();
|
|
11923
|
-
this.astCache.set(formula, ast);
|
|
11924
|
-
}
|
|
11925
|
-
return ast;
|
|
12180
|
+
return this.parsed.parse(formula);
|
|
11926
12181
|
}
|
|
11927
12182
|
now() {
|
|
11928
12183
|
return this.options.now ? this.options.now() : /* @__PURE__ */ new Date();
|
|
@@ -11931,20 +12186,6 @@ var EngineHost = class {
|
|
|
11931
12186
|
return this.options.random ? this.options.random() : Math.random();
|
|
11932
12187
|
}
|
|
11933
12188
|
// ---- graph ----
|
|
11934
|
-
build() {
|
|
11935
|
-
this.nodes.clear();
|
|
11936
|
-
this.footprints.clear();
|
|
11937
|
-
this.footprintIndex = void 0;
|
|
11938
|
-
this.workbook.sheets.forEach((sheet, s) => {
|
|
11939
|
-
for (const [row2, cells] of sheet.rows) {
|
|
11940
|
-
for (const [col, cell] of cells) {
|
|
11941
|
-
if (cell.formula) this.createNode(s, row2, col, cell, true);
|
|
11942
|
-
}
|
|
11943
|
-
}
|
|
11944
|
-
});
|
|
11945
|
-
this.built = true;
|
|
11946
|
-
this.graphChanged();
|
|
11947
|
-
}
|
|
11948
12189
|
createNode(sheet, row2, col, cell, initial) {
|
|
11949
12190
|
const formula = cell.formula ?? "";
|
|
11950
12191
|
const parsed = this.parse(formula);
|
|
@@ -11973,6 +12214,14 @@ var EngineHost = class {
|
|
|
11973
12214
|
map.set(cellKey(row2, col), node);
|
|
11974
12215
|
return node;
|
|
11975
12216
|
}
|
|
12217
|
+
/** Parses a node's text again after a structural edit rewrote it (see `FormulaNode.stale`). */
|
|
12218
|
+
refreshAst(node) {
|
|
12219
|
+
const parsed = this.parse(node.formula);
|
|
12220
|
+
delete node.stale;
|
|
12221
|
+
delete node.parseError;
|
|
12222
|
+
node.ast = parsed instanceof FormulaError ? void 0 : parsed;
|
|
12223
|
+
if (parsed instanceof FormulaError && parsed.code) node.parseError = err(parsed.code);
|
|
12224
|
+
}
|
|
11976
12225
|
removeNode(node, changed) {
|
|
11977
12226
|
const sheet = this.workbook.sheets[node.sheet];
|
|
11978
12227
|
if (node.spill && sheet) {
|
|
@@ -12403,6 +12652,7 @@ var EngineCore = class extends EngineHost {
|
|
|
12403
12652
|
return { host: this, sheet, row: row2, col, scope: void 0, depth: 0, root, legacy };
|
|
12404
12653
|
}
|
|
12405
12654
|
evaluateFormula(node) {
|
|
12655
|
+
if (node.stale) this.refreshAst(node);
|
|
12406
12656
|
if (!node.ast) return node.parseError ?? ERR.NAME;
|
|
12407
12657
|
const ast = node.ast;
|
|
12408
12658
|
const frame = this.frameFor(node.sheet, node.row, node.col, ast, node.legacy);
|
|
@@ -12420,20 +12670,363 @@ var EngineCore = class extends EngineHost {
|
|
|
12420
12670
|
}
|
|
12421
12671
|
};
|
|
12422
12672
|
|
|
12673
|
+
// xlsx/formula/shift-graph.ts
|
|
12674
|
+
var POSITIONAL = /* @__PURE__ */ new Set(["ROW", "COLUMN"]);
|
|
12675
|
+
var DESCRIPTIVE = /* @__PURE__ */ new Set(["FORMULATEXT", "CELL", "SHEET"]);
|
|
12676
|
+
var traitsCache = /* @__PURE__ */ new WeakMap();
|
|
12677
|
+
function astTraits(ast) {
|
|
12678
|
+
const cached = traitsCache.get(ast);
|
|
12679
|
+
if (cached) return cached;
|
|
12680
|
+
const sheets = /* @__PURE__ */ new Set();
|
|
12681
|
+
const traits = { complex: false, opaque: false, positional: false, descriptive: false, sheets };
|
|
12682
|
+
const stack2 = [ast];
|
|
12683
|
+
while (stack2.length) {
|
|
12684
|
+
const node = stack2.pop();
|
|
12685
|
+
switch (node.type) {
|
|
12686
|
+
case "ref":
|
|
12687
|
+
if (node.prefix) {
|
|
12688
|
+
sheets.add(node.prefix.sheet.toLowerCase());
|
|
12689
|
+
if (node.prefix.sheet2 !== void 0) {
|
|
12690
|
+
sheets.add(node.prefix.sheet2.toLowerCase());
|
|
12691
|
+
traits.complex = true;
|
|
12692
|
+
}
|
|
12693
|
+
}
|
|
12694
|
+
break;
|
|
12695
|
+
case "name":
|
|
12696
|
+
if (node.prefix) sheets.add(node.prefix.sheet.toLowerCase());
|
|
12697
|
+
traits.complex = true;
|
|
12698
|
+
break;
|
|
12699
|
+
case "structured":
|
|
12700
|
+
traits.complex = true;
|
|
12701
|
+
break;
|
|
12702
|
+
case "unary":
|
|
12703
|
+
case "percent":
|
|
12704
|
+
stack2.push(node.operand);
|
|
12705
|
+
break;
|
|
12706
|
+
case "binary":
|
|
12707
|
+
stack2.push(node.left, node.right);
|
|
12708
|
+
break;
|
|
12709
|
+
case "call":
|
|
12710
|
+
if (POSITIONAL.has(node.name)) traits.positional = true;
|
|
12711
|
+
if (DESCRIPTIVE.has(node.name)) traits.descriptive = true;
|
|
12712
|
+
if (!getFunction(node.name)) traits.complex = traits.opaque = true;
|
|
12713
|
+
stack2.push(...node.args);
|
|
12714
|
+
break;
|
|
12715
|
+
case "invoke":
|
|
12716
|
+
stack2.push(node.callee, ...node.args);
|
|
12717
|
+
break;
|
|
12718
|
+
}
|
|
12719
|
+
}
|
|
12720
|
+
traitsCache.set(ast, traits);
|
|
12721
|
+
return traits;
|
|
12722
|
+
}
|
|
12723
|
+
function intervalDelta(a, b, shift2) {
|
|
12724
|
+
const { at, count: count2 } = shift2;
|
|
12725
|
+
if (count2 > 0) {
|
|
12726
|
+
if (b < at) return 0;
|
|
12727
|
+
if (a < at) return void 0;
|
|
12728
|
+
return b + count2 > (shift2.axis === "row" ? MAX_ROW : MAX_COL) ? void 0 : count2;
|
|
12729
|
+
}
|
|
12730
|
+
const last = at - count2 - 1;
|
|
12731
|
+
if (b < at) return 0;
|
|
12732
|
+
if (a > last) return count2;
|
|
12733
|
+
return void 0;
|
|
12734
|
+
}
|
|
12735
|
+
function areaDelta(area, sheet, shift2) {
|
|
12736
|
+
if (area.sheet !== sheet) return 0;
|
|
12737
|
+
const { start, end } = area.range;
|
|
12738
|
+
return shift2.axis === "row" ? intervalDelta(start.row, end.row, shift2) : intervalDelta(start.col, end.col, shift2);
|
|
12739
|
+
}
|
|
12740
|
+
function movedRange(range2, axis, delta) {
|
|
12741
|
+
if (delta === 0) return range2;
|
|
12742
|
+
return axis === "row" ? {
|
|
12743
|
+
start: { row: range2.start.row + delta, col: range2.start.col },
|
|
12744
|
+
end: { row: range2.end.row + delta, col: range2.end.col }
|
|
12745
|
+
} : {
|
|
12746
|
+
start: { row: range2.start.row, col: range2.start.col + delta },
|
|
12747
|
+
end: { row: range2.end.row, col: range2.end.col + delta }
|
|
12748
|
+
};
|
|
12749
|
+
}
|
|
12750
|
+
function reachesEdit(areas, sheet, shift2) {
|
|
12751
|
+
for (const area of areas) {
|
|
12752
|
+
if (area.sheet !== sheet) continue;
|
|
12753
|
+
if ((shift2.axis === "row" ? area.range.end.row : area.range.end.col) >= shift2.at) return true;
|
|
12754
|
+
}
|
|
12755
|
+
return false;
|
|
12756
|
+
}
|
|
12757
|
+
function intersectionMoves(area, delta, pos, nodeDelta, axis) {
|
|
12758
|
+
if (delta === nodeDelta) return false;
|
|
12759
|
+
const { start, end } = area.range;
|
|
12760
|
+
const a = axis === "row" ? start.row : start.col;
|
|
12761
|
+
const b = axis === "row" ? end.row : end.col;
|
|
12762
|
+
if (a === b) return false;
|
|
12763
|
+
return pos >= a && pos <= b || pos + nodeDelta >= a + delta && pos + nodeDelta <= b + delta;
|
|
12764
|
+
}
|
|
12765
|
+
|
|
12766
|
+
// xlsx/formula/engine-structure.ts
|
|
12767
|
+
var sameAreas = (a, b) => a.length === b.length && a.every((x, i2) => {
|
|
12768
|
+
const y = b[i2];
|
|
12769
|
+
return x.sheet === y.sheet && sameRange(x.range, y.range);
|
|
12770
|
+
});
|
|
12771
|
+
var EngineStructure = class extends EngineCore {
|
|
12772
|
+
/** Formulas a structural edit left to recalculate (with their dependents) on the next pass. */
|
|
12773
|
+
structuralSeeds = /* @__PURE__ */ new Set();
|
|
12774
|
+
/** Whether the graph describes the workbook as it was before the edit just reported. */
|
|
12775
|
+
graphReady() {
|
|
12776
|
+
return this.built && !this.needsFull;
|
|
12777
|
+
}
|
|
12778
|
+
/** Parses a node's current text again and recomputes its precedents. */
|
|
12779
|
+
reanalyze(node) {
|
|
12780
|
+
const parsed = this.parse(node.formula);
|
|
12781
|
+
delete node.stale;
|
|
12782
|
+
delete node.parseError;
|
|
12783
|
+
if (parsed instanceof FormulaError) {
|
|
12784
|
+
node.ast = void 0;
|
|
12785
|
+
if (parsed.code) node.parseError = err(parsed.code);
|
|
12786
|
+
node.deps = [];
|
|
12787
|
+
node.dynamicDeps = [];
|
|
12788
|
+
return;
|
|
12789
|
+
}
|
|
12790
|
+
node.ast = parsed;
|
|
12791
|
+
const found = analyze(parsed, this, node.sheet, node.row, node.col);
|
|
12792
|
+
node.deps = found.deps;
|
|
12793
|
+
node.dynamicDeps = found.dynamicDeps;
|
|
12794
|
+
node.volatile = found.volatile;
|
|
12795
|
+
node.unsupported = found.unsupported;
|
|
12796
|
+
}
|
|
12797
|
+
/**
|
|
12798
|
+
* Moves the graph for rows or columns inserted or deleted on `sheet`, after the workbook was
|
|
12799
|
+
* changed (cells moved, formulas rewritten). Spills on the sheet, array formulas the edit cuts
|
|
12800
|
+
* and anything unexpected fall back to a rebuild on the next recalculation.
|
|
12801
|
+
*/
|
|
12802
|
+
shiftCells(sheet, shift2) {
|
|
12803
|
+
if (!this.graphReady() || !this.shiftable(sheet, shift2)) {
|
|
12804
|
+
this.invalidate();
|
|
12805
|
+
return;
|
|
12806
|
+
}
|
|
12807
|
+
const ws = this.workbook.sheets[sheet];
|
|
12808
|
+
const own = this.nodes.get(sheet);
|
|
12809
|
+
if (!ws) return;
|
|
12810
|
+
const moved = /* @__PURE__ */ new Map();
|
|
12811
|
+
if (own) {
|
|
12812
|
+
const next = /* @__PURE__ */ new Map();
|
|
12813
|
+
for (const node of own.values()) {
|
|
12814
|
+
const pos = shift2.axis === "row" ? node.row : node.col;
|
|
12815
|
+
const delta = intervalDelta(pos, pos, shift2);
|
|
12816
|
+
if (delta === void 0) {
|
|
12817
|
+
this.dropNode(node);
|
|
12818
|
+
continue;
|
|
12819
|
+
}
|
|
12820
|
+
if (delta !== 0) {
|
|
12821
|
+
moved.set(node, delta);
|
|
12822
|
+
if (shift2.axis === "row") node.row += delta;
|
|
12823
|
+
else node.col += delta;
|
|
12824
|
+
}
|
|
12825
|
+
next.set(cellKey(node.row, node.col), node);
|
|
12826
|
+
}
|
|
12827
|
+
this.nodes.set(sheet, next);
|
|
12828
|
+
}
|
|
12829
|
+
for (const map of this.nodes.values())
|
|
12830
|
+
for (const node of map.values()) {
|
|
12831
|
+
if (!this.shiftNode(node, sheet, shift2, moved.get(node) ?? 0)) {
|
|
12832
|
+
this.invalidate();
|
|
12833
|
+
return;
|
|
12834
|
+
}
|
|
12835
|
+
}
|
|
12836
|
+
this.boundsCache.clear();
|
|
12837
|
+
this.graphChanged();
|
|
12838
|
+
}
|
|
12839
|
+
/** No spill or stale spilled value on the sheet, and no array formula the edit cuts. */
|
|
12840
|
+
shiftable(sheet, shift2) {
|
|
12841
|
+
for (const node of this.footprints) {
|
|
12842
|
+
if (node.sheet !== sheet) continue;
|
|
12843
|
+
if (node.spill || node.blockedSpill) return false;
|
|
12844
|
+
if (node.arrayRange && areaDelta({ sheet, range: node.arrayRange }, sheet, shift2) === void 0)
|
|
12845
|
+
return false;
|
|
12846
|
+
}
|
|
12847
|
+
const ws = this.workbook.sheets[sheet];
|
|
12848
|
+
let spilled = false;
|
|
12849
|
+
ws?.rows.forEach((cells) => {
|
|
12850
|
+
if (!spilled) cells.forEach((cell) => spilled ||= isSpilledCell(cell));
|
|
12851
|
+
});
|
|
12852
|
+
return !spilled;
|
|
12853
|
+
}
|
|
12854
|
+
dropNode(node) {
|
|
12855
|
+
this.structuralSeeds.delete(node);
|
|
12856
|
+
this.cycles.delete(node);
|
|
12857
|
+
this.footprints.delete(node);
|
|
12858
|
+
}
|
|
12859
|
+
/** Updates one formula for the edit; false when the graph cannot follow it. */
|
|
12860
|
+
shiftNode(node, sheet, shift2, nodeDelta) {
|
|
12861
|
+
const cell = this.workbook.sheets[node.sheet]?.rows.get(node.row)?.get(node.col);
|
|
12862
|
+
if (cell?.formula === void 0) return false;
|
|
12863
|
+
if (node.arrayRange) {
|
|
12864
|
+
const delta = areaDelta({ sheet: node.sheet, range: node.arrayRange }, sheet, shift2);
|
|
12865
|
+
if (delta === void 0) return false;
|
|
12866
|
+
node.arrayRange = movedRange(node.arrayRange, shift2.axis, delta);
|
|
12867
|
+
if (!cell.arrayRange || !sameRange(node.arrayRange, normalizeRange(cell.arrayRange)))
|
|
12868
|
+
return false;
|
|
12869
|
+
}
|
|
12870
|
+
const changed = cell.formula !== node.formula;
|
|
12871
|
+
const traits = node.ast && astTraits(node.ast);
|
|
12872
|
+
const reached = reachesEdit(node.deps, sheet, shift2) || reachesEdit(node.dynamicDeps, sheet, shift2);
|
|
12873
|
+
if (!changed && !reached && nodeDelta === 0 && !traits?.descriptive && !traits?.opaque)
|
|
12874
|
+
return true;
|
|
12875
|
+
if (traits?.complex) {
|
|
12876
|
+
node.formula = cell.formula;
|
|
12877
|
+
this.reanalyze(node);
|
|
12878
|
+
this.structuralSeeds.add(node);
|
|
12879
|
+
return true;
|
|
12880
|
+
}
|
|
12881
|
+
const pos = shift2.axis === "row" ? node.row - nodeDelta : node.col - nodeDelta;
|
|
12882
|
+
const moves = { seed: !!traits?.descriptive, moved: false, cut: false };
|
|
12883
|
+
const deps = this.moveAreas(node.deps, sheet, shift2, pos, nodeDelta, moves);
|
|
12884
|
+
const dynamicDeps = this.moveAreas(node.dynamicDeps, sheet, shift2, pos, nodeDelta, moves);
|
|
12885
|
+
const { cut, moved: anyMoved } = moves;
|
|
12886
|
+
let seed = moves.seed;
|
|
12887
|
+
if (cut || changed !== anyMoved) {
|
|
12888
|
+
node.formula = cell.formula;
|
|
12889
|
+
this.reanalyze(node);
|
|
12890
|
+
this.structuralSeeds.add(node);
|
|
12891
|
+
return true;
|
|
12892
|
+
}
|
|
12893
|
+
if (traits?.positional && (anyMoved || nodeDelta !== 0)) seed = true;
|
|
12894
|
+
node.deps = deps;
|
|
12895
|
+
node.dynamicDeps = dynamicDeps;
|
|
12896
|
+
if (changed) {
|
|
12897
|
+
node.formula = cell.formula;
|
|
12898
|
+
node.stale = true;
|
|
12899
|
+
}
|
|
12900
|
+
if (seed) this.structuralSeeds.add(node);
|
|
12901
|
+
return true;
|
|
12902
|
+
}
|
|
12903
|
+
/**
|
|
12904
|
+
* Areas moved for the edit (the same list when none moves). Records in `moves` whether one
|
|
12905
|
+
* moved, one was cut (deleted, widened, pushed off the grid) and whether implicit intersection
|
|
12906
|
+
* with one can now pick another cell.
|
|
12907
|
+
*/
|
|
12908
|
+
moveAreas(list, sheet, shift2, pos, nodeDelta, moves) {
|
|
12909
|
+
let out;
|
|
12910
|
+
for (let i2 = 0; i2 < list.length; i2++) {
|
|
12911
|
+
const area = list[i2];
|
|
12912
|
+
const delta = areaDelta(area, sheet, shift2);
|
|
12913
|
+
if (delta === void 0) {
|
|
12914
|
+
moves.cut = true;
|
|
12915
|
+
continue;
|
|
12916
|
+
}
|
|
12917
|
+
if (intersectionMoves(area, delta, pos, nodeDelta, shift2.axis)) moves.seed = true;
|
|
12918
|
+
if (delta === 0) continue;
|
|
12919
|
+
moves.moved = true;
|
|
12920
|
+
out ??= list.slice();
|
|
12921
|
+
out[i2] = { sheet: area.sheet, range: movedRange(area.range, shift2.axis, delta) };
|
|
12922
|
+
}
|
|
12923
|
+
return out ?? list;
|
|
12924
|
+
}
|
|
12925
|
+
/**
|
|
12926
|
+
* Follows a sheet rename (`from` to `to`, formulas already rewritten): precedents are kept by
|
|
12927
|
+
* sheet index, so only rewritten formulas need their text parsed again, and only formulas that
|
|
12928
|
+
* name the new sheet without having been rewritten (previously unresolved), describe sheets
|
|
12929
|
+
* (CELL, SHEET, FORMULATEXT) or read defined names whose areas changed are recalculated.
|
|
12930
|
+
*/
|
|
12931
|
+
renameSheet(from, to) {
|
|
12932
|
+
if (!this.graphReady()) {
|
|
12933
|
+
this.invalidate();
|
|
12934
|
+
return;
|
|
12935
|
+
}
|
|
12936
|
+
const target2 = to.toLowerCase();
|
|
12937
|
+
let depsChanged = false;
|
|
12938
|
+
for (const map of this.nodes.values())
|
|
12939
|
+
for (const node of map.values()) {
|
|
12940
|
+
const cell = this.workbook.sheets[node.sheet]?.rows.get(node.row)?.get(node.col);
|
|
12941
|
+
if (cell?.formula === void 0) {
|
|
12942
|
+
this.invalidate();
|
|
12943
|
+
return;
|
|
12944
|
+
}
|
|
12945
|
+
const changed = cell.formula !== node.formula;
|
|
12946
|
+
const traits = node.ast && astTraits(node.ast);
|
|
12947
|
+
node.formula = cell.formula;
|
|
12948
|
+
if (traits?.complex || !changed && traits?.sheets.has(target2)) {
|
|
12949
|
+
const deps = node.deps;
|
|
12950
|
+
const dynamicDeps = node.dynamicDeps;
|
|
12951
|
+
this.reanalyze(node);
|
|
12952
|
+
const same4 = sameAreas(deps, node.deps) && sameAreas(dynamicDeps, node.dynamicDeps);
|
|
12953
|
+
if (!same4) depsChanged = true;
|
|
12954
|
+
if (!same4 || !traits?.complex) this.structuralSeeds.add(node);
|
|
12955
|
+
} else if (changed) node.stale = true;
|
|
12956
|
+
if (traits?.descriptive || traits?.opaque) this.structuralSeeds.add(node);
|
|
12957
|
+
}
|
|
12958
|
+
if (depsChanged) this.graphChanged();
|
|
12959
|
+
}
|
|
12960
|
+
/** Takes the formulas queued by structural edits. */
|
|
12961
|
+
takeStructuralSeeds(into) {
|
|
12962
|
+
for (const node of this.structuralSeeds)
|
|
12963
|
+
if (this.nodes.get(node.sheet)?.get(cellKey(node.row, node.col)) === node) into.add(node);
|
|
12964
|
+
this.structuralSeeds.clear();
|
|
12965
|
+
}
|
|
12966
|
+
};
|
|
12967
|
+
|
|
12423
12968
|
// xlsx/formula/engine.ts
|
|
12424
|
-
var Engine = class extends
|
|
12969
|
+
var Engine = class extends EngineStructure {
|
|
12970
|
+
preparation;
|
|
12971
|
+
/** The prepared formulas the first recalculation checks (see `trustsStoredValues`). */
|
|
12972
|
+
prepared;
|
|
12973
|
+
// ---- the graph ----
|
|
12974
|
+
prepare(timeRemaining) {
|
|
12975
|
+
if (this.built || this.needsFull) return true;
|
|
12976
|
+
this.preparation ??= this.startPreparation();
|
|
12977
|
+
if (!this.preparation.run(timeRemaining)) return false;
|
|
12978
|
+
this.finishPreparation(this.preparation);
|
|
12979
|
+
return true;
|
|
12980
|
+
}
|
|
12981
|
+
discardPreparation() {
|
|
12982
|
+
if (!this.fresh || this.needsFull) return;
|
|
12983
|
+
this.preparation = void 0;
|
|
12984
|
+
this.prepared = void 0;
|
|
12985
|
+
this.structuralSeeds.clear();
|
|
12986
|
+
this.nodes.clear();
|
|
12987
|
+
this.footprints.clear();
|
|
12988
|
+
this.graphChanged();
|
|
12989
|
+
this.built = false;
|
|
12990
|
+
}
|
|
12991
|
+
/** Completes the graph, continuing a preparation that is under way. */
|
|
12992
|
+
build() {
|
|
12993
|
+
const preparation = this.preparation ?? this.startPreparation();
|
|
12994
|
+
preparation.run();
|
|
12995
|
+
this.finishPreparation(preparation);
|
|
12996
|
+
}
|
|
12997
|
+
startPreparation() {
|
|
12998
|
+
this.nodes.clear();
|
|
12999
|
+
this.footprints.clear();
|
|
13000
|
+
this.footprintIndex = void 0;
|
|
13001
|
+
this.prepared = void 0;
|
|
13002
|
+
return new GraphPreparation(
|
|
13003
|
+
this.workbook,
|
|
13004
|
+
(s, row2, col, cell) => this.createNode(s, row2, col, cell, true)
|
|
13005
|
+
);
|
|
13006
|
+
}
|
|
13007
|
+
finishPreparation(preparation) {
|
|
13008
|
+
this.preparation = void 0;
|
|
13009
|
+
this.built = true;
|
|
13010
|
+
this.graphChanged();
|
|
13011
|
+
this.reverseIndex = preparation.reverse;
|
|
13012
|
+
this.prepared = preparation.formulas;
|
|
13013
|
+
}
|
|
12425
13014
|
// ---- recalculation ----
|
|
12426
13015
|
recalculateAll() {
|
|
13016
|
+
this.fresh = false;
|
|
13017
|
+
this.prepared = void 0;
|
|
12427
13018
|
if (this.needsFull) this.releaseAllSpills();
|
|
12428
13019
|
if (!this.built || this.needsFull) this.build();
|
|
12429
13020
|
this.needsFull = false;
|
|
13021
|
+
this.structuralSeeds.clear();
|
|
12430
13022
|
this.cycles = /* @__PURE__ */ new Set();
|
|
12431
13023
|
this.run(new Set(this.allNodes()), true);
|
|
12432
13024
|
}
|
|
12433
13025
|
recalculateFrom(changes) {
|
|
12434
13026
|
const seeds = /* @__PURE__ */ new Set();
|
|
12435
|
-
if (
|
|
12436
|
-
this.
|
|
13027
|
+
if (this.fresh && !this.needsFull) {
|
|
13028
|
+
this.fresh = false;
|
|
13029
|
+
if (!this.built) this.build();
|
|
12437
13030
|
if (!this.trustsStoredValues(changes, seeds)) {
|
|
12438
13031
|
this.recalculateAll();
|
|
12439
13032
|
return;
|
|
@@ -12477,6 +13070,7 @@ var Engine = class extends EngineCore {
|
|
|
12477
13070
|
}
|
|
12478
13071
|
}
|
|
12479
13072
|
if (structural) this.graphChanged();
|
|
13073
|
+
this.takeStructuralSeeds(seeds);
|
|
12480
13074
|
const reverse = this.reverse();
|
|
12481
13075
|
for (const area of changed) reverse.dependents(area.sheet, area.range, seeds);
|
|
12482
13076
|
for (const node of this.allNodes()) if (node.volatile) seeds.add(node);
|
|
@@ -12488,13 +13082,18 @@ var Engine = class extends EngineCore {
|
|
|
12488
13082
|
* without a value into `missing`.
|
|
12489
13083
|
*/
|
|
12490
13084
|
trustsStoredValues(changes, missing) {
|
|
13085
|
+
const prepared = this.prepared;
|
|
13086
|
+
this.prepared = void 0;
|
|
13087
|
+
if (!prepared) return false;
|
|
12491
13088
|
const changed = new Set(changes.map((c) => `${c.sheet}:${cellKey(c.row, c.col)}`));
|
|
12492
|
-
|
|
12493
|
-
|
|
12494
|
-
if (
|
|
13089
|
+
const current = (node) => this.nodes.get(node.sheet)?.get(cellKey(node.row, node.col)) === node;
|
|
13090
|
+
for (const node of prepared.dynamic) {
|
|
13091
|
+
if (current(node) && !changed.has(`${node.sheet}:${cellKey(node.row, node.col)}`))
|
|
12495
13092
|
return false;
|
|
13093
|
+
}
|
|
13094
|
+
for (const node of prepared.unvalued) {
|
|
12496
13095
|
const cell = this.workbook.sheets[node.sheet]?.rows.get(node.row)?.get(node.col);
|
|
12497
|
-
if (cell && cell.value === null
|
|
13096
|
+
if (current(node) && cell && cell.value === null) missing.add(node);
|
|
12498
13097
|
}
|
|
12499
13098
|
return true;
|
|
12500
13099
|
}
|
|
@@ -12508,7 +13107,10 @@ var Engine = class extends EngineCore {
|
|
|
12508
13107
|
return !!anchor?.spill && rangeHas(anchor.spill, row2, col);
|
|
12509
13108
|
}
|
|
12510
13109
|
invalidate() {
|
|
13110
|
+
this.structuralSeeds.clear();
|
|
12511
13111
|
this.releaseAllSpills();
|
|
13112
|
+
this.preparation = void 0;
|
|
13113
|
+
this.prepared = void 0;
|
|
12512
13114
|
this.nodes.clear();
|
|
12513
13115
|
this.footprints.clear();
|
|
12514
13116
|
this.graphChanged();
|
|
@@ -12553,7 +13155,7 @@ function createCalcEngine(workbook, options = {}) {
|
|
|
12553
13155
|
return new Engine(workbook, options);
|
|
12554
13156
|
}
|
|
12555
13157
|
|
|
12556
|
-
// xlsx/formula/
|
|
13158
|
+
// xlsx/formula/ref-text.ts
|
|
12557
13159
|
function safeTokens(formula) {
|
|
12558
13160
|
try {
|
|
12559
13161
|
return tokenize(formula);
|
|
@@ -12572,50 +13174,26 @@ function formatRefSpec(spec2) {
|
|
|
12572
13174
|
if (spec2.kind === "cell") return a;
|
|
12573
13175
|
return `${a}:${cornerText(spec2.end, spec2.kind)}`;
|
|
12574
13176
|
}
|
|
12575
|
-
function
|
|
13177
|
+
function rewriteRef(token, ref) {
|
|
12576
13178
|
const prefix = token.prefix?.text ?? "";
|
|
12577
13179
|
if (!ref) return `${prefix}#REF!`;
|
|
12578
13180
|
return `${prefix}${formatRefSpec(ref)}${token.spill ? "#" : ""}`;
|
|
12579
13181
|
}
|
|
12580
13182
|
var sameSpec = (a, b) => a.kind === b.kind && a.start.row === b.start.row && a.start.col === b.start.col && a.end.row === b.end.row && a.end.col === b.end.col;
|
|
12581
|
-
|
|
12582
|
-
|
|
12583
|
-
|
|
12584
|
-
|
|
12585
|
-
|
|
12586
|
-
|
|
12587
|
-
const move = (c) => {
|
|
12588
|
-
const row2 = spec2.kind === "cols" || c.rowAbs ? c.row : c.row + dRow;
|
|
12589
|
-
const col = spec2.kind === "rows" || c.colAbs ? c.col : c.col + dCol;
|
|
12590
|
-
if (row2 < 0 || row2 > MAX_ROW || col < 0 || col > MAX_COL) return void 0;
|
|
12591
|
-
return { ...c, row: row2, col };
|
|
12592
|
-
};
|
|
12593
|
-
const start = move(spec2.start);
|
|
12594
|
-
const end = move(spec2.end);
|
|
12595
|
-
const next = start && end ? { kind: spec2.kind, start, end } : void 0;
|
|
12596
|
-
if (next && sameSpec(next, spec2)) continue;
|
|
12597
|
-
token.text = rewrite(token, next);
|
|
12598
|
-
}
|
|
12599
|
-
return joinTokens(tokens);
|
|
13183
|
+
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);
|
|
13184
|
+
function prefixText(prefix) {
|
|
13185
|
+
const sheets = prefix.sheet2 !== void 0 ? `${prefix.sheet}:${prefix.sheet2}` : prefix.sheet;
|
|
13186
|
+
const book = prefix.book !== void 0 ? `[${prefix.book}]` : "";
|
|
13187
|
+
const quote = needsQuote(prefix.sheet) || prefix.sheet2 !== void 0 && needsQuote(prefix.sheet2);
|
|
13188
|
+
return quote ? `'${(book + sheets).replace(/'/g, "''")}'!` : `${book}${sheets}!`;
|
|
12600
13189
|
}
|
|
12601
|
-
|
|
12602
|
-
|
|
12603
|
-
|
|
12604
|
-
|
|
12605
|
-
|
|
12606
|
-
|
|
12607
|
-
|
|
12608
|
-
const na2 = a >= at ? a + count2 : a;
|
|
12609
|
-
const nb2 = b >= at ? b + count2 : b;
|
|
12610
|
-
if (nb2 > max) return na2 > max ? void 0 : [na2, max];
|
|
12611
|
-
return [na2, nb2];
|
|
12612
|
-
}
|
|
12613
|
-
const n = -count2;
|
|
12614
|
-
const last = at + n - 1;
|
|
12615
|
-
if (a >= at && b <= last) return void 0;
|
|
12616
|
-
const na = a < at ? a : a <= last ? at : a - n;
|
|
12617
|
-
const nb = b < at ? b : b <= last ? at - 1 : b - n;
|
|
12618
|
-
return [na, nb];
|
|
13190
|
+
|
|
13191
|
+
// xlsx/formula/shift-formula.ts
|
|
13192
|
+
var templates = /* @__PURE__ */ new Map();
|
|
13193
|
+
var MAX_TEMPLATES2 = 2e5;
|
|
13194
|
+
function remember(text2, template) {
|
|
13195
|
+
if (templates.size >= MAX_TEMPLATES2) templates.clear();
|
|
13196
|
+
templates.set(text2, template);
|
|
12619
13197
|
}
|
|
12620
13198
|
function mergeSpacedAreas(tokens) {
|
|
12621
13199
|
const out = [];
|
|
@@ -12642,63 +13220,145 @@ function mergeSpacedAreas(tokens) {
|
|
|
12642
13220
|
}
|
|
12643
13221
|
return out;
|
|
12644
13222
|
}
|
|
12645
|
-
function
|
|
12646
|
-
|
|
13223
|
+
function templateOf(formula) {
|
|
13224
|
+
const cached = templates.get(formula);
|
|
13225
|
+
if (cached !== void 0) return cached;
|
|
12647
13226
|
const raw = safeTokens(formula);
|
|
12648
|
-
|
|
12649
|
-
|
|
12650
|
-
|
|
12651
|
-
|
|
12652
|
-
|
|
12653
|
-
|
|
12654
|
-
|
|
12655
|
-
|
|
12656
|
-
|
|
12657
|
-
|
|
12658
|
-
|
|
12659
|
-
|
|
12660
|
-
|
|
12661
|
-
|
|
12662
|
-
|
|
12663
|
-
|
|
12664
|
-
|
|
12665
|
-
|
|
12666
|
-
|
|
12667
|
-
|
|
12668
|
-
|
|
12669
|
-
|
|
12670
|
-
|
|
12671
|
-
|
|
12672
|
-
|
|
12673
|
-
|
|
12674
|
-
|
|
12675
|
-
|
|
13227
|
+
let template = null;
|
|
13228
|
+
if (raw) {
|
|
13229
|
+
template = [];
|
|
13230
|
+
let literal2 = "";
|
|
13231
|
+
for (const token of mergeSpacedAreas(raw)) {
|
|
13232
|
+
if (token.kind !== "ref" && !(token.kind === "name" && token.prefix)) {
|
|
13233
|
+
literal2 += token.text;
|
|
13234
|
+
continue;
|
|
13235
|
+
}
|
|
13236
|
+
if (literal2) template.push(literal2);
|
|
13237
|
+
literal2 = "";
|
|
13238
|
+
const part = { kind: token.kind, text: token.text };
|
|
13239
|
+
if (token.prefix) {
|
|
13240
|
+
part.prefix = token.prefix;
|
|
13241
|
+
if (token.prefix.book === void 0) part.sheet = token.prefix.sheet.toLowerCase();
|
|
13242
|
+
}
|
|
13243
|
+
if (token.ref) part.ref = token.ref;
|
|
13244
|
+
if (token.spill) part.spill = true;
|
|
13245
|
+
template.push(part);
|
|
13246
|
+
}
|
|
13247
|
+
if (literal2) template.push(literal2);
|
|
13248
|
+
}
|
|
13249
|
+
remember(formula, template);
|
|
13250
|
+
return template;
|
|
13251
|
+
}
|
|
13252
|
+
function rewriteTemplate(formula, rewrite) {
|
|
13253
|
+
const template = templateOf(formula);
|
|
13254
|
+
if (!template) return formula;
|
|
13255
|
+
let next;
|
|
13256
|
+
for (let i2 = 0; i2 < template.length; i2++) {
|
|
13257
|
+
const part = template[i2];
|
|
13258
|
+
if (typeof part === "string") continue;
|
|
13259
|
+
const changed = rewrite(part);
|
|
13260
|
+
if (!changed) continue;
|
|
13261
|
+
next ??= template.slice();
|
|
13262
|
+
next[i2] = changed;
|
|
13263
|
+
}
|
|
13264
|
+
if (!next) return formula;
|
|
13265
|
+
const text2 = next.map((part) => typeof part === "string" ? part : part.text).join("");
|
|
13266
|
+
remember(text2, next);
|
|
13267
|
+
return text2;
|
|
13268
|
+
}
|
|
13269
|
+
function shiftInterval(a, b, at, count2, max) {
|
|
13270
|
+
if (count2 > 0) {
|
|
13271
|
+
const na2 = a >= at ? a + count2 : a;
|
|
13272
|
+
const nb2 = b >= at ? b + count2 : b;
|
|
13273
|
+
if (nb2 > max) return na2 > max ? void 0 : [na2, max];
|
|
13274
|
+
return [na2, nb2];
|
|
12676
13275
|
}
|
|
12677
|
-
|
|
13276
|
+
const n = -count2;
|
|
13277
|
+
const last = at + n - 1;
|
|
13278
|
+
if (a >= at && b <= last) return void 0;
|
|
13279
|
+
const na = a < at ? a : a <= last ? at : a - n;
|
|
13280
|
+
const nb = b < at ? b : b <= last ? at - 1 : b - n;
|
|
13281
|
+
return [na, nb];
|
|
12678
13282
|
}
|
|
12679
|
-
|
|
12680
|
-
|
|
12681
|
-
|
|
12682
|
-
const
|
|
12683
|
-
const
|
|
12684
|
-
|
|
13283
|
+
function shiftRef(ref, spec2) {
|
|
13284
|
+
const isRow = spec2.axis === "row";
|
|
13285
|
+
if (isRow && ref.kind === "cols" || !isRow && ref.kind === "rows") return ref;
|
|
13286
|
+
const startFirst = isRow ? ref.start.row <= ref.end.row : ref.start.col <= ref.end.col;
|
|
13287
|
+
const lo = startFirst ? ref.start : ref.end;
|
|
13288
|
+
const hi = startFirst ? ref.end : ref.start;
|
|
13289
|
+
const shifted2 = shiftInterval(
|
|
13290
|
+
isRow ? lo.row : lo.col,
|
|
13291
|
+
isRow ? hi.row : hi.col,
|
|
13292
|
+
spec2.at,
|
|
13293
|
+
spec2.count,
|
|
13294
|
+
isRow ? MAX_ROW : MAX_COL
|
|
13295
|
+
);
|
|
13296
|
+
if (!shifted2) return void 0;
|
|
13297
|
+
const [a, b] = shifted2;
|
|
13298
|
+
const nlo = isRow ? { ...lo, row: a } : { ...lo, col: a };
|
|
13299
|
+
const nhi = isRow ? { ...hi, row: b } : { ...hi, col: b };
|
|
13300
|
+
const next = {
|
|
13301
|
+
kind: ref.kind,
|
|
13302
|
+
start: startFirst ? nlo : nhi,
|
|
13303
|
+
end: startFirst ? nhi : nlo
|
|
13304
|
+
};
|
|
13305
|
+
if (ref.kind === "cell") next.end = next.start;
|
|
13306
|
+
return sameSpec(next, ref) ? ref : next;
|
|
13307
|
+
}
|
|
13308
|
+
function shiftFormula(formula, formulaSheet, spec2) {
|
|
13309
|
+
if (spec2.count === 0) return formula;
|
|
13310
|
+
const sheet = spec2.sheet.toLowerCase();
|
|
13311
|
+
const own = formulaSheet.toLowerCase() === sheet;
|
|
13312
|
+
return rewriteTemplate(formula, (part) => {
|
|
13313
|
+
if (part.kind !== "ref" || !part.ref || (part.prefix ? part.sheet !== sheet : !own))
|
|
13314
|
+
return void 0;
|
|
13315
|
+
const next = shiftRef(part.ref, spec2);
|
|
13316
|
+
if (next === part.ref) return void 0;
|
|
13317
|
+
const out = { kind: "ref", text: rewriteRef(part, next) };
|
|
13318
|
+
if (part.prefix) out.prefix = part.prefix;
|
|
13319
|
+
if (part.sheet !== void 0) out.sheet = part.sheet;
|
|
13320
|
+
if (next) out.ref = next;
|
|
13321
|
+
if (part.spill) out.spill = true;
|
|
13322
|
+
return out;
|
|
13323
|
+
});
|
|
12685
13324
|
}
|
|
12686
13325
|
function renameSheetInFormula(formula, oldName, newName) {
|
|
12687
|
-
const tokens = safeTokens(formula);
|
|
12688
|
-
if (!tokens) return formula;
|
|
12689
13326
|
const lower2 = oldName.toLowerCase();
|
|
12690
|
-
|
|
12691
|
-
const prefix =
|
|
12692
|
-
if (!prefix ||
|
|
12693
|
-
const first2 =
|
|
13327
|
+
return rewriteTemplate(formula, (part) => {
|
|
13328
|
+
const prefix = part.prefix;
|
|
13329
|
+
if (!prefix || part.sheet === void 0) return void 0;
|
|
13330
|
+
const first2 = part.sheet === lower2;
|
|
12694
13331
|
const second = prefix.sheet2?.toLowerCase() === lower2;
|
|
12695
|
-
if (!first2 && !second)
|
|
13332
|
+
if (!first2 && !second) return void 0;
|
|
12696
13333
|
const renamed = { ...prefix, sheet: first2 ? newName : prefix.sheet };
|
|
12697
13334
|
if (prefix.sheet2 !== void 0) renamed.sheet2 = second ? newName : prefix.sheet2;
|
|
12698
13335
|
const text2 = prefixText(renamed);
|
|
12699
|
-
token.text = text2 + token.text.slice(prefix.text.length);
|
|
12700
13336
|
renamed.text = text2;
|
|
12701
|
-
|
|
13337
|
+
const out = { ...part, text: text2 + part.text.slice(prefix.text.length) };
|
|
13338
|
+
out.prefix = renamed;
|
|
13339
|
+
out.sheet = renamed.sheet.toLowerCase();
|
|
13340
|
+
return out;
|
|
13341
|
+
});
|
|
13342
|
+
}
|
|
13343
|
+
|
|
13344
|
+
// xlsx/formula/transform.ts
|
|
13345
|
+
function translateFormula(formula, dRow, dCol) {
|
|
13346
|
+
const tokens = safeTokens(formula);
|
|
13347
|
+
if (!tokens) return formula;
|
|
13348
|
+
for (const token of tokens) {
|
|
13349
|
+
if (token.kind !== "ref" || !token.ref) continue;
|
|
13350
|
+
const spec2 = token.ref;
|
|
13351
|
+
const move = (c) => {
|
|
13352
|
+
const row2 = spec2.kind === "cols" || c.rowAbs ? c.row : c.row + dRow;
|
|
13353
|
+
const col = spec2.kind === "rows" || c.colAbs ? c.col : c.col + dCol;
|
|
13354
|
+
if (row2 < 0 || row2 > MAX_ROW || col < 0 || col > MAX_COL) return void 0;
|
|
13355
|
+
return { ...c, row: row2, col };
|
|
13356
|
+
};
|
|
13357
|
+
const start = move(spec2.start);
|
|
13358
|
+
const end = move(spec2.end);
|
|
13359
|
+
const next = start && end ? { kind: spec2.kind, start, end } : void 0;
|
|
13360
|
+
if (next && sameSpec(next, spec2)) continue;
|
|
13361
|
+
token.text = rewriteRef(token, next);
|
|
12702
13362
|
}
|
|
12703
13363
|
return joinTokens(tokens);
|
|
12704
13364
|
}
|
|
@@ -13022,13 +13682,13 @@ function dataBarLengths(rule, node) {
|
|
|
13022
13682
|
maxLength: rule.maxLength ?? numAttr(bar, "maxLength") ?? 90
|
|
13023
13683
|
};
|
|
13024
13684
|
}
|
|
13025
|
-
function rewriteConditionalExtension(rule,
|
|
13685
|
+
function rewriteConditionalExtension(rule, rewrite) {
|
|
13026
13686
|
if (!rule.extensionXml) return;
|
|
13027
13687
|
const doc = parseXml(rule.extensionXml);
|
|
13028
13688
|
let changed = false;
|
|
13029
13689
|
for (const formula of descendants(doc.documentElement, "f", XM)) {
|
|
13030
13690
|
const before = formula.textContent ?? "";
|
|
13031
|
-
const next =
|
|
13691
|
+
const next = rewrite(before);
|
|
13032
13692
|
if (before !== next) {
|
|
13033
13693
|
formula.textContent = next;
|
|
13034
13694
|
changed = true;
|
|
@@ -14055,13 +14715,13 @@ function linearTrend(values2) {
|
|
|
14055
14715
|
const slope = den ? num2 / den : 0;
|
|
14056
14716
|
return (k) => Number((meanY + slope * (k - meanX)).toPrecision(15));
|
|
14057
14717
|
}
|
|
14058
|
-
var
|
|
14718
|
+
var isDigit5 = (ch) => ch !== void 0 && ch >= "0" && ch <= "9";
|
|
14059
14719
|
function matchTextNumber(text2) {
|
|
14060
14720
|
let end = text2.length;
|
|
14061
|
-
while (end > 0 && !
|
|
14721
|
+
while (end > 0 && !isDigit5(text2[end - 1])) end--;
|
|
14062
14722
|
if (end === 0) return null;
|
|
14063
14723
|
let start = end;
|
|
14064
|
-
while (start > 0 &&
|
|
14724
|
+
while (start > 0 && isDigit5(text2[start - 1])) start--;
|
|
14065
14725
|
return [text2, text2.slice(0, start), text2.slice(start, end), text2.slice(end)];
|
|
14066
14726
|
}
|
|
14067
14727
|
var QUARTER = /^(q|qtr|quarter)(\s?)([1-4])$/i;
|
|
@@ -14244,10 +14904,10 @@ function removeValidationArea(rules, area) {
|
|
|
14244
14904
|
}
|
|
14245
14905
|
|
|
14246
14906
|
// xlsx/edit/conditional-formulas.ts
|
|
14247
|
-
function rewriteConditionalRule(rule,
|
|
14907
|
+
function rewriteConditionalRule(rule, rewrite) {
|
|
14248
14908
|
const safe2 = (formula) => {
|
|
14249
14909
|
try {
|
|
14250
|
-
return
|
|
14910
|
+
return rewrite(formula);
|
|
14251
14911
|
} catch {
|
|
14252
14912
|
return formula;
|
|
14253
14913
|
}
|
|
@@ -14766,7 +15426,7 @@ function shiftPreservedXml(sheet, shift2, moveRange, banded) {
|
|
|
14766
15426
|
(xml) => xml.includes("sqref")
|
|
14767
15427
|
);
|
|
14768
15428
|
}
|
|
14769
|
-
function rewritePreservedFormulas(sheet,
|
|
15429
|
+
function rewritePreservedFormulas(sheet, rewrite) {
|
|
14770
15430
|
editEntries(
|
|
14771
15431
|
sheet,
|
|
14772
15432
|
"extLst",
|
|
@@ -14776,7 +15436,7 @@ function rewritePreservedFormulas(sheet, rewrite2) {
|
|
|
14776
15436
|
const text2 = f6.textContent ?? "";
|
|
14777
15437
|
let next = text2;
|
|
14778
15438
|
try {
|
|
14779
|
-
next =
|
|
15439
|
+
next = rewrite(text2, sheet.name);
|
|
14780
15440
|
} catch {
|
|
14781
15441
|
next = text2;
|
|
14782
15442
|
}
|
|
@@ -14791,46 +15451,46 @@ function rewritePreservedFormulas(sheet, rewrite2) {
|
|
|
14791
15451
|
}
|
|
14792
15452
|
|
|
14793
15453
|
// xlsx/edit/shift-formulas.ts
|
|
14794
|
-
function safe(
|
|
15454
|
+
function safe(rewrite, formula, formulaSheet) {
|
|
14795
15455
|
try {
|
|
14796
|
-
return
|
|
15456
|
+
return rewrite(formula, formulaSheet);
|
|
14797
15457
|
} catch {
|
|
14798
15458
|
return formula;
|
|
14799
15459
|
}
|
|
14800
15460
|
}
|
|
14801
|
-
function rewriteFormulas(workbook,
|
|
14802
|
-
for (const sheet of workbook.sheets) rewriteSheetFormulas(sheet,
|
|
15461
|
+
function rewriteFormulas(workbook, rewrite) {
|
|
15462
|
+
for (const sheet of workbook.sheets) rewriteSheetFormulas(sheet, rewrite);
|
|
14803
15463
|
for (const definedName of workbook.definedNames) {
|
|
14804
15464
|
const local = definedName.localSheet === void 0 ? void 0 : workbook.sheets[definedName.localSheet];
|
|
14805
|
-
definedName.formula = safe(
|
|
15465
|
+
definedName.formula = safe(rewrite, definedName.formula, local?.name ?? "");
|
|
14806
15466
|
}
|
|
14807
15467
|
}
|
|
14808
|
-
function rewriteSheetFormulas(sheet,
|
|
14809
|
-
rewritePreservedFormulas(sheet,
|
|
15468
|
+
function rewriteSheetFormulas(sheet, rewrite) {
|
|
15469
|
+
rewritePreservedFormulas(sheet, rewrite);
|
|
14810
15470
|
{
|
|
14811
15471
|
const name = sheet.name;
|
|
14812
15472
|
for (const table2 of sheet.tables)
|
|
14813
15473
|
for (const column of table2.columns)
|
|
14814
15474
|
if (column.calculatedColumnFormula !== void 0)
|
|
14815
|
-
column.calculatedColumnFormula = safe(
|
|
15475
|
+
column.calculatedColumnFormula = safe(rewrite, column.calculatedColumnFormula, name);
|
|
14816
15476
|
for (const cells of sheet.rows.values())
|
|
14817
15477
|
for (const cell of cells.values())
|
|
14818
|
-
if (cell.formula !== void 0) cell.formula = safe(
|
|
15478
|
+
if (cell.formula !== void 0) cell.formula = safe(rewrite, cell.formula, name);
|
|
14819
15479
|
for (const cf of sheet.conditionalFormats)
|
|
14820
|
-
for (const rule of cf.rules) rewriteConditionalRule(rule, (f6) =>
|
|
15480
|
+
for (const rule of cf.rules) rewriteConditionalRule(rule, (f6) => rewrite(f6, name));
|
|
14821
15481
|
for (const dv of sheet.dataValidations) {
|
|
14822
|
-
if (dv.formula1 !== void 0) dv.formula1 = safe(
|
|
14823
|
-
if (dv.formula2 !== void 0) dv.formula2 = safe(
|
|
15482
|
+
if (dv.formula1 !== void 0) dv.formula1 = safe(rewrite, dv.formula1, name);
|
|
15483
|
+
if (dv.formula2 !== void 0) dv.formula2 = safe(rewrite, dv.formula2, name);
|
|
14824
15484
|
}
|
|
14825
15485
|
for (const link of sheet.hyperlinks)
|
|
14826
15486
|
if (link.location && /![A-Za-z$]/.test(link.location))
|
|
14827
|
-
link.location = safe(
|
|
15487
|
+
link.location = safe(rewrite, link.location, name);
|
|
14828
15488
|
for (const drawing of sheet.drawings) {
|
|
14829
15489
|
if (drawing.kind !== "chart") continue;
|
|
14830
15490
|
for (const series of drawing.series) {
|
|
14831
|
-
if (series.nameRef) series.nameRef = safe(
|
|
14832
|
-
if (series.categoriesRef) series.categoriesRef = safe(
|
|
14833
|
-
if (series.valuesRef) series.valuesRef = safe(
|
|
15491
|
+
if (series.nameRef) series.nameRef = safe(rewrite, series.nameRef, name);
|
|
15492
|
+
if (series.categoriesRef) series.categoriesRef = safe(rewrite, series.categoriesRef, name);
|
|
15493
|
+
if (series.valuesRef) series.valuesRef = safe(rewrite, series.valuesRef, name);
|
|
14834
15494
|
}
|
|
14835
15495
|
}
|
|
14836
15496
|
}
|
|
@@ -15017,7 +15677,7 @@ function shiftAxis(ctx, s, axis, at, count2, insert) {
|
|
|
15017
15677
|
applyAxisShift(ctx, sheet, shift2);
|
|
15018
15678
|
if (insert) inheritFormats(sheet, axis, at, count2);
|
|
15019
15679
|
},
|
|
15020
|
-
{ sheet: s, structural: true }
|
|
15680
|
+
{ sheet: s, structural: true, calc: { kind: "shift", sheet: s, shift: shift2 } }
|
|
15021
15681
|
);
|
|
15022
15682
|
}
|
|
15023
15683
|
var insertRows = (ctx, s, at, count2) => shiftAxis(ctx, s, "row", at, count2, true);
|
|
@@ -16831,6 +17491,14 @@ function setCalcMode(ctx, mode) {
|
|
|
16831
17491
|
|
|
16832
17492
|
// xlsx/edit/session-calc.ts
|
|
16833
17493
|
var isStructural = (step) => step.structural || step.entries.some((entry) => entry.before.kind !== "cells");
|
|
17494
|
+
function hintFor(step, mode) {
|
|
17495
|
+
const hint = step.calc;
|
|
17496
|
+
if (!hint) return void 0;
|
|
17497
|
+
if (hint.kind === "rename")
|
|
17498
|
+
return mode === "undo" ? { kind: "rename", from: hint.to, to: hint.from } : hint;
|
|
17499
|
+
return mode === "undo" ? void 0 : hint;
|
|
17500
|
+
}
|
|
17501
|
+
var settingsOf = (workbook) => `${workbook.iterate ? `${workbook.iterate.count}:${workbook.iterate.delta}` : ""}|${workbook.date1904}`;
|
|
16834
17502
|
var SessionCalculator = class {
|
|
16835
17503
|
constructor(workbook, calc, enabled) {
|
|
16836
17504
|
this.workbook = workbook;
|
|
@@ -16840,43 +17508,113 @@ var SessionCalculator = class {
|
|
|
16840
17508
|
workbook;
|
|
16841
17509
|
calc;
|
|
16842
17510
|
enabled;
|
|
16843
|
-
/** Structural edits
|
|
17511
|
+
/** Structural edits the engine could not follow leave the dependency graph stale (manual mode). */
|
|
16844
17512
|
staleGraph = false;
|
|
17513
|
+
/** Cells changed in manual mode since the last calculation. */
|
|
17514
|
+
dirty = [];
|
|
17515
|
+
/** The settings at the last calculation; undefined before the first. */
|
|
17516
|
+
calculated;
|
|
16845
17517
|
/** Recalculates after an applied, undone or redone step (failures become warnings). */
|
|
16846
|
-
afterStep(step) {
|
|
16847
|
-
if (!this.enabled)
|
|
17518
|
+
afterStep(step, mode = "apply") {
|
|
17519
|
+
if (!this.enabled) {
|
|
17520
|
+
this.calc.discardPreparation();
|
|
17521
|
+
return;
|
|
17522
|
+
}
|
|
17523
|
+
const structural = isStructural(step);
|
|
17524
|
+
const hint = structural ? hintFor(step, mode) : void 0;
|
|
16848
17525
|
if (calcModeOf(this.workbook) === "manual") {
|
|
16849
|
-
if (
|
|
17526
|
+
if (hint && !this.staleGraph && !this.dirty.length) {
|
|
17527
|
+
this.guard(() => this.follow(hint));
|
|
17528
|
+
return;
|
|
17529
|
+
}
|
|
17530
|
+
this.calc.discardPreparation();
|
|
17531
|
+
if (structural) this.staleGraph = true;
|
|
17532
|
+
else this.dirty.push(...touchedCells(step));
|
|
16850
17533
|
return;
|
|
16851
17534
|
}
|
|
16852
|
-
|
|
17535
|
+
if (hint && !this.staleGraph) {
|
|
17536
|
+
this.guard(() => {
|
|
17537
|
+
this.follow(hint);
|
|
17538
|
+
this.calc.recalculateFrom(touchedCells(step));
|
|
17539
|
+
this.calculated = settingsOf(this.workbook);
|
|
17540
|
+
});
|
|
17541
|
+
return;
|
|
17542
|
+
}
|
|
17543
|
+
this.recalc(structural, () => touchedCells(step));
|
|
16853
17544
|
}
|
|
16854
17545
|
/** Recalculates after a change applied outside the history (a collaborator's edit). */
|
|
16855
17546
|
afterExternal(structural, cells) {
|
|
16856
|
-
if (!this.enabled)
|
|
16857
|
-
|
|
17547
|
+
if (!this.enabled || calcModeOf(this.workbook) === "manual") {
|
|
17548
|
+
this.calc.discardPreparation();
|
|
17549
|
+
if (!this.enabled) return;
|
|
16858
17550
|
if (structural) this.staleGraph = true;
|
|
17551
|
+
else this.dirty.push(...cells);
|
|
16859
17552
|
return;
|
|
16860
17553
|
}
|
|
16861
17554
|
this.recalc(structural, () => cells);
|
|
16862
17555
|
}
|
|
16863
|
-
|
|
17556
|
+
follow(hint) {
|
|
17557
|
+
if (hint.kind === "shift") this.calc.shiftCells(hint.sheet, hint.shift);
|
|
17558
|
+
else this.calc.renameSheet(hint.from, hint.to);
|
|
17559
|
+
}
|
|
17560
|
+
guard(run) {
|
|
17561
|
+
try {
|
|
17562
|
+
run();
|
|
17563
|
+
} catch (error) {
|
|
17564
|
+
const message = `Recalculation failed: ${error instanceof Error ? error.message : String(error)}`;
|
|
17565
|
+
if (!this.workbook.warnings.includes(message)) this.workbook.warnings.push(message);
|
|
17566
|
+
}
|
|
17567
|
+
}
|
|
17568
|
+
/** Builds the dependency graph ahead of the first edit (see `EditSession.prepareCalculation`). */
|
|
17569
|
+
prepare(timeRemaining) {
|
|
17570
|
+
if (!this.enabled || calcModeOf(this.workbook) === "manual" || this.staleGraph) return true;
|
|
16864
17571
|
try {
|
|
17572
|
+
return this.calc.prepare(timeRemaining);
|
|
17573
|
+
} catch {
|
|
17574
|
+
this.calc.discardPreparation();
|
|
17575
|
+
return true;
|
|
17576
|
+
}
|
|
17577
|
+
}
|
|
17578
|
+
/**
|
|
17579
|
+
* Before a structural edit the graph can follow in place: finishes a graph being prepared (or
|
|
17580
|
+
* builds it) while it still matches the workbook, so the edit moves it instead of rebuilding.
|
|
17581
|
+
*/
|
|
17582
|
+
beforeStructural() {
|
|
17583
|
+
if (!this.enabled || calcModeOf(this.workbook) === "manual" || this.staleGraph) return;
|
|
17584
|
+
this.prepare();
|
|
17585
|
+
}
|
|
17586
|
+
recalc(structural, cells) {
|
|
17587
|
+
this.guard(() => {
|
|
16865
17588
|
if (this.staleGraph || structural) this.full();
|
|
16866
17589
|
else {
|
|
16867
17590
|
const changed = cells();
|
|
16868
17591
|
if (changed.length) this.calc.recalculateFrom(changed);
|
|
17592
|
+
this.calculated = settingsOf(this.workbook);
|
|
16869
17593
|
}
|
|
16870
|
-
}
|
|
16871
|
-
const message = `Recalculation failed: ${error instanceof Error ? error.message : String(error)}`;
|
|
16872
|
-
if (!this.workbook.warnings.includes(message)) this.workbook.warnings.push(message);
|
|
16873
|
-
}
|
|
17594
|
+
});
|
|
16874
17595
|
}
|
|
16875
|
-
/** Rebuilds the dependency graph and recalculates every formula (F9). */
|
|
17596
|
+
/** Rebuilds the dependency graph and recalculates every formula (Ctrl+Alt+F9). */
|
|
16876
17597
|
full() {
|
|
16877
17598
|
this.staleGraph = false;
|
|
17599
|
+
this.dirty = [];
|
|
16878
17600
|
this.calc.invalidate();
|
|
16879
17601
|
this.calc.recalculateAll();
|
|
17602
|
+
this.calculated = settingsOf(this.workbook);
|
|
17603
|
+
}
|
|
17604
|
+
/**
|
|
17605
|
+
* Calculate Now (F9): the cells changed since the last calculation, the formulas structural
|
|
17606
|
+
* edits queued, their dependents and the volatile functions. Everything when `full`, before
|
|
17607
|
+
* the session's first calculation, after the iteration settings changed or while the graph
|
|
17608
|
+
* is stale.
|
|
17609
|
+
*/
|
|
17610
|
+
now(full) {
|
|
17611
|
+
if (full || this.staleGraph || this.calculated !== settingsOf(this.workbook)) {
|
|
17612
|
+
this.full();
|
|
17613
|
+
return;
|
|
17614
|
+
}
|
|
17615
|
+
const changed = this.dirty;
|
|
17616
|
+
this.dirty = [];
|
|
17617
|
+
this.calc.recalculateFrom(changed);
|
|
16880
17618
|
}
|
|
16881
17619
|
/**
|
|
16882
17620
|
* Recalculates one sheet's formulas and their dependents (Shift+F9); after structural edits
|
|
@@ -20385,12 +21123,12 @@ function renameSheet(ctx, index2, name) {
|
|
|
20385
21123
|
ctx.run(
|
|
20386
21124
|
"Rename sheet",
|
|
20387
21125
|
"sheets",
|
|
20388
|
-
[{ kind: "
|
|
21126
|
+
[{ kind: "refs" }],
|
|
20389
21127
|
() => {
|
|
20390
21128
|
rewriteFormulas(workbook, (formula) => renameSheetInFormula(formula, old, name));
|
|
20391
21129
|
sheet.name = name;
|
|
20392
21130
|
},
|
|
20393
|
-
{ sheet: index2, structural: true }
|
|
21131
|
+
{ sheet: index2, structural: true, calc: { kind: "rename", from: old, to: name } }
|
|
20394
21132
|
);
|
|
20395
21133
|
}
|
|
20396
21134
|
function moveSheet(ctx, from, to) {
|
|
@@ -20766,13 +21504,12 @@ function createEditSession(workbook, options = {}) {
|
|
|
20766
21504
|
for (const listener of [...listeners2]) listener(change);
|
|
20767
21505
|
};
|
|
20768
21506
|
const calculator = new SessionCalculator(workbook, calc, autoRecalc);
|
|
20769
|
-
const recalc = (step) => calculator.afterStep(step);
|
|
20770
|
-
const begin = (label2, kind, info) =>
|
|
20771
|
-
step
|
|
20772
|
-
|
|
20773
|
-
sheet: info.sheet,
|
|
20774
|
-
|
|
20775
|
-
});
|
|
21507
|
+
const recalc = (step, mode = "apply") => calculator.afterStep(step, mode);
|
|
21508
|
+
const begin = (label2, kind, info) => {
|
|
21509
|
+
const step = { label: label2, entries: [], structural: info.structural ?? false };
|
|
21510
|
+
if (info.calc) step.calc = info.calc;
|
|
21511
|
+
return { step, kind, sheet: info.sheet, ranges: [...info.ranges ?? []] };
|
|
21512
|
+
};
|
|
20776
21513
|
const finish = (current) => {
|
|
20777
21514
|
if (!current.step.entries.length) return;
|
|
20778
21515
|
history.push(current.step);
|
|
@@ -20797,10 +21534,12 @@ function createEditSession(workbook, options = {}) {
|
|
|
20797
21534
|
const outer = !open;
|
|
20798
21535
|
const current = open ?? begin(label2, kind, info);
|
|
20799
21536
|
if (!outer) {
|
|
21537
|
+
delete current.step.calc;
|
|
20800
21538
|
if (info.structural) current.step.structural = true;
|
|
20801
21539
|
if (current.sheet === void 0 && info.sheet !== void 0) current.sheet = info.sheet;
|
|
20802
21540
|
current.ranges.push(...info.ranges ?? []);
|
|
20803
21541
|
}
|
|
21542
|
+
if (outer && info.calc) calculator.beforeStructural();
|
|
20804
21543
|
open = current;
|
|
20805
21544
|
const mark = current.step.entries.length;
|
|
20806
21545
|
const befores = scopes.map((scope) => captureScope(workbook, scope));
|
|
@@ -20848,7 +21587,7 @@ function createEditSession(workbook, options = {}) {
|
|
|
20848
21587
|
if (open) throw new Error(`Cannot ${kind} inside a batch`);
|
|
20849
21588
|
const step = kind === "undo" ? history.undo(workbook) : history.redo(workbook);
|
|
20850
21589
|
if (!step) return false;
|
|
20851
|
-
recalc(step);
|
|
21590
|
+
recalc(step, kind);
|
|
20852
21591
|
emit({ kind, label: step.label, structural: step.structural });
|
|
20853
21592
|
return true;
|
|
20854
21593
|
};
|
|
@@ -20927,10 +21666,11 @@ function createEditSession(workbook, options = {}) {
|
|
|
20927
21666
|
setDocumentProperties: (patch) => setDocumentProperties(ctx, patch),
|
|
20928
21667
|
setAutoRecalc: (enabled) => setCalcMode(ctx, enabled ? "auto" : "manual"),
|
|
20929
21668
|
autoRecalc: () => autoRecalc && calcModeOf(workbook) === "auto",
|
|
20930
|
-
calculateNow() {
|
|
20931
|
-
calculator.full
|
|
21669
|
+
calculateNow(options2) {
|
|
21670
|
+
calculator.now(options2?.full ?? false);
|
|
20932
21671
|
emit({ kind: "cells", label: "Calculate now", structural: false });
|
|
20933
21672
|
},
|
|
21673
|
+
prepareCalculation: (opts) => calculator.prepare(opts?.timeRemaining),
|
|
20934
21674
|
calculateSheet(s) {
|
|
20935
21675
|
calculator.sheet(s);
|
|
20936
21676
|
emit({ kind: "cells", label: "Calculate sheet", sheet: s, structural: false });
|