@gridsheet/react-core 2.2.0 → 3.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/components/Cell.d.ts.map +1 -1
  2. package/dist/components/CellStateOverlay.d.ts.map +1 -1
  3. package/dist/components/ColumnMenu.d.ts.map +1 -1
  4. package/dist/components/Editor.d.ts.map +1 -1
  5. package/dist/components/GridSheet.d.ts.map +1 -1
  6. package/dist/components/HeaderCellLeft.d.ts.map +1 -1
  7. package/dist/components/HeaderCellTop.d.ts.map +1 -1
  8. package/dist/components/RowMenu.d.ts +3 -0
  9. package/dist/components/RowMenu.d.ts.map +1 -0
  10. package/dist/components/Tabular.d.ts.map +1 -1
  11. package/dist/constants.d.ts +9 -0
  12. package/dist/constants.d.ts.map +1 -1
  13. package/dist/formula/evaluator.d.ts +2 -0
  14. package/dist/formula/evaluator.d.ts.map +1 -1
  15. package/dist/formula/functions/__async.d.ts +59 -0
  16. package/dist/formula/functions/__async.d.ts.map +1 -0
  17. package/dist/formula/functions/__base.d.ts +5 -0
  18. package/dist/formula/functions/__base.d.ts.map +1 -1
  19. package/dist/formula/functions/__utils.d.ts.map +1 -1
  20. package/dist/formula/solver.d.ts.map +1 -1
  21. package/dist/index.d.ts +5 -4
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +1358 -570
  24. package/dist/index.js.map +1 -1
  25. package/dist/lib/cell.d.ts +3 -0
  26. package/dist/lib/cell.d.ts.map +1 -0
  27. package/dist/lib/{converters.d.ts → coords.d.ts} +1 -1
  28. package/dist/lib/coords.d.ts.map +1 -0
  29. package/dist/lib/hub.d.ts +4 -7
  30. package/dist/lib/hub.d.ts.map +1 -1
  31. package/dist/lib/operation.d.ts +1 -0
  32. package/dist/lib/operation.d.ts.map +1 -1
  33. package/dist/lib/palette.d.ts.map +1 -1
  34. package/dist/lib/{structs.d.ts → spatial.d.ts} +17 -1
  35. package/dist/lib/{structs.d.ts.map → spatial.d.ts.map} +1 -1
  36. package/dist/lib/table.d.ts +112 -65
  37. package/dist/lib/table.d.ts.map +1 -1
  38. package/dist/renderers/core.d.ts +1 -0
  39. package/dist/renderers/core.d.ts.map +1 -1
  40. package/dist/store/actions.d.ts +17 -37
  41. package/dist/store/actions.d.ts.map +1 -1
  42. package/dist/store/dispatchers.d.ts.map +1 -1
  43. package/dist/styles/minified.d.ts +2 -2
  44. package/dist/styles/minified.d.ts.map +1 -1
  45. package/dist/types.d.ts +23 -12
  46. package/dist/types.d.ts.map +1 -1
  47. package/package.json +1 -1
  48. package/dist/lib/converters.d.ts.map +0 -1
package/dist/index.js CHANGED
@@ -18,6 +18,11 @@ class Special {
18
18
  this.name = name;
19
19
  }
20
20
  }
21
+ class Pending {
22
+ constructor(promise) {
23
+ this.promise = promise;
24
+ }
25
+ }
21
26
  const SECONDS_IN_DAY = 86400;
22
27
  const FULLDATE_FORMAT_UTC = "YYYY-MM-DDTHH:mm:ss.SSSZ";
23
28
  const RESET_ZONE = {
@@ -245,33 +250,6 @@ const aa2oa = (aa, fields) => {
245
250
  });
246
251
  return oa;
247
252
  };
248
- const putMatrix = (dst, src, dstArea, filter = () => true) => {
249
- const lostRows = {};
250
- const { top, left, bottom, right } = dstArea;
251
- const { height: dstNumRows, width: dstNumCols } = matrixShape({
252
- matrix: dst,
253
- base: 1
254
- });
255
- for (let y = top; y <= bottom; y++) {
256
- const lostRow = [];
257
- for (let x = left; x <= right; x++) {
258
- const srcPoint = { y: y - top, x: x - left };
259
- const dstPoint = { y, x };
260
- const value = src[y - top][x - left];
261
- if (y < dstNumRows - 1 && x < dstNumCols - 1) {
262
- if (filter({ srcValue: value, dstValue: dst[y][x], srcPoint, dstPoint })) {
263
- dst[y][x] = value;
264
- }
265
- continue;
266
- }
267
- if (lostRow.length === 0) {
268
- lostRows[p2a(dstPoint)] = [lostRow];
269
- }
270
- lostRow.push(value);
271
- }
272
- }
273
- return lostRows;
274
- };
275
253
  const createMatrix = (numRows, numCols, fill) => {
276
254
  return [...Array(numRows)].map(() => Array(numCols).fill(fill));
277
255
  };
@@ -411,6 +389,91 @@ const binarySearch = (low, high, predicate, lessThan) => {
411
389
  }
412
390
  return high;
413
391
  };
