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