minerva-design 1.19.2 → 1.19.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.
- package/CHANGELOG.md +10 -0
- package/dist/dom/dismissable-layer.d.cts +7 -5
- package/dist/dom/dismissable-layer.d.ts +7 -5
- package/dist/dom/focus-scope.d.cts +3 -2
- package/dist/dom/focus-scope.d.ts +3 -2
- package/dist/dom/index.cjs +2 -2
- package/dist/dom/index.cjs.map +1 -1
- package/dist/dom/index.js +398 -374
- package/dist/dom/index.js.map +1 -1
- package/dist/dom/internal/shared-state.d.cts +13 -0
- package/dist/dom/internal/shared-state.d.ts +13 -0
- package/dist/taro/{components-R1m1BIE0.js → components-BUS7TwNX.js} +1 -1
- package/dist/taro/icons.js +1 -1
- package/dist/taro/index.js +1 -1
- package/dist/taro/monaco.js +1 -1
- package/dist/uni/AutoComplete.vue +33 -25
- package/dist/web-components/cdn/minerva.js +414 -414
- package/dist/web-components/cdn/minerva.js.map +1 -1
- package/package.json +1 -1
package/dist/dom/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["offset","offsetMiddleware","flip","flipMiddleware","shift","shiftMiddleware","sizeMiddleware","arrowMiddleware","canUseDOM","getOwnerDocument","node","getOwnerWindow","isHTMLElement","value","win","getActiveElement","active","root","contains","parent","child","isShadowRoot","flat","flatParentNode","shadow","slotOf","getEventTarget","path","event","FOCUSABLE_SELECTOR","isDisabled","el","fieldset","legend","assigned","name","slot","flatParent","isHiddenByStyle","summary","visibility","isFocusable","getTabIndex","attr","isTabbable","collect","out","visit","renderRoot","container","getFocusables","all","options","asRadio","input","radioGroupOf","radio","getTabbables","tabbables","radioGroups","chosen","scope","groups","current","positive","item","a","b","natural","focusElement","doc","previous","focused","focusFirst","candidate","candidates","FOCUS_SCOPE_MOUNT_EVENT","FOCUS_SCOPE_UNMOUNT_EVENT","scopeStack","pushScope","removeScope","entry","index","runAutoFocusHandler","type","handler","withoutLinksFirst","isLink","items","createFocusScope","userPaused","stackPaused","previouslyFocused","lastFocused","addedTabIndex","observer","isPaused","paused","focusInside","onFocusIn","trapped","target","onFocusOut","next","onKeyDown","loop","first","last","onMutations","resolveAutoFocusTarget","autoFocus","ObserverCtor","onMountAutoFocus","now","restoreFocus","onUnmountAutoFocus","getFocusScopeCount","ESCAPE_CONSUMER_ATTRIBUTE","layers","documents","findLayer","layer","parentOf","l","isAncestor","seen","p","ancestor","isInside","branch","other","highestModalIndex","i","isPointerEventsEnabled","setInlinePointerEvents","style","syncPointerEvents","modalIndex","state","hasModal","body","enable","runHandlers","wasPrevented","cancelled","preventedUncancelable","restore","native","handlers","dismissOutside","kind","attachDocument","existing","top","pendingClick","onPointerDown","detachDocument","createDismissableLayer","element","implicitParent","destroyed","handle","getLayerStack","SCROLLBAR_GAP_VAR","locks","getScrollbarGap","gap","applyLock","html","isPage","saved","computed","lockScroll","released","isScrollLocked","KEEP_VISIBLE_SELECTOR","IGNORED_TAGS","counters","preexisting","hasAttribute","attribute","hide","count","unhide","hideOthers","list","targets","targetSet","keep","hidden","walk","undone","defaultIsDisabled","defaultGetText","createRovingFocus","typeahead","createTypeahead","getItems","itemSelector","sync","isItemDisabled","activate","changed","focus","onActiveChange","itemFromEvent","currentIndex","getNextIndex","focusOnMove","getItemText","opts","nearestInRow","origin","from","centerX","best","bestRow","bestDx","elements","rect","dy","direction","dx","composedParent","getDirection","dir","resolveDirection","explicit","logicalArrowKey","key","centerInScroller","max","scroller","view","delta","min","upper","clamped","getPortalContainer","PORTAL_HOST_ATTRIBUTE","createPortalHost","host","VIEWPORT_PADDING","ARROW_PADDING","buildMiddleware","offset$1","flip$1","shift$1","mainAxis","crossAxis","middleware","offset","flip","shift","limitShift","sizing","matchAnchorWidth","fitViewportHeight","size","availableWidth","availableHeight","rects","arrowElement","arrow","computeAnchoredPosition","sizeData","result","computePosition","reference","floating","arrowData","autoPosition","stop","autoUpdate","onUpdate","parsePlacement","side","align","placement","toPlacement","CAMEL_TO_PLACEMENT","map","fromCamelPlacement","toCamelPlacement","c","getTransformOrigin","alignPercent","vertical","cross","arrowSize","main","applyPosition","isPointInPolygon","point","inside","j","polygon","xi","yi","xj","yj","y","x","getGraceArea","exitPoint","padding","createPointerGrace","area","startedAt","expired","timeout","targetRect","maxTime","part","getExitAnimationDuration","animation","transition","waitForExitAnimation","duration","events","done","onEnd","timer","resolve","getAdjacentTabbable","NON_TEXT_INPUT_TYPES","isEditableTarget","INTERACTIVE_SELECTOR","role","isInteractiveEventTarget","DASHBOARD_COLUMN_ATTRIBUTE","DASHBOARD_CARD_ATTRIBUTE","MOUSE_THRESHOLD","TOUCH_DELAY","TOUCH_TOLERANCE","EDGE","MAX_SPEED","text","dashboardDataAdapter","ownColumn","parts","column","names","adapter","title","card","empty","visuallyHidden","createDashboardDrag","drag","pending","hint","live","line","frame","keyedColumns","keyedCards","layout","columnElement","cardOf","cardFromPath","ensureLayer","refresh","cancel","toggle","announce","position","message","dashboardSlots","box","accept","isDashboardNoop","move","targetAt","distance","d","midpoints","dashboardCardMove","dashboardInsertIndex","paint","others","left","width","placeGhost","lift","pointer","mode","ghost","onDocumentKeyDown","preventDefault","autoScroll","onCardBlur","finish","stopPointer","drop","attempt","onPointerMove","onPointerUp","onPointerCancel","onTouchMove","startPointerDrag","id","startsOnControl","touch","moved","retarget","same","swallowClick","edgeScroll","start","end","axis","edge","step","before","scrolled","reveal","outer","inner","action","dashboardKeyAction","dashboardKeyboardTarget","neighbor","onDragStart","KANBAN_COLUMN_ATTRIBUTE","KANBAN_CARD_ATTRIBUTE","kanbanDataAdapter","createKanbanDrag","fetchTextWith","response","url","crossOrigin","textTrackCueText","cues","track","lines","cue","cueText","bindMediaCaptions","media","textTrackOf","setMode","emit","onText","selected","tracks","cleanups","on","listener","disposed","fallback","update","activeCueText","loadCaptions","loaded","textTrack","isSrtSource","onCueChange","show","cleanup","codeRoot","boundaries","selection","composed","textOffset","range","total","clickedCodeMark","marks","getCodeSelectionRange","source","points","code","DARK_SCHEME_QUERY","getSystemTheme","isBilingualTheme","theme","resolveTheme","themes","systemTheme","isThemeName","appliedKeys","generateCSSVariables","themeStyles","themeKeys","applyThemeStyles","THEME_COOKIE_NAME","PALETTE_COOKIE_NAME","THEME_COOKIE_MAX_AGE","parseThemeCookie","isThemeMode","parsePaletteCookie","isPalette","readCookieValue","cookieHeader","raw","parseThemeCookies","defaults","serializeThemeCookie","escapeRegExp","createThemeInitScript","defaultTheme","fallbackPalette","presetPalette","defaultPalette","design","designAttributes","PALETTES","THEME_INIT_SCRIPT","K","utf8","bytes","char","sha256","bitLength","high","word","h","w","rotr","n","s0","s1","e","f","g","hh","ch","t1","t2","BASE64","base64","cspHash","script","THEME_INIT_SCRIPT_HASH","applyDesignAttributes","attributes","DESIGN_ATTRIBUTES","primaryColorTheme","primaryColorTokens","pair","base","tokenToCss","primaryColorCss","block","selector"],"sources":["../../../dom/src/dom.ts","../../../dom/src/focus-scope.ts","../../../dom/src/dismissable-layer.ts","../../../dom/src/scroll-lock.ts","../../../dom/src/hide-others.ts","../../../dom/src/roving-focus.ts","../../../dom/src/nearest-in-row.ts","../../../dom/src/direction.ts","../../../dom/src/center-in-scroller.ts","../../../dom/src/portal.ts","../../../dom/src/positioning.ts","../../../dom/src/pointer-grace.ts","../../../dom/src/presence.ts","../../../dom/src/adjacent-tabbable.ts","../../../dom/src/editable-target.ts","../../../dom/src/interactive-target.ts","../../../dom/src/dashboard-drag.ts","../../../dom/src/media-captions.ts","../../../dom/src/code-selection.ts","../../../dom/src/theme/apply-theme.ts","../../../dom/src/theme/cookies.ts","../../../dom/src/theme/csp.ts","../../../dom/src/theme/design-attributes.ts","../../../dom/src/theme/primary-color.ts"],"sourcesContent":["/**\n * Small DOM helpers shared by every primitive. All of them are safe to import\n * on the server: nothing touches `window` / `document` until called.\n */\n\n/** `true` when running in a browser-like environment (window + document). */\nexport function canUseDOM(): boolean {\n return (\n typeof window !== \"undefined\" &&\n typeof document !== \"undefined\" &&\n typeof document.createElement === \"function\"\n );\n}\n\n/**\n * Returns the document owning `node` (or the node itself when it is a\n * Document). Falls back to the global `document`.\n */\nexport function getOwnerDocument(node?: Node | null): Document {\n if (node) {\n if (node.nodeType === 9) return node as Document;\n if (node.ownerDocument) return node.ownerDocument;\n }\n return document;\n}\n\n/** The window owning `node` (falls back to the global `window`). */\nexport function getOwnerWindow(node?: Node | null): Window & typeof globalThis {\n return (getOwnerDocument(node).defaultView ?? window) as Window &\n typeof globalThis;\n}\n\n/** Whether `value` is an `HTMLElement` (realm-safe: works across iframes). */\nexport function isHTMLElement(value: unknown): value is HTMLElement {\n if (!value || typeof value !== \"object\") return false;\n const node = value as Node;\n if (node.nodeType !== 1) return false;\n const win = node.ownerDocument?.defaultView;\n if (win && value instanceof win.HTMLElement) return true;\n return typeof HTMLElement !== \"undefined\" && value instanceof HTMLElement;\n}\n\n/**\n * The deepest focused element, piercing open shadow roots.\n * @param root - Document or shadow root to start from. @default document\n */\nexport function getActiveElement(\n root: Document | ShadowRoot = document,\n): Element | null {\n let active = root.activeElement;\n while (active?.shadowRoot?.activeElement) {\n active = active.shadowRoot.activeElement;\n }\n return active;\n}\n\n/**\n * Like `Node.contains`, but also returns `true` when `child` lives inside a\n * shadow tree hosted (at any depth) by `parent`, or is rendered inside\n * `parent` through a `<slot>` (flat tree: light DOM content slotted into a\n * shadow tree, e.g. the body of a custom element dialog).\n */\nexport function contains(\n parent: Node | null | undefined,\n child: Node | null | undefined,\n): boolean {\n if (!parent || !child) return false;\n let node: Node | null = child;\n while (node) {\n if (parent === node || parent.contains(node)) return true;\n const root = node.getRootNode();\n node = isShadowRoot(root) ? root.host : null;\n }\n for (let flat = flatParentNode(child); flat; flat = flatParentNode(flat)) {\n if (flat === parent) return true;\n }\n return false;\n}\n\n/** Parent of `node` in the flat tree (slot of slotted content, host of a shadow root). */\nfunction flatParentNode(node: Node): Node | null {\n const parent = node.parentNode;\n if (!parent) return null;\n if (isShadowRoot(parent)) return parent.host;\n const shadow = (parent as Element).shadowRoot;\n return shadow ? slotOf(node, shadow) : parent;\n}\n\nfunction isShadowRoot(node: Node): node is ShadowRoot {\n return node.nodeType === 11 && \"host\" in node && !!(node as ShadowRoot).host;\n}\n\n/** The event's real target, piercing open shadow roots (`composedPath()[0]`). */\nexport function getEventTarget(event: Event): EventTarget | null {\n const path = event.composedPath?.();\n return (path && path.length > 0 ? path[0] : event.target) ?? null;\n}\n\n// Written without a top-level call so bundlers can drop it when unused.\nconst FOCUSABLE_SELECTOR =\n \"a[href],area[href],button,input,select,textarea,iframe,object,embed,\" +\n \"audio[controls],video[controls],summary,[contenteditable],[tabindex]\";\n\nfunction isDisabled(el: Element): boolean {\n if ((el as HTMLButtonElement).disabled === true) return true;\n if (el.hasAttribute(\"disabled\") && \"disabled\" in el) return true;\n // A disabled <fieldset> disables its controls, except inside its first legend.\n const fieldset = el.closest(\"fieldset[disabled]\");\n if (fieldset && \"disabled\" in el) {\n const legend = fieldset.querySelector(\":scope > legend\");\n if (!legend || !legend.contains(el)) return true;\n }\n return false;\n}\n\n/** Slot of a shadow root that `node` (a light child of its host) renders in. */\nfunction slotOf(node: Node, shadow: ShadowRoot): HTMLSlotElement | null {\n const assigned = (node as Element | Text).assignedSlot;\n if (assigned) return assigned;\n // DOMs without slot assignment (e.g. happy-dom): match by slot name.\n const name =\n node.nodeType === 1 ? ((node as Element).getAttribute(\"slot\") ?? \"\") : \"\";\n return (\n Array.from(shadow.querySelectorAll(\"slot\")).find(\n (slot) => (slot.getAttribute(\"name\") ?? \"\") === name,\n ) ?? null\n );\n}\n\n/**\n * Parent in the flat (rendered) tree: the slot an element is assigned to,\n * else its parent element, else the host of its shadow root. `false` when\n * the element is a light child of a shadow host that is not slotted (not\n * rendered at all).\n */\nfunction flatParent(el: Element): Element | null | false {\n const parent = el.parentElement;\n if (parent?.shadowRoot) return slotOf(el, parent.shadowRoot) ?? false;\n if (parent) return parent;\n const root = el.parentNode;\n return root && isShadowRoot(root) ? root.host : null;\n}\n\nfunction isHiddenByStyle(el: Element): boolean {\n const win = el.ownerDocument.defaultView;\n if (!win) return false;\n // `hidden` / display:none on any ancestor (in the flat tree, so through\n // slots and shadow roots) removes the whole subtree.\n for (let node: Element | null = el; node;) {\n if ((node as HTMLElement).hidden) return true;\n if (win.getComputedStyle(node).display === \"none\") return true;\n // closed <details>: only its <summary> is rendered\n if (\n node !== el &&\n node.tagName === \"DETAILS\" &&\n !(node as HTMLDetailsElement).open\n ) {\n const summary = node.querySelector(\":scope > summary\");\n if (!summary || !summary.contains(el)) return true;\n }\n const parent = flatParent(node);\n if (parent === false) return true;\n node = parent;\n }\n const visibility = win.getComputedStyle(el).visibility;\n return visibility === \"hidden\" || visibility === \"collapse\";\n}\n\n/**\n * Whether `el` can receive focus (programmatically or by pointer): a\n * focusable element that is not disabled, `inert`, hidden\n * (`hidden`, `display: none`, `visibility: hidden`, closed `<details>`)\n * nor an `<input type=\"hidden\">`.\n */\nexport function isFocusable(el: Element): boolean {\n if (!el.matches(FOCUSABLE_SELECTOR)) return false;\n if (el.matches(\"[contenteditable='false']\") && !el.hasAttribute(\"tabindex\"))\n return false;\n if (el.tagName === \"INPUT\" && (el as HTMLInputElement).type === \"hidden\")\n return false;\n if (\n el.tagName === \"SUMMARY\" &&\n el.parentElement?.tagName === \"DETAILS\" &&\n el.parentElement.querySelector(\":scope > summary\") !== el\n )\n return false;\n if (isDisabled(el)) return false;\n if (el.closest(\"[inert]\")) return false;\n return !isHiddenByStyle(el);\n}\n\nfunction getTabIndex(el: Element): number {\n const attr = el.getAttribute(\"tabindex\");\n if (attr !== null && attr.trim() !== \"\") {\n const value = Number.parseInt(attr, 10);\n if (!Number.isNaN(value)) return value;\n }\n return 0;\n}\n\n/** Whether `el` is reachable with the Tab key (focusable, tabindex >= 0). */\nexport function isTabbable(el: Element): boolean {\n return isFocusable(el) && getTabIndex(el) >= 0;\n}\n\n/**\n * Collects candidates in rendering (flat tree) order: open shadow roots are\n * walked instead of their host's light children, and a `<slot>` contributes\n * its assigned elements (or its fallback content when nothing is assigned).\n * Light children of a shadow host that are not slotted are not rendered, so\n * they are skipped, like the browser's sequential focus navigation does.\n */\nfunction collect(root: ParentNode, out: Element[]): void {\n for (const el of Array.from(root.children)) visit(el, out);\n}\n\nfunction visit(el: Element, out: Element[]): void {\n out.push(el);\n if (el.shadowRoot) {\n collect(el.shadowRoot, out);\n return;\n }\n if (el.tagName === \"SLOT\") {\n const assigned =\n (el as HTMLSlotElement).assignedElements?.({ flatten: true }) ?? [];\n if (assigned.length > 0) {\n for (const child of assigned) visit(child, out);\n return;\n }\n }\n collect(el, out);\n}\n\n/** The node whose descendants are rendered: a host's open shadow root. */\nfunction renderRoot(container: Element | ShadowRoot): ParentNode {\n return (container as Element).shadowRoot ?? container;\n}\n\nexport interface TabbableOptions {\n /**\n * Keep only one radio per group (checked one, or the first when none is\n * checked), like the browser's Tab order. @default true\n */\n radioGroups?: boolean;\n /** Also consider the container itself. @default false */\n includeContainer?: boolean;\n}\n\n/**\n * Focusable elements inside `container` (flat tree order: open shadow roots\n * and slotted content included; a shadow host is walked through its shadow\n * root), including `tabindex=\"-1\"` ones.\n */\nexport function getFocusables(\n container: Element | ShadowRoot,\n options: Pick<TabbableOptions, \"includeContainer\"> = {},\n): HTMLElement[] {\n const all: Element[] = [];\n if (options.includeContainer && container.nodeType === 1) {\n all.push(container as Element);\n }\n collect(renderRoot(container), all);\n return all.filter(\n (el): el is HTMLElement => isHTMLElement(el) && isFocusable(el),\n );\n}\n\nfunction asRadio(el: Element): HTMLInputElement | null {\n const input = el as HTMLInputElement;\n return input.tagName === \"INPUT\" && input.type === \"radio\" && input.name\n ? input\n : null;\n}\n\n/** Radios of one group: same name within the same form (or root node). */\nfunction radioGroupOf(radio: HTMLInputElement): [object, string] {\n return [radio.form ?? radio.getRootNode(), radio.name];\n}\n\n/**\n * Elements reachable with Tab inside `container`, in Tab order: positive\n * `tabindex` first (ascending), then `tabindex=0` / natural order.\n * Excludes disabled, hidden, inert and `tabindex=\"-1\"` elements, and\n * collapses radio groups to their checked (or first) radio.\n */\nexport function getTabbables(\n container: Element | ShadowRoot,\n options: TabbableOptions = {},\n): HTMLElement[] {\n const { radioGroups = true } = options;\n let tabbables = getFocusables(container, options).filter(\n (el) => getTabIndex(el) >= 0,\n );\n\n if (radioGroups) {\n // scope (form / root) -> group name -> chosen radio\n const chosen = new Map<object, Map<string, HTMLInputElement>>();\n for (const el of tabbables) {\n const radio = asRadio(el);\n if (!radio) continue;\n const [scope, name] = radioGroupOf(radio);\n let groups = chosen.get(scope);\n if (!groups) chosen.set(scope, (groups = new Map()));\n const current = groups.get(name);\n if (!current || (!current.checked && radio.checked)) {\n groups.set(name, radio);\n }\n }\n tabbables = tabbables.filter((el) => {\n const radio = asRadio(el);\n if (!radio) return true;\n const [scope, name] = radioGroupOf(radio);\n return chosen.get(scope)?.get(name) === radio;\n });\n }\n\n const positive = tabbables\n .map((el, index) => ({ el, index, tabIndex: getTabIndex(el) }))\n .filter((item) => item.tabIndex > 0)\n .sort((a, b) => a.tabIndex - b.tabIndex || a.index - b.index)\n .map((item) => item.el);\n const natural = tabbables.filter((el) => getTabIndex(el) === 0);\n return [...positive, ...natural];\n}\n\nexport interface FocusElementOptions {\n /** Do not scroll the element into view. @default false */\n preventScroll?: boolean;\n /** Select the text of inputs / textareas after focusing. @default false */\n select?: boolean;\n}\n\n/**\n * Focuses `el` (no-op for `null`). Returns `true` when `el` is focused\n * afterwards.\n */\nexport function focusElement(\n el: HTMLElement | SVGElement | null | undefined,\n options: FocusElementOptions = {},\n): boolean {\n if (!el || typeof el.focus !== \"function\") return false;\n const doc = getOwnerDocument(el);\n const previous = getActiveElement(doc);\n el.focus({ preventScroll: options.preventScroll ?? false });\n const focused = getActiveElement(doc) === el;\n if (\n focused &&\n options.select &&\n el !== previous &&\n (el.tagName === \"INPUT\" || el.tagName === \"TEXTAREA\") &&\n typeof (el as HTMLInputElement).select === \"function\"\n ) {\n (el as HTMLInputElement).select();\n }\n return focused;\n}\n\n/**\n * Focuses the first candidate that actually accepts focus.\n * @returns the focused element, or `null` when none did.\n */\nexport function focusFirst(\n candidates: Iterable<HTMLElement | null | undefined>,\n options: FocusElementOptions = {},\n): HTMLElement | null {\n for (const candidate of candidates) {\n if (focusElement(candidate, options)) return candidate as HTMLElement;\n }\n return null;\n}\n","import {\n contains,\n focusElement,\n focusFirst,\n getActiveElement,\n getEventTarget,\n getOwnerDocument,\n getTabbables,\n isHTMLElement,\n} from \"./dom\";\n\n/** Name of the cancelable event dispatched on the container on activation. */\nexport const FOCUS_SCOPE_MOUNT_EVENT = \"minerva.focusScope.autoFocusOnMount\";\n/** Name of the cancelable event dispatched on the container on deactivation. */\nexport const FOCUS_SCOPE_UNMOUNT_EVENT =\n \"minerva.focusScope.autoFocusOnUnmount\";\n\n/**\n * Auto-focus callback: return `false` or call `event.preventDefault()` to\n * skip the default focus move (and move focus yourself if needed).\n */\nexport type FocusScopeAutoFocusHandler = (event: Event) => void | boolean;\n\nexport interface FocusScopeOptions {\n /**\n * Keep focus inside the container: Tab / Shift+Tab cannot leave it and\n * focus moving elsewhere is pulled back. @default false\n */\n trapped?: boolean;\n /** Tab on the last tabbable goes to the first (and vice versa). @default false */\n loop?: boolean;\n /**\n * What to focus on activation (skipped when focus is already inside):\n * `true` = first tabbable (links last) or the container; an element; or a\n * function returning one (falls back to `true` behaviour on `null`).\n * @default true\n */\n autoFocus?: boolean | HTMLElement | (() => HTMLElement | null);\n /**\n * Where focus goes on deactivation: `true` = the element that was focused\n * before activation; an element; `false` = leave focus alone.\n * @default true\n */\n restoreFocus?: boolean | HTMLElement;\n /** Called before auto-focusing on activation (cancelable). */\n onMountAutoFocus?: FocusScopeAutoFocusHandler;\n /** Called before restoring focus on deactivation (cancelable). */\n onUnmountAutoFocus?: FocusScopeAutoFocusHandler;\n}\n\nexport interface FocusScope {\n /** Starts the scope: auto-focus, trap, push onto the scope stack. */\n activate(): void;\n /**\n * Stops the scope: removes listeners, resumes the previous scope and\n * restores focus (deferred to the next macrotask, see below).\n */\n deactivate(): void;\n /** Temporarily stops trapping (e.g. while a nested non-modal layer is open). */\n pause(): void;\n /** Undoes `pause()`. */\n resume(): void;\n /** Whether the scope is active and not paused. */\n isActive(): boolean;\n}\n\ninterface ScopeEntry {\n setStackPaused(paused: boolean): void;\n}\n\n/** Active scopes, last = topmost. Only the topmost scope traps focus. */\nconst scopeStack: ScopeEntry[] = [];\n\nfunction pushScope(entry: ScopeEntry) {\n scopeStack[scopeStack.length - 1]?.setStackPaused(true);\n removeScope(entry);\n scopeStack.push(entry);\n entry.setStackPaused(false);\n}\n\nfunction removeScope(entry: ScopeEntry) {\n const index = scopeStack.indexOf(entry);\n if (index === -1) return;\n scopeStack.splice(index, 1);\n scopeStack[scopeStack.length - 1]?.setStackPaused(false);\n}\n\nfunction runAutoFocusHandler(\n container: HTMLElement,\n type: string,\n handler: FocusScopeAutoFocusHandler | undefined,\n): boolean {\n const win = container.ownerDocument.defaultView;\n const EventCtor = win?.CustomEvent ?? CustomEvent;\n const event = new EventCtor(type, { bubbles: false, cancelable: true });\n container.dispatchEvent(event);\n const result = handler?.(event);\n return result !== false && !event.defaultPrevented;\n}\n\n/** Links are focused last on auto-focus (they are rarely the primary action). */\nfunction withoutLinksFirst(items: HTMLElement[]): HTMLElement[] {\n const isLink = (el: HTMLElement) => el.tagName === \"A\";\n return [...items.filter((el) => !isLink(el)), ...items.filter(isLink)];\n}\n\n/**\n * Creates a focus scope on `container`: auto-focus on activation, optional\n * focus trap (Tab wrapping, pulling focus back) and focus restoration on\n * deactivation.\n *\n * Scopes form a global stack: activating a scope pauses the previous one,\n * deactivating it resumes the previous one, so nested dialogs work.\n *\n * Focus restoration runs in a `setTimeout(0)` after `deactivate()`, so it\n * works whether the container is removed before or after the call. It is\n * skipped when, by then, focus has deliberately moved elsewhere outside the\n * container (e.g. the user clicked another input).\n *\n * @example\n * const scope = createFocusScope(dialog, { trapped: true, loop: true });\n * scope.activate();\n * // ...\n * scope.deactivate();\n */\nexport function createFocusScope(\n container: HTMLElement,\n options: FocusScopeOptions = {},\n): FocusScope {\n const {\n trapped = false,\n loop = false,\n autoFocus = true,\n restoreFocus = true,\n onMountAutoFocus,\n onUnmountAutoFocus,\n } = options;\n\n const doc = getOwnerDocument(container);\n let active = false;\n let userPaused = false;\n let stackPaused = false;\n let previouslyFocused: HTMLElement | null = null;\n let lastFocused: HTMLElement | null = null;\n let addedTabIndex = false;\n let observer: MutationObserver | null = null;\n\n const isPaused = () => userPaused || stackPaused;\n const entry: ScopeEntry = {\n setStackPaused(paused) {\n stackPaused = paused;\n },\n };\n\n const focusInside = () =>\n focusElement(lastFocused?.isConnected ? lastFocused : container, {\n select: true,\n }) || focusElement(container);\n\n const onFocusIn = (event: FocusEvent) => {\n if (!trapped || isPaused()) return;\n const target = getEventTarget(event);\n if (target instanceof Node && contains(container, target)) {\n if (isHTMLElement(target)) lastFocused = target;\n } else {\n focusInside();\n }\n };\n\n const onFocusOut = (event: FocusEvent) => {\n if (!trapped || isPaused()) return;\n const next = event.relatedTarget;\n // `null`: the window lost focus or the focused element was removed;\n // the latter is handled by the MutationObserver below.\n if (next === null) return;\n // `relatedTarget` is retargeted to the listener's tree: focus moving\n // into a shadow root reports the shadow host. When that host contains\n // the container, the real target is unknown here; the following\n // `focusin` (which carries the real target in its composed path) pulls\n // focus back if it really left.\n if (\n next instanceof Node &&\n (next as Element).shadowRoot &&\n contains(next, container)\n ) {\n return;\n }\n if (!(next instanceof Node) || !contains(container, next)) focusInside();\n };\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (!loop && !trapped) return;\n if (isPaused() || event.defaultPrevented) return;\n if (event.key !== \"Tab\" || event.altKey || event.ctrlKey || event.metaKey)\n return;\n const focused = getActiveElement(doc);\n const tabbables = getTabbables(container);\n if (tabbables.length === 0) {\n if (focused === container || trapped) event.preventDefault();\n return;\n }\n const first = tabbables[0];\n const last = tabbables[tabbables.length - 1];\n if (!event.shiftKey && focused === last) {\n event.preventDefault();\n if (loop) focusElement(first, { select: true });\n } else if (event.shiftKey && (focused === first || focused === container)) {\n event.preventDefault();\n if (loop) focusElement(last, { select: true });\n }\n };\n\n const onMutations = () => {\n if (!trapped || isPaused()) return;\n const focused = getActiveElement(doc);\n if (!focused || focused === doc.body) focusElement(container);\n };\n\n const resolveAutoFocusTarget = (): HTMLElement[] => {\n const tabbables = () => withoutLinksFirst(getTabbables(container));\n if (isHTMLElement(autoFocus)) return [autoFocus, ...tabbables()];\n if (typeof autoFocus === \"function\") {\n const target = autoFocus();\n return target ? [target, ...tabbables()] : tabbables();\n }\n return tabbables();\n };\n\n return {\n activate() {\n if (active) return;\n active = true;\n userPaused = false;\n const focused = getActiveElement(doc);\n previouslyFocused = isHTMLElement(focused) ? focused : null;\n\n if (!container.hasAttribute(\"tabindex\")) {\n container.setAttribute(\"tabindex\", \"-1\");\n addedTabIndex = true;\n }\n\n pushScope(entry);\n doc.addEventListener(\"focusin\", onFocusIn);\n doc.addEventListener(\"focusout\", onFocusOut);\n container.addEventListener(\"keydown\", onKeyDown);\n const ObserverCtor =\n doc.defaultView?.MutationObserver ??\n (typeof MutationObserver !== \"undefined\" ? MutationObserver : null);\n if (ObserverCtor) {\n observer = new ObserverCtor(onMutations);\n observer.observe(container, { childList: true, subtree: true });\n }\n\n const alreadyInside =\n focused instanceof Node && contains(container, focused);\n if (alreadyInside) {\n lastFocused = isHTMLElement(focused) ? focused : null;\n } else if (\n autoFocus !== false &&\n runAutoFocusHandler(\n container,\n FOCUS_SCOPE_MOUNT_EVENT,\n onMountAutoFocus,\n )\n ) {\n const target = focusFirst(resolveAutoFocusTarget(), { select: true });\n if (!target) focusElement(container);\n }\n const now = getActiveElement(doc);\n if (isHTMLElement(now) && contains(container, now)) lastFocused = now;\n },\n\n deactivate() {\n if (!active) return;\n active = false;\n doc.removeEventListener(\"focusin\", onFocusIn);\n doc.removeEventListener(\"focusout\", onFocusOut);\n container.removeEventListener(\"keydown\", onKeyDown);\n observer?.disconnect();\n observer = null;\n removeScope(entry);\n if (addedTabIndex) {\n container.removeAttribute(\"tabindex\");\n addedTabIndex = false;\n }\n\n const target =\n restoreFocus === false\n ? null\n : restoreFocus === true\n ? previouslyFocused\n : restoreFocus;\n previouslyFocused = null;\n lastFocused = null;\n if (!target) return;\n\n const win = doc.defaultView;\n const schedule = win?.setTimeout.bind(win) ?? setTimeout;\n schedule(() => {\n if (!target.isConnected) return;\n // Respect a deliberate focus move outside the (old) container.\n const focused = getActiveElement(doc);\n const focusLost =\n !focused ||\n focused === doc.body ||\n !focused.isConnected ||\n contains(container, focused);\n if (!focusLost) return;\n if (\n runAutoFocusHandler(\n container,\n FOCUS_SCOPE_UNMOUNT_EVENT,\n onUnmountAutoFocus,\n )\n ) {\n focusElement(target, { select: true });\n }\n }, 0);\n },\n\n pause() {\n userPaused = true;\n },\n\n resume() {\n userPaused = false;\n },\n\n isActive() {\n return active && !isPaused();\n },\n };\n}\n\n/** Number of active focus scopes (for tests / debugging). */\nexport function getFocusScopeCount(): number {\n return scopeStack.length;\n}\n","import { contains, getEventTarget, getOwnerDocument } from \"./dom\";\n\n/**\n * Attribute marking an element that handles Escape itself while it is set:\n * Escape pressed inside it does not dismiss the topmost layer.\n */\nexport const ESCAPE_CONSUMER_ATTRIBUTE = \"data-minerva-escape-consumer\";\n\n/**\n * Outside-interaction callback. Receives the original DOM event; call\n * `event.preventDefault()` or return `false` to keep the layer open.\n */\nexport type DismissHandler<E extends Event> = (event: E) => void | boolean;\n\nexport interface DismissableLayerOptions {\n /** Escape pressed while this layer is the topmost one. */\n onEscapeKeyDown?: DismissHandler<KeyboardEvent>;\n /** Pointer pressed outside the layer (and its branches / child layers). */\n onPointerDownOutside?: DismissHandler<PointerEvent>;\n /** Focus moved outside the layer (and its branches / child layers). */\n onFocusOutside?: DismissHandler<FocusEvent>;\n /** Either of the two above (called after the specific handler). */\n onInteractOutside?: DismissHandler<PointerEvent | FocusEvent>;\n /** The layer should close (no handler cancelled the interaction). */\n onDismiss?: () => void;\n /**\n * Make everything below this layer inert to the pointer (modal):\n * `body` gets `pointer-events: none`, this layer and the layers above it\n * get `pointer-events: auto`. Layers below are not dismissed by pointer.\n * @default false\n */\n disableOutsidePointerEvents?: boolean;\n /**\n * Elements treated as part of the layer (e.g. the trigger), so\n * interacting with them is not \"outside\".\n */\n branches?: () => Array<Element | null | undefined>;\n /**\n * Return `true` to ignore an interaction entirely (neither inside nor\n * outside), e.g. clicks in a toast viewport.\n */\n excludeFromOutside?: (target: Node) => boolean;\n /**\n * Explicit parent layer. Interactions inside a child layer are \"inside\" for\n * all of its ancestors. When omitted, the parent is the closest layer whose\n * element contains this one, else the layer directly below in the stack\n * (layers opened while another is open are treated as its children, which\n * makes portalled nested menus / popovers work). Pass `null` to make the\n * layer a root.\n */\n parent?: DismissableLayer | Element | null;\n}\n\nexport interface DismissableLayer {\n /** The layer element. */\n readonly element: Element;\n /** Removes the layer from the stack and restores pointer-events. */\n destroy(): void;\n /** Merges new options (handlers, branches, disableOutsidePointerEvents...). */\n update(options: Partial<DismissableLayerOptions>): void;\n}\n\n/** Debug view of a stacked layer. */\nexport interface LayerInfo {\n element: Element;\n disableOutsidePointerEvents: boolean;\n parent: Element | null;\n}\n\ninterface Layer {\n handle: DismissableLayer;\n element: Element;\n options: DismissableLayerOptions;\n /** Pointer handling starts on the next tick (ignore the opening click). */\n pointerReady: boolean;\n readyTimer: ReturnType<typeof setTimeout> | undefined;\n /** Inline `pointer-events` before we touched it. */\n originalPointerEvents: string | null;\n /** Implicit parent resolved at creation time (stack order / DOM). */\n implicitParent: Layer | null;\n}\n\n/** Bottom -> top. */\nconst layers: Layer[] = [];\n\ninterface DocumentState {\n refs: number;\n cleanup: () => void;\n bodyPointerEvents: string | null;\n}\nconst documents = new Map<Document, DocumentState>();\n\nfunction findLayer(target: DismissableLayer | Element | null | undefined) {\n if (!target) return null;\n return (\n layers.find((layer) => layer.handle === target) ??\n layers.find((layer) => layer.element === target) ??\n null\n );\n}\n\nfunction parentOf(layer: Layer): Layer | null {\n const { parent } = layer.options;\n if (parent === null) return null;\n if (parent !== undefined) {\n if (parent instanceof Object && \"destroy\" in parent) {\n return findLayer(parent);\n }\n // an element: the layer that is (or contains) it\n return (\n findLayer(parent) ??\n [...layers]\n .reverse()\n .find((l) => l !== layer && contains(l.element, parent)) ??\n null\n );\n }\n return layers.includes(layer.implicitParent as Layer)\n ? layer.implicitParent\n : null;\n}\n\nfunction isAncestor(ancestor: Layer, layer: Layer): boolean {\n const seen = new Set<Layer>();\n for (let p = parentOf(layer); p && !seen.has(p); p = parentOf(p)) {\n if (p === ancestor) return true;\n seen.add(p);\n }\n return false;\n}\n\n/** Whether `target` is inside `layer`, its branches or any descendant layer. */\nfunction isInside(layer: Layer, target: Node): boolean {\n if (contains(layer.element, target)) return true;\n const branches = layer.options.branches?.() ?? [];\n if (branches.some((branch) => branch && contains(branch, target))) {\n return true;\n }\n return layers.some(\n (other) =>\n other !== layer &&\n isAncestor(layer, other) &&\n (contains(other.element, target) ||\n (other.options.branches?.() ?? []).some(\n (branch) => branch && contains(branch, target),\n )),\n );\n}\n\nfunction highestModalIndex(): number {\n for (let i = layers.length - 1; i >= 0; i--) {\n if (layers[i].options.disableOutsidePointerEvents) return i;\n }\n return -1;\n}\n\nfunction isPointerEventsEnabled(layer: Layer): boolean {\n return layers.indexOf(layer) >= highestModalIndex();\n}\n\nfunction setInlinePointerEvents(el: Element, value: string | null) {\n const style = (el as HTMLElement).style;\n if (!style) return;\n if (value === null || value === \"\") style.removeProperty(\"pointer-events\");\n else style.pointerEvents = value;\n}\n\n/** Re-applies body / layer `pointer-events` after any stack change. */\nfunction syncPointerEvents() {\n const modalIndex = highestModalIndex();\n for (const [doc, state] of documents) {\n const hasModal =\n modalIndex !== -1 &&\n layers.some(\n (l, i) =>\n i <= modalIndex &&\n l.options.disableOutsidePointerEvents &&\n getOwnerDocument(l.element) === doc,\n );\n const body = doc.body;\n if (!body) continue;\n if (hasModal && state.bodyPointerEvents === null) {\n state.bodyPointerEvents = body.style.pointerEvents ?? \"\";\n body.style.pointerEvents = \"none\";\n } else if (!hasModal && state.bodyPointerEvents !== null) {\n setInlinePointerEvents(body, state.bodyPointerEvents);\n state.bodyPointerEvents = null;\n }\n }\n layers.forEach((layer, index) => {\n const enable = modalIndex !== -1 && index >= modalIndex;\n setInlinePointerEvents(\n layer.element,\n enable ? \"auto\" : layer.originalPointerEvents,\n );\n });\n}\n\n/** Calls the handlers; `true` when nothing cancelled the dismissal. */\nfunction runHandlers<E extends Event>(\n event: E,\n handlers: Array<DismissHandler<E> | undefined>,\n): boolean {\n const wasPrevented = event.defaultPrevented;\n let cancelled = false;\n // `focusin` (and synthetic events) are not cancelable: `preventDefault()`\n // would be a no-op and could not keep the layer open. Record the call\n // instead, so the documented contract holds for every event type.\n let preventedUncancelable = false;\n const restore = !event.cancelable;\n if (restore) {\n const native = event.preventDefault;\n Object.defineProperty(event, \"preventDefault\", {\n configurable: true,\n value() {\n preventedUncancelable = true;\n native.call(event);\n },\n });\n }\n try {\n for (const handler of handlers) {\n if (handler?.(event) === false) cancelled = true;\n }\n } finally {\n if (restore) delete (event as { preventDefault?: unknown }).preventDefault;\n }\n if (preventedUncancelable) cancelled = true;\n return !cancelled && (wasPrevented || !event.defaultPrevented);\n}\n\nfunction dismissOutside<E extends PointerEvent | FocusEvent>(\n event: E,\n kind: \"pointer\" | \"focus\",\n) {\n const target = getEventTarget(event);\n if (!(target instanceof Object) || !(\"nodeType\" in target)) return;\n const node = target as Node;\n // Topmost first: snapshot, handlers may destroy layers.\n const candidates = [...layers].reverse().filter((layer) => {\n if (\n kind === \"pointer\" &&\n (!layer.pointerReady || !isPointerEventsEnabled(layer))\n )\n return false;\n if (layer.options.excludeFromOutside?.(node)) return false;\n return !isInside(layer, node);\n });\n for (const layer of candidates) {\n if (!layers.includes(layer)) continue;\n const { options } = layer;\n const specific =\n kind === \"pointer\"\n ? (options.onPointerDownOutside as DismissHandler<E> | undefined)\n : (options.onFocusOutside as DismissHandler<E> | undefined);\n const ok = runHandlers<E>(event, [\n specific,\n options.onInteractOutside as DismissHandler<E> | undefined,\n ]);\n if (ok) options.onDismiss?.();\n }\n}\n\nfunction attachDocument(doc: Document) {\n const existing = documents.get(doc);\n if (existing) {\n existing.refs += 1;\n return;\n }\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key !== \"Escape\") return;\n // A control inside the layer consumes this Escape itself (e.g. a closed\n // combobox clearing its text): the layer stays open.\n const target = getEventTarget(event) as Element | null;\n if (target?.closest?.(`[${ESCAPE_CONSUMER_ATTRIBUTE}]`)) return;\n const top = [...layers]\n .reverse()\n .find((layer) => getOwnerDocument(layer.element) === doc);\n if (!top) return;\n const ok = runHandlers(event, [top.options.onEscapeKeyDown]);\n if (ok && top.options.onDismiss) {\n // e.g. keep the browser from leaving fullscreen\n event.preventDefault();\n top.options.onDismiss();\n }\n };\n\n let pendingClick: (() => void) | null = null;\n const onPointerDown = (event: PointerEvent) => {\n if (pendingClick) {\n doc.removeEventListener(\"click\", pendingClick);\n pendingClick = null;\n }\n if (event.pointerType === \"touch\") {\n // Touch: wait for the click so scrolling gestures do not dismiss.\n pendingClick = () => {\n pendingClick = null;\n dismissOutside(event, \"pointer\");\n };\n doc.addEventListener(\"click\", pendingClick, { once: true });\n return;\n }\n dismissOutside(event, \"pointer\");\n };\n\n const onFocusIn = (event: FocusEvent) => dismissOutside(event, \"focus\");\n\n doc.addEventListener(\"keydown\", onKeyDown, true);\n doc.addEventListener(\"pointerdown\", onPointerDown, true);\n doc.addEventListener(\"focusin\", onFocusIn, true);\n\n documents.set(doc, {\n refs: 1,\n bodyPointerEvents: null,\n cleanup() {\n doc.removeEventListener(\"keydown\", onKeyDown, true);\n doc.removeEventListener(\"pointerdown\", onPointerDown, true);\n doc.removeEventListener(\"focusin\", onFocusIn, true);\n if (pendingClick) doc.removeEventListener(\"click\", pendingClick);\n },\n });\n}\n\nfunction detachDocument(doc: Document) {\n const state = documents.get(doc);\n if (!state) return;\n state.refs -= 1;\n if (state.refs > 0) return;\n state.cleanup();\n if (state.bodyPointerEvents !== null && doc.body) {\n setInlinePointerEvents(doc.body, state.bodyPointerEvents);\n }\n documents.delete(doc);\n}\n\n/**\n * Registers `element` as a dismissable layer (popover, menu, dialog...).\n *\n * - Escape: only the topmost layer is notified.\n * - Pointer down / focus outside: a layer is notified when the interaction\n * is outside itself, its `branches` and its descendant layers, so clicking\n * in a (portalled) submenu never dismisses its parent menu.\n * - Pointer handling starts on the next tick so the click that opened the\n * layer does not immediately dismiss it. Touch pointers are handled on the\n * following `click` (so scroll gestures do not dismiss).\n * - Handlers get the original event; `preventDefault()` (or returning\n * `false`) cancels the dismissal.\n *\n * @example\n * const layer = createDismissableLayer(menu, {\n * branches: () => [trigger],\n * onDismiss: () => close(),\n * });\n * // later\n * layer.destroy();\n */\nexport function createDismissableLayer(\n element: Element,\n options: DismissableLayerOptions = {},\n): DismissableLayer {\n const doc = getOwnerDocument(element);\n const implicitParent =\n [...layers].reverse().find((l) => contains(l.element, element)) ??\n layers[layers.length - 1] ??\n null;\n\n let destroyed = false;\n const handle: DismissableLayer = {\n element,\n destroy() {\n if (destroyed) return;\n destroyed = true;\n clearTimeout(layer.readyTimer);\n const index = layers.indexOf(layer);\n if (index !== -1) layers.splice(index, 1);\n setInlinePointerEvents(element, layer.originalPointerEvents);\n syncPointerEvents();\n detachDocument(doc);\n },\n update(next) {\n if (destroyed) return;\n layer.options = { ...layer.options, ...next };\n syncPointerEvents();\n },\n };\n\n const layer: Layer = {\n handle,\n element,\n options: { ...options },\n pointerReady: false,\n readyTimer: undefined,\n originalPointerEvents:\n (element as HTMLElement).style?.getPropertyValue(\"pointer-events\") ||\n null,\n implicitParent,\n };\n\n layers.push(layer);\n attachDocument(doc);\n syncPointerEvents();\n const win = doc.defaultView;\n layer.readyTimer = (win?.setTimeout.bind(win) ?? setTimeout)(() => {\n layer.pointerReady = true;\n }, 0) as ReturnType<typeof setTimeout>;\n\n return handle;\n}\n\n/** Current layer stack, bottom -> top (for tests / debugging). */\nexport function getLayerStack(): LayerInfo[] {\n return layers.map((layer) => ({\n element: layer.element,\n disableOutsidePointerEvents: !!layer.options.disableOutsidePointerEvents,\n parent: parentOf(layer)?.element ?? null,\n }));\n}\n","import { canUseDOM } from \"./dom\";\n\n/** CSS variable (on `<html>`) holding the compensated scrollbar width. */\nexport const SCROLLBAR_GAP_VAR = \"--minerva-scrollbar-gap\";\n\ninterface LockState {\n count: number;\n restore: () => void;\n}\n\nconst locks = new Map<HTMLElement, LockState>();\n\n/**\n * Width of the scrollbar that hiding overflow on `target` would remove:\n * `innerWidth - documentElement.clientWidth` for the body, else\n * `offsetWidth - clientWidth`.\n */\nexport function getScrollbarGap(target: HTMLElement): number {\n const doc = target.ownerDocument;\n const win = doc.defaultView;\n const gap =\n target === doc.body || target === doc.documentElement\n ? (win?.innerWidth ?? 0) - doc.documentElement.clientWidth\n : target.offsetWidth - target.clientWidth;\n return Math.max(0, gap || 0);\n}\n\nfunction applyLock(target: HTMLElement): () => void {\n const doc = target.ownerDocument;\n const html = doc.documentElement;\n const isPage = target === doc.body;\n const gap = getScrollbarGap(target);\n\n const saved = {\n overflow: target.style.overflow,\n paddingRight: target.style.paddingRight,\n htmlOverflow: html.style.overflow,\n gapVar: html.style.getPropertyValue(SCROLLBAR_GAP_VAR),\n };\n\n if (gap > 0) {\n const computed = doc.defaultView?.getComputedStyle(target).paddingRight;\n const current = Number.parseFloat(computed ?? \"\") || 0;\n target.style.paddingRight = `${current + gap}px`;\n }\n target.style.overflow = \"hidden\";\n if (isPage) {\n // iOS Safari only stops page scrolling when <html> is locked too.\n html.style.overflow = \"hidden\";\n html.style.setProperty(SCROLLBAR_GAP_VAR, `${gap}px`);\n }\n\n return () => {\n target.style.overflow = saved.overflow;\n target.style.paddingRight = saved.paddingRight;\n if (isPage) {\n html.style.overflow = saved.htmlOverflow;\n if (saved.gapVar) html.style.setProperty(SCROLLBAR_GAP_VAR, saved.gapVar);\n else html.style.removeProperty(SCROLLBAR_GAP_VAR);\n }\n };\n}\n\n/**\n * Prevents `target` (the page by default) from scrolling, compensating the\n * scrollbar width with `padding-right` so the layout does not shift, and\n * exposing it as `--minerva-scrollbar-gap` on `<html>` (for fixed elements).\n *\n * Nested-safe: locks are reference counted per target and the original\n * inline styles are restored when the last lock is released.\n *\n * @returns an idempotent unlock function (a no-op outside the browser).\n */\nexport function lockScroll(target?: HTMLElement): () => void {\n if (!canUseDOM()) return () => {};\n const el = target ?? document.body;\n let state = locks.get(el);\n if (state) {\n state.count += 1;\n } else {\n state = { count: 1, restore: applyLock(el) };\n locks.set(el, state);\n }\n\n let released = false;\n return () => {\n if (released) return;\n released = true;\n const current = locks.get(el);\n if (!current) return;\n current.count -= 1;\n if (current.count === 0) {\n locks.delete(el);\n current.restore();\n }\n };\n}\n\n/** Whether `target` (the body by default) is currently scroll-locked. */\nexport function isScrollLocked(target?: HTMLElement): boolean {\n if (!canUseDOM()) return false;\n return locks.has(target ?? document.body);\n}\n","import { canUseDOM } from \"./dom\";\n\nexport interface HideOthersOptions {\n /** Only elements inside `root` are hidden. @default document.body */\n root?: Element;\n /**\n * `\"aria-hidden\"` hides from assistive tech only; `\"inert\"` also blocks\n * focus and pointer interaction. @default \"aria-hidden\"\n */\n attribute?: \"aria-hidden\" | \"inert\";\n}\n\n/** Elements matching this selector are never hidden. */\nexport const KEEP_VISIBLE_SELECTOR = \"[aria-live], [data-minerva-keep-visible]\";\n\nconst IGNORED_TAGS = new Set([\"SCRIPT\", \"STYLE\", \"TEMPLATE\", \"LINK\", \"META\"]);\n\n/** attribute -> element -> number of active hideOthers() calls hiding it */\nconst counters: Record<string, WeakMap<Element, number>> = {\n \"aria-hidden\": new WeakMap(),\n inert: new WeakMap(),\n};\n/** attribute -> elements that already had the attribute before us */\nconst preexisting: Record<string, WeakSet<Element>> = {\n \"aria-hidden\": new WeakSet(),\n inert: new WeakSet(),\n};\n\nfunction hasAttribute(el: Element, attribute: string): boolean {\n if (attribute === \"aria-hidden\") {\n const value = el.getAttribute(\"aria-hidden\");\n return value !== null && value !== \"false\";\n }\n return el.hasAttribute(attribute);\n}\n\nfunction hide(el: Element, attribute: string) {\n const count = counters[attribute].get(el) ?? 0;\n if (count === 0) {\n if (hasAttribute(el, attribute)) {\n preexisting[attribute].add(el);\n } else {\n preexisting[attribute].delete(el);\n el.setAttribute(attribute, attribute === \"inert\" ? \"\" : \"true\");\n }\n }\n counters[attribute].set(el, count + 1);\n}\n\nfunction unhide(el: Element, attribute: string) {\n const count = counters[attribute].get(el) ?? 0;\n if (count <= 0) return;\n if (count === 1) {\n counters[attribute].delete(el);\n if (!preexisting[attribute].has(el)) el.removeAttribute(attribute);\n preexisting[attribute].delete(el);\n } else {\n counters[attribute].set(el, count - 1);\n }\n}\n\n/**\n * Hides everything in `root` except `targets` (and their ancestors), for\n * modal dialogs: every sibling along the path from `root` to each target is\n * marked `aria-hidden=\"true\"` (or `inert`). Live regions (`[aria-live]`) and\n * `[data-minerva-keep-visible]` elements are left alone.\n *\n * Nested-safe: overlapping calls are reference counted per element, and an\n * attribute that existed before the first call is preserved on undo.\n *\n * @returns an idempotent undo function.\n */\nexport function hideOthers(\n targets: Element | Element[],\n options: HideOthersOptions = {},\n): () => void {\n if (!canUseDOM()) return () => {};\n const { root = document.body, attribute = \"aria-hidden\" } = options;\n const list = (Array.isArray(targets) ? targets : [targets]).filter(\n (target) => target && root.contains(target) && target !== root,\n );\n if (list.length === 0) return () => {};\n\n const targetSet = new Set<Element>(list);\n const keep = new Set<Element>();\n for (const target of list) {\n for (let el: Element | null = target; el && el !== root;) {\n keep.add(el);\n el = el.parentElement;\n }\n }\n\n const hidden: Element[] = [];\n const walk = (parent: Element) => {\n for (const child of Array.from(parent.children)) {\n if (keep.has(child)) {\n if (!targetSet.has(child)) walk(child);\n continue;\n }\n if (IGNORED_TAGS.has(child.tagName)) continue;\n if (child.matches(KEEP_VISIBLE_SELECTOR)) continue;\n hide(child, attribute);\n hidden.push(child);\n }\n };\n walk(root);\n\n let undone = false;\n return () => {\n if (undone) return;\n undone = true;\n for (const el of hidden) unhide(el, attribute);\n };\n}\n","import {\n createTypeahead,\n getNextIndex,\n type Direction,\n type Orientation,\n type TypeaheadOptions,\n} from \"@minerva/core\";\nimport { contains, focusElement, getEventTarget } from \"./dom\";\n\nexport interface RovingFocusOptions {\n /** Selector for items inside the container. @default \"[data-minerva-item]\" */\n itemSelector?: string;\n /** Custom item getter (takes precedence over `itemSelector`). */\n getItems?: () => HTMLElement[];\n /** @default \"vertical\" */\n orientation?: Orientation;\n /** @default \"ltr\" */\n dir?: Direction;\n /** @default true */\n loop?: boolean;\n /** Enable typeahead (`true` or typeahead options). @default false */\n typeahead?: boolean | TypeaheadOptions;\n /** Item text for typeahead. @default `data-text-value` or textContent */\n getItemText?: (item: HTMLElement) => string;\n /**\n * Disabled items are skipped by keyboard navigation.\n * @default `disabled`, `aria-disabled=\"true\"` or `data-disabled`\n */\n isItemDisabled?: (item: HTMLElement) => boolean;\n /** Called when the active item changes. */\n onActiveChange?: (item: HTMLElement, index: number) => void;\n /** Move DOM focus to the newly active item. @default true */\n focusOnMove?: boolean;\n /** Enables PageUp / PageDown with this step. */\n pageSize?: number;\n}\n\nexport interface RovingFocus {\n /** Makes an item (element or index) the active one (tabindex 0). */\n setActive(item: HTMLElement | number, options?: { focus?: boolean }): void;\n /** The active item (`tabindex=\"0\"`), if any. */\n getActive(): HTMLElement | null;\n /** Re-applies tabindex after items were added / removed. */\n refresh(): void;\n /** Removes the listeners (tabindex attributes are left as they are). */\n destroy(): void;\n}\n\nconst defaultIsDisabled = (item: HTMLElement) =>\n item.hasAttribute(\"disabled\") ||\n item.getAttribute(\"aria-disabled\") === \"true\" ||\n item.hasAttribute(\"data-disabled\");\n\nconst defaultGetText = (item: HTMLElement) =>\n item.dataset.textValue ?? item.textContent ?? \"\";\n\n/**\n * Roving tabindex controller: exactly one item has `tabindex=\"0\"`, the\n * others `-1`; arrow keys / Home / End (and optional typeahead) move the\n * active item. Clicking / focusing an item makes it active.\n */\nexport function createRovingFocus(\n container: HTMLElement,\n options: RovingFocusOptions = {},\n): RovingFocus {\n const {\n itemSelector = \"[data-minerva-item]\",\n orientation = \"vertical\",\n dir = \"ltr\",\n loop = true,\n getItemText = defaultGetText,\n isItemDisabled = defaultIsDisabled,\n onActiveChange,\n focusOnMove = true,\n pageSize,\n } = options;\n const typeahead = options.typeahead\n ? createTypeahead(options.typeahead === true ? {} : options.typeahead)\n : null;\n\n const getItems = (): HTMLElement[] =>\n options.getItems\n ? options.getItems()\n : Array.from(container.querySelectorAll<HTMLElement>(itemSelector));\n\n let active: HTMLElement | null = null;\n\n const sync = (items = getItems()) => {\n if (!active || !items.includes(active)) {\n active =\n items.find((item) => item.getAttribute(\"tabindex\") === \"0\") ??\n items.find((item) => !isItemDisabled(item)) ??\n null;\n }\n for (const item of items) {\n item.setAttribute(\"tabindex\", item === active ? \"0\" : \"-1\");\n }\n };\n\n const activate = (\n item: HTMLElement,\n items: HTMLElement[],\n focus: boolean,\n ) => {\n const changed = item !== active;\n active = item;\n sync(items);\n if (focus) focusElement(item);\n if (changed) onActiveChange?.(item, items.indexOf(item));\n };\n\n const itemFromEvent = (event: Event, items: HTMLElement[]) => {\n const target = getEventTarget(event);\n if (!(target instanceof Node)) return null;\n return items.find((item) => contains(item, target)) ?? null;\n };\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.defaultPrevented) return;\n const items = getItems();\n if (items.length === 0) return;\n const current = itemFromEvent(event, items) ?? active;\n const currentIndex = current ? items.indexOf(current) : -1;\n const isDisabled = (i: number) => isItemDisabled(items[i]);\n\n if (!event.altKey && !event.ctrlKey && !event.metaKey) {\n const next = getNextIndex({\n currentIndex,\n count: items.length,\n key: event.key,\n orientation,\n dir,\n loop,\n isDisabled,\n pageSize,\n });\n if (next !== null) {\n event.preventDefault();\n typeahead?.reset();\n activate(items[next], items, focusOnMove);\n return;\n }\n if (typeahead) {\n const index = typeahead.search(\n event.key,\n items.map((item) => ({\n text: getItemText(item),\n disabled: isItemDisabled(item),\n })),\n currentIndex,\n );\n if (index !== -1) {\n event.preventDefault();\n activate(items[index], items, focusOnMove);\n }\n }\n }\n };\n\n const onFocusIn = (event: FocusEvent) => {\n const items = getItems();\n const item = itemFromEvent(event, items);\n if (item && item !== active) activate(item, items, false);\n };\n\n container.addEventListener(\"keydown\", onKeyDown);\n container.addEventListener(\"focusin\", onFocusIn);\n sync();\n\n return {\n setActive(item, opts = {}) {\n const items = getItems();\n const el = typeof item === \"number\" ? items[item] : item;\n if (!el || !items.includes(el)) return;\n activate(el, items, opts.focus ?? focusOnMove);\n },\n getActive() {\n return active;\n },\n refresh() {\n sync();\n },\n destroy() {\n container.removeEventListener(\"keydown\", onKeyDown);\n container.removeEventListener(\"focusin\", onFocusIn);\n typeahead?.reset();\n },\n };\n}\n","// Vertical arrow navigation in a wrapping row of items (no fixed columns):\n// the item of the nearest row above / below whose center is the closest\n// horizontally, from the rendered geometry.\n\n/**\n * The element of `elements` in the nearest row above (`direction` -1) or\n * below (1) `from`, closest to its horizontal center; null when there is\n * none (or nothing is laid out, e.g. in jsdom).\n */\nexport function nearestInRow<T extends Element>(\n elements: readonly T[],\n from: Element,\n direction: 1 | -1,\n): T | null {\n const origin = from.getBoundingClientRect();\n const centerX = origin.left + origin.width / 2;\n let best: T | null = null;\n let bestRow = Infinity;\n let bestDx = Infinity;\n for (const element of elements) {\n if (element === from) continue;\n const rect = element.getBoundingClientRect();\n if (!rect.width && !rect.height) continue;\n const dy = (rect.top - origin.top) * direction;\n if (dy < Math.max(1, origin.height / 2)) continue;\n const dx = Math.abs(rect.left + rect.width / 2 - centerX);\n // a nearer row wins; within the same row (1px tolerance), the closest\n if (dy < bestRow - 1 || (Math.abs(dy - bestRow) <= 1 && dx < bestDx)) {\n best = element;\n bestRow = Math.min(bestRow, dy);\n bestDx = dx;\n }\n }\n return best;\n}\n","// Reading direction (LTR / RTL) of an element, for keyboard handlers whose\n// arrow keys follow the visual order. Nothing runs at import time.\n\n/** Reading direction of a piece of UI. */\nexport type ReadingDirection = \"ltr\" | \"rtl\";\n\n/**\n * Parent in the composed (flat) tree: the slot of slotted content, the\n * parent element, or the host of a shadow root.\n */\nfunction composedParent(node: Element): Element | null {\n if (node.assignedSlot) return node.assignedSlot;\n if (node.parentElement) return node.parentElement;\n const root = node.parentNode;\n return root && root.nodeType === 11 && \"host\" in root\n ? (root as ShadowRoot).host\n : null;\n}\n\n/**\n * Resolves the reading direction that applies to `element`: the nearest\n * ancestor (or self) with `dir=\"ltr\"` / `dir=\"rtl\"` wins, walking up through\n * slots and shadow hosts; `dir=\"auto\"` and invalid values are skipped. Then\n * the computed CSS `direction`, then `\"ltr\"`.\n *\n * Call it lazily (in event handlers / effects), never at import time.\n */\nexport function getDirection(\n element: Element | null | undefined,\n): ReadingDirection {\n for (let node = element ?? null; node; node = composedParent(node)) {\n const dir = node.getAttribute(\"dir\")?.toLowerCase();\n if (dir === \"rtl\" || dir === \"ltr\") return dir;\n }\n if (element) {\n const view = element.ownerDocument?.defaultView;\n const computed = view?.getComputedStyle?.(element).direction;\n if (computed === \"rtl\") return \"rtl\";\n }\n return \"ltr\";\n}\n\n/**\n * `explicit` when given, otherwise the direction inherited by `element`\n * (see {@link getDirection}).\n */\nexport function resolveDirection(\n explicit: ReadingDirection | undefined,\n element: Element | null | undefined,\n): ReadingDirection {\n return explicit ?? getDirection(element);\n}\n\n/**\n * Maps a physical arrow key to its logical meaning for `element`: in RTL,\n * ArrowLeft and ArrowRight are swapped (ArrowLeft = \"next\"), so handlers can\n * be written once for LTR. Other keys are returned as is.\n */\nexport function logicalArrowKey(\n key: string,\n element: Element | null | undefined,\n explicit?: ReadingDirection,\n): string {\n if (key !== \"ArrowLeft\" && key !== \"ArrowRight\") return key;\n if (resolveDirection(explicit, element) !== \"rtl\") return key;\n return key === \"ArrowLeft\" ? \"ArrowRight\" : \"ArrowLeft\";\n}\n","// Brings an item of a horizontally scrolling row into view by scrolling the\n// row only (never the page, unlike element.scrollIntoView).\nimport { getDirection } from \"./direction\";\n\n/**\n * Scrolls `scroller` horizontally so that `element` (one of its\n * descendants) is centered, clamped to the scrollable range (`0..max`, or\n * `-max..0` in RTL). Does nothing when the row does not overflow (or nothing\n * is laid out, e.g. in jsdom).\n */\nexport function centerInScroller(scroller: Element, element: Element): void {\n const max = scroller.scrollWidth - scroller.clientWidth;\n if (max <= 0) return;\n const view = scroller.getBoundingClientRect();\n const item = element.getBoundingClientRect();\n const delta = item.left + item.width / 2 - (view.left + view.width / 2);\n const next = scroller.scrollLeft + delta;\n const rtl = getDirection(scroller) === \"rtl\";\n const [min, upper] = rtl ? [-max, 0] : [0, max];\n const clamped = Math.round(Math.min(upper, Math.max(min, next)));\n if (clamped !== scroller.scrollLeft) scroller.scrollLeft = clamped;\n}\n","import { canUseDOM } from \"./dom\";\n\n/**\n * Resolves where portalled content goes: the explicit container when given,\n * else `document.body` (`null` on the server).\n */\nexport function getPortalContainer(explicit?: Element | null): Element | null {\n if (explicit) return explicit;\n return canUseDOM() ? document.body : null;\n}\n\nexport interface PortalHostOptions {\n /** `id` of the host element. */\n id?: string;\n /** Extra attributes (e.g. `class`, `data-theme`, `dir`). */\n attributes?: Record<string, string>;\n /** Where the host is appended. @default document.body */\n parent?: Element | null;\n /** Tag name of the host. @default \"div\" */\n tagName?: string;\n}\n\n/** Attribute set on every host created by `createPortalHost`. */\nexport const PORTAL_HOST_ATTRIBUTE = \"data-minerva-portal\";\n\n/**\n * Creates and appends a dedicated portal host element, e.g. a theme-scoped\n * container carrying `data-theme` so portalled overlays inherit the theme\n * variables. Remove it with `host.remove()`.\n */\nexport function createPortalHost(options: PortalHostOptions = {}): HTMLElement {\n const parent = getPortalContainer(options.parent);\n if (!parent) {\n throw new Error(\"createPortalHost() requires a DOM environment\");\n }\n const host = parent.ownerDocument.createElement(options.tagName ?? \"div\");\n host.setAttribute(PORTAL_HOST_ATTRIBUTE, \"\");\n if (options.id) host.id = options.id;\n for (const [name, value] of Object.entries(options.attributes ?? {})) {\n host.setAttribute(name, value);\n }\n parent.appendChild(host);\n return host;\n}\n","import {\n arrow as arrowMiddleware,\n autoUpdate,\n computePosition,\n flip as flipMiddleware,\n limitShift,\n offset as offsetMiddleware,\n shift as shiftMiddleware,\n size as sizeMiddleware,\n type AutoUpdateOptions,\n type ElementRects,\n type Middleware,\n type MiddlewareData,\n type Placement,\n type Strategy,\n type VirtualElement,\n} from \"@floating-ui/dom\";\n\nexport type { Placement, VirtualElement, Strategy, MiddlewareData };\n\n/** Side of the anchor the floating element sits on. */\nexport type Side = \"top\" | \"right\" | \"bottom\" | \"left\";\n/** Alignment along the anchor. */\nexport type Align = \"start\" | \"center\" | \"end\";\n/** An element or a virtual element (e.g. the cursor position). */\nexport type AnchorElement = Element | VirtualElement;\n\n/** Minimum distance kept between a floating element and the viewport edge. */\nexport const VIEWPORT_PADDING = 8;\n/** Padding between the arrow and the floating element's corners. */\nexport const ARROW_PADDING = 6;\n\nexport interface AnchoredPositionOptions {\n /** Preferred placement; may flip when it overflows. @default \"bottom\" */\n placement?: Placement;\n /**\n * Gap from the anchor (main axis) and skid along it (cross axis), in px.\n * @default { mainAxis: 8, crossAxis: 0 }\n */\n offset?: { mainAxis?: number; crossAxis?: number };\n /** Flip to the opposite side when there is not enough room. @default true */\n flip?: boolean;\n /** Shift along the anchor to stay inside the viewport. @default true */\n shift?: boolean;\n /**\n * Size the floating element after the anchor: `\"min\"` makes it at least\n * as wide as the anchor, `\"exact\"` exactly as wide. Also caps `maxWidth`\n * to the available width. @default false\n */\n matchAnchorWidth?: false | \"min\" | \"exact\";\n /**\n * Cap the floating element's height (`maxHeight`) to the space available.\n * Also caps `maxWidth` to the available width. @default false\n */\n fitViewportHeight?: boolean;\n /** Arrow element, centered on the anchor. */\n arrowElement?: HTMLElement | null;\n /**\n * Minimum distance kept between the floating element and the viewport\n * edges (collision padding) used by flip, shift and size, in px.\n * @default VIEWPORT_PADDING (8)\n */\n padding?: number;\n /** Options for `autoUpdate` (used by `autoPosition` only). */\n autoUpdate?: AutoUpdateOptions;\n}\n\nexport interface AnchoredPositionResult {\n /** Left (px, viewport coordinates since the strategy is `fixed`). */\n x: number;\n /** Top (px). */\n y: number;\n /** Final placement, after flipping. */\n placement: Placement;\n strategy: Strategy;\n middlewareData: MiddlewareData;\n /** Arrow offsets (left for top/bottom placements, top for left/right). */\n arrow: { x?: number; y?: number };\n /** Space available for the floating element (from the size middleware). */\n availableWidth?: number;\n availableHeight?: number;\n /** Measured anchor / floating rectangles. */\n rects?: ElementRects;\n}\n\ninterface SizeData {\n availableWidth: number;\n availableHeight: number;\n}\n\nfunction buildMiddleware(\n options: AnchoredPositionOptions,\n sizeData: Partial<SizeData>,\n): Middleware[] {\n const {\n offset,\n flip = true,\n shift = true,\n matchAnchorWidth = false,\n fitViewportHeight = false,\n arrowElement,\n padding = VIEWPORT_PADDING,\n } = options;\n const mainAxis = offset?.mainAxis ?? 8;\n const crossAxis = offset?.crossAxis ?? 0;\n\n const middleware: Middleware[] = [offsetMiddleware({ mainAxis, crossAxis })];\n if (flip) {\n // \"alignment\": flip start <-> end before shifting, keep the side otherwise\n middleware.push(flipMiddleware({ padding, crossAxis: \"alignment\" }));\n }\n if (shift) {\n middleware.push(shiftMiddleware({ padding, limiter: limitShift() }));\n }\n const sizing = !!matchAnchorWidth || fitViewportHeight;\n middleware.push(\n sizeMiddleware({\n padding,\n apply({ rects, availableHeight, availableWidth, elements }) {\n sizeData.availableWidth = availableWidth;\n sizeData.availableHeight = availableHeight;\n if (!sizing) return;\n const style = elements.floating.style;\n if (matchAnchorWidth === \"exact\") {\n style.width = `${rects.reference.width}px`;\n } else if (matchAnchorWidth === \"min\") {\n style.minWidth = `${rects.reference.width}px`;\n }\n style.maxWidth = `${Math.max(0, availableWidth)}px`;\n if (fitViewportHeight) {\n style.maxHeight = `${Math.max(0, availableHeight)}px`;\n }\n },\n }),\n );\n if (arrowElement) {\n middleware.push(\n arrowMiddleware({ element: arrowElement, padding: ARROW_PADDING }),\n );\n }\n middleware.push({\n name: \"minervaRects\",\n fn: ({ rects }) => ({ data: { ...rects } }),\n });\n return middleware;\n}\n\n/**\n * Computes the position of `floating` anchored to `reference` (one shot).\n *\n * Same behaviour as the React library's `useAnchoredPosition`: `fixed` strategy,\n * offset (default 8px), flip (padding 8, cross-axis `\"alignment\"`), shift\n * (padding 8 + `limitShift`), optional size constraints and arrow\n * (padding 6). Position with `left` / `top` (see `applyPosition`), never a\n * transform, so CSS animations can use `transform` freely.\n */\nexport async function computeAnchoredPosition(\n reference: AnchorElement,\n floating: HTMLElement,\n options: AnchoredPositionOptions = {},\n): Promise<AnchoredPositionResult> {\n const sizeData: Partial<SizeData> = {};\n const result = await computePosition(reference, floating, {\n placement: options.placement ?? \"bottom\",\n strategy: \"fixed\",\n middleware: buildMiddleware(options, sizeData),\n });\n const arrowData = result.middlewareData.arrow;\n return {\n x: result.x,\n y: result.y,\n placement: result.placement,\n strategy: result.strategy,\n middlewareData: result.middlewareData,\n arrow: { x: arrowData?.x, y: arrowData?.y },\n availableWidth: sizeData.availableWidth,\n availableHeight: sizeData.availableHeight,\n rects: result.middlewareData.minervaRects as ElementRects | undefined,\n };\n}\n\n/**\n * Keeps `floating` positioned while the anchor / floating element move or\n * resize, or the page scrolls (`autoUpdate`). `onUpdate` receives each new\n * result (typically `(r) => applyPosition(floating, r)`).\n *\n * @returns cleanup function (stops updating; pending results are dropped).\n */\nexport function autoPosition(\n reference: AnchorElement,\n floating: HTMLElement,\n options: AnchoredPositionOptions,\n onUpdate: (result: AnchoredPositionResult) => void,\n): () => void {\n let active = true;\n const stop = autoUpdate(\n reference,\n floating,\n () => {\n void computeAnchoredPosition(reference, floating, options).then(\n (result) => {\n if (active) onUpdate(result);\n },\n );\n },\n options.autoUpdate,\n );\n return () => {\n active = false;\n stop();\n };\n}\n\n/** `\"bottom-start\"` -> `{ side: \"bottom\", align: \"start\" }` */\nexport function parsePlacement(placement: Placement): {\n side: Side;\n align: Align;\n} {\n const [side, align] = placement.split(\"-\") as [Side, Align | undefined];\n return { side, align: align ?? \"center\" };\n}\n\n/** `(\"bottom\", \"start\")` -> `\"bottom-start\"`; `\"center\"` -> `\"bottom\"`. */\nexport function toPlacement(side: Side, align: Align = \"center\"): Placement {\n return (align === \"center\" ? side : `${side}-${align}`) as Placement;\n}\n\n// A pure IIFE (not a top-level loop) so bundlers can drop it when\n// `fromCamelPlacement` is unused.\nconst CAMEL_TO_PLACEMENT: Record<string, Placement> = /* @__PURE__ */ (() => {\n const map: Record<string, Placement> = {};\n for (const side of [\"top\", \"bottom\", \"left\", \"right\"] as const) {\n map[side] = side;\n map[`${side}Start`] = `${side}-start`;\n map[`${side}End`] = `${side}-end`;\n }\n return map;\n})();\n\n/** `\"bottomStart\"` -> `\"bottom-start\"` (kebab-case is returned as is). */\nexport function fromCamelPlacement(value: string): Placement {\n return CAMEL_TO_PLACEMENT[value] ?? (value as Placement);\n}\n\n/** `\"bottom-start\"` -> `\"bottomStart\"` */\nexport function toCamelPlacement(placement: Placement): string {\n return placement.replace(/-(\\w)/, (_, c: string) => c.toUpperCase());\n}\n\n/**\n * CSS `transform-origin` pointing at the anchor, for scale-in animations.\n * With arrow offsets, the origin is the arrow tip (center of an arrow of\n * `arrowSize` px).\n */\nexport function getTransformOrigin(\n placement: Placement,\n arrow?: { x?: number; y?: number },\n arrowSize = 0,\n): string {\n const { side, align } = parsePlacement(placement);\n const alignPercent = { start: \"0%\", center: \"50%\", end: \"100%\" }[align];\n const vertical = side === \"top\" || side === \"bottom\";\n const cross = vertical\n ? arrow?.x != null\n ? `${arrow.x + arrowSize / 2}px`\n : alignPercent\n : arrow?.y != null\n ? `${arrow.y + arrowSize / 2}px`\n : alignPercent;\n // the origin sits on the edge facing the anchor\n const main = { top: \"100%\", bottom: \"0%\", left: \"100%\", right: \"0%\" }[side];\n return vertical ? `${cross} ${main}` : `${main} ${cross}`;\n}\n\n/**\n * Writes a result onto the floating element: `position`, `left`, `top`,\n * `data-side` / `data-align` / `data-placement` and the CSS variables\n * `--minerva-transform-origin`, `--minerva-anchor-width/height`,\n * `--minerva-available-width/height`.\n */\nexport function applyPosition(\n floating: HTMLElement,\n result: AnchoredPositionResult,\n options: { arrowSize?: number } = {},\n): void {\n const { style } = floating;\n const { side, align } = parsePlacement(result.placement);\n style.position = result.strategy;\n style.left = `${result.x}px`;\n style.top = `${result.y}px`;\n floating.setAttribute(\"data-side\", side);\n floating.setAttribute(\"data-align\", align);\n floating.setAttribute(\"data-placement\", result.placement);\n style.setProperty(\n \"--minerva-transform-origin\",\n getTransformOrigin(result.placement, result.arrow, options.arrowSize),\n );\n const reference = result.rects?.reference;\n if (reference) {\n style.setProperty(\"--minerva-anchor-width\", `${reference.width}px`);\n style.setProperty(\"--minerva-anchor-height\", `${reference.height}px`);\n }\n if (result.availableWidth != null) {\n style.setProperty(\n \"--minerva-available-width\",\n `${Math.max(0, result.availableWidth)}px`,\n );\n }\n if (result.availableHeight != null) {\n style.setProperty(\n \"--minerva-available-height\",\n `${Math.max(0, result.availableHeight)}px`,\n );\n }\n}\n","/** A point in client (viewport) coordinates. */\nexport interface Point {\n x: number;\n y: number;\n}\n\n/** A closed polygon (the last point connects back to the first). */\nexport type Polygon = Point[];\n\n/** Side of the exit point on which the target (e.g. the submenu) lies. */\nexport type GraceSide = \"top\" | \"right\" | \"bottom\" | \"left\";\n\n/** Rectangle in client coordinates (a `DOMRect` works). */\nexport interface GraceRect {\n top: number;\n right: number;\n bottom: number;\n left: number;\n}\n\n/**\n * Ray-casting point-in-polygon test (points exactly on an edge may go\n * either way).\n */\nexport function isPointInPolygon(point: Point, polygon: Polygon): boolean {\n const { x, y } = point;\n let inside = false;\n for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {\n const xi = polygon[i].x;\n const yi = polygon[i].y;\n const xj = polygon[j].x;\n const yj = polygon[j].y;\n const intersect =\n yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi;\n if (intersect) inside = !inside;\n }\n return inside;\n}\n\n/**\n * The \"safe triangle\" between the point where the pointer left a trigger\n * (e.g. a submenu item) and the target rectangle (the submenu): a polygon\n * from the exit point (pushed back by `padding` px so it is strictly\n * inside) to the near and far edges of the target.\n */\nexport function getGraceArea(\n exitPoint: Point,\n rect: GraceRect,\n side: GraceSide,\n padding = 5,\n): Polygon {\n switch (side) {\n case \"right\":\n return [\n { x: exitPoint.x - padding, y: exitPoint.y },\n { x: rect.left, y: rect.top },\n { x: rect.right, y: rect.top },\n { x: rect.right, y: rect.bottom },\n { x: rect.left, y: rect.bottom },\n ];\n case \"left\":\n return [\n { x: exitPoint.x + padding, y: exitPoint.y },\n { x: rect.right, y: rect.top },\n { x: rect.left, y: rect.top },\n { x: rect.left, y: rect.bottom },\n { x: rect.right, y: rect.bottom },\n ];\n case \"bottom\":\n return [\n { x: exitPoint.x, y: exitPoint.y - padding },\n { x: rect.left, y: rect.top },\n { x: rect.left, y: rect.bottom },\n { x: rect.right, y: rect.bottom },\n { x: rect.right, y: rect.top },\n ];\n case \"top\":\n return [\n { x: exitPoint.x, y: exitPoint.y + padding },\n { x: rect.left, y: rect.bottom },\n { x: rect.left, y: rect.top },\n { x: rect.right, y: rect.top },\n { x: rect.right, y: rect.bottom },\n ];\n }\n}\n\nexport interface PointerGraceOptions {\n /** Grace area padding, see `getGraceArea`. @default 5 */\n padding?: number;\n /**\n * The grace area expires after this many ms (the pointer is assumed to\n * have stopped heading to the target). `0` disables expiry. @default 300\n */\n timeout?: number;\n}\n\nexport interface PointerGrace {\n /** Starts a grace period when the pointer leaves the trigger. */\n start(exitPoint: Point, targetRect: GraceRect, side: GraceSide): void;\n /** Whether `point` is inside the current (non-expired) grace area. */\n isInGraceArea(point: Point): boolean;\n /** Ends the grace period. */\n clear(): void;\n /** Current grace polygon, if any (for debugging / drawing). */\n getArea(): Polygon | null;\n}\n\n/**\n * Pointer \"grace intent\" for submenus: while the pointer travels from a\n * submenu trigger towards the open submenu it may cross sibling items;\n * those should not steal the hover as long as the pointer is inside the\n * safe triangle.\n */\nexport function createPointerGrace(\n options: PointerGraceOptions = {},\n): PointerGrace {\n const { padding = 5, timeout = 300 } = options;\n let area: Polygon | null = null;\n let startedAt = 0;\n\n const expired = () => timeout > 0 && Date.now() - startedAt > timeout;\n\n return {\n start(exitPoint, targetRect, side) {\n area = getGraceArea(exitPoint, targetRect, side, padding);\n startedAt = Date.now();\n },\n isInGraceArea(point) {\n if (!area) return false;\n if (expired()) {\n area = null;\n return false;\n }\n return isPointInPolygon(point, area);\n },\n clear() {\n area = null;\n },\n getArea() {\n if (area && expired()) area = null;\n return area;\n },\n };\n}\n","export interface WaitForExitAnimationOptions {\n /**\n * Safety net (ms) after which the promise resolves even if no end event\n * fired (e.g. the animation was removed). @default computed duration + 50\n */\n timeout?: number;\n}\n\n/** Parses a CSS time list (\"0.2s, 150ms\") and returns the largest value in ms. */\nfunction maxTime(value: string | undefined | null): number {\n if (!value) return 0;\n return Math.max(\n 0,\n ...value.split(\",\").map((part) => {\n const t = part.trim();\n const n = Number.parseFloat(t);\n if (Number.isNaN(n)) return 0;\n return t.endsWith(\"ms\") ? n : n * 1000;\n }),\n );\n}\n\n/**\n * Total running time (ms) of the CSS animations / transitions on `el`\n * (`0` when there is none, e.g. `animation-name: none`).\n */\nexport function getExitAnimationDuration(el: Element): number {\n const win = el.ownerDocument.defaultView;\n if (!win) return 0;\n const style = win.getComputedStyle(el);\n const name = style.animationName;\n const animation =\n name && name !== \"none\"\n ? maxTime(style.animationDuration) + maxTime(style.animationDelay)\n : 0;\n const transition =\n maxTime(style.transitionDuration) + maxTime(style.transitionDelay);\n return Math.max(animation, transition);\n}\n\n/**\n * Resolves once `el` finished its exit animation / transition\n * (`animationend`, `transitionend` or their `cancel` events on `el` itself),\n * or immediately when it has none. Use it to delay unmounting.\n */\nexport function waitForExitAnimation(\n el: Element,\n options: WaitForExitAnimationOptions = {},\n): Promise<void> {\n const duration = getExitAnimationDuration(el);\n if (duration <= 0) return Promise.resolve();\n const win = el.ownerDocument.defaultView;\n const timeout = options.timeout ?? duration + 50;\n\n return new Promise((resolve) => {\n const events = [\n \"animationend\",\n \"animationcancel\",\n \"transitionend\",\n \"transitioncancel\",\n ];\n const done = () => {\n for (const type of events) el.removeEventListener(type, onEnd);\n (win?.clearTimeout.bind(win) ?? clearTimeout)(timer);\n resolve();\n };\n const onEnd = (event: Event) => {\n if (event.target === el) done();\n };\n for (const type of events) el.addEventListener(type, onEnd);\n const timer = (win?.setTimeout.bind(win) ?? setTimeout)(\n done,\n timeout,\n ) as ReturnType<typeof setTimeout>;\n });\n}\n","import { contains, getFocusables, isTabbable } from \"./dom\";\n\n/**\n * The tabbable element following `el` in document order (outside `el`,\n * shadow trees and slotted content included), else the one preceding it,\n * else `null`. Used to move focus off an element about to be removed.\n */\nexport function getAdjacentTabbable(el: HTMLElement): HTMLElement | null {\n const candidates = getFocusables(el.ownerDocument.body).filter(\n (candidate) => !contains(el, candidate) && isTabbable(candidate),\n );\n const next = candidates.find(\n (candidate) =>\n el.compareDocumentPosition(candidate) & Node.DOCUMENT_POSITION_FOLLOWING,\n );\n if (next) return next;\n const previous = candidates.filter(\n (candidate) =>\n el.compareDocumentPosition(candidate) & Node.DOCUMENT_POSITION_PRECEDING,\n );\n return previous[previous.length - 1] ?? null;\n}\n","// Whether a keyboard event target takes text input (global shortcuts and\n// toast hotkeys must not steal keys typed in a field). DOM only.\n\nconst NON_TEXT_INPUT_TYPES = [\n \"button\",\n \"checkbox\",\n \"color\",\n \"file\",\n \"image\",\n \"radio\",\n \"range\",\n \"reset\",\n \"submit\",\n];\n\n/**\n * Whether `target` takes text input: text-like inputs, textareas, selects\n * and contenteditable hosts. Always `false` without a DOM (SSR).\n */\nexport function isEditableTarget(target: EventTarget | null): boolean {\n if (typeof HTMLElement === \"undefined\" || !(target instanceof HTMLElement)) {\n return false;\n }\n if (target.isContentEditable) return true;\n if (target instanceof HTMLTextAreaElement) return true;\n if (target instanceof HTMLSelectElement) return true;\n if (target instanceof HTMLInputElement) {\n return !NON_TEXT_INPUT_TYPES.includes(target.type);\n }\n return false;\n}\n","// Whether a pointer / keyboard event comes from an interactive element nested\n// in a container that itself reacts to clicks (e.g. a flashcard that flips on\n// click must not flip when a link or button inside a face is used). DOM only.\n\n/** Elements that handle clicks themselves. */\nexport const INTERACTIVE_SELECTOR = [\n \"a[href]\",\n \"area[href]\",\n \"button\",\n \"input\",\n \"select\",\n \"textarea\",\n \"label\",\n \"summary\",\n \"iframe\",\n \"object\",\n \"embed\",\n \"audio[controls]\",\n \"video[controls]\",\n \"[contenteditable]:not([contenteditable='false'])\",\n \"[tabindex]\",\n ...[\n \"button\",\n \"link\",\n \"checkbox\",\n \"radio\",\n \"switch\",\n \"tab\",\n \"menuitem\",\n \"option\",\n \"slider\",\n \"spinbutton\",\n \"textbox\",\n \"searchbox\",\n \"combobox\",\n ].map((role) => `[role='${role}']`),\n].join(\",\");\n\n/**\n * Whether `event` originates from an interactive element (link, button, form\n * control, element with a tabindex or a widget role) strictly inside\n * `container`. Uses the composed path, so slotted (light DOM) content of a\n * shadow root is handled. Always `false` without a DOM (SSR).\n */\nexport function isInteractiveEventTarget(\n event: Pick<Event, \"target\"> & Partial<Pick<Event, \"composedPath\">>,\n container: Element,\n): boolean {\n if (typeof Element === \"undefined\") return false;\n let path: EventTarget[] = event.composedPath?.() ?? [];\n if (!path.length) {\n path = [];\n for (\n let node = event.target as Node | null;\n node;\n node = node.parentNode ?? (node as ShadowRoot).host ?? null\n ) {\n path.push(node);\n }\n }\n for (const node of path) {\n if (node === container) return false;\n if (node instanceof Element && node.matches(INTERACTIVE_SELECTOR)) {\n return true;\n }\n }\n return false;\n}\n","// Drag and drop of the cards of a DashboardColumns, shared by the web renderers\n// (React DOM, Vue, Web Components, Angular). The board stays controlled: the\n// controller never moves a card, it shows where the card would land (a\n// floating copy under the pointer, a drop line, the target column\n// highlighted) and reports a `DashboardCardMove` on drop.\n//\n// - pointer: Pointer Events (mouse, pen and touch; no HTML5 drag and drop,\n// which touch screens lack). A mouse drag starts after a few pixels; touch\n// and pen need a long press so that swiping still scrolls the board. The\n// board scrolls horizontally, and the column under the pointer vertically,\n// near their edges. Escape cancels.\n// - keyboard: on a focused card, Space / Enter picks it up, the arrows move\n// it (Left / Right between columns, Up / Down within one), Space / Enter\n// drops it, Escape cancels; every step is announced in a live region.\n//\n// The renderer describes its DOM with an adapter (columns, cards, keys and\n// labels, the scrolling body of a column) and re-reads its props through\n// getters, so one controller lives as long as the board.\nimport {\n isDashboardNoop,\n dashboardCardMove,\n dashboardInsertIndex,\n dashboardKeyAction,\n dashboardKeyboardTarget,\n dashboardSlots,\n type DashboardCardMove,\n type DashboardLayoutColumn,\n type DashboardPosition,\n} from \"@minerva/core\";\nimport { getDirection } from \"./direction\";\nimport { INTERACTIVE_SELECTOR } from \"./interactive-target\";\n\n/** How a renderer exposes the columns and cards of a board */\nexport interface DashboardDragAdapter {\n /** The columns of the board, in order */\n columns(): HTMLElement[];\n /** Key (`value`) of a column; columns without one take no cards */\n columnKey(column: HTMLElement): string | null | undefined;\n /** Name of a column in the announcements (its title) */\n columnLabel(column: HTMLElement): string;\n /** The cards of a column, in order */\n cards(column: HTMLElement): HTMLElement[];\n /** Key (`value`) of a card; cards without one cannot be dragged */\n cardKey(card: HTMLElement): string | null | undefined;\n /** Name of a card in the announcements */\n cardLabel(card: HTMLElement): string;\n /** The vertically scrolling body of a column (its list, else its empty content) */\n body(column: HTMLElement): HTMLElement | null;\n}\n\n/** Options of `createDashboardDrag` (read on every use: pass getters) */\nexport interface DashboardDragOptions extends DashboardDragAdapter {\n /** The horizontally scrolling element of the board */\n scroller(): HTMLElement | null;\n /**\n * Element holding the drag layer (the floating card, the drop line, the\n * live region and the keyboard instructions); the board root by default.\n * It must share the cards' tree scope (the instructions are their\n * `aria-describedby`).\n */\n layerParent?(): HTMLElement;\n /** Id of the keyboard instructions element the cards are described by */\n hintId: string;\n /** Whether dragging is on (the `draggable` prop) */\n enabled(): boolean;\n /** Whether a card may be dropped there (the `canDrop` prop) */\n canDrop?(move: DashboardCardMove): boolean;\n /** Reports a drop that moves a card (the `onCardMove` prop / event) */\n onMove(move: DashboardCardMove): void;\n /** Translates a `dashboard.*` message */\n t(key: string, params?: Record<string, string | number>): string;\n}\n\n/** A drag controller attached to a board root */\nexport interface DashboardDrag {\n /** Whether a card is picked up */\n readonly dragging: boolean;\n /** Syncs the layer with the options (call after every render) */\n refresh(): void;\n /** Drops nothing: puts a picked-up card back */\n cancel(): void;\n /** Removes the listeners and the layer */\n destroy(): void;\n}\n\n/** Attribute naming the key of a column (React, Vue, Angular) */\nexport const DASHBOARD_COLUMN_ATTRIBUTE = \"data-dashboard-column\";\n/** Attribute naming the key of a card (React, Vue, Angular) */\nexport const DASHBOARD_CARD_ATTRIBUTE = \"data-dashboard-card\";\n\n/** Pixels a mouse moves before a press becomes a drag */\nconst MOUSE_THRESHOLD = 4;\n/** Long press (ms) that picks a card up with touch / pen */\nconst TOUCH_DELAY = 250;\n/** Pixels a finger may move during the long press (more: a scroll) */\nconst TOUCH_TOLERANCE = 8;\n/** Width of the edges that auto-scroll (pixels) */\nconst EDGE = 48;\n/** Fastest auto-scroll step (pixels per frame) */\nconst MAX_SPEED = 16;\n\nconst text = (element: Element | null | undefined) =>\n (element?.textContent ?? \"\").replace(/\\s+/g, \" \").trim();\n\n/**\n * Adapter of the renderers that mark their DOM with data attributes:\n * `data-dashboard-column` / `data-dashboard-card` hold the keys, the column parts\n * are `data-minerva=\"dashboard-column\"` + `data-part=\"title\" | \"list\" |\n * \"empty\"`. Nested boards are ignored.\n */\nexport function dashboardDataAdapter(root: HTMLElement): DashboardDragAdapter {\n const ownColumn = (element: Element) =>\n element.parentElement?.closest(`[${DASHBOARD_COLUMN_ATTRIBUTE}]`);\n const parts = (column: HTMLElement, names: string[]) =>\n Array.from(\n column.querySelectorAll<HTMLElement>(\n names\n .map(\n (name) => `[data-minerva=\"dashboard-column\"][data-part=\"${name}\"]`,\n )\n .join(\",\"),\n ),\n ).filter((element) => ownColumn(element) === column);\n const adapter: DashboardDragAdapter = {\n columns: () =>\n Array.from(\n root.querySelectorAll<HTMLElement>(`[${DASHBOARD_COLUMN_ATTRIBUTE}]`),\n ).filter(\n (column) =>\n column.parentElement?.closest(\n '[data-minerva=\"dashboard-columns\"]',\n ) === root,\n ),\n columnKey: (column) => column.getAttribute(DASHBOARD_COLUMN_ATTRIBUTE),\n columnLabel: (column) => {\n const [title] = parts(column, [\"title\"]);\n return (\n text(title) ||\n column.getAttribute(\"aria-label\") ||\n adapter.columnKey(column) ||\n \"\"\n );\n },\n cards: (column) =>\n Array.from(\n column.querySelectorAll<HTMLElement>(`[${DASHBOARD_CARD_ATTRIBUTE}]`),\n ).filter((card) => ownColumn(card) === column),\n cardKey: (card) => card.getAttribute(DASHBOARD_CARD_ATTRIBUTE),\n cardLabel: (card) =>\n card.getAttribute(\"aria-label\") ||\n text(card) ||\n adapter.cardKey(card) ||\n \"\",\n body: (column) => {\n const body = parts(column, [\"list\", \"empty\"]);\n const list = body.find((part) => part.dataset.part === \"list\");\n const empty = body.find((part) => part.dataset.part === \"empty\");\n return adapter.cards(column).length > 0\n ? (list ?? empty ?? null)\n : (empty ?? list ?? null);\n },\n };\n return adapter;\n}\n\ninterface Drag {\n mode: \"pointer\" | \"keyboard\";\n card: HTMLElement;\n key: string;\n label: string;\n from: DashboardPosition;\n /** Where the card would land (`null`: nowhere, a drop cancels) */\n target: DashboardPosition | null;\n column: HTMLElement | null;\n /** Pointer: id, position, and where the card was grabbed */\n pointerId?: number;\n x: number;\n y: number;\n grabX: number;\n grabY: number;\n ghost?: HTMLElement;\n}\n\ninterface Pending {\n card: HTMLElement;\n pointerId: number;\n touch: boolean;\n x: number;\n y: number;\n timer?: ReturnType<typeof setTimeout>;\n}\n\nconst visuallyHidden =\n \"position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0\";\n\n/**\n * Attaches drag and drop of cards to a board: pointer listeners on `root`\n * (events from the cards bubble to it, across shadow roots too) and a layer\n * appended to it while dragging is enabled.\n */\nexport function createDashboardDrag(\n root: HTMLElement,\n options: DashboardDragOptions,\n): DashboardDrag {\n const doc = root.ownerDocument;\n const view = doc.defaultView ?? window;\n let drag: Drag | null = null;\n let pending: Pending | null = null;\n let layer: HTMLElement | null = null;\n let hint: HTMLElement | null = null;\n let live: HTMLElement | null = null;\n let line: HTMLElement | null = null;\n let frame = 0;\n let destroyed = false;\n\n // --- layout ------------------------------------------------------------\n\n const keyedColumns = () =>\n options\n .columns()\n .map((element) => ({ element, key: options.columnKey(element) }))\n .filter((column): column is { element: HTMLElement; key: string } =>\n Boolean(column.key),\n );\n\n const keyedCards = (column: HTMLElement) =>\n options\n .cards(column)\n .map((element) => ({ element, key: options.cardKey(element) }))\n .filter((card): card is { element: HTMLElement; key: string } =>\n Boolean(card.key),\n );\n\n const layout = (): DashboardLayoutColumn[] =>\n keyedColumns().map(({ element, key }) => ({\n key,\n cards: keyedCards(element).map((card) => card.key),\n }));\n\n const columnElement = (key: string) =>\n keyedColumns().find((column) => column.key === key)?.element ?? null;\n\n /** The draggable card `node` is (with its column key), if any */\n const cardOf = (node: EventTarget | null) => {\n if (!(node instanceof HTMLElement)) return null;\n for (const column of keyedColumns()) {\n const card = keyedCards(column.element).find(\n (entry) => entry.element === node,\n );\n if (card) return { ...card, column: column.key };\n }\n return null;\n };\n\n /** The card a pointer event starts on (closest card in the composed path) */\n const cardFromPath = (event: Event) => {\n for (const node of event.composedPath()) {\n if (node === root) return null;\n const card = cardOf(node);\n if (card) return card;\n }\n return null;\n };\n\n // --- layer ----------------------------------------------------------------\n\n const ensureLayer = () => {\n if (layer) return;\n layer = doc.createElement(\"div\");\n layer.setAttribute(\"data-dashboard-layer\", \"\");\n // a zero-size fixed box: its children are placed in viewport\n // coordinates (corrected by its own offset under a transformed ancestor)\n layer.style.cssText =\n \"position:fixed;top:0;left:0;width:0;height:0;overflow:visible;pointer-events:none;z-index:var(--z-popover, 1000)\";\n hint = doc.createElement(\"span\");\n hint.hidden = true;\n live = doc.createElement(\"div\");\n live.setAttribute(\"role\", \"status\");\n live.setAttribute(\"aria-live\", \"assertive\");\n live.setAttribute(\"aria-atomic\", \"true\");\n live.style.cssText = visuallyHidden;\n layer.append(hint, live);\n };\n\n const refresh = () => {\n if (destroyed) return;\n if (!options.enabled()) {\n if (drag) cancel();\n layer?.remove();\n return;\n }\n ensureLayer();\n const parent = options.layerParent?.() ?? root;\n if (layer!.parentNode !== parent) parent.append(layer!);\n hint!.id = options.hintId;\n hint!.textContent = options.t(\"dashboard.dragHint\");\n };\n\n let toggle = false;\n const announce = (\n message: \"lifted\" | \"over\" | \"dropped\" | \"cancelled\",\n position: DashboardPosition,\n ) => {\n if (!drag || !live) return;\n const all = layout();\n const column = columnElement(position.column);\n // a trailing no-break space alternates so that a repeated message is\n // announced again\n toggle = !toggle;\n live.textContent =\n options.t(`dashboard.${message}`, {\n card: drag.label,\n column: column ? options.columnLabel(column) : position.column,\n position: position.index + 1,\n total: dashboardSlots(all, drag.key, position.column),\n }) + (toggle ? \"\\u00a0\" : \"\");\n };\n\n const origin = () => {\n const box = layer?.getBoundingClientRect();\n return { x: box?.left ?? 0, y: box?.top ?? 0 };\n };\n\n // --- target --------------------------------------------------------------\n\n const accept = (move: DashboardCardMove) =>\n isDashboardNoop(move) || !options.canDrop || options.canDrop(move);\n\n /** Where a card dropped at (x, y) would land, `null` for nowhere */\n const targetAt = (x: number, y: number): DashboardPosition | null => {\n if (!drag) return null;\n const scroller = options.scroller();\n if (scroller) {\n const box = scroller.getBoundingClientRect();\n if (\n x < box.left - EDGE ||\n x > box.right + EDGE ||\n y < box.top - EDGE ||\n y > box.bottom + EDGE\n )\n return null;\n }\n let best: { key: string; element: HTMLElement } | null = null;\n let distance = Infinity;\n for (const column of keyedColumns()) {\n const box = column.element.getBoundingClientRect();\n const d = x < box.left ? box.left - x : x > box.right ? x - box.right : 0;\n if (d < distance) {\n distance = d;\n best = column;\n }\n }\n if (!best) return null;\n const midpoints = keyedCards(best.element)\n .filter((card) => card.element !== drag!.card)\n .map((card) => {\n const box = card.element.getBoundingClientRect();\n return box.top + box.height / 2;\n });\n const move = dashboardCardMove(layout(), drag.key, {\n column: best.key,\n index: dashboardInsertIndex(midpoints, y),\n });\n return move && accept(move)\n ? { column: move.toColumn, index: move.toIndex }\n : null;\n };\n\n /** Shows the drop line and the highlighted column of the target */\n const paint = () => {\n if (!drag) return;\n const column = drag.target ? columnElement(drag.target.column) : null;\n if (drag.column !== column) {\n drag.column?.removeAttribute(\"data-dashboard-drop-target\");\n column?.setAttribute(\"data-dashboard-drop-target\", \"\");\n drag.column = column;\n }\n if (!column || !drag.target) {\n line?.remove();\n line = null;\n return;\n }\n if (!line) {\n line = doc.createElement(\"div\");\n line.setAttribute(\"data-dashboard-drop-line\", \"\");\n line.setAttribute(\"aria-hidden\", \"true\");\n line.style.cssText =\n \"position:absolute;height:2px;margin-top:-1px;border-radius:1px;background:var(--dashboard-drop-indicator-color, var(--primary-color));forced-color-adjust:none;pointer-events:none\";\n layer?.append(line);\n }\n const others = keyedCards(column)\n .filter((card) => card.element !== drag!.card)\n .map((card) => card.element.getBoundingClientRect());\n const body = (options.body(column) ?? column).getBoundingClientRect();\n const index = drag.target.index;\n let y: number;\n let left = body.left + 8;\n let width = Math.max(0, body.width - 16);\n if (others.length === 0) {\n y = body.top + Math.min(8, body.height / 2);\n } else {\n const next = others[index];\n const previous = others[index - 1];\n if (next && previous) y = (previous.bottom + next.top) / 2;\n else if (next) y = next.top - 4;\n else y = previous!.bottom + 4;\n const reference = others[0]!;\n left = reference.left;\n width = reference.width;\n }\n // keep the line inside the visible part of the column body\n y = Math.min(Math.max(y, body.top), body.bottom);\n const offset = origin();\n line.style.left = `${left - offset.x}px`;\n line.style.top = `${y - offset.y}px`;\n line.style.width = `${width}px`;\n };\n\n const placeGhost = () => {\n if (!drag?.ghost) return;\n const offset = origin();\n drag.ghost.style.left = `${drag.x - drag.grabX - offset.x}px`;\n drag.ghost.style.top = `${drag.y - drag.grabY - offset.y}px`;\n };\n\n // --- lifecycle --------------------------------------------------------------\n\n const lift = (\n card: { element: HTMLElement; key: string; column: string },\n mode: Drag[\"mode\"],\n pointer?: { x: number; y: number; id: number },\n ) => {\n const from = layout();\n const index = from\n .find((column) => column.key === card.column)!\n .cards.indexOf(card.key);\n drag = {\n mode,\n card: card.element,\n key: card.key,\n label: options.cardLabel(card.element),\n from: { column: card.column, index },\n target: { column: card.column, index },\n column: null,\n x: pointer?.x ?? 0,\n y: pointer?.y ?? 0,\n grabX: 0,\n grabY: 0,\n pointerId: pointer?.id,\n };\n ensureLayer();\n refresh();\n card.element.setAttribute(\"data-dashboard-dragging\", mode);\n root.setAttribute(\"data-dashboard-dragging\", mode);\n if (pointer) {\n const box = card.element.getBoundingClientRect();\n drag.grabX = pointer.x - box.left;\n drag.grabY = pointer.y - box.top;\n const ghost = card.element.cloneNode(true) as HTMLElement;\n for (const element of [ghost, ...ghost.querySelectorAll(\"[id]\")])\n element.removeAttribute(\"id\");\n ghost.removeAttribute(\"data-dashboard-dragging\");\n ghost.removeAttribute(DASHBOARD_CARD_ATTRIBUTE);\n ghost.removeAttribute(\"tabindex\");\n ghost.setAttribute(\"aria-hidden\", \"true\");\n ghost.setAttribute(\"inert\", \"\");\n ghost.setAttribute(\"data-dashboard-ghost\", \"\");\n ghost.style.position = \"absolute\";\n ghost.style.boxSizing = \"border-box\";\n ghost.style.width = `${box.width}px`;\n ghost.style.margin = \"0\";\n ghost.style.pointerEvents = \"none\";\n ghost.style.opacity = \"0.92\";\n ghost.style.transform = \"rotate(1.5deg)\";\n ghost.style.boxShadow = \"var(--shadow-lg, 0 10px 24px rgb(0 0 0 / 0.18))\";\n ghost.style.cursor = \"grabbing\";\n drag.ghost = ghost;\n layer!.append(ghost);\n placeGhost();\n view.getSelection?.()?.removeAllRanges();\n doc.addEventListener(\"keydown\", onDocumentKeyDown, true);\n doc.addEventListener(\"contextmenu\", preventDefault, true);\n frame = view.requestAnimationFrame(autoScroll);\n } else {\n card.element.addEventListener(\"blur\", onCardBlur);\n }\n paint();\n announce(\"lifted\", drag.from);\n };\n\n /** Removes every trace of the drag; returns it */\n const finish = () => {\n const current = drag;\n if (!current) return null;\n current.card.removeAttribute(\"data-dashboard-dragging\");\n current.card.removeEventListener(\"blur\", onCardBlur);\n current.column?.removeAttribute(\"data-dashboard-drop-target\");\n root.removeAttribute(\"data-dashboard-dragging\");\n current.ghost?.remove();\n line?.remove();\n line = null;\n view.cancelAnimationFrame(frame);\n doc.removeEventListener(\"keydown\", onDocumentKeyDown, true);\n doc.removeEventListener(\"contextmenu\", preventDefault, true);\n stopPointer();\n return current;\n };\n\n const cancel = () => {\n const current = drag;\n if (!current) return;\n announce(\"cancelled\", current.from);\n finish();\n drag = null;\n };\n\n const drop = () => {\n const current = drag;\n if (!current) return;\n const move = current.target\n ? dashboardCardMove(layout(), current.key, current.target)\n : undefined;\n if (!move || !accept(move)) {\n cancel();\n return;\n }\n announce(\"dropped\", { column: move.toColumn, index: move.toIndex });\n finish();\n drag = null;\n if (isDashboardNoop(move)) return;\n options.onMove(move);\n if (current.mode === \"keyboard\") restoreFocus(current.key, current.card);\n };\n\n /**\n * The app re-renders the moved card, often as a new element: give it the\n * focus back (once the renderer has updated) unless focus went elsewhere\n */\n const restoreFocus = (key: string, previous: HTMLElement) => {\n const attempt = () => {\n if (destroyed) return;\n const active = doc.activeElement;\n if (active && active !== doc.body && active !== previous) return;\n if (active === previous && previous.isConnected) return;\n for (const column of keyedColumns()) {\n const card = keyedCards(column.element).find(\n (entry) => entry.key === key,\n );\n if (card) {\n card.element.focus();\n return;\n }\n }\n };\n view.requestAnimationFrame(() => {\n attempt();\n view.requestAnimationFrame(attempt);\n });\n };\n\n // --- pointer ------------------------------------------------------------------\n\n const preventDefault = (event: Event) => event.preventDefault();\n\n const stopPointer = () => {\n if (pending?.timer) clearTimeout(pending.timer);\n pending = null;\n doc.removeEventListener(\"pointermove\", onPointerMove);\n doc.removeEventListener(\"pointerup\", onPointerUp);\n doc.removeEventListener(\"pointercancel\", onPointerCancel);\n root.removeEventListener(\"touchmove\", onTouchMove);\n };\n\n const startPointerDrag = (x: number, y: number) => {\n if (!pending) return;\n const card = cardOf(pending.card);\n const id = pending.pointerId;\n if (pending.timer) clearTimeout(pending.timer);\n pending = null;\n if (!card) return;\n lift(card, \"pointer\", { x, y, id });\n };\n\n /**\n * Whether a press starts on a control inside the card (a button, a link):\n * it keeps working and does not drag. The card's own shadow content (the\n * focusable wrapper of a web component card) is not such a control.\n */\n const startsOnControl = (event: Event, card: HTMLElement) => {\n for (const node of event.composedPath()) {\n if (node === card) return false;\n if (!(node instanceof Element)) continue;\n if (card.shadowRoot && node.getRootNode() === card.shadowRoot) continue;\n if (node.matches(INTERACTIVE_SELECTOR)) return true;\n }\n return false;\n };\n\n const onPointerDown = (event: PointerEvent) => {\n if (!options.enabled() || drag || pending) return;\n if (!event.isPrimary || (event.pointerType === \"mouse\" && event.button))\n return;\n const card = cardFromPath(event);\n if (!card || startsOnControl(event, card.element)) return;\n const touch = event.pointerType !== \"mouse\";\n pending = {\n card: card.element,\n pointerId: event.pointerId,\n touch,\n x: event.clientX,\n y: event.clientY,\n };\n if (touch) {\n const { x, y } = pending;\n pending.timer = setTimeout(() => startPointerDrag(x, y), TOUCH_DELAY);\n // the long press must be able to stop the page / board from scrolling\n root.addEventListener(\"touchmove\", onTouchMove, { passive: false });\n }\n doc.addEventListener(\"pointermove\", onPointerMove);\n doc.addEventListener(\"pointerup\", onPointerUp);\n doc.addEventListener(\"pointercancel\", onPointerCancel);\n };\n\n const onPointerMove = (event: PointerEvent) => {\n if (pending && event.pointerId === pending.pointerId) {\n const moved = Math.hypot(\n event.clientX - pending.x,\n event.clientY - pending.y,\n );\n if (pending.touch) {\n // moving before the long press is a scroll\n if (moved > TOUCH_TOLERANCE) stopPointer();\n return;\n }\n if (moved < MOUSE_THRESHOLD) return;\n startPointerDrag(pending.x, pending.y);\n }\n if (!drag || drag.mode !== \"pointer\" || event.pointerId !== drag.pointerId)\n return;\n event.preventDefault();\n drag.x = event.clientX;\n drag.y = event.clientY;\n placeGhost();\n retarget();\n };\n\n const retarget = () => {\n if (!drag) return;\n const next = targetAt(drag.x, drag.y);\n const same =\n next === drag.target ||\n (next &&\n drag.target &&\n next.column === drag.target.column &&\n next.index === drag.target.index);\n drag.target = next;\n paint();\n if (!same && next) announce(\"over\", next);\n };\n\n const onPointerUp = (event: PointerEvent) => {\n if (drag?.mode === \"pointer\" && event.pointerId === drag.pointerId) {\n // the click that follows a drag must not activate the card\n doc.addEventListener(\"click\", swallowClick, true);\n setTimeout(() => doc.removeEventListener(\"click\", swallowClick, true), 0);\n drop();\n return;\n }\n if (pending && event.pointerId === pending.pointerId) stopPointer();\n };\n\n const swallowClick = (event: Event) => {\n event.preventDefault();\n event.stopPropagation();\n doc.removeEventListener(\"click\", swallowClick, true);\n };\n\n const onPointerCancel = (event: PointerEvent) => {\n if (drag?.mode === \"pointer\" && event.pointerId === drag.pointerId)\n cancel();\n else if (pending && event.pointerId === pending.pointerId) stopPointer();\n };\n\n const onTouchMove = (event: TouchEvent) => {\n if (drag?.mode === \"pointer\" && event.cancelable) event.preventDefault();\n };\n\n /** Scrolls `scroller` along an axis when the pointer is near its edges */\n const edgeScroll = (\n scroller: HTMLElement,\n axis: \"x\" | \"y\",\n position: number,\n ) => {\n const box = scroller.getBoundingClientRect();\n const [start, end] =\n axis === \"x\" ? [box.left, box.right] : [box.top, box.bottom];\n const edge = Math.min(EDGE, (end - start) / 4);\n if (edge <= 0) return false;\n let step = 0;\n if (position < start + edge)\n step = -Math.ceil(MAX_SPEED * (1 - Math.max(0, position - start) / edge));\n else if (position > end - edge)\n step = Math.ceil(MAX_SPEED * (1 - Math.max(0, end - position) / edge));\n if (!step) return false;\n const before = axis === \"x\" ? scroller.scrollLeft : scroller.scrollTop;\n if (axis === \"x\") scroller.scrollLeft += step;\n else scroller.scrollTop += step;\n return (axis === \"x\" ? scroller.scrollLeft : scroller.scrollTop) !== before;\n };\n\n const autoScroll = () => {\n if (!drag || drag.mode !== \"pointer\") return;\n const scroller = options.scroller();\n let scrolled = scroller ? edgeScroll(scroller, \"x\", drag.x) : false;\n const body = drag.column ? options.body(drag.column) : null;\n if (body) scrolled = edgeScroll(body, \"y\", drag.y) || scrolled;\n if (scrolled) retarget();\n frame = view.requestAnimationFrame(autoScroll);\n };\n\n // --- keyboard -----------------------------------------------------------------\n\n /** Scrolls the board / column body (never the page) to show `element` */\n const reveal = (scroller: HTMLElement | null, element: Element) => {\n if (!scroller) return;\n const outer = scroller.getBoundingClientRect();\n const inner = element.getBoundingClientRect();\n if (inner.left < outer.left) scroller.scrollLeft -= outer.left - inner.left;\n else if (inner.right > outer.right)\n scroller.scrollLeft += Math.min(\n inner.right - outer.right,\n inner.left - outer.left,\n );\n if (inner.top < outer.top) scroller.scrollTop -= outer.top - inner.top;\n else if (inner.bottom > outer.bottom)\n scroller.scrollTop += Math.min(\n inner.bottom - outer.bottom,\n inner.top - outer.top,\n );\n };\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (!options.enabled() || event.defaultPrevented) return;\n if (event.altKey || event.ctrlKey || event.metaKey) return;\n const action = dashboardKeyAction(event.key, getDirection(root) === \"rtl\");\n if (!action) return;\n if (!drag) {\n if (action !== \"toggle\" || event.repeat) return;\n const card = cardOf(event.target);\n if (!card) return;\n event.preventDefault();\n lift(card, \"keyboard\");\n return;\n }\n if (drag.mode !== \"keyboard\" || event.target !== drag.card) return;\n event.preventDefault();\n event.stopPropagation();\n if (action === \"toggle\") {\n if (!event.repeat) drop();\n return;\n }\n if (action === \"cancel\") {\n cancel();\n return;\n }\n const current = drag.target ?? drag.from;\n const next = dashboardKeyboardTarget(\n layout(),\n drag.key,\n current,\n action,\n options.canDrop ? accept : undefined,\n );\n if (!next) return;\n drag.target = next;\n const column = columnElement(next.column);\n if (column) {\n reveal(options.scroller(), column);\n const neighbor = keyedCards(column).filter(\n (card) => card.element !== drag!.card,\n )[next.index];\n const body = options.body(column);\n if (neighbor) reveal(body, neighbor.element);\n else if (body) body.scrollTop = body.scrollHeight;\n }\n paint();\n announce(\"over\", next);\n };\n\n const onDocumentKeyDown = (event: KeyboardEvent) => {\n if (\n drag?.mode === \"pointer\" &&\n dashboardKeyAction(event.key) === \"cancel\"\n ) {\n event.preventDefault();\n event.stopPropagation();\n cancel();\n }\n };\n\n const onCardBlur = () => {\n if (drag?.mode === \"keyboard\") cancel();\n };\n\n /**\n * Native drag and drop (links, images, a draggable=\"true\" card or board)\n * stays off\n */\n const onDragStart = (event: DragEvent) => {\n if (\n options.enabled() &&\n (drag || pending || event.target === root || cardFromPath(event))\n )\n event.preventDefault();\n };\n\n root.addEventListener(\"pointerdown\", onPointerDown);\n root.addEventListener(\"keydown\", onKeyDown);\n root.addEventListener(\"dragstart\", onDragStart);\n refresh();\n\n return {\n get dragging() {\n return drag !== null;\n },\n refresh,\n cancel,\n destroy() {\n finish();\n drag = null;\n destroyed = true;\n root.removeEventListener(\"pointerdown\", onPointerDown);\n root.removeEventListener(\"keydown\", onKeyDown);\n root.removeEventListener(\"dragstart\", onDragStart);\n layer?.remove();\n layer = null;\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Deprecated aliases (the component was called KanbanBoard): kept for one\n// minor release cycle, not documented. The attribute values changed too.\n\n/** @deprecated Use `DashboardDragAdapter` */\nexport type KanbanDragAdapter = DashboardDragAdapter;\n/** @deprecated Use `DashboardDragOptions` */\nexport type KanbanDragOptions = DashboardDragOptions;\n/** @deprecated Use `DashboardDrag` */\nexport type KanbanDrag = DashboardDrag;\n/** @deprecated Use `DASHBOARD_COLUMN_ATTRIBUTE` (now `\"data-dashboard-column\"`) */\nexport const KANBAN_COLUMN_ATTRIBUTE = DASHBOARD_COLUMN_ATTRIBUTE;\n/** @deprecated Use `DASHBOARD_CARD_ATTRIBUTE` (now `\"data-dashboard-card\"`) */\nexport const KANBAN_CARD_ATTRIBUTE = DASHBOARD_CARD_ATTRIBUTE;\n/** @deprecated Use `dashboardDataAdapter` */\nexport const kanbanDataAdapter = dashboardDataAdapter;\n/** @deprecated Use `createDashboardDrag` */\nexport const createKanbanDrag = createDashboardDrag;\n","// Captions of the web media players (React / Vue / Angular MediaPlayer,\n// <minerva-media-player>): the players render their tracks as <track>\n// children of the <audio> / <video> and draw the active cue themselves, so\n// captions look the same in every browser and work for audio too.\nimport {\n activeCueText,\n cueText,\n isSrtSource,\n loadCaptions,\n type MediaCue,\n type MediaTrack,\n} from \"@minerva/core\";\n\n/** Options of {@link bindMediaCaptions}. */\nexport interface MediaCaptionsOptions {\n /**\n * CORS mode of the player (`crossOrigin` of the media element): the\n * fallback fetch sends credentials only for `use-credentials`.\n */\n crossOrigin?: string | null;\n /** Reads a captions file (defaults to `fetch`). */\n fetchText?: (url: string) => Promise<string>;\n}\n\nconst fetchTextWith =\n (crossOrigin?: string | null) =>\n async (url: string): Promise<string> => {\n if (typeof fetch !== \"function\") throw new Error(\"fetch is unavailable\");\n const response = await fetch(url, {\n credentials:\n crossOrigin === \"use-credentials\" ? \"include\" : \"same-origin\",\n });\n if (!response.ok) throw new Error(`HTTP ${response.status}`);\n return response.text();\n };\n\n/** Plain text of a TextTrack's active cues (one cue per line). */\nexport function textTrackCueText(track: TextTrack | null | undefined): string {\n const cues = track?.activeCues;\n if (!cues) return \"\";\n const lines: string[] = [];\n for (let i = 0; i < cues.length; i++) {\n const cue = cues[i] as (TextTrackCue & { text?: string }) | undefined;\n const text = cueText(cue?.text ?? \"\");\n if (text) lines.push(text);\n }\n return lines.join(\"\\n\");\n}\n\n/**\n * Shows the captions of `tracks[index]` (`-1` = off) of a media element whose\n * <track> children render `tracks` in order: the selected TextTrack is\n * `hidden` (loaded, not drawn by the browser) and `onText` receives the text\n * of its active cues on each `cuechange`. SRT files, failed <track> loads and\n * media without TextTrack support fall back to fetching and parsing the file\n * (`loadCaptions`), synchronized on `timeupdate`. While the video is in the\n * browser's own fullscreen (iOS) or picture-in-picture window, where the\n * overlay can't be seen, the track is `showing` instead.\n *\n * Returns the cleanup (removes the listeners, disables the tracks).\n */\nexport function bindMediaCaptions(\n media: HTMLMediaElement,\n tracks: readonly MediaTrack[],\n index: number,\n onText: (text: string) => void,\n options: MediaCaptionsOptions = {},\n): () => void {\n const elements = Array.from(media.children).filter(\n (el): el is HTMLTrackElement => el.localName === \"track\",\n );\n const textTrackOf = (el: HTMLTrackElement | undefined) => {\n try {\n return el?.track ?? null;\n } catch {\n return null;\n }\n };\n const setMode = (el: HTMLTrackElement | undefined, mode: TextTrackMode) => {\n const track = textTrackOf(el);\n if (track && track.mode !== mode) track.mode = mode;\n };\n elements.forEach((el, i) => {\n if (i !== index) setMode(el, \"disabled\");\n });\n\n let last: string | null = null;\n const emit = (text: string) => {\n if (text === last) return;\n last = text;\n onText(text);\n };\n\n const selected = index >= 0 ? tracks[index] : undefined;\n if (!selected) {\n emit(\"\");\n return () => undefined;\n }\n\n const cleanups: Array<() => void> = [];\n const on = (\n target: EventTarget,\n type: string,\n listener: EventListener,\n ): void => {\n target.addEventListener(type, listener);\n cleanups.push(() => target.removeEventListener(type, listener));\n };\n let disposed = false;\n\n const fallback = () => {\n let cues: MediaCue[] = [];\n const update = () => emit(activeCueText(cues, media.currentTime));\n emit(\"\");\n on(media, \"timeupdate\", update);\n on(media, \"seeked\", update);\n loadCaptions(\n selected.src,\n options.fetchText ?? fetchTextWith(options.crossOrigin),\n ).then(\n (loaded) => {\n if (disposed) return;\n cues = loaded;\n update();\n },\n () => {\n if (!disposed) emit(\"\");\n },\n );\n };\n\n const element = elements[index];\n const textTrack = textTrackOf(element);\n if (element && textTrack && !isSrtSource(selected.src)) {\n textTrack.mode = \"hidden\";\n let native = true;\n const onCueChange = () => {\n if (native) emit(textTrackCueText(textTrack));\n };\n on(textTrack, \"cuechange\", onCueChange);\n on(element, \"error\", () => {\n if (!native || disposed) return;\n native = false;\n fallback();\n });\n const show = () => {\n if (native) textTrack.mode = \"showing\";\n };\n const hide = () => {\n if (native) textTrack.mode = \"hidden\";\n };\n on(media, \"webkitbeginfullscreen\", show);\n on(media, \"webkitendfullscreen\", hide);\n on(media, \"enterpictureinpicture\", show);\n on(media, \"leavepictureinpicture\", hide);\n onCueChange();\n } else {\n setMode(element, \"disabled\");\n fallback();\n }\n\n return () => {\n disposed = true;\n for (const cleanup of cleanups.splice(0)) cleanup();\n setMode(element, \"disabled\");\n };\n}\n","// Maps a DOM selection inside a code block to offsets of its code, so an app\n// can save the selected range as a mark (`CodeMark` of @minerva/core). DOM\n// only (React DOM, Vue, Angular, Web Components, Taro H5).\n\n/** A selected range of a code block's code */\nexport interface CodeSelectionRange {\n /** Start offset (inclusive), in UTF-16 code units of the code */\n start: number;\n /** End offset (exclusive), in UTF-16 code units of the code */\n end: number;\n /** The selected code (`code.slice(start, end)`) */\n text: string;\n}\n\ntype Boundary = readonly [node: Node, offset: number];\n\n/** The <code> holding the text: `container` itself or its first <code>. */\nfunction codeRoot(container: Element | ShadowRoot): Node {\n if (container instanceof Element && container.localName === \"code\")\n return container;\n return container.querySelector(\"code\") ?? container;\n}\n\n/** Selected range(s) of `selection`, as boundaries (first start, last end). */\nfunction boundaries(\n selection: Selection | AbstractRange,\n root: Node,\n): [Boundary, Boundary] | null {\n if (\"rangeCount\" in selection) {\n if (!selection.rangeCount) return null;\n const shadow = root.getRootNode();\n // a selection inside a shadow root: the composed range (Chrome / Safari /\n // Firefox), else the plain ranges (light DOM or older browsers)\n let composed: StaticRange[] | null = null;\n if (\n typeof ShadowRoot !== \"undefined\" &&\n shadow instanceof ShadowRoot &&\n typeof (selection as SelectionWithComposed).getComposedRanges ===\n \"function\"\n ) {\n try {\n composed = (selection as SelectionWithComposed).getComposedRanges({\n shadowRoots: [shadow],\n });\n } catch {\n composed = null; // older signature: getComposedRanges(...roots)\n }\n }\n const first = composed?.[0] ?? selection.getRangeAt(0);\n const last =\n composed?.[composed.length - 1] ??\n selection.getRangeAt(selection.rangeCount - 1);\n return [\n [first.startContainer, first.startOffset],\n [last.endContainer, last.endOffset],\n ];\n }\n return [\n [selection.startContainer, selection.startOffset],\n [selection.endContainer, selection.endOffset],\n ];\n}\n\ninterface SelectionWithComposed extends Selection {\n getComposedRanges(options: { shadowRoots: ShadowRoot[] }): StaticRange[];\n}\n\n/** Offset in the text of `root` of a boundary point (clamped to the text). */\nfunction textOffset(root: Node, [node, offset]: Boundary, total: number) {\n if (node === root || root.contains(node)) {\n const range = (root.ownerDocument ?? document).createRange();\n range.setStart(root, 0);\n range.setEnd(node, offset);\n return Math.min(total, range.toString().length);\n }\n const position = root.compareDocumentPosition(node);\n if (position & Node.DOCUMENT_POSITION_CONTAINS) {\n // `node` is an ancestor: the boundary is before its child `offset`\n let child: Node = root;\n while (child.parentNode && child.parentNode !== node)\n child = child.parentNode;\n const index = Array.prototype.indexOf.call(node.childNodes, child);\n return index < offset ? total : 0;\n }\n return position & Node.DOCUMENT_POSITION_PRECEDING ? 0 : total;\n}\n\n/**\n * The mark of a click in a code block: the item of `marks` at the\n * `data-mark-index` of the <mark> holding `target` (inside `container`),\n * `undefined` elsewhere or when the click ends a text selection drag in the\n * code (the user was selecting, not clicking the mark). Used by the\n * CodeBlock `onMarkClick` / `mark-click` of the web renderers.\n */\nexport function clickedCodeMark<M>(\n target: EventTarget | null,\n container: Element,\n marks: readonly M[] | null | undefined,\n): M | undefined {\n const element =\n target && typeof (target as Element).closest === \"function\"\n ? (target as Element).closest(\"mark[data-mark-index]\")\n : null;\n if (!element || !container.contains(element)) return undefined;\n const root = container.getRootNode() as Document | ShadowRoot;\n const selection =\n (root as { getSelection?: () => Selection | null }).getSelection?.() ??\n container.ownerDocument.getSelection();\n if (\n selection &&\n !selection.isCollapsed &&\n container.contains(selection.anchorNode)\n )\n return undefined;\n return marks?.[Number(element.getAttribute(\"data-mark-index\"))];\n}\n\n/**\n * Offsets in the code of a selection made in a code block (CodeBlock of\n * every web renderer), to save it as a mark.\n *\n * `container` is the code block's <pre> (React `ref`, the Vue / Angular\n * element), its <code>, or any ancestor holding a single code block (its\n * first <code> is used); `selection` defaults to the document selection\n * (a `Range` / `StaticRange` also works). Line numbers are generated\n * content, so they never count. A selection extending outside the code is\n * clamped to it. Returns `null` without a DOM, a selection, or when nothing\n * of the code is selected.\n *\n * For `<minerva-code-block>` (shadow DOM) use its `getSelectionRange()`.\n */\nexport function getCodeSelectionRange(\n container: Element | ShadowRoot | null | undefined,\n selection?: Selection | AbstractRange | null,\n): CodeSelectionRange | null {\n if (!container || typeof document === \"undefined\") return null;\n const root = codeRoot(container);\n const source =\n selection === undefined\n ? (root.ownerDocument?.defaultView ?? window).getSelection()\n : selection;\n if (!source) return null;\n const points = boundaries(source, root);\n if (!points) return null;\n const code = root.textContent ?? \"\";\n const a = textOffset(root, points[0], code.length);\n const b = textOffset(root, points[1], code.length);\n const start = Math.min(a, b);\n const end = Math.max(a, b);\n if (start === end) return null;\n return { start, end, text: code.slice(start, end) };\n}\n","import type {\n ComponentTheme,\n CustomBilingualTheme,\n DefaultTheme,\n Theme,\n ThemeMap,\n ThemeName,\n} from \"@minerva/core\";\nimport { isThemeName, themeKeys, themes } from \"@minerva/core\";\n\nconst DARK_SCHEME_QUERY = \"(prefers-color-scheme: dark)\";\n\n/**\n * Read the user's preferred color scheme. Falls back to \"light\" when\n * `matchMedia` is unavailable (SSR, old browsers, some test environments).\n */\nexport const getSystemTheme = (): DefaultTheme => {\n if (typeof window === \"undefined\" || !window.matchMedia) return \"light\";\n return window.matchMedia(DARK_SCHEME_QUERY).matches ? \"dark\" : \"light\";\n};\n\nexport const isBilingualTheme = (\n theme: unknown,\n): theme is CustomBilingualTheme =>\n typeof theme === \"object\" &&\n theme !== null &&\n \"light\" in theme &&\n \"dark\" in theme &&\n typeof (theme as CustomBilingualTheme).light === \"object\" &&\n typeof (theme as CustomBilingualTheme).dark === \"object\";\n\n/**\n * Resolve any accepted theme value to a concrete theme object.\n * - \"auto\" and light/dark pairs follow `systemTheme`\n * - built-in names are looked up in `themes`\n * - plain objects are used as-is\n */\nexport const resolveTheme = (\n theme: Theme,\n systemTheme: DefaultTheme = getSystemTheme(),\n): ComponentTheme | ThemeMap => {\n if (theme === \"auto\" || theme === \"system\") return themes[systemTheme];\n if (typeof theme === \"string\") {\n if (!isThemeName(theme)) {\n throw new Error(\n `Unsupported theme \"${theme}\", expected one of: auto, system, ${Object.keys(themes).join(\", \")}`,\n );\n }\n return themes[theme];\n }\n if (isBilingualTheme(theme)) return theme[systemTheme];\n return theme;\n};\n\n/** Keys written by the last `generateCSSVariables` call, per target. */\nconst appliedKeys = new WeakMap<CSSStyleDeclaration, Set<string>>();\n\n/**\n * Write every theme entry as a CSS custom property (`--<key>`).\n *\n * Variables written by a previous call on the same target (and any built-in\n * theme key) that the new theme does not define are removed, so switching from\n * e.g. a dark theme that sets `--surface-color` to a custom theme that does not\n * falls back to the stylesheet default instead of keeping a stale value.\n *\n * @param themeStyles {CSSStyleDeclaration} - Target style declaration\n * @param theme {ComponentTheme | ThemeMap} - Theme object\n */\nexport const generateCSSVariables = (\n themeStyles: CSSStyleDeclaration,\n theme: ComponentTheme | ThemeMap,\n) => {\n const next = new Set<string>();\n Object.entries(theme).forEach(([key, value]) => {\n if (value !== undefined && value !== null && value !== \"\") next.add(key);\n });\n\n const stale = new Set([\n ...(appliedKeys.get(themeStyles) ?? []),\n ...themeKeys,\n ]);\n stale.forEach((key) => {\n if (!next.has(key)) themeStyles.removeProperty(`--${key}`);\n });\n\n next.forEach((key) => {\n themeStyles.setProperty(\n `--${key}`,\n String((theme as Record<string, string>)[key]),\n );\n });\n appliedKeys.set(themeStyles, next);\n};\n\n/**\n * Apply theme styles to the document root\n * @param theme {Theme | ThemeName} - Theme name or object\n * @param systemTheme {DefaultTheme} - Scheme used for \"auto\" and light/dark pairs\n */\nexport const applyThemeStyles = (\n theme: Theme | ThemeName,\n systemTheme?: DefaultTheme,\n) => {\n generateCSSVariables(\n document.documentElement.style,\n resolveTheme(theme, systemTheme),\n );\n};\n","/**\n * Server-safe theme helpers (web): cookie names, cookie parsing and the\n * no-flash init script.\n *\n * This module has no framework import and no DOM access at load time (the\n * init script only runs in the browser). It lives in `@minerva/dom` (web\n * only: cookies and `<html>` attributes) and is re-exported by the server-safe\n * `minerva-design/theme-utils` entry, so React Server Components (e.g. a\n * root layout) can read the theme cookies and inline the init script.\n *\n * Theme model (two orthogonal axes):\n * mode \"light\" | \"dark\" | \"system\" (system follows prefers-color-scheme)\n * palette \"editorial\" | \"tech\" | \"graphite\" | \"cool\" | none (Minerva's default look)\n *\n * Both are reflected on `<html>` as `data-theme` (resolved light / dark) and\n * `data-palette`, which select the palette token blocks of `style.css`.\n *\n * import { THEME_INIT_SCRIPT } from \"minerva-design/theme-utils\";\n *\n * <html suppressHydrationWarning>\n * <head>\n * <script suppressHydrationWarning dangerouslySetInnerHTML={{ __html: THEME_INIT_SCRIPT }} />\n * </head>\n * ...\n */\n\nimport {\n PALETTES,\n designAttributes,\n isPalette,\n isThemeMode,\n presetPalette,\n type DesignOptions,\n type Palette,\n type ThemeMode,\n} from \"@minerva/core\";\n\n/** Cookie storing the {@link ThemeMode}. */\nexport const THEME_COOKIE_NAME = \"theme\";\n\n/** Cookie storing the {@link Palette}. */\nexport const PALETTE_COOKIE_NAME = \"palette\";\n\n/** Cookie lifetime: one year, in seconds. */\nexport const THEME_COOKIE_MAX_AGE = 60 * 60 * 24 * 365;\n\n/** Parse a raw `theme` cookie value; invalid / missing values give `fallback`. */\nexport function parseThemeCookie(\n value: string | undefined | null,\n fallback: ThemeMode = \"system\",\n): ThemeMode {\n return isThemeMode(value) ? value : fallback;\n}\n\n/**\n * Parse a raw `palette` cookie value; invalid / missing values give `fallback`\n * (`null` = no palette, Minerva's default look).\n */\nexport function parsePaletteCookie<F extends Palette | null = null>(\n value: string | undefined | null,\n fallback: F = null as F,\n): Palette | F {\n return isPalette(value) ? value : fallback;\n}\n\n/**\n * Read one cookie from a `Cookie` header / `document.cookie` string.\n * Returns `undefined` when absent. Values are URI-decoded.\n */\nexport function readCookieValue(\n cookieHeader: string | undefined | null,\n name: string,\n): string | undefined {\n if (!cookieHeader) return undefined;\n for (const part of cookieHeader.split(\";\")) {\n const index = part.indexOf(\"=\");\n if (index === -1) continue;\n if (part.slice(0, index).trim() !== name) continue;\n const raw = part.slice(index + 1).trim();\n try {\n return decodeURIComponent(raw);\n } catch {\n return raw;\n }\n }\n return undefined;\n}\n\n/** Theme preferences parsed from a request's `Cookie` header. */\nexport interface ThemeCookies {\n theme: ThemeMode;\n palette: Palette | null;\n}\n\n/** Parse both theme cookies from a `Cookie` header (server side). */\nexport function parseThemeCookies(\n cookieHeader: string | undefined | null,\n defaults: { theme?: ThemeMode; palette?: Palette | null } = {},\n): ThemeCookies {\n return {\n theme: parseThemeCookie(\n readCookieValue(cookieHeader, THEME_COOKIE_NAME),\n defaults.theme ?? \"system\",\n ),\n palette: parsePaletteCookie(\n readCookieValue(cookieHeader, PALETTE_COOKIE_NAME),\n defaults.palette ?? null,\n ),\n };\n}\n\n/** `Set-Cookie`-style string for a theme preference (client or server). */\nexport function serializeThemeCookie(name: string, value: string): string {\n return `${name}=${encodeURIComponent(value)}; path=/; max-age=${THEME_COOKIE_MAX_AGE}; SameSite=Lax`;\n}\n\nexport interface ThemeInitScriptOptions {\n /** Mode used when the cookie is missing / invalid. @default \"system\" */\n defaultTheme?: ThemeMode;\n /**\n * Palette used when the cookie is missing / invalid and `<html>` has no\n * valid `data-palette` yet. `null` leaves `data-palette` unset (Minerva's\n * default look). @default null\n */\n defaultPalette?: Palette | null;\n /**\n * Design axes (preset / density / radius / shadow / font scale) written on\n * `<html>` as data attributes before the first paint. The preset's palette\n * is used as `defaultPalette` unless one is given.\n */\n design?: DesignOptions;\n}\n\nconst escapeRegExp = (value: string) =>\n value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\n/**\n * Build the inline, render-blocking init script. Before hydration it reads the\n * `theme` / `palette` cookies (falling back to `prefers-color-scheme` and the\n * defaults) and writes `data-theme`, `data-palette` and `color-scheme` on\n * `<html>`, so the first paint already uses the right tokens (no flash).\n */\nexport function createThemeInitScript(\n options: ThemeInitScriptOptions = {},\n): string {\n const defaultTheme = parseThemeCookie(options.defaultTheme);\n const fallbackPalette =\n options.defaultPalette === undefined\n ? presetPalette(options.design?.preset)\n : options.defaultPalette;\n const defaultPalette = isPalette(fallbackPalette) ? fallbackPalette : \"\";\n const design = options.design\n ? Object.entries(designAttributes(options.design))\n .map(([name, value]) => `d.setAttribute('${name}','${value}');`)\n .join(\"\")\n : \"\";\n const palettes = `[${PALETTES.map((p) => `'${p}'`).join(\",\")}]`;\n const themeRe = `/(?:^|; )${escapeRegExp(THEME_COOKIE_NAME)}=([^;]+)/`;\n const paletteRe = `/(?:^|; )${escapeRegExp(PALETTE_COOKIE_NAME)}=([^;]+)/`;\n return (\n `(function(){try{var d=document.documentElement,c=document.cookie,P=${palettes};` +\n `var tm=c.match(${themeRe});var t=tm?tm[1]:'${defaultTheme}';` +\n `if(t!=='light'&&t!=='dark'&&t!=='system')t='${defaultTheme}';` +\n `if(t==='system')t=window.matchMedia&&window.matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light';` +\n `d.dataset.theme=t;d.style.colorScheme=t;` +\n `var hp=d.dataset.palette;var f=P.indexOf(hp)>-1?hp:'${defaultPalette}';` +\n `var pm=c.match(${paletteRe});var p=pm?pm[1]:f;if(P.indexOf(p)<0)p=f;` +\n `if(p)d.dataset.palette=p;else delete d.dataset.palette;${design}}catch(e){}})();`\n );\n}\n\n/**\n * Default init script: cookie mode (else system), cookie palette (else the\n * `data-palette` already rendered on `<html>`, else none).\n */\nexport const THEME_INIT_SCRIPT: string =\n /* @__PURE__ */ createThemeInitScript();\n","/**\n * Content-Security-Policy support for the inline theme init script.\n *\n * A strict CSP (`script-src 'nonce-…'` or `'sha256-…'`, no\n * `'unsafe-inline'`) blocks an inline `<script>` unless it carries the\n * request's nonce or its hash is listed. Either render\n * `<script nonce={nonce}>` with the script, or list the script's hash:\n *\n * Content-Security-Policy: script-src 'self' ${THEME_INIT_SCRIPT_HASH}\n *\n * `cspHash()` computes it for a custom `createThemeInitScript(...)` output\n * (synchronous and dependency-free, so it works in every server runtime).\n */\nimport { THEME_INIT_SCRIPT } from \"./cookies\";\n\nconst K = [\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,\n 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,\n 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,\n 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,\n 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,\n 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,\n 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,\n 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,\n 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n];\n\n/** UTF-8 bytes of `text` (TextEncoder is not available in every runtime) */\nfunction utf8(text: string): number[] {\n const bytes: number[] = [];\n for (const char of text) {\n const code = char.codePointAt(0)!;\n if (code < 0x80) bytes.push(code);\n else if (code < 0x800) bytes.push(0xc0 | (code >> 6), 0x80 | (code & 63));\n else if (code < 0x10000) {\n bytes.push(\n 0xe0 | (code >> 12),\n 0x80 | ((code >> 6) & 63),\n 0x80 | (code & 63),\n );\n } else {\n bytes.push(\n 0xf0 | (code >> 18),\n 0x80 | ((code >> 12) & 63),\n 0x80 | ((code >> 6) & 63),\n 0x80 | (code & 63),\n );\n }\n }\n return bytes;\n}\n\n/** SHA-256 digest of the UTF-8 encoding of `text` */\nfunction sha256(text: string): number[] {\n const bytes = utf8(text);\n const bitLength = bytes.length * 8;\n bytes.push(0x80);\n while (bytes.length % 64 !== 56) bytes.push(0);\n const high = Math.floor(bitLength / 0x100000000);\n for (const word of [high, bitLength >>> 0]) {\n bytes.push(\n (word >>> 24) & 255,\n (word >>> 16) & 255,\n (word >>> 8) & 255,\n word & 255,\n );\n }\n const h = [\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c,\n 0x1f83d9ab, 0x5be0cd19,\n ];\n const w = new Array<number>(64);\n const rotr = (x: number, n: number) => (x >>> n) | (x << (32 - n));\n for (let offset = 0; offset < bytes.length; offset += 64) {\n for (let i = 0; i < 16; i++) {\n const j = offset + i * 4;\n w[i] =\n (bytes[j] << 24) |\n (bytes[j + 1] << 16) |\n (bytes[j + 2] << 8) |\n bytes[j + 3];\n }\n for (let i = 16; i < 64; i++) {\n const s0 = rotr(w[i - 15], 7) ^ rotr(w[i - 15], 18) ^ (w[i - 15] >>> 3);\n const s1 = rotr(w[i - 2], 17) ^ rotr(w[i - 2], 19) ^ (w[i - 2] >>> 10);\n w[i] = (w[i - 16] + s0 + w[i - 7] + s1) | 0;\n }\n let [a, b, c, d, e, f, g, hh] = h;\n for (let i = 0; i < 64; i++) {\n const s1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);\n const ch = (e & f) ^ (~e & g);\n const t1 = (hh + s1 + ch + K[i] + w[i]) | 0;\n const s0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);\n const maj = (a & b) ^ (a & c) ^ (b & c);\n const t2 = (s0 + maj) | 0;\n hh = g;\n g = f;\n f = e;\n e = (d + t1) | 0;\n d = c;\n c = b;\n b = a;\n a = (t1 + t2) | 0;\n }\n h[0] = (h[0] + a) | 0;\n h[1] = (h[1] + b) | 0;\n h[2] = (h[2] + c) | 0;\n h[3] = (h[3] + d) | 0;\n h[4] = (h[4] + e) | 0;\n h[5] = (h[5] + f) | 0;\n h[6] = (h[6] + g) | 0;\n h[7] = (h[7] + hh) | 0;\n }\n return h.flatMap((x) => [\n (x >>> 24) & 255,\n (x >>> 16) & 255,\n (x >>> 8) & 255,\n x & 255,\n ]);\n}\n\nconst BASE64 =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\nfunction base64(bytes: number[]): string {\n let out = \"\";\n for (let i = 0; i < bytes.length; i += 3) {\n const [a, b = 0, c = 0] = bytes.slice(i, i + 3);\n const n = (a << 16) | (b << 8) | c;\n out += BASE64[(n >> 18) & 63] + BASE64[(n >> 12) & 63];\n out += i + 1 < bytes.length ? BASE64[(n >> 6) & 63] : \"=\";\n out += i + 2 < bytes.length ? BASE64[n & 63] : \"=\";\n }\n return out;\n}\n\n/**\n * CSP source expression of an inline script: `'sha256-<base64 digest>'` of\n * its exact text (the content of the `<script>` element, byte for byte).\n */\nexport function cspHash(script: string): string {\n return `'sha256-${base64(sha256(script))}'`;\n}\n\n/** `cspHash(THEME_INIT_SCRIPT)`, for `script-src` of a strict CSP */\nexport const THEME_INIT_SCRIPT_HASH: string =\n /* @__PURE__ */ cspHash(THEME_INIT_SCRIPT);\n","// Applies the design axes (see `designAttributes` in @minerva/core) to a DOM\n// element. Web only: other renderers resolve the design to concrete values\n// (`resolveTokens`) instead of data attributes.\nimport {\n DESIGN_ATTRIBUTES,\n designAttributes,\n type DesignOptions,\n type ResolvedDesign,\n} from \"@minerva/core\";\n\n/**\n * Writes (or removes) the design attributes on an element. Standard values\n * are removed unless `all` is set.\n */\nexport function applyDesignAttributes(\n element: Element,\n design: DesignOptions | ResolvedDesign | null,\n { all = false }: { all?: boolean } = {},\n): void {\n const attributes = design ? designAttributes(design, { all }) : {};\n for (const name of Object.values(DESIGN_ATTRIBUTES)) {\n const value = attributes[name];\n if (value === undefined) element.removeAttribute(name);\n else element.setAttribute(name, value);\n }\n}\n","// Brand color (`primaryColor`) of the web renderers as CSS variables: the\n// token block of core's `primaryColorTokens`, serialized like tokens.css.\nimport {\n primaryColorTokens,\n tokenToCss,\n type PrimaryColorPair,\n type ResolvedThemeMode,\n type ThemeMap,\n} from \"@minerva/core\";\n\n/** Theme / palette tokens a brand color is applied over */\ntype BaseTheme = object | null | undefined;\n\n/**\n * The brand color of `mode` as theme entries (`{ \"primary-color\": ...,\n * \"primary-color-hover\": \"color-mix(...)\", ... }`), ready for\n * `generateCSSVariables` or an inline `style`. `base` is the theme or\n * palette it is applied over (keeps a palette's distinct accent).\n */\nexport function primaryColorTheme(\n pair: PrimaryColorPair,\n mode: ResolvedThemeMode,\n base?: BaseTheme,\n): ThemeMap {\n return Object.fromEntries(\n Object.entries(primaryColorTokens(pair[mode], base)).map(([key, value]) => [\n key,\n tokenToCss(value),\n ]),\n ) as ThemeMap;\n}\n\n/** Options of `primaryColorCss`. */\nexport interface PrimaryColorCssOptions {\n /**\n * Element the rules target\n * @default \":root\"\n */\n selector?: string;\n /** Theme / palette each mode is applied over */\n base?: Partial<Record<ResolvedThemeMode, BaseTheme>>;\n}\n\n/**\n * A style sheet applying a brand color before any script runs (server\n * rendering): the light values on `selector`, the dark ones when it has\n * `data-theme=\"dark\"` (set by `THEME_INIT_SCRIPT` / the root provider).\n * Colors are normalized by `resolvePrimaryColor`, so the text is safe to\n * inline in a `<style>` element.\n */\nexport function primaryColorCss(\n pair: PrimaryColorPair,\n { selector = \":root\", base }: PrimaryColorCssOptions = {},\n): string {\n const block = (mode: ResolvedThemeMode) =>\n Object.entries(primaryColorTheme(pair, mode, base?.[mode]))\n .map(([key, value]) => `--${key}:${String(value)}`)\n .join(\";\");\n return `${selector}:not([data-theme=dark]){${block(\"light\")}}${selector}[data-theme=dark]{${block(\"dark\")}}`;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["host","offset","offsetMiddleware","flip","flipMiddleware","shift","shiftMiddleware","sizeMiddleware","arrowMiddleware","canUseDOM","getOwnerDocument","node","getOwnerWindow","isHTMLElement","value","win","getActiveElement","active","root","contains","parent","child","isShadowRoot","flat","flatParentNode","shadow","slotOf","getEventTarget","path","event","FOCUSABLE_SELECTOR","isDisabled","el","fieldset","legend","assigned","name","slot","flatParent","isHiddenByStyle","summary","visibility","isFocusable","getTabIndex","attr","isTabbable","collect","out","visit","renderRoot","container","getFocusables","all","options","asRadio","input","radioGroupOf","radio","getTabbables","tabbables","radioGroups","chosen","scope","groups","current","positive","item","a","b","natural","focusElement","doc","previous","focused","focusFirst","candidate","candidates","sharedState","symbol","key","init","FOCUS_SCOPE_MOUNT_EVENT","FOCUS_SCOPE_UNMOUNT_EVENT","scopeStack","topScope","i","pushScope","entry","removeScope","index","runAutoFocusHandler","type","handler","withoutLinksFirst","isLink","items","createFocusScope","userPaused","stackPaused","previouslyFocused","lastFocused","addedTabIndex","observer","isPaused","paused","focusInside","onFocusIn","trapped","target","onFocusOut","next","onKeyDown","loop","first","last","onMutations","resolveAutoFocusTarget","autoFocus","ObserverCtor","onMountAutoFocus","now","restoreFocus","onUnmountAutoFocus","getFocusScopeCount","ESCAPE_CONSUMER_ATTRIBUTE","layersOf","layers","layer","findLayer","parentOf","l","isAncestor","seen","p","ancestor","isInside","branch","other","highestModalIndex","stack","isPointerEventsEnabled","setInlinePointerEvents","style","syncPointerEvents","modalIndex","state","documents","body","enable","runHandlers","wasPrevented","cancelled","preventedUncancelable","restore","native","handlers","dismissOutside","kind","attachDocument","existing","top","pendingClick","onPointerDown","detachDocument","createDismissableLayer","element","sameDocument","implicitParent","destroyed","handle","getLayerStack","SCROLLBAR_GAP_VAR","locks","getScrollbarGap","gap","applyLock","html","isPage","saved","computed","lockScroll","released","isScrollLocked","KEEP_VISIBLE_SELECTOR","IGNORED_TAGS","hasAttribute","attribute","hide","count","counters","preexisting","unhide","hideOthers","list","targets","targetSet","keep","hidden","walk","undone","defaultIsDisabled","defaultGetText","createRovingFocus","typeahead","createTypeahead","getItems","itemSelector","sync","isItemDisabled","activate","changed","focus","onActiveChange","itemFromEvent","currentIndex","getNextIndex","focusOnMove","getItemText","opts","nearestInRow","origin","from","centerX","best","bestRow","bestDx","elements","rect","dy","direction","dx","composedParent","getDirection","dir","resolveDirection","explicit","logicalArrowKey","centerInScroller","max","scroller","view","delta","min","upper","clamped","getPortalContainer","PORTAL_HOST_ATTRIBUTE","createPortalHost","host","VIEWPORT_PADDING","ARROW_PADDING","buildMiddleware","offset$1","flip$1","shift$1","mainAxis","crossAxis","middleware","offset","flip","shift","limitShift","sizing","matchAnchorWidth","fitViewportHeight","size","availableWidth","availableHeight","rects","arrowElement","arrow","computeAnchoredPosition","sizeData","result","computePosition","reference","floating","arrowData","autoPosition","stop","autoUpdate","onUpdate","parsePlacement","side","align","placement","toPlacement","CAMEL_TO_PLACEMENT","map","fromCamelPlacement","toCamelPlacement","c","getTransformOrigin","alignPercent","vertical","cross","arrowSize","main","applyPosition","isPointInPolygon","point","inside","j","polygon","xi","yi","xj","yj","y","x","getGraceArea","exitPoint","padding","createPointerGrace","area","startedAt","expired","timeout","targetRect","maxTime","part","getExitAnimationDuration","animation","transition","waitForExitAnimation","duration","events","done","onEnd","timer","resolve","getAdjacentTabbable","NON_TEXT_INPUT_TYPES","isEditableTarget","INTERACTIVE_SELECTOR","role","isInteractiveEventTarget","DASHBOARD_COLUMN_ATTRIBUTE","DASHBOARD_CARD_ATTRIBUTE","MOUSE_THRESHOLD","TOUCH_DELAY","TOUCH_TOLERANCE","EDGE","MAX_SPEED","text","dashboardDataAdapter","ownColumn","parts","column","names","adapter","title","card","empty","visuallyHidden","createDashboardDrag","drag","pending","hint","live","line","frame","keyedColumns","keyedCards","layout","columnElement","cardOf","cardFromPath","ensureLayer","refresh","cancel","toggle","announce","position","message","dashboardSlots","box","accept","isDashboardNoop","move","targetAt","distance","d","midpoints","dashboardCardMove","dashboardInsertIndex","paint","others","left","width","placeGhost","lift","pointer","mode","ghost","onDocumentKeyDown","preventDefault","autoScroll","onCardBlur","finish","stopPointer","drop","attempt","onPointerMove","onPointerUp","onPointerCancel","onTouchMove","startPointerDrag","id","startsOnControl","touch","moved","retarget","same","swallowClick","edgeScroll","start","end","axis","edge","step","before","scrolled","reveal","outer","inner","action","dashboardKeyAction","dashboardKeyboardTarget","neighbor","onDragStart","KANBAN_COLUMN_ATTRIBUTE","KANBAN_CARD_ATTRIBUTE","kanbanDataAdapter","createKanbanDrag","fetchTextWith","response","url","crossOrigin","textTrackCueText","cues","track","lines","cue","cueText","bindMediaCaptions","media","textTrackOf","setMode","emit","onText","selected","tracks","cleanups","on","listener","disposed","fallback","update","activeCueText","loadCaptions","loaded","textTrack","isSrtSource","onCueChange","show","cleanup","codeRoot","boundaries","selection","composed","textOffset","range","total","clickedCodeMark","marks","getCodeSelectionRange","source","points","code","DARK_SCHEME_QUERY","getSystemTheme","isBilingualTheme","theme","resolveTheme","themes","systemTheme","isThemeName","appliedKeys","generateCSSVariables","themeStyles","themeKeys","applyThemeStyles","THEME_COOKIE_NAME","PALETTE_COOKIE_NAME","THEME_COOKIE_MAX_AGE","parseThemeCookie","isThemeMode","parsePaletteCookie","isPalette","readCookieValue","cookieHeader","raw","parseThemeCookies","defaults","serializeThemeCookie","escapeRegExp","createThemeInitScript","defaultTheme","fallbackPalette","presetPalette","defaultPalette","design","designAttributes","PALETTES","THEME_INIT_SCRIPT","K","utf8","bytes","char","sha256","bitLength","high","word","h","w","rotr","n","s0","s1","e","f","g","hh","ch","t1","t2","BASE64","base64","cspHash","script","THEME_INIT_SCRIPT_HASH","applyDesignAttributes","attributes","DESIGN_ATTRIBUTES","primaryColorTheme","primaryColorTokens","pair","base","tokenToCss","primaryColorCss","block","selector"],"sources":["../../../dom/src/dom.ts","../../../dom/src/internal/shared-state.ts","../../../dom/src/focus-scope.ts","../../../dom/src/dismissable-layer.ts","../../../dom/src/scroll-lock.ts","../../../dom/src/hide-others.ts","../../../dom/src/roving-focus.ts","../../../dom/src/nearest-in-row.ts","../../../dom/src/direction.ts","../../../dom/src/center-in-scroller.ts","../../../dom/src/portal.ts","../../../dom/src/positioning.ts","../../../dom/src/pointer-grace.ts","../../../dom/src/presence.ts","../../../dom/src/adjacent-tabbable.ts","../../../dom/src/editable-target.ts","../../../dom/src/interactive-target.ts","../../../dom/src/dashboard-drag.ts","../../../dom/src/media-captions.ts","../../../dom/src/code-selection.ts","../../../dom/src/theme/apply-theme.ts","../../../dom/src/theme/cookies.ts","../../../dom/src/theme/csp.ts","../../../dom/src/theme/design-attributes.ts","../../../dom/src/theme/primary-color.ts"],"sourcesContent":["/**\n * Small DOM helpers shared by every primitive. All of them are safe to import\n * on the server: nothing touches `window` / `document` until called.\n */\n\n/** `true` when running in a browser-like environment (window + document). */\nexport function canUseDOM(): boolean {\n return (\n typeof window !== \"undefined\" &&\n typeof document !== \"undefined\" &&\n typeof document.createElement === \"function\"\n );\n}\n\n/**\n * Returns the document owning `node` (or the node itself when it is a\n * Document). Falls back to the global `document`.\n */\nexport function getOwnerDocument(node?: Node | null): Document {\n if (node) {\n if (node.nodeType === 9) return node as Document;\n if (node.ownerDocument) return node.ownerDocument;\n }\n return document;\n}\n\n/** The window owning `node` (falls back to the global `window`). */\nexport function getOwnerWindow(node?: Node | null): Window & typeof globalThis {\n return (getOwnerDocument(node).defaultView ?? window) as Window &\n typeof globalThis;\n}\n\n/** Whether `value` is an `HTMLElement` (realm-safe: works across iframes). */\nexport function isHTMLElement(value: unknown): value is HTMLElement {\n if (!value || typeof value !== \"object\") return false;\n const node = value as Node;\n if (node.nodeType !== 1) return false;\n const win = node.ownerDocument?.defaultView;\n if (win && value instanceof win.HTMLElement) return true;\n return typeof HTMLElement !== \"undefined\" && value instanceof HTMLElement;\n}\n\n/**\n * The deepest focused element, piercing open shadow roots.\n * @param root - Document or shadow root to start from. @default document\n */\nexport function getActiveElement(\n root: Document | ShadowRoot = document,\n): Element | null {\n let active = root.activeElement;\n while (active?.shadowRoot?.activeElement) {\n active = active.shadowRoot.activeElement;\n }\n return active;\n}\n\n/**\n * Like `Node.contains`, but also returns `true` when `child` lives inside a\n * shadow tree hosted (at any depth) by `parent`, or is rendered inside\n * `parent` through a `<slot>` (flat tree: light DOM content slotted into a\n * shadow tree, e.g. the body of a custom element dialog).\n */\nexport function contains(\n parent: Node | null | undefined,\n child: Node | null | undefined,\n): boolean {\n if (!parent || !child) return false;\n let node: Node | null = child;\n while (node) {\n if (parent === node || parent.contains(node)) return true;\n const root = node.getRootNode();\n node = isShadowRoot(root) ? root.host : null;\n }\n for (let flat = flatParentNode(child); flat; flat = flatParentNode(flat)) {\n if (flat === parent) return true;\n }\n return false;\n}\n\n/** Parent of `node` in the flat tree (slot of slotted content, host of a shadow root). */\nfunction flatParentNode(node: Node): Node | null {\n const parent = node.parentNode;\n if (!parent) return null;\n if (isShadowRoot(parent)) return parent.host;\n const shadow = (parent as Element).shadowRoot;\n return shadow ? slotOf(node, shadow) : parent;\n}\n\nfunction isShadowRoot(node: Node): node is ShadowRoot {\n return node.nodeType === 11 && \"host\" in node && !!(node as ShadowRoot).host;\n}\n\n/** The event's real target, piercing open shadow roots (`composedPath()[0]`). */\nexport function getEventTarget(event: Event): EventTarget | null {\n const path = event.composedPath?.();\n return (path && path.length > 0 ? path[0] : event.target) ?? null;\n}\n\n// Written without a top-level call so bundlers can drop it when unused.\nconst FOCUSABLE_SELECTOR =\n \"a[href],area[href],button,input,select,textarea,iframe,object,embed,\" +\n \"audio[controls],video[controls],summary,[contenteditable],[tabindex]\";\n\nfunction isDisabled(el: Element): boolean {\n if ((el as HTMLButtonElement).disabled === true) return true;\n if (el.hasAttribute(\"disabled\") && \"disabled\" in el) return true;\n // A disabled <fieldset> disables its controls, except inside its first legend.\n const fieldset = el.closest(\"fieldset[disabled]\");\n if (fieldset && \"disabled\" in el) {\n const legend = fieldset.querySelector(\":scope > legend\");\n if (!legend || !legend.contains(el)) return true;\n }\n return false;\n}\n\n/** Slot of a shadow root that `node` (a light child of its host) renders in. */\nfunction slotOf(node: Node, shadow: ShadowRoot): HTMLSlotElement | null {\n const assigned = (node as Element | Text).assignedSlot;\n if (assigned) return assigned;\n // DOMs without slot assignment (e.g. happy-dom): match by slot name.\n const name =\n node.nodeType === 1 ? ((node as Element).getAttribute(\"slot\") ?? \"\") : \"\";\n return (\n Array.from(shadow.querySelectorAll(\"slot\")).find(\n (slot) => (slot.getAttribute(\"name\") ?? \"\") === name,\n ) ?? null\n );\n}\n\n/**\n * Parent in the flat (rendered) tree: the slot an element is assigned to,\n * else its parent element, else the host of its shadow root. `false` when\n * the element is a light child of a shadow host that is not slotted (not\n * rendered at all).\n */\nfunction flatParent(el: Element): Element | null | false {\n const parent = el.parentElement;\n if (parent?.shadowRoot) return slotOf(el, parent.shadowRoot) ?? false;\n if (parent) return parent;\n const root = el.parentNode;\n return root && isShadowRoot(root) ? root.host : null;\n}\n\nfunction isHiddenByStyle(el: Element): boolean {\n const win = el.ownerDocument.defaultView;\n if (!win) return false;\n // `hidden` / display:none on any ancestor (in the flat tree, so through\n // slots and shadow roots) removes the whole subtree.\n for (let node: Element | null = el; node;) {\n if ((node as HTMLElement).hidden) return true;\n if (win.getComputedStyle(node).display === \"none\") return true;\n // closed <details>: only its <summary> is rendered\n if (\n node !== el &&\n node.tagName === \"DETAILS\" &&\n !(node as HTMLDetailsElement).open\n ) {\n const summary = node.querySelector(\":scope > summary\");\n if (!summary || !summary.contains(el)) return true;\n }\n const parent = flatParent(node);\n if (parent === false) return true;\n node = parent;\n }\n const visibility = win.getComputedStyle(el).visibility;\n return visibility === \"hidden\" || visibility === \"collapse\";\n}\n\n/**\n * Whether `el` can receive focus (programmatically or by pointer): a\n * focusable element that is not disabled, `inert`, hidden\n * (`hidden`, `display: none`, `visibility: hidden`, closed `<details>`)\n * nor an `<input type=\"hidden\">`.\n */\nexport function isFocusable(el: Element): boolean {\n if (!el.matches(FOCUSABLE_SELECTOR)) return false;\n if (el.matches(\"[contenteditable='false']\") && !el.hasAttribute(\"tabindex\"))\n return false;\n if (el.tagName === \"INPUT\" && (el as HTMLInputElement).type === \"hidden\")\n return false;\n if (\n el.tagName === \"SUMMARY\" &&\n el.parentElement?.tagName === \"DETAILS\" &&\n el.parentElement.querySelector(\":scope > summary\") !== el\n )\n return false;\n if (isDisabled(el)) return false;\n if (el.closest(\"[inert]\")) return false;\n return !isHiddenByStyle(el);\n}\n\nfunction getTabIndex(el: Element): number {\n const attr = el.getAttribute(\"tabindex\");\n if (attr !== null && attr.trim() !== \"\") {\n const value = Number.parseInt(attr, 10);\n if (!Number.isNaN(value)) return value;\n }\n return 0;\n}\n\n/** Whether `el` is reachable with the Tab key (focusable, tabindex >= 0). */\nexport function isTabbable(el: Element): boolean {\n return isFocusable(el) && getTabIndex(el) >= 0;\n}\n\n/**\n * Collects candidates in rendering (flat tree) order: open shadow roots are\n * walked instead of their host's light children, and a `<slot>` contributes\n * its assigned elements (or its fallback content when nothing is assigned).\n * Light children of a shadow host that are not slotted are not rendered, so\n * they are skipped, like the browser's sequential focus navigation does.\n */\nfunction collect(root: ParentNode, out: Element[]): void {\n for (const el of Array.from(root.children)) visit(el, out);\n}\n\nfunction visit(el: Element, out: Element[]): void {\n out.push(el);\n if (el.shadowRoot) {\n collect(el.shadowRoot, out);\n return;\n }\n if (el.tagName === \"SLOT\") {\n const assigned =\n (el as HTMLSlotElement).assignedElements?.({ flatten: true }) ?? [];\n if (assigned.length > 0) {\n for (const child of assigned) visit(child, out);\n return;\n }\n }\n collect(el, out);\n}\n\n/** The node whose descendants are rendered: a host's open shadow root. */\nfunction renderRoot(container: Element | ShadowRoot): ParentNode {\n return (container as Element).shadowRoot ?? container;\n}\n\nexport interface TabbableOptions {\n /**\n * Keep only one radio per group (checked one, or the first when none is\n * checked), like the browser's Tab order. @default true\n */\n radioGroups?: boolean;\n /** Also consider the container itself. @default false */\n includeContainer?: boolean;\n}\n\n/**\n * Focusable elements inside `container` (flat tree order: open shadow roots\n * and slotted content included; a shadow host is walked through its shadow\n * root), including `tabindex=\"-1\"` ones.\n */\nexport function getFocusables(\n container: Element | ShadowRoot,\n options: Pick<TabbableOptions, \"includeContainer\"> = {},\n): HTMLElement[] {\n const all: Element[] = [];\n if (options.includeContainer && container.nodeType === 1) {\n all.push(container as Element);\n }\n collect(renderRoot(container), all);\n return all.filter(\n (el): el is HTMLElement => isHTMLElement(el) && isFocusable(el),\n );\n}\n\nfunction asRadio(el: Element): HTMLInputElement | null {\n const input = el as HTMLInputElement;\n return input.tagName === \"INPUT\" && input.type === \"radio\" && input.name\n ? input\n : null;\n}\n\n/** Radios of one group: same name within the same form (or root node). */\nfunction radioGroupOf(radio: HTMLInputElement): [object, string] {\n return [radio.form ?? radio.getRootNode(), radio.name];\n}\n\n/**\n * Elements reachable with Tab inside `container`, in Tab order: positive\n * `tabindex` first (ascending), then `tabindex=0` / natural order.\n * Excludes disabled, hidden, inert and `tabindex=\"-1\"` elements, and\n * collapses radio groups to their checked (or first) radio.\n */\nexport function getTabbables(\n container: Element | ShadowRoot,\n options: TabbableOptions = {},\n): HTMLElement[] {\n const { radioGroups = true } = options;\n let tabbables = getFocusables(container, options).filter(\n (el) => getTabIndex(el) >= 0,\n );\n\n if (radioGroups) {\n // scope (form / root) -> group name -> chosen radio\n const chosen = new Map<object, Map<string, HTMLInputElement>>();\n for (const el of tabbables) {\n const radio = asRadio(el);\n if (!radio) continue;\n const [scope, name] = radioGroupOf(radio);\n let groups = chosen.get(scope);\n if (!groups) chosen.set(scope, (groups = new Map()));\n const current = groups.get(name);\n if (!current || (!current.checked && radio.checked)) {\n groups.set(name, radio);\n }\n }\n tabbables = tabbables.filter((el) => {\n const radio = asRadio(el);\n if (!radio) return true;\n const [scope, name] = radioGroupOf(radio);\n return chosen.get(scope)?.get(name) === radio;\n });\n }\n\n const positive = tabbables\n .map((el, index) => ({ el, index, tabIndex: getTabIndex(el) }))\n .filter((item) => item.tabIndex > 0)\n .sort((a, b) => a.tabIndex - b.tabIndex || a.index - b.index)\n .map((item) => item.el);\n const natural = tabbables.filter((el) => getTabIndex(el) === 0);\n return [...positive, ...natural];\n}\n\nexport interface FocusElementOptions {\n /** Do not scroll the element into view. @default false */\n preventScroll?: boolean;\n /** Select the text of inputs / textareas after focusing. @default false */\n select?: boolean;\n}\n\n/**\n * Focuses `el` (no-op for `null`). Returns `true` when `el` is focused\n * afterwards.\n */\nexport function focusElement(\n el: HTMLElement | SVGElement | null | undefined,\n options: FocusElementOptions = {},\n): boolean {\n if (!el || typeof el.focus !== \"function\") return false;\n const doc = getOwnerDocument(el);\n const previous = getActiveElement(doc);\n el.focus({ preventScroll: options.preventScroll ?? false });\n const focused = getActiveElement(doc) === el;\n if (\n focused &&\n options.select &&\n el !== previous &&\n (el.tagName === \"INPUT\" || el.tagName === \"TEXTAREA\") &&\n typeof (el as HTMLInputElement).select === \"function\"\n ) {\n (el as HTMLInputElement).select();\n }\n return focused;\n}\n\n/**\n * Focuses the first candidate that actually accepts focus.\n * @returns the focused element, or `null` when none did.\n */\nexport function focusFirst(\n candidates: Iterable<HTMLElement | null | undefined>,\n options: FocusElementOptions = {},\n): HTMLElement | null {\n for (const candidate of candidates) {\n if (focusElement(candidate, options)) return candidate as HTMLElement;\n }\n return null;\n}\n","/**\n * Runtime state shared by every copy of this package loaded in the realm\n * (the ESM and CJS builds side by side, duplicated bundles...). Stacks and\n * reference counts kept in plain module variables would split between\n * copies: e.g. two scroll locks on the same body, each believing it is the\n * only one, the first release restoring the styles under the second.\n *\n * The value is stored on `globalThis` under `Symbol.for(\"minerva.dom.<key>\")`,\n * created by the first copy that asks for it. Version the key (`\"x.v1\"`) and\n * bump it whenever the shape of the state changes, so copies of different\n * versions never read each other's state with the wrong shape.\n */\nexport function sharedState<T>(key: string, init: () => T): T {\n const symbol = Symbol.for(`minerva.dom.${key}`);\n const host = globalThis as unknown as Record<symbol, T | undefined>;\n let value = host[symbol];\n if (value === undefined) {\n value = init();\n Object.defineProperty(globalThis, symbol, {\n value,\n configurable: true,\n enumerable: false,\n writable: false,\n });\n }\n return value;\n}\n","import {\n contains,\n focusElement,\n focusFirst,\n getActiveElement,\n getEventTarget,\n getOwnerDocument,\n getTabbables,\n isHTMLElement,\n} from \"./dom\";\nimport { sharedState } from \"./internal/shared-state\";\n\n/** Name of the cancelable event dispatched on the container on activation. */\nexport const FOCUS_SCOPE_MOUNT_EVENT = \"minerva.focusScope.autoFocusOnMount\";\n/** Name of the cancelable event dispatched on the container on deactivation. */\nexport const FOCUS_SCOPE_UNMOUNT_EVENT =\n \"minerva.focusScope.autoFocusOnUnmount\";\n\n/**\n * Auto-focus callback: return `false` or call `event.preventDefault()` to\n * skip the default focus move (and move focus yourself if needed).\n */\nexport type FocusScopeAutoFocusHandler = (event: Event) => void | boolean;\n\nexport interface FocusScopeOptions {\n /**\n * Keep focus inside the container: Tab / Shift+Tab cannot leave it and\n * focus moving elsewhere is pulled back. @default false\n */\n trapped?: boolean;\n /** Tab on the last tabbable goes to the first (and vice versa). @default false */\n loop?: boolean;\n /**\n * What to focus on activation (skipped when focus is already inside):\n * `true` = first tabbable (links last) or the container; an element; or a\n * function returning one (falls back to `true` behaviour on `null`).\n * @default true\n */\n autoFocus?: boolean | HTMLElement | (() => HTMLElement | null);\n /**\n * Where focus goes on deactivation: `true` = the element that was focused\n * before activation; an element; `false` = leave focus alone.\n * @default true\n */\n restoreFocus?: boolean | HTMLElement;\n /** Called before auto-focusing on activation (cancelable). */\n onMountAutoFocus?: FocusScopeAutoFocusHandler;\n /** Called before restoring focus on deactivation (cancelable). */\n onUnmountAutoFocus?: FocusScopeAutoFocusHandler;\n}\n\nexport interface FocusScope {\n /** Starts the scope: auto-focus, trap, push onto the scope stack. */\n activate(): void;\n /**\n * Stops the scope: removes listeners, resumes the previous scope and\n * restores focus (deferred to the next macrotask, see below).\n */\n deactivate(): void;\n /** Temporarily stops trapping (e.g. while a nested non-modal layer is open). */\n pause(): void;\n /** Undoes `pause()`. */\n resume(): void;\n /** Whether the scope is active and not paused. */\n isActive(): boolean;\n}\n\ninterface ScopeEntry {\n doc: Document;\n setStackPaused(paused: boolean): void;\n}\n\n/**\n * Active scopes, last = topmost. Only the topmost scope of each document\n * traps focus (focus is per document). Shared by every module copy: two\n * stacks would leave two \"topmost\" traps fighting over focus.\n */\nconst scopeStack = sharedState(\"focus-scope.v1\", (): ScopeEntry[] => []);\n\nfunction topScope(doc: Document): ScopeEntry | undefined {\n for (let i = scopeStack.length - 1; i >= 0; i--) {\n if (scopeStack[i].doc === doc) return scopeStack[i];\n }\n return undefined;\n}\n\nfunction pushScope(entry: ScopeEntry) {\n topScope(entry.doc)?.setStackPaused(true);\n removeScope(entry);\n scopeStack.push(entry);\n entry.setStackPaused(false);\n}\n\nfunction removeScope(entry: ScopeEntry) {\n const index = scopeStack.indexOf(entry);\n if (index === -1) return;\n scopeStack.splice(index, 1);\n topScope(entry.doc)?.setStackPaused(false);\n}\n\nfunction runAutoFocusHandler(\n container: HTMLElement,\n type: string,\n handler: FocusScopeAutoFocusHandler | undefined,\n): boolean {\n const win = container.ownerDocument.defaultView;\n const EventCtor = win?.CustomEvent ?? CustomEvent;\n const event = new EventCtor(type, { bubbles: false, cancelable: true });\n container.dispatchEvent(event);\n const result = handler?.(event);\n return result !== false && !event.defaultPrevented;\n}\n\n/** Links are focused last on auto-focus (they are rarely the primary action). */\nfunction withoutLinksFirst(items: HTMLElement[]): HTMLElement[] {\n const isLink = (el: HTMLElement) => el.tagName === \"A\";\n return [...items.filter((el) => !isLink(el)), ...items.filter(isLink)];\n}\n\n/**\n * Creates a focus scope on `container`: auto-focus on activation, optional\n * focus trap (Tab wrapping, pulling focus back) and focus restoration on\n * deactivation.\n *\n * Scopes form a stack per document: activating a scope pauses the previous\n * one of the same document, deactivating it resumes it, so nested dialogs\n * work.\n *\n * Focus restoration runs in a `setTimeout(0)` after `deactivate()`, so it\n * works whether the container is removed before or after the call. It is\n * skipped when, by then, focus has deliberately moved elsewhere outside the\n * container (e.g. the user clicked another input).\n *\n * @example\n * const scope = createFocusScope(dialog, { trapped: true, loop: true });\n * scope.activate();\n * // ...\n * scope.deactivate();\n */\nexport function createFocusScope(\n container: HTMLElement,\n options: FocusScopeOptions = {},\n): FocusScope {\n const {\n trapped = false,\n loop = false,\n autoFocus = true,\n restoreFocus = true,\n onMountAutoFocus,\n onUnmountAutoFocus,\n } = options;\n\n const doc = getOwnerDocument(container);\n let active = false;\n let userPaused = false;\n let stackPaused = false;\n let previouslyFocused: HTMLElement | null = null;\n let lastFocused: HTMLElement | null = null;\n let addedTabIndex = false;\n let observer: MutationObserver | null = null;\n\n const isPaused = () => userPaused || stackPaused;\n const entry: ScopeEntry = {\n doc,\n setStackPaused(paused) {\n stackPaused = paused;\n },\n };\n\n const focusInside = () =>\n focusElement(lastFocused?.isConnected ? lastFocused : container, {\n select: true,\n }) || focusElement(container);\n\n const onFocusIn = (event: FocusEvent) => {\n if (!trapped || isPaused()) return;\n const target = getEventTarget(event);\n if (target instanceof Node && contains(container, target)) {\n if (isHTMLElement(target)) lastFocused = target;\n } else {\n focusInside();\n }\n };\n\n const onFocusOut = (event: FocusEvent) => {\n if (!trapped || isPaused()) return;\n const next = event.relatedTarget;\n // `null`: the window lost focus or the focused element was removed;\n // the latter is handled by the MutationObserver below.\n if (next === null) return;\n // `relatedTarget` is retargeted to the listener's tree: focus moving\n // into a shadow root reports the shadow host. When that host contains\n // the container, the real target is unknown here; the following\n // `focusin` (which carries the real target in its composed path) pulls\n // focus back if it really left.\n if (\n next instanceof Node &&\n (next as Element).shadowRoot &&\n contains(next, container)\n ) {\n return;\n }\n if (!(next instanceof Node) || !contains(container, next)) focusInside();\n };\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (!loop && !trapped) return;\n if (isPaused() || event.defaultPrevented) return;\n if (event.key !== \"Tab\" || event.altKey || event.ctrlKey || event.metaKey)\n return;\n const focused = getActiveElement(doc);\n const tabbables = getTabbables(container);\n if (tabbables.length === 0) {\n if (focused === container || trapped) event.preventDefault();\n return;\n }\n const first = tabbables[0];\n const last = tabbables[tabbables.length - 1];\n if (!event.shiftKey && focused === last) {\n event.preventDefault();\n if (loop) focusElement(first, { select: true });\n } else if (event.shiftKey && (focused === first || focused === container)) {\n event.preventDefault();\n if (loop) focusElement(last, { select: true });\n }\n };\n\n const onMutations = () => {\n if (!trapped || isPaused()) return;\n const focused = getActiveElement(doc);\n if (!focused || focused === doc.body) focusElement(container);\n };\n\n const resolveAutoFocusTarget = (): HTMLElement[] => {\n const tabbables = () => withoutLinksFirst(getTabbables(container));\n if (isHTMLElement(autoFocus)) return [autoFocus, ...tabbables()];\n if (typeof autoFocus === \"function\") {\n const target = autoFocus();\n return target ? [target, ...tabbables()] : tabbables();\n }\n return tabbables();\n };\n\n return {\n activate() {\n if (active) return;\n active = true;\n userPaused = false;\n const focused = getActiveElement(doc);\n previouslyFocused = isHTMLElement(focused) ? focused : null;\n\n if (!container.hasAttribute(\"tabindex\")) {\n container.setAttribute(\"tabindex\", \"-1\");\n addedTabIndex = true;\n }\n\n pushScope(entry);\n doc.addEventListener(\"focusin\", onFocusIn);\n doc.addEventListener(\"focusout\", onFocusOut);\n container.addEventListener(\"keydown\", onKeyDown);\n const ObserverCtor =\n doc.defaultView?.MutationObserver ??\n (typeof MutationObserver !== \"undefined\" ? MutationObserver : null);\n if (ObserverCtor) {\n observer = new ObserverCtor(onMutations);\n observer.observe(container, { childList: true, subtree: true });\n }\n\n const alreadyInside =\n focused instanceof Node && contains(container, focused);\n if (alreadyInside) {\n lastFocused = isHTMLElement(focused) ? focused : null;\n } else if (\n autoFocus !== false &&\n runAutoFocusHandler(\n container,\n FOCUS_SCOPE_MOUNT_EVENT,\n onMountAutoFocus,\n )\n ) {\n const target = focusFirst(resolveAutoFocusTarget(), { select: true });\n if (!target) focusElement(container);\n }\n const now = getActiveElement(doc);\n if (isHTMLElement(now) && contains(container, now)) lastFocused = now;\n },\n\n deactivate() {\n if (!active) return;\n active = false;\n doc.removeEventListener(\"focusin\", onFocusIn);\n doc.removeEventListener(\"focusout\", onFocusOut);\n container.removeEventListener(\"keydown\", onKeyDown);\n observer?.disconnect();\n observer = null;\n removeScope(entry);\n if (addedTabIndex) {\n container.removeAttribute(\"tabindex\");\n addedTabIndex = false;\n }\n\n const target =\n restoreFocus === false\n ? null\n : restoreFocus === true\n ? previouslyFocused\n : restoreFocus;\n previouslyFocused = null;\n lastFocused = null;\n if (!target) return;\n\n const win = doc.defaultView;\n const schedule = win?.setTimeout.bind(win) ?? setTimeout;\n schedule(() => {\n if (!target.isConnected) return;\n // Respect a deliberate focus move outside the (old) container.\n const focused = getActiveElement(doc);\n const focusLost =\n !focused ||\n focused === doc.body ||\n !focused.isConnected ||\n contains(container, focused);\n if (!focusLost) return;\n if (\n runAutoFocusHandler(\n container,\n FOCUS_SCOPE_UNMOUNT_EVENT,\n onUnmountAutoFocus,\n )\n ) {\n focusElement(target, { select: true });\n }\n }, 0);\n },\n\n pause() {\n userPaused = true;\n },\n\n resume() {\n userPaused = false;\n },\n\n isActive() {\n return active && !isPaused();\n },\n };\n}\n\n/** Number of active focus scopes (for tests / debugging). */\nexport function getFocusScopeCount(): number {\n return scopeStack.length;\n}\n","import { contains, getEventTarget, getOwnerDocument } from \"./dom\";\nimport { sharedState } from \"./internal/shared-state\";\n\n/**\n * Attribute marking an element that handles Escape itself while it is set:\n * Escape pressed inside it does not dismiss the topmost layer.\n */\nexport const ESCAPE_CONSUMER_ATTRIBUTE = \"data-minerva-escape-consumer\";\n\n/**\n * Outside-interaction callback. Receives the original DOM event; call\n * `event.preventDefault()` or return `false` to keep the layer open.\n */\nexport type DismissHandler<E extends Event> = (event: E) => void | boolean;\n\nexport interface DismissableLayerOptions {\n /** Escape pressed while this layer is the topmost one. */\n onEscapeKeyDown?: DismissHandler<KeyboardEvent>;\n /** Pointer pressed outside the layer (and its branches / child layers). */\n onPointerDownOutside?: DismissHandler<PointerEvent>;\n /** Focus moved outside the layer (and its branches / child layers). */\n onFocusOutside?: DismissHandler<FocusEvent>;\n /** Either of the two above (called after the specific handler). */\n onInteractOutside?: DismissHandler<PointerEvent | FocusEvent>;\n /** The layer should close (no handler cancelled the interaction). */\n onDismiss?: () => void;\n /**\n * Make everything below this layer inert to the pointer (modal):\n * `body` gets `pointer-events: none`, this layer and the layers above it\n * get `pointer-events: auto`. Layers below are not dismissed by pointer.\n * @default false\n */\n disableOutsidePointerEvents?: boolean;\n /**\n * Elements treated as part of the layer (e.g. the trigger), so\n * interacting with them is not \"outside\".\n */\n branches?: () => Array<Element | null | undefined>;\n /**\n * Return `true` to ignore an interaction entirely (neither inside nor\n * outside), e.g. clicks in a toast viewport.\n */\n excludeFromOutside?: (target: Node) => boolean;\n /**\n * Explicit parent layer. Interactions inside a child layer are \"inside\" for\n * all of its ancestors. When omitted, the parent is the closest layer whose\n * element contains this one, else the layer directly below in the stack of\n * the same document (layers opened while another is open are treated as its\n * children, which makes portalled nested menus / popovers work). Pass `null`\n * to make the layer a root.\n */\n parent?: DismissableLayer | Element | null;\n}\n\nexport interface DismissableLayer {\n /** The layer element. */\n readonly element: Element;\n /** Removes the layer from the stack and restores pointer-events. */\n destroy(): void;\n /** Merges new options (handlers, branches, disableOutsidePointerEvents...). */\n update(options: Partial<DismissableLayerOptions>): void;\n}\n\n/** Debug view of a stacked layer. */\nexport interface LayerInfo {\n element: Element;\n disableOutsidePointerEvents: boolean;\n parent: Element | null;\n}\n\ninterface Layer {\n handle: DismissableLayer;\n element: Element;\n /** Owner document at creation (whose listeners handle this layer). */\n doc: Document;\n options: DismissableLayerOptions;\n /** Pointer handling starts on the next tick (ignore the opening click). */\n pointerReady: boolean;\n readyTimer: ReturnType<typeof setTimeout> | undefined;\n /** Inline `pointer-events` before we touched it. */\n originalPointerEvents: string | null;\n /** Implicit parent resolved at creation time (stack order / DOM). */\n implicitParent: Layer | null;\n}\n\ninterface DocumentState {\n refs: number;\n cleanup: () => void;\n bodyPointerEvents: string | null;\n}\n\n/**\n * Shared by every module copy: one stack (so \"topmost\" / modal / parent\n * resolution sees every layer) and one set of listeners per document (so a\n * single Escape never dismisses one layer per copy).\n */\nconst { layers, documents } = sharedState(\"dismissable-layer.v1\", () => ({\n /** Bottom -> top, all documents. */\n layers: [] as Layer[],\n documents: new WeakMap<Document, DocumentState>(),\n}));\n\n/** The layers of `doc`, bottom -> top. Interactions never cross documents. */\nfunction layersOf(doc: Document): Layer[] {\n return layers.filter((layer) => layer.doc === doc);\n}\n\nfunction findLayer(target: DismissableLayer | Element | null | undefined) {\n if (!target) return null;\n return (\n layers.find((layer) => layer.handle === target) ??\n layers.find((layer) => layer.element === target) ??\n null\n );\n}\n\nfunction parentOf(layer: Layer): Layer | null {\n const { parent } = layer.options;\n if (parent === null) return null;\n if (parent !== undefined) {\n if (typeof parent === \"object\" && \"destroy\" in parent) {\n return findLayer(parent);\n }\n // an element: the layer that is (or contains) it\n return (\n findLayer(parent) ??\n [...layers]\n .reverse()\n .find((l) => l !== layer && contains(l.element, parent)) ??\n null\n );\n }\n return layers.includes(layer.implicitParent as Layer)\n ? layer.implicitParent\n : null;\n}\n\nfunction isAncestor(ancestor: Layer, layer: Layer): boolean {\n const seen = new Set<Layer>();\n for (let p = parentOf(layer); p && !seen.has(p); p = parentOf(p)) {\n if (p === ancestor) return true;\n seen.add(p);\n }\n return false;\n}\n\n/** Whether `target` is inside `layer`, its branches or any descendant layer. */\nfunction isInside(layer: Layer, target: Node): boolean {\n if (contains(layer.element, target)) return true;\n const branches = layer.options.branches?.() ?? [];\n if (branches.some((branch) => branch && contains(branch, target))) {\n return true;\n }\n return layers.some(\n (other) =>\n other !== layer &&\n isAncestor(layer, other) &&\n (contains(other.element, target) ||\n (other.options.branches?.() ?? []).some(\n (branch) => branch && contains(branch, target),\n )),\n );\n}\n\n/** Index (in `stack`) of the topmost modal layer, `-1` when none. */\nfunction highestModalIndex(stack: Layer[]): number {\n for (let i = stack.length - 1; i >= 0; i--) {\n if (stack[i].options.disableOutsidePointerEvents) return i;\n }\n return -1;\n}\n\n/** A modal layer only blocks the layers below it in its own document. */\nfunction isPointerEventsEnabled(layer: Layer): boolean {\n const stack = layersOf(layer.doc);\n return stack.indexOf(layer) >= highestModalIndex(stack);\n}\n\nfunction setInlinePointerEvents(el: Element, value: string | null) {\n const style = (el as HTMLElement).style;\n if (!style) return;\n if (value === null || value === \"\") style.removeProperty(\"pointer-events\");\n else style.pointerEvents = value;\n}\n\n/** Re-applies `doc`'s body / layer `pointer-events` after a stack change. */\nfunction syncPointerEvents(doc: Document) {\n const stack = layersOf(doc);\n const modalIndex = highestModalIndex(stack);\n const state = documents.get(doc);\n const body = doc.body;\n if (state && body) {\n if (modalIndex !== -1 && state.bodyPointerEvents === null) {\n state.bodyPointerEvents = body.style.pointerEvents ?? \"\";\n body.style.pointerEvents = \"none\";\n } else if (modalIndex === -1 && state.bodyPointerEvents !== null) {\n setInlinePointerEvents(body, state.bodyPointerEvents);\n state.bodyPointerEvents = null;\n }\n }\n stack.forEach((layer, index) => {\n const enable = modalIndex !== -1 && index >= modalIndex;\n setInlinePointerEvents(\n layer.element,\n enable ? \"auto\" : layer.originalPointerEvents,\n );\n });\n}\n\n/** Calls the handlers; `true` when nothing cancelled the dismissal. */\nfunction runHandlers<E extends Event>(\n event: E,\n handlers: Array<DismissHandler<E> | undefined>,\n): boolean {\n const wasPrevented = event.defaultPrevented;\n let cancelled = false;\n // `focusin` (and synthetic events) are not cancelable: `preventDefault()`\n // would be a no-op and could not keep the layer open. Record the call\n // instead, so the documented contract holds for every event type.\n let preventedUncancelable = false;\n const restore = !event.cancelable;\n if (restore) {\n const native = event.preventDefault;\n Object.defineProperty(event, \"preventDefault\", {\n configurable: true,\n value() {\n preventedUncancelable = true;\n native.call(event);\n },\n });\n }\n try {\n for (const handler of handlers) {\n if (handler?.(event) === false) cancelled = true;\n }\n } finally {\n if (restore) delete (event as { preventDefault?: unknown }).preventDefault;\n }\n if (preventedUncancelable) cancelled = true;\n return !cancelled && (wasPrevented || !event.defaultPrevented);\n}\n\nfunction dismissOutside<E extends PointerEvent | FocusEvent>(\n event: E,\n kind: \"pointer\" | \"focus\",\n doc: Document,\n) {\n const target = getEventTarget(event);\n // Not `instanceof Object`: nodes of an iframe come from another realm.\n if (!target || typeof target !== \"object\" || !(\"nodeType\" in target)) {\n return;\n }\n const node = target as Node;\n // Topmost first: snapshot, handlers may destroy layers.\n const candidates = layersOf(doc)\n .reverse()\n .filter((layer) => {\n if (\n kind === \"pointer\" &&\n (!layer.pointerReady || !isPointerEventsEnabled(layer))\n )\n return false;\n if (layer.options.excludeFromOutside?.(node)) return false;\n return !isInside(layer, node);\n });\n for (const layer of candidates) {\n if (!layers.includes(layer)) continue;\n const { options } = layer;\n const specific =\n kind === \"pointer\"\n ? (options.onPointerDownOutside as DismissHandler<E> | undefined)\n : (options.onFocusOutside as DismissHandler<E> | undefined);\n const ok = runHandlers<E>(event, [\n specific,\n options.onInteractOutside as DismissHandler<E> | undefined,\n ]);\n if (ok) options.onDismiss?.();\n }\n}\n\nfunction attachDocument(doc: Document) {\n const existing = documents.get(doc);\n if (existing) {\n existing.refs += 1;\n return;\n }\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key !== \"Escape\") return;\n // A control inside the layer consumes this Escape itself (e.g. a closed\n // combobox clearing its text): the layer stays open.\n const target = getEventTarget(event) as Element | null;\n if (target?.closest?.(`[${ESCAPE_CONSUMER_ATTRIBUTE}]`)) return;\n const stack = layersOf(doc);\n const top = stack[stack.length - 1];\n if (!top) return;\n const ok = runHandlers(event, [top.options.onEscapeKeyDown]);\n if (ok && top.options.onDismiss) {\n // e.g. keep the browser from leaving fullscreen\n event.preventDefault();\n top.options.onDismiss();\n }\n };\n\n let pendingClick: (() => void) | null = null;\n const onPointerDown = (event: PointerEvent) => {\n if (pendingClick) {\n doc.removeEventListener(\"click\", pendingClick);\n pendingClick = null;\n }\n if (event.pointerType === \"touch\") {\n // Touch: wait for the click so scrolling gestures do not dismiss.\n pendingClick = () => {\n pendingClick = null;\n dismissOutside(event, \"pointer\", doc);\n };\n doc.addEventListener(\"click\", pendingClick, { once: true });\n return;\n }\n dismissOutside(event, \"pointer\", doc);\n };\n\n const onFocusIn = (event: FocusEvent) => dismissOutside(event, \"focus\", doc);\n\n doc.addEventListener(\"keydown\", onKeyDown, true);\n doc.addEventListener(\"pointerdown\", onPointerDown, true);\n doc.addEventListener(\"focusin\", onFocusIn, true);\n\n documents.set(doc, {\n refs: 1,\n bodyPointerEvents: null,\n cleanup() {\n doc.removeEventListener(\"keydown\", onKeyDown, true);\n doc.removeEventListener(\"pointerdown\", onPointerDown, true);\n doc.removeEventListener(\"focusin\", onFocusIn, true);\n if (pendingClick) doc.removeEventListener(\"click\", pendingClick);\n },\n });\n}\n\nfunction detachDocument(doc: Document) {\n const state = documents.get(doc);\n if (!state) return;\n state.refs -= 1;\n if (state.refs > 0) return;\n state.cleanup();\n if (state.bodyPointerEvents !== null && doc.body) {\n setInlinePointerEvents(doc.body, state.bodyPointerEvents);\n }\n documents.delete(doc);\n}\n\n/**\n * Registers `element` as a dismissable layer (popover, menu, dialog...).\n *\n * - Escape: only the topmost layer of the document is notified.\n * - Pointer down / focus outside: a layer is notified when the interaction\n * is outside itself, its `branches` and its descendant layers, so clicking\n * in a (portalled) submenu never dismisses its parent menu.\n * - Layers only react to interactions in their own document (iframes, other\n * windows); a modal layer only blocks the layers of its own document.\n * - Pointer handling starts on the next tick so the click that opened the\n * layer does not immediately dismiss it. Touch pointers are handled on the\n * following `click` (so scroll gestures do not dismiss).\n * - Handlers get the original event; `preventDefault()` (or returning\n * `false`) cancels the dismissal.\n *\n * @example\n * const layer = createDismissableLayer(menu, {\n * branches: () => [trigger],\n * onDismiss: () => close(),\n * });\n * // later\n * layer.destroy();\n */\nexport function createDismissableLayer(\n element: Element,\n options: DismissableLayerOptions = {},\n): DismissableLayer {\n const doc = getOwnerDocument(element);\n const sameDocument = layersOf(doc);\n const implicitParent =\n [...sameDocument].reverse().find((l) => contains(l.element, element)) ??\n sameDocument[sameDocument.length - 1] ??\n null;\n\n let destroyed = false;\n const handle: DismissableLayer = {\n element,\n destroy() {\n if (destroyed) return;\n destroyed = true;\n clearTimeout(layer.readyTimer);\n const index = layers.indexOf(layer);\n if (index !== -1) layers.splice(index, 1);\n setInlinePointerEvents(element, layer.originalPointerEvents);\n syncPointerEvents(doc);\n detachDocument(doc);\n },\n update(next) {\n if (destroyed) return;\n layer.options = { ...layer.options, ...next };\n syncPointerEvents(doc);\n },\n };\n\n const layer: Layer = {\n handle,\n element,\n doc,\n options: { ...options },\n pointerReady: false,\n readyTimer: undefined,\n originalPointerEvents:\n (element as HTMLElement).style?.getPropertyValue(\"pointer-events\") ||\n null,\n implicitParent,\n };\n\n layers.push(layer);\n attachDocument(doc);\n syncPointerEvents(doc);\n const win = doc.defaultView;\n layer.readyTimer = (win?.setTimeout.bind(win) ?? setTimeout)(() => {\n layer.pointerReady = true;\n }, 0) as ReturnType<typeof setTimeout>;\n\n return handle;\n}\n\n/** Current layer stack, bottom -> top (for tests / debugging). */\nexport function getLayerStack(): LayerInfo[] {\n return layers.map((layer) => ({\n element: layer.element,\n disableOutsidePointerEvents: !!layer.options.disableOutsidePointerEvents,\n parent: parentOf(layer)?.element ?? null,\n }));\n}\n","import { canUseDOM } from \"./dom\";\nimport { sharedState } from \"./internal/shared-state\";\n\n/** CSS variable (on `<html>`) holding the compensated scrollbar width. */\nexport const SCROLLBAR_GAP_VAR = \"--minerva-scrollbar-gap\";\n\ninterface LockState {\n count: number;\n restore: () => void;\n}\n\n/** Per target element (hence per document); shared by every module copy. */\nconst locks = sharedState(\n \"scroll-lock.v1\",\n () => new WeakMap<HTMLElement, LockState>(),\n);\n\n/**\n * Width of the scrollbar that hiding overflow on `target` would remove:\n * `innerWidth - documentElement.clientWidth` for the body, else\n * `offsetWidth - clientWidth`.\n */\nexport function getScrollbarGap(target: HTMLElement): number {\n const doc = target.ownerDocument;\n const win = doc.defaultView;\n const gap =\n target === doc.body || target === doc.documentElement\n ? (win?.innerWidth ?? 0) - doc.documentElement.clientWidth\n : target.offsetWidth - target.clientWidth;\n return Math.max(0, gap || 0);\n}\n\nfunction applyLock(target: HTMLElement): () => void {\n const doc = target.ownerDocument;\n const html = doc.documentElement;\n const isPage = target === doc.body;\n const gap = getScrollbarGap(target);\n\n const saved = {\n overflow: target.style.overflow,\n paddingRight: target.style.paddingRight,\n htmlOverflow: html.style.overflow,\n gapVar: html.style.getPropertyValue(SCROLLBAR_GAP_VAR),\n };\n\n if (gap > 0) {\n const computed = doc.defaultView?.getComputedStyle(target).paddingRight;\n const current = Number.parseFloat(computed ?? \"\") || 0;\n target.style.paddingRight = `${current + gap}px`;\n }\n target.style.overflow = \"hidden\";\n if (isPage) {\n // iOS Safari only stops page scrolling when <html> is locked too.\n html.style.overflow = \"hidden\";\n html.style.setProperty(SCROLLBAR_GAP_VAR, `${gap}px`);\n }\n\n return () => {\n target.style.overflow = saved.overflow;\n target.style.paddingRight = saved.paddingRight;\n if (isPage) {\n html.style.overflow = saved.htmlOverflow;\n if (saved.gapVar) html.style.setProperty(SCROLLBAR_GAP_VAR, saved.gapVar);\n else html.style.removeProperty(SCROLLBAR_GAP_VAR);\n }\n };\n}\n\n/**\n * Prevents `target` (the page by default) from scrolling, compensating the\n * scrollbar width with `padding-right` so the layout does not shift, and\n * exposing it as `--minerva-scrollbar-gap` on `<html>` (for fixed elements).\n *\n * Nested-safe: locks are reference counted per target and the original\n * inline styles are restored when the last lock is released.\n *\n * @returns an idempotent unlock function (a no-op outside the browser).\n */\nexport function lockScroll(target?: HTMLElement): () => void {\n if (!canUseDOM()) return () => {};\n const el = target ?? document.body;\n let state = locks.get(el);\n if (state) {\n state.count += 1;\n } else {\n state = { count: 1, restore: applyLock(el) };\n locks.set(el, state);\n }\n\n let released = false;\n return () => {\n if (released) return;\n released = true;\n const current = locks.get(el);\n if (!current) return;\n current.count -= 1;\n if (current.count === 0) {\n locks.delete(el);\n current.restore();\n }\n };\n}\n\n/** Whether `target` (the body by default) is currently scroll-locked. */\nexport function isScrollLocked(target?: HTMLElement): boolean {\n if (!canUseDOM()) return false;\n return locks.has(target ?? document.body);\n}\n","import { canUseDOM } from \"./dom\";\nimport { sharedState } from \"./internal/shared-state\";\n\nexport interface HideOthersOptions {\n /** Only elements inside `root` are hidden. @default document.body */\n root?: Element;\n /**\n * `\"aria-hidden\"` hides from assistive tech only; `\"inert\"` also blocks\n * focus and pointer interaction. @default \"aria-hidden\"\n */\n attribute?: \"aria-hidden\" | \"inert\";\n}\n\n/** Elements matching this selector are never hidden. */\nexport const KEEP_VISIBLE_SELECTOR = \"[aria-live], [data-minerva-keep-visible]\";\n\nconst IGNORED_TAGS = new Set([\"SCRIPT\", \"STYLE\", \"TEMPLATE\", \"LINK\", \"META\"]);\n\n/**\n * Shared by every module copy, so overlapping calls from different copies\n * still count each other (and never take a pre-existing attribute for ours).\n */\nconst { counters, preexisting } = sharedState(\"hide-others.v1\", () => ({\n /** attribute -> element -> number of active hideOthers() calls hiding it */\n counters: {\n \"aria-hidden\": new WeakMap(),\n inert: new WeakMap(),\n } as Record<string, WeakMap<Element, number>>,\n /** attribute -> elements that already had the attribute before us */\n preexisting: {\n \"aria-hidden\": new WeakSet(),\n inert: new WeakSet(),\n } as Record<string, WeakSet<Element>>,\n}));\n\nfunction hasAttribute(el: Element, attribute: string): boolean {\n if (attribute === \"aria-hidden\") {\n const value = el.getAttribute(\"aria-hidden\");\n return value !== null && value !== \"false\";\n }\n return el.hasAttribute(attribute);\n}\n\nfunction hide(el: Element, attribute: string) {\n const count = counters[attribute].get(el) ?? 0;\n if (count === 0) {\n if (hasAttribute(el, attribute)) {\n preexisting[attribute].add(el);\n } else {\n preexisting[attribute].delete(el);\n el.setAttribute(attribute, attribute === \"inert\" ? \"\" : \"true\");\n }\n }\n counters[attribute].set(el, count + 1);\n}\n\nfunction unhide(el: Element, attribute: string) {\n const count = counters[attribute].get(el) ?? 0;\n if (count <= 0) return;\n if (count === 1) {\n counters[attribute].delete(el);\n if (!preexisting[attribute].has(el)) el.removeAttribute(attribute);\n preexisting[attribute].delete(el);\n } else {\n counters[attribute].set(el, count - 1);\n }\n}\n\n/**\n * Hides everything in `root` except `targets` (and their ancestors), for\n * modal dialogs: every sibling along the path from `root` to each target is\n * marked `aria-hidden=\"true\"` (or `inert`). Live regions (`[aria-live]`) and\n * `[data-minerva-keep-visible]` elements are left alone.\n *\n * Nested-safe: overlapping calls are reference counted per element, and an\n * attribute that existed before the first call is preserved on undo.\n *\n * @returns an idempotent undo function.\n */\nexport function hideOthers(\n targets: Element | Element[],\n options: HideOthersOptions = {},\n): () => void {\n if (!canUseDOM()) return () => {};\n const { root = document.body, attribute = \"aria-hidden\" } = options;\n const list = (Array.isArray(targets) ? targets : [targets]).filter(\n (target) => target && root.contains(target) && target !== root,\n );\n if (list.length === 0) return () => {};\n\n const targetSet = new Set<Element>(list);\n const keep = new Set<Element>();\n for (const target of list) {\n for (let el: Element | null = target; el && el !== root;) {\n keep.add(el);\n el = el.parentElement;\n }\n }\n\n const hidden: Element[] = [];\n const walk = (parent: Element) => {\n for (const child of Array.from(parent.children)) {\n if (keep.has(child)) {\n if (!targetSet.has(child)) walk(child);\n continue;\n }\n if (IGNORED_TAGS.has(child.tagName)) continue;\n if (child.matches(KEEP_VISIBLE_SELECTOR)) continue;\n hide(child, attribute);\n hidden.push(child);\n }\n };\n walk(root);\n\n let undone = false;\n return () => {\n if (undone) return;\n undone = true;\n for (const el of hidden) unhide(el, attribute);\n };\n}\n","import {\n createTypeahead,\n getNextIndex,\n type Direction,\n type Orientation,\n type TypeaheadOptions,\n} from \"@minerva/core\";\nimport { contains, focusElement, getEventTarget } from \"./dom\";\n\nexport interface RovingFocusOptions {\n /** Selector for items inside the container. @default \"[data-minerva-item]\" */\n itemSelector?: string;\n /** Custom item getter (takes precedence over `itemSelector`). */\n getItems?: () => HTMLElement[];\n /** @default \"vertical\" */\n orientation?: Orientation;\n /** @default \"ltr\" */\n dir?: Direction;\n /** @default true */\n loop?: boolean;\n /** Enable typeahead (`true` or typeahead options). @default false */\n typeahead?: boolean | TypeaheadOptions;\n /** Item text for typeahead. @default `data-text-value` or textContent */\n getItemText?: (item: HTMLElement) => string;\n /**\n * Disabled items are skipped by keyboard navigation.\n * @default `disabled`, `aria-disabled=\"true\"` or `data-disabled`\n */\n isItemDisabled?: (item: HTMLElement) => boolean;\n /** Called when the active item changes. */\n onActiveChange?: (item: HTMLElement, index: number) => void;\n /** Move DOM focus to the newly active item. @default true */\n focusOnMove?: boolean;\n /** Enables PageUp / PageDown with this step. */\n pageSize?: number;\n}\n\nexport interface RovingFocus {\n /** Makes an item (element or index) the active one (tabindex 0). */\n setActive(item: HTMLElement | number, options?: { focus?: boolean }): void;\n /** The active item (`tabindex=\"0\"`), if any. */\n getActive(): HTMLElement | null;\n /** Re-applies tabindex after items were added / removed. */\n refresh(): void;\n /** Removes the listeners (tabindex attributes are left as they are). */\n destroy(): void;\n}\n\nconst defaultIsDisabled = (item: HTMLElement) =>\n item.hasAttribute(\"disabled\") ||\n item.getAttribute(\"aria-disabled\") === \"true\" ||\n item.hasAttribute(\"data-disabled\");\n\nconst defaultGetText = (item: HTMLElement) =>\n item.dataset.textValue ?? item.textContent ?? \"\";\n\n/**\n * Roving tabindex controller: exactly one item has `tabindex=\"0\"`, the\n * others `-1`; arrow keys / Home / End (and optional typeahead) move the\n * active item. Clicking / focusing an item makes it active.\n */\nexport function createRovingFocus(\n container: HTMLElement,\n options: RovingFocusOptions = {},\n): RovingFocus {\n const {\n itemSelector = \"[data-minerva-item]\",\n orientation = \"vertical\",\n dir = \"ltr\",\n loop = true,\n getItemText = defaultGetText,\n isItemDisabled = defaultIsDisabled,\n onActiveChange,\n focusOnMove = true,\n pageSize,\n } = options;\n const typeahead = options.typeahead\n ? createTypeahead(options.typeahead === true ? {} : options.typeahead)\n : null;\n\n const getItems = (): HTMLElement[] =>\n options.getItems\n ? options.getItems()\n : Array.from(container.querySelectorAll<HTMLElement>(itemSelector));\n\n let active: HTMLElement | null = null;\n\n const sync = (items = getItems()) => {\n if (!active || !items.includes(active)) {\n active =\n items.find((item) => item.getAttribute(\"tabindex\") === \"0\") ??\n items.find((item) => !isItemDisabled(item)) ??\n null;\n }\n for (const item of items) {\n item.setAttribute(\"tabindex\", item === active ? \"0\" : \"-1\");\n }\n };\n\n const activate = (\n item: HTMLElement,\n items: HTMLElement[],\n focus: boolean,\n ) => {\n const changed = item !== active;\n active = item;\n sync(items);\n if (focus) focusElement(item);\n if (changed) onActiveChange?.(item, items.indexOf(item));\n };\n\n const itemFromEvent = (event: Event, items: HTMLElement[]) => {\n const target = getEventTarget(event);\n if (!(target instanceof Node)) return null;\n return items.find((item) => contains(item, target)) ?? null;\n };\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.defaultPrevented) return;\n const items = getItems();\n if (items.length === 0) return;\n const current = itemFromEvent(event, items) ?? active;\n const currentIndex = current ? items.indexOf(current) : -1;\n const isDisabled = (i: number) => isItemDisabled(items[i]);\n\n if (!event.altKey && !event.ctrlKey && !event.metaKey) {\n const next = getNextIndex({\n currentIndex,\n count: items.length,\n key: event.key,\n orientation,\n dir,\n loop,\n isDisabled,\n pageSize,\n });\n if (next !== null) {\n event.preventDefault();\n typeahead?.reset();\n activate(items[next], items, focusOnMove);\n return;\n }\n if (typeahead) {\n const index = typeahead.search(\n event.key,\n items.map((item) => ({\n text: getItemText(item),\n disabled: isItemDisabled(item),\n })),\n currentIndex,\n );\n if (index !== -1) {\n event.preventDefault();\n activate(items[index], items, focusOnMove);\n }\n }\n }\n };\n\n const onFocusIn = (event: FocusEvent) => {\n const items = getItems();\n const item = itemFromEvent(event, items);\n if (item && item !== active) activate(item, items, false);\n };\n\n container.addEventListener(\"keydown\", onKeyDown);\n container.addEventListener(\"focusin\", onFocusIn);\n sync();\n\n return {\n setActive(item, opts = {}) {\n const items = getItems();\n const el = typeof item === \"number\" ? items[item] : item;\n if (!el || !items.includes(el)) return;\n activate(el, items, opts.focus ?? focusOnMove);\n },\n getActive() {\n return active;\n },\n refresh() {\n sync();\n },\n destroy() {\n container.removeEventListener(\"keydown\", onKeyDown);\n container.removeEventListener(\"focusin\", onFocusIn);\n typeahead?.reset();\n },\n };\n}\n","// Vertical arrow navigation in a wrapping row of items (no fixed columns):\n// the item of the nearest row above / below whose center is the closest\n// horizontally, from the rendered geometry.\n\n/**\n * The element of `elements` in the nearest row above (`direction` -1) or\n * below (1) `from`, closest to its horizontal center; null when there is\n * none (or nothing is laid out, e.g. in jsdom).\n */\nexport function nearestInRow<T extends Element>(\n elements: readonly T[],\n from: Element,\n direction: 1 | -1,\n): T | null {\n const origin = from.getBoundingClientRect();\n const centerX = origin.left + origin.width / 2;\n let best: T | null = null;\n let bestRow = Infinity;\n let bestDx = Infinity;\n for (const element of elements) {\n if (element === from) continue;\n const rect = element.getBoundingClientRect();\n if (!rect.width && !rect.height) continue;\n const dy = (rect.top - origin.top) * direction;\n if (dy < Math.max(1, origin.height / 2)) continue;\n const dx = Math.abs(rect.left + rect.width / 2 - centerX);\n // a nearer row wins; within the same row (1px tolerance), the closest\n if (dy < bestRow - 1 || (Math.abs(dy - bestRow) <= 1 && dx < bestDx)) {\n best = element;\n bestRow = Math.min(bestRow, dy);\n bestDx = dx;\n }\n }\n return best;\n}\n","// Reading direction (LTR / RTL) of an element, for keyboard handlers whose\n// arrow keys follow the visual order. Nothing runs at import time.\n\n/** Reading direction of a piece of UI. */\nexport type ReadingDirection = \"ltr\" | \"rtl\";\n\n/**\n * Parent in the composed (flat) tree: the slot of slotted content, the\n * parent element, or the host of a shadow root.\n */\nfunction composedParent(node: Element): Element | null {\n if (node.assignedSlot) return node.assignedSlot;\n if (node.parentElement) return node.parentElement;\n const root = node.parentNode;\n return root && root.nodeType === 11 && \"host\" in root\n ? (root as ShadowRoot).host\n : null;\n}\n\n/**\n * Resolves the reading direction that applies to `element`: the nearest\n * ancestor (or self) with `dir=\"ltr\"` / `dir=\"rtl\"` wins, walking up through\n * slots and shadow hosts; `dir=\"auto\"` and invalid values are skipped. Then\n * the computed CSS `direction`, then `\"ltr\"`.\n *\n * Call it lazily (in event handlers / effects), never at import time.\n */\nexport function getDirection(\n element: Element | null | undefined,\n): ReadingDirection {\n for (let node = element ?? null; node; node = composedParent(node)) {\n const dir = node.getAttribute(\"dir\")?.toLowerCase();\n if (dir === \"rtl\" || dir === \"ltr\") return dir;\n }\n if (element) {\n const view = element.ownerDocument?.defaultView;\n const computed = view?.getComputedStyle?.(element).direction;\n if (computed === \"rtl\") return \"rtl\";\n }\n return \"ltr\";\n}\n\n/**\n * `explicit` when given, otherwise the direction inherited by `element`\n * (see {@link getDirection}).\n */\nexport function resolveDirection(\n explicit: ReadingDirection | undefined,\n element: Element | null | undefined,\n): ReadingDirection {\n return explicit ?? getDirection(element);\n}\n\n/**\n * Maps a physical arrow key to its logical meaning for `element`: in RTL,\n * ArrowLeft and ArrowRight are swapped (ArrowLeft = \"next\"), so handlers can\n * be written once for LTR. Other keys are returned as is.\n */\nexport function logicalArrowKey(\n key: string,\n element: Element | null | undefined,\n explicit?: ReadingDirection,\n): string {\n if (key !== \"ArrowLeft\" && key !== \"ArrowRight\") return key;\n if (resolveDirection(explicit, element) !== \"rtl\") return key;\n return key === \"ArrowLeft\" ? \"ArrowRight\" : \"ArrowLeft\";\n}\n","// Brings an item of a horizontally scrolling row into view by scrolling the\n// row only (never the page, unlike element.scrollIntoView).\nimport { getDirection } from \"./direction\";\n\n/**\n * Scrolls `scroller` horizontally so that `element` (one of its\n * descendants) is centered, clamped to the scrollable range (`0..max`, or\n * `-max..0` in RTL). Does nothing when the row does not overflow (or nothing\n * is laid out, e.g. in jsdom).\n */\nexport function centerInScroller(scroller: Element, element: Element): void {\n const max = scroller.scrollWidth - scroller.clientWidth;\n if (max <= 0) return;\n const view = scroller.getBoundingClientRect();\n const item = element.getBoundingClientRect();\n const delta = item.left + item.width / 2 - (view.left + view.width / 2);\n const next = scroller.scrollLeft + delta;\n const rtl = getDirection(scroller) === \"rtl\";\n const [min, upper] = rtl ? [-max, 0] : [0, max];\n const clamped = Math.round(Math.min(upper, Math.max(min, next)));\n if (clamped !== scroller.scrollLeft) scroller.scrollLeft = clamped;\n}\n","import { canUseDOM } from \"./dom\";\n\n/**\n * Resolves where portalled content goes: the explicit container when given,\n * else `document.body` (`null` on the server).\n */\nexport function getPortalContainer(explicit?: Element | null): Element | null {\n if (explicit) return explicit;\n return canUseDOM() ? document.body : null;\n}\n\nexport interface PortalHostOptions {\n /** `id` of the host element. */\n id?: string;\n /** Extra attributes (e.g. `class`, `data-theme`, `dir`). */\n attributes?: Record<string, string>;\n /** Where the host is appended. @default document.body */\n parent?: Element | null;\n /** Tag name of the host. @default \"div\" */\n tagName?: string;\n}\n\n/** Attribute set on every host created by `createPortalHost`. */\nexport const PORTAL_HOST_ATTRIBUTE = \"data-minerva-portal\";\n\n/**\n * Creates and appends a dedicated portal host element, e.g. a theme-scoped\n * container carrying `data-theme` so portalled overlays inherit the theme\n * variables. Remove it with `host.remove()`.\n */\nexport function createPortalHost(options: PortalHostOptions = {}): HTMLElement {\n const parent = getPortalContainer(options.parent);\n if (!parent) {\n throw new Error(\"createPortalHost() requires a DOM environment\");\n }\n const host = parent.ownerDocument.createElement(options.tagName ?? \"div\");\n host.setAttribute(PORTAL_HOST_ATTRIBUTE, \"\");\n if (options.id) host.id = options.id;\n for (const [name, value] of Object.entries(options.attributes ?? {})) {\n host.setAttribute(name, value);\n }\n parent.appendChild(host);\n return host;\n}\n","import {\n arrow as arrowMiddleware,\n autoUpdate,\n computePosition,\n flip as flipMiddleware,\n limitShift,\n offset as offsetMiddleware,\n shift as shiftMiddleware,\n size as sizeMiddleware,\n type AutoUpdateOptions,\n type ElementRects,\n type Middleware,\n type MiddlewareData,\n type Placement,\n type Strategy,\n type VirtualElement,\n} from \"@floating-ui/dom\";\n\nexport type { Placement, VirtualElement, Strategy, MiddlewareData };\n\n/** Side of the anchor the floating element sits on. */\nexport type Side = \"top\" | \"right\" | \"bottom\" | \"left\";\n/** Alignment along the anchor. */\nexport type Align = \"start\" | \"center\" | \"end\";\n/** An element or a virtual element (e.g. the cursor position). */\nexport type AnchorElement = Element | VirtualElement;\n\n/** Minimum distance kept between a floating element and the viewport edge. */\nexport const VIEWPORT_PADDING = 8;\n/** Padding between the arrow and the floating element's corners. */\nexport const ARROW_PADDING = 6;\n\nexport interface AnchoredPositionOptions {\n /** Preferred placement; may flip when it overflows. @default \"bottom\" */\n placement?: Placement;\n /**\n * Gap from the anchor (main axis) and skid along it (cross axis), in px.\n * @default { mainAxis: 8, crossAxis: 0 }\n */\n offset?: { mainAxis?: number; crossAxis?: number };\n /** Flip to the opposite side when there is not enough room. @default true */\n flip?: boolean;\n /** Shift along the anchor to stay inside the viewport. @default true */\n shift?: boolean;\n /**\n * Size the floating element after the anchor: `\"min\"` makes it at least\n * as wide as the anchor, `\"exact\"` exactly as wide. Also caps `maxWidth`\n * to the available width. @default false\n */\n matchAnchorWidth?: false | \"min\" | \"exact\";\n /**\n * Cap the floating element's height (`maxHeight`) to the space available.\n * Also caps `maxWidth` to the available width. @default false\n */\n fitViewportHeight?: boolean;\n /** Arrow element, centered on the anchor. */\n arrowElement?: HTMLElement | null;\n /**\n * Minimum distance kept between the floating element and the viewport\n * edges (collision padding) used by flip, shift and size, in px.\n * @default VIEWPORT_PADDING (8)\n */\n padding?: number;\n /** Options for `autoUpdate` (used by `autoPosition` only). */\n autoUpdate?: AutoUpdateOptions;\n}\n\nexport interface AnchoredPositionResult {\n /** Left (px, viewport coordinates since the strategy is `fixed`). */\n x: number;\n /** Top (px). */\n y: number;\n /** Final placement, after flipping. */\n placement: Placement;\n strategy: Strategy;\n middlewareData: MiddlewareData;\n /** Arrow offsets (left for top/bottom placements, top for left/right). */\n arrow: { x?: number; y?: number };\n /** Space available for the floating element (from the size middleware). */\n availableWidth?: number;\n availableHeight?: number;\n /** Measured anchor / floating rectangles. */\n rects?: ElementRects;\n}\n\ninterface SizeData {\n availableWidth: number;\n availableHeight: number;\n}\n\nfunction buildMiddleware(\n options: AnchoredPositionOptions,\n sizeData: Partial<SizeData>,\n): Middleware[] {\n const {\n offset,\n flip = true,\n shift = true,\n matchAnchorWidth = false,\n fitViewportHeight = false,\n arrowElement,\n padding = VIEWPORT_PADDING,\n } = options;\n const mainAxis = offset?.mainAxis ?? 8;\n const crossAxis = offset?.crossAxis ?? 0;\n\n const middleware: Middleware[] = [offsetMiddleware({ mainAxis, crossAxis })];\n if (flip) {\n // \"alignment\": flip start <-> end before shifting, keep the side otherwise\n middleware.push(flipMiddleware({ padding, crossAxis: \"alignment\" }));\n }\n if (shift) {\n middleware.push(shiftMiddleware({ padding, limiter: limitShift() }));\n }\n const sizing = !!matchAnchorWidth || fitViewportHeight;\n middleware.push(\n sizeMiddleware({\n padding,\n apply({ rects, availableHeight, availableWidth, elements }) {\n sizeData.availableWidth = availableWidth;\n sizeData.availableHeight = availableHeight;\n if (!sizing) return;\n const style = elements.floating.style;\n if (matchAnchorWidth === \"exact\") {\n style.width = `${rects.reference.width}px`;\n } else if (matchAnchorWidth === \"min\") {\n style.minWidth = `${rects.reference.width}px`;\n }\n style.maxWidth = `${Math.max(0, availableWidth)}px`;\n if (fitViewportHeight) {\n style.maxHeight = `${Math.max(0, availableHeight)}px`;\n }\n },\n }),\n );\n if (arrowElement) {\n middleware.push(\n arrowMiddleware({ element: arrowElement, padding: ARROW_PADDING }),\n );\n }\n middleware.push({\n name: \"minervaRects\",\n fn: ({ rects }) => ({ data: { ...rects } }),\n });\n return middleware;\n}\n\n/**\n * Computes the position of `floating` anchored to `reference` (one shot).\n *\n * Same behaviour as the React library's `useAnchoredPosition`: `fixed` strategy,\n * offset (default 8px), flip (padding 8, cross-axis `\"alignment\"`), shift\n * (padding 8 + `limitShift`), optional size constraints and arrow\n * (padding 6). Position with `left` / `top` (see `applyPosition`), never a\n * transform, so CSS animations can use `transform` freely.\n */\nexport async function computeAnchoredPosition(\n reference: AnchorElement,\n floating: HTMLElement,\n options: AnchoredPositionOptions = {},\n): Promise<AnchoredPositionResult> {\n const sizeData: Partial<SizeData> = {};\n const result = await computePosition(reference, floating, {\n placement: options.placement ?? \"bottom\",\n strategy: \"fixed\",\n middleware: buildMiddleware(options, sizeData),\n });\n const arrowData = result.middlewareData.arrow;\n return {\n x: result.x,\n y: result.y,\n placement: result.placement,\n strategy: result.strategy,\n middlewareData: result.middlewareData,\n arrow: { x: arrowData?.x, y: arrowData?.y },\n availableWidth: sizeData.availableWidth,\n availableHeight: sizeData.availableHeight,\n rects: result.middlewareData.minervaRects as ElementRects | undefined,\n };\n}\n\n/**\n * Keeps `floating` positioned while the anchor / floating element move or\n * resize, or the page scrolls (`autoUpdate`). `onUpdate` receives each new\n * result (typically `(r) => applyPosition(floating, r)`).\n *\n * @returns cleanup function (stops updating; pending results are dropped).\n */\nexport function autoPosition(\n reference: AnchorElement,\n floating: HTMLElement,\n options: AnchoredPositionOptions,\n onUpdate: (result: AnchoredPositionResult) => void,\n): () => void {\n let active = true;\n const stop = autoUpdate(\n reference,\n floating,\n () => {\n void computeAnchoredPosition(reference, floating, options).then(\n (result) => {\n if (active) onUpdate(result);\n },\n );\n },\n options.autoUpdate,\n );\n return () => {\n active = false;\n stop();\n };\n}\n\n/** `\"bottom-start\"` -> `{ side: \"bottom\", align: \"start\" }` */\nexport function parsePlacement(placement: Placement): {\n side: Side;\n align: Align;\n} {\n const [side, align] = placement.split(\"-\") as [Side, Align | undefined];\n return { side, align: align ?? \"center\" };\n}\n\n/** `(\"bottom\", \"start\")` -> `\"bottom-start\"`; `\"center\"` -> `\"bottom\"`. */\nexport function toPlacement(side: Side, align: Align = \"center\"): Placement {\n return (align === \"center\" ? side : `${side}-${align}`) as Placement;\n}\n\n// A pure IIFE (not a top-level loop) so bundlers can drop it when\n// `fromCamelPlacement` is unused.\nconst CAMEL_TO_PLACEMENT: Record<string, Placement> = /* @__PURE__ */ (() => {\n const map: Record<string, Placement> = {};\n for (const side of [\"top\", \"bottom\", \"left\", \"right\"] as const) {\n map[side] = side;\n map[`${side}Start`] = `${side}-start`;\n map[`${side}End`] = `${side}-end`;\n }\n return map;\n})();\n\n/** `\"bottomStart\"` -> `\"bottom-start\"` (kebab-case is returned as is). */\nexport function fromCamelPlacement(value: string): Placement {\n return CAMEL_TO_PLACEMENT[value] ?? (value as Placement);\n}\n\n/** `\"bottom-start\"` -> `\"bottomStart\"` */\nexport function toCamelPlacement(placement: Placement): string {\n return placement.replace(/-(\\w)/, (_, c: string) => c.toUpperCase());\n}\n\n/**\n * CSS `transform-origin` pointing at the anchor, for scale-in animations.\n * With arrow offsets, the origin is the arrow tip (center of an arrow of\n * `arrowSize` px).\n */\nexport function getTransformOrigin(\n placement: Placement,\n arrow?: { x?: number; y?: number },\n arrowSize = 0,\n): string {\n const { side, align } = parsePlacement(placement);\n const alignPercent = { start: \"0%\", center: \"50%\", end: \"100%\" }[align];\n const vertical = side === \"top\" || side === \"bottom\";\n const cross = vertical\n ? arrow?.x != null\n ? `${arrow.x + arrowSize / 2}px`\n : alignPercent\n : arrow?.y != null\n ? `${arrow.y + arrowSize / 2}px`\n : alignPercent;\n // the origin sits on the edge facing the anchor\n const main = { top: \"100%\", bottom: \"0%\", left: \"100%\", right: \"0%\" }[side];\n return vertical ? `${cross} ${main}` : `${main} ${cross}`;\n}\n\n/**\n * Writes a result onto the floating element: `position`, `left`, `top`,\n * `data-side` / `data-align` / `data-placement` and the CSS variables\n * `--minerva-transform-origin`, `--minerva-anchor-width/height`,\n * `--minerva-available-width/height`.\n */\nexport function applyPosition(\n floating: HTMLElement,\n result: AnchoredPositionResult,\n options: { arrowSize?: number } = {},\n): void {\n const { style } = floating;\n const { side, align } = parsePlacement(result.placement);\n style.position = result.strategy;\n style.left = `${result.x}px`;\n style.top = `${result.y}px`;\n floating.setAttribute(\"data-side\", side);\n floating.setAttribute(\"data-align\", align);\n floating.setAttribute(\"data-placement\", result.placement);\n style.setProperty(\n \"--minerva-transform-origin\",\n getTransformOrigin(result.placement, result.arrow, options.arrowSize),\n );\n const reference = result.rects?.reference;\n if (reference) {\n style.setProperty(\"--minerva-anchor-width\", `${reference.width}px`);\n style.setProperty(\"--minerva-anchor-height\", `${reference.height}px`);\n }\n if (result.availableWidth != null) {\n style.setProperty(\n \"--minerva-available-width\",\n `${Math.max(0, result.availableWidth)}px`,\n );\n }\n if (result.availableHeight != null) {\n style.setProperty(\n \"--minerva-available-height\",\n `${Math.max(0, result.availableHeight)}px`,\n );\n }\n}\n","/** A point in client (viewport) coordinates. */\nexport interface Point {\n x: number;\n y: number;\n}\n\n/** A closed polygon (the last point connects back to the first). */\nexport type Polygon = Point[];\n\n/** Side of the exit point on which the target (e.g. the submenu) lies. */\nexport type GraceSide = \"top\" | \"right\" | \"bottom\" | \"left\";\n\n/** Rectangle in client coordinates (a `DOMRect` works). */\nexport interface GraceRect {\n top: number;\n right: number;\n bottom: number;\n left: number;\n}\n\n/**\n * Ray-casting point-in-polygon test (points exactly on an edge may go\n * either way).\n */\nexport function isPointInPolygon(point: Point, polygon: Polygon): boolean {\n const { x, y } = point;\n let inside = false;\n for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {\n const xi = polygon[i].x;\n const yi = polygon[i].y;\n const xj = polygon[j].x;\n const yj = polygon[j].y;\n const intersect =\n yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi;\n if (intersect) inside = !inside;\n }\n return inside;\n}\n\n/**\n * The \"safe triangle\" between the point where the pointer left a trigger\n * (e.g. a submenu item) and the target rectangle (the submenu): a polygon\n * from the exit point (pushed back by `padding` px so it is strictly\n * inside) to the near and far edges of the target.\n */\nexport function getGraceArea(\n exitPoint: Point,\n rect: GraceRect,\n side: GraceSide,\n padding = 5,\n): Polygon {\n switch (side) {\n case \"right\":\n return [\n { x: exitPoint.x - padding, y: exitPoint.y },\n { x: rect.left, y: rect.top },\n { x: rect.right, y: rect.top },\n { x: rect.right, y: rect.bottom },\n { x: rect.left, y: rect.bottom },\n ];\n case \"left\":\n return [\n { x: exitPoint.x + padding, y: exitPoint.y },\n { x: rect.right, y: rect.top },\n { x: rect.left, y: rect.top },\n { x: rect.left, y: rect.bottom },\n { x: rect.right, y: rect.bottom },\n ];\n case \"bottom\":\n return [\n { x: exitPoint.x, y: exitPoint.y - padding },\n { x: rect.left, y: rect.top },\n { x: rect.left, y: rect.bottom },\n { x: rect.right, y: rect.bottom },\n { x: rect.right, y: rect.top },\n ];\n case \"top\":\n return [\n { x: exitPoint.x, y: exitPoint.y + padding },\n { x: rect.left, y: rect.bottom },\n { x: rect.left, y: rect.top },\n { x: rect.right, y: rect.top },\n { x: rect.right, y: rect.bottom },\n ];\n }\n}\n\nexport interface PointerGraceOptions {\n /** Grace area padding, see `getGraceArea`. @default 5 */\n padding?: number;\n /**\n * The grace area expires after this many ms (the pointer is assumed to\n * have stopped heading to the target). `0` disables expiry. @default 300\n */\n timeout?: number;\n}\n\nexport interface PointerGrace {\n /** Starts a grace period when the pointer leaves the trigger. */\n start(exitPoint: Point, targetRect: GraceRect, side: GraceSide): void;\n /** Whether `point` is inside the current (non-expired) grace area. */\n isInGraceArea(point: Point): boolean;\n /** Ends the grace period. */\n clear(): void;\n /** Current grace polygon, if any (for debugging / drawing). */\n getArea(): Polygon | null;\n}\n\n/**\n * Pointer \"grace intent\" for submenus: while the pointer travels from a\n * submenu trigger towards the open submenu it may cross sibling items;\n * those should not steal the hover as long as the pointer is inside the\n * safe triangle.\n */\nexport function createPointerGrace(\n options: PointerGraceOptions = {},\n): PointerGrace {\n const { padding = 5, timeout = 300 } = options;\n let area: Polygon | null = null;\n let startedAt = 0;\n\n const expired = () => timeout > 0 && Date.now() - startedAt > timeout;\n\n return {\n start(exitPoint, targetRect, side) {\n area = getGraceArea(exitPoint, targetRect, side, padding);\n startedAt = Date.now();\n },\n isInGraceArea(point) {\n if (!area) return false;\n if (expired()) {\n area = null;\n return false;\n }\n return isPointInPolygon(point, area);\n },\n clear() {\n area = null;\n },\n getArea() {\n if (area && expired()) area = null;\n return area;\n },\n };\n}\n","export interface WaitForExitAnimationOptions {\n /**\n * Safety net (ms) after which the promise resolves even if no end event\n * fired (e.g. the animation was removed). @default computed duration + 50\n */\n timeout?: number;\n}\n\n/** Parses a CSS time list (\"0.2s, 150ms\") and returns the largest value in ms. */\nfunction maxTime(value: string | undefined | null): number {\n if (!value) return 0;\n return Math.max(\n 0,\n ...value.split(\",\").map((part) => {\n const t = part.trim();\n const n = Number.parseFloat(t);\n if (Number.isNaN(n)) return 0;\n return t.endsWith(\"ms\") ? n : n * 1000;\n }),\n );\n}\n\n/**\n * Total running time (ms) of the CSS animations / transitions on `el`\n * (`0` when there is none, e.g. `animation-name: none`).\n */\nexport function getExitAnimationDuration(el: Element): number {\n const win = el.ownerDocument.defaultView;\n if (!win) return 0;\n const style = win.getComputedStyle(el);\n const name = style.animationName;\n const animation =\n name && name !== \"none\"\n ? maxTime(style.animationDuration) + maxTime(style.animationDelay)\n : 0;\n const transition =\n maxTime(style.transitionDuration) + maxTime(style.transitionDelay);\n return Math.max(animation, transition);\n}\n\n/**\n * Resolves once `el` finished its exit animation / transition\n * (`animationend`, `transitionend` or their `cancel` events on `el` itself),\n * or immediately when it has none. Use it to delay unmounting.\n */\nexport function waitForExitAnimation(\n el: Element,\n options: WaitForExitAnimationOptions = {},\n): Promise<void> {\n const duration = getExitAnimationDuration(el);\n if (duration <= 0) return Promise.resolve();\n const win = el.ownerDocument.defaultView;\n const timeout = options.timeout ?? duration + 50;\n\n return new Promise((resolve) => {\n const events = [\n \"animationend\",\n \"animationcancel\",\n \"transitionend\",\n \"transitioncancel\",\n ];\n const done = () => {\n for (const type of events) el.removeEventListener(type, onEnd);\n (win?.clearTimeout.bind(win) ?? clearTimeout)(timer);\n resolve();\n };\n const onEnd = (event: Event) => {\n if (event.target === el) done();\n };\n for (const type of events) el.addEventListener(type, onEnd);\n const timer = (win?.setTimeout.bind(win) ?? setTimeout)(\n done,\n timeout,\n ) as ReturnType<typeof setTimeout>;\n });\n}\n","import { contains, getFocusables, isTabbable } from \"./dom\";\n\n/**\n * The tabbable element following `el` in document order (outside `el`,\n * shadow trees and slotted content included), else the one preceding it,\n * else `null`. Used to move focus off an element about to be removed.\n */\nexport function getAdjacentTabbable(el: HTMLElement): HTMLElement | null {\n const candidates = getFocusables(el.ownerDocument.body).filter(\n (candidate) => !contains(el, candidate) && isTabbable(candidate),\n );\n const next = candidates.find(\n (candidate) =>\n el.compareDocumentPosition(candidate) & Node.DOCUMENT_POSITION_FOLLOWING,\n );\n if (next) return next;\n const previous = candidates.filter(\n (candidate) =>\n el.compareDocumentPosition(candidate) & Node.DOCUMENT_POSITION_PRECEDING,\n );\n return previous[previous.length - 1] ?? null;\n}\n","// Whether a keyboard event target takes text input (global shortcuts and\n// toast hotkeys must not steal keys typed in a field). DOM only.\n\nconst NON_TEXT_INPUT_TYPES = [\n \"button\",\n \"checkbox\",\n \"color\",\n \"file\",\n \"image\",\n \"radio\",\n \"range\",\n \"reset\",\n \"submit\",\n];\n\n/**\n * Whether `target` takes text input: text-like inputs, textareas, selects\n * and contenteditable hosts. Always `false` without a DOM (SSR).\n */\nexport function isEditableTarget(target: EventTarget | null): boolean {\n if (typeof HTMLElement === \"undefined\" || !(target instanceof HTMLElement)) {\n return false;\n }\n if (target.isContentEditable) return true;\n if (target instanceof HTMLTextAreaElement) return true;\n if (target instanceof HTMLSelectElement) return true;\n if (target instanceof HTMLInputElement) {\n return !NON_TEXT_INPUT_TYPES.includes(target.type);\n }\n return false;\n}\n","// Whether a pointer / keyboard event comes from an interactive element nested\n// in a container that itself reacts to clicks (e.g. a flashcard that flips on\n// click must not flip when a link or button inside a face is used). DOM only.\n\n/** Elements that handle clicks themselves. */\nexport const INTERACTIVE_SELECTOR = [\n \"a[href]\",\n \"area[href]\",\n \"button\",\n \"input\",\n \"select\",\n \"textarea\",\n \"label\",\n \"summary\",\n \"iframe\",\n \"object\",\n \"embed\",\n \"audio[controls]\",\n \"video[controls]\",\n \"[contenteditable]:not([contenteditable='false'])\",\n \"[tabindex]\",\n ...[\n \"button\",\n \"link\",\n \"checkbox\",\n \"radio\",\n \"switch\",\n \"tab\",\n \"menuitem\",\n \"option\",\n \"slider\",\n \"spinbutton\",\n \"textbox\",\n \"searchbox\",\n \"combobox\",\n ].map((role) => `[role='${role}']`),\n].join(\",\");\n\n/**\n * Whether `event` originates from an interactive element (link, button, form\n * control, element with a tabindex or a widget role) strictly inside\n * `container`. Uses the composed path, so slotted (light DOM) content of a\n * shadow root is handled. Always `false` without a DOM (SSR).\n */\nexport function isInteractiveEventTarget(\n event: Pick<Event, \"target\"> & Partial<Pick<Event, \"composedPath\">>,\n container: Element,\n): boolean {\n if (typeof Element === \"undefined\") return false;\n let path: EventTarget[] = event.composedPath?.() ?? [];\n if (!path.length) {\n path = [];\n for (\n let node = event.target as Node | null;\n node;\n node = node.parentNode ?? (node as ShadowRoot).host ?? null\n ) {\n path.push(node);\n }\n }\n for (const node of path) {\n if (node === container) return false;\n if (node instanceof Element && node.matches(INTERACTIVE_SELECTOR)) {\n return true;\n }\n }\n return false;\n}\n","// Drag and drop of the cards of a DashboardColumns, shared by the web renderers\n// (React DOM, Vue, Web Components, Angular). The board stays controlled: the\n// controller never moves a card, it shows where the card would land (a\n// floating copy under the pointer, a drop line, the target column\n// highlighted) and reports a `DashboardCardMove` on drop.\n//\n// - pointer: Pointer Events (mouse, pen and touch; no HTML5 drag and drop,\n// which touch screens lack). A mouse drag starts after a few pixels; touch\n// and pen need a long press so that swiping still scrolls the board. The\n// board scrolls horizontally, and the column under the pointer vertically,\n// near their edges. Escape cancels.\n// - keyboard: on a focused card, Space / Enter picks it up, the arrows move\n// it (Left / Right between columns, Up / Down within one), Space / Enter\n// drops it, Escape cancels; every step is announced in a live region.\n//\n// The renderer describes its DOM with an adapter (columns, cards, keys and\n// labels, the scrolling body of a column) and re-reads its props through\n// getters, so one controller lives as long as the board.\nimport {\n isDashboardNoop,\n dashboardCardMove,\n dashboardInsertIndex,\n dashboardKeyAction,\n dashboardKeyboardTarget,\n dashboardSlots,\n type DashboardCardMove,\n type DashboardLayoutColumn,\n type DashboardPosition,\n} from \"@minerva/core\";\nimport { getDirection } from \"./direction\";\nimport { INTERACTIVE_SELECTOR } from \"./interactive-target\";\n\n/** How a renderer exposes the columns and cards of a board */\nexport interface DashboardDragAdapter {\n /** The columns of the board, in order */\n columns(): HTMLElement[];\n /** Key (`value`) of a column; columns without one take no cards */\n columnKey(column: HTMLElement): string | null | undefined;\n /** Name of a column in the announcements (its title) */\n columnLabel(column: HTMLElement): string;\n /** The cards of a column, in order */\n cards(column: HTMLElement): HTMLElement[];\n /** Key (`value`) of a card; cards without one cannot be dragged */\n cardKey(card: HTMLElement): string | null | undefined;\n /** Name of a card in the announcements */\n cardLabel(card: HTMLElement): string;\n /** The vertically scrolling body of a column (its list, else its empty content) */\n body(column: HTMLElement): HTMLElement | null;\n}\n\n/** Options of `createDashboardDrag` (read on every use: pass getters) */\nexport interface DashboardDragOptions extends DashboardDragAdapter {\n /** The horizontally scrolling element of the board */\n scroller(): HTMLElement | null;\n /**\n * Element holding the drag layer (the floating card, the drop line, the\n * live region and the keyboard instructions); the board root by default.\n * It must share the cards' tree scope (the instructions are their\n * `aria-describedby`).\n */\n layerParent?(): HTMLElement;\n /** Id of the keyboard instructions element the cards are described by */\n hintId: string;\n /** Whether dragging is on (the `draggable` prop) */\n enabled(): boolean;\n /** Whether a card may be dropped there (the `canDrop` prop) */\n canDrop?(move: DashboardCardMove): boolean;\n /** Reports a drop that moves a card (the `onCardMove` prop / event) */\n onMove(move: DashboardCardMove): void;\n /** Translates a `dashboard.*` message */\n t(key: string, params?: Record<string, string | number>): string;\n}\n\n/** A drag controller attached to a board root */\nexport interface DashboardDrag {\n /** Whether a card is picked up */\n readonly dragging: boolean;\n /** Syncs the layer with the options (call after every render) */\n refresh(): void;\n /** Drops nothing: puts a picked-up card back */\n cancel(): void;\n /** Removes the listeners and the layer */\n destroy(): void;\n}\n\n/** Attribute naming the key of a column (React, Vue, Angular) */\nexport const DASHBOARD_COLUMN_ATTRIBUTE = \"data-dashboard-column\";\n/** Attribute naming the key of a card (React, Vue, Angular) */\nexport const DASHBOARD_CARD_ATTRIBUTE = \"data-dashboard-card\";\n\n/** Pixels a mouse moves before a press becomes a drag */\nconst MOUSE_THRESHOLD = 4;\n/** Long press (ms) that picks a card up with touch / pen */\nconst TOUCH_DELAY = 250;\n/** Pixels a finger may move during the long press (more: a scroll) */\nconst TOUCH_TOLERANCE = 8;\n/** Width of the edges that auto-scroll (pixels) */\nconst EDGE = 48;\n/** Fastest auto-scroll step (pixels per frame) */\nconst MAX_SPEED = 16;\n\nconst text = (element: Element | null | undefined) =>\n (element?.textContent ?? \"\").replace(/\\s+/g, \" \").trim();\n\n/**\n * Adapter of the renderers that mark their DOM with data attributes:\n * `data-dashboard-column` / `data-dashboard-card` hold the keys, the column parts\n * are `data-minerva=\"dashboard-column\"` + `data-part=\"title\" | \"list\" |\n * \"empty\"`. Nested boards are ignored.\n */\nexport function dashboardDataAdapter(root: HTMLElement): DashboardDragAdapter {\n const ownColumn = (element: Element) =>\n element.parentElement?.closest(`[${DASHBOARD_COLUMN_ATTRIBUTE}]`);\n const parts = (column: HTMLElement, names: string[]) =>\n Array.from(\n column.querySelectorAll<HTMLElement>(\n names\n .map(\n (name) => `[data-minerva=\"dashboard-column\"][data-part=\"${name}\"]`,\n )\n .join(\",\"),\n ),\n ).filter((element) => ownColumn(element) === column);\n const adapter: DashboardDragAdapter = {\n columns: () =>\n Array.from(\n root.querySelectorAll<HTMLElement>(`[${DASHBOARD_COLUMN_ATTRIBUTE}]`),\n ).filter(\n (column) =>\n column.parentElement?.closest(\n '[data-minerva=\"dashboard-columns\"]',\n ) === root,\n ),\n columnKey: (column) => column.getAttribute(DASHBOARD_COLUMN_ATTRIBUTE),\n columnLabel: (column) => {\n const [title] = parts(column, [\"title\"]);\n return (\n text(title) ||\n column.getAttribute(\"aria-label\") ||\n adapter.columnKey(column) ||\n \"\"\n );\n },\n cards: (column) =>\n Array.from(\n column.querySelectorAll<HTMLElement>(`[${DASHBOARD_CARD_ATTRIBUTE}]`),\n ).filter((card) => ownColumn(card) === column),\n cardKey: (card) => card.getAttribute(DASHBOARD_CARD_ATTRIBUTE),\n cardLabel: (card) =>\n card.getAttribute(\"aria-label\") ||\n text(card) ||\n adapter.cardKey(card) ||\n \"\",\n body: (column) => {\n const body = parts(column, [\"list\", \"empty\"]);\n const list = body.find((part) => part.dataset.part === \"list\");\n const empty = body.find((part) => part.dataset.part === \"empty\");\n return adapter.cards(column).length > 0\n ? (list ?? empty ?? null)\n : (empty ?? list ?? null);\n },\n };\n return adapter;\n}\n\ninterface Drag {\n mode: \"pointer\" | \"keyboard\";\n card: HTMLElement;\n key: string;\n label: string;\n from: DashboardPosition;\n /** Where the card would land (`null`: nowhere, a drop cancels) */\n target: DashboardPosition | null;\n column: HTMLElement | null;\n /** Pointer: id, position, and where the card was grabbed */\n pointerId?: number;\n x: number;\n y: number;\n grabX: number;\n grabY: number;\n ghost?: HTMLElement;\n}\n\ninterface Pending {\n card: HTMLElement;\n pointerId: number;\n touch: boolean;\n x: number;\n y: number;\n timer?: ReturnType<typeof setTimeout>;\n}\n\nconst visuallyHidden =\n \"position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0\";\n\n/**\n * Attaches drag and drop of cards to a board: pointer listeners on `root`\n * (events from the cards bubble to it, across shadow roots too) and a layer\n * appended to it while dragging is enabled.\n */\nexport function createDashboardDrag(\n root: HTMLElement,\n options: DashboardDragOptions,\n): DashboardDrag {\n const doc = root.ownerDocument;\n const view = doc.defaultView ?? window;\n let drag: Drag | null = null;\n let pending: Pending | null = null;\n let layer: HTMLElement | null = null;\n let hint: HTMLElement | null = null;\n let live: HTMLElement | null = null;\n let line: HTMLElement | null = null;\n let frame = 0;\n let destroyed = false;\n\n // --- layout ------------------------------------------------------------\n\n const keyedColumns = () =>\n options\n .columns()\n .map((element) => ({ element, key: options.columnKey(element) }))\n .filter((column): column is { element: HTMLElement; key: string } =>\n Boolean(column.key),\n );\n\n const keyedCards = (column: HTMLElement) =>\n options\n .cards(column)\n .map((element) => ({ element, key: options.cardKey(element) }))\n .filter((card): card is { element: HTMLElement; key: string } =>\n Boolean(card.key),\n );\n\n const layout = (): DashboardLayoutColumn[] =>\n keyedColumns().map(({ element, key }) => ({\n key,\n cards: keyedCards(element).map((card) => card.key),\n }));\n\n const columnElement = (key: string) =>\n keyedColumns().find((column) => column.key === key)?.element ?? null;\n\n /** The draggable card `node` is (with its column key), if any */\n const cardOf = (node: EventTarget | null) => {\n if (!(node instanceof HTMLElement)) return null;\n for (const column of keyedColumns()) {\n const card = keyedCards(column.element).find(\n (entry) => entry.element === node,\n );\n if (card) return { ...card, column: column.key };\n }\n return null;\n };\n\n /** The card a pointer event starts on (closest card in the composed path) */\n const cardFromPath = (event: Event) => {\n for (const node of event.composedPath()) {\n if (node === root) return null;\n const card = cardOf(node);\n if (card) return card;\n }\n return null;\n };\n\n // --- layer ----------------------------------------------------------------\n\n const ensureLayer = () => {\n if (layer) return;\n layer = doc.createElement(\"div\");\n layer.setAttribute(\"data-dashboard-layer\", \"\");\n // a zero-size fixed box: its children are placed in viewport\n // coordinates (corrected by its own offset under a transformed ancestor)\n layer.style.cssText =\n \"position:fixed;top:0;left:0;width:0;height:0;overflow:visible;pointer-events:none;z-index:var(--z-popover, 1000)\";\n hint = doc.createElement(\"span\");\n hint.hidden = true;\n live = doc.createElement(\"div\");\n live.setAttribute(\"role\", \"status\");\n live.setAttribute(\"aria-live\", \"assertive\");\n live.setAttribute(\"aria-atomic\", \"true\");\n live.style.cssText = visuallyHidden;\n layer.append(hint, live);\n };\n\n const refresh = () => {\n if (destroyed) return;\n if (!options.enabled()) {\n if (drag) cancel();\n layer?.remove();\n return;\n }\n ensureLayer();\n const parent = options.layerParent?.() ?? root;\n if (layer!.parentNode !== parent) parent.append(layer!);\n hint!.id = options.hintId;\n hint!.textContent = options.t(\"dashboard.dragHint\");\n };\n\n let toggle = false;\n const announce = (\n message: \"lifted\" | \"over\" | \"dropped\" | \"cancelled\",\n position: DashboardPosition,\n ) => {\n if (!drag || !live) return;\n const all = layout();\n const column = columnElement(position.column);\n // a trailing no-break space alternates so that a repeated message is\n // announced again\n toggle = !toggle;\n live.textContent =\n options.t(`dashboard.${message}`, {\n card: drag.label,\n column: column ? options.columnLabel(column) : position.column,\n position: position.index + 1,\n total: dashboardSlots(all, drag.key, position.column),\n }) + (toggle ? \"\\u00a0\" : \"\");\n };\n\n const origin = () => {\n const box = layer?.getBoundingClientRect();\n return { x: box?.left ?? 0, y: box?.top ?? 0 };\n };\n\n // --- target --------------------------------------------------------------\n\n const accept = (move: DashboardCardMove) =>\n isDashboardNoop(move) || !options.canDrop || options.canDrop(move);\n\n /** Where a card dropped at (x, y) would land, `null` for nowhere */\n const targetAt = (x: number, y: number): DashboardPosition | null => {\n if (!drag) return null;\n const scroller = options.scroller();\n if (scroller) {\n const box = scroller.getBoundingClientRect();\n if (\n x < box.left - EDGE ||\n x > box.right + EDGE ||\n y < box.top - EDGE ||\n y > box.bottom + EDGE\n )\n return null;\n }\n let best: { key: string; element: HTMLElement } | null = null;\n let distance = Infinity;\n for (const column of keyedColumns()) {\n const box = column.element.getBoundingClientRect();\n const d = x < box.left ? box.left - x : x > box.right ? x - box.right : 0;\n if (d < distance) {\n distance = d;\n best = column;\n }\n }\n if (!best) return null;\n const midpoints = keyedCards(best.element)\n .filter((card) => card.element !== drag!.card)\n .map((card) => {\n const box = card.element.getBoundingClientRect();\n return box.top + box.height / 2;\n });\n const move = dashboardCardMove(layout(), drag.key, {\n column: best.key,\n index: dashboardInsertIndex(midpoints, y),\n });\n return move && accept(move)\n ? { column: move.toColumn, index: move.toIndex }\n : null;\n };\n\n /** Shows the drop line and the highlighted column of the target */\n const paint = () => {\n if (!drag) return;\n const column = drag.target ? columnElement(drag.target.column) : null;\n if (drag.column !== column) {\n drag.column?.removeAttribute(\"data-dashboard-drop-target\");\n column?.setAttribute(\"data-dashboard-drop-target\", \"\");\n drag.column = column;\n }\n if (!column || !drag.target) {\n line?.remove();\n line = null;\n return;\n }\n if (!line) {\n line = doc.createElement(\"div\");\n line.setAttribute(\"data-dashboard-drop-line\", \"\");\n line.setAttribute(\"aria-hidden\", \"true\");\n line.style.cssText =\n \"position:absolute;height:2px;margin-top:-1px;border-radius:1px;background:var(--dashboard-drop-indicator-color, var(--primary-color));forced-color-adjust:none;pointer-events:none\";\n layer?.append(line);\n }\n const others = keyedCards(column)\n .filter((card) => card.element !== drag!.card)\n .map((card) => card.element.getBoundingClientRect());\n const body = (options.body(column) ?? column).getBoundingClientRect();\n const index = drag.target.index;\n let y: number;\n let left = body.left + 8;\n let width = Math.max(0, body.width - 16);\n if (others.length === 0) {\n y = body.top + Math.min(8, body.height / 2);\n } else {\n const next = others[index];\n const previous = others[index - 1];\n if (next && previous) y = (previous.bottom + next.top) / 2;\n else if (next) y = next.top - 4;\n else y = previous!.bottom + 4;\n const reference = others[0]!;\n left = reference.left;\n width = reference.width;\n }\n // keep the line inside the visible part of the column body\n y = Math.min(Math.max(y, body.top), body.bottom);\n const offset = origin();\n line.style.left = `${left - offset.x}px`;\n line.style.top = `${y - offset.y}px`;\n line.style.width = `${width}px`;\n };\n\n const placeGhost = () => {\n if (!drag?.ghost) return;\n const offset = origin();\n drag.ghost.style.left = `${drag.x - drag.grabX - offset.x}px`;\n drag.ghost.style.top = `${drag.y - drag.grabY - offset.y}px`;\n };\n\n // --- lifecycle --------------------------------------------------------------\n\n const lift = (\n card: { element: HTMLElement; key: string; column: string },\n mode: Drag[\"mode\"],\n pointer?: { x: number; y: number; id: number },\n ) => {\n const from = layout();\n const index = from\n .find((column) => column.key === card.column)!\n .cards.indexOf(card.key);\n drag = {\n mode,\n card: card.element,\n key: card.key,\n label: options.cardLabel(card.element),\n from: { column: card.column, index },\n target: { column: card.column, index },\n column: null,\n x: pointer?.x ?? 0,\n y: pointer?.y ?? 0,\n grabX: 0,\n grabY: 0,\n pointerId: pointer?.id,\n };\n ensureLayer();\n refresh();\n card.element.setAttribute(\"data-dashboard-dragging\", mode);\n root.setAttribute(\"data-dashboard-dragging\", mode);\n if (pointer) {\n const box = card.element.getBoundingClientRect();\n drag.grabX = pointer.x - box.left;\n drag.grabY = pointer.y - box.top;\n const ghost = card.element.cloneNode(true) as HTMLElement;\n for (const element of [ghost, ...ghost.querySelectorAll(\"[id]\")])\n element.removeAttribute(\"id\");\n ghost.removeAttribute(\"data-dashboard-dragging\");\n ghost.removeAttribute(DASHBOARD_CARD_ATTRIBUTE);\n ghost.removeAttribute(\"tabindex\");\n ghost.setAttribute(\"aria-hidden\", \"true\");\n ghost.setAttribute(\"inert\", \"\");\n ghost.setAttribute(\"data-dashboard-ghost\", \"\");\n ghost.style.position = \"absolute\";\n ghost.style.boxSizing = \"border-box\";\n ghost.style.width = `${box.width}px`;\n ghost.style.margin = \"0\";\n ghost.style.pointerEvents = \"none\";\n ghost.style.opacity = \"0.92\";\n ghost.style.transform = \"rotate(1.5deg)\";\n ghost.style.boxShadow = \"var(--shadow-lg, 0 10px 24px rgb(0 0 0 / 0.18))\";\n ghost.style.cursor = \"grabbing\";\n drag.ghost = ghost;\n layer!.append(ghost);\n placeGhost();\n view.getSelection?.()?.removeAllRanges();\n doc.addEventListener(\"keydown\", onDocumentKeyDown, true);\n doc.addEventListener(\"contextmenu\", preventDefault, true);\n frame = view.requestAnimationFrame(autoScroll);\n } else {\n card.element.addEventListener(\"blur\", onCardBlur);\n }\n paint();\n announce(\"lifted\", drag.from);\n };\n\n /** Removes every trace of the drag; returns it */\n const finish = () => {\n const current = drag;\n if (!current) return null;\n current.card.removeAttribute(\"data-dashboard-dragging\");\n current.card.removeEventListener(\"blur\", onCardBlur);\n current.column?.removeAttribute(\"data-dashboard-drop-target\");\n root.removeAttribute(\"data-dashboard-dragging\");\n current.ghost?.remove();\n line?.remove();\n line = null;\n view.cancelAnimationFrame(frame);\n doc.removeEventListener(\"keydown\", onDocumentKeyDown, true);\n doc.removeEventListener(\"contextmenu\", preventDefault, true);\n stopPointer();\n return current;\n };\n\n const cancel = () => {\n const current = drag;\n if (!current) return;\n announce(\"cancelled\", current.from);\n finish();\n drag = null;\n };\n\n const drop = () => {\n const current = drag;\n if (!current) return;\n const move = current.target\n ? dashboardCardMove(layout(), current.key, current.target)\n : undefined;\n if (!move || !accept(move)) {\n cancel();\n return;\n }\n announce(\"dropped\", { column: move.toColumn, index: move.toIndex });\n finish();\n drag = null;\n if (isDashboardNoop(move)) return;\n options.onMove(move);\n if (current.mode === \"keyboard\") restoreFocus(current.key, current.card);\n };\n\n /**\n * The app re-renders the moved card, often as a new element: give it the\n * focus back (once the renderer has updated) unless focus went elsewhere\n */\n const restoreFocus = (key: string, previous: HTMLElement) => {\n const attempt = () => {\n if (destroyed) return;\n const active = doc.activeElement;\n if (active && active !== doc.body && active !== previous) return;\n if (active === previous && previous.isConnected) return;\n for (const column of keyedColumns()) {\n const card = keyedCards(column.element).find(\n (entry) => entry.key === key,\n );\n if (card) {\n card.element.focus();\n return;\n }\n }\n };\n view.requestAnimationFrame(() => {\n attempt();\n view.requestAnimationFrame(attempt);\n });\n };\n\n // --- pointer ------------------------------------------------------------------\n\n const preventDefault = (event: Event) => event.preventDefault();\n\n const stopPointer = () => {\n if (pending?.timer) clearTimeout(pending.timer);\n pending = null;\n doc.removeEventListener(\"pointermove\", onPointerMove);\n doc.removeEventListener(\"pointerup\", onPointerUp);\n doc.removeEventListener(\"pointercancel\", onPointerCancel);\n root.removeEventListener(\"touchmove\", onTouchMove);\n };\n\n const startPointerDrag = (x: number, y: number) => {\n if (!pending) return;\n const card = cardOf(pending.card);\n const id = pending.pointerId;\n if (pending.timer) clearTimeout(pending.timer);\n pending = null;\n if (!card) return;\n lift(card, \"pointer\", { x, y, id });\n };\n\n /**\n * Whether a press starts on a control inside the card (a button, a link):\n * it keeps working and does not drag. The card's own shadow content (the\n * focusable wrapper of a web component card) is not such a control.\n */\n const startsOnControl = (event: Event, card: HTMLElement) => {\n for (const node of event.composedPath()) {\n if (node === card) return false;\n if (!(node instanceof Element)) continue;\n if (card.shadowRoot && node.getRootNode() === card.shadowRoot) continue;\n if (node.matches(INTERACTIVE_SELECTOR)) return true;\n }\n return false;\n };\n\n const onPointerDown = (event: PointerEvent) => {\n if (!options.enabled() || drag || pending) return;\n if (!event.isPrimary || (event.pointerType === \"mouse\" && event.button))\n return;\n const card = cardFromPath(event);\n if (!card || startsOnControl(event, card.element)) return;\n const touch = event.pointerType !== \"mouse\";\n pending = {\n card: card.element,\n pointerId: event.pointerId,\n touch,\n x: event.clientX,\n y: event.clientY,\n };\n if (touch) {\n const { x, y } = pending;\n pending.timer = setTimeout(() => startPointerDrag(x, y), TOUCH_DELAY);\n // the long press must be able to stop the page / board from scrolling\n root.addEventListener(\"touchmove\", onTouchMove, { passive: false });\n }\n doc.addEventListener(\"pointermove\", onPointerMove);\n doc.addEventListener(\"pointerup\", onPointerUp);\n doc.addEventListener(\"pointercancel\", onPointerCancel);\n };\n\n const onPointerMove = (event: PointerEvent) => {\n if (pending && event.pointerId === pending.pointerId) {\n const moved = Math.hypot(\n event.clientX - pending.x,\n event.clientY - pending.y,\n );\n if (pending.touch) {\n // moving before the long press is a scroll\n if (moved > TOUCH_TOLERANCE) stopPointer();\n return;\n }\n if (moved < MOUSE_THRESHOLD) return;\n startPointerDrag(pending.x, pending.y);\n }\n if (!drag || drag.mode !== \"pointer\" || event.pointerId !== drag.pointerId)\n return;\n event.preventDefault();\n drag.x = event.clientX;\n drag.y = event.clientY;\n placeGhost();\n retarget();\n };\n\n const retarget = () => {\n if (!drag) return;\n const next = targetAt(drag.x, drag.y);\n const same =\n next === drag.target ||\n (next &&\n drag.target &&\n next.column === drag.target.column &&\n next.index === drag.target.index);\n drag.target = next;\n paint();\n if (!same && next) announce(\"over\", next);\n };\n\n const onPointerUp = (event: PointerEvent) => {\n if (drag?.mode === \"pointer\" && event.pointerId === drag.pointerId) {\n // the click that follows a drag must not activate the card\n doc.addEventListener(\"click\", swallowClick, true);\n setTimeout(() => doc.removeEventListener(\"click\", swallowClick, true), 0);\n drop();\n return;\n }\n if (pending && event.pointerId === pending.pointerId) stopPointer();\n };\n\n const swallowClick = (event: Event) => {\n event.preventDefault();\n event.stopPropagation();\n doc.removeEventListener(\"click\", swallowClick, true);\n };\n\n const onPointerCancel = (event: PointerEvent) => {\n if (drag?.mode === \"pointer\" && event.pointerId === drag.pointerId)\n cancel();\n else if (pending && event.pointerId === pending.pointerId) stopPointer();\n };\n\n const onTouchMove = (event: TouchEvent) => {\n if (drag?.mode === \"pointer\" && event.cancelable) event.preventDefault();\n };\n\n /** Scrolls `scroller` along an axis when the pointer is near its edges */\n const edgeScroll = (\n scroller: HTMLElement,\n axis: \"x\" | \"y\",\n position: number,\n ) => {\n const box = scroller.getBoundingClientRect();\n const [start, end] =\n axis === \"x\" ? [box.left, box.right] : [box.top, box.bottom];\n const edge = Math.min(EDGE, (end - start) / 4);\n if (edge <= 0) return false;\n let step = 0;\n if (position < start + edge)\n step = -Math.ceil(MAX_SPEED * (1 - Math.max(0, position - start) / edge));\n else if (position > end - edge)\n step = Math.ceil(MAX_SPEED * (1 - Math.max(0, end - position) / edge));\n if (!step) return false;\n const before = axis === \"x\" ? scroller.scrollLeft : scroller.scrollTop;\n if (axis === \"x\") scroller.scrollLeft += step;\n else scroller.scrollTop += step;\n return (axis === \"x\" ? scroller.scrollLeft : scroller.scrollTop) !== before;\n };\n\n const autoScroll = () => {\n if (!drag || drag.mode !== \"pointer\") return;\n const scroller = options.scroller();\n let scrolled = scroller ? edgeScroll(scroller, \"x\", drag.x) : false;\n const body = drag.column ? options.body(drag.column) : null;\n if (body) scrolled = edgeScroll(body, \"y\", drag.y) || scrolled;\n if (scrolled) retarget();\n frame = view.requestAnimationFrame(autoScroll);\n };\n\n // --- keyboard -----------------------------------------------------------------\n\n /** Scrolls the board / column body (never the page) to show `element` */\n const reveal = (scroller: HTMLElement | null, element: Element) => {\n if (!scroller) return;\n const outer = scroller.getBoundingClientRect();\n const inner = element.getBoundingClientRect();\n if (inner.left < outer.left) scroller.scrollLeft -= outer.left - inner.left;\n else if (inner.right > outer.right)\n scroller.scrollLeft += Math.min(\n inner.right - outer.right,\n inner.left - outer.left,\n );\n if (inner.top < outer.top) scroller.scrollTop -= outer.top - inner.top;\n else if (inner.bottom > outer.bottom)\n scroller.scrollTop += Math.min(\n inner.bottom - outer.bottom,\n inner.top - outer.top,\n );\n };\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (!options.enabled() || event.defaultPrevented) return;\n if (event.altKey || event.ctrlKey || event.metaKey) return;\n const action = dashboardKeyAction(event.key, getDirection(root) === \"rtl\");\n if (!action) return;\n if (!drag) {\n if (action !== \"toggle\" || event.repeat) return;\n const card = cardOf(event.target);\n if (!card) return;\n event.preventDefault();\n lift(card, \"keyboard\");\n return;\n }\n if (drag.mode !== \"keyboard\" || event.target !== drag.card) return;\n event.preventDefault();\n event.stopPropagation();\n if (action === \"toggle\") {\n if (!event.repeat) drop();\n return;\n }\n if (action === \"cancel\") {\n cancel();\n return;\n }\n const current = drag.target ?? drag.from;\n const next = dashboardKeyboardTarget(\n layout(),\n drag.key,\n current,\n action,\n options.canDrop ? accept : undefined,\n );\n if (!next) return;\n drag.target = next;\n const column = columnElement(next.column);\n if (column) {\n reveal(options.scroller(), column);\n const neighbor = keyedCards(column).filter(\n (card) => card.element !== drag!.card,\n )[next.index];\n const body = options.body(column);\n if (neighbor) reveal(body, neighbor.element);\n else if (body) body.scrollTop = body.scrollHeight;\n }\n paint();\n announce(\"over\", next);\n };\n\n const onDocumentKeyDown = (event: KeyboardEvent) => {\n if (\n drag?.mode === \"pointer\" &&\n dashboardKeyAction(event.key) === \"cancel\"\n ) {\n event.preventDefault();\n event.stopPropagation();\n cancel();\n }\n };\n\n const onCardBlur = () => {\n if (drag?.mode === \"keyboard\") cancel();\n };\n\n /**\n * Native drag and drop (links, images, a draggable=\"true\" card or board)\n * stays off\n */\n const onDragStart = (event: DragEvent) => {\n if (\n options.enabled() &&\n (drag || pending || event.target === root || cardFromPath(event))\n )\n event.preventDefault();\n };\n\n root.addEventListener(\"pointerdown\", onPointerDown);\n root.addEventListener(\"keydown\", onKeyDown);\n root.addEventListener(\"dragstart\", onDragStart);\n refresh();\n\n return {\n get dragging() {\n return drag !== null;\n },\n refresh,\n cancel,\n destroy() {\n finish();\n drag = null;\n destroyed = true;\n root.removeEventListener(\"pointerdown\", onPointerDown);\n root.removeEventListener(\"keydown\", onKeyDown);\n root.removeEventListener(\"dragstart\", onDragStart);\n layer?.remove();\n layer = null;\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Deprecated aliases (the component was called KanbanBoard): kept for one\n// minor release cycle, not documented. The attribute values changed too.\n\n/** @deprecated Use `DashboardDragAdapter` */\nexport type KanbanDragAdapter = DashboardDragAdapter;\n/** @deprecated Use `DashboardDragOptions` */\nexport type KanbanDragOptions = DashboardDragOptions;\n/** @deprecated Use `DashboardDrag` */\nexport type KanbanDrag = DashboardDrag;\n/** @deprecated Use `DASHBOARD_COLUMN_ATTRIBUTE` (now `\"data-dashboard-column\"`) */\nexport const KANBAN_COLUMN_ATTRIBUTE = DASHBOARD_COLUMN_ATTRIBUTE;\n/** @deprecated Use `DASHBOARD_CARD_ATTRIBUTE` (now `\"data-dashboard-card\"`) */\nexport const KANBAN_CARD_ATTRIBUTE = DASHBOARD_CARD_ATTRIBUTE;\n/** @deprecated Use `dashboardDataAdapter` */\nexport const kanbanDataAdapter = dashboardDataAdapter;\n/** @deprecated Use `createDashboardDrag` */\nexport const createKanbanDrag = createDashboardDrag;\n","// Captions of the web media players (React / Vue / Angular MediaPlayer,\n// <minerva-media-player>): the players render their tracks as <track>\n// children of the <audio> / <video> and draw the active cue themselves, so\n// captions look the same in every browser and work for audio too.\nimport {\n activeCueText,\n cueText,\n isSrtSource,\n loadCaptions,\n type MediaCue,\n type MediaTrack,\n} from \"@minerva/core\";\n\n/** Options of {@link bindMediaCaptions}. */\nexport interface MediaCaptionsOptions {\n /**\n * CORS mode of the player (`crossOrigin` of the media element): the\n * fallback fetch sends credentials only for `use-credentials`.\n */\n crossOrigin?: string | null;\n /** Reads a captions file (defaults to `fetch`). */\n fetchText?: (url: string) => Promise<string>;\n}\n\nconst fetchTextWith =\n (crossOrigin?: string | null) =>\n async (url: string): Promise<string> => {\n if (typeof fetch !== \"function\") throw new Error(\"fetch is unavailable\");\n const response = await fetch(url, {\n credentials:\n crossOrigin === \"use-credentials\" ? \"include\" : \"same-origin\",\n });\n if (!response.ok) throw new Error(`HTTP ${response.status}`);\n return response.text();\n };\n\n/** Plain text of a TextTrack's active cues (one cue per line). */\nexport function textTrackCueText(track: TextTrack | null | undefined): string {\n const cues = track?.activeCues;\n if (!cues) return \"\";\n const lines: string[] = [];\n for (let i = 0; i < cues.length; i++) {\n const cue = cues[i] as (TextTrackCue & { text?: string }) | undefined;\n const text = cueText(cue?.text ?? \"\");\n if (text) lines.push(text);\n }\n return lines.join(\"\\n\");\n}\n\n/**\n * Shows the captions of `tracks[index]` (`-1` = off) of a media element whose\n * <track> children render `tracks` in order: the selected TextTrack is\n * `hidden` (loaded, not drawn by the browser) and `onText` receives the text\n * of its active cues on each `cuechange`. SRT files, failed <track> loads and\n * media without TextTrack support fall back to fetching and parsing the file\n * (`loadCaptions`), synchronized on `timeupdate`. While the video is in the\n * browser's own fullscreen (iOS) or picture-in-picture window, where the\n * overlay can't be seen, the track is `showing` instead.\n *\n * Returns the cleanup (removes the listeners, disables the tracks).\n */\nexport function bindMediaCaptions(\n media: HTMLMediaElement,\n tracks: readonly MediaTrack[],\n index: number,\n onText: (text: string) => void,\n options: MediaCaptionsOptions = {},\n): () => void {\n const elements = Array.from(media.children).filter(\n (el): el is HTMLTrackElement => el.localName === \"track\",\n );\n const textTrackOf = (el: HTMLTrackElement | undefined) => {\n try {\n return el?.track ?? null;\n } catch {\n return null;\n }\n };\n const setMode = (el: HTMLTrackElement | undefined, mode: TextTrackMode) => {\n const track = textTrackOf(el);\n if (track && track.mode !== mode) track.mode = mode;\n };\n elements.forEach((el, i) => {\n if (i !== index) setMode(el, \"disabled\");\n });\n\n let last: string | null = null;\n const emit = (text: string) => {\n if (text === last) return;\n last = text;\n onText(text);\n };\n\n const selected = index >= 0 ? tracks[index] : undefined;\n if (!selected) {\n emit(\"\");\n return () => undefined;\n }\n\n const cleanups: Array<() => void> = [];\n const on = (\n target: EventTarget,\n type: string,\n listener: EventListener,\n ): void => {\n target.addEventListener(type, listener);\n cleanups.push(() => target.removeEventListener(type, listener));\n };\n let disposed = false;\n\n const fallback = () => {\n let cues: MediaCue[] = [];\n const update = () => emit(activeCueText(cues, media.currentTime));\n emit(\"\");\n on(media, \"timeupdate\", update);\n on(media, \"seeked\", update);\n loadCaptions(\n selected.src,\n options.fetchText ?? fetchTextWith(options.crossOrigin),\n ).then(\n (loaded) => {\n if (disposed) return;\n cues = loaded;\n update();\n },\n () => {\n if (!disposed) emit(\"\");\n },\n );\n };\n\n const element = elements[index];\n const textTrack = textTrackOf(element);\n if (element && textTrack && !isSrtSource(selected.src)) {\n textTrack.mode = \"hidden\";\n let native = true;\n const onCueChange = () => {\n if (native) emit(textTrackCueText(textTrack));\n };\n on(textTrack, \"cuechange\", onCueChange);\n on(element, \"error\", () => {\n if (!native || disposed) return;\n native = false;\n fallback();\n });\n const show = () => {\n if (native) textTrack.mode = \"showing\";\n };\n const hide = () => {\n if (native) textTrack.mode = \"hidden\";\n };\n on(media, \"webkitbeginfullscreen\", show);\n on(media, \"webkitendfullscreen\", hide);\n on(media, \"enterpictureinpicture\", show);\n on(media, \"leavepictureinpicture\", hide);\n onCueChange();\n } else {\n setMode(element, \"disabled\");\n fallback();\n }\n\n return () => {\n disposed = true;\n for (const cleanup of cleanups.splice(0)) cleanup();\n setMode(element, \"disabled\");\n };\n}\n","// Maps a DOM selection inside a code block to offsets of its code, so an app\n// can save the selected range as a mark (`CodeMark` of @minerva/core). DOM\n// only (React DOM, Vue, Angular, Web Components, Taro H5).\n\n/** A selected range of a code block's code */\nexport interface CodeSelectionRange {\n /** Start offset (inclusive), in UTF-16 code units of the code */\n start: number;\n /** End offset (exclusive), in UTF-16 code units of the code */\n end: number;\n /** The selected code (`code.slice(start, end)`) */\n text: string;\n}\n\ntype Boundary = readonly [node: Node, offset: number];\n\n/** The <code> holding the text: `container` itself or its first <code>. */\nfunction codeRoot(container: Element | ShadowRoot): Node {\n if (container instanceof Element && container.localName === \"code\")\n return container;\n return container.querySelector(\"code\") ?? container;\n}\n\n/** Selected range(s) of `selection`, as boundaries (first start, last end). */\nfunction boundaries(\n selection: Selection | AbstractRange,\n root: Node,\n): [Boundary, Boundary] | null {\n if (\"rangeCount\" in selection) {\n if (!selection.rangeCount) return null;\n const shadow = root.getRootNode();\n // a selection inside a shadow root: the composed range (Chrome / Safari /\n // Firefox), else the plain ranges (light DOM or older browsers)\n let composed: StaticRange[] | null = null;\n if (\n typeof ShadowRoot !== \"undefined\" &&\n shadow instanceof ShadowRoot &&\n typeof (selection as SelectionWithComposed).getComposedRanges ===\n \"function\"\n ) {\n try {\n composed = (selection as SelectionWithComposed).getComposedRanges({\n shadowRoots: [shadow],\n });\n } catch {\n composed = null; // older signature: getComposedRanges(...roots)\n }\n }\n const first = composed?.[0] ?? selection.getRangeAt(0);\n const last =\n composed?.[composed.length - 1] ??\n selection.getRangeAt(selection.rangeCount - 1);\n return [\n [first.startContainer, first.startOffset],\n [last.endContainer, last.endOffset],\n ];\n }\n return [\n [selection.startContainer, selection.startOffset],\n [selection.endContainer, selection.endOffset],\n ];\n}\n\ninterface SelectionWithComposed extends Selection {\n getComposedRanges(options: { shadowRoots: ShadowRoot[] }): StaticRange[];\n}\n\n/** Offset in the text of `root` of a boundary point (clamped to the text). */\nfunction textOffset(root: Node, [node, offset]: Boundary, total: number) {\n if (node === root || root.contains(node)) {\n const range = (root.ownerDocument ?? document).createRange();\n range.setStart(root, 0);\n range.setEnd(node, offset);\n return Math.min(total, range.toString().length);\n }\n const position = root.compareDocumentPosition(node);\n if (position & Node.DOCUMENT_POSITION_CONTAINS) {\n // `node` is an ancestor: the boundary is before its child `offset`\n let child: Node = root;\n while (child.parentNode && child.parentNode !== node)\n child = child.parentNode;\n const index = Array.prototype.indexOf.call(node.childNodes, child);\n return index < offset ? total : 0;\n }\n return position & Node.DOCUMENT_POSITION_PRECEDING ? 0 : total;\n}\n\n/**\n * The mark of a click in a code block: the item of `marks` at the\n * `data-mark-index` of the <mark> holding `target` (inside `container`),\n * `undefined` elsewhere or when the click ends a text selection drag in the\n * code (the user was selecting, not clicking the mark). Used by the\n * CodeBlock `onMarkClick` / `mark-click` of the web renderers.\n */\nexport function clickedCodeMark<M>(\n target: EventTarget | null,\n container: Element,\n marks: readonly M[] | null | undefined,\n): M | undefined {\n const element =\n target && typeof (target as Element).closest === \"function\"\n ? (target as Element).closest(\"mark[data-mark-index]\")\n : null;\n if (!element || !container.contains(element)) return undefined;\n const root = container.getRootNode() as Document | ShadowRoot;\n const selection =\n (root as { getSelection?: () => Selection | null }).getSelection?.() ??\n container.ownerDocument.getSelection();\n if (\n selection &&\n !selection.isCollapsed &&\n container.contains(selection.anchorNode)\n )\n return undefined;\n return marks?.[Number(element.getAttribute(\"data-mark-index\"))];\n}\n\n/**\n * Offsets in the code of a selection made in a code block (CodeBlock of\n * every web renderer), to save it as a mark.\n *\n * `container` is the code block's <pre> (React `ref`, the Vue / Angular\n * element), its <code>, or any ancestor holding a single code block (its\n * first <code> is used); `selection` defaults to the document selection\n * (a `Range` / `StaticRange` also works). Line numbers are generated\n * content, so they never count. A selection extending outside the code is\n * clamped to it. Returns `null` without a DOM, a selection, or when nothing\n * of the code is selected.\n *\n * For `<minerva-code-block>` (shadow DOM) use its `getSelectionRange()`.\n */\nexport function getCodeSelectionRange(\n container: Element | ShadowRoot | null | undefined,\n selection?: Selection | AbstractRange | null,\n): CodeSelectionRange | null {\n if (!container || typeof document === \"undefined\") return null;\n const root = codeRoot(container);\n const source =\n selection === undefined\n ? (root.ownerDocument?.defaultView ?? window).getSelection()\n : selection;\n if (!source) return null;\n const points = boundaries(source, root);\n if (!points) return null;\n const code = root.textContent ?? \"\";\n const a = textOffset(root, points[0], code.length);\n const b = textOffset(root, points[1], code.length);\n const start = Math.min(a, b);\n const end = Math.max(a, b);\n if (start === end) return null;\n return { start, end, text: code.slice(start, end) };\n}\n","import type {\n ComponentTheme,\n CustomBilingualTheme,\n DefaultTheme,\n Theme,\n ThemeMap,\n ThemeName,\n} from \"@minerva/core\";\nimport { isThemeName, themeKeys, themes } from \"@minerva/core\";\nimport { sharedState } from \"../internal/shared-state\";\n\nconst DARK_SCHEME_QUERY = \"(prefers-color-scheme: dark)\";\n\n/**\n * Read the user's preferred color scheme. Falls back to \"light\" when\n * `matchMedia` is unavailable (SSR, old browsers, some test environments).\n */\nexport const getSystemTheme = (): DefaultTheme => {\n if (typeof window === \"undefined\" || !window.matchMedia) return \"light\";\n return window.matchMedia(DARK_SCHEME_QUERY).matches ? \"dark\" : \"light\";\n};\n\nexport const isBilingualTheme = (\n theme: unknown,\n): theme is CustomBilingualTheme =>\n typeof theme === \"object\" &&\n theme !== null &&\n \"light\" in theme &&\n \"dark\" in theme &&\n typeof (theme as CustomBilingualTheme).light === \"object\" &&\n typeof (theme as CustomBilingualTheme).dark === \"object\";\n\n/**\n * Resolve any accepted theme value to a concrete theme object.\n * - \"auto\" and light/dark pairs follow `systemTheme`\n * - built-in names are looked up in `themes`\n * - plain objects are used as-is\n */\nexport const resolveTheme = (\n theme: Theme,\n systemTheme: DefaultTheme = getSystemTheme(),\n): ComponentTheme | ThemeMap => {\n if (theme === \"auto\" || theme === \"system\") return themes[systemTheme];\n if (typeof theme === \"string\") {\n if (!isThemeName(theme)) {\n throw new Error(\n `Unsupported theme \"${theme}\", expected one of: auto, system, ${Object.keys(themes).join(\", \")}`,\n );\n }\n return themes[theme];\n }\n if (isBilingualTheme(theme)) return theme[systemTheme];\n return theme;\n};\n\n/**\n * Keys written by the last `generateCSSVariables` call, per target. Shared by\n * every module copy, so a copy switching themes removes the custom keys\n * another copy wrote.\n */\nconst appliedKeys = sharedState(\n \"theme-applied-keys.v1\",\n () => new WeakMap<CSSStyleDeclaration, Set<string>>(),\n);\n\n/**\n * Write every theme entry as a CSS custom property (`--<key>`).\n *\n * Variables written by a previous call on the same target (and any built-in\n * theme key) that the new theme does not define are removed, so switching from\n * e.g. a dark theme that sets `--surface-color` to a custom theme that does not\n * falls back to the stylesheet default instead of keeping a stale value.\n *\n * @param themeStyles {CSSStyleDeclaration} - Target style declaration\n * @param theme {ComponentTheme | ThemeMap} - Theme object\n */\nexport const generateCSSVariables = (\n themeStyles: CSSStyleDeclaration,\n theme: ComponentTheme | ThemeMap,\n) => {\n const next = new Set<string>();\n Object.entries(theme).forEach(([key, value]) => {\n if (value !== undefined && value !== null && value !== \"\") next.add(key);\n });\n\n const stale = new Set([\n ...(appliedKeys.get(themeStyles) ?? []),\n ...themeKeys,\n ]);\n stale.forEach((key) => {\n if (!next.has(key)) themeStyles.removeProperty(`--${key}`);\n });\n\n next.forEach((key) => {\n themeStyles.setProperty(\n `--${key}`,\n String((theme as Record<string, string>)[key]),\n );\n });\n appliedKeys.set(themeStyles, next);\n};\n\n/**\n * Apply theme styles to the document root\n * @param theme {Theme | ThemeName} - Theme name or object\n * @param systemTheme {DefaultTheme} - Scheme used for \"auto\" and light/dark pairs\n */\nexport const applyThemeStyles = (\n theme: Theme | ThemeName,\n systemTheme?: DefaultTheme,\n) => {\n generateCSSVariables(\n document.documentElement.style,\n resolveTheme(theme, systemTheme),\n );\n};\n","/**\n * Server-safe theme helpers (web): cookie names, cookie parsing and the\n * no-flash init script.\n *\n * This module has no framework import and no DOM access at load time (the\n * init script only runs in the browser). It lives in `@minerva/dom` (web\n * only: cookies and `<html>` attributes) and is re-exported by the server-safe\n * `minerva-design/theme-utils` entry, so React Server Components (e.g. a\n * root layout) can read the theme cookies and inline the init script.\n *\n * Theme model (two orthogonal axes):\n * mode \"light\" | \"dark\" | \"system\" (system follows prefers-color-scheme)\n * palette \"editorial\" | \"tech\" | \"graphite\" | \"cool\" | none (Minerva's default look)\n *\n * Both are reflected on `<html>` as `data-theme` (resolved light / dark) and\n * `data-palette`, which select the palette token blocks of `style.css`.\n *\n * import { THEME_INIT_SCRIPT } from \"minerva-design/theme-utils\";\n *\n * <html suppressHydrationWarning>\n * <head>\n * <script suppressHydrationWarning dangerouslySetInnerHTML={{ __html: THEME_INIT_SCRIPT }} />\n * </head>\n * ...\n */\n\nimport {\n PALETTES,\n designAttributes,\n isPalette,\n isThemeMode,\n presetPalette,\n type DesignOptions,\n type Palette,\n type ThemeMode,\n} from \"@minerva/core\";\n\n/** Cookie storing the {@link ThemeMode}. */\nexport const THEME_COOKIE_NAME = \"theme\";\n\n/** Cookie storing the {@link Palette}. */\nexport const PALETTE_COOKIE_NAME = \"palette\";\n\n/** Cookie lifetime: one year, in seconds. */\nexport const THEME_COOKIE_MAX_AGE = 60 * 60 * 24 * 365;\n\n/** Parse a raw `theme` cookie value; invalid / missing values give `fallback`. */\nexport function parseThemeCookie(\n value: string | undefined | null,\n fallback: ThemeMode = \"system\",\n): ThemeMode {\n return isThemeMode(value) ? value : fallback;\n}\n\n/**\n * Parse a raw `palette` cookie value; invalid / missing values give `fallback`\n * (`null` = no palette, Minerva's default look).\n */\nexport function parsePaletteCookie<F extends Palette | null = null>(\n value: string | undefined | null,\n fallback: F = null as F,\n): Palette | F {\n return isPalette(value) ? value : fallback;\n}\n\n/**\n * Read one cookie from a `Cookie` header / `document.cookie` string.\n * Returns `undefined` when absent. Values are URI-decoded.\n */\nexport function readCookieValue(\n cookieHeader: string | undefined | null,\n name: string,\n): string | undefined {\n if (!cookieHeader) return undefined;\n for (const part of cookieHeader.split(\";\")) {\n const index = part.indexOf(\"=\");\n if (index === -1) continue;\n if (part.slice(0, index).trim() !== name) continue;\n const raw = part.slice(index + 1).trim();\n try {\n return decodeURIComponent(raw);\n } catch {\n return raw;\n }\n }\n return undefined;\n}\n\n/** Theme preferences parsed from a request's `Cookie` header. */\nexport interface ThemeCookies {\n theme: ThemeMode;\n palette: Palette | null;\n}\n\n/** Parse both theme cookies from a `Cookie` header (server side). */\nexport function parseThemeCookies(\n cookieHeader: string | undefined | null,\n defaults: { theme?: ThemeMode; palette?: Palette | null } = {},\n): ThemeCookies {\n return {\n theme: parseThemeCookie(\n readCookieValue(cookieHeader, THEME_COOKIE_NAME),\n defaults.theme ?? \"system\",\n ),\n palette: parsePaletteCookie(\n readCookieValue(cookieHeader, PALETTE_COOKIE_NAME),\n defaults.palette ?? null,\n ),\n };\n}\n\n/** `Set-Cookie`-style string for a theme preference (client or server). */\nexport function serializeThemeCookie(name: string, value: string): string {\n return `${name}=${encodeURIComponent(value)}; path=/; max-age=${THEME_COOKIE_MAX_AGE}; SameSite=Lax`;\n}\n\nexport interface ThemeInitScriptOptions {\n /** Mode used when the cookie is missing / invalid. @default \"system\" */\n defaultTheme?: ThemeMode;\n /**\n * Palette used when the cookie is missing / invalid and `<html>` has no\n * valid `data-palette` yet. `null` leaves `data-palette` unset (Minerva's\n * default look). @default null\n */\n defaultPalette?: Palette | null;\n /**\n * Design axes (preset / density / radius / shadow / font scale) written on\n * `<html>` as data attributes before the first paint. The preset's palette\n * is used as `defaultPalette` unless one is given.\n */\n design?: DesignOptions;\n}\n\nconst escapeRegExp = (value: string) =>\n value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\n/**\n * Build the inline, render-blocking init script. Before hydration it reads the\n * `theme` / `palette` cookies (falling back to `prefers-color-scheme` and the\n * defaults) and writes `data-theme`, `data-palette` and `color-scheme` on\n * `<html>`, so the first paint already uses the right tokens (no flash).\n */\nexport function createThemeInitScript(\n options: ThemeInitScriptOptions = {},\n): string {\n const defaultTheme = parseThemeCookie(options.defaultTheme);\n const fallbackPalette =\n options.defaultPalette === undefined\n ? presetPalette(options.design?.preset)\n : options.defaultPalette;\n const defaultPalette = isPalette(fallbackPalette) ? fallbackPalette : \"\";\n const design = options.design\n ? Object.entries(designAttributes(options.design))\n .map(([name, value]) => `d.setAttribute('${name}','${value}');`)\n .join(\"\")\n : \"\";\n const palettes = `[${PALETTES.map((p) => `'${p}'`).join(\",\")}]`;\n const themeRe = `/(?:^|; )${escapeRegExp(THEME_COOKIE_NAME)}=([^;]+)/`;\n const paletteRe = `/(?:^|; )${escapeRegExp(PALETTE_COOKIE_NAME)}=([^;]+)/`;\n return (\n `(function(){try{var d=document.documentElement,c=document.cookie,P=${palettes};` +\n `var tm=c.match(${themeRe});var t=tm?tm[1]:'${defaultTheme}';` +\n `if(t!=='light'&&t!=='dark'&&t!=='system')t='${defaultTheme}';` +\n `if(t==='system')t=window.matchMedia&&window.matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light';` +\n `d.dataset.theme=t;d.style.colorScheme=t;` +\n `var hp=d.dataset.palette;var f=P.indexOf(hp)>-1?hp:'${defaultPalette}';` +\n `var pm=c.match(${paletteRe});var p=pm?pm[1]:f;if(P.indexOf(p)<0)p=f;` +\n `if(p)d.dataset.palette=p;else delete d.dataset.palette;${design}}catch(e){}})();`\n );\n}\n\n/**\n * Default init script: cookie mode (else system), cookie palette (else the\n * `data-palette` already rendered on `<html>`, else none).\n */\nexport const THEME_INIT_SCRIPT: string =\n /* @__PURE__ */ createThemeInitScript();\n","/**\n * Content-Security-Policy support for the inline theme init script.\n *\n * A strict CSP (`script-src 'nonce-…'` or `'sha256-…'`, no\n * `'unsafe-inline'`) blocks an inline `<script>` unless it carries the\n * request's nonce or its hash is listed. Either render\n * `<script nonce={nonce}>` with the script, or list the script's hash:\n *\n * Content-Security-Policy: script-src 'self' ${THEME_INIT_SCRIPT_HASH}\n *\n * `cspHash()` computes it for a custom `createThemeInitScript(...)` output\n * (synchronous and dependency-free, so it works in every server runtime).\n */\nimport { THEME_INIT_SCRIPT } from \"./cookies\";\n\nconst K = [\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,\n 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,\n 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,\n 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,\n 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,\n 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,\n 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,\n 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,\n 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n];\n\n/** UTF-8 bytes of `text` (TextEncoder is not available in every runtime) */\nfunction utf8(text: string): number[] {\n const bytes: number[] = [];\n for (const char of text) {\n const code = char.codePointAt(0)!;\n if (code < 0x80) bytes.push(code);\n else if (code < 0x800) bytes.push(0xc0 | (code >> 6), 0x80 | (code & 63));\n else if (code < 0x10000) {\n bytes.push(\n 0xe0 | (code >> 12),\n 0x80 | ((code >> 6) & 63),\n 0x80 | (code & 63),\n );\n } else {\n bytes.push(\n 0xf0 | (code >> 18),\n 0x80 | ((code >> 12) & 63),\n 0x80 | ((code >> 6) & 63),\n 0x80 | (code & 63),\n );\n }\n }\n return bytes;\n}\n\n/** SHA-256 digest of the UTF-8 encoding of `text` */\nfunction sha256(text: string): number[] {\n const bytes = utf8(text);\n const bitLength = bytes.length * 8;\n bytes.push(0x80);\n while (bytes.length % 64 !== 56) bytes.push(0);\n const high = Math.floor(bitLength / 0x100000000);\n for (const word of [high, bitLength >>> 0]) {\n bytes.push(\n (word >>> 24) & 255,\n (word >>> 16) & 255,\n (word >>> 8) & 255,\n word & 255,\n );\n }\n const h = [\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c,\n 0x1f83d9ab, 0x5be0cd19,\n ];\n const w = new Array<number>(64);\n const rotr = (x: number, n: number) => (x >>> n) | (x << (32 - n));\n for (let offset = 0; offset < bytes.length; offset += 64) {\n for (let i = 0; i < 16; i++) {\n const j = offset + i * 4;\n w[i] =\n (bytes[j] << 24) |\n (bytes[j + 1] << 16) |\n (bytes[j + 2] << 8) |\n bytes[j + 3];\n }\n for (let i = 16; i < 64; i++) {\n const s0 = rotr(w[i - 15], 7) ^ rotr(w[i - 15], 18) ^ (w[i - 15] >>> 3);\n const s1 = rotr(w[i - 2], 17) ^ rotr(w[i - 2], 19) ^ (w[i - 2] >>> 10);\n w[i] = (w[i - 16] + s0 + w[i - 7] + s1) | 0;\n }\n let [a, b, c, d, e, f, g, hh] = h;\n for (let i = 0; i < 64; i++) {\n const s1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);\n const ch = (e & f) ^ (~e & g);\n const t1 = (hh + s1 + ch + K[i] + w[i]) | 0;\n const s0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);\n const maj = (a & b) ^ (a & c) ^ (b & c);\n const t2 = (s0 + maj) | 0;\n hh = g;\n g = f;\n f = e;\n e = (d + t1) | 0;\n d = c;\n c = b;\n b = a;\n a = (t1 + t2) | 0;\n }\n h[0] = (h[0] + a) | 0;\n h[1] = (h[1] + b) | 0;\n h[2] = (h[2] + c) | 0;\n h[3] = (h[3] + d) | 0;\n h[4] = (h[4] + e) | 0;\n h[5] = (h[5] + f) | 0;\n h[6] = (h[6] + g) | 0;\n h[7] = (h[7] + hh) | 0;\n }\n return h.flatMap((x) => [\n (x >>> 24) & 255,\n (x >>> 16) & 255,\n (x >>> 8) & 255,\n x & 255,\n ]);\n}\n\nconst BASE64 =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\nfunction base64(bytes: number[]): string {\n let out = \"\";\n for (let i = 0; i < bytes.length; i += 3) {\n const [a, b = 0, c = 0] = bytes.slice(i, i + 3);\n const n = (a << 16) | (b << 8) | c;\n out += BASE64[(n >> 18) & 63] + BASE64[(n >> 12) & 63];\n out += i + 1 < bytes.length ? BASE64[(n >> 6) & 63] : \"=\";\n out += i + 2 < bytes.length ? BASE64[n & 63] : \"=\";\n }\n return out;\n}\n\n/**\n * CSP source expression of an inline script: `'sha256-<base64 digest>'` of\n * its exact text (the content of the `<script>` element, byte for byte).\n */\nexport function cspHash(script: string): string {\n return `'sha256-${base64(sha256(script))}'`;\n}\n\n/** `cspHash(THEME_INIT_SCRIPT)`, for `script-src` of a strict CSP */\nexport const THEME_INIT_SCRIPT_HASH: string =\n /* @__PURE__ */ cspHash(THEME_INIT_SCRIPT);\n","// Applies the design axes (see `designAttributes` in @minerva/core) to a DOM\n// element. Web only: other renderers resolve the design to concrete values\n// (`resolveTokens`) instead of data attributes.\nimport {\n DESIGN_ATTRIBUTES,\n designAttributes,\n type DesignOptions,\n type ResolvedDesign,\n} from \"@minerva/core\";\n\n/**\n * Writes (or removes) the design attributes on an element. Standard values\n * are removed unless `all` is set.\n */\nexport function applyDesignAttributes(\n element: Element,\n design: DesignOptions | ResolvedDesign | null,\n { all = false }: { all?: boolean } = {},\n): void {\n const attributes = design ? designAttributes(design, { all }) : {};\n for (const name of Object.values(DESIGN_ATTRIBUTES)) {\n const value = attributes[name];\n if (value === undefined) element.removeAttribute(name);\n else element.setAttribute(name, value);\n }\n}\n","// Brand color (`primaryColor`) of the web renderers as CSS variables: the\n// token block of core's `primaryColorTokens`, serialized like tokens.css.\nimport {\n primaryColorTokens,\n tokenToCss,\n type PrimaryColorPair,\n type ResolvedThemeMode,\n type ThemeMap,\n} from \"@minerva/core\";\n\n/** Theme / palette tokens a brand color is applied over */\ntype BaseTheme = object | null | undefined;\n\n/**\n * The brand color of `mode` as theme entries (`{ \"primary-color\": ...,\n * \"primary-color-hover\": \"color-mix(...)\", ... }`), ready for\n * `generateCSSVariables` or an inline `style`. `base` is the theme or\n * palette it is applied over (keeps a palette's distinct accent).\n */\nexport function primaryColorTheme(\n pair: PrimaryColorPair,\n mode: ResolvedThemeMode,\n base?: BaseTheme,\n): ThemeMap {\n return Object.fromEntries(\n Object.entries(primaryColorTokens(pair[mode], base)).map(([key, value]) => [\n key,\n tokenToCss(value),\n ]),\n ) as ThemeMap;\n}\n\n/** Options of `primaryColorCss`. */\nexport interface PrimaryColorCssOptions {\n /**\n * Element the rules target\n * @default \":root\"\n */\n selector?: string;\n /** Theme / palette each mode is applied over */\n base?: Partial<Record<ResolvedThemeMode, BaseTheme>>;\n}\n\n/**\n * A style sheet applying a brand color before any script runs (server\n * rendering): the light values on `selector`, the dark ones when it has\n * `data-theme=\"dark\"` (set by `THEME_INIT_SCRIPT` / the root provider).\n * Colors are normalized by `resolvePrimaryColor`, so the text is safe to\n * inline in a `<style>` element.\n */\nexport function primaryColorCss(\n pair: PrimaryColorPair,\n { selector = \":root\", base }: PrimaryColorCssOptions = {},\n): string {\n const block = (mode: ResolvedThemeMode) =>\n Object.entries(primaryColorTheme(pair, mode, base?.[mode]))\n .map(([key, value]) => `--${key}:${String(value)}`)\n .join(\";\");\n return `${selector}:not([data-theme=dark]){${block(\"light\")}}${selector}[data-theme=dark]{${block(\"dark\")}}`;\n}\n"],"mappings":"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"}
|