@gridsheet/react-core 2.0.5 → 2.2.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
@@ -465,6 +465,8 @@ const shouldTracking = (operation2) => {
465
465
  return true;
466
466
  case "MOVE":
467
467
  return true;
468
+ case "SORT_ROWS":
469
+ return true;
468
470
  }
469
471
  return false;
470
472
  };
@@ -505,21 +507,17 @@ const isXSheetFocused = (store) => {
505
507
  };
506
508
  const getCellRectPositions = (table, { y, x }) => {
507
509
  var _a, _b;
508
- let { width, height } = table.getRectSize({
509
- top: 1,
510
- left: 1,
511
- bottom: y,
512
- right: x
513
- });
514
- width += table.headerWidth;
515
- height += table.headerHeight;
516
- const w = ((_a = table.getCellByPoint({ y: 0, x }, "SYSTEM")) == null ? void 0 : _a.width) || DEFAULT_WIDTH;
517
- const h = ((_b = table.getCellByPoint({ y, x: 0 }, "SYSTEM")) == null ? void 0 : _b.height) || DEFAULT_HEIGHT;
510
+ const colCell = table.getCellByPoint({ y: 0, x }, "SYSTEM");
511
+ const rowCell = table.getCellByPoint({ y, x: 0 }, "SYSTEM");
512
+ const left = ((_a = colCell == null ? void 0 : colCell.system) == null ? void 0 : _a.offsetLeft) ?? 0;
513
+ const top = ((_b = rowCell == null ? void 0 : rowCell.system) == null ? void 0 : _b.offsetTop) ?? 0;
514
+ const w = (colCell == null ? void 0 : colCell.width) || DEFAULT_WIDTH;
515
+ const h = (rowCell == null ? void 0 : rowCell.filtered) ? 0 : (rowCell == null ? void 0 : rowCell.height) || DEFAULT_HEIGHT;
518
516
  return {
519
- top: height,
520
- left: width,
521
- bottom: height + h,
522
- right: width + w,
517
+ top,
518
+ left,
519
+ bottom: top + h,
520
+ right: left + w,
523
521
  width: w,
524
522
  height: h
525
523
  };
@@ -550,6 +548,9 @@ const virtualize = (table, e) => {
550
548
  }
551
549
  }
