@ai-matrx/office 0.8.21 → 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.
@@ -1193,25 +1193,25 @@ function rebaseUndoStack(items, remote) {
1193
1193
  let dropped = 0;
1194
1194
  for (let i = items.length - 1; i >= 0; i--) {
1195
1195
  const item = items[i];
1196
- let ok2 = true;
1196
+ let ok3 = true;
1197
1197
  for (const list of [item.undoMutations, item.redoMutations]) {
1198
1198
  for (const m of list ?? []) {
1199
1199
  if (m.id !== RICH_TEXT_EDITING) continue;
1200
1200
  try {
1201
1201
  if (touchesPageSetup(m.params.actions) && touchesPageSetup(remote)) throw new Error("page setup");
1202
1202
  const r = transformDocsOp(m.params.actions, remote, "left");
1203
- if (isNoopDocsOp(r.op)) ok2 = false;
1203
+ if (isNoopDocsOp(r.op)) ok3 = false;
1204
1204
  else {
1205
1205
  m.params = { ...m.params, actions: r.op };
1206
1206
  delete m.params.textRanges;
1207
1207
  delete m.params.layoutState;
1208
1208
  }
1209
1209
  } catch {
1210
- ok2 = false;
1210
+ ok3 = false;
1211
1211
  }
1212
1212
  }
1213
1213
  }
1214
- if (!ok2) {
1214
+ if (!ok3) {
1215
1215
  items.splice(i, 1);
1216
1216
  dropped++;
1217
1217
  }
@@ -1766,6 +1766,9 @@ var SHEET_MUTATIONS = {
1766
1766
  "sheet.mutation.insert-sheet": covered("sheet", "index", "sheet"),
1767
1767
  "sheet.mutation.remove-sheet": covered("sheet", "sheetIndex", "sheetsLeft"),
1768
1768
  "sheet.mutation.set-worksheet-order": covered("sheet", "fromOrder", "toOrder"),
1769
+ // ── covered (C9): our own cell comment anchors (comment-anchor-transform.ts; not emitted by Univer) ──────
1770
+ "matrx.mutation.set-comment-anchor": covered("anchor", "anchorId", "cell"),
1771
+ "sheet.mutation.reorder-range": covered("sort", "range", "order"),
1769
1772
  // ── never travels ────────────────────────────────────────────────────────────────────────────────
1770
1773
  "formula.mutation.set-formula-calculation-start": never(FORMULA_RESULT),
1771
1774
  "formula.mutation.set-trigger-formula-calculation-start": never(FORMULA_RESULT),
@@ -1799,7 +1802,6 @@ var SHEET_MUTATIONS = {
1799
1802
  "thread-comment.mutation.resolve-comment": never(UNIVER_COMMENTS),
1800
1803
  "thread-comment.mutation.delete-comment": never(UNIVER_COMMENTS),
1801
1804
  // ── barriers: X (no transform yet, design §10) ───────────────────────────────────────────────────
1802
- "sheet.mutation.reorder-range": barrier("X", "sort: a permutation, not transformed yet"),
1803
1805
  "sheet.mutation.move-range": barrier("X", "cut-paste carries the sender's cell matrices"),
1804
1806
  "sheet.mutation.set-worksheet-hidden": barrier("X", "sheet-level setting: not in C5a"),
1805
1807
  "sheet.mutation.set-tab-color": barrier("X", "sheet-level setting: not in C5a"),
@@ -2208,6 +2210,74 @@ function refSheetsFor(texts, sheets) {
2208
2210
  return Object.keys(out).length ? out : void 0;
2209
2211
  }
2210
2212
 
2213
+ // src/collab/sheets/comment-anchor-transform.ts
2214
+ var SET_SHEET_COMMENT_ANCHOR = "matrx.mutation.set-comment-anchor";
2215
+ var REMOVE_SHEET = "sheet.mutation.remove-sheet";
2216
+ function structuralAxisOp(id, params) {
2217
+ const p = params;
2218
+ switch (id) {
2219
+ case "sheet.mutation.insert-row":
2220
+ return p.range ? { axis: "row", op: { kind: "insert", at: p.range.startRow, count: p.range.endRow - p.range.startRow + 1 } } : null;
2221
+ case "sheet.mutation.remove-rows":
2222
+ return p.range ? { axis: "row", op: { kind: "remove", start: p.range.startRow, count: p.range.endRow - p.range.startRow + 1 } } : null;
2223
+ case "sheet.mutation.insert-col":
2224
+ return p.range ? { axis: "col", op: { kind: "insert", at: p.range.startColumn, count: p.range.endColumn - p.range.startColumn + 1 } } : null;
2225
+ case "sheet.mutation.remove-col":
2226
+ return p.range ? { axis: "col", op: { kind: "remove", start: p.range.startColumn, count: p.range.endColumn - p.range.startColumn + 1 } } : null;
2227
+ case "sheet.mutation.move-rows":
2228
+ 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;
2229
+ case "sheet.mutation.move-columns":
2230
+ return p.sourceRange && p.targetRange ? {
2231
+ axis: "col",
2232
+ op: { kind: "move", from: p.sourceRange.startColumn, count: p.sourceRange.endColumn - p.sourceRange.startColumn + 1, to: p.targetRange.startColumn }
2233
+ } : null;
2234
+ default:
2235
+ return null;
2236
+ }
2237
+ }
2238
+ function moveSheetAnchorCell(cell, sheet, id, params) {
2239
+ if (String(params.subUnitId ?? "") !== sheet) return cell;
2240
+ if (id === REMOVE_SHEET) return null;
2241
+ const s = structuralAxisOp(id, params);
2242
+ if (!s) return cell;
2243
+ if (s.axis === "row") {
2244
+ const row = mapIndex(s.op, cell.row);
2245
+ return row === null ? null : row === cell.row ? cell : { row, col: cell.col };
2246
+ }
2247
+ const col = mapIndex(s.op, cell.col);
2248
+ return col === null ? null : col === cell.col ? cell : { row: cell.row, col };
2249
+ }
2250
+ function colName(c) {
2251
+ let s = "";
2252
+ for (let n = c + 1; n > 0; n = Math.floor((n - 1) / 26)) s = String.fromCharCode(65 + (n - 1) % 26) + s;
2253
+ return s;
2254
+ }
2255
+ var sheetCellName = (cell) => `${colName(cell.col)}${cell.row + 1}`;
2256
+ function cellOf(m) {
2257
+ const c = m.params.cell;
2258
+ return c && typeof c.row === "number" && typeof c.col === "number" ? c : null;
2259
+ }
2260
+ var ok = (op, lost = [], dropped = []) => ({ op, lost, dropped });
2261
+ var label = (m) => {
2262
+ const c = cellOf(m);
2263
+ return `${String(m.params.subUnitId ?? "")}!${c ? sheetCellName(c) : "?"} comment`;
2264
+ };
2265
+ function transformCommentAnchor(x, y, side) {
2266
+ const xa = x.id === SET_SHEET_COMMENT_ANCHOR;
2267
+ const ya = y.id === SET_SHEET_COMMENT_ANCHOR;
2268
+ if (!xa && !ya) return null;
2269
+ if (!xa) return ok([x]);
2270
+ if (ya) {
2271
+ if (x.params.anchorId !== y.params.anchorId || x.params.subUnitId !== y.params.subUnitId) return ok([x]);
2272
+ return side === "left" ? ok([x], [label(y)]) : ok([], [], [label(x)]);
2273
+ }
2274
+ const cell = cellOf(x);
2275
+ if (!cell) return ok([x]);
2276
+ const moved = moveSheetAnchorCell(cell, String(x.params.subUnitId ?? ""), y.id, y.params);
2277
+ if (!moved) return ok([], [], [label(x)]);
2278
+ return ok([moved === cell ? x : { id: x.id, params: { ...x.params, cell: moved } }]);
2279
+ }
2280
+
2211
2281
  // src/collab/sheets/transform/transform.ts
2212
2282
  var SHEET_TRANSFORMER_VERSION = "c5c-1";
2213
2283
  var ID = {
@@ -2233,21 +2303,22 @@ var ID = {
2233
2303
  colCount: "sheet.mutation.set-worksheet-column-count",
2234
2304
  insertSheet: "sheet.mutation.insert-sheet",
2235
2305
  removeSheet: "sheet.mutation.remove-sheet",
2236
- sheetOrder: "sheet.mutation.set-worksheet-order"
2306
+ sheetOrder: "sheet.mutation.set-worksheet-order",
2307
+ sort: "sheet.mutation.reorder-range"
2237
2308
  };
2238
2309
  var PAIR_BARRIERS = {};
2239
2310
  var pairKey = (a, b) => a < b ? `${a}|${b}` : `${b}|${a}`;
2240
2311
  var barrier2 = (reason) => ({ barrier: true, reason });
2241
- var ok = (op, lost = [], dropped = []) => ({ op, lost, dropped });
2312
+ var ok2 = (op, lost = [], dropped = []) => ({ op, lost, dropped });
2242
2313
  var flip = (side) => side === "left" ? "right" : "left";
2243
2314
  var sheetOf = (m) => String(m.params.subUnitId ?? "");
2244
- function colName(c) {
2315
+ function colName2(c) {
2245
2316
  let s = "";
2246
2317
  for (let n = c + 1; n > 0; n = Math.floor((n - 1) / 26)) s = String.fromCharCode(65 + (n - 1) % 26) + s;
2247
2318
  return s;
2248
2319
  }
2249
- var cellRef = (sheet, row, col) => `${sheet}!${colName(col)}${row + 1}`;
2250
- var rangeRef = (sheet, r) => `${sheet}!${colName(r.startColumn)}${r.startRow + 1}:${colName(r.endColumn)}${r.endRow + 1}`;
2320
+ var cellRef = (sheet, row, col) => `${sheet}!${colName2(col)}${row + 1}`;
2321
+ var rangeRef = (sheet, r) => `${sheet}!${colName2(r.startColumn)}${r.startRow + 1}:${colName2(r.endColumn)}${r.endRow + 1}`;
2251
2322
  function structuralOf(m) {
2252
2323
  const p = m.params;
2253
2324
  switch (m.id) {
@@ -2502,9 +2573,9 @@ function transformCell(X, Y4, side) {
2502
2573
  return { entries: Object.keys(out).length ? [out, ...tail] : tail, xLost, yLost };
2503
2574
  }
2504
2575
  function transformCellsOverCells(x, y, side) {
2505
- if (sheetOf(x) !== sheetOf(y)) return ok([x]);
2576
+ if (sheetOf(x) !== sheetOf(y)) return ok2([x]);
2506
2577
  const ycells = cellsOf(y);
2507
- if (!cellsOverlap(cellsOf(x), ycells)) return ok([x]);
2578
+ if (!cellsOverlap(cellsOf(x), ycells)) return ok2([x]);
2508
2579
  const xd = isDerived(x);
2509
2580
  const yd = isDerived(y);
2510
2581
  const eff = derivedSide(x, y, side);
@@ -2530,7 +2601,7 @@ function transformCellsOverCells(x, y, side) {
2530
2601
  });
2531
2602
  if (why) return barrier2(why);
2532
2603
  const op = passes.filter((p) => !isEmptyMatrix(p)).map((p) => cellsMutation(x, p));
2533
- return ok(op, lost, dropped);
2604
+ return ok2(op, lost, dropped);
2534
2605
  }
2535
2606
  var SIDE_CAR_PARAMS = ["refSheets", "previousName", "derived", "sheetIndex", "sheetsLeft"];
2536
2607
  var isDerived = (m) => m.params.derived === true;
@@ -2601,7 +2672,7 @@ function cellThrough(sheet, change, r, c) {
2601
2672
  return nr === null || nc === null ? null : [nr, nc];
2602
2673
  }
2603
2674
  function cellsOverChange(x, change) {
2604
- if (!hasFormula(x) && (change.kind !== "axis" || change.sheet !== sheetOf(x))) return ok([x]);
2675
+ if (!hasFormula(x) && (change.kind !== "axis" || change.sheet !== sheetOf(x))) return ok2([x]);
2605
2676
  const ctx = formulaCtx(x);
2606
2677
  const out = {};
2607
2678
  const dropped = [];
@@ -2630,9 +2701,9 @@ function cellsOverChange(x, change) {
2630
2701
  });
2631
2702
  if (why) return barrier2(why);
2632
2703
  const rsAfter = refSheetsAfter(ctx.refSheets, change);
2633
- if (!changed && JSON.stringify(rsAfter ?? null) === JSON.stringify(ctx.refSheets ?? null)) return ok([x]);
2704
+ if (!changed && JSON.stringify(rsAfter ?? null) === JSON.stringify(ctx.refSheets ?? null)) return ok2([x]);
2634
2705
  const params = { ...withRefSheets(x.params, rsAfter), cellValue: out };
2635
- return ok(isEmptyMatrix(out) ? [] : [{ id: x.id, params }], [], dropped);
2706
+ return ok2(isEmptyMatrix(out) ? [] : [{ id: x.id, params }], [], dropped);
2636
2707
  }
2637
2708
  function rewritesOf(y, change) {
2638
2709
  if (!hasFormula(y)) return null;
@@ -2679,36 +2750,36 @@ function formulaPair(x, y, side) {
2679
2750
  const fy = familyOf(y.id);
2680
2751
  const SET_NAME_BARRIER = "set-defined-name without previousName (capture must record the name it replaces) against formula text";
2681
2752
  if (fx === "defname" && fy === "defname") {
2682
- if (String(x.params.id) !== String(y.params.id)) return ok([x]);
2753
+ if (String(x.params.id) !== String(y.params.id)) return ok2([x]);
2683
2754
  const eff = derivedSide(x, y, side);
2684
- if (eff === "left") return ok([x], isDerived(y) ? [] : [`defined name "${String(y.params.name)}"`]);
2685
- return ok([], [], isDerived(x) ? [] : [`defined name "${String(x.params.name)}"`]);
2755
+ if (eff === "left") return ok2([x], isDerived(y) ? [] : [`defined name "${String(y.params.name)}"`]);
2756
+ return ok2([], [], isDerived(x) ? [] : [`defined name "${String(x.params.name)}"`]);
2686
2757
  }
2687
2758
  if (fx === "defname") {
2688
2759
  if (fy === "cell") {
2689
2760
  if (setNameWithoutPrevious(x) && hasFormula(y)) return barrier2(SET_NAME_BARRIER);
2690
2761
  const ch2 = refChangeOf(x);
2691
- if (!ch2) return ok([x]);
2762
+ if (!ch2) return ok2([x]);
2692
2763
  const add = rewritesOf(y, ch2);
2693
2764
  if (typeof add === "string") return barrier2(add);
2694
- return ok(add ? [x, add] : [x]);
2765
+ return ok2(add ? [x, add] : [x]);
2695
2766
  }
2696
2767
  const ch = refChangeOf(y);
2697
- if (!ch) return ok([x]);
2768
+ if (!ch) return ok2([x]);
2698
2769
  const r = definedNameThrough(x, ch);
2699
- return typeof r === "string" ? barrier2(r) : ok([r.op]);
2770
+ return typeof r === "string" ? barrier2(r) : ok2([r.op]);
2700
2771
  }
2701
2772
  if (fy === "defname") {
2702
2773
  if (fx === "cell") {
2703
2774
  if (setNameWithoutPrevious(y) && hasFormula(x)) return barrier2(SET_NAME_BARRIER);
2704
2775
  const ch2 = refChangeOf(y);
2705
- return ch2 ? cellsOverChange(x, ch2) : ok([x]);
2776
+ return ch2 ? cellsOverChange(x, ch2) : ok2([x]);
2706
2777
  }
2707
2778
  const ch = refChangeOf(x);
2708
- if (!ch) return ok([x]);
2779
+ if (!ch) return ok2([x]);
2709
2780
  const r = definedNameThrough(y, ch);
2710
2781
  if (typeof r === "string") return barrier2(r);
2711
- return ok(r.changed ? [x, asDerived(r.op)] : [x]);
2782
+ return ok2(r.changed ? [x, asDerived(r.op)] : [x]);
2712
2783
  }
2713
2784
  if (fx === "cell") {
2714
2785
  const ch = refChangeOf(y);
@@ -2723,7 +2794,7 @@ function formulaPair(x, y, side) {
2723
2794
  });
2724
2795
  const add = rewritesOf(y, ch);
2725
2796
  if (typeof add === "string") return barrier2(add);
2726
- return ok(add ? [x, add] : [x], lost);
2797
+ return ok2(add ? [x, add] : [x], lost);
2727
2798
  }
2728
2799
  return null;
2729
2800
  }
@@ -2871,20 +2942,20 @@ function numfmtPair(x, y, side, sx, sy) {
2871
2942
  const nx = isNumfmt(x);
2872
2943
  const ny = isNumfmt(y);
2873
2944
  if (!nx && !ny) return null;
2874
- if (nx && sy) return ok(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsThrough(sy, p.ranges) }))));
2875
- if (ny && sx) return ok([x]);
2945
+ if (nx && sy) return ok2(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsThrough(sy, p.ranges) }))));
2946
+ if (ny && sx) return ok2([x]);
2876
2947
  if (nx && ny) {
2877
- if (side === "left") return ok([x]);
2948
+ if (side === "left") return ok2([x]);
2878
2949
  const ys = nfParts(y).flatMap((p) => p.ranges);
2879
- return ok(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsMinus(p.ranges, ys) }))));
2950
+ return ok2(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsMinus(p.ranges, ys) }))));
2880
2951
  }
