@ai-matrx/office 0.8.20 → 0.8.21
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/CHANGELOG.md +20 -2
- package/dist/collab-sheets-transform.cjs +354 -16
- package/dist/collab-sheets-transform.cjs.map +1 -1
- package/dist/collab-sheets-transform.d.cts +32 -4
- package/dist/collab-sheets-transform.d.ts +32 -4
- package/dist/collab-sheets-transform.js +354 -16
- package/dist/collab-sheets-transform.js.map +1 -1
- package/dist/univer-collab.cjs +414 -27
- package/dist/univer-collab.cjs.map +1 -1
- package/dist/univer-collab.d.cts +6 -1
- package/dist/univer-collab.d.ts +6 -1
- package/dist/univer-collab.js +414 -27
- package/dist/univer-collab.js.map +1 -1
- package/package.json +3 -3
|
@@ -24,6 +24,14 @@ var SHEET_MUTATIONS = {
|
|
|
24
24
|
"sheet.mutation.set-worksheet-row-auto-height": covered("size", "rowsAutoHeightInfo"),
|
|
25
25
|
"sheet.mutation.set-worksheet-col-width": covered("size", "ranges", "colWidth"),
|
|
26
26
|
"sheet.mutation.set-worksheet-name": covered("name", "name"),
|
|
27
|
+
// ── covered (C5c) ────────────────────────────────────────────────────────────────────────────────
|
|
28
|
+
"sheet.mutation.set.numfmt": covered("numfmt", "values", "refMap"),
|
|
29
|
+
"sheet.mutation.remove.numfmt": covered("numfmt", "ranges"),
|
|
30
|
+
"sheet.mutation.set-worksheet-row-count": covered("count", "rowCount"),
|
|
31
|
+
"sheet.mutation.set-worksheet-column-count": covered("count", "columnCount"),
|
|
32
|
+
"sheet.mutation.insert-sheet": covered("sheet", "index", "sheet"),
|
|
33
|
+
"sheet.mutation.remove-sheet": covered("sheet", "sheetIndex", "sheetsLeft"),
|
|
34
|
+
"sheet.mutation.set-worksheet-order": covered("sheet", "fromOrder", "toOrder"),
|
|
27
35
|
// ── never travels ────────────────────────────────────────────────────────────────────────────────
|
|
28
36
|
"formula.mutation.set-formula-calculation-start": never(FORMULA_RESULT),
|
|
29
37
|
"formula.mutation.set-trigger-formula-calculation-start": never(FORMULA_RESULT),
|
|
@@ -58,12 +66,7 @@ var SHEET_MUTATIONS = {
|
|
|
58
66
|
"thread-comment.mutation.delete-comment": never(UNIVER_COMMENTS),
|
|
59
67
|
// ── barriers: X (no transform yet, design §10) ───────────────────────────────────────────────────
|
|
60
68
|
"sheet.mutation.reorder-range": barrier("X", "sort: a permutation, not transformed yet"),
|
|
61
|
-
"sheet.mutation.set-worksheet-row-count": barrier("X", "absolute row count; needs delta semantics"),
|
|
62
|
-
"sheet.mutation.set-worksheet-column-count": barrier("X", "absolute column count; needs delta semantics"),
|
|
63
|
-
"sheet.mutation.set-worksheet-order": barrier("X", "absolute sheet order; needs move semantics"),
|
|
64
69
|
"sheet.mutation.move-range": barrier("X", "cut-paste carries the sender's cell matrices"),
|
|
65
|
-
"sheet.mutation.insert-sheet": barrier("X", "sheet add: not in C5a"),
|
|
66
|
-
"sheet.mutation.remove-sheet": barrier("X", "sheet remove: not in C5a"),
|
|
67
70
|
"sheet.mutation.set-worksheet-hidden": barrier("X", "sheet-level setting: not in C5a"),
|
|
68
71
|
"sheet.mutation.set-tab-color": barrier("X", "sheet-level setting: not in C5a"),
|
|
69
72
|
"sheet.mutation.set-workbook-name": barrier("X", "workbook-level setting: not in C5a"),
|
|
@@ -78,8 +81,6 @@ var SHEET_MUTATIONS = {
|
|
|
78
81
|
"sheet.mutation.set-row-visible": barrier("X", "row visibility: not in C5a"),
|
|
79
82
|
"sheet.mutation.set-col-hidden": barrier("X", "column visibility: not in C5a"),
|
|
80
83
|
"sheet.mutation.set-col-visible": barrier("X", "column visibility: not in C5a"),
|
|
81
|
-
"sheet.mutation.set.numfmt": barrier("X", "number formats by range: not in C5a"),
|
|
82
|
-
"sheet.mutation.remove.numfmt": barrier("X", "number formats by range: not in C5a"),
|
|
83
84
|
"sheet.mutation.add-range-protection": barrier("X", "permissions: not in C5a"),
|
|
84
85
|
"sheet.mutation.set-range-protection": barrier("X", "permissions: not in C5a"),
|
|
85
86
|
"sheet.mutation.delete-range-protection": barrier("X", "permissions: not in C5a"),
|
|
@@ -483,7 +484,7 @@ function refSheetsFor(texts, sheets) {
|
|
|
483
484
|
}
|
|
484
485
|
|
|
485
486
|
// src/collab/sheets/transform/transform.ts
|
|
486
|
-
var SHEET_TRANSFORMER_VERSION = "
|
|
487
|
+
var SHEET_TRANSFORMER_VERSION = "c5c-1";
|
|
487
488
|
var ID = {
|
|
488
489
|
values: "sheet.mutation.set-range-values",
|
|
489
490
|
insertRow: "sheet.mutation.insert-row",
|
|
@@ -500,7 +501,14 @@ var ID = {
|
|
|
500
501
|
colWidth: "sheet.mutation.set-worksheet-col-width",
|
|
501
502
|
name: "sheet.mutation.set-worksheet-name",
|
|
502
503
|
setName: "formula.mutation.set-defined-name",
|
|
503
|
-
removeName: "formula.mutation.remove-defined-name"
|
|
504
|
+
removeName: "formula.mutation.remove-defined-name",
|
|
505
|
+
setNumfmt: "sheet.mutation.set.numfmt",
|
|
506
|
+
removeNumfmt: "sheet.mutation.remove.numfmt",
|
|
507
|
+
rowCount: "sheet.mutation.set-worksheet-row-count",
|
|
508
|
+
colCount: "sheet.mutation.set-worksheet-column-count",
|
|
509
|
+
insertSheet: "sheet.mutation.insert-sheet",
|
|
510
|
+
removeSheet: "sheet.mutation.remove-sheet",
|
|
511
|
+
sheetOrder: "sheet.mutation.set-worksheet-order"
|
|
504
512
|
};
|
|
505
513
|
var PAIR_BARRIERS = {};
|
|
506
514
|
var pairKey = (a, b) => a < b ? `${a}|${b}` : `${b}|${a}`;
|
|
@@ -612,6 +620,20 @@ function mergeThrough(s, m) {
|
|
|
612
620
|
}
|
|
613
621
|
return { range: m, fixup: false };
|
|
614
622
|
}
|
|
623
|
+
function mergeFixupsOwed(m, mergesBefore) {
|
|
624
|
+
const st = structuralOf(m);
|
|
625
|
+
if (!st) return null;
|
|
626
|
+
const remove = [];
|
|
627
|
+
const add = [];
|
|
628
|
+
for (const q of mergesBefore) {
|
|
629
|
+
const t = mergeThrough(st, q);
|
|
630
|
+
if (!t.fixup) continue;
|
|
631
|
+
remove.push({ startRow: q.startRow, endRow: q.endRow, startColumn: q.startColumn, endColumn: q.endColumn, ...q.rangeType !== void 0 ? { rangeType: q.rangeType } : {} });
|
|
632
|
+
if (t.range) add.push({ ...t.range });
|
|
633
|
+
}
|
|
634
|
+
return remove.length ? { remove, add } : null;
|
|
635
|
+
}
|
|
636
|
+
var isStructuralMutation = (m) => structuralOf(m) !== null;
|
|
615
637
|
function exactMergeRemovals(group, merges) {
|
|
616
638
|
const sim = new Map(Object.entries(merges).map(([k, v]) => [k, v.map((r) => ({ ...r }))]));
|
|
617
639
|
const out = [];
|
|
@@ -658,8 +680,24 @@ function cellsMutation(template, cells) {
|
|
|
658
680
|
function putCell(cells, r, c, v) {
|
|
659
681
|
(cells[r] ??= {})[c] = v;
|
|
660
682
|
}
|
|
683
|
+
function cellsOverlap(a, b) {
|
|
684
|
+
for (const r of Object.keys(a)) {
|
|
685
|
+
const br = b[r];
|
|
686
|
+
if (!br) continue;
|
|
687
|
+
for (const c of Object.keys(a[r] ?? {})) if (c in br) return true;
|
|
688
|
+
}
|
|
689
|
+
return false;
|
|
690
|
+
}
|
|
661
691
|
var isEmptyMatrix = (cells) => Object.values(cells).every((row) => Object.keys(row).length === 0);
|
|
692
|
+
var cellBarrierCache = /* @__PURE__ */ new WeakMap();
|
|
662
693
|
function cellBarrier(m) {
|
|
694
|
+
const hit = cellBarrierCache.get(m);
|
|
695
|
+
if (hit !== void 0) return hit;
|
|
696
|
+
const why = cellBarrierOf(m);
|
|
697
|
+
cellBarrierCache.set(m, why);
|
|
698
|
+
return why;
|
|
699
|
+
}
|
|
700
|
+
function cellBarrierOf(m) {
|
|
663
701
|
if (m.params.isOverrideStyle) return "set-range-values with isOverrideStyle (whole-style replace) is not covered";
|
|
664
702
|
let why = null;
|
|
665
703
|
forEachCell(cellsOf(m), (_r, _c, v) => {
|
|
@@ -741,6 +779,7 @@ function transformCell(X, Y, side) {
|
|
|
741
779
|
function transformCellsOverCells(x, y, side) {
|
|
742
780
|
if (sheetOf(x) !== sheetOf(y)) return ok([x]);
|
|
743
781
|
const ycells = cellsOf(y);
|
|
782
|
+
if (!cellsOverlap(cellsOf(x), ycells)) return ok([x]);
|
|
744
783
|
const xd = isDerived(x);
|
|
745
784
|
const yd = isDerived(y);
|
|
746
785
|
const eff = derivedSide(x, y, side);
|
|
@@ -768,7 +807,7 @@ function transformCellsOverCells(x, y, side) {
|
|
|
768
807
|
const op = passes.filter((p) => !isEmptyMatrix(p)).map((p) => cellsMutation(x, p));
|
|
769
808
|
return ok(op, lost, dropped);
|
|
770
809
|
}
|
|
771
|
-
var SIDE_CAR_PARAMS = ["refSheets", "previousName", "derived"];
|
|
810
|
+
var SIDE_CAR_PARAMS = ["refSheets", "previousName", "derived", "sheetIndex", "sheetsLeft"];
|
|
772
811
|
var isDerived = (m) => m.params.derived === true;
|
|
773
812
|
function derivedSide(x, y, side) {
|
|
774
813
|
const xd = isDerived(x);
|
|
@@ -790,7 +829,15 @@ function withRefSheets(params, rs) {
|
|
|
790
829
|
return out;
|
|
791
830
|
}
|
|
792
831
|
var hasFormulaText = (v) => !!v && (isFormulaText(v.f) || typeof v.ref === "string");
|
|
832
|
+
var hasFormulaCache = /* @__PURE__ */ new WeakMap();
|
|
793
833
|
function hasFormula(m) {
|
|
834
|
+
const hit = hasFormulaCache.get(m);
|
|
835
|
+
if (hit !== void 0) return hit;
|
|
836
|
+
const any = hasFormulaOf(m);
|
|
837
|
+
hasFormulaCache.set(m, any);
|
|
838
|
+
return any;
|
|
839
|
+
}
|
|
840
|
+
function hasFormulaOf(m) {
|
|
794
841
|
let any = false;
|
|
795
842
|
forEachCell(cellsOf(m), (_r, _c, v) => {
|
|
796
843
|
any ||= hasFormulaText(v);
|
|
@@ -829,15 +876,18 @@ function cellThrough(sheet, change, r, c) {
|
|
|
829
876
|
return nr === null || nc === null ? null : [nr, nc];
|
|
830
877
|
}
|
|
831
878
|
function cellsOverChange(x, change) {
|
|
879
|
+
if (!hasFormula(x) && (change.kind !== "axis" || change.sheet !== sheetOf(x))) return ok([x]);
|
|
832
880
|
const ctx = formulaCtx(x);
|
|
833
881
|
const out = {};
|
|
834
882
|
const dropped = [];
|
|
835
883
|
let why = null;
|
|
884
|
+
let changed = false;
|
|
836
885
|
forEachCell(cellsOf(x), (r, c, v) => {
|
|
837
886
|
if (why) return;
|
|
838
887
|
const at = cellThrough(sheetOf(x), change, r, c);
|
|
839
888
|
if (!at) {
|
|
840
889
|
dropped.push(cellRef(sheetOf(x), r, c));
|
|
890
|
+
changed = true;
|
|
841
891
|
return;
|
|
842
892
|
}
|
|
843
893
|
let e = v;
|
|
@@ -848,14 +898,19 @@ function cellsOverChange(x, change) {
|
|
|
848
898
|
return;
|
|
849
899
|
}
|
|
850
900
|
e = res.entry;
|
|
901
|
+
if (res.changed) changed = true;
|
|
851
902
|
}
|
|
903
|
+
if (at[0] !== r || at[1] !== c) changed = true;
|
|
852
904
|
putCell(out, at[0], at[1], e);
|
|
853
905
|
});
|
|
854
906
|
if (why) return barrier2(why);
|
|
855
|
-
const
|
|
907
|
+
const rsAfter = refSheetsAfter(ctx.refSheets, change);
|
|
908
|
+
if (!changed && JSON.stringify(rsAfter ?? null) === JSON.stringify(ctx.refSheets ?? null)) return ok([x]);
|
|
909
|
+
const params = { ...withRefSheets(x.params, rsAfter), cellValue: out };
|
|
856
910
|
return ok(isEmptyMatrix(out) ? [] : [{ id: x.id, params }], [], dropped);
|
|
857
911
|
}
|
|
858
912
|
function rewritesOf(y, change) {
|
|
913
|
+
if (!hasFormula(y)) return null;
|
|
859
914
|
const ctx = formulaCtx(y);
|
|
860
915
|
const out = {};
|
|
861
916
|
let why = null;
|
|
@@ -1001,6 +1056,255 @@ function buildSize(template, values) {
|
|
|
1001
1056
|
const value = uniform !== void 0 && [...values.values()].every((v) => v === uniform) ? uniform : Object.fromEntries(values);
|
|
1002
1057
|
return { id: template.id, params: { ...p, ranges, [field]: value } };
|
|
1003
1058
|
}
|
|
1059
|
+
var isNumfmt = (m) => m.id === ID.setNumfmt || m.id === ID.removeNumfmt;
|
|
1060
|
+
function nfParts(m) {
|
|
1061
|
+
if (m.id === ID.removeNumfmt) return [{ key: null, ranges: (m.params.ranges ?? []).map((r) => ({ ...r })) }];
|
|
1062
|
+
const values = m.params.values ?? {};
|
|
1063
|
+
return Object.keys(values).map((k) => ({ key: k, ranges: (values[k]?.ranges ?? []).map((r) => ({ ...r })) }));
|
|
1064
|
+
}
|
|
1065
|
+
function nfBuild(m, parts) {
|
|
1066
|
+
const keep = parts.filter((p) => p.ranges.length);
|
|
1067
|
+
if (!keep.length) return [];
|
|
1068
|
+
if (m.id === ID.removeNumfmt) return [{ id: m.id, params: { ...m.params, ranges: keep[0].ranges } }];
|
|
1069
|
+
const values = {};
|
|
1070
|
+
const refMap = {};
|
|
1071
|
+
const srcValues = m.params.values ?? {};
|
|
1072
|
+
const srcRef = m.params.refMap ?? {};
|
|
1073
|
+
for (const p of keep) {
|
|
1074
|
+
values[p.key] = { ...srcValues[p.key], ranges: p.ranges };
|
|
1075
|
+
refMap[p.key] = srcRef[p.key];
|
|
1076
|
+
}
|
|
1077
|
+
return [{ id: m.id, params: { ...m.params, values, refMap } }];
|
|
1078
|
+
}
|
|
1079
|
+
function nfValueAt(m, row, col) {
|
|
1080
|
+
for (const p of nfParts(m))
|
|
1081
|
+
if (p.ranges.some((r) => r.startRow <= row && row <= r.endRow && r.startColumn <= col && col <= r.endColumn)) {
|
|
1082
|
+
if (p.key === null) return null;
|
|
1083
|
+
const ref = (m.params.refMap ?? {})[p.key];
|
|
1084
|
+
return { pattern: ref?.pattern };
|
|
1085
|
+
}
|
|
1086
|
+
return void 0;
|
|
1087
|
+
}
|
|
1088
|
+
function spanThrough(op, lo, hi) {
|
|
1089
|
+
const pieces = [];
|
|
1090
|
+
if (op.kind === "insert") pieces.push([0, op.at - 1, 0], [op.at, Infinity, op.count]);
|
|
1091
|
+
else if (op.kind === "remove") pieces.push([0, op.start - 1, 0], [op.start + op.count, Infinity, -op.count]);
|
|
1092
|
+
else if (op.count <= 0 || op.to >= op.from && op.to <= op.from + op.count) pieces.push([0, Infinity, 0]);
|
|
1093
|
+
else if (op.to > op.from) {
|
|
1094
|
+
const n = op.count;
|
|
1095
|
+
pieces.push([0, op.from - 1, 0], [op.from, op.from + n - 1, op.to - n - op.from], [op.from + n, op.to - 1, -n], [op.to, Infinity, 0]);
|
|
1096
|
+
} else {
|
|
1097
|
+
const n = op.count;
|
|
1098
|
+
pieces.push([0, op.to - 1, 0], [op.to, op.from - 1, n], [op.from, op.from + n - 1, op.to - op.from], [op.from + n, Infinity, 0]);
|
|
1099
|
+
}
|
|
1100
|
+
const out = [];
|
|
1101
|
+
for (const [a, b, d] of pieces) {
|
|
1102
|
+
const x0 = Math.max(a, lo);
|
|
1103
|
+
const x1 = Math.min(b, hi);
|
|
1104
|
+
if (x0 <= x1) out.push([x0 + d, x1 + d]);
|
|
1105
|
+
}
|
|
1106
|
+
out.sort((p, q) => p[0] - q[0]);
|
|
1107
|
+
const merged = [];
|
|
1108
|
+
for (const p of out) {
|
|
1109
|
+
const last = merged[merged.length - 1];
|
|
1110
|
+
if (last && last[1] + 1 >= p[0]) last[1] = Math.max(last[1], p[1]);
|
|
1111
|
+
else merged.push([p[0], p[1]]);
|
|
1112
|
+
}
|
|
1113
|
+
return merged;
|
|
1114
|
+
}
|
|
1115
|
+
function rectsThrough(st, rects) {
|
|
1116
|
+
const [a0, a1] = S(st.axis);
|
|
1117
|
+
const out = [];
|
|
1118
|
+
for (const r of rects) for (const [lo, hi] of spanThrough(st.op, r[a0], r[a1])) out.push({ ...r, [a0]: lo, [a1]: hi });
|
|
1119
|
+
return out;
|
|
1120
|
+
}
|
|
1121
|
+
function rectMinus(a, b) {
|
|
1122
|
+
if (a.startRow > b.endRow || b.startRow > a.endRow || a.startColumn > b.endColumn || b.startColumn > a.endColumn) return [a];
|
|
1123
|
+
const out = [];
|
|
1124
|
+
if (a.startRow < b.startRow) out.push({ ...a, endRow: b.startRow - 1 });
|
|
1125
|
+
if (a.endRow > b.endRow) out.push({ ...a, startRow: b.endRow + 1 });
|
|
1126
|
+
const r0 = Math.max(a.startRow, b.startRow);
|
|
1127
|
+
const r1 = Math.min(a.endRow, b.endRow);
|
|
1128
|
+
if (a.startColumn < b.startColumn) out.push({ ...a, startRow: r0, endRow: r1, endColumn: b.startColumn - 1 });
|
|
1129
|
+
if (a.endColumn > b.endColumn) out.push({ ...a, startRow: r0, endRow: r1, startColumn: b.endColumn + 1 });
|
|
1130
|
+
return out;
|
|
1131
|
+
}
|
|
1132
|
+
function rectsMinus(as, bs) {
|
|
1133
|
+
let cur = as;
|
|
1134
|
+
for (const b of bs) cur = cur.flatMap((a) => rectMinus(a, b));
|
|
1135
|
+
return cur;
|
|
1136
|
+
}
|
|
1137
|
+
function nWrites(m) {
|
|
1138
|
+
const out = [];
|
|
1139
|
+
forEachCell(cellsOf(m), (r, c, v) => {
|
|
1140
|
+
if (v === null || v.s === null || v.s && typeof v.s === "object" && "n" in v.s)
|
|
1141
|
+
out.push({ startRow: r, endRow: r, startColumn: c, endColumn: c });
|
|
1142
|
+
});
|
|
1143
|
+
return out;
|
|
1144
|
+
}
|
|
1145
|
+
function numfmtPair(x, y, side, sx, sy) {
|
|
1146
|
+
const nx = isNumfmt(x);
|
|
1147
|
+
const ny = isNumfmt(y);
|
|
1148
|
+
if (!nx && !ny) return null;
|
|
1149
|
+
if (nx && sy) return ok(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsThrough(sy, p.ranges) }))));
|
|
1150
|
+
if (ny && sx) return ok([x]);
|
|
1151
|
+
if (nx && ny) {
|
|
1152
|
+
if (side === "left") return ok([x]);
|
|
1153
|
+
const ys = nfParts(y).flatMap((p) => p.ranges);
|
|
1154
|
+
return ok(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsMinus(p.ranges, ys) }))));
|
|
1155
|
+
}
|
|
1156
|
+
if (nx && y.id === ID.values) {
|
|
1157
|
+
if (side === "left") return ok([x]);
|
|
1158
|
+
const ys = nWrites(y);
|
|
1159
|
+
return ys.length ? ok(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsMinus(p.ranges, ys) })))) : ok([x]);
|
|
1160
|
+
}
|
|
1161
|
+
if (ny && x.id === ID.values) {
|
|
1162
|
+
if (side === "left") return ok([x]);
|
|
1163
|
+
const out = {};
|
|
1164
|
+
const tail = {};
|
|
1165
|
+
let touched = false;
|
|
1166
|
+
forEachCell(cellsOf(x), (r, c, v) => {
|
|
1167
|
+
const n = nfValueAt(y, r, c);
|
|
1168
|
+
if (n === void 0) return putCell(out, r, c, v);
|
|
1169
|
+
if (v === null || v.s === null) {
|
|
1170
|
+
putCell(out, r, c, v);
|
|
1171
|
+
if (n) {
|
|
1172
|
+
putCell(tail, r, c, { s: { n } });
|
|
1173
|
+
touched = true;
|
|
1174
|
+
}
|
|
1175
|
+
return;
|
|
1176
|
+
}
|
|
1177
|
+
if (v.s && typeof v.s === "object" && "n" in v.s) {
|
|
1178
|
+
const { n: _drop, ...rest } = v.s;
|
|
1179
|
+
const e = { ...v };
|
|
1180
|
+
if (Object.keys(rest).length) e.s = rest;
|
|
1181
|
+
else delete e.s;
|
|
1182
|
+
touched = true;
|
|
1183
|
+
if (Object.keys(e).length) putCell(out, r, c, e);
|
|
1184
|
+
return;
|
|
1185
|
+
}
|
|
1186
|
+
putCell(out, r, c, v);
|
|
1187
|
+
});
|
|
1188
|
+
if (!touched) return ok([x]);
|
|
1189
|
+
const ops = [];
|
|
1190
|
+
if (!isEmptyMatrix(out)) ops.push(cellsMutation(x, out));
|
|
1191
|
+
if (!isEmptyMatrix(tail)) ops.push({ id: ID.values, params: { subUnitId: sheetOf(x), cellValue: tail } });
|
|
1192
|
+
return ok(ops);
|
|
1193
|
+
}
|
|
1194
|
+
return ok([x]);
|
|
1195
|
+
}
|
|
1196
|
+
var isCount = (m) => m.id === ID.rowCount || m.id === ID.colCount;
|
|
1197
|
+
var countAxis = (m) => m.id === ID.rowCount ? "row" : "col";
|
|
1198
|
+
var countKey = (m) => m.id === ID.rowCount ? "rowCount" : "columnCount";
|
|
1199
|
+
function countPair(x, y, sy) {
|
|
1200
|
+
if (!isCount(x)) return isCount(y) ? ok([x]) : null;
|
|
1201
|
+
const k = countKey(x);
|
|
1202
|
+
const v = Number(x.params[k]);
|
|
1203
|
+
if (sy) {
|
|
1204
|
+
if (sy.axis !== countAxis(x) || sy.op.kind === "move") return ok([x]);
|
|
1205
|
+
const d = sy.op.kind === "insert" ? sy.op.count : -sy.op.count;
|
|
1206
|
+
return ok([{ id: x.id, params: { ...x.params, [k]: Math.max(1, v + d) } }]);
|
|
1207
|
+
}
|
|
1208
|
+
if (isCount(y) && y.id === x.id) {
|
|
1209
|
+
const w = Number(y.params[k]);
|
|
1210
|
+
return ok([w > v ? { id: x.id, params: { ...x.params, [k]: w } } : x]);
|
|
1211
|
+
}
|
|
1212
|
+
return ok([x]);
|
|
1213
|
+
}
|
|
1214
|
+
var isSheetOp = (m) => m.id === ID.insertSheet || m.id === ID.removeSheet || m.id === ID.sheetOrder;
|
|
1215
|
+
var sheetIdOf = (m) => m.id === ID.insertSheet ? String(m.params.sheet?.id ?? "") : sheetOf(m);
|
|
1216
|
+
function sheetAxisOf(m) {
|
|
1217
|
+
const p = m.params;
|
|
1218
|
+
if (m.id === ID.insertSheet) return typeof p.index === "number" ? { kind: "insert", at: p.index, count: 1 } : null;
|
|
1219
|
+
if (m.id === ID.removeSheet) return typeof p.sheetIndex === "number" ? { kind: "remove", start: p.sheetIndex, count: 1 } : null;
|
|
1220
|
+
if (m.id === ID.sheetOrder) {
|
|
1221
|
+
const f = Number(p.fromOrder);
|
|
1222
|
+
const t = Number(p.toOrder);
|
|
1223
|
+
return { kind: "move", from: f, count: 1, to: t > f ? t + 1 : t };
|
|
1224
|
+
}
|
|
1225
|
+
return null;
|
|
1226
|
+
}
|
|
1227
|
+
function buildSheetOp(template, op) {
|
|
1228
|
+
if (op.kind === "insert") return { id: template.id, params: { ...template.params, index: op.at } };
|
|
1229
|
+
if (op.kind === "remove") return { id: template.id, params: { ...template.params, sheetIndex: op.start } };
|
|
1230
|
+
return { id: template.id, params: { ...template.params, fromOrder: op.from, toOrder: op.to > op.from ? op.to - 1 : op.to } };
|
|
1231
|
+
}
|
|
1232
|
+
function namesSheet(m, id) {
|
|
1233
|
+
const rs = refSheetsOf(m);
|
|
1234
|
+
return !!rs && Object.values(rs).includes(id) && (m.id === ID.setName || hasFormula(m));
|
|
1235
|
+
}
|
|
1236
|
+
function sheetPair(x, y, side) {
|
|
1237
|
+
const xs = isSheetOp(x);
|
|
1238
|
+
const ys = isSheetOp(y);
|
|
1239
|
+
if (!xs && !ys) return null;
|
|
1240
|
+
if (xs && ys) {
|
|
1241
|
+
const a = sheetAxisOf(x);
|
|
1242
|
+
const b = sheetAxisOf(y);
|
|
1243
|
+
if (!a || !b) return barrier2("a sheet add or remove without its index (capture must call annotateSheetOps)");
|
|
1244
|
+
if (x.id === ID.insertSheet && y.id === ID.insertSheet && sheetIdOf(x) === sheetIdOf(y)) {
|
|
1245
|
+
return JSON.stringify(x.params) === JSON.stringify(y.params) ? ok([]) : barrier2("the same sheet id added twice with different content");
|
|
1246
|
+
}
|
|
1247
|
+
if (x.id === ID.removeSheet && typeof x.params.sheetsLeft === "number" && sheetIdOf(x) !== sheetIdOf(y) && (y.id === ID.removeSheet || y.id === ID.insertSheet)) {
|
|
1248
|
+
const left = x.params.sheetsLeft + (y.id === ID.insertSheet ? 1 : -1);
|
|
1249
|
+
if (left < 1) return barrier2("concurrent sheet removes would leave the workbook without a sheet");
|
|
1250
|
+
const out2 = transformAxis(a, b, side);
|
|
1251
|
+
if (!out2) return barrier2("sheet order: no transform");
|
|
1252
|
+
return ok(out2.map((o) => buildSheetOp({ id: x.id, params: { ...x.params, sheetsLeft: left } }, o)));
|
|
1253
|
+
}
|
|
1254
|
+
const out = transformAxis(a, b, side);
|
|
1255
|
+
if (!out) return barrier2("sheet order: no transform");
|
|
1256
|
+
return ok(out.map((o) => buildSheetOp(x, o)), [], out.length === 0 && x.id === ID.sheetOrder ? [`${sheetIdOf(x)}: sheet order`] : []);
|
|
1257
|
+
}
|
|
1258
|
+
if (ys) {
|
|
1259
|
+
if (y.id !== ID.removeSheet) return ok([x]);
|
|
1260
|
+
const gone2 = sheetOf(y);
|
|
1261
|
+
if (namesSheet(x, gone2)) return barrier2("a formula names a sheet removed at the same time");
|
|
1262
|
+
if (sheetOf(x) === gone2 && x.id !== ID.setName && x.id !== ID.removeName)
|
|
1263
|
+
return ok([], [], isDerived(x) ? [] : [`${gone2}: the sheet was removed`]);
|
|
1264
|
+
return ok([x]);
|
|
1265
|
+
}
|
|
1266
|
+
if (x.id !== ID.removeSheet) return ok([x]);
|
|
1267
|
+
const gone = sheetOf(x);
|
|
1268
|
+
if (namesSheet(y, gone)) return barrier2("a formula names a sheet removed at the same time");
|
|
1269
|
+
return ok([x], sheetOf(y) === gone && !isDerived(y) && y.id !== ID.setName && y.id !== ID.removeName ? [`${gone}: the sheet was removed`] : []);
|
|
1270
|
+
}
|
|
1271
|
+
function annotateSheetOps(group, sheetOrder) {
|
|
1272
|
+
const order = [...sheetOrder];
|
|
1273
|
+
return group.map((m) => {
|
|
1274
|
+
if (m.id === ID.insertSheet) {
|
|
1275
|
+
const index = typeof m.params.index === "number" ? Math.min(m.params.index, order.length) : order.length;
|
|
1276
|
+
order.splice(index, 0, sheetIdOf(m));
|
|
1277
|
+
return index === m.params.index ? m : { id: m.id, params: { ...m.params, index } };
|
|
1278
|
+
}
|
|
1279
|
+
if (m.id === ID.removeSheet) {
|
|
1280
|
+
const i = order.indexOf(sheetOf(m));
|
|
1281
|
+
if (i >= 0) order.splice(i, 1);
|
|
1282
|
+
return i >= 0 ? { id: m.id, params: { ...m.params, sheetIndex: i, sheetsLeft: order.length } } : m;
|
|
1283
|
+
}
|
|
1284
|
+
if (m.id === ID.sheetOrder) {
|
|
1285
|
+
const f = Number(m.params.fromOrder);
|
|
1286
|
+
const [id] = order.splice(f, 1);
|
|
1287
|
+
order.splice(Number(m.params.toOrder), 0, id ?? sheetOf(m));
|
|
1288
|
+
}
|
|
1289
|
+
return m;
|
|
1290
|
+
});
|
|
1291
|
+
}
|
|
1292
|
+
function inlineSheetStyles(sheet, styleOf) {
|
|
1293
|
+
const out = JSON.parse(JSON.stringify(sheet));
|
|
1294
|
+
const fix = (o) => {
|
|
1295
|
+
if (o && typeof o.s === "string") {
|
|
1296
|
+
const st = styleOf(o.s);
|
|
1297
|
+
if (st) o.s = JSON.parse(JSON.stringify(st));
|
|
1298
|
+
}
|
|
1299
|
+
};
|
|
1300
|
+
for (const row of Object.values(out.cellData ?? {})) for (const cell of Object.values(row ?? {})) fix(cell);
|
|
1301
|
+
for (const key of ["rowData", "columnData"]) for (const v of Object.values(out[key] ?? {})) fix(v);
|
|
1302
|
+
if (typeof out.defaultStyle === "string") {
|
|
1303
|
+
const st = styleOf(out.defaultStyle);
|
|
1304
|
+
if (st) out.defaultStyle = JSON.parse(JSON.stringify(st));
|
|
1305
|
+
}
|
|
1306
|
+
return out;
|
|
1307
|
+
}
|
|
1004
1308
|
function familyOf(id) {
|
|
1005
1309
|
const e = SHEET_MUTATIONS[id];
|
|
1006
1310
|
return e && e.kind === "covered" ? e.family : "";
|
|
@@ -1017,6 +1321,8 @@ function transformMutation(x, y, side) {
|
|
|
1017
1321
|
}
|
|
1018
1322
|
const pb = PAIR_BARRIERS[pairKey(x.id, y.id)];
|
|
1019
1323
|
if (pb) return barrier2(`${x.id} \xD7 ${y.id}: ${pb.reason}${pb.seed === null ? "" : ` (fuzz seed ${pb.seed})`}`);
|
|
1324
|
+
const sp = sheetPair(x, y, side);
|
|
1325
|
+
if (sp) return sp;
|
|
1020
1326
|
const fp = formulaPair(x, y, side);
|
|
1021
1327
|
if (fp) return fp;
|
|
1022
1328
|
if (sheetOf(x) !== sheetOf(y)) return ok([x]);
|
|
@@ -1024,6 +1330,10 @@ function transformMutation(x, y, side) {
|
|
|
1024
1330
|
const fy = familyOf(y.id);
|
|
1025
1331
|
const sy = structuralOf(y);
|
|
1026
1332
|
const sx = structuralOf(x);
|
|
1333
|
+
const cp = countPair(x, y, sy);
|
|
1334
|
+
if (cp) return cp;
|
|
1335
|
+
const np = numfmtPair(x, y, side, sx, sy);
|
|
1336
|
+
if (np) return np;
|
|
1027
1337
|
if (sx && sy) {
|
|
1028
1338
|
if (sx.axis !== sy.axis) return ok([x]);
|
|
1029
1339
|
const out = transformAxis(sx.op, sy.op, side);
|
|
@@ -1131,22 +1441,45 @@ function tSeq(xs, ys, side, acc) {
|
|
|
1131
1441
|
acc.dropped.push(...a.dropped);
|
|
1132
1442
|
return [a.op, b.op];
|
|
1133
1443
|
}
|
|
1444
|
+
const outX = [];
|
|
1445
|
+
let curY = ys;
|
|
1446
|
+
for (const x of xs) {
|
|
1447
|
+
let curX = [x];
|
|
1448
|
+
const nextY = [];
|
|
1449
|
+
for (const y of curY) {
|
|
1450
|
+
if (curX.length === 0) {
|
|
1451
|
+
nextY.push(y);
|
|
1452
|
+
continue;
|
|
1453
|
+
}
|
|
1454
|
+
const r = tSeq(curX, [y], side, acc);
|
|
1455
|
+
if (blocked(r)) return r;
|
|
1456
|
+
curX = r[0];
|
|
1457
|
+
for (const m of r[1]) nextY.push(m);
|
|
1458
|
+
}
|
|
1459
|
+
for (const m of curX) outX.push(m);
|
|
1460
|
+
curY = nextY;
|
|
1461
|
+
}
|
|
1462
|
+
return [outX, curY];
|
|
1463
|
+
}
|
|
1464
|
+
function tSeqOld(xs, ys, side, acc) {
|
|
1465
|
+
if (xs.length === 0 || ys.length === 0) return [xs, ys];
|
|
1466
|
+
if (xs.length === 1 && ys.length === 1) return tSeq(xs, ys, side, acc);
|
|
1134
1467
|
if (xs.length > 1) {
|
|
1135
|
-
const first2 =
|
|
1468
|
+
const first2 = tSeqOld([xs[0]], ys, side, acc);
|
|
1136
1469
|
if (blocked(first2)) return first2;
|
|
1137
|
-
const rest2 =
|
|
1470
|
+
const rest2 = tSeqOld(xs.slice(1), first2[1], side, acc);
|
|
1138
1471
|
if (blocked(rest2)) return rest2;
|
|
1139
1472
|
return [[...first2[0], ...rest2[0]], rest2[1]];
|
|
1140
1473
|
}
|
|
1141
|
-
const first =
|
|
1474
|
+
const first = tSeqOld(xs, [ys[0]], side, acc);
|
|
1142
1475
|
if (blocked(first)) return first;
|
|
1143
|
-
const rest =
|
|
1476
|
+
const rest = tSeqOld(first[0], ys.slice(1), side, acc);
|
|
1144
1477
|
if (blocked(rest)) return rest;
|
|
1145
1478
|
return [rest[0], [...first[1], ...rest[1]]];
|
|
1146
1479
|
}
|
|
1147
1480
|
function transformGroup(x, y, side) {
|
|
1148
1481
|
const acc = { lost: [], dropped: [] };
|
|
1149
|
-
const r = tSeq([...x], [...y], side, acc);
|
|
1482
|
+
const r = (process.env.OLD_TSEQ ? tSeqOld : tSeq)([...x], [...y], side, acc);
|
|
1150
1483
|
if (blocked(r)) return r;
|
|
1151
1484
|
return { op: r[0], lost: [...new Set(acc.lost)], dropped: [...new Set(acc.dropped)] };
|
|
1152
1485
|
}
|
|
@@ -1173,19 +1506,24 @@ export {
|
|
|
1173
1506
|
SIDE_CAR_PARAMS,
|
|
1174
1507
|
allowParams,
|
|
1175
1508
|
annotateFormulas,
|
|
1509
|
+
annotateSheetOps,
|
|
1176
1510
|
cellRef,
|
|
1177
1511
|
completeCellContent,
|
|
1178
1512
|
exactMergeRemovals,
|
|
1179
1513
|
forApply,
|
|
1180
1514
|
formulaBarrier,
|
|
1515
|
+
inlineSheetStyles,
|
|
1181
1516
|
isBarrier,
|
|
1182
1517
|
isFormulaText,
|
|
1518
|
+
isStructuralMutation,
|
|
1183
1519
|
mapIndex,
|
|
1520
|
+
mergeFixupsOwed,
|
|
1184
1521
|
mergeThrough,
|
|
1185
1522
|
refSheetsAfter,
|
|
1186
1523
|
refSheetsFor,
|
|
1187
1524
|
rewriteFormula,
|
|
1188
1525
|
sheetTransformer,
|
|
1526
|
+
spanThrough,
|
|
1189
1527
|
transformAxis,
|
|
1190
1528
|
transformGroup,
|
|
1191
1529
|
transformMutation
|