552
550
  for (let y = 1; y <= table.getNumRows(); y++) {
551
+ if (table.isRowFiltered(y)) {
552
+ continue;
553
+ }
553
554
  const h = ((_b = table.getCellByPoint({ y, x: 0 }, "SYSTEM")) == null ? void 0 : _b.height) || DEFAULT_HEIGHT;
554
555
  height += h;
555
556
  if (boundaryTop === 0 && height > top) {
@@ -560,7 +561,7 @@ const virtualize = (table, e) => {
560
561
  break;
561
562
  }
562
563
  }
563
- const ys = range(boundaryTop, boundaryBottom);
564
+ const ys = boundaryTop === 0 ? [] : range(boundaryTop, boundaryBottom).filter((y) => !table.isRowFiltered(y));
564
565
  const xs = range(boundaryLeft, boundaryRight);
565
566
  const before = table.getRectSize({
566
567
  top: 1,
@@ -662,14 +663,20 @@ const Resize = 1024;
662
663
  const SetRenderer = 2048;
663
664
  const SetParser = 4096;
664
665
  const SetPolicy = 16384;
666
+ const Sort = 32768;
667
+ const Filter = 65536;
668
+ const SetLabel = 131072;
669
+ const SetLabeler = 262144;
665
670
  const NoOperation = 0;
666
671
  const Move = MoveFrom | MoveTo;
667
- const Update = Write | Style | Copy | Resize | SetRenderer | SetParser | SetPolicy;
672
+ const Update = Write | Style | Copy | Resize | SetRenderer | SetParser | SetPolicy | SetLabel | SetLabeler;
668
673
  const InsertRows = InsertRowsAbove | InsertRowsBelow;
669
674
  const InsertCols = InsertColsLeft | InsertColsRight;
670
675
  const Add = InsertRows | InsertCols;
671
676
  const Delete = RemoveRows | RemoveCols;
672
677
  const ReadOnly = Update | Delete | Add | Move;
678
+ const ColumnMenu$1 = Filter | Sort | SetLabel;
679
+ const ViewOnly = ReadOnly | ColumnMenu$1;
673
680
  const hasOperation = (operation2, flag) => {
674
681
  if (operation2 === void 0) {
675
682
  return false;
@@ -717,13 +724,27 @@ const debugOperations = (prevention) => {
717
724
  if (hasOperation(prevention, SetParser)) {
718
725
  operations2.push("SetParser");
719
726
  }
727
+ if (hasOperation(prevention, SetPolicy)) {
728
+ operations2.push("SetPolicy");
729
+ }
730
+ if (hasOperation(prevention, SetLabel)) {
731
+ operations2.push("SetLabel");
732
+ }
733
+ if (hasOperation(prevention, Sort)) {
734
+ operations2.push("Sort");
735
+ }
736
+ if (hasOperation(prevention, Filter)) {
737
+ operations2.push("Filter");
738
+ }
720
739
  return operations2;
721
740
  };
722
741
  const operation = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
723
742
  __proto__: null,
724
743
  Add,
744
+ ColumnMenu: ColumnMenu$1,
725
745
  Copy,
726
746
  Delete,
747
+ Filter,
727
748
  InsertCols,
728
749
  InsertColsLeft,
729
750
  InsertColsRight,
@@ -738,11 +759,15 @@ const operation = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePro
738
759
  RemoveCols,
739
760
  RemoveRows,
740
761
  Resize,
762
+ SetLabel,
763
+ SetLabeler,
741
764
  SetParser,
742
765
  SetPolicy,
743
766
  SetRenderer,
767
+ Sort,
744
768
  Style,
745
769
  Update,
770
+ ViewOnly,
746
771
  Write,
747
772
  debugOperations,
748
773
  hasOperation
@@ -1888,6 +1913,9 @@ class TimeDelta {
1888
1913
  result = result.replace("S", String(tokens[3]).padStart(1, "0").substring(0, 1));
1889
1914
  return result;
1890
1915
  }
1916
+ toMilliseconds() {
1917
+ return this.date1.getTime() - this.date2.getTime();
1918
+ }
1891
1919
  toJSON() {
1892
1920
  return this.stringify();
1893
1921
  }
@@ -3033,13 +3061,23 @@ class ArrowAction extends CoreAction {
3033
3061
  if (nextY < 1 || numRows < nextY || nextX < 1 || numCols < nextX) {
3034
3062
  return store;
3035
3063
  }
3064
+ let resolvedY = nextY;
3065
+ if (table.isRowFiltered(resolvedY)) {
3066
+ const dir = deltaY >= 0 ? 1 : -1;
3067
+ while (resolvedY >= 1 && resolvedY <= numRows && table.isRowFiltered(resolvedY)) {
3068
+ resolvedY += dir;
3069
+ }
3070
+ if (resolvedY < 1 || resolvedY > numRows) {
3071
+ return store;
3072
+ }
3073
+ }
3036
3074
  let { y: editorTop, x: editorLeft, height, width } = store.editorRect;
3037
3075
  if (deltaY > 0) {
3038
- for (let i = y; i < nextY; i++) {
3076
+ for (let i = y; i < resolvedY; i++) {
3039
3077
  editorTop += ((_a = table.getCellByPoint({ y: i, x: 0 }, "SYSTEM")) == null ? void 0 : _a.height) || DEFAULT_HEIGHT;
3040
3078
  }
3041
3079
  } else if (deltaY < 0) {
3042
- for (let i = y - 1; i >= nextY; i--) {
3080
+ for (let i = y - 1; i >= resolvedY; i--) {
3043
3081
  editorTop -= ((_b = table.getCellByPoint({ y: i, x: 0 }, "SYSTEM")) == null ? void 0 : _b.height) || DEFAULT_HEIGHT;
3044
3082
  }
3045
3083
  }
@@ -3052,14 +3090,14 @@ class ArrowAction extends CoreAction {
3052
3090
  editorLeft -= ((_d = table.getCellByPoint({ y: 0, x: i }, "SYSTEM")) == null ? void 0 : _d.width) || DEFAULT_WIDTH;
3053
3091
  }
3054
3092
  }
3055
- const cell = table.getCellByPoint({ y: nextY, x: nextX }, "SYSTEM");
3093
+ const cell = table.getCellByPoint({ y: resolvedY, x: nextX }, "SYSTEM");
3056
3094
  height = (cell == null ? void 0 : cell.height) || DEFAULT_HEIGHT;
3057
3095
  width = (cell == null ? void 0 : cell.width) || DEFAULT_WIDTH;
3058
- smartScroll(table, tabularRef.current, { y: nextY, x: nextX });
3096
+ smartScroll(table, tabularRef.current, { y: resolvedY, x: nextX });
3059
3097
  return {
3060
3098
  ...store,
3061
3099
  selectingZone: { startY: -1, startX: -1, endY: -1, endX: -1 },
3062
- choosing: { y: nextY, x: nextX },
3100
+ choosing: { y: resolvedY, x: nextX },
3063
3101
  editorRect: { y: editorTop, x: editorLeft, height, width }
3064
3102
  };
3065
3103
  }
@@ -3127,6 +3165,17 @@ class WalkAction extends CoreAction {
3127
3165
  if (nextY < 1 || numRows < nextY || nextX < 1 || numCols < nextX) {
3128
3166
  return store;
3129
3167
  }
3168
+ if (table.isRowFiltered(nextY)) {
3169
+ const dir = deltaY >= 0 ? 1 : -1;
3170
+ const lo = top !== -1 ? top : 1;
3171
+ const hi = bottom !== -1 ? bottom : numRows;
3172
+ while (nextY >= lo && nextY <= hi && table.isRowFiltered(nextY)) {
3173
+ nextY += dir;
3174
+ }
3175
+ if (nextY < lo || nextY > hi || table.isRowFiltered(nextY)) {
3176
+ return store;
3177
+ }
3178
+ }
3130
3179
  if (deltaY > 0) {
3131
3180
  for (let i = y; i < nextY; i++) {
3132
3181
  editorTop += ((_a = table.getCellByPoint({ y: i, x: 0 }, "SYSTEM")) == null ? void 0 : _a.height) || DEFAULT_HEIGHT;
@@ -3370,6 +3419,152 @@ class RemoveColsAction extends CoreAction {
3370
3419
  }
3371
3420
  }
3372
3421
  const removeCols = new RemoveColsAction().bind();
3422
+ class SortRowsAction extends CoreAction {
3423
+ reduce(store, payload) {
3424
+ const { x, direction } = payload;
3425
+ const { tableReactive: tableRef, selectingZone, choosing } = store;
3426
+ const table = tableRef.current;
3427
+ if (table == null) {
3428
+ return store;
3429
+ }
3430
+ table.sortRows({
3431
+ x,
3432
+ direction,
3433
+ undoReflection: {
3434
+ sheetId: table.sheetId,
3435
+ selectingZone,
3436
+ choosing
3437
+ },
3438
+ redoReflection: {
3439
+ sheetId: table.sheetId,
3440
+ selectingZone,
3441
+ choosing
3442
+ }
3443
+ });
3444
+ return {
3445
+ ...store,
3446
+ tableReactive: { current: table }
3447
+ };
3448
+ }
3449
+ }
3450
+ const sortRows = new SortRowsAction().bind();
3451
+ class FilterRowsAction extends CoreAction {
3452
+ reduce(store, payload) {
3453
+ const { x, filter } = payload;
3454
+ const { tableReactive: tableRef, selectingZone, choosing } = store;
3455
+ const table = tableRef.current;
3456
+ if (table == null) {
3457
+ return store;
3458
+ }
3459
+ table.filterRows({
3460
+ x,
3461
+ filter,
3462
+ undoReflection: {
3463
+ sheetId: table.sheetId,
3464
+ selectingZone,
3465
+ choosing
3466
+ },
3467
+ redoReflection: {
3468
+ sheetId: table.sheetId,
3469
+ selectingZone,
3470
+ choosing
3471
+ }
3472
+ });
3473
+ let newChoosing = choosing;
3474
+ if (table.isRowFiltered(choosing.y)) {
3475
+ for (let y = 1; y <= table.getNumRows(); y++) {
3476
+ if (!table.isRowFiltered(y)) {
3477
+ newChoosing = { y, x: choosing.x };
3478
+ break;
3479
+ }
3480
+ }
3481
+ }
3482
+ return {
3483
+ ...store,
3484
+ choosing: newChoosing,
3485
+ selectingZone: newChoosing !== choosing ? resetZone : selectingZone,
3486
+ tableReactive: { current: table }
3487
+ };
3488
+ }
3489
+ }
3490
+ const filterRows = new FilterRowsAction().bind();
3491
+ class ClearFilterRowsAction extends CoreAction {
3492
+ reduce(store, payload) {
3493
+ const { x } = payload;
3494
+ const { tableReactive: tableRef, selectingZone, choosing } = store;
3495
+ const table = tableRef.current;
3496
+ if (table == null) {
3497
+ return store;
3498
+ }
3499
+ table.clearFilterRows(
3500
+ x,
3501
+ {
3502
+ sheetId: table.sheetId,
3503
+ selectingZone,
3504
+ choosing
3505
+ },
3506
+ {
3507
+ sheetId: table.sheetId,
3508
+ selectingZone,
3509
+ choosing
3510
+ }
3511
+ );
3512
+ let newChoosing = choosing;
3513
+ if (table.isRowFiltered(choosing.y)) {
3514
+ for (let y = 1; y <= table.getNumRows(); y++) {
3515
+ if (!table.isRowFiltered(y)) {
3516
+ newChoosing = { y, x: choosing.x };
3517
+ break;
3518
+ }
3519
+ }
3520
+ }
3521
+ return {
3522
+ ...store,
3523
+ choosing: newChoosing,
3524
+ selectingZone: newChoosing !== choosing ? resetZone : selectingZone,
3525
+ tableReactive: { current: table }
3526
+ };
3527
+ }
3528
+ }
3529
+ const clearFilterRows = new ClearFilterRowsAction().bind();
3530
+ class SetColumnMenuAction extends CoreAction {
3531
+ reduce(store, payload) {
3532
+ return {
3533
+ ...store,
3534
+ columnMenuState: payload
3535
+ };
3536
+ }
3537
+ }
3538
+ const setColumnMenu = new SetColumnMenuAction().bind();
3539
+ class SetColLabelAction extends CoreAction {
3540
+ reduce(store, payload) {
3541
+ const { x, label } = payload;
3542
+ const { tableReactive: tableRef, selectingZone, choosing } = store;
3543
+ const table = tableRef.current;
3544
+ if (table == null) {
3545
+ return store;
3546
+ }
3547
+ table.setColLabel({
3548
+ x,
3549
+ label,
3550
+ undoReflection: {
3551
+ sheetId: table.sheetId,
3552
+ selectingZone,
3553
+ choosing
3554
+ },
3555
+ redoReflection: {
3556
+ sheetId: table.sheetId,
3557
+ selectingZone,
3558
+ choosing
3559
+ }
3560
+ });
3561
+ return {
3562
+ ...store,
3563
+ tableReactive: { current: table }
3564
+ };
3565
+ }
3566
+ }
3567
+ const setColLabel = new SetColLabelAction().bind();
3373
3568
  class setStoreAction extends CoreAction {
3374
3569
  reduce(store, payload) {
3375
3570
  return {
@@ -3402,7 +3597,11 @@ const userActions = {
3402
3597
  insertColsLeft,
3403
3598
  insertColsRight,
3404
3599
  removeRows,
3405
- removeCols
3600
+ removeCols,
3601
+ sortRows,
3602
+ filterRows,
3603
+ clearFilterRows,
3604
+ setColLabel
3406
3605
  };
3407
3606
  const clip = (store) => {
3408
3607
  const { selectingZone, choosing, editorRef, tableReactive: tableRef } = store;
@@ -4819,6 +5018,26 @@ const colsRemover = async ({ store, dispatch }) => {
4819
5018
  dispatch(removeCols({ numCols, x: left, operator: "USER" }));
4820
5019
  (_a = editorRef.current) == null ? void 0 : _a.focus();
4821
5020
  };
5021
+ const rowsSorterAsc = async ({ store, dispatch }, x) => {
5022
+ var _a;
5023
+ dispatch(sortRows({ x, direction: "asc" }));
5024
+ (_a = store.editorRef.current) == null ? void 0 : _a.focus();
5025
+ };
5026
+ const rowsSorterDesc = async ({ store, dispatch }, x) => {
5027
+ var _a;
5028
+ dispatch(sortRows({ x, direction: "desc" }));
5029
+ (_a = store.editorRef.current) == null ? void 0 : _a.focus();
5030
+ };
5031
+ const rowsFilterer = async ({ store, dispatch }, x, filter) => {
5032
+ var _a;
5033
+ dispatch(filterRows({ x, filter }));
5034
+ (_a = store.editorRef.current) == null ? void 0 : _a.focus();
5035
+ };
5036
+ const rowsFilterClearer = async ({ store, dispatch }, x) => {
5037
+ var _a;
5038
+ dispatch(clearFilterRows({ x }));
5039
+ (_a = store.editorRef.current) == null ? void 0 : _a.focus();
5040
+ };
4822
5041
  const syncers = {
4823
5042
  copy: copier,
4824
5043
  cut: cutter,
@@ -4830,7 +5049,11 @@ const syncers = {
4830
5049
  insertColsLeft: colsInserterLeft,
4831
5050
  insertColsRight: colsInserterRight,
4832
5051
  removeRows: rowsRemover,
4833
- removeCols: colsRemover
5052
+ removeCols: colsRemover,
5053
+ sortRowsAsc: rowsSorterAsc,
5054
+ sortRowsDesc: rowsSorterDesc,
5055
+ filterRows: rowsFilterer,
5056
+ clearFilter: rowsFilterClearer
4834
5057
  };
4835
5058
  const ContextMenu = () => {
4836
5059
  const { store, dispatch } = useContext(Context);
@@ -5124,6 +5347,310 @@ const defaultContextMenuItems = [
5124
5347
  UndoItem,
5125
5348
  RedoItem
5126
5349
  ];
5350
+ const METHOD_LABELS = {
5351
+ eq: "=",
5352
+ ne: "≠",
5353
+ gt: ">",
5354
+ gte: "≥",
5355
+ lt: "<",
5356
+ lte: "≤",
5357
+ blank: "Blank",
5358
+ nonblank: "Nonblank",
5359
+ includes: "Includes",
5360
+ excludes: "Excludes"
5361
+ };
5362
+ const NO_VALUE_METHODS = ["blank", "nonblank"];
5363
+ const DEFAULT_CONDITION = { method: "eq", value: [""] };
5364
+ const ColumnMenu = () => {
5365
+ const { store, dispatch } = useContext(Context);
5366
+ const { columnMenuState, tableReactive: tableRef, editorRef } = store;
5367
+ const table = tableRef.current;
5368
+ const [conditions, setConditions] = useState([{ ...DEFAULT_CONDITION }]);
5369
+ const [mode, setMode] = useState("or");
5370
+ const [label, setLabel] = useState("");
5371
+ const labelInputRef = useRef(null);
5372
+ const x = columnMenuState == null ? void 0 : columnMenuState.x;
5373
+ const position = columnMenuState == null ? void 0 : columnMenuState.position;
5374
+ useEffect(() => {
5375
+ if (x != null && table) {
5376
+ const colCell2 = table.getCellByPoint({ y: 0, x }, "SYSTEM");
5377
+ const existing = colCell2 == null ? void 0 : colCell2.filter;
5378
+ if (existing && existing.conditions.length > 0) {
5379
+ setConditions(existing.conditions.map((c) => ({ ...c, value: [...c.value] })));
5380
+ setMode(existing.mode || "or");
5381
+ } else {
5382
+ setConditions([{ ...DEFAULT_CONDITION, value: [""] }]);
5383
+ setMode("or");
5384
+ }
5385
+ setLabel((colCell2 == null ? void 0 : colCell2.label) ?? "");
5386
+ }
5387
+ }, [x]);
5388
+ const handleClose = useCallback(() => {
5389
+ var _a;
5390
+ dispatch(setColumnMenu(null));
5391
+ (_a = editorRef.current) == null ? void 0 : _a.focus();
5392
+ }, [dispatch, editorRef]);
5393
+ const handleApplyLabel = useCallback(() => {
5394
+ var _a;
5395
+ if (x == null) {
5396
+ return;
5397
+ }
5398
+ dispatch(setColLabel({ x, label }));
5399
+ dispatch(setColumnMenu(null));
5400
+ (_a = editorRef.current) == null ? void 0 : _a.focus();
5401
+ }, [dispatch, x, label, editorRef]);
5402
+ const handleSortAsc = useCallback(() => {
5403
+ var _a;
5404
+ if (x == null) {
5405
+ return;
5406
+ }
5407
+ dispatch(sortRows({ x, direction: "asc" }));
5408
+ dispatch(setColumnMenu(null));
5409
+ (_a = editorRef.current) == null ? void 0 : _a.focus();
5410
+ }, [dispatch, x, editorRef]);
5411
+ const handleSortDesc = useCallback(() => {
5412
+ var _a;
5413
+ if (x == null) {
5414
+ return;
5415
+ }
5416
+ dispatch(sortRows({ x, direction: "desc" }));
5417
+ dispatch(setColumnMenu(null));
5418
+ (_a = editorRef.current) == null ? void 0 : _a.focus();
5419
+ }, [dispatch, x, editorRef]);
5420
+ const handleApplyFilter = useCallback(() => {
5421
+ var _a;
5422
+ if (x == null) {
5423
+ return;
5424
+ }
5425
+ const valid = conditions.filter((c) => {
5426
+ if (NO_VALUE_METHODS.includes(c.method)) {
5427
+ return true;
5428
+ }
5429
+ return c.value.some((v) => v.trim() !== "");
5430
+ });
5431
+ if (valid.length === 0) {
5432
+ dispatch(clearFilterRows({ x }));
5433
+ } else {
5434
+ dispatch(
5435
+ filterRows({
5436
+ x,
5437
+ filter: { mode, conditions: valid }
5438
+ })
5439
+ );
5440
+ }
5441
+ dispatch(setColumnMenu(null));
5442
+ (_a = editorRef.current) == null ? void 0 : _a.focus();
5443
+ }, [dispatch, x, conditions, mode, editorRef]);
5444
+ const handleResetColumn = useCallback(() => {
5445
+ var _a;
5446
+ if (x == null) return;
5447
+ dispatch(clearFilterRows({ x }));
5448
+ setConditions([{ ...DEFAULT_CONDITION, value: [""] }]);
5449
+ setMode("or");
5450
+ dispatch(setColumnMenu(null));
5451
+ (_a = editorRef.current) == null ? void 0 : _a.focus();
5452
+ }, [dispatch, x, editorRef]);
5453
+ const handleResetAll = useCallback(() => {
5454
+ var _a;
5455
+ dispatch(clearFilterRows({}));
5456
+ setConditions([{ ...DEFAULT_CONDITION, value: [""] }]);
5457
+ setMode("or");
5458
+ dispatch(setColumnMenu(null));
5459
+ (_a = editorRef.current) == null ? void 0 : _a.focus();
5460
+ }, [dispatch, editorRef]);
5461
+ const updateCondition = useCallback((index, patch) => {
5462
+ setConditions((prev) => {
5463
+ const next = [...prev];
5464
+ next[index] = { ...next[index], ...patch };
5465
+ return next;
5466
+ });
5467
+ }, []);
5468
+ const addCondition = useCallback(() => {
5469
+ setConditions((prev) => [...prev, { ...DEFAULT_CONDITION, value: [""] }]);
5470
+ }, []);
5471
+ const removeCondition = useCallback((index) => {
5472
+ setConditions((prev) => {
5473
+ if (prev.length <= 1) {
5474
+ return [{ ...DEFAULT_CONDITION, value: [""] }];
5475
+ }
5476
+ return prev.filter((_, i) => i !== index);
5477
+ });
5478
+ }, []);
5479
+ if (!columnMenuState || !table || x == null || !position) {
5480
+ return null;
5481
+ }
5482
+ const hasAnyFilter = table.hasActiveFilters();
5483
+ const colCell = table.getCellByPoint({ y: 0, x }, "SYSTEM");
5484
+ const sortDisabled = hasOperation(colCell == null ? void 0 : colCell.prevention, Sort);
5485
+ const filterDisabled = hasOperation(colCell == null ? void 0 : colCell.prevention, Filter);
5486
+ const labelDisabled = hasOperation(colCell == null ? void 0 : colCell.prevention, SetLabel);
5487
+ const labelPlaceholder = table.getLabel(void 0, colCell == null ? void 0 : colCell.labeler, x) ?? x2c(x);
5488
+ const insertDisabled = table.maxNumCols !== -1 && table.getNumCols() + 1 > table.maxNumCols;
5489
+ insertDisabled || hasOperation(colCell == null ? void 0 : colCell.prevention, InsertColsLeft);
5490
+ insertDisabled || hasOperation(colCell == null ? void 0 : colCell.prevention, InsertColsRight);
5491
+ table.minNumCols !== -1 && table.getNumCols() - 1 < table.minNumCols || hasOperation(colCell == null ? void 0 : colCell.prevention, RemoveCols);
5492
+ return /* @__PURE__ */ jsx(
5493
+ Fixed,
5494
+ {
5495
+ className: "gs-column-menu-modal",
5496
+ onClick: (e) => {
5497
+ e.preventDefault();
5498
+ handleClose();
5499
+ return false;
5500
+ },
5501
+ children: /* @__PURE__ */ jsx(
5502
+ "div",
5503
+ {
5504
+ className: "gs-column-menu",
5505
+ style: { top: position.y, left: position.x },
5506
+ onClick: (e) => e.stopPropagation(),
5507
+ children: /* @__PURE__ */ jsxs("ul", { children: [
5508
+ /* @__PURE__ */ jsxs("li", { className: `gs-column-menu-filter${filterDisabled ? " gs-disabled" : ""}`, children: [
5509
+ /* @__PURE__ */ jsxs("div", { className: "gs-filter-header", children: [
5510
+ /* @__PURE__ */ jsx("div", { className: "gs-menu-name", children: "Filter" }),
5511
+ /* @__PURE__ */ jsx("button", { className: "gs-filter-add-btn", onClick: addCondition, disabled: filterDisabled, children: "+ ADD" }),
5512
+ /* @__PURE__ */ jsxs("div", { className: `gs-filter-mode-toggle${conditions.length <= 1 ? " gs-disabled" : ""}`, children: [
5513
+ /* @__PURE__ */ jsxs("label", { className: mode === "and" ? "gs-active" : "", children: [
5514
+ /* @__PURE__ */ jsx(
5515
+ "input",
5516
+ {
5517
+ type: "radio",
5518
+ name: "gs-filter-mode",
5519
+ checked: mode === "and",
5520
+ onChange: () => setMode("and"),
5521
+ disabled: filterDisabled || conditions.length <= 1
5522
+ }
5523
+ ),
5524
+ "AND"
5525
+ ] }),
5526
+ /* @__PURE__ */ jsxs("label", { className: mode === "or" ? "gs-active" : "", children: [
5527
+ /* @__PURE__ */ jsx(
5528
+ "input",
5529
+ {
5530
+ type: "radio",
5531
+ name: "gs-filter-mode",
5532
+ checked: mode === "or",
5533
+ onChange: () => setMode("or"),
5534
+ disabled: filterDisabled || conditions.length <= 1
5535
+ }
5536
+ ),
5537
+ "OR"
5538
+ ] })
5539
+ ] })
5540
+ ] }),
5541
+ /* @__PURE__ */ jsx("div", { className: "gs-filter-conditions", children: conditions.map((cond, i) => /* @__PURE__ */ jsxs("div", { className: "gs-filter-condition-row", children: [
5542
+ /* @__PURE__ */ jsx(
5543
+ "select",
5544
+ {
5545
+ className: "gs-filter-method-select",
5546
+ value: cond.method,
5547
+ disabled: filterDisabled,
5548
+ onChange: (e) => updateCondition(i, {
5549
+ method: e.target.value
5550
+ }),
5551
+ children: Object.keys(METHOD_LABELS).map((m) => /* @__PURE__ */ jsx("option", { value: m, children: METHOD_LABELS[m] }, m))
5552
+ }
5553
+ ),
5554
+ !NO_VALUE_METHODS.includes(cond.method) && /* @__PURE__ */ jsx(
5555
+ "input",
5556
+ {
5557
+ className: "gs-filter-value-input",
5558
+ type: "text",
5559
+ placeholder: "Value",
5560
+ value: cond.value[0] || "",
5561
+ disabled: filterDisabled,
5562
+ onChange: (e) => updateCondition(i, { value: [e.target.value] }),
5563
+ onKeyDown: (e) => {
5564
+ if (e.nativeEvent.isComposing) {
5565
+ return;
5566
+ }
5567
+ if (e.key === "Enter") {
5568
+ handleApplyFilter();
5569
+ }
5570
+ if (e.key === "Escape") {
5571
+ handleClose();
5572
+ }
5573
+ }
5574
+ }
5575
+ ),
5576
+ /* @__PURE__ */ jsx(
5577
+ "button",
5578
+ {
5579
+ className: "gs-filter-remove-btn",
5580
+ onClick: () => removeCondition(i),
5581
+ disabled: filterDisabled,
5582
+ title: "Remove condition",
5583
+ children: "✕"
5584
+ }
5585
+ )
5586
+ ] }, i)) }),
5587
+ /* @__PURE__ */ jsxs("div", { className: "gs-filter-actions", children: [
5588
+ hasAnyFilter && /* @__PURE__ */ jsx("button", { className: "gs-filter-reset-all-btn", onClick: handleResetAll, disabled: filterDisabled, children: "RESET ALL" }),
5589
+ /* @__PURE__ */ jsxs("div", { className: "gs-filter-actions-right", children: [
5590
+ (colCell == null ? void 0 : colCell.filter) && /* @__PURE__ */ jsx("button", { className: "gs-filter-reset-btn", onClick: handleResetColumn, disabled: filterDisabled, children: "RESET" }),
5591
+ /* @__PURE__ */ jsx("button", { className: "gs-filter-apply-btn", onClick: handleApplyFilter, disabled: filterDisabled, children: "APPLY" })
5592
+ ] })
5593
+ ] })
5594
+ ] }),
5595
+ /* @__PURE__ */ jsx("li", { className: "gs-menu-divider" }),
5596
+ /* @__PURE__ */ jsx(
5597
+ "li",
5598
+ {
5599
+ className: sortDisabled ? "gs-disabled" : "gs-enabled",
5600
+ onClick: () => {
5601
+ if (!sortDisabled) {
5602
+ handleSortAsc();
5603
+ }
5604
+ },
5605
+ children: /* @__PURE__ */ jsx("div", { className: "gs-menu-name", children: "Sort A to Z" })
5606
+ }
5607
+ ),
5608
+ /* @__PURE__ */ jsx(
5609
+ "li",
5610
+ {
5611
+ className: sortDisabled ? "gs-disabled" : "gs-enabled",
5612
+ onClick: () => {
5613
+ if (!sortDisabled) {
5614
+ handleSortDesc();
5615
+ }
5616
+ },
5617
+ children: /* @__PURE__ */ jsx("div", { className: "gs-menu-name", children: "Sort Z to A" })
5618
+ }
5619
+ ),
5620
+ /* @__PURE__ */ jsx("li", { className: "gs-menu-divider" }),
5621
+ /* @__PURE__ */ jsx("li", { className: `gs-column-menu-label${labelDisabled ? " gs-disabled" : ""}`, children: /* @__PURE__ */ jsxs("div", { className: "gs-label-input-row", children: [
5622
+ /* @__PURE__ */ jsx("div", { className: "gs-menu-name", children: "Label:" }),
5623
+ /* @__PURE__ */ jsx(
5624
+ "input",
5625
+ {
5626
+ ref: labelInputRef,
5627
+ className: "gs-label-input",
5628
+ type: "text",
5629
+ placeholder: labelPlaceholder,
5630
+ value: label,
5631
+ disabled: labelDisabled,
5632
+ onChange: (e) => setLabel(e.target.value),
5633
+ onKeyDown: (e) => {
5634
+ if (e.nativeEvent.isComposing) {
5635
+ return;
5636
+ }
5637
+ if (e.key === "Enter") {
5638
+ handleApplyLabel();
5639
+ }
5640
+ if (e.key === "Escape") {
5641
+ handleClose();
5642
+ }
5643
+ }
5644
+ }
5645
+ ),
5646
+ /* @__PURE__ */ jsx("button", { className: "gs-label-apply-btn", onClick: handleApplyLabel, disabled: labelDisabled, children: "UPDATE" })
5647
+ ] }) })
5648
+ ] })
5649
+ }
5650
+ )
5651
+ }
5652
+ );
5653
+ };
5127
5654
  var utc$2 = { exports: {} };
5128
5655
  var utc$1 = utc$2.exports;
5129
5656
  var hasRequiredUtc;
@@ -5279,11 +5806,103 @@ var timezoneExports = requireTimezone();
5279
5806
  const timezone = /* @__PURE__ */ getDefaultExportFromCjs(timezoneExports);
5280
5807
  dayjs.extend(timezone);
5281
5808
  dayjs.extend(utc);
5282
- const BOOLS = { true: true, false: false };
5283
5809
  const NUMS = /* @__PURE__ */ new Set(["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]);
5284
5810
  const NUMS_Z = /* @__PURE__ */ new Set([...NUMS, "Z", "z"]);
5285
5811
  const JFMASOND = /* @__PURE__ */ new Set(["J", "F", "M", "A", "S", "O", "N", "D", ...NUMS]);
5286
5812
  const NBRYNLGPTVC = /* @__PURE__ */ new Set(["N", "B", "R", "Y", "N", "L", "G", "P", "T", "V", "C", ...NUMS_Z]);
5813
+ const DATE_WORDS = /* @__PURE__ */ new Set([
5814
+ "jan",
5815
+ "feb",
5816
+ "mar",
5817
+ "apr",
5818
+ "may",
5819
+ "jun",
5820
+ "jul",
5821
+ "aug",
5822
+ "sep",
5823
+ "oct",
5824
+ "nov",
5825
+ "dec",
5826
+ "january",
5827
+ "february",
5828
+ "march",
5829
+ "april",
5830
+ "june",
5831
+ "july",
5832
+ "august",
5833
+ "september",
5834
+ "october",
5835
+ "november",
5836
+ "december",
5837
+ "mon",
5838
+ "tue",
5839
+ "wed",
5840
+ "thu",
5841
+ "fri",
5842
+ "sat",
5843
+ "sun",
5844
+ "monday",
5845
+ "tuesday",
5846
+ "wednesday",
5847
+ "thursday",
5848
+ "friday",
5849
+ "saturday",
5850
+ "sunday",
5851
+ "am",
5852
+ "pm",
5853
+ "utc",
5854
+ "gmt",
5855
+ "est",
5856
+ "cst",
5857
+ "mst",
5858
+ "pst",
5859
+ "jst",
5860
+ "cet",
5861
+ "eet",
5862
+ "ist",
5863
+ "aest",
5864
+ "edt",
5865
+ "cdt",
5866
+ "mdt",
5867
+ "pdt",
5868
+ "bst",
5869
+ "hst",
5870
+ "akst",
5871
+ "akdt",
5872
+ "nzst",
5873
+ "nzdt",
5874
+ "t",
5875
+ "z"
5876
+ ]);
5877
+ function parseDate(value) {
5878
+ const first = value[0];
5879
+ if (first == null || !JFMASOND.has(first.toUpperCase())) {
5880
+ return;
5881
+ }
5882
+ if (!NBRYNLGPTVC.has(value[value.length - 1].toUpperCase())) {
5883
+ return;
5884
+ }
5885
+ if (value.match(/[=*&#@!?[\]{}"'()|%\\<>~+\r\n]/)) {
5886
+ return;
5887
+ }
5888
+ const words = value.split(/[\s,/\-:.]+/).filter(Boolean);
5889
+ for (const word of words) {
5890
+ if (/^[a-zA-Z]+$/.test(word) && !DATE_WORDS.has(word.toLowerCase())) {
5891
+ return;
5892
+ }
5893
+ }
5894
+ let timeZone = "UTC";
5895
+ try {
5896
+ timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
5897
+ } catch (e) {
5898
+ }
5899
+ try {
5900
+ const day = dayjs.tz(value, timeZone);
5901
+ return day.toDate();
5902
+ } catch (e) {
5903
+ }
5904
+ }
5905
+ const BOOLS = { true: true, false: false };
5287
5906
  class Parser2 {
5288
5907
  constructor(props) {
5289
5908
  this.applyMixins(props == null ? void 0 : props.mixins);
@@ -5371,26 +5990,7 @@ class Parser2 {
5371
5990
  return TimeDelta.parse(value);
5372
5991
  }
5373
5992
  date(value, cell) {
5374
- const first = value[0];
5375
- if (first == null || !JFMASOND.has(first.toUpperCase())) {
5376
- return;
5377
- }
5378
- if (!NBRYNLGPTVC.has(value[value.length - 1].toUpperCase())) {
5379
- return;
5380
- }
5381
- if (value.match(/[=*&#@!?[\]{}"'()|%\\<>~+\r\n]/)) {
5382
- return;
5383
- }
5384
- let timeZone = "UTC";
5385
- try {
5386
- timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
5387
- } catch (e) {
5388
- }
5389
- try {
5390
- const day = dayjs.tz(value, timeZone);
5391
- return day.toDate();
5392
- } catch (e) {
5393
- }
5993
+ return parseDate(value);
5394
5994
  }
5395
5995
  }
5396
5996
  const defaultParser = new Parser2();
@@ -7661,6 +8261,174 @@ class Policy {
7661
8261
  }
7662
8262
  }
7663
8263
  const defaultPolicy = new Policy();
8264
+ const _str = (v) => v == null ? "" : String(v);
8265
+ function detectType(cellValue) {
8266
+ if (typeof cellValue === "number") {
8267
+ return "number";
8268
+ }
8269
+ if (cellValue instanceof Date) {
8270
+ return "date";
8271
+ }
8272
+ if (TimeDelta.is(cellValue)) {
8273
+ return "timedelta";
8274
+ }
8275
+ if (typeof cellValue === "boolean") {
8276
+ return "boolean";
8277
+ }
8278
+ return "string";
8279
+ }
8280
+ function parseAsType(v, type) {
8281
+ switch (type) {
8282
+ case "number": {
8283
+ let s = v.replace(/[,_]/g, "");
8284
+ let scale = 1;
8285
+ if (s.endsWith("%")) {
8286
+ s = s.slice(0, -1);
8287
+ scale = 0.01;
8288
+ }
8289
+ const n = Number(s);
8290
+ return { ok: !isNaN(n), num: n * scale };
8291
+ }
8292
+ case "date": {
8293
+ const d = parseDate(v);
8294
+ if (!d) {
8295
+ return { ok: false, num: NaN };
8296
+ }
8297
+ return { ok: true, num: d.getTime() };
8298
+ }
8299
+ case "timedelta": {
8300
+ const td = TimeDelta.parse(v);
8301
+ return td ? { ok: true, num: td.toMilliseconds() } : { ok: false, num: NaN };
8302
+ }
8303
+ case "boolean": {
8304
+ const bv = v.toLowerCase();
8305
+ if (bv === "true") {
8306
+ return { ok: true, num: 1 };
8307
+ }
8308
+ if (bv === "false") {
8309
+ return { ok: true, num: 0 };
8310
+ }
8311
+ return { ok: false, num: NaN };
8312
+ }
8313
+ default:
8314
+ return { ok: false, num: NaN };
8315
+ }
8316
+ }
8317
+ function toNumeric(cellValue, type) {
8318
+ switch (type) {
8319
+ case "number":
8320
+ return cellValue;
8321
+ case "date":
8322
+ return cellValue.getTime();
8323
+ case "timedelta":
8324
+ return TimeDelta.ensure(cellValue).toMilliseconds();
8325
+ case "boolean":
8326
+ return cellValue ? 1 : 0;
8327
+ default:
8328
+ return NaN;
8329
+ }
8330
+ }
8331
+ const filterEq = (condition, cellValue) => {
8332
+ const vt = detectType(cellValue);
8333
+ if (vt === "string") {
8334
+ const s = _str(cellValue);
8335
+ return condition.value.some((v) => s === v);
8336
+ }
8337
+ const cellNum = toNumeric(cellValue, vt);
8338
+ return condition.value.some((v) => {
8339
+ const parsed = parseAsType(v, vt);
8340
+ return parsed.ok && cellNum === parsed.num;
8341
+ });
8342
+ };
8343
+ const filterNe = (condition, cellValue) => {
8344
+ const vt = detectType(cellValue);
8345
+ if (vt === "string") {
8346
+ const s = _str(cellValue);
8347
+ return !condition.value.some((v) => s === v);
8348
+ }
8349
+ const cellNum = toNumeric(cellValue, vt);
8350
+ return !condition.value.some((v) => {
8351
+ const parsed = parseAsType(v, vt);
8352
+ return parsed.ok && cellNum === parsed.num;
8353
+ });
8354
+ };
8355
+ const filterGt = (condition, cellValue) => {
8356
+ const vt = detectType(cellValue);
8357
+ if (vt === "string") {
8358
+ return _str(cellValue) > condition.value[0];
8359
+ }
8360
+ const cellNum = toNumeric(cellValue, vt);
8361
+ const parsed = parseAsType(condition.value[0], vt);
8362
+ return parsed.ok && cellNum > parsed.num;
8363
+ };
8364
+ const filterGte = (condition, cellValue) => {
8365
+ const vt = detectType(cellValue);
8366
+ if (vt === "string") {
8367
+ return _str(cellValue) >= condition.value[0];
8368
+ }
8369
+ const cellNum = toNumeric(cellValue, vt);
8370
+ const parsed = parseAsType(condition.value[0], vt);
8371
+ return parsed.ok && cellNum >= parsed.num;
8372
+ };
8373
+ const filterLt = (condition, cellValue) => {
8374
+ const vt = detectType(cellValue);
8375
+ if (vt === "string") {
8376
+ return _str(cellValue) < condition.value[0];
8377
+ }
8378
+ const cellNum = toNumeric(cellValue, vt);
8379
+ const parsed = parseAsType(condition.value[0], vt);
8380
+ return parsed.ok && cellNum < parsed.num;
8381
+ };
8382
+ const filterLte = (condition, cellValue) => {
8383
+ const vt = detectType(cellValue);
8384
+ if (vt === "string") {
8385
+ return _str(cellValue) <= condition.value[0];
8386
+ }
8387
+ const cellNum = toNumeric(cellValue, vt);
8388
+ const parsed = parseAsType(condition.value[0], vt);
8389
+ return parsed.ok && cellNum <= parsed.num;
8390
+ };
8391
+ const filterBlank = (_condition, cellValue) => {
8392
+ return cellValue == null || _str(cellValue) === "";
8393
+ };
8394
+ const filterNonblank = (_condition, cellValue) => {
8395
+ return cellValue != null && _str(cellValue) !== "";
8396
+ };
8397
+ const filterIncludes = (condition, cellValue) => {
8398
+ const s = _str(cellValue).toLowerCase();
8399
+ return condition.value.some((v) => s.includes(v.toLowerCase()));
8400
+ };
8401
+ const filterExcludes = (condition, cellValue) => {
8402
+ const s = _str(cellValue).toLowerCase();
8403
+ return !condition.value.some((v) => s.includes(v.toLowerCase()));
8404
+ };
8405
+ const filterFunctions = {
8406
+ eq: filterEq,
8407
+ ne: filterNe,
8408
+ gt: filterGt,
8409
+ gte: filterGte,
8410
+ lt: filterLt,
8411
+ lte: filterLte,
8412
+ blank: filterBlank,
8413
+ nonblank: filterNonblank,
8414
+ includes: filterIncludes,
8415
+ excludes: filterExcludes
8416
+ };
8417
+ function evaluateFilterCondition(condition, cellValue) {
8418
+ const fn = filterFunctions[condition.method];
8419
+ return fn ? fn(condition, cellValue) : true;
8420
+ }
8421
+ function evaluateFilterConfig(filter, cellValue) {
8422
+ const mode = filter.mode ?? "or";
8423
+ if (filter.conditions.length === 0) {
8424
+ return true;
8425
+ }
8426
+ if (mode === "and") {
8427
+ return filter.conditions.every((c) => evaluateFilterCondition(c, cellValue));
8428
+ } else {
8429
+ return filter.conditions.some((c) => evaluateFilterCondition(c, cellValue));
8430
+ }
8431
+ }
7664
8432
  class ReferencePreserver {
7665
8433
  constructor(table) {
7666
8434
  this.map = {};
@@ -7712,6 +8480,7 @@ class Table {
7712
8480
  this.idsToBeIdentified = [];
7713
8481
  this.totalWidth = 0;
7714
8482
  this.totalHeight = 0;
8483
+ this.fullHeight = 0;
7715
8484
  this.version = 0;
7716
8485
  this.area = { top: 0, left: 0, bottom: 0, right: 0 };
7717
8486
  this.addressCaches = /* @__PURE__ */ new Map();
@@ -7746,6 +8515,278 @@ class Table {
7746
8515
  historicize
7747
8516
  });
7748
8517
  }
8518
+ /** Get the raw (mutable) cell data for a point. Unlike getCellByPoint, this returns the actual wire.data reference. */
8519
+ _getRawCellByPoint({ y, x }) {
8520
+ var _a;
8521
+ const id = (_a = this.idMatrix[y]) == null ? void 0 : _a[x];
8522
+ if (id == null) {
8523
+ return void 0;
8524
+ }
8525
+ return this.wire.data[id];
8526
+ }
8527
+ isRowFiltered(y) {
8528
+ var _a;
8529
+ return !!((_a = this._getRawCellByPoint({ y, x: 0 })) == null ? void 0 : _a.filtered);
8530
+ }
8531
+ hasActiveFilters() {
8532
+ const numCols = this.getNumCols();
8533
+ for (let col = 1; col <= numCols; col++) {
8534
+ const colCell = this._getRawCellByPoint({ y: 0, x: col });
8535
+ if ((colCell == null ? void 0 : colCell.filter) && colCell.filter.conditions.length > 0) {
8536
+ return true;
8537
+ }
8538
+ }
8539
+ return false;
8540
+ }
8541
+ /** Capture the current state of all filter-related cells (column headers + row headers) as a CellsByIdType snapshot */
8542
+ /** Capture the full cell state of all filter-related header cells as a CellsByIdType snapshot */
8543
+ _captureFilterCellStates() {
8544
+ var _a, _b;
8545
+ const snapshot = {};
8546
+ const numCols = this.getNumCols();
8547
+ const numRows = this.getNumRows();
8548
+ for (let col = 1; col <= numCols; col++) {
8549
+ const id = (_a = this.idMatrix[0]) == null ? void 0 : _a[col];
8550
+ if (id != null) {
8551
+ snapshot[id] = { ...this.wire.data[id] };
8552
+ }
8553
+ }
8554
+ for (let y = 1; y <= numRows; y++) {
8555
+ const id = (_b = this.idMatrix[y]) == null ? void 0 : _b[0];
8556
+ if (id != null) {
8557
+ snapshot[id] = { ...this.wire.data[id] };
8558
+ }
8559
+ }
8560
+ return snapshot;
8561
+ }
8562
+ filterRows({
8563
+ x,
8564
+ filter,
8565
+ undoReflection,
8566
+ redoReflection
8567
+ }) {
8568
+ const diffBefore = this._captureFilterCellStates();
8569
+ const colCell = this._getRawCellByPoint({ y: 0, x });
8570
+ if (colCell) {
8571
+ colCell.filter = filter;
8572
+ }
8573
+ this._reapplyFilters();
8574
+ const diffAfter = this._captureFilterCellStates();
8575
+ this.pushHistory({
8576
+ applyed: true,
8577
+ operation: "UPDATE",
8578
+ srcSheetId: this.sheetId,
8579
+ dstSheetId: this.sheetId,
8580
+ undoReflection,
8581
+ redoReflection,
8582
+ diffBefore,
8583
+ diffAfter,
8584
+ partial: false
8585
+ });
8586
+ return this.refresh(false, true);
8587
+ }
8588
+ setColLabel({
8589
+ x,
8590
+ label,
8591
+ undoReflection,
8592
+ redoReflection
8593
+ }) {
8594
+ var _a;
8595
+ const id = (_a = this.idMatrix[0]) == null ? void 0 : _a[x];
8596
+ const diffBefore = {};
8597
+ if (id != null) {
8598
+ diffBefore[id] = { ...this.wire.data[id] };
8599
+ }
8600
+ const colCell = this._getRawCellByPoint({ y: 0, x });
8601
+ if (colCell) {
8602
+ if (label === "") {
8603
+ delete colCell.label;
8604
+ } else {
8605
+ colCell.label = label;
8606
+ }
8607
+ }
8608
+ const diffAfter = {};
8609
+ if (id != null) {
8610
+ diffAfter[id] = { ...this.wire.data[id] };
8611
+ }
8612
+ const changed = Object.keys(diffBefore).some(
8613
+ (id2) => JSON.stringify(diffBefore[id2]) !== JSON.stringify(diffAfter[id2])
8614
+ );
8615
+ if (changed) {
8616
+ this.pushHistory({
8617
+ applyed: true,
8618
+ operation: "UPDATE",
8619
+ srcSheetId: this.sheetId,
8620
+ dstSheetId: this.sheetId,
8621
+ undoReflection,
8622
+ redoReflection,
8623
+ diffBefore,
8624
+ diffAfter,
8625
+ partial: false
8626
+ });
8627
+ }
8628
+ return this.refresh(false, true);
8629
+ }
8630
+ clearFilterRows(x, undoReflection, redoReflection) {
8631
+ const diffBefore = this._captureFilterCellStates();
8632
+ if (x != null) {
8633
+ const colCell = this._getRawCellByPoint({ y: 0, x });
8634
+ if (colCell) {
8635
+ delete colCell.filter;
8636
+ }
8637
+ } else {
8638
+ const numCols = this.getNumCols();
8639
+ for (let col = 1; col <= numCols; col++) {
8640
+ const colCell = this._getRawCellByPoint({ y: 0, x: col });
8641
+ if (colCell == null ? void 0 : colCell.filter) {
8642
+ delete colCell.filter;
8643
+ }
8644
+ }
8645
+ }
8646
+ this._reapplyFilters();
8647
+ const diffAfter = this._captureFilterCellStates();
8648
+ const changed = Object.keys(diffBefore).some(
8649
+ (id) => JSON.stringify(diffBefore[id]) !== JSON.stringify(diffAfter[id])
8650
+ );
8651
+ if (changed) {
8652
+ this.pushHistory({
8653
+ applyed: true,
8654
+ operation: "UPDATE",
8655
+ srcSheetId: this.sheetId,
8656
+ dstSheetId: this.sheetId,
8657
+ undoReflection,
8658
+ redoReflection,
8659
+ diffBefore,
8660
+ diffAfter,
8661
+ partial: false
8662
+ });
8663
+ }
8664
+ return this.refresh(false, true);
8665
+ }
8666
+ _evaluateFilterConfig(filter, cellValue) {
8667
+ return evaluateFilterConfig(filter, cellValue);
8668
+ }
8669
+ _reapplyFilters() {
8670
+ const numCols = this.getNumCols();
8671
+ const activeFilters = [];
8672
+ for (let col = 1; col <= numCols; col++) {
8673
+ const colCell = this._getRawCellByPoint({ y: 0, x: col });
8674
+ if ((colCell == null ? void 0 : colCell.filter) && colCell.filter.conditions.length > 0) {
8675
+ activeFilters.push({ x: col, filter: colCell.filter });
8676
+ }
8677
+ }
8678
+ const numRows = this.getNumRows();
8679
+ for (let y = 1; y <= numRows; y++) {
8680
+ const rowCell = this._getRawCellByPoint({ y, x: 0 });
8681
+ if (rowCell) {
8682
+ delete rowCell.filtered;
8683
+ }
8684
+ }
8685
+ if (activeFilters.length === 0) {
8686
+ return;
8687
+ }
8688
+ for (let y = 1; y <= numRows; y++) {
8689
+ let visible = true;
8690
+ for (const { x: col, filter } of activeFilters) {
8691
+ const cell = this.getCellByPoint({ y, x: col }, "COMPLETE");
8692
+ if (!this._evaluateFilterConfig(filter, cell == null ? void 0 : cell.value)) {
8693
+ visible = false;
8694
+ break;
8695
+ }
8696
+ }
8697
+ if (!visible) {
8698
+ const rowCell = this._getRawCellByPoint({ y, x: 0 });
8699
+ if (rowCell) {
8700
+ rowCell.filtered = true;
8701
+ }
8702
+ }
8703
+ }
8704
+ }
8705
+ sortRows({
8706
+ x,
8707
+ direction,
8708
+ undoReflection,
8709
+ redoReflection
8710
+ }) {
8711
+ const numRows = this.getNumRows();
8712
+ if (numRows <= 1) {
8713
+ return this;
8714
+ }
8715
+ const rowsBefore = [];
8716
+ for (let y = 1; y <= numRows; y++) {
8717
+ rowsBefore.push([...this.idMatrix[y]]);
8718
+ }
8719
+ const rowIndices = [];
8720
+ for (let y = 1; y <= numRows; y++) {
8721
+ rowIndices.push(y);
8722
+ }
8723
+ rowIndices.sort((a, b) => {
8724
+ const cellA = this.getCellByPoint({ y: a, x }, "COMPLETE");
8725
+ const cellB = this.getCellByPoint({ y: b, x }, "COMPLETE");
8726
+ const valA = cellA == null ? void 0 : cellA.value;
8727
+ const valB = cellB == null ? void 0 : cellB.value;
8728
+ if (valA == null && valB == null) {
8729
+ return 0;
8730
+ }
8731
+ if (valA == null) {
8732
+ return 1;
8733
+ }
8734
+ if (valB == null) {
8735
+ return -1;
8736
+ }
8737
+ let cmp = 0;
8738
+ if (typeof valA === "number" && typeof valB === "number") {
8739
+ cmp = valA - valB;
8740
+ } else if (valA instanceof Date && valB instanceof Date) {
8741
+ cmp = valA.getTime() - valB.getTime();
8742
+ } else {
8743
+ cmp = String(valA).localeCompare(String(valB));
8744
+ }
8745
+ return direction === "asc" ? cmp : -cmp;
8746
+ });
8747
+ let changed = false;
8748
+ for (let i = 0; i < rowIndices.length; i++) {
8749
+ if (rowIndices[i] !== i + 1) {
8750
+ changed = true;
8751
+ break;
8752
+ }
8753
+ }
8754
+ if (!changed) {
8755
+ return this;
8756
+ }
8757
+ this._applySortOrder(rowIndices);
8758
+ const rowsAfter = [];
8759
+ for (let y = 1; y <= numRows; y++) {
8760
+ rowsAfter.push([...this.idMatrix[y]]);
8761
+ }
8762
+ this.pushHistory({
8763
+ applyed: true,
8764
+ operation: "SORT_ROWS",
8765
+ srcSheetId: this.sheetId,
8766
+ dstSheetId: this.sheetId,
8767
+ undoReflection,
8768
+ redoReflection,
8769
+ rowsBefore,
8770
+ rowsAfter
8771
+ });
8772
+ return this.refresh(true, true);
8773
+ }
8774
+ _applySortOrder(newOrder) {
8775
+ const savedRows = [];
8776
+ for (let i = 0; i < newOrder.length; i++) {
8777
+ savedRows.push(this.idMatrix[newOrder[i]]);
8778
+ }
8779
+ for (let i = 0; i < newOrder.length; i++) {
8780
+ this.idMatrix[i + 1] = savedRows[i];
8781
+ }
8782
+ this.addressCaches.clear();
8783
+ }
8784
+ _restoreRows(rows) {
8785
+ for (let i = 0; i < rows.length; i++) {
8786
+ this.idMatrix[i + 1] = [...rows[i]];
8787
+ }
8788
+ this.addressCaches.clear();
8789
+ }
7749
8790
  get isInitialized() {
7750
8791
  return this.status === 2;
7751
8792
  }
@@ -7869,6 +8910,7 @@ class Table {
7869
8910
  } else {
7870
8911
  delete stacked.height;
7871
8912
  delete stacked.width;
8913
+ delete stacked.label;
7872
8914
  delete stacked.labeler;
7873
8915
  }
7874
8916
  stacked.system = { id, changedAt, dependents: /* @__PURE__ */ new Set(), sheetId: this.sheetId };
@@ -7888,26 +8930,51 @@ class Table {
7888
8930
  return (this.wire.cellHead++).toString(36);
7889
8931
  }
7890
8932
  getRectSize({ top, left, bottom, right }) {
7891
- var _a, _b;
7892
- let width = 0, height = 0;
7893
- for (let x = left || 1; x < right; x++) {
7894
- width += ((_a = this.getCellByPoint({ y: 0, x }, "SYSTEM")) == null ? void 0 : _a.width) || DEFAULT_WIDTH;
7895
- }
7896
- for (let y = top || 1; y < bottom; y++) {
7897
- height += ((_b = this.getCellByPoint({ y, x: 0 }, "SYSTEM")) == null ? void 0 : _b.height) || DEFAULT_HEIGHT;
7898
- }
8933
+ var _a, _b, _c, _d;
8934
+ const l = left || 1;
8935
+ const t = top || 1;
8936
+ const colRightCell = this.getCellByPoint({ y: 0, x: right }, "SYSTEM");
8937
+ const colLeftCell = this.getCellByPoint({ y: 0, x: l }, "SYSTEM");
8938
+ const rowBottomCell = this.getCellByPoint({ y: bottom, x: 0 }, "SYSTEM");
8939
+ const rowTopCell = this.getCellByPoint({ y: t, x: 0 }, "SYSTEM");
8940
+ const rw = ((_a = colRightCell == null ? void 0 : colRightCell.system) == null ? void 0 : _a.offsetLeft) ?? 0;
8941
+ const lw = ((_b = colLeftCell == null ? void 0 : colLeftCell.system) == null ? void 0 : _b.offsetLeft) ?? 0;
8942
+ const rh = ((_c = rowBottomCell == null ? void 0 : rowBottomCell.system) == null ? void 0 : _c.offsetTop) ?? 0;
8943
+ const th = ((_d = rowTopCell == null ? void 0 : rowTopCell.system) == null ? void 0 : _d.offsetTop) ?? 0;
8944
+ const width = Math.max(0, rw - lw);
8945
+ const height = Math.max(0, rh - th);
7899
8946
  return { width, height };
7900
8947
  }
7901
8948
  setTotalSize() {
7902
- const { bottom, right } = this.area;
7903
- const { width, height } = this.getRectSize({
7904
- top: 1,
7905
- left: 1,
7906
- bottom: bottom + 1,
7907
- right: right + 1
7908
- });
7909
- this.totalWidth = width + this.headerWidth;
7910
- this.totalHeight = height + this.headerHeight;
8949
+ const numCols = this.getNumCols();
8950
+ const numRows = this.getNumRows();
8951
+ const headerW = this.headerWidth;
8952
+ const headerH = this.headerHeight;
8953
+ let accW = 0;
8954
+ for (let x = 1; x <= numCols; x++) {
8955
+ const cell = this.getCellByPoint({ y: 0, x }, "SYSTEM");
8956
+ const w = (cell == null ? void 0 : cell.width) || DEFAULT_WIDTH;
8957
+ if (cell == null ? void 0 : cell.system) {
8958
+ cell.system.offsetLeft = headerW + accW;
8959
+ }
8960
+ accW += w;
8961
+ }
8962
+ this.totalWidth = headerW + accW;
8963
+ let accH = 0;
8964
+ let fullH = 0;
8965
+ for (let y = 1; y <= numRows; y++) {
8966
+ const cell = this.getCellByPoint({ y, x: 0 }, "SYSTEM");
8967
+ const h = (cell == null ? void 0 : cell.height) || DEFAULT_HEIGHT;
8968
+ if (cell == null ? void 0 : cell.system) {
8969
+ cell.system.offsetTop = headerH + accH;
8970
+ }
8971
+ if (!(cell == null ? void 0 : cell.filtered)) {
8972
+ accH += h;
8973
+ }
8974
+ fullH += h;
8975
+ }
8976
+ this.totalHeight = headerH + accH;
8977
+ this.fullHeight = headerH + fullH;
7911
8978
  }
7912
8979
  refresh(relocate = false, resize = false) {
7913
8980
  this.incrementVersion();
@@ -8520,7 +9587,7 @@ class Table {
8520
9587
  diff,
8521
9588
  partial = true,
8522
9589
  updateChangedAt = true,
8523
- ignoreFields = ["labeler"],
9590
+ ignoreFields = ["label", "labeler"],
8524
9591
  operator = "SYSTEM",
8525
9592
  operation: op = Update,
8526
9593
  formulaIdentify = true
@@ -9043,7 +10110,7 @@ class Table {
9043
10110
  break;
9044
10111
  case "INSERT_ROWS": {
9045
10112
  if (history.diffBefore) {
9046
- dstTable.applyDiff(history.diffBefore, history.partial);
10113
+ dstTable.applyDiff(history.diffBefore, false);
9047
10114
  }
9048
10115
  const { height } = matrixShape({ matrix: history.idMatrix });
9049
10116
  dstTable.idMatrix.splice(history.y, height);
@@ -9108,6 +10175,11 @@ class Table {
9108
10175
  }
9109
10176
  break;
9110
10177
  }
10178
+ case "SORT_ROWS": {
10179
+ dstTable._restoreRows(history.rowsBefore);
10180
+ dstTable._reapplyFilters();
10181
+ break;
10182
+ }
9111
10183
  }
9112
10184
  this.refresh(shouldTracking(history.operation), true);
9113
10185
  return {
@@ -9132,11 +10204,11 @@ class Table {
9132
10204
  }
9133
10205
  switch (history.operation) {
9134
10206
  case "UPDATE":
9135
- dstTable.applyDiff(history.diffAfter, history.partial);
10207
+ dstTable.applyDiff(history.diffAfter, false);
9136
10208
  break;
9137
10209
  case "INSERT_ROWS": {
9138
10210
  if (history.diffAfter) {
9139
- dstTable.applyDiff(history.diffAfter, history.partial);
10211
+ dstTable.applyDiff(history.diffAfter, false);
9140
10212
  }
9141
10213
  const { height } = matrixShape({ matrix: history.idMatrix });
9142
10214
  dstTable.idMatrix.splice(history.y, 0, ...history.idMatrix);
@@ -9145,7 +10217,7 @@ class Table {
9145
10217
  }
9146
10218
  case "INSERT_COLS": {
9147
10219
  if (history.diffAfter) {
9148
- dstTable.applyDiff(history.diffAfter, history.partial);
10220
+ dstTable.applyDiff(history.diffAfter, false);
9149
10221
  }
9150
10222
  const { width } = matrixShape({ matrix: history.idMatrix });
9151
10223
  dstTable.idMatrix.map((row, i) => {
@@ -9179,6 +10251,12 @@ class Table {
9179
10251
  if (srcTable) {
9180
10252
  dstTable.move({ srcTable, src, dst, operator: "USER", historicize: false });
9181
10253
  }
10254
+ break;
10255
+ }
10256
+ case "SORT_ROWS": {
10257
+ dstTable._restoreRows(history.rowsAfter);
10258
+ dstTable._reapplyFilters();
10259
+ break;
9182
10260
  }
9183
10261
  }
9184
10262
  this.refresh(shouldTracking(history.operation), true);
@@ -9193,12 +10271,18 @@ class Table {
9193
10271
  getFunction(name) {
9194
10272
  return this.functions[name];
9195
10273
  }
9196
- getLabel(key, n) {
9197
- if (key == null) {
10274
+ getLabel(label, labelerKey, n) {
10275
+ if (label != null) {
10276
+ return label;
10277
+ }
10278
+ if (labelerKey == null) {
9198
10279
  return null;
9199
10280
  }
9200
- const labeler = this.labelers[key];
9201
- return labeler == null ? void 0 : labeler(n);
10281
+ const labeler = this.labelers[labelerKey];
10282
+ if (labeler) {
10283
+ return labeler(n);
10284
+ }
10285
+ return null;
9202
10286
  }
9203
10287
  getBase() {
9204
10288
  return this;
@@ -9263,7 +10347,7 @@ const safePreventDefault = (e) => {
9263
10347
  e.preventDefault();
9264
10348
  }
9265
10349
  };
9266
- const Cell = memo(({ y, x, operationStyle }) => {
10350
+ const Cell = memo(({ y, x }) => {
9267
10351
  const rowId = y2r(y);
9268
10352
  const colId = x2c(x);
9269
10353
  const address = `${colId}${rowId}`;
@@ -9499,8 +10583,7 @@ const Cell = memo(({ y, x, operationStyle }) => {
9499
10583
  "data-address": address,
9500
10584
  className: `gs-cell ${among(selectingArea, { y, x }) ? "gs-selecting" : ""} ${pointed ? "gs-choosing" : ""} ${editing ? "gs-editing" : ""}`,
9501
10585
  style: {
9502
- ...cell == null ? void 0 : cell.style,
9503
- ...operationStyle
10586
+ ...cell == null ? void 0 : cell.style
9504
10587
  },
9505
10588
  onContextMenu,
9506
10589
  onDoubleClick,
@@ -9720,11 +10803,13 @@ const HeaderCellTop = memo(({ x }) => {
9720
10803
  editorRef,
9721
10804
  autofillDraggingTo,
9722
10805
  dragging,
9723
- contextMenuItems
10806
+ contextMenuItems,
10807
+ columnMenuState
9724
10808
  } = store;
9725
10809
  const table = tableRef.current;
9726
10810
  const col = table == null ? void 0 : table.getCellByPoint({ y: 0, x }, "SYSTEM");
9727
10811
  const width = (col == null ? void 0 : col.width) || DEFAULT_WIDTH;
10812
+ const hasFilter = !!((col == null ? void 0 : col.filter) && col.filter.conditions.length > 0);
9728
10813
  const xSheetFocused = isXSheetFocused(store);
9729
10814
  const lastFocused = table == null ? void 0 : table.wire.lastFocused;
9730
10815
  const editingAnywhere = !!((table == null ? void 0 : table.wire.editingAddress) || editingAddress);
@@ -9873,7 +10958,25 @@ const HeaderCellTop = memo(({ x }) => {
9873
10958
  vertical: -1
9874
10959
  }
9875
10960
  ),
9876
- table.getLabel(col == null ? void 0 : col.labeler, x) ?? colId,
10961
+ table.getLabel(col == null ? void 0 : col.label, col == null ? void 0 : col.labeler, x) ?? colId,
10962
+ !hasOperation(col == null ? void 0 : col.prevention, ColumnMenu$1) && /* @__PURE__ */ jsx(
10963
+ "button",
10964
+ {
10965
+ className: `gs-column-menu-btn ${hasFilter ? "gs-filtered" : ""} ${(columnMenuState == null ? void 0 : columnMenuState.x) === x ? "gs-active" : ""}`,
10966
+ onMouseDown: (e) => {
10967
+ e.stopPropagation();
10968
+ e.preventDefault();
10969
+ const rect = e.target.getBoundingClientRect();
10970
+ if ((columnMenuState == null ? void 0 : columnMenuState.x) === x) {
10971
+ dispatch(setColumnMenu(null));
10972
+ } else {
10973
+ dispatch(setColumnMenu({ x, position: { y: rect.bottom, x: rect.left } }));
10974
+ }
10975
+ },
10976
+ title: "Sort & Filter",
10977
+ children: "⋮"
10978
+ }
10979
+ ),
9877
10980
  /* @__PURE__ */ jsx(
9878
10981
  "div",
9879
10982
  {
@@ -10058,7 +11161,7 @@ const HeaderCellLeft = memo(({ y }) => {
10058
11161
  horizontal: -1
10059
11162
  }
10060
11163
  ),
10061
- table.getLabel(row == null ? void 0 : row.labeler, y) ?? rowId,
11164
+ table.getLabel(row == null ? void 0 : row.label, row == null ? void 0 : row.labeler, y) ?? rowId,
10062
11165
  /* @__PURE__ */ jsx(
10063
11166
  "div",
10064
11167
  {
@@ -10076,6 +11179,263 @@ const HeaderCellLeft = memo(({ y }) => {
10076
11179
  }
10077
11180
  );
10078
11181
  });
11182
+ const COLOR_POINTED = "#0077ff";
11183
+ const COLOR_SELECTED = "#0077ff";
11184
+ const SELECTING_FILL = "rgba(0, 128, 255, 0.2)";
11185
+ const COLOR_COPYING = "#0077ff";
11186
+ const COLOR_CUTTING = "#0077ff";
11187
+ const SEARCH_MATCHING_BACKGROUND = "rgba(0, 200, 100, 0.2)";
11188
+ const COLOR_SEARCH_MATCHING = "#00aa78";
11189
+ const COLOR_AUTOFILL = "#444444";
11190
+ const HEADER_COLORS = {
11191
+ light: {
11192
+ selecting: "rgba(0, 0, 0, 0.1)",
11193
+ choosing: "rgba(0, 0, 0, 0.2)",
11194
+ thSelecting: "rgba(0, 0, 0, 0.55)"
11195
+ },
11196
+ dark: {
11197
+ selecting: "rgba(255, 255, 255, 0.08)",
11198
+ choosing: "rgba(255, 255, 255, 0.18)",
11199
+ thSelecting: "rgba(255, 255, 255, 0.4)"
11200
+ }
11201
+ };
11202
+ const fillRect = (ctx, x, y, width, height, color) => {
11203
+ ctx.fillStyle = color;
11204
+ ctx.fillRect(x, y, width, height);
11205
+ };
11206
+ const drawRect = (ctx, x, y, width, height, color, lineWidth = 2, dashPattern = [], fillColor) => {
11207
+ if (fillColor) {
11208
+ ctx.fillStyle = fillColor;
11209
+ ctx.fillRect(x, y, width, height);
11210
+ }
11211
+ ctx.strokeStyle = color;
11212
+ ctx.lineWidth = lineWidth;
11213
+ ctx.setLineDash(dashPattern);
11214
+ ctx.strokeRect(x + lineWidth / 2, y + lineWidth / 2, width - lineWidth, height - lineWidth);
11215
+ ctx.setLineDash([]);
11216
+ };
11217
+ const drawAreaRectViewport = (ctx, table, scrollTop, scrollLeft, viewW, viewH, area, color, lineWidth = 2, dashPattern = [], fillColor) => {
11218
+ const { top, left, bottom, right } = area;
11219
+ if (top === -1 || left === -1 || bottom === -1 || right === -1) {
11220
+ return;
11221
+ }
11222
+ const topLeft = getCellRectPositions(table, { y: top, x: left });
11223
+ const bottomRight = getCellRectPositions(table, { y: bottom, x: right });
11224
+ const x1 = topLeft.left - scrollLeft;
11225
+ const y1 = topLeft.top - scrollTop;
11226
+ const x2 = bottomRight.right - scrollLeft;
11227
+ const y2 = bottomRight.bottom - scrollTop;
11228
+ if (x2 < 0 || x1 > viewW || y2 < 0 || y1 > viewH) {
11229
+ return;
11230
+ }
11231
+ drawRect(ctx, x1, y1, x2 - x1, y2 - y1, color, lineWidth, dashPattern, fillColor);
11232
+ };
11233
+ const CellStateOverlay = ({ refs = {} }) => {
11234
+ const { store } = useContext(Context);
11235
+ const {
11236
+ tableReactive,
11237
+ tabularRef,
11238
+ choosing,
11239
+ selectingZone,
11240
+ matchingCells,
11241
+ matchingCellIndex,
11242
+ autofillDraggingTo,
11243
+ topHeaderSelecting,
11244
+ leftHeaderSelecting,
11245
+ mode,
11246
+ dragging
11247
+ } = store;
11248
+ const table = tableReactive.current;
11249
+ const canvasRef = useRef(null);
11250
+ const rafIdRef = useRef(0);
11251
+ const storeRef = useRef(store);
11252
+ storeRef.current = store;
11253
+ const drawCanvas = useCallback(() => {
11254
+ if (!table || !tabularRef.current || !canvasRef.current) {
11255
+ return;
11256
+ }
11257
+ const canvas = canvasRef.current;
11258
+ const ctx = canvas.getContext("2d");
11259
+ if (!ctx) {
11260
+ return;
11261
+ }
11262
+ const container = tabularRef.current;
11263
+ const dpr = window.devicePixelRatio || 1;
11264
+ const w = container.clientWidth;
11265
+ const h = container.clientHeight;
11266
+ if (canvas.width !== w * dpr || canvas.height !== h * dpr) {
11267
+ canvas.style.width = `${w}px`;
11268
+ canvas.style.height = `${h}px`;
11269
+ canvas.width = w * dpr;
11270
+ canvas.height = h * dpr;
11271
+ }
11272
+ ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
11273
+ ctx.clearRect(0, 0, w, h);
11274
+ const { wire } = table;
11275
+ const scrollTop = container.scrollTop;
11276
+ const scrollLeft = container.scrollLeft;
11277
+ const headerW = table.headerWidth;
11278
+ const headerH = table.headerHeight;
11279
+ ctx.save();
11280
+ ctx.beginPath();
11281
+ ctx.rect(headerW, headerH, w - headerW, h - headerH);
11282
+ ctx.clip();
11283
+ const selectingArea = zoneToArea(selectingZone);
11284
+ drawAreaRectViewport(ctx, table, scrollTop, scrollLeft, w, h, selectingArea, COLOR_SELECTED, 1, [], SELECTING_FILL);
11285
+ if (autofillDraggingTo) {
11286
+ const autofill = new Autofill(storeRef.current, autofillDraggingTo);
11287
+ drawAreaRectViewport(ctx, table, scrollTop, scrollLeft, w, h, autofill.wholeArea, COLOR_AUTOFILL, 1, [5, 5]);
11288
+ }
11289
+ {
11290
+ const { y, x } = choosing;
11291
+ if (y !== -1 && x !== -1) {
11292
+ const pos = getCellRectPositions(table, { y, x });
11293
+ const vx = pos.left - scrollLeft;
11294
+ const vy = pos.top - scrollTop;
11295
+ drawRect(ctx, vx, vy, pos.width, pos.height, COLOR_POINTED, 2, []);
11296
+ }
11297
+ }
11298
+ const { copyingSheetId, copyingZone, cutting } = wire;
11299
+ if (table.sheetId === copyingSheetId) {
11300
+ const copyingArea = zoneToArea(copyingZone);
11301
+ const color = cutting ? COLOR_CUTTING : COLOR_COPYING;
11302
+ const dashPattern = cutting ? [4, 4] : [6, 4];
11303
+ drawAreaRectViewport(ctx, table, scrollTop, scrollLeft, w, h, copyingArea, color, 2.5, dashPattern);
11304
+ }
11305
+ Object.entries(refs).forEach(([ref, i]) => {
11306
+ const palette = COLOR_PALETTE[i % COLOR_PALETTE.length];
11307
+ try {
11308
+ const refArea = table.rangeToArea(ref);
11309
+ drawAreaRectViewport(ctx, table, scrollTop, scrollLeft, w, h, refArea, palette, 2, [5, 5]);
11310
+ } catch (e) {
11311
+ }
11312
+ });
11313
+ matchingCells.forEach((address, index) => {
11314
+ const { y, x } = a2p(address);
11315
+ const pos = getCellRectPositions(table, { y, x });
11316
+ const vx = pos.left - scrollLeft;
11317
+ const vy = pos.top - scrollTop;
11318
+ if (vx + pos.width < 0 || vx > w || vy + pos.height < 0 || vy > h) {
11319
+ return;
11320
+ }
11321
+ const isCurrentMatch = index === matchingCellIndex;
11322
+ drawRect(
11323
+ ctx,
11324
+ vx,
11325
+ vy,
11326
+ pos.width,
11327
+ pos.height,
11328
+ isCurrentMatch ? COLOR_SEARCH_MATCHING : "transparent",
11329
+ isCurrentMatch ? 2 : 0,
11330
+ [],
11331
+ SEARCH_MATCHING_BACKGROUND
11332
+ );
11333
+ });
11334
+ ctx.restore();
11335
+ const headerColors = HEADER_COLORS[mode] || HEADER_COLORS.light;
11336
+ const numCols = table.getNumCols();
11337
+ const numRows = table.getNumRows();
11338
+ for (let x = 1; x <= numCols; x++) {
11339
+ let color = null;
11340
+ if (between({ start: selectingZone.startX, end: selectingZone.endX }, x)) {
11341
+ color = topHeaderSelecting ? headerColors.thSelecting : headerColors.selecting;
11342
+ }
11343
+ if (choosing.x === x) {
11344
+ color = headerColors.choosing;
11345
+ }
11346
+ if (!color) {
11347
+ continue;
11348
+ }
11349
+ const pos = getCellRectPositions(table, { y: 1, x });
11350
+ const left = pos.left - scrollLeft;
11351
+ if (left + pos.width < headerW || left > w) {
11352
+ continue;
11353
+ }
11354
+ fillRect(ctx, left, 0, pos.width, headerH, color);
11355
+ }
11356
+ for (let y = 1; y <= numRows; y++) {
11357
+ if (table.isRowFiltered(y)) {
11358
+ continue;
11359
+ }
11360
+ let color = null;
11361
+ if (between({ start: selectingZone.startY, end: selectingZone.endY }, y)) {
11362
+ color = leftHeaderSelecting ? headerColors.thSelecting : headerColors.selecting;
11363
+ }
11364
+ if (choosing.y === y) {
11365
+ color = headerColors.choosing;
11366
+ }
11367
+ if (!color) {
11368
+ continue;
11369
+ }
11370
+ const pos = getCellRectPositions(table, { y, x: 1 });
11371
+ const top = pos.top - scrollTop;
11372
+ if (top + pos.height < headerH || top > h) {
11373
+ continue;
11374
+ }
11375
+ fillRect(ctx, 0, top, headerW, pos.height, color);
11376
+ }
11377
+ }, [
11378
+ table,
11379
+ tabularRef,
11380
+ choosing,
11381
+ selectingZone,
11382
+ matchingCells,
11383
+ matchingCellIndex,
11384
+ autofillDraggingTo,
11385
+ topHeaderSelecting,
11386
+ leftHeaderSelecting,
11387
+ mode,
11388
+ dragging,
11389
+ refs
11390
+ ]);
11391
+ const scheduleDrawCanvas = useCallback(() => {
11392
+ cancelAnimationFrame(rafIdRef.current);
11393
+ rafIdRef.current = requestAnimationFrame(drawCanvas);
11394
+ }, [drawCanvas]);
11395
+ const handleScroll = useCallback(() => {
11396
+ drawCanvas();
11397
+ }, [drawCanvas]);
11398
+ useEffect(() => {
11399
+ scheduleDrawCanvas();
11400
+ return () => cancelAnimationFrame(rafIdRef.current);
11401
+ }, [scheduleDrawCanvas]);
11402
+ useEffect(() => {
11403
+ const container = tabularRef.current;
11404
+ if (!container) {
11405
+ return;
11406
+ }
11407
+ container.addEventListener("scroll", handleScroll);
11408
+ return () => {
11409
+ container.removeEventListener("scroll", handleScroll);
11410
+ };
11411
+ }, [tabularRef, handleScroll]);
11412
+ return /* @__PURE__ */ jsx(
11413
+ "div",
11414
+ {
11415
+ style: {
11416
+ position: "sticky",
11417
+ top: 0,
11418
+ left: 0,
11419
+ width: 0,
11420
+ height: 0,
11421
+ overflow: "visible",
11422
+ pointerEvents: "none",
11423
+ zIndex: 10
11424
+ },
11425
+ children: /* @__PURE__ */ jsx(
11426
+ "canvas",
11427
+ {
11428
+ ref: canvasRef,
11429
+ className: "gs-cell-state-overlay",
11430
+ style: {
11431
+ pointerEvents: "none",
11432
+ display: "block"
11433
+ }
11434
+ }
11435
+ )
11436
+ }
11437
+ );
11438
+ };
10079
11439
  const Tabular = () => {
10080
11440
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
10081
11441
  const [palette, setPalette] = useState({});
@@ -10176,13 +11536,13 @@ const Tabular = () => {
10176
11536
  }
10177
11537
  setVirtualized(virtualize(table, tabularRef.current));
10178
11538
  }, [tabularRef.current, tableReactive, (_a = mainRef.current) == null ? void 0 : _a.clientHeight, (_b = mainRef.current) == null ? void 0 : _b.clientWidth]);
11539
+ const mergedRefs = {
11540
+ ...palette,
11541
+ ...table ? table.wire.paletteBySheetName[table.sheetName] : {}
11542
+ };
10179
11543
  if (!table || !table.wire.ready) {
10180
11544
  return null;
10181
11545
  }
10182
- const operationStyles = useOperationStyles(store, {
10183
- ...palette,
10184
- ...table.wire.paletteBySheetName[table.sheetName]
10185
- });
10186
11546
  return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
10187
11547
  "div",
10188
11548
  {
@@ -10194,7 +11554,7 @@ const Tabular = () => {
10194
11554
  ref: tabularRef,
10195
11555
  onMouseMove: handleMouseMove,
10196
11556
  onScroll: handleScroll,
10197
- children: /* @__PURE__ */ jsx(
11557
+ children: /* @__PURE__ */ jsxs(
10198
11558
  "div",
10199
11559
  {
10200
11560
  className: "gs-tabular-inner",
@@ -10202,204 +11562,73 @@ const Tabular = () => {
10202
11562
  width: table.totalWidth + 1,
10203
11563
  height: table.totalHeight + 1
10204
11564
  },
10205
- children: /* @__PURE__ */ jsxs("table", { className: `gs-table`, children: [
10206
- /* @__PURE__ */ jsx("thead", { className: "gs-thead", style: { height: table.headerHeight }, children: /* @__PURE__ */ jsxs("tr", { className: "gs-row", children: [
10207
- /* @__PURE__ */ jsx(
10208
- "th",
10209
- {
10210
- className: "gs-th gs-th-left gs-th-top",
10211
- style: { position: "sticky", width: table.headerWidth, height: table.headerHeight },
10212
- onClick: handleSelectAllClick,
10213
- children: /* @__PURE__ */ jsx("div", { className: "gs-th-inner", children: /* @__PURE__ */ jsx(
10214
- ScrollHandle,
10215
- {
10216
- className: leftHeaderSelecting || topHeaderSelecting ? "gs-hidden" : "",
10217
- style: { position: "absolute" },
10218
- horizontal: leftHeaderSelecting ? 0 : -1,
10219
- vertical: topHeaderSelecting ? 0 : -1
10220
- }
10221
- ) })
10222
- }
10223
- ),
10224
- /* @__PURE__ */ jsx(
10225
- "th",
10226
- {
10227
- className: "gs-adjuster gs-adjuster-horizontal gs-adjuster-horizontal-left",
10228
- style: { width: ((_c = virtualized == null ? void 0 : virtualized.adjuster) == null ? void 0 : _c.left) ?? 1 }
10229
- }
10230
- ),
10231
- (_e = (_d = virtualized == null ? void 0 : virtualized.xs) == null ? void 0 : _d.map) == null ? void 0 : _e.call(_d, (x) => /* @__PURE__ */ jsx(HeaderCellTop, { x }, x)),
10232
- /* @__PURE__ */ jsx(
10233
- "th",
10234
- {
10235
- className: "gs-adjuster gs-adjuster-horizontal gs-adjuster-horizontal-right",
10236
- style: { width: (_f = virtualized == null ? void 0 : virtualized.adjuster) == null ? void 0 : _f.right }
10237
- }
10238
- )
10239
- ] }) }),
10240
- /* @__PURE__ */ jsx("tbody", { className: "gs-table-body-adjuster", children: /* @__PURE__ */ jsxs("tr", { className: "gs-row", children: [
10241
- /* @__PURE__ */ jsx(
10242
- "th",
10243
- {
10244
- className: `gs-adjuster gs-adjuster-horizontal gs-adjuster-vertical`,
10245
- style: { height: ((_g = virtualized == null ? void 0 : virtualized.adjuster) == null ? void 0 : _g.top) ?? 1 }
10246
- }
10247
- ),
10248
- /* @__PURE__ */ jsx("td", { className: "gs-adjuster gs-adjuster-vertical" }),
10249
- (_h = virtualized == null ? void 0 : virtualized.xs) == null ? void 0 : _h.map((x) => /* @__PURE__ */ jsx("td", { className: "gs-adjuster gs-adjuster-vertical" }, x)),
10250
- /* @__PURE__ */ jsx("th", { className: `gs-adjuster gs-adjuster-horizontal gs-adjuster-vertical` })
10251
- ] }) }),
10252
- /* @__PURE__ */ jsx("tbody", { className: "gs-table-body-data", children: (_i = virtualized == null ? void 0 : virtualized.ys) == null ? void 0 : _i.map((y) => {
10253
- var _a2;
10254
- return /* @__PURE__ */ jsxs("tr", { className: "gs-row", children: [
10255
- /* @__PURE__ */ jsx(HeaderCellLeft, { y }),
10256
- /* @__PURE__ */ jsx("td", { className: "gs-adjuster gs-adjuster-horizontal gs-adjuster-horizontal-left" }),
10257
- (_a2 = virtualized == null ? void 0 : virtualized.xs) == null ? void 0 : _a2.map((x) => /* @__PURE__ */ jsx(Cell, { y, x, operationStyle: operationStyles[p2a({ y, x })] }, x)),
10258
- /* @__PURE__ */ jsx("td", { className: "gs-adjuster gs-adjuster-horizontal gs-adjuster-horizontal-right" })
10259
- ] }, y);
10260
- }) })
10261
- ] })
11565
+ children: [
11566
+ /* @__PURE__ */ jsx(CellStateOverlay, { refs: mergedRefs }),
11567
+ /* @__PURE__ */ jsxs("table", { className: `gs-table`, children: [
11568
+ /* @__PURE__ */ jsx("thead", { className: "gs-thead", style: { height: table.headerHeight }, children: /* @__PURE__ */ jsxs("tr", { className: "gs-row", children: [
11569
+ /* @__PURE__ */ jsx(
11570
+ "th",
11571
+ {
11572
+ className: "gs-th gs-th-left gs-th-top",
11573
+ style: { position: "sticky", width: table.headerWidth, height: table.headerHeight },
11574
+ onClick: handleSelectAllClick,
11575
+ children: /* @__PURE__ */ jsx("div", { className: "gs-th-inner", children: /* @__PURE__ */ jsx(
11576
+ ScrollHandle,
11577
+ {
11578
+ className: leftHeaderSelecting || topHeaderSelecting ? "gs-hidden" : "",
11579
+ style: { position: "absolute" },
11580
+ horizontal: leftHeaderSelecting ? 0 : -1,
11581
+ vertical: topHeaderSelecting ? 0 : -1
11582
+ }
11583
+ ) })
11584
+ }
11585
+ ),
11586
+ /* @__PURE__ */ jsx(
11587
+ "th",
11588
+ {
11589
+ className: "gs-adjuster gs-adjuster-horizontal gs-adjuster-horizontal-left",
11590
+ style: { width: ((_c = virtualized == null ? void 0 : virtualized.adjuster) == null ? void 0 : _c.left) ?? 1 }
11591
+ }
11592
+ ),
11593
+ (_e = (_d = virtualized == null ? void 0 : virtualized.xs) == null ? void 0 : _d.map) == null ? void 0 : _e.call(_d, (x) => /* @__PURE__ */ jsx(HeaderCellTop, { x }, x)),
11594
+ /* @__PURE__ */ jsx(
11595
+ "th",
11596
+ {
11597
+ className: "gs-adjuster gs-adjuster-horizontal gs-adjuster-horizontal-right",
11598
+ style: { width: (_f = virtualized == null ? void 0 : virtualized.adjuster) == null ? void 0 : _f.right }
11599
+ }
11600
+ )
11601
+ ] }) }),
11602
+ /* @__PURE__ */ jsx("tbody", { className: "gs-table-body-adjuster", children: /* @__PURE__ */ jsxs("tr", { className: "gs-row", children: [
11603
+ /* @__PURE__ */ jsx(
11604
+ "th",
11605
+ {
11606
+ className: `gs-adjuster gs-adjuster-horizontal gs-adjuster-vertical`,
11607
+ style: { height: ((_g = virtualized == null ? void 0 : virtualized.adjuster) == null ? void 0 : _g.top) ?? 1 }
11608
+ }
11609
+ ),
11610
+ /* @__PURE__ */ jsx("td", { className: "gs-adjuster gs-adjuster-vertical" }),
11611
+ (_h = virtualized == null ? void 0 : virtualized.xs) == null ? void 0 : _h.map((x) => /* @__PURE__ */ jsx("td", { className: "gs-adjuster gs-adjuster-vertical" }, x)),
11612
+ /* @__PURE__ */ jsx("th", { className: `gs-adjuster gs-adjuster-horizontal gs-adjuster-vertical` })
11613
+ ] }) }),
11614
+ /* @__PURE__ */ jsx("tbody", { className: "gs-table-body-data", children: (_i = virtualized == null ? void 0 : virtualized.ys) == null ? void 0 : _i.map((y) => {
11615
+ var _a2;
11616
+ return /* @__PURE__ */ jsxs("tr", { className: "gs-row", children: [
11617
+ /* @__PURE__ */ jsx(HeaderCellLeft, { y }),
11618
+ /* @__PURE__ */ jsx("td", { className: "gs-adjuster gs-adjuster-horizontal gs-adjuster-horizontal-left" }),
11619
+ (_a2 = virtualized == null ? void 0 : virtualized.xs) == null ? void 0 : _a2.map((x) => /* @__PURE__ */ jsx(Cell, { y, x }, x)),
11620
+ /* @__PURE__ */ jsx("td", { className: "gs-adjuster gs-adjuster-horizontal gs-adjuster-horizontal-right" })
11621
+ ] }, y);
11622
+ }) })
11623
+ ] })
11624
+ ]
10262
11625
  }
10263
11626
  )
10264
11627
  }
10265
11628
  ) });
10266
11629
  };
10267
- const BORDER_POINTED = "solid 2px #0077ff";
10268
- const BORDER_SELECTED = "solid 1px #0077ff";
10269
- const BORDER_CUTTING = "dotted 2px #0077ff";
10270
- const BORDER_COPYING = "dashed 2px #0077ff";
10271
- const SEARCH_MATCHING_BACKGROUND = "rgba(0,200,100,.2)";
10272
- const SEARCH_MATCHING_BORDER = "solid 2px #00aa78";
10273
- const AUTOFILL_BORDER = "dashed 1px #444444";
10274
- const useOperationStyles = (store, refs) => {
10275
- const cellStyles = {};
10276
- const updateStyle = (point, style) => {
10277
- const address = p2a(point);
10278
- cellStyles[address] = cellStyles[address] || {};
10279
- Object.assign(cellStyles[address], style);
10280
- };
10281
- const {
10282
- choosing,
10283
- selectingZone,
10284
- matchingCells,
10285
- matchingCellIndex,
10286
- tableReactive,
10287
- autofillDraggingTo,
10288
- editingAddress
10289
- } = store;
10290
- const table = tableReactive.current;
10291
- if (!table) {
10292
- return {};
10293
- }
10294
- const { wire } = table;
10295
- const { copyingSheetId, copyingZone, cutting } = wire;
10296
- const editingAnywhere = !!(wire.editingAddress || editingAddress);
10297
- {
10298
- const { top, left, bottom, right } = zoneToArea(selectingZone);
10299
- if (!editingAnywhere) {
10300
- for (let y = top; y <= bottom; y++) {
10301
- updateStyle({ y, x: left - 1 }, { borderRight: BORDER_SELECTED });
10302
- updateStyle({ y, x: left }, { borderLeft: BORDER_SELECTED });
10303
- updateStyle({ y, x: right }, { borderRight: BORDER_SELECTED });
10304
- updateStyle({ y, x: right + 1 }, { borderLeft: BORDER_SELECTED });
10305
- }
10306
- for (let x = left; x <= right; x++) {
10307
- updateStyle({ y: top - 1, x }, { borderBottom: BORDER_SELECTED });
10308
- updateStyle({ y: top, x }, { borderTop: BORDER_SELECTED });
10309
- updateStyle({ y: bottom, x }, { borderBottom: BORDER_SELECTED });
10310
- updateStyle({ y: bottom + 1, x }, { borderTop: BORDER_SELECTED });
10311
- }
10312
- }
10313
- }
10314
- if (autofillDraggingTo) {
10315
- const autofill = new Autofill(store, autofillDraggingTo);
10316
- const { top, left, bottom, right } = autofill.wholeArea;
10317
- for (let y = top; y <= bottom; y++) {
10318
- updateStyle({ y, x: left - 1 }, { borderRight: AUTOFILL_BORDER });
10319
- updateStyle({ y, x: left }, { borderLeft: AUTOFILL_BORDER });
10320
- updateStyle({ y, x: right }, { borderRight: AUTOFILL_BORDER });
10321
- updateStyle({ y, x: right + 1 }, { borderLeft: AUTOFILL_BORDER });
10322
- }
10323
- for (let x = left; x <= right; x++) {
10324
- updateStyle({ y: top - 1, x }, { borderBottom: AUTOFILL_BORDER });
10325
- updateStyle({ y: top, x }, { borderTop: AUTOFILL_BORDER });
10326
- updateStyle({ y: bottom, x }, { borderBottom: AUTOFILL_BORDER });
10327
- updateStyle({ y: bottom + 1, x }, { borderTop: AUTOFILL_BORDER });
10328
- }
10329
- }
10330
- {
10331
- const { y, x } = choosing;
10332
- updateStyle(
10333
- { y, x },
10334
- {
10335
- borderLeft: BORDER_POINTED,
10336
- borderRight: BORDER_POINTED,
10337
- borderTop: BORDER_POINTED,
10338
- borderBottom: BORDER_POINTED
10339
- }
10340
- );
10341
- updateStyle({ y, x: x - 1 }, { borderRight: BORDER_POINTED });
10342
- updateStyle({ y, x: x + 1 }, { borderLeft: BORDER_POINTED });
10343
- updateStyle({ y: y - 1, x }, { borderBottom: BORDER_POINTED });
10344
- updateStyle({ y: y + 1, x }, { borderTop: BORDER_POINTED });
10345
- }
10346
- if (table.sheetId === copyingSheetId) {
10347
- const borderStyle = cutting ? BORDER_CUTTING : BORDER_COPYING;
10348
- const { top, left, bottom, right } = zoneToArea(copyingZone);
10349
- for (let y = top; y <= bottom; y++) {
10350
- updateStyle({ y, x: left - 1 }, { borderRight: borderStyle });
10351
- updateStyle({ y, x: left }, { borderLeft: borderStyle });
10352
- updateStyle({ y, x: right }, { borderRight: borderStyle });
10353
- updateStyle({ y, x: right + 1 }, { borderLeft: borderStyle });
10354
- }
10355
- for (let x = left; x <= right; x++) {
10356
- updateStyle({ y: top - 1, x }, { borderBottom: borderStyle });
10357
- updateStyle({ y: top, x }, { borderTop: borderStyle });
10358
- updateStyle({ y: bottom, x }, { borderBottom: borderStyle });
10359
- updateStyle({ y: bottom + 1, x }, { borderTop: borderStyle });
10360
- }
10361
- }
10362
- Object.entries(refs).forEach(([ref, i]) => {
10363
- const palette = COLOR_PALETTE[i % COLOR_PALETTE.length];
10364
- const borderStyle = `dashed 2px ${palette}`;
10365
- const { top, left, bottom, right } = table.rangeToArea(ref);
10366
- for (let y = top; y <= bottom; y++) {
10367
- updateStyle({ y, x: left - 1 }, { borderRight: borderStyle });
10368
- updateStyle({ y, x: left }, { borderLeft: borderStyle });
10369
- updateStyle({ y, x: right }, { borderRight: borderStyle });
10370
- updateStyle({ y, x: right + 1 }, { borderLeft: borderStyle });
10371
- }
10372
- for (let x = left; x <= right; x++) {
10373
- updateStyle({ y: top - 1, x }, { borderBottom: borderStyle });
10374
- updateStyle({ y: top, x }, { borderTop: borderStyle });
10375
- updateStyle({ y: bottom, x }, { borderBottom: borderStyle });
10376
- updateStyle({ y: bottom + 1, x }, { borderTop: borderStyle });
10377
- }
10378
- });
10379
- matchingCells.forEach((address) => {
10380
- const { y, x } = a2p(address);
10381
- updateStyle({ y, x }, { backgroundColor: SEARCH_MATCHING_BACKGROUND });
10382
- });
10383
- if (matchingCells.length > 0) {
10384
- const { y, x } = a2p(matchingCells[matchingCellIndex]);
10385
- updateStyle(
10386
- { y, x },
10387
- {
10388
- borderLeft: SEARCH_MATCHING_BORDER,
10389
- borderRight: SEARCH_MATCHING_BORDER,
10390
- borderTop: SEARCH_MATCHING_BORDER,
10391
- borderBottom: SEARCH_MATCHING_BORDER
10392
- }
10393
- );
10394
- updateStyle({ y, x: x - 1 }, { borderRight: SEARCH_MATCHING_BORDER });
10395
- updateStyle({ y, x: x + 1 }, { borderLeft: SEARCH_MATCHING_BORDER });
10396
- updateStyle({ y: y - 1, x }, { borderBottom: SEARCH_MATCHING_BORDER });
10397
- updateStyle({ y: y + 1, x }, { borderTop: SEARCH_MATCHING_BORDER });
10398
- }
10399
- return cellStyles;
10400
- };
10401
- const LAST_MODIFIED = 1753483021;
10402
- 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{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:#f7f7f7}.gs-root1[data-mode=light] .gs-th{background-color:#efefef;color:#666}.gs-root1[data-mode=light] .gs-th.gs-selecting{background-color:#d2d2d2}.gs-root1[data-mode=light] .gs-th.gs-choosing{background-color:#bbb}.gs-root1[data-mode=light] .gs-th.gs-th-selecting{background-color:#555;color:#fff}.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{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:#212121}.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.gs-selecting{background-color:#606060}.gs-root1[data-mode=dark] .gs-th.gs-choosing{background-color:#777}.gs-root1[data-mode=dark] .gs-th.gs-th-selecting{background-color:#aaa;color:#444}.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-cell-inner-wrap.gs-selecting{background-color:rgba(0,128,255,.2)}.gs-cell.gs-copying textarea:focus{outline:solid 1px #0077ff}.gs-cell.gs-selecting{z-index:1}.gs-cell.gs-selecting .gs-cell-inner{background-color:rgba(0,128,255,.2)}.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,.2);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:3}.gs-contextmenu{z-index:3;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{min-width:250px;color:#555;margin:0;padding:0}.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-divider{background-color:#aaa;margin:10px 0;padding:0;height:1px}.gs-contextmenu li .gs-menu-name{flex:1;font-size:15px;letter-spacing:1px}.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-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:3;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-x:contain}.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)}}`;
11630
+ const LAST_MODIFIED = 1771145572;
11631
+ const CSS = `.gs-root1{display:inline-block;position:relative;border-spacing:0;width:fit-content;max-width:100%;overflow:auto;font-family:"SF Pro Text","SF Pro Icons","Helvetica Neue",Helvetica,Arial,Meiryo,sans-serif;visibility:hidden;opacity:0}.gs-root1.gs-initialized{visibility:visible;opacity:1;transition:opacity .2s ease-in-out}.gs-root1 .gs-main{flex:1;max-width:100%;overflow:hidden;position:relative;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box}.gs-root1 .gs-resizing{width:100%;height:100%;position:absolute;background-color:rgba(0,127,255,.08);top:0;left:0;z-index:2}.gs-root1 .gs-line-horizontal{width:100%}.gs-root1 .gs-line-vertical{height:100%}.gs-root1 .gs-line{position:relative;top:0;left:0;border:dotted 1px #07f;box-sizing:border-box}.gs-root1 .gs-line span{font-size:10px;padding:3px;background-color:#07f;color:#fff;margin:0;position:absolute;top:0;left:0}.gs-root1 .gs-scroll-handle{width:100%;height:100%;cursor:cell}.gs-hidden{visibility:hidden;position:absolute;top:0;left:0;width:0;height:0;overflow:hidden;pointer-events:none;z-index:-1}.gs-fixed{position:fixed;top:0;left:0;z-index:1}.gs-root1[data-mode=light]{background-color:#e2e2e2;color:#000}.gs-root1[data-mode=light] .gs-main{background-color:#e2e2e2;border-right:solid 1px #ddd;border-bottom:solid 1px #ddd}.gs-root1[data-mode=light] .gs-tabular{background-color:#e2e2e2}.gs-root1[data-mode=light] .gs-formula-bar{background-color:#efefef}.gs-root1[data-mode=light] .gs-formula-bar-editor-inner{color:#555}.gs-root1[data-mode=light] .gs-cell{background-color:#f7f7f7;border-top:solid 1px #ddd;border-left:solid 1px #ddd}.gs-root1[data-mode=light] .gs-adjuster{background-color:#ddd}.gs-root1[data-mode=light] .gs-tabular-inner{background-color:#ddd}.gs-root1[data-mode=light] .gs-th{background-color:#efefef;color:#666}.gs-root1[data-mode=light] .gs-th-top{border-left:solid 1px #ddd}.gs-root1[data-mode=light] .gs-th-top .gs-th-inner{border-top:solid 1px #ddd}.gs-root1[data-mode=light] .gs-th-left{border-top:solid 1px #ddd}.gs-root1[data-mode=light] .gs-th-left .gs-th-inner{border-left:solid 1px #ddd}.gs-root1[data-mode=light] .gs-search-bar{color:rgba(0,0,0,.3)}.gs-editor[data-mode=light].gs-editing textarea{caret-color:#000000}.gs-editor[data-mode=light].gs-editing .gs-editor-hl{background-color:#f7f7f7;color:#000}.gs-editor[data-mode=light] .gs-editor-options{color:#000;background-color:#f7f7f7;border:solid 1px #ddd}.gs-root1[data-mode=dark]{background-color:#5a5a5a;color:#eee}.gs-root1[data-mode=dark] .gs-main{background-color:#3f3f3f;border-right:solid 1px #5a5a5a;border-bottom:solid 1px #5a5a5a}.gs-root1[data-mode=dark] .gs-tabular{background-color:#3f3f3f}.gs-root1[data-mode=dark] .gs-formula-bar{background-color:#4f4f4f}.gs-root1[data-mode=dark] .gs-formula-bar-editor-inner{color:#bbb}.gs-root1[data-mode=dark] .gs-cell{background-color:#212121;border-top:solid 1px #5a5a5a;border-left:solid 1px #5a5a5a}.gs-root1[data-mode=dark] .gs-adjuster{background-color:#5a5a5a}.gs-root1[data-mode=dark] .gs-tabular-inner{background-color:#5a5a5a}.gs-root1[data-mode=dark] .gs-large-editor textarea{color:#eee;caret-color:#eeeeee}.gs-root1[data-mode=dark] .gs-th{background-color:#4f4f4f;color:#eee}.gs-root1[data-mode=dark] .gs-th-top{border-left:solid 1px #5a5a5a}.gs-root1[data-mode=dark] .gs-th-top .gs-th-inner{border-top:solid 1px #5a5a5a}.gs-root1[data-mode=dark] .gs-th-left{border-top:solid 1px #5a5a5a}.gs-root1[data-mode=dark] .gs-th-left .gs-th-inner{border-left:solid 1px #5a5a5a}.gs-root1[data-mode=dark] .gs-search-bar textarea{color:#eee;caret-color:#eeeeee}.gs-root1[data-mode=dark] .gs-search-bar{color:rgba(255,255,255,.3)}.gs-editor[data-mode=dark].gs-editing textarea{caret-color:#eeeeee}.gs-editor[data-mode=dark].gs-editing .gs-editor-hl{background-color:#212121;color:#eee}.gs-editor[data-mode=dark] .gs-editor-options{color:#eee;background-color:#5a5a5a;border:solid 1px #5a5a5a}.gs-cell{transition:border-color .2s ease;padding:0;margin:0;box-sizing:border-box;position:relative;font-size:13px;letter-spacing:1px;line-height:24px;cursor:cell;user-select:none;-webkit-user-select:none;-moz-user-select:none}.gs-cell.gs-copying textarea:focus{outline:solid 1px #0077ff}.gs-cell.gs-selecting{z-index:1}.gs-cell.gs-selecting .gs-cell-label{display:block}.gs-cell.gs-choosing{margin-top:-1px;margin-left:-1px;z-index:1}.gs-cell.gs-choosing.gs-editing{color:transparent}.gs-cell.gs-choosing .gs-cell-label{display:block}.gs-cell .gs-formula-error-triangle{position:absolute;top:0;right:0;border-top:3px solid rgba(200,0,0,.9);border-right:3px solid rgba(200,0,0,.9);border-bottom:3px solid transparent;border-left:3px solid transparent;z-index:1}.gs-cell .gs-cell-label{font-size:8px;font-weight:400;font-style:normal;font-family:math,monospace,serif;letter-spacing:1px;line-height:14px;position:absolute;top:0;right:0;background-color:rgba(0,128,255,.6);color:rgba(255,255,255,.6);padding:0 2px;display:none;opacity:.7}.gs-cell .gs-cell-inner-wrap{width:100%;height:100%;position:absolute;top:0;left:0}.gs-cell .gs-cell-inner{width:100%;height:100%;overflow:hidden;display:flex;box-sizing:border-box;border:none!important}.gs-cell .gs-cell-rendered{overflow:hidden;white-space:pre-wrap;cursor:cell;word-wrap:break-word;word-break:break-all;padding:0 2px;width:100%;height:100%}.gs-cell .gs-cell-rendered>*{position:relative}.gs-cell .gs-cell-rendered>.backface{z-index:0}.gs-cell .gs-autofill-drag{background-color:#07f;position:absolute;width:7px;height:7px;bottom:0;right:0;margin-right:-3.5px;margin-bottom:-3.5px;cursor:crosshair;z-index:1}.gs-th[data-x="1"] .gs-th-inner-wrap{border-left:none}.gs-th[data-y="1"] .gs-th-inner-wrap{border-top:none}.gs-cell[data-x="1"]{border-left:none}.gs-cell[data-y="1"]{border-top:none}.gs-contextmenu-modal{width:100%;height:100vh;z-index:12}.gs-contextmenu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px}.gs-contextmenu ul{color:#555;margin:0;padding:0;min-width:250px}.gs-contextmenu li{padding:5px 10px;list-style-type:none;display:flex}.gs-contextmenu li.gs-enabled{cursor:pointer}.gs-contextmenu li.gs-enabled:hover{background-color:#eee}.gs-contextmenu li.gs-disabled{opacity:.5;cursor:not-allowed}.gs-contextmenu li .gs-menu-name{font-size:13px;letter-spacing:1px}.gs-contextmenu li.gs-menu-divider{background-color:#aaa;padding:0;height:1px;margin:10px 0}.gs-contextmenu li .gs-menu-name{flex:1}.gs-contextmenu li .gs-menu-shortcut{font-size:10px;line-height:20px;color:#999}.gs-contextmenu li .gs-menu-shortcut:before{content:"( "}.gs-contextmenu li .gs-menu-shortcut:after{content:" )"}.gs-contextmenu li .gs-menu-shortcut .gs-menu-underline{text-decoration:underline}.gs-column-menu-modal{width:100%;height:100vh;z-index:12}.gs-column-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px}.gs-column-menu ul{color:#555;margin:0;padding:0;min-width:200px}.gs-column-menu li{padding:5px 10px;list-style-type:none}.gs-column-menu li.gs-enabled{cursor:pointer}.gs-column-menu li.gs-enabled:hover{background-color:#eee}.gs-column-menu li.gs-disabled{opacity:.5;cursor:not-allowed}.gs-column-menu li .gs-menu-name{font-size:13px;letter-spacing:1px}.gs-column-menu li.gs-menu-divider{background-color:#aaa;padding:0;height:1px;margin:5px 0}.gs-column-menu .gs-column-menu-label{padding:5px 10px}.gs-column-menu .gs-label-input-row{display:flex;gap:4px;align-items:center}.gs-column-menu .gs-label-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;background-color:transparent;box-shadow:none}.gs-column-menu .gs-label-input:focus{border-bottom-color:#07f;outline:0;box-shadow:none}.gs-column-menu .gs-label-apply-btn{font-size:12px;padding:3px 13px;border:1px solid transparent;border-radius:3px;background-color:transparent;color:#1a8a1a;cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-label-apply-btn:hover{border-color:#1a8a1a}.gs-column-menu .gs-column-menu-filter{padding:5px 10px}.gs-column-menu .gs-filter-header{display:flex;align-items:center;gap:8px}.gs-column-menu .gs-filter-header .gs-filter-add-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#555;letter-spacing:1px}.gs-column-menu .gs-filter-header .gs-filter-add-btn:hover{border-color:#555}.gs-column-menu .gs-filter-mode-toggle{display:flex;gap:6px;margin-left:auto}.gs-column-menu .gs-filter-mode-toggle label{display:flex;align-items:center;gap:3px;font-size:11px;font-weight:700;letter-spacing:.5px;color:#888;cursor:pointer;user-select:none}.gs-column-menu .gs-filter-mode-toggle label input[type=radio]{margin:0;cursor:pointer}.gs-column-menu .gs-filter-mode-toggle label.gs-active{color:#07f}.gs-column-menu .gs-filter-mode-toggle.gs-disabled{opacity:.4;pointer-events:none}.gs-column-menu .gs-filter-conditions{display:flex;flex-direction:column;gap:5px;margin-top:6px;max-height:200px;overflow-y:auto}.gs-column-menu .gs-filter-condition-row{display:flex;gap:4px;align-items:normal}.gs-column-menu .gs-filter-method-select{font-size:12px;padding:4px 4px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;background-color:#fff;box-shadow:none;min-width:40px;max-width:80px;cursor:pointer}.gs-column-menu .gs-filter-method-select:focus{border-bottom-color:#07f;outline:0;box-shadow:none}.gs-column-menu .gs-filter-value-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;width:80px;background-color:transparent;box-shadow:none}.gs-column-menu .gs-filter-value-input:focus{border-bottom-color:#07f;outline:0;box-shadow:none}.gs-column-menu .gs-filter-remove-btn{font-size:12px;padding:0;border:none;border-radius:3px;background-color:transparent;cursor:pointer;color:#999;line-height:1;flex-shrink:0}.gs-column-menu .gs-filter-remove-btn:hover{color:#c33}.gs-column-menu .gs-filter-actions{display:flex;gap:4px;margin-top:10px;align-items:center}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#c33;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn:hover{border-color:#c33}.gs-column-menu .gs-filter-actions .gs-filter-actions-right{display:flex;gap:4px;margin-left:auto}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#e08000;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn:hover{border-color:#e08000}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn{font-size:12px;padding:3px 13px;border:1px solid transparent;border-radius:3px;background-color:transparent;color:#07f;cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn:hover{border-color:#07f}.gs-column-menu-btn{position:absolute;right:4px;top:50%;transform:translateY(-50%);background-color:rgba(128,128,128,.3);border:1px solid #ccc;border-radius:50%;cursor:pointer;font-size:12px;font-weight:700;line-height:1;color:#888;width:18px;height:18px;padding:0;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s ease;z-index:2}.gs-column-menu-btn.gs-filtered{opacity:1;background-color:#e0edff;border-color:#07f;color:#07f}.gs-column-menu-btn.gs-active{opacity:1;background-color:#d0e0ff;border-color:#07f;color:#07f}.gs-th-top:hover .gs-column-menu-btn{opacity:1}.gs-editor-hl{padding:0 2px!important;position:absolute;font-family:monospace,Arial;font-size:12px;line-height:24px;letter-spacing:1px}.gs-formula-bar-editor-inner{position:relative;display:table-cell}.gs-editor{opacity:0;z-index:-1}.gs-editor .gs-editor-inner{position:relative}.gs-editor .gs-editor-hl{box-sizing:content-box;border:solid 2px #07f;margin:-2px -1px}.gs-editor textarea{width:100%;padding:0 2px!important;position:absolute;font-size:12px;font-family:monospace,Arial;line-height:24px;letter-spacing:1px;top:0;left:0;border:none;outline:0;background-color:transparent;color:transparent;resize:none;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;overflow:hidden;cursor:default;white-space:pre;height:auto}.gs-editor.gs-editing{z-index:11;opacity:1}.gs-editor.gs-editing .gs-cell-label{pointer-events:none;font-family:math,monospace,serif;position:absolute;top:0;right:0;margin-top:-15px;margin-right:-2px;padding:0 2px;font-size:10px;background-color:rgba(0,119,255,.75);color:#fff;z-index:1}.gs-formula-bar{width:100%;position:relative;display:table;align-items:center;justify-content:center;border-top:solid 1px rgba(128,128,128,.3);border-left:solid 1px rgba(128,128,128,.3);border-right:solid 1px rgba(128,128,128,.3);box-sizing:border-box}.gs-formula-bar .gs-selecting-address{display:table-cell;vertical-align:middle;width:60px;color:rgba(200,200,200);font-size:13px;text-align:center}.gs-formula-bar .gs-fx{display:table-cell;vertical-align:middle;width:30px;color:rgba(200,200,200);font-style:italic;font-family:cursive;text-align:center;border-left:solid 1px rgba(128,128,128,.5);font-size:15px}.gs-formula-bar .gs-editor-hl{z-index:0;overflow-y:auto;box-sizing:border-box;white-space:pre-wrap;word-break:break-all}.gs-formula-bar textarea{position:relative;z-index:1;width:100%;vertical-align:bottom;color:transparent;border:none;background-color:transparent;padding:0 2px;box-sizing:border-box;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;resize:vertical;caret-color:rgba(128,128,128);white-space:pre-wrap;word-break:break-all}.gs-token-type-INVALID_REF{color:red}.gs-token-type-VALUE.gs-token-entity-type-boolean,.gs-token-type-VALUE.gs-token-entity-type-number{color:#39f}.gs-token-type-VALUE.gs-token-entity-type-string{color:#090}.gs-editor-options{padding:0;box-shadow:0 2px 8px rgba(0,0,0,.25);border:1px solid rgba(128,128,128,.2);border-radius:4px}.gs-editor-option{cursor:pointer;list-style:none;padding:5px;font-size:12px}.gs-editor-option:hover{background-color:rgba(128,128,128,.1)}.gs-editor-option-selected{background-color:rgba(128,128,128,.2)}.gs-adjuster{padding:0}.gs-table{margin:0}.gs-tabular{overflow:auto;display:block;box-sizing:border-box;overscroll-behavior:none;position:relative}.gs-tabular-inner>table{table-layout:fixed;border-collapse:collapse;border-spacing:0}.gs-th{z-index:2;padding:0;position:sticky;font-size:13px;font-weight:400;box-sizing:border-box;vertical-align:top}.gs-th .gs-resizer{position:absolute;border-color:transparent;box-sizing:border-box;z-index:2}.gs-th .gs-resizer:hover{background-color:#07f}.gs-th .gs-resizer.gs-protected{display:none}.gs-th-inner{height:100%;box-sizing:border-box;vertical-align:middle;overflow:hidden;display:flex;align-items:center;justify-content:center}.gs-th-inner-wrap{height:100%;box-sizing:border-box;background-color:transparent}.gs-th-top{top:0;overflow:hidden}.gs-th-top .gs-resizer{top:0;right:0;width:3px;cursor:e-resize}.gs-th-top .gs-resizer.gs-dragging{border-right-style:dotted;height:1000000px!important;cursor:e-resize}.gs-th-left{left:0;overflow:hidden;min-width:30px;border-top:solid 1px #ddd}.gs-th-left .gs-resizer{left:0;bottom:0;height:3px;cursor:n-resize}.gs-th-left .gs-resizer.gs-dragging{border-bottom-style:dotted;width:1000000px!important;cursor:n-resize}.gs-th-top.gs-th-left{top:0;left:0;z-index:3;border:none!important}.gs-search-bar{width:100%;display:table;align-items:center;justify-content:center;border-top:solid 1px rgba(128,128,128,.3);border-left:solid 1px rgba(128,128,128,.3);border-right:solid 1px rgba(128,128,128,.3);box-sizing:border-box;background-color:rgba(200,50,0,.2)}.gs-search-bar.gs-search-found{background-color:rgba(0,200,100,.2)}.gs-search-bar .gs-search-bar-inner{vertical-align:middle;border-left:solid 1px rgba(128,128,128,.5)}.gs-search-bar .gs-search-bar-icon{border-left:solid 1px rgba(128,128,128,.3);display:table-cell;vertical-align:middle;width:30px}.gs-search-bar textarea{background-color:transparent;border:none;padding:0 2px;box-sizing:border-box;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;caret-color:rgba(128,128,128);white-space:pre-wrap;word-break:break-all;display:table-cell;vertical-align:middle;width:100%;resize:none}.gs-search-progress{display:table-cell;color:#999;font-size:13px;width:60px;vertical-align:middle;white-space:nowrap;text-align:center}.gs-search-close{display:table-cell;cursor:pointer;vertical-align:middle;width:24px}.gs-search-casesensitive{display:table-cell;cursor:pointer;vertical-align:middle;width:30px}.gs-search-casesensitive span{font-size:14px;padding:0 3px}.gs-search-casesensitive span.gs-search-casesensitive-on{color:#07f;background-color:rgba(200,200,255,.5);border-radius:3px}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}`;
10403
11632
  const embedStyle = () => {
10404
11633
  if (typeof window === "undefined") {
10405
11634
  return;
@@ -10804,6 +12033,7 @@ function GridSheet({
10804
12033
  contextMenuItems: contextMenuItems ?? defaultContextMenuItems,
10805
12034
  resizingPositionY: [-1, -1, -1],
10806
12035
  resizingPositionX: [-1, -1, -1],
12036
+ columnMenuState: null,
10807
12037
  minNumRows: 1,
10808
12038
  maxNumRows: -1,
10809
12039
  minNumCols: 1,
@@ -10860,7 +12090,7 @@ function GridSheet({
10860
12090
  style: {
10861
12091
  //width: '100%',
10862
12092
  maxWidth: (((_a = store.tableReactive.current) == null ? void 0 : _a.totalWidth) || 0) + 2,
10863
- maxHeight: (((_b = store.tableReactive.current) == null ? void 0 : _b.totalHeight) || 0) + 2,
12093
+ maxHeight: (((_b = store.tableReactive.current) == null ? void 0 : _b.fullHeight) || 0) + 2,
10864
12094
  overflow: "auto",
10865
12095
  resize: sheetResize,
10866
12096
  ...style
@@ -10870,6 +12100,7 @@ function GridSheet({
10870
12100
  /* @__PURE__ */ jsx(Tabular, {}),
10871
12101
  /* @__PURE__ */ jsx(StoreObserver, { ...{ ...options, sheetHeight, sheetWidth, sheetName, connector } }),
10872
12102
  /* @__PURE__ */ jsx(ContextMenu, {}),
12103
+ /* @__PURE__ */ jsx(ColumnMenu, {}),
10873
12104
  /* @__PURE__ */ jsx(Resizer, {}),
10874
12105
  /* @__PURE__ */ jsx(Emitter, {})
10875
12106
  ]