2881
2952
  if (nx && y.id === ID.values) {
2882
- if (side === "left") return ok([x]);
2953
+ if (side === "left") return ok2([x]);
2883
2954
  const ys = nWrites(y);
2884
- return ys.length ? ok(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsMinus(p.ranges, ys) })))) : ok([x]);
2955
+ return ys.length ? ok2(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsMinus(p.ranges, ys) })))) : ok2([x]);
2885
2956
  }
2886
2957
  if (ny && x.id === ID.values) {
2887
- if (side === "left") return ok([x]);
2958
+ if (side === "left") return ok2([x]);
2888
2959
  const out = {};
2889
2960
  const tail = {};
2890
2961
  let touched = false;
@@ -2910,31 +2981,31 @@ function numfmtPair(x, y, side, sx, sy) {
2910
2981
  }
2911
2982
  putCell(out, r, c, v);
2912
2983
  });
2913
- if (!touched) return ok([x]);
2984
+ if (!touched) return ok2([x]);
2914
2985
  const ops = [];
2915
2986
  if (!isEmptyMatrix(out)) ops.push(cellsMutation(x, out));
2916
2987
  if (!isEmptyMatrix(tail)) ops.push({ id: ID.values, params: { subUnitId: sheetOf(x), cellValue: tail } });
