staffa 0.16.0 → 0.17.1
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/README.md +1 -1
- package/dist/components/menu.d.ts +18 -7
- package/dist/components/menu.js +52 -21
- package/dist/components/panels.d.ts +10 -7
- package/dist/components/panels.js +12 -9
- package/dist/components/tooltip.js +9 -2
- package/dist/staffa.esm.js +1 -1
- package/package.json +1 -1
- package/skill/MenuItem.md +16 -6
- package/skill/Panel.md +3 -3
- package/skill/SKILL.md +1 -1
- package/src/components/menu.ts +71 -27
- package/src/components/panels.ts +15 -12
- package/src/components/tooltip.ts +8 -2
package/README.md
CHANGED
|
@@ -164,7 +164,7 @@ Each handler gets a `$panel` proxy: the params from its route, plus what the she
|
|
|
164
164
|
|
|
165
165
|
**The stack is an object, not a global.** `S.main()` hands back the `PanelStack` — `pushPanel`, `replacePanel`, `openPanelStack`, `closePanel`, and the live, reactive `panels` / `currentPanel` / `currentPanelIndex` — and every panel gets that same object as `$panel.stack`, which is what a route handler uses, since it runs while the `S.main()` call is still going. Every navigation settles asynchronously (closes travel through the browser's history), so each method returns a `Promise<boolean>`. Don't hold a `Panel` across a navigation; read it fresh. To navigate on behalf of one particular screen — a row's click handler — use that panel's own `$panel.open(href, how?)`, which does exactly what a link inside it does; `pushPanel` builds on the *current* panel instead.
|
|
166
166
|
|
|
167
|
-
**Columns and widths.** The content area is the window minus the nav sidebar, or `S.main({ maxWidth })` of it, centred — the same width whatever is open, so the sidebar, top bar and footer never move. It divides into the
|
|
167
|
+
**Columns and widths.** The content area is the window minus the nav sidebar, or `S.main({ maxWidth })` of it, centred — the same width whatever is open, so the sidebar, top bar and footer never move. It divides into the fewest whole number of columns of at most **540px** each, never narrower than **360px**; `$panel.maxWidth` asks for one, two (the default), three of them or the lot. A column's width depends only on the window, never on what else is open, so opening or closing a panel never resizes another. Its ask is a ceiling, never a floor: aim your layout at 360px and let it degrade gracefully below that. `$panel.width` is the resolved figure in pixels, correct before your handler draws.
|
|
168
168
|
|
|
169
169
|
**A panel declares its chrome; the shell places it.** A screen says what it is called and what it can do; everything else in its column — headings, cards, boxes — is the screen's own content, drawn like any other.
|
|
170
170
|
|
|
@@ -29,12 +29,14 @@ export interface MenuItem {
|
|
|
29
29
|
/**
|
|
30
30
|
* A keyboard shortcut that activates this item: `"mod+k"`, `"f2"`, a bare
|
|
31
31
|
* `"?"`. The spelling, and which keystrokes are yours to take, are
|
|
32
|
-
* documented on {@link bindKey}.
|
|
33
|
-
* the row (not on a touch device)
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
32
|
+
* documented on {@link bindKey}. In a dropdown or context menu the
|
|
33
|
+
* combination shows at the right end of the row (not on a touch device); a
|
|
34
|
+
* nav row — `S.main`'s sidebar, {@link menu} — keeps its label clean and
|
|
35
|
+
* tells it in its {@link MenuItem.tooltip | tooltip} instead. Either way
|
|
36
|
+
* it reaches screen readers as `aria-keyshortcuts`, and the `?` overview
|
|
37
|
+
* ({@link showKeyHelp}) lists it under the item's label. Activating runs
|
|
38
|
+
* `click` with the `KeyboardEvent` and follows `href` as a fresh navigation
|
|
39
|
+
* to it — the target getting its own panel stack, as a nav item's does.
|
|
38
40
|
*
|
|
39
41
|
* The shortcut works with the menu shut — rather the point of one on a
|
|
40
42
|
* dropdown or context menu — for as long as whatever owns the items is
|
|
@@ -44,6 +46,12 @@ export interface MenuItem {
|
|
|
44
46
|
* not bound.
|
|
45
47
|
*/
|
|
46
48
|
key?: string;
|
|
49
|
+
/**
|
|
50
|
+
* A tooltip for this item, shown on hover and keyboard focus. A string
|
|
51
|
+
* renders as rich text. In a nav, the item's `key` is shown underneath it,
|
|
52
|
+
* behind a subtle separator (see {@link MenuItem.key}).
|
|
53
|
+
*/
|
|
54
|
+
tooltip?: Slot;
|
|
47
55
|
/**
|
|
48
56
|
* Pages this item claims *beyond* its own `href`: a string claims that path
|
|
49
57
|
* and everything under it (`"/mail"` claims `/mail/…`, not `/mailbox`), a
|
|
@@ -171,8 +179,11 @@ export type ContextMenuOptions = Omit<FloatingMenuOptions, "anchor" | "at" | "cl
|
|
|
171
179
|
* @param onLeafSelect Optional — run when a *leaf* item is activated (used by
|
|
172
180
|
* the floating menu to close itself on selection). A branch expanding is
|
|
173
181
|
* not a selection, so it doesn't run this.
|
|
182
|
+
* @param keyHints Print each row's `key` at its right end, as the floating
|
|
183
|
+
* menus do. Off — any kind of nav — a row tells its key in its tooltip
|
|
184
|
+
* instead, keeping the resting rows quiet.
|
|
174
185
|
*/
|
|
175
|
-
export declare function drawMenu(items: MenuEntry[], onLeafSelect?: () => void): void;
|
|
186
|
+
export declare function drawMenu(items: MenuEntry[], onLeafSelect?: () => void, keyHints?: boolean): void;
|
|
176
187
|
/**
|
|
177
188
|
* Whether any item anywhere in `items` — branches, their leaves, `match` claims — is
|
|
178
189
|
* the current page. Exported because the shell's tagline rule (`taglineFits` in
|
package/dist/components/menu.js
CHANGED
|
@@ -4,6 +4,7 @@ import { drawSlot, mountPortal, focusFirst } from "../core.js";
|
|
|
4
4
|
import { menu as menuIcon, chevronRight, externalLink as newTabIcon, link as linkIcon } from "../icons.js";
|
|
5
5
|
import { button } from "./button.js";
|
|
6
6
|
import { toast } from "./toast.js";
|
|
7
|
+
import { addTooltip } from "./tooltip.js";
|
|
7
8
|
import { bindKey, formatKey } from "../keys.js";
|
|
8
9
|
// Styles shared by the floating dropdown and the sidebar nav. The item styles
|
|
9
10
|
// aren't scoped to a container, so `drawMenu` can render into either one.
|
|
@@ -62,6 +63,11 @@ A.insertGlobalCss({
|
|
|
62
63
|
"@media (hover: none) and (pointer: coarse)": {
|
|
63
64
|
".s-menu-key": "display:none",
|
|
64
65
|
},
|
|
66
|
+
// A nav row's key rides its tooltip instead (see `drawHints`): a quiet line of
|
|
67
|
+
// its own, under the item's tip content when it has one, split off by the
|
|
68
|
+
// menu's own fading hairline.
|
|
69
|
+
".s-menu-tt-key": "font-family:inherit font-size:0.85em opacity:0.7 white-space:nowrap",
|
|
70
|
+
".s-tt-tip hr.s-menu-sep": "margin: 0.35em 0;",
|
|
65
71
|
// A branch row's fold indicator: a › that turns downward while the branch is open.
|
|
66
72
|
".s-menu-chevron": "margin-left:auto flex-shrink:0 display:flex transition: transform 0.15s ease;",
|
|
67
73
|
// Two `margin-left:auto`s in one row would split the free space between them,
|
|
@@ -100,8 +106,11 @@ A.insertGlobalCss({
|
|
|
100
106
|
* @param onLeafSelect Optional — run when a *leaf* item is activated (used by
|
|
101
107
|
* the floating menu to close itself on selection). A branch expanding is
|
|
102
108
|
* not a selection, so it doesn't run this.
|
|
109
|
+
* @param keyHints Print each row's `key` at its right end, as the floating
|
|
110
|
+
* menus do. Off — any kind of nav — a row tells its key in its tooltip
|
|
111
|
+
* instead, keeping the resting rows quiet.
|
|
103
112
|
*/
|
|
104
|
-
export function drawMenu(items, onLeafSelect) {
|
|
113
|
+
export function drawMenu(items, onLeafSelect, keyHints) {
|
|
105
114
|
// Roving focus via the DOM: query the live item elements on each keypress.
|
|
106
115
|
A("keydown=", (e) => {
|
|
107
116
|
// interceptLinks' own Enter handler preventDefault()s the activation, so no
|
|
@@ -127,13 +136,16 @@ export function drawMenu(items, onLeafSelect) {
|
|
|
127
136
|
(cur + dir + els.length) % els.length;
|
|
128
137
|
els[next].focus();
|
|
129
138
|
});
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
139
|
+
drawEntries(items, {
|
|
140
|
+
onLeafSelect,
|
|
141
|
+
keyHints,
|
|
142
|
+
// Whether the current page is in this menu *at all* — a fact no single
|
|
143
|
+
// branch can tell, and one the fold logic needs (see `drawBranch`).
|
|
144
|
+
// Derived, so branches re-run only when the answer flips.
|
|
145
|
+
$hasCurrent: A.derive(() => anyCurrent(items)),
|
|
146
|
+
});
|
|
135
147
|
}
|
|
136
|
-
function drawEntries(items,
|
|
148
|
+
function drawEntries(items, ctx) {
|
|
137
149
|
for (const entry of items) {
|
|
138
150
|
if (typeof entry === "string" || typeof entry === "function") {
|
|
139
151
|
drawSlot(entry);
|
|
@@ -144,12 +156,12 @@ function drawEntries(items, onLeafSelect, $menuHasCurrent) {
|
|
|
144
156
|
continue;
|
|
145
157
|
}
|
|
146
158
|
if (entry.items)
|
|
147
|
-
drawBranch(entry,
|
|
159
|
+
drawBranch(entry, ctx);
|
|
148
160
|
else
|
|
149
|
-
drawLeaf(entry,
|
|
161
|
+
drawLeaf(entry, ctx);
|
|
150
162
|
}
|
|
151
163
|
}
|
|
152
|
-
function drawLeaf(entry,
|
|
164
|
+
function drawLeaf(entry, ctx) {
|
|
153
165
|
// Whether the aria-current scope below has run before: only a *later* run
|
|
154
166
|
// should animate the reveal.
|
|
155
167
|
let drawn = false;
|
|
@@ -182,13 +194,13 @@ function drawLeaf(entry, onLeafSelect) {
|
|
|
182
194
|
e.preventDefault();
|
|
183
195
|
return;
|
|
184
196
|
}
|
|
185
|
-
onLeafSelect?.();
|
|
197
|
+
ctx.onLeafSelect?.();
|
|
186
198
|
entry.click?.(e);
|
|
187
199
|
});
|
|
188
200
|
if (entry.icon)
|
|
189
201
|
A("span.s-menu-icon", () => drawSlot(entry.icon));
|
|
190
202
|
drawSlot(entry.label);
|
|
191
|
-
|
|
203
|
+
drawHints(entry, ctx);
|
|
192
204
|
});
|
|
193
205
|
}
|
|
194
206
|
/**
|
|
@@ -212,7 +224,7 @@ function setFold(href, open) {
|
|
|
212
224
|
* exactly while it holds the current page. Only a branch with no link anywhere below
|
|
213
225
|
* it keeps the native toggle.
|
|
214
226
|
*/
|
|
215
|
-
function drawBranch(entry,
|
|
227
|
+
function drawBranch(entry, ctx) {
|
|
216
228
|
const href = entry.href ?? firstLeafHref(entry.items);
|
|
217
229
|
// Derived, so the attribute scope below re-runs only when the fold answer flips.
|
|
218
230
|
// When the current page is nowhere in the menu, nothing has an opinion and the fold
|
|
@@ -222,7 +234,7 @@ function drawBranch(entry, onLeafSelect, $menuHasCurrent) {
|
|
|
222
234
|
? A.derive(() => {
|
|
223
235
|
if (containsCurrent(entry))
|
|
224
236
|
return setFold(href, true);
|
|
225
|
-
if (
|
|
237
|
+
if (ctx.$hasCurrent.value)
|
|
226
238
|
return setFold(href, false);
|
|
227
239
|
return foldMemory.get(href) ?? false;
|
|
228
240
|
})
|
|
@@ -261,10 +273,10 @@ function drawBranch(entry, onLeafSelect, $menuHasCurrent) {
|
|
|
261
273
|
if (entry.icon)
|
|
262
274
|
A("span.s-menu-icon", () => drawSlot(entry.icon));
|
|
263
275
|
drawSlot(entry.label);
|
|
264
|
-
|
|
276
|
+
drawHints(entry, ctx);
|
|
265
277
|
A("span.s-menu-chevron aria-hidden=true", () => chevronRight());
|
|
266
278
|
});
|
|
267
|
-
A("div.s-menu-sub", () => drawEntries(entry.items,
|
|
279
|
+
A("div.s-menu-sub", () => drawEntries(entry.items, ctx));
|
|
268
280
|
});
|
|
269
281
|
}
|
|
270
282
|
/**
|
|
@@ -328,12 +340,31 @@ function firstLeafHref(items) {
|
|
|
328
340
|
return undefined;
|
|
329
341
|
}
|
|
330
342
|
// ─── Keyboard shortcuts ──────────────────────────────────────────────────────
|
|
331
|
-
/**
|
|
332
|
-
|
|
343
|
+
/**
|
|
344
|
+
* A row's shortcut hint and tooltip. In a floating menu the shortcut sits at
|
|
345
|
+
* the right end of the row; a nav row keeps its label clean and tells it in
|
|
346
|
+
* its tooltip instead — under the item's own `tooltip` content, when it has
|
|
347
|
+
* one, behind a subtle hairline. See {@link MenuItem.key}.
|
|
348
|
+
*/
|
|
349
|
+
function drawHints(entry, ctx) {
|
|
350
|
+
const tipKey = ctx.keyHints ? undefined : entry.key;
|
|
333
351
|
// `aria-hidden`: the row already carries the shortcut as `aria-keyshortcuts`,
|
|
334
|
-
// which is what a screen reader reads out —
|
|
335
|
-
if (entry.key)
|
|
352
|
+
// which is what a screen reader reads out — the hint is the sighted half.
|
|
353
|
+
if (entry.key && !tipKey)
|
|
336
354
|
A("kbd.s-menu-key aria-hidden=true text=", formatKey(entry.key));
|
|
355
|
+
if (entry.tooltip == null && !tipKey)
|
|
356
|
+
return;
|
|
357
|
+
addTooltip({
|
|
358
|
+
placement: "right",
|
|
359
|
+
tip: () => {
|
|
360
|
+
drawSlot(entry.tooltip);
|
|
361
|
+
if (tipKey) {
|
|
362
|
+
if (entry.tooltip != null)
|
|
363
|
+
A("hr.s-menu-sep");
|
|
364
|
+
A("kbd.s-menu-tt-key aria-hidden=true text=", formatKey(tipKey));
|
|
365
|
+
}
|
|
366
|
+
},
|
|
367
|
+
});
|
|
337
368
|
}
|
|
338
369
|
/**
|
|
339
370
|
* Bind the shortcuts of every item in a menu — see {@link MenuItem.key} — for as
|
|
@@ -493,7 +524,7 @@ mountPortal(() => {
|
|
|
493
524
|
const menuEl = A("div.s-menu-list.s-s.neutral.shadow create=hidden destroy=hidden", f.dropdownAttrs, () => {
|
|
494
525
|
// One drawMenu call, not one per section: it owns the container's roving
|
|
495
526
|
// keyboard focus, and two of them would move it twice per keypress.
|
|
496
|
-
drawMenu(f.link != null ? [...linkItems(f.link), { separator: true }, ...f.items] : f.items, closeFloating);
|
|
527
|
+
drawMenu(f.link != null ? [...linkItems(f.link), { separator: true }, ...f.items] : f.items, closeFloating, true);
|
|
497
528
|
});
|
|
498
529
|
// Capture-phase document handlers replace an invisible backdrop element:
|
|
499
530
|
// any click outside the panel + anchor closes; Escape/Tab close.
|
|
@@ -161,9 +161,9 @@ export interface Panel<P = Record<string, string | number | string[]>> {
|
|
|
161
161
|
* The widest this panel can usefully be — a ceiling the shell never
|
|
162
162
|
* exceeds, so the draw function never has to look right past it. It is
|
|
163
163
|
* counted in the shell's *columns*: the content area divides into the
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
164
|
+
* fewest whole number of columns of at most 540px each (two columns of 540
|
|
165
|
+
* in a 1080px area, three of ~507 in 1520px), and a column is never
|
|
166
|
+
* narrower than 360 — where the area holds just one, a small centres in it
|
|
167
167
|
* rather than stretching. So an ask never exceeds its column count × 540:
|
|
168
168
|
*
|
|
169
169
|
* - `"small"` — one column, never above 540px: lists, detail forms.
|
|
@@ -672,10 +672,13 @@ export declare class PanelStackController implements PanelStack {
|
|
|
672
672
|
* up here that could drift from the bars above and below. Widths stay
|
|
673
673
|
* fractional: a rounded column edge would drift a pixel away from that chrome.
|
|
674
674
|
*
|
|
675
|
-
* The area divides into the
|
|
676
|
-
* {@link
|
|
677
|
-
*
|
|
678
|
-
*
|
|
675
|
+
* The area divides into the fewest whole number of columns of at most
|
|
676
|
+
* {@link SMALL_MAX_PX} — so 1080px is two of 540, 1520px three of ~507 —
|
|
677
|
+
* keeping columns as wide as the cap allows rather than as narrow as
|
|
678
|
+
* {@link SMALL_MIN_PX} permits. Only below 720px can that division dip under
|
|
679
|
+
* the minimum; there a single column, capped at 540, centres in the area
|
|
680
|
+
* instead. A width is therefore a pure function of the window: a panel NEVER
|
|
681
|
+
* resizes because a neighbour came or went.
|
|
679
682
|
*
|
|
680
683
|
* `undefined` while the shell has no width yet (not in a document, or
|
|
681
684
|
* `display:none`); the next pass tries again.
|
|
@@ -117,10 +117,9 @@ const PAGE_MS = 250;
|
|
|
117
117
|
/** How long a freshly pushed `loading` panel holds its enter animation. */
|
|
118
118
|
const LOADING_HOLD_MS = 300;
|
|
119
119
|
/**
|
|
120
|
-
* The bounds of a column: at
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
* area to it as well makes every ask's ceiling uniformly column count × 540.
|
|
120
|
+
* The bounds of a column: at most 540px — the width columns aim for, the area
|
|
121
|
+
* dividing into the fewest of them that stay within it — and at least 360px,
|
|
122
|
+
* about the narrowest phone in common use, so where a panel's layout is aimed.
|
|
124
123
|
*/
|
|
125
124
|
const SMALL_MIN_PX = 360;
|
|
126
125
|
export const SMALL_MAX_PX = 540;
|
|
@@ -1151,10 +1150,13 @@ export class PanelStackController {
|
|
|
1151
1150
|
* up here that could drift from the bars above and below. Widths stay
|
|
1152
1151
|
* fractional: a rounded column edge would drift a pixel away from that chrome.
|
|
1153
1152
|
*
|
|
1154
|
-
* The area divides into the
|
|
1155
|
-
* {@link
|
|
1156
|
-
*
|
|
1157
|
-
*
|
|
1153
|
+
* The area divides into the fewest whole number of columns of at most
|
|
1154
|
+
* {@link SMALL_MAX_PX} — so 1080px is two of 540, 1520px three of ~507 —
|
|
1155
|
+
* keeping columns as wide as the cap allows rather than as narrow as
|
|
1156
|
+
* {@link SMALL_MIN_PX} permits. Only below 720px can that division dip under
|
|
1157
|
+
* the minimum; there a single column, capped at 540, centres in the area
|
|
1158
|
+
* instead. A width is therefore a pure function of the window: a panel NEVER
|
|
1159
|
+
* resizes because a neighbour came or went.
|
|
1158
1160
|
*
|
|
1159
1161
|
* `undefined` while the shell has no width yet (not in a document, or
|
|
1160
1162
|
* `display:none`); the next pass tries again.
|
|
@@ -1164,7 +1166,8 @@ export class PanelStackController {
|
|
|
1164
1166
|
const area = el ? el.getBoundingClientRect().width : 0;
|
|
1165
1167
|
if (!area)
|
|
1166
1168
|
return undefined;
|
|
1167
|
-
const
|
|
1169
|
+
const cols = Math.ceil(area / SMALL_MAX_PX);
|
|
1170
|
+
const small = area / cols >= SMALL_MIN_PX ? area / cols : Math.min(area, SMALL_MAX_PX);
|
|
1168
1171
|
const units = (n) => Math.min(n * small, area);
|
|
1169
1172
|
return { area, size: { small, medium: units(2), large: units(3), none: area } };
|
|
1170
1173
|
}
|
|
@@ -124,10 +124,17 @@ export function addTooltip(opts) {
|
|
|
124
124
|
};
|
|
125
125
|
A("mouseenter=", show);
|
|
126
126
|
A("mouseleave=", scheduleHide);
|
|
127
|
-
|
|
127
|
+
// Keyboard focus only: programmatic focus (a nav opening on its current row,
|
|
128
|
+
// say) would pop a tip over the very thing it describes.
|
|
129
|
+
A("focusin=", (e) => {
|
|
130
|
+
if (e.target.matches?.(":focus-visible"))
|
|
131
|
+
show(e);
|
|
132
|
+
});
|
|
128
133
|
A("focusout=", scheduleHide);
|
|
129
134
|
A.clean(() => {
|
|
130
|
-
|
|
135
|
+
// Compare raw: the proxy's getter wraps stored objects, so `$ttActive.value.opts`
|
|
136
|
+
// would be a Proxy that never equals our raw `opts`.
|
|
137
|
+
if (A.unproxy($ttActive).value?.opts === opts)
|
|
131
138
|
$ttActive.value = undefined;
|
|
132
139
|
});
|
|
133
140
|
}
|
package/dist/staffa.esm.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import R from"aberdeen";var X1=t=>`background: linear-gradient(${t}, color-mix(in oklab, $s-bg, white 9%), color-mix(in oklab, $s-bg, black 9%));`,G1=X1("170deg"),V1=X1("180deg"),A1="staffa:darkMode",j1=R.proxy({value:q2()});function q2(){try{let t=localStorage.getItem(A1);if(t==="dark")return!0;if(t==="light")return!1}catch{}}function T2(t){j1.value=t;try{t===void 0?localStorage.removeItem(A1):localStorage.setItem(A1,t?"dark":"light")}catch{}}function _1(t=!1){let a=j1.value;return a===void 0&&!t?R.darkMode():a}R(()=>{_1()?R.insertGlobalCss({":root, .s-s.neutral":"--s-bg:#0e0f12 --s-text:#e9eaec",".s-s.neutral":"--s-bg:#191b1f --s-text:#e9eaec",".s-s.neutral .s-s.neutral":"--s-bg:#23262b"}):R.insertGlobalCss({":root, .s-s.neutral":"--s-bg:#eef0f3 --s-text:#1d1f24",".s-s.neutral, .s-s.neutral":"--s-bg:#ffffff --s-text:#1d1f24",".s-s.neutral .s-s.neutral":"--s-bg:#f6f7f9"})});R.setSpacingCssVars(1.1);R.insertGlobalCss({"*, *::before, *::after":"box-sizing:border-box",html:"text-size-adjust:100%",body:"m:0 p:$3 line-height:1.5 font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; -webkit-font-smoothing:antialiased background-color:$s-bg text:$s-text",a:"color: $s-link-fg; text-decoration:underline text-underline-offset:2px; transition: color 0.12s, filter 0.12s;","a:hover":"filter: brightness(1.15)","input, button, textarea, select, optgroup":"font:inherit color:inherit","input:where(:not([type=checkbox],[type=radio],[type=range],[type=file],[type=color],[type=image],[type=submit],[type=button],[type=reset],[type=hidden])), textarea, select":"background:$s-bg border: 1px solid $s-faint; r:$s-radius-sm padding: 0.45em 0.65em; max-width:100%","input:where([type=checkbox],[type=radio])":"width:1.15em height:1.15em cursor:pointer","input[type=range]":"appearance:none background:transparent cursor:pointer vertical-align:middle","input[type=range]::-webkit-slider-runnable-track":"height:4px r:99px background:$s-faint","input[type=range]::-moz-range-track":"height:4px r:99px background:$s-faint","input[type=range]::-moz-range-progress":"height:4px r:99px background:$s-accent","input[type=range]::-webkit-slider-thumb":"appearance:none width:16px height:16px margin-top:-6px r:50% background:$s-accent","input[type=range]::-moz-range-thumb":"width:16px height:16px border:0 r:50% background:$s-accent","input[type=file]":"cursor:pointer",progress:"appearance:none border:0 height:6px r:99px background:$s-faint overflow:hidden vertical-align:middle","progress::-webkit-progress-bar":"background:$s-faint r:99px","progress::-webkit-progress-value":"background:$s-accent r:99px","progress::-moz-progress-bar":"background:$s-accent r:99px",meter:"vertical-align:middle",fieldset:"border: 1px solid $s-faint; r:$s-radius-sm padding:$2 min-width:0",legend:"padding: 0 $1; font-weight:600","code, kbd, samp, pre":"font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;",code:"background: color-mix(in oklab, $s-text, $s-bg 86%); padding: 0.12em 0.34em; r:4px font-size:0.9em",pre:"background: color-mix(in oklab, $s-text, $s-bg 92%); p:$3 r: $s-radius; overflow:auto","pre code":"background:transparent p:0","img, svg, video, canvas":"max-width:100% h:auto",hr:"border:0 border-top: 1px solid $s-faint;","::placeholder":"color: $s-muted; opacity:1",":focus-visible":"outline: 2px solid $s-focus; outline-offset:2px",small:"color:$s-muted font-size:0.9em","@media (prefers-reduced-motion: reduce)":{"*, *::before, *::after":"transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; scroll-behavior: auto !important;"},":root":"--s-primary:#00a884 --s-danger:#dc5b41 --s-success:#00a884 --s-warning:#ef6b00 --s-link:#3f8cd8 --s-radius-sm:6px --s-radius:12px --s-radius-lg:18px --s-focus: color-mix(in srgb, $s-primary 38%, transparent); --s-gradient: linear-gradient(135deg, color-mix(in oklab, $s-primary, white 16%), color-mix(in oklab, $s-primary, black 14%));",":root, .s-s.neutral":"--s-accent:$s-primary --s-link-fg:$s-link",".s-s:not(.neutral)":"--s-bg:$s-primary border:0 --s-text:#eee --s-accent:#fff --s-link-fg:#eef --s-muted: color-mix(in srgb, #fff 70%, transparent); --s-faint: color-mix(in srgb, #fff 30%, transparent);",".s-s.danger":"--s-bg:$s-danger",".s-s.success":"--s-bg:$s-success",".s-s.warning":"--s-bg:$s-warning",".s-s.link":"--s-bg:$s-link",".s-s.primary":"--s-bg:$s-primary",":root, .s-s":"--s-muted: color-mix(in oklab, $s-text, $s-bg 42%); --s-faint: color-mix(in oklab, $s-text, $s-bg 80%); color:$s-text accent-color:$s-accent scrollbar-width:thin scrollbar-color: $s-faint transparent;",".s-s, body":G1,".s-s":"r:$s-radius",":where(.s-s.neutral)":"border: 1px solid $s-faint;",".s-s::-webkit-scrollbar, .s-s ::-webkit-scrollbar":"width:10px height:10px",".s-s::-webkit-scrollbar-track, .s-s ::-webkit-scrollbar-track":"background:transparent",".s-s::-webkit-scrollbar-thumb, .s-s ::-webkit-scrollbar-thumb":"background:$s-faint border-radius:99px border: 2px solid transparent; background-clip:padding-box",".s-s.shadow.neutral:not(.s-btn)":"box-shadow: 0 4px 14px rgba(0,0,0,0.13);",".s-s.extra-shadow.neutral:not(.s-btn)":"box-shadow: 0 18px 50px rgba(0,0,0,0.28);",".s-s.shadow:not(.neutral):not(.tonal):not(.outlined)":"box-shadow: 0 4px 14px color-mix(in srgb, $s-bg 30%, transparent);",".s-s.extra-shadow:not(.neutral):not(.tonal):not(.outlined)":"box-shadow: 0 14px 40px color-mix(in srgb, $s-bg 40%, transparent);",".s-s.no-shadow":"box-shadow: none !important;",".s-s:not(.neutral).tonal, .s-s:not(.neutral).outlined":"--s-text:$s-bg --s-accent:$s-bg --s-link-fg:$s-bg --s-faint: color-mix(in srgb, $s-bg 30%, transparent); --s-muted: color-mix(in srgb, $s-bg 70%, transparent);",".s-s:not(.neutral).tonal":"background: color-mix(in srgb, $s-bg 15%, transparent); border: 1px solid $s-faint;",".s-s:not(.neutral).outlined":"background: transparent; border: 1px solid color-mix(in srgb, $s-bg 45%, transparent);",".s-s:not(.neutral) .s-s.tonal, .s-s:not(.neutral) .s-s.outlined":"--s-text:#fff --s-accent:#fff --s-link-fg:#fff "+G1+" border-color: transparent;"});R.insertGlobalCss({".s-preload, .s-preload *, .s-preload *::before, .s-preload *::after":"transition: none !important; animation: none !important;"});if(typeof document<"u"&&typeof requestAnimationFrame=="function"){let t=document.documentElement;t.classList.add("s-preload"),requestAnimationFrame(()=>requestAnimationFrame(()=>t.classList.remove("s-preload")))}R.insertGlobalCss({":disabled, [aria-disabled=true]":"opacity:0.45 filter:saturate(0.6) user-select:none",":disabled, [aria-disabled=true], :disabled *, [aria-disabled=true] *":"pointer-events:none cursor:not-allowed"});var R2="p, ul, ol, dl, blockquote, pre, table, figure, hr, h1, h2, h3, h4, h5, h6";R.insertGlobalCss({[`${R2}`]:{"&":"margin:0","&:not(:first-child)":"margin-top:$3"},"h1, h2, h3, h4, h5, h6":{"&":"line-height:1.15 font-weight:700 text-wrap:balance","&:not(:first-child)":"margin-top:1.4em"},h1:"font-size:2em font-weight:800 letter-spacing:-0.022em",h2:"font-size:1.55em letter-spacing:-0.018em",h3:"font-size:1.3em letter-spacing:-0.011em",h4:"font-size:1.1em",h5:"font-size:0.95em letter-spacing:0.005em",h6:"font-size:0.8em fg:$s-muted text-transform:uppercase letter-spacing:0.07em","ul, ol":{"&":"padding-left:1.5em","> li:not(:first-child), li > &:not(:first-child)":"margin-top:$1"},blockquote:"border-left: 3px solid $s-faint; padding-left: $3; fg: $s-muted",table:"border-collapse:collapse","th, td":"text-align:left padding: $1 $2; border-bottom: 1px solid $s-faint; vertical-align:top",th:"font-weight:600","thead th":"border-bottom: 2px solid $s-faint;",dt:"font-weight:600",dd:"margin-left: 1.5em",figcaption:"fg:$s-muted font-size:0.9em margin-top:$1 text-align:center"});import k1 from"aberdeen";var s1=typeof navigator<"u"&&/mac|iphone|ipad|ipod/i.test(navigator.platform||navigator.userAgent),D2={esc:"escape",space:" "},Z2={" ":"Space",escape:"Esc",arrowup:"\u2191",arrowdown:"\u2193",arrowleft:"\u2190",arrowright:"\u2192"},l1=new WeakMap,E=[];function J1(){let t=k1();if(!t)throw new Error("Staffa: claimKeyboard needs a current element");return E.push(t),()=>{let a=E.indexOf(t);a>=0&&E.splice(a,1)}}function Y1(t){let[,a,e,h]=/^(mod\+)?(shift\+)?(.*)$/i.exec(t),p=h.toLowerCase();if(p=D2[p]??p,!p||p.length>1&&/[-+]/.test(p))throw new Error(`Staffa: can't parse key "${t}" \u2014 write "k", "f2", "mod+k" or "mod+shift+f2"`);if(e&&p.toUpperCase()===p)throw new Error(`Staffa: "${t}" \u2014 write the shifted character itself ("?", not "shift+/")`);return(a?"mod+":"")+(e?"shift+":"")+p}function B2(t){if(t.altKey||(s1?t.ctrlKey:t.metaKey))return null;let a=t.key.toLowerCase(),e=t.shiftKey&&(a.length>1||t.key.toUpperCase()!==a);return((s1?t.metaKey:t.ctrlKey)?"mod+":"")+(e?"shift+":"")+a}function t2(t,a){if(!(a instanceof HTMLElement))return!1;let e=t.startsWith("mod+"),h=t.replace(/^(mod\+)?(shift\+)?/,"");if(h==="enter"&&a.closest("a[href]")!=null||!e&&(h==="enter"||h===" ")&&a.closest("button, summary, [role=button]")!=null)return!0;let p=a.tagName;return!e&&h!=="escape"&&(p==="INPUT"||p==="TEXTAREA"||p==="SELECT"||a.isContentEditable)}function a2(t,a){let e=E[E.length-1];return a.global===!0||!e||e.contains(t)}function I2(t){for(let a=E.length-1;a>=0;a--)if(E[a].contains(t))return E[a]}function e2(){return E[E.length-1]??document.body}function h2(t){let a=E[E.length-1];return a&&!(t&&a.contains(t))?a:t??document.body}var Q1=!1;function F2(t){if(t.defaultPrevented||t.repeat||t.isComposing)return;let a=B2(t),e=t.target instanceof Element?t.target:null;if(!(a==null||t2(a,e)))for(let h=h2(e);h;h=h.parentElement){let p=l1.get(h)?.get(a);if(p&&a2(h,p)){p.press&&(t.preventDefault(),p.press(t));return}}}function p2(t){let a=new Map;for(let e=h2(t);e;e=e.parentElement){let h=l1.get(e);if(h)for(let[p,r]of h)!a.has(p)&&a2(e,r)&&!t2(p,t)&&a.set(p,r)}return[...a]}function S(t,a,e,h="normal"){let p=k1(),r=h==="global"?document.body:h==="local"?p:h==="normal"?(p&&I2(p))??document.body:h;if(!r)throw new Error("Staffa: a local key binding needs a current element");let o=Y1(t),d=l1.get(r);d||l1.set(r,d=new Map);let c={description:a,press:e,global:h==="global",prev:d.get(o)};d.set(o,c),Q1||(Q1=!0,document.addEventListener("keydown",F2)),k1.clean(()=>{let n=d.get(o);if(n===c)c.prev?d.set(o,c.prev):d.delete(o);else for(;n;n=n.prev)if(n.prev===c){n.prev=c.prev;break}})}function q(t,a=!1){let e=Y1(t),h=e.startsWith("mod+"),p=h?e.slice(4):e,r=p.startsWith("shift+"),o=r?p.slice(6):p,d=o.length===1?o.toUpperCase():o[0].toUpperCase()+o.slice(1);if(a){let n=o===" "?"Space":r||o.length>1?d:o;return(h?s1?"Meta+":"Control+":"")+(r?"Shift+":"")+n}let c=Z2[o]??d;return s1?(r?"\u21E7":"")+(h?"\u2318":"")+c:(h?"Ctrl+":"")+(r?"Shift+":"")+c}import W from"aberdeen";import r2 from"aberdeen";var M1=640,U2=0;function U(t="s"){return`${t}-${++U2}`}function x(t,...a){t!=null&&(typeof t=="function"?t(...a):r2("rich=",t))}var K2="a[href], button, input, select, textarea, [tabindex]";function J(t,a){let e=p=>p instanceof HTMLElement&&!p.hasAttribute("disabled")&&p.getAttribute("aria-disabled")!=="true"&&p.tabIndex>=0&&p.getClientRects().length>0,h=(a?[...t.querySelectorAll(a)].find(e):void 0)??[...t.querySelectorAll(K2)].find(e);return h?.focus(),h!=null}function K(t){queueMicrotask(()=>r2(t))}import b from"aberdeen";import $ from"aberdeen";import D from"aberdeen";D.insertGlobalCss({".s-tt-tip":{"&":"position:fixed z-index:500 max-width:20rem w:max-content padding: 0.3em 0.65em; font-size:0.85em line-height:1.4 pointer-events:none"}});var Y=D.proxy(void 0),Z=null;typeof window<"u"&&window.addEventListener("scroll",()=>{Y.value=void 0},{capture:!0,passive:!0});function N2(t,a,e,h){let r=window.innerWidth,o=window.innerHeight,d=0,c=0;return h==="bottom"?(d=t.left+(t.width-a)/2,c=t.bottom+7,c+e>o-8&&(c=t.top-e-7)):h==="left"?(d=t.left-a-7,c=t.top+(t.height-e)/2,d<8&&(d=t.right+7)):h==="right"?(d=t.right+7,c=t.top+(t.height-e)/2,d+a>r-8&&(d=t.left-a-7)):(d=t.left+(t.width-a)/2,c=t.top-e-7,c<8&&(c=t.bottom+7)),{x:Math.max(8,Math.min(d,r-a-8)),y:Math.max(8,Math.min(c,o-e-8))}}function L1(){Z&&clearTimeout(Z),Z=setTimeout(()=>{Y.value=void 0,Z=null},100)}K(()=>{let t=Y.value;if(!t)return;let{opts:a,anchor:e}=t,h=a.placement??"top",p=D("div.s-tt-tip.s-s.neutral.shadow role=tooltip visibility:hidden",a.attrs,()=>{D("mouseenter=",()=>{Z&&(clearTimeout(Z),Z=null)}),D("mouseleave=",L1),x(a.tip)});requestAnimationFrame(()=>{if(!document.body.contains(p))return;let r=e.getBoundingClientRect(),{x:o,y:d}=N2(r,p.offsetWidth,p.offsetHeight,h);p.style.left=o+"px",p.style.top=d+"px",p.style.visibility=""})});function C1(t){let a=e=>{Z&&(clearTimeout(Z),Z=null),Y.value={opts:t,anchor:e.currentTarget}};D("mouseenter=",a),D("mouseleave=",L1),D("focusin=",a),D("focusout=",L1),D.clean(()=>{Y.value?.opts===t&&(Y.value=void 0)})}$.insertGlobalCss({".s-btn":{"&":"display:inline-flex align-items:center justify-content:center gap:$2 font-weight:450 line-height:1.1 white-space:nowrap cursor:pointer text-decoration:none padding: $m2 $m3; transition: background 0.15s, border-color 0.15s, color 0.15s, filter 0.15s, box-shadow 0.15s, transform 0.08s;","&:focus-visible":"outline: 3px solid $s-focus; outline-offset: 1px;","&:hover":"filter: brightness(1.06)","&.tonal:hover, &.outlined:hover":"background: color-mix(in srgb, $s-bg 24%, transparent);","&.neutral:hover":"filter:none background: color-mix(in srgb, $s-text 8%, $s-bg);","> svg":"width:1.25em height:1.25em","&:active:not(:disabled)":"transform: translateY(1px)","&.small, .small > &":"padding: $m1 $m2; font-size:0.85em border-radius:$s-radius-sm","&.large, .large > &":"font-size:1.4em border-radius:$s-radius-lg"},".s-icon-btn":{"&":"display:inline-flex align-items:center justify-content:center flex-shrink:0 width:2rem height:2rem p:0 border:0 background:transparent cursor:pointer fg:$s-muted r:$s-radius-sm line-height:1 font-size:1rem text-decoration:none transition: color 0.12s, background 0.12s;","> svg":"width:1.25em height:1.25em","&:hover:not(:disabled):not([aria-disabled=true])":"fg:$s-text background: color-mix(in srgb, $s-text 10%, transparent);","&:focus-visible":"outline: 3px solid $s-focus; outline-offset:1px","&.small, .small > &":"width:1.6rem height:1.6rem font-size:0.8rem","&.large, .large > &":"width:2.4rem height:2.4rem font-size:1.2rem"}});function h1(t){let a=t.href!=null?"a":"button";$(`${a}.s-icon-btn`,t.attrs,()=>{o2(t),$("aria-label=",t.ariaLabel),t.key&&d2(t.key,t.ariaLabel,void 0,t.disabled),x(t.icon)})}function o2(t){t.href!=null?($("role=button"),t.disabled?$("aria-disabled=true"):$("href=",t.href)):($("type=",t.type??"button"),t.disabled&&$("disabled=true")),t.click&&!t.disabled&&$("click=",t.click)}function d2(t,a,e,h){let p=$(),r=a?`${a} \xB7 ${q(t)}`:q(t);C1({tip:()=>$("#",r)}),h||($("aria-keyshortcuts=",q(t,!0)),S(t,typeof e=="string"?e:a,()=>p.click()))}function T(t={}){let a=typeof t=="string"||typeof t=="function"?{content:t}:t,e=a.href!=null?"a":"button";$(`${e}.s-btn.s-s.shadow`,a.attrs,()=>{o2(a),a.ariaLabel&&$("aria-label=",a.ariaLabel),a.key&&d2(a.key,a.ariaLabel,a.content,a.disabled),x(a.icon),x(a.content)})}import c2 from"aberdeen";c2.insertGlobalCss({".s-bgroup":{"&":"display:inline-flex align-items:stretch","&.s-spaced":"gap:$2 flex-wrap:wrap","&.s-vertical":"flex-direction:column","&.s-attached":"gap:0","&.s-attached:not(.s-vertical) > .s-btn:not(:first-child)":"margin-left:-1px","&.s-attached:not(.s-vertical) > .s-btn:not(:first-child):not(:last-child)":"r:0","&.s-attached:not(.s-vertical) > .s-btn:first-child:not(:last-child)":"border-top-right-radius:0 border-bottom-right-radius:0","&.s-attached:not(.s-vertical) > .s-btn:last-child:not(:first-child)":"border-top-left-radius:0 border-bottom-left-radius:0","&.s-attached.s-vertical > .s-btn:not(:first-child)":"margin-top:-1px","&.s-attached.s-vertical > .s-btn:not(:first-child):not(:last-child)":"r:0","&.s-attached.s-vertical > .s-btn:first-child:not(:last-child)":"border-bottom-left-radius:0 border-bottom-right-radius:0","&.s-attached.s-vertical > .s-btn:last-child:not(:first-child)":"border-top-left-radius:0 border-top-right-radius:0","&.s-attached > .s-btn:hover, &.s-attached > .s-btn:focus-visible":"z-index:1"}});function X(t={}){let e=`.s-${t.layout??"attached"}${t.vertical?".s-vertical":""}`;c2(`div.s-bgroup${e} role=group`,t.attrs,()=>{if(t.buttons)for(let h of t.buttons)T(h);x(t.content)})}import j from"aberdeen";import L from"aberdeen";L.insertGlobalCss({".s-field":{"&":"display:flex flex-direction:column gap:$1","> label":"font-weight:600 font-size:0.9em fg:$s-text user-select:none"},".s-req":"fg:$s-danger margin-left:2px",".s-help":"font-size:0.82em fg:$s-muted",".s-error":"font-size:0.82em fg:$s-danger",".s-input":{"&":"w:100% background: color-mix(in oklab, $s-bg, $s-text 4%); color:$s-text border: 1px solid $s-faint; r:$s-radius padding: 0.55em 0.7em; transition: border-color 0.15s, box-shadow 0.15s;","&:hover:not(:disabled)":"border-color: color-mix(in oklab, $s-text, $s-bg 55%);","&:focus-visible":"border-color:$s-accent box-shadow: 0 0 0 3px $s-focus; outline:none","&[aria-invalid=true]":"border-color:$s-danger"}});function N(t,a){let e=t.id??U("field"),h=()=>!!t.error;L("div.s-field",t.attrs,()=>{L(()=>{t.label!=null&&L("label for=",e,()=>{x(t.label),t.required&&L("span.s-req aria-hidden=true #*")})}),a(e,h),L(()=>{t.help!=null&&!t.error&&L("div.s-help",()=>x(t.help))}),L(()=>{t.error&&L("div.s-error role=alert #",t.error)})})}function t1(t,a,e,h){L("id=",a),t.name&&L("name=",t.name),L(()=>{t.disabled&&L("disabled=true")}),L(()=>{t.required&&L("aria-required=true")}),L(()=>L("aria-invalid=",e()?"true":"false")),h&&L("bind=",h)}function z1(t={}){N(t,(a,e)=>{j("input.s-input",t.inputAttrs,()=>{j("type=",t.type??"text"),t.placeholder!=null&&j("placeholder=",t.placeholder),t.autocomplete!=null&&j("autocomplete=",t.autocomplete),t.value!=null&&!t.bind&&j("value=",t.value),t.input&&j("input=",t.input),t.change&&j("change=",t.change),t1(t,a,e,t.bind)})})}b.insertGlobalCss({".s-backdrop":{"&":"position:fixed inset:0 z-index:200 display:block background: rgba(0,0,0,0.55); transition: opacity 0.4s ease-in-out;","&.hidden":"opacity:0 pointer-events:none"},".s-dialog":{"&":"position:fixed z-index:200 top:50% left:50% display:flex flex-direction:column transform:translate(-50%,-50%) min-width:min(20rem,90vw) max-width:min(90vw,44rem) max-height:min(88vh,800px) r: $s-radius-lg; overflow:hidden transition: opacity 0.2s ease-out, transform 0.2s ease-out;","> header":"display:flex align-items:center gap:$2 padding: $2 $3; border:0 border-bottom: 1px solid $s-faint; r:0 font-weight:600 flex-shrink:0","> footer":"display:flex align-items:center justify-content:flex-end gap:$2 padding: $2 $3; border:0 border-top: 1px solid $s-faint; r:0 flex-shrink:0","> div":"p:$3 gap:$3 display:flex flex-direction:column overflow-y:auto flex:1 min-height:0","&.hidden":"opacity:0 pointer-events:none transform: translate(-50%, calc(-50% + 20px)); pointer-events:none"}});var p1=b.proxy({}),W2=0,n2=b.derive(()=>{let t=Object.keys(p1);if(t.length)return t[t.length-1]});function S1(){return n2.value!=null}K(()=>{b.onEach(p1,({resolve:t,opts:a},e)=>{let h=()=>{delete p1[e]};b.clean(()=>{a.onClose?.(),t()});let p=document.activeElement;b.clean(()=>{p instanceof HTMLElement&&document.contains(p)&&p.focus()});let r=b.derive(()=>n2.value!=e);b("div.s-backdrop create=hidden destroy=hidden .hidden=",r,"click=",()=>{a.allowCancel!==!1&&h()});let o=b("div.s-dialog.neutral.s-s.extra-shadow create=hidden destroy=hidden",a.attrs,()=>{a.keyboardTransparent||b.clean(J1());let d=e2();b(()=>{let c=a.allowCancel!==!1;S("esc",c?"Close this dialog":void 0,c?h:()=>{},d)}),b(()=>{a.header!=null&&b("header.s-s.neutral",a.headerAttrs,()=>x(a.header))}),b("div",a.contentAttrs,()=>{x(a.content,h)}),b(()=>{a.footer!=null&&b("footer.s-s.neutral",a.footerAttrs,()=>x(a.footer))})});requestAnimationFrame(()=>{document.body.contains(o)&&J(o)})})});function a1(t){let a=++W2;return t.cancelWithScope!==!1&&b.clean(()=>{delete p1[a]}),new Promise(e=>{p1[a]={resolve:e,opts:t}})}function G2(t,a={}){return a1({header:"Alert",allowCancel:!0,content:e=>{b("p",()=>{b("#",t)}),X({layout:"spaced",attrs:"align-self:flex-end",content:()=>{T({content:"OK",click:e})}})},...a})}function X2(t,a={}){return new Promise(e=>{let h=!1;a1({header:"Confirm",allowCancel:!0,content:p=>{b("p",()=>{b("#",t)}),X({layout:"spaced",attrs:"align-self:flex-end",content:()=>{T({content:"Cancel",attrs:".neutral",click:p}),T({content:"OK",click:()=>{h=!0,p()}})}})},...a,onClose:()=>{e(h),a.onClose?.()}})})}function j2(t,a="",e={}){return new Promise(h=>{let p=null;a1({header:"Input",allowCancel:!0,content:r=>{b("p",()=>{b("#",t)});let o=b.proxy({value:a});b("form display:contents",()=>{b("submit=",d=>{d.preventDefault(),p=o.value,r()}),z1({bind:b.ref(o,"value")}),X({layout:"spaced",attrs:"align-self:flex-end",content:()=>{T({content:"Cancel",attrs:".neutral",type:"button",click:r}),T({content:"OK",type:"submit"})}})})},...e,onClose:()=>{h(p),e.onClose?.()}})})}W.insertGlobalCss({".s-keyhelp":{"&":"display:flex flex-direction:column gap:$1 min-width:14rem","> div":"display:flex align-items:baseline justify-content:space-between gap:$4",kbd:"font-family:inherit font-size:0.85em fg:$s-muted white-space:nowrap border: 1px solid $s-faint; r:$s-radius-sm padding: 0 0.4em;"}});var x1=null;function $1(){if(x1){x1();return}let t=p2(document.activeElement);a1({header:"Keyboard shortcuts",cancelWithScope:!1,keyboardTransparent:!0,onClose:()=>{x1=null},content:a=>{x1=a;let e=h=>{h.repeat||["Control","Shift","Alt","Meta","Escape","?"].includes(h.key)||a()};document.addEventListener("keydown",e,!0),W.clean(()=>document.removeEventListener("keydown",e,!0)),W("div.s-keyhelp",()=>{for(let[h,p]of t)p.description!==void 0&&W("div",()=>{W("span",()=>x(p.description)),W("kbd text=",q(h))})})}})}var i2=W.proxy(!0);function _2(t){i2.value=t}W(()=>{i2.value&&(S("?",void 0,$1,"global"),S("mod+?","This overview",$1,"global"))});import M from"aberdeen";M.insertGlobalCss({".s-ac":{"&":"position:relative","> .s-control":"display:flex flex-wrap:wrap align-items:center gap:$1 background: color-mix(in oklab, $s-bg, $s-text 4%); color:$s-text border: 1px solid $s-faint; r:$s-radius padding: 0.3em 0.4em; cursor:text; transition: border-color 0.15s, box-shadow 0.15s;","> .s-control:hover":"border-color: color-mix(in oklab, $s-text, $s-bg 55%);","> .s-control:focus-within":"border-color:$s-accent box-shadow: 0 0 0 3px $s-focus;","&[aria-invalid=true] > .s-control":"border-color:$s-danger",".s-chip":"display:inline-flex align-items:center gap:$1 font-size:0.85em background: color-mix(in oklab, $s-bg, $s-text 10%); border: 1px solid $s-faint; r:$s-radius padding: 0.1em 0.2em 0.1em 0.5em;",".s-chip > button":"cursor:pointer border:0 background:transparent fg:$s-muted font-size:1.1em line-height:1 padding: 0 0.2em; r:4px",".s-chip > button:hover":"fg:$s-text background:$s-faint",input:"flex:1 min-width:6ch border:0 background:transparent color:inherit outline:none padding:0.25em","> .s-menu":"position:absolute top:100% left:0 right:0 z-index:20 margin-top:4px max-height:15rem overflow-y:auto list-style:none p:$1 margin-bottom:0","> .s-menu li":"margin:0",".s-option":"padding: 0.45em 0.6em; r:6px cursor:pointer transition: background 0.1s;",".s-option[aria-selected=true]":"background: color-mix(in srgb, $s-text 10%, transparent);",".s-add":"fg:$s-accent font-style:italic",".s-empty":"padding: 0.45em 0.6em; fg:$s-muted"}});function Q2(t){return typeof t=="string"?{value:t,label:t}:{value:t.value,label:t.label??t.value}}function J2(t){let a=U("ac-menu"),e=M.proxy({query:"",open:!1,active:0}),h=()=>(typeof t.options=="function"?t.options():t.options).map(Q2),p=()=>{let i=t.bind?.value;return i==null||i===""?[]:Array.isArray(i)?i:[i]},r=i=>h().find(m=>m.value===i)?.label??i;if(!t.multi){let i=t.bind?M.peek(t.bind,"value"):void 0;typeof i=="string"&&i&&(e.query=M.peek(()=>r(i)))}let o=()=>{let i=new Set(p()),m=h();t.multi&&(m=m.filter(H=>!i.has(H.value)));let g=e.query.trim().toLowerCase();return g&&(m=m.filter(H=>H.label.toLowerCase().includes(g))),m},d=(i,m)=>{if(t.multi){let g=Array.isArray(t.bind?.value)?[...t.bind.value]:[];g.includes(i)||g.push(i),t.bind&&(t.bind.value=g),e.query=""}else t.bind&&(t.bind.value=i),e.query=r(i),e.open=!1;e.active=0,m?.focus()},c=i=>{if(!t.bind)return;let m=t.bind.value??[];t.bind.value=m.filter(g=>g!==i)};N(t,(i,m)=>{M("div.s-ac",t.inputAttrs,()=>{M(()=>M("aria-invalid=",m()?"true":"false"));let g;M("div.s-control",()=>{M("click=",()=>g?.focus()),M(()=>{if(t.multi)for(let H of p())M("span.s-chip",()=>{M("span #",M.peek(()=>r(H))),M("button type=button aria-label=",`Remove ${H}`,()=>{M("#\xD7"),M("click=",l=>{l.stopPropagation(),c(H),g?.focus()})})})}),g=M("input type=text role=combobox autocomplete=off",()=>{M("id=",i,`aria-controls=${a} aria-autocomplete=list`),t.placeholder!=null&&M("placeholder=",t.placeholder),t.disabled&&M("disabled=true"),t.required&&M("aria-required=true"),M("bind=",M.ref(e,"query")),M(()=>M("aria-expanded=",e.open?"true":"false")),M(()=>{let l=o()[e.active];M("aria-activedescendant=",e.open&&l?`${a}-opt-${e.active}`:"")}),M("input=",()=>{e.open=!0,e.active=0}),M("focus=",()=>{e.open=!0}),M("blur=",()=>{setTimeout(()=>y(),150)}),M("keydown=",H=>n(H,g))})}),M(()=>{if(!e.open)return;let H=o(),l=e.query.trim(),f=t.allowCustom!==!1&&l!==""&&!H.some(C=>C.label.toLowerCase()===l.toLowerCase());M("ul.s-menu.s-s.neutral.shadow role=listbox",`id=${a}`,()=>{H.forEach((C,z)=>{M("li.s-option role=option",`id=${a}-opt-${z}`,()=>{M(()=>M("aria-selected=",e.active===z?"true":"false")),M("#",C.label),M("mousedown=",i1=>i1.preventDefault()),M("click=",()=>d(C.value,g)),M("mousemove=",()=>{e.active=z})})}),f&&M("li.s-option.s-add role=option",()=>{M("#",`Add "${l}"`),M("mousedown=",C=>C.preventDefault()),M("click=",()=>d(l,g))}),H.length===0&&!f&&M("li.s-empty #No matches")})}),M(()=>{if(t.name)if(t.multi)for(let H of p())M("input type=hidden",()=>{M("name=",t.name),M("value=",H)});else M("input type=hidden",()=>{M("name=",t.name),M("value=",p()[0]??"")})})})});function n(i,m){let g=o(),H=g.length-1;if(i.key==="ArrowDown")i.preventDefault(),e.open=!0,e.active=Math.min(H,e.active+1);else if(i.key==="ArrowUp")i.preventDefault(),e.active=Math.max(0,e.active-1);else if(i.key==="Enter"){i.preventDefault();let l=g[e.active];l?d(l.value,m):t.allowCustom!==!1&&e.query.trim()?d(e.query.trim(),m):e.open&&(e.open=!1)}else if(i.key==="Escape")e.open&&(i.preventDefault(),e.open=!1,t.multi||(e.query=r(p()[0]??"")));else if(i.key==="Backspace"&&t.multi&&e.query===""){let l=p();l.length&&c(l[l.length-1])}}function y(){e.open=!1,t.multi?e.query="":t.allowCustom!==!1&&e.query.trim()?d(e.query.trim()):e.query=r(p()[0]??"")}}import _ from"aberdeen";import Y2 from"aberdeen";var r1={size:24,color:"currentColor",strokeWidth:2,cap:"round",join:"round"};function t0(t,a){let e=a.size??r1.size,h=Y2('svg.s-icon aria-hidden=true viewBox="0 0 24 24" fill=none',"width=",e,"height=",e,"stroke=",a.color??r1.color,"stroke-width=",a.strokeWidth??r1.strokeWidth,"stroke-linecap=",a.cap??r1.cap,"stroke-linejoin=",a.join??r1.join,a.attrs);h.innerHTML=t}function P(t){return(a={})=>t0(t,a)}var s2=P('<path d="m9 18 6-6-6-6" />');var l2=P('<circle cx="12" cy="12" r="10" />');var M2=P('<path d="M15 3h6v6" /><path d="M10 14 21 3" /><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />');var x2=P('<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" /><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" />');var v1=P('<path d="M4 5h16" /><path d="M4 12h16" /><path d="M4 19h16" />');var v2=P('<path d="M12 17v5" /><path d="M15 9.34V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H7.89" /><path d="m2 2 20 20" /><path d="M9 9v1.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h11" />'),P1=P('<path d="M12 17v5" /><path d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z" />');var m2=P('<path d="M22 2 2 22" />');var e1=P('<path d="M18 6 6 18" /><path d="m6 6 12 12" />');_.insertGlobalCss({".s-box":{"&":"display:flex flex-direction:column overflow:hidden r: $s-radius-lg; position:relative","&:not(:first-child)":"margin-top: $3","> header":"display:flex align-items:center gap:$2 padding: $2 $3; border:0 border-bottom: 1px solid $s-faint; r:0 font-weight:600","> footer":"display:flex align-items:center justify-content:flex-end gap:$2 padding: $2 $3; border:0 border-top: 1px solid $s-faint; r:0","> div":"p:$3 gap:$3","> header > .s-box-close":"margin-left:auto","> .s-box-close":"position:absolute top:$2 right:$2 z-index:1"}});function a0(t={}){let a=typeof t=="string"||typeof t=="function"?{content:t}:t;_("section.s-box.s-s.neutral.shadow",a.attrs,()=>{_(()=>{a.header!=null?_("header.s-s.neutral",a.headerAttrs,()=>{x(a.header),typeof a.close=="function"&&u2(a.close)}):typeof a.close=="function"&&u2(a.close)}),_("div",a.contentAttrs,()=>{x(a.content)}),_(()=>{a.footer!=null&&_("footer.s-s.neutral",a.footerAttrs,()=>x(a.footer))})})}function u2(t){h1({icon:e1,ariaLabel:"Close",click:t,attrs:".s-box-close"})}import O1 from"aberdeen";function e0(t){O1(()=>{let a=t.bind.value;X({attrs:t.attrs,buttons:Object.entries(t.options).map(([e,h])=>({content:h,ariaLabel:typeof h=="function"?e:void 0,attrs:a===e?".primary":".neutral",click:()=>{t.bind.value=t.allowDeselect&&a===e?void 0:e}}))})}),t.name&&O1(()=>O1("input type=hidden name=",t.name,"value=",t.bind.value??""))}import k from"aberdeen";k.insertGlobalCss({".s-check":{"&":"display:flex flex-direction:column gap:$1","> label":"display:flex align-items:center gap:$2 cursor:pointer user-select:none","> label:has(input:disabled)":"cursor:not-allowed opacity:0.45 filter:saturate(0.6)",input:"cursor:inherit m:0"}});function h0(t={}){let a=t.id??U("check");k("div.s-check",t.attrs,()=>{k("label for=",a,()=>{k("input type=checkbox",t.inputAttrs,()=>{k("id=",a),t.name&&k("name=",t.name),t.checked&&!t.bind&&k("checked=true"),t.change&&k("change=",t.change),k(()=>{t.disabled&&k("disabled=true")}),k(()=>{t.required&&k("aria-required=true")}),t.bind&&k("bind=",t.bind)}),k(()=>{t.label!=null&&x(t.label),t.required&&k("span.s-req aria-hidden=true #*")})}),k(()=>{t.help!=null&&!t.error&&k("div.s-help",()=>x(t.help))}),k(()=>{t.error&&k("div.s-error role=alert #",t.error)})})}import Q from"aberdeen";Q.insertGlobalCss({".s-form":{"&":"display:flex flex-direction:column gap:$3","&.grid":"display:grid grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); gap:$3","&.grid > .s-wide, &.grid > footer":"grid-column: 1 / -1;","> footer":"display:flex align-items:center justify-content:flex-end gap:$2 flex-wrap:wrap margin-top:$1"}});function p0(t={}){let a=typeof t=="string"||typeof t=="function"?{content:t}:t;Q("form.s-form",a.attrs,()=>{Q(()=>{Q(".grid=",a.layout==="grid")}),Q("submit=",e=>{if(e.preventDefault(),a.submit){let h=new FormData(e.target),p={};for(let r of new Set(h.keys())){let o=h.getAll(r);p[r]=o.length===1?o[0]:o}a.submit(p,e)}}),x(a.content),Q(()=>{a.actions&&Q("footer",a.actionsAttrs,()=>x(a.actions))})})}import v from"aberdeen";import{current as N1}from"aberdeen/route";import u from"aberdeen";import{matchCurrent as c0,current as u1,go as f2}from"aberdeen/route";import V from"aberdeen";import{grow as r0,shrink as o0}from"aberdeen/transitions";V.insertGlobalCss({".s-toasts":"position:fixed bottom:$3 right:$3 z-index:400 display:flex flex-direction:column gap:$2 pointer-events:none max-width:min(90vw,24rem) w:24rem",".s-toast":{"&":"display:flex align-items:flex-start gap:$2 padding: $3; pointer-events:auto position:relative overflow:hidden",".s-toast-body":"display:flex flex-direction:column gap:$1 flex:1 min-width:0",".s-toast-title":"font-weight:700 line-height:1.3",".s-toast-close":"cursor:pointer border:0 background:transparent fg:$s-muted font-size:1.1em line-height:1 padding: 0 0.15em; r:4px flex-shrink:0 align-self:flex-start",".s-toast-close:hover":"fg:$s-text",".s-toast-close:focus-visible":"outline:none box-shadow: 0 0 0 3px $s-focus; fg:$s-text",".s-toast-progress":"position:absolute bottom:0 left:0 right:0 height:2px background:$s-accent width:100%"}});var d0=0,o1=V.proxy({});K(()=>{V.peek(()=>V.isEmpty(o1))&&V.isEmpty(o1)||V("div.s-toasts",()=>{V.onEach(o1,t=>{let{opts:a,id:e}=t,h=a.type==="danger"||a.type==="warning"?"alert":"status",p=a.type==null||a.type==="neutral"?"neutral":a.type,r=a.duration??6e3,o,d=null,c=()=>{clearTimeout(o),d&&(d.style.transition="none",d.style.width="100%",d.offsetWidth,d.style.transition=`width ${r}ms linear`,d.style.width="0%"),o=setTimeout(()=>E1(e),r)},n=()=>{clearTimeout(o),o=void 0,d&&(d.style.transition="none",d.style.width="100%")};V.clean(()=>clearTimeout(o)),V(`div.s-toast.s-s.${p}.extra-shadow aria-live=polite role=${h}`,"create=",r0,"destroy=",o0,a.attrs,()=>{r>0&&(V("mouseenter=",n),V("mouseleave=",c)),V("div.s-toast-body",()=>{V(()=>{a.title!=null&&V("div.s-toast-title",()=>x(a.title))}),V("div.s-toast-msg",()=>x(a.message))}),V(()=>{a.dismissible!==!1&&V("button.s-toast-close type=button aria-label=Dismiss",()=>{V("#\xD7"),V("click=",()=>E1(e))})}),r>0&&(d=V("div.s-toast-progress"))}),r>0&&requestAnimationFrame(c)})})});function E1(t){delete o1[t]}function m1(t){let a=++d0;return o1[a]={id:a,opts:t},()=>E1(a)}u.insertGlobalCss({".s-menu-list":"position:fixed z-index:350 min-width:10rem display:flex flex-direction:column p:$1 r:$s-radius-lg max-width: calc(100vw - 16px); overflow-y:auto max-height:min(80vh,28rem) transition: opacity 0.15s, transform 0.15s, visibility 0s;",".s-menu-list.hidden":"opacity:0 pointer-events:none transform:translateY(-6px) visibility:hidden transition: opacity 0.15s, transform 0.15s, visibility 0.15s;",".s-menu-item":"display:flex align-items:center gap:$2 w:100% scroll-margin:$2 padding: $m2 0; line-height:1.1 r:$s-radius cursor:pointer text-align:left font-weight:450 font-size:0.9em border:0 background:transparent fg:$s-text text-decoration:none transition: color 0.12s, transform 0.12s, text-shadow 0.12s;",".s-menu-item:focus-visible:not([aria-current=page]), .s-menu-item:hover:not([aria-disabled=true]):not([aria-current=page])":"filter:none color: color-mix(in lab, $s-primary 33%, $s-text);",".s-menu-item:focus-visible":"outline-offset:-2px background: color-mix(in srgb, $s-accent 14%, transparent);",".s-menu-item[aria-current=page]":"color:$s-accent filter:none",".s-menu-list .s-menu-item":"padding-inline:$2",".s-menu-item[aria-disabled=true]":"opacity:0.45 cursor:not-allowed pointer-events:none",".s-menu-icon":"flex-shrink:0",".s-menu-list .s-menu-icon":"display:flex",".s-menu-list .s-menu-icon > svg":"width:1.25em height:1.25em","hr.s-menu-sep":"border:0 height:1px margin: $1 0.6rem; background: linear-gradient(to right, transparent, $s-faint 18%, $s-faint 82%, transparent);",".s-menu-key":"margin-left:auto padding-left:$2 font-family:inherit font-size:0.8em opacity:0.55 white-space:nowrap flex-shrink:0","@media (hover: none) and (pointer: coarse)":{".s-menu-key":"display:none"},".s-menu-chevron":"margin-left:auto flex-shrink:0 display:flex transition: transform 0.15s ease;",".s-menu-key + .s-menu-chevron":"margin-left:0",".s-menu-chevron > svg":"width:1em height:1em",".s-menu-details":{"> summary":"list-style:none","> summary::-webkit-details-marker":"display:none","&::details-content":"interpolate-size:allow-keywords block-size:0 overflow-y:clip transition: block-size 0.15s ease, content-visibility 0.15s allow-discrete;","&[open]::details-content":"block-size:auto","&[open] > summary .s-menu-chevron":"transform:rotate(90deg)"},".s-menu-sub":"display:flex flex-direction:column gap:$1 padding-left:$3",".s-menu-inline":"display:flex flex-direction:column gap:$1"});function d1(t,a){u("keydown=",h=>{if(h.key==="Enter"&&!h.ctrlKey&&!h.metaKey&&!h.shiftKey&&!h.altKey&&h.target.tagName==="A"){queueMicrotask(()=>a?.());return}if(h.key!=="ArrowDown"&&h.key!=="ArrowUp"&&h.key!=="Home"&&h.key!=="End")return;h.preventDefault();let r=[...h.currentTarget.querySelectorAll(".s-menu-item")].filter(n=>n.getAttribute("aria-disabled")!=="true"&&!s0(n));if(!r.length)return;let o=r.indexOf(document.activeElement),d=h.key==="ArrowUp"?-1:1,c=h.key==="Home"?0:h.key==="End"?r.length-1:o<0?d>0?0:r.length-1:(o+d+r.length)%r.length;r[c].focus()});let e=u.derive(()=>q1(t));g2(t,a,e)}function g2(t,a,e){for(let h of t){if(typeof h=="string"||typeof h=="function"){x(h);continue}if("separator"in h){u("hr.s-menu-sep");continue}h.items?i0(h,a,e):n0(h,a)}}function n0(t,a){let e=!1,h=u(t.href?"a.s-menu-item data-panel=open":"button.s-menu-item type=button",t.attrs,()=>{t.href&&(u("href=",t.href),t.target&&u("target=",t.target),u(()=>{let p=!e;e=!0,T1(t)&&(u("aria-current=page"),requestAnimationFrame(()=>h.scrollIntoView({block:"nearest",behavior:p?"instant":"smooth"})))})),t.disabled&&u("aria-disabled=true"),t.key&&u("aria-keyshortcuts=",q(t.key,!0)),u("click=",p=>{if(t.disabled){p.preventDefault();return}a?.(),t.click?.(p)}),t.icon&&u("span.s-menu-icon",()=>x(t.icon)),x(t.label),H2(t)})}var b2=new Map;function y2(t,a){return b2.set(t,a),a}function i0(t,a,e){let h=t.href??w2(t.items),p=h!=null?u.derive(()=>R1(t)?y2(h,!0):e==null||e.value?y2(h,!1):b2.get(h)??!1):null;u("details.s-menu-details",()=>{p&&u(()=>{p.value&&u("open=true")}),u("summary.s-menu-item.s-menu-branch",t.attrs,()=>{t.disabled&&u("aria-disabled=true"),t.key&&u("aria-keyshortcuts=",q(t.key,!0)),u(()=>{T1(t)&&u("aria-current=page")}),u("click=",r=>{if(t.disabled){r.preventDefault();return}h!=null&&(r.preventDefault(),M0(h),f2(h)),t.click?.(r)}),t.icon&&u("span.s-menu-icon",()=>x(t.icon)),x(t.label),H2(t),u("span.s-menu-chevron aria-hidden=true",()=>s2())}),u("div.s-menu-sub",()=>g2(t.items,a,e))})}function s0(t){for(let a=t.closest("details");a;a=a.parentElement&&a.parentElement.closest("details"))if(!a.open&&t.closest("summary")?.parentElement!==a)return!0;return!1}function q1(t){return t.some(a=>typeof a!="string"&&typeof a!="function"&&!("separator"in a)&&R1(a))}function T1(t){if(t.href!=null&&c0(t.href))return!0;let a=t.match;if(a==null)return!1;let e=u1.path;if(typeof a=="function")return a(e);let h=a.replace(/\/+$/,"")||"/";return e===h||e.startsWith(h==="/"?"/":h+"/")}function R1(t){if(T1(t))return!0;for(let a of t.items??[])if(!(typeof a=="string"||typeof a=="function"||"separator"in a)&&R1(a))return!0;return!1}function w2(t){for(let a of t){if(typeof a=="string"||typeof a=="function"||"separator"in a)continue;let e=a.href??(a.items?w2(a.items):void 0);if(e!=null)return e}}function H2(t){t.key&&u("kbd.s-menu-key aria-hidden=true text=",q(t.key))}function c1(t,a){u(()=>{for(let e of A2(t(),[]))S(e.key,e.label,h=>{V2(),a?.(),e.click?.(h),e.href!=null&&l0(e.href,e.target)})})}function A2(t,a){for(let e of t)typeof e=="string"||typeof e=="function"||"separator"in e||(e.key&&!e.disabled&&a.push(e),e.items&&A2(e.items,a));return a}function l0(t,a){let e=new URL(t,location.href);a?window.open(e.href,a,a==="_blank"?"noopener":""):e.origin!==location.origin?location.href=e.href:f2(t)}var y1=null;function M0(t){try{y1=new URL(t,location.href).pathname.replace(/\/+$/,"")||"/"}catch{y1=null}}function D1(t){return y1!==t?!1:(y1=null,!0)}var G=u.proxy({opts:null});function F(){let t=G.opts?.anchor;G.opts=null,t?.focus()}function f1(t){let a=G.opts;return a!=null&&(t==null||a.anchor===t)}function V2(t){f1(t)&&F()}function x0(t,a){let e=t.offsetWidth,h=t.offsetHeight,p=window.innerWidth,r=window.innerHeight,o=4,d=a.left;d+e>p-8&&(d=Math.max(8,a.right-e));let c=a.bottom+o;c+h>r-8&&a.top-h-o>=8&&(c=a.top-h-o),t.style.left=Math.max(8,d)+"px",t.style.top=Math.max(8,c)+"px"}function v0(t){return[{label:"Open in new tab",icon:M2,click:()=>{window.open(t,"_blank","noopener")}},{label:"Copy link",icon:x2,click:()=>{m0(t)}}]}async function m0(t){let a=new URL(t,location.href).href;try{await navigator.clipboard.writeText(a),m1({message:"Link copied."})}catch{m1({message:"Couldn't copy the link.",type:"danger"})}}K(()=>{let t=G.opts;if(!t)return;let a=u("div.s-menu-list.s-s.neutral.shadow create=hidden destroy=hidden",t.dropdownAttrs,()=>{d1(t.link!=null?[...v0(t.link),{separator:!0},...t.items]:t.items,F)}),e=r=>{let o=r.target;!a.contains(o)&&(t.closeOnAnchorClick||!t.anchor.contains(o))&&F()},h=r=>{(r.key==="Escape"||r.key==="Tab")&&(r.preventDefault(),F())},p=u.peek(u1,"path");u(()=>{u1.path!==p&&!D1(u1.path)&&F()}),document.addEventListener("click",e,!0),document.addEventListener("keydown",h,!0),u.clean(()=>{document.removeEventListener("click",e,!0),document.removeEventListener("keydown",h,!0)}),requestAnimationFrame(()=>{if(!document.body.contains(a))return;let r=t.at?{left:t.at.x,right:t.at.x,top:t.at.y,bottom:t.at.y}:t.anchor.getBoundingClientRect();x0(a,r),J(a,".s-menu-item[aria-current=page]")})});function u0(t){u("nav.s-menu-inline",t.attrs,()=>{c1(()=>t.items,()=>t.onLeafSelect?.()),d1(t.items,t.onLeafSelect)})}function Z1(t){return G.opts=t,F}function B1(t){c1(()=>t.items);let a=null;u.clean(()=>{G.opts?.anchor===a&&F()}),u("contextmenu=",e=>{e.preventDefault(),a=e.currentTarget,Z1({...t,anchor:a,at:{x:e.clientX,y:e.clientY},closeOnAnchorClick:!0})})}function y0(t){c1(()=>t.items);let a=null;u.clean(()=>{G.opts?.anchor===a&&F()}),T({icon:v1,...t.button?.content==null?{ariaLabel:"Open menu"}:null,attrs:".neutral",...t.button,click:e=>{if(a=e.currentTarget,G.opts?.anchor===a){F();return}Z1({items:t.items,anchor:a,dropdownAttrs:t.dropdownAttrs})}})}import s,{OPAQUE as L2}from"aberdeen";import*as w from"aberdeen/route";import A from"aberdeen";var f0=P('<path d="m15 18-6-6 6-6"/>'),g0=P('<path d="m9 18 6-6-6-6"/>');A.insertGlobalCss({".s-strip":{"&":"position:relative display:flex min-width:0","> .s-strip-row":"display:flex align-items:center flex:1 min-width:0 overflow-x:auto overflow-y:hidden scrollbar-width:none scroll-behavior:smooth","> .s-strip-row::-webkit-scrollbar":"display:none","> .s-strip-btn":"position:absolute top:0 bottom:0 z-index:1 display:none align-items:center justify-content:center width:2.4em border:0 padding:0 cursor:pointer fg:$s-muted transition: color 0.15s;","> .s-strip-btn:hover":"fg:$s-text","> .s-strip-btn-left":"left:0 justify-content:flex-start background: linear-gradient(to right, $s-bg 45%, transparent)","> .s-strip-btn-right":"right:0 justify-content:flex-end background: linear-gradient(to left, $s-bg 45%, transparent)","&.s-can-left > .s-strip-btn-left, &.s-can-right > .s-strip-btn-right":"display:flex"},".s-tabs":{"&":"display:flex flex-direction:column gap:$3",".s-tabbar":"border-bottom: 1px solid $s-faint;",".s-tablist":"gap:$1 align-items:stretch margin-bottom:-1px",".s-tab":"display:inline-flex align-items:center gap:$2 cursor:pointer background:transparent border:0 color: $s-muted; font-weight:600 padding: 0.6em 0.9em; white-space:nowrap border-bottom: 3px solid transparent; transition: color 0.15s, background 0.15s, border-color 0.15s;",".s-tab:hover:not(:disabled), .s-tab[aria-selected=true]":"color: $s-text;",".s-tab:focus-visible":"outline:none box-shadow: inset 0 0 0 2px $s-focus; r: $s-radius;",".s-tab[aria-selected=true]":"border-image: $s-gradient 1;",".s-tabpanel":"display:block"}});function g1(t){A("div.s-strip",t.attrs,()=>{let a=A("div.s-strip-row",t.stripAttrs,()=>x(t.content));k2(a,-1),k2(a,1),w0(a)})}function b1(t){let a=t.parentElement;if(!a||!t.isConnected)return;let e=parseFloat(getComputedStyle(a).fontSize)*2.6,h=t.getBoundingClientRect(),p=a.getBoundingClientRect(),r=h.left-p.left,o=h.right-p.right;r<e?a.scrollBy({left:r-e,behavior:"smooth"}):o>-e&&a.scrollBy({left:o+e,behavior:"smooth"})}function b0(t){let a=U("tabs"),e=(r,o)=>r.id??String(o),h=t.bind??A.proxy(e(t.tabs[0]??{label:""},0));t.tabs.length>0&&!t.tabs.some((r,o)=>e(r,o)===A.peek(()=>h.value))&&(h.value=e(t.tabs[0],0));let p=(r,o)=>{r.disabled||(h.value=e(r,o))};A("div.s-tabs",t.attrs,()=>{g1({attrs:".s-tabbar",stripAttrs:".s-tablist role=tablist",content:()=>{t.tabs.forEach((r,o)=>{let d=e(r,o),c=A("button.s-tab type=button role=tab",()=>{A("id=",`${a}-tab-${d}`,"aria-controls=",`${a}-panel-${d}`),A(()=>{let n=h.value===d;A("aria-selected=",n?"true":"false"),A("tabindex=",n?"0":"-1"),n&&requestAnimationFrame(()=>b1(c))}),r.disabled&&A("disabled=true"),A("click=",()=>p(r,o)),A("keydown=",n=>H0(n,t.tabs,o,p)),x(r.icon),x(r.label)})})}}),A("div.s-tabpanel role=tabpanel",t.contentAttrs,()=>{A(()=>{let r=h.value,o=t.tabs.findIndex((c,n)=>e(c,n)===r),d=t.tabs[o]??t.tabs[0];d&&(A("id=",`${a}-panel-${e(d,o)}`,"aria-labelledby=",`${a}-tab-${e(d,o)}`),x(d.content))})})})}function k2(t,a){A(`button.s-strip-btn.s-strip-btn-${a<0?"left":"right"} type=button`,()=>{A("tabindex=-1 aria-hidden=true"),A("click=",()=>t.scrollBy({left:a*t.clientWidth*.8,behavior:"smooth"})),(a<0?f0:g0)({size:"1.1em"})})}function w0(t){let a=t.parentElement;if(!a||typeof ResizeObserver>"u")return;let e=()=>{let r=t.scrollWidth-t.clientWidth;a.classList.toggle("s-can-left",t.scrollLeft>1),a.classList.toggle("s-can-right",t.scrollLeft<r-1)};t.addEventListener("scroll",e,{passive:!0});let h=new ResizeObserver(e);h.observe(t);let p=typeof MutationObserver>"u"?void 0:new MutationObserver(r=>{for(let o of r){for(let d of o.addedNodes)d instanceof Element&&h.observe(d);for(let d of o.removedNodes)d instanceof Element&&h.unobserve(d)}e()});p?.observe(t,{childList:!0});for(let r of Array.from(t.children))h.observe(r);e(),A.clean(()=>{t.removeEventListener("scroll",e),h.disconnect(),p?.disconnect()})}function H0(t,a,e,h){let p=e;if(t.key==="ArrowRight"||t.key==="ArrowDown")p=(e+1)%a.length;else if(t.key==="ArrowLeft"||t.key==="ArrowUp")p=(e-1+a.length)%a.length;else if(t.key==="Home")p=0;else if(t.key==="End")p=a.length-1;else return;t.preventDefault();let r=p>=e?1:-1;for(let o=0;o<a.length;o++){let d=a[p];if(d&&!d.disabled){h(d,p),t.currentTarget?.parentElement?.children[p]?.focus();return}p=(p+r+a.length)%a.length}}var U1={integer(t){if(!/^(0|-?[1-9]\d*)$/.test(t))return;let a=Number(t);return Number.isSafeInteger(a)?a:void 0}};function B(t){let a=String(t).replace(/\/+$/,"");return a.startsWith("/")||(a=`/${a}`),a}function n1(t){let a=B(t);return a==="/"?[]:a.slice(1).split("/")}function C2(t){let a=n1(t),e=a.map((h,p)=>{if(!h.startsWith("[")||!h.endsWith("]"))return{kind:"lit",value:h};let r=/^\[\.\.\.([A-Za-z_$][\w$]*)\]$/.exec(h);if(r){if(p!==a.length-1)throw new Error(`Staffa: "${h}" must be the last segment of route "${t}"`);return{kind:"rest",name:r[1]}}let o=/^\[([A-Za-z_$][\w$]*)(?:=([A-Za-z_$][\w$]*))?\]$/.exec(h);if(!o)throw new Error(`Staffa: malformed param "${h}" in route "${t}"`);let[,d,c]=o;if(c&&!(c in U1))throw new Error(`Staffa: unknown matcher "${c}" in route "${t}" (known: ${Object.keys(U1).join(", ")})`);return{kind:"param",name:d,matcher:c}});return{key:t,segs:e}}function A0(t){try{return decodeURIComponent(t)}catch{return t}}function I1(t,a){let e={};for(let h=0;h<t.segs.length;h++){let p=t.segs[h];if(p.kind==="rest")return h>=a.length?null:(e[p.name]=a.slice(h).join("/"),e);if(h>=a.length)return null;let r=a[h];if(p.kind==="lit"){if(r!==p.value)return null}else if(p.matcher){let o=U1[p.matcher](r);if(o===void 0)return null;e[p.name]=o}else e[p.name]=A0(r)}return t.segs.length===a.length?e:null}var $2=250,V0=300,k0=360,K1=540,z2=2;s.insertGlobalCss({":root":`--s-panel-ms:${$2}ms`,".s-panels":"flex:1 min-width:0 min-height:0 position:relative overflow:clip isolation:isolate "+V1,".s-panel":{"&":"position:absolute top:0 bottom:0 left:0 display:flex flex-direction:column "+V1+" visibility:visible transition: left var(--s-panel-ms) ease, transform var(--s-panel-ms) ease-out, opacity var(--s-panel-ms) linear, visibility 0s;","&.s-panel-sep::before":"content:'' position:absolute left:0 top:0.6rem bottom:0.6rem width:1px z-index:1 background: linear-gradient(to bottom, transparent, $s-faint 18%, $s-faint 82%, transparent);","&.s-panel-enter":"opacity:0 transition:none transform: translateX(8cqw);","&.s-panel-closing":"opacity:0 pointer-events:none transform: translateX(8cqw);","&.s-panel-hidden, &.s-panel-parked":"opacity:0 visibility:hidden transition: left var(--s-panel-ms) ease, transform var(--s-panel-ms) ease-out, opacity var(--s-panel-ms) linear, visibility var(--s-panel-ms);","&.s-panel-hidden":"transform: translateX(-8cqw);","&.s-panel-parked":"transform: translateX(8cqw);"},".s-panel > .s-content":"flex:1 min-height:0 overflow-y:auto overflow-x:hidden p:$3",".s-panel-actions":"display:flex align-items:center justify-content:flex-end gap:$1 flex-shrink:0 padding: $3 $3 0;",".s-crumbs > .s-strip-row":"gap:$m1",".s-crumb":{"&":"flex: 1 0 4rem; font-size:0.85em line-height:1.5 fg:$s-muted text-decoration:none white-space:nowrap max-width:max-content overflow:hidden text-overflow:ellipsis transition: color 0.12s;","&.s-crumb-on":"font-weight:600 fg:$s-text","a&:hover":"filter:none color: color-mix(in lab, $s-primary 33%, $s-text);","svg.s-crumb-pin":"vertical-align:-0.12em margin-right:0.3em opacity:0.8 fill:currentColor","svg.s-crumb-unsaved":"vertical-align:0.08em margin-right:0.3em fill:currentColor"},"svg.s-crumb-sep":"flex-shrink:0 opacity:0.4",".s-main.s-shell-snap .s-panel":"transition:none",".s-panel-loading":{"&":"position:absolute inset:0 display:flex align-items:center justify-content:center gap:$1 pointer-events:none",i:"width:0.5rem height:0.5rem r:50% background:$s-muted opacity:0.45 animation: s-panel-pulse 1s ease-in-out infinite;","i:nth-child(2)":"animation-delay:0.15s","i:nth-child(3)":"animation-delay:0.3s"},"@keyframes s-panel-pulse":{"0%, 100%":"opacity:0.25 transform:scale(0.8)","50%":"opacity:0.7 transform:scale(1)"}});var F1=!1,w1=class{[L2]=!0;compiled;ancestors;opts;$state=s.proxy({live:[],focus:0});$open=s.proxy({});nextOrder=0;containerEl;geom;lastGeom;layoutQueued=!1;timers=new Set;intent=null;settling=null;lastSeen=null;queued=null;constructor(a){if(F1)throw new Error("Staffa: only one routed S.main() (one with `routes`) can be active at a time");F1=!0,this.opts=a,this.compiled=Object.entries(a.routes).map(([e,h])=>({...C2(e),draw:h})),this.ancestors=Object.entries(a.ancestors??{}).filter(e=>e[1]!=null).map(([e,h])=>({...C2(e),fn:h})),s(()=>{let e=this.computeTarget(),h={...w.current.search},p=w.current.hash;s.peek(()=>{let r=this.lastSeen;if(r&&r.path!==w.current.path){let o=this.$state.live.find(d=>d.path===r.path);o&&(o.search=r.search,o.hash=r.hash)}this.lastSeen={path:w.current.path,search:h,hash:p},this.propose(e),Array.isArray(w.current.state.panels)||Object.assign(w.current.state,this.stateFor({stack:this.paths(),focus:this.$state.focus}))})}),this.interceptLinks(),this.watchTitle(),this.guardTabClose(),s.clean(()=>{for(let e of this.timers)clearTimeout(e);this.timers.clear(),this.queued?.settle(!1),this.queued=null,F1=!1})}resolve(a){let e=n1(a);for(let h of this.compiled){let p=I1(h,e);if(p)return{draw:h.draw,params:p}}return{draw:this.opts.notFound??z0,params:{}}}matches(a){let e=n1(a);return this.compiled.some(h=>I1(h,e)!=null)}deriveStack(a){let e=B(a),h=this.askAncestors(e),p=h?h.map(B):this.prefixesOf(e),r=[];for(let o of p)o!==e&&!r.includes(o)&&this.matches(o)&&r.push(o);return r.push(e),r}askAncestors(a){let e=n1(a);for(let h of this.ancestors){let p=I1(h,e);if(p)return h.fn(p,a)??void 0}}prefixesOf(a){let e=n1(a),h=[];for(let p=1;p<e.length;p++)h.push("/"+e.slice(0,p).join("/"));return h}pinnedIn(a,e){return a.filter(h=>e.includes(h)?!1:this.$state.live.find(p=>p.path===h)?.$panel.pinned===!0)}unsavedAt(a){return this.$state.live.find(e=>e.path===a)?.$panel.unsaved===!0}targetFor(a,e){let h=Array.isArray(e?.panels)?e.panels.map(String):null;if(h){let p=Array.isArray(e.parked)?e.parked.map(String):[],r=B(a),o=new Set([r]),d=n=>n.map(B).filter(y=>!o.has(y)&&!!o.add(y)),c=d(h);return{stack:[...c,r,...d(p)],focus:c.length}}return s.peek(()=>{let p=this.deriveStack(a).slice(0,-1),r=[...p,...this.pinnedIn(this.paths(),[...p,B(a)]),B(a)];return{stack:r,focus:r.length-1}})}computeTarget(){return this.targetFor(w.current.path,w.current.state)}paths(){return this.$state.live.map(a=>a.path)}propose(a){let e=this.$state.live.filter(h=>!a.stack.includes(h.path)&&h.$panel.unsaved).map(h=>h.path);e.length&&(a={stack:[...a.stack,...e],focus:a.focus}),!(S2(this.paths(),a.stack)&&a.focus===this.$state.focus)&&this.commit(a,w.current.nav)}commit(a,e){this.geom=void 0;let h=w.current.state.pinned,p=new Set(Array.isArray(h)?h.map(String):[]),r=new Map(this.$state.live.map(d=>[d.path,d])),o=[];for(let d of a.stack){let c=r.get(d);if(c){r.delete(d),o.push(c);continue}let n=this.createEntry(d,o.length<=a.focus,p.has(d));e!=="load"&&e!=="back"&&(n.enter=!0),o.push(n),this.$open[d]=n}for(let d of r.values())this.beginClose(d);this.$state.live=o,this.$state.focus=Math.min(a.focus,o.length-1),this.scheduleLayout()}createEntry(a,e,h){let{draw:p,params:r}=this.resolve(a),o={[L2]:!0,order:this.nextOrder++,path:a,draw:p,$ui:s.proxy({holding:!1}),maxWidth:"medium",width:0};return o.$panel=s.proxy({stack:this,params:r,path:a,width:0,visible:e,pinned:h||void 0,close:()=>this.closePath(o.path),open:(d,c)=>this.navigate(d,{from:o.path,how:c})}),o}beginClose(a){a.closing=!0,a.$panel.visible=!1,a.el&&(a.el.style.zIndex=String(z2*this.$state.live.indexOf(a))),delete this.$open[a.path]}playExit(a,e){if(!a.closing){e.remove();return}e.classList.add("s-panel-closing"),e.setAttribute("inert","");let h=()=>{clearTimeout(p),this.timers.delete(p),e.remove()};e.addEventListener("transitionend",r=>{r.target===e&&r.propertyName==="opacity"&&h()});let p=setTimeout(h,$2+80);this.timers.add(p)}intended(){return this.intent??{stack:this.paths(),focus:this.$state.focus}}stateFor(a){return{panels:a.stack.slice(0,a.focus),parked:a.stack.slice(a.focus+1),pinned:this.pinnedPaths()}}pinnedPaths(){return this.$state.live.filter(a=>a.$panel.pinned).map(a=>a.path)}issue(a,e){return this.intent=a,this.settling?(this.queued?.settle(!1),new Promise(h=>{this.queued={run:e,settle:h}})):this.start(e)}start(a){let e=p=>{this.settling=null;let r=this.queued;return this.queued=null,p&&r?this.start(r.run).then(r.settle,()=>r.settle(!1)):(this.intent=null,r?.settle(!1)),p},h=Promise.resolve(a()).then(e,p=>(console.error(p),e(!1)));return this.settling=h,h}focusAt(a){let e=this.intended();if(a<0||a>=e.stack.length||a===e.focus)return Promise.resolve(!1);let h={stack:e.stack,focus:a},p=e.stack[a];return this.issue(h,()=>{let r=this.$state.live.find(o=>o.path===p);return w.go({path:p,search:r?.search,hash:r?.hash,state:this.stateFor(h)})})}back(){return s.peek(()=>{let a=this.intended();return a.focus===a.stack.length-1&&!this.unsavedAt(a.stack[a.focus])?this.closePath(a.stack[a.focus]??""):a.focus===0?Promise.resolve(!1):this.focusAt(a.focus-1)})}closePath(a){return s.peek(()=>{let e=this.intended(),h=e.stack.indexOf(B(a));if(h<0||e.stack.length<2||this.unsavedAt(e.stack[h]))return Promise.resolve(!1);let p=e.stack.filter((n,y)=>y!==h),r=h===e.focus?Math.max(0,h-1):e.focus-(h<e.focus?1:0),o={stack:p,focus:r};if(h===e.focus&&h===e.stack.length-1){let n=this.$state.live.find(m=>m.path===p[r]),y={};n?.search&&(y.search=n.search),n?.hash&&(y.hash=n.hash);let i=p.filter(m=>this.$state.live.find(g=>g.path===m)?.$panel.pinned===!0);return this.issue(o,()=>Promise.resolve(w.back({path:p[r],state:{panels:p.slice(0,r),parked:[]}},y)).then(m=>(m&&(w.current.state.pinned=i),m)))}let d=p[r],c=d!==e.stack[e.focus];return this.issue(o,()=>{let n=c?this.$state.live.find(y=>y.path===d):void 0;return w.go({path:d,search:c?n?.search:{...w.current.search},hash:c?n?.hash:w.current.hash,state:this.stateFor(o)})})})}navigate(a,{from:e,how:h,beneath:p}={}){let r=h??this.opts.linkNavigation,o=r==="open"?null:e??null,d=r==="replace";return s.peek(()=>{let c;try{c=new URL(a,location.href)}catch{return Promise.resolve(!1)}let n=B(c.pathname),y=this.intended(),i=p?-1:y.stack.indexOf(n),m;if(i>=0&&r!=="replace"&&r!=="open"){let f=this.pinnedIn(y.stack.slice(i+1),[]);m={stack:[...y.stack.slice(0,i+1),...f],focus:i}}else{let f=o==null?-1:y.stack.indexOf(o),z=(p?p.map(B):f<0?this.deriveStack(n).slice(0,-1):y.stack.slice(0,d?f:f+1)).filter((W1,O2,E2)=>W1!==n&&E2.indexOf(W1)===O2),i1=[...z,...this.pinnedIn(y.stack,[...z,n,d?o:null])];m={stack:[...i1,n],focus:i1.length}}let g=i>=0?this.$state.live.find(f=>f.path===n):void 0,H=c.search?Object.fromEntries(new URLSearchParams(c.search)):g?.search??{},l=c.hash||g?.hash||"";return m.focus===y.focus&&S2(m.stack,y.stack)&&c.search===location.search&&(c.hash||"")===(location.hash||"")?Promise.resolve(!0):this.issue(m,()=>w.go({path:n,search:H,hash:l,state:this.stateFor(m)}))})}pushPath(a,e){return s.peek(()=>{let h=this.intended();return this.navigate(a,{from:h.stack[h.focus],how:e?"replace":"push"})})}interceptLinks(){w.interceptLinks((a,e,h)=>{if(h instanceof KeyboardEvent&&(h.ctrlKey||h.metaKey||h.shiftKey||h.altKey))return!1;let p=e.getAttribute("data-panel")??void 0,r=e.closest(".s-panel"),o=r?this.$state.live.find(d=>d.el===r):e.closest(".s-panel-origin")?this.$state.live[this.$state.focus]:void 0;return this.navigate(a.href,{from:o?.path,how:p}),!0})}get currentPanel(){return this.$state.live[this.$state.focus]?.$panel}get panels(){return this.$state.live.map(a=>a.$panel)}get currentPanelIndex(){return this.$state.focus}pushPanel(a){return this.pushPath(a,!1)}replacePanel(a){return this.pushPath(a,!0)}openPanelStack(a,e){return this.navigate(a,{how:"open",beneath:e})}closePanel(a){return s.peek(()=>{let e=this.intended();return this.closePath(a??e.stack[e.focus]??"")})}setColumns(a){this.opts.columns!==a&&(this.opts.columns=a,this.scheduleLayout())}setLinkNavigation(a){this.opts.linkNavigation=a}drawCrumbs(){g1({attrs:".s-crumbs role=navigation aria-label=Breadcrumbs",content:()=>{s(()=>{let a=this.panels.map(p=>p.path),e=this.currentPanelIndex,h;for(let p=0;p<a.length;p++){p&&m2({size:"0.85em",attrs:".s-crumb-sep"});let r=this.drawCrumb(a[p],p,p===e);p===e&&(h=r)}requestAnimationFrame(()=>{h&&b1(h)})})}})}drawCrumb(a,e,h){let p=this.$state.live[e];return s(h?"span.s-crumb aria-current=page":"a.s-crumb",()=>{h||s("href=",a),s(()=>{p?.$panel.visible&&s(".s-crumb-on")}),s(()=>{p?.$panel.unsaved&&l2({size:"0.45em",attrs:".s-crumb-unsaved"})}),s(()=>{p?.$panel.pinned&&P1({size:"0.85em",attrs:".s-crumb-pin"})}),s(()=>{s("#",p?.$panel.title??p?.$ui.fallback??(a.split("/").pop()||a))}),B1({link:a,items:[{label:()=>{s(()=>{s("#",p?.$panel.pinned?"Unpin":"Pin")})},icon:()=>{s(()=>{(p?.$panel.pinned?v2:P1)()})},click:()=>{p&&this.togglePin(p)}},{label:"Close",icon:e1,disabled:p?.$panel.unsaved===!0,click:()=>{this.closePath(a)}}]})})}togglePin(a){a.$panel.pinned=!a.$panel.pinned||void 0,w.current.state.pinned=this.pinnedPaths()}watchTitle(){let a=document.title;s(()=>{let e=this.$state.live[this.$state.focus],h=e?.$panel.title??e?.$ui.fallback,p=typeof this.opts.title=="string"?this.opts.title:void 0,r=this.$state.live.some(d=>d.$panel.unsaved),o=h&&p?`${h} \xB7 ${p}`:h||p;o&&(document.title=(r?"\u2022 ":"")+o)}),s.clean(()=>{document.title=a})}guardTabClose(){if(typeof window>"u")return;let a=e=>{let h=this.$state.live.find(p=>p.$panel.unsaved);h&&(e.preventDefault(),e.returnValue=!0,this.flushLayout(),h.$panel.visible||this.focusAt(this.intended().stack.indexOf(h.path)))};s(()=>{this.$state.live.some(e=>e.$panel.unsaved)&&(window.addEventListener("beforeunload",a),s.clean(()=>window.removeEventListener("beforeunload",a)))})}drawColumns(){let a=s("div.s-panels role=main",()=>{this.containerEl=s(),s.onEach(this.$open,e=>this.drawPanel(e),e=>e.order)});if(typeof ResizeObserver<"u"){let e=new ResizeObserver(()=>this.layout());e.observe(a),s.clean(()=>e.disconnect())}s.clean(()=>{this.containerEl===a&&(this.containerEl=void 0)}),this.scheduleLayout()}drawPanel(a){let e;s(()=>{let h=a.$panel.maxWidth;a.maxWidth=h==="small"||h==="large"||h==="none"?h:"medium";let p=this.roomFor(a.maxWidth);p&&(a.width=p,s.peek(a.$panel,"width")!==p&&(a.$panel.width=p),e&&(e.style.width=`${p}px`,this.scheduleLayout()))}),e=s(`section.s-panel${a.width?` w:${a.width}px`:""}`,"destroy=",h=>this.playExit(a,h),()=>{s(()=>this.drawActions(a)),s("div.s-content",()=>{if(a.draw(a.$panel),w.persistScroll(a.path),s.peek(a.$panel,"title")==null){let h=C0(s());h&&s.peek(a.$ui,"fallback")!==h&&(a.$ui.fallback=h)}}),s(()=>{!a.$panel.loading||a.$ui.holding||s("div.s-panel-loading aria-hidden=true",()=>{s("i"),s("i"),s("i")})})}),a.el=e,a.placed=!1,e.style.transition="none",s.clean(()=>{a.el===e&&(a.el=void 0)}),s(()=>{a.$panel.loading,this.scheduleLayout()}),this.scheduleLayout()}drawActions(a){this.opts.$shell.narrow||a.$panel.actions==null||s("div.s-panel-actions",()=>x(a.$panel.actions))}scheduleLayout(){this.layoutQueued||(this.layoutQueued=!0,requestAnimationFrame(()=>this.flushLayout()))}flushLayout(){this.layoutQueued&&(this.layoutQueued=!1,this.layout())}measure(){let a=this.containerEl,e=a?a.getBoundingClientRect().width:0;if(!e)return;let h=Math.min(e/Math.max(1,Math.floor(e/k0)),K1),p=r=>Math.min(r*h,e);return{area:e,size:{small:h,medium:p(2),large:p(3),none:e}}}geometry(){return this.geom??=this.measure()}roomFor(a){return this.geometry()?.size[a]??0}layout(){let a=this.containerEl,e=a?.closest(".s-main");if(!a||!e)return;let h=this.$state.live,p=h.length;if(!p||h.some(l=>!l.el))return;this.geom=void 0;let r=this.geometry();if(!r)return;let o=this.opts.columns==="single",d=this.lastGeom?.area!==r.area;d&&(this.lastGeom=r,e.classList.add("s-shell-snap"));let c=l=>r.size[l.maxWidth],n=Math.min(this.$state.focus,p-1),y=n,i=c(h[n]);if(!o)for(let l=n-1;l>=0;l--){let f=i+c(h[l]);if(f>r.area)break;i=f,y=l}let m=(r.area-i)/2;for(let l=y;l<=n;l++)h[l].width=c(h[l]);for(let l of h)l.width||(l.width=c(l));let g=[],H=m;for(let l=0;l<p;l++){let f=h[l],C=f.el,z=l>=y&&l<=n;L0(C,z?H:l>n?m+i:m,f.width,z2*l+1),f.$panel.visible!==z&&(f.$panel.visible=z),f.$panel.width!==f.width&&(f.$panel.width=f.width),z&&(H+=f.width),C.classList.toggle("s-panel-sep",z&&l>y),C.classList.toggle("s-panel-hidden",l<y),C.classList.toggle("s-panel-parked",l>n),C.toggleAttribute("inert",!z),!f.placed&&(g.push(f),!f.$panel.loading||f.holdDone?f.$ui.holding=!1:f.$ui.holding||(f.$ui.holding=!0,this.holdEnter(f)),f.enter&&z&&C.classList.add("s-panel-enter"))}(g.length||d)&&a.offsetWidth,d&&e.classList.remove("s-shell-snap");for(let l of g)l.$ui.holding||(l.el.style.transition="",l.el.classList.remove("s-panel-enter"),l.enter=!1,l.placed=!0)}holdEnter(a){let e=setTimeout(()=>{this.timers.delete(e),a.holdDone=!0,a.$ui.holding&&(a.$ui.holding=!1,this.scheduleLayout())},V0);this.timers.add(e)}};function L0(t,a,e,h){t.style.left=`${a}px`,t.style.width=`${e}px`,t.style.zIndex=String(h)}function S2(t,a){return t.length===a.length&&t.every((e,h)=>e===a[h])}function C0(t){let a=document.createTreeWalker(t,NodeFilter.SHOW_TEXT);for(let e=a.nextNode();e;e=a.nextNode()){let h=e.textContent.trim();if(h)return h.length>48?`${h.slice(0,47).trimEnd()}\u2026`:h}}function z0(t){s("p fg:$s-muted",()=>s("#",`No panel at ${t.path}`))}var S0=200;v.insertGlobalCss({".s-main":{"&":"display:flex flex-direction:column min-height:100vh max-height:100vh container-type:inline-size","body > &":"margin: calc(-1 * $3)","> header":"border:0 border-bottom: 1px solid $s-faint; r:0 position:sticky top:0 z-index:10","> footer":"border-top: 1px solid $s-faint; fg:$s-muted","> header > .s-bar, > footer > .s-bar":"display:flex align-items:center width:100% margin-inline:auto gap:$3 padding: $2 $3;","> header .s-logo, > header .s-nav-trigger":"display:flex align-items:center flex-shrink:0","> header .s-nav-trigger":"margin-left:-0.375rem","> header .s-logo":"font-size:1.4em background: $s-gradient; -webkit-background-clip:text; background-clip:text; color:transparent;","> header .s-titles":"display:flex flex-direction:column min-width:5rem flex: 0 1 auto;","> header .s-subtitle":"fg:$s-muted font-size:0.85em line-height:1.5 overflow:hidden text-overflow:ellipsis white-space:nowrap","> header .s-title":"font-weight:800 font-size:1.1em line-height:1.2 overflow:hidden text-overflow:ellipsis white-space:nowrap letter-spacing:-0.01em background: $s-gradient; -webkit-background-clip:text; background-clip:text; color:transparent; width:fit-content max-width:100%","> header a.s-logo, > header a.s-title":"text-decoration:none filter:none cursor:pointer","> header .s-menu":"display:flex align-items:center justify-content:flex-end gap:$2 flex: 1 0.1 auto; min-width:0",".s-body":"flex:1 overflow:clip display:flex flex-direction:row min-height:0 justify-content:center position:relative",".s-body-inner":"flex:1 min-width:0 display:flex flex-direction:row min-height:0","&.s-nav-right .s-body-inner":"flex-direction:row-reverse",".s-nav-sep":"width:1px flex-shrink:0 align-self:stretch margin: 0.6rem 0; border:0 background: linear-gradient(to bottom, transparent, $s-faint 18%, $s-faint 82%, transparent);",".s-body main":"flex:1 min-width:0 min-height:0 overflow-x:hidden overflow-y:auto display:flex flex-direction:column transition: transform var(--s-panel-ms) ease;",".s-body main.s-slide-in":"transform: translateX(100%); transition:none",".s-body main > .s-content":"width:100% flex:1 p:$3",".s-body main.s-scroll-y":"margin-right:$3"},".s-nav-panel":{"&":"display:flex flex-direction:column overflow-y:auto flex-shrink:0 width: calc(var(--s-nav-w) - 1px); padding:$3 gap:$1"},".s-nav-page":{"&":"position:absolute inset:0 z-index:5 display:flex flex-direction:column overflow-y:auto overscroll-behavior:contain border:0 r:0 padding:$2 gap:$1 transition: transform var(--s-panel-ms) ease, visibility 0s;","&.s-nav-page-off":"transform:translateX(-100%) pointer-events:none visibility:hidden transition: transform var(--s-panel-ms) ease, visibility var(--s-panel-ms);",".s-menu-item":"padding: $2 $3; min-height:3rem font-size:1.05em gap:$3"},[`@container (max-width: ${M1}px)`]:{".s-main .s-nav-panel, .s-main .s-nav-sep":"display:none",".s-main > header > .s-bar":"gap:$1 padding: $1 $2;",".s-main .s-body main.s-scroll-y":"margin-right:0"},[`@container (max-width: ${K1}px)`]:{".s-content > .s-box":"margin-inline: calc(-1 * $3); r:0 border-inline:0"}});function $0(t={}){let a=t.nav,e=t.navPosition??"left",h=v.proxy({open:!1}),p=v.proxy({narrow:typeof document<"u"&&document.documentElement.clientWidth<=M1}),r=t.routes;if(r!=null&&t.content!=null)throw new Error("Staffa: S.main() takes either `content` or `routes`, not both");let o=r?new w1({routes:r,notFound:t.notFound,ancestors:t.ancestors,title:t.title,$shell:p}):null;o&&(v(()=>o.setColumns(t.columns)),v(()=>o.setLinkNavigation(t.linkNavigation)));let d=o&&t.home!==null?t.home??"/":null,c=()=>{t.maxWidth!=null&&v("max-width:",t.maxWidth)},n=v("div.s-main",t.attrs,()=>{v(()=>{a==null||!a.items.length?v("--s-nav-w: 0px"):v(`.s-nav-${e}`,`--s-nav-w: ${t.navWidth??S0}px`)}),v(()=>{(o!=null||t.title!=null||t.subtitle!=null||t.logo!=null||t.menu!=null||a!=null&&a.items.length>0)&&v("header.s-s.neutral",t.topbarAttrs,()=>{v("div.s-bar",()=>{v(c),v(()=>{if(p.narrow&&a!=null&&a.items.length){v("div.s-nav-trigger",()=>T0(a,h));return}t.logo!=null&&v(d!=null?"a.s-logo aria-label=Home":"div.s-logo",()=>{d!=null&&v("href=",d),x(t.logo)})}),v("div.s-titles",()=>{v(()=>{t.title!=null&&v(d!=null?"a.s-title":"div.s-title",()=>{d!=null&&v("href=",d),x(t.title)})}),O0(t,o,a,p)}),v(()=>{let i=p.narrow?o?.currentPanel?.actions:void 0,m=i??t.menu;m!=null&&v(`div.s-menu${i!=null?".s-panel-origin":""}`,()=>x(m))})})})}),v("div.s-body",()=>{v("div.s-body-inner",()=>{v(c),v(()=>{a==null||!a.items.length||(v(`nav.s-nav-panel.s-nav-${e}`,t.navAttrs,()=>{d1(a.items)}),v("div.s-nav-sep aria-hidden=true"))}),Z0(t,o)}),v(()=>{a!=null&&a.items.length&&h.open&&R0(a,t.navPageAttrs,h,p)})}),v(()=>{t.footer!=null&&v("footer",()=>{v("div.s-bar",()=>{v(c),x(t.footer)})})})});return q0(n,p),a!=null&&c1(()=>a.items,()=>{h.open=!1}),(a!=null||o)&&v(()=>{let y=m=>()=>{S1()||f1()||m()},i=()=>n.querySelector(".s-nav-trigger button");h.open?S("Esc","Close the navigation",y(()=>{h.open=!1,i()?.focus()}),"global"):o&&o.currentPanelIndex>0?S("Esc","Back to the previous panel",y(()=>{o.back()}),"global"):S("Esc","Jump to the navigation",y(()=>{let m=n.querySelector(".s-nav-panel");m?.offsetParent!=null?(m.querySelector("[aria-current=page]")??m.querySelector(".s-menu-item:not([aria-disabled=true])"))?.focus():i()?.click()}),"global")}),o??void 0}var H1=null;function P0(){H1?.()}function O0(t,a,e,h){v(()=>{if(t.subtitle!=null&&(a==null||E0(a,e,h))){v("div.s-subtitle",()=>x(t.subtitle));return}a?.drawCrumbs()})}function E0(t,a,e){return e.narrow||a==null||t.panels.length>1?!1:q1(a.items)}function q0(t,a){if(typeof ResizeObserver>"u")return;let e=new ResizeObserver(h=>{let p=h[0]?.contentBoxSize?.[0],r=p?p.inlineSize:h[0]?.contentRect.width;r!=null&&(a.narrow=r<=M1)});e.observe(t),v.clean(()=>e.disconnect())}function T0(t,a){h1({icon:t.button?.icon??(()=>v(()=>(a.open?e1:v1)())),ariaLabel:t.button?.ariaLabel??"Open navigation",attrs:t.button?.attrs,click:()=>{a.open=!a.open}})}function R0(t,a,e,h){let p=!1,r=()=>{p=!0,e.open=!1},o=v("nav.s-nav-page.s-s.neutral aria-label=Navigation create=s-nav-page-off destroy=s-nav-page-off",a,()=>d1(t.items,r));H1=r,v.clean(()=>{H1===r&&(H1=null)});let d=v.peek(N1,"path");v(()=>{N1.path!==d&&!D1(N1.path)&&r()});let c=o.closest(".s-main"),n=o.parentElement?.querySelector(":scope > .s-body-inner"),y=n?.querySelector(":scope > main");n?.setAttribute("inert",""),v(()=>{h.narrow||(e.open=!1)}),v.clean(()=>{n?.removeAttribute("inert"),p&&(y&&D0(y),c?.querySelector(".s-nav-trigger button")?.focus())}),requestAnimationFrame(()=>{document.body.contains(o)&&J(o,".s-menu-item[aria-current=page]")})}function D0(t){t.classList.add("s-slide-in"),t.offsetWidth,t.classList.remove("s-slide-in")}function Z0(t,a){if(a){a.drawColumns();return}let e=v("main",()=>{v("div.s-content",t.contentAttrs,()=>{x(t.content)})});B0(e)}function B0(t){if(typeof ResizeObserver>"u")return;let a=()=>t.classList.toggle("s-scroll-y",t.offsetWidth>t.clientWidth),e=new ResizeObserver(a);e.observe(t),t.firstElementChild&&e.observe(t.firstElementChild),a(),v.clean(()=>e.disconnect())}import O from"aberdeen";O.insertGlobalCss({".s-select_wrap":{"&":"position:relative display:block",select:"w:100% cursor:pointer padding-right:2.2em; appearance:none","&::after":"content: '\u25BE'; position:absolute right:0.7em top:50%; transform: translateY(-50%); pointer-events:none fg:$s-muted font-size:0.85em"}});function I0(t){N(t,(a,e)=>{O("div.s-select_wrap",()=>{O("select.s-input",t.inputAttrs,()=>{t1(t,a,e),O("change=",h=>{t.bind&&(t.bind.value=h.target.value)}),O(()=>{let h=typeof t.options=="function"?t.options():t.options,p=t.bind?.value??"";t.placeholder!=null&&O("option",()=>{O("value= disabled=true hidden=true"),p||O("selected=true"),O("#",t.placeholder)});for(let r of h){let o=typeof r=="string"?{value:r,label:r}:{value:r.value,label:r.label??r.value};O("option",()=>{O("value=",o.value),o.value===p&&O("selected=true"),O("#",o.label)})}})})})})}import I from"aberdeen";I.insertGlobalCss({"textarea.s-input":"resize:vertical min-height:3em line-height:1.45","textarea.s-input.s-autoGrow":"resize:none min-height:2.5em overflow-y:hidden"});function F0(t={}){let a=t.autoGrow!==!1;N(t,(e,h)=>{let p=I("textarea.s-input",t.inputAttrs,()=>{a?(I(".s-autoGrow"),I("input=",r=>{P2(r.currentTarget),t.input&&t.input(r)})):(I("rows=",t.rows??4),I("resize:",t.resize??"vertical"),t.input&&I("input=",t.input)),t.placeholder!=null&&I("placeholder=",t.placeholder),t.value!=null&&!t.bind&&I("value=",t.value),t.change&&I("change=",t.change),t1(t,e,h,t.bind)});a&&requestAnimationFrame(()=>P2(p))})}function P2(t){t.style.height="auto",t.style.height=`${t.scrollHeight}px`}export{B1 as addContextMenu,C1 as addTooltip,G2 as alert,J2 as autocomplete,S as bindKey,a0 as box,T as button,e0 as buttonChooser,X as buttonGroup,h0 as checkbox,V2 as closeFloatingMenu,P0 as closeNav,X2 as confirm,a1 as dialog,p0 as form,q as formatKey,_1 as getDarkMode,h1 as iconButton,S1 as isDialogOpen,f1 as isFloatingMenuOpen,$0 as main,u0 as menu,y0 as menuButton,j2 as prompt,b1 as revealInStrip,g1 as scrollStrip,I0 as select,T2 as setDarkMode,_2 as setKeyHelp,Z1 as showFloatingMenu,$1 as showKeyHelp,b0 as tabs,F0 as textarea,z1 as textline,m1 as toast};
|
|
1
|
+
import D from"aberdeen";var X1=t=>`background: linear-gradient(${t}, color-mix(in oklab, $s-bg, white 9%), color-mix(in oklab, $s-bg, black 9%));`,G1=X1("170deg"),L1=X1("180deg"),k1="staffa:darkMode",j1=D.proxy({value:q2()});function q2(){try{let t=localStorage.getItem(k1);if(t==="dark")return!0;if(t==="light")return!1}catch{}}function T2(t){j1.value=t;try{t===void 0?localStorage.removeItem(k1):localStorage.setItem(k1,t?"dark":"light")}catch{}}function _1(t=!1){let a=j1.value;return a===void 0&&!t?D.darkMode():a}D(()=>{_1()?D.insertGlobalCss({":root, .s-s.neutral":"--s-bg:#0e0f12 --s-text:#e9eaec",".s-s.neutral":"--s-bg:#191b1f --s-text:#e9eaec",".s-s.neutral .s-s.neutral":"--s-bg:#23262b"}):D.insertGlobalCss({":root, .s-s.neutral":"--s-bg:#eef0f3 --s-text:#1d1f24",".s-s.neutral, .s-s.neutral":"--s-bg:#ffffff --s-text:#1d1f24",".s-s.neutral .s-s.neutral":"--s-bg:#f6f7f9"})});D.setSpacingCssVars(1.1);D.insertGlobalCss({"*, *::before, *::after":"box-sizing:border-box",html:"text-size-adjust:100%",body:"m:0 p:$3 line-height:1.5 font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; -webkit-font-smoothing:antialiased background-color:$s-bg text:$s-text",a:"color: $s-link-fg; text-decoration:underline text-underline-offset:2px; transition: color 0.12s, filter 0.12s;","a:hover":"filter: brightness(1.15)","input, button, textarea, select, optgroup":"font:inherit color:inherit","input:where(:not([type=checkbox],[type=radio],[type=range],[type=file],[type=color],[type=image],[type=submit],[type=button],[type=reset],[type=hidden])), textarea, select":"background:$s-bg border: 1px solid $s-faint; r:$s-radius-sm padding: 0.45em 0.65em; max-width:100%","input:where([type=checkbox],[type=radio])":"width:1.15em height:1.15em cursor:pointer","input[type=range]":"appearance:none background:transparent cursor:pointer vertical-align:middle","input[type=range]::-webkit-slider-runnable-track":"height:4px r:99px background:$s-faint","input[type=range]::-moz-range-track":"height:4px r:99px background:$s-faint","input[type=range]::-moz-range-progress":"height:4px r:99px background:$s-accent","input[type=range]::-webkit-slider-thumb":"appearance:none width:16px height:16px margin-top:-6px r:50% background:$s-accent","input[type=range]::-moz-range-thumb":"width:16px height:16px border:0 r:50% background:$s-accent","input[type=file]":"cursor:pointer",progress:"appearance:none border:0 height:6px r:99px background:$s-faint overflow:hidden vertical-align:middle","progress::-webkit-progress-bar":"background:$s-faint r:99px","progress::-webkit-progress-value":"background:$s-accent r:99px","progress::-moz-progress-bar":"background:$s-accent r:99px",meter:"vertical-align:middle",fieldset:"border: 1px solid $s-faint; r:$s-radius-sm padding:$2 min-width:0",legend:"padding: 0 $1; font-weight:600","code, kbd, samp, pre":"font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;",code:"background: color-mix(in oklab, $s-text, $s-bg 86%); padding: 0.12em 0.34em; r:4px font-size:0.9em",pre:"background: color-mix(in oklab, $s-text, $s-bg 92%); p:$3 r: $s-radius; overflow:auto","pre code":"background:transparent p:0","img, svg, video, canvas":"max-width:100% h:auto",hr:"border:0 border-top: 1px solid $s-faint;","::placeholder":"color: $s-muted; opacity:1",":focus-visible":"outline: 2px solid $s-focus; outline-offset:2px",small:"color:$s-muted font-size:0.9em","@media (prefers-reduced-motion: reduce)":{"*, *::before, *::after":"transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; scroll-behavior: auto !important;"},":root":"--s-primary:#00a884 --s-danger:#dc5b41 --s-success:#00a884 --s-warning:#ef6b00 --s-link:#3f8cd8 --s-radius-sm:6px --s-radius:12px --s-radius-lg:18px --s-focus: color-mix(in srgb, $s-primary 38%, transparent); --s-gradient: linear-gradient(135deg, color-mix(in oklab, $s-primary, white 16%), color-mix(in oklab, $s-primary, black 14%));",":root, .s-s.neutral":"--s-accent:$s-primary --s-link-fg:$s-link",".s-s:not(.neutral)":"--s-bg:$s-primary border:0 --s-text:#eee --s-accent:#fff --s-link-fg:#eef --s-muted: color-mix(in srgb, #fff 70%, transparent); --s-faint: color-mix(in srgb, #fff 30%, transparent);",".s-s.danger":"--s-bg:$s-danger",".s-s.success":"--s-bg:$s-success",".s-s.warning":"--s-bg:$s-warning",".s-s.link":"--s-bg:$s-link",".s-s.primary":"--s-bg:$s-primary",":root, .s-s":"--s-muted: color-mix(in oklab, $s-text, $s-bg 42%); --s-faint: color-mix(in oklab, $s-text, $s-bg 80%); color:$s-text accent-color:$s-accent scrollbar-width:thin scrollbar-color: $s-faint transparent;",".s-s, body":G1,".s-s":"r:$s-radius",":where(.s-s.neutral)":"border: 1px solid $s-faint;",".s-s::-webkit-scrollbar, .s-s ::-webkit-scrollbar":"width:10px height:10px",".s-s::-webkit-scrollbar-track, .s-s ::-webkit-scrollbar-track":"background:transparent",".s-s::-webkit-scrollbar-thumb, .s-s ::-webkit-scrollbar-thumb":"background:$s-faint border-radius:99px border: 2px solid transparent; background-clip:padding-box",".s-s.shadow.neutral:not(.s-btn)":"box-shadow: 0 4px 14px rgba(0,0,0,0.13);",".s-s.extra-shadow.neutral:not(.s-btn)":"box-shadow: 0 18px 50px rgba(0,0,0,0.28);",".s-s.shadow:not(.neutral):not(.tonal):not(.outlined)":"box-shadow: 0 4px 14px color-mix(in srgb, $s-bg 30%, transparent);",".s-s.extra-shadow:not(.neutral):not(.tonal):not(.outlined)":"box-shadow: 0 14px 40px color-mix(in srgb, $s-bg 40%, transparent);",".s-s.no-shadow":"box-shadow: none !important;",".s-s:not(.neutral).tonal, .s-s:not(.neutral).outlined":"--s-text:$s-bg --s-accent:$s-bg --s-link-fg:$s-bg --s-faint: color-mix(in srgb, $s-bg 30%, transparent); --s-muted: color-mix(in srgb, $s-bg 70%, transparent);",".s-s:not(.neutral).tonal":"background: color-mix(in srgb, $s-bg 15%, transparent); border: 1px solid $s-faint;",".s-s:not(.neutral).outlined":"background: transparent; border: 1px solid color-mix(in srgb, $s-bg 45%, transparent);",".s-s:not(.neutral) .s-s.tonal, .s-s:not(.neutral) .s-s.outlined":"--s-text:#fff --s-accent:#fff --s-link-fg:#fff "+G1+" border-color: transparent;"});D.insertGlobalCss({".s-preload, .s-preload *, .s-preload *::before, .s-preload *::after":"transition: none !important; animation: none !important;"});if(typeof document<"u"&&typeof requestAnimationFrame=="function"){let t=document.documentElement;t.classList.add("s-preload"),requestAnimationFrame(()=>requestAnimationFrame(()=>t.classList.remove("s-preload")))}D.insertGlobalCss({":disabled, [aria-disabled=true]":"opacity:0.45 filter:saturate(0.6) user-select:none",":disabled, [aria-disabled=true], :disabled *, [aria-disabled=true] *":"pointer-events:none cursor:not-allowed"});var R2="p, ul, ol, dl, blockquote, pre, table, figure, hr, h1, h2, h3, h4, h5, h6";D.insertGlobalCss({[`${R2}`]:{"&":"margin:0","&:not(:first-child)":"margin-top:$3"},"h1, h2, h3, h4, h5, h6":{"&":"line-height:1.15 font-weight:700 text-wrap:balance","&:not(:first-child)":"margin-top:1.4em"},h1:"font-size:2em font-weight:800 letter-spacing:-0.022em",h2:"font-size:1.55em letter-spacing:-0.018em",h3:"font-size:1.3em letter-spacing:-0.011em",h4:"font-size:1.1em",h5:"font-size:0.95em letter-spacing:0.005em",h6:"font-size:0.8em fg:$s-muted text-transform:uppercase letter-spacing:0.07em","ul, ol":{"&":"padding-left:1.5em","> li:not(:first-child), li > &:not(:first-child)":"margin-top:$1"},blockquote:"border-left: 3px solid $s-faint; padding-left: $3; fg: $s-muted",table:"border-collapse:collapse","th, td":"text-align:left padding: $1 $2; border-bottom: 1px solid $s-faint; vertical-align:top",th:"font-weight:600","thead th":"border-bottom: 2px solid $s-faint;",dt:"font-weight:600",dd:"margin-left: 1.5em",figcaption:"fg:$s-muted font-size:0.9em margin-top:$1 text-align:center"});import C1 from"aberdeen";var l1=typeof navigator<"u"&&/mac|iphone|ipad|ipod/i.test(navigator.platform||navigator.userAgent),D2={esc:"escape",space:" "},Z2={" ":"Space",escape:"Esc",arrowup:"\u2191",arrowdown:"\u2193",arrowleft:"\u2190",arrowright:"\u2192"},M1=new WeakMap,E=[];function J1(){let t=C1();if(!t)throw new Error("Staffa: claimKeyboard needs a current element");return E.push(t),()=>{let a=E.indexOf(t);a>=0&&E.splice(a,1)}}function Y1(t){let[,a,e,h]=/^(mod\+)?(shift\+)?(.*)$/i.exec(t),p=h.toLowerCase();if(p=D2[p]??p,!p||p.length>1&&/[-+]/.test(p))throw new Error(`Staffa: can't parse key "${t}" \u2014 write "k", "f2", "mod+k" or "mod+shift+f2"`);if(e&&p.toUpperCase()===p)throw new Error(`Staffa: "${t}" \u2014 write the shifted character itself ("?", not "shift+/")`);return(a?"mod+":"")+(e?"shift+":"")+p}function B2(t){if(t.altKey||(l1?t.ctrlKey:t.metaKey))return null;let a=t.key.toLowerCase(),e=t.shiftKey&&(a.length>1||t.key.toUpperCase()!==a);return((l1?t.metaKey:t.ctrlKey)?"mod+":"")+(e?"shift+":"")+a}function t2(t,a){if(!(a instanceof HTMLElement))return!1;let e=t.startsWith("mod+"),h=t.replace(/^(mod\+)?(shift\+)?/,"");if(h==="enter"&&a.closest("a[href]")!=null||!e&&(h==="enter"||h===" ")&&a.closest("button, summary, [role=button]")!=null)return!0;let p=a.tagName;return!e&&h!=="escape"&&(p==="INPUT"||p==="TEXTAREA"||p==="SELECT"||a.isContentEditable)}function a2(t,a){let e=E[E.length-1];return a.global===!0||!e||e.contains(t)}function I2(t){for(let a=E.length-1;a>=0;a--)if(E[a].contains(t))return E[a]}function e2(){return E[E.length-1]??document.body}function h2(t){let a=E[E.length-1];return a&&!(t&&a.contains(t))?a:t??document.body}var Q1=!1;function F2(t){if(t.defaultPrevented||t.repeat||t.isComposing)return;let a=B2(t),e=t.target instanceof Element?t.target:null;if(!(a==null||t2(a,e)))for(let h=h2(e);h;h=h.parentElement){let p=M1.get(h)?.get(a);if(p&&a2(h,p)){p.press&&(t.preventDefault(),p.press(t));return}}}function p2(t){let a=new Map;for(let e=h2(t);e;e=e.parentElement){let h=M1.get(e);if(h)for(let[p,r]of h)!a.has(p)&&a2(e,r)&&!t2(p,t)&&a.set(p,r)}return[...a]}function S(t,a,e,h="normal"){let p=C1(),r=h==="global"?document.body:h==="local"?p:h==="normal"?(p&&I2(p))??document.body:h;if(!r)throw new Error("Staffa: a local key binding needs a current element");let o=Y1(t),d=M1.get(r);d||M1.set(r,d=new Map);let c={description:a,press:e,global:h==="global",prev:d.get(o)};d.set(o,c),Q1||(Q1=!0,document.addEventListener("keydown",F2)),C1.clean(()=>{let n=d.get(o);if(n===c)c.prev?d.set(o,c.prev):d.delete(o);else for(;n;n=n.prev)if(n.prev===c){n.prev=c.prev;break}})}function q(t,a=!1){let e=Y1(t),h=e.startsWith("mod+"),p=h?e.slice(4):e,r=p.startsWith("shift+"),o=r?p.slice(6):p,d=o.length===1?o.toUpperCase():o[0].toUpperCase()+o.slice(1);if(a){let n=o===" "?"Space":r||o.length>1?d:o;return(h?l1?"Meta+":"Control+":"")+(r?"Shift+":"")+n}let c=Z2[o]??d;return l1?(r?"\u21E7":"")+(h?"\u2318":"")+c:(h?"Ctrl+":"")+(r?"Shift+":"")+c}import W from"aberdeen";import r2 from"aberdeen";var x1=640,U2=0;function U(t="s"){return`${t}-${++U2}`}function x(t,...a){t!=null&&(typeof t=="function"?t(...a):r2("rich=",t))}var K2="a[href], button, input, select, textarea, [tabindex]";function J(t,a){let e=p=>p instanceof HTMLElement&&!p.hasAttribute("disabled")&&p.getAttribute("aria-disabled")!=="true"&&p.tabIndex>=0&&p.getClientRects().length>0,h=(a?[...t.querySelectorAll(a)].find(e):void 0)??[...t.querySelectorAll(K2)].find(e);return h?.focus(),h!=null}function K(t){queueMicrotask(()=>r2(t))}import b from"aberdeen";import $ from"aberdeen";import T from"aberdeen";T.insertGlobalCss({".s-tt-tip":{"&":"position:fixed z-index:500 max-width:20rem w:max-content padding: 0.3em 0.65em; font-size:0.85em line-height:1.4 pointer-events:none"}});var Y=T.proxy(void 0),Z=null;typeof window<"u"&&window.addEventListener("scroll",()=>{Y.value=void 0},{capture:!0,passive:!0});function N2(t,a,e,h){let r=window.innerWidth,o=window.innerHeight,d=0,c=0;return h==="bottom"?(d=t.left+(t.width-a)/2,c=t.bottom+7,c+e>o-8&&(c=t.top-e-7)):h==="left"?(d=t.left-a-7,c=t.top+(t.height-e)/2,d<8&&(d=t.right+7)):h==="right"?(d=t.right+7,c=t.top+(t.height-e)/2,d+a>r-8&&(d=t.left-a-7)):(d=t.left+(t.width-a)/2,c=t.top-e-7,c<8&&(c=t.bottom+7)),{x:Math.max(8,Math.min(d,r-a-8)),y:Math.max(8,Math.min(c,o-e-8))}}function z1(){Z&&clearTimeout(Z),Z=setTimeout(()=>{Y.value=void 0,Z=null},100)}K(()=>{let t=Y.value;if(!t)return;let{opts:a,anchor:e}=t,h=a.placement??"top",p=T("div.s-tt-tip.s-s.neutral.shadow role=tooltip visibility:hidden",a.attrs,()=>{T("mouseenter=",()=>{Z&&(clearTimeout(Z),Z=null)}),T("mouseleave=",z1),x(a.tip)});requestAnimationFrame(()=>{if(!document.body.contains(p))return;let r=e.getBoundingClientRect(),{x:o,y:d}=N2(r,p.offsetWidth,p.offsetHeight,h);p.style.left=o+"px",p.style.top=d+"px",p.style.visibility=""})});function h1(t){let a=e=>{Z&&(clearTimeout(Z),Z=null),Y.value={opts:t,anchor:e.currentTarget}};T("mouseenter=",a),T("mouseleave=",z1),T("focusin=",e=>{e.target.matches?.(":focus-visible")&&a(e)}),T("focusout=",z1),T.clean(()=>{T.unproxy(Y).value?.opts===t&&(Y.value=void 0)})}$.insertGlobalCss({".s-btn":{"&":"display:inline-flex align-items:center justify-content:center gap:$2 font-weight:450 line-height:1.1 white-space:nowrap cursor:pointer text-decoration:none padding: $m2 $m3; transition: background 0.15s, border-color 0.15s, color 0.15s, filter 0.15s, box-shadow 0.15s, transform 0.08s;","&:focus-visible":"outline: 3px solid $s-focus; outline-offset: 1px;","&:hover":"filter: brightness(1.06)","&.tonal:hover, &.outlined:hover":"background: color-mix(in srgb, $s-bg 24%, transparent);","&.neutral:hover":"filter:none background: color-mix(in srgb, $s-text 8%, $s-bg);","> svg":"width:1.25em height:1.25em","&:active:not(:disabled)":"transform: translateY(1px)","&.small, .small > &":"padding: $m1 $m2; font-size:0.85em border-radius:$s-radius-sm","&.large, .large > &":"font-size:1.4em border-radius:$s-radius-lg"},".s-icon-btn":{"&":"display:inline-flex align-items:center justify-content:center flex-shrink:0 width:2rem height:2rem p:0 border:0 background:transparent cursor:pointer fg:$s-muted r:$s-radius-sm line-height:1 font-size:1rem text-decoration:none transition: color 0.12s, background 0.12s;","> svg":"width:1.25em height:1.25em","&:hover:not(:disabled):not([aria-disabled=true])":"fg:$s-text background: color-mix(in srgb, $s-text 10%, transparent);","&:focus-visible":"outline: 3px solid $s-focus; outline-offset:1px","&.small, .small > &":"width:1.6rem height:1.6rem font-size:0.8rem","&.large, .large > &":"width:2.4rem height:2.4rem font-size:1.2rem"}});function p1(t){let a=t.href!=null?"a":"button";$(`${a}.s-icon-btn`,t.attrs,()=>{o2(t),$("aria-label=",t.ariaLabel),t.key&&d2(t.key,t.ariaLabel,void 0,t.disabled),x(t.icon)})}function o2(t){t.href!=null?($("role=button"),t.disabled?$("aria-disabled=true"):$("href=",t.href)):($("type=",t.type??"button"),t.disabled&&$("disabled=true")),t.click&&!t.disabled&&$("click=",t.click)}function d2(t,a,e,h){let p=$(),r=a?`${a} \xB7 ${q(t)}`:q(t);h1({tip:()=>$("#",r)}),h||($("aria-keyshortcuts=",q(t,!0)),S(t,typeof e=="string"?e:a,()=>p.click()))}function R(t={}){let a=typeof t=="string"||typeof t=="function"?{content:t}:t,e=a.href!=null?"a":"button";$(`${e}.s-btn.s-s.shadow`,a.attrs,()=>{o2(a),a.ariaLabel&&$("aria-label=",a.ariaLabel),a.key&&d2(a.key,a.ariaLabel,a.content,a.disabled),x(a.icon),x(a.content)})}import c2 from"aberdeen";c2.insertGlobalCss({".s-bgroup":{"&":"display:inline-flex align-items:stretch","&.s-spaced":"gap:$2 flex-wrap:wrap","&.s-vertical":"flex-direction:column","&.s-attached":"gap:0","&.s-attached:not(.s-vertical) > .s-btn:not(:first-child)":"margin-left:-1px","&.s-attached:not(.s-vertical) > .s-btn:not(:first-child):not(:last-child)":"r:0","&.s-attached:not(.s-vertical) > .s-btn:first-child:not(:last-child)":"border-top-right-radius:0 border-bottom-right-radius:0","&.s-attached:not(.s-vertical) > .s-btn:last-child:not(:first-child)":"border-top-left-radius:0 border-bottom-left-radius:0","&.s-attached.s-vertical > .s-btn:not(:first-child)":"margin-top:-1px","&.s-attached.s-vertical > .s-btn:not(:first-child):not(:last-child)":"r:0","&.s-attached.s-vertical > .s-btn:first-child:not(:last-child)":"border-bottom-left-radius:0 border-bottom-right-radius:0","&.s-attached.s-vertical > .s-btn:last-child:not(:first-child)":"border-top-left-radius:0 border-top-right-radius:0","&.s-attached > .s-btn:hover, &.s-attached > .s-btn:focus-visible":"z-index:1"}});function X(t={}){let e=`.s-${t.layout??"attached"}${t.vertical?".s-vertical":""}`;c2(`div.s-bgroup${e} role=group`,t.attrs,()=>{if(t.buttons)for(let h of t.buttons)R(h);x(t.content)})}import j from"aberdeen";import L from"aberdeen";L.insertGlobalCss({".s-field":{"&":"display:flex flex-direction:column gap:$1","> label":"font-weight:600 font-size:0.9em fg:$s-text user-select:none"},".s-req":"fg:$s-danger margin-left:2px",".s-help":"font-size:0.82em fg:$s-muted",".s-error":"font-size:0.82em fg:$s-danger",".s-input":{"&":"w:100% background: color-mix(in oklab, $s-bg, $s-text 4%); color:$s-text border: 1px solid $s-faint; r:$s-radius padding: 0.55em 0.7em; transition: border-color 0.15s, box-shadow 0.15s;","&:hover:not(:disabled)":"border-color: color-mix(in oklab, $s-text, $s-bg 55%);","&:focus-visible":"border-color:$s-accent box-shadow: 0 0 0 3px $s-focus; outline:none","&[aria-invalid=true]":"border-color:$s-danger"}});function N(t,a){let e=t.id??U("field"),h=()=>!!t.error;L("div.s-field",t.attrs,()=>{L(()=>{t.label!=null&&L("label for=",e,()=>{x(t.label),t.required&&L("span.s-req aria-hidden=true #*")})}),a(e,h),L(()=>{t.help!=null&&!t.error&&L("div.s-help",()=>x(t.help))}),L(()=>{t.error&&L("div.s-error role=alert #",t.error)})})}function t1(t,a,e,h){L("id=",a),t.name&&L("name=",t.name),L(()=>{t.disabled&&L("disabled=true")}),L(()=>{t.required&&L("aria-required=true")}),L(()=>L("aria-invalid=",e()?"true":"false")),h&&L("bind=",h)}function S1(t={}){N(t,(a,e)=>{j("input.s-input",t.inputAttrs,()=>{j("type=",t.type??"text"),t.placeholder!=null&&j("placeholder=",t.placeholder),t.autocomplete!=null&&j("autocomplete=",t.autocomplete),t.value!=null&&!t.bind&&j("value=",t.value),t.input&&j("input=",t.input),t.change&&j("change=",t.change),t1(t,a,e,t.bind)})})}b.insertGlobalCss({".s-backdrop":{"&":"position:fixed inset:0 z-index:200 display:block background: rgba(0,0,0,0.55); transition: opacity 0.4s ease-in-out;","&.hidden":"opacity:0 pointer-events:none"},".s-dialog":{"&":"position:fixed z-index:200 top:50% left:50% display:flex flex-direction:column transform:translate(-50%,-50%) min-width:min(20rem,90vw) max-width:min(90vw,44rem) max-height:min(88vh,800px) r: $s-radius-lg; overflow:hidden transition: opacity 0.2s ease-out, transform 0.2s ease-out;","> header":"display:flex align-items:center gap:$2 padding: $2 $3; border:0 border-bottom: 1px solid $s-faint; r:0 font-weight:600 flex-shrink:0","> footer":"display:flex align-items:center justify-content:flex-end gap:$2 padding: $2 $3; border:0 border-top: 1px solid $s-faint; r:0 flex-shrink:0","> div":"p:$3 gap:$3 display:flex flex-direction:column overflow-y:auto flex:1 min-height:0","&.hidden":"opacity:0 pointer-events:none transform: translate(-50%, calc(-50% + 20px)); pointer-events:none"}});var r1=b.proxy({}),W2=0,n2=b.derive(()=>{let t=Object.keys(r1);if(t.length)return t[t.length-1]});function $1(){return n2.value!=null}K(()=>{b.onEach(r1,({resolve:t,opts:a},e)=>{let h=()=>{delete r1[e]};b.clean(()=>{a.onClose?.(),t()});let p=document.activeElement;b.clean(()=>{p instanceof HTMLElement&&document.contains(p)&&p.focus()});let r=b.derive(()=>n2.value!=e);b("div.s-backdrop create=hidden destroy=hidden .hidden=",r,"click=",()=>{a.allowCancel!==!1&&h()});let o=b("div.s-dialog.neutral.s-s.extra-shadow create=hidden destroy=hidden",a.attrs,()=>{a.keyboardTransparent||b.clean(J1());let d=e2();b(()=>{let c=a.allowCancel!==!1;S("esc",c?"Close this dialog":void 0,c?h:()=>{},d)}),b(()=>{a.header!=null&&b("header.s-s.neutral",a.headerAttrs,()=>x(a.header))}),b("div",a.contentAttrs,()=>{x(a.content,h)}),b(()=>{a.footer!=null&&b("footer.s-s.neutral",a.footerAttrs,()=>x(a.footer))})});requestAnimationFrame(()=>{document.body.contains(o)&&J(o)})})});function a1(t){let a=++W2;return t.cancelWithScope!==!1&&b.clean(()=>{delete r1[a]}),new Promise(e=>{r1[a]={resolve:e,opts:t}})}function G2(t,a={}){return a1({header:"Alert",allowCancel:!0,content:e=>{b("p",()=>{b("#",t)}),X({layout:"spaced",attrs:"align-self:flex-end",content:()=>{R({content:"OK",click:e})}})},...a})}function X2(t,a={}){return new Promise(e=>{let h=!1;a1({header:"Confirm",allowCancel:!0,content:p=>{b("p",()=>{b("#",t)}),X({layout:"spaced",attrs:"align-self:flex-end",content:()=>{R({content:"Cancel",attrs:".neutral",click:p}),R({content:"OK",click:()=>{h=!0,p()}})}})},...a,onClose:()=>{e(h),a.onClose?.()}})})}function j2(t,a="",e={}){return new Promise(h=>{let p=null;a1({header:"Input",allowCancel:!0,content:r=>{b("p",()=>{b("#",t)});let o=b.proxy({value:a});b("form display:contents",()=>{b("submit=",d=>{d.preventDefault(),p=o.value,r()}),S1({bind:b.ref(o,"value")}),X({layout:"spaced",attrs:"align-self:flex-end",content:()=>{R({content:"Cancel",attrs:".neutral",type:"button",click:r}),R({content:"OK",type:"submit"})}})})},...e,onClose:()=>{h(p),e.onClose?.()}})})}W.insertGlobalCss({".s-keyhelp":{"&":"display:flex flex-direction:column gap:$1 min-width:14rem","> div":"display:flex align-items:baseline justify-content:space-between gap:$4",kbd:"font-family:inherit font-size:0.85em fg:$s-muted white-space:nowrap border: 1px solid $s-faint; r:$s-radius-sm padding: 0 0.4em;"}});var v1=null;function P1(){if(v1){v1();return}let t=p2(document.activeElement);a1({header:"Keyboard shortcuts",cancelWithScope:!1,keyboardTransparent:!0,onClose:()=>{v1=null},content:a=>{v1=a;let e=h=>{h.repeat||["Control","Shift","Alt","Meta","Escape","?"].includes(h.key)||a()};document.addEventListener("keydown",e,!0),W.clean(()=>document.removeEventListener("keydown",e,!0)),W("div.s-keyhelp",()=>{for(let[h,p]of t)p.description!==void 0&&W("div",()=>{W("span",()=>x(p.description)),W("kbd text=",q(h))})})}})}var i2=W.proxy(!0);function _2(t){i2.value=t}W(()=>{i2.value&&(S("?",void 0,P1,"global"),S("mod+?","This overview",P1,"global"))});import M from"aberdeen";M.insertGlobalCss({".s-ac":{"&":"position:relative","> .s-control":"display:flex flex-wrap:wrap align-items:center gap:$1 background: color-mix(in oklab, $s-bg, $s-text 4%); color:$s-text border: 1px solid $s-faint; r:$s-radius padding: 0.3em 0.4em; cursor:text; transition: border-color 0.15s, box-shadow 0.15s;","> .s-control:hover":"border-color: color-mix(in oklab, $s-text, $s-bg 55%);","> .s-control:focus-within":"border-color:$s-accent box-shadow: 0 0 0 3px $s-focus;","&[aria-invalid=true] > .s-control":"border-color:$s-danger",".s-chip":"display:inline-flex align-items:center gap:$1 font-size:0.85em background: color-mix(in oklab, $s-bg, $s-text 10%); border: 1px solid $s-faint; r:$s-radius padding: 0.1em 0.2em 0.1em 0.5em;",".s-chip > button":"cursor:pointer border:0 background:transparent fg:$s-muted font-size:1.1em line-height:1 padding: 0 0.2em; r:4px",".s-chip > button:hover":"fg:$s-text background:$s-faint",input:"flex:1 min-width:6ch border:0 background:transparent color:inherit outline:none padding:0.25em","> .s-menu":"position:absolute top:100% left:0 right:0 z-index:20 margin-top:4px max-height:15rem overflow-y:auto list-style:none p:$1 margin-bottom:0","> .s-menu li":"margin:0",".s-option":"padding: 0.45em 0.6em; r:6px cursor:pointer transition: background 0.1s;",".s-option[aria-selected=true]":"background: color-mix(in srgb, $s-text 10%, transparent);",".s-add":"fg:$s-accent font-style:italic",".s-empty":"padding: 0.45em 0.6em; fg:$s-muted"}});function Q2(t){return typeof t=="string"?{value:t,label:t}:{value:t.value,label:t.label??t.value}}function J2(t){let a=U("ac-menu"),e=M.proxy({query:"",open:!1,active:0}),h=()=>(typeof t.options=="function"?t.options():t.options).map(Q2),p=()=>{let i=t.bind?.value;return i==null||i===""?[]:Array.isArray(i)?i:[i]},r=i=>h().find(m=>m.value===i)?.label??i;if(!t.multi){let i=t.bind?M.peek(t.bind,"value"):void 0;typeof i=="string"&&i&&(e.query=M.peek(()=>r(i)))}let o=()=>{let i=new Set(p()),m=h();t.multi&&(m=m.filter(H=>!i.has(H.value)));let g=e.query.trim().toLowerCase();return g&&(m=m.filter(H=>H.label.toLowerCase().includes(g))),m},d=(i,m)=>{if(t.multi){let g=Array.isArray(t.bind?.value)?[...t.bind.value]:[];g.includes(i)||g.push(i),t.bind&&(t.bind.value=g),e.query=""}else t.bind&&(t.bind.value=i),e.query=r(i),e.open=!1;e.active=0,m?.focus()},c=i=>{if(!t.bind)return;let m=t.bind.value??[];t.bind.value=m.filter(g=>g!==i)};N(t,(i,m)=>{M("div.s-ac",t.inputAttrs,()=>{M(()=>M("aria-invalid=",m()?"true":"false"));let g;M("div.s-control",()=>{M("click=",()=>g?.focus()),M(()=>{if(t.multi)for(let H of p())M("span.s-chip",()=>{M("span #",M.peek(()=>r(H))),M("button type=button aria-label=",`Remove ${H}`,()=>{M("#\xD7"),M("click=",l=>{l.stopPropagation(),c(H),g?.focus()})})})}),g=M("input type=text role=combobox autocomplete=off",()=>{M("id=",i,`aria-controls=${a} aria-autocomplete=list`),t.placeholder!=null&&M("placeholder=",t.placeholder),t.disabled&&M("disabled=true"),t.required&&M("aria-required=true"),M("bind=",M.ref(e,"query")),M(()=>M("aria-expanded=",e.open?"true":"false")),M(()=>{let l=o()[e.active];M("aria-activedescendant=",e.open&&l?`${a}-opt-${e.active}`:"")}),M("input=",()=>{e.open=!0,e.active=0}),M("focus=",()=>{e.open=!0}),M("blur=",()=>{setTimeout(()=>y(),150)}),M("keydown=",H=>n(H,g))})}),M(()=>{if(!e.open)return;let H=o(),l=e.query.trim(),f=t.allowCustom!==!1&&l!==""&&!H.some(C=>C.label.toLowerCase()===l.toLowerCase());M("ul.s-menu.s-s.neutral.shadow role=listbox",`id=${a}`,()=>{H.forEach((C,z)=>{M("li.s-option role=option",`id=${a}-opt-${z}`,()=>{M(()=>M("aria-selected=",e.active===z?"true":"false")),M("#",C.label),M("mousedown=",s1=>s1.preventDefault()),M("click=",()=>d(C.value,g)),M("mousemove=",()=>{e.active=z})})}),f&&M("li.s-option.s-add role=option",()=>{M("#",`Add "${l}"`),M("mousedown=",C=>C.preventDefault()),M("click=",()=>d(l,g))}),H.length===0&&!f&&M("li.s-empty #No matches")})}),M(()=>{if(t.name)if(t.multi)for(let H of p())M("input type=hidden",()=>{M("name=",t.name),M("value=",H)});else M("input type=hidden",()=>{M("name=",t.name),M("value=",p()[0]??"")})})})});function n(i,m){let g=o(),H=g.length-1;if(i.key==="ArrowDown")i.preventDefault(),e.open=!0,e.active=Math.min(H,e.active+1);else if(i.key==="ArrowUp")i.preventDefault(),e.active=Math.max(0,e.active-1);else if(i.key==="Enter"){i.preventDefault();let l=g[e.active];l?d(l.value,m):t.allowCustom!==!1&&e.query.trim()?d(e.query.trim(),m):e.open&&(e.open=!1)}else if(i.key==="Escape")e.open&&(i.preventDefault(),e.open=!1,t.multi||(e.query=r(p()[0]??"")));else if(i.key==="Backspace"&&t.multi&&e.query===""){let l=p();l.length&&c(l[l.length-1])}}function y(){e.open=!1,t.multi?e.query="":t.allowCustom!==!1&&e.query.trim()?d(e.query.trim()):e.query=r(p()[0]??"")}}import _ from"aberdeen";import Y2 from"aberdeen";var o1={size:24,color:"currentColor",strokeWidth:2,cap:"round",join:"round"};function t0(t,a){let e=a.size??o1.size,h=Y2('svg.s-icon aria-hidden=true viewBox="0 0 24 24" fill=none',"width=",e,"height=",e,"stroke=",a.color??o1.color,"stroke-width=",a.strokeWidth??o1.strokeWidth,"stroke-linecap=",a.cap??o1.cap,"stroke-linejoin=",a.join??o1.join,a.attrs);h.innerHTML=t}function P(t){return(a={})=>t0(t,a)}var s2=P('<path d="m9 18 6-6-6-6" />');var l2=P('<circle cx="12" cy="12" r="10" />');var M2=P('<path d="M15 3h6v6" /><path d="M10 14 21 3" /><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />');var x2=P('<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" /><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" />');var m1=P('<path d="M4 5h16" /><path d="M4 12h16" /><path d="M4 19h16" />');var v2=P('<path d="M12 17v5" /><path d="M15 9.34V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H7.89" /><path d="m2 2 20 20" /><path d="M9 9v1.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h11" />'),O1=P('<path d="M12 17v5" /><path d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z" />');var m2=P('<path d="M22 2 2 22" />');var e1=P('<path d="M18 6 6 18" /><path d="m6 6 12 12" />');_.insertGlobalCss({".s-box":{"&":"display:flex flex-direction:column overflow:hidden r: $s-radius-lg; position:relative","&:not(:first-child)":"margin-top: $3","> header":"display:flex align-items:center gap:$2 padding: $2 $3; border:0 border-bottom: 1px solid $s-faint; r:0 font-weight:600","> footer":"display:flex align-items:center justify-content:flex-end gap:$2 padding: $2 $3; border:0 border-top: 1px solid $s-faint; r:0","> div":"p:$3 gap:$3","> header > .s-box-close":"margin-left:auto","> .s-box-close":"position:absolute top:$2 right:$2 z-index:1"}});function a0(t={}){let a=typeof t=="string"||typeof t=="function"?{content:t}:t;_("section.s-box.s-s.neutral.shadow",a.attrs,()=>{_(()=>{a.header!=null?_("header.s-s.neutral",a.headerAttrs,()=>{x(a.header),typeof a.close=="function"&&u2(a.close)}):typeof a.close=="function"&&u2(a.close)}),_("div",a.contentAttrs,()=>{x(a.content)}),_(()=>{a.footer!=null&&_("footer.s-s.neutral",a.footerAttrs,()=>x(a.footer))})})}function u2(t){p1({icon:e1,ariaLabel:"Close",click:t,attrs:".s-box-close"})}import E1 from"aberdeen";function e0(t){E1(()=>{let a=t.bind.value;X({attrs:t.attrs,buttons:Object.entries(t.options).map(([e,h])=>({content:h,ariaLabel:typeof h=="function"?e:void 0,attrs:a===e?".primary":".neutral",click:()=>{t.bind.value=t.allowDeselect&&a===e?void 0:e}}))})}),t.name&&E1(()=>E1("input type=hidden name=",t.name,"value=",t.bind.value??""))}import k from"aberdeen";k.insertGlobalCss({".s-check":{"&":"display:flex flex-direction:column gap:$1","> label":"display:flex align-items:center gap:$2 cursor:pointer user-select:none","> label:has(input:disabled)":"cursor:not-allowed opacity:0.45 filter:saturate(0.6)",input:"cursor:inherit m:0"}});function h0(t={}){let a=t.id??U("check");k("div.s-check",t.attrs,()=>{k("label for=",a,()=>{k("input type=checkbox",t.inputAttrs,()=>{k("id=",a),t.name&&k("name=",t.name),t.checked&&!t.bind&&k("checked=true"),t.change&&k("change=",t.change),k(()=>{t.disabled&&k("disabled=true")}),k(()=>{t.required&&k("aria-required=true")}),t.bind&&k("bind=",t.bind)}),k(()=>{t.label!=null&&x(t.label),t.required&&k("span.s-req aria-hidden=true #*")})}),k(()=>{t.help!=null&&!t.error&&k("div.s-help",()=>x(t.help))}),k(()=>{t.error&&k("div.s-error role=alert #",t.error)})})}import Q from"aberdeen";Q.insertGlobalCss({".s-form":{"&":"display:flex flex-direction:column gap:$3","&.grid":"display:grid grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); gap:$3","&.grid > .s-wide, &.grid > footer":"grid-column: 1 / -1;","> footer":"display:flex align-items:center justify-content:flex-end gap:$2 flex-wrap:wrap margin-top:$1"}});function p0(t={}){let a=typeof t=="string"||typeof t=="function"?{content:t}:t;Q("form.s-form",a.attrs,()=>{Q(()=>{Q(".grid=",a.layout==="grid")}),Q("submit=",e=>{if(e.preventDefault(),a.submit){let h=new FormData(e.target),p={};for(let r of new Set(h.keys())){let o=h.getAll(r);p[r]=o.length===1?o[0]:o}a.submit(p,e)}}),x(a.content),Q(()=>{a.actions&&Q("footer",a.actionsAttrs,()=>x(a.actions))})})}import v from"aberdeen";import{current as N1}from"aberdeen/route";import u from"aberdeen";import{matchCurrent as c0,current as y1,go as f2}from"aberdeen/route";import V from"aberdeen";import{grow as r0,shrink as o0}from"aberdeen/transitions";V.insertGlobalCss({".s-toasts":"position:fixed bottom:$3 right:$3 z-index:400 display:flex flex-direction:column gap:$2 pointer-events:none max-width:min(90vw,24rem) w:24rem",".s-toast":{"&":"display:flex align-items:flex-start gap:$2 padding: $3; pointer-events:auto position:relative overflow:hidden",".s-toast-body":"display:flex flex-direction:column gap:$1 flex:1 min-width:0",".s-toast-title":"font-weight:700 line-height:1.3",".s-toast-close":"cursor:pointer border:0 background:transparent fg:$s-muted font-size:1.1em line-height:1 padding: 0 0.15em; r:4px flex-shrink:0 align-self:flex-start",".s-toast-close:hover":"fg:$s-text",".s-toast-close:focus-visible":"outline:none box-shadow: 0 0 0 3px $s-focus; fg:$s-text",".s-toast-progress":"position:absolute bottom:0 left:0 right:0 height:2px background:$s-accent width:100%"}});var d0=0,d1=V.proxy({});K(()=>{V.peek(()=>V.isEmpty(d1))&&V.isEmpty(d1)||V("div.s-toasts",()=>{V.onEach(d1,t=>{let{opts:a,id:e}=t,h=a.type==="danger"||a.type==="warning"?"alert":"status",p=a.type==null||a.type==="neutral"?"neutral":a.type,r=a.duration??6e3,o,d=null,c=()=>{clearTimeout(o),d&&(d.style.transition="none",d.style.width="100%",d.offsetWidth,d.style.transition=`width ${r}ms linear`,d.style.width="0%"),o=setTimeout(()=>q1(e),r)},n=()=>{clearTimeout(o),o=void 0,d&&(d.style.transition="none",d.style.width="100%")};V.clean(()=>clearTimeout(o)),V(`div.s-toast.s-s.${p}.extra-shadow aria-live=polite role=${h}`,"create=",r0,"destroy=",o0,a.attrs,()=>{r>0&&(V("mouseenter=",n),V("mouseleave=",c)),V("div.s-toast-body",()=>{V(()=>{a.title!=null&&V("div.s-toast-title",()=>x(a.title))}),V("div.s-toast-msg",()=>x(a.message))}),V(()=>{a.dismissible!==!1&&V("button.s-toast-close type=button aria-label=Dismiss",()=>{V("#\xD7"),V("click=",()=>q1(e))})}),r>0&&(d=V("div.s-toast-progress"))}),r>0&&requestAnimationFrame(c)})})});function q1(t){delete d1[t]}function u1(t){let a=++d0;return d1[a]={id:a,opts:t},()=>q1(a)}u.insertGlobalCss({".s-menu-list":"position:fixed z-index:350 min-width:10rem display:flex flex-direction:column p:$1 r:$s-radius-lg max-width: calc(100vw - 16px); overflow-y:auto max-height:min(80vh,28rem) transition: opacity 0.15s, transform 0.15s, visibility 0s;",".s-menu-list.hidden":"opacity:0 pointer-events:none transform:translateY(-6px) visibility:hidden transition: opacity 0.15s, transform 0.15s, visibility 0.15s;",".s-menu-item":"display:flex align-items:center gap:$2 w:100% scroll-margin:$2 padding: $m2 0; line-height:1.1 r:$s-radius cursor:pointer text-align:left font-weight:450 font-size:0.9em border:0 background:transparent fg:$s-text text-decoration:none transition: color 0.12s, transform 0.12s, text-shadow 0.12s;",".s-menu-item:focus-visible:not([aria-current=page]), .s-menu-item:hover:not([aria-disabled=true]):not([aria-current=page])":"filter:none color: color-mix(in lab, $s-primary 33%, $s-text);",".s-menu-item:focus-visible":"outline-offset:-2px background: color-mix(in srgb, $s-accent 14%, transparent);",".s-menu-item[aria-current=page]":"color:$s-accent filter:none",".s-menu-list .s-menu-item":"padding-inline:$2",".s-menu-item[aria-disabled=true]":"opacity:0.45 cursor:not-allowed pointer-events:none",".s-menu-icon":"flex-shrink:0",".s-menu-list .s-menu-icon":"display:flex",".s-menu-list .s-menu-icon > svg":"width:1.25em height:1.25em","hr.s-menu-sep":"border:0 height:1px margin: $1 0.6rem; background: linear-gradient(to right, transparent, $s-faint 18%, $s-faint 82%, transparent);",".s-menu-key":"margin-left:auto padding-left:$2 font-family:inherit font-size:0.8em opacity:0.55 white-space:nowrap flex-shrink:0","@media (hover: none) and (pointer: coarse)":{".s-menu-key":"display:none"},".s-menu-tt-key":"font-family:inherit font-size:0.85em opacity:0.7 white-space:nowrap",".s-tt-tip hr.s-menu-sep":"margin: 0.35em 0;",".s-menu-chevron":"margin-left:auto flex-shrink:0 display:flex transition: transform 0.15s ease;",".s-menu-key + .s-menu-chevron":"margin-left:0",".s-menu-chevron > svg":"width:1em height:1em",".s-menu-details":{"> summary":"list-style:none","> summary::-webkit-details-marker":"display:none","&::details-content":"interpolate-size:allow-keywords block-size:0 overflow-y:clip transition: block-size 0.15s ease, content-visibility 0.15s allow-discrete;","&[open]::details-content":"block-size:auto","&[open] > summary .s-menu-chevron":"transform:rotate(90deg)"},".s-menu-sub":"display:flex flex-direction:column gap:$1 padding-left:$3",".s-menu-inline":"display:flex flex-direction:column gap:$1"});function c1(t,a,e){u("keydown=",h=>{if(h.key==="Enter"&&!h.ctrlKey&&!h.metaKey&&!h.shiftKey&&!h.altKey&&h.target.tagName==="A"){queueMicrotask(()=>a?.());return}if(h.key!=="ArrowDown"&&h.key!=="ArrowUp"&&h.key!=="Home"&&h.key!=="End")return;h.preventDefault();let r=[...h.currentTarget.querySelectorAll(".s-menu-item")].filter(n=>n.getAttribute("aria-disabled")!=="true"&&!s0(n));if(!r.length)return;let o=r.indexOf(document.activeElement),d=h.key==="ArrowUp"?-1:1,c=h.key==="Home"?0:h.key==="End"?r.length-1:o<0?d>0?0:r.length-1:(o+d+r.length)%r.length;r[c].focus()}),g2(t,{onLeafSelect:a,keyHints:e,$hasCurrent:u.derive(()=>T1(t))})}function g2(t,a){for(let e of t){if(typeof e=="string"||typeof e=="function"){x(e);continue}if("separator"in e){u("hr.s-menu-sep");continue}e.items?i0(e,a):n0(e,a)}}function n0(t,a){let e=!1,h=u(t.href?"a.s-menu-item data-panel=open":"button.s-menu-item type=button",t.attrs,()=>{t.href&&(u("href=",t.href),t.target&&u("target=",t.target),u(()=>{let p=!e;e=!0,R1(t)&&(u("aria-current=page"),requestAnimationFrame(()=>h.scrollIntoView({block:"nearest",behavior:p?"instant":"smooth"})))})),t.disabled&&u("aria-disabled=true"),t.key&&u("aria-keyshortcuts=",q(t.key,!0)),u("click=",p=>{if(t.disabled){p.preventDefault();return}a.onLeafSelect?.(),t.click?.(p)}),t.icon&&u("span.s-menu-icon",()=>x(t.icon)),x(t.label),H2(t,a)})}var b2=new Map;function y2(t,a){return b2.set(t,a),a}function i0(t,a){let e=t.href??w2(t.items),h=e!=null?u.derive(()=>D1(t)?y2(e,!0):a.$hasCurrent.value?y2(e,!1):b2.get(e)??!1):null;u("details.s-menu-details",()=>{h&&u(()=>{h.value&&u("open=true")}),u("summary.s-menu-item.s-menu-branch",t.attrs,()=>{t.disabled&&u("aria-disabled=true"),t.key&&u("aria-keyshortcuts=",q(t.key,!0)),u(()=>{R1(t)&&u("aria-current=page")}),u("click=",p=>{if(t.disabled){p.preventDefault();return}e!=null&&(p.preventDefault(),M0(e),f2(e)),t.click?.(p)}),t.icon&&u("span.s-menu-icon",()=>x(t.icon)),x(t.label),H2(t,a),u("span.s-menu-chevron aria-hidden=true",()=>s2())}),u("div.s-menu-sub",()=>g2(t.items,a))})}function s0(t){for(let a=t.closest("details");a;a=a.parentElement&&a.parentElement.closest("details"))if(!a.open&&t.closest("summary")?.parentElement!==a)return!0;return!1}function T1(t){return t.some(a=>typeof a!="string"&&typeof a!="function"&&!("separator"in a)&&D1(a))}function R1(t){if(t.href!=null&&c0(t.href))return!0;let a=t.match;if(a==null)return!1;let e=y1.path;if(typeof a=="function")return a(e);let h=a.replace(/\/+$/,"")||"/";return e===h||e.startsWith(h==="/"?"/":h+"/")}function D1(t){if(R1(t))return!0;for(let a of t.items??[])if(!(typeof a=="string"||typeof a=="function"||"separator"in a)&&D1(a))return!0;return!1}function w2(t){for(let a of t){if(typeof a=="string"||typeof a=="function"||"separator"in a)continue;let e=a.href??(a.items?w2(a.items):void 0);if(e!=null)return e}}function H2(t,a){let e=a.keyHints?void 0:t.key;t.key&&!e&&u("kbd.s-menu-key aria-hidden=true text=",q(t.key)),!(t.tooltip==null&&!e)&&h1({placement:"right",tip:()=>{x(t.tooltip),e&&(t.tooltip!=null&&u("hr.s-menu-sep"),u("kbd.s-menu-tt-key aria-hidden=true text=",q(e)))}})}function n1(t,a){u(()=>{for(let e of A2(t(),[]))S(e.key,e.label,h=>{V2(),a?.(),e.click?.(h),e.href!=null&&l0(e.href,e.target)})})}function A2(t,a){for(let e of t)typeof e=="string"||typeof e=="function"||"separator"in e||(e.key&&!e.disabled&&a.push(e),e.items&&A2(e.items,a));return a}function l0(t,a){let e=new URL(t,location.href);a?window.open(e.href,a,a==="_blank"?"noopener":""):e.origin!==location.origin?location.href=e.href:f2(t)}var f1=null;function M0(t){try{f1=new URL(t,location.href).pathname.replace(/\/+$/,"")||"/"}catch{f1=null}}function Z1(t){return f1!==t?!1:(f1=null,!0)}var G=u.proxy({opts:null});function F(){let t=G.opts?.anchor;G.opts=null,t?.focus()}function g1(t){let a=G.opts;return a!=null&&(t==null||a.anchor===t)}function V2(t){g1(t)&&F()}function x0(t,a){let e=t.offsetWidth,h=t.offsetHeight,p=window.innerWidth,r=window.innerHeight,o=4,d=a.left;d+e>p-8&&(d=Math.max(8,a.right-e));let c=a.bottom+o;c+h>r-8&&a.top-h-o>=8&&(c=a.top-h-o),t.style.left=Math.max(8,d)+"px",t.style.top=Math.max(8,c)+"px"}function v0(t){return[{label:"Open in new tab",icon:M2,click:()=>{window.open(t,"_blank","noopener")}},{label:"Copy link",icon:x2,click:()=>{m0(t)}}]}async function m0(t){let a=new URL(t,location.href).href;try{await navigator.clipboard.writeText(a),u1({message:"Link copied."})}catch{u1({message:"Couldn't copy the link.",type:"danger"})}}K(()=>{let t=G.opts;if(!t)return;let a=u("div.s-menu-list.s-s.neutral.shadow create=hidden destroy=hidden",t.dropdownAttrs,()=>{c1(t.link!=null?[...v0(t.link),{separator:!0},...t.items]:t.items,F,!0)}),e=r=>{let o=r.target;!a.contains(o)&&(t.closeOnAnchorClick||!t.anchor.contains(o))&&F()},h=r=>{(r.key==="Escape"||r.key==="Tab")&&(r.preventDefault(),F())},p=u.peek(y1,"path");u(()=>{y1.path!==p&&!Z1(y1.path)&&F()}),document.addEventListener("click",e,!0),document.addEventListener("keydown",h,!0),u.clean(()=>{document.removeEventListener("click",e,!0),document.removeEventListener("keydown",h,!0)}),requestAnimationFrame(()=>{if(!document.body.contains(a))return;let r=t.at?{left:t.at.x,right:t.at.x,top:t.at.y,bottom:t.at.y}:t.anchor.getBoundingClientRect();x0(a,r),J(a,".s-menu-item[aria-current=page]")})});function u0(t){u("nav.s-menu-inline",t.attrs,()=>{n1(()=>t.items,()=>t.onLeafSelect?.()),c1(t.items,t.onLeafSelect)})}function B1(t){return G.opts=t,F}function I1(t){n1(()=>t.items);let a=null;u.clean(()=>{G.opts?.anchor===a&&F()}),u("contextmenu=",e=>{e.preventDefault(),a=e.currentTarget,B1({...t,anchor:a,at:{x:e.clientX,y:e.clientY},closeOnAnchorClick:!0})})}function y0(t){n1(()=>t.items);let a=null;u.clean(()=>{G.opts?.anchor===a&&F()}),R({icon:m1,...t.button?.content==null?{ariaLabel:"Open menu"}:null,attrs:".neutral",...t.button,click:e=>{if(a=e.currentTarget,G.opts?.anchor===a){F();return}B1({items:t.items,anchor:a,dropdownAttrs:t.dropdownAttrs})}})}import s,{OPAQUE as L2}from"aberdeen";import*as w from"aberdeen/route";import A from"aberdeen";var f0=P('<path d="m15 18-6-6 6-6"/>'),g0=P('<path d="m9 18 6-6-6-6"/>');A.insertGlobalCss({".s-strip":{"&":"position:relative display:flex min-width:0","> .s-strip-row":"display:flex align-items:center flex:1 min-width:0 overflow-x:auto overflow-y:hidden scrollbar-width:none scroll-behavior:smooth","> .s-strip-row::-webkit-scrollbar":"display:none","> .s-strip-btn":"position:absolute top:0 bottom:0 z-index:1 display:none align-items:center justify-content:center width:2.4em border:0 padding:0 cursor:pointer fg:$s-muted transition: color 0.15s;","> .s-strip-btn:hover":"fg:$s-text","> .s-strip-btn-left":"left:0 justify-content:flex-start background: linear-gradient(to right, $s-bg 45%, transparent)","> .s-strip-btn-right":"right:0 justify-content:flex-end background: linear-gradient(to left, $s-bg 45%, transparent)","&.s-can-left > .s-strip-btn-left, &.s-can-right > .s-strip-btn-right":"display:flex"},".s-tabs":{"&":"display:flex flex-direction:column gap:$3",".s-tabbar":"border-bottom: 1px solid $s-faint;",".s-tablist":"gap:$1 align-items:stretch margin-bottom:-1px",".s-tab":"display:inline-flex align-items:center gap:$2 cursor:pointer background:transparent border:0 color: $s-muted; font-weight:600 padding: 0.6em 0.9em; white-space:nowrap border-bottom: 3px solid transparent; transition: color 0.15s, background 0.15s, border-color 0.15s;",".s-tab:hover:not(:disabled), .s-tab[aria-selected=true]":"color: $s-text;",".s-tab:focus-visible":"outline:none box-shadow: inset 0 0 0 2px $s-focus; r: $s-radius;",".s-tab[aria-selected=true]":"border-image: $s-gradient 1;",".s-tabpanel":"display:block"}});function b1(t){A("div.s-strip",t.attrs,()=>{let a=A("div.s-strip-row",t.stripAttrs,()=>x(t.content));k2(a,-1),k2(a,1),w0(a)})}function w1(t){let a=t.parentElement;if(!a||!t.isConnected)return;let e=parseFloat(getComputedStyle(a).fontSize)*2.6,h=t.getBoundingClientRect(),p=a.getBoundingClientRect(),r=h.left-p.left,o=h.right-p.right;r<e?a.scrollBy({left:r-e,behavior:"smooth"}):o>-e&&a.scrollBy({left:o+e,behavior:"smooth"})}function b0(t){let a=U("tabs"),e=(r,o)=>r.id??String(o),h=t.bind??A.proxy(e(t.tabs[0]??{label:""},0));t.tabs.length>0&&!t.tabs.some((r,o)=>e(r,o)===A.peek(()=>h.value))&&(h.value=e(t.tabs[0],0));let p=(r,o)=>{r.disabled||(h.value=e(r,o))};A("div.s-tabs",t.attrs,()=>{b1({attrs:".s-tabbar",stripAttrs:".s-tablist role=tablist",content:()=>{t.tabs.forEach((r,o)=>{let d=e(r,o),c=A("button.s-tab type=button role=tab",()=>{A("id=",`${a}-tab-${d}`,"aria-controls=",`${a}-panel-${d}`),A(()=>{let n=h.value===d;A("aria-selected=",n?"true":"false"),A("tabindex=",n?"0":"-1"),n&&requestAnimationFrame(()=>w1(c))}),r.disabled&&A("disabled=true"),A("click=",()=>p(r,o)),A("keydown=",n=>H0(n,t.tabs,o,p)),x(r.icon),x(r.label)})})}}),A("div.s-tabpanel role=tabpanel",t.contentAttrs,()=>{A(()=>{let r=h.value,o=t.tabs.findIndex((c,n)=>e(c,n)===r),d=t.tabs[o]??t.tabs[0];d&&(A("id=",`${a}-panel-${e(d,o)}`,"aria-labelledby=",`${a}-tab-${e(d,o)}`),x(d.content))})})})}function k2(t,a){A(`button.s-strip-btn.s-strip-btn-${a<0?"left":"right"} type=button`,()=>{A("tabindex=-1 aria-hidden=true"),A("click=",()=>t.scrollBy({left:a*t.clientWidth*.8,behavior:"smooth"})),(a<0?f0:g0)({size:"1.1em"})})}function w0(t){let a=t.parentElement;if(!a||typeof ResizeObserver>"u")return;let e=()=>{let r=t.scrollWidth-t.clientWidth;a.classList.toggle("s-can-left",t.scrollLeft>1),a.classList.toggle("s-can-right",t.scrollLeft<r-1)};t.addEventListener("scroll",e,{passive:!0});let h=new ResizeObserver(e);h.observe(t);let p=typeof MutationObserver>"u"?void 0:new MutationObserver(r=>{for(let o of r){for(let d of o.addedNodes)d instanceof Element&&h.observe(d);for(let d of o.removedNodes)d instanceof Element&&h.unobserve(d)}e()});p?.observe(t,{childList:!0});for(let r of Array.from(t.children))h.observe(r);e(),A.clean(()=>{t.removeEventListener("scroll",e),h.disconnect(),p?.disconnect()})}function H0(t,a,e,h){let p=e;if(t.key==="ArrowRight"||t.key==="ArrowDown")p=(e+1)%a.length;else if(t.key==="ArrowLeft"||t.key==="ArrowUp")p=(e-1+a.length)%a.length;else if(t.key==="Home")p=0;else if(t.key==="End")p=a.length-1;else return;t.preventDefault();let r=p>=e?1:-1;for(let o=0;o<a.length;o++){let d=a[p];if(d&&!d.disabled){h(d,p),t.currentTarget?.parentElement?.children[p]?.focus();return}p=(p+r+a.length)%a.length}}var K1={integer(t){if(!/^(0|-?[1-9]\d*)$/.test(t))return;let a=Number(t);return Number.isSafeInteger(a)?a:void 0}};function B(t){let a=String(t).replace(/\/+$/,"");return a.startsWith("/")||(a=`/${a}`),a}function i1(t){let a=B(t);return a==="/"?[]:a.slice(1).split("/")}function C2(t){let a=i1(t),e=a.map((h,p)=>{if(!h.startsWith("[")||!h.endsWith("]"))return{kind:"lit",value:h};let r=/^\[\.\.\.([A-Za-z_$][\w$]*)\]$/.exec(h);if(r){if(p!==a.length-1)throw new Error(`Staffa: "${h}" must be the last segment of route "${t}"`);return{kind:"rest",name:r[1]}}let o=/^\[([A-Za-z_$][\w$]*)(?:=([A-Za-z_$][\w$]*))?\]$/.exec(h);if(!o)throw new Error(`Staffa: malformed param "${h}" in route "${t}"`);let[,d,c]=o;if(c&&!(c in K1))throw new Error(`Staffa: unknown matcher "${c}" in route "${t}" (known: ${Object.keys(K1).join(", ")})`);return{kind:"param",name:d,matcher:c}});return{key:t,segs:e}}function A0(t){try{return decodeURIComponent(t)}catch{return t}}function F1(t,a){let e={};for(let h=0;h<t.segs.length;h++){let p=t.segs[h];if(p.kind==="rest")return h>=a.length?null:(e[p.name]=a.slice(h).join("/"),e);if(h>=a.length)return null;let r=a[h];if(p.kind==="lit"){if(r!==p.value)return null}else if(p.matcher){let o=K1[p.matcher](r);if(o===void 0)return null;e[p.name]=o}else e[p.name]=A0(r)}return t.segs.length===a.length?e:null}var $2=250,V0=300,k0=360,H1=540,z2=2;s.insertGlobalCss({":root":`--s-panel-ms:${$2}ms`,".s-panels":"flex:1 min-width:0 min-height:0 position:relative overflow:clip isolation:isolate "+L1,".s-panel":{"&":"position:absolute top:0 bottom:0 left:0 display:flex flex-direction:column "+L1+" visibility:visible transition: left var(--s-panel-ms) ease, transform var(--s-panel-ms) ease-out, opacity var(--s-panel-ms) linear, visibility 0s;","&.s-panel-sep::before":"content:'' position:absolute left:0 top:0.6rem bottom:0.6rem width:1px z-index:1 background: linear-gradient(to bottom, transparent, $s-faint 18%, $s-faint 82%, transparent);","&.s-panel-enter":"opacity:0 transition:none transform: translateX(8cqw);","&.s-panel-closing":"opacity:0 pointer-events:none transform: translateX(8cqw);","&.s-panel-hidden, &.s-panel-parked":"opacity:0 visibility:hidden transition: left var(--s-panel-ms) ease, transform var(--s-panel-ms) ease-out, opacity var(--s-panel-ms) linear, visibility var(--s-panel-ms);","&.s-panel-hidden":"transform: translateX(-8cqw);","&.s-panel-parked":"transform: translateX(8cqw);"},".s-panel > .s-content":"flex:1 min-height:0 overflow-y:auto overflow-x:hidden p:$3",".s-panel-actions":"display:flex align-items:center justify-content:flex-end gap:$1 flex-shrink:0 padding: $3 $3 0;",".s-crumbs > .s-strip-row":"gap:$m1",".s-crumb":{"&":"flex: 1 0 4rem; font-size:0.85em line-height:1.5 fg:$s-muted text-decoration:none white-space:nowrap max-width:max-content overflow:hidden text-overflow:ellipsis transition: color 0.12s;","&.s-crumb-on":"font-weight:600 fg:$s-text","a&:hover":"filter:none color: color-mix(in lab, $s-primary 33%, $s-text);","svg.s-crumb-pin":"vertical-align:-0.12em margin-right:0.3em opacity:0.8 fill:currentColor","svg.s-crumb-unsaved":"vertical-align:0.08em margin-right:0.3em fill:currentColor"},"svg.s-crumb-sep":"flex-shrink:0 opacity:0.4",".s-main.s-shell-snap .s-panel":"transition:none",".s-panel-loading":{"&":"position:absolute inset:0 display:flex align-items:center justify-content:center gap:$1 pointer-events:none",i:"width:0.5rem height:0.5rem r:50% background:$s-muted opacity:0.45 animation: s-panel-pulse 1s ease-in-out infinite;","i:nth-child(2)":"animation-delay:0.15s","i:nth-child(3)":"animation-delay:0.3s"},"@keyframes s-panel-pulse":{"0%, 100%":"opacity:0.25 transform:scale(0.8)","50%":"opacity:0.7 transform:scale(1)"}});var U1=!1,A1=class{[L2]=!0;compiled;ancestors;opts;$state=s.proxy({live:[],focus:0});$open=s.proxy({});nextOrder=0;containerEl;geom;lastGeom;layoutQueued=!1;timers=new Set;intent=null;settling=null;lastSeen=null;queued=null;constructor(a){if(U1)throw new Error("Staffa: only one routed S.main() (one with `routes`) can be active at a time");U1=!0,this.opts=a,this.compiled=Object.entries(a.routes).map(([e,h])=>({...C2(e),draw:h})),this.ancestors=Object.entries(a.ancestors??{}).filter(e=>e[1]!=null).map(([e,h])=>({...C2(e),fn:h})),s(()=>{let e=this.computeTarget(),h={...w.current.search},p=w.current.hash;s.peek(()=>{let r=this.lastSeen;if(r&&r.path!==w.current.path){let o=this.$state.live.find(d=>d.path===r.path);o&&(o.search=r.search,o.hash=r.hash)}this.lastSeen={path:w.current.path,search:h,hash:p},this.propose(e),Array.isArray(w.current.state.panels)||Object.assign(w.current.state,this.stateFor({stack:this.paths(),focus:this.$state.focus}))})}),this.interceptLinks(),this.watchTitle(),this.guardTabClose(),s.clean(()=>{for(let e of this.timers)clearTimeout(e);this.timers.clear(),this.queued?.settle(!1),this.queued=null,U1=!1})}resolve(a){let e=i1(a);for(let h of this.compiled){let p=F1(h,e);if(p)return{draw:h.draw,params:p}}return{draw:this.opts.notFound??z0,params:{}}}matches(a){let e=i1(a);return this.compiled.some(h=>F1(h,e)!=null)}deriveStack(a){let e=B(a),h=this.askAncestors(e),p=h?h.map(B):this.prefixesOf(e),r=[];for(let o of p)o!==e&&!r.includes(o)&&this.matches(o)&&r.push(o);return r.push(e),r}askAncestors(a){let e=i1(a);for(let h of this.ancestors){let p=F1(h,e);if(p)return h.fn(p,a)??void 0}}prefixesOf(a){let e=i1(a),h=[];for(let p=1;p<e.length;p++)h.push("/"+e.slice(0,p).join("/"));return h}pinnedIn(a,e){return a.filter(h=>e.includes(h)?!1:this.$state.live.find(p=>p.path===h)?.$panel.pinned===!0)}unsavedAt(a){return this.$state.live.find(e=>e.path===a)?.$panel.unsaved===!0}targetFor(a,e){let h=Array.isArray(e?.panels)?e.panels.map(String):null;if(h){let p=Array.isArray(e.parked)?e.parked.map(String):[],r=B(a),o=new Set([r]),d=n=>n.map(B).filter(y=>!o.has(y)&&!!o.add(y)),c=d(h);return{stack:[...c,r,...d(p)],focus:c.length}}return s.peek(()=>{let p=this.deriveStack(a).slice(0,-1),r=[...p,...this.pinnedIn(this.paths(),[...p,B(a)]),B(a)];return{stack:r,focus:r.length-1}})}computeTarget(){return this.targetFor(w.current.path,w.current.state)}paths(){return this.$state.live.map(a=>a.path)}propose(a){let e=this.$state.live.filter(h=>!a.stack.includes(h.path)&&h.$panel.unsaved).map(h=>h.path);e.length&&(a={stack:[...a.stack,...e],focus:a.focus}),!(S2(this.paths(),a.stack)&&a.focus===this.$state.focus)&&this.commit(a,w.current.nav)}commit(a,e){this.geom=void 0;let h=w.current.state.pinned,p=new Set(Array.isArray(h)?h.map(String):[]),r=new Map(this.$state.live.map(d=>[d.path,d])),o=[];for(let d of a.stack){let c=r.get(d);if(c){r.delete(d),o.push(c);continue}let n=this.createEntry(d,o.length<=a.focus,p.has(d));e!=="load"&&e!=="back"&&(n.enter=!0),o.push(n),this.$open[d]=n}for(let d of r.values())this.beginClose(d);this.$state.live=o,this.$state.focus=Math.min(a.focus,o.length-1),this.scheduleLayout()}createEntry(a,e,h){let{draw:p,params:r}=this.resolve(a),o={[L2]:!0,order:this.nextOrder++,path:a,draw:p,$ui:s.proxy({holding:!1}),maxWidth:"medium",width:0};return o.$panel=s.proxy({stack:this,params:r,path:a,width:0,visible:e,pinned:h||void 0,close:()=>this.closePath(o.path),open:(d,c)=>this.navigate(d,{from:o.path,how:c})}),o}beginClose(a){a.closing=!0,a.$panel.visible=!1,a.el&&(a.el.style.zIndex=String(z2*this.$state.live.indexOf(a))),delete this.$open[a.path]}playExit(a,e){if(!a.closing){e.remove();return}e.classList.add("s-panel-closing"),e.setAttribute("inert","");let h=()=>{clearTimeout(p),this.timers.delete(p),e.remove()};e.addEventListener("transitionend",r=>{r.target===e&&r.propertyName==="opacity"&&h()});let p=setTimeout(h,$2+80);this.timers.add(p)}intended(){return this.intent??{stack:this.paths(),focus:this.$state.focus}}stateFor(a){return{panels:a.stack.slice(0,a.focus),parked:a.stack.slice(a.focus+1),pinned:this.pinnedPaths()}}pinnedPaths(){return this.$state.live.filter(a=>a.$panel.pinned).map(a=>a.path)}issue(a,e){return this.intent=a,this.settling?(this.queued?.settle(!1),new Promise(h=>{this.queued={run:e,settle:h}})):this.start(e)}start(a){let e=p=>{this.settling=null;let r=this.queued;return this.queued=null,p&&r?this.start(r.run).then(r.settle,()=>r.settle(!1)):(this.intent=null,r?.settle(!1)),p},h=Promise.resolve(a()).then(e,p=>(console.error(p),e(!1)));return this.settling=h,h}focusAt(a){let e=this.intended();if(a<0||a>=e.stack.length||a===e.focus)return Promise.resolve(!1);let h={stack:e.stack,focus:a},p=e.stack[a];return this.issue(h,()=>{let r=this.$state.live.find(o=>o.path===p);return w.go({path:p,search:r?.search,hash:r?.hash,state:this.stateFor(h)})})}back(){return s.peek(()=>{let a=this.intended();return a.focus===a.stack.length-1&&!this.unsavedAt(a.stack[a.focus])?this.closePath(a.stack[a.focus]??""):a.focus===0?Promise.resolve(!1):this.focusAt(a.focus-1)})}closePath(a){return s.peek(()=>{let e=this.intended(),h=e.stack.indexOf(B(a));if(h<0||e.stack.length<2||this.unsavedAt(e.stack[h]))return Promise.resolve(!1);let p=e.stack.filter((n,y)=>y!==h),r=h===e.focus?Math.max(0,h-1):e.focus-(h<e.focus?1:0),o={stack:p,focus:r};if(h===e.focus&&h===e.stack.length-1){let n=this.$state.live.find(m=>m.path===p[r]),y={};n?.search&&(y.search=n.search),n?.hash&&(y.hash=n.hash);let i=p.filter(m=>this.$state.live.find(g=>g.path===m)?.$panel.pinned===!0);return this.issue(o,()=>Promise.resolve(w.back({path:p[r],state:{panels:p.slice(0,r),parked:[]}},y)).then(m=>(m&&(w.current.state.pinned=i),m)))}let d=p[r],c=d!==e.stack[e.focus];return this.issue(o,()=>{let n=c?this.$state.live.find(y=>y.path===d):void 0;return w.go({path:d,search:c?n?.search:{...w.current.search},hash:c?n?.hash:w.current.hash,state:this.stateFor(o)})})})}navigate(a,{from:e,how:h,beneath:p}={}){let r=h??this.opts.linkNavigation,o=r==="open"?null:e??null,d=r==="replace";return s.peek(()=>{let c;try{c=new URL(a,location.href)}catch{return Promise.resolve(!1)}let n=B(c.pathname),y=this.intended(),i=p?-1:y.stack.indexOf(n),m;if(i>=0&&r!=="replace"&&r!=="open"){let f=this.pinnedIn(y.stack.slice(i+1),[]);m={stack:[...y.stack.slice(0,i+1),...f],focus:i}}else{let f=o==null?-1:y.stack.indexOf(o),z=(p?p.map(B):f<0?this.deriveStack(n).slice(0,-1):y.stack.slice(0,d?f:f+1)).filter((W1,O2,E2)=>W1!==n&&E2.indexOf(W1)===O2),s1=[...z,...this.pinnedIn(y.stack,[...z,n,d?o:null])];m={stack:[...s1,n],focus:s1.length}}let g=i>=0?this.$state.live.find(f=>f.path===n):void 0,H=c.search?Object.fromEntries(new URLSearchParams(c.search)):g?.search??{},l=c.hash||g?.hash||"";return m.focus===y.focus&&S2(m.stack,y.stack)&&c.search===location.search&&(c.hash||"")===(location.hash||"")?Promise.resolve(!0):this.issue(m,()=>w.go({path:n,search:H,hash:l,state:this.stateFor(m)}))})}pushPath(a,e){return s.peek(()=>{let h=this.intended();return this.navigate(a,{from:h.stack[h.focus],how:e?"replace":"push"})})}interceptLinks(){w.interceptLinks((a,e,h)=>{if(h instanceof KeyboardEvent&&(h.ctrlKey||h.metaKey||h.shiftKey||h.altKey))return!1;let p=e.getAttribute("data-panel")??void 0,r=e.closest(".s-panel"),o=r?this.$state.live.find(d=>d.el===r):e.closest(".s-panel-origin")?this.$state.live[this.$state.focus]:void 0;return this.navigate(a.href,{from:o?.path,how:p}),!0})}get currentPanel(){return this.$state.live[this.$state.focus]?.$panel}get panels(){return this.$state.live.map(a=>a.$panel)}get currentPanelIndex(){return this.$state.focus}pushPanel(a){return this.pushPath(a,!1)}replacePanel(a){return this.pushPath(a,!0)}openPanelStack(a,e){return this.navigate(a,{how:"open",beneath:e})}closePanel(a){return s.peek(()=>{let e=this.intended();return this.closePath(a??e.stack[e.focus]??"")})}setColumns(a){this.opts.columns!==a&&(this.opts.columns=a,this.scheduleLayout())}setLinkNavigation(a){this.opts.linkNavigation=a}drawCrumbs(){b1({attrs:".s-crumbs role=navigation aria-label=Breadcrumbs",content:()=>{s(()=>{let a=this.panels.map(p=>p.path),e=this.currentPanelIndex,h;for(let p=0;p<a.length;p++){p&&m2({size:"0.85em",attrs:".s-crumb-sep"});let r=this.drawCrumb(a[p],p,p===e);p===e&&(h=r)}requestAnimationFrame(()=>{h&&w1(h)})})}})}drawCrumb(a,e,h){let p=this.$state.live[e];return s(h?"span.s-crumb aria-current=page":"a.s-crumb",()=>{h||s("href=",a),s(()=>{p?.$panel.visible&&s(".s-crumb-on")}),s(()=>{p?.$panel.unsaved&&l2({size:"0.45em",attrs:".s-crumb-unsaved"})}),s(()=>{p?.$panel.pinned&&O1({size:"0.85em",attrs:".s-crumb-pin"})}),s(()=>{s("#",p?.$panel.title??p?.$ui.fallback??(a.split("/").pop()||a))}),I1({link:a,items:[{label:()=>{s(()=>{s("#",p?.$panel.pinned?"Unpin":"Pin")})},icon:()=>{s(()=>{(p?.$panel.pinned?v2:O1)()})},click:()=>{p&&this.togglePin(p)}},{label:"Close",icon:e1,disabled:p?.$panel.unsaved===!0,click:()=>{this.closePath(a)}}]})})}togglePin(a){a.$panel.pinned=!a.$panel.pinned||void 0,w.current.state.pinned=this.pinnedPaths()}watchTitle(){let a=document.title;s(()=>{let e=this.$state.live[this.$state.focus],h=e?.$panel.title??e?.$ui.fallback,p=typeof this.opts.title=="string"?this.opts.title:void 0,r=this.$state.live.some(d=>d.$panel.unsaved),o=h&&p?`${h} \xB7 ${p}`:h||p;o&&(document.title=(r?"\u2022 ":"")+o)}),s.clean(()=>{document.title=a})}guardTabClose(){if(typeof window>"u")return;let a=e=>{let h=this.$state.live.find(p=>p.$panel.unsaved);h&&(e.preventDefault(),e.returnValue=!0,this.flushLayout(),h.$panel.visible||this.focusAt(this.intended().stack.indexOf(h.path)))};s(()=>{this.$state.live.some(e=>e.$panel.unsaved)&&(window.addEventListener("beforeunload",a),s.clean(()=>window.removeEventListener("beforeunload",a)))})}drawColumns(){let a=s("div.s-panels role=main",()=>{this.containerEl=s(),s.onEach(this.$open,e=>this.drawPanel(e),e=>e.order)});if(typeof ResizeObserver<"u"){let e=new ResizeObserver(()=>this.layout());e.observe(a),s.clean(()=>e.disconnect())}s.clean(()=>{this.containerEl===a&&(this.containerEl=void 0)}),this.scheduleLayout()}drawPanel(a){let e;s(()=>{let h=a.$panel.maxWidth;a.maxWidth=h==="small"||h==="large"||h==="none"?h:"medium";let p=this.roomFor(a.maxWidth);p&&(a.width=p,s.peek(a.$panel,"width")!==p&&(a.$panel.width=p),e&&(e.style.width=`${p}px`,this.scheduleLayout()))}),e=s(`section.s-panel${a.width?` w:${a.width}px`:""}`,"destroy=",h=>this.playExit(a,h),()=>{s(()=>this.drawActions(a)),s("div.s-content",()=>{if(a.draw(a.$panel),w.persistScroll(a.path),s.peek(a.$panel,"title")==null){let h=C0(s());h&&s.peek(a.$ui,"fallback")!==h&&(a.$ui.fallback=h)}}),s(()=>{!a.$panel.loading||a.$ui.holding||s("div.s-panel-loading aria-hidden=true",()=>{s("i"),s("i"),s("i")})})}),a.el=e,a.placed=!1,e.style.transition="none",s.clean(()=>{a.el===e&&(a.el=void 0)}),s(()=>{a.$panel.loading,this.scheduleLayout()}),this.scheduleLayout()}drawActions(a){this.opts.$shell.narrow||a.$panel.actions==null||s("div.s-panel-actions",()=>x(a.$panel.actions))}scheduleLayout(){this.layoutQueued||(this.layoutQueued=!0,requestAnimationFrame(()=>this.flushLayout()))}flushLayout(){this.layoutQueued&&(this.layoutQueued=!1,this.layout())}measure(){let a=this.containerEl,e=a?a.getBoundingClientRect().width:0;if(!e)return;let h=Math.ceil(e/H1),p=e/h>=k0?e/h:Math.min(e,H1),r=o=>Math.min(o*p,e);return{area:e,size:{small:p,medium:r(2),large:r(3),none:e}}}geometry(){return this.geom??=this.measure()}roomFor(a){return this.geometry()?.size[a]??0}layout(){let a=this.containerEl,e=a?.closest(".s-main");if(!a||!e)return;let h=this.$state.live,p=h.length;if(!p||h.some(l=>!l.el))return;this.geom=void 0;let r=this.geometry();if(!r)return;let o=this.opts.columns==="single",d=this.lastGeom?.area!==r.area;d&&(this.lastGeom=r,e.classList.add("s-shell-snap"));let c=l=>r.size[l.maxWidth],n=Math.min(this.$state.focus,p-1),y=n,i=c(h[n]);if(!o)for(let l=n-1;l>=0;l--){let f=i+c(h[l]);if(f>r.area)break;i=f,y=l}let m=(r.area-i)/2;for(let l=y;l<=n;l++)h[l].width=c(h[l]);for(let l of h)l.width||(l.width=c(l));let g=[],H=m;for(let l=0;l<p;l++){let f=h[l],C=f.el,z=l>=y&&l<=n;L0(C,z?H:l>n?m+i:m,f.width,z2*l+1),f.$panel.visible!==z&&(f.$panel.visible=z),f.$panel.width!==f.width&&(f.$panel.width=f.width),z&&(H+=f.width),C.classList.toggle("s-panel-sep",z&&l>y),C.classList.toggle("s-panel-hidden",l<y),C.classList.toggle("s-panel-parked",l>n),C.toggleAttribute("inert",!z),!f.placed&&(g.push(f),!f.$panel.loading||f.holdDone?f.$ui.holding=!1:f.$ui.holding||(f.$ui.holding=!0,this.holdEnter(f)),f.enter&&z&&C.classList.add("s-panel-enter"))}(g.length||d)&&a.offsetWidth,d&&e.classList.remove("s-shell-snap");for(let l of g)l.$ui.holding||(l.el.style.transition="",l.el.classList.remove("s-panel-enter"),l.enter=!1,l.placed=!0)}holdEnter(a){let e=setTimeout(()=>{this.timers.delete(e),a.holdDone=!0,a.$ui.holding&&(a.$ui.holding=!1,this.scheduleLayout())},V0);this.timers.add(e)}};function L0(t,a,e,h){t.style.left=`${a}px`,t.style.width=`${e}px`,t.style.zIndex=String(h)}function S2(t,a){return t.length===a.length&&t.every((e,h)=>e===a[h])}function C0(t){let a=document.createTreeWalker(t,NodeFilter.SHOW_TEXT);for(let e=a.nextNode();e;e=a.nextNode()){let h=e.textContent.trim();if(h)return h.length>48?`${h.slice(0,47).trimEnd()}\u2026`:h}}function z0(t){s("p fg:$s-muted",()=>s("#",`No panel at ${t.path}`))}var S0=200;v.insertGlobalCss({".s-main":{"&":"display:flex flex-direction:column min-height:100vh max-height:100vh container-type:inline-size","body > &":"margin: calc(-1 * $3)","> header":"border:0 border-bottom: 1px solid $s-faint; r:0 position:sticky top:0 z-index:10","> footer":"border-top: 1px solid $s-faint; fg:$s-muted","> header > .s-bar, > footer > .s-bar":"display:flex align-items:center width:100% margin-inline:auto gap:$3 padding: $2 $3;","> header .s-logo, > header .s-nav-trigger":"display:flex align-items:center flex-shrink:0","> header .s-nav-trigger":"margin-left:-0.375rem","> header .s-logo":"font-size:1.4em background: $s-gradient; -webkit-background-clip:text; background-clip:text; color:transparent;","> header .s-titles":"display:flex flex-direction:column min-width:5rem flex: 0 1 auto;","> header .s-subtitle":"fg:$s-muted font-size:0.85em line-height:1.5 overflow:hidden text-overflow:ellipsis white-space:nowrap","> header .s-title":"font-weight:800 font-size:1.1em line-height:1.2 overflow:hidden text-overflow:ellipsis white-space:nowrap letter-spacing:-0.01em background: $s-gradient; -webkit-background-clip:text; background-clip:text; color:transparent; width:fit-content max-width:100%","> header a.s-logo, > header a.s-title":"text-decoration:none filter:none cursor:pointer","> header .s-menu":"display:flex align-items:center justify-content:flex-end gap:$2 flex: 1 0.1 auto; min-width:0",".s-body":"flex:1 overflow:clip display:flex flex-direction:row min-height:0 justify-content:center position:relative",".s-body-inner":"flex:1 min-width:0 display:flex flex-direction:row min-height:0","&.s-nav-right .s-body-inner":"flex-direction:row-reverse",".s-nav-sep":"width:1px flex-shrink:0 align-self:stretch margin: 0.6rem 0; border:0 background: linear-gradient(to bottom, transparent, $s-faint 18%, $s-faint 82%, transparent);",".s-body main":"flex:1 min-width:0 min-height:0 overflow-x:hidden overflow-y:auto display:flex flex-direction:column transition: transform var(--s-panel-ms) ease;",".s-body main.s-slide-in":"transform: translateX(100%); transition:none",".s-body main > .s-content":"width:100% flex:1 p:$3",".s-body main.s-scroll-y":"margin-right:$3"},".s-nav-panel":{"&":"display:flex flex-direction:column overflow-y:auto flex-shrink:0 width: calc(var(--s-nav-w) - 1px); padding:$3 gap:$1"},".s-nav-page":{"&":"position:absolute inset:0 z-index:5 display:flex flex-direction:column overflow-y:auto overscroll-behavior:contain border:0 r:0 padding:$2 gap:$1 transition: transform var(--s-panel-ms) ease, visibility 0s;","&.s-nav-page-off":"transform:translateX(-100%) pointer-events:none visibility:hidden transition: transform var(--s-panel-ms) ease, visibility var(--s-panel-ms);",".s-menu-item":"padding: $2 $3; min-height:3rem font-size:1.05em gap:$3"},[`@container (max-width: ${x1}px)`]:{".s-main .s-nav-panel, .s-main .s-nav-sep":"display:none",".s-main > header > .s-bar":"gap:$1 padding: $1 $2;",".s-main .s-body main.s-scroll-y":"margin-right:0"},[`@container (max-width: ${H1}px)`]:{".s-content > .s-box":"margin-inline: calc(-1 * $3); r:0 border-inline:0"}});function $0(t={}){let a=t.nav,e=t.navPosition??"left",h=v.proxy({open:!1}),p=v.proxy({narrow:typeof document<"u"&&document.documentElement.clientWidth<=x1}),r=t.routes;if(r!=null&&t.content!=null)throw new Error("Staffa: S.main() takes either `content` or `routes`, not both");let o=r?new A1({routes:r,notFound:t.notFound,ancestors:t.ancestors,title:t.title,$shell:p}):null;o&&(v(()=>o.setColumns(t.columns)),v(()=>o.setLinkNavigation(t.linkNavigation)));let d=o&&t.home!==null?t.home??"/":null,c=()=>{t.maxWidth!=null&&v("max-width:",t.maxWidth)},n=v("div.s-main",t.attrs,()=>{v(()=>{a==null||!a.items.length?v("--s-nav-w: 0px"):v(`.s-nav-${e}`,`--s-nav-w: ${t.navWidth??S0}px`)}),v(()=>{(o!=null||t.title!=null||t.subtitle!=null||t.logo!=null||t.menu!=null||a!=null&&a.items.length>0)&&v("header.s-s.neutral",t.topbarAttrs,()=>{v("div.s-bar",()=>{v(c),v(()=>{if(p.narrow&&a!=null&&a.items.length){v("div.s-nav-trigger",()=>T0(a,h));return}t.logo!=null&&v(d!=null?"a.s-logo aria-label=Home":"div.s-logo",()=>{d!=null&&v("href=",d),x(t.logo)})}),v("div.s-titles",()=>{v(()=>{t.title!=null&&v(d!=null?"a.s-title":"div.s-title",()=>{d!=null&&v("href=",d),x(t.title)})}),O0(t,o,a,p)}),v(()=>{let i=p.narrow?o?.currentPanel?.actions:void 0,m=i??t.menu;m!=null&&v(`div.s-menu${i!=null?".s-panel-origin":""}`,()=>x(m))})})})}),v("div.s-body",()=>{v("div.s-body-inner",()=>{v(c),v(()=>{a==null||!a.items.length||(v(`nav.s-nav-panel.s-nav-${e}`,t.navAttrs,()=>{c1(a.items)}),v("div.s-nav-sep aria-hidden=true"))}),Z0(t,o)}),v(()=>{a!=null&&a.items.length&&h.open&&R0(a,t.navPageAttrs,h,p)})}),v(()=>{t.footer!=null&&v("footer",()=>{v("div.s-bar",()=>{v(c),x(t.footer)})})})});return q0(n,p),a!=null&&n1(()=>a.items,()=>{h.open=!1}),(a!=null||o)&&v(()=>{let y=m=>()=>{$1()||g1()||m()},i=()=>n.querySelector(".s-nav-trigger button");h.open?S("Esc","Close the navigation",y(()=>{h.open=!1,i()?.focus()}),"global"):o&&o.currentPanelIndex>0?S("Esc","Back to the previous panel",y(()=>{o.back()}),"global"):S("Esc","Jump to the navigation",y(()=>{let m=n.querySelector(".s-nav-panel");m?.offsetParent!=null?(m.querySelector("[aria-current=page]")??m.querySelector(".s-menu-item:not([aria-disabled=true])"))?.focus():i()?.click()}),"global")}),o??void 0}var V1=null;function P0(){V1?.()}function O0(t,a,e,h){v(()=>{if(t.subtitle!=null&&(a==null||E0(a,e,h))){v("div.s-subtitle",()=>x(t.subtitle));return}a?.drawCrumbs()})}function E0(t,a,e){return e.narrow||a==null||t.panels.length>1?!1:T1(a.items)}function q0(t,a){if(typeof ResizeObserver>"u")return;let e=new ResizeObserver(h=>{let p=h[0]?.contentBoxSize?.[0],r=p?p.inlineSize:h[0]?.contentRect.width;r!=null&&(a.narrow=r<=x1)});e.observe(t),v.clean(()=>e.disconnect())}function T0(t,a){p1({icon:t.button?.icon??(()=>v(()=>(a.open?e1:m1)())),ariaLabel:t.button?.ariaLabel??"Open navigation",attrs:t.button?.attrs,click:()=>{a.open=!a.open}})}function R0(t,a,e,h){let p=!1,r=()=>{p=!0,e.open=!1},o=v("nav.s-nav-page.s-s.neutral aria-label=Navigation create=s-nav-page-off destroy=s-nav-page-off",a,()=>c1(t.items,r));V1=r,v.clean(()=>{V1===r&&(V1=null)});let d=v.peek(N1,"path");v(()=>{N1.path!==d&&!Z1(N1.path)&&r()});let c=o.closest(".s-main"),n=o.parentElement?.querySelector(":scope > .s-body-inner"),y=n?.querySelector(":scope > main");n?.setAttribute("inert",""),v(()=>{h.narrow||(e.open=!1)}),v.clean(()=>{n?.removeAttribute("inert"),p&&(y&&D0(y),c?.querySelector(".s-nav-trigger button")?.focus())}),requestAnimationFrame(()=>{document.body.contains(o)&&J(o,".s-menu-item[aria-current=page]")})}function D0(t){t.classList.add("s-slide-in"),t.offsetWidth,t.classList.remove("s-slide-in")}function Z0(t,a){if(a){a.drawColumns();return}let e=v("main",()=>{v("div.s-content",t.contentAttrs,()=>{x(t.content)})});B0(e)}function B0(t){if(typeof ResizeObserver>"u")return;let a=()=>t.classList.toggle("s-scroll-y",t.offsetWidth>t.clientWidth),e=new ResizeObserver(a);e.observe(t),t.firstElementChild&&e.observe(t.firstElementChild),a(),v.clean(()=>e.disconnect())}import O from"aberdeen";O.insertGlobalCss({".s-select_wrap":{"&":"position:relative display:block",select:"w:100% cursor:pointer padding-right:2.2em; appearance:none","&::after":"content: '\u25BE'; position:absolute right:0.7em top:50%; transform: translateY(-50%); pointer-events:none fg:$s-muted font-size:0.85em"}});function I0(t){N(t,(a,e)=>{O("div.s-select_wrap",()=>{O("select.s-input",t.inputAttrs,()=>{t1(t,a,e),O("change=",h=>{t.bind&&(t.bind.value=h.target.value)}),O(()=>{let h=typeof t.options=="function"?t.options():t.options,p=t.bind?.value??"";t.placeholder!=null&&O("option",()=>{O("value= disabled=true hidden=true"),p||O("selected=true"),O("#",t.placeholder)});for(let r of h){let o=typeof r=="string"?{value:r,label:r}:{value:r.value,label:r.label??r.value};O("option",()=>{O("value=",o.value),o.value===p&&O("selected=true"),O("#",o.label)})}})})})})}import I from"aberdeen";I.insertGlobalCss({"textarea.s-input":"resize:vertical min-height:3em line-height:1.45","textarea.s-input.s-autoGrow":"resize:none min-height:2.5em overflow-y:hidden"});function F0(t={}){let a=t.autoGrow!==!1;N(t,(e,h)=>{let p=I("textarea.s-input",t.inputAttrs,()=>{a?(I(".s-autoGrow"),I("input=",r=>{P2(r.currentTarget),t.input&&t.input(r)})):(I("rows=",t.rows??4),I("resize:",t.resize??"vertical"),t.input&&I("input=",t.input)),t.placeholder!=null&&I("placeholder=",t.placeholder),t.value!=null&&!t.bind&&I("value=",t.value),t.change&&I("change=",t.change),t1(t,e,h,t.bind)});a&&requestAnimationFrame(()=>P2(p))})}function P2(t){t.style.height="auto",t.style.height=`${t.scrollHeight}px`}export{I1 as addContextMenu,h1 as addTooltip,G2 as alert,J2 as autocomplete,S as bindKey,a0 as box,R as button,e0 as buttonChooser,X as buttonGroup,h0 as checkbox,V2 as closeFloatingMenu,P0 as closeNav,X2 as confirm,a1 as dialog,p0 as form,q as formatKey,_1 as getDarkMode,p1 as iconButton,$1 as isDialogOpen,g1 as isFloatingMenuOpen,$0 as main,u0 as menu,y0 as menuButton,j2 as prompt,w1 as revealInStrip,b1 as scrollStrip,I0 as select,T2 as setDarkMode,_2 as setKeyHelp,B1 as showFloatingMenu,P1 as showKeyHelp,b0 as tabs,F0 as textarea,S1 as textline,u1 as toast};
|
package/package.json
CHANGED
package/skill/MenuItem.md
CHANGED
|
@@ -42,12 +42,14 @@ columns rather than on top of whatever panel the menu was drawn in. Pass
|
|
|
42
42
|
|
|
43
43
|
A keyboard shortcut that activates this item: `"mod+k"`, `"f2"`, a bare
|
|
44
44
|
`"?"`. The spelling, and which keystrokes are yours to take, are
|
|
45
|
-
documented on `bindKey`.
|
|
46
|
-
the row (not on a touch device)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
45
|
+
documented on `bindKey`. In a dropdown or context menu the
|
|
46
|
+
combination shows at the right end of the row (not on a touch device); a
|
|
47
|
+
nav row — `S.main`'s sidebar, `menu` — keeps its label clean and
|
|
48
|
+
tells it in its | tooltip instead. Either way
|
|
49
|
+
it reaches screen readers as `aria-keyshortcuts`, and the `?` overview
|
|
50
|
+
(`showKeyHelp`) lists it under the item's label. Activating runs
|
|
51
|
+
`click` with the `KeyboardEvent` and follows `href` as a fresh navigation
|
|
52
|
+
to it — the target getting its own panel stack, as a nav item's does.
|
|
51
53
|
|
|
52
54
|
The shortcut works with the menu shut — rather the point of one on a
|
|
53
55
|
dropdown or context menu — for as long as whatever owns the items is
|
|
@@ -58,6 +60,14 @@ not bound.
|
|
|
58
60
|
|
|
59
61
|
**Type:** `string`
|
|
60
62
|
|
|
63
|
+
### menuItem.tooltip · member
|
|
64
|
+
|
|
65
|
+
A tooltip for this item, shown on hover and keyboard focus. A string
|
|
66
|
+
renders as rich text. In a nav, the item's `key` is shown underneath it,
|
|
67
|
+
behind a subtle separator (see `MenuItem.key`).
|
|
68
|
+
|
|
69
|
+
**Type:** `Slot`
|
|
70
|
+
|
|
61
71
|
### menuItem.match · member
|
|
62
72
|
|
|
63
73
|
Pages this item claims *beyond* its own `href`: a string claims that path
|
package/skill/Panel.md
CHANGED
|
@@ -96,9 +96,9 @@ visible at once, and both of them are really there.
|
|
|
96
96
|
The widest this panel can usefully be — a ceiling the shell never
|
|
97
97
|
exceeds, so the draw function never has to look right past it. It is
|
|
98
98
|
counted in the shell's *columns*: the content area divides into the
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
99
|
+
fewest whole number of columns of at most 540px each (two columns of 540
|
|
100
|
+
in a 1080px area, three of ~507 in 1520px), and a column is never
|
|
101
|
+
narrower than 360 — where the area holds just one, a small centres in it
|
|
102
102
|
rather than stretching. So an ask never exceeds its column count × 540:
|
|
103
103
|
|
|
104
104
|
- `"small"` — one column, never above 540px: lists, detail forms.
|
package/skill/SKILL.md
CHANGED
|
@@ -169,7 +169,7 @@ Each handler gets a `$panel` proxy: the params from its route, plus what the she
|
|
|
169
169
|
|
|
170
170
|
**The stack is an object, not a global.** `S.main()` hands back the `PanelStack` — `pushPanel`, `replacePanel`, `openPanelStack`, `closePanel`, and the live, reactive `panels` / `currentPanel` / `currentPanelIndex` — and every panel gets that same object as `$panel.stack`, which is what a route handler uses, since it runs while the `S.main()` call is still going. Every navigation settles asynchronously (closes travel through the browser's history), so each method returns a `Promise<boolean>`. Don't hold a `Panel` across a navigation; read it fresh. To navigate on behalf of one particular screen — a row's click handler — use that panel's own `$panel.open(href, how?)`, which does exactly what a link inside it does; `pushPanel` builds on the *current* panel instead.
|
|
171
171
|
|
|
172
|
-
**Columns and widths.** The content area is the window minus the nav sidebar, or `S.main({ maxWidth })` of it, centred — the same width whatever is open, so the sidebar, top bar and footer never move. It divides into the
|
|
172
|
+
**Columns and widths.** The content area is the window minus the nav sidebar, or `S.main({ maxWidth })` of it, centred — the same width whatever is open, so the sidebar, top bar and footer never move. It divides into the fewest whole number of columns of at most **540px** each, never narrower than **360px**; `$panel.maxWidth` asks for one, two (the default), three of them or the lot. A column's width depends only on the window, never on what else is open, so opening or closing a panel never resizes another. Its ask is a ceiling, never a floor: aim your layout at 360px and let it degrade gracefully below that. `$panel.width` is the resolved figure in pixels, correct before your handler draws.
|
|
173
173
|
|
|
174
174
|
**A panel declares its chrome; the shell places it.** A screen says what it is called and what it can do; everything else in its column — headings, cards, boxes — is the screen's own content, drawn like any other.
|
|
175
175
|
|
package/src/components/menu.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { type Slot, type Attributes, drawSlot, mountPortal, focusFirst } from ".
|
|
|
4
4
|
import { menu as menuIcon, chevronRight, externalLink as newTabIcon, link as linkIcon } from "../icons.js";
|
|
5
5
|
import { button, type ButtonOptions } from "./button.js";
|
|
6
6
|
import { toast } from "./toast.js";
|
|
7
|
+
import { addTooltip } from "./tooltip.js";
|
|
7
8
|
import { bindKey, formatKey } from "../keys.js";
|
|
8
9
|
|
|
9
10
|
/**
|
|
@@ -35,12 +36,14 @@ export interface MenuItem {
|
|
|
35
36
|
/**
|
|
36
37
|
* A keyboard shortcut that activates this item: `"mod+k"`, `"f2"`, a bare
|
|
37
38
|
* `"?"`. The spelling, and which keystrokes are yours to take, are
|
|
38
|
-
* documented on {@link bindKey}.
|
|
39
|
-
* the row (not on a touch device)
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
39
|
+
* documented on {@link bindKey}. In a dropdown or context menu the
|
|
40
|
+
* combination shows at the right end of the row (not on a touch device); a
|
|
41
|
+
* nav row — `S.main`'s sidebar, {@link menu} — keeps its label clean and
|
|
42
|
+
* tells it in its {@link MenuItem.tooltip | tooltip} instead. Either way
|
|
43
|
+
* it reaches screen readers as `aria-keyshortcuts`, and the `?` overview
|
|
44
|
+
* ({@link showKeyHelp}) lists it under the item's label. Activating runs
|
|
45
|
+
* `click` with the `KeyboardEvent` and follows `href` as a fresh navigation
|
|
46
|
+
* to it — the target getting its own panel stack, as a nav item's does.
|
|
44
47
|
*
|
|
45
48
|
* The shortcut works with the menu shut — rather the point of one on a
|
|
46
49
|
* dropdown or context menu — for as long as whatever owns the items is
|
|
@@ -50,6 +53,12 @@ export interface MenuItem {
|
|
|
50
53
|
* not bound.
|
|
51
54
|
*/
|
|
52
55
|
key?: string;
|
|
56
|
+
/**
|
|
57
|
+
* A tooltip for this item, shown on hover and keyboard focus. A string
|
|
58
|
+
* renders as rich text. In a nav, the item's `key` is shown underneath it,
|
|
59
|
+
* behind a subtle separator (see {@link MenuItem.key}).
|
|
60
|
+
*/
|
|
61
|
+
tooltip?: Slot;
|
|
53
62
|
/**
|
|
54
63
|
* Pages this item claims *beyond* its own `href`: a string claims that path
|
|
55
64
|
* and everything under it (`"/mail"` claims `/mail/…`, not `/mailbox`), a
|
|
@@ -229,6 +238,11 @@ A.insertGlobalCss({
|
|
|
229
238
|
"@media (hover: none) and (pointer: coarse)": {
|
|
230
239
|
".s-menu-key": "display:none",
|
|
231
240
|
},
|
|
241
|
+
// A nav row's key rides its tooltip instead (see `drawHints`): a quiet line of
|
|
242
|
+
// its own, under the item's tip content when it has one, split off by the
|
|
243
|
+
// menu's own fading hairline.
|
|
244
|
+
".s-menu-tt-key": "font-family:inherit font-size:0.85em opacity:0.7 white-space:nowrap",
|
|
245
|
+
".s-tt-tip hr.s-menu-sep": "margin: 0.35em 0;",
|
|
232
246
|
// A branch row's fold indicator: a › that turns downward while the branch is open.
|
|
233
247
|
".s-menu-chevron": "margin-left:auto flex-shrink:0 display:flex transition: transform 0.15s ease;",
|
|
234
248
|
// Two `margin-left:auto`s in one row would split the free space between them,
|
|
@@ -269,8 +283,11 @@ A.insertGlobalCss({
|
|
|
269
283
|
* @param onLeafSelect Optional — run when a *leaf* item is activated (used by
|
|
270
284
|
* the floating menu to close itself on selection). A branch expanding is
|
|
271
285
|
* not a selection, so it doesn't run this.
|
|
286
|
+
* @param keyHints Print each row's `key` at its right end, as the floating
|
|
287
|
+
* menus do. Off — any kind of nav — a row tells its key in its tooltip
|
|
288
|
+
* instead, keeping the resting rows quiet.
|
|
272
289
|
*/
|
|
273
|
-
export function drawMenu(items: MenuEntry[], onLeafSelect?: () => void): void {
|
|
290
|
+
export function drawMenu(items: MenuEntry[], onLeafSelect?: () => void, keyHints?: boolean): void {
|
|
274
291
|
// Roving focus via the DOM: query the live item elements on each keypress.
|
|
275
292
|
A("keydown=", (e: KeyboardEvent) => {
|
|
276
293
|
// interceptLinks' own Enter handler preventDefault()s the activation, so no
|
|
@@ -296,23 +313,33 @@ export function drawMenu(items: MenuEntry[], onLeafSelect?: () => void): void {
|
|
|
296
313
|
els[next].focus();
|
|
297
314
|
});
|
|
298
315
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
316
|
+
drawEntries(items, {
|
|
317
|
+
onLeafSelect,
|
|
318
|
+
keyHints,
|
|
319
|
+
// Whether the current page is in this menu *at all* — a fact no single
|
|
320
|
+
// branch can tell, and one the fold logic needs (see `drawBranch`).
|
|
321
|
+
// Derived, so branches re-run only when the answer flips.
|
|
322
|
+
$hasCurrent: A.derive(() => anyCurrent(items)),
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/** What one {@link drawMenu} rendering shares with every row it draws. */
|
|
327
|
+
interface MenuCtx {
|
|
328
|
+
onLeafSelect?: () => void;
|
|
329
|
+
keyHints?: boolean;
|
|
330
|
+
$hasCurrent: { value: boolean };
|
|
304
331
|
}
|
|
305
332
|
|
|
306
|
-
function drawEntries(items: MenuEntry[],
|
|
333
|
+
function drawEntries(items: MenuEntry[], ctx: MenuCtx): void {
|
|
307
334
|
for (const entry of items) {
|
|
308
335
|
if (typeof entry === "string" || typeof entry === "function") { drawSlot(entry); continue; }
|
|
309
336
|
if ("separator" in entry) { A("hr.s-menu-sep"); continue; }
|
|
310
|
-
if (entry.items) drawBranch(entry,
|
|
311
|
-
else drawLeaf(entry,
|
|
337
|
+
if (entry.items) drawBranch(entry, ctx);
|
|
338
|
+
else drawLeaf(entry, ctx);
|
|
312
339
|
}
|
|
313
340
|
}
|
|
314
341
|
|
|
315
|
-
function drawLeaf(entry: MenuItem,
|
|
342
|
+
function drawLeaf(entry: MenuItem, ctx: MenuCtx): void {
|
|
316
343
|
// Whether the aria-current scope below has run before: only a *later* run
|
|
317
344
|
// should animate the reveal.
|
|
318
345
|
let drawn = false;
|
|
@@ -339,12 +366,12 @@ function drawLeaf(entry: MenuItem, onLeafSelect?: () => void): void {
|
|
|
339
366
|
if (entry.key) A("aria-keyshortcuts=", formatKey(entry.key, true));
|
|
340
367
|
A("click=", (e: Event) => {
|
|
341
368
|
if (entry.disabled) { e.preventDefault(); return; }
|
|
342
|
-
onLeafSelect?.();
|
|
369
|
+
ctx.onLeafSelect?.();
|
|
343
370
|
entry.click?.(e);
|
|
344
371
|
});
|
|
345
372
|
if (entry.icon) A("span.s-menu-icon", () => drawSlot(entry.icon));
|
|
346
373
|
drawSlot(entry.label);
|
|
347
|
-
|
|
374
|
+
drawHints(entry, ctx);
|
|
348
375
|
});
|
|
349
376
|
}
|
|
350
377
|
|
|
@@ -371,7 +398,7 @@ function setFold(href: string, open: boolean): boolean {
|
|
|
371
398
|
* exactly while it holds the current page. Only a branch with no link anywhere below
|
|
372
399
|
* it keeps the native toggle.
|
|
373
400
|
*/
|
|
374
|
-
function drawBranch(entry: MenuItem,
|
|
401
|
+
function drawBranch(entry: MenuItem, ctx: MenuCtx): void {
|
|
375
402
|
const href = entry.href ?? firstLeafHref(entry.items!);
|
|
376
403
|
// Derived, so the attribute scope below re-runs only when the fold answer flips.
|
|
377
404
|
// When the current page is nowhere in the menu, nothing has an opinion and the fold
|
|
@@ -380,7 +407,7 @@ function drawBranch(entry: MenuItem, onLeafSelect?: () => void, $menuHasCurrent?
|
|
|
380
407
|
const $open = href != null
|
|
381
408
|
? A.derive(() => {
|
|
382
409
|
if (containsCurrent(entry)) return setFold(href, true);
|
|
383
|
-
if (
|
|
410
|
+
if (ctx.$hasCurrent.value) return setFold(href, false);
|
|
384
411
|
return foldMemory.get(href) ?? false;
|
|
385
412
|
})
|
|
386
413
|
: null;
|
|
@@ -411,11 +438,11 @@ function drawBranch(entry: MenuItem, onLeafSelect?: () => void, $menuHasCurrent?
|
|
|
411
438
|
});
|
|
412
439
|
if (entry.icon) A("span.s-menu-icon", () => drawSlot(entry.icon));
|
|
413
440
|
drawSlot(entry.label);
|
|
414
|
-
|
|
441
|
+
drawHints(entry, ctx);
|
|
415
442
|
A("span.s-menu-chevron aria-hidden=true", () => chevronRight());
|
|
416
443
|
});
|
|
417
444
|
|
|
418
|
-
A("div.s-menu-sub", () => drawEntries(entry.items!,
|
|
445
|
+
A("div.s-menu-sub", () => drawEntries(entry.items!, ctx));
|
|
419
446
|
});
|
|
420
447
|
}
|
|
421
448
|
|
|
@@ -482,11 +509,28 @@ function firstLeafHref(items: MenuEntry[]): string | undefined {
|
|
|
482
509
|
|
|
483
510
|
// ─── Keyboard shortcuts ──────────────────────────────────────────────────────
|
|
484
511
|
|
|
485
|
-
/**
|
|
486
|
-
|
|
512
|
+
/**
|
|
513
|
+
* A row's shortcut hint and tooltip. In a floating menu the shortcut sits at
|
|
514
|
+
* the right end of the row; a nav row keeps its label clean and tells it in
|
|
515
|
+
* its tooltip instead — under the item's own `tooltip` content, when it has
|
|
516
|
+
* one, behind a subtle hairline. See {@link MenuItem.key}.
|
|
517
|
+
*/
|
|
518
|
+
function drawHints(entry: MenuItem, ctx: MenuCtx): void {
|
|
519
|
+
const tipKey = ctx.keyHints ? undefined : entry.key;
|
|
487
520
|
// `aria-hidden`: the row already carries the shortcut as `aria-keyshortcuts`,
|
|
488
|
-
// which is what a screen reader reads out —
|
|
489
|
-
if (entry.key) A("kbd.s-menu-key aria-hidden=true text=", formatKey(entry.key));
|
|
521
|
+
// which is what a screen reader reads out — the hint is the sighted half.
|
|
522
|
+
if (entry.key && !tipKey) A("kbd.s-menu-key aria-hidden=true text=", formatKey(entry.key));
|
|
523
|
+
if (entry.tooltip == null && !tipKey) return;
|
|
524
|
+
addTooltip({
|
|
525
|
+
placement: "right",
|
|
526
|
+
tip: () => {
|
|
527
|
+
drawSlot(entry.tooltip);
|
|
528
|
+
if (tipKey) {
|
|
529
|
+
if (entry.tooltip != null) A("hr.s-menu-sep");
|
|
530
|
+
A("kbd.s-menu-tt-key aria-hidden=true text=", formatKey(tipKey));
|
|
531
|
+
}
|
|
532
|
+
},
|
|
533
|
+
});
|
|
490
534
|
}
|
|
491
535
|
|
|
492
536
|
/**
|
|
@@ -649,7 +693,7 @@ mountPortal(() => {
|
|
|
649
693
|
const menuEl = A("div.s-menu-list.s-s.neutral.shadow create=hidden destroy=hidden", f.dropdownAttrs, () => {
|
|
650
694
|
// One drawMenu call, not one per section: it owns the container's roving
|
|
651
695
|
// keyboard focus, and two of them would move it twice per keypress.
|
|
652
|
-
drawMenu(f.link != null ? [...linkItems(f.link), { separator: true }, ...f.items] : f.items, closeFloating);
|
|
696
|
+
drawMenu(f.link != null ? [...linkItems(f.link), { separator: true }, ...f.items] : f.items, closeFloating, true);
|
|
653
697
|
}) as HTMLElement;
|
|
654
698
|
|
|
655
699
|
// Capture-phase document handlers replace an invisible backdrop element:
|
package/src/components/panels.ts
CHANGED
|
@@ -179,9 +179,9 @@ export interface Panel<P = Record<string, string | number | string[]>> {
|
|
|
179
179
|
* The widest this panel can usefully be — a ceiling the shell never
|
|
180
180
|
* exceeds, so the draw function never has to look right past it. It is
|
|
181
181
|
* counted in the shell's *columns*: the content area divides into the
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
182
|
+
* fewest whole number of columns of at most 540px each (two columns of 540
|
|
183
|
+
* in a 1080px area, three of ~507 in 1520px), and a column is never
|
|
184
|
+
* narrower than 360 — where the area holds just one, a small centres in it
|
|
185
185
|
* rather than stretching. So an ask never exceeds its column count × 540:
|
|
186
186
|
*
|
|
187
187
|
* - `"small"` — one column, never above 540px: lists, detail forms.
|
|
@@ -421,10 +421,9 @@ const PAGE_MS = 250;
|
|
|
421
421
|
/** How long a freshly pushed `loading` panel holds its enter animation. */
|
|
422
422
|
const LOADING_HOLD_MS = 300;
|
|
423
423
|
/**
|
|
424
|
-
* The bounds of a column: at
|
|
425
|
-
*
|
|
426
|
-
*
|
|
427
|
-
* area to it as well makes every ask's ceiling uniformly column count × 540.
|
|
424
|
+
* The bounds of a column: at most 540px — the width columns aim for, the area
|
|
425
|
+
* dividing into the fewest of them that stay within it — and at least 360px,
|
|
426
|
+
* about the narrowest phone in common use, so where a panel's layout is aimed.
|
|
428
427
|
*/
|
|
429
428
|
const SMALL_MIN_PX = 360;
|
|
430
429
|
export const SMALL_MAX_PX = 540;
|
|
@@ -1696,10 +1695,13 @@ export class PanelStackController implements PanelStack {
|
|
|
1696
1695
|
* up here that could drift from the bars above and below. Widths stay
|
|
1697
1696
|
* fractional: a rounded column edge would drift a pixel away from that chrome.
|
|
1698
1697
|
*
|
|
1699
|
-
* The area divides into the
|
|
1700
|
-
* {@link
|
|
1701
|
-
*
|
|
1702
|
-
*
|
|
1698
|
+
* The area divides into the fewest whole number of columns of at most
|
|
1699
|
+
* {@link SMALL_MAX_PX} — so 1080px is two of 540, 1520px three of ~507 —
|
|
1700
|
+
* keeping columns as wide as the cap allows rather than as narrow as
|
|
1701
|
+
* {@link SMALL_MIN_PX} permits. Only below 720px can that division dip under
|
|
1702
|
+
* the minimum; there a single column, capped at 540, centres in the area
|
|
1703
|
+
* instead. A width is therefore a pure function of the window: a panel NEVER
|
|
1704
|
+
* resizes because a neighbour came or went.
|
|
1703
1705
|
*
|
|
1704
1706
|
* `undefined` while the shell has no width yet (not in a document, or
|
|
1705
1707
|
* `display:none`); the next pass tries again.
|
|
@@ -1708,7 +1710,8 @@ export class PanelStackController implements PanelStack {
|
|
|
1708
1710
|
const el = this.containerEl;
|
|
1709
1711
|
const area = el ? el.getBoundingClientRect().width : 0;
|
|
1710
1712
|
if (!area) return undefined;
|
|
1711
|
-
const
|
|
1713
|
+
const cols = Math.ceil(area / SMALL_MAX_PX);
|
|
1714
|
+
const small = area / cols >= SMALL_MIN_PX ? area / cols : Math.min(area, SMALL_MAX_PX);
|
|
1712
1715
|
const units = (n: number) => Math.min(n * small, area);
|
|
1713
1716
|
return { area, size: { small, medium: units(2), large: units(3), none: area } };
|
|
1714
1717
|
}
|
|
@@ -133,10 +133,16 @@ export function addTooltip(opts: TooltipOptions): void {
|
|
|
133
133
|
|
|
134
134
|
A("mouseenter=", show);
|
|
135
135
|
A("mouseleave=", scheduleHide);
|
|
136
|
-
|
|
136
|
+
// Keyboard focus only: programmatic focus (a nav opening on its current row,
|
|
137
|
+
// say) would pop a tip over the very thing it describes.
|
|
138
|
+
A("focusin=", (e: Event) => {
|
|
139
|
+
if ((e.target as Element).matches?.(":focus-visible")) show(e);
|
|
140
|
+
});
|
|
137
141
|
A("focusout=", scheduleHide);
|
|
138
142
|
|
|
139
143
|
A.clean(() => {
|
|
140
|
-
|
|
144
|
+
// Compare raw: the proxy's getter wraps stored objects, so `$ttActive.value.opts`
|
|
145
|
+
// would be a Proxy that never equals our raw `opts`.
|
|
146
|
+
if (A.unproxy($ttActive).value?.opts === opts) $ttActive.value = undefined;
|
|
141
147
|
});
|
|
142
148
|
}
|