@svgrid/enterprise 3.1.1 → 3.1.2
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/SvSheet.svelte +7 -1
- package/dist/cdn/svgrid-enterprise.svelte-external.js +10534 -10332
- package/dist/designer/assets/{index-DkhD2kIe.js → index-V_cMXdxt.js} +311 -311
- package/dist/designer/assets/validate-YxSrBF1H.js +1 -0
- package/dist/designer/index.html +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/node/studio.js +16 -4
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +1 -0
- package/dist/server/server-row-model.d.ts +9 -0
- package/dist/server/server-row-model.js +120 -3
- package/dist/server/worker-data-source.d.ts +62 -0
- package/dist/server/worker-data-source.js +133 -0
- package/dist/studio/emit-project.js +8 -3
- package/dist/sveltekit/in-memory.d.ts +21 -1
- package/dist/sveltekit/in-memory.js +153 -105
- package/dist/sveltekit/index.d.ts +1 -1
- package/dist/version.d.ts +14 -1
- package/dist/version.js +14 -1
- package/dist/wc/sv-sheet-element.js +14 -9
- package/dist/wc/{validate-BqDthkNr.js → validate-JAuMsk6Z.js} +36 -36
- package/dist/worker/columnar.d.ts +42 -0
- package/dist/worker/columnar.js +410 -0
- package/dist/worker/index.d.ts +12 -0
- package/dist/worker/index.js +12 -0
- package/dist/worker/infer-schema.d.ts +21 -0
- package/dist/worker/infer-schema.js +34 -0
- package/dist/worker/protocol.d.ts +73 -0
- package/dist/worker/protocol.js +14 -0
- package/dist/worker/serve.d.ts +44 -0
- package/dist/worker/serve.js +100 -0
- package/package.json +7 -3
- package/dist/designer/assets/validate-C3B8QKsM.js +0 -1
|
@@ -1082,7 +1082,7 @@ function hn(e) {
|
|
|
1082
1082
|
for (let e = 0; e < r.length; e++) {
|
|
1083
1083
|
let t = r[e], n = i?.[e];
|
|
1084
1084
|
if (n && n.original === t) {
|
|
1085
|
-
n[Kt] = null, n[qt] = null, c[e] = n;
|
|
1085
|
+
n[Kt] !== null && (n[Kt] = null), n[qt] !== null && (n[qt] = null), c[e] = n;
|
|
1086
1086
|
continue;
|
|
1087
1087
|
}
|
|
1088
1088
|
l && l.size * 4 >= r.length && (l = null);
|
|
@@ -2011,7 +2011,7 @@ function br(e) {
|
|
|
2011
2011
|
}
|
|
2012
2012
|
}
|
|
2013
2013
|
if (i?.columnDef.editorType === "checkbox") {
|
|
2014
|
-
e.toggleBooleanCell(n.rowIndex, n.colIndex);
|
|
2014
|
+
(e.isCellEditableAt?.(n.rowIndex, n.colIndex) ?? !0) && e.toggleBooleanCell(n.rowIndex, n.colIndex);
|
|
2015
2015
|
return;
|
|
2016
2016
|
}
|
|
2017
2017
|
e.onCellDoubleClick(n.rowIndex, n.colIndex);
|
|
@@ -3688,7 +3688,7 @@ function Ir(e) {
|
|
|
3688
3688
|
return;
|
|
3689
3689
|
}
|
|
3690
3690
|
let o = xr(r, i), s = e.getCellDisplayValue(r.id, i.id, o);
|
|
3691
|
-
|
|
3691
|
+
e.props.onCellClick?.({
|
|
3692
3692
|
rowIndex: t,
|
|
3693
3693
|
colIndex: n,
|
|
3694
3694
|
columnId: i.id,
|
|
@@ -3698,8 +3698,10 @@ function Ir(e) {
|
|
|
3698
3698
|
rowIndex: t,
|
|
3699
3699
|
columnId: i.id,
|
|
3700
3700
|
row: r.original
|
|
3701
|
-
})
|
|
3702
|
-
|
|
3701
|
+
});
|
|
3702
|
+
let c = i.columnDef.editorType === "checkbox", l = !c && typeof s == "boolean" && i.columnDef.cell == null;
|
|
3703
|
+
if (c || l) {
|
|
3704
|
+
(e.isCellEditableAt?.(t, n) ?? !0) && (c || e.editingEnabled) && e.toggleBooleanCell(t, n), a(t, n), p(t, n), e.editingCell = null;
|
|
3703
3705
|
return;
|
|
3704
3706
|
}
|
|
3705
3707
|
if (e.activeAtPointerDown !== null && e.activeAtPointerDown.rowIndex === t && e.activeAtPointerDown.colIndex === n && e.editingEnabled && e.props.editOnSecondClick !== !1) {
|
|
@@ -6405,8 +6407,11 @@ function Vi(e, t) {
|
|
|
6405
6407
|
if (St) return e;
|
|
6406
6408
|
let t = e;
|
|
6407
6409
|
if (o(d).trim()) {
|
|
6408
|
-
let e = we(o(d),
|
|
6409
|
-
t = t.filter((t) =>
|
|
6410
|
+
let e = s.filterLocale ?? s.localization?.locale, n = we(o(d), e), r = Et.getAllColumns().map((e) => e.id);
|
|
6411
|
+
t = t.filter((t) => {
|
|
6412
|
+
for (let i of r) if (we(String(t.getCellValueByColumnId(i) ?? ""), e).includes(n)) return !0;
|
|
6413
|
+
return !1;
|
|
6414
|
+
});
|
|
6410
6415
|
}
|
|
6411
6416
|
if (t = cn(t), o(m)) {
|
|
6412
6417
|
let e = $r();
|
|
@@ -10243,7 +10248,7 @@ function jc(e, n) {
|
|
|
10243
10248
|
}), c(e, s);
|
|
10244
10249
|
};
|
|
10245
10250
|
R(s, (e) => {
|
|
10246
|
-
n().columnDef.editorType === "checkbox" || typeof r() == "boolean" ? e(l) : (n().columnDef.editorType === "list" || n().columnDef.editorType === "chips") && n().columnDef.cell == null ? e(f, 1) : n().columnDef.sparkline && n().columnDef.cell == null ? e(h, 2) : e(g, -1);
|
|
10251
|
+
(n().columnDef.editorType === "checkbox" || typeof r() == "boolean") && n().columnDef.cell == null ? e(l) : (n().columnDef.editorType === "list" || n().columnDef.editorType === "chips") && n().columnDef.cell == null ? e(f, 1) : n().columnDef.sparkline && n().columnDef.cell == null ? e(h, 2) : e(g, -1);
|
|
10247
10252
|
}), c(e, a);
|
|
10248
10253
|
}, n = (e, t = I) => {
|
|
10249
10254
|
let n = J(() => t().getCanExpand?.() ?? !1);
|
|
@@ -38466,7 +38471,7 @@ var XF = (e, t = I, n = I) => {
|
|
|
38466
38471
|
c(e, t);
|
|
38467
38472
|
}, QF = g("<span class=\"sheet-databar-axis svelte-1qw5b1f\"></span>"), $F = g("<span class=\"sheet-databar svelte-1qw5b1f\"></span> <!>", 1), eI = g("<span class=\"sheet-sparkline svelte-1qw5b1f\" aria-hidden=\"true\"><!></span>"), tI = g("<span aria-hidden=\"true\"></span>"), nI = g("<span aria-hidden=\"true\"></span>"), rI = g("<span aria-hidden=\"true\"></span>"), iI = g("<img class=\"sheet-cell-image svelte-1qw5b1f\" draggable=\"false\"/>"), aI = he("<svg viewBox=\"0 0 10 10\" width=\"10\" height=\"10\" aria-hidden=\"true\"><path d=\"M1 1.5h8L6 5.5v3L4 9.5v-4z\" fill=\"currentColor\"></path></svg>"), oI = he("<svg viewBox=\"0 0 10 10\" width=\"10\" height=\"10\" aria-hidden=\"true\"><path d=\"M2 3.5l3 3 3-3\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path></svg>"), sI = g("<button type=\"button\"><!></button>"), cI = g("<span class=\"sheet-invalid-circle svelte-1qw5b1f\" role=\"img\"></span>"), lI = g("<button type=\"button\" class=\"sheet-dropdown-arrow svelte-1qw5b1f\"><svg viewBox=\"0 0 10 10\" width=\"10\" height=\"10\" aria-hidden=\"true\"><path d=\"M2 3.5l3 3 3-3\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path></svg></button>"), uI = g("<span class=\"sheet-cell-control checkbox svelte-1qw5b1f\"><input type=\"checkbox\" class=\"svelte-1qw5b1f\"/></span>"), dI = g("<button type=\"button\" class=\"sheet-cell-control button svelte-1qw5b1f\"> </button>"), fI = g("<label class=\"svelte-1qw5b1f\"><input type=\"radio\" class=\"svelte-1qw5b1f\"/> </label>"), pI = g("<span class=\"sheet-cell-control radio svelte-1qw5b1f\" role=\"radiogroup\"></span>"), mI = g("<!> <!> <!> <!> <!> <span><!> </span> <!> <!> <!> <!> <!>", 1), hI = he("<path d=\"M6 10.5V2M2.5 5.5L6 2l3.5 3.5\" fill=\"none\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>"), gI = he("<path d=\"M1.5 6h9M7 2.5L10.5 6 7 9.5\" fill=\"none\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>"), _I = he("<path d=\"M6 1.5V10M2.5 6.5L6 10l3.5-3.5\" fill=\"none\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>"), vI = he("<circle cx=\"6\" cy=\"6\" r=\"4.5\"></circle>"), yI = he("<path d=\"M2.5 11V1.5h6.5L7.5 4l1.5 2.5H2.5\" stroke-width=\"1\" stroke-linejoin=\"round\"></path>"), bI = he("<circle cx=\"6\" cy=\"6\" r=\"5\"></circle><path d=\"M3.5 6.2l1.8 1.8L8.6 4.5\" fill=\"none\" stroke=\"#fff\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>", 1), xI = he("<path d=\"M6 1l5.2 9.5H.8z\"></path><path d=\"M6 4.5v3M6 9.2v.1\" fill=\"none\" stroke=\"#fff\" stroke-width=\"1.5\" stroke-linecap=\"round\"></path>", 1), SI = he("<circle cx=\"6\" cy=\"6\" r=\"5\"></circle><path d=\"M4 4l4 4M8 4l-4 4\" fill=\"none\" stroke=\"#fff\" stroke-width=\"1.6\" stroke-linecap=\"round\"></path>", 1), CI = he("<svg class=\"sheet-cf-icon svelte-1qw5b1f\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" aria-hidden=\"true\"><!></svg>"), wI = g("<span class=\"corner svelte-1qw5b1f\" aria-hidden=\"true\"></span>"), TI = g("<span class=\"none svelte-1qw5b1f\"> </span>"), EI = g("<span class=\"author svelte-1qw5b1f\"> </span>"), DI = g("<button type=\"button\" class=\"entry svelte-1qw5b1f\"><span class=\"addr svelte-1qw5b1f\"> </span> <!> <span> </span></button>"), OI = g("<div class=\"sheet-comments svelte-1qw5b1f\"><!></div>"), kI = g("<div aria-hidden=\"true\"></div>"), AI = g("<div class=\"sheet-resize-tip svelte-1qw5b1f\" role=\"status\"> </div>"), jI = g("<button type=\"button\" class=\"sheet-outline-level svelte-1qw5b1f\"> </button>"), MI = g("<div class=\"sheet-outline-levels svelte-1qw5b1f\" role=\"group\"></div>"), NI = g("<span class=\"sheet-outline-line svelte-1qw5b1f\" aria-hidden=\"true\"></span>"), PI = g("<!> <button type=\"button\"> </button>", 1), FI = g("<div class=\"sheet-outline-bar svelte-1qw5b1f\"><!> <!></div>"), II = he("<circle r=\"3\" fill=\"#1d4ed8\"></circle><line class=\"sheet-trace-arrow\" stroke=\"#1d4ed8\" stroke-width=\"1.5\" marker-end=\"url(#sheet-trace-head)\"></line>", 1), LI = he("<svg class=\"sheet-trace-layer svelte-1qw5b1f\" aria-hidden=\"true\"><defs><marker id=\"sheet-trace-head\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto-start-reverse\"><path d=\"M0 0L10 5L0 10z\" fill=\"#1d4ed8\"></path></marker></defs><!></svg>"), RI = g("<div class=\"sheet-presence svelte-1qw5b1f\"></div> <span> </span>", 1), zI = g("<div class=\"sheet-presence-layer svelte-1qw5b1f\" aria-hidden=\"true\"></div>"), BI = g("<div class=\"sheet-object-title svelte-1qw5b1f\"> </div>"), VI = g("<div class=\"sheet-object-inner svelte-1qw5b1f\"><!> <!></div>"), HI = g("<img class=\"sheet-object-image svelte-1qw5b1f\" draggable=\"false\"/>"), UI = g("<span class=\"sheet-object-grip svelte-1qw5b1f\" aria-hidden=\"true\"></span>"), WI = g("<div role=\"figure\"><!> <!></div>"), GI = g("<div class=\"sheet-object-layer svelte-1qw5b1f\"></div>"), KI = g("<li role=\"option\"><button type=\"button\" tabindex=\"-1\"> </button></li>"), qI = g("<ul class=\"sheet-fn-suggest svelte-1qw5b1f\" role=\"listbox\"></ul>"), JI = g("<div class=\"title svelte-1qw5b1f\"> </div>"), YI = g("<div class=\"text\"> </div>"), XI = g("<div class=\"sheet-input-message svelte-1qw5b1f\" role=\"note\"><!> <!></div>"), ZI = g("<span class=\"box svelte-1qw5b1f\"></span>"), QI = g("<div class=\"sheet-cell-anchor svelte-1qw5b1f\"><!></div>"), $I = g("<span> <b class=\"svelte-1qw5b1f\"> </b></span>"), eL = g("<span> <b class=\"svelte-1qw5b1f\"> </b></span>"), tL = g("<!> <span> <b class=\"svelte-1qw5b1f\"> </b></span> <!>", 1), nL = g("<div class=\"status svelte-1qw5b1f\" role=\"status\" aria-live=\"off\"><span class=\"mode svelte-1qw5b1f\"> </span> <span class=\"grow svelte-1qw5b1f\"></span> <!></div>"), rL = g("<div class=\"sv-sheet-dialog-buttons\"><button type=\"button\" class=\"btn primary\"> </button> <button type=\"button\" class=\"btn\"> </button></div>"), iL = g("<div class=\"sv-sheet-dialog\"><p class=\"note\"> </p></div>"), aL = g("<div class=\"sv-sheet-dialog-buttons\"><button type=\"button\" class=\"btn primary\"> </button> <button type=\"button\" class=\"btn\"> </button></div>"), oL = g("<div class=\"sv-sheet-dialog\"><p class=\"note\"> </p></div>"), sL = g("<div><!> <!> <!> <div><!> <!> <!> <!> <!> <!> <!> <!> <!> <!></div> <!> <!> <!> <!> <!> <!> <!> <!> <input class=\"sheet-file-input svelte-1qw5b1f\" type=\"file\" accept=\"image/*\" aria-hidden=\"true\" tabindex=\"-1\"/> <!> <!> <!> <!> <!> <!> <!> <!> <!> <!> <!> <!> <!> <!> <!> <!> <!> <!> <input class=\"sheet-file-input svelte-1qw5b1f\" type=\"file\" accept=\".xlsx,.xls,.ods,.csv,.tsv,.txt,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel,application/vnd.oasis.opendocument.spreadsheet,text/csv,text/tab-separated-values\" aria-hidden=\"true\" tabindex=\"-1\"/> <!> <!> <!></div>"), cL = {
|
|
38468
38473
|
hash: "svelte-1qw5b1f",
|
|
38469
|
-
code: "\n /* ---- the dialogs --------------------------------------------------- */\n /* Portalled to <body>, so these rules are global: one look for Find and\n Replace, Paste Special, Format Cells and Insert Function. */.sv-sheet-dialog {display:flex;flex-direction:column;gap:10px;font-family:var(--sg-font, \"Segoe UI\", system-ui, sans-serif);font-size:13px;color:var(--sg-fg, #242424);}.sv-sheet-dialog .field {display:grid;grid-template-columns:110px 1fr;align-items:center;gap:8px;}.sv-sheet-dialog .field.auto {grid-template-columns:auto 1fr;}.sv-sheet-dialog input[type=\"text\"],\n .sv-sheet-dialog input[type=\"number\"],\n .sv-sheet-dialog select {height:26px;padding:0 6px;font:inherit;color:inherit;background:var(--sg-bg, #fff);border:1px solid var(--sg-border, #d1d1d1);border-radius:var(--sg-radius, 3px);}.sv-sheet-dialog input[type=\"number\"] {width:72px;}.sv-sheet-dialog input[type=\"text\"]:focus,\n .sv-sheet-dialog input[type=\"number\"]:focus,\n .sv-sheet-dialog select:focus {outline:none;border-color:var(--sg-accent, #217346);box-shadow:0 0 0 1px var(--sg-accent, #217346);}.sv-sheet-dialog .checks {display:flex;flex-wrap:wrap;align-items:center;gap:6px 16px;}.sv-sheet-dialog .check {display:inline-flex;align-items:center;gap:6px;cursor:default;}.sv-sheet-dialog .status {min-height:18px;margin:0;color:var(--sg-muted, #616161);}.sv-sheet-dialog .note {margin:0;line-height:1.5;}.sv-sheet-dialog-buttons {display:flex;flex-wrap:wrap;justify-content:flex-end;gap:6px;}.sv-sheet-dialog-buttons .btn {height:26px;padding:0 14px;font-family:var(--sg-font, \"Segoe UI\", system-ui, sans-serif);font-size:13px;color:var(--sg-fg, #242424);background:var(--sg-bg, #fff);border:1px solid var(--sg-border, #d1d1d1);border-radius:var(--sg-radius, 3px);cursor:pointer;}.sv-sheet-dialog-buttons .btn:hover:not(:disabled) {background:var(--sg-row-hover-bg, #f5f5f5);}.sv-sheet-dialog-buttons .btn:disabled {opacity:0.5;cursor:default;}.sv-sheet-dialog-buttons .btn.primary {color:var(--sg-on-accent, #fff);background:var(--sg-accent, #217346);border-color:var(--sg-accent, #217346);}.sv-sheet-dialog-buttons .btn.primary:hover:not(:disabled) {background:var(--sg-accent, #217346);filter:brightness(1.08);}.sv-sheet.svelte-1qw5b1f {display:flex;flex-direction:column;gap:0;\n /* A comment's mark is red on a spreadsheet whatever the theme, as the\n fill handle is the accent: the theme's danger colour, Excel's red\n where a theme has none. The grid's own amber is a data-grid\n convention, not a sheet's. */--sg-note-corner: var(--sg-danger, #c42b1c);font-family:var(--sg-font, \"Segoe UI\", system-ui, sans-serif);color:var(--sg-fg, #242424);background:var(--sg-bg-subtle, var(--sg-header-bg, #f3f3f3));\n /* A sheet's headers are 22px whatever a preset asks of a data grid's\n (Ember's are 48px), and its text is set solid: a host page's prose\n line-height must not stretch the rows. */--sg-header-min-height: 0px;line-height:1.3;}\n /* height=\"100%\": the shell is a flex item and the grid takes what the\n chrome leaves. min-height: 0 on both, or the flex item refuses to shrink\n below the grid's content and overflows exactly as a fixed height did. */.sv-sheet.fill.svelte-1qw5b1f {flex:1 1 0;min-height:0;height:100%;}.sheet-grid.svelte-1qw5b1f {display:flex;flex-direction:column;position:relative;border-top:1px solid var(--sg-border, #d9d9d9);}\n /* The comment editor's anchor: an invisible box laid over the cell,\n inert to the pointer so the cell under it still takes clicks. */\n /* Excel's dotted guide at the border being dragged, across the sheet. */\n /* Above the grid's sticky header (z-index 30), as Excel draws it through\n the header band too; the tip above everything the sheet draws. */.sheet-resize-guide.svelte-1qw5b1f {position:absolute;z-index:40;pointer-events:none;}.sheet-resize-guide.col.svelte-1qw5b1f {top:0;bottom:0;width:0;border-left:1px dotted var(--sg-fg, #242424);}.sheet-resize-guide.row.svelte-1qw5b1f {left:0;right:0;height:0;border-top:1px dotted var(--sg-fg, #242424);}\n /* Excel's resize tip, beside the pointer while a border is dragged. */.sheet-resize-tip.svelte-1qw5b1f {position:absolute;z-index:1000;padding:2px 6px;font-size:12px;line-height:1.4;white-space:nowrap;pointer-events:none;color:var(--sg-fg, #242424);background:var(--sg-bg, #fff);border:1px solid var(--sg-border, #d1d1d1);border-radius:3px;box-shadow:0 2px 6px rgba(0, 0, 0, 0.15);}\n /* The sparkline fills its cell, behind the text and out of the way of the\n pointer: the cell is still selected, dragged and edited as a cell. */.sheet-sparkline.svelte-1qw5b1f {position:absolute;inset:3px;display:flex;align-items:center;justify-content:center;pointer-events:none;overflow:hidden;}.sheet-cell-anchor.svelte-1qw5b1f {position:absolute;z-index:7;pointer-events:none;}.sheet-cell-anchor.svelte-1qw5b1f .box:where(.svelte-1qw5b1f) {display:inline-block;}.sheet-file-input.svelte-1qw5b1f {display:none;}\n /* The object layer: charts and pictures over the cells. The layer itself\n lets the pointer through, each object catches it. No z-index on the\n layer, so it makes no stacking context and each object is stacked\n against the grid's sticky cells on its own: an object in the scrolling\n pane under the frozen cells (z-index 30) and the frozen rows (31), one\n hung from a frozen cell over them, and all under the header (35). */.sheet-object-layer.svelte-1qw5b1f {position:absolute;inset:0;pointer-events:none;}.sheet-object.svelte-1qw5b1f {position:absolute;z-index:7;pointer-events:auto;background:var(--sg-bg, #fff);border:1px solid var(--sg-border, #d1d1d1);box-shadow:0 1px 4px rgb(0 0 0 / 12%);box-sizing:border-box;overflow:hidden;cursor:move;touch-action:none;}.sheet-object.frozen.svelte-1qw5b1f {z-index:32;}.sheet-object.dragging.svelte-1qw5b1f {z-index:33;}.sheet-object.selected.svelte-1qw5b1f {border-color:var(--sg-accent, #107c41);box-shadow:0 0 0 1px var(--sg-accent, #107c41), 0 2px 8px rgb(0 0 0 / 16%);}.sheet-object-inner.svelte-1qw5b1f {display:flex;flex-direction:column;width:100%;height:100%;padding:4px;box-sizing:border-box;}.sheet-object-title.svelte-1qw5b1f {padding:0 4px 2px;font-size:12px;font-weight:600;text-align:center;color:var(--sg-fg, #242424);}.sheet-object-image.svelte-1qw5b1f {display:block;width:100%;height:100%;object-fit:contain;user-select:none;}.sheet-object-grip.svelte-1qw5b1f {position:absolute;inset-inline-end:-1px;bottom:-1px;width:12px;height:12px;background:var(--sg-accent, #107c41);border:1px solid var(--sg-bg, #fff);cursor:nwse-resize;touch-action:none;}[dir=\"rtl\"] .sheet-object-grip.svelte-1qw5b1f {cursor:nesw-resize;}.sheet-trace-layer.svelte-1qw5b1f {position:absolute;inset:0;width:100%;height:100%;z-index:6;pointer-events:none;overflow:visible;}\n /* A cell drawn as a control. It sits over the cell's own text rather\n than replacing it, so the value stays visible to a screen reader and\n to a column that is only partly controlled. */.sheet-cell-control.svelte-1qw5b1f {position:absolute;inset:0;display:flex;align-items:center;justify-content:center;gap:6px;pointer-events:none;\n /* The control covers the cell's own TRUE / FALSE, so it has to carry\n the cell's background rather than a colour of its own. `inherit`\n takes whatever the cell computed to, which is the only thing that\n stays right across the themes and the banded rows. */background:inherit;}.sheet-cell-control.svelte-1qw5b1f > :where(.svelte-1qw5b1f),\n .sheet-cell-control.svelte-1qw5b1f input:where(.svelte-1qw5b1f),\n .sheet-cell-control.svelte-1qw5b1f label:where(.svelte-1qw5b1f) {pointer-events:auto;}.sheet-cell-control.checkbox.svelte-1qw5b1f input:where(.svelte-1qw5b1f) {margin:0;cursor:pointer;}.sheet-cell-control.button.svelte-1qw5b1f {font:inherit;font-size:11px;line-height:1;inset:2px;padding:0 8px;border:1px solid var(--sg-border, #c4c4c4);border-radius:3px;background:var(--sg-header-bg, #f3f3f3);color:inherit;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.sheet-cell-control.button.svelte-1qw5b1f:hover:not(:disabled) {background:var(--sg-row-hover-bg, #e8e8e8);}.sheet-cell-control.button.svelte-1qw5b1f:disabled {cursor:default;opacity:0.6;}.sheet-cell-control.radio.svelte-1qw5b1f {justify-content:flex-start;padding-inline:4px;font-size:11px;overflow:hidden;}.sheet-cell-control.radio.svelte-1qw5b1f label:where(.svelte-1qw5b1f) {display:inline-flex;align-items:center;gap:3px;cursor:pointer;white-space:nowrap;}.sheet-cell-control.radio.svelte-1qw5b1f input:where(.svelte-1qw5b1f) {margin:0;}\n /* Excel's outline bar, down the inline-start edge of the grid. Logical\n insets rather than `left`, so it sits on the correct side in RTL.\n\n Its width is a variable because two rules have to agree on it: the\n bar's own, and the inset that moves the grid out from under it. They\n did not agree when the second rule aimed at the wrong class, and the\n bar sat on top of the row numbers with nothing to say it had. */.sheet-grid.svelte-1qw5b1f {--sheet-outline-width: 18px;}.sheet-outline-bar.svelte-1qw5b1f {position:absolute;inset-block:0;inset-inline-start:0;width:var(--sheet-outline-width);z-index:7;pointer-events:none;background:var(--sg-header-bg, #f6f6f6);border-inline-end:1px solid var(--sg-border, #d4d4d4);}.sheet-outline-levels.svelte-1qw5b1f {position:absolute;inset-block-start:0;inset-inline:0;display:flex;flex-direction:column;align-items:center;gap:1px;padding-block-start:2px;pointer-events:auto;}.sheet-outline-level.svelte-1qw5b1f {width:13px;height:13px;padding:0;font:inherit;font-size:9px;line-height:1;border:1px solid var(--sg-border, #b4b4b4);border-radius:2px;background:var(--sg-bg, #fff);color:inherit;cursor:pointer;}.sheet-outline-level.svelte-1qw5b1f:hover {background:var(--sg-row-hover-bg, #eaeaea);}\n /* The bracket: a line down the rows a group owns, with a foot at each\n end, the way Excel draws one. */.sheet-outline-line.svelte-1qw5b1f {position:absolute;inset-inline-start:8px;width:1px;background:var(--sg-muted, #8a8a8a);}.sheet-outline-line.svelte-1qw5b1f::before,\n .sheet-outline-line.svelte-1qw5b1f::after {content:'';position:absolute;inset-inline-start:0;width:4px;height:1px;background:inherit;}.sheet-outline-line.svelte-1qw5b1f::before {top:0;}.sheet-outline-line.svelte-1qw5b1f::after {bottom:0;}.sheet-outline-toggle.svelte-1qw5b1f {position:absolute;inset-inline-start:3px;width:11px;height:11px;margin-block-start:-6px;padding:0;display:grid;place-items:center;font:inherit;font-size:10px;line-height:1;border:1px solid var(--sg-border, #8a8a8a);border-radius:1px;background:var(--sg-bg, #fff);color:inherit;cursor:pointer;pointer-events:auto;}.sheet-outline-toggle.svelte-1qw5b1f:hover {background:var(--sg-row-hover-bg, #eaeaea);}\n /* The grid gets out of the bar's way only while there is one to show.\n The root's class is `sv-grid-root`; aiming this at `.sv-grid` matched\n nothing, so the bar painted straight over the row numbers. */.sheet-grid.svelte-1qw5b1f:has(> .sheet-outline-bar:where(.svelte-1qw5b1f)) > .sv-grid-root {margin-inline-start:var(--sheet-outline-width);width:calc(100% - var(--sheet-outline-width));}\n /* Circle Invalid Data: a red oval on the cell's box, over its content. */.sheet-invalid-circle.svelte-1qw5b1f {position:absolute;inset:0;border:1.5px solid #d03a2c;border-radius:50%;pointer-events:none;z-index:3;}\n /* The Input Message: Excel's small pale box under the selected cell. */.sheet-input-message.svelte-1qw5b1f {position:absolute;z-index:7;max-width:240px;padding:4px 8px;font-size:12px;line-height:1.4;pointer-events:none;color:var(--sg-fg, #242424);background:var(--sg-bg, #fff);border:1px solid var(--sg-border, #d1d1d1);border-radius:3px;box-shadow:0 2px 6px rgba(0, 0, 0, 0.15);white-space:pre-wrap;}.sheet-input-message.svelte-1qw5b1f .title:where(.svelte-1qw5b1f) {font-weight:700;}\n /* Formula AutoComplete under the cell, styled as the formula bar's list. */.sheet-fn-suggest.svelte-1qw5b1f {position:absolute;z-index:40;margin:0;padding:2px;list-style:none;min-width:180px;max-height:220px;overflow-y:auto;border:1px solid var(--sg-border, #d1d1d1);border-radius:4px;background:var(--sg-bg, #fff);color:var(--sg-fg, #242424);box-shadow:0 8px 24px rgb(0 0 0 / 0.14);font-size:12px;}.sheet-fn-suggest.svelte-1qw5b1f button:where(.svelte-1qw5b1f) {display:block;width:100%;text-align:left;font:inherit;border:0;background:transparent;color:inherit;padding:4px 8px;border-radius:3px;cursor:pointer;}.sheet-fn-suggest.svelte-1qw5b1f button.active:where(.svelte-1qw5b1f),\n .sheet-fn-suggest.svelte-1qw5b1f button:where(.svelte-1qw5b1f):hover {background:var(--sg-row-hover-bg, #f0f0f0);}\n /* The in-cell dropdown arrow: a small button at the cell's right edge,\n above the cell text like the note corner. */.sheet-dropdown-arrow.svelte-1qw5b1f {position:absolute;top:50%;right:1px;transform:translateY(-50%);width:16px;height:16px;display:grid;place-items:center;padding:0;color:var(--sg-fg, #242424);background:var(--sg-bg, #fff);border:1px solid var(--sg-border, #d1d1d1);border-radius:2px;cursor:pointer;z-index:6;}.sheet-dropdown-arrow.svelte-1qw5b1f:hover {background:var(--sg-row-hover-bg, #f0f0f0);}\n /* The AutoFilter arrow on a header cell, a funnel once filtered. */.sheet-filter-arrow.svelte-1qw5b1f {position:absolute;top:50%;right:1px;transform:translateY(-50%);width:16px;height:16px;display:grid;place-items:center;padding:0;color:var(--sg-muted, #616161);background:var(--sg-bg, #fff);border:1px solid var(--sg-border, #d1d1d1);border-radius:2px;cursor:pointer;z-index:6;}.sheet-filter-arrow.svelte-1qw5b1f:hover {background:var(--sg-row-hover-bg, #f0f0f0);}.sheet-filter-arrow.filtered.svelte-1qw5b1f {color:color-mix(in srgb, var(--sg-info, #0f6cbd) 80%, var(--sg-fg, #242424));}\n /* Excel turns the row numbers of a filtered region blue. */\n /* Excel's blue row numbers under a filter. Mixed toward the text colour so\n a host theme whose info colour is a light cyan still clears 4.5:1 at the\n gutter's 13px; Excel's own #0f6cbd already does. */.sv-sheet.svelte-1qw5b1f tr.sheet-filtered > td.sv-grid-row-number-cell {color:color-mix(in srgb, var(--sg-info, #0f6cbd) 80%, var(--sg-fg, #242424));}\n /* A data bar behind the cell text, a third of the height off the edges\n as Excel draws it. */.sheet-databar.svelte-1qw5b1f {position:absolute;top:2px;bottom:2px;border-radius:1px;opacity:0.85;pointer-events:none;}.sheet-databar-axis.svelte-1qw5b1f {position:absolute;top:1px;bottom:1px;width:0;border-left:1px dashed var(--sg-muted, #616161);opacity:0.6;pointer-events:none;}\n /* Excel's marching ants: a dashed line on the cell's outline edges, the\n dashes walking clockwise. Drawn as background layers, one per edge, so\n it costs the compositor and nothing else; above the cell text and the\n data bar, under the editor and the note corner (z-index 6). Each layer\n is one 8px tile of the dash repeated along its edge, so sliding it a\n tile per cycle is seamless: a single full-width stretch slid the same\n way opened a gap at one end and closed it at the other, which read as\n a flicker rather than a walk. The walk is the signal that the sheet is\n in copy mode, as it is in Excel, so it is not switched off for\n prefers-reduced-motion: two pixels of dash, nothing else moves. */.sheet-ants.svelte-1qw5b1f {position:absolute;inset:0;z-index:5;pointer-events:none;--ants-on: var(--sg-fg, #242424);--ants-off: var(--sg-bg, #fff);--ants-top: none;--ants-bottom: none;--ants-left: none;--ants-right: none;background-image:var(--ants-top), var(--ants-bottom), var(--ants-left), var(--ants-right);background-repeat:repeat-x, repeat-x, repeat-y, repeat-y;background-size:8px 2px, 8px 2px, 2px 8px, 2px 8px;background-position:0 0, 0 100%, 0 0, 100% 0;\n animation: svelte-1qw5b1f-sheet-ants 0.35s linear infinite;}.sheet-ants.top.svelte-1qw5b1f {--ants-top: linear-gradient(to right, var(--ants-on) 0 4px, var(--ants-off) 4px 8px);}.sheet-ants.bottom.svelte-1qw5b1f {--ants-bottom: linear-gradient(to right, var(--ants-on) 0 4px, var(--ants-off) 4px 8px);}.sheet-ants.left.svelte-1qw5b1f {--ants-left: linear-gradient(to bottom, var(--ants-on) 0 4px, var(--ants-off) 4px 8px);}.sheet-ants.right.svelte-1qw5b1f {--ants-right: linear-gradient(to bottom, var(--ants-on) 0 4px, var(--ants-off) 4px 8px);}\n /* The dynamic array's outline: a thin blue rim on the spill the active cell is in. */.sheet-spill-edge.svelte-1qw5b1f {position:absolute;inset:0;z-index:4;pointer-events:none;--spill-c: var(--sg-accent, #2b6cb0);box-shadow:none;}.sheet-spill-edge.top.svelte-1qw5b1f {border-top:1px solid var(--spill-c);}.sheet-spill-edge.bottom.svelte-1qw5b1f {border-bottom:1px solid var(--spill-c);}.sheet-spill-edge.left.svelte-1qw5b1f {border-left:1px solid var(--spill-c);}.sheet-spill-edge.right.svelte-1qw5b1f {border-right:1px solid var(--spill-c);}\n @keyframes svelte-1qw5b1f-sheet-ants {\n to { background-position: 8px 0, -8px 100%, 0 -8px, 100% 8px; }\n }\n /* An icon at the left of the cell; the text keeps its own alignment. */.sheet-cell.has-icon.svelte-1qw5b1f {padding-left:20px;}.sheet-cf-icon.svelte-1qw5b1f {position:absolute;left:4px;top:50%;transform:translateY(-50%);}\n /* Show All Comments: a strip under the formula bar. */.sheet-comments.svelte-1qw5b1f {display:flex;flex-wrap:wrap;gap:4px 8px;max-height:96px;overflow-y:auto;padding:4px 8px;font-size:12px;border-top:1px solid var(--sg-border, #d9d9d9);background:var(--sg-bg-subtle, #f3f3f3);}.sheet-comments.svelte-1qw5b1f .none:where(.svelte-1qw5b1f) {color:var(--sg-muted, #616161);}.sheet-comments.svelte-1qw5b1f .entry:where(.svelte-1qw5b1f) {display:inline-flex;gap:6px;max-width:320px;padding:2px 8px;font:inherit;color:inherit;background:var(--sg-bg, #fff);border:1px solid var(--sg-border, #d9d9d9);border-radius:3px;cursor:pointer;}.sheet-comments.svelte-1qw5b1f .entry:where(.svelte-1qw5b1f):hover {background:var(--sg-row-hover-bg, #f0f0f0);}.sheet-comments.svelte-1qw5b1f .addr:where(.svelte-1qw5b1f) {font-weight:600;color:var(--sg-muted, #616161);}.sheet-comments.svelte-1qw5b1f .author:where(.svelte-1qw5b1f) {font-weight:600;}.sheet-comments.svelte-1qw5b1f .text.resolved:where(.svelte-1qw5b1f) {text-decoration:line-through;color:var(--sg-muted, #616161);}.sheet-comments.svelte-1qw5b1f .text:where(.svelte-1qw5b1f) {overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.sheet-grid.fill.svelte-1qw5b1f {flex:1 1 0;min-height:0;}\n /* The formula bar sits on the ribbon's grey ground, as it does in Excel. */.sv-sheet.svelte-1qw5b1f > .sv-formula-bar {margin:4px 6px;}.sv-sheet.svelte-1qw5b1f > .sv-ribbon {border-left:0;border-right:0;border-top:0;border-radius:0;}\n\n /*\n * Excel's own palette, light and dark with the page, for `look=\"excel\"`.\n * Tokens, so every part underneath - the grid included - picks them up.\n * The default look leaves every token to the host's theme.\n */.sv-sheet.look-excel.svelte-1qw5b1f {\n /* Excel's note mark is a red triangle. */--sg-note-corner: #c42b1c;--sg-bg: #ffffff;--sg-fg: #242424;--sg-muted: #616161;--sg-border: #d9d9d9;--sg-header-bg: #f3f3f3;--sg-header-fg: #444444;--sg-bg-subtle: #f3f3f3;--sg-row-alt-bg: #ffffff;--sg-row-hover-bg: #f0f0f0;--sg-muted-bg: #e6e6e6;--sg-selection-bg: rgba(16, 124, 65, 0.12);--sg-input-bg: #ffffff;--sg-input-border: #c8c6c4;--sg-accent: #107c41;--sg-on-accent: #ffffff;--sg-focus-ring: #107c41;--sg-success: #107c41;--sg-info: #0f6cbd;--sg-warning: #f2c811;--sg-danger: #c42b1c;--sg-radius: 0px;--sg-radius-lg: 6px;--sg-font: \"Aptos\", \"Aptos Narrow\", \"Segoe UI\", Calibri, Arial, sans-serif;}[data-theme=\"dark\"] .sv-sheet.look-excel.svelte-1qw5b1f {--sg-bg: #1f1f1f;--sg-fg: #e6e6e6;--sg-muted: #a6a6a6;--sg-border: #3d3d3d;--sg-header-bg: #2b2b2b;--sg-header-fg: #d0d0d0;--sg-bg-subtle: #292929;--sg-row-alt-bg: #1f1f1f;--sg-row-hover-bg: #363636;--sg-muted-bg: #404040;--sg-selection-bg: rgba(63, 166, 110, 0.2);--sg-input-bg: #262626;--sg-input-border: #4a4a4a;--sg-accent: #3fa66e;--sg-on-accent: #ffffff;--sg-focus-ring: #3fa66e;--sg-success: #3fa66e;--sg-info: #4cc2ff;--sg-warning: #f2c811;--sg-danger: #f1707b;}\n @media (prefers-color-scheme: dark) {:root:not([data-theme=\"light\"]) .sv-sheet.look-excel.svelte-1qw5b1f {--sg-bg: #1f1f1f;--sg-fg: #e6e6e6;--sg-muted: #a6a6a6;--sg-border: #3d3d3d;--sg-header-bg: #2b2b2b;--sg-header-fg: #d0d0d0;--sg-bg-subtle: #292929;--sg-row-alt-bg: #1f1f1f;--sg-row-hover-bg: #363636;--sg-muted-bg: #404040;--sg-selection-bg: rgba(63, 166, 110, 0.2);--sg-input-bg: #262626;--sg-input-border: #4a4a4a;--sg-accent: #3fa66e;--sg-on-accent: #ffffff;--sg-focus-ring: #3fa66e;--sg-success: #3fa66e;--sg-info: #4cc2ff;--sg-warning: #f2c811;--sg-danger: #f1707b;}\n }\n\n /* ---- the sheet's geometry ------------------------------------------ */\n /* Column letters: 22px, centred, plain weight; the gutter to match. */.sv-sheet.svelte-1qw5b1f .sv-grid-head .sv-grid-column {height:22px;padding:0;font-size:12px;font-weight:400;color:var(--sg-header-fg, var(--sg-muted, #444));}.sv-sheet.svelte-1qw5b1f .sv-grid-head .sv-grid-column .sv-grid-header-cell {justify-content:center;}.sv-sheet.svelte-1qw5b1f .sv-grid-head .sv-grid-column .sv-grid-header-sort {justify-content:center;}\n /* Row numbers are centred in the gutter, as Excel's are. */.sv-sheet.svelte-1qw5b1f .sv-grid-row-number-cell {font-size:12px;padding:0 4px;line-height:1.3;text-align:center;}.sv-sheet.svelte-1qw5b1f .sv-grid-head .sv-grid-column,\n .sv-sheet.svelte-1qw5b1f td.sv-grid-cell {line-height:1.3;}\n /*\n * Header borders, as Excel draws them: a hairline between every column\n * letter and under the header row, a hairline between every row number\n * and to the right of the gutter, and the Select All corner framed by\n * both. The grid fuses the gutter into the header band by painting its\n * right edge in the header colour; a sheet wants the line.\n */.sv-sheet.svelte-1qw5b1f .sv-grid-head .sv-grid-column {border-right:1px solid var(--sg-border, #d9d9d9);border-bottom:1px solid var(--sg-border, #d9d9d9);}\n /* A hidden column's letter takes no room at all: the hairline above\n would keep it a pixel wide. Its neighbours' lines meet at the seam,\n which is the doubled line Excel draws where a column is hidden. */.sv-sheet.svelte-1qw5b1f .sv-grid-head .sv-grid-column.sv-grid-column-collapsed {border-right-width:0;}\n /*\n * Where a column or a row is hidden, Excel thickens the header line at\n * the seam so the gap in the letters or numbers has a mark. The letter\n * after the fold carries a 2px left edge (a border, since the header's\n * selection shading uses its box-shadow); the number after hidden rows\n * a 2px top edge painted on a pseudo-element, since a border there would\n * push the row a pixel taller than the virtualizer laid it out.\n */.sv-sheet.svelte-1qw5b1f .sv-grid-head .sv-grid-column.sv-grid-column-collapsed + .sv-grid-column:not(.sv-grid-column-collapsed) {border-left:2px solid var(--sg-muted, #8a8a8a);}.sv-sheet.svelte-1qw5b1f tr.sv-grid-row-collapsed + tr:not(.sv-grid-row-collapsed) > td.sv-grid-row-number-cell::before {content:\"\";position:absolute;left:0;right:0;top:0;height:2px;background:var(--sg-muted, #8a8a8a);pointer-events:none;}.sv-sheet.svelte-1qw5b1f .sv-grid-row-number-column,\n .sv-sheet.svelte-1qw5b1f .sv-grid-row-number-cell {border-right:1px solid var(--sg-border, #d9d9d9);}\n /*\n * Excel shades the headers the selection touches - a step darker than the\n * header band, mixed from the text colour so it lands right on a dark\n * theme too - and marks them with a 2px line in the accent along the edge\n * that faces the cells. The line sits over the hairline, as Excel's does.\n */\n /* A column or row selected whole: the accent, white on green, as Excel's. */.sv-sheet.svelte-1qw5b1f th.sheet-col-whole,\n .sv-sheet.svelte-1qw5b1f th.sheet-col-whole .sv-grid-header-cell,\n .sv-sheet.svelte-1qw5b1f td.sv-grid-row-number-cell.sheet-row-whole {background:var(--sg-accent, #217346) !important;color:var(--sg-on-accent, #fff) !important;}.sv-sheet.svelte-1qw5b1f th.sheet-col-selected {background:color-mix(in srgb, var(--sg-fg, #242424) 13%, var(--sg-header-bg, #f3f3f3) 87%);color:var(--sg-fg, #242424);box-shadow:inset 0 -2px 0 0 var(--sg-accent, #107c41);}.sv-sheet.svelte-1qw5b1f tr:has(> td.sv-grid-cell-active) > td.sv-grid-row-number-cell,\n .sv-sheet.svelte-1qw5b1f tr:has(> td[data-selected-range=\"true\"]) > td.sv-grid-row-number-cell {background:color-mix(in srgb, var(--sg-fg, #242424) 13%, var(--sg-header-bg, #f3f3f3) 87%);color:var(--sg-fg, #242424);box-shadow:inset -2px 0 0 0 var(--sg-accent, #107c41);}\n /* No hover wash on cells: a sheet does not light rows up under the mouse. */.sv-sheet.svelte-1qw5b1f tbody tr:hover > .sv-grid-cell:not([data-selected-range=\"true\"]):not(.sv-grid-row-number-cell) {background-color:var(--sg-bg, #fff);}.sv-sheet.svelte-1qw5b1f .sv-grid-cell {font-size:13px;}\n\n /*\n * The selection rectangle, as Excel draws it: the range tinted and framed\n * by a 2px line in the accent, the active cell inside it left unshaded\n * with no ring of its own (the frame is the ring), and the fill handle a\n * small square on the bottom-right corner, ringed in the sheet colour so\n * it reads against the frame. A lone active cell is a one-cell range and\n * gets the same frame, white inside.\n *\n * Painted on a pseudo-element ABOVE the cell's content rather than on the\n * td itself. The grid draws the tint as the td's background and the frame\n * as inset shadows, both of which sit under the td's children - and the\n * sheet's cell span now covers the whole td, so on a filled cell the\n * selection vanished under the fill. The overlay is translucent, so a\n * fill inside a selection reads a shade darker, which is what Excel shows.\n *\n * The tint is the theme's accent at a low alpha, not `--sg-selection-bg`:\n * that token is an opaque surface in most themes (Ember's is #ffece3),\n * and an opaque overlay above the content hid the text of every selected\n * cell but the active one. Excel's own tint is its green at 12%.\n */.sv-sheet.svelte-1qw5b1f td.sv-grid-cell[data-selected-range=\"true\"],\n .sv-sheet.svelte-1qw5b1f td.sv-grid-cell-active {background:var(--sg-bg, #fff);box-shadow:none;}.sv-sheet.svelte-1qw5b1f td.sv-grid-cell[data-selected-range=\"true\"]::after,\n .sv-sheet.svelte-1qw5b1f td.sv-grid-cell-active::after {content:\"\";position:absolute;inset:0;z-index:2;pointer-events:none;background:color-mix(in srgb, var(--sg-accent, #107c41) 14%, transparent);box-shadow:var(--sv-range-top), var(--sv-range-bottom), var(--sv-range-left), var(--sv-range-right);}\n /* The active cell: no tint, and a frame of its own only when it is not\n inside a range, whose frame it otherwise shares. Written out with the\n range attribute so it outranks the tint rule above; with a shorter\n selector the active cell inside a range was tinted like the rest, and\n Excel leaves it white. */.sv-sheet.svelte-1qw5b1f td.sv-grid-cell-active::after,\n .sv-sheet.svelte-1qw5b1f td.sv-grid-cell.sv-grid-cell-active[data-selected-range=\"true\"]::after {background:transparent;}.sv-sheet.svelte-1qw5b1f td.sv-grid-cell-active:not([data-selected-range=\"true\"])::after {box-shadow:inset 0 0 0 2px var(--sg-accent, #107c41);}\n /* Nothing over the editor while a cell is being typed into. */.sv-sheet.svelte-1qw5b1f td.sv-grid-cell-editing::after {display:none;}.sv-sheet.svelte-1qw5b1f .sv-grid-fill-handle {width:8px;height:8px;right:-1px;bottom:-1px;border:1px solid var(--sg-bg, #fff);border-radius:0;}.sv-sheet.svelte-1qw5b1f .sv-grid-fill-handle:hover {transform:none;}\n\n /* Headers respond to the pointer the way Excel's do: a shade darker under\n it, and the cursor says what a click will select. */.sv-sheet.svelte-1qw5b1f .sv-grid-head .sv-grid-column:hover,\n .sv-sheet.svelte-1qw5b1f td.sv-grid-row-number-cell:hover {background:color-mix(in srgb, var(--sg-fg, #242424) 7%, var(--sg-header-bg, #f3f3f3) 93%);}\n /*\n * Excel's cursors: the white cross over the cells, a black arrow pointing\n * down the column over a letter and along the row over a number (drawn,\n * since no CSS cursor is one; the hotspot is the tip), the plain arrow\n * over the corner, and the double-headed arrows on the borders. The\n * fill handle's crosshair and the selection border's move cursor are\n * the grid's own.\n */.sv-sheet.svelte-1qw5b1f td.sv-grid-cell:not(.sv-grid-row-number-cell):not(.sv-grid-cell-editing) {cursor:cell;}.sv-sheet.svelte-1qw5b1f .sv-grid-head .sv-grid-column[data-svgrid-header-col],\n .sv-sheet.svelte-1qw5b1f .sv-grid-head .sv-grid-column[data-svgrid-header-col] .sv-grid-header-sort,\n .sv-sheet.svelte-1qw5b1f .sv-grid-head .sv-grid-column[data-svgrid-header-col] .sv-grid-header-cell {cursor:url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path d='M8 14.5L2.2 8.2h3.6V1.5h4.4v6.7h3.6z' fill='%23000' stroke='%23fff' stroke-width='1.2' stroke-linejoin='round'/></svg>\") 8 15, pointer;}.sv-sheet.svelte-1qw5b1f td.sv-grid-row-number-cell {cursor:url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path d='M14.5 8L8.2 13.8v-3.6H1.5V5.8h6.7V2.2z' fill='%23000' stroke='%23fff' stroke-width='1.2' stroke-linejoin='round'/></svg>\") 15 8, pointer;}.sv-sheet.svelte-1qw5b1f th.sv-grid-row-number-column {cursor:default;}.sv-sheet.svelte-1qw5b1f .sv-grid-resize-handle {cursor:col-resize;}.sv-sheet.svelte-1qw5b1f .sv-grid-row-resize-handle {cursor:row-resize;}\n\n /* The in-cell editor, widened over the neighbours while a long formula\n is typed: the cell it sits in is already lifted above the row. */.sv-sheet.svelte-1qw5b1f td.sv-grid-cell-editing {overflow:visible;}.sv-sheet.svelte-1qw5b1f td.sv-grid-cell-editing .sv-grid-cell-editor {position:relative;z-index:2;max-width:none;background:var(--sg-bg, #fff);}\n\n /* A cell a formula in progress refers to, in that reference's colour.\n An overlay too, for the same reason as the selection's: a filled cell\n would otherwise hide it. Translucent, so the fill shows through. */.sv-sheet.svelte-1qw5b1f td[data-sheet-ref]::before {content:\"\";position:absolute;inset:0;z-index:2;pointer-events:none;box-shadow:var(--sheet-ref-edges, none);background:color-mix(in srgb, var(--sheet-ref) 12%, transparent);}\n /* The editor's text under the coloured mirror: only the caret shows. */.sv-sheet.svelte-1qw5b1f .sv-grid-cell-editor.sheet-ref-text {color:transparent;caret-color:var(--sg-fg, #242424);}\n /* Format Painter armed: a brush for a pointer, as Excel shows. */.sheet-grid.painting.svelte-1qw5b1f td.sv-grid-cell {cursor:url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 18 18'><path d='M10.2 2.4l5.4 5.4-3.6 3.6-5.4-5.4z' fill='%23fff' stroke='%23222' stroke-width='1.4' stroke-linejoin='round'/><path d='M6.6 6L3.2 9.4a1.8 1.8 0 0 0 0 2.6l2.8 2.8a1.8 1.8 0 0 0 2.6 0L12 11.4' fill='none' stroke='%23222' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/></svg>\") 3 15, cell;}.sv-sheet.svelte-1qw5b1f .sheet-ref-mirror {position:absolute;z-index:21;overflow:hidden;white-space:pre-wrap;overflow-wrap:break-word;color:var(--sg-fg, #242424);pointer-events:none;background:transparent;}\n\n /* The Select All corner: a triangle pointing into the sheet. */.corner.svelte-1qw5b1f {display:block;width:100%;height:100%;position:relative;}.corner.svelte-1qw5b1f::after {content:\"\";position:absolute;right:3px;bottom:3px;border-style:solid;border-width:0 0 9px 9px;border-color:transparent transparent var(--sg-muted, #b0b0b0) transparent;}\n\n /*\n * A sheet cell fills its td edge to edge, so a fill colour reaches the\n * gridlines the way it does in Excel rather than leaving a halo of cell\n * background around it.\n *\n * The grid pads a left-aligned td by 12px and a block child only rises to\n * its own line height, so a fill used to stop short on the left and leave\n * a hairline top and bottom. The td gives up its padding and the span is\n * laid over the td's whole box instead, and does its own padding. A grid\n * container rather than a block so the text centres vertically at any row\n * height, including one the user has dragged taller. Text that does not\n * fit is cut at the edge, as Excel cuts it, not ellipsised.\n */.sv-sheet.svelte-1qw5b1f td.sv-grid-cell:not(.sv-grid-row-number-cell) {padding:0;position:relative;}.sheet-cell.svelte-1qw5b1f {position:absolute;inset:0;display:grid;align-items:center;padding:0 4px;line-height:1.3;white-space:nowrap;overflow:hidden;}\n /* The table style: a filled header, a tinted band on alternate rows, a\n line over the totals. Behind everything the cell itself draws, and out\n of the pointer's way. */.sheet-table-fill.svelte-1qw5b1f {position:absolute;inset:0;pointer-events:none;}.sheet-table-fill.header.svelte-1qw5b1f {background:var(--sheet-table-header, color-mix(in srgb, var(--sg-accent, #107c41) 16%, transparent));border-bottom:1px solid var(--sheet-table-border, color-mix(in srgb, var(--sg-accent, #107c41) 45%, transparent));}.sheet-table-fill.band.svelte-1qw5b1f {background:var(--sheet-table-band, color-mix(in srgb, var(--sg-accent, #107c41) 7%, transparent));}.sheet-table-fill.totals.svelte-1qw5b1f {background:var(--sheet-table-totals, color-mix(in srgb, var(--sg-accent, #107c41) 12%, transparent));border-top:1px solid var(--sheet-table-border, color-mix(in srgb, var(--sg-accent, #107c41) 45%, transparent));}\n\n /* A picture in the cell: fitted inside it, and out of the pointer's way\n so the cell is selected, dragged and typed into as a cell. */.sheet-cell-image.svelte-1qw5b1f {position:absolute;inset:1px 2px;width:calc(100% - 4px);height:calc(100% - 2px);object-fit:contain;pointer-events:none;}\n\n /* Presence: a thin box in the person's colour around their selection, and\n a tag on their cursor. Over the cells, out of the pointer's way, and\n never in the way of reading a number: the box is a border, not a fill. */.sheet-presence-layer.svelte-1qw5b1f {position:absolute;inset:0;pointer-events:none;z-index:4;}.sheet-presence.svelte-1qw5b1f {position:absolute;border:2px solid var(--sheet-presence-colour, #2563eb);border-radius:2px;background:color-mix(in srgb, var(--sheet-presence-colour, #2563eb) 8%, transparent);}.sheet-presence-tag.svelte-1qw5b1f {position:absolute;transform:translateY(-100%);padding:1px 5px;border-radius:3px 3px 3px 0;z-index:1;background:var(--sheet-presence-colour, #2563eb);color:#fff;font-size:11px;line-height:1.5;white-space:nowrap;max-width:160px;overflow:hidden;text-overflow:ellipsis;}\n /* No room above: under the cell, the corner turned the other way. */.sheet-presence-tag.below.svelte-1qw5b1f {transform:none;border-radius:0 3px 3px 3px;}\n\n /* Excel's link: the theme's link colour, underlined, and a hand over it.\n The cell is still a cell - it is selected, dragged and typed into the\n same way - so this is a span rather than an anchor. */.sheet-cell.linked.svelte-1qw5b1f {color:var(--sg-info, #0f6cbd);text-decoration:underline;text-underline-offset:2px;cursor:pointer;}.sheet-cell.linked.svelte-1qw5b1f:hover {color:color-mix(in srgb, var(--sg-info, #0f6cbd) 80%, var(--sg-fg, #242424));}.sheet-cell.formula.svelte-1qw5b1f {font-family:ui-monospace, Menlo, monospace;color:var(--sg-accent, #107c41);}\n\n /*\n * Text spilling over empty neighbours, as in Excel. The grid's td clips\n * its content; for a spilling cell it is opened up, and the span grows to\n * its text (capped at the run of empty cells) and paints its own\n * background over the neighbours, which also hides the gridlines under\n * the text the way Excel does. z-index lifts it above the later tds in\n * the row, which would otherwise paint over it in DOM order.\n */.sv-sheet.svelte-1qw5b1f td.sv-grid-cell:has(> .sheet-cell.spill) {overflow:visible;}.sheet-cell.spill.svelte-1qw5b1f {right:auto;z-index:1;width:max-content;min-width:100%;background:var(--sg-bg, #fff);}\n\n /* ---- View > Show --------------------------------------------------- */\n /* Gridlines off keeps the cell geometry (the borders go transparent, so\n nothing shifts) and leaves the borders a cell has of its own. */.sv-sheet.no-gridlines.svelte-1qw5b1f td.sv-grid-cell {border-color:transparent;}.sv-sheet.no-headings.svelte-1qw5b1f .sv-grid-head {display:none;}\n\n /* ---- status bar ---------------------------------------------------- */.status.svelte-1qw5b1f {display:flex;align-items:center;gap:18px;height:22px;padding:0 10px;font-size:12px;\n /* Explicit: a host page that uppercases small text turns \"Count\" into\n \"COUNT\", which reads as shouting rather than as a status bar. */text-transform:none;letter-spacing:normal;color:var(--sg-fg, #242424);border-top:1px solid var(--sg-border, #d9d9d9);background:var(--sg-header-bg, #f3f3f3);}.status.svelte-1qw5b1f .grow:where(.svelte-1qw5b1f) {flex:1 1 auto;}.status.svelte-1qw5b1f .mode:where(.svelte-1qw5b1f) {color:var(--sg-muted, #616161);}.status.svelte-1qw5b1f b:where(.svelte-1qw5b1f) {font-weight:400;font-variant-numeric:tabular-nums;}"
|
|
38474
|
+
code: "\n /* ---- the dialogs --------------------------------------------------- */\n /* Portalled to <body>, so these rules are global: one look for Find and\n Replace, Paste Special, Format Cells and Insert Function. */.sv-sheet-dialog {display:flex;flex-direction:column;gap:10px;font-family:var(--sg-font, \"Segoe UI\", system-ui, sans-serif);font-size:13px;color:var(--sg-fg, #242424);}.sv-sheet-dialog .field {display:grid;grid-template-columns:110px 1fr;align-items:center;gap:8px;}.sv-sheet-dialog .field.auto {grid-template-columns:auto 1fr;}.sv-sheet-dialog input[type=\"text\"],\n .sv-sheet-dialog input[type=\"number\"],\n .sv-sheet-dialog select {height:26px;padding:0 6px;font:inherit;color:inherit;background:var(--sg-bg, #fff);border:1px solid var(--sg-border, #d1d1d1);border-radius:var(--sg-radius, 3px);}.sv-sheet-dialog input[type=\"number\"] {width:72px;}.sv-sheet-dialog input[type=\"text\"]:focus,\n .sv-sheet-dialog input[type=\"number\"]:focus,\n .sv-sheet-dialog select:focus {outline:none;border-color:var(--sg-accent, #217346);box-shadow:0 0 0 1px var(--sg-accent, #217346);}.sv-sheet-dialog .checks {display:flex;flex-wrap:wrap;align-items:center;gap:6px 16px;}.sv-sheet-dialog .check {display:inline-flex;align-items:center;gap:6px;cursor:default;}.sv-sheet-dialog .status {min-height:18px;margin:0;color:var(--sg-muted, #616161);}.sv-sheet-dialog .note {margin:0;line-height:1.5;}.sv-sheet-dialog-buttons {display:flex;flex-wrap:wrap;justify-content:flex-end;gap:6px;}.sv-sheet-dialog-buttons .btn {height:26px;padding:0 14px;font-family:var(--sg-font, \"Segoe UI\", system-ui, sans-serif);font-size:13px;color:var(--sg-fg, #242424);background:var(--sg-bg, #fff);border:1px solid var(--sg-border, #d1d1d1);border-radius:var(--sg-radius, 3px);cursor:pointer;}.sv-sheet-dialog-buttons .btn:hover:not(:disabled) {background:var(--sg-row-hover-bg, #f5f5f5);}.sv-sheet-dialog-buttons .btn:disabled {opacity:0.5;cursor:default;}.sv-sheet-dialog-buttons .btn.primary {color:var(--sg-on-accent, #fff);background:var(--sg-accent, #217346);border-color:var(--sg-accent, #217346);}.sv-sheet-dialog-buttons .btn.primary:hover:not(:disabled) {background:var(--sg-accent, #217346);filter:brightness(1.08);}.sv-sheet.svelte-1qw5b1f {display:flex;flex-direction:column;gap:0;\n /* A comment's mark is red on a spreadsheet whatever the theme, as the\n fill handle is the accent: the theme's danger colour, Excel's red\n where a theme has none. The grid's own amber is a data-grid\n convention, not a sheet's. */--sg-note-corner: var(--sg-danger, #c42b1c);font-family:var(--sg-font, \"Segoe UI\", system-ui, sans-serif);color:var(--sg-fg, #242424);background:var(--sg-bg-subtle, var(--sg-header-bg, #f3f3f3));\n /* A sheet's headers are 22px whatever a preset asks of a data grid's\n (Ember's are 48px), and its text is set solid: a host page's prose\n line-height must not stretch the rows. */--sg-header-min-height: 0px;line-height:1.3;}\n /* height=\"100%\": the shell is a flex item and the grid takes what the\n chrome leaves. min-height: 0 on both, or the flex item refuses to shrink\n below the grid's content and overflows exactly as a fixed height did. */.sv-sheet.fill.svelte-1qw5b1f {flex:1 1 0;min-height:0;height:100%;}.sheet-grid.svelte-1qw5b1f {display:flex;flex-direction:column;position:relative;border-top:1px solid var(--sg-border, #d9d9d9);}\n /* The comment editor's anchor: an invisible box laid over the cell,\n inert to the pointer so the cell under it still takes clicks. */\n /* Excel's dotted guide at the border being dragged, across the sheet. */\n /* Above the grid's sticky header (z-index 30), as Excel draws it through\n the header band too; the tip above everything the sheet draws. */.sheet-resize-guide.svelte-1qw5b1f {position:absolute;z-index:40;pointer-events:none;}.sheet-resize-guide.col.svelte-1qw5b1f {top:0;bottom:0;width:0;border-left:1px dotted var(--sg-fg, #242424);}.sheet-resize-guide.row.svelte-1qw5b1f {left:0;right:0;height:0;border-top:1px dotted var(--sg-fg, #242424);}\n /* Excel's resize tip, beside the pointer while a border is dragged. */.sheet-resize-tip.svelte-1qw5b1f {position:absolute;z-index:1000;padding:2px 6px;font-size:12px;line-height:1.4;white-space:nowrap;pointer-events:none;color:var(--sg-fg, #242424);background:var(--sg-bg, #fff);border:1px solid var(--sg-border, #d1d1d1);border-radius:3px;box-shadow:0 2px 6px rgba(0, 0, 0, 0.15);}\n /* The sparkline fills its cell, behind the text and out of the way of the\n pointer: the cell is still selected, dragged and edited as a cell. */.sheet-sparkline.svelte-1qw5b1f {position:absolute;inset:3px;display:flex;align-items:center;justify-content:center;pointer-events:none;overflow:hidden;}.sheet-cell-anchor.svelte-1qw5b1f {position:absolute;z-index:7;pointer-events:none;}.sheet-cell-anchor.svelte-1qw5b1f .box:where(.svelte-1qw5b1f) {display:inline-block;}.sheet-file-input.svelte-1qw5b1f {display:none;}\n /* The object layer: charts and pictures over the cells. The layer itself\n lets the pointer through, each object catches it. No z-index on the\n layer, so it makes no stacking context and each object is stacked\n against the grid's sticky cells on its own: an object in the scrolling\n pane under the frozen cells (z-index 30) and the frozen rows (31), one\n hung from a frozen cell over them, and all under the header (35).\n `overflow: clip` because an object's clip-path hides the part below the\n sheet's window but still counts as scrollable overflow: a chart hanging\n past the bottom made the page taller, and scrolling the sheet shrank it\n again, so a scrolled page jumped. `clip` rather than `hidden` keeps the\n layer from becoming a scroll container. */.sheet-object-layer.svelte-1qw5b1f {position:absolute;inset:0;overflow:clip;pointer-events:none;}.sheet-object.svelte-1qw5b1f {position:absolute;z-index:7;pointer-events:auto;background:var(--sg-bg, #fff);border:1px solid var(--sg-border, #d1d1d1);box-shadow:0 1px 4px rgb(0 0 0 / 12%);box-sizing:border-box;overflow:hidden;cursor:move;touch-action:none;}.sheet-object.frozen.svelte-1qw5b1f {z-index:32;}.sheet-object.dragging.svelte-1qw5b1f {z-index:33;}.sheet-object.selected.svelte-1qw5b1f {border-color:var(--sg-accent, #107c41);box-shadow:0 0 0 1px var(--sg-accent, #107c41), 0 2px 8px rgb(0 0 0 / 16%);}.sheet-object-inner.svelte-1qw5b1f {display:flex;flex-direction:column;width:100%;height:100%;padding:4px;box-sizing:border-box;}.sheet-object-title.svelte-1qw5b1f {padding:0 4px 2px;font-size:12px;font-weight:600;text-align:center;color:var(--sg-fg, #242424);}.sheet-object-image.svelte-1qw5b1f {display:block;width:100%;height:100%;object-fit:contain;user-select:none;}.sheet-object-grip.svelte-1qw5b1f {position:absolute;inset-inline-end:-1px;bottom:-1px;width:12px;height:12px;background:var(--sg-accent, #107c41);border:1px solid var(--sg-bg, #fff);cursor:nwse-resize;touch-action:none;}[dir=\"rtl\"] .sheet-object-grip.svelte-1qw5b1f {cursor:nesw-resize;}.sheet-trace-layer.svelte-1qw5b1f {position:absolute;inset:0;width:100%;height:100%;z-index:6;pointer-events:none;overflow:visible;}\n /* A cell drawn as a control. It sits over the cell's own text rather\n than replacing it, so the value stays visible to a screen reader and\n to a column that is only partly controlled. */.sheet-cell-control.svelte-1qw5b1f {position:absolute;inset:0;display:flex;align-items:center;justify-content:center;gap:6px;pointer-events:none;\n /* The control covers the cell's own TRUE / FALSE, so it has to carry\n the cell's background rather than a colour of its own. `inherit`\n takes whatever the cell computed to, which is the only thing that\n stays right across the themes and the banded rows. */background:inherit;}.sheet-cell-control.svelte-1qw5b1f > :where(.svelte-1qw5b1f),\n .sheet-cell-control.svelte-1qw5b1f input:where(.svelte-1qw5b1f),\n .sheet-cell-control.svelte-1qw5b1f label:where(.svelte-1qw5b1f) {pointer-events:auto;}.sheet-cell-control.checkbox.svelte-1qw5b1f input:where(.svelte-1qw5b1f) {margin:0;cursor:pointer;}.sheet-cell-control.button.svelte-1qw5b1f {font:inherit;font-size:11px;line-height:1;inset:2px;padding:0 8px;border:1px solid var(--sg-border, #c4c4c4);border-radius:3px;background:var(--sg-header-bg, #f3f3f3);color:inherit;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.sheet-cell-control.button.svelte-1qw5b1f:hover:not(:disabled) {background:var(--sg-row-hover-bg, #e8e8e8);}.sheet-cell-control.button.svelte-1qw5b1f:disabled {cursor:default;opacity:0.6;}.sheet-cell-control.radio.svelte-1qw5b1f {justify-content:flex-start;padding-inline:4px;font-size:11px;overflow:hidden;}.sheet-cell-control.radio.svelte-1qw5b1f label:where(.svelte-1qw5b1f) {display:inline-flex;align-items:center;gap:3px;cursor:pointer;white-space:nowrap;}.sheet-cell-control.radio.svelte-1qw5b1f input:where(.svelte-1qw5b1f) {margin:0;}\n /* Excel's outline bar, down the inline-start edge of the grid. Logical\n insets rather than `left`, so it sits on the correct side in RTL.\n\n Its width is a variable because two rules have to agree on it: the\n bar's own, and the inset that moves the grid out from under it. They\n did not agree when the second rule aimed at the wrong class, and the\n bar sat on top of the row numbers with nothing to say it had. */.sheet-grid.svelte-1qw5b1f {--sheet-outline-width: 18px;}.sheet-outline-bar.svelte-1qw5b1f {position:absolute;inset-block:0;inset-inline-start:0;width:var(--sheet-outline-width);z-index:7;pointer-events:none;background:var(--sg-header-bg, #f6f6f6);border-inline-end:1px solid var(--sg-border, #d4d4d4);}.sheet-outline-levels.svelte-1qw5b1f {position:absolute;inset-block-start:0;inset-inline:0;display:flex;flex-direction:column;align-items:center;gap:1px;padding-block-start:2px;pointer-events:auto;}.sheet-outline-level.svelte-1qw5b1f {width:13px;height:13px;padding:0;font:inherit;font-size:9px;line-height:1;border:1px solid var(--sg-border, #b4b4b4);border-radius:2px;background:var(--sg-bg, #fff);color:inherit;cursor:pointer;}.sheet-outline-level.svelte-1qw5b1f:hover {background:var(--sg-row-hover-bg, #eaeaea);}\n /* The bracket: a line down the rows a group owns, with a foot at each\n end, the way Excel draws one. */.sheet-outline-line.svelte-1qw5b1f {position:absolute;inset-inline-start:8px;width:1px;background:var(--sg-muted, #8a8a8a);}.sheet-outline-line.svelte-1qw5b1f::before,\n .sheet-outline-line.svelte-1qw5b1f::after {content:'';position:absolute;inset-inline-start:0;width:4px;height:1px;background:inherit;}.sheet-outline-line.svelte-1qw5b1f::before {top:0;}.sheet-outline-line.svelte-1qw5b1f::after {bottom:0;}.sheet-outline-toggle.svelte-1qw5b1f {position:absolute;inset-inline-start:3px;width:11px;height:11px;margin-block-start:-6px;padding:0;display:grid;place-items:center;font:inherit;font-size:10px;line-height:1;border:1px solid var(--sg-border, #8a8a8a);border-radius:1px;background:var(--sg-bg, #fff);color:inherit;cursor:pointer;pointer-events:auto;}.sheet-outline-toggle.svelte-1qw5b1f:hover {background:var(--sg-row-hover-bg, #eaeaea);}\n /* The grid gets out of the bar's way only while there is one to show.\n The root's class is `sv-grid-root`; aiming this at `.sv-grid` matched\n nothing, so the bar painted straight over the row numbers. */.sheet-grid.svelte-1qw5b1f:has(> .sheet-outline-bar:where(.svelte-1qw5b1f)) > .sv-grid-root {margin-inline-start:var(--sheet-outline-width);width:calc(100% - var(--sheet-outline-width));}\n /* Circle Invalid Data: a red oval on the cell's box, over its content. */.sheet-invalid-circle.svelte-1qw5b1f {position:absolute;inset:0;border:1.5px solid #d03a2c;border-radius:50%;pointer-events:none;z-index:3;}\n /* The Input Message: Excel's small pale box under the selected cell. */.sheet-input-message.svelte-1qw5b1f {position:absolute;z-index:7;max-width:240px;padding:4px 8px;font-size:12px;line-height:1.4;pointer-events:none;color:var(--sg-fg, #242424);background:var(--sg-bg, #fff);border:1px solid var(--sg-border, #d1d1d1);border-radius:3px;box-shadow:0 2px 6px rgba(0, 0, 0, 0.15);white-space:pre-wrap;}.sheet-input-message.svelte-1qw5b1f .title:where(.svelte-1qw5b1f) {font-weight:700;}\n /* Formula AutoComplete under the cell, styled as the formula bar's list. */.sheet-fn-suggest.svelte-1qw5b1f {position:absolute;z-index:40;margin:0;padding:2px;list-style:none;min-width:180px;max-height:220px;overflow-y:auto;border:1px solid var(--sg-border, #d1d1d1);border-radius:4px;background:var(--sg-bg, #fff);color:var(--sg-fg, #242424);box-shadow:0 8px 24px rgb(0 0 0 / 0.14);font-size:12px;}.sheet-fn-suggest.svelte-1qw5b1f button:where(.svelte-1qw5b1f) {display:block;width:100%;text-align:left;font:inherit;border:0;background:transparent;color:inherit;padding:4px 8px;border-radius:3px;cursor:pointer;}.sheet-fn-suggest.svelte-1qw5b1f button.active:where(.svelte-1qw5b1f),\n .sheet-fn-suggest.svelte-1qw5b1f button:where(.svelte-1qw5b1f):hover {background:var(--sg-row-hover-bg, #f0f0f0);}\n /* The in-cell dropdown arrow: a small button at the cell's right edge,\n above the cell text like the note corner. */.sheet-dropdown-arrow.svelte-1qw5b1f {position:absolute;top:50%;right:1px;transform:translateY(-50%);width:16px;height:16px;display:grid;place-items:center;padding:0;color:var(--sg-fg, #242424);background:var(--sg-bg, #fff);border:1px solid var(--sg-border, #d1d1d1);border-radius:2px;cursor:pointer;z-index:6;}.sheet-dropdown-arrow.svelte-1qw5b1f:hover {background:var(--sg-row-hover-bg, #f0f0f0);}\n /* The AutoFilter arrow on a header cell, a funnel once filtered. */.sheet-filter-arrow.svelte-1qw5b1f {position:absolute;top:50%;right:1px;transform:translateY(-50%);width:16px;height:16px;display:grid;place-items:center;padding:0;color:var(--sg-muted, #616161);background:var(--sg-bg, #fff);border:1px solid var(--sg-border, #d1d1d1);border-radius:2px;cursor:pointer;z-index:6;}.sheet-filter-arrow.svelte-1qw5b1f:hover {background:var(--sg-row-hover-bg, #f0f0f0);}.sheet-filter-arrow.filtered.svelte-1qw5b1f {color:color-mix(in srgb, var(--sg-info, #0f6cbd) 80%, var(--sg-fg, #242424));}\n /* Excel turns the row numbers of a filtered region blue. */\n /* Excel's blue row numbers under a filter. Mixed toward the text colour so\n a host theme whose info colour is a light cyan still clears 4.5:1 at the\n gutter's 13px; Excel's own #0f6cbd already does. */.sv-sheet.svelte-1qw5b1f tr.sheet-filtered > td.sv-grid-row-number-cell {color:color-mix(in srgb, var(--sg-info, #0f6cbd) 80%, var(--sg-fg, #242424));}\n /* A data bar behind the cell text, a third of the height off the edges\n as Excel draws it. */.sheet-databar.svelte-1qw5b1f {position:absolute;top:2px;bottom:2px;border-radius:1px;opacity:0.85;pointer-events:none;}.sheet-databar-axis.svelte-1qw5b1f {position:absolute;top:1px;bottom:1px;width:0;border-left:1px dashed var(--sg-muted, #616161);opacity:0.6;pointer-events:none;}\n /* Excel's marching ants: a dashed line on the cell's outline edges, the\n dashes walking clockwise. Drawn as background layers, one per edge, so\n it costs the compositor and nothing else; above the cell text and the\n data bar, under the editor and the note corner (z-index 6). Each layer\n is one 8px tile of the dash repeated along its edge, so sliding it a\n tile per cycle is seamless: a single full-width stretch slid the same\n way opened a gap at one end and closed it at the other, which read as\n a flicker rather than a walk. The walk is the signal that the sheet is\n in copy mode, as it is in Excel, so it is not switched off for\n prefers-reduced-motion: two pixels of dash, nothing else moves. */.sheet-ants.svelte-1qw5b1f {position:absolute;inset:0;z-index:5;pointer-events:none;--ants-on: var(--sg-fg, #242424);--ants-off: var(--sg-bg, #fff);--ants-top: none;--ants-bottom: none;--ants-left: none;--ants-right: none;background-image:var(--ants-top), var(--ants-bottom), var(--ants-left), var(--ants-right);background-repeat:repeat-x, repeat-x, repeat-y, repeat-y;background-size:8px 2px, 8px 2px, 2px 8px, 2px 8px;background-position:0 0, 0 100%, 0 0, 100% 0;\n animation: svelte-1qw5b1f-sheet-ants 0.35s linear infinite;}.sheet-ants.top.svelte-1qw5b1f {--ants-top: linear-gradient(to right, var(--ants-on) 0 4px, var(--ants-off) 4px 8px);}.sheet-ants.bottom.svelte-1qw5b1f {--ants-bottom: linear-gradient(to right, var(--ants-on) 0 4px, var(--ants-off) 4px 8px);}.sheet-ants.left.svelte-1qw5b1f {--ants-left: linear-gradient(to bottom, var(--ants-on) 0 4px, var(--ants-off) 4px 8px);}.sheet-ants.right.svelte-1qw5b1f {--ants-right: linear-gradient(to bottom, var(--ants-on) 0 4px, var(--ants-off) 4px 8px);}\n /* The dynamic array's outline: a thin blue rim on the spill the active cell is in. */.sheet-spill-edge.svelte-1qw5b1f {position:absolute;inset:0;z-index:4;pointer-events:none;--spill-c: var(--sg-accent, #2b6cb0);box-shadow:none;}.sheet-spill-edge.top.svelte-1qw5b1f {border-top:1px solid var(--spill-c);}.sheet-spill-edge.bottom.svelte-1qw5b1f {border-bottom:1px solid var(--spill-c);}.sheet-spill-edge.left.svelte-1qw5b1f {border-left:1px solid var(--spill-c);}.sheet-spill-edge.right.svelte-1qw5b1f {border-right:1px solid var(--spill-c);}\n @keyframes svelte-1qw5b1f-sheet-ants {\n to { background-position: 8px 0, -8px 100%, 0 -8px, 100% 8px; }\n }\n /* An icon at the left of the cell; the text keeps its own alignment. */.sheet-cell.has-icon.svelte-1qw5b1f {padding-left:20px;}.sheet-cf-icon.svelte-1qw5b1f {position:absolute;left:4px;top:50%;transform:translateY(-50%);}\n /* Show All Comments: a strip under the formula bar. */.sheet-comments.svelte-1qw5b1f {display:flex;flex-wrap:wrap;gap:4px 8px;max-height:96px;overflow-y:auto;padding:4px 8px;font-size:12px;border-top:1px solid var(--sg-border, #d9d9d9);background:var(--sg-bg-subtle, #f3f3f3);}.sheet-comments.svelte-1qw5b1f .none:where(.svelte-1qw5b1f) {color:var(--sg-muted, #616161);}.sheet-comments.svelte-1qw5b1f .entry:where(.svelte-1qw5b1f) {display:inline-flex;gap:6px;max-width:320px;padding:2px 8px;font:inherit;color:inherit;background:var(--sg-bg, #fff);border:1px solid var(--sg-border, #d9d9d9);border-radius:3px;cursor:pointer;}.sheet-comments.svelte-1qw5b1f .entry:where(.svelte-1qw5b1f):hover {background:var(--sg-row-hover-bg, #f0f0f0);}.sheet-comments.svelte-1qw5b1f .addr:where(.svelte-1qw5b1f) {font-weight:600;color:var(--sg-muted, #616161);}.sheet-comments.svelte-1qw5b1f .author:where(.svelte-1qw5b1f) {font-weight:600;}.sheet-comments.svelte-1qw5b1f .text.resolved:where(.svelte-1qw5b1f) {text-decoration:line-through;color:var(--sg-muted, #616161);}.sheet-comments.svelte-1qw5b1f .text:where(.svelte-1qw5b1f) {overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.sheet-grid.fill.svelte-1qw5b1f {flex:1 1 0;min-height:0;}\n /* The formula bar sits on the ribbon's grey ground, as it does in Excel. */.sv-sheet.svelte-1qw5b1f > .sv-formula-bar {margin:4px 6px;}.sv-sheet.svelte-1qw5b1f > .sv-ribbon {border-left:0;border-right:0;border-top:0;border-radius:0;}\n\n /*\n * Excel's own palette, light and dark with the page, for `look=\"excel\"`.\n * Tokens, so every part underneath - the grid included - picks them up.\n * The default look leaves every token to the host's theme.\n */.sv-sheet.look-excel.svelte-1qw5b1f {\n /* Excel's note mark is a red triangle. */--sg-note-corner: #c42b1c;--sg-bg: #ffffff;--sg-fg: #242424;--sg-muted: #616161;--sg-border: #d9d9d9;--sg-header-bg: #f3f3f3;--sg-header-fg: #444444;--sg-bg-subtle: #f3f3f3;--sg-row-alt-bg: #ffffff;--sg-row-hover-bg: #f0f0f0;--sg-muted-bg: #e6e6e6;--sg-selection-bg: rgba(16, 124, 65, 0.12);--sg-input-bg: #ffffff;--sg-input-border: #c8c6c4;--sg-accent: #107c41;--sg-on-accent: #ffffff;--sg-focus-ring: #107c41;--sg-success: #107c41;--sg-info: #0f6cbd;--sg-warning: #f2c811;--sg-danger: #c42b1c;--sg-radius: 0px;--sg-radius-lg: 6px;--sg-font: \"Aptos\", \"Aptos Narrow\", \"Segoe UI\", Calibri, Arial, sans-serif;}[data-theme=\"dark\"] .sv-sheet.look-excel.svelte-1qw5b1f {--sg-bg: #1f1f1f;--sg-fg: #e6e6e6;--sg-muted: #a6a6a6;--sg-border: #3d3d3d;--sg-header-bg: #2b2b2b;--sg-header-fg: #d0d0d0;--sg-bg-subtle: #292929;--sg-row-alt-bg: #1f1f1f;--sg-row-hover-bg: #363636;--sg-muted-bg: #404040;--sg-selection-bg: rgba(63, 166, 110, 0.2);--sg-input-bg: #262626;--sg-input-border: #4a4a4a;--sg-accent: #3fa66e;--sg-on-accent: #ffffff;--sg-focus-ring: #3fa66e;--sg-success: #3fa66e;--sg-info: #4cc2ff;--sg-warning: #f2c811;--sg-danger: #f1707b;}\n @media (prefers-color-scheme: dark) {:root:not([data-theme=\"light\"]) .sv-sheet.look-excel.svelte-1qw5b1f {--sg-bg: #1f1f1f;--sg-fg: #e6e6e6;--sg-muted: #a6a6a6;--sg-border: #3d3d3d;--sg-header-bg: #2b2b2b;--sg-header-fg: #d0d0d0;--sg-bg-subtle: #292929;--sg-row-alt-bg: #1f1f1f;--sg-row-hover-bg: #363636;--sg-muted-bg: #404040;--sg-selection-bg: rgba(63, 166, 110, 0.2);--sg-input-bg: #262626;--sg-input-border: #4a4a4a;--sg-accent: #3fa66e;--sg-on-accent: #ffffff;--sg-focus-ring: #3fa66e;--sg-success: #3fa66e;--sg-info: #4cc2ff;--sg-warning: #f2c811;--sg-danger: #f1707b;}\n }\n\n /* ---- the sheet's geometry ------------------------------------------ */\n /* Column letters: 22px, centred, plain weight; the gutter to match. */.sv-sheet.svelte-1qw5b1f .sv-grid-head .sv-grid-column {height:22px;padding:0;font-size:12px;font-weight:400;color:var(--sg-header-fg, var(--sg-muted, #444));}.sv-sheet.svelte-1qw5b1f .sv-grid-head .sv-grid-column .sv-grid-header-cell {justify-content:center;}.sv-sheet.svelte-1qw5b1f .sv-grid-head .sv-grid-column .sv-grid-header-sort {justify-content:center;}\n /* Row numbers are centred in the gutter, as Excel's are. */.sv-sheet.svelte-1qw5b1f .sv-grid-row-number-cell {font-size:12px;padding:0 4px;line-height:1.3;text-align:center;}.sv-sheet.svelte-1qw5b1f .sv-grid-head .sv-grid-column,\n .sv-sheet.svelte-1qw5b1f td.sv-grid-cell {line-height:1.3;}\n /*\n * Header borders, as Excel draws them: a hairline between every column\n * letter and under the header row, a hairline between every row number\n * and to the right of the gutter, and the Select All corner framed by\n * both. The grid fuses the gutter into the header band by painting its\n * right edge in the header colour; a sheet wants the line.\n */.sv-sheet.svelte-1qw5b1f .sv-grid-head .sv-grid-column {border-right:1px solid var(--sg-border, #d9d9d9);border-bottom:1px solid var(--sg-border, #d9d9d9);}\n /* A hidden column's letter takes no room at all: the hairline above\n would keep it a pixel wide. Its neighbours' lines meet at the seam,\n which is the doubled line Excel draws where a column is hidden. */.sv-sheet.svelte-1qw5b1f .sv-grid-head .sv-grid-column.sv-grid-column-collapsed {border-right-width:0;}\n /*\n * Where a column or a row is hidden, Excel thickens the header line at\n * the seam so the gap in the letters or numbers has a mark. The letter\n * after the fold carries a 2px left edge (a border, since the header's\n * selection shading uses its box-shadow); the number after hidden rows\n * a 2px top edge painted on a pseudo-element, since a border there would\n * push the row a pixel taller than the virtualizer laid it out.\n */.sv-sheet.svelte-1qw5b1f .sv-grid-head .sv-grid-column.sv-grid-column-collapsed + .sv-grid-column:not(.sv-grid-column-collapsed) {border-left:2px solid var(--sg-muted, #8a8a8a);}.sv-sheet.svelte-1qw5b1f tr.sv-grid-row-collapsed + tr:not(.sv-grid-row-collapsed) > td.sv-grid-row-number-cell::before {content:\"\";position:absolute;left:0;right:0;top:0;height:2px;background:var(--sg-muted, #8a8a8a);pointer-events:none;}.sv-sheet.svelte-1qw5b1f .sv-grid-row-number-column,\n .sv-sheet.svelte-1qw5b1f .sv-grid-row-number-cell {border-right:1px solid var(--sg-border, #d9d9d9);}\n /*\n * Excel shades the headers the selection touches - a step darker than the\n * header band, mixed from the text colour so it lands right on a dark\n * theme too - and marks them with a 2px line in the accent along the edge\n * that faces the cells. The line sits over the hairline, as Excel's does.\n */\n /* A column or row selected whole: the accent, white on green, as Excel's. */.sv-sheet.svelte-1qw5b1f th.sheet-col-whole,\n .sv-sheet.svelte-1qw5b1f th.sheet-col-whole .sv-grid-header-cell,\n .sv-sheet.svelte-1qw5b1f td.sv-grid-row-number-cell.sheet-row-whole {background:var(--sg-accent, #217346) !important;color:var(--sg-on-accent, #fff) !important;}.sv-sheet.svelte-1qw5b1f th.sheet-col-selected {background:color-mix(in srgb, var(--sg-fg, #242424) 13%, var(--sg-header-bg, #f3f3f3) 87%);color:var(--sg-fg, #242424);box-shadow:inset 0 -2px 0 0 var(--sg-accent, #107c41);}.sv-sheet.svelte-1qw5b1f tr:has(> td.sv-grid-cell-active) > td.sv-grid-row-number-cell,\n .sv-sheet.svelte-1qw5b1f tr:has(> td[data-selected-range=\"true\"]) > td.sv-grid-row-number-cell {background:color-mix(in srgb, var(--sg-fg, #242424) 13%, var(--sg-header-bg, #f3f3f3) 87%);color:var(--sg-fg, #242424);box-shadow:inset -2px 0 0 0 var(--sg-accent, #107c41);}\n /* No hover wash on cells: a sheet does not light rows up under the mouse. */.sv-sheet.svelte-1qw5b1f tbody tr:hover > .sv-grid-cell:not([data-selected-range=\"true\"]):not(.sv-grid-row-number-cell) {background-color:var(--sg-bg, #fff);}.sv-sheet.svelte-1qw5b1f .sv-grid-cell {font-size:13px;}\n\n /*\n * The selection rectangle, as Excel draws it: the range tinted and framed\n * by a 2px line in the accent, the active cell inside it left unshaded\n * with no ring of its own (the frame is the ring), and the fill handle a\n * small square on the bottom-right corner, ringed in the sheet colour so\n * it reads against the frame. A lone active cell is a one-cell range and\n * gets the same frame, white inside.\n *\n * Painted on a pseudo-element ABOVE the cell's content rather than on the\n * td itself. The grid draws the tint as the td's background and the frame\n * as inset shadows, both of which sit under the td's children - and the\n * sheet's cell span now covers the whole td, so on a filled cell the\n * selection vanished under the fill. The overlay is translucent, so a\n * fill inside a selection reads a shade darker, which is what Excel shows.\n *\n * The tint is the theme's accent at a low alpha, not `--sg-selection-bg`:\n * that token is an opaque surface in most themes (Ember's is #ffece3),\n * and an opaque overlay above the content hid the text of every selected\n * cell but the active one. Excel's own tint is its green at 12%.\n */.sv-sheet.svelte-1qw5b1f td.sv-grid-cell[data-selected-range=\"true\"],\n .sv-sheet.svelte-1qw5b1f td.sv-grid-cell-active {background:var(--sg-bg, #fff);box-shadow:none;}.sv-sheet.svelte-1qw5b1f td.sv-grid-cell[data-selected-range=\"true\"]::after,\n .sv-sheet.svelte-1qw5b1f td.sv-grid-cell-active::after {content:\"\";position:absolute;inset:0;z-index:2;pointer-events:none;background:color-mix(in srgb, var(--sg-accent, #107c41) 14%, transparent);box-shadow:var(--sv-range-top), var(--sv-range-bottom), var(--sv-range-left), var(--sv-range-right);}\n /* The active cell: no tint, and a frame of its own only when it is not\n inside a range, whose frame it otherwise shares. Written out with the\n range attribute so it outranks the tint rule above; with a shorter\n selector the active cell inside a range was tinted like the rest, and\n Excel leaves it white. */.sv-sheet.svelte-1qw5b1f td.sv-grid-cell-active::after,\n .sv-sheet.svelte-1qw5b1f td.sv-grid-cell.sv-grid-cell-active[data-selected-range=\"true\"]::after {background:transparent;}.sv-sheet.svelte-1qw5b1f td.sv-grid-cell-active:not([data-selected-range=\"true\"])::after {box-shadow:inset 0 0 0 2px var(--sg-accent, #107c41);}\n /* Nothing over the editor while a cell is being typed into. */.sv-sheet.svelte-1qw5b1f td.sv-grid-cell-editing::after {display:none;}.sv-sheet.svelte-1qw5b1f .sv-grid-fill-handle {width:8px;height:8px;right:-1px;bottom:-1px;border:1px solid var(--sg-bg, #fff);border-radius:0;}.sv-sheet.svelte-1qw5b1f .sv-grid-fill-handle:hover {transform:none;}\n\n /* Headers respond to the pointer the way Excel's do: a shade darker under\n it, and the cursor says what a click will select. */.sv-sheet.svelte-1qw5b1f .sv-grid-head .sv-grid-column:hover,\n .sv-sheet.svelte-1qw5b1f td.sv-grid-row-number-cell:hover {background:color-mix(in srgb, var(--sg-fg, #242424) 7%, var(--sg-header-bg, #f3f3f3) 93%);}\n /*\n * Excel's cursors: the white cross over the cells, a black arrow pointing\n * down the column over a letter and along the row over a number (drawn,\n * since no CSS cursor is one; the hotspot is the tip), the plain arrow\n * over the corner, and the double-headed arrows on the borders. The\n * fill handle's crosshair and the selection border's move cursor are\n * the grid's own.\n */.sv-sheet.svelte-1qw5b1f td.sv-grid-cell:not(.sv-grid-row-number-cell):not(.sv-grid-cell-editing) {cursor:cell;}.sv-sheet.svelte-1qw5b1f .sv-grid-head .sv-grid-column[data-svgrid-header-col],\n .sv-sheet.svelte-1qw5b1f .sv-grid-head .sv-grid-column[data-svgrid-header-col] .sv-grid-header-sort,\n .sv-sheet.svelte-1qw5b1f .sv-grid-head .sv-grid-column[data-svgrid-header-col] .sv-grid-header-cell {cursor:url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path d='M8 14.5L2.2 8.2h3.6V1.5h4.4v6.7h3.6z' fill='%23000' stroke='%23fff' stroke-width='1.2' stroke-linejoin='round'/></svg>\") 8 15, pointer;}.sv-sheet.svelte-1qw5b1f td.sv-grid-row-number-cell {cursor:url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path d='M14.5 8L8.2 13.8v-3.6H1.5V5.8h6.7V2.2z' fill='%23000' stroke='%23fff' stroke-width='1.2' stroke-linejoin='round'/></svg>\") 15 8, pointer;}.sv-sheet.svelte-1qw5b1f th.sv-grid-row-number-column {cursor:default;}.sv-sheet.svelte-1qw5b1f .sv-grid-resize-handle {cursor:col-resize;}.sv-sheet.svelte-1qw5b1f .sv-grid-row-resize-handle {cursor:row-resize;}\n\n /* The in-cell editor, widened over the neighbours while a long formula\n is typed: the cell it sits in is already lifted above the row. */.sv-sheet.svelte-1qw5b1f td.sv-grid-cell-editing {overflow:visible;}.sv-sheet.svelte-1qw5b1f td.sv-grid-cell-editing .sv-grid-cell-editor {position:relative;z-index:2;max-width:none;background:var(--sg-bg, #fff);}\n\n /* A cell a formula in progress refers to, in that reference's colour.\n An overlay too, for the same reason as the selection's: a filled cell\n would otherwise hide it. Translucent, so the fill shows through. */.sv-sheet.svelte-1qw5b1f td[data-sheet-ref]::before {content:\"\";position:absolute;inset:0;z-index:2;pointer-events:none;box-shadow:var(--sheet-ref-edges, none);background:color-mix(in srgb, var(--sheet-ref) 12%, transparent);}\n /* The editor's text under the coloured mirror: only the caret shows. */.sv-sheet.svelte-1qw5b1f .sv-grid-cell-editor.sheet-ref-text {color:transparent;caret-color:var(--sg-fg, #242424);}\n /* Format Painter armed: a brush for a pointer, as Excel shows. */.sheet-grid.painting.svelte-1qw5b1f td.sv-grid-cell {cursor:url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 18 18'><path d='M10.2 2.4l5.4 5.4-3.6 3.6-5.4-5.4z' fill='%23fff' stroke='%23222' stroke-width='1.4' stroke-linejoin='round'/><path d='M6.6 6L3.2 9.4a1.8 1.8 0 0 0 0 2.6l2.8 2.8a1.8 1.8 0 0 0 2.6 0L12 11.4' fill='none' stroke='%23222' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/></svg>\") 3 15, cell;}.sv-sheet.svelte-1qw5b1f .sheet-ref-mirror {position:absolute;z-index:21;overflow:hidden;white-space:pre-wrap;overflow-wrap:break-word;color:var(--sg-fg, #242424);pointer-events:none;background:transparent;}\n\n /* The Select All corner: a triangle pointing into the sheet. */.corner.svelte-1qw5b1f {display:block;width:100%;height:100%;position:relative;}.corner.svelte-1qw5b1f::after {content:\"\";position:absolute;right:3px;bottom:3px;border-style:solid;border-width:0 0 9px 9px;border-color:transparent transparent var(--sg-muted, #b0b0b0) transparent;}\n\n /*\n * A sheet cell fills its td edge to edge, so a fill colour reaches the\n * gridlines the way it does in Excel rather than leaving a halo of cell\n * background around it.\n *\n * The grid pads a left-aligned td by 12px and a block child only rises to\n * its own line height, so a fill used to stop short on the left and leave\n * a hairline top and bottom. The td gives up its padding and the span is\n * laid over the td's whole box instead, and does its own padding. A grid\n * container rather than a block so the text centres vertically at any row\n * height, including one the user has dragged taller. Text that does not\n * fit is cut at the edge, as Excel cuts it, not ellipsised.\n */.sv-sheet.svelte-1qw5b1f td.sv-grid-cell:not(.sv-grid-row-number-cell) {padding:0;position:relative;}.sheet-cell.svelte-1qw5b1f {position:absolute;inset:0;display:grid;align-items:center;padding:0 4px;line-height:1.3;white-space:nowrap;overflow:hidden;}\n /* The table style: a filled header, a tinted band on alternate rows, a\n line over the totals. Behind everything the cell itself draws, and out\n of the pointer's way. */.sheet-table-fill.svelte-1qw5b1f {position:absolute;inset:0;pointer-events:none;}.sheet-table-fill.header.svelte-1qw5b1f {background:var(--sheet-table-header, color-mix(in srgb, var(--sg-accent, #107c41) 16%, transparent));border-bottom:1px solid var(--sheet-table-border, color-mix(in srgb, var(--sg-accent, #107c41) 45%, transparent));}.sheet-table-fill.band.svelte-1qw5b1f {background:var(--sheet-table-band, color-mix(in srgb, var(--sg-accent, #107c41) 7%, transparent));}.sheet-table-fill.totals.svelte-1qw5b1f {background:var(--sheet-table-totals, color-mix(in srgb, var(--sg-accent, #107c41) 12%, transparent));border-top:1px solid var(--sheet-table-border, color-mix(in srgb, var(--sg-accent, #107c41) 45%, transparent));}\n\n /* A picture in the cell: fitted inside it, and out of the pointer's way\n so the cell is selected, dragged and typed into as a cell. */.sheet-cell-image.svelte-1qw5b1f {position:absolute;inset:1px 2px;width:calc(100% - 4px);height:calc(100% - 2px);object-fit:contain;pointer-events:none;}\n\n /* Presence: a thin box in the person's colour around their selection, and\n a tag on their cursor. Over the cells, out of the pointer's way, and\n never in the way of reading a number: the box is a border, not a fill. */.sheet-presence-layer.svelte-1qw5b1f {position:absolute;inset:0;pointer-events:none;z-index:4;}.sheet-presence.svelte-1qw5b1f {position:absolute;border:2px solid var(--sheet-presence-colour, #2563eb);border-radius:2px;background:color-mix(in srgb, var(--sheet-presence-colour, #2563eb) 8%, transparent);}.sheet-presence-tag.svelte-1qw5b1f {position:absolute;transform:translateY(-100%);padding:1px 5px;border-radius:3px 3px 3px 0;z-index:1;background:var(--sheet-presence-colour, #2563eb);color:#fff;font-size:11px;line-height:1.5;white-space:nowrap;max-width:160px;overflow:hidden;text-overflow:ellipsis;}\n /* No room above: under the cell, the corner turned the other way. */.sheet-presence-tag.below.svelte-1qw5b1f {transform:none;border-radius:0 3px 3px 3px;}\n\n /* Excel's link: the theme's link colour, underlined, and a hand over it.\n The cell is still a cell - it is selected, dragged and typed into the\n same way - so this is a span rather than an anchor. */.sheet-cell.linked.svelte-1qw5b1f {color:var(--sg-info, #0f6cbd);text-decoration:underline;text-underline-offset:2px;cursor:pointer;}.sheet-cell.linked.svelte-1qw5b1f:hover {color:color-mix(in srgb, var(--sg-info, #0f6cbd) 80%, var(--sg-fg, #242424));}.sheet-cell.formula.svelte-1qw5b1f {font-family:ui-monospace, Menlo, monospace;color:var(--sg-accent, #107c41);}\n\n /*\n * Text spilling over empty neighbours, as in Excel. The grid's td clips\n * its content; for a spilling cell it is opened up, and the span grows to\n * its text (capped at the run of empty cells) and paints its own\n * background over the neighbours, which also hides the gridlines under\n * the text the way Excel does. z-index lifts it above the later tds in\n * the row, which would otherwise paint over it in DOM order.\n */.sv-sheet.svelte-1qw5b1f td.sv-grid-cell:has(> .sheet-cell.spill) {overflow:visible;}.sheet-cell.spill.svelte-1qw5b1f {right:auto;z-index:1;width:max-content;min-width:100%;background:var(--sg-bg, #fff);}\n\n /* ---- View > Show --------------------------------------------------- */\n /* Gridlines off keeps the cell geometry (the borders go transparent, so\n nothing shifts) and leaves the borders a cell has of its own. */.sv-sheet.no-gridlines.svelte-1qw5b1f td.sv-grid-cell {border-color:transparent;}.sv-sheet.no-headings.svelte-1qw5b1f .sv-grid-head {display:none;}\n\n /* ---- status bar ---------------------------------------------------- */.status.svelte-1qw5b1f {display:flex;align-items:center;gap:18px;height:22px;padding:0 10px;font-size:12px;\n /* Explicit: a host page that uppercases small text turns \"Count\" into\n \"COUNT\", which reads as shouting rather than as a status bar. */text-transform:none;letter-spacing:normal;color:var(--sg-fg, #242424);border-top:1px solid var(--sg-border, #d9d9d9);background:var(--sg-header-bg, #f3f3f3);}.status.svelte-1qw5b1f .grow:where(.svelte-1qw5b1f) {flex:1 1 auto;}.status.svelte-1qw5b1f .mode:where(.svelte-1qw5b1f) {color:var(--sg-muted, #616161);}.status.svelte-1qw5b1f b:where(.svelte-1qw5b1f) {font-weight:400;font-variant-numeric:tabular-nums;}"
|
|
38470
38475
|
};
|
|
38471
38476
|
function lL(e, t) {
|
|
38472
38477
|
M(t, !0), v(e, cL);
|
|
@@ -8,69 +8,69 @@ function t(t) {
|
|
|
8
8
|
}
|
|
9
9
|
//#endregion
|
|
10
10
|
//#region ../grid/dist/validate.js
|
|
11
|
-
var n = 10, r = "https://svgrid.com/docs/getting-started/3-data-and-columns/";
|
|
12
|
-
function
|
|
13
|
-
for (let n of e) n.columns?.length ?
|
|
11
|
+
var n = 10, r = 1e3, i = "https://svgrid.com/docs/getting-started/3-data-and-columns/";
|
|
12
|
+
function a(e, t = []) {
|
|
13
|
+
for (let n of e) n.columns?.length ? a(n.columns, t) : t.push(n);
|
|
14
14
|
return t;
|
|
15
15
|
}
|
|
16
|
-
function
|
|
17
|
-
let
|
|
18
|
-
for (let
|
|
19
|
-
|
|
20
|
-
t(
|
|
16
|
+
function o(e) {
|
|
17
|
+
let o = [], c = a(e.columns ?? []), l = [], u = e.data ?? [], d = Math.min(u.length, r);
|
|
18
|
+
for (let e = 0; e < d && l.length < n; e += 1) {
|
|
19
|
+
let n = u[e];
|
|
20
|
+
t(n) || l.push(n);
|
|
21
21
|
}
|
|
22
|
-
if (
|
|
22
|
+
if (l.length && !e.serverGroup) {
|
|
23
23
|
let e = /* @__PURE__ */ new Set();
|
|
24
|
-
for (let t of
|
|
25
|
-
for (let t of
|
|
24
|
+
for (let t of l) if (t && typeof t == "object") for (let n of Object.keys(t)) e.add(n);
|
|
25
|
+
for (let t of c) {
|
|
26
26
|
let n = t.field;
|
|
27
27
|
if (!n || t.fieldFn || e.has(n)) continue;
|
|
28
|
-
let
|
|
29
|
-
|
|
28
|
+
let r = s(n, [...e]);
|
|
29
|
+
o.push(`[svgrid] Column field "${n}" does not exist on your row data, so that column renders empty.${r ? ` Did you mean "${r}"?` : ""} Available keys: ${[...e].slice(0, 12).join(", ")}. See ${i}`);
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
|
-
let
|
|
33
|
-
for (let e of
|
|
32
|
+
let f = /* @__PURE__ */ new Map();
|
|
33
|
+
for (let e of c) {
|
|
34
34
|
let t = e.id ?? e.field;
|
|
35
|
-
t &&
|
|
35
|
+
t && f.set(t, (f.get(t) ?? 0) + 1);
|
|
36
36
|
}
|
|
37
|
-
for (let [e, t] of
|
|
38
|
-
let
|
|
39
|
-
e.pageSize !== void 0 &&
|
|
40
|
-
let
|
|
41
|
-
for (let e of
|
|
37
|
+
for (let [e, t] of f) t > 1 && o.push(`[svgrid] ${t} columns share the id "${e}". Column state (sorting, filtering, pinning, width) is keyed by id, so they will act as one. Give each an explicit \`id\`. See ${i}`);
|
|
38
|
+
let p = e.pageable === void 0 && e.showPagination === void 0;
|
|
39
|
+
e.pageSize !== void 0 && p && o.push("[svgrid] `pageSize` is set but pagination was never turned on, so it has no effect and every row renders. Add `pageable` to switch the pager on."), !(e.sortable === !0 || e.features?.rowSortingFeature) && c.some((e) => e.sortable === !0) && o.push("[svgrid] A column sets `sortable: true`, but sorting is not enabled on the grid, so its header does nothing. Add `sortable` to <SvGrid> (it registers the sorting feature for you).");
|
|
40
|
+
let m = /* @__PURE__ */ new Set();
|
|
41
|
+
for (let e of c) {
|
|
42
42
|
let t = e.id ?? e.field;
|
|
43
|
-
t &&
|
|
43
|
+
t && m.add(t);
|
|
44
44
|
}
|
|
45
45
|
for (let t of e.groupBy ?? []) {
|
|
46
|
-
if (
|
|
47
|
-
let e =
|
|
48
|
-
|
|
46
|
+
if (m.has(t)) continue;
|
|
47
|
+
let e = s(t, [...m]);
|
|
48
|
+
o.push(`[svgrid] \`groupBy\` refers to column "${t}", which does not exist, so that grouping level is ignored.${e ? ` Did you mean "${e}"?` : ""} Column ids: ${[...m].slice(0, 12).join(", ")}`);
|
|
49
49
|
}
|
|
50
|
-
let
|
|
51
|
-
if (
|
|
50
|
+
let h = e.treeData?.column;
|
|
51
|
+
if (h && !m.has(h) && o.push(`[svgrid] \`treeData.column\` refers to column "${h}", which does not exist, so the expander falls back to the first visible column.`), l.length && e.treeData) {
|
|
52
52
|
let t = /* @__PURE__ */ new Set();
|
|
53
|
-
for (let e of
|
|
53
|
+
for (let e of l) if (e && typeof e == "object") for (let n of Object.keys(e)) t.add(n);
|
|
54
54
|
let n = e.treeData.parentField;
|
|
55
55
|
if (n && !t.has(n)) {
|
|
56
|
-
let e =
|
|
57
|
-
|
|
56
|
+
let e = s(n, [...t]);
|
|
57
|
+
o.push(`[svgrid] \`treeData.parentField\` is "${n}", which is not on your row data, so every row becomes a root and no hierarchy appears.${e ? ` Did you mean "${e}"?` : ""}`);
|
|
58
58
|
}
|
|
59
59
|
let r = e.treeData.idField;
|
|
60
|
-
r && !t.has(r) &&
|
|
60
|
+
r && !t.has(r) && o.push(`[svgrid] \`treeData.idField\` is "${r}", which is not on your row data, so parent lookups cannot match and the tree stays flat.`);
|
|
61
61
|
}
|
|
62
|
-
return e.gantt && e.treeData &&
|
|
62
|
+
return e.gantt && e.treeData && o.push("[svgrid] `gantt` and `treeData` are both set. The Gantt builds its own work-breakdown tree from `gantt.parentField` and needs every descendant row, but `treeData` hides collapsed children from the view, so summary bars will under-report. Remove `treeData` and set `gantt.parentField` instead."), (e.initialColumnPinning?.left?.length ?? 0) + (e.initialColumnPinning?.right?.length ?? 0) > 0 && e.columnVirtualization !== !1 && o.push("[svgrid] `initialColumnPinning` is set while column virtualization is on (its default), so the pinned columns will not stick - the virtualizer recycles column nodes. Add `columnVirtualization={false}`."), e.externalPagination === !0 && e.rowCount === void 0 && o.push("[svgrid] `externalPagination` is on but `rowCount` is not set, so the pager cannot know how many pages exist. Pass the server total as `rowCount`."), e.externalSort === !0 && !e.onSortingChange && o.push("[svgrid] `externalSort` is on but there is no `onSortingChange` handler, so clicking a header changes nothing - the grid stopped sorting and nobody is listening. Add `onSortingChange` and re-fetch in your handler."), e.externalFilter === !0 && !e.onFiltersChange && o.push("[svgrid] `externalFilter` is on but there is no `onFiltersChange` handler, so filtering the grid changes nothing. Add `onFiltersChange` and re-fetch in your handler."), o;
|
|
63
63
|
}
|
|
64
|
-
function
|
|
64
|
+
function s(e, t) {
|
|
65
65
|
let n, r = Infinity;
|
|
66
66
|
for (let i of t) {
|
|
67
|
-
let t =
|
|
67
|
+
let t = c(e.toLowerCase(), i.toLowerCase());
|
|
68
68
|
t < r && (r = t, n = i);
|
|
69
69
|
}
|
|
70
70
|
let i = Math.min(3, Math.floor(e.length / 3) + 1);
|
|
71
71
|
return r <= i ? n : void 0;
|
|
72
72
|
}
|
|
73
|
-
function
|
|
73
|
+
function c(e, t) {
|
|
74
74
|
if (e === t) return 0;
|
|
75
75
|
let n = Array(t.length + 1);
|
|
76
76
|
for (let e = 0; e <= t.length; e++) n[e] = e;
|
|
@@ -85,4 +85,4 @@ function s(e, t) {
|
|
|
85
85
|
return n[t.length];
|
|
86
86
|
}
|
|
87
87
|
//#endregion
|
|
88
|
-
export {
|
|
88
|
+
export { o as validateGridConfig };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The query engine behind `serveWorkerDataSource`: the in-memory reference
|
|
3
|
+
* source's answers, computed over columns instead of row objects.
|
|
4
|
+
*
|
|
5
|
+
* Each field becomes a dictionary - its distinct values, and one integer code
|
|
6
|
+
* per row - built once, in the background, while the worker is idle. Then:
|
|
7
|
+
*
|
|
8
|
+
* - A filter is decided once per DISTINCT value, with the reference's own
|
|
9
|
+
* `matchesPredicate`, and a row passes when its code does. Searching a
|
|
10
|
+
* million rows of 80 customers tests 80 strings.
|
|
11
|
+
* - A sort ranks the distinct values once (numerically, or with the same
|
|
12
|
+
* collator the reference uses) and orders rows with a stable counting sort
|
|
13
|
+
* over the ranks: integer work, linear in the row count, no string compares.
|
|
14
|
+
* - A grouping buckets rows by code and accumulates aggregates in row order,
|
|
15
|
+
* so sums come out bit-for-bit what the reference adds up.
|
|
16
|
+
*
|
|
17
|
+
* Exact equivalence is the contract, not a goal: anything this engine does
|
|
18
|
+
* not accelerate goes to the reference source holding the same rows - the
|
|
19
|
+
* advanced filter expression, pivot, and a sort on a column that mixes
|
|
20
|
+
* numbers with other values (where the reference's comparison is not a
|
|
21
|
+
* total order, so there is no ranking to reproduce). Writes go through the
|
|
22
|
+
* reference too, and the columns are rebuilt from its rows.
|
|
23
|
+
*/
|
|
24
|
+
import type { RowData, ServerDataSource } from '@svgrid/grid';
|
|
25
|
+
import type { EntitySchema } from '../schema.js';
|
|
26
|
+
import type { AggregateBucket, AggregateRequest } from '../sources/aggregate.js';
|
|
27
|
+
export type ColumnarDataSource<TData extends RowData> = Required<Pick<ServerDataSource<TData>, 'getRows' | 'createRow' | 'updateRow' | 'deleteRow' | 'updateWhere'>> & {
|
|
28
|
+
getAggregate(request: AggregateRequest): Promise<AggregateBucket[]>;
|
|
29
|
+
rows(): ReadonlyArray<TData>;
|
|
30
|
+
/**
|
|
31
|
+
* Build one more column's dictionary and ranks. Returns false once every
|
|
32
|
+
* schema field is built. `serveWorkerDataSource` calls it between requests,
|
|
33
|
+
* so the first sort on any column finds its work already done.
|
|
34
|
+
*/
|
|
35
|
+
warm(): boolean;
|
|
36
|
+
/** How many requests this engine answered, and how many it handed to the reference. */
|
|
37
|
+
stats(): {
|
|
38
|
+
columnar: number;
|
|
39
|
+
reference: number;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
export declare function createColumnarDataSource<TData extends RowData>(initial: ReadonlyArray<TData>, schema: EntitySchema<TData>): ColumnarDataSource<TData>;
|