2917
- return ok(ops);
2988
+ return ok2(ops);
2918
2989
  }
2919
- return ok([x]);
2990
+ return ok2([x]);
2920
2991
  }
2921
2992
  var isCount = (m) => m.id === ID.rowCount || m.id === ID.colCount;
2922
2993
  var countAxis = (m) => m.id === ID.rowCount ? "row" : "col";
2923
2994
  var countKey = (m) => m.id === ID.rowCount ? "rowCount" : "columnCount";
2924
2995
  function countPair(x, y, sy) {
2925
- if (!isCount(x)) return isCount(y) ? ok([x]) : null;
2996
+ if (!isCount(x)) return isCount(y) ? ok2([x]) : null;
2926
2997
  const k = countKey(x);
2927
2998
  const v = Number(x.params[k]);
2928
2999
  if (sy) {
2929
- if (sy.axis !== countAxis(x) || sy.op.kind === "move") return ok([x]);
3000
+ if (sy.axis !== countAxis(x) || sy.op.kind === "move") return ok2([x]);
2930
3001
  const d = sy.op.kind === "insert" ? sy.op.count : -sy.op.count;
2931
- return ok([{ id: x.id, params: { ...x.params, [k]: Math.max(1, v + d) } }]);
3002
+ return ok2([{ id: x.id, params: { ...x.params, [k]: Math.max(1, v + d) } }]);
2932
3003
  }
2933
3004
  if (isCount(y) && y.id === x.id) {
2934
3005
  const w = Number(y.params[k]);
2935
- return ok([w > v ? { id: x.id, params: { ...x.params, [k]: w } } : x]);
3006
+ return ok2([w > v ? { id: x.id, params: { ...x.params, [k]: w } } : x]);
2936
3007
  }
2937
- return ok([x]);
3008
+ return ok2([x]);
2938
3009
  }
