staffa 0.18.2 → 0.18.3

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.
@@ -31,6 +31,10 @@ export interface AutocompleteOptions extends FieldOptions {
31
31
  * optional free-text entry, and full keyboard control (arrows, enter, escape,
32
32
  * backspace-to-remove). Implements the ARIA combobox/listbox pattern.
33
33
  *
34
+ * The suggestion list is portalled to `document.body`, so a dialog or a
35
+ * scrolling column can neither clip it nor grow a scrollbar around it. It hangs
36
+ * off whichever side of the field has the room, and follows it as things move.
37
+ *
34
38
  * @example
35
39
  * ```ts
36
40
  * // Single select from a fixed list
@@ -1,9 +1,8 @@
1
1
  import A from "aberdeen";
2
- import { uniqueId } from "../core.js";
2
+ import { followAnchor, mountPortal, uniqueId } from "../core.js";
3
3
  import { drawField } from "./field.js";
4
4
  A.insertGlobalCss({
5
5
  ".s-ac": {
6
- "&": "position:relative",
7
6
  // Same light inset field as `.s-input` (see field.ts), derived from the surface.
8
7
  "> .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;",
9
8
  "> .s-control:hover": "border-color: color-mix(in oklab, $s-text, $s-bg 55%);",
@@ -13,16 +12,56 @@ A.insertGlobalCss({
13
12
  ".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",
14
13
  ".s-chip > button:hover": "fg:$s-text background:$s-faint",
15
14
  "input": "flex:1 min-width:6ch border:0 background:transparent color:inherit outline:none padding:0.25em",
16
- // Background, border, radius and elevation come from the popup's
17
- // `.s-s.neutral.shadow` surface (see below).
18
- "> .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",
19
- "> .s-menu li": "margin:0",
15
+ },
16
+ // Background, border, radius and elevation come from the `.s-s.neutral.shadow`
17
+ // surface it carries; `place()` below sizes and positions it. Both of its
18
+ // classes are named here: standing in `<body>` rather than inside the field,
19
+ // it would otherwise lose to theme.ts's flow margins on `ul` and `li`.
20
+ ".s-ac-menu.s-s": {
21
+ "&": "position:fixed max-height:15rem overflow-y:auto list-style:none p:$1 margin:0",
22
+ li: "margin:0",
20
23
  ".s-option": "padding: 0.45em 0.6em; r:6px cursor:pointer transition: background 0.1s;",
21
24
  ".s-option[aria-selected=true]": "background: color-mix(in srgb, $s-text 10%, transparent);",
22
25
  ".s-add": "fg:$s-accent font-style:italic",
23
26
  ".s-empty": "padding: 0.45em 0.6em; fg:$s-muted",
24
27
  },
25
28
  });
29
+ // Only one list is up at a time — it belongs to whichever field has focus — so
30
+ // one portal at the end of <body> serves them all. Drawn inside the field, the
31
+ // list would be clipped by a dialog or a scrolling column, and would stretch
32
+ // that scroller's bar to reach it.
33
+ const $popup = A.proxy({ cur: null });
34
+ /** Hang the list under the field — or over it, when that's where the room is. */
35
+ function place(el, r) {
36
+ const gap = 4, edge = 8;
37
+ // Measured at the stylesheet's own cap, so the flip is decided on the height
38
+ // the list wants, not on whatever the last placement clamped it to.
39
+ el.style.maxHeight = "";
40
+ const want = el.offsetHeight;
41
+ const below = window.innerHeight - r.bottom - gap - edge;
42
+ const above = r.top - gap - edge;
43
+ const up = want > below && above > below;
44
+ el.style.left = `${r.left}px`;
45
+ el.style.width = `${r.width}px`;
46
+ el.style.maxHeight = `${Math.min(want, Math.max(up ? above : below, 60))}px`;
47
+ el.style.top = up ? "auto" : `${r.bottom + gap}px`;
48
+ el.style.bottom = up ? `${window.innerHeight - r.top + gap}px` : "auto";
49
+ }
50
+ mountPortal(() => {
51
+ const p = $popup.cur;
52
+ if (!p)
53
+ return;
54
+ let sizeChanged;
55
+ const el = A("ul.s-ac-menu.s-s.neutral.shadow role=listbox", `id=${p.id} z-index:${p.zIndex}`, () => {
56
+ // A press in the list must not blur the field: the click that follows is
57
+ // what commits, and dragging the scrollbar has to keep it open too.
58
+ A("mousedown=", (e) => e.preventDefault());
59
+ p.draw();
60
+ // Re-run as you type, with the rows; the list's height changes with them.
61
+ sizeChanged?.();
62
+ });
63
+ sizeChanged = followAnchor(p.anchor, (r) => place(el, r));
64
+ });
26
65
  function normOption(o) {
27
66
  return typeof o === "string" ? { value: o, label: o } : { value: o.value, label: o.label ?? o.value };
28
67
  }
@@ -31,6 +70,10 @@ function normOption(o) {
31
70
  * optional free-text entry, and full keyboard control (arrows, enter, escape,
32
71
  * backspace-to-remove). Implements the ARIA combobox/listbox pattern.
33
72
  *
73
+ * The suggestion list is portalled to `document.body`, so a dialog or a
74
+ * scrolling column can neither clip it nor grow a scrollbar around it. It hangs
75
+ * off whichever side of the field has the room, and follows it as things move.
76
+ *
34
77
  * @example
35
78
  * ```ts
36
79
  * // Single select from a fixed list
@@ -103,11 +146,36 @@ export function autocomplete(opts) {
103
146
  const arr = opts.bind.value ?? [];
104
147
  opts.bind.value = arr.filter((v) => v !== value);
105
148
  };
149
+ let inputEl;
150
+ /** The list's rows. Runs in the body portal, on this field's state. */
151
+ const drawList = () => {
152
+ const list = filtered();
153
+ const q = $st.query.trim();
154
+ const showAdd = opts.allowCustom !== false && q !== "" && !list.some((o) => o.label.toLowerCase() === q.toLowerCase());
155
+ list.forEach((option, i) => {
156
+ A("li.s-option role=option", `id=${menuId}-opt-${i}`, () => {
157
+ A(() => A("aria-selected=", $st.active === i ? "true" : "false"));
158
+ A("#", option.label);
159
+ A("click=", () => commit(option.value, inputEl));
160
+ A("mousemove=", () => {
161
+ $st.active = i;
162
+ });
163
+ });
164
+ });
165
+ if (showAdd) {
166
+ A("li.s-option.s-add role=option", () => {
167
+ A("#", `Add "${q}"`);
168
+ A("click=", () => commit(q, inputEl));
169
+ });
170
+ }
171
+ if (list.length === 0 && !showAdd) {
172
+ A("li.s-empty #No matches");
173
+ }
174
+ };
106
175
  drawField(opts, (id, isInvalid) => {
107
176
  A("div.s-ac", opts.inputAttrs, () => {
108
177
  A(() => A("aria-invalid=", isInvalid() ? "true" : "false"));
109
- let inputEl;
110
- A("div.s-control", () => {
178
+ const controlEl = A("div.s-control", () => {
111
179
  A("click=", () => inputEl?.focus());
112
180
  // Chips for multi-select.
113
181
  A(() => {
@@ -156,36 +224,16 @@ export function autocomplete(opts) {
156
224
  A("keydown=", (e) => onKey(e, inputEl));
157
225
  });
158
226
  });
159
- // The suggestions popup.
227
+ // Hand the list to the portal for as long as it is up. Its layer clears
228
+ // the dialog the field sits in, but stays under one that may open over
229
+ // it — a field on the page can't paint across a modal.
160
230
  A(() => {
161
231
  if (!$st.open)
162
232
  return;
163
- const list = filtered();
164
- const q = $st.query.trim();
165
- const showAdd = opts.allowCustom !== false && q !== "" && !list.some((o) => o.label.toLowerCase() === q.toLowerCase());
166
- A("ul.s-menu.s-s.neutral.shadow role=listbox", `id=${menuId}`, () => {
167
- list.forEach((option, i) => {
168
- A("li.s-option role=option", `id=${menuId}-opt-${i}`, () => {
169
- A(() => A("aria-selected=", $st.active === i ? "true" : "false"));
170
- A("#", option.label);
171
- A("mousedown=", (e) => e.preventDefault());
172
- A("click=", () => commit(option.value, inputEl));
173
- A("mousemove=", () => {
174
- $st.active = i;
175
- });
176
- });
177
- });
178
- if (showAdd) {
179
- A("li.s-option.s-add role=option", () => {
180
- A("#", `Add "${q}"`);
181
- A("mousedown=", (e) => e.preventDefault());
182
- A("click=", () => commit(q, inputEl));
183
- });
184
- }
185
- if (list.length === 0 && !showAdd) {
186
- A("li.s-empty #No matches");
187
- }
188
- });
233
+ const zIndex = controlEl.closest(".s-dialog") ? 350 : 150;
234
+ $popup.cur = { id: menuId, anchor: controlEl, zIndex, draw: drawList };
235
+ A.clean(() => { if ($popup.cur?.id === menuId)
236
+ $popup.cur = null; });
189
237
  });
190
238
  // Hidden inputs so the selection participates in native FormData.
191
239
  A(() => {
@@ -1,6 +1,6 @@
1
1
  import A from "aberdeen";
2
2
  import { matchCurrent, current as currentRoute, go } from "aberdeen/route";
3
- import { drawSlot, mountPortal, focusFirst } from "../core.js";
3
+ import { drawSlot, followAnchor, 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";
@@ -551,17 +551,14 @@ mountPortal(() => {
551
551
  document.removeEventListener("click", onClick, true);
552
552
  document.removeEventListener("keydown", onKey, true);
553
553
  });
554
- // Position after layout, then focus the first enabled item.
554
+ // At the supplied point when given — the pointer location for a context menu
555
+ // — otherwise below the anchor.
556
+ followAnchor(f.at ? new DOMRect(f.at.x, f.at.y, 0, 0) : f.anchor, (rect) => positionMenu(menuEl, rect));
557
+ // Once it can take focus: the current-page item if there is one, else the
558
+ // first focusable element (covers custom slot content, not just `.s-menu-item`s).
555
559
  requestAnimationFrame(() => {
556
- if (!document.body.contains(menuEl))
557
- return;
558
- // Position at the supplied point (a zero-size rect) when given — e.g. the
559
- // pointer location for a context menu — otherwise below the anchor.
560
- const rect = f.at ? { left: f.at.x, right: f.at.x, top: f.at.y, bottom: f.at.y } : f.anchor.getBoundingClientRect();
561
- positionMenu(menuEl, rect);
562
- // Focus the current-page item if there is one, else the first focusable
563
- // element (covers custom slot content, not just `.s-menu-item`s).
564
- focusFirst(menuEl, ".s-menu-item[aria-current=page]");
560
+ if (document.body.contains(menuEl))
561
+ focusFirst(menuEl, ".s-menu-item[aria-current=page]");
565
562
  });
566
563
  });
567
564
  // ─── Public API ──────────────────────────────────────────────────────────────
@@ -1,5 +1,5 @@
1
1
  import A from "aberdeen";
2
- import { drawSlot, mountPortal } from "../core.js";
2
+ import { drawSlot, followAnchor, mountPortal } from "../core.js";
3
3
  // Background, ink, border, radius and elevation come from the `.s-s.neutral.shadow`
4
4
  // surface; portalled to <body>, it renders at the page's next neutral shade.
5
5
  A.insertGlobalCss({
@@ -14,10 +14,6 @@ A.insertGlobalCss({
14
14
  // At most one tooltip at a time; the anchor is the element whose rect positions it.
15
15
  const $ttActive = A.proxy(undefined);
16
16
  let hideTimer = null;
17
- // Hide tooltip when the page scrolls (anchor has moved).
18
- if (typeof window !== "undefined") {
19
- window.addEventListener("scroll", () => { $ttActive.value = undefined; }, { capture: true, passive: true });
20
- }
21
17
  function computePos(rect, tipW, tipH, placement) {
22
18
  const gap = 7;
23
19
  const vw = window.innerWidth;
@@ -72,7 +68,7 @@ mountPortal(() => {
72
68
  return;
73
69
  const { opts, anchor } = active;
74
70
  const placement = opts.placement ?? "top";
75
- const tipEl = A("div.s-tt-tip.s-s.neutral.shadow role=tooltip visibility:hidden", opts.attrs, () => {
71
+ const tipEl = A("div.s-tt-tip.s-s.neutral.shadow role=tooltip", opts.attrs, () => {
76
72
  A("mouseenter=", () => {
77
73
  if (hideTimer) {
78
74
  clearTimeout(hideTimer);
@@ -82,14 +78,16 @@ mountPortal(() => {
82
78
  A("mouseleave=", scheduleHide);
83
79
  drawSlot(opts.tip);
84
80
  });
85
- requestAnimationFrame(() => {
86
- if (!document.body.contains(tipEl))
81
+ followAnchor(anchor, (rect) => {
82
+ // Out of the viewport, or on a panel that slid off and went inert: nothing
83
+ // left to explain, and no `mouseleave` is coming to say so.
84
+ if (rect.bottom < 0 || rect.top > window.innerHeight || rect.right < 0 || rect.left > window.innerWidth || anchor.closest("[inert]")) {
85
+ $ttActive.value = undefined;
87
86
  return;
88
- const rect = anchor.getBoundingClientRect();
87
+ }
89
88
  const { x, y } = computePos(rect, tipEl.offsetWidth, tipEl.offsetHeight, placement);
90
89
  tipEl.style.left = x + "px";
91
90
  tipEl.style.top = y + "px";
92
- tipEl.style.visibility = "";
93
91
  });
94
92
  });
95
93
  // ─── Public component ────────────────────────────────────────────────────────
package/dist/core.d.ts CHANGED
@@ -81,3 +81,16 @@ export declare function focusFirst(container: HTMLElement, prefer?: string): boo
81
81
  * `<body>` gets its content first and the overlays stay at the end.
82
82
  */
83
83
  export declare function mountPortal(draw: () => void): void;
84
+ /**
85
+ * Keep a `position:fixed` overlay glued to its anchor. `place` gets the anchor's
86
+ * viewport rect right away, and again whenever it changes: frame by frame while
87
+ * the anchor is on the move — riding a dialog's opening animation or a panel's
88
+ * slide, or scrolling — and not at all once it has been at rest for half a
89
+ * second, until one of the events that precede any movement wakes the loop. So
90
+ * an overlay left standing open doesn't keep the page awake. Stops with the
91
+ * current scope; a point (a `DOMRect` of no size) is followed like an element.
92
+ *
93
+ * Returns a function to call when the overlay's own size changed (its rows
94
+ * redrawn, say), so it gets placed again.
95
+ */
96
+ export declare function followAnchor(anchor: Element | DOMRect, place: (rect: DOMRect) => void): () => void;
package/dist/core.js CHANGED
@@ -57,3 +57,41 @@ export function focusFirst(container, prefer) {
57
57
  export function mountPortal(draw) {
58
58
  queueMicrotask(() => A(draw));
59
59
  }
60
+ /** Something scrolled, the window resized, or an animation began: an anchor may be on the move. */
61
+ const WAKE_EVENTS = ["scroll", "resize", "transitionstart", "animationstart"];
62
+ /**
63
+ * Keep a `position:fixed` overlay glued to its anchor. `place` gets the anchor's
64
+ * viewport rect right away, and again whenever it changes: frame by frame while
65
+ * the anchor is on the move — riding a dialog's opening animation or a panel's
66
+ * slide, or scrolling — and not at all once it has been at rest for half a
67
+ * second, until one of the events that precede any movement wakes the loop. So
68
+ * an overlay left standing open doesn't keep the page awake. Stops with the
69
+ * current scope; a point (a `DOMRect` of no size) is followed like an element.
70
+ *
71
+ * Returns a function to call when the overlay's own size changed (its rows
72
+ * redrawn, say), so it gets placed again.
73
+ */
74
+ export function followAnchor(anchor, place) {
75
+ let placedAt = "", raf = 0, still = 0;
76
+ const track = () => {
77
+ const r = anchor instanceof Element ? anchor.getBoundingClientRect() : anchor;
78
+ const at = `${r.left} ${r.top} ${r.bottom} ${r.width}`;
79
+ if (at !== placedAt) {
80
+ placedAt = at;
81
+ place(r);
82
+ still = 0;
83
+ }
84
+ raf = ++still > 30 ? 0 : requestAnimationFrame(track);
85
+ };
86
+ const wake = () => { still = 0; if (!raf)
87
+ track(); };
88
+ for (const ev of WAKE_EVENTS)
89
+ window.addEventListener(ev, wake, true);
90
+ A.clean(() => {
91
+ cancelAnimationFrame(raf);
92
+ for (const ev of WAKE_EVENTS)
93
+ window.removeEventListener(ev, wake, true);
94
+ });
95
+ track();
96
+ return () => { placedAt = ""; wake(); };
97
+ }
@@ -1 +1 @@
1
- import B from"aberdeen";var J1=t=>`background: $s-bg linear-gradient(${t}, color-mix(in oklab, $s-bg, white 9%), color-mix(in oklab, $s-bg, black 9%));`,$1=J1("170deg"),O1=J1("180deg"),P1="staffa:darkMode",Y1=B.proxy({value:q2()});function q2(){try{let t=localStorage.getItem(P1);if(t==="dark")return!0;if(t==="light")return!1}catch{}}function R2(t){Y1.value=t;try{t===void 0?localStorage.removeItem(P1):localStorage.setItem(P1,t?"dark":"light")}catch{}}function t2(t=!1){let a=Y1.value;return a===void 0&&!t?B.darkMode():a}B(()=>{t2()?B.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"}):B.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"})});B.setSpacingCssVars(1.1);B.insertGlobalCss({"*, *::before, *::after":"box-sizing:border-box",html:"text-size-adjust:100%",body:"m:0 p:$3 min-height:100dvh line-height:1.5 font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; -webkit-font-smoothing:antialiased text:$s-text "+$1,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":$1+" 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 "+$1+" border-color: transparent;"});B.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")))}B.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 D2="p, ul, ol, dl, blockquote, pre, table, figure, hr, h1, h2, h3, h4, h5, h6";B.insertGlobalCss({[`${D2}`]:{"&":"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 E1 from"aberdeen";var u1=typeof navigator<"u"&&/mac|iphone|ipad|ipod/i.test(navigator.platform||navigator.userAgent),Z2={esc:"escape",space:" "},B2={" ":"Space",escape:"Esc",arrowup:"\u2191",arrowdown:"\u2193",arrowleft:"\u2190",arrowright:"\u2192"},y1=new WeakMap,T=[];function e2(){let t=E1();if(!t)throw new Error("Staffa: claimKeyboard needs a current element");return T.push(t),()=>{let a=T.indexOf(t);a>=0&&T.splice(a,1)}}function h2(t){let[,a,e,h]=/^(mod\+)?(shift\+)?(.*)$/i.exec(t),p=h.toLowerCase();if(p=Z2[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 F2(t){if(t.altKey||(u1?t.ctrlKey:t.metaKey))return null;let a=t.key.toLowerCase(),e=t.shiftKey&&(a.length>1||t.key.toUpperCase()!==a);return((u1?t.metaKey:t.ctrlKey)?"mod+":"")+(e?"shift+":"")+a}function p2(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 r2(t,a){let e=T[T.length-1];return a.global===!0||!e||e.contains(t)}function I2(t){for(let a=T.length-1;a>=0;a--)if(T[a].contains(t))return T[a]}function o2(){return T[T.length-1]??document.body}function d2(t){let a=T[T.length-1];return a&&!(t&&a.contains(t))?a:t??document.body}var a2=!1;function U2(t){if(t.defaultPrevented||t.repeat||t.isComposing)return;let a=F2(t),e=t.target instanceof Element?t.target:null;if(!(a==null||p2(a,e)))for(let h=d2(e);h;h=h.parentElement){let p=y1.get(h)?.get(a);if(p&&r2(h,p)){p.press&&(t.preventDefault(),p.press(t));return}}}function n2(t){let a=new Map;for(let e=d2(t);e;e=e.parentElement){let h=y1.get(e);if(h)for(let[p,r]of h)!a.has(p)&&r2(e,r)&&!p2(p,t)&&a.set(p,r)}return[...a]}function $(t,a,e,h="normal"){let p=E1(),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=h2(t),d=y1.get(r);d||y1.set(r,d=new Map);let n={description:a,press:e,global:h==="global",prev:d.get(o)};d.set(o,n),a2||(a2=!0,document.addEventListener("keydown",U2)),E1.clean(()=>{let c=d.get(o);if(c===n)n.prev?d.set(o,n.prev):d.delete(o);else for(;c;c=c.prev)if(c.prev===n){c.prev=n.prev;break}})}function q(t,a=!1){let e=h2(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 c=o===" "?"Space":r||o.length>1?d:o;return(h?u1?"Meta+":"Control+":"")+(r?"Shift+":"")+c}let n=B2[o]??d;return u1?(r?"\u21E7":"")+(h?"\u2318":"")+n:(h?"Ctrl+":"")+(r?"Shift+":"")+n}import Q from"aberdeen";import c2 from"aberdeen";var f1=640,K2=0;function X(t="s"){return`${t}-${++K2}`}function x(t,...a){t!=null&&(typeof t=="function"?t(...a):c2("rich=",t))}var N2="a[href], button, input, select, textarea, [tabindex]";function p1(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(N2)].find(e);return h?.focus(),h!=null}function j(t){queueMicrotask(()=>c2(t))}import w from"aberdeen";import P from"aberdeen";import R from"aberdeen";R.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 r1=R.proxy(void 0),F=null;typeof window<"u"&&window.addEventListener("scroll",()=>{r1.value=void 0},{capture:!0,passive:!0});function W2(t,a,e,h){let r=window.innerWidth,o=window.innerHeight,d=0,n=0;return h==="bottom"?(d=t.left+(t.width-a)/2,n=t.bottom+7,n+e>o-8&&(n=t.top-e-7)):h==="left"?(d=t.left-a-7,n=t.top+(t.height-e)/2,d<8&&(d=t.right+7)):h==="right"?(d=t.right+7,n=t.top+(t.height-e)/2,d+a>r-8&&(d=t.left-a-7)):(d=t.left+(t.width-a)/2,n=t.top-e-7,n<8&&(n=t.bottom+7)),{x:Math.max(8,Math.min(d,r-a-8)),y:Math.max(8,Math.min(n,o-e-8))}}function T1(){F&&clearTimeout(F),F=setTimeout(()=>{r1.value=void 0,F=null},100)}j(()=>{let t=r1.value;if(!t)return;let{opts:a,anchor:e}=t,h=a.placement??"top",p=R("div.s-tt-tip.s-s.neutral.shadow role=tooltip visibility:hidden",a.attrs,()=>{R("mouseenter=",()=>{F&&(clearTimeout(F),F=null)}),R("mouseleave=",T1),x(a.tip)});requestAnimationFrame(()=>{if(!document.body.contains(p))return;let r=e.getBoundingClientRect(),{x:o,y:d}=W2(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=>{F&&(clearTimeout(F),F=null),r1.value={opts:t,anchor:e.currentTarget}};R("mouseenter=",a),R("mouseleave=",T1),R("focusin=",e=>{e.target.matches?.(":focus-visible")&&a(e)}),R("focusout=",T1),R.clean(()=>{R.unproxy(r1).value?.opts===t&&(r1.value=void 0)})}P.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 i1(t){let a=t.href!=null?"a":"button";P(`${a}.s-icon-btn`,t.attrs,()=>{i2(t),P("aria-label=",t.ariaLabel),t.key&&s2(t.key,t.ariaLabel,void 0,t.disabled),x(t.icon)})}function i2(t){t.href!=null?(P("role=button"),t.disabled?P("aria-disabled=true"):P("href=",t.href)):(P("type=",t.type??"button"),t.disabled&&P("disabled=true")),t.click&&!t.disabled&&P("click=",t.click)}function s2(t,a,e,h){let p=P(),r=a?`${a} \xB7 ${q(t)}`:q(t);c1({tip:()=>P("#",r)}),h||(P("aria-keyshortcuts=",q(t,!0)),$(t,typeof e=="string"?e:a,()=>p.click()))}function D(t={}){let a=typeof t=="string"||typeof t=="function"?{content:t}:t,e=a.href!=null?"a":"button";P(`${e}.s-btn.s-s.shadow`,a.attrs,()=>{i2(a),a.ariaLabel&&P("aria-label=",a.ariaLabel),a.key&&s2(a.key,a.ariaLabel,a.content,a.disabled),x(a.icon),x(a.content)})}import l2 from"aberdeen";l2.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 Y(t={}){let e=`.s-${t.layout??"attached"}${t.vertical?".s-vertical":""}`;l2(`div.s-bgroup${e} role=group`,t.attrs,()=>{if(t.buttons)for(let h of t.buttons)D(h);x(t.content)})}import t1 from"aberdeen";import S from"aberdeen";S.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 _(t,a){let e=t.id??X("field"),h=()=>!!t.error;S("div.s-field",t.attrs,()=>{S(()=>{t.label!=null&&S("label for=",e,()=>{x(t.label),t.required&&S("span.s-req aria-hidden=true #*")})}),a(e,h),S(()=>{t.help!=null&&!t.error&&S("div.s-help",()=>x(t.help))}),S(()=>{t.error&&S("div.s-error role=alert #",t.error)})})}function o1(t,a,e,h){S("id=",a),t.name&&S("name=",t.name),S(()=>{t.disabled&&S("disabled=true")}),S(()=>{t.required&&S("aria-required=true")}),S(()=>S("aria-invalid=",e()?"true":"false")),h&&S("bind=",h)}function q1(t={}){_(t,(a,e)=>{t1("input.s-input",t.inputAttrs,()=>{t1("type=",t.type??"text"),t.placeholder!=null&&t1("placeholder=",t.placeholder),t.autocomplete!=null&&t1("autocomplete=",t.autocomplete),t.value!=null&&!t.bind&&t1("value=",t.value),t.input&&t1("input=",t.input),t.change&&t1("change=",t.change),o1(t,a,e,t.bind)})})}w.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 s1=w.proxy({}),G2=0,M2=w.derive(()=>{let t=Object.keys(s1);if(t.length)return t[t.length-1]});function R1(){return M2.value!=null}j(()=>{w.onEach(s1,({resolve:t,opts:a},e)=>{let h=()=>{delete s1[e]};w.clean(()=>{a.onClose?.(),t()});let p=document.activeElement;w.clean(()=>{p instanceof HTMLElement&&document.contains(p)&&p.focus()});let r=w.derive(()=>M2.value!=e);w("div.s-backdrop create=hidden destroy=hidden .hidden=",r,"click=",()=>{a.allowCancel!==!1&&h()});let o=w("div.s-dialog.neutral.s-s.extra-shadow create=hidden destroy=hidden",a.attrs,()=>{a.keyboardTransparent||w.clean(e2());let d=o2();w(()=>{let n=a.allowCancel!==!1;$("esc",n?"Close this dialog":void 0,n?h:()=>{},d)}),w(()=>{a.header!=null&&w("header.s-s.neutral",a.headerAttrs,()=>x(a.header))}),w("div",a.contentAttrs,()=>{x(a.content,h)}),w(()=>{a.footer!=null&&w("footer.s-s.neutral",a.footerAttrs,()=>x(a.footer))})});requestAnimationFrame(()=>{document.body.contains(o)&&p1(o)})})});function d1(t){let a=++G2;return t.cancelWithScope!==!1&&w.clean(()=>{delete s1[a]}),new Promise(e=>{s1[a]={resolve:e,opts:t}})}function X2(t,a={}){return d1({header:"Alert",allowCancel:!0,content:e=>{w("p",()=>{w("#",t)}),Y({layout:"spaced",attrs:"align-self:flex-end",content:()=>{D({content:"OK",click:e})}})},...a})}function j2(t,a={}){return new Promise(e=>{let h=!1;d1({header:"Confirm",allowCancel:!0,content:p=>{w("p",()=>{w("#",t)}),Y({layout:"spaced",attrs:"align-self:flex-end",content:()=>{D({content:"Cancel",attrs:".neutral",click:p}),D({content:"OK",click:()=>{h=!0,p()}})}})},...a,onClose:()=>{e(h),a.onClose?.()}})})}function _2(t,a="",e={}){return new Promise(h=>{let p=null;d1({header:"Input",allowCancel:!0,content:r=>{w("p",()=>{w("#",t)});let o=w.proxy({value:a});w("form display:contents",()=>{w("submit=",d=>{d.preventDefault(),p=o.value,r()}),q1({bind:w.ref(o,"value")}),Y({layout:"spaced",attrs:"align-self:flex-end",content:()=>{D({content:"Cancel",attrs:".neutral",type:"button",click:r}),D({content:"OK",type:"submit"})}})})},...e,onClose:()=>{h(p),e.onClose?.()}})})}Q.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 g1=null;function D1(){if(g1){g1();return}let t=n2(document.activeElement);d1({header:"Keyboard shortcuts",cancelWithScope:!1,keyboardTransparent:!0,onClose:()=>{g1=null},content:a=>{g1=a;let e=h=>{h.repeat||["Control","Shift","Alt","Meta","Escape","?"].includes(h.key)||a()};document.addEventListener("keydown",e,!0),Q.clean(()=>document.removeEventListener("keydown",e,!0)),Q("div.s-keyhelp",()=>{for(let[h,p]of t)p.description!==void 0&&Q("div",()=>{Q("span",()=>x(p.description)),Q("kbd text=",q(h))})})}})}var x2=Q.proxy(!0);function Q2(t){x2.value=t}Q(()=>{x2.value&&($("?",void 0,D1,"global"),$("mod+?","This overview",D1,"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 J2(t){return typeof t=="string"?{value:t,label:t}:{value:t.value,label:t.label??t.value}}function Y2(t){let a=X("ac-menu"),e=M.proxy({query:"",open:!1,active:0}),h=()=>(typeof t.options=="function"?t.options():t.options).map(J2),p=()=>{let l=t.bind?.value;return l==null||l===""?[]:Array.isArray(l)?l:[l]},r=l=>h().find(u=>u.value===l)?.label??l;if(!t.multi){let l=t.bind?M.peek(t.bind,"value"):void 0;typeof l=="string"&&l&&(e.query=M.peek(()=>r(l)))}let o=()=>{let l=new Set(p()),u=h();t.multi&&(u=u.filter(H=>!l.has(H.value)));let b=e.query.trim().toLowerCase();return b&&(u=u.filter(H=>H.label.toLowerCase().includes(b))),u},d=(l,u)=>{if(t.multi){let b=Array.isArray(t.bind?.value)?[...t.bind.value]:[];b.includes(l)||b.push(l),t.bind&&(t.bind.value=b),e.query=""}else t.bind&&(t.bind.value=l),e.query=r(l),e.open=!1;e.active=0,u?.focus()},n=l=>{if(!t.bind)return;let u=t.bind.value??[];t.bind.value=u.filter(b=>b!==l)};_(t,(l,u)=>{M("div.s-ac",t.inputAttrs,()=>{M(()=>M("aria-invalid=",u()?"true":"false"));let b;M("div.s-control",()=>{M("click=",()=>b?.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=",k=>{k.stopPropagation(),n(H),b?.focus()})})})}),b=M("input type=text role=combobox autocomplete=off",()=>{M("id=",l,`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 k=o()[e.active];M("aria-activedescendant=",e.open&&k?`${a}-opt-${e.active}`:"")}),M("input=",()=>{e.open=!0,e.active=0}),M("focus=",()=>{e.open=!0}),M("blur=",()=>{setTimeout(()=>m(),150)}),M("keydown=",H=>c(H,b))})}),M(()=>{if(!e.open)return;let H=o(),k=e.query.trim(),G=t.allowCustom!==!1&&k!==""&&!H.some(V=>V.label.toLowerCase()===k.toLowerCase());M("ul.s-menu.s-s.neutral.shadow role=listbox",`id=${a}`,()=>{H.forEach((V,Z)=>{M("li.s-option role=option",`id=${a}-opt-${Z}`,()=>{M(()=>M("aria-selected=",e.active===Z?"true":"false")),M("#",V.label),M("mousedown=",s=>s.preventDefault()),M("click=",()=>d(V.value,b)),M("mousemove=",()=>{e.active=Z})})}),G&&M("li.s-option.s-add role=option",()=>{M("#",`Add "${k}"`),M("mousedown=",V=>V.preventDefault()),M("click=",()=>d(k,b))}),H.length===0&&!G&&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 c(l,u){let b=o(),H=b.length-1;if(l.key==="ArrowDown")l.preventDefault(),e.open=!0,e.active=Math.min(H,e.active+1);else if(l.key==="ArrowUp")l.preventDefault(),e.active=Math.max(0,e.active-1);else if(l.key==="Enter"){l.preventDefault();let k=b[e.active];k?d(k.value,u):t.allowCustom!==!1&&e.query.trim()?d(e.query.trim(),u):e.open&&(e.open=!1)}else if(l.key==="Escape")e.open&&(l.preventDefault(),e.open=!1,t.multi||(e.query=r(p()[0]??"")));else if(l.key==="Backspace"&&t.multi&&e.query===""){let k=p();k.length&&n(k[k.length-1])}}function m(){e.open=!1,t.multi?e.query="":t.allowCustom!==!1&&e.query.trim()?d(e.query.trim()):e.query=r(p()[0]??"")}}import a1 from"aberdeen";import t0 from"aberdeen";var l1={size:24,color:"currentColor",strokeWidth:2,cap:"round",join:"round"};function a0(t,a){let e=a.size??l1.size,h=t0('svg.s-icon aria-hidden=true viewBox="0 0 24 24" fill=none',"width=",e,"height=",e,"stroke=",a.color??l1.color,"stroke-width=",a.strokeWidth??l1.strokeWidth,"stroke-linecap=",a.cap??l1.cap,"stroke-linejoin=",a.join??l1.join,a.attrs);h.innerHTML=t}function O(t){return(a={})=>a0(t,a)}var v2=O('<path d="m9 18 6-6-6-6" />');var m2=O('<circle cx="12" cy="12" r="10" />');var u2=O('<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 y2=O('<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 b1=O('<path d="M4 5h16" /><path d="M4 12h16" /><path d="M4 19h16" />');var f2=O('<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" />'),Z1=O('<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 g2=O('<path d="M22 2 2 22" />');var n1=O('<path d="M18 6 6 18" /><path d="m6 6 12 12" />');a1.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 e0(t={}){let a=typeof t=="string"||typeof t=="function"?{content:t}:t;a1("section.s-box.s-s.neutral.shadow",a.attrs,()=>{a1(()=>{a.header!=null?a1("header.s-s.neutral",a.headerAttrs,()=>{x(a.header),typeof a.close=="function"&&b2(a.close)}):typeof a.close=="function"&&b2(a.close)}),a1("div",a.contentAttrs,()=>{x(a.content)}),a1(()=>{a.footer!=null&&a1("footer.s-s.neutral",a.footerAttrs,()=>x(a.footer))})})}function b2(t){i1({icon:n1,ariaLabel:"Close",click:t,attrs:".s-box-close"})}import B1 from"aberdeen";function h0(t){B1(()=>{let a=t.bind.value;Y({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&&B1(()=>B1("input type=hidden name=",t.name,"value=",t.bind.value??""))}import z from"aberdeen";z.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 p0(t={}){let a=t.id??X("check");z("div.s-check",t.attrs,()=>{z("label for=",a,()=>{z("input type=checkbox",t.inputAttrs,()=>{z("id=",a),t.name&&z("name=",t.name),t.checked&&!t.bind&&z("checked=true"),t.change&&z("change=",t.change),z(()=>{t.disabled&&z("disabled=true")}),z(()=>{t.required&&z("aria-required=true")}),t.bind&&z("bind=",t.bind)}),z(()=>{t.label!=null&&x(t.label),t.required&&z("span.s-req aria-hidden=true #*")})}),z(()=>{t.help!=null&&!t.error&&z("div.s-help",()=>x(t.help))}),z(()=>{t.error&&z("div.s-error role=alert #",t.error)})})}import e1 from"aberdeen";e1.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 r0(t={}){let a=typeof t=="string"||typeof t=="function"?{content:t}:t;e1("form.s-form",a.attrs,()=>{e1(()=>{e1(".grid=",a.layout==="grid")}),e1("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),e1(()=>{a.actions&&e1("footer",a.actionsAttrs,()=>x(a.actions))})})}import v from"aberdeen";import{current as Q1}from"aberdeen/route";import f from"aberdeen";import{matchCurrent as c0,current as H1,go as H2}from"aberdeen/route";import C from"aberdeen";import{grow as o0,shrink as d0}from"aberdeen/transitions";C.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 n0=0,M1=C.proxy({});j(()=>{C.peek(()=>C.isEmpty(M1))&&C.isEmpty(M1)||C("div.s-toasts",()=>{C.onEach(M1,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,n=()=>{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(()=>F1(e),r)},c=()=>{clearTimeout(o),o=void 0,d&&(d.style.transition="none",d.style.width="100%")};C.clean(()=>clearTimeout(o)),C(`div.s-toast.s-s.${p}.extra-shadow aria-live=polite role=${h}`,"create=",o0,"destroy=",d0,a.attrs,()=>{r>0&&(C("mouseenter=",c),C("mouseleave=",n)),C("div.s-toast-body",()=>{C(()=>{a.title!=null&&C("div.s-toast-title",()=>x(a.title))}),C("div.s-toast-msg",()=>x(a.message))}),C(()=>{a.dismissible!==!1&&C("button.s-toast-close type=button aria-label=Dismiss",()=>{C("#\xD7"),C("click=",()=>F1(e))})}),r>0&&(d=C("div.s-toast-progress"))}),r>0&&requestAnimationFrame(n)})})});function F1(t){delete M1[t]}function w1(t){let a=++n0;return M1[a]={id:a,opts:t},()=>F1(a)}f.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 x1(t,a,e){f("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(c=>c.getAttribute("aria-disabled")!=="true"&&!l0(c));if(!r.length)return;let o=r.indexOf(document.activeElement),d=h.key==="ArrowUp"?-1:1,n=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[n].focus()}),A2(t,{onLeafSelect:a,keyHints:e,$hasCurrent:f.derive(()=>I1(t))})}function A2(t,a){for(let e of t){if(typeof e=="string"||typeof e=="function"){x(e);continue}if("separator"in e){f("hr.s-menu-sep");continue}e.items?s0(e,a):i0(e,a)}}function i0(t,a){let e=!1,h=f(t.href?"a.s-menu-item data-panel=open":"button.s-menu-item type=button",t.attrs,()=>{t.href&&(f("href=",t.href),t.target&&f("target=",t.target),f(()=>{let p=!e;e=!0,U1(t)&&(f("aria-current=page"),requestAnimationFrame(()=>h.scrollIntoView({block:"nearest",behavior:p?"instant":"smooth"})))})),t.disabled&&f("aria-disabled=true"),t.key&&f("aria-keyshortcuts=",q(t.key,!0)),f("click=",p=>{if(t.disabled){p.preventDefault();return}a.onLeafSelect?.(),t.click?.(p)}),t.icon&&f("span.s-menu-icon",()=>x(t.icon)),x(t.label),L2(t,a)})}var V2=new Map;function w2(t,a){return V2.set(t,a),a}function s0(t,a){let e=t.href??k2(t.items),h=e!=null?f.derive(()=>K1(t)?w2(e,!0):a.$hasCurrent.value?w2(e,!1):V2.get(e)??!1):null;f("details.s-menu-details",()=>{h&&f(()=>{h.value&&f("open=true")}),f("summary.s-menu-item.s-menu-branch",t.attrs,()=>{t.disabled&&f("aria-disabled=true"),t.key&&f("aria-keyshortcuts=",q(t.key,!0)),f(()=>{U1(t)&&f("aria-current=page")}),f("click=",p=>{if(t.disabled){p.preventDefault();return}e!=null&&(p.preventDefault(),x0(e),H2(e)),t.click?.(p)}),t.icon&&f("span.s-menu-icon",()=>x(t.icon)),x(t.label),L2(t,a),f("span.s-menu-chevron aria-hidden=true",()=>v2())}),f("div.s-menu-sub",()=>A2(t.items,a))})}function l0(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 I1(t){return t.some(a=>typeof a!="string"&&typeof a!="function"&&!("separator"in a)&&K1(a))}function U1(t){if(t.href!=null&&c0(t.href))return!0;let a=t.match;if(a==null)return!1;let e=H1.path;if(typeof a=="function")return a(e);let h=a.replace(/\/+$/,"")||"/";return e===h||e.startsWith(h==="/"?"/":h+"/")}function K1(t){if(U1(t))return!0;for(let a of t.items??[])if(!(typeof a=="string"||typeof a=="function"||"separator"in a)&&K1(a))return!0;return!1}function k2(t){for(let a of t){if(typeof a=="string"||typeof a=="function"||"separator"in a)continue;let e=a.href??(a.items?k2(a.items):void 0);if(e!=null)return e}}function L2(t,a){let e=a.keyHints?void 0:t.key;t.key&&!e&&f("kbd.s-menu-key aria-hidden=true text=",q(t.key)),!(t.tooltip==null&&!e)&&c1({placement:"right",tip:()=>{x(t.tooltip),e&&(t.tooltip!=null&&f("hr.s-menu-sep"),f("kbd.s-menu-tt-key aria-hidden=true text=",q(e)))}})}function v1(t,a){f(()=>{for(let e of C2(t(),[]))$(e.key,e.label,h=>{z2(),a?.(),e.click?.(h),e.href!=null&&M0(e.href,e.target)})})}function C2(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&&C2(e.items,a));return a}function M0(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:H2(t)}var A1=null;function x0(t){try{A1=new URL(t,location.href).pathname.replace(/\/+$/,"")||"/"}catch{A1=null}}function N1(t){return A1!==t?!1:(A1=null,!0)}var J=f.proxy({opts:null});function W(){let t=J.opts?.anchor;J.opts=null,t?.focus()}function V1(t){let a=J.opts;return a!=null&&(t==null||a.anchor===t)}function z2(t){V1(t)&&W()}function v0(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 n=a.bottom+o;n+h>r-8&&a.top-h-o>=8&&(n=a.top-h-o),t.style.left=Math.max(8,d)+"px",t.style.top=Math.max(8,n)+"px"}function m0(t){return[{label:"Open in new tab",icon:u2,click:()=>{window.open(t,"_blank","noopener")}},{label:"Copy link",icon:y2,click:()=>{u0(t)}}]}async function u0(t){let a=new URL(t,location.href).href;try{await navigator.clipboard.writeText(a),w1({message:"Link copied."})}catch{w1({message:"Couldn't copy the link.",type:"danger"})}}j(()=>{let t=J.opts;if(!t)return;let a=f("div.s-menu-list.s-s.neutral.shadow create=hidden destroy=hidden",t.dropdownAttrs,()=>{x1(t.link!=null?[...m0(t.link),{separator:!0},...t.items]:t.items,W,!0)}),e=r=>{let o=r.target;!a.contains(o)&&(t.closeOnAnchorClick||!t.anchor.contains(o))&&W()},h=r=>{(r.key==="Escape"||r.key==="Tab")&&(r.preventDefault(),W())},p=f.peek(H1,"path");f(()=>{H1.path!==p&&!N1(H1.path)&&W()}),document.addEventListener("click",e,!0),document.addEventListener("keydown",h,!0),f.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();v0(a,r),p1(a,".s-menu-item[aria-current=page]")})});function y0(t){f("nav.s-menu-inline",t.attrs,()=>{v1(()=>t.items,()=>t.onLeafSelect?.()),x1(t.items,t.onLeafSelect)})}function W1(t){return J.opts=t,W}function G1(t){v1(()=>t.items);let a=null;f.clean(()=>{J.opts?.anchor===a&&W()}),f("contextmenu=",e=>{e.preventDefault(),a=e.currentTarget,W1({...t,anchor:a,at:{x:e.clientX,y:e.clientY},closeOnAnchorClick:!0})})}function f0(t){v1(()=>t.items);let a=null;f.clean(()=>{J.opts?.anchor===a&&W()}),D({icon:b1,...t.button?.content==null?{ariaLabel:"Open menu"}:null,attrs:".neutral",...t.button,click:e=>{if(a=e.currentTarget,J.opts?.anchor===a){W();return}W1({items:t.items,anchor:a,dropdownAttrs:t.dropdownAttrs})}})}import i,{OPAQUE as $2}from"aberdeen";import*as g from"aberdeen/route";import L from"aberdeen";var g0=O('<path d="m15 18-6-6 6-6"/>'),b0=O('<path d="m9 18 6-6-6-6"/>');L.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 k1(t){L("div.s-strip",t.attrs,()=>{let a=L("div.s-strip-row",t.stripAttrs,()=>x(t.content));S2(a,-1),S2(a,1),H0(a)})}function L1(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 w0(t){let a=X("tabs"),e=(r,o)=>r.id??String(o),h=t.bind??L.proxy(e(t.tabs[0]??{label:""},0));t.tabs.length>0&&!t.tabs.some((r,o)=>e(r,o)===L.peek(()=>h.value))&&(h.value=e(t.tabs[0],0));let p=(r,o)=>{r.disabled||(h.value=e(r,o))};L("div.s-tabs",t.attrs,()=>{k1({attrs:".s-tabbar",stripAttrs:".s-tablist role=tablist",content:()=>{t.tabs.forEach((r,o)=>{let d=e(r,o),n=L("button.s-tab type=button role=tab",()=>{L("id=",`${a}-tab-${d}`,"aria-controls=",`${a}-panel-${d}`),L(()=>{let c=h.value===d;L("aria-selected=",c?"true":"false"),L("tabindex=",c?"0":"-1"),c&&requestAnimationFrame(()=>L1(n))}),r.disabled&&L("disabled=true"),L("click=",()=>p(r,o)),L("keydown=",c=>A0(c,t.tabs,o,p)),x(r.icon),x(r.label)})})}}),L("div.s-tabpanel role=tabpanel",t.contentAttrs,()=>{L(()=>{let r=h.value,o=t.tabs.findIndex((n,c)=>e(n,c)===r),d=t.tabs[o]??t.tabs[0];d&&(L("id=",`${a}-panel-${e(d,o)}`,"aria-labelledby=",`${a}-tab-${e(d,o)}`),x(d.content))})})})}function S2(t,a){L(`button.s-strip-btn.s-strip-btn-${a<0?"left":"right"} type=button`,()=>{L("tabindex=-1 aria-hidden=true"),L("click=",()=>t.scrollBy({left:a*t.clientWidth*.8,behavior:"smooth"})),(a<0?g0:b0)({size:"1.1em"})})}function H0(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(),L.clean(()=>{t.removeEventListener("scroll",e),h.disconnect(),p?.disconnect()})}function A0(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 _1={integer(t){if(!/^(0|-?[1-9]\d*)$/.test(t))return;let a=Number(t);return Number.isSafeInteger(a)?a:void 0}};function I(t){let a=String(t).replace(/\/+$/,"");return a.startsWith("/")||(a=`/${a}`),a}function m1(t){let a=I(t);return a==="/"?[]:a.slice(1).split("/")}function P2(t){let a=m1(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,n]=o;if(n&&!(n in _1))throw new Error(`Staffa: unknown matcher "${n}" in route "${t}" (known: ${Object.keys(_1).join(", ")})`);return{kind:"param",name:d,matcher:n}});return{key:t,segs:e}}function V0(t){try{return decodeURIComponent(t)}catch{return t}}function X1(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=_1[p.matcher](r);if(o===void 0)return null;e[p.name]=o}else e[p.name]=V0(r)}return t.segs.length===a.length?e:null}var U=250,k0=300,L0=360,C1=540;i.insertGlobalCss({":root":`--s-panel-ms:${U}ms`,".s-panels":"flex:1 min-width:0 min-height:0 position:relative overflow:clip isolation:isolate "+O1,".s-panel":{"&":"position:absolute top:0 bottom:0 left:0 display:flex flex-direction:column "+O1+` z-index:2 transition: transform ${U}ms ease-out, opacity ${U}ms linear;`,"&.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-new":"z-index:1","&.s-panel-closing":"z-index:0 opacity:0 pointer-events:none","&.s-panel-enter":"opacity:0","&.s-panel-hidden, &.s-panel-parked":"visibility:hidden"},".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 j1=!1,z1=class{[$2]=!0;compiled;ancestors;opts;$state=i.proxy({live:[],focus:0});$open=i.proxy({});nextOrder=0;containerEl;geom;lastGeom;layoutQueued=!1;timers=new Set;exiting=new Set;intent=null;settling=null;lastSeen=null;queued=null;constructor(a){if(j1)throw new Error("Staffa: only one routed S.main() (one with `routes`) can be active at a time");j1=!0,this.opts=a,this.compiled=Object.entries(a.routes).map(([e,h])=>({...P2(e),draw:h})),this.ancestors=Object.entries(a.ancestors??{}).filter(e=>e[1]!=null).map(([e,h])=>({...P2(e),fn:h})),i(()=>{let e=this.computeTarget(),h={...g.current.search},p=g.current.hash;i.peek(()=>{let r=this.lastSeen;if(r&&r.path!==g.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:g.current.path,search:h,hash:p},this.propose(e),Array.isArray(g.current.state.panels)||Object.assign(g.current.state,this.stateFor({stack:this.paths(),focus:this.$state.focus}))})}),this.interceptLinks(),this.watchTitle(),this.guardTabClose(),i.clean(()=>{for(let e of this.timers)clearTimeout(e);this.timers.clear(),this.queued?.settle(!1),this.queued=null,j1=!1})}resolve(a){let e=m1(a);for(let h of this.compiled){let p=X1(h,e);if(p)return{draw:h.draw,params:p}}return{draw:this.opts.notFound??S0,params:{}}}matches(a){let e=m1(a);return this.compiled.some(h=>X1(h,e)!=null)}deriveStack(a){let e=I(a),h=this.askAncestors(e),p=h?h.map(I):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=m1(a);for(let h of this.ancestors){let p=X1(h,e);if(p)return h.fn(p,a)??void 0}}prefixesOf(a){let e=m1(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=I(a),o=new Set([r]),d=c=>c.map(I).filter(m=>!o.has(m)&&!!o.add(m)),n=d(h);return{stack:[...n,r,...d(p)],focus:n.length}}return i.peek(()=>{let p=this.deriveStack(a).slice(0,-1),r=[...p,...this.pinnedIn(this.paths(),[...p,I(a)]),I(a)];return{stack:r,focus:r.length-1}})}computeTarget(){return this.targetFor(g.current.path,g.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}),!(O2(this.paths(),a.stack)&&a.focus===this.$state.focus)&&this.commit(a,g.current.nav)}commit(a,e){this.geom=void 0;let h=g.current.state.pinned,p=new Set(Array.isArray(h)?h.map(String):[]),r=new Map(this.$state.live.map(n=>[n.path,n])),o=[];for(let n of a.stack){let c=r.get(n);if(c){r.delete(n),o.push(c);continue}let m=this.createEntry(n,o.length<=a.focus,p.has(n));e!=="load"&&(m.enter=!0),o.push(m),this.$open[n]=m}let d;for(let n of this.$state.live)r.has(n.path)?this.beginClose(n,d):d=n.path;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={[$2]:!0,order:this.nextOrder++,path:a,draw:p,$ui:i.proxy({holding:!1}),maxWidth:"medium",width:0};return o.$panel=i.proxy({stack:this,params:r,path:a,width:0,visible:e,pinned:h||void 0,close:()=>this.closePath(o.path),open:(d,n)=>this.navigate(d,{from:o.path,how:n})}),o}beginClose(a,e){a.closing=!0,a.anchor=e,a.$panel.visible=!1,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=a.placed?{el:e,anchor:a.anchor,ride:0}:null;h&&this.exiting.add(h),this.afterTransition(e,"opacity",()=>{h&&this.exiting.delete(h),e.remove()})}afterTransition(a,e,h){let p=!1,r=setTimeout(()=>d(),U+80);this.timers.add(r);let o=()=>{clearTimeout(r),this.timers.delete(r)},d=()=>{o(),p||(p=!0,h())},n=c=>m=>{m.target===a&&m.propertyName===e&&c()};a.addEventListener("transitionrun",n(o)),a.addEventListener("transitionend",n(d)),a.addEventListener("transitioncancel",n(d))}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 g.go({path:p,search:r?.search,hash:r?.hash,state:this.stateFor(h)})})}back(){return i.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 i.peek(()=>{let e=this.intended(),h=e.stack.indexOf(I(a));if(h<0||e.stack.length<2||this.unsavedAt(e.stack[h]))return Promise.resolve(!1);let p=e.stack.filter((c,m)=>m!==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 c=this.$state.live.find(u=>u.path===p[r]),m={};c?.search&&(m.search=c.search),c?.hash&&(m.hash=c.hash);let l=p.filter(u=>this.$state.live.find(b=>b.path===u)?.$panel.pinned===!0);return this.issue(o,()=>Promise.resolve(g.back({path:p[r],state:{panels:p.slice(0,r),parked:[]}},m)).then(u=>(u&&(g.current.state.pinned=l),u)))}let d=p[r],n=d!==e.stack[e.focus];return this.issue(o,()=>{let c=n?this.$state.live.find(m=>m.path===d):void 0;return g.go({path:d,search:n?c?.search:{...g.current.search},hash:n?c?.hash:g.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 i.peek(()=>{let n;try{n=new URL(a,location.href)}catch{return Promise.resolve(!1)}let c=I(n.pathname),m=this.intended(),l=p?-1:m.stack.indexOf(c),u;if(l>=0&&r!=="replace"&&r!=="open"){let V=this.pinnedIn(m.stack.slice(l+1),[]);u={stack:[...m.stack.slice(0,l+1),...V],focus:l}}else{let V=o==null?-1:m.stack.indexOf(o),s=(p?p.map(I):V<0?this.deriveStack(c).slice(0,-1):m.stack.slice(0,d?V:V+1)).filter((A,N,h1)=>A!==c&&h1.indexOf(A)===N),y=[...s,...this.pinnedIn(m.stack,[...s,c,d?o:null])];u={stack:[...y,c],focus:y.length}}let b=l>=0?this.$state.live.find(V=>V.path===c):void 0,H=n.search?Object.fromEntries(new URLSearchParams(n.search)):b?.search??{},k=n.hash||b?.hash||"";if(u.focus===m.focus&&O2(u.stack,m.stack)&&n.search===location.search&&(n.hash||"")===(location.hash||""))return Promise.resolve(!0);let G=this.stateFor(u);return d?this.issue(u,()=>(g.current.path=c,g.current.search=H,g.current.hash=k,g.current.state=G,i.runQueue(),g.current.path===c)):this.issue(u,()=>g.go({path:c,search:H,hash:k,state:G}))})}pushPath(a,e){return i.peek(()=>{let h=this.intended();return this.navigate(a,{from:h.stack[h.focus],how:e?"replace":"push"})})}interceptLinks(){g.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 i.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(){k1({attrs:".s-crumbs role=navigation aria-label=Breadcrumbs",content:()=>{i(()=>{let a=this.panels.map(p=>p.path),e=this.currentPanelIndex,h;for(let p=0;p<a.length;p++){p&&g2({size:"0.85em",attrs:".s-crumb-sep"});let r=this.drawCrumb(a[p],p,p===e);p===e&&(h=r)}requestAnimationFrame(()=>{h&&L1(h)})})}})}drawCrumb(a,e,h){let p=this.$state.live[e];return i(h?"span.s-crumb aria-current=page":"a.s-crumb",()=>{h||i("href=",a),i(()=>{p?.$panel.visible&&i(".s-crumb-on")}),i(()=>{p?.$panel.unsaved&&m2({size:"0.45em",attrs:".s-crumb-unsaved"})}),i(()=>{p?.$panel.pinned&&Z1({size:"0.85em",attrs:".s-crumb-pin"})}),i(()=>{i("#",p?.$panel.title??p?.$ui.fallback??(a.split("/").pop()||a))}),G1({link:a,items:[{label:()=>{i(()=>{i("#",p?.$panel.pinned?"Unpin":"Pin")})},icon:()=>{i(()=>{(p?.$panel.pinned?f2:Z1)()})},click:()=>{p&&this.togglePin(p)}},{label:"Close",icon:n1,disabled:p?.$panel.unsaved===!0,click:()=>{this.closePath(a)}}]})})}togglePin(a){a.$panel.pinned=!a.$panel.pinned||void 0,g.current.state.pinned=this.pinnedPaths()}watchTitle(){let a=document.title;i(()=>{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)}),i.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)))};i(()=>{this.$state.live.some(e=>e.$panel.unsaved)&&(window.addEventListener("beforeunload",a),i.clean(()=>window.removeEventListener("beforeunload",a)))})}drawColumns(){let a=i("div.s-panels role=main",()=>{this.containerEl=i(),i.onEach(this.$open,e=>this.drawPanel(e),e=>e.order)});if(typeof ResizeObserver<"u"){let e=new ResizeObserver(()=>this.layout());e.observe(a),i.clean(()=>e.disconnect())}i.clean(()=>{this.containerEl===a&&(this.containerEl=void 0)}),this.scheduleLayout()}drawPanel(a){let e;i(()=>{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,i.peek(a.$panel,"width")!==p&&(a.$panel.width=p),e&&(e.style.width=`${p}px`,this.scheduleLayout()))}),e=i(`section.s-panel${a.width?` w:${a.width}px`:""}`,"destroy=",h=>this.playExit(a,h),()=>{i(()=>this.drawActions(a)),i("div.s-content",()=>{if(a.draw(a.$panel),g.persistScroll(a.path),i.peek(a.$panel,"title")==null){let h=z0(i());h&&i.peek(a.$ui,"fallback")!==h&&(a.$ui.fallback=h)}}),i(()=>{!a.$panel.loading||a.$ui.holding||i("div.s-panel-loading aria-hidden=true",()=>{i("i"),i("i"),i("i")})})}),a.el=e,a.placed=!1,e.style.transition="none",i.clean(()=>{a.el===e&&(a.el=void 0)}),i(()=>{a.$panel.loading,this.scheduleLayout()}),this.scheduleLayout()}drawActions(a){this.opts.$shell.narrow||a.$panel.actions==null||i("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/C1),p=e/h>=L0?e/h:Math.min(e,C1),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(s=>!s.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 n=s=>r.size[s.maxWidth],c=Math.min(this.$state.focus,p-1),m=c,l=n(h[c]);if(!o)for(let s=c-1;s>=0;s--){let y=l+n(h[s]);if(y>r.area)break;l=y,m=s}let u=m>0?0:(r.area-l)/2;for(let s=m;s<=c;s++)h[s].width=n(h[s]);for(let s of h)s.width||(s.width=n(s));let b=[],H=[],k=new Map,G=new Map;if(!d)for(let s of h)s.placed&&G.set(s,C0(s.el));let V=u,Z=0;for(let s=0;s<m;s++)V-=h[s].width;for(let s=0;s<p;s++){let y=h[s],A=y.el,N=s>=m&&s<=c;s===c+1&&(V=Math.max(V,r.area)),(y.enter||!y.placed)&&(!y.$panel.loading||y.holdDone?y.$ui.holding=!1:y.$ui.holding||(y.$ui.holding=!0,this.holdEnter(y))),y.placed?(Z=parseFloat(A.style.left)-V,k.set(y.path,Z),Z&&!d&&(A.style.transition=`opacity ${U}ms linear`,A.style.transform=`translateX(${(G.get(y)??0)+Z}px)`,H.push(A)),A.style.left=`${V}px`,y.enter&&!y.$ui.holding&&this.releaseEnter(y)):(b.push(y),A.style.left=`${V}px`,y.enter&&N&&(A.style.transform=`translateX(${Z}px)`,A.classList.add("s-panel-enter","s-panel-new"))),A.style.width=`${y.width}px`,V+=y.width,y.$panel.visible!==N&&(y.$panel.visible=N),y.$panel.width!==y.width&&(y.$panel.width=y.width),A.classList.toggle("s-panel-sep",N&&s>m);let h1=s<m,T2=A.classList.contains("s-panel-hidden")||A.classList.contains("s-panel-parked");N?A.classList.remove("s-panel-hidden","s-panel-parked"):T2||!y.placed||d?(A.classList.toggle("s-panel-hidden",h1),A.classList.toggle("s-panel-parked",!h1)):this.afterTransition(A,"transform",()=>{y.el!==A||!y.offstage||(A.classList.toggle("s-panel-hidden",h1),A.classList.toggle("s-panel-parked",!h1))}),y.offstage=!N,A.toggleAttribute("inert",!N)}for(let s of this.exiting){let y=s.anchor==null?void 0:k.get(s.anchor);y&&(s.ride-=y,s.el.style.transform=`translateX(${s.ride}px)`)}(b.length||H.length||d)&&a.offsetWidth,d&&e.classList.remove("s-shell-snap");for(let s of H)s.style.transition="",s.style.transform="";for(let s of b){let y=s.el;y.style.transition="",y.style.transform="",s.placed=!0,s.$ui.holding||this.releaseEnter(s)}}releaseEnter(a){a.enter=!1;let e=a.el;!e||!e.classList.contains("s-panel-enter")||(e.classList.remove("s-panel-enter"),this.afterTransition(e,"opacity",()=>e.classList.remove("s-panel-new")))}holdEnter(a){let e=setTimeout(()=>{this.timers.delete(e),a.holdDone=!0,a.$ui.holding&&(a.$ui.holding=!1,this.scheduleLayout())},k0);this.timers.add(e)}};function O2(t,a){return t.length===a.length&&t.every((e,h)=>e===a[h])}function C0(t){let a=getComputedStyle(t).transform;return a&&a!=="none"?new DOMMatrixReadOnly(a).m41:0}function z0(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 S0(t){i("p fg:$s-muted",()=>i("#",`No panel at ${t.path}`))}var $0=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 1 auto;",".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 ${U}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 ${U}ms ease, visibility 0s;`,"&.s-nav-page-off":`transform:translateX(-100%) pointer-events:none visibility:hidden transition: transform ${U}ms ease, visibility 0s ${U}ms;`,".s-menu-item":"padding: $2 $3; min-height:3rem font-size:1.05em gap:$3"},[`@container (max-width: ${f1}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: ${C1}px)`]:{".s-content > .s-box":"margin-inline: calc(-1 * $3); r:0 border-inline:0"}});function P0(t={}){let a=t.nav,e=t.navPosition??"left",h=v.proxy({open:!1}),p=v.proxy({narrow:typeof document<"u"&&document.documentElement.clientWidth<=f1}),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 z1({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,n=()=>{t.maxWidth!=null&&v("max-width:",t.maxWidth)},c=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??$0}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(n),v(()=>{if(p.narrow&&a!=null&&a.items.length){v("div.s-nav-trigger",()=>R0(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)})}),E0(t,o,a,p)}),v(()=>{let l=p.narrow?o?.currentPanel?.actions:void 0,u=l??t.menu;u!=null&&v(`div.s-menu${l!=null?".s-panel-origin":""}`,()=>x(u))})})})}),v("div.s-body",()=>{v("div.s-body-inner",()=>{v(n),v(()=>{a==null||!a.items.length||(v(`nav.s-nav-panel.s-nav-${e}`,t.navAttrs,()=>{x1(a.items)}),v("div.s-nav-sep aria-hidden=true"))}),B0(t,o)}),v(()=>{a!=null&&a.items.length&&h.open&&D0(a,t.navPageAttrs,h,p)})}),v(()=>{t.footer!=null&&v("footer",()=>{v("div.s-bar",()=>{v(n),x(t.footer)})})})});return q0(c,p),a!=null&&v1(()=>a.items,()=>{h.open=!1}),(a!=null||o)&&v(()=>{let m=u=>()=>{R1()||V1()||u()},l=()=>c.querySelector(".s-nav-trigger button");h.open?$("Esc","Close the navigation",m(()=>{h.open=!1,l()?.focus()}),"global"):o&&o.currentPanelIndex>0?$("Esc","Back to the previous panel",m(()=>{o.back()}),"global"):$("Esc","Jump to the navigation",m(()=>{let u=c.querySelector(".s-nav-panel");u?.offsetParent!=null?(u.querySelector("[aria-current=page]")??u.querySelector(".s-menu-item:not([aria-disabled=true])"))?.focus():l()?.click()}),"global")}),o??void 0}var S1=null;function O0(){S1?.()}function E0(t,a,e,h){v(()=>{if(t.subtitle!=null&&(a==null||T0(a,e,h))){v("div.s-subtitle",()=>x(t.subtitle));return}a?.drawCrumbs()})}function T0(t,a,e){return e.narrow||a==null||t.panels.length>1?!1:I1(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<=f1)});e.observe(t),v.clean(()=>e.disconnect())}function R0(t,a){i1({icon:t.button?.icon??(()=>v(()=>(a.open?n1:b1)())),ariaLabel:t.button?.ariaLabel??"Open navigation",attrs:t.button?.attrs,click:()=>{a.open=!a.open}})}function D0(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,()=>x1(t.items,r));S1=r,v.clean(()=>{S1===r&&(S1=null)});let d=v.peek(Q1,"path");v(()=>{Q1.path!==d&&!N1(Q1.path)&&r()});let n=o.closest(".s-main"),c=o.parentElement?.querySelector(":scope > .s-body-inner"),m=c?.querySelector(":scope > main");c?.setAttribute("inert",""),v(()=>{h.narrow||(e.open=!1)}),v.clean(()=>{c?.removeAttribute("inert"),p&&(m&&Z0(m),n?.querySelector(".s-nav-trigger button")?.focus())}),requestAnimationFrame(()=>{document.body.contains(o)&&p1(o,".s-menu-item[aria-current=page]")})}function Z0(t){t.classList.add("s-slide-in"),t.offsetWidth,t.classList.remove("s-slide-in")}function B0(t,a){if(a){a.drawColumns();return}let e=v("main",()=>{v("div.s-content",t.contentAttrs,()=>{x(t.content)})});F0(e)}function F0(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 E from"aberdeen";E.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){_(t,(a,e)=>{E("div.s-select_wrap",()=>{E("select.s-input",t.inputAttrs,()=>{o1(t,a,e),E("change=",h=>{t.bind&&(t.bind.value=h.target.value)}),E(()=>{let h=typeof t.options=="function"?t.options():t.options,p=t.bind?.value??"";t.placeholder!=null&&E("option",()=>{E("value= disabled=true hidden=true"),p||E("selected=true"),E("#",t.placeholder)});for(let r of h){let o=typeof r=="string"?{value:r,label:r}:{value:r.value,label:r.label??r.value};E("option",()=>{E("value=",o.value),o.value===p&&E("selected=true"),E("#",o.label)})}})})})})}import K from"aberdeen";K.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 U0(t={}){let a=t.autoGrow!==!1;_(t,(e,h)=>{let p=K("textarea.s-input",t.inputAttrs,()=>{a?(K(".s-autoGrow"),K("input=",r=>{E2(r.currentTarget),t.input&&t.input(r)})):(K("rows=",t.rows??4),K("resize:",t.resize??"vertical"),t.input&&K("input=",t.input)),t.placeholder!=null&&K("placeholder=",t.placeholder),t.value!=null&&!t.bind&&K("value=",t.value),t.change&&K("change=",t.change),o1(t,e,h,t.bind)});a&&requestAnimationFrame(()=>E2(p))})}function E2(t){t.style.height="auto",t.style.height=`${t.scrollHeight}px`}export{G1 as addContextMenu,c1 as addTooltip,X2 as alert,Y2 as autocomplete,$ as bindKey,e0 as box,D as button,h0 as buttonChooser,Y as buttonGroup,p0 as checkbox,z2 as closeFloatingMenu,O0 as closeNav,j2 as confirm,d1 as dialog,r0 as form,q as formatKey,t2 as getDarkMode,i1 as iconButton,R1 as isDialogOpen,V1 as isFloatingMenuOpen,P0 as main,y0 as menu,f0 as menuButton,_2 as prompt,L1 as revealInStrip,k1 as scrollStrip,I0 as select,R2 as setDarkMode,Q2 as setKeyHelp,W1 as showFloatingMenu,D1 as showKeyHelp,w0 as tabs,U0 as textarea,q1 as textline,w1 as toast};
1
+ import B from"aberdeen";var a2=t=>`background: $s-bg linear-gradient(${t}, color-mix(in oklab, $s-bg, white 9%), color-mix(in oklab, $s-bg, black 9%));`,E1=a2("170deg"),T1=a2("180deg"),O1="staffa:darkMode",e2=B.proxy({value:Z2()});function Z2(){try{let t=localStorage.getItem(O1);if(t==="dark")return!0;if(t==="light")return!1}catch{}}function B2(t){e2.value=t;try{t===void 0?localStorage.removeItem(O1):localStorage.setItem(O1,t?"dark":"light")}catch{}}function h2(t=!1){let a=e2.value;return a===void 0&&!t?B.darkMode():a}B(()=>{h2()?B.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"}):B.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"})});B.setSpacingCssVars(1.1);B.insertGlobalCss({"*, *::before, *::after":"box-sizing:border-box",html:"text-size-adjust:100%",body:"m:0 p:$3 min-height:100dvh line-height:1.5 font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; -webkit-font-smoothing:antialiased text:$s-text "+E1,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":E1+" 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);",code:"background:transparent padding:0",pre:"background:transparent border: 1px solid $s-faint;"},".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 "+E1+" border-color: transparent;"});B.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")))}B.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 I2="p, ul, ol, dl, blockquote, pre, table, figure, hr, h1, h2, h3, h4, h5, h6";B.insertGlobalCss({[`${I2}`]:{"&":"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 q1 from"aberdeen";var y1=typeof navigator<"u"&&/mac|iphone|ipad|ipod/i.test(navigator.platform||navigator.userAgent),F2={esc:"escape",space:" "},U2={" ":"Space",escape:"Esc",arrowup:"\u2191",arrowdown:"\u2193",arrowleft:"\u2190",arrowright:"\u2192"},f1=new WeakMap,q=[];function r2(){let t=q1();if(!t)throw new Error("Staffa: claimKeyboard needs a current element");return q.push(t),()=>{let a=q.indexOf(t);a>=0&&q.splice(a,1)}}function o2(t){let[,a,e,h]=/^(mod\+)?(shift\+)?(.*)$/i.exec(t),p=h.toLowerCase();if(p=F2[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 K2(t){if(t.altKey||(y1?t.ctrlKey:t.metaKey))return null;let a=t.key.toLowerCase(),e=t.shiftKey&&(a.length>1||t.key.toUpperCase()!==a);return((y1?t.metaKey:t.ctrlKey)?"mod+":"")+(e?"shift+":"")+a}function d2(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 n2(t,a){let e=q[q.length-1];return a.global===!0||!e||e.contains(t)}function N2(t){for(let a=q.length-1;a>=0;a--)if(q[a].contains(t))return q[a]}function c2(){return q[q.length-1]??document.body}function i2(t){let a=q[q.length-1];return a&&!(t&&a.contains(t))?a:t??document.body}var p2=!1;function W2(t){if(t.defaultPrevented||t.repeat||t.isComposing)return;let a=K2(t),e=t.target instanceof Element?t.target:null;if(!(a==null||d2(a,e)))for(let h=i2(e);h;h=h.parentElement){let p=f1.get(h)?.get(a);if(p&&n2(h,p)){p.press&&(t.preventDefault(),p.press(t));return}}}function s2(t){let a=new Map;for(let e=i2(t);e;e=e.parentElement){let h=f1.get(e);if(h)for(let[p,r]of h)!a.has(p)&&n2(e,r)&&!d2(p,t)&&a.set(p,r)}return[...a]}function P(t,a,e,h="normal"){let p=q1(),r=h==="global"?document.body:h==="local"?p:h==="normal"?(p&&N2(p))??document.body:h;if(!r)throw new Error("Staffa: a local key binding needs a current element");let o=o2(t),d=f1.get(r);d||f1.set(r,d=new Map);let n={description:a,press:e,global:h==="global",prev:d.get(o)};d.set(o,n),p2||(p2=!0,document.addEventListener("keydown",W2)),q1.clean(()=>{let c=d.get(o);if(c===n)n.prev?d.set(o,n.prev):d.delete(o);else for(;c;c=c.prev)if(c.prev===n){c.prev=n.prev;break}})}function R(t,a=!1){let e=o2(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 c=o===" "?"Space":r||o.length>1?d:o;return(h?y1?"Meta+":"Control+":"")+(r?"Shift+":"")+c}let n=U2[o]??d;return y1?(r?"\u21E7":"")+(h?"\u2318":"")+n:(h?"Ctrl+":"")+(r?"Shift+":"")+n}import _ from"aberdeen";import R1 from"aberdeen";var g1=640,G2=0;function X(t="s"){return`${t}-${++G2}`}function M(t,...a){t!=null&&(typeof t=="function"?t(...a):R1("rich=",t))}var X2="a[href], button, input, select, textarea, [tabindex]";function p1(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(X2)].find(e);return h?.focus(),h!=null}function I(t){queueMicrotask(()=>R1(t))}var l2=["scroll","resize","transitionstart","animationstart"];function r1(t,a){let e="",h=0,p=0,r=()=>{let d=t instanceof Element?t.getBoundingClientRect():t,n=`${d.left} ${d.top} ${d.bottom} ${d.width}`;n!==e&&(e=n,a(d),p=0),h=++p>30?0:requestAnimationFrame(r)},o=()=>{p=0,h||r()};for(let d of l2)window.addEventListener(d,o,!0);return R1.clean(()=>{cancelAnimationFrame(h);for(let d of l2)window.removeEventListener(d,o,!0)}),r(),()=>{e="",o()}}import A from"aberdeen";import E 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 o1=D.proxy(void 0),F=null;function j2(t,a,e,h){let r=window.innerWidth,o=window.innerHeight,d=0,n=0;return h==="bottom"?(d=t.left+(t.width-a)/2,n=t.bottom+7,n+e>o-8&&(n=t.top-e-7)):h==="left"?(d=t.left-a-7,n=t.top+(t.height-e)/2,d<8&&(d=t.right+7)):h==="right"?(d=t.right+7,n=t.top+(t.height-e)/2,d+a>r-8&&(d=t.left-a-7)):(d=t.left+(t.width-a)/2,n=t.top-e-7,n<8&&(n=t.bottom+7)),{x:Math.max(8,Math.min(d,r-a-8)),y:Math.max(8,Math.min(n,o-e-8))}}function D1(){F&&clearTimeout(F),F=setTimeout(()=>{o1.value=void 0,F=null},100)}I(()=>{let t=o1.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",a.attrs,()=>{D("mouseenter=",()=>{F&&(clearTimeout(F),F=null)}),D("mouseleave=",D1),M(a.tip)});r1(e,r=>{if(r.bottom<0||r.top>window.innerHeight||r.right<0||r.left>window.innerWidth||e.closest("[inert]")){o1.value=void 0;return}let{x:o,y:d}=j2(r,p.offsetWidth,p.offsetHeight,h);p.style.left=o+"px",p.style.top=d+"px"})});function i1(t){let a=e=>{F&&(clearTimeout(F),F=null),o1.value={opts:t,anchor:e.currentTarget}};D("mouseenter=",a),D("mouseleave=",D1),D("focusin=",e=>{e.target.matches?.(":focus-visible")&&a(e)}),D("focusout=",D1),D.clean(()=>{D.unproxy(o1).value?.opts===t&&(o1.value=void 0)})}E.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 s1(t){let a=t.href!=null?"a":"button";E(`${a}.s-icon-btn`,t.attrs,()=>{M2(t),E("aria-label=",t.ariaLabel),t.key&&x2(t.key,t.ariaLabel,void 0,t.disabled),M(t.icon)})}function M2(t){t.href!=null?(E("role=button"),t.disabled?E("aria-disabled=true"):E("href=",t.href)):(E("type=",t.type??"button"),t.disabled&&E("disabled=true")),t.click&&!t.disabled&&E("click=",t.click)}function x2(t,a,e,h){let p=E(),r=a?`${a} \xB7 ${R(t)}`:R(t);i1({tip:()=>E("#",r)}),h||(E("aria-keyshortcuts=",R(t,!0)),P(t,typeof e=="string"?e:a,()=>p.click()))}function Z(t={}){let a=typeof t=="string"||typeof t=="function"?{content:t}:t,e=a.href!=null?"a":"button";E(`${e}.s-btn.s-s.shadow`,a.attrs,()=>{M2(a),a.ariaLabel&&E("aria-label=",a.ariaLabel),a.key&&x2(a.key,a.ariaLabel,a.content,a.disabled),M(a.icon),M(a.content)})}import v2 from"aberdeen";v2.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 J(t={}){let e=`.s-${t.layout??"attached"}${t.vertical?".s-vertical":""}`;v2(`div.s-bgroup${e} role=group`,t.attrs,()=>{if(t.buttons)for(let h of t.buttons)Z(h);M(t.content)})}import Y from"aberdeen";import S from"aberdeen";S.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 j(t,a){let e=t.id??X("field"),h=()=>!!t.error;S("div.s-field",t.attrs,()=>{S(()=>{t.label!=null&&S("label for=",e,()=>{M(t.label),t.required&&S("span.s-req aria-hidden=true #*")})}),a(e,h),S(()=>{t.help!=null&&!t.error&&S("div.s-help",()=>M(t.help))}),S(()=>{t.error&&S("div.s-error role=alert #",t.error)})})}function d1(t,a,e,h){S("id=",a),t.name&&S("name=",t.name),S(()=>{t.disabled&&S("disabled=true")}),S(()=>{t.required&&S("aria-required=true")}),S(()=>S("aria-invalid=",e()?"true":"false")),h&&S("bind=",h)}function Z1(t={}){j(t,(a,e)=>{Y("input.s-input",t.inputAttrs,()=>{Y("type=",t.type??"text"),t.placeholder!=null&&Y("placeholder=",t.placeholder),t.autocomplete!=null&&Y("autocomplete=",t.autocomplete),t.value!=null&&!t.bind&&Y("value=",t.value),t.input&&Y("input=",t.input),t.change&&Y("change=",t.change),d1(t,a,e,t.bind)})})}A.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 l1=A.proxy({}),_2=0,m2=A.derive(()=>{let t=Object.keys(l1);if(t.length)return t[t.length-1]});function B1(){return m2.value!=null}I(()=>{A.onEach(l1,({resolve:t,opts:a},e)=>{let h=()=>{delete l1[e]};A.clean(()=>{a.onClose?.(),t()});let p=document.activeElement;A.clean(()=>{p instanceof HTMLElement&&document.contains(p)&&p.focus()});let r=A.derive(()=>m2.value!=e);A("div.s-backdrop create=hidden destroy=hidden .hidden=",r,"click=",()=>{a.allowCancel!==!1&&h()});let o=A("div.s-dialog.neutral.s-s.extra-shadow create=hidden destroy=hidden",a.attrs,()=>{a.keyboardTransparent||A.clean(r2());let d=c2();A(()=>{let n=a.allowCancel!==!1;P("esc",n?"Close this dialog":void 0,n?h:()=>{},d)}),A(()=>{a.header!=null&&A("header.s-s.neutral",a.headerAttrs,()=>M(a.header))}),A("div",a.contentAttrs,()=>{M(a.content,h)}),A(()=>{a.footer!=null&&A("footer.s-s.neutral",a.footerAttrs,()=>M(a.footer))})});requestAnimationFrame(()=>{document.body.contains(o)&&p1(o)})})});function n1(t){let a=++_2;return t.cancelWithScope!==!1&&A.clean(()=>{delete l1[a]}),new Promise(e=>{l1[a]={resolve:e,opts:t}})}function Q2(t,a={}){return n1({header:"Alert",allowCancel:!0,content:e=>{A("p",()=>{A("#",t)}),J({layout:"spaced",attrs:"align-self:flex-end",content:()=>{Z({content:"OK",click:e})}})},...a})}function J2(t,a={}){return new Promise(e=>{let h=!1;n1({header:"Confirm",allowCancel:!0,content:p=>{A("p",()=>{A("#",t)}),J({layout:"spaced",attrs:"align-self:flex-end",content:()=>{Z({content:"Cancel",attrs:".neutral",click:p}),Z({content:"OK",click:()=>{h=!0,p()}})}})},...a,onClose:()=>{e(h),a.onClose?.()}})})}function Y2(t,a="",e={}){return new Promise(h=>{let p=null;n1({header:"Input",allowCancel:!0,content:r=>{A("p",()=>{A("#",t)});let o=A.proxy({value:a});A("form display:contents",()=>{A("submit=",d=>{d.preventDefault(),p=o.value,r()}),Z1({bind:A.ref(o,"value")}),J({layout:"spaced",attrs:"align-self:flex-end",content:()=>{Z({content:"Cancel",attrs:".neutral",type:"button",click:r}),Z({content:"OK",type:"submit"})}})})},...e,onClose:()=>{h(p),e.onClose?.()}})})}_.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 b1=null;function I1(){if(b1){b1();return}let t=s2(document.activeElement);n1({header:"Keyboard shortcuts",cancelWithScope:!1,keyboardTransparent:!0,onClose:()=>{b1=null},content:a=>{b1=a;let e=h=>{h.repeat||["Control","Shift","Alt","Meta","Escape","?"].includes(h.key)||a()};document.addEventListener("keydown",e,!0),_.clean(()=>document.removeEventListener("keydown",e,!0)),_("div.s-keyhelp",()=>{for(let[h,p]of t)p.description!==void 0&&_("div",()=>{_("span",()=>M(p.description)),_("kbd text=",R(h))})})}})}var u2=_.proxy(!0);function t0(t){u2.value=t}_(()=>{u2.value&&(P("?",void 0,I1,"global"),P("mod+?","This overview",I1,"global"))});import s from"aberdeen";s.insertGlobalCss({".s-ac":{"> .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-ac-menu.s-s":{"&":"position:fixed max-height:15rem overflow-y:auto list-style:none p:$1 margin:0",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"}});var w1=s.proxy({cur:null});function a0(t,a){t.style.maxHeight="";let p=t.offsetHeight,r=window.innerHeight-a.bottom-4-8,o=a.top-4-8,d=p>r&&o>r;t.style.left=`${a.left}px`,t.style.width=`${a.width}px`,t.style.maxHeight=`${Math.min(p,Math.max(d?o:r,60))}px`,t.style.top=d?"auto":`${a.bottom+4}px`,t.style.bottom=d?`${window.innerHeight-a.top+4}px`:"auto"}I(()=>{let t=w1.cur;if(!t)return;let a,e=s("ul.s-ac-menu.s-s.neutral.shadow role=listbox",`id=${t.id} z-index:${t.zIndex}`,()=>{s("mousedown=",h=>h.preventDefault()),t.draw(),a?.()});a=r1(t.anchor,h=>a0(e,h))});function e0(t){return typeof t=="string"?{value:t,label:t}:{value:t.value,label:t.label??t.value}}function h0(t){let a=X("ac-menu"),e=s.proxy({query:"",open:!1,active:0}),h=()=>(typeof t.options=="function"?t.options():t.options).map(e0),p=()=>{let v=t.bind?.value;return v==null||v===""?[]:Array.isArray(v)?v:[v]},r=v=>h().find(b=>b.value===v)?.label??v;if(!t.multi){let v=t.bind?s.peek(t.bind,"value"):void 0;typeof v=="string"&&v&&(e.query=s.peek(()=>r(v)))}let o=()=>{let v=new Set(p()),b=h();t.multi&&(b=b.filter(H=>!v.has(H.value)));let V=e.query.trim().toLowerCase();return V&&(b=b.filter(H=>H.label.toLowerCase().includes(V))),b},d=(v,b)=>{if(t.multi){let V=Array.isArray(t.bind?.value)?[...t.bind.value]:[];V.includes(v)||V.push(v),t.bind&&(t.bind.value=V),e.query=""}else t.bind&&(t.bind.value=v),e.query=r(v),e.open=!1;e.active=0,b?.focus()},n=v=>{if(!t.bind)return;let b=t.bind.value??[];t.bind.value=b.filter(V=>V!==v)},c,m=()=>{let v=o(),b=e.query.trim(),V=t.allowCustom!==!1&&b!==""&&!v.some(H=>H.label.toLowerCase()===b.toLowerCase());v.forEach((H,f)=>{s("li.s-option role=option",`id=${a}-opt-${f}`,()=>{s(()=>s("aria-selected=",e.active===f?"true":"false")),s("#",H.label),s("click=",()=>d(H.value,c)),s("mousemove=",()=>{e.active=f})})}),V&&s("li.s-option.s-add role=option",()=>{s("#",`Add "${b}"`),s("click=",()=>d(b,c))}),v.length===0&&!V&&s("li.s-empty #No matches")};j(t,(v,b)=>{s("div.s-ac",t.inputAttrs,()=>{s(()=>s("aria-invalid=",b()?"true":"false"));let V=s("div.s-control",()=>{s("click=",()=>c?.focus()),s(()=>{if(t.multi)for(let H of p())s("span.s-chip",()=>{s("span #",s.peek(()=>r(H))),s("button type=button aria-label=",`Remove ${H}`,()=>{s("#\xD7"),s("click=",f=>{f.stopPropagation(),n(H),c?.focus()})})})}),c=s("input type=text role=combobox autocomplete=off",()=>{s("id=",v,`aria-controls=${a} aria-autocomplete=list`),t.placeholder!=null&&s("placeholder=",t.placeholder),t.disabled&&s("disabled=true"),t.required&&s("aria-required=true"),s("bind=",s.ref(e,"query")),s(()=>s("aria-expanded=",e.open?"true":"false")),s(()=>{let f=o()[e.active];s("aria-activedescendant=",e.open&&f?`${a}-opt-${e.active}`:"")}),s("input=",()=>{e.open=!0,e.active=0}),s("focus=",()=>{e.open=!0}),s("blur=",()=>{setTimeout(()=>w(),150)}),s("keydown=",H=>z(H,c))})});s(()=>{if(!e.open)return;let H=V.closest(".s-dialog")?350:150;w1.cur={id:a,anchor:V,zIndex:H,draw:m},s.clean(()=>{w1.cur?.id===a&&(w1.cur=null)})}),s(()=>{if(t.name)if(t.multi)for(let H of p())s("input type=hidden",()=>{s("name=",t.name),s("value=",H)});else s("input type=hidden",()=>{s("name=",t.name),s("value=",p()[0]??"")})})})});function z(v,b){let V=o(),H=V.length-1;if(v.key==="ArrowDown")v.preventDefault(),e.open=!0,e.active=Math.min(H,e.active+1);else if(v.key==="ArrowUp")v.preventDefault(),e.active=Math.max(0,e.active-1);else if(v.key==="Enter"){v.preventDefault();let f=V[e.active];f?d(f.value,b):t.allowCustom!==!1&&e.query.trim()?d(e.query.trim(),b):e.open&&(e.open=!1)}else if(v.key==="Escape")e.open&&(v.preventDefault(),e.open=!1,t.multi||(e.query=r(p()[0]??"")));else if(v.key==="Backspace"&&t.multi&&e.query===""){let f=p();f.length&&n(f[f.length-1])}}function w(){e.open=!1,t.multi?e.query="":t.allowCustom!==!1&&e.query.trim()?d(e.query.trim()):e.query=r(p()[0]??"")}}import t1 from"aberdeen";import p0 from"aberdeen";var M1={size:24,color:"currentColor",strokeWidth:2,cap:"round",join:"round"};function r0(t,a){let e=a.size??M1.size,h=p0('svg.s-icon aria-hidden=true viewBox="0 0 24 24" fill=none',"width=",e,"height=",e,"stroke=",a.color??M1.color,"stroke-width=",a.strokeWidth??M1.strokeWidth,"stroke-linecap=",a.cap??M1.cap,"stroke-linejoin=",a.join??M1.join,a.attrs);h.innerHTML=t}function O(t){return(a={})=>r0(t,a)}var y2=O('<path d="m9 18 6-6-6-6" />');var f2=O('<circle cx="12" cy="12" r="10" />');var g2=O('<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 b2=O('<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 H1=O('<path d="M4 5h16" /><path d="M4 12h16" /><path d="M4 19h16" />');var w2=O('<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" />'),F1=O('<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 H2=O('<path d="M22 2 2 22" />');var c1=O('<path d="M18 6 6 18" /><path d="m6 6 12 12" />');t1.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 o0(t={}){let a=typeof t=="string"||typeof t=="function"?{content:t}:t;t1("section.s-box.s-s.neutral.shadow",a.attrs,()=>{t1(()=>{a.header!=null?t1("header.s-s.neutral",a.headerAttrs,()=>{M(a.header),typeof a.close=="function"&&A2(a.close)}):typeof a.close=="function"&&A2(a.close)}),t1("div",a.contentAttrs,()=>{M(a.content)}),t1(()=>{a.footer!=null&&t1("footer.s-s.neutral",a.footerAttrs,()=>M(a.footer))})})}function A2(t){s1({icon:c1,ariaLabel:"Close",click:t,attrs:".s-box-close"})}import U1 from"aberdeen";function d0(t){U1(()=>{let a=t.bind.value;J({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&&U1(()=>U1("input type=hidden name=",t.name,"value=",t.bind.value??""))}import $ from"aberdeen";$.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 n0(t={}){let a=t.id??X("check");$("div.s-check",t.attrs,()=>{$("label for=",a,()=>{$("input type=checkbox",t.inputAttrs,()=>{$("id=",a),t.name&&$("name=",t.name),t.checked&&!t.bind&&$("checked=true"),t.change&&$("change=",t.change),$(()=>{t.disabled&&$("disabled=true")}),$(()=>{t.required&&$("aria-required=true")}),t.bind&&$("bind=",t.bind)}),$(()=>{t.label!=null&&M(t.label),t.required&&$("span.s-req aria-hidden=true #*")})}),$(()=>{t.help!=null&&!t.error&&$("div.s-help",()=>M(t.help))}),$(()=>{t.error&&$("div.s-error role=alert #",t.error)})})}import a1 from"aberdeen";a1.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 c0(t={}){let a=typeof t=="string"||typeof t=="function"?{content:t}:t;a1("form.s-form",a.attrs,()=>{a1(()=>{a1(".grid=",a.layout==="grid")}),a1("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)}}),M(a.content),a1(()=>{a.actions&&a1("footer",a.actionsAttrs,()=>M(a.actions))})})}import x from"aberdeen";import{current as t2}from"aberdeen/route";import y from"aberdeen";import{matchCurrent as M0,current as V1,go as k2}from"aberdeen/route";import C from"aberdeen";import{grow as i0,shrink as s0}from"aberdeen/transitions";C.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 l0=0,x1=C.proxy({});I(()=>{C.peek(()=>C.isEmpty(x1))&&C.isEmpty(x1)||C("div.s-toasts",()=>{C.onEach(x1,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,n=()=>{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(()=>K1(e),r)},c=()=>{clearTimeout(o),o=void 0,d&&(d.style.transition="none",d.style.width="100%")};C.clean(()=>clearTimeout(o)),C(`div.s-toast.s-s.${p}.extra-shadow aria-live=polite role=${h}`,"create=",i0,"destroy=",s0,a.attrs,()=>{r>0&&(C("mouseenter=",c),C("mouseleave=",n)),C("div.s-toast-body",()=>{C(()=>{a.title!=null&&C("div.s-toast-title",()=>M(a.title))}),C("div.s-toast-msg",()=>M(a.message))}),C(()=>{a.dismissible!==!1&&C("button.s-toast-close type=button aria-label=Dismiss",()=>{C("#\xD7"),C("click=",()=>K1(e))})}),r>0&&(d=C("div.s-toast-progress"))}),r>0&&requestAnimationFrame(n)})})});function K1(t){delete x1[t]}function A1(t){let a=++l0;return x1[a]={id:a,opts:t},()=>K1(a)}y.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 v1(t,a,e){y("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(c=>c.getAttribute("aria-disabled")!=="true"&&!m0(c));if(!r.length)return;let o=r.indexOf(document.activeElement),d=h.key==="ArrowUp"?-1:1,n=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[n].focus()}),L2(t,{onLeafSelect:a,keyHints:e,$hasCurrent:y.derive(()=>N1(t))})}function L2(t,a){for(let e of t){if(typeof e=="string"||typeof e=="function"){M(e);continue}if("separator"in e){y("hr.s-menu-sep");continue}e.items?v0(e,a):x0(e,a)}}function x0(t,a){let e=!1,h=y(t.href?"a.s-menu-item data-panel=open":"button.s-menu-item type=button",t.attrs,()=>{t.href&&(y("href=",t.href),t.target&&y("target=",t.target),y(()=>{let p=!e;e=!0,W1(t)&&(y("aria-current=page"),requestAnimationFrame(()=>h.scrollIntoView({block:"nearest",behavior:p?"instant":"smooth"})))})),t.disabled&&y("aria-disabled=true"),t.key&&y("aria-keyshortcuts=",R(t.key,!0)),y("click=",p=>{if(t.disabled){p.preventDefault();return}a.onLeafSelect?.(),t.click?.(p)}),t.icon&&y("span.s-menu-icon",()=>M(t.icon)),M(t.label),$2(t,a)})}var C2=new Map;function V2(t,a){return C2.set(t,a),a}function v0(t,a){let e=t.href??z2(t.items),h=e!=null?y.derive(()=>G1(t)?V2(e,!0):a.$hasCurrent.value?V2(e,!1):C2.get(e)??!1):null;y("details.s-menu-details",()=>{h&&y(()=>{h.value&&y("open=true")}),y("summary.s-menu-item.s-menu-branch",t.attrs,()=>{t.disabled&&y("aria-disabled=true"),t.key&&y("aria-keyshortcuts=",R(t.key,!0)),y(()=>{W1(t)&&y("aria-current=page")}),y("click=",p=>{if(t.disabled){p.preventDefault();return}e!=null&&(p.preventDefault(),y0(e),k2(e)),t.click?.(p)}),t.icon&&y("span.s-menu-icon",()=>M(t.icon)),M(t.label),$2(t,a),y("span.s-menu-chevron aria-hidden=true",()=>y2())}),y("div.s-menu-sub",()=>L2(t.items,a))})}function m0(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 N1(t){return t.some(a=>typeof a!="string"&&typeof a!="function"&&!("separator"in a)&&G1(a))}function W1(t){if(t.href!=null&&M0(t.href))return!0;let a=t.match;if(a==null)return!1;let e=V1.path;if(typeof a=="function")return a(e);let h=a.replace(/\/+$/,"")||"/";return e===h||e.startsWith(h==="/"?"/":h+"/")}function G1(t){if(W1(t))return!0;for(let a of t.items??[])if(!(typeof a=="string"||typeof a=="function"||"separator"in a)&&G1(a))return!0;return!1}function z2(t){for(let a of t){if(typeof a=="string"||typeof a=="function"||"separator"in a)continue;let e=a.href??(a.items?z2(a.items):void 0);if(e!=null)return e}}function $2(t,a){let e=a.keyHints?void 0:t.key;t.key&&!e&&y("kbd.s-menu-key aria-hidden=true text=",R(t.key)),!(t.tooltip==null&&!e)&&i1({placement:"right",tip:()=>{M(t.tooltip),e&&(t.tooltip!=null&&y("hr.s-menu-sep"),y("kbd.s-menu-tt-key aria-hidden=true text=",R(e)))}})}function m1(t,a){y(()=>{for(let e of S2(t(),[]))P(e.key,e.label,h=>{P2(),a?.(),e.click?.(h),e.href!=null&&u0(e.href,e.target)})})}function S2(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&&S2(e.items,a));return a}function u0(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:k2(t)}var k1=null;function y0(t){try{k1=new URL(t,location.href).pathname.replace(/\/+$/,"")||"/"}catch{k1=null}}function X1(t){return k1!==t?!1:(k1=null,!0)}var Q=y.proxy({opts:null});function G(){let t=Q.opts?.anchor;Q.opts=null,t?.focus()}function L1(t){let a=Q.opts;return a!=null&&(t==null||a.anchor===t)}function P2(t){L1(t)&&G()}function f0(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 n=a.bottom+o;n+h>r-8&&a.top-h-o>=8&&(n=a.top-h-o),t.style.left=Math.max(8,d)+"px",t.style.top=Math.max(8,n)+"px"}function g0(t){return[{label:"Open in new tab",icon:g2,click:()=>{window.open(t,"_blank","noopener")}},{label:"Copy link",icon:b2,click:()=>{b0(t)}}]}async function b0(t){let a=new URL(t,location.href).href;try{await navigator.clipboard.writeText(a),A1({message:"Link copied."})}catch{A1({message:"Couldn't copy the link.",type:"danger"})}}I(()=>{let t=Q.opts;if(!t)return;let a=y("div.s-menu-list.s-s.neutral.shadow create=hidden destroy=hidden",t.dropdownAttrs,()=>{v1(t.link!=null?[...g0(t.link),{separator:!0},...t.items]:t.items,G,!0)}),e=r=>{let o=r.target;!a.contains(o)&&(t.closeOnAnchorClick||!t.anchor.contains(o))&&G()},h=r=>{(r.key==="Escape"||r.key==="Tab")&&(r.preventDefault(),G())},p=y.peek(V1,"path");y(()=>{V1.path!==p&&!X1(V1.path)&&G()}),document.addEventListener("click",e,!0),document.addEventListener("keydown",h,!0),y.clean(()=>{document.removeEventListener("click",e,!0),document.removeEventListener("keydown",h,!0)}),r1(t.at?new DOMRect(t.at.x,t.at.y,0,0):t.anchor,r=>f0(a,r)),requestAnimationFrame(()=>{document.body.contains(a)&&p1(a,".s-menu-item[aria-current=page]")})});function w0(t){y("nav.s-menu-inline",t.attrs,()=>{m1(()=>t.items,()=>t.onLeafSelect?.()),v1(t.items,t.onLeafSelect)})}function j1(t){return Q.opts=t,G}function _1(t){m1(()=>t.items);let a=null;y.clean(()=>{Q.opts?.anchor===a&&G()}),y("contextmenu=",e=>{e.preventDefault(),a=e.currentTarget,j1({...t,anchor:a,at:{x:e.clientX,y:e.clientY},closeOnAnchorClick:!0})})}function H0(t){m1(()=>t.items);let a=null;y.clean(()=>{Q.opts?.anchor===a&&G()}),Z({icon:H1,...t.button?.content==null?{ariaLabel:"Open menu"}:null,attrs:".neutral",...t.button,click:e=>{if(a=e.currentTarget,Q.opts?.anchor===a){G();return}j1({items:t.items,anchor:a,dropdownAttrs:t.dropdownAttrs})}})}import i,{OPAQUE as O2}from"aberdeen";import*as g from"aberdeen/route";import L from"aberdeen";var A0=O('<path d="m15 18-6-6 6-6"/>'),V0=O('<path d="m9 18 6-6-6-6"/>');L.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 C1(t){L("div.s-strip",t.attrs,()=>{let a=L("div.s-strip-row",t.stripAttrs,()=>M(t.content));E2(a,-1),E2(a,1),L0(a)})}function z1(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 k0(t){let a=X("tabs"),e=(r,o)=>r.id??String(o),h=t.bind??L.proxy(e(t.tabs[0]??{label:""},0));t.tabs.length>0&&!t.tabs.some((r,o)=>e(r,o)===L.peek(()=>h.value))&&(h.value=e(t.tabs[0],0));let p=(r,o)=>{r.disabled||(h.value=e(r,o))};L("div.s-tabs",t.attrs,()=>{C1({attrs:".s-tabbar",stripAttrs:".s-tablist role=tablist",content:()=>{t.tabs.forEach((r,o)=>{let d=e(r,o),n=L("button.s-tab type=button role=tab",()=>{L("id=",`${a}-tab-${d}`,"aria-controls=",`${a}-panel-${d}`),L(()=>{let c=h.value===d;L("aria-selected=",c?"true":"false"),L("tabindex=",c?"0":"-1"),c&&requestAnimationFrame(()=>z1(n))}),r.disabled&&L("disabled=true"),L("click=",()=>p(r,o)),L("keydown=",c=>C0(c,t.tabs,o,p)),M(r.icon),M(r.label)})})}}),L("div.s-tabpanel role=tabpanel",t.contentAttrs,()=>{L(()=>{let r=h.value,o=t.tabs.findIndex((n,c)=>e(n,c)===r),d=t.tabs[o]??t.tabs[0];d&&(L("id=",`${a}-panel-${e(d,o)}`,"aria-labelledby=",`${a}-tab-${e(d,o)}`),M(d.content))})})})}function E2(t,a){L(`button.s-strip-btn.s-strip-btn-${a<0?"left":"right"} type=button`,()=>{L("tabindex=-1 aria-hidden=true"),L("click=",()=>t.scrollBy({left:a*t.clientWidth*.8,behavior:"smooth"})),(a<0?A0:V0)({size:"1.1em"})})}function L0(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(),L.clean(()=>{t.removeEventListener("scroll",e),h.disconnect(),p?.disconnect()})}function C0(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 Y1={integer(t){if(!/^(0|-?[1-9]\d*)$/.test(t))return;let a=Number(t);return Number.isSafeInteger(a)?a:void 0}};function U(t){let a=String(t).replace(/\/+$/,"");return a.startsWith("/")||(a=`/${a}`),a}function u1(t){let a=U(t);return a==="/"?[]:a.slice(1).split("/")}function T2(t){let a=u1(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,n]=o;if(n&&!(n in Y1))throw new Error(`Staffa: unknown matcher "${n}" in route "${t}" (known: ${Object.keys(Y1).join(", ")})`);return{kind:"param",name:d,matcher:n}});return{key:t,segs:e}}function z0(t){try{return decodeURIComponent(t)}catch{return t}}function Q1(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=Y1[p.matcher](r);if(o===void 0)return null;e[p.name]=o}else e[p.name]=z0(r)}return t.segs.length===a.length?e:null}var K=250,$0=300,S0=360,$1=540;i.insertGlobalCss({":root":`--s-panel-ms:${K}ms`,".s-panels":"flex:1 min-width:0 min-height:0 position:relative overflow:clip isolation:isolate "+T1,".s-panel":{"&":"position:absolute top:0 bottom:0 left:0 display:flex flex-direction:column "+T1+` z-index:2 transition: transform ${K}ms ease-out, opacity ${K}ms linear;`,"&.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-new":"z-index:1","&.s-panel-closing":"z-index:0 opacity:0 pointer-events:none","&.s-panel-enter":"opacity:0","&.s-panel-hidden, &.s-panel-parked":"visibility:hidden"},".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 J1=!1,S1=class{[O2]=!0;compiled;ancestors;opts;$state=i.proxy({live:[],focus:0});$open=i.proxy({});nextOrder=0;containerEl;geom;lastGeom;layoutQueued=!1;timers=new Set;exiting=new Set;intent=null;settling=null;lastSeen=null;queued=null;constructor(a){if(J1)throw new Error("Staffa: only one routed S.main() (one with `routes`) can be active at a time");J1=!0,this.opts=a,this.compiled=Object.entries(a.routes).map(([e,h])=>({...T2(e),draw:h})),this.ancestors=Object.entries(a.ancestors??{}).filter(e=>e[1]!=null).map(([e,h])=>({...T2(e),fn:h})),i(()=>{let e=this.computeTarget(),h={...g.current.search},p=g.current.hash;i.peek(()=>{let r=this.lastSeen;if(r&&r.path!==g.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:g.current.path,search:h,hash:p},this.propose(e),Array.isArray(g.current.state.panels)||Object.assign(g.current.state,this.stateFor({stack:this.paths(),focus:this.$state.focus}))})}),this.interceptLinks(),this.watchTitle(),this.guardTabClose(),i.clean(()=>{for(let e of this.timers)clearTimeout(e);this.timers.clear(),this.queued?.settle(!1),this.queued=null,J1=!1})}resolve(a){let e=u1(a);for(let h of this.compiled){let p=Q1(h,e);if(p)return{draw:h.draw,params:p}}return{draw:this.opts.notFound??O0,params:{}}}matches(a){let e=u1(a);return this.compiled.some(h=>Q1(h,e)!=null)}deriveStack(a){let e=U(a),h=this.askAncestors(e),p=h?h.map(U):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=u1(a);for(let h of this.ancestors){let p=Q1(h,e);if(p)return h.fn(p,a)??void 0}}prefixesOf(a){let e=u1(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=U(a),o=new Set([r]),d=c=>c.map(U).filter(m=>!o.has(m)&&!!o.add(m)),n=d(h);return{stack:[...n,r,...d(p)],focus:n.length}}return i.peek(()=>{let p=this.deriveStack(a).slice(0,-1),r=[...p,...this.pinnedIn(this.paths(),[...p,U(a)]),U(a)];return{stack:r,focus:r.length-1}})}computeTarget(){return this.targetFor(g.current.path,g.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}),!(q2(this.paths(),a.stack)&&a.focus===this.$state.focus)&&this.commit(a,g.current.nav)}commit(a,e){this.geom=void 0;let h=g.current.state.pinned,p=new Set(Array.isArray(h)?h.map(String):[]),r=new Map(this.$state.live.map(n=>[n.path,n])),o=[];for(let n of a.stack){let c=r.get(n);if(c){r.delete(n),o.push(c);continue}let m=this.createEntry(n,o.length<=a.focus,p.has(n));e!=="load"&&(m.enter=!0),o.push(m),this.$open[n]=m}let d;for(let n of this.$state.live)r.has(n.path)?this.beginClose(n,d):d=n.path;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={[O2]:!0,order:this.nextOrder++,path:a,draw:p,$ui:i.proxy({holding:!1}),maxWidth:"medium",width:0};return o.$panel=i.proxy({stack:this,params:r,path:a,width:0,visible:e,pinned:h||void 0,close:()=>this.closePath(o.path),open:(d,n)=>this.navigate(d,{from:o.path,how:n})}),o}beginClose(a,e){a.closing=!0,a.anchor=e,a.$panel.visible=!1,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=a.placed?{el:e,anchor:a.anchor,ride:0}:null;h&&this.exiting.add(h),this.afterTransition(e,"opacity",()=>{h&&this.exiting.delete(h),e.remove()})}afterTransition(a,e,h){let p=!1,r=setTimeout(()=>d(),K+80);this.timers.add(r);let o=()=>{clearTimeout(r),this.timers.delete(r)},d=()=>{o(),p||(p=!0,h())},n=c=>m=>{m.target===a&&m.propertyName===e&&c()};a.addEventListener("transitionrun",n(o)),a.addEventListener("transitionend",n(d)),a.addEventListener("transitioncancel",n(d))}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 g.go({path:p,search:r?.search,hash:r?.hash,state:this.stateFor(h)})})}back(){return i.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 i.peek(()=>{let e=this.intended(),h=e.stack.indexOf(U(a));if(h<0||e.stack.length<2||this.unsavedAt(e.stack[h]))return Promise.resolve(!1);let p=e.stack.filter((c,m)=>m!==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 c=this.$state.live.find(w=>w.path===p[r]),m={};c?.search&&(m.search=c.search),c?.hash&&(m.hash=c.hash);let z=p.filter(w=>this.$state.live.find(v=>v.path===w)?.$panel.pinned===!0);return this.issue(o,()=>Promise.resolve(g.back({path:p[r],state:{panels:p.slice(0,r),parked:[]}},m)).then(w=>(w&&(g.current.state.pinned=z),w)))}let d=p[r],n=d!==e.stack[e.focus];return this.issue(o,()=>{let c=n?this.$state.live.find(m=>m.path===d):void 0;return g.go({path:d,search:n?c?.search:{...g.current.search},hash:n?c?.hash:g.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 i.peek(()=>{let n;try{n=new URL(a,location.href)}catch{return Promise.resolve(!1)}let c=U(n.pathname),m=this.intended(),z=p?-1:m.stack.indexOf(c),w;if(z>=0&&r!=="replace"&&r!=="open"){let f=this.pinnedIn(m.stack.slice(z+1),[]);w={stack:[...m.stack.slice(0,z+1),...f],focus:z}}else{let f=o==null?-1:m.stack.indexOf(o),l=(p?p.map(U):f<0?this.deriveStack(c).slice(0,-1):m.stack.slice(0,d?f:f+1)).filter((k,W,h1)=>k!==c&&h1.indexOf(k)===W),u=[...l,...this.pinnedIn(m.stack,[...l,c,d?o:null])];w={stack:[...u,c],focus:u.length}}let v=z>=0?this.$state.live.find(f=>f.path===c):void 0,b=n.search?Object.fromEntries(new URLSearchParams(n.search)):v?.search??{},V=n.hash||v?.hash||"";if(w.focus===m.focus&&q2(w.stack,m.stack)&&n.search===location.search&&(n.hash||"")===(location.hash||""))return Promise.resolve(!0);let H=this.stateFor(w);return d?this.issue(w,()=>(g.current.path=c,g.current.search=b,g.current.hash=V,g.current.state=H,i.runQueue(),g.current.path===c)):this.issue(w,()=>g.go({path:c,search:b,hash:V,state:H}))})}pushPath(a,e){return i.peek(()=>{let h=this.intended();return this.navigate(a,{from:h.stack[h.focus],how:e?"replace":"push"})})}interceptLinks(){g.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 i.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(){C1({attrs:".s-crumbs role=navigation aria-label=Breadcrumbs",content:()=>{i(()=>{let a=this.panels.map(p=>p.path),e=this.currentPanelIndex,h;for(let p=0;p<a.length;p++){p&&H2({size:"0.85em",attrs:".s-crumb-sep"});let r=this.drawCrumb(a[p],p,p===e);p===e&&(h=r)}requestAnimationFrame(()=>{h&&z1(h)})})}})}drawCrumb(a,e,h){let p=this.$state.live[e];return i(h?"span.s-crumb aria-current=page":"a.s-crumb",()=>{h||i("href=",a),i(()=>{p?.$panel.visible&&i(".s-crumb-on")}),i(()=>{p?.$panel.unsaved&&f2({size:"0.45em",attrs:".s-crumb-unsaved"})}),i(()=>{p?.$panel.pinned&&F1({size:"0.85em",attrs:".s-crumb-pin"})}),i(()=>{i("#",p?.$panel.title??p?.$ui.fallback??(a.split("/").pop()||a))}),_1({link:a,items:[{label:()=>{i(()=>{i("#",p?.$panel.pinned?"Unpin":"Pin")})},icon:()=>{i(()=>{(p?.$panel.pinned?w2:F1)()})},click:()=>{p&&this.togglePin(p)}},{label:"Close",icon:c1,disabled:p?.$panel.unsaved===!0,click:()=>{this.closePath(a)}}]})})}togglePin(a){a.$panel.pinned=!a.$panel.pinned||void 0,g.current.state.pinned=this.pinnedPaths()}watchTitle(){let a=document.title;i(()=>{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)}),i.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)))};i(()=>{this.$state.live.some(e=>e.$panel.unsaved)&&(window.addEventListener("beforeunload",a),i.clean(()=>window.removeEventListener("beforeunload",a)))})}drawColumns(){let a=i("div.s-panels role=main",()=>{this.containerEl=i(),i.onEach(this.$open,e=>this.drawPanel(e),e=>e.order)});if(typeof ResizeObserver<"u"){let e=new ResizeObserver(()=>this.layout());e.observe(a),i.clean(()=>e.disconnect())}i.clean(()=>{this.containerEl===a&&(this.containerEl=void 0)}),this.scheduleLayout()}drawPanel(a){let e;i(()=>{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,i.peek(a.$panel,"width")!==p&&(a.$panel.width=p),e&&(e.style.width=`${p}px`,this.scheduleLayout()))}),e=i(`section.s-panel${a.width?` w:${a.width}px`:""}`,"destroy=",h=>this.playExit(a,h),()=>{i(()=>this.drawActions(a)),i("div.s-content",()=>{if(a.draw(a.$panel),g.persistScroll(a.path),i.peek(a.$panel,"title")==null){let h=E0(i());h&&i.peek(a.$ui,"fallback")!==h&&(a.$ui.fallback=h)}}),i(()=>{!a.$panel.loading||a.$ui.holding||i("div.s-panel-loading aria-hidden=true",()=>{i("i"),i("i"),i("i")})})}),a.el=e,a.placed=!1,e.style.transition="none",i.clean(()=>{a.el===e&&(a.el=void 0)}),i(()=>{a.$panel.loading,this.scheduleLayout()}),this.scheduleLayout()}drawActions(a){this.opts.$shell.narrow||a.$panel.actions==null||i("div.s-panel-actions",()=>M(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/$1),p=e/h>=S0?e/h:Math.min(e,$1),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 n=l=>r.size[l.maxWidth],c=Math.min(this.$state.focus,p-1),m=c,z=n(h[c]);if(!o)for(let l=c-1;l>=0;l--){let u=z+n(h[l]);if(u>r.area)break;z=u,m=l}let w=m>0?0:(r.area-z)/2;for(let l=m;l<=c;l++)h[l].width=n(h[l]);for(let l of h)l.width||(l.width=n(l));let v=[],b=[],V=new Map,H=new Map;if(!d)for(let l of h)l.placed&&H.set(l,P0(l.el));let f=w,e1=0;for(let l=0;l<m;l++)f-=h[l].width;for(let l=0;l<p;l++){let u=h[l],k=u.el,W=l>=m&&l<=c;l===c+1&&(f=Math.max(f,r.area)),(u.enter||!u.placed)&&(!u.$panel.loading||u.holdDone?u.$ui.holding=!1:u.$ui.holding||(u.$ui.holding=!0,this.holdEnter(u))),u.placed?(e1=parseFloat(k.style.left)-f,V.set(u.path,e1),e1&&!d&&(k.style.transition=`opacity ${K}ms linear`,k.style.transform=`translateX(${(H.get(u)??0)+e1}px)`,b.push(k)),k.style.left=`${f}px`,u.enter&&!u.$ui.holding&&this.releaseEnter(u)):(v.push(u),k.style.left=`${f}px`,u.enter&&W&&(k.style.transform=`translateX(${e1}px)`,k.classList.add("s-panel-enter","s-panel-new"))),k.style.width=`${u.width}px`,f+=u.width,u.$panel.visible!==W&&(u.$panel.visible=W),u.$panel.width!==u.width&&(u.$panel.width=u.width),k.classList.toggle("s-panel-sep",W&&l>m);let h1=l<m,D2=k.classList.contains("s-panel-hidden")||k.classList.contains("s-panel-parked");W?k.classList.remove("s-panel-hidden","s-panel-parked"):D2||!u.placed||d?(k.classList.toggle("s-panel-hidden",h1),k.classList.toggle("s-panel-parked",!h1)):this.afterTransition(k,"transform",()=>{u.el!==k||!u.offstage||(k.classList.toggle("s-panel-hidden",h1),k.classList.toggle("s-panel-parked",!h1))}),u.offstage=!W,k.toggleAttribute("inert",!W)}for(let l of this.exiting){let u=l.anchor==null?void 0:V.get(l.anchor);u&&(l.ride-=u,l.el.style.transform=`translateX(${l.ride}px)`)}(v.length||b.length||d)&&a.offsetWidth,d&&e.classList.remove("s-shell-snap");for(let l of b)l.style.transition="",l.style.transform="";for(let l of v){let u=l.el;u.style.transition="",u.style.transform="",l.placed=!0,l.$ui.holding||this.releaseEnter(l)}}releaseEnter(a){a.enter=!1;let e=a.el;!e||!e.classList.contains("s-panel-enter")||(e.classList.remove("s-panel-enter"),this.afterTransition(e,"opacity",()=>e.classList.remove("s-panel-new")))}holdEnter(a){let e=setTimeout(()=>{this.timers.delete(e),a.holdDone=!0,a.$ui.holding&&(a.$ui.holding=!1,this.scheduleLayout())},$0);this.timers.add(e)}};function q2(t,a){return t.length===a.length&&t.every((e,h)=>e===a[h])}function P0(t){let a=getComputedStyle(t).transform;return a&&a!=="none"?new DOMMatrixReadOnly(a).m41:0}function E0(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 O0(t){i("p fg:$s-muted",()=>i("#",`No panel at ${t.path}`))}var T0=200;x.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 1 auto;",".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 ${K}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 ${K}ms ease, visibility 0s;`,"&.s-nav-page-off":`transform:translateX(-100%) pointer-events:none visibility:hidden transition: transform ${K}ms ease, visibility 0s ${K}ms;`,".s-menu-item":"padding: $2 $3; min-height:3rem font-size:1.05em gap:$3"},[`@container (max-width: ${g1}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: ${$1}px)`]:{".s-content > .s-box":"margin-inline: calc(-1 * $3); r:0 border-inline:0"}});function q0(t={}){let a=t.nav,e=t.navPosition??"left",h=x.proxy({open:!1}),p=x.proxy({narrow:typeof document<"u"&&document.documentElement.clientWidth<=g1}),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 S1({routes:r,notFound:t.notFound,ancestors:t.ancestors,title:t.title,$shell:p}):null;o&&(x(()=>o.setColumns(t.columns)),x(()=>o.setLinkNavigation(t.linkNavigation)));let d=o&&t.home!==null?t.home??"/":null,n=()=>{t.maxWidth!=null&&x("max-width:",t.maxWidth)},c=x("div.s-main",t.attrs,()=>{x(()=>{a==null||!a.items.length?x("--s-nav-w: 0px"):x(`.s-nav-${e}`,`--s-nav-w: ${t.navWidth??T0}px`)}),x(()=>{(o!=null||t.title!=null||t.subtitle!=null||t.logo!=null||t.menu!=null||a!=null&&a.items.length>0)&&x("header.s-s.neutral",t.topbarAttrs,()=>{x("div.s-bar",()=>{x(n),x(()=>{if(p.narrow&&a!=null&&a.items.length){x("div.s-nav-trigger",()=>I0(a,h));return}t.logo!=null&&x(d!=null?"a.s-logo aria-label=Home":"div.s-logo",()=>{d!=null&&x("href=",d),M(t.logo)})}),x("div.s-titles",()=>{x(()=>{t.title!=null&&x(d!=null?"a.s-title":"div.s-title",()=>{d!=null&&x("href=",d),M(t.title)})}),D0(t,o,a,p)}),x(()=>{let z=p.narrow?o?.currentPanel?.actions:void 0,w=z??t.menu;w!=null&&x(`div.s-menu${z!=null?".s-panel-origin":""}`,()=>M(w))})})})}),x("div.s-body",()=>{x("div.s-body-inner",()=>{x(n),x(()=>{a==null||!a.items.length||(x(`nav.s-nav-panel.s-nav-${e}`,t.navAttrs,()=>{v1(a.items)}),x("div.s-nav-sep aria-hidden=true"))}),K0(t,o)}),x(()=>{a!=null&&a.items.length&&h.open&&F0(a,t.navPageAttrs,h,p)})}),x(()=>{t.footer!=null&&x("footer",()=>{x("div.s-bar",()=>{x(n),M(t.footer)})})})});return B0(c,p),a!=null&&m1(()=>a.items,()=>{h.open=!1}),(a!=null||o)&&x(()=>{let m=w=>()=>{B1()||L1()||w()},z=()=>c.querySelector(".s-nav-trigger button");h.open?P("Esc","Close the navigation",m(()=>{h.open=!1,z()?.focus()}),"global"):o&&o.currentPanelIndex>0?P("Esc","Back to the previous panel",m(()=>{o.back()}),"global"):P("Esc","Jump to the navigation",m(()=>{let w=c.querySelector(".s-nav-panel");w?.offsetParent!=null?(w.querySelector("[aria-current=page]")??w.querySelector(".s-menu-item:not([aria-disabled=true])"))?.focus():z()?.click()}),"global")}),o??void 0}var P1=null;function R0(){P1?.()}function D0(t,a,e,h){x(()=>{if(t.subtitle!=null&&(a==null||Z0(a,e,h))){x("div.s-subtitle",()=>M(t.subtitle));return}a?.drawCrumbs()})}function Z0(t,a,e){return e.narrow||a==null||t.panels.length>1?!1:N1(a.items)}function B0(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<=g1)});e.observe(t),x.clean(()=>e.disconnect())}function I0(t,a){s1({icon:t.button?.icon??(()=>x(()=>(a.open?c1:H1)())),ariaLabel:t.button?.ariaLabel??"Open navigation",attrs:t.button?.attrs,click:()=>{a.open=!a.open}})}function F0(t,a,e,h){let p=!1,r=()=>{p=!0,e.open=!1},o=x("nav.s-nav-page.s-s.neutral aria-label=Navigation create=s-nav-page-off destroy=s-nav-page-off",a,()=>v1(t.items,r));P1=r,x.clean(()=>{P1===r&&(P1=null)});let d=x.peek(t2,"path");x(()=>{t2.path!==d&&!X1(t2.path)&&r()});let n=o.closest(".s-main"),c=o.parentElement?.querySelector(":scope > .s-body-inner"),m=c?.querySelector(":scope > main");c?.setAttribute("inert",""),x(()=>{h.narrow||(e.open=!1)}),x.clean(()=>{c?.removeAttribute("inert"),p&&(m&&U0(m),n?.querySelector(".s-nav-trigger button")?.focus())}),requestAnimationFrame(()=>{document.body.contains(o)&&p1(o,".s-menu-item[aria-current=page]")})}function U0(t){t.classList.add("s-slide-in"),t.offsetWidth,t.classList.remove("s-slide-in")}function K0(t,a){if(a){a.drawColumns();return}let e=x("main",()=>{x("div.s-content",t.contentAttrs,()=>{M(t.content)})});N0(e)}function N0(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(),x.clean(()=>e.disconnect())}import T from"aberdeen";T.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 W0(t){j(t,(a,e)=>{T("div.s-select_wrap",()=>{T("select.s-input",t.inputAttrs,()=>{d1(t,a,e),T("change=",h=>{t.bind&&(t.bind.value=h.target.value)}),T(()=>{let h=typeof t.options=="function"?t.options():t.options,p=t.bind?.value??"";t.placeholder!=null&&T("option",()=>{T("value= disabled=true hidden=true"),p||T("selected=true"),T("#",t.placeholder)});for(let r of h){let o=typeof r=="string"?{value:r,label:r}:{value:r.value,label:r.label??r.value};T("option",()=>{T("value=",o.value),o.value===p&&T("selected=true"),T("#",o.label)})}})})})})}import N from"aberdeen";N.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 G0(t={}){let a=t.autoGrow!==!1;j(t,(e,h)=>{let p=N("textarea.s-input",t.inputAttrs,()=>{a?(N(".s-autoGrow"),N("input=",r=>{R2(r.currentTarget),t.input&&t.input(r)})):(N("rows=",t.rows??4),N("resize:",t.resize??"vertical"),t.input&&N("input=",t.input)),t.placeholder!=null&&N("placeholder=",t.placeholder),t.value!=null&&!t.bind&&N("value=",t.value),t.change&&N("change=",t.change),d1(t,e,h,t.bind)});a&&requestAnimationFrame(()=>R2(p))})}function R2(t){t.style.height="auto",t.style.height=`${t.scrollHeight}px`}export{_1 as addContextMenu,i1 as addTooltip,Q2 as alert,h0 as autocomplete,P as bindKey,o0 as box,Z as button,d0 as buttonChooser,J as buttonGroup,n0 as checkbox,P2 as closeFloatingMenu,R0 as closeNav,J2 as confirm,n1 as dialog,c0 as form,R as formatKey,h2 as getDarkMode,s1 as iconButton,B1 as isDialogOpen,L1 as isFloatingMenuOpen,q0 as main,w0 as menu,H0 as menuButton,Y2 as prompt,z1 as revealInStrip,C1 as scrollStrip,W0 as select,B2 as setDarkMode,t0 as setKeyHelp,j1 as showFloatingMenu,I1 as showKeyHelp,k0 as tabs,G0 as textarea,Z1 as textline,A1 as toast};
package/dist/theme.js CHANGED
@@ -212,7 +212,14 @@ A.insertGlobalCss({
212
212
  ".s-s.no-shadow": "box-shadow: none !important;",
213
213
  // Accent variants: the fill colour becomes the ink, over a soft self-tint
214
214
  // (`tonal`) or a transparent body with a colour edge (`outlined`).
215
- ".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);",
215
+ ".s-s:not(.neutral).tonal, .s-s:not(.neutral).outlined": {
216
+ "&": "--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);",
217
+ // The ink *is* the surface colour here, so the fill `code` and `pre` mix
218
+ // from their text/background pair would land invisibly on itself. The
219
+ // monospace face carries inline code on its own; a block keeps a hairline.
220
+ code: "background:transparent padding:0",
221
+ pre: "background:transparent border: 1px solid $s-faint;",
222
+ },
216
223
  ".s-s:not(.neutral).tonal": "background: color-mix(in srgb, $s-bg 15%, transparent); border: 1px solid $s-faint;",
217
224
  ".s-s:not(.neutral).outlined": "background: transparent; border: 1px solid color-mix(in srgb, $s-bg 45%, transparent);",
218
225
  // A surface inside an accent surface is forced back to filled: a translucent
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "staffa",
3
- "version": "0.18.2",
3
+ "version": "0.18.3",
4
4
  "description": "An opinionated component library for the Aberdeen reactive UI library.",
5
5
  "license": "ISC",
6
6
  "author": "",
@@ -4,6 +4,10 @@ A combobox with type-ahead filtering. Supports single or multi-select (chips),
4
4
  optional free-text entry, and full keyboard control (arrows, enter, escape,
5
5
  backspace-to-remove). Implements the ARIA combobox/listbox pattern.
6
6
 
7
+ The suggestion list is portalled to `document.body`, so a dialog or a
8
+ scrolling column can neither clip it nor grow a scrollbar around it. It hangs
9
+ off whichever side of the field has the room, and follows it as things move.
10
+
7
11
  **Signature:** `(opts: AutocompleteOptions) => void`
8
12
 
9
13
  **Parameters:**
@@ -1,5 +1,5 @@
1
1
  import A from "aberdeen";
2
- import { type Bindable, uniqueId } from "../core.js";
2
+ import { type Bindable, followAnchor, mountPortal, uniqueId } from "../core.js";
3
3
  import { type FieldOptions, drawField } from "./field.js";
4
4
 
5
5
  /** A selectable option: a bare string, or a `{ value, label }` pair. */
@@ -34,7 +34,6 @@ export interface AutocompleteOptions extends FieldOptions {
34
34
 
35
35
  A.insertGlobalCss({
36
36
  ".s-ac": {
37
- "&": "position:relative",
38
37
  // Same light inset field as `.s-input` (see field.ts), derived from the surface.
39
38
  "> .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;",
40
39
  "> .s-control:hover": "border-color: color-mix(in oklab, $s-text, $s-bg 55%);",
@@ -44,10 +43,14 @@ A.insertGlobalCss({
44
43
  ".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",
45
44
  ".s-chip > button:hover": "fg:$s-text background:$s-faint",
46
45
  "input": "flex:1 min-width:6ch border:0 background:transparent color:inherit outline:none padding:0.25em",
47
- // Background, border, radius and elevation come from the popup's
48
- // `.s-s.neutral.shadow` surface (see below).
49
- "> .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",
50
- "> .s-menu li": "margin:0",
46
+ },
47
+ // Background, border, radius and elevation come from the `.s-s.neutral.shadow`
48
+ // surface it carries; `place()` below sizes and positions it. Both of its
49
+ // classes are named here: standing in `<body>` rather than inside the field,
50
+ // it would otherwise lose to theme.ts's flow margins on `ul` and `li`.
51
+ ".s-ac-menu.s-s": {
52
+ "&": "position:fixed max-height:15rem overflow-y:auto list-style:none p:$1 margin:0",
53
+ li: "margin:0",
51
54
  ".s-option": "padding: 0.45em 0.6em; r:6px cursor:pointer transition: background 0.1s;",
52
55
  ".s-option[aria-selected=true]": "background: color-mix(in srgb, $s-text 10%, transparent);",
53
56
  ".s-add": "fg:$s-accent font-style:italic",
@@ -55,6 +58,58 @@ A.insertGlobalCss({
55
58
  },
56
59
  });
57
60
 
61
+ /** The list one {@link autocomplete} currently has up. */
62
+ interface AcPopup {
63
+ /** The `<ul>`'s id, which the field points `aria-controls` at — and its identity here. */
64
+ id: string;
65
+ /** The field's control box: the list matches its width and hangs off it. */
66
+ anchor: HTMLElement;
67
+ /** Over the dialog the field stands in, or under the dialog layer altogether. */
68
+ zIndex: number;
69
+ /** Draws the `<li>`s, reading the field's own state from its closure. */
70
+ draw: () => void;
71
+ }
72
+
73
+ // Only one list is up at a time — it belongs to whichever field has focus — so
74
+ // one portal at the end of <body> serves them all. Drawn inside the field, the
75
+ // list would be clipped by a dialog or a scrolling column, and would stretch
76
+ // that scroller's bar to reach it.
77
+ const $popup = A.proxy<{ cur: AcPopup | null }>({ cur: null });
78
+
79
+ /** Hang the list under the field — or over it, when that's where the room is. */
80
+ function place(el: HTMLElement, r: DOMRect): void {
81
+ const gap = 4, edge = 8;
82
+ // Measured at the stylesheet's own cap, so the flip is decided on the height
83
+ // the list wants, not on whatever the last placement clamped it to.
84
+ el.style.maxHeight = "";
85
+ const want = el.offsetHeight;
86
+ const below = window.innerHeight - r.bottom - gap - edge;
87
+ const above = r.top - gap - edge;
88
+ const up = want > below && above > below;
89
+ el.style.left = `${r.left}px`;
90
+ el.style.width = `${r.width}px`;
91
+ el.style.maxHeight = `${Math.min(want, Math.max(up ? above : below, 60))}px`;
92
+ el.style.top = up ? "auto" : `${r.bottom + gap}px`;
93
+ el.style.bottom = up ? `${window.innerHeight - r.top + gap}px` : "auto";
94
+ }
95
+
96
+ mountPortal(() => {
97
+ const p = $popup.cur;
98
+ if (!p) return;
99
+ let sizeChanged: (() => void) | undefined;
100
+
101
+ const el = A("ul.s-ac-menu.s-s.neutral.shadow role=listbox", `id=${p.id} z-index:${p.zIndex}`, () => {
102
+ // A press in the list must not blur the field: the click that follows is
103
+ // what commits, and dragging the scrollbar has to keep it open too.
104
+ A("mousedown=", (e: Event) => e.preventDefault());
105
+ p.draw();
106
+ // Re-run as you type, with the rows; the list's height changes with them.
107
+ sizeChanged?.();
108
+ }) as HTMLElement;
109
+
110
+ sizeChanged = followAnchor(p.anchor, (r) => place(el, r));
111
+ });
112
+
58
113
  function normOption(o: AutocompleteOptionInput): AcOption {
59
114
  return typeof o === "string" ? { value: o, label: o } : { value: o.value, label: o.label ?? o.value };
60
115
  }
@@ -64,6 +119,10 @@ function normOption(o: AutocompleteOptionInput): AcOption {
64
119
  * optional free-text entry, and full keyboard control (arrows, enter, escape,
65
120
  * backspace-to-remove). Implements the ARIA combobox/listbox pattern.
66
121
  *
122
+ * The suggestion list is portalled to `document.body`, so a dialog or a
123
+ * scrolling column can neither clip it nor grow a scrollbar around it. It hangs
124
+ * off whichever side of the field has the room, and follows it as things move.
125
+ *
67
126
  * @example
68
127
  * ```ts
69
128
  * // Single select from a fixed list
@@ -133,13 +192,40 @@ export function autocomplete(opts: AutocompleteOptions): void {
133
192
  opts.bind.value = arr.filter((v) => v !== value);
134
193
  };
135
194
 
195
+ let inputEl: HTMLInputElement | undefined;
196
+
197
+ /** The list's rows. Runs in the body portal, on this field's state. */
198
+ const drawList = () => {
199
+ const list = filtered();
200
+ const q = $st.query.trim();
201
+ const showAdd = opts.allowCustom !== false && q !== "" && !list.some((o) => o.label.toLowerCase() === q.toLowerCase());
202
+
203
+ list.forEach((option, i) => {
204
+ A("li.s-option role=option", `id=${menuId}-opt-${i}`, () => {
205
+ A(() => A("aria-selected=", $st.active === i ? "true" : "false"));
206
+ A("#", option.label);
207
+ A("click=", () => commit(option.value, inputEl));
208
+ A("mousemove=", () => {
209
+ $st.active = i;
210
+ });
211
+ });
212
+ });
213
+ if (showAdd) {
214
+ A("li.s-option.s-add role=option", () => {
215
+ A("#", `Add "${q}"`);
216
+ A("click=", () => commit(q, inputEl));
217
+ });
218
+ }
219
+ if (list.length === 0 && !showAdd) {
220
+ A("li.s-empty #No matches");
221
+ }
222
+ };
223
+
136
224
  drawField(opts, (id, isInvalid) => {
137
225
  A("div.s-ac", opts.inputAttrs, () => {
138
226
  A(() => A("aria-invalid=", isInvalid() ? "true" : "false"));
139
227
 
140
- let inputEl: HTMLInputElement | undefined;
141
-
142
- A("div.s-control", () => {
228
+ const controlEl = A("div.s-control", () => {
143
229
  A("click=", () => inputEl?.focus());
144
230
 
145
231
  // Chips for multi-select.
@@ -185,38 +271,16 @@ export function autocomplete(opts: AutocompleteOptions): void {
185
271
  });
186
272
  A("keydown=", (e: KeyboardEvent) => onKey(e, inputEl));
187
273
  }) as HTMLInputElement;
188
- });
274
+ }) as HTMLElement;
189
275
 
190
- // The suggestions popup.
276
+ // Hand the list to the portal for as long as it is up. Its layer clears
277
+ // the dialog the field sits in, but stays under one that may open over
278
+ // it — a field on the page can't paint across a modal.
191
279
  A(() => {
192
280
  if (!$st.open) return;
193
- const list = filtered();
194
- const q = $st.query.trim();
195
- const showAdd = opts.allowCustom !== false && q !== "" && !list.some((o) => o.label.toLowerCase() === q.toLowerCase());
196
-
197
- A("ul.s-menu.s-s.neutral.shadow role=listbox", `id=${menuId}`, () => {
198
- list.forEach((option, i) => {
199
- A("li.s-option role=option", `id=${menuId}-opt-${i}`, () => {
200
- A(() => A("aria-selected=", $st.active === i ? "true" : "false"));
201
- A("#", option.label);
202
- A("mousedown=", (e: Event) => e.preventDefault());
203
- A("click=", () => commit(option.value, inputEl));
204
- A("mousemove=", () => {
205
- $st.active = i;
206
- });
207
- });
208
- });
209
- if (showAdd) {
210
- A("li.s-option.s-add role=option", () => {
211
- A("#", `Add "${q}"`);
212
- A("mousedown=", (e: Event) => e.preventDefault());
213
- A("click=", () => commit(q, inputEl));
214
- });
215
- }
216
- if (list.length === 0 && !showAdd) {
217
- A("li.s-empty #No matches");
218
- }
219
- });
281
+ const zIndex = controlEl.closest(".s-dialog") ? 350 : 150;
282
+ $popup.cur = { id: menuId, anchor: controlEl, zIndex, draw: drawList };
283
+ A.clean(() => { if ($popup.cur?.id === menuId) $popup.cur = null; });
220
284
  });
221
285
 
222
286
  // Hidden inputs so the selection participates in native FormData.
@@ -1,6 +1,6 @@
1
1
  import A from "aberdeen";
2
2
  import { matchCurrent, current as currentRoute, go } from "aberdeen/route";
3
- import { type Slot, type Attributes, drawSlot, mountPortal, focusFirst } from "../core.js";
3
+ import { type Slot, type Attributes, drawSlot, followAnchor, 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, type ButtonOptions } from "./button.js";
6
6
  import { toast } from "./toast.js";
@@ -647,7 +647,7 @@ export function closeFloatingMenu(anchor?: HTMLElement): void {
647
647
  if (isFloatingMenuOpen(anchor)) closeFloating();
648
648
  }
649
649
 
650
- function positionMenu(menuEl: HTMLElement, rect: { left: number; right: number; top: number; bottom: number }): void {
650
+ function positionMenu(menuEl: HTMLElement, rect: DOMRect): void {
651
651
  const mw = menuEl.offsetWidth, mh = menuEl.offsetHeight;
652
652
  const vw = window.innerWidth, vh = window.innerHeight;
653
653
  const gap = 4;
@@ -717,16 +717,13 @@ mountPortal(() => {
717
717
  document.removeEventListener("keydown", onKey, true);
718
718
  });
719
719
 
720
- // Position after layout, then focus the first enabled item.
720
+ // At the supplied point when given — the pointer location for a context menu
721
+ // — otherwise below the anchor.
722
+ followAnchor(f.at ? new DOMRect(f.at.x, f.at.y, 0, 0) : f.anchor, (rect) => positionMenu(menuEl, rect));
723
+ // Once it can take focus: the current-page item if there is one, else the
724
+ // first focusable element (covers custom slot content, not just `.s-menu-item`s).
721
725
  requestAnimationFrame(() => {
722
- if (!document.body.contains(menuEl)) return;
723
- // Position at the supplied point (a zero-size rect) when given — e.g. the
724
- // pointer location for a context menu — otherwise below the anchor.
725
- const rect = f.at ? { left: f.at.x, right: f.at.x, top: f.at.y, bottom: f.at.y } : f.anchor.getBoundingClientRect();
726
- positionMenu(menuEl, rect);
727
- // Focus the current-page item if there is one, else the first focusable
728
- // element (covers custom slot content, not just `.s-menu-item`s).
729
- focusFirst(menuEl, ".s-menu-item[aria-current=page]");
726
+ if (document.body.contains(menuEl)) focusFirst(menuEl, ".s-menu-item[aria-current=page]");
730
727
  });
731
728
  });
732
729
 
@@ -1,5 +1,5 @@
1
1
  import A from "aberdeen";
2
- import { type Slot, type Attributes, drawSlot, mountPortal } from "../core.js";
2
+ import { type Slot, type Attributes, drawSlot, followAnchor, mountPortal } from "../core.js";
3
3
 
4
4
  /** Options for {@link addTooltip}. */
5
5
  export interface TooltipOptions {
@@ -32,11 +32,6 @@ A.insertGlobalCss({
32
32
  const $ttActive = A.proxy<{ opts: TooltipOptions; anchor: HTMLElement } | undefined>(undefined);
33
33
  let hideTimer: ReturnType<typeof setTimeout> | null = null;
34
34
 
35
- // Hide tooltip when the page scrolls (anchor has moved).
36
- if (typeof window !== "undefined") {
37
- window.addEventListener("scroll", () => { $ttActive.value = undefined; }, { capture: true, passive: true });
38
- }
39
-
40
35
  function computePos(rect: DOMRect, tipW: number, tipH: number, placement: string): { x: number; y: number } {
41
36
  const gap = 7;
42
37
  const vw = window.innerWidth;
@@ -84,7 +79,7 @@ mountPortal(() => {
84
79
  const { opts, anchor } = active;
85
80
  const placement = opts.placement ?? "top";
86
81
 
87
- const tipEl = A("div.s-tt-tip.s-s.neutral.shadow role=tooltip visibility:hidden", opts.attrs, () => {
82
+ const tipEl = A("div.s-tt-tip.s-s.neutral.shadow role=tooltip", opts.attrs, () => {
88
83
  A("mouseenter=", () => {
89
84
  if (hideTimer) { clearTimeout(hideTimer); hideTimer = null; }
90
85
  });
@@ -92,13 +87,16 @@ mountPortal(() => {
92
87
  drawSlot(opts.tip);
93
88
  }) as HTMLElement;
94
89
 
95
- requestAnimationFrame(() => {
96
- if (!document.body.contains(tipEl)) return;
97
- const rect = anchor.getBoundingClientRect();
90
+ followAnchor(anchor, (rect) => {
91
+ // Out of the viewport, or on a panel that slid off and went inert: nothing
92
+ // left to explain, and no `mouseleave` is coming to say so.
93
+ if (rect.bottom < 0 || rect.top > window.innerHeight || rect.right < 0 || rect.left > window.innerWidth || anchor.closest("[inert]")) {
94
+ $ttActive.value = undefined;
95
+ return;
96
+ }
98
97
  const { x, y } = computePos(rect, tipEl.offsetWidth, tipEl.offsetHeight, placement);
99
98
  tipEl.style.left = x + "px";
100
99
  tipEl.style.top = y + "px";
101
- tipEl.style.visibility = "";
102
100
  });
103
101
  });
104
102
 
package/src/core.ts CHANGED
@@ -114,3 +114,36 @@ export function focusFirst(container: HTMLElement, prefer?: string): boolean {
114
114
  export function mountPortal(draw: () => void): void {
115
115
  queueMicrotask(() => A(draw));
116
116
  }
117
+
118
+ /** Something scrolled, the window resized, or an animation began: an anchor may be on the move. */
119
+ const WAKE_EVENTS = ["scroll", "resize", "transitionstart", "animationstart"];
120
+
121
+ /**
122
+ * Keep a `position:fixed` overlay glued to its anchor. `place` gets the anchor's
123
+ * viewport rect right away, and again whenever it changes: frame by frame while
124
+ * the anchor is on the move — riding a dialog's opening animation or a panel's
125
+ * slide, or scrolling — and not at all once it has been at rest for half a
126
+ * second, until one of the events that precede any movement wakes the loop. So
127
+ * an overlay left standing open doesn't keep the page awake. Stops with the
128
+ * current scope; a point (a `DOMRect` of no size) is followed like an element.
129
+ *
130
+ * Returns a function to call when the overlay's own size changed (its rows
131
+ * redrawn, say), so it gets placed again.
132
+ */
133
+ export function followAnchor(anchor: Element | DOMRect, place: (rect: DOMRect) => void): () => void {
134
+ let placedAt = "", raf = 0, still = 0;
135
+ const track = () => {
136
+ const r = anchor instanceof Element ? anchor.getBoundingClientRect() : anchor;
137
+ const at = `${r.left} ${r.top} ${r.bottom} ${r.width}`;
138
+ if (at !== placedAt) { placedAt = at; place(r); still = 0; }
139
+ raf = ++still > 30 ? 0 : requestAnimationFrame(track);
140
+ };
141
+ const wake = () => { still = 0; if (!raf) track(); };
142
+ for (const ev of WAKE_EVENTS) window.addEventListener(ev, wake, true);
143
+ A.clean(() => {
144
+ cancelAnimationFrame(raf);
145
+ for (const ev of WAKE_EVENTS) window.removeEventListener(ev, wake, true);
146
+ });
147
+ track();
148
+ return () => { placedAt = ""; wake(); };
149
+ }
package/src/theme.ts CHANGED
@@ -229,8 +229,14 @@ A.insertGlobalCss({
229
229
 
230
230
  // Accent variants: the fill colour becomes the ink, over a soft self-tint
231
231
  // (`tonal`) or a transparent body with a colour edge (`outlined`).
232
- ".s-s:not(.neutral).tonal, .s-s:not(.neutral).outlined":
233
- "--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);",
232
+ ".s-s:not(.neutral).tonal, .s-s:not(.neutral).outlined": {
233
+ "&": "--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);",
234
+ // The ink *is* the surface colour here, so the fill `code` and `pre` mix
235
+ // from their text/background pair would land invisibly on itself. The
236
+ // monospace face carries inline code on its own; a block keeps a hairline.
237
+ code: "background:transparent padding:0",
238
+ pre: "background:transparent border: 1px solid $s-faint;",
239
+ },
234
240
  ".s-s:not(.neutral).tonal":
235
241
  "background: color-mix(in srgb, $s-bg 15%, transparent); border: 1px solid $s-faint;",
236
242
  ".s-s:not(.neutral).outlined":