392
+ const addressesToAreas = (addresses) => {
393
+ if (addresses.length === 0) {
394
+ return [];
395
+ }
396
+ const points = addresses.map((addr) => {
397
+ const { y, x } = a2p(addr);
398
+ return { y, x };
399
+ });
400
+ const key = (y, x) => `${y},${x}`;
401
+ const pointSet = new Set(points.map((p) => key(p.y, p.x)));
402
+ const visited = /* @__PURE__ */ new Set();
403
+ const areas = [];
404
+ for (const p of points) {
405
+ const k = key(p.y, p.x);
406
+ if (visited.has(k)) {
407
+ continue;
408
+ }
409
+ let top = p.y, left = p.x, bottom = p.y, right = p.x;
410
+ const queue = [p];
411
+ visited.add(k);
412
+ while (queue.length > 0) {
413
+ const { y, x } = queue.shift();
414
+ if (y < top) {
415
+ top = y;
416
+ }
417
+ if (y > bottom) {
418
+ bottom = y;
419
+ }
420
+ if (x < left) {
421
+ left = x;
422
+ }
423
+ if (x > right) {
424
+ right = x;
425
+ }
426
+ for (const [dy, dx] of [
427
+ [0, 1],
428
+ [0, -1],
429
+ [1, 0],
430
+ [-1, 0]
431
+ ]) {
432
+ const nk = key(y + dy, x + dx);
433
+ if (pointSet.has(nk) && !visited.has(nk)) {
434
+ visited.add(nk);
435
+ queue.push({ y: y + dy, x: x + dx });
436
+ }
437
+ }
438
+ }
439
+ areas.push({ top, left, bottom, right });
440
+ }
441
+ return areas;
442
+ };
443
+ const addressesToCols = (addresses, asc = true) => {
444
+ const seen = /* @__PURE__ */ new Set();
445
+ const cols = [];
446
+ for (const addr of addresses) {
447
+ const { x } = a2p(addr);
448
+ if (!seen.has(x)) {
449
+ seen.add(x);
450
+ cols.push(x);
451
+ }
452
+ }
453
+ if (asc === true) {
454
+ cols.sort((a, b) => a - b);
455
+ } else if (asc === false) {
456
+ cols.sort((a, b) => b - a);
457
+ }
458
+ return cols;
459
+ };
460
+ const addressesToRows = (addresses, asc = true) => {
461
+ const seen = /* @__PURE__ */ new Set();
462
+ const rows = [];
463
+ for (const addr of addresses) {
464
+ const { y } = a2p(addr);
465
+ if (!seen.has(y)) {
466
+ seen.add(y);
467
+ rows.push(y);
468
+ }
469
+ }
470
+ if (asc === true) {
471
+ rows.sort((a, b) => a - b);
472
+ } else if (asc === false) {
473
+ rows.sort((a, b) => b - a);
474
+ }
475
+ return rows;
476
+ };
414
477
  const restrictPoints = (store, table) => {
415
478
  const { choosing, selectingZone } = store;
416
479
  let { y, x } = choosing;
@@ -509,8 +572,8 @@ const getCellRectPositions = (table, { y, x }) => {
509
572
  var _a, _b;
510
573
  const colCell = table.getCellByPoint({ y: 0, x }, "SYSTEM");
511
574
  const rowCell = table.getCellByPoint({ y, x: 0 }, "SYSTEM");
512
- const left = ((_a = colCell == null ? void 0 : colCell.system) == null ? void 0 : _a.offsetLeft) ?? 0;
513
- const top = ((_b = rowCell == null ? void 0 : rowCell.system) == null ? void 0 : _b.offsetTop) ?? 0;
575
+ const left = ((_a = colCell == null ? void 0 : colCell._sys) == null ? void 0 : _a.offsetLeft) ?? 0;
576
+ const top = ((_b = rowCell == null ? void 0 : rowCell._sys) == null ? void 0 : _b.offsetTop) ?? 0;
514
577
  const w = (colCell == null ? void 0 : colCell.width) || DEFAULT_WIDTH;
515
578
  const h = (rowCell == null ? void 0 : rowCell.filtered) ? 0 : (rowCell == null ? void 0 : rowCell.height) || DEFAULT_HEIGHT;
516
579
  return {
@@ -676,6 +739,7 @@ const Add = InsertRows | InsertCols;
676
739
  const Delete = RemoveRows | RemoveCols;
677
740
  const ReadOnly = Update | Delete | Add | Move;
678
741
  const ColumnMenu$1 = Filter | Sort | SetLabel;
742
+ const RowMenu$1 = 524288;
679
743
  const ViewOnly = ReadOnly | ColumnMenu$1;
680
744
  const hasOperation = (operation2, flag) => {
681
745
  if (operation2 === void 0) {
@@ -759,6 +823,7 @@ const operation = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePro
759
823
  RemoveCols,
760
824
  RemoveRows,
761
825
  Resize,
826
+ RowMenu: RowMenu$1,
762
827
  SetLabel,
763
828
  SetLabeler,
764
829
  SetParser,
@@ -1072,10 +1137,14 @@ const getId = (idString, stripAbsolute = true) => {
1072
1137
  };
1073
1138
  class FormulaError {
1074
1139
  constructor(code, message, error) {
1140
+ this.__isFormulaError = true;
1075
1141
  this.code = code;
1076
1142
  this.message = message;
1077
1143
  this.error = error;
1078
1144
  }
1145
+ static is(obj) {
1146
+ return obj instanceof FormulaError || (obj == null ? void 0 : obj.__isFormulaError) === true;
1147
+ }
1079
1148
  }
1080
1149
  class Entity {
1081
1150
  constructor(value) {
@@ -1134,7 +1203,7 @@ class RefEntity extends Entity {
1134
1203
  return this.value;
1135
1204
  }
1136
1205
  const system = table.wire.getSystem(id, table);
1137
- table.wire.data[id].system = system;
1206
+ table.wire.data[id]._sys = system;
1138
1207
  system.dependents.add(dependency);
1139
1208
  return `#${parsed.table.sheetId}!${formula}`;
1140
1209
  }
@@ -1175,7 +1244,7 @@ class RangeEntity extends Entity {
1175
1244
  return this.value;
1176
1245
  }
1177
1246
  const system = table.wire.getSystem(id, table);
1178
- table.wire.data[id].system = system;
1247
+ table.wire.data[id]._sys = system;
1179
1248
  system.dependents.add(dependency);
1180
1249
  formulas.push(formula);
1181
1250
  }
@@ -1226,7 +1295,7 @@ class IdEntity extends Entity {
1226
1295
  if (dependency) {
1227
1296
  ids.forEach((id) => {
1228
1297
  const system = table.wire.getSystem(id, table);
1229
- table.wire.data[id].system = system;
1298
+ table.wire.data[id]._sys = system;
1230
1299
  system.dependents.add(dependency);
1231
1300
  });
1232
1301
  }
@@ -1279,7 +1348,7 @@ class IdRangeEntity extends Entity {
1279
1348
  if (dependency) {
1280
1349
  ids.forEach((id) => {
1281
1350
  const system = table.wire.getSystem(id, table);
1282
- table.wire.data[id].system = system;
1351
+ table.wire.data[id]._sys = system;
1283
1352
  system.dependents.add(dependency);
1284
1353
  });
1285
1354
  }
@@ -2042,7 +2111,7 @@ class Autofill {
2042
2111
  get applied() {
2043
2112
  var _a, _b;
2044
2113
  const [orientation, sign] = DirectionMapping[this.direction];
2045
- const matrix = this.table.getMatrix({ area: this.src, refEvaluation: "SYSTEM" });
2114
+ const matrix = this.table.getCellMatrix({ area: this.src, refEvaluation: "SYSTEM" });
2046
2115
  const srcShape = areaShape({ ...this.src, base: 1 });
2047
2116
  const dstShape = areaShape({ ...this.dst, base: 1 });
2048
2117
  const diff = {};
@@ -2755,6 +2824,8 @@ class PasteAction extends CoreAction {
2755
2824
  });
2756
2825
  }
2757
2826
  const nextSelectingZone = restrictZone(areaToZone(selectingArea));
2827
+ nextSelectingZone.endX = Math.min(nextSelectingZone.endX, newTable.getNumCols());
2828
+ nextSelectingZone.endY = Math.min(nextSelectingZone.endY, newTable.getNumRows());
2758
2829
  return {
2759
2830
  ...store,
2760
2831
  tableReactive: { current: newTable },
@@ -2813,16 +2884,26 @@ class SelectRowsAction extends CoreAction {
2813
2884
  reduce(store, payload) {
2814
2885
  const { range: range2, numCols } = payload;
2815
2886
  const { start, end } = range2;
2887
+ const table = store.tableReactive.current;
2816
2888
  const selectingZone = {
2817
2889
  startY: start,
2818
2890
  startX: 1,
2819
2891
  endY: end,
2820
2892
  endX: numCols
2821
2893
  };
2894
+ let choosingY = start;
2895
+ if (table) {
2896
+ for (let y = start; y <= end; y++) {
2897
+ if (!table.isRowFiltered(y)) {
2898
+ choosingY = y;
2899
+ break;
2900
+ }
2901
+ }
2902
+ }
2822
2903
  return {
2823
2904
  ...store,
2824
2905
  selectingZone,
2825
- choosing: { y: start, x: 0 },
2906
+ choosing: { y: choosingY, x: 1 },
2826
2907
  leftHeaderSelecting: true,
2827
2908
  topHeaderSelecting: false
2828
2909
  };
@@ -2833,16 +2914,26 @@ class SelectColsAction extends CoreAction {
2833
2914
  reduce(store, payload) {
2834
2915
  const { range: range2, numRows } = payload;
2835
2916
  const { start, end } = range2;
2917
+ const table = store.tableReactive.current;
2836
2918
  const selectingZone = {
2837
2919
  startY: 1,
2838
2920
  startX: start,
2839
2921
  endY: numRows,
2840
2922
  endX: end
2841
2923
  };
2924
+ let choosingY = 1;
2925
+ if (table) {
2926
+ for (let y = 1; y <= numRows; y++) {
2927
+ if (!table.isRowFiltered(y)) {
2928
+ choosingY = y;
2929
+ break;
2930
+ }
2931
+ }
2932
+ }
2842
2933
  return {
2843
2934
  ...store,
2844
2935
  selectingZone,
2845
- choosing: { y: 0, x: start },
2936
+ choosing: { y: choosingY, x: start },
2846
2937
  leftHeaderSelecting: false,
2847
2938
  topHeaderSelecting: true
2848
2939
  };
@@ -2939,6 +3030,9 @@ class ClearAction extends CoreAction {
2939
3030
  const diff = {};
2940
3031
  let diffCount = 0;
2941
3032
  for (let y = top; y <= bottom; y++) {
3033
+ if (table.isRowFiltered(y)) {
3034
+ continue;
3035
+ }
2942
3036
  for (let x = left; x <= right; x++) {
2943
3037
  const cell = table.getCellByPoint({ y, x }, "SYSTEM");
2944
3038
  const address = p2a({ y, x });
@@ -3427,20 +3521,12 @@ class SortRowsAction extends CoreAction {
3427
3521
  if (table == null) {
3428
3522
  return store;
3429
3523
  }
3430
- table.sortRows({
3431
- x,
3432
- direction,
3433
- undoReflection: {
3434
- sheetId: table.sheetId,
3435
- selectingZone,
3436
- choosing
3437
- },
3438
- redoReflection: {
3439
- sheetId: table.sheetId,
3440
- selectingZone,
3441
- choosing
3442
- }
3443
- });
3524
+ table.sortRows({ x, direction });
3525
+ const reflection = { sheetId: table.sheetId, selectingZone, choosing };
3526
+ if (table.wire.lastHistory) {
3527
+ table.wire.lastHistory.undoReflection = reflection;
3528
+ table.wire.lastHistory.redoReflection = reflection;
3529
+ }
3444
3530
  return {
3445
3531
  ...store,
3446
3532
  tableReactive: { current: table }
@@ -3456,20 +3542,12 @@ class FilterRowsAction extends CoreAction {
3456
3542
  if (table == null) {
3457
3543
  return store;
3458
3544
  }
3459
- table.filterRows({
3460
- x,
3461
- filter,
3462
- undoReflection: {
3463
- sheetId: table.sheetId,
3464
- selectingZone,
3465
- choosing
3466
- },
3467
- redoReflection: {
3468
- sheetId: table.sheetId,
3469
- selectingZone,
3470
- choosing
3471
- }
3472
- });
3545
+ table.filterRows({ x, filter });
3546
+ const reflection = { sheetId: table.sheetId, selectingZone, choosing };
3547
+ if (table.wire.lastHistory) {
3548
+ table.wire.lastHistory.undoReflection = reflection;
3549
+ table.wire.lastHistory.redoReflection = reflection;
3550
+ }
3473
3551
  let newChoosing = choosing;
3474
3552
  if (table.isRowFiltered(choosing.y)) {
3475
3553
  for (let y = 1; y <= table.getNumRows(); y++) {
@@ -3483,50 +3561,20 @@ class FilterRowsAction extends CoreAction {
3483
3561
  ...store,
3484
3562
  choosing: newChoosing,
3485
3563
  selectingZone: newChoosing !== choosing ? resetZone : selectingZone,
3486
- tableReactive: { current: table }
3487
- };
3488
- }
3489
- }
3490
- const filterRows = new FilterRowsAction().bind();
3491
- class ClearFilterRowsAction extends CoreAction {
3492
- reduce(store, payload) {
3493
- const { x } = payload;
3494
- const { tableReactive: tableRef, selectingZone, choosing } = store;
3495
- const table = tableRef.current;
3496
- if (table == null) {
3497
- return store;
3498
- }
3499
- table.clearFilterRows(
3500
- x,
3501
- {
3502
- sheetId: table.sheetId,
3503
- selectingZone,
3504
- choosing
3505
- },
3506
- {
3507
- sheetId: table.sheetId,
3508
- selectingZone,
3509
- choosing
3510
- }
3511
- );
3512
- let newChoosing = choosing;
3513
- if (table.isRowFiltered(choosing.y)) {
3514
- for (let y = 1; y <= table.getNumRows(); y++) {
3515
- if (!table.isRowFiltered(y)) {
3516
- newChoosing = { y, x: choosing.x };
3517
- break;
3564
+ tableReactive: { current: table },
3565
+ callback: ({ tableReactive: tableRef2 }) => {
3566
+ const t = tableRef2.current;
3567
+ if (t) {
3568
+ t.wire.transmit({
3569
+ cutting: false,
3570
+ copyingZone: resetZone
3571
+ });
3518
3572
  }
3519
3573
  }
3520
- }
3521
- return {
3522
- ...store,
3523
- choosing: newChoosing,
3524
- selectingZone: newChoosing !== choosing ? resetZone : selectingZone,
3525
- tableReactive: { current: table }
3526
3574
  };
3527
3575
  }
3528
3576
  }
3529
- const clearFilterRows = new ClearFilterRowsAction().bind();
3577
+ const filterRows = new FilterRowsAction().bind();
3530
3578
  class SetColumnMenuAction extends CoreAction {
3531
3579
  reduce(store, payload) {
3532
3580
  return {
@@ -3536,35 +3584,15 @@ class SetColumnMenuAction extends CoreAction {
3536
3584
  }
3537
3585
  }
3538
3586
  const setColumnMenu = new SetColumnMenuAction().bind();
3539
- class SetColLabelAction extends CoreAction {
3587
+ class SetRowMenuAction extends CoreAction {
3540
3588
  reduce(store, payload) {
3541
- const { x, label } = payload;
3542
- const { tableReactive: tableRef, selectingZone, choosing } = store;
3543
- const table = tableRef.current;
3544
- if (table == null) {
3545
- return store;
3546
- }
3547
- table.setColLabel({
3548
- x,
3549
- label,
3550
- undoReflection: {
3551
- sheetId: table.sheetId,
3552
- selectingZone,
3553
- choosing
3554
- },
3555
- redoReflection: {
3556
- sheetId: table.sheetId,
3557
- selectingZone,
3558
- choosing
3559
- }
3560
- });
3561
3589
  return {
3562
3590
  ...store,
3563
- tableReactive: { current: table }
3591
+ rowMenuState: payload
3564
3592
  };
3565
3593
  }
3566
3594
  }
3567
- const setColLabel = new SetColLabelAction().bind();
3595
+ const setRowMenu = new SetRowMenuAction().bind();
3568
3596
  class setStoreAction extends CoreAction {
3569
3597
  reduce(store, payload) {
3570
3598
  return {
@@ -3599,9 +3627,7 @@ const userActions = {
3599
3627
  removeRows,
3600
3628
  removeCols,
3601
3629
  sortRows,
3602
- filterRows,
3603
- clearFilterRows,
3604
- setColLabel
3630
+ filterRows
3605
3631
  };
3606
3632
  const clip = (store) => {
3607
3633
  const { selectingZone, choosing, editorRef, tableReactive: tableRef } = store;
@@ -3641,6 +3667,9 @@ const clip = (store) => {
3641
3667
  const table2tsv = (table) => {
3642
3668
  const lines = [];
3643
3669
  for (let y = table.top; y <= table.bottom; y++) {
3670
+ if (table.isRowFiltered(y)) {
3671
+ continue;
3672
+ }
3644
3673
  const cols = [];
3645
3674
  for (let x = table.left; x <= table.right; x++) {
3646
3675
  const point = { y, x };
@@ -3659,6 +3688,9 @@ const table2tsv = (table) => {
3659
3688
  const table2html = (table) => {
3660
3689
  const lines = [];
3661
3690
  for (let y = table.top; y <= table.bottom; y++) {
3691
+ if (table.isRowFiltered(y)) {
3692
+ continue;
3693
+ }
3662
3694
  const cols = [];
3663
3695
  for (let x = table.left; x <= table.right; x++) {
3664
3696
  const point = { y, x };
@@ -3773,7 +3805,9 @@ const COLOR_PALETTE = [
3773
3805
  // pink
3774
3806
  "#FF00FF",
3775
3807
  // navy
3776
- "#3366FF"
3808
+ "#3366FF",
3809
+ // cyan
3810
+ "#008888"
3777
3811
  ];
3778
3812
  const useBrowser = () => {
3779
3813
  const [ok, setOk] = useState(false);
@@ -4227,6 +4261,13 @@ const Editor = ({ mode }) => {
4227
4261
  return false;
4228
4262
  }
4229
4263
  break;
4264
+ case "Delete":
4265
+ if (!editing) {
4266
+ dispatch(clear(null));
4267
+ dispatch(setInputting(""));
4268
+ return false;
4269
+ }
4270
+ break;
4230
4271
  case "Shift":
4231
4272
  setShiftKey(true);
4232
4273
  return false;
@@ -5020,22 +5061,34 @@ const colsRemover = async ({ store, dispatch }) => {
5020
5061
  };
5021
5062
  const rowsSorterAsc = async ({ store, dispatch }, x) => {
5022
5063
  var _a;
5064
+ const table = store.tableReactive.current;
5065
+ if (table && (table.hasPendingCells() || table.wire.asyncPending.size > 0)) {
5066
+ await table.waitForPending();
5067
+ }
5023
5068
  dispatch(sortRows({ x, direction: "asc" }));
5024
5069
  (_a = store.editorRef.current) == null ? void 0 : _a.focus();
5025
5070
  };
5026
5071
  const rowsSorterDesc = async ({ store, dispatch }, x) => {
5027
5072
  var _a;
5073
+ const table = store.tableReactive.current;
5074
+ if (table && (table.hasPendingCells() || table.wire.asyncPending.size > 0)) {
5075
+ await table.waitForPending();
5076
+ }
5028
5077
  dispatch(sortRows({ x, direction: "desc" }));
5029
5078
  (_a = store.editorRef.current) == null ? void 0 : _a.focus();
5030
5079
  };
5031
5080
  const rowsFilterer = async ({ store, dispatch }, x, filter) => {
5032
5081
  var _a;
5082
+ const table = store.tableReactive.current;
5083
+ if (table && (table.hasPendingCells() || table.wire.asyncPending.size > 0)) {
5084
+ await table.waitForPending();
5085
+ }
5033
5086
  dispatch(filterRows({ x, filter }));
5034
5087
  (_a = store.editorRef.current) == null ? void 0 : _a.focus();
5035
5088
  };
5036
5089
  const rowsFilterClearer = async ({ store, dispatch }, x) => {
5037
5090
  var _a;
5038
- dispatch(clearFilterRows({ x }));
5091
+ dispatch(filterRows({ x }));
5039
5092
  (_a = store.editorRef.current) == null ? void 0 : _a.focus();
5040
5093
  };
5041
5094
  const syncers = {
@@ -5363,14 +5416,64 @@ const NO_VALUE_METHODS = ["blank", "nonblank"];
5363
5416
  const DEFAULT_CONDITION = { method: "eq", value: [""] };
5364
5417
  const ColumnMenu = () => {
5365
5418
  const { store, dispatch } = useContext(Context);
5366
- const { columnMenuState, tableReactive: tableRef, editorRef } = store;
5419
+ const { columnMenuState, tableReactive: tableRef, editorRef, selectingZone } = store;
5367
5420
  const table = tableRef.current;
5368
5421
  const [conditions, setConditions] = useState([{ ...DEFAULT_CONDITION }]);
5369
5422
  const [mode, setMode] = useState("or");
5370
5423
  const [label, setLabel] = useState("");
5371
5424
  const labelInputRef = useRef(null);
5425
+ const [pendingAction, setPendingAction] = useState(null);
5426
+ const waiting = pendingAction != null;
5372
5427
  const x = columnMenuState == null ? void 0 : columnMenuState.x;
5373
5428
  const position = columnMenuState == null ? void 0 : columnMenuState.position;
5429
+ const firstValueRef = useCallback(
5430
+ (node) => {
5431
+ if (node) {
5432
+ node.focus();
5433
+ }
5434
+ },
5435
+ [x]
5436
+ );
5437
+ useEffect(() => {
5438
+ if (!pendingAction) {
5439
+ return;
5440
+ }
5441
+ let cancelled = false;
5442
+ const execute = () => {
5443
+ var _a;
5444
+ if (cancelled) {
5445
+ return;
5446
+ }
5447
+ const currentTable2 = tableRef.current;
5448
+ if (!currentTable2) {
5449
+ return;
5450
+ }
5451
+ const { type, x: actionX, filter } = pendingAction;
5452
+ if (type === "sortAsc") {
5453
+ dispatch(sortRows({ x: actionX, direction: "asc" }));
5454
+ } else if (type === "sortDesc") {
5455
+ dispatch(sortRows({ x: actionX, direction: "desc" }));
5456
+ } else if (type === "filter" && filter) {
5457
+ if (filter.conditions.length === 0) {
5458
+ dispatch(filterRows({ x: actionX }));
5459
+ } else {
5460
+ dispatch(filterRows({ x: actionX, filter }));
5461
+ }
5462
+ }
5463
+ setPendingAction(null);
5464
+ dispatch(setColumnMenu(null));
5465
+ (_a = editorRef.current) == null ? void 0 : _a.focus();
5466
+ };
5467
+ const currentTable = tableRef.current;
5468
+ if (currentTable && (currentTable.hasPendingCells() || currentTable.wire.asyncPending.size > 0)) {
5469
+ currentTable.waitForPending().then(execute);
5470
+ } else {
5471
+ execute();
5472
+ }
5473
+ return () => {
5474
+ cancelled = true;
5475
+ };
5476
+ }, [pendingAction, dispatch, editorRef, tableRef]);
5374
5477
  useEffect(() => {
5375
5478
  if (x != null && table) {
5376
5479
  const colCell2 = table.getCellByPoint({ y: 0, x }, "SYSTEM");
@@ -5392,33 +5495,46 @@ const ColumnMenu = () => {
5392
5495
  }, [dispatch, editorRef]);
5393
5496
  const handleApplyLabel = useCallback(() => {
5394
5497
  var _a;
5395
- if (x == null) {
5498
+ if (x == null || table == null) {
5396
5499
  return;
5397
5500
  }
5398
- dispatch(setColLabel({ x, label }));
5501
+ const address = p2a({ y: 0, x });
5502
+ table.update({
5503
+ diff: { [address]: { label: label || void 0 } },
5504
+ partial: true,
5505
+ ignoreFields: [],
5506
+ undoReflection: {
5507
+ sheetId: table.sheetId,
5508
+ selectingZone: store.selectingZone,
5509
+ choosing: store.choosing
5510
+ },
5511
+ redoReflection: {
5512
+ sheetId: table.sheetId,
5513
+ selectingZone: store.selectingZone,
5514
+ choosing: store.choosing
5515
+ }
5516
+ });
5399
5517
  dispatch(setColumnMenu(null));
5518
+ dispatch(
5519
+ setStore({
5520
+ tableReactive: { current: table }
5521
+ })
5522
+ );
5400
5523
  (_a = editorRef.current) == null ? void 0 : _a.focus();
5401
- }, [dispatch, x, label, editorRef]);
5524
+ }, [dispatch, x, label, editorRef, table, store.selectingZone, store.choosing]);
5402
5525
  const handleSortAsc = useCallback(() => {
5403
- var _a;
5404
5526
  if (x == null) {
5405
5527
  return;
5406
5528
  }
5407
- dispatch(sortRows({ x, direction: "asc" }));
5408
- dispatch(setColumnMenu(null));
5409
- (_a = editorRef.current) == null ? void 0 : _a.focus();
5410
- }, [dispatch, x, editorRef]);
5529
+ setPendingAction({ type: "sortAsc", x });
5530
+ }, [x]);
5411
5531
  const handleSortDesc = useCallback(() => {
5412
- var _a;
5413
5532
  if (x == null) {
5414
5533
  return;
5415
5534
  }
5416
- dispatch(sortRows({ x, direction: "desc" }));
5417
- dispatch(setColumnMenu(null));
5418
- (_a = editorRef.current) == null ? void 0 : _a.focus();
5419
- }, [dispatch, x, editorRef]);
5535
+ setPendingAction({ type: "sortDesc", x });
5536
+ }, [x]);
5420
5537
  const handleApplyFilter = useCallback(() => {
5421
- var _a;
5422
5538
  if (x == null) {
5423
5539
  return;
5424
5540
  }
@@ -5428,23 +5544,19 @@ const ColumnMenu = () => {
5428
5544
  }
5429
5545
  return c.value.some((v) => v.trim() !== "");
5430
5546
  });
5431
- if (valid.length === 0) {
5432
- dispatch(clearFilterRows({ x }));
5433
- } else {
5434
- dispatch(
5435
- filterRows({
5436
- x,
5437
- filter: { mode, conditions: valid }
5438
- })
5439
- );
5440
- }
5441
- dispatch(setColumnMenu(null));
5442
- (_a = editorRef.current) == null ? void 0 : _a.focus();
5443
- }, [dispatch, x, conditions, mode, editorRef]);
5547
+ setPendingAction({
5548
+ type: "filter",
5549
+ x,
5550
+ filter: { mode, conditions: valid }
5551
+ });
5552
+ }, [x, conditions, mode]);
5444
5553
  const handleResetColumn = useCallback(() => {
5445
5554
  var _a;
5446
- if (x == null) return;
5447
- dispatch(clearFilterRows({ x }));
5555
+ if (x == null) {
5556
+ return;
5557
+ }
5558
+ setPendingAction(null);
5559
+ dispatch(filterRows({ x }));
5448
5560
  setConditions([{ ...DEFAULT_CONDITION, value: [""] }]);
5449
5561
  setMode("or");
5450
5562
  dispatch(setColumnMenu(null));
@@ -5452,12 +5564,35 @@ const ColumnMenu = () => {
5452
5564
  }, [dispatch, x, editorRef]);
5453
5565
  const handleResetAll = useCallback(() => {
5454
5566
  var _a;
5455
- dispatch(clearFilterRows({}));
5567
+ setPendingAction(null);
5568
+ dispatch(filterRows({}));
5456
5569
  setConditions([{ ...DEFAULT_CONDITION, value: [""] }]);
5457
5570
  setMode("or");
5458
5571
  dispatch(setColumnMenu(null));
5459
5572
  (_a = editorRef.current) == null ? void 0 : _a.focus();
5460
5573
  }, [dispatch, editorRef]);
5574
+ const handleCancel = useCallback(() => {
5575
+ var _a;
5576
+ setPendingAction(null);
5577
+ dispatch(setColumnMenu(null));
5578
+ (_a = editorRef.current) == null ? void 0 : _a.focus();
5579
+ }, [dispatch, editorRef]);
5580
+ useEffect(() => {
5581
+ if (!waiting) {
5582
+ return;
5583
+ }
5584
+ const onKeyDown = (e) => {
5585
+ if (e.key === "Escape") {
5586
+ e.preventDefault();
5587
+ e.stopPropagation();
5588
+ handleCancel();
5589
+ }
5590
+ };
5591
+ document.addEventListener("keydown", onKeyDown, true);
5592
+ return () => {
5593
+ document.removeEventListener("keydown", onKeyDown, true);
5594
+ };
5595
+ }, [waiting, handleCancel]);
5461
5596
  const updateCondition = useCallback((index, patch) => {
5462
5597
  setConditions((prev) => {
5463
5598
  const next = [...prev];
@@ -5485,20 +5620,39 @@ const ColumnMenu = () => {
5485
5620
  const filterDisabled = hasOperation(colCell == null ? void 0 : colCell.prevention, Filter);
5486
5621
  const labelDisabled = hasOperation(colCell == null ? void 0 : colCell.prevention, SetLabel);
5487
5622
  const labelPlaceholder = table.getLabel(void 0, colCell == null ? void 0 : colCell.labeler, x) ?? x2c(x);
5488
- const insertDisabled = table.maxNumCols !== -1 && table.getNumCols() + 1 > table.maxNumCols;
5489
- insertDisabled || hasOperation(colCell == null ? void 0 : colCell.prevention, InsertColsLeft);
5490
- insertDisabled || hasOperation(colCell == null ? void 0 : colCell.prevention, InsertColsRight);
5491
- table.minNumCols !== -1 && table.getNumCols() - 1 < table.minNumCols || hasOperation(colCell == null ? void 0 : colCell.prevention, RemoveCols);
5623
+ const selColStart = Math.min(selectingZone.startX, selectingZone.endX);
5624
+ const selColEnd = Math.max(selectingZone.startX, selectingZone.endX);
5625
+ const isFullColSelection = selectingZone.startY === 1 && selectingZone.endY === table.getNumRows();
5626
+ const numSelectedCols = isFullColSelection && between({ start: selectingZone.startX, end: selectingZone.endX }, x) ? selColEnd - selColStart + 1 : 1;
5627
+ const insertDisabled = table.maxNumCols !== -1 && table.getNumCols() + numSelectedCols > table.maxNumCols;
5628
+ const insertLeftDisabled = insertDisabled || hasOperation(colCell == null ? void 0 : colCell.prevention, InsertColsLeft);
5629
+ const insertRightDisabled = insertDisabled || hasOperation(colCell == null ? void 0 : colCell.prevention, InsertColsRight);
5630
+ const removeDisabled = table.minNumCols !== -1 && table.getNumCols() - numSelectedCols < table.minNumCols || hasOperation(colCell == null ? void 0 : colCell.prevention, RemoveCols);
5631
+ const waitingMessage = (pendingAction == null ? void 0 : pendingAction.type) === "filter" ? "Filtering..." : (pendingAction == null ? void 0 : pendingAction.type) === "sortAsc" || (pendingAction == null ? void 0 : pendingAction.type) === "sortDesc" ? "Sorting..." : "Processing...";
5492
5632
  return /* @__PURE__ */ jsx(
5493
5633
  Fixed,
5494
5634
  {
5495
5635
  className: "gs-column-menu-modal",
5496
5636
  onClick: (e) => {
5497
5637
  e.preventDefault();
5498
- handleClose();
5638
+ if (!waiting) {
5639
+ handleClose();
5640
+ }
5499
5641
  return false;
5500
5642
  },
5501
- children: /* @__PURE__ */ jsx(
5643
+ children: waiting ? /* @__PURE__ */ jsxs(
5644
+ "div",
5645
+ {
5646
+ className: "gs-column-menu gs-column-menu-waiting",
5647
+ style: { top: position.y, left: position.x },
5648
+ onClick: (e) => e.stopPropagation(),
5649
+ children: [
5650
+ /* @__PURE__ */ jsx("div", { className: "gs-waiting-message", children: waitingMessage }),
5651
+ /* @__PURE__ */ jsx("div", { className: "gs-waiting-spinner" }),
5652
+ /* @__PURE__ */ jsx("button", { className: "gs-waiting-cancel-btn", onClick: handleCancel, children: "CANCEL" })
5653
+ ]
5654
+ }
5655
+ ) : /* @__PURE__ */ jsx(
5502
5656
  "div",
5503
5657
  {
5504
5658
  className: "gs-column-menu",
@@ -5545,6 +5699,7 @@ const ColumnMenu = () => {
5545
5699
  className: "gs-filter-method-select",
5546
5700
  value: cond.method,
5547
5701
  disabled: filterDisabled,
5702
+ tabIndex: i * 2 + 1,
5548
5703
  onChange: (e) => updateCondition(i, {
5549
5704
  method: e.target.value
5550
5705
  }),
@@ -5554,11 +5709,13 @@ const ColumnMenu = () => {
5554
5709
  !NO_VALUE_METHODS.includes(cond.method) && /* @__PURE__ */ jsx(
5555
5710
  "input",
5556
5711
  {
5712
+ ref: i === 0 ? firstValueRef : void 0,
5557
5713
  className: "gs-filter-value-input",
5558
5714
  type: "text",
5559
5715
  placeholder: "Value",
5560
5716
  value: cond.value[0] || "",
5561
5717
  disabled: filterDisabled,
5718
+ tabIndex: i * 2 + 2,
5562
5719
  onChange: (e) => updateCondition(i, { value: [e.target.value] }),
5563
5720
  onKeyDown: (e) => {
5564
5721
  if (e.nativeEvent.isComposing) {
@@ -5585,9 +5742,9 @@ const ColumnMenu = () => {
5585
5742
  )
5586
5743
  ] }, i)) }),
5587
5744
  /* @__PURE__ */ jsxs("div", { className: "gs-filter-actions", children: [
5588
- hasAnyFilter && /* @__PURE__ */ jsx("button", { className: "gs-filter-reset-all-btn", onClick: handleResetAll, disabled: filterDisabled, children: "RESET ALL" }),
5745
+ hasAnyFilter && /* @__PURE__ */ jsx("button", { className: "gs-filter-reset-all-btn", onClick: handleResetAll, children: "RESET ALL" }),
5589
5746
  /* @__PURE__ */ jsxs("div", { className: "gs-filter-actions-right", children: [
5590
- (colCell == null ? void 0 : colCell.filter) && /* @__PURE__ */ jsx("button", { className: "gs-filter-reset-btn", onClick: handleResetColumn, disabled: filterDisabled, children: "RESET" }),
5747
+ (colCell == null ? void 0 : colCell.filter) && /* @__PURE__ */ jsx("button", { className: "gs-filter-reset-btn", onClick: handleResetColumn, children: "RESET" }),
5591
5748
  /* @__PURE__ */ jsx("button", { className: "gs-filter-apply-btn", onClick: handleApplyFilter, disabled: filterDisabled, children: "APPLY" })
5592
5749
  ] })
5593
5750
  ] })
@@ -5644,33 +5801,285 @@ const ColumnMenu = () => {
5644
5801
  }
5645
5802
  ),
5646
5803
  /* @__PURE__ */ jsx("button", { className: "gs-label-apply-btn", onClick: handleApplyLabel, disabled: labelDisabled, children: "UPDATE" })
5647
- ] }) })
5648
- ] })
5649
- }
5650
- )
5651
- }
5652
- );
5653
- };
5654
- var utc$2 = { exports: {} };
5655
- var utc$1 = utc$2.exports;
5656
- var hasRequiredUtc;
5657
- function requireUtc() {
5658
- if (hasRequiredUtc) return utc$2.exports;
5659
- hasRequiredUtc = 1;
5660
- (function(module, exports) {
5661
- !function(t, i) {
5662
- module.exports = i();
5663
- }(utc$1, function() {
5664
- var t = "minute", i = /[+-]\d\d(?::?\d\d)?/g, e = /([+-]|\d\d)/g;
5665
- return function(s, f, n) {
5666
- var u = f.prototype;
5667
- n.utc = function(t2) {
5668
- var i2 = { date: t2, utc: true, args: arguments };
5669
- return new f(i2);
5670
- }, u.utc = function(i2) {
5671
- var e2 = n(this.toDate(), { locale: this.$L, utc: true });
5672
- return i2 ? e2.add(this.utcOffset(), t) : e2;
5673
- }, u.local = function() {
5804
+ ] }) }),
5805
+ /* @__PURE__ */ jsx("li", { className: "gs-menu-divider" }),
5806
+ /* @__PURE__ */ jsx(
5807
+ "li",
5808
+ {
5809
+ className: "gs-enabled",
5810
+ onClick: async () => {
5811
+ await cutter({ store, dispatch });
5812
+ dispatch(setColumnMenu(null));
5813
+ },
5814
+ children: /* @__PURE__ */ jsx("div", { className: "gs-menu-name", children: "Cut" })
5815
+ }
5816
+ ),
5817
+ /* @__PURE__ */ jsx(
5818
+ "li",
5819
+ {
5820
+ className: "gs-enabled",
5821
+ onClick: async () => {
5822
+ await copier({ store, dispatch });
5823
+ dispatch(setColumnMenu(null));
5824
+ },
5825
+ children: /* @__PURE__ */ jsx("div", { className: "gs-menu-name", children: "Copy" })
5826
+ }
5827
+ ),
5828
+ /* @__PURE__ */ jsx(
5829
+ "li",
5830
+ {
5831
+ className: "gs-enabled",
5832
+ onClick: async () => {
5833
+ await paster({ store, dispatch }, false);
5834
+ dispatch(setColumnMenu(null));
5835
+ },
5836
+ children: /* @__PURE__ */ jsx("div", { className: "gs-menu-name", children: "Paste" })
5837
+ }
5838
+ ),
5839
+ /* @__PURE__ */ jsx(
5840
+ "li",
5841
+ {
5842
+ className: "gs-enabled",
5843
+ onClick: async () => {
5844
+ await paster({ store, dispatch }, true);
5845
+ dispatch(setColumnMenu(null));
5846
+ },
5847
+ children: /* @__PURE__ */ jsx("div", { className: "gs-menu-name", children: "Paste only value" })
5848
+ }
5849
+ ),
5850
+ /* @__PURE__ */ jsx("li", { className: "gs-menu-divider" }),
5851
+ /* @__PURE__ */ jsx(
5852
+ "li",
5853
+ {
5854
+ className: insertLeftDisabled ? "gs-disabled" : "gs-enabled",
5855
+ onClick: () => {
5856
+ var _a;
5857
+ if (!insertLeftDisabled) {
5858
+ dispatch(insertColsLeft({ numCols: numSelectedCols, x, operator: "USER" }));
5859
+ dispatch(setColumnMenu(null));
5860
+ (_a = editorRef.current) == null ? void 0 : _a.focus();
5861
+ }
5862
+ },
5863
+ children: /* @__PURE__ */ jsxs("div", { className: "gs-menu-name", children: [
5864
+ "Insert ",
5865
+ numSelectedCols,
5866
+ " column",
5867
+ numSelectedCols > 1 ? "s" : "",
5868
+ " left"
5869
+ ] })
5870
+ }
5871
+ ),
5872
+ /* @__PURE__ */ jsx(
5873
+ "li",
5874
+ {
5875
+ className: insertRightDisabled ? "gs-disabled" : "gs-enabled",
5876
+ onClick: () => {
5877
+ var _a;
5878
+ if (!insertRightDisabled) {
5879
+ dispatch(insertColsRight({ numCols: numSelectedCols, x, operator: "USER" }));
5880
+ dispatch(setColumnMenu(null));
5881
+ (_a = editorRef.current) == null ? void 0 : _a.focus();
5882
+ }
5883
+ },
5884
+ children: /* @__PURE__ */ jsxs("div", { className: "gs-menu-name", children: [
5885
+ "Insert ",
5886
+ numSelectedCols,
5887
+ " column",
5888
+ numSelectedCols > 1 ? "s" : "",
5889
+ " right"
5890
+ ] })
5891
+ }
5892
+ ),
5893
+ /* @__PURE__ */ jsx(
5894
+ "li",
5895
+ {
5896
+ className: removeDisabled ? "gs-disabled" : "gs-enabled",
5897
+ onClick: () => {
5898
+ var _a;
5899
+ if (!removeDisabled) {
5900
+ dispatch(removeCols({ numCols: numSelectedCols, x, operator: "USER" }));
5901
+ dispatch(setColumnMenu(null));
5902
+ (_a = editorRef.current) == null ? void 0 : _a.focus();
5903
+ }
5904
+ },
5905
+ children: /* @__PURE__ */ jsxs("div", { className: "gs-menu-name", children: [
5906
+ "Remove ",
5907
+ numSelectedCols,
5908
+ " column",
5909
+ numSelectedCols > 1 ? "s" : ""
5910
+ ] })
5911
+ }
5912
+ )
5913
+ ] })
5914
+ }
5915
+ )
5916
+ }
5917
+ );
5918
+ };
5919
+ const RowMenu = () => {
5920
+ const { store, dispatch } = useContext(Context);
5921
+ const { rowMenuState, tableReactive: tableRef, editorRef, selectingZone } = store;
5922
+ const table = tableRef.current;
5923
+ const y = rowMenuState == null ? void 0 : rowMenuState.y;
5924
+ const position = rowMenuState == null ? void 0 : rowMenuState.position;
5925
+ const handleClose = () => {
5926
+ var _a;
5927
+ dispatch(setRowMenu(null));
5928
+ (_a = editorRef.current) == null ? void 0 : _a.focus();
5929
+ };
5930
+ if (!rowMenuState || !table || y == null || !position) {
5931
+ return null;
5932
+ }
5933
+ const rowCell = table.getCellByPoint({ y, x: 0 }, "SYSTEM");
5934
+ const selRowStart = Math.min(selectingZone.startY, selectingZone.endY);
5935
+ const selRowEnd = Math.max(selectingZone.startY, selectingZone.endY);
5936
+ const isFullRowSelection = selectingZone.startX === 1 && selectingZone.endX === table.getNumCols();
5937
+ const numSelectedRows = isFullRowSelection && between({ start: selectingZone.startY, end: selectingZone.endY }, y) ? selRowEnd - selRowStart + 1 : 1;
5938
+ const insertDisabled = table.maxNumRows !== -1 && table.getNumRows() + numSelectedRows > table.maxNumRows;
5939
+ const insertAboveDisabled = insertDisabled || hasOperation(rowCell == null ? void 0 : rowCell.prevention, InsertRowsAbove);
5940
+ const insertBelowDisabled = insertDisabled || hasOperation(rowCell == null ? void 0 : rowCell.prevention, InsertRowsBelow);
5941
+ const removeDisabled = table.minNumRows !== -1 && table.getNumRows() - numSelectedRows < table.minNumRows || hasOperation(rowCell == null ? void 0 : rowCell.prevention, RemoveRows);
5942
+ return /* @__PURE__ */ jsx(
5943
+ Fixed,
5944
+ {
5945
+ className: "gs-row-menu-modal",
5946
+ onClick: (e) => {
5947
+ e.preventDefault();
5948
+ handleClose();
5949
+ return false;
5950
+ },
5951
+ children: /* @__PURE__ */ jsx("div", { className: "gs-row-menu", style: { top: position.y, left: position.x }, onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxs("ul", { children: [
5952
+ /* @__PURE__ */ jsx(
5953
+ "li",
5954
+ {
5955
+ className: "gs-enabled",
5956
+ onClick: async () => {
5957
+ await cutter({ store, dispatch });
5958
+ dispatch(setRowMenu(null));
5959
+ },
5960
+ children: /* @__PURE__ */ jsx("div", { className: "gs-menu-name", children: "Cut" })
5961
+ }
5962
+ ),
5963
+ /* @__PURE__ */ jsx(
5964
+ "li",
5965
+ {
5966
+ className: "gs-enabled",
5967
+ onClick: async () => {
5968
+ await copier({ store, dispatch });
5969
+ dispatch(setRowMenu(null));
5970
+ },
5971
+ children: /* @__PURE__ */ jsx("div", { className: "gs-menu-name", children: "Copy" })
5972
+ }
5973
+ ),
5974
+ /* @__PURE__ */ jsx(
5975
+ "li",
5976
+ {
5977
+ className: "gs-enabled",
5978
+ onClick: async () => {
5979
+ await paster({ store, dispatch }, false);
5980
+ dispatch(setRowMenu(null));
5981
+ },
5982
+ children: /* @__PURE__ */ jsx("div", { className: "gs-menu-name", children: "Paste" })
5983
+ }
5984
+ ),
5985
+ /* @__PURE__ */ jsx(
5986
+ "li",
5987
+ {
5988
+ className: "gs-enabled",
5989
+ onClick: async () => {
5990
+ await paster({ store, dispatch }, true);
5991
+ dispatch(setRowMenu(null));
5992
+ },
5993
+ children: /* @__PURE__ */ jsx("div", { className: "gs-menu-name", children: "Paste only value" })
5994
+ }
5995
+ ),
5996
+ /* @__PURE__ */ jsx("li", { className: "gs-menu-divider" }),
5997
+ /* @__PURE__ */ jsx(
5998
+ "li",
5999
+ {
6000
+ className: insertAboveDisabled ? "gs-disabled" : "gs-enabled",
6001
+ onClick: () => {
6002
+ var _a;
6003
+ if (!insertAboveDisabled) {
6004
+ dispatch(insertRowsAbove({ numRows: numSelectedRows, y, operator: "USER" }));
6005
+ dispatch(setRowMenu(null));
6006
+ (_a = editorRef.current) == null ? void 0 : _a.focus();
6007
+ }
6008
+ },
6009
+ children: /* @__PURE__ */ jsxs("div", { className: "gs-menu-name", children: [
6010
+ "Insert ",
6011
+ numSelectedRows,
6012
+ " row",
6013
+ numSelectedRows > 1 ? "s" : "",
6014
+ " above"
6015
+ ] })
6016
+ }
6017
+ ),
6018
+ /* @__PURE__ */ jsx(
6019
+ "li",
6020
+ {
6021
+ className: insertBelowDisabled ? "gs-disabled" : "gs-enabled",
6022
+ onClick: () => {
6023
+ var _a;
6024
+ if (!insertBelowDisabled) {
6025
+ dispatch(insertRowsBelow({ numRows: numSelectedRows, y, operator: "USER" }));
6026
+ dispatch(setRowMenu(null));
6027
+ (_a = editorRef.current) == null ? void 0 : _a.focus();
6028
+ }
6029
+ },
6030
+ children: /* @__PURE__ */ jsxs("div", { className: "gs-menu-name", children: [
6031
+ "Insert ",
6032
+ numSelectedRows,
6033
+ " row",
6034
+ numSelectedRows > 1 ? "s" : "",
6035
+ " below"
6036
+ ] })
6037
+ }
6038
+ ),
6039
+ /* @__PURE__ */ jsx(
6040
+ "li",
6041
+ {
6042
+ className: removeDisabled ? "gs-disabled" : "gs-enabled",
6043
+ onClick: () => {
6044
+ var _a;
6045
+ if (!removeDisabled) {
6046
+ dispatch(removeRows({ numRows: numSelectedRows, y, operator: "USER" }));
6047
+ dispatch(setRowMenu(null));
6048
+ (_a = editorRef.current) == null ? void 0 : _a.focus();
6049
+ }
6050
+ },
6051
+ children: /* @__PURE__ */ jsxs("div", { className: "gs-menu-name", children: [
6052
+ "Remove ",
6053
+ numSelectedRows,
6054
+ " row",
6055
+ numSelectedRows > 1 ? "s" : ""
6056
+ ] })
6057
+ }
6058
+ )
6059
+ ] }) })
6060
+ }
6061
+ );
6062
+ };
6063
+ var utc$2 = { exports: {} };
6064
+ var utc$1 = utc$2.exports;
6065
+ var hasRequiredUtc;
6066
+ function requireUtc() {
6067
+ if (hasRequiredUtc) return utc$2.exports;
6068
+ hasRequiredUtc = 1;
6069
+ (function(module, exports) {
6070
+ !function(t, i) {
6071
+ module.exports = i();
6072
+ }(utc$1, function() {
6073
+ var t = "minute", i = /[+-]\d\d(?::?\d\d)?/g, e = /([+-]|\d\d)/g;
6074
+ return function(s, f, n) {
6075
+ var u = f.prototype;
6076
+ n.utc = function(t2) {
6077
+ var i2 = { date: t2, utc: true, args: arguments };
6078
+ return new f(i2);
6079
+ }, u.utc = function(i2) {
6080
+ var e2 = n(this.toDate(), { locale: this.$L, utc: true });
6081
+ return i2 ? e2.add(this.utcOffset(), t) : e2;
6082
+ }, u.local = function() {
5674
6083
  return n(this.toDate(), { locale: this.$L, utc: false });
5675
6084
  };
5676
6085
  var o = u.parse;
@@ -6026,6 +6435,9 @@ const solveFormula = ({ value, table, raise = true, refEvaluation = "TABLE", ori
6026
6435
  } else {
6027
6436
  table.setSolvedCache(origin, solved);
6028
6437
  }
6438
+ if (solved instanceof Pending) {
6439
+ table.setSolvedCache(origin, solved);
6440
+ }
6029
6441
  return solved;
6030
6442
  };
6031
6443
  const solveTable = ({ table, raise = true }) => {
@@ -6039,6 +6451,8 @@ const solveTable = ({ table, raise = true }) => {
6039
6451
  try {
6040
6452
  if (cache === SOLVING) {
6041
6453
  throw new FormulaError("#REF!", "References are circulating.", new Error(value));
6454
+ } else if (cache instanceof Pending) {
6455
+ return cache;
6042
6456
  } else if (cache instanceof FormulaError) {
6043
6457
  throw cache;
6044
6458
  } else if (cache != null) {
@@ -6059,6 +6473,9 @@ const solveTable = ({ table, raise = true }) => {
6059
6473
  });
6060
6474
  };
6061
6475
  const stripTable = ({ value, y = 0, x = 0, raise = true, history = /* @__PURE__ */ new Set() }) => {
6476
+ if (value instanceof Pending) {
6477
+ return value;
6478
+ }
6062
6479
  if (value instanceof Table) {
6063
6480
  const id = value.getId({ x, y });
6064
6481
  if (history.has(id)) {
@@ -6128,6 +6545,9 @@ class Renderer {
6128
6545
  if (this.condition && !this.condition(value)) {
6129
6546
  return this.complement ? this.complement(value) : this.stringify(props);
6130
6547
  }
6548
+ if (value instanceof Pending) {
6549
+ return this.pending(props);
6550
+ }
6131
6551
  if (value == null) {
6132
6552
  return this.null(props);
6133
6553
  }
@@ -6145,7 +6565,7 @@ class Renderer {
6145
6565
  if (Array.isArray(value)) {
6146
6566
  return this.array(props);
6147
6567
  }
6148
- if (value instanceof FormulaError) {
6568
+ if (FormulaError.is(value)) {
6149
6569
  throw value;
6150
6570
  }
6151
6571
  return this.object(props);
@@ -6160,10 +6580,16 @@ class Renderer {
6160
6580
  }
6161
6581
  return "";
6162
6582
  }
6583
+ pending(_props) {
6584
+ return "";
6585
+ }
6163
6586
  stringify({ value, cell, table, point }) {
6164
6587
  if (value === void 0) {
6165
6588
  value = cell == null ? void 0 : cell.value;
6166
6589
  }
6590
+ if (value instanceof Pending) {
6591
+ return "";
6592
+ }
6167
6593
  if (value instanceof Date) {
6168
6594
  return this.date({ value, cell, table, point });
6169
6595
  }
@@ -6220,19 +6646,124 @@ class Renderer {
6220
6646
  }
6221
6647
  }
6222
6648
  const defaultRenderer = new Renderer();
6649
+ const filterCellFields = (cell, ignoreFields) => {
6650
+ if (ignoreFields.length === 0) {
6651
+ return cell;
6652
+ }
6653
+ return Object.fromEntries(
6654
+ Object.entries(cell).filter(([key]) => !ignoreFields.includes(key))
6655
+ );
6656
+ };
6657
+ const asyncCacheMiss = new Special("asyncCacheMiss");
6658
+ const hasPendingArg = (args) => {
6659
+ return args.some((v) => v instanceof Pending);
6660
+ };
6661
+ const isTable = (v) => v != null && typeof v === "object" && "sheetId" in v && "wire" in v;
6662
+ const cyrb53 = (str, seed = 0) => {
6663
+ let h1 = 3735928559 ^ seed;
6664
+ let h2 = 1103547991 ^ seed;
6665
+ for (let i = 0; i < str.length; i++) {
6666
+ const ch = str.charCodeAt(i);
6667
+ h1 = Math.imul(h1 ^ ch, 2654435761);
6668
+ h2 = Math.imul(h2 ^ ch, 1597334677);
6669
+ }
6670
+ h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507);
6671
+ h1 ^= Math.imul(h2 ^ h2 >>> 13, 3266489909);
6672
+ h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507);
6673
+ h2 ^= Math.imul(h1 ^ h1 >>> 13, 3266489909);
6674
+ return 4294967296 * (2097151 & h2) + (h1 >>> 0);
6675
+ };
6676
+ const buildAsyncCacheKey = (funcName, bareArgs, hashPrecision = 1) => {
6677
+ const argsJson = JSON.stringify(bareArgs, (_key, value) => {
6678
+ if (isTable(value)) {
6679
+ return value.getFieldMatrix();
6680
+ }
6681
+ if (value instanceof Pending) {
6682
+ return null;
6683
+ }
6684
+ return value;
6685
+ });
6686
+ const hashes = Array.from({ length: hashPrecision }, (_, i) => cyrb53(argsJson, i).toString(36));
6687
+ return `${funcName}:${argsJson.length}:${hashes.join("-")}`;
6688
+ };
6689
+ const getAsyncCache = (table, origin, key) => {
6690
+ const cellId = table.getId(origin);
6691
+ const wire = table.wire;
6692
+ const cell = wire.data[cellId];
6693
+ if ((cell == null ? void 0 : cell.asyncCache) != null) {
6694
+ const ac = cell.asyncCache;
6695
+ if (ac.key === key) {
6696
+ if (ac.expireTime == null || Date.now() < ac.expireTime) {
6697
+ return ac.value;
6698
+ }
6699
+ delete cell.asyncCache;
6700
+ } else {
6701
+ delete cell.asyncCache;
6702
+ }
6703
+ }
6704
+ if (wire.asyncPending.has(cellId)) {
6705
+ return wire.asyncPending.get(cellId);
6706
+ }
6707
+ return asyncCacheMiss;
6708
+ };
6709
+ const getOrSaveAsyncCache = (promise, table, origin, key, ttlMilliseconds) => {
6710
+ const cellId = table.getId(origin);
6711
+ const wire = table.wire;
6712
+ const expireTime = ttlMilliseconds != null ? Date.now() + ttlMilliseconds : void 0;
6713
+ const pending = new Pending(promise);
6714
+ wire.asyncPending.set(cellId, pending);
6715
+ promise.then((result) => {
6716
+ const c = wire.data[cellId];
6717
+ if (c != null) {
6718
+ c.asyncCache = { value: result, key, expireTime };
6719
+ }
6720
+ }).catch((error) => {
6721
+ const errValue = new FormulaError("#ASYNC!", (error == null ? void 0 : error.message) ?? String(error), error instanceof Error ? error : void 0);
6722
+ const c = wire.data[cellId];
6723
+ if (c != null) {
6724
+ c.asyncCache = { value: errValue, key, expireTime };
6725
+ }
6726
+ }).finally(() => {
6727
+ wire.asyncPending.delete(cellId);
6728
+ wire.solvedCaches.clear();
6729
+ wire.transmit();
6730
+ });
6731
+ return pending;
6732
+ };
6733
+ const createPropagatedPending = () => {
6734
+ return new Pending(Promise.resolve());
6735
+ };
6223
6736
  class BaseFunction {
6224
6737
  constructor({ args, table, origin }) {
6225
6738
  this.example = "_BASE()";
6226
6739
  this.helpTexts = ["Function's description."];
6227
6740
  this.helpArgs = [{ name: "value1", description: "" }];
6741
+ this.hashPrecision = 1;
6228
6742
  this.bareArgs = args.map((a) => a.evaluate({ table }));
6229
6743
  this.table = table;
6230
6744
  this.origin = origin;
6231
6745
  }
6232
6746
  validate() {
6233
6747
  }
6748
+ get isMainAsync() {
6749
+ var _a, _b;
6750
+ const mainDescriptor = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(this), "main");
6751
+ return ((_b = (_a = mainDescriptor == null ? void 0 : mainDescriptor.value) == null ? void 0 : _a.constructor) == null ? void 0 : _b.name) === "AsyncFunction";
6752
+ }
6234
6753
  call() {
6235
6754
  this.validate();
6755
+ if (hasPendingArg(this.bareArgs)) {
6756
+ return createPropagatedPending();
6757
+ }
6758
+ if (this.isMainAsync) {
6759
+ const key = buildAsyncCacheKey(this.constructor.name, this.bareArgs, this.hashPrecision);
6760
+ const cachedResult = getAsyncCache(this.table, this.origin, key);
6761
+ if (cachedResult !== asyncCacheMiss) {
6762
+ return cachedResult;
6763
+ }
6764
+ const result = this.main(...this.bareArgs);
6765
+ return getOrSaveAsyncCache(result, this.table, this.origin, key, this.ttlMilliseconds);
6766
+ }
6236
6767
  return this.main(...this.bareArgs);
6237
6768
  }
6238
6769
  }
@@ -6270,6 +6801,9 @@ const ne = (left, right) => {
6270
6801
  };
6271
6802
  const ensureNumber = (value, options) => {
6272
6803
  const { alternative, ignore } = options || {};
6804
+ if (value instanceof Pending) {
6805
+ return value;
6806
+ }
6273
6807
  if (typeof value === "undefined" && typeof alternative !== "undefined") {
6274
6808
  return alternative;
6275
6809
  }
@@ -6299,6 +6833,9 @@ const ensureNumber = (value, options) => {
6299
6833
  return num;
6300
6834
  };
6301
6835
  const ensureString = (value) => {
6836
+ if (value instanceof Pending) {
6837
+ return value;
6838
+ }
6302
6839
  if (value === 0) {
6303
6840
  return "0";
6304
6841
  }
@@ -6320,6 +6857,9 @@ const ensureString = (value) => {
6320
6857
  };
6321
6858
  const ensureBoolean = (value, options) => {
6322
6859
  const { alternative, ignore } = options ?? {};
6860
+ if (value instanceof Pending) {
6861
+ return value;
6862
+ }
6323
6863
  if (typeof value === "undefined" && typeof alternative !== "undefined") {
6324
6864
  return alternative;
6325
6865
  }
@@ -8101,7 +8641,6 @@ class Wire {
8101
8641
  policies = {},
8102
8642
  onSave,
8103
8643
  onChange,
8104
- onEdit,
8105
8644
  onRemoveRows,
8106
8645
  onRemoveCols,
8107
8646
  onInsertRows,
@@ -8122,6 +8661,7 @@ class Wire {
8122
8661
  this.paletteBySheetName = {};
8123
8662
  this.lastFocused = null;
8124
8663
  this.solvedCaches = /* @__PURE__ */ new Map();
8664
+ this.asyncPending = /* @__PURE__ */ new Map();
8125
8665
  this.copyingSheetId = 0;
8126
8666
  this.copyingZone = RESET_ZONE;
8127
8667
  this.cutting = false;
@@ -8149,7 +8689,6 @@ class Wire {
8149
8689
  this.policies = policies;
8150
8690
  this.onSave = onSave;
8151
8691
  this.onChange = onChange;
8152
- this.onEdit = onEdit;
8153
8692
  this.onRemoveRows = onRemoveRows;
8154
8693
  this.onRemoveCols = onRemoveCols;
8155
8694
  this.onInsertRows = onInsertRows;
@@ -8186,13 +8725,13 @@ class Wire {
8186
8725
  }
8187
8726
  getSystem(id, table) {
8188
8727
  const cell = this.data[id];
8189
- if (cell == null ? void 0 : cell.system) {
8190
- return cell.system;
8728
+ if (cell == null ? void 0 : cell._sys) {
8729
+ return cell._sys;
8191
8730
  }
8192
8731
  return {
8193
8732
  id,
8194
8733
  sheetId: table.sheetId,
8195
- changedAt: /* @__PURE__ */ new Date(),
8734
+ changedTime: Date.now(),
8196
8735
  dependents: /* @__PURE__ */ new Set()
8197
8736
  };
8198
8737
  }
@@ -8439,7 +8978,7 @@ class ReferencePreserver {
8439
8978
  ids.forEach((id) => {
8440
8979
  var _a, _b;
8441
8980
  const cell = this.table.wire.data[id];
8442
- (_b = (_a = cell == null ? void 0 : cell.system) == null ? void 0 : _a.dependents) == null ? void 0 : _b.forEach((did) => {
8981
+ (_b = (_a = cell == null ? void 0 : cell._sys) == null ? void 0 : _a.dependents) == null ? void 0 : _b.forEach((did) => {
8443
8982
  this.dependentIds.add(did);
8444
8983
  });
8445
8984
  });
@@ -8484,8 +9023,9 @@ class Table {
8484
9023
  this.version = 0;
8485
9024
  this.area = { top: 0, left: 0, bottom: 0, right: 0 };
8486
9025
  this.addressCaches = /* @__PURE__ */ new Map();
9026
+ this.lastChangedAddresses = [];
8487
9027
  this.idMatrix = [];
8488
- this.changedAt = /* @__PURE__ */ new Date();
9028
+ this.changedTime = Date.now();
8489
9029
  this.minNumRows = minNumRows || 0;
8490
9030
  this.maxNumRows = maxNumRows || 0;
8491
9031
  this.minNumCols = minNumCols || 0;
@@ -8538,6 +9078,59 @@ class Table {
8538
9078
  }
8539
9079
  return false;
8540
9080
  }
9081
+ /**
9082
+ * Returns true if any data cell in this sheet currently holds a Pending value
9083
+ * (i.e. an async formula that hasn't resolved yet).
9084
+ */
9085
+ hasPendingCells() {
9086
+ const numRows = this.getNumRows();
9087
+ const numCols = this.getNumCols();
9088
+ for (let y = 1; y <= numRows; y++) {
9089
+ for (let x = 1; x <= numCols; x++) {
9090
+ const cell = this.getCellByPoint({ y, x }, "COMPLETE");
9091
+ if ((cell == null ? void 0 : cell.value) instanceof Pending) {
9092
+ return true;
9093
+ }
9094
+ }
9095
+ }
9096
+ return false;
9097
+ }
9098
+ /**
9099
+ * Returns a Promise that resolves when all in-flight async formula computations
9100
+ * have completed and no data cells hold Pending values.
9101
+ * If nothing is pending, resolves immediately.
9102
+ * Useful for waiting before sort/filter so that cell values are fully resolved.
9103
+ */
9104
+ waitForPending() {
9105
+ const pendingMap = this.wire.asyncPending;
9106
+ if (pendingMap.size > 0) {
9107
+ const promises = Array.from(pendingMap.values()).map((p) => p.promise);
9108
+ return Promise.all(promises).then(() => this.waitForPending());
9109
+ }
9110
+ if (this.hasPendingCells()) {
9111
+ return new Promise((resolve) => {
9112
+ const check2 = () => {
9113
+ if (this.wire.asyncPending.size > 0) {
9114
+ const promises = Array.from(this.wire.asyncPending.values()).map((p) => p.promise);
9115
+ Promise.all(promises).then(check2);
9116
+ } else if (this.hasPendingCells()) {
9117
+ setTimeout(check2, 50);
9118
+ } else {
9119
+ resolve();
9120
+ }
9121
+ };
9122
+ check2();
9123
+ });
9124
+ }
9125
+ return Promise.resolve();
9126
+ }
9127
+ /**
9128
+ * Returns the addresses that were changed in the most recent `_update()` call.
9129
+ * Useful inside `onChange` to know which cells were modified.
9130
+ */
9131
+ getLastChangedAddresses() {
9132
+ return this.lastChangedAddresses;
9133
+ }
8541
9134
  /** Capture the current state of all filter-related cells (column headers + row headers) as a CellsByIdType snapshot */
8542
9135
  /** Capture the full cell state of all filter-related header cells as a CellsByIdType snapshot */
8543
9136
  _captureFilterCellStates() {
@@ -8561,84 +9154,21 @@ class Table {
8561
9154
  }
8562
9155
  filterRows({
8563
9156
  x,
8564
- filter,
8565
- undoReflection,
8566
- redoReflection
8567
- }) {
8568
- const diffBefore = this._captureFilterCellStates();
8569
- const colCell = this._getRawCellByPoint({ y: 0, x });
8570
- if (colCell) {
8571
- colCell.filter = filter;
8572
- }
8573
- this._reapplyFilters();
8574
- const diffAfter = this._captureFilterCellStates();
8575
- this.pushHistory({
8576
- applyed: true,
8577
- operation: "UPDATE",
8578
- srcSheetId: this.sheetId,
8579
- dstSheetId: this.sheetId,
8580
- undoReflection,
8581
- redoReflection,
8582
- diffBefore,
8583
- diffAfter,
8584
- partial: false
8585
- });
8586
- return this.refresh(false, true);
8587
- }
8588
- setColLabel({
8589
- x,
8590
- label,
8591
- undoReflection,
8592
- redoReflection
8593
- }) {
8594
- var _a;
8595
- const id = (_a = this.idMatrix[0]) == null ? void 0 : _a[x];
8596
- const diffBefore = {};
8597
- if (id != null) {
8598
- diffBefore[id] = { ...this.wire.data[id] };
8599
- }
8600
- const colCell = this._getRawCellByPoint({ y: 0, x });
8601
- if (colCell) {
8602
- if (label === "") {
8603
- delete colCell.label;
8604
- } else {
8605
- colCell.label = label;
8606
- }
8607
- }
8608
- const diffAfter = {};
8609
- if (id != null) {
8610
- diffAfter[id] = { ...this.wire.data[id] };
8611
- }
8612
- const changed = Object.keys(diffBefore).some(
8613
- (id2) => JSON.stringify(diffBefore[id2]) !== JSON.stringify(diffAfter[id2])
8614
- );
8615
- if (changed) {
8616
- this.pushHistory({
8617
- applyed: true,
8618
- operation: "UPDATE",
8619
- srcSheetId: this.sheetId,
8620
- dstSheetId: this.sheetId,
8621
- undoReflection,
8622
- redoReflection,
8623
- diffBefore,
8624
- diffAfter,
8625
- partial: false
8626
- });
8627
- }
8628
- return this.refresh(false, true);
8629
- }
8630
- clearFilterRows(x, undoReflection, redoReflection) {
9157
+ filter
9158
+ } = {}) {
8631
9159
  const diffBefore = this._captureFilterCellStates();
8632
- if (x != null) {
8633
- const colCell = this._getRawCellByPoint({ y: 0, x });
8634
- if (colCell) {
8635
- delete colCell.filter;
8636
- }
8637
- } else {
9160
+ if (x == null) {
8638
9161
  const numCols = this.getNumCols();
8639
9162
  for (let col = 1; col <= numCols; col++) {
8640
9163
  const colCell = this._getRawCellByPoint({ y: 0, x: col });
8641
- if (colCell == null ? void 0 : colCell.filter) {
9164
+ colCell == null ? true : delete colCell.filter;
9165
+ }
9166
+ } else {
9167
+ const colCell = this._getRawCellByPoint({ y: 0, x });
9168
+ if (colCell) {
9169
+ if (filter) {
9170
+ colCell.filter = filter;
9171
+ } else {
8642
9172
  delete colCell.filter;
8643
9173
  }
8644
9174
  }
@@ -8654,8 +9184,6 @@ class Table {
8654
9184
  operation: "UPDATE",
8655
9185
  srcSheetId: this.sheetId,
8656
9186
  dstSheetId: this.sheetId,
8657
- undoReflection,
8658
- redoReflection,
8659
9187
  diffBefore,
8660
9188
  diffAfter,
8661
9189
  partial: false
@@ -8663,59 +9191,48 @@ class Table {
8663
9191
  }
8664
9192
  return this.refresh(false, true);
8665
9193
  }
8666
- _evaluateFilterConfig(filter, cellValue) {
8667
- return evaluateFilterConfig(filter, cellValue);
8668
- }
8669
9194
  _reapplyFilters() {
8670
9195
  const numCols = this.getNumCols();
8671
9196
  const activeFilters = [];
9197
+ const changedAddresses = [];
8672
9198
  for (let col = 1; col <= numCols; col++) {
8673
9199
  const colCell = this._getRawCellByPoint({ y: 0, x: col });
8674
9200
  if ((colCell == null ? void 0 : colCell.filter) && colCell.filter.conditions.length > 0) {
8675
9201
  activeFilters.push({ x: col, filter: colCell.filter });
8676
9202
  }
9203
+ changedAddresses.push(p2a({ y: 0, x: col }));
8677
9204
  }
8678
9205
  const numRows = this.getNumRows();
8679
9206
  for (let y = 1; y <= numRows; y++) {
8680
9207
  const rowCell = this._getRawCellByPoint({ y, x: 0 });
8681
- if (rowCell) {
8682
- delete rowCell.filtered;
9208
+ if (!rowCell) {
9209
+ continue;
8683
9210
  }
8684
- }
8685
- if (activeFilters.length === 0) {
8686
- return;
8687
- }
8688
- for (let y = 1; y <= numRows; y++) {
8689
- let visible = true;
9211
+ let shouldFilter = false;
8690
9212
  for (const { x: col, filter } of activeFilters) {
8691
9213
  const cell = this.getCellByPoint({ y, x: col }, "COMPLETE");
8692
- if (!this._evaluateFilterConfig(filter, cell == null ? void 0 : cell.value)) {
8693
- visible = false;
9214
+ if (!evaluateFilterConfig(filter, cell == null ? void 0 : cell.value)) {
9215
+ shouldFilter = true;
8694
9216
  break;
8695
9217
  }
8696
9218
  }
8697
- if (!visible) {
8698
- const rowCell = this._getRawCellByPoint({ y, x: 0 });
8699
- if (rowCell) {
8700
- rowCell.filtered = true;
8701
- }
9219
+ const wasFiltered = !!rowCell.filtered;
9220
+ if (shouldFilter) {
9221
+ rowCell.filtered = true;
9222
+ } else {
9223
+ delete rowCell.filtered;
9224
+ }
9225
+ if (wasFiltered !== shouldFilter) {
9226
+ changedAddresses.push(p2a({ y, x: 0 }));
8702
9227
  }
8703
9228
  }
9229
+ this.lastChangedAddresses = changedAddresses;
8704
9230
  }
8705
- sortRows({
8706
- x,
8707
- direction,
8708
- undoReflection,
8709
- redoReflection
8710
- }) {
9231
+ sortRows({ x, direction }) {
8711
9232
  const numRows = this.getNumRows();
8712
9233
  if (numRows <= 1) {
8713
9234
  return this;
8714
9235
  }
8715
- const rowsBefore = [];
8716
- for (let y = 1; y <= numRows; y++) {
8717
- rowsBefore.push([...this.idMatrix[y]]);
8718
- }
8719
9236
  const rowIndices = [];
8720
9237
  for (let y = 1; y <= numRows; y++) {
8721
9238
  rowIndices.push(y);
@@ -8754,24 +9271,42 @@ class Table {
8754
9271
  if (!changed) {
8755
9272
  return this;
8756
9273
  }
8757
- this._applySortOrder(rowIndices);
8758
- const rowsAfter = [];
8759
- for (let y = 1; y <= numRows; y++) {
8760
- rowsAfter.push([...this.idMatrix[y]]);
9274
+ const sortedRowMapping = {};
9275
+ for (let newY = 0; newY < rowIndices.length; newY++) {
9276
+ const oldY = rowIndices[newY];
9277
+ sortedRowMapping[oldY] = newY + 1;
9278
+ }
9279
+ const savedRows = [];
9280
+ for (let i = 0; i < rowIndices.length; i++) {
9281
+ savedRows.push(this.idMatrix[rowIndices[i]]);
9282
+ }
9283
+ for (let i = 0; i < rowIndices.length; i++) {
9284
+ this.idMatrix[i + 1] = savedRows[i];
8761
9285
  }
9286
+ this.addressCaches.clear();
8762
9287
  this.pushHistory({
8763
9288
  applyed: true,
8764
9289
  operation: "SORT_ROWS",
8765
9290
  srcSheetId: this.sheetId,
8766
9291
  dstSheetId: this.sheetId,
8767
- undoReflection,
8768
- redoReflection,
8769
- rowsBefore,
8770
- rowsAfter
9292
+ sortedRowMapping
8771
9293
  });
8772
9294
  return this.refresh(true, true);
8773
9295
  }
8774
- _applySortOrder(newOrder) {
9296
+ _sortRowMapping(sortedRowMapping, inverse = false) {
9297
+ const numRows = this.getNumRows();
9298
+ const newOrder = new Array(numRows);
9299
+ if (inverse) {
9300
+ for (const [oldYStr, newY] of Object.entries(sortedRowMapping)) {
9301
+ const oldY = Number(oldYStr);
9302
+ newOrder[oldY - 1] = newY;
9303
+ }
9304
+ } else {
9305
+ for (const [oldYStr, newY] of Object.entries(sortedRowMapping)) {
9306
+ const oldY = Number(oldYStr);
9307
+ newOrder[newY - 1] = oldY;
9308
+ }
9309
+ }
8775
9310
  const savedRows = [];
8776
9311
  for (let i = 0; i < newOrder.length; i++) {
8777
9312
  savedRows.push(this.idMatrix[newOrder[i]]);
@@ -8781,12 +9316,6 @@ class Table {
8781
9316
  }
8782
9317
  this.addressCaches.clear();
8783
9318
  }
8784
- _restoreRows(rows) {
8785
- for (let i = 0; i < rows.length; i++) {
8786
- this.idMatrix[i + 1] = [...rows[i]];
8787
- }
8788
- this.addressCaches.clear();
8789
- }
8790
9319
  get isInitialized() {
8791
9320
  return this.status === 2;
8792
9321
  }
@@ -8809,7 +9338,7 @@ class Table {
8809
9338
  this.idsToBeIdentified.forEach((id) => {
8810
9339
  var _a;
8811
9340
  const cell = this.wire.data[id];
8812
- if (((_a = cell == null ? void 0 : cell.system) == null ? void 0 : _a.sheetId) == null) {
9341
+ if (((_a = cell == null ? void 0 : cell._sys) == null ? void 0 : _a.sheetId) == null) {
8813
9342
  return;
8814
9343
  }
8815
9344
  cell.value = identifyFormula(cell == null ? void 0 : cell.value, {
@@ -8840,7 +9369,7 @@ class Table {
8840
9369
  cells[0] = { width: HEADER_WIDTH, height: HEADER_HEIGHT };
8841
9370
  }
8842
9371
  const auto = getMaxSizesFromCells(cells);
8843
- const changedAt = /* @__PURE__ */ new Date();
9372
+ const changedTime = Date.now();
8844
9373
  this.area = {
8845
9374
  top: 1,
8846
9375
  left: 1,
@@ -8913,7 +9442,7 @@ class Table {
8913
9442
  delete stacked.label;
8914
9443
  delete stacked.labeler;
8915
9444
  }
8916
- stacked.system = { id, changedAt, dependents: /* @__PURE__ */ new Set(), sheetId: this.sheetId };
9445
+ stacked._sys = { id, changedTime, dependents: /* @__PURE__ */ new Set(), sheetId: this.sheetId };
8917
9446
  this.wire.data[id] = stacked;
8918
9447
  }
8919
9448
  }
@@ -8937,10 +9466,10 @@ class Table {
8937
9466
  const colLeftCell = this.getCellByPoint({ y: 0, x: l }, "SYSTEM");
8938
9467
  const rowBottomCell = this.getCellByPoint({ y: bottom, x: 0 }, "SYSTEM");
8939
9468
  const rowTopCell = this.getCellByPoint({ y: t, x: 0 }, "SYSTEM");
8940
- const rw = ((_a = colRightCell == null ? void 0 : colRightCell.system) == null ? void 0 : _a.offsetLeft) ?? 0;
8941
- const lw = ((_b = colLeftCell == null ? void 0 : colLeftCell.system) == null ? void 0 : _b.offsetLeft) ?? 0;
8942
- const rh = ((_c = rowBottomCell == null ? void 0 : rowBottomCell.system) == null ? void 0 : _c.offsetTop) ?? 0;
8943
- const th = ((_d = rowTopCell == null ? void 0 : rowTopCell.system) == null ? void 0 : _d.offsetTop) ?? 0;
9469
+ const rw = ((_a = colRightCell == null ? void 0 : colRightCell._sys) == null ? void 0 : _a.offsetLeft) ?? 0;
9470
+ const lw = ((_b = colLeftCell == null ? void 0 : colLeftCell._sys) == null ? void 0 : _b.offsetLeft) ?? 0;
9471
+ const rh = ((_c = rowBottomCell == null ? void 0 : rowBottomCell._sys) == null ? void 0 : _c.offsetTop) ?? 0;
9472
+ const th = ((_d = rowTopCell == null ? void 0 : rowTopCell._sys) == null ? void 0 : _d.offsetTop) ?? 0;
8944
9473
  const width = Math.max(0, rw - lw);
8945
9474
  const height = Math.max(0, rh - th);
8946
9475
  return { width, height };
@@ -8954,8 +9483,8 @@ class Table {
8954
9483
  for (let x = 1; x <= numCols; x++) {
8955
9484
  const cell = this.getCellByPoint({ y: 0, x }, "SYSTEM");
8956
9485
  const w = (cell == null ? void 0 : cell.width) || DEFAULT_WIDTH;
8957
- if (cell == null ? void 0 : cell.system) {
8958
- cell.system.offsetLeft = headerW + accW;
9486
+ if (cell == null ? void 0 : cell._sys) {
9487
+ cell._sys.offsetLeft = headerW + accW;
8959
9488
  }
8960
9489
  accW += w;
8961
9490
  }
@@ -8965,8 +9494,8 @@ class Table {
8965
9494
  for (let y = 1; y <= numRows; y++) {
8966
9495
  const cell = this.getCellByPoint({ y, x: 0 }, "SYSTEM");
8967
9496
  const h = (cell == null ? void 0 : cell.height) || DEFAULT_HEIGHT;
8968
- if (cell == null ? void 0 : cell.system) {
8969
- cell.system.offsetTop = headerH + accH;
9497
+ if (cell == null ? void 0 : cell._sys) {
9498
+ cell._sys.offsetTop = headerH + accH;
8970
9499
  }
8971
9500
  if (!(cell == null ? void 0 : cell.filtered)) {
8972
9501
  accH += h;
@@ -8978,8 +9507,8 @@ class Table {
8978
9507
  }
8979
9508
  refresh(relocate = false, resize = false) {
8980
9509
  this.incrementVersion();
8981
- this.lastChangedAt = this.changedAt;
8982
- this.changedAt = /* @__PURE__ */ new Date();
9510
+ this.lastChangedTime = this.changedTime;
9511
+ this.changedTime = Date.now();
8983
9512
  this.clearSolvedCaches();
8984
9513
  if (relocate) {
8985
9514
  this.addressCaches.clear();
@@ -9137,14 +9666,23 @@ class Table {
9137
9666
  return matrix;
9138
9667
  }
9139
9668
  getFieldObject({
9140
- area,
9141
9669
  field = "value",
9142
9670
  refEvaluation = "COMPLETE",
9143
9671
  raise = false,
9144
- filter = noFilter
9672
+ filter = noFilter,
9673
+ addresses
9145
9674
  } = {}) {
9146
9675
  const result = {};
9147
- const { top, left, bottom, right } = area ?? this.area;
9676
+ if (addresses) {
9677
+ for (const addr of addresses) {
9678
+ const cell = this.getCellByAddress(addr, refEvaluation, raise) ?? {};
9679
+ if (filter(cell)) {
9680
+ result[addr] = cell[field];
9681
+ }
9682
+ }
9683
+ return result;
9684
+ }
9685
+ const { top, left, bottom, right } = this.area;
9148
9686
  for (let y = top; y <= bottom; y++) {
9149
9687
  for (let x = left; x <= right; x++) {
9150
9688
  const cell = this.getCellByPoint({ y, x }, refEvaluation, raise) ?? {};
@@ -9159,11 +9697,13 @@ class Table {
9159
9697
  field = "value",
9160
9698
  refEvaluation = "COMPLETE",
9161
9699
  raise = false,
9162
- filter = noFilter
9700
+ filter = noFilter,
9701
+ rows
9163
9702
  } = {}) {
9164
9703
  const result = [];
9165
9704
  const { top, left, bottom, right } = this.area;
9166
- for (let y = top; y <= bottom; y++) {
9705
+ const ys = rows ?? Array.from({ length: bottom - top + 1 }, (_, i) => top + i);
9706
+ for (const y of ys) {
9167
9707
  const row = {};
9168
9708
  result.push(row);
9169
9709
  for (let x = left; x <= right; x++) {
@@ -9179,11 +9719,13 @@ class Table {
9179
9719
  field = "value",
9180
9720
  refEvaluation = "COMPLETE",
9181
9721
  raise = false,
9182
- filter = noFilter
9722
+ filter = noFilter,
9723
+ cols
9183
9724
  } = {}) {
9184
9725
  const result = [];
9185
9726
  const { top, left, bottom, right } = this.area;
9186
- for (let x = left; x <= right; x++) {
9727
+ const xs = cols ? cols.map((c) => typeof c === "string" ? c2x(c) : c) : Array.from({ length: right - left + 1 }, (_, i) => left + i);
9728
+ for (const x of xs) {
9187
9729
  const col = {};
9188
9730
  result.push(col);
9189
9731
  for (let y = top; y <= bottom; y++) {
@@ -9195,11 +9737,12 @@ class Table {
9195
9737
  }
9196
9738
  return result;
9197
9739
  }
9198
- getMatrix({
9740
+ getCellMatrix({
9199
9741
  area,
9200
9742
  refEvaluation = "SYSTEM",
9201
9743
  raise = false,
9202
- filter = noFilter
9744
+ filter = noFilter,
9745
+ ignoreFields = []
9203
9746
  } = {}) {
9204
9747
  const { top, left, bottom, right } = area || {
9205
9748
  top: 1,
@@ -9212,15 +9755,32 @@ class Table {
9212
9755
  for (let x = left; x <= right; x++) {
9213
9756
  const cell = this.getCellByPoint({ y, x }, refEvaluation, raise) ?? {};
9214
9757
  if (filter(cell)) {
9215
- matrix[y - top][x - left] = cell;
9758
+ const filteredCell = filterCellFields(cell, ignoreFields);
9759
+ matrix[y - top][x - left] = filteredCell;
9216
9760
  }
9217
9761
  }
9218
9762
  }
9219
9763
  return matrix;
9220
9764
  }
9221
- getObject({ refEvaluation = "SYSTEM", area, raise = false, filter = noFilter } = {}) {
9765
+ getCellObject({
9766
+ refEvaluation = "SYSTEM",
9767
+ raise = false,
9768
+ filter = noFilter,
9769
+ addresses,
9770
+ ignoreFields = []
9771
+ } = {}) {
9222
9772
  const result = {};
9223
- const { top, left, bottom, right } = area || {
9773
+ if (addresses) {
9774
+ for (const addr of addresses) {
9775
+ const cell = this.getCellByAddress(addr, refEvaluation, raise) ?? {};
9776
+ if (filter(cell)) {
9777
+ const filteredCell = filterCellFields(cell, ignoreFields);
9778
+ result[addr] = filteredCell;
9779
+ }
9780
+ }
9781
+ return result;
9782
+ }
9783
+ const { top, left, bottom, right } = {
9224
9784
  top: 1,
9225
9785
  left: 1,
9226
9786
  bottom: this.area.bottom,
@@ -9230,37 +9790,54 @@ class Table {
9230
9790
  for (let x = left; x <= right; x++) {
9231
9791
  const cell = this.getCellByPoint({ y, x }, refEvaluation, raise) ?? {};
9232
9792
  if (filter(cell)) {
9233
- result[p2a({ y, x })] = cell;
9793
+ const filteredCell = filterCellFields(cell, ignoreFields);
9794
+ result[p2a({ y, x })] = filteredCell;
9234
9795
  }
9235
9796
  }
9236
9797
  }
9237
9798
  return result;
9238
9799
  }
9239
- getRows({ refEvaluation = "COMPLETE", raise = false, filter = noFilter } = {}) {
9800
+ getCellRows({
9801
+ refEvaluation = "COMPLETE",
9802
+ raise = false,
9803
+ filter = noFilter,
9804
+ rows,
9805
+ ignoreFields = []
9806
+ } = {}) {
9240
9807
  const result = [];
9241
9808
  const { top, left, bottom, right } = this.area;
9242
- for (let y = top; y <= bottom; y++) {
9809
+ const ys = rows ?? Array.from({ length: bottom - top + 1 }, (_, i) => top + i);
9810
+ for (const y of ys) {
9243
9811
  const row = {};
9244
9812
  result.push(row);
9245
9813
  for (let x = left; x <= right; x++) {
9246
9814
  const cell = this.getCellByPoint({ y: y - top, x: x - left }, refEvaluation, raise) ?? {};
9247
9815
  if (filter(cell)) {
9248
- row[x2c(x)] = cell;
9816
+ const filteredCell = filterCellFields(cell, ignoreFields);
9817
+ row[x2c(x)] = filteredCell;
9249
9818
  }
9250
9819
  }
9251
9820
  }
9252
9821
  return result;
9253
9822
  }
9254
- getCols({ refEvaluation = "COMPLETE", raise = false, filter = noFilter } = {}) {
9823
+ getCellCols({
9824
+ refEvaluation = "COMPLETE",
9825
+ raise = false,
9826
+ filter = noFilter,
9827
+ cols,
9828
+ ignoreFields = []
9829
+ } = {}) {
9255
9830
  const result = [];
9256
9831
  const { top, left, bottom, right } = this.area;
9257
- for (let x = left; x <= right; x++) {
9832
+ const xs = cols ? cols.map((c) => typeof c === "string" ? c2x(c) : c) : Array.from({ length: right - left + 1 }, (_, i) => left + i);
9833
+ for (const x of xs) {
9258
9834
  const col = {};
9259
9835
  result.push(col);
9260
9836
  for (let y = top; y <= bottom; y++) {
9261
9837
  const cell = this.getCellByPoint({ y: y - top, x: x - left }, refEvaluation, raise) ?? {};
9262
9838
  if (filter(cell)) {
9263
- col[y2r(y)] = cell;
9839
+ const filteredCell = filterCellFields(cell, ignoreFields);
9840
+ col[y2r(y)] = filteredCell;
9264
9841
  }
9265
9842
  }
9266
9843
  }
@@ -9288,15 +9865,13 @@ class Table {
9288
9865
  });
9289
9866
  }
9290
9867
  if (history.operation === "MOVE") {
9291
- Object.keys(history.lostRows).forEach((address) => {
9292
- const idMatrix = history.lostRows[address];
9293
- idMatrix.map(
9294
- (ids) => ids.forEach((id) => {
9295
- if (id != null) {
9296
- delete this.wire.data[id];
9297
- }
9298
- })
9299
- );
9868
+ history.moveRelations.forEach(([from, to]) => {
9869
+ if (from.startsWith("#")) {
9870
+ delete this.wire.data[from.slice(1)];
9871
+ }
9872
+ if (to.startsWith("#")) {
9873
+ delete this.wire.data[to.slice(1)];
9874
+ }
9300
9875
  });
9301
9876
  }
9302
9877
  }
@@ -9338,32 +9913,13 @@ class Table {
9338
9913
  }
9339
9914
  return matrix;
9340
9915
  }
9341
- setChangedAt(cell, changedAt) {
9342
- if ((cell == null ? void 0 : cell.system) == null) {
9916
+ setChangedTime(cell, changedTime) {
9917
+ if ((cell == null ? void 0 : cell._sys) == null) {
9343
9918
  return null;
9344
9919
  }
9345
- cell.system.changedAt = changedAt ?? /* @__PURE__ */ new Date();
9920
+ cell._sys.changedTime = changedTime ?? Date.now();
9346
9921
  return cell;
9347
9922
  }
9348
- getUpdatedArea(diff) {
9349
- let minY = Infinity;
9350
- let minX = Infinity;
9351
- let maxY = -Infinity;
9352
- let maxX = -Infinity;
9353
- Object.keys(diff).forEach((address) => {
9354
- const point = a2p(address);
9355
- minY = Math.min(minY, point.y);
9356
- minX = Math.min(minX, point.x);
9357
- maxY = Math.max(maxY, point.y);
9358
- maxX = Math.max(maxX, point.x);
9359
- });
9360
- return {
9361
- top: minY,
9362
- left: minX,
9363
- bottom: maxY,
9364
- right: maxX
9365
- };
9366
- }
9367
9923
  copyCellLayout(cell) {
9368
9924
  if (cell == null) {
9369
9925
  return void 0;
@@ -9404,83 +9960,10 @@ class Table {
9404
9960
  undoReflection,
9405
9961
  redoReflection
9406
9962
  }) {
9407
- const matrixNew = this.getNewIdMatrix(src);
9408
- const matrixFrom = srcTable.__raw__.getIdMatrixFromArea(src);
9409
- const matrixTo = this.getIdMatrixFromArea(dst);
9410
- const diffBefore = {};
9411
- const preserver = new ReferencePreserver(this);
9412
- const lostRows = putMatrix(this.idMatrix, matrixFrom, dst, ({ srcValue: srcId, dstValue: dstId }) => {
9413
- var _a;
9414
- if (srcId == null || dstId == null) {
9415
- return false;
9416
- }
9417
- preserver.map[dstId] = srcId;
9418
- preserver.addTheDependents(srcId, dstId);
9419
- const srcCell = this.wire.data[srcId];
9420
- const dstCell = this.wire.data[dstId];
9421
- if (operator === "USER" && (hasOperation(srcCell == null ? void 0 : srcCell.prevention, MoveFrom) || hasOperation(dstCell == null ? void 0 : dstCell.prevention, MoveTo))) {
9422
- return false;
9423
- }
9424
- const policy = this.policies[dstCell == null ? void 0 : dstCell.policy] ?? defaultPolicy;
9425
- const patch = policy.restrict({
9426
- table: this,
9427
- point: this.getPointById(dstId),
9428
- patch: srcCell,
9429
- original: dstCell,
9430
- operation: MoveTo
9431
- });
9432
- if (patch) {
9433
- diffBefore[srcId] = { ...srcCell };
9434
- this.wire.data[srcId] = {
9435
- ...srcCell,
9436
- ...patch,
9437
- system: {
9438
- id: srcId,
9439
- sheetId: this.sheetId,
9440
- changedAt: /* @__PURE__ */ new Date(),
9441
- dependents: ((_a = srcCell == null ? void 0 : srcCell.system) == null ? void 0 : _a.dependents) ?? /* @__PURE__ */ new Set()
9442
- }
9443
- };
9444
- }
9445
- if (srcCell != null) {
9446
- this.setChangedAt(srcCell, /* @__PURE__ */ new Date());
9447
- }
9448
- return true;
9449
- });
9450
9963
  const srcTableRaw = srcTable.__raw__;
9964
+ const moveRelations = this._createMoveRelations(srcTableRaw, src, this, dst);
9965
+ const { diffBefore, diffAfter } = this._moveCells(srcTableRaw, this, moveRelations, false, operator);
9451
9966
  const srcContext = this.wire.contextsBySheetId[srcTableRaw.sheetId];
9452
- putMatrix(srcTableRaw.idMatrix, matrixNew, src, ({ srcValue: newId, dstValue: srcId, dstPoint: srcPoint }) => {
9453
- var _a;
9454
- if (among(dst, srcPoint) && srcTable === this) {
9455
- return false;
9456
- }
9457
- preserver.map[srcId] = newId;
9458
- const srcCell = srcTableRaw.wire.data[srcId];
9459
- if (operator === "USER" && hasOperation(srcCell == null ? void 0 : srcCell.prevention, MoveFrom)) {
9460
- return false;
9461
- }
9462
- const policy = this.policies[srcCell == null ? void 0 : srcCell.policy] ?? defaultPolicy;
9463
- const patch = policy.restrict({
9464
- table: srcTableRaw,
9465
- point: srcTableRaw.getPointById(srcId),
9466
- patch: void 0,
9467
- original: srcCell,
9468
- operation: MoveFrom
9469
- });
9470
- srcTableRaw.wire.data[newId] = {
9471
- value: null,
9472
- ...patch,
9473
- system: {
9474
- id: newId,
9475
- sheetId: srcTableRaw.sheetId,
9476
- changedAt: /* @__PURE__ */ new Date(),
9477
- dependents: ((_a = srcCell == null ? void 0 : srcCell.system) == null ? void 0 : _a.dependents) ?? /* @__PURE__ */ new Set()
9478
- }
9479
- };
9480
- return true;
9481
- });
9482
- const resolvedDiff = preserver.resolveDependents();
9483
- Object.assign(diffBefore, resolvedDiff);
9484
9967
  if (srcTable !== this && srcContext !== null) {
9485
9968
  const { dispatch } = srcContext;
9486
9969
  requestAnimationFrame(() => {
@@ -9496,21 +9979,237 @@ class Table {
9496
9979
  undoReflection,
9497
9980
  redoReflection,
9498
9981
  diffBefore,
9499
- diffAfter: {},
9500
- src,
9501
- dst,
9502
- matrixFrom,
9503
- matrixTo,
9504
- matrixNew,
9505
- lostRows
9982
+ diffAfter,
9983
+ moveRelations
9506
9984
  });
9507
9985
  }
9508
- if (this.wire.onEdit) {
9509
- this.wire.onEdit({ table: srcTable.__raw__.trim(src) });
9510
- this.wire.onEdit({ table: this.__raw__.trim(dst) });
9511
- }
9512
9986
  return this.refresh(true);
9513
9987
  }
9988
+ /**
9989
+ * Build MoveRelations from src area to dst area, skipping filtered rows.
9990
+ *
9991
+ * Layout of the returned array (processed in this order by _moveCells):
9992
+ * 1. Entries where [0] is a newly-generated ID — these fill the vacated src cells (processed last in forward order)
9993
+ * 2. Entries where [0] is a src address and [1] is a dst address — the actual moves (processed first in forward order, descending)
9994
+ * Entries whose [1] is an existing ID mean the destination cell is displaced/overflowed and
9995
+ * is no longer addressable; on forward pass they are skipped; on reverse pass the ID is written back.
9996
+ */
9997
+ _createMoveRelations(srcTable, src, dstTable, dst) {
9998
+ const { top: srcTop, left: srcLeft, bottom: srcBottom, right: srcRight } = src;
9999
+ const { top: dstTop, left: dstLeft } = dst;
10000
+ const dstNumRows = dstTable.getNumRows();
10001
+ const dstNumCols = dstTable.getNumCols();
10002
+ const srcVisibleRows = [];
10003
+ for (let y = srcTop; y <= srcBottom; y++) {
10004
+ if (!srcTable.isRowFiltered(y)) {
10005
+ srcVisibleRows.push(y);
10006
+ }
10007
+ }
10008
+ const srcNumCols = srcRight - srcLeft + 1;
10009
+ const srcNumVisibleRows = srcVisibleRows.length;
10010
+ const dstVisibleRows = [];
10011
+ {
10012
+ let di = 0;
10013
+ let y = dstTop;
10014
+ while (di < srcNumVisibleRows) {
10015
+ if (!dstTable.isRowFiltered(y)) {
10016
+ dstVisibleRows.push(y);
10017
+ di++;
10018
+ }
10019
+ y++;
10020
+ }
10021
+ }
10022
+ const srcCellSet = /* @__PURE__ */ new Set();
10023
+ for (let di = 0; di < srcNumVisibleRows; di++) {
10024
+ const srcY = srcVisibleRows[di];
10025
+ for (let j = 0; j < srcNumCols; j++) {
10026
+ srcCellSet.add(p2a({ y: srcY, x: srcLeft + j }));
10027
+ }
10028
+ }
10029
+ const dstAddrSet = /* @__PURE__ */ new Set();
10030
+ for (let di = 0; di < srcNumVisibleRows; di++) {
10031
+ const dstY = dstVisibleRows[di];
10032
+ for (let j = 0; j < srcNumCols; j++) {
10033
+ const dstX = dstLeft + j;
10034
+ if (dstY <= dstNumRows && dstX <= dstNumCols) {
10035
+ dstAddrSet.add(p2a({ y: dstY, x: dstX }));
10036
+ }
10037
+ }
10038
+ }
10039
+ const moveEntries = [];
10040
+ const vacateEntries = [];
10041
+ for (let di = 0; di < srcNumVisibleRows; di++) {
10042
+ const srcY = srcVisibleRows[di];
10043
+ const dstY = dstVisibleRows[di];
10044
+ for (let j = 0; j < srcNumCols; j++) {
10045
+ const srcX = srcLeft + j;
10046
+ const dstX = dstLeft + j;
10047
+ const srcAddr = p2a({ y: srcY, x: srcX });
10048
+ if (dstY <= dstNumRows && dstX <= dstNumCols) {
10049
+ const dstAddr = p2a({ y: dstY, x: dstX });
10050
+ moveEntries.push([srcAddr, dstAddr, null]);
10051
+ } else {
10052
+ const srcId = srcTable.getId({ y: srcY, x: srcX });
10053
+ moveEntries.push([srcAddr, `#${srcId}`, "overflow"]);
10054
+ }
10055
+ }
10056
+ }
10057
+ for (let di = 0; di < srcNumVisibleRows; di++) {
10058
+ const dstY = dstVisibleRows[di];
10059
+ for (let j = 0; j < srcNumCols; j++) {
10060
+ const dstX = dstLeft + j;
10061
+ if (dstY > dstNumRows || dstX > dstNumCols) {
10062
+ continue;
10063
+ }
10064
+ const dstAddr = p2a({ y: dstY, x: dstX });
10065
+ if (!srcCellSet.has(dstAddr)) {
10066
+ const existingId = dstTable.getId({ y: dstY, x: dstX });
10067
+ if (existingId != null) {
10068
+ moveEntries.push([dstAddr, `#${existingId}`, "displace"]);
10069
+ }
10070
+ }
10071
+ }
10072
+ }
10073
+ for (let di = 0; di < srcNumVisibleRows; di++) {
10074
+ const srcY = srcVisibleRows[di];
10075
+ for (let j = 0; j < srcNumCols; j++) {
10076
+ const srcX = srcLeft + j;
10077
+ const srcAddr = p2a({ y: srcY, x: srcX });
10078
+ if (srcTable === dstTable && dstAddrSet.has(srcAddr)) {
10079
+ continue;
10080
+ }
10081
+ const newId = `#${srcTable.generateId()}`;
10082
+ vacateEntries.push([newId, srcAddr, "vacate"]);
10083
+ }
10084
+ }
10085
+ return [...vacateEntries, ...moveEntries];
10086
+ }
10087
+ /**
10088
+ * Apply (or reverse) a MoveRelations list.
10089
+ *
10090
+ * Forward (reverse=false): process descending — actual ID moves happen bottom-up so
10091
+ * earlier entries don't clobber later ones; vacate entries (at front of array) are
10092
+ * applied last.
10093
+ * Reverse (reverse=true): process ascending — restores IDs in the natural order.
10094
+ *
10095
+ * On forward pass: applies policy, collects diffBefore, runs ReferencePreserver.
10096
+ * On reverse pass: only moves IDs (caller is responsible for applyDiff(diffBefore)).
10097
+ */
10098
+ _moveCells(srcTable, dstTable, moveRelations, reverse, operator = "SYSTEM") {
10099
+ var _a, _b;
10100
+ const diffBefore = {};
10101
+ const preserver = new ReferencePreserver(dstTable);
10102
+ const indices = reverse ? Array.from({ length: moveRelations.length }, (_, i) => i) : Array.from({ length: moveRelations.length }, (_, i) => moveRelations.length - 1 - i);
10103
+ for (const idx of indices) {
10104
+ const kind = moveRelations[idx][2];
10105
+ if (!reverse && (kind === "overflow" || kind === "displace")) {
10106
+ continue;
10107
+ }
10108
+ if (reverse && kind === "vacate") {
10109
+ continue;
10110
+ }
10111
+ const stripId = (s) => s.startsWith("#") ? s.slice(1) : s;
10112
+ let fromId;
10113
+ let toPoint;
10114
+ let writeTable;
10115
+ if (!reverse) {
10116
+ if (kind === "vacate") {
10117
+ fromId = stripId(moveRelations[idx][0]);
10118
+ toPoint = a2p(moveRelations[idx][1]);
10119
+ writeTable = srcTable;
10120
+ } else {
10121
+ fromId = srcTable.getId(a2p(moveRelations[idx][0]));
10122
+ toPoint = a2p(moveRelations[idx][1]);
10123
+ writeTable = dstTable;
10124
+ }
10125
+ } else {
10126
+ if (kind === "overflow") {
10127
+ fromId = stripId(moveRelations[idx][1]);
10128
+ toPoint = a2p(moveRelations[idx][0]);
10129
+ writeTable = srcTable;
10130
+ } else if (kind === "displace") {
10131
+ fromId = stripId(moveRelations[idx][1]);
10132
+ toPoint = a2p(moveRelations[idx][0]);
10133
+ writeTable = dstTable;
10134
+ } else {
10135
+ fromId = dstTable.getId(a2p(moveRelations[idx][1]));
10136
+ toPoint = a2p(moveRelations[idx][0]);
10137
+ writeTable = srcTable;
10138
+ }
10139
+ }
10140
+ const toId = writeTable.getId(toPoint);
10141
+ if (fromId == null || toId == null) {
10142
+ continue;
10143
+ }
10144
+ if (!reverse) {
10145
+ const fromCell = srcTable.wire.data[fromId];
10146
+ const toCell = writeTable.wire.data[toId];
10147
+ if (operator === "USER" && (hasOperation(fromCell == null ? void 0 : fromCell.prevention, MoveFrom) || hasOperation(toCell == null ? void 0 : toCell.prevention, MoveTo))) {
10148
+ continue;
10149
+ }
10150
+ if (kind === "vacate") {
10151
+ const policy = srcTable.policies[toCell == null ? void 0 : toCell.policy] ?? defaultPolicy;
10152
+ const patch = policy.restrict({
10153
+ table: srcTable,
10154
+ point: srcTable.getPointById(toId),
10155
+ patch: void 0,
10156
+ original: toCell,
10157
+ operation: MoveFrom
10158
+ });
10159
+ srcTable.wire.data[fromId] = {
10160
+ value: null,
10161
+ ...patch,
10162
+ _sys: {
10163
+ id: fromId,
10164
+ sheetId: srcTable.sheetId,
10165
+ changedTime: Date.now(),
10166
+ dependents: ((_a = toCell == null ? void 0 : toCell._sys) == null ? void 0 : _a.dependents) ?? /* @__PURE__ */ new Set()
10167
+ }
10168
+ };
10169
+ preserver.map[toId] = fromId;
10170
+ } else {
10171
+ const policy = dstTable.policies[toCell == null ? void 0 : toCell.policy] ?? defaultPolicy;
10172
+ const patch = policy.restrict({
10173
+ table: dstTable,
10174
+ point: dstTable.getPointById(toId),
10175
+ patch: fromCell,
10176
+ original: toCell,
10177
+ operation: MoveTo
10178
+ });
10179
+ if (patch) {
10180
+ diffBefore[fromId] = { ...fromCell };
10181
+ srcTable.wire.data[fromId] = {
10182
+ ...fromCell,
10183
+ ...patch,
10184
+ _sys: {
10185
+ id: fromId,
10186
+ sheetId: srcTable.sheetId,
10187
+ changedTime: Date.now(),
10188
+ dependents: ((_b = fromCell == null ? void 0 : fromCell._sys) == null ? void 0 : _b.dependents) ?? /* @__PURE__ */ new Set()
10189
+ }
10190
+ };
10191
+ }
10192
+ if (fromCell != null) {
10193
+ this.setChangedTime(fromCell, Date.now());
10194
+ }
10195
+ preserver.map[toId] = fromId;
10196
+ preserver.addTheDependents(fromId, toId);
10197
+ }
10198
+ }
10199
+ writeTable.idMatrix[toPoint.y][toPoint.x] = fromId;
10200
+ }
10201
+ const changedAddresses = moveRelations.filter(([, , k]) => k === null).map(([, to]) => to);
10202
+ if (srcTable === dstTable) {
10203
+ const srcAddresses = moveRelations.filter(([, , k]) => k === null || k === "vacate").map(([from]) => from);
10204
+ dstTable.lastChangedAddresses = [.../* @__PURE__ */ new Set([...srcAddresses, ...changedAddresses])];
10205
+ } else {
10206
+ dstTable.lastChangedAddresses = changedAddresses;
10207
+ srcTable.lastChangedAddresses = moveRelations.filter(([, , k]) => k === null || k === "vacate").map(([from]) => from);
10208
+ }
10209
+ const resolvedDiff = preserver.resolveDependents("move");
10210
+ Object.assign(diffBefore, resolvedDiff);
10211
+ return { diffBefore, diffAfter: {} };
10212
+ }
9514
10213
  copy({
9515
10214
  srcTable = this,
9516
10215
  src,
@@ -9521,33 +10220,41 @@ class Table {
9521
10220
  redoReflection
9522
10221
  }) {
9523
10222
  const isXSheet = srcTable !== this;
9524
- const { height: maxHeight, width: maxWidth } = areaShape({ ...src, base: 1 });
9525
- const { top: topFrom, left: leftFrom } = src;
10223
+ const { top: topFrom, left: leftFrom, bottom: bottomFrom, right: rightFrom } = src;
9526
10224
  const { top: topTo, left: leftTo, bottom: bottomTo, right: rightTo } = dst;
9527
10225
  const diff = {};
9528
- const changedAt = /* @__PURE__ */ new Date();
9529
- for (let i = 0; i <= bottomTo - topTo; i++) {
9530
- const toY = topTo + i;
9531
- if (toY > this.getNumRows()) {
10226
+ const changedTime = Date.now();
10227
+ const srcVisibleRows = [];
10228
+ for (let y = topFrom; y <= bottomFrom; y++) {
10229
+ if (!srcTable.isRowFiltered(y)) {
10230
+ srcVisibleRows.push(y);
10231
+ }
10232
+ }
10233
+ const dstVisibleRows = [];
10234
+ for (let y = topTo; y <= bottomTo; y++) {
10235
+ if (y > this.getNumRows()) {
9532
10236
  continue;
9533
10237
  }
9534
- for (let j = 0; j <= rightTo - leftTo; j++) {
10238
+ if (!this.isRowFiltered(y)) {
10239
+ dstVisibleRows.push(y);
10240
+ }
10241
+ }
10242
+ const srcNumVisibleRows = srcVisibleRows.length;
10243
+ const srcNumCols = rightFrom - leftFrom + 1;
10244
+ const dstNumCols = rightTo - leftTo + 1;
10245
+ for (let di = 0; di < dstVisibleRows.length; di++) {
10246
+ const toY = dstVisibleRows[di];
10247
+ const fromY = srcVisibleRows[di % srcNumVisibleRows];
10248
+ for (let j = 0; j <= dstNumCols - 1; j++) {
9535
10249
  const toX = leftTo + j;
9536
10250
  if (toX > this.getNumCols()) {
9537
10251
  continue;
9538
10252
  }
9539
- const fromY = topFrom + i % maxHeight;
9540
- const fromX = leftFrom + j % maxWidth;
10253
+ const fromX = leftFrom + j % srcNumCols;
9541
10254
  const slideY = isXSheet ? 0 : toY - fromY;
9542
10255
  const slideX = isXSheet ? 0 : toX - fromX;
9543
10256
  const cell = {
9544
- ...srcTable.getCellByPoint(
9545
- {
9546
- y: topFrom + i % maxHeight,
9547
- x: leftFrom + j % maxWidth
9548
- },
9549
- "SYSTEM"
9550
- )
10257
+ ...srcTable.getCellByPoint({ y: fromY, x: fromX }, "SYSTEM")
9551
10258
  };
9552
10259
  const dstPoint = { y: toY, x: toX };
9553
10260
  const value = identifyFormula(cell == null ? void 0 : cell.value, {
@@ -9556,7 +10263,7 @@ class Table {
9556
10263
  slideY,
9557
10264
  slideX
9558
10265
  });
9559
- this.setChangedAt(cell, changedAt);
10266
+ this.setChangedTime(cell, changedTime);
9560
10267
  const address = p2a(dstPoint);
9561
10268
  if (onlyValue) {
9562
10269
  const dstCell = this.getCellByPoint(dstPoint, "SYSTEM");
@@ -9586,7 +10293,7 @@ class Table {
9586
10293
  _update({
9587
10294
  diff,
9588
10295
  partial = true,
9589
- updateChangedAt = true,
10296
+ updateChangedTime = true,
9590
10297
  ignoreFields = ["label", "labeler"],
9591
10298
  operator = "SYSTEM",
9592
10299
  operation: op = Update,
@@ -9594,7 +10301,7 @@ class Table {
9594
10301
  }) {
9595
10302
  const diffBefore = {};
9596
10303
  const diffAfter = {};
9597
- const changedAt = /* @__PURE__ */ new Date();
10304
+ const changedTime = Date.now();
9598
10305
  let resized = false;
9599
10306
  Object.keys(diff).forEach((address) => {
9600
10307
  var _a, _b, _c, _d;
@@ -9631,8 +10338,8 @@ class Table {
9631
10338
  if (operator === "USER" && hasOperation(original == null ? void 0 : original.prevention, SetParser)) {
9632
10339
  patch == null ? true : delete patch.parser;
9633
10340
  }
9634
- if (updateChangedAt) {
9635
- this.setChangedAt(patch, changedAt);
10341
+ if (updateChangedTime) {
10342
+ this.setChangedTime(patch, changedTime);
9636
10343
  }
9637
10344
  if (patch.width != null || patch.height != null) {
9638
10345
  resized = true;
@@ -9646,17 +10353,14 @@ class Table {
9646
10353
  original,
9647
10354
  operation: op
9648
10355
  });
9649
- patch = { ...p, system: { ...original.system, changedAt } };
10356
+ patch = { ...p, system: { ...original._sys, changedTime } };
9650
10357
  if (partial) {
9651
10358
  diffAfter[id] = this.wire.data[id] = { ...original, ...patch };
9652
10359
  } else {
9653
10360
  diffAfter[id] = this.wire.data[id] = patch;
9654
10361
  }
9655
10362
  });
9656
- if (this.wire.onEdit && Object.keys(diff).length > 0) {
9657
- const updatedArea = this.getUpdatedArea(diff);
9658
- this.wire.onEdit({ table: this.__raw__.trim(updatedArea) });
9659
- }
10363
+ this.lastChangedAddresses = Object.keys(diff);
9660
10364
  return {
9661
10365
  diffBefore,
9662
10366
  diffAfter,
@@ -9666,10 +10370,11 @@ class Table {
9666
10370
  update({
9667
10371
  diff,
9668
10372
  partial = true,
9669
- updateChangedAt = true,
10373
+ updateChangedTime = true,
9670
10374
  historicize = true,
9671
10375
  operator = "SYSTEM",
9672
10376
  operation: op = Update,
10377
+ ignoreFields,
9673
10378
  undoReflection,
9674
10379
  redoReflection
9675
10380
  }) {
@@ -9678,7 +10383,8 @@ class Table {
9678
10383
  partial,
9679
10384
  operator,
9680
10385
  operation: op,
9681
- updateChangedAt
10386
+ updateChangedTime,
10387
+ ...ignoreFields != null ? { ignoreFields } : {}
9682
10388
  });
9683
10389
  if (historicize) {
9684
10390
  this.pushHistory({
@@ -9698,7 +10404,7 @@ class Table {
9698
10404
  writeRawCellMatrix({
9699
10405
  point,
9700
10406
  matrix,
9701
- updateChangedAt = true,
10407
+ updateChangedTime = true,
9702
10408
  historicize = true,
9703
10409
  onlyValue = false,
9704
10410
  operator = "SYSTEM",
@@ -9707,32 +10413,40 @@ class Table {
9707
10413
  }) {
9708
10414
  const { y: baseY, x: baseX } = point;
9709
10415
  const diff = {};
9710
- matrix.forEach((cells, i) => {
9711
- const y = baseY + i;
9712
- if (y > this.bottom) {
9713
- return;
10416
+ let srcRowIndex = 0;
10417
+ let dstY = baseY;
10418
+ while (srcRowIndex < matrix.length) {
10419
+ if (dstY > this.bottom) {
10420
+ break;
9714
10421
  }
10422
+ if (this.isRowFiltered(dstY)) {
10423
+ dstY++;
10424
+ continue;
10425
+ }
10426
+ const cells = matrix[srcRowIndex];
9715
10427
  cells.forEach((newCell, j) => {
9716
10428
  const x = baseX + j;
9717
10429
  if (x > this.right) {
9718
10430
  return;
9719
10431
  }
9720
- const point2 = { y, x };
9721
- const parsed = this.parse(point2, newCell.value ?? "");
10432
+ const dstPoint = { y: dstY, x };
10433
+ const parsed = this.parse(dstPoint, newCell.value ?? "");
9722
10434
  parsed.style = { ...newCell.style, ...parsed.style };
9723
10435
  if (onlyValue) {
9724
- const currentCell = this.getCellByPoint(point2, "SYSTEM");
10436
+ const currentCell = this.getCellByPoint(dstPoint, "SYSTEM");
9725
10437
  parsed.style = currentCell == null ? void 0 : currentCell.style;
9726
10438
  parsed.justifyContent = currentCell == null ? void 0 : currentCell.justifyContent;
9727
10439
  parsed.alignItems = currentCell == null ? void 0 : currentCell.alignItems;
9728
10440
  }
9729
- diff[p2a(point2)] = parsed;
10441
+ diff[p2a(dstPoint)] = parsed;
9730
10442
  });
9731
- });
10443
+ srcRowIndex++;
10444
+ dstY++;
10445
+ }
9732
10446
  return this.update({
9733
10447
  diff,
9734
10448
  partial: true,
9735
- updateChangedAt,
10449
+ updateChangedTime,
9736
10450
  historicize,
9737
10451
  operator,
9738
10452
  operation: Write,
@@ -9765,7 +10479,7 @@ class Table {
9765
10479
  baseY,
9766
10480
  diff,
9767
10481
  partial,
9768
- updateChangedAt,
10482
+ updateChangedTime,
9769
10483
  operator = "SYSTEM",
9770
10484
  undoReflection,
9771
10485
  redoReflection
@@ -9776,7 +10490,7 @@ class Table {
9776
10490
  }
9777
10491
  const numCols = this.getNumCols(1);
9778
10492
  const rows = [];
9779
- const changedAt = /* @__PURE__ */ new Date();
10493
+ const changedTime = Date.now();
9780
10494
  for (let i = 0; i < numRows; i++) {
9781
10495
  const row = [];
9782
10496
  for (let j = 0; j < numCols; j++) {
@@ -9786,10 +10500,10 @@ class Table {
9786
10500
  const copied = this.copyCellLayout(cell);
9787
10501
  this.wire.data[id] = {
9788
10502
  ...copied,
9789
- system: {
10503
+ _sys: {
9790
10504
  id,
9791
10505
  sheetId: this.sheetId,
9792
- changedAt,
10506
+ changedTime,
9793
10507
  dependents: /* @__PURE__ */ new Set()
9794
10508
  }
9795
10509
  };
@@ -9810,7 +10524,7 @@ class Table {
9810
10524
  idMatrix: rows
9811
10525
  });
9812
10526
  if (diff) {
9813
- Object.assign(this.wire.lastHistory, this._update({ diff, partial, updateChangedAt, operator }), { partial });
10527
+ Object.assign(this.wire.lastHistory, this._update({ diff, partial, updateChangedTime, operator }), { partial });
9814
10528
  }
9815
10529
  if (this.wire.onInsertRows) {
9816
10530
  const cloned = this.clone();
@@ -9893,7 +10607,7 @@ class Table {
9893
10607
  baseX,
9894
10608
  diff,
9895
10609
  partial,
9896
- updateChangedAt,
10610
+ updateChangedTime,
9897
10611
  operator = "SYSTEM",
9898
10612
  undoReflection,
9899
10613
  redoReflection
@@ -9904,7 +10618,7 @@ class Table {
9904
10618
  }
9905
10619
  const numRows = this.getNumRows(1);
9906
10620
  const rows = [];
9907
- const changedAt = /* @__PURE__ */ new Date();
10621
+ const changedTime = Date.now();
9908
10622
  for (let i = 0; i <= numRows; i++) {
9909
10623
  const row = [];
9910
10624
  for (let j = 0; j < numCols; j++) {
@@ -9915,10 +10629,10 @@ class Table {
9915
10629
  this.idMatrix[i].splice(x, 0, id);
9916
10630
  this.wire.data[id] = {
9917
10631
  ...copied,
9918
- system: {
10632
+ _sys: {
9919
10633
  id,
9920
10634
  sheetId: this.sheetId,
9921
- changedAt,
10635
+ changedTime,
9922
10636
  dependents: /* @__PURE__ */ new Set()
9923
10637
  }
9924
10638
  };
@@ -9938,7 +10652,7 @@ class Table {
9938
10652
  idMatrix: rows
9939
10653
  });
9940
10654
  if (diff) {
9941
- Object.assign(this.wire.lastHistory, this._update({ diff, partial, updateChangedAt, operator }), { partial });
10655
+ Object.assign(this.wire.lastHistory, this._update({ diff, partial, updateChangedTime, operator }), { partial });
9942
10656
  }
9943
10657
  if (this.wire.onInsertCols) {
9944
10658
  const cloned = this.clone();
@@ -10081,14 +10795,14 @@ class Table {
10081
10795
  if (!partial) {
10082
10796
  Object.keys(diff).forEach((id) => {
10083
10797
  const cell = diff[id] ?? {};
10084
- this.setChangedAt(cell);
10798
+ this.setChangedTime(cell);
10085
10799
  this.wire.data[id] = { ...cell };
10086
10800
  });
10087
10801
  return;
10088
10802
  }
10089
10803
  Object.keys(diff).map((id) => {
10090
10804
  const cell = diff[id] ?? {};
10091
- this.setChangedAt(cell);
10805
+ this.setChangedTime(cell);
10092
10806
  this.wire.data[id] = { ...this.getById(id), ...cell };
10093
10807
  });
10094
10808
  }
@@ -10149,34 +10863,14 @@ class Table {
10149
10863
  break;
10150
10864
  }
10151
10865
  case "MOVE": {
10152
- const { top: yFrom, left: xFrom } = history.src;
10153
- const { top: yTo, left: xTo } = history.dst;
10154
- const { height: rows, width: cols } = matrixShape({
10155
- matrix: history.matrixFrom,
10156
- base: -1
10157
- });
10158
10866
  if (srcTable) {
10159
- putMatrix(srcTable.idMatrix, history.matrixFrom, {
10160
- top: yFrom,
10161
- left: xFrom,
10162
- bottom: yFrom + rows,
10163
- right: xFrom + cols
10164
- });
10867
+ this._moveCells(srcTable, dstTable, history.moveRelations, true);
10165
10868
  }
10166
- putMatrix(dstTable.idMatrix, history.matrixTo, {
10167
- top: yTo,
10168
- left: xTo,
10169
- bottom: yTo + rows,
10170
- right: xTo + cols
10171
- });
10172
10869
  dstTable.applyDiff(history.diffBefore, false);
10173
- if (history.diffAfter) {
10174
- dstTable.applyDiff(history.diffAfter, false);
10175
- }
10176
10870
  break;
10177
10871
  }
10178
10872
  case "SORT_ROWS": {
10179
- dstTable._restoreRows(history.rowsBefore);
10873
+ dstTable._sortRowMapping(history.sortedRowMapping, true);
10180
10874
  dstTable._reapplyFilters();
10181
10875
  break;
10182
10876
  }
@@ -10247,14 +10941,13 @@ class Table {
10247
10941
  break;
10248
10942
  }
10249
10943
  case "MOVE": {
10250
- const { src, dst } = history;
10251
10944
  if (srcTable) {
10252
- dstTable.move({ srcTable, src, dst, operator: "USER", historicize: false });
10945
+ this._moveCells(srcTable, dstTable, history.moveRelations, false);
10253
10946
  }
10254
10947
  break;
10255
10948
  }
10256
10949
  case "SORT_ROWS": {
10257
- dstTable._restoreRows(history.rowsAfter);
10950
+ dstTable._sortRowMapping(history.sortedRowMapping, false);
10258
10951
  dstTable._reapplyFilters();
10259
10952
  break;
10260
10953
  }
@@ -10418,6 +11111,7 @@ const Cell = memo(({ y, x }) => {
10418
11111
  console.error(e);
10419
11112
  }
10420
11113
  }
11114
+ const isPendingCell = table.getSolvedCache({ y, x }) instanceof Pending;
10421
11115
  const input = editorRef.current;
10422
11116
  const editingAnywhere = !!(table.wire.editingAddress || editingAddress);
10423
11117
  const handleDragStart = useCallback(
@@ -10581,7 +11275,7 @@ const Cell = memo(({ y, x }) => {
10581
11275
  "data-x": x,
10582
11276
  "data-y": y,
10583
11277
  "data-address": address,
10584
- className: `gs-cell ${among(selectingArea, { y, x }) ? "gs-selecting" : ""} ${pointed ? "gs-choosing" : ""} ${editing ? "gs-editing" : ""}`,
11278
+ className: `gs-cell ${among(selectingArea, { y, x }) ? "gs-selecting" : ""} ${pointed ? "gs-choosing" : ""} ${editing ? "gs-editing" : ""} ${isPendingCell ? "gs-pending" : ""}`,
10585
11279
  style: {
10586
11280
  ...cell == null ? void 0 : cell.style
10587
11281
  },
@@ -10864,7 +11558,6 @@ const HeaderCellTop = memo(({ x }) => {
10864
11558
  if (editingAnywhere) {
10865
11559
  writeCell((lastFocused == null ? void 0 : lastFocused.value) ?? "");
10866
11560
  }
10867
- dispatch(choose({ y: 1, x: startX }));
10868
11561
  dispatch(setEditingAddress(""));
10869
11562
  dispatch(setDragging(true));
10870
11563
  if (autofillDraggingTo) {
@@ -10962,14 +11655,30 @@ const HeaderCellTop = memo(({ x }) => {
10962
11655
  !hasOperation(col == null ? void 0 : col.prevention, ColumnMenu$1) && /* @__PURE__ */ jsx(
10963
11656
  "button",
10964
11657
  {
10965
- className: `gs-column-menu-btn ${hasFilter ? "gs-filtered" : ""} ${(columnMenuState == null ? void 0 : columnMenuState.x) === x ? "gs-active" : ""}`,
11658
+ className: `gs-menu-btn gs-column-menu-btn ${hasFilter ? "gs-filtered" : ""} ${(columnMenuState == null ? void 0 : columnMenuState.x) === x ? "gs-active" : ""}`,
10966
11659
  onMouseDown: (e) => {
10967
11660
  e.stopPropagation();
10968
11661
  e.preventDefault();
10969
- const rect = e.target.getBoundingClientRect();
11662
+ e.currentTarget.dataset.pressX = String(e.clientX);
11663
+ e.currentTarget.dataset.pressY = String(e.clientY);
11664
+ },
11665
+ onMouseUp: (e) => {
11666
+ e.stopPropagation();
11667
+ const btn = e.currentTarget;
11668
+ const pressX = Number(btn.dataset.pressX ?? e.clientX);
11669
+ const pressY = Number(btn.dataset.pressY ?? e.clientY);
11670
+ const moved = Math.abs(e.clientX - pressX) > 4 || Math.abs(e.clientY - pressY) > 4;
11671
+ if (moved) {
11672
+ return;
11673
+ }
11674
+ const rect = btn.getBoundingClientRect();
10970
11675
  if ((columnMenuState == null ? void 0 : columnMenuState.x) === x) {
10971
11676
  dispatch(setColumnMenu(null));
10972
11677
  } else {
11678
+ const alreadySelected = between({ start: selectingZone.startX, end: selectingZone.endX }, x) && selectingZone.startY === 1 && selectingZone.endY === table.getNumRows();
11679
+ if (!alreadySelected) {
11680
+ dispatch(selectCols({ range: { start: x, end: x }, numRows: table.getNumRows() }));
11681
+ }
10973
11682
  dispatch(setColumnMenu({ x, position: { y: rect.bottom, x: rect.left } }));
10974
11683
  }
10975
11684
  },
@@ -11007,7 +11716,8 @@ const HeaderCellLeft = memo(({ y }) => {
11007
11716
  tableReactive: tableRef,
11008
11717
  autofillDraggingTo,
11009
11718
  dragging,
11010
- contextMenuItems
11719
+ contextMenuItems,
11720
+ rowMenuState
11011
11721
  } = store;
11012
11722
  const table = tableRef.current;
11013
11723
  const row = table == null ? void 0 : table.getCellByPoint({ y, x: 0 }, "SYSTEM");
@@ -11066,7 +11776,6 @@ const HeaderCellLeft = memo(({ y }) => {
11066
11776
  if (editingAnywhere) {
11067
11777
  writeCell((lastFocused == null ? void 0 : lastFocused.value) ?? "");
11068
11778
  }
11069
- dispatch(choose({ y: startY, x: 1 }));
11070
11779
  dispatch(setEditingAddress(""));
11071
11780
  dispatch(setDragging(true));
11072
11781
  if (autofillDraggingTo) {
@@ -11162,6 +11871,41 @@ const HeaderCellLeft = memo(({ y }) => {
11162
11871
  }
11163
11872
  ),
11164
11873
  table.getLabel(row == null ? void 0 : row.label, row == null ? void 0 : row.labeler, y) ?? rowId,
11874
+ !hasOperation(row == null ? void 0 : row.prevention, RowMenu$1) && /* @__PURE__ */ jsx(
11875
+ "button",
11876
+ {
11877
+ className: `gs-menu-btn gs-row-menu-btn ${(rowMenuState == null ? void 0 : rowMenuState.y) === y ? "gs-active" : ""}`,
11878
+ onMouseDown: (e) => {
11879
+ e.stopPropagation();
11880
+ e.preventDefault();
11881
+ e.currentTarget.dataset.pressX = String(e.clientX);
11882
+ e.currentTarget.dataset.pressY = String(e.clientY);
11883
+ handleDragStart(e);
11884
+ },
11885
+ onMouseUp: (e) => {
11886
+ e.stopPropagation();
11887
+ const btn = e.currentTarget;
11888
+ const pressX = Number(btn.dataset.pressX ?? e.clientX);
11889
+ const pressY = Number(btn.dataset.pressY ?? e.clientY);
11890
+ const moved = Math.abs(e.clientX - pressX) > 4 || Math.abs(e.clientY - pressY) > 4;
11891
+ if (moved) {
11892
+ return;
11893
+ }
11894
+ const rect = btn.getBoundingClientRect();
11895
+ if ((rowMenuState == null ? void 0 : rowMenuState.y) === y) {
11896
+ dispatch(setRowMenu(null));
11897
+ } else {
11898
+ const alreadySelected = between({ start: selectingZone.startY, end: selectingZone.endY }, y) && selectingZone.startX === 1 && selectingZone.endX === table.getNumCols();
11899
+ if (!alreadySelected) {
11900
+ dispatch(selectRows({ range: { start: y, end: y }, numCols: table.getNumCols() }));
11901
+ }
11902
+ dispatch(setRowMenu({ y, position: { y: rect.bottom, x: rect.right } }));
11903
+ }
11904
+ },
11905
+ title: "Row menu",
11906
+ children: "⋮"
11907
+ }
11908
+ ),
11165
11909
  /* @__PURE__ */ jsx(
11166
11910
  "div",
11167
11911
  {
@@ -11186,7 +11930,7 @@ const COLOR_COPYING = "#0077ff";
11186
11930
  const COLOR_CUTTING = "#0077ff";
11187
11931
  const SEARCH_MATCHING_BACKGROUND = "rgba(0, 200, 100, 0.2)";
11188
11932
  const COLOR_SEARCH_MATCHING = "#00aa78";
11189
- const COLOR_AUTOFILL = "#444444";
11933
+ const COLOR_AUTOFILL = "#0077aa";
11190
11934
  const HEADER_COLORS = {
11191
11935
  light: {
11192
11936
  selecting: "rgba(0, 0, 0, 0.1)",
@@ -11351,7 +12095,11 @@ const CellStateOverlay = ({ refs = {} }) => {
11351
12095
  if (left + pos.width < headerW || left > w) {
11352
12096
  continue;
11353
12097
  }
11354
- fillRect(ctx, left, 0, pos.width, headerH, color);
12098
+ const drawLeft = Math.max(left, headerW);
12099
+ const drawWidth = Math.min(left + pos.width, w) - drawLeft;
12100
+ if (drawWidth > 0) {
12101
+ fillRect(ctx, drawLeft, 0, drawWidth, headerH, color);
12102
+ }
11355
12103
  }
11356
12104
  for (let y = 1; y <= numRows; y++) {
11357
12105
  if (table.isRowFiltered(y)) {
@@ -11372,7 +12120,11 @@ const CellStateOverlay = ({ refs = {} }) => {
11372
12120
  if (top + pos.height < headerH || top > h) {
11373
12121
  continue;
11374
12122
  }
11375
- fillRect(ctx, 0, top, headerW, pos.height, color);
12123
+ const drawTop = Math.max(top, headerH);
12124
+ const drawHeight = Math.min(top + pos.height, h) - drawTop;
12125
+ if (drawHeight > 0) {
12126
+ fillRect(ctx, 0, drawTop, headerW, drawHeight, color);
12127
+ }
11376
12128
  }
11377
12129
  }, [
11378
12130
  table,
@@ -11450,7 +12202,8 @@ const Tabular = () => {
11450
12202
  sheetHeight,
11451
12203
  inputting,
11452
12204
  leftHeaderSelecting,
11453
- topHeaderSelecting
12205
+ topHeaderSelecting,
12206
+ contextMenuItems
11454
12207
  } = store;
11455
12208
  const table = tableReactive.current;
11456
12209
  const [virtualized, setVirtualized] = useState(null);
@@ -11572,15 +12325,43 @@ const Tabular = () => {
11572
12325
  className: "gs-th gs-th-left gs-th-top",
11573
12326
  style: { position: "sticky", width: table.headerWidth, height: table.headerHeight },
11574
12327
  onClick: handleSelectAllClick,
11575
- children: /* @__PURE__ */ jsx("div", { className: "gs-th-inner", children: /* @__PURE__ */ jsx(
11576
- ScrollHandle,
11577
- {
11578
- className: leftHeaderSelecting || topHeaderSelecting ? "gs-hidden" : "",
11579
- style: { position: "absolute" },
11580
- horizontal: leftHeaderSelecting ? 0 : -1,
11581
- vertical: topHeaderSelecting ? 0 : -1
11582
- }
11583
- ) })
12328
+ children: /* @__PURE__ */ jsxs("div", { className: "gs-th-inner", children: [
12329
+ /* @__PURE__ */ jsx(
12330
+ ScrollHandle,
12331
+ {
12332
+ className: leftHeaderSelecting || topHeaderSelecting ? "gs-hidden" : "",
12333
+ style: { position: "absolute" },
12334
+ horizontal: leftHeaderSelecting ? 0 : -1,
12335
+ vertical: topHeaderSelecting ? 0 : -1
12336
+ }
12337
+ ),
12338
+ contextMenuItems.length > 0 && /* @__PURE__ */ jsx(
12339
+ "button",
12340
+ {
12341
+ className: "gs-menu-btn gs-corner-menu-btn",
12342
+ title: "Menu",
12343
+ onClick: (e) => e.stopPropagation(),
12344
+ onMouseDown: (e) => {
12345
+ e.preventDefault();
12346
+ e.currentTarget.dataset.pressX = String(e.clientX);
12347
+ e.currentTarget.dataset.pressY = String(e.clientY);
12348
+ },
12349
+ onMouseUp: (e) => {
12350
+ e.stopPropagation();
12351
+ const btn = e.currentTarget;
12352
+ const pressX = Number(btn.dataset.pressX ?? e.clientX);
12353
+ const pressY = Number(btn.dataset.pressY ?? e.clientY);
12354
+ const moved = Math.abs(e.clientX - pressX) > 4 || Math.abs(e.clientY - pressY) > 4;
12355
+ if (moved) {
12356
+ return;
12357
+ }
12358
+ const rect = btn.getBoundingClientRect();
12359
+ dispatch(setContextMenuPosition({ y: rect.bottom, x: rect.left }));
12360
+ },
12361
+ children: "⋮"
12362
+ }
12363
+ )
12364
+ ] })
11584
12365
  }
11585
12366
  ),
11586
12367
  /* @__PURE__ */ jsx(
@@ -11627,8 +12408,8 @@ const Tabular = () => {
11627
12408
  }
11628
12409
  ) });
11629
12410
  };
11630
- const LAST_MODIFIED = 1771145572;
11631
- const CSS = `.gs-root1{display:inline-block;position:relative;border-spacing:0;width:fit-content;max-width:100%;overflow:auto;font-family:"SF Pro Text","SF Pro Icons","Helvetica Neue",Helvetica,Arial,Meiryo,sans-serif;visibility:hidden;opacity:0}.gs-root1.gs-initialized{visibility:visible;opacity:1;transition:opacity .2s ease-in-out}.gs-root1 .gs-main{flex:1;max-width:100%;overflow:hidden;position:relative;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box}.gs-root1 .gs-resizing{width:100%;height:100%;position:absolute;background-color:rgba(0,127,255,.08);top:0;left:0;z-index:2}.gs-root1 .gs-line-horizontal{width:100%}.gs-root1 .gs-line-vertical{height:100%}.gs-root1 .gs-line{position:relative;top:0;left:0;border:dotted 1px #07f;box-sizing:border-box}.gs-root1 .gs-line span{font-size:10px;padding:3px;background-color:#07f;color:#fff;margin:0;position:absolute;top:0;left:0}.gs-root1 .gs-scroll-handle{width:100%;height:100%;cursor:cell}.gs-hidden{visibility:hidden;position:absolute;top:0;left:0;width:0;height:0;overflow:hidden;pointer-events:none;z-index:-1}.gs-fixed{position:fixed;top:0;left:0;z-index:1}.gs-root1[data-mode=light]{background-color:#e2e2e2;color:#000}.gs-root1[data-mode=light] .gs-main{background-color:#e2e2e2;border-right:solid 1px #ddd;border-bottom:solid 1px #ddd}.gs-root1[data-mode=light] .gs-tabular{background-color:#e2e2e2}.gs-root1[data-mode=light] .gs-formula-bar{background-color:#efefef}.gs-root1[data-mode=light] .gs-formula-bar-editor-inner{color:#555}.gs-root1[data-mode=light] .gs-cell{background-color:#f7f7f7;border-top:solid 1px #ddd;border-left:solid 1px #ddd}.gs-root1[data-mode=light] .gs-adjuster{background-color:#ddd}.gs-root1[data-mode=light] .gs-tabular-inner{background-color:#ddd}.gs-root1[data-mode=light] .gs-th{background-color:#efefef;color:#666}.gs-root1[data-mode=light] .gs-th-top{border-left:solid 1px #ddd}.gs-root1[data-mode=light] .gs-th-top .gs-th-inner{border-top:solid 1px #ddd}.gs-root1[data-mode=light] .gs-th-left{border-top:solid 1px #ddd}.gs-root1[data-mode=light] .gs-th-left .gs-th-inner{border-left:solid 1px #ddd}.gs-root1[data-mode=light] .gs-search-bar{color:rgba(0,0,0,.3)}.gs-editor[data-mode=light].gs-editing textarea{caret-color:#000000}.gs-editor[data-mode=light].gs-editing .gs-editor-hl{background-color:#f7f7f7;color:#000}.gs-editor[data-mode=light] .gs-editor-options{color:#000;background-color:#f7f7f7;border:solid 1px #ddd}.gs-root1[data-mode=dark]{background-color:#5a5a5a;color:#eee}.gs-root1[data-mode=dark] .gs-main{background-color:#3f3f3f;border-right:solid 1px #5a5a5a;border-bottom:solid 1px #5a5a5a}.gs-root1[data-mode=dark] .gs-tabular{background-color:#3f3f3f}.gs-root1[data-mode=dark] .gs-formula-bar{background-color:#4f4f4f}.gs-root1[data-mode=dark] .gs-formula-bar-editor-inner{color:#bbb}.gs-root1[data-mode=dark] .gs-cell{background-color:#212121;border-top:solid 1px #5a5a5a;border-left:solid 1px #5a5a5a}.gs-root1[data-mode=dark] .gs-adjuster{background-color:#5a5a5a}.gs-root1[data-mode=dark] .gs-tabular-inner{background-color:#5a5a5a}.gs-root1[data-mode=dark] .gs-large-editor textarea{color:#eee;caret-color:#eeeeee}.gs-root1[data-mode=dark] .gs-th{background-color:#4f4f4f;color:#eee}.gs-root1[data-mode=dark] .gs-th-top{border-left:solid 1px #5a5a5a}.gs-root1[data-mode=dark] .gs-th-top .gs-th-inner{border-top:solid 1px #5a5a5a}.gs-root1[data-mode=dark] .gs-th-left{border-top:solid 1px #5a5a5a}.gs-root1[data-mode=dark] .gs-th-left .gs-th-inner{border-left:solid 1px #5a5a5a}.gs-root1[data-mode=dark] .gs-search-bar textarea{color:#eee;caret-color:#eeeeee}.gs-root1[data-mode=dark] .gs-search-bar{color:rgba(255,255,255,.3)}.gs-editor[data-mode=dark].gs-editing textarea{caret-color:#eeeeee}.gs-editor[data-mode=dark].gs-editing .gs-editor-hl{background-color:#212121;color:#eee}.gs-editor[data-mode=dark] .gs-editor-options{color:#eee;background-color:#5a5a5a;border:solid 1px #5a5a5a}.gs-cell{transition:border-color .2s ease;padding:0;margin:0;box-sizing:border-box;position:relative;font-size:13px;letter-spacing:1px;line-height:24px;cursor:cell;user-select:none;-webkit-user-select:none;-moz-user-select:none}.gs-cell.gs-copying textarea:focus{outline:solid 1px #0077ff}.gs-cell.gs-selecting{z-index:1}.gs-cell.gs-selecting .gs-cell-label{display:block}.gs-cell.gs-choosing{margin-top:-1px;margin-left:-1px;z-index:1}.gs-cell.gs-choosing.gs-editing{color:transparent}.gs-cell.gs-choosing .gs-cell-label{display:block}.gs-cell .gs-formula-error-triangle{position:absolute;top:0;right:0;border-top:3px solid rgba(200,0,0,.9);border-right:3px solid rgba(200,0,0,.9);border-bottom:3px solid transparent;border-left:3px solid transparent;z-index:1}.gs-cell .gs-cell-label{font-size:8px;font-weight:400;font-style:normal;font-family:math,monospace,serif;letter-spacing:1px;line-height:14px;position:absolute;top:0;right:0;background-color:rgba(0,128,255,.6);color:rgba(255,255,255,.6);padding:0 2px;display:none;opacity:.7}.gs-cell .gs-cell-inner-wrap{width:100%;height:100%;position:absolute;top:0;left:0}.gs-cell .gs-cell-inner{width:100%;height:100%;overflow:hidden;display:flex;box-sizing:border-box;border:none!important}.gs-cell .gs-cell-rendered{overflow:hidden;white-space:pre-wrap;cursor:cell;word-wrap:break-word;word-break:break-all;padding:0 2px;width:100%;height:100%}.gs-cell .gs-cell-rendered>*{position:relative}.gs-cell .gs-cell-rendered>.backface{z-index:0}.gs-cell .gs-autofill-drag{background-color:#07f;position:absolute;width:7px;height:7px;bottom:0;right:0;margin-right:-3.5px;margin-bottom:-3.5px;cursor:crosshair;z-index:1}.gs-th[data-x="1"] .gs-th-inner-wrap{border-left:none}.gs-th[data-y="1"] .gs-th-inner-wrap{border-top:none}.gs-cell[data-x="1"]{border-left:none}.gs-cell[data-y="1"]{border-top:none}.gs-contextmenu-modal{width:100%;height:100vh;z-index:12}.gs-contextmenu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px}.gs-contextmenu ul{color:#555;margin:0;padding:0;min-width:250px}.gs-contextmenu li{padding:5px 10px;list-style-type:none;display:flex}.gs-contextmenu li.gs-enabled{cursor:pointer}.gs-contextmenu li.gs-enabled:hover{background-color:#eee}.gs-contextmenu li.gs-disabled{opacity:.5;cursor:not-allowed}.gs-contextmenu li .gs-menu-name{font-size:13px;letter-spacing:1px}.gs-contextmenu li.gs-menu-divider{background-color:#aaa;padding:0;height:1px;margin:10px 0}.gs-contextmenu li .gs-menu-name{flex:1}.gs-contextmenu li .gs-menu-shortcut{font-size:10px;line-height:20px;color:#999}.gs-contextmenu li .gs-menu-shortcut:before{content:"( "}.gs-contextmenu li .gs-menu-shortcut:after{content:" )"}.gs-contextmenu li .gs-menu-shortcut .gs-menu-underline{text-decoration:underline}.gs-column-menu-modal{width:100%;height:100vh;z-index:12}.gs-column-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px}.gs-column-menu ul{color:#555;margin:0;padding:0;min-width:200px}.gs-column-menu li{padding:5px 10px;list-style-type:none}.gs-column-menu li.gs-enabled{cursor:pointer}.gs-column-menu li.gs-enabled:hover{background-color:#eee}.gs-column-menu li.gs-disabled{opacity:.5;cursor:not-allowed}.gs-column-menu li .gs-menu-name{font-size:13px;letter-spacing:1px}.gs-column-menu li.gs-menu-divider{background-color:#aaa;padding:0;height:1px;margin:5px 0}.gs-column-menu .gs-column-menu-label{padding:5px 10px}.gs-column-menu .gs-label-input-row{display:flex;gap:4px;align-items:center}.gs-column-menu .gs-label-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;background-color:transparent;box-shadow:none}.gs-column-menu .gs-label-input:focus{border-bottom-color:#07f;outline:0;box-shadow:none}.gs-column-menu .gs-label-apply-btn{font-size:12px;padding:3px 13px;border:1px solid transparent;border-radius:3px;background-color:transparent;color:#1a8a1a;cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-label-apply-btn:hover{border-color:#1a8a1a}.gs-column-menu .gs-column-menu-filter{padding:5px 10px}.gs-column-menu .gs-filter-header{display:flex;align-items:center;gap:8px}.gs-column-menu .gs-filter-header .gs-filter-add-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#555;letter-spacing:1px}.gs-column-menu .gs-filter-header .gs-filter-add-btn:hover{border-color:#555}.gs-column-menu .gs-filter-mode-toggle{display:flex;gap:6px;margin-left:auto}.gs-column-menu .gs-filter-mode-toggle label{display:flex;align-items:center;gap:3px;font-size:11px;font-weight:700;letter-spacing:.5px;color:#888;cursor:pointer;user-select:none}.gs-column-menu .gs-filter-mode-toggle label input[type=radio]{margin:0;cursor:pointer}.gs-column-menu .gs-filter-mode-toggle label.gs-active{color:#07f}.gs-column-menu .gs-filter-mode-toggle.gs-disabled{opacity:.4;pointer-events:none}.gs-column-menu .gs-filter-conditions{display:flex;flex-direction:column;gap:5px;margin-top:6px;max-height:200px;overflow-y:auto}.gs-column-menu .gs-filter-condition-row{display:flex;gap:4px;align-items:normal}.gs-column-menu .gs-filter-method-select{font-size:12px;padding:4px 4px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;background-color:#fff;box-shadow:none;min-width:40px;max-width:80px;cursor:pointer}.gs-column-menu .gs-filter-method-select:focus{border-bottom-color:#07f;outline:0;box-shadow:none}.gs-column-menu .gs-filter-value-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;width:80px;background-color:transparent;box-shadow:none}.gs-column-menu .gs-filter-value-input:focus{border-bottom-color:#07f;outline:0;box-shadow:none}.gs-column-menu .gs-filter-remove-btn{font-size:12px;padding:0;border:none;border-radius:3px;background-color:transparent;cursor:pointer;color:#999;line-height:1;flex-shrink:0}.gs-column-menu .gs-filter-remove-btn:hover{color:#c33}.gs-column-menu .gs-filter-actions{display:flex;gap:4px;margin-top:10px;align-items:center}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#c33;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn:hover{border-color:#c33}.gs-column-menu .gs-filter-actions .gs-filter-actions-right{display:flex;gap:4px;margin-left:auto}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#e08000;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn:hover{border-color:#e08000}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn{font-size:12px;padding:3px 13px;border:1px solid transparent;border-radius:3px;background-color:transparent;color:#07f;cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn:hover{border-color:#07f}.gs-column-menu-btn{position:absolute;right:4px;top:50%;transform:translateY(-50%);background-color:rgba(128,128,128,.3);border:1px solid #ccc;border-radius:50%;cursor:pointer;font-size:12px;font-weight:700;line-height:1;color:#888;width:18px;height:18px;padding:0;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s ease;z-index:2}.gs-column-menu-btn.gs-filtered{opacity:1;background-color:#e0edff;border-color:#07f;color:#07f}.gs-column-menu-btn.gs-active{opacity:1;background-color:#d0e0ff;border-color:#07f;color:#07f}.gs-th-top:hover .gs-column-menu-btn{opacity:1}.gs-editor-hl{padding:0 2px!important;position:absolute;font-family:monospace,Arial;font-size:12px;line-height:24px;letter-spacing:1px}.gs-formula-bar-editor-inner{position:relative;display:table-cell}.gs-editor{opacity:0;z-index:-1}.gs-editor .gs-editor-inner{position:relative}.gs-editor .gs-editor-hl{box-sizing:content-box;border:solid 2px #07f;margin:-2px -1px}.gs-editor textarea{width:100%;padding:0 2px!important;position:absolute;font-size:12px;font-family:monospace,Arial;line-height:24px;letter-spacing:1px;top:0;left:0;border:none;outline:0;background-color:transparent;color:transparent;resize:none;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;overflow:hidden;cursor:default;white-space:pre;height:auto}.gs-editor.gs-editing{z-index:11;opacity:1}.gs-editor.gs-editing .gs-cell-label{pointer-events:none;font-family:math,monospace,serif;position:absolute;top:0;right:0;margin-top:-15px;margin-right:-2px;padding:0 2px;font-size:10px;background-color:rgba(0,119,255,.75);color:#fff;z-index:1}.gs-formula-bar{width:100%;position:relative;display:table;align-items:center;justify-content:center;border-top:solid 1px rgba(128,128,128,.3);border-left:solid 1px rgba(128,128,128,.3);border-right:solid 1px rgba(128,128,128,.3);box-sizing:border-box}.gs-formula-bar .gs-selecting-address{display:table-cell;vertical-align:middle;width:60px;color:rgba(200,200,200);font-size:13px;text-align:center}.gs-formula-bar .gs-fx{display:table-cell;vertical-align:middle;width:30px;color:rgba(200,200,200);font-style:italic;font-family:cursive;text-align:center;border-left:solid 1px rgba(128,128,128,.5);font-size:15px}.gs-formula-bar .gs-editor-hl{z-index:0;overflow-y:auto;box-sizing:border-box;white-space:pre-wrap;word-break:break-all}.gs-formula-bar textarea{position:relative;z-index:1;width:100%;vertical-align:bottom;color:transparent;border:none;background-color:transparent;padding:0 2px;box-sizing:border-box;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;resize:vertical;caret-color:rgba(128,128,128);white-space:pre-wrap;word-break:break-all}.gs-token-type-INVALID_REF{color:red}.gs-token-type-VALUE.gs-token-entity-type-boolean,.gs-token-type-VALUE.gs-token-entity-type-number{color:#39f}.gs-token-type-VALUE.gs-token-entity-type-string{color:#090}.gs-editor-options{padding:0;box-shadow:0 2px 8px rgba(0,0,0,.25);border:1px solid rgba(128,128,128,.2);border-radius:4px}.gs-editor-option{cursor:pointer;list-style:none;padding:5px;font-size:12px}.gs-editor-option:hover{background-color:rgba(128,128,128,.1)}.gs-editor-option-selected{background-color:rgba(128,128,128,.2)}.gs-adjuster{padding:0}.gs-table{margin:0}.gs-tabular{overflow:auto;display:block;box-sizing:border-box;overscroll-behavior:none;position:relative}.gs-tabular-inner>table{table-layout:fixed;border-collapse:collapse;border-spacing:0}.gs-th{z-index:2;padding:0;position:sticky;font-size:13px;font-weight:400;box-sizing:border-box;vertical-align:top}.gs-th .gs-resizer{position:absolute;border-color:transparent;box-sizing:border-box;z-index:2}.gs-th .gs-resizer:hover{background-color:#07f}.gs-th .gs-resizer.gs-protected{display:none}.gs-th-inner{height:100%;box-sizing:border-box;vertical-align:middle;overflow:hidden;display:flex;align-items:center;justify-content:center}.gs-th-inner-wrap{height:100%;box-sizing:border-box;background-color:transparent}.gs-th-top{top:0;overflow:hidden}.gs-th-top .gs-resizer{top:0;right:0;width:3px;cursor:e-resize}.gs-th-top .gs-resizer.gs-dragging{border-right-style:dotted;height:1000000px!important;cursor:e-resize}.gs-th-left{left:0;overflow:hidden;min-width:30px;border-top:solid 1px #ddd}.gs-th-left .gs-resizer{left:0;bottom:0;height:3px;cursor:n-resize}.gs-th-left .gs-resizer.gs-dragging{border-bottom-style:dotted;width:1000000px!important;cursor:n-resize}.gs-th-top.gs-th-left{top:0;left:0;z-index:3;border:none!important}.gs-search-bar{width:100%;display:table;align-items:center;justify-content:center;border-top:solid 1px rgba(128,128,128,.3);border-left:solid 1px rgba(128,128,128,.3);border-right:solid 1px rgba(128,128,128,.3);box-sizing:border-box;background-color:rgba(200,50,0,.2)}.gs-search-bar.gs-search-found{background-color:rgba(0,200,100,.2)}.gs-search-bar .gs-search-bar-inner{vertical-align:middle;border-left:solid 1px rgba(128,128,128,.5)}.gs-search-bar .gs-search-bar-icon{border-left:solid 1px rgba(128,128,128,.3);display:table-cell;vertical-align:middle;width:30px}.gs-search-bar textarea{background-color:transparent;border:none;padding:0 2px;box-sizing:border-box;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;caret-color:rgba(128,128,128);white-space:pre-wrap;word-break:break-all;display:table-cell;vertical-align:middle;width:100%;resize:none}.gs-search-progress{display:table-cell;color:#999;font-size:13px;width:60px;vertical-align:middle;white-space:nowrap;text-align:center}.gs-search-close{display:table-cell;cursor:pointer;vertical-align:middle;width:24px}.gs-search-casesensitive{display:table-cell;cursor:pointer;vertical-align:middle;width:30px}.gs-search-casesensitive span{font-size:14px;padding:0 3px}.gs-search-casesensitive span.gs-search-casesensitive-on{color:#07f;background-color:rgba(200,200,255,.5);border-radius:3px}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}`;
12411
+ const LAST_MODIFIED = 1771698337;
12412
+ const CSS = `.gs-root1{display:inline-block;position:relative;border-spacing:0;width:fit-content;max-width:100%;overflow:auto;font-family:"SF Pro Text","SF Pro Icons","Helvetica Neue",Helvetica,Arial,Meiryo,sans-serif;visibility:hidden;opacity:0}.gs-root1.gs-initialized{visibility:visible;opacity:1;transition:opacity .2s ease-in-out}.gs-root1 .gs-main{flex:1;max-width:100%;overflow:hidden;position:relative;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box}.gs-root1 .gs-resizing{width:100%;height:100%;position:absolute;background-color:rgba(0,127,255,.08);top:0;left:0;z-index:2}.gs-root1 .gs-line-horizontal{width:100%}.gs-root1 .gs-line-vertical{height:100%}.gs-root1 .gs-line{position:relative;top:0;left:0;border:dotted 1px #07f;box-sizing:border-box}.gs-root1 .gs-line span{font-size:10px;padding:3px;background-color:#07f;color:#fff;margin:0;position:absolute;top:0;left:0}.gs-root1 .gs-scroll-handle{width:100%;height:100%;cursor:cell}.gs-hidden{visibility:hidden;position:absolute;top:0;left:0;width:0;height:0;overflow:hidden;pointer-events:none;z-index:-1}.gs-fixed{position:fixed;top:0;left:0;z-index:1}.gs-root1[data-mode=light]{background-color:#e2e2e2;color:#000}.gs-root1[data-mode=light] .gs-main{background-color:#e2e2e2;border-right:solid 1px #ddd;border-bottom:solid 1px #ddd}.gs-root1[data-mode=light] .gs-tabular{background-color:#e2e2e2}.gs-root1[data-mode=light] .gs-formula-bar{background-color:#efefef}.gs-root1[data-mode=light] .gs-formula-bar-editor-inner{color:#555}.gs-root1[data-mode=light] .gs-cell{background-color:#f7f7f7;border-top:solid 1px #ddd;border-left:solid 1px #ddd}.gs-root1[data-mode=light] .gs-adjuster{background-color:#ddd}.gs-root1[data-mode=light] .gs-tabular-inner{background-color:#ddd}.gs-root1[data-mode=light] .gs-th{background-color:#efefef;color:#666}.gs-root1[data-mode=light] .gs-th-top{border-left:solid 1px #ddd}.gs-root1[data-mode=light] .gs-th-top .gs-th-inner{border-top:solid 1px #ddd}.gs-root1[data-mode=light] .gs-th-left{border-top:solid 1px #ddd}.gs-root1[data-mode=light] .gs-th-left .gs-th-inner{border-left:solid 1px #ddd}.gs-root1[data-mode=light] .gs-search-bar{color:rgba(0,0,0,.3)}.gs-editor[data-mode=light].gs-editing textarea{caret-color:#000000}.gs-editor[data-mode=light].gs-editing .gs-editor-hl{background-color:#f7f7f7;color:#000}.gs-editor[data-mode=light] .gs-editor-options{color:#000;background-color:#f7f7f7;border:solid 1px #ddd}.gs-root1[data-mode=dark]{background-color:#5a5a5a;color:#eee}.gs-root1[data-mode=dark] .gs-main{background-color:#3f3f3f;border-right:solid 1px #5a5a5a;border-bottom:solid 1px #5a5a5a}.gs-root1[data-mode=dark] .gs-tabular{background-color:#3f3f3f}.gs-root1[data-mode=dark] .gs-formula-bar{background-color:#4f4f4f}.gs-root1[data-mode=dark] .gs-formula-bar-editor-inner{color:#bbb}.gs-root1[data-mode=dark] .gs-cell{background-color:#212121;border-top:solid 1px #5a5a5a;border-left:solid 1px #5a5a5a}.gs-root1[data-mode=dark] .gs-adjuster{background-color:#5a5a5a}.gs-root1[data-mode=dark] .gs-tabular-inner{background-color:#5a5a5a}.gs-root1[data-mode=dark] .gs-large-editor textarea{color:#eee;caret-color:#eeeeee}.gs-root1[data-mode=dark] .gs-th{background-color:#4f4f4f;color:#eee}.gs-root1[data-mode=dark] .gs-th-top{border-left:solid 1px #5a5a5a}.gs-root1[data-mode=dark] .gs-th-top .gs-th-inner{border-top:solid 1px #5a5a5a}.gs-root1[data-mode=dark] .gs-th-left{border-top:solid 1px #5a5a5a}.gs-root1[data-mode=dark] .gs-th-left .gs-th-inner{border-left:solid 1px #5a5a5a}.gs-root1[data-mode=dark] .gs-search-bar textarea{color:#eee;caret-color:#eeeeee}.gs-root1[data-mode=dark] .gs-search-bar{color:rgba(255,255,255,.3)}.gs-editor[data-mode=dark].gs-editing textarea{caret-color:#eeeeee}.gs-editor[data-mode=dark].gs-editing .gs-editor-hl{background-color:#212121;color:#eee}.gs-editor[data-mode=dark] .gs-editor-options{color:#eee;background-color:#5a5a5a;border:solid 1px #5a5a5a}.gs-cell{transition:border-color .2s ease;padding:0;margin:0;box-sizing:border-box;position:relative;font-size:13px;letter-spacing:1px;line-height:24px;cursor:cell;user-select:none;-webkit-user-select:none;-moz-user-select:none}.gs-cell.gs-copying textarea:focus{outline:solid 1px #0077ff}.gs-cell.gs-selecting{z-index:1}.gs-cell.gs-selecting .gs-cell-label{display:block}.gs-cell.gs-choosing{margin-top:-1px;margin-left:-1px;z-index:1}.gs-cell.gs-choosing.gs-editing{color:transparent}.gs-cell.gs-choosing .gs-cell-label{display:block}.gs-cell.gs-pending .gs-cell-rendered{position:relative;overflow:hidden}.gs-cell.gs-pending .gs-cell-rendered::after{content:'';position:absolute;bottom:0;left:0;height:4px;width:40%;border-radius:1px;background:rgba(100,140,255,.6);animation:gs-pending-slide 1.4s ease-in-out infinite}.gs-cell .gs-formula-error-triangle{position:absolute;top:0;right:0;border-top:3px solid rgba(200,0,0,.9);border-right:3px solid rgba(200,0,0,.9);border-bottom:3px solid transparent;border-left:3px solid transparent;z-index:1}.gs-cell .gs-cell-label{font-size:8px;font-weight:400;font-style:normal;font-family:math,monospace,serif;letter-spacing:1px;line-height:14px;position:absolute;top:0;right:0;background-color:rgba(0,128,255,.6);color:rgba(255,255,255,.6);padding:0 2px;display:none;opacity:.7}.gs-cell .gs-cell-inner-wrap{width:100%;height:100%;position:absolute;top:0;left:0}.gs-cell .gs-cell-inner{width:100%;height:100%;overflow:hidden;display:flex;box-sizing:border-box;border:none!important}.gs-cell .gs-cell-rendered{overflow:hidden;white-space:pre-wrap;cursor:cell;word-wrap:break-word;word-break:break-all;padding:0 2px;width:100%;height:100%}.gs-cell .gs-cell-rendered>*{position:relative}.gs-cell .gs-cell-rendered>.backface{z-index:0}.gs-cell .gs-autofill-drag{background-color:#07f;position:absolute;width:7px;height:7px;bottom:0;right:0;margin-right:-3.5px;margin-bottom:-3.5px;cursor:crosshair;z-index:1}.gs-th[data-x="1"] .gs-th-inner-wrap{border-left:none}.gs-th[data-y="1"] .gs-th-inner-wrap{border-top:none}.gs-cell[data-x="1"]{border-left:none}.gs-cell[data-y="1"]{border-top:none}.gs-menu-btn{position:absolute;background-color:rgba(128,128,128,.3);border:1px solid #ccc;border-radius:50%;cursor:pointer;font-size:12px;font-weight:700;line-height:1;color:#888;width:18px;height:18px;padding:0;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s ease;z-index:2}.gs-contextmenu-modal{width:100%;height:100vh;z-index:12}.gs-contextmenu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-contextmenu:hover{opacity:1}.gs-contextmenu ul{color:#555;margin:0;padding:0;min-width:250px}.gs-contextmenu li{padding:5px 10px;list-style-type:none;display:flex}.gs-contextmenu li.gs-enabled{cursor:pointer}.gs-contextmenu li.gs-enabled:hover{background-color:#eee}.gs-contextmenu li.gs-disabled{opacity:.5;cursor:not-allowed}.gs-contextmenu li .gs-menu-name{font-size:13px;letter-spacing:1px}.gs-contextmenu li.gs-menu-divider{background-color:#aaa;padding:0;height:1px;margin:10px 0}.gs-contextmenu li .gs-menu-name{flex:1}.gs-contextmenu li .gs-menu-shortcut{font-size:10px;line-height:20px;color:#999}.gs-contextmenu li .gs-menu-shortcut:before{content:"( "}.gs-contextmenu li .gs-menu-shortcut:after{content:" )"}.gs-contextmenu li .gs-menu-shortcut .gs-menu-underline{text-decoration:underline}.gs-column-menu-modal{width:100%;height:100vh;z-index:12}.gs-column-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-column-menu:hover{opacity:1}.gs-column-menu ul{color:#555;margin:0;padding:0;min-width:200px}.gs-column-menu li{padding:5px 10px;list-style-type:none}.gs-column-menu li.gs-enabled{cursor:pointer}.gs-column-menu li.gs-enabled:hover{background-color:#eee}.gs-column-menu li.gs-disabled{opacity:.5;cursor:not-allowed}.gs-column-menu li .gs-menu-name{font-size:13px;letter-spacing:1px}.gs-column-menu li.gs-menu-divider{background-color:#aaa;padding:0;height:1px;margin:5px 0}.gs-column-menu .gs-column-menu-label{padding:5px 10px}.gs-column-menu .gs-label-input-row{display:flex;gap:4px;align-items:center}.gs-column-menu .gs-label-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;width:100px;background-color:transparent;box-shadow:none}.gs-column-menu .gs-label-input:focus{border-bottom-color:#07f;outline:0;box-shadow:none}.gs-column-menu .gs-label-apply-btn{font-size:12px;padding:3px 6px;border:1px solid transparent;border-radius:3px;background-color:transparent;color:#1a8a1a;cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-label-apply-btn:hover{border-color:#1a8a1a}.gs-column-menu .gs-column-menu-filter{padding:5px 10px}.gs-column-menu .gs-filter-header{display:flex;align-items:center;gap:8px}.gs-column-menu .gs-filter-header .gs-filter-add-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#555;letter-spacing:1px}.gs-column-menu .gs-filter-header .gs-filter-add-btn:hover{border-color:#555}.gs-column-menu .gs-filter-mode-toggle{display:flex;gap:6px;margin-left:auto}.gs-column-menu .gs-filter-mode-toggle label{display:flex;align-items:center;gap:3px;font-size:11px;font-weight:700;letter-spacing:.5px;color:#888;cursor:pointer;user-select:none}.gs-column-menu .gs-filter-mode-toggle label input[type=radio]{margin:0;cursor:pointer}.gs-column-menu .gs-filter-mode-toggle label.gs-active{color:#07f}.gs-column-menu .gs-filter-mode-toggle.gs-disabled{opacity:.4;pointer-events:none}.gs-column-menu .gs-filter-conditions{display:flex;flex-direction:column;gap:5px;margin-top:6px;max-height:200px;overflow-y:auto}.gs-column-menu .gs-filter-condition-row{display:flex;gap:4px;align-items:normal}.gs-column-menu .gs-filter-method-select{font-size:12px;padding:4px 4px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;background-color:#fff;box-shadow:none;min-width:40px;max-width:80px;cursor:pointer}.gs-column-menu .gs-filter-method-select:focus{border-bottom-color:#07f;outline:0;box-shadow:none}.gs-column-menu .gs-filter-value-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;width:80px;background-color:transparent;box-shadow:none}.gs-column-menu .gs-filter-value-input:focus{border-bottom-color:#07f;outline:0;box-shadow:none}.gs-column-menu .gs-filter-remove-btn{font-size:12px;padding:0;border:none;border-radius:3px;background-color:transparent;cursor:pointer;color:#999;line-height:1;flex-shrink:0}.gs-column-menu .gs-filter-remove-btn:hover{color:#c33}.gs-column-menu .gs-filter-actions{display:flex;gap:4px;margin-top:10px;align-items:center}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#c33;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn:hover{border-color:#c33}.gs-column-menu .gs-filter-actions .gs-filter-actions-right{display:flex;gap:4px;margin-left:auto}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#e08000;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn:hover{border-color:#e08000}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn{font-size:12px;padding:3px 6px;border:1px solid transparent;border-radius:3px;background-color:transparent;color:#07f;cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn:hover{border-color:#07f}.gs-column-menu-waiting{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:20px 30px;gap:12px;min-width:180px}.gs-column-menu-waiting .gs-waiting-message{font-size:13px;font-weight:700;color:#555;letter-spacing:.5px}.gs-column-menu-waiting .gs-waiting-spinner{width:24px;height:24px;border:3px solid #e0e0e0;border-top-color:#07f;border-radius:50%;animation:spin .8s linear infinite}.gs-column-menu-waiting .gs-waiting-cancel-btn{font-size:12px;padding:4px 18px;border:1px solid #c33;border-radius:3px;background-color:transparent;color:#c33;cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu-waiting .gs-waiting-cancel-btn:hover{background-color:#c33;color:#fff}.gs-column-menu-btn{right:4px;top:50%;transform:translateY(-50%)}.gs-column-menu-btn.gs-filtered{opacity:1;background-color:#e0edff;border-color:#07f;color:#07f}.gs-column-menu-btn.gs-active{opacity:1;background-color:#d0e0ff;border-color:#07f;color:#07f}.gs-th-top:hover .gs-column-menu-btn{opacity:1}.gs-row-menu-modal{width:100%;height:100vh;z-index:12}.gs-row-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-row-menu:hover{opacity:1}.gs-row-menu ul{color:#555;margin:0;padding:0;min-width:200px}.gs-row-menu li{padding:5px 10px;list-style-type:none}.gs-row-menu li.gs-enabled{cursor:pointer}.gs-row-menu li.gs-enabled:hover{background-color:#eee}.gs-row-menu li.gs-disabled{opacity:.5;cursor:not-allowed}.gs-row-menu li .gs-menu-name{font-size:13px;letter-spacing:1px}.gs-row-menu li.gs-menu-divider{background-color:#aaa;padding:0;height:1px;margin:5px 0}.gs-row-menu-btn{top:50%;transform:translateY(-50%);right:2px}.gs-row-menu-btn.gs-active{opacity:1;background-color:#d0e0ff;border-color:#07f;color:#07f}.gs-th-left:hover .gs-row-menu-btn{opacity:1}.gs-corner-menu-btn{bottom:2px;right:2px}.gs-corner-menu-btn:hover{opacity:1;background-color:#d0e0ff;border-color:#07f;color:#07f}.gs-th-left.gs-th-top:hover .gs-corner-menu-btn{opacity:1}.gs-editor-hl{padding:0 2px!important;position:absolute;font-family:monospace,Arial;font-size:12px;line-height:24px;letter-spacing:1px}.gs-formula-bar-editor-inner{position:relative;display:table-cell}.gs-editor{opacity:0;z-index:-1}.gs-editor .gs-editor-inner{position:relative}.gs-editor .gs-editor-hl{box-sizing:content-box;border:solid 2px #07f;margin:-2px -1px}.gs-editor textarea{width:100%;padding:0 2px!important;position:absolute;font-size:12px;font-family:monospace,Arial;line-height:24px;letter-spacing:1px;top:0;left:0;border:none;outline:0;background-color:transparent;color:transparent;resize:none;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;overflow:hidden;cursor:default;white-space:pre;height:auto}.gs-editor.gs-editing{z-index:11;opacity:1}.gs-editor.gs-editing .gs-cell-label{pointer-events:none;font-family:math,monospace,serif;position:absolute;top:0;right:0;margin-top:-15px;margin-right:-2px;padding:0 2px;font-size:10px;background-color:rgba(0,119,255,.75);color:#fff;z-index:1}.gs-formula-bar{width:100%;position:relative;display:table;align-items:center;justify-content:center;border-top:solid 1px rgba(128,128,128,.3);border-left:solid 1px rgba(128,128,128,.3);border-right:solid 1px rgba(128,128,128,.3);box-sizing:border-box}.gs-formula-bar .gs-selecting-address{display:table-cell;vertical-align:middle;width:60px;color:rgba(200,200,200);font-size:13px;text-align:center}.gs-formula-bar .gs-fx{display:table-cell;vertical-align:middle;width:30px;color:rgba(200,200,200);font-style:italic;font-family:cursive;text-align:center;border-left:solid 1px rgba(128,128,128,.5);font-size:15px}.gs-formula-bar .gs-editor-hl{z-index:0;overflow-y:auto;box-sizing:border-box;white-space:pre-wrap;word-break:break-all}.gs-formula-bar textarea{position:relative;z-index:1;width:100%;vertical-align:bottom;color:transparent;border:none;background-color:transparent;padding:0 2px;box-sizing:border-box;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;resize:vertical;caret-color:rgba(128,128,128);white-space:pre-wrap;word-break:break-all}.gs-token-type-INVALID_REF{color:red}.gs-token-type-VALUE.gs-token-entity-type-boolean,.gs-token-type-VALUE.gs-token-entity-type-number{color:#39f}.gs-token-type-VALUE.gs-token-entity-type-string{color:#090}.gs-editor-options{padding:0;box-shadow:0 2px 8px rgba(0,0,0,.25);border:1px solid rgba(128,128,128,.2);border-radius:4px}.gs-editor-option{cursor:pointer;list-style:none;padding:5px;font-size:12px}.gs-editor-option:hover{background-color:rgba(128,128,128,.1)}.gs-editor-option-selected{background-color:rgba(128,128,128,.2)}.gs-adjuster{padding:0}.gs-table{margin:0}.gs-tabular{overflow:auto;display:block;box-sizing:border-box;overscroll-behavior:none;position:relative}.gs-tabular-inner>table{table-layout:fixed;border-collapse:collapse;border-spacing:0}.gs-th{z-index:2;padding:0;position:sticky;font-size:13px;font-weight:400;box-sizing:border-box;vertical-align:top}.gs-th .gs-resizer{position:absolute;border-color:transparent;box-sizing:border-box;z-index:2}.gs-th .gs-resizer:hover{background-color:#07f}.gs-th .gs-resizer.gs-protected{display:none}.gs-th-inner{height:100%;box-sizing:border-box;vertical-align:middle;overflow:hidden;display:flex;align-items:center;justify-content:center}.gs-th-inner-wrap{height:100%;box-sizing:border-box;background-color:transparent}.gs-th-top{top:0;overflow:hidden}.gs-th-top .gs-resizer{top:0;right:0;width:3px;cursor:e-resize}.gs-th-top .gs-resizer.gs-dragging{border-right-style:dotted;height:1000000px!important;cursor:e-resize}.gs-th-left{left:0;overflow:hidden;min-width:30px;border-top:solid 1px #ddd}.gs-th-left .gs-resizer{left:0;bottom:0;height:3px;cursor:n-resize}.gs-th-left .gs-resizer.gs-dragging{border-bottom-style:dotted;width:1000000px!important;cursor:n-resize}.gs-th-top.gs-th-left{top:0;left:0;z-index:3;border:none!important}.gs-search-bar{width:100%;display:table;align-items:center;justify-content:center;border-top:solid 1px rgba(128,128,128,.3);border-left:solid 1px rgba(128,128,128,.3);border-right:solid 1px rgba(128,128,128,.3);box-sizing:border-box;background-color:rgba(200,50,0,.2)}.gs-search-bar.gs-search-found{background-color:rgba(0,200,100,.2)}.gs-search-bar .gs-search-bar-inner{vertical-align:middle;border-left:solid 1px rgba(128,128,128,.5)}.gs-search-bar .gs-search-bar-icon{border-left:solid 1px rgba(128,128,128,.3);display:table-cell;vertical-align:middle;width:30px}.gs-search-bar textarea{background-color:transparent;border:none;padding:0 2px;box-sizing:border-box;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;caret-color:rgba(128,128,128);white-space:pre-wrap;word-break:break-all;display:table-cell;vertical-align:middle;width:100%;resize:none}.gs-search-progress{display:table-cell;color:#999;font-size:13px;width:60px;vertical-align:middle;white-space:nowrap;text-align:center}.gs-search-close{display:table-cell;cursor:pointer;vertical-align:middle;width:24px}.gs-search-casesensitive{display:table-cell;cursor:pointer;vertical-align:middle;width:30px}.gs-search-casesensitive span{font-size:14px;padding:0 3px}.gs-search-casesensitive span.gs-search-casesensitive-on{color:#07f;background-color:rgba(200,200,255,.5);border-radius:3px}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@keyframes gs-pending-slide{0%{left:-40%}100%{left:100%}}@keyframes gs-pending-pulse{0%{left:0;width:0}50%{left:0;width:100%}100%{left:100%;width:0}}`;
11632
12413
  const embedStyle = () => {
11633
12414
  if (typeof window === "undefined") {
11634
12415
  return;
@@ -12034,6 +12815,7 @@ function GridSheet({
12034
12815
  resizingPositionY: [-1, -1, -1],
12035
12816
  resizingPositionX: [-1, -1, -1],
12036
12817
  columnMenuState: null,
12818
+ rowMenuState: null,
12037
12819
  minNumRows: 1,
12038
12820
  maxNumRows: -1,
12039
12821
  minNumCols: 1,
@@ -12101,6 +12883,7 @@ function GridSheet({
12101
12883
  /* @__PURE__ */ jsx(StoreObserver, { ...{ ...options, sheetHeight, sheetWidth, sheetName, connector } }),
12102
12884
  /* @__PURE__ */ jsx(ContextMenu, {}),
12103
12885
  /* @__PURE__ */ jsx(ColumnMenu, {}),
12886
+ /* @__PURE__ */ jsx(RowMenu, {}),
12104
12887
  /* @__PURE__ */ jsx(Resizer, {}),
12105
12888
  /* @__PURE__ */ jsx(Emitter, {})
12106
12889
  ]
@@ -12192,6 +12975,7 @@ export {
12192
12975
  FormulaError,
12193
12976
  GridSheet,
12194
12977
  Parser2 as Parser,
12978
+ Pending,
12195
12979
  PluginBase,
12196
12980
  Policy,
12197
12981
  Renderer,
@@ -12201,6 +12985,9 @@ export {
12201
12985
  Wire,
12202
12986
  a2p,
12203
12987
  aa2oa,
12988
+ addressesToAreas,
12989
+ addressesToCols,
12990
+ addressesToRows,
12204
12991
  areaToRange,
12205
12992
  areaToZone,
12206
12993
  buildInitialCells,
@@ -12217,6 +13004,7 @@ export {
12217
13004
  operation as operations,
12218
13005
  p2a,
12219
13006
  r2y,
13007
+ solveTable,
12220
13008
  syncers,
12221
13009
  updateTable,
12222
13010
  useConnector,