2939
3010
  var isSheetOp = (m) => m.id === ID.insertSheet || m.id === ID.removeSheet || m.id === ID.sheetOrder;
2940
3011
  var sheetIdOf = (m) => m.id === ID.insertSheet ? String(m.params.sheet?.id ?? "") : sheetOf(m);
@@ -2967,31 +3038,31 @@ function sheetPair(x, y, side) {
2967
3038
  const b = sheetAxisOf(y);
2968
3039
  if (!a || !b) return barrier2("a sheet add or remove without its index (capture must call annotateSheetOps)");
2969
3040
  if (x.id === ID.insertSheet && y.id === ID.insertSheet && sheetIdOf(x) === sheetIdOf(y)) {
2970
- return JSON.stringify(x.params) === JSON.stringify(y.params) ? ok([]) : barrier2("the same sheet id added twice with different content");
3041
+ return JSON.stringify(x.params) === JSON.stringify(y.params) ? ok2([]) : barrier2("the same sheet id added twice with different content");
2971
3042
  }
2972
3043
  if (x.id === ID.removeSheet && typeof x.params.sheetsLeft === "number" && sheetIdOf(x) !== sheetIdOf(y) && (y.id === ID.removeSheet || y.id === ID.insertSheet)) {
2973
3044
  const left = x.params.sheetsLeft + (y.id === ID.insertSheet ? 1 : -1);
2974
3045
  if (left < 1) return barrier2("concurrent sheet removes would leave the workbook without a sheet");
2975
3046
  const out2 = transformAxis(a, b, side);
2976
3047
  if (!out2) return barrier2("sheet order: no transform");
2977
- return ok(out2.map((o) => buildSheetOp({ id: x.id, params: { ...x.params, sheetsLeft: left } }, o)));
3048
+ return ok2(out2.map((o) => buildSheetOp({ id: x.id, params: { ...x.params, sheetsLeft: left } }, o)));
2978
3049
  }
2979
3050
  const out = transformAxis(a, b, side);
2980
3051
  if (!out) return barrier2("sheet order: no transform");
2981
- return ok(out.map((o) => buildSheetOp(x, o)), [], out.length === 0 && x.id === ID.sheetOrder ? [`${sheetIdOf(x)}: sheet order`] : []);
3052
+ return ok2(out.map((o) => buildSheetOp(x, o)), [], out.length === 0 && x.id === ID.sheetOrder ? [`${sheetIdOf(x)}: sheet order`] : []);
2982
3053
  }
