@ai-matrx/office 0.8.22 → 0.8.23
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 -0
- package/dist/collab-sheets-transform.cjs +151 -79
- package/dist/collab-sheets-transform.cjs.map +1 -1
- package/dist/collab-sheets-transform.d.cts +1 -1
- package/dist/collab-sheets-transform.d.ts +1 -1
- package/dist/collab-sheets-transform.js +151 -79
- package/dist/collab-sheets-transform.js.map +1 -1
- package/dist/docs.cjs +74 -1
- package/dist/docs.cjs.map +1 -1
- package/dist/docs.d.cts +52 -1
- package/dist/docs.d.ts +52 -1
- package/dist/docs.js +73 -0
- package/dist/docs.js.map +1 -1
- package/dist/sheets-comment-anchors.cjs +217 -0
- package/dist/sheets-comment-anchors.cjs.map +1 -0
- package/dist/sheets-comment-anchors.d.cts +52 -0
- package/dist/sheets-comment-anchors.d.ts +52 -0
- package/dist/sheets-comment-anchors.js +217 -0
- package/dist/sheets-comment-anchors.js.map +1 -0
- package/dist/univer-collab.cjs +164 -92
- package/dist/univer-collab.cjs.map +1 -1
- package/dist/univer-collab.js +164 -92
- package/dist/univer-collab.js.map +1 -1
- package/package.json +13 -3
|
@@ -45,7 +45,7 @@ interface SheetRange {
|
|
|
45
45
|
* column width, worksheet name. C5b: formula text in cells (`f`, array `ref`) and defined names. Shared
|
|
46
46
|
* formulas (`si`) stay barriers (see transform.ts cellBarrier); ranged resources are C5c.
|
|
47
47
|
*/
|
|
48
|
-
type SheetFamily = "cell" | "structure" | "merge" | "size" | "name" | "defname" | "numfmt" | "count" | "sheet" | "sort";
|
|
48
|
+
type SheetFamily = "cell" | "structure" | "merge" | "size" | "name" | "defname" | "numfmt" | "count" | "sheet" | "sort" | "anchor";
|
|
49
49
|
interface CoveredEntry {
|
|
50
50
|
readonly kind: "covered";
|
|
51
51
|
readonly family: SheetFamily;
|
|
@@ -45,7 +45,7 @@ interface SheetRange {
|
|
|
45
45
|
* column width, worksheet name. C5b: formula text in cells (`f`, array `ref`) and defined names. Shared
|
|
46
46
|
* formulas (`si`) stay barriers (see transform.ts cellBarrier); ranged resources are C5c.
|
|
47
47
|
*/
|
|
48
|
-
type SheetFamily = "cell" | "structure" | "merge" | "size" | "name" | "defname" | "numfmt" | "count" | "sheet" | "sort";
|
|
48
|
+
type SheetFamily = "cell" | "structure" | "merge" | "size" | "name" | "defname" | "numfmt" | "count" | "sheet" | "sort" | "anchor";
|
|
49
49
|
interface CoveredEntry {
|
|
50
50
|
readonly kind: "covered";
|
|
51
51
|
readonly family: SheetFamily;
|
|
@@ -32,6 +32,8 @@ var SHEET_MUTATIONS = {
|
|
|
32
32
|
"sheet.mutation.insert-sheet": covered("sheet", "index", "sheet"),
|
|
33
33
|
"sheet.mutation.remove-sheet": covered("sheet", "sheetIndex", "sheetsLeft"),
|
|
34
34
|
"sheet.mutation.set-worksheet-order": covered("sheet", "fromOrder", "toOrder"),
|
|
35
|
+
// ── covered (C9): our own cell comment anchors (comment-anchor-transform.ts; not emitted by Univer) ──────
|
|
36
|
+
"matrx.mutation.set-comment-anchor": covered("anchor", "anchorId", "cell"),
|
|
35
37
|
"sheet.mutation.reorder-range": covered("sort", "range", "order"),
|
|
36
38
|
// ── never travels ────────────────────────────────────────────────────────────────────────────────
|
|
37
39
|
"formula.mutation.set-formula-calculation-start": never(FORMULA_RESULT),
|
|
@@ -483,6 +485,74 @@ function refSheetsFor(texts, sheets) {
|
|
|
483
485
|
return Object.keys(out).length ? out : void 0;
|
|
484
486
|
}
|
|
485
487
|
|
|
488
|
+
// src/collab/sheets/comment-anchor-transform.ts
|
|
489
|
+
var SET_SHEET_COMMENT_ANCHOR = "matrx.mutation.set-comment-anchor";
|
|
490
|
+
var REMOVE_SHEET = "sheet.mutation.remove-sheet";
|
|
491
|
+
function structuralAxisOp(id, params) {
|
|
492
|
+
const p = params;
|
|
493
|
+
switch (id) {
|
|
494
|
+
case "sheet.mutation.insert-row":
|
|
495
|
+
return p.range ? { axis: "row", op: { kind: "insert", at: p.range.startRow, count: p.range.endRow - p.range.startRow + 1 } } : null;
|
|
496
|
+
case "sheet.mutation.remove-rows":
|
|
497
|
+
return p.range ? { axis: "row", op: { kind: "remove", start: p.range.startRow, count: p.range.endRow - p.range.startRow + 1 } } : null;
|
|
498
|
+
case "sheet.mutation.insert-col":
|
|
499
|
+
return p.range ? { axis: "col", op: { kind: "insert", at: p.range.startColumn, count: p.range.endColumn - p.range.startColumn + 1 } } : null;
|
|
500
|
+
case "sheet.mutation.remove-col":
|
|
501
|
+
return p.range ? { axis: "col", op: { kind: "remove", start: p.range.startColumn, count: p.range.endColumn - p.range.startColumn + 1 } } : null;
|
|
502
|
+
case "sheet.mutation.move-rows":
|
|
503
|
+
return p.sourceRange && p.targetRange ? { axis: "row", op: { kind: "move", from: p.sourceRange.startRow, count: p.sourceRange.endRow - p.sourceRange.startRow + 1, to: p.targetRange.startRow } } : null;
|
|
504
|
+
case "sheet.mutation.move-columns":
|
|
505
|
+
return p.sourceRange && p.targetRange ? {
|
|
506
|
+
axis: "col",
|
|
507
|
+
op: { kind: "move", from: p.sourceRange.startColumn, count: p.sourceRange.endColumn - p.sourceRange.startColumn + 1, to: p.targetRange.startColumn }
|
|
508
|
+
} : null;
|
|
509
|
+
default:
|
|
510
|
+
return null;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
function moveSheetAnchorCell(cell, sheet, id, params) {
|
|
514
|
+
if (String(params.subUnitId ?? "") !== sheet) return cell;
|
|
515
|
+
if (id === REMOVE_SHEET) return null;
|
|
516
|
+
const s = structuralAxisOp(id, params);
|
|
517
|
+
if (!s) return cell;
|
|
518
|
+
if (s.axis === "row") {
|
|
519
|
+
const row = mapIndex(s.op, cell.row);
|
|
520
|
+
return row === null ? null : row === cell.row ? cell : { row, col: cell.col };
|
|
521
|
+
}
|
|
522
|
+
const col = mapIndex(s.op, cell.col);
|
|
523
|
+
return col === null ? null : col === cell.col ? cell : { row: cell.row, col };
|
|
524
|
+
}
|
|
525
|
+
function colName(c) {
|
|
526
|
+
let s = "";
|
|
527
|
+
for (let n = c + 1; n > 0; n = Math.floor((n - 1) / 26)) s = String.fromCharCode(65 + (n - 1) % 26) + s;
|
|
528
|
+
return s;
|
|
529
|
+
}
|
|
530
|
+
var sheetCellName = (cell) => `${colName(cell.col)}${cell.row + 1}`;
|
|
531
|
+
function cellOf(m) {
|
|
532
|
+
const c = m.params.cell;
|
|
533
|
+
return c && typeof c.row === "number" && typeof c.col === "number" ? c : null;
|
|
534
|
+
}
|
|
535
|
+
var ok = (op, lost = [], dropped = []) => ({ op, lost, dropped });
|
|
536
|
+
var label = (m) => {
|
|
537
|
+
const c = cellOf(m);
|
|
538
|
+
return `${String(m.params.subUnitId ?? "")}!${c ? sheetCellName(c) : "?"} comment`;
|
|
539
|
+
};
|
|
540
|
+
function transformCommentAnchor(x, y, side) {
|
|
541
|
+
const xa = x.id === SET_SHEET_COMMENT_ANCHOR;
|
|
542
|
+
const ya = y.id === SET_SHEET_COMMENT_ANCHOR;
|
|
543
|
+
if (!xa && !ya) return null;
|
|
544
|
+
if (!xa) return ok([x]);
|
|
545
|
+
if (ya) {
|
|
546
|
+
if (x.params.anchorId !== y.params.anchorId || x.params.subUnitId !== y.params.subUnitId) return ok([x]);
|
|
547
|
+
return side === "left" ? ok([x], [label(y)]) : ok([], [], [label(x)]);
|
|
548
|
+
}
|
|
549
|
+
const cell = cellOf(x);
|
|
550
|
+
if (!cell) return ok([x]);
|
|
551
|
+
const moved = moveSheetAnchorCell(cell, String(x.params.subUnitId ?? ""), y.id, y.params);
|
|
552
|
+
if (!moved) return ok([], [], [label(x)]);
|
|
553
|
+
return ok([moved === cell ? x : { id: x.id, params: { ...x.params, cell: moved } }]);
|
|
554
|
+
}
|
|
555
|
+
|
|
486
556
|
// src/collab/sheets/transform/transform.ts
|
|
487
557
|
var SHEET_TRANSFORMER_VERSION = "c5c-1";
|
|
488
558
|
var ID = {
|
|
@@ -514,16 +584,16 @@ var ID = {
|
|
|
514
584
|
var PAIR_BARRIERS = {};
|
|
515
585
|
var pairKey = (a, b) => a < b ? `${a}|${b}` : `${b}|${a}`;
|
|
516
586
|
var barrier2 = (reason) => ({ barrier: true, reason });
|
|
517
|
-
var
|
|
587
|
+
var ok2 = (op, lost = [], dropped = []) => ({ op, lost, dropped });
|
|
518
588
|
var flip = (side) => side === "left" ? "right" : "left";
|
|
519
589
|
var sheetOf = (m) => String(m.params.subUnitId ?? "");
|
|
520
|
-
function
|
|
590
|
+
function colName2(c) {
|
|
521
591
|
let s = "";
|
|
522
592
|
for (let n = c + 1; n > 0; n = Math.floor((n - 1) / 26)) s = String.fromCharCode(65 + (n - 1) % 26) + s;
|
|
523
593
|
return s;
|
|
524
594
|
}
|
|
525
|
-
var cellRef = (sheet, row, col) => `${sheet}!${
|
|
526
|
-
var rangeRef = (sheet, r) => `${sheet}!${
|
|
595
|
+
var cellRef = (sheet, row, col) => `${sheet}!${colName2(col)}${row + 1}`;
|
|
596
|
+
var rangeRef = (sheet, r) => `${sheet}!${colName2(r.startColumn)}${r.startRow + 1}:${colName2(r.endColumn)}${r.endRow + 1}`;
|
|
527
597
|
function structuralOf(m) {
|
|
528
598
|
const p = m.params;
|
|
529
599
|
switch (m.id) {
|
|
@@ -778,9 +848,9 @@ function transformCell(X, Y, side) {
|
|
|
778
848
|
return { entries: Object.keys(out).length ? [out, ...tail] : tail, xLost, yLost };
|
|
779
849
|
}
|
|
780
850
|
function transformCellsOverCells(x, y, side) {
|
|
781
|
-
if (sheetOf(x) !== sheetOf(y)) return
|
|
851
|
+
if (sheetOf(x) !== sheetOf(y)) return ok2([x]);
|
|
782
852
|
const ycells = cellsOf(y);
|
|
783
|
-
if (!cellsOverlap(cellsOf(x), ycells)) return
|
|
853
|
+
if (!cellsOverlap(cellsOf(x), ycells)) return ok2([x]);
|
|
784
854
|
const xd = isDerived(x);
|
|
785
855
|
const yd = isDerived(y);
|
|
786
856
|
const eff = derivedSide(x, y, side);
|
|
@@ -806,7 +876,7 @@ function transformCellsOverCells(x, y, side) {
|
|
|
806
876
|
});
|
|
807
877
|
if (why) return barrier2(why);
|
|
808
878
|
const op = passes.filter((p) => !isEmptyMatrix(p)).map((p) => cellsMutation(x, p));
|
|
809
|
-
return
|
|
879
|
+
return ok2(op, lost, dropped);
|
|
810
880
|
}
|
|
811
881
|
var SIDE_CAR_PARAMS = ["refSheets", "previousName", "derived", "sheetIndex", "sheetsLeft"];
|
|
812
882
|
var isDerived = (m) => m.params.derived === true;
|
|
@@ -877,7 +947,7 @@ function cellThrough(sheet, change, r, c) {
|
|
|
877
947
|
return nr === null || nc === null ? null : [nr, nc];
|
|
878
948
|
}
|
|
879
949
|
function cellsOverChange(x, change) {
|
|
880
|
-
if (!hasFormula(x) && (change.kind !== "axis" || change.sheet !== sheetOf(x))) return
|
|
950
|
+
if (!hasFormula(x) && (change.kind !== "axis" || change.sheet !== sheetOf(x))) return ok2([x]);
|
|
881
951
|
const ctx = formulaCtx(x);
|
|
882
952
|
const out = {};
|
|
883
953
|
const dropped = [];
|
|
@@ -906,9 +976,9 @@ function cellsOverChange(x, change) {
|
|
|
906
976
|
});
|
|
907
977
|
if (why) return barrier2(why);
|
|
908
978
|
const rsAfter = refSheetsAfter(ctx.refSheets, change);
|
|
909
|
-
if (!changed && JSON.stringify(rsAfter ?? null) === JSON.stringify(ctx.refSheets ?? null)) return
|
|
979
|
+
if (!changed && JSON.stringify(rsAfter ?? null) === JSON.stringify(ctx.refSheets ?? null)) return ok2([x]);
|
|
910
980
|
const params = { ...withRefSheets(x.params, rsAfter), cellValue: out };
|
|
911
|
-
return
|
|
981
|
+
return ok2(isEmptyMatrix(out) ? [] : [{ id: x.id, params }], [], dropped);
|
|
912
982
|
}
|
|
913
983
|
function rewritesOf(y, change) {
|
|
914
984
|
if (!hasFormula(y)) return null;
|
|
@@ -955,36 +1025,36 @@ function formulaPair(x, y, side) {
|
|
|
955
1025
|
const fy = familyOf(y.id);
|
|
956
1026
|
const SET_NAME_BARRIER = "set-defined-name without previousName (capture must record the name it replaces) against formula text";
|
|
957
1027
|
if (fx === "defname" && fy === "defname") {
|
|
958
|
-
if (String(x.params.id) !== String(y.params.id)) return
|
|
1028
|
+
if (String(x.params.id) !== String(y.params.id)) return ok2([x]);
|
|
959
1029
|
const eff = derivedSide(x, y, side);
|
|
960
|
-
if (eff === "left") return
|
|
961
|
-
return
|
|
1030
|
+
if (eff === "left") return ok2([x], isDerived(y) ? [] : [`defined name "${String(y.params.name)}"`]);
|
|
1031
|
+
return ok2([], [], isDerived(x) ? [] : [`defined name "${String(x.params.name)}"`]);
|
|
962
1032
|
}
|
|
963
1033
|
if (fx === "defname") {
|
|
964
1034
|
if (fy === "cell") {
|
|
965
1035
|
if (setNameWithoutPrevious(x) && hasFormula(y)) return barrier2(SET_NAME_BARRIER);
|
|
966
1036
|
const ch2 = refChangeOf(x);
|
|
967
|
-
if (!ch2) return
|
|
1037
|
+
if (!ch2) return ok2([x]);
|
|
968
1038
|
const add = rewritesOf(y, ch2);
|
|
969
1039
|
if (typeof add === "string") return barrier2(add);
|
|
970
|
-
return
|
|
1040
|
+
return ok2(add ? [x, add] : [x]);
|
|
971
1041
|
}
|
|
972
1042
|
const ch = refChangeOf(y);
|
|
973
|
-
if (!ch) return
|
|
1043
|
+
if (!ch) return ok2([x]);
|
|
974
1044
|
const r = definedNameThrough(x, ch);
|
|
975
|
-
return typeof r === "string" ? barrier2(r) :
|
|
1045
|
+
return typeof r === "string" ? barrier2(r) : ok2([r.op]);
|
|
976
1046
|
}
|
|
977
1047
|
if (fy === "defname") {
|
|
978
1048
|
if (fx === "cell") {
|
|
979
1049
|
if (setNameWithoutPrevious(y) && hasFormula(x)) return barrier2(SET_NAME_BARRIER);
|
|
980
1050
|
const ch2 = refChangeOf(y);
|
|
981
|
-
return ch2 ? cellsOverChange(x, ch2) :
|
|
1051
|
+
return ch2 ? cellsOverChange(x, ch2) : ok2([x]);
|
|
982
1052
|
}
|
|
983
1053
|
const ch = refChangeOf(x);
|
|
984
|
-
if (!ch) return
|
|
1054
|
+
if (!ch) return ok2([x]);
|
|
985
1055
|
const r = definedNameThrough(y, ch);
|
|
986
1056
|
if (typeof r === "string") return barrier2(r);
|
|
987
|
-
return
|
|
1057
|
+
return ok2(r.changed ? [x, asDerived(r.op)] : [x]);
|
|
988
1058
|
}
|
|
989
1059
|
if (fx === "cell") {
|
|
990
1060
|
const ch = refChangeOf(y);
|
|
@@ -999,7 +1069,7 @@ function formulaPair(x, y, side) {
|
|
|
999
1069
|
});
|
|
1000
1070
|
const add = rewritesOf(y, ch);
|
|
1001
1071
|
if (typeof add === "string") return barrier2(add);
|
|
1002
|
-
return
|
|
1072
|
+
return ok2(add ? [x, add] : [x], lost);
|
|
1003
1073
|
}
|
|
1004
1074
|
return null;
|
|
1005
1075
|
}
|
|
@@ -1147,20 +1217,20 @@ function numfmtPair(x, y, side, sx, sy) {
|
|
|
1147
1217
|
const nx = isNumfmt(x);
|
|
1148
1218
|
const ny = isNumfmt(y);
|
|
1149
1219
|
if (!nx && !ny) return null;
|
|
1150
|
-
if (nx && sy) return
|
|
1151
|
-
if (ny && sx) return
|
|
1220
|
+
if (nx && sy) return ok2(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsThrough(sy, p.ranges) }))));
|
|
1221
|
+
if (ny && sx) return ok2([x]);
|
|
1152
1222
|
if (nx && ny) {
|
|
1153
|
-
if (side === "left") return
|
|
1223
|
+
if (side === "left") return ok2([x]);
|
|
1154
1224
|
const ys = nfParts(y).flatMap((p) => p.ranges);
|
|
1155
|
-
return
|
|
1225
|
+
return ok2(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsMinus(p.ranges, ys) }))));
|
|
1156
1226
|
}
|
|
1157
1227
|
if (nx && y.id === ID.values) {
|
|
1158
|
-
if (side === "left") return
|
|
1228
|
+
if (side === "left") return ok2([x]);
|
|
1159
1229
|
const ys = nWrites(y);
|
|
1160
|
-
return ys.length ?
|
|
1230
|
+
return ys.length ? ok2(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsMinus(p.ranges, ys) })))) : ok2([x]);
|
|
1161
1231
|
}
|
|
1162
1232
|
if (ny && x.id === ID.values) {
|
|
1163
|
-
if (side === "left") return
|
|
1233
|
+
if (side === "left") return ok2([x]);
|
|
1164
1234
|
const out = {};
|
|
1165
1235
|
const tail = {};
|
|
1166
1236
|
let touched = false;
|
|
@@ -1186,31 +1256,31 @@ function numfmtPair(x, y, side, sx, sy) {
|
|
|
1186
1256
|
}
|
|
1187
1257
|
putCell(out, r, c, v);
|
|
1188
1258
|
});
|
|
1189
|
-
if (!touched) return
|
|
1259
|
+
if (!touched) return ok2([x]);
|
|
1190
1260
|
const ops = [];
|
|
1191
1261
|
if (!isEmptyMatrix(out)) ops.push(cellsMutation(x, out));
|
|
1192
1262
|
if (!isEmptyMatrix(tail)) ops.push({ id: ID.values, params: { subUnitId: sheetOf(x), cellValue: tail } });
|
|
1193
|
-
return
|
|
1263
|
+
return ok2(ops);
|
|
1194
1264
|
}
|
|
1195
|
-
return
|
|
1265
|
+
return ok2([x]);
|
|
1196
1266
|
}
|
|
1197
1267
|
var isCount = (m) => m.id === ID.rowCount || m.id === ID.colCount;
|
|
1198
1268
|
var countAxis = (m) => m.id === ID.rowCount ? "row" : "col";
|
|
1199
1269
|
var countKey = (m) => m.id === ID.rowCount ? "rowCount" : "columnCount";
|
|
1200
1270
|
function countPair(x, y, sy) {
|
|
1201
|
-
if (!isCount(x)) return isCount(y) ?
|
|
1271
|
+
if (!isCount(x)) return isCount(y) ? ok2([x]) : null;
|
|
1202
1272
|
const k = countKey(x);
|
|
1203
1273
|
const v = Number(x.params[k]);
|
|
1204
1274
|
if (sy) {
|
|
1205
|
-
if (sy.axis !== countAxis(x) || sy.op.kind === "move") return
|
|
1275
|
+
if (sy.axis !== countAxis(x) || sy.op.kind === "move") return ok2([x]);
|
|
1206
1276
|
const d = sy.op.kind === "insert" ? sy.op.count : -sy.op.count;
|
|
1207
|
-
return
|
|
1277
|
+
return ok2([{ id: x.id, params: { ...x.params, [k]: Math.max(1, v + d) } }]);
|
|
1208
1278
|
}
|
|
1209
1279
|
if (isCount(y) && y.id === x.id) {
|
|
1210
1280
|
const w = Number(y.params[k]);
|
|
1211
|
-
return
|
|
1281
|
+
return ok2([w > v ? { id: x.id, params: { ...x.params, [k]: w } } : x]);
|
|
1212
1282
|
}
|
|
1213
|
-
return
|
|
1283
|
+
return ok2([x]);
|
|
1214
1284
|
}
|
|
1215
1285
|
var isSheetOp = (m) => m.id === ID.insertSheet || m.id === ID.removeSheet || m.id === ID.sheetOrder;
|
|
1216
1286
|
var sheetIdOf = (m) => m.id === ID.insertSheet ? String(m.params.sheet?.id ?? "") : sheetOf(m);
|
|
@@ -1243,31 +1313,31 @@ function sheetPair(x, y, side) {
|
|
|
1243
1313
|
const b = sheetAxisOf(y);
|
|
1244
1314
|
if (!a || !b) return barrier2("a sheet add or remove without its index (capture must call annotateSheetOps)");
|
|
1245
1315
|
if (x.id === ID.insertSheet && y.id === ID.insertSheet && sheetIdOf(x) === sheetIdOf(y)) {
|
|
1246
|
-
return JSON.stringify(x.params) === JSON.stringify(y.params) ?
|
|
1316
|
+
return JSON.stringify(x.params) === JSON.stringify(y.params) ? ok2([]) : barrier2("the same sheet id added twice with different content");
|
|
1247
1317
|
}
|
|
1248
1318
|
if (x.id === ID.removeSheet && typeof x.params.sheetsLeft === "number" && sheetIdOf(x) !== sheetIdOf(y) && (y.id === ID.removeSheet || y.id === ID.insertSheet)) {
|
|
1249
1319
|
const left = x.params.sheetsLeft + (y.id === ID.insertSheet ? 1 : -1);
|
|
1250
1320
|
if (left < 1) return barrier2("concurrent sheet removes would leave the workbook without a sheet");
|
|
1251
1321
|
const out2 = transformAxis(a, b, side);
|
|
1252
1322
|
if (!out2) return barrier2("sheet order: no transform");
|
|
1253
|
-
return
|
|
1323
|
+
return ok2(out2.map((o) => buildSheetOp({ id: x.id, params: { ...x.params, sheetsLeft: left } }, o)));
|
|
1254
1324
|
}
|
|
1255
1325
|
const out = transformAxis(a, b, side);
|
|
1256
1326
|
if (!out) return barrier2("sheet order: no transform");
|
|
1257
|
-
return
|
|
1327
|
+
return ok2(out.map((o) => buildSheetOp(x, o)), [], out.length === 0 && x.id === ID.sheetOrder ? [`${sheetIdOf(x)}: sheet order`] : []);
|
|
1258
1328
|
}
|
|
1259
1329
|
if (ys) {
|
|
1260
|
-
if (y.id !== ID.removeSheet) return
|
|
1330
|
+
if (y.id !== ID.removeSheet) return ok2([x]);
|
|
1261
1331
|
const gone2 = sheetOf(y);
|
|
1262
1332
|
if (namesSheet(x, gone2)) return barrier2("a formula names a sheet removed at the same time");
|
|
1263
1333
|
if (sheetOf(x) === gone2 && x.id !== ID.setName && x.id !== ID.removeName)
|
|
1264
|
-
return
|
|
1265
|
-
return
|
|
1334
|
+
return ok2([], [], isDerived(x) ? [] : [`${gone2}: the sheet was removed`]);
|
|
1335
|
+
return ok2([x]);
|
|
1266
1336
|
}
|
|
1267
|
-
if (x.id !== ID.removeSheet) return
|
|
1337
|
+
if (x.id !== ID.removeSheet) return ok2([x]);
|
|
1268
1338
|
const gone = sheetOf(x);
|
|
1269
1339
|
if (namesSheet(y, gone)) return barrier2("a formula names a sheet removed at the same time");
|
|
1270
|
-
return
|
|
1340
|
+
return ok2([x], sheetOf(y) === gone && !isDerived(y) && y.id !== ID.setName && y.id !== ID.removeName ? [`${gone}: the sheet was removed`] : []);
|
|
1271
1341
|
}
|
|
1272
1342
|
function annotateSheetOps(group, sheetOrder) {
|
|
1273
1343
|
const order = [...sheetOrder];
|
|
@@ -1365,22 +1435,22 @@ function sortPair(x, y, sx, sy) {
|
|
|
1365
1435
|
const a = sortOf(x).range;
|
|
1366
1436
|
const b = sortOf(y).range;
|
|
1367
1437
|
const overlap = a.startRow <= b.endRow && b.startRow <= a.endRow && a.startColumn <= b.endColumn && b.startColumn <= a.endColumn;
|
|
1368
|
-
return overlap ? barrier2("two sorts of overlapping ranges at once") :
|
|
1438
|
+
return overlap ? barrier2("two sorts of overlapping ranges at once") : ok2([x]);
|
|
1369
1439
|
}
|
|
1370
1440
|
if (xs) {
|
|
1371
1441
|
if (sy) {
|
|
1372
1442
|
const t = sortThrough(sortOf(x), sy);
|
|
1373
|
-
return t ?
|
|
1443
|
+
return t ? ok2(buildSort(x, t)) : barrier2("a row or column move through a sorted range");
|
|
1374
1444
|
}
|
|
1375
|
-
return
|
|
1445
|
+
return ok2([x]);
|
|
1376
1446
|
}
|
|
1377
1447
|
const o = sortOf(y);
|
|
1378
1448
|
const Q = sortQ(o);
|
|
1379
1449
|
const moved = (r) => r >= o.range.startRow && r <= o.range.endRow && Q.has(r);
|
|
1380
1450
|
if (sx) {
|
|
1381
|
-
if (sx.axis === "col") return sx.op.kind === "move" && !sortThrough(o, sx) ? barrier2("a column move through a sorted range") :
|
|
1382
|
-
if (sx.op.kind === "insert") return
|
|
1383
|
-
if (sx.op.kind === "move") return sortThrough(o, sx) ?
|
|
1451
|
+
if (sx.axis === "col") return sx.op.kind === "move" && !sortThrough(o, sx) ? barrier2("a column move through a sorted range") : ok2([x]);
|
|
1452
|
+
if (sx.op.kind === "insert") return ok2([x]);
|
|
1453
|
+
if (sx.op.kind === "move") return sortThrough(o, sx) ? ok2([x]) : barrier2("a row move through a sorted range");
|
|
1384
1454
|
const rows = [];
|
|
1385
1455
|
let partial = false;
|
|
1386
1456
|
for (let i = sx.op.start; i < sx.op.start + sx.op.count; i++) {
|
|
@@ -1388,7 +1458,7 @@ function sortPair(x, y, sx, sy) {
|
|
|
1388
1458
|
rows.push(Q.get(i) ?? i);
|
|
1389
1459
|
}
|
|
1390
1460
|
if (partial) return barrier2("a row remove against a concurrent sort of those rows");
|
|
1391
|
-
return
|
|
1461
|
+
return ok2([x]);
|
|
1392
1462
|
}
|
|
1393
1463
|
if (x.id === ID.values) {
|
|
1394
1464
|
const out = {};
|
|
@@ -1399,7 +1469,7 @@ function sortPair(x, y, sx, sy) {
|
|
|
1399
1469
|
changed = true;
|
|
1400
1470
|
} else putCell(out, r, c, v);
|
|
1401
1471
|
});
|
|
1402
|
-
return changed ?
|
|
1472
|
+
return changed ? ok2([cellsMutation(x, out)]) : ok2([x]);
|
|
1403
1473
|
}
|
|
1404
1474
|
if (isNumfmt(x)) {
|
|
1405
1475
|
const parts = nfParts(x).map((p) => {
|
|
@@ -1415,9 +1485,9 @@ function sortPair(x, y, sx, sy) {
|
|
|
1415
1485
|
}
|
|
1416
1486
|
return { ...p, ranges };
|
|
1417
1487
|
});
|
|
1418
|
-
return
|
|
1488
|
+
return ok2(nfBuild(x, parts));
|
|
1419
1489
|
}
|
|
1420
|
-
return
|
|
1490
|
+
return ok2([x]);
|
|
1421
1491
|
}
|
|
1422
1492
|
function familyOf(id) {
|
|
1423
1493
|
const e = SHEET_MUTATIONS[id];
|
|
@@ -1433,13 +1503,15 @@ function transformMutation(x, y, side) {
|
|
|
1433
1503
|
if (why) return barrier2(why);
|
|
1434
1504
|
}
|
|
1435
1505
|
}
|
|
1506
|
+
const ca = transformCommentAnchor(x, y, side);
|
|
1507
|
+
if (ca) return ca;
|
|
1436
1508
|
const pb = PAIR_BARRIERS[pairKey(x.id, y.id)];
|
|
1437
1509
|
if (pb) return barrier2(`${x.id} \xD7 ${y.id}: ${pb.reason}${pb.seed === null ? "" : ` (fuzz seed ${pb.seed})`}`);
|
|
1438
1510
|
const sp = sheetPair(x, y, side);
|
|
1439
1511
|
if (sp) return sp;
|
|
1440
1512
|
const fp = formulaPair(x, y, side);
|
|
1441
1513
|
if (fp) return fp;
|
|
1442
|
-
if (sheetOf(x) !== sheetOf(y)) return
|
|
1514
|
+
if (sheetOf(x) !== sheetOf(y)) return ok2([x]);
|
|
1443
1515
|
const fx = familyOf(x.id);
|
|
1444
1516
|
const fy = familyOf(y.id);
|
|
1445
1517
|
const sy = structuralOf(y);
|
|
@@ -1451,11 +1523,11 @@ function transformMutation(x, y, side) {
|
|
|
1451
1523
|
const np = numfmtPair(x, y, side, sx, sy);
|
|
1452
1524
|
if (np) return np;
|
|
1453
1525
|
if (sx && sy) {
|
|
1454
|
-
if (sx.axis !== sy.axis) return
|
|
1526
|
+
if (sx.axis !== sy.axis) return ok2([x]);
|
|
1455
1527
|
const out = transformAxis(sx.op, sy.op, side);
|
|
1456
1528
|
if (!out) return barrier2(`${x.id} over ${y.id}: moved blocks overlap in part, or the block would split`);
|
|
1457
1529
|
const dropped = out.length === 0 && sx.op.kind === "move" ? [`${sheetOf(x)}: moved ${sx.axis}s`] : [];
|
|
1458
|
-
return
|
|
1530
|
+
return ok2(out.map((o) => buildStructural(x, sx.axis, o)), [], dropped);
|
|
1459
1531
|
}
|
|
1460
1532
|
if (sy) {
|
|
1461
1533
|
if (fx === "merge") {
|
|
@@ -1466,23 +1538,23 @@ function transformMutation(x, y, side) {
|
|
|
1466
1538
|
if (t) kept.push(t);
|
|
1467
1539
|
else dropped.push(rangeRef(sheetOf(x), r));
|
|
1468
1540
|
}
|
|
1469
|
-
return
|
|
1541
|
+
return ok2(kept.length ? [withRanges(x, kept)] : [], [], x.id === ID.addMerge ? dropped : []);
|
|
1470
1542
|
}
|
|
1471
1543
|
if (fx === "size") {
|
|
1472
1544
|
const size = sizeOf(x);
|
|
1473
|
-
if (size.axis !== sy.axis) return
|
|
1545
|
+
if (size.axis !== sy.axis) return ok2([x]);
|
|
1474
1546
|
const next = /* @__PURE__ */ new Map();
|
|
1475
1547
|
for (const [i, v] of size.values) {
|
|
1476
1548
|
const m = mapIndex(sy.op, i);
|
|
1477
1549
|
if (m !== null) next.set(m, v);
|
|
1478
1550
|
}
|
|
1479
1551
|
const built = buildSize(x, next);
|
|
1480
|
-
return
|
|
1552
|
+
return ok2(built ? [built] : []);
|
|
1481
1553
|
}
|
|
1482
|
-
return
|
|
1554
|
+
return ok2([x]);
|
|
1483
1555
|
}
|
|
1484
1556
|
if (sx) {
|
|
1485
|
-
if (fy !== "merge" || y.id !== ID.addMerge) return
|
|
1557
|
+
if (fy !== "merge" || y.id !== ID.addMerge) return ok2([x]);
|
|
1486
1558
|
const remove = [];
|
|
1487
1559
|
const add = [];
|
|
1488
1560
|
for (const r of mergeRanges(y)) {
|
|
@@ -1492,11 +1564,11 @@ function transformMutation(x, y, side) {
|
|
|
1492
1564
|
if (t.range) add.push(t.range);
|
|
1493
1565
|
}
|
|
1494
1566
|
const lostMerges = mergeRanges(y).filter((r) => mergeThrough(sx, r).range === null).map((r) => rangeRef(sheetOf(y), r));
|
|
1495
|
-
if (!remove.length) return
|
|
1567
|
+
if (!remove.length) return ok2([x], lostMerges);
|
|
1496
1568
|
const sheet = sheetOf(x);
|
|
1497
1569
|
const pre = sx.op.kind === "insert" ? [] : [mergeMutation(ID.removeMerge, sheet, remove)];
|
|
1498
1570
|
const mid = sx.op.kind === "insert" ? [mergeMutation(ID.removeMerge, sheet, remove)] : [];
|
|
1499
|
-
return
|
|
1571
|
+
return ok2([...pre, x, ...mid, ...add.length ? [mergeMutation(ID.addMerge, sheet, add)] : []], lostMerges);
|
|
1500
1572
|
}
|
|
1501
1573
|
if (fx === "cell" && fy === "cell") return transformCellsOverCells(x, y, side);
|
|
1502
1574
|
if (fx === "merge" && fy === "merge") {
|
|
@@ -1505,45 +1577,45 @@ function transformMutation(x, y, side) {
|
|
|
1505
1577
|
const hit = (r) => yr.some((q) => intersects(r, q));
|
|
1506
1578
|
const sheet = sheetOf(x);
|
|
1507
1579
|
if (x.id === ID.addMerge && y.id === ID.addMerge) {
|
|
1508
|
-
if (!xr.some(hit)) return
|
|
1580
|
+
if (!xr.some(hit)) return ok2([x]);
|
|
1509
1581
|
if (side === "left") {
|
|
1510
1582
|
const lost = yr.filter((q) => xr.some((r) => intersects(r, q))).map((q) => rangeRef(sheet, q));
|
|
1511
|
-
return
|
|
1583
|
+
return ok2([mergeMutation(ID.removeMerge, sheet, xr.filter(hit)), x], lost);
|
|
1512
1584
|
}
|
|
1513
1585
|
const kept = xr.filter((r) => !hit(r));
|
|
1514
|
-
return
|
|
1586
|
+
return ok2(kept.length ? [withRanges(x, kept)] : [], [], xr.filter(hit).map((r) => rangeRef(sheet, r)));
|
|
1515
1587
|
}
|
|
1516
1588
|
if (x.id === ID.addMerge && y.id === ID.removeMerge) {
|
|
1517
|
-
if (side === "left" || !xr.some(hit)) return
|
|
1589
|
+
if (side === "left" || !xr.some(hit)) return ok2([x], side === "left" && xr.some(hit) ? yr.filter((q) => xr.some((r) => intersects(r, q))).map((q) => rangeRef(sheet, q)) : []);
|
|
1518
1590
|
const kept = xr.filter((r) => !hit(r));
|
|
1519
|
-
return
|
|
1591
|
+
return ok2(kept.length ? [withRanges(x, kept)] : [], [], xr.filter(hit).map((r) => rangeRef(sheet, r)));
|
|
1520
1592
|
}
|
|
1521
1593
|
if (x.id === ID.removeMerge && y.id === ID.addMerge) {
|
|
1522
1594
|
const touched = yr.filter((q) => xr.some((r) => intersects(r, q)));
|
|
1523
|
-
if (!touched.length) return
|
|
1524
|
-
if (side === "left") return
|
|
1525
|
-
return
|
|
1595
|
+
if (!touched.length) return ok2([x]);
|
|
1596
|
+
if (side === "left") return ok2([x], touched.map((q) => rangeRef(sheet, q)));
|
|
1597
|
+
return ok2([x, mergeMutation(ID.addMerge, sheet, touched)], [], xr.filter(hit).map((r) => rangeRef(sheet, r)));
|
|
1526
1598
|
}
|
|
1527
|
-
return
|
|
1599
|
+
return ok2([x]);
|
|
1528
1600
|
}
|
|
1529
1601
|
if (fx === "size" && fy === "size") {
|
|
1530
1602
|
const a = sizeOf(x);
|
|
1531
1603
|
const b = sizeOf(y);
|
|
1532
|
-
if (a.axis !== b.axis || a.attr !== b.attr) return
|
|
1604
|
+
if (a.axis !== b.axis || a.attr !== b.attr) return ok2([x]);
|
|
1533
1605
|
if (side === "left") {
|
|
1534
1606
|
const lost = [...a.values.keys()].filter((i) => b.values.has(i)).map((i) => `${sheetOf(x)}: ${a.axis} ${i + 1} ${a.attr}`);
|
|
1535
|
-
return
|
|
1607
|
+
return ok2([x], lost);
|
|
1536
1608
|
}
|
|
1537
1609
|
const next = new Map([...a.values].filter(([i]) => !b.values.has(i)));
|
|
1538
1610
|
const built = buildSize(x, next);
|
|
1539
1611
|
const dropped = [...a.values.keys()].filter((i) => b.values.has(i)).map((i) => `${sheetOf(x)}: ${a.axis} ${i + 1} ${a.attr}`);
|
|
1540
|
-
return
|
|
1612
|
+
return ok2(built ? [built] : [], [], dropped);
|
|
1541
1613
|
}
|
|
1542
1614
|
if (fx === "name" && fy === "name") {
|
|
1543
|
-
if (side === "left") return
|
|
1544
|
-
return
|
|
1615
|
+
if (side === "left") return ok2([x], [`${sheetOf(x)}: name "${String(y.params.name)}"`]);
|
|
1616
|
+
return ok2([], [], [`${sheetOf(x)}: name "${String(x.params.name)}"`]);
|
|
1545
1617
|
}
|
|
1546
|
-
return
|
|
1618
|
+
return ok2([x]);
|
|
1547
1619
|
}
|
|
1548
1620
|
var blocked = (p) => !Array.isArray(p);
|
|
1549
1621
|
function tSeq(xs, ys, side, acc) {
|