2983
3054
  if (ys) {
2984
- if (y.id !== ID.removeSheet) return ok([x]);
3055
+ if (y.id !== ID.removeSheet) return ok2([x]);
2985
3056
  const gone2 = sheetOf(y);
2986
3057
  if (namesSheet(x, gone2)) return barrier2("a formula names a sheet removed at the same time");
2987
3058
  if (sheetOf(x) === gone2 && x.id !== ID.setName && x.id !== ID.removeName)
2988
- return ok([], [], isDerived(x) ? [] : [`${gone2}: the sheet was removed`]);
2989
- return ok([x]);
3059
+ return ok2([], [], isDerived(x) ? [] : [`${gone2}: the sheet was removed`]);
3060
+ return ok2([x]);
2990
3061
  }
2991
- if (x.id !== ID.removeSheet) return ok([x]);
3062
+ if (x.id !== ID.removeSheet) return ok2([x]);
2992
3063
  const gone = sheetOf(x);
2993
3064
  if (namesSheet(y, gone)) return barrier2("a formula names a sheet removed at the same time");
2994
- return ok([x], sheetOf(y) === gone && !isDerived(y) && y.id !== ID.setName && y.id !== ID.removeName ? [`${gone}: the sheet was removed`] : []);
3065
+ return ok2([x], sheetOf(y) === gone && !isDerived(y) && y.id !== ID.setName && y.id !== ID.removeName ? [`${gone}: the sheet was removed`] : []);
2995
3066
  }
2996
3067
  function annotateSheetOps(group, sheetOrder) {
2997
3068
  const order = [...sheetOrder];
@@ -3030,6 +3101,119 @@ function inlineSheetStyles(sheet, styleOf) {
3030
3101
  }
3031
3102
  return out;
3032
3103
  }
3104
+ var isSort = (m) => m.id === ID.sort;
3105
+ function sortOf(m) {
3106
+ const P = /* @__PURE__ */ new Map();
3107
+ for (const [t, src] of Object.entries(m.params.order ?? {})) P.set(Number(t), Number(src));
3108
+ return { range: { ...m.params.range }, P };
3109
+ }
3110
+ var sortQ = (o) => new Map([...o.P].map(([t, s0]) => [s0, t]));
3111
+ function buildSort(template, o) {
3112
+ const order = {};
3113
+ for (const [t, s0] of [...o.P].sort((a, b) => a[0] - b[0])) if (t !== s0) order[t] = s0;
3114
+ if (!Object.keys(order).length || o.range.startRow > o.range.endRow || o.range.startColumn > o.range.endColumn) return [];
3115
+ return [{ id: template.id, params: { ...template.params, range: o.range, order } }];
3116
+ }
3117
+ var inSortCols = (o, c) => c >= o.range.startColumn && c <= o.range.endColumn;
3118
+ function sortThrough(o, st) {
3119
+ const r = o.range;
3120
+ if (st.axis === "col") {
3121
+ if (st.op.kind === "move") {
3122
+ const { from, count, to } = st.op;
3123
+ const touches = !(from + count - 1 < r.startColumn || from > r.endColumn) || to > r.startColumn && to <= r.endColumn;
3124
+ if (touches) return null;
3125
+ const spans3 = spanThrough(st.op, r.startColumn, r.endColumn);
3126
+ return spans3.length === 1 ? { range: { ...r, startColumn: spans3[0][0], endColumn: spans3[0][1] }, P: o.P } : null;
3127
+ }
3128
+ const spans2 = spanThrough(st.op, r.startColumn, r.endColumn);
3129
+ if (!spans2.length) return { range: { ...r, startColumn: 1, endColumn: 0 }, P: /* @__PURE__ */ new Map() };
3130
+ return { range: { ...r, startColumn: spans2[0][0], endColumn: spans2[spans2.length - 1][1] }, P: o.P };
3131
+ }
3132
+ const op = st.op;
3133
+ if (op.kind === "move") {
3134
+ const touches = !(op.from + op.count - 1 < r.startRow || op.from > r.endRow) || op.to > r.startRow && op.to <= r.endRow;
3135
+ if (touches) return null;
3136
+ }
3137
+ if (op.kind === "insert" || op.kind === "move") {
3138
+ const P2 = /* @__PURE__ */ new Map();
3139
+ for (const [t, s0] of o.P) P2.set(mapIndex(op, t), mapIndex(op, s0));
3140
+ const spans2 = spanThrough(op, r.startRow, r.endRow);
3141
+ return { range: { ...r, startRow: spans2[0][0], endRow: spans2[spans2.length - 1][1] }, P: P2 };
3142
+ }
3143
+ const removed = (i) => i >= op.start && i < op.start + op.count;
3144
+ const Q = sortQ(o);
3145
+ const goneTargets = [];
3146
+ for (let i = op.start; i < op.start + op.count; i++) goneTargets.push(Q.get(i) ?? i);
3147
+ goneTargets.sort((a, b) => a - b);
3148
+ const compact = (t) => t - goneTargets.filter((g) => g < t).length;
3149
+ const P = /* @__PURE__ */ new Map();
3150
+ for (const [t, s0] of o.P) if (!removed(s0)) P.set(compact(t), mapIndex(op, s0));
3151
+ const spans = spanThrough(op, r.startRow, r.endRow);
3152
+ if (!spans.length) return { range: { ...r, startRow: 1, endRow: 0 }, P: /* @__PURE__ */ new Map() };
3153
+ return { range: { ...r, startRow: spans[0][0], endRow: spans[spans.length - 1][1] }, P };
3154
+ }
3155
+ function sortPair(x, y, sx, sy) {
3156
+ const xs = isSort(x);
3157
+ const ys = isSort(y);
3158
+ if (!xs && !ys) return null;
3159
+ if (xs && ys) {
3160
+ const a = sortOf(x).range;
3161
+ const b = sortOf(y).range;
3162
+ const overlap = a.startRow <= b.endRow && b.startRow <= a.endRow && a.startColumn <= b.endColumn && b.startColumn <= a.endColumn;
3163
+ return overlap ? barrier2("two sorts of overlapping ranges at once") : ok2([x]);
3164
+ }
3165
+ if (xs) {
3166
+ if (sy) {
3167
+ const t = sortThrough(sortOf(x), sy);
3168
+ return t ? ok2(buildSort(x, t)) : barrier2("a row or column move through a sorted range");
3169
+ }
3170
+ return ok2([x]);
3171
+ }
3172
+ const o = sortOf(y);
3173
+ const Q = sortQ(o);
3174
+ const moved = (r) => r >= o.range.startRow && r <= o.range.endRow && Q.has(r);
3175
+ if (sx) {
3176
+ if (sx.axis === "col") return sx.op.kind === "move" && !sortThrough(o, sx) ? barrier2("a column move through a sorted range") : ok2([x]);
3177
+ if (sx.op.kind === "insert") return ok2([x]);
3178
+ if (sx.op.kind === "move") return sortThrough(o, sx) ? ok2([x]) : barrier2("a row move through a sorted range");
3179
+ const rows = [];
3180
+ let partial = false;
3181
+ for (let i = sx.op.start; i < sx.op.start + sx.op.count; i++) {
3182
+ if (moved(i)) partial = true;
3183
+ rows.push(Q.get(i) ?? i);
3184
+ }
3185
+ if (partial) return barrier2("a row remove against a concurrent sort of those rows");
3186
+ return ok2([x]);
3187
+ }
3188
+ if (x.id === ID.values) {
3189
+ const out = {};
3190
+ let changed = false;
3191
+ forEachCell(cellsOf(x), (r, c, v) => {
3192
+ if (inSortCols(o, c) && moved(r)) {
3193
+ putCell(out, Q.get(r), c, v);
3194
+ changed = true;
3195
+ } else putCell(out, r, c, v);
3196
+ });
3197
+ return changed ? ok2([cellsMutation(x, out)]) : ok2([x]);
3198
+ }
3199
+ if (isNumfmt(x)) {
3200
+ const parts = nfParts(x).map((p) => {
3201
+ const ranges = [];
3202
+ for (const rc of p.ranges) {
3203
+ const inner = { ...rc, startRow: Math.max(rc.startRow, o.range.startRow), endRow: Math.min(rc.endRow, o.range.endRow), startColumn: Math.max(rc.startColumn, o.range.startColumn), endColumn: Math.min(rc.endColumn, o.range.endColumn) };
3204
+ if (inner.startRow > inner.endRow || inner.startColumn > inner.endColumn) {
3205
+ ranges.push(rc);
3206
+ continue;
3207
+ }
3208
+ ranges.push(...rectMinus(rc, inner));
3209
+ for (let r = inner.startRow; r <= inner.endRow; r++) ranges.push({ ...inner, startRow: Q.get(r) ?? r, endRow: Q.get(r) ?? r });
3210
+ }
3211
+ return { ...p, ranges };
3212
+ });
3213
+ return ok2(nfBuild(x, parts));
3214
+ }
3215
+ return ok2([x]);
3216
+ }
3033
3217
  function familyOf(id) {
3034
3218
  const e = SHEET_MUTATIONS[id];
3035
3219
  return e && e.kind === "covered" ? e.family : "";
@@ -3044,27 +3228,31 @@ function transformMutation(x, y, side) {
3044
3228
  if (why) return barrier2(why);
3045
3229
  }
3046
3230
  }
3231
+ const ca = transformCommentAnchor(x, y, side);
3232
+ if (ca) return ca;
3047
3233
  const pb = PAIR_BARRIERS[pairKey(x.id, y.id)];
3048
3234
  if (pb) return barrier2(`${x.id} \xD7 ${y.id}: ${pb.reason}${pb.seed === null ? "" : ` (fuzz seed ${pb.seed})`}`);
3049
3235
  const sp = sheetPair(x, y, side);
3050
3236
  if (sp) return sp;
3051
3237
  const fp = formulaPair(x, y, side);
3052
3238
  if (fp) return fp;
3053
- if (sheetOf(x) !== sheetOf(y)) return ok([x]);
3239
+ if (sheetOf(x) !== sheetOf(y)) return ok2([x]);
3054
3240
  const fx = familyOf(x.id);
3055
3241
  const fy = familyOf(y.id);
3056
3242
  const sy = structuralOf(y);
3057
3243
  const sx = structuralOf(x);
3244
+ const sortp = sortPair(x, y, sx, sy);
3245
+ if (sortp) return sortp;
3058
3246
  const cp = countPair(x, y, sy);
3059
3247
  if (cp) return cp;
3060
3248
  const np = numfmtPair(x, y, side, sx, sy);
3061
3249
  if (np) return np;
3062
3250
  if (sx && sy) {
3063
- if (sx.axis !== sy.axis) return ok([x]);
3251
+ if (sx.axis !== sy.axis) return ok2([x]);
3064
3252
  const out = transformAxis(sx.op, sy.op, side);
3065
3253
  if (!out) return barrier2(`${x.id} over ${y.id}: moved blocks overlap in part, or the block would split`);
3066
3254
  const dropped = out.length === 0 && sx.op.kind === "move" ? [`${sheetOf(x)}: moved ${sx.axis}s`] : [];
3067
- return ok(out.map((o) => buildStructural(x, sx.axis, o)), [], dropped);
3255
+ return ok2(out.map((o) => buildStructural(x, sx.axis, o)), [], dropped);
3068
3256
  }
3069
3257
  if (sy) {
3070
3258
  if (fx === "merge") {
@@ -3075,23 +3263,23 @@ function transformMutation(x, y, side) {
3075
3263
  if (t) kept.push(t);
3076
3264
  else dropped.push(rangeRef(sheetOf(x), r));
3077
3265
  }
3078
- return ok(kept.length ? [withRanges(x, kept)] : [], [], x.id === ID.addMerge ? dropped : []);
3266
+ return ok2(kept.length ? [withRanges(x, kept)] : [], [], x.id === ID.addMerge ? dropped : []);
3079
3267
  }
3080
3268
  if (fx === "size") {
3081
3269
  const size = sizeOf(x);
3082
- if (size.axis !== sy.axis) return ok([x]);
3270
+ if (size.axis !== sy.axis) return ok2([x]);
3083
3271
  const next = /* @__PURE__ */ new Map();
3084
3272
  for (const [i, v] of size.values) {
3085
3273
  const m = mapIndex(sy.op, i);
3086
3274
  if (m !== null) next.set(m, v);
3087
3275
  }
3088
3276
  const built = buildSize(x, next);
3089
- return ok(built ? [built] : []);
3277
+ return ok2(built ? [built] : []);
3090
3278
  }
3091
- return ok([x]);
3279
+ return ok2([x]);
3092
3280
  }
3093
3281
  if (sx) {
3094
- if (fy !== "merge" || y.id !== ID.addMerge) return ok([x]);
3282
+ if (fy !== "merge" || y.id !== ID.addMerge) return ok2([x]);
3095
3283
  const remove = [];
3096
3284
  const add = [];
3097
3285
  for (const r of mergeRanges(y)) {
@@ -3101,11 +3289,11 @@ function transformMutation(x, y, side) {
3101
3289
  if (t.range) add.push(t.range);
3102
3290
  }
3103
3291
  const lostMerges = mergeRanges(y).filter((r) => mergeThrough(sx, r).range === null).map((r) => rangeRef(sheetOf(y), r));
3104
- if (!remove.length) return ok([x], lostMerges);
3292
+ if (!remove.length) return ok2([x], lostMerges);
3105
3293
  const sheet = sheetOf(x);
3106
3294
  const pre = sx.op.kind === "insert" ? [] : [mergeMutation(ID.removeMerge, sheet, remove)];
3107
3295
  const mid = sx.op.kind === "insert" ? [mergeMutation(ID.removeMerge, sheet, remove)] : [];
3108
- return ok([...pre, x, ...mid, ...add.length ? [mergeMutation(ID.addMerge, sheet, add)] : []], lostMerges);
3296
+ return ok2([...pre, x, ...mid, ...add.length ? [mergeMutation(ID.addMerge, sheet, add)] : []], lostMerges);
3109
3297
  }
3110
3298
  if (fx === "cell" && fy === "cell") return transformCellsOverCells(x, y, side);
3111
3299
  if (fx === "merge" && fy === "merge") {
@@ -3114,45 +3302,45 @@ function transformMutation(x, y, side) {
3114
3302
  const hit = (r) => yr.some((q) => intersects(r, q));
3115
3303
  const sheet = sheetOf(x);
3116
3304
  if (x.id === ID.addMerge && y.id === ID.addMerge) {
3117
- if (!xr.some(hit)) return ok([x]);
3305
+ if (!xr.some(hit)) return ok2([x]);
3118
3306
  if (side === "left") {
3119
3307
  const lost = yr.filter((q) => xr.some((r) => intersects(r, q))).map((q) => rangeRef(sheet, q));
3120
- return ok([mergeMutation(ID.removeMerge, sheet, xr.filter(hit)), x], lost);
3308
+ return ok2([mergeMutation(ID.removeMerge, sheet, xr.filter(hit)), x], lost);
3121
3309
  }
3122
3310
  const kept = xr.filter((r) => !hit(r));
3123
- return ok(kept.length ? [withRanges(x, kept)] : [], [], xr.filter(hit).map((r) => rangeRef(sheet, r)));
3311
+ return ok2(kept.length ? [withRanges(x, kept)] : [], [], xr.filter(hit).map((r) => rangeRef(sheet, r)));
3124
3312
  }
3125
3313
  if (x.id === ID.addMerge && y.id === ID.removeMerge) {
3126
- if (side === "left" || !xr.some(hit)) return ok([x], side === "left" && xr.some(hit) ? yr.filter((q) => xr.some((r) => intersects(r, q))).map((q) => rangeRef(sheet, q)) : []);
3314
+ 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)) : []);
3127
3315
  const kept = xr.filter((r) => !hit(r));
3128
- return ok(kept.length ? [withRanges(x, kept)] : [], [], xr.filter(hit).map((r) => rangeRef(sheet, r)));
3316
+ return ok2(kept.length ? [withRanges(x, kept)] : [], [], xr.filter(hit).map((r) => rangeRef(sheet, r)));
3129
3317
  }
3130
3318
  if (x.id === ID.removeMerge && y.id === ID.addMerge) {
3131
3319
  const touched = yr.filter((q) => xr.some((r) => intersects(r, q)));
3132
- if (!touched.length) return ok([x]);
3133
- if (side === "left") return ok([x], touched.map((q) => rangeRef(sheet, q)));
3134
- return ok([x, mergeMutation(ID.addMerge, sheet, touched)], [], xr.filter(hit).map((r) => rangeRef(sheet, r)));
3320
+ if (!touched.length) return ok2([x]);
3321
+ if (side === "left") return ok2([x], touched.map((q) => rangeRef(sheet, q)));
3322
+ return ok2([x, mergeMutation(ID.addMerge, sheet, touched)], [], xr.filter(hit).map((r) => rangeRef(sheet, r)));
3135
3323
  }
3136
- return ok([x]);
3324
+ return ok2([x]);
3137
3325
  }
3138
3326
  if (fx === "size" && fy === "size") {
3139
3327
  const a = sizeOf(x);
3140
3328
  const b = sizeOf(y);
3141
- if (a.axis !== b.axis || a.attr !== b.attr) return ok([x]);
3329
+ if (a.axis !== b.axis || a.attr !== b.attr) return ok2([x]);
3142
3330
  if (side === "left") {
3143
3331
  const lost = [...a.values.keys()].filter((i) => b.values.has(i)).map((i) => `${sheetOf(x)}: ${a.axis} ${i + 1} ${a.attr}`);
3144
- return ok([x], lost);
3332
+ return ok2([x], lost);
3145
3333
  }
3146
3334
  const next = new Map([...a.values].filter(([i]) => !b.values.has(i)));
3147
3335
  const built = buildSize(x, next);
3148
3336
  const dropped = [...a.values.keys()].filter((i) => b.values.has(i)).map((i) => `${sheetOf(x)}: ${a.axis} ${i + 1} ${a.attr}`);
3149
- return ok(built ? [built] : [], [], dropped);
3337
+ return ok2(built ? [built] : [], [], dropped);
3150
3338
  }
3151
3339
  if (fx === "name" && fy === "name") {
3152
- if (side === "left") return ok([x], [`${sheetOf(x)}: name "${String(y.params.name)}"`]);
3153
- return ok([], [], [`${sheetOf(x)}: name "${String(x.params.name)}"`]);
3340
+ if (side === "left") return ok2([x], [`${sheetOf(x)}: name "${String(y.params.name)}"`]);
3341
+ return ok2([], [], [`${sheetOf(x)}: name "${String(x.params.name)}"`]);
3154
3342
  }
3155
- return ok([x]);
3343
+ return ok2([x]);
3156
3344
  }
3157
3345
  var blocked = (p) => !Array.isArray(p);
3158
3346
  function tSeq(xs, ys, side, acc) {
@@ -3331,10 +3519,10 @@ function rebaseSheetUndoStack(items, remote, unitId) {
3331
3519
  let dropped = 0;
3332
3520
  for (let i = items.length - 1; i >= 0; i--) {
3333
3521
  const item = items[i];
3334
- let ok2 = true;
3522
+ let ok3 = true;
3335
3523
  for (const key of ["undoMutations", "redoMutations"]) {
3336
3524
  const list = item[key];
3337
- if (!ok2 || !list?.length) continue;
3525
+ if (!ok3 || !list?.length) continue;
3338
3526
  const isOperation = (id) => !SHEET_MUTATIONS[id] && id.includes(".operation.");
3339
3527
  const operations = list.filter((m) => isOperation(m.id));
3340
3528
  let shaped = cachedShape(list);
@@ -3343,14 +3531,14 @@ function rebaseSheetUndoStack(items, remote, unitId) {
3343
3531
  shapedLists.set(list, { src: list.slice(), shaped });
3344
3532
  }
3345
3533
  if (shaped.some((m) => m === null)) {
3346
- ok2 = false;
3534
+ ok3 = false;
3347
3535
  continue;
3348
3536
  }
3349
3537
  if (!shaped.length) continue;
3350
3538
  try {
3351
3539
  const r = transformGroup(shaped, remote, "left");
3352
3540
  if (isBarrier(r) || r.op.length === 0) {
3353
- ok2 = false;
3541
+ ok3 = false;
3354
3542
  continue;
3355
3543
  }
3356
3544
  if (r.op.length === shaped.length && r.op.every((m, i2) => m === shaped[i2])) continue;
@@ -3358,10 +3546,10 @@ function rebaseSheetUndoStack(items, remote, unitId) {
3358
3546
  shapedLists.set(next, { src: next.slice(), shaped: r.op });
3359
3547
  item[key] = next;
3360
3548
  } catch {
3361
- ok2 = false;
3549
+ ok3 = false;
3362
3550
  }
3363
3551
  }
3364
- if (!ok2) {
3552
+ if (!ok3) {
3365
3553
  items.splice(i, 1);
3366
3554
  dropped++;
3367
3555
  }
@@ -3582,7 +3770,7 @@ function univerSheetsOtPort(o) {
3582
3770
  return out;
3583
3771
  };
3584
3772
  const sheetOrder = () => (o.workbook()?.getSheets() ?? []).map((ws) => ws.getSheetId());
3585
- const openGroup = (label) => ({ label, order: sheetOrder(), sheets: sheetNames(), names: definedNames(), mutations: [], inverses: [], notShared: null });
3773
+ const openGroup = (label2) => ({ label: label2, order: sheetOrder(), sheets: sheetNames(), names: definedNames(), mutations: [], inverses: [], notShared: null });
3586
3774
  const emit = (e) => {
3587
3775
  for (const l of [...listeners]) {
3588
3776
  try {
@@ -3761,6 +3949,11 @@ function univerSheetsOtPort(o) {
3761
3949
  return { m, inverse: [{ id: "sheet.mutation.remove-col", params: { subUnitId: sheet, range: json(params.range) } }] };
3762
3950
  case ADD_MERGE:
3763
3951
  return { m, inverse: [{ id: REMOVE_MERGE, params: { subUnitId: sheet, ranges: json(params.ranges) } }] };
3952
+ case "sheet.mutation.reorder-range": {
3953
+ const order = {};
3954
+ for (const [t, src] of Object.entries(params.order ?? {})) order[String(src)] = Number(t);
3955
+ return { m, inverse: [{ id: info.id, params: { subUnitId: sheet, range: json(params.range), order } }] };
3956
+ }
3764
3957
  case SHEET_NAME:
3765
3958
  return { m, inverse: before2.name !== void 0 ? [{ id: SHEET_NAME, params: { subUnitId: sheet, name: before2.name } }] : void 0 };
3766
3959
  default:
@@ -3833,8 +4026,8 @@ function univerSheetsOtPort(o) {
3833
4026
  const a = forApply(m);
3834
4027
  applying = true;
3835
4028
  try {
3836
- const ok2 = cs.syncExecuteCommand(a.id, { ...json(a.params), unitId: u }, { fromCollab: true });
3837
- if (ok2 === false) throw new Error(`"${m.id}" was refused by the editor`);
4029
+ const ok3 = cs.syncExecuteCommand(a.id, { ...json(a.params), unitId: u }, { fromCollab: true });
4030
+ if (ok3 === false) throw new Error(`"${m.id}" was refused by the editor`);
3838
4031
  } finally {
3839
4032
  applying = false;
3840
4033
  }