diff --git a/docs/webui/chat.md b/docs/webui/chat.md index 522519368..9eac375a7 100644 --- a/docs/webui/chat.md +++ b/docs/webui/chat.md @@ -8,7 +8,7 @@ Chat reads the canonical memory-only generation defaults saved in Settings. Open ## Interaction and cancellation -Enter sends outside IME composition; Shift+Enter inserts a newline. New, rename, delete, system prompt, copy, and explicit edit-and-regenerate are local conversation operations. Editing asks before discarding that response and subsequent turns. Reasoning is collapsed by default; tool calls are inspectable structured text and are never executed. A response must include a finish reason, nonempty content/reasoning/tool data, and a complete SSE stream before it becomes complete. Network errors, authentication loss, navigation and Stop do not retry generation or mark a partial answer successful. +Enter and Cmd/Ctrl+Enter send outside IME composition; Shift+Enter inserts a newline. In the composer, Cmd+N on Apple platforms and Ctrl+N elsewhere start a new empty conversation, leaving Ctrl+N as the native caret-movement binding inside a macOS textarea, and nothing fires while composition is active (`isComposing` or keyCode 229). The New conversation button sits in the Chat page header; the conversation and model pickers stay below it. A new conversation is refused at the 50-conversation cap and while a request, history operation or image load is busy. New, rename, delete, system prompt, copy, and explicit edit-and-regenerate are local conversation operations. Editing asks before discarding that response and subsequent turns. Reasoning is collapsed by default; tool calls are inspectable structured text and are never executed. A response must include a finish reason, nonempty content/reasoning/tool data, and a complete SSE stream before it becomes complete. Network errors, authentication loss, navigation and Stop do not retry generation or mark a partial answer successful. Stop aborts the transport and retains cancelled partial output. A follow-up runtime observation is useful diagnostic context, not a per-request cancellation receipt. The isolated real-browser acceptance harness separately observes the server's request lease count rise and return to zero after Stop. Closing a page never unloads a shared model. diff --git a/docs/webui/design-system.md b/docs/webui/design-system.md index b3c02da67..39f91d7d4 100644 --- a/docs/webui/design-system.md +++ b/docs/webui/design-system.md @@ -49,7 +49,15 @@ All controls expose visible focus, disabled and busy states, minimum 24 px targe ## Shell and localization -`AppShell` defines the sidebar, top toolbar, content column (the shared PageLayout) and optional inspector. Primary navigation contains Models, Chat, Activity and Settings; the component gallery remains available as the direct `#gallery` artifact route and is listed in the command palette only while that route is already active. Cmd/Ctrl+K opens the command palette, `?` opens keyboard help, Escape closes the active dialog through the native dialog mechanism or the navigation drawer through its own handler, with focus back on the opener, and `[`/`]` move primary navigation only while the sidebar owns focus. Global shortcuts are suppressed inside edit controls, modal dialogs, the open navigation drawer, IME composition and Alt-key chords. Compact widths below 960 px use the shared Drawer as a left off-canvas sheet opened from the toolbar, with the page behind it inert while it is open; widening past 960 px while it is open closes it and moves focus to the desktop sidebar. No permanent mobile rail is rendered. +`AppShell` (`webui/src/design-system/shell.tsx`) defines the sidebar, top toolbar, content column (the shared PageLayout) and optional inspector. App hands it plain data (`loadedModels` as `ShellLoadedModel` records and a `connection` summary) plus callbacks, so the shell imports neither the provider nor the catalog. Primary navigation contains Models, Chat, Activity and Settings. The component gallery is a direct `#gallery` artifact route only; it is in neither the navigation nor the command palette. + +The toolbar names the models the server holds, from `loadedModels(snapshot)` in `webui/src/provider-surfaces.tsx`: entries in `ready`, `loading`, `draining` or `unloading`, ready first, then by display name. It never shows the browser's selection, which stays visible only in the Chat model picker and the Settings target. The region shows a count, up to `TOOLBAR_CHIP_LIMIT` (3) chips with the truncated name and a lifecycle StatusBadge, and a "+n" chip that opens the command palette; with nothing loaded it says "No model loaded". `AppShell.loadedModels` is `null` when the loaded models are not known, and the region then says "Loaded models unknown" instead: App passes `null` until an authenticated session holds a catalog snapshot, which covers signed out, the window before the first catalog page and the reset after a server restart, so the toolbar never claims that nothing is loaded on a server it has not read. On a desktop toolbar short of room the chips share it equally, and each gives up space in order: the name truncates down to 5rem, the badge narrows to its state dot, then the name truncates further. Below 960 px the region is a toolbar row of its own that scrolls sideways inside itself instead of wrapping: chips keep their width up to `min(14rem, 80%)` with truncated names, so the sticky toolbar stays two rows high (title, chips) however many models are loaded, and three below 320 px (title, actions, chips). A chip reached with Tab is scrolled fully into view, since Chromium leaves an element that is already partly visible where it is. The full name stays in the chip's `title` and the state in its accessible name. A chip selects the model and opens its inspector on Models, or opens Models with no inspector if the model has left the catalog; it never loads or unloads. Opening the model that is already selected dispatches no selection (`modelSelectionFor` in `provider-surfaces.tsx` computes the target), because a selection change restarts observation and clears the runtime history. Chips take their accessible name from their visible text and carry no `aria-label`. The sidebar footer reads `{mode} · {status} · v{version}`; the server instance id and the event sequence appear only inside a collapsed "Connection details" disclosure under it. + +Every route renders exactly one `PageHeader` as the first child of the shell's PageLayout, with the route's actions in its action slot and the route's stale or action error in its error slot. The adapter always makes that h1 the route's dialog focus fallback (`tabIndex=-1` and `data-dialog-focus-fallback`), so each route has exactly one fallback and `restoreModalFocus` lands on a named heading when a dialog closes after its opener is gone. Routes do not hand-roll headings, eyebrow lines or heading button rows. + +The command palette (`webui/src/command-palette.tsx`) opens with an empty query. Its Commands section lists the four routes and "New conversation", matched on the localized label or the route id, so Korean input finds them too. Its Models section lists the loaded models while the query is empty, and otherwise the catalog entries whose display name or id contains the query (`paletteModelMatches`: case-insensitive, loaded first, at most 20). Selecting a model does what a chip does; the palette has no way to load a model. + +`globalShortcuts` in `shell.tsx` is the single source for the keyboard help dialog, so the list cannot drift from the handlers: Cmd/Ctrl+K, Cmd/Ctrl+N, Cmd/Ctrl+Enter, Esc, `[`/`]` and `?`. The shell handles Cmd/Ctrl+K (palette), `?` (help) and Cmd/Ctrl+N, which opens Chat and, when Chat is available, raises `requestNewConversation()` in `features/chat/session.ts`; Chat consumes that request once on mount or on change and runs its own guarded `create()`. Escape closes the active dialog through the native dialog mechanism or the navigation drawer through its own handler, with focus back on the opener, and `[`/`]` move primary navigation only while the sidebar owns focus. Global shortcuts are suppressed inside edit controls, modal dialogs, the open navigation drawer, IME composition and Alt-key chords; the chat composer handles Cmd/Ctrl+Enter and Cmd/Ctrl+N itself outside composition. Compact widths below 960 px use the shared Drawer as a left off-canvas sheet opened from the toolbar, with the page behind it inert while it is open; widening past 960 px while it is open closes it and moves focus to the desktop sidebar. No permanent mobile rail is rendered. Below 320 px the layout holds down to 195 CSS px; see the [layout floor](ux-contract.md#visual-and-viewport-contract). The production shell consumes the shared `WebUiProvider` snapshot and actions directly: LoginView submits through `actions.login`, logout uses `actions.logout`, and connection, catalog/operation freshness, selected model and schema recovery derive from the shared authority. It maintains no second session cache. Initial browsing makes no local API call before explicit login; authenticated route browsing does not load models or call inference endpoints. Models, Chat and Activity currently expose truthful staged guidance until their feature-page issues implement the workflows. @@ -57,7 +65,7 @@ Every user-facing string has a typed key in `webui/src/i18n/catalog.ts` and a sy ## Verification -The component gallery is available at `#gallery`. `pnpm --dir webui run unit` executes the activity-stream and theme-selector node:test specs (35 tests) and 470 Vitest tests across 51 files, covering the shared client/provider, shell and theme behavior and the shared-component adapters. `pnpm --dir webui run browser` executes 88 Playwright tests, 89 with `MLXCEL_WEBUI_FONT_DIAGNOSTICS=1`: 21 layout and accessibility cases (14 gallery and 7 product-shell variants), seven further `browser.spec.ts` cases covering provider/mock-API journeys, keyboard/focus/shortcut behavior, production-selector compact reflow, contrast/reduced-motion/visibility behavior and backdrop-filter fallback, the Activity, Chat, Models and Settings route specs, the shared-component specs `ui-common-components.spec.ts` (14 cases) and `ui-common-shell.spec.ts` (12 cases), and 23 `theme.spec.ts` cases covering the pre-mount theme, live host-scheme changes, the Settings theme controls, the unchanged mlxcel baseline and the glass intensity, transparency, contrast and motion rules. The variants in `webui/tests/browser-fixtures.ts` cover 390/1024/1440 widths, all four theme ids, tinted/opaque, high contrast and CJK labels. Each of the 21 cases runs axe with all violations rejected and asserts measured geometry: document and key-panel overflow, toolbar hiding above 960 px, 44 px compact hit targets, data-table column visibility, heading hierarchy across repeated tab remounts and progress/sample row alignment. No pixel baselines are committed. A baseline is specific to one renderer, font set and platform, so keeping one per platform required a hosted capture and a manual visual review on every font, Chromium or UI change, and it bought no assertion that the geometry checks do not already make. A failing case still writes its actual page image and a trace into `webui/test-results/`, which is git-ignored and uploaded as a CI artifact; run with `--headed` to watch a variant render. The CI job still pins `fonts-dejavu-core`, `fonts-dejavu-extra` and `fonts-wqy-zenhei` on Ubuntu 24.04, because the geometry assertions measure text and the CJK drawer variant needs a Korean face to lay out at all. The opt-in `MLXCEL_WEBUI_FONT_DIAGNOSTICS=1` test reports the fonts Chromium actually resolved, rather than trusting `fc-match` alone. +The component gallery is available at `#gallery`. `pnpm --dir webui run unit` executes the activity-stream and theme-selector node:test specs (35 tests) and 538 Vitest tests across 54 files, covering the shared client/provider, shell and theme behavior and the shared-component adapters. `pnpm --dir webui run browser` executes 108 Playwright tests, 109 with `MLXCEL_WEBUI_FONT_DIAGNOSTICS=1`: 21 layout and accessibility cases (14 gallery and 7 product-shell variants), eight further `browser.spec.ts` cases covering provider/mock-API journeys, keyboard/focus/shortcut behavior (including the six-entry help list and Control+N), production-selector compact reflow, contrast/reduced-motion/visibility behavior and backdrop-filter fallback, the Activity, Chat, Models and Settings route specs, 14 `shell.spec.ts` cases (the 195 and 320 CSS px layout floor in English and Korean, the loaded-model chip and its "+n" overflow, chips still naming their models in a tight 1024 px toolbar, the compact chip row scrolling in place with the toolbar held at two rows at 400 and 700 px, and palette model search), the shared-component specs `ui-common-components.spec.ts` (14 cases) and `ui-common-shell.spec.ts` (12 cases), and 23 `theme.spec.ts` cases covering the pre-mount theme, live host-scheme changes, the Settings theme controls, the unchanged mlxcel baseline and the glass intensity, transparency, contrast and motion rules. The variants in `webui/tests/browser-fixtures.ts` cover 390/1024/1440 widths, all four theme ids, tinted/opaque, high contrast and CJK labels. Each of the 21 cases runs axe with all violations rejected and asserts measured geometry: document and key-panel overflow, toolbar hiding above 960 px, 44 px compact hit targets, data-table column visibility, heading hierarchy across repeated tab remounts and progress/sample row alignment. No pixel baselines are committed. A baseline is specific to one renderer, font set and platform, so keeping one per platform required a hosted capture and a manual visual review on every font, Chromium or UI change, and it bought no assertion that the geometry checks do not already make. A failing case still writes its actual page image and a trace into `webui/test-results/`, which is git-ignored and uploaded as a CI artifact; run with `--headed` to watch a variant render. The CI job still pins `fonts-dejavu-core`, `fonts-dejavu-extra` and `fonts-wqy-zenhei` on Ubuntu 24.04, because the geometry assertions measure text and the CJK drawer variant needs a Korean face to lay out at all. The opt-in `MLXCEL_WEBUI_FONT_DIAGNOSTICS=1` test reports the fonts Chromium actually resolved, rather than trusting `fc-match` alone. The text-scale case uses a test-only root attribute to enlarge text metrics to 200%; compact wrapping itself is implemented in production CSS, and a separate test checks it without text-scale layout selectors. These assertions cover document/key-panel overflow, full labels, visible compact focus and 44 px compact toolbar targets; they are not native browser zoom tests. Product-shell cases use explicit mock API responses, not a real backend session. diff --git a/docs/webui/ui-common.md b/docs/webui/ui-common.md index f0890bcda..1a0060b4c 100644 --- a/docs/webui/ui-common.md +++ b/docs/webui/ui-common.md @@ -23,7 +23,7 @@ The WebUI uses all 17 components that `dist/index.d.ts` exports. `grep -rn '@lab | ErrorBanner | Adapter over common ErrorState that keeps the `ErrorBanner` name and props (`title`, `body`, `action`, `tone`, `testId`). A ref bridge removes the package's `role="alert" aria-live="polite"` from its inner block, so the section stays the only live region with `role="status"` for info and `role="alert"` otherwise. It also sets `role="none"` on the package's h2 title, so no heading lands inside sections that already own one. `action` stays a ReactNode rendered by the adapter because `primaryAction {label, onClick}` cannot express the chat anchor or icon buttons. Tones map error to danger, warning to warning and info to accent. Adapter CSS makes it the compact banner and keeps the `.ds-banner` root with its high-contrast border. | | Card | Common BaseCard with `.surface-card` kept on the root. The adapter passes `role` (article, or region for a named focusable container) because BaseCard renders a role-less div, turns `hoverable` off for non-interactive cards, and restores the keyboard focus outline that BaseCard's `:focus-within` rule removes. Used by the gallery; StatCard builds on it. | | PageLayout | Common PageLayout (wide variant, 1400 px cap) as the shell's content column, keeping `.app-content`. Adapter CSS drops the package's extra 0.5 rem inline padding below 768 px because `.app-content-grid` already pads the column. | -| PageHeader | Common PageHeader for Settings, the gallery and the ProductConnectionSurface states. A ref bridge restores the title and description test ids and, with `focusFallback`, puts `tabIndex=-1` and `data-dialog-focus-fallback` on the Settings h1, so a dialog closing without a usable opener lands on a named heading. It has no eyebrow slot. Adapter CSS keeps the product's bold page-title typography. The Models, Chat and Activity headings are not migrated yet. | +| PageHeader | Common PageHeader on every route (Models, Chat, Activity, Settings, the gallery and the ProductConnectionSurface states), always the first child of the shell's PageLayout. Route actions go in `actions`; the route's stale or action error goes in `error` and `errorDetail` with `onRetry`, typed so a Retry always carries a localized `retryLabel` (the package default is English, which is also why the dismiss control is not exposed). A ref bridge restores the title, description and error-block test ids (`errorTestId` lands on `.page-header__error`, re-applied on every render because the block mounts and unmounts with `error`) and always puts `tabIndex=-1` and `data-dialog-focus-fallback` on the h1, so each route has exactly one fallback and a dialog closing without a usable opener lands on a named heading. It has no eyebrow slot. Adapter CSS keeps the product's bold page-title typography, caps each action at the column width so labels wrap, and draws the error block like the product's error banner. | | StatCard | Common StatCard for the Activity runtime tiles: a group named "label: value", with scope, observed time and reason in the hint slot. Values arrive as formatted strings. Adapter CSS undoes the package's label and value truncation, label uppercasing and hover lift. | | LoadingStatus | Decorative common Skeleton rows under one visible, localized `role="status"` in the Models table loading slot. SkeletonRow and SkeletonText are not used because each mounts one status per row named "Loading"; SkeletonCard and SkeletonChart have no matching surface. | | SmoothHeight | Common SmoothHeight around the Activity operations list. It is active only while an operation is in flight plus a 400 ms settle window, so a settled list is never height-pinned or clipped by its `overflow: hidden`. The settle window always runs the full 400 ms from the latest transition to false, so a false→true→false sequence within that window restarts it instead of releasing early. | diff --git a/docs/webui/ux-contract.md b/docs/webui/ux-contract.md index 7ab5b4963..28fe0285b 100644 --- a/docs/webui/ux-contract.md +++ b/docs/webui/ux-contract.md @@ -16,7 +16,11 @@ Minimum destructive keys: `models.delete.confirm.title`, `models.delete.confirm. ## Keyboard and accessibility -Global shortcuts: `⌘/Ctrl+K` focus command/search, `⌘/Ctrl+N` new chat, `⌘/Ctrl+Enter` send, `Esc` stop current transient interaction or close dialog, `[`/`]` move primary navigation when the sidebar has focus, `?` open keyboard help. Text inputs must be IME-safe and never send while composition is active. Focus is visible, restored after dialogs, and kept inside modals. Dialog, listbox, menu, table and toast roles follow WCAG 2.2 AA expectations with screen-reader summaries for streaming updates. +Global shortcuts, in the order the keyboard help dialog lists them from `globalShortcuts` in `webui/src/design-system/shell.tsx`: `⌘/Ctrl+K` opens the command palette, `⌘/Ctrl+N` starts a new conversation and opens Chat, `⌘/Ctrl+Enter` sends the message from the chat composer, `Esc` closes the open dialog or navigation drawer, `[`/`]` move primary navigation while the sidebar has focus, `?` opens keyboard help. None fires while typing in an edit field, inside an open dialog or the navigation drawer, during IME composition or with Alt; the chat composer handles `⌘/Ctrl+Enter` and `⌘/Ctrl+N` itself, outside composition. + +Browsers reserve `⌘/Ctrl+N` for a new window. In a stock Chrome, Safari or Firefox window the key opens a browser window and never reaches the page; the handler still calls `preventDefault` wherever the event does arrive, and headless Chromium delivers it, which `webui/tests/browser.spec.ts` checks. "New conversation" therefore stays reachable from the command palette and the Chat page header. + +Text inputs must be IME-safe and never send while composition is active. Focus is visible, restored after dialogs, and kept inside modals. Dialog, listbox, menu, table and toast roles follow WCAG 2.2 AA expectations with screen-reader summaries for streaming updates. ## Metrics, units and context labels @@ -26,6 +30,8 @@ Use IEC bytes for file/model sizes, decimal tokens/s for throughput, millisecond Use system fonts, 4 px spacing, semantic color/material/elevation/radius/motion tokens, default light/dark following the OS, explicit color-scheme override, a standard and a glass theme family, glass intensity 0–100 default 35, reduce-transparency, reduce-motion and high-contrast overrides. Glass belongs on sidebar/toolbar/popovers; tables, transcripts and forms use stable readable surfaces. Without `backdrop-filter`, use an opaque fallback. Motion is 120–180 ms and disabled under reduced motion. +Layout floor: every route holds without page-level horizontal scroll down to a 195 CSS px viewport, which is a 390 px window at 200 percent browser zoom and below the 320 CSS px that WCAG 2.2 SC 1.4.10 requires. Below 320 px the toolbar stops being sticky, keeps its title and subtitle on one truncated line each (full text in `title`), and puts its actions and the loaded-model chips on rows of their own. Single-column grid tracks use `minmax(0, 1fr)` so intrinsic widths cannot push the page wider; nothing clips overflow on `html`, `body` or the shell. `webui/tests/shell.spec.ts` pins the floor at 195×422 and, as a regression guard, 320×422, in English and Korean, over the gallery Controls, States and Data tabs, the open navigation drawer, the signed-out login and the signed-in Models, Chat, Activity and Settings routes with a loaded-model chip in the toolbar. It asserts `scrollWidth - clientWidth <= 1` on each and that the toolbar title does not overlap any toolbar control. + Minimum shared states the browser suite must exercise: Models empty, Models populated with long CJK name, model details with unsupported action, download indeterminate, load failure, Chat streaming with reasoning and tool-call panes, Activity operation history with SSE reset, Settings partial success, unauthorized, offline, and mobile off-canvas navigation. Reference viewports are 390×844, 1024×768, and 1440×900 at device scale factor 1, plus light/dark/high-contrast variants for core states. These cases assert accessibility and measured geometry rather than comparing pixels, and they use the same fixtures as route/client tests; passing against mock responses does not prove runtime acceptance. ## Shared design-system artifact (#1843) diff --git a/src/webui/assets/assets/code-highlight-B24EZUmw.js b/src/webui/assets/assets/code-highlight-Dk2RxJiZ.js similarity index 93% rename from src/webui/assets/assets/code-highlight-B24EZUmw.js rename to src/webui/assets/assets/code-highlight-Dk2RxJiZ.js index c6f6b499b..25f74113f 100644 --- a/src/webui/assets/assets/code-highlight-B24EZUmw.js +++ b/src/webui/assets/assets/code-highlight-Dk2RxJiZ.js @@ -1 +1 @@ -import{i as e,n as t,r as n}from"./index-CCGbr2W2.js";var r=e(n(),1),i=t(),a=new Set([`js`,`javascript`,`ts`,`typescript`,`json`,`py`,`python`,`rs`,`rust`,`sh`,`bash`]),o=new Set(`const let var function return if else for while class import from export default async await def with as try catch except raise fn pub use impl struct enum match mut self true false null None True False`.split(` `)),s=(0,r.memo)(function({code:e,language:t}){if(!a.has(t.toLowerCase())||e.length>32768)return(0,i.jsx)(`code`,{children:e});let n=[],r=/("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|\b[A-Za-z_]\w*\b|\b\d+(?:\.\d+)?\b)/g,s=0,c=0;for(let t of e.matchAll(r)){if(++c>4096)break;n.push(e.slice(s,t.index));let r=t[0],a=/^['"]/.test(r)?`string`:/^\d/.test(r)?`number`:o.has(r)?`keyword`:void 0;n.push(a?(0,i.jsx)(`span`,{className:`chat-code-${a}`,children:r},t.index):r),s=t.index+r.length}return n.push(e.slice(s)),(0,i.jsx)(`code`,{children:n})});export{s as default}; \ No newline at end of file +import{i as e,n as t,r as n}from"./index-CQvJAqGK.js";var r=e(n(),1),i=t(),a=new Set([`js`,`javascript`,`ts`,`typescript`,`json`,`py`,`python`,`rs`,`rust`,`sh`,`bash`]),o=new Set(`const let var function return if else for while class import from export default async await def with as try catch except raise fn pub use impl struct enum match mut self true false null None True False`.split(` `)),s=(0,r.memo)(function({code:e,language:t}){if(!a.has(t.toLowerCase())||e.length>32768)return(0,i.jsx)(`code`,{children:e});let n=[],r=/("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|\b[A-Za-z_]\w*\b|\b\d+(?:\.\d+)?\b)/g,s=0,c=0;for(let t of e.matchAll(r)){if(++c>4096)break;n.push(e.slice(s,t.index));let r=t[0],a=/^['"]/.test(r)?`string`:/^\d/.test(r)?`number`:o.has(r)?`keyword`:void 0;n.push(a?(0,i.jsx)(`span`,{className:`chat-code-${a}`,children:r},t.index):r),s=t.index+r.length}return n.push(e.slice(s)),(0,i.jsx)(`code`,{children:n})});export{s as default}; \ No newline at end of file diff --git a/src/webui/assets/assets/history-B_cN6LK7.js b/src/webui/assets/assets/history-BBsc_X23.js similarity index 94% rename from src/webui/assets/assets/history-B_cN6LK7.js rename to src/webui/assets/assets/history-BBsc_X23.js index f6e44dd48..07aae8d11 100644 --- a/src/webui/assets/assets/history-B_cN6LK7.js +++ b/src/webui/assets/assets/history-BBsc_X23.js @@ -1 +1 @@ -import{n as e,r as t,t as n}from"./index-CCGbr2W2.js";t();var r=e();function i({samples:e,locale:t}){let i=e.at(-1)?.receivedAt??0,a=e.flatMap(e=>{let t=e.runtime.measurements.active_requests?.value;return t==null?[]:[{time:e.receivedAt,value:t}]}),o=Math.max(1,...a.map(e=>e.value));return(0,r.jsxs)(`section`,{children:[(0,r.jsx)(`h3`,{children:n(t,`activity.history.show`)}),(0,r.jsx)(`p`,{children:n(t,`activity.history.note`)}),a.length===0?(0,r.jsx)(`p`,{children:n(t,`activity.unavailable`)}):(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(`svg`,{className:`activity-chart`,viewBox:`0 0 600 180`,role:`img`,"aria-label":n(t,`activity.chart.label`),children:[(0,r.jsx)(`title`,{children:n(t,`activity.chart.title`)}),a.map(e=>(0,r.jsx)(`circle`,{cx:5+(e.time-i+3e5)/3e5*590,cy:170-e.value/o*160,r:`3`},e.time))]}),(0,r.jsxs)(`details`,{children:[(0,r.jsx)(`summary`,{children:n(t,`activity.details`)}),(0,r.jsx)(`ol`,{children:a.map(e=>(0,r.jsxs)(`li`,{children:[(0,r.jsx)(`time`,{children:new Date(e.time).toLocaleTimeString(t)}),`: `,n(t,`activity.chart.point`,{value:String(e.value)})]},e.time))})]})]})]})}export{i as default}; \ No newline at end of file +import{n as e,r as t,t as n}from"./index-CQvJAqGK.js";t();var r=e();function i({samples:e,locale:t}){let i=e.at(-1)?.receivedAt??0,a=e.flatMap(e=>{let t=e.runtime.measurements.active_requests?.value;return t==null?[]:[{time:e.receivedAt,value:t}]}),o=Math.max(1,...a.map(e=>e.value));return(0,r.jsxs)(`section`,{children:[(0,r.jsx)(`h3`,{children:n(t,`activity.history.show`)}),(0,r.jsx)(`p`,{children:n(t,`activity.history.note`)}),a.length===0?(0,r.jsx)(`p`,{children:n(t,`activity.unavailable`)}):(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(`svg`,{className:`activity-chart`,viewBox:`0 0 600 180`,role:`img`,"aria-label":n(t,`activity.chart.label`),children:[(0,r.jsx)(`title`,{children:n(t,`activity.chart.title`)}),a.map(e=>(0,r.jsx)(`circle`,{cx:5+(e.time-i+3e5)/3e5*590,cy:170-e.value/o*160,r:`3`},e.time))]}),(0,r.jsxs)(`details`,{children:[(0,r.jsx)(`summary`,{children:n(t,`activity.details`)}),(0,r.jsx)(`ol`,{children:a.map(e=>(0,r.jsxs)(`li`,{children:[(0,r.jsx)(`time`,{children:new Date(e.time).toLocaleTimeString(t)}),`: `,n(t,`activity.chart.point`,{value:String(e.value)})]},e.time))})]})]})]})}export{i as default}; \ No newline at end of file diff --git a/src/webui/assets/assets/index-CCGbr2W2.js b/src/webui/assets/assets/index-CCGbr2W2.js deleted file mode 100644 index 22729f08c..000000000 --- a/src/webui/assets/assets/index-CCGbr2W2.js +++ /dev/null @@ -1,3741 +0,0 @@ -var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),s=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;li[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},c=(n,r,o)=>(o=n==null?{}:e(i(n)),s(r||!n||!n.__esModule||!a.call(n,`default`)?t(o,`default`,{value:n,enumerable:!0}):o,n)),l=o((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.portal`),r=Symbol.for(`react.fragment`),i=Symbol.for(`react.strict_mode`),a=Symbol.for(`react.profiler`),o=Symbol.for(`react.consumer`),s=Symbol.for(`react.context`),c=Symbol.for(`react.forward_ref`),l=Symbol.for(`react.suspense`),u=Symbol.for(`react.memo`),d=Symbol.for(`react.lazy`),f=Symbol.for(`react.activity`),p=Symbol.for(`react.view_transition`),m=Symbol.iterator;function h(e){return typeof e!=`object`||!e?null:(e=m&&e[m]||e[`@@iterator`],typeof e==`function`?e:null)}var g={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},_=Object.assign,v={};function y(e,t,n){this.props=e,this.context=t,this.refs=v,this.updater=n||g}y.prototype.isReactComponent={},y.prototype.setState=function(e,t){if(typeof e!=`object`&&typeof e!=`function`&&e!=null)throw Error(`takes an object of state variables to update or a function which returns an object of state variables.`);this.updater.enqueueSetState(this,e,t,`setState`)},y.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,`forceUpdate`)};function b(){}b.prototype=y.prototype;function x(e,t,n){this.props=e,this.context=t,this.refs=v,this.updater=n||g}var S=x.prototype=new b;S.constructor=x,_(S,y.prototype),S.isPureReactComponent=!0;var C=Array.isArray;function w(){}var T={H:null,A:null,T:null,S:null},E=Object.prototype.hasOwnProperty;function D(e,n,r){var i=r.ref;return{$$typeof:t,type:e,key:n,ref:i===void 0?null:i,props:r}}function O(e,t){return D(e.type,t,e.props)}function k(e){return typeof e==`object`&&!!e&&e.$$typeof===t}function ee(e){var t={"=":`=0`,":":`=2`};return`$`+e.replace(/[=:]/g,function(e){return t[e]})}var A=/\/+/g;function te(e,t){return typeof e==`object`&&e&&e.key!=null?ee(``+e.key):t.toString(36)}function ne(e){switch(e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason;default:switch(typeof e.status==`string`?e.then(w,w):(e.status=`pending`,e.then(function(t){e.status===`pending`&&(e.status=`fulfilled`,e.value=t)},function(t){e.status===`pending`&&(e.status=`rejected`,e.reason=t)})),e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason}}throw e}function j(e,r,i,a,o){var s=typeof e;(s===`undefined`||s===`boolean`)&&(e=null);var c=!1;if(e===null)c=!0;else switch(s){case`bigint`:case`string`:case`number`:c=!0;break;case`object`:switch(e.$$typeof){case t:case n:c=!0;break;case d:return c=e._init,j(c(e._payload),r,i,a,o)}}if(c)return o=o(e),c=a===``?`.`+te(e,0):a,C(o)?(i=``,c!=null&&(i=c.replace(A,`$&/`)+`/`),j(o,r,i,``,function(e){return e})):o!=null&&(k(o)&&(o=O(o,i+(o.key==null||e&&e.key===o.key?``:(``+o.key).replace(A,`$&/`)+`/`)+c)),r.push(o)),1;c=0;var l=a===``?`.`:a+`:`;if(C(e))for(var u=0;u{t.exports=l()})),d=o((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0>>1,a=e[r];if(0>>1;ri(c,n))li(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(li(u,n))e[r]=u,e[l]=n,r=l;else break a}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return n===0?e.id-t.id:n}if(e.unstable_now=void 0,typeof performance==`object`&&typeof performance.now==`function`){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,s=o.now();e.unstable_now=function(){return o.now()-s}}var c=[],l=[],u=1,d=null,f=3,p=!1,m=!1,h=!1,g=!1,_=typeof setTimeout==`function`?setTimeout:null,v=typeof clearTimeout==`function`?clearTimeout:null,y=typeof setImmediate<`u`?setImmediate:null;function b(e){for(var i=n(l);i!==null;){if(i.callback===null)r(l);else if(i.startTime<=e)r(l),i.sortIndex=i.expirationTime,t(c,i);else break;i=n(l)}}function x(e){if(h=!1,b(e),!m){if(n(c)!==null)m=!0,S||(S=!0,O());else{var t=n(l);t!==null&&A(x,t.startTime-e)}}}var S=!1,C=-1,w=5,T=-1;function E(){return g?!0:!(e.unstable_now()-Tt&&E());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=t);if(t=e.unstable_now(),typeof s==`function`){d.callback=s,b(t),i=!0;break b}d===n(c)&&r(c),b(t)}else r(c);d=n(c)}if(d!==null)i=!0;else{var u=n(l);u!==null&&A(x,u.startTime-t),i=!1}}break a}finally{d=null,f=a,p=!1}i=void 0}}finally{i?O():S=!1}}}var O;if(typeof y==`function`)O=function(){y(D)};else if(typeof MessageChannel<`u`){var k=new MessageChannel,ee=k.port2;k.port1.onmessage=D,O=function(){ee.postMessage(null)}}else O=function(){_(D,0)};function A(t,n){C=_(function(){t(e.unstable_now())},n)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_forceFrameRate=function(e){0>e||125o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(v(C),C=-1):h=!0,A(x,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,S||(S=!0,O()))),r},e.unstable_shouldYield=E,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),f=o(((e,t)=>{t.exports=d()})),p=o((e=>{var t=u();function n(e){var t=`https://react.dev/errors/`+e;if(1{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=p()})),h=o((e=>{var t=f(),n=u(),r=m();function i(e){var t=`https://react.dev/errors/`+e;if(1_e||(e.current=ge[_e],ge[_e]=null,_e--)}function R(e,t){_e++,ge[_e]=e.current,e.current=t}var be=ve(null),xe=ve(null),Se=ve(null),Ce=ve(null);function we(e,t){switch(R(Se,t),R(xe,e),R(be,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?up(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=up(t),e=dp(t,e);else switch(e){case`svg`:e=1;break;case`math`:e=2;break;default:e=0}}ye(be),R(be,e)}function Te(){ye(be),ye(xe),ye(Se)}function Ee(e){var t=e.memoizedState;t!==null&&(sh._currentValue=t.memoizedState,R(Ce,e)),t=be.current;var n=dp(t,e.type);t!==n&&(R(xe,e),R(be,n))}function De(e){xe.current===e&&(ye(be),ye(xe)),Ce.current===e&&(ye(Ce),sh._currentValue=he)}var Oe,ke;function z(e){if(Oe===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);Oe=t&&t[1]||``,ke=-1)`:-1i||c[r]!==l[i]){var u=` -`+c[r].replace(` at new `,` at `);return e.displayName&&u.includes(``)&&(u=u.replace(``,e.displayName)),u}while(1<=r&&0<=i);break}}}finally{B=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:``)?z(n):``}function je(e,t){switch(e.tag){case 26:case 27:case 5:return z(e.type);case 16:return z(`Lazy`);case 13:return e.child!==t&&t!==null?z(`Suspense Fallback`):z(`Suspense`);case 19:return z(`SuspenseList`);case 0:case 15:return Ae(e.type,!1);case 11:return Ae(e.type.render,!1);case 1:return Ae(e.type,!0);case 31:return z(`Activity`);case 30:return z(`ViewTransition`);default:return``}}function Me(e){try{var t=``,n=null;do t+=je(e,n),n=e,e=e.return;while(e);return t}catch(e){return` -Error generating stack: `+e.message+` -`+e.stack}}var Ne=Object.prototype.hasOwnProperty,Pe=t.unstable_scheduleCallback,Fe=t.unstable_cancelCallback,Ie=t.unstable_shouldYield,Le=t.unstable_requestPaint,Re=t.unstable_now,ze=t.unstable_getCurrentPriorityLevel,Be=t.unstable_ImmediatePriority,Ve=t.unstable_UserBlockingPriority,He=t.unstable_NormalPriority,Ue=t.unstable_LowPriority,We=t.unstable_IdlePriority,Ge=t.log,Ke=t.unstable_setDisableYieldValue,qe=null,Je=null;function Ye(e){if(typeof Ge==`function`&&Ke(e),Je&&typeof Je.setStrictMode==`function`)try{Je.setStrictMode(qe,e)}catch{}}var Xe=Math.clz32?Math.clz32:$e,Ze=Math.log,Qe=Math.LN2;function $e(e){return e>>>=0,e===0?32:31-(Ze(e)/Qe|0)|0}var et=256,tt=262144,nt=4194304;function rt(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&-e;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function it(e,t,n){var r=e.pendingLanes;if(r===0)return 0;var i=0,a=e.suspendedLanes,o=e.pingedLanes;e=e.warmLanes;var s=r&134217727;return s===0?(s=r&~a,s===0?o===0?n||(n=r&~e,n!==0&&(i=rt(n))):i=rt(o):i=rt(s)):(r=s&~a,r===0?(o&=s,o===0?n||(n=s&~e,n!==0&&(i=rt(n))):i=rt(o)):i=rt(r)),i===0?0:t!==0&&t!==i&&(t&a)===0&&(a=i&-i,n=t&-t,a>=n||a===32&&n&4194048)?t:i}function at(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function ot(e,t){t&8&&(t|=t&32);var n=e.entangledLanes;if(n!==0)for(e=e.entanglements,n&=t;0n;n++)t.push(e);return t}function ut(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function dt(e,t,n,r,i,a){var o=e.pendingLanes;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=n,e.entangledLanes&=n,e.errorRecoveryDisabledLanes&=n,e.shellSuspendCounter=0;var s=e.entanglements,c=e.expirationTimes,l=e.hiddenUpdates;for(n=o&~n;0`u`||window.document===void 0||window.document.createElement===void 0),Tn=!1;if(wn)try{var En={};Object.defineProperty(En,"passive",{get:function(){Tn=!0}}),window.addEventListener(`test`,En,En),window.removeEventListener(`test`,En,En)}catch{Tn=!1}var Dn=null,On=null,kn=null;function An(){if(kn)return kn;var e,t=On,n=t.length,r,i=`value`in Dn?Dn.value:Dn.textContent,a=i.length;for(e=0;e=lr),fr=` `,pr=!1;function mr(e,t){switch(e){case`keyup`:return sr.indexOf(t.keyCode)!==-1;case`keydown`:return t.keyCode!==229;case`keypress`:case`mousedown`:case`focusout`:return!0;default:return!1}}function hr(e){return e=e.detail,typeof e==`object`&&`data`in e?e.data:null}var gr=!1;function _r(e,t){switch(e){case`compositionend`:return hr(t);case`keypress`:return t.which===32?(pr=!0,fr):null;case`textInput`:return e=t.data,e===fr&&pr?null:e;default:return null}}function vr(e,t){if(gr)return e===`compositionend`||!cr&&mr(e,t)?(e=An(),kn=On=Dn=null,gr=!1,e):null;switch(e){case`paste`:return null;case`keypress`:if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:n,offset:t-e};e=r}a:{for(;n;){if(n.nextSibling){n=n.nextSibling;break a}n=n.parentNode}n=void 0}n=Vr(n)}}function Ur(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Ur(e,t.parentNode):`contains`in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function Wr(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=Br(e.document);t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href==`string`}catch{n=!1}if(n)e=t.contentWindow;else break;t=Br(e.document)}return t}function Gr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t===`input`&&(e.type===`text`||e.type===`search`||e.type===`tel`||e.type===`url`||e.type===`password`)||t===`textarea`||e.contentEditable===`true`)}var Kr=wn&&`documentMode`in document&&11>=document.documentMode,qr=null,Jr=null,Yr=null,Xr=!1;function Zr(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;Xr||qr==null||qr!==Br(r)||(r=qr,`selectionStart`in r&&Gr(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),Yr&&zr(Yr,r)||(Yr=r,r=Jf(Jr,`onSelect`),0>=o,i-=o,qi=1<<32-Xe(t)+i|n<h?(g=d,d=null):g=d.sibling;var _=p(i,d,s[h],c);if(_===null){d===null&&(d=g);break}e&&d&&_.alternate===null&&t(i,d),a=o(_,a,h),u===null?l=_:u.sibling=_,u=_,d=g}if(h===s.length)return n(i,d),U&&Yi(i,h),l;if(d===null){for(;hg?(_=h,h=null):_=h.sibling;var y=p(a,h,v.value,l);if(y===null){h===null&&(h=_);break}e&&h&&y.alternate===null&&t(a,h),s=o(y,s,g),d===null?u=y:d.sibling=y,d=y,h=_}if(v.done)return n(a,h),U&&Yi(a,g),u;if(h===null){for(;!v.done;g++,v=c.next())v=f(a,v.value,l),v!==null&&(s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return U&&Yi(a,g),u}for(h=r(h);!v.done;g++,v=c.next())v=m(h,a,g,v.value,l),v!==null&&(e&&(_=v.alternate,_!==null&&h.delete(_.key===null?g:_.key)),s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return e&&h.forEach(function(e){return t(a,e)}),U&&Yi(a,g),u}function _(e,r,o,c){if(typeof o==`object`&&o&&o.type===A&&o.key===null&&o.props.ref===void 0&&(o=o.props.children),typeof o==`object`&&o){switch(o.$$typeof){case k:a:{for(var l=o.key;r!==null;){if(r.key===l){if(l=o.type,l===A){if(r.tag===7){n(e,r.sibling),c=a(r,o.props.children),ao(c,o),c.return=e,e=c;break a}}else if(r.elementType===l||typeof l==`object`&&l&&l.$$typeof===oe&&Qa(l)===r.type){n(e,r.sibling),c=a(r,o.props),ao(c,o),c.return=e,e=c;break a}n(e,r);break}t(e,r),r=r.sibling}o.type===A?(c=Pi(o.props.children,e.mode,c,o.key),ao(c,o),c.return=e,e=c):(c=Ni(o.type,o.key,o.props,null,e.mode,c),ao(c,o),c.return=e,e=c)}return s(e);case ee:a:{for(l=o.key;r!==null;){if(r.key===l){if(r.tag===4&&r.stateNode.containerInfo===o.containerInfo&&r.stateNode.implementation===o.implementation){n(e,r.sibling),c=a(r,o.children||[]),c.return=e,e=c;break a}n(e,r);break}t(e,r),r=r.sibling}c=Li(o,e.mode,c),c.return=e,e=c}return s(e);case oe:return o=Qa(o),_(e,r,o,c)}if(me(o))return h(e,r,o,c);if(de(o)){if(l=de(o),typeof l!=`function`)throw Error(i(150));return o=l.call(o),g(e,r,o,c)}if(typeof o.then==`function`)return _(e,r,io(o),c);if(o.$$typeof===M)return _(e,r,Ca(e,o),c);oo(e,o)}return typeof o==`string`&&o!==``||typeof o==`number`||typeof o==`bigint`?(o=``+o,r!==null&&r.tag===6?(n(e,r.sibling),c=a(r,o),c.return=e,e=c):(n(e,r),c=Fi(o,e.mode,c),c.return=e,e=c),s(e)):n(e,r)}return function(e,t,n,r){try{ro=0;var i=_(e,t,n,r);return no=null,i}catch(t){if(t===Ka||t===Ja)throw t;var a=ki(29,t,null,e.mode);return a.lanes=r,a.return=e,a}}}var co=so(!0),lo=so(!1),uo=!1;function fo(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function po(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function mo(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function ho(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,q&2){var i=r.pending;return i===null?t.next=t:(t.next=i.next,i.next=t),r.pending=t,t=Ei(e),Ti(e,null,n),t}return Si(e,r,t,n),Ei(e)}function go(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,n&4194048)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,pt(e,n)}}function _o(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var i=null,a=null;if(n=n.firstBaseUpdate,n!==null){do{var o={lane:n.lane,tag:n.tag,payload:n.payload,callback:null,next:null};a===null?i=a=o:a=a.next=o,n=n.next}while(n!==null);a===null?i=a=t:a=a.next=t}else i=a=t;n={baseState:r.baseState,firstBaseUpdate:i,lastBaseUpdate:a,shared:r.shared,callbacks:r.callbacks},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}var vo=!1;function yo(){if(vo){var e=La;if(e!==null)throw e}}function bo(e,t,n,r){vo=!1;var i=e.updateQueue;uo=!1;var a=i.firstBaseUpdate,o=i.lastBaseUpdate,s=i.shared.pending;if(s!==null){i.shared.pending=null;var c=s,l=c.next;c.next=null,o===null?a=l:o.next=l,o=c;var u=e.alternate;u!==null&&(u=u.updateQueue,s=u.lastBaseUpdate,s!==o&&(s===null?u.firstBaseUpdate=l:s.next=l,u.lastBaseUpdate=c))}if(a!==null){var d=i.baseState;o=0,u=l=c=null,s=a;do{var f=s.lane&-536870913,p=f!==s.lane;if(p?(Y&f)===f:(r&f)===f){f!==0&&f===Ia&&(vo=!0),u!==null&&(u=u.next={lane:0,tag:s.tag,payload:s.payload,callback:null,next:null});a:{var m=e,h=s;f=t;var g=n;switch(h.tag){case 1:if(m=h.payload,typeof m==`function`){d=m.call(g,d,f);break a}d=m;break a;case 3:m.flags=m.flags&-65537|128;case 0:if(m=h.payload,f=typeof m==`function`?m.call(g,d,f):m,f==null)break a;d=D({},d,f);break a;case 2:uo=!0}}f=s.callback,f!==null&&(e.flags|=64,p&&(e.flags|=8192),p=i.callbacks,p===null?i.callbacks=[f]:p.push(f))}else p={lane:f,tag:s.tag,payload:s.payload,callback:s.callback,next:null},u===null?(l=u=p,c=d):u=u.next=p,o|=f;if(s=s.next,s===null){if(s=i.shared.pending,s===null)break;p=s,s=p.next,p.next=null,i.lastBaseUpdate=p,i.shared.pending=null}}while(1);u===null&&(c=d),i.baseState=c,i.firstBaseUpdate=l,i.lastBaseUpdate=u,a===null&&(i.shared.lanes=0),od|=o,e.lanes=o,e.memoizedState=d}}function xo(e,t){if(typeof e!=`function`)throw Error(i(191,e));e.call(t)}function So(e,t){var n=e.callbacks;if(n!==null)for(e.callbacks=null,e=0;ea?a:8;var o=I.T,s={};s.types=o===null?null:o.types,I.T=s,cc(e,!1,t,n);try{var c=i(),l=I.S;l!==null&&l(s,c),typeof c==`object`&&c&&typeof c.then==`function`?sc(e,t,Ba(c,r),jd(e)):sc(e,t,r,jd(e))}catch(n){sc(e,t,{then:function(){},status:`rejected`,reason:n},jd())}finally{L.p=a,o!==null&&s.types!==null&&(o.types=s.types),I.T=o}}function Zs(){}function Qs(e,t,n,r){if(e.tag!==5)throw Error(i(476));var a=$s(e).queue;Xs(e,a,t,he,n===null?Zs:function(){return ec(e),n(r)})}function $s(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:he,baseState:he,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:ls,lastRenderedState:he},next:null};var n={};return t.next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:ls,lastRenderedState:n},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function ec(e){var t=$s(e);t.next===null&&(t=e.alternate.memoizedState),sc(e,t.next.queue,{},jd())}function tc(){return Sa(sh)}function nc(){return is().memoizedState}function rc(){return is().memoizedState}function ic(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var n=jd();e=mo(n);var r=ho(t,e,n);r!==null&&(Pd(r,t,n),go(r,t,n)),t={cache:ka()},e.payload=t;return}t=t.return}}function ac(e,t,n){var r=jd();n={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null},lc(e)?uc(t,n):(n=Ci(e,t,n,r),n!==null&&(Pd(n,e,r),dc(n,t,r)))}function oc(e,t,n){sc(e,t,n,jd())}function sc(e,t,n,r){var i={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null};if(lc(e))uc(t,i);else{var a=e.alternate;if(e.lanes===0&&(a===null||a.lanes===0)&&(a=t.lastRenderedReducer,a!==null))try{var o=t.lastRenderedState,s=a(o,n);if(i.hasEagerState=!0,i.eagerState=s,Rr(s,o))return Si(e,t,i,0),$u===null&&xi(),!1}catch{}if(n=Ci(e,t,i,r),n!==null)return Pd(n,e,r),dc(n,t,r),!0}return!1}function cc(e,t,n,r){if(r={lane:2,revertLane:Pf(),gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null},lc(e)){if(t)throw Error(i(479))}else t=Ci(e,n,r,2),t!==null&&Pd(t,e,2)}function lc(e){var t=e.alternate;return e===W||t!==null&&t===W}function uc(e,t){Ho=Vo=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function dc(e,t,n){if(n&4194048){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,pt(e,n)}}var fc={readContext:Sa,use:ss,useCallback:Jo,useContext:Jo,useEffect:Jo,useImperativeHandle:Jo,useLayoutEffect:Jo,useInsertionEffect:Jo,useMemo:Jo,useReducer:Jo,useRef:Jo,useState:Jo,useDebugValue:Jo,useDeferredValue:Jo,useTransition:Jo,useSyncExternalStore:Jo,useId:Jo,useHostTransitionStatus:Jo,useFormState:Jo,useActionState:Jo,useOptimistic:Jo,useMemoCache:Jo,useCacheRefresh:Jo,useEffectEvent:Jo},pc={readContext:Sa,use:ss,useCallback:function(e,t){return rs().memoizedState=[e,t===void 0?null:t],e},useContext:Sa,useEffect:Ls,useImperativeHandle:function(e,t,n){n=n==null?null:n.concat([e]),Fs(4194308,4,Us.bind(null,t,e),n)},useLayoutEffect:function(e,t){return Fs(4194308,4,e,t)},useInsertionEffect:function(e,t){Fs(4,2,e,t)},useMemo:function(e,t){var n=rs();t=t===void 0?null:t;var r=e();if(Uo){Ye(!0);try{e()}finally{Ye(!1)}}return n.memoizedState=[r,t],r},useReducer:function(e,t,n){var r=rs();if(n!==void 0){var i=n(t);if(Uo){Ye(!0);try{n(t)}finally{Ye(!1)}}}else i=t;return r.memoizedState=r.baseState=i,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:i},r.queue=e,e=e.dispatch=ac.bind(null,W,e),[r.memoizedState,e]},useRef:function(e){var t=rs();return e={current:e},t.memoizedState=e},useState:function(e){e=ys(e);var t=e.queue,n=oc.bind(null,W,t);return t.dispatch=n,[e.memoizedState,n]},useDebugValue:Gs,useDeferredValue:function(e,t){return Js(rs(),e,t)},useTransition:function(){var e=ys(!1);return e=Xs.bind(null,W,e.queue,!0,!1),rs().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var r=W,a=rs();if(U){if(n===void 0)throw Error(i(407));n=n()}else{if(n=t(),$u===null)throw Error(i(349));Y&127||ms(r,t,n)}a.memoizedState=n;var o={value:n,getSnapshot:t};return a.queue=o,Ls(gs.bind(null,r,o,e),[e]),r.flags|=2048,Ns(9,{destroy:void 0},hs.bind(null,r,o,n,t),null),n},useId:function(){var e=rs(),t=$u.identifierPrefix;if(U){var n=Ji,r=qi;n=(r&~(1<<32-Xe(r)-1)).toString(32)+n,t=`_`+t+`R_`+n,n=Wo++,0<\/script>`,o=o.removeChild(o.firstChild);break;case`select`:o=typeof r.is==`string`?s.createElement(`select`,{is:r.is}):s.createElement(`select`),r.multiple?o.multiple=!0:r.size&&(o.size=r.size);break;default:o=typeof r.is==`string`?s.createElement(a,{is:r.is}):s.createElement(a)}}o[bt]=t,o[xt]=r;a:for(s=t.child;s!==null;){if(s.tag===5||s.tag===6)o.appendChild(s.stateNode);else if(s.tag!==4&&s.tag!==27&&s.child!==null){s.child.return=s,s=s.child;continue}if(s===t)break a;for(;s.sibling===null;){if(s.return===null||s.return===t)break a;s=s.return}s.sibling.return=s.return,s=s.sibling}t.stateNode=o;a:switch(np(o,a,r),a){case`button`:case`input`:case`select`:case`textarea`:r=!!r.autoFocus;break a;case`img`:r=!0;break a;default:r=!1}r&&dl(t)}}return gl(t),t.subtreeFlags&=-33554433,fl(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,n),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==r&&dl(t);else{if(typeof r!=`string`&&t.stateNode===null)throw Error(i(166));if(e=Se.current,ca(t)){if(e=t.stateNode,n=t.memoizedProps,r=null,a=ea,a!==null)switch(a.tag){case 27:case 5:r=a.memoizedProps}e[bt]=t,e=!!(e.nodeValue===n||r!==null&&!0===r.suppressHydrationWarning||ep(e.nodeValue,n)),e||aa(t,!0)}else e=lp(e).createTextNode(r),e[bt]=t,t.stateNode=e}return gl(t),null;case 31:if(n=t.memoizedState,e===null||e.memoizedState!==null){if(r=ca(t),n!==null){if(e===null){if(!r)throw Error(i(318));if(e=t.memoizedState,e=e===null?null:e.dehydrated,!e)throw Error(i(557));e[bt]=t}else la(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;gl(t),e=!1}else n=ua(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),e=!0;if(!e)return t.flags&256?(Po(t),t):(Po(t),null);if(t.flags&128)throw Error(i(558))}return gl(t),null;case 13:if(r=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(a=ca(t),r!==null&&r.dehydrated!==null){if(e===null){if(!a)throw Error(i(318));if(a=t.memoizedState,a=a===null?null:a.dehydrated,!a)throw Error(i(317));a[bt]=t}else la(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;gl(t),a=!1}else a=ua(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=a),a=!0;if(!a)return t.flags&256?(Po(t),t):(Po(t),null)}return Po(t),t.flags&128?(t.lanes=n,t):(n=r!==null,e=e!==null&&e.memoizedState!==null,n&&(r=t.child,a=null,r.alternate!==null&&r.alternate.memoizedState!==null&&r.alternate.memoizedState.cachePool!==null&&(a=r.alternate.memoizedState.cachePool.pool),o=null,r.memoizedState!==null&&r.memoizedState.cachePool!==null&&(o=r.memoizedState.cachePool.pool),o!==a&&(r.flags|=2048)),n!==e&&n&&(t.child.flags|=8192),ml(t,t.updateQueue),gl(t),null);case 4:return Te(),e===null&&Wf(t.stateNode.containerInfo),t.flags|=67108864,gl(t),null;case 10:return ga(t.type),gl(t),null;case 19:if(Lo(t),r=t.memoizedState,r===null)return gl(t),null;if(a=!!(t.flags&128),o=r.rendering,o===null){if(a)hl(r,!1);else{if(ad!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(o=Ro(e),o!==null){for(t.flags|=128,hl(r,!1),e=o.updateQueue,t.updateQueue=e,ml(t,e),t.subtreeFlags=0,e=n,n=t.child;n!==null;)Mi(n,e),n=n.sibling;return Io(t,Fo.current&1|2),U&&Yi(t,r.treeForkCount),t.child}e=e.sibling}r.tail!==null&&Re()>gd&&(t.flags|=128,a=!0,hl(r,!1),t.lanes=4194304)}}else{if(!a){if(e=Ro(o),e!==null){if(t.flags|=128,a=!0,e=e.updateQueue,t.updateQueue=e,ml(t,e),hl(r,!0),r.tail===null&&r.tailMode!==`collapsed`&&r.tailMode!==`visible`&&!o.alternate&&!U)return gl(t),null}else 2*Re()-r.renderingStartTime>gd&&n!==536870912&&(t.flags|=128,a=!0,hl(r,!1),t.lanes=4194304)}r.isBackwards?(o.sibling=t.child,t.child=o):(e=r.last,e===null?t.child=o:e.sibling=o,r.last=o)}if(r.tail!==null){e=r.tail;a:{for(n=e;n!==null;){if(n.alternate!==null){n=!1;break a}n=n.sibling}n=!0}return r.rendering=e,r.tail=e.sibling,r.renderingStartTime=Re(),e.sibling=null,o=Fo.current,o=a?o&1|2:o&1,r.tailMode===`visible`||r.tailMode===`collapsed`||!n||U?Io(t,o):(n=o,R(Oo,t),R(Fo,n),ko===null&&(ko=t)),U&&Yi(t,r.treeForkCount),e}return gl(t),null;case 22:case 23:return Po(t),Do(),r=t.memoizedState!==null,e===null?r&&(t.flags|=8192):e.memoizedState!==null!==r&&(t.flags|=8192),r?n&536870912&&!(t.flags&128)&&(gl(t),t.subtreeFlags&6&&(t.flags|=8192)):gl(t),n=t.updateQueue,n!==null&&ml(t,n.retryQueue),n=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(n=e.memoizedState.cachePool.pool),r=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(r=t.memoizedState.cachePool.pool),r!==n&&(t.flags|=2048),e!==null&&ye(Ha),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),ga(Oa),gl(t),null;case 25:return null;case 30:return t.flags|=33554432,gl(t),null}throw Error(i(156,t.tag))}function vl(e,t){switch(Qi(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return ga(Oa),Te(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return De(t),null;case 31:if(t.memoizedState!==null){if(Po(t),t.alternate===null)throw Error(i(340));la()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(Po(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(i(340));la()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return Lo(t),e=t.flags,e&65536?(t.flags=e&-65537|128,e=t.memoizedState,e!==null&&(e.rendering=null,e.tail=null),t.flags|=4,t):null;case 4:return Te(),null;case 10:return ga(t.type),null;case 22:case 23:return Po(t),Do(),e!==null&&ye(Ha),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return ga(Oa),null;case 25:return null;default:return null}}function yl(e,t){switch(Qi(t),t.tag){case 3:ga(Oa),Te();break;case 26:case 27:case 5:De(t);break;case 4:Te();break;case 31:t.memoizedState!==null&&Po(t);break;case 13:Po(t);break;case 19:Lo(t);break;case 10:ga(t.type);break;case 22:case 23:Po(t),Do(),e!==null&&ye(Ha);break;case 24:ga(Oa)}}function bl(e,t){try{var n=t.updateQueue,r=n===null?null:n.lastEffect;if(r!==null){var i=r.next;n=i;do{if((n.tag&e)===e){r=void 0;var a=n.create,o=n.inst;r=a(),o.destroy=r}n=n.next}while(n!==i)}}catch(e){Z(t,t.return,e)}}function xl(e,t,n){try{var r=t.updateQueue,i=r===null?null:r.lastEffect;if(i!==null){var a=i.next;r=a;do{if((r.tag&e)===e){var o=r.inst,s=o.destroy;if(s!==void 0){o.destroy=void 0,i=t;var c=n,l=s;try{l()}catch(e){Z(i,c,e)}}}r=r.next}while(r!==a)}}catch(e){Z(t,t.return,e)}}function Sl(e){var t=e.updateQueue;if(t!==null){var n=e.stateNode;try{So(t,n)}catch(t){Z(e,e.return,t)}}}function Cl(e,t,n){n.props=bc(e.type,e.memoizedProps),n.state=e.memoizedState;try{n.componentWillUnmount()}catch(n){Z(e,t,n)}}function wl(e,t){try{var n=e.ref;if(n!==null){switch(e.tag){case 26:case 27:case 5:var r=e.stateNode;break;case 30:var i=e.stateNode,a=mi(e.memoizedProps,i);(i.ref===null||i.ref.name!==a)&&(i.ref=Pp(a)),r=i.ref;break;case 7:if(e.stateNode===null){var o=new Fp(e);h(e.child,!1,Qp,o,void 0,void 0),e.stateNode=o}r=e.stateNode;break;default:r=e.stateNode}typeof n==`function`?e.refCleanup=n(r):n.current=r}}catch(n){Z(e,t,n)}}function Tl(e,t){var n=e.ref,r=e.refCleanup;if(n!==null){if(typeof r==`function`)try{r()}catch(n){Z(e,t,n)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof n==`function`)try{n(null)}catch(n){Z(e,t,n)}else n.current=null}}function El(e,t){if((e.tag===5||e.tag===27||e.tag===6)&&e.alternate===null&&t!==null)for(var n=0;n title`))),np(r,t,n),r[bt]=e,Nt(r),t=r;break a;case`link`:if(o=Gm(`link`,`href`,a).get(t+(n.href||``))){for(s=0;sg&&(o=g,g=h,h=o);var _=Hr(s,h),v=Hr(s,g);if(_&&v&&(p.rangeCount!==1||p.anchorNode!==_.node||p.anchorOffset!==_.offset||p.focusNode!==v.node||p.focusOffset!==v.offset)){var y=d.createRange();y.setStart(_.node,_.offset),p.removeAllRanges(),h>g?(p.addRange(y),p.extend(v.node,v.offset)):(y.setEnd(v.node,v.offset),p.addRange(y))}}}}for(d=[],p=s;p=p.parentNode;)p.nodeType===1&&d.push({element:p,left:p.scrollLeft,top:p.scrollTop});for(typeof s.focus==`function`&&s.focus(),s=0;sn?32:n,I.T=null,n=wd,wd=null;var o=bd,s=Sd;if(yd=0,xd=bd=null,Sd=0,q&6)throw Error(i(331));var c=q;if(q|=4,Ju(o.current),Bu(o,o.current,s,n),q=c,Df(0,!1),Je&&typeof Je.onPostCommitFiberRoot==`function`)try{Je.onPostCommitFiberRoot(qe,o)}catch{}return!0}finally{L.p=a,I.T=r,uf(e,t)}}function pf(e,t,n){t=zi(n,t),t=Ec(e.stateNode,t,2),e=ho(e,t,2),e!==null&&(ut(e,2),Ef(e))}function Z(e,t,n){if(e.tag===3)pf(e,e,n);else for(;t!==null;){if(t.tag===3){pf(t,e,n);break}if(t.tag===1){var r=t.stateNode;if(typeof t.type.getDerivedStateFromError==`function`||typeof r.componentDidCatch==`function`&&(vd===null||!vd.has(r))){e=zi(n,e),n=Dc(2),r=ho(t,n,2),r!==null&&(Oc(n,r,t,e),ut(r,2),Ef(r));break}}t=t.return}}function mf(e,t,n){var r=e.pingCache;if(r===null){r=e.pingCache=new Qu;var i=new Set;r.set(t,i)}else i=r.get(t),i===void 0&&(i=new Set,r.set(t,i));i.has(n)||(rd=!0,i.add(n),e=hf.bind(null,e,t,n),t.then(e,e))}function hf(e,t,n){var r=e.pingCache;r!==null&&r.delete(t),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,$u===e&&(Y&n)===n&&(ad===4||ad===3&&(Y&62914560)===Y&&300>Re()-md?q&2?cd|=n:Vd(e,0):cd|=n,ud===Y&&(ud=0)),Ef(e)}function gf(e,t){t===0&&(t=ct()),e=wi(e,t),e!==null&&(ut(e,t),Ef(e))}function _f(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),gf(e,n)}function vf(e,t){var n=0;switch(e.tag){case 31:case 13:var r=e.stateNode,a=e.memoizedState;a!==null&&(n=a.retryLane);break;case 19:r=e.stateNode;break;case 22:r=e.stateNode._retryCache;break;default:throw Error(i(314))}r!==null&&r.delete(t),gf(e,n)}function yf(e,t){return Pe(e,t)}var bf=null,xf=null,Sf=!1,Cf=!1,wf=!1,Tf=0;function Ef(e){e!==xf&&e.next===null&&(xf===null?bf=xf=e:xf=xf.next=e),Cf=!0,Sf||(Sf=!0,Nf())}function Df(e,t){if(!wf&&Cf){wf=!0;do for(var n=!1,r=bf;r!==null;){if(!t){if(e!==0){var i=r.pendingLanes;if(i===0)var a=0;else{var o=r.suspendedLanes,s=r.pingedLanes;a=(1<<31-Xe(42|e)+1)-1,a&=i&~(o&~s),a=a&201326741?a&201326741|1:a?a|2:0}a!==0&&(n=!0,Mf(r,a))}else a=Y,a=it(r,r===$u?a:0,r.cancelPendingCommit!==null||r.timeoutHandle!==-1),!(a&3)||at(r,a)||(n=!0,Mf(r,a))}r=r.next}while(n);wf=!1}}function Of(){kf()}function kf(){Cf=Sf=!1;var e=0;Tf!==0&&hp()&&(e=Tf);for(var t=Re(),n=null,r=bf;r!==null;){var i=r.next,a=Af(r,t);a===0?(r.next=null,n===null?bf=i:n.next=i,i===null&&(xf=n)):(n=r,(e!==0||a&3)&&(Cf=!0)),r=i}yd!==0&&yd!==5||Df(e,!1),Tf!==0&&(Tf=0)}function Af(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,i=e.expirationTimes,a=e.pendingLanes&-62914561;0s)break;var u=c.transferSize,d=c.initiatorType;u&&ap(d)&&(c=c.responseEnd,o+=u*(c$m){s.length=o;break}f=new Promise(jp.bind(f)),s.push(f)}}}if(0`u`?null:document;function Tm(e,t,n){var r=wm;if(r&&typeof t==`string`&&t){var i=$t(t);i=`link[rel="`+e+`"][href="`+i+`"]`,typeof n==`string`&&(i+=`[crossorigin="`+n+`"]`),ym.has(i)||(ym.add(i),e={rel:e,crossOrigin:n,href:t},r.querySelector(i)===null&&(t=r.createElement(`link`),np(t,`link`,e),Nt(t),r.head.appendChild(t)))}}function Em(e){xm.D(e),Tm(`dns-prefetch`,e,null)}function Dm(e,t){xm.C(e,t),Tm(`preconnect`,e,t)}function Om(e,t,n){xm.L(e,t,n);var r=wm;if(r&&e&&t){var i=`link[rel="preload"][as="`+$t(t)+`"]`;t===`image`&&n&&n.imageSrcSet?(i+=`[imagesrcset="`+$t(n.imageSrcSet)+`"]`,typeof n.imageSizes==`string`&&(i+=`[imagesizes="`+$t(n.imageSizes)+`"]`)):i+=`[href="`+$t(e)+`"]`;var a=i;switch(t){case`style`:a=Pm(e);break;case`script`:a=Rm(e)}if(!(vm.has(a)||(e=D({rel:`preload`,href:t===`image`&&n&&n.imageSrcSet?void 0:e,as:t},n),vm.set(a,e),r.querySelector(i)!==null||t===`style`&&r.querySelector(Fm(a))||t===`script`&&r.querySelector(zm(a))))){var o=r.createElement(`link`);np(o,`link`,e),t===`style`&&(o[Ot]=!0,o.onload=o.onerror=function(){Pt(o)}),Nt(o),r.head.appendChild(o)}}}function km(e,t){xm.m(e,t);var n=wm;if(n&&e){var r=t&&typeof t.as==`string`?t.as:`script`,i=`link[rel="modulepreload"][as="`+$t(r)+`"][href="`+$t(e)+`"]`,a=i;switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:a=Rm(e)}if(!vm.has(a)&&(e=D({rel:`modulepreload`,href:e},t),vm.set(a,e),n.querySelector(i)===null)){switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:if(n.querySelector(zm(a)))return}r=n.createElement(`link`),np(r,`link`,e),Nt(r),n.head.appendChild(r)}}}function Am(e,t,n){xm.S(e,t,n);var r=wm;if(r&&e){var i=V(r).hoistableStyles,a=Pm(e);t||=`default`;var o=i.get(a);if(!o){var s={loading:0,preload:null};if(o=r.querySelector(Fm(a)))s.loading=5;else{e=D({rel:`stylesheet`,href:e,"data-precedence":t},n),(n=vm.get(a))&&Hm(e,n);var c=o=r.createElement(`link`);Nt(c),np(c,`link`,e),c._p=new Promise(function(e,t){c.onload=e,c.onerror=t}),c.addEventListener(`load`,function(){s.loading|=1}),c.addEventListener(`error`,function(){s.loading|=2}),s.loading|=4,Vm(o,t,r)}o={type:`stylesheet`,instance:o,count:1,state:s},i.set(a,o)}}}function jm(e,t){xm.X(e,t);var n=wm;if(n&&e){var r=V(n).hoistableScripts,i=Rm(e),a=r.get(i);a||(a=n.querySelector(zm(i)),a||(e=D({src:e,async:!0},t),(t=vm.get(i))&&Um(e,t),a=n.createElement(`script`),Nt(a),np(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Mm(e,t){xm.M(e,t);var n=wm;if(n&&e){var r=V(n).hoistableScripts,i=Rm(e),a=r.get(i);a||(a=n.querySelector(zm(i)),a||(e=D({src:e,async:!0,type:`module`},t),(t=vm.get(i))&&Um(e,t),a=n.createElement(`script`),Nt(a),np(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Nm(e,t,n,r){var a=(a=Se.current)?bm(a):null;if(!a)throw Error(i(446));switch(e){case`meta`:case`title`:return null;case`style`:return typeof n.precedence==`string`&&typeof n.href==`string`?(n=Pm(n.href),t=V(a).hoistableStyles,r=t.get(n),r||(r={type:`style`,instance:null,count:0,state:null},t.set(n,r)),r):{type:`void`,instance:null,count:0,state:null};case`link`:if(n.rel===`stylesheet`&&typeof n.href==`string`&&typeof n.precedence==`string`){e=Pm(n.href);var o=V(a).hoistableStyles,s=o.get(e);if(s||(a=a.ownerDocument||a,s={type:`stylesheet`,instance:null,count:0,state:{loading:0,preload:null}},o.set(e,s),(o=a.querySelector(Fm(e)))?o._p||(s.instance=o,s.state.loading=5):(o=vm.get(e),o||(o={rel:`preload`,as:`style`,href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},vm.set(e,o)),Lm(a,e,o,s.state))),t&&r===null)throw Error(i(528,``));return s}if(t&&r!==null)throw Error(i(529,``));return null;case`script`:return t=n.async,n=n.src,typeof n==`string`&&t&&typeof t!=`function`&&typeof t!=`symbol`?(n=Rm(n),t=V(a).hoistableScripts,r=t.get(n),r||(r={type:`script`,instance:null,count:0,state:null},t.set(n,r)),r):{type:`void`,instance:null,count:0,state:null};default:throw Error(i(444,e))}}function Pm(e){return`href="`+$t(e)+`"`}function Fm(e){return`link[rel="stylesheet"][`+e+`]`}function Im(e){return D({},e,{"data-precedence":e.precedence,precedence:null})}function Lm(e,t,n,r){if(t=e.querySelector(`link[rel="preload"][as="style"][`+t+`]`)){if(!0!==t[Ot]){r.loading=1;return}}else t=e.createElement(`link`),t[Ot]=!0,t.onload=t.onerror=Pt.bind(null,t),np(t,`link`,n),Nt(t),e.head.appendChild(t);r.preload=t,t.addEventListener(`load`,function(){return r.loading|=1}),t.addEventListener(`error`,function(){return r.loading|=2})}function Rm(e){return`[src="`+$t(e)+`"]`}function zm(e){return`script[async]`+e}function Bm(e,t,n){if(t.count++,t.instance===null)switch(t.type){case`style`:var r=e.querySelector(`style[data-href~="`+$t(n.href)+`"]`);if(r)return t.instance=r,Nt(r),r;var a=D({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return r=(e.ownerDocument||e).createElement(`style`),Nt(r),np(r,`style`,a),Vm(r,n.precedence,e),t.instance=r;case`stylesheet`:a=Pm(n.href);var o=e.querySelector(Fm(a));if(o)return t.state.loading|=4,t.instance=o,Nt(o),o;r=Im(n),(a=vm.get(a))&&Hm(r,a),o=(e.ownerDocument||e).createElement(`link`),Nt(o);var s=o;return s._p=new Promise(function(e,t){s.onload=e,s.onerror=t}),np(o,`link`,r),t.state.loading|=4,Vm(o,n.precedence,e),t.instance=o;case`script`:return o=Rm(n.src),(a=e.querySelector(zm(o)))?(t.instance=a,Nt(a),a):(r=n,(a=vm.get(o))&&(r=D({},n),Um(r,a)),e=e.ownerDocument||e,a=e.createElement(`script`),Nt(a),np(a,`link`,r),e.head.appendChild(a),t.instance=a);case`void`:return null;default:throw Error(i(443,t.type))}else t.type===`stylesheet`&&!(t.state.loading&4)&&(r=t.instance,t.state.loading|=4,Vm(r,n.precedence,e));return t.instance}function Vm(e,t,n){for(var r=n.querySelectorAll(`link[rel="stylesheet"][data-precedence],style[data-precedence]`),i=r.length?r[r.length-1]:null,a=i,o=0;o title`):null)}function qm(e,t,n){if(n===1||t.itemProp!=null)return!1;switch(e){case`meta`:case`title`:return!0;case`style`:if(typeof t.precedence!=`string`||typeof t.href!=`string`||t.href===``)break;return!0;case`link`:if(typeof t.rel!=`string`||typeof t.href!=`string`||t.href===``||t.onLoad||t.onError)break;switch(t.rel){case`stylesheet`:return e=t.disabled,typeof t.precedence==`string`&&e==null;default:return!0}case`script`:if(t.async&&typeof t.async!=`function`&&typeof t.async!=`symbol`&&!t.onLoad&&!t.onError&&t.src&&typeof t.src==`string`)return!0}return!1}function Jm(e,t){return e===`img`&&t.src!=null&&t.src!==``&&t.onLoad==null&&t.loading!==`lazy`}function Ym(e){return!(e.type===`stylesheet`&&!(e.state.loading&3))}function Xm(e){return(e.width||100)*(e.height||100)*(typeof devicePixelRatio==`number`?devicePixelRatio:1)*.25}function Zm(e,t){typeof t.decode==`function`&&(e.imgCount++,t.complete||(e.imgBytes+=Xm(t),e.suspenseyImages.push(t)),e=rh.bind(e),t.decode().then(e,e))}function Qm(e,t,n,r){if(n.type===`stylesheet`&&(typeof r.media!=`string`||!1!==matchMedia(r.media).matches)&&!(n.state.loading&4)){if(n.instance===null){var i=Pm(r.href),a=t.querySelector(Fm(i));if(a){t=a._p,typeof t==`object`&&t&&typeof t.then==`function`&&(e.count++,e=nh.bind(e),t.then(e,e)),n.state.loading|=4,n.instance=a,Nt(a);return}a=t.ownerDocument||t,r=Im(r),(i=vm.get(i))&&Hm(r,i),a=a.createElement(`link`),Nt(a);var o=a;o._p=new Promise(function(e,t){o.onload=e,o.onerror=t}),np(a,`link`,r),n.instance=a}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,t),(t=n.state.preload)&&!(n.state.loading&3)&&(e.count++,n=nh.bind(e),t.addEventListener(`load`,n),t.addEventListener(`error`,n))}}var $m=0;function eh(e,t){return e.stylesheets&&e.count===0&&ah(e,e.stylesheets),0$m?50:800)+t);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(r),clearTimeout(i)}}:null}function th(e){if(e.count===0&&(e.imgCount===0||!e.waitingForImages)){if(e.stylesheets)ah(e,e.stylesheets);else if(e.unsuspend){var t=e.unsuspend;e.unsuspend=null,t()}}}function nh(){this.count--,th(this)}function rh(){this.imgCount--,th(this)}var ih=null;function ah(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,ih=new Map,t.forEach(oh,e),ih=null,nh.call(e))}function oh(e,t){if(!(t.state.loading&4)){var n=ih.get(e);if(n)var r=n.get(null);else{n=new Map,ih.set(e,n);for(var i=e.querySelectorAll(`link[data-precedence],style[data-precedence]`),a=0;a{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=h()})),_=c(u(),1),v=g(),y=o((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),b=o(((e,t)=>{t.exports=y()})),x=b(),S={models:(0,x.jsx)(`path`,{d:`M5 6.5A1.5 1.5 0 0 1 6.5 5h4A1.5 1.5 0 0 1 12 6.5v4a1.5 1.5 0 0 1-1.5 1.5h-4A1.5 1.5 0 0 1 5 10.5zm8 0A1.5 1.5 0 0 1 14.5 5h3A1.5 1.5 0 0 1 19 6.5v11a1.5 1.5 0 0 1-1.5 1.5h-3a1.5 1.5 0 0 1-1.5-1.5zm-8 8A1.5 1.5 0 0 1 6.5 13h4a1.5 1.5 0 0 1 1.5 1.5v3a1.5 1.5 0 0 1-1.5 1.5h-4A1.5 1.5 0 0 1 5 17.5z`}),chat:(0,x.jsx)(`path`,{d:`M5.5 7.5A2.5 2.5 0 0 1 8 5h8a2.5 2.5 0 0 1 2.5 2.5v5A2.5 2.5 0 0 1 16 15h-3.7l-3.6 3.2a.7.7 0 0 1-1.2-.52V15A2.5 2.5 0 0 1 5.5 12.5z`}),activity:(0,x.jsx)(`path`,{d:`M4.5 13h3l1.8-5.5 3.2 9 2.1-6.5h4.9`}),settings:(0,x.jsx)(`path`,{d:`M12 8.2a3.8 3.8 0 1 0 0 7.6 3.8 3.8 0 0 0 0-7.6Zm0-3.2v2m0 10v2m7-7h-2M7 12H5m11.95-4.95-1.42 1.42M8.47 15.53l-1.42 1.42m9.9 0-1.42-1.42M8.47 8.47 7.05 7.05`}),gallery:(0,x.jsx)(`path`,{d:`M5 6.5A1.5 1.5 0 0 1 6.5 5h11A1.5 1.5 0 0 1 19 6.5v11a1.5 1.5 0 0 1-1.5 1.5h-11A1.5 1.5 0 0 1 5 17.5zm3 2h8m-8 3h8m-8 3h5`}),command:(0,x.jsx)(`path`,{d:`M8 8.5A2.5 2.5 0 1 1 5.5 6 2.5 2.5 0 0 1 8 8.5Zm0 7A2.5 2.5 0 1 1 5.5 13 2.5 2.5 0 0 1 8 15.5Zm8-7A2.5 2.5 0 1 1 13.5 6 2.5 2.5 0 0 1 16 8.5Zm0 7A2.5 2.5 0 1 1 13.5 13 2.5 2.5 0 0 1 16 15.5Z`}),help:(0,x.jsx)(`path`,{d:`M9.5 9a2.5 2.5 0 1 1 4.4 1.62c-.68.72-1.9 1.18-1.9 2.38v.25m0 3.25h.01M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18Z`}),menu:(0,x.jsx)(`path`,{d:`M5 7h14M5 12h14M5 17h14`}),close:(0,x.jsx)(`path`,{d:`m7 7 10 10M17 7 7 17`}),search:(0,x.jsx)(`path`,{d:`m16.5 16.5 3 3M11 18a7 7 0 1 1 0-14 7 7 0 0 1 0 14Z`}),warning:(0,x.jsx)(`path`,{d:`M12 4.8 21 19H3zm0 5.2v4m0 2.5h.01`}),key:(0,x.jsx)(`path`,{d:`M14.5 9.5A4.5 4.5 0 1 0 11 13.9l2.1 2.1H16v2h2v2h2v-2.9l-4.6-4.6a4.5 4.5 0 0 0-.9-3Z`}),schema:(0,x.jsx)(`path`,{d:`M6 5h7l5 5v9H6zm7 0v5h5M9 13h6M9 16h6M9 10h2`})};function C(e){return(0,x.jsx)(`svg`,{className:e.className??`ds-icon`,"aria-hidden":`true`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`1.8`,strokeLinecap:`round`,strokeLinejoin:`round`,children:S[e.name]})}var w=(0,_.forwardRef)(function({children:e,onClick:t,onDoubleClick:n,onMouseDown:r,onMouseEnter:i,onKeyDown:a,type:o=`button`,disabled:s=!1,variant:c=`secondary`,size:l=`medium`,shape:u=`default`,fullWidth:d=!1,icon:f,iconPosition:p=`left`,iconOnly:m=!1,inline:h=!1,loading:g=!1,active:v=!1,ariaLabel:y,title:b,role:S,id:C,tabIndex:w,className:T=``,style:E,"aria-pressed":D,"aria-checked":O,"aria-selected":k,"aria-expanded":ee,"aria-haspopup":A,"aria-controls":te,"aria-describedby":ne,"aria-busy":j,"data-testid":M},N){let re=(0,_.useCallback)(e=>{!s&&!g&&t&&t(e)},[s,g,t]),ie=[`button`,`button--${c}`,`button--${l}`,u!=="default"&&`button--${u}`,d&&`button--full-width`,m&&`button--icon-only`,h&&`button--inline`,g&&`button--loading`,v&&`button--active`,T].filter(Boolean).join(` `),ae=f??(m?e:void 0),oe=!m&&e,se=ae&&!g;return(0,x.jsxs)(`button`,{ref:N,type:o,onClick:re,onDoubleClick:n,onMouseDown:r,onMouseEnter:i,onKeyDown:a,disabled:s||g,className:ie,"aria-label":y??(m&&typeof e==`string`?e:void 0),title:b,role:S,id:C,tabIndex:w,style:E,"aria-pressed":D,"aria-checked":O,"aria-selected":k,"aria-expanded":ee,"aria-haspopup":A,"aria-controls":te,"aria-describedby":ne,"aria-busy":j,"data-testid":M,children:[g&&(0,x.jsx)(`span`,{className:`button__loading-spinner`,"aria-hidden":`true`}),se&&p===`left`&&(0,x.jsx)(`span`,{className:`button__icon`,"aria-hidden":`true`,children:ae}),oe&&(h?e:(0,x.jsx)(`span`,{className:`button__text`,children:e})),se&&p===`right`&&(0,x.jsx)(`span`,{className:`button__icon`,"aria-hidden":`true`,children:ae})]})});function T({children:e,variant:t=`default`,size:n=`small`,className:r=``}){let i=[`badge`,`badge--${t}`,`badge--${n}`,r].filter(Boolean).join(` `);return(0,x.jsx)(`span`,{className:i,children:e})}function E(e){switch(e){case`running`:return`success`;case`preparing`:return`info`;case`idle`:return`default`;case`busy`:return`primary`;case`stopping`:return`warning`;case`terminated`:return`default`;case`error`:return`danger`}}function D(e){return e===`preparing`||e===`stopping`||e===`busy`}function O({state:e,label:t,size:n=`small`,pulse:r,className:i=``}){let a=r??D(e),o=[`status-tag`,`status-tag--${e}`,i].filter(Boolean).join(` `);return(0,x.jsxs)(T,{variant:E(e),size:n,className:o,children:[a&&(0,x.jsx)(`span`,{className:`status-tag__indicator`,"aria-hidden":`true`,"data-testid":`status-tag-indicator`}),(0,x.jsx)(`span`,{className:`status-tag__label`,children:t})]})}var k=(0,_.memo)(O);function ee({value:e,variant:t=`primary`,size:n=`md`,showLabel:r=!1,label:i,className:a=``,animated:o=!0,ariaLabel:s}){let c=e===null,l=e===null?0:Math.max(0,Math.min(100,e)),u=[`progress-bar`,`progress-bar--${t}`,`progress-bar--${n}`,c?`progress-bar--indeterminate`:``,o?`progress-bar--animated`:``,a].filter(Boolean).join(` `),d=i??(r&&!c?`${l.toFixed(0)}%`:null);return(0,x.jsxs)(`div`,{className:`progress-bar-wrapper`,children:[(0,x.jsx)(`div`,{className:u,role:`progressbar`,"aria-valuenow":c?void 0:l,"aria-valuemin":0,"aria-valuemax":100,"aria-label":s,"aria-busy":c,children:(0,x.jsx)(`div`,{className:`progress-bar__fill`,style:c?void 0:{width:`${String(l)}%`}})}),d&&(0,x.jsx)(`span`,{className:`progress-bar__label`,children:d})]})}function A({illustration:e,title:t,description:n,primaryAction:r,secondaryAction:i,children:a,className:o=``,showIllustration:s=!0}){let c=r?.onClick,l=i?.onClick,u=(0,_.useCallback)(()=>{c?.()},[c]),d=(0,_.useCallback)(()=>{l?.()},[l]),f=(0,_.useMemo)(()=>[`empty-state`,o].filter(Boolean).join(` `),[o]);return(0,x.jsxs)(`div`,{className:f,role:`status`,"aria-live":`polite`,children:[s&&e&&(0,x.jsx)(`div`,{className:`empty-state__illustration`,children:e}),(0,x.jsxs)(`div`,{className:`empty-state__content`,children:[(0,x.jsx)(`h3`,{className:`empty-state__title`,children:t}),(0,x.jsx)(`p`,{className:`empty-state__description`,children:n}),a]}),(r||i)&&(0,x.jsxs)(`div`,{className:`empty-state__actions`,children:[r&&(0,x.jsx)(w,{variant:`primary`,onClick:u,className:`empty-state__action-btn empty-state__action-btn--primary`,children:r.label}),i&&(0,x.jsx)(x.Fragment,{children:i.href?(0,x.jsx)(`a`,{href:i.href,className:`empty-state__action-link`,onClick:d,children:i.label}):(0,x.jsx)(w,{variant:`ghost`,onClick:d,className:`empty-state__action-btn empty-state__action-btn--secondary`,children:i.label})})]})]})}var te=(0,_.memo)(A);function ne({tabs:e,groups:t=[],defaultTab:n,activeTab:r,onTabChange:i,className:a=``,panelClassName:o=``,ariaLabel:s,showOverflowControls:c=!0,showGroupLabels:l=!0,overflowMode:u,variant:d=`underlined`,fillContainer:f=!1,renderPanel:p=!0,moreTabsLabel:m=`More tabs`,selectTabLabel:h=`Select tab`,scrollLeftLabel:g=`Scroll left`,scrollRightLabel:v=`Scroll right`}){let y=u??(t.length>0?`menu`:`dropdown`),[b,S]=(0,_.useState)(n||e[0]?.id||``),[C,w]=(0,_.useState)(!1),[T,E]=(0,_.useState)(!1),[D,O]=(0,_.useState)(!1),[k,ee]=(0,_.useState)(!1),[A,te]=(0,_.useState)(!1),[ne,j]=(0,_.useState)(-1),M=(0,_.useRef)(null),N=(0,_.useRef)(new Map),re=(0,_.useRef)(null),ie=(0,_.useRef)(null),ae=(0,_.useRef)(null),oe=(0,_.useRef)([]),se=(0,_.useRef)(null),ce=(0,_.useRef)(0),P=(0,_.useRef)(0),F=r??b,le=(0,_.useMemo)(()=>t.length>0?t.map(t=>({group:t,tabs:e.filter(e=>e.groupId===t.id)})):[{group:null,tabs:e}],[t,e]),ue=(0,_.useMemo)(()=>le.flatMap(({tabs:e})=>e),[le]),de=(0,_.useCallback)(e=>{r||S(e),i?.(e),te(!1)},[r,i]),fe=(0,_.useCallback)((t,n)=>{let r;switch(t.key){case`ArrowRight`:t.preventDefault(),r=n===e.length-1?0:n+1;break;case`ArrowLeft`:t.preventDefault(),r=n===0?e.length-1:n-1;break;case`Home`:t.preventDefault(),r=0;break;case`End`:t.preventDefault(),r=e.length-1;break;default:return}let i=e[r];i&&(de(i.id),N.current.get(i.id)?.focus())},[e,de]),pe=(0,_.useCallback)((e,t)=>{t?N.current.set(e,t):N.current.delete(e)},[]),me=(0,_.useCallback)(()=>{let e=M.current;if(!e||!c){w(!1),E(!1);return}let{scrollLeft:t,scrollWidth:n,clientWidth:r}=e;w(t>0),E(t+r{let t=M.current;if(!t)return;let n=t.clientWidth*.75;t.scrollBy({left:e===`left`?-n:n,behavior:`smooth`}),se.current!==null&&clearTimeout(se.current),se.current=setTimeout(me,300)},[me]),L=(0,_.useCallback)(()=>{if(!M.current||D)return;let e=N.current.get(F);if(!e)return;let t=M.current,n=e.getBoundingClientRect(),r=t.getBoundingClientRect();n.leftr.right&&(t.scrollLeft+=n.right-r.right+8)},[F,D]),he=(0,_.useCallback)(()=>{typeof window>`u`||y!==`dropdown`||O(window.innerWidth<480)},[y]),ge=(0,_.useCallback)(()=>{ee(e=>!e)},[]),_e=(0,_.useCallback)(e=>{e.key===`Escape`&&k&&(e.preventDefault(),ee(!1))},[k]),ve=(0,_.useCallback)(e=>{e.touches[0]&&(ce.current=e.touches[0].clientX)},[]),ye=(0,_.useCallback)(e=>{e.touches[0]&&(P.current=e.touches[0].clientX)},[]),R=(0,_.useCallback)(()=>{if(!ce.current||!P.current)return;let t=ce.current-P.current;if(Math.abs(t)>50){let n=e.findIndex(e=>e.id===F),r=e[n+1],i=e[n-1];t>0&&r?de(r.id):t<0&&i&&de(i.id)}ce.current=0,P.current=0},[F,e,de]),be=(0,_.useCallback)(e=>{let t=ue.length;switch(e.key){case`Escape`:e.preventDefault(),te(!1),j(-1),ae.current?.focus();break;case`ArrowDown`:e.preventDefault(),j(e=>{let n=e>=t-1?0:e+1;return oe.current[n]?.focus(),n});break;case`ArrowUp`:e.preventDefault(),j(e=>{let n=e<=0?t-1:e-1;return oe.current[n]?.focus(),n});break;case`Home`:e.preventDefault(),j(0),oe.current[0]?.focus();break;case`End`:e.preventDefault(),j(t-1),oe.current[t-1]?.focus()}},[ue.length]),xe=(0,_.useCallback)(e=>{e.key===`Escape`&&A&&(e.preventDefault(),te(!1),j(-1))},[A]);(0,_.useEffect)(()=>{if(!k)return;let e=e=>{re.current&&!re.current.contains(e.target)&&ee(!1)};return document.addEventListener(`mousedown`,e),()=>{document.removeEventListener(`mousedown`,e)}},[k]),(0,_.useEffect)(()=>{if(!A)return;let e=e=>{ie.current&&!ie.current.contains(e.target)&&(te(!1),j(-1))},t=e=>{e.key===`Escape`&&(te(!1),j(-1),ae.current?.focus())};return document.addEventListener(`mousedown`,e),document.addEventListener(`keydown`,t),()=>{document.removeEventListener(`mousedown`,e),document.removeEventListener(`keydown`,t)}},[A]),(0,_.useEffect)(()=>{if(A&&oe.current.length>0){let e=ue.findIndex(e=>e.id===F),t=e>=0?e:0;j(t),requestAnimationFrame(()=>{oe.current[t]?.focus()})}},[A,ue,F]),(0,_.useEffect)(()=>{if(!e.find(e=>e.id===F)){let t=e[0];t&&de(t.id)}},[e,F,de]),(0,_.useEffect)(()=>{he(),me();let e=()=>{he(),me()};return window.addEventListener(`resize`,e),()=>{window.removeEventListener(`resize`,e)}},[he,me]),(0,_.useEffect)(()=>{L()},[F,L]),(0,_.useEffect)(()=>{me()},[e,me]),(0,_.useEffect)(()=>()=>{se.current!==null&&clearTimeout(se.current)},[]);let Se=e.find(e=>e.id===F)?.content,Ce=e.find(e=>e.id===F)?.label,we=t.length>0;oe.current=[];let Te=(e,t)=>{let n=e.id===F;return(0,x.jsxs)(`button`,{ref:t=>{pe(e.id,t)},role:`tab`,"aria-selected":n,"aria-controls":p?`tabpanel-${e.id}`:void 0,id:`tab-${e.id}`,tabIndex:n?0:-1,className:`tabs__tab${n?` tabs__tab--active`:``}`,onClick:()=>{de(e.id)},onKeyDown:e=>{fe(e,t),(e.key===`ArrowLeft`||e.key===`ArrowRight`||e.key===`Home`||e.key===`End`)&&e.stopPropagation()},children:[e.labelPrefix,(0,x.jsx)(`span`,{className:`tabs__tab-label`,children:e.label}),e.labelExtra]},e.id)},Ee=()=>we?le.map(({group:t,tabs:n},r)=>(0,x.jsxs)(`div`,{className:`tabs__group`,children:[t&&(0,x.jsxs)(x.Fragment,{children:[r>0&&(0,x.jsx)(`div`,{className:`tabs__separator`,role:`separator`,"aria-hidden":`true`}),l&&(0,x.jsx)(`span`,{className:`tabs__group-label`,children:t.label})]}),(0,x.jsx)(`div`,{className:`tabs__group-tabs`,children:n.map(t=>{let n=e.findIndex(e=>e.id===t.id);return Te(t,n)})})]},t?.id||`default`)):e.map((e,t)=>Te(e,t)),De=()=>y!==`menu`||!c?null:(0,x.jsxs)(`div`,{className:`tabs__overflow`,ref:ie,children:[(0,x.jsx)(`button`,{ref:ae,type:`button`,className:`tabs__overflow-btn`,onClick:()=>{te(!A)},onKeyDown:xe,"aria-label":m,"aria-expanded":A,"aria-haspopup":`menu`,children:(0,x.jsxs)(`svg`,{width:`20`,height:`20`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,x.jsx)(`circle`,{cx:`12`,cy:`12`,r:`1`}),(0,x.jsx)(`circle`,{cx:`12`,cy:`5`,r:`1`}),(0,x.jsx)(`circle`,{cx:`12`,cy:`19`,r:`1`})]})}),A&&(0,x.jsx)(`div`,{className:`tabs__overflow-menu`,role:`menu`,onKeyDown:be,children:le.map(({group:e,tabs:t})=>(0,x.jsxs)(`div`,{className:`tabs__overflow-group`,children:[e&&l&&(0,x.jsx)(`div`,{className:`tabs__overflow-group-label`,children:e.label}),t.map(e=>{let t=e.id===F,n=ue.findIndex(t=>t.id===e.id);return(0,x.jsxs)(`button`,{ref:e=>{e&&(oe.current[n]=e)},role:`menuitem`,tabIndex:ne===n?0:-1,className:`tabs__overflow-item ${t?`tabs__overflow-item--active`:``}`,onClick:()=>{de(e.id)},children:[e.labelPrefix,(0,x.jsx)(`span`,{children:e.label}),e.labelExtra]},e.id)})]},e?.id||`default`))})]}),Oe=d===`segmented`||d===`compact`;return y===`dropdown`&&D&&!Oe?(0,x.jsxs)(`div`,{className:`tabs tabs--mobile-dropdown ${a}`,children:[(0,x.jsxs)(`div`,{className:`tabs__dropdown-container`,ref:re,children:[(0,x.jsxs)(`button`,{className:`tabs__dropdown-trigger`,onClick:ge,onKeyDown:_e,"aria-expanded":k,"aria-haspopup":`listbox`,"aria-label":s||h,children:[(0,x.jsx)(`span`,{className:`tabs__dropdown-label`,children:Ce}),(0,x.jsx)(`svg`,{className:`tabs__dropdown-arrow ${k?`tabs__dropdown-arrow--open`:``}`,width:`16`,height:`16`,viewBox:`0 0 16 16`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,"aria-hidden":`true`,children:(0,x.jsx)(`path`,{d:`M4 6L8 10L12 6`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`})})]}),k&&(0,x.jsx)(`div`,{className:`tabs__dropdown-menu`,role:`listbox`,children:e.map(e=>(0,x.jsx)(`button`,{role:`option`,"aria-selected":e.id===F,className:`tabs__dropdown-item ${e.id===F?`tabs__dropdown-item--active`:``}`,onClick:()=>{de(e.id),ee(!1)},children:e.label},e.id))})]}),p&&(0,x.jsx)(`div`,{id:`tabpanel-${F}`,role:`tabpanel`,"aria-labelledby":`tab-${F}`,className:`tabs__panel ${o}`.trim(),tabIndex:0,onTouchStart:ve,onTouchMove:ye,onTouchEnd:R,children:Se})]}):(0,x.jsxs)(`div`,{className:`tabs ${y===`menu`?`tabs--overflow-menu`:``} ${d===`segmented`?`tabs--variant-segmented`:d===`compact`?`tabs--variant-compact`:``} ${Oe&&f?`tabs--fill-container`:``} ${a}`.replace(/\s+/g,` `).trim(),children:[(0,x.jsxs)(`div`,{className:`tabs__container`,children:[c&&C&&(0,x.jsx)(`button`,{className:`tabs__scroll-arrow tabs__scroll-arrow--left`,onClick:()=>{I(`left`)},"aria-label":g,tabIndex:-1,children:(0,x.jsx)(`svg`,{width:`20`,height:`20`,viewBox:`0 0 20 20`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,"aria-hidden":`true`,children:(0,x.jsx)(`path`,{d:`M12 15L7 10L12 5`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`})})}),(0,x.jsx)(`div`,{ref:M,className:`tabs__list`,role:`tablist`,"aria-label":s,onScroll:me,onKeyDown:t=>{let n=e.findIndex(e=>e.id===F);n<0||fe(t,n)},onTouchStart:y===`dropdown`?ve:void 0,onTouchMove:y===`dropdown`?ye:void 0,onTouchEnd:y===`dropdown`?R:void 0,children:Ee()}),c&&T&&(0,x.jsx)(`button`,{className:`tabs__scroll-arrow tabs__scroll-arrow--right`,onClick:()=>{I(`right`)},"aria-label":v,tabIndex:-1,children:(0,x.jsx)(`svg`,{width:`20`,height:`20`,viewBox:`0 0 20 20`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,"aria-hidden":`true`,children:(0,x.jsx)(`path`,{d:`M8 5L13 10L8 15`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`})})}),De()]}),p&&(0,x.jsx)(`div`,{id:`tabpanel-${F}`,role:`tabpanel`,"aria-labelledby":`tab-${F}`,className:`tabs__panel ${o}`.trim(),tabIndex:0,children:Se})]})}var j=[`a`,`button`,`input`,`select`,`textarea`,`summary`,`label`,`[contenteditable='true']`,`[role='button']`,`[role='link']`,`[tabindex]:not([tabindex='-1'])`].join(`,`);function M(e,t){if(!(e instanceof Element)||!(t instanceof Element))return!1;let n=e.closest(j);return n!==null&&n!==t&&t.contains(n)}var N={widths:{},visibility:{}};function re(e,t){let n=e.map((e,t)=>({row:e,i:t}));return n.sort((e,n)=>{let r=t(e.row,n.row);return r===0?e.i-n.i:r}),n.map(({row:e})=>e)}function ie(e,t){let{sortComparator:n}=e;if(n)return(e,r)=>n(e,r,t);let r=e.sortValueAccessor;return r?(e,n)=>{let i=r(e),a=r(n);if(i==null&&a==null)return 0;if(i==null)return 1;if(a==null)return-1;let o;return o=typeof i==`number`&&typeof a==`number`?i-a:String(i).localeCompare(String(a)),t===`asc`?o:-o}:()=>0}function ae(e,t,n){if(e.sortable)return e.id===t?n===`asc`?`ascending`:`descending`:`none`}function oe({direction:e}){return e===`none`?(0,x.jsx)(`span`,{className:`data-table__sort-icon data-table__sort-icon--none`,"aria-hidden":`true`,children:(0,x.jsxs)(`svg`,{width:`10`,height:`14`,viewBox:`0 0 10 14`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,children:[(0,x.jsx)(`path`,{d:`M5 1L1 5H9L5 1Z`,fill:`currentColor`,opacity:`0.35`}),(0,x.jsx)(`path`,{d:`M5 13L9 9H1L5 13Z`,fill:`currentColor`,opacity:`0.35`})]})}):e===`asc`?(0,x.jsx)(`span`,{className:`data-table__sort-icon data-table__sort-icon--asc`,"aria-hidden":`true`,children:(0,x.jsxs)(`svg`,{width:`10`,height:`14`,viewBox:`0 0 10 14`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,children:[(0,x.jsx)(`path`,{d:`M5 1L1 5H9L5 1Z`,fill:`currentColor`}),(0,x.jsx)(`path`,{d:`M5 13L9 9H1L5 13Z`,fill:`currentColor`,opacity:`0.25`})]})}):(0,x.jsx)(`span`,{className:`data-table__sort-icon data-table__sort-icon--desc`,"aria-hidden":`true`,children:(0,x.jsxs)(`svg`,{width:`10`,height:`14`,viewBox:`0 0 10 14`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,children:[(0,x.jsx)(`path`,{d:`M5 1L1 5H9L5 1Z`,fill:`currentColor`,opacity:`0.25`}),(0,x.jsx)(`path`,{d:`M5 13L9 9H1L5 13Z`,fill:`currentColor`})]})})}function se({columns:e,rows:t,getRowKey:n,emptyState:r,loadingState:i,loading:a=!1,columnState:o,onColumnStateChange:s,className:c=``,ariaLabel:l=`Data table`,testId:u,onRowClick:d,isRowClickable:f,rowClassName:p,sortColumnId:m,sortDirection:h,onSortChange:g}){let[v,y]=(0,_.useState)(()=>o??N);(0,_.useEffect)(()=>{o&&y(o)},[o]);let b=m!==void 0||h!==void 0,[S,C]=(0,_.useState)(void 0),[w,T]=(0,_.useState)(void 0),E=b?m:S,D=b?h:w,O=(0,_.useCallback)(e=>{if(!e.sortable)return;let t,n;E===e.id?D===(e.defaultSortDirection??`asc`)?(t=e.id,n=D===`asc`?`desc`:`asc`):(t=void 0,n=void 0):(t=e.id,n=e.defaultSortDirection??`asc`),b||(C(t),T(n)),g?.(t,n)},[E,D,b,g]),k=(0,_.useMemo)(()=>e.filter(e=>e.alwaysVisible?!0:v.visibility[e.id]!==!1),[e,v.visibility]),ee=(0,_.useCallback)(e=>{let t=v.widths[e.id];return typeof t==`number`&&t>0?t:e.initialWidth},[v.widths]),A=(0,_.useRef)(null),te=(0,_.useCallback)((e,t,n)=>{if(t.noResize)return;e.preventDefault(),e.stopPropagation(),A.current={columnId:t.id,startX:e.clientX,startWidth:n,minWidth:t.minWidth??80};let r=e=>{let t=A.current;if(!t)return;let n=e.clientX-t.startX,r=Math.max(t.minWidth,t.startWidth+n);y(e=>({...e,widths:{...e.widths,[t.columnId]:r}}))},i=()=>{A.current=null,window.removeEventListener(`mousemove`,r),window.removeEventListener(`mouseup`,i)};window.addEventListener(`mousemove`,r),window.addEventListener(`mouseup`,i)},[]),ne=(0,_.useRef)(v);(0,_.useEffect)(()=>{ne.current!==v&&(ne.current=v,s?.(v))},[v,s]);let j=(0,_.useMemo)(()=>{if(!E||!D)return t;let n=e.find(e=>e.id===E);return n?.sortable?re(t,ie(n,D)):t},[t,e,E,D]),se=[`data-table`,c].filter(Boolean).join(` `);return(0,x.jsx)(`div`,{className:se,"data-testid":u,children:(0,x.jsxs)(`table`,{className:`data-table__table`,"aria-label":l,role:`table`,children:[(0,x.jsx)(`thead`,{className:`data-table__head`,children:(0,x.jsx)(`tr`,{className:`data-table__row data-table__row--head`,children:k.map(e=>{let t=ee(e),n=e.sortable&&e.id===E;return(0,x.jsxs)(`th`,{scope:`col`,className:[`data-table__cell`,`data-table__cell--head`,e.sortable&&`data-table__cell--sortable`,n&&`data-table__cell--sort-active`,e.className,e.align&&`data-table__cell--align-${e.align}`].filter(Boolean).join(` `),style:t?{width:`${String(t)}px`}:void 0,"aria-sort":ae(e,E,D),onClick:e.sortable?()=>{O(e)}:void 0,onKeyDown:e.sortable?t=>{(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),O(e))}:void 0,tabIndex:e.sortable?0:void 0,children:[(0,x.jsx)(`span`,{className:`data-table__head-label`,children:e.header}),e.sortable&&(0,x.jsx)(oe,{direction:n&&D?D:`none`}),!e.noResize&&(0,x.jsx)(`div`,{role:`separator`,"aria-orientation":`vertical`,className:`data-table__resize-handle`,onMouseDown:n=>{te(n,e,t??e.minWidth??120)}})]},e.id)})})}),(0,x.jsx)(`tbody`,{className:`data-table__body`,children:a?(0,x.jsx)(`tr`,{className:`data-table__row data-table__row--state`,children:(0,x.jsx)(`td`,{colSpan:k.length||1,className:`data-table__state-cell`,children:i??(0,x.jsx)(`div`,{className:`data-table__loading`})})}):j.length===0?(0,x.jsx)(`tr`,{className:`data-table__row data-table__row--state`,children:(0,x.jsx)(`td`,{colSpan:k.length||1,className:`data-table__state-cell`,children:r})}):j.map((e,t)=>{let r=n(e,t),i=!!(d&&(f?.(e,t)??!0)),a=p?.(e,t);return(0,x.jsx)(`tr`,{className:[`data-table__row`,i&&`data-table__row--clickable`,a].filter(Boolean).join(` `),onClick:i?t=>{M(t.target,t.currentTarget)||d?.(e)}:void 0,onKeyDown:i?t=>{(t.key===`Enter`||t.key===` `)&&(M(t.target,t.currentTarget)||(t.preventDefault(),d?.(e)))}:void 0,tabIndex:i?0:void 0,role:i?`button`:void 0,children:k.map(n=>(0,x.jsx)(`td`,{className:[`data-table__cell`,n.className,n.align&&`data-table__cell--align-${n.align}`].filter(Boolean).join(` `),children:n.render(e,t)},n.id))},r)})})]})})}var ce=(0,_.memo)(se),P=(0,_.forwardRef)(function({tone:e=`secondary`,busy:t=!1,className:n=``,children:r,"aria-label":i,...a},o){return(0,x.jsx)(w,{...a,ref:o,inline:!0,variant:e,loading:t,"aria-busy":t||a[`aria-busy`],ariaLabel:i,className:`ds-button ds-button-${e} ${n}`.trim(),children:(0,x.jsx)(`span`,{children:r})})}),F=(0,_.forwardRef)(function({label:e,icon:t,busy:n=!1,className:r=``,...i},a){return(0,x.jsx)(w,{...i,ref:a,inline:!0,iconOnly:!0,icon:(0,x.jsx)(C,{name:t}),ariaLabel:e,title:i.title??e,variant:`secondary`,loading:n,"aria-busy":n||i[`aria-busy`],className:`ds-icon-button ${r}`.trim()})}),le={unloaded:`terminated`,loading:`preparing`,ready:`running`,draining:`stopping`,unloading:`stopping`,failed:`error`};function ue(e){return(0,x.jsx)(`span`,{className:`ds-status-wrap`,"data-state":e.state,"aria-label":e.label,children:(0,x.jsx)(k,{state:le[e.state],label:e.children,pulse:!1,className:`ds-status`})})}function de(e){let t=e.value===void 0||!Number.isFinite(e.value)?null:Math.max(0,Math.min(100,e.value));return(0,x.jsxs)(`div`,{className:`ds-progress`,children:[(0,x.jsx)(ee,{value:t,ariaLabel:e.label,animated:!1}),e.detail?(0,x.jsx)(`small`,{children:e.detail}):null]})}function fe(e){return(0,x.jsx)(`section`,{className:`ds-empty`,"data-testid":e.testId,ref:e=>{let t=e?.querySelector(`.empty-state__title`);t?.setAttribute(`role`,`heading`),t?.setAttribute(`aria-level`,`2`)},children:(0,x.jsx)(te,{title:e.title,description:e.body,illustration:(0,x.jsx)(C,{name:`models`}),children:e.action})})}function pe(e){let t=(0,_.useId)();if(e.tabs.length===0)return(0,x.jsx)(`section`,{className:`ds-tabs`});let n=e.tabs.map(e=>({id:`${t}-${e.id}`,label:e.label,content:e.panel})),r=e.tabs.find(t=>t.id===e.active)??e.tabs[0];return(0,x.jsx)(`section`,{onKeyDownCapture:e=>{e.nativeEvent.isComposing&&e.stopPropagation()},children:(0,x.jsx)(ne,{className:`ds-tabs`,tabs:n,activeTab:`${t}-${r.id}`,onTabChange:n=>{let r=e.tabs.find(e=>`${t}-${e.id}`===n);r&&e.onChange(r.id)},ariaLabel:e.label??`Sections`,variant:`segmented`,fillContainer:!0,overflowMode:`menu`,showOverflowControls:!1,showGroupLabels:!1})})}var me=`ds-row-primary`,I=`a[href], button, input, select, textarea, summary, label, [contenteditable="true"], [role="button"], [role="link"], [tabindex]:not([tabindex="-1"])`;function L(e){if(e.defaultPrevented||e.button!==0||!(e.target instanceof Element))return;let t=e.target.closest(`tbody > tr`);if(!t||!e.currentTarget.contains(t)||t.classList.contains(`data-table__row--state`))return;let n=t.querySelector(`.${me}`);if(!n||n.matches(`:disabled, [aria-disabled="true"]`))return;let r=e.target.closest(I);if(r&&t.contains(r))return;let i=window.getSelection();(!i||i.isCollapsed||i.toString().trim()===``||!t.contains(i.anchorNode)&&!t.contains(i.focusNode))&&(n.focus({preventScroll:!0}),n.click())}function he({activateRowPrimary:e=!1,...t}){let n=(0,x.jsx)(ce,{...t,className:`ds-common-table ${t.className??``}`.trim()});return e?(0,x.jsx)(`div`,{className:`ds-row-activation`,onClick:L,children:n}):n}function ge({className:e,style:t,size:n}){let r=n??`1em`;return(0,x.jsx)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,width:r,height:r,fill:`none`,viewBox:`0 0 24 24`,strokeWidth:1.5,stroke:`currentColor`,className:e,style:t,"aria-hidden":`true`,children:(0,x.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M12 9v3.75m9-.75a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 3.75h.008v.008H12v-.008Z`})})}function _e({tone:e=`danger`,icon:t,title:n,message:r,primaryAction:i,secondaryAction:a,className:o=``,showIcon:s=!0}){let c=(0,_.useCallback)(()=>{i?.onClick()},[i]),l=(0,_.useCallback)(()=>{a?.onClick()},[a]),u=[`error-state`,`error-state--${e}`,o].filter(Boolean).join(` `);return(0,x.jsxs)(`div`,{className:u,role:`alert`,"aria-live":`polite`,children:[s&&(0,x.jsx)(`div`,{className:`error-state__icon`,"aria-hidden":`true`,children:t??(0,x.jsx)(ge,{size:48})}),(0,x.jsx)(`h2`,{className:`error-state__title`,children:n}),(0,x.jsx)(`p`,{className:`error-state__message`,children:r}),(i||a)&&(0,x.jsxs)(`div`,{className:`error-state__actions`,children:[i&&(0,x.jsx)(w,{variant:`primary`,onClick:c,className:`error-state__action-btn error-state__action-btn--primary`,children:i.label}),a&&(0,x.jsx)(w,{variant:`secondary`,onClick:l,className:`error-state__action-btn error-state__action-btn--secondary`,children:a.label})]})]})}function ve({width:e=`100%`,height:t=`20px`,variant:n=`rect`,className:r=``,testId:i,loadingLabel:a=`Loading`,decorative:o=!1}){let s=[`skeleton`,`skeleton--${n}`,r].filter(Boolean).join(` `);return(0,x.jsx)(`div`,{className:s,style:{width:e,height:t},...o?{"aria-hidden":!0}:{role:`status`,"aria-busy":!0,"aria-label":a},"data-testid":i,children:(0,x.jsx)(`span`,{className:`skeleton__shimmer`})})}var ye={error:`danger`,warning:`warning`,info:`accent`};function R(e){let t=e.tone??`error`;return(0,x.jsxs)(`section`,{className:`ds-banner`,"data-tone":t,role:t===`info`?`status`:`alert`,"data-testid":e.testId,ref:e=>{let t=e?.querySelector(`.error-state`);t?.removeAttribute(`role`),t?.removeAttribute(`aria-live`),e?.querySelector(`.error-state__title`)?.setAttribute(`role`,`none`)},children:[(0,x.jsx)(_e,{tone:ye[t],title:e.title,message:e.body,showIcon:!1}),e.action]})}function be(e){return(0,x.jsxs)(`div`,{className:`ds-loading`,role:`status`,children:[(0,x.jsx)(`p`,{className:`ds-loading__label`,children:e.label}),(0,x.jsx)(`div`,{className:`ds-loading__shapes`,"aria-hidden":`true`,children:Array.from({length:e.rows??3},(e,t)=>(0,x.jsx)(ve,{decorative:!0,width:`100%`,height:`20px`},t))})]})}var xe=(0,_.createContext)(!1),Se=m();function Ce({value:e,onChange:t,onBlur:n,options:r,label:i,placeholder:a=`Select...`,disabled:o=!1,size:s=`default`,fullWidth:c=!1,className:l=``,searchable:u=!1,searchPlaceholder:d,"aria-label":f,"aria-describedby":p,invalid:m=!1,noOptionsLabel:h=`No options`}){let[g,v]=(0,_.useState)(!1),[y,b]=(0,_.useState)(-1),[S,C]=(0,_.useState)(``),[w,T]=(0,_.useState)({top:0,left:0,width:0}),E=(0,_.useRef)(null),D=(0,_.useRef)(null),O=(0,_.useRef)(null),k=(0,_.useRef)(null),ee=(0,_.useRef)([]),A=(0,_.useId)(),te=(0,_.useId)(),ne=(0,_.useId)(),j=i!=null&&i!==!1,M=r.find(t=>t.value===e),N=(0,_.useMemo)(()=>{let e=S.trim().toLowerCase();return!u||e.length===0?r:r.filter(t=>[t.label,t.value,t.description??``].some(t=>t.toLowerCase().includes(e)))},[r,S,u]),re=(0,_.useCallback)((e,t)=>{for(let n=e;n>=0&&n`${te}-option-${String(e)}`,ae=y>=0?ie(y):void 0,oe=(0,_.useCallback)(()=>{if(!D.current)return;let e=D.current.getBoundingClientRect();T({top:e.bottom+4,left:e.left,width:e.width})},[]),se=(0,_.useCallback)(()=>{if(o)return;oe(),v(!0);let t=N.findIndex(t=>t.value===e&&!t.disabled);b(t===-1?re(0,1):t)},[o,N,e,oe,re]),ce=(0,_.useCallback)(()=>{v(!1),b(-1),C(``),D.current?.focus()},[]),P=(0,_.useCallback)((e,n)=>{n&&(n.stopPropagation(),n.preventDefault()),!e.disabled&&(t(e.value),ce())},[t,ce]);(0,_.useEffect)(()=>{let e=e=>{if(!g)return;let t=e.target,n=E.current&&!E.current.contains(t),r=O.current&&!O.current.contains(t);n&&r&&ce()},t=e=>{e.key===`Escape`&&g&&ce()};return g&&(document.addEventListener(`mousedown`,e),document.addEventListener(`keydown`,t)),()=>{document.removeEventListener(`mousedown`,e),document.removeEventListener(`keydown`,t)}},[g,ce]),(0,_.useEffect)(()=>{if(!g)return;let e=()=>{oe()};return window.addEventListener(`resize`,e),window.addEventListener(`scroll`,e,!0),()=>{window.removeEventListener(`resize`,e),window.removeEventListener(`scroll`,e,!0)}},[g,oe]),(0,_.useEffect)(()=>{g&&u&&k.current?.focus()},[g,u]),(0,_.useEffect)(()=>{if(!g||!u)return;ee.current=[];let t=N.findIndex(t=>t.value===e&&!t.disabled);b(t>=0?t:re(0,1))},[g,S,u,e,N,re]);let F=(0,_.useCallback)(e=>{if(!o)switch(e.key){case`Enter`:case` `:if(e.preventDefault(),g){let e=N[y];e&&P(e)}else se();break;case`Escape`:e.preventDefault(),g&&ce();break;case`ArrowDown`:if(e.preventDefault(),!g)se();else{let e=re(y+1,1);e>=0&&b(e)}break;case`ArrowUp`:if(e.preventDefault(),g){let e=re(y-1,-1);e>=0&&b(e)}break;case`Tab`:g&&ce()}},[o,g,y,N,re,se,ce,P]),le=(0,_.useCallback)(e=>{switch(e.key){case`Enter`:{e.preventDefault();let t=N[y];t&&P(t);break}case`Escape`:e.preventDefault(),e.stopPropagation(),ce();break;case`ArrowDown`:e.preventDefault(),b(e=>{let t=re(e+1,1);return t>=0?t:e});break;case`ArrowUp`:e.preventDefault(),b(e=>{let t=re(e-1,-1);return t>=0?t:e});break;case`Tab`:ce()}},[ce,y,P,N,re]);(0,_.useEffect)(()=>{let e=ee.current[y];g&&y>=0&&e&&e.scrollIntoView({block:`nearest`,behavior:`smooth`})},[g,y]);let ue=s==="default"?``:`select--${s}`,de=c?`select--full-width`:``,fe=j?`select--labelled`:``,pe=j?ne:void 0,me=d??f;return(0,x.jsxs)(`div`,{ref:E,className:`select ${ue} ${de} ${fe} ${g?`select--open`:``} ${o?`select--disabled`:``} ${l}`,children:[j&&(0,x.jsx)(`span`,{className:`select__label`,id:ne,children:i}),(0,x.jsxs)(`button`,{ref:D,type:`button`,className:`select__trigger`,onClick:()=>{g?ce():se()},onKeyDown:F,onBlur:n,disabled:o,"aria-haspopup":`listbox`,"aria-expanded":g,"aria-controls":g?A:void 0,"aria-activedescendant":g?ae:void 0,"aria-label":f,"aria-labelledby":pe,"aria-describedby":p,"aria-invalid":m||void 0,children:[M?(0,x.jsxs)(`span`,{className:`select__value`,children:[M.icon&&(0,x.jsx)(`span`,{className:`select__value-icon`,children:M.icon}),(0,x.jsx)(`span`,{className:`select__value-label`,children:M.label})]}):(0,x.jsx)(`span`,{className:`select__placeholder`,children:a}),(0,x.jsx)(`span`,{className:`select__chevron ${g?`select__chevron--open`:``}`,children:(0,x.jsx)(`svg`,{width:`10`,height:`6`,viewBox:`0 0 10 6`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,children:(0,x.jsx)(`path`,{d:`M1 1L5 5L9 1`,stroke:`currentColor`,strokeWidth:`1.5`,strokeLinecap:`round`,strokeLinejoin:`round`})})})]}),g&&(0,Se.createPortal)((0,x.jsxs)(`div`,{ref:O,className:`select__dropdown select__dropdown--portal`,style:{position:`fixed`,top:`${String(w.top)}px`,left:`${String(w.left)}px`,width:`${String(w.width)}px`},children:[u&&(0,x.jsx)(`div`,{className:`select__search`,children:(0,x.jsx)(`input`,{ref:k,className:`select__search-input`,type:`search`,value:S,onChange:e=>C(e.currentTarget.value),onKeyDown:le,placeholder:d,"aria-label":me,"aria-labelledby":me?void 0:pe,"aria-controls":A,"aria-activedescendant":ae,autoComplete:`off`,spellCheck:!1})}),(0,x.jsx)(`div`,{className:`select__options`,role:`listbox`,id:A,"aria-label":f,"aria-labelledby":pe,children:N.length===0?(0,x.jsx)(`div`,{className:`select__empty`,children:h}):N.map((t,n)=>(0,x.jsxs)(`div`,{id:ie(n),ref:e=>{ee.current[n]=e},className:`select__option ${t.value===e?`select__option--selected`:``} ${n===y?`select__option--focused`:``} ${t.disabled?`select__option--disabled`:``}`,role:`option`,"aria-selected":t.value===e,"aria-disabled":t.disabled||void 0,"aria-label":t.description?t.label+`. `+t.description:void 0,onClick:e=>{P(t,e)},onMouseEnter:()=>{t.disabled||b(n)},children:[t.icon&&(0,x.jsx)(`span`,{className:`select__option-icon`,children:t.icon}),(0,x.jsxs)(`div`,{className:`select__option-content`,children:[(0,x.jsx)(`span`,{className:`select__option-label`,children:t.label}),t.description&&(0,x.jsx)(`span`,{className:`select__option-description`,children:t.description})]}),t.value===e&&(0,x.jsx)(`span`,{className:`select__option-check`,children:(0,x.jsx)(`svg`,{width:`14`,height:`10`,viewBox:`0 0 14 10`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,children:(0,x.jsx)(`path`,{d:`M1 5L5 9L13 1`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`})})})]},t.value))})]}),document.body)]})}var we=[{key:`models.library.subtitle`,en:`Inspect local checkpoints. Selecting never loads a model.`,ko:`로컬 체크포인트를 확인하세요. 선택만으로 모델을 로드하지 않습니다.`,test_id:`models-library-subtitle`},{key:`models.library.search`,en:`Search local models`,ko:`로컬 모델 검색`,test_id:`models-library-search`},{key:`models.library.source`,en:`Source`,ko:`소스`,test_id:`models-library-source`},{key:`models.library.task`,en:`Task`,ko:`작업`,test_id:`models-library-task`},{key:`models.library.status`,en:`Lifecycle`,ko:`수명주기`,test_id:`models-library-status`},{key:`models.library.sort`,en:`Sort`,ko:`정렬`,test_id:`models-library-sort`},{key:`models.library.name`,en:`Model`,ko:`모델`,test_id:`models-library-name`},{key:`models.library.all`,en:`All`,ko:`전체`,test_id:`models-library-all`},{key:`models.library.add`,en:`Add Model`,ko:`모델 추가`,test_id:`models-library-add`},{key:`models.library.rescan`,en:`Rescan local roots`,ko:`로컬 경로 다시 검색`,test_id:`models-library-rescan`},{key:`models.library.refresh`,en:`Refresh server state`,ko:`서버 상태 새로고침`,test_id:`models-library-refresh`},{key:`models.library.roots`,en:`Configured roots`,ko:`설정된 경로`,test_id:`models-library-roots`},{key:`models.library.roots_help`,en:`To change roots, restart the server with your local directory. This command is an example, not an executed action.`,ko:`경로를 변경하려면 로컬 디렉터리를 지정하여 서버를 다시 시작하세요. 아래 명령은 예시이며 자동 실행되지 않습니다.`,test_id:`models-library-roots-help`},{key:`models.library.single`,en:`Single-model mode: lifecycle and cache changes are read-only. Restart without -m to manage models.`,ko:`단일 모델 모드: 수명주기 및 캐시는 읽기 전용입니다. 모델을 관리하려면 -m 없이 다시 시작하세요.`,test_id:`models-library-single`},{key:`models.library.unknown`,en:`Unknown`,ko:`알 수 없음`,test_id:`models-library-unknown`},{key:`models.library.yes`,en:`Yes`,ko:`예`,test_id:`models-library-yes`},{key:`models.library.no`,en:`No`,ko:`아니요`,test_id:`models-library-no`},{key:`models.library.inspect`,en:`Inspect {name}`,ko:`{name} 자세히 보기`,test_id:`models-library-inspect`},{key:`models.library.selected`,en:`Selected`,ko:`선택됨`,test_id:`models-library-selected`},{key:`models.library.details`,en:`Model details`,ko:`모델 상세`,test_id:`models-library-details`},{key:`models.library.support`,en:`Support / completeness`,ko:`지원 / 완전성`,test_id:`models-library-support`},{key:`models.library.supported`,en:`Supported architecture`,ko:`지원되는 아키텍처`,test_id:`models-library-supported`},{key:`models.library.unsupported`,en:`Unsupported architecture`,ko:`지원되지 않는 아키텍처`,test_id:`models-library-unsupported`},{key:`models.library.complete`,en:`Complete files`,ko:`파일 완전함`,test_id:`models-library-complete`},{key:`models.library.incomplete`,en:`Incomplete files`,ko:`불완전한 파일`,test_id:`models-library-incomplete`},{key:`models.library.architecture`,en:`Architecture`,ko:`아키텍처`,test_id:`models-library-architecture`},{key:`models.library.backend`,en:`Runnable on this backend`,ko:`현재 백엔드 실행 가능`,test_id:`models-library-backend`},{key:`models.library.tested`,en:`Checkpoint validated`,ko:`검증된 체크포인트`,test_id:`models-library-tested`},{key:`models.library.tested_help`,en:`Family support does not prove this checkpoint was tested.`,ko:`계열 지원은 해당 체크포인트의 검증을 의미하지 않습니다.`,test_id:`models-library-tested-help`},{key:`models.library.disk`,en:`Disk size`,ko:`디스크 크기`,test_id:`models-library-disk`},{key:`models.library.memory`,en:`Estimated memory (not measured)`,ko:`예상 메모리 (측정값 아님)`,test_id:`models-library-memory`},{key:`models.library.context`,en:`Effective context (tokens)`,ko:`실제 컨텍스트 (토큰)`,test_id:`models-library-context`},{key:`models.library.profile`,en:`Next-load profile`,ko:`다음 로드 프로필`,test_id:`models-library-profile`},{key:`models.library.defaults`,en:`Server defaults; see Settings for scope and overrides.`,ko:`서버 기본값입니다. 범위와 재정의는 설정에서 확인하세요.`,test_id:`models-library-defaults`},{key:`models.library.error`,en:`Action could not complete`,ko:`작업을 완료하지 못함`,test_id:`models-library-error`},{key:`models.library.last_error`,en:`Last server error`,ko:`최근 서버 오류`,test_id:`models-library-last-error`},{key:`models.library.chat`,en:`Use in Chat`,ko:`채팅에서 사용`,test_id:`models-library-chat`},{key:`models.library.chat_reason`,en:`Chat requires a ready provider with an available chat capability. Other tasks remain available through their API.`,ko:`채팅에는 준비된 제공자와 사용 가능한 채팅 기능이 필요합니다. 다른 작업은 API로 사용하세요.`,test_id:`models-library-chat-reason`},{key:`models.library.api`,en:`API task documentation`,ko:`API 작업 문서`,test_id:`models-library-api`},{key:`models.library.delete`,en:`Delete cached files`,ko:`캐시 파일 삭제`,test_id:`models-library-delete`},{key:`models.library.delete_body`,en:`Permanently delete the managed cache entry {name} ({source}). This removes files from disk, unlike Unload. To confirm, type the model ID shown below, not the model name.`,ko:`관리 캐시 항목 {name} ({source})을 영구 삭제합니다. 언로드와 달리 디스크 파일을 제거합니다. 확인하려면 모델 이름이 아니라 아래에 표시된 모델 ID를 입력하세요.`,test_id:`models-library-delete-body`},{key:`models.library.confirm_name`,en:`Opaque model ID shown above (starts with mdl_)`,ko:`위에 표시된 모델 ID (mdl_로 시작)`,test_id:`models-library-confirm-name`},{key:`models.library.unload_body`,en:`Unload {name} ({source}): {count} active requests must drain before the worker exits. Files remain on disk. A timeout is a failure, not a completed unload.`,ko:`{name} ({source}) 언로드: 활성 요청 {count}개를 배출한 뒤 작업자가 종료됩니다. 디스크 파일은 유지됩니다. 시간 초과는 완료가 아닌 실패입니다.`,test_id:`models-library-unload-body`},{key:`models.library.confirm`,en:`Confirm`,ko:`확인`,test_id:`models-library-confirm`},{key:`models.library.cancel`,en:`Cancel`,ko:`취소`,test_id:`models-library-cancel`},{key:`models.library.repo`,en:`Public HuggingFace repo ID`,ko:`공개 HuggingFace 저장소 ID`,test_id:`models-library-repo`},{key:`models.library.revision`,en:`Revision (optional)`,ko:`리비전 (선택)`,test_id:`models-library-revision`},{key:`models.library.network`,en:`Only this explicit action contacts HuggingFace. Files go to the server-managed cache below. Size is unknown until the server resolves file metadata. Search never contacts external services.`,ko:`이 작업을 명시적으로 실행할 때만 HuggingFace에 연결합니다. 파일은 아래 서버 관리 캐시에 저장됩니다. 크기는 서버가 파일 메타데이터를 확인할 때까지 알 수 없습니다. 검색은 외부 서비스에 연결하지 않습니다.`,test_id:`models-library-network`},{key:`models.library.public`,en:`This is a public, ungated repository`,ko:`공개된 비게이트 저장소입니다`,test_id:`models-library-public`},{key:`models.library.private`,en:`Private or gated downloads are unavailable in the WebUI. Use an authenticated HuggingFace CLI outside the server, then rescan a configured local root. Do not paste credentials here.`,ko:`비공개 또는 게이트 다운로드는 WebUI에서 지원하지 않습니다. 서버 외부에서 인증된 HuggingFace CLI를 사용한 뒤 설정된 로컬 경로를 다시 검색하세요. 여기에 인증 정보를 입력하지 마세요.`,test_id:`models-library-private`},{key:`models.library.repo_invalid`,en:`Enter owner/repository, not a URL or a local path.`,ko:`URL이나 로컬 경로가 아닌 소유자/저장소를 입력하세요.`,test_id:`models-library-repo-invalid`},{key:`models.library.operations`,en:`Library operations`,ko:`라이브러리 작업`,test_id:`models-library-operations`},{key:`models.library.pending`,en:`Request outcome is being reconciled. Do not resubmit; refresh to observe the server operation.`,ko:`요청 결과를 확인하고 있습니다. 재제출하지 말고 새로고침하여 서버 작업을 확인하세요.`,test_id:`models-library-pending`},{key:`models.library.retry_download`,en:`Retry download`,ko:`다운로드 재시도`,test_id:`models-library-retry-download`},{key:`models.library.cancel_download`,en:`Cancel download`,ko:`다운로드 취소`,test_id:`models-library-cancel-download`},{key:`models.library.cancel_body`,en:`Cancel the download of {name}? Unpublished partial files are not a usable model.`,ko:`{name} 다운로드를 취소할까요? 공개되지 않은 부분 파일은 사용할 수 있는 모델이 아닙니다.`,test_id:`models-library-cancel-body`},{key:`models.library.progress`,en:`Download progress`,ko:`다운로드 진행률`,test_id:`models-library-progress`},{key:`models.library.worker`,en:`Worker exit observed`,ko:`작업자 종료 확인`,test_id:`models-library-worker`},{key:`models.library.stale`,en:`State changed or is not current. Refresh, inspect the latest revision, and explicitly confirm again.`,ko:`상태가 변경되었거나 최신이 아닙니다. 새로고침하고 최신 리비전을 확인한 뒤 다시 명시적으로 확인하세요.`,test_id:`models-library-stale`},{key:`models.library.capacity`,en:`Capacity / conflicting operation`,ko:`용량 / 작업 충돌`,test_id:`models-library-capacity`},{key:`models.library.capacity_body`,en:`Do not repeatedly load. Review active models below. If capacity is full, explicitly choose an idle ready model to unload before this load. Busy models are never offered as eviction targets. Eviction is not rolled back if the new load fails.`,ko:`반복해서 로드하지 마세요. 아래 활성 모델을 확인하세요. 용량이 가득 차면 이번 로드 전에 언로드할 유휴 준비 모델을 명시적으로 선택하세요. 사용 중인 모델은 교체 대상으로 제공되지 않습니다. 새 로드 실패 시 교체는 되돌려지지 않습니다.`,test_id:`models-library-capacity-body`},{key:`models.library.eviction`,en:`Explicit eviction target`,ko:`명시적 교체 대상`,test_id:`models-library-eviction`},{key:`models.library.choose`,en:`Choose a model`,ko:`모델 선택`,test_id:`models-library-choose`},{key:`models.library.evict_load`,en:`Unload target and load`,ko:`대상 언로드 후 로드`,test_id:`models-library-evict-load`},{key:`models.library.active`,en:`Active requests`,ko:`활성 요청`,test_id:`models-library-active`},{key:`models.library.page`,en:`Page {page} of {pages} · {count} models`,ko:`{pages}페이지 중 {page} · 모델 {count}개`,test_id:`models-library-page`},{key:`models.library.previous`,en:`Previous page`,ko:`이전 페이지`,test_id:`models-library-previous`},{key:`models.library.next`,en:`Next page`,ko:`다음 페이지`,test_id:`models-library-next`},{key:`models.library.filtered`,en:`No matching local models`,ko:`일치하는 로컬 모델 없음`,test_id:`models-library-filtered`},{key:`models.library.filtered_body`,en:`Change the local search or filters.`,ko:`로컬 검색어나 필터를 변경하세요.`,test_id:`models-library-filtered-body`},{key:`models.library.waiting`,en:`Waiting for an authoritative catalog snapshot`,ko:`서버의 카탈로그 스냅샷을 기다리는 중`,test_id:`models-library-waiting`},{key:`models.library.sort_name`,en:`Name (A–Z)`,ko:`이름 (오름차순)`,test_id:`models-library-sort-name`},{key:`models.library.sort_status`,en:`Lifecycle`,ko:`수명주기`,test_id:`models-library-sort-status`},{key:`models.library.sort_source`,en:`Source`,ko:`소스`,test_id:`models-library-sort-source`},{key:`models.library.sort_task`,en:`Task`,ko:`작업`,test_id:`models-library-sort-task`},{key:`models.library.unavailable`,en:`Not available for this server or model`,ko:`현재 서버 또는 모델에서 사용할 수 없음`,test_id:`models-library-unavailable`},{key:`models.library.permission`,en:`Root could not be read. Check server directory permissions, then rescan.`,ko:`경로를 읽지 못했습니다. 서버 디렉터리 권한을 확인한 뒤 다시 검색하세요.`,test_id:`models-library-permission`},{key:`models.library.copy`,en:`Copy command`,ko:`명령 복사`,test_id:`models-library-copy`},{key:`models.library.copied`,en:`Copied`,ko:`복사됨`,test_id:`models-library-copied`},{key:`models.library.copy_failed`,en:`Select and copy the command below.`,ko:`아래 명령을 선택하여 복사하세요.`,test_id:`models-library-copy-failed`},{key:`models.library.accepted`,en:`Accepted; waiting for observed server state.`,ko:`접수됨. 서버에서 관측된 상태를 기다리는 중입니다.`,test_id:`models-library-accepted`},{key:`models.library.operation_state`,en:`Operation state`,ko:`작업 상태`,test_id:`models-library-operation-state`}],Te=[{key:`chat.eyebrow`,en:`Local inference`,ko:`로컬 추론`,test_id:`chat-eyebrow`},{key:`chat.intro`,en:`Memory-only by default. Changing the model affects the next turn, never the running request.`,ko:`기본적으로 메모리에만 보관합니다. 모델을 바꾸면 다음 턴에만 적용되며 실행 중인 요청은 바뀌지 않습니다.`,test_id:`chat-intro`},{key:`chat.new_conversation`,en:`New conversation`,ko:`새 대화`,test_id:`chat-new-conversation`},{key:`chat.conversation.default_title`,en:`New conversation`,ko:`새 대화`,test_id:`chat-conversation-default-title`},{key:`chat.conversation.label`,en:`Conversation`,ko:`대화`,test_id:`chat-conversation-label`},{key:`chat.conversation.choose`,en:`Choose conversation`,ko:`대화 선택`,test_id:`chat-conversation-choose`},{key:`chat.model.label`,en:`Model for next turn`,ko:`다음 턴에 사용할 모델`,test_id:`chat-model-label`},{key:`chat.model.choose`,en:`Select a model`,ko:`모델 선택`,test_id:`chat-model-choose`},{key:`chat.no_model.title`,en:`Choose a ready chat model`,ko:`준비된 대화 모델을 선택하세요`,test_id:`chat-no-model-title`},{key:`chat.no_model.body`,en:`Selection never loads a model. Load one explicitly in Models. Embeddings, reranking and other tasks use their documented API, not this composer.`,ko:`선택만으로 모델을 로드하지 않습니다. 모델 화면에서 명시적으로 로드하세요. 임베딩, 재순위화 등 다른 작업은 이 입력창이 아니라 문서화된 API를 사용합니다.`,test_id:`chat-no-model-body`},{key:`chat.no_model.action`,en:`Open Models`,ko:`모델 화면 열기`,test_id:`chat-no-model-action`},{key:`chat.settings.summary`,en:`Conversation settings`,ko:`대화 설정`,test_id:`chat-settings-summary`},{key:`chat.settings.name`,en:`Conversation name`,ko:`대화 이름`,test_id:`chat-settings-name`},{key:`chat.settings.system_prompt`,en:`System prompt`,ko:`시스템 프롬프트`,test_id:`chat-settings-system-prompt`},{key:`chat.settings.sampling`,en:`Sampling defaults are set in {link} and frozen when sending.`,ko:`샘플링 기본값은 {link}에서 지정하며 전송할 때 고정됩니다.`,test_id:`chat-settings-sampling`},{key:`chat.settings.delete`,en:`Delete conversation`,ko:`대화 삭제`,test_id:`chat-settings-delete`},{key:`chat.composer.label`,en:`Message`,ko:`메시지`,test_id:`chat-composer-label`},{key:`chat.composer.hint`,en:`Enter sends · Shift+Enter inserts a line. {count}/{max} characters.`,ko:`Enter로 보내고 Shift+Enter로 줄을 바꿉니다. {count}/{max}자.`,test_id:`chat-composer-hint`},{key:`chat.images.label`,en:`Local images`,ko:`로컬 이미지`,test_id:`chat-images-label`},{key:`chat.images.unsupported`,en:`Image attachments require provider-confirmed vision support.`,ko:`이미지를 첨부하려면 provider가 확인한 비전 지원이 필요합니다.`,test_id:`chat-images-unsupported`},{key:`chat.images.remove`,en:`Remove {name}`,ko:`{name} 제거`,test_id:`chat-images-remove`},{key:`chat.stop`,en:`Stop`,ko:`중지`,test_id:`chat-stop`},{key:`chat.error.title`,en:`Chat could not continue`,ko:`대화를 계속할 수 없습니다`,test_id:`chat-error-title`},{key:`chat.error.view_closed`,en:`View closed. The request was aborted and was not retried.`,ko:`화면을 닫았습니다. 요청을 중단했으며 다시 시도하지 않았습니다.`,test_id:`chat-error-view-closed`},{key:`chat.error.vision_unsupported`,en:`The selected provider does not confirm vision support. Remove images or select a vision model.`,ko:`선택한 provider가 비전 지원을 확인하지 않습니다. 이미지를 제거하거나 비전 모델을 선택하세요.`,test_id:`chat-error-vision-unsupported`},{key:`chat.error.conversation_limit`,en:`Conversation limit reached. Delete or export older conversations first.`,ko:`대화 개수 한도에 도달했습니다. 먼저 이전 대화를 삭제하거나 내보내세요.`,test_id:`chat-error-conversation-limit`},{key:`chat.error.invalid_parameters`,en:`Invalid next-turn parameters.`,ko:`다음 턴 매개변수가 올바르지 않습니다.`,test_id:`chat-error-invalid-parameters`},{key:`chat.error.turn_limit`,en:`This conversation reached its 100-turn limit. Start a new conversation.`,ko:`이 대화는 100턴 한도에 도달했습니다. 새 대화를 시작하세요.`,test_id:`chat-error-turn-limit`},{key:`chat.error.images_exceed`,en:`Conversation images exceed the current server count, size or decode limits. Remove attachments or start a new conversation.`,ko:`대화 이미지가 현재 서버의 개수, 크기 또는 디코드 한도를 넘습니다. 첨부를 제거하거나 새 대화를 시작하세요.`,test_id:`chat-error-images-exceed`},{key:`chat.error.body_limit`,en:`The complete request exceeds the server or 16 MiB browser JSON body limit. Remove attachments or start a shorter conversation.`,ko:`전체 요청이 서버 또는 16 MiB 브라우저 JSON 본문 한도를 넘습니다. 첨부를 제거하거나 더 짧은 대화를 시작하세요.`,test_id:`chat-error-body-limit`},{key:`chat.error.memory_budget`,en:`Conversation memory budget reached. Export and clear older history first.`,ko:`대화 메모리 예산에 도달했습니다. 먼저 이전 기록을 내보내고 지우세요.`,test_id:`chat-error-memory-budget`},{key:`chat.error.memory_budget_stream`,en:`Conversation memory budget reached. No further output was retained.`,ko:`대화 메모리 예산에 도달했습니다. 이후 출력은 보존하지 않았습니다.`,test_id:`chat-error-memory-budget-stream`},{key:`chat.error.generation_failed`,en:`Generation failed or disconnected. Partial output is preserved. Check context limits, authentication and server availability; nothing was retried.`,ko:`생성에 실패했거나 연결이 끊겼습니다. 부분 출력은 보존됩니다. 컨텍스트 한도, 인증, 서버 상태를 확인하세요. 자동으로 다시 시도하지 않았습니다.`,test_id:`chat-error-generation-failed`},{key:`chat.error.images_invalid`,en:`Images must be bounded local PNG, JPEG or WebP files. No URL, SVG or HTML input is accepted.`,ko:`이미지는 크기 한도 안의 로컬 PNG, JPEG 또는 WebP 파일이어야 합니다. URL, SVG, HTML 입력은 허용하지 않습니다.`,test_id:`chat-error-images-invalid`},{key:`chat.announce.stopped`,en:`Stopped locally; checking server activity.`,ko:`로컬에서 중지했습니다. 서버 활동을 확인하는 중입니다.`,test_id:`chat-announce-stopped`},{key:`chat.announce.aborted_observed`,en:`Request aborted. Server observation refreshed at {time}. See Activity for active requests; this is not a per-request cancellation receipt.`,ko:`요청을 중단했습니다. 서버 관측값을 {time}에 새로 고쳤습니다. 활성 요청은 활동 화면에서 확인하세요. 이 메시지는 요청별 취소 확인이 아닙니다.`,test_id:`chat-announce-aborted-observed`},{key:`chat.announce.unknown_time`,en:`an unknown time`,ko:`알 수 없는 시각`,test_id:`chat-announce-unknown-time`},{key:`chat.announce.aborted_unobserved`,en:`Request aborted. Backend cancellation could not be observed; inspect Activity before unloading.`,ko:`요청을 중단했습니다. 백엔드 취소를 확인할 수 없으니 언로드하기 전에 활동 화면을 확인하세요.`,test_id:`chat-announce-aborted-unobserved`},{key:`chat.announce.generating`,en:`Generating.`,ko:`생성하는 중입니다.`,test_id:`chat-announce-generating`},{key:`chat.announce.complete`,en:`Response complete.`,ko:`응답이 완료되었습니다.`,test_id:`chat-announce-complete`},{key:`chat.announce.failed`,en:`Generation failed; partial response preserved.`,ko:`생성에 실패했습니다. 부분 응답은 보존됩니다.`,test_id:`chat-announce-failed`},{key:`chat.transcript.label`,en:`Conversation transcript`,ko:`대화 기록`,test_id:`chat-transcript-label`},{key:`chat.transcript.empty`,en:`No messages yet. Start with a prompt after loading a model.`,ko:`아직 메시지가 없습니다. 모델을 로드한 뒤 프롬프트를 입력해 시작하세요.`,test_id:`chat-transcript-empty`},{key:`chat.transcript.jump`,en:`Jump to latest`,ko:`최신 메시지로 이동`,test_id:`chat-transcript-jump`},{key:`chat.transcript.turn_label`,en:`Turn with {model}`,ko:`{model} 턴`,test_id:`chat-transcript-turn-label`},{key:`chat.transcript.status.streaming`,en:`Streaming`,ko:`스트리밍 중`,test_id:`chat-transcript-status-streaming`},{key:`chat.transcript.status.complete`,en:`Complete`,ko:`완료`,test_id:`chat-transcript-status-complete`},{key:`chat.transcript.status.cancelled`,en:`Cancelled`,ko:`취소됨`,test_id:`chat-transcript-status-cancelled`},{key:`chat.transcript.status.interrupted`,en:`Interrupted`,ko:`중단됨`,test_id:`chat-transcript-status-interrupted`},{key:`chat.transcript.status.error`,en:`Error`,ko:`오류`,test_id:`chat-transcript-status-error`},{key:`chat.transcript.images`,en:`{count} local image attachment(s)`,ko:`로컬 이미지 첨부 {count}개`,test_id:`chat-transcript-images`},{key:`chat.transcript.edit`,en:`Edit and regenerate`,ko:`편집 후 다시 생성`,test_id:`chat-transcript-edit`},{key:`chat.transcript.edit.confirm.title`,en:`Edit this prompt?`,ko:`이 프롬프트를 편집할까요?`,test_id:`chat-transcript-edit-confirm-title`},{key:`chat.transcript.edit.confirm.body`,en:`This response and all later turns in this conversation are discarded. The prompt returns to the composer.`,ko:`이 응답과 이 대화의 이후 모든 턴이 삭제됩니다. 프롬프트는 입력창으로 돌아갑니다.`,test_id:`chat-transcript-edit-confirm-body`},{key:`chat.transcript.edit.confirm`,en:`Discard and edit`,ko:`삭제하고 편집`,test_id:`chat-transcript-edit-confirm`},{key:`chat.transcript.reasoning_thinking`,en:`Reasoning · Thinking`,ko:`추론 · 생각하는 중`,test_id:`chat-transcript-reasoning-thinking`},{key:`chat.transcript.thinking`,en:`Thinking…`,ko:`생각하는 중…`,test_id:`chat-transcript-thinking`},{key:`chat.transcript.waiting`,en:`Waiting for response…`,ko:`응답을 기다리는 중…`,test_id:`chat-transcript-waiting`},{key:`chat.transcript.tool_call`,en:`Tool call: {name} (not executed)`,ko:`도구 호출: {name} (실행하지 않음)`,test_id:`chat-transcript-tool-call`},{key:`chat.transcript.tool_name_pending`,en:`Name pending`,ko:`이름 대기 중`,test_id:`chat-transcript-tool-name-pending`},{key:`chat.transcript.copy`,en:`Copy response`,ko:`응답 복사`,test_id:`chat-transcript-copy`},{key:`chat.transcript.copied`,en:`Copied response.`,ko:`응답을 복사했습니다.`,test_id:`chat-transcript-copied`},{key:`chat.transcript.copy_failed`,en:`Copy unavailable; select the response text instead.`,ko:`복사할 수 없습니다. 응답 텍스트를 직접 선택하세요.`,test_id:`chat-transcript-copy-failed`},{key:`chat.transcript.details`,en:`Response details`,ko:`응답 상세`,test_id:`chat-transcript-details`},{key:`chat.transcript.finish_reason`,en:`Finish reason`,ko:`종료 사유`,test_id:`chat-transcript-finish-reason`},{key:`chat.transcript.unknown`,en:`Unknown`,ko:`알 수 없음`,test_id:`chat-transcript-unknown`},{key:`chat.transcript.usage`,en:`Usage (server reported)`,ko:`사용량 (서버 보고)`,test_id:`chat-transcript-usage`},{key:`chat.transcript.usage_value`,en:`{prompt} prompt / {completion} completion / {total} total tokens`,ko:`프롬프트 {prompt} / 완성 {completion} / 전체 {total} 토큰`,test_id:`chat-transcript-usage-value`},{key:`chat.transcript.first_delta`,en:`First delta (client observed)`,ko:`첫 델타 (클라이언트 관측)`,test_id:`chat-transcript-first-delta`},{key:`chat.transcript.decode_rate`,en:`Decode rate (client estimate)`,ko:`디코드 속도 (클라이언트 추정)`,test_id:`chat-transcript-decode-rate`},{key:`chat.transcript.metrics_note`,en:`First delta measures send to first non-empty content, reasoning or tool delta, including transport. Decode rate uses reported completion tokens minus one over the remaining client-observed stream duration; it is not a server kernel metric.`,ko:`첫 델타는 전송부터 비어 있지 않은 첫 내용, 추론 또는 도구 델타까지의 시간이며 전송 구간을 포함합니다. 디코드 속도는 보고된 완성 토큰 수에서 1을 뺀 값을 클라이언트가 관측한 나머지 스트림 시간으로 나눈 값이며 서버 커널 지표가 아닙니다.`,test_id:`chat-transcript-metrics-note`},{key:`chat.params.summary`,en:`Parameters for next turn`,ko:`다음 턴 매개변수`,test_id:`chat-params-summary`},{key:`chat.params.body`,en:`These overrides apply once, after Send accepts a request. Blank fields inherit Settings; absent Settings fields inherit the server. Changes never affect a running turn.`,ko:`이 재정의 값은 보내기로 요청이 수락된 뒤 한 번만 적용됩니다. 빈 필드는 설정 값을, 설정에 없는 필드는 서버 값을 상속합니다. 실행 중인 턴에는 영향을 주지 않습니다.`,test_id:`chat-params-body`},{key:`chat.params.field`,en:`Next turn {name}`,ko:`다음 턴 {name}`,test_id:`chat-params-field`},{key:`chat.params.inherited`,en:`Inherited: {value}`,ko:`상속 값: {value}`,test_id:`chat-params-inherited`},{key:`chat.params.server_default`,en:`server default`,ko:`서버 기본값`,test_id:`chat-params-server-default`},{key:`chat.params.clear`,en:`Clear next-turn overrides`,ko:`다음 턴 재정의 지우기`,test_id:`chat-params-clear`},{key:`chat.privacy.summary`,en:`Local history and privacy`,ko:`로컬 기록과 개인정보`,test_id:`chat-privacy-summary`},{key:`chat.privacy.body`,en:`Conversations stay in memory unless you opt in below. Signing out or refreshing requires authentication again; saved history belongs to this browser origin, not a server account. No API keys are stored.`,ko:`아래에서 동의하지 않으면 대화는 메모리에만 남습니다. 로그아웃하거나 새로고침하면 다시 인증해야 합니다. 저장된 기록은 서버 계정이 아니라 이 브라우저 origin에 속합니다. API 키는 저장하지 않습니다.`,test_id:`chat-privacy-body`},{key:`chat.privacy.save`,en:`Save conversations on this device (IndexedDB)`,ko:`이 기기에 대화 저장 (IndexedDB)`,test_id:`chat-privacy-save`},{key:`chat.privacy.include_images`,en:`Also include attached image bytes in saved history and exports (separate consent)`,ko:`저장 기록과 내보내기에 첨부 이미지 바이트도 포함 (별도 동의)`,test_id:`chat-privacy-include-images`},{key:`chat.privacy.note`,en:`Turning saving off stops future writes; use Clear All to remove previously saved history. Re-enable explicitly after refresh to read it.`,ko:`저장을 끄면 이후 쓰기만 멈춥니다. 이미 저장된 기록은 모두 지우기로 삭제하세요. 새로고침 후 기록을 읽으려면 다시 명시적으로 켜세요.`,test_id:`chat-privacy-note`},{key:`chat.privacy.export`,en:`Export JSON`,ko:`JSON 내보내기`,test_id:`chat-privacy-export`},{key:`chat.privacy.export_failed`,en:`Export exceeds the bounded history size or contains unsupported data.`,ko:`내보내기가 기록 크기 한도를 넘거나 지원하지 않는 데이터를 포함합니다.`,test_id:`chat-privacy-export-failed`},{key:`chat.privacy.clear`,en:`Clear All`,ko:`모두 지우기`,test_id:`chat-privacy-clear`},{key:`chat.privacy.cleared`,en:`All history cleared.`,ko:`모든 기록을 지웠습니다.`,test_id:`chat-privacy-cleared`},{key:`chat.privacy.clear_failed`,en:`Stored history could not be cleared. Check browser storage permissions; no success is claimed.`,ko:`저장된 기록을 지우지 못했습니다. 브라우저 저장소 권한을 확인하세요. 성공으로 처리하지 않았습니다.`,test_id:`chat-privacy-clear-failed`},{key:`chat.privacy.import`,en:`Import conversation JSON (replaces current history)`,ko:`대화 JSON 가져오기 (현재 기록을 대체)`,test_id:`chat-privacy-import`},{key:`chat.privacy.import_too_large`,en:`Import exceeds 16 MiB.`,ko:`가져오기가 16 MiB를 넘습니다.`,test_id:`chat-privacy-import-too-large`},{key:`chat.privacy.import_rejected`,en:`Import rejected: unsupported version, invalid data or exceeded limits.`,ko:`가져오기를 거부했습니다. 지원하지 않는 버전, 잘못된 데이터 또는 한도 초과입니다.`,test_id:`chat-privacy-import-rejected`},{key:`chat.privacy.save_failed`,en:`History was not saved. Storage may be full or unavailable; export your conversation.`,ko:`기록을 저장하지 못했습니다. 저장소가 가득 찼거나 사용할 수 없을 수 있으니 대화를 내보내세요.`,test_id:`chat-privacy-save-failed`},{key:`chat.privacy.open_failed`,en:`Local history could not be opened or its images failed validation. Nothing was saved.`,ko:`로컬 기록을 열 수 없거나 이미지 검증에 실패했습니다. 아무것도 저장하지 않았습니다.`,test_id:`chat-privacy-open-failed`},{key:`chat.privacy.title`,en:`Local history`,ko:`로컬 기록`,test_id:`chat-privacy-title`},{key:`chat.privacy.replace_saved.confirm.title`,en:`Replace the in-memory conversations with saved history?`,ko:`메모리의 대화를 저장된 기록으로 바꿀까요?`,test_id:`chat-privacy-replace-saved-confirm-title`},{key:`chat.privacy.replace_saved.confirm.body`,en:`The conversations in memory are discarded and replaced by the saved history. Export current conversations first if needed.`,ko:`메모리의 대화는 삭제되고 저장된 기록으로 대체됩니다. 필요하면 먼저 현재 대화를 내보내세요.`,test_id:`chat-privacy-replace-saved-confirm-body`},{key:`chat.privacy.replace_saved.confirm`,en:`Replace with saved history`,ko:`저장된 기록으로 바꾸기`,test_id:`chat-privacy-replace-saved-confirm`},{key:`chat.privacy.clear.confirm.title`,en:`Delete all in-memory and saved conversations for this browser origin?`,ko:`이 브라우저 origin의 메모리 대화와 저장된 대화를 모두 삭제할까요?`,test_id:`chat-privacy-clear-confirm-title`},{key:`chat.privacy.clear.confirm`,en:`Delete all history`,ko:`모든 기록 삭제`,test_id:`chat-privacy-clear-confirm`},{key:`chat.privacy.replace_import.confirm.title`,en:`Replace the current conversations with validated imported history?`,ko:`현재 대화를 검증된 가져온 기록으로 바꿀까요?`,test_id:`chat-privacy-replace-import-confirm-title`},{key:`chat.privacy.replace_import.confirm.body`,en:`The current conversations are discarded and replaced by the imported history. Export current conversations first if needed.`,ko:`현재 대화는 삭제되고 가져온 기록으로 대체됩니다. 필요하면 먼저 현재 대화를 내보내세요.`,test_id:`chat-privacy-replace-import-confirm-body`},{key:`chat.privacy.replace_import.confirm`,en:`Replace with imported history`,ko:`가져온 기록으로 바꾸기`,test_id:`chat-privacy-replace-import-confirm`}],Ee=[{key:`settings.server.privacy.title`,en:`Privacy · browser only`,ko:`개인정보 · 브라우저 전용`,test_id:`settings-server-privacy-title`},{key:`settings.server.privacy.body`,en:`Appearance and explicitly saved load profiles use this browser’s preferences. Request defaults stay in memory; API credentials and system prompts are never stored by Settings. Conversation history is controlled separately in Chat.`,ko:`모양과 명시적으로 저장한 로드 프로필은 브라우저 환경설정을 사용합니다. 요청 기본값은 메모리에만 유지하며 API 자격 증명과 시스템 프롬프트는 설정에서 저장하지 않습니다. 대화 기록은 채팅에서 별도로 관리합니다.`,test_id:`settings-server-privacy-body`},{key:`settings.server.unavailable.title`,en:`Server controls unavailable`,ko:`서버 제어 사용 불가`,test_id:`settings-server-unavailable-title`},{key:`settings.server.unavailable.body`,en:`Connect from Models or Chat, or refresh the connection before changing server settings. Browser appearance and request defaults remain available. Schema mismatch disables server controls.`,ko:`모델이나 채팅에서 연결하거나 연결을 새로 고친 후 서버 설정을 변경하세요. 브라우저 모양과 요청 기본값은 계속 사용할 수 있습니다. 스키마 불일치 시 서버 제어가 비활성화됩니다.`,test_id:`settings-server-unavailable-body`},{key:`settings.server.model`,en:`Selected model for settings`,ko:`설정 대상 모델`,test_id:`settings-server-model`},{key:`settings.server.model.none`,en:`No model selected`,ko:`선택한 모델 없음`,test_id:`settings-server-model-none`},{key:`settings.server.model.hint`,en:`Selection changes browser context only. It never loads, unloads or reroutes an existing request.`,ko:`선택은 브라우저 문맥만 변경하며 모델을 로드하거나 언로드하거나 기존 요청의 대상을 변경하지 않습니다.`,test_id:`settings-server-model-hint`},{key:`settings.server.context.title`,en:`Effective context · observed, not estimated`,ko:`실제 컨텍스트 · 추정이 아닌 관측값`,test_id:`settings-server-context-title`},{key:`settings.server.context.n_ctx`,en:`Per-slot context tokens (/props n_ctx)`,ko:`슬롯별 컨텍스트 토큰 (/props n_ctx)`,test_id:`settings-server-context-n-ctx`},{key:`settings.server.context.n_ctx_hint`,en:`Zero/missing is unknown; do not multiply this value into a shared-pool capacity. Unified KV remains separate work (#1815).`,ko:`0 또는 누락은 알 수 없음입니다. 이 값에 슬롯 수를 곱해 공유 풀 용량으로 간주하지 않습니다. 통합 KV는 별도 작업입니다 (#1815).`,test_id:`settings-server-context-n-ctx-hint`},{key:`settings.server.context.slots`,en:`Configured slots (/props total_slots)`,ko:`설정된 슬롯 (/props total_slots)`,test_id:`settings-server-context-slots`},{key:`settings.server.context.kv_mode`,en:`Active resolved KV cache mode (/props)`,ko:`현재 실제 KV 캐시 모드 (/props)`,test_id:`settings-server-context-kv-mode`},{key:`settings.server.context.geometry`,en:`Reported context geometry`,ko:`보고된 컨텍스트 구성`,test_id:`settings-server-context-geometry`},{key:`settings.server.context.geometry_unknown`,en:`Unknown / props disabled or unavailable`,ko:`알 수 없음 / props 비활성화 또는 사용 불가`,test_id:`settings-server-context-geometry-unknown`},{key:`settings.server.unknown`,en:`Unknown`,ko:`알 수 없음`,test_id:`settings-server-unknown`},{key:`settings.server.no_model.title`,en:`No ready model selected`,ko:`준비된 모델이 선택되지 않음`,test_id:`settings-server-no-model-title`},{key:`settings.server.no_model.body`,en:`Selection never loads a model. Load explicitly from Models to read live settings.`,ko:`모델 선택은 로드를 수행하지 않습니다. 모델 화면에서 명시적으로 로드하여 실시간 설정을 확인하세요.`,test_id:`settings-server-no-model-body`},{key:`settings.server.live_disabled.title`,en:`Live settings disabled by operator`,ko:`운영자가 실시간 설정을 비활성화함`,test_id:`settings-server-live-disabled-title`},{key:`settings.server.live_disabled.body`,en:`Restart with --settings to enable this endpoint. WebUI never enables settings, props, metrics or slots implicitly.`,ko:`엔드포인트를 활성화하려면 --settings로 재시작하세요. WebUI는 settings, props, metrics 또는 slots를 자동으로 활성화하지 않습니다.`,test_id:`settings-server-live-disabled-body`},{key:`settings.generation.title`,en:`Generation · next request`,ko:`생성 · 다음 요청`,test_id:`settings-generation-title`},{key:`settings.generation.body`,en:`These defaults stay in browser memory only. Blank fields are omitted and inherit server defaults. Existing turns are frozen; changing defaults never alters an in-flight request. System prompts belong to individual conversations in Chat and are not stored here.`,ko:`기본값은 브라우저 메모리에만 남습니다. 빈 필드는 생략되어 서버 기본값을 사용합니다. 진행 중인 요청은 변경되지 않습니다. 시스템 프롬프트는 채팅의 개별 대화에서 설정하며 여기에 저장하지 않습니다.`,test_id:`settings-generation-body`},{key:`settings.generation.current`,en:`Current next-request default: {value}`,ko:`현재 다음 요청 기본값: {value}`,test_id:`settings-generation-current`},{key:`settings.generation.inherit`,en:`inherit`,ko:`상속`,test_id:`settings-generation-inherit`},{key:`settings.generation.invalid`,en:`Invalid defaults`,ko:`잘못된 기본값`,test_id:`settings-generation-invalid`},{key:`settings.generation.error_title`,en:`Invalid request defaults`,ko:`잘못된 요청 기본값`,test_id:`settings-generation-error-title`},{key:`settings.generation.save`,en:`Save session defaults`,ko:`세션 기본값 저장`,test_id:`settings-generation-save`},{key:`settings.generation.reset_open`,en:`Reset request defaults…`,ko:`요청 기본값 초기화…`,test_id:`settings-generation-reset-open`},{key:`settings.generation.reasoning_label`,en:`Reasoning / structured output`,ko:`추론 / 구조화 출력`,test_id:`settings-generation-reasoning-label`},{key:`settings.generation.reasoning_value`,en:`Endpoint-specific controls are available only where explicitly supported in Chat.`,ko:`채팅에서 명시적으로 지원되는 엔드포인트에만 제공됩니다.`,test_id:`settings-generation-reasoning-value`},{key:`settings.generation.reasoning_hint`,en:`No unsupported parameters are sent.`,ko:`지원되지 않는 매개변수는 전송하지 않습니다.`,test_id:`settings-generation-reasoning-hint`},{key:`settings.generation.reset.title`,en:`Reset request defaults?`,ko:`요청 기본값을 초기화할까요?`,test_id:`settings-generation-reset-title`},{key:`settings.generation.reset.body`,en:`Only browser-session request defaults will be cleared. Server and next-load profiles remain unchanged.`,ko:`브라우저 세션 요청 기본값만 지워집니다. 서버와 다음 로드 프로필은 변경되지 않습니다.`,test_id:`settings-generation-reset-body`},{key:`settings.generation.reset.confirm`,en:`Reset request defaults`,ko:`요청 기본값 초기화`,test_id:`settings-generation-reset-confirm`},{key:`settings.live.title`,en:`Loaded model · live server values`,ko:`로드된 모델 · 실시간 서버 값`,test_id:`settings-live-title`},{key:`settings.live.body`,en:`Changes affect newly admitted requests. Fingerprints detect already-observed external changes, not atomic compare-and-swap. Numeric bounds remain enforced by the server; this schema publishes types and allowed enums, not numeric min/max.`,ko:`변경은 새로 수락되는 요청에 적용됩니다. 지문은 관측된 외부 변경을 감지하지만 원자적 비교 교환은 아닙니다. 숫자 범위는 서버가 검증합니다. 스키마에는 타입과 허용 열거값만 있습니다.`,test_id:`settings-live-body`},{key:`settings.live.unavailable`,en:`Settings unavailable. The server may have disabled --settings.`,ko:`설정을 사용할 수 없습니다. 서버에서 --settings가 비활성화되었을 수 있습니다.`,test_id:`settings-live-unavailable`},{key:`settings.live.refreshed`,en:`Current values refreshed. Review the retained draft before applying.`,ko:`현재 값을 새로 고쳤습니다. 남아 있는 초안을 검토한 후 적용하세요.`,test_id:`settings-live-refreshed`},{key:`settings.live.refresh_failed`,en:`Refresh failed. No changes submitted.`,ko:`새로 고침에 실패했습니다. 변경 사항은 전송되지 않았습니다.`,test_id:`settings-live-refresh-failed`},{key:`settings.live.invalid_value`,en:`Invalid value`,ko:`잘못된 값`,test_id:`settings-live-invalid-value`},{key:`settings.live.conflict`,en:`Another client changed these settings. Current values refreshed; review and Apply again to reconfirm.`,ko:`다른 클라이언트가 설정을 변경했습니다. 갱신된 현재 값을 검토하고 다시 적용하여 확인하세요.`,test_id:`settings-live-conflict`},{key:`settings.live.partial`,en:`{applied} applied; {rejected} rejected. Rejected drafts retained.`,ko:`{applied}개 적용, {rejected}개 거부됨. 거부된 초안은 유지됩니다.`,test_id:`settings-live-partial`},{key:`settings.live.applied`,en:`Accepted fields applied; reading effective values.`,ko:`승인된 필드를 적용했습니다. 실제 값을 다시 읽습니다.`,test_id:`settings-live-applied`},{key:`settings.live.unknown_outcome`,en:`The outcome may be unknown. Refresh effective values before retrying; no automatic PATCH retry.`,ko:`결과를 확정할 수 없습니다. 재시도 전에 실제 값을 새로 고치세요. PATCH는 자동 재시도하지 않습니다.`,test_id:`settings-live-unknown-outcome`},{key:`settings.live.result_title`,en:`Settings result`,ko:`설정 결과`,test_id:`settings-live-result-title`},{key:`settings.live.refresh`,en:`Refresh current values`,ko:`현재 값 새로 고침`,test_id:`settings-live-refresh`},{key:`settings.live.apply`,en:`Apply live draft`,ko:`실시간 초안 적용`,test_id:`settings-live-apply`},{key:`settings.live.reset_open`,en:`Reset live draft…`,ko:`실시간 초안 초기화…`,test_id:`settings-live-reset-open`},{key:`settings.live.hint`,en:`{help} Current: {current}. Type: {type}`,ko:`{help} 현재: {current}. 타입: {type}`,test_id:`settings-live-hint`},{key:`settings.live.hint_allowed`,en:`{help} Current: {current}. Type: {type}; allowed: {allowed}`,ko:`{help} 현재: {current}. 타입: {type}; 허용: {allowed}`,test_id:`settings-live-hint-allowed`},{key:`settings.live.startup`,en:`Server startup · restart required (read-only)`,ko:`서버 시작 · 재시작 필요 (읽기 전용)`,test_id:`settings-live-startup`},{key:`settings.live.reset.title`,en:`Reset live draft only?`,ko:`실시간 초안만 초기화할까요?`,test_id:`settings-live-reset-title`},{key:`settings.live.reset.body`,en:`Stage server startup defaults for mutable fields. No server change occurs until Apply.`,ko:`변경 가능한 필드에 서버 시작 기본값을 초안으로 설정합니다. 적용 전에는 서버가 변경되지 않습니다.`,test_id:`settings-live-reset-body`},{key:`settings.live.reset.confirm`,en:`Reset draft`,ko:`초안 초기화`,test_id:`settings-live-reset-confirm`},{key:`settings.profile.title`,en:`Next load · browser profile`,ko:`다음 로드 · 브라우저 프로필`,test_id:`settings-profile-title`},{key:`settings.profile.body`,en:`Explicit CLI settings take precedence over this profile; the profile overrides a preset only where CLI has not pinned a value. Effective resolved values must be read after loading. Saving is not loading. A loaded model requires an explicit unload and load from Models; failed loads retain this pending profile.`,ko:`명시적 CLI 설정이 프로필보다 우선합니다. CLI로 고정되지 않은 값에만 프로필이 프리셋보다 우선합니다. 실제 값은 로드 후 확인하세요. 저장은 로드가 아닙니다. 로드된 모델은 모델 화면에서 명시적으로 언로드 후 로드해야 하며, 실패 시 프로필은 대기 상태로 남습니다.`,test_id:`settings-profile-body`},{key:`settings.profile.saved`,en:`Browser profile saved. Nothing loaded or changed on the server.`,ko:`브라우저 프로필을 저장했습니다. 서버에서 로드하거나 변경한 내용은 없습니다.`,test_id:`settings-profile-saved`},{key:`settings.profile.failed`,en:`Profile operation failed`,ko:`프로필 작업에 실패했습니다`,test_id:`settings-profile-failed`},{key:`settings.profile.single.title`,en:`Single-model mode: restart required`,ko:`단일 모델 모드: 재시작 필요`,test_id:`settings-profile-single-title`},{key:`settings.profile.single.body`,en:`These preferences cannot be applied to this running worker. Restart with validated CLI flags, or start model-free mode to use load operations.`,ko:`실행 중인 워커에 적용할 수 없습니다. 검증된 CLI 플래그로 재시작하거나 모델 없는 모드에서 로드 작업을 사용하세요.`,test_id:`settings-profile-single-body`},{key:`settings.profile.scope`,en:`Profile scope`,ko:`프로필 범위`,test_id:`settings-profile-scope`},{key:`settings.profile.scope.reusable`,en:`Reusable defaults`,ko:`재사용 기본값`,test_id:`settings-profile-scope-reusable`},{key:`settings.profile.ctx_hint`,en:`Blank: inherit. Actual per-slot context is resolved by the server, not estimated here.`,ko:`빈 값: 상속. 슬롯별 실제 컨텍스트는 서버가 결정하며 여기서 추정하지 않습니다.`,test_id:`settings-profile-ctx-hint`},{key:`settings.profile.parallel_hint`,en:`Scheduler/worker geometry changes only on the next explicit load.`,ko:`스케줄러/워커 구성은 다음 명시적 로드에서만 변경됩니다.`,test_id:`settings-profile-parallel-hint`},{key:`settings.profile.inherit`,en:`Inherit`,ko:`상속`,test_id:`settings-profile-inherit`},{key:`settings.profile.restrictions`,en:`Backend/model restrictions are validated by the existing loader; accepting a browser profile does not promise a model supports every mode. Draft models, adapters, distributed topology and other worker geometry are read-only in v1.`,ko:`백엔드/모델 제약은 기존 로더가 검증합니다. 브라우저 프로필 저장이 모든 모드의 지원을 보장하지 않습니다. 초안 모델, 어댑터, 분산 구성 및 기타 워커 설정은 v1에서 읽기 전용입니다.`,test_id:`settings-profile-restrictions`},{key:`settings.profile.result_title`,en:`Profile result`,ko:`프로필 결과`,test_id:`settings-profile-result-title`},{key:`settings.profile.save`,en:`Save pending profile`,ko:`대기 프로필 저장`,test_id:`settings-profile-save`},{key:`settings.profile.discard`,en:`Discard draft`,ko:`초안 취소`,test_id:`settings-profile-discard`},{key:`settings.profile.reset_open`,en:`Reset selected profile…`,ko:`선택 프로필 초기화…`,test_id:`settings-profile-reset-open`},{key:`settings.profile.saved_pending`,en:`Saved pending profile (not active)`,ko:`저장된 대기 프로필 (미적용)`,test_id:`settings-profile-saved-pending`},{key:`settings.profile.cli`,en:`Sanitized CLI flags · display only; model source omitted`,ko:`안전한 CLI 플래그 · 표시 전용; 모델 소스 생략`,test_id:`settings-profile-cli`},{key:`settings.profile.transfer`,en:`Import / export browser profiles`,ko:`브라우저 프로필 가져오기 / 내보내기`,test_id:`settings-profile-transfer`},{key:`settings.profile.transfer.label`,en:`Versioned profile JSON`,ko:`버전이 있는 프로필 JSON`,test_id:`settings-profile-transfer-label`},{key:`settings.profile.transfer.export`,en:`Export to text`,ko:`텍스트로 내보내기`,test_id:`settings-profile-transfer-export`},{key:`settings.profile.transfer.import`,en:`Validate and import`,ko:`검증 후 가져오기`,test_id:`settings-profile-transfer-import`},{key:`settings.profile.reset.title`,en:`Reset this browser profile?`,ko:`이 브라우저 프로필을 초기화할까요?`,test_id:`settings-profile-reset-title`},{key:`settings.profile.reset.body`,en:`Resets only the selected scope. Model scope falls back to reusable defaults; reusable scope leaves model-specific profiles intact. Does not change a running worker.`,ko:`선택한 범위만 초기화합니다. 모델 범위는 재사용 기본값으로 돌아가며 재사용 범위는 모델별 프로필을 유지합니다. 실행 중인 워커는 변경하지 않습니다.`,test_id:`settings-profile-reset-body`},{key:`settings.profile.reset.confirm`,en:`Reset profile`,ko:`프로필 초기화`,test_id:`settings-profile-reset-confirm`},{key:`settings.context_check.label`,en:`Optional raw prompt budget check`,ko:`선택적 원시 프롬프트 예산 확인`,test_id:`settings-context-check-label`},{key:`settings.context_check.hint`,en:`Sent only when Check is pressed; never persisted. Raw tokens exclude chat templates, conversation history and media. Server validation is final.`,ko:`확인을 누를 때만 전송하며 저장하지 않습니다. 원시 토큰은 채팅 템플릿, 대화 기록, 미디어를 제외합니다. 최종 검증은 서버가 수행합니다.`,test_id:`settings-context-check-hint`},{key:`settings.context_check.check`,en:`Check with model tokenizer`,ko:`모델 토크나이저로 확인`,test_id:`settings-context-check-check`},{key:`settings.context_check.unavailable`,en:`Tokenization unavailable; budget unknown.`,ko:`토큰화 불가; 예산을 알 수 없습니다.`,test_id:`settings-context-check-unavailable`},{key:`settings.context_check.not_measured`,en:`Not measured`,ko:`측정하지 않음`,test_id:`settings-context-check-not-measured`},{key:`settings.context_check.count`,en:`{count} raw tokens. {verdict}`,ko:`{count} 원시 토큰. {verdict}`,test_id:`settings-context-check-count`},{key:`settings.context_check.exceeds`,en:`Raw input + requested output already exceeds observed context.`,ko:`원시 입력 + 요청 출력이 관측 컨텍스트를 초과합니다.`,test_id:`settings-context-check-exceeds`},{key:`settings.context_check.unknown`,en:`Context/output is unknown; no fit claim.`,ko:`컨텍스트/출력을 알 수 없어 수용 가능 여부를 판단하지 않습니다.`,test_id:`settings-context-check-unknown`},{key:`settings.context_check.fits`,en:`Raw input + output fits, but templated chat may still exceed the context.`,ko:`원시 입력 + 출력은 들어가지만 템플릿 적용 채팅은 컨텍스트를 초과할 수 있습니다.`,test_id:`settings-context-check-fits`}],De=[{key:`activity.intro`,en:`Operations and runtime observations. Browsing never loads a model.`,ko:`작업과 런타임 관측입니다. 조회는 모델을 로드하지 않습니다.`,test_id:`activity-intro`},{key:`activity.session`,en:`History belongs to this server session: up to 200 terminal operations for one hour. A restart clears it; reconnect reconciles the authoritative snapshot.`,ko:`기록은 서버 세션에 속합니다. 완료 작업 최대 200개를 한 시간 보관하며, 재시작 시 초기화하고 재연결 시 서버 상태와 대조합니다.`,test_id:`activity-session`},{key:`activity.export`,en:`Export sanitized diagnostics`,ko:`민감 정보 없는 진단 내보내기`,test_id:`activity-export`},{key:`activity.refresh`,en:`Refresh observations`,ko:`관측 새로고침`,test_id:`activity-refresh`},{key:`activity.stale`,en:`Observations are stale. Last values are not current measurements.`,ko:`관측이 최신 상태가 아닙니다. 마지막 값은 현재 측정값이 아닙니다.`,test_id:`activity-stale`},{key:`activity.updated`,en:`Last successful snapshot`,ko:`마지막 성공 스냅샷`,test_id:`activity-updated`},{key:`activity.pending`,en:`Waiting for the first snapshot`,ko:`첫 스냅샷을 기다리는 중`,test_id:`activity-pending`},{key:`activity.operations`,en:`Operations`,ko:`작업`,test_id:`activity-operations`},{key:`activity.operations.counts`,en:`Operations: {active} active · {failed} failed`,ko:`작업: {active} 진행 중 · {failed} 실패`,test_id:`activity-operations-counts`},{key:`activity.operations.empty.title`,en:`No operations in this session`,ko:`이 세션의 작업 없음`,test_id:`activity-operations-empty-title`},{key:`activity.operations.empty.body`,en:`Explicit downloads, loads, drains and removals will appear here.`,ko:`명시적인 다운로드, 로드, 드레인 및 삭제 작업이 표시됩니다.`,test_id:`activity-operations-empty-body`},{key:`activity.cancel`,en:`Request cancellation`,ko:`취소 요청`,test_id:`activity-cancel`},{key:`activity.cancelling`,en:`Cancellation requested; waiting for worker acknowledgement.`,ko:`취소 요청됨. 작업자 확인을 기다립니다.`,test_id:`activity-cancelling`},{key:`activity.failure`,en:`The action failed. Check its state and refresh before retrying from Models.`,ko:`작업에 실패했습니다. 상태를 확인하고 새로고침한 후 모델 화면에서 재시도하세요.`,test_id:`activity-failure`},{key:`activity.cancel_failed`,en:`Cancellation could not be confirmed. Refresh to reconcile the operation.`,ko:`취소를 확인하지 못했습니다. 새로고침하여 작업 상태를 대조하세요.`,test_id:`activity-cancel-failed`},{key:`activity.cancel_unsupported`,en:`Cancellation is unavailable for this operation; worker execution is not interrupted.`,ko:`이 작업은 취소할 수 없습니다. 실행 중인 작업자를 강제로 중단하지 않습니다.`,test_id:`activity-cancel-unsupported`},{key:`activity.runtime`,en:`Selected model runtime`,ko:`선택한 모델 런타임`,test_id:`activity-runtime`},{key:`activity.select`,en:`Select a model to observe`,ko:`관측할 모델 선택`,test_id:`activity-select`},{key:`activity.select_body`,en:`Use the model picker. Selection does not load the model.`,ko:`모델 선택기를 사용하세요. 선택만으로 모델을 로드하지 않습니다.`,test_id:`activity-select-body`},{key:`activity.unavailable`,en:`N/A — no authoritative sample is available.`,ko:`N/A — 확인된 관측값이 없습니다.`,test_id:`activity-unavailable`},{key:`activity.not_available`,en:`N/A`,ko:`N/A`,test_id:`activity-not-available`},{key:`activity.memory`,en:`Memory figures have separate scopes and may overlap. Do not add process, allocator, device and cache values together.`,ko:`메모리 수치는 서로 다른 범위이며 중복될 수 있습니다. 프로세스, 할당자, 장치 및 캐시 값을 합산하지 마세요.`,test_id:`activity-memory`},{key:`activity.timing`,en:`Server counters are not browser TTFT. Chat shows request-send to first reasoning/content delta separately; no rendered word counts are used as tokens.`,ko:`서버 카운터는 브라우저 TTFT가 아닙니다. 채팅은 요청 전송부터 첫 추론/내용 델타까지 별도로 표시하며, 단어 수를 토큰으로 사용하지 않습니다.`,test_id:`activity-timing`},{key:`activity.slots`,en:`Request slots`,ko:`요청 슬롯`,test_id:`activity-slots`},{key:`activity.slot`,en:`Slot`,ko:`슬롯`,test_id:`activity-slot`},{key:`activity.processing`,en:`Processing`,ko:`처리 중`,test_id:`activity-processing`},{key:`activity.idle`,en:`Idle`,ko:`유휴`,test_id:`activity-idle`},{key:`activity.context`,en:`Request context window`,ko:`요청 컨텍스트 한도`,test_id:`activity-context`},{key:`activity.pool`,en:`Shared pool context`,ko:`공유 풀 컨텍스트`,test_id:`activity-pool`},{key:`activity.parallel`,en:`Effective parallelism`,ko:`실제 병렬도`,test_id:`activity-parallel`},{key:`activity.context_line`,en:`{context}: {request} tokens · {pool}: {shared} tokens`,ko:`{context}: {request} 토큰 · {pool}: {shared} 토큰`,test_id:`activity-context-line`},{key:`activity.no_context`,en:`N/A — context denominator is unknown; no occupancy percentage is inferred.`,ko:`N/A — 컨텍스트 분모를 알 수 없어 점유율을 추정하지 않습니다.`,test_id:`activity-no-context`},{key:`activity.slot_progress`,en:`{used} / {total} tokens`,ko:`{used} / {total} 토큰`,test_id:`activity-slot-progress`},{key:`activity.slot_tokens`,en:`Accepted decode: {decoded} tokens · Cached prompt: {cached} tokens`,ko:`수락된 디코드: {decoded} 토큰 · 캐시된 프롬프트: {cached} 토큰`,test_id:`activity-slot-tokens`},{key:`activity.history.show`,en:`Show recent history`,ko:`최근 기록 보기`,test_id:`activity-history-show`},{key:`activity.history.hide`,en:`Hide recent history`,ko:`최근 기록 숨기기`,test_id:`activity-history-hide`},{key:`activity.history.note`,en:`Five-minute in-memory history, at most 150 two-second samples. Hidden tabs stop observation; gaps and counter resets are not interpolated.`,ko:`메모리 내 5분 기록이며 2초 간격 최대 150개입니다. 숨겨진 탭은 관측을 중지합니다. 공백과 카운터 초기화를 보간하지 않습니다.`,test_id:`activity-history-note`},{key:`activity.chart.label`,en:`Active requests: discrete observations over the last five minutes`,ko:`활성 요청: 최근 5분 동안의 개별 관측값`,test_id:`activity-chart-label`},{key:`activity.chart.title`,en:`Active requests (requests, selected model)`,ko:`활성 요청 (요청 수, 선택한 모델)`,test_id:`activity-chart-title`},{key:`activity.chart.point`,en:`{value} requests`,ko:`요청 {value}개`,test_id:`activity-chart-point`},{key:`activity.scope`,en:`Scope`,ko:`범위`,test_id:`activity-scope`},{key:`activity.observed`,en:`Observed at`,ko:`관측 시각`,test_id:`activity-observed`},{key:`activity.metric_details`,en:`All measurements and sources`,ko:`전체 측정값과 출처`,test_id:`activity-metric-details`},{key:`activity.unavailable_count`,en:`Unavailable measurements`,ko:`사용할 수 없는 측정값`,test_id:`activity-unavailable-count`},{key:`activity.unavailable_reason`,en:`Some sources are disabled or do not publish an authoritative sample. Expand details for individual reasons.`,ko:`일부 출처가 비활성화되었거나 확인된 관측값을 제공하지 않습니다. 상세 내용을 펼쳐 개별 사유를 확인하세요.`,test_id:`activity-unavailable-reason`},{key:`activity.no_primary`,en:`No primary request counters are available.`,ko:`사용 가능한 주요 요청 카운터가 없습니다.`,test_id:`activity-no-primary`},{key:`activity.bytes`,en:`bytes downloaded`,ko:`다운로드 바이트`,test_id:`activity-bytes`},{key:`activity.download_progress`,en:`{completed} / {total} bytes`,ko:`{completed} / {total} 바이트`,test_id:`activity-download-progress`},{key:`activity.details`,en:`Operation details`,ko:`작업 상세`,test_id:`activity-details`},{key:`activity.status`,en:`Operation status`,ko:`작업 상태`,test_id:`activity-status`},{key:`activity.unknown_time`,en:`Unknown`,ko:`알 수 없음`,test_id:`activity-unknown-time`},{key:`activity.metric.active_requests`,en:`Active requests`,ko:`활성 요청`,test_id:`activity-metric-active-requests`},{key:`activity.metric.queued_requests`,en:`Queued requests`,ko:`대기 요청`,test_id:`activity-metric-queued-requests`},{key:`activity.metric.completed_requests_total`,en:`Total completed requests`,ko:`누적 완료 요청`,test_id:`activity-metric-completed-requests-total`},{key:`activity.metric.completion_tokens_total`,en:`Total completion tokens`,ko:`누적 완료 토큰`,test_id:`activity-metric-completion-tokens-total`},{key:`activity.metric.gpu_utilization`,en:`GPU utilization`,ko:`GPU 사용률`,test_id:`activity-metric-gpu-utilization`},{key:`activity.metric.ttft`,en:`Time to first token`,ko:`첫 토큰 도달 시간`,test_id:`activity-metric-ttft`},{key:`activity.metric.decode_rate`,en:`Decode rate`,ko:`디코드 속도`,test_id:`activity-metric-decode-rate`},{key:`activity.metric.process_resident_bytes`,en:`Process resident memory`,ko:`프로세스 상주 메모리`,test_id:`activity-metric-process-resident-bytes`},{key:`activity.metric.allocator_active_bytes`,en:`Active allocator memory`,ko:`할당자 활성 메모리`,test_id:`activity-metric-allocator-active-bytes`},{key:`activity.metric.allocator_cache_bytes`,en:`Cached allocator memory`,ko:`할당자 캐시 메모리`,test_id:`activity-metric-allocator-cache-bytes`},{key:`activity.metric.allocator_peak_bytes`,en:`Peak allocator memory`,ko:`할당자 최대 메모리`,test_id:`activity-metric-allocator-peak-bytes`},{key:`activity.metric.device_total_bytes`,en:`Device memory`,ko:`장치 메모리`,test_id:`activity-metric-device-total-bytes`},{key:`activity.metric.model_weights_bytes`,en:`Model weights estimate`,ko:`모델 가중치 추정량`,test_id:`activity-metric-model-weights-bytes`},{key:`activity.metric.kv_cache_bytes`,en:`KV cache memory`,ko:`KV 캐시 메모리`,test_id:`activity-metric-kv-cache-bytes`},{key:`activity.metric.generation_time_ms_total`,en:`Total generation time`,ko:`누적 생성 시간`,test_id:`activity-metric-generation-time-ms-total`},{key:`activity.metric.decode_tokens_total`,en:`Accepted decode tokens`,ko:`수락된 디코드 토큰`,test_id:`activity-metric-decode-tokens-total`},{key:`activity.metric.decode_time_us_total`,en:`Total decode time`,ko:`누적 디코드 시간`,test_id:`activity-metric-decode-time-us-total`},{key:`activity.metric.prompt_cache_bytes`,en:`Prompt cache memory`,ko:`프롬프트 캐시 메모리`,test_id:`activity-metric-prompt-cache-bytes`},{key:`activity.metric.prompt_cache_entries`,en:`Prompt cache entries`,ko:`프롬프트 캐시 항목`,test_id:`activity-metric-prompt-cache-entries`}],Oe=[{key:`app.title`,en:`mlxcel WebUI`,ko:`mlxcel 웹 UI`,test_id:`app-title`},{key:`app.subtitle`,en:`Local model control plane`,ko:`로컬 모델 제어판`,test_id:`app-subtitle`},{key:`nav.models`,en:`Models`,ko:`모델`,test_id:`nav-models`},{key:`nav.chat`,en:`Chat`,ko:`대화`,test_id:`nav-chat`},{key:`nav.activity`,en:`Activity`,ko:`활동`,test_id:`nav-activity`},{key:`nav.settings`,en:`Settings`,ko:`설정`,test_id:`nav-settings`},{key:`nav.gallery`,en:`Gallery`,ko:`갤러리`,test_id:`nav-gallery`},{key:`nav.primary`,en:`Primary navigation`,ko:`주 내비게이션`,test_id:`nav-primary`},{key:`nav.home`,en:`mlxcel home`,ko:`mlxcel 홈`,test_id:`nav-home`},{key:`toolbar.command`,en:`Command`,ko:`명령`,test_id:`toolbar-command`},{key:`toolbar.help`,en:`Keyboard help`,ko:`키보드 도움말`,test_id:`toolbar-help`},{key:`toolbar.logout`,en:`Clear WebUI session`,ko:`WebUI 세션 지우기`,test_id:`toolbar-logout`},{key:`toolbar.menu`,en:`Open navigation`,ko:`내비게이션 열기`,test_id:`toolbar-menu`},{key:`connection.ready`,en:`Shell loaded; local API not connected`,ko:`셸 로드됨; 로컬 API 미연결`,test_id:`connection-ready`},{key:`connection.offline`,en:`Server connection is offline`,ko:`서버 연결이 오프라인입니다`,test_id:`connection-offline`},{key:`connection.prompt.title`,en:`Connect to the local WebUI API`,ko:`로컬 WebUI API에 연결하세요`,test_id:`connection-prompt-title`},{key:`connection.prompt.body`,en:`The shell is loaded, but catalog, chat and activity data wait for the authenticated local server connection.`,ko:`셸은 로드되었지만 카탈로그, 대화, 활동 데이터는 인증된 로컬 서버 연결을 기다립니다.`,test_id:`connection-prompt-body`},{key:`connection.prompt.detail`,en:`Start mlxcel-server with --webui, enter the terminal session key when prompted, then refresh this view.`,ko:`mlxcel-server를 --webui로 시작하고, 요청되면 터미널 세션 키를 입력한 뒤 이 화면을 새로고침하세요.`,test_id:`connection-prompt-detail`},{key:`connection.footer.connected`,en:`{mode} · {status} · v{version} · seq {sequence}`,ko:`{mode} · {status} · v{version} · seq {sequence}`,test_id:`connection-footer-connected`},{key:`connection.snapshot.pending`,en:`pending`,ko:`대기 중`,test_id:`connection-snapshot-pending`},{key:`connection.authenticated.title`,en:`Authenticated local API session`,ko:`인증된 로컬 API 세션`,test_id:`connection-authenticated-title`},{key:`connection.authenticated.body`,en:`This route is connected to the shared provider. Browsing does not load models or start inference; load, unload and chat actions remain explicit.`,ko:`이 경로는 공유 provider에 연결되어 있습니다. 탐색만으로 모델을 로드하거나 추론을 시작하지 않으며, 로드·언로드·대화 동작은 명시적으로 실행됩니다.`,test_id:`connection-authenticated-body`},{key:`connection.authenticated.detail`,en:`Backend {mode}; build {version}; state {status}; catalog {count}; operations {operations}; snapshot {sequence}.`,ko:`백엔드 {mode}; 빌드 {version}; 상태 {status}; 카탈로그 {count}; 작업 {operations}; 스냅샷 {sequence}.`,test_id:`connection-authenticated-detail`},{key:`connection.error.title`,en:`Provider connection needs attention`,ko:`Provider 연결 확인 필요`,test_id:`connection-error-title`},{key:`connection.error.stale`,en:`The server snapshot changed; retry to take a fresh catalog and operation snapshot before continuing.`,ko:`서버 스냅샷이 바뀌었습니다. 계속하기 전에 다시 시도해 새 카탈로그와 작업 스냅샷을 가져오세요.`,test_id:`connection-error-stale`},{key:`connection.error.forbidden`,en:`The authenticated session is not allowed to access this UI endpoint.`,ko:`인증된 세션이 이 UI 엔드포인트에 접근할 수 없습니다.`,test_id:`connection-error-forbidden`},{key:`connection.error.unauthorized`,en:`The server rejected the current session key. Sign in again with the latest terminal key.`,ko:`서버가 현재 세션 키를 거부했습니다. 터미널에 표시된 최신 키로 다시 로그인하세요.`,test_id:`connection-error-unauthorized`},{key:`connection.error.generic`,en:`Retry the shared provider snapshot before issuing any model control action.`,ko:`모델 제어 동작을 실행하기 전에 공유 provider 스냅샷을 다시 가져오세요.`,test_id:`connection-error-generic`},{key:`connection.status.idle`,en:`idle`,ko:`대기`,test_id:`connection-status-idle`},{key:`connection.status.bootstrapping`,en:`bootstrapping`,ko:`부트스트랩`,test_id:`connection-status-bootstrapping`},{key:`connection.status.ready`,en:`ready`,ko:`준비`,test_id:`connection-status-ready`},{key:`connection.status.streaming`,en:`streaming`,ko:`스트리밍`,test_id:`connection-status-streaming`},{key:`connection.status.polling`,en:`polling`,ko:`폴링`,test_id:`connection-status-polling`},{key:`connection.status.offline`,en:`offline`,ko:`오프라인`,test_id:`connection-status-offline`},{key:`connection.status.stale`,en:`stale`,ko:`낡음`,test_id:`connection-status-stale`},{key:`connection.status.unauthorized`,en:`unauthorized`,ko:`인증 실패`,test_id:`connection-status-unauthorized`},{key:`connection.status.forbidden`,en:`forbidden`,ko:`거부됨`,test_id:`connection-status-forbidden`},{key:`connection.status.schema_mismatch`,en:`schema mismatch`,ko:`스키마 불일치`,test_id:`connection-status-schema-mismatch`},{key:`connection.status.error`,en:`error`,ko:`오류`,test_id:`connection-status-error`},{key:`auth.login`,en:`WebUI session login`,ko:`WebUI 세션 로그인`,test_id:`auth-login`},{key:`models.title`,en:`Model library`,ko:`모델 라이브러리`,test_id:`models-title`},{key:`models.empty.title`,en:`No local models yet`,ko:`아직 로컬 모델이 없습니다`,test_id:`models-empty-title`},{key:`models.empty.body`,en:`Browse, download, and load models explicitly. The shell never autoloads a checkpoint.`,ko:`모델을 명시적으로 탐색, 다운로드, 로드하세요. 셸은 체크포인트를 자동 로드하지 않습니다.`,test_id:`models-empty-body`},{key:`models.long_name`,en:`Qwen3-Very-Long-Local-Checkpoint-Name-With-Mixed-English-and-한국어-모델-이름`,ko:`Qwen3-Very-Long-Local-Checkpoint-Name-With-Mixed-English-and-한국어-모델-이름`,test_id:`models-long-name`},{key:`models.unsupported.reason`,en:`Vision input is unavailable for this backend; chat remains text-only.`,ko:`이 백엔드에서는 비전 입력을 사용할 수 없어 대화는 텍스트 전용입니다.`,test_id:`models-unsupported-reason`},{key:`models.load`,en:`Load`,ko:`로드`,test_id:`models-load`},{key:`models.unload`,en:`Unload`,ko:`언로드`,test_id:`models-unload`},{key:`models.status.ready`,en:`Ready`,ko:`준비됨`,test_id:`models-status-ready`},{key:`models.status.unloaded`,en:`Unloaded`,ko:`언로드됨`,test_id:`models-status-unloaded`},{key:`models.status.failed`,en:`Failed`,ko:`실패`,test_id:`models-status-failed`},{key:`models.status.loading`,en:`Loading`,ko:`로드 중`,test_id:`models-status-loading`},{key:`models.status.draining`,en:`Draining`,ko:`drain 중`,test_id:`models-status-draining`},{key:`models.status.unloading`,en:`Unloading`,ko:`언로드 중`,test_id:`models-status-unloading`},{key:`models.delete.confirm.title`,en:`Delete model from cache?`,ko:`캐시에서 모델을 삭제할까요?`,test_id:`dialog-delete-model-title`},{key:`models.delete.confirm.body`,en:`Delete {model} from the managed cache. Loaded or non-cache models cannot be deleted.`,ko:`관리 캐시에서 {model} 모델을 삭제합니다. 로드 중이거나 캐시 모델이 아니면 삭제할 수 없습니다.`,test_id:`dialog-delete-model-body`},{key:`models.delete.confirm.token_label`,en:`Type DELETE to confirm`,ko:`확인하려면 DELETE를 입력하세요`,test_id:`dialog-delete-model-token`},{key:`models.unload.confirm.body`,en:`Unload {model} after active requests drain; browser tabs will keep their selected model.`,ko:`활성 요청이 비워진 뒤 {model} 모델을 언로드합니다. 브라우저 탭의 선택 모델은 유지됩니다.`,test_id:`dialog-unload-model-body`},{key:`chat.title`,en:`Chat`,ko:`대화`,test_id:`chat-title`},{key:`chat.placeholder`,en:`Type a message; IME composition is preserved.`,ko:`메시지를 입력하세요. IME 조합은 보존됩니다.`,test_id:`chat-placeholder`},{key:`chat.streaming.status`,en:`Streaming tokens from the selected ready model.`,ko:`선택한 준비 모델에서 토큰을 스트리밍 중입니다.`,test_id:`chat-streaming-status`},{key:`chat.reasoning`,en:`Reasoning`,ko:`추론`,test_id:`chat-reasoning`},{key:`chat.tool_call`,en:`Tool call preview`,ko:`도구 호출 미리보기`,test_id:`chat-tool-call`},{key:`downloads.cancel.confirm.body`,en:`Cancel this download only after the server acknowledges worker shutdown.`,ko:`서버가 작업자 중지를 확인한 뒤에만 이 다운로드를 취소합니다.`,test_id:`dialog-cancel-download-body`},{key:`activity.title`,en:`Activity`,ko:`활동`,test_id:`activity-title`},{key:`activity.progress.indeterminate`,en:`Downloaded {bytes}; total size is not known yet.`,ko:`{bytes} 다운로드됨; 전체 크기는 아직 알 수 없습니다.`,test_id:`activity-progress-indeterminate`},{key:`activity.sse_reset`,en:`Event stream reset; take a fresh snapshot before resuming updates.`,ko:`이벤트 스트림이 재설정되었습니다. 업데이트를 재개하기 전에 새 스냅샷을 가져오세요.`,test_id:`activity-sse-reset`},{key:`settings.title`,en:`Settings`,ko:`설정`,test_id:`settings-title`},{key:`settings.appearance`,en:`Appearance preferences`,ko:`화면 표시 설정`,test_id:`settings-appearance`},{key:`settings.theme`,en:`Theme`,ko:`테마`,test_id:`settings-theme`},{key:`settings.color_scheme`,en:`Color scheme`,ko:`색상 모드`,test_id:`settings-color-scheme`},{key:`settings.material`,en:`Material`,ko:`재질`,test_id:`settings-material`},{key:`settings.glass_intensity`,en:`Glass intensity`,ko:`글래스 강도`,test_id:`settings-glass-intensity`},{key:`settings.reduce_motion`,en:`Reduce motion`,ko:`동작 줄이기`,test_id:`settings-reduce-motion`},{key:`settings.reduce_transparency`,en:`Reduce transparency`,ko:`투명도 줄이기`,test_id:`settings-reduce-transparency`},{key:`settings.high_contrast`,en:`High contrast`,ko:`고대비`,test_id:`settings-high-contrast`},{key:`settings.locale`,en:`Language`,ko:`언어`,test_id:`settings-locale`},{key:`settings.partial_success`,en:`Some settings changed; fields controlled by CLI or the loaded worker were left unchanged.`,ko:`일부 설정만 변경되었습니다. CLI 또는 로드된 워커가 제어하는 필드는 변경되지 않았습니다.`,test_id:`settings-partial-success`},{key:`settings.browser_only`,en:`Browser appearance only`,ko:`브라우저 표시 설정 전용`,test_id:`settings-browser-only`},{key:`settings.browser_only.body`,en:`These preferences stay in this browser and do not claim server or worker settings changed.`,ko:`이 설정은 이 브라우저에만 남으며 서버나 워커 설정 변경을 의미하지 않습니다.`,test_id:`settings-browser-only-body`},{key:`settings.clear_history.confirm.body`,en:`Clear only the explicit local browser history store; API keys are never persisted there.`,ko:`명시적으로 켠 로컬 브라우저 기록 저장소만 지웁니다. API 키는 그곳에 저장하지 않습니다.`,test_id:`dialog-clear-history-body`},{key:`state.unauthorized.title`,en:`Authentication required`,ko:`인증이 필요합니다`,test_id:`state-unauthorized-title`},{key:`state.unauthorized.body`,en:`Enter the session key printed by the local server terminal.`,ko:`로컬 서버 터미널에 한 번 표시된 세션 키를 입력하세요.`,test_id:`state-unauthorized-body`},{key:`state.offline.title`,en:`Server offline`,ko:`서버 오프라인`,test_id:`state-offline-title`},{key:`state.offline.body`,en:`The shell is available, but model data waits for the local API.`,ko:`셸은 사용할 수 있지만 모델 데이터는 로컬 API를 기다립니다.`,test_id:`state-offline-body`},{key:`state.schema_mismatch.title`,en:`UI schema mismatch`,ko:`UI 스키마 불일치`,test_id:`state-schema-mismatch-title`},{key:`state.schema_mismatch.body`,en:`The shell loaded, but the server reports a different UI API schema version; refresh after updating the bundle or server.`,ko:`셸은 로드되었지만 서버가 다른 UI API 스키마 버전을 보고했습니다. 번들이나 서버를 업데이트한 뒤 새로고침하세요.`,test_id:`state-schema-mismatch-body`},{key:`command.title`,en:`Command palette`,ko:`명령 팔레트`,test_id:`command-title`},{key:`select.search`,en:`Search options`,ko:`옵션 검색`,test_id:`select-search`},{key:`select.no_options`,en:`No matching options.`,ko:`일치하는 옵션이 없습니다.`,test_id:`select-no-options`},{key:`command.search`,en:`Search commands`,ko:`명령 검색`,test_id:`command-search`},{key:`command.no_results`,en:`No commands match this search.`,ko:`검색과 일치하는 명령이 없습니다.`,test_id:`command-no-results`},{key:`help.title`,en:`Keyboard shortcuts`,ko:`키보드 단축키`,test_id:`help-title`},{key:`help.body`,en:`Command opens search. Escape closes overlays. Brackets move navigation only while the sidebar has focus.`,ko:`Command는 검색을 엽니다. Escape는 오버레이를 닫습니다. 대괄호는 사이드바에 포커스가 있을 때만 내비게이션을 이동합니다.`,test_id:`help-body`},{key:`gallery.title`,en:`Design system gallery`,ko:`디자인 시스템 갤러리`,test_id:`gallery-title`},{key:`gallery.subtitle`,en:`Shared tokens, controls, states, and viewport fixtures for page implementers.`,ko:`페이지 구현자를 위한 공유 토큰, 컨트롤, 상태, 뷰포트 픽스처입니다.`,test_id:`gallery-subtitle`},{key:`gallery.long_cjk`,en:`Long English and 한국어 labels truncate with accessible full labels.`,ko:`긴 English 및 한국어 레이블은 접근 가능한 전체 레이블을 유지하며 줄임표 처리됩니다.`,test_id:`gallery-long-cjk`},{key:`model.selected.none`,en:`No model selected`,ko:`선택한 모델 없음`,test_id:`model-selected-none`},{key:`common.unavailable`,en:`Unavailable until server adapters connect`,ko:`서버 어댑터 연결 전에는 사용할 수 없습니다`,test_id:`common-unavailable`},{key:`common.cancel`,en:`Cancel`,ko:`취소`,test_id:`common-cancel`},{key:`common.delete`,en:`Delete`,ko:`삭제`,test_id:`common-delete`},{key:`common.retry`,en:`Retry`,ko:`다시 시도`,test_id:`common-retry`},{key:`common.reload`,en:`Reload`,ko:`새로고침`,test_id:`common-reload`},{key:`common.enter_key`,en:`Enter key`,ko:`키 입력`,test_id:`common-enter-key`},{key:`common.add_model`,en:`Add model`,ko:`모델 추가`,test_id:`common-add-model`},{key:`common.send`,en:`Send`,ko:`보내기`,test_id:`common-send`},{key:`routes.models.eyebrow`,en:`Local library`,ko:`로컬 라이브러리`,test_id:`routes-models-eyebrow`},{key:`routes.chat.eyebrow`,en:`Conversation`,ko:`대화`,test_id:`routes-chat-eyebrow`},{key:`routes.activity.eyebrow`,en:`Operations`,ko:`작업`,test_id:`routes-activity-eyebrow`},{key:`routes.settings.eyebrow`,en:`Browser only`,ko:`브라우저 전용`,test_id:`routes-settings-eyebrow`},{key:`adapters.pending.title`,en:`Local API is not connected yet`,ko:`로컬 API가 아직 연결되지 않았습니다`,test_id:`adapters-pending-title`},{key:`adapters.pending.body`,en:`This route shows the production shell only. Catalog, lifecycle, and runtime data will come from the shared typed client in the integration wave.`,ko:`이 경로는 프로덕션 셸만 보여줍니다. 카탈로그, 수명주기, 런타임 데이터는 통합 웨이브의 공유 typed client에서 제공됩니다.`,test_id:`adapters-pending-body`},{key:`chat.pending.body`,en:`Chat controls stay disabled until an authenticated ready model is selected by the shared state provider.`,ko:`공유 상태 provider가 인증된 준비 모델을 선택하기 전까지 대화 컨트롤은 비활성화됩니다.`,test_id:`chat-pending-body`},{key:`activity.empty.title`,en:`No active operations`,ko:`활성 작업 없음`,test_id:`activity-empty-title`},{key:`activity.empty.body`,en:`Loads, downloads, drains and SSE resets appear here after the lifecycle adapter connects.`,ko:`수명주기 어댑터가 연결된 뒤 로드, 다운로드, drain, SSE reset이 여기에 표시됩니다.`,test_id:`activity-empty-body`},{key:`gallery.tab.sections`,en:`Gallery sections`,ko:`갤러리 섹션`,test_id:`gallery-tab-sections`},{key:`gallery.tab.controls`,en:`Controls`,ko:`컨트롤`,test_id:`gallery-tab-controls`},{key:`gallery.tab.states`,en:`States`,ko:`상태`,test_id:`gallery-tab-states`},{key:`gallery.tab.data`,en:`Data display`,ko:`데이터 표시`,test_id:`gallery-tab-data`},{key:`gallery.controls.title`,en:`Buttons and fields`,ko:`버튼과 필드`,test_id:`gallery-controls-title`},{key:`gallery.controls.primary`,en:`Primary`,ko:`기본`,test_id:`gallery-controls-primary`},{key:`gallery.controls.secondary`,en:`Secondary`,ko:`보조`,test_id:`gallery-controls-secondary`},{key:`gallery.controls.danger`,en:`Danger`,ko:`위험`,test_id:`gallery-controls-danger`},{key:`gallery.controls.busy`,en:`Busy`,ko:`진행 중`,test_id:`gallery-controls-busy`},{key:`gallery.field.repo`,en:`Repository ID`,ko:`저장소 ID`,test_id:`gallery-field-repo`},{key:`gallery.field.repo_error`,en:`Use owner/name without a URL.`,ko:`URL 없이 owner/name 형식을 사용하세요.`,test_id:`gallery-field-repo-error`},{key:`gallery.field.repo_hint`,en:`Sample only; downloads require the later lifecycle adapter.`,ko:`샘플 전용입니다. 다운로드는 후속 수명주기 어댑터가 필요합니다.`,test_id:`gallery-field-repo-hint`},{key:`gallery.progress.measured`,en:`Sample download progress`,ko:`예시 다운로드 진행률`,test_id:`gallery-progress-measured`},{key:`gallery.select.native`,en:`Shared select combobox`,ko:`공통 선택 콤보박스`,test_id:`gallery-select-native`},{key:`gallery.overlays.title`,en:`Overlays`,ko:`오버레이`,test_id:`gallery-overlays-title`},{key:`gallery.tooltip`,en:`Tooltips are descriptive only`,ko:`툴팁은 설명 전용입니다`,test_id:`gallery-tooltip`},{key:`gallery.dialog.open`,en:`Open dialog`,ko:`다이얼로그 열기`,test_id:`gallery-dialog-open`},{key:`gallery.states.load_failed`,en:`Load failed`,ko:`로드 실패`,test_id:`gallery-states-load-failed`},{key:`gallery.states.load_failed_body`,en:`The worker exited before becoming ready; retry after checking logs.`,ko:`워커가 준비되기 전에 종료되었습니다. 로그 확인 후 다시 시도하세요.`,test_id:`gallery-states-load-failed-body`},{key:`gallery.data.title`,en:`Model rows`,ko:`모델 행`,test_id:`gallery-data-title`},{key:`gallery.data.name`,en:`Name`,ko:`이름`,test_id:`gallery-data-name`},{key:`gallery.data.status`,en:`Status`,ko:`상태`,test_id:`gallery-data-status`},{key:`gallery.data.rate`,en:`Rate`,ko:`속도`,test_id:`gallery-data-rate`},{key:`gallery.data.inspector`,en:`Inspector`,ko:`인스펙터`,test_id:`gallery-data-inspector`},{key:`gallery.sample.reasoning_body`,en:`Reasoning text is visually separated from answer content.`,ko:`추론 텍스트는 답변 본문과 시각적으로 분리됩니다.`,test_id:`gallery-sample-reasoning-body`},{key:`gallery.sample.tool_preview`,en:`{ "tool": "display_only" }`,ko:`{ "tool": "표시_전용" }`,test_id:`gallery-sample-tool-preview`},{key:`common.close`,en:`Close`,ko:`닫기`,test_id:`common-close`},{key:`settings.theme.mlxcel`,en:`Standard`,ko:`표준`,test_id:`settings-theme-mlxcel`},{key:`settings.theme.glass`,en:`Glass`,ko:`글래스`,test_id:`settings-theme-glass`},{key:`settings.color_scheme.system`,en:`System`,ko:`시스템`,test_id:`settings-color-scheme-system`},{key:`settings.color_scheme.light`,en:`Light`,ko:`라이트`,test_id:`settings-color-scheme-light`},{key:`settings.color_scheme.dark`,en:`Dark`,ko:`다크`,test_id:`settings-color-scheme-dark`},{key:`settings.material.glass`,en:`Glass`,ko:`글래스`,test_id:`settings-material-glass`},{key:`settings.material.tinted`,en:`Tinted`,ko:`틴트`,test_id:`settings-material-tinted`},{key:`settings.material.opaque`,en:`Opaque`,ko:`불투명`,test_id:`settings-material-opaque`},{key:`settings.locale.en`,en:`English`,ko:`영어`,test_id:`settings-locale-en`},{key:`settings.locale.ko`,en:`Korean`,ko:`한국어`,test_id:`settings-locale-ko`},{key:`settings.high_contrast.system`,en:`Follow system`,ko:`시스템 따르기`,test_id:`settings-high-contrast-system`},{key:`settings.high_contrast.on`,en:`On`,ko:`켬`,test_id:`settings-high-contrast-on`},{key:`settings.high_contrast.off`,en:`Off`,ko:`끔`,test_id:`settings-high-contrast-off`},{key:`gallery.issue`,en:`Issue #1843`,ko:`이슈 #1843`,test_id:`gallery-issue`},{key:`gallery.hover_focus`,en:`Hover or focus`,ko:`호버 또는 포커스`,test_id:`gallery-hover-focus`},{key:`gallery.download`,en:`Download`,ko:`다운로드`,test_id:`gallery-download`},{key:`gallery.lifecycle.samples`,en:`Lifecycle sample badges`,ko:`수명주기 샘플 배지`,test_id:`gallery-lifecycle-samples`},{key:`gallery.sample.caption`,en:`Sample model table`,ko:`샘플 모델 표`,test_id:`gallery-sample-caption`},{key:`gallery.sample.label`,en:`Sample fixture`,ko:`샘플 픽스처`,test_id:`gallery-sample-label`},{key:`login.token.label`,en:`Session key`,ko:`세션 키`,test_id:`login-token-label`},{key:`login.token.help`,en:`Use the key printed once by the local server. It stays in memory only.`,ko:`로컬 서버가 한 번 출력한 키를 사용하세요. 키는 메모리에만 유지됩니다.`,test_id:`login-token-help`},{key:`login.submit`,en:`Connect`,ko:`연결`,test_id:`login-submit`},{key:`login.logout`,en:`Clear key`,ko:`키 지우기`,test_id:`login-logout`},{key:`login.error.sample`,en:`Sample error: the key was not accepted by the local API.`,ko:`샘플 오류: 로컬 API가 키를 허용하지 않았습니다.`,test_id:`login-error-sample`},{key:`login.error.wrong_key`,en:`The session key was rejected. Copy the latest key printed by the local server terminal.`,ko:`세션 키가 거부되었습니다. 로컬 서버 터미널에 표시된 최신 키를 복사하세요.`,test_id:`login-error-wrong-key`},{key:`login.error.offline`,en:`Could not reach the local WebUI API. Check that mlxcel-server is still running with --webui.`,ko:`로컬 WebUI API에 연결할 수 없습니다. mlxcel-server가 --webui로 계속 실행 중인지 확인하세요.`,test_id:`login-error-offline`},{key:`login.error.forbidden`,en:`The key authenticated, but this UI endpoint is forbidden for the current server session.`,ko:`키 인증은 되었지만 현재 서버 세션에서 이 UI 엔드포인트가 금지되어 있습니다.`,test_id:`login-error-forbidden`},{key:`login.error.schema`,en:`The server response does not match this bundled UI schema. Reload after updating the server or bundle.`,ko:`서버 응답이 번들된 UI 스키마와 일치하지 않습니다. 서버나 번들을 업데이트한 뒤 새로고침하세요.`,test_id:`login-error-schema`},{key:`login.error.generic`,en:`The local API could not complete authentication. Retry with the latest terminal key.`,ko:`로컬 API 인증을 완료할 수 없습니다. 터미널에 표시된 최신 키로 다시 시도하세요.`,test_id:`login-error-generic`},{key:`gallery.delete_token`,en:`DELETE`,ko:`DELETE`,test_id:`gallery-delete-token`},{key:`models.next_profile.body`,en:`Pending browser profile; not applied yet. Explicit CLI/environment settings take precedence. Read effective values after loading.`,ko:`대기 중인 브라우저 프로필이며 아직 적용되지 않았습니다. 명시적 CLI/환경 설정이 우선합니다. 실제 값은 로드 후 확인하세요.`,test_id:`models-next-profile-body`},{key:`models.next_profile.edit`,en:`Edit profile`,ko:`프로필 편집`,test_id:`models-next-profile-edit`},{key:`format.unknown`,en:`unknown`,ko:`알 수 없음`,test_id:`format-unknown`},{key:`format.not_measured`,en:`not yet measured`,ko:`아직 측정되지 않음`,test_id:`format-not-measured`},...we,...Te,...Ee,...De],ke=new Map(Oe.map(e=>[e.key,e]));function z(e,t,n={}){let r=ke.get(t);return r?r[e].replace(/\{(\w+)\}/g,(e,t)=>Object.hasOwn(n,t)?n[t]:`{${t}}`):t}function B(e){return ke.get(e)?.test_id??e.replaceAll(`.`,`-`)}function Ae(e){let t=(0,_.useContext)(xe),n=(0,_.useId)(),r=`${n}-hint`,i=`${n}-error`,a=[e.hint?r:null,e.error?i:null].filter(Boolean).join(` `)||void 0,o=e.disabled||e.busy,s=(0,x.jsxs)(x.Fragment,{children:[e.hint?(0,x.jsx)(`small`,{id:r,"data-tone":`hint`,children:e.hint}):null,e.error?(0,x.jsx)(`small`,{id:i,"data-tone":`error`,children:e.error}):null]});return t?(0,x.jsxs)(`label`,{className:`ds-field`,htmlFor:n,"data-disabled":o||void 0,children:[(0,x.jsx)(`span`,{children:e.label}),(0,x.jsx)(`select`,{id:n,value:e.value,disabled:o,"aria-busy":e.busy||void 0,"aria-invalid":e.error?`true`:void 0,"aria-describedby":a,"data-testid":e.testId,onChange:t=>e.onChange(t.currentTarget.value),children:e.options.map(e=>(0,x.jsx)(`option`,{...e,children:e.label},e.value))}),s]}):(0,x.jsxs)(`div`,{ref:t=>{let n=t?.querySelector(`.select__trigger`);n?.setAttribute(`role`,`combobox`),e.busy?n?.setAttribute(`aria-busy`,`true`):n?.removeAttribute(`aria-busy`)},onKeyDownCapture:e=>{e.nativeEvent.isComposing&&e.stopPropagation()},className:`ds-field ds-common-select`,"data-disabled":o||void 0,"aria-busy":e.busy||void 0,"data-testid":e.testId,children:[(0,x.jsx)(Ce,{value:e.value,options:e.options,onChange:e.onChange,label:e.label,disabled:o,invalid:!!e.error,"aria-describedby":a,fullWidth:!0,noOptionsLabel:z(e.locale??`en`,`select.no_options`),searchPlaceholder:z(e.locale??`en`,`select.search`)}),s]})}var je={narrow:`400px`,medium:`520px`,wide:`900px`};function Me({isOpen:e,onClose:t,title:n,subtitle:r,width:i=`medium`,children:a,footer:o,className:s=``,ariaLabelledBy:c,ariaDescribedBy:l,closeLabel:u=`Close`,preventDismiss:d=!1,onDismissAttempt:f}){let p=(0,_.useRef)(null),[m,h]=(0,_.useState)(!1),g=(0,_.useRef)(d);g.current=d;let v=(0,_.useRef)(f);v.current=f;let y=(0,_.useCallback)(()=>g.current?(h(!0),v.current?.(),!0):!1,[]),b=(0,_.useCallback)(e=>{e.animationName===`drawer-shake`&&h(!1)},[]),S=(0,_.useRef)(null),C=(0,_.useRef)(null),[w,T]=(0,_.useState)(!1),E=(0,_.useRef)(!1);(0,_.useEffect)(()=>{e&&!E.current?(E.current=!0,requestAnimationFrame(()=>{requestAnimationFrame(()=>{T(!0)})})):T(!!e)},[e]);let D=e&&w,O=i in je?je[i]:i,k=c||`drawer-title`,ee=l||(r?`drawer-subtitle`:void 0);(0,_.useEffect)(()=>{if(!e)return;S.current=document.activeElement;let n=p.current;if(!n)return;requestAnimationFrame(()=>{C.current?.focus()});let r=n.querySelectorAll(`button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])`),i=r[0],a=r[r.length-1],o=e=>{if(e.key===`Escape`){if(y())return;t();return}e.key===`Tab`&&(e.shiftKey?document.activeElement===i&&(e.preventDefault(),a?.focus()):document.activeElement===a&&(e.preventDefault(),i?.focus()))};return n.addEventListener(`keydown`,o),()=>{n.removeEventListener(`keydown`,o),S.current&&S.current.focus()}},[e,t,y]);let A=(0,_.useCallback)(e=>{if(e.target===e.currentTarget){if(y())return;t()}},[t,y]);return(0,x.jsx)(`div`,{className:`drawer__backdrop ${D?`drawer__backdrop--open`:``}`,onClick:A,role:`presentation`,"aria-hidden":!e,inert:!e,children:(0,x.jsxs)(`aside`,{ref:p,className:`drawer ${D?`drawer--open`:``} ${m?`drawer--shaking`:``} ${s}`,style:{width:O,maxWidth:`100vw`},role:`dialog`,"aria-modal":`true`,"aria-labelledby":k,"aria-describedby":ee,onAnimationEnd:b,children:[(0,x.jsxs)(`header`,{className:`drawer__header`,children:[(0,x.jsxs)(`div`,{className:`drawer__title-row`,children:[(0,x.jsx)(`h2`,{id:k,className:`drawer__title`,children:n}),(0,x.jsx)(`button`,{ref:C,type:`button`,className:`drawer__close-btn`,onClick:t,"aria-label":u,children:(0,x.jsxs)(`svg`,{width:`20`,height:`20`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,x.jsx)(`path`,{d:`M18 6L6 18`}),(0,x.jsx)(`path`,{d:`M6 6l12 12`})]})})]}),r&&(0,x.jsx)(`p`,{id:ee,className:`drawer__subtitle`,children:r})]}),(0,x.jsx)(`div`,{className:`drawer__content`,children:a}),o&&(0,x.jsx)(`footer`,{className:`drawer__footer`,children:o})]})})}var Ne=120;function Pe({content:e,children:t,className:n,contentClassName:r,tooltipId:i,tabIndex:a=0,toggleable:o=!1}){let[s,c]=(0,_.useState)(!1),[l,u]=(0,_.useState)(null),d=(0,_.useRef)(null),f=(0,_.useRef)(null),p=(0,_.useRef)(!0),m=(0,_.useRef)(null),h=(0,_.useId)(),g=i??`tooltip-${h}`;(0,_.useEffect)(()=>(p.current=!0,()=>{p.current=!1,m.current!==null&&clearTimeout(m.current)}),[]),(0,_.useEffect)(()=>{let e=f.current;if(!e)return;let t=()=>{p.current&&c(!0)},n=()=>{p.current&&(c(!1),u(null))};return e.addEventListener(`focusin`,t),e.addEventListener(`focusout`,n),()=>{e.removeEventListener(`focusin`,t),e.removeEventListener(`focusout`,n)}},[]);let v=(0,_.useCallback)(()=>{let e=f.current,t=d.current;if(!p.current||!e||!t)return;let n=e.getBoundingClientRect(),r=t.getBoundingClientRect(),i=n.top,a=window.innerHeight-n.bottom,o=r.height,s=ii?`bottom`:`top`,c=n.left+n.width/2,l=r.width,m=c-l/2,h=window.innerWidth;m+l>h-16&&(m=h-l-16),m<16&&(m=16);let g=s===`top`?n.top-o-8:n.bottom+8;u({top:g,left:m,placement:s})},[]);(0,_.useLayoutEffect)(()=>{if(s)return v(),window.addEventListener(`scroll`,v,{capture:!0,passive:!0}),window.addEventListener(`resize`,v),()=>{window.removeEventListener(`scroll`,v,{capture:!0}),window.removeEventListener(`resize`,v)}},[s,v]);let y=(0,_.useCallback)(()=>{m.current!==null&&(clearTimeout(m.current),m.current=null),c(!0)},[]),b=(0,_.useCallback)(()=>{m.current!==null&&(clearTimeout(m.current),m.current=null),c(!1),u(null)},[]),S=(0,_.useCallback)(()=>{m.current!==null&&clearTimeout(m.current),m.current=setTimeout(()=>{m.current=null,p.current&&(c(!1),u(null))},Ne)},[]);(0,_.useEffect)(()=>{if(!s)return;let e=e=>{e.key===`Escape`&&b()};return document.addEventListener(`keydown`,e),()=>{document.removeEventListener(`keydown`,e)}},[s,b]);let C=(0,_.useCallback)(e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),s?b():y())},[s,b,y]),w=s&&(0,x.jsx)(`div`,{ref:d,id:g,className:`tooltip__content tooltip__content--${l?.placement??`top`} ${r??``}`,style:l?{top:`${String(l.top)}px`,left:`${String(l.left)}px`}:{visibility:`hidden`},role:`tooltip`,children:typeof e==`string`?(0,x.jsx)(`p`,{className:`tooltip__text`,children:e}):e});return(0,x.jsxs)(`div`,{ref:f,className:`tooltip__wrapper ${n??``}`,onMouseEnter:y,onMouseLeave:S,onKeyDown:o?C:void 0,tabIndex:a,role:o?`button`:void 0,"aria-expanded":o?s:void 0,"aria-describedby":s?g:void 0,children:[t,w&&(0,Se.createPortal)(w,document.body)]})}var Fe=`min(320px, calc(100vw - 32px))`;function Ie(e){let t=(0,_.useId)(),n=(0,_.useRef)(e.onClose);n.current=e.onClose;let r=(0,_.useCallback)(()=>n.current(),[]),i=(0,_.useRef)(null);return(0,_.useEffect)(()=>{if(!e.open)return;let t=0,n=0,a=()=>{let e=i.current?.querySelector(`.drawer`);e&&!e.contains(document.activeElement)&&(e.querySelector(`.drawer__close-btn`)?.focus(),!e.contains(document.activeElement)&&n++<10&&(t=requestAnimationFrame(a)))};t=requestAnimationFrame(a);let o=e=>{if(e.key!==`Escape`||e.isComposing||e.defaultPrevented)return;let t=i.current?.querySelector(`.drawer`);t&&e.target instanceof Node&&t.contains(e.target)||r()};return document.addEventListener(`keydown`,o),()=>{cancelAnimationFrame(t),document.removeEventListener(`keydown`,o)}},[e.open,r]),(0,x.jsx)(`div`,{className:`ds-drawer-host`,ref:t=>{i.current=t,e.testId&&t?.querySelector(`.drawer`)?.setAttribute(`data-testid`,e.testId)},children:(0,x.jsx)(Me,{isOpen:e.open,onClose:r,title:e.title,closeLabel:e.closeLabel,ariaLabelledBy:t,width:Fe,className:`ds-drawer`,children:e.children})})}function Le(e){let t=(0,_.useContext)(xe),n=(0,_.useId)(),r=[e.children.props[`aria-describedby`],n].filter(Boolean).join(` `),i=_.cloneElement(e.children,{"aria-describedby":r});return t?(0,x.jsxs)(`span`,{className:`ds-tooltip-wrap`,children:[i,(0,x.jsx)(`span`,{className:`ds-tooltip`,role:`tooltip`,id:n,children:e.content})]}):(0,x.jsxs)(Pe,{content:e.content,tabIndex:-1,className:`ds-tooltip-trigger`,children:[i,(0,x.jsx)(`span`,{id:n,hidden:!0,children:e.content})]})}var Re=(0,_.forwardRef)(({children:e,className:t=``,style:n,onClick:r,onKeyDown:i,clickable:a,variant:o=`default`,direction:s=`column`,state:c=`idle`,hoverable:l=!0,ariaLabel:u,role:d,ariaChecked:f,tabIndex:p,testId:m},h)=>{let g=a??!!r,_=e=>{i&&i(e),g&&r&&(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),r())},v=[`base-card`,`base-card--${o}`,s===`row`&&`base-card--row`,l&&`base-card--hoverable`,g&&`base-card--clickable`,c!==`idle`&&`base-card--${c}`,t].filter(Boolean).join(` `);return(0,x.jsx)(`div`,{ref:h,className:v,style:n,onClick:r,onKeyDown:_,role:d??(g?`button`:void 0),tabIndex:g?p??0:p,"aria-label":u,"aria-checked":f,"aria-disabled":c===`disabled`||void 0,"data-testid":m,children:e})});Re.displayName=`BaseCard`;function ze({title:e,description:t,actions:n,error:r,onErrorDismiss:i,className:a=``,errorDetail:o,onRetry:s,retryLabel:c=`Retry`,dismissErrorLabel:l=`Dismiss error`}){let u=[`page-header`,a].filter(Boolean).join(` `);return(0,x.jsxs)(`header`,{className:u,children:[(0,x.jsxs)(`div`,{className:`page-header__content`,children:[(0,x.jsxs)(`div`,{className:`page-header__text`,children:[(0,x.jsx)(`h1`,{className:`page-header__title`,children:e}),t&&(0,x.jsx)(`p`,{className:`page-header__description`,children:t})]}),n&&(0,x.jsx)(`div`,{className:`page-header__actions`,children:n})]}),r&&(0,x.jsxs)(`div`,{className:`page-header__error`,role:`alert`,children:[(0,x.jsxs)(`div`,{className:`page-header__error-body`,children:[(0,x.jsx)(`span`,{className:`page-header__error-text`,children:r}),o&&(0,x.jsx)(`span`,{className:`page-header__error-detail`,children:o})]}),(s||i)&&(0,x.jsxs)(`div`,{className:`page-header__error-actions`,children:[s&&(0,x.jsx)(w,{variant:`secondary`,size:`small`,className:`page-header__error-retry`,onClick:s,children:c}),i&&(0,x.jsx)(`button`,{type:`button`,className:`page-header__error-dismiss`,onClick:i,"aria-label":l,children:`×`})]})]})]})}function Be({children:e,variant:t=`standard`,className:n=``,...r}){let i=[`page-layout`,`page-layout--${t}`,n].filter(Boolean).join(` `);return(0,x.jsx)(`div`,{className:i,...r,children:e})}var Ve=250;function He({active:e,children:t,className:n}){let r=(0,_.useRef)(null),i=(0,_.useRef)(null),a=(0,_.useRef)(null);return(0,_.useLayoutEffect)(()=>{let t=r.current,n=i.current;if(!t||!n||typeof ResizeObserver>`u`)return;if(!e)return a.current=window.setTimeout(()=>{t.style.height=``,a.current=null},Ve),()=>{a.current!==null&&(window.clearTimeout(a.current),a.current=null)};a.current!==null&&(window.clearTimeout(a.current),a.current=null);let o=()=>{t.style.height=`${n.offsetHeight.toFixed(0)}px`};o();let s=new ResizeObserver(o);return s.observe(n),()=>{s.disconnect()}},[e]),(0,x.jsx)(`div`,{ref:r,className:`smooth-height${e?` smooth-height--active`:``}${n?` ${n}`:``}`,children:(0,x.jsx)(`div`,{ref:i,className:`smooth-height__content`,children:t})})}function Ue(e){return(0,x.jsx)(Re,{className:`ds-card surface-card ${e.className??``}`.trim(),role:e.role??`article`,ariaLabel:e.ariaLabel,tabIndex:e.tabIndex,hoverable:!1,children:e.children})}function We(e){return(0,x.jsx)(Be,{variant:`wide`,className:`ds-page-layout ${e.className??``}`.trim(),children:e.children})}function Ge(e){return(0,x.jsx)(`div`,{className:`ds-page-header ${e.className??``}`.trim(),ref:t=>{let n=t?.querySelector(`.page-header__title`),r=t?.querySelector(`.page-header__description`);n&&e.titleTestId&&(n.dataset.testid=e.titleTestId),r&&e.descriptionTestId&&(r.dataset.testid=e.descriptionTestId),n&&e.focusFallback&&(n.tabIndex=-1,n.setAttribute(`data-dialog-focus-fallback`,``))},children:(0,x.jsx)(ze,{title:e.title,description:e.description})})}var Ke=400;function qe(e){let[t,n]=(0,_.useState)(e.animate),[r,i]=(0,_.useState)(!1),[a,o]=(0,_.useState)(0);return t!==e.animate&&(n(e.animate),e.animate||(i(!0),o(e=>e+1))),(0,_.useEffect)(()=>{if(!r)return;let e=window.setTimeout(()=>i(!1),Ke);return()=>window.clearTimeout(e)},[r,a]),(0,x.jsx)(He,{active:e.animate||r,className:`ds-smooth-height`,children:e.children})}var Je=`(prefers-reduced-motion: reduce)`;function Ye(){return typeof window>`u`||typeof window.matchMedia!=`function`?!1:window.matchMedia(Je).matches}function Xe(){let[e,t]=(0,_.useState)(Ye);return(0,_.useEffect)(()=>{if(typeof window>`u`||typeof window.matchMedia!=`function`)return;let e=window.matchMedia(Je),n=e=>{t(e.matches)};return e.addEventListener(`change`,n),()=>{e.removeEventListener(`change`,n)}},[]),e}var Ze=800;function Qe(e,t){let[n,r]=(0,_.useState)(t?0:e),i=(0,_.useRef)(t?0:e),a=(0,_.useRef)(null);return(0,_.useEffect)(()=>{if(!t){i.current=e,r(e);return}let n=i.current,o=performance.now(),s=t=>{let c=Math.min((t-o)/Ze,1),l=1-(1-c)**3;r(Math.round(n+(e-n)*l)),c<1?a.current=requestAnimationFrame(s):i.current=e};return a.current=requestAnimationFrame(s),()=>{a.current!==null&&cancelAnimationFrame(a.current)}},[e,t]),t?n:e}var $e={up:`▲`,down:`▼`,flat:`•`};function et(e,t){return typeof e==`number`?t?t(e):e.toLocaleString():e}function tt({label:e,labelNode:t,value:n,valueSuffix:r,hint:i,icon:a,tone:o=`default`,trend:s,onClick:c,loading:l=!1,ariaLabel:u,className:d=``,testId:f,format:p,animate:m=!1,sparkline:h,emphasis:g=`default`}){let _=Xe(),v=typeof n==`number`,y=m&&v&&!l&&!_,b=Qe(v?n:0,y),S=et(v&&y?b:n,p),C=u??(l?e:`${e}: ${et(n,p)}${r??``}`),w=[`stat-card`,`corner-accent`,`stat-card--tone-${o}`,g==="default"?``:`stat-card--${g}`,d].filter(Boolean).join(` `);return(0,x.jsxs)(Re,{className:w,onClick:c,role:c?void 0:`group`,ariaLabel:C,testId:f,children:[(0,x.jsxs)(`div`,{className:`stat-card__header`,children:[(0,x.jsx)(`span`,{className:`stat-card__label`,children:t??e}),a&&(0,x.jsx)(`span`,{className:`stat-card__icon`,"aria-hidden":`true`,children:a})]}),(0,x.jsxs)(`div`,{className:`stat-card__body`,children:[l?(0,x.jsx)(ve,{width:`60%`,height:`2rem`}):h?(0,x.jsxs)(`span`,{className:`stat-card__value-line`,children:[(0,x.jsxs)(`span`,{className:`stat-card__value-row`,children:[(0,x.jsx)(`span`,{className:`stat-card__value`,children:S}),r&&(0,x.jsx)(`span`,{className:`stat-card__value-suffix`,children:r})]}),(0,x.jsx)(`span`,{className:`stat-card__sparkline`,children:h})]}):(0,x.jsxs)(`span`,{className:`stat-card__value-row`,children:[(0,x.jsx)(`span`,{className:`stat-card__value`,children:S}),r&&(0,x.jsx)(`span`,{className:`stat-card__value-suffix`,children:r})]}),s&&!l&&(0,x.jsxs)(`span`,{className:`stat-card__trend stat-card__trend--${s.direction}`,"aria-label":s.ariaLabel??s.label,children:[(0,x.jsx)(`span`,{"aria-hidden":`true`,children:$e[s.direction]}),(0,x.jsx)(`span`,{children:s.label})]})]}),i!=null&&(0,x.jsx)(`div`,{className:`stat-card__hint`,children:l?(0,x.jsx)(ve,{width:`80%`,height:`0.85rem`}):i})]})}var nt=(0,_.memo)(tt);function rt(e){return(0,x.jsx)(nt,{label:e.label,value:e.value,hint:e.hint,className:`ds-stat-card ${e.className??``}`.trim(),testId:e.testId})}function it(e){return(0,x.jsx)(T,{variant:e.tone===`accent`?`primary`:`default`,className:`ds-badge`,children:e.children})}function at(e){let t=(0,_.useId)(),n=`${t}-label`,r=`${t}-hint`,i=`${t}-error`,a=[e.hint?r:null,e.error?i:null].filter(Boolean).join(` `)||void 0;return(0,x.jsxs)(`label`,{className:`ds-field`,htmlFor:t,"data-disabled":e.disabled||e.busy||void 0,children:[(0,x.jsx)(`span`,{id:n,children:e.label}),(0,x.jsx)(`input`,{id:t,"aria-labelledby":n,value:e.value,placeholder:e.placeholder,disabled:e.disabled||e.busy,"aria-busy":e.busy||void 0,"aria-invalid":e.error?`true`:void 0,"aria-describedby":a,"data-testid":e.testId,onChange:t=>e.onChange?.(t.currentTarget.value)}),e.hint?(0,x.jsx)(`small`,{id:r,"data-tone":`hint`,children:e.hint}):null,e.error?(0,x.jsx)(`small`,{id:i,"data-tone":`error`,children:e.error}):null]})}function ot(e){let t=(0,_.useRef)(null),n=(0,_.useRef)(null),r=(0,_.useId)(),i=e.labelledBy??r,a=(0,_.useRef)(!1),o=(0,_.useRef)(e.onClose);return o.current=e.onClose,(0,_.useEffect)(()=>{let r=t.current;r&&(e.open&&!r.open&&(n.current=document.activeElement instanceof HTMLElement?document.activeElement:null,r.showModal(),r.querySelector(`[data-autofocus], button, input, select, textarea, a[href], [tabindex]:not([tabindex="-1"])`)?.focus()),!e.open&&r.open&&(a.current=!0,r.close()))},[e.open]),(0,_.useEffect)(()=>{let e=t.current;if(!e)return;let r=()=>{let t=n.current;st(e,t),n.current=null},i=()=>{a.current?a.current=!1:o.current(),window.setTimeout(r,0)},s=t=>{if(t.key!==`Tab`)return;let n=Array.from(e.querySelectorAll(`button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), a[href], [tabindex]:not([tabindex="-1"])`)).filter(e=>e.offsetParent!==null||e===document.activeElement);if(n.length===0)return;let r=n[0],i=n[n.length-1];t.shiftKey&&document.activeElement===r?(t.preventDefault(),i.focus()):!t.shiftKey&&document.activeElement===i&&(t.preventDefault(),r.focus())};return e.addEventListener(`close`,i),e.addEventListener(`keydown`,s),()=>{e.removeEventListener(`close`,i),e.removeEventListener(`keydown`,s);let t=n.current;window.setTimeout(()=>st(e,t),0)}},[]),(0,x.jsxs)(`dialog`,{className:`ds-dialog ${e.className??``}`.trim(),"data-position":e.position??`center`,ref:t,"aria-labelledby":i,"data-testid":e.testId,children:[(0,x.jsxs)(`header`,{children:[(0,x.jsx)(`h2`,{id:i,children:e.title}),(0,x.jsx)(F,{label:e.closeLabel??`Close`,icon:`close`,onClick:()=>{let e=n.current;a.current=!0,o.current(),t.current?.close(),window.setTimeout(()=>{let n=t.current;n&&st(n,e)},0)},"data-testid":`dialog-close`})]}),(0,x.jsx)(`div`,{children:(0,x.jsx)(xe.Provider,{value:!0,children:e.children})})]})}function st(e,t){if(e.isConnected&&e.open)return;let n=document.activeElement;if(n&&n!==document.body&&n!==document.documentElement&&!e.contains(n)||document.querySelector(`dialog[open]`))return;let r=e=>!!e?.isConnected&&e!==document.body&&!e.matches(`:disabled, [aria-disabled="true"]`)&&!e.closest(`[inert], [hidden]`);if(r(t)){t.focus();return}let i=document.querySelector(`[data-dialog-focus-fallback]`)??document.querySelector(`main button:not(:disabled)`);r(i)&&i.focus()}function ct(e){return(0,x.jsx)(ot,{...e})}function lt(e){return(0,x.jsxs)(ct,{open:e.open,title:e.title,onClose:e.onClose,testId:e.testId,closeLabel:e.closeLabel,children:[(0,x.jsx)(`p`,{children:e.body}),(0,x.jsxs)(`div`,{className:`dialog-actions`,children:[(0,x.jsx)(P,{"data-testid":`${e.testId}-cancel`,onClick:e.onClose,children:e.cancelLabel}),(0,x.jsx)(P,{tone:e.tone??`primary`,busy:e.busy,disabled:e.busy,"data-testid":`${e.testId}-confirm`,onClick:e.onConfirm,children:e.confirmLabel})]})]})}function ut(e){return(0,x.jsxs)(`aside`,{className:`ds-inspector`,"aria-label":e.title,children:[(0,x.jsx)(`h2`,{children:e.title}),e.children]})}function dt(e){return(0,x.jsxs)(`table`,{className:`ds-table`,children:[(0,x.jsx)(`caption`,{children:e.caption}),e.children]})}function ft(e){return(0,x.jsx)(`ul`,{className:`ds-list`,"aria-label":e.label,children:e.children})}function pt(e){let[t,n]=_.useState(``),r=_.useId();return _.useEffect(()=>()=>n(``),[]),(0,x.jsxs)(`form`,{className:`ds-login`,"data-testid":e.testId,autoComplete:`off`,onSubmit:r=>{if(r.preventDefault(),e.busy||t.trim().length===0)return;let i=t;n(``),e.onSubmit(i)},children:[(0,x.jsx)(`h2`,{children:e.title}),(0,x.jsx)(`p`,{children:e.body}),(0,x.jsxs)(`label`,{className:`ds-field`,children:[(0,x.jsx)(`span`,{children:e.tokenLabel}),(0,x.jsx)(`input`,{type:`password`,autoComplete:`off`,spellCheck:!1,autoCapitalize:`none`,autoCorrect:`off`,value:t,disabled:e.busy,"aria-invalid":e.error?`true`:void 0,"aria-describedby":r,onChange:e=>n(e.currentTarget.value)}),(0,x.jsx)(`small`,{id:r,"data-tone":e.error?`error`:`hint`,children:e.error??e.tokenHelp})]}),(0,x.jsxs)(`div`,{className:`dialog-actions`,children:[(0,x.jsx)(P,{tone:`primary`,type:`submit`,busy:e.busy,disabled:t.trim().length===0,children:e.submitLabel}),e.onLogout&&e.logoutLabel?(0,x.jsx)(P,{type:`button`,onClick:()=>{n(``),e.onLogout?.()},children:e.logoutLabel}):null]})]})}function mt(e){return(0,x.jsx)(R,{tone:`error`,title:e.title,body:e.body,action:(0,x.jsxs)(P,{onClick:e.onRecover,children:[(0,x.jsx)(C,{name:`schema`}),e.actionLabel]})})}function ht(e){if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Malformed settings response.`);return e}function gt(e){if(typeof e!=`string`||!/^[0-9a-f]{64}$/.test(e))throw Error(`Malformed settings fingerprint.`);return e}function _t(e){let t=ht(e);if(!Array.isArray(t.schema)||t.schema.length>256)throw Error(`Malformed settings schema.`);let n=new Set;return{schema:t.schema.map(e=>{let t=ht(e);if(typeof t.name!=`string`||n.has(t.name)||typeof t.type!=`string`||![`bool`,`int`,`int_or_null`,`float`,`str`,`str_or_null`,`array`,`object`,`object_or_null`].includes(t.type)||typeof t.mutable!=`boolean`||typeof t.help!=`string`||!(t.allowed===null||Array.isArray(t.allowed)&&t.allowed.every(e=>typeof e==`string`))||t.reason!==void 0&&typeof t.reason!=`string`||!Object.hasOwn(t,`default`))throw Error(`Malformed setting specification.`);return n.add(t.name),t}),current:ht(t.current),fingerprint:gt(t.fingerprint)}}function vt(e){let t=ht(e);if(!Array.isArray(t.rejected)||!t.rejected.every(e=>{let t=ht(e);return typeof t.name==`string`&&typeof t.reason==`string`}))throw Error(`Malformed settings rejection list.`);return{applied:ht(t.applied),rejected:t.rejected,current:ht(t.current),fingerprint:gt(t.fingerprint)}}function yt(e){let t=ht(e),n=ht(t.default_generation_settings),r=e=>typeof e==`number`&&Number.isSafeInteger(e)&&e>0?e:null;return{nCtx:r(n.n_ctx),kvCacheMode:typeof t.kv_cache_mode==`string`&&t.kv_cache_mode.length<=64&&/^[a-z0-9+_-]+$/.test(t.kv_cache_mode)?t.kv_cache_mode:null,totalSlots:r(t.total_slots),geometry:t.geometry===void 0?null:ht(t.geometry)}}function bt(e,t){if(!e.mutable)throw Error(e.reason??`Restart required.`);let n=t;if(![`str`,`str_or_null`].includes(e.type)||e.type===`str_or_null`&&t===`null`)try{n=JSON.parse(t)}catch{throw Error(`Enter a valid ${e.type} value.`)}let r=e.type.endsWith(`_or_null`),i=e.type.replace(`_or_null`,``);if(!(r&&n===null)&&(i===`bool`?typeof n!=`boolean`:i===`int`?typeof n!=`number`||!Number.isSafeInteger(n):i===`float`?typeof n!=`number`||!Number.isFinite(n):i===`str`?typeof n!=`string`:i===`array`?!Array.isArray(n):typeof n!=`object`||!n||Array.isArray(n)))throw Error(`Expected ${e.type}.`);if(e.allowed!==null&&(typeof n!=`string`||!e.allowed.includes(n)))throw Error(`Allowed values: ${e.allowed.join(`, `)}.`);return n}function xt(e,t){return typeof t==`string`&&[`str`,`str_or_null`].includes(e.type)?t:JSON.stringify(t)??``}function St(e){let t=ht(e);if(!Array.isArray(t.tokens)||!t.tokens.every(e=>typeof e==`number`&&Number.isInteger(e)))throw Error(`Malformed tokenization response.`);return t.tokens.length}var Ct=1048576,wt=class{decoder=new TextDecoder(`utf-8`);maxFrameBytes;onMessage;onDone;buffered=``;eventName=``;dataLines=[];id=null;retry=null;frameBytes=0;ended=!1;get done(){return this.ended}constructor(e){this.maxFrameBytes=e.maxFrameBytes??Ct,this.onMessage=e.onMessage,this.onDone=e.onDone}push(e){if(!this.ended){if(this.frameBytes+=e.byteLength,this.frameBytes>this.maxFrameBytes)throw Error(`SSE frame exceeded the configured byte limit.`);this.buffered+=this.decoder.decode(e,{stream:!0}),this.drainLines(!1)}}close(){if(this.ended)return;let e=this.decoder.decode();e.length>0&&(this.buffered+=e),this.drainLines(!0),this.buffered.length>0&&(this.consumeLine(this.buffered),this.buffered=``),this.dispatch()}drainLines(e){for(;this.buffered.length>0;){let t=this.buffered.indexOf(` -`),n=this.buffered.indexOf(`\r`),r;if(r=t===-1?n:n===-1?t:Math.min(t,n),r===-1||this.buffered[r]===`\r`&&this.buffered[r+1]===void 0&&!e)break;let i=this.buffered.slice(0,r),a=this.buffered[r]===`\r`&&this.buffered[r+1]===` -`?r+2:r+1;this.buffered=this.buffered.slice(a),this.consumeLine(i)}e&&this.buffered.length===0&&this.dispatch()}consumeLine(e){if(e.length===0){this.dispatch();return}if(e.startsWith(`:`))return;let t=e.indexOf(`:`),n=t===-1?e:e.slice(0,t),r=t===-1?``:e.slice(t+1),i=r.startsWith(` `)?r.slice(1):r;n===`event`?this.eventName=i:n===`data`?this.dataLines.push(i):n===`id`?this.id=i:n===`retry`&&/^\d+$/.test(i)&&(this.retry=Number(i))}dispatch(){if(this.dataLines.length===0){this.eventName=``,this.retry=null,this.frameBytes=0;return}let e=this.dataLines.join(` -`),t=this.eventName.length===0?`message`:this.eventName;if(this.eventName=``,this.dataLines=[],this.frameBytes=0,e===`[DONE]`){this.ended=!0,this.onDone?.();return}this.onMessage({event:t,data:e,id:this.id,retry:this.retry}),this.retry=null}};function Tt(e){return Array.from(e).some(e=>{let t=e.charCodeAt(0);return t<=32||t>=127&&t<=159})}function Et(e){if(/[\\?#]/.test(e)||Tt(e)||e.includes(`//`))throw Error(`WebUI API base must not contain a query, hash, backslash, whitespace, controls or empty path segments.`);for(let t of e.split(`/`)){let e;try{e=decodeURIComponent(t)}catch{throw Error(`WebUI API base contains an invalid path escape.`)}if(e===`.`||e===`..`)throw Error(`WebUI API base must not contain dot path segments.`);if(/[/\\%?#]/.test(e)||Tt(e))throw Error(`WebUI API base contains an ambiguous encoded path segment.`)}}function Dt(e){let t=e??kt();if(t===``)return``;if(!t.startsWith(`/`)||t.startsWith(`//`))throw Error(`WebUI API base must be a same-origin absolute path.`);return Et(t),new URL(t,`http://webui.invalid`).pathname.replace(/\/$/,``)}function Ot(e){return/^(.*)\/webui(?:\/(?:index\.html)?)?$/.exec(e)?.[1]??null}function kt(){if(typeof document>`u`)return``;let e=document.querySelector(`meta[name="mlxcel-ui-api-base"]`)?.content;if(e!==void 0&&e.length>0)return Dt(e);let t=document.querySelector(`base`)?.getAttribute(`href`);if(t!=null&&t.length>0){let e=t.replace(/^[a-z][a-z\d+.-]*:\/\/[^/]*/i,``);Et(e===`.`?``:e.replace(/^\.\//,``));let n=new URL(t,document.URL);if(n.origin!==window.location.origin||n.username||n.password||n.search||n.hash)throw Error(`WebUI document base must stay on the current origin without credentials, query or hash.`);return Dt(Ot(n.pathname)??n.pathname)}let n=window.location.pathname,r=Ot(n);return r===null?``:(Et(n),Dt(r))}function At(e,t,n){if(!t.startsWith(`/ui-api/v1/`)&&t!==`/v1/chat/completions`&&t!==`/v1/responses`&&t!==`/settings`&&t!==`/props`&&t!==`/tokenize`)throw Error(`WebUI client paths must stay under /ui-api/v1/ or the approved inference stream endpoints.`);let r=new URLSearchParams;for(let[e,t]of Object.entries(n??{}))t!=null&&r.set(e,String(t));return`${e}${t}${r.size===0?``:`?${r.toString()}`}`}function jt(e){if(e.length===0)throw Error(`Opaque path segment must not be empty.`);return encodeURIComponent(e)}var Mt=`{ - "openapi": "3.1.0", - "info": { - "title": "mlxcel WebUI local control API", - "version": "1.0.0", - "description": "Contract gate for epic #1834. This file is JSON-compatible YAML by policy so the validator has no external dependency." - }, - "servers": [ - { - "url": "{api_prefix}", - "variables": { - "api_prefix": { - "default": "", - "description": "Validated server API prefix; paths below include /ui-api/v1 and the prefix is never derived from browser input." - } - } - } - ], - "security": [ - { - "bearerAuth": [] - } - ], - "paths": { - "/ui-api/v1/bootstrap": { - "get": { - "summary": "Return server identity, enabled features, redacted roots and hard limits without model initialization.", - "responses": { - "200": { - "description": "Bootstrap response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/BootstrapResponse" - }, - "examples": { - "fixture": { - "externalValue": "../../tests/fixtures/webui/examples/bootstrap.model-free.json" - } - } - } - } - }, - "401": { - "description": "Authentication required", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - }, - "403": { - "description": "Forbidden by browser security checks", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - } - } - } - }, - "/ui-api/v1/catalog": { - "get": { - "summary": "List the deterministic model inventory. Query: limit 1..200 default 50, cursor, q, source, task, lifecycle, support, completeness. No downloads or loads.", - "responses": { - "200": { - "description": "Catalog page", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CatalogListResponse" - }, - "examples": { - "fixture": { - "externalValue": "../../tests/fixtures/webui/examples/catalog.page.json" - } - } - } - } - }, - "400": { - "description": "Invalid filter or cursor", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - }, - "401": { - "description": "Authentication required", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - }, - "403": { - "description": "Forbidden by browser security checks", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - } - }, - "parameters": [ - { - "name": "limit", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "minimum": 1, - "maximum": 200, - "default": 50 - }, - "description": "Page size. Values above 200 are rejected rather than clamped." - }, - { - "name": "cursor", - "in": "query", - "required": false, - "schema": { - "$ref": "#/components/schemas/CursorToken" - }, - "description": "Opaque cursor returned by the previous page." - }, - { - "name": "q", - "in": "query", - "required": false, - "schema": { - "type": "string", - "maxLength": 128 - }, - "description": "Case-insensitive display/inference-id substring filter." - }, - { - "name": "source", - "in": "query", - "required": false, - "schema": { - "$ref": "#/components/schemas/CatalogSourceKind" - }, - "description": "Filter by source kind." - }, - { - "name": "task", - "in": "query", - "required": false, - "schema": { - "$ref": "#/components/schemas/TaskKind" - }, - "description": "Filter by declared task capability." - }, - { - "name": "lifecycle", - "in": "query", - "required": false, - "schema": { - "$ref": "#/components/schemas/ModelLifecycleState" - }, - "description": "Filter by inference lifecycle state." - }, - { - "name": "support", - "in": "query", - "required": false, - "schema": { - "type": "boolean" - }, - "description": "true keeps supported+runnable entries, false keeps unsupported entries." - }, - { - "name": "completeness", - "in": "query", - "required": false, - "schema": { - "type": "boolean" - }, - "description": "true keeps complete checkpoints, false keeps incomplete entries." - } - ] - } - }, - "/ui-api/v1/catalog/{id}": { - "get": { - "summary": "Read one catalog entry by opaque model id.", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "$ref": "#/components/schemas/ModelId" - } - } - ], - "responses": { - "200": { - "description": "Catalog entry", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CatalogEntry" - } - } - } - }, - "404": { - "description": "Unknown model id", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - }, - "401": { - "description": "Authentication required", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - }, - "403": { - "description": "Forbidden by browser security checks", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - } - } - } - }, - "/ui-api/v1/catalog/refresh": { - "post": { - "summary": "Start a bounded background rescan; GET never mutates.", - "responses": { - "202": { - "description": "Accepted", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/OperationAccepted" - } - } - } - }, - "429": { - "description": "Operation limit", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - }, - "401": { - "description": "Authentication required", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - }, - "403": { - "description": "Forbidden by browser security checks", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - }, - "422": { - "description": "Catalog refresh is unsupported in read-only single-model mode", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - } - } - } - }, - "/ui-api/v1/model-actions": { - "post": { - "summary": "Load or unload through the shared lifecycle coordinator. Duplicate idempotency keys replay the original operation inside this server instance.", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ModelActionRequest" - }, - "examples": { - "fixture": { - "externalValue": "../../tests/fixtures/webui/examples/request.model-action.load.json" - } - } - } - } - }, - "responses": { - "202": { - "description": "Accepted", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/OperationAccepted" - }, - "examples": { - "fixture": { - "externalValue": "../../tests/fixtures/webui/examples/operation.accepted.json" - } - } - } - } - }, - "409": { - "description": "Stale revision or conflicting action", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - }, - "422": { - "description": "Unsupported action/profile", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - }, - "401": { - "description": "Authentication required", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - }, - "403": { - "description": "Forbidden by browser security checks", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - }, - "413": { - "description": "JSON request body exceeds the WebUI contract limit", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - } - } - } - }, - "/ui-api/v1/downloads": { - "post": { - "summary": "Download a public HuggingFace repository into the configured cache after explicit consent.", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DownloadRequest" - }, - "examples": { - "fixture": { - "externalValue": "../../tests/fixtures/webui/examples/request.download.json" - } - } - } - } - }, - "responses": { - "202": { - "description": "Accepted", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/OperationAccepted" - }, - "examples": { - "fixture": { - "externalValue": "../../tests/fixtures/webui/examples/operation.accepted.json" - } - } - } - } - }, - "422": { - "description": "Invalid or unsupported repository", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - }, - "401": { - "description": "Authentication required", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - }, - "403": { - "description": "Forbidden by browser security checks", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - }, - "413": { - "description": "JSON request body exceeds the WebUI contract limit", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - } - } - } - }, - "/ui-api/v1/model-removals": { - "post": { - "summary": "Remove a cache-owned model only after server checks and UI confirmation.", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RemovalRequest" - }, - "examples": { - "fixture": { - "externalValue": "../../tests/fixtures/webui/examples/request.removal.json" - } - } - } - } - }, - "responses": { - "202": { - "description": "Accepted", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/OperationAccepted" - }, - "examples": { - "fixture": { - "externalValue": "../../tests/fixtures/webui/examples/operation.accepted.json" - } - } - } - } - }, - "409": { - "description": "Busy/loading/downloading/draining model", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - }, - "422": { - "description": "Non-cache model cannot be removed", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - }, - "401": { - "description": "Authentication required", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - }, - "403": { - "description": "Forbidden by browser security checks", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - }, - "413": { - "description": "JSON request body exceeds the WebUI contract limit", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - } - } - } - }, - "/ui-api/v1/operations": { - "get": { - "summary": "List active operations plus the bounded terminal history. Query: limit default 50 max 200, cursor, state, kind, target.", - "responses": { - "200": { - "description": "Operations page", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/OperationsListResponse" - }, - "examples": { - "fixture": { - "externalValue": "../../tests/fixtures/webui/examples/operations.list.json" - } - } - } - } - }, - "401": { - "description": "Authentication required", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - }, - "403": { - "description": "Forbidden by browser security checks", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - } - }, - "parameters": [ - { - "name": "limit", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "minimum": 1, - "maximum": 200, - "default": 50 - }, - "description": "Page size for active plus terminal operation records." - }, - { - "name": "cursor", - "in": "query", - "required": false, - "schema": { - "$ref": "#/components/schemas/CursorToken" - }, - "description": "Opaque cursor returned by the previous page." - }, - { - "name": "state", - "in": "query", - "required": false, - "schema": { - "$ref": "#/components/schemas/OperationState" - }, - "description": "Filter by operation state." - }, - { - "name": "kind", - "in": "query", - "required": false, - "schema": { - "$ref": "#/components/schemas/OperationKind" - }, - "description": "Filter by operation kind." - }, - { - "name": "target", - "in": "query", - "required": false, - "schema": { - "type": "string", - "maxLength": 128, - "pattern": "^[A-Za-z0-9._~-]{1,128}(?![\\\\s\\\\S])" - }, - "description": "Opaque model id or operation target token; never a filesystem path." - } - ] - } - }, - "/ui-api/v1/operations/{id}": { - "get": { - "summary": "Read one operation by id.", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "$ref": "#/components/schemas/OperationId" - } - } - ], - "responses": { - "200": { - "description": "Operation", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Operation" - }, - "examples": { - "fixture": { - "externalValue": "../../tests/fixtures/webui/examples/operation.running.json" - } - } - } - } - }, - "404": { - "description": "Unknown operation", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - }, - "401": { - "description": "Authentication required", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - }, - "403": { - "description": "Forbidden by browser security checks", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - } - } - } - }, - "/ui-api/v1/operations/{id}/cancel": { - "post": { - "summary": "Request cancellation; completion is reported only after the worker stops or cancellation is rejected.", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "$ref": "#/components/schemas/OperationId" - } - } - ], - "responses": { - "202": { - "description": "Cancellation accepted", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/OperationAccepted" - } - } - } - }, - "422": { - "description": "Cancellation unsupported", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - }, - "401": { - "description": "Authentication required", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - }, - "403": { - "description": "Forbidden by browser security checks", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - } - } - } - }, - "/ui-api/v1/events": { - "get": { - "summary": "Authenticated SSE stream. Clients normally reconnect with the paired server_instance_id and after_sequence query cursor computed from the minimum authoritative resource fence. Last-Event-ID remains supported only as an opaque legacy replay cursor and must not be sent together with the paired query cursor. Ring gaps or changed server_instance_id produce a reset event and full resnapshot.", - "responses": { - "200": { - "description": "SSE event stream carrying UiEvent JSON payloads" - }, - "409": { - "description": "Replay gap or server restart", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - }, - "401": { - "description": "Authentication required", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - }, - "403": { - "description": "Forbidden by browser security checks", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - } - }, - "parameters": [ - { - "name": "Last-Event-ID", - "in": "header", - "required": false, - "schema": { - "$ref": "#/components/schemas/EventId" - }, - "description": "Opaque event id from the last applied SSE event. It is a legacy cursor and is rejected when either paired replay query parameter is present." - }, - { - "name": "server_instance_id", - "in": "query", - "required": false, - "schema": { - "$ref": "#/components/schemas/ServerInstanceId" - }, - "description": "Server instance that produced after_sequence. Required exactly when after_sequence is supplied; a different instance returns a typed server_restart event." - }, - { - "name": "after_sequence", - "in": "query", - "required": false, - "schema": { - "$ref": "#/components/schemas/EventSequence" - }, - "description": "Replay every retained event with sequence greater than this value. Required exactly when server_instance_id is supplied; 0 and the current sequence are valid. Non-safe integers, future sequences, duplicate parameters and malformed values are rejected." - } - ] - } - }, - "/ui-api/v1/runtime": { - "get": { - "summary": "Model-scoped observation snapshot from existing settings/slot/cache/worker counters. Query: model_id required. No autoload and no sampling work.", - "parameters": [ - { - "name": "model_id", - "in": "query", - "required": true, - "schema": { - "$ref": "#/components/schemas/ModelId" - } - } - ], - "responses": { - "200": { - "description": "Runtime snapshot", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RuntimeSnapshot" - }, - "examples": { - "fixture": { - "externalValue": "../../tests/fixtures/webui/examples/runtime.snapshot.json" - } - } - } - } - }, - "404": { - "description": "Unknown model id", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - }, - "401": { - "description": "Authentication required", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - }, - "403": { - "description": "Forbidden by browser security checks", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorEnvelope" - } - } - } - } - } - } - } - }, - "components": { - "securitySchemes": { - "bearerAuth": { - "type": "http", - "scheme": "bearer" - } - }, - "schemas": { - "SchemaVersion": { - "type": "string", - "const": "webui.ui-api.v1" - }, - "ServerMode": { - "type": "string", - "enum": [ - "model_free", - "single_model", - "router_pool" - ] - }, - "FeatureFlag": { - "type": "string", - "enum": [ - "webui", - "catalog", - "download", - "cache_delete", - "load", - "unload", - "chat", - "runtime", - "settings", - "local_history", - "image_input" - ] - }, - "CapabilityPhase": { - "type": "string", - "enum": [ - "pre_load", - "provider_ready" - ] - }, - "ActionState": { - "type": "string", - "enum": [ - "enabled", - "disabled", - "read_only" - ] - }, - "ModelLifecycleState": { - "type": "string", - "enum": [ - "unloaded", - "loading", - "ready", - "draining", - "unloading", - "failed" - ] - }, - "DownloadState": { - "type": "string", - "enum": [ - "absent", - "downloading", - "complete", - "incomplete", - "failed" - ] - }, - "OperationState": { - "type": "string", - "enum": [ - "queued", - "running", - "cancelling", - "succeeded", - "failed", - "cancelled" - ] - }, - "OperationKind": { - "type": "string", - "enum": [ - "catalog_refresh", - "model_load", - "model_unload", - "download", - "model_removal", - "settings_patch" - ] - }, - "CatalogSourceKind": { - "type": "string", - "enum": [ - "cache", - "models_dir", - "preset", - "single_model" - ] - }, - "TaskKind": { - "type": "string", - "enum": [ - "chat", - "completion", - "embedding", - "rerank", - "audio_transcription", - "audio_speech", - "vision_input", - "image_generation" - ] - }, - "UiEventType": { - "type": "string", - "enum": [ - "snapshot", - "model_revision", - "operation", - "download_progress", - "runtime", - "settings", - "reset", - "gap", - "server_restart", - "heartbeat" - ] - }, - "ServerInstanceId": { - "type": "string", - "minLength": 1, - "maxLength": 128, - "pattern": "^[A-Za-z0-9._~-]{1,128}(?![\\\\s\\\\S])", - "description": "Opaque per-process server instance id; never carries a path or credential." - }, - "ModelId": { - "type": "string", - "pattern": "^mdl_[A-Za-z0-9_-]{43}(?![\\\\s\\\\S])", - "description": "Opaque stable UI model id." - }, - "OperationId": { - "type": "string", - "minLength": 1, - "maxLength": 128, - "pattern": "^[A-Za-z0-9._~-]{1,128}(?![\\\\s\\\\S])", - "description": "Opaque operation id; printable token only." - }, - "EventId": { - "type": "string", - "minLength": 1, - "maxLength": 160, - "pattern": "^evt_[A-Za-z0-9._~-]{1,160}(?![\\\\s\\\\S])", - "description": "Opaque SSE event id; also sent as the SSE id field." - }, - "EventSequence": { - "type": "integer", - "minimum": 0, - "maximum": 9007199254740991, - "description": "Non-negative UI event sequence small enough to round-trip through JavaScript Number without precision loss." - }, - "EventReplayQuery": { - "type": "object", - "additionalProperties": false, - "required": [ - "server_instance_id", - "after_sequence" - ], - "properties": { - "server_instance_id": { - "$ref": "#/components/schemas/ServerInstanceId" - }, - "after_sequence": { - "$ref": "#/components/schemas/EventSequence" - } - } - }, - "CursorToken": { - "type": "string", - "minLength": 1, - "maxLength": 512, - "pattern": "^[A-Za-z0-9._~-]{1,512}(?![\\\\s\\\\S])", - "description": "Opaque pagination cursor. Control characters, slashes and backslashes are forbidden." - }, - "IdempotencyKey": { - "type": "string", - "minLength": 8, - "maxLength": 128, - "pattern": "^[A-Za-z0-9._~-]{8,128}(?![\\\\s\\\\S])", - "description": "Client-supplied idempotency token scoped to one server instance; printable token only." - }, - "HuggingFaceRepoId": { - "type": "string", - "minLength": 1, - "maxLength": 193, - "pattern": "^(?!.*(?:^|/)\\\\.\\\\.?($|/))[A-Za-z0-9][A-Za-z0-9._-]{0,95}/[A-Za-z0-9][A-Za-z0-9._-]{0,95}(?![\\\\s\\\\S])", - "description": "Public HuggingFace owner/name id. Dot-only path segments and URL/path syntax are rejected." - }, - "RevisionRef": { - "type": [ - "string", - "null" - ], - "minLength": 1, - "maxLength": 128, - "pattern": "^(?!.*(?:^|/)\\\\.\\\\.?($|/))[A-Za-z0-9._~+/-]+(?![\\\\s\\\\S])", - "description": "Repository revision ref resolved and pinned before writing weights. Dot-only path segments and control characters are rejected." - }, - "ApiBase": { - "type": "string", - "minLength": 0, - "maxLength": 128, - "pattern": "^(?![\\\\s\\\\S])|^/(?!/)(?!.*//)(?!.*(?:^|/)\\\\.\\\\.?($|/))[A-Za-z0-9._~!$&'()*+,;=:@%/-]*(?![\\\\s\\\\S])", - "description": "Validated same-origin relative API prefix. Protocol-relative URLs, query strings, fragments, dot segments and doubled slashes are rejected." - }, - "KvCacheModeName": { - "type": "string", - "enum": [ - "fp16", - "float16", - "int8", - "i8", - "turbo4-asym", - "fp16+turbo4", - "turbo3-asym", - "fp16+turbo3", - "turbo3", - "turbo4", - "turbo4-sym", - "turbo4-delegated", - "fp16+turbo4-delegated" - ], - "description": "Accepted by KVCacheMode::from_str / --kv-cache-mode; GGML-only cache spellings such as q8_0 are intentionally absent." - }, - "ErrorCode": { - "type": "string", - "enum": [ - "invalid_request", - "unauthorized", - "forbidden", - "not_found", - "stale_revision", - "conflict", - "unsupported", - "rate_limited", - "unavailable", - "payload_too_large", - "server_restarted", - "event_gap", - "partial_success" - ] - }, - "FieldError": { - "type": "object", - "additionalProperties": false, - "required": [ - "field", - "code", - "message" - ], - "properties": { - "field": { - "type": "string", - "minLength": 1, - "maxLength": 128, - "pattern": "^[A-Za-z0-9_.:-]+(?![\\\\s\\\\S])" - }, - "code": { - "type": "string", - "minLength": 1, - "maxLength": 64, - "pattern": "^[A-Za-z0-9_.:-]+(?![\\\\s\\\\S])" - }, - "message": { - "type": "string", - "minLength": 1, - "maxLength": 512 - } - } - }, - "ErrorBody": { - "type": "object", - "additionalProperties": false, - "required": [ - "code", - "message", - "retryable" - ], - "properties": { - "code": { - "$ref": "#/components/schemas/ErrorCode" - }, - "message": { - "type": "string", - "minLength": 1, - "maxLength": 512 - }, - "retryable": { - "type": "boolean" - }, - "field_errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/FieldError" - }, - "maxItems": 16 - }, - "operation_id": { - "$ref": "#/components/schemas/OperationId" - } - } - }, - "ErrorEnvelope": { - "type": "object", - "additionalProperties": false, - "required": [ - "error", - "request_id" - ], - "properties": { - "error": { - "$ref": "#/components/schemas/ErrorBody" - }, - "request_id": { - "$ref": "#/components/schemas/OperationId" - } - } - }, - "ActionAvailability": { - "type": "object", - "additionalProperties": false, - "required": [ - "state", - "reason" - ], - "properties": { - "state": { - "$ref": "#/components/schemas/ActionState" - }, - "reason": { - "type": [ - "string", - "null" - ], - "maxLength": 256 - }, - "instructions": { - "type": [ - "string", - "null" - ], - "maxLength": 512 - } - } - }, - "BuildInfo": { - "type": "object", - "additionalProperties": false, - "required": [ - "version", - "git_commit", - "target", - "features" - ], - "properties": { - "version": { - "type": "string" - }, - "git_commit": { - "type": [ - "string", - "null" - ] - }, - "target": { - "type": "string" - }, - "features": { - "type": "array", - "items": { - "$ref": "#/components/schemas/FeatureFlag" - } - } - } - }, - "BackendIdentity": { - "type": "object", - "additionalProperties": false, - "required": [ - "server_instance_id", - "mode", - "api_base", - "auth_required", - "build" - ], - "properties": { - "server_instance_id": { - "$ref": "#/components/schemas/ServerInstanceId" - }, - "mode": { - "$ref": "#/components/schemas/ServerMode" - }, - "api_base": { - "$ref": "#/components/schemas/ApiBase" - }, - "auth_required": { - "type": "boolean" - }, - "build": { - "$ref": "#/components/schemas/BuildInfo" - } - } - }, - "RootSummary": { - "type": "object", - "additionalProperties": false, - "required": [ - "kind", - "display_name", - "redacted" - ], - "properties": { - "kind": { - "type": "string", - "enum": [ - "cache", - "models_dir", - "preset_file", - "single_model" - ] - }, - "display_name": { - "type": "string", - "minLength": 1, - "maxLength": 128 - }, - "redacted": { - "type": "boolean" - }, - "writable": { - "type": "boolean" - }, - "error": { - "type": [ - "string", - "null" - ], - "maxLength": 512 - } - } - }, - "LimitSummary": { - "type": "object", - "additionalProperties": false, - "required": [ - "catalog_default_page_size", - "catalog_max_page_size", - "json_body_bytes", - "metadata_bytes_per_entry", - "events_ring_size", - "events_retention_seconds", - "terminal_operations_retained", - "terminal_operations_retention_seconds", - "max_active_operations", - "max_concurrent_loads", - "max_concurrent_downloads", - "next_load_ctx_size_max", - "next_load_n_parallel_max", - "cursor_bytes", - "settings_fields_max", - "measurements_max" - ], - "properties": { - "catalog_default_page_size": { - "type": "integer", - "const": 50 - }, - "catalog_max_page_size": { - "type": "integer", - "const": 200 - }, - "json_body_bytes": { - "type": "integer", - "const": 2097152 - }, - "metadata_bytes_per_entry": { - "type": "integer", - "const": 16384 - }, - "events_ring_size": { - "type": "integer", - "const": 1024 - }, - "events_retention_seconds": { - "type": "integer", - "const": 600 - }, - "terminal_operations_retained": { - "type": "integer", - "const": 200 - }, - "terminal_operations_retention_seconds": { - "type": "integer", - "const": 3600 - }, - "max_active_operations": { - "type": "integer", - "const": 64 - }, - "max_concurrent_loads": { - "type": "integer", - "const": 1 - }, - "max_concurrent_downloads": { - "type": "integer", - "const": 1 - }, - "next_load_ctx_size_max": { - "type": "integer", - "const": 262144 - }, - "next_load_n_parallel_max": { - "type": "integer", - "const": 32 - }, - "cursor_bytes": { - "type": "integer", - "const": 512 - }, - "settings_fields_max": { - "type": "integer", - "const": 64 - }, - "measurements_max": { - "type": "integer", - "const": 64 - } - } - }, - "BootstrapResponse": { - "type": "object", - "additionalProperties": false, - "required": [ - "schema_version", - "server", - "features", - "actions", - "roots", - "limits", - "media_limits" - ], - "properties": { - "schema_version": { - "$ref": "#/components/schemas/SchemaVersion" - }, - "server": { - "$ref": "#/components/schemas/BackendIdentity" - }, - "features": { - "type": "array", - "items": { - "$ref": "#/components/schemas/FeatureFlag" - }, - "maxItems": 16 - }, - "actions": { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/ActionAvailability" - }, - "maxProperties": 32 - }, - "roots": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RootSummary" - }, - "maxItems": 8 - }, - "limits": { - "$ref": "#/components/schemas/LimitSummary" - }, - "media_limits": { - "$ref": "#/components/schemas/MediaLimits" - } - } - }, - "ModelIdentity": { - "type": "object", - "additionalProperties": false, - "required": [ - "id", - "inference_id", - "display_name", - "source", - "source_key_hash", - "generation", - "revision", - "content_fingerprint" - ], - "properties": { - "id": { - "$ref": "#/components/schemas/ModelId" - }, - "inference_id": { - "type": "string", - "minLength": 1, - "maxLength": 256 - }, - "display_name": { - "type": "string", - "minLength": 1, - "maxLength": 256, - "description": "The model's inference id with no character rewriting: the full id for cache and preset entries (owner/name for a cache repo), the directory name for models_dir entries, and the last /-separated segment of the served id for single_model. A label only: select and operate on a model by id." - }, - "source": { - "$ref": "#/components/schemas/CatalogSourceKind" - }, - "source_key_hash": { - "type": "string", - "pattern": "^[a-f0-9]{64}(?![\\\\s\\\\S])", - "description": "SHA-256 of the redacted canonical source key; used for collision tests without exposing paths." - }, - "generation": { - "type": "integer", - "minimum": 1 - }, - "revision": { - "type": "integer", - "minimum": 1 - }, - "content_fingerprint": { - "type": [ - "string", - "null" - ], - "description": "Fingerprint of currently observed checkpoint content when known; affects generation/revision, not stable ID.", - "maxLength": 128 - } - } - }, - "MeasuredValue": { - "type": "object", - "additionalProperties": false, - "required": [ - "value", - "unit", - "scope", - "measured_at", - "reason" - ], - "properties": { - "value": { - "type": [ - "number", - "null" - ] - }, - "unit": { - "type": "string", - "maxLength": 32 - }, - "scope": { - "type": "string", - "enum": [ - "model", - "slot", - "pool", - "server", - "unknown" - ] - }, - "measured_at": { - "anyOf": [ - { - "type": "string", - "format": "date-time" - }, - { - "type": "null" - } - ] - }, - "reason": { - "type": [ - "string", - "null" - ], - "maxLength": 256 - } - } - }, - "Capability": { - "type": "object", - "additionalProperties": false, - "required": [ - "task", - "phase", - "available", - "reason" - ], - "properties": { - "task": { - "$ref": "#/components/schemas/TaskKind" - }, - "phase": { - "$ref": "#/components/schemas/CapabilityPhase" - }, - "available": { - "type": "boolean" - }, - "reason": { - "type": [ - "string", - "null" - ], - "maxLength": 256 - } - } - }, - "LifecycleSnapshot": { - "type": "object", - "additionalProperties": false, - "required": [ - "state", - "download", - "busy", - "active_requests", - "draining_requests", - "worker_exit_observed", - "last_error" - ], - "properties": { - "state": { - "$ref": "#/components/schemas/ModelLifecycleState" - }, - "download": { - "$ref": "#/components/schemas/DownloadState" - }, - "busy": { - "type": "boolean" - }, - "active_requests": { - "type": "integer", - "minimum": 0 - }, - "draining_requests": { - "type": "integer", - "minimum": 0 - }, - "worker_exit_observed": { - "type": "boolean" - }, - "last_error": { - "type": [ - "string", - "null" - ], - "maxLength": 512 - } - } - }, - "CatalogEntry": { - "type": "object", - "additionalProperties": false, - "required": [ - "identity", - "capabilities", - "lifecycle", - "complete", - "supported", - "removable", - "metadata", - "removal" - ], - "properties": { - "identity": { - "$ref": "#/components/schemas/ModelIdentity" - }, - "capabilities": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Capability" - }, - "maxItems": 16 - }, - "lifecycle": { - "$ref": "#/components/schemas/LifecycleSnapshot" - }, - "complete": { - "type": "boolean" - }, - "supported": { - "type": "boolean" - }, - "removable": { - "type": "boolean" - }, - "metadata": { - "$ref": "#/components/schemas/CatalogMetadata" - }, - "removal": { - "$ref": "#/components/schemas/RemovalStatus" - } - } - }, - "Pagination": { - "type": "object", - "additionalProperties": false, - "required": [ - "limit", - "next_cursor", - "total_known" - ], - "properties": { - "limit": { - "type": "integer", - "minimum": 1, - "maximum": 200 - }, - "next_cursor": { - "type": [ - "string", - "null" - ], - "maxLength": 512, - "pattern": "^[A-Za-z0-9._~-]{1,512}(?![\\\\s\\\\S])" - }, - "total_known": { - "type": [ - "integer", - "null" - ], - "minimum": 0 - } - } - }, - "CatalogListResponse": { - "type": "object", - "additionalProperties": false, - "required": [ - "schema_version", - "items", - "pagination", - "server_instance_id", - "snapshot_sequence" - ], - "properties": { - "schema_version": { - "$ref": "#/components/schemas/SchemaVersion" - }, - "items": { - "type": "array", - "items": { - "$ref": "#/components/schemas/CatalogEntry" - }, - "maxItems": 200 - }, - "pagination": { - "$ref": "#/components/schemas/Pagination" - }, - "server_instance_id": { - "$ref": "#/components/schemas/ServerInstanceId" - }, - "snapshot_sequence": { - "$ref": "#/components/schemas/EventSequence", - "description": "Single global event sequence after which this snapshot is authoritative." - } - } - }, - "LoadProfile": { - "type": "object", - "additionalProperties": false, - "required": [], - "description": "Next-load profile override. Contract gate #1835 intentionally exposes only #1846-approved fields backed by existing server startup validators.", - "properties": { - "ctx_size": { - "type": [ - "integer", - "null" - ], - "minimum": 1, - "maximum": 262144, - "description": "Maps to existing --ctx-size; WebUI rejects larger values rather than attempting a new runtime mode." - }, - "n_parallel": { - "type": [ - "integer", - "null" - ], - "minimum": 1, - "maximum": 32, - "description": "Maps to existing --parallel/--n-parallel slot count." - }, - "kv_cache_mode": { - "anyOf": [ - { - "$ref": "#/components/schemas/KvCacheModeName" - }, - { - "type": "null" - } - ] - } - } - }, - "ModelActionRequest": { - "type": "object", - "additionalProperties": false, - "required": [ - "model_id", - "action", - "expected_revision", - "idempotency_key" - ], - "properties": { - "model_id": { - "$ref": "#/components/schemas/ModelId" - }, - "action": { - "type": "string", - "enum": [ - "load", - "unload" - ] - }, - "expected_revision": { - "type": "integer", - "minimum": 1 - }, - "idempotency_key": { - "$ref": "#/components/schemas/IdempotencyKey" - }, - "load_profile": { - "$ref": "#/components/schemas/LoadProfile" - }, - "eviction_target_id": { - "$ref": "#/components/schemas/ModelId" - }, - "eviction_target_expected_revision": { - "type": "integer", - "minimum": 1, - "description": "Catalog revision of eviction_target_id observed when the user confirmed the eviction; required when eviction_target_id is present and forbidden otherwise." - } - } - }, - "DownloadRequest": { - "type": "object", - "additionalProperties": false, - "required": [ - "repo_id", - "idempotency_key" - ], - "properties": { - "repo_id": { - "$ref": "#/components/schemas/HuggingFaceRepoId" - }, - "revision": { - "$ref": "#/components/schemas/RevisionRef" - }, - "idempotency_key": { - "$ref": "#/components/schemas/IdempotencyKey" - } - } - }, - "RemovalRequest": { - "type": "object", - "additionalProperties": false, - "required": [ - "model_id", - "expected_revision", - "idempotency_key" - ], - "properties": { - "model_id": { - "$ref": "#/components/schemas/ModelId" - }, - "expected_revision": { - "type": "integer", - "minimum": 1 - }, - "idempotency_key": { - "$ref": "#/components/schemas/IdempotencyKey" - } - } - }, - "CatalogOperationTarget": { - "type": "object", - "additionalProperties": false, - "required": [ - "target_kind", - "scope" - ], - "properties": { - "target_kind": { - "const": "catalog" - }, - "scope": { - "type": "string", - "enum": [ - "full", - "roots", - "entry" - ] - }, - "model_id": { - "anyOf": [ - { - "$ref": "#/components/schemas/ModelId" - }, - { - "type": "null" - } - ] - } - } - }, - "ModelOperationTarget": { - "type": "object", - "additionalProperties": false, - "required": [ - "target_kind", - "model_id", - "requested_revision" - ], - "properties": { - "target_kind": { - "const": "model" - }, - "model_id": { - "$ref": "#/components/schemas/ModelId" - }, - "requested_revision": { - "type": [ - "integer", - "null" - ], - "minimum": 1 - }, - "eviction_target_id": { - "anyOf": [ - { - "$ref": "#/components/schemas/ModelId" - }, - { - "type": "null" - } - ] - }, - "eviction_target_expected_revision": { - "type": [ - "integer", - "null" - ], - "minimum": 1 - } - } - }, - "DownloadOperationTarget": { - "type": "object", - "additionalProperties": false, - "required": [ - "target_kind", - "repo_id", - "revision" - ], - "properties": { - "target_kind": { - "const": "download" - }, - "repo_id": { - "$ref": "#/components/schemas/HuggingFaceRepoId" - }, - "revision": { - "$ref": "#/components/schemas/RevisionRef" - } - } - }, - "SettingsOperationTarget": { - "type": "object", - "additionalProperties": false, - "required": [ - "target_kind", - "model_id", - "scope" - ], - "properties": { - "target_kind": { - "const": "settings" - }, - "model_id": { - "$ref": "#/components/schemas/ModelId" - }, - "scope": { - "type": "string", - "enum": [ - "next_load_profile", - "loaded_model_live", - "request_only" - ] - } - } - }, - "OperationTarget": { - "oneOf": [ - { - "$ref": "#/components/schemas/CatalogOperationTarget" - }, - { - "$ref": "#/components/schemas/ModelOperationTarget" - }, - { - "$ref": "#/components/schemas/DownloadOperationTarget" - }, - { - "$ref": "#/components/schemas/SettingsOperationTarget" - } - ] - }, - "CatalogRefreshResult": { - "type": "object", - "additionalProperties": false, - "required": [ - "result_kind", - "scanned_entries", - "changed_entries", - "snapshot_sequence" - ], - "properties": { - "result_kind": { - "const": "catalog_refresh" - }, - "scanned_entries": { - "type": "integer", - "minimum": 0 - }, - "changed_entries": { - "type": "integer", - "minimum": 0 - }, - "snapshot_sequence": { - "$ref": "#/components/schemas/EventSequence" - } - } - }, - "ModelEvictionReport": { - "type": "object", - "additionalProperties": false, - "required": [ - "requested_target_id", - "displaced_model_id", - "outcome", - "rollbackable" - ], - "properties": { - "requested_target_id": { - "anyOf": [ - { - "$ref": "#/components/schemas/ModelId" - }, - { - "type": "null" - } - ] - }, - "displaced_model_id": { - "anyOf": [ - { - "$ref": "#/components/schemas/ModelId" - }, - { - "type": "null" - } - ] - }, - "outcome": { - "type": "string", - "enum": [ - "not_needed", - "displaced", - "failed_after_displacement" - ] - }, - "rollbackable": { - "type": "boolean" - } - } - }, - "ModelActionResult": { - "type": "object", - "additionalProperties": false, - "required": [ - "result_kind", - "model_id", - "revision", - "lifecycle" - ], - "properties": { - "result_kind": { - "type": "string", - "enum": [ - "model_load", - "model_unload", - "model_removal" - ] - }, - "model_id": { - "$ref": "#/components/schemas/ModelId" - }, - "revision": { - "type": "integer", - "minimum": 1 - }, - "lifecycle": { - "$ref": "#/components/schemas/LifecycleSnapshot" - }, - "eviction": { - "anyOf": [ - { - "$ref": "#/components/schemas/ModelEvictionReport" - }, - { - "type": "null" - } - ] - } - } - }, - "DownloadResult": { - "type": "object", - "additionalProperties": false, - "required": [ - "result_kind", - "repo_id", - "revision", - "download" - ], - "properties": { - "result_kind": { - "const": "download" - }, - "repo_id": { - "$ref": "#/components/schemas/HuggingFaceRepoId" - }, - "revision": { - "$ref": "#/components/schemas/RevisionRef" - }, - "model_id": { - "anyOf": [ - { - "$ref": "#/components/schemas/ModelId" - }, - { - "type": "null" - } - ] - }, - "download": { - "$ref": "#/components/schemas/DownloadState" - } - } - }, - "SettingsPatchResult": { - "type": "object", - "additionalProperties": false, - "required": [ - "result_kind", - "model_id", - "settings" - ], - "properties": { - "result_kind": { - "const": "settings_patch" - }, - "model_id": { - "$ref": "#/components/schemas/ModelId" - }, - "settings": { - "$ref": "#/components/schemas/RuntimeSettingsReport" - } - } - }, - "OperationResult": { - "oneOf": [ - { - "$ref": "#/components/schemas/CatalogRefreshResult" - }, - { - "$ref": "#/components/schemas/ModelActionResult" - }, - { - "$ref": "#/components/schemas/DownloadResult" - }, - { - "$ref": "#/components/schemas/SettingsPatchResult" - } - ] - }, - "OperationAccepted": { - "type": "object", - "additionalProperties": false, - "required": [ - "operation_id", - "state", - "idempotent_replay" - ], - "properties": { - "operation_id": { - "$ref": "#/components/schemas/OperationId" - }, - "state": { - "$ref": "#/components/schemas/OperationState" - }, - "idempotent_replay": { - "type": "boolean" - } - } - }, - "ProgressBytes": { - "type": "object", - "additionalProperties": false, - "required": [ - "completed_bytes", - "total_bytes", - "indeterminate" - ], - "properties": { - "completed_bytes": { - "type": "integer", - "minimum": 0 - }, - "total_bytes": { - "type": [ - "integer", - "null" - ], - "minimum": 0 - }, - "indeterminate": { - "type": "boolean" - } - } - }, - "Operation": { - "type": "object", - "additionalProperties": false, - "required": [ - "operation_id", - "kind", - "state", - "created_at", - "updated_at", - "idempotency_scope", - "target", - "progress", - "result", - "error", - "cancellable", - "cancel_reason" - ], - "properties": { - "operation_id": { - "$ref": "#/components/schemas/OperationId" - }, - "kind": { - "$ref": "#/components/schemas/OperationKind" - }, - "state": { - "$ref": "#/components/schemas/OperationState" - }, - "created_at": { - "type": "string", - "format": "date-time", - "description": "RFC3339 UTC timestamp with offset, e.g. 2026-09-12T03:04:05Z." - }, - "updated_at": { - "type": "string", - "format": "date-time", - "description": "RFC3339 UTC timestamp with offset, e.g. 2026-09-12T03:04:05Z." - }, - "idempotency_scope": { - "type": "string", - "const": "server_instance" - }, - "target": { - "$ref": "#/components/schemas/OperationTarget" - }, - "progress": { - "$ref": "#/components/schemas/ProgressBytes" - }, - "result": { - "anyOf": [ - { - "$ref": "#/components/schemas/OperationResult" - }, - { - "type": "null" - } - ] - }, - "error": { - "anyOf": [ - { - "$ref": "#/components/schemas/ErrorBody" - }, - { - "type": "null" - } - ] - }, - "cancellable": { - "type": "boolean" - }, - "cancel_reason": { - "type": [ - "string", - "null" - ], - "maxLength": 512 - } - } - }, - "OperationsListResponse": { - "type": "object", - "additionalProperties": false, - "required": [ - "items", - "pagination", - "server_instance_id", - "snapshot_sequence" - ], - "properties": { - "items": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Operation" - }, - "maxItems": 200 - }, - "pagination": { - "$ref": "#/components/schemas/Pagination" - }, - "server_instance_id": { - "$ref": "#/components/schemas/ServerInstanceId" - }, - "snapshot_sequence": { - "$ref": "#/components/schemas/EventSequence", - "description": "Single global event sequence after which this snapshot is authoritative." - } - } - }, - "RuntimeSettingsReport": { - "type": "object", - "additionalProperties": false, - "required": [ - "scope", - "effective", - "overridden_by_cli", - "partial_errors" - ], - "properties": { - "scope": { - "type": "string", - "enum": [ - "server_startup", - "per_model_preset", - "next_load_profile", - "request_only", - "loaded_model_live" - ] - }, - "effective": { - "type": "object", - "additionalProperties": { - "type": [ - "string", - "number", - "boolean", - "null" - ] - }, - "maxProperties": 64 - }, - "overridden_by_cli": { - "type": "array", - "items": { - "type": "string" - }, - "maxItems": 64 - }, - "partial_errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/FieldError" - }, - "maxItems": 16 - } - } - }, - "RuntimeSnapshot": { - "type": "object", - "additionalProperties": false, - "required": [ - "schema_version", - "server_instance_id", - "model_id", - "revision", - "snapshot_sequence", - "measurements", - "settings", - "slots" - ], - "properties": { - "schema_version": { - "$ref": "#/components/schemas/SchemaVersion" - }, - "server_instance_id": { - "$ref": "#/components/schemas/ServerInstanceId" - }, - "model_id": { - "$ref": "#/components/schemas/ModelId" - }, - "revision": { - "type": "integer", - "minimum": 1 - }, - "measurements": { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/MeasuredValue" - }, - "maxProperties": 64 - }, - "settings": { - "$ref": "#/components/schemas/RuntimeSettingsReport" - }, - "snapshot_sequence": { - "$ref": "#/components/schemas/EventSequence", - "description": "Single global event sequence after which this snapshot is authoritative." - }, - "slots": { - "$ref": "#/components/schemas/RuntimeSlots" - } - } - }, - "UiEvent": { - "oneOf": [ - { - "$ref": "#/components/schemas/SnapshotEvent" - }, - { - "$ref": "#/components/schemas/ModelRevisionEvent" - }, - { - "$ref": "#/components/schemas/OperationEvent" - }, - { - "$ref": "#/components/schemas/DownloadProgressEvent" - }, - { - "$ref": "#/components/schemas/RuntimeEvent" - }, - { - "$ref": "#/components/schemas/SettingsEvent" - }, - { - "$ref": "#/components/schemas/ResetEvent" - }, - { - "$ref": "#/components/schemas/GapEvent" - }, - { - "$ref": "#/components/schemas/ServerRestartEvent" - }, - { - "$ref": "#/components/schemas/HeartbeatEvent" - } - ] - }, - "StringContract": { - "type": "object", - "additionalProperties": false, - "required": [ - "key", - "en", - "ko", - "test_id" - ], - "properties": { - "key": { - "type": "string", - "pattern": "^[a-z0-9_.-]+(?![\\\\s\\\\S])", - "maxLength": 128 - }, - "en": { - "type": "string", - "minLength": 1, - "maxLength": 512 - }, - "ko": { - "type": "string", - "minLength": 1, - "maxLength": 512 - }, - "test_id": { - "type": "string", - "pattern": "^[a-z0-9-]+(?![\\\\s\\\\S])", - "maxLength": 128 - } - } - }, - "TransitionStep": { - "type": "object", - "additionalProperties": false, - "required": [ - "from", - "action", - "to", - "http_status", - "event", - "allowed" - ], - "properties": { - "from": { - "$ref": "#/components/schemas/ModelLifecycleState" - }, - "action": { - "type": "string", - "minLength": 1 - }, - "to": { - "$ref": "#/components/schemas/ModelLifecycleState" - }, - "http_status": { - "type": "integer", - "minimum": 100, - "maximum": 599 - }, - "event": { - "$ref": "#/components/schemas/UiEventType" - }, - "allowed": { - "type": "boolean" - }, - "error": { - "anyOf": [ - { - "$ref": "#/components/schemas/ErrorEnvelope" - }, - { - "type": "null" - } - ] - } - } - }, - "WebUiContractFixture": { - "type": "object", - "additionalProperties": false, - "required": [ - "scenario", - "description", - "given", - "steps", - "expected" - ], - "properties": { - "scenario": { - "type": "string", - "enum": [ - "duplicate_load", - "load_unload_race", - "busy_eviction", - "stale_revision", - "failed_load", - "download_cancel", - "deletion_refusal", - "sse_gap", - "server_restart", - "unknown_null_partial_error" - ] - }, - "description": { - "type": "string", - "minLength": 1 - }, - "given": { - "type": "object", - "additionalProperties": { - "type": [ - "string", - "number", - "boolean", - "null", - "array", - "object" - ] - } - }, - "steps": { - "type": "array", - "items": { - "$ref": "#/components/schemas/TransitionStep" - }, - "minItems": 1 - }, - "expected": { - "type": "object", - "additionalProperties": { - "type": [ - "string", - "number", - "boolean", - "null", - "array", - "object" - ] - } - } - } - }, - "SupportStatus": { - "type": "object", - "additionalProperties": false, - "required": [ - "architecturally_supported", - "runnable_on_backend", - "complete", - "reason", - "architecturally_supported_reason", - "runnable_on_backend_reason", - "complete_reason", - "tested_checkpoint", - "tested_checkpoint_reason" - ], - "properties": { - "architecturally_supported": { - "type": "boolean" - }, - "runnable_on_backend": { - "type": "boolean" - }, - "complete": { - "type": "boolean" - }, - "reason": { - "type": [ - "string", - "null" - ], - "maxLength": 512 - }, - "architecturally_supported_reason": { - "type": [ - "string", - "null" - ], - "maxLength": 512 - }, - "runnable_on_backend_reason": { - "type": [ - "string", - "null" - ], - "maxLength": 512 - }, - "complete_reason": { - "type": [ - "string", - "null" - ], - "maxLength": 512 - }, - "tested_checkpoint": { - "type": "boolean", - "description": "True only when the catalog has explicit compatibility evidence for this checkpoint; static registry support alone does not set this." - }, - "tested_checkpoint_reason": { - "type": [ - "string", - "null" - ], - "maxLength": 512 - } - } - }, - "CatalogMetadata": { - "type": "object", - "additionalProperties": false, - "required": [ - "architecture", - "declared_architectures", - "input_tasks", - "output_tasks", - "quantization", - "format", - "parameter_count", - "disk_bytes", - "memory_estimate_bytes", - "support", - "model_type", - "unknown_reasons" - ], - "properties": { - "architecture": { - "type": [ - "string", - "null" - ], - "maxLength": 128 - }, - "declared_architectures": { - "type": [ - "array", - "null" - ], - "items": { - "type": "string", - "maxLength": 128 - }, - "maxItems": 16, - "description": "Raw config.json architectures array when readable and bounded." - }, - "input_tasks": { - "type": "array", - "items": { - "$ref": "#/components/schemas/TaskKind" - }, - "maxItems": 16 - }, - "output_tasks": { - "type": "array", - "items": { - "$ref": "#/components/schemas/TaskKind" - }, - "maxItems": 16 - }, - "quantization": { - "type": [ - "string", - "null" - ], - "maxLength": 128 - }, - "format": { - "type": [ - "string", - "null" - ], - "maxLength": 128 - }, - "parameter_count": { - "type": [ - "integer", - "null" - ], - "minimum": 0 - }, - "disk_bytes": { - "type": [ - "integer", - "null" - ], - "minimum": 0 - }, - "memory_estimate_bytes": { - "type": [ - "integer", - "null" - ], - "minimum": 0 - }, - "support": { - "$ref": "#/components/schemas/SupportStatus" - }, - "model_type": { - "type": [ - "string", - "null" - ], - "maxLength": 128, - "description": "Raw config.json model_type when readable; architecture is the resolved mlxcel registry id." - }, - "unknown_reasons": { - "$ref": "#/components/schemas/CatalogMetadataUnknownReasons" - } - } - }, - "SnapshotPayload": { - "type": "object", - "additionalProperties": false, - "required": [ - "snapshot_sequence", - "catalog_changed", - "operations_changed", - "runtime_model_ids" - ], - "properties": { - "snapshot_sequence": { - "$ref": "#/components/schemas/EventSequence" - }, - "catalog_changed": { - "type": "boolean" - }, - "operations_changed": { - "type": "boolean" - }, - "runtime_model_ids": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ModelId" - }, - "maxItems": 200 - } - } - }, - "ModelRevisionPayload": { - "type": "object", - "additionalProperties": false, - "required": [ - "model_id", - "revision", - "lifecycle" - ], - "properties": { - "model_id": { - "$ref": "#/components/schemas/ModelId" - }, - "revision": { - "type": "integer", - "minimum": 1 - }, - "lifecycle": { - "$ref": "#/components/schemas/LifecycleSnapshot" - } - } - }, - "OperationPayload": { - "type": "object", - "additionalProperties": false, - "required": [ - "operation" - ], - "properties": { - "operation": { - "$ref": "#/components/schemas/Operation" - } - } - }, - "DownloadProgressPayload": { - "type": "object", - "additionalProperties": false, - "required": [ - "operation_id", - "progress" - ], - "properties": { - "operation_id": { - "$ref": "#/components/schemas/OperationId" - }, - "progress": { - "$ref": "#/components/schemas/ProgressBytes" - } - } - }, - "RuntimePayload": { - "type": "object", - "additionalProperties": false, - "required": [ - "runtime" - ], - "properties": { - "runtime": { - "$ref": "#/components/schemas/RuntimeSnapshot" - } - } - }, - "SettingsPayload": { - "type": "object", - "additionalProperties": false, - "required": [ - "model_id", - "settings" - ], - "properties": { - "model_id": { - "$ref": "#/components/schemas/ModelId" - }, - "settings": { - "$ref": "#/components/schemas/RuntimeSettingsReport" - } - } - }, - "ResetPayload": { - "type": "object", - "additionalProperties": false, - "required": [ - "reason", - "resnapshot" - ], - "properties": { - "reason": { - "enum": [ - "gap", - "server_restart", - "retention_expired", - "manual_reset" - ] - }, - "resnapshot": { - "type": "boolean" - } - } - }, - "HeartbeatPayload": { - "type": "object", - "additionalProperties": false, - "required": [ - "server_time" - ], - "properties": { - "server_time": { - "type": "string", - "format": "date-time" - } - } - }, - "RequirementMapEntry": { - "type": "object", - "additionalProperties": false, - "required": [ - "id", - "epic_requirement", - "child", - "contract_artifact", - "test_fixture" - ], - "properties": { - "id": { - "type": "string", - "maxLength": 256 - }, - "epic_requirement": { - "type": "string", - "maxLength": 256 - }, - "child": { - "type": "string", - "pattern": "^#[0-9]+(?![\\\\s\\\\S])" - }, - "contract_artifact": { - "type": "string", - "maxLength": 256 - }, - "test_fixture": { - "type": "string", - "maxLength": 256 - } - } - }, - "RequirementMap": { - "type": "object", - "additionalProperties": false, - "required": [ - "requirements" - ], - "properties": { - "requirements": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/components/schemas/RequirementMapEntry" - }, - "maxItems": 64 - } - } - }, - "StringCatalog": { - "type": "object", - "additionalProperties": false, - "required": [ - "strings" - ], - "properties": { - "strings": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/components/schemas/StringContract" - }, - "maxItems": 1024 - } - } - }, - "SnapshotEvent": { - "type": "object", - "additionalProperties": false, - "required": [ - "schema_version", - "server_instance_id", - "sequence", - "type", - "payload", - "event_id", - "emitted_at" - ], - "properties": { - "schema_version": { - "$ref": "#/components/schemas/SchemaVersion" - }, - "server_instance_id": { - "$ref": "#/components/schemas/ServerInstanceId" - }, - "sequence": { - "$ref": "#/components/schemas/EventSequence" - }, - "type": { - "const": "snapshot" - }, - "payload": { - "$ref": "#/components/schemas/SnapshotPayload" - }, - "event_id": { - "$ref": "#/components/schemas/EventId" - }, - "emitted_at": { - "type": "string", - "format": "date-time", - "description": "RFC3339 UTC time at which the event was appended to the server ring." - } - } - }, - "ModelRevisionEvent": { - "type": "object", - "additionalProperties": false, - "required": [ - "schema_version", - "server_instance_id", - "sequence", - "type", - "payload", - "event_id", - "emitted_at" - ], - "properties": { - "schema_version": { - "$ref": "#/components/schemas/SchemaVersion" - }, - "server_instance_id": { - "$ref": "#/components/schemas/ServerInstanceId" - }, - "sequence": { - "$ref": "#/components/schemas/EventSequence" - }, - "type": { - "const": "model_revision" - }, - "payload": { - "$ref": "#/components/schemas/ModelRevisionPayload" - }, - "event_id": { - "$ref": "#/components/schemas/EventId" - }, - "emitted_at": { - "type": "string", - "format": "date-time", - "description": "RFC3339 UTC time at which the event was appended to the server ring." - } - } - }, - "OperationEvent": { - "type": "object", - "additionalProperties": false, - "required": [ - "schema_version", - "server_instance_id", - "sequence", - "type", - "payload", - "event_id", - "emitted_at" - ], - "properties": { - "schema_version": { - "$ref": "#/components/schemas/SchemaVersion" - }, - "server_instance_id": { - "$ref": "#/components/schemas/ServerInstanceId" - }, - "sequence": { - "$ref": "#/components/schemas/EventSequence" - }, - "type": { - "const": "operation" - }, - "payload": { - "$ref": "#/components/schemas/OperationPayload" - }, - "event_id": { - "$ref": "#/components/schemas/EventId" - }, - "emitted_at": { - "type": "string", - "format": "date-time", - "description": "RFC3339 UTC time at which the event was appended to the server ring." - } - } - }, - "DownloadProgressEvent": { - "type": "object", - "additionalProperties": false, - "required": [ - "schema_version", - "server_instance_id", - "sequence", - "type", - "payload", - "event_id", - "emitted_at" - ], - "properties": { - "schema_version": { - "$ref": "#/components/schemas/SchemaVersion" - }, - "server_instance_id": { - "$ref": "#/components/schemas/ServerInstanceId" - }, - "sequence": { - "$ref": "#/components/schemas/EventSequence" - }, - "type": { - "const": "download_progress" - }, - "payload": { - "$ref": "#/components/schemas/DownloadProgressPayload" - }, - "event_id": { - "$ref": "#/components/schemas/EventId" - }, - "emitted_at": { - "type": "string", - "format": "date-time", - "description": "RFC3339 UTC time at which the event was appended to the server ring." - } - } - }, - "RuntimeEvent": { - "type": "object", - "additionalProperties": false, - "required": [ - "schema_version", - "server_instance_id", - "sequence", - "type", - "payload", - "event_id", - "emitted_at" - ], - "properties": { - "schema_version": { - "$ref": "#/components/schemas/SchemaVersion" - }, - "server_instance_id": { - "$ref": "#/components/schemas/ServerInstanceId" - }, - "sequence": { - "$ref": "#/components/schemas/EventSequence" - }, - "type": { - "const": "runtime" - }, - "payload": { - "$ref": "#/components/schemas/RuntimePayload" - }, - "event_id": { - "$ref": "#/components/schemas/EventId" - }, - "emitted_at": { - "type": "string", - "format": "date-time", - "description": "RFC3339 UTC time at which the event was appended to the server ring." - } - } - }, - "SettingsEvent": { - "type": "object", - "additionalProperties": false, - "required": [ - "schema_version", - "server_instance_id", - "sequence", - "type", - "payload", - "event_id", - "emitted_at" - ], - "properties": { - "schema_version": { - "$ref": "#/components/schemas/SchemaVersion" - }, - "server_instance_id": { - "$ref": "#/components/schemas/ServerInstanceId" - }, - "sequence": { - "$ref": "#/components/schemas/EventSequence" - }, - "type": { - "const": "settings" - }, - "payload": { - "$ref": "#/components/schemas/SettingsPayload" - }, - "event_id": { - "$ref": "#/components/schemas/EventId" - }, - "emitted_at": { - "type": "string", - "format": "date-time", - "description": "RFC3339 UTC time at which the event was appended to the server ring." - } - } - }, - "ResetEvent": { - "type": "object", - "additionalProperties": false, - "required": [ - "schema_version", - "server_instance_id", - "sequence", - "type", - "payload", - "event_id", - "emitted_at" - ], - "properties": { - "schema_version": { - "$ref": "#/components/schemas/SchemaVersion" - }, - "server_instance_id": { - "$ref": "#/components/schemas/ServerInstanceId" - }, - "sequence": { - "$ref": "#/components/schemas/EventSequence" - }, - "type": { - "const": "reset" - }, - "payload": { - "$ref": "#/components/schemas/ResetPayload" - }, - "event_id": { - "$ref": "#/components/schemas/EventId" - }, - "emitted_at": { - "type": "string", - "format": "date-time", - "description": "RFC3339 UTC time at which the event was appended to the server ring." - } - } - }, - "GapEvent": { - "type": "object", - "additionalProperties": false, - "required": [ - "schema_version", - "server_instance_id", - "sequence", - "type", - "payload", - "event_id", - "emitted_at" - ], - "properties": { - "schema_version": { - "$ref": "#/components/schemas/SchemaVersion" - }, - "server_instance_id": { - "$ref": "#/components/schemas/ServerInstanceId" - }, - "sequence": { - "$ref": "#/components/schemas/EventSequence" - }, - "type": { - "const": "gap" - }, - "payload": { - "$ref": "#/components/schemas/ResetPayload" - }, - "event_id": { - "$ref": "#/components/schemas/EventId" - }, - "emitted_at": { - "type": "string", - "format": "date-time", - "description": "RFC3339 UTC time at which the event was appended to the server ring." - } - } - }, - "ServerRestartEvent": { - "type": "object", - "additionalProperties": false, - "required": [ - "schema_version", - "server_instance_id", - "sequence", - "type", - "payload", - "event_id", - "emitted_at" - ], - "properties": { - "schema_version": { - "$ref": "#/components/schemas/SchemaVersion" - }, - "server_instance_id": { - "$ref": "#/components/schemas/ServerInstanceId" - }, - "sequence": { - "$ref": "#/components/schemas/EventSequence" - }, - "type": { - "const": "server_restart" - }, - "payload": { - "$ref": "#/components/schemas/ResetPayload" - }, - "event_id": { - "$ref": "#/components/schemas/EventId" - }, - "emitted_at": { - "type": "string", - "format": "date-time", - "description": "RFC3339 UTC time at which the event was appended to the server ring." - } - } - }, - "HeartbeatEvent": { - "type": "object", - "additionalProperties": false, - "required": [ - "schema_version", - "server_instance_id", - "sequence", - "type", - "payload", - "event_id", - "emitted_at" - ], - "properties": { - "schema_version": { - "$ref": "#/components/schemas/SchemaVersion" - }, - "server_instance_id": { - "$ref": "#/components/schemas/ServerInstanceId" - }, - "sequence": { - "$ref": "#/components/schemas/EventSequence" - }, - "type": { - "const": "heartbeat" - }, - "payload": { - "$ref": "#/components/schemas/HeartbeatPayload" - }, - "event_id": { - "$ref": "#/components/schemas/EventId" - }, - "emitted_at": { - "type": "string", - "format": "date-time", - "description": "RFC3339 UTC time at which the event was appended to the server ring." - } - } - }, - "CanonicalIdentityInput": { - "type": "object", - "additionalProperties": false, - "required": [ - "version", - "source", - "source_rank", - "namespace_hash", - "entry_key" - ], - "properties": { - "version": { - "type": "integer", - "const": 1 - }, - "source": { - "$ref": "#/components/schemas/CatalogSourceKind" - }, - "source_rank": { - "type": "integer", - "minimum": 0, - "maximum": 3 - }, - "namespace_hash": { - "type": "string", - "pattern": "^[a-f0-9]{64}(?![\\\\s\\\\S])" - }, - "entry_key": { - "type": "string", - "minLength": 1, - "maxLength": 256 - } - } - }, - "IdentityVector": { - "type": "object", - "additionalProperties": false, - "required": [ - "source", - "source_rank", - "redacted_source_key", - "entry_key", - "source_key_hash", - "canonical_identity", - "expected_id" - ], - "properties": { - "source": { - "$ref": "#/components/schemas/CatalogSourceKind" - }, - "source_rank": { - "type": "integer", - "minimum": 0, - "maximum": 3 - }, - "redacted_source_key": { - "type": "string", - "minLength": 1 - }, - "entry_key": { - "type": "string", - "minLength": 1 - }, - "source_key_hash": { - "type": "string", - "pattern": "^[a-f0-9]{64}(?![\\\\s\\\\S])" - }, - "canonical_identity": { - "$ref": "#/components/schemas/CanonicalIdentityInput" - }, - "expected_id": { - "type": "string", - "pattern": "^mdl_[A-Za-z0-9_-]{43}(?![\\\\s\\\\S])" - } - } - }, - "IdentityVectors": { - "type": "object", - "additionalProperties": false, - "required": [ - "identity_vectors" - ], - "properties": { - "identity_vectors": { - "type": "array", - "minItems": 2, - "items": { - "$ref": "#/components/schemas/IdentityVector" - } - } - } - }, - "RemovalStatus": { - "type": "object", - "additionalProperties": false, - "required": [ - "eligible", - "reason", - "instructions" - ], - "properties": { - "eligible": { - "type": "boolean" - }, - "reason": { - "type": [ - "string", - "null" - ], - "maxLength": 512 - }, - "instructions": { - "type": [ - "string", - "null" - ], - "maxLength": 512 - } - } - }, - "CatalogMetadataUnknownReasons": { - "type": "object", - "additionalProperties": false, - "required": [], - "description": "Reasons for metadata fields that are null or deliberately unmeasured.", - "properties": { - "architecture": { - "type": [ - "string", - "null" - ], - "maxLength": 512 - }, - "declared_architectures": { - "type": [ - "string", - "null" - ], - "maxLength": 512 - }, - "model_type": { - "type": [ - "string", - "null" - ], - "maxLength": 512 - }, - "quantization": { - "type": [ - "string", - "null" - ], - "maxLength": 512 - }, - "format": { - "type": [ - "string", - "null" - ], - "maxLength": 512 - }, - "parameter_count": { - "type": [ - "string", - "null" - ], - "maxLength": 512 - }, - "disk_bytes": { - "type": [ - "string", - "null" - ], - "maxLength": 512 - }, - "memory_estimate_bytes": { - "type": [ - "string", - "null" - ], - "maxLength": 512 - } - } - }, - "RuntimeSlot": { - "type": "object", - "additionalProperties": false, - "required": [ - "id", - "processing", - "prompt_tokens", - "cached_prompt_tokens", - "decoded_tokens" - ], - "properties": { - "id": { - "type": "integer", - "minimum": 0 - }, - "processing": { - "type": "boolean" - }, - "prompt_tokens": { - "type": [ - "integer", - "null" - ], - "minimum": 0, - "description": "Current context occupancy from GET /slots n_prompt_tokens: includes processed prompt and accepted decoded tokens. Never add decoded_tokens again." - }, - "cached_prompt_tokens": { - "type": [ - "integer", - "null" - ], - "minimum": 0 - }, - "decoded_tokens": { - "type": [ - "integer", - "null" - ], - "minimum": 0 - } - } - }, - "RuntimeSlots": { - "type": "object", - "additionalProperties": false, - "required": [ - "available", - "reason", - "measured_at", - "configured_parallelism", - "effective_parallelism", - "request_context_tokens", - "shared_pool_context_tokens", - "items" - ], - "properties": { - "available": { - "type": "boolean" - }, - "reason": { - "type": [ - "string", - "null" - ], - "maxLength": 256 - }, - "measured_at": { - "anyOf": [ - { - "type": "string", - "format": "date-time" - }, - { - "type": "null" - } - ] - }, - "configured_parallelism": { - "type": "integer", - "minimum": 0 - }, - "effective_parallelism": { - "type": [ - "integer", - "null" - ], - "minimum": 0 - }, - "request_context_tokens": { - "type": [ - "integer", - "null" - ], - "minimum": 0 - }, - "shared_pool_context_tokens": { - "type": [ - "integer", - "null" - ], - "minimum": 0 - }, - "items": { - "type": "array", - "maxItems": 256, - "items": { - "$ref": "#/components/schemas/RuntimeSlot" - } - } - } - }, - "MediaLimits": { - "type": "object", - "additionalProperties": false, - "required": [ - "max_images", - "max_image_bytes", - "max_width", - "max_height", - "max_decoded_bytes", - "max_body_bytes" - ], - "properties": { - "max_images": { - "type": "integer", - "minimum": 0, - "maximum": 9007199254740991 - }, - "max_image_bytes": { - "type": "integer", - "minimum": 0, - "maximum": 9007199254740991 - }, - "max_width": { - "type": "integer", - "minimum": 0, - "maximum": 9007199254740991 - }, - "max_height": { - "type": "integer", - "minimum": 0, - "maximum": 9007199254740991 - }, - "max_decoded_bytes": { - "type": "integer", - "minimum": 0, - "maximum": 9007199254740991 - }, - "max_body_bytes": { - "type": "integer", - "minimum": 0, - "maximum": 9007199254740991 - } - }, - "description": "Resolved server image admission and WebUI JSON body limits; clients may impose additional lower local safety ceilings. JSON budget includes base64 encoding, transcript and request envelope." - } - } - } -} -`,V=class extends Error{path;constructor(e,t){super(`${e}: ${t}`),this.path=e,this.name=`ValidationError`}},Nt=It(Mt);function Pt(e,t,n=`$`){let r=qt(Nt,[`components`,`schemas`],`#/components/schemas`)[e];if(r===void 0)throw new V(n,`unknown schema ${e}`);Lt(r,t,n)}function Ft(e){return JSON.parse(e)}function It(e){return Kt(Ft(e),`$contract`)}function Lt(e,t,n){let r=Kt(e,`${n}#schema`);if(typeof r.$ref==`string`){Lt(Wt(r.$ref),t,n);return}if(r.anyOf!==void 0){if(!Array.isArray(r.anyOf)||!r.anyOf.some(e=>Gt(e,t,n)))throw new V(n,`did not match any allowed schema`);return}if(r.oneOf!==void 0){if(!Array.isArray(r.oneOf))throw new V(n,`schema oneOf must be an array`);let e=r.oneOf.filter(e=>Gt(e,t,n)).length;if(e!==1)throw new V(n,`matched ${e} oneOf schemas`);return}if(r.const!==void 0&&t!==r.const)throw new V(n,`expected constant ${String(r.const)}`);if(Array.isArray(r.enum)&&!r.enum.some(e=>e===t))throw new V(n,`unexpected enum value ${String(t)}`);let i=r.type;if(Array.isArray(i)){if(!i.some(e=>Ut(e,t)))throw new V(n,`expected one of ${i.join(`, `)}`)}else if(typeof i==`string`&&!Ut(i,t))throw new V(n,`expected ${i}`);typeof t==`string`&&Vt(r,t,n),typeof t==`number`&&H(r,t,n),Array.isArray(t)&&zt(r,t,n),Jt(t)&&Rt(r,t,n)}function Rt(e,t,n){let r=Yt(e.required,`${n}#schema.required`,!1),i=e.properties===void 0?{}:Kt(e.properties,`${n}#schema.properties`);for(let e of r)if(!(e in t))throw new V(`${n}.${e}`,`missing required property`);if(e.maxProperties!==void 0&&Object.keys(t).length>Xt(e.maxProperties,`${n}#schema.maxProperties`))throw new V(n,`too many object properties`);for(let[r,a]of Object.entries(t)){let t=i[r];if(t!==void 0)Lt(t,a,`${n}.${r}`);else if(e.additionalProperties===!1)throw new V(`${n}.${r}`,`unexpected property`);else Jt(e.additionalProperties)&&Lt(e.additionalProperties,a,`${n}.${r}`)}}function zt(e,t,n){if(e.minItems!==void 0&&t.lengthXt(e.maxItems,`${n}#schema.maxItems`))throw new V(n,`array longer than maximum`);e.items!==void 0&&t.forEach((t,r)=>Lt(e.items,t,`${n}[${r}]`))}function Bt(e){let t=0;for(let n=0;n65535?2:1;return t}function Vt(e,t,n){let r=Bt(t);if(e.minLength!==void 0&&rXt(e.maxLength,`${n}#schema.maxLength`))throw new V(n,`string longer than maximum`);if(typeof e.pattern==`string`&&!new RegExp(e.pattern,`u`).test(t))throw new V(n,`string does not match pattern`);if(e.format===`date-time`&&!Ht(t))throw new V(n,`invalid RFC3339 date-time`)}function Ht(e){return/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/.test(e)?!Number.isNaN(Date.parse(e)):!1}function H(e,t,n){if(!Number.isFinite(t))throw new V(n,`expected finite number`);if(e.type===`integer`&&!Number.isInteger(t))throw new V(n,`expected integer`);if(e.minimum!==void 0&&tXt(e.maximum,`${n}#schema.maximum`))throw new V(n,`number above maximum`)}function Ut(e,t){return e===`null`?t===null:e===`array`?Array.isArray(t):e===`object`?Jt(t):e===`integer`?typeof t==`number`&&Number.isInteger(t):e===`number`?typeof t==`number`&&Number.isFinite(t):typeof t===e}function Wt(e){if(!e.startsWith(`#/`))throw new V(`$ref`,`unsupported external ref ${e}`);return e.slice(2).split(`/`).map(e=>e.replace(/~1/g,`/`).replace(/~0/g,`~`)).reduce((t,n)=>Kt(t,e)[n],Nt)}function Gt(e,t,n){try{return Lt(e,t,n),!0}catch(e){if(e instanceof V)return!1;throw e}}function Kt(e,t){if(!Jt(e))throw new V(t,`expected object`);return e}function qt(e,t,n){return t.reduce((e,t)=>Kt(e,n)[t],e)}function Jt(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Yt(e,t,n){if(e===void 0&&!n)return[];if(!Array.isArray(e)||!e.every(e=>typeof e==`string`))throw new V(t,`expected string array`);return e}function Xt(e,t){if(typeof e!=`number`||!Number.isFinite(e))throw new V(t,`expected numeric schema bound`);return e}function Zt(e,t,n){return Pt(e,t,n),t}function Qt(e,t=`$`){return Zt(`ErrorEnvelope`,e,t)}function $t(e,t=`$`){return Zt(`BootstrapResponse`,e,t)}function en(e,t=`$`){return Zt(`CatalogEntry`,e,t)}function tn(e,t=`$`){return Zt(`CatalogListResponse`,e,t)}function nn(e,t=`$`){return Zt(`OperationsListResponse`,e,t)}function rn(e,t=`$`){return Zt(`Operation`,e,t)}function an(e,t=`$`){return Zt(`OperationAccepted`,e,t)}function on(e,t=`$`){return Zt(`RuntimeSnapshot`,e,t)}function sn(e,t=`$`){return Zt(`UiEvent`,e,t)}var cn=class extends Error{status;envelope;constructor(e,t,n){super(n??t?.error.message??`WebUI request failed with HTTP ${e}`),this.status=e,this.envelope=t,this.name=`WebUiHttpError`}},ln=2097152,un=class{apiBase;fetchImpl;bearerToken=null;onUnauthorized;controllers=new Set;constructor(e={}){this.apiBase=Dt(e.apiBase),this.fetchImpl=e.fetchImpl??fetch.bind(globalThis),this.onUnauthorized=e.onUnauthorized}setBearerToken(e){this.bearerToken=e}abortAll(){for(let e of this.controllers)e.abort();this.controllers.clear()}async bootstrap(e){return this.request(`/ui-api/v1/bootstrap`,$t,{method:`GET`,signal:e})}async catalog(e={},t){return this.request(`/ui-api/v1/catalog`,tn,{method:`GET`,query:{...e},signal:t})}async catalogEntry(e,t){return this.request(`/ui-api/v1/catalog/${jt(e)}`,en,{method:`GET`,signal:t})}async refreshCatalog(e,t){return this.request(`/ui-api/v1/catalog/refresh`,an,{method:`POST`,body:{idempotency_key:e},signal:t})}async modelAction(e,t){return this.request(`/ui-api/v1/model-actions`,an,{method:`POST`,body:e,signal:t})}async download(e,t){return this.request(`/ui-api/v1/downloads`,an,{method:`POST`,body:e,signal:t})}async removeModel(e,t){return this.request(`/ui-api/v1/model-removals`,an,{method:`POST`,body:e,signal:t})}async operationsPage(e={},t){return this.request(`/ui-api/v1/operations`,nn,{method:`GET`,query:e,signal:t})}async operations(e){let t=[],n,r=null;for(;;){let i=await this.operationsPage(n===void 0?{}:{cursor:n},e);if(r===null)r=i.server_instance_id;else if(i.server_instance_id!==r)throw Error(`Operations pagination crossed a server restart; refresh the authoritative snapshot.`);if(t.push(...i.items),i.pagination.next_cursor===null)return t;n=i.pagination.next_cursor}}async operation(e,t){return this.request(`/ui-api/v1/operations/${jt(e)}`,rn,{method:`GET`,signal:t})}async cancelOperation(e,t){return this.request(`/ui-api/v1/operations/${jt(e)}/cancel`,an,{method:`POST`,body:{},signal:t})}async runtime(e,t){let n=await this.request(`/ui-api/v1/runtime`,on,{method:`GET`,query:{model_id:e,autoload:!1},signal:t});if(n.model_id!==e)throw Error(`Runtime response model_id did not match the requested model.`);return n}async tokenCount(e,t,n){return this.request(`/tokenize`,St,{method:`POST`,query:{model:e,autoload:!1},body:{content:t,add_special:!1,parse_special:!0,with_pieces:!1},signal:n})}async settings(e,t){return this.request(`/settings`,_t,{method:`GET`,query:{model:e,autoload:!1},signal:t})}async patchSettings(e,t,n){return this.request(`/settings`,vt,{method:`PATCH`,query:{model:e,autoload:!1},body:{op:`merge`,values:t},signal:n})}async modelProps(e,t){return this.request(`/props`,yt,{method:`GET`,query:{model:e,autoload:!1},signal:t})}async events(e,t,n){let r=n?.serverInstanceId!==void 0&&n.serverInstanceId!==null&&n.afterSequence!==null&&n.afterSequence!==void 0,i=r?{server_instance_id:n.serverInstanceId,after_sequence:n.afterSequence}:void 0,a=new Headers({Accept:`text/event-stream`});!r&&n?.lastEventId!==void 0&&n.lastEventId!==null&&a.set(`Last-Event-ID`,n.lastEventId),await this.sse(At(this.apiBase,`/ui-api/v1/events`,i),{method:`GET`,signal:t,headers:a},{onDone:e.onDone,onFrame:t=>{t.retry!==null&&e.onRetryAfter?.(t.retry),t.data.length>0&&e.onEvent(sn(Ft(t.data)))}})}async chatCompletions(e,t,n,r){await this.sse(At(this.apiBase,`/v1/chat/completions`,{autoload:!1}),{method:`POST`,body:pn(t,e),signal:r,headers:{Accept:`text/event-stream`}},n)}async responses(e,t,n,r){await this.sse(At(this.apiBase,`/v1/responses`,{autoload:!1}),{method:`POST`,body:pn(t,e),signal:r,headers:{Accept:`text/event-stream`}},n)}async request(e,t,n){let r=await this.fetchWithAuth(At(this.apiBase,e,n.query),n);try{return r.response.ok||await this.throwHttp(r.response,r.signal),t(Ft(await this.readBody(r.response,r.signal)))}finally{this.controllers.delete(r.controller),r.cleanup()}}async sse(e,t,n){let r=await this.fetchWithAuth(e,t);try{let e=r.response;if(e.ok||await this.throwHttp(e,r.signal),e.body===null)throw Error(`WebUI event stream response has no body.`);let t=new wt({onDone:n.onDone,onMessage:n.onFrame}),i=e.body.getReader();try{for(;;){let e=await mn(i,r.signal);if(e.done)break;t.push(e.value)}if(t.close(),!t.done&&r.signal.aborted!==!0)throw Error(`WebUI event stream ended before a DONE frame.`)}catch(e){throw await i.cancel().catch(()=>void 0),e}finally{i.releaseLock()}}finally{this.controllers.delete(r.controller),r.cleanup()}}async fetchWithAuth(e,t){let n=new AbortController,{signal:r,cleanup:i}=hn(n,t.signal);this.controllers.add(n);let a=new Headers(t.headers);a.set(`Accept`,a.get(`Accept`)??`application/json`),this.bearerToken!==null&&a.set(`Authorization`,`Bearer ${this.bearerToken}`),t.body!==void 0&&a.set(`Content-Type`,`application/json`);try{return{response:await this.fetchImpl(e,{method:t.method,headers:a,body:t.body===void 0?void 0:JSON.stringify(t.body),signal:r,credentials:`same-origin`,cache:`no-store`,redirect:`error`}),controller:n,signal:r,cleanup:i}}catch(e){throw this.controllers.delete(n),i(),e}}async throwHttp(e,t){let n=this.bearerToken;e.status===401&&(this.bearerToken=null,this.abortAll(),this.onUnauthorized?.());let r=null;try{let n=await this.readBody(e,t);n.length>0&&(r=Qt(Ft(n)))}catch{r=null}throw new cn(e.status,dn(r,n),fn(r?.error.message??`WebUI request failed with HTTP ${e.status}`,n))}async readBody(e,t){if(e.body===null)return``;let n=e.body.getReader(),r=[],i=0;try{for(;;){let e=await mn(n,t);if(e.done)break;if(i+=e.value.byteLength,i>ln)throw Error(`WebUI JSON response exceeded the configured byte limit.`);r.push(e.value)}}catch(e){throw await n.cancel().catch(()=>void 0),e}finally{n.releaseLock()}let a=new Uint8Array(i),o=0;for(let e of r)a.set(e,o),o+=e.byteLength;return new TextDecoder().decode(a)}};function dn(e,t){return e===null?null:{...e,error:{...e.error,message:fn(e.error.message,t),field_errors:e.error.field_errors?.map(e=>({...e,message:fn(e.message,t)}))}}}function fn(e,t){let n=e.replace(/Bearer\s+\S+/gi,`Bearer [redacted]`).replace(/token[=:]\s*\S+/gi,`token=[redacted]`);return t!==null&&t.length>0&&(n=n.split(t).join(`[redacted]`)),n}function pn(e,t){if(t.length===0)throw Error(`Inference model id is required for streaming inference.`);if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Streaming inference bodies must be JSON objects.`);return{...e,model:t,stream:!0}}async function mn(e,t){if(t.aborted)throw await e.cancel().catch(()=>void 0),gn();let n=null;try{let r=await Promise.race([e.read(),new Promise((r,i)=>{n=()=>{e.cancel().catch(()=>void 0),i(gn())},t.addEventListener(`abort`,n,{once:!0})})]);if(t.aborted)throw gn();return r}finally{n!==null&&t.removeEventListener(`abort`,n)}}function hn(e,t){if(t===void 0)return{signal:e.signal,cleanup:()=>void 0};let n=()=>e.abort(t.reason);return t.aborted?n():t.addEventListener(`abort`,n,{once:!0}),{signal:e.signal,cleanup:()=>t.removeEventListener(`abort`,n)}}function gn(){return typeof DOMException==`function`?new DOMException(`The WebUI request was aborted.`,`AbortError`):Error(`The WebUI request was aborted.`)}function _n(e,t,n){let r=e.filter(e=>e.runtime.server_instance_id===t.server_instance_id&&e.runtime.model_id===t.model_id&&e.receivedAt>n-3e5&&e.receivedAt<=n),i=r.at(-1);return i!==void 0&&Math.floor(i.receivedAt/2e3)===Math.floor(n/2e3)&&r.pop(),[...r,{receivedAt:n,runtime:t}].slice(-150)}function vn(e,t){let n=[...e.values()].sort((e,t)=>t.updated_at.localeCompare(e.updated_at)),r=n.filter(e=>!yn(e)),i=n.filter(e=>yn(e)&&Date.parse(e.updated_at)>t-36e5).slice(0,200);return new Map([...r,...i].map(e=>[e.operation_id,e]))}function yn(e){return[`succeeded`,`failed`,`cancelled`].includes(e.state)}var bn=`webui.ui-api.v1`;function xn(){return{schemaVersion:bn,auth:{status:`signed-out`,tokenPresent:!1},connection:`idle`,bootstrap:null,catalog:[],catalogSequence:null,operations:new Map,runtimes:new Map,runtimeHistory:[],selectedModelId:null,serverInstanceId:null,lastEventId:null,lastSequence:null,lastUpdatedAt:null,lastSuccessfulAt:null,error:null,pendingReconciliations:new Map,resourceFences:{catalog:null,operationsSnapshot:null,operations:new Map,models:new Map,runtimes:new Map}}}function Sn(e,t){return t.type===`login-start`?{...e,auth:{status:`authenticating`,tokenPresent:!0},connection:`bootstrapping`,error:null}:t.type===`login-success`?Cn(e,t.bootstrap,t.now):t.type===`logout`?{...xn(),lastUpdatedAt:t.now}:t.type===`select-model`?{...e,selectedModelId:t.modelId,runtimeHistory:[]}:t.type===`catalog`?wn(e,t.response,t.now):t.type===`operations-snapshot`?Tn(e,t.response,t.now):t.type===`operation`?En(e,t.operation,t.sequence,t.now):t.type===`runtime`?Dn(e,t.runtime,t.sequence,t.now):t.type===`event`?On(e,t.event,t.now):t.type===`pending`?{...e,pendingReconciliations:In(e.pendingReconciliations,t.item.idempotencyKey,t.item)}:t.type===`reconciled`?{...e,pendingReconciliations:Ln(e.pendingReconciliations,t.idempotencyKey)}:{...e,connection:t.connection,error:t.error??null,lastUpdatedAt:t.now}}function Cn(e,t,n){let r=t.server.server_instance_id;return e.serverInstanceId!==null&&e.serverInstanceId!==r?{...xn(),auth:{status:`authenticated`,tokenPresent:!0},connection:`ready`,bootstrap:t,serverInstanceId:r,lastUpdatedAt:n}:{...e,auth:{status:`authenticated`,tokenPresent:!0},connection:`ready`,bootstrap:t,serverInstanceId:r,lastUpdatedAt:n,error:null}}function wn(e,t,n){if(e.serverInstanceId!==null&&t.server_instance_id!==e.serverInstanceId)return Mn(e,t.server_instance_id,n);if(e.catalogSequence!==null&&t.snapshot_sequenceo.has(e)))};return Nn({...e,operations:o,serverInstanceId:t.server_instance_id,lastSequence:Fn(s),error:null,resourceFences:s},n)}function En(e,t,n,r){if(n!==null&&e.resourceFences.operationsSnapshot!==null&&n<=e.resourceFences.operationsSnapshot)return e;let i=e.resourceFences.operations.get(t.operation_id);if(n!==null&&i!==void 0&&n<=i)return e;let a=vn(In(e.operations,t.operation_id,t),r),o=n===null?e.resourceFences.operations:In(e.resourceFences.operations,t.operation_id,n),s={...e.resourceFences,operations:new Map([...o].filter(([e])=>a.has(e)))};return Nn({...e,operations:a,lastSequence:Fn(s),error:null,resourceFences:s},r)}function Dn(e,t,n,r){if(e.serverInstanceId!==null&&t.server_instance_id!==e.serverInstanceId)return Mn(e,t.server_instance_id,r);let i=e.resourceFences.runtimes.get(t.model_id);if(n!==null&&i!==void 0&&ne.identity.id===r&&t.payload.revision>=e.identity.revision?{...e,identity:{...e.identity,revision:t.payload.revision},lifecycle:t.payload.lifecycle}:e),o={...e.resourceFences,models:In(e.resourceFences.models,r,t.sequence)};return Nn({...e,catalog:a,serverInstanceId:t.server_instance_id,lastEventId:t.event_id,lastSequence:Fn(o),connection:`streaming`,resourceFences:o},n)}function An(e,t,n){let r=t.payload.runtime,i=e.resourceFences.runtimes.get(r.model_id);if(i!==void 0&&t.sequence<=i)return e;let a={...e.resourceFences,runtimes:In(e.resourceFences.runtimes,r.model_id,t.sequence)};return Nn({...e,runtimes:In(e.runtimes,r.model_id,r),runtimeHistory:r.model_id===e.selectedModelId?_n(e.runtimeHistory,r,n):e.runtimeHistory,serverInstanceId:t.server_instance_id,lastEventId:t.event_id,lastSequence:Fn(a),connection:`streaming`,resourceFences:a},n)}function jn(e,t,n){let r=t.type===`server_restart`?null:e.lastSuccessfulAt;return{...xn(),auth:e.auth,connection:`stale`,serverInstanceId:t.server_instance_id,selectedModelId:e.selectedModelId,lastEventId:t.event_id,error:{code:t.type,message:t.payload.reason,retryable:t.payload.resnapshot},pendingReconciliations:e.pendingReconciliations,lastUpdatedAt:n,lastSuccessfulAt:r}}function Mn(e,t,n){return{...xn(),auth:e.auth,connection:`stale`,serverInstanceId:t,selectedModelId:e.selectedModelId,error:{code:`server_restarted`,message:`The mlxcel server restarted; refresh the authoritative snapshot before continuing.`,retryable:!0},pendingReconciliations:e.pendingReconciliations,lastUpdatedAt:n}}function Nn(e,t){return{...e,lastUpdatedAt:t,lastSuccessfulAt:t}}function Pn(e,t){if(e.length>0){let n=new Map(e.map(e=>[e.identity.id,e]));for(let e of t.items)n.set(e.identity.id,e);return Array.from(n.values()).sort((e,t)=>e.identity.display_name.localeCompare(t.identity.display_name))}return t.items}function Fn(e){let t=[e.catalog,e.operationsSnapshot,...e.operations.values(),...e.models.values(),...e.runtimes.values()].filter(e=>e!==null);return t.length===0?null:Math.min(...t)}function In(e,t,n){let r=new Map(e);return r.set(t,n),r}function Ln(e,t){let n=new Map(e);return n.delete(t),n}var Rn=2e3,zn=1e4,Bn=3e4,Vn=6e4,Hn=6e4,Un=new Set([`snapshot`,`model_revision`]),Wn=class{client;dispatch;getSnapshot;clock;visibility;random;timer=null;observationTimer=null;inflight=null;eventAbort=null;stopped=!0;failures=0;generation=0;needsFullSnapshot=!0;lastFullSnapshotAt=null;unsubscribe;constructor(e){this.client=e.client,this.dispatch=e.dispatch,this.getSnapshot=e.getSnapshot,this.clock=e.clock??Xn,this.visibility=e.visibility??Zn,this.random=e.random??Math.random,this.unsubscribe=this.visibility.subscribe(()=>this.visibilityChanged())}start(){this.stopped&&(this.stopped=!1,this.generation+=1,this.needsFullSnapshot=!0,this.reschedule(0))}stop(){this.generation+=1,this.stopped=!0,this.timer!==null&&this.clock.clearTimeout(this.timer),this.timer=null,this.observationTimer!==null&&this.clock.clearTimeout(this.observationTimer),this.observationTimer=null,this.inflight?.abort(),this.inflight=null,this.eventAbort?.abort(),this.eventAbort=null}selectionChanged(){this.cancelObservation(),this.reschedule(0)}fullSnapshotDue(e){let t=this.getSnapshot();return t.bootstrap===null||t.catalogSequence===null||this.needsFullSnapshot||this.lastFullSnapshotAt===null||this.eventAbort===null?!0:e-this.lastFullSnapshotAt>=Hn}cancelObservation(){this.generation+=1,this.observationTimer!==null&&this.clock.clearTimeout(this.observationTimer),this.observationTimer=null,this.inflight?.abort(),this.inflight=null,this.eventAbort?.abort(),this.eventAbort=null,this.timer!==null&&this.clock.clearTimeout(this.timer),this.timer=null}visibilityChanged(){this.cancelObservation(),this.needsFullSnapshot=!0,!this.stopped&&(this.dispatch({type:`connection`,connection:`stale`,now:this.clock.now()}),this.reschedule(0))}dispose(){this.stop(),this.unsubscribe()}async resnapshot(){this.needsFullSnapshot=!0,await this.refresh()}async refresh(){if(this.inflight!==null)return;let e=new AbortController;this.inflight=e;let t=this.generation,n=this.clock.now(),r=this.clock.setTimeout(()=>{e.abort(),this.generation===t&&this.dispatch({type:`connection`,connection:`stale`,error:{code:`observation_timeout`,message:`Runtime observation timed out; retrying.`,retryable:!0},now:this.clock.now()})},zn);this.observationTimer=r;try{if(this.getSnapshot().auth.status===`signed-out`)return;let r=this.fullSnapshotDue(n),i=null,a=[];if(r){if(i=await this.client.bootstrap(e.signal),!this.isCurrent(e,t)||this.getSnapshot().auth.status===`signed-out`||(this.dispatch({type:`login-success`,bootstrap:i,now:n}),a=await this.catalogSnapshot(e.signal),!this.isCurrent(e,t)))return;for(let e of a)this.dispatch({type:`catalog`,response:e,now:n})}let o=await this.operationSnapshot(e.signal);if(!this.isCurrent(e,t))return;let s=a.at(-1),c=o[0];if(s!==void 0&&c!==void 0&&c.server_instance_id!==s.server_instance_id){this.dispatch({type:`connection`,connection:`stale`,error:{code:`snapshot_mismatch`,message:`Operation and catalog snapshots came from different server instances.`,retryable:!0},now:n});return}let l=o.flatMap(e=>(this.dispatch({type:`operations-snapshot`,response:e,now:n}),e.items)),u=this.getSnapshot().selectedModelId,d=r&&i!==null&&u!==null&&a.every(e=>e.server_instance_id===i.server.server_instance_id)&&!a.some(e=>e.items.some(e=>e.identity.id===u));if(d&&this.dispatch({type:`select-model`,modelId:null}),d||await this.refreshSelectedRuntime(e.signal,t),r&&(this.needsFullSnapshot=!1,this.lastFullSnapshotAt=n),!this.isCurrent(e,t))return;let f=this.reconcilePending(l,n);this.failures=0,f||this.dispatch({type:`connection`,connection:`ready`,now:n}),this.eventAbort===null&&!this.visibility.hidden()&&this.startEvents()}catch(n){!e.signal.aborted&&this.generation===t&&(this.failures+=1,this.dispatch({type:`connection`,connection:Kn(n),error:qn(n),now:this.clock.now()}))}finally{this.clock.clearTimeout(r),this.observationTimer===r&&(this.observationTimer=null),this.inflight===e&&(this.inflight=null),!this.stopped&&this.generation===t&&this.reschedule(this.pollDelay())}}noteUnknownPost(e){this.dispatch({type:`pending`,item:e}),this.reschedule(0)}startEvents(){this.eventAbort?.abort();let e=new AbortController;this.eventAbort=e;let t=this.generation,n=Gn(this.getSnapshot());this.client.events({onEvent:n=>{this.generation===t&&!e.signal.aborted&&!this.stopped&&this.handleEvent(n)},onRetryAfter:n=>{this.generation===t&&!e.signal.aborted&&!this.stopped&&this.reschedule(n)}},e.signal,n).then(()=>{this.generation===t&&(this.eventAbort===e&&(this.eventAbort=null),!e.signal.aborted&&!this.stopped&&this.reschedule(this.backoffDelay()))}).catch(n=>{e.signal.aborted||this.stopped||this.generation!==t||(this.failures+=1,this.eventAbort=null,this.dispatch({type:`connection`,connection:Kn(n),error:qn(n),now:this.clock.now()}),this.reschedule(this.backoffDelay()))})}handleEvent(e){this.dispatch({type:`event`,event:e,now:this.clock.now()}),Un.has(e.type)&&(this.needsFullSnapshot=!0),(e.type===`server_restart`||e.type===`gap`||e.type===`reset`)&&e.payload.resnapshot&&(this.needsFullSnapshot=!0,this.eventAbort?.abort(),this.eventAbort=null,this.refresh())}async catalogSnapshot(e){let t=[],n,r=null;for(;;){let i=await this.client.catalog(n===void 0?{}:{cursor:n},e);if(r===null?r=i:Yn(`catalog`,r,i),t.push(i),i.pagination.next_cursor===null)return t;n=i.pagination.next_cursor}}async operationSnapshot(e){let t=[],n,r=null;for(;;){let i=await this.client.operationsPage(n===void 0?{}:{cursor:n},e);if(r===null?r=i:Yn(`operations`,r,i),t.push(i),i.pagination.next_cursor===null)return t;n=i.pagination.next_cursor}}async refreshSelectedRuntime(e,t){let n=this.getSnapshot().selectedModelId;if(n===null)return;let r;try{r=await this.client.runtime(n,e)}catch(e){throw typeof e==`object`&&e&&`status`in e&&e.status===404?new Jn(`Selected model changed during observation; refreshing the catalog.`):e}e.aborted||this.generation!==t||this.getSnapshot().selectedModelId===n&&this.dispatch({type:`runtime`,runtime:r,sequence:r.snapshot_sequence,now:this.clock.now()})}reconcilePending(e,t){let n=!1,r=new Set(e.map(e=>e.operation_id));for(let e of this.getSnapshot().pendingReconciliations.values())e.operationId!==null&&r.has(e.operationId)?this.dispatch({type:`reconciled`,idempotencyKey:e.idempotencyKey}):t-e.createdAt>=Vn&&(this.dispatch({type:`reconciled`,idempotencyKey:e.idempotencyKey}),this.dispatch({type:`connection`,connection:`stale`,error:{code:`unknown_post_unresolved`,message:`A previous control request could not be matched to an operation after reconciliation.`,retryable:!0},now:t}),n=!0);return n}reschedule(e){this.stopped||this.visibility.hidden()||(this.timer!==null&&this.clock.clearTimeout(this.timer),this.timer=this.clock.setTimeout(()=>{this.timer=null,this.refresh()},e))}pollDelay(){return Rn}backoffDelay(){let e=Math.min(Bn,500*2**Math.min(6,this.failures));return Math.round(e/2+this.random()*(e/2))}isCurrent(e,t){return this.inflight===e&&this.generation===t&&!e.signal.aborted}};function Gn(e){let t=Fn(e.resourceFences);if(e.serverInstanceId!==null&&t!==null)return{lastEventId:null,serverInstanceId:e.serverInstanceId,afterSequence:t};if(e.lastEventId!==null)return{lastEventId:e.lastEventId,serverInstanceId:null,afterSequence:null}}function Kn(e){if(e instanceof Jn)return`stale`;let t=typeof e==`object`&&e&&`status`in e&&typeof e.status==`number`?e.status:null;return t===401||e instanceof Error&&/401|unauthorized/i.test(e.message)?`unauthorized`:t===403||e instanceof Error&&/403|forbidden/i.test(e.message)?`forbidden`:e instanceof DOMException&&e.name===`AbortError`?`stale`:`offline`}function qn(e){return e instanceof Jn?{code:e.code,message:e.message,retryable:!0}:{code:`sync_error`,message:e instanceof Error?e.message.replace(/Bearer\s+\S+/gi,`Bearer [redacted]`):`Unknown WebUI client error`,retryable:!0}}var Jn=class extends Error{code=`snapshot_mismatch`;constructor(e){super(e),this.name=`SnapshotConsistencyError`}};function Yn(e,t,n){if(n.server_instance_id!==t.server_instance_id)throw new Jn(`${e} pagination crossed a server restart; refresh the authoritative snapshot.`);if(n.snapshot_sequence!==t.snapshot_sequence)throw new Jn(`${e} pagination crossed snapshot sequence boundaries; refresh the authoritative snapshot.`)}var Xn={setTimeout:(e,t)=>globalThis.setTimeout(e,t),clearTimeout:e=>globalThis.clearTimeout(e),now:()=>Date.now()},Zn={hidden:()=>typeof document<`u`&&document.hidden,subscribe:e=>typeof document>`u`?()=>void 0:(document.addEventListener(`visibilitychange`,e),()=>document.removeEventListener(`visibilitychange`,e))},Qn=_.createContext(null),$n=_.createContext(null);function er({children:e,apiBase:t,fetchImpl:n}){let[r,i]=_.useReducer(Sn,void 0,xn),a=_.useRef(r);a.current=r;let o=_.useRef(0),s=_.useRef(null),c=_.useMemo(()=>new un({apiBase:t,fetchImpl:n,onUnauthorized:()=>{o.current+=1,s.current?.stop(),i({type:`logout`,now:Date.now()})}}),[t,n]);_.useEffect(()=>{let e=new Wn({client:c,dispatch:i,getSnapshot:()=>a.current});return s.current=e,()=>{e.dispose(),s.current=null,c.abortAll()}},[c]);let l=_.useMemo(()=>({getTokenCount:(e,t,n)=>c.tokenCount(d(e),t,n),getSettings:(e,t)=>c.settings(d(e),t),patchSettings:(e,t,n)=>c.patchSettings(d(e),t,n),getModelProps:(e,t)=>c.modelProps(d(e),t),login:async e=>{o.current+=1;let t=o.current;c.abortAll(),c.setBearerToken(e),i({type:`login-start`});try{let e=await c.bootstrap();if(o.current!==t)return;i({type:`login-success`,bootstrap:e,now:Date.now()}),s.current?.start()}catch(e){throw o.current===t&&(c.setBearerToken(null),c.abortAll(),i({type:`logout`,now:Date.now()})),e}},logout:()=>{o.current+=1,s.current?.stop(),c.setBearerToken(null),c.abortAll(),i({type:`logout`,now:Date.now()})},refresh:async()=>{await s.current?.resnapshot()},selectModel:e=>{i({type:`select-model`,modelId:e}),s.current?.selectionChanged()},loadModel:async e=>{await u(`model-action`,e.idempotency_key,e.model_id,()=>c.modelAction(e))},unloadModel:async e=>{await u(`model-action`,e.idempotency_key,e.model_id,()=>c.modelAction(e))},downloadModel:async e=>{await u(`download`,e.idempotency_key,void 0,()=>c.download(e))},removeModel:async e=>{await u(`removal`,e.idempotency_key,e.model_id,()=>c.removeModel(e))},refreshRuntime:async e=>{let t=o.current,n=await c.runtime(e);return o.current===t&&i({type:`runtime`,runtime:n,sequence:n.snapshot_sequence,now:Date.now()}),n},refreshCatalog:async e=>{await u(`catalog-refresh`,e,void 0,()=>c.refreshCatalog(e))},cancelOperation:async e=>{let t=o.current;await c.cancelOperation(e),o.current===t&&await s.current?.resnapshot()},streamChatCompletions:async(e,t,n,r)=>{await c.chatCompletions(d(e),t,n,r)},streamResponses:async(e,t,n,r)=>{await c.responses(d(e),t,n,r)}}),[c]);async function u(e,t,n,r){let i=o.current;try{let a=await r();if(o.current!==i)return;s.current?.noteUnknownPost({kind:e,idempotencyKey:t,operationId:a.operation_id,modelId:n,createdAt:Date.now()})}catch(r){throw o.current===i&&!(r instanceof cn)&&s.current?.noteUnknownPost({kind:e,idempotencyKey:t,operationId:null,modelId:n,createdAt:Date.now()}),r}}function d(e){let t=a.current.catalog.find(t=>t.identity.id===e);if(t===void 0)throw Error(`Selected model is not present in the catalog snapshot.`);if(t.identity.inference_id.length===0)throw Error(`Selected model does not expose an inference model id.`);return t.identity.inference_id}return(0,x.jsx)($n.Provider,{value:l,children:(0,x.jsx)(Qn.Provider,{value:r,children:e})})}function tr(){let e=_.useContext(Qn);if(e===null)throw Error(`useWebUi must be used within WebUiProvider.`);return e}function nr(){let e=_.useContext($n);if(e===null)throw Error(`useWebUiActions must be used within WebUiProvider.`);return e}var rr=Object.freeze({}),ir=[`max_tokens`,`temperature`,`top_p`,`top_k`,`min_p`,`repetition_penalty`,`seed`];function ar(e){if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Request defaults must be an object.`);let t={};for(let[n,r]of Object.entries(e)){if(!ir.includes(n))throw Error(`Unsupported request default: ${n}`);if(r!==void 0){if(typeof r!=`number`||!Number.isFinite(r))throw Error(`${n} must be a finite number; leave blank to inherit.`);if([`max_tokens`,`top_k`,`seed`].includes(n)&&!Number.isSafeInteger(r))throw Error(`${n} must be a safe integer.`);if(n===`max_tokens`&&r<1||n===`temperature`&&r<0||n===`top_k`&&r<0||[`top_p`,`min_p`].includes(n)&&(r<0||r>1)||n===`repetition_penalty`&&r<=0||n===`seed`&&r<0)throw Error(`${n} is outside its supported range.`);t[n]=r}}return Object.freeze(t)}var or=rr,sr=new Set;function cr(e){return sr.add(e),()=>sr.delete(e)}function lr(e){or=ar(e);for(let e of sr)e()}function ur(){lr(rr)}function dr(){return{defaults:(0,_.useSyncExternalStore)(cr,()=>or,()=>rr),setDefaults:lr,reset:ur}}function fr(e,t,n){return e===null||e<=0||t===null||n===void 0?`unknown`:t+n>e?`exceeds`:`raw-fits`}function pr({modelId:e,nCtx:t,locale:n}){let r=nr(),{defaults:i}=dr(),[a,o]=(0,_.useState)(``),[s,c]=(0,_.useState)(null),[l,u]=(0,_.useState)(!1),[d,f]=(0,_.useState)(!1),p=(0,_.useRef)(null);(0,_.useEffect)(()=>()=>p.current?.abort(),[]);let m=async()=>{p.current?.abort();let t=new AbortController;p.current=t,u(!0),f(!1),c(null);try{let n=await r.getTokenCount(e,a,t.signal);t.signal.aborted||c(n)}catch{t.signal.aborted||f(!0)}finally{t.signal.aborted||u(!1)}},h=fr(t,s,i.max_tokens),g=h===`exceeds`?z(n,`settings.context_check.exceeds`):h===`unknown`?z(n,`settings.context_check.unknown`):z(n,`settings.context_check.fits`);return(0,x.jsxs)(`div`,{children:[(0,x.jsx)(at,{label:z(n,`settings.context_check.label`),value:a,onChange:e=>{p.current?.abort(),u(!1),o(e),c(null)},hint:z(n,`settings.context_check.hint`)}),(0,x.jsx)(P,{disabled:l||a.length===0,onClick:()=>void m(),children:z(n,`settings.context_check.check`)}),(0,x.jsx)(`p`,{role:`status`,children:d?z(n,`settings.context_check.unavailable`):s===null?z(n,`settings.context_check.not_measured`):z(n,`settings.context_check.count`,{count:String(s),verdict:g})})]})}function mr(e){return e instanceof cn?e.status===401?`wrong-key`:e.status===403?`forbidden`:`generic`:e instanceof V||e instanceof Error&&e.name===`ValidationError`?`schema`:e instanceof TypeError||e instanceof Error&&/fetch|network|offline|connection/i.test(e.message)?`offline`:`generic`}function hr(e,t){let n=Tr(t);return n===null?z(e,`model.selected.none`):`${n.identity.display_name} · ${Er(e,n.lifecycle.state)}`}function gr(e,t){return t.bootstrap===null?z(e,`connection.ready`):z(e,`connection.footer.connected`,{mode:t.bootstrap.server.mode,version:t.bootstrap.server.build.version,sequence:Dr(e,t),status:_r(e,t.connection)})}function _r(e,t){return z(e,{idle:`connection.status.idle`,bootstrapping:`connection.status.bootstrapping`,ready:`connection.status.ready`,streaming:`connection.status.streaming`,polling:`connection.status.polling`,offline:`connection.status.offline`,stale:`connection.status.stale`,unauthorized:`connection.status.unauthorized`,forbidden:`connection.status.forbidden`,"schema-mismatch":`connection.status.schema_mismatch`,error:`connection.status.error`}[t])}function vr(e){return e.snapshot.auth.status===`authenticated`?e.snapshot.connection===`schema-mismatch`?(0,x.jsx)(xr,{...e}):(0,x.jsx)(br,{...e}):(0,x.jsx)(yr,{...e})}function yr(e){return e.authFailure===`schema`?(0,x.jsx)(xr,{...e}):(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsx)(Ge,{className:`connection-prompt`,title:e.title,titleTestId:e.titleTestId,description:z(e.locale,`connection.prompt.body`),descriptionTestId:B(`connection.prompt.body`)}),(0,x.jsx)(pt,{title:z(e.locale,`state.unauthorized.title`),body:z(e.locale,`state.unauthorized.body`),tokenLabel:z(e.locale,`login.token.label`),tokenHelp:z(e.locale,`login.token.help`),submitLabel:z(e.locale,`login.submit`),logoutLabel:z(e.locale,`login.logout`),error:e.authFailure===null?void 0:wr(e.locale,e.authFailure),busy:e.snapshot.auth.status===`authenticating`,onSubmit:e.onLogin,onLogout:e.onLogout,testId:B(`auth.login`)})]})}function br(e){let t=e.snapshot.connection===`offline`||e.snapshot.connection===`stale`||e.snapshot.connection===`error`||e.snapshot.connection===`unauthorized`||e.snapshot.connection===`forbidden`;return(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsx)(Ge,{className:`connection-prompt`,title:e.title,titleTestId:e.titleTestId,description:z(e.locale,`connection.authenticated.body`),descriptionTestId:B(`connection.authenticated.body`)}),(0,x.jsx)(R,{tone:`info`,title:z(e.locale,`connection.authenticated.title`),body:Sr(e.locale,e.snapshot),testId:B(`connection.authenticated.detail`)}),t?(0,x.jsx)(R,{title:z(e.locale,`connection.error.title`),body:Cr(e.locale,e.snapshot.connection),action:(0,x.jsx)(P,{onClick:e.onRetry,children:z(e.locale,`common.retry`)}),testId:B(`connection.error.title`)}):null]})}function xr(e){return(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsx)(Ge,{className:`connection-prompt`,title:e.title,titleTestId:e.titleTestId}),(0,x.jsx)(mt,{title:z(e.locale,`state.schema_mismatch.title`),body:z(e.locale,`state.schema_mismatch.body`),actionLabel:z(e.locale,`common.reload`),onRecover:e.onRecoverSchema})]})}function Sr(e,t){let n=t.bootstrap;return n===null?z(e,`connection.prompt.detail`):z(e,`connection.authenticated.detail`,{mode:n.server.mode,version:n.server.build.version,status:_r(e,t.connection),count:t.catalogSequence===null?z(e,`connection.snapshot.pending`):String(t.catalog.length),operations:t.resourceFences.operationsSnapshot===null?z(e,`connection.snapshot.pending`):String(t.operations.size),sequence:Dr(e,t)})}function Cr(e,t){return t===`offline`?z(e,`state.offline.body`):t===`stale`?z(e,`connection.error.stale`):t===`forbidden`?z(e,`connection.error.forbidden`):t===`unauthorized`?z(e,`connection.error.unauthorized`):z(e,`connection.error.generic`)}function wr(e,t){return t===`wrong-key`?z(e,`login.error.wrong_key`):t===`offline`?z(e,`login.error.offline`):t===`forbidden`?z(e,`login.error.forbidden`):t===`schema`?z(e,`login.error.schema`):z(e,`login.error.generic`)}function Tr(e){return e.selectedModelId===null?null:e.catalog.find(t=>t.identity.id===e.selectedModelId)??null}function Er(e,t){return z(e,{unloaded:`models.status.unloaded`,loading:`models.status.loading`,ready:`models.status.ready`,draining:`models.status.draining`,unloading:`models.status.unloading`,failed:`models.status.failed`}[t])}function Dr(e,t){return String(t.lastSequence??t.catalogSequence??t.resourceFences.operationsSnapshot??z(e,`connection.snapshot.pending`))}function Or({locale:e}){let{defaults:t,setDefaults:n,reset:r}=dr(),[i,a]=(0,_.useState)(()=>Object.fromEntries(Object.entries(t).map(([e,t])=>[e,String(t)]))),[o,s]=(0,_.useState)(``),[c,l]=(0,_.useState)(!1);return(0,x.jsxs)(`section`,{className:`screen-stack`,children:[(0,x.jsx)(`h2`,{children:z(e,`settings.generation.title`)}),(0,x.jsx)(`p`,{children:z(e,`settings.generation.body`)}),(0,x.jsx)(`div`,{className:`settings-grid`,children:ir.map(n=>(0,x.jsx)(at,{label:n,value:i[n]??``,onChange:e=>a(t=>({...t,[n]:e})),hint:z(e,`settings.generation.current`,{value:t[n]?.toString()??z(e,`settings.generation.inherit`)})},n))}),o?(0,x.jsx)(R,{title:z(e,`settings.generation.error_title`),body:o}):null,(0,x.jsxs)(`div`,{children:[(0,x.jsx)(P,{onClick:()=>{try{n(ar(Object.fromEntries(Object.entries(i).filter(([,e])=>e.trim()!==``).map(([e,t])=>[e,Number(t)])))),s(``)}catch(t){s(t instanceof Error?t.message:z(e,`settings.generation.invalid`))}},children:z(e,`settings.generation.save`)}),` `,(0,x.jsx)(P,{onClick:()=>l(!0),children:z(e,`settings.generation.reset_open`)})]}),(0,x.jsx)(at,{label:z(e,`settings.generation.reasoning_label`),value:z(e,`settings.generation.reasoning_value`),disabled:!0,hint:z(e,`settings.generation.reasoning_hint`)}),(0,x.jsxs)(ct,{open:c,title:z(e,`settings.generation.reset.title`),closeLabel:z(e,`common.close`),onClose:()=>l(!1),children:[(0,x.jsx)(`p`,{children:z(e,`settings.generation.reset.body`)}),(0,x.jsx)(P,{onClick:()=>{r(),a({}),s(``),l(!1)},children:z(e,`settings.generation.reset.confirm`)})]})]})}function kr({modelId:e,locale:t}){let n=nr(),[r,i]=(0,_.useState)(null),[a,o]=(0,_.useState)({}),[s,c]=(0,_.useState)({}),[l,u]=(0,_.useState)(``),[d,f]=(0,_.useState)(!1),[p,m]=(0,_.useState)(!1),h=(0,_.useRef)(null),g=(0,_.useRef)(t);g.current=t,(0,_.useEffect)(()=>{let t=new AbortController;return h.current=t,f(!0),n.getSettings(e,t.signal).then(e=>{t.signal.aborted||i(e)}).catch(()=>{t.signal.aborted||u(z(g.current,`settings.live.unavailable`))}).finally(()=>{t.signal.aborted||f(!1)}),()=>t.abort()},[n,e]);let v=async()=>{let t=h.current;if(!(t===null||t.signal.aborted)){f(!0);try{let r=await n.getSettings(e,t.signal);t.signal.aborted||(i(r),u(z(g.current,`settings.live.refreshed`)))}catch{t.signal.aborted||u(z(g.current,`settings.live.refresh_failed`))}finally{t.signal.aborted||f(!1)}}},y=async()=>{let s=h.current;if(s===null||s.signal.aborted||r===null)return;let l={},d={};for(let e of r.schema)if(Object.hasOwn(a,e.name))try{l[e.name]=bt(e,a[e.name])}catch(n){d[e.name]=n instanceof Error?n.message:z(t,`settings.live.invalid_value`)}if(c(d),!(Object.keys(d).length>0)){f(!0);try{let t=await n.getSettings(e,s.signal);if(s.signal.aborted)return;if(t.fingerprint!==r.fingerprint){i(t),u(z(g.current,`settings.live.conflict`));return}let a=await n.patchSettings(e,l,s.signal);if(s.signal.aborted)return;c(Object.fromEntries(a.rejected.map(e=>[e.name,e.reason]))),o(e=>Object.fromEntries(Object.entries(e).filter(([e])=>!Object.hasOwn(a.applied,e)))),u(a.rejected.length>0?z(g.current,`settings.live.partial`,{applied:String(Object.keys(a.applied).length),rejected:String(a.rejected.length)}):z(g.current,`settings.live.applied`));let d=await n.getSettings(e,s.signal);s.signal.aborted||i(d)}catch{s.signal.aborted||u(z(g.current,`settings.live.unknown_outcome`))}finally{s.signal.aborted||f(!1)}}},b=(e,n)=>{let r={help:e.help,current:xt(e,n),type:e.type};return e.allowed===null?z(t,`settings.live.hint`,r):z(t,`settings.live.hint_allowed`,{...r,allowed:e.allowed.join(`, `)})};return(0,x.jsxs)(`section`,{className:`screen-stack`,children:[(0,x.jsx)(`h2`,{children:z(t,`settings.live.title`)}),(0,x.jsx)(`p`,{children:z(t,`settings.live.body`)}),l?(0,x.jsx)(R,{tone:`warning`,title:z(t,`settings.live.result_title`),body:l}):null,(0,x.jsxs)(`div`,{children:[(0,x.jsx)(P,{onClick:()=>void v(),disabled:d,children:z(t,`settings.live.refresh`)}),` `,(0,x.jsx)(P,{onClick:()=>void y(),disabled:d||Object.keys(a).length===0,children:z(t,`settings.live.apply`)}),` `,(0,x.jsx)(P,{onClick:()=>m(!0),disabled:d||r===null,children:z(t,`settings.live.reset_open`)})]}),r?.schema.filter(e=>e.mutable).map(e=>(0,x.jsx)(at,{label:e.name,value:a[e.name]??xt(e,r.current[e.name]),onChange:t=>o(n=>({...n,[e.name]:t})),disabled:d,error:s[e.name],hint:b(e,r.current[e.name])},e.name)),(0,x.jsxs)(`details`,{children:[(0,x.jsx)(`summary`,{children:z(t,`settings.live.startup`)}),r?.schema.filter(e=>!e.mutable).map(e=>(0,x.jsx)(at,{label:e.name,value:xt(e,r.current[e.name]),disabled:!0,hint:e.reason??e.help},e.name))]}),(0,x.jsxs)(ct,{open:p,title:z(t,`settings.live.reset.title`),closeLabel:z(t,`common.close`),onClose:()=>m(!1),children:[(0,x.jsx)(`p`,{children:z(t,`settings.live.reset.body`)}),(0,x.jsx)(P,{onClick:()=>{r!==null&&o(Object.fromEntries(r.schema.filter(e=>e.mutable).map(e=>[e.name,xt(e,e.default)]))),c({}),m(!1)},children:z(t,`settings.live.reset.confirm`)})]})]})}var Ar=[`fp16`,`float16`,`int8`,`i8`,`turbo4-asym`,`fp16+turbo4`,`turbo3-asym`,`fp16+turbo3`,`turbo3`,`turbo4`,`turbo4-sym`,`turbo4-delegated`,`fp16+turbo4-delegated`],jr=Object.freeze({});function Mr(e){if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Profile must be an object.`);let t={};for(let[n,r]of Object.entries(e)){if(![`ctx_size`,`n_parallel`,`kv_cache_mode`].includes(n))throw Error(`Unsafe or unsupported profile field: ${n}`);if(r!=null){if(n===`kv_cache_mode`){if(typeof r!=`string`||!Ar.includes(r))throw Error(`Unknown KV cache mode.`);t.kv_cache_mode=r}else{if(typeof r!=`number`||!Number.isInteger(r)||r<1||r>(n===`ctx_size`?262144:32))throw Error(`${n} is outside its supported range.`);n===`ctx_size`?t.ctx_size=r:t.n_parallel=r}}}return Object.freeze(t)}function Nr(e){if(e.length>65536)throw Error(`Profile import exceeds 64 KiB.`);let t=JSON.parse(e);if(typeof t!=`object`||!t||Array.isArray(t))throw Error(`Invalid profile document.`);let n=t;if(n.version===0&&Object.keys(n).every(e=>[`version`,`profile`].includes(e)))return{version:1,reusable:Mr(n.profile),models:{}};if(n.version!==1||Object.keys(n).some(e=>![`version`,`reusable`,`models`].includes(e)))throw Error(`Unsupported profile version or fields.`);if(typeof n.models!=`object`||n.models===null||Array.isArray(n.models))throw Error(`Invalid model profiles.`);let r=Object.create(null);if(Object.keys(n.models).length>200)throw Error(`Too many model profiles.`);for(let[e,t]of Object.entries(n.models)){if(!/^mdl_[A-Za-z0-9_-]{43}$/.test(e))throw Error(`Model profiles require opaque catalog IDs.`);r[e]=Mr(t)}return{version:1,reusable:Mr(n.reusable),models:r}}var Pr=`mlxcel.webui.load-profiles.v1`,Fr={version:1,reusable:jr,models:{}},Ir=!1,Lr=new Set;function Rr(e){return Lr.add(e),()=>Lr.delete(e)}function zr(){if(!Ir){Ir=!0;try{let e=localStorage.getItem(Pr);e!==null&&(Fr=Nr(e))}catch{}}}function Br(e){let t=JSON.stringify(e),n=Nr(t);localStorage.setItem(Pr,t),Fr=n;for(let e of Lr)e()}function Vr(e){zr();let t=(0,_.useSyncExternalStore)(Rr,()=>Fr);return{reusable:t.reusable,modelProfile:e===null?jr:t.models[e]??jr,profile:e!==null&&Object.hasOwn(t.models,e)?t.models[e]:t.reusable,save:(t,n)=>{let r=Mr(t);if(n===`model`&&e===null)throw Error(`Select a model first.`);Br(n===`reusable`?{...Fr,reusable:r}:{...Fr,models:{...Fr.models,[e]:r}})},reset:(t=e===null?`reusable`:`model`)=>{let n=Object.fromEntries(Object.entries(Fr.models).filter(([t])=>t!==e));Br(t===`reusable`?{...Fr,reusable:jr}:{...Fr,models:n})},exportJson:()=>JSON.stringify(Fr,null,2),importJson:e=>Br(Nr(e))}}function Hr(e){let t=Mr(e);return[`mlxcel-server --webui`,t.ctx_size===void 0?``:`--ctx-size ${t.ctx_size}`,t.n_parallel===void 0?``:`--parallel ${t.n_parallel}`,t.kv_cache_mode===void 0?``:`--kv-cache-mode ${t.kv_cache_mode}`].filter(Boolean).join(` `)}function Ur({model:e,locale:t,single:n}){let r=Vr(e?.identity.id??null),[i,a]=(0,_.useState)(r.profile),[o,s]=(0,_.useState)(e===null?`reusable`:`model`),[c,l]=(0,_.useState)(``),[u,d]=(0,_.useState)(``),[f,p]=(0,_.useState)(!1),m=o===`reusable`?r.reusable:r.modelProfile;(0,_.useEffect)(()=>{a(m)},[m]);let h=e=>{try{e(),d(z(t,`settings.profile.saved`))}catch(e){d(e instanceof Error?e.message:z(t,`settings.profile.failed`))}};return(0,x.jsxs)(`section`,{className:`screen-stack`,children:[(0,x.jsx)(`h2`,{children:z(t,`settings.profile.title`)}),(0,x.jsx)(`p`,{children:z(t,`settings.profile.body`)}),n?(0,x.jsx)(R,{tone:`info`,title:z(t,`settings.profile.single.title`),body:z(t,`settings.profile.single.body`)}):null,(0,x.jsx)(Ae,{locale:t,label:z(t,`settings.profile.scope`),value:o,onChange:e=>s(e),options:[{value:`reusable`,label:z(t,`settings.profile.scope.reusable`)},...e===null?[]:[{value:`model`,label:e.identity.display_name}]]}),(0,x.jsxs)(`div`,{className:`settings-grid`,children:[(0,x.jsx)(at,{label:`ctx_size (1–262144)`,value:i.ctx_size?.toString()??``,onChange:e=>a({...i,ctx_size:e.trim()===``?void 0:Number(e)}),hint:z(t,`settings.profile.ctx_hint`)}),(0,x.jsx)(at,{label:`n_parallel (1–32)`,value:i.n_parallel?.toString()??``,onChange:e=>a({...i,n_parallel:e.trim()===``?void 0:Number(e)}),hint:z(t,`settings.profile.parallel_hint`)}),(0,x.jsx)(Ae,{locale:t,label:`kv_cache_mode`,value:i.kv_cache_mode??``,onChange:e=>a({...i,kv_cache_mode:e===``?void 0:e}),options:[{value:``,label:z(t,`settings.profile.inherit`)},...Ar.map(e=>({value:e,label:e}))]})]}),(0,x.jsx)(`p`,{children:z(t,`settings.profile.restrictions`)}),u?(0,x.jsx)(R,{tone:`info`,title:z(t,`settings.profile.result_title`),body:u}):null,(0,x.jsxs)(`div`,{children:[(0,x.jsx)(P,{onClick:()=>h(()=>r.save(Mr(i),o)),children:z(t,`settings.profile.save`)}),` `,(0,x.jsx)(P,{onClick:()=>{a(m),d(``)},children:z(t,`settings.profile.discard`)}),` `,(0,x.jsx)(P,{onClick:()=>p(!0),children:z(t,`settings.profile.reset_open`)})]}),(0,x.jsxs)(`p`,{children:[z(t,`settings.profile.saved_pending`),`: `,(0,x.jsx)(`code`,{children:JSON.stringify(m)})]}),(0,x.jsx)(`p`,{children:z(t,`settings.profile.cli`)}),(0,x.jsx)(`code`,{children:Hr(m)}),(0,x.jsxs)(`details`,{children:[(0,x.jsx)(`summary`,{children:z(t,`settings.profile.transfer`)}),(0,x.jsxs)(`label`,{className:`ds-field`,children:[(0,x.jsx)(`span`,{children:z(t,`settings.profile.transfer.label`)}),(0,x.jsx)(`textarea`,{value:c,onChange:e=>l(e.currentTarget.value),maxLength:65536,rows:6})]}),(0,x.jsx)(P,{onClick:()=>l(r.exportJson()),children:z(t,`settings.profile.transfer.export`)}),` `,(0,x.jsx)(P,{onClick:()=>h(()=>r.importJson(c)),children:z(t,`settings.profile.transfer.import`)})]}),(0,x.jsxs)(ct,{open:f,title:z(t,`settings.profile.reset.title`),closeLabel:z(t,`common.close`),onClose:()=>p(!1),children:[(0,x.jsx)(`p`,{children:z(t,`settings.profile.reset.body`)}),(0,x.jsx)(P,{onClick:()=>{h(()=>r.reset(o)),p(!1)},children:z(t,`settings.profile.reset.confirm`)})]})]})}function Wr({locale:e}){let t=tr(),n=nr(),r=t.catalog.find(e=>e.identity.id===t.selectedModelId)??null,[i,a]=(0,_.useState)(null),o=t.auth.status===`authenticated`&&[`ready`,`streaming`,`polling`].includes(t.connection),s=o&&r?.lifecycle.state===`ready`?r.identity.id:null;(0,_.useEffect)(()=>{if(a(null),s===null)return;let e=new AbortController;return n.getModelProps(s,e.signal).then(t=>{e.signal.aborted||a(t)}).catch(()=>void 0),()=>e.abort()},[n,s,r?.identity.revision]);let c=z(e,`settings.server.unknown`);return(0,x.jsxs)(`div`,{className:`screen-stack settings-sections`,children:[(0,x.jsxs)(`section`,{className:`screen-stack`,children:[(0,x.jsx)(`h2`,{children:z(e,`settings.server.privacy.title`)}),(0,x.jsx)(`p`,{children:z(e,`settings.server.privacy.body`)})]}),(0,x.jsx)(Or,{locale:e}),o?(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(Ae,{locale:e,label:z(e,`settings.server.model`),value:t.selectedModelId??``,options:[{value:``,label:z(e,`settings.server.model.none`)},...t.catalog.map(t=>({value:t.identity.id,label:`${t.identity.display_name} · ${Er(e,t.lifecycle.state)}`}))],onChange:e=>n.selectModel(e===``?null:e),hint:z(e,`settings.server.model.hint`),testId:`settings-model-selector`}),(0,x.jsx)(Ur,{model:r,locale:e,single:t.bootstrap?.server.mode===`single_model`},r?.identity.id??`reusable`),(0,x.jsxs)(`section`,{className:`screen-stack`,children:[(0,x.jsx)(`h2`,{children:z(e,`settings.server.context.title`)}),(0,x.jsx)(at,{label:z(e,`settings.server.context.n_ctx`),value:i?.nCtx?.toString()??c,disabled:!0,hint:z(e,`settings.server.context.n_ctx_hint`)}),(0,x.jsx)(at,{label:z(e,`settings.server.context.slots`),value:i?.totalSlots?.toString()??c,disabled:!0}),(0,x.jsx)(at,{label:z(e,`settings.server.context.kv_mode`),value:i?.kvCacheMode??c,disabled:!0}),(0,x.jsxs)(`p`,{children:[z(e,`settings.server.context.geometry`),`: `,(0,x.jsx)(`code`,{children:i?.geometry===null||i===null?z(e,`settings.server.context.geometry_unknown`):JSON.stringify(i.geometry)})]}),s===null?null:(0,x.jsx)(pr,{modelId:s,nCtx:i?.nCtx??null,locale:e},s)]}),s===null?(0,x.jsx)(R,{tone:`info`,title:z(e,`settings.server.no_model.title`),body:z(e,`settings.server.no_model.body`)}):t.bootstrap?.features.includes(`settings`)===!0?(0,x.jsx)(kr,{modelId:s,locale:e},s):(0,x.jsx)(R,{tone:`info`,title:z(e,`settings.server.live_disabled.title`),body:z(e,`settings.server.live_disabled.body`)})]}):(0,x.jsx)(R,{tone:`warning`,title:z(e,`settings.server.unavailable.title`),body:z(e,`settings.server.unavailable.body`)})]})}var Gr=[{id:`models`,key:`nav.models`,icon:`models`},{id:`chat`,key:`nav.chat`,icon:`chat`},{id:`activity`,key:`nav.activity`,icon:`activity`},{id:`settings`,key:`nav.settings`,icon:`settings`}];function Kr(e){let t=(0,_.useRef)(null),n=(0,_.useRef)(e.onCommand),r=(0,_.useRef)(e.onHelp),[i,a]=(0,_.useState)(!1);(0,_.useEffect)(()=>{n.current=e.onCommand,r.current=e.onHelp},[e.onCommand,e.onHelp]),(0,_.useEffect)(()=>{let e=e=>{let t=e.target,i=t instanceof HTMLElement&&(t.isContentEditable||!!t.closest(`[role="combobox"], [role="listbox"]`)||[`INPUT`,`TEXTAREA`,`SELECT`].includes(t.tagName)),o=t instanceof HTMLElement&&!!t.closest(`dialog[open], [role="dialog"][aria-modal="true"]`);e.isComposing||e.altKey||i||o||((e.metaKey||e.ctrlKey)&&e.key.toLowerCase()===`k`&&(e.preventDefault(),a(!1),n.current()),(e.key===`?`||e.key===`/`&&e.shiftKey)&&(e.preventDefault(),a(!1),r.current()))};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[]),(0,_.useEffect)(()=>{if(!i||typeof window.matchMedia!=`function`)return;let e=window.matchMedia(`(max-width: 960px)`),n=()=>{e.matches||(a(!1),requestAnimationFrame(()=>{let e=document.activeElement;if(e&&e!==document.body&&!e.closest(`[aria-modal="true"]`))return;let n=t.current;(n?.querySelector(`a[aria-current="page"]`)??n?.querySelector(`a`))?.focus()}))};return e.addEventListener(`change`,n),()=>e.removeEventListener(`change`,n)},[i]);let o=n=>{let r=Gr[(Gr.findIndex(t=>t.id===e.route)+n+Gr.length)%Gr.length];e.onRouteChange(r.id),requestAnimationFrame(()=>t.current?.querySelector(`a[href="#${r.id}"]`)?.focus())},s=e=>{(e.key===`[`||e.key===`]`)&&(e.altKey||e.metaKey||e.ctrlKey||e.nativeEvent.isComposing||(e.preventDefault(),o(e.key===`]`?1:-1)))},c=t=>{e.onRouteChange(t),a(!1)};return(0,x.jsxs)(`div`,{className:`app-shell`,children:[(0,x.jsx)(qr,{locale:e.locale,route:e.route,onRouteChange:c,onKeyDown:s,ref:t,className:`app-sidebar desktop-sidebar material-glass`,connectionLabel:e.connectionLabel,connectionState:e.connectionState}),(0,x.jsx)(Ie,{open:i,title:z(e.locale,`nav.primary`),onClose:()=>a(!1),closeLabel:z(e.locale,`common.close`),testId:`mobile-nav-sheet`,children:(0,x.jsx)(qr,{locale:e.locale,route:e.route,onRouteChange:c,onKeyDown:s,className:`app-sidebar sheet-sidebar`,connectionLabel:e.connectionLabel,connectionState:e.connectionState})}),(0,x.jsxs)(`main`,{className:`app-main`,"aria-labelledby":`app-title`,inert:i,children:[(0,x.jsxs)(`header`,{className:`app-toolbar material-glass`,children:[(0,x.jsx)(F,{className:`mobile-menu-button`,label:z(e.locale,`toolbar.menu`),icon:`menu`,onClick:()=>a(!0),"data-testid":B(`toolbar.menu`)}),(0,x.jsxs)(`div`,{className:`toolbar-title`,children:[(0,x.jsx)(`p`,{id:`app-title`,"data-testid":B(`app.title`),children:z(e.locale,`app.title`)}),(0,x.jsx)(`span`,{"data-testid":B(`app.subtitle`),children:z(e.locale,`app.subtitle`)})]}),(0,x.jsx)(`div`,{className:`selected-model`,title:e.selectedModel,children:e.selectedModel}),(0,x.jsxs)(`div`,{className:`toolbar-actions`,children:[e.sessionAction,(0,x.jsx)(F,{label:z(e.locale,`toolbar.command`),icon:`command`,onClick:e.onCommand,"data-testid":B(`toolbar.command`)}),(0,x.jsx)(F,{label:z(e.locale,`toolbar.help`),icon:`help`,onClick:e.onHelp,"data-testid":B(`toolbar.help`)})]})]}),(0,x.jsxs)(`div`,{className:`app-content-grid ${e.inspector?`has-inspector`:``}`.trim(),children:[(0,x.jsx)(We,{className:`app-content`,children:e.children}),e.inspector]})]})]})}var qr=_.forwardRef((e,t)=>(0,x.jsxs)(`aside`,{className:e.className,"aria-label":z(e.locale,`nav.primary`),onKeyDown:e.onKeyDown,ref:t,tabIndex:-1,children:[(0,x.jsxs)(`a`,{className:`brand-mark`,href:`#models`,"aria-label":z(e.locale,`nav.home`),onClick:t=>{t.preventDefault(),e.onRouteChange(`models`)},children:[(0,x.jsx)(`span`,{className:`brand-symbol`,"aria-hidden":`true`,children:`mx`}),(0,x.jsx)(`span`,{className:`brand-name`,children:`mlxcel`})]}),(0,x.jsx)(`nav`,{className:`app-nav`,children:Gr.map(t=>(0,x.jsxs)(`a`,{href:`#${t.id}`,"aria-label":z(e.locale,t.key),"aria-current":e.route===t.id?`page`:void 0,"data-testid":B(t.key),onClick:n=>{n.preventDefault(),e.onRouteChange(t.id)},children:[(0,x.jsx)(C,{name:t.icon}),(0,x.jsx)(`span`,{className:`app-nav-label`,children:z(e.locale,t.key)})]},t.id))}),(0,x.jsxs)(`footer`,{children:[(0,x.jsx)(`span`,{className:`connection-dot`,"data-state":e.connectionState,"aria-hidden":`true`}),(0,x.jsx)(`span`,{"data-testid":B(`connection.ready`),children:e.connectionLabel})]})]}));qr.displayName=`Sidebar`;var Jr=[`mlxcel`,`glass`],Yr=[`light`,`dark`],Xr=[`system`,`light`,`dark`],Zr=`mlxcel`,Qr=`system`;Jr.flatMap(e=>Yr.map(t=>`${e}-${t}`));var $r=`(prefers-color-scheme: dark)`;function ei(e){return typeof e==`string`&&Jr.includes(e)}function ti(e){return typeof e==`string`&&Xr.includes(e)}function ni(e,t){return`${e}-${t}`}function ri(){try{return typeof window>`u`||typeof window.matchMedia!=`function`?`light`:window.matchMedia(`(prefers-color-scheme: dark)`).matches?`dark`:`light`}catch{return`light`}}function ii(e,t=ri()){return e===`system`?t:e}function ai(e,t,n=ri()){let r=ii(t,n);return{id:ni(e,r),family:e,scheme:r,preference:t}}function oi(e){if(typeof window>`u`||typeof window.matchMedia!=`function`)return()=>void 0;let t;try{t=window.matchMedia($r)}catch{return()=>void 0}let n=t=>e(t.matches?`dark`:`light`);return t.addEventListener(`change`,n),()=>t.removeEventListener(`change`,n)}var si={themeFamily:Zr,colorScheme:Qr,material:`glass`,glassIntensity:35,reduceMotion:!1,reduceTransparency:!1,highContrast:`system`,locale:`en`},ci=`mlxcel.webui.appearance`;function li(e){let t=typeof e==`number`&&Number.isFinite(e)?e:si.glassIntensity;return Math.max(0,Math.min(100,Math.round(t)))}function ui(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function di(e){return e===`glass`||e===`tinted`||e===`opaque`}function fi(e){return e===`system`||e===`on`||e===`off`}function pi(e){return fi(e)?e:e===!0?`on`:e===!1?`off`:si.highContrast}function mi(e){return ti(e.colorScheme)?e.colorScheme:e.colorScheme===void 0&&ti(e.theme)?e.theme:si.colorScheme}function hi(e){return e===`en`||e===`ko`}function gi(){if(typeof window>`u`)return si;let e;try{e=window.localStorage.getItem(ci)}catch{return si}if(!e)return si;try{let t=JSON.parse(e);return ui(t)?{themeFamily:ei(t.themeFamily)?t.themeFamily:si.themeFamily,colorScheme:mi(t),material:di(t.material)?t.material:si.material,glassIntensity:li(t.glassIntensity),reduceMotion:t.reduceMotion===!0,reduceTransparency:t.reduceTransparency===!0,highContrast:pi(t.highContrast),locale:hi(t.locale)?t.locale:si.locale}:si}catch{return si}}function _i(e){try{window.localStorage.setItem(ci,JSON.stringify(e))}catch{}}function vi(){return typeof CSS>`u`||typeof CSS.supports!=`function`?!1:CSS.supports(`backdrop-filter: blur(1px)`)||CSS.supports(`-webkit-backdrop-filter: blur(1px)`)}function yi(e,t,n=ri()){let r=ai(t.themeFamily,t.colorScheme,n);e.dataset.theme=r.id,e.dataset.themeFamily=r.family,e.dataset.colorScheme=r.preference,e.dataset.material=t.reduceTransparency?`opaque`:t.material,e.dataset.glassIntensity=String(li(t.glassIntensity)),e.dataset.reduceMotion=String(t.reduceMotion),e.dataset.reduceTransparency=String(t.reduceTransparency),e.dataset.highContrast=t.highContrast,e.dataset.backdropFilter=vi()?`supported`:`unsupported`,e.lang=t.locale}function bi(e){return e.value===null||!Number.isFinite(e.value)?`N/A`:`${new Intl.NumberFormat(void 0,{maximumFractionDigits:2}).format(e.value)} ${e.unit}`}function xi(e){let t=e.progress;return!t.indeterminate&&t.total_bytes!==null&&t.total_bytes>0?Math.min(100,100*t.completed_bytes/t.total_bytes):void 0}function Si(e){let t=e.selectedModelId===null?void 0:e.runtimes.get(e.selectedModelId);return JSON.stringify({format:`mlxcel-webui-diagnostics-v1`,connection:e.connection,last_successful_at:e.lastSuccessfulAt,operation_counts:Object.fromEntries([`queued`,`running`,`cancelling`,`succeeded`,`failed`,`cancelled`].map(t=>[t,[...e.operations.values()].filter(e=>e.state===t).length])),catalog_count:e.catalog.length,runtime_present:t!==void 0,history_samples:e.runtimeHistory.length,measurements:t===void 0?[]:Object.values(t.measurements).map(e=>({value:e.value,available:e.value!==null}))},null,2)}function Ci(e){let t=URL.createObjectURL(new Blob([Si(e)],{type:`application/json`})),n=document.createElement(`a`);n.href=t,n.download=`mlxcel-diagnostics.json`,n.click(),URL.revokeObjectURL(t)}function wi({operations:e,locale:t,stale:n}){let r=[...e.values()].sort((e,t)=>Number(yn(e))-Number(yn(t))||t.updated_at.localeCompare(e.updated_at));return(0,x.jsxs)(`section`,{"aria-label":z(t,`activity.operations`),children:[(0,x.jsx)(`h2`,{children:z(t,`activity.operations`)}),(0,x.jsx)(`p`,{role:`status`,"aria-live":`polite`,children:z(t,`activity.operations.counts`,{active:String(r.filter(e=>!yn(e)).length),failed:String(r.filter(e=>e.state===`failed`).length)})}),(0,x.jsx)(`p`,{children:z(t,`activity.session`)}),(0,x.jsx)(qe,{animate:r.some(e=>!yn(e)),children:r.length===0?(0,x.jsx)(fe,{title:z(t,`activity.operations.empty.title`),body:z(t,`activity.operations.empty.body`)}):(0,x.jsx)(`ol`,{className:`activity-operations`,children:r.map(e=>(0,x.jsx)(`li`,{children:(0,x.jsx)(Ti,{operation:e,locale:t,stale:n})},e.operation_id))})})]})}function Ti({operation:e,locale:t,stale:n}){let r=nr(),i=tr(),a=e.target,o=a.target_kind===`model`?i.catalog.find(e=>e.identity.id===a.model_id)?.identity.display_name??a.model_id:a.target_kind===`download`?a.repo_id:a.target_kind,[s,c]=(0,_.useState)(!1),[l,u]=(0,_.useState)(!1),d=yn(e),f=async()=>{c(!0),u(!1);try{await r.cancelOperation(e.operation_id)}catch{u(!0)}finally{c(!1)}};return(0,x.jsxs)(`article`,{className:`activity-operation`,children:[(0,x.jsxs)(`header`,{children:[(0,x.jsx)(`strong`,{children:e.kind.replaceAll(`_`,` `)}),(0,x.jsx)(ue,{state:e.state===`failed`?`failed`:d?`unloaded`:e.state===`cancelling`?`draining`:`loading`,label:z(t,`activity.status`),children:e.state})]}),(0,x.jsx)(`p`,{children:o}),(0,x.jsx)(`p`,{children:(0,x.jsx)(`time`,{dateTime:e.updated_at,children:new Date(e.updated_at).toLocaleString(t)})}),!d&&e.kind===`download`?(0,x.jsx)(de,{label:z(t,`activity.bytes`),value:xi(e),detail:z(t,`activity.download_progress`,{completed:e.progress.completed_bytes.toLocaleString(t),total:e.progress.total_bytes?.toLocaleString(t)??z(t,`activity.not_available`)})}):null,e.state===`cancelling`?(0,x.jsx)(`p`,{role:`status`,children:z(t,`activity.cancelling`)}):null,e.state===`failed`?(0,x.jsx)(R,{title:z(t,`activity.failure`),body:e.error?.code??`operation_failed`}):null,(0,x.jsxs)(`details`,{children:[(0,x.jsx)(`summary`,{children:z(t,`activity.details`)}),(0,x.jsx)(`p`,{children:e.operation_id}),(0,x.jsx)(`p`,{children:e.target.target_kind===`model`?e.target.model_id:e.target.target_kind})]}),!d&&e.state!==`cancelling`?e.cancellable?(0,x.jsx)(P,{disabled:n,busy:s,onClick:()=>{f()},children:z(t,`activity.cancel`)}):(0,x.jsx)(`p`,{children:z(t,`activity.cancel_unsupported`)}):null,l?(0,x.jsx)(R,{title:z(t,`activity.cancel_failed`),body:z(t,`activity.refresh`)}):null]})}var Ei=new Set(De.map(e=>e.key).filter(e=>e.startsWith(`activity.metric.`))),Di=e=>Ei.has(e);function Oi({runtime:e,locale:t,stale:n=!1}){if(e===void 0)return(0,x.jsx)(fe,{title:z(t,`activity.runtime`),body:z(t,`activity.unavailable`)});let r=Object.entries(e.measurements),i=new Set([`active_requests`,`queued_requests`,`completed_requests_total`,`completion_tokens_total`]),a=r.filter(([e,t])=>i.has(e)&&t.value!==null&&Number.isFinite(t.value)),o=r.filter(([,e])=>e.value===null||!Number.isFinite(e.value)).length,s=e=>{let n=`activity.metric.${e}`;return Di(n)?z(t,n):e.replaceAll(`_`,` `)},c=z(t,`activity.not_available`);return(0,x.jsxs)(`section`,{"aria-label":z(t,`activity.runtime`),children:[(0,x.jsx)(`h2`,{children:z(t,`activity.runtime`)}),n?(0,x.jsx)(R,{tone:`warning`,title:z(t,`activity.stale`),body:z(t,`activity.observed`)}):null,(0,x.jsx)(`div`,{className:`activity-metrics activity-metrics--summary`,"data-testid":`runtime-summary`,children:a.map(([e,t])=>(0,x.jsx)(rt,{className:`activity-metric`,label:s(e),value:bi(t)},e))}),a.length===0?(0,x.jsx)(`p`,{children:z(t,`activity.no_primary`)}):null,o>0?(0,x.jsxs)(`p`,{children:[z(t,`activity.unavailable_count`),`: `,o,`. `,z(t,`activity.unavailable_reason`)]}):null,(0,x.jsx)(`h3`,{children:z(t,`activity.slots`)}),(0,x.jsxs)(`p`,{children:[z(t,`activity.parallel`),`: `,e.slots.effective_parallelism??c,` / `,e.slots.configured_parallelism]}),(0,x.jsx)(`p`,{children:z(t,`activity.context_line`,{context:z(t,`activity.context`),request:e.slots.request_context_tokens?.toString()??c,pool:z(t,`activity.pool`),shared:e.slots.shared_pool_context_tokens?.toString()??c})}),e.slots.reason===null?null:(0,x.jsx)(`p`,{children:e.slots.reason}),(0,x.jsxs)(`p`,{children:[z(t,`activity.observed`),`: `,e.slots.measured_at===null?z(t,`activity.unknown_time`):new Date(e.slots.measured_at).toLocaleString(t)]}),e.slots.available?e.slots.items.map(n=>(0,x.jsxs)(`section`,{"aria-label":`${z(t,`activity.slot`)} ${n.id}`,children:[(0,x.jsxs)(`h4`,{children:[z(t,`activity.slot`),` `,n.id,` · `,n.processing?z(t,`activity.processing`):z(t,`activity.idle`)]}),n.prompt_tokens!==null&&e.slots.request_context_tokens!==null&&e.slots.request_context_tokens>0?(0,x.jsx)(de,{label:`${z(t,`activity.slot`)} ${n.id} ${z(t,`activity.context`)}`,value:n.prompt_tokens/e.slots.request_context_tokens*100,detail:z(t,`activity.slot_progress`,{used:String(n.prompt_tokens),total:String(e.slots.request_context_tokens)})}):(0,x.jsx)(`p`,{children:z(t,`activity.no_context`)}),(0,x.jsx)(`p`,{children:z(t,`activity.slot_tokens`,{decoded:n.decoded_tokens?.toString()??c,cached:n.cached_prompt_tokens?.toString()??c})})]},n.id)):e.slots.reason===null?(0,x.jsx)(`p`,{children:z(t,`activity.unavailable`)}):null,(0,x.jsxs)(`details`,{className:`activity-measurement-details`,children:[(0,x.jsx)(`summary`,{children:z(t,`activity.metric_details`)}),(0,x.jsx)(`p`,{children:z(t,`activity.memory`)}),(0,x.jsx)(`p`,{children:z(t,`activity.timing`)}),(0,x.jsx)(`div`,{className:`activity-metrics`,children:r.map(([e,n])=>(0,x.jsx)(rt,{className:`activity-metric`,label:s(e),value:bi(n),hint:(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(`p`,{children:[z(t,`activity.scope`),`: `,n.scope]}),(0,x.jsxs)(`p`,{children:[z(t,`activity.observed`),`: `,n.measured_at===null?z(t,`activity.unknown_time`):new Date(n.measured_at).toLocaleString(t)]}),n.reason===null?null:(0,x.jsx)(`p`,{children:n.reason})]})},e))})]})]})}var ki=(function(){let e=typeof document<`u`&&document.createElement(`link`).relList;return e&&e.supports&&e.supports(`modulepreload`)?`modulepreload`:`preload`})(),Ai=function(e,t){return new URL(e,t).href},ji={},Mi=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function s(e){return import.meta.resolve?import.meta.resolve(e):new URL(e,import.meta.url).href}r=o(t.map(t=>{if(t=Ai(t,n),t=s(t),t in ji)return;ji[t]=!0;let r=t.endsWith(`.css`);for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}let i=document.createElement(`link`);if(i.rel=r?`stylesheet`:ki,r||(i.as=`script`),i.crossOrigin=``,i.href=t,a&&i.setAttribute(`nonce`,a),document.head.appendChild(i),r)return new Promise((e,n)=>{i.addEventListener(`load`,e),i.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}).filter(e=>e!==void 0))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},Ni=(0,_.lazy)(()=>Mi(()=>import(`./history-B_cN6LK7.js`),[],import.meta.url));function Pi({locale:e}){let t=tr(),n=nr(),[r,i]=(0,_.useState)(!1),a=![`ready`,`streaming`,`polling`].includes(t.connection),o=t.runtimeHistory.at(-1)?.receivedAt??null,s=a||o===null||t.lastUpdatedAt!==null&&t.lastUpdatedAt-o>4e3,c=t.selectedModelId===null?void 0:t.runtimes.get(t.selectedModelId);return(0,x.jsxs)(`div`,{className:`screen-stack`,"data-testid":`activity-page`,children:[(0,x.jsxs)(`section`,{className:`screen-heading`,children:[(0,x.jsx)(`h1`,{"data-testid":B(`activity.title`),children:z(e,`activity.title`)}),(0,x.jsx)(`p`,{children:z(e,`activity.intro`)}),(0,x.jsxs)(`p`,{children:[z(e,`activity.updated`),`: `,t.lastSuccessfulAt===null?z(e,`activity.pending`):(0,x.jsx)(`time`,{children:new Date(t.lastSuccessfulAt).toLocaleString(e)})]})]}),(0,x.jsx)(Ae,{locale:e,label:z(e,`activity.select`),value:t.selectedModelId??``,onChange:e=>n.selectModel(e||null),options:[{value:``,label:z(e,`activity.select`)},...t.catalog.map(e=>({value:e.identity.id,label:e.identity.display_name}))]}),(0,x.jsxs)(`div`,{className:`activity-toolbar`,children:[(0,x.jsx)(P,{onClick:()=>{n.refresh()},children:z(e,`activity.refresh`)}),(0,x.jsx)(P,{onClick:()=>Ci(t),children:z(e,`activity.export`)})]}),a?(0,x.jsx)(R,{tone:`warning`,title:z(e,`activity.stale`),body:z(e,`activity.refresh`)}):null,(0,x.jsx)(wi,{operations:t.operations,locale:e,stale:a}),t.selectedModelId===null?(0,x.jsx)(fe,{title:z(e,`activity.select`),body:z(e,`activity.select_body`)}):(0,x.jsx)(Oi,{runtime:c,locale:e,stale:s}),(0,x.jsx)(P,{onClick:()=>i(!r),children:r?z(e,`activity.history.hide`):z(e,`activity.history.show`)}),r?(0,x.jsx)(_.Suspense,{fallback:(0,x.jsx)(`p`,{children:z(e,`activity.pending`)}),children:(0,x.jsx)(Ni,{samples:t.runtimeHistory,locale:e})}):null]})}var Fi=e=>[`succeeded`,`failed`,`cancelled`].includes(e.state),Ii=e=>e.auth.status===`authenticated`&&e.bootstrap!==null&&e.catalogSequence!==null&&[`ready`,`streaming`,`polling`].includes(e.connection);function Li(e,t){return Ii(e)&&e.bootstrap?.actions[t]?.state===`enabled`}function Ri(e,t){return[...e.operations.values()].some(e=>!Fi(e)&&e.target.target_kind===`model`&&(e.target.model_id===t||e.target.eviction_target_id===t))||[...e.pendingReconciliations.values()].some(e=>e.modelId===t)}function zi(e,t){return Li(e,`load`)&&t.supported&&t.complete&&t.metadata.support.runnable_on_backend&&!t.lifecycle.busy&&[`unloaded`,`failed`].includes(t.lifecycle.state)&&!Ri(e,t.identity.id)}function Bi(e,t){return Li(e,`unload`)&&t.lifecycle.state===`ready`&&!Ri(e,t.identity.id)}function Vi(e,t){return Li(e,`cache_delete`)&&t.identity.source===`cache`&&t.removable&&t.removal.eligible&&!t.lifecycle.busy&&t.lifecycle.active_requests===0&&[`unloaded`,`failed`].includes(t.lifecycle.state)&&!Ri(e,t.identity.id)}function Hi(e,t){return Ii(e)&&t.lifecycle.state===`ready`&&t.capabilities.some(e=>e.task===`chat`&&e.phase===`provider_ready`&&e.available)}function Ui(e,t){return e.catalog.filter(n=>n.identity.id!==t&&Bi(e,n)&&!n.lifecycle.busy&&n.lifecycle.active_requests===0&&n.lifecycle.draining_requests===0)}function Wi(e,t){if(e===null)return z(t,`models.library.unknown`);if(e===0)return`0 B`;let n=Math.min(4,Math.floor(Math.log(e)/Math.log(1024)));return`${(e/1024**n).toLocaleString(t,{maximumFractionDigits:1})} ${[`B`,`KiB`,`MiB`,`GiB`,`TiB`][n]}`}function Gi(e,t){return e instanceof cn?e.envelope?.error.code===`stale_revision`?z(t,`models.library.stale`):e.message:z(t,`models.library.pending`)}function Ki(e,t){let n=t.query.trim().toLocaleLowerCase();return e.filter(e=>(!n||[e.identity.display_name,e.identity.inference_id,e.metadata.architecture??``].some(e=>e.toLocaleLowerCase().includes(n)))&&(!t.source||e.identity.source===t.source)&&(!t.task||e.capabilities.some(e=>e.task===t.task))&&(!t.status||e.lifecycle.state===t.status)).sort((e,n)=>{let r=e=>t.sort===`status`?e.lifecycle.state:t.sort===`source`?e.identity.source:t.sort===`task`?e.capabilities.map(e=>e.task).join(`,`):e.identity.display_name;return r(e).localeCompare(r(n))||e.identity.id.localeCompare(n.identity.id)})}function qi(e){let t=e.split(`/`);return t.length===2&&t.every(e=>e.length<=96&&/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(e))}function Ji(e){return e.length===0||e.length<=128&&e.split(`/`).every(e=>e!==`.`&&e!==`..`&&/^[A-Za-z0-9._~+-]+$/.test(e))}function Yi({value:e,state:t,locale:n,busy:r,onClose:i,onConfirm:a}){let[o,s]=(0,_.useState)(``),[c,l]=(0,_.useState)(),u=e.kind===`capacity`?Ui(t,e.entry.identity.id):[],d=e.kind===`cancel`?e.operation.target.target_kind===`download`?e.operation.target.repo_id:e.operation.operation_id:e.entry.identity.display_name,f=z(n,e.kind===`delete`?`models.library.delete`:e.kind===`unload`?`models.unload`:e.kind===`cancel`?`models.library.cancel_download`:`models.library.capacity`),p=e.kind===`capacity`?z(n,`models.library.capacity_body`):e.kind===`cancel`?z(n,`models.library.cancel_body`,{name:d}):z(n,e.kind===`delete`?`models.library.delete_body`:`models.library.unload_body`,{name:d,source:e.entry.identity.source,count:String(e.entry.lifecycle.active_requests)}),m=t.serverInstanceId===e.instance&&(e.kind===`cancel`||t.catalog.some(t=>t.identity.id===e.entry.identity.id&&t.identity.revision===e.entry.identity.revision)),h=m&&(e.kind===`delete`?o===e.entry.identity.id:e.kind!==`capacity`||u.some(e=>e.identity.id===o&&e.identity.revision===c));return(0,x.jsxs)(ct,{open:!0,title:f,onClose:i,closeLabel:z(n,`common.close`),testId:`models-confirm`,children:[(0,x.jsx)(`p`,{className:`models-wrap`,children:p}),e.kind===`delete`?(0,x.jsx)(`code`,{className:`models-wrap`,children:e.entry.identity.id}):null,e.kind===`capacity`&&o&&!h?(0,x.jsx)(`p`,{role:`alert`,children:z(n,`models.library.stale`)}):null,m?null:(0,x.jsx)(`p`,{role:`alert`,children:z(n,`models.library.stale`)}),e.kind===`delete`?(0,x.jsx)(at,{label:z(n,`models.library.confirm_name`),value:o,onChange:s,testId:`models-confirm-name`}):null,e.kind===`capacity`?(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(`ul`,{children:t.catalog.filter(e=>[`ready`,`loading`,`draining`,`unloading`].includes(e.lifecycle.state)).map(e=>(0,x.jsxs)(`li`,{className:`models-wrap`,children:[e.identity.display_name,` · `,e.lifecycle.state,` · `,z(n,`models.library.active`),`:`,` `,e.lifecycle.active_requests]},e.identity.id))}),(0,x.jsx)(Ae,{locale:n,label:z(n,`models.library.eviction`),value:o,onChange:e=>{s(e),l(u.find(t=>t.identity.id===e)?.identity.revision)},options:[{value:``,label:z(n,`models.library.choose`)},...u.map(e=>({value:e.identity.id,label:e.identity.display_name}))],testId:`models-eviction-target`})]}):null,(0,x.jsxs)(`div`,{className:`dialog-actions`,children:[(0,x.jsx)(P,{onClick:i,children:z(n,`models.library.cancel`)}),(0,x.jsx)(P,{tone:`danger`,"data-testid":`models-confirm-submit`,busy:r,disabled:!h||r,onClick:()=>a(e.kind===`capacity`?o:void 0,c),children:z(n,e.kind===`capacity`?`models.library.evict_load`:`models.library.confirm`)})]})]})}function Xi({locale:e,state:t,busy:n,onClose:r,onDownload:i,initial:a,error:o}){let[s,c]=(0,_.useState)(a?.repo??``),[l,u]=(0,_.useState)(a?.revision??``),[d,f]=(0,_.useState)(!1),p=qi(s.trim())&&Ji(l.trim());return(0,x.jsx)(ct,{open:!0,title:z(e,`models.library.add`),onClose:r,closeLabel:z(e,`common.close`),testId:`models-add-dialog`,children:(0,x.jsxs)(`form`,{onSubmit:e=>{e.preventDefault(),p&&d&&!n&&i(s.trim(),l.trim())},children:[o?(0,x.jsx)(`p`,{role:`alert`,children:o}):null,(0,x.jsx)(`p`,{children:z(e,`models.library.network`)}),(0,x.jsx)(`ul`,{children:t.bootstrap?.roots.filter(e=>e.kind===`cache`).map((e,t)=>(0,x.jsx)(`li`,{children:e.display_name},t))}),(0,x.jsx)(at,{label:z(e,`models.library.repo`),value:s,onChange:c,testId:`models-repo`,error:s&&!qi(s.trim())?z(e,`models.library.repo_invalid`):void 0}),(0,x.jsx)(at,{label:z(e,`models.library.revision`),value:l,onChange:u,testId:`models-revision`}),(0,x.jsxs)(`label`,{className:`toggle`,children:[(0,x.jsx)(`input`,{type:`checkbox`,checked:d,onChange:e=>f(e.currentTarget.checked),"data-testid":`models-public-repo`}),(0,x.jsx)(`span`,{children:z(e,`models.library.public`)})]}),(0,x.jsx)(`p`,{children:z(e,`models.library.private`)}),(0,x.jsx)(`pre`,{className:`models-wrap`,children:`hf download OWNER/REPO --local-dir /path/to/models/checkpoint`}),(0,x.jsxs)(`div`,{className:`dialog-actions`,children:[(0,x.jsx)(P,{onClick:r,children:z(e,`models.library.cancel`)}),(0,x.jsx)(P,{type:`submit`,tone:`primary`,busy:n,disabled:!p||!d||n,"data-testid":`models-download-submit`,children:z(e,`models.library.add`)})]})]})})}function Zi({locale:e}){return(0,x.jsxs)(`p`,{"data-testid":`models-pending-profile`,children:[z(e,`models.next_profile.body`),` `,(0,x.jsx)(`a`,{href:`#settings`,children:z(e,`models.next_profile.edit`)})]})}function Qi({entry:e,profile:t,state:n,locale:r,busy:i,onAction:a,onChat:o}){let s=e.metadata,c=n.runtimes.get(e.identity.id),l=c?.revision===e.identity.revision?c.settings.effective.ctx_size:null,u=e=>e==null?z(r,`models.library.unknown`):String(e),d=e=>z(r,e?`models.library.yes`:`models.library.no`),f=[[z(r,`models.library.source`),e.identity.source],[z(r,`models.library.architecture`),u(s.architecture)],[z(r,`models.library.backend`),d(s.support.runnable_on_backend)],[z(r,`models.library.tested`),d(s.support.tested_checkpoint)],[z(r,`models.library.disk`),Wi(s.disk_bytes,r)],[z(r,`models.library.memory`),Wi(s.memory_estimate_bytes,r)],[z(r,`models.library.context`),u(typeof l==`number`?l:null)],[z(r,`models.library.profile`),Object.keys(t).length?JSON.stringify(t):z(r,`models.library.defaults`)],[z(r,`models.library.active`),String(e.lifecycle.active_requests)],[z(r,`models.library.worker`),d(e.lifecycle.worker_exit_observed)]],p=[s.support.reason,s.support.architecturally_supported_reason,s.support.runnable_on_backend_reason,s.support.complete_reason,s.support.tested_checkpoint_reason,...Object.values(s.unknown_reasons),...e.capabilities.map(e=>e.reason)].filter(e=>!!e);return(0,x.jsxs)(ut,{title:z(r,`models.library.details`),children:[(0,x.jsx)(`h3`,{children:e.identity.display_name}),(0,x.jsx)(`code`,{className:`models-wrap`,children:e.identity.id}),(0,x.jsx)(ue,{state:e.lifecycle.state,children:Er(r,e.lifecycle.state)}),(0,x.jsx)(`dl`,{children:f.map(([e,t])=>(0,x.jsxs)(_.Fragment,{children:[(0,x.jsx)(`dt`,{children:e}),(0,x.jsx)(`dd`,{children:t})]},e))}),Object.keys(t).length?(0,x.jsx)(Zi,{locale:r}):null,(0,x.jsx)(`p`,{children:z(r,`models.library.tested_help`)}),[...new Set(p)].map(e=>(0,x.jsx)(`p`,{children:e},e)),e.lifecycle.last_error?(0,x.jsxs)(`p`,{role:`alert`,children:[z(r,`models.library.last_error`),`: `,e.lifecycle.last_error]}):null,(0,x.jsxs)(`div`,{className:`button-row`,children:[(0,x.jsx)(P,{"data-testid":`models-load`,disabled:i||!zi(n,e),onClick:()=>a(`load`),children:z(r,`models.load`)}),(0,x.jsx)(P,{"data-testid":`models-use-chat`,disabled:i||!Hi(n,e),onClick:o,children:z(r,`models.library.chat`)}),(0,x.jsx)(P,{"data-testid":`models-unload`,disabled:i||!Bi(n,e),onClick:()=>a(`unload`),children:z(r,`models.unload`)}),e.identity.source===`cache`?(0,x.jsx)(P,{tone:`danger`,"data-testid":`models-delete`,disabled:i||!Vi(n,e),onClick:()=>a(`delete`),children:z(r,`models.library.delete`)}):null]}),Hi(n,e)?null:(0,x.jsx)(`p`,{children:z(r,`models.library.chat_reason`)}),e.removal.eligible?null:(0,x.jsxs)(`p`,{children:[e.removal.reason,` `,e.removal.instructions]}),Object.entries(n.bootstrap?.actions??{}).filter(([,e])=>e.state!==`enabled`).map(([e,t])=>(0,x.jsxs)(`p`,{children:[e,`: `,t.reason,` `,t.instructions]},e)),(0,x.jsx)(`a`,{href:`https://github.com/lablup/mlxcel/blob/main/docs/llama-server-compat.md`,target:`_blank`,rel:`noreferrer`,children:z(r,`models.library.api`)}),(0,x.jsx)(`ul`,{children:e.capabilities.map(e=>(0,x.jsxs)(`li`,{children:[e.task,` · `,e.phase,` · `,d(e.available)]},`${e.task}-${e.phase}`))})]})}function $i({state:e,locale:t,busy:n,downloadPending:r,onCancel:i,onRetry:a,onCapacity:o}){let s=[...e.operations.values()].filter(e=>[`download`,`model_load`,`model_unload`,`model_removal`,`catalog_refresh`].includes(e.kind)).sort((e,t)=>Number(Fi(e))-Number(Fi(t))||t.created_at.localeCompare(e.created_at));return!s.length&&!e.pendingReconciliations.size?(0,x.jsx)(x.Fragment,{}):(0,x.jsxs)(`section`,{className:`models-operations`,"aria-label":z(t,`models.library.operations`),children:[(0,x.jsx)(`h2`,{children:z(t,`models.library.operations`)}),e.pendingReconciliations.size?(0,x.jsx)(`p`,{role:`status`,"data-testid":`models-pending`,children:z(t,`models.library.pending`)}):null,(0,x.jsx)(`ul`,{className:`ds-list`,children:s.slice(0,64).map(s=>(0,x.jsx)(`li`,{"data-testid":`models-operation`,children:(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`strong`,{children:ta(s,e)}),(0,x.jsxs)(`p`,{children:[(0,x.jsx)(`code`,{children:s.operation_id}),s.target.target_kind===`model`?(0,x.jsxs)(`span`,{children:[` `,`· `,(0,x.jsx)(`code`,{children:s.target.model_id})]}):null,` `,`· `,z(t,`models.library.operation_state`),`: `,s.state]}),s.kind===`download`?(0,x.jsx)(de,{label:z(t,`models.library.progress`),value:!s.progress.indeterminate&&s.progress.total_bytes!==null&&s.progress.total_bytes>0?s.progress.completed_bytes/s.progress.total_bytes*100:void 0,detail:`${Wi(s.progress.completed_bytes,t)} / ${Wi(s.progress.total_bytes,t)}`}):null,s.error?(0,x.jsxs)(`p`,{role:`alert`,children:[s.error.code,`: `,s.error.message]}):null,s.result&&`lifecycle`in s.result?(0,x.jsxs)(`p`,{children:[s.result.lifecycle.state,` · `,z(t,`models.library.worker`),`:`,` `,z(t,s.result.lifecycle.worker_exit_observed?`models.library.yes`:`models.library.no`)]}):null,s.cancel_reason?(0,x.jsx)(`p`,{children:s.cancel_reason}):null,(0,x.jsxs)(`div`,{className:`button-row`,children:[s.kind===`model_load`&&s.state===`failed`&&s.error?.code===`conflict`&&s.target.target_kind===`model`?(0,x.jsx)(P,{disabled:n||!e.catalog.some(t=>t.identity.id===ea(s)&&zi(e,t)),onClick:()=>o(ea(s)),children:z(t,`models.library.capacity`)}):null,s.kind===`download`&&!Fi(s)?(0,x.jsx)(P,{disabled:n||!Ii(e)||!s.cancellable||s.state===`cancelling`,onClick:()=>i(s),children:z(t,`models.library.cancel_download`)}):null,s.kind===`download`&&(s.state===`failed`||s.state===`cancelled`)?(0,x.jsx)(P,{disabled:n||r||!Li(e,`download`),onClick:()=>a(s),children:z(t,`models.library.retry_download`)}):null]})]})},s.operation_id))})]})}function ea(e){return e.target.target_kind===`model`?e.target.model_id:``}function ta(e,t){let n=e.target;return n.target_kind===`download`?n.repo_id:n.target_kind===`model`?t.catalog.find(e=>e.identity.id===n.model_id)?.identity.display_name??n.model_id:e.kind}var U=25;function na({locale:e}){let t=tr(),n=nr(),[r,i]=(0,_.useState)({query:``,source:``,task:``,status:``,sort:`name`}),[a,o]=(0,_.useState)(0),[s,c]=(0,_.useState)(!1),l=(0,_.useRef)(!1),[u,d]=(0,_.useState)(null),[f,p]=(0,_.useState)(null),[m,h]=(0,_.useState)(null),[g,v]=(0,_.useState)(`copy`),y=t.catalog.find(e=>e.identity.id===t.selectedModelId),{profile:b}=Vr(y?.identity.id??null),{profile:S}=Vr(f?.kind===`capacity`?f.entry.identity.id:null),C=Ki(t.catalog,r),w=Math.max(1,Math.ceil(C.length/U)),T=Math.min(a,w-1),E=[...t.operations.values()].some(e=>e.kind===`download`&&!Fi(e))||[...t.pendingReconciliations.values()].some(e=>e.kind===`download`),D=[...t.operations.values()].some(e=>e.kind===`catalog_refresh`&&!Fi(e))||[...t.pendingReconciliations.values()].some(e=>e.kind===`catalog-refresh`),O=e=>{i({...r,...e}),o(0)},k=async(n,r)=>{if(l.current||!Ii(t))return!1;l.current=!0,c(!0),d(null);try{return await n(),!0}catch(t){return d(Gi(t,e)),r?.(t),!1}finally{l.current=!1,c(!1)}},ee=(r,i,a=b)=>{if(!zi(t,r)){d(z(e,`models.library.stale`));return}if(i&&!Ui(t,r.identity.id).some(e=>e.identity.id===i.id&&e.identity.revision===i.revision)){d(z(e,`models.library.stale`));return}k(()=>n.loadModel({action:`load`,...Object.keys(a).length?{load_profile:{...a}}:{},model_id:r.identity.id,expected_revision:r.identity.revision,idempotency_key:crypto.randomUUID(),...i?{eviction_target_id:i.id,eviction_target_expected_revision:i.revision}:{}}),e=>{e instanceof cn&&e.envelope?.error.code===`conflict`&&p({kind:`capacity`,entry:r,instance:t.serverInstanceId})})},A=e=>{y&&(e===`load`?ee(y):p({kind:e,entry:y,instance:t.serverInstanceId}))},te=(r,i)=>{let a=f;if(a&&!l.current){if(a.instance!==t.serverInstanceId){d(z(e,`models.library.stale`)),p(null);return}if(a.kind===`cancel`){let e=t.operations.get(a.operation.operation_id);if(!e||!e.cancellable||Fi(e)||e.state===`cancelling`){p(null);return}k(()=>n.cancelOperation(e.operation_id))}else{let o=t.catalog.find(e=>e.identity.id===a.entry.identity.id);if(!o||o.identity.revision!==a.entry.identity.revision){d(z(e,`models.library.stale`)),p(null);return}if(a.kind===`capacity`){if(!Ui(t,o.identity.id).some(e=>e.identity.id===r&&e.identity.revision===i)){d(z(e,`models.library.stale`));return}ee(o,r&&i!==void 0?{id:r,revision:i}:void 0,S)}else a.kind===`unload`&&Bi(t,o)?k(()=>n.unloadModel({action:`unload`,model_id:o.identity.id,expected_revision:o.identity.revision,idempotency_key:crypto.randomUUID()})):a.kind===`delete`&&Vi(t,o)?k(()=>n.removeModel({model_id:o.identity.id,expected_revision:o.identity.revision,idempotency_key:crypto.randomUUID()})):d(z(e,`models.library.stale`))}p(null)}},ne=e=>{e.target.target_kind===`download`&&h({repo:e.target.repo_id,revision:e.target.revision??``})},j=`mlxcel-server --webui --models-dir /path/to/models --no-models-autoload`,M=[{id:`name`,header:z(e,`models.library.name`),noResize:!0,render:r=>(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(P,{tone:`ghost`,className:me,"aria-label":z(e,`models.library.inspect`,{name:r.identity.display_name}),onClick:()=>{r.identity.id!==t.selectedModelId&&n.selectModel(r.identity.id)},children:r.identity.display_name}),(0,x.jsxs)(`span`,{className:`models-row-meta`,children:[r.identity.id===t.selectedModelId?(0,x.jsx)(it,{tone:`accent`,children:z(e,`models.library.selected`)}):null,` `,(0,x.jsx)(it,{children:r.identity.source}),` `,(0,x.jsx)(it,{children:r.metadata.quantization??z(e,`models.library.unknown`)})]})]})},{id:`task`,header:z(e,`models.library.task`),noResize:!0,render:t=>t.capabilities.map(e=>e.task).filter((e,t,n)=>n.indexOf(e)===t).join(`, `)||z(e,`models.library.unknown`)},{id:`status`,header:z(e,`models.library.status`),noResize:!0,render:t=>(0,x.jsx)(ue,{state:t.lifecycle.state,children:Er(e,t.lifecycle.state)})},{id:`support`,header:z(e,`models.library.support`),noResize:!0,render:t=>(0,x.jsxs)(x.Fragment,{children:[z(e,t.metadata.support.architecturally_supported?`models.library.supported`:`models.library.unsupported`),(0,x.jsx)(`br`,{}),z(e,t.complete?`models.library.complete`:`models.library.incomplete`)]})}];return(0,x.jsxs)(`div`,{className:`screen-stack models-library`,"data-testid":`models-library`,children:[(0,x.jsxs)(`section`,{className:`screen-heading`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:z(e,`routes.models.eyebrow`)}),(0,x.jsx)(`h1`,{tabIndex:-1,"data-dialog-focus-fallback":!0,"data-testid":B(`models.title`),children:z(e,`models.title`)}),(0,x.jsx)(`p`,{children:z(e,`models.library.subtitle`)})]}),Ii(t)?null:(0,x.jsx)(R,{title:z(e,`models.library.stale`),body:t.error?.message??z(e,`models.library.waiting`),action:(0,x.jsx)(P,{onClick:()=>{n.refresh()},children:z(e,`models.library.refresh`)}),testId:`connection-error-title`}),u?(0,x.jsx)(R,{title:z(e,`models.library.error`),body:u,action:(0,x.jsx)(P,{onClick:()=>{d(null),n.refresh()},children:z(e,`models.library.refresh`)}),testId:`models-action-error`}):null,t.bootstrap?.server.mode===`single_model`?(0,x.jsx)(R,{tone:`info`,title:z(e,`models.library.single`),body:`mlxcel-server --webui`,testId:`models-read-only`}):null,(0,x.jsxs)(`div`,{className:`button-row`,children:[(0,x.jsx)(P,{tone:`primary`,onClick:()=>h({repo:``,revision:``}),disabled:s||E||!Li(t,`download`),"data-testid":`models-add`,children:z(e,`models.library.add`)}),(0,x.jsx)(P,{disabled:s||D||!Ii(t)||t.bootstrap?.server.mode===`single_model`,onClick:()=>{k(()=>n.refreshCatalog(crypto.randomUUID()))},"data-testid":`models-rescan`,children:z(e,`models.library.rescan`)}),(0,x.jsx)(P,{onClick:()=>{n.refresh()},disabled:s,children:z(e,`models.library.refresh`)})]}),Object.entries(t.bootstrap?.actions??{}).filter(([,e])=>e.state!==`enabled`).map(([e,t])=>(0,x.jsxs)(`p`,{children:[e,`: `,t.reason,` `,t.instructions]},e)),(0,x.jsx)(`p`,{"data-testid":`connection-authenticated-detail`,children:Sr(e,t)}),(0,x.jsxs)(`details`,{open:t.catalog.length===0,children:[(0,x.jsx)(`summary`,{children:z(e,`models.library.roots`)}),(0,x.jsx)(`ul`,{children:t.bootstrap?.roots.map((t,n)=>(0,x.jsxs)(`li`,{children:[(0,x.jsx)(`strong`,{children:t.display_name}),` · `,t.kind,t.error?(0,x.jsxs)(`p`,{role:`alert`,children:[z(e,`models.library.permission`),` `,t.error]}):null]},n))}),(0,x.jsx)(`p`,{children:z(e,`models.library.roots_help`)}),(0,x.jsx)(`pre`,{className:`models-wrap`,children:j}),(0,x.jsx)(P,{onClick:()=>{navigator.clipboard?.writeText(j).then(()=>v(`copied`)).catch(()=>v(`copy_failed`)),navigator.clipboard||v(`copy_failed`)},children:z(e,`models.library.${g}`)}),(0,x.jsx)(`span`,{role:`status`,children:g===`copy`?``:z(e,`models.library.${g}`)})]}),(0,x.jsxs)(`div`,{className:`models-toolbar`,children:[(0,x.jsx)(at,{label:z(e,`models.library.search`),value:r.query,onChange:e=>O({query:e}),testId:`models-search`}),(0,x.jsx)(Ae,{locale:e,label:z(e,`models.library.source`),value:r.source,onChange:e=>O({source:e}),options:[{value:``,label:z(e,`models.library.all`)},...[...new Set(t.catalog.map(e=>e.identity.source))].sort().map(e=>({value:e,label:e}))]}),(0,x.jsx)(Ae,{locale:e,label:z(e,`models.library.task`),value:r.task,onChange:e=>O({task:e}),options:[{value:``,label:z(e,`models.library.all`)},...[...new Set(t.catalog.flatMap(e=>e.capabilities.map(e=>e.task)))].sort().map(e=>({value:e,label:e}))]}),(0,x.jsx)(Ae,{locale:e,label:z(e,`models.library.status`),value:r.status,onChange:e=>O({status:e}),options:[{value:``,label:z(e,`models.library.all`)},...[`unloaded`,`loading`,`ready`,`draining`,`unloading`,`failed`].map(t=>({value:t,label:Er(e,t)}))]}),(0,x.jsx)(Ae,{locale:e,label:z(e,`models.library.sort`),value:r.sort,onChange:e=>O({sort:e}),options:[`name`,`status`,`source`,`task`].map(t=>({value:t,label:z(e,`models.library.sort_${t}`)}))})]}),(0,x.jsxs)(`div`,{className:`models-layout`,children:[(0,x.jsxs)(`section`,{children:[(0,x.jsx)(he,{columns:M,rows:C.slice(T*U,(T+1)*U),getRowKey:e=>e.identity.id,ariaLabel:z(e,`models.title`),testId:`models-table`,activateRowPrimary:!0,rowClassName:e=>e.identity.id===t.selectedModelId?`models-selected`:void 0,loading:t.catalogSequence===null,loadingState:(0,x.jsx)(be,{label:z(e,`models.library.waiting`)}),emptyState:(0,x.jsx)(fe,{title:z(e,t.catalog.length===0?`models.empty.title`:`models.library.filtered`),body:z(e,t.catalog.length===0?`models.empty.body`:`models.library.filtered_body`),testId:`models-empty`})}),(0,x.jsxs)(`nav`,{className:`models-pagination`,"aria-label":z(e,`models.title`),children:[(0,x.jsx)(P,{disabled:T===0,onClick:()=>o(T-1),children:z(e,`models.library.previous`)}),(0,x.jsx)(`span`,{role:`status`,children:z(e,`models.library.page`,{page:String(T+1),pages:String(w),count:String(C.length)})}),(0,x.jsx)(P,{disabled:T>=w-1,onClick:()=>o(T+1),children:z(e,`models.library.next`)})]})]}),y?(0,x.jsx)(Qi,{entry:y,profile:b,state:t,locale:e,busy:s,onAction:A,onChat:()=>{Hi(t,y)&&(n.selectModel(y.identity.id),window.location.hash=`chat`)}}):null]}),(0,x.jsx)($i,{state:t,locale:e,busy:s,downloadPending:E,onCancel:e=>p({kind:`cancel`,operation:e,instance:t.serverInstanceId}),onRetry:ne,onCapacity:e=>{let n=t.catalog.find(t=>t.identity.id===e);n&&zi(t,n)&&p({kind:`capacity`,entry:n,instance:t.serverInstanceId})}}),f?(0,x.jsx)(Yi,{value:f,state:t,locale:e,busy:s,onClose:()=>p(null),onConfirm:te},f.kind):null,m?(0,x.jsx)(Xi,{locale:e,state:t,initial:m,error:u,busy:s||E||!Li(t,`download`),onClose:()=>h(null),onDownload:(e,r)=>{Li(t,`download`)&&!E&&k(()=>n.downloadModel({repo_id:e,revision:r||null,idempotency_key:crypto.randomUUID()})).then(e=>{e&&h(null)})}}):null]})}var ra={en:`en-US`,ko:`ko-KR`},ia=e=>ra[e];function aa(e,t){if(!Number.isFinite(e)||e<0)return z(t,`format.unknown`);let n=[`B`,`KiB`,`MiB`,`GiB`,`TiB`],r=e,i=0;for(;r>=1024&&in(!0)})},{id:`states`,label:z(e.locale,`gallery.tab.states`),panel:(0,x.jsx)(la,{locale:e.locale})},{id:`data`,label:z(e.locale,`gallery.tab.data`),panel:(0,x.jsx)(ua,{locale:e.locale})}]}),(0,x.jsxs)(ct,{open:t,title:z(e.locale,`models.delete.confirm.title`),onClose:()=>n(!1),testId:`gallery-dialog`,closeLabel:z(e.locale,`common.close`),children:[(0,x.jsx)(`p`,{"data-testid":B(`models.delete.confirm.body`),children:z(e.locale,`models.delete.confirm.body`,{model:a})}),(0,x.jsx)(at,{label:z(e.locale,`models.delete.confirm.token_label`),value:``,placeholder:z(e.locale,`gallery.delete_token`)}),(0,x.jsxs)(`div`,{className:`dialog-actions`,children:[(0,x.jsx)(P,{onClick:()=>n(!1),children:z(e.locale,`common.cancel`)}),(0,x.jsx)(P,{tone:`danger`,children:z(e.locale,`common.delete`)})]})]})]})}function ca(e){return(0,x.jsxs)(`div`,{className:`gallery-grid`,children:[(0,x.jsxs)(Ue,{children:[(0,x.jsx)(`h2`,{children:z(e.locale,`gallery.controls.title`)}),(0,x.jsxs)(`div`,{className:`control-row`,children:[(0,x.jsx)(P,{tone:`primary`,children:z(e.locale,`gallery.controls.primary`)}),(0,x.jsx)(P,{children:z(e.locale,`gallery.controls.secondary`)}),(0,x.jsx)(P,{tone:`danger`,children:z(e.locale,`gallery.controls.danger`)}),(0,x.jsx)(P,{busy:!0,children:z(e.locale,`gallery.controls.busy`)})]}),(0,x.jsx)(at,{label:z(e.locale,`gallery.field.repo`),value:e.value,onChange:e.onValueChange,error:z(e.locale,`gallery.field.repo_error`),hint:z(e.locale,`gallery.field.repo_hint`),testId:`gallery-field`}),(0,x.jsx)(Ae,{locale:e.locale,label:z(e.locale,`gallery.select.native`),value:e.selectValue,onChange:e.onSelectChange,options:[{value:`ready`,label:z(e.locale,`models.status.ready`)},{value:`unloaded`,label:z(e.locale,`models.status.unloaded`)}]})]}),(0,x.jsxs)(Ue,{children:[(0,x.jsx)(`h2`,{children:z(e.locale,`gallery.overlays.title`)}),(0,x.jsx)(`p`,{children:z(e.locale,`gallery.long_cjk`)}),(0,x.jsxs)(`div`,{className:`control-row`,children:[(0,x.jsx)(Le,{content:z(e.locale,`gallery.tooltip`),children:(0,x.jsx)(P,{children:z(e.locale,`gallery.hover_focus`)})}),(0,x.jsx)(P,{tone:`primary`,onClick:e.onOpenDialog,children:z(e.locale,`gallery.dialog.open`)})]})]})]})}function la(e){return(0,x.jsxs)(`div`,{className:`gallery-grid`,children:[(0,x.jsx)(pt,{title:z(e.locale,`state.unauthorized.title`),body:z(e.locale,`state.unauthorized.body`),tokenLabel:z(e.locale,`login.token.label`),tokenHelp:z(e.locale,`login.token.help`),submitLabel:z(e.locale,`login.submit`),logoutLabel:z(e.locale,`login.logout`),onSubmit:()=>void 0,onLogout:()=>void 0,testId:`gallery-login`}),(0,x.jsx)(mt,{title:z(e.locale,`state.schema_mismatch.title`),body:z(e.locale,`state.schema_mismatch.body`),actionLabel:z(e.locale,`common.reload`),onRecover:()=>void 0}),(0,x.jsx)(fe,{title:z(e.locale,`models.empty.title`),body:z(e.locale,`models.empty.body`),action:(0,x.jsx)(P,{tone:`primary`,children:z(e.locale,`common.add_model`)}),testId:`gallery-empty`}),(0,x.jsx)(R,{tone:`warning`,title:z(e.locale,`gallery.states.load_failed`),body:z(e.locale,`gallery.states.load_failed_body`),action:(0,x.jsx)(P,{children:z(e.locale,`common.retry`)})}),(0,x.jsxs)(`div`,{className:`gallery-progress-samples`,children:[(0,x.jsx)(de,{label:z(e.locale,`gallery.download`),detail:z(e.locale,`activity.progress.indeterminate`,{bytes:aa(67108864,e.locale)})}),(0,x.jsx)(de,{label:z(e.locale,`gallery.progress.measured`),value:37})]}),(0,x.jsxs)(ft,{label:z(e.locale,`gallery.lifecycle.samples`),children:[(0,x.jsx)(`li`,{children:(0,x.jsx)(ue,{state:`loading`,children:z(e.locale,`models.status.loading`)})}),(0,x.jsx)(`li`,{children:(0,x.jsx)(ue,{state:`draining`,children:z(e.locale,`models.status.draining`)})}),(0,x.jsx)(`li`,{children:(0,x.jsx)(ue,{state:`unloading`,children:z(e.locale,`models.status.unloading`)})})]})]})}function ua(e){return(0,x.jsxs)(`div`,{className:`gallery-grid dense-gallery`,children:[(0,x.jsxs)(Ue,{className:`table-card`,role:`region`,tabIndex:0,ariaLabel:z(e.locale,`gallery.sample.caption`),children:[(0,x.jsx)(`h2`,{children:z(e.locale,`gallery.data.title`)}),(0,x.jsxs)(dt,{caption:z(e.locale,`gallery.sample.caption`),children:[(0,x.jsx)(`thead`,{children:(0,x.jsxs)(`tr`,{children:[(0,x.jsx)(`th`,{children:z(e.locale,`gallery.data.name`)}),(0,x.jsx)(`th`,{children:z(e.locale,`gallery.data.status`)}),(0,x.jsx)(`th`,{children:z(e.locale,`gallery.data.rate`)})]})}),(0,x.jsxs)(`tbody`,{children:[(0,x.jsxs)(`tr`,{children:[(0,x.jsx)(`td`,{children:(0,x.jsx)(`span`,{className:`truncate`,title:z(e.locale,`models.long_name`),"aria-label":z(e.locale,`models.long_name`),children:z(e.locale,`models.long_name`)})}),(0,x.jsx)(`td`,{children:(0,x.jsx)(ue,{state:`ready`,children:z(e.locale,`models.status.ready`)})}),(0,x.jsx)(`td`,{children:oa(39.4,e.locale)})]}),(0,x.jsxs)(`tr`,{children:[(0,x.jsx)(`td`,{children:(0,x.jsx)(`span`,{className:`truncate`,title:`granite-4.0-h-tiny-4bit`,"aria-label":`granite-4.0-h-tiny-4bit`,children:`granite-4.0-h-tiny-4bit`})}),(0,x.jsx)(`td`,{children:(0,x.jsx)(ue,{state:`unloaded`,children:z(e.locale,`models.status.unloaded`)})}),(0,x.jsx)(`td`,{children:oa(null,e.locale)})]})]})]})]}),(0,x.jsxs)(ut,{title:z(e.locale,`gallery.data.inspector`),children:[(0,x.jsx)(`p`,{className:`sample-label`,children:z(e.locale,`gallery.sample.label`)}),(0,x.jsx)(`p`,{children:z(e.locale,`models.unsupported.reason`)}),(0,x.jsx)(ue,{state:`failed`,children:z(e.locale,`models.status.failed`)}),(0,x.jsx)(`hr`,{}),(0,x.jsx)(`p`,{children:z(e.locale,`gallery.sample.reasoning_body`)}),(0,x.jsx)(`code`,{children:z(e.locale,`gallery.sample.tool_preview`)})]})]})}var da={count:4,bytes:8388608,dimension:4096,pixels:16e6},fa=new Set([`image/png`,`image/jpeg`,`image/webp`]);function pa(e,t){let n=new DataView(e.buffer,e.byteOffset,e.byteLength),r=(t,n)=>String.fromCharCode(...e.subarray(t,t+n));if(t===`image/png`&&e.length>=33&&e[0]===137&&r(1,7)===`PNG\r - -`&&n.getUint32(8)===13&&r(12,4)===`IHDR`)return[n.getUint32(16),n.getUint32(20)];if(t===`image/jpeg`&&e.length>=4&&e[0]===255&&e[1]===216){let t=2;for(;t+4<=e.length&&e[t++]===255;){for(;e[t]===255;)t++;let r=e[t++];if(r===217||r===218)break;if(r===1||r>=208&&r<=215)continue;if(t+2>e.length)break;let i=n.getUint16(t);if(i<2||t+i>e.length)break;if([192,193,194,195,197,198,199,201,202,203,205,206,207].includes(r)&&i>=8)return[n.getUint16(t+5),n.getUint16(t+3)];t+=i}}if(t===`image/webp`&&e.length>=25&&r(0,4)===`RIFF`&&r(8,4)===`WEBP`&&n.getUint32(4,!0)+8===e.length){let t=r(12,4),i=n.getUint32(16,!0);if(i<5||20+i>e.length)throw Error(`Invalid WebP chunk length.`);let a=t=>e[t]|e[t+1]<<8|e[t+2]<<16;if(t===`VP8X`&&e.length>=30&&n.getUint32(16,!0)>=10&&!(e[20]&2))return[a(24)+1,a(27)+1];if(t===`VP8 `&&e.length>=30&&e[23]===157&&e[24]===1&&e[25]===42)return[n.getUint16(26,!0)&16383,n.getUint16(28,!0)&16383];if(t===`VP8L`&&e[20]===47){let e=n.getUint32(21,!0);return[(e&16383)+1,(e>>>14&16383)+1]}}throw Error(`Image content does not match a supported PNG, JPEG or non-animated WebP image.`)}function ma(e){return new Promise((t,n)=>{let r=new FileReader;r.onerror=()=>n(Error(`Could not read the selected image.`)),r.onabort=()=>n(Error(`Image reading was cancelled.`)),r.onload=()=>r.result instanceof ArrayBuffer?t(new Uint8Array(r.result)):n(Error(`Invalid image data.`)),r.readAsArrayBuffer(e)})}function ha(e){if(!e||[e.max_images,e.max_image_bytes,e.max_width,e.max_height,e.max_decoded_bytes,e.max_body_bytes].some(e=>!Number.isSafeInteger(e)||e<=0))throw Error(`Image limits are unavailable.`)}function ga(e,t,n){if(!e||!t||e>Math.min(da.dimension,n.max_width)||t>Math.min(da.dimension,n.max_height)||e*t>da.pixels||e*t*4>n.max_decoded_bytes)throw Error(`Image dimensions exceed the server or browser decode budget.`)}function _a(e,t){if(e.length===0){if(!t||!Number.isSafeInteger(t.max_body_bytes)||t.max_body_bytes<=0)throw Error(`Request body limit is unavailable.`);return}if(ha(t),e.length>t.max_images)throw Error(`Conversation images exceed the server image count limit.`);let n=0,r=Math.min(da.bytes,t.max_image_bytes);for(let i of e){if(!i||!fa.has(i.type)||typeof i.dataUrl!=`string`)throw Error(`Invalid local image attachment.`);if(n+=i.dataUrl.length,n>t.max_body_bytes)throw Error(`Images exceed the server request body limit.`);let e=`data:${i.type};base64,`;if(!i.dataUrl.startsWith(e))throw Error(`Invalid image data URL.`);if(i.dataUrl.length-e.length>4*Math.ceil(r/3))throw Error(`Image exceeds the current server or browser byte limit.`)}for(let n of e){let e=n.dataUrl.slice(`data:${n.type};base64,`.length);if(!e||e.length%4!=0||!/^[A-Za-z0-9+/]*={0,2}$/.test(e))throw Error(`Invalid image base64 encoding.`);let i=atob(e);if(btoa(i)!==e)throw Error(`Image base64 encoding must be canonical.`);if(!i.length||i.length>r)throw Error(`Image exceeds the current server or browser byte limit.`);let a=new Uint8Array(i.length);for(let e=0;ei||t!==r.length)throw Error(`Attach at most ${i} images per message; existing attachment count must match.`);for(let e of o){if(!(e instanceof File)||!fa.has(e.type))throw Error(`Choose local PNG, JPEG or WebP image files.`);if(!e.size||e.size>a)throw Error(`Each image must be nonempty and no larger than ${a} bytes.`)}if(r.reduce((e,t)=>e+t.dataUrl.length,0)+o.reduce((e,t)=>e+4*Math.ceil(t.size/3)+`data:${t.type};base64,`.length,0)>n.max_body_bytes)throw Error(`Images exceed the server request body limit.`);let s=[];for(let e of o){let t=await ma(e),[r,i]=pa(t,e.type);if(ga(r,i,n),typeof createImageBitmap==`function`){let t;try{t=await createImageBitmap(e,{imageOrientation:`none`})}catch{throw Error(`The image could not be decoded.`)}try{if(t.width!==r||t.height!==i)throw Error(`Decoded image dimensions do not match its header.`)}finally{t.close()}}let a=``;for(let e=0;e{if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Malformed chat stream.`);return e};function xa(e){if(e==null)return``;if(typeof e!=`string`)throw Error(`Malformed text delta.`);return e}function Sa(e){if(typeof e!=`number`||!Number.isSafeInteger(e)||e<0)throw Error(`Malformed usage.`);return e}function Ca(e,t,n){if(t.length>256e3)throw Error(`Chat frame exceeds the display limit.`);let r=ba(JSON.parse(t));if(r.error!==void 0)throw Error(`The server reported a generation error. No automatic retry was made.`);let i={...e};if(r.usage!==void 0&&r.usage!==null){let e=ba(r.usage);i={...i,usage:{prompt_tokens:Sa(e.prompt_tokens),completion_tokens:Sa(e.completion_tokens),total_tokens:Sa(e.total_tokens)}}}if(!Array.isArray(r.choices)||r.choices.length>1)throw Error(`Malformed chat choices.`);for(let e of r.choices){let t=ba(e);if(t.index!==0)throw Error(`Unexpected chat choice index.`);let r=ba(t.delta),a=xa(r.content),o=xa(r.reasoning_content??r.reasoning),s=i.tools.map(e=>({...e}));if(r.tool_calls!==void 0&&r.tool_calls!==null){if(!Array.isArray(r.tool_calls)||r.tool_calls.length>32)throw Error(`Too many tool calls.`);for(let e of r.tool_calls){let t=ba(e),n=Sa(t.index);if(n>=32)throw Error(`Tool index exceeds the display limit.`);let r=t.function===void 0?{}:ba(t.function),i=s.find(e=>e.index===n)??{index:n,id:``,name:``,arguments:``},a={index:n,id:i.id+xa(t.id),name:i.name+xa(r.name),arguments:i.arguments+xa(r.arguments)};s=[...s.filter(e=>e.index!==n),a].sort((e,t)=>e.index-t.index)}}let c=a.length>0||o.length>0||s.length>0;if(i={...i,content:i.content+a,reasoning:i.reasoning+o,tools:s,ttftMs:i.ttftMs??(c?n:null)},t.finish_reason!==null&&t.finish_reason!==void 0){let e=xa(t.finish_reason);if(e.length>64)throw Error(`Invalid finish reason.`);i={...i,finishReason:e}}}if(i.content.length+i.reasoning.length+JSON.stringify(i.tools).length>256e3)throw Error(`Response exceeds the bounded display limit; generation stopped.`);return i}function wa(e,t){if(e.finishReason===null||!e.content&&!e.reasoning&&e.tools.length===0)throw Error(`The server returned an empty or unfinished response.`);return{...e,status:`complete`,elapsedMs:t}}function Ta(e,t){let n=e?[{role:`system`,content:e}]:[];for(let e of t)n.push({role:`user`,content:e.images.length?[{type:`text`,text:e.prompt},...e.images.map(e=>({type:`image_url`,image_url:{url:e.dataUrl}}))]:e.prompt}),e.status===`complete`&&e.content&&n.push({role:`assistant`,content:e.content});return n}function Ea(e){return e.usage===null||e.ttftMs===null||e.elapsedMs===null||e.elapsedMs<=e.ttftMs||e.usage.completion_tokens<=1?null:(e.usage.completion_tokens-1)*1e3/(e.elapsedMs-e.ttftMs)}var Da=Object.freeze({conversations:50,turnsPerConversation:200,totalTurns:1e3,textCharacters:262144,jsonBytes:16777216,imageBytes:8388608,imagesPerTurn:8,toolsPerTurn:128}),Oa=`mlxcel.webui.chat.v1`,ka=`history`,Aa=`conversations`,ja=1,Ma=new Set([`temperature`,`top_p`,`top_k`,`min_p`,`max_tokens`,`seed`,`repetition_penalty`,`presence_penalty`,`frequency_penalty`]),Na=class extends Error{constructor(e=`Conversation history is invalid or exceeds the local history limits.`){super(e),this.name=`HistoryValidationError`}},Pa=class extends Error{constructor(e,t){super(e,t),this.name=`HistoryStorageError`}};function Fa(){throw new Na}function Ia(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return Fa();let n=Object.getPrototypeOf(e);if(n!==Object.prototype&&n!==null)return Fa();let r=Object.keys(e);return r.length!==t.length||r.some(e=>!t.includes(e))?Fa():e}function La(e,t=Da.textCharacters){return typeof e!=`string`||e.length>t?Fa():e}function Ra(e){let t=La(e,512);return!t||Array.from(t).some(e=>e.charCodeAt(0)<32||e.charCodeAt(0)===127)?Fa():t}function za(e,t=!1){return typeof e!=`number`||!Number.isFinite(e)||e<0||t&&!Number.isSafeInteger(e)?Fa():e}function Ba(e,t){return e===null?null:t(e)}function Va(e,t){return!Array.isArray(e)||e.length>t?Fa():e}function Ha(e){return new TextEncoder().encode(e).byteLength}function Ua(e,t){let n=0,r=0,i=0,a=new Set;return Va(e,Da.conversations).map(e=>{let o=Ia(e,[`id`,`title`,`systemPrompt`,`turns`,`updatedAt`]),s=Ra(o.id);if(a.has(s))return Fa();a.add(s);let c=new Set,l=Va(o.turns,Da.turnsPerConversation).map(e=>{if(++n>Da.totalTurns)return Fa();let a=Ia(e,[`id`,`modelId`,`modelRevision`,`inferenceId`,`modelName`,`prompt`,`content`,`reasoning`,`tools`,`status`,`finishReason`,`usage`,`ttftMs`,`elapsedMs`,`error`,`parameters`,`images`]),o=Ra(a.id);if(c.has(o))return Fa();c.add(o);let s=La(a.status,32);if(![`streaming`,`complete`,`cancelled`,`interrupted`,`error`].includes(s))return Fa();let l={};if(!a.parameters||typeof a.parameters!=`object`||Array.isArray(a.parameters)||![Object.prototype,null].includes(Object.getPrototypeOf(a.parameters)))return Fa();for(let[e,t]of Object.entries(a.parameters)){if(!Ma.has(e)||typeof t!=`number`||!Number.isFinite(t))return Fa();l[e]=t}let u=new Set,d=Va(a.tools,Da.toolsPerTurn).map(e=>{let t=Ia(e,[`index`,`id`,`name`,`arguments`]),n=za(t.index,!0);return u.has(n)?Fa():(u.add(n),{index:n,id:La(t.id,512),name:La(t.name,512),arguments:La(t.arguments)})}),f=Va(a.images,Da.imagesPerTurn).map(e=>{let t=Ia(e,[`name`,`type`,`dataUrl`]),n=La(t.type,64);if(![`image/png`,`image/jpeg`,`image/webp`].includes(n))return Fa();let i=La(t.dataUrl,Da.imageBytes*2),a=`data:${n};base64,`;if(!i.startsWith(a))return Fa();let o=i.slice(a.length);return!o||o.length%4!=0||!/^[A-Za-z0-9+/]*={0,2}$/u.test(o)||(r+=o.length*3/4-(o.endsWith(`==`)?2:+!!o.endsWith(`=`)),r>Da.imageBytes)?Fa():{name:La(t.name,512),type:n,dataUrl:i}}),p={id:o,modelId:Ra(a.modelId),modelRevision:za(a.modelRevision,!0),inferenceId:Ra(a.inferenceId),modelName:La(a.modelName,512),prompt:La(a.prompt),content:La(a.content),reasoning:La(a.reasoning),tools:d,status:s===`streaming`?`interrupted`:s,finishReason:Ba(a.finishReason,La),usage:Ba(a.usage,e=>{let t=Ia(e,[`prompt_tokens`,`completion_tokens`,`total_tokens`]);return{prompt_tokens:za(t.prompt_tokens,!0),completion_tokens:za(t.completion_tokens,!0),total_tokens:za(t.total_tokens,!0)}}),ttftMs:Ba(a.ttftMs,za),elapsedMs:Ba(a.elapsedMs,za),error:Ba(a.error,La),parameters:l,images:t.includeImages?f:[]};return p.status===`complete`&&(!p.finishReason||!p.content&&!p.reasoning&&!p.tools.length)||(i+=Ha(JSON.stringify(p)),i>Da.jsonBytes)?Fa():p});return{id:s,title:La(o.title,512),systemPrompt:La(o.systemPrompt),turns:l,updatedAt:za(o.updatedAt,!0)}})}function Wa(e,t={}){let n=Ua(e,t);return Ha(JSON.stringify(n))>Da.jsonBytes?Fa():n}function Ga(e,t={}){let n=JSON.stringify({version:ja,conversations:Wa(e,t)});return Ha(n)>Da.jsonBytes?Fa():n}function Ka(e,t={}){if(Ha(e)>Da.jsonBytes)return Fa();let n;try{n=JSON.parse(e)}catch{return Fa()}let r=Ia(n,[`version`,`conversations`]);return r.version===ja?Wa(r.conversations,t):Fa()}function qa(e){return new Pa(e instanceof DOMException&&e.name===`QuotaExceededError`?`Local history storage is full. Export or clear history, or disable persistence; the current conversation remains in memory.`:`Local history storage is unavailable. The current conversation remains in memory.`,{cause:e})}function Ja(e={}){let t=!1,n=!1,r=0,i,a,o=new Set,s=()=>{let t=e.indexedDB??globalThis.indexedDB;if(!t)throw new Pa(`This browser does not support local history storage.`);return t},c=()=>{r++;for(let e of o)try{e.abort()}catch{}o.clear(),i?.close(),i=void 0,a=void 0},l=()=>{if(i)return Promise.resolve(i);if(a)return a;let e=r;return a=new Promise((n,a)=>{let o=s().open(Oa,ja);o.onupgradeneeded=()=>{o.result.objectStoreNames.contains(ka)||o.result.createObjectStore(ka)},o.onerror=()=>a(qa(o.error));let l=!1;o.onblocked=()=>{l=!0,a(new Pa(`Close other WebUI tabs to access local history.`))},o.onsuccess=()=>{if(l||!t||e!==r){o.result.close(),a(new Pa(`Local history persistence was disabled.`));return}i=o.result,i.onversionchange=c,n(i)}}),a.catch(t=>{throw e===r&&(a=void 0),t})};async function u(e,i){if(!t||n)return;let a=r;try{let s=await l();return!t||n||r!==a?void 0:await new Promise((t,n)=>{let r=s.transaction(ka,e);o.add(r);let a=i(r.objectStore(ka));r.oncomplete=()=>{o.delete(r),t(a.result)},r.onabort=r.onerror=()=>{o.delete(r),n(qa(r.error??a.error))}})}catch(e){throw e instanceof Pa?e:qa(e)}}return{setEnabled(e){t!==e&&(t=e,e||c())},async load(e={}){let t=await u(`readonly`,e=>e.get(Aa));return t===void 0?[]:Ka(La(t,Da.jsonBytes),e)},async save(e,n={}){if(!t)return;let r=Ga(e,n);await u(`readwrite`,e=>e.put(r,Aa))},async clear(){if(n)throw new Pa(`Local history is already being cleared.`);n=!0;let e=!1;c();try{await new Promise((t,r)=>{let i=s().deleteDatabase(Oa);i.onsuccess=()=>{n=!1,t()},i.onerror=()=>{n=!1,r(qa(i.error))},i.onblocked=()=>{e=!0,r(new Pa(`Close other WebUI tabs to clear local history.`))}})}catch(t){throw e||(n=!1),t instanceof Pa?t:qa(t)}},close:c}}var Ya=[],Xa=0,Za=new Set;function Qa(){return Xa}function $a(e){return{id:crypto.randomUUID(),title:e,systemPrompt:``,turns:[],updatedAt:Date.now()}}var eo=new WeakMap;function to(e){let t=eo.get(e);if(t!==void 0)return t;let n=new TextEncoder().encode(JSON.stringify(e)).byteLength;return eo.set(e,n),n}function no(e){return e.length>Da.conversations||e.reduce((e,t)=>e+t.turns.length,0)>Da.totalTurns?!1:2+Math.max(0,e.length-1)+e.reduce((e,t)=>e+new TextEncoder().encode(JSON.stringify({...t,turns:[]})).byteLength+t.turns.reduce((e,t)=>e+to(t),0)+Math.max(0,t.turns.length-1),0)<=Da.jsonBytes}function ro(e){Ya=e;for(let e of Za)e()}function io(e){if(!no(e))throw Error(`Conversation memory limit exceeded.`);Xa++,ro(e)}function ao(e){let t=Ya.some(t=>t.id===e.id)?Ya.map(t=>t.id===e.id?e:t):[...Ya,e];return no(t)?(ro(t),!0):!1}function oo(){return(0,_.useSyncExternalStore)(e=>(Za.add(e),()=>Za.delete(e)),()=>Ya)}var so=(0,_.lazy)(()=>Mi(()=>import(`./code-highlight-B24EZUmw.js`),[],import.meta.url)),co=65536,lo=512;function uo(e){let t=[];for(let n=0;nvoid a(),children:r})]}),(0,x.jsx)(`pre`,{children:n?(0,x.jsx)(_.Suspense,{fallback:(0,x.jsx)(`code`,{children:e}),children:(0,x.jsx)(so,{code:e,language:t})}):(0,x.jsx)(`code`,{children:e})})]})}),mo=(0,_.memo)(function({text:e,streaming:t=!1}){let n=e.slice(0,co).split(` -`),r=[],i=0;for(;i=s[1].length&&[...t].every(e=>e===s[1][0])){c=!0;break}o.push(e)}r.push((0,x.jsx)(po,{code:o.join(` -`),language:s[2].slice(0,40),complete:c||!t&&e.length<=co},a))}else if(/^#{1,6} /.test(o))r.push((0,x.jsx)(`p`,{className:`chat-markdown-heading`,children:(0,x.jsx)(`strong`,{children:uo(o.replace(/^#{1,6} /,``))})},a));else if(/^[-*] /.test(o)){let e=[o.slice(2)];for(;i(0,x.jsx)(`li`,{children:uo(e)},t))},a))}else o.trim()&&r.push((0,x.jsx)(`p`,{children:uo(o)},a))}return(0,x.jsxs)(`div`,{className:`chat-markdown`,children:[r,(e.length>co||i0?(0,x.jsx)(`p`,{children:z(i,`chat.transcript.images`,{count:String(e.images.length)})}):null,(0,x.jsx)(P,{disabled:r,onClick:()=>n(t),children:z(i,`chat.transcript.edit`)}),e.reasoning?(0,x.jsxs)(`details`,{children:[(0,x.jsx)(`summary`,{children:e.status===`streaming`&&!e.content?z(i,`chat.transcript.reasoning_thinking`):z(i,`chat.reasoning`)}),(0,x.jsx)(`pre`,{children:e.reasoning})]}):null,e.status===`streaming`&&!e.content?(0,x.jsx)(`p`,{children:e.reasoning?z(i,`chat.transcript.thinking`):z(i,`chat.transcript.waiting`)}):null,(0,x.jsx)(mo,{text:e.content,streaming:e.status===`streaming`}),e.tools.map(e=>(0,x.jsxs)(`details`,{children:[(0,x.jsx)(`summary`,{children:z(i,`chat.transcript.tool_call`,{name:e.name||z(i,`chat.transcript.tool_name_pending`)})}),(0,x.jsx)(`pre`,{children:e.arguments})]},e.index)),e.error?(0,x.jsx)(`p`,{role:`alert`,children:e.error}):null,(0,x.jsxs)(`div`,{className:`chat-toolbar`,children:[(0,x.jsx)(P,{onClick:()=>{(async()=>{try{await navigator.clipboard.writeText(e.content),o(`chat.transcript.copied`)}catch{o(`chat.transcript.copy_failed`)}})()},children:z(i,`chat.transcript.copy`)}),(0,x.jsx)(`span`,{role:`status`,children:a===null?``:z(i,a)})]}),(0,x.jsxs)(`details`,{children:[(0,x.jsx)(`summary`,{children:z(i,`chat.transcript.details`)}),(0,x.jsxs)(`dl`,{className:`chat-metrics`,children:[(0,x.jsx)(`dt`,{children:z(i,`chat.transcript.finish_reason`)}),(0,x.jsx)(`dd`,{children:e.finishReason??c}),(0,x.jsx)(`dt`,{children:z(i,`chat.transcript.usage`)}),(0,x.jsx)(`dd`,{children:e.usage?z(i,`chat.transcript.usage_value`,{prompt:String(e.usage.prompt_tokens),completion:String(e.usage.completion_tokens),total:String(e.usage.total_tokens)}):c}),(0,x.jsx)(`dt`,{children:z(i,`chat.transcript.first_delta`)}),(0,x.jsx)(`dd`,{children:e.ttftMs===null?c:`${Math.round(e.ttftMs)} ms`}),(0,x.jsx)(`dt`,{children:z(i,`chat.transcript.decode_rate`)}),(0,x.jsx)(`dd`,{children:s===null?c:`${s.toFixed(1)} tokens/s`})]}),(0,x.jsx)(`p`,{children:z(i,`chat.transcript.metrics_note`)}),(0,x.jsx)(`pre`,{children:JSON.stringify(e.parameters,null,2)})]})]})});function _o({turns:e,onEdit:t,busy:n,locale:r}){let i=(0,_.useRef)(t);i.current=t;let a=(0,_.useCallback)(e=>i.current(e),[]),o=(0,_.useRef)(null),s=(0,_.useRef)(!0),[c,l]=(0,_.useState)(!1),u=e.at(-1);return(0,_.useEffect)(()=>{s.current&&o.current&&window.getSelection()?.isCollapsed!==!1&&(o.current.scrollTop=o.current.scrollHeight)},[u?.content,u?.reasoning,e.length]),(0,x.jsxs)(`section`,{"aria-label":z(r,`chat.transcript.label`),children:[(0,x.jsx)(`div`,{className:`chat-transcript`,ref:o,tabIndex:0,onScroll:()=>{let e=o.current;e&&(s.current=e.scrollHeight-e.scrollTop-e.clientHeight<80,l(!s.current))},children:e.length?e.map((e,t)=>(0,x.jsx)(go,{turn:e,index:t,busy:n,locale:r,onEdit:a},e.id)):(0,x.jsx)(`p`,{children:z(r,`chat.transcript.empty`)})}),c?(0,x.jsx)(P,{onClick:()=>{s.current=!0,o.current&&(o.current.scrollTop=o.current.scrollHeight),l(!1)},children:z(r,`chat.transcript.jump`)}):null]})}function vo({conversations:e,busy:t,onPending:n,limits:r,onReplace:i,locale:a}){let o=(0,_.useRef)(Ja()),[s,c]=(0,_.useState)(!1),l=(0,_.useRef)(t);l.current=t;let u=e=>{c(e),n(e)},[d,f]=(0,_.useState)(!1),[p,m]=(0,_.useState)(!1),[h,g]=(0,_.useState)(null),[v,y]=(0,_.useState)(null),b=(0,_.useRef)(null),S=e=>{b.current=e,y(e)},C=(0,_.useRef)(null),w=(0,_.useRef)(0);(0,_.useEffect)(()=>{if(!d)return;let t=setTimeout(()=>{o.current.save(e,{includeImages:p}).catch(()=>g(`chat.privacy.save_failed`))},300);return()=>clearTimeout(t)},[e,d,p]),(0,_.useEffect)(()=>{let e=o.current;return()=>{w.current++,e.close(),n(!1)}},[]);let T=async(t,n)=>{let a=++w.current;if(o.current.setEnabled(t),!t){f(!1);return}u(!0);try{let t=await o.current.load({includeImages:p});if(await yo(t,r),a!==w.current||l.current)return;if(t.length&&e.length){S({kind:`replace-saved`,saved:t,operation:a,trigger:n});return}t.length&&i(t),f(!0)}catch{o.current.setEnabled(!1),a===w.current&&g(`chat.privacy.open_failed`)}finally{a===w.current&&u(!1)}},E=()=>{let e=++w.current;u(!0),f(!1),m(!1),o.current.setEnabled(!1),o.current.clear().then(()=>{e===w.current&&!l.current&&(i([]),g(`chat.privacy.cleared`))}).catch(()=>{e===w.current&&g(`chat.privacy.clear_failed`)}).finally(()=>{e===w.current&&(u(!1),window.setTimeout(()=>{document.activeElement===document.body&&C.current?.focus()},0))})},D=e=>{let t=b.current;if(b.current=null,y(null),t===null)return;if(t.kind===`clear`){e&&!l.current&&E();return}if(t.operation!==w.current)return;if(t.kind===`replace-saved`){if(!e)o.current.setEnabled(!1);else if(!l.current)try{i(t.saved),f(!0)}catch{o.current.setEnabled(!1),g(`chat.privacy.open_failed`)}}else if(e&&!l.current)try{i(t.imported)}catch{g(`chat.privacy.import_rejected`)}let n=t.trigger;window.setTimeout(()=>{let e=document.activeElement;n.isConnected&&!n.matches(`:disabled`)&&(e===null||e===document.body)&&n.focus()},0)},O=(e,t,n,r,i)=>v?.kind===e?(0,x.jsx)(lt,{open:!0,title:z(a,t),body:z(a,n),confirmLabel:z(a,r),cancelLabel:z(a,`common.cancel`),closeLabel:z(a,`common.close`),tone:`danger`,testId:i,onConfirm:()=>D(!0),onClose:()=>D(!1)}):null;return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(`details`,{className:`chat-privacy`,children:[(0,x.jsx)(`summary`,{children:z(a,`chat.privacy.summary`)}),(0,x.jsx)(`p`,{children:z(a,`chat.privacy.body`)}),(0,x.jsxs)(`label`,{className:`toggle`,children:[(0,x.jsx)(`input`,{type:`checkbox`,checked:d,disabled:t||s,onChange:e=>{T(e.target.checked,e.currentTarget)}}),z(a,`chat.privacy.save`)]}),(0,x.jsxs)(`label`,{className:`toggle`,children:[(0,x.jsx)(`input`,{type:`checkbox`,checked:p,disabled:t||s,onChange:e=>m(e.target.checked)}),z(a,`chat.privacy.include_images`)]}),(0,x.jsx)(`p`,{children:z(a,`chat.privacy.note`)}),(0,x.jsxs)(`div`,{className:`chat-toolbar`,children:[(0,x.jsx)(P,{disabled:t||s,onClick:()=>{try{let t=new Blob([Ga(e,{includeImages:p})],{type:`application/json`}),n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=`mlxcel-conversations.json`,r.click(),setTimeout(()=>URL.revokeObjectURL(n),1e3)}catch{g(`chat.privacy.export_failed`)}},children:z(a,`chat.privacy.export`)}),(0,x.jsx)(P,{ref:C,disabled:t||s,onClick:()=>S({kind:`clear`}),children:z(a,`chat.privacy.clear`)})]}),(0,x.jsxs)(`label`,{className:`ds-field`,children:[z(a,`chat.privacy.import`),(0,x.jsx)(`input`,{type:`file`,accept:`application/json,.json`,disabled:t||s,onChange:e=>{let t=e.currentTarget,n=e.target.files?.[0];if(e.target.value=``,!n)return;if(n.size>16777216){g(`chat.privacy.import_too_large`);return}let i=++w.current;u(!0),n.text().then(async e=>{let n=Ka(e,{includeImages:p});await yo(n,r),!(i!==w.current||l.current)&&S({kind:`replace-import`,imported:n,operation:i,trigger:t})}).catch(()=>{i===w.current&&g(`chat.privacy.import_rejected`)}).finally(()=>{i===w.current&&u(!1)})}})]}),h?(0,x.jsx)(R,{tone:`info`,title:z(a,`chat.privacy.title`),body:z(a,h)}):null]}),O(`replace-saved`,`chat.privacy.replace_saved.confirm.title`,`chat.privacy.replace_saved.confirm.body`,`chat.privacy.replace_saved.confirm`,`chat-replace-saved-dialog`),O(`clear`,`chat.privacy.clear.confirm.title`,`settings.clear_history.confirm.body`,`chat.privacy.clear.confirm`,`chat-clear-history-dialog`),O(`replace-import`,`chat.privacy.replace_import.confirm.title`,`chat.privacy.replace_import.confirm.body`,`chat.privacy.replace_import.confirm`,`chat-replace-import-dialog`)]})}async function yo(e,t){for(let n of e)for(let e of n.turns)if(e.images.length){if(!t)throw Error(`Server image limits unavailable.`);e.images=await va(e.images.map(e=>{let t=atob(e.dataUrl.slice(e.dataUrl.indexOf(`,`)+1)),n=Uint8Array.from(t,e=>e.charCodeAt(0));return new File([n],e.name,{type:e.type})}),0,t)}}function bo(e,t){let n=Object.fromEntries(Object.entries(t).filter(([,e])=>e!==void 0&&e.trim()!==``).map(([e,t])=>[e,Number(t)]));return{...ar({...e,...n})}}function xo({defaults:e,draft:t,onChange:n,locale:r}){return(0,x.jsxs)(`details`,{className:`chat-parameters`,children:[(0,x.jsx)(`summary`,{children:z(r,`chat.params.summary`)}),(0,x.jsx)(`p`,{children:z(r,`chat.params.body`)}),(0,x.jsx)(`div`,{className:`chat-parameter-grid`,children:ir.map(i=>(0,x.jsx)(at,{label:z(r,`chat.params.field`,{name:i}),value:t[i]??``,onChange:e=>n({...t,[i]:e}),hint:z(r,`chat.params.inherited`,{value:e[i]?.toString()??z(r,`chat.params.server_default`)})},i))}),(0,x.jsx)(P,{onClick:()=>n({}),children:z(r,`chat.params.clear`)})]})}var So=new Set([`en`,`ko`].map(e=>z(e,`chat.conversation.default_title`)));function Co({locale:e}){let t=tr(),n=nr(),{defaults:r}=dr(),[i,a]=(0,_.useState)({}),o=oo(),[s,c]=(0,_.useState)(null),[l,u]=(0,_.useState)(``),[d,f]=(0,_.useState)([]),[p,m]=(0,_.useState)(null),[h,g]=(0,_.useState)(``),[v,y]=(0,_.useState)(!1),[b,S]=(0,_.useState)(!1),[C,w]=(0,_.useState)(!1),[T,E]=(0,_.useState)(null),D=(0,_.useRef)(e);D.current=e;let O=(e,t)=>z(D.current,e,t),k=(0,_.useRef)(null),ee=(0,_.useRef)(0),A=(0,_.useRef)(!1),te=(0,_.useRef)(0),ne=(0,_.useRef)(null),j=o.find(e=>e.id===s)??null,M=t.catalog.find(e=>e.identity.id===t.selectedModelId),N=[`ready`,`streaming`,`polling`].includes(t.connection)&&M?.lifecycle.state===`ready`&&M.capabilities.some(e=>e.task===`chat`&&e.phase===`provider_ready`&&e.available),re=N&&t.bootstrap!==null&&Object.values(t.bootstrap.media_limits).every(e=>e>0)&&M?.capabilities.some(e=>e.task===`vision_input`&&e.phase===`provider_ready`&&e.available);(0,_.useEffect)(()=>()=>{ee.current++,te.current++;let e=ne.current;e!==null&&(e.turn={...e.turn,status:`interrupted`,error:z(D.current,`chat.error.view_closed`)},e.controller.abort(),e.flush())},[]);let ie=()=>{if(v||b||C||o.length>=50)return;ee.current++;let e=$a(O(`chat.conversation.default_title`));ao(e),c(e.id),u(``),f([])},ae=()=>{let e=ne.current;if(e===null)return;e.turn={...e.turn,status:`cancelled`,error:null},e.controller.abort(),e.flush();let t=++te.current;g(O(`chat.announce.stopped`)),n.refreshRuntime(e.turn.modelId).then(e=>{te.current===t&&g(O(`chat.announce.aborted_observed`,{time:e.measurements.active_requests?.measured_at??O(`chat.announce.unknown_time`)}))}).catch(()=>{te.current===t&&g(O(`chat.announce.aborted_unobserved`))})},oe=async()=>{if(ne.current!==null||b||C||!N||M===void 0||!l.trim()||l.length>32e3)return;if((d.length||j?.turns.some(e=>e.images.length))&&!re){m(O(`chat.error.vision_unsupported`));return}if(j===null&&o.length>=50){m(O(`chat.error.conversation_limit`));return}let e;try{e=bo(r,i)}catch(e){m(e instanceof Error?e.message:O(`chat.error.invalid_parameters`));return}let s=j??$a(O(`chat.conversation.default_title`));if(s.turns.length>=100){m(O(`chat.error.turn_limit`));return}c(s.id);let p=new AbortController,h=performance.now(),_={id:crypto.randomUUID(),modelId:M.identity.id,inferenceId:M.identity.inference_id,modelName:M.identity.display_name,modelRevision:M.identity.revision,prompt:l,content:``,reasoning:``,tools:[],status:`streaming`,finishReason:null,usage:null,ttftMs:null,elapsedMs:null,error:null,parameters:e,images:d.map(e=>({...e}))};s={...s,title:s.turns.length===0&&So.has(s.title)?l.slice(0,80):s.title,turns:[...s.turns,_],updatedAt:Date.now()};try{if(!t.bootstrap)throw Error(`Limits unavailable`);_a(s.turns.flatMap(e=>e.images),t.bootstrap.media_limits)}catch{m(O(`chat.error.images_exceed`));return}let v={..._.parameters,model:_.inferenceId,stream:!0,messages:Ta(s.systemPrompt,s.turns),stream_options:{include_usage:!0}},x=Math.min(t.bootstrap?.media_limits.max_body_bytes??0,16777216);if(new TextEncoder().encode(JSON.stringify(v)).byteLength>x){m(O(`chat.error.body_limit`));return}if(!ao(s)){m(O(`chat.error.memory_budget`));return}let S=null,w=Qa(),T={controller:p,turn:_,conversation:s,flush:()=>{if(S!==null&&clearTimeout(S),S=null,Qa()!==w)return;let e=T.conversation;T.conversation={...T.conversation,turns:T.conversation.turns.map(e=>e.id===_.id?T.turn:e),updatedAt:Date.now()},ao(T.conversation)||(p.abort(),T.conversation=e,T.turn={...e.turns.find(e=>e.id===_.id)??_,status:`error`,error:null},T.conversation={...e,turns:e.turns.map(e=>e.id===_.id?T.turn:e)},ao(T.conversation),m(O(`chat.error.memory_budget_stream`)))}};a({}),ne.current=T,te.current++,y(!0),m(null),u(``),f([]),T.flush(),g(O(`chat.announce.generating`));try{await n.streamChatCompletions(_.modelId,v,{onFrame:e=>{p.signal.aborted||(T.turn=Ca(T.turn,e.data,performance.now()-h),S===null&&(S=setTimeout(T.flush,50)))}},p.signal),p.signal.aborted||(T.turn=wa(T.turn,performance.now()-h),g(O(`chat.announce.complete`)))}catch{p.signal.aborted||(p.abort(),T.turn={...T.turn,status:`error`,elapsedMs:performance.now()-h,error:O(`chat.error.generation_failed`)},g(O(`chat.announce.failed`)))}finally{T.flush(),ne.current===T&&(ne.current=null),y(!1)}},se=()=>{let e=T;if(E(null),e===null||v||b||C||j===null||j.id!==e.conversationId||j.turns[e.index]?.id!==e.turnId)return;let{index:t}=e;u(j.turns[t].prompt),f(j.turns[t].images),ao({...j,turns:j.turns.slice(0,t)}),window.setTimeout(()=>k.current?.focus(),0)},[ce,F=``]=z(e,`chat.settings.sampling`).split(`{link}`);return(0,x.jsxs)(`div`,{className:`screen-stack chat-screen`,children:[(0,x.jsxs)(`section`,{className:`screen-heading`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:z(e,`chat.eyebrow`)}),(0,x.jsx)(`h1`,{tabIndex:-1,"data-dialog-focus-fallback":!0,"data-testid":B(`chat.title`),children:z(e,`chat.title`)}),(0,x.jsx)(`p`,{children:z(e,`chat.intro`)})]}),(0,x.jsxs)(`div`,{className:`chat-toolbar`,children:[(0,x.jsx)(P,{onClick:ie,disabled:v||b||C||o.length>=50,children:z(e,`chat.new_conversation`)}),(0,x.jsx)(Ae,{locale:e,label:z(e,`chat.conversation.label`),value:s??``,disabled:v||b||C,onChange:e=>{c(e),u(``),f([])},options:[{value:``,label:z(e,`chat.conversation.choose`)},...o.map(e=>({value:e.id,label:e.title}))]}),(0,x.jsx)(Ae,{locale:e,label:z(e,`chat.model.label`),value:t.selectedModelId??``,onChange:e=>n.selectModel(e||null),options:[{value:``,label:z(e,`chat.model.choose`)},...t.catalog.map(t=>({value:t.identity.id,label:`${t.identity.display_name} · ${Er(e,t.lifecycle.state)}`}))]})]}),N?null:(0,x.jsx)(R,{tone:`info`,title:z(e,`chat.no_model.title`),body:z(e,`chat.no_model.body`),action:(0,x.jsx)(`a`,{href:`#models`,children:z(e,`chat.no_model.action`)})}),j?(0,x.jsxs)(`details`,{children:[(0,x.jsx)(`summary`,{children:z(e,`chat.settings.summary`)}),(0,x.jsx)(at,{label:z(e,`chat.settings.name`),value:j.title,disabled:v||b||C,onChange:e=>ao({...j,title:e.slice(0,120)})}),(0,x.jsxs)(`label`,{className:`ds-field`,children:[z(e,`chat.settings.system_prompt`),(0,x.jsx)(`textarea`,{value:j.systemPrompt,maxLength:ya,disabled:v||b||C,onChange:e=>ao({...j,systemPrompt:e.target.value})})]}),(0,x.jsxs)(`p`,{children:[ce,(0,x.jsx)(`a`,{href:`#settings`,children:z(e,`nav.settings`)}),F]}),(0,x.jsx)(P,{disabled:v||b||C,onClick:()=>{io(o.filter(e=>e.id!==j.id)),c(null)},children:z(e,`chat.settings.delete`)})]}):null,(0,x.jsx)(xo,{defaults:r,draft:i,onChange:a,locale:e}),(0,x.jsx)(_o,{turns:j?.turns??[],onEdit:e=>{if(v||b||C||j===null)return;let t=j.turns[e];t&&E({conversationId:j.id,turnId:t.id,index:e})},busy:v||b||C,locale:e}),T===null?null:(0,x.jsx)(lt,{open:!0,title:z(e,`chat.transcript.edit.confirm.title`),body:z(e,`chat.transcript.edit.confirm.body`),confirmLabel:z(e,`chat.transcript.edit.confirm`),cancelLabel:z(e,`common.cancel`),closeLabel:z(e,`common.close`),tone:`danger`,testId:`chat-edit-dialog`,onConfirm:se,onClose:()=>E(null)}),p?(0,x.jsx)(R,{title:z(e,`chat.error.title`),body:p}):null,(0,x.jsxs)(`div`,{className:`chat-composer`,children:[(0,x.jsxs)(`label`,{className:`ds-field`,children:[z(e,`chat.composer.label`),(0,x.jsx)(`textarea`,{ref:k,"aria-label":z(e,`chat.composer.label`),value:l,maxLength:ya,disabled:v||b||C,onChange:e=>u(e.target.value),onCompositionStart:()=>{A.current=!0},onCompositionEnd:()=>{A.current=!1},onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&!A.current&&!e.nativeEvent.isComposing&&e.keyCode!==229&&(e.preventDefault(),oe())}})]}),(0,x.jsx)(`p`,{children:z(e,`chat.composer.hint`,{count:String(l.length),max:String(ya)})}),re?(0,x.jsxs)(`label`,{className:`ds-field`,children:[z(e,`chat.images.label`),(0,x.jsx)(`input`,{type:`file`,accept:`image/png,image/jpeg,image/webp`,multiple:!0,disabled:v||b||C,onChange:e=>{let n=e.target.files;if(n&&t.bootstrap){let e=++ee.current;w(!0),va(n,d.length,t.bootstrap.media_limits,d).then(t=>{e===ee.current&&f(e=>[...e,...t])}).catch(()=>m(O(`chat.error.images_invalid`))).finally(()=>{e===ee.current&&w(!1)})}e.target.value=``}})]}):(0,x.jsx)(`p`,{children:z(e,`chat.images.unsupported`)}),(0,x.jsx)(`div`,{className:`chat-images`,children:d.map((t,n)=>(0,x.jsxs)(`figure`,{children:[(0,x.jsx)(`img`,{src:t.dataUrl,alt:t.name}),(0,x.jsx)(P,{disabled:v||b||C,onClick:()=>f(d.filter((e,t)=>n!==t)),children:z(e,`chat.images.remove`,{name:t.name})})]},`${t.name}-${n}`))}),(0,x.jsxs)(`div`,{className:`chat-toolbar`,children:[(0,x.jsx)(P,{tone:`primary`,disabled:!N||v||b||C||!l.trim(),onClick:()=>{oe()},children:z(e,`common.send`)}),(0,x.jsx)(P,{disabled:!v,onClick:ae,children:z(e,`chat.stop`)})]})]}),(0,x.jsx)(`p`,{role:`status`,"aria-live":`polite`,"aria-atomic":`true`,children:h}),(0,x.jsx)(vo,{conversations:o,busy:v||C,onPending:S,limits:t.bootstrap?.media_limits,onReplace:e=>{io(e),c(null)},locale:e})]})}var wo=[`models`,`chat`,`activity`,`settings`,`gallery`],To=[`models`,`chat`,`activity`,`settings`];function Eo(){let e=window.location.hash.slice(1).replace(/^\//,``);return wo.includes(e)?e:`models`}function Do(){let e=tr(),t=nr(),[n,r]=(0,_.useState)(Eo),[i,a]=(0,_.useState)(gi),[o,s]=(0,_.useState)(null),[c,l]=(0,_.useState)(null),u=(0,_.useRef)(0);(0,_.useEffect)(()=>()=>{u.current+=1},[]),(0,_.useEffect)(()=>{let e=()=>r(Eo());return window.addEventListener(`hashchange`,e),()=>window.removeEventListener(`hashchange`,e)},[]),(0,_.useEffect)(()=>{if(yi(document.documentElement,i),_i(i),i.colorScheme===`system`)return oi(e=>yi(document.documentElement,i,e))},[i]),(0,_.useEffect)(()=>{let e=()=>{document.documentElement.dataset.documentHidden=String(document.hidden)};return e(),document.addEventListener(`visibilitychange`,e),()=>document.removeEventListener(`visibilitychange`,e)},[]),(0,_.useEffect)(()=>{e.auth.status===`authenticated`&&l(null)},[e.auth.status]),(0,_.useEffect)(()=>{e.auth.status===`signed-out`&&io([])},[e.auth.status]);let d=e=>{r(e),window.history.replaceState(null,``,`#${e}`)},f=e=>{let n=u.current+1;u.current=n,l(null),t.login(e).catch(e=>{u.current===n&&(e instanceof DOMException&&e.name===`AbortError`||l(mr(e)))})},p=()=>{u.current+=1,l(null),t.logout()},m=Oo(n,i,a,{snapshot:e,authFailure:c,login:f,logout:p,retry:()=>{l(null),t.refresh()},recoverSchema:()=>{p(),window.location.reload()}});return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(Kr,{locale:i.locale,route:n,onRouteChange:d,onCommand:()=>s(`command`),onHelp:()=>s(`help`),selectedModel:hr(i.locale,e),connectionLabel:gr(i.locale,e),connectionState:e.connection,sessionAction:e.auth.tokenPresent?(0,x.jsx)(F,{label:z(i.locale,`toolbar.logout`),icon:`key`,onClick:p,"data-testid":B(`toolbar.logout`)}):null,inspector:null,children:m}),(0,x.jsx)(Po,{open:o===`command`,locale:i.locale,onClose:()=>s(null),onNavigate:e=>{d(e),s(null)}}),(0,x.jsxs)(ct,{open:o===`help`,title:z(i.locale,`help.title`),onClose:()=>s(null),testId:`help-dialog`,closeLabel:z(i.locale,`common.close`),children:[(0,x.jsx)(`p`,{"data-testid":B(`help.body`),children:z(i.locale,`help.body`)}),(0,x.jsxs)(`ul`,{className:`shortcut-list`,children:[(0,x.jsxs)(`li`,{children:[(0,x.jsx)(`kbd`,{children:`⌘/Ctrl`}),` + `,(0,x.jsx)(`kbd`,{children:`K`}),` `,z(i.locale,`command.search`)]}),(0,x.jsxs)(`li`,{children:[(0,x.jsx)(`kbd`,{children:`Esc`}),` `,z(i.locale,`common.cancel`)]}),(0,x.jsxs)(`li`,{children:[(0,x.jsx)(`kbd`,{children:`[`}),` / `,(0,x.jsx)(`kbd`,{children:`]`}),` `,z(i.locale,`nav.models`)]})]})]})]})}function Oo(e,t,n,r){return e===`models`?(0,x.jsx)(ko,{locale:t.locale,context:r}):e===`chat`?(0,x.jsx)(Ao,{locale:t.locale,context:r}):e===`activity`?(0,x.jsx)(jo,{locale:t.locale,context:r}):e===`settings`?(0,x.jsx)(Mo,{appearance:t,setAppearance:n}):(0,x.jsx)(sa,{locale:t.locale})}function ko(e){return e.context.snapshot.auth.status===`authenticated`&&e.context.snapshot.connection!==`schema-mismatch`?(0,x.jsx)(na,{locale:e.locale}):(0,x.jsx)(vr,{locale:e.locale,title:z(e.locale,`models.title`),titleTestId:B(`models.title`),snapshot:e.context.snapshot,authFailure:e.context.authFailure,onLogin:e.context.login,onLogout:e.context.logout,onRetry:e.context.retry,onRecoverSchema:e.context.recoverSchema})}function Ao(e){return e.context.snapshot.auth.status===`authenticated`&&e.context.snapshot.connection!==`schema-mismatch`?(0,x.jsx)(Co,{locale:e.locale}):(0,x.jsx)(vr,{locale:e.locale,title:z(e.locale,`chat.title`),titleTestId:B(`chat.title`),snapshot:e.context.snapshot,authFailure:e.context.authFailure,onLogin:e.context.login,onLogout:e.context.logout,onRetry:e.context.retry,onRecoverSchema:e.context.recoverSchema})}function jo(e){return e.context.snapshot.auth.status===`authenticated`&&![`schema-mismatch`,`forbidden`,`unauthorized`].includes(e.context.snapshot.connection)?(0,x.jsx)(Pi,{locale:e.locale}):(0,x.jsx)(vr,{locale:e.locale,title:z(e.locale,`activity.title`),titleTestId:B(`activity.title`),snapshot:e.context.snapshot,authFailure:e.context.authFailure,onLogin:e.context.login,onLogout:e.context.logout,onRetry:e.context.retry,onRecoverSchema:e.context.recoverSchema})}function Mo(e){let t=t=>e.setAppearance({...e.appearance,...t});return(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsx)(Ge,{title:z(e.appearance.locale,`settings.title`),titleTestId:B(`settings.title`),description:z(e.appearance.locale,`settings.browser_only`),descriptionTestId:B(`settings.appearance`),focusFallback:!0}),(0,x.jsxs)(`div`,{className:`settings-grid`,children:[(0,x.jsx)(Ae,{locale:e.appearance.locale,label:z(e.appearance.locale,`settings.theme`),value:e.appearance.themeFamily,onChange:e=>t({themeFamily:e}),options:[{value:`mlxcel`,label:z(e.appearance.locale,`settings.theme.mlxcel`)},{value:`glass`,label:z(e.appearance.locale,`settings.theme.glass`)}],testId:B(`settings.theme`)}),(0,x.jsx)(Ae,{locale:e.appearance.locale,label:z(e.appearance.locale,`settings.color_scheme`),value:e.appearance.colorScheme,onChange:e=>t({colorScheme:e}),options:[{value:`system`,label:z(e.appearance.locale,`settings.color_scheme.system`)},{value:`light`,label:z(e.appearance.locale,`settings.color_scheme.light`)},{value:`dark`,label:z(e.appearance.locale,`settings.color_scheme.dark`)}],testId:B(`settings.color_scheme`)}),(0,x.jsx)(Ae,{locale:e.appearance.locale,label:z(e.appearance.locale,`settings.material`),value:e.appearance.material,onChange:e=>t({material:e}),options:[{value:`glass`,label:z(e.appearance.locale,`settings.material.glass`)},{value:`tinted`,label:z(e.appearance.locale,`settings.material.tinted`)},{value:`opaque`,label:z(e.appearance.locale,`settings.material.opaque`)}],testId:B(`settings.material`)}),(0,x.jsx)(Ae,{locale:e.appearance.locale,label:z(e.appearance.locale,`settings.locale`),value:e.appearance.locale,onChange:e=>t({locale:e}),options:[{value:`en`,label:z(e.appearance.locale,`settings.locale.en`)},{value:`ko`,label:z(e.appearance.locale,`settings.locale.ko`)}],testId:B(`settings.locale`)}),(0,x.jsx)(Ae,{locale:e.appearance.locale,label:z(e.appearance.locale,`settings.high_contrast`),value:e.appearance.highContrast,onChange:e=>t({highContrast:e}),options:[{value:`system`,label:z(e.appearance.locale,`settings.high_contrast.system`)},{value:`on`,label:z(e.appearance.locale,`settings.high_contrast.on`)},{value:`off`,label:z(e.appearance.locale,`settings.high_contrast.off`)}],testId:B(`settings.high_contrast`)}),(0,x.jsxs)(`label`,{className:`ds-field`,children:[(0,x.jsxs)(`span`,{children:[z(e.appearance.locale,`settings.glass_intensity`),`: `,e.appearance.glassIntensity]}),(0,x.jsx)(`input`,{type:`range`,min:`0`,max:`100`,value:e.appearance.glassIntensity,onChange:e=>t({glassIntensity:Number(e.currentTarget.value)}),"data-testid":B(`settings.glass_intensity`)})]}),(0,x.jsx)(No,{label:z(e.appearance.locale,`settings.reduce_motion`),checked:e.appearance.reduceMotion,onChange:e=>t({reduceMotion:e}),testId:B(`settings.reduce_motion`)}),(0,x.jsx)(No,{label:z(e.appearance.locale,`settings.reduce_transparency`),checked:e.appearance.reduceTransparency,onChange:e=>t({reduceTransparency:e}),testId:B(`settings.reduce_transparency`)})]}),(0,x.jsx)(R,{tone:`info`,title:z(e.appearance.locale,`settings.browser_only`),body:z(e.appearance.locale,`settings.browser_only.body`),testId:B(`settings.browser_only`)}),(0,x.jsx)(Wr,{locale:e.appearance.locale})]})}function No(e){return(0,x.jsxs)(`label`,{className:`toggle`,children:[(0,x.jsx)(`input`,{type:`checkbox`,checked:e.checked,onChange:t=>e.onChange(t.currentTarget.checked),"data-testid":e.testId}),(0,x.jsx)(`span`,{children:e.label})]})}function Po(e){let[t,n]=(0,_.useState)(``),r=(e.locale&&window.location.hash.includes(`gallery`)?wo:To).filter(e=>e.includes(t.toLowerCase()));return(0,x.jsxs)(ct,{open:e.open,title:z(e.locale,`command.title`),onClose:e.onClose,testId:`command-dialog`,closeLabel:z(e.locale,`common.close`),children:[(0,x.jsx)(at,{label:z(e.locale,`command.search`),value:t,onChange:n,testId:B(`command.search`)}),r.length===0?(0,x.jsx)(`p`,{"data-testid":B(`command.no_results`),children:z(e.locale,`command.no_results`)}):(0,x.jsx)(`div`,{className:`command-list`,children:r.map(t=>(0,x.jsx)(P,{onClick:()=>e.onNavigate(t),children:z(e.locale,t===`models`?`nav.models`:t===`chat`?`nav.chat`:t===`activity`?`nav.activity`:t===`settings`?`nav.settings`:`nav.gallery`)},t))})]})}var Fo=document.getElementById(`root`);if(Fo===null)throw Error(`Missing #root element for mlxcel WebUI.`);(0,v.createRoot)(Fo).render((0,x.jsx)(_.StrictMode,{children:(0,x.jsx)(er,{children:(0,x.jsx)(Do,{})})}));export{c as i,b as n,u as r,z as t}; \ No newline at end of file diff --git a/src/webui/assets/assets/index-CQvJAqGK.js b/src/webui/assets/assets/index-CQvJAqGK.js new file mode 100644 index 000000000..11da18c12 --- /dev/null +++ b/src/webui/assets/assets/index-CQvJAqGK.js @@ -0,0 +1,3741 @@ +var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),s=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;li[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},c=(n,r,o)=>(o=n==null?{}:e(i(n)),s(r||!n||!n.__esModule||!a.call(n,`default`)?t(o,`default`,{value:n,enumerable:!0}):o,n)),l=o((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.portal`),r=Symbol.for(`react.fragment`),i=Symbol.for(`react.strict_mode`),a=Symbol.for(`react.profiler`),o=Symbol.for(`react.consumer`),s=Symbol.for(`react.context`),c=Symbol.for(`react.forward_ref`),l=Symbol.for(`react.suspense`),u=Symbol.for(`react.memo`),d=Symbol.for(`react.lazy`),f=Symbol.for(`react.activity`),p=Symbol.for(`react.view_transition`),m=Symbol.iterator;function h(e){return typeof e!=`object`||!e?null:(e=m&&e[m]||e[`@@iterator`],typeof e==`function`?e:null)}var g={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},_=Object.assign,v={};function y(e,t,n){this.props=e,this.context=t,this.refs=v,this.updater=n||g}y.prototype.isReactComponent={},y.prototype.setState=function(e,t){if(typeof e!=`object`&&typeof e!=`function`&&e!=null)throw Error(`takes an object of state variables to update or a function which returns an object of state variables.`);this.updater.enqueueSetState(this,e,t,`setState`)},y.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,`forceUpdate`)};function b(){}b.prototype=y.prototype;function x(e,t,n){this.props=e,this.context=t,this.refs=v,this.updater=n||g}var S=x.prototype=new b;S.constructor=x,_(S,y.prototype),S.isPureReactComponent=!0;var C=Array.isArray;function w(){}var T={H:null,A:null,T:null,S:null},E=Object.prototype.hasOwnProperty;function D(e,n,r){var i=r.ref;return{$$typeof:t,type:e,key:n,ref:i===void 0?null:i,props:r}}function O(e,t){return D(e.type,t,e.props)}function k(e){return typeof e==`object`&&!!e&&e.$$typeof===t}function ee(e){var t={"=":`=0`,":":`=2`};return`$`+e.replace(/[=:]/g,function(e){return t[e]})}var A=/\/+/g;function te(e,t){return typeof e==`object`&&e&&e.key!=null?ee(``+e.key):t.toString(36)}function ne(e){switch(e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason;default:switch(typeof e.status==`string`?e.then(w,w):(e.status=`pending`,e.then(function(t){e.status===`pending`&&(e.status=`fulfilled`,e.value=t)},function(t){e.status===`pending`&&(e.status=`rejected`,e.reason=t)})),e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason}}throw e}function j(e,r,i,a,o){var s=typeof e;(s===`undefined`||s===`boolean`)&&(e=null);var c=!1;if(e===null)c=!0;else switch(s){case`bigint`:case`string`:case`number`:c=!0;break;case`object`:switch(e.$$typeof){case t:case n:c=!0;break;case d:return c=e._init,j(c(e._payload),r,i,a,o)}}if(c)return o=o(e),c=a===``?`.`+te(e,0):a,C(o)?(i=``,c!=null&&(i=c.replace(A,`$&/`)+`/`),j(o,r,i,``,function(e){return e})):o!=null&&(k(o)&&(o=O(o,i+(o.key==null||e&&e.key===o.key?``:(``+o.key).replace(A,`$&/`)+`/`)+c)),r.push(o)),1;c=0;var l=a===``?`.`:a+`:`;if(C(e))for(var u=0;u{t.exports=l()})),d=o((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0>>1,a=e[r];if(0>>1;ri(c,n))li(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(li(u,n))e[r]=u,e[l]=n,r=l;else break a}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return n===0?e.id-t.id:n}if(e.unstable_now=void 0,typeof performance==`object`&&typeof performance.now==`function`){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,s=o.now();e.unstable_now=function(){return o.now()-s}}var c=[],l=[],u=1,d=null,f=3,p=!1,m=!1,h=!1,g=!1,_=typeof setTimeout==`function`?setTimeout:null,v=typeof clearTimeout==`function`?clearTimeout:null,y=typeof setImmediate<`u`?setImmediate:null;function b(e){for(var i=n(l);i!==null;){if(i.callback===null)r(l);else if(i.startTime<=e)r(l),i.sortIndex=i.expirationTime,t(c,i);else break;i=n(l)}}function x(e){if(h=!1,b(e),!m){if(n(c)!==null)m=!0,S||(S=!0,O());else{var t=n(l);t!==null&&A(x,t.startTime-e)}}}var S=!1,C=-1,w=5,T=-1;function E(){return g?!0:!(e.unstable_now()-Tt&&E());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=t);if(t=e.unstable_now(),typeof s==`function`){d.callback=s,b(t),i=!0;break b}d===n(c)&&r(c),b(t)}else r(c);d=n(c)}if(d!==null)i=!0;else{var u=n(l);u!==null&&A(x,u.startTime-t),i=!1}}break a}finally{d=null,f=a,p=!1}i=void 0}}finally{i?O():S=!1}}}var O;if(typeof y==`function`)O=function(){y(D)};else if(typeof MessageChannel<`u`){var k=new MessageChannel,ee=k.port2;k.port1.onmessage=D,O=function(){ee.postMessage(null)}}else O=function(){_(D,0)};function A(t,n){C=_(function(){t(e.unstable_now())},n)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_forceFrameRate=function(e){0>e||125o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(v(C),C=-1):h=!0,A(x,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,S||(S=!0,O()))),r},e.unstable_shouldYield=E,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),f=o(((e,t)=>{t.exports=d()})),p=o((e=>{var t=u();function n(e){var t=`https://react.dev/errors/`+e;if(1{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=p()})),h=o((e=>{var t=f(),n=u(),r=m();function i(e){var t=`https://react.dev/errors/`+e;if(1ve||(e.current=_e[ve],_e[ve]=null,ve--)}function L(e,t){ve++,_e[ve]=e.current,e.current=t}var xe=ye(null),Se=ye(null),Ce=ye(null),we=ye(null);function Te(e,t){switch(L(Ce,t),L(Se,e),L(xe,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?up(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=up(t),e=dp(t,e);else switch(e){case`svg`:e=1;break;case`math`:e=2;break;default:e=0}}be(xe),L(xe,e)}function Ee(){be(xe),be(Se),be(Ce)}function De(e){var t=e.memoizedState;t!==null&&(sh._currentValue=t.memoizedState,L(we,e)),t=xe.current;var n=dp(t,e.type);t!==n&&(L(Se,e),L(xe,n))}function Oe(e){Se.current===e&&(be(xe),be(Se)),we.current===e&&(be(we),sh._currentValue=ge)}var ke,Ae;function R(e){if(ke===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);ke=t&&t[1]||``,Ae=-1)`:-1i||c[r]!==l[i]){var u=` +`+c[r].replace(` at new `,` at `);return e.displayName&&u.includes(``)&&(u=u.replace(``,e.displayName)),u}while(1<=r&&0<=i);break}}}finally{z=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:``)?R(n):``}function Me(e,t){switch(e.tag){case 26:case 27:case 5:return R(e.type);case 16:return R(`Lazy`);case 13:return e.child!==t&&t!==null?R(`Suspense Fallback`):R(`Suspense`);case 19:return R(`SuspenseList`);case 0:case 15:return je(e.type,!1);case 11:return je(e.type.render,!1);case 1:return je(e.type,!0);case 31:return R(`Activity`);case 30:return R(`ViewTransition`);default:return``}}function Ne(e){try{var t=``,n=null;do t+=Me(e,n),n=e,e=e.return;while(e);return t}catch(e){return` +Error generating stack: `+e.message+` +`+e.stack}}var Pe=Object.prototype.hasOwnProperty,Fe=t.unstable_scheduleCallback,Ie=t.unstable_cancelCallback,Le=t.unstable_shouldYield,Re=t.unstable_requestPaint,ze=t.unstable_now,Be=t.unstable_getCurrentPriorityLevel,Ve=t.unstable_ImmediatePriority,He=t.unstable_UserBlockingPriority,Ue=t.unstable_NormalPriority,We=t.unstable_LowPriority,Ge=t.unstable_IdlePriority,Ke=t.log,qe=t.unstable_setDisableYieldValue,Je=null,Ye=null;function Xe(e){if(typeof Ke==`function`&&qe(e),Ye&&typeof Ye.setStrictMode==`function`)try{Ye.setStrictMode(Je,e)}catch{}}var Ze=Math.clz32?Math.clz32:et,Qe=Math.log,$e=Math.LN2;function et(e){return e>>>=0,e===0?32:31-(Qe(e)/$e|0)|0}var tt=256,nt=262144,rt=4194304;function it(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&-e;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function at(e,t,n){var r=e.pendingLanes;if(r===0)return 0;var i=0,a=e.suspendedLanes,o=e.pingedLanes;e=e.warmLanes;var s=r&134217727;return s===0?(s=r&~a,s===0?o===0?n||(n=r&~e,n!==0&&(i=it(n))):i=it(o):i=it(s)):(r=s&~a,r===0?(o&=s,o===0?n||(n=s&~e,n!==0&&(i=it(n))):i=it(o)):i=it(r)),i===0?0:t!==0&&t!==i&&(t&a)===0&&(a=i&-i,n=t&-t,a>=n||a===32&&n&4194048)?t:i}function ot(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function st(e,t){t&8&&(t|=t&32);var n=e.entangledLanes;if(n!==0)for(e=e.entanglements,n&=t;0n;n++)t.push(e);return t}function dt(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function ft(e,t,n,r,i,a){var o=e.pendingLanes;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=n,e.entangledLanes&=n,e.errorRecoveryDisabledLanes&=n,e.shellSuspendCounter=0;var s=e.entanglements,c=e.expirationTimes,l=e.hiddenUpdates;for(n=o&~n;0`u`||window.document===void 0||window.document.createElement===void 0),En=!1;if(Tn)try{var Dn={};Object.defineProperty(Dn,"passive",{get:function(){En=!0}}),window.addEventListener(`test`,Dn,Dn),window.removeEventListener(`test`,Dn,Dn)}catch{En=!1}var On=null,kn=null,An=null;function jn(){if(An)return An;var e,t=kn,n=t.length,r,i=`value`in On?On.value:On.textContent,a=i.length;for(e=0;e=ur),pr=` `,mr=!1;function hr(e,t){switch(e){case`keyup`:return cr.indexOf(t.keyCode)!==-1;case`keydown`:return t.keyCode!==229;case`keypress`:case`mousedown`:case`focusout`:return!0;default:return!1}}function gr(e){return e=e.detail,typeof e==`object`&&`data`in e?e.data:null}var _r=!1;function vr(e,t){switch(e){case`compositionend`:return gr(t);case`keypress`:return t.which===32?(mr=!0,pr):null;case`textInput`:return e=t.data,e===pr&&mr?null:e;default:return null}}function yr(e,t){if(_r)return e===`compositionend`||!lr&&hr(e,t)?(e=jn(),An=kn=On=null,_r=!1,e):null;switch(e){case`paste`:return null;case`keypress`:if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:n,offset:t-e};e=r}a:{for(;n;){if(n.nextSibling){n=n.nextSibling;break a}n=n.parentNode}n=void 0}n=Hr(n)}}function Wr(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Wr(e,t.parentNode):`contains`in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function Gr(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=Vr(e.document);t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href==`string`}catch{n=!1}if(n)e=t.contentWindow;else break;t=Vr(e.document)}return t}function Kr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t===`input`&&(e.type===`text`||e.type===`search`||e.type===`tel`||e.type===`url`||e.type===`password`)||t===`textarea`||e.contentEditable===`true`)}var qr=Tn&&`documentMode`in document&&11>=document.documentMode,Jr=null,Yr=null,Xr=null,Zr=!1;function Qr(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;Zr||Jr==null||Jr!==Vr(r)||(r=Jr,`selectionStart`in r&&Kr(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),Xr&&Br(Xr,r)||(Xr=r,r=Jf(Yr,`onSelect`),0>=o,i-=o,Ji=1<<32-Ze(t)+i|n<h?(g=d,d=null):g=d.sibling;var _=p(i,d,s[h],c);if(_===null){d===null&&(d=g);break}e&&d&&_.alternate===null&&t(i,d),a=o(_,a,h),u===null?l=_:u.sibling=_,u=_,d=g}if(h===s.length)return n(i,d),U&&Xi(i,h),l;if(d===null){for(;hg?(_=h,h=null):_=h.sibling;var y=p(a,h,v.value,l);if(y===null){h===null&&(h=_);break}e&&h&&y.alternate===null&&t(a,h),s=o(y,s,g),d===null?u=y:d.sibling=y,d=y,h=_}if(v.done)return n(a,h),U&&Xi(a,g),u;if(h===null){for(;!v.done;g++,v=c.next())v=f(a,v.value,l),v!==null&&(s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return U&&Xi(a,g),u}for(h=r(h);!v.done;g++,v=c.next())v=m(h,a,g,v.value,l),v!==null&&(e&&(_=v.alternate,_!==null&&h.delete(_.key===null?g:_.key)),s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return e&&h.forEach(function(e){return t(a,e)}),U&&Xi(a,g),u}function _(e,r,o,c){if(typeof o==`object`&&o&&o.type===A&&o.key===null&&o.props.ref===void 0&&(o=o.props.children),typeof o==`object`&&o){switch(o.$$typeof){case k:a:{for(var l=o.key;r!==null;){if(r.key===l){if(l=o.type,l===A){if(r.tag===7){n(e,r.sibling),c=a(r,o.props.children),ao(c,o),c.return=e,e=c;break a}}else if(r.elementType===l||typeof l==`object`&&l&&l.$$typeof===se&&Qa(l)===r.type){n(e,r.sibling),c=a(r,o.props),ao(c,o),c.return=e,e=c;break a}n(e,r);break}t(e,r),r=r.sibling}o.type===A?(c=Fi(o.props.children,e.mode,c,o.key),ao(c,o),c.return=e,e=c):(c=Pi(o.type,o.key,o.props,null,e.mode,c),ao(c,o),c.return=e,e=c)}return s(e);case ee:a:{for(l=o.key;r!==null;){if(r.key===l){if(r.tag===4&&r.stateNode.containerInfo===o.containerInfo&&r.stateNode.implementation===o.implementation){n(e,r.sibling),c=a(r,o.children||[]),c.return=e,e=c;break a}n(e,r);break}t(e,r),r=r.sibling}c=Ri(o,e.mode,c),c.return=e,e=c}return s(e);case se:return o=Qa(o),_(e,r,o,c)}if(he(o))return h(e,r,o,c);if(fe(o)){if(l=fe(o),typeof l!=`function`)throw Error(i(150));return o=l.call(o),g(e,r,o,c)}if(typeof o.then==`function`)return _(e,r,io(o),c);if(o.$$typeof===M)return _(e,r,Ca(e,o),c);oo(e,o)}return typeof o==`string`&&o!==``||typeof o==`number`||typeof o==`bigint`?(o=``+o,r!==null&&r.tag===6?(n(e,r.sibling),c=a(r,o),c.return=e,e=c):(n(e,r),c=Ii(o,e.mode,c),c.return=e,e=c),s(e)):n(e,r)}return function(e,t,n,r){try{ro=0;var i=_(e,t,n,r);return no=null,i}catch(t){if(t===Ka||t===Ja)throw t;var a=Ai(29,t,null,e.mode);return a.lanes=r,a.return=e,a}}}var co=so(!0),lo=so(!1),uo=!1;function fo(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function po(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function mo(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function ho(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,q&2){var i=r.pending;return i===null?t.next=t:(t.next=i.next,i.next=t),r.pending=t,t=Di(e),Ei(e,null,n),t}return Ci(e,r,t,n),Di(e)}function go(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,n&4194048)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,mt(e,n)}}function _o(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var i=null,a=null;if(n=n.firstBaseUpdate,n!==null){do{var o={lane:n.lane,tag:n.tag,payload:n.payload,callback:null,next:null};a===null?i=a=o:a=a.next=o,n=n.next}while(n!==null);a===null?i=a=t:a=a.next=t}else i=a=t;n={baseState:r.baseState,firstBaseUpdate:i,lastBaseUpdate:a,shared:r.shared,callbacks:r.callbacks},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}var vo=!1;function yo(){if(vo){var e=La;if(e!==null)throw e}}function bo(e,t,n,r){vo=!1;var i=e.updateQueue;uo=!1;var a=i.firstBaseUpdate,o=i.lastBaseUpdate,s=i.shared.pending;if(s!==null){i.shared.pending=null;var c=s,l=c.next;c.next=null,o===null?a=l:o.next=l,o=c;var u=e.alternate;u!==null&&(u=u.updateQueue,s=u.lastBaseUpdate,s!==o&&(s===null?u.firstBaseUpdate=l:s.next=l,u.lastBaseUpdate=c))}if(a!==null){var d=i.baseState;o=0,u=l=c=null,s=a;do{var f=s.lane&-536870913,p=f!==s.lane;if(p?(Y&f)===f:(r&f)===f){f!==0&&f===Ia&&(vo=!0),u!==null&&(u=u.next={lane:0,tag:s.tag,payload:s.payload,callback:null,next:null});a:{var m=e,h=s;f=t;var g=n;switch(h.tag){case 1:if(m=h.payload,typeof m==`function`){d=m.call(g,d,f);break a}d=m;break a;case 3:m.flags=m.flags&-65537|128;case 0:if(m=h.payload,f=typeof m==`function`?m.call(g,d,f):m,f==null)break a;d=D({},d,f);break a;case 2:uo=!0}}f=s.callback,f!==null&&(e.flags|=64,p&&(e.flags|=8192),p=i.callbacks,p===null?i.callbacks=[f]:p.push(f))}else p={lane:f,tag:s.tag,payload:s.payload,callback:s.callback,next:null},u===null?(l=u=p,c=d):u=u.next=p,o|=f;if(s=s.next,s===null){if(s=i.shared.pending,s===null)break;p=s,s=p.next,p.next=null,i.lastBaseUpdate=p,i.shared.pending=null}}while(1);u===null&&(c=d),i.baseState=c,i.firstBaseUpdate=l,i.lastBaseUpdate=u,a===null&&(i.shared.lanes=0),od|=o,e.lanes=o,e.memoizedState=d}}function xo(e,t){if(typeof e!=`function`)throw Error(i(191,e));e.call(t)}function So(e,t){var n=e.callbacks;if(n!==null)for(e.callbacks=null,e=0;ea?a:8;var o=F.T,s={};s.types=o===null?null:o.types,F.T=s,cc(e,!1,t,n);try{var c=i(),l=F.S;l!==null&&l(s,c),typeof c==`object`&&c&&typeof c.then==`function`?sc(e,t,Ba(c,r),jd(e)):sc(e,t,r,jd(e))}catch(n){sc(e,t,{then:function(){},status:`rejected`,reason:n},jd())}finally{I.p=a,o!==null&&s.types!==null&&(o.types=s.types),F.T=o}}function Zs(){}function Qs(e,t,n,r){if(e.tag!==5)throw Error(i(476));var a=$s(e).queue;Xs(e,a,t,ge,n===null?Zs:function(){return ec(e),n(r)})}function $s(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:ge,baseState:ge,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:ls,lastRenderedState:ge},next:null};var n={};return t.next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:ls,lastRenderedState:n},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function ec(e){var t=$s(e);t.next===null&&(t=e.alternate.memoizedState),sc(e,t.next.queue,{},jd())}function tc(){return Sa(sh)}function nc(){return is().memoizedState}function rc(){return is().memoizedState}function ic(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var n=jd();e=mo(n);var r=ho(t,e,n);r!==null&&(Pd(r,t,n),go(r,t,n)),t={cache:ka()},e.payload=t;return}t=t.return}}function ac(e,t,n){var r=jd();n={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null},lc(e)?uc(t,n):(n=wi(e,t,n,r),n!==null&&(Pd(n,e,r),dc(n,t,r)))}function oc(e,t,n){sc(e,t,n,jd())}function sc(e,t,n,r){var i={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null};if(lc(e))uc(t,i);else{var a=e.alternate;if(e.lanes===0&&(a===null||a.lanes===0)&&(a=t.lastRenderedReducer,a!==null))try{var o=t.lastRenderedState,s=a(o,n);if(i.hasEagerState=!0,i.eagerState=s,zr(s,o))return Ci(e,t,i,0),$u===null&&Si(),!1}catch{}if(n=wi(e,t,i,r),n!==null)return Pd(n,e,r),dc(n,t,r),!0}return!1}function cc(e,t,n,r){if(r={lane:2,revertLane:Pf(),gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null},lc(e)){if(t)throw Error(i(479))}else t=wi(e,n,r,2),t!==null&&Pd(t,e,2)}function lc(e){var t=e.alternate;return e===W||t!==null&&t===W}function uc(e,t){Ho=Vo=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function dc(e,t,n){if(n&4194048){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,mt(e,n)}}var fc={readContext:Sa,use:ss,useCallback:Jo,useContext:Jo,useEffect:Jo,useImperativeHandle:Jo,useLayoutEffect:Jo,useInsertionEffect:Jo,useMemo:Jo,useReducer:Jo,useRef:Jo,useState:Jo,useDebugValue:Jo,useDeferredValue:Jo,useTransition:Jo,useSyncExternalStore:Jo,useId:Jo,useHostTransitionStatus:Jo,useFormState:Jo,useActionState:Jo,useOptimistic:Jo,useMemoCache:Jo,useCacheRefresh:Jo,useEffectEvent:Jo},pc={readContext:Sa,use:ss,useCallback:function(e,t){return rs().memoizedState=[e,t===void 0?null:t],e},useContext:Sa,useEffect:Ls,useImperativeHandle:function(e,t,n){n=n==null?null:n.concat([e]),Fs(4194308,4,Us.bind(null,t,e),n)},useLayoutEffect:function(e,t){return Fs(4194308,4,e,t)},useInsertionEffect:function(e,t){Fs(4,2,e,t)},useMemo:function(e,t){var n=rs();t=t===void 0?null:t;var r=e();if(Uo){Xe(!0);try{e()}finally{Xe(!1)}}return n.memoizedState=[r,t],r},useReducer:function(e,t,n){var r=rs();if(n!==void 0){var i=n(t);if(Uo){Xe(!0);try{n(t)}finally{Xe(!1)}}}else i=t;return r.memoizedState=r.baseState=i,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:i},r.queue=e,e=e.dispatch=ac.bind(null,W,e),[r.memoizedState,e]},useRef:function(e){var t=rs();return e={current:e},t.memoizedState=e},useState:function(e){e=ys(e);var t=e.queue,n=oc.bind(null,W,t);return t.dispatch=n,[e.memoizedState,n]},useDebugValue:Gs,useDeferredValue:function(e,t){return Js(rs(),e,t)},useTransition:function(){var e=ys(!1);return e=Xs.bind(null,W,e.queue,!0,!1),rs().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var r=W,a=rs();if(U){if(n===void 0)throw Error(i(407));n=n()}else{if(n=t(),$u===null)throw Error(i(349));Y&127||ms(r,t,n)}a.memoizedState=n;var o={value:n,getSnapshot:t};return a.queue=o,Ls(gs.bind(null,r,o,e),[e]),r.flags|=2048,Ns(9,{destroy:void 0},hs.bind(null,r,o,n,t),null),n},useId:function(){var e=rs(),t=$u.identifierPrefix;if(U){var n=Yi,r=Ji;n=(r&~(1<<32-Ze(r)-1)).toString(32)+n,t=`_`+t+`R_`+n,n=Wo++,0<\/script>`,o=o.removeChild(o.firstChild);break;case`select`:o=typeof r.is==`string`?s.createElement(`select`,{is:r.is}):s.createElement(`select`),r.multiple?o.multiple=!0:r.size&&(o.size=r.size);break;default:o=typeof r.is==`string`?s.createElement(a,{is:r.is}):s.createElement(a)}}o[xt]=t,o[St]=r;a:for(s=t.child;s!==null;){if(s.tag===5||s.tag===6)o.appendChild(s.stateNode);else if(s.tag!==4&&s.tag!==27&&s.child!==null){s.child.return=s,s=s.child;continue}if(s===t)break a;for(;s.sibling===null;){if(s.return===null||s.return===t)break a;s=s.return}s.sibling.return=s.return,s=s.sibling}t.stateNode=o;a:switch(np(o,a,r),a){case`button`:case`input`:case`select`:case`textarea`:r=!!r.autoFocus;break a;case`img`:r=!0;break a;default:r=!1}r&&dl(t)}}return gl(t),t.subtreeFlags&=-33554433,fl(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,n),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==r&&dl(t);else{if(typeof r!=`string`&&t.stateNode===null)throw Error(i(166));if(e=Ce.current,ca(t)){if(e=t.stateNode,n=t.memoizedProps,r=null,a=ta,a!==null)switch(a.tag){case 27:case 5:r=a.memoizedProps}e[xt]=t,e=!!(e.nodeValue===n||r!==null&&!0===r.suppressHydrationWarning||ep(e.nodeValue,n)),e||aa(t,!0)}else e=lp(e).createTextNode(r),e[xt]=t,t.stateNode=e}return gl(t),null;case 31:if(n=t.memoizedState,e===null||e.memoizedState!==null){if(r=ca(t),n!==null){if(e===null){if(!r)throw Error(i(318));if(e=t.memoizedState,e=e===null?null:e.dehydrated,!e)throw Error(i(557));e[xt]=t}else la(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;gl(t),e=!1}else n=ua(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),e=!0;if(!e)return t.flags&256?(Po(t),t):(Po(t),null);if(t.flags&128)throw Error(i(558))}return gl(t),null;case 13:if(r=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(a=ca(t),r!==null&&r.dehydrated!==null){if(e===null){if(!a)throw Error(i(318));if(a=t.memoizedState,a=a===null?null:a.dehydrated,!a)throw Error(i(317));a[xt]=t}else la(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;gl(t),a=!1}else a=ua(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=a),a=!0;if(!a)return t.flags&256?(Po(t),t):(Po(t),null)}return Po(t),t.flags&128?(t.lanes=n,t):(n=r!==null,e=e!==null&&e.memoizedState!==null,n&&(r=t.child,a=null,r.alternate!==null&&r.alternate.memoizedState!==null&&r.alternate.memoizedState.cachePool!==null&&(a=r.alternate.memoizedState.cachePool.pool),o=null,r.memoizedState!==null&&r.memoizedState.cachePool!==null&&(o=r.memoizedState.cachePool.pool),o!==a&&(r.flags|=2048)),n!==e&&n&&(t.child.flags|=8192),ml(t,t.updateQueue),gl(t),null);case 4:return Ee(),e===null&&Wf(t.stateNode.containerInfo),t.flags|=67108864,gl(t),null;case 10:return ga(t.type),gl(t),null;case 19:if(Lo(t),r=t.memoizedState,r===null)return gl(t),null;if(a=!!(t.flags&128),o=r.rendering,o===null){if(a)hl(r,!1);else{if(ad!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(o=Ro(e),o!==null){for(t.flags|=128,hl(r,!1),e=o.updateQueue,t.updateQueue=e,ml(t,e),t.subtreeFlags=0,e=n,n=t.child;n!==null;)Ni(n,e),n=n.sibling;return Io(t,Fo.current&1|2),U&&Xi(t,r.treeForkCount),t.child}e=e.sibling}r.tail!==null&&ze()>gd&&(t.flags|=128,a=!0,hl(r,!1),t.lanes=4194304)}}else{if(!a){if(e=Ro(o),e!==null){if(t.flags|=128,a=!0,e=e.updateQueue,t.updateQueue=e,ml(t,e),hl(r,!0),r.tail===null&&r.tailMode!==`collapsed`&&r.tailMode!==`visible`&&!o.alternate&&!U)return gl(t),null}else 2*ze()-r.renderingStartTime>gd&&n!==536870912&&(t.flags|=128,a=!0,hl(r,!1),t.lanes=4194304)}r.isBackwards?(o.sibling=t.child,t.child=o):(e=r.last,e===null?t.child=o:e.sibling=o,r.last=o)}if(r.tail!==null){e=r.tail;a:{for(n=e;n!==null;){if(n.alternate!==null){n=!1;break a}n=n.sibling}n=!0}return r.rendering=e,r.tail=e.sibling,r.renderingStartTime=ze(),e.sibling=null,o=Fo.current,o=a?o&1|2:o&1,r.tailMode===`visible`||r.tailMode===`collapsed`||!n||U?Io(t,o):(n=o,L(Oo,t),L(Fo,n),ko===null&&(ko=t)),U&&Xi(t,r.treeForkCount),e}return gl(t),null;case 22:case 23:return Po(t),Do(),r=t.memoizedState!==null,e===null?r&&(t.flags|=8192):e.memoizedState!==null!==r&&(t.flags|=8192),r?n&536870912&&!(t.flags&128)&&(gl(t),t.subtreeFlags&6&&(t.flags|=8192)):gl(t),n=t.updateQueue,n!==null&&ml(t,n.retryQueue),n=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(n=e.memoizedState.cachePool.pool),r=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(r=t.memoizedState.cachePool.pool),r!==n&&(t.flags|=2048),e!==null&&be(Ha),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),ga(Oa),gl(t),null;case 25:return null;case 30:return t.flags|=33554432,gl(t),null}throw Error(i(156,t.tag))}function vl(e,t){switch($i(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return ga(Oa),Ee(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return Oe(t),null;case 31:if(t.memoizedState!==null){if(Po(t),t.alternate===null)throw Error(i(340));la()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(Po(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(i(340));la()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return Lo(t),e=t.flags,e&65536?(t.flags=e&-65537|128,e=t.memoizedState,e!==null&&(e.rendering=null,e.tail=null),t.flags|=4,t):null;case 4:return Ee(),null;case 10:return ga(t.type),null;case 22:case 23:return Po(t),Do(),e!==null&&be(Ha),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return ga(Oa),null;case 25:return null;default:return null}}function yl(e,t){switch($i(t),t.tag){case 3:ga(Oa),Ee();break;case 26:case 27:case 5:Oe(t);break;case 4:Ee();break;case 31:t.memoizedState!==null&&Po(t);break;case 13:Po(t);break;case 19:Lo(t);break;case 10:ga(t.type);break;case 22:case 23:Po(t),Do(),e!==null&&be(Ha);break;case 24:ga(Oa)}}function bl(e,t){try{var n=t.updateQueue,r=n===null?null:n.lastEffect;if(r!==null){var i=r.next;n=i;do{if((n.tag&e)===e){r=void 0;var a=n.create,o=n.inst;r=a(),o.destroy=r}n=n.next}while(n!==i)}}catch(e){Z(t,t.return,e)}}function xl(e,t,n){try{var r=t.updateQueue,i=r===null?null:r.lastEffect;if(i!==null){var a=i.next;r=a;do{if((r.tag&e)===e){var o=r.inst,s=o.destroy;if(s!==void 0){o.destroy=void 0,i=t;var c=n,l=s;try{l()}catch(e){Z(i,c,e)}}}r=r.next}while(r!==a)}}catch(e){Z(t,t.return,e)}}function Sl(e){var t=e.updateQueue;if(t!==null){var n=e.stateNode;try{So(t,n)}catch(t){Z(e,e.return,t)}}}function Cl(e,t,n){n.props=bc(e.type,e.memoizedProps),n.state=e.memoizedState;try{n.componentWillUnmount()}catch(n){Z(e,t,n)}}function wl(e,t){try{var n=e.ref;if(n!==null){switch(e.tag){case 26:case 27:case 5:var r=e.stateNode;break;case 30:var i=e.stateNode,a=hi(e.memoizedProps,i);(i.ref===null||i.ref.name!==a)&&(i.ref=Pp(a)),r=i.ref;break;case 7:if(e.stateNode===null){var o=new Fp(e);h(e.child,!1,Qp,o,void 0,void 0),e.stateNode=o}r=e.stateNode;break;default:r=e.stateNode}typeof n==`function`?e.refCleanup=n(r):n.current=r}}catch(n){Z(e,t,n)}}function Tl(e,t){var n=e.ref,r=e.refCleanup;if(n!==null){if(typeof r==`function`)try{r()}catch(n){Z(e,t,n)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof n==`function`)try{n(null)}catch(n){Z(e,t,n)}else n.current=null}}function El(e,t){if((e.tag===5||e.tag===27||e.tag===6)&&e.alternate===null&&t!==null)for(var n=0;n title`))),np(r,t,n),r[xt]=e,Pt(r),t=r;break a;case`link`:if(o=Gm(`link`,`href`,a).get(t+(n.href||``))){for(s=0;sg&&(o=g,g=h,h=o);var _=Ur(s,h),v=Ur(s,g);if(_&&v&&(p.rangeCount!==1||p.anchorNode!==_.node||p.anchorOffset!==_.offset||p.focusNode!==v.node||p.focusOffset!==v.offset)){var y=d.createRange();y.setStart(_.node,_.offset),p.removeAllRanges(),h>g?(p.addRange(y),p.extend(v.node,v.offset)):(y.setEnd(v.node,v.offset),p.addRange(y))}}}}for(d=[],p=s;p=p.parentNode;)p.nodeType===1&&d.push({element:p,left:p.scrollLeft,top:p.scrollTop});for(typeof s.focus==`function`&&s.focus(),s=0;sn?32:n,F.T=null,n=wd,wd=null;var o=bd,s=Sd;if(yd=0,xd=bd=null,Sd=0,q&6)throw Error(i(331));var c=q;if(q|=4,Ju(o.current),Bu(o,o.current,s,n),q=c,Df(0,!1),Ye&&typeof Ye.onPostCommitFiberRoot==`function`)try{Ye.onPostCommitFiberRoot(Je,o)}catch{}return!0}finally{I.p=a,F.T=r,uf(e,t)}}function pf(e,t,n){t=Bi(n,t),t=Ec(e.stateNode,t,2),e=ho(e,t,2),e!==null&&(dt(e,2),Ef(e))}function Z(e,t,n){if(e.tag===3)pf(e,e,n);else for(;t!==null;){if(t.tag===3){pf(t,e,n);break}if(t.tag===1){var r=t.stateNode;if(typeof t.type.getDerivedStateFromError==`function`||typeof r.componentDidCatch==`function`&&(vd===null||!vd.has(r))){e=Bi(n,e),n=Dc(2),r=ho(t,n,2),r!==null&&(Oc(n,r,t,e),dt(r,2),Ef(r));break}}t=t.return}}function mf(e,t,n){var r=e.pingCache;if(r===null){r=e.pingCache=new Qu;var i=new Set;r.set(t,i)}else i=r.get(t),i===void 0&&(i=new Set,r.set(t,i));i.has(n)||(rd=!0,i.add(n),e=hf.bind(null,e,t,n),t.then(e,e))}function hf(e,t,n){var r=e.pingCache;r!==null&&r.delete(t),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,$u===e&&(Y&n)===n&&(ad===4||ad===3&&(Y&62914560)===Y&&300>ze()-md?q&2?cd|=n:Vd(e,0):cd|=n,ud===Y&&(ud=0)),Ef(e)}function gf(e,t){t===0&&(t=lt()),e=Ti(e,t),e!==null&&(dt(e,t),Ef(e))}function _f(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),gf(e,n)}function vf(e,t){var n=0;switch(e.tag){case 31:case 13:var r=e.stateNode,a=e.memoizedState;a!==null&&(n=a.retryLane);break;case 19:r=e.stateNode;break;case 22:r=e.stateNode._retryCache;break;default:throw Error(i(314))}r!==null&&r.delete(t),gf(e,n)}function yf(e,t){return Fe(e,t)}var bf=null,xf=null,Sf=!1,Cf=!1,wf=!1,Tf=0;function Ef(e){e!==xf&&e.next===null&&(xf===null?bf=xf=e:xf=xf.next=e),Cf=!0,Sf||(Sf=!0,Nf())}function Df(e,t){if(!wf&&Cf){wf=!0;do for(var n=!1,r=bf;r!==null;){if(!t){if(e!==0){var i=r.pendingLanes;if(i===0)var a=0;else{var o=r.suspendedLanes,s=r.pingedLanes;a=(1<<31-Ze(42|e)+1)-1,a&=i&~(o&~s),a=a&201326741?a&201326741|1:a?a|2:0}a!==0&&(n=!0,Mf(r,a))}else a=Y,a=at(r,r===$u?a:0,r.cancelPendingCommit!==null||r.timeoutHandle!==-1),!(a&3)||ot(r,a)||(n=!0,Mf(r,a))}r=r.next}while(n);wf=!1}}function Of(){kf()}function kf(){Cf=Sf=!1;var e=0;Tf!==0&&hp()&&(e=Tf);for(var t=ze(),n=null,r=bf;r!==null;){var i=r.next,a=Af(r,t);a===0?(r.next=null,n===null?bf=i:n.next=i,i===null&&(xf=n)):(n=r,(e!==0||a&3)&&(Cf=!0)),r=i}yd!==0&&yd!==5||Df(e,!1),Tf!==0&&(Tf=0)}function Af(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,i=e.expirationTimes,a=e.pendingLanes&-62914561;0s)break;var u=c.transferSize,d=c.initiatorType;u&&ap(d)&&(c=c.responseEnd,o+=u*(c$m){s.length=o;break}f=new Promise(jp.bind(f)),s.push(f)}}}if(0`u`?null:document;function Tm(e,t,n){var r=wm;if(r&&typeof t==`string`&&t){var i=en(t);i=`link[rel="`+e+`"][href="`+i+`"]`,typeof n==`string`&&(i+=`[crossorigin="`+n+`"]`),ym.has(i)||(ym.add(i),e={rel:e,crossOrigin:n,href:t},r.querySelector(i)===null&&(t=r.createElement(`link`),np(t,`link`,e),Pt(t),r.head.appendChild(t)))}}function Em(e){xm.D(e),Tm(`dns-prefetch`,e,null)}function Dm(e,t){xm.C(e,t),Tm(`preconnect`,e,t)}function Om(e,t,n){xm.L(e,t,n);var r=wm;if(r&&e&&t){var i=`link[rel="preload"][as="`+en(t)+`"]`;t===`image`&&n&&n.imageSrcSet?(i+=`[imagesrcset="`+en(n.imageSrcSet)+`"]`,typeof n.imageSizes==`string`&&(i+=`[imagesizes="`+en(n.imageSizes)+`"]`)):i+=`[href="`+en(e)+`"]`;var a=i;switch(t){case`style`:a=Pm(e);break;case`script`:a=Rm(e)}if(!(vm.has(a)||(e=D({rel:`preload`,href:t===`image`&&n&&n.imageSrcSet?void 0:e,as:t},n),vm.set(a,e),r.querySelector(i)!==null||t===`style`&&r.querySelector(Fm(a))||t===`script`&&r.querySelector(zm(a))))){var o=r.createElement(`link`);np(o,`link`,e),t===`style`&&(o[kt]=!0,o.onload=o.onerror=function(){Ft(o)}),Pt(o),r.head.appendChild(o)}}}function km(e,t){xm.m(e,t);var n=wm;if(n&&e){var r=t&&typeof t.as==`string`?t.as:`script`,i=`link[rel="modulepreload"][as="`+en(r)+`"][href="`+en(e)+`"]`,a=i;switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:a=Rm(e)}if(!vm.has(a)&&(e=D({rel:`modulepreload`,href:e},t),vm.set(a,e),n.querySelector(i)===null)){switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:if(n.querySelector(zm(a)))return}r=n.createElement(`link`),np(r,`link`,e),Pt(r),n.head.appendChild(r)}}}function Am(e,t,n){xm.S(e,t,n);var r=wm;if(r&&e){var i=B(r).hoistableStyles,a=Pm(e);t||=`default`;var o=i.get(a);if(!o){var s={loading:0,preload:null};if(o=r.querySelector(Fm(a)))s.loading=5;else{e=D({rel:`stylesheet`,href:e,"data-precedence":t},n),(n=vm.get(a))&&Hm(e,n);var c=o=r.createElement(`link`);Pt(c),np(c,`link`,e),c._p=new Promise(function(e,t){c.onload=e,c.onerror=t}),c.addEventListener(`load`,function(){s.loading|=1}),c.addEventListener(`error`,function(){s.loading|=2}),s.loading|=4,Vm(o,t,r)}o={type:`stylesheet`,instance:o,count:1,state:s},i.set(a,o)}}}function jm(e,t){xm.X(e,t);var n=wm;if(n&&e){var r=B(n).hoistableScripts,i=Rm(e),a=r.get(i);a||(a=n.querySelector(zm(i)),a||(e=D({src:e,async:!0},t),(t=vm.get(i))&&Um(e,t),a=n.createElement(`script`),Pt(a),np(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Mm(e,t){xm.M(e,t);var n=wm;if(n&&e){var r=B(n).hoistableScripts,i=Rm(e),a=r.get(i);a||(a=n.querySelector(zm(i)),a||(e=D({src:e,async:!0,type:`module`},t),(t=vm.get(i))&&Um(e,t),a=n.createElement(`script`),Pt(a),np(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Nm(e,t,n,r){var a=(a=Ce.current)?bm(a):null;if(!a)throw Error(i(446));switch(e){case`meta`:case`title`:return null;case`style`:return typeof n.precedence==`string`&&typeof n.href==`string`?(n=Pm(n.href),t=B(a).hoistableStyles,r=t.get(n),r||(r={type:`style`,instance:null,count:0,state:null},t.set(n,r)),r):{type:`void`,instance:null,count:0,state:null};case`link`:if(n.rel===`stylesheet`&&typeof n.href==`string`&&typeof n.precedence==`string`){e=Pm(n.href);var o=B(a).hoistableStyles,s=o.get(e);if(s||(a=a.ownerDocument||a,s={type:`stylesheet`,instance:null,count:0,state:{loading:0,preload:null}},o.set(e,s),(o=a.querySelector(Fm(e)))?o._p||(s.instance=o,s.state.loading=5):(o=vm.get(e),o||(o={rel:`preload`,as:`style`,href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},vm.set(e,o)),Lm(a,e,o,s.state))),t&&r===null)throw Error(i(528,``));return s}if(t&&r!==null)throw Error(i(529,``));return null;case`script`:return t=n.async,n=n.src,typeof n==`string`&&t&&typeof t!=`function`&&typeof t!=`symbol`?(n=Rm(n),t=B(a).hoistableScripts,r=t.get(n),r||(r={type:`script`,instance:null,count:0,state:null},t.set(n,r)),r):{type:`void`,instance:null,count:0,state:null};default:throw Error(i(444,e))}}function Pm(e){return`href="`+en(e)+`"`}function Fm(e){return`link[rel="stylesheet"][`+e+`]`}function Im(e){return D({},e,{"data-precedence":e.precedence,precedence:null})}function Lm(e,t,n,r){if(t=e.querySelector(`link[rel="preload"][as="style"][`+t+`]`)){if(!0!==t[kt]){r.loading=1;return}}else t=e.createElement(`link`),t[kt]=!0,t.onload=t.onerror=Ft.bind(null,t),np(t,`link`,n),Pt(t),e.head.appendChild(t);r.preload=t,t.addEventListener(`load`,function(){return r.loading|=1}),t.addEventListener(`error`,function(){return r.loading|=2})}function Rm(e){return`[src="`+en(e)+`"]`}function zm(e){return`script[async]`+e}function Bm(e,t,n){if(t.count++,t.instance===null)switch(t.type){case`style`:var r=e.querySelector(`style[data-href~="`+en(n.href)+`"]`);if(r)return t.instance=r,Pt(r),r;var a=D({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return r=(e.ownerDocument||e).createElement(`style`),Pt(r),np(r,`style`,a),Vm(r,n.precedence,e),t.instance=r;case`stylesheet`:a=Pm(n.href);var o=e.querySelector(Fm(a));if(o)return t.state.loading|=4,t.instance=o,Pt(o),o;r=Im(n),(a=vm.get(a))&&Hm(r,a),o=(e.ownerDocument||e).createElement(`link`),Pt(o);var s=o;return s._p=new Promise(function(e,t){s.onload=e,s.onerror=t}),np(o,`link`,r),t.state.loading|=4,Vm(o,n.precedence,e),t.instance=o;case`script`:return o=Rm(n.src),(a=e.querySelector(zm(o)))?(t.instance=a,Pt(a),a):(r=n,(a=vm.get(o))&&(r=D({},n),Um(r,a)),e=e.ownerDocument||e,a=e.createElement(`script`),Pt(a),np(a,`link`,r),e.head.appendChild(a),t.instance=a);case`void`:return null;default:throw Error(i(443,t.type))}else t.type===`stylesheet`&&!(t.state.loading&4)&&(r=t.instance,t.state.loading|=4,Vm(r,n.precedence,e));return t.instance}function Vm(e,t,n){for(var r=n.querySelectorAll(`link[rel="stylesheet"][data-precedence],style[data-precedence]`),i=r.length?r[r.length-1]:null,a=i,o=0;o title`):null)}function qm(e,t,n){if(n===1||t.itemProp!=null)return!1;switch(e){case`meta`:case`title`:return!0;case`style`:if(typeof t.precedence!=`string`||typeof t.href!=`string`||t.href===``)break;return!0;case`link`:if(typeof t.rel!=`string`||typeof t.href!=`string`||t.href===``||t.onLoad||t.onError)break;switch(t.rel){case`stylesheet`:return e=t.disabled,typeof t.precedence==`string`&&e==null;default:return!0}case`script`:if(t.async&&typeof t.async!=`function`&&typeof t.async!=`symbol`&&!t.onLoad&&!t.onError&&t.src&&typeof t.src==`string`)return!0}return!1}function Jm(e,t){return e===`img`&&t.src!=null&&t.src!==``&&t.onLoad==null&&t.loading!==`lazy`}function Ym(e){return!(e.type===`stylesheet`&&!(e.state.loading&3))}function Xm(e){return(e.width||100)*(e.height||100)*(typeof devicePixelRatio==`number`?devicePixelRatio:1)*.25}function Zm(e,t){typeof t.decode==`function`&&(e.imgCount++,t.complete||(e.imgBytes+=Xm(t),e.suspenseyImages.push(t)),e=rh.bind(e),t.decode().then(e,e))}function Qm(e,t,n,r){if(n.type===`stylesheet`&&(typeof r.media!=`string`||!1!==matchMedia(r.media).matches)&&!(n.state.loading&4)){if(n.instance===null){var i=Pm(r.href),a=t.querySelector(Fm(i));if(a){t=a._p,typeof t==`object`&&t&&typeof t.then==`function`&&(e.count++,e=nh.bind(e),t.then(e,e)),n.state.loading|=4,n.instance=a,Pt(a);return}a=t.ownerDocument||t,r=Im(r),(i=vm.get(i))&&Hm(r,i),a=a.createElement(`link`),Pt(a);var o=a;o._p=new Promise(function(e,t){o.onload=e,o.onerror=t}),np(a,`link`,r),n.instance=a}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,t),(t=n.state.preload)&&!(n.state.loading&3)&&(e.count++,n=nh.bind(e),t.addEventListener(`load`,n),t.addEventListener(`error`,n))}}var $m=0;function eh(e,t){return e.stylesheets&&e.count===0&&ah(e,e.stylesheets),0$m?50:800)+t);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(r),clearTimeout(i)}}:null}function th(e){if(e.count===0&&(e.imgCount===0||!e.waitingForImages)){if(e.stylesheets)ah(e,e.stylesheets);else if(e.unsuspend){var t=e.unsuspend;e.unsuspend=null,t()}}}function nh(){this.count--,th(this)}function rh(){this.imgCount--,th(this)}var ih=null;function ah(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,ih=new Map,t.forEach(oh,e),ih=null,nh.call(e))}function oh(e,t){if(!(t.state.loading&4)){var n=ih.get(e);if(n)var r=n.get(null);else{n=new Map,ih.set(e,n);for(var i=e.querySelectorAll(`link[data-precedence],style[data-precedence]`),a=0;a{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=h()})),_=c(u(),1),v=g(),y=o((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),b=o(((e,t)=>{t.exports=y()})),x=b(),S={models:(0,x.jsx)(`path`,{d:`M5 6.5A1.5 1.5 0 0 1 6.5 5h4A1.5 1.5 0 0 1 12 6.5v4a1.5 1.5 0 0 1-1.5 1.5h-4A1.5 1.5 0 0 1 5 10.5zm8 0A1.5 1.5 0 0 1 14.5 5h3A1.5 1.5 0 0 1 19 6.5v11a1.5 1.5 0 0 1-1.5 1.5h-3a1.5 1.5 0 0 1-1.5-1.5zm-8 8A1.5 1.5 0 0 1 6.5 13h4a1.5 1.5 0 0 1 1.5 1.5v3a1.5 1.5 0 0 1-1.5 1.5h-4A1.5 1.5 0 0 1 5 17.5z`}),chat:(0,x.jsx)(`path`,{d:`M5.5 7.5A2.5 2.5 0 0 1 8 5h8a2.5 2.5 0 0 1 2.5 2.5v5A2.5 2.5 0 0 1 16 15h-3.7l-3.6 3.2a.7.7 0 0 1-1.2-.52V15A2.5 2.5 0 0 1 5.5 12.5z`}),activity:(0,x.jsx)(`path`,{d:`M4.5 13h3l1.8-5.5 3.2 9 2.1-6.5h4.9`}),settings:(0,x.jsx)(`path`,{d:`M12 8.2a3.8 3.8 0 1 0 0 7.6 3.8 3.8 0 0 0 0-7.6Zm0-3.2v2m0 10v2m7-7h-2M7 12H5m11.95-4.95-1.42 1.42M8.47 15.53l-1.42 1.42m9.9 0-1.42-1.42M8.47 8.47 7.05 7.05`}),gallery:(0,x.jsx)(`path`,{d:`M5 6.5A1.5 1.5 0 0 1 6.5 5h11A1.5 1.5 0 0 1 19 6.5v11a1.5 1.5 0 0 1-1.5 1.5h-11A1.5 1.5 0 0 1 5 17.5zm3 2h8m-8 3h8m-8 3h5`}),command:(0,x.jsx)(`path`,{d:`M8 8.5A2.5 2.5 0 1 1 5.5 6 2.5 2.5 0 0 1 8 8.5Zm0 7A2.5 2.5 0 1 1 5.5 13 2.5 2.5 0 0 1 8 15.5Zm8-7A2.5 2.5 0 1 1 13.5 6 2.5 2.5 0 0 1 16 8.5Zm0 7A2.5 2.5 0 1 1 13.5 13 2.5 2.5 0 0 1 16 15.5Z`}),help:(0,x.jsx)(`path`,{d:`M9.5 9a2.5 2.5 0 1 1 4.4 1.62c-.68.72-1.9 1.18-1.9 2.38v.25m0 3.25h.01M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18Z`}),menu:(0,x.jsx)(`path`,{d:`M5 7h14M5 12h14M5 17h14`}),close:(0,x.jsx)(`path`,{d:`m7 7 10 10M17 7 7 17`}),search:(0,x.jsx)(`path`,{d:`m16.5 16.5 3 3M11 18a7 7 0 1 1 0-14 7 7 0 0 1 0 14Z`}),warning:(0,x.jsx)(`path`,{d:`M12 4.8 21 19H3zm0 5.2v4m0 2.5h.01`}),key:(0,x.jsx)(`path`,{d:`M14.5 9.5A4.5 4.5 0 1 0 11 13.9l2.1 2.1H16v2h2v2h2v-2.9l-4.6-4.6a4.5 4.5 0 0 0-.9-3Z`}),schema:(0,x.jsx)(`path`,{d:`M6 5h7l5 5v9H6zm7 0v5h5M9 13h6M9 16h6M9 10h2`})};function C(e){return(0,x.jsx)(`svg`,{className:e.className??`ds-icon`,"aria-hidden":`true`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`1.8`,strokeLinecap:`round`,strokeLinejoin:`round`,children:S[e.name]})}var w=(0,_.forwardRef)(function({children:e,onClick:t,onDoubleClick:n,onMouseDown:r,onMouseEnter:i,onKeyDown:a,type:o=`button`,disabled:s=!1,variant:c=`secondary`,size:l=`medium`,shape:u=`default`,fullWidth:d=!1,icon:f,iconPosition:p=`left`,iconOnly:m=!1,inline:h=!1,loading:g=!1,active:v=!1,ariaLabel:y,title:b,role:S,id:C,tabIndex:w,className:T=``,style:E,"aria-pressed":D,"aria-checked":O,"aria-selected":k,"aria-expanded":ee,"aria-haspopup":A,"aria-controls":te,"aria-describedby":ne,"aria-busy":j,"data-testid":M},re){let ie=(0,_.useCallback)(e=>{!s&&!g&&t&&t(e)},[s,g,t]),ae=[`button`,`button--${c}`,`button--${l}`,u!=="default"&&`button--${u}`,d&&`button--full-width`,m&&`button--icon-only`,h&&`button--inline`,g&&`button--loading`,v&&`button--active`,T].filter(Boolean).join(` `),oe=f??(m?e:void 0),se=!m&&e,ce=oe&&!g;return(0,x.jsxs)(`button`,{ref:re,type:o,onClick:ie,onDoubleClick:n,onMouseDown:r,onMouseEnter:i,onKeyDown:a,disabled:s||g,className:ae,"aria-label":y??(m&&typeof e==`string`?e:void 0),title:b,role:S,id:C,tabIndex:w,style:E,"aria-pressed":D,"aria-checked":O,"aria-selected":k,"aria-expanded":ee,"aria-haspopup":A,"aria-controls":te,"aria-describedby":ne,"aria-busy":j,"data-testid":M,children:[g&&(0,x.jsx)(`span`,{className:`button__loading-spinner`,"aria-hidden":`true`}),ce&&p===`left`&&(0,x.jsx)(`span`,{className:`button__icon`,"aria-hidden":`true`,children:oe}),se&&(h?e:(0,x.jsx)(`span`,{className:`button__text`,children:e})),ce&&p===`right`&&(0,x.jsx)(`span`,{className:`button__icon`,"aria-hidden":`true`,children:oe})]})});function T({children:e,variant:t=`default`,size:n=`small`,className:r=``}){let i=[`badge`,`badge--${t}`,`badge--${n}`,r].filter(Boolean).join(` `);return(0,x.jsx)(`span`,{className:i,children:e})}function E(e){switch(e){case`running`:return`success`;case`preparing`:return`info`;case`idle`:return`default`;case`busy`:return`primary`;case`stopping`:return`warning`;case`terminated`:return`default`;case`error`:return`danger`}}function D(e){return e===`preparing`||e===`stopping`||e===`busy`}function O({state:e,label:t,size:n=`small`,pulse:r,className:i=``}){let a=r??D(e),o=[`status-tag`,`status-tag--${e}`,i].filter(Boolean).join(` `);return(0,x.jsxs)(T,{variant:E(e),size:n,className:o,children:[a&&(0,x.jsx)(`span`,{className:`status-tag__indicator`,"aria-hidden":`true`,"data-testid":`status-tag-indicator`}),(0,x.jsx)(`span`,{className:`status-tag__label`,children:t})]})}var k=(0,_.memo)(O);function ee({value:e,variant:t=`primary`,size:n=`md`,showLabel:r=!1,label:i,className:a=``,animated:o=!0,ariaLabel:s}){let c=e===null,l=e===null?0:Math.max(0,Math.min(100,e)),u=[`progress-bar`,`progress-bar--${t}`,`progress-bar--${n}`,c?`progress-bar--indeterminate`:``,o?`progress-bar--animated`:``,a].filter(Boolean).join(` `),d=i??(r&&!c?`${l.toFixed(0)}%`:null);return(0,x.jsxs)(`div`,{className:`progress-bar-wrapper`,children:[(0,x.jsx)(`div`,{className:u,role:`progressbar`,"aria-valuenow":c?void 0:l,"aria-valuemin":0,"aria-valuemax":100,"aria-label":s,"aria-busy":c,children:(0,x.jsx)(`div`,{className:`progress-bar__fill`,style:c?void 0:{width:`${String(l)}%`}})}),d&&(0,x.jsx)(`span`,{className:`progress-bar__label`,children:d})]})}function A({illustration:e,title:t,description:n,primaryAction:r,secondaryAction:i,children:a,className:o=``,showIllustration:s=!0}){let c=r?.onClick,l=i?.onClick,u=(0,_.useCallback)(()=>{c?.()},[c]),d=(0,_.useCallback)(()=>{l?.()},[l]),f=(0,_.useMemo)(()=>[`empty-state`,o].filter(Boolean).join(` `),[o]);return(0,x.jsxs)(`div`,{className:f,role:`status`,"aria-live":`polite`,children:[s&&e&&(0,x.jsx)(`div`,{className:`empty-state__illustration`,children:e}),(0,x.jsxs)(`div`,{className:`empty-state__content`,children:[(0,x.jsx)(`h3`,{className:`empty-state__title`,children:t}),(0,x.jsx)(`p`,{className:`empty-state__description`,children:n}),a]}),(r||i)&&(0,x.jsxs)(`div`,{className:`empty-state__actions`,children:[r&&(0,x.jsx)(w,{variant:`primary`,onClick:u,className:`empty-state__action-btn empty-state__action-btn--primary`,children:r.label}),i&&(0,x.jsx)(x.Fragment,{children:i.href?(0,x.jsx)(`a`,{href:i.href,className:`empty-state__action-link`,onClick:d,children:i.label}):(0,x.jsx)(w,{variant:`ghost`,onClick:d,className:`empty-state__action-btn empty-state__action-btn--secondary`,children:i.label})})]})]})}var te=(0,_.memo)(A);function ne({tabs:e,groups:t=[],defaultTab:n,activeTab:r,onTabChange:i,className:a=``,panelClassName:o=``,ariaLabel:s,showOverflowControls:c=!0,showGroupLabels:l=!0,overflowMode:u,variant:d=`underlined`,fillContainer:f=!1,renderPanel:p=!0,moreTabsLabel:m=`More tabs`,selectTabLabel:h=`Select tab`,scrollLeftLabel:g=`Scroll left`,scrollRightLabel:v=`Scroll right`}){let y=u??(t.length>0?`menu`:`dropdown`),[b,S]=(0,_.useState)(n||e[0]?.id||``),[C,w]=(0,_.useState)(!1),[T,E]=(0,_.useState)(!1),[D,O]=(0,_.useState)(!1),[k,ee]=(0,_.useState)(!1),[A,te]=(0,_.useState)(!1),[ne,j]=(0,_.useState)(-1),M=(0,_.useRef)(null),re=(0,_.useRef)(new Map),ie=(0,_.useRef)(null),ae=(0,_.useRef)(null),oe=(0,_.useRef)(null),se=(0,_.useRef)([]),ce=(0,_.useRef)(null),le=(0,_.useRef)(0),N=(0,_.useRef)(0),P=r??b,ue=(0,_.useMemo)(()=>t.length>0?t.map(t=>({group:t,tabs:e.filter(e=>e.groupId===t.id)})):[{group:null,tabs:e}],[t,e]),de=(0,_.useMemo)(()=>ue.flatMap(({tabs:e})=>e),[ue]),fe=(0,_.useCallback)(e=>{r||S(e),i?.(e),te(!1)},[r,i]),pe=(0,_.useCallback)((t,n)=>{let r;switch(t.key){case`ArrowRight`:t.preventDefault(),r=n===e.length-1?0:n+1;break;case`ArrowLeft`:t.preventDefault(),r=n===0?e.length-1:n-1;break;case`Home`:t.preventDefault(),r=0;break;case`End`:t.preventDefault(),r=e.length-1;break;default:return}let i=e[r];i&&(fe(i.id),re.current.get(i.id)?.focus())},[e,fe]),me=(0,_.useCallback)((e,t)=>{t?re.current.set(e,t):re.current.delete(e)},[]),he=(0,_.useCallback)(()=>{let e=M.current;if(!e||!c){w(!1),E(!1);return}let{scrollLeft:t,scrollWidth:n,clientWidth:r}=e;w(t>0),E(t+r{let t=M.current;if(!t)return;let n=t.clientWidth*.75;t.scrollBy({left:e===`left`?-n:n,behavior:`smooth`}),ce.current!==null&&clearTimeout(ce.current),ce.current=setTimeout(he,300)},[he]),I=(0,_.useCallback)(()=>{if(!M.current||D)return;let e=re.current.get(P);if(!e)return;let t=M.current,n=e.getBoundingClientRect(),r=t.getBoundingClientRect();n.leftr.right&&(t.scrollLeft+=n.right-r.right+8)},[P,D]),ge=(0,_.useCallback)(()=>{typeof window>`u`||y!==`dropdown`||O(window.innerWidth<480)},[y]),_e=(0,_.useCallback)(()=>{ee(e=>!e)},[]),ve=(0,_.useCallback)(e=>{e.key===`Escape`&&k&&(e.preventDefault(),ee(!1))},[k]),ye=(0,_.useCallback)(e=>{e.touches[0]&&(le.current=e.touches[0].clientX)},[]),be=(0,_.useCallback)(e=>{e.touches[0]&&(N.current=e.touches[0].clientX)},[]),L=(0,_.useCallback)(()=>{if(!le.current||!N.current)return;let t=le.current-N.current;if(Math.abs(t)>50){let n=e.findIndex(e=>e.id===P),r=e[n+1],i=e[n-1];t>0&&r?fe(r.id):t<0&&i&&fe(i.id)}le.current=0,N.current=0},[P,e,fe]),xe=(0,_.useCallback)(e=>{let t=de.length;switch(e.key){case`Escape`:e.preventDefault(),te(!1),j(-1),oe.current?.focus();break;case`ArrowDown`:e.preventDefault(),j(e=>{let n=e>=t-1?0:e+1;return se.current[n]?.focus(),n});break;case`ArrowUp`:e.preventDefault(),j(e=>{let n=e<=0?t-1:e-1;return se.current[n]?.focus(),n});break;case`Home`:e.preventDefault(),j(0),se.current[0]?.focus();break;case`End`:e.preventDefault(),j(t-1),se.current[t-1]?.focus()}},[de.length]),Se=(0,_.useCallback)(e=>{e.key===`Escape`&&A&&(e.preventDefault(),te(!1),j(-1))},[A]);(0,_.useEffect)(()=>{if(!k)return;let e=e=>{ie.current&&!ie.current.contains(e.target)&&ee(!1)};return document.addEventListener(`mousedown`,e),()=>{document.removeEventListener(`mousedown`,e)}},[k]),(0,_.useEffect)(()=>{if(!A)return;let e=e=>{ae.current&&!ae.current.contains(e.target)&&(te(!1),j(-1))},t=e=>{e.key===`Escape`&&(te(!1),j(-1),oe.current?.focus())};return document.addEventListener(`mousedown`,e),document.addEventListener(`keydown`,t),()=>{document.removeEventListener(`mousedown`,e),document.removeEventListener(`keydown`,t)}},[A]),(0,_.useEffect)(()=>{if(A&&se.current.length>0){let e=de.findIndex(e=>e.id===P),t=e>=0?e:0;j(t),requestAnimationFrame(()=>{se.current[t]?.focus()})}},[A,de,P]),(0,_.useEffect)(()=>{if(!e.find(e=>e.id===P)){let t=e[0];t&&fe(t.id)}},[e,P,fe]),(0,_.useEffect)(()=>{ge(),he();let e=()=>{ge(),he()};return window.addEventListener(`resize`,e),()=>{window.removeEventListener(`resize`,e)}},[ge,he]),(0,_.useEffect)(()=>{I()},[P,I]),(0,_.useEffect)(()=>{he()},[e,he]),(0,_.useEffect)(()=>()=>{ce.current!==null&&clearTimeout(ce.current)},[]);let Ce=e.find(e=>e.id===P)?.content,we=e.find(e=>e.id===P)?.label,Te=t.length>0;se.current=[];let Ee=(e,t)=>{let n=e.id===P;return(0,x.jsxs)(`button`,{ref:t=>{me(e.id,t)},role:`tab`,"aria-selected":n,"aria-controls":p?`tabpanel-${e.id}`:void 0,id:`tab-${e.id}`,tabIndex:n?0:-1,className:`tabs__tab${n?` tabs__tab--active`:``}`,onClick:()=>{fe(e.id)},onKeyDown:e=>{pe(e,t),(e.key===`ArrowLeft`||e.key===`ArrowRight`||e.key===`Home`||e.key===`End`)&&e.stopPropagation()},children:[e.labelPrefix,(0,x.jsx)(`span`,{className:`tabs__tab-label`,children:e.label}),e.labelExtra]},e.id)},De=()=>Te?ue.map(({group:t,tabs:n},r)=>(0,x.jsxs)(`div`,{className:`tabs__group`,children:[t&&(0,x.jsxs)(x.Fragment,{children:[r>0&&(0,x.jsx)(`div`,{className:`tabs__separator`,role:`separator`,"aria-hidden":`true`}),l&&(0,x.jsx)(`span`,{className:`tabs__group-label`,children:t.label})]}),(0,x.jsx)(`div`,{className:`tabs__group-tabs`,children:n.map(t=>{let n=e.findIndex(e=>e.id===t.id);return Ee(t,n)})})]},t?.id||`default`)):e.map((e,t)=>Ee(e,t)),Oe=()=>y!==`menu`||!c?null:(0,x.jsxs)(`div`,{className:`tabs__overflow`,ref:ae,children:[(0,x.jsx)(`button`,{ref:oe,type:`button`,className:`tabs__overflow-btn`,onClick:()=>{te(!A)},onKeyDown:Se,"aria-label":m,"aria-expanded":A,"aria-haspopup":`menu`,children:(0,x.jsxs)(`svg`,{width:`20`,height:`20`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,x.jsx)(`circle`,{cx:`12`,cy:`12`,r:`1`}),(0,x.jsx)(`circle`,{cx:`12`,cy:`5`,r:`1`}),(0,x.jsx)(`circle`,{cx:`12`,cy:`19`,r:`1`})]})}),A&&(0,x.jsx)(`div`,{className:`tabs__overflow-menu`,role:`menu`,onKeyDown:xe,children:ue.map(({group:e,tabs:t})=>(0,x.jsxs)(`div`,{className:`tabs__overflow-group`,children:[e&&l&&(0,x.jsx)(`div`,{className:`tabs__overflow-group-label`,children:e.label}),t.map(e=>{let t=e.id===P,n=de.findIndex(t=>t.id===e.id);return(0,x.jsxs)(`button`,{ref:e=>{e&&(se.current[n]=e)},role:`menuitem`,tabIndex:ne===n?0:-1,className:`tabs__overflow-item ${t?`tabs__overflow-item--active`:``}`,onClick:()=>{fe(e.id)},children:[e.labelPrefix,(0,x.jsx)(`span`,{children:e.label}),e.labelExtra]},e.id)})]},e?.id||`default`))})]}),ke=d===`segmented`||d===`compact`;return y===`dropdown`&&D&&!ke?(0,x.jsxs)(`div`,{className:`tabs tabs--mobile-dropdown ${a}`,children:[(0,x.jsxs)(`div`,{className:`tabs__dropdown-container`,ref:ie,children:[(0,x.jsxs)(`button`,{className:`tabs__dropdown-trigger`,onClick:_e,onKeyDown:ve,"aria-expanded":k,"aria-haspopup":`listbox`,"aria-label":s||h,children:[(0,x.jsx)(`span`,{className:`tabs__dropdown-label`,children:we}),(0,x.jsx)(`svg`,{className:`tabs__dropdown-arrow ${k?`tabs__dropdown-arrow--open`:``}`,width:`16`,height:`16`,viewBox:`0 0 16 16`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,"aria-hidden":`true`,children:(0,x.jsx)(`path`,{d:`M4 6L8 10L12 6`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`})})]}),k&&(0,x.jsx)(`div`,{className:`tabs__dropdown-menu`,role:`listbox`,children:e.map(e=>(0,x.jsx)(`button`,{role:`option`,"aria-selected":e.id===P,className:`tabs__dropdown-item ${e.id===P?`tabs__dropdown-item--active`:``}`,onClick:()=>{fe(e.id),ee(!1)},children:e.label},e.id))})]}),p&&(0,x.jsx)(`div`,{id:`tabpanel-${P}`,role:`tabpanel`,"aria-labelledby":`tab-${P}`,className:`tabs__panel ${o}`.trim(),tabIndex:0,onTouchStart:ye,onTouchMove:be,onTouchEnd:L,children:Ce})]}):(0,x.jsxs)(`div`,{className:`tabs ${y===`menu`?`tabs--overflow-menu`:``} ${d===`segmented`?`tabs--variant-segmented`:d===`compact`?`tabs--variant-compact`:``} ${ke&&f?`tabs--fill-container`:``} ${a}`.replace(/\s+/g,` `).trim(),children:[(0,x.jsxs)(`div`,{className:`tabs__container`,children:[c&&C&&(0,x.jsx)(`button`,{className:`tabs__scroll-arrow tabs__scroll-arrow--left`,onClick:()=>{F(`left`)},"aria-label":g,tabIndex:-1,children:(0,x.jsx)(`svg`,{width:`20`,height:`20`,viewBox:`0 0 20 20`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,"aria-hidden":`true`,children:(0,x.jsx)(`path`,{d:`M12 15L7 10L12 5`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`})})}),(0,x.jsx)(`div`,{ref:M,className:`tabs__list`,role:`tablist`,"aria-label":s,onScroll:he,onKeyDown:t=>{let n=e.findIndex(e=>e.id===P);n<0||pe(t,n)},onTouchStart:y===`dropdown`?ye:void 0,onTouchMove:y===`dropdown`?be:void 0,onTouchEnd:y===`dropdown`?L:void 0,children:De()}),c&&T&&(0,x.jsx)(`button`,{className:`tabs__scroll-arrow tabs__scroll-arrow--right`,onClick:()=>{F(`right`)},"aria-label":v,tabIndex:-1,children:(0,x.jsx)(`svg`,{width:`20`,height:`20`,viewBox:`0 0 20 20`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,"aria-hidden":`true`,children:(0,x.jsx)(`path`,{d:`M8 5L13 10L8 15`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`})})}),Oe()]}),p&&(0,x.jsx)(`div`,{id:`tabpanel-${P}`,role:`tabpanel`,"aria-labelledby":`tab-${P}`,className:`tabs__panel ${o}`.trim(),tabIndex:0,children:Ce})]})}var j=[`a`,`button`,`input`,`select`,`textarea`,`summary`,`label`,`[contenteditable='true']`,`[role='button']`,`[role='link']`,`[tabindex]:not([tabindex='-1'])`].join(`,`);function M(e,t){if(!(e instanceof Element)||!(t instanceof Element))return!1;let n=e.closest(j);return n!==null&&n!==t&&t.contains(n)}var re={widths:{},visibility:{}};function ie(e,t){let n=e.map((e,t)=>({row:e,i:t}));return n.sort((e,n)=>{let r=t(e.row,n.row);return r===0?e.i-n.i:r}),n.map(({row:e})=>e)}function ae(e,t){let{sortComparator:n}=e;if(n)return(e,r)=>n(e,r,t);let r=e.sortValueAccessor;return r?(e,n)=>{let i=r(e),a=r(n);if(i==null&&a==null)return 0;if(i==null)return 1;if(a==null)return-1;let o;return o=typeof i==`number`&&typeof a==`number`?i-a:String(i).localeCompare(String(a)),t===`asc`?o:-o}:()=>0}function oe(e,t,n){if(e.sortable)return e.id===t?n===`asc`?`ascending`:`descending`:`none`}function se({direction:e}){return e===`none`?(0,x.jsx)(`span`,{className:`data-table__sort-icon data-table__sort-icon--none`,"aria-hidden":`true`,children:(0,x.jsxs)(`svg`,{width:`10`,height:`14`,viewBox:`0 0 10 14`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,children:[(0,x.jsx)(`path`,{d:`M5 1L1 5H9L5 1Z`,fill:`currentColor`,opacity:`0.35`}),(0,x.jsx)(`path`,{d:`M5 13L9 9H1L5 13Z`,fill:`currentColor`,opacity:`0.35`})]})}):e===`asc`?(0,x.jsx)(`span`,{className:`data-table__sort-icon data-table__sort-icon--asc`,"aria-hidden":`true`,children:(0,x.jsxs)(`svg`,{width:`10`,height:`14`,viewBox:`0 0 10 14`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,children:[(0,x.jsx)(`path`,{d:`M5 1L1 5H9L5 1Z`,fill:`currentColor`}),(0,x.jsx)(`path`,{d:`M5 13L9 9H1L5 13Z`,fill:`currentColor`,opacity:`0.25`})]})}):(0,x.jsx)(`span`,{className:`data-table__sort-icon data-table__sort-icon--desc`,"aria-hidden":`true`,children:(0,x.jsxs)(`svg`,{width:`10`,height:`14`,viewBox:`0 0 10 14`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,children:[(0,x.jsx)(`path`,{d:`M5 1L1 5H9L5 1Z`,fill:`currentColor`,opacity:`0.25`}),(0,x.jsx)(`path`,{d:`M5 13L9 9H1L5 13Z`,fill:`currentColor`})]})})}function ce({columns:e,rows:t,getRowKey:n,emptyState:r,loadingState:i,loading:a=!1,columnState:o,onColumnStateChange:s,className:c=``,ariaLabel:l=`Data table`,testId:u,onRowClick:d,isRowClickable:f,rowClassName:p,sortColumnId:m,sortDirection:h,onSortChange:g}){let[v,y]=(0,_.useState)(()=>o??re);(0,_.useEffect)(()=>{o&&y(o)},[o]);let b=m!==void 0||h!==void 0,[S,C]=(0,_.useState)(void 0),[w,T]=(0,_.useState)(void 0),E=b?m:S,D=b?h:w,O=(0,_.useCallback)(e=>{if(!e.sortable)return;let t,n;E===e.id?D===(e.defaultSortDirection??`asc`)?(t=e.id,n=D===`asc`?`desc`:`asc`):(t=void 0,n=void 0):(t=e.id,n=e.defaultSortDirection??`asc`),b||(C(t),T(n)),g?.(t,n)},[E,D,b,g]),k=(0,_.useMemo)(()=>e.filter(e=>e.alwaysVisible?!0:v.visibility[e.id]!==!1),[e,v.visibility]),ee=(0,_.useCallback)(e=>{let t=v.widths[e.id];return typeof t==`number`&&t>0?t:e.initialWidth},[v.widths]),A=(0,_.useRef)(null),te=(0,_.useCallback)((e,t,n)=>{if(t.noResize)return;e.preventDefault(),e.stopPropagation(),A.current={columnId:t.id,startX:e.clientX,startWidth:n,minWidth:t.minWidth??80};let r=e=>{let t=A.current;if(!t)return;let n=e.clientX-t.startX,r=Math.max(t.minWidth,t.startWidth+n);y(e=>({...e,widths:{...e.widths,[t.columnId]:r}}))},i=()=>{A.current=null,window.removeEventListener(`mousemove`,r),window.removeEventListener(`mouseup`,i)};window.addEventListener(`mousemove`,r),window.addEventListener(`mouseup`,i)},[]),ne=(0,_.useRef)(v);(0,_.useEffect)(()=>{ne.current!==v&&(ne.current=v,s?.(v))},[v,s]);let j=(0,_.useMemo)(()=>{if(!E||!D)return t;let n=e.find(e=>e.id===E);return n?.sortable?ie(t,ae(n,D)):t},[t,e,E,D]),ce=[`data-table`,c].filter(Boolean).join(` `);return(0,x.jsx)(`div`,{className:ce,"data-testid":u,children:(0,x.jsxs)(`table`,{className:`data-table__table`,"aria-label":l,role:`table`,children:[(0,x.jsx)(`thead`,{className:`data-table__head`,children:(0,x.jsx)(`tr`,{className:`data-table__row data-table__row--head`,children:k.map(e=>{let t=ee(e),n=e.sortable&&e.id===E;return(0,x.jsxs)(`th`,{scope:`col`,className:[`data-table__cell`,`data-table__cell--head`,e.sortable&&`data-table__cell--sortable`,n&&`data-table__cell--sort-active`,e.className,e.align&&`data-table__cell--align-${e.align}`].filter(Boolean).join(` `),style:t?{width:`${String(t)}px`}:void 0,"aria-sort":oe(e,E,D),onClick:e.sortable?()=>{O(e)}:void 0,onKeyDown:e.sortable?t=>{(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),O(e))}:void 0,tabIndex:e.sortable?0:void 0,children:[(0,x.jsx)(`span`,{className:`data-table__head-label`,children:e.header}),e.sortable&&(0,x.jsx)(se,{direction:n&&D?D:`none`}),!e.noResize&&(0,x.jsx)(`div`,{role:`separator`,"aria-orientation":`vertical`,className:`data-table__resize-handle`,onMouseDown:n=>{te(n,e,t??e.minWidth??120)}})]},e.id)})})}),(0,x.jsx)(`tbody`,{className:`data-table__body`,children:a?(0,x.jsx)(`tr`,{className:`data-table__row data-table__row--state`,children:(0,x.jsx)(`td`,{colSpan:k.length||1,className:`data-table__state-cell`,children:i??(0,x.jsx)(`div`,{className:`data-table__loading`})})}):j.length===0?(0,x.jsx)(`tr`,{className:`data-table__row data-table__row--state`,children:(0,x.jsx)(`td`,{colSpan:k.length||1,className:`data-table__state-cell`,children:r})}):j.map((e,t)=>{let r=n(e,t),i=!!(d&&(f?.(e,t)??!0)),a=p?.(e,t);return(0,x.jsx)(`tr`,{className:[`data-table__row`,i&&`data-table__row--clickable`,a].filter(Boolean).join(` `),onClick:i?t=>{M(t.target,t.currentTarget)||d?.(e)}:void 0,onKeyDown:i?t=>{(t.key===`Enter`||t.key===` `)&&(M(t.target,t.currentTarget)||(t.preventDefault(),d?.(e)))}:void 0,tabIndex:i?0:void 0,role:i?`button`:void 0,children:k.map(n=>(0,x.jsx)(`td`,{className:[`data-table__cell`,n.className,n.align&&`data-table__cell--align-${n.align}`].filter(Boolean).join(` `),children:n.render(e,t)},n.id))},r)})})]})})}var le=(0,_.memo)(ce),N=(0,_.forwardRef)(function({tone:e=`secondary`,busy:t=!1,className:n=``,children:r,"aria-label":i,...a},o){return(0,x.jsx)(w,{...a,ref:o,inline:!0,variant:e,loading:t,"aria-busy":t||a[`aria-busy`],ariaLabel:i,className:`ds-button ds-button-${e} ${n}`.trim(),children:(0,x.jsx)(`span`,{children:r})})}),P=(0,_.forwardRef)(function({label:e,icon:t,busy:n=!1,className:r=``,...i},a){return(0,x.jsx)(w,{...i,ref:a,inline:!0,iconOnly:!0,icon:(0,x.jsx)(C,{name:t}),ariaLabel:e,title:i.title??e,variant:`secondary`,loading:n,"aria-busy":n||i[`aria-busy`],className:`ds-icon-button ${r}`.trim()})}),ue={unloaded:`terminated`,loading:`preparing`,ready:`running`,draining:`stopping`,unloading:`stopping`,failed:`error`};function de(e){return(0,x.jsx)(`span`,{className:`ds-status-wrap`,"data-state":e.state,"aria-label":e.label,children:(0,x.jsx)(k,{state:ue[e.state],label:e.children,pulse:!1,className:`ds-status`})})}function fe(e){let t=e.value===void 0||!Number.isFinite(e.value)?null:Math.max(0,Math.min(100,e.value));return(0,x.jsxs)(`div`,{className:`ds-progress`,children:[(0,x.jsx)(ee,{value:t,ariaLabel:e.label,animated:!1}),e.detail?(0,x.jsx)(`small`,{children:e.detail}):null]})}function pe(e){return(0,x.jsx)(`section`,{className:`ds-empty`,"data-testid":e.testId,ref:e=>{let t=e?.querySelector(`.empty-state__title`);t?.setAttribute(`role`,`heading`),t?.setAttribute(`aria-level`,`2`)},children:(0,x.jsx)(te,{title:e.title,description:e.body,illustration:(0,x.jsx)(C,{name:`models`}),children:e.action})})}function me(e){let t=(0,_.useId)();if(e.tabs.length===0)return(0,x.jsx)(`section`,{className:`ds-tabs`});let n=e.tabs.map(e=>({id:`${t}-${e.id}`,label:e.label,content:e.panel})),r=e.tabs.find(t=>t.id===e.active)??e.tabs[0];return(0,x.jsx)(`section`,{onKeyDownCapture:e=>{e.nativeEvent.isComposing&&e.stopPropagation()},children:(0,x.jsx)(ne,{className:`ds-tabs`,tabs:n,activeTab:`${t}-${r.id}`,onTabChange:n=>{let r=e.tabs.find(e=>`${t}-${e.id}`===n);r&&e.onChange(r.id)},ariaLabel:e.label??`Sections`,variant:`segmented`,fillContainer:!0,overflowMode:`menu`,showOverflowControls:!1,showGroupLabels:!1})})}var he=`ds-row-primary`,F=`a[href], button, input, select, textarea, summary, label, [contenteditable="true"], [role="button"], [role="link"], [tabindex]:not([tabindex="-1"])`;function I(e){if(e.defaultPrevented||e.button!==0||!(e.target instanceof Element))return;let t=e.target.closest(`tbody > tr`);if(!t||!e.currentTarget.contains(t)||t.classList.contains(`data-table__row--state`))return;let n=t.querySelector(`.${he}`);if(!n||n.matches(`:disabled, [aria-disabled="true"]`))return;let r=e.target.closest(F);if(r&&t.contains(r))return;let i=window.getSelection();(!i||i.isCollapsed||i.toString().trim()===``||!t.contains(i.anchorNode)&&!t.contains(i.focusNode))&&(n.focus({preventScroll:!0}),n.click())}function ge({activateRowPrimary:e=!1,...t}){let n=(0,x.jsx)(le,{...t,className:`ds-common-table ${t.className??``}`.trim()});return e?(0,x.jsx)(`div`,{className:`ds-row-activation`,onClick:I,children:n}):n}function _e({className:e,style:t,size:n}){let r=n??`1em`;return(0,x.jsx)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,width:r,height:r,fill:`none`,viewBox:`0 0 24 24`,strokeWidth:1.5,stroke:`currentColor`,className:e,style:t,"aria-hidden":`true`,children:(0,x.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M12 9v3.75m9-.75a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 3.75h.008v.008H12v-.008Z`})})}function ve({tone:e=`danger`,icon:t,title:n,message:r,primaryAction:i,secondaryAction:a,className:o=``,showIcon:s=!0}){let c=(0,_.useCallback)(()=>{i?.onClick()},[i]),l=(0,_.useCallback)(()=>{a?.onClick()},[a]),u=[`error-state`,`error-state--${e}`,o].filter(Boolean).join(` `);return(0,x.jsxs)(`div`,{className:u,role:`alert`,"aria-live":`polite`,children:[s&&(0,x.jsx)(`div`,{className:`error-state__icon`,"aria-hidden":`true`,children:t??(0,x.jsx)(_e,{size:48})}),(0,x.jsx)(`h2`,{className:`error-state__title`,children:n}),(0,x.jsx)(`p`,{className:`error-state__message`,children:r}),(i||a)&&(0,x.jsxs)(`div`,{className:`error-state__actions`,children:[i&&(0,x.jsx)(w,{variant:`primary`,onClick:c,className:`error-state__action-btn error-state__action-btn--primary`,children:i.label}),a&&(0,x.jsx)(w,{variant:`secondary`,onClick:l,className:`error-state__action-btn error-state__action-btn--secondary`,children:a.label})]})]})}function ye({width:e=`100%`,height:t=`20px`,variant:n=`rect`,className:r=``,testId:i,loadingLabel:a=`Loading`,decorative:o=!1}){let s=[`skeleton`,`skeleton--${n}`,r].filter(Boolean).join(` `);return(0,x.jsx)(`div`,{className:s,style:{width:e,height:t},...o?{"aria-hidden":!0}:{role:`status`,"aria-busy":!0,"aria-label":a},"data-testid":i,children:(0,x.jsx)(`span`,{className:`skeleton__shimmer`})})}var be={error:`danger`,warning:`warning`,info:`accent`};function L(e){let t=e.tone??`error`;return(0,x.jsxs)(`section`,{className:`ds-banner`,"data-tone":t,role:t===`info`?`status`:`alert`,"data-testid":e.testId,ref:e=>{let t=e?.querySelector(`.error-state`);t?.removeAttribute(`role`),t?.removeAttribute(`aria-live`),e?.querySelector(`.error-state__title`)?.setAttribute(`role`,`none`)},children:[(0,x.jsx)(ve,{tone:be[t],title:e.title,message:e.body,showIcon:!1}),e.action]})}function xe(e){return(0,x.jsxs)(`div`,{className:`ds-loading`,role:`status`,children:[(0,x.jsx)(`p`,{className:`ds-loading__label`,children:e.label}),(0,x.jsx)(`div`,{className:`ds-loading__shapes`,"aria-hidden":`true`,children:Array.from({length:e.rows??3},(e,t)=>(0,x.jsx)(ye,{decorative:!0,width:`100%`,height:`20px`},t))})]})}var Se=(0,_.createContext)(!1),Ce=m();function we({value:e,onChange:t,onBlur:n,options:r,label:i,placeholder:a=`Select...`,disabled:o=!1,size:s=`default`,fullWidth:c=!1,className:l=``,searchable:u=!1,searchPlaceholder:d,"aria-label":f,"aria-describedby":p,invalid:m=!1,noOptionsLabel:h=`No options`}){let[g,v]=(0,_.useState)(!1),[y,b]=(0,_.useState)(-1),[S,C]=(0,_.useState)(``),[w,T]=(0,_.useState)({top:0,left:0,width:0}),E=(0,_.useRef)(null),D=(0,_.useRef)(null),O=(0,_.useRef)(null),k=(0,_.useRef)(null),ee=(0,_.useRef)([]),A=(0,_.useId)(),te=(0,_.useId)(),ne=(0,_.useId)(),j=i!=null&&i!==!1,M=r.find(t=>t.value===e),re=(0,_.useMemo)(()=>{let e=S.trim().toLowerCase();return!u||e.length===0?r:r.filter(t=>[t.label,t.value,t.description??``].some(t=>t.toLowerCase().includes(e)))},[r,S,u]),ie=(0,_.useCallback)((e,t)=>{for(let n=e;n>=0&&n`${te}-option-${String(e)}`,oe=y>=0?ae(y):void 0,se=(0,_.useCallback)(()=>{if(!D.current)return;let e=D.current.getBoundingClientRect();T({top:e.bottom+4,left:e.left,width:e.width})},[]),ce=(0,_.useCallback)(()=>{if(o)return;se(),v(!0);let t=re.findIndex(t=>t.value===e&&!t.disabled);b(t===-1?ie(0,1):t)},[o,re,e,se,ie]),le=(0,_.useCallback)(()=>{v(!1),b(-1),C(``),D.current?.focus()},[]),N=(0,_.useCallback)((e,n)=>{n&&(n.stopPropagation(),n.preventDefault()),!e.disabled&&(t(e.value),le())},[t,le]);(0,_.useEffect)(()=>{let e=e=>{if(!g)return;let t=e.target,n=E.current&&!E.current.contains(t),r=O.current&&!O.current.contains(t);n&&r&&le()},t=e=>{e.key===`Escape`&&g&&le()};return g&&(document.addEventListener(`mousedown`,e),document.addEventListener(`keydown`,t)),()=>{document.removeEventListener(`mousedown`,e),document.removeEventListener(`keydown`,t)}},[g,le]),(0,_.useEffect)(()=>{if(!g)return;let e=()=>{se()};return window.addEventListener(`resize`,e),window.addEventListener(`scroll`,e,!0),()=>{window.removeEventListener(`resize`,e),window.removeEventListener(`scroll`,e,!0)}},[g,se]),(0,_.useEffect)(()=>{g&&u&&k.current?.focus()},[g,u]),(0,_.useEffect)(()=>{if(!g||!u)return;ee.current=[];let t=re.findIndex(t=>t.value===e&&!t.disabled);b(t>=0?t:ie(0,1))},[g,S,u,e,re,ie]);let P=(0,_.useCallback)(e=>{if(!o)switch(e.key){case`Enter`:case` `:if(e.preventDefault(),g){let e=re[y];e&&N(e)}else ce();break;case`Escape`:e.preventDefault(),g&&le();break;case`ArrowDown`:if(e.preventDefault(),!g)ce();else{let e=ie(y+1,1);e>=0&&b(e)}break;case`ArrowUp`:if(e.preventDefault(),g){let e=ie(y-1,-1);e>=0&&b(e)}break;case`Tab`:g&&le()}},[o,g,y,re,ie,ce,le,N]),ue=(0,_.useCallback)(e=>{switch(e.key){case`Enter`:{e.preventDefault();let t=re[y];t&&N(t);break}case`Escape`:e.preventDefault(),e.stopPropagation(),le();break;case`ArrowDown`:e.preventDefault(),b(e=>{let t=ie(e+1,1);return t>=0?t:e});break;case`ArrowUp`:e.preventDefault(),b(e=>{let t=ie(e-1,-1);return t>=0?t:e});break;case`Tab`:le()}},[le,y,N,re,ie]);(0,_.useEffect)(()=>{let e=ee.current[y];g&&y>=0&&e&&e.scrollIntoView({block:`nearest`,behavior:`smooth`})},[g,y]);let de=s==="default"?``:`select--${s}`,fe=c?`select--full-width`:``,pe=j?`select--labelled`:``,me=j?ne:void 0,he=d??f;return(0,x.jsxs)(`div`,{ref:E,className:`select ${de} ${fe} ${pe} ${g?`select--open`:``} ${o?`select--disabled`:``} ${l}`,children:[j&&(0,x.jsx)(`span`,{className:`select__label`,id:ne,children:i}),(0,x.jsxs)(`button`,{ref:D,type:`button`,className:`select__trigger`,onClick:()=>{g?le():ce()},onKeyDown:P,onBlur:n,disabled:o,"aria-haspopup":`listbox`,"aria-expanded":g,"aria-controls":g?A:void 0,"aria-activedescendant":g?oe:void 0,"aria-label":f,"aria-labelledby":me,"aria-describedby":p,"aria-invalid":m||void 0,children:[M?(0,x.jsxs)(`span`,{className:`select__value`,children:[M.icon&&(0,x.jsx)(`span`,{className:`select__value-icon`,children:M.icon}),(0,x.jsx)(`span`,{className:`select__value-label`,children:M.label})]}):(0,x.jsx)(`span`,{className:`select__placeholder`,children:a}),(0,x.jsx)(`span`,{className:`select__chevron ${g?`select__chevron--open`:``}`,children:(0,x.jsx)(`svg`,{width:`10`,height:`6`,viewBox:`0 0 10 6`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,children:(0,x.jsx)(`path`,{d:`M1 1L5 5L9 1`,stroke:`currentColor`,strokeWidth:`1.5`,strokeLinecap:`round`,strokeLinejoin:`round`})})})]}),g&&(0,Ce.createPortal)((0,x.jsxs)(`div`,{ref:O,className:`select__dropdown select__dropdown--portal`,style:{position:`fixed`,top:`${String(w.top)}px`,left:`${String(w.left)}px`,width:`${String(w.width)}px`},children:[u&&(0,x.jsx)(`div`,{className:`select__search`,children:(0,x.jsx)(`input`,{ref:k,className:`select__search-input`,type:`search`,value:S,onChange:e=>C(e.currentTarget.value),onKeyDown:ue,placeholder:d,"aria-label":he,"aria-labelledby":he?void 0:me,"aria-controls":A,"aria-activedescendant":oe,autoComplete:`off`,spellCheck:!1})}),(0,x.jsx)(`div`,{className:`select__options`,role:`listbox`,id:A,"aria-label":f,"aria-labelledby":me,children:re.length===0?(0,x.jsx)(`div`,{className:`select__empty`,children:h}):re.map((t,n)=>(0,x.jsxs)(`div`,{id:ae(n),ref:e=>{ee.current[n]=e},className:`select__option ${t.value===e?`select__option--selected`:``} ${n===y?`select__option--focused`:``} ${t.disabled?`select__option--disabled`:``}`,role:`option`,"aria-selected":t.value===e,"aria-disabled":t.disabled||void 0,"aria-label":t.description?t.label+`. `+t.description:void 0,onClick:e=>{N(t,e)},onMouseEnter:()=>{t.disabled||b(n)},children:[t.icon&&(0,x.jsx)(`span`,{className:`select__option-icon`,children:t.icon}),(0,x.jsxs)(`div`,{className:`select__option-content`,children:[(0,x.jsx)(`span`,{className:`select__option-label`,children:t.label}),t.description&&(0,x.jsx)(`span`,{className:`select__option-description`,children:t.description})]}),t.value===e&&(0,x.jsx)(`span`,{className:`select__option-check`,children:(0,x.jsx)(`svg`,{width:`14`,height:`10`,viewBox:`0 0 14 10`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,children:(0,x.jsx)(`path`,{d:`M1 5L5 9L13 1`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`})})})]},t.value))})]}),document.body)]})}var Te=[{key:`models.library.subtitle`,en:`Inspect local checkpoints. Selecting never loads a model.`,ko:`로컬 체크포인트를 확인하세요. 선택만으로 모델을 로드하지 않습니다.`,test_id:`models-library-subtitle`},{key:`models.library.search`,en:`Search local models`,ko:`로컬 모델 검색`,test_id:`models-library-search`},{key:`models.library.source`,en:`Source`,ko:`소스`,test_id:`models-library-source`},{key:`models.library.task`,en:`Task`,ko:`작업`,test_id:`models-library-task`},{key:`models.library.status`,en:`Lifecycle`,ko:`수명주기`,test_id:`models-library-status`},{key:`models.library.sort`,en:`Sort`,ko:`정렬`,test_id:`models-library-sort`},{key:`models.library.name`,en:`Model`,ko:`모델`,test_id:`models-library-name`},{key:`models.library.all`,en:`All`,ko:`전체`,test_id:`models-library-all`},{key:`models.library.add`,en:`Add Model`,ko:`모델 추가`,test_id:`models-library-add`},{key:`models.library.rescan`,en:`Rescan local roots`,ko:`로컬 경로 다시 검색`,test_id:`models-library-rescan`},{key:`models.library.refresh`,en:`Refresh server state`,ko:`서버 상태 새로고침`,test_id:`models-library-refresh`},{key:`models.library.roots`,en:`Configured roots`,ko:`설정된 경로`,test_id:`models-library-roots`},{key:`models.library.roots_help`,en:`To change roots, restart the server with your local directory. This command is an example, not an executed action.`,ko:`경로를 변경하려면 로컬 디렉터리를 지정하여 서버를 다시 시작하세요. 아래 명령은 예시이며 자동 실행되지 않습니다.`,test_id:`models-library-roots-help`},{key:`models.library.single`,en:`Single-model mode: lifecycle and cache changes are read-only. Restart without -m to manage models.`,ko:`단일 모델 모드: 수명주기 및 캐시는 읽기 전용입니다. 모델을 관리하려면 -m 없이 다시 시작하세요.`,test_id:`models-library-single`},{key:`models.library.unknown`,en:`Unknown`,ko:`알 수 없음`,test_id:`models-library-unknown`},{key:`models.library.yes`,en:`Yes`,ko:`예`,test_id:`models-library-yes`},{key:`models.library.no`,en:`No`,ko:`아니요`,test_id:`models-library-no`},{key:`models.library.inspect`,en:`Inspect {name}`,ko:`{name} 자세히 보기`,test_id:`models-library-inspect`},{key:`models.library.selected`,en:`Selected`,ko:`선택됨`,test_id:`models-library-selected`},{key:`models.library.details`,en:`Model details`,ko:`모델 상세`,test_id:`models-library-details`},{key:`models.library.support`,en:`Support / completeness`,ko:`지원 / 완전성`,test_id:`models-library-support`},{key:`models.library.supported`,en:`Supported architecture`,ko:`지원되는 아키텍처`,test_id:`models-library-supported`},{key:`models.library.unsupported`,en:`Unsupported architecture`,ko:`지원되지 않는 아키텍처`,test_id:`models-library-unsupported`},{key:`models.library.complete`,en:`Complete files`,ko:`파일 완전함`,test_id:`models-library-complete`},{key:`models.library.incomplete`,en:`Incomplete files`,ko:`불완전한 파일`,test_id:`models-library-incomplete`},{key:`models.library.architecture`,en:`Architecture`,ko:`아키텍처`,test_id:`models-library-architecture`},{key:`models.library.backend`,en:`Runnable on this backend`,ko:`현재 백엔드 실행 가능`,test_id:`models-library-backend`},{key:`models.library.tested`,en:`Checkpoint validated`,ko:`검증된 체크포인트`,test_id:`models-library-tested`},{key:`models.library.tested_help`,en:`Family support does not prove this checkpoint was tested.`,ko:`계열 지원은 해당 체크포인트의 검증을 의미하지 않습니다.`,test_id:`models-library-tested-help`},{key:`models.library.disk`,en:`Disk size`,ko:`디스크 크기`,test_id:`models-library-disk`},{key:`models.library.memory`,en:`Estimated memory (not measured)`,ko:`예상 메모리 (측정값 아님)`,test_id:`models-library-memory`},{key:`models.library.context`,en:`Effective context (tokens)`,ko:`실제 컨텍스트 (토큰)`,test_id:`models-library-context`},{key:`models.library.profile`,en:`Next-load profile`,ko:`다음 로드 프로필`,test_id:`models-library-profile`},{key:`models.library.defaults`,en:`Server defaults; see Settings for scope and overrides.`,ko:`서버 기본값입니다. 범위와 재정의는 설정에서 확인하세요.`,test_id:`models-library-defaults`},{key:`models.library.error`,en:`Action could not complete`,ko:`작업을 완료하지 못함`,test_id:`models-library-error`},{key:`models.library.last_error`,en:`Last server error`,ko:`최근 서버 오류`,test_id:`models-library-last-error`},{key:`models.library.chat`,en:`Use in Chat`,ko:`채팅에서 사용`,test_id:`models-library-chat`},{key:`models.library.chat_reason`,en:`Chat requires a ready provider with an available chat capability. Other tasks remain available through their API.`,ko:`채팅에는 준비된 제공자와 사용 가능한 채팅 기능이 필요합니다. 다른 작업은 API로 사용하세요.`,test_id:`models-library-chat-reason`},{key:`models.library.api`,en:`API task documentation`,ko:`API 작업 문서`,test_id:`models-library-api`},{key:`models.library.delete`,en:`Delete cached files`,ko:`캐시 파일 삭제`,test_id:`models-library-delete`},{key:`models.library.delete_body`,en:`Permanently delete the managed cache entry {name} ({source}). This removes files from disk, unlike Unload. To confirm, type the model ID shown below, not the model name.`,ko:`관리 캐시 항목 {name} ({source})을 영구 삭제합니다. 언로드와 달리 디스크 파일을 제거합니다. 확인하려면 모델 이름이 아니라 아래에 표시된 모델 ID를 입력하세요.`,test_id:`models-library-delete-body`},{key:`models.library.confirm_name`,en:`Opaque model ID shown above (starts with mdl_)`,ko:`위에 표시된 모델 ID (mdl_로 시작)`,test_id:`models-library-confirm-name`},{key:`models.library.unload_body`,en:`Unload {name} ({source}): {count} active requests must drain before the worker exits. Files remain on disk. A timeout is a failure, not a completed unload.`,ko:`{name} ({source}) 언로드: 활성 요청 {count}개를 배출한 뒤 작업자가 종료됩니다. 디스크 파일은 유지됩니다. 시간 초과는 완료가 아닌 실패입니다.`,test_id:`models-library-unload-body`},{key:`models.library.confirm`,en:`Confirm`,ko:`확인`,test_id:`models-library-confirm`},{key:`models.library.cancel`,en:`Cancel`,ko:`취소`,test_id:`models-library-cancel`},{key:`models.library.repo`,en:`Public HuggingFace repo ID`,ko:`공개 HuggingFace 저장소 ID`,test_id:`models-library-repo`},{key:`models.library.revision`,en:`Revision (optional)`,ko:`리비전 (선택)`,test_id:`models-library-revision`},{key:`models.library.network`,en:`Only this explicit action contacts HuggingFace. Files go to the server-managed cache below. Size is unknown until the server resolves file metadata. Search never contacts external services.`,ko:`이 작업을 명시적으로 실행할 때만 HuggingFace에 연결합니다. 파일은 아래 서버 관리 캐시에 저장됩니다. 크기는 서버가 파일 메타데이터를 확인할 때까지 알 수 없습니다. 검색은 외부 서비스에 연결하지 않습니다.`,test_id:`models-library-network`},{key:`models.library.public`,en:`This is a public, ungated repository`,ko:`공개된 비게이트 저장소입니다`,test_id:`models-library-public`},{key:`models.library.private`,en:`Private or gated downloads are unavailable in the WebUI. Use an authenticated HuggingFace CLI outside the server, then rescan a configured local root. Do not paste credentials here.`,ko:`비공개 또는 게이트 다운로드는 WebUI에서 지원하지 않습니다. 서버 외부에서 인증된 HuggingFace CLI를 사용한 뒤 설정된 로컬 경로를 다시 검색하세요. 여기에 인증 정보를 입력하지 마세요.`,test_id:`models-library-private`},{key:`models.library.repo_invalid`,en:`Enter owner/repository, not a URL or a local path.`,ko:`URL이나 로컬 경로가 아닌 소유자/저장소를 입력하세요.`,test_id:`models-library-repo-invalid`},{key:`models.library.operations`,en:`Library operations`,ko:`라이브러리 작업`,test_id:`models-library-operations`},{key:`models.library.pending`,en:`Request outcome is being reconciled. Do not resubmit; refresh to observe the server operation.`,ko:`요청 결과를 확인하고 있습니다. 재제출하지 말고 새로고침하여 서버 작업을 확인하세요.`,test_id:`models-library-pending`},{key:`models.library.retry_download`,en:`Retry download`,ko:`다운로드 재시도`,test_id:`models-library-retry-download`},{key:`models.library.cancel_download`,en:`Cancel download`,ko:`다운로드 취소`,test_id:`models-library-cancel-download`},{key:`models.library.cancel_body`,en:`Cancel the download of {name}? Unpublished partial files are not a usable model.`,ko:`{name} 다운로드를 취소할까요? 공개되지 않은 부분 파일은 사용할 수 있는 모델이 아닙니다.`,test_id:`models-library-cancel-body`},{key:`models.library.progress`,en:`Download progress`,ko:`다운로드 진행률`,test_id:`models-library-progress`},{key:`models.library.worker`,en:`Worker exit observed`,ko:`작업자 종료 확인`,test_id:`models-library-worker`},{key:`models.library.stale`,en:`State changed or is not current. Refresh, inspect the latest revision, and explicitly confirm again.`,ko:`상태가 변경되었거나 최신이 아닙니다. 새로고침하고 최신 리비전을 확인한 뒤 다시 명시적으로 확인하세요.`,test_id:`models-library-stale`},{key:`models.library.capacity`,en:`Capacity / conflicting operation`,ko:`용량 / 작업 충돌`,test_id:`models-library-capacity`},{key:`models.library.capacity_body`,en:`Do not repeatedly load. Review active models below. If capacity is full, explicitly choose an idle ready model to unload before this load. Busy models are never offered as eviction targets. Eviction is not rolled back if the new load fails.`,ko:`반복해서 로드하지 마세요. 아래 활성 모델을 확인하세요. 용량이 가득 차면 이번 로드 전에 언로드할 유휴 준비 모델을 명시적으로 선택하세요. 사용 중인 모델은 교체 대상으로 제공되지 않습니다. 새 로드 실패 시 교체는 되돌려지지 않습니다.`,test_id:`models-library-capacity-body`},{key:`models.library.eviction`,en:`Explicit eviction target`,ko:`명시적 교체 대상`,test_id:`models-library-eviction`},{key:`models.library.choose`,en:`Choose a model`,ko:`모델 선택`,test_id:`models-library-choose`},{key:`models.library.evict_load`,en:`Unload target and load`,ko:`대상 언로드 후 로드`,test_id:`models-library-evict-load`},{key:`models.library.active`,en:`Active requests`,ko:`활성 요청`,test_id:`models-library-active`},{key:`models.library.page`,en:`Page {page} of {pages} · {count} models`,ko:`{pages}페이지 중 {page} · 모델 {count}개`,test_id:`models-library-page`},{key:`models.library.previous`,en:`Previous page`,ko:`이전 페이지`,test_id:`models-library-previous`},{key:`models.library.next`,en:`Next page`,ko:`다음 페이지`,test_id:`models-library-next`},{key:`models.library.filtered`,en:`No matching local models`,ko:`일치하는 로컬 모델 없음`,test_id:`models-library-filtered`},{key:`models.library.filtered_body`,en:`Change the local search or filters.`,ko:`로컬 검색어나 필터를 변경하세요.`,test_id:`models-library-filtered-body`},{key:`models.library.waiting`,en:`Waiting for an authoritative catalog snapshot`,ko:`서버의 카탈로그 스냅샷을 기다리는 중`,test_id:`models-library-waiting`},{key:`models.library.sort_name`,en:`Name (A–Z)`,ko:`이름 (오름차순)`,test_id:`models-library-sort-name`},{key:`models.library.sort_status`,en:`Lifecycle`,ko:`수명주기`,test_id:`models-library-sort-status`},{key:`models.library.sort_source`,en:`Source`,ko:`소스`,test_id:`models-library-sort-source`},{key:`models.library.sort_task`,en:`Task`,ko:`작업`,test_id:`models-library-sort-task`},{key:`models.library.unavailable`,en:`Not available for this server or model`,ko:`현재 서버 또는 모델에서 사용할 수 없음`,test_id:`models-library-unavailable`},{key:`models.library.permission`,en:`Root could not be read. Check server directory permissions, then rescan.`,ko:`경로를 읽지 못했습니다. 서버 디렉터리 권한을 확인한 뒤 다시 검색하세요.`,test_id:`models-library-permission`},{key:`models.library.copy`,en:`Copy command`,ko:`명령 복사`,test_id:`models-library-copy`},{key:`models.library.copied`,en:`Copied`,ko:`복사됨`,test_id:`models-library-copied`},{key:`models.library.copy_failed`,en:`Select and copy the command below.`,ko:`아래 명령을 선택하여 복사하세요.`,test_id:`models-library-copy-failed`},{key:`models.library.accepted`,en:`Accepted; waiting for observed server state.`,ko:`접수됨. 서버에서 관측된 상태를 기다리는 중입니다.`,test_id:`models-library-accepted`},{key:`models.library.operation_state`,en:`Operation state`,ko:`작업 상태`,test_id:`models-library-operation-state`}],Ee=[{key:`chat.intro`,en:`Memory-only by default. Changing the model affects the next turn, never the running request.`,ko:`기본적으로 메모리에만 보관합니다. 모델을 바꾸면 다음 턴에만 적용되며 실행 중인 요청은 바뀌지 않습니다.`,test_id:`chat-intro`},{key:`chat.new_conversation`,en:`New conversation`,ko:`새 대화`,test_id:`chat-new-conversation`},{key:`chat.conversation.default_title`,en:`New conversation`,ko:`새 대화`,test_id:`chat-conversation-default-title`},{key:`chat.conversation.label`,en:`Conversation`,ko:`대화`,test_id:`chat-conversation-label`},{key:`chat.conversation.choose`,en:`Choose conversation`,ko:`대화 선택`,test_id:`chat-conversation-choose`},{key:`chat.model.label`,en:`Model for next turn`,ko:`다음 턴에 사용할 모델`,test_id:`chat-model-label`},{key:`chat.model.choose`,en:`Select a model`,ko:`모델 선택`,test_id:`chat-model-choose`},{key:`chat.no_model.title`,en:`Choose a ready chat model`,ko:`준비된 대화 모델을 선택하세요`,test_id:`chat-no-model-title`},{key:`chat.no_model.body`,en:`Selection never loads a model. Load one explicitly in Models. Embeddings, reranking and other tasks use their documented API, not this composer.`,ko:`선택만으로 모델을 로드하지 않습니다. 모델 화면에서 명시적으로 로드하세요. 임베딩, 재순위화 등 다른 작업은 이 입력창이 아니라 문서화된 API를 사용합니다.`,test_id:`chat-no-model-body`},{key:`chat.no_model.action`,en:`Open Models`,ko:`모델 화면 열기`,test_id:`chat-no-model-action`},{key:`chat.settings.summary`,en:`Conversation settings`,ko:`대화 설정`,test_id:`chat-settings-summary`},{key:`chat.settings.name`,en:`Conversation name`,ko:`대화 이름`,test_id:`chat-settings-name`},{key:`chat.settings.system_prompt`,en:`System prompt`,ko:`시스템 프롬프트`,test_id:`chat-settings-system-prompt`},{key:`chat.settings.sampling`,en:`Sampling defaults are set in {link} and frozen when sending.`,ko:`샘플링 기본값은 {link}에서 지정하며 전송할 때 고정됩니다.`,test_id:`chat-settings-sampling`},{key:`chat.settings.delete`,en:`Delete conversation`,ko:`대화 삭제`,test_id:`chat-settings-delete`},{key:`chat.composer.label`,en:`Message`,ko:`메시지`,test_id:`chat-composer-label`},{key:`chat.composer.hint`,en:`Enter sends · Shift+Enter inserts a line. {count}/{max} characters.`,ko:`Enter로 보내고 Shift+Enter로 줄을 바꿉니다. {count}/{max}자.`,test_id:`chat-composer-hint`},{key:`chat.images.label`,en:`Local images`,ko:`로컬 이미지`,test_id:`chat-images-label`},{key:`chat.images.unsupported`,en:`Image attachments require provider-confirmed vision support.`,ko:`이미지를 첨부하려면 provider가 확인한 비전 지원이 필요합니다.`,test_id:`chat-images-unsupported`},{key:`chat.images.remove`,en:`Remove {name}`,ko:`{name} 제거`,test_id:`chat-images-remove`},{key:`chat.stop`,en:`Stop`,ko:`중지`,test_id:`chat-stop`},{key:`chat.error.title`,en:`Chat could not continue`,ko:`대화를 계속할 수 없습니다`,test_id:`chat-error-title`},{key:`chat.error.view_closed`,en:`View closed. The request was aborted and was not retried.`,ko:`화면을 닫았습니다. 요청을 중단했으며 다시 시도하지 않았습니다.`,test_id:`chat-error-view-closed`},{key:`chat.error.vision_unsupported`,en:`The selected provider does not confirm vision support. Remove images or select a vision model.`,ko:`선택한 provider가 비전 지원을 확인하지 않습니다. 이미지를 제거하거나 비전 모델을 선택하세요.`,test_id:`chat-error-vision-unsupported`},{key:`chat.error.conversation_limit`,en:`Conversation limit reached. Delete or export older conversations first.`,ko:`대화 개수 한도에 도달했습니다. 먼저 이전 대화를 삭제하거나 내보내세요.`,test_id:`chat-error-conversation-limit`},{key:`chat.error.invalid_parameters`,en:`Invalid next-turn parameters.`,ko:`다음 턴 매개변수가 올바르지 않습니다.`,test_id:`chat-error-invalid-parameters`},{key:`chat.error.turn_limit`,en:`This conversation reached its 100-turn limit. Start a new conversation.`,ko:`이 대화는 100턴 한도에 도달했습니다. 새 대화를 시작하세요.`,test_id:`chat-error-turn-limit`},{key:`chat.error.images_exceed`,en:`Conversation images exceed the current server count, size or decode limits. Remove attachments or start a new conversation.`,ko:`대화 이미지가 현재 서버의 개수, 크기 또는 디코드 한도를 넘습니다. 첨부를 제거하거나 새 대화를 시작하세요.`,test_id:`chat-error-images-exceed`},{key:`chat.error.body_limit`,en:`The complete request exceeds the server or 16 MiB browser JSON body limit. Remove attachments or start a shorter conversation.`,ko:`전체 요청이 서버 또는 16 MiB 브라우저 JSON 본문 한도를 넘습니다. 첨부를 제거하거나 더 짧은 대화를 시작하세요.`,test_id:`chat-error-body-limit`},{key:`chat.error.memory_budget`,en:`Conversation memory budget reached. Export and clear older history first.`,ko:`대화 메모리 예산에 도달했습니다. 먼저 이전 기록을 내보내고 지우세요.`,test_id:`chat-error-memory-budget`},{key:`chat.error.memory_budget_stream`,en:`Conversation memory budget reached. No further output was retained.`,ko:`대화 메모리 예산에 도달했습니다. 이후 출력은 보존하지 않았습니다.`,test_id:`chat-error-memory-budget-stream`},{key:`chat.error.generation_failed`,en:`Generation failed or disconnected. Partial output is preserved. Check context limits, authentication and server availability; nothing was retried.`,ko:`생성에 실패했거나 연결이 끊겼습니다. 부분 출력은 보존됩니다. 컨텍스트 한도, 인증, 서버 상태를 확인하세요. 자동으로 다시 시도하지 않았습니다.`,test_id:`chat-error-generation-failed`},{key:`chat.error.images_invalid`,en:`Images must be bounded local PNG, JPEG or WebP files. No URL, SVG or HTML input is accepted.`,ko:`이미지는 크기 한도 안의 로컬 PNG, JPEG 또는 WebP 파일이어야 합니다. URL, SVG, HTML 입력은 허용하지 않습니다.`,test_id:`chat-error-images-invalid`},{key:`chat.announce.stopped`,en:`Stopped locally; checking server activity.`,ko:`로컬에서 중지했습니다. 서버 활동을 확인하는 중입니다.`,test_id:`chat-announce-stopped`},{key:`chat.announce.aborted_observed`,en:`Request aborted. Server observation refreshed at {time}. See Activity for active requests; this is not a per-request cancellation receipt.`,ko:`요청을 중단했습니다. 서버 관측값을 {time}에 새로 고쳤습니다. 활성 요청은 활동 화면에서 확인하세요. 이 메시지는 요청별 취소 확인이 아닙니다.`,test_id:`chat-announce-aborted-observed`},{key:`chat.announce.unknown_time`,en:`an unknown time`,ko:`알 수 없는 시각`,test_id:`chat-announce-unknown-time`},{key:`chat.announce.aborted_unobserved`,en:`Request aborted. Backend cancellation could not be observed; inspect Activity before unloading.`,ko:`요청을 중단했습니다. 백엔드 취소를 확인할 수 없으니 언로드하기 전에 활동 화면을 확인하세요.`,test_id:`chat-announce-aborted-unobserved`},{key:`chat.announce.generating`,en:`Generating.`,ko:`생성하는 중입니다.`,test_id:`chat-announce-generating`},{key:`chat.announce.complete`,en:`Response complete.`,ko:`응답이 완료되었습니다.`,test_id:`chat-announce-complete`},{key:`chat.announce.failed`,en:`Generation failed; partial response preserved.`,ko:`생성에 실패했습니다. 부분 응답은 보존됩니다.`,test_id:`chat-announce-failed`},{key:`chat.transcript.label`,en:`Conversation transcript`,ko:`대화 기록`,test_id:`chat-transcript-label`},{key:`chat.transcript.empty`,en:`No messages yet. Start with a prompt after loading a model.`,ko:`아직 메시지가 없습니다. 모델을 로드한 뒤 프롬프트를 입력해 시작하세요.`,test_id:`chat-transcript-empty`},{key:`chat.transcript.jump`,en:`Jump to latest`,ko:`최신 메시지로 이동`,test_id:`chat-transcript-jump`},{key:`chat.transcript.turn_label`,en:`Turn with {model}`,ko:`{model} 턴`,test_id:`chat-transcript-turn-label`},{key:`chat.transcript.status.streaming`,en:`Streaming`,ko:`스트리밍 중`,test_id:`chat-transcript-status-streaming`},{key:`chat.transcript.status.complete`,en:`Complete`,ko:`완료`,test_id:`chat-transcript-status-complete`},{key:`chat.transcript.status.cancelled`,en:`Cancelled`,ko:`취소됨`,test_id:`chat-transcript-status-cancelled`},{key:`chat.transcript.status.interrupted`,en:`Interrupted`,ko:`중단됨`,test_id:`chat-transcript-status-interrupted`},{key:`chat.transcript.status.error`,en:`Error`,ko:`오류`,test_id:`chat-transcript-status-error`},{key:`chat.transcript.images`,en:`{count} local image attachment(s)`,ko:`로컬 이미지 첨부 {count}개`,test_id:`chat-transcript-images`},{key:`chat.transcript.edit`,en:`Edit and regenerate`,ko:`편집 후 다시 생성`,test_id:`chat-transcript-edit`},{key:`chat.transcript.edit.confirm.title`,en:`Edit this prompt?`,ko:`이 프롬프트를 편집할까요?`,test_id:`chat-transcript-edit-confirm-title`},{key:`chat.transcript.edit.confirm.body`,en:`This response and all later turns in this conversation are discarded. The prompt returns to the composer.`,ko:`이 응답과 이 대화의 이후 모든 턴이 삭제됩니다. 프롬프트는 입력창으로 돌아갑니다.`,test_id:`chat-transcript-edit-confirm-body`},{key:`chat.transcript.edit.confirm`,en:`Discard and edit`,ko:`삭제하고 편집`,test_id:`chat-transcript-edit-confirm`},{key:`chat.transcript.reasoning_thinking`,en:`Reasoning · Thinking`,ko:`추론 · 생각하는 중`,test_id:`chat-transcript-reasoning-thinking`},{key:`chat.transcript.thinking`,en:`Thinking…`,ko:`생각하는 중…`,test_id:`chat-transcript-thinking`},{key:`chat.transcript.waiting`,en:`Waiting for response…`,ko:`응답을 기다리는 중…`,test_id:`chat-transcript-waiting`},{key:`chat.transcript.tool_call`,en:`Tool call: {name} (not executed)`,ko:`도구 호출: {name} (실행하지 않음)`,test_id:`chat-transcript-tool-call`},{key:`chat.transcript.tool_name_pending`,en:`Name pending`,ko:`이름 대기 중`,test_id:`chat-transcript-tool-name-pending`},{key:`chat.transcript.copy`,en:`Copy response`,ko:`응답 복사`,test_id:`chat-transcript-copy`},{key:`chat.transcript.copied`,en:`Copied response.`,ko:`응답을 복사했습니다.`,test_id:`chat-transcript-copied`},{key:`chat.transcript.copy_failed`,en:`Copy unavailable; select the response text instead.`,ko:`복사할 수 없습니다. 응답 텍스트를 직접 선택하세요.`,test_id:`chat-transcript-copy-failed`},{key:`chat.transcript.details`,en:`Response details`,ko:`응답 상세`,test_id:`chat-transcript-details`},{key:`chat.transcript.finish_reason`,en:`Finish reason`,ko:`종료 사유`,test_id:`chat-transcript-finish-reason`},{key:`chat.transcript.unknown`,en:`Unknown`,ko:`알 수 없음`,test_id:`chat-transcript-unknown`},{key:`chat.transcript.usage`,en:`Usage (server reported)`,ko:`사용량 (서버 보고)`,test_id:`chat-transcript-usage`},{key:`chat.transcript.usage_value`,en:`{prompt} prompt / {completion} completion / {total} total tokens`,ko:`프롬프트 {prompt} / 완성 {completion} / 전체 {total} 토큰`,test_id:`chat-transcript-usage-value`},{key:`chat.transcript.first_delta`,en:`First delta (client observed)`,ko:`첫 델타 (클라이언트 관측)`,test_id:`chat-transcript-first-delta`},{key:`chat.transcript.decode_rate`,en:`Decode rate (client estimate)`,ko:`디코드 속도 (클라이언트 추정)`,test_id:`chat-transcript-decode-rate`},{key:`chat.transcript.metrics_note`,en:`First delta measures send to first non-empty content, reasoning or tool delta, including transport. Decode rate uses reported completion tokens minus one over the remaining client-observed stream duration; it is not a server kernel metric.`,ko:`첫 델타는 전송부터 비어 있지 않은 첫 내용, 추론 또는 도구 델타까지의 시간이며 전송 구간을 포함합니다. 디코드 속도는 보고된 완성 토큰 수에서 1을 뺀 값을 클라이언트가 관측한 나머지 스트림 시간으로 나눈 값이며 서버 커널 지표가 아닙니다.`,test_id:`chat-transcript-metrics-note`},{key:`chat.params.summary`,en:`Parameters for next turn`,ko:`다음 턴 매개변수`,test_id:`chat-params-summary`},{key:`chat.params.body`,en:`These overrides apply once, after Send accepts a request. Blank fields inherit Settings; absent Settings fields inherit the server. Changes never affect a running turn.`,ko:`이 재정의 값은 보내기로 요청이 수락된 뒤 한 번만 적용됩니다. 빈 필드는 설정 값을, 설정에 없는 필드는 서버 값을 상속합니다. 실행 중인 턴에는 영향을 주지 않습니다.`,test_id:`chat-params-body`},{key:`chat.params.field`,en:`Next turn {name}`,ko:`다음 턴 {name}`,test_id:`chat-params-field`},{key:`chat.params.inherited`,en:`Inherited: {value}`,ko:`상속 값: {value}`,test_id:`chat-params-inherited`},{key:`chat.params.server_default`,en:`server default`,ko:`서버 기본값`,test_id:`chat-params-server-default`},{key:`chat.params.clear`,en:`Clear next-turn overrides`,ko:`다음 턴 재정의 지우기`,test_id:`chat-params-clear`},{key:`chat.privacy.summary`,en:`Local history and privacy`,ko:`로컬 기록과 개인정보`,test_id:`chat-privacy-summary`},{key:`chat.privacy.body`,en:`Conversations stay in memory unless you opt in below. Signing out or refreshing requires authentication again; saved history belongs to this browser origin, not a server account. No API keys are stored.`,ko:`아래에서 동의하지 않으면 대화는 메모리에만 남습니다. 로그아웃하거나 새로고침하면 다시 인증해야 합니다. 저장된 기록은 서버 계정이 아니라 이 브라우저 origin에 속합니다. API 키는 저장하지 않습니다.`,test_id:`chat-privacy-body`},{key:`chat.privacy.save`,en:`Save conversations on this device (IndexedDB)`,ko:`이 기기에 대화 저장 (IndexedDB)`,test_id:`chat-privacy-save`},{key:`chat.privacy.include_images`,en:`Also include attached image bytes in saved history and exports (separate consent)`,ko:`저장 기록과 내보내기에 첨부 이미지 바이트도 포함 (별도 동의)`,test_id:`chat-privacy-include-images`},{key:`chat.privacy.note`,en:`Turning saving off stops future writes; use Clear All to remove previously saved history. Re-enable explicitly after refresh to read it.`,ko:`저장을 끄면 이후 쓰기만 멈춥니다. 이미 저장된 기록은 모두 지우기로 삭제하세요. 새로고침 후 기록을 읽으려면 다시 명시적으로 켜세요.`,test_id:`chat-privacy-note`},{key:`chat.privacy.export`,en:`Export JSON`,ko:`JSON 내보내기`,test_id:`chat-privacy-export`},{key:`chat.privacy.export_failed`,en:`Export exceeds the bounded history size or contains unsupported data.`,ko:`내보내기가 기록 크기 한도를 넘거나 지원하지 않는 데이터를 포함합니다.`,test_id:`chat-privacy-export-failed`},{key:`chat.privacy.clear`,en:`Clear All`,ko:`모두 지우기`,test_id:`chat-privacy-clear`},{key:`chat.privacy.cleared`,en:`All history cleared.`,ko:`모든 기록을 지웠습니다.`,test_id:`chat-privacy-cleared`},{key:`chat.privacy.clear_failed`,en:`Stored history could not be cleared. Check browser storage permissions; no success is claimed.`,ko:`저장된 기록을 지우지 못했습니다. 브라우저 저장소 권한을 확인하세요. 성공으로 처리하지 않았습니다.`,test_id:`chat-privacy-clear-failed`},{key:`chat.privacy.import`,en:`Import conversation JSON (replaces current history)`,ko:`대화 JSON 가져오기 (현재 기록을 대체)`,test_id:`chat-privacy-import`},{key:`chat.privacy.import_too_large`,en:`Import exceeds 16 MiB.`,ko:`가져오기가 16 MiB를 넘습니다.`,test_id:`chat-privacy-import-too-large`},{key:`chat.privacy.import_rejected`,en:`Import rejected: unsupported version, invalid data or exceeded limits.`,ko:`가져오기를 거부했습니다. 지원하지 않는 버전, 잘못된 데이터 또는 한도 초과입니다.`,test_id:`chat-privacy-import-rejected`},{key:`chat.privacy.save_failed`,en:`History was not saved. Storage may be full or unavailable; export your conversation.`,ko:`기록을 저장하지 못했습니다. 저장소가 가득 찼거나 사용할 수 없을 수 있으니 대화를 내보내세요.`,test_id:`chat-privacy-save-failed`},{key:`chat.privacy.open_failed`,en:`Local history could not be opened or its images failed validation. Nothing was saved.`,ko:`로컬 기록을 열 수 없거나 이미지 검증에 실패했습니다. 아무것도 저장하지 않았습니다.`,test_id:`chat-privacy-open-failed`},{key:`chat.privacy.title`,en:`Local history`,ko:`로컬 기록`,test_id:`chat-privacy-title`},{key:`chat.privacy.replace_saved.confirm.title`,en:`Replace the in-memory conversations with saved history?`,ko:`메모리의 대화를 저장된 기록으로 바꿀까요?`,test_id:`chat-privacy-replace-saved-confirm-title`},{key:`chat.privacy.replace_saved.confirm.body`,en:`The conversations in memory are discarded and replaced by the saved history. Export current conversations first if needed.`,ko:`메모리의 대화는 삭제되고 저장된 기록으로 대체됩니다. 필요하면 먼저 현재 대화를 내보내세요.`,test_id:`chat-privacy-replace-saved-confirm-body`},{key:`chat.privacy.replace_saved.confirm`,en:`Replace with saved history`,ko:`저장된 기록으로 바꾸기`,test_id:`chat-privacy-replace-saved-confirm`},{key:`chat.privacy.clear.confirm.title`,en:`Delete all in-memory and saved conversations for this browser origin?`,ko:`이 브라우저 origin의 메모리 대화와 저장된 대화를 모두 삭제할까요?`,test_id:`chat-privacy-clear-confirm-title`},{key:`chat.privacy.clear.confirm`,en:`Delete all history`,ko:`모든 기록 삭제`,test_id:`chat-privacy-clear-confirm`},{key:`chat.privacy.replace_import.confirm.title`,en:`Replace the current conversations with validated imported history?`,ko:`현재 대화를 검증된 가져온 기록으로 바꿀까요?`,test_id:`chat-privacy-replace-import-confirm-title`},{key:`chat.privacy.replace_import.confirm.body`,en:`The current conversations are discarded and replaced by the imported history. Export current conversations first if needed.`,ko:`현재 대화는 삭제되고 가져온 기록으로 대체됩니다. 필요하면 먼저 현재 대화를 내보내세요.`,test_id:`chat-privacy-replace-import-confirm-body`},{key:`chat.privacy.replace_import.confirm`,en:`Replace with imported history`,ko:`가져온 기록으로 바꾸기`,test_id:`chat-privacy-replace-import-confirm`}],De=[{key:`settings.server.privacy.title`,en:`Privacy · browser only`,ko:`개인정보 · 브라우저 전용`,test_id:`settings-server-privacy-title`},{key:`settings.server.privacy.body`,en:`Appearance and explicitly saved load profiles use this browser’s preferences. Request defaults stay in memory; API credentials and system prompts are never stored by Settings. Conversation history is controlled separately in Chat.`,ko:`모양과 명시적으로 저장한 로드 프로필은 브라우저 환경설정을 사용합니다. 요청 기본값은 메모리에만 유지하며 API 자격 증명과 시스템 프롬프트는 설정에서 저장하지 않습니다. 대화 기록은 채팅에서 별도로 관리합니다.`,test_id:`settings-server-privacy-body`},{key:`settings.server.unavailable.title`,en:`Server controls unavailable`,ko:`서버 제어 사용 불가`,test_id:`settings-server-unavailable-title`},{key:`settings.server.unavailable.body`,en:`Connect from Models or Chat, or refresh the connection before changing server settings. Browser appearance and request defaults remain available. Schema mismatch disables server controls.`,ko:`모델이나 채팅에서 연결하거나 연결을 새로 고친 후 서버 설정을 변경하세요. 브라우저 모양과 요청 기본값은 계속 사용할 수 있습니다. 스키마 불일치 시 서버 제어가 비활성화됩니다.`,test_id:`settings-server-unavailable-body`},{key:`settings.server.model`,en:`Selected model for settings`,ko:`설정 대상 모델`,test_id:`settings-server-model`},{key:`settings.server.model.none`,en:`No model selected`,ko:`선택한 모델 없음`,test_id:`settings-server-model-none`},{key:`settings.server.model.hint`,en:`Selection changes browser context only. It never loads, unloads or reroutes an existing request.`,ko:`선택은 브라우저 문맥만 변경하며 모델을 로드하거나 언로드하거나 기존 요청의 대상을 변경하지 않습니다.`,test_id:`settings-server-model-hint`},{key:`settings.server.context.title`,en:`Effective context · observed, not estimated`,ko:`실제 컨텍스트 · 추정이 아닌 관측값`,test_id:`settings-server-context-title`},{key:`settings.server.context.n_ctx`,en:`Per-slot context tokens (/props n_ctx)`,ko:`슬롯별 컨텍스트 토큰 (/props n_ctx)`,test_id:`settings-server-context-n-ctx`},{key:`settings.server.context.n_ctx_hint`,en:`Zero/missing is unknown; do not multiply this value into a shared-pool capacity. Unified KV remains separate work (#1815).`,ko:`0 또는 누락은 알 수 없음입니다. 이 값에 슬롯 수를 곱해 공유 풀 용량으로 간주하지 않습니다. 통합 KV는 별도 작업입니다 (#1815).`,test_id:`settings-server-context-n-ctx-hint`},{key:`settings.server.context.slots`,en:`Configured slots (/props total_slots)`,ko:`설정된 슬롯 (/props total_slots)`,test_id:`settings-server-context-slots`},{key:`settings.server.context.kv_mode`,en:`Active resolved KV cache mode (/props)`,ko:`현재 실제 KV 캐시 모드 (/props)`,test_id:`settings-server-context-kv-mode`},{key:`settings.server.context.geometry`,en:`Reported context geometry`,ko:`보고된 컨텍스트 구성`,test_id:`settings-server-context-geometry`},{key:`settings.server.context.geometry_unknown`,en:`Unknown / props disabled or unavailable`,ko:`알 수 없음 / props 비활성화 또는 사용 불가`,test_id:`settings-server-context-geometry-unknown`},{key:`settings.server.unknown`,en:`Unknown`,ko:`알 수 없음`,test_id:`settings-server-unknown`},{key:`settings.server.no_model.title`,en:`No ready model selected`,ko:`준비된 모델이 선택되지 않음`,test_id:`settings-server-no-model-title`},{key:`settings.server.no_model.body`,en:`Selection never loads a model. Load explicitly from Models to read live settings.`,ko:`모델 선택은 로드를 수행하지 않습니다. 모델 화면에서 명시적으로 로드하여 실시간 설정을 확인하세요.`,test_id:`settings-server-no-model-body`},{key:`settings.server.live_disabled.title`,en:`Live settings disabled by operator`,ko:`운영자가 실시간 설정을 비활성화함`,test_id:`settings-server-live-disabled-title`},{key:`settings.server.live_disabled.body`,en:`Restart with --settings to enable this endpoint. WebUI never enables settings, props, metrics or slots implicitly.`,ko:`엔드포인트를 활성화하려면 --settings로 재시작하세요. WebUI는 settings, props, metrics 또는 slots를 자동으로 활성화하지 않습니다.`,test_id:`settings-server-live-disabled-body`},{key:`settings.generation.title`,en:`Generation · next request`,ko:`생성 · 다음 요청`,test_id:`settings-generation-title`},{key:`settings.generation.body`,en:`These defaults stay in browser memory only. Blank fields are omitted and inherit server defaults. Existing turns are frozen; changing defaults never alters an in-flight request. System prompts belong to individual conversations in Chat and are not stored here.`,ko:`기본값은 브라우저 메모리에만 남습니다. 빈 필드는 생략되어 서버 기본값을 사용합니다. 진행 중인 요청은 변경되지 않습니다. 시스템 프롬프트는 채팅의 개별 대화에서 설정하며 여기에 저장하지 않습니다.`,test_id:`settings-generation-body`},{key:`settings.generation.current`,en:`Current next-request default: {value}`,ko:`현재 다음 요청 기본값: {value}`,test_id:`settings-generation-current`},{key:`settings.generation.inherit`,en:`inherit`,ko:`상속`,test_id:`settings-generation-inherit`},{key:`settings.generation.invalid`,en:`Invalid defaults`,ko:`잘못된 기본값`,test_id:`settings-generation-invalid`},{key:`settings.generation.error_title`,en:`Invalid request defaults`,ko:`잘못된 요청 기본값`,test_id:`settings-generation-error-title`},{key:`settings.generation.save`,en:`Save session defaults`,ko:`세션 기본값 저장`,test_id:`settings-generation-save`},{key:`settings.generation.reset_open`,en:`Reset request defaults…`,ko:`요청 기본값 초기화…`,test_id:`settings-generation-reset-open`},{key:`settings.generation.reasoning_label`,en:`Reasoning / structured output`,ko:`추론 / 구조화 출력`,test_id:`settings-generation-reasoning-label`},{key:`settings.generation.reasoning_value`,en:`Endpoint-specific controls are available only where explicitly supported in Chat.`,ko:`채팅에서 명시적으로 지원되는 엔드포인트에만 제공됩니다.`,test_id:`settings-generation-reasoning-value`},{key:`settings.generation.reasoning_hint`,en:`No unsupported parameters are sent.`,ko:`지원되지 않는 매개변수는 전송하지 않습니다.`,test_id:`settings-generation-reasoning-hint`},{key:`settings.generation.reset.title`,en:`Reset request defaults?`,ko:`요청 기본값을 초기화할까요?`,test_id:`settings-generation-reset-title`},{key:`settings.generation.reset.body`,en:`Only browser-session request defaults will be cleared. Server and next-load profiles remain unchanged.`,ko:`브라우저 세션 요청 기본값만 지워집니다. 서버와 다음 로드 프로필은 변경되지 않습니다.`,test_id:`settings-generation-reset-body`},{key:`settings.generation.reset.confirm`,en:`Reset request defaults`,ko:`요청 기본값 초기화`,test_id:`settings-generation-reset-confirm`},{key:`settings.live.title`,en:`Loaded model · live server values`,ko:`로드된 모델 · 실시간 서버 값`,test_id:`settings-live-title`},{key:`settings.live.body`,en:`Changes affect newly admitted requests. Fingerprints detect already-observed external changes, not atomic compare-and-swap. Numeric bounds remain enforced by the server; this schema publishes types and allowed enums, not numeric min/max.`,ko:`변경은 새로 수락되는 요청에 적용됩니다. 지문은 관측된 외부 변경을 감지하지만 원자적 비교 교환은 아닙니다. 숫자 범위는 서버가 검증합니다. 스키마에는 타입과 허용 열거값만 있습니다.`,test_id:`settings-live-body`},{key:`settings.live.unavailable`,en:`Settings unavailable. The server may have disabled --settings.`,ko:`설정을 사용할 수 없습니다. 서버에서 --settings가 비활성화되었을 수 있습니다.`,test_id:`settings-live-unavailable`},{key:`settings.live.refreshed`,en:`Current values refreshed. Review the retained draft before applying.`,ko:`현재 값을 새로 고쳤습니다. 남아 있는 초안을 검토한 후 적용하세요.`,test_id:`settings-live-refreshed`},{key:`settings.live.refresh_failed`,en:`Refresh failed. No changes submitted.`,ko:`새로 고침에 실패했습니다. 변경 사항은 전송되지 않았습니다.`,test_id:`settings-live-refresh-failed`},{key:`settings.live.invalid_value`,en:`Invalid value`,ko:`잘못된 값`,test_id:`settings-live-invalid-value`},{key:`settings.live.conflict`,en:`Another client changed these settings. Current values refreshed; review and Apply again to reconfirm.`,ko:`다른 클라이언트가 설정을 변경했습니다. 갱신된 현재 값을 검토하고 다시 적용하여 확인하세요.`,test_id:`settings-live-conflict`},{key:`settings.live.partial`,en:`{applied} applied; {rejected} rejected. Rejected drafts retained.`,ko:`{applied}개 적용, {rejected}개 거부됨. 거부된 초안은 유지됩니다.`,test_id:`settings-live-partial`},{key:`settings.live.applied`,en:`Accepted fields applied; reading effective values.`,ko:`승인된 필드를 적용했습니다. 실제 값을 다시 읽습니다.`,test_id:`settings-live-applied`},{key:`settings.live.unknown_outcome`,en:`The outcome may be unknown. Refresh effective values before retrying; no automatic PATCH retry.`,ko:`결과를 확정할 수 없습니다. 재시도 전에 실제 값을 새로 고치세요. PATCH는 자동 재시도하지 않습니다.`,test_id:`settings-live-unknown-outcome`},{key:`settings.live.result_title`,en:`Settings result`,ko:`설정 결과`,test_id:`settings-live-result-title`},{key:`settings.live.refresh`,en:`Refresh current values`,ko:`현재 값 새로 고침`,test_id:`settings-live-refresh`},{key:`settings.live.apply`,en:`Apply live draft`,ko:`실시간 초안 적용`,test_id:`settings-live-apply`},{key:`settings.live.reset_open`,en:`Reset live draft…`,ko:`실시간 초안 초기화…`,test_id:`settings-live-reset-open`},{key:`settings.live.hint`,en:`{help} Current: {current}. Type: {type}`,ko:`{help} 현재: {current}. 타입: {type}`,test_id:`settings-live-hint`},{key:`settings.live.hint_allowed`,en:`{help} Current: {current}. Type: {type}; allowed: {allowed}`,ko:`{help} 현재: {current}. 타입: {type}; 허용: {allowed}`,test_id:`settings-live-hint-allowed`},{key:`settings.live.startup`,en:`Server startup · restart required (read-only)`,ko:`서버 시작 · 재시작 필요 (읽기 전용)`,test_id:`settings-live-startup`},{key:`settings.live.reset.title`,en:`Reset live draft only?`,ko:`실시간 초안만 초기화할까요?`,test_id:`settings-live-reset-title`},{key:`settings.live.reset.body`,en:`Stage server startup defaults for mutable fields. No server change occurs until Apply.`,ko:`변경 가능한 필드에 서버 시작 기본값을 초안으로 설정합니다. 적용 전에는 서버가 변경되지 않습니다.`,test_id:`settings-live-reset-body`},{key:`settings.live.reset.confirm`,en:`Reset draft`,ko:`초안 초기화`,test_id:`settings-live-reset-confirm`},{key:`settings.profile.title`,en:`Next load · browser profile`,ko:`다음 로드 · 브라우저 프로필`,test_id:`settings-profile-title`},{key:`settings.profile.body`,en:`Explicit CLI settings take precedence over this profile; the profile overrides a preset only where CLI has not pinned a value. Effective resolved values must be read after loading. Saving is not loading. A loaded model requires an explicit unload and load from Models; failed loads retain this pending profile.`,ko:`명시적 CLI 설정이 프로필보다 우선합니다. CLI로 고정되지 않은 값에만 프로필이 프리셋보다 우선합니다. 실제 값은 로드 후 확인하세요. 저장은 로드가 아닙니다. 로드된 모델은 모델 화면에서 명시적으로 언로드 후 로드해야 하며, 실패 시 프로필은 대기 상태로 남습니다.`,test_id:`settings-profile-body`},{key:`settings.profile.saved`,en:`Browser profile saved. Nothing loaded or changed on the server.`,ko:`브라우저 프로필을 저장했습니다. 서버에서 로드하거나 변경한 내용은 없습니다.`,test_id:`settings-profile-saved`},{key:`settings.profile.failed`,en:`Profile operation failed`,ko:`프로필 작업에 실패했습니다`,test_id:`settings-profile-failed`},{key:`settings.profile.single.title`,en:`Single-model mode: restart required`,ko:`단일 모델 모드: 재시작 필요`,test_id:`settings-profile-single-title`},{key:`settings.profile.single.body`,en:`These preferences cannot be applied to this running worker. Restart with validated CLI flags, or start model-free mode to use load operations.`,ko:`실행 중인 워커에 적용할 수 없습니다. 검증된 CLI 플래그로 재시작하거나 모델 없는 모드에서 로드 작업을 사용하세요.`,test_id:`settings-profile-single-body`},{key:`settings.profile.scope`,en:`Profile scope`,ko:`프로필 범위`,test_id:`settings-profile-scope`},{key:`settings.profile.scope.reusable`,en:`Reusable defaults`,ko:`재사용 기본값`,test_id:`settings-profile-scope-reusable`},{key:`settings.profile.ctx_hint`,en:`Blank: inherit. Actual per-slot context is resolved by the server, not estimated here.`,ko:`빈 값: 상속. 슬롯별 실제 컨텍스트는 서버가 결정하며 여기서 추정하지 않습니다.`,test_id:`settings-profile-ctx-hint`},{key:`settings.profile.parallel_hint`,en:`Scheduler/worker geometry changes only on the next explicit load.`,ko:`스케줄러/워커 구성은 다음 명시적 로드에서만 변경됩니다.`,test_id:`settings-profile-parallel-hint`},{key:`settings.profile.inherit`,en:`Inherit`,ko:`상속`,test_id:`settings-profile-inherit`},{key:`settings.profile.restrictions`,en:`Backend/model restrictions are validated by the existing loader; accepting a browser profile does not promise a model supports every mode. Draft models, adapters, distributed topology and other worker geometry are read-only in v1.`,ko:`백엔드/모델 제약은 기존 로더가 검증합니다. 브라우저 프로필 저장이 모든 모드의 지원을 보장하지 않습니다. 초안 모델, 어댑터, 분산 구성 및 기타 워커 설정은 v1에서 읽기 전용입니다.`,test_id:`settings-profile-restrictions`},{key:`settings.profile.result_title`,en:`Profile result`,ko:`프로필 결과`,test_id:`settings-profile-result-title`},{key:`settings.profile.save`,en:`Save pending profile`,ko:`대기 프로필 저장`,test_id:`settings-profile-save`},{key:`settings.profile.discard`,en:`Discard draft`,ko:`초안 취소`,test_id:`settings-profile-discard`},{key:`settings.profile.reset_open`,en:`Reset selected profile…`,ko:`선택 프로필 초기화…`,test_id:`settings-profile-reset-open`},{key:`settings.profile.saved_pending`,en:`Saved pending profile (not active)`,ko:`저장된 대기 프로필 (미적용)`,test_id:`settings-profile-saved-pending`},{key:`settings.profile.cli`,en:`Sanitized CLI flags · display only; model source omitted`,ko:`안전한 CLI 플래그 · 표시 전용; 모델 소스 생략`,test_id:`settings-profile-cli`},{key:`settings.profile.transfer`,en:`Import / export browser profiles`,ko:`브라우저 프로필 가져오기 / 내보내기`,test_id:`settings-profile-transfer`},{key:`settings.profile.transfer.label`,en:`Versioned profile JSON`,ko:`버전이 있는 프로필 JSON`,test_id:`settings-profile-transfer-label`},{key:`settings.profile.transfer.export`,en:`Export to text`,ko:`텍스트로 내보내기`,test_id:`settings-profile-transfer-export`},{key:`settings.profile.transfer.import`,en:`Validate and import`,ko:`검증 후 가져오기`,test_id:`settings-profile-transfer-import`},{key:`settings.profile.reset.title`,en:`Reset this browser profile?`,ko:`이 브라우저 프로필을 초기화할까요?`,test_id:`settings-profile-reset-title`},{key:`settings.profile.reset.body`,en:`Resets only the selected scope. Model scope falls back to reusable defaults; reusable scope leaves model-specific profiles intact. Does not change a running worker.`,ko:`선택한 범위만 초기화합니다. 모델 범위는 재사용 기본값으로 돌아가며 재사용 범위는 모델별 프로필을 유지합니다. 실행 중인 워커는 변경하지 않습니다.`,test_id:`settings-profile-reset-body`},{key:`settings.profile.reset.confirm`,en:`Reset profile`,ko:`프로필 초기화`,test_id:`settings-profile-reset-confirm`},{key:`settings.context_check.label`,en:`Optional raw prompt budget check`,ko:`선택적 원시 프롬프트 예산 확인`,test_id:`settings-context-check-label`},{key:`settings.context_check.hint`,en:`Sent only when Check is pressed; never persisted. Raw tokens exclude chat templates, conversation history and media. Server validation is final.`,ko:`확인을 누를 때만 전송하며 저장하지 않습니다. 원시 토큰은 채팅 템플릿, 대화 기록, 미디어를 제외합니다. 최종 검증은 서버가 수행합니다.`,test_id:`settings-context-check-hint`},{key:`settings.context_check.check`,en:`Check with model tokenizer`,ko:`모델 토크나이저로 확인`,test_id:`settings-context-check-check`},{key:`settings.context_check.unavailable`,en:`Tokenization unavailable; budget unknown.`,ko:`토큰화 불가; 예산을 알 수 없습니다.`,test_id:`settings-context-check-unavailable`},{key:`settings.context_check.not_measured`,en:`Not measured`,ko:`측정하지 않음`,test_id:`settings-context-check-not-measured`},{key:`settings.context_check.count`,en:`{count} raw tokens. {verdict}`,ko:`{count} 원시 토큰. {verdict}`,test_id:`settings-context-check-count`},{key:`settings.context_check.exceeds`,en:`Raw input + requested output already exceeds observed context.`,ko:`원시 입력 + 요청 출력이 관측 컨텍스트를 초과합니다.`,test_id:`settings-context-check-exceeds`},{key:`settings.context_check.unknown`,en:`Context/output is unknown; no fit claim.`,ko:`컨텍스트/출력을 알 수 없어 수용 가능 여부를 판단하지 않습니다.`,test_id:`settings-context-check-unknown`},{key:`settings.context_check.fits`,en:`Raw input + output fits, but templated chat may still exceed the context.`,ko:`원시 입력 + 출력은 들어가지만 템플릿 적용 채팅은 컨텍스트를 초과할 수 있습니다.`,test_id:`settings-context-check-fits`}],Oe=[{key:`activity.intro`,en:`Operations and runtime observations. Browsing never loads a model.`,ko:`작업과 런타임 관측입니다. 조회는 모델을 로드하지 않습니다.`,test_id:`activity-intro`},{key:`activity.session`,en:`History belongs to this server session: up to 200 terminal operations for one hour. A restart clears it; reconnect reconciles the authoritative snapshot.`,ko:`기록은 서버 세션에 속합니다. 완료 작업 최대 200개를 한 시간 보관하며, 재시작 시 초기화하고 재연결 시 서버 상태와 대조합니다.`,test_id:`activity-session`},{key:`activity.export`,en:`Export sanitized diagnostics`,ko:`민감 정보 없는 진단 내보내기`,test_id:`activity-export`},{key:`activity.refresh`,en:`Refresh observations`,ko:`관측 새로고침`,test_id:`activity-refresh`},{key:`activity.stale`,en:`Observations are stale. Last values are not current measurements.`,ko:`관측이 최신 상태가 아닙니다. 마지막 값은 현재 측정값이 아닙니다.`,test_id:`activity-stale`},{key:`activity.updated`,en:`Last successful snapshot`,ko:`마지막 성공 스냅샷`,test_id:`activity-updated`},{key:`activity.pending`,en:`Waiting for the first snapshot`,ko:`첫 스냅샷을 기다리는 중`,test_id:`activity-pending`},{key:`activity.operations`,en:`Operations`,ko:`작업`,test_id:`activity-operations`},{key:`activity.operations.counts`,en:`Operations: {active} active · {failed} failed`,ko:`작업: {active} 진행 중 · {failed} 실패`,test_id:`activity-operations-counts`},{key:`activity.operations.empty.title`,en:`No operations in this session`,ko:`이 세션의 작업 없음`,test_id:`activity-operations-empty-title`},{key:`activity.operations.empty.body`,en:`Explicit downloads, loads, drains and removals will appear here.`,ko:`명시적인 다운로드, 로드, 드레인 및 삭제 작업이 표시됩니다.`,test_id:`activity-operations-empty-body`},{key:`activity.cancel`,en:`Request cancellation`,ko:`취소 요청`,test_id:`activity-cancel`},{key:`activity.cancelling`,en:`Cancellation requested; waiting for worker acknowledgement.`,ko:`취소 요청됨. 작업자 확인을 기다립니다.`,test_id:`activity-cancelling`},{key:`activity.failure`,en:`The action failed. Check its state and refresh before retrying from Models.`,ko:`작업에 실패했습니다. 상태를 확인하고 새로고침한 후 모델 화면에서 재시도하세요.`,test_id:`activity-failure`},{key:`activity.cancel_failed`,en:`Cancellation could not be confirmed. Refresh to reconcile the operation.`,ko:`취소를 확인하지 못했습니다. 새로고침하여 작업 상태를 대조하세요.`,test_id:`activity-cancel-failed`},{key:`activity.cancel_unsupported`,en:`Cancellation is unavailable for this operation; worker execution is not interrupted.`,ko:`이 작업은 취소할 수 없습니다. 실행 중인 작업자를 강제로 중단하지 않습니다.`,test_id:`activity-cancel-unsupported`},{key:`activity.runtime`,en:`Selected model runtime`,ko:`선택한 모델 런타임`,test_id:`activity-runtime`},{key:`activity.select`,en:`Select a model to observe`,ko:`관측할 모델 선택`,test_id:`activity-select`},{key:`activity.select_body`,en:`Use the model picker. Selection does not load the model.`,ko:`모델 선택기를 사용하세요. 선택만으로 모델을 로드하지 않습니다.`,test_id:`activity-select-body`},{key:`activity.unavailable`,en:`N/A — no authoritative sample is available.`,ko:`N/A — 확인된 관측값이 없습니다.`,test_id:`activity-unavailable`},{key:`activity.not_available`,en:`N/A`,ko:`N/A`,test_id:`activity-not-available`},{key:`activity.memory`,en:`Memory figures have separate scopes and may overlap. Do not add process, allocator, device and cache values together.`,ko:`메모리 수치는 서로 다른 범위이며 중복될 수 있습니다. 프로세스, 할당자, 장치 및 캐시 값을 합산하지 마세요.`,test_id:`activity-memory`},{key:`activity.timing`,en:`Server counters are not browser TTFT. Chat shows request-send to first reasoning/content delta separately; no rendered word counts are used as tokens.`,ko:`서버 카운터는 브라우저 TTFT가 아닙니다. 채팅은 요청 전송부터 첫 추론/내용 델타까지 별도로 표시하며, 단어 수를 토큰으로 사용하지 않습니다.`,test_id:`activity-timing`},{key:`activity.slots`,en:`Request slots`,ko:`요청 슬롯`,test_id:`activity-slots`},{key:`activity.slot`,en:`Slot`,ko:`슬롯`,test_id:`activity-slot`},{key:`activity.processing`,en:`Processing`,ko:`처리 중`,test_id:`activity-processing`},{key:`activity.idle`,en:`Idle`,ko:`유휴`,test_id:`activity-idle`},{key:`activity.context`,en:`Request context window`,ko:`요청 컨텍스트 한도`,test_id:`activity-context`},{key:`activity.pool`,en:`Shared pool context`,ko:`공유 풀 컨텍스트`,test_id:`activity-pool`},{key:`activity.parallel`,en:`Effective parallelism`,ko:`실제 병렬도`,test_id:`activity-parallel`},{key:`activity.context_line`,en:`{context}: {request} tokens · {pool}: {shared} tokens`,ko:`{context}: {request} 토큰 · {pool}: {shared} 토큰`,test_id:`activity-context-line`},{key:`activity.no_context`,en:`N/A — context denominator is unknown; no occupancy percentage is inferred.`,ko:`N/A — 컨텍스트 분모를 알 수 없어 점유율을 추정하지 않습니다.`,test_id:`activity-no-context`},{key:`activity.slot_progress`,en:`{used} / {total} tokens`,ko:`{used} / {total} 토큰`,test_id:`activity-slot-progress`},{key:`activity.slot_tokens`,en:`Accepted decode: {decoded} tokens · Cached prompt: {cached} tokens`,ko:`수락된 디코드: {decoded} 토큰 · 캐시된 프롬프트: {cached} 토큰`,test_id:`activity-slot-tokens`},{key:`activity.history.show`,en:`Show recent history`,ko:`최근 기록 보기`,test_id:`activity-history-show`},{key:`activity.history.hide`,en:`Hide recent history`,ko:`최근 기록 숨기기`,test_id:`activity-history-hide`},{key:`activity.history.note`,en:`Five-minute in-memory history, at most 150 two-second samples. Hidden tabs stop observation; gaps and counter resets are not interpolated.`,ko:`메모리 내 5분 기록이며 2초 간격 최대 150개입니다. 숨겨진 탭은 관측을 중지합니다. 공백과 카운터 초기화를 보간하지 않습니다.`,test_id:`activity-history-note`},{key:`activity.chart.label`,en:`Active requests: discrete observations over the last five minutes`,ko:`활성 요청: 최근 5분 동안의 개별 관측값`,test_id:`activity-chart-label`},{key:`activity.chart.title`,en:`Active requests (requests, selected model)`,ko:`활성 요청 (요청 수, 선택한 모델)`,test_id:`activity-chart-title`},{key:`activity.chart.point`,en:`{value} requests`,ko:`요청 {value}개`,test_id:`activity-chart-point`},{key:`activity.scope`,en:`Scope`,ko:`범위`,test_id:`activity-scope`},{key:`activity.observed`,en:`Observed at`,ko:`관측 시각`,test_id:`activity-observed`},{key:`activity.metric_details`,en:`All measurements and sources`,ko:`전체 측정값과 출처`,test_id:`activity-metric-details`},{key:`activity.unavailable_count`,en:`Unavailable measurements`,ko:`사용할 수 없는 측정값`,test_id:`activity-unavailable-count`},{key:`activity.unavailable_reason`,en:`Some sources are disabled or do not publish an authoritative sample. Expand details for individual reasons.`,ko:`일부 출처가 비활성화되었거나 확인된 관측값을 제공하지 않습니다. 상세 내용을 펼쳐 개별 사유를 확인하세요.`,test_id:`activity-unavailable-reason`},{key:`activity.no_primary`,en:`No primary request counters are available.`,ko:`사용 가능한 주요 요청 카운터가 없습니다.`,test_id:`activity-no-primary`},{key:`activity.bytes`,en:`bytes downloaded`,ko:`다운로드 바이트`,test_id:`activity-bytes`},{key:`activity.download_progress`,en:`{completed} / {total} bytes`,ko:`{completed} / {total} 바이트`,test_id:`activity-download-progress`},{key:`activity.details`,en:`Operation details`,ko:`작업 상세`,test_id:`activity-details`},{key:`activity.status`,en:`Operation status`,ko:`작업 상태`,test_id:`activity-status`},{key:`activity.unknown_time`,en:`Unknown`,ko:`알 수 없음`,test_id:`activity-unknown-time`},{key:`activity.metric.active_requests`,en:`Active requests`,ko:`활성 요청`,test_id:`activity-metric-active-requests`},{key:`activity.metric.queued_requests`,en:`Queued requests`,ko:`대기 요청`,test_id:`activity-metric-queued-requests`},{key:`activity.metric.completed_requests_total`,en:`Total completed requests`,ko:`누적 완료 요청`,test_id:`activity-metric-completed-requests-total`},{key:`activity.metric.completion_tokens_total`,en:`Total completion tokens`,ko:`누적 완료 토큰`,test_id:`activity-metric-completion-tokens-total`},{key:`activity.metric.gpu_utilization`,en:`GPU utilization`,ko:`GPU 사용률`,test_id:`activity-metric-gpu-utilization`},{key:`activity.metric.ttft`,en:`Time to first token`,ko:`첫 토큰 도달 시간`,test_id:`activity-metric-ttft`},{key:`activity.metric.decode_rate`,en:`Decode rate`,ko:`디코드 속도`,test_id:`activity-metric-decode-rate`},{key:`activity.metric.process_resident_bytes`,en:`Process resident memory`,ko:`프로세스 상주 메모리`,test_id:`activity-metric-process-resident-bytes`},{key:`activity.metric.allocator_active_bytes`,en:`Active allocator memory`,ko:`할당자 활성 메모리`,test_id:`activity-metric-allocator-active-bytes`},{key:`activity.metric.allocator_cache_bytes`,en:`Cached allocator memory`,ko:`할당자 캐시 메모리`,test_id:`activity-metric-allocator-cache-bytes`},{key:`activity.metric.allocator_peak_bytes`,en:`Peak allocator memory`,ko:`할당자 최대 메모리`,test_id:`activity-metric-allocator-peak-bytes`},{key:`activity.metric.device_total_bytes`,en:`Device memory`,ko:`장치 메모리`,test_id:`activity-metric-device-total-bytes`},{key:`activity.metric.model_weights_bytes`,en:`Model weights estimate`,ko:`모델 가중치 추정량`,test_id:`activity-metric-model-weights-bytes`},{key:`activity.metric.kv_cache_bytes`,en:`KV cache memory`,ko:`KV 캐시 메모리`,test_id:`activity-metric-kv-cache-bytes`},{key:`activity.metric.generation_time_ms_total`,en:`Total generation time`,ko:`누적 생성 시간`,test_id:`activity-metric-generation-time-ms-total`},{key:`activity.metric.decode_tokens_total`,en:`Accepted decode tokens`,ko:`수락된 디코드 토큰`,test_id:`activity-metric-decode-tokens-total`},{key:`activity.metric.decode_time_us_total`,en:`Total decode time`,ko:`누적 디코드 시간`,test_id:`activity-metric-decode-time-us-total`},{key:`activity.metric.prompt_cache_bytes`,en:`Prompt cache memory`,ko:`프롬프트 캐시 메모리`,test_id:`activity-metric-prompt-cache-bytes`},{key:`activity.metric.prompt_cache_entries`,en:`Prompt cache entries`,ko:`프롬프트 캐시 항목`,test_id:`activity-metric-prompt-cache-entries`}],ke=[{key:`app.title`,en:`mlxcel WebUI`,ko:`mlxcel 웹 UI`,test_id:`app-title`},{key:`app.subtitle`,en:`Local model control plane`,ko:`로컬 모델 제어판`,test_id:`app-subtitle`},{key:`nav.models`,en:`Models`,ko:`모델`,test_id:`nav-models`},{key:`nav.chat`,en:`Chat`,ko:`대화`,test_id:`nav-chat`},{key:`nav.activity`,en:`Activity`,ko:`활동`,test_id:`nav-activity`},{key:`nav.settings`,en:`Settings`,ko:`설정`,test_id:`nav-settings`},{key:`nav.gallery`,en:`Gallery`,ko:`갤러리`,test_id:`nav-gallery`},{key:`nav.primary`,en:`Primary navigation`,ko:`주 내비게이션`,test_id:`nav-primary`},{key:`nav.home`,en:`mlxcel home`,ko:`mlxcel 홈`,test_id:`nav-home`},{key:`toolbar.command`,en:`Command`,ko:`명령`,test_id:`toolbar-command`},{key:`toolbar.help`,en:`Keyboard help`,ko:`키보드 도움말`,test_id:`toolbar-help`},{key:`toolbar.logout`,en:`Clear WebUI session`,ko:`WebUI 세션 지우기`,test_id:`toolbar-logout`},{key:`toolbar.menu`,en:`Open navigation`,ko:`내비게이션 열기`,test_id:`toolbar-menu`},{key:`toolbar.loaded.label`,en:`Loaded models`,ko:`로드된 모델`,test_id:`toolbar-loaded`},{key:`toolbar.loaded.none`,en:`No model loaded`,ko:`로드된 모델 없음`,test_id:`toolbar-loaded-none`},{key:`toolbar.loaded.unknown`,en:`Loaded models unknown`,ko:`로드된 모델 알 수 없음`,test_id:`toolbar-loaded-unknown`},{key:`toolbar.loaded.count`,en:`{count} loaded`,ko:`{count}개 로드됨`,test_id:`toolbar-loaded-count`},{key:`toolbar.loaded.more`,en:`+{count}`,ko:`+{count}`,test_id:`toolbar-loaded-more`},{key:`toolbar.loaded.more_label`,en:`+{count}, show all loaded models`,ko:`+{count}, 로드된 모델 모두 보기`,test_id:`toolbar-loaded-more-label`},{key:`connection.ready`,en:`Shell loaded; local API not connected`,ko:`셸 로드됨; 로컬 API 미연결`,test_id:`connection-ready`},{key:`connection.offline`,en:`Server connection is offline`,ko:`서버 연결이 오프라인입니다`,test_id:`connection-offline`},{key:`connection.prompt.title`,en:`Connect to the local WebUI API`,ko:`로컬 WebUI API에 연결하세요`,test_id:`connection-prompt-title`},{key:`connection.prompt.body`,en:`The shell is loaded, but catalog, chat and activity data wait for the authenticated local server connection.`,ko:`셸은 로드되었지만 카탈로그, 대화, 활동 데이터는 인증된 로컬 서버 연결을 기다립니다.`,test_id:`connection-prompt-body`},{key:`connection.prompt.detail`,en:`Start mlxcel-server with --webui, enter the terminal session key when prompted, then refresh this view.`,ko:`mlxcel-server를 --webui로 시작하고, 요청되면 터미널 세션 키를 입력한 뒤 이 화면을 새로고침하세요.`,test_id:`connection-prompt-detail`},{key:`connection.footer.connected`,en:`{mode} · {status} · v{version}`,ko:`{mode} · {status} · v{version}`,test_id:`connection-footer-connected`},{key:`connection.footer.details`,en:`Connection details`,ko:`연결 세부 정보`,test_id:`connection-footer-details`},{key:`connection.footer.instance`,en:`Server instance: {id}`,ko:`서버 인스턴스: {id}`,test_id:`connection-footer-instance`},{key:`connection.footer.sequence`,en:`Event sequence: {sequence}`,ko:`이벤트 순번: {sequence}`,test_id:`connection-footer-sequence`},{key:`connection.snapshot.pending`,en:`pending`,ko:`대기 중`,test_id:`connection-snapshot-pending`},{key:`connection.authenticated.title`,en:`Authenticated local API session`,ko:`인증된 로컬 API 세션`,test_id:`connection-authenticated-title`},{key:`connection.authenticated.body`,en:`This route is connected to the shared provider. Browsing does not load models or start inference; load, unload and chat actions remain explicit.`,ko:`이 경로는 공유 provider에 연결되어 있습니다. 탐색만으로 모델을 로드하거나 추론을 시작하지 않으며, 로드·언로드·대화 동작은 명시적으로 실행됩니다.`,test_id:`connection-authenticated-body`},{key:`connection.authenticated.detail`,en:`Backend {mode}; build {version}; state {status}; catalog {count}; operations {operations}; snapshot {sequence}.`,ko:`백엔드 {mode}; 빌드 {version}; 상태 {status}; 카탈로그 {count}; 작업 {operations}; 스냅샷 {sequence}.`,test_id:`connection-authenticated-detail`},{key:`connection.error.title`,en:`Provider connection needs attention`,ko:`Provider 연결 확인 필요`,test_id:`connection-error-title`},{key:`connection.error.stale`,en:`The server snapshot changed; retry to take a fresh catalog and operation snapshot before continuing.`,ko:`서버 스냅샷이 바뀌었습니다. 계속하기 전에 다시 시도해 새 카탈로그와 작업 스냅샷을 가져오세요.`,test_id:`connection-error-stale`},{key:`connection.error.forbidden`,en:`The authenticated session is not allowed to access this UI endpoint.`,ko:`인증된 세션이 이 UI 엔드포인트에 접근할 수 없습니다.`,test_id:`connection-error-forbidden`},{key:`connection.error.unauthorized`,en:`The server rejected the current session key. Sign in again with the latest terminal key.`,ko:`서버가 현재 세션 키를 거부했습니다. 터미널에 표시된 최신 키로 다시 로그인하세요.`,test_id:`connection-error-unauthorized`},{key:`connection.error.generic`,en:`Retry the shared provider snapshot before issuing any model control action.`,ko:`모델 제어 동작을 실행하기 전에 공유 provider 스냅샷을 다시 가져오세요.`,test_id:`connection-error-generic`},{key:`connection.status.idle`,en:`idle`,ko:`대기`,test_id:`connection-status-idle`},{key:`connection.status.bootstrapping`,en:`bootstrapping`,ko:`부트스트랩`,test_id:`connection-status-bootstrapping`},{key:`connection.status.ready`,en:`ready`,ko:`준비`,test_id:`connection-status-ready`},{key:`connection.status.streaming`,en:`streaming`,ko:`스트리밍`,test_id:`connection-status-streaming`},{key:`connection.status.polling`,en:`polling`,ko:`폴링`,test_id:`connection-status-polling`},{key:`connection.status.offline`,en:`offline`,ko:`오프라인`,test_id:`connection-status-offline`},{key:`connection.status.stale`,en:`stale`,ko:`낡음`,test_id:`connection-status-stale`},{key:`connection.status.unauthorized`,en:`unauthorized`,ko:`인증 실패`,test_id:`connection-status-unauthorized`},{key:`connection.status.forbidden`,en:`forbidden`,ko:`거부됨`,test_id:`connection-status-forbidden`},{key:`connection.status.schema_mismatch`,en:`schema mismatch`,ko:`스키마 불일치`,test_id:`connection-status-schema-mismatch`},{key:`connection.status.error`,en:`error`,ko:`오류`,test_id:`connection-status-error`},{key:`auth.login`,en:`WebUI session login`,ko:`WebUI 세션 로그인`,test_id:`auth-login`},{key:`models.title`,en:`Model library`,ko:`모델 라이브러리`,test_id:`models-title`},{key:`models.empty.title`,en:`No local models yet`,ko:`아직 로컬 모델이 없습니다`,test_id:`models-empty-title`},{key:`models.empty.body`,en:`Browse, download, and load models explicitly. The shell never autoloads a checkpoint.`,ko:`모델을 명시적으로 탐색, 다운로드, 로드하세요. 셸은 체크포인트를 자동 로드하지 않습니다.`,test_id:`models-empty-body`},{key:`models.long_name`,en:`Qwen3-Very-Long-Local-Checkpoint-Name-With-Mixed-English-and-한국어-모델-이름`,ko:`Qwen3-Very-Long-Local-Checkpoint-Name-With-Mixed-English-and-한국어-모델-이름`,test_id:`models-long-name`},{key:`models.unsupported.reason`,en:`Vision input is unavailable for this backend; chat remains text-only.`,ko:`이 백엔드에서는 비전 입력을 사용할 수 없어 대화는 텍스트 전용입니다.`,test_id:`models-unsupported-reason`},{key:`models.load`,en:`Load`,ko:`로드`,test_id:`models-load`},{key:`models.unload`,en:`Unload`,ko:`언로드`,test_id:`models-unload`},{key:`models.status.ready`,en:`Ready`,ko:`준비됨`,test_id:`models-status-ready`},{key:`models.status.unloaded`,en:`Unloaded`,ko:`언로드됨`,test_id:`models-status-unloaded`},{key:`models.status.failed`,en:`Failed`,ko:`실패`,test_id:`models-status-failed`},{key:`models.status.loading`,en:`Loading`,ko:`로드 중`,test_id:`models-status-loading`},{key:`models.status.draining`,en:`Draining`,ko:`drain 중`,test_id:`models-status-draining`},{key:`models.status.unloading`,en:`Unloading`,ko:`언로드 중`,test_id:`models-status-unloading`},{key:`models.delete.confirm.title`,en:`Delete model from cache?`,ko:`캐시에서 모델을 삭제할까요?`,test_id:`dialog-delete-model-title`},{key:`models.delete.confirm.body`,en:`Delete {model} from the managed cache. Loaded or non-cache models cannot be deleted.`,ko:`관리 캐시에서 {model} 모델을 삭제합니다. 로드 중이거나 캐시 모델이 아니면 삭제할 수 없습니다.`,test_id:`dialog-delete-model-body`},{key:`models.delete.confirm.token_label`,en:`Type DELETE to confirm`,ko:`확인하려면 DELETE를 입력하세요`,test_id:`dialog-delete-model-token`},{key:`models.unload.confirm.body`,en:`Unload {model} after active requests drain; browser tabs will keep their selected model.`,ko:`활성 요청이 비워진 뒤 {model} 모델을 언로드합니다. 브라우저 탭의 선택 모델은 유지됩니다.`,test_id:`dialog-unload-model-body`},{key:`chat.title`,en:`Chat`,ko:`대화`,test_id:`chat-title`},{key:`chat.placeholder`,en:`Type a message; IME composition is preserved.`,ko:`메시지를 입력하세요. IME 조합은 보존됩니다.`,test_id:`chat-placeholder`},{key:`chat.streaming.status`,en:`Streaming tokens from the selected ready model.`,ko:`선택한 준비 모델에서 토큰을 스트리밍 중입니다.`,test_id:`chat-streaming-status`},{key:`chat.reasoning`,en:`Reasoning`,ko:`추론`,test_id:`chat-reasoning`},{key:`chat.tool_call`,en:`Tool call preview`,ko:`도구 호출 미리보기`,test_id:`chat-tool-call`},{key:`downloads.cancel.confirm.body`,en:`Cancel this download only after the server acknowledges worker shutdown.`,ko:`서버가 작업자 중지를 확인한 뒤에만 이 다운로드를 취소합니다.`,test_id:`dialog-cancel-download-body`},{key:`activity.title`,en:`Activity`,ko:`활동`,test_id:`activity-title`},{key:`activity.progress.indeterminate`,en:`Downloaded {bytes}; total size is not known yet.`,ko:`{bytes} 다운로드됨; 전체 크기는 아직 알 수 없습니다.`,test_id:`activity-progress-indeterminate`},{key:`activity.sse_reset`,en:`Event stream reset; take a fresh snapshot before resuming updates.`,ko:`이벤트 스트림이 재설정되었습니다. 업데이트를 재개하기 전에 새 스냅샷을 가져오세요.`,test_id:`activity-sse-reset`},{key:`settings.title`,en:`Settings`,ko:`설정`,test_id:`settings-title`},{key:`settings.appearance`,en:`Appearance preferences`,ko:`화면 표시 설정`,test_id:`settings-appearance`},{key:`settings.theme`,en:`Theme`,ko:`테마`,test_id:`settings-theme`},{key:`settings.color_scheme`,en:`Color scheme`,ko:`색상 모드`,test_id:`settings-color-scheme`},{key:`settings.material`,en:`Material`,ko:`재질`,test_id:`settings-material`},{key:`settings.glass_intensity`,en:`Glass intensity`,ko:`글래스 강도`,test_id:`settings-glass-intensity`},{key:`settings.reduce_motion`,en:`Reduce motion`,ko:`동작 줄이기`,test_id:`settings-reduce-motion`},{key:`settings.reduce_transparency`,en:`Reduce transparency`,ko:`투명도 줄이기`,test_id:`settings-reduce-transparency`},{key:`settings.high_contrast`,en:`High contrast`,ko:`고대비`,test_id:`settings-high-contrast`},{key:`settings.locale`,en:`Language`,ko:`언어`,test_id:`settings-locale`},{key:`settings.partial_success`,en:`Some settings changed; fields controlled by CLI or the loaded worker were left unchanged.`,ko:`일부 설정만 변경되었습니다. CLI 또는 로드된 워커가 제어하는 필드는 변경되지 않았습니다.`,test_id:`settings-partial-success`},{key:`settings.browser_only`,en:`Browser appearance only`,ko:`브라우저 표시 설정 전용`,test_id:`settings-browser-only`},{key:`settings.browser_only.body`,en:`These preferences stay in this browser and do not claim server or worker settings changed.`,ko:`이 설정은 이 브라우저에만 남으며 서버나 워커 설정 변경을 의미하지 않습니다.`,test_id:`settings-browser-only-body`},{key:`settings.clear_history.confirm.body`,en:`Clear only the explicit local browser history store; API keys are never persisted there.`,ko:`명시적으로 켠 로컬 브라우저 기록 저장소만 지웁니다. API 키는 그곳에 저장하지 않습니다.`,test_id:`dialog-clear-history-body`},{key:`state.unauthorized.title`,en:`Authentication required`,ko:`인증이 필요합니다`,test_id:`state-unauthorized-title`},{key:`state.unauthorized.body`,en:`Enter the session key printed by the local server terminal.`,ko:`로컬 서버 터미널에 한 번 표시된 세션 키를 입력하세요.`,test_id:`state-unauthorized-body`},{key:`state.offline.title`,en:`Server offline`,ko:`서버 오프라인`,test_id:`state-offline-title`},{key:`state.offline.body`,en:`The shell is available, but model data waits for the local API.`,ko:`셸은 사용할 수 있지만 모델 데이터는 로컬 API를 기다립니다.`,test_id:`state-offline-body`},{key:`state.schema_mismatch.title`,en:`UI schema mismatch`,ko:`UI 스키마 불일치`,test_id:`state-schema-mismatch-title`},{key:`state.schema_mismatch.body`,en:`The shell loaded, but the server reports a different UI API schema version; refresh after updating the bundle or server.`,ko:`셸은 로드되었지만 서버가 다른 UI API 스키마 버전을 보고했습니다. 번들이나 서버를 업데이트한 뒤 새로고침하세요.`,test_id:`state-schema-mismatch-body`},{key:`command.title`,en:`Command palette`,ko:`명령 팔레트`,test_id:`command-title`},{key:`select.search`,en:`Search options`,ko:`옵션 검색`,test_id:`select-search`},{key:`select.no_options`,en:`No matching options.`,ko:`일치하는 옵션이 없습니다.`,test_id:`select-no-options`},{key:`command.search`,en:`Search commands and models`,ko:`명령과 모델 검색`,test_id:`command-search`},{key:`command.no_results`,en:`No commands or models match this search.`,ko:`검색과 일치하는 명령이나 모델이 없습니다.`,test_id:`command-no-results`},{key:`command.section.commands`,en:`Commands`,ko:`명령`,test_id:`command-section-commands`},{key:`command.section.models`,en:`Models`,ko:`모델`,test_id:`command-section-models`},{key:`help.title`,en:`Keyboard shortcuts`,ko:`키보드 단축키`,test_id:`help-title`},{key:`help.body`,en:`Shortcuts do not fire while you type in a field, inside an open dialog (Esc still closes it) or during IME composition. Cmd/Ctrl+N and Cmd/Ctrl+Enter also work in the chat message field. Brackets move navigation only while the sidebar has focus.`,ko:`입력란에 입력하는 중, 열린 다이얼로그 안(Esc로 닫기는 가능), IME 조합 중에는 단축키가 동작하지 않습니다. Cmd/Ctrl+N과 Cmd/Ctrl+Enter는 대화 메시지 입력란에서도 동작합니다. 대괄호는 사이드바에 포커스가 있을 때만 내비게이션을 이동합니다.`,test_id:`help-body`},{key:`help.shortcut.command`,en:`Open the command palette`,ko:`명령 팔레트 열기`,test_id:`help-shortcut-command`},{key:`help.shortcut.new_chat`,en:`Start a new conversation`,ko:`새 대화 시작`,test_id:`help-shortcut-new-chat`},{key:`help.shortcut.send`,en:`Send the message from the composer`,ko:`입력 중인 메시지 보내기`,test_id:`help-shortcut-send`},{key:`help.shortcut.escape`,en:`Close the open dialog or navigation`,ko:`열린 다이얼로그나 내비게이션 닫기`,test_id:`help-shortcut-escape`},{key:`help.shortcut.navigate`,en:`Move primary navigation while the sidebar has focus`,ko:`사이드바에 포커스가 있을 때 주 내비게이션 이동`,test_id:`help-shortcut-navigate`},{key:`help.shortcut.help`,en:`Show keyboard shortcuts`,ko:`키보드 단축키 보기`,test_id:`help-shortcut-help`},{key:`gallery.title`,en:`Design system gallery`,ko:`디자인 시스템 갤러리`,test_id:`gallery-title`},{key:`gallery.subtitle`,en:`Shared tokens, controls, states, and viewport fixtures for page implementers.`,ko:`페이지 구현자를 위한 공유 토큰, 컨트롤, 상태, 뷰포트 픽스처입니다.`,test_id:`gallery-subtitle`},{key:`gallery.long_cjk`,en:`Long English and 한국어 labels truncate with accessible full labels.`,ko:`긴 English 및 한국어 레이블은 접근 가능한 전체 레이블을 유지하며 줄임표 처리됩니다.`,test_id:`gallery-long-cjk`},{key:`common.unavailable`,en:`Unavailable until server adapters connect`,ko:`서버 어댑터 연결 전에는 사용할 수 없습니다`,test_id:`common-unavailable`},{key:`common.cancel`,en:`Cancel`,ko:`취소`,test_id:`common-cancel`},{key:`common.delete`,en:`Delete`,ko:`삭제`,test_id:`common-delete`},{key:`common.retry`,en:`Retry`,ko:`다시 시도`,test_id:`common-retry`},{key:`common.reload`,en:`Reload`,ko:`새로고침`,test_id:`common-reload`},{key:`common.enter_key`,en:`Enter key`,ko:`키 입력`,test_id:`common-enter-key`},{key:`common.add_model`,en:`Add model`,ko:`모델 추가`,test_id:`common-add-model`},{key:`common.send`,en:`Send`,ko:`보내기`,test_id:`common-send`},{key:`adapters.pending.title`,en:`Local API is not connected yet`,ko:`로컬 API가 아직 연결되지 않았습니다`,test_id:`adapters-pending-title`},{key:`adapters.pending.body`,en:`This route shows the production shell only. Catalog, lifecycle, and runtime data will come from the shared typed client in the integration wave.`,ko:`이 경로는 프로덕션 셸만 보여줍니다. 카탈로그, 수명주기, 런타임 데이터는 통합 웨이브의 공유 typed client에서 제공됩니다.`,test_id:`adapters-pending-body`},{key:`chat.pending.body`,en:`Chat controls stay disabled until an authenticated ready model is selected by the shared state provider.`,ko:`공유 상태 provider가 인증된 준비 모델을 선택하기 전까지 대화 컨트롤은 비활성화됩니다.`,test_id:`chat-pending-body`},{key:`activity.empty.title`,en:`No active operations`,ko:`활성 작업 없음`,test_id:`activity-empty-title`},{key:`activity.empty.body`,en:`Loads, downloads, drains and SSE resets appear here after the lifecycle adapter connects.`,ko:`수명주기 어댑터가 연결된 뒤 로드, 다운로드, drain, SSE reset이 여기에 표시됩니다.`,test_id:`activity-empty-body`},{key:`gallery.tab.sections`,en:`Gallery sections`,ko:`갤러리 섹션`,test_id:`gallery-tab-sections`},{key:`gallery.tab.controls`,en:`Controls`,ko:`컨트롤`,test_id:`gallery-tab-controls`},{key:`gallery.tab.states`,en:`States`,ko:`상태`,test_id:`gallery-tab-states`},{key:`gallery.tab.data`,en:`Data display`,ko:`데이터 표시`,test_id:`gallery-tab-data`},{key:`gallery.controls.title`,en:`Buttons and fields`,ko:`버튼과 필드`,test_id:`gallery-controls-title`},{key:`gallery.controls.primary`,en:`Primary`,ko:`기본`,test_id:`gallery-controls-primary`},{key:`gallery.controls.secondary`,en:`Secondary`,ko:`보조`,test_id:`gallery-controls-secondary`},{key:`gallery.controls.danger`,en:`Danger`,ko:`위험`,test_id:`gallery-controls-danger`},{key:`gallery.controls.busy`,en:`Busy`,ko:`진행 중`,test_id:`gallery-controls-busy`},{key:`gallery.field.repo`,en:`Repository ID`,ko:`저장소 ID`,test_id:`gallery-field-repo`},{key:`gallery.field.repo_error`,en:`Use owner/name without a URL.`,ko:`URL 없이 owner/name 형식을 사용하세요.`,test_id:`gallery-field-repo-error`},{key:`gallery.field.repo_hint`,en:`Sample only; downloads require the later lifecycle adapter.`,ko:`샘플 전용입니다. 다운로드는 후속 수명주기 어댑터가 필요합니다.`,test_id:`gallery-field-repo-hint`},{key:`gallery.progress.measured`,en:`Sample download progress`,ko:`예시 다운로드 진행률`,test_id:`gallery-progress-measured`},{key:`gallery.select.native`,en:`Shared select combobox`,ko:`공통 선택 콤보박스`,test_id:`gallery-select-native`},{key:`gallery.overlays.title`,en:`Overlays`,ko:`오버레이`,test_id:`gallery-overlays-title`},{key:`gallery.tooltip`,en:`Tooltips are descriptive only`,ko:`툴팁은 설명 전용입니다`,test_id:`gallery-tooltip`},{key:`gallery.dialog.open`,en:`Open dialog`,ko:`다이얼로그 열기`,test_id:`gallery-dialog-open`},{key:`gallery.states.load_failed`,en:`Load failed`,ko:`로드 실패`,test_id:`gallery-states-load-failed`},{key:`gallery.states.load_failed_body`,en:`The worker exited before becoming ready; retry after checking logs.`,ko:`워커가 준비되기 전에 종료되었습니다. 로그 확인 후 다시 시도하세요.`,test_id:`gallery-states-load-failed-body`},{key:`gallery.data.title`,en:`Model rows`,ko:`모델 행`,test_id:`gallery-data-title`},{key:`gallery.data.name`,en:`Name`,ko:`이름`,test_id:`gallery-data-name`},{key:`gallery.data.status`,en:`Status`,ko:`상태`,test_id:`gallery-data-status`},{key:`gallery.data.rate`,en:`Rate`,ko:`속도`,test_id:`gallery-data-rate`},{key:`gallery.data.inspector`,en:`Inspector`,ko:`인스펙터`,test_id:`gallery-data-inspector`},{key:`gallery.sample.reasoning_body`,en:`Reasoning text is visually separated from answer content.`,ko:`추론 텍스트는 답변 본문과 시각적으로 분리됩니다.`,test_id:`gallery-sample-reasoning-body`},{key:`gallery.sample.tool_preview`,en:`{ "tool": "display_only" }`,ko:`{ "tool": "표시_전용" }`,test_id:`gallery-sample-tool-preview`},{key:`common.close`,en:`Close`,ko:`닫기`,test_id:`common-close`},{key:`settings.theme.mlxcel`,en:`Standard`,ko:`표준`,test_id:`settings-theme-mlxcel`},{key:`settings.theme.glass`,en:`Glass`,ko:`글래스`,test_id:`settings-theme-glass`},{key:`settings.color_scheme.system`,en:`System`,ko:`시스템`,test_id:`settings-color-scheme-system`},{key:`settings.color_scheme.light`,en:`Light`,ko:`라이트`,test_id:`settings-color-scheme-light`},{key:`settings.color_scheme.dark`,en:`Dark`,ko:`다크`,test_id:`settings-color-scheme-dark`},{key:`settings.material.glass`,en:`Glass`,ko:`글래스`,test_id:`settings-material-glass`},{key:`settings.material.tinted`,en:`Tinted`,ko:`틴트`,test_id:`settings-material-tinted`},{key:`settings.material.opaque`,en:`Opaque`,ko:`불투명`,test_id:`settings-material-opaque`},{key:`settings.locale.en`,en:`English`,ko:`영어`,test_id:`settings-locale-en`},{key:`settings.locale.ko`,en:`Korean`,ko:`한국어`,test_id:`settings-locale-ko`},{key:`settings.high_contrast.system`,en:`Follow system`,ko:`시스템 따르기`,test_id:`settings-high-contrast-system`},{key:`settings.high_contrast.on`,en:`On`,ko:`켬`,test_id:`settings-high-contrast-on`},{key:`settings.high_contrast.off`,en:`Off`,ko:`끔`,test_id:`settings-high-contrast-off`},{key:`gallery.hover_focus`,en:`Hover or focus`,ko:`호버 또는 포커스`,test_id:`gallery-hover-focus`},{key:`gallery.download`,en:`Download`,ko:`다운로드`,test_id:`gallery-download`},{key:`gallery.lifecycle.samples`,en:`Lifecycle sample badges`,ko:`수명주기 샘플 배지`,test_id:`gallery-lifecycle-samples`},{key:`gallery.sample.caption`,en:`Sample model table`,ko:`샘플 모델 표`,test_id:`gallery-sample-caption`},{key:`gallery.sample.label`,en:`Sample fixture`,ko:`샘플 픽스처`,test_id:`gallery-sample-label`},{key:`login.token.label`,en:`Session key`,ko:`세션 키`,test_id:`login-token-label`},{key:`login.token.help`,en:`Use the key printed once by the local server. It stays in memory only.`,ko:`로컬 서버가 한 번 출력한 키를 사용하세요. 키는 메모리에만 유지됩니다.`,test_id:`login-token-help`},{key:`login.submit`,en:`Connect`,ko:`연결`,test_id:`login-submit`},{key:`login.logout`,en:`Clear key`,ko:`키 지우기`,test_id:`login-logout`},{key:`login.error.sample`,en:`Sample error: the key was not accepted by the local API.`,ko:`샘플 오류: 로컬 API가 키를 허용하지 않았습니다.`,test_id:`login-error-sample`},{key:`login.error.wrong_key`,en:`The session key was rejected. Copy the latest key printed by the local server terminal.`,ko:`세션 키가 거부되었습니다. 로컬 서버 터미널에 표시된 최신 키를 복사하세요.`,test_id:`login-error-wrong-key`},{key:`login.error.offline`,en:`Could not reach the local WebUI API. Check that mlxcel-server is still running with --webui.`,ko:`로컬 WebUI API에 연결할 수 없습니다. mlxcel-server가 --webui로 계속 실행 중인지 확인하세요.`,test_id:`login-error-offline`},{key:`login.error.forbidden`,en:`The key authenticated, but this UI endpoint is forbidden for the current server session.`,ko:`키 인증은 되었지만 현재 서버 세션에서 이 UI 엔드포인트가 금지되어 있습니다.`,test_id:`login-error-forbidden`},{key:`login.error.schema`,en:`The server response does not match this bundled UI schema. Reload after updating the server or bundle.`,ko:`서버 응답이 번들된 UI 스키마와 일치하지 않습니다. 서버나 번들을 업데이트한 뒤 새로고침하세요.`,test_id:`login-error-schema`},{key:`login.error.generic`,en:`The local API could not complete authentication. Retry with the latest terminal key.`,ko:`로컬 API 인증을 완료할 수 없습니다. 터미널에 표시된 최신 키로 다시 시도하세요.`,test_id:`login-error-generic`},{key:`gallery.delete_token`,en:`DELETE`,ko:`DELETE`,test_id:`gallery-delete-token`},{key:`models.next_profile.body`,en:`Pending browser profile; not applied yet. Explicit CLI/environment settings take precedence. Read effective values after loading.`,ko:`대기 중인 브라우저 프로필이며 아직 적용되지 않았습니다. 명시적 CLI/환경 설정이 우선합니다. 실제 값은 로드 후 확인하세요.`,test_id:`models-next-profile-body`},{key:`models.next_profile.edit`,en:`Edit profile`,ko:`프로필 편집`,test_id:`models-next-profile-edit`},{key:`format.unknown`,en:`unknown`,ko:`알 수 없음`,test_id:`format-unknown`},{key:`format.not_measured`,en:`not yet measured`,ko:`아직 측정되지 않음`,test_id:`format-not-measured`},...Te,...Ee,...De,...Oe],Ae=new Map(ke.map(e=>[e.key,e]));function R(e,t,n={}){let r=Ae.get(t);return r?r[e].replace(/\{(\w+)\}/g,(e,t)=>Object.hasOwn(n,t)?n[t]:`{${t}}`):t}function z(e){return Ae.get(e)?.test_id??e.replaceAll(`.`,`-`)}function je(e){let t=(0,_.useContext)(Se),n=(0,_.useId)(),r=`${n}-hint`,i=`${n}-error`,a=[e.hint?r:null,e.error?i:null].filter(Boolean).join(` `)||void 0,o=e.disabled||e.busy,s=(0,x.jsxs)(x.Fragment,{children:[e.hint?(0,x.jsx)(`small`,{id:r,"data-tone":`hint`,children:e.hint}):null,e.error?(0,x.jsx)(`small`,{id:i,"data-tone":`error`,children:e.error}):null]});return t?(0,x.jsxs)(`label`,{className:`ds-field`,htmlFor:n,"data-disabled":o||void 0,children:[(0,x.jsx)(`span`,{children:e.label}),(0,x.jsx)(`select`,{id:n,value:e.value,disabled:o,"aria-busy":e.busy||void 0,"aria-invalid":e.error?`true`:void 0,"aria-describedby":a,"data-testid":e.testId,onChange:t=>e.onChange(t.currentTarget.value),children:e.options.map(e=>(0,x.jsx)(`option`,{...e,children:e.label},e.value))}),s]}):(0,x.jsxs)(`div`,{ref:t=>{let n=t?.querySelector(`.select__trigger`);n?.setAttribute(`role`,`combobox`),e.busy?n?.setAttribute(`aria-busy`,`true`):n?.removeAttribute(`aria-busy`)},onKeyDownCapture:e=>{e.nativeEvent.isComposing&&e.stopPropagation()},className:`ds-field ds-common-select`,"data-disabled":o||void 0,"aria-busy":e.busy||void 0,"data-testid":e.testId,children:[(0,x.jsx)(we,{value:e.value,options:e.options,onChange:e.onChange,label:e.label,disabled:o,invalid:!!e.error,"aria-describedby":a,fullWidth:!0,noOptionsLabel:R(e.locale??`en`,`select.no_options`),searchPlaceholder:R(e.locale??`en`,`select.search`)}),s]})}var Me={narrow:`400px`,medium:`520px`,wide:`900px`};function Ne({isOpen:e,onClose:t,title:n,subtitle:r,width:i=`medium`,children:a,footer:o,className:s=``,ariaLabelledBy:c,ariaDescribedBy:l,closeLabel:u=`Close`,preventDismiss:d=!1,onDismissAttempt:f}){let p=(0,_.useRef)(null),[m,h]=(0,_.useState)(!1),g=(0,_.useRef)(d);g.current=d;let v=(0,_.useRef)(f);v.current=f;let y=(0,_.useCallback)(()=>g.current?(h(!0),v.current?.(),!0):!1,[]),b=(0,_.useCallback)(e=>{e.animationName===`drawer-shake`&&h(!1)},[]),S=(0,_.useRef)(null),C=(0,_.useRef)(null),[w,T]=(0,_.useState)(!1),E=(0,_.useRef)(!1);(0,_.useEffect)(()=>{e&&!E.current?(E.current=!0,requestAnimationFrame(()=>{requestAnimationFrame(()=>{T(!0)})})):T(!!e)},[e]);let D=e&&w,O=i in Me?Me[i]:i,k=c||`drawer-title`,ee=l||(r?`drawer-subtitle`:void 0);(0,_.useEffect)(()=>{if(!e)return;S.current=document.activeElement;let n=p.current;if(!n)return;requestAnimationFrame(()=>{C.current?.focus()});let r=n.querySelectorAll(`button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])`),i=r[0],a=r[r.length-1],o=e=>{if(e.key===`Escape`){if(y())return;t();return}e.key===`Tab`&&(e.shiftKey?document.activeElement===i&&(e.preventDefault(),a?.focus()):document.activeElement===a&&(e.preventDefault(),i?.focus()))};return n.addEventListener(`keydown`,o),()=>{n.removeEventListener(`keydown`,o),S.current&&S.current.focus()}},[e,t,y]);let A=(0,_.useCallback)(e=>{if(e.target===e.currentTarget){if(y())return;t()}},[t,y]);return(0,x.jsx)(`div`,{className:`drawer__backdrop ${D?`drawer__backdrop--open`:``}`,onClick:A,role:`presentation`,"aria-hidden":!e,inert:!e,children:(0,x.jsxs)(`aside`,{ref:p,className:`drawer ${D?`drawer--open`:``} ${m?`drawer--shaking`:``} ${s}`,style:{width:O,maxWidth:`100vw`},role:`dialog`,"aria-modal":`true`,"aria-labelledby":k,"aria-describedby":ee,onAnimationEnd:b,children:[(0,x.jsxs)(`header`,{className:`drawer__header`,children:[(0,x.jsxs)(`div`,{className:`drawer__title-row`,children:[(0,x.jsx)(`h2`,{id:k,className:`drawer__title`,children:n}),(0,x.jsx)(`button`,{ref:C,type:`button`,className:`drawer__close-btn`,onClick:t,"aria-label":u,children:(0,x.jsxs)(`svg`,{width:`20`,height:`20`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,x.jsx)(`path`,{d:`M18 6L6 18`}),(0,x.jsx)(`path`,{d:`M6 6l12 12`})]})})]}),r&&(0,x.jsx)(`p`,{id:ee,className:`drawer__subtitle`,children:r})]}),(0,x.jsx)(`div`,{className:`drawer__content`,children:a}),o&&(0,x.jsx)(`footer`,{className:`drawer__footer`,children:o})]})})}var Pe=120;function Fe({content:e,children:t,className:n,contentClassName:r,tooltipId:i,tabIndex:a=0,toggleable:o=!1}){let[s,c]=(0,_.useState)(!1),[l,u]=(0,_.useState)(null),d=(0,_.useRef)(null),f=(0,_.useRef)(null),p=(0,_.useRef)(!0),m=(0,_.useRef)(null),h=(0,_.useId)(),g=i??`tooltip-${h}`;(0,_.useEffect)(()=>(p.current=!0,()=>{p.current=!1,m.current!==null&&clearTimeout(m.current)}),[]),(0,_.useEffect)(()=>{let e=f.current;if(!e)return;let t=()=>{p.current&&c(!0)},n=()=>{p.current&&(c(!1),u(null))};return e.addEventListener(`focusin`,t),e.addEventListener(`focusout`,n),()=>{e.removeEventListener(`focusin`,t),e.removeEventListener(`focusout`,n)}},[]);let v=(0,_.useCallback)(()=>{let e=f.current,t=d.current;if(!p.current||!e||!t)return;let n=e.getBoundingClientRect(),r=t.getBoundingClientRect(),i=n.top,a=window.innerHeight-n.bottom,o=r.height,s=ii?`bottom`:`top`,c=n.left+n.width/2,l=r.width,m=c-l/2,h=window.innerWidth;m+l>h-16&&(m=h-l-16),m<16&&(m=16);let g=s===`top`?n.top-o-8:n.bottom+8;u({top:g,left:m,placement:s})},[]);(0,_.useLayoutEffect)(()=>{if(s)return v(),window.addEventListener(`scroll`,v,{capture:!0,passive:!0}),window.addEventListener(`resize`,v),()=>{window.removeEventListener(`scroll`,v,{capture:!0}),window.removeEventListener(`resize`,v)}},[s,v]);let y=(0,_.useCallback)(()=>{m.current!==null&&(clearTimeout(m.current),m.current=null),c(!0)},[]),b=(0,_.useCallback)(()=>{m.current!==null&&(clearTimeout(m.current),m.current=null),c(!1),u(null)},[]),S=(0,_.useCallback)(()=>{m.current!==null&&clearTimeout(m.current),m.current=setTimeout(()=>{m.current=null,p.current&&(c(!1),u(null))},Pe)},[]);(0,_.useEffect)(()=>{if(!s)return;let e=e=>{e.key===`Escape`&&b()};return document.addEventListener(`keydown`,e),()=>{document.removeEventListener(`keydown`,e)}},[s,b]);let C=(0,_.useCallback)(e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),s?b():y())},[s,b,y]),w=s&&(0,x.jsx)(`div`,{ref:d,id:g,className:`tooltip__content tooltip__content--${l?.placement??`top`} ${r??``}`,style:l?{top:`${String(l.top)}px`,left:`${String(l.left)}px`}:{visibility:`hidden`},role:`tooltip`,children:typeof e==`string`?(0,x.jsx)(`p`,{className:`tooltip__text`,children:e}):e});return(0,x.jsxs)(`div`,{ref:f,className:`tooltip__wrapper ${n??``}`,onMouseEnter:y,onMouseLeave:S,onKeyDown:o?C:void 0,tabIndex:a,role:o?`button`:void 0,"aria-expanded":o?s:void 0,"aria-describedby":s?g:void 0,children:[t,w&&(0,Ce.createPortal)(w,document.body)]})}var Ie=`min(320px, calc(100vw - 32px))`;function Le(e){let t=(0,_.useId)(),n=(0,_.useRef)(e.onClose);n.current=e.onClose;let r=(0,_.useCallback)(()=>n.current(),[]),i=(0,_.useRef)(null);return(0,_.useEffect)(()=>{if(!e.open)return;let t=0,n=0,a=()=>{let e=i.current?.querySelector(`.drawer`);e&&!e.contains(document.activeElement)&&(e.querySelector(`.drawer__close-btn`)?.focus(),!e.contains(document.activeElement)&&n++<10&&(t=requestAnimationFrame(a)))};t=requestAnimationFrame(a);let o=e=>{if(e.key!==`Escape`||e.isComposing||e.defaultPrevented)return;let t=i.current?.querySelector(`.drawer`);t&&e.target instanceof Node&&t.contains(e.target)||r()};return document.addEventListener(`keydown`,o),()=>{cancelAnimationFrame(t),document.removeEventListener(`keydown`,o)}},[e.open,r]),(0,x.jsx)(`div`,{className:`ds-drawer-host`,ref:t=>{i.current=t,e.testId&&t?.querySelector(`.drawer`)?.setAttribute(`data-testid`,e.testId)},children:(0,x.jsx)(Ne,{isOpen:e.open,onClose:r,title:e.title,closeLabel:e.closeLabel,ariaLabelledBy:t,width:Ie,className:`ds-drawer`,children:e.children})})}function Re(e){let t=(0,_.useContext)(Se),n=(0,_.useId)(),r=[e.children.props[`aria-describedby`],n].filter(Boolean).join(` `),i=_.cloneElement(e.children,{"aria-describedby":r});return t?(0,x.jsxs)(`span`,{className:`ds-tooltip-wrap`,children:[i,(0,x.jsx)(`span`,{className:`ds-tooltip`,role:`tooltip`,id:n,children:e.content})]}):(0,x.jsxs)(Fe,{content:e.content,tabIndex:-1,className:`ds-tooltip-trigger`,children:[i,(0,x.jsx)(`span`,{id:n,hidden:!0,children:e.content})]})}var ze=(0,_.forwardRef)(({children:e,className:t=``,style:n,onClick:r,onKeyDown:i,clickable:a,variant:o=`default`,direction:s=`column`,state:c=`idle`,hoverable:l=!0,ariaLabel:u,role:d,ariaChecked:f,tabIndex:p,testId:m},h)=>{let g=a??!!r,_=e=>{i&&i(e),g&&r&&(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),r())},v=[`base-card`,`base-card--${o}`,s===`row`&&`base-card--row`,l&&`base-card--hoverable`,g&&`base-card--clickable`,c!==`idle`&&`base-card--${c}`,t].filter(Boolean).join(` `);return(0,x.jsx)(`div`,{ref:h,className:v,style:n,onClick:r,onKeyDown:_,role:d??(g?`button`:void 0),tabIndex:g?p??0:p,"aria-label":u,"aria-checked":f,"aria-disabled":c===`disabled`||void 0,"data-testid":m,children:e})});ze.displayName=`BaseCard`;function Be({title:e,description:t,actions:n,error:r,onErrorDismiss:i,className:a=``,errorDetail:o,onRetry:s,retryLabel:c=`Retry`,dismissErrorLabel:l=`Dismiss error`}){let u=[`page-header`,a].filter(Boolean).join(` `);return(0,x.jsxs)(`header`,{className:u,children:[(0,x.jsxs)(`div`,{className:`page-header__content`,children:[(0,x.jsxs)(`div`,{className:`page-header__text`,children:[(0,x.jsx)(`h1`,{className:`page-header__title`,children:e}),t&&(0,x.jsx)(`p`,{className:`page-header__description`,children:t})]}),n&&(0,x.jsx)(`div`,{className:`page-header__actions`,children:n})]}),r&&(0,x.jsxs)(`div`,{className:`page-header__error`,role:`alert`,children:[(0,x.jsxs)(`div`,{className:`page-header__error-body`,children:[(0,x.jsx)(`span`,{className:`page-header__error-text`,children:r}),o&&(0,x.jsx)(`span`,{className:`page-header__error-detail`,children:o})]}),(s||i)&&(0,x.jsxs)(`div`,{className:`page-header__error-actions`,children:[s&&(0,x.jsx)(w,{variant:`secondary`,size:`small`,className:`page-header__error-retry`,onClick:s,children:c}),i&&(0,x.jsx)(`button`,{type:`button`,className:`page-header__error-dismiss`,onClick:i,"aria-label":l,children:`×`})]})]})]})}function Ve({children:e,variant:t=`standard`,className:n=``,...r}){let i=[`page-layout`,`page-layout--${t}`,n].filter(Boolean).join(` `);return(0,x.jsx)(`div`,{className:i,...r,children:e})}var He=250;function Ue({active:e,children:t,className:n}){let r=(0,_.useRef)(null),i=(0,_.useRef)(null),a=(0,_.useRef)(null);return(0,_.useLayoutEffect)(()=>{let t=r.current,n=i.current;if(!t||!n||typeof ResizeObserver>`u`)return;if(!e)return a.current=window.setTimeout(()=>{t.style.height=``,a.current=null},He),()=>{a.current!==null&&(window.clearTimeout(a.current),a.current=null)};a.current!==null&&(window.clearTimeout(a.current),a.current=null);let o=()=>{t.style.height=`${n.offsetHeight.toFixed(0)}px`};o();let s=new ResizeObserver(o);return s.observe(n),()=>{s.disconnect()}},[e]),(0,x.jsx)(`div`,{ref:r,className:`smooth-height${e?` smooth-height--active`:``}${n?` ${n}`:``}`,children:(0,x.jsx)(`div`,{ref:i,className:`smooth-height__content`,children:t})})}function We(e){return(0,x.jsx)(ze,{className:`ds-card surface-card ${e.className??``}`.trim(),role:e.role??`article`,ariaLabel:e.ariaLabel,tabIndex:e.tabIndex,hoverable:!1,children:e.children})}function Ge(e){return(0,x.jsx)(Ve,{variant:`wide`,className:`ds-page-layout ${e.className??``}`.trim(),children:e.children})}function Ke(e){return(0,x.jsx)(`div`,{className:`ds-page-header ${e.className??``}`.trim(),ref:t=>{let n=t?.querySelector(`.page-header__title`),r=t?.querySelector(`.page-header__description`),i=t?.querySelector(`.page-header__error`);n&&(n.tabIndex=-1,n.setAttribute(`data-dialog-focus-fallback`,``),e.titleTestId&&(n.dataset.testid=e.titleTestId)),r&&e.descriptionTestId&&(r.dataset.testid=e.descriptionTestId),i&&e.errorTestId&&(i.dataset.testid=e.errorTestId)},children:(0,x.jsx)(Be,{title:e.title,description:e.description,actions:e.actions,error:e.error,errorDetail:e.errorDetail,onRetry:e.onRetry,retryLabel:e.retryLabel})})}var qe=400;function Je(e){let[t,n]=(0,_.useState)(e.animate),[r,i]=(0,_.useState)(!1),[a,o]=(0,_.useState)(0);return t!==e.animate&&(n(e.animate),e.animate||(i(!0),o(e=>e+1))),(0,_.useEffect)(()=>{if(!r)return;let e=window.setTimeout(()=>i(!1),qe);return()=>window.clearTimeout(e)},[r,a]),(0,x.jsx)(Ue,{active:e.animate||r,className:`ds-smooth-height`,children:e.children})}var Ye=`(prefers-reduced-motion: reduce)`;function Xe(){return typeof window>`u`||typeof window.matchMedia!=`function`?!1:window.matchMedia(Ye).matches}function Ze(){let[e,t]=(0,_.useState)(Xe);return(0,_.useEffect)(()=>{if(typeof window>`u`||typeof window.matchMedia!=`function`)return;let e=window.matchMedia(Ye),n=e=>{t(e.matches)};return e.addEventListener(`change`,n),()=>{e.removeEventListener(`change`,n)}},[]),e}var Qe=800;function $e(e,t){let[n,r]=(0,_.useState)(t?0:e),i=(0,_.useRef)(t?0:e),a=(0,_.useRef)(null);return(0,_.useEffect)(()=>{if(!t){i.current=e,r(e);return}let n=i.current,o=performance.now(),s=t=>{let c=Math.min((t-o)/Qe,1),l=1-(1-c)**3;r(Math.round(n+(e-n)*l)),c<1?a.current=requestAnimationFrame(s):i.current=e};return a.current=requestAnimationFrame(s),()=>{a.current!==null&&cancelAnimationFrame(a.current)}},[e,t]),t?n:e}var et={up:`▲`,down:`▼`,flat:`•`};function tt(e,t){return typeof e==`number`?t?t(e):e.toLocaleString():e}function nt({label:e,labelNode:t,value:n,valueSuffix:r,hint:i,icon:a,tone:o=`default`,trend:s,onClick:c,loading:l=!1,ariaLabel:u,className:d=``,testId:f,format:p,animate:m=!1,sparkline:h,emphasis:g=`default`}){let _=Ze(),v=typeof n==`number`,y=m&&v&&!l&&!_,b=$e(v?n:0,y),S=tt(v&&y?b:n,p),C=u??(l?e:`${e}: ${tt(n,p)}${r??``}`),w=[`stat-card`,`corner-accent`,`stat-card--tone-${o}`,g==="default"?``:`stat-card--${g}`,d].filter(Boolean).join(` `);return(0,x.jsxs)(ze,{className:w,onClick:c,role:c?void 0:`group`,ariaLabel:C,testId:f,children:[(0,x.jsxs)(`div`,{className:`stat-card__header`,children:[(0,x.jsx)(`span`,{className:`stat-card__label`,children:t??e}),a&&(0,x.jsx)(`span`,{className:`stat-card__icon`,"aria-hidden":`true`,children:a})]}),(0,x.jsxs)(`div`,{className:`stat-card__body`,children:[l?(0,x.jsx)(ye,{width:`60%`,height:`2rem`}):h?(0,x.jsxs)(`span`,{className:`stat-card__value-line`,children:[(0,x.jsxs)(`span`,{className:`stat-card__value-row`,children:[(0,x.jsx)(`span`,{className:`stat-card__value`,children:S}),r&&(0,x.jsx)(`span`,{className:`stat-card__value-suffix`,children:r})]}),(0,x.jsx)(`span`,{className:`stat-card__sparkline`,children:h})]}):(0,x.jsxs)(`span`,{className:`stat-card__value-row`,children:[(0,x.jsx)(`span`,{className:`stat-card__value`,children:S}),r&&(0,x.jsx)(`span`,{className:`stat-card__value-suffix`,children:r})]}),s&&!l&&(0,x.jsxs)(`span`,{className:`stat-card__trend stat-card__trend--${s.direction}`,"aria-label":s.ariaLabel??s.label,children:[(0,x.jsx)(`span`,{"aria-hidden":`true`,children:et[s.direction]}),(0,x.jsx)(`span`,{children:s.label})]})]}),i!=null&&(0,x.jsx)(`div`,{className:`stat-card__hint`,children:l?(0,x.jsx)(ye,{width:`80%`,height:`0.85rem`}):i})]})}var rt=(0,_.memo)(nt);function it(e){return(0,x.jsx)(rt,{label:e.label,value:e.value,hint:e.hint,className:`ds-stat-card ${e.className??``}`.trim(),testId:e.testId})}function at(e){return(0,x.jsx)(T,{variant:e.tone===`accent`?`primary`:`default`,className:`ds-badge`,children:e.children})}function ot(e){let t=(0,_.useId)(),n=`${t}-label`,r=`${t}-hint`,i=`${t}-error`,a=[e.hint?r:null,e.error?i:null].filter(Boolean).join(` `)||void 0;return(0,x.jsxs)(`label`,{className:`ds-field`,htmlFor:t,"data-disabled":e.disabled||e.busy||void 0,children:[(0,x.jsx)(`span`,{id:n,children:e.label}),(0,x.jsx)(`input`,{id:t,"aria-labelledby":n,value:e.value,placeholder:e.placeholder,disabled:e.disabled||e.busy,"aria-busy":e.busy||void 0,"aria-invalid":e.error?`true`:void 0,"aria-describedby":a,"data-testid":e.testId,onChange:t=>e.onChange?.(t.currentTarget.value)}),e.hint?(0,x.jsx)(`small`,{id:r,"data-tone":`hint`,children:e.hint}):null,e.error?(0,x.jsx)(`small`,{id:i,"data-tone":`error`,children:e.error}):null]})}function st(e){let t=(0,_.useRef)(null),n=(0,_.useRef)(null),r=(0,_.useId)(),i=e.labelledBy??r,a=(0,_.useRef)(!1),o=(0,_.useRef)(e.onClose);return o.current=e.onClose,(0,_.useEffect)(()=>{let r=t.current;r&&(e.open&&!r.open&&(n.current=document.activeElement instanceof HTMLElement?document.activeElement:null,r.showModal(),r.querySelector(`[data-autofocus], button, input, select, textarea, a[href], [tabindex]:not([tabindex="-1"])`)?.focus()),!e.open&&r.open&&(a.current=!0,r.close()))},[e.open]),(0,_.useEffect)(()=>{let e=t.current;if(!e)return;let r=()=>{let t=n.current;ct(e,t),n.current=null},i=()=>{a.current?a.current=!1:o.current(),window.setTimeout(r,0)},s=t=>{if(t.key!==`Tab`)return;let n=Array.from(e.querySelectorAll(`button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), a[href], [tabindex]:not([tabindex="-1"])`)).filter(e=>e.offsetParent!==null||e===document.activeElement);if(n.length===0)return;let r=n[0],i=n[n.length-1];t.shiftKey&&document.activeElement===r?(t.preventDefault(),i.focus()):!t.shiftKey&&document.activeElement===i&&(t.preventDefault(),r.focus())};return e.addEventListener(`close`,i),e.addEventListener(`keydown`,s),()=>{e.removeEventListener(`close`,i),e.removeEventListener(`keydown`,s);let t=n.current;window.setTimeout(()=>ct(e,t),0)}},[]),(0,x.jsxs)(`dialog`,{className:`ds-dialog ${e.className??``}`.trim(),"data-position":e.position??`center`,ref:t,"aria-labelledby":i,"data-testid":e.testId,children:[(0,x.jsxs)(`header`,{children:[(0,x.jsx)(`h2`,{id:i,children:e.title}),(0,x.jsx)(P,{label:e.closeLabel??`Close`,icon:`close`,onClick:()=>{let e=n.current;a.current=!0,o.current(),t.current?.close(),window.setTimeout(()=>{let n=t.current;n&&ct(n,e)},0)},"data-testid":`dialog-close`})]}),(0,x.jsx)(`div`,{children:(0,x.jsx)(Se.Provider,{value:!0,children:e.children})})]})}function ct(e,t){if(e.isConnected&&e.open)return;let n=document.activeElement;if(n&&n!==document.body&&n!==document.documentElement&&!e.contains(n)||document.querySelector(`dialog[open]`))return;let r=e=>!!e?.isConnected&&e!==document.body&&!e.matches(`:disabled, [aria-disabled="true"]`)&&!e.closest(`[inert], [hidden]`);if(r(t)){t.focus();return}let i=document.querySelector(`[data-dialog-focus-fallback]`)??document.querySelector(`main button:not(:disabled)`);r(i)&&i.focus()}function lt(e){return(0,x.jsx)(st,{...e})}function ut(e){return(0,x.jsxs)(lt,{open:e.open,title:e.title,onClose:e.onClose,testId:e.testId,closeLabel:e.closeLabel,children:[(0,x.jsx)(`p`,{children:e.body}),(0,x.jsxs)(`div`,{className:`dialog-actions`,children:[(0,x.jsx)(N,{"data-testid":`${e.testId}-cancel`,onClick:e.onClose,children:e.cancelLabel}),(0,x.jsx)(N,{tone:e.tone??`primary`,busy:e.busy,disabled:e.busy,"data-testid":`${e.testId}-confirm`,onClick:e.onConfirm,children:e.confirmLabel})]})]})}function dt(e){return(0,x.jsxs)(`aside`,{className:`ds-inspector`,"aria-label":e.title,children:[(0,x.jsx)(`h2`,{children:e.title}),e.children]})}function ft(e){return(0,x.jsxs)(`table`,{className:`ds-table`,children:[(0,x.jsx)(`caption`,{children:e.caption}),e.children]})}function pt(e){return(0,x.jsx)(`ul`,{className:`ds-list`,"aria-label":e.label,children:e.children})}function mt(e){let[t,n]=_.useState(``),r=_.useId();return _.useEffect(()=>()=>n(``),[]),(0,x.jsxs)(`form`,{className:`ds-login`,"data-testid":e.testId,autoComplete:`off`,onSubmit:r=>{if(r.preventDefault(),e.busy||t.trim().length===0)return;let i=t;n(``),e.onSubmit(i)},children:[(0,x.jsx)(`h2`,{children:e.title}),(0,x.jsx)(`p`,{children:e.body}),(0,x.jsxs)(`label`,{className:`ds-field`,children:[(0,x.jsx)(`span`,{children:e.tokenLabel}),(0,x.jsx)(`input`,{type:`password`,autoComplete:`off`,spellCheck:!1,autoCapitalize:`none`,autoCorrect:`off`,value:t,disabled:e.busy,"aria-invalid":e.error?`true`:void 0,"aria-describedby":r,onChange:e=>n(e.currentTarget.value)}),(0,x.jsx)(`small`,{id:r,"data-tone":e.error?`error`:`hint`,children:e.error??e.tokenHelp})]}),(0,x.jsxs)(`div`,{className:`dialog-actions`,children:[(0,x.jsx)(N,{tone:`primary`,type:`submit`,busy:e.busy,disabled:t.trim().length===0,children:e.submitLabel}),e.onLogout&&e.logoutLabel?(0,x.jsx)(N,{type:`button`,onClick:()=>{n(``),e.onLogout?.()},children:e.logoutLabel}):null]})]})}function ht(e){return(0,x.jsx)(L,{tone:`error`,title:e.title,body:e.body,action:(0,x.jsxs)(N,{onClick:e.onRecover,children:[(0,x.jsx)(C,{name:`schema`}),e.actionLabel]})})}function gt(e){if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Malformed settings response.`);return e}function _t(e){if(typeof e!=`string`||!/^[0-9a-f]{64}$/.test(e))throw Error(`Malformed settings fingerprint.`);return e}function vt(e){let t=gt(e);if(!Array.isArray(t.schema)||t.schema.length>256)throw Error(`Malformed settings schema.`);let n=new Set;return{schema:t.schema.map(e=>{let t=gt(e);if(typeof t.name!=`string`||n.has(t.name)||typeof t.type!=`string`||![`bool`,`int`,`int_or_null`,`float`,`str`,`str_or_null`,`array`,`object`,`object_or_null`].includes(t.type)||typeof t.mutable!=`boolean`||typeof t.help!=`string`||!(t.allowed===null||Array.isArray(t.allowed)&&t.allowed.every(e=>typeof e==`string`))||t.reason!==void 0&&typeof t.reason!=`string`||!Object.hasOwn(t,`default`))throw Error(`Malformed setting specification.`);return n.add(t.name),t}),current:gt(t.current),fingerprint:_t(t.fingerprint)}}function yt(e){let t=gt(e);if(!Array.isArray(t.rejected)||!t.rejected.every(e=>{let t=gt(e);return typeof t.name==`string`&&typeof t.reason==`string`}))throw Error(`Malformed settings rejection list.`);return{applied:gt(t.applied),rejected:t.rejected,current:gt(t.current),fingerprint:_t(t.fingerprint)}}function bt(e){let t=gt(e),n=gt(t.default_generation_settings),r=e=>typeof e==`number`&&Number.isSafeInteger(e)&&e>0?e:null;return{nCtx:r(n.n_ctx),kvCacheMode:typeof t.kv_cache_mode==`string`&&t.kv_cache_mode.length<=64&&/^[a-z0-9+_-]+$/.test(t.kv_cache_mode)?t.kv_cache_mode:null,totalSlots:r(t.total_slots),geometry:t.geometry===void 0?null:gt(t.geometry)}}function xt(e,t){if(!e.mutable)throw Error(e.reason??`Restart required.`);let n=t;if(![`str`,`str_or_null`].includes(e.type)||e.type===`str_or_null`&&t===`null`)try{n=JSON.parse(t)}catch{throw Error(`Enter a valid ${e.type} value.`)}let r=e.type.endsWith(`_or_null`),i=e.type.replace(`_or_null`,``);if(!(r&&n===null)&&(i===`bool`?typeof n!=`boolean`:i===`int`?typeof n!=`number`||!Number.isSafeInteger(n):i===`float`?typeof n!=`number`||!Number.isFinite(n):i===`str`?typeof n!=`string`:i===`array`?!Array.isArray(n):typeof n!=`object`||!n||Array.isArray(n)))throw Error(`Expected ${e.type}.`);if(e.allowed!==null&&(typeof n!=`string`||!e.allowed.includes(n)))throw Error(`Allowed values: ${e.allowed.join(`, `)}.`);return n}function St(e,t){return typeof t==`string`&&[`str`,`str_or_null`].includes(e.type)?t:JSON.stringify(t)??``}function Ct(e){let t=gt(e);if(!Array.isArray(t.tokens)||!t.tokens.every(e=>typeof e==`number`&&Number.isInteger(e)))throw Error(`Malformed tokenization response.`);return t.tokens.length}var wt=1048576,Tt=class{decoder=new TextDecoder(`utf-8`);maxFrameBytes;onMessage;onDone;buffered=``;eventName=``;dataLines=[];id=null;retry=null;frameBytes=0;ended=!1;get done(){return this.ended}constructor(e){this.maxFrameBytes=e.maxFrameBytes??wt,this.onMessage=e.onMessage,this.onDone=e.onDone}push(e){if(!this.ended){if(this.frameBytes+=e.byteLength,this.frameBytes>this.maxFrameBytes)throw Error(`SSE frame exceeded the configured byte limit.`);this.buffered+=this.decoder.decode(e,{stream:!0}),this.drainLines(!1)}}close(){if(this.ended)return;let e=this.decoder.decode();e.length>0&&(this.buffered+=e),this.drainLines(!0),this.buffered.length>0&&(this.consumeLine(this.buffered),this.buffered=``),this.dispatch()}drainLines(e){for(;this.buffered.length>0;){let t=this.buffered.indexOf(` +`),n=this.buffered.indexOf(`\r`),r;if(r=t===-1?n:n===-1?t:Math.min(t,n),r===-1||this.buffered[r]===`\r`&&this.buffered[r+1]===void 0&&!e)break;let i=this.buffered.slice(0,r),a=this.buffered[r]===`\r`&&this.buffered[r+1]===` +`?r+2:r+1;this.buffered=this.buffered.slice(a),this.consumeLine(i)}e&&this.buffered.length===0&&this.dispatch()}consumeLine(e){if(e.length===0){this.dispatch();return}if(e.startsWith(`:`))return;let t=e.indexOf(`:`),n=t===-1?e:e.slice(0,t),r=t===-1?``:e.slice(t+1),i=r.startsWith(` `)?r.slice(1):r;n===`event`?this.eventName=i:n===`data`?this.dataLines.push(i):n===`id`?this.id=i:n===`retry`&&/^\d+$/.test(i)&&(this.retry=Number(i))}dispatch(){if(this.dataLines.length===0){this.eventName=``,this.retry=null,this.frameBytes=0;return}let e=this.dataLines.join(` +`),t=this.eventName.length===0?`message`:this.eventName;if(this.eventName=``,this.dataLines=[],this.frameBytes=0,e===`[DONE]`){this.ended=!0,this.onDone?.();return}this.onMessage({event:t,data:e,id:this.id,retry:this.retry}),this.retry=null}};function Et(e){return Array.from(e).some(e=>{let t=e.charCodeAt(0);return t<=32||t>=127&&t<=159})}function Dt(e){if(/[\\?#]/.test(e)||Et(e)||e.includes(`//`))throw Error(`WebUI API base must not contain a query, hash, backslash, whitespace, controls or empty path segments.`);for(let t of e.split(`/`)){let e;try{e=decodeURIComponent(t)}catch{throw Error(`WebUI API base contains an invalid path escape.`)}if(e===`.`||e===`..`)throw Error(`WebUI API base must not contain dot path segments.`);if(/[/\\%?#]/.test(e)||Et(e))throw Error(`WebUI API base contains an ambiguous encoded path segment.`)}}function Ot(e){let t=e??At();if(t===``)return``;if(!t.startsWith(`/`)||t.startsWith(`//`))throw Error(`WebUI API base must be a same-origin absolute path.`);return Dt(t),new URL(t,`http://webui.invalid`).pathname.replace(/\/$/,``)}function kt(e){return/^(.*)\/webui(?:\/(?:index\.html)?)?$/.exec(e)?.[1]??null}function At(){if(typeof document>`u`)return``;let e=document.querySelector(`meta[name="mlxcel-ui-api-base"]`)?.content;if(e!==void 0&&e.length>0)return Ot(e);let t=document.querySelector(`base`)?.getAttribute(`href`);if(t!=null&&t.length>0){let e=t.replace(/^[a-z][a-z\d+.-]*:\/\/[^/]*/i,``);Dt(e===`.`?``:e.replace(/^\.\//,``));let n=new URL(t,document.URL);if(n.origin!==window.location.origin||n.username||n.password||n.search||n.hash)throw Error(`WebUI document base must stay on the current origin without credentials, query or hash.`);return Ot(kt(n.pathname)??n.pathname)}let n=window.location.pathname,r=kt(n);return r===null?``:(Dt(n),Ot(r))}function jt(e,t,n){if(!t.startsWith(`/ui-api/v1/`)&&t!==`/v1/chat/completions`&&t!==`/v1/responses`&&t!==`/settings`&&t!==`/props`&&t!==`/tokenize`)throw Error(`WebUI client paths must stay under /ui-api/v1/ or the approved inference stream endpoints.`);let r=new URLSearchParams;for(let[e,t]of Object.entries(n??{}))t!=null&&r.set(e,String(t));return`${e}${t}${r.size===0?``:`?${r.toString()}`}`}function Mt(e){if(e.length===0)throw Error(`Opaque path segment must not be empty.`);return encodeURIComponent(e)}var Nt=`{ + "openapi": "3.1.0", + "info": { + "title": "mlxcel WebUI local control API", + "version": "1.0.0", + "description": "Contract gate for epic #1834. This file is JSON-compatible YAML by policy so the validator has no external dependency." + }, + "servers": [ + { + "url": "{api_prefix}", + "variables": { + "api_prefix": { + "default": "", + "description": "Validated server API prefix; paths below include /ui-api/v1 and the prefix is never derived from browser input." + } + } + } + ], + "security": [ + { + "bearerAuth": [] + } + ], + "paths": { + "/ui-api/v1/bootstrap": { + "get": { + "summary": "Return server identity, enabled features, redacted roots and hard limits without model initialization.", + "responses": { + "200": { + "description": "Bootstrap response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BootstrapResponse" + }, + "examples": { + "fixture": { + "externalValue": "../../tests/fixtures/webui/examples/bootstrap.model-free.json" + } + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + }, + "403": { + "description": "Forbidden by browser security checks", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + } + } + } + }, + "/ui-api/v1/catalog": { + "get": { + "summary": "List the deterministic model inventory. Query: limit 1..200 default 50, cursor, q, source, task, lifecycle, support, completeness. No downloads or loads.", + "responses": { + "200": { + "description": "Catalog page", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CatalogListResponse" + }, + "examples": { + "fixture": { + "externalValue": "../../tests/fixtures/webui/examples/catalog.page.json" + } + } + } + } + }, + "400": { + "description": "Invalid filter or cursor", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + }, + "403": { + "description": "Forbidden by browser security checks", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + } + }, + "parameters": [ + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 200, + "default": 50 + }, + "description": "Page size. Values above 200 are rejected rather than clamped." + }, + { + "name": "cursor", + "in": "query", + "required": false, + "schema": { + "$ref": "#/components/schemas/CursorToken" + }, + "description": "Opaque cursor returned by the previous page." + }, + { + "name": "q", + "in": "query", + "required": false, + "schema": { + "type": "string", + "maxLength": 128 + }, + "description": "Case-insensitive display/inference-id substring filter." + }, + { + "name": "source", + "in": "query", + "required": false, + "schema": { + "$ref": "#/components/schemas/CatalogSourceKind" + }, + "description": "Filter by source kind." + }, + { + "name": "task", + "in": "query", + "required": false, + "schema": { + "$ref": "#/components/schemas/TaskKind" + }, + "description": "Filter by declared task capability." + }, + { + "name": "lifecycle", + "in": "query", + "required": false, + "schema": { + "$ref": "#/components/schemas/ModelLifecycleState" + }, + "description": "Filter by inference lifecycle state." + }, + { + "name": "support", + "in": "query", + "required": false, + "schema": { + "type": "boolean" + }, + "description": "true keeps supported+runnable entries, false keeps unsupported entries." + }, + { + "name": "completeness", + "in": "query", + "required": false, + "schema": { + "type": "boolean" + }, + "description": "true keeps complete checkpoints, false keeps incomplete entries." + } + ] + } + }, + "/ui-api/v1/catalog/{id}": { + "get": { + "summary": "Read one catalog entry by opaque model id.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "$ref": "#/components/schemas/ModelId" + } + } + ], + "responses": { + "200": { + "description": "Catalog entry", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CatalogEntry" + } + } + } + }, + "404": { + "description": "Unknown model id", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + }, + "403": { + "description": "Forbidden by browser security checks", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + } + } + } + }, + "/ui-api/v1/catalog/refresh": { + "post": { + "summary": "Start a bounded background rescan; GET never mutates.", + "responses": { + "202": { + "description": "Accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OperationAccepted" + } + } + } + }, + "429": { + "description": "Operation limit", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + }, + "403": { + "description": "Forbidden by browser security checks", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + }, + "422": { + "description": "Catalog refresh is unsupported in read-only single-model mode", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + } + } + } + }, + "/ui-api/v1/model-actions": { + "post": { + "summary": "Load or unload through the shared lifecycle coordinator. Duplicate idempotency keys replay the original operation inside this server instance.", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ModelActionRequest" + }, + "examples": { + "fixture": { + "externalValue": "../../tests/fixtures/webui/examples/request.model-action.load.json" + } + } + } + } + }, + "responses": { + "202": { + "description": "Accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OperationAccepted" + }, + "examples": { + "fixture": { + "externalValue": "../../tests/fixtures/webui/examples/operation.accepted.json" + } + } + } + } + }, + "409": { + "description": "Stale revision or conflicting action", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + }, + "422": { + "description": "Unsupported action/profile", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + }, + "403": { + "description": "Forbidden by browser security checks", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + }, + "413": { + "description": "JSON request body exceeds the WebUI contract limit", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + } + } + } + }, + "/ui-api/v1/downloads": { + "post": { + "summary": "Download a public HuggingFace repository into the configured cache after explicit consent.", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DownloadRequest" + }, + "examples": { + "fixture": { + "externalValue": "../../tests/fixtures/webui/examples/request.download.json" + } + } + } + } + }, + "responses": { + "202": { + "description": "Accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OperationAccepted" + }, + "examples": { + "fixture": { + "externalValue": "../../tests/fixtures/webui/examples/operation.accepted.json" + } + } + } + } + }, + "422": { + "description": "Invalid or unsupported repository", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + }, + "403": { + "description": "Forbidden by browser security checks", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + }, + "413": { + "description": "JSON request body exceeds the WebUI contract limit", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + } + } + } + }, + "/ui-api/v1/model-removals": { + "post": { + "summary": "Remove a cache-owned model only after server checks and UI confirmation.", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RemovalRequest" + }, + "examples": { + "fixture": { + "externalValue": "../../tests/fixtures/webui/examples/request.removal.json" + } + } + } + } + }, + "responses": { + "202": { + "description": "Accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OperationAccepted" + }, + "examples": { + "fixture": { + "externalValue": "../../tests/fixtures/webui/examples/operation.accepted.json" + } + } + } + } + }, + "409": { + "description": "Busy/loading/downloading/draining model", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + }, + "422": { + "description": "Non-cache model cannot be removed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + }, + "403": { + "description": "Forbidden by browser security checks", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + }, + "413": { + "description": "JSON request body exceeds the WebUI contract limit", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + } + } + } + }, + "/ui-api/v1/operations": { + "get": { + "summary": "List active operations plus the bounded terminal history. Query: limit default 50 max 200, cursor, state, kind, target.", + "responses": { + "200": { + "description": "Operations page", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OperationsListResponse" + }, + "examples": { + "fixture": { + "externalValue": "../../tests/fixtures/webui/examples/operations.list.json" + } + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + }, + "403": { + "description": "Forbidden by browser security checks", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + } + }, + "parameters": [ + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 200, + "default": 50 + }, + "description": "Page size for active plus terminal operation records." + }, + { + "name": "cursor", + "in": "query", + "required": false, + "schema": { + "$ref": "#/components/schemas/CursorToken" + }, + "description": "Opaque cursor returned by the previous page." + }, + { + "name": "state", + "in": "query", + "required": false, + "schema": { + "$ref": "#/components/schemas/OperationState" + }, + "description": "Filter by operation state." + }, + { + "name": "kind", + "in": "query", + "required": false, + "schema": { + "$ref": "#/components/schemas/OperationKind" + }, + "description": "Filter by operation kind." + }, + { + "name": "target", + "in": "query", + "required": false, + "schema": { + "type": "string", + "maxLength": 128, + "pattern": "^[A-Za-z0-9._~-]{1,128}(?![\\\\s\\\\S])" + }, + "description": "Opaque model id or operation target token; never a filesystem path." + } + ] + } + }, + "/ui-api/v1/operations/{id}": { + "get": { + "summary": "Read one operation by id.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "$ref": "#/components/schemas/OperationId" + } + } + ], + "responses": { + "200": { + "description": "Operation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Operation" + }, + "examples": { + "fixture": { + "externalValue": "../../tests/fixtures/webui/examples/operation.running.json" + } + } + } + } + }, + "404": { + "description": "Unknown operation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + }, + "403": { + "description": "Forbidden by browser security checks", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + } + } + } + }, + "/ui-api/v1/operations/{id}/cancel": { + "post": { + "summary": "Request cancellation; completion is reported only after the worker stops or cancellation is rejected.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "$ref": "#/components/schemas/OperationId" + } + } + ], + "responses": { + "202": { + "description": "Cancellation accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OperationAccepted" + } + } + } + }, + "422": { + "description": "Cancellation unsupported", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + }, + "403": { + "description": "Forbidden by browser security checks", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + } + } + } + }, + "/ui-api/v1/events": { + "get": { + "summary": "Authenticated SSE stream. Clients normally reconnect with the paired server_instance_id and after_sequence query cursor computed from the minimum authoritative resource fence. Last-Event-ID remains supported only as an opaque legacy replay cursor and must not be sent together with the paired query cursor. Ring gaps or changed server_instance_id produce a reset event and full resnapshot.", + "responses": { + "200": { + "description": "SSE event stream carrying UiEvent JSON payloads" + }, + "409": { + "description": "Replay gap or server restart", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + }, + "403": { + "description": "Forbidden by browser security checks", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + } + }, + "parameters": [ + { + "name": "Last-Event-ID", + "in": "header", + "required": false, + "schema": { + "$ref": "#/components/schemas/EventId" + }, + "description": "Opaque event id from the last applied SSE event. It is a legacy cursor and is rejected when either paired replay query parameter is present." + }, + { + "name": "server_instance_id", + "in": "query", + "required": false, + "schema": { + "$ref": "#/components/schemas/ServerInstanceId" + }, + "description": "Server instance that produced after_sequence. Required exactly when after_sequence is supplied; a different instance returns a typed server_restart event." + }, + { + "name": "after_sequence", + "in": "query", + "required": false, + "schema": { + "$ref": "#/components/schemas/EventSequence" + }, + "description": "Replay every retained event with sequence greater than this value. Required exactly when server_instance_id is supplied; 0 and the current sequence are valid. Non-safe integers, future sequences, duplicate parameters and malformed values are rejected." + } + ] + } + }, + "/ui-api/v1/runtime": { + "get": { + "summary": "Model-scoped observation snapshot from existing settings/slot/cache/worker counters. Query: model_id required. No autoload and no sampling work.", + "parameters": [ + { + "name": "model_id", + "in": "query", + "required": true, + "schema": { + "$ref": "#/components/schemas/ModelId" + } + } + ], + "responses": { + "200": { + "description": "Runtime snapshot", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RuntimeSnapshot" + }, + "examples": { + "fixture": { + "externalValue": "../../tests/fixtures/webui/examples/runtime.snapshot.json" + } + } + } + } + }, + "404": { + "description": "Unknown model id", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + }, + "403": { + "description": "Forbidden by browser security checks", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorEnvelope" + } + } + } + } + } + } + } + }, + "components": { + "securitySchemes": { + "bearerAuth": { + "type": "http", + "scheme": "bearer" + } + }, + "schemas": { + "SchemaVersion": { + "type": "string", + "const": "webui.ui-api.v1" + }, + "ServerMode": { + "type": "string", + "enum": [ + "model_free", + "single_model", + "router_pool" + ] + }, + "FeatureFlag": { + "type": "string", + "enum": [ + "webui", + "catalog", + "download", + "cache_delete", + "load", + "unload", + "chat", + "runtime", + "settings", + "local_history", + "image_input" + ] + }, + "CapabilityPhase": { + "type": "string", + "enum": [ + "pre_load", + "provider_ready" + ] + }, + "ActionState": { + "type": "string", + "enum": [ + "enabled", + "disabled", + "read_only" + ] + }, + "ModelLifecycleState": { + "type": "string", + "enum": [ + "unloaded", + "loading", + "ready", + "draining", + "unloading", + "failed" + ] + }, + "DownloadState": { + "type": "string", + "enum": [ + "absent", + "downloading", + "complete", + "incomplete", + "failed" + ] + }, + "OperationState": { + "type": "string", + "enum": [ + "queued", + "running", + "cancelling", + "succeeded", + "failed", + "cancelled" + ] + }, + "OperationKind": { + "type": "string", + "enum": [ + "catalog_refresh", + "model_load", + "model_unload", + "download", + "model_removal", + "settings_patch" + ] + }, + "CatalogSourceKind": { + "type": "string", + "enum": [ + "cache", + "models_dir", + "preset", + "single_model" + ] + }, + "TaskKind": { + "type": "string", + "enum": [ + "chat", + "completion", + "embedding", + "rerank", + "audio_transcription", + "audio_speech", + "vision_input", + "image_generation" + ] + }, + "UiEventType": { + "type": "string", + "enum": [ + "snapshot", + "model_revision", + "operation", + "download_progress", + "runtime", + "settings", + "reset", + "gap", + "server_restart", + "heartbeat" + ] + }, + "ServerInstanceId": { + "type": "string", + "minLength": 1, + "maxLength": 128, + "pattern": "^[A-Za-z0-9._~-]{1,128}(?![\\\\s\\\\S])", + "description": "Opaque per-process server instance id; never carries a path or credential." + }, + "ModelId": { + "type": "string", + "pattern": "^mdl_[A-Za-z0-9_-]{43}(?![\\\\s\\\\S])", + "description": "Opaque stable UI model id." + }, + "OperationId": { + "type": "string", + "minLength": 1, + "maxLength": 128, + "pattern": "^[A-Za-z0-9._~-]{1,128}(?![\\\\s\\\\S])", + "description": "Opaque operation id; printable token only." + }, + "EventId": { + "type": "string", + "minLength": 1, + "maxLength": 160, + "pattern": "^evt_[A-Za-z0-9._~-]{1,160}(?![\\\\s\\\\S])", + "description": "Opaque SSE event id; also sent as the SSE id field." + }, + "EventSequence": { + "type": "integer", + "minimum": 0, + "maximum": 9007199254740991, + "description": "Non-negative UI event sequence small enough to round-trip through JavaScript Number without precision loss." + }, + "EventReplayQuery": { + "type": "object", + "additionalProperties": false, + "required": [ + "server_instance_id", + "after_sequence" + ], + "properties": { + "server_instance_id": { + "$ref": "#/components/schemas/ServerInstanceId" + }, + "after_sequence": { + "$ref": "#/components/schemas/EventSequence" + } + } + }, + "CursorToken": { + "type": "string", + "minLength": 1, + "maxLength": 512, + "pattern": "^[A-Za-z0-9._~-]{1,512}(?![\\\\s\\\\S])", + "description": "Opaque pagination cursor. Control characters, slashes and backslashes are forbidden." + }, + "IdempotencyKey": { + "type": "string", + "minLength": 8, + "maxLength": 128, + "pattern": "^[A-Za-z0-9._~-]{8,128}(?![\\\\s\\\\S])", + "description": "Client-supplied idempotency token scoped to one server instance; printable token only." + }, + "HuggingFaceRepoId": { + "type": "string", + "minLength": 1, + "maxLength": 193, + "pattern": "^(?!.*(?:^|/)\\\\.\\\\.?($|/))[A-Za-z0-9][A-Za-z0-9._-]{0,95}/[A-Za-z0-9][A-Za-z0-9._-]{0,95}(?![\\\\s\\\\S])", + "description": "Public HuggingFace owner/name id. Dot-only path segments and URL/path syntax are rejected." + }, + "RevisionRef": { + "type": [ + "string", + "null" + ], + "minLength": 1, + "maxLength": 128, + "pattern": "^(?!.*(?:^|/)\\\\.\\\\.?($|/))[A-Za-z0-9._~+/-]+(?![\\\\s\\\\S])", + "description": "Repository revision ref resolved and pinned before writing weights. Dot-only path segments and control characters are rejected." + }, + "ApiBase": { + "type": "string", + "minLength": 0, + "maxLength": 128, + "pattern": "^(?![\\\\s\\\\S])|^/(?!/)(?!.*//)(?!.*(?:^|/)\\\\.\\\\.?($|/))[A-Za-z0-9._~!$&'()*+,;=:@%/-]*(?![\\\\s\\\\S])", + "description": "Validated same-origin relative API prefix. Protocol-relative URLs, query strings, fragments, dot segments and doubled slashes are rejected." + }, + "KvCacheModeName": { + "type": "string", + "enum": [ + "fp16", + "float16", + "int8", + "i8", + "turbo4-asym", + "fp16+turbo4", + "turbo3-asym", + "fp16+turbo3", + "turbo3", + "turbo4", + "turbo4-sym", + "turbo4-delegated", + "fp16+turbo4-delegated" + ], + "description": "Accepted by KVCacheMode::from_str / --kv-cache-mode; GGML-only cache spellings such as q8_0 are intentionally absent." + }, + "ErrorCode": { + "type": "string", + "enum": [ + "invalid_request", + "unauthorized", + "forbidden", + "not_found", + "stale_revision", + "conflict", + "unsupported", + "rate_limited", + "unavailable", + "payload_too_large", + "server_restarted", + "event_gap", + "partial_success" + ] + }, + "FieldError": { + "type": "object", + "additionalProperties": false, + "required": [ + "field", + "code", + "message" + ], + "properties": { + "field": { + "type": "string", + "minLength": 1, + "maxLength": 128, + "pattern": "^[A-Za-z0-9_.:-]+(?![\\\\s\\\\S])" + }, + "code": { + "type": "string", + "minLength": 1, + "maxLength": 64, + "pattern": "^[A-Za-z0-9_.:-]+(?![\\\\s\\\\S])" + }, + "message": { + "type": "string", + "minLength": 1, + "maxLength": 512 + } + } + }, + "ErrorBody": { + "type": "object", + "additionalProperties": false, + "required": [ + "code", + "message", + "retryable" + ], + "properties": { + "code": { + "$ref": "#/components/schemas/ErrorCode" + }, + "message": { + "type": "string", + "minLength": 1, + "maxLength": 512 + }, + "retryable": { + "type": "boolean" + }, + "field_errors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FieldError" + }, + "maxItems": 16 + }, + "operation_id": { + "$ref": "#/components/schemas/OperationId" + } + } + }, + "ErrorEnvelope": { + "type": "object", + "additionalProperties": false, + "required": [ + "error", + "request_id" + ], + "properties": { + "error": { + "$ref": "#/components/schemas/ErrorBody" + }, + "request_id": { + "$ref": "#/components/schemas/OperationId" + } + } + }, + "ActionAvailability": { + "type": "object", + "additionalProperties": false, + "required": [ + "state", + "reason" + ], + "properties": { + "state": { + "$ref": "#/components/schemas/ActionState" + }, + "reason": { + "type": [ + "string", + "null" + ], + "maxLength": 256 + }, + "instructions": { + "type": [ + "string", + "null" + ], + "maxLength": 512 + } + } + }, + "BuildInfo": { + "type": "object", + "additionalProperties": false, + "required": [ + "version", + "git_commit", + "target", + "features" + ], + "properties": { + "version": { + "type": "string" + }, + "git_commit": { + "type": [ + "string", + "null" + ] + }, + "target": { + "type": "string" + }, + "features": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FeatureFlag" + } + } + } + }, + "BackendIdentity": { + "type": "object", + "additionalProperties": false, + "required": [ + "server_instance_id", + "mode", + "api_base", + "auth_required", + "build" + ], + "properties": { + "server_instance_id": { + "$ref": "#/components/schemas/ServerInstanceId" + }, + "mode": { + "$ref": "#/components/schemas/ServerMode" + }, + "api_base": { + "$ref": "#/components/schemas/ApiBase" + }, + "auth_required": { + "type": "boolean" + }, + "build": { + "$ref": "#/components/schemas/BuildInfo" + } + } + }, + "RootSummary": { + "type": "object", + "additionalProperties": false, + "required": [ + "kind", + "display_name", + "redacted" + ], + "properties": { + "kind": { + "type": "string", + "enum": [ + "cache", + "models_dir", + "preset_file", + "single_model" + ] + }, + "display_name": { + "type": "string", + "minLength": 1, + "maxLength": 128 + }, + "redacted": { + "type": "boolean" + }, + "writable": { + "type": "boolean" + }, + "error": { + "type": [ + "string", + "null" + ], + "maxLength": 512 + } + } + }, + "LimitSummary": { + "type": "object", + "additionalProperties": false, + "required": [ + "catalog_default_page_size", + "catalog_max_page_size", + "json_body_bytes", + "metadata_bytes_per_entry", + "events_ring_size", + "events_retention_seconds", + "terminal_operations_retained", + "terminal_operations_retention_seconds", + "max_active_operations", + "max_concurrent_loads", + "max_concurrent_downloads", + "next_load_ctx_size_max", + "next_load_n_parallel_max", + "cursor_bytes", + "settings_fields_max", + "measurements_max" + ], + "properties": { + "catalog_default_page_size": { + "type": "integer", + "const": 50 + }, + "catalog_max_page_size": { + "type": "integer", + "const": 200 + }, + "json_body_bytes": { + "type": "integer", + "const": 2097152 + }, + "metadata_bytes_per_entry": { + "type": "integer", + "const": 16384 + }, + "events_ring_size": { + "type": "integer", + "const": 1024 + }, + "events_retention_seconds": { + "type": "integer", + "const": 600 + }, + "terminal_operations_retained": { + "type": "integer", + "const": 200 + }, + "terminal_operations_retention_seconds": { + "type": "integer", + "const": 3600 + }, + "max_active_operations": { + "type": "integer", + "const": 64 + }, + "max_concurrent_loads": { + "type": "integer", + "const": 1 + }, + "max_concurrent_downloads": { + "type": "integer", + "const": 1 + }, + "next_load_ctx_size_max": { + "type": "integer", + "const": 262144 + }, + "next_load_n_parallel_max": { + "type": "integer", + "const": 32 + }, + "cursor_bytes": { + "type": "integer", + "const": 512 + }, + "settings_fields_max": { + "type": "integer", + "const": 64 + }, + "measurements_max": { + "type": "integer", + "const": 64 + } + } + }, + "BootstrapResponse": { + "type": "object", + "additionalProperties": false, + "required": [ + "schema_version", + "server", + "features", + "actions", + "roots", + "limits", + "media_limits" + ], + "properties": { + "schema_version": { + "$ref": "#/components/schemas/SchemaVersion" + }, + "server": { + "$ref": "#/components/schemas/BackendIdentity" + }, + "features": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FeatureFlag" + }, + "maxItems": 16 + }, + "actions": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/ActionAvailability" + }, + "maxProperties": 32 + }, + "roots": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RootSummary" + }, + "maxItems": 8 + }, + "limits": { + "$ref": "#/components/schemas/LimitSummary" + }, + "media_limits": { + "$ref": "#/components/schemas/MediaLimits" + } + } + }, + "ModelIdentity": { + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "inference_id", + "display_name", + "source", + "source_key_hash", + "generation", + "revision", + "content_fingerprint" + ], + "properties": { + "id": { + "$ref": "#/components/schemas/ModelId" + }, + "inference_id": { + "type": "string", + "minLength": 1, + "maxLength": 256 + }, + "display_name": { + "type": "string", + "minLength": 1, + "maxLength": 256, + "description": "The model's inference id with no character rewriting: the full id for cache and preset entries (owner/name for a cache repo), the directory name for models_dir entries, and the last /-separated segment of the served id for single_model. A label only: select and operate on a model by id." + }, + "source": { + "$ref": "#/components/schemas/CatalogSourceKind" + }, + "source_key_hash": { + "type": "string", + "pattern": "^[a-f0-9]{64}(?![\\\\s\\\\S])", + "description": "SHA-256 of the redacted canonical source key; used for collision tests without exposing paths." + }, + "generation": { + "type": "integer", + "minimum": 1 + }, + "revision": { + "type": "integer", + "minimum": 1 + }, + "content_fingerprint": { + "type": [ + "string", + "null" + ], + "description": "Fingerprint of currently observed checkpoint content when known; affects generation/revision, not stable ID.", + "maxLength": 128 + } + } + }, + "MeasuredValue": { + "type": "object", + "additionalProperties": false, + "required": [ + "value", + "unit", + "scope", + "measured_at", + "reason" + ], + "properties": { + "value": { + "type": [ + "number", + "null" + ] + }, + "unit": { + "type": "string", + "maxLength": 32 + }, + "scope": { + "type": "string", + "enum": [ + "model", + "slot", + "pool", + "server", + "unknown" + ] + }, + "measured_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ] + }, + "reason": { + "type": [ + "string", + "null" + ], + "maxLength": 256 + } + } + }, + "Capability": { + "type": "object", + "additionalProperties": false, + "required": [ + "task", + "phase", + "available", + "reason" + ], + "properties": { + "task": { + "$ref": "#/components/schemas/TaskKind" + }, + "phase": { + "$ref": "#/components/schemas/CapabilityPhase" + }, + "available": { + "type": "boolean" + }, + "reason": { + "type": [ + "string", + "null" + ], + "maxLength": 256 + } + } + }, + "LifecycleSnapshot": { + "type": "object", + "additionalProperties": false, + "required": [ + "state", + "download", + "busy", + "active_requests", + "draining_requests", + "worker_exit_observed", + "last_error" + ], + "properties": { + "state": { + "$ref": "#/components/schemas/ModelLifecycleState" + }, + "download": { + "$ref": "#/components/schemas/DownloadState" + }, + "busy": { + "type": "boolean" + }, + "active_requests": { + "type": "integer", + "minimum": 0 + }, + "draining_requests": { + "type": "integer", + "minimum": 0 + }, + "worker_exit_observed": { + "type": "boolean" + }, + "last_error": { + "type": [ + "string", + "null" + ], + "maxLength": 512 + } + } + }, + "CatalogEntry": { + "type": "object", + "additionalProperties": false, + "required": [ + "identity", + "capabilities", + "lifecycle", + "complete", + "supported", + "removable", + "metadata", + "removal" + ], + "properties": { + "identity": { + "$ref": "#/components/schemas/ModelIdentity" + }, + "capabilities": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Capability" + }, + "maxItems": 16 + }, + "lifecycle": { + "$ref": "#/components/schemas/LifecycleSnapshot" + }, + "complete": { + "type": "boolean" + }, + "supported": { + "type": "boolean" + }, + "removable": { + "type": "boolean" + }, + "metadata": { + "$ref": "#/components/schemas/CatalogMetadata" + }, + "removal": { + "$ref": "#/components/schemas/RemovalStatus" + } + } + }, + "Pagination": { + "type": "object", + "additionalProperties": false, + "required": [ + "limit", + "next_cursor", + "total_known" + ], + "properties": { + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 200 + }, + "next_cursor": { + "type": [ + "string", + "null" + ], + "maxLength": 512, + "pattern": "^[A-Za-z0-9._~-]{1,512}(?![\\\\s\\\\S])" + }, + "total_known": { + "type": [ + "integer", + "null" + ], + "minimum": 0 + } + } + }, + "CatalogListResponse": { + "type": "object", + "additionalProperties": false, + "required": [ + "schema_version", + "items", + "pagination", + "server_instance_id", + "snapshot_sequence" + ], + "properties": { + "schema_version": { + "$ref": "#/components/schemas/SchemaVersion" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CatalogEntry" + }, + "maxItems": 200 + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" + }, + "server_instance_id": { + "$ref": "#/components/schemas/ServerInstanceId" + }, + "snapshot_sequence": { + "$ref": "#/components/schemas/EventSequence", + "description": "Single global event sequence after which this snapshot is authoritative." + } + } + }, + "LoadProfile": { + "type": "object", + "additionalProperties": false, + "required": [], + "description": "Next-load profile override. Contract gate #1835 intentionally exposes only #1846-approved fields backed by existing server startup validators.", + "properties": { + "ctx_size": { + "type": [ + "integer", + "null" + ], + "minimum": 1, + "maximum": 262144, + "description": "Maps to existing --ctx-size; WebUI rejects larger values rather than attempting a new runtime mode." + }, + "n_parallel": { + "type": [ + "integer", + "null" + ], + "minimum": 1, + "maximum": 32, + "description": "Maps to existing --parallel/--n-parallel slot count." + }, + "kv_cache_mode": { + "anyOf": [ + { + "$ref": "#/components/schemas/KvCacheModeName" + }, + { + "type": "null" + } + ] + } + } + }, + "ModelActionRequest": { + "type": "object", + "additionalProperties": false, + "required": [ + "model_id", + "action", + "expected_revision", + "idempotency_key" + ], + "properties": { + "model_id": { + "$ref": "#/components/schemas/ModelId" + }, + "action": { + "type": "string", + "enum": [ + "load", + "unload" + ] + }, + "expected_revision": { + "type": "integer", + "minimum": 1 + }, + "idempotency_key": { + "$ref": "#/components/schemas/IdempotencyKey" + }, + "load_profile": { + "$ref": "#/components/schemas/LoadProfile" + }, + "eviction_target_id": { + "$ref": "#/components/schemas/ModelId" + }, + "eviction_target_expected_revision": { + "type": "integer", + "minimum": 1, + "description": "Catalog revision of eviction_target_id observed when the user confirmed the eviction; required when eviction_target_id is present and forbidden otherwise." + } + } + }, + "DownloadRequest": { + "type": "object", + "additionalProperties": false, + "required": [ + "repo_id", + "idempotency_key" + ], + "properties": { + "repo_id": { + "$ref": "#/components/schemas/HuggingFaceRepoId" + }, + "revision": { + "$ref": "#/components/schemas/RevisionRef" + }, + "idempotency_key": { + "$ref": "#/components/schemas/IdempotencyKey" + } + } + }, + "RemovalRequest": { + "type": "object", + "additionalProperties": false, + "required": [ + "model_id", + "expected_revision", + "idempotency_key" + ], + "properties": { + "model_id": { + "$ref": "#/components/schemas/ModelId" + }, + "expected_revision": { + "type": "integer", + "minimum": 1 + }, + "idempotency_key": { + "$ref": "#/components/schemas/IdempotencyKey" + } + } + }, + "CatalogOperationTarget": { + "type": "object", + "additionalProperties": false, + "required": [ + "target_kind", + "scope" + ], + "properties": { + "target_kind": { + "const": "catalog" + }, + "scope": { + "type": "string", + "enum": [ + "full", + "roots", + "entry" + ] + }, + "model_id": { + "anyOf": [ + { + "$ref": "#/components/schemas/ModelId" + }, + { + "type": "null" + } + ] + } + } + }, + "ModelOperationTarget": { + "type": "object", + "additionalProperties": false, + "required": [ + "target_kind", + "model_id", + "requested_revision" + ], + "properties": { + "target_kind": { + "const": "model" + }, + "model_id": { + "$ref": "#/components/schemas/ModelId" + }, + "requested_revision": { + "type": [ + "integer", + "null" + ], + "minimum": 1 + }, + "eviction_target_id": { + "anyOf": [ + { + "$ref": "#/components/schemas/ModelId" + }, + { + "type": "null" + } + ] + }, + "eviction_target_expected_revision": { + "type": [ + "integer", + "null" + ], + "minimum": 1 + } + } + }, + "DownloadOperationTarget": { + "type": "object", + "additionalProperties": false, + "required": [ + "target_kind", + "repo_id", + "revision" + ], + "properties": { + "target_kind": { + "const": "download" + }, + "repo_id": { + "$ref": "#/components/schemas/HuggingFaceRepoId" + }, + "revision": { + "$ref": "#/components/schemas/RevisionRef" + } + } + }, + "SettingsOperationTarget": { + "type": "object", + "additionalProperties": false, + "required": [ + "target_kind", + "model_id", + "scope" + ], + "properties": { + "target_kind": { + "const": "settings" + }, + "model_id": { + "$ref": "#/components/schemas/ModelId" + }, + "scope": { + "type": "string", + "enum": [ + "next_load_profile", + "loaded_model_live", + "request_only" + ] + } + } + }, + "OperationTarget": { + "oneOf": [ + { + "$ref": "#/components/schemas/CatalogOperationTarget" + }, + { + "$ref": "#/components/schemas/ModelOperationTarget" + }, + { + "$ref": "#/components/schemas/DownloadOperationTarget" + }, + { + "$ref": "#/components/schemas/SettingsOperationTarget" + } + ] + }, + "CatalogRefreshResult": { + "type": "object", + "additionalProperties": false, + "required": [ + "result_kind", + "scanned_entries", + "changed_entries", + "snapshot_sequence" + ], + "properties": { + "result_kind": { + "const": "catalog_refresh" + }, + "scanned_entries": { + "type": "integer", + "minimum": 0 + }, + "changed_entries": { + "type": "integer", + "minimum": 0 + }, + "snapshot_sequence": { + "$ref": "#/components/schemas/EventSequence" + } + } + }, + "ModelEvictionReport": { + "type": "object", + "additionalProperties": false, + "required": [ + "requested_target_id", + "displaced_model_id", + "outcome", + "rollbackable" + ], + "properties": { + "requested_target_id": { + "anyOf": [ + { + "$ref": "#/components/schemas/ModelId" + }, + { + "type": "null" + } + ] + }, + "displaced_model_id": { + "anyOf": [ + { + "$ref": "#/components/schemas/ModelId" + }, + { + "type": "null" + } + ] + }, + "outcome": { + "type": "string", + "enum": [ + "not_needed", + "displaced", + "failed_after_displacement" + ] + }, + "rollbackable": { + "type": "boolean" + } + } + }, + "ModelActionResult": { + "type": "object", + "additionalProperties": false, + "required": [ + "result_kind", + "model_id", + "revision", + "lifecycle" + ], + "properties": { + "result_kind": { + "type": "string", + "enum": [ + "model_load", + "model_unload", + "model_removal" + ] + }, + "model_id": { + "$ref": "#/components/schemas/ModelId" + }, + "revision": { + "type": "integer", + "minimum": 1 + }, + "lifecycle": { + "$ref": "#/components/schemas/LifecycleSnapshot" + }, + "eviction": { + "anyOf": [ + { + "$ref": "#/components/schemas/ModelEvictionReport" + }, + { + "type": "null" + } + ] + } + } + }, + "DownloadResult": { + "type": "object", + "additionalProperties": false, + "required": [ + "result_kind", + "repo_id", + "revision", + "download" + ], + "properties": { + "result_kind": { + "const": "download" + }, + "repo_id": { + "$ref": "#/components/schemas/HuggingFaceRepoId" + }, + "revision": { + "$ref": "#/components/schemas/RevisionRef" + }, + "model_id": { + "anyOf": [ + { + "$ref": "#/components/schemas/ModelId" + }, + { + "type": "null" + } + ] + }, + "download": { + "$ref": "#/components/schemas/DownloadState" + } + } + }, + "SettingsPatchResult": { + "type": "object", + "additionalProperties": false, + "required": [ + "result_kind", + "model_id", + "settings" + ], + "properties": { + "result_kind": { + "const": "settings_patch" + }, + "model_id": { + "$ref": "#/components/schemas/ModelId" + }, + "settings": { + "$ref": "#/components/schemas/RuntimeSettingsReport" + } + } + }, + "OperationResult": { + "oneOf": [ + { + "$ref": "#/components/schemas/CatalogRefreshResult" + }, + { + "$ref": "#/components/schemas/ModelActionResult" + }, + { + "$ref": "#/components/schemas/DownloadResult" + }, + { + "$ref": "#/components/schemas/SettingsPatchResult" + } + ] + }, + "OperationAccepted": { + "type": "object", + "additionalProperties": false, + "required": [ + "operation_id", + "state", + "idempotent_replay" + ], + "properties": { + "operation_id": { + "$ref": "#/components/schemas/OperationId" + }, + "state": { + "$ref": "#/components/schemas/OperationState" + }, + "idempotent_replay": { + "type": "boolean" + } + } + }, + "ProgressBytes": { + "type": "object", + "additionalProperties": false, + "required": [ + "completed_bytes", + "total_bytes", + "indeterminate" + ], + "properties": { + "completed_bytes": { + "type": "integer", + "minimum": 0 + }, + "total_bytes": { + "type": [ + "integer", + "null" + ], + "minimum": 0 + }, + "indeterminate": { + "type": "boolean" + } + } + }, + "Operation": { + "type": "object", + "additionalProperties": false, + "required": [ + "operation_id", + "kind", + "state", + "created_at", + "updated_at", + "idempotency_scope", + "target", + "progress", + "result", + "error", + "cancellable", + "cancel_reason" + ], + "properties": { + "operation_id": { + "$ref": "#/components/schemas/OperationId" + }, + "kind": { + "$ref": "#/components/schemas/OperationKind" + }, + "state": { + "$ref": "#/components/schemas/OperationState" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "RFC3339 UTC timestamp with offset, e.g. 2026-09-12T03:04:05Z." + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "RFC3339 UTC timestamp with offset, e.g. 2026-09-12T03:04:05Z." + }, + "idempotency_scope": { + "type": "string", + "const": "server_instance" + }, + "target": { + "$ref": "#/components/schemas/OperationTarget" + }, + "progress": { + "$ref": "#/components/schemas/ProgressBytes" + }, + "result": { + "anyOf": [ + { + "$ref": "#/components/schemas/OperationResult" + }, + { + "type": "null" + } + ] + }, + "error": { + "anyOf": [ + { + "$ref": "#/components/schemas/ErrorBody" + }, + { + "type": "null" + } + ] + }, + "cancellable": { + "type": "boolean" + }, + "cancel_reason": { + "type": [ + "string", + "null" + ], + "maxLength": 512 + } + } + }, + "OperationsListResponse": { + "type": "object", + "additionalProperties": false, + "required": [ + "items", + "pagination", + "server_instance_id", + "snapshot_sequence" + ], + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Operation" + }, + "maxItems": 200 + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" + }, + "server_instance_id": { + "$ref": "#/components/schemas/ServerInstanceId" + }, + "snapshot_sequence": { + "$ref": "#/components/schemas/EventSequence", + "description": "Single global event sequence after which this snapshot is authoritative." + } + } + }, + "RuntimeSettingsReport": { + "type": "object", + "additionalProperties": false, + "required": [ + "scope", + "effective", + "overridden_by_cli", + "partial_errors" + ], + "properties": { + "scope": { + "type": "string", + "enum": [ + "server_startup", + "per_model_preset", + "next_load_profile", + "request_only", + "loaded_model_live" + ] + }, + "effective": { + "type": "object", + "additionalProperties": { + "type": [ + "string", + "number", + "boolean", + "null" + ] + }, + "maxProperties": 64 + }, + "overridden_by_cli": { + "type": "array", + "items": { + "type": "string" + }, + "maxItems": 64 + }, + "partial_errors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FieldError" + }, + "maxItems": 16 + } + } + }, + "RuntimeSnapshot": { + "type": "object", + "additionalProperties": false, + "required": [ + "schema_version", + "server_instance_id", + "model_id", + "revision", + "snapshot_sequence", + "measurements", + "settings", + "slots" + ], + "properties": { + "schema_version": { + "$ref": "#/components/schemas/SchemaVersion" + }, + "server_instance_id": { + "$ref": "#/components/schemas/ServerInstanceId" + }, + "model_id": { + "$ref": "#/components/schemas/ModelId" + }, + "revision": { + "type": "integer", + "minimum": 1 + }, + "measurements": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/MeasuredValue" + }, + "maxProperties": 64 + }, + "settings": { + "$ref": "#/components/schemas/RuntimeSettingsReport" + }, + "snapshot_sequence": { + "$ref": "#/components/schemas/EventSequence", + "description": "Single global event sequence after which this snapshot is authoritative." + }, + "slots": { + "$ref": "#/components/schemas/RuntimeSlots" + } + } + }, + "UiEvent": { + "oneOf": [ + { + "$ref": "#/components/schemas/SnapshotEvent" + }, + { + "$ref": "#/components/schemas/ModelRevisionEvent" + }, + { + "$ref": "#/components/schemas/OperationEvent" + }, + { + "$ref": "#/components/schemas/DownloadProgressEvent" + }, + { + "$ref": "#/components/schemas/RuntimeEvent" + }, + { + "$ref": "#/components/schemas/SettingsEvent" + }, + { + "$ref": "#/components/schemas/ResetEvent" + }, + { + "$ref": "#/components/schemas/GapEvent" + }, + { + "$ref": "#/components/schemas/ServerRestartEvent" + }, + { + "$ref": "#/components/schemas/HeartbeatEvent" + } + ] + }, + "StringContract": { + "type": "object", + "additionalProperties": false, + "required": [ + "key", + "en", + "ko", + "test_id" + ], + "properties": { + "key": { + "type": "string", + "pattern": "^[a-z0-9_.-]+(?![\\\\s\\\\S])", + "maxLength": 128 + }, + "en": { + "type": "string", + "minLength": 1, + "maxLength": 512 + }, + "ko": { + "type": "string", + "minLength": 1, + "maxLength": 512 + }, + "test_id": { + "type": "string", + "pattern": "^[a-z0-9-]+(?![\\\\s\\\\S])", + "maxLength": 128 + } + } + }, + "TransitionStep": { + "type": "object", + "additionalProperties": false, + "required": [ + "from", + "action", + "to", + "http_status", + "event", + "allowed" + ], + "properties": { + "from": { + "$ref": "#/components/schemas/ModelLifecycleState" + }, + "action": { + "type": "string", + "minLength": 1 + }, + "to": { + "$ref": "#/components/schemas/ModelLifecycleState" + }, + "http_status": { + "type": "integer", + "minimum": 100, + "maximum": 599 + }, + "event": { + "$ref": "#/components/schemas/UiEventType" + }, + "allowed": { + "type": "boolean" + }, + "error": { + "anyOf": [ + { + "$ref": "#/components/schemas/ErrorEnvelope" + }, + { + "type": "null" + } + ] + } + } + }, + "WebUiContractFixture": { + "type": "object", + "additionalProperties": false, + "required": [ + "scenario", + "description", + "given", + "steps", + "expected" + ], + "properties": { + "scenario": { + "type": "string", + "enum": [ + "duplicate_load", + "load_unload_race", + "busy_eviction", + "stale_revision", + "failed_load", + "download_cancel", + "deletion_refusal", + "sse_gap", + "server_restart", + "unknown_null_partial_error" + ] + }, + "description": { + "type": "string", + "minLength": 1 + }, + "given": { + "type": "object", + "additionalProperties": { + "type": [ + "string", + "number", + "boolean", + "null", + "array", + "object" + ] + } + }, + "steps": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TransitionStep" + }, + "minItems": 1 + }, + "expected": { + "type": "object", + "additionalProperties": { + "type": [ + "string", + "number", + "boolean", + "null", + "array", + "object" + ] + } + } + } + }, + "SupportStatus": { + "type": "object", + "additionalProperties": false, + "required": [ + "architecturally_supported", + "runnable_on_backend", + "complete", + "reason", + "architecturally_supported_reason", + "runnable_on_backend_reason", + "complete_reason", + "tested_checkpoint", + "tested_checkpoint_reason" + ], + "properties": { + "architecturally_supported": { + "type": "boolean" + }, + "runnable_on_backend": { + "type": "boolean" + }, + "complete": { + "type": "boolean" + }, + "reason": { + "type": [ + "string", + "null" + ], + "maxLength": 512 + }, + "architecturally_supported_reason": { + "type": [ + "string", + "null" + ], + "maxLength": 512 + }, + "runnable_on_backend_reason": { + "type": [ + "string", + "null" + ], + "maxLength": 512 + }, + "complete_reason": { + "type": [ + "string", + "null" + ], + "maxLength": 512 + }, + "tested_checkpoint": { + "type": "boolean", + "description": "True only when the catalog has explicit compatibility evidence for this checkpoint; static registry support alone does not set this." + }, + "tested_checkpoint_reason": { + "type": [ + "string", + "null" + ], + "maxLength": 512 + } + } + }, + "CatalogMetadata": { + "type": "object", + "additionalProperties": false, + "required": [ + "architecture", + "declared_architectures", + "input_tasks", + "output_tasks", + "quantization", + "format", + "parameter_count", + "disk_bytes", + "memory_estimate_bytes", + "support", + "model_type", + "unknown_reasons" + ], + "properties": { + "architecture": { + "type": [ + "string", + "null" + ], + "maxLength": 128 + }, + "declared_architectures": { + "type": [ + "array", + "null" + ], + "items": { + "type": "string", + "maxLength": 128 + }, + "maxItems": 16, + "description": "Raw config.json architectures array when readable and bounded." + }, + "input_tasks": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TaskKind" + }, + "maxItems": 16 + }, + "output_tasks": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TaskKind" + }, + "maxItems": 16 + }, + "quantization": { + "type": [ + "string", + "null" + ], + "maxLength": 128 + }, + "format": { + "type": [ + "string", + "null" + ], + "maxLength": 128 + }, + "parameter_count": { + "type": [ + "integer", + "null" + ], + "minimum": 0 + }, + "disk_bytes": { + "type": [ + "integer", + "null" + ], + "minimum": 0 + }, + "memory_estimate_bytes": { + "type": [ + "integer", + "null" + ], + "minimum": 0 + }, + "support": { + "$ref": "#/components/schemas/SupportStatus" + }, + "model_type": { + "type": [ + "string", + "null" + ], + "maxLength": 128, + "description": "Raw config.json model_type when readable; architecture is the resolved mlxcel registry id." + }, + "unknown_reasons": { + "$ref": "#/components/schemas/CatalogMetadataUnknownReasons" + } + } + }, + "SnapshotPayload": { + "type": "object", + "additionalProperties": false, + "required": [ + "snapshot_sequence", + "catalog_changed", + "operations_changed", + "runtime_model_ids" + ], + "properties": { + "snapshot_sequence": { + "$ref": "#/components/schemas/EventSequence" + }, + "catalog_changed": { + "type": "boolean" + }, + "operations_changed": { + "type": "boolean" + }, + "runtime_model_ids": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ModelId" + }, + "maxItems": 200 + } + } + }, + "ModelRevisionPayload": { + "type": "object", + "additionalProperties": false, + "required": [ + "model_id", + "revision", + "lifecycle" + ], + "properties": { + "model_id": { + "$ref": "#/components/schemas/ModelId" + }, + "revision": { + "type": "integer", + "minimum": 1 + }, + "lifecycle": { + "$ref": "#/components/schemas/LifecycleSnapshot" + } + } + }, + "OperationPayload": { + "type": "object", + "additionalProperties": false, + "required": [ + "operation" + ], + "properties": { + "operation": { + "$ref": "#/components/schemas/Operation" + } + } + }, + "DownloadProgressPayload": { + "type": "object", + "additionalProperties": false, + "required": [ + "operation_id", + "progress" + ], + "properties": { + "operation_id": { + "$ref": "#/components/schemas/OperationId" + }, + "progress": { + "$ref": "#/components/schemas/ProgressBytes" + } + } + }, + "RuntimePayload": { + "type": "object", + "additionalProperties": false, + "required": [ + "runtime" + ], + "properties": { + "runtime": { + "$ref": "#/components/schemas/RuntimeSnapshot" + } + } + }, + "SettingsPayload": { + "type": "object", + "additionalProperties": false, + "required": [ + "model_id", + "settings" + ], + "properties": { + "model_id": { + "$ref": "#/components/schemas/ModelId" + }, + "settings": { + "$ref": "#/components/schemas/RuntimeSettingsReport" + } + } + }, + "ResetPayload": { + "type": "object", + "additionalProperties": false, + "required": [ + "reason", + "resnapshot" + ], + "properties": { + "reason": { + "enum": [ + "gap", + "server_restart", + "retention_expired", + "manual_reset" + ] + }, + "resnapshot": { + "type": "boolean" + } + } + }, + "HeartbeatPayload": { + "type": "object", + "additionalProperties": false, + "required": [ + "server_time" + ], + "properties": { + "server_time": { + "type": "string", + "format": "date-time" + } + } + }, + "RequirementMapEntry": { + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "epic_requirement", + "child", + "contract_artifact", + "test_fixture" + ], + "properties": { + "id": { + "type": "string", + "maxLength": 256 + }, + "epic_requirement": { + "type": "string", + "maxLength": 256 + }, + "child": { + "type": "string", + "pattern": "^#[0-9]+(?![\\\\s\\\\S])" + }, + "contract_artifact": { + "type": "string", + "maxLength": 256 + }, + "test_fixture": { + "type": "string", + "maxLength": 256 + } + } + }, + "RequirementMap": { + "type": "object", + "additionalProperties": false, + "required": [ + "requirements" + ], + "properties": { + "requirements": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/components/schemas/RequirementMapEntry" + }, + "maxItems": 64 + } + } + }, + "StringCatalog": { + "type": "object", + "additionalProperties": false, + "required": [ + "strings" + ], + "properties": { + "strings": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/components/schemas/StringContract" + }, + "maxItems": 1024 + } + } + }, + "SnapshotEvent": { + "type": "object", + "additionalProperties": false, + "required": [ + "schema_version", + "server_instance_id", + "sequence", + "type", + "payload", + "event_id", + "emitted_at" + ], + "properties": { + "schema_version": { + "$ref": "#/components/schemas/SchemaVersion" + }, + "server_instance_id": { + "$ref": "#/components/schemas/ServerInstanceId" + }, + "sequence": { + "$ref": "#/components/schemas/EventSequence" + }, + "type": { + "const": "snapshot" + }, + "payload": { + "$ref": "#/components/schemas/SnapshotPayload" + }, + "event_id": { + "$ref": "#/components/schemas/EventId" + }, + "emitted_at": { + "type": "string", + "format": "date-time", + "description": "RFC3339 UTC time at which the event was appended to the server ring." + } + } + }, + "ModelRevisionEvent": { + "type": "object", + "additionalProperties": false, + "required": [ + "schema_version", + "server_instance_id", + "sequence", + "type", + "payload", + "event_id", + "emitted_at" + ], + "properties": { + "schema_version": { + "$ref": "#/components/schemas/SchemaVersion" + }, + "server_instance_id": { + "$ref": "#/components/schemas/ServerInstanceId" + }, + "sequence": { + "$ref": "#/components/schemas/EventSequence" + }, + "type": { + "const": "model_revision" + }, + "payload": { + "$ref": "#/components/schemas/ModelRevisionPayload" + }, + "event_id": { + "$ref": "#/components/schemas/EventId" + }, + "emitted_at": { + "type": "string", + "format": "date-time", + "description": "RFC3339 UTC time at which the event was appended to the server ring." + } + } + }, + "OperationEvent": { + "type": "object", + "additionalProperties": false, + "required": [ + "schema_version", + "server_instance_id", + "sequence", + "type", + "payload", + "event_id", + "emitted_at" + ], + "properties": { + "schema_version": { + "$ref": "#/components/schemas/SchemaVersion" + }, + "server_instance_id": { + "$ref": "#/components/schemas/ServerInstanceId" + }, + "sequence": { + "$ref": "#/components/schemas/EventSequence" + }, + "type": { + "const": "operation" + }, + "payload": { + "$ref": "#/components/schemas/OperationPayload" + }, + "event_id": { + "$ref": "#/components/schemas/EventId" + }, + "emitted_at": { + "type": "string", + "format": "date-time", + "description": "RFC3339 UTC time at which the event was appended to the server ring." + } + } + }, + "DownloadProgressEvent": { + "type": "object", + "additionalProperties": false, + "required": [ + "schema_version", + "server_instance_id", + "sequence", + "type", + "payload", + "event_id", + "emitted_at" + ], + "properties": { + "schema_version": { + "$ref": "#/components/schemas/SchemaVersion" + }, + "server_instance_id": { + "$ref": "#/components/schemas/ServerInstanceId" + }, + "sequence": { + "$ref": "#/components/schemas/EventSequence" + }, + "type": { + "const": "download_progress" + }, + "payload": { + "$ref": "#/components/schemas/DownloadProgressPayload" + }, + "event_id": { + "$ref": "#/components/schemas/EventId" + }, + "emitted_at": { + "type": "string", + "format": "date-time", + "description": "RFC3339 UTC time at which the event was appended to the server ring." + } + } + }, + "RuntimeEvent": { + "type": "object", + "additionalProperties": false, + "required": [ + "schema_version", + "server_instance_id", + "sequence", + "type", + "payload", + "event_id", + "emitted_at" + ], + "properties": { + "schema_version": { + "$ref": "#/components/schemas/SchemaVersion" + }, + "server_instance_id": { + "$ref": "#/components/schemas/ServerInstanceId" + }, + "sequence": { + "$ref": "#/components/schemas/EventSequence" + }, + "type": { + "const": "runtime" + }, + "payload": { + "$ref": "#/components/schemas/RuntimePayload" + }, + "event_id": { + "$ref": "#/components/schemas/EventId" + }, + "emitted_at": { + "type": "string", + "format": "date-time", + "description": "RFC3339 UTC time at which the event was appended to the server ring." + } + } + }, + "SettingsEvent": { + "type": "object", + "additionalProperties": false, + "required": [ + "schema_version", + "server_instance_id", + "sequence", + "type", + "payload", + "event_id", + "emitted_at" + ], + "properties": { + "schema_version": { + "$ref": "#/components/schemas/SchemaVersion" + }, + "server_instance_id": { + "$ref": "#/components/schemas/ServerInstanceId" + }, + "sequence": { + "$ref": "#/components/schemas/EventSequence" + }, + "type": { + "const": "settings" + }, + "payload": { + "$ref": "#/components/schemas/SettingsPayload" + }, + "event_id": { + "$ref": "#/components/schemas/EventId" + }, + "emitted_at": { + "type": "string", + "format": "date-time", + "description": "RFC3339 UTC time at which the event was appended to the server ring." + } + } + }, + "ResetEvent": { + "type": "object", + "additionalProperties": false, + "required": [ + "schema_version", + "server_instance_id", + "sequence", + "type", + "payload", + "event_id", + "emitted_at" + ], + "properties": { + "schema_version": { + "$ref": "#/components/schemas/SchemaVersion" + }, + "server_instance_id": { + "$ref": "#/components/schemas/ServerInstanceId" + }, + "sequence": { + "$ref": "#/components/schemas/EventSequence" + }, + "type": { + "const": "reset" + }, + "payload": { + "$ref": "#/components/schemas/ResetPayload" + }, + "event_id": { + "$ref": "#/components/schemas/EventId" + }, + "emitted_at": { + "type": "string", + "format": "date-time", + "description": "RFC3339 UTC time at which the event was appended to the server ring." + } + } + }, + "GapEvent": { + "type": "object", + "additionalProperties": false, + "required": [ + "schema_version", + "server_instance_id", + "sequence", + "type", + "payload", + "event_id", + "emitted_at" + ], + "properties": { + "schema_version": { + "$ref": "#/components/schemas/SchemaVersion" + }, + "server_instance_id": { + "$ref": "#/components/schemas/ServerInstanceId" + }, + "sequence": { + "$ref": "#/components/schemas/EventSequence" + }, + "type": { + "const": "gap" + }, + "payload": { + "$ref": "#/components/schemas/ResetPayload" + }, + "event_id": { + "$ref": "#/components/schemas/EventId" + }, + "emitted_at": { + "type": "string", + "format": "date-time", + "description": "RFC3339 UTC time at which the event was appended to the server ring." + } + } + }, + "ServerRestartEvent": { + "type": "object", + "additionalProperties": false, + "required": [ + "schema_version", + "server_instance_id", + "sequence", + "type", + "payload", + "event_id", + "emitted_at" + ], + "properties": { + "schema_version": { + "$ref": "#/components/schemas/SchemaVersion" + }, + "server_instance_id": { + "$ref": "#/components/schemas/ServerInstanceId" + }, + "sequence": { + "$ref": "#/components/schemas/EventSequence" + }, + "type": { + "const": "server_restart" + }, + "payload": { + "$ref": "#/components/schemas/ResetPayload" + }, + "event_id": { + "$ref": "#/components/schemas/EventId" + }, + "emitted_at": { + "type": "string", + "format": "date-time", + "description": "RFC3339 UTC time at which the event was appended to the server ring." + } + } + }, + "HeartbeatEvent": { + "type": "object", + "additionalProperties": false, + "required": [ + "schema_version", + "server_instance_id", + "sequence", + "type", + "payload", + "event_id", + "emitted_at" + ], + "properties": { + "schema_version": { + "$ref": "#/components/schemas/SchemaVersion" + }, + "server_instance_id": { + "$ref": "#/components/schemas/ServerInstanceId" + }, + "sequence": { + "$ref": "#/components/schemas/EventSequence" + }, + "type": { + "const": "heartbeat" + }, + "payload": { + "$ref": "#/components/schemas/HeartbeatPayload" + }, + "event_id": { + "$ref": "#/components/schemas/EventId" + }, + "emitted_at": { + "type": "string", + "format": "date-time", + "description": "RFC3339 UTC time at which the event was appended to the server ring." + } + } + }, + "CanonicalIdentityInput": { + "type": "object", + "additionalProperties": false, + "required": [ + "version", + "source", + "source_rank", + "namespace_hash", + "entry_key" + ], + "properties": { + "version": { + "type": "integer", + "const": 1 + }, + "source": { + "$ref": "#/components/schemas/CatalogSourceKind" + }, + "source_rank": { + "type": "integer", + "minimum": 0, + "maximum": 3 + }, + "namespace_hash": { + "type": "string", + "pattern": "^[a-f0-9]{64}(?![\\\\s\\\\S])" + }, + "entry_key": { + "type": "string", + "minLength": 1, + "maxLength": 256 + } + } + }, + "IdentityVector": { + "type": "object", + "additionalProperties": false, + "required": [ + "source", + "source_rank", + "redacted_source_key", + "entry_key", + "source_key_hash", + "canonical_identity", + "expected_id" + ], + "properties": { + "source": { + "$ref": "#/components/schemas/CatalogSourceKind" + }, + "source_rank": { + "type": "integer", + "minimum": 0, + "maximum": 3 + }, + "redacted_source_key": { + "type": "string", + "minLength": 1 + }, + "entry_key": { + "type": "string", + "minLength": 1 + }, + "source_key_hash": { + "type": "string", + "pattern": "^[a-f0-9]{64}(?![\\\\s\\\\S])" + }, + "canonical_identity": { + "$ref": "#/components/schemas/CanonicalIdentityInput" + }, + "expected_id": { + "type": "string", + "pattern": "^mdl_[A-Za-z0-9_-]{43}(?![\\\\s\\\\S])" + } + } + }, + "IdentityVectors": { + "type": "object", + "additionalProperties": false, + "required": [ + "identity_vectors" + ], + "properties": { + "identity_vectors": { + "type": "array", + "minItems": 2, + "items": { + "$ref": "#/components/schemas/IdentityVector" + } + } + } + }, + "RemovalStatus": { + "type": "object", + "additionalProperties": false, + "required": [ + "eligible", + "reason", + "instructions" + ], + "properties": { + "eligible": { + "type": "boolean" + }, + "reason": { + "type": [ + "string", + "null" + ], + "maxLength": 512 + }, + "instructions": { + "type": [ + "string", + "null" + ], + "maxLength": 512 + } + } + }, + "CatalogMetadataUnknownReasons": { + "type": "object", + "additionalProperties": false, + "required": [], + "description": "Reasons for metadata fields that are null or deliberately unmeasured.", + "properties": { + "architecture": { + "type": [ + "string", + "null" + ], + "maxLength": 512 + }, + "declared_architectures": { + "type": [ + "string", + "null" + ], + "maxLength": 512 + }, + "model_type": { + "type": [ + "string", + "null" + ], + "maxLength": 512 + }, + "quantization": { + "type": [ + "string", + "null" + ], + "maxLength": 512 + }, + "format": { + "type": [ + "string", + "null" + ], + "maxLength": 512 + }, + "parameter_count": { + "type": [ + "string", + "null" + ], + "maxLength": 512 + }, + "disk_bytes": { + "type": [ + "string", + "null" + ], + "maxLength": 512 + }, + "memory_estimate_bytes": { + "type": [ + "string", + "null" + ], + "maxLength": 512 + } + } + }, + "RuntimeSlot": { + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "processing", + "prompt_tokens", + "cached_prompt_tokens", + "decoded_tokens" + ], + "properties": { + "id": { + "type": "integer", + "minimum": 0 + }, + "processing": { + "type": "boolean" + }, + "prompt_tokens": { + "type": [ + "integer", + "null" + ], + "minimum": 0, + "description": "Current context occupancy from GET /slots n_prompt_tokens: includes processed prompt and accepted decoded tokens. Never add decoded_tokens again." + }, + "cached_prompt_tokens": { + "type": [ + "integer", + "null" + ], + "minimum": 0 + }, + "decoded_tokens": { + "type": [ + "integer", + "null" + ], + "minimum": 0 + } + } + }, + "RuntimeSlots": { + "type": "object", + "additionalProperties": false, + "required": [ + "available", + "reason", + "measured_at", + "configured_parallelism", + "effective_parallelism", + "request_context_tokens", + "shared_pool_context_tokens", + "items" + ], + "properties": { + "available": { + "type": "boolean" + }, + "reason": { + "type": [ + "string", + "null" + ], + "maxLength": 256 + }, + "measured_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ] + }, + "configured_parallelism": { + "type": "integer", + "minimum": 0 + }, + "effective_parallelism": { + "type": [ + "integer", + "null" + ], + "minimum": 0 + }, + "request_context_tokens": { + "type": [ + "integer", + "null" + ], + "minimum": 0 + }, + "shared_pool_context_tokens": { + "type": [ + "integer", + "null" + ], + "minimum": 0 + }, + "items": { + "type": "array", + "maxItems": 256, + "items": { + "$ref": "#/components/schemas/RuntimeSlot" + } + } + } + }, + "MediaLimits": { + "type": "object", + "additionalProperties": false, + "required": [ + "max_images", + "max_image_bytes", + "max_width", + "max_height", + "max_decoded_bytes", + "max_body_bytes" + ], + "properties": { + "max_images": { + "type": "integer", + "minimum": 0, + "maximum": 9007199254740991 + }, + "max_image_bytes": { + "type": "integer", + "minimum": 0, + "maximum": 9007199254740991 + }, + "max_width": { + "type": "integer", + "minimum": 0, + "maximum": 9007199254740991 + }, + "max_height": { + "type": "integer", + "minimum": 0, + "maximum": 9007199254740991 + }, + "max_decoded_bytes": { + "type": "integer", + "minimum": 0, + "maximum": 9007199254740991 + }, + "max_body_bytes": { + "type": "integer", + "minimum": 0, + "maximum": 9007199254740991 + } + }, + "description": "Resolved server image admission and WebUI JSON body limits; clients may impose additional lower local safety ceilings. JSON budget includes base64 encoding, transcript and request envelope." + } + } + } +} +`,B=class extends Error{path;constructor(e,t){super(`${e}: ${t}`),this.path=e,this.name=`ValidationError`}},Pt=Lt(Nt);function Ft(e,t,n=`$`){let r=Jt(Pt,[`components`,`schemas`],`#/components/schemas`)[e];if(r===void 0)throw new B(n,`unknown schema ${e}`);Rt(r,t,n)}function It(e){return JSON.parse(e)}function Lt(e){return qt(It(e),`$contract`)}function Rt(e,t,n){let r=qt(e,`${n}#schema`);if(typeof r.$ref==`string`){Rt(Gt(r.$ref),t,n);return}if(r.anyOf!==void 0){if(!Array.isArray(r.anyOf)||!r.anyOf.some(e=>Kt(e,t,n)))throw new B(n,`did not match any allowed schema`);return}if(r.oneOf!==void 0){if(!Array.isArray(r.oneOf))throw new B(n,`schema oneOf must be an array`);let e=r.oneOf.filter(e=>Kt(e,t,n)).length;if(e!==1)throw new B(n,`matched ${e} oneOf schemas`);return}if(r.const!==void 0&&t!==r.const)throw new B(n,`expected constant ${String(r.const)}`);if(Array.isArray(r.enum)&&!r.enum.some(e=>e===t))throw new B(n,`unexpected enum value ${String(t)}`);let i=r.type;if(Array.isArray(i)){if(!i.some(e=>Wt(e,t)))throw new B(n,`expected one of ${i.join(`, `)}`)}else if(typeof i==`string`&&!Wt(i,t))throw new B(n,`expected ${i}`);typeof t==`string`&&Ht(r,t,n),typeof t==`number`&&V(r,t,n),Array.isArray(t)&&Bt(r,t,n),Yt(t)&&zt(r,t,n)}function zt(e,t,n){let r=Xt(e.required,`${n}#schema.required`,!1),i=e.properties===void 0?{}:qt(e.properties,`${n}#schema.properties`);for(let e of r)if(!(e in t))throw new B(`${n}.${e}`,`missing required property`);if(e.maxProperties!==void 0&&Object.keys(t).length>Zt(e.maxProperties,`${n}#schema.maxProperties`))throw new B(n,`too many object properties`);for(let[r,a]of Object.entries(t)){let t=i[r];if(t!==void 0)Rt(t,a,`${n}.${r}`);else if(e.additionalProperties===!1)throw new B(`${n}.${r}`,`unexpected property`);else Yt(e.additionalProperties)&&Rt(e.additionalProperties,a,`${n}.${r}`)}}function Bt(e,t,n){if(e.minItems!==void 0&&t.lengthZt(e.maxItems,`${n}#schema.maxItems`))throw new B(n,`array longer than maximum`);e.items!==void 0&&t.forEach((t,r)=>Rt(e.items,t,`${n}[${r}]`))}function Vt(e){let t=0;for(let n=0;n65535?2:1;return t}function Ht(e,t,n){let r=Vt(t);if(e.minLength!==void 0&&rZt(e.maxLength,`${n}#schema.maxLength`))throw new B(n,`string longer than maximum`);if(typeof e.pattern==`string`&&!new RegExp(e.pattern,`u`).test(t))throw new B(n,`string does not match pattern`);if(e.format===`date-time`&&!Ut(t))throw new B(n,`invalid RFC3339 date-time`)}function Ut(e){return/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/.test(e)?!Number.isNaN(Date.parse(e)):!1}function V(e,t,n){if(!Number.isFinite(t))throw new B(n,`expected finite number`);if(e.type===`integer`&&!Number.isInteger(t))throw new B(n,`expected integer`);if(e.minimum!==void 0&&tZt(e.maximum,`${n}#schema.maximum`))throw new B(n,`number above maximum`)}function Wt(e,t){return e===`null`?t===null:e===`array`?Array.isArray(t):e===`object`?Yt(t):e===`integer`?typeof t==`number`&&Number.isInteger(t):e===`number`?typeof t==`number`&&Number.isFinite(t):typeof t===e}function Gt(e){if(!e.startsWith(`#/`))throw new B(`$ref`,`unsupported external ref ${e}`);return e.slice(2).split(`/`).map(e=>e.replace(/~1/g,`/`).replace(/~0/g,`~`)).reduce((t,n)=>qt(t,e)[n],Pt)}function Kt(e,t,n){try{return Rt(e,t,n),!0}catch(e){if(e instanceof B)return!1;throw e}}function qt(e,t){if(!Yt(e))throw new B(t,`expected object`);return e}function Jt(e,t,n){return t.reduce((e,t)=>qt(e,n)[t],e)}function Yt(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Xt(e,t,n){if(e===void 0&&!n)return[];if(!Array.isArray(e)||!e.every(e=>typeof e==`string`))throw new B(t,`expected string array`);return e}function Zt(e,t){if(typeof e!=`number`||!Number.isFinite(e))throw new B(t,`expected numeric schema bound`);return e}function Qt(e,t,n){return Ft(e,t,n),t}function $t(e,t=`$`){return Qt(`ErrorEnvelope`,e,t)}function en(e,t=`$`){return Qt(`BootstrapResponse`,e,t)}function tn(e,t=`$`){return Qt(`CatalogEntry`,e,t)}function nn(e,t=`$`){return Qt(`CatalogListResponse`,e,t)}function rn(e,t=`$`){return Qt(`OperationsListResponse`,e,t)}function an(e,t=`$`){return Qt(`Operation`,e,t)}function on(e,t=`$`){return Qt(`OperationAccepted`,e,t)}function sn(e,t=`$`){return Qt(`RuntimeSnapshot`,e,t)}function cn(e,t=`$`){return Qt(`UiEvent`,e,t)}var ln=class extends Error{status;envelope;constructor(e,t,n){super(n??t?.error.message??`WebUI request failed with HTTP ${e}`),this.status=e,this.envelope=t,this.name=`WebUiHttpError`}},un=2097152,dn=class{apiBase;fetchImpl;bearerToken=null;onUnauthorized;controllers=new Set;constructor(e={}){this.apiBase=Ot(e.apiBase),this.fetchImpl=e.fetchImpl??fetch.bind(globalThis),this.onUnauthorized=e.onUnauthorized}setBearerToken(e){this.bearerToken=e}abortAll(){for(let e of this.controllers)e.abort();this.controllers.clear()}async bootstrap(e){return this.request(`/ui-api/v1/bootstrap`,en,{method:`GET`,signal:e})}async catalog(e={},t){return this.request(`/ui-api/v1/catalog`,nn,{method:`GET`,query:{...e},signal:t})}async catalogEntry(e,t){return this.request(`/ui-api/v1/catalog/${Mt(e)}`,tn,{method:`GET`,signal:t})}async refreshCatalog(e,t){return this.request(`/ui-api/v1/catalog/refresh`,on,{method:`POST`,body:{idempotency_key:e},signal:t})}async modelAction(e,t){return this.request(`/ui-api/v1/model-actions`,on,{method:`POST`,body:e,signal:t})}async download(e,t){return this.request(`/ui-api/v1/downloads`,on,{method:`POST`,body:e,signal:t})}async removeModel(e,t){return this.request(`/ui-api/v1/model-removals`,on,{method:`POST`,body:e,signal:t})}async operationsPage(e={},t){return this.request(`/ui-api/v1/operations`,rn,{method:`GET`,query:e,signal:t})}async operations(e){let t=[],n,r=null;for(;;){let i=await this.operationsPage(n===void 0?{}:{cursor:n},e);if(r===null)r=i.server_instance_id;else if(i.server_instance_id!==r)throw Error(`Operations pagination crossed a server restart; refresh the authoritative snapshot.`);if(t.push(...i.items),i.pagination.next_cursor===null)return t;n=i.pagination.next_cursor}}async operation(e,t){return this.request(`/ui-api/v1/operations/${Mt(e)}`,an,{method:`GET`,signal:t})}async cancelOperation(e,t){return this.request(`/ui-api/v1/operations/${Mt(e)}/cancel`,on,{method:`POST`,body:{},signal:t})}async runtime(e,t){let n=await this.request(`/ui-api/v1/runtime`,sn,{method:`GET`,query:{model_id:e,autoload:!1},signal:t});if(n.model_id!==e)throw Error(`Runtime response model_id did not match the requested model.`);return n}async tokenCount(e,t,n){return this.request(`/tokenize`,Ct,{method:`POST`,query:{model:e,autoload:!1},body:{content:t,add_special:!1,parse_special:!0,with_pieces:!1},signal:n})}async settings(e,t){return this.request(`/settings`,vt,{method:`GET`,query:{model:e,autoload:!1},signal:t})}async patchSettings(e,t,n){return this.request(`/settings`,yt,{method:`PATCH`,query:{model:e,autoload:!1},body:{op:`merge`,values:t},signal:n})}async modelProps(e,t){return this.request(`/props`,bt,{method:`GET`,query:{model:e,autoload:!1},signal:t})}async events(e,t,n){let r=n?.serverInstanceId!==void 0&&n.serverInstanceId!==null&&n.afterSequence!==null&&n.afterSequence!==void 0,i=r?{server_instance_id:n.serverInstanceId,after_sequence:n.afterSequence}:void 0,a=new Headers({Accept:`text/event-stream`});!r&&n?.lastEventId!==void 0&&n.lastEventId!==null&&a.set(`Last-Event-ID`,n.lastEventId),await this.sse(jt(this.apiBase,`/ui-api/v1/events`,i),{method:`GET`,signal:t,headers:a},{onDone:e.onDone,onFrame:t=>{t.retry!==null&&e.onRetryAfter?.(t.retry),t.data.length>0&&e.onEvent(cn(It(t.data)))}})}async chatCompletions(e,t,n,r){await this.sse(jt(this.apiBase,`/v1/chat/completions`,{autoload:!1}),{method:`POST`,body:mn(t,e),signal:r,headers:{Accept:`text/event-stream`}},n)}async responses(e,t,n,r){await this.sse(jt(this.apiBase,`/v1/responses`,{autoload:!1}),{method:`POST`,body:mn(t,e),signal:r,headers:{Accept:`text/event-stream`}},n)}async request(e,t,n){let r=await this.fetchWithAuth(jt(this.apiBase,e,n.query),n);try{return r.response.ok||await this.throwHttp(r.response,r.signal),t(It(await this.readBody(r.response,r.signal)))}finally{this.controllers.delete(r.controller),r.cleanup()}}async sse(e,t,n){let r=await this.fetchWithAuth(e,t);try{let e=r.response;if(e.ok||await this.throwHttp(e,r.signal),e.body===null)throw Error(`WebUI event stream response has no body.`);let t=new Tt({onDone:n.onDone,onMessage:n.onFrame}),i=e.body.getReader();try{for(;;){let e=await hn(i,r.signal);if(e.done)break;t.push(e.value)}if(t.close(),!t.done&&r.signal.aborted!==!0)throw Error(`WebUI event stream ended before a DONE frame.`)}catch(e){throw await i.cancel().catch(()=>void 0),e}finally{i.releaseLock()}}finally{this.controllers.delete(r.controller),r.cleanup()}}async fetchWithAuth(e,t){let n=new AbortController,{signal:r,cleanup:i}=gn(n,t.signal);this.controllers.add(n);let a=new Headers(t.headers);a.set(`Accept`,a.get(`Accept`)??`application/json`),this.bearerToken!==null&&a.set(`Authorization`,`Bearer ${this.bearerToken}`),t.body!==void 0&&a.set(`Content-Type`,`application/json`);try{return{response:await this.fetchImpl(e,{method:t.method,headers:a,body:t.body===void 0?void 0:JSON.stringify(t.body),signal:r,credentials:`same-origin`,cache:`no-store`,redirect:`error`}),controller:n,signal:r,cleanup:i}}catch(e){throw this.controllers.delete(n),i(),e}}async throwHttp(e,t){let n=this.bearerToken;e.status===401&&(this.bearerToken=null,this.abortAll(),this.onUnauthorized?.());let r=null;try{let n=await this.readBody(e,t);n.length>0&&(r=$t(It(n)))}catch{r=null}throw new ln(e.status,fn(r,n),pn(r?.error.message??`WebUI request failed with HTTP ${e.status}`,n))}async readBody(e,t){if(e.body===null)return``;let n=e.body.getReader(),r=[],i=0;try{for(;;){let e=await hn(n,t);if(e.done)break;if(i+=e.value.byteLength,i>un)throw Error(`WebUI JSON response exceeded the configured byte limit.`);r.push(e.value)}}catch(e){throw await n.cancel().catch(()=>void 0),e}finally{n.releaseLock()}let a=new Uint8Array(i),o=0;for(let e of r)a.set(e,o),o+=e.byteLength;return new TextDecoder().decode(a)}};function fn(e,t){return e===null?null:{...e,error:{...e.error,message:pn(e.error.message,t),field_errors:e.error.field_errors?.map(e=>({...e,message:pn(e.message,t)}))}}}function pn(e,t){let n=e.replace(/Bearer\s+\S+/gi,`Bearer [redacted]`).replace(/token[=:]\s*\S+/gi,`token=[redacted]`);return t!==null&&t.length>0&&(n=n.split(t).join(`[redacted]`)),n}function mn(e,t){if(t.length===0)throw Error(`Inference model id is required for streaming inference.`);if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Streaming inference bodies must be JSON objects.`);return{...e,model:t,stream:!0}}async function hn(e,t){if(t.aborted)throw await e.cancel().catch(()=>void 0),_n();let n=null;try{let r=await Promise.race([e.read(),new Promise((r,i)=>{n=()=>{e.cancel().catch(()=>void 0),i(_n())},t.addEventListener(`abort`,n,{once:!0})})]);if(t.aborted)throw _n();return r}finally{n!==null&&t.removeEventListener(`abort`,n)}}function gn(e,t){if(t===void 0)return{signal:e.signal,cleanup:()=>void 0};let n=()=>e.abort(t.reason);return t.aborted?n():t.addEventListener(`abort`,n,{once:!0}),{signal:e.signal,cleanup:()=>t.removeEventListener(`abort`,n)}}function _n(){return typeof DOMException==`function`?new DOMException(`The WebUI request was aborted.`,`AbortError`):Error(`The WebUI request was aborted.`)}function vn(e,t,n){let r=e.filter(e=>e.runtime.server_instance_id===t.server_instance_id&&e.runtime.model_id===t.model_id&&e.receivedAt>n-3e5&&e.receivedAt<=n),i=r.at(-1);return i!==void 0&&Math.floor(i.receivedAt/2e3)===Math.floor(n/2e3)&&r.pop(),[...r,{receivedAt:n,runtime:t}].slice(-150)}function yn(e,t){let n=[...e.values()].sort((e,t)=>t.updated_at.localeCompare(e.updated_at)),r=n.filter(e=>!bn(e)),i=n.filter(e=>bn(e)&&Date.parse(e.updated_at)>t-36e5).slice(0,200);return new Map([...r,...i].map(e=>[e.operation_id,e]))}function bn(e){return[`succeeded`,`failed`,`cancelled`].includes(e.state)}var xn=`webui.ui-api.v1`;function Sn(){return{schemaVersion:xn,auth:{status:`signed-out`,tokenPresent:!1},connection:`idle`,bootstrap:null,catalog:[],catalogSequence:null,operations:new Map,runtimes:new Map,runtimeHistory:[],selectedModelId:null,serverInstanceId:null,lastEventId:null,lastSequence:null,lastUpdatedAt:null,lastSuccessfulAt:null,error:null,pendingReconciliations:new Map,resourceFences:{catalog:null,operationsSnapshot:null,operations:new Map,models:new Map,runtimes:new Map}}}function Cn(e,t){return t.type===`login-start`?{...e,auth:{status:`authenticating`,tokenPresent:!0},connection:`bootstrapping`,error:null}:t.type===`login-success`?wn(e,t.bootstrap,t.now):t.type===`logout`?{...Sn(),lastUpdatedAt:t.now}:t.type===`select-model`?{...e,selectedModelId:t.modelId,runtimeHistory:[]}:t.type===`catalog`?Tn(e,t.response,t.now):t.type===`operations-snapshot`?En(e,t.response,t.now):t.type===`operation`?Dn(e,t.operation,t.sequence,t.now):t.type===`runtime`?On(e,t.runtime,t.sequence,t.now):t.type===`event`?kn(e,t.event,t.now):t.type===`pending`?{...e,pendingReconciliations:Ln(e.pendingReconciliations,t.item.idempotencyKey,t.item)}:t.type===`reconciled`?{...e,pendingReconciliations:Rn(e.pendingReconciliations,t.idempotencyKey)}:{...e,connection:t.connection,error:t.error??null,lastUpdatedAt:t.now}}function wn(e,t,n){let r=t.server.server_instance_id;return e.serverInstanceId!==null&&e.serverInstanceId!==r?{...Sn(),auth:{status:`authenticated`,tokenPresent:!0},connection:`ready`,bootstrap:t,serverInstanceId:r,lastUpdatedAt:n}:{...e,auth:{status:`authenticated`,tokenPresent:!0},connection:`ready`,bootstrap:t,serverInstanceId:r,lastUpdatedAt:n,error:null}}function Tn(e,t,n){if(e.serverInstanceId!==null&&t.server_instance_id!==e.serverInstanceId)return Nn(e,t.server_instance_id,n);if(e.catalogSequence!==null&&t.snapshot_sequenceo.has(e)))};return Pn({...e,operations:o,serverInstanceId:t.server_instance_id,lastSequence:In(s),error:null,resourceFences:s},n)}function Dn(e,t,n,r){if(n!==null&&e.resourceFences.operationsSnapshot!==null&&n<=e.resourceFences.operationsSnapshot)return e;let i=e.resourceFences.operations.get(t.operation_id);if(n!==null&&i!==void 0&&n<=i)return e;let a=yn(Ln(e.operations,t.operation_id,t),r),o=n===null?e.resourceFences.operations:Ln(e.resourceFences.operations,t.operation_id,n),s={...e.resourceFences,operations:new Map([...o].filter(([e])=>a.has(e)))};return Pn({...e,operations:a,lastSequence:In(s),error:null,resourceFences:s},r)}function On(e,t,n,r){if(e.serverInstanceId!==null&&t.server_instance_id!==e.serverInstanceId)return Nn(e,t.server_instance_id,r);let i=e.resourceFences.runtimes.get(t.model_id);if(n!==null&&i!==void 0&&ne.identity.id===r&&t.payload.revision>=e.identity.revision?{...e,identity:{...e.identity,revision:t.payload.revision},lifecycle:t.payload.lifecycle}:e),o={...e.resourceFences,models:Ln(e.resourceFences.models,r,t.sequence)};return Pn({...e,catalog:a,serverInstanceId:t.server_instance_id,lastEventId:t.event_id,lastSequence:In(o),connection:`streaming`,resourceFences:o},n)}function jn(e,t,n){let r=t.payload.runtime,i=e.resourceFences.runtimes.get(r.model_id);if(i!==void 0&&t.sequence<=i)return e;let a={...e.resourceFences,runtimes:Ln(e.resourceFences.runtimes,r.model_id,t.sequence)};return Pn({...e,runtimes:Ln(e.runtimes,r.model_id,r),runtimeHistory:r.model_id===e.selectedModelId?vn(e.runtimeHistory,r,n):e.runtimeHistory,serverInstanceId:t.server_instance_id,lastEventId:t.event_id,lastSequence:In(a),connection:`streaming`,resourceFences:a},n)}function Mn(e,t,n){let r=t.type===`server_restart`?null:e.lastSuccessfulAt;return{...Sn(),auth:e.auth,connection:`stale`,serverInstanceId:t.server_instance_id,selectedModelId:e.selectedModelId,lastEventId:t.event_id,error:{code:t.type,message:t.payload.reason,retryable:t.payload.resnapshot},pendingReconciliations:e.pendingReconciliations,lastUpdatedAt:n,lastSuccessfulAt:r}}function Nn(e,t,n){return{...Sn(),auth:e.auth,connection:`stale`,serverInstanceId:t,selectedModelId:e.selectedModelId,error:{code:`server_restarted`,message:`The mlxcel server restarted; refresh the authoritative snapshot before continuing.`,retryable:!0},pendingReconciliations:e.pendingReconciliations,lastUpdatedAt:n}}function Pn(e,t){return{...e,lastUpdatedAt:t,lastSuccessfulAt:t}}function Fn(e,t){if(e.length>0){let n=new Map(e.map(e=>[e.identity.id,e]));for(let e of t.items)n.set(e.identity.id,e);return Array.from(n.values()).sort((e,t)=>e.identity.display_name.localeCompare(t.identity.display_name))}return t.items}function In(e){let t=[e.catalog,e.operationsSnapshot,...e.operations.values(),...e.models.values(),...e.runtimes.values()].filter(e=>e!==null);return t.length===0?null:Math.min(...t)}function Ln(e,t,n){let r=new Map(e);return r.set(t,n),r}function Rn(e,t){let n=new Map(e);return n.delete(t),n}var zn=2e3,Bn=1e4,Vn=3e4,Hn=6e4,Un=6e4,Wn=new Set([`snapshot`,`model_revision`]),Gn=class{client;dispatch;getSnapshot;clock;visibility;random;timer=null;observationTimer=null;inflight=null;eventAbort=null;stopped=!0;failures=0;generation=0;needsFullSnapshot=!0;lastFullSnapshotAt=null;unsubscribe;constructor(e){this.client=e.client,this.dispatch=e.dispatch,this.getSnapshot=e.getSnapshot,this.clock=e.clock??Zn,this.visibility=e.visibility??Qn,this.random=e.random??Math.random,this.unsubscribe=this.visibility.subscribe(()=>this.visibilityChanged())}start(){this.stopped&&(this.stopped=!1,this.generation+=1,this.needsFullSnapshot=!0,this.reschedule(0))}stop(){this.generation+=1,this.stopped=!0,this.timer!==null&&this.clock.clearTimeout(this.timer),this.timer=null,this.observationTimer!==null&&this.clock.clearTimeout(this.observationTimer),this.observationTimer=null,this.inflight?.abort(),this.inflight=null,this.eventAbort?.abort(),this.eventAbort=null}selectionChanged(){this.cancelObservation(),this.reschedule(0)}fullSnapshotDue(e){let t=this.getSnapshot();return t.bootstrap===null||t.catalogSequence===null||this.needsFullSnapshot||this.lastFullSnapshotAt===null||this.eventAbort===null?!0:e-this.lastFullSnapshotAt>=Un}cancelObservation(){this.generation+=1,this.observationTimer!==null&&this.clock.clearTimeout(this.observationTimer),this.observationTimer=null,this.inflight?.abort(),this.inflight=null,this.eventAbort?.abort(),this.eventAbort=null,this.timer!==null&&this.clock.clearTimeout(this.timer),this.timer=null}visibilityChanged(){this.cancelObservation(),this.needsFullSnapshot=!0,!this.stopped&&(this.dispatch({type:`connection`,connection:`stale`,now:this.clock.now()}),this.reschedule(0))}dispose(){this.stop(),this.unsubscribe()}async resnapshot(){this.needsFullSnapshot=!0,await this.refresh()}async refresh(){if(this.inflight!==null)return;let e=new AbortController;this.inflight=e;let t=this.generation,n=this.clock.now(),r=this.clock.setTimeout(()=>{e.abort(),this.generation===t&&this.dispatch({type:`connection`,connection:`stale`,error:{code:`observation_timeout`,message:`Runtime observation timed out; retrying.`,retryable:!0},now:this.clock.now()})},Bn);this.observationTimer=r;try{if(this.getSnapshot().auth.status===`signed-out`)return;let r=this.fullSnapshotDue(n),i=null,a=[];if(r){if(i=await this.client.bootstrap(e.signal),!this.isCurrent(e,t)||this.getSnapshot().auth.status===`signed-out`||(this.dispatch({type:`login-success`,bootstrap:i,now:n}),a=await this.catalogSnapshot(e.signal),!this.isCurrent(e,t)))return;for(let e of a)this.dispatch({type:`catalog`,response:e,now:n})}let o=await this.operationSnapshot(e.signal);if(!this.isCurrent(e,t))return;let s=a.at(-1),c=o[0];if(s!==void 0&&c!==void 0&&c.server_instance_id!==s.server_instance_id){this.dispatch({type:`connection`,connection:`stale`,error:{code:`snapshot_mismatch`,message:`Operation and catalog snapshots came from different server instances.`,retryable:!0},now:n});return}let l=o.flatMap(e=>(this.dispatch({type:`operations-snapshot`,response:e,now:n}),e.items)),u=this.getSnapshot().selectedModelId,d=r&&i!==null&&u!==null&&a.every(e=>e.server_instance_id===i.server.server_instance_id)&&!a.some(e=>e.items.some(e=>e.identity.id===u));if(d&&this.dispatch({type:`select-model`,modelId:null}),d||await this.refreshSelectedRuntime(e.signal,t),r&&(this.needsFullSnapshot=!1,this.lastFullSnapshotAt=n),!this.isCurrent(e,t))return;let f=this.reconcilePending(l,n);this.failures=0,f||this.dispatch({type:`connection`,connection:`ready`,now:n}),this.eventAbort===null&&!this.visibility.hidden()&&this.startEvents()}catch(n){!e.signal.aborted&&this.generation===t&&(this.failures+=1,this.dispatch({type:`connection`,connection:qn(n),error:Jn(n),now:this.clock.now()}))}finally{this.clock.clearTimeout(r),this.observationTimer===r&&(this.observationTimer=null),this.inflight===e&&(this.inflight=null),!this.stopped&&this.generation===t&&this.reschedule(this.pollDelay())}}noteUnknownPost(e){this.dispatch({type:`pending`,item:e}),this.reschedule(0)}startEvents(){this.eventAbort?.abort();let e=new AbortController;this.eventAbort=e;let t=this.generation,n=Kn(this.getSnapshot());this.client.events({onEvent:n=>{this.generation===t&&!e.signal.aborted&&!this.stopped&&this.handleEvent(n)},onRetryAfter:n=>{this.generation===t&&!e.signal.aborted&&!this.stopped&&this.reschedule(n)}},e.signal,n).then(()=>{this.generation===t&&(this.eventAbort===e&&(this.eventAbort=null),!e.signal.aborted&&!this.stopped&&this.reschedule(this.backoffDelay()))}).catch(n=>{e.signal.aborted||this.stopped||this.generation!==t||(this.failures+=1,this.eventAbort=null,this.dispatch({type:`connection`,connection:qn(n),error:Jn(n),now:this.clock.now()}),this.reschedule(this.backoffDelay()))})}handleEvent(e){this.dispatch({type:`event`,event:e,now:this.clock.now()}),Wn.has(e.type)&&(this.needsFullSnapshot=!0),(e.type===`server_restart`||e.type===`gap`||e.type===`reset`)&&e.payload.resnapshot&&(this.needsFullSnapshot=!0,this.eventAbort?.abort(),this.eventAbort=null,this.refresh())}async catalogSnapshot(e){let t=[],n,r=null;for(;;){let i=await this.client.catalog(n===void 0?{}:{cursor:n},e);if(r===null?r=i:Xn(`catalog`,r,i),t.push(i),i.pagination.next_cursor===null)return t;n=i.pagination.next_cursor}}async operationSnapshot(e){let t=[],n,r=null;for(;;){let i=await this.client.operationsPage(n===void 0?{}:{cursor:n},e);if(r===null?r=i:Xn(`operations`,r,i),t.push(i),i.pagination.next_cursor===null)return t;n=i.pagination.next_cursor}}async refreshSelectedRuntime(e,t){let n=this.getSnapshot().selectedModelId;if(n===null)return;let r;try{r=await this.client.runtime(n,e)}catch(e){throw typeof e==`object`&&e&&`status`in e&&e.status===404?new Yn(`Selected model changed during observation; refreshing the catalog.`):e}e.aborted||this.generation!==t||this.getSnapshot().selectedModelId===n&&this.dispatch({type:`runtime`,runtime:r,sequence:r.snapshot_sequence,now:this.clock.now()})}reconcilePending(e,t){let n=!1,r=new Set(e.map(e=>e.operation_id));for(let e of this.getSnapshot().pendingReconciliations.values())e.operationId!==null&&r.has(e.operationId)?this.dispatch({type:`reconciled`,idempotencyKey:e.idempotencyKey}):t-e.createdAt>=Hn&&(this.dispatch({type:`reconciled`,idempotencyKey:e.idempotencyKey}),this.dispatch({type:`connection`,connection:`stale`,error:{code:`unknown_post_unresolved`,message:`A previous control request could not be matched to an operation after reconciliation.`,retryable:!0},now:t}),n=!0);return n}reschedule(e){this.stopped||this.visibility.hidden()||(this.timer!==null&&this.clock.clearTimeout(this.timer),this.timer=this.clock.setTimeout(()=>{this.timer=null,this.refresh()},e))}pollDelay(){return zn}backoffDelay(){let e=Math.min(Vn,500*2**Math.min(6,this.failures));return Math.round(e/2+this.random()*(e/2))}isCurrent(e,t){return this.inflight===e&&this.generation===t&&!e.signal.aborted}};function Kn(e){let t=In(e.resourceFences);if(e.serverInstanceId!==null&&t!==null)return{lastEventId:null,serverInstanceId:e.serverInstanceId,afterSequence:t};if(e.lastEventId!==null)return{lastEventId:e.lastEventId,serverInstanceId:null,afterSequence:null}}function qn(e){if(e instanceof Yn)return`stale`;let t=typeof e==`object`&&e&&`status`in e&&typeof e.status==`number`?e.status:null;return t===401||e instanceof Error&&/401|unauthorized/i.test(e.message)?`unauthorized`:t===403||e instanceof Error&&/403|forbidden/i.test(e.message)?`forbidden`:e instanceof DOMException&&e.name===`AbortError`?`stale`:`offline`}function Jn(e){return e instanceof Yn?{code:e.code,message:e.message,retryable:!0}:{code:`sync_error`,message:e instanceof Error?e.message.replace(/Bearer\s+\S+/gi,`Bearer [redacted]`):`Unknown WebUI client error`,retryable:!0}}var Yn=class extends Error{code=`snapshot_mismatch`;constructor(e){super(e),this.name=`SnapshotConsistencyError`}};function Xn(e,t,n){if(n.server_instance_id!==t.server_instance_id)throw new Yn(`${e} pagination crossed a server restart; refresh the authoritative snapshot.`);if(n.snapshot_sequence!==t.snapshot_sequence)throw new Yn(`${e} pagination crossed snapshot sequence boundaries; refresh the authoritative snapshot.`)}var Zn={setTimeout:(e,t)=>globalThis.setTimeout(e,t),clearTimeout:e=>globalThis.clearTimeout(e),now:()=>Date.now()},Qn={hidden:()=>typeof document<`u`&&document.hidden,subscribe:e=>typeof document>`u`?()=>void 0:(document.addEventListener(`visibilitychange`,e),()=>document.removeEventListener(`visibilitychange`,e))},$n=_.createContext(null),er=_.createContext(null);function tr({children:e,apiBase:t,fetchImpl:n}){let[r,i]=_.useReducer(Cn,void 0,Sn),a=_.useRef(r);a.current=r;let o=_.useRef(0),s=_.useRef(null),c=_.useMemo(()=>new dn({apiBase:t,fetchImpl:n,onUnauthorized:()=>{o.current+=1,s.current?.stop(),i({type:`logout`,now:Date.now()})}}),[t,n]);_.useEffect(()=>{let e=new Gn({client:c,dispatch:i,getSnapshot:()=>a.current});return s.current=e,()=>{e.dispose(),s.current=null,c.abortAll()}},[c]);let l=_.useMemo(()=>({getTokenCount:(e,t,n)=>c.tokenCount(d(e),t,n),getSettings:(e,t)=>c.settings(d(e),t),patchSettings:(e,t,n)=>c.patchSettings(d(e),t,n),getModelProps:(e,t)=>c.modelProps(d(e),t),login:async e=>{o.current+=1;let t=o.current;c.abortAll(),c.setBearerToken(e),i({type:`login-start`});try{let e=await c.bootstrap();if(o.current!==t)return;i({type:`login-success`,bootstrap:e,now:Date.now()}),s.current?.start()}catch(e){throw o.current===t&&(c.setBearerToken(null),c.abortAll(),i({type:`logout`,now:Date.now()})),e}},logout:()=>{o.current+=1,s.current?.stop(),c.setBearerToken(null),c.abortAll(),i({type:`logout`,now:Date.now()})},refresh:async()=>{await s.current?.resnapshot()},selectModel:e=>{i({type:`select-model`,modelId:e}),s.current?.selectionChanged()},loadModel:async e=>{await u(`model-action`,e.idempotency_key,e.model_id,()=>c.modelAction(e))},unloadModel:async e=>{await u(`model-action`,e.idempotency_key,e.model_id,()=>c.modelAction(e))},downloadModel:async e=>{await u(`download`,e.idempotency_key,void 0,()=>c.download(e))},removeModel:async e=>{await u(`removal`,e.idempotency_key,e.model_id,()=>c.removeModel(e))},refreshRuntime:async e=>{let t=o.current,n=await c.runtime(e);return o.current===t&&i({type:`runtime`,runtime:n,sequence:n.snapshot_sequence,now:Date.now()}),n},refreshCatalog:async e=>{await u(`catalog-refresh`,e,void 0,()=>c.refreshCatalog(e))},cancelOperation:async e=>{let t=o.current;await c.cancelOperation(e),o.current===t&&await s.current?.resnapshot()},streamChatCompletions:async(e,t,n,r)=>{await c.chatCompletions(d(e),t,n,r)},streamResponses:async(e,t,n,r)=>{await c.responses(d(e),t,n,r)}}),[c]);async function u(e,t,n,r){let i=o.current;try{let a=await r();if(o.current!==i)return;s.current?.noteUnknownPost({kind:e,idempotencyKey:t,operationId:a.operation_id,modelId:n,createdAt:Date.now()})}catch(r){throw o.current===i&&!(r instanceof ln)&&s.current?.noteUnknownPost({kind:e,idempotencyKey:t,operationId:null,modelId:n,createdAt:Date.now()}),r}}function d(e){let t=a.current.catalog.find(t=>t.identity.id===e);if(t===void 0)throw Error(`Selected model is not present in the catalog snapshot.`);if(t.identity.inference_id.length===0)throw Error(`Selected model does not expose an inference model id.`);return t.identity.inference_id}return(0,x.jsx)(er.Provider,{value:l,children:(0,x.jsx)($n.Provider,{value:r,children:e})})}function nr(){let e=_.useContext($n);if(e===null)throw Error(`useWebUi must be used within WebUiProvider.`);return e}function rr(){let e=_.useContext(er);if(e===null)throw Error(`useWebUiActions must be used within WebUiProvider.`);return e}var ir=Object.freeze({}),ar=[`max_tokens`,`temperature`,`top_p`,`top_k`,`min_p`,`repetition_penalty`,`seed`];function or(e){if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Request defaults must be an object.`);let t={};for(let[n,r]of Object.entries(e)){if(!ar.includes(n))throw Error(`Unsupported request default: ${n}`);if(r!==void 0){if(typeof r!=`number`||!Number.isFinite(r))throw Error(`${n} must be a finite number; leave blank to inherit.`);if([`max_tokens`,`top_k`,`seed`].includes(n)&&!Number.isSafeInteger(r))throw Error(`${n} must be a safe integer.`);if(n===`max_tokens`&&r<1||n===`temperature`&&r<0||n===`top_k`&&r<0||[`top_p`,`min_p`].includes(n)&&(r<0||r>1)||n===`repetition_penalty`&&r<=0||n===`seed`&&r<0)throw Error(`${n} is outside its supported range.`);t[n]=r}}return Object.freeze(t)}var sr=ir,cr=new Set;function lr(e){return cr.add(e),()=>cr.delete(e)}function ur(e){sr=or(e);for(let e of cr)e()}function dr(){ur(ir)}function fr(){return{defaults:(0,_.useSyncExternalStore)(lr,()=>sr,()=>ir),setDefaults:ur,reset:dr}}function pr(e,t,n){return e===null||e<=0||t===null||n===void 0?`unknown`:t+n>e?`exceeds`:`raw-fits`}function mr({modelId:e,nCtx:t,locale:n}){let r=rr(),{defaults:i}=fr(),[a,o]=(0,_.useState)(``),[s,c]=(0,_.useState)(null),[l,u]=(0,_.useState)(!1),[d,f]=(0,_.useState)(!1),p=(0,_.useRef)(null);(0,_.useEffect)(()=>()=>p.current?.abort(),[]);let m=async()=>{p.current?.abort();let t=new AbortController;p.current=t,u(!0),f(!1),c(null);try{let n=await r.getTokenCount(e,a,t.signal);t.signal.aborted||c(n)}catch{t.signal.aborted||f(!0)}finally{t.signal.aborted||u(!1)}},h=pr(t,s,i.max_tokens),g=h===`exceeds`?R(n,`settings.context_check.exceeds`):h===`unknown`?R(n,`settings.context_check.unknown`):R(n,`settings.context_check.fits`);return(0,x.jsxs)(`div`,{children:[(0,x.jsx)(ot,{label:R(n,`settings.context_check.label`),value:a,onChange:e=>{p.current?.abort(),u(!1),o(e),c(null)},hint:R(n,`settings.context_check.hint`)}),(0,x.jsx)(N,{disabled:l||a.length===0,onClick:()=>void m(),children:R(n,`settings.context_check.check`)}),(0,x.jsx)(`p`,{role:`status`,children:d?R(n,`settings.context_check.unavailable`):s===null?R(n,`settings.context_check.not_measured`):R(n,`settings.context_check.count`,{count:String(s),verdict:g})})]})}function hr(e){return e instanceof ln?e.status===401?`wrong-key`:e.status===403?`forbidden`:`generic`:e instanceof B||e instanceof Error&&e.name===`ValidationError`?`schema`:e instanceof TypeError||e instanceof Error&&/fetch|network|offline|connection/i.test(e.message)?`offline`:`generic`}var gr=new Set([`ready`,`loading`,`draining`,`unloading`]);function _r(e){return gr.has(e)}function vr(e,t){let n=e=>e.lifecycle.state===`ready`?0:_r(e.lifecycle.state)?1:2;return n(e)-n(t)||e.identity.display_name.localeCompare(t.identity.display_name)||e.identity.id.localeCompare(t.identity.id)}function yr(e){return e.catalog.filter(e=>_r(e.lifecycle.state)).sort(vr)}function br(e,t){return e.catalog.some(e=>e.identity.id===t)?t:null}function xr(e,t){return t.bootstrap===null?R(e,`connection.ready`):R(e,`connection.footer.connected`,{mode:t.bootstrap.server.mode,version:t.bootstrap.server.build.version,status:Cr(e,t.connection)})}function Sr(e,t){if(t.bootstrap===null)return null;let n=R(e,`format.unknown`),r=t.serverInstanceId??t.bootstrap.server.server_instance_id,i=t.lastSequence??t.catalogSequence??t.resourceFences.operationsSnapshot;return{instance:r||n,sequence:i===null?n:String(i)}}function Cr(e,t){return R(e,{idle:`connection.status.idle`,bootstrapping:`connection.status.bootstrapping`,ready:`connection.status.ready`,streaming:`connection.status.streaming`,polling:`connection.status.polling`,offline:`connection.status.offline`,stale:`connection.status.stale`,unauthorized:`connection.status.unauthorized`,forbidden:`connection.status.forbidden`,"schema-mismatch":`connection.status.schema_mismatch`,error:`connection.status.error`}[t])}function wr(e){return e.snapshot.auth.status===`authenticated`?e.snapshot.connection===`schema-mismatch`?(0,x.jsx)(Dr,{...e}):(0,x.jsx)(Er,{...e}):(0,x.jsx)(Tr,{...e})}function Tr(e){return e.authFailure===`schema`?(0,x.jsx)(Dr,{...e}):(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsx)(Ke,{className:`connection-prompt`,title:e.title,titleTestId:e.titleTestId,description:R(e.locale,`connection.prompt.body`),descriptionTestId:z(`connection.prompt.body`)}),(0,x.jsx)(mt,{title:R(e.locale,`state.unauthorized.title`),body:R(e.locale,`state.unauthorized.body`),tokenLabel:R(e.locale,`login.token.label`),tokenHelp:R(e.locale,`login.token.help`),submitLabel:R(e.locale,`login.submit`),logoutLabel:R(e.locale,`login.logout`),error:e.authFailure===null?void 0:Ar(e.locale,e.authFailure),busy:e.snapshot.auth.status===`authenticating`,onSubmit:e.onLogin,onLogout:e.onLogout,testId:z(`auth.login`)})]})}function Er(e){let t=e.snapshot.connection===`offline`||e.snapshot.connection===`stale`||e.snapshot.connection===`error`||e.snapshot.connection===`unauthorized`||e.snapshot.connection===`forbidden`;return(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsx)(Ke,{className:`connection-prompt`,title:e.title,titleTestId:e.titleTestId,description:R(e.locale,`connection.authenticated.body`),descriptionTestId:z(`connection.authenticated.body`)}),(0,x.jsx)(L,{tone:`info`,title:R(e.locale,`connection.authenticated.title`),body:Or(e.locale,e.snapshot),testId:z(`connection.authenticated.detail`)}),t?(0,x.jsx)(L,{title:R(e.locale,`connection.error.title`),body:kr(e.locale,e.snapshot.connection),action:(0,x.jsx)(N,{onClick:e.onRetry,children:R(e.locale,`common.retry`)}),testId:z(`connection.error.title`)}):null]})}function Dr(e){return(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsx)(Ke,{className:`connection-prompt`,title:e.title,titleTestId:e.titleTestId}),(0,x.jsx)(ht,{title:R(e.locale,`state.schema_mismatch.title`),body:R(e.locale,`state.schema_mismatch.body`),actionLabel:R(e.locale,`common.reload`),onRecover:e.onRecoverSchema})]})}function Or(e,t){let n=t.bootstrap;return n===null?R(e,`connection.prompt.detail`):R(e,`connection.authenticated.detail`,{mode:n.server.mode,version:n.server.build.version,status:Cr(e,t.connection),count:t.catalogSequence===null?R(e,`connection.snapshot.pending`):String(t.catalog.length),operations:t.resourceFences.operationsSnapshot===null?R(e,`connection.snapshot.pending`):String(t.operations.size),sequence:Mr(e,t)})}function kr(e,t){return t===`offline`?R(e,`state.offline.body`):t===`stale`?R(e,`connection.error.stale`):t===`forbidden`?R(e,`connection.error.forbidden`):t===`unauthorized`?R(e,`connection.error.unauthorized`):R(e,`connection.error.generic`)}function Ar(e,t){return t===`wrong-key`?R(e,`login.error.wrong_key`):t===`offline`?R(e,`login.error.offline`):t===`forbidden`?R(e,`login.error.forbidden`):t===`schema`?R(e,`login.error.schema`):R(e,`login.error.generic`)}function jr(e,t){return R(e,{unloaded:`models.status.unloaded`,loading:`models.status.loading`,ready:`models.status.ready`,draining:`models.status.draining`,unloading:`models.status.unloading`,failed:`models.status.failed`}[t])}function Mr(e,t){return String(t.lastSequence??t.catalogSequence??t.resourceFences.operationsSnapshot??R(e,`connection.snapshot.pending`))}function Nr({locale:e}){let{defaults:t,setDefaults:n,reset:r}=fr(),[i,a]=(0,_.useState)(()=>Object.fromEntries(Object.entries(t).map(([e,t])=>[e,String(t)]))),[o,s]=(0,_.useState)(``),[c,l]=(0,_.useState)(!1);return(0,x.jsxs)(`section`,{className:`screen-stack`,children:[(0,x.jsx)(`h2`,{children:R(e,`settings.generation.title`)}),(0,x.jsx)(`p`,{children:R(e,`settings.generation.body`)}),(0,x.jsx)(`div`,{className:`settings-grid`,children:ar.map(n=>(0,x.jsx)(ot,{label:n,value:i[n]??``,onChange:e=>a(t=>({...t,[n]:e})),hint:R(e,`settings.generation.current`,{value:t[n]?.toString()??R(e,`settings.generation.inherit`)})},n))}),o?(0,x.jsx)(L,{title:R(e,`settings.generation.error_title`),body:o}):null,(0,x.jsxs)(`div`,{children:[(0,x.jsx)(N,{onClick:()=>{try{n(or(Object.fromEntries(Object.entries(i).filter(([,e])=>e.trim()!==``).map(([e,t])=>[e,Number(t)])))),s(``)}catch(t){s(t instanceof Error?t.message:R(e,`settings.generation.invalid`))}},children:R(e,`settings.generation.save`)}),` `,(0,x.jsx)(N,{onClick:()=>l(!0),children:R(e,`settings.generation.reset_open`)})]}),(0,x.jsx)(ot,{label:R(e,`settings.generation.reasoning_label`),value:R(e,`settings.generation.reasoning_value`),disabled:!0,hint:R(e,`settings.generation.reasoning_hint`)}),(0,x.jsxs)(lt,{open:c,title:R(e,`settings.generation.reset.title`),closeLabel:R(e,`common.close`),onClose:()=>l(!1),children:[(0,x.jsx)(`p`,{children:R(e,`settings.generation.reset.body`)}),(0,x.jsx)(N,{onClick:()=>{r(),a({}),s(``),l(!1)},children:R(e,`settings.generation.reset.confirm`)})]})]})}function Pr({modelId:e,locale:t}){let n=rr(),[r,i]=(0,_.useState)(null),[a,o]=(0,_.useState)({}),[s,c]=(0,_.useState)({}),[l,u]=(0,_.useState)(``),[d,f]=(0,_.useState)(!1),[p,m]=(0,_.useState)(!1),h=(0,_.useRef)(null),g=(0,_.useRef)(t);g.current=t,(0,_.useEffect)(()=>{let t=new AbortController;return h.current=t,f(!0),n.getSettings(e,t.signal).then(e=>{t.signal.aborted||i(e)}).catch(()=>{t.signal.aborted||u(R(g.current,`settings.live.unavailable`))}).finally(()=>{t.signal.aborted||f(!1)}),()=>t.abort()},[n,e]);let v=async()=>{let t=h.current;if(!(t===null||t.signal.aborted)){f(!0);try{let r=await n.getSettings(e,t.signal);t.signal.aborted||(i(r),u(R(g.current,`settings.live.refreshed`)))}catch{t.signal.aborted||u(R(g.current,`settings.live.refresh_failed`))}finally{t.signal.aborted||f(!1)}}},y=async()=>{let s=h.current;if(s===null||s.signal.aborted||r===null)return;let l={},d={};for(let e of r.schema)if(Object.hasOwn(a,e.name))try{l[e.name]=xt(e,a[e.name])}catch(n){d[e.name]=n instanceof Error?n.message:R(t,`settings.live.invalid_value`)}if(c(d),!(Object.keys(d).length>0)){f(!0);try{let t=await n.getSettings(e,s.signal);if(s.signal.aborted)return;if(t.fingerprint!==r.fingerprint){i(t),u(R(g.current,`settings.live.conflict`));return}let a=await n.patchSettings(e,l,s.signal);if(s.signal.aborted)return;c(Object.fromEntries(a.rejected.map(e=>[e.name,e.reason]))),o(e=>Object.fromEntries(Object.entries(e).filter(([e])=>!Object.hasOwn(a.applied,e)))),u(a.rejected.length>0?R(g.current,`settings.live.partial`,{applied:String(Object.keys(a.applied).length),rejected:String(a.rejected.length)}):R(g.current,`settings.live.applied`));let d=await n.getSettings(e,s.signal);s.signal.aborted||i(d)}catch{s.signal.aborted||u(R(g.current,`settings.live.unknown_outcome`))}finally{s.signal.aborted||f(!1)}}},b=(e,n)=>{let r={help:e.help,current:St(e,n),type:e.type};return e.allowed===null?R(t,`settings.live.hint`,r):R(t,`settings.live.hint_allowed`,{...r,allowed:e.allowed.join(`, `)})};return(0,x.jsxs)(`section`,{className:`screen-stack`,children:[(0,x.jsx)(`h2`,{children:R(t,`settings.live.title`)}),(0,x.jsx)(`p`,{children:R(t,`settings.live.body`)}),l?(0,x.jsx)(L,{tone:`warning`,title:R(t,`settings.live.result_title`),body:l}):null,(0,x.jsxs)(`div`,{children:[(0,x.jsx)(N,{onClick:()=>void v(),disabled:d,children:R(t,`settings.live.refresh`)}),` `,(0,x.jsx)(N,{onClick:()=>void y(),disabled:d||Object.keys(a).length===0,children:R(t,`settings.live.apply`)}),` `,(0,x.jsx)(N,{onClick:()=>m(!0),disabled:d||r===null,children:R(t,`settings.live.reset_open`)})]}),r?.schema.filter(e=>e.mutable).map(e=>(0,x.jsx)(ot,{label:e.name,value:a[e.name]??St(e,r.current[e.name]),onChange:t=>o(n=>({...n,[e.name]:t})),disabled:d,error:s[e.name],hint:b(e,r.current[e.name])},e.name)),(0,x.jsxs)(`details`,{children:[(0,x.jsx)(`summary`,{children:R(t,`settings.live.startup`)}),r?.schema.filter(e=>!e.mutable).map(e=>(0,x.jsx)(ot,{label:e.name,value:St(e,r.current[e.name]),disabled:!0,hint:e.reason??e.help},e.name))]}),(0,x.jsxs)(lt,{open:p,title:R(t,`settings.live.reset.title`),closeLabel:R(t,`common.close`),onClose:()=>m(!1),children:[(0,x.jsx)(`p`,{children:R(t,`settings.live.reset.body`)}),(0,x.jsx)(N,{onClick:()=>{r!==null&&o(Object.fromEntries(r.schema.filter(e=>e.mutable).map(e=>[e.name,St(e,e.default)]))),c({}),m(!1)},children:R(t,`settings.live.reset.confirm`)})]})]})}var Fr=[`fp16`,`float16`,`int8`,`i8`,`turbo4-asym`,`fp16+turbo4`,`turbo3-asym`,`fp16+turbo3`,`turbo3`,`turbo4`,`turbo4-sym`,`turbo4-delegated`,`fp16+turbo4-delegated`],Ir=Object.freeze({});function Lr(e){if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Profile must be an object.`);let t={};for(let[n,r]of Object.entries(e)){if(![`ctx_size`,`n_parallel`,`kv_cache_mode`].includes(n))throw Error(`Unsafe or unsupported profile field: ${n}`);if(r!=null){if(n===`kv_cache_mode`){if(typeof r!=`string`||!Fr.includes(r))throw Error(`Unknown KV cache mode.`);t.kv_cache_mode=r}else{if(typeof r!=`number`||!Number.isInteger(r)||r<1||r>(n===`ctx_size`?262144:32))throw Error(`${n} is outside its supported range.`);n===`ctx_size`?t.ctx_size=r:t.n_parallel=r}}}return Object.freeze(t)}function Rr(e){if(e.length>65536)throw Error(`Profile import exceeds 64 KiB.`);let t=JSON.parse(e);if(typeof t!=`object`||!t||Array.isArray(t))throw Error(`Invalid profile document.`);let n=t;if(n.version===0&&Object.keys(n).every(e=>[`version`,`profile`].includes(e)))return{version:1,reusable:Lr(n.profile),models:{}};if(n.version!==1||Object.keys(n).some(e=>![`version`,`reusable`,`models`].includes(e)))throw Error(`Unsupported profile version or fields.`);if(typeof n.models!=`object`||n.models===null||Array.isArray(n.models))throw Error(`Invalid model profiles.`);let r=Object.create(null);if(Object.keys(n.models).length>200)throw Error(`Too many model profiles.`);for(let[e,t]of Object.entries(n.models)){if(!/^mdl_[A-Za-z0-9_-]{43}$/.test(e))throw Error(`Model profiles require opaque catalog IDs.`);r[e]=Lr(t)}return{version:1,reusable:Lr(n.reusable),models:r}}var zr=`mlxcel.webui.load-profiles.v1`,Br={version:1,reusable:Ir,models:{}},Vr=!1,Hr=new Set;function Ur(e){return Hr.add(e),()=>Hr.delete(e)}function Wr(){if(!Vr){Vr=!0;try{let e=localStorage.getItem(zr);e!==null&&(Br=Rr(e))}catch{}}}function Gr(e){let t=JSON.stringify(e),n=Rr(t);localStorage.setItem(zr,t),Br=n;for(let e of Hr)e()}function Kr(e){Wr();let t=(0,_.useSyncExternalStore)(Ur,()=>Br);return{reusable:t.reusable,modelProfile:e===null?Ir:t.models[e]??Ir,profile:e!==null&&Object.hasOwn(t.models,e)?t.models[e]:t.reusable,save:(t,n)=>{let r=Lr(t);if(n===`model`&&e===null)throw Error(`Select a model first.`);Gr(n===`reusable`?{...Br,reusable:r}:{...Br,models:{...Br.models,[e]:r}})},reset:(t=e===null?`reusable`:`model`)=>{let n=Object.fromEntries(Object.entries(Br.models).filter(([t])=>t!==e));Gr(t===`reusable`?{...Br,reusable:Ir}:{...Br,models:n})},exportJson:()=>JSON.stringify(Br,null,2),importJson:e=>Gr(Rr(e))}}function qr(e){let t=Lr(e);return[`mlxcel-server --webui`,t.ctx_size===void 0?``:`--ctx-size ${t.ctx_size}`,t.n_parallel===void 0?``:`--parallel ${t.n_parallel}`,t.kv_cache_mode===void 0?``:`--kv-cache-mode ${t.kv_cache_mode}`].filter(Boolean).join(` `)}function Jr({model:e,locale:t,single:n}){let r=Kr(e?.identity.id??null),[i,a]=(0,_.useState)(r.profile),[o,s]=(0,_.useState)(e===null?`reusable`:`model`),[c,l]=(0,_.useState)(``),[u,d]=(0,_.useState)(``),[f,p]=(0,_.useState)(!1),m=o===`reusable`?r.reusable:r.modelProfile;(0,_.useEffect)(()=>{a(m)},[m]);let h=e=>{try{e(),d(R(t,`settings.profile.saved`))}catch(e){d(e instanceof Error?e.message:R(t,`settings.profile.failed`))}};return(0,x.jsxs)(`section`,{className:`screen-stack`,children:[(0,x.jsx)(`h2`,{children:R(t,`settings.profile.title`)}),(0,x.jsx)(`p`,{children:R(t,`settings.profile.body`)}),n?(0,x.jsx)(L,{tone:`info`,title:R(t,`settings.profile.single.title`),body:R(t,`settings.profile.single.body`)}):null,(0,x.jsx)(je,{locale:t,label:R(t,`settings.profile.scope`),value:o,onChange:e=>s(e),options:[{value:`reusable`,label:R(t,`settings.profile.scope.reusable`)},...e===null?[]:[{value:`model`,label:e.identity.display_name}]]}),(0,x.jsxs)(`div`,{className:`settings-grid`,children:[(0,x.jsx)(ot,{label:`ctx_size (1–262144)`,value:i.ctx_size?.toString()??``,onChange:e=>a({...i,ctx_size:e.trim()===``?void 0:Number(e)}),hint:R(t,`settings.profile.ctx_hint`)}),(0,x.jsx)(ot,{label:`n_parallel (1–32)`,value:i.n_parallel?.toString()??``,onChange:e=>a({...i,n_parallel:e.trim()===``?void 0:Number(e)}),hint:R(t,`settings.profile.parallel_hint`)}),(0,x.jsx)(je,{locale:t,label:`kv_cache_mode`,value:i.kv_cache_mode??``,onChange:e=>a({...i,kv_cache_mode:e===``?void 0:e}),options:[{value:``,label:R(t,`settings.profile.inherit`)},...Fr.map(e=>({value:e,label:e}))]})]}),(0,x.jsx)(`p`,{children:R(t,`settings.profile.restrictions`)}),u?(0,x.jsx)(L,{tone:`info`,title:R(t,`settings.profile.result_title`),body:u}):null,(0,x.jsxs)(`div`,{children:[(0,x.jsx)(N,{onClick:()=>h(()=>r.save(Lr(i),o)),children:R(t,`settings.profile.save`)}),` `,(0,x.jsx)(N,{onClick:()=>{a(m),d(``)},children:R(t,`settings.profile.discard`)}),` `,(0,x.jsx)(N,{onClick:()=>p(!0),children:R(t,`settings.profile.reset_open`)})]}),(0,x.jsxs)(`p`,{children:[R(t,`settings.profile.saved_pending`),`: `,(0,x.jsx)(`code`,{children:JSON.stringify(m)})]}),(0,x.jsx)(`p`,{children:R(t,`settings.profile.cli`)}),(0,x.jsx)(`code`,{children:qr(m)}),(0,x.jsxs)(`details`,{children:[(0,x.jsx)(`summary`,{children:R(t,`settings.profile.transfer`)}),(0,x.jsxs)(`label`,{className:`ds-field`,children:[(0,x.jsx)(`span`,{children:R(t,`settings.profile.transfer.label`)}),(0,x.jsx)(`textarea`,{value:c,onChange:e=>l(e.currentTarget.value),maxLength:65536,rows:6})]}),(0,x.jsx)(N,{onClick:()=>l(r.exportJson()),children:R(t,`settings.profile.transfer.export`)}),` `,(0,x.jsx)(N,{onClick:()=>h(()=>r.importJson(c)),children:R(t,`settings.profile.transfer.import`)})]}),(0,x.jsxs)(lt,{open:f,title:R(t,`settings.profile.reset.title`),closeLabel:R(t,`common.close`),onClose:()=>p(!1),children:[(0,x.jsx)(`p`,{children:R(t,`settings.profile.reset.body`)}),(0,x.jsx)(N,{onClick:()=>{h(()=>r.reset(o)),p(!1)},children:R(t,`settings.profile.reset.confirm`)})]})]})}function Yr({locale:e}){let t=nr(),n=rr(),r=t.catalog.find(e=>e.identity.id===t.selectedModelId)??null,[i,a]=(0,_.useState)(null),o=t.auth.status===`authenticated`&&[`ready`,`streaming`,`polling`].includes(t.connection),s=o&&r?.lifecycle.state===`ready`?r.identity.id:null;(0,_.useEffect)(()=>{if(a(null),s===null)return;let e=new AbortController;return n.getModelProps(s,e.signal).then(t=>{e.signal.aborted||a(t)}).catch(()=>void 0),()=>e.abort()},[n,s,r?.identity.revision]);let c=R(e,`settings.server.unknown`);return(0,x.jsxs)(`div`,{className:`screen-stack settings-sections`,children:[(0,x.jsxs)(`section`,{className:`screen-stack`,children:[(0,x.jsx)(`h2`,{children:R(e,`settings.server.privacy.title`)}),(0,x.jsx)(`p`,{children:R(e,`settings.server.privacy.body`)})]}),(0,x.jsx)(Nr,{locale:e}),o?(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(je,{locale:e,label:R(e,`settings.server.model`),value:t.selectedModelId??``,options:[{value:``,label:R(e,`settings.server.model.none`)},...t.catalog.map(t=>({value:t.identity.id,label:`${t.identity.display_name} · ${jr(e,t.lifecycle.state)}`}))],onChange:e=>n.selectModel(e===``?null:e),hint:R(e,`settings.server.model.hint`),testId:`settings-model-selector`}),(0,x.jsx)(Jr,{model:r,locale:e,single:t.bootstrap?.server.mode===`single_model`},r?.identity.id??`reusable`),(0,x.jsxs)(`section`,{className:`screen-stack`,children:[(0,x.jsx)(`h2`,{children:R(e,`settings.server.context.title`)}),(0,x.jsx)(ot,{label:R(e,`settings.server.context.n_ctx`),value:i?.nCtx?.toString()??c,disabled:!0,hint:R(e,`settings.server.context.n_ctx_hint`)}),(0,x.jsx)(ot,{label:R(e,`settings.server.context.slots`),value:i?.totalSlots?.toString()??c,disabled:!0}),(0,x.jsx)(ot,{label:R(e,`settings.server.context.kv_mode`),value:i?.kvCacheMode??c,disabled:!0}),(0,x.jsxs)(`p`,{children:[R(e,`settings.server.context.geometry`),`: `,(0,x.jsx)(`code`,{children:i?.geometry===null||i===null?R(e,`settings.server.context.geometry_unknown`):JSON.stringify(i.geometry)})]}),s===null?null:(0,x.jsx)(mr,{modelId:s,nCtx:i?.nCtx??null,locale:e},s)]}),s===null?(0,x.jsx)(L,{tone:`info`,title:R(e,`settings.server.no_model.title`),body:R(e,`settings.server.no_model.body`)}):t.bootstrap?.features.includes(`settings`)===!0?(0,x.jsx)(Pr,{modelId:s,locale:e},s):(0,x.jsx)(L,{tone:`info`,title:R(e,`settings.server.live_disabled.title`),body:R(e,`settings.server.live_disabled.body`)})]}):(0,x.jsx)(L,{tone:`warning`,title:R(e,`settings.server.unavailable.title`),body:R(e,`settings.server.unavailable.body`)})]})}var Xr=[{id:`models`,key:`nav.models`,testId:`command-route-models`},{id:`chat`,key:`nav.chat`,testId:`command-route-chat`},{id:`activity`,key:`nav.activity`,testId:`command-route-activity`},{id:`settings`,key:`nav.settings`,testId:`command-route-settings`},{id:`new-chat`,key:`chat.new_conversation`,testId:`command-new-chat`}];function Zr(e,t,n=20){let r=t.trim().toLowerCase();return r===``?[]:e.filter(e=>e.identity.display_name.toLowerCase().includes(r)||e.identity.id.toLowerCase().includes(r)).sort(vr).slice(0,Math.max(0,n))}function Qr(e){let[t,n]=(0,_.useState)(``),[r,i]=(0,_.useState)(e.open),a=(0,_.useId)(),o=(0,_.useId)();e.open!==r&&(i(e.open),n(``));let s=t.trim().toLowerCase(),c=Xr.filter(t=>s===``||t.id.includes(s)||R(e.locale,t.key).toLowerCase().includes(s)),l=s===``?e.loaded:Zr(e.catalog,s),u=t=>{t.id===`new-chat`?e.onNewChat():e.onNavigate(t.id)};return(0,x.jsxs)(lt,{open:e.open,title:R(e.locale,`command.title`),onClose:e.onClose,testId:`command-dialog`,closeLabel:R(e.locale,`common.close`),children:[(0,x.jsx)(ot,{label:R(e.locale,`command.search`),value:t,onChange:n,testId:z(`command.search`)}),c.length===0&&l.length===0?(0,x.jsx)(`p`,{"data-testid":z(`command.no_results`),children:R(e.locale,`command.no_results`)}):null,c.length>0?(0,x.jsxs)(`div`,{className:`command-section`,role:`group`,"aria-labelledby":a,children:[(0,x.jsx)(`h3`,{id:a,children:R(e.locale,`command.section.commands`)}),(0,x.jsx)(`div`,{className:`command-list`,children:c.map(t=>(0,x.jsx)(N,{"data-testid":t.testId,onClick:()=>u(t),children:R(e.locale,t.key)},t.id))})]}):null,l.length>0?(0,x.jsxs)(`div`,{className:`command-section`,role:`group`,"aria-labelledby":o,children:[(0,x.jsx)(`h3`,{id:o,children:R(e.locale,`command.section.models`)}),(0,x.jsx)(`div`,{className:`command-list`,children:l.map(t=>(0,x.jsx)(N,{className:`command-model`,title:t.identity.display_name,"data-testid":`command-model`,onClick:()=>e.onOpenModel(t.identity.id),children:`${t.identity.display_name} · ${jr(e.locale,t.lifecycle.state)}`},t.identity.id))})]}):null]})}var $r=[{id:`models`,key:`nav.models`,icon:`models`},{id:`chat`,key:`nav.chat`,icon:`chat`},{id:`activity`,key:`nav.activity`,icon:`activity`},{id:`settings`,key:`nav.settings`,icon:`settings`}],ei=[{id:`command`,keys:[`⌘/Ctrl`,`K`],separator:`+`,key:`help.shortcut.command`},{id:`new-chat`,keys:[`⌘/Ctrl`,`N`],separator:`+`,key:`help.shortcut.new_chat`},{id:`send`,keys:[`⌘/Ctrl`,`Enter`],separator:`+`,key:`help.shortcut.send`},{id:`escape`,keys:[`Esc`],separator:`+`,key:`help.shortcut.escape`},{id:`navigate`,keys:[`[`,`]`],separator:`/`,key:`help.shortcut.navigate`},{id:`help`,keys:[`?`],separator:`+`,key:`help.shortcut.help`}];function ti(e){let t=(0,_.useRef)(null),n=(0,_.useRef)(e.onCommand),r=(0,_.useRef)(e.onHelp),i=(0,_.useRef)(e.onNewChat),[a,o]=(0,_.useState)(!1);(0,_.useEffect)(()=>{n.current=e.onCommand,r.current=e.onHelp,i.current=e.onNewChat},[e.onCommand,e.onHelp,e.onNewChat]),(0,_.useEffect)(()=>{let e=e=>{let t=e.target,a=t instanceof HTMLElement&&(t.isContentEditable||!!t.closest(`[role="combobox"], [role="listbox"]`)||[`INPUT`,`TEXTAREA`,`SELECT`].includes(t.tagName)),s=t instanceof HTMLElement&&!!t.closest(`dialog[open], [role="dialog"][aria-modal="true"]`);if(e.isComposing||e.altKey||a||s)return;let c=e.metaKey||e.ctrlKey;if(c&&e.key.toLowerCase()===`k`&&(e.preventDefault(),o(!1),n.current()),c&&!e.shiftKey&&e.key.toLowerCase()===`n`){if(e.preventDefault(),e.repeat)return;o(!1),i.current()}(e.key===`?`||e.key===`/`&&e.shiftKey)&&(e.preventDefault(),o(!1),r.current())};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[]),(0,_.useEffect)(()=>{if(!a||typeof window.matchMedia!=`function`)return;let e=window.matchMedia(`(max-width: 960px)`),n=()=>{e.matches||(o(!1),requestAnimationFrame(()=>{let e=document.activeElement;if(e&&e!==document.body&&!e.closest(`[aria-modal="true"]`))return;let n=t.current;(n?.querySelector(`a[aria-current="page"]`)??n?.querySelector(`a`))?.focus()}))};return e.addEventListener(`change`,n),()=>e.removeEventListener(`change`,n)},[a]);let s=n=>{let r=$r[($r.findIndex(t=>t.id===e.route)+n+$r.length)%$r.length];e.onRouteChange(r.id),requestAnimationFrame(()=>t.current?.querySelector(`a[href="#${r.id}"]`)?.focus())},c=e=>{(e.key===`[`||e.key===`]`)&&(e.altKey||e.metaKey||e.ctrlKey||e.nativeEvent.isComposing||(e.preventDefault(),s(e.key===`]`?1:-1)))},l=t=>{e.onRouteChange(t),o(!1)};return(0,x.jsxs)(`div`,{className:`app-shell`,children:[(0,x.jsx)(ii,{locale:e.locale,route:e.route,onRouteChange:l,onKeyDown:c,ref:t,className:`app-sidebar desktop-sidebar material-glass`,connection:e.connection}),(0,x.jsx)(Le,{open:a,title:R(e.locale,`nav.primary`),onClose:()=>o(!1),closeLabel:R(e.locale,`common.close`),testId:`mobile-nav-sheet`,children:(0,x.jsx)(ii,{locale:e.locale,route:e.route,onRouteChange:l,onKeyDown:c,className:`app-sidebar sheet-sidebar`,connection:e.connection})}),(0,x.jsxs)(`main`,{className:`app-main`,"aria-labelledby":`app-title`,inert:a,children:[(0,x.jsxs)(`header`,{className:`app-toolbar material-glass`,children:[(0,x.jsx)(P,{className:`mobile-menu-button`,label:R(e.locale,`toolbar.menu`),icon:`menu`,onClick:()=>o(!0),"data-testid":z(`toolbar.menu`)}),(0,x.jsxs)(`div`,{className:`toolbar-title`,children:[(0,x.jsx)(`p`,{id:`app-title`,title:R(e.locale,`app.title`),"data-testid":z(`app.title`),children:R(e.locale,`app.title`)}),(0,x.jsx)(`span`,{title:R(e.locale,`app.subtitle`),"data-testid":z(`app.subtitle`),children:R(e.locale,`app.subtitle`)})]}),(0,x.jsx)(ni,{locale:e.locale,models:e.loadedModels,onOpenModel:e.onOpenModel,onMore:e.onCommand}),(0,x.jsxs)(`div`,{className:`toolbar-actions`,children:[e.sessionAction,(0,x.jsx)(P,{label:R(e.locale,`toolbar.command`),icon:`command`,onClick:e.onCommand,"data-testid":z(`toolbar.command`)}),(0,x.jsx)(P,{label:R(e.locale,`toolbar.help`),icon:`help`,onClick:e.onHelp,"data-testid":z(`toolbar.help`)})]})]}),(0,x.jsxs)(`div`,{className:`app-content-grid ${e.inspector?`has-inspector`:``}`.trim(),children:[(0,x.jsx)(Ge,{className:`app-content`,children:e.children}),e.inspector]})]})]})}function ni(e){let t=e.models??[],n=t.slice(0,3),r=t.length-n.length,i=e.models===null?`toolbar.loaded.unknown`:t.length===0?`toolbar.loaded.none`:null;return(0,x.jsx)(`div`,{className:`toolbar-loaded`,role:`group`,"aria-label":R(e.locale,`toolbar.loaded.label`),"data-testid":z(`toolbar.loaded.label`),onFocus:ri,children:i===null?(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(`span`,{className:`toolbar-loaded-count`,"data-testid":z(`toolbar.loaded.count`),children:R(e.locale,`toolbar.loaded.count`,{count:String(t.length)})}),n.map(t=>(0,x.jsxs)(N,{tone:`ghost`,className:`toolbar-chip`,title:t.name,"data-testid":`toolbar-loaded-chip`,onClick:()=>e.onOpenModel(t.id),children:[(0,x.jsx)(`span`,{className:`truncate`,children:t.name}),(0,x.jsx)(de,{state:t.state,children:t.stateLabel})]},t.id)),r>0?(0,x.jsx)(N,{tone:`ghost`,className:`toolbar-chip toolbar-chip-more`,"aria-label":R(e.locale,`toolbar.loaded.more_label`,{count:String(r)}),"data-testid":z(`toolbar.loaded.more`),onClick:e.onMore,children:R(e.locale,`toolbar.loaded.more`,{count:String(r)})}):null]}):(0,x.jsx)(`span`,{className:`toolbar-loaded-count`,"data-testid":z(i),children:R(e.locale,i)})})}function ri(e){let t=e.target;t instanceof HTMLElement&&typeof t.scrollIntoView==`function`&&t.matches(`:focus-visible`)&&t.scrollIntoView({block:`nearest`,inline:`nearest`})}var ii=_.forwardRef((e,t)=>(0,x.jsxs)(`aside`,{className:e.className,"aria-label":R(e.locale,`nav.primary`),onKeyDown:e.onKeyDown,ref:t,tabIndex:-1,children:[(0,x.jsxs)(`a`,{className:`brand-mark`,href:`#models`,"aria-label":R(e.locale,`nav.home`),onClick:t=>{t.preventDefault(),e.onRouteChange(`models`)},children:[(0,x.jsx)(`span`,{className:`brand-symbol`,"aria-hidden":`true`,children:`mx`}),(0,x.jsx)(`span`,{className:`brand-name`,children:`mlxcel`})]}),(0,x.jsx)(`nav`,{className:`app-nav`,children:$r.map(t=>(0,x.jsxs)(`a`,{href:`#${t.id}`,"aria-label":R(e.locale,t.key),"aria-current":e.route===t.id?`page`:void 0,"data-testid":z(t.key),onClick:n=>{n.preventDefault(),e.onRouteChange(t.id)},children:[(0,x.jsx)(C,{name:t.icon}),(0,x.jsx)(`span`,{className:`app-nav-label`,children:R(e.locale,t.key)})]},t.id))}),(0,x.jsxs)(`footer`,{children:[(0,x.jsxs)(`div`,{className:`connection-status`,children:[(0,x.jsx)(`span`,{className:`connection-dot`,"data-state":e.connection.state,"aria-hidden":`true`}),(0,x.jsx)(`span`,{"data-testid":z(`connection.ready`),children:e.connection.label})]}),e.connection.details?(0,x.jsxs)(`details`,{className:`connection-details`,"data-testid":z(`connection.footer.details`),children:[(0,x.jsx)(`summary`,{children:R(e.locale,`connection.footer.details`)}),(0,x.jsx)(`p`,{"data-testid":z(`connection.footer.instance`),children:R(e.locale,`connection.footer.instance`,{id:e.connection.details.instance})}),(0,x.jsx)(`p`,{"data-testid":z(`connection.footer.sequence`),children:R(e.locale,`connection.footer.sequence`,{sequence:e.connection.details.sequence})})]}):null]})]}));ii.displayName=`Sidebar`;var ai=[`mlxcel`,`glass`],oi=[`light`,`dark`],si=[`system`,`light`,`dark`],ci=`mlxcel`,li=`system`;ai.flatMap(e=>oi.map(t=>`${e}-${t}`));var ui=`(prefers-color-scheme: dark)`;function di(e){return typeof e==`string`&&ai.includes(e)}function fi(e){return typeof e==`string`&&si.includes(e)}function pi(e,t){return`${e}-${t}`}function mi(){try{return typeof window>`u`||typeof window.matchMedia!=`function`?`light`:window.matchMedia(`(prefers-color-scheme: dark)`).matches?`dark`:`light`}catch{return`light`}}function hi(e,t=mi()){return e===`system`?t:e}function gi(e,t,n=mi()){let r=hi(t,n);return{id:pi(e,r),family:e,scheme:r,preference:t}}function _i(e){if(typeof window>`u`||typeof window.matchMedia!=`function`)return()=>void 0;let t;try{t=window.matchMedia(ui)}catch{return()=>void 0}let n=t=>e(t.matches?`dark`:`light`);return t.addEventListener(`change`,n),()=>t.removeEventListener(`change`,n)}var vi={themeFamily:ci,colorScheme:li,material:`glass`,glassIntensity:35,reduceMotion:!1,reduceTransparency:!1,highContrast:`system`,locale:`en`},yi=`mlxcel.webui.appearance`;function bi(e){let t=typeof e==`number`&&Number.isFinite(e)?e:vi.glassIntensity;return Math.max(0,Math.min(100,Math.round(t)))}function xi(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Si(e){return e===`glass`||e===`tinted`||e===`opaque`}function Ci(e){return e===`system`||e===`on`||e===`off`}function wi(e){return Ci(e)?e:e===!0?`on`:e===!1?`off`:vi.highContrast}function Ti(e){return fi(e.colorScheme)?e.colorScheme:e.colorScheme===void 0&&fi(e.theme)?e.theme:vi.colorScheme}function Ei(e){return e===`en`||e===`ko`}function Di(){if(typeof window>`u`)return vi;let e;try{e=window.localStorage.getItem(yi)}catch{return vi}if(!e)return vi;try{let t=JSON.parse(e);return xi(t)?{themeFamily:di(t.themeFamily)?t.themeFamily:vi.themeFamily,colorScheme:Ti(t),material:Si(t.material)?t.material:vi.material,glassIntensity:bi(t.glassIntensity),reduceMotion:t.reduceMotion===!0,reduceTransparency:t.reduceTransparency===!0,highContrast:wi(t.highContrast),locale:Ei(t.locale)?t.locale:vi.locale}:vi}catch{return vi}}function Oi(e){try{window.localStorage.setItem(yi,JSON.stringify(e))}catch{}}function ki(){return typeof CSS>`u`||typeof CSS.supports!=`function`?!1:CSS.supports(`backdrop-filter: blur(1px)`)||CSS.supports(`-webkit-backdrop-filter: blur(1px)`)}function Ai(e,t,n=mi()){let r=gi(t.themeFamily,t.colorScheme,n);e.dataset.theme=r.id,e.dataset.themeFamily=r.family,e.dataset.colorScheme=r.preference,e.dataset.material=t.reduceTransparency?`opaque`:t.material,e.dataset.glassIntensity=String(bi(t.glassIntensity)),e.dataset.reduceMotion=String(t.reduceMotion),e.dataset.reduceTransparency=String(t.reduceTransparency),e.dataset.highContrast=t.highContrast,e.dataset.backdropFilter=ki()?`supported`:`unsupported`,e.lang=t.locale}function ji(e){return e.value===null||!Number.isFinite(e.value)?`N/A`:`${new Intl.NumberFormat(void 0,{maximumFractionDigits:2}).format(e.value)} ${e.unit}`}function Mi(e){let t=e.progress;return!t.indeterminate&&t.total_bytes!==null&&t.total_bytes>0?Math.min(100,100*t.completed_bytes/t.total_bytes):void 0}function Ni(e){let t=e.selectedModelId===null?void 0:e.runtimes.get(e.selectedModelId);return JSON.stringify({format:`mlxcel-webui-diagnostics-v1`,connection:e.connection,last_successful_at:e.lastSuccessfulAt,operation_counts:Object.fromEntries([`queued`,`running`,`cancelling`,`succeeded`,`failed`,`cancelled`].map(t=>[t,[...e.operations.values()].filter(e=>e.state===t).length])),catalog_count:e.catalog.length,runtime_present:t!==void 0,history_samples:e.runtimeHistory.length,measurements:t===void 0?[]:Object.values(t.measurements).map(e=>({value:e.value,available:e.value!==null}))},null,2)}function Pi(e){let t=URL.createObjectURL(new Blob([Ni(e)],{type:`application/json`})),n=document.createElement(`a`);n.href=t,n.download=`mlxcel-diagnostics.json`,n.click(),URL.revokeObjectURL(t)}function Fi({operations:e,locale:t,stale:n}){let r=[...e.values()].sort((e,t)=>Number(bn(e))-Number(bn(t))||t.updated_at.localeCompare(e.updated_at));return(0,x.jsxs)(`section`,{"aria-label":R(t,`activity.operations`),children:[(0,x.jsx)(`h2`,{children:R(t,`activity.operations`)}),(0,x.jsx)(`p`,{role:`status`,"aria-live":`polite`,children:R(t,`activity.operations.counts`,{active:String(r.filter(e=>!bn(e)).length),failed:String(r.filter(e=>e.state===`failed`).length)})}),(0,x.jsx)(`p`,{children:R(t,`activity.session`)}),(0,x.jsx)(Je,{animate:r.some(e=>!bn(e)),children:r.length===0?(0,x.jsx)(pe,{title:R(t,`activity.operations.empty.title`),body:R(t,`activity.operations.empty.body`)}):(0,x.jsx)(`ol`,{className:`activity-operations`,children:r.map(e=>(0,x.jsx)(`li`,{children:(0,x.jsx)(Ii,{operation:e,locale:t,stale:n})},e.operation_id))})})]})}function Ii({operation:e,locale:t,stale:n}){let r=rr(),i=nr(),a=e.target,o=a.target_kind===`model`?i.catalog.find(e=>e.identity.id===a.model_id)?.identity.display_name??a.model_id:a.target_kind===`download`?a.repo_id:a.target_kind,[s,c]=(0,_.useState)(!1),[l,u]=(0,_.useState)(!1),d=bn(e),f=async()=>{c(!0),u(!1);try{await r.cancelOperation(e.operation_id)}catch{u(!0)}finally{c(!1)}};return(0,x.jsxs)(`article`,{className:`activity-operation`,children:[(0,x.jsxs)(`header`,{children:[(0,x.jsx)(`strong`,{children:e.kind.replaceAll(`_`,` `)}),(0,x.jsx)(de,{state:e.state===`failed`?`failed`:d?`unloaded`:e.state===`cancelling`?`draining`:`loading`,label:R(t,`activity.status`),children:e.state})]}),(0,x.jsx)(`p`,{children:o}),(0,x.jsx)(`p`,{children:(0,x.jsx)(`time`,{dateTime:e.updated_at,children:new Date(e.updated_at).toLocaleString(t)})}),!d&&e.kind===`download`?(0,x.jsx)(fe,{label:R(t,`activity.bytes`),value:Mi(e),detail:R(t,`activity.download_progress`,{completed:e.progress.completed_bytes.toLocaleString(t),total:e.progress.total_bytes?.toLocaleString(t)??R(t,`activity.not_available`)})}):null,e.state===`cancelling`?(0,x.jsx)(`p`,{role:`status`,children:R(t,`activity.cancelling`)}):null,e.state===`failed`?(0,x.jsx)(L,{title:R(t,`activity.failure`),body:e.error?.code??`operation_failed`}):null,(0,x.jsxs)(`details`,{children:[(0,x.jsx)(`summary`,{children:R(t,`activity.details`)}),(0,x.jsx)(`p`,{children:e.operation_id}),(0,x.jsx)(`p`,{children:e.target.target_kind===`model`?e.target.model_id:e.target.target_kind})]}),!d&&e.state!==`cancelling`?e.cancellable?(0,x.jsx)(N,{disabled:n,busy:s,onClick:()=>{f()},children:R(t,`activity.cancel`)}):(0,x.jsx)(`p`,{children:R(t,`activity.cancel_unsupported`)}):null,l?(0,x.jsx)(L,{title:R(t,`activity.cancel_failed`),body:R(t,`activity.refresh`)}):null]})}var Li=new Set(Oe.map(e=>e.key).filter(e=>e.startsWith(`activity.metric.`))),Ri=e=>Li.has(e);function zi({runtime:e,locale:t,stale:n=!1}){if(e===void 0)return(0,x.jsx)(pe,{title:R(t,`activity.runtime`),body:R(t,`activity.unavailable`)});let r=Object.entries(e.measurements),i=new Set([`active_requests`,`queued_requests`,`completed_requests_total`,`completion_tokens_total`]),a=r.filter(([e,t])=>i.has(e)&&t.value!==null&&Number.isFinite(t.value)),o=r.filter(([,e])=>e.value===null||!Number.isFinite(e.value)).length,s=e=>{let n=`activity.metric.${e}`;return Ri(n)?R(t,n):e.replaceAll(`_`,` `)},c=R(t,`activity.not_available`);return(0,x.jsxs)(`section`,{"aria-label":R(t,`activity.runtime`),children:[(0,x.jsx)(`h2`,{children:R(t,`activity.runtime`)}),n?(0,x.jsx)(L,{tone:`warning`,title:R(t,`activity.stale`),body:R(t,`activity.observed`)}):null,(0,x.jsx)(`div`,{className:`activity-metrics activity-metrics--summary`,"data-testid":`runtime-summary`,children:a.map(([e,t])=>(0,x.jsx)(it,{className:`activity-metric`,label:s(e),value:ji(t)},e))}),a.length===0?(0,x.jsx)(`p`,{children:R(t,`activity.no_primary`)}):null,o>0?(0,x.jsxs)(`p`,{children:[R(t,`activity.unavailable_count`),`: `,o,`. `,R(t,`activity.unavailable_reason`)]}):null,(0,x.jsx)(`h3`,{children:R(t,`activity.slots`)}),(0,x.jsxs)(`p`,{children:[R(t,`activity.parallel`),`: `,e.slots.effective_parallelism??c,` / `,e.slots.configured_parallelism]}),(0,x.jsx)(`p`,{children:R(t,`activity.context_line`,{context:R(t,`activity.context`),request:e.slots.request_context_tokens?.toString()??c,pool:R(t,`activity.pool`),shared:e.slots.shared_pool_context_tokens?.toString()??c})}),e.slots.reason===null?null:(0,x.jsx)(`p`,{children:e.slots.reason}),(0,x.jsxs)(`p`,{children:[R(t,`activity.observed`),`: `,e.slots.measured_at===null?R(t,`activity.unknown_time`):new Date(e.slots.measured_at).toLocaleString(t)]}),e.slots.available?e.slots.items.map(n=>(0,x.jsxs)(`section`,{"aria-label":`${R(t,`activity.slot`)} ${n.id}`,children:[(0,x.jsxs)(`h4`,{children:[R(t,`activity.slot`),` `,n.id,` · `,n.processing?R(t,`activity.processing`):R(t,`activity.idle`)]}),n.prompt_tokens!==null&&e.slots.request_context_tokens!==null&&e.slots.request_context_tokens>0?(0,x.jsx)(fe,{label:`${R(t,`activity.slot`)} ${n.id} ${R(t,`activity.context`)}`,value:n.prompt_tokens/e.slots.request_context_tokens*100,detail:R(t,`activity.slot_progress`,{used:String(n.prompt_tokens),total:String(e.slots.request_context_tokens)})}):(0,x.jsx)(`p`,{children:R(t,`activity.no_context`)}),(0,x.jsx)(`p`,{children:R(t,`activity.slot_tokens`,{decoded:n.decoded_tokens?.toString()??c,cached:n.cached_prompt_tokens?.toString()??c})})]},n.id)):e.slots.reason===null?(0,x.jsx)(`p`,{children:R(t,`activity.unavailable`)}):null,(0,x.jsxs)(`details`,{className:`activity-measurement-details`,children:[(0,x.jsx)(`summary`,{children:R(t,`activity.metric_details`)}),(0,x.jsx)(`p`,{children:R(t,`activity.memory`)}),(0,x.jsx)(`p`,{children:R(t,`activity.timing`)}),(0,x.jsx)(`div`,{className:`activity-metrics`,children:r.map(([e,n])=>(0,x.jsx)(it,{className:`activity-metric`,label:s(e),value:ji(n),hint:(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(`p`,{children:[R(t,`activity.scope`),`: `,n.scope]}),(0,x.jsxs)(`p`,{children:[R(t,`activity.observed`),`: `,n.measured_at===null?R(t,`activity.unknown_time`):new Date(n.measured_at).toLocaleString(t)]}),n.reason===null?null:(0,x.jsx)(`p`,{children:n.reason})]})},e))})]})]})}var Bi=(function(){let e=typeof document<`u`&&document.createElement(`link`).relList;return e&&e.supports&&e.supports(`modulepreload`)?`modulepreload`:`preload`})(),Vi=function(e,t){return new URL(e,t).href},Hi={},Ui=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function s(e){return import.meta.resolve?import.meta.resolve(e):new URL(e,import.meta.url).href}r=o(t.map(t=>{if(t=Vi(t,n),t=s(t),t in Hi)return;Hi[t]=!0;let r=t.endsWith(`.css`);for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}let i=document.createElement(`link`);if(i.rel=r?`stylesheet`:Bi,r||(i.as=`script`),i.crossOrigin=``,i.href=t,a&&i.setAttribute(`nonce`,a),document.head.appendChild(i),r)return new Promise((e,n)=>{i.addEventListener(`load`,e),i.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}).filter(e=>e!==void 0))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},Wi=(0,_.lazy)(()=>Ui(()=>import(`./history-BBsc_X23.js`),[],import.meta.url));function Gi({locale:e}){let t=nr(),n=rr(),[r,i]=(0,_.useState)(!1),a=![`ready`,`streaming`,`polling`].includes(t.connection),o=t.runtimeHistory.at(-1)?.receivedAt??null,s=a||o===null||t.lastUpdatedAt!==null&&t.lastUpdatedAt-o>4e3,c=t.selectedModelId===null?void 0:t.runtimes.get(t.selectedModelId);return(0,x.jsxs)(`div`,{className:`screen-stack`,"data-testid":`activity-page`,children:[(0,x.jsx)(Ke,{title:R(e,`activity.title`),titleTestId:z(`activity.title`),description:R(e,`activity.intro`),actions:(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(N,{onClick:()=>{n.refresh()},"data-testid":z(`activity.refresh`),children:R(e,`activity.refresh`)}),(0,x.jsx)(N,{onClick:()=>Pi(t),"data-testid":z(`activity.export`),children:R(e,`activity.export`)})]}),error:a?R(e,`activity.stale`):null,errorTestId:z(`activity.stale`),onRetry:()=>{n.refresh()},retryLabel:R(e,`activity.refresh`)}),(0,x.jsxs)(`p`,{className:`activity-updated`,children:[R(e,`activity.updated`),`: `,t.lastSuccessfulAt===null?R(e,`activity.pending`):(0,x.jsx)(`time`,{children:new Date(t.lastSuccessfulAt).toLocaleString(e)})]}),(0,x.jsx)(je,{locale:e,label:R(e,`activity.select`),value:t.selectedModelId??``,onChange:e=>n.selectModel(e||null),options:[{value:``,label:R(e,`activity.select`)},...t.catalog.map(e=>({value:e.identity.id,label:e.identity.display_name}))]}),(0,x.jsx)(Fi,{operations:t.operations,locale:e,stale:a}),t.selectedModelId===null?(0,x.jsx)(pe,{title:R(e,`activity.select`),body:R(e,`activity.select_body`)}):(0,x.jsx)(zi,{runtime:c,locale:e,stale:s}),(0,x.jsx)(N,{onClick:()=>i(!r),children:r?R(e,`activity.history.hide`):R(e,`activity.history.show`)}),r?(0,x.jsx)(_.Suspense,{fallback:(0,x.jsx)(`p`,{children:R(e,`activity.pending`)}),children:(0,x.jsx)(Wi,{samples:t.runtimeHistory,locale:e})}):null]})}var Ki=e=>[`succeeded`,`failed`,`cancelled`].includes(e.state),qi=e=>e.auth.status===`authenticated`&&e.bootstrap!==null&&e.catalogSequence!==null&&[`ready`,`streaming`,`polling`].includes(e.connection);function Ji(e,t){return qi(e)&&e.bootstrap?.actions[t]?.state===`enabled`}function Yi(e,t){return[...e.operations.values()].some(e=>!Ki(e)&&e.target.target_kind===`model`&&(e.target.model_id===t||e.target.eviction_target_id===t))||[...e.pendingReconciliations.values()].some(e=>e.modelId===t)}function Xi(e,t){return Ji(e,`load`)&&t.supported&&t.complete&&t.metadata.support.runnable_on_backend&&!t.lifecycle.busy&&[`unloaded`,`failed`].includes(t.lifecycle.state)&&!Yi(e,t.identity.id)}function Zi(e,t){return Ji(e,`unload`)&&t.lifecycle.state===`ready`&&!Yi(e,t.identity.id)}function Qi(e,t){return Ji(e,`cache_delete`)&&t.identity.source===`cache`&&t.removable&&t.removal.eligible&&!t.lifecycle.busy&&t.lifecycle.active_requests===0&&[`unloaded`,`failed`].includes(t.lifecycle.state)&&!Yi(e,t.identity.id)}function $i(e,t){return qi(e)&&t.lifecycle.state===`ready`&&t.capabilities.some(e=>e.task===`chat`&&e.phase===`provider_ready`&&e.available)}function ea(e,t){return e.catalog.filter(n=>n.identity.id!==t&&Zi(e,n)&&!n.lifecycle.busy&&n.lifecycle.active_requests===0&&n.lifecycle.draining_requests===0)}function ta(e,t){if(e===null)return R(t,`models.library.unknown`);if(e===0)return`0 B`;let n=Math.min(4,Math.floor(Math.log(e)/Math.log(1024)));return`${(e/1024**n).toLocaleString(t,{maximumFractionDigits:1})} ${[`B`,`KiB`,`MiB`,`GiB`,`TiB`][n]}`}function H(e,t){return e instanceof ln?e.envelope?.error.code===`stale_revision`?R(t,`models.library.stale`):e.message:R(t,`models.library.pending`)}function U(e,t){let n=t.query.trim().toLocaleLowerCase();return e.filter(e=>(!n||[e.identity.display_name,e.identity.inference_id,e.metadata.architecture??``].some(e=>e.toLocaleLowerCase().includes(n)))&&(!t.source||e.identity.source===t.source)&&(!t.task||e.capabilities.some(e=>e.task===t.task))&&(!t.status||e.lifecycle.state===t.status)).sort((e,n)=>{let r=e=>t.sort===`status`?e.lifecycle.state:t.sort===`source`?e.identity.source:t.sort===`task`?e.capabilities.map(e=>e.task).join(`,`):e.identity.display_name;return r(e).localeCompare(r(n))||e.identity.id.localeCompare(n.identity.id)})}function na(e){let t=e.split(`/`);return t.length===2&&t.every(e=>e.length<=96&&/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(e))}function ra(e){return e.length===0||e.length<=128&&e.split(`/`).every(e=>e!==`.`&&e!==`..`&&/^[A-Za-z0-9._~+-]+$/.test(e))}function ia({value:e,state:t,locale:n,busy:r,onClose:i,onConfirm:a}){let[o,s]=(0,_.useState)(``),[c,l]=(0,_.useState)(),u=e.kind===`capacity`?ea(t,e.entry.identity.id):[],d=e.kind===`cancel`?e.operation.target.target_kind===`download`?e.operation.target.repo_id:e.operation.operation_id:e.entry.identity.display_name,f=R(n,e.kind===`delete`?`models.library.delete`:e.kind===`unload`?`models.unload`:e.kind===`cancel`?`models.library.cancel_download`:`models.library.capacity`),p=e.kind===`capacity`?R(n,`models.library.capacity_body`):e.kind===`cancel`?R(n,`models.library.cancel_body`,{name:d}):R(n,e.kind===`delete`?`models.library.delete_body`:`models.library.unload_body`,{name:d,source:e.entry.identity.source,count:String(e.entry.lifecycle.active_requests)}),m=t.serverInstanceId===e.instance&&(e.kind===`cancel`||t.catalog.some(t=>t.identity.id===e.entry.identity.id&&t.identity.revision===e.entry.identity.revision)),h=m&&(e.kind===`delete`?o===e.entry.identity.id:e.kind!==`capacity`||u.some(e=>e.identity.id===o&&e.identity.revision===c));return(0,x.jsxs)(lt,{open:!0,title:f,onClose:i,closeLabel:R(n,`common.close`),testId:`models-confirm`,children:[(0,x.jsx)(`p`,{className:`models-wrap`,children:p}),e.kind===`delete`?(0,x.jsx)(`code`,{className:`models-wrap`,children:e.entry.identity.id}):null,e.kind===`capacity`&&o&&!h?(0,x.jsx)(`p`,{role:`alert`,children:R(n,`models.library.stale`)}):null,m?null:(0,x.jsx)(`p`,{role:`alert`,children:R(n,`models.library.stale`)}),e.kind===`delete`?(0,x.jsx)(ot,{label:R(n,`models.library.confirm_name`),value:o,onChange:s,testId:`models-confirm-name`}):null,e.kind===`capacity`?(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(`ul`,{children:t.catalog.filter(e=>[`ready`,`loading`,`draining`,`unloading`].includes(e.lifecycle.state)).map(e=>(0,x.jsxs)(`li`,{className:`models-wrap`,children:[e.identity.display_name,` · `,e.lifecycle.state,` · `,R(n,`models.library.active`),`:`,` `,e.lifecycle.active_requests]},e.identity.id))}),(0,x.jsx)(je,{locale:n,label:R(n,`models.library.eviction`),value:o,onChange:e=>{s(e),l(u.find(t=>t.identity.id===e)?.identity.revision)},options:[{value:``,label:R(n,`models.library.choose`)},...u.map(e=>({value:e.identity.id,label:e.identity.display_name}))],testId:`models-eviction-target`})]}):null,(0,x.jsxs)(`div`,{className:`dialog-actions`,children:[(0,x.jsx)(N,{onClick:i,children:R(n,`models.library.cancel`)}),(0,x.jsx)(N,{tone:`danger`,"data-testid":`models-confirm-submit`,busy:r,disabled:!h||r,onClick:()=>a(e.kind===`capacity`?o:void 0,c),children:R(n,e.kind===`capacity`?`models.library.evict_load`:`models.library.confirm`)})]})]})}function aa({locale:e,state:t,busy:n,onClose:r,onDownload:i,initial:a,error:o}){let[s,c]=(0,_.useState)(a?.repo??``),[l,u]=(0,_.useState)(a?.revision??``),[d,f]=(0,_.useState)(!1),p=na(s.trim())&&ra(l.trim());return(0,x.jsx)(lt,{open:!0,title:R(e,`models.library.add`),onClose:r,closeLabel:R(e,`common.close`),testId:`models-add-dialog`,children:(0,x.jsxs)(`form`,{onSubmit:e=>{e.preventDefault(),p&&d&&!n&&i(s.trim(),l.trim())},children:[o?(0,x.jsx)(`p`,{role:`alert`,children:o}):null,(0,x.jsx)(`p`,{children:R(e,`models.library.network`)}),(0,x.jsx)(`ul`,{children:t.bootstrap?.roots.filter(e=>e.kind===`cache`).map((e,t)=>(0,x.jsx)(`li`,{children:e.display_name},t))}),(0,x.jsx)(ot,{label:R(e,`models.library.repo`),value:s,onChange:c,testId:`models-repo`,error:s&&!na(s.trim())?R(e,`models.library.repo_invalid`):void 0}),(0,x.jsx)(ot,{label:R(e,`models.library.revision`),value:l,onChange:u,testId:`models-revision`}),(0,x.jsxs)(`label`,{className:`toggle`,children:[(0,x.jsx)(`input`,{type:`checkbox`,checked:d,onChange:e=>f(e.currentTarget.checked),"data-testid":`models-public-repo`}),(0,x.jsx)(`span`,{children:R(e,`models.library.public`)})]}),(0,x.jsx)(`p`,{children:R(e,`models.library.private`)}),(0,x.jsx)(`pre`,{className:`models-wrap`,children:`hf download OWNER/REPO --local-dir /path/to/models/checkpoint`}),(0,x.jsxs)(`div`,{className:`dialog-actions`,children:[(0,x.jsx)(N,{onClick:r,children:R(e,`models.library.cancel`)}),(0,x.jsx)(N,{type:`submit`,tone:`primary`,busy:n,disabled:!p||!d||n,"data-testid":`models-download-submit`,children:R(e,`models.library.add`)})]})]})})}function oa({locale:e}){return(0,x.jsxs)(`p`,{"data-testid":`models-pending-profile`,children:[R(e,`models.next_profile.body`),` `,(0,x.jsx)(`a`,{href:`#settings`,children:R(e,`models.next_profile.edit`)})]})}function sa({entry:e,profile:t,state:n,locale:r,busy:i,onAction:a,onChat:o}){let s=e.metadata,c=n.runtimes.get(e.identity.id),l=c?.revision===e.identity.revision?c.settings.effective.ctx_size:null,u=e=>e==null?R(r,`models.library.unknown`):String(e),d=e=>R(r,e?`models.library.yes`:`models.library.no`),f=[[R(r,`models.library.source`),e.identity.source],[R(r,`models.library.architecture`),u(s.architecture)],[R(r,`models.library.backend`),d(s.support.runnable_on_backend)],[R(r,`models.library.tested`),d(s.support.tested_checkpoint)],[R(r,`models.library.disk`),ta(s.disk_bytes,r)],[R(r,`models.library.memory`),ta(s.memory_estimate_bytes,r)],[R(r,`models.library.context`),u(typeof l==`number`?l:null)],[R(r,`models.library.profile`),Object.keys(t).length?JSON.stringify(t):R(r,`models.library.defaults`)],[R(r,`models.library.active`),String(e.lifecycle.active_requests)],[R(r,`models.library.worker`),d(e.lifecycle.worker_exit_observed)]],p=[s.support.reason,s.support.architecturally_supported_reason,s.support.runnable_on_backend_reason,s.support.complete_reason,s.support.tested_checkpoint_reason,...Object.values(s.unknown_reasons),...e.capabilities.map(e=>e.reason)].filter(e=>!!e);return(0,x.jsxs)(dt,{title:R(r,`models.library.details`),children:[(0,x.jsx)(`h3`,{children:e.identity.display_name}),(0,x.jsx)(`code`,{className:`models-wrap`,children:e.identity.id}),(0,x.jsx)(de,{state:e.lifecycle.state,children:jr(r,e.lifecycle.state)}),(0,x.jsx)(`dl`,{children:f.map(([e,t])=>(0,x.jsxs)(_.Fragment,{children:[(0,x.jsx)(`dt`,{children:e}),(0,x.jsx)(`dd`,{children:t})]},e))}),Object.keys(t).length?(0,x.jsx)(oa,{locale:r}):null,(0,x.jsx)(`p`,{children:R(r,`models.library.tested_help`)}),[...new Set(p)].map(e=>(0,x.jsx)(`p`,{children:e},e)),e.lifecycle.last_error?(0,x.jsxs)(`p`,{role:`alert`,children:[R(r,`models.library.last_error`),`: `,e.lifecycle.last_error]}):null,(0,x.jsxs)(`div`,{className:`button-row`,children:[(0,x.jsx)(N,{"data-testid":`models-load`,disabled:i||!Xi(n,e),onClick:()=>a(`load`),children:R(r,`models.load`)}),(0,x.jsx)(N,{"data-testid":`models-use-chat`,disabled:i||!$i(n,e),onClick:o,children:R(r,`models.library.chat`)}),(0,x.jsx)(N,{"data-testid":`models-unload`,disabled:i||!Zi(n,e),onClick:()=>a(`unload`),children:R(r,`models.unload`)}),e.identity.source===`cache`?(0,x.jsx)(N,{tone:`danger`,"data-testid":`models-delete`,disabled:i||!Qi(n,e),onClick:()=>a(`delete`),children:R(r,`models.library.delete`)}):null]}),$i(n,e)?null:(0,x.jsx)(`p`,{children:R(r,`models.library.chat_reason`)}),e.removal.eligible?null:(0,x.jsxs)(`p`,{children:[e.removal.reason,` `,e.removal.instructions]}),Object.entries(n.bootstrap?.actions??{}).filter(([,e])=>e.state!==`enabled`).map(([e,t])=>(0,x.jsxs)(`p`,{children:[e,`: `,t.reason,` `,t.instructions]},e)),(0,x.jsx)(`a`,{href:`https://github.com/lablup/mlxcel/blob/main/docs/llama-server-compat.md`,target:`_blank`,rel:`noreferrer`,children:R(r,`models.library.api`)}),(0,x.jsx)(`ul`,{children:e.capabilities.map(e=>(0,x.jsxs)(`li`,{children:[e.task,` · `,e.phase,` · `,d(e.available)]},`${e.task}-${e.phase}`))})]})}function ca({state:e,locale:t,busy:n,downloadPending:r,onCancel:i,onRetry:a,onCapacity:o}){let s=[...e.operations.values()].filter(e=>[`download`,`model_load`,`model_unload`,`model_removal`,`catalog_refresh`].includes(e.kind)).sort((e,t)=>Number(Ki(e))-Number(Ki(t))||t.created_at.localeCompare(e.created_at));return!s.length&&!e.pendingReconciliations.size?(0,x.jsx)(x.Fragment,{}):(0,x.jsxs)(`section`,{className:`models-operations`,"aria-label":R(t,`models.library.operations`),children:[(0,x.jsx)(`h2`,{children:R(t,`models.library.operations`)}),e.pendingReconciliations.size?(0,x.jsx)(`p`,{role:`status`,"data-testid":`models-pending`,children:R(t,`models.library.pending`)}):null,(0,x.jsx)(`ul`,{className:`ds-list`,children:s.slice(0,64).map(s=>(0,x.jsx)(`li`,{"data-testid":`models-operation`,children:(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`strong`,{children:ua(s,e)}),(0,x.jsxs)(`p`,{children:[(0,x.jsx)(`code`,{children:s.operation_id}),s.target.target_kind===`model`?(0,x.jsxs)(`span`,{children:[` `,`· `,(0,x.jsx)(`code`,{children:s.target.model_id})]}):null,` `,`· `,R(t,`models.library.operation_state`),`: `,s.state]}),s.kind===`download`?(0,x.jsx)(fe,{label:R(t,`models.library.progress`),value:!s.progress.indeterminate&&s.progress.total_bytes!==null&&s.progress.total_bytes>0?s.progress.completed_bytes/s.progress.total_bytes*100:void 0,detail:`${ta(s.progress.completed_bytes,t)} / ${ta(s.progress.total_bytes,t)}`}):null,s.error?(0,x.jsxs)(`p`,{role:`alert`,children:[s.error.code,`: `,s.error.message]}):null,s.result&&`lifecycle`in s.result?(0,x.jsxs)(`p`,{children:[s.result.lifecycle.state,` · `,R(t,`models.library.worker`),`:`,` `,R(t,s.result.lifecycle.worker_exit_observed?`models.library.yes`:`models.library.no`)]}):null,s.cancel_reason?(0,x.jsx)(`p`,{children:s.cancel_reason}):null,(0,x.jsxs)(`div`,{className:`button-row`,children:[s.kind===`model_load`&&s.state===`failed`&&s.error?.code===`conflict`&&s.target.target_kind===`model`?(0,x.jsx)(N,{disabled:n||!e.catalog.some(t=>t.identity.id===la(s)&&Xi(e,t)),onClick:()=>o(la(s)),children:R(t,`models.library.capacity`)}):null,s.kind===`download`&&!Ki(s)?(0,x.jsx)(N,{disabled:n||!qi(e)||!s.cancellable||s.state===`cancelling`,onClick:()=>i(s),children:R(t,`models.library.cancel_download`)}):null,s.kind===`download`&&(s.state===`failed`||s.state===`cancelled`)?(0,x.jsx)(N,{disabled:n||r||!Ji(e,`download`),onClick:()=>a(s),children:R(t,`models.library.retry_download`)}):null]})]})},s.operation_id))})]})}function la(e){return e.target.target_kind===`model`?e.target.model_id:``}function ua(e,t){let n=e.target;return n.target_kind===`download`?n.repo_id:n.target_kind===`model`?t.catalog.find(e=>e.identity.id===n.model_id)?.identity.display_name??n.model_id:e.kind}var da=25;function fa({locale:e}){let t=nr(),n=rr(),[r,i]=(0,_.useState)({query:``,source:``,task:``,status:``,sort:`name`}),[a,o]=(0,_.useState)(0),[s,c]=(0,_.useState)(!1),l=(0,_.useRef)(!1),[u,d]=(0,_.useState)(null),[f,p]=(0,_.useState)(null),[m,h]=(0,_.useState)(null),[g,v]=(0,_.useState)(`copy`),y=t.catalog.find(e=>e.identity.id===t.selectedModelId),{profile:b}=Kr(y?.identity.id??null),{profile:S}=Kr(f?.kind===`capacity`?f.entry.identity.id:null),C=U(t.catalog,r),w=Math.max(1,Math.ceil(C.length/da)),T=Math.min(a,w-1),E=[...t.operations.values()].some(e=>e.kind===`download`&&!Ki(e))||[...t.pendingReconciliations.values()].some(e=>e.kind===`download`),D=[...t.operations.values()].some(e=>e.kind===`catalog_refresh`&&!Ki(e))||[...t.pendingReconciliations.values()].some(e=>e.kind===`catalog-refresh`),O=e=>{i({...r,...e}),o(0)},k=async(n,r)=>{if(l.current||!qi(t))return!1;l.current=!0,c(!0),d(null);try{return await n(),!0}catch(t){return d(H(t,e)),r?.(t),!1}finally{l.current=!1,c(!1)}},ee=(r,i,a=b)=>{if(!Xi(t,r)){d(R(e,`models.library.stale`));return}if(i&&!ea(t,r.identity.id).some(e=>e.identity.id===i.id&&e.identity.revision===i.revision)){d(R(e,`models.library.stale`));return}k(()=>n.loadModel({action:`load`,...Object.keys(a).length?{load_profile:{...a}}:{},model_id:r.identity.id,expected_revision:r.identity.revision,idempotency_key:crypto.randomUUID(),...i?{eviction_target_id:i.id,eviction_target_expected_revision:i.revision}:{}}),e=>{e instanceof ln&&e.envelope?.error.code===`conflict`&&p({kind:`capacity`,entry:r,instance:t.serverInstanceId})})},A=e=>{y&&(e===`load`?ee(y):p({kind:e,entry:y,instance:t.serverInstanceId}))},te=(r,i)=>{let a=f;if(a&&!l.current){if(a.instance!==t.serverInstanceId){d(R(e,`models.library.stale`)),p(null);return}if(a.kind===`cancel`){let e=t.operations.get(a.operation.operation_id);if(!e||!e.cancellable||Ki(e)||e.state===`cancelling`){p(null);return}k(()=>n.cancelOperation(e.operation_id))}else{let o=t.catalog.find(e=>e.identity.id===a.entry.identity.id);if(!o||o.identity.revision!==a.entry.identity.revision){d(R(e,`models.library.stale`)),p(null);return}if(a.kind===`capacity`){if(!ea(t,o.identity.id).some(e=>e.identity.id===r&&e.identity.revision===i)){d(R(e,`models.library.stale`));return}ee(o,r&&i!==void 0?{id:r,revision:i}:void 0,S)}else a.kind===`unload`&&Zi(t,o)?k(()=>n.unloadModel({action:`unload`,model_id:o.identity.id,expected_revision:o.identity.revision,idempotency_key:crypto.randomUUID()})):a.kind===`delete`&&Qi(t,o)?k(()=>n.removeModel({model_id:o.identity.id,expected_revision:o.identity.revision,idempotency_key:crypto.randomUUID()})):d(R(e,`models.library.stale`))}p(null)}},ne=e=>{e.target.target_kind===`download`&&h({repo:e.target.repo_id,revision:e.target.revision??``})},j=`mlxcel-server --webui --models-dir /path/to/models --no-models-autoload`,M=[{id:`name`,header:R(e,`models.library.name`),noResize:!0,render:r=>(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(N,{tone:`ghost`,className:he,"aria-label":R(e,`models.library.inspect`,{name:r.identity.display_name}),onClick:()=>{r.identity.id!==t.selectedModelId&&n.selectModel(r.identity.id)},children:r.identity.display_name}),(0,x.jsxs)(`span`,{className:`models-row-meta`,children:[r.identity.id===t.selectedModelId?(0,x.jsx)(at,{tone:`accent`,children:R(e,`models.library.selected`)}):null,` `,(0,x.jsx)(at,{children:r.identity.source}),` `,(0,x.jsx)(at,{children:r.metadata.quantization??R(e,`models.library.unknown`)})]})]})},{id:`task`,header:R(e,`models.library.task`),noResize:!0,render:t=>t.capabilities.map(e=>e.task).filter((e,t,n)=>n.indexOf(e)===t).join(`, `)||R(e,`models.library.unknown`)},{id:`status`,header:R(e,`models.library.status`),noResize:!0,render:t=>(0,x.jsx)(de,{state:t.lifecycle.state,children:jr(e,t.lifecycle.state)})},{id:`support`,header:R(e,`models.library.support`),noResize:!0,render:t=>(0,x.jsxs)(x.Fragment,{children:[R(e,t.metadata.support.architecturally_supported?`models.library.supported`:`models.library.unsupported`),(0,x.jsx)(`br`,{}),R(e,t.complete?`models.library.complete`:`models.library.incomplete`)]})}];return(0,x.jsxs)(`div`,{className:`screen-stack models-library`,"data-testid":`models-library`,children:[(0,x.jsx)(Ke,{title:R(e,`models.title`),titleTestId:z(`models.title`),description:R(e,`models.library.subtitle`),actions:(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(N,{tone:`primary`,onClick:()=>h({repo:``,revision:``}),disabled:s||E||!Ji(t,`download`),"data-testid":`models-add`,children:R(e,`models.library.add`)}),(0,x.jsx)(N,{disabled:s||D||!qi(t)||t.bootstrap?.server.mode===`single_model`,onClick:()=>{k(()=>n.refreshCatalog(crypto.randomUUID()))},"data-testid":`models-rescan`,children:R(e,`models.library.rescan`)}),(0,x.jsx)(N,{onClick:()=>{n.refresh()},disabled:s,children:R(e,`models.library.refresh`)})]}),error:qi(t)?u===null?null:R(e,`models.library.error`):R(e,`models.library.stale`),errorDetail:qi(t)?u:t.error?.message??R(e,`models.library.waiting`),errorTestId:qi(t)?`models-action-error`:`connection-error-title`,onRetry:()=>{d(null),n.refresh()},retryLabel:R(e,`models.library.refresh`)}),t.bootstrap?.server.mode===`single_model`?(0,x.jsx)(L,{tone:`info`,title:R(e,`models.library.single`),body:`mlxcel-server --webui`,testId:`models-read-only`}):null,Object.entries(t.bootstrap?.actions??{}).filter(([,e])=>e.state!==`enabled`).map(([e,t])=>(0,x.jsxs)(`p`,{children:[e,`: `,t.reason,` `,t.instructions]},e)),(0,x.jsx)(`p`,{"data-testid":`connection-authenticated-detail`,children:Or(e,t)}),(0,x.jsxs)(`details`,{open:t.catalog.length===0,children:[(0,x.jsx)(`summary`,{children:R(e,`models.library.roots`)}),(0,x.jsx)(`ul`,{children:t.bootstrap?.roots.map((t,n)=>(0,x.jsxs)(`li`,{children:[(0,x.jsx)(`strong`,{children:t.display_name}),` · `,t.kind,t.error?(0,x.jsxs)(`p`,{role:`alert`,children:[R(e,`models.library.permission`),` `,t.error]}):null]},n))}),(0,x.jsx)(`p`,{children:R(e,`models.library.roots_help`)}),(0,x.jsx)(`pre`,{className:`models-wrap`,children:j}),(0,x.jsx)(N,{onClick:()=>{navigator.clipboard?.writeText(j).then(()=>v(`copied`)).catch(()=>v(`copy_failed`)),navigator.clipboard||v(`copy_failed`)},children:R(e,`models.library.${g}`)}),(0,x.jsx)(`span`,{role:`status`,children:g===`copy`?``:R(e,`models.library.${g}`)})]}),(0,x.jsxs)(`div`,{className:`models-toolbar`,children:[(0,x.jsx)(ot,{label:R(e,`models.library.search`),value:r.query,onChange:e=>O({query:e}),testId:`models-search`}),(0,x.jsx)(je,{locale:e,label:R(e,`models.library.source`),value:r.source,onChange:e=>O({source:e}),options:[{value:``,label:R(e,`models.library.all`)},...[...new Set(t.catalog.map(e=>e.identity.source))].sort().map(e=>({value:e,label:e}))]}),(0,x.jsx)(je,{locale:e,label:R(e,`models.library.task`),value:r.task,onChange:e=>O({task:e}),options:[{value:``,label:R(e,`models.library.all`)},...[...new Set(t.catalog.flatMap(e=>e.capabilities.map(e=>e.task)))].sort().map(e=>({value:e,label:e}))]}),(0,x.jsx)(je,{locale:e,label:R(e,`models.library.status`),value:r.status,onChange:e=>O({status:e}),options:[{value:``,label:R(e,`models.library.all`)},...[`unloaded`,`loading`,`ready`,`draining`,`unloading`,`failed`].map(t=>({value:t,label:jr(e,t)}))]}),(0,x.jsx)(je,{locale:e,label:R(e,`models.library.sort`),value:r.sort,onChange:e=>O({sort:e}),options:[`name`,`status`,`source`,`task`].map(t=>({value:t,label:R(e,`models.library.sort_${t}`)}))})]}),(0,x.jsxs)(`div`,{className:`models-layout`,children:[(0,x.jsxs)(`section`,{children:[(0,x.jsx)(ge,{columns:M,rows:C.slice(T*da,(T+1)*da),getRowKey:e=>e.identity.id,ariaLabel:R(e,`models.title`),testId:`models-table`,activateRowPrimary:!0,rowClassName:e=>e.identity.id===t.selectedModelId?`models-selected`:void 0,loading:t.catalogSequence===null,loadingState:(0,x.jsx)(xe,{label:R(e,`models.library.waiting`)}),emptyState:(0,x.jsx)(pe,{title:R(e,t.catalog.length===0?`models.empty.title`:`models.library.filtered`),body:R(e,t.catalog.length===0?`models.empty.body`:`models.library.filtered_body`),testId:`models-empty`})}),(0,x.jsxs)(`nav`,{className:`models-pagination`,"aria-label":R(e,`models.title`),children:[(0,x.jsx)(N,{disabled:T===0,onClick:()=>o(T-1),children:R(e,`models.library.previous`)}),(0,x.jsx)(`span`,{role:`status`,children:R(e,`models.library.page`,{page:String(T+1),pages:String(w),count:String(C.length)})}),(0,x.jsx)(N,{disabled:T>=w-1,onClick:()=>o(T+1),children:R(e,`models.library.next`)})]})]}),y?(0,x.jsx)(sa,{entry:y,profile:b,state:t,locale:e,busy:s,onAction:A,onChat:()=>{$i(t,y)&&(n.selectModel(y.identity.id),window.location.hash=`chat`)}}):null]}),(0,x.jsx)(ca,{state:t,locale:e,busy:s,downloadPending:E,onCancel:e=>p({kind:`cancel`,operation:e,instance:t.serverInstanceId}),onRetry:ne,onCapacity:e=>{let n=t.catalog.find(t=>t.identity.id===e);n&&Xi(t,n)&&p({kind:`capacity`,entry:n,instance:t.serverInstanceId})}}),f?(0,x.jsx)(ia,{value:f,state:t,locale:e,busy:s,onClose:()=>p(null),onConfirm:te},f.kind):null,m?(0,x.jsx)(aa,{locale:e,state:t,initial:m,error:u,busy:s||E||!Ji(t,`download`),onClose:()=>h(null),onDownload:(e,r)=>{Ji(t,`download`)&&!E&&k(()=>n.downloadModel({repo_id:e,revision:r||null,idempotency_key:crypto.randomUUID()})).then(e=>{e&&h(null)})}}):null]})}var pa={en:`en-US`,ko:`ko-KR`},ma=e=>pa[e];function ha(e,t){if(!Number.isFinite(e)||e<0)return R(t,`format.unknown`);let n=[`B`,`KiB`,`MiB`,`GiB`,`TiB`],r=e,i=0;for(;r>=1024&&in(!0)})},{id:`states`,label:R(e.locale,`gallery.tab.states`),panel:(0,x.jsx)(ya,{locale:e.locale})},{id:`data`,label:R(e.locale,`gallery.tab.data`),panel:(0,x.jsx)(ba,{locale:e.locale})}]}),(0,x.jsxs)(lt,{open:t,title:R(e.locale,`models.delete.confirm.title`),onClose:()=>n(!1),testId:`gallery-dialog`,closeLabel:R(e.locale,`common.close`),children:[(0,x.jsx)(`p`,{"data-testid":z(`models.delete.confirm.body`),children:R(e.locale,`models.delete.confirm.body`,{model:a})}),(0,x.jsx)(ot,{label:R(e.locale,`models.delete.confirm.token_label`),value:``,placeholder:R(e.locale,`gallery.delete_token`)}),(0,x.jsxs)(`div`,{className:`dialog-actions`,children:[(0,x.jsx)(N,{onClick:()=>n(!1),children:R(e.locale,`common.cancel`)}),(0,x.jsx)(N,{tone:`danger`,children:R(e.locale,`common.delete`)})]})]})]})}function va(e){return(0,x.jsxs)(`div`,{className:`gallery-grid`,children:[(0,x.jsxs)(We,{children:[(0,x.jsx)(`h2`,{children:R(e.locale,`gallery.controls.title`)}),(0,x.jsxs)(`div`,{className:`control-row`,children:[(0,x.jsx)(N,{tone:`primary`,children:R(e.locale,`gallery.controls.primary`)}),(0,x.jsx)(N,{children:R(e.locale,`gallery.controls.secondary`)}),(0,x.jsx)(N,{tone:`danger`,children:R(e.locale,`gallery.controls.danger`)}),(0,x.jsx)(N,{busy:!0,children:R(e.locale,`gallery.controls.busy`)})]}),(0,x.jsx)(ot,{label:R(e.locale,`gallery.field.repo`),value:e.value,onChange:e.onValueChange,error:R(e.locale,`gallery.field.repo_error`),hint:R(e.locale,`gallery.field.repo_hint`),testId:`gallery-field`}),(0,x.jsx)(je,{locale:e.locale,label:R(e.locale,`gallery.select.native`),value:e.selectValue,onChange:e.onSelectChange,options:[{value:`ready`,label:R(e.locale,`models.status.ready`)},{value:`unloaded`,label:R(e.locale,`models.status.unloaded`)}]})]}),(0,x.jsxs)(We,{children:[(0,x.jsx)(`h2`,{children:R(e.locale,`gallery.overlays.title`)}),(0,x.jsx)(`p`,{children:R(e.locale,`gallery.long_cjk`)}),(0,x.jsxs)(`div`,{className:`control-row`,children:[(0,x.jsx)(Re,{content:R(e.locale,`gallery.tooltip`),children:(0,x.jsx)(N,{children:R(e.locale,`gallery.hover_focus`)})}),(0,x.jsx)(N,{tone:`primary`,onClick:e.onOpenDialog,children:R(e.locale,`gallery.dialog.open`)})]})]})]})}function ya(e){return(0,x.jsxs)(`div`,{className:`gallery-grid`,children:[(0,x.jsx)(mt,{title:R(e.locale,`state.unauthorized.title`),body:R(e.locale,`state.unauthorized.body`),tokenLabel:R(e.locale,`login.token.label`),tokenHelp:R(e.locale,`login.token.help`),submitLabel:R(e.locale,`login.submit`),logoutLabel:R(e.locale,`login.logout`),onSubmit:()=>void 0,onLogout:()=>void 0,testId:`gallery-login`}),(0,x.jsx)(ht,{title:R(e.locale,`state.schema_mismatch.title`),body:R(e.locale,`state.schema_mismatch.body`),actionLabel:R(e.locale,`common.reload`),onRecover:()=>void 0}),(0,x.jsx)(pe,{title:R(e.locale,`models.empty.title`),body:R(e.locale,`models.empty.body`),action:(0,x.jsx)(N,{tone:`primary`,children:R(e.locale,`common.add_model`)}),testId:`gallery-empty`}),(0,x.jsx)(L,{tone:`warning`,title:R(e.locale,`gallery.states.load_failed`),body:R(e.locale,`gallery.states.load_failed_body`),action:(0,x.jsx)(N,{children:R(e.locale,`common.retry`)})}),(0,x.jsxs)(`div`,{className:`gallery-progress-samples`,children:[(0,x.jsx)(fe,{label:R(e.locale,`gallery.download`),detail:R(e.locale,`activity.progress.indeterminate`,{bytes:ha(67108864,e.locale)})}),(0,x.jsx)(fe,{label:R(e.locale,`gallery.progress.measured`),value:37})]}),(0,x.jsxs)(pt,{label:R(e.locale,`gallery.lifecycle.samples`),children:[(0,x.jsx)(`li`,{children:(0,x.jsx)(de,{state:`loading`,children:R(e.locale,`models.status.loading`)})}),(0,x.jsx)(`li`,{children:(0,x.jsx)(de,{state:`draining`,children:R(e.locale,`models.status.draining`)})}),(0,x.jsx)(`li`,{children:(0,x.jsx)(de,{state:`unloading`,children:R(e.locale,`models.status.unloading`)})})]})]})}function ba(e){return(0,x.jsxs)(`div`,{className:`gallery-grid dense-gallery`,children:[(0,x.jsxs)(We,{className:`table-card`,role:`region`,tabIndex:0,ariaLabel:R(e.locale,`gallery.sample.caption`),children:[(0,x.jsx)(`h2`,{children:R(e.locale,`gallery.data.title`)}),(0,x.jsxs)(ft,{caption:R(e.locale,`gallery.sample.caption`),children:[(0,x.jsx)(`thead`,{children:(0,x.jsxs)(`tr`,{children:[(0,x.jsx)(`th`,{children:R(e.locale,`gallery.data.name`)}),(0,x.jsx)(`th`,{children:R(e.locale,`gallery.data.status`)}),(0,x.jsx)(`th`,{children:R(e.locale,`gallery.data.rate`)})]})}),(0,x.jsxs)(`tbody`,{children:[(0,x.jsxs)(`tr`,{children:[(0,x.jsx)(`td`,{children:(0,x.jsx)(`span`,{className:`truncate`,title:R(e.locale,`models.long_name`),"aria-label":R(e.locale,`models.long_name`),children:R(e.locale,`models.long_name`)})}),(0,x.jsx)(`td`,{children:(0,x.jsx)(de,{state:`ready`,children:R(e.locale,`models.status.ready`)})}),(0,x.jsx)(`td`,{children:ga(39.4,e.locale)})]}),(0,x.jsxs)(`tr`,{children:[(0,x.jsx)(`td`,{children:(0,x.jsx)(`span`,{className:`truncate`,title:`granite-4.0-h-tiny-4bit`,"aria-label":`granite-4.0-h-tiny-4bit`,children:`granite-4.0-h-tiny-4bit`})}),(0,x.jsx)(`td`,{children:(0,x.jsx)(de,{state:`unloaded`,children:R(e.locale,`models.status.unloaded`)})}),(0,x.jsx)(`td`,{children:ga(null,e.locale)})]})]})]})]}),(0,x.jsxs)(dt,{title:R(e.locale,`gallery.data.inspector`),children:[(0,x.jsx)(`p`,{className:`sample-label`,children:R(e.locale,`gallery.sample.label`)}),(0,x.jsx)(`p`,{children:R(e.locale,`models.unsupported.reason`)}),(0,x.jsx)(de,{state:`failed`,children:R(e.locale,`models.status.failed`)}),(0,x.jsx)(`hr`,{}),(0,x.jsx)(`p`,{children:R(e.locale,`gallery.sample.reasoning_body`)}),(0,x.jsx)(`code`,{children:R(e.locale,`gallery.sample.tool_preview`)})]})]})}function xa(){if(typeof navigator>`u`)return!1;let e=navigator,t=e.userAgentData?.platform??e.platform??e.userAgent??``;return/mac|iphone|ipad|ipod/i.test(t)}function Sa(e){return xa()?e.metaKey:e.ctrlKey}var Ca={count:4,bytes:8388608,dimension:4096,pixels:16e6},wa=new Set([`image/png`,`image/jpeg`,`image/webp`]);function Ta(e,t){let n=new DataView(e.buffer,e.byteOffset,e.byteLength),r=(t,n)=>String.fromCharCode(...e.subarray(t,t+n));if(t===`image/png`&&e.length>=33&&e[0]===137&&r(1,7)===`PNG\r + +`&&n.getUint32(8)===13&&r(12,4)===`IHDR`)return[n.getUint32(16),n.getUint32(20)];if(t===`image/jpeg`&&e.length>=4&&e[0]===255&&e[1]===216){let t=2;for(;t+4<=e.length&&e[t++]===255;){for(;e[t]===255;)t++;let r=e[t++];if(r===217||r===218)break;if(r===1||r>=208&&r<=215)continue;if(t+2>e.length)break;let i=n.getUint16(t);if(i<2||t+i>e.length)break;if([192,193,194,195,197,198,199,201,202,203,205,206,207].includes(r)&&i>=8)return[n.getUint16(t+5),n.getUint16(t+3)];t+=i}}if(t===`image/webp`&&e.length>=25&&r(0,4)===`RIFF`&&r(8,4)===`WEBP`&&n.getUint32(4,!0)+8===e.length){let t=r(12,4),i=n.getUint32(16,!0);if(i<5||20+i>e.length)throw Error(`Invalid WebP chunk length.`);let a=t=>e[t]|e[t+1]<<8|e[t+2]<<16;if(t===`VP8X`&&e.length>=30&&n.getUint32(16,!0)>=10&&!(e[20]&2))return[a(24)+1,a(27)+1];if(t===`VP8 `&&e.length>=30&&e[23]===157&&e[24]===1&&e[25]===42)return[n.getUint16(26,!0)&16383,n.getUint16(28,!0)&16383];if(t===`VP8L`&&e[20]===47){let e=n.getUint32(21,!0);return[(e&16383)+1,(e>>>14&16383)+1]}}throw Error(`Image content does not match a supported PNG, JPEG or non-animated WebP image.`)}function Ea(e){return new Promise((t,n)=>{let r=new FileReader;r.onerror=()=>n(Error(`Could not read the selected image.`)),r.onabort=()=>n(Error(`Image reading was cancelled.`)),r.onload=()=>r.result instanceof ArrayBuffer?t(new Uint8Array(r.result)):n(Error(`Invalid image data.`)),r.readAsArrayBuffer(e)})}function Da(e){if(!e||[e.max_images,e.max_image_bytes,e.max_width,e.max_height,e.max_decoded_bytes,e.max_body_bytes].some(e=>!Number.isSafeInteger(e)||e<=0))throw Error(`Image limits are unavailable.`)}function Oa(e,t,n){if(!e||!t||e>Math.min(Ca.dimension,n.max_width)||t>Math.min(Ca.dimension,n.max_height)||e*t>Ca.pixels||e*t*4>n.max_decoded_bytes)throw Error(`Image dimensions exceed the server or browser decode budget.`)}function ka(e,t){if(e.length===0){if(!t||!Number.isSafeInteger(t.max_body_bytes)||t.max_body_bytes<=0)throw Error(`Request body limit is unavailable.`);return}if(Da(t),e.length>t.max_images)throw Error(`Conversation images exceed the server image count limit.`);let n=0,r=Math.min(Ca.bytes,t.max_image_bytes);for(let i of e){if(!i||!wa.has(i.type)||typeof i.dataUrl!=`string`)throw Error(`Invalid local image attachment.`);if(n+=i.dataUrl.length,n>t.max_body_bytes)throw Error(`Images exceed the server request body limit.`);let e=`data:${i.type};base64,`;if(!i.dataUrl.startsWith(e))throw Error(`Invalid image data URL.`);if(i.dataUrl.length-e.length>4*Math.ceil(r/3))throw Error(`Image exceeds the current server or browser byte limit.`)}for(let n of e){let e=n.dataUrl.slice(`data:${n.type};base64,`.length);if(!e||e.length%4!=0||!/^[A-Za-z0-9+/]*={0,2}$/.test(e))throw Error(`Invalid image base64 encoding.`);let i=atob(e);if(btoa(i)!==e)throw Error(`Image base64 encoding must be canonical.`);if(!i.length||i.length>r)throw Error(`Image exceeds the current server or browser byte limit.`);let a=new Uint8Array(i.length);for(let e=0;ei||t!==r.length)throw Error(`Attach at most ${i} images per message; existing attachment count must match.`);for(let e of o){if(!(e instanceof File)||!wa.has(e.type))throw Error(`Choose local PNG, JPEG or WebP image files.`);if(!e.size||e.size>a)throw Error(`Each image must be nonempty and no larger than ${a} bytes.`)}if(r.reduce((e,t)=>e+t.dataUrl.length,0)+o.reduce((e,t)=>e+4*Math.ceil(t.size/3)+`data:${t.type};base64,`.length,0)>n.max_body_bytes)throw Error(`Images exceed the server request body limit.`);let s=[];for(let e of o){let t=await Ea(e),[r,i]=Ta(t,e.type);if(Oa(r,i,n),typeof createImageBitmap==`function`){let t;try{t=await createImageBitmap(e,{imageOrientation:`none`})}catch{throw Error(`The image could not be decoded.`)}try{if(t.width!==r||t.height!==i)throw Error(`Decoded image dimensions do not match its header.`)}finally{t.close()}}let a=``;for(let e=0;e{if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Malformed chat stream.`);return e};function Na(e){if(e==null)return``;if(typeof e!=`string`)throw Error(`Malformed text delta.`);return e}function Pa(e){if(typeof e!=`number`||!Number.isSafeInteger(e)||e<0)throw Error(`Malformed usage.`);return e}function Fa(e,t,n){if(t.length>256e3)throw Error(`Chat frame exceeds the display limit.`);let r=Ma(JSON.parse(t));if(r.error!==void 0)throw Error(`The server reported a generation error. No automatic retry was made.`);let i={...e};if(r.usage!==void 0&&r.usage!==null){let e=Ma(r.usage);i={...i,usage:{prompt_tokens:Pa(e.prompt_tokens),completion_tokens:Pa(e.completion_tokens),total_tokens:Pa(e.total_tokens)}}}if(!Array.isArray(r.choices)||r.choices.length>1)throw Error(`Malformed chat choices.`);for(let e of r.choices){let t=Ma(e);if(t.index!==0)throw Error(`Unexpected chat choice index.`);let r=Ma(t.delta),a=Na(r.content),o=Na(r.reasoning_content??r.reasoning),s=i.tools.map(e=>({...e}));if(r.tool_calls!==void 0&&r.tool_calls!==null){if(!Array.isArray(r.tool_calls)||r.tool_calls.length>32)throw Error(`Too many tool calls.`);for(let e of r.tool_calls){let t=Ma(e),n=Pa(t.index);if(n>=32)throw Error(`Tool index exceeds the display limit.`);let r=t.function===void 0?{}:Ma(t.function),i=s.find(e=>e.index===n)??{index:n,id:``,name:``,arguments:``},a={index:n,id:i.id+Na(t.id),name:i.name+Na(r.name),arguments:i.arguments+Na(r.arguments)};s=[...s.filter(e=>e.index!==n),a].sort((e,t)=>e.index-t.index)}}let c=a.length>0||o.length>0||s.length>0;if(i={...i,content:i.content+a,reasoning:i.reasoning+o,tools:s,ttftMs:i.ttftMs??(c?n:null)},t.finish_reason!==null&&t.finish_reason!==void 0){let e=Na(t.finish_reason);if(e.length>64)throw Error(`Invalid finish reason.`);i={...i,finishReason:e}}}if(i.content.length+i.reasoning.length+JSON.stringify(i.tools).length>256e3)throw Error(`Response exceeds the bounded display limit; generation stopped.`);return i}function Ia(e,t){if(e.finishReason===null||!e.content&&!e.reasoning&&e.tools.length===0)throw Error(`The server returned an empty or unfinished response.`);return{...e,status:`complete`,elapsedMs:t}}function La(e,t){let n=e?[{role:`system`,content:e}]:[];for(let e of t)n.push({role:`user`,content:e.images.length?[{type:`text`,text:e.prompt},...e.images.map(e=>({type:`image_url`,image_url:{url:e.dataUrl}}))]:e.prompt}),e.status===`complete`&&e.content&&n.push({role:`assistant`,content:e.content});return n}function Ra(e){return e.usage===null||e.ttftMs===null||e.elapsedMs===null||e.elapsedMs<=e.ttftMs||e.usage.completion_tokens<=1?null:(e.usage.completion_tokens-1)*1e3/(e.elapsedMs-e.ttftMs)}var za=Object.freeze({conversations:50,turnsPerConversation:200,totalTurns:1e3,textCharacters:262144,jsonBytes:16777216,imageBytes:8388608,imagesPerTurn:8,toolsPerTurn:128}),Ba=`mlxcel.webui.chat.v1`,Va=`history`,Ha=`conversations`,Ua=1,Wa=new Set([`temperature`,`top_p`,`top_k`,`min_p`,`max_tokens`,`seed`,`repetition_penalty`,`presence_penalty`,`frequency_penalty`]),Ga=class extends Error{constructor(e=`Conversation history is invalid or exceeds the local history limits.`){super(e),this.name=`HistoryValidationError`}},Ka=class extends Error{constructor(e,t){super(e,t),this.name=`HistoryStorageError`}};function qa(){throw new Ga}function Ja(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return qa();let n=Object.getPrototypeOf(e);if(n!==Object.prototype&&n!==null)return qa();let r=Object.keys(e);return r.length!==t.length||r.some(e=>!t.includes(e))?qa():e}function Ya(e,t=za.textCharacters){return typeof e!=`string`||e.length>t?qa():e}function Xa(e){let t=Ya(e,512);return!t||Array.from(t).some(e=>e.charCodeAt(0)<32||e.charCodeAt(0)===127)?qa():t}function Za(e,t=!1){return typeof e!=`number`||!Number.isFinite(e)||e<0||t&&!Number.isSafeInteger(e)?qa():e}function Qa(e,t){return e===null?null:t(e)}function $a(e,t){return!Array.isArray(e)||e.length>t?qa():e}function eo(e){return new TextEncoder().encode(e).byteLength}function to(e,t){let n=0,r=0,i=0,a=new Set;return $a(e,za.conversations).map(e=>{let o=Ja(e,[`id`,`title`,`systemPrompt`,`turns`,`updatedAt`]),s=Xa(o.id);if(a.has(s))return qa();a.add(s);let c=new Set,l=$a(o.turns,za.turnsPerConversation).map(e=>{if(++n>za.totalTurns)return qa();let a=Ja(e,[`id`,`modelId`,`modelRevision`,`inferenceId`,`modelName`,`prompt`,`content`,`reasoning`,`tools`,`status`,`finishReason`,`usage`,`ttftMs`,`elapsedMs`,`error`,`parameters`,`images`]),o=Xa(a.id);if(c.has(o))return qa();c.add(o);let s=Ya(a.status,32);if(![`streaming`,`complete`,`cancelled`,`interrupted`,`error`].includes(s))return qa();let l={};if(!a.parameters||typeof a.parameters!=`object`||Array.isArray(a.parameters)||![Object.prototype,null].includes(Object.getPrototypeOf(a.parameters)))return qa();for(let[e,t]of Object.entries(a.parameters)){if(!Wa.has(e)||typeof t!=`number`||!Number.isFinite(t))return qa();l[e]=t}let u=new Set,d=$a(a.tools,za.toolsPerTurn).map(e=>{let t=Ja(e,[`index`,`id`,`name`,`arguments`]),n=Za(t.index,!0);return u.has(n)?qa():(u.add(n),{index:n,id:Ya(t.id,512),name:Ya(t.name,512),arguments:Ya(t.arguments)})}),f=$a(a.images,za.imagesPerTurn).map(e=>{let t=Ja(e,[`name`,`type`,`dataUrl`]),n=Ya(t.type,64);if(![`image/png`,`image/jpeg`,`image/webp`].includes(n))return qa();let i=Ya(t.dataUrl,za.imageBytes*2),a=`data:${n};base64,`;if(!i.startsWith(a))return qa();let o=i.slice(a.length);return!o||o.length%4!=0||!/^[A-Za-z0-9+/]*={0,2}$/u.test(o)||(r+=o.length*3/4-(o.endsWith(`==`)?2:+!!o.endsWith(`=`)),r>za.imageBytes)?qa():{name:Ya(t.name,512),type:n,dataUrl:i}}),p={id:o,modelId:Xa(a.modelId),modelRevision:Za(a.modelRevision,!0),inferenceId:Xa(a.inferenceId),modelName:Ya(a.modelName,512),prompt:Ya(a.prompt),content:Ya(a.content),reasoning:Ya(a.reasoning),tools:d,status:s===`streaming`?`interrupted`:s,finishReason:Qa(a.finishReason,Ya),usage:Qa(a.usage,e=>{let t=Ja(e,[`prompt_tokens`,`completion_tokens`,`total_tokens`]);return{prompt_tokens:Za(t.prompt_tokens,!0),completion_tokens:Za(t.completion_tokens,!0),total_tokens:Za(t.total_tokens,!0)}}),ttftMs:Qa(a.ttftMs,Za),elapsedMs:Qa(a.elapsedMs,Za),error:Qa(a.error,Ya),parameters:l,images:t.includeImages?f:[]};return p.status===`complete`&&(!p.finishReason||!p.content&&!p.reasoning&&!p.tools.length)||(i+=eo(JSON.stringify(p)),i>za.jsonBytes)?qa():p});return{id:s,title:Ya(o.title,512),systemPrompt:Ya(o.systemPrompt),turns:l,updatedAt:Za(o.updatedAt,!0)}})}function no(e,t={}){let n=to(e,t);return eo(JSON.stringify(n))>za.jsonBytes?qa():n}function ro(e,t={}){let n=JSON.stringify({version:Ua,conversations:no(e,t)});return eo(n)>za.jsonBytes?qa():n}function io(e,t={}){if(eo(e)>za.jsonBytes)return qa();let n;try{n=JSON.parse(e)}catch{return qa()}let r=Ja(n,[`version`,`conversations`]);return r.version===Ua?no(r.conversations,t):qa()}function ao(e){return new Ka(e instanceof DOMException&&e.name===`QuotaExceededError`?`Local history storage is full. Export or clear history, or disable persistence; the current conversation remains in memory.`:`Local history storage is unavailable. The current conversation remains in memory.`,{cause:e})}function oo(e={}){let t=!1,n=!1,r=0,i,a,o=new Set,s=()=>{let t=e.indexedDB??globalThis.indexedDB;if(!t)throw new Ka(`This browser does not support local history storage.`);return t},c=()=>{r++;for(let e of o)try{e.abort()}catch{}o.clear(),i?.close(),i=void 0,a=void 0},l=()=>{if(i)return Promise.resolve(i);if(a)return a;let e=r;return a=new Promise((n,a)=>{let o=s().open(Ba,Ua);o.onupgradeneeded=()=>{o.result.objectStoreNames.contains(Va)||o.result.createObjectStore(Va)},o.onerror=()=>a(ao(o.error));let l=!1;o.onblocked=()=>{l=!0,a(new Ka(`Close other WebUI tabs to access local history.`))},o.onsuccess=()=>{if(l||!t||e!==r){o.result.close(),a(new Ka(`Local history persistence was disabled.`));return}i=o.result,i.onversionchange=c,n(i)}}),a.catch(t=>{throw e===r&&(a=void 0),t})};async function u(e,i){if(!t||n)return;let a=r;try{let s=await l();return!t||n||r!==a?void 0:await new Promise((t,n)=>{let r=s.transaction(Va,e);o.add(r);let a=i(r.objectStore(Va));r.oncomplete=()=>{o.delete(r),t(a.result)},r.onabort=r.onerror=()=>{o.delete(r),n(ao(r.error??a.error))}})}catch(e){throw e instanceof Ka?e:ao(e)}}return{setEnabled(e){t!==e&&(t=e,e||c())},async load(e={}){let t=await u(`readonly`,e=>e.get(Ha));return t===void 0?[]:io(Ya(t,za.jsonBytes),e)},async save(e,n={}){if(!t)return;let r=ro(e,n);await u(`readwrite`,e=>e.put(r,Ha))},async clear(){if(n)throw new Ka(`Local history is already being cleared.`);n=!0;let e=!1;c();try{await new Promise((t,r)=>{let i=s().deleteDatabase(Ba);i.onsuccess=()=>{n=!1,t()},i.onerror=()=>{n=!1,r(ao(i.error))},i.onblocked=()=>{e=!0,r(new Ka(`Close other WebUI tabs to clear local history.`))}})}catch(t){throw e||(n=!1),t instanceof Ka?t:ao(t)}},close:c}}var so=[],co=0,lo=0,uo=0,fo=new Set;function po(e){return fo.add(e),()=>{fo.delete(e)}}function mo(){return co}function ho(e){return{id:crypto.randomUUID(),title:e,systemPrompt:``,turns:[],updatedAt:Date.now()}}var go=new WeakMap;function _o(e){let t=go.get(e);if(t!==void 0)return t;let n=new TextEncoder().encode(JSON.stringify(e)).byteLength;return go.set(e,n),n}function vo(e){return e.length>za.conversations||e.reduce((e,t)=>e+t.turns.length,0)>za.totalTurns?!1:2+Math.max(0,e.length-1)+e.reduce((e,t)=>e+new TextEncoder().encode(JSON.stringify({...t,turns:[]})).byteLength+t.turns.reduce((e,t)=>e+_o(t),0)+Math.max(0,t.turns.length-1),0)<=za.jsonBytes}function yo(){for(let e of fo)e()}function bo(e){so=e,yo()}function xo(e){if(!vo(e))throw Error(`Conversation memory limit exceeded.`);co++,lo=0,bo(e)}function So(){uo++,lo=uo,yo()}function Co(){return(0,_.useSyncExternalStore)(po,()=>lo)}function wo(){let e=lo!==0;return lo=0,e}function To(e){let t=so.some(t=>t.id===e.id)?so.map(t=>t.id===e.id?e:t):[...so,e];return vo(t)?(bo(t),!0):!1}function Eo(){return(0,_.useSyncExternalStore)(po,()=>so)}var Do=(0,_.lazy)(()=>Ui(()=>import(`./code-highlight-Dk2RxJiZ.js`),[],import.meta.url)),Oo=65536,ko=512;function Ao(e){let t=[];for(let n=0;nvoid a(),children:r})]}),(0,x.jsx)(`pre`,{children:n?(0,x.jsx)(_.Suspense,{fallback:(0,x.jsx)(`code`,{children:e}),children:(0,x.jsx)(Do,{code:e,language:t})}):(0,x.jsx)(`code`,{children:e})})]})}),No=(0,_.memo)(function({text:e,streaming:t=!1}){let n=e.slice(0,Oo).split(` +`),r=[],i=0;for(;i=s[1].length&&[...t].every(e=>e===s[1][0])){c=!0;break}o.push(e)}r.push((0,x.jsx)(Mo,{code:o.join(` +`),language:s[2].slice(0,40),complete:c||!t&&e.length<=Oo},a))}else if(/^#{1,6} /.test(o))r.push((0,x.jsx)(`p`,{className:`chat-markdown-heading`,children:(0,x.jsx)(`strong`,{children:Ao(o.replace(/^#{1,6} /,``))})},a));else if(/^[-*] /.test(o)){let e=[o.slice(2)];for(;i(0,x.jsx)(`li`,{children:Ao(e)},t))},a))}else o.trim()&&r.push((0,x.jsx)(`p`,{children:Ao(o)},a))}return(0,x.jsxs)(`div`,{className:`chat-markdown`,children:[r,(e.length>Oo||i0?(0,x.jsx)(`p`,{children:R(i,`chat.transcript.images`,{count:String(e.images.length)})}):null,(0,x.jsx)(N,{disabled:r,onClick:()=>n(t),children:R(i,`chat.transcript.edit`)}),e.reasoning?(0,x.jsxs)(`details`,{children:[(0,x.jsx)(`summary`,{children:e.status===`streaming`&&!e.content?R(i,`chat.transcript.reasoning_thinking`):R(i,`chat.reasoning`)}),(0,x.jsx)(`pre`,{children:e.reasoning})]}):null,e.status===`streaming`&&!e.content?(0,x.jsx)(`p`,{children:e.reasoning?R(i,`chat.transcript.thinking`):R(i,`chat.transcript.waiting`)}):null,(0,x.jsx)(No,{text:e.content,streaming:e.status===`streaming`}),e.tools.map(e=>(0,x.jsxs)(`details`,{children:[(0,x.jsx)(`summary`,{children:R(i,`chat.transcript.tool_call`,{name:e.name||R(i,`chat.transcript.tool_name_pending`)})}),(0,x.jsx)(`pre`,{children:e.arguments})]},e.index)),e.error?(0,x.jsx)(`p`,{role:`alert`,children:e.error}):null,(0,x.jsxs)(`div`,{className:`chat-toolbar`,children:[(0,x.jsx)(N,{onClick:()=>{(async()=>{try{await navigator.clipboard.writeText(e.content),o(`chat.transcript.copied`)}catch{o(`chat.transcript.copy_failed`)}})()},children:R(i,`chat.transcript.copy`)}),(0,x.jsx)(`span`,{role:`status`,children:a===null?``:R(i,a)})]}),(0,x.jsxs)(`details`,{children:[(0,x.jsx)(`summary`,{children:R(i,`chat.transcript.details`)}),(0,x.jsxs)(`dl`,{className:`chat-metrics`,children:[(0,x.jsx)(`dt`,{children:R(i,`chat.transcript.finish_reason`)}),(0,x.jsx)(`dd`,{children:e.finishReason??c}),(0,x.jsx)(`dt`,{children:R(i,`chat.transcript.usage`)}),(0,x.jsx)(`dd`,{children:e.usage?R(i,`chat.transcript.usage_value`,{prompt:String(e.usage.prompt_tokens),completion:String(e.usage.completion_tokens),total:String(e.usage.total_tokens)}):c}),(0,x.jsx)(`dt`,{children:R(i,`chat.transcript.first_delta`)}),(0,x.jsx)(`dd`,{children:e.ttftMs===null?c:`${Math.round(e.ttftMs)} ms`}),(0,x.jsx)(`dt`,{children:R(i,`chat.transcript.decode_rate`)}),(0,x.jsx)(`dd`,{children:s===null?c:`${s.toFixed(1)} tokens/s`})]}),(0,x.jsx)(`p`,{children:R(i,`chat.transcript.metrics_note`)}),(0,x.jsx)(`pre`,{children:JSON.stringify(e.parameters,null,2)})]})]})});function Io({turns:e,onEdit:t,busy:n,locale:r}){let i=(0,_.useRef)(t);i.current=t;let a=(0,_.useCallback)(e=>i.current(e),[]),o=(0,_.useRef)(null),s=(0,_.useRef)(!0),[c,l]=(0,_.useState)(!1),u=e.at(-1);return(0,_.useEffect)(()=>{s.current&&o.current&&window.getSelection()?.isCollapsed!==!1&&(o.current.scrollTop=o.current.scrollHeight)},[u?.content,u?.reasoning,e.length]),(0,x.jsxs)(`section`,{"aria-label":R(r,`chat.transcript.label`),children:[(0,x.jsx)(`div`,{className:`chat-transcript`,ref:o,tabIndex:0,onScroll:()=>{let e=o.current;e&&(s.current=e.scrollHeight-e.scrollTop-e.clientHeight<80,l(!s.current))},children:e.length?e.map((e,t)=>(0,x.jsx)(Fo,{turn:e,index:t,busy:n,locale:r,onEdit:a},e.id)):(0,x.jsx)(`p`,{children:R(r,`chat.transcript.empty`)})}),c?(0,x.jsx)(N,{onClick:()=>{s.current=!0,o.current&&(o.current.scrollTop=o.current.scrollHeight),l(!1)},children:R(r,`chat.transcript.jump`)}):null]})}function Lo({conversations:e,busy:t,onPending:n,limits:r,onReplace:i,locale:a}){let o=(0,_.useRef)(oo()),[s,c]=(0,_.useState)(!1),l=(0,_.useRef)(t);l.current=t;let u=e=>{c(e),n(e)},[d,f]=(0,_.useState)(!1),[p,m]=(0,_.useState)(!1),[h,g]=(0,_.useState)(null),[v,y]=(0,_.useState)(null),b=(0,_.useRef)(null),S=e=>{b.current=e,y(e)},C=(0,_.useRef)(null),w=(0,_.useRef)(0);(0,_.useEffect)(()=>{if(!d)return;let t=setTimeout(()=>{o.current.save(e,{includeImages:p}).catch(()=>g(`chat.privacy.save_failed`))},300);return()=>clearTimeout(t)},[e,d,p]),(0,_.useEffect)(()=>{let e=o.current;return()=>{w.current++,e.close(),n(!1)}},[]);let T=async(t,n)=>{let a=++w.current;if(o.current.setEnabled(t),!t){f(!1);return}u(!0);try{let t=await o.current.load({includeImages:p});if(await Ro(t,r),a!==w.current||l.current)return;if(t.length&&e.length){S({kind:`replace-saved`,saved:t,operation:a,trigger:n});return}t.length&&i(t),f(!0)}catch{o.current.setEnabled(!1),a===w.current&&g(`chat.privacy.open_failed`)}finally{a===w.current&&u(!1)}},E=()=>{let e=++w.current;u(!0),f(!1),m(!1),o.current.setEnabled(!1),o.current.clear().then(()=>{e===w.current&&!l.current&&(i([]),g(`chat.privacy.cleared`))}).catch(()=>{e===w.current&&g(`chat.privacy.clear_failed`)}).finally(()=>{e===w.current&&(u(!1),window.setTimeout(()=>{document.activeElement===document.body&&C.current?.focus()},0))})},D=e=>{let t=b.current;if(b.current=null,y(null),t===null)return;if(t.kind===`clear`){e&&!l.current&&E();return}if(t.operation!==w.current)return;if(t.kind===`replace-saved`){if(!e)o.current.setEnabled(!1);else if(!l.current)try{i(t.saved),f(!0)}catch{o.current.setEnabled(!1),g(`chat.privacy.open_failed`)}}else if(e&&!l.current)try{i(t.imported)}catch{g(`chat.privacy.import_rejected`)}let n=t.trigger;window.setTimeout(()=>{let e=document.activeElement;n.isConnected&&!n.matches(`:disabled`)&&(e===null||e===document.body)&&n.focus()},0)},O=(e,t,n,r,i)=>v?.kind===e?(0,x.jsx)(ut,{open:!0,title:R(a,t),body:R(a,n),confirmLabel:R(a,r),cancelLabel:R(a,`common.cancel`),closeLabel:R(a,`common.close`),tone:`danger`,testId:i,onConfirm:()=>D(!0),onClose:()=>D(!1)}):null;return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(`details`,{className:`chat-privacy`,children:[(0,x.jsx)(`summary`,{children:R(a,`chat.privacy.summary`)}),(0,x.jsx)(`p`,{children:R(a,`chat.privacy.body`)}),(0,x.jsxs)(`label`,{className:`toggle`,children:[(0,x.jsx)(`input`,{type:`checkbox`,checked:d,disabled:t||s,onChange:e=>{T(e.target.checked,e.currentTarget)}}),R(a,`chat.privacy.save`)]}),(0,x.jsxs)(`label`,{className:`toggle`,children:[(0,x.jsx)(`input`,{type:`checkbox`,checked:p,disabled:t||s,onChange:e=>m(e.target.checked)}),R(a,`chat.privacy.include_images`)]}),(0,x.jsx)(`p`,{children:R(a,`chat.privacy.note`)}),(0,x.jsxs)(`div`,{className:`chat-toolbar`,children:[(0,x.jsx)(N,{disabled:t||s,onClick:()=>{try{let t=new Blob([ro(e,{includeImages:p})],{type:`application/json`}),n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=`mlxcel-conversations.json`,r.click(),setTimeout(()=>URL.revokeObjectURL(n),1e3)}catch{g(`chat.privacy.export_failed`)}},children:R(a,`chat.privacy.export`)}),(0,x.jsx)(N,{ref:C,disabled:t||s,onClick:()=>S({kind:`clear`}),children:R(a,`chat.privacy.clear`)})]}),(0,x.jsxs)(`label`,{className:`ds-field`,children:[R(a,`chat.privacy.import`),(0,x.jsx)(`input`,{type:`file`,accept:`application/json,.json`,disabled:t||s,onChange:e=>{let t=e.currentTarget,n=e.target.files?.[0];if(e.target.value=``,!n)return;if(n.size>16777216){g(`chat.privacy.import_too_large`);return}let i=++w.current;u(!0),n.text().then(async e=>{let n=io(e,{includeImages:p});await Ro(n,r),!(i!==w.current||l.current)&&S({kind:`replace-import`,imported:n,operation:i,trigger:t})}).catch(()=>{i===w.current&&g(`chat.privacy.import_rejected`)}).finally(()=>{i===w.current&&u(!1)})}})]}),h?(0,x.jsx)(L,{tone:`info`,title:R(a,`chat.privacy.title`),body:R(a,h)}):null]}),O(`replace-saved`,`chat.privacy.replace_saved.confirm.title`,`chat.privacy.replace_saved.confirm.body`,`chat.privacy.replace_saved.confirm`,`chat-replace-saved-dialog`),O(`clear`,`chat.privacy.clear.confirm.title`,`settings.clear_history.confirm.body`,`chat.privacy.clear.confirm`,`chat-clear-history-dialog`),O(`replace-import`,`chat.privacy.replace_import.confirm.title`,`chat.privacy.replace_import.confirm.body`,`chat.privacy.replace_import.confirm`,`chat-replace-import-dialog`)]})}async function Ro(e,t){for(let n of e)for(let e of n.turns)if(e.images.length){if(!t)throw Error(`Server image limits unavailable.`);e.images=await Aa(e.images.map(e=>{let t=atob(e.dataUrl.slice(e.dataUrl.indexOf(`,`)+1)),n=Uint8Array.from(t,e=>e.charCodeAt(0));return new File([n],e.name,{type:e.type})}),0,t)}}function zo(e,t){let n=Object.fromEntries(Object.entries(t).filter(([,e])=>e!==void 0&&e.trim()!==``).map(([e,t])=>[e,Number(t)]));return{...or({...e,...n})}}function W({defaults:e,draft:t,onChange:n,locale:r}){return(0,x.jsxs)(`details`,{className:`chat-parameters`,children:[(0,x.jsx)(`summary`,{children:R(r,`chat.params.summary`)}),(0,x.jsx)(`p`,{children:R(r,`chat.params.body`)}),(0,x.jsx)(`div`,{className:`chat-parameter-grid`,children:ar.map(i=>(0,x.jsx)(ot,{label:R(r,`chat.params.field`,{name:i}),value:t[i]??``,onChange:e=>n({...t,[i]:e}),hint:R(r,`chat.params.inherited`,{value:e[i]?.toString()??R(r,`chat.params.server_default`)})},i))}),(0,x.jsx)(N,{onClick:()=>n({}),children:R(r,`chat.params.clear`)})]})}var G=new Set([`en`,`ko`].map(e=>R(e,`chat.conversation.default_title`)));function Bo({locale:e}){let t=nr(),n=rr(),{defaults:r}=fr(),[i,a]=(0,_.useState)({}),o=Eo(),[s,c]=(0,_.useState)(null),[l,u]=(0,_.useState)(``),[d,f]=(0,_.useState)([]),[p,m]=(0,_.useState)(null),[h,g]=(0,_.useState)(``),[v,y]=(0,_.useState)(!1),[b,S]=(0,_.useState)(!1),[C,w]=(0,_.useState)(!1),[T,E]=(0,_.useState)(null),D=(0,_.useRef)(e);D.current=e;let O=(e,t)=>R(D.current,e,t),k=(0,_.useRef)(null),ee=(0,_.useRef)(0),A=(0,_.useRef)(!1),te=(0,_.useRef)(0),ne=(0,_.useRef)(null),j=o.find(e=>e.id===s)??null,M=t.catalog.find(e=>e.identity.id===t.selectedModelId),re=[`ready`,`streaming`,`polling`].includes(t.connection)&&M?.lifecycle.state===`ready`&&M.capabilities.some(e=>e.task===`chat`&&e.phase===`provider_ready`&&e.available),ie=re&&t.bootstrap!==null&&Object.values(t.bootstrap.media_limits).every(e=>e>0)&&M?.capabilities.some(e=>e.task===`vision_input`&&e.phase===`provider_ready`&&e.available);(0,_.useEffect)(()=>()=>{ee.current++,te.current++;let e=ne.current;e!==null&&(e.turn={...e.turn,status:`interrupted`,error:R(D.current,`chat.error.view_closed`)},e.controller.abort(),e.flush())},[]);let ae=()=>{if(v||b||C||o.length>=50)return;ee.current++;let e=ho(O(`chat.conversation.default_title`));To(e),c(e.id),u(``),f([])},oe=Co(),se=(0,_.useRef)(ae);se.current=ae,(0,_.useEffect)(()=>{wo()&&se.current()},[oe]);let ce=()=>{let e=ne.current;if(e===null)return;e.turn={...e.turn,status:`cancelled`,error:null},e.controller.abort(),e.flush();let t=++te.current;g(O(`chat.announce.stopped`)),n.refreshRuntime(e.turn.modelId).then(e=>{te.current===t&&g(O(`chat.announce.aborted_observed`,{time:e.measurements.active_requests?.measured_at??O(`chat.announce.unknown_time`)}))}).catch(()=>{te.current===t&&g(O(`chat.announce.aborted_unobserved`))})},le=async()=>{if(ne.current!==null||b||C||!re||M===void 0||!l.trim()||l.length>32e3)return;if((d.length||j?.turns.some(e=>e.images.length))&&!ie){m(O(`chat.error.vision_unsupported`));return}if(j===null&&o.length>=50){m(O(`chat.error.conversation_limit`));return}let e;try{e=zo(r,i)}catch(e){m(e instanceof Error?e.message:O(`chat.error.invalid_parameters`));return}let s=j??ho(O(`chat.conversation.default_title`));if(s.turns.length>=100){m(O(`chat.error.turn_limit`));return}c(s.id);let p=new AbortController,h=performance.now(),_={id:crypto.randomUUID(),modelId:M.identity.id,inferenceId:M.identity.inference_id,modelName:M.identity.display_name,modelRevision:M.identity.revision,prompt:l,content:``,reasoning:``,tools:[],status:`streaming`,finishReason:null,usage:null,ttftMs:null,elapsedMs:null,error:null,parameters:e,images:d.map(e=>({...e}))};s={...s,title:s.turns.length===0&&G.has(s.title)?l.slice(0,80):s.title,turns:[...s.turns,_],updatedAt:Date.now()};try{if(!t.bootstrap)throw Error(`Limits unavailable`);ka(s.turns.flatMap(e=>e.images),t.bootstrap.media_limits)}catch{m(O(`chat.error.images_exceed`));return}let v={..._.parameters,model:_.inferenceId,stream:!0,messages:La(s.systemPrompt,s.turns),stream_options:{include_usage:!0}},x=Math.min(t.bootstrap?.media_limits.max_body_bytes??0,16777216);if(new TextEncoder().encode(JSON.stringify(v)).byteLength>x){m(O(`chat.error.body_limit`));return}if(!To(s)){m(O(`chat.error.memory_budget`));return}let S=null,w=mo(),T={controller:p,turn:_,conversation:s,flush:()=>{if(S!==null&&clearTimeout(S),S=null,mo()!==w)return;let e=T.conversation;T.conversation={...T.conversation,turns:T.conversation.turns.map(e=>e.id===_.id?T.turn:e),updatedAt:Date.now()},To(T.conversation)||(p.abort(),T.conversation=e,T.turn={...e.turns.find(e=>e.id===_.id)??_,status:`error`,error:null},T.conversation={...e,turns:e.turns.map(e=>e.id===_.id?T.turn:e)},To(T.conversation),m(O(`chat.error.memory_budget_stream`)))}};a({}),ne.current=T,te.current++,y(!0),m(null),u(``),f([]),T.flush(),g(O(`chat.announce.generating`));try{await n.streamChatCompletions(_.modelId,v,{onFrame:e=>{p.signal.aborted||(T.turn=Fa(T.turn,e.data,performance.now()-h),S===null&&(S=setTimeout(T.flush,50)))}},p.signal),p.signal.aborted||(T.turn=Ia(T.turn,performance.now()-h),g(O(`chat.announce.complete`)))}catch{p.signal.aborted||(p.abort(),T.turn={...T.turn,status:`error`,elapsedMs:performance.now()-h,error:O(`chat.error.generation_failed`)},g(O(`chat.announce.failed`)))}finally{T.flush(),ne.current===T&&(ne.current=null),y(!1)}},P=()=>{let e=T;if(E(null),e===null||v||b||C||j===null||j.id!==e.conversationId||j.turns[e.index]?.id!==e.turnId)return;let{index:t}=e;u(j.turns[t].prompt),f(j.turns[t].images),To({...j,turns:j.turns.slice(0,t)}),window.setTimeout(()=>k.current?.focus(),0)},[ue,de=``]=R(e,`chat.settings.sampling`).split(`{link}`);return(0,x.jsxs)(`div`,{className:`screen-stack chat-screen`,children:[(0,x.jsx)(Ke,{title:R(e,`chat.title`),titleTestId:z(`chat.title`),description:R(e,`chat.intro`),actions:(0,x.jsx)(N,{onClick:ae,disabled:v||b||C||o.length>=50,"data-testid":z(`chat.new_conversation`),children:R(e,`chat.new_conversation`)})}),(0,x.jsxs)(`div`,{className:`chat-toolbar`,children:[(0,x.jsx)(je,{locale:e,label:R(e,`chat.conversation.label`),value:s??``,disabled:v||b||C,onChange:e=>{c(e),u(``),f([])},options:[{value:``,label:R(e,`chat.conversation.choose`)},...o.map(e=>({value:e.id,label:e.title}))]}),(0,x.jsx)(je,{locale:e,label:R(e,`chat.model.label`),value:t.selectedModelId??``,onChange:e=>n.selectModel(e||null),options:[{value:``,label:R(e,`chat.model.choose`)},...t.catalog.map(t=>({value:t.identity.id,label:`${t.identity.display_name} · ${jr(e,t.lifecycle.state)}`}))]})]}),re?null:(0,x.jsx)(L,{tone:`info`,title:R(e,`chat.no_model.title`),body:R(e,`chat.no_model.body`),action:(0,x.jsx)(`a`,{href:`#models`,children:R(e,`chat.no_model.action`)})}),j?(0,x.jsxs)(`details`,{children:[(0,x.jsx)(`summary`,{children:R(e,`chat.settings.summary`)}),(0,x.jsx)(ot,{label:R(e,`chat.settings.name`),value:j.title,disabled:v||b||C,onChange:e=>To({...j,title:e.slice(0,120)})}),(0,x.jsxs)(`label`,{className:`ds-field`,children:[R(e,`chat.settings.system_prompt`),(0,x.jsx)(`textarea`,{value:j.systemPrompt,maxLength:ja,disabled:v||b||C,onChange:e=>To({...j,systemPrompt:e.target.value})})]}),(0,x.jsxs)(`p`,{children:[ue,(0,x.jsx)(`a`,{href:`#settings`,children:R(e,`nav.settings`)}),de]}),(0,x.jsx)(N,{disabled:v||b||C,onClick:()=>{xo(o.filter(e=>e.id!==j.id)),c(null)},children:R(e,`chat.settings.delete`)})]}):null,(0,x.jsx)(W,{defaults:r,draft:i,onChange:a,locale:e}),(0,x.jsx)(Io,{turns:j?.turns??[],onEdit:e=>{if(v||b||C||j===null)return;let t=j.turns[e];t&&E({conversationId:j.id,turnId:t.id,index:e})},busy:v||b||C,locale:e}),T===null?null:(0,x.jsx)(ut,{open:!0,title:R(e,`chat.transcript.edit.confirm.title`),body:R(e,`chat.transcript.edit.confirm.body`),confirmLabel:R(e,`chat.transcript.edit.confirm`),cancelLabel:R(e,`common.cancel`),closeLabel:R(e,`common.close`),tone:`danger`,testId:`chat-edit-dialog`,onConfirm:P,onClose:()=>E(null)}),p?(0,x.jsx)(L,{title:R(e,`chat.error.title`),body:p}):null,(0,x.jsxs)(`div`,{className:`chat-composer`,children:[(0,x.jsxs)(`label`,{className:`ds-field`,children:[R(e,`chat.composer.label`),(0,x.jsx)(`textarea`,{ref:k,"aria-label":R(e,`chat.composer.label`),value:l,maxLength:ja,disabled:v||b||C,onChange:e=>u(e.target.value),onCompositionStart:()=>{A.current=!0},onCompositionEnd:()=>{A.current=!1},onKeyDown:e=>{if(!(A.current||e.nativeEvent.isComposing||e.keyCode===229)){if(Sa(e)&&!e.altKey&&!e.shiftKey&&e.key.toLowerCase()===`n`){e.preventDefault(),e.repeat||ae();return}e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),le())}}})]}),(0,x.jsx)(`p`,{children:R(e,`chat.composer.hint`,{count:String(l.length),max:String(ja)})}),ie?(0,x.jsxs)(`label`,{className:`ds-field`,children:[R(e,`chat.images.label`),(0,x.jsx)(`input`,{type:`file`,accept:`image/png,image/jpeg,image/webp`,multiple:!0,disabled:v||b||C,onChange:e=>{let n=e.target.files;if(n&&t.bootstrap){let e=++ee.current;w(!0),Aa(n,d.length,t.bootstrap.media_limits,d).then(t=>{e===ee.current&&f(e=>[...e,...t])}).catch(()=>m(O(`chat.error.images_invalid`))).finally(()=>{e===ee.current&&w(!1)})}e.target.value=``}})]}):(0,x.jsx)(`p`,{children:R(e,`chat.images.unsupported`)}),(0,x.jsx)(`div`,{className:`chat-images`,children:d.map((t,n)=>(0,x.jsxs)(`figure`,{children:[(0,x.jsx)(`img`,{src:t.dataUrl,alt:t.name}),(0,x.jsx)(N,{disabled:v||b||C,onClick:()=>f(d.filter((e,t)=>n!==t)),children:R(e,`chat.images.remove`,{name:t.name})})]},`${t.name}-${n}`))}),(0,x.jsxs)(`div`,{className:`chat-toolbar`,children:[(0,x.jsx)(N,{tone:`primary`,disabled:!re||v||b||C||!l.trim(),onClick:()=>{le()},children:R(e,`common.send`)}),(0,x.jsx)(N,{disabled:!v,onClick:ce,children:R(e,`chat.stop`)})]})]}),(0,x.jsx)(`p`,{role:`status`,"aria-live":`polite`,"aria-atomic":`true`,children:h}),(0,x.jsx)(Lo,{conversations:o,busy:v||C,onPending:S,limits:t.bootstrap?.media_limits,onReplace:e=>{xo(e),c(null)},locale:e})]})}var Vo=[`models`,`chat`,`activity`,`settings`,`gallery`];function Ho(e){return e.auth.status===`authenticated`&&e.connection!==`schema-mismatch`}function Uo(){let e=window.location.hash.slice(1).replace(/^\//,``);return Vo.includes(e)?e:`models`}function Wo(){let e=nr(),t=rr(),[n,r]=(0,_.useState)(Uo),[i,a]=(0,_.useState)(Di),[o,s]=(0,_.useState)(null),[c,l]=(0,_.useState)(null),u=(0,_.useRef)(0);(0,_.useEffect)(()=>()=>{u.current+=1},[]),(0,_.useEffect)(()=>{let e=()=>r(Uo());return window.addEventListener(`hashchange`,e),()=>window.removeEventListener(`hashchange`,e)},[]),(0,_.useEffect)(()=>{if(Ai(document.documentElement,i),Oi(i),i.colorScheme===`system`)return _i(e=>Ai(document.documentElement,i,e))},[i]),(0,_.useEffect)(()=>{let e=()=>{document.documentElement.dataset.documentHidden=String(document.hidden)};return e(),document.addEventListener(`visibilitychange`,e),()=>document.removeEventListener(`visibilitychange`,e)},[]),(0,_.useEffect)(()=>{e.auth.status===`authenticated`&&l(null)},[e.auth.status]),(0,_.useEffect)(()=>{e.auth.status===`signed-out`&&xo([])},[e.auth.status]);let d=e=>{r(e),window.history.replaceState(null,``,`#${e}`)},f=e=>{let n=u.current+1;u.current=n,l(null),t.login(e).catch(e=>{u.current===n&&(e instanceof DOMException&&e.name===`AbortError`||l(hr(e)))})},p=()=>{u.current+=1,l(null),t.logout()},m=()=>{l(null),t.refresh()},h=()=>{p(),window.location.reload()},g=n=>{let r=br(e,n);r!==e.selectedModelId&&t.selectModel(r),d(`models`),s(null)},v=()=>{Ho(e)&&So(),d(`chat`),s(null)},y=yr(e),b=e.auth.status===`authenticated`&&e.catalogSequence!==null?y.map(e=>({id:e.identity.id,name:e.identity.display_name,state:e.lifecycle.state,stateLabel:jr(i.locale,e.lifecycle.state)})):null,S=Go(n,i,a,{snapshot:e,authFailure:c,login:f,logout:p,retry:m,recoverSchema:h});return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(ti,{locale:i.locale,route:n,onRouteChange:d,onCommand:()=>s(`command`),onHelp:()=>s(`help`),onNewChat:v,onOpenModel:g,loadedModels:b,connection:{label:xr(i.locale,e),state:e.connection,details:Sr(i.locale,e)},sessionAction:e.auth.tokenPresent?(0,x.jsx)(P,{label:R(i.locale,`toolbar.logout`),icon:`key`,onClick:p,"data-testid":z(`toolbar.logout`)}):null,inspector:null,children:S}),(0,x.jsx)(Qr,{open:o===`command`,locale:i.locale,catalog:e.catalog,loaded:y,onClose:()=>s(null),onNavigate:e=>{d(e),s(null)},onNewChat:v,onOpenModel:g}),(0,x.jsxs)(lt,{open:o===`help`,title:R(i.locale,`help.title`),onClose:()=>s(null),testId:`help-dialog`,closeLabel:R(i.locale,`common.close`),children:[(0,x.jsx)(`p`,{"data-testid":z(`help.body`),children:R(i.locale,`help.body`)}),(0,x.jsx)(`ul`,{className:`shortcut-list`,"data-testid":`help-shortcuts`,children:ei.map(e=>(0,x.jsxs)(`li`,{"data-testid":`help-shortcut-${e.id}`,children:[(0,x.jsx)(`span`,{className:`shortcut-keys`,children:e.keys.map((t,n)=>(0,x.jsxs)(_.Fragment,{children:[n>0?` ${e.separator} `:null,(0,x.jsx)(`kbd`,{children:t})]},t))}),(0,x.jsx)(`span`,{children:R(i.locale,e.key)})]},e.id))})]})]})}function Go(e,t,n,r){return e===`models`?(0,x.jsx)(Ko,{locale:t.locale,context:r}):e===`chat`?(0,x.jsx)(qo,{locale:t.locale,context:r}):e===`activity`?(0,x.jsx)(Jo,{locale:t.locale,context:r}):e===`settings`?(0,x.jsx)(Yo,{appearance:t,setAppearance:n}):(0,x.jsx)(_a,{locale:t.locale})}function Ko(e){return e.context.snapshot.auth.status===`authenticated`&&e.context.snapshot.connection!==`schema-mismatch`?(0,x.jsx)(fa,{locale:e.locale}):(0,x.jsx)(wr,{locale:e.locale,title:R(e.locale,`models.title`),titleTestId:z(`models.title`),snapshot:e.context.snapshot,authFailure:e.context.authFailure,onLogin:e.context.login,onLogout:e.context.logout,onRetry:e.context.retry,onRecoverSchema:e.context.recoverSchema})}function qo(e){return e.context.snapshot.auth.status===`authenticated`&&e.context.snapshot.connection!==`schema-mismatch`?(0,x.jsx)(Bo,{locale:e.locale}):(0,x.jsx)(wr,{locale:e.locale,title:R(e.locale,`chat.title`),titleTestId:z(`chat.title`),snapshot:e.context.snapshot,authFailure:e.context.authFailure,onLogin:e.context.login,onLogout:e.context.logout,onRetry:e.context.retry,onRecoverSchema:e.context.recoverSchema})}function Jo(e){return e.context.snapshot.auth.status===`authenticated`&&![`schema-mismatch`,`forbidden`,`unauthorized`].includes(e.context.snapshot.connection)?(0,x.jsx)(Gi,{locale:e.locale}):(0,x.jsx)(wr,{locale:e.locale,title:R(e.locale,`activity.title`),titleTestId:z(`activity.title`),snapshot:e.context.snapshot,authFailure:e.context.authFailure,onLogin:e.context.login,onLogout:e.context.logout,onRetry:e.context.retry,onRecoverSchema:e.context.recoverSchema})}function Yo(e){let t=t=>e.setAppearance({...e.appearance,...t});return(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsx)(Ke,{title:R(e.appearance.locale,`settings.title`),titleTestId:z(`settings.title`),description:R(e.appearance.locale,`settings.browser_only`),descriptionTestId:z(`settings.appearance`)}),(0,x.jsxs)(`div`,{className:`settings-grid`,children:[(0,x.jsx)(je,{locale:e.appearance.locale,label:R(e.appearance.locale,`settings.theme`),value:e.appearance.themeFamily,onChange:e=>t({themeFamily:e}),options:[{value:`mlxcel`,label:R(e.appearance.locale,`settings.theme.mlxcel`)},{value:`glass`,label:R(e.appearance.locale,`settings.theme.glass`)}],testId:z(`settings.theme`)}),(0,x.jsx)(je,{locale:e.appearance.locale,label:R(e.appearance.locale,`settings.color_scheme`),value:e.appearance.colorScheme,onChange:e=>t({colorScheme:e}),options:[{value:`system`,label:R(e.appearance.locale,`settings.color_scheme.system`)},{value:`light`,label:R(e.appearance.locale,`settings.color_scheme.light`)},{value:`dark`,label:R(e.appearance.locale,`settings.color_scheme.dark`)}],testId:z(`settings.color_scheme`)}),(0,x.jsx)(je,{locale:e.appearance.locale,label:R(e.appearance.locale,`settings.material`),value:e.appearance.material,onChange:e=>t({material:e}),options:[{value:`glass`,label:R(e.appearance.locale,`settings.material.glass`)},{value:`tinted`,label:R(e.appearance.locale,`settings.material.tinted`)},{value:`opaque`,label:R(e.appearance.locale,`settings.material.opaque`)}],testId:z(`settings.material`)}),(0,x.jsx)(je,{locale:e.appearance.locale,label:R(e.appearance.locale,`settings.locale`),value:e.appearance.locale,onChange:e=>t({locale:e}),options:[{value:`en`,label:R(e.appearance.locale,`settings.locale.en`)},{value:`ko`,label:R(e.appearance.locale,`settings.locale.ko`)}],testId:z(`settings.locale`)}),(0,x.jsx)(je,{locale:e.appearance.locale,label:R(e.appearance.locale,`settings.high_contrast`),value:e.appearance.highContrast,onChange:e=>t({highContrast:e}),options:[{value:`system`,label:R(e.appearance.locale,`settings.high_contrast.system`)},{value:`on`,label:R(e.appearance.locale,`settings.high_contrast.on`)},{value:`off`,label:R(e.appearance.locale,`settings.high_contrast.off`)}],testId:z(`settings.high_contrast`)}),(0,x.jsxs)(`label`,{className:`ds-field`,children:[(0,x.jsxs)(`span`,{children:[R(e.appearance.locale,`settings.glass_intensity`),`: `,e.appearance.glassIntensity]}),(0,x.jsx)(`input`,{type:`range`,min:`0`,max:`100`,value:e.appearance.glassIntensity,onChange:e=>t({glassIntensity:Number(e.currentTarget.value)}),"data-testid":z(`settings.glass_intensity`)})]}),(0,x.jsx)(Xo,{label:R(e.appearance.locale,`settings.reduce_motion`),checked:e.appearance.reduceMotion,onChange:e=>t({reduceMotion:e}),testId:z(`settings.reduce_motion`)}),(0,x.jsx)(Xo,{label:R(e.appearance.locale,`settings.reduce_transparency`),checked:e.appearance.reduceTransparency,onChange:e=>t({reduceTransparency:e}),testId:z(`settings.reduce_transparency`)})]}),(0,x.jsx)(L,{tone:`info`,title:R(e.appearance.locale,`settings.browser_only`),body:R(e.appearance.locale,`settings.browser_only.body`),testId:z(`settings.browser_only`)}),(0,x.jsx)(Yr,{locale:e.appearance.locale})]})}function Xo(e){return(0,x.jsxs)(`label`,{className:`toggle`,children:[(0,x.jsx)(`input`,{type:`checkbox`,checked:e.checked,onChange:t=>e.onChange(t.currentTarget.checked),"data-testid":e.testId}),(0,x.jsx)(`span`,{children:e.label})]})}var Zo=document.getElementById(`root`);if(Zo===null)throw Error(`Missing #root element for mlxcel WebUI.`);(0,v.createRoot)(Zo).render((0,x.jsx)(_.StrictMode,{children:(0,x.jsx)(tr,{children:(0,x.jsx)(Wo,{})})}));export{c as i,b as n,u as r,R as t}; \ No newline at end of file diff --git a/src/webui/assets/assets/index-CHdEXEMP.css b/src/webui/assets/assets/index-jRmdkkyk.css similarity index 61% rename from src/webui/assets/assets/index-CHdEXEMP.css rename to src/webui/assets/assets/index-jRmdkkyk.css index 1cdb23f5f..2d2f6c996 100644 --- a/src/webui/assets/assets/index-CHdEXEMP.css +++ b/src/webui/assets/assets/index-jRmdkkyk.css @@ -1 +1 @@ -:root{--token-borderRadius:.375rem;--token-borderRadiusLG:.5rem;--token-borderRadiusSM:.25rem;--token-borderRadiusXL:.75rem;--token-controlHeightSM:2rem;--token-controlHeight:2.5rem;--token-controlHeightLG:2.75rem;--token-boxShadow:0 1px 2px 0 #00000008, 0 1px 6px -1px #00000005, 0 2px 4px 0 #00000005;--token-boxShadowSecondary:0 6px 16px 0 #00000014, 0 3px 6px -4px #0000001f, 0 9px 28px 8px #0000000d;--token-boxShadowTertiary:0 1px 3px #0000001a;--token-buttonActiveTransform:scale(.97);--token-buttonBorderRadius:.375rem;--token-buttonHoverTransform:translateY(-1px);--token-buttonDangerBg:transparent;--token-buttonDangerBgActive:#ff4d4f33;--token-buttonDangerBgHover:#ff4d4f1a;--token-buttonDangerBorder:1px solid #c82333;--token-buttonDangerShadow:none;--token-buttonDangerText:#c82333;--token-buttonGhostBackdrop:none;--token-buttonGhostBg:transparent;--token-buttonGhostBgActive:#f5f5f5;--token-buttonGhostBgHover:#ff7a000f;--token-buttonGhostBorder:1px solid transparent;--token-buttonGhostBorderHover:1px solid transparent;--token-buttonGhostShadow:none;--token-buttonGhostShadowHover:none;--token-buttonPrimaryBackdrop:none;--token-buttonPrimaryBg:var(--token-colorPrimary);--token-buttonPrimaryBgHover:#e86e00;--token-buttonPrimaryBorder:none;--token-buttonPrimaryShadow:0 2px 4px #ff7a0033;--token-buttonPrimaryShadowHover:0 4px 8px #ff7a0040;--token-buttonSecondaryBackdrop:none;--token-buttonSecondaryBg:transparent;--token-buttonSecondaryBgActive:#f5f5f5;--token-buttonSecondaryBgHover:#ff7a000f;--token-buttonSecondaryBorder:1px solid var(--token-colorBorder);--token-buttonSecondaryBorderHover:1px solid #ff7a004d;--token-buttonSecondaryShadow:none;--token-buttonSuccessBackdrop:none;--token-buttonSuccessBg:var(--token-colorSuccess);--token-buttonSuccessBgHover:#006654;--token-buttonSuccessBorder:none;--token-buttonSuccessShadow:0 2px 4px #00bd9b33;--token-colorBgContainer:#fff;--token-colorBgElevated:#fff;--token-colorBgLayout:#f5f5f5;--token-colorBgMask:#00000073;--token-colorBgTextActive:#00000014;--token-colorBgTextHover:#0000000a;--token-colorBorder:#d9d9d9;--token-colorBorderSecondary:#e5e7eb;--token-colorFillQuaternary:#fafafa;--token-colorFillSecondary:#f3f4f6;--token-colorFillTertiary:#f9fafb;--token-colorError:#c82333;--token-colorInfo:#06c;--token-colorLink:#ff7a00;--token-colorLinkHover:#7c3aed;--token-colorPrimary:#ff7a00;--token-colorPrimaryActive:#cc6200;--token-colorPrimaryBg:#ff7a001a;--token-colorPrimaryBgHover:#ff7a0029;--token-colorPrimaryBorder:#ff7a0033;--token-colorSuccess:#007a63;--token-colorSuccessActive:#005244;--token-colorSuccessBg:#00bd9b0d;--token-colorSuccessBorder:#00bd9b66;--token-colorSuccessBorderHover:#00bd9b99;--token-colorSuccessBoxShadow:0 4px 12px #00bd9b26;--token-colorWarning:#9a5d00;--token-colorText:#141414;--token-colorTextDisabled:#767676;--token-colorTextPlaceholder:#767676;--token-colorTextQuaternary:#bfbfbf;--token-colorTextSecondary:#595959;--token-colorTextTertiary:#737373;--token-focusRingColor:#b95b06;--token-focusRingOffset:2px;--token-focusRingStyle:solid;--token-focusRingWidth:2px;--token-fontFamily:"Ubuntu Sans", "Pretendard Variable", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;--token-fontSize:.875rem;--token-fontSizeLG:1rem;--token-fontSizeSM:.75rem;--token-fontSizeXL:1.25rem;--token-fontSizeXXL:1.5rem;--token-fontSizeXXS:.5rem;--token-marginXXS:4px;--token-padding:.75rem;--token-paddingLG:1.5rem;--token-paddingMD:1rem;--token-paddingSM:.5rem;--token-paddingXL:2rem;--token-paddingXS:.25rem;--token-paddingXXS:.125rem;--token-scrollbarSize:.5rem;--token-scrollbarRadius:.25rem;--token-motionDurationFast:.1s;--token-motionDurationMid:.2s;--token-motionDurationSlow:.3s;--token-themeTransitionDuration:.25s;--token-themeTransitionTiming:ease-in-out;--token-tabActiveBg:#ff7a001a;--token-tabFocusShadow:0 0 0 3px #ff7a0026;--token-tabHoverBg:var(--token-colorFillSecondary);--token-zIndexDrawer:1100;--token-zIndexDrawerContent:1101;--token-zIndexPopover:1150;--token-zIndexTooltip:1300;--token-fontSizeHeading1:2rem;--token-fontSizeHeading2:1.5rem;--token-fontSizeHeading3:1.25rem;--token-fontSizeHeading4:1rem;--token-fontSizeDisplay4:1.75rem;--token-boxShadowDrawerRight:-4px 0 20px #00000026;--token-buttonPrimaryBgActive:var(--token-colorPrimaryActive);--token-buttonSuccessBgActive:var(--token-colorSuccessActive);--token-buttonDangerShadowHover:var(--token-buttonDangerShadow);--token-buttonSuccessShadowHover:var(--token-buttonSuccessShadow);--token-buttonSecondaryShadowHover:0 2px 6px #0000000f, inset 0 1px 0 #fffc;scrollbar-width:thin;scrollbar-color:var(--token-colorBorder,#d9d9d9) transparent}::-webkit-scrollbar{width:var(--token-scrollbarSize,.5rem);height:var(--token-scrollbarSize,.5rem)}::-webkit-scrollbar-track{background:0 0}::-webkit-scrollbar-thumb{background-color:var(--token-colorBorder,#d9d9d9);border-radius:var(--token-scrollbarRadius,.25rem)}::-webkit-scrollbar-thumb:hover{background-color:var(--token-colorTextTertiary,#737373)}[data-theme=mlxcel-light],[data-theme=mlxcel-dark],[data-theme=glass-light],[data-theme=glass-dark]{--token-boxShadow:var(--shadow-card);--token-boxShadowDrawerRight:var(--shadow-card);--token-boxShadowSecondary:var(--shadow-card);--token-boxShadowTertiary:var(--shadow-chrome);--token-buttonActiveTransform:none;--token-buttonDangerBg:var(--button-danger-fill);--token-buttonDangerBgActive:var(--button-danger-fill-active);--token-buttonDangerBgHover:var(--button-danger-fill-active);--token-buttonDangerBorder:1px solid var(--color-separator);--token-buttonDangerShadow:none;--token-buttonDangerShadowHover:none;--token-buttonDangerText:white;--token-buttonGhostBackdrop:none;--token-buttonGhostBg:transparent;--token-buttonGhostBgActive:var(--color-selection);--token-buttonGhostBgHover:var(--color-selection);--token-buttonGhostBorder:1px solid var(--color-separator);--token-buttonGhostBorderHover:1px solid var(--color-separator);--token-buttonGhostShadow:none;--token-buttonGhostShadowHover:none;--token-buttonHoverTransform:none;--token-buttonPrimaryBackdrop:none;--token-buttonPrimaryBg:var(--button-primary-fill);--token-buttonPrimaryBgActive:var(--button-primary-fill-active);--token-buttonPrimaryBgHover:var(--button-primary-fill-active);--token-buttonPrimaryBorder:1px solid var(--color-separator);--token-buttonPrimaryShadow:none;--token-buttonPrimaryShadowHover:none;--token-buttonSecondaryBackdrop:none;--token-buttonSecondaryBg:var(--material-control-bg);--token-buttonSecondaryBgActive:var(--color-selection);--token-buttonSecondaryBgHover:var(--color-selection);--token-buttonSecondaryBorder:1px solid var(--color-separator);--token-buttonSecondaryBorderHover:1px solid var(--color-separator);--token-buttonSecondaryShadow:none;--token-buttonSecondaryShadowHover:none;--token-buttonSuccessBackdrop:none;--token-buttonSuccessBg:var(--color-success);--token-buttonSuccessBgActive:var(--color-success);--token-buttonSuccessBgHover:var(--color-success);--token-buttonSuccessBorder:1px solid var(--color-separator);--token-buttonSuccessShadow:none;--token-buttonSuccessShadowHover:none;--token-colorBgContainer:var(--color-bg-elevated);--token-colorBgElevated:var(--color-bg-elevated);--token-colorBgLayout:var(--color-bg);--token-colorBgMask:#080a0e6b;--token-colorBgTextActive:var(--color-selection);--token-colorBgTextHover:var(--color-selection);--token-colorBorder:var(--color-separator);--token-colorBorderSecondary:var(--color-separator);--token-colorError:var(--color-error);--token-colorFillQuaternary:var(--color-bg-neutral);--token-colorFillSecondary:var(--color-bg-neutral);--token-colorFillTertiary:var(--color-bg-neutral);--token-colorInfo:var(--color-focus);--token-colorLink:var(--color-focus);--token-colorLinkHover:var(--color-focus);--token-colorPrimary:var(--color-focus);--token-colorPrimaryActive:var(--color-focus);--token-colorPrimaryBg:var(--color-selection);--token-colorPrimaryBgHover:var(--color-selection);--token-colorPrimaryBorder:var(--color-separator);--token-colorSuccess:var(--color-success);--token-colorSuccessActive:var(--color-success);--token-colorSuccessBg:var(--color-success-bg);--token-colorSuccessBorder:var(--color-separator);--token-colorSuccessBorderHover:var(--color-separator);--token-colorSuccessBoxShadow:none;--token-colorText:var(--color-text);--token-colorTextDisabled:var(--color-muted);--token-colorTextPlaceholder:var(--color-muted);--token-colorTextQuaternary:var(--color-muted);--token-colorTextSecondary:var(--color-muted);--token-colorTextTertiary:var(--color-muted);--token-colorWarning:var(--color-warning);--token-focusRingColor:var(--color-focus);--token-tabActiveBg:var(--color-bg-elevated);--token-tabFocusShadow:var(--focus-ring);--token-tabHoverBg:var(--color-selection)}[data-theme=mlxcel-light]{--color-bg:#f3f4f6;--color-bg-elevated:#fff;--color-bg-neutral:#f8f8fa;--color-text:#151a24;--color-muted:#59647a;--color-separator:#212a3d1f;--color-focus:#245bd8;--color-selection:#242a3714;--color-warning:#8a5200;--color-warning-bg:#fff4d8;--color-error:#b42318;--color-error-bg:#fff0ed;--color-success:#137333;--color-success-bg:#eaf7ee;--material-glass-bg:rgba(248, 249, 251, var(--material-glass-alpha));--material-content-bg:#ffffffd1;--material-control-bg:#ffffff94;--shadow-chrome:0 1px 0 #ffffff9e inset;--shadow-card:0 12px 36px #1f253412}[data-theme=mlxcel-dark]{--color-bg:#0e1117;--color-bg-elevated:#181d27;--color-bg-neutral:#111722;--color-text:#f5f7fb;--color-muted:#aeb8c9;--color-separator:#ffffff1f;--color-focus:#9dbdff;--color-selection:#ffffff1a;--color-warning:#ffd28a;--color-warning-bg:#8b5c0038;--color-error:#ffb4a8;--color-error-bg:#982b1c3d;--color-success:#9be6b0;--color-success-bg:#196c3738;--material-glass-bg:rgba(24, 28, 36, var(--material-glass-alpha));--material-content-bg:#191d26d6;--material-control-bg:#ffffff14;--shadow-chrome:0 1px 0 #ffffff14 inset;--shadow-card:0 14px 40px #00000038}[data-theme=mlxcel-light],[data-theme=mlxcel-dark]{--button-primary-fill:#245bd8;--button-primary-fill-active:#1c4dbc;--button-danger-fill:#c6352b;--button-danger-fill-active:#aa2b23}[data-theme=glass-light]{--color-bg:#e6ebf3;--color-bg-elevated:#fbfbfd;--color-bg-neutral:#f1f2f6;--color-text:#1d1d1f;--color-muted:#545458;--color-separator:#3c3c4324;--color-focus:#0058b9;--color-selection:#0058b91a;--color-warning:#8a4f00;--color-warning-bg:#ff95001f;--color-error:#b3261e;--color-error-bg:#ff3b301a;--color-success:#1b6f3c;--color-success-bg:#34c7591f;--material-glass-bg:linear-gradient(180deg, #ffffff5c, #fff0 64px), rgba(248, 249, 252, var(--material-glass-alpha));--material-content-bg:#fffffff0;--material-control-bg:linear-gradient(180deg, #ffffff80, #fff0 60%), #7878801f;--shadow-chrome:inset 0 1px 0 #ffffffb8;--shadow-card:0 1px 2px #0f172a0a, 0 10px 30px #0f172a12;--shadow-popover:0 12px 40px #0000001f, 0 4px 12px #0000000f;--glass-edge:#ffffff26;--glass-highlight:linear-gradient(180deg, #ffffff2e 0%, #ffffff0d 40%, transparent 100%);--glass-button-shadow:0 1px 3px #0058b933;--glass-danger-shadow:0 1px 3px #b3261e33;--button-primary-solid:#0058b9;--button-primary-fill-active:#004a9c;--button-danger-solid:#b3261e;--button-danger-fill-active:#99201a}[data-theme=glass-dark]{--color-bg:#0b0d12;--color-bg-elevated:#1c1c1f;--color-bg-neutral:#232327;--color-text:#f5f5f7;--color-muted:#b8b8bc;--color-separator:#ffffff1f;--color-focus:#6cb2ff;--color-selection:#409cff2e;--color-warning:#ffb340;--color-warning-bg:#ff9f0a24;--color-error:#ff7b72;--color-error-bg:#ff453a29;--color-success:#4cd964;--color-success-bg:#32d74b24;--material-glass-bg:linear-gradient(180deg, #ffffff14, #fff0 64px), rgba(30, 30, 34, var(--material-glass-alpha));--material-content-bg:#242428f0;--material-control-bg:linear-gradient(180deg, #ffffff1a, #fff0 60%), #ffffff1a;--shadow-chrome:inset 0 1px 0 #ffffff24;--shadow-card:0 1px 2px #0000004d, 0 12px 32px #00000047;--shadow-popover:0 12px 40px #00000073, 0 4px 12px #0000004d;--glass-edge:#ffffff1a;--glass-highlight:linear-gradient(180deg, #ffffff26 0%, #ffffff0a 40%, transparent 100%);--glass-button-shadow:0 1px 3px #00000059;--glass-danger-shadow:0 1px 3px #00000059;--button-primary-solid:#0a5bc0;--button-primary-fill-active:#0a4ea6;--button-danger-solid:#b3261e;--button-danger-fill-active:#99201a}[data-theme=glass-light],[data-theme=glass-dark]{--button-primary-fill:var(--glass-highlight), var(--button-primary-solid);--button-danger-fill:var(--glass-highlight), var(--button-danger-solid);--token-boxShadowSecondary:var(--shadow-popover);--token-buttonActiveTransform:scale(.985);--token-buttonDangerBorder:1px solid var(--glass-edge);--token-buttonDangerShadow:var(--glass-danger-shadow);--token-buttonDangerShadowHover:var(--glass-danger-shadow);--token-buttonPrimaryBorder:1px solid var(--glass-edge);--token-buttonPrimaryShadow:var(--glass-button-shadow);--token-buttonPrimaryShadowHover:var(--glass-button-shadow);--token-buttonSecondaryShadow:var(--shadow-chrome);--token-buttonSecondaryShadowHover:var(--shadow-chrome);--token-colorBgMask:#080a0e52}:root[data-theme-family=glass][data-material=opaque],:root[data-theme-family=glass][data-reduce-transparency=true],:root[data-theme-family=glass][data-backdrop-filter=unsupported],:root[data-theme-family=glass][data-high-contrast=on]{--material-content-bg:var(--color-bg-elevated);--material-control-bg:var(--color-bg-neutral);--button-primary-fill:var(--button-primary-solid);--button-danger-fill:var(--button-danger-solid)}@media (prefers-reduced-transparency:reduce){:root[data-theme-family=glass]{--material-content-bg:var(--color-bg-elevated);--material-control-bg:var(--color-bg-neutral);--button-primary-fill:var(--button-primary-solid);--button-danger-fill:var(--button-danger-solid)}}@media (prefers-contrast:more){:root[data-theme-family=glass]:not([data-high-contrast=off]){--material-content-bg:var(--color-bg-elevated);--material-control-bg:var(--color-bg-neutral);--button-primary-fill:var(--button-primary-solid);--button-danger-fill:var(--button-danger-solid)}}:root[data-theme-family=glass][data-reduce-motion=true]{--token-buttonActiveTransform:none}@media (prefers-reduced-motion:reduce){:root[data-theme-family=glass]{--token-buttonActiveTransform:none}}.settings-sections{overflow-wrap:anywhere;min-width:0}.settings-sections .ds-field{min-width:0}.button{font-family:var(--token-fontFamily,"Ubuntu Sans", "Pretendard Variable", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif);border-radius:var(--token-buttonBorderRadius,var(--token-borderRadius,.375rem));cursor:pointer;transition:background var(--token-motionDurationFast,.1s) ease-out, border-color var(--token-motionDurationFast,.1s) ease-out, box-shadow var(--token-motionDurationMid,.2s) ease-out, transform .15s cubic-bezier(.25, .46, .45, .94), color var(--token-motionDurationFast,.1s) ease-out, opacity var(--token-motionDurationFast,.1s) ease-out;white-space:nowrap;min-height:var(--token-controlHeightLG,2.75rem);border:1px solid #0000;justify-content:center;align-items:center;gap:.375rem;font-weight:500;display:inline-flex;position:relative}.button:disabled{opacity:.6;cursor:not-allowed}.button:focus-visible{outline:var(--token-focusRingWidth,2px) var(--token-focusRingStyle,solid) var(--token-focusRingColor,var(--token-colorPrimary));outline-offset:var(--token-focusRingOffset,2px)}.button--full-width{width:100%}.button.button--inline{--token-buttonHoverTransform:none;--token-buttonActiveTransform:none;--token-buttonGhostBorder:none;--token-buttonGhostBorderHover:none;--token-buttonSecondaryBorder:none;--token-buttonSecondaryBorderHover:none;--token-buttonPrimaryBorder:none;--token-buttonDangerBorder:none;min-height:auto;transition:background-color var(--token-motionDurationFast,.1s) ease-out, color var(--token-motionDurationFast,.1s) ease-out;line-height:1}.button--inline{justify-content:flex-start}.button.button--inline>svg{flex-shrink:0;display:block}.button.button--inline:hover:not(:disabled),.button.button--inline:active:not(:disabled){box-shadow:none!important;transform:none!important}.button--xsmall{font-size:var(--token-fontSizeSM,.75rem);gap:.1875rem;min-height:1.75rem;padding:.125rem .375rem}.button--small{padding:var(--token-paddingXS,.25rem) var(--token-paddingSM,.5rem);font-size:var(--token-fontSizeSM,.75rem);min-height:var(--token-controlHeightSM,2rem);gap:.25rem}.button--medium{padding:var(--token-paddingXS,.25rem) var(--token-padding,.75rem);font-size:var(--token-fontSize,.875rem);gap:.375rem}.button--large{padding:var(--token-paddingSM,.5rem) var(--token-paddingMD,1rem);font-size:var(--token-fontSize,.875rem);gap:.5rem}.button--icon-only{padding:var(--token-paddingXS,.25rem);aspect-ratio:1}.button--icon-only.button--xsmall{padding:.125rem}.button--icon-only.button--small{padding:var(--token-paddingXS,.25rem)}.button--icon-only.button--large{padding:var(--token-paddingSM,.5rem)}.button--circle{aspect-ratio:1;padding:var(--token-paddingXS,.25rem);border-radius:50%}.button--circle.button--xsmall{padding:.125rem}.button--circle.button--small{padding:var(--token-paddingXS,.25rem)}.button--circle.button--large{padding:var(--token-paddingSM,.5rem)}.button--primary{background:var(--token-buttonPrimaryBg,linear-gradient(180deg, #fff3 0%, transparent 50%), #8b5cf6);color:#fff;border:var(--token-buttonPrimaryBorder,none);box-shadow:var(--token-buttonPrimaryShadow,0 2px 6px #8b5cf640, inset 0 1px 1px #fff3);-webkit-backdrop-filter:var(--token-buttonPrimaryBackdrop,none)}.button--primary:hover:not(:disabled){background:var(--token-buttonPrimaryBgHover,linear-gradient(180deg, #ffffff40 0%, transparent 50%), #7c3aed);box-shadow:var(--token-buttonPrimaryShadowHover,0 4px 10px #8b5cf64d, inset 0 1px 1px #ffffff40);transform:var(--token-buttonHoverTransform,translateY(-1px))}.button--primary:active:not(:disabled){background:var(--token-buttonPrimaryBgActive,var(--token-colorPrimaryActive,#6d28d9));transform:var(--token-buttonActiveTransform,scale(.97));box-shadow:var(--token-buttonPrimaryShadow,0 2px 6px #8b5cf640, inset 0 1px 1px #fff3)}.button--secondary{background:var(--token-buttonSecondaryBg,#8b5cf60a);color:var(--token-colorTextSecondary,#595959);border:var(--token-buttonSecondaryBorder,1px solid #8b5cf633);box-shadow:var(--token-buttonSecondaryShadow,0 1px 3px #0000000a, inset 0 1px 0 #fffc);-webkit-backdrop-filter:var(--token-buttonSecondaryBackdrop,none)}.button--secondary:hover:not(:disabled){background:var(--token-buttonSecondaryBgHover,#8b5cf614);border:var(--token-buttonSecondaryBorderHover,1px solid #8b5cf64d);color:var(--token-colorText,#141414);box-shadow:var(--token-buttonSecondaryShadowHover,var(--token-buttonSecondaryShadow,0 1px 3px #0000000a, inset 0 1px 0 #fffc));transform:var(--token-buttonHoverTransform,translateY(-1px))}.button--secondary:active:not(:disabled){background:var(--token-buttonSecondaryBgActive,var(--token-colorBgLayout,#f5f5f5));transform:var(--token-buttonActiveTransform,scale(.97));box-shadow:var(--token-buttonSecondaryShadow,0 1px 3px #0000000a, inset 0 1px 0 #fffc)}.button--danger{background:var(--token-buttonDangerBg,transparent);color:var(--token-buttonDangerText,var(--token-colorError,#c82333));border:var(--token-buttonDangerBorder,1px solid #c82333);box-shadow:var(--token-buttonDangerShadow,none)}.button--danger:hover:not(:disabled){background:var(--token-buttonDangerBgHover,#ff4d4f1a);border-color:var(--token-colorError,#c82333);box-shadow:var(--token-buttonDangerShadowHover,var(--token-buttonDangerShadow,none));transform:var(--token-buttonHoverTransform,translateY(-1px))}.button--danger:active:not(:disabled){background:var(--token-buttonDangerBgActive,#ff4d4f33);transform:var(--token-buttonActiveTransform,scale(.97));box-shadow:var(--token-buttonDangerShadow,none)}.button--success{background:var(--token-buttonSuccessBg,linear-gradient(180deg, #fff3 0%, transparent 50%), #007a63);color:#fff;border:var(--token-buttonSuccessBorder,none);box-shadow:var(--token-buttonSuccessShadow,0 2px 6px #00bd9b40, inset 0 1px 1px #fff3);-webkit-backdrop-filter:var(--token-buttonSuccessBackdrop,none)}.button--success:hover:not(:disabled){background:var(--token-buttonSuccessBgHover,linear-gradient(180deg, #ffffff40 0%, transparent 50%), #006654);box-shadow:var(--token-buttonSuccessShadowHover,var(--token-buttonSuccessShadow,0 2px 6px #00bd9b40, inset 0 1px 1px #fff3));transform:var(--token-buttonHoverTransform,translateY(-1px))}.button--success:active:not(:disabled){background:var(--token-buttonSuccessBgActive,var(--token-colorSuccessActive,#005244));transform:var(--token-buttonActiveTransform,scale(.97));box-shadow:var(--token-buttonSuccessShadow,0 2px 6px #00bd9b40, inset 0 1px 1px #fff3)}.button--ghost{background:var(--token-buttonGhostBg,transparent);color:var(--token-colorTextSecondary,#595959);border:var(--token-buttonGhostBorder,1px solid transparent);box-shadow:var(--token-buttonGhostShadow,none);-webkit-backdrop-filter:var(--token-buttonGhostBackdrop,none)}.button--ghost:hover:not(:disabled){background:var(--token-buttonGhostBgHover,#8b5cf60f);border:var(--token-buttonGhostBorderHover,var(--token-buttonGhostBorder,1px solid transparent));color:var(--token-colorText,#141414);box-shadow:var(--token-buttonGhostShadowHover,none);transform:var(--token-buttonHoverTransform,translateY(-1px))}.button--ghost:active:not(:disabled){background:var(--token-buttonGhostBgActive,var(--token-colorBgLayout,#f5f5f5));transform:var(--token-buttonActiveTransform,scale(.97))}.button--text{color:var(--token-colorTextSecondary,#595959);box-shadow:none;background:0 0;border:1px solid #0000;min-height:auto;padding:.25rem .5rem}.button--text:hover:not(:disabled){background:var(--token-colorBgTextHover,#0000000a);color:var(--token-colorText,#141414);transform:none}.button--text:active:not(:disabled){background:var(--token-colorBgTextActive,#00000014);transform:none}.button--outline{color:var(--token-colorTextSecondary,#595959);border:1px solid var(--token-colorBorderSecondary,#00000026);box-shadow:none;background:0 0}.button--outline:hover:not(:disabled){background:var(--token-colorBgTextHover,#0000000a);border-color:var(--token-colorPrimary,#8b5cf6);color:var(--token-colorPrimary,#8b5cf6);transform:var(--token-buttonHoverTransform,translateY(-1px))}.button--outline:active:not(:disabled){background:var(--token-colorBgTextActive,#00000014);transform:var(--token-buttonActiveTransform,scale(.97))}.button[role=tab]{border:1px solid #0000}.button[role=tab]:hover:not(:disabled),.button[role=tab]:active:not(:disabled){transform:none}.button--active{color:var(--token-colorPrimary,#8b5cf6);font-weight:600}.button--active.button--ghost,.button--active.button--text{background:var(--token-colorPrimaryBg,#1677ff14);color:var(--token-colorPrimary,#8b5cf6)}.button--active.button--outline,.button--active.button--secondary{background:var(--token-colorPrimaryBg,#1677ff14);border-color:var(--token-colorPrimary,#8b5cf6);color:var(--token-colorPrimary,#8b5cf6)}.button--loading{pointer-events:none}.button--loading .button__text,.button--loading .button__icon{opacity:0}.button__loading-spinner{border:.125rem solid;border-top-color:#0000;border-radius:50%;width:.875rem;height:.875rem;animation:.6s linear infinite button-spinner-rotate;position:absolute}@keyframes button-spinner-rotate{to{transform:rotate(360deg)}}.button__icon{justify-content:center;align-items:center;line-height:1;display:inline-flex}.button__icon svg{display:block}.button__text{line-height:1}@media (prefers-reduced-motion:reduce){.button{transition:none}.button:hover:not(:disabled),.button:active:not(:disabled){transform:none}.button__loading-spinner{opacity:.6;border-top-color:currentColor;animation:none}}.badge{border-radius:var(--token-borderRadiusSM,.25rem);text-transform:uppercase;letter-spacing:.02em;white-space:nowrap;justify-content:center;align-items:center;min-height:1.5rem;font-weight:600;display:inline-flex}.badge--small{padding:var(--token-paddingXXS,.125rem) var(--token-paddingSM,.5rem);font-size:var(--token-fontSizeSM,.75rem)}.badge--medium{padding:var(--token-paddingXS,.25rem) var(--token-paddingMD,1rem);font-size:var(--token-fontSizeSM,.75rem)}.badge--default{background-color:var(--token-colorFillSecondary,#f3f4f6);color:var(--token-colorTextSecondary,#595959)}.badge--primary{color:var(--token-colorPrimary,#8b5cf6);background-color:#1890ff1f}.badge--success{color:var(--token-colorSuccess,#007a63);background-color:#52c41a1f}.badge--warning{color:var(--token-colorWarning,#9a5d00);background-color:#faad141f}.badge--danger{color:var(--token-colorError,#c82333);background-color:#ff4d4f1f}.badge--info{color:var(--token-colorInfo,#06c);background-color:#028df21f}.status-tag{align-items:center;gap:var(--token-paddingXXS,4px);display:inline-flex}.status-tag__indicator{background-color:currentColor;border-radius:50%;width:6px;height:6px;animation:1.6s ease-in-out infinite status-tag-pulse;display:inline-block}@keyframes status-tag-pulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.45;transform:scale(.85)}}.status-tag__label{display:inline-block}@media (prefers-reduced-motion:reduce){.status-tag__indicator{animation:none}}.progress-bar-wrapper{align-items:center;gap:.5rem;width:100%;display:flex}.progress-bar{background:var(--token-colorFillSecondary,#f3f4f6);border-radius:999px;flex:1;position:relative;overflow:hidden}.progress-bar--sm{height:4px}.progress-bar--md{height:6px}.progress-bar--lg{height:8px}.progress-bar__fill{border-radius:999px;height:100%;transition:none}.progress-bar--animated .progress-bar__fill{transition:width .3s}.progress-bar--primary .progress-bar__fill{background:var(--token-colorPrimary,#8b5cf6)}.progress-bar--success .progress-bar__fill{background:var(--token-colorSuccess,#52c41a)}.progress-bar--error .progress-bar__fill{background:var(--token-colorError,#ff4d4f)}.progress-bar--warning .progress-bar__fill{background:var(--token-colorWarning,#faad14)}.progress-bar--indeterminate{background:linear-gradient(90deg, var(--token-colorFillSecondary,#f3f4f6) 0%, var(--token-colorPrimaryBg,#1890ff1a) 50%, var(--token-colorFillSecondary,#f3f4f6) 100%);background-size:200% 100%;animation:1.5s ease-in-out infinite progress-bar-shimmer}.progress-bar--indeterminate .progress-bar__fill{display:none}@keyframes progress-bar-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.progress-bar__label{font-size:var(--token-fontSizeSM,.75rem);color:var(--token-colorText,#141414);white-space:nowrap;text-align:right;min-width:3ch;font-weight:500}@media (prefers-reduced-motion:reduce){.progress-bar--indeterminate{animation:none}.progress-bar--animated .progress-bar__fill{transition:none}}.empty-state{padding:var(--token-paddingXL,2rem) var(--token-paddingLG,1.5rem);text-align:center;flex-direction:column;justify-content:center;align-items:center;min-height:300px;animation:.5s ease-out empty-state-fade-in;display:flex}@keyframes empty-state-fade-in{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.empty-state__illustration{margin-bottom:var(--token-paddingLG,1.5rem);position:relative}.empty-state__icon{color:var(--token-colorTextQuaternary,#bfbfbf);transition:color var(--token-motionDurationMid,.2s)}.empty-state__illustration:before{content:"";background:radial-gradient(circle, color-mix(in srgb, var(--token-colorPrimary,#8b5cf6) 8%, transparent) 0%, transparent 70%);z-index:-1;opacity:0;will-change:opacity, transform;border-radius:50%;animation:3s ease-in-out infinite glow-pulse;position:absolute;inset:-20px}@keyframes glow-pulse{0%,to{opacity:0;transform:scale(.95)}50%{opacity:1;transform:scale(1)}}.illustration-sparkle{transform-origin:50%;will-change:opacity, transform;animation:2s ease-in-out infinite sparkle-twinkle}@keyframes sparkle-twinkle{0%,to{opacity:.4;transform:scale(.8)}50%{opacity:1;transform:scale(1.2)}}.illustration-arrow{will-change:transform;animation:2s ease-in-out infinite arrow-bounce}@keyframes arrow-bounce{0%,to{transform:translateY(0)}50%{transform:translateY(5px)}}.illustration-needle{transform-origin:256px 308px;will-change:transform;animation:3s ease-in-out infinite needle-swing}@keyframes needle-swing{0%{transform:rotate(-12deg)}50%{transform:rotate(12deg)}to{transform:rotate(-12deg)}}.empty-state__content{margin-bottom:var(--token-paddingLG,1.5rem);max-width:480px}.empty-state__title{margin:0 0 var(--token-paddingSM,.5rem) 0;font-size:var(--token-fontSizeXL,1.25rem);color:var(--token-colorText,#141414);font-weight:600;line-height:1.4}.empty-state__description{font-size:var(--token-fontSize,.875rem);color:var(--token-colorTextSecondary,#595959);margin:0;line-height:1.6}.empty-state__actions{gap:var(--token-paddingMD,1rem);flex-wrap:wrap;justify-content:center;align-items:center;display:flex}.empty-state__action-btn{min-width:120px}.empty-state__action-link{font-size:var(--token-fontSize,.875rem);color:var(--token-colorLink,#8b5cf6);padding:var(--token-paddingXS,.25rem) var(--token-paddingSM,.5rem);border-radius:var(--token-borderRadiusSM,.25rem);transition:color var(--token-motionDurationFast,.1s), background-color var(--token-motionDurationFast,.1s);text-decoration:none}.empty-state__action-link:hover{color:var(--token-colorLinkHover,#7c3aed);background-color:var(--token-colorFillTertiary,#f9fafb)}.empty-state__action-link:focus{outline:var(--token-focusRingWidth,2px) var(--token-focusRingStyle,solid) var(--token-focusRingColor,var(--token-colorPrimary));outline-offset:var(--token-focusRingOffset,2px)}.empty-state--chat .empty-state__illustration:before{background:radial-gradient(circle, var(--token-colorPrimaryBg,#8b5cf61a) 0%, transparent 70%)}.empty-state--models .empty-state__illustration:before{background:radial-gradient(circle,#1890ff14 0%,#0000 70%)}.empty-state--creations .empty-state__illustration:before{background:radial-gradient(circle,#722ed114 0%,#0000 70%)}.empty-state--text .empty-state__illustration:before{background:radial-gradient(circle,#5263d114 0%,#0000 70%)}.empty-state--benchmark .empty-state__illustration:before{background:radial-gradient(circle,#00bd9b14 0%,#0000 70%)}.empty-state--statistics .empty-state__illustration:before{background:radial-gradient(circle,#13c2c214 0%,#0000 70%)}.empty-state--error .empty-state__illustration:before{background:radial-gradient(circle,#ff4d4f14 0%,#0000 70%)}@media (prefers-color-scheme:dark){.empty-state--chat .empty-state__illustration:before{background:radial-gradient(circle, var(--token-colorPrimaryBg,#8b5cf61a) 0%, transparent 70%)}.empty-state--models .empty-state__illustration:before{background:radial-gradient(circle,#1890ff1f 0%,#0000 70%)}.empty-state--creations .empty-state__illustration:before{background:radial-gradient(circle,#722ed11f 0%,#0000 70%)}.empty-state--text .empty-state__illustration:before{background:radial-gradient(circle,#5263d11f 0%,#0000 70%)}.empty-state--benchmark .empty-state__illustration:before{background:radial-gradient(circle,#00bd9b1f 0%,#0000 70%)}.empty-state--statistics .empty-state__illustration:before{background:radial-gradient(circle,#13c2c21f 0%,#0000 70%)}.empty-state--error .empty-state__illustration:before{background:radial-gradient(circle,#ff4d4f1f 0%,#0000 70%)}}@media (prefers-reduced-motion:reduce){.empty-state{animation:none}.empty-state__illustration:before{opacity:.5;animation:none}.illustration-sparkle,.illustration-arrow,.illustration-needle{animation:none}}@media (width<=768px){.empty-state{padding:var(--token-paddingLG,1.5rem) var(--token-paddingMD,1rem);min-height:250px}.empty-state__illustration{margin-bottom:var(--token-paddingMD,1rem)}.empty-state__icon{width:80px;height:80px}.empty-state__title{font-size:var(--token-fontSizeLG,1rem)}.empty-state__description{font-size:var(--token-fontSize,.875rem)}.empty-state__actions{gap:var(--token-paddingSM,.5rem);flex-direction:column;width:100%}.empty-state__action-btn{width:100%;min-width:unset}}@media (width<=480px){.empty-state__icon{width:64px;height:64px}.empty-state__title{font-size:var(--token-fontSizeLG,1rem)}}.tabs{flex-direction:column;width:100%;display:flex}.tabs__container{align-items:center;gap:var(--token-paddingXS,.25rem);margin:0 0 var(--token-paddingMD,1rem);display:flex;position:relative}.tabs__list{gap:var(--token-paddingXS,.25rem);padding:var(--token-paddingSM,.5rem) var(--token-paddingMD,1rem);background-color:var(--token-colorBgContainer,#fff);border:1px solid var(--token-colorBorderSecondary,#e5e7eb);border-radius:var(--token-borderRadiusXL,.75rem);z-index:10;box-shadow:var(--token-boxShadow,0 1px 2px 0 #00000008, 0 1px 6px -1px #00000005, 0 2px 4px 0 #00000005);scrollbar-width:none;scroll-behavior:smooth;-webkit-overflow-scrolling:touch;flex:1;min-width:0;display:flex;position:sticky;top:0;overflow:auto hidden}.tabs__list::-webkit-scrollbar{display:none}.tabs--overflow-menu .tabs__list{gap:var(--token-paddingMD,1rem)}.tabs__tab{align-items:center;gap:var(--token-paddingXS,.25rem);padding:var(--token-paddingSM,.5rem) var(--token-paddingMD,1rem);font-size:var(--token-fontSize,.875rem);color:var(--token-colorTextSecondary,#595959);border-radius:var(--token-borderRadiusLG,.5rem);cursor:pointer;transition:color var(--token-motionDurationFast,.1s), background-color var(--token-motionDurationFast,.1s);white-space:nowrap;background:0 0;border:none;flex-shrink:0;font-weight:500;display:flex}.tabs__tab:hover{color:var(--token-colorText,#141414);background-color:var(--token-tabHoverBg,#f3f4f6)}.tabs__tab:focus{box-shadow:var(--token-tabFocusShadow,0 0 0 3px #8b5cf626)}.tabs__tab:focus:not(:focus-visible){outline:none}.tabs__tab:focus-visible{outline:var(--token-focusRingWidth,2px) var(--token-focusRingStyle,solid) var(--token-focusRingColor,var(--token-colorPrimary));outline-offset:var(--token-focusRingOffset,2px)}.tabs__tab--active{color:var(--token-colorPrimary,#8b5cf6);background-color:var(--token-tabActiveBg,#8b5cf61a)}.tabs__tab--active:hover{background-color:var(--token-tabActiveBg,#8b5cf61a)}.tabs__tab-label{display:inline-block}.tabs__tag-badge{font-size:var(--token-fontSizeXXS,.5rem);text-transform:uppercase;letter-spacing:.03em;pointer-events:none;padding:1px 4px;line-height:1}.tabs__group{align-items:center;gap:var(--token-paddingXS,.25rem);flex-shrink:0;display:flex}.tabs__group-label{font-size:var(--token-fontSizeSM,.75rem);color:var(--token-colorTextTertiary,#737373);text-transform:uppercase;letter-spacing:.05em;white-space:nowrap;padding:0 var(--token-paddingXS,.25rem);-webkit-user-select:none;user-select:none;font-weight:600}.tabs__separator{background-color:var(--token-colorBorderSecondary,#e5e7eb);width:1px;height:24px;margin:0 var(--token-paddingSM,.5rem);flex-shrink:0}.tabs__group-tabs{gap:var(--token-paddingXS,.25rem);align-items:center;display:flex}.tabs__scroll-arrow{background-color:var(--token-colorBgContainer,#fff);border:1px solid var(--token-colorBorderSecondary,#e5e7eb);border-radius:var(--token-borderRadiusLG,.5rem);width:32px;height:32px;color:var(--token-colorTextSecondary,#595959);cursor:pointer;transition:background-color var(--token-motionDurationFast,.1s), color var(--token-motionDurationFast,.1s), border-color var(--token-motionDurationFast,.1s);box-shadow:var(--token-boxShadow,0 1px 2px 0 #00000008, 0 1px 6px -1px #00000005, 0 2px 4px 0 #00000005);flex-shrink:0;justify-content:center;align-items:center;padding:0;display:flex}.tabs__scroll-arrow:hover{background-color:var(--token-colorFillSecondary,#f3f4f6);color:var(--token-colorText,#141414);border-color:var(--token-colorBorder,#d9d9d9)}.tabs__scroll-arrow:active{background-color:var(--token-colorFillTertiary,#f9fafb)}.tabs__scroll-arrow:focus{box-shadow:var(--token-tabFocusShadow,0 0 0 3px #8b5cf626)}.tabs__scroll-arrow:focus:not(:focus-visible){outline:none}.tabs__scroll-arrow:focus-visible{outline:var(--token-focusRingWidth,2px) var(--token-focusRingStyle,solid) var(--token-focusRingColor,var(--token-colorPrimary));outline-offset:var(--token-focusRingOffset,2px)}.tabs__scroll-arrow--left{margin-right:-4px}.tabs__scroll-arrow--right{margin-left:-4px}.tabs__panel,.tabs__panel:focus{outline:none}.tabs--mobile-dropdown{flex-direction:column;width:100%;display:flex}.tabs__dropdown-container{margin:0 0 var(--token-paddingMD,1rem);position:relative}.tabs__dropdown-trigger{width:100%;padding:var(--token-paddingSM,.5rem) var(--token-paddingMD,1rem);background-color:var(--token-colorBgContainer,#fff);border:1px solid var(--token-colorBorderSecondary,#e5e7eb);border-radius:var(--token-borderRadiusLG,.5rem);color:var(--token-colorText,#141414);font-size:var(--token-fontSize,.875rem);cursor:pointer;transition:background-color var(--token-motionDurationFast,.1s), border-color var(--token-motionDurationFast,.1s);box-shadow:var(--token-boxShadow,0 1px 2px 0 #00000008, 0 1px 6px -1px #00000005, 0 2px 4px 0 #00000005);justify-content:space-between;align-items:center;font-weight:500;display:flex}.tabs__dropdown-trigger:hover{background-color:var(--token-colorFillSecondary,#f3f4f6);border-color:var(--token-colorBorder,#d9d9d9)}.tabs__dropdown-trigger:focus{border-color:color-mix(in srgb, var(--token-colorPrimary) 70%, var(--token-colorText));box-shadow:var(--token-tabFocusShadow,0 0 0 3px #8b5cf626)}.tabs__dropdown-trigger:focus:not(:focus-visible){outline:none}.tabs__dropdown-trigger:focus-visible{outline:var(--token-focusRingWidth,2px) var(--token-focusRingStyle,solid) var(--token-focusRingColor,var(--token-colorPrimary));outline-offset:var(--token-focusRingOffset,2px)}.tabs__dropdown-label{text-align:left;flex:1}.tabs__dropdown-arrow{transition:transform var(--token-motionDurationMid,.2s);flex-shrink:0}.tabs__dropdown-arrow--open{transform:rotate(180deg)}.tabs__dropdown-menu{z-index:100;background-color:var(--token-colorBgContainer,#fff);border:1px solid var(--token-colorBorderSecondary,#e5e7eb);border-radius:var(--token-borderRadiusLG,.5rem);box-shadow:var(--token-boxShadowSecondary,0 6px 16px 0 #00000014, 0 3px 6px -4px #0000001f, 0 9px 28px 8px #0000000d);animation:tabs-dropdown-fade-in var(--token-motionDurationMid,.2s);position:absolute;top:calc(100% + 4px);left:0;right:0;overflow:hidden}@keyframes tabs-dropdown-fade-in{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}.tabs__dropdown-item{width:100%;padding:var(--token-paddingSM,.5rem) var(--token-paddingMD,1rem);color:var(--token-colorText,#141414);font-size:var(--token-fontSize,.875rem);text-align:left;cursor:pointer;transition:background-color var(--token-motionDurationFast,.1s);background:0 0;border:none;font-weight:400;display:block}.tabs__dropdown-item:hover{background-color:var(--token-colorFillSecondary,#f3f4f6)}.tabs__dropdown-item:focus-visible{outline:var(--token-focusRingWidth,2px) var(--token-focusRingStyle,solid) var(--token-focusRingColor,var(--token-colorPrimary));outline-offset:-2px}.tabs__dropdown-item--active{color:var(--token-colorPrimary,#8b5cf6);background-color:var(--token-tabActiveBg,#8b5cf61a);font-weight:500}.tabs__dropdown-item--active:hover{background-color:var(--token-tabActiveBg,#8b5cf61a)}.tabs__overflow{flex-shrink:0;display:none;position:relative}.tabs__overflow-btn{background-color:var(--token-colorBgContainer,#fff);border:1px solid var(--token-colorBorderSecondary,#e5e7eb);border-radius:var(--token-borderRadiusLG,.5rem);width:36px;height:36px;color:var(--token-colorTextSecondary,#595959);cursor:pointer;transition:background-color var(--token-motionDurationFast,.1s), color var(--token-motionDurationFast,.1s);box-shadow:var(--token-boxShadow,0 1px 2px 0 #00000008, 0 1px 6px -1px #00000005, 0 2px 4px 0 #00000005);justify-content:center;align-items:center;padding:0;display:flex}.tabs__overflow-btn:hover{background-color:var(--token-colorFillSecondary,#f3f4f6);color:var(--token-colorText,#141414)}.tabs__overflow-btn:focus{box-shadow:var(--token-tabFocusShadow,0 0 0 3px #8b5cf626)}.tabs__overflow-btn:focus:not(:focus-visible){outline:none}.tabs__overflow-btn:focus-visible{outline:var(--token-focusRingWidth,2px) var(--token-focusRingStyle,solid) var(--token-focusRingColor,var(--token-colorPrimary));outline-offset:var(--token-focusRingOffset,2px)}.tabs__overflow-menu{background-color:var(--token-colorBgElevated,#fff);border:1px solid var(--token-colorBorderSecondary,#e5e7eb);border-radius:var(--token-borderRadiusLG,.5rem);min-width:200px;max-width:calc(100vw - 2rem);max-height:400px;box-shadow:var(--token-boxShadowSecondary,0 6px 16px 0 #00000014, 0 3px 6px -4px #0000001f, 0 9px 28px 8px #0000000d);z-index:var(--token-zIndexPopover,1150);padding:var(--token-paddingXS,.25rem);position:absolute;top:calc(100% + 8px);right:0;overflow-y:auto}.tabs__overflow-group{flex-direction:column;display:flex}.tabs__overflow-group+.tabs__overflow-group{margin-top:var(--token-paddingSM,.5rem);padding-top:var(--token-paddingSM,.5rem);border-top:1px solid var(--token-colorBorderSecondary,#e5e7eb)}.tabs__overflow-group-label{font-size:var(--token-fontSizeSM,.75rem);color:var(--token-colorTextTertiary,#737373);text-transform:uppercase;letter-spacing:.05em;padding:var(--token-paddingXS,.25rem) var(--token-paddingSM,.5rem);margin-bottom:var(--token-paddingXXS,.125rem);font-weight:600}.tabs__overflow-item{justify-content:space-between;align-items:center;gap:var(--token-paddingSM,.5rem);width:100%;padding:var(--token-paddingSM,.5rem) var(--token-paddingMD,1rem);font-size:var(--token-fontSize,.875rem);color:var(--token-colorText,#141414);border-radius:var(--token-borderRadiusSM,.25rem);text-align:left;cursor:pointer;transition:background-color var(--token-motionDurationFast,.1s);background:0 0;border:none;display:flex}.tabs__overflow-item:hover{background-color:var(--token-colorFillSecondary,#f3f4f6)}.tabs__overflow-item:focus-visible{outline:var(--token-focusRingWidth,2px) var(--token-focusRingStyle,solid) var(--token-focusRingColor,var(--token-colorPrimary));outline-offset:-2px}.tabs__overflow-item--active{color:var(--token-colorPrimary,#8b5cf6);background-color:var(--token-tabActiveBg,#8b5cf61a);font-weight:600}.tabs__overflow-item--active:hover{background-color:var(--token-tabActiveBg,#8b5cf61a)}@media (width>=480px) and (width<=767px){.tabs:not(.tabs--overflow-menu) .tabs__list{padding:var(--token-paddingSM,.5rem)}.tabs:not(.tabs--overflow-menu) .tabs__tab{padding:var(--token-paddingXS,.25rem) var(--token-paddingSM,.5rem);font-size:var(--token-fontSize,.875rem)}.tabs:not(.tabs--overflow-menu) .tabs__scroll-arrow{width:28px;height:28px}}@media (width<=479px){.tabs:not(.tabs--overflow-menu) .tabs__scroll-arrow{display:none}}@media (width<=767px){.tabs--overflow-menu .tabs__overflow{display:block}.tabs--overflow-menu .tabs__list{padding:var(--token-paddingSM,.5rem);gap:0}.tabs--overflow-menu .tabs__group-label,.tabs--overflow-menu .tabs__separator{display:none}.tabs--overflow-menu .tabs__group,.tabs--overflow-menu .tabs__group-tabs{gap:0}.tabs--overflow-menu .tabs__tab{min-width:auto;padding:var(--token-paddingSM,.5rem) var(--token-padding,.75rem);font-size:var(--token-fontSize,.875rem);flex:1}.tabs--overflow-menu .tabs__scroll-arrow{display:none!important}}.tabs--variant-segmented .tabs__container{gap:0}.tabs--variant-segmented .tabs__list{background-color:var(--token-colorFillTertiary,#f9fafb);border-radius:var(--token-borderRadiusLG,.5rem);padding:var(--token-paddingXS,.25rem);gap:var(--token-paddingXS,.25rem);z-index:auto;box-shadow:none;border:1px solid #0000;position:static;top:auto;overflow-x:visible}.tabs--variant-segmented .tabs__tab{border-radius:var(--token-borderRadius,.375rem);color:var(--token-colorTextSecondary,#595959);background:0 0;border:1px solid #0000;font-weight:500}.tabs--variant-segmented .tabs__tab:hover:not(.tabs__tab--active){background-color:var(--token-colorFillSecondary,#f3f4f6);color:var(--token-colorText,#141414)}.tabs--variant-segmented .tabs__tab--active{color:var(--token-colorText,#141414);background-color:var(--token-colorBgContainer,#fff);box-shadow:var(--token-boxShadowTertiary,0 1px 3px #0000001a)}.tabs--variant-segmented .tabs__tab--active:hover{background-color:var(--token-colorBgContainer,#fff)}.tabs--variant-segmented.tabs--fill-container .tabs__tab{text-align:center;flex:1;justify-content:center}.tabs--variant-segmented .tabs__scroll-arrow{display:none}.tabs--variant-compact .tabs__container{gap:0;margin:0}.tabs--variant-compact .tabs__list{background-color:var(--token-colorFillQuaternary,#fafafa);border-radius:var(--token-borderRadiusSM,.25rem);z-index:auto;box-shadow:none;border:1px solid #0000;flex:none;gap:2px;min-width:0;padding:2px;display:inline-flex;position:static;top:auto;overflow-x:visible}.tabs--variant-compact .tabs__tab{padding:var(--token-paddingXS,.25rem) var(--token-paddingSM,.5rem);font-size:var(--token-fontSize,.875rem);border-radius:calc(var(--token-borderRadiusSM,.25rem) - 1px);color:var(--token-colorTextSecondary,#595959);background:0 0;border:1px solid #0000;min-width:72px;font-weight:500}.tabs--variant-compact .tabs__tab:hover:not(.tabs__tab--active){background-color:var(--token-colorFillSecondary,#f3f4f6);color:var(--token-colorText,#141414)}.tabs--variant-compact .tabs__tab--active{color:var(--token-colorText,#141414);background-color:var(--token-colorBgContainer,#fff);box-shadow:var(--token-boxShadowTertiary,0 1px 3px #0000001a)}.tabs--variant-compact .tabs__tab--active:hover{background-color:var(--token-colorBgContainer,#fff)}.tabs--variant-compact.tabs--fill-container .tabs__tab{text-align:center;flex:1;justify-content:center}.tabs--variant-compact .tabs__scroll-arrow{display:none}.tabs--variant-segmented .tabs__group,.tabs--variant-compact .tabs__group{gap:0}.tabs--variant-segmented .tabs__group-tabs,.tabs--variant-compact .tabs__group-tabs{gap:var(--token-paddingXS,.25rem)}@media (width<=479px){.tabs--variant-segmented .tabs__list{overflow-x:auto}}@media (prefers-reduced-motion:reduce){.tabs__list{scroll-behavior:auto}.tabs__scroll-arrow,.tabs__tab,.tabs__dropdown-trigger,.tabs__dropdown-item,.tabs__dropdown-arrow,.tabs__overflow-btn,.tabs__overflow-item{transition:none}.tabs__dropdown-menu{animation:none}.tabs__scroll-arrow:active{transform:none}.tabs--variant-segmented .tabs__tab,.tabs--variant-compact .tabs__tab{transition:none}}.data-table{border:1px solid var(--token-colorBorderSecondary,var(--token-colorBorder,#d9d9d9));border-radius:var(--token-borderRadiusLG,8px);background-color:var(--token-colorBgContainer,#fff);width:100%;position:relative;overflow-x:auto}.data-table__table{border-collapse:collapse;table-layout:auto;width:100%}.data-table__head{z-index:1;background-color:var(--token-colorFillQuaternary,var(--token-colorBgLayout,#f5f5f5));position:sticky;top:0}.data-table__row{border-bottom:1px solid var(--token-colorBorderSecondary,transparent)}.data-table__row:last-of-type{border-bottom:none}.data-table__row--clickable{cursor:pointer;transition:background-color var(--token-motionDurationFast,.12s) ease}.data-table__row--clickable:hover{background-color:var(--token-colorFillQuaternary,#0000000a)}.data-table__row--clickable:focus-visible{outline:var(--token-focusRingWidth,2px) var(--token-focusRingStyle,solid) var(--token-focusRingColor,var(--token-colorPrimary));outline-offset:-2px}.data-table__cell{padding:var(--token-paddingSM,.5rem) var(--token-paddingMD,1rem);font-size:var(--token-fontSize,.875rem);color:var(--token-colorText,#141414);vertical-align:middle;word-break:break-word}.data-table__cell--align-right{text-align:right}.data-table__cell--align-center{text-align:center}.data-table__cell--head{font-weight:600;font-size:var(--token-fontSizeSM,.75rem);text-transform:uppercase;letter-spacing:.05em;color:var(--token-colorTextSecondary,#595959);background-color:var(--token-colorFillQuaternary,var(--token-colorBgLayout,#f5f5f5));border-bottom:1px solid var(--token-colorBorderSecondary,var(--token-colorBorder,#d9d9d9));-webkit-user-select:none;user-select:none;white-space:nowrap;word-break:normal;overflow-wrap:normal;position:relative}.data-table__head-label{vertical-align:middle;display:inline-block}.data-table__cell--sortable{cursor:pointer;-webkit-user-select:none;user-select:none}.data-table__cell--sortable:hover{background-color:var(--token-colorFillTertiary,#0000000f)}.data-table__cell--sortable:focus-visible{outline:var(--token-focusRingWidth,2px) var(--token-focusRingStyle,solid) var(--token-focusRingColor,var(--token-colorPrimary));outline-offset:-2px}.data-table__cell--sort-active{color:var(--token-colorPrimary,#8b5cf6)}.data-table__sort-icon{vertical-align:middle;color:var(--token-colorTextSecondary,#595959);flex-shrink:0;align-items:center;margin-inline-start:var(--token-marginXXS,4px);line-height:0;display:inline-flex}.data-table__cell--sort-active .data-table__sort-icon{color:var(--token-colorPrimary,#8b5cf6)}.data-table__resize-handle{cursor:col-resize;width:6px;transition:background-color var(--token-motionDurationFast,.12s) ease;background-color:#0000;position:absolute;top:0;bottom:0;right:0}.data-table__resize-handle:hover{background-color:var(--token-colorPrimaryBorder,var(--token-colorPrimary,#8b5cf6));opacity:.5}.data-table__state-cell{padding:var(--token-paddingLG,16px);text-align:center;color:var(--token-colorTextSecondary,#595959)}.data-table__loading{background:linear-gradient(90deg, var(--token-colorFillQuaternary,#fafafa) 25%, var(--token-colorFillTertiary,#f9fafb) 50%, var(--token-colorFillQuaternary,#fafafa) 75%);border-radius:var(--token-borderRadiusSM,.25rem);background-size:200% 100%;width:100%;height:24px;animation:1.4s ease-in-out infinite data-table-shimmer}@keyframes data-table-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}@media (prefers-reduced-motion:reduce){.data-table__loading{animation:none}}.error-state{padding:var(--token-paddingXL,2rem);text-align:center;flex-direction:column;justify-content:center;align-items:center;min-height:200px;display:flex}.error-state__icon{width:64px;height:64px;margin-bottom:var(--token-paddingLG,1.5rem);color:var(--token-colorError,#c82333);transition:transform var(--token-motionDurationMid,.2s);background-color:#ff4d4f1a;border-radius:50%;justify-content:center;align-items:center;display:flex}.error-state__icon svg{width:48px;height:48px}.error-state__title{margin:0 0 var(--token-paddingSM,.5rem);font-size:var(--token-fontSizeXL,1.25rem);color:var(--token-colorText,#141414);font-weight:600;line-height:1.4}.error-state__message{margin:0 0 var(--token-paddingLG,1.5rem);font-size:var(--token-fontSize,.875rem);color:var(--token-colorTextSecondary,#595959);max-width:480px;line-height:1.5}.error-state__actions{gap:var(--token-padding,.75rem);flex-wrap:wrap;justify-content:center;display:flex}.error-state__action-btn{min-width:120px}.error-state--danger .error-state__icon{color:var(--token-colorError,#c82333);background-color:#ff4d4f1a}.error-state--warning .error-state__icon{color:var(--token-colorWarning,#9a5d00);background-color:#faad141a}.error-state--accent .error-state__icon{color:var(--token-colorPrimary,#8b5cf6);background-color:var(--token-colorPrimaryBg,#8b5cf61a)}@media (prefers-reduced-motion:reduce){.error-state__icon{transition:none}}@media (width<=767px){.error-state{padding:var(--token-paddingLG,1.5rem)}.error-state__icon{width:56px;height:56px;margin-bottom:var(--token-paddingMD,1rem)}.error-state__icon svg{width:40px;height:40px}.error-state__title{font-size:var(--token-fontSizeLG,1rem)}.error-state__message{font-size:var(--token-fontSize,.875rem)}.error-state__actions{flex-direction:column;width:100%}.error-state__action-btn{width:100%;min-width:unset}}.skeleton{background-color:var(--token-colorFillTertiary,#f9fafb);border-radius:var(--token-borderRadiusSM,.25rem);display:inline-block;position:relative;overflow:hidden}.skeleton--rect{border-radius:var(--token-borderRadiusSM,.25rem)}.skeleton--circle{border-radius:50%}.skeleton--text{border-radius:var(--token-borderRadiusSM,.25rem);height:1em;transform:scaleY(.6)}.skeleton__shimmer{background:linear-gradient(90deg, transparent 0%, var(--token-colorBgContainer,#fff) 50%, transparent 100%);animation:skeleton-shimmer var(--token-motionDurationSlow,1.5s) infinite;position:absolute;inset:0;transform:translate(-100%)}@keyframes skeleton-shimmer{0%{transform:translate(-100%)}to{transform:translate(100%)}}@media (prefers-reduced-motion:reduce){.skeleton__shimmer{animation:none}}.select{display:inline-block;position:relative}.select--full-width{width:100%;display:block}.select--labelled{gap:var(--token-paddingXS);flex-direction:column;display:flex}.select__label{font-size:var(--token-fontSizeSM);color:var(--token-colorTextSecondary);font-weight:500}.select__trigger{justify-content:space-between;align-items:center;gap:var(--token-paddingSM);width:100%;min-height:var(--token-controlHeight);padding:var(--token-paddingXS) var(--token-padding);font-size:var(--token-fontSize);font-family:var(--token-fontFamily);color:var(--token-colorText);background-color:var(--token-colorBgContainer);border:1px solid var(--token-colorBorder);border-radius:var(--token-borderRadius);cursor:pointer;transition:all var(--token-motionDurationFast);text-align:left;display:flex}.select__trigger:hover:not(:disabled){border-color:var(--token-colorPrimary)}.select__trigger:focus{border-color:color-mix(in srgb, var(--token-colorPrimary) 70%, var(--token-colorText));box-shadow:0 0 0 2px var(--token-colorPrimaryBg);outline:none}.select--open .select__trigger{border-color:var(--token-colorPrimary);box-shadow:0 0 0 2px var(--token-colorPrimaryBg);border-bottom-right-radius:0;border-bottom-left-radius:0}.select--disabled .select__trigger{cursor:not-allowed;opacity:.6;background-color:var(--token-colorFillTertiary)}.select--small .select__trigger{min-height:var(--token-controlHeightSM);padding:var(--token-paddingXS) var(--token-paddingSM);font-size:var(--token-fontSizeSM)}.select--medium .select__trigger{min-height:var(--token-controlHeight);padding:var(--token-paddingXS) var(--token-padding);font-size:var(--token-fontSize)}.select--large .select__trigger{min-height:var(--token-controlHeightLG);padding:var(--token-paddingSM) var(--token-padding);font-size:var(--token-fontSize)}.select__trigger{min-width:120px}.select__value{align-items:center;gap:var(--token-paddingSM);flex:1;min-width:0;display:flex;overflow:hidden}.select__value-icon{color:var(--token-colorTextSecondary);flex-shrink:0;justify-content:center;align-items:center;display:flex}.select__value-label{text-overflow:ellipsis;white-space:nowrap;font-weight:500;overflow:hidden}.select__placeholder{color:var(--token-colorTextTertiary)}.select__chevron{color:var(--token-colorTextSecondary);transition:transform var(--token-motionDurationFast);flex-shrink:0;justify-content:center;align-items:center;display:flex}.select__chevron--open{transform:rotate(180deg)}.select__dropdown{z-index:var(--token-zIndexPopover);background:var(--token-colorBgElevated);border:1px solid var(--token-colorPrimary);border-radius:0 0 var(--token-borderRadius) var(--token-borderRadius);box-shadow:var(--token-boxShadowSecondary);border-top:none;flex-direction:column;max-height:240px;animation:.15s ease-out selectDropdownOpen;display:flex;position:absolute;top:100%;left:0;right:0;overflow:hidden}.select__dropdown--portal{border:1px solid var(--token-colorBorder);border-radius:var(--token-borderRadius);z-index:var(--token-zIndexTooltip);position:fixed}.select__search{padding:var(--token-paddingSM);background:var(--token-colorBgElevated);border-bottom:1px solid var(--token-colorBorderSecondary);flex-shrink:0}.select__search-input{box-sizing:border-box;width:100%;padding:var(--token-paddingXS) var(--token-paddingSM);font-family:var(--token-fontFamily);font-size:var(--token-fontSize);color:var(--token-colorText);background:var(--token-colorBgContainer);border:1px solid var(--token-colorBorder);border-radius:var(--token-borderRadiusSM);transition:border-color var(--token-motionDurationFast), box-shadow var(--token-motionDurationFast)}.select__search-input::placeholder{color:var(--token-colorTextPlaceholder)}.select__search-input:focus-visible{border-color:color-mix(in srgb, var(--token-colorPrimary) 70%, var(--token-colorText));box-shadow:0 0 0 2px var(--token-colorPrimaryBg);outline:none}.select__options{min-height:0;overflow-y:auto}@keyframes selectDropdownOpen{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.select__options::-webkit-scrollbar{width:var(--token-scrollbarSize);height:var(--token-scrollbarSize)}.select__options::-webkit-scrollbar-track{background:0 0}.select__options::-webkit-scrollbar-thumb{background-color:var(--token-colorBorder);border-radius:var(--token-scrollbarRadius)}.select__options::-webkit-scrollbar-thumb:hover{background-color:var(--token-colorTextTertiary)}.select__option{align-items:center;gap:var(--token-paddingSM);padding:var(--token-paddingSM) var(--token-padding);font-size:var(--token-fontSize);color:var(--token-colorText);cursor:pointer;transition:background-color var(--token-motionDurationFast);-webkit-user-select:none;user-select:none;display:flex}.select__option--disabled{color:var(--token-colorTextDisabled);cursor:not-allowed}.select__option:first-child{border-radius:0}.select__option:last-child{border-radius:0 0 var(--token-borderRadius) var(--token-borderRadius)}.select__option:hover:not(.select__option--disabled),.select__option--focused:not(.select__option--disabled){background-color:var(--token-colorFillSecondary)}.select__option--selected{background-color:var(--token-colorPrimaryBg)}.select__option--selected:hover,.select__option--selected.select__option--focused{background-color:var(--token-colorPrimaryBgHover)}.select__option-icon{width:20px;height:20px;color:var(--token-colorTextSecondary);flex-shrink:0;justify-content:center;align-items:center;display:flex}.select__option--selected .select__option-icon{color:var(--token-colorPrimary)}.select__option-content{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.select__option-label{font-weight:500}.select__option--selected .select__option-label{color:var(--token-colorPrimary)}.select__option-description{font-size:var(--token-fontSizeSM);color:var(--token-colorTextTertiary)}.select__option-check{color:var(--token-colorPrimary);flex-shrink:0;justify-content:center;align-items:center;display:flex}.select__empty{padding:var(--token-padding) var(--token-paddingMD);color:var(--token-colorTextTertiary);text-align:center;font-style:italic}.select--large .select__option{padding:var(--token-paddingSM) var(--token-paddingMD);font-size:var(--token-fontSize)}.select--large .select__option-icon{width:24px;height:24px}.select--large .select__option-description{font-size:var(--token-fontSizeSM)}.drawer__backdrop.drawer__backdrop{background-color:var(--token-colorBgMask,#00000073);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);z-index:var(--token-zIndexDrawer,1100);pointer-events:none;visibility:hidden;opacity:0;transition:opacity var(--token-motionDurationMid,.3s) ease, visibility 0s linear var(--token-motionDurationMid,.3s), background-color var(--token-themeTransitionDuration,.25s) var(--token-themeTransitionTiming,ease-in-out), backdrop-filter var(--token-themeTransitionDuration,.25s) var(--token-themeTransitionTiming,ease-in-out);position:fixed;inset:0}.drawer__backdrop--open.drawer__backdrop--open{pointer-events:auto;visibility:visible;opacity:1;transition:opacity var(--token-motionDurationMid,.3s) ease, visibility 0s linear 0s, background-color var(--token-themeTransitionDuration,.25s) var(--token-themeTransitionTiming,ease-in-out), backdrop-filter var(--token-themeTransitionDuration,.25s) var(--token-themeTransitionTiming,ease-in-out)}.drawer.drawer{background-color:var(--token-colorBgContainer,#fff);box-shadow:var(--token-boxShadowDrawerRight,-4px 0 20px #00000026);opacity:0;transition:transform var(--token-motionDurationMid,.3s) cubic-bezier(.4, 0, .2, 1), opacity var(--token-motionDurationMid,.3s) ease, background-color var(--token-themeTransitionDuration,.25s) var(--token-themeTransitionTiming,ease-in-out), color var(--token-themeTransitionDuration,.25s) var(--token-themeTransitionTiming,ease-in-out), border-color var(--token-themeTransitionDuration,.25s) var(--token-themeTransitionTiming,ease-in-out), box-shadow var(--token-themeTransitionDuration,.25s) var(--token-themeTransitionTiming,ease-in-out);z-index:var(--token-zIndexDrawerContent,1101);flex-direction:column;display:flex;position:fixed;top:0;bottom:0;right:0;transform:translate(100%)}.drawer.drawer--open{opacity:1;transform:translate(0)}.drawer__header{padding:var(--token-paddingLG,1.5rem);border-bottom:1px solid var(--token-colorBorder,#d9d9d9);flex-shrink:0}.drawer__title-row{justify-content:space-between;align-items:center;gap:var(--token-paddingMD,1rem);display:flex}.drawer__title{font-size:var(--token-fontSizeHeading4,1.25rem);color:var(--token-colorText,#141414);margin:0;font-weight:600}.drawer__subtitle{font-size:var(--token-fontSizeSM,.875rem);color:var(--token-colorTextSecondary,#6b7280);margin:var(--token-paddingSM,.5rem) 0 0 0;text-overflow:ellipsis;overflow:hidden}.drawer__close-btn.drawer__close-btn{border-radius:var(--token-borderRadius,6px);width:2rem;height:2rem;color:var(--token-colorTextSecondary,#6b7280);cursor:pointer;transition:background-color var(--token-motionDurationFast,.15s) ease, color var(--token-motionDurationFast,.15s) ease, border-color var(--token-themeTransitionDuration,.25s) var(--token-themeTransitionTiming,ease-in-out);background:0 0;border:none;flex-shrink:0;justify-content:center;align-items:center;display:flex}.drawer__close-btn:hover{background-color:var(--token-colorFillSecondary,#f3f4f6);color:var(--token-colorText,#141414)}.drawer__close-btn:focus-visible{outline:var(--token-focusRingWidth,2px) var(--token-focusRingStyle,solid) var(--token-focusRingColor,var(--token-colorPrimary));outline-offset:var(--token-focusRingOffset,2px)}.drawer__content{flex:1;overflow:hidden auto}.drawer__footer{padding:var(--token-paddingMD,1rem) var(--token-paddingLG,1.5rem);border-top:1px solid var(--token-colorBorder,#d9d9d9);background-color:var(--token-colorFillSecondary,#f3f4f6);flex-shrink:0}@media (prefers-reduced-motion:reduce){.drawer__backdrop.drawer__backdrop,.drawer.drawer,.drawer__close-btn.drawer__close-btn,.drawer__backdrop--open.drawer__backdrop--open{transition:none}}@media (prefers-reduced-transparency:reduce){.drawer__backdrop.drawer__backdrop{-webkit-backdrop-filter:none;background-color:#000000a6}}@media (width<=767px){.drawer{width:100vw!important;max-width:100vw!important}.drawer__header,.drawer__footer{padding:var(--token-paddingMD,1rem)}}@keyframes drawer-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-4px)}20%,40%,60%,80%{transform:translate(4px)}}.drawer--shaking{animation:.4s ease-in-out drawer-shake}@media (prefers-reduced-motion:reduce){.drawer--shaking{animation:none}}.tooltip__wrapper{display:inline-flex}.tooltip__wrapper:focus-visible{outline:var(--token-focusRingWidth,2px) var(--token-focusRingStyle,solid) var(--token-focusRingColor,var(--token-colorPrimary));outline-offset:var(--token-focusRingOffset,2px);border-radius:var(--token-borderRadiusSM,.25rem)}.tooltip__wrapper:focus:not(:focus-visible){outline:none}.tooltip__content{z-index:var(--token-zIndexTooltip,1300);color:#f3f4f6;max-width:280px;font-size:var(--token-fontSize,.875rem);background-color:#1f2937;border-radius:6px;padding:.5rem .75rem;line-height:1.4;position:fixed;box-shadow:0 4px 12px #00000026}.tooltip__content p,.tooltip__content span{color:#f3f4f6}.tooltip__text{color:#f3f4f6;margin:0}.tooltip__content.param-tooltip__content{width:280px}.base-card{padding:var(--token-paddingMD,1rem);background-color:var(--token-colorFillTertiary,#f9fafb);border-radius:var(--token-borderRadiusLG,.5rem);transition:border-color var(--token-motionDurationFast,.1s), box-shadow var(--token-motionDurationMid,.2s), transform var(--token-motionDurationMid,.2s), background-color var(--token-motionDurationFast,.1s);border:1px solid #0000;flex-direction:column;display:flex;position:relative}.base-card--row{flex-direction:row}.base-card--hoverable:hover{border-color:var(--token-colorBorderSecondary,#e5e7eb);box-shadow:var(--token-boxShadowSecondary,0 6px 16px 0 #00000014, 0 3px 6px -4px #0000001f, 0 9px 28px 8px #0000000d);transform:translateY(-2px)}.base-card--clickable{cursor:pointer}.base-card--clickable:hover{border-color:var(--token-colorPrimary,#8b5cf6);transform:translateY(-2px);box-shadow:0 4px 12px #0000001a}.base-card:focus-within{border-color:color-mix(in srgb, var(--token-colorPrimary) 70%, var(--token-colorText));outline:none}.base-card--clickable:focus{outline:var(--token-focusRingWidth,2px) var(--token-focusRingStyle,solid) var(--token-focusRingColor,var(--token-colorPrimary));outline-offset:var(--token-focusRingOffset,2px)}.base-card--default{background-color:var(--token-colorFillTertiary,#f9fafb)}.base-card--installed{background-color:var(--token-colorBgContainer,#fff);border-color:var(--token-colorBorderSecondary,#e5e7eb)}.base-card--available{background-color:var(--token-colorFillQuaternary,#fafafa);border-color:var(--token-colorBorderSecondary,#e5e7eb)}.base-card--active{border-color:var(--token-colorSuccessBorder,#00bd9b66);background-color:var(--token-colorSuccessBg,#00bd9b0d)}.base-card--active:hover{border-color:var(--token-colorSuccessBorderHover,#00bd9b99);box-shadow:var(--token-colorSuccessBoxShadow,0 4px 12px #00bd9b26)}.base-card--loading{border-color:color-mix(in srgb, var(--token-colorPrimary,#8b5cf6) 40%, transparent);background-color:color-mix(in srgb, var(--token-colorPrimary,#8b5cf6) 3%, transparent);animation:2s ease-in-out infinite base-card-pulse}@keyframes base-card-pulse{0%,to{border-color:color-mix(in srgb, var(--token-colorPrimary,#8b5cf6) 30%, transparent);box-shadow:0 0 #0000}50%{border-color:color-mix(in srgb, var(--token-colorPrimary,#8b5cf6) 50%, transparent);box-shadow:0 0 0 4px var(--token-colorPrimaryBg,#8b5cf61a)}}.base-card--disabled{opacity:.5;pointer-events:none;filter:grayscale(50%)}.base-card--disabled:hover{box-shadow:none;border-color:#0000;transform:none}.base-card--warning{background-color:#faad1408;border-color:#faad1466}@media (prefers-reduced-motion:reduce){.base-card{transition:none}.base-card--hoverable:hover,.base-card--clickable:hover{transform:none}.base-card--loading{animation:none}}@media (width<=767px){.base-card{padding:var(--token-paddingSM,.5rem)}}.page-header{margin-bottom:var(--token-paddingLG,1.5rem)}.page-header__content{justify-content:space-between;align-items:flex-start;gap:var(--token-paddingMD,1rem);flex-wrap:wrap;display:flex}.page-header__text{flex:20rem;min-width:min(100%,12rem)}.page-header__title{margin:0 0 var(--token-paddingSM,.5rem);font-size:var(--token-fontSizeDisplay4,1.75rem);letter-spacing:.02em;color:var(--token-colorText,#141414);font-weight:300}.page-header__description{font-size:var(--token-fontSize,.875rem);color:var(--token-colorTextSecondary,#595959);margin:0}.page-header__actions{justify-content:flex-end;align-items:flex-start;gap:var(--token-paddingSM,.5rem);flex-wrap:wrap;flex:0 auto;min-width:0;margin-left:auto;display:flex}.page-header__actions>*{flex-shrink:0}.page-header__error{justify-content:space-between;align-items:center;gap:var(--token-paddingSM,.5rem);margin-top:var(--token-paddingSM,.5rem);padding:var(--token-paddingSM,.5rem) var(--token-paddingMD,1rem);font-size:var(--token-fontSize,.875rem);color:var(--token-colorError,#c82333);border-radius:var(--token-borderRadiusLG,.5rem);background-color:#ff4d4f14;border:1px solid #ff4d4f4d;display:flex}.page-header__error-text{word-break:break-word;flex:1}.page-header__error-dismiss{font-size:var(--token-fontSizeXL,1.25rem);color:currentColor;cursor:pointer;opacity:.7;width:24px;height:24px;transition:opacity var(--token-motionDurationFast,.1s);background:0 0;border:none;flex-shrink:0;justify-content:center;align-items:center;padding:0;line-height:1;display:flex}.page-header__error-dismiss:hover{opacity:1}@media (width<=767px){.page-header__content{flex-direction:column;align-items:stretch}.page-header__text{flex:none;min-width:0}.page-header__actions{justify-content:flex-end}}.page-header__error-body{gap:var(--token-paddingXXS,.125rem);flex-direction:column;flex:1;min-width:0;display:flex}.page-header__error-detail{font-size:var(--token-fontSizeSM,.75rem);color:var(--token-colorTextTertiary,#737373);word-break:break-word}.page-header__error-actions{align-items:center;gap:var(--token-paddingSM,.5rem);padding-left:var(--token-paddingXS,.25rem);flex-shrink:0;display:flex}.page-layout{flex-direction:column;width:100%;min-height:100%;margin:0 auto;display:flex}.page-layout--standard{max-width:900px}.page-layout--wide{max-width:1400px}.page-layout--full{max-width:none}@media (width<=767px){.page-layout:not(.page-layout--full){padding:0 var(--token-paddingSM,.5rem)}}.smooth-height--active{transition:height var(--token-motionDurationMid,.2s) ease-out;overflow:hidden}.smooth-height__content{display:flow-root}@media (prefers-reduced-motion:reduce){.smooth-height--active{transition:none}}.stat-card{gap:var(--token-paddingSM,.5rem);min-width:0;overflow:hidden}.stat-card__header{justify-content:space-between;align-items:center;gap:var(--token-paddingXS,.25rem);display:flex}.stat-card__label{font-size:var(--token-fontSizeSM,.75rem);color:var(--token-colorTextSecondary,#ffffff73);text-transform:uppercase;letter-spacing:.04em;white-space:nowrap;text-overflow:ellipsis;font-weight:600;overflow:hidden}.stat-card__icon{border-radius:var(--token-borderRadiusSM,.25rem);background:var(--token-colorFillSecondary,#ffffff0a);width:28px;height:28px;color:var(--token-colorTextSecondary,#fff9);flex-shrink:0;justify-content:center;align-items:center;display:inline-flex}.stat-card__body{flex-direction:column;gap:4px;display:flex}.stat-card__value-row{flex-wrap:wrap;align-items:baseline;gap:.3em;display:inline-flex}.stat-card__value-line{justify-content:space-between;align-items:center;gap:var(--token-paddingSM,.5rem);min-width:0;display:flex}.stat-card__sparkline{flex-shrink:0;align-items:center;display:inline-flex}.stat-card__value{font-size:var(--token-fontSizeXXL,1.5rem);color:var(--token-colorText,#141414);font-variant-numeric:tabular-nums;text-overflow:ellipsis;white-space:nowrap;min-width:0;font-weight:600;line-height:1.1;overflow:hidden}.stat-card__value-suffix{font-size:var(--token-fontSize,.875rem);color:var(--token-colorTextSecondary,#ffffff73);font-weight:400}.stat-card__trend{font-size:var(--token-fontSizeSM,.75rem);align-items:center;gap:4px;font-weight:500;display:inline-flex}.stat-card__trend--up{color:var(--token-colorSuccess,#52c41a)}.stat-card__trend--down{color:var(--token-colorError,#f5222d)}.stat-card__trend--flat{color:var(--token-colorTextSecondary,#ffffff73)}.stat-card__hint{font-size:var(--token-fontSizeSM,.75rem);color:var(--token-colorTextSecondary,#ffffff73);line-height:1.4}.stat-card.stat-card--prominent{padding:var(--token-paddingLG,1.5rem)}.stat-card--prominent{background:linear-gradient(135deg, var(--token-colorBgContainer,#fff) 0%, color-mix(in srgb, var(--token-colorPrimary,#8b5cf6) 4%, transparent) 100%)}.stat-card--prominent:hover{border-color:color-mix(in srgb, var(--token-colorPrimary,#8b5cf6) 30%, transparent)}.stat-card--prominent .stat-card__value{font-size:var(--token-fontSizeHeading1,2.25rem)}.stat-card--prominent .stat-card__icon{width:34px;height:34px}.stat-card.stat-card--compact{padding:var(--token-paddingSM,.5rem)}.stat-card--compact .stat-card__value{font-size:var(--token-fontSizeHeading3,1.5rem)}.stat-card--tone-success .stat-card__value{color:var(--token-colorSuccess,#52c41a)}.stat-card--tone-success .stat-card__icon{color:var(--token-colorSuccess,#52c41a);background:#52c41a1f}.stat-card--tone-warning .stat-card__value{color:var(--token-colorWarning,#faad14)}.stat-card--tone-warning .stat-card__icon{color:var(--token-colorWarning,#faad14);background:#faad1424}.stat-card--tone-danger .stat-card__value{color:var(--token-colorError,#f5222d)}.stat-card--tone-danger .stat-card__icon{color:var(--token-colorError,#f5222d);background:#f5222d1f}.stat-card--tone-info .stat-card__value{color:var(--token-colorPrimary,#8b5cf6)}.stat-card--tone-info .stat-card__icon{color:var(--token-colorPrimary,#8b5cf6);background:#6a35fc1f}.stat-card--tone-success{--corner-accent-color:var(--token-colorSuccess,#52c41a)}.stat-card--tone-warning{--corner-accent-color:var(--token-colorWarning,#faad14)}.stat-card--tone-danger{--corner-accent-color:var(--token-colorError,#f5222d)}.stat-card--tone-info{--corner-accent-color:var(--token-colorPrimary,#8b5cf6)}@media (prefers-reduced-motion:reduce){.stat-card__trend{transition:none}}.activity-operations{margin:0;padding:0;list-style:none}.activity-operation{padding:var(--space-4);border-bottom:1px solid var(--color-separator);overflow-wrap:anywhere}.activity-operation header{gap:var(--space-3);flex-wrap:wrap;justify-content:space-between;align-items:center;display:flex}.activity-toolbar{gap:var(--space-3);flex-wrap:wrap;display:flex}.activity-metrics{gap:var(--space-4);grid-template-columns:repeat(auto-fit,minmax(min(100%,280px),1fr));display:grid}.activity-metric{padding:var(--space-4);border-bottom:1px solid var(--color-separator);overflow-wrap:anywhere;margin:0}.activity-metric dt{font-weight:600}.activity-metric dd{margin:var(--space-2) 0}.activity-chart{width:100%;height:180px;color:var(--color-focus)}.activity-chart circle{fill:currentColor}.activity-metrics--summary{gap:var(--space-2);grid-template-columns:repeat(auto-fit,minmax(min(100%,140px),1fr))}.activity-metrics--summary .activity-metric{padding:var(--space-2)}.activity-measurement-details{margin-top:var(--space-4)}.activity-measurement-details>summary{cursor:pointer;padding:var(--space-2);border-radius:var(--radius-sm)}.activity-measurement-details>summary:focus-visible{outline:2px solid var(--color-focus);outline-offset:2px}.models-layout{gap:var(--space-6,24px);grid-template-columns:minmax(0,1fr) minmax(260px,320px);align-items:start;display:grid}.models-layout>*,.models-library{min-width:0}.models-library .models-toolbar{flex-wrap:wrap;align-items:end;gap:12px;display:flex}.models-toolbar>.ds-field{flex:150px}.models-library .models-wrap,.models-library pre,.models-library code,.models-library dd,.models-library h3,.models-library td{white-space:pre-wrap;overflow-wrap:anywhere}.models-library .ds-inspector{width:auto;position:static}.models-library .ds-inspector dd{margin:4px 0 16px}.models-library .ds-inspector dt{color:var(--color-muted);font-size:.85rem}.models-library .models-selected{background:var(--color-selection)}.models-library .data-table__cell{vertical-align:top}.models-library .data-table__cell:first-child{min-width:160px;max-width:320px}.models-library .models-pagination{flex-wrap:wrap;align-items:center;gap:12px;padding-block:16px;display:flex}.models-operations .ds-list li{display:block}.models-operations code{font-size:.8rem}.models-library summary{cursor:pointer;padding-block:12px}@media (width<=1100px){.models-layout{grid-template-columns:minmax(0,1fr)}}.models-library .ds-common-table{max-width:100%;overflow-x:auto}.models-library .data-table__cell .ds-button span{white-space:normal;overflow-wrap:anywhere}.models-library{grid-template-columns:minmax(0,1fr)}.models-library>*,.models-operations,.models-operations .ds-list,.models-operations li,.models-operations li>div{min-width:0;max-width:100%}.models-operations strong,.models-operations p{overflow-wrap:anywhere}.models-library .button-row{flex-wrap:wrap;gap:8px;display:flex}.models-layout:not(:has(.ds-inspector)){grid-template-columns:minmax(0,1fr)}.models-library [data-testid=models-pending-profile] a{min-height:24px;padding-block:2px;display:inline-block}.models-library .models-row-meta{gap:var(--space-1,4px);margin-top:var(--space-1,4px);flex-wrap:wrap;display:flex}.chat-screen{min-width:0}.chat-toolbar{gap:var(--space-3,12px);flex-wrap:wrap;align-items:end;display:flex}.chat-toolbar .ds-field{flex:1;min-width:180px}.chat-transcript{overflow-anchor:none;max-height:60vh;overflow:auto}.chat-turn{padding-block:var(--space-4,16px);border-bottom:1px solid var(--color-separator);overflow-wrap:anywhere}.chat-turn header{flex-wrap:wrap;justify-content:space-between;align-items:center;display:flex}.chat-turn h2{font-size:1rem}.chat-turn pre,.chat-prompt{white-space:pre-wrap;overflow-wrap:anywhere}.chat-turn pre{max-height:24rem;overflow:auto}.chat-composer textarea,.chat-screen textarea{resize:vertical;box-sizing:border-box;width:100%;min-height:7rem;max-height:24rem;color:inherit;background:var(--color-bg-elevated);border:1px solid var(--color-separator);border-radius:var(--radius-sm);font:inherit;padding:12px}.chat-images{flex-wrap:wrap;gap:12px;display:flex}.chat-images figure{max-width:160px;margin:0}.chat-images img{object-fit:contain;max-width:100%;max-height:120px}.chat-metrics{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:8px;display:grid}.chat-metrics dd{margin:0}.chat-screen details{padding-block:8px}.chat-screen summary{cursor:pointer;align-content:center;min-height:44px}.chat-code-block{min-width:0}.chat-code-block pre{white-space:pre;overflow-x:auto}.chat-code-toolbar{justify-content:space-between;align-items:center;gap:8px;display:flex}.chat-code-keyword{color:var(--color-focus,currentColor);font-weight:600}.chat-code-string{color:var(--color-text)}.chat-code-number{color:var(--color-muted)}.chat-screen a[href^=\#]{align-items:center;min-width:24px;min-height:44px;display:inline-flex}.chat-markdown a{min-width:24px;min-height:24px;display:inline-block}.chat-privacy .toggle{min-height:44px}.chat-privacy .toggle input{flex:0 0 24px;min-width:24px;min-height:24px}.chat-parameter-grid{grid-template-columns:repeat(auto-fit,minmax(min(100%,220px),1fr));gap:12px;display:grid}*{box-sizing:border-box}html{background:var(--color-bg);color:var(--color-text)}body{background:var(--color-bg);min-width:320px;min-height:100vh;margin:0}a{color:inherit;text-decoration:none}button{cursor:pointer}.sr-only{clip:rect(0,0,0,0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.app-shell{background:var(--color-bg);grid-template-columns:224px minmax(0,1fr);gap:0;min-height:100vh;padding:0;display:grid}.app-sidebar{gap:var(--space-4);min-width:0;color:var(--color-text);padding:0 var(--space-4) var(--space-4);border-radius:0;flex-direction:column;display:flex}.desktop-sidebar{height:100vh;box-shadow:none;border-width:0 1px 0 0;align-self:start;position:sticky;top:0}.sheet-sidebar{border-radius:0;min-height:calc(100vh - 156px);padding:0}.brand-mark{align-items:center;gap:var(--space-2);min-height:58px;margin:0 calc(var(--space-4) * -1);padding:0 var(--space-4);color:var(--color-text);letter-spacing:-.03em;border-bottom:1px solid var(--color-separator);font-weight:760;display:flex}.brand-symbol{border-radius:var(--radius-xs);background:var(--color-selection);letter-spacing:-.05em;place-items:center;width:26px;height:26px;font-size:.78rem;display:grid}.brand-name{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.app-nav{gap:var(--space-1);display:grid}.app-nav a{align-items:center;gap:var(--space-3);border-radius:var(--radius-sm);min-height:34px;color:var(--color-muted);transition:background var(--motion-fast), color var(--motion-fast);padding:7px 9px;display:flex}.app-nav a[aria-current=page]{color:var(--color-text);background:var(--color-selection);font-weight:650}.app-nav a:hover{background:color-mix(in srgb, var(--color-selection) 72%, transparent)}.app-sidebar footer{align-items:center;gap:var(--space-2);color:var(--color-muted);margin-top:auto;font-size:.9rem;display:flex}.connection-dot{background:var(--color-muted);width:8px;height:8px;box-shadow:0 0 0 3px var(--color-bg-neutral);border-radius:50%}.connection-dot[data-state=ready],.connection-dot[data-state=streaming],.connection-dot[data-state=polling]{background:var(--color-success)}.connection-dot[data-state=bootstrapping],.connection-dot[data-state=stale]{background:var(--color-warning)}.connection-dot[data-state=offline],.connection-dot[data-state=unauthorized],.connection-dot[data-state=forbidden],.connection-dot[data-state=schema-mismatch],.connection-dot[data-state=error]{background:var(--color-error)}.app-main{min-width:0;min-height:100vh;color:var(--color-text);background:var(--color-bg-elevated);grid-template-rows:auto 1fr;display:grid}.app-toolbar{z-index:2;align-items:center;gap:var(--space-3);min-height:58px;padding:0 var(--space-4);box-shadow:none;border-width:0 0 1px;border-radius:0;grid-template-columns:auto minmax(160px,auto) minmax(0,1fr) auto;display:grid;position:sticky;top:0}.mobile-menu-button.ds-icon-button{display:none}.app-toolbar p{margin:0;font-weight:760}.app-toolbar span{color:var(--color-muted);font-size:.9rem}.toolbar-actions,.control-row,.dialog-actions{align-items:center;gap:var(--space-2);flex-wrap:wrap;display:flex}.selected-model{min-width:0;max-width:min(48vw,620px);color:var(--color-muted);background:var(--material-control-bg);border:1px solid var(--color-separator);text-overflow:ellipsis;white-space:nowrap;border-radius:999px;justify-self:center;padding:6px 12px;overflow:hidden}.app-content-grid{gap:var(--space-5);min-width:0;padding:var(--space-6);grid-template-columns:minmax(0,1fr);display:grid}.app-content-grid.has-inspector{grid-template-columns:minmax(0,1fr) minmax(280px,340px)}.app-content{min-width:0}.screen-stack{gap:var(--space-5);min-width:0;display:grid}.screen-heading,.surface-card{min-width:0;padding:var(--space-5)}.screen-heading{background:0 0;border:0;border-radius:0;padding:0}.eyebrow{margin:0 0 var(--space-2);color:var(--color-focus);text-transform:uppercase;letter-spacing:.08em;font-size:.78rem;font-weight:800}h1{letter-spacing:-.025em;margin:0;font-size:clamp(1.45rem,2.6vw,1.75rem);line-height:1.12}h2{letter-spacing:-.02em}.screen-heading p:last-child,.surface-card p{color:var(--color-muted);line-height:1.55}.connection-prompt{max-width:760px}.model-grid,.gallery-grid,.settings-grid{gap:var(--space-4);grid-template-columns:repeat(2,minmax(0,1fr));min-width:0;display:grid}.dense-gallery{align-items:start}.model-card{gap:var(--space-4);display:grid}.truncate{text-overflow:ellipsis;white-space:nowrap;min-width:0;display:block;overflow:hidden}.chat-screen{min-height:100%}.transcript{gap:var(--space-3);display:grid}.transcript details{border:1px solid var(--color-separator);border-radius:var(--radius-md);padding:var(--space-3)}.composer{gap:var(--space-3);grid-template-columns:minmax(0,1fr) auto;align-items:end;display:grid}.composer textarea{resize:vertical;min-height:88px}.toggle{align-items:center;gap:var(--space-2);min-height:36px;color:var(--color-text);display:flex}.toggle input{width:24px;height:24px}.command-list{gap:var(--space-2);display:grid}.shortcut-list{padding-left:var(--space-5)}kbd{border:1px solid var(--color-separator);border-radius:var(--radius-xs);background:var(--color-bg-neutral);padding:2px 6px}.table-card{overflow:auto}.sample-label{color:var(--color-muted);text-transform:uppercase;letter-spacing:.06em;font-weight:700}.screen-heading,.surface-card,.ds-field,.ds-tabs,.ds-tabs [role=tablist]{min-width:0;max-width:100%}.screen-heading h1,.screen-heading p,.surface-card h2,.surface-card p,.ds-field span,.ds-field small{overflow-wrap:anywhere;word-break:normal}.control-row,.dialog-actions{align-items:stretch}.control-row>*,.dialog-actions>*{min-width:0;max-width:100%}@media (width<=1180px){.app-content-grid.has-inspector,.dense-gallery{grid-template-columns:1fr}}@media (width<=960px){.app-shell{grid-template-columns:1fr;padding:0}.desktop-sidebar{display:none}.app-toolbar .ds-icon-button{min-width:44px;min-height:44px}.mobile-menu-button.ds-icon-button{display:inline-grid}.app-content-grid{padding:var(--space-4);grid-template-columns:1fr}.app-toolbar{grid-template-columns:auto minmax(0,1fr) auto}.toolbar-title{min-width:0}.toolbar-actions{grid-area:1/3;justify-self:end}.selected-model{grid-area:2/1/auto/-1;justify-self:stretch;max-width:100%}.app-nav a{min-height:44px}}@media (width<=560px){.app-shell{gap:0;padding:0}.app-sidebar footer{font-size:.8rem}.brand-mark{min-height:52px}.brand-symbol{width:24px;height:24px}.app-toolbar{min-height:auto;padding:var(--space-3)}.app-content-grid{padding:var(--space-4)}.model-grid,.gallery-grid,.settings-grid{grid-template-columns:1fr}.screen-heading{padding:0}.surface-card{padding:var(--space-4)}.ds-table{min-width:520px}.composer{grid-template-columns:1fr}}:root{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light dark;--space-1:4px;--space-2:8px;--space-3:12px;--space-4:16px;--space-5:20px;--space-6:24px;--space-8:32px;--radius-xs:8px;--radius-sm:12px;--radius-md:16px;--radius-lg:18px;--radius-xl:24px;--radius-xxl:28px;--motion-fast:.12s;--motion-standard:.16s;--motion-slow:.18s;--focus-ring:0 0 0 3px color-mix(in srgb, var(--color-focus) 42%, transparent);--material-glass-alpha:.72;--material-glass-blur:18px;--material-glass-saturation:118%;font-family:-apple-system,BlinkMacSystemFont,SF Pro Text,Segoe UI,system-ui,sans-serif}@media (prefers-color-scheme:dark){:root{--lightningcss-light: ;--lightningcss-dark:initial}}:root[data-theme$=-light]{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light}:root[data-theme$=-dark]{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}:root[data-material=tinted]{--material-glass-bg:color-mix(in srgb, var(--color-bg-elevated) 64%, #6f87ff 12%)}:root[data-material=opaque],:root[data-reduce-transparency=true],:root[data-backdrop-filter=unsupported]{--material-glass-bg:var(--color-bg-elevated)}:root[data-high-contrast=on]{--color-separator:currentColor;--color-selection:color-mix(in srgb, var(--color-focus) 30%, transparent);--material-glass-bg:var(--color-bg-elevated)}@media (prefers-contrast:more){:root:not([data-high-contrast=off]){--color-separator:currentColor;--material-glass-bg:var(--color-bg-elevated);--color-selection:color-mix(in srgb, var(--color-focus) 30%, transparent)}}@media (prefers-reduced-transparency:reduce){:root[data-theme]{--material-glass-bg:var(--color-bg-elevated)}}@media (prefers-reduced-motion:reduce){:root{--motion-fast:1ms;--motion-standard:1ms;--motion-slow:1ms}}:root[data-reduce-motion=true]{--motion-fast:1ms;--motion-standard:1ms;--motion-slow:1ms}:root[data-test-text-scale="200"]{font-size:200%}.material-glass{background:var(--material-glass-bg);border:1px solid var(--color-separator);box-shadow:var(--shadow-chrome);-webkit-backdrop-filter:blur(var(--material-glass-blur)) saturate(var(--material-glass-saturation));backdrop-filter:blur(var(--material-glass-blur)) saturate(var(--material-glass-saturation))}@supports not ((-webkit-backdrop-filter:blur(1px)) or (backdrop-filter:blur(1px))){.material-glass{background:var(--color-bg-elevated)}}.ds-button,.ds-icon-button,input,select,textarea{font:inherit}.ds-button,.ds-icon-button{border:1px solid var(--color-separator);min-width:32px;min-height:32px;color:var(--color-text);background:var(--material-control-bg);transition:background var(--motion-fast), transform var(--motion-fast), border-color var(--motion-fast);border-radius:999px}.ds-button{justify-content:center;align-items:center;gap:var(--space-2);white-space:normal;overflow-wrap:anywhere;min-width:32px;padding:7px 14px;font-weight:650;display:inline-flex}.ds-icon-button{place-items:center;padding:0 9px;display:inline-grid}.ds-icon{flex:none;width:18px;height:18px}.ds-button:hover:where(:not(:disabled)),.ds-icon-button:hover:where(:not(:disabled)){background:var(--color-selection)}.ds-button:active,.ds-icon-button:active{transform:scale(.985)}.ds-button:focus-visible,.ds-icon-button:focus-visible,a:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,[role=tab]:focus-visible{box-shadow:var(--focus-ring);outline:none}.ds-button:disabled,.ds-icon-button:disabled,.ds-field[data-disabled=true]{opacity:.56;cursor:not-allowed}.ds-button-primary{color:#fff;background:var(--token-buttonPrimaryBg);border-color:#245bd8}.ds-button-danger{color:#fff;background:var(--token-buttonDangerBg);border-color:#c6352b}.ds-button-ghost{background:0 0}.ds-spinner{width:14px;height:14px;animation:spin var(--motion-slow) linear infinite;border:2px solid;border-right-color:#0000;border-radius:50%}.ds-field{gap:var(--space-2);color:var(--color-muted);display:grid}.ds-field>span{color:var(--color-text);font-size:.9rem;font-weight:650}.ds-field input,.ds-field select,textarea{border-radius:var(--radius-sm);border:1px solid var(--color-separator);width:100%;min-width:0;min-height:36px;color:var(--color-text);background:var(--color-bg-elevated);overflow-wrap:anywhere;padding:8px 10px}.ds-field small[data-tone=error]{color:var(--color-error)}.ds-field small[data-tone=hint]{color:var(--color-muted)}.ds-status{align-items:center;gap:var(--space-1);border:1px solid var(--color-separator);border-radius:999px;min-height:24px;padding:3px 9px;font-size:.82rem;font-weight:700;display:inline-flex}.ds-status:before{content:"";background:var(--color-muted);border-radius:50%;width:8px;height:8px}.ds-status[data-state=ready]{color:var(--color-success);background:var(--color-success-bg)}.ds-status[data-state=failed]{color:var(--color-error);background:var(--color-error-bg)}.ds-status[data-state=loading],.ds-status[data-state=draining],.ds-status[data-state=unloading]{color:var(--color-warning);background:var(--color-warning-bg)}.ds-status[data-state=loading]:before,.ds-status[data-state=draining]:before,.ds-status[data-state=unloading]:before{animation:pulse var(--motion-slow) ease-in-out infinite alternate}.ds-progress{gap:var(--space-2);display:grid}.ds-progress [role=progressbar]{background:var(--color-bg-neutral);border:1px solid var(--color-separator);border-radius:999px;height:10px;overflow:hidden}.ds-progress span{border-radius:inherit;background:linear-gradient(90deg,#2f6cff,#7b61ff);width:48%;height:100%;display:block}.ds-progress span[data-progress=indeterminate]{animation:slide var(--motion-slow) ease-in-out infinite alternate}.ds-empty,.surface-card,.ds-inspector,.ds-banner,.ds-table,.ds-list,.ds-login{background:var(--material-content-bg);border:1px solid var(--color-separator);box-shadow:var(--shadow-card);border-radius:var(--radius-lg)}.ds-empty{text-align:center;place-items:center;gap:var(--space-2);padding:var(--space-6);display:grid}.ds-empty .empty-state__illustration{border-radius:var(--radius-md);background:var(--color-selection);width:44px;height:44px;color:var(--color-focus);place-items:center;display:grid}.ds-empty h2,.ds-empty p,.ds-banner p{margin:0}.ds-banner{gap:var(--space-2);padding:var(--space-4);color:var(--color-error);background:var(--color-error-bg);display:grid}.ds-banner[data-tone=warning]{color:var(--color-warning);background:var(--color-warning-bg)}.ds-banner[data-tone=info]{color:var(--color-text);background:var(--color-selection)}.ds-dialog{width:min(560px,100vw - 32px);color:var(--color-text);background:var(--color-bg-elevated);border:1px solid var(--color-separator);border-radius:var(--radius-xl);padding:0;box-shadow:0 30px 120px #00000052}.ds-dialog::backdrop{background:#080a0e6b}.ds-dialog header{justify-content:space-between;align-items:center;gap:var(--space-4);padding:var(--space-4) var(--space-5);border-bottom:1px solid var(--color-separator);display:flex}.ds-dialog h2{margin:0;font-size:1.1rem}.ds-dialog>div{padding:var(--space-5)}.ds-tooltip-wrap{min-width:0;max-width:100%;display:inline-flex;position:relative}.ds-tooltip{z-index:10;opacity:0;pointer-events:none;border-radius:var(--radius-sm);width:max-content;max-width:240px;color:var(--color-bg-elevated);background:var(--color-text);transition:opacity var(--motion-fast);padding:6px 9px;position:absolute;inset:auto auto calc(100% + 8px) 0}.ds-tooltip-wrap:focus-within .ds-tooltip,.ds-tooltip-wrap:hover .ds-tooltip{opacity:1}.ds-tabs{gap:var(--space-4);display:grid}.ds-tabs [role=tablist]{gap:var(--space-1);padding:var(--space-1);border:1px solid var(--color-separator);border-radius:var(--radius-lg);background:var(--color-bg-neutral);flex-wrap:wrap;width:100%;max-width:100%;display:flex;overflow:visible}.ds-tabs [role=tab]{min-width:0;min-height:32px;color:var(--color-muted);font:inherit;white-space:normal;overflow-wrap:anywhere;background:0 0;border:0;border-radius:999px;flex:8rem;padding:6px 12px;font-weight:650}.ds-tabs [aria-selected=true]{color:var(--color-text);background:var(--color-bg-elevated);box-shadow:inset 0 0 0 1px var(--color-separator)}.ds-inspector{padding:var(--space-5);align-self:start;min-width:0}.ds-inspector h2{margin-top:0;font-size:1rem}.ds-table{table-layout:fixed;border-collapse:separate;border-spacing:0;width:100%;overflow:hidden}.ds-table caption{text-align:left;color:var(--color-muted);padding:10px 14px}.ds-table th,.ds-table td{text-align:left;border-bottom:1px solid var(--color-separator);padding:10px 12px;overflow:hidden}.ds-table tr:last-child td{border-bottom:0}.ds-table th:first-child,.ds-table td:first-child{width:52%}.ds-table th:nth-child(2),.ds-table td:nth-child(2){width:22%}.ds-table th:nth-child(3),.ds-table td:nth-child(3){width:26%}.ds-table .truncate{max-width:100%}.ds-list{gap:var(--space-2);padding:var(--space-4);margin:0;list-style:none;display:grid}.ds-login{gap:var(--space-3);padding:var(--space-4);display:grid}.ds-login h2,.ds-login p{margin:0}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{to{opacity:.45}}@keyframes slide{0%{transform:translate(-60%)}to{transform:translate(120%)}}@media (prefers-reduced-motion:reduce){*,:before,:after{transition-duration:1ms!important;animation:none!important}}:root[data-reduce-motion=true] *,:root[data-reduce-motion=true] :before,:root[data-reduce-motion=true] :after,:root[data-document-hidden=true] *,:root[data-document-hidden=true] :before,:root[data-document-hidden=true] :after{transition-duration:1ms!important;animation:none!important}:root[data-high-contrast=on] .ds-button,:root[data-high-contrast=on] .ds-icon-button,:root[data-high-contrast=on] .surface-card,:root[data-high-contrast=on] .ds-empty,:root[data-high-contrast=on] .ds-inspector,:root[data-high-contrast=on] .ds-banner{border-width:2px}@media (prefers-contrast:more){:root:not([data-high-contrast=off]) .ds-button,:root:not([data-high-contrast=off]) .ds-icon-button,:root:not([data-high-contrast=off]) .surface-card,:root:not([data-high-contrast=off]) .ds-empty,:root:not([data-high-contrast=off]) .ds-inspector,:root:not([data-high-contrast=off]) .ds-banner{border-width:2px}}:root[data-glass-intensity="0"]{--material-glass-alpha:.3;--material-glass-blur:12px;--material-glass-saturation:112.0%}:root[data-glass-intensity="1"]{--material-glass-alpha:.303;--material-glass-blur:12.24px;--material-glass-saturation:112.36%}:root[data-glass-intensity="2"]{--material-glass-alpha:.307;--material-glass-blur:12.48px;--material-glass-saturation:112.72%}:root[data-glass-intensity="3"]{--material-glass-alpha:.31;--material-glass-blur:12.72px;--material-glass-saturation:113.08%}:root[data-glass-intensity="4"]{--material-glass-alpha:.314;--material-glass-blur:12.96px;--material-glass-saturation:113.44%}:root[data-glass-intensity="5"]{--material-glass-alpha:.317;--material-glass-blur:13.2px;--material-glass-saturation:113.8%}:root[data-glass-intensity="6"]{--material-glass-alpha:.32;--material-glass-blur:13.44px;--material-glass-saturation:114.16%}:root[data-glass-intensity="7"]{--material-glass-alpha:.324;--material-glass-blur:13.68px;--material-glass-saturation:114.52%}:root[data-glass-intensity="8"]{--material-glass-alpha:.327;--material-glass-blur:13.92px;--material-glass-saturation:114.88%}:root[data-glass-intensity="9"]{--material-glass-alpha:.331;--material-glass-blur:14.16px;--material-glass-saturation:115.24%}:root[data-glass-intensity="10"]{--material-glass-alpha:.334;--material-glass-blur:14.4px;--material-glass-saturation:115.6%}:root[data-glass-intensity="11"]{--material-glass-alpha:.337;--material-glass-blur:14.64px;--material-glass-saturation:115.96%}:root[data-glass-intensity="12"]{--material-glass-alpha:.341;--material-glass-blur:14.88px;--material-glass-saturation:116.32%}:root[data-glass-intensity="13"]{--material-glass-alpha:.344;--material-glass-blur:15.12px;--material-glass-saturation:116.68%}:root[data-glass-intensity="14"]{--material-glass-alpha:.348;--material-glass-blur:15.36px;--material-glass-saturation:117.04%}:root[data-glass-intensity="15"]{--material-glass-alpha:.351;--material-glass-blur:15.6px;--material-glass-saturation:117.4%}:root[data-glass-intensity="16"]{--material-glass-alpha:.354;--material-glass-blur:15.84px;--material-glass-saturation:117.76%}:root[data-glass-intensity="17"]{--material-glass-alpha:.358;--material-glass-blur:16.08px;--material-glass-saturation:118.12%}:root[data-glass-intensity="18"]{--material-glass-alpha:.361;--material-glass-blur:16.32px;--material-glass-saturation:118.48%}:root[data-glass-intensity="19"]{--material-glass-alpha:.365;--material-glass-blur:16.56px;--material-glass-saturation:118.84%}:root[data-glass-intensity="20"]{--material-glass-alpha:.368;--material-glass-blur:16.8px;--material-glass-saturation:119.2%}:root[data-glass-intensity="21"]{--material-glass-alpha:.371;--material-glass-blur:17.04px;--material-glass-saturation:119.56%}:root[data-glass-intensity="22"]{--material-glass-alpha:.375;--material-glass-blur:17.28px;--material-glass-saturation:119.92%}:root[data-glass-intensity="23"]{--material-glass-alpha:.378;--material-glass-blur:17.52px;--material-glass-saturation:120.28%}:root[data-glass-intensity="24"]{--material-glass-alpha:.382;--material-glass-blur:17.76px;--material-glass-saturation:120.64%}:root[data-glass-intensity="25"]{--material-glass-alpha:.385;--material-glass-blur:18px;--material-glass-saturation:121.0%}:root[data-glass-intensity="26"]{--material-glass-alpha:.388;--material-glass-blur:18.24px;--material-glass-saturation:121.36%}:root[data-glass-intensity="27"]{--material-glass-alpha:.392;--material-glass-blur:18.48px;--material-glass-saturation:121.72%}:root[data-glass-intensity="28"]{--material-glass-alpha:.395;--material-glass-blur:18.72px;--material-glass-saturation:122.08%}:root[data-glass-intensity="29"]{--material-glass-alpha:.399;--material-glass-blur:18.96px;--material-glass-saturation:122.44%}:root[data-glass-intensity="30"]{--material-glass-alpha:.402;--material-glass-blur:19.2px;--material-glass-saturation:122.8%}:root[data-glass-intensity="31"]{--material-glass-alpha:.405;--material-glass-blur:19.44px;--material-glass-saturation:123.16%}:root[data-glass-intensity="32"]{--material-glass-alpha:.409;--material-glass-blur:19.68px;--material-glass-saturation:123.52%}:root[data-glass-intensity="33"]{--material-glass-alpha:.412;--material-glass-blur:19.92px;--material-glass-saturation:123.88%}:root[data-glass-intensity="34"]{--material-glass-alpha:.416;--material-glass-blur:20.16px;--material-glass-saturation:124.24%}:root[data-glass-intensity="35"]{--material-glass-alpha:.419;--material-glass-blur:20.4px;--material-glass-saturation:124.6%}:root[data-glass-intensity="36"]{--material-glass-alpha:.422;--material-glass-blur:20.64px;--material-glass-saturation:124.96%}:root[data-glass-intensity="37"]{--material-glass-alpha:.426;--material-glass-blur:20.88px;--material-glass-saturation:125.32%}:root[data-glass-intensity="38"]{--material-glass-alpha:.429;--material-glass-blur:21.12px;--material-glass-saturation:125.68%}:root[data-glass-intensity="39"]{--material-glass-alpha:.433;--material-glass-blur:21.36px;--material-glass-saturation:126.04%}:root[data-glass-intensity="40"]{--material-glass-alpha:.436;--material-glass-blur:21.6px;--material-glass-saturation:126.4%}:root[data-glass-intensity="41"]{--material-glass-alpha:.439;--material-glass-blur:21.84px;--material-glass-saturation:126.76%}:root[data-glass-intensity="42"]{--material-glass-alpha:.443;--material-glass-blur:22.08px;--material-glass-saturation:127.12%}:root[data-glass-intensity="43"]{--material-glass-alpha:.446;--material-glass-blur:22.32px;--material-glass-saturation:127.48%}:root[data-glass-intensity="44"]{--material-glass-alpha:.45;--material-glass-blur:22.56px;--material-glass-saturation:127.84%}:root[data-glass-intensity="45"]{--material-glass-alpha:.453;--material-glass-blur:22.8px;--material-glass-saturation:128.2%}:root[data-glass-intensity="46"]{--material-glass-alpha:.456;--material-glass-blur:23.04px;--material-glass-saturation:128.56%}:root[data-glass-intensity="47"]{--material-glass-alpha:.46;--material-glass-blur:23.28px;--material-glass-saturation:128.92%}:root[data-glass-intensity="48"]{--material-glass-alpha:.463;--material-glass-blur:23.52px;--material-glass-saturation:129.28%}:root[data-glass-intensity="49"]{--material-glass-alpha:.467;--material-glass-blur:23.76px;--material-glass-saturation:129.64%}:root[data-glass-intensity="50"]{--material-glass-alpha:.47;--material-glass-blur:24px;--material-glass-saturation:130.0%}:root[data-glass-intensity="51"]{--material-glass-alpha:.473;--material-glass-blur:24.24px;--material-glass-saturation:130.36%}:root[data-glass-intensity="52"]{--material-glass-alpha:.477;--material-glass-blur:24.48px;--material-glass-saturation:130.72%}:root[data-glass-intensity="53"]{--material-glass-alpha:.48;--material-glass-blur:24.72px;--material-glass-saturation:131.08%}:root[data-glass-intensity="54"]{--material-glass-alpha:.484;--material-glass-blur:24.96px;--material-glass-saturation:131.44%}:root[data-glass-intensity="55"]{--material-glass-alpha:.487;--material-glass-blur:25.2px;--material-glass-saturation:131.8%}:root[data-glass-intensity="56"]{--material-glass-alpha:.49;--material-glass-blur:25.44px;--material-glass-saturation:132.16%}:root[data-glass-intensity="57"]{--material-glass-alpha:.494;--material-glass-blur:25.68px;--material-glass-saturation:132.52%}:root[data-glass-intensity="58"]{--material-glass-alpha:.497;--material-glass-blur:25.92px;--material-glass-saturation:132.88%}:root[data-glass-intensity="59"]{--material-glass-alpha:.501;--material-glass-blur:26.16px;--material-glass-saturation:133.24%}:root[data-glass-intensity="60"]{--material-glass-alpha:.504;--material-glass-blur:26.4px;--material-glass-saturation:133.6%}:root[data-glass-intensity="61"]{--material-glass-alpha:.507;--material-glass-blur:26.64px;--material-glass-saturation:133.96%}:root[data-glass-intensity="62"]{--material-glass-alpha:.511;--material-glass-blur:26.88px;--material-glass-saturation:134.32%}:root[data-glass-intensity="63"]{--material-glass-alpha:.514;--material-glass-blur:27.12px;--material-glass-saturation:134.68%}:root[data-glass-intensity="64"]{--material-glass-alpha:.518;--material-glass-blur:27.36px;--material-glass-saturation:135.04%}:root[data-glass-intensity="65"]{--material-glass-alpha:.521;--material-glass-blur:27.6px;--material-glass-saturation:135.4%}:root[data-glass-intensity="66"]{--material-glass-alpha:.524;--material-glass-blur:27.84px;--material-glass-saturation:135.76%}:root[data-glass-intensity="67"]{--material-glass-alpha:.528;--material-glass-blur:28.08px;--material-glass-saturation:136.12%}:root[data-glass-intensity="68"]{--material-glass-alpha:.531;--material-glass-blur:28.32px;--material-glass-saturation:136.48%}:root[data-glass-intensity="69"]{--material-glass-alpha:.535;--material-glass-blur:28.56px;--material-glass-saturation:136.84%}:root[data-glass-intensity="70"]{--material-glass-alpha:.538;--material-glass-blur:28.8px;--material-glass-saturation:137.2%}:root[data-glass-intensity="71"]{--material-glass-alpha:.541;--material-glass-blur:29.04px;--material-glass-saturation:137.56%}:root[data-glass-intensity="72"]{--material-glass-alpha:.545;--material-glass-blur:29.28px;--material-glass-saturation:137.92%}:root[data-glass-intensity="73"]{--material-glass-alpha:.548;--material-glass-blur:29.52px;--material-glass-saturation:138.28%}:root[data-glass-intensity="74"]{--material-glass-alpha:.552;--material-glass-blur:29.76px;--material-glass-saturation:138.64%}:root[data-glass-intensity="75"]{--material-glass-alpha:.555;--material-glass-blur:30px;--material-glass-saturation:139.0%}:root[data-glass-intensity="76"]{--material-glass-alpha:.558;--material-glass-blur:30.24px;--material-glass-saturation:139.36%}:root[data-glass-intensity="77"]{--material-glass-alpha:.562;--material-glass-blur:30.48px;--material-glass-saturation:139.72%}:root[data-glass-intensity="78"]{--material-glass-alpha:.565;--material-glass-blur:30.72px;--material-glass-saturation:140.08%}:root[data-glass-intensity="79"]{--material-glass-alpha:.569;--material-glass-blur:30.96px;--material-glass-saturation:140.44%}:root[data-glass-intensity="80"]{--material-glass-alpha:.572;--material-glass-blur:31.2px;--material-glass-saturation:140.8%}:root[data-glass-intensity="81"]{--material-glass-alpha:.575;--material-glass-blur:31.44px;--material-glass-saturation:141.16%}:root[data-glass-intensity="82"]{--material-glass-alpha:.579;--material-glass-blur:31.68px;--material-glass-saturation:141.52%}:root[data-glass-intensity="83"]{--material-glass-alpha:.582;--material-glass-blur:31.92px;--material-glass-saturation:141.88%}:root[data-glass-intensity="84"]{--material-glass-alpha:.586;--material-glass-blur:32.16px;--material-glass-saturation:142.24%}:root[data-glass-intensity="85"]{--material-glass-alpha:.589;--material-glass-blur:32.4px;--material-glass-saturation:142.6%}:root[data-glass-intensity="86"]{--material-glass-alpha:.592;--material-glass-blur:32.64px;--material-glass-saturation:142.96%}:root[data-glass-intensity="87"]{--material-glass-alpha:.596;--material-glass-blur:32.88px;--material-glass-saturation:143.32%}:root[data-glass-intensity="88"]{--material-glass-alpha:.599;--material-glass-blur:33.12px;--material-glass-saturation:143.68%}:root[data-glass-intensity="89"]{--material-glass-alpha:.603;--material-glass-blur:33.36px;--material-glass-saturation:144.04%}:root[data-glass-intensity="90"]{--material-glass-alpha:.606;--material-glass-blur:33.6px;--material-glass-saturation:144.4%}:root[data-glass-intensity="91"]{--material-glass-alpha:.609;--material-glass-blur:33.84px;--material-glass-saturation:144.76%}:root[data-glass-intensity="92"]{--material-glass-alpha:.613;--material-glass-blur:34.08px;--material-glass-saturation:145.12%}:root[data-glass-intensity="93"]{--material-glass-alpha:.616;--material-glass-blur:34.32px;--material-glass-saturation:145.48%}:root[data-glass-intensity="94"]{--material-glass-alpha:.62;--material-glass-blur:34.56px;--material-glass-saturation:145.84%}:root[data-glass-intensity="95"]{--material-glass-alpha:.623;--material-glass-blur:34.8px;--material-glass-saturation:146.2%}:root[data-glass-intensity="96"]{--material-glass-alpha:.626;--material-glass-blur:35.04px;--material-glass-saturation:146.56%}:root[data-glass-intensity="97"]{--material-glass-alpha:.63;--material-glass-blur:35.28px;--material-glass-saturation:146.92%}:root[data-glass-intensity="98"]{--material-glass-alpha:.633;--material-glass-blur:35.52px;--material-glass-saturation:147.28%}:root[data-glass-intensity="99"]{--material-glass-alpha:.637;--material-glass-blur:35.76px;--material-glass-saturation:147.64%}:root[data-glass-intensity="100"]{--material-glass-alpha:.64;--material-glass-blur:36px;--material-glass-saturation:148.0%}:root[data-material=opaque],:root[data-reduce-transparency=true],:root[data-backdrop-filter=unsupported],:root[data-high-contrast=on]{--material-glass-blur:0px;--material-glass-saturation:100%}@media (prefers-reduced-transparency:reduce){:root[data-glass-intensity]{--material-glass-blur:0px;--material-glass-saturation:100%}}@media (prefers-contrast:more){:root:not([data-high-contrast=off]){--material-glass-blur:0px;--material-glass-saturation:100%}}:root{--token-borderRadius:var(--radius-sm);--token-borderRadiusLG:var(--radius-lg);--token-borderRadiusSM:var(--radius-xs);--token-borderRadiusXL:var(--radius-xl);--token-buttonBorderRadius:999px;--token-controlHeight:36px;--token-controlHeightLG:44px;--token-controlHeightSM:32px;--token-focusRingOffset:2px;--token-focusRingStyle:solid;--token-focusRingWidth:2px;--token-fontFamily:-apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", system-ui, sans-serif;--token-fontSize:1rem;--token-fontSizeDisplay4:2rem;--token-fontSizeHeading1:1.75rem;--token-fontSizeHeading2:1.5rem;--token-fontSizeHeading3:1.25rem;--token-fontSizeHeading4:1rem;--token-fontSizeLG:1.125rem;--token-fontSizeSM:.9rem;--token-fontSizeXL:1.25rem;--token-fontSizeXXL:1.5rem;--token-fontSizeXXS:.75rem;--token-marginXXS:var(--space-1);--token-motionDurationFast:var(--motion-fast);--token-motionDurationMid:var(--motion-standard);--token-motionDurationSlow:var(--motion-slow);--token-padding:var(--space-3);--token-paddingLG:var(--space-5);--token-paddingMD:var(--space-4);--token-paddingSM:var(--space-2);--token-paddingXL:var(--space-6);--token-paddingXS:var(--space-1);--token-paddingXXS:var(--space-1);--token-scrollbarRadius:999px;--token-scrollbarSize:6px;--token-themeTransitionDuration:var(--motion-standard);--token-themeTransitionTiming:ease;--token-zIndexDrawer:90;--token-zIndexDrawerContent:91;--token-zIndexPopover:100;--token-zIndexTooltip:110}.button.ds-button.button--inline,.button.ds-icon-button.button--inline{border:1px solid var(--color-separator);min-height:32px;line-height:normal;font:inherit;border-radius:999px;font-weight:650}.button.ds-button.button--inline{gap:var(--space-2);white-space:normal;overflow-wrap:anywhere;justify-content:center;padding:7px 14px}.button.ds-icon-button.button--inline{aspect-ratio:auto;justify-content:center;min-width:32px;padding:0 9px}.button.ds-button-secondary,.button.ds-icon-button{color:var(--color-text)}.button.ds-button-primary,.button.ds-button-danger{color:#fff}.button.ds-button:disabled,.button.ds-icon-button:disabled{opacity:.56}.button.ds-button:focus-visible,.button.ds-icon-button:focus-visible{box-shadow:var(--focus-ring);outline:none}.app-toolbar .ds-icon-button .button__icon{color:inherit}.ds-button .button__loading-spinner{width:14px;height:14px}.ds-icon-button .button__icon{place-items:center;display:inline-grid}.ds-status.badge{text-transform:none;gap:var(--space-1);border:1px solid var(--color-separator);min-height:24px;color:var(--color-text);background:0 0;border-radius:999px;padding:3px 9px;font-size:.82rem;font-weight:700}.ds-status-wrap[data-state=ready] .ds-status{color:var(--color-success);background:var(--color-success-bg)}.ds-status-wrap[data-state=failed] .ds-status{color:var(--color-error);background:var(--color-error-bg)}.ds-status-wrap[data-state=loading] .ds-status,.ds-status-wrap[data-state=draining] .ds-status,.ds-status-wrap[data-state=unloading] .ds-status{color:var(--color-warning);background:var(--color-warning-bg)}.ds-status-wrap[data-state=loading] .ds-status:before,.ds-status-wrap[data-state=draining] .ds-status:before,.ds-status-wrap[data-state=unloading] .ds-status:before{animation:pulse var(--motion-slow) ease-in-out infinite alternate}.ds-progress .progress-bar__fill{border-radius:inherit;background:linear-gradient(90deg,#2f6cff,#7b61ff);height:100%}.ds-progress .progress-bar--indeterminate{background:var(--color-bg-neutral);animation:none}.ds-progress .progress-bar--indeterminate .progress-bar__fill{width:48%;animation:slide var(--motion-slow) ease-in-out infinite alternate;display:block}.ds-empty .empty-state{gap:var(--space-2);width:100%;min-height:0;padding:0;animation:none}.ds-empty .empty-state__illustration{border-radius:var(--radius-md);background:var(--color-selection);width:44px;height:44px;color:var(--color-focus);place-items:center;margin:0;display:grid}.ds-empty .empty-state__illustration:before{content:none}.ds-empty .empty-state__content{justify-items:center;gap:var(--space-2);min-width:0;max-width:100%;margin:0;display:grid}.ds-empty .empty-state__title{margin:0;font-size:1.5em;font-weight:700;line-height:normal}.ds-empty .empty-state__description{color:var(--color-text);overflow-wrap:anywhere;line-height:normal}.ds-tabs.tabs{gap:var(--space-4);min-width:0}.ds-tabs .tabs__container{box-shadow:none;background:0 0;border:0;border-radius:0;margin:0;padding:0;overflow:visible}.ds-tabs .tabs__list{min-width:0;overflow:visible}.ds-tabs.tabs--fill-container .tabs__tab{white-space:normal;overflow-wrap:anywhere;flex:8rem;min-width:0}.ds-tabs .tabs__tab--active{box-shadow:inset 0 0 0 1px var(--color-separator);transform:none}.ds-tabs .tabs__panel{border:0;min-width:0;padding:0;animation:none}.ds-tabs .tabs__tab-label{white-space:normal;overflow-wrap:anywhere}.ds-common-select .select__trigger{min-width:0;min-height:36px;font:inherit;padding:8px 10px}.ds-common-select .select__value-label,.select__option-label{white-space:normal;overflow-wrap:anywhere}.ds-common-select .select__value{overflow:visible}.ds-common-select .select--labelled{gap:var(--space-2)}.ds-common-select .select__label{color:var(--color-text);font-size:.9rem;font-weight:650}.select__dropdown--portal{max-width:calc(100vw - 16px)}.tooltip__wrapper.ds-tooltip-trigger{min-width:0;max-width:100%}.ds-drawer-host{display:contents}.drawer.ds-drawer{color:var(--color-text);background:var(--color-bg-elevated);border:1px solid var(--color-separator);border-radius:var(--radius-xl);inset:12px auto 12px 12px;overflow:hidden;transform:translate(calc(-100% - 12px));box-shadow:0 30px 120px #00000052;width:min(320px,100vw - 32px)!important;max-width:calc(100vw - 32px)!important}.drawer.ds-drawer.drawer--open{transform:translate(0)}.ds-drawer .drawer__header{padding:var(--space-4) var(--space-5);border-bottom:1px solid var(--color-separator)}.ds-drawer .drawer__title{color:var(--color-text);font-size:1.1rem}.ds-drawer .drawer__close-btn{color:var(--color-text)}.ds-drawer .drawer__close-btn:focus-visible{box-shadow:var(--focus-ring);outline:none}.ds-drawer .drawer__content{padding:var(--space-5)}.base-card.ds-card{display:block}.base-card.ds-card:focus-visible{outline:2px solid var(--color-focus);outline-offset:2px}.page-layout.ds-page-layout{padding-inline:0}.ds-page-header{min-width:0;max-width:100%}.ds-page-header .page-header{margin:0}.ds-page-header .page-header__title{color:var(--color-text);letter-spacing:-.025em;overflow-wrap:anywhere;margin:0;font-size:clamp(1.45rem,2.6vw,1.75rem);font-weight:700;line-height:1.12}.ds-page-header .page-header__description{color:var(--color-muted);overflow-wrap:anywhere;margin:1em 0 0;font-size:1rem;line-height:1.55}.ds-stat-card .stat-card__label,.ds-stat-card .stat-card__value{text-overflow:clip;white-space:normal;overflow-wrap:anywhere;min-width:0;overflow:visible}.ds-stat-card .stat-card__label{color:var(--color-text);letter-spacing:normal;text-transform:none;font-size:.9rem}.ds-stat-card .stat-card__value{color:var(--color-text);font-size:1.25rem}.ds-stat-card .stat-card__hint{color:var(--color-muted);font-size:.85rem}.ds-stat-card .stat-card__hint p{margin:var(--space-1) 0 0}.base-card.ds-stat-card:hover{box-shadow:none;transform:none}.ds-loading{gap:var(--space-2);display:grid}.ds-loading__label{color:var(--color-muted);margin:0}.ds-loading__shapes{gap:var(--space-2);display:grid}.badge.ds-badge{letter-spacing:normal;text-transform:none;white-space:normal;overflow-wrap:anywhere;min-height:20px}.badge.ds-badge.badge--primary{color:var(--color-text);box-shadow:inset 0 0 0 1px var(--color-focus);background-color:#0000}.ds-banner .error-state{gap:var(--space-2);text-align:start;place-content:start stretch;place-items:start;min-height:0;padding:0;display:grid}.ds-banner .error-state__title{color:inherit;font-size:inherit;font-weight:700;line-height:inherit;margin:0}.ds-banner .error-state__message{max-width:none;color:inherit;font-size:inherit;line-height:inherit;margin:0}.ds-common-table{color:var(--color-text);background:var(--material-content-bg);border-radius:var(--radius-lg)}.ds-row-activation{display:contents}.ds-row-activation :where(tbody>tr:has(.ds-row-primary:not(:disabled,[aria-disabled=true]))){cursor:pointer}.ds-row-activation :where(tbody>tr:has(.ds-row-primary:not(:disabled,[aria-disabled=true])):hover){background-color:var(--token-colorFillQuaternary)}.ds-row-activation tbody>tr:has(.ds-row-primary:focus-visible){outline:2px solid var(--color-focus);outline-offset:-2px}@media (width<=560px),(pointer:coarse){.app-toolbar .button.ds-icon-button.button--inline{min-width:44px;min-height:44px}}:root[data-high-contrast=on] .button.ds-button,:root[data-high-contrast=on] .button.ds-icon-button{border-width:2px}@media (prefers-contrast:more){:root:not([data-high-contrast=off]) .button.ds-button,:root:not([data-high-contrast=off]) .button.ds-icon-button{border-width:2px}}.gallery-progress-samples{align-content:start;gap:var(--space-4);min-width:0;display:grid} +:root{--token-borderRadius:.375rem;--token-borderRadiusLG:.5rem;--token-borderRadiusSM:.25rem;--token-borderRadiusXL:.75rem;--token-controlHeightSM:2rem;--token-controlHeight:2.5rem;--token-controlHeightLG:2.75rem;--token-boxShadow:0 1px 2px 0 #00000008, 0 1px 6px -1px #00000005, 0 2px 4px 0 #00000005;--token-boxShadowSecondary:0 6px 16px 0 #00000014, 0 3px 6px -4px #0000001f, 0 9px 28px 8px #0000000d;--token-boxShadowTertiary:0 1px 3px #0000001a;--token-buttonActiveTransform:scale(.97);--token-buttonBorderRadius:.375rem;--token-buttonHoverTransform:translateY(-1px);--token-buttonDangerBg:transparent;--token-buttonDangerBgActive:#ff4d4f33;--token-buttonDangerBgHover:#ff4d4f1a;--token-buttonDangerBorder:1px solid #c82333;--token-buttonDangerShadow:none;--token-buttonDangerText:#c82333;--token-buttonGhostBackdrop:none;--token-buttonGhostBg:transparent;--token-buttonGhostBgActive:#f5f5f5;--token-buttonGhostBgHover:#ff7a000f;--token-buttonGhostBorder:1px solid transparent;--token-buttonGhostBorderHover:1px solid transparent;--token-buttonGhostShadow:none;--token-buttonGhostShadowHover:none;--token-buttonPrimaryBackdrop:none;--token-buttonPrimaryBg:var(--token-colorPrimary);--token-buttonPrimaryBgHover:#e86e00;--token-buttonPrimaryBorder:none;--token-buttonPrimaryShadow:0 2px 4px #ff7a0033;--token-buttonPrimaryShadowHover:0 4px 8px #ff7a0040;--token-buttonSecondaryBackdrop:none;--token-buttonSecondaryBg:transparent;--token-buttonSecondaryBgActive:#f5f5f5;--token-buttonSecondaryBgHover:#ff7a000f;--token-buttonSecondaryBorder:1px solid var(--token-colorBorder);--token-buttonSecondaryBorderHover:1px solid #ff7a004d;--token-buttonSecondaryShadow:none;--token-buttonSuccessBackdrop:none;--token-buttonSuccessBg:var(--token-colorSuccess);--token-buttonSuccessBgHover:#006654;--token-buttonSuccessBorder:none;--token-buttonSuccessShadow:0 2px 4px #00bd9b33;--token-colorBgContainer:#fff;--token-colorBgElevated:#fff;--token-colorBgLayout:#f5f5f5;--token-colorBgMask:#00000073;--token-colorBgTextActive:#00000014;--token-colorBgTextHover:#0000000a;--token-colorBorder:#d9d9d9;--token-colorBorderSecondary:#e5e7eb;--token-colorFillQuaternary:#fafafa;--token-colorFillSecondary:#f3f4f6;--token-colorFillTertiary:#f9fafb;--token-colorError:#c82333;--token-colorInfo:#06c;--token-colorLink:#ff7a00;--token-colorLinkHover:#7c3aed;--token-colorPrimary:#ff7a00;--token-colorPrimaryActive:#cc6200;--token-colorPrimaryBg:#ff7a001a;--token-colorPrimaryBgHover:#ff7a0029;--token-colorPrimaryBorder:#ff7a0033;--token-colorSuccess:#007a63;--token-colorSuccessActive:#005244;--token-colorSuccessBg:#00bd9b0d;--token-colorSuccessBorder:#00bd9b66;--token-colorSuccessBorderHover:#00bd9b99;--token-colorSuccessBoxShadow:0 4px 12px #00bd9b26;--token-colorWarning:#9a5d00;--token-colorText:#141414;--token-colorTextDisabled:#767676;--token-colorTextPlaceholder:#767676;--token-colorTextQuaternary:#bfbfbf;--token-colorTextSecondary:#595959;--token-colorTextTertiary:#737373;--token-focusRingColor:#b95b06;--token-focusRingOffset:2px;--token-focusRingStyle:solid;--token-focusRingWidth:2px;--token-fontFamily:"Ubuntu Sans", "Pretendard Variable", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;--token-fontSize:.875rem;--token-fontSizeLG:1rem;--token-fontSizeSM:.75rem;--token-fontSizeXL:1.25rem;--token-fontSizeXXL:1.5rem;--token-fontSizeXXS:.5rem;--token-marginXXS:4px;--token-padding:.75rem;--token-paddingLG:1.5rem;--token-paddingMD:1rem;--token-paddingSM:.5rem;--token-paddingXL:2rem;--token-paddingXS:.25rem;--token-paddingXXS:.125rem;--token-scrollbarSize:.5rem;--token-scrollbarRadius:.25rem;--token-motionDurationFast:.1s;--token-motionDurationMid:.2s;--token-motionDurationSlow:.3s;--token-themeTransitionDuration:.25s;--token-themeTransitionTiming:ease-in-out;--token-tabActiveBg:#ff7a001a;--token-tabFocusShadow:0 0 0 3px #ff7a0026;--token-tabHoverBg:var(--token-colorFillSecondary);--token-zIndexDrawer:1100;--token-zIndexDrawerContent:1101;--token-zIndexPopover:1150;--token-zIndexTooltip:1300;--token-fontSizeHeading1:2rem;--token-fontSizeHeading2:1.5rem;--token-fontSizeHeading3:1.25rem;--token-fontSizeHeading4:1rem;--token-fontSizeDisplay4:1.75rem;--token-boxShadowDrawerRight:-4px 0 20px #00000026;--token-buttonPrimaryBgActive:var(--token-colorPrimaryActive);--token-buttonSuccessBgActive:var(--token-colorSuccessActive);--token-buttonDangerShadowHover:var(--token-buttonDangerShadow);--token-buttonSuccessShadowHover:var(--token-buttonSuccessShadow);--token-buttonSecondaryShadowHover:0 2px 6px #0000000f, inset 0 1px 0 #fffc;scrollbar-width:thin;scrollbar-color:var(--token-colorBorder,#d9d9d9) transparent}::-webkit-scrollbar{width:var(--token-scrollbarSize,.5rem);height:var(--token-scrollbarSize,.5rem)}::-webkit-scrollbar-track{background:0 0}::-webkit-scrollbar-thumb{background-color:var(--token-colorBorder,#d9d9d9);border-radius:var(--token-scrollbarRadius,.25rem)}::-webkit-scrollbar-thumb:hover{background-color:var(--token-colorTextTertiary,#737373)}[data-theme=mlxcel-light],[data-theme=mlxcel-dark],[data-theme=glass-light],[data-theme=glass-dark]{--token-boxShadow:var(--shadow-card);--token-boxShadowDrawerRight:var(--shadow-card);--token-boxShadowSecondary:var(--shadow-card);--token-boxShadowTertiary:var(--shadow-chrome);--token-buttonActiveTransform:none;--token-buttonDangerBg:var(--button-danger-fill);--token-buttonDangerBgActive:var(--button-danger-fill-active);--token-buttonDangerBgHover:var(--button-danger-fill-active);--token-buttonDangerBorder:1px solid var(--color-separator);--token-buttonDangerShadow:none;--token-buttonDangerShadowHover:none;--token-buttonDangerText:white;--token-buttonGhostBackdrop:none;--token-buttonGhostBg:transparent;--token-buttonGhostBgActive:var(--color-selection);--token-buttonGhostBgHover:var(--color-selection);--token-buttonGhostBorder:1px solid var(--color-separator);--token-buttonGhostBorderHover:1px solid var(--color-separator);--token-buttonGhostShadow:none;--token-buttonGhostShadowHover:none;--token-buttonHoverTransform:none;--token-buttonPrimaryBackdrop:none;--token-buttonPrimaryBg:var(--button-primary-fill);--token-buttonPrimaryBgActive:var(--button-primary-fill-active);--token-buttonPrimaryBgHover:var(--button-primary-fill-active);--token-buttonPrimaryBorder:1px solid var(--color-separator);--token-buttonPrimaryShadow:none;--token-buttonPrimaryShadowHover:none;--token-buttonSecondaryBackdrop:none;--token-buttonSecondaryBg:var(--material-control-bg);--token-buttonSecondaryBgActive:var(--color-selection);--token-buttonSecondaryBgHover:var(--color-selection);--token-buttonSecondaryBorder:1px solid var(--color-separator);--token-buttonSecondaryBorderHover:1px solid var(--color-separator);--token-buttonSecondaryShadow:none;--token-buttonSecondaryShadowHover:none;--token-buttonSuccessBackdrop:none;--token-buttonSuccessBg:var(--color-success);--token-buttonSuccessBgActive:var(--color-success);--token-buttonSuccessBgHover:var(--color-success);--token-buttonSuccessBorder:1px solid var(--color-separator);--token-buttonSuccessShadow:none;--token-buttonSuccessShadowHover:none;--token-colorBgContainer:var(--color-bg-elevated);--token-colorBgElevated:var(--color-bg-elevated);--token-colorBgLayout:var(--color-bg);--token-colorBgMask:#080a0e6b;--token-colorBgTextActive:var(--color-selection);--token-colorBgTextHover:var(--color-selection);--token-colorBorder:var(--color-separator);--token-colorBorderSecondary:var(--color-separator);--token-colorError:var(--color-error);--token-colorFillQuaternary:var(--color-bg-neutral);--token-colorFillSecondary:var(--color-bg-neutral);--token-colorFillTertiary:var(--color-bg-neutral);--token-colorInfo:var(--color-focus);--token-colorLink:var(--color-focus);--token-colorLinkHover:var(--color-focus);--token-colorPrimary:var(--color-focus);--token-colorPrimaryActive:var(--color-focus);--token-colorPrimaryBg:var(--color-selection);--token-colorPrimaryBgHover:var(--color-selection);--token-colorPrimaryBorder:var(--color-separator);--token-colorSuccess:var(--color-success);--token-colorSuccessActive:var(--color-success);--token-colorSuccessBg:var(--color-success-bg);--token-colorSuccessBorder:var(--color-separator);--token-colorSuccessBorderHover:var(--color-separator);--token-colorSuccessBoxShadow:none;--token-colorText:var(--color-text);--token-colorTextDisabled:var(--color-muted);--token-colorTextPlaceholder:var(--color-muted);--token-colorTextQuaternary:var(--color-muted);--token-colorTextSecondary:var(--color-muted);--token-colorTextTertiary:var(--color-muted);--token-colorWarning:var(--color-warning);--token-focusRingColor:var(--color-focus);--token-tabActiveBg:var(--color-bg-elevated);--token-tabFocusShadow:var(--focus-ring);--token-tabHoverBg:var(--color-selection)}[data-theme=mlxcel-light]{--color-bg:#f3f4f6;--color-bg-elevated:#fff;--color-bg-neutral:#f8f8fa;--color-text:#151a24;--color-muted:#59647a;--color-separator:#212a3d1f;--color-focus:#245bd8;--color-selection:#242a3714;--color-warning:#8a5200;--color-warning-bg:#fff4d8;--color-error:#b42318;--color-error-bg:#fff0ed;--color-success:#137333;--color-success-bg:#eaf7ee;--material-glass-bg:rgba(248, 249, 251, var(--material-glass-alpha));--material-content-bg:#ffffffd1;--material-control-bg:#ffffff94;--shadow-chrome:0 1px 0 #ffffff9e inset;--shadow-card:0 12px 36px #1f253412}[data-theme=mlxcel-dark]{--color-bg:#0e1117;--color-bg-elevated:#181d27;--color-bg-neutral:#111722;--color-text:#f5f7fb;--color-muted:#aeb8c9;--color-separator:#ffffff1f;--color-focus:#9dbdff;--color-selection:#ffffff1a;--color-warning:#ffd28a;--color-warning-bg:#8b5c0038;--color-error:#ffb4a8;--color-error-bg:#982b1c3d;--color-success:#9be6b0;--color-success-bg:#196c3738;--material-glass-bg:rgba(24, 28, 36, var(--material-glass-alpha));--material-content-bg:#191d26d6;--material-control-bg:#ffffff14;--shadow-chrome:0 1px 0 #ffffff14 inset;--shadow-card:0 14px 40px #00000038}[data-theme=mlxcel-light],[data-theme=mlxcel-dark]{--button-primary-fill:#245bd8;--button-primary-fill-active:#1c4dbc;--button-danger-fill:#c6352b;--button-danger-fill-active:#aa2b23}[data-theme=glass-light]{--color-bg:#e6ebf3;--color-bg-elevated:#fbfbfd;--color-bg-neutral:#f1f2f6;--color-text:#1d1d1f;--color-muted:#545458;--color-separator:#3c3c4324;--color-focus:#0058b9;--color-selection:#0058b91a;--color-warning:#8a4f00;--color-warning-bg:#ff95001f;--color-error:#b3261e;--color-error-bg:#ff3b301a;--color-success:#1b6f3c;--color-success-bg:#34c7591f;--material-glass-bg:linear-gradient(180deg, #ffffff5c, #fff0 64px), rgba(248, 249, 252, var(--material-glass-alpha));--material-content-bg:#fffffff0;--material-control-bg:linear-gradient(180deg, #ffffff80, #fff0 60%), #7878801f;--shadow-chrome:inset 0 1px 0 #ffffffb8;--shadow-card:0 1px 2px #0f172a0a, 0 10px 30px #0f172a12;--shadow-popover:0 12px 40px #0000001f, 0 4px 12px #0000000f;--glass-edge:#ffffff26;--glass-highlight:linear-gradient(180deg, #ffffff2e 0%, #ffffff0d 40%, transparent 100%);--glass-button-shadow:0 1px 3px #0058b933;--glass-danger-shadow:0 1px 3px #b3261e33;--button-primary-solid:#0058b9;--button-primary-fill-active:#004a9c;--button-danger-solid:#b3261e;--button-danger-fill-active:#99201a}[data-theme=glass-dark]{--color-bg:#0b0d12;--color-bg-elevated:#1c1c1f;--color-bg-neutral:#232327;--color-text:#f5f5f7;--color-muted:#b8b8bc;--color-separator:#ffffff1f;--color-focus:#6cb2ff;--color-selection:#409cff2e;--color-warning:#ffb340;--color-warning-bg:#ff9f0a24;--color-error:#ff7b72;--color-error-bg:#ff453a29;--color-success:#4cd964;--color-success-bg:#32d74b24;--material-glass-bg:linear-gradient(180deg, #ffffff14, #fff0 64px), rgba(30, 30, 34, var(--material-glass-alpha));--material-content-bg:#242428f0;--material-control-bg:linear-gradient(180deg, #ffffff1a, #fff0 60%), #ffffff1a;--shadow-chrome:inset 0 1px 0 #ffffff24;--shadow-card:0 1px 2px #0000004d, 0 12px 32px #00000047;--shadow-popover:0 12px 40px #00000073, 0 4px 12px #0000004d;--glass-edge:#ffffff1a;--glass-highlight:linear-gradient(180deg, #ffffff26 0%, #ffffff0a 40%, transparent 100%);--glass-button-shadow:0 1px 3px #00000059;--glass-danger-shadow:0 1px 3px #00000059;--button-primary-solid:#0a5bc0;--button-primary-fill-active:#0a4ea6;--button-danger-solid:#b3261e;--button-danger-fill-active:#99201a}[data-theme=glass-light],[data-theme=glass-dark]{--button-primary-fill:var(--glass-highlight), var(--button-primary-solid);--button-danger-fill:var(--glass-highlight), var(--button-danger-solid);--token-boxShadowSecondary:var(--shadow-popover);--token-buttonActiveTransform:scale(.985);--token-buttonDangerBorder:1px solid var(--glass-edge);--token-buttonDangerShadow:var(--glass-danger-shadow);--token-buttonDangerShadowHover:var(--glass-danger-shadow);--token-buttonPrimaryBorder:1px solid var(--glass-edge);--token-buttonPrimaryShadow:var(--glass-button-shadow);--token-buttonPrimaryShadowHover:var(--glass-button-shadow);--token-buttonSecondaryShadow:var(--shadow-chrome);--token-buttonSecondaryShadowHover:var(--shadow-chrome);--token-colorBgMask:#080a0e52}:root[data-theme-family=glass][data-material=opaque],:root[data-theme-family=glass][data-reduce-transparency=true],:root[data-theme-family=glass][data-backdrop-filter=unsupported],:root[data-theme-family=glass][data-high-contrast=on]{--material-content-bg:var(--color-bg-elevated);--material-control-bg:var(--color-bg-neutral);--button-primary-fill:var(--button-primary-solid);--button-danger-fill:var(--button-danger-solid)}@media (prefers-reduced-transparency:reduce){:root[data-theme-family=glass]{--material-content-bg:var(--color-bg-elevated);--material-control-bg:var(--color-bg-neutral);--button-primary-fill:var(--button-primary-solid);--button-danger-fill:var(--button-danger-solid)}}@media (prefers-contrast:more){:root[data-theme-family=glass]:not([data-high-contrast=off]){--material-content-bg:var(--color-bg-elevated);--material-control-bg:var(--color-bg-neutral);--button-primary-fill:var(--button-primary-solid);--button-danger-fill:var(--button-danger-solid)}}:root[data-theme-family=glass][data-reduce-motion=true]{--token-buttonActiveTransform:none}@media (prefers-reduced-motion:reduce){:root[data-theme-family=glass]{--token-buttonActiveTransform:none}}.settings-sections{overflow-wrap:anywhere;min-width:0}.settings-sections .ds-field{min-width:0}.button{font-family:var(--token-fontFamily,"Ubuntu Sans", "Pretendard Variable", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif);border-radius:var(--token-buttonBorderRadius,var(--token-borderRadius,.375rem));cursor:pointer;transition:background var(--token-motionDurationFast,.1s) ease-out, border-color var(--token-motionDurationFast,.1s) ease-out, box-shadow var(--token-motionDurationMid,.2s) ease-out, transform .15s cubic-bezier(.25, .46, .45, .94), color var(--token-motionDurationFast,.1s) ease-out, opacity var(--token-motionDurationFast,.1s) ease-out;white-space:nowrap;min-height:var(--token-controlHeightLG,2.75rem);border:1px solid #0000;justify-content:center;align-items:center;gap:.375rem;font-weight:500;display:inline-flex;position:relative}.button:disabled{opacity:.6;cursor:not-allowed}.button:focus-visible{outline:var(--token-focusRingWidth,2px) var(--token-focusRingStyle,solid) var(--token-focusRingColor,var(--token-colorPrimary));outline-offset:var(--token-focusRingOffset,2px)}.button--full-width{width:100%}.button.button--inline{--token-buttonHoverTransform:none;--token-buttonActiveTransform:none;--token-buttonGhostBorder:none;--token-buttonGhostBorderHover:none;--token-buttonSecondaryBorder:none;--token-buttonSecondaryBorderHover:none;--token-buttonPrimaryBorder:none;--token-buttonDangerBorder:none;min-height:auto;transition:background-color var(--token-motionDurationFast,.1s) ease-out, color var(--token-motionDurationFast,.1s) ease-out;line-height:1}.button--inline{justify-content:flex-start}.button.button--inline>svg{flex-shrink:0;display:block}.button.button--inline:hover:not(:disabled),.button.button--inline:active:not(:disabled){box-shadow:none!important;transform:none!important}.button--xsmall{font-size:var(--token-fontSizeSM,.75rem);gap:.1875rem;min-height:1.75rem;padding:.125rem .375rem}.button--small{padding:var(--token-paddingXS,.25rem) var(--token-paddingSM,.5rem);font-size:var(--token-fontSizeSM,.75rem);min-height:var(--token-controlHeightSM,2rem);gap:.25rem}.button--medium{padding:var(--token-paddingXS,.25rem) var(--token-padding,.75rem);font-size:var(--token-fontSize,.875rem);gap:.375rem}.button--large{padding:var(--token-paddingSM,.5rem) var(--token-paddingMD,1rem);font-size:var(--token-fontSize,.875rem);gap:.5rem}.button--icon-only{padding:var(--token-paddingXS,.25rem);aspect-ratio:1}.button--icon-only.button--xsmall{padding:.125rem}.button--icon-only.button--small{padding:var(--token-paddingXS,.25rem)}.button--icon-only.button--large{padding:var(--token-paddingSM,.5rem)}.button--circle{aspect-ratio:1;padding:var(--token-paddingXS,.25rem);border-radius:50%}.button--circle.button--xsmall{padding:.125rem}.button--circle.button--small{padding:var(--token-paddingXS,.25rem)}.button--circle.button--large{padding:var(--token-paddingSM,.5rem)}.button--primary{background:var(--token-buttonPrimaryBg,linear-gradient(180deg, #fff3 0%, transparent 50%), #8b5cf6);color:#fff;border:var(--token-buttonPrimaryBorder,none);box-shadow:var(--token-buttonPrimaryShadow,0 2px 6px #8b5cf640, inset 0 1px 1px #fff3);-webkit-backdrop-filter:var(--token-buttonPrimaryBackdrop,none)}.button--primary:hover:not(:disabled){background:var(--token-buttonPrimaryBgHover,linear-gradient(180deg, #ffffff40 0%, transparent 50%), #7c3aed);box-shadow:var(--token-buttonPrimaryShadowHover,0 4px 10px #8b5cf64d, inset 0 1px 1px #ffffff40);transform:var(--token-buttonHoverTransform,translateY(-1px))}.button--primary:active:not(:disabled){background:var(--token-buttonPrimaryBgActive,var(--token-colorPrimaryActive,#6d28d9));transform:var(--token-buttonActiveTransform,scale(.97));box-shadow:var(--token-buttonPrimaryShadow,0 2px 6px #8b5cf640, inset 0 1px 1px #fff3)}.button--secondary{background:var(--token-buttonSecondaryBg,#8b5cf60a);color:var(--token-colorTextSecondary,#595959);border:var(--token-buttonSecondaryBorder,1px solid #8b5cf633);box-shadow:var(--token-buttonSecondaryShadow,0 1px 3px #0000000a, inset 0 1px 0 #fffc);-webkit-backdrop-filter:var(--token-buttonSecondaryBackdrop,none)}.button--secondary:hover:not(:disabled){background:var(--token-buttonSecondaryBgHover,#8b5cf614);border:var(--token-buttonSecondaryBorderHover,1px solid #8b5cf64d);color:var(--token-colorText,#141414);box-shadow:var(--token-buttonSecondaryShadowHover,var(--token-buttonSecondaryShadow,0 1px 3px #0000000a, inset 0 1px 0 #fffc));transform:var(--token-buttonHoverTransform,translateY(-1px))}.button--secondary:active:not(:disabled){background:var(--token-buttonSecondaryBgActive,var(--token-colorBgLayout,#f5f5f5));transform:var(--token-buttonActiveTransform,scale(.97));box-shadow:var(--token-buttonSecondaryShadow,0 1px 3px #0000000a, inset 0 1px 0 #fffc)}.button--danger{background:var(--token-buttonDangerBg,transparent);color:var(--token-buttonDangerText,var(--token-colorError,#c82333));border:var(--token-buttonDangerBorder,1px solid #c82333);box-shadow:var(--token-buttonDangerShadow,none)}.button--danger:hover:not(:disabled){background:var(--token-buttonDangerBgHover,#ff4d4f1a);border-color:var(--token-colorError,#c82333);box-shadow:var(--token-buttonDangerShadowHover,var(--token-buttonDangerShadow,none));transform:var(--token-buttonHoverTransform,translateY(-1px))}.button--danger:active:not(:disabled){background:var(--token-buttonDangerBgActive,#ff4d4f33);transform:var(--token-buttonActiveTransform,scale(.97));box-shadow:var(--token-buttonDangerShadow,none)}.button--success{background:var(--token-buttonSuccessBg,linear-gradient(180deg, #fff3 0%, transparent 50%), #007a63);color:#fff;border:var(--token-buttonSuccessBorder,none);box-shadow:var(--token-buttonSuccessShadow,0 2px 6px #00bd9b40, inset 0 1px 1px #fff3);-webkit-backdrop-filter:var(--token-buttonSuccessBackdrop,none)}.button--success:hover:not(:disabled){background:var(--token-buttonSuccessBgHover,linear-gradient(180deg, #ffffff40 0%, transparent 50%), #006654);box-shadow:var(--token-buttonSuccessShadowHover,var(--token-buttonSuccessShadow,0 2px 6px #00bd9b40, inset 0 1px 1px #fff3));transform:var(--token-buttonHoverTransform,translateY(-1px))}.button--success:active:not(:disabled){background:var(--token-buttonSuccessBgActive,var(--token-colorSuccessActive,#005244));transform:var(--token-buttonActiveTransform,scale(.97));box-shadow:var(--token-buttonSuccessShadow,0 2px 6px #00bd9b40, inset 0 1px 1px #fff3)}.button--ghost{background:var(--token-buttonGhostBg,transparent);color:var(--token-colorTextSecondary,#595959);border:var(--token-buttonGhostBorder,1px solid transparent);box-shadow:var(--token-buttonGhostShadow,none);-webkit-backdrop-filter:var(--token-buttonGhostBackdrop,none)}.button--ghost:hover:not(:disabled){background:var(--token-buttonGhostBgHover,#8b5cf60f);border:var(--token-buttonGhostBorderHover,var(--token-buttonGhostBorder,1px solid transparent));color:var(--token-colorText,#141414);box-shadow:var(--token-buttonGhostShadowHover,none);transform:var(--token-buttonHoverTransform,translateY(-1px))}.button--ghost:active:not(:disabled){background:var(--token-buttonGhostBgActive,var(--token-colorBgLayout,#f5f5f5));transform:var(--token-buttonActiveTransform,scale(.97))}.button--text{color:var(--token-colorTextSecondary,#595959);box-shadow:none;background:0 0;border:1px solid #0000;min-height:auto;padding:.25rem .5rem}.button--text:hover:not(:disabled){background:var(--token-colorBgTextHover,#0000000a);color:var(--token-colorText,#141414);transform:none}.button--text:active:not(:disabled){background:var(--token-colorBgTextActive,#00000014);transform:none}.button--outline{color:var(--token-colorTextSecondary,#595959);border:1px solid var(--token-colorBorderSecondary,#00000026);box-shadow:none;background:0 0}.button--outline:hover:not(:disabled){background:var(--token-colorBgTextHover,#0000000a);border-color:var(--token-colorPrimary,#8b5cf6);color:var(--token-colorPrimary,#8b5cf6);transform:var(--token-buttonHoverTransform,translateY(-1px))}.button--outline:active:not(:disabled){background:var(--token-colorBgTextActive,#00000014);transform:var(--token-buttonActiveTransform,scale(.97))}.button[role=tab]{border:1px solid #0000}.button[role=tab]:hover:not(:disabled),.button[role=tab]:active:not(:disabled){transform:none}.button--active{color:var(--token-colorPrimary,#8b5cf6);font-weight:600}.button--active.button--ghost,.button--active.button--text{background:var(--token-colorPrimaryBg,#1677ff14);color:var(--token-colorPrimary,#8b5cf6)}.button--active.button--outline,.button--active.button--secondary{background:var(--token-colorPrimaryBg,#1677ff14);border-color:var(--token-colorPrimary,#8b5cf6);color:var(--token-colorPrimary,#8b5cf6)}.button--loading{pointer-events:none}.button--loading .button__text,.button--loading .button__icon{opacity:0}.button__loading-spinner{border:.125rem solid;border-top-color:#0000;border-radius:50%;width:.875rem;height:.875rem;animation:.6s linear infinite button-spinner-rotate;position:absolute}@keyframes button-spinner-rotate{to{transform:rotate(360deg)}}.button__icon{justify-content:center;align-items:center;line-height:1;display:inline-flex}.button__icon svg{display:block}.button__text{line-height:1}@media (prefers-reduced-motion:reduce){.button{transition:none}.button:hover:not(:disabled),.button:active:not(:disabled){transform:none}.button__loading-spinner{opacity:.6;border-top-color:currentColor;animation:none}}.badge{border-radius:var(--token-borderRadiusSM,.25rem);text-transform:uppercase;letter-spacing:.02em;white-space:nowrap;justify-content:center;align-items:center;min-height:1.5rem;font-weight:600;display:inline-flex}.badge--small{padding:var(--token-paddingXXS,.125rem) var(--token-paddingSM,.5rem);font-size:var(--token-fontSizeSM,.75rem)}.badge--medium{padding:var(--token-paddingXS,.25rem) var(--token-paddingMD,1rem);font-size:var(--token-fontSizeSM,.75rem)}.badge--default{background-color:var(--token-colorFillSecondary,#f3f4f6);color:var(--token-colorTextSecondary,#595959)}.badge--primary{color:var(--token-colorPrimary,#8b5cf6);background-color:#1890ff1f}.badge--success{color:var(--token-colorSuccess,#007a63);background-color:#52c41a1f}.badge--warning{color:var(--token-colorWarning,#9a5d00);background-color:#faad141f}.badge--danger{color:var(--token-colorError,#c82333);background-color:#ff4d4f1f}.badge--info{color:var(--token-colorInfo,#06c);background-color:#028df21f}.status-tag{align-items:center;gap:var(--token-paddingXXS,4px);display:inline-flex}.status-tag__indicator{background-color:currentColor;border-radius:50%;width:6px;height:6px;animation:1.6s ease-in-out infinite status-tag-pulse;display:inline-block}@keyframes status-tag-pulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.45;transform:scale(.85)}}.status-tag__label{display:inline-block}@media (prefers-reduced-motion:reduce){.status-tag__indicator{animation:none}}.progress-bar-wrapper{align-items:center;gap:.5rem;width:100%;display:flex}.progress-bar{background:var(--token-colorFillSecondary,#f3f4f6);border-radius:999px;flex:1;position:relative;overflow:hidden}.progress-bar--sm{height:4px}.progress-bar--md{height:6px}.progress-bar--lg{height:8px}.progress-bar__fill{border-radius:999px;height:100%;transition:none}.progress-bar--animated .progress-bar__fill{transition:width .3s}.progress-bar--primary .progress-bar__fill{background:var(--token-colorPrimary,#8b5cf6)}.progress-bar--success .progress-bar__fill{background:var(--token-colorSuccess,#52c41a)}.progress-bar--error .progress-bar__fill{background:var(--token-colorError,#ff4d4f)}.progress-bar--warning .progress-bar__fill{background:var(--token-colorWarning,#faad14)}.progress-bar--indeterminate{background:linear-gradient(90deg, var(--token-colorFillSecondary,#f3f4f6) 0%, var(--token-colorPrimaryBg,#1890ff1a) 50%, var(--token-colorFillSecondary,#f3f4f6) 100%);background-size:200% 100%;animation:1.5s ease-in-out infinite progress-bar-shimmer}.progress-bar--indeterminate .progress-bar__fill{display:none}@keyframes progress-bar-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.progress-bar__label{font-size:var(--token-fontSizeSM,.75rem);color:var(--token-colorText,#141414);white-space:nowrap;text-align:right;min-width:3ch;font-weight:500}@media (prefers-reduced-motion:reduce){.progress-bar--indeterminate{animation:none}.progress-bar--animated .progress-bar__fill{transition:none}}.empty-state{padding:var(--token-paddingXL,2rem) var(--token-paddingLG,1.5rem);text-align:center;flex-direction:column;justify-content:center;align-items:center;min-height:300px;animation:.5s ease-out empty-state-fade-in;display:flex}@keyframes empty-state-fade-in{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.empty-state__illustration{margin-bottom:var(--token-paddingLG,1.5rem);position:relative}.empty-state__icon{color:var(--token-colorTextQuaternary,#bfbfbf);transition:color var(--token-motionDurationMid,.2s)}.empty-state__illustration:before{content:"";background:radial-gradient(circle, color-mix(in srgb, var(--token-colorPrimary,#8b5cf6) 8%, transparent) 0%, transparent 70%);z-index:-1;opacity:0;will-change:opacity, transform;border-radius:50%;animation:3s ease-in-out infinite glow-pulse;position:absolute;inset:-20px}@keyframes glow-pulse{0%,to{opacity:0;transform:scale(.95)}50%{opacity:1;transform:scale(1)}}.illustration-sparkle{transform-origin:50%;will-change:opacity, transform;animation:2s ease-in-out infinite sparkle-twinkle}@keyframes sparkle-twinkle{0%,to{opacity:.4;transform:scale(.8)}50%{opacity:1;transform:scale(1.2)}}.illustration-arrow{will-change:transform;animation:2s ease-in-out infinite arrow-bounce}@keyframes arrow-bounce{0%,to{transform:translateY(0)}50%{transform:translateY(5px)}}.illustration-needle{transform-origin:256px 308px;will-change:transform;animation:3s ease-in-out infinite needle-swing}@keyframes needle-swing{0%{transform:rotate(-12deg)}50%{transform:rotate(12deg)}to{transform:rotate(-12deg)}}.empty-state__content{margin-bottom:var(--token-paddingLG,1.5rem);max-width:480px}.empty-state__title{margin:0 0 var(--token-paddingSM,.5rem) 0;font-size:var(--token-fontSizeXL,1.25rem);color:var(--token-colorText,#141414);font-weight:600;line-height:1.4}.empty-state__description{font-size:var(--token-fontSize,.875rem);color:var(--token-colorTextSecondary,#595959);margin:0;line-height:1.6}.empty-state__actions{gap:var(--token-paddingMD,1rem);flex-wrap:wrap;justify-content:center;align-items:center;display:flex}.empty-state__action-btn{min-width:120px}.empty-state__action-link{font-size:var(--token-fontSize,.875rem);color:var(--token-colorLink,#8b5cf6);padding:var(--token-paddingXS,.25rem) var(--token-paddingSM,.5rem);border-radius:var(--token-borderRadiusSM,.25rem);transition:color var(--token-motionDurationFast,.1s), background-color var(--token-motionDurationFast,.1s);text-decoration:none}.empty-state__action-link:hover{color:var(--token-colorLinkHover,#7c3aed);background-color:var(--token-colorFillTertiary,#f9fafb)}.empty-state__action-link:focus{outline:var(--token-focusRingWidth,2px) var(--token-focusRingStyle,solid) var(--token-focusRingColor,var(--token-colorPrimary));outline-offset:var(--token-focusRingOffset,2px)}.empty-state--chat .empty-state__illustration:before{background:radial-gradient(circle, var(--token-colorPrimaryBg,#8b5cf61a) 0%, transparent 70%)}.empty-state--models .empty-state__illustration:before{background:radial-gradient(circle,#1890ff14 0%,#0000 70%)}.empty-state--creations .empty-state__illustration:before{background:radial-gradient(circle,#722ed114 0%,#0000 70%)}.empty-state--text .empty-state__illustration:before{background:radial-gradient(circle,#5263d114 0%,#0000 70%)}.empty-state--benchmark .empty-state__illustration:before{background:radial-gradient(circle,#00bd9b14 0%,#0000 70%)}.empty-state--statistics .empty-state__illustration:before{background:radial-gradient(circle,#13c2c214 0%,#0000 70%)}.empty-state--error .empty-state__illustration:before{background:radial-gradient(circle,#ff4d4f14 0%,#0000 70%)}@media (prefers-color-scheme:dark){.empty-state--chat .empty-state__illustration:before{background:radial-gradient(circle, var(--token-colorPrimaryBg,#8b5cf61a) 0%, transparent 70%)}.empty-state--models .empty-state__illustration:before{background:radial-gradient(circle,#1890ff1f 0%,#0000 70%)}.empty-state--creations .empty-state__illustration:before{background:radial-gradient(circle,#722ed11f 0%,#0000 70%)}.empty-state--text .empty-state__illustration:before{background:radial-gradient(circle,#5263d11f 0%,#0000 70%)}.empty-state--benchmark .empty-state__illustration:before{background:radial-gradient(circle,#00bd9b1f 0%,#0000 70%)}.empty-state--statistics .empty-state__illustration:before{background:radial-gradient(circle,#13c2c21f 0%,#0000 70%)}.empty-state--error .empty-state__illustration:before{background:radial-gradient(circle,#ff4d4f1f 0%,#0000 70%)}}@media (prefers-reduced-motion:reduce){.empty-state{animation:none}.empty-state__illustration:before{opacity:.5;animation:none}.illustration-sparkle,.illustration-arrow,.illustration-needle{animation:none}}@media (width<=768px){.empty-state{padding:var(--token-paddingLG,1.5rem) var(--token-paddingMD,1rem);min-height:250px}.empty-state__illustration{margin-bottom:var(--token-paddingMD,1rem)}.empty-state__icon{width:80px;height:80px}.empty-state__title{font-size:var(--token-fontSizeLG,1rem)}.empty-state__description{font-size:var(--token-fontSize,.875rem)}.empty-state__actions{gap:var(--token-paddingSM,.5rem);flex-direction:column;width:100%}.empty-state__action-btn{width:100%;min-width:unset}}@media (width<=480px){.empty-state__icon{width:64px;height:64px}.empty-state__title{font-size:var(--token-fontSizeLG,1rem)}}.tabs{flex-direction:column;width:100%;display:flex}.tabs__container{align-items:center;gap:var(--token-paddingXS,.25rem);margin:0 0 var(--token-paddingMD,1rem);display:flex;position:relative}.tabs__list{gap:var(--token-paddingXS,.25rem);padding:var(--token-paddingSM,.5rem) var(--token-paddingMD,1rem);background-color:var(--token-colorBgContainer,#fff);border:1px solid var(--token-colorBorderSecondary,#e5e7eb);border-radius:var(--token-borderRadiusXL,.75rem);z-index:10;box-shadow:var(--token-boxShadow,0 1px 2px 0 #00000008, 0 1px 6px -1px #00000005, 0 2px 4px 0 #00000005);scrollbar-width:none;scroll-behavior:smooth;-webkit-overflow-scrolling:touch;flex:1;min-width:0;display:flex;position:sticky;top:0;overflow:auto hidden}.tabs__list::-webkit-scrollbar{display:none}.tabs--overflow-menu .tabs__list{gap:var(--token-paddingMD,1rem)}.tabs__tab{align-items:center;gap:var(--token-paddingXS,.25rem);padding:var(--token-paddingSM,.5rem) var(--token-paddingMD,1rem);font-size:var(--token-fontSize,.875rem);color:var(--token-colorTextSecondary,#595959);border-radius:var(--token-borderRadiusLG,.5rem);cursor:pointer;transition:color var(--token-motionDurationFast,.1s), background-color var(--token-motionDurationFast,.1s);white-space:nowrap;background:0 0;border:none;flex-shrink:0;font-weight:500;display:flex}.tabs__tab:hover{color:var(--token-colorText,#141414);background-color:var(--token-tabHoverBg,#f3f4f6)}.tabs__tab:focus{box-shadow:var(--token-tabFocusShadow,0 0 0 3px #8b5cf626)}.tabs__tab:focus:not(:focus-visible){outline:none}.tabs__tab:focus-visible{outline:var(--token-focusRingWidth,2px) var(--token-focusRingStyle,solid) var(--token-focusRingColor,var(--token-colorPrimary));outline-offset:var(--token-focusRingOffset,2px)}.tabs__tab--active{color:var(--token-colorPrimary,#8b5cf6);background-color:var(--token-tabActiveBg,#8b5cf61a)}.tabs__tab--active:hover{background-color:var(--token-tabActiveBg,#8b5cf61a)}.tabs__tab-label{display:inline-block}.tabs__tag-badge{font-size:var(--token-fontSizeXXS,.5rem);text-transform:uppercase;letter-spacing:.03em;pointer-events:none;padding:1px 4px;line-height:1}.tabs__group{align-items:center;gap:var(--token-paddingXS,.25rem);flex-shrink:0;display:flex}.tabs__group-label{font-size:var(--token-fontSizeSM,.75rem);color:var(--token-colorTextTertiary,#737373);text-transform:uppercase;letter-spacing:.05em;white-space:nowrap;padding:0 var(--token-paddingXS,.25rem);-webkit-user-select:none;user-select:none;font-weight:600}.tabs__separator{background-color:var(--token-colorBorderSecondary,#e5e7eb);width:1px;height:24px;margin:0 var(--token-paddingSM,.5rem);flex-shrink:0}.tabs__group-tabs{gap:var(--token-paddingXS,.25rem);align-items:center;display:flex}.tabs__scroll-arrow{background-color:var(--token-colorBgContainer,#fff);border:1px solid var(--token-colorBorderSecondary,#e5e7eb);border-radius:var(--token-borderRadiusLG,.5rem);width:32px;height:32px;color:var(--token-colorTextSecondary,#595959);cursor:pointer;transition:background-color var(--token-motionDurationFast,.1s), color var(--token-motionDurationFast,.1s), border-color var(--token-motionDurationFast,.1s);box-shadow:var(--token-boxShadow,0 1px 2px 0 #00000008, 0 1px 6px -1px #00000005, 0 2px 4px 0 #00000005);flex-shrink:0;justify-content:center;align-items:center;padding:0;display:flex}.tabs__scroll-arrow:hover{background-color:var(--token-colorFillSecondary,#f3f4f6);color:var(--token-colorText,#141414);border-color:var(--token-colorBorder,#d9d9d9)}.tabs__scroll-arrow:active{background-color:var(--token-colorFillTertiary,#f9fafb)}.tabs__scroll-arrow:focus{box-shadow:var(--token-tabFocusShadow,0 0 0 3px #8b5cf626)}.tabs__scroll-arrow:focus:not(:focus-visible){outline:none}.tabs__scroll-arrow:focus-visible{outline:var(--token-focusRingWidth,2px) var(--token-focusRingStyle,solid) var(--token-focusRingColor,var(--token-colorPrimary));outline-offset:var(--token-focusRingOffset,2px)}.tabs__scroll-arrow--left{margin-right:-4px}.tabs__scroll-arrow--right{margin-left:-4px}.tabs__panel,.tabs__panel:focus{outline:none}.tabs--mobile-dropdown{flex-direction:column;width:100%;display:flex}.tabs__dropdown-container{margin:0 0 var(--token-paddingMD,1rem);position:relative}.tabs__dropdown-trigger{width:100%;padding:var(--token-paddingSM,.5rem) var(--token-paddingMD,1rem);background-color:var(--token-colorBgContainer,#fff);border:1px solid var(--token-colorBorderSecondary,#e5e7eb);border-radius:var(--token-borderRadiusLG,.5rem);color:var(--token-colorText,#141414);font-size:var(--token-fontSize,.875rem);cursor:pointer;transition:background-color var(--token-motionDurationFast,.1s), border-color var(--token-motionDurationFast,.1s);box-shadow:var(--token-boxShadow,0 1px 2px 0 #00000008, 0 1px 6px -1px #00000005, 0 2px 4px 0 #00000005);justify-content:space-between;align-items:center;font-weight:500;display:flex}.tabs__dropdown-trigger:hover{background-color:var(--token-colorFillSecondary,#f3f4f6);border-color:var(--token-colorBorder,#d9d9d9)}.tabs__dropdown-trigger:focus{border-color:color-mix(in srgb, var(--token-colorPrimary) 70%, var(--token-colorText));box-shadow:var(--token-tabFocusShadow,0 0 0 3px #8b5cf626)}.tabs__dropdown-trigger:focus:not(:focus-visible){outline:none}.tabs__dropdown-trigger:focus-visible{outline:var(--token-focusRingWidth,2px) var(--token-focusRingStyle,solid) var(--token-focusRingColor,var(--token-colorPrimary));outline-offset:var(--token-focusRingOffset,2px)}.tabs__dropdown-label{text-align:left;flex:1}.tabs__dropdown-arrow{transition:transform var(--token-motionDurationMid,.2s);flex-shrink:0}.tabs__dropdown-arrow--open{transform:rotate(180deg)}.tabs__dropdown-menu{z-index:100;background-color:var(--token-colorBgContainer,#fff);border:1px solid var(--token-colorBorderSecondary,#e5e7eb);border-radius:var(--token-borderRadiusLG,.5rem);box-shadow:var(--token-boxShadowSecondary,0 6px 16px 0 #00000014, 0 3px 6px -4px #0000001f, 0 9px 28px 8px #0000000d);animation:tabs-dropdown-fade-in var(--token-motionDurationMid,.2s);position:absolute;top:calc(100% + 4px);left:0;right:0;overflow:hidden}@keyframes tabs-dropdown-fade-in{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}.tabs__dropdown-item{width:100%;padding:var(--token-paddingSM,.5rem) var(--token-paddingMD,1rem);color:var(--token-colorText,#141414);font-size:var(--token-fontSize,.875rem);text-align:left;cursor:pointer;transition:background-color var(--token-motionDurationFast,.1s);background:0 0;border:none;font-weight:400;display:block}.tabs__dropdown-item:hover{background-color:var(--token-colorFillSecondary,#f3f4f6)}.tabs__dropdown-item:focus-visible{outline:var(--token-focusRingWidth,2px) var(--token-focusRingStyle,solid) var(--token-focusRingColor,var(--token-colorPrimary));outline-offset:-2px}.tabs__dropdown-item--active{color:var(--token-colorPrimary,#8b5cf6);background-color:var(--token-tabActiveBg,#8b5cf61a);font-weight:500}.tabs__dropdown-item--active:hover{background-color:var(--token-tabActiveBg,#8b5cf61a)}.tabs__overflow{flex-shrink:0;display:none;position:relative}.tabs__overflow-btn{background-color:var(--token-colorBgContainer,#fff);border:1px solid var(--token-colorBorderSecondary,#e5e7eb);border-radius:var(--token-borderRadiusLG,.5rem);width:36px;height:36px;color:var(--token-colorTextSecondary,#595959);cursor:pointer;transition:background-color var(--token-motionDurationFast,.1s), color var(--token-motionDurationFast,.1s);box-shadow:var(--token-boxShadow,0 1px 2px 0 #00000008, 0 1px 6px -1px #00000005, 0 2px 4px 0 #00000005);justify-content:center;align-items:center;padding:0;display:flex}.tabs__overflow-btn:hover{background-color:var(--token-colorFillSecondary,#f3f4f6);color:var(--token-colorText,#141414)}.tabs__overflow-btn:focus{box-shadow:var(--token-tabFocusShadow,0 0 0 3px #8b5cf626)}.tabs__overflow-btn:focus:not(:focus-visible){outline:none}.tabs__overflow-btn:focus-visible{outline:var(--token-focusRingWidth,2px) var(--token-focusRingStyle,solid) var(--token-focusRingColor,var(--token-colorPrimary));outline-offset:var(--token-focusRingOffset,2px)}.tabs__overflow-menu{background-color:var(--token-colorBgElevated,#fff);border:1px solid var(--token-colorBorderSecondary,#e5e7eb);border-radius:var(--token-borderRadiusLG,.5rem);min-width:200px;max-width:calc(100vw - 2rem);max-height:400px;box-shadow:var(--token-boxShadowSecondary,0 6px 16px 0 #00000014, 0 3px 6px -4px #0000001f, 0 9px 28px 8px #0000000d);z-index:var(--token-zIndexPopover,1150);padding:var(--token-paddingXS,.25rem);position:absolute;top:calc(100% + 8px);right:0;overflow-y:auto}.tabs__overflow-group{flex-direction:column;display:flex}.tabs__overflow-group+.tabs__overflow-group{margin-top:var(--token-paddingSM,.5rem);padding-top:var(--token-paddingSM,.5rem);border-top:1px solid var(--token-colorBorderSecondary,#e5e7eb)}.tabs__overflow-group-label{font-size:var(--token-fontSizeSM,.75rem);color:var(--token-colorTextTertiary,#737373);text-transform:uppercase;letter-spacing:.05em;padding:var(--token-paddingXS,.25rem) var(--token-paddingSM,.5rem);margin-bottom:var(--token-paddingXXS,.125rem);font-weight:600}.tabs__overflow-item{justify-content:space-between;align-items:center;gap:var(--token-paddingSM,.5rem);width:100%;padding:var(--token-paddingSM,.5rem) var(--token-paddingMD,1rem);font-size:var(--token-fontSize,.875rem);color:var(--token-colorText,#141414);border-radius:var(--token-borderRadiusSM,.25rem);text-align:left;cursor:pointer;transition:background-color var(--token-motionDurationFast,.1s);background:0 0;border:none;display:flex}.tabs__overflow-item:hover{background-color:var(--token-colorFillSecondary,#f3f4f6)}.tabs__overflow-item:focus-visible{outline:var(--token-focusRingWidth,2px) var(--token-focusRingStyle,solid) var(--token-focusRingColor,var(--token-colorPrimary));outline-offset:-2px}.tabs__overflow-item--active{color:var(--token-colorPrimary,#8b5cf6);background-color:var(--token-tabActiveBg,#8b5cf61a);font-weight:600}.tabs__overflow-item--active:hover{background-color:var(--token-tabActiveBg,#8b5cf61a)}@media (width>=480px) and (width<=767px){.tabs:not(.tabs--overflow-menu) .tabs__list{padding:var(--token-paddingSM,.5rem)}.tabs:not(.tabs--overflow-menu) .tabs__tab{padding:var(--token-paddingXS,.25rem) var(--token-paddingSM,.5rem);font-size:var(--token-fontSize,.875rem)}.tabs:not(.tabs--overflow-menu) .tabs__scroll-arrow{width:28px;height:28px}}@media (width<=479px){.tabs:not(.tabs--overflow-menu) .tabs__scroll-arrow{display:none}}@media (width<=767px){.tabs--overflow-menu .tabs__overflow{display:block}.tabs--overflow-menu .tabs__list{padding:var(--token-paddingSM,.5rem);gap:0}.tabs--overflow-menu .tabs__group-label,.tabs--overflow-menu .tabs__separator{display:none}.tabs--overflow-menu .tabs__group,.tabs--overflow-menu .tabs__group-tabs{gap:0}.tabs--overflow-menu .tabs__tab{min-width:auto;padding:var(--token-paddingSM,.5rem) var(--token-padding,.75rem);font-size:var(--token-fontSize,.875rem);flex:1}.tabs--overflow-menu .tabs__scroll-arrow{display:none!important}}.tabs--variant-segmented .tabs__container{gap:0}.tabs--variant-segmented .tabs__list{background-color:var(--token-colorFillTertiary,#f9fafb);border-radius:var(--token-borderRadiusLG,.5rem);padding:var(--token-paddingXS,.25rem);gap:var(--token-paddingXS,.25rem);z-index:auto;box-shadow:none;border:1px solid #0000;position:static;top:auto;overflow-x:visible}.tabs--variant-segmented .tabs__tab{border-radius:var(--token-borderRadius,.375rem);color:var(--token-colorTextSecondary,#595959);background:0 0;border:1px solid #0000;font-weight:500}.tabs--variant-segmented .tabs__tab:hover:not(.tabs__tab--active){background-color:var(--token-colorFillSecondary,#f3f4f6);color:var(--token-colorText,#141414)}.tabs--variant-segmented .tabs__tab--active{color:var(--token-colorText,#141414);background-color:var(--token-colorBgContainer,#fff);box-shadow:var(--token-boxShadowTertiary,0 1px 3px #0000001a)}.tabs--variant-segmented .tabs__tab--active:hover{background-color:var(--token-colorBgContainer,#fff)}.tabs--variant-segmented.tabs--fill-container .tabs__tab{text-align:center;flex:1;justify-content:center}.tabs--variant-segmented .tabs__scroll-arrow{display:none}.tabs--variant-compact .tabs__container{gap:0;margin:0}.tabs--variant-compact .tabs__list{background-color:var(--token-colorFillQuaternary,#fafafa);border-radius:var(--token-borderRadiusSM,.25rem);z-index:auto;box-shadow:none;border:1px solid #0000;flex:none;gap:2px;min-width:0;padding:2px;display:inline-flex;position:static;top:auto;overflow-x:visible}.tabs--variant-compact .tabs__tab{padding:var(--token-paddingXS,.25rem) var(--token-paddingSM,.5rem);font-size:var(--token-fontSize,.875rem);border-radius:calc(var(--token-borderRadiusSM,.25rem) - 1px);color:var(--token-colorTextSecondary,#595959);background:0 0;border:1px solid #0000;min-width:72px;font-weight:500}.tabs--variant-compact .tabs__tab:hover:not(.tabs__tab--active){background-color:var(--token-colorFillSecondary,#f3f4f6);color:var(--token-colorText,#141414)}.tabs--variant-compact .tabs__tab--active{color:var(--token-colorText,#141414);background-color:var(--token-colorBgContainer,#fff);box-shadow:var(--token-boxShadowTertiary,0 1px 3px #0000001a)}.tabs--variant-compact .tabs__tab--active:hover{background-color:var(--token-colorBgContainer,#fff)}.tabs--variant-compact.tabs--fill-container .tabs__tab{text-align:center;flex:1;justify-content:center}.tabs--variant-compact .tabs__scroll-arrow{display:none}.tabs--variant-segmented .tabs__group,.tabs--variant-compact .tabs__group{gap:0}.tabs--variant-segmented .tabs__group-tabs,.tabs--variant-compact .tabs__group-tabs{gap:var(--token-paddingXS,.25rem)}@media (width<=479px){.tabs--variant-segmented .tabs__list{overflow-x:auto}}@media (prefers-reduced-motion:reduce){.tabs__list{scroll-behavior:auto}.tabs__scroll-arrow,.tabs__tab,.tabs__dropdown-trigger,.tabs__dropdown-item,.tabs__dropdown-arrow,.tabs__overflow-btn,.tabs__overflow-item{transition:none}.tabs__dropdown-menu{animation:none}.tabs__scroll-arrow:active{transform:none}.tabs--variant-segmented .tabs__tab,.tabs--variant-compact .tabs__tab{transition:none}}.data-table{border:1px solid var(--token-colorBorderSecondary,var(--token-colorBorder,#d9d9d9));border-radius:var(--token-borderRadiusLG,8px);background-color:var(--token-colorBgContainer,#fff);width:100%;position:relative;overflow-x:auto}.data-table__table{border-collapse:collapse;table-layout:auto;width:100%}.data-table__head{z-index:1;background-color:var(--token-colorFillQuaternary,var(--token-colorBgLayout,#f5f5f5));position:sticky;top:0}.data-table__row{border-bottom:1px solid var(--token-colorBorderSecondary,transparent)}.data-table__row:last-of-type{border-bottom:none}.data-table__row--clickable{cursor:pointer;transition:background-color var(--token-motionDurationFast,.12s) ease}.data-table__row--clickable:hover{background-color:var(--token-colorFillQuaternary,#0000000a)}.data-table__row--clickable:focus-visible{outline:var(--token-focusRingWidth,2px) var(--token-focusRingStyle,solid) var(--token-focusRingColor,var(--token-colorPrimary));outline-offset:-2px}.data-table__cell{padding:var(--token-paddingSM,.5rem) var(--token-paddingMD,1rem);font-size:var(--token-fontSize,.875rem);color:var(--token-colorText,#141414);vertical-align:middle;word-break:break-word}.data-table__cell--align-right{text-align:right}.data-table__cell--align-center{text-align:center}.data-table__cell--head{font-weight:600;font-size:var(--token-fontSizeSM,.75rem);text-transform:uppercase;letter-spacing:.05em;color:var(--token-colorTextSecondary,#595959);background-color:var(--token-colorFillQuaternary,var(--token-colorBgLayout,#f5f5f5));border-bottom:1px solid var(--token-colorBorderSecondary,var(--token-colorBorder,#d9d9d9));-webkit-user-select:none;user-select:none;white-space:nowrap;word-break:normal;overflow-wrap:normal;position:relative}.data-table__head-label{vertical-align:middle;display:inline-block}.data-table__cell--sortable{cursor:pointer;-webkit-user-select:none;user-select:none}.data-table__cell--sortable:hover{background-color:var(--token-colorFillTertiary,#0000000f)}.data-table__cell--sortable:focus-visible{outline:var(--token-focusRingWidth,2px) var(--token-focusRingStyle,solid) var(--token-focusRingColor,var(--token-colorPrimary));outline-offset:-2px}.data-table__cell--sort-active{color:var(--token-colorPrimary,#8b5cf6)}.data-table__sort-icon{vertical-align:middle;color:var(--token-colorTextSecondary,#595959);flex-shrink:0;align-items:center;margin-inline-start:var(--token-marginXXS,4px);line-height:0;display:inline-flex}.data-table__cell--sort-active .data-table__sort-icon{color:var(--token-colorPrimary,#8b5cf6)}.data-table__resize-handle{cursor:col-resize;width:6px;transition:background-color var(--token-motionDurationFast,.12s) ease;background-color:#0000;position:absolute;top:0;bottom:0;right:0}.data-table__resize-handle:hover{background-color:var(--token-colorPrimaryBorder,var(--token-colorPrimary,#8b5cf6));opacity:.5}.data-table__state-cell{padding:var(--token-paddingLG,16px);text-align:center;color:var(--token-colorTextSecondary,#595959)}.data-table__loading{background:linear-gradient(90deg, var(--token-colorFillQuaternary,#fafafa) 25%, var(--token-colorFillTertiary,#f9fafb) 50%, var(--token-colorFillQuaternary,#fafafa) 75%);border-radius:var(--token-borderRadiusSM,.25rem);background-size:200% 100%;width:100%;height:24px;animation:1.4s ease-in-out infinite data-table-shimmer}@keyframes data-table-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}@media (prefers-reduced-motion:reduce){.data-table__loading{animation:none}}.error-state{padding:var(--token-paddingXL,2rem);text-align:center;flex-direction:column;justify-content:center;align-items:center;min-height:200px;display:flex}.error-state__icon{width:64px;height:64px;margin-bottom:var(--token-paddingLG,1.5rem);color:var(--token-colorError,#c82333);transition:transform var(--token-motionDurationMid,.2s);background-color:#ff4d4f1a;border-radius:50%;justify-content:center;align-items:center;display:flex}.error-state__icon svg{width:48px;height:48px}.error-state__title{margin:0 0 var(--token-paddingSM,.5rem);font-size:var(--token-fontSizeXL,1.25rem);color:var(--token-colorText,#141414);font-weight:600;line-height:1.4}.error-state__message{margin:0 0 var(--token-paddingLG,1.5rem);font-size:var(--token-fontSize,.875rem);color:var(--token-colorTextSecondary,#595959);max-width:480px;line-height:1.5}.error-state__actions{gap:var(--token-padding,.75rem);flex-wrap:wrap;justify-content:center;display:flex}.error-state__action-btn{min-width:120px}.error-state--danger .error-state__icon{color:var(--token-colorError,#c82333);background-color:#ff4d4f1a}.error-state--warning .error-state__icon{color:var(--token-colorWarning,#9a5d00);background-color:#faad141a}.error-state--accent .error-state__icon{color:var(--token-colorPrimary,#8b5cf6);background-color:var(--token-colorPrimaryBg,#8b5cf61a)}@media (prefers-reduced-motion:reduce){.error-state__icon{transition:none}}@media (width<=767px){.error-state{padding:var(--token-paddingLG,1.5rem)}.error-state__icon{width:56px;height:56px;margin-bottom:var(--token-paddingMD,1rem)}.error-state__icon svg{width:40px;height:40px}.error-state__title{font-size:var(--token-fontSizeLG,1rem)}.error-state__message{font-size:var(--token-fontSize,.875rem)}.error-state__actions{flex-direction:column;width:100%}.error-state__action-btn{width:100%;min-width:unset}}.skeleton{background-color:var(--token-colorFillTertiary,#f9fafb);border-radius:var(--token-borderRadiusSM,.25rem);display:inline-block;position:relative;overflow:hidden}.skeleton--rect{border-radius:var(--token-borderRadiusSM,.25rem)}.skeleton--circle{border-radius:50%}.skeleton--text{border-radius:var(--token-borderRadiusSM,.25rem);height:1em;transform:scaleY(.6)}.skeleton__shimmer{background:linear-gradient(90deg, transparent 0%, var(--token-colorBgContainer,#fff) 50%, transparent 100%);animation:skeleton-shimmer var(--token-motionDurationSlow,1.5s) infinite;position:absolute;inset:0;transform:translate(-100%)}@keyframes skeleton-shimmer{0%{transform:translate(-100%)}to{transform:translate(100%)}}@media (prefers-reduced-motion:reduce){.skeleton__shimmer{animation:none}}.select{display:inline-block;position:relative}.select--full-width{width:100%;display:block}.select--labelled{gap:var(--token-paddingXS);flex-direction:column;display:flex}.select__label{font-size:var(--token-fontSizeSM);color:var(--token-colorTextSecondary);font-weight:500}.select__trigger{justify-content:space-between;align-items:center;gap:var(--token-paddingSM);width:100%;min-height:var(--token-controlHeight);padding:var(--token-paddingXS) var(--token-padding);font-size:var(--token-fontSize);font-family:var(--token-fontFamily);color:var(--token-colorText);background-color:var(--token-colorBgContainer);border:1px solid var(--token-colorBorder);border-radius:var(--token-borderRadius);cursor:pointer;transition:all var(--token-motionDurationFast);text-align:left;display:flex}.select__trigger:hover:not(:disabled){border-color:var(--token-colorPrimary)}.select__trigger:focus{border-color:color-mix(in srgb, var(--token-colorPrimary) 70%, var(--token-colorText));box-shadow:0 0 0 2px var(--token-colorPrimaryBg);outline:none}.select--open .select__trigger{border-color:var(--token-colorPrimary);box-shadow:0 0 0 2px var(--token-colorPrimaryBg);border-bottom-right-radius:0;border-bottom-left-radius:0}.select--disabled .select__trigger{cursor:not-allowed;opacity:.6;background-color:var(--token-colorFillTertiary)}.select--small .select__trigger{min-height:var(--token-controlHeightSM);padding:var(--token-paddingXS) var(--token-paddingSM);font-size:var(--token-fontSizeSM)}.select--medium .select__trigger{min-height:var(--token-controlHeight);padding:var(--token-paddingXS) var(--token-padding);font-size:var(--token-fontSize)}.select--large .select__trigger{min-height:var(--token-controlHeightLG);padding:var(--token-paddingSM) var(--token-padding);font-size:var(--token-fontSize)}.select__trigger{min-width:120px}.select__value{align-items:center;gap:var(--token-paddingSM);flex:1;min-width:0;display:flex;overflow:hidden}.select__value-icon{color:var(--token-colorTextSecondary);flex-shrink:0;justify-content:center;align-items:center;display:flex}.select__value-label{text-overflow:ellipsis;white-space:nowrap;font-weight:500;overflow:hidden}.select__placeholder{color:var(--token-colorTextTertiary)}.select__chevron{color:var(--token-colorTextSecondary);transition:transform var(--token-motionDurationFast);flex-shrink:0;justify-content:center;align-items:center;display:flex}.select__chevron--open{transform:rotate(180deg)}.select__dropdown{z-index:var(--token-zIndexPopover);background:var(--token-colorBgElevated);border:1px solid var(--token-colorPrimary);border-radius:0 0 var(--token-borderRadius) var(--token-borderRadius);box-shadow:var(--token-boxShadowSecondary);border-top:none;flex-direction:column;max-height:240px;animation:.15s ease-out selectDropdownOpen;display:flex;position:absolute;top:100%;left:0;right:0;overflow:hidden}.select__dropdown--portal{border:1px solid var(--token-colorBorder);border-radius:var(--token-borderRadius);z-index:var(--token-zIndexTooltip);position:fixed}.select__search{padding:var(--token-paddingSM);background:var(--token-colorBgElevated);border-bottom:1px solid var(--token-colorBorderSecondary);flex-shrink:0}.select__search-input{box-sizing:border-box;width:100%;padding:var(--token-paddingXS) var(--token-paddingSM);font-family:var(--token-fontFamily);font-size:var(--token-fontSize);color:var(--token-colorText);background:var(--token-colorBgContainer);border:1px solid var(--token-colorBorder);border-radius:var(--token-borderRadiusSM);transition:border-color var(--token-motionDurationFast), box-shadow var(--token-motionDurationFast)}.select__search-input::placeholder{color:var(--token-colorTextPlaceholder)}.select__search-input:focus-visible{border-color:color-mix(in srgb, var(--token-colorPrimary) 70%, var(--token-colorText));box-shadow:0 0 0 2px var(--token-colorPrimaryBg);outline:none}.select__options{min-height:0;overflow-y:auto}@keyframes selectDropdownOpen{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.select__options::-webkit-scrollbar{width:var(--token-scrollbarSize);height:var(--token-scrollbarSize)}.select__options::-webkit-scrollbar-track{background:0 0}.select__options::-webkit-scrollbar-thumb{background-color:var(--token-colorBorder);border-radius:var(--token-scrollbarRadius)}.select__options::-webkit-scrollbar-thumb:hover{background-color:var(--token-colorTextTertiary)}.select__option{align-items:center;gap:var(--token-paddingSM);padding:var(--token-paddingSM) var(--token-padding);font-size:var(--token-fontSize);color:var(--token-colorText);cursor:pointer;transition:background-color var(--token-motionDurationFast);-webkit-user-select:none;user-select:none;display:flex}.select__option--disabled{color:var(--token-colorTextDisabled);cursor:not-allowed}.select__option:first-child{border-radius:0}.select__option:last-child{border-radius:0 0 var(--token-borderRadius) var(--token-borderRadius)}.select__option:hover:not(.select__option--disabled),.select__option--focused:not(.select__option--disabled){background-color:var(--token-colorFillSecondary)}.select__option--selected{background-color:var(--token-colorPrimaryBg)}.select__option--selected:hover,.select__option--selected.select__option--focused{background-color:var(--token-colorPrimaryBgHover)}.select__option-icon{width:20px;height:20px;color:var(--token-colorTextSecondary);flex-shrink:0;justify-content:center;align-items:center;display:flex}.select__option--selected .select__option-icon{color:var(--token-colorPrimary)}.select__option-content{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.select__option-label{font-weight:500}.select__option--selected .select__option-label{color:var(--token-colorPrimary)}.select__option-description{font-size:var(--token-fontSizeSM);color:var(--token-colorTextTertiary)}.select__option-check{color:var(--token-colorPrimary);flex-shrink:0;justify-content:center;align-items:center;display:flex}.select__empty{padding:var(--token-padding) var(--token-paddingMD);color:var(--token-colorTextTertiary);text-align:center;font-style:italic}.select--large .select__option{padding:var(--token-paddingSM) var(--token-paddingMD);font-size:var(--token-fontSize)}.select--large .select__option-icon{width:24px;height:24px}.select--large .select__option-description{font-size:var(--token-fontSizeSM)}.drawer__backdrop.drawer__backdrop{background-color:var(--token-colorBgMask,#00000073);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);z-index:var(--token-zIndexDrawer,1100);pointer-events:none;visibility:hidden;opacity:0;transition:opacity var(--token-motionDurationMid,.3s) ease, visibility 0s linear var(--token-motionDurationMid,.3s), background-color var(--token-themeTransitionDuration,.25s) var(--token-themeTransitionTiming,ease-in-out), backdrop-filter var(--token-themeTransitionDuration,.25s) var(--token-themeTransitionTiming,ease-in-out);position:fixed;inset:0}.drawer__backdrop--open.drawer__backdrop--open{pointer-events:auto;visibility:visible;opacity:1;transition:opacity var(--token-motionDurationMid,.3s) ease, visibility 0s linear 0s, background-color var(--token-themeTransitionDuration,.25s) var(--token-themeTransitionTiming,ease-in-out), backdrop-filter var(--token-themeTransitionDuration,.25s) var(--token-themeTransitionTiming,ease-in-out)}.drawer.drawer{background-color:var(--token-colorBgContainer,#fff);box-shadow:var(--token-boxShadowDrawerRight,-4px 0 20px #00000026);opacity:0;transition:transform var(--token-motionDurationMid,.3s) cubic-bezier(.4, 0, .2, 1), opacity var(--token-motionDurationMid,.3s) ease, background-color var(--token-themeTransitionDuration,.25s) var(--token-themeTransitionTiming,ease-in-out), color var(--token-themeTransitionDuration,.25s) var(--token-themeTransitionTiming,ease-in-out), border-color var(--token-themeTransitionDuration,.25s) var(--token-themeTransitionTiming,ease-in-out), box-shadow var(--token-themeTransitionDuration,.25s) var(--token-themeTransitionTiming,ease-in-out);z-index:var(--token-zIndexDrawerContent,1101);flex-direction:column;display:flex;position:fixed;top:0;bottom:0;right:0;transform:translate(100%)}.drawer.drawer--open{opacity:1;transform:translate(0)}.drawer__header{padding:var(--token-paddingLG,1.5rem);border-bottom:1px solid var(--token-colorBorder,#d9d9d9);flex-shrink:0}.drawer__title-row{justify-content:space-between;align-items:center;gap:var(--token-paddingMD,1rem);display:flex}.drawer__title{font-size:var(--token-fontSizeHeading4,1.25rem);color:var(--token-colorText,#141414);margin:0;font-weight:600}.drawer__subtitle{font-size:var(--token-fontSizeSM,.875rem);color:var(--token-colorTextSecondary,#6b7280);margin:var(--token-paddingSM,.5rem) 0 0 0;text-overflow:ellipsis;overflow:hidden}.drawer__close-btn.drawer__close-btn{border-radius:var(--token-borderRadius,6px);width:2rem;height:2rem;color:var(--token-colorTextSecondary,#6b7280);cursor:pointer;transition:background-color var(--token-motionDurationFast,.15s) ease, color var(--token-motionDurationFast,.15s) ease, border-color var(--token-themeTransitionDuration,.25s) var(--token-themeTransitionTiming,ease-in-out);background:0 0;border:none;flex-shrink:0;justify-content:center;align-items:center;display:flex}.drawer__close-btn:hover{background-color:var(--token-colorFillSecondary,#f3f4f6);color:var(--token-colorText,#141414)}.drawer__close-btn:focus-visible{outline:var(--token-focusRingWidth,2px) var(--token-focusRingStyle,solid) var(--token-focusRingColor,var(--token-colorPrimary));outline-offset:var(--token-focusRingOffset,2px)}.drawer__content{flex:1;overflow:hidden auto}.drawer__footer{padding:var(--token-paddingMD,1rem) var(--token-paddingLG,1.5rem);border-top:1px solid var(--token-colorBorder,#d9d9d9);background-color:var(--token-colorFillSecondary,#f3f4f6);flex-shrink:0}@media (prefers-reduced-motion:reduce){.drawer__backdrop.drawer__backdrop,.drawer.drawer,.drawer__close-btn.drawer__close-btn,.drawer__backdrop--open.drawer__backdrop--open{transition:none}}@media (prefers-reduced-transparency:reduce){.drawer__backdrop.drawer__backdrop{-webkit-backdrop-filter:none;background-color:#000000a6}}@media (width<=767px){.drawer{width:100vw!important;max-width:100vw!important}.drawer__header,.drawer__footer{padding:var(--token-paddingMD,1rem)}}@keyframes drawer-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-4px)}20%,40%,60%,80%{transform:translate(4px)}}.drawer--shaking{animation:.4s ease-in-out drawer-shake}@media (prefers-reduced-motion:reduce){.drawer--shaking{animation:none}}.tooltip__wrapper{display:inline-flex}.tooltip__wrapper:focus-visible{outline:var(--token-focusRingWidth,2px) var(--token-focusRingStyle,solid) var(--token-focusRingColor,var(--token-colorPrimary));outline-offset:var(--token-focusRingOffset,2px);border-radius:var(--token-borderRadiusSM,.25rem)}.tooltip__wrapper:focus:not(:focus-visible){outline:none}.tooltip__content{z-index:var(--token-zIndexTooltip,1300);color:#f3f4f6;max-width:280px;font-size:var(--token-fontSize,.875rem);background-color:#1f2937;border-radius:6px;padding:.5rem .75rem;line-height:1.4;position:fixed;box-shadow:0 4px 12px #00000026}.tooltip__content p,.tooltip__content span{color:#f3f4f6}.tooltip__text{color:#f3f4f6;margin:0}.tooltip__content.param-tooltip__content{width:280px}.base-card{padding:var(--token-paddingMD,1rem);background-color:var(--token-colorFillTertiary,#f9fafb);border-radius:var(--token-borderRadiusLG,.5rem);transition:border-color var(--token-motionDurationFast,.1s), box-shadow var(--token-motionDurationMid,.2s), transform var(--token-motionDurationMid,.2s), background-color var(--token-motionDurationFast,.1s);border:1px solid #0000;flex-direction:column;display:flex;position:relative}.base-card--row{flex-direction:row}.base-card--hoverable:hover{border-color:var(--token-colorBorderSecondary,#e5e7eb);box-shadow:var(--token-boxShadowSecondary,0 6px 16px 0 #00000014, 0 3px 6px -4px #0000001f, 0 9px 28px 8px #0000000d);transform:translateY(-2px)}.base-card--clickable{cursor:pointer}.base-card--clickable:hover{border-color:var(--token-colorPrimary,#8b5cf6);transform:translateY(-2px);box-shadow:0 4px 12px #0000001a}.base-card:focus-within{border-color:color-mix(in srgb, var(--token-colorPrimary) 70%, var(--token-colorText));outline:none}.base-card--clickable:focus{outline:var(--token-focusRingWidth,2px) var(--token-focusRingStyle,solid) var(--token-focusRingColor,var(--token-colorPrimary));outline-offset:var(--token-focusRingOffset,2px)}.base-card--default{background-color:var(--token-colorFillTertiary,#f9fafb)}.base-card--installed{background-color:var(--token-colorBgContainer,#fff);border-color:var(--token-colorBorderSecondary,#e5e7eb)}.base-card--available{background-color:var(--token-colorFillQuaternary,#fafafa);border-color:var(--token-colorBorderSecondary,#e5e7eb)}.base-card--active{border-color:var(--token-colorSuccessBorder,#00bd9b66);background-color:var(--token-colorSuccessBg,#00bd9b0d)}.base-card--active:hover{border-color:var(--token-colorSuccessBorderHover,#00bd9b99);box-shadow:var(--token-colorSuccessBoxShadow,0 4px 12px #00bd9b26)}.base-card--loading{border-color:color-mix(in srgb, var(--token-colorPrimary,#8b5cf6) 40%, transparent);background-color:color-mix(in srgb, var(--token-colorPrimary,#8b5cf6) 3%, transparent);animation:2s ease-in-out infinite base-card-pulse}@keyframes base-card-pulse{0%,to{border-color:color-mix(in srgb, var(--token-colorPrimary,#8b5cf6) 30%, transparent);box-shadow:0 0 #0000}50%{border-color:color-mix(in srgb, var(--token-colorPrimary,#8b5cf6) 50%, transparent);box-shadow:0 0 0 4px var(--token-colorPrimaryBg,#8b5cf61a)}}.base-card--disabled{opacity:.5;pointer-events:none;filter:grayscale(50%)}.base-card--disabled:hover{box-shadow:none;border-color:#0000;transform:none}.base-card--warning{background-color:#faad1408;border-color:#faad1466}@media (prefers-reduced-motion:reduce){.base-card{transition:none}.base-card--hoverable:hover,.base-card--clickable:hover{transform:none}.base-card--loading{animation:none}}@media (width<=767px){.base-card{padding:var(--token-paddingSM,.5rem)}}.page-header{margin-bottom:var(--token-paddingLG,1.5rem)}.page-header__content{justify-content:space-between;align-items:flex-start;gap:var(--token-paddingMD,1rem);flex-wrap:wrap;display:flex}.page-header__text{flex:20rem;min-width:min(100%,12rem)}.page-header__title{margin:0 0 var(--token-paddingSM,.5rem);font-size:var(--token-fontSizeDisplay4,1.75rem);letter-spacing:.02em;color:var(--token-colorText,#141414);font-weight:300}.page-header__description{font-size:var(--token-fontSize,.875rem);color:var(--token-colorTextSecondary,#595959);margin:0}.page-header__actions{justify-content:flex-end;align-items:flex-start;gap:var(--token-paddingSM,.5rem);flex-wrap:wrap;flex:0 auto;min-width:0;margin-left:auto;display:flex}.page-header__actions>*{flex-shrink:0}.page-header__error{justify-content:space-between;align-items:center;gap:var(--token-paddingSM,.5rem);margin-top:var(--token-paddingSM,.5rem);padding:var(--token-paddingSM,.5rem) var(--token-paddingMD,1rem);font-size:var(--token-fontSize,.875rem);color:var(--token-colorError,#c82333);border-radius:var(--token-borderRadiusLG,.5rem);background-color:#ff4d4f14;border:1px solid #ff4d4f4d;display:flex}.page-header__error-text{word-break:break-word;flex:1}.page-header__error-dismiss{font-size:var(--token-fontSizeXL,1.25rem);color:currentColor;cursor:pointer;opacity:.7;width:24px;height:24px;transition:opacity var(--token-motionDurationFast,.1s);background:0 0;border:none;flex-shrink:0;justify-content:center;align-items:center;padding:0;line-height:1;display:flex}.page-header__error-dismiss:hover{opacity:1}@media (width<=767px){.page-header__content{flex-direction:column;align-items:stretch}.page-header__text{flex:none;min-width:0}.page-header__actions{justify-content:flex-end}}.page-header__error-body{gap:var(--token-paddingXXS,.125rem);flex-direction:column;flex:1;min-width:0;display:flex}.page-header__error-detail{font-size:var(--token-fontSizeSM,.75rem);color:var(--token-colorTextTertiary,#737373);word-break:break-word}.page-header__error-actions{align-items:center;gap:var(--token-paddingSM,.5rem);padding-left:var(--token-paddingXS,.25rem);flex-shrink:0;display:flex}.page-layout{flex-direction:column;width:100%;min-height:100%;margin:0 auto;display:flex}.page-layout--standard{max-width:900px}.page-layout--wide{max-width:1400px}.page-layout--full{max-width:none}@media (width<=767px){.page-layout:not(.page-layout--full){padding:0 var(--token-paddingSM,.5rem)}}.smooth-height--active{transition:height var(--token-motionDurationMid,.2s) ease-out;overflow:hidden}.smooth-height__content{display:flow-root}@media (prefers-reduced-motion:reduce){.smooth-height--active{transition:none}}.stat-card{gap:var(--token-paddingSM,.5rem);min-width:0;overflow:hidden}.stat-card__header{justify-content:space-between;align-items:center;gap:var(--token-paddingXS,.25rem);display:flex}.stat-card__label{font-size:var(--token-fontSizeSM,.75rem);color:var(--token-colorTextSecondary,#ffffff73);text-transform:uppercase;letter-spacing:.04em;white-space:nowrap;text-overflow:ellipsis;font-weight:600;overflow:hidden}.stat-card__icon{border-radius:var(--token-borderRadiusSM,.25rem);background:var(--token-colorFillSecondary,#ffffff0a);width:28px;height:28px;color:var(--token-colorTextSecondary,#fff9);flex-shrink:0;justify-content:center;align-items:center;display:inline-flex}.stat-card__body{flex-direction:column;gap:4px;display:flex}.stat-card__value-row{flex-wrap:wrap;align-items:baseline;gap:.3em;display:inline-flex}.stat-card__value-line{justify-content:space-between;align-items:center;gap:var(--token-paddingSM,.5rem);min-width:0;display:flex}.stat-card__sparkline{flex-shrink:0;align-items:center;display:inline-flex}.stat-card__value{font-size:var(--token-fontSizeXXL,1.5rem);color:var(--token-colorText,#141414);font-variant-numeric:tabular-nums;text-overflow:ellipsis;white-space:nowrap;min-width:0;font-weight:600;line-height:1.1;overflow:hidden}.stat-card__value-suffix{font-size:var(--token-fontSize,.875rem);color:var(--token-colorTextSecondary,#ffffff73);font-weight:400}.stat-card__trend{font-size:var(--token-fontSizeSM,.75rem);align-items:center;gap:4px;font-weight:500;display:inline-flex}.stat-card__trend--up{color:var(--token-colorSuccess,#52c41a)}.stat-card__trend--down{color:var(--token-colorError,#f5222d)}.stat-card__trend--flat{color:var(--token-colorTextSecondary,#ffffff73)}.stat-card__hint{font-size:var(--token-fontSizeSM,.75rem);color:var(--token-colorTextSecondary,#ffffff73);line-height:1.4}.stat-card.stat-card--prominent{padding:var(--token-paddingLG,1.5rem)}.stat-card--prominent{background:linear-gradient(135deg, var(--token-colorBgContainer,#fff) 0%, color-mix(in srgb, var(--token-colorPrimary,#8b5cf6) 4%, transparent) 100%)}.stat-card--prominent:hover{border-color:color-mix(in srgb, var(--token-colorPrimary,#8b5cf6) 30%, transparent)}.stat-card--prominent .stat-card__value{font-size:var(--token-fontSizeHeading1,2.25rem)}.stat-card--prominent .stat-card__icon{width:34px;height:34px}.stat-card.stat-card--compact{padding:var(--token-paddingSM,.5rem)}.stat-card--compact .stat-card__value{font-size:var(--token-fontSizeHeading3,1.5rem)}.stat-card--tone-success .stat-card__value{color:var(--token-colorSuccess,#52c41a)}.stat-card--tone-success .stat-card__icon{color:var(--token-colorSuccess,#52c41a);background:#52c41a1f}.stat-card--tone-warning .stat-card__value{color:var(--token-colorWarning,#faad14)}.stat-card--tone-warning .stat-card__icon{color:var(--token-colorWarning,#faad14);background:#faad1424}.stat-card--tone-danger .stat-card__value{color:var(--token-colorError,#f5222d)}.stat-card--tone-danger .stat-card__icon{color:var(--token-colorError,#f5222d);background:#f5222d1f}.stat-card--tone-info .stat-card__value{color:var(--token-colorPrimary,#8b5cf6)}.stat-card--tone-info .stat-card__icon{color:var(--token-colorPrimary,#8b5cf6);background:#6a35fc1f}.stat-card--tone-success{--corner-accent-color:var(--token-colorSuccess,#52c41a)}.stat-card--tone-warning{--corner-accent-color:var(--token-colorWarning,#faad14)}.stat-card--tone-danger{--corner-accent-color:var(--token-colorError,#f5222d)}.stat-card--tone-info{--corner-accent-color:var(--token-colorPrimary,#8b5cf6)}@media (prefers-reduced-motion:reduce){.stat-card__trend{transition:none}}.activity-operations{margin:0;padding:0;list-style:none}.activity-operation{padding:var(--space-4);border-bottom:1px solid var(--color-separator);overflow-wrap:anywhere}.activity-operation header{gap:var(--space-3);flex-wrap:wrap;justify-content:space-between;align-items:center;display:flex}.activity-updated{color:var(--color-muted);overflow-wrap:anywhere;margin:0}.activity-metrics{gap:var(--space-4);grid-template-columns:repeat(auto-fit,minmax(min(100%,280px),1fr));display:grid}.activity-metric{padding:var(--space-4);border-bottom:1px solid var(--color-separator);overflow-wrap:anywhere;margin:0}.activity-metric dt{font-weight:600}.activity-metric dd{margin:var(--space-2) 0}.activity-chart{width:100%;height:180px;color:var(--color-focus)}.activity-chart circle{fill:currentColor}.activity-metrics--summary{gap:var(--space-2);grid-template-columns:repeat(auto-fit,minmax(min(100%,140px),1fr))}.activity-metrics--summary .activity-metric{padding:var(--space-2)}.activity-measurement-details{margin-top:var(--space-4)}.activity-measurement-details>summary{cursor:pointer;padding:var(--space-2);border-radius:var(--radius-sm)}.activity-measurement-details>summary:focus-visible{outline:2px solid var(--color-focus);outline-offset:2px}.models-layout{gap:var(--space-6,24px);grid-template-columns:minmax(0,1fr) minmax(260px,320px);align-items:start;display:grid}.models-layout>*,.models-library{min-width:0}.models-library .models-toolbar{flex-wrap:wrap;align-items:end;gap:12px;display:flex}.models-toolbar>.ds-field{flex:150px}.models-library .models-wrap,.models-library pre,.models-library code,.models-library dd,.models-library h3,.models-library td{white-space:pre-wrap;overflow-wrap:anywhere}.models-library .ds-inspector{width:auto;position:static}.models-library .ds-inspector dd{margin:4px 0 16px}.models-library .ds-inspector dt{color:var(--color-muted);font-size:.85rem}.models-library .models-selected{background:var(--color-selection)}.models-library .data-table__cell{vertical-align:top}.models-library .data-table__cell:first-child{min-width:160px;max-width:320px}.models-library .models-pagination{flex-wrap:wrap;align-items:center;gap:12px;padding-block:16px;display:flex}.models-operations .ds-list li{display:block}.models-operations code{font-size:.8rem}.models-library summary{cursor:pointer;padding-block:12px}@media (width<=1100px){.models-layout{grid-template-columns:minmax(0,1fr)}}.models-library .ds-common-table{max-width:100%;overflow-x:auto}.models-library .data-table__cell .ds-button span{white-space:normal;overflow-wrap:anywhere}.models-library{grid-template-columns:minmax(0,1fr)}.models-library>*,.models-operations,.models-operations .ds-list,.models-operations li,.models-operations li>div{min-width:0;max-width:100%}.models-operations strong,.models-operations p{overflow-wrap:anywhere}.models-library .button-row{flex-wrap:wrap;gap:8px;display:flex}.models-layout:not(:has(.ds-inspector)){grid-template-columns:minmax(0,1fr)}.models-library [data-testid=models-pending-profile] a{min-height:24px;padding-block:2px;display:inline-block}.models-library .models-row-meta{gap:var(--space-1,4px);margin-top:var(--space-1,4px);flex-wrap:wrap;display:flex}.chat-screen{min-width:0}.chat-toolbar{gap:var(--space-3,12px);flex-wrap:wrap;align-items:end;display:flex}.chat-toolbar .ds-field{flex:1;min-width:min(180px,100%)}.chat-transcript{overflow-anchor:none;max-height:60vh;overflow:auto}.chat-turn{padding-block:var(--space-4,16px);border-bottom:1px solid var(--color-separator);overflow-wrap:anywhere}.chat-turn header{flex-wrap:wrap;justify-content:space-between;align-items:center;display:flex}.chat-turn h2{font-size:1rem}.chat-turn pre,.chat-prompt{white-space:pre-wrap;overflow-wrap:anywhere}.chat-turn pre{max-height:24rem;overflow:auto}.chat-composer textarea,.chat-screen textarea{resize:vertical;box-sizing:border-box;width:100%;min-height:7rem;max-height:24rem;color:inherit;background:var(--color-bg-elevated);border:1px solid var(--color-separator);border-radius:var(--radius-sm);font:inherit;padding:12px}.chat-images{flex-wrap:wrap;gap:12px;display:flex}.chat-images figure{max-width:160px;margin:0}.chat-images img{object-fit:contain;max-width:100%;max-height:120px}.chat-metrics{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:8px;display:grid}.chat-metrics dd{margin:0}.chat-screen details{padding-block:8px}.chat-screen summary{cursor:pointer;align-content:center;min-height:44px}.chat-code-block{min-width:0}.chat-code-block pre{white-space:pre;overflow-x:auto}.chat-code-toolbar{justify-content:space-between;align-items:center;gap:8px;display:flex}.chat-code-keyword{color:var(--color-focus,currentColor);font-weight:600}.chat-code-string{color:var(--color-text)}.chat-code-number{color:var(--color-muted)}.chat-screen a[href^=\#]{align-items:center;min-width:24px;min-height:44px;display:inline-flex}.chat-markdown a{min-width:24px;min-height:24px;display:inline-block}.chat-privacy .toggle{min-height:44px}.chat-privacy .toggle input{flex:0 0 24px;min-width:24px;min-height:24px}.chat-parameter-grid{grid-template-columns:repeat(auto-fit,minmax(min(100%,220px),1fr));gap:12px;display:grid}*{box-sizing:border-box}html{background:var(--color-bg);color:var(--color-text)}body{background:var(--color-bg);min-height:100vh;margin:0}a{color:inherit;text-decoration:none}button{cursor:pointer}.sr-only{clip:rect(0,0,0,0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.app-shell{background:var(--color-bg);grid-template-columns:224px minmax(0,1fr);gap:0;min-height:100vh;padding:0;display:grid}.app-sidebar{gap:var(--space-4);min-width:0;color:var(--color-text);padding:0 var(--space-4) var(--space-4);border-radius:0;flex-direction:column;display:flex}.desktop-sidebar{height:100vh;box-shadow:none;border-width:0 1px 0 0;align-self:start;position:sticky;top:0}.sheet-sidebar{border-radius:0;min-height:calc(100vh - 156px);padding:0}.brand-mark{align-items:center;gap:var(--space-2);min-height:58px;margin:0 calc(var(--space-4) * -1);padding:0 var(--space-4);color:var(--color-text);letter-spacing:-.03em;border-bottom:1px solid var(--color-separator);font-weight:760;display:flex}.brand-symbol{border-radius:var(--radius-xs);background:var(--color-selection);letter-spacing:-.05em;place-items:center;width:26px;height:26px;font-size:.78rem;display:grid}.brand-name{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.app-nav{gap:var(--space-1);display:grid}.app-nav a{align-items:center;gap:var(--space-3);border-radius:var(--radius-sm);min-height:34px;color:var(--color-muted);transition:background var(--motion-fast), color var(--motion-fast);padding:7px 9px;display:flex}.app-nav a[aria-current=page]{color:var(--color-text);background:var(--color-selection);font-weight:650}.app-nav a:hover{background:color-mix(in srgb, var(--color-selection) 72%, transparent)}.app-sidebar footer{gap:var(--space-1);min-width:0;color:var(--color-muted);margin-top:auto;font-size:.9rem;display:grid}.connection-status{align-items:center;gap:var(--space-2);min-width:0;display:flex}.connection-status>span:last-child{overflow-wrap:anywhere;min-width:0}.connection-details{min-width:0;font-size:.8rem}.connection-details summary{cursor:pointer;overflow-wrap:anywhere;max-width:100%;min-height:24px;line-height:24px}.connection-details p{margin:var(--space-1) 0 0;overflow-wrap:anywhere}.connection-dot{background:var(--color-muted);width:8px;height:8px;box-shadow:0 0 0 3px var(--color-bg-neutral);border-radius:50%}.connection-dot[data-state=ready],.connection-dot[data-state=streaming],.connection-dot[data-state=polling]{background:var(--color-success)}.connection-dot[data-state=bootstrapping],.connection-dot[data-state=stale]{background:var(--color-warning)}.connection-dot[data-state=offline],.connection-dot[data-state=unauthorized],.connection-dot[data-state=forbidden],.connection-dot[data-state=schema-mismatch],.connection-dot[data-state=error]{background:var(--color-error)}.app-main{min-width:0;min-height:100vh;color:var(--color-text);background:var(--color-bg-elevated);grid-template-rows:auto 1fr;display:grid}.app-toolbar{z-index:2;align-items:center;gap:var(--space-3);min-height:58px;padding:0 var(--space-4);box-shadow:none;border-width:0 0 1px;border-radius:0;grid-template-columns:auto minmax(0,max-content) auto minmax(0,1fr);display:grid;position:sticky;top:0}.mobile-menu-button.ds-icon-button{display:none}.toolbar-title p{margin:0;font-weight:760}.toolbar-title span{color:var(--color-muted);font-size:.9rem}.toolbar-actions,.control-row,.dialog-actions{align-items:center;gap:var(--space-2);flex-wrap:wrap;display:flex}.app-toolbar .toolbar-actions{flex-wrap:nowrap}.toolbar-loaded{align-items:center;gap:var(--space-2);min-width:0;color:var(--color-muted);grid-template-columns:max-content;grid-auto-columns:minmax(0,max-content);grid-auto-flow:column;display:grid}.toolbar-loaded-count{white-space:nowrap;flex:none;font-size:.9rem}.toolbar-loaded .button.toolbar-chip.button--inline{flex:0 auto;min-width:0;max-width:14rem;min-height:32px;padding:3px 4px 3px 8px;overflow:hidden}.toolbar-loaded .button.toolbar-chip-more.button--inline{flex:none;padding:3px 10px}.toolbar-chip>span{align-items:center;gap:var(--space-1);min-width:0;max-width:100%;display:flex}.toolbar-chip .truncate{min-width:min(5rem, 100% - var(--space-1) - 28px);flex:1 100000 auto}.toolbar-chip .ds-status-wrap{flex:0 auto;min-width:28px;display:flex}.toolbar-chip .ds-status{min-width:0;overflow:hidden}.toolbar-chip .ds-status:before{flex:none}.toolbar-chip .ds-status .status-tag__label{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.app-content-grid{gap:var(--space-5);min-width:0;padding:var(--space-6);grid-template-columns:minmax(0,1fr);display:grid}.app-content-grid.has-inspector{grid-template-columns:minmax(0,1fr) minmax(280px,340px)}.app-content{min-width:0}.screen-stack{gap:var(--space-5);grid-template-columns:minmax(0,1fr);min-width:0;display:grid}.surface-card{min-width:0;padding:var(--space-5)}h1{letter-spacing:-.025em;margin:0;font-size:clamp(1.45rem,2.6vw,1.75rem);line-height:1.12}h2{letter-spacing:-.02em}.surface-card p{color:var(--color-muted);line-height:1.55}.connection-prompt{max-width:760px}.model-grid,.gallery-grid,.settings-grid{gap:var(--space-4);grid-template-columns:repeat(2,minmax(0,1fr));min-width:0;display:grid}.dense-gallery{align-items:start}.model-card{gap:var(--space-4);display:grid}.truncate{text-overflow:ellipsis;white-space:nowrap;min-width:0;display:block;overflow:hidden}.chat-screen{min-height:100%}.transcript{gap:var(--space-3);display:grid}.transcript details{border:1px solid var(--color-separator);border-radius:var(--radius-md);padding:var(--space-3)}.composer{gap:var(--space-3);grid-template-columns:minmax(0,1fr) auto;align-items:end;display:grid}.composer textarea{resize:vertical;min-height:88px}.toggle{align-items:center;gap:var(--space-2);min-height:36px;color:var(--color-text);display:flex}.toggle input{width:24px;height:24px}.command-section{gap:var(--space-2);margin-top:var(--space-4);display:grid}.command-section h3{color:var(--color-muted);margin:0;font-size:.9rem}.command-list{gap:var(--space-2);display:grid}.shortcut-list{gap:var(--space-2);padding-left:var(--space-5);display:grid}.shortcut-keys{white-space:nowrap;margin-inline-end:var(--space-2)}kbd{border:1px solid var(--color-separator);border-radius:var(--radius-xs);background:var(--color-bg-neutral);padding:2px 6px}.table-card{overflow:auto}.sample-label{color:var(--color-muted);text-transform:uppercase;letter-spacing:.06em;font-weight:700}.surface-card,.ds-field,.ds-tabs,.ds-tabs [role=tablist]{min-width:0;max-width:100%}.surface-card h2,.surface-card p,.ds-field span,.ds-field small{overflow-wrap:anywhere;word-break:normal}.control-row,.dialog-actions{align-items:stretch}.control-row>*,.dialog-actions>*{min-width:0;max-width:100%}@media (width<=1180px){.app-content-grid.has-inspector,.dense-gallery{grid-template-columns:1fr}}@media (width<=960px){.app-shell{grid-template-columns:1fr;padding:0}.desktop-sidebar{display:none}.app-toolbar .ds-icon-button{min-width:44px;min-height:44px}.mobile-menu-button.ds-icon-button{display:inline-grid}.app-content-grid{padding:var(--space-4);grid-template-columns:1fr}.app-toolbar{grid-template-columns:auto minmax(0,1fr) auto}.toolbar-title{min-width:0}.toolbar-actions{grid-area:1/3;justify-self:end}.toolbar-loaded{scrollbar-width:thin;flex-wrap:nowrap;grid-area:2/1/auto/-1;margin:-4px;padding:4px;scroll-padding-inline:4px;display:flex;overflow-x:auto}.toolbar-loaded .button.toolbar-chip.button--inline{flex:none;max-width:min(14rem,80%)}.app-nav a{min-height:44px}}@media (width<=560px){.app-shell{gap:0;padding:0}.app-sidebar footer{font-size:.8rem}.brand-mark{min-height:52px}.brand-symbol{width:24px;height:24px}.app-toolbar{min-height:auto;padding:var(--space-3)}.app-content-grid{padding:var(--space-4)}.model-grid,.gallery-grid,.settings-grid{grid-template-columns:minmax(0,1fr)}.surface-card{padding:var(--space-4)}.ds-table{min-width:520px}.composer{grid-template-columns:1fr}}@media (width<=319px){.app-toolbar{grid-template-columns:auto minmax(0,1fr);position:static}.toolbar-title p,.toolbar-title span{text-overflow:ellipsis;white-space:nowrap;display:block;overflow:hidden}.toolbar-actions{grid-area:2/1/auto/-1;justify-self:start}.toolbar-loaded{grid-row:3}}:root{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light dark;--space-1:4px;--space-2:8px;--space-3:12px;--space-4:16px;--space-5:20px;--space-6:24px;--space-8:32px;--radius-xs:8px;--radius-sm:12px;--radius-md:16px;--radius-lg:18px;--radius-xl:24px;--radius-xxl:28px;--motion-fast:.12s;--motion-standard:.16s;--motion-slow:.18s;--focus-ring:0 0 0 3px color-mix(in srgb, var(--color-focus) 42%, transparent);--material-glass-alpha:.72;--material-glass-blur:18px;--material-glass-saturation:118%;font-family:-apple-system,BlinkMacSystemFont,SF Pro Text,Segoe UI,system-ui,sans-serif}@media (prefers-color-scheme:dark){:root{--lightningcss-light: ;--lightningcss-dark:initial}}:root[data-theme$=-light]{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light}:root[data-theme$=-dark]{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}:root[data-material=tinted]{--material-glass-bg:color-mix(in srgb, var(--color-bg-elevated) 64%, #6f87ff 12%)}:root[data-material=opaque],:root[data-reduce-transparency=true],:root[data-backdrop-filter=unsupported]{--material-glass-bg:var(--color-bg-elevated)}:root[data-high-contrast=on]{--color-separator:currentColor;--color-selection:color-mix(in srgb, var(--color-focus) 30%, transparent);--material-glass-bg:var(--color-bg-elevated)}@media (prefers-contrast:more){:root:not([data-high-contrast=off]){--color-separator:currentColor;--material-glass-bg:var(--color-bg-elevated);--color-selection:color-mix(in srgb, var(--color-focus) 30%, transparent)}}@media (prefers-reduced-transparency:reduce){:root[data-theme]{--material-glass-bg:var(--color-bg-elevated)}}@media (prefers-reduced-motion:reduce){:root{--motion-fast:1ms;--motion-standard:1ms;--motion-slow:1ms}}:root[data-reduce-motion=true]{--motion-fast:1ms;--motion-standard:1ms;--motion-slow:1ms}:root[data-test-text-scale="200"]{font-size:200%}.material-glass{background:var(--material-glass-bg);border:1px solid var(--color-separator);box-shadow:var(--shadow-chrome);-webkit-backdrop-filter:blur(var(--material-glass-blur)) saturate(var(--material-glass-saturation));backdrop-filter:blur(var(--material-glass-blur)) saturate(var(--material-glass-saturation))}@supports not ((-webkit-backdrop-filter:blur(1px)) or (backdrop-filter:blur(1px))){.material-glass{background:var(--color-bg-elevated)}}.ds-button,.ds-icon-button,input,select,textarea{font:inherit}.ds-button,.ds-icon-button{border:1px solid var(--color-separator);min-width:32px;min-height:32px;color:var(--color-text);background:var(--material-control-bg);transition:background var(--motion-fast), transform var(--motion-fast), border-color var(--motion-fast);border-radius:999px}.ds-button{justify-content:center;align-items:center;gap:var(--space-2);white-space:normal;overflow-wrap:anywhere;min-width:32px;padding:7px 14px;font-weight:650;display:inline-flex}.ds-icon-button{place-items:center;padding:0 9px;display:inline-grid}.ds-icon{flex:none;width:18px;height:18px}.ds-button:hover:where(:not(:disabled)),.ds-icon-button:hover:where(:not(:disabled)){background:var(--color-selection)}.ds-button:active,.ds-icon-button:active{transform:scale(.985)}.ds-button:focus-visible,.ds-icon-button:focus-visible,a:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,[role=tab]:focus-visible{box-shadow:var(--focus-ring);outline:none}.ds-button:disabled,.ds-icon-button:disabled,.ds-field[data-disabled=true]{opacity:.56;cursor:not-allowed}.ds-button-primary{color:#fff;background:var(--token-buttonPrimaryBg);border-color:#245bd8}.ds-button-danger{color:#fff;background:var(--token-buttonDangerBg);border-color:#c6352b}.ds-button-ghost{background:0 0}.ds-spinner{width:14px;height:14px;animation:spin var(--motion-slow) linear infinite;border:2px solid;border-right-color:#0000;border-radius:50%}.ds-field{gap:var(--space-2);color:var(--color-muted);display:grid}.ds-field>span{color:var(--color-text);font-size:.9rem;font-weight:650}.ds-field input,.ds-field select,textarea{border-radius:var(--radius-sm);border:1px solid var(--color-separator);width:100%;min-width:0;min-height:36px;color:var(--color-text);background:var(--color-bg-elevated);overflow-wrap:anywhere;padding:8px 10px}.ds-field small[data-tone=error]{color:var(--color-error)}.ds-field small[data-tone=hint]{color:var(--color-muted)}.ds-status{align-items:center;gap:var(--space-1);border:1px solid var(--color-separator);border-radius:999px;min-height:24px;padding:3px 9px;font-size:.82rem;font-weight:700;display:inline-flex}.ds-status:before{content:"";background:var(--color-muted);border-radius:50%;width:8px;height:8px}.ds-status[data-state=ready]{color:var(--color-success);background:var(--color-success-bg)}.ds-status[data-state=failed]{color:var(--color-error);background:var(--color-error-bg)}.ds-status[data-state=loading],.ds-status[data-state=draining],.ds-status[data-state=unloading]{color:var(--color-warning);background:var(--color-warning-bg)}.ds-status[data-state=loading]:before,.ds-status[data-state=draining]:before,.ds-status[data-state=unloading]:before{animation:pulse var(--motion-slow) ease-in-out infinite alternate}.ds-progress{gap:var(--space-2);display:grid}.ds-progress [role=progressbar]{background:var(--color-bg-neutral);border:1px solid var(--color-separator);border-radius:999px;height:10px;overflow:hidden}.ds-progress span{border-radius:inherit;background:linear-gradient(90deg,#2f6cff,#7b61ff);width:48%;height:100%;display:block}.ds-progress span[data-progress=indeterminate]{animation:slide var(--motion-slow) ease-in-out infinite alternate}.ds-empty,.surface-card,.ds-inspector,.ds-banner,.ds-table,.ds-list,.ds-login{background:var(--material-content-bg);border:1px solid var(--color-separator);box-shadow:var(--shadow-card);border-radius:var(--radius-lg)}.ds-empty{text-align:center;place-items:center;gap:var(--space-2);padding:var(--space-6);display:grid}.ds-empty .empty-state__illustration{border-radius:var(--radius-md);background:var(--color-selection);width:44px;height:44px;color:var(--color-focus);place-items:center;display:grid}.ds-empty h2,.ds-empty p,.ds-banner p{margin:0}.ds-banner{gap:var(--space-2);padding:var(--space-4);color:var(--color-error);background:var(--color-error-bg);display:grid}.ds-banner[data-tone=warning]{color:var(--color-warning);background:var(--color-warning-bg)}.ds-banner[data-tone=info]{color:var(--color-text);background:var(--color-selection)}.ds-dialog{width:min(560px,100vw - 32px);color:var(--color-text);background:var(--color-bg-elevated);border:1px solid var(--color-separator);border-radius:var(--radius-xl);padding:0;box-shadow:0 30px 120px #00000052}.ds-dialog::backdrop{background:#080a0e6b}.ds-dialog header{justify-content:space-between;align-items:center;gap:var(--space-4);padding:var(--space-4) var(--space-5);border-bottom:1px solid var(--color-separator);display:flex}.ds-dialog h2{margin:0;font-size:1.1rem}.ds-dialog>div{padding:var(--space-5)}.ds-tooltip-wrap{min-width:0;max-width:100%;display:inline-flex;position:relative}.ds-tooltip{z-index:10;opacity:0;pointer-events:none;border-radius:var(--radius-sm);width:max-content;max-width:240px;color:var(--color-bg-elevated);background:var(--color-text);transition:opacity var(--motion-fast);padding:6px 9px;position:absolute;inset:auto auto calc(100% + 8px) 0}.ds-tooltip-wrap:focus-within .ds-tooltip,.ds-tooltip-wrap:hover .ds-tooltip{opacity:1}.ds-tabs{gap:var(--space-4);display:grid}.ds-tabs [role=tablist]{gap:var(--space-1);padding:var(--space-1);border:1px solid var(--color-separator);border-radius:var(--radius-lg);background:var(--color-bg-neutral);flex-wrap:wrap;width:100%;max-width:100%;display:flex;overflow:visible}.ds-tabs [role=tab]{min-width:0;min-height:32px;color:var(--color-muted);font:inherit;white-space:normal;overflow-wrap:anywhere;background:0 0;border:0;border-radius:999px;flex:8rem;padding:6px 12px;font-weight:650}.ds-tabs [aria-selected=true]{color:var(--color-text);background:var(--color-bg-elevated);box-shadow:inset 0 0 0 1px var(--color-separator)}.ds-inspector{padding:var(--space-5);align-self:start;min-width:0}.ds-inspector h2{margin-top:0;font-size:1rem}.ds-table{table-layout:fixed;border-collapse:separate;border-spacing:0;width:100%;overflow:hidden}.ds-table caption{text-align:left;color:var(--color-muted);padding:10px 14px}.ds-table th,.ds-table td{text-align:left;border-bottom:1px solid var(--color-separator);padding:10px 12px;overflow:hidden}.ds-table tr:last-child td{border-bottom:0}.ds-table th:first-child,.ds-table td:first-child{width:52%}.ds-table th:nth-child(2),.ds-table td:nth-child(2){width:22%}.ds-table th:nth-child(3),.ds-table td:nth-child(3){width:26%}.ds-table .truncate{max-width:100%}.ds-list{gap:var(--space-2);padding:var(--space-4);margin:0;list-style:none;display:grid}.ds-login{gap:var(--space-3);padding:var(--space-4);display:grid}.ds-login h2,.ds-login p{overflow-wrap:anywhere;margin:0}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{to{opacity:.45}}@keyframes slide{0%{transform:translate(-60%)}to{transform:translate(120%)}}@media (prefers-reduced-motion:reduce){*,:before,:after{transition-duration:1ms!important;animation:none!important}}:root[data-reduce-motion=true] *,:root[data-reduce-motion=true] :before,:root[data-reduce-motion=true] :after,:root[data-document-hidden=true] *,:root[data-document-hidden=true] :before,:root[data-document-hidden=true] :after{transition-duration:1ms!important;animation:none!important}:root[data-high-contrast=on] .ds-button,:root[data-high-contrast=on] .ds-icon-button,:root[data-high-contrast=on] .surface-card,:root[data-high-contrast=on] .ds-empty,:root[data-high-contrast=on] .ds-inspector,:root[data-high-contrast=on] .ds-banner{border-width:2px}@media (prefers-contrast:more){:root:not([data-high-contrast=off]) .ds-button,:root:not([data-high-contrast=off]) .ds-icon-button,:root:not([data-high-contrast=off]) .surface-card,:root:not([data-high-contrast=off]) .ds-empty,:root:not([data-high-contrast=off]) .ds-inspector,:root:not([data-high-contrast=off]) .ds-banner{border-width:2px}}:root[data-glass-intensity="0"]{--material-glass-alpha:.3;--material-glass-blur:12px;--material-glass-saturation:112.0%}:root[data-glass-intensity="1"]{--material-glass-alpha:.303;--material-glass-blur:12.24px;--material-glass-saturation:112.36%}:root[data-glass-intensity="2"]{--material-glass-alpha:.307;--material-glass-blur:12.48px;--material-glass-saturation:112.72%}:root[data-glass-intensity="3"]{--material-glass-alpha:.31;--material-glass-blur:12.72px;--material-glass-saturation:113.08%}:root[data-glass-intensity="4"]{--material-glass-alpha:.314;--material-glass-blur:12.96px;--material-glass-saturation:113.44%}:root[data-glass-intensity="5"]{--material-glass-alpha:.317;--material-glass-blur:13.2px;--material-glass-saturation:113.8%}:root[data-glass-intensity="6"]{--material-glass-alpha:.32;--material-glass-blur:13.44px;--material-glass-saturation:114.16%}:root[data-glass-intensity="7"]{--material-glass-alpha:.324;--material-glass-blur:13.68px;--material-glass-saturation:114.52%}:root[data-glass-intensity="8"]{--material-glass-alpha:.327;--material-glass-blur:13.92px;--material-glass-saturation:114.88%}:root[data-glass-intensity="9"]{--material-glass-alpha:.331;--material-glass-blur:14.16px;--material-glass-saturation:115.24%}:root[data-glass-intensity="10"]{--material-glass-alpha:.334;--material-glass-blur:14.4px;--material-glass-saturation:115.6%}:root[data-glass-intensity="11"]{--material-glass-alpha:.337;--material-glass-blur:14.64px;--material-glass-saturation:115.96%}:root[data-glass-intensity="12"]{--material-glass-alpha:.341;--material-glass-blur:14.88px;--material-glass-saturation:116.32%}:root[data-glass-intensity="13"]{--material-glass-alpha:.344;--material-glass-blur:15.12px;--material-glass-saturation:116.68%}:root[data-glass-intensity="14"]{--material-glass-alpha:.348;--material-glass-blur:15.36px;--material-glass-saturation:117.04%}:root[data-glass-intensity="15"]{--material-glass-alpha:.351;--material-glass-blur:15.6px;--material-glass-saturation:117.4%}:root[data-glass-intensity="16"]{--material-glass-alpha:.354;--material-glass-blur:15.84px;--material-glass-saturation:117.76%}:root[data-glass-intensity="17"]{--material-glass-alpha:.358;--material-glass-blur:16.08px;--material-glass-saturation:118.12%}:root[data-glass-intensity="18"]{--material-glass-alpha:.361;--material-glass-blur:16.32px;--material-glass-saturation:118.48%}:root[data-glass-intensity="19"]{--material-glass-alpha:.365;--material-glass-blur:16.56px;--material-glass-saturation:118.84%}:root[data-glass-intensity="20"]{--material-glass-alpha:.368;--material-glass-blur:16.8px;--material-glass-saturation:119.2%}:root[data-glass-intensity="21"]{--material-glass-alpha:.371;--material-glass-blur:17.04px;--material-glass-saturation:119.56%}:root[data-glass-intensity="22"]{--material-glass-alpha:.375;--material-glass-blur:17.28px;--material-glass-saturation:119.92%}:root[data-glass-intensity="23"]{--material-glass-alpha:.378;--material-glass-blur:17.52px;--material-glass-saturation:120.28%}:root[data-glass-intensity="24"]{--material-glass-alpha:.382;--material-glass-blur:17.76px;--material-glass-saturation:120.64%}:root[data-glass-intensity="25"]{--material-glass-alpha:.385;--material-glass-blur:18px;--material-glass-saturation:121.0%}:root[data-glass-intensity="26"]{--material-glass-alpha:.388;--material-glass-blur:18.24px;--material-glass-saturation:121.36%}:root[data-glass-intensity="27"]{--material-glass-alpha:.392;--material-glass-blur:18.48px;--material-glass-saturation:121.72%}:root[data-glass-intensity="28"]{--material-glass-alpha:.395;--material-glass-blur:18.72px;--material-glass-saturation:122.08%}:root[data-glass-intensity="29"]{--material-glass-alpha:.399;--material-glass-blur:18.96px;--material-glass-saturation:122.44%}:root[data-glass-intensity="30"]{--material-glass-alpha:.402;--material-glass-blur:19.2px;--material-glass-saturation:122.8%}:root[data-glass-intensity="31"]{--material-glass-alpha:.405;--material-glass-blur:19.44px;--material-glass-saturation:123.16%}:root[data-glass-intensity="32"]{--material-glass-alpha:.409;--material-glass-blur:19.68px;--material-glass-saturation:123.52%}:root[data-glass-intensity="33"]{--material-glass-alpha:.412;--material-glass-blur:19.92px;--material-glass-saturation:123.88%}:root[data-glass-intensity="34"]{--material-glass-alpha:.416;--material-glass-blur:20.16px;--material-glass-saturation:124.24%}:root[data-glass-intensity="35"]{--material-glass-alpha:.419;--material-glass-blur:20.4px;--material-glass-saturation:124.6%}:root[data-glass-intensity="36"]{--material-glass-alpha:.422;--material-glass-blur:20.64px;--material-glass-saturation:124.96%}:root[data-glass-intensity="37"]{--material-glass-alpha:.426;--material-glass-blur:20.88px;--material-glass-saturation:125.32%}:root[data-glass-intensity="38"]{--material-glass-alpha:.429;--material-glass-blur:21.12px;--material-glass-saturation:125.68%}:root[data-glass-intensity="39"]{--material-glass-alpha:.433;--material-glass-blur:21.36px;--material-glass-saturation:126.04%}:root[data-glass-intensity="40"]{--material-glass-alpha:.436;--material-glass-blur:21.6px;--material-glass-saturation:126.4%}:root[data-glass-intensity="41"]{--material-glass-alpha:.439;--material-glass-blur:21.84px;--material-glass-saturation:126.76%}:root[data-glass-intensity="42"]{--material-glass-alpha:.443;--material-glass-blur:22.08px;--material-glass-saturation:127.12%}:root[data-glass-intensity="43"]{--material-glass-alpha:.446;--material-glass-blur:22.32px;--material-glass-saturation:127.48%}:root[data-glass-intensity="44"]{--material-glass-alpha:.45;--material-glass-blur:22.56px;--material-glass-saturation:127.84%}:root[data-glass-intensity="45"]{--material-glass-alpha:.453;--material-glass-blur:22.8px;--material-glass-saturation:128.2%}:root[data-glass-intensity="46"]{--material-glass-alpha:.456;--material-glass-blur:23.04px;--material-glass-saturation:128.56%}:root[data-glass-intensity="47"]{--material-glass-alpha:.46;--material-glass-blur:23.28px;--material-glass-saturation:128.92%}:root[data-glass-intensity="48"]{--material-glass-alpha:.463;--material-glass-blur:23.52px;--material-glass-saturation:129.28%}:root[data-glass-intensity="49"]{--material-glass-alpha:.467;--material-glass-blur:23.76px;--material-glass-saturation:129.64%}:root[data-glass-intensity="50"]{--material-glass-alpha:.47;--material-glass-blur:24px;--material-glass-saturation:130.0%}:root[data-glass-intensity="51"]{--material-glass-alpha:.473;--material-glass-blur:24.24px;--material-glass-saturation:130.36%}:root[data-glass-intensity="52"]{--material-glass-alpha:.477;--material-glass-blur:24.48px;--material-glass-saturation:130.72%}:root[data-glass-intensity="53"]{--material-glass-alpha:.48;--material-glass-blur:24.72px;--material-glass-saturation:131.08%}:root[data-glass-intensity="54"]{--material-glass-alpha:.484;--material-glass-blur:24.96px;--material-glass-saturation:131.44%}:root[data-glass-intensity="55"]{--material-glass-alpha:.487;--material-glass-blur:25.2px;--material-glass-saturation:131.8%}:root[data-glass-intensity="56"]{--material-glass-alpha:.49;--material-glass-blur:25.44px;--material-glass-saturation:132.16%}:root[data-glass-intensity="57"]{--material-glass-alpha:.494;--material-glass-blur:25.68px;--material-glass-saturation:132.52%}:root[data-glass-intensity="58"]{--material-glass-alpha:.497;--material-glass-blur:25.92px;--material-glass-saturation:132.88%}:root[data-glass-intensity="59"]{--material-glass-alpha:.501;--material-glass-blur:26.16px;--material-glass-saturation:133.24%}:root[data-glass-intensity="60"]{--material-glass-alpha:.504;--material-glass-blur:26.4px;--material-glass-saturation:133.6%}:root[data-glass-intensity="61"]{--material-glass-alpha:.507;--material-glass-blur:26.64px;--material-glass-saturation:133.96%}:root[data-glass-intensity="62"]{--material-glass-alpha:.511;--material-glass-blur:26.88px;--material-glass-saturation:134.32%}:root[data-glass-intensity="63"]{--material-glass-alpha:.514;--material-glass-blur:27.12px;--material-glass-saturation:134.68%}:root[data-glass-intensity="64"]{--material-glass-alpha:.518;--material-glass-blur:27.36px;--material-glass-saturation:135.04%}:root[data-glass-intensity="65"]{--material-glass-alpha:.521;--material-glass-blur:27.6px;--material-glass-saturation:135.4%}:root[data-glass-intensity="66"]{--material-glass-alpha:.524;--material-glass-blur:27.84px;--material-glass-saturation:135.76%}:root[data-glass-intensity="67"]{--material-glass-alpha:.528;--material-glass-blur:28.08px;--material-glass-saturation:136.12%}:root[data-glass-intensity="68"]{--material-glass-alpha:.531;--material-glass-blur:28.32px;--material-glass-saturation:136.48%}:root[data-glass-intensity="69"]{--material-glass-alpha:.535;--material-glass-blur:28.56px;--material-glass-saturation:136.84%}:root[data-glass-intensity="70"]{--material-glass-alpha:.538;--material-glass-blur:28.8px;--material-glass-saturation:137.2%}:root[data-glass-intensity="71"]{--material-glass-alpha:.541;--material-glass-blur:29.04px;--material-glass-saturation:137.56%}:root[data-glass-intensity="72"]{--material-glass-alpha:.545;--material-glass-blur:29.28px;--material-glass-saturation:137.92%}:root[data-glass-intensity="73"]{--material-glass-alpha:.548;--material-glass-blur:29.52px;--material-glass-saturation:138.28%}:root[data-glass-intensity="74"]{--material-glass-alpha:.552;--material-glass-blur:29.76px;--material-glass-saturation:138.64%}:root[data-glass-intensity="75"]{--material-glass-alpha:.555;--material-glass-blur:30px;--material-glass-saturation:139.0%}:root[data-glass-intensity="76"]{--material-glass-alpha:.558;--material-glass-blur:30.24px;--material-glass-saturation:139.36%}:root[data-glass-intensity="77"]{--material-glass-alpha:.562;--material-glass-blur:30.48px;--material-glass-saturation:139.72%}:root[data-glass-intensity="78"]{--material-glass-alpha:.565;--material-glass-blur:30.72px;--material-glass-saturation:140.08%}:root[data-glass-intensity="79"]{--material-glass-alpha:.569;--material-glass-blur:30.96px;--material-glass-saturation:140.44%}:root[data-glass-intensity="80"]{--material-glass-alpha:.572;--material-glass-blur:31.2px;--material-glass-saturation:140.8%}:root[data-glass-intensity="81"]{--material-glass-alpha:.575;--material-glass-blur:31.44px;--material-glass-saturation:141.16%}:root[data-glass-intensity="82"]{--material-glass-alpha:.579;--material-glass-blur:31.68px;--material-glass-saturation:141.52%}:root[data-glass-intensity="83"]{--material-glass-alpha:.582;--material-glass-blur:31.92px;--material-glass-saturation:141.88%}:root[data-glass-intensity="84"]{--material-glass-alpha:.586;--material-glass-blur:32.16px;--material-glass-saturation:142.24%}:root[data-glass-intensity="85"]{--material-glass-alpha:.589;--material-glass-blur:32.4px;--material-glass-saturation:142.6%}:root[data-glass-intensity="86"]{--material-glass-alpha:.592;--material-glass-blur:32.64px;--material-glass-saturation:142.96%}:root[data-glass-intensity="87"]{--material-glass-alpha:.596;--material-glass-blur:32.88px;--material-glass-saturation:143.32%}:root[data-glass-intensity="88"]{--material-glass-alpha:.599;--material-glass-blur:33.12px;--material-glass-saturation:143.68%}:root[data-glass-intensity="89"]{--material-glass-alpha:.603;--material-glass-blur:33.36px;--material-glass-saturation:144.04%}:root[data-glass-intensity="90"]{--material-glass-alpha:.606;--material-glass-blur:33.6px;--material-glass-saturation:144.4%}:root[data-glass-intensity="91"]{--material-glass-alpha:.609;--material-glass-blur:33.84px;--material-glass-saturation:144.76%}:root[data-glass-intensity="92"]{--material-glass-alpha:.613;--material-glass-blur:34.08px;--material-glass-saturation:145.12%}:root[data-glass-intensity="93"]{--material-glass-alpha:.616;--material-glass-blur:34.32px;--material-glass-saturation:145.48%}:root[data-glass-intensity="94"]{--material-glass-alpha:.62;--material-glass-blur:34.56px;--material-glass-saturation:145.84%}:root[data-glass-intensity="95"]{--material-glass-alpha:.623;--material-glass-blur:34.8px;--material-glass-saturation:146.2%}:root[data-glass-intensity="96"]{--material-glass-alpha:.626;--material-glass-blur:35.04px;--material-glass-saturation:146.56%}:root[data-glass-intensity="97"]{--material-glass-alpha:.63;--material-glass-blur:35.28px;--material-glass-saturation:146.92%}:root[data-glass-intensity="98"]{--material-glass-alpha:.633;--material-glass-blur:35.52px;--material-glass-saturation:147.28%}:root[data-glass-intensity="99"]{--material-glass-alpha:.637;--material-glass-blur:35.76px;--material-glass-saturation:147.64%}:root[data-glass-intensity="100"]{--material-glass-alpha:.64;--material-glass-blur:36px;--material-glass-saturation:148.0%}:root[data-material=opaque],:root[data-reduce-transparency=true],:root[data-backdrop-filter=unsupported],:root[data-high-contrast=on]{--material-glass-blur:0px;--material-glass-saturation:100%}@media (prefers-reduced-transparency:reduce){:root[data-glass-intensity]{--material-glass-blur:0px;--material-glass-saturation:100%}}@media (prefers-contrast:more){:root:not([data-high-contrast=off]){--material-glass-blur:0px;--material-glass-saturation:100%}}:root{--token-borderRadius:var(--radius-sm);--token-borderRadiusLG:var(--radius-lg);--token-borderRadiusSM:var(--radius-xs);--token-borderRadiusXL:var(--radius-xl);--token-buttonBorderRadius:999px;--token-controlHeight:36px;--token-controlHeightLG:44px;--token-controlHeightSM:32px;--token-focusRingOffset:2px;--token-focusRingStyle:solid;--token-focusRingWidth:2px;--token-fontFamily:-apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", system-ui, sans-serif;--token-fontSize:1rem;--token-fontSizeDisplay4:2rem;--token-fontSizeHeading1:1.75rem;--token-fontSizeHeading2:1.5rem;--token-fontSizeHeading3:1.25rem;--token-fontSizeHeading4:1rem;--token-fontSizeLG:1.125rem;--token-fontSizeSM:.9rem;--token-fontSizeXL:1.25rem;--token-fontSizeXXL:1.5rem;--token-fontSizeXXS:.75rem;--token-marginXXS:var(--space-1);--token-motionDurationFast:var(--motion-fast);--token-motionDurationMid:var(--motion-standard);--token-motionDurationSlow:var(--motion-slow);--token-padding:var(--space-3);--token-paddingLG:var(--space-5);--token-paddingMD:var(--space-4);--token-paddingSM:var(--space-2);--token-paddingXL:var(--space-6);--token-paddingXS:var(--space-1);--token-paddingXXS:var(--space-1);--token-scrollbarRadius:999px;--token-scrollbarSize:6px;--token-themeTransitionDuration:var(--motion-standard);--token-themeTransitionTiming:ease;--token-zIndexDrawer:90;--token-zIndexDrawerContent:91;--token-zIndexPopover:100;--token-zIndexTooltip:110}.button.ds-button.button--inline,.button.ds-icon-button.button--inline{border:1px solid var(--color-separator);min-height:32px;line-height:normal;font:inherit;border-radius:999px;font-weight:650}.button.ds-button.button--inline{gap:var(--space-2);white-space:normal;overflow-wrap:anywhere;justify-content:center;padding:7px 14px}.button.ds-icon-button.button--inline{aspect-ratio:auto;justify-content:center;min-width:32px;padding:0 9px}.button.ds-button-secondary,.button.ds-icon-button{color:var(--color-text)}.button.ds-button-primary,.button.ds-button-danger{color:#fff}.button.ds-button:disabled,.button.ds-icon-button:disabled{opacity:.56}.button.ds-button:focus-visible,.button.ds-icon-button:focus-visible{box-shadow:var(--focus-ring);outline:none}.app-toolbar .ds-icon-button .button__icon{color:inherit}.ds-button .button__loading-spinner{width:14px;height:14px}.ds-icon-button .button__icon{place-items:center;display:inline-grid}.ds-status.badge{text-transform:none;gap:var(--space-1);border:1px solid var(--color-separator);min-height:24px;color:var(--color-text);background:0 0;border-radius:999px;padding:3px 9px;font-size:.82rem;font-weight:700}.ds-status-wrap[data-state=ready] .ds-status{color:var(--color-success);background:var(--color-success-bg)}.ds-status-wrap[data-state=failed] .ds-status{color:var(--color-error);background:var(--color-error-bg)}.ds-status-wrap[data-state=loading] .ds-status,.ds-status-wrap[data-state=draining] .ds-status,.ds-status-wrap[data-state=unloading] .ds-status{color:var(--color-warning);background:var(--color-warning-bg)}.ds-status-wrap[data-state=loading] .ds-status:before,.ds-status-wrap[data-state=draining] .ds-status:before,.ds-status-wrap[data-state=unloading] .ds-status:before{animation:pulse var(--motion-slow) ease-in-out infinite alternate}.ds-progress .progress-bar__fill{border-radius:inherit;background:linear-gradient(90deg,#2f6cff,#7b61ff);height:100%}.ds-progress .progress-bar--indeterminate{background:var(--color-bg-neutral);animation:none}.ds-progress .progress-bar--indeterminate .progress-bar__fill{width:48%;animation:slide var(--motion-slow) ease-in-out infinite alternate;display:block}.ds-empty .empty-state{gap:var(--space-2);width:100%;min-height:0;padding:0;animation:none}.ds-empty .empty-state__illustration{border-radius:var(--radius-md);background:var(--color-selection);width:44px;height:44px;color:var(--color-focus);place-items:center;margin:0;display:grid}.ds-empty .empty-state__illustration:before{content:none}.ds-empty .empty-state__content{justify-items:center;gap:var(--space-2);min-width:0;max-width:100%;margin:0;display:grid}.ds-empty .empty-state__title{margin:0;font-size:1.5em;font-weight:700;line-height:normal}.ds-empty .empty-state__description{color:var(--color-text);overflow-wrap:anywhere;line-height:normal}.ds-tabs.tabs{gap:var(--space-4);min-width:0}.ds-tabs .tabs__container{box-shadow:none;background:0 0;border:0;border-radius:0;margin:0;padding:0;overflow:visible}.ds-tabs .tabs__list{min-width:0;overflow:visible}.ds-tabs.tabs--fill-container .tabs__tab{white-space:normal;overflow-wrap:anywhere;flex:8rem;min-width:0}.ds-tabs .tabs__tab--active{box-shadow:inset 0 0 0 1px var(--color-separator);transform:none}.ds-tabs .tabs__panel{border:0;min-width:0;padding:0;animation:none}.ds-tabs .tabs__tab-label{white-space:normal;overflow-wrap:anywhere}.ds-common-select .select__trigger{min-width:0;min-height:36px;font:inherit;padding:8px 10px}.ds-common-select .select__value-label,.select__option-label{white-space:normal;overflow-wrap:anywhere}.ds-common-select .select__value{overflow:visible}.ds-common-select .select--labelled{gap:var(--space-2)}.ds-common-select .select__label{color:var(--color-text);font-size:.9rem;font-weight:650}.select__dropdown--portal{max-width:calc(100vw - 16px)}.tooltip__wrapper.ds-tooltip-trigger{min-width:0;max-width:100%}.ds-drawer-host{display:contents}.drawer.ds-drawer{color:var(--color-text);background:var(--color-bg-elevated);border:1px solid var(--color-separator);border-radius:var(--radius-xl);inset:12px auto 12px 12px;overflow:hidden;transform:translate(calc(-100% - 12px));box-shadow:0 30px 120px #00000052;width:min(320px,100vw - 32px)!important;max-width:calc(100vw - 32px)!important}.drawer.ds-drawer.drawer--open{transform:translate(0)}.ds-drawer .drawer__header{padding:var(--space-4) var(--space-5);border-bottom:1px solid var(--color-separator)}.ds-drawer .drawer__title{min-width:0;color:var(--color-text);overflow-wrap:anywhere;font-size:1.1rem}.ds-drawer .drawer__close-btn{color:var(--color-text);flex:none}.ds-drawer .drawer__close-btn:focus-visible{box-shadow:var(--focus-ring);outline:none}.ds-drawer .drawer__content{padding:var(--space-5)}.base-card.ds-card{display:block}.base-card.ds-card:focus-visible{outline:2px solid var(--color-focus);outline-offset:2px}.page-layout.ds-page-layout{padding-inline:0}.ds-page-header{min-width:0;max-width:100%}.ds-page-header .page-header{margin:0}.ds-page-header .page-header__title{color:var(--color-text);letter-spacing:-.025em;overflow-wrap:anywhere;margin:0;font-size:clamp(1.45rem,2.6vw,1.75rem);font-weight:700;line-height:1.12}.ds-page-header .page-header__description{color:var(--color-muted);overflow-wrap:anywhere;margin:1em 0 0;font-size:1rem;line-height:1.55}.ds-page-header .page-header__actions,.ds-page-header .page-header__actions>*{max-width:100%}.ds-page-header .page-header__error{margin-top:var(--space-4);padding:var(--space-3) var(--space-4);color:var(--color-error);background:var(--color-error-bg);border:1px solid var(--color-separator);border-radius:var(--radius-lg);flex-wrap:wrap;font-size:1rem}.ds-page-header .page-header__error-body{flex:12rem;min-width:0}.ds-page-header .page-header__error-text{overflow-wrap:anywhere;font-weight:700}.ds-page-header .page-header__error-detail{color:var(--color-text);overflow-wrap:anywhere;font-size:.9rem}.ds-page-header .page-header__error-actions{flex-shrink:1;min-width:0;max-width:100%;padding-left:0}.ds-page-header .button.page-header__error-retry{border:1px solid var(--color-separator);max-width:100%;min-height:32px;color:var(--color-text);background:var(--material-control-bg);font:inherit;white-space:normal;overflow-wrap:anywhere;border-radius:999px;padding:7px 14px;font-weight:650;line-height:normal}.ds-page-header .button.page-header__error-retry:focus-visible{box-shadow:var(--focus-ring);outline:none}.ds-stat-card .stat-card__label,.ds-stat-card .stat-card__value{text-overflow:clip;white-space:normal;overflow-wrap:anywhere;min-width:0;overflow:visible}.ds-stat-card .stat-card__label{color:var(--color-text);letter-spacing:normal;text-transform:none;font-size:.9rem}.ds-stat-card .stat-card__value{color:var(--color-text);font-size:1.25rem}.ds-stat-card .stat-card__hint{color:var(--color-muted);font-size:.85rem}.ds-stat-card .stat-card__hint p{margin:var(--space-1) 0 0}.base-card.ds-stat-card:hover{box-shadow:none;transform:none}.ds-loading{gap:var(--space-2);display:grid}.ds-loading__label{color:var(--color-muted);margin:0}.ds-loading__shapes{gap:var(--space-2);display:grid}.badge.ds-badge{letter-spacing:normal;text-transform:none;white-space:normal;overflow-wrap:anywhere;min-height:20px}.badge.ds-badge.badge--primary{color:var(--color-text);box-shadow:inset 0 0 0 1px var(--color-focus);background-color:#0000}.ds-banner .error-state{gap:var(--space-2);text-align:start;place-content:start stretch;place-items:start;min-height:0;padding:0;display:grid}.ds-banner .error-state__title{color:inherit;font-size:inherit;font-weight:700;line-height:inherit;margin:0}.ds-banner .error-state__message{max-width:none;color:inherit;font-size:inherit;line-height:inherit;margin:0}.ds-common-table{color:var(--color-text);background:var(--material-content-bg);border-radius:var(--radius-lg)}.ds-row-activation{display:contents}.ds-row-activation :where(tbody>tr:has(.ds-row-primary:not(:disabled,[aria-disabled=true]))){cursor:pointer}.ds-row-activation :where(tbody>tr:has(.ds-row-primary:not(:disabled,[aria-disabled=true])):hover){background-color:var(--token-colorFillQuaternary)}.ds-row-activation tbody>tr:has(.ds-row-primary:focus-visible){outline:2px solid var(--color-focus);outline-offset:-2px}@media (width<=560px),(pointer:coarse){.app-toolbar .button.ds-icon-button.button--inline{min-width:44px;min-height:44px}}:root[data-high-contrast=on] .button.ds-button,:root[data-high-contrast=on] .button.ds-icon-button,:root[data-high-contrast=on] .ds-page-header .button.page-header__error-retry,:root[data-high-contrast=on] .ds-page-header .page-header__error{border-width:2px}@media (prefers-contrast:more){:root:not([data-high-contrast=off]) .button.ds-button,:root:not([data-high-contrast=off]) .button.ds-icon-button,:root:not([data-high-contrast=off]) .ds-page-header .button.page-header__error-retry,:root:not([data-high-contrast=off]) .ds-page-header .page-header__error{border-width:2px}}.gallery-progress-samples{align-content:start;gap:var(--space-4);min-width:0;display:grid} diff --git a/src/webui/assets/index.html b/src/webui/assets/index.html index e73c0ff59..e8e8f26b8 100644 --- a/src/webui/assets/index.html +++ b/src/webui/assets/index.html @@ -6,8 +6,8 @@ mlxcel WebUI - - + +
diff --git a/src/webui/assets/mlxcel-webui-manifest.json b/src/webui/assets/mlxcel-webui-manifest.json index e874195a9..8a348db21 100644 --- a/src/webui/assets/mlxcel-webui-manifest.json +++ b/src/webui/assets/mlxcel-webui-manifest.json @@ -1,42 +1,42 @@ { "budgets": { - "embedded_asset_bytes": 746104, + "embedded_asset_bytes": 755830, "embedded_asset_limit_bytes": 5242880, - "initial_js_gzip_bytes": 158146, + "initial_js_gzip_bytes": 159871, "initial_js_gzip_limit_bytes": 204800, - "total_js_gzip_bytes": 159325, + "total_js_gzip_bytes": 161050, "total_js_gzip_limit_bytes": 716800 }, "files": [ { "bytes": 951, - "gzip_bytes": 613, - "path": "assets/code-highlight-B24EZUmw.js", - "sha256": "5015bf4e231a2944b84e11144de91736e62fe4ec2919d7034ec2e2f242bf619b" + "gzip_bytes": 614, + "path": "assets/code-highlight-Dk2RxJiZ.js", + "sha256": "307afce1fa23daff3edb6ed75f7ea5ff2c9e0cb55518fe15a84e947db08d1224" }, { "bytes": 1134, - "gzip_bytes": 566, - "path": "assets/history-B_cN6LK7.js", - "sha256": "543d0301e16274f6571e0101b329123f91dda0bc42984f3e2bc0602e00ca0820" + "gzip_bytes": 565, + "path": "assets/history-BBsc_X23.js", + "sha256": "1812350b22a3304d359b1467f6b25171dbc0f468f73f235bb2c5766f3a5c8741" }, { - "bytes": 609104, - "gzip_bytes": 157157, - "path": "assets/index-CCGbr2W2.js", - "sha256": "4e2e166e278a15ae05ae90ea2881cabff8c13e83e79c13b05173f7f3ea680ed0" + "bytes": 615798, + "gzip_bytes": 158882, + "path": "assets/index-CQvJAqGK.js", + "sha256": "f8612db770d78d2f2f1c6cbc41f5052f7fdcc60b2f94a57d8e7b7a75c9871056" }, { - "bytes": 116777, - "gzip_bytes": 18527, - "path": "assets/index-CHdEXEMP.css", - "sha256": "503d11e47505305a5e6bda4ea31976ea20f53d08bbdbe32dd0c0a0b095fbf27b" + "bytes": 119809, + "gzip_bytes": 19046, + "path": "assets/index-jRmdkkyk.css", + "sha256": "db7caabf81182398f8e102dbc9ccc22d796fc096a307d577a823e99ccfda3421" }, { "bytes": 503, - "gzip_bytes": 303, + "gzip_bytes": 302, "path": "index.html", - "sha256": "c6bd85fd1a15741bfc9d96c6cb4063d74ed47c35e9a68d640d39407daa7316a6" + "sha256": "c206fbd03011f41190e35f41655bb195b44a09913cbc6a9621d5efc6b5fd2cb4" }, { "bytes": 2129, @@ -73,5 +73,5 @@ }, "pnpm_version": "11.18.0", "schema_version": 1, - "source_digest_sha256": "99d56437dcb42febc536c46ed8095a3d2c479074bd630a64903fdda1fd7a65c0" + "source_digest_sha256": "2ab50c0b1ad976de3df2242e41a581e7d714a7f41ceed7b305c2e98375794855" } diff --git a/tests/fixtures/webui/strings.json b/tests/fixtures/webui/strings.json index 8d40be784..1c139602a 100644 --- a/tests/fixtures/webui/strings.json +++ b/tests/fixtures/webui/strings.json @@ -78,6 +78,42 @@ "ko": "내비게이션 열기", "test_id": "toolbar-menu" }, + { + "key": "toolbar.loaded.label", + "en": "Loaded models", + "ko": "로드된 모델", + "test_id": "toolbar-loaded" + }, + { + "key": "toolbar.loaded.none", + "en": "No model loaded", + "ko": "로드된 모델 없음", + "test_id": "toolbar-loaded-none" + }, + { + "key": "toolbar.loaded.unknown", + "en": "Loaded models unknown", + "ko": "로드된 모델 알 수 없음", + "test_id": "toolbar-loaded-unknown" + }, + { + "key": "toolbar.loaded.count", + "en": "{count} loaded", + "ko": "{count}개 로드됨", + "test_id": "toolbar-loaded-count" + }, + { + "key": "toolbar.loaded.more", + "en": "+{count}", + "ko": "+{count}", + "test_id": "toolbar-loaded-more" + }, + { + "key": "toolbar.loaded.more_label", + "en": "+{count}, show all loaded models", + "ko": "+{count}, 로드된 모델 모두 보기", + "test_id": "toolbar-loaded-more-label" + }, { "key": "connection.ready", "en": "Shell loaded; local API not connected", @@ -110,10 +146,28 @@ }, { "key": "connection.footer.connected", - "en": "{mode} · {status} · v{version} · seq {sequence}", - "ko": "{mode} · {status} · v{version} · seq {sequence}", + "en": "{mode} · {status} · v{version}", + "ko": "{mode} · {status} · v{version}", "test_id": "connection-footer-connected" }, + { + "key": "connection.footer.details", + "en": "Connection details", + "ko": "연결 세부 정보", + "test_id": "connection-footer-details" + }, + { + "key": "connection.footer.instance", + "en": "Server instance: {id}", + "ko": "서버 인스턴스: {id}", + "test_id": "connection-footer-instance" + }, + { + "key": "connection.footer.sequence", + "en": "Event sequence: {sequence}", + "ko": "이벤트 순번: {sequence}", + "test_id": "connection-footer-sequence" + }, { "key": "connection.snapshot.pending", "en": "pending", @@ -536,16 +590,28 @@ }, { "key": "command.search", - "en": "Search commands", - "ko": "명령 검색", + "en": "Search commands and models", + "ko": "명령과 모델 검색", "test_id": "command-search" }, { "key": "command.no_results", - "en": "No commands match this search.", - "ko": "검색과 일치하는 명령이 없습니다.", + "en": "No commands or models match this search.", + "ko": "검색과 일치하는 명령이나 모델이 없습니다.", "test_id": "command-no-results" }, + { + "key": "command.section.commands", + "en": "Commands", + "ko": "명령", + "test_id": "command-section-commands" + }, + { + "key": "command.section.models", + "en": "Models", + "ko": "모델", + "test_id": "command-section-models" + }, { "key": "help.title", "en": "Keyboard shortcuts", @@ -554,10 +620,46 @@ }, { "key": "help.body", - "en": "Command opens search. Escape closes overlays. Brackets move navigation only while the sidebar has focus.", - "ko": "Command는 검색을 엽니다. Escape는 오버레이를 닫습니다. 대괄호는 사이드바에 포커스가 있을 때만 내비게이션을 이동합니다.", + "en": "Shortcuts do not fire while you type in a field, inside an open dialog (Esc still closes it) or during IME composition. Cmd/Ctrl+N and Cmd/Ctrl+Enter also work in the chat message field. Brackets move navigation only while the sidebar has focus.", + "ko": "입력란에 입력하는 중, 열린 다이얼로그 안(Esc로 닫기는 가능), IME 조합 중에는 단축키가 동작하지 않습니다. Cmd/Ctrl+N과 Cmd/Ctrl+Enter는 대화 메시지 입력란에서도 동작합니다. 대괄호는 사이드바에 포커스가 있을 때만 내비게이션을 이동합니다.", "test_id": "help-body" }, + { + "key": "help.shortcut.command", + "en": "Open the command palette", + "ko": "명령 팔레트 열기", + "test_id": "help-shortcut-command" + }, + { + "key": "help.shortcut.new_chat", + "en": "Start a new conversation", + "ko": "새 대화 시작", + "test_id": "help-shortcut-new-chat" + }, + { + "key": "help.shortcut.send", + "en": "Send the message from the composer", + "ko": "입력 중인 메시지 보내기", + "test_id": "help-shortcut-send" + }, + { + "key": "help.shortcut.escape", + "en": "Close the open dialog or navigation", + "ko": "열린 다이얼로그나 내비게이션 닫기", + "test_id": "help-shortcut-escape" + }, + { + "key": "help.shortcut.navigate", + "en": "Move primary navigation while the sidebar has focus", + "ko": "사이드바에 포커스가 있을 때 주 내비게이션 이동", + "test_id": "help-shortcut-navigate" + }, + { + "key": "help.shortcut.help", + "en": "Show keyboard shortcuts", + "ko": "키보드 단축키 보기", + "test_id": "help-shortcut-help" + }, { "key": "gallery.title", "en": "Design system gallery", @@ -576,12 +678,6 @@ "ko": "긴 English 및 한국어 레이블은 접근 가능한 전체 레이블을 유지하며 줄임표 처리됩니다.", "test_id": "gallery-long-cjk" }, - { - "key": "model.selected.none", - "en": "No model selected", - "ko": "선택한 모델 없음", - "test_id": "model-selected-none" - }, { "key": "common.unavailable", "en": "Unavailable until server adapters connect", @@ -630,30 +726,6 @@ "ko": "보내기", "test_id": "common-send" }, - { - "key": "routes.models.eyebrow", - "en": "Local library", - "ko": "로컬 라이브러리", - "test_id": "routes-models-eyebrow" - }, - { - "key": "routes.chat.eyebrow", - "en": "Conversation", - "ko": "대화", - "test_id": "routes-chat-eyebrow" - }, - { - "key": "routes.activity.eyebrow", - "en": "Operations", - "ko": "작업", - "test_id": "routes-activity-eyebrow" - }, - { - "key": "routes.settings.eyebrow", - "en": "Browser only", - "ko": "브라우저 전용", - "test_id": "routes-settings-eyebrow" - }, { "key": "adapters.pending.title", "en": "Local API is not connected yet", @@ -924,12 +996,6 @@ "ko": "끔", "test_id": "settings-high-contrast-off" }, - { - "key": "gallery.issue", - "en": "Issue #1843", - "ko": "이슈 #1843", - "test_id": "gallery-issue" - }, { "key": "gallery.hover_focus", "en": "Hover or focus", @@ -1542,12 +1608,6 @@ "ko": "아직 측정되지 않음", "test_id": "format-not-measured" }, - { - "key": "chat.eyebrow", - "en": "Local inference", - "ko": "로컬 추론", - "test_id": "chat-eyebrow" - }, { "key": "chat.intro", "en": "Memory-only by default. Changing the model affects the next turn, never the running request.", diff --git a/webui/src/app.provider.test.tsx b/webui/src/app.provider.test.tsx index fec2aaff3..d7e0cc0f1 100644 --- a/webui/src/app.provider.test.tsx +++ b/webui/src/app.provider.test.tsx @@ -6,7 +6,8 @@ import bootstrapFixture from '../../tests/fixtures/webui/examples/bootstrap.mode import catalogFixture from '../../tests/fixtures/webui/examples/catalog.page.json'; import operationsFixture from '../../tests/fixtures/webui/examples/operations.list.json'; import { App } from './app'; -import { WebUiProvider } from './state'; +import { replaceConversations, useConversations } from './features/chat/session'; +import { WebUiProvider, WebUiSynchronizer } from './state'; interface FetchCall { readonly url: string; @@ -19,12 +20,15 @@ type Scenario = 'happy' | 'bad-key' | 'offline' | 'malformed-bootstrap' | 'sync- let root: Root | null = null; let host: HTMLDivElement | null = null; +let conversationCount = 0; +function ConversationsProbe(): null { conversationCount = useConversations().length; return null; } beforeEach(() => { HTMLDialogElement.prototype.showModal = vi.fn(function showModal(this: HTMLDialogElement) { this.setAttribute('open', ''); }); HTMLDialogElement.prototype.close = vi.fn(function close(this: HTMLDialogElement) { this.removeAttribute('open'); this.dispatchEvent(new Event('close')); }); localStorage.clear(); sessionStorage.clear(); + replaceConversations([]); window.history.replaceState(null, '', '/webui/#models'); host = document.createElement('div'); host.id = 'root'; @@ -41,10 +45,29 @@ afterEach(() => { }); function renderApp(fetchImpl: typeof fetch): void { - act(() => root?.render()); + act(() => root?.render()); } -function createMockFetch(scenario: Scenario): { readonly calls: FetchCall[]; readonly fetchImpl: typeof fetch } { +// The catalog fixture's single model, loaded and chat-ready on the server. +function readyCatalog(page: typeof catalogFixture): typeof catalogFixture { + const entry = page.items[0]; + entry.lifecycle.state = 'ready'; + entry.lifecycle.worker_exit_observed = false; + entry.capabilities = [{ task: 'chat', phase: 'provider_ready', available: true, reason: null }]; + return page; +} + +// The fixture's unloaded model next to a second one whose load failed: neither holds a worker. +function unloadedAndFailedCatalog(page: typeof catalogFixture): typeof catalogFixture { + const failed = structuredClone(page.items[0]); + failed.identity = { ...failed.identity, id: `mdl_${'f'.repeat(43)}`, inference_id: 'beta', display_name: 'beta', source_key_hash: 'f'.repeat(64) }; + failed.lifecycle = { ...failed.lifecycle, state: 'failed' }; + page.items = [page.items[0], failed]; + page.pagination = { ...page.pagination, total_known: 2 }; + return page; +} + +function createMockFetch(scenario: Scenario, catalog: (page: typeof catalogFixture) => typeof catalogFixture = (page) => page): { readonly calls: FetchCall[]; readonly fetchImpl: typeof fetch } { const calls: FetchCall[] = []; let bootstrapCount = 0; const fetchImpl: typeof fetch = async (input, init) => { @@ -57,7 +80,7 @@ function createMockFetch(scenario: Scenario): { readonly calls: FetchCall[]; rea if (scenario === 'malformed-bootstrap') return jsonResponse({ schema_version: 'wrong', server: { server_instance_id: 'srv_bad' } }); return jsonResponse(makeBootstrap()); } - if (url.startsWith('/ui-api/v1/catalog')) return jsonResponse(makeCatalog()); + if (url.startsWith('/ui-api/v1/catalog')) return jsonResponse(catalog(makeCatalog())); if (url.startsWith('/ui-api/v1/operations')) { if (scenario === 'sync-401' && bootstrapCount >= 2) return jsonResponse({ error: { code: 'unauthorized', message: 'stale session', retryable: false }, request_id: 'req_sync_401' }, 401); return jsonResponse(makeOperations()); @@ -143,6 +166,7 @@ describe('provider-backed WebUI shell', () => { expect(snapshotCalls.map((call) => call.url).join('\n')).toContain('/ui-api/v1/catalog'); expect(document.querySelector('[data-testid="connection-authenticated-detail"]')?.textContent).toContain('catalog 1'); expect(document.querySelector('[data-testid="connection-ready"]')?.textContent).toContain('model_free'); + expect(document.querySelector('[data-testid="connection-ready"]')?.textContent).not.toContain('seq'); expect(`${localStorage.getItem('good-key')} ${sessionStorage.getItem('good-key')}`).not.toContain('good-key'); expect(mock.calls.map((call) => call.url).join(' ')).not.toContain('good-key'); }); @@ -264,4 +288,149 @@ describe('provider-backed WebUI shell', () => { expect(urls).not.toContain('/ui-api/v1/model-actions'); expect(urls).not.toContain('/ui-api/v1/downloads'); }); + + it('names the server-loaded model in the toolbar with no browser selection and opens its inspector from the chip', async () => { + const mock = createMockFetch('happy', readyCatalog); + renderApp(mock.fetchImpl); + const region = document.querySelector('[data-testid="toolbar-loaded"]'); + expect(region?.getAttribute('role')).toBe('group'); + expect(region?.getAttribute('aria-label')).toBe('Loaded models'); + // Signed out, nothing has been read from the server, so the toolbar claims nothing about it. + expect(region?.textContent).toBe('Loaded models unknown'); + expect(region?.querySelector('[data-testid="toolbar-loaded-unknown"]')).not.toBeNull(); + expect(region?.querySelector('[data-testid="toolbar-loaded-none"]')).toBeNull(); + await submitSessionKey('good-key'); + await waitFor(() => expect(document.querySelector('[data-testid="toolbar-loaded-count"]')?.textContent).toBe('1 loaded')); + const chips = document.querySelectorAll('[data-testid="toolbar-loaded-chip"]'); + expect(chips).toHaveLength(1); + expect(chips[0].textContent).toBe('alphaReady'); + expect(chips[0].title).toBe('alpha'); + expect(chips[0].hasAttribute('aria-label')).toBe(false); + expect(chips[0].querySelector('.ds-status-wrap[data-state="ready"]')?.textContent).toBe('Ready'); + expect(document.querySelector('[data-testid="toolbar-loaded-more"]')).toBeNull(); + expect(document.querySelector('aside[aria-label="Model details"]')).toBeNull(); + act(() => document.querySelector('[data-testid="nav-settings"]')?.click()); + expect(window.location.hash).toBe('#settings'); + act(() => document.querySelector('[data-testid="toolbar-loaded-chip"]')?.click()); + await waitFor(() => expect(document.querySelector('aside[aria-label="Model details"]')?.textContent).toContain('alpha')); + expect(window.location.hash).toBe('#models'); + expect(mock.calls.map((call) => call.url).join('\n')).not.toContain('/ui-api/v1/model-actions'); + }); + + it('says the loaded models are unknown until the first catalog page, then that none is loaded when every entry is unloaded or failed', async () => { + let releaseCatalog: (() => void) | null = null; + const catalogGate = new Promise((resolve) => { releaseCatalog = resolve; }); + const fetchImpl: typeof fetch = async (input) => { + const url = String(input); + if (url.startsWith('/ui-api/v1/bootstrap')) return jsonResponse(makeBootstrap()); + if (url.startsWith('/ui-api/v1/catalog')) { + await catalogGate; + return jsonResponse(unloadedAndFailedCatalog(makeCatalog())); + } + if (url.startsWith('/ui-api/v1/operations')) return jsonResponse(makeOperations()); + if (url.startsWith('/ui-api/v1/events')) return new Response('data: [DONE]\n\n', { status: 200, headers: { 'content-type': 'text/event-stream' } }); + return jsonResponse({ error: { code: 'not_found', message: `Unexpected ${url}`, retryable: false }, request_id: 'req_unexpected' }, 404); + }; + renderApp(fetchImpl); + const region = (): HTMLElement | null => document.querySelector('[data-testid="toolbar-loaded"]'); + await submitSessionKey('good-key'); + // Authenticated, but the catalog snapshot has not arrived: still unknown, not "none". + await waitFor(() => expect(document.querySelector('[data-testid="connection-authenticated-detail"]')?.textContent).toContain('catalog pending')); + expect(document.querySelector('[data-testid="toolbar-logout"]')).not.toBeNull(); + expect(region()?.textContent).toBe('Loaded models unknown'); + await act(async () => { releaseCatalog?.(); await Promise.resolve(); }); + await waitFor(() => expect(document.querySelector('[data-testid="connection-authenticated-detail"]')?.textContent).toContain('catalog 2')); + expect(region()?.textContent).toBe('No model loaded'); + expect(region()?.querySelector('[data-testid="toolbar-loaded-none"]')).not.toBeNull(); + expect(region()?.querySelectorAll('[data-testid="toolbar-loaded-chip"]')).toHaveLength(0); + }); + + it('does not restart observation when a chip or the palette opens the model that is already selected', async () => { + // Every selection change reaches the synchronizer through selectionChanged, which cancels + // observation, refetches and (with the reducer) clears the runtime history. + const selectionChanged = vi.spyOn(WebUiSynchronizer.prototype, 'selectionChanged'); + const mock = createMockFetch('happy', readyCatalog); + renderApp(mock.fetchImpl); + await submitSessionKey('good-key'); + await waitFor(() => expect(document.querySelector('[data-testid="toolbar-loaded-count"]')?.textContent).toBe('1 loaded')); + expect(selectionChanged).not.toHaveBeenCalled(); + act(() => document.querySelector('[data-testid="toolbar-loaded-chip"]')?.click()); + await waitFor(() => expect(document.querySelector('aside[aria-label="Model details"]')?.textContent).toContain('alpha')); + expect(selectionChanged).toHaveBeenCalledTimes(1); + act(() => document.querySelector('[data-testid="nav-settings"]')?.click()); + act(() => document.querySelector('[data-testid="toolbar-loaded-chip"]')?.click()); + expect(window.location.hash).toBe('#models'); + act(() => document.querySelector('[data-testid="nav-activity"]')?.click()); + act(() => document.querySelector('[data-testid="toolbar-command"]')?.click()); + const dialog = document.querySelector('[data-testid="command-dialog"]'); + act(() => dialog?.querySelector('[data-testid="command-model"]')?.click()); + expect(window.location.hash).toBe('#models'); + expect(dialog?.hasAttribute('open')).toBe(false); + expect(selectionChanged).toHaveBeenCalledTimes(1); + }); + + it('keeps the footer to mode, status and version and puts the instance and sequence only in its details', async () => { + const mock = createMockFetch('happy'); + renderApp(mock.fetchImpl); + expect(document.querySelector('[data-testid="connection-footer-details"]')).toBeNull(); + await submitSessionKey('good-key'); + await waitFor(() => expect(document.querySelector('[data-testid="connection-footer-details"]')).not.toBeNull()); + const instance = bootstrapFixture.server.server_instance_id; + const label = document.querySelector('[data-testid="connection-ready"]'); + expect(label?.textContent).toMatch(/^model_free · \w+ · v0\.7\.0$/); + const footer = label?.closest('footer'); + const details = footer?.querySelector('details.connection-details'); + expect(details?.open).toBe(false); + expect(details?.querySelector('summary')?.textContent).toBe('Connection details'); + expect(details?.querySelector('[data-testid="connection-footer-instance"]')?.textContent).toBe(`Server instance: ${instance}`); + expect(details?.querySelector('[data-testid="connection-footer-sequence"]')?.textContent).toMatch(/^Event sequence: \d+$/); + // Outside the disclosure, the footer shows neither identifier. + const outside = Array.from(footer?.childNodes ?? []).filter((node) => node !== details).map((node) => node.textContent).join(' '); + expect(outside).not.toContain(instance); + expect(outside).not.toMatch(/sequence|seq/i); + }); + + it.each(['models', 'activity', 'settings'])('starts a new empty conversation with Cmd/Ctrl+N from %s', async (route) => { + const mock = createMockFetch('happy', readyCatalog); + renderApp(mock.fetchImpl); + await submitSessionKey('good-key'); + await waitFor(() => expect(document.querySelector('[data-testid="toolbar-loaded-count"]')).not.toBeNull()); + act(() => document.querySelector(`[data-testid="nav-${route}"]`)?.click()); + act(() => { (document.activeElement as HTMLElement | null)?.blur(); }); + expect(conversationCount).toBe(0); + let event: KeyboardEvent | undefined; + act(() => { event = new KeyboardEvent('keydown', { key: 'n', ctrlKey: true, bubbles: true, cancelable: true }); document.body.dispatchEvent(event); }); + expect(event?.defaultPrevented).toBe(true); + await waitFor(() => expect(conversationCount).toBe(1)); + expect(window.location.hash).toBe('#chat'); + expect(document.querySelector('[data-testid="chat-title"]')).not.toBeNull(); + act(() => { document.body.dispatchEvent(new KeyboardEvent('keydown', { key: 'n', metaKey: true, bubbles: true, cancelable: true })); }); + await waitFor(() => expect(conversationCount).toBe(2)); + expect(mock.calls.map((call) => call.url).join('\n')).not.toContain('/v1/chat/completions'); + }); + + it('finds a catalog model in the command palette and opens its inspector without any model action', async () => { + const mock = createMockFetch('happy'); + renderApp(mock.fetchImpl); + await submitSessionKey('good-key'); + await waitFor(() => expect(document.querySelector('[data-testid="connection-authenticated-detail"]')?.textContent).toContain('catalog 1')); + act(() => document.querySelector('[data-testid="nav-activity"]')?.click()); + act(() => document.querySelector('[data-testid="toolbar-command"]')?.click()); + const dialog = document.querySelector('[data-testid="command-dialog"]'); + expect(dialog?.hasAttribute('open')).toBe(true); + // Nothing is loaded, so the empty query lists commands only. + expect(dialog?.querySelectorAll('[data-testid="command-model"]')).toHaveLength(0); + const search = dialog?.querySelector('[data-testid="command-search"]'); + act(() => { Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set?.call(search, 'ALP'); search?.dispatchEvent(new Event('input', { bubbles: true })); }); + const hits = dialog?.querySelectorAll('[data-testid="command-model"]'); + expect(Array.from(hits ?? []).map((hit) => hit.textContent)).toEqual(['alpha · Unloaded']); + act(() => { Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set?.call(search, catalogFixture.items[0].identity.id.slice(4, 14)); search?.dispatchEvent(new Event('input', { bubbles: true })); }); + expect(dialog?.querySelectorAll('[data-testid="command-model"]')).toHaveLength(1); + act(() => dialog?.querySelector('[data-testid="command-model"]')?.click()); + await waitFor(() => expect(document.querySelector('aside[aria-label="Model details"]')?.textContent).toContain('alpha')); + expect(window.location.hash).toBe('#models'); + expect(dialog?.hasAttribute('open')).toBe(false); + expect(mock.calls.filter((call) => call.method !== 'GET')).toEqual([]); + expect(mock.calls.map((call) => call.url).join('\n')).not.toContain('/ui-api/v1/model-actions'); + }); }); diff --git a/webui/src/app.tsx b/webui/src/app.tsx index c97d4742d..2b264fb34 100644 --- a/webui/src/app.tsx +++ b/webui/src/app.tsx @@ -1,23 +1,28 @@ import { ServerSettings } from './features/settings/server-settings'; import React, { useEffect, useRef, useState } from 'react'; -import type { WebUiSnapshot } from './api/types'; -import { AppShell, type RouteId } from './design-system/shell'; +import type { ModelId, WebUiSnapshot } from './api/types'; +import { CommandPalette } from './command-palette'; +import { AppShell, globalShortcuts, type RouteId, type ShellLoadedModel } from './design-system/shell'; import { applyAppearance, DEFAULT_APPEARANCE, loadAppearance, saveAppearance, type AppearancePreferences, type ColorSchemePreference, type ContrastPreference, type ThemeFamily } from './design-system/preferences'; import { onSystemColorSchemeChange } from './design-system/theme'; -import { Button, Dialog, ErrorBanner, Field, IconButton, PageHeader, Select } from './design-system/primitives'; +import { Dialog, ErrorBanner, IconButton, PageHeader, Select } from './design-system/primitives'; import { ActivityPage } from './features/activity'; import { ModelsLibrary } from './features/models/screen'; import { DesignGallery } from './gallery'; -import { classifyAuthFailure, connectionFooterLabel, ProductConnectionSurface, selectedModelLabel, type AuthFailure } from './provider-surfaces'; +import { classifyAuthFailure, connectionFooterDetails, connectionFooterLabel, lifecycleLabel, loadedModels, modelSelectionFor, ProductConnectionSurface, type AuthFailure } from './provider-surfaces'; import { useWebUi, useWebUiActions } from './state'; import { t, testId } from './i18n/catalog'; import { Chat } from './features/chat/chat'; -import { replaceConversations } from './features/chat/session'; +import { replaceConversations, requestNewConversation } from './features/chat/session'; const routes: RouteId[] = ['models', 'chat', 'activity', 'settings', 'gallery']; -const paletteRoutes: RouteId[] = ['models', 'chat', 'activity', 'settings']; type Overlay = 'command' | 'help' | null; +// The same condition under which ChatScreen renders the real Chat, which consumes requests. +function chatAvailable(snapshot: WebUiSnapshot): boolean { + return snapshot.auth.status === 'authenticated' && snapshot.connection !== 'schema-mismatch'; +} + function routeFromHash(): RouteId { const raw = window.location.hash.slice(1).replace(/^\//, '') as RouteId; return routes.includes(raw) ? raw : 'models'; @@ -88,16 +93,46 @@ export function App(): React.JSX.Element { logout(); window.location.reload(); }; + // Chip and palette: select the model and open its inspector on Models. A model that + // left the catalog in the meantime opens Models with no inspector. Never loads. Opening + // the model that is already selected dispatches nothing: a selection change cancels + // observation, refetches and clears the runtime history. + const openModel = (id: ModelId): void => { + const target = modelSelectionFor(snapshot, id); + if (target !== snapshot.selectedModelId) actions.selectModel(target); + navigate('models'); + setOverlay(null); + }; + // Cmd/Ctrl+N and the palette. Signed out, Chat shows the connection surface and nothing + // would consume a request, so none is left behind. + const newChat = (): void => { + if (chatAvailable(snapshot)) requestNewConversation(); + navigate('chat'); + setOverlay(null); + }; + const loaded = loadedModels(snapshot); + // Unknown until an authenticated session holds a catalog snapshot (signed out, the window + // before the first page, and the reset after a server restart): the toolbar must not claim + // "No model loaded" about a server it has not read. + const catalogKnown = snapshot.auth.status === 'authenticated' && snapshot.catalogSequence !== null; + const shellLoaded: ShellLoadedModel[] | null = catalogKnown ? loaded.map((entry) => ({ id: entry.identity.id, name: entry.identity.display_name, state: entry.lifecycle.state, stateLabel: lifecycleLabel(appearance.locale, entry.lifecycle.state) })) : null; const body = renderRoute(route, appearance, setAppearance, { snapshot, authFailure, login, logout, retry, recoverSchema }); return ( <> - setOverlay('command')} onHelp={() => setOverlay('help')} selectedModel={selectedModelLabel(appearance.locale, snapshot)} connectionLabel={connectionFooterLabel(appearance.locale, snapshot)} connectionState={snapshot.connection} sessionAction={snapshot.auth.tokenPresent ? : null} inspector={null}> + setOverlay('command')} onHelp={() => setOverlay('help')} onNewChat={newChat} onOpenModel={openModel} loadedModels={shellLoaded} connection={{ label: connectionFooterLabel(appearance.locale, snapshot), state: snapshot.connection, details: connectionFooterDetails(appearance.locale, snapshot) }} sessionAction={snapshot.auth.tokenPresent ? : null} inspector={null}> {body} - setOverlay(null)} onNavigate={(next) => { navigate(next); setOverlay(null); }} /> + setOverlay(null)} onNavigate={(next) => { navigate(next); setOverlay(null); }} onNewChat={newChat} onOpenModel={openModel} /> setOverlay(null)} testId="help-dialog" closeLabel={t(appearance.locale, 'common.close')}>

{t(appearance.locale, 'help.body')}

-
  • ⌘/Ctrl + K {t(appearance.locale, 'command.search')}
  • Esc {t(appearance.locale, 'common.cancel')}
  • [ / ] {t(appearance.locale, 'nav.models')}
+
    + {globalShortcuts.map((shortcut) => ( +
  • + {shortcut.keys.map((key, index) => {index > 0 ? ` ${shortcut.separator} ` : null}{key})} + {t(appearance.locale, shortcut.key)} +
  • + ))} +
); @@ -138,7 +173,7 @@ function ActivityScreen(props: { locale: AppearancePreferences['locale']; contex function SettingsScreen(props: { appearance: AppearancePreferences; setAppearance: (next: AppearancePreferences) => void }): React.JSX.Element { const set = (patch: Partial): void => props.setAppearance({ ...props.appearance, ...patch }); return ( -
set({ colorScheme: value as ColorSchemePreference })} options={[{ value: 'system', label: t(props.appearance.locale, 'settings.color_scheme.system') }, { value: 'light', label: t(props.appearance.locale, 'settings.color_scheme.light') }, { value: 'dark', label: t(props.appearance.locale, 'settings.color_scheme.dark') }]} testId={testId('settings.color_scheme')} /> set({ locale: value as AppearancePreferences['locale'] })} options={[{ value: 'en', label: t(props.appearance.locale, 'settings.locale.en') }, { value: 'ko', label: t(props.appearance.locale, 'settings.locale.ko') }]} testId={testId('settings.locale')} /> set({ glassIntensity: Number(event.currentTarget.value) })} data-testid={testId('settings.glass_intensity')} /> set({ reduceMotion: checked })} testId={testId('settings.reduce_motion')} /> set({ reduceTransparency: checked })} testId={testId('settings.reduce_transparency')} />
+
set({ colorScheme: value as ColorSchemePreference })} options={[{ value: 'system', label: t(props.appearance.locale, 'settings.color_scheme.system') }, { value: 'light', label: t(props.appearance.locale, 'settings.color_scheme.light') }, { value: 'dark', label: t(props.appearance.locale, 'settings.color_scheme.dark') }]} testId={testId('settings.color_scheme')} /> set({ locale: value as AppearancePreferences['locale'] })} options={[{ value: 'en', label: t(props.appearance.locale, 'settings.locale.en') }, { value: 'ko', label: t(props.appearance.locale, 'settings.locale.ko') }]} testId={testId('settings.locale')} /> set({ glassIntensity: Number(event.currentTarget.value) })} data-testid={testId('settings.glass_intensity')} /> set({ reduceMotion: checked })} testId={testId('settings.reduce_motion')} /> set({ reduceTransparency: checked })} testId={testId('settings.reduce_transparency')} />
); } @@ -146,16 +181,4 @@ function Toggle(props: { label: string; checked: boolean; onChange: (checked: bo return ; } -function CommandPalette(props: { open: boolean; locale: AppearancePreferences['locale']; onClose: () => void; onNavigate: (route: RouteId) => void }): React.JSX.Element { - const [query, setQuery] = useState(''); - const searchable = props.locale && window.location.hash.includes('gallery') ? routes : paletteRoutes; - const items = searchable.filter((route) => route.includes(query.toLowerCase())); - return ( - - - {items.length === 0 ?

{t(props.locale, 'command.no_results')}

:
{items.map((route) => )}
} -
- ); -} - export { DEFAULT_APPEARANCE }; diff --git a/webui/src/command-palette.test.tsx b/webui/src/command-palette.test.tsx new file mode 100644 index 000000000..29f3e65d1 --- /dev/null +++ b/webui/src/command-palette.test.tsx @@ -0,0 +1,55 @@ +// Copyright 2026 Lablup Inc. Licensed under Apache-2.0. +import React, { act } from 'react'; +import { createRoot, type Root } from 'react-dom/client'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import type { CatalogEntry } from './api/types'; +import { CommandPalette } from './command-palette'; +import { model } from './features/models/test-fixtures'; + +function entry(id: string, name: string): CatalogEntry { + const base = model(); + return { ...base, identity: { ...base.identity, id, display_name: name } }; +} + +let host: HTMLDivElement; +let root: Root; + +beforeEach(() => { + HTMLDialogElement.prototype.showModal = vi.fn(function showModal(this: HTMLDialogElement) { this.setAttribute('open', ''); }); + HTMLDialogElement.prototype.close = vi.fn(function close(this: HTMLDialogElement) { this.removeAttribute('open'); this.dispatchEvent(new Event('close')); }); + host = document.createElement('div'); + document.body.append(host); + root = createRoot(host); +}); + +afterEach(() => { + act(() => root.unmount()); + host.remove(); + vi.restoreAllMocks(); +}); + +describe('CommandPalette', () => { + it('clears a typed query on close, so the closed dialog holds no stale model matches', () => { + const catalog = [entry('mdl_llama', 'llama-3'), entry('mdl_qwen', 'qwen-2.5')]; + let open = true; + const render = (): void => act(() => root.render( + {}} onNavigate={() => {}} onNewChat={() => {}} onOpenModel={() => {}} />, + )); + render(); + const search = host.querySelector('[data-testid="command-search"]'); + if (!search) throw new Error('Missing search field'); + act(() => { + Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set?.call(search, 'llama'); + search.dispatchEvent(new Event('input', { bubbles: true })); + }); + expect(host.querySelectorAll('[data-testid="command-model"]')).toHaveLength(1); + open = false; + render(); + expect(search.value).toBe(''); + expect(host.querySelectorAll('[data-testid="command-model"]')).toHaveLength(0); + open = true; + render(); + expect(search.value).toBe(''); + expect(host.querySelectorAll('[data-testid="command-model"]')).toHaveLength(0); + }); +}); diff --git a/webui/src/command-palette.tsx b/webui/src/command-palette.tsx new file mode 100644 index 000000000..8b8d8a257 --- /dev/null +++ b/webui/src/command-palette.tsx @@ -0,0 +1,88 @@ +// Copyright 2025-2026 Lablup Inc. Licensed under the Apache License, Version 2.0. +import React, { useId, useState } from 'react'; +import type { CatalogEntry, ModelId } from './api/types'; +import { Button, Dialog, Field } from './design-system/primitives'; +import type { RouteId } from './design-system/shell'; +import type { Locale, StringKey } from './i18n/catalog'; +import { t, testId } from './i18n/catalog'; +import { compareByLoadedThenName, lifecycleLabel } from './provider-surfaces'; + +/** Model hits past this many are dropped; the palette is a jump list, not a library. */ +export const PALETTE_MODEL_LIMIT = 20; + +// Gallery is not listed: it stays a direct, hash-only `#gallery` route. +type PaletteCommand = { readonly id: Exclude | 'new-chat'; readonly key: StringKey; readonly testId: string }; +const COMMANDS: ReadonlyArray = [ + { id: 'models', key: 'nav.models', testId: 'command-route-models' }, + { id: 'chat', key: 'nav.chat', testId: 'command-route-chat' }, + { id: 'activity', key: 'nav.activity', testId: 'command-route-activity' }, + { id: 'settings', key: 'nav.settings', testId: 'command-route-settings' }, + { id: 'new-chat', key: 'chat.new_conversation', testId: 'command-new-chat' }, +]; + +/** Catalog entries whose display name or id contains `query` (case-insensitive), loaded first, then by name. */ +export function paletteModelMatches(catalog: ReadonlyArray, query: string, limit = PALETTE_MODEL_LIMIT): CatalogEntry[] { + const needle = query.trim().toLowerCase(); + if (needle === '') return []; + return catalog + .filter((entry) => entry.identity.display_name.toLowerCase().includes(needle) || entry.identity.id.toLowerCase().includes(needle)) + .sort(compareByLoadedThenName) + .slice(0, Math.max(0, limit)); +} + +export interface CommandPaletteProps { + readonly open: boolean; + readonly locale: Locale; + readonly catalog: ReadonlyArray; + /** The toolbar's loaded models, listed while the query is empty. */ + readonly loaded: ReadonlyArray; + readonly onClose: () => void; + readonly onNavigate: (route: Exclude) => void; + readonly onNewChat: () => void; + /** Selects the model and opens its inspector on Models; never loads it. */ + readonly onOpenModel: (id: ModelId) => void; +} + +export function CommandPalette(props: CommandPaletteProps): React.JSX.Element { + const [query, setQuery] = useState(''); + const [wasOpen, setWasOpen] = useState(props.open); + const commandsId = useId(); + const modelsId = useId(); + // Every opening starts from an empty query, which lists the loaded models. Closing clears it + // too, so a query typed before closing does not keep matching in the background and holding + // up to PALETTE_MODEL_LIMIT model buttons in a dialog nothing can see. + if (props.open !== wasOpen) { + setWasOpen(props.open); + setQuery(''); + } + const needle = query.trim().toLowerCase(); + const commands = COMMANDS.filter((command) => needle === '' || command.id.includes(needle) || t(props.locale, command.key).toLowerCase().includes(needle)); + const models = needle === '' ? props.loaded : paletteModelMatches(props.catalog, needle); + const run = (command: PaletteCommand): void => { + if (command.id === 'new-chat') props.onNewChat(); + else props.onNavigate(command.id); + }; + return ( + + + {commands.length === 0 && models.length === 0 ?

{t(props.locale, 'command.no_results')}

: null} + {commands.length > 0 ? ( +
+

{t(props.locale, 'command.section.commands')}

+
{commands.map((command) => )}
+
+ ) : null} + {models.length > 0 ? ( +
+

{t(props.locale, 'command.section.models')}

+
{models.map((entry) => ( + + ))}
+
+ ) : null} +
+ ); +} + diff --git a/webui/src/design-system/common-components.css b/webui/src/design-system/common-components.css index 1dd4c5939..3d928ce31 100644 --- a/webui/src/design-system/common-components.css +++ b/webui/src/design-system/common-components.css @@ -45,8 +45,9 @@ .drawer.ds-drawer { top: 12px; bottom: 12px; left: 12px; right: auto; width: min(320px, calc(100vw - 32px)) !important; max-width: calc(100vw - 32px) !important; transform: translateX(calc(-100% - 12px)); color: var(--color-text); background: var(--color-bg-elevated); border: 1px solid var(--color-separator); border-radius: var(--radius-xl); box-shadow: 0 30px 120px rgba(0, 0, 0, 0.32); overflow: hidden; } .drawer.ds-drawer.drawer--open { transform: translateX(0); } .ds-drawer .drawer__header { padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--color-separator); } -.ds-drawer .drawer__title { color: var(--color-text); font-size: 1.1rem; } -.ds-drawer .drawer__close-btn { color: var(--color-text); } +/* The title shrinks and wraps before it can push the close button out of a 163 px drawer (a 195 CSS px viewport) in a wide font. */ +.ds-drawer .drawer__title { min-width: 0; color: var(--color-text); font-size: 1.1rem; overflow-wrap: anywhere; } +.ds-drawer .drawer__close-btn { flex: none; color: var(--color-text); } .ds-drawer .drawer__close-btn:focus-visible { outline: none; box-shadow: var(--focus-ring); } .ds-drawer .drawer__content { padding: var(--space-5); } /* Card: BaseCard keeps the previous block flow; its :focus-within rule removes the outline, so restore a visible keyboard ring. */ @@ -59,6 +60,17 @@ .ds-page-header .page-header { margin: 0; } .ds-page-header .page-header__title { margin: 0; color: var(--color-text); font-size: clamp(1.45rem, 2.6vw, 1.75rem); font-weight: 700; line-height: 1.12; letter-spacing: -0.025em; overflow-wrap: anywhere; } .ds-page-header .page-header__description { margin: 1em 0 0; color: var(--color-muted); font-size: 1rem; line-height: 1.55; overflow-wrap: anywhere; } +/* Route actions sit in the header's action slot; the package keeps them at their max-content width, so cap each at the column and let its label wrap. */ +.ds-page-header .page-header__actions { max-width: 100%; } +.ds-page-header .page-header__actions > * { max-width: 100%; } +/* The header error is the route's stale or action alert: drawn like the product's error banner, wrapping its Retry below the text when narrow. */ +.ds-page-header .page-header__error { flex-wrap: wrap; margin-top: var(--space-4); padding: var(--space-3) var(--space-4); color: var(--color-error); background: var(--color-error-bg); border: 1px solid var(--color-separator); border-radius: var(--radius-lg); font-size: 1rem; } +.ds-page-header .page-header__error-body { flex: 1 1 12rem; min-width: 0; } +.ds-page-header .page-header__error-text { font-weight: 700; overflow-wrap: anywhere; } +.ds-page-header .page-header__error-detail { color: var(--color-text); font-size: 0.9rem; overflow-wrap: anywhere; } +.ds-page-header .page-header__error-actions { flex-shrink: 1; min-width: 0; max-width: 100%; padding-left: 0; } +.ds-page-header .button.page-header__error-retry { min-height: 32px; max-width: 100%; padding: 7px 14px; border: 1px solid var(--color-separator); border-radius: 999px; color: var(--color-text); background: var(--material-control-bg); font: inherit; font-weight: 650; line-height: normal; white-space: normal; overflow-wrap: anywhere; } +.ds-page-header .button.page-header__error-retry:focus-visible { outline: none; box-shadow: var(--focus-ring); } /* StatCard: labels and values wrap instead of truncating, keep their authored casing, and the non-interactive tile does not lift on hover. */ .ds-stat-card .stat-card__label, .ds-stat-card .stat-card__value { min-width: 0; overflow: visible; text-overflow: clip; white-space: normal; overflow-wrap: anywhere; } .ds-stat-card .stat-card__label { color: var(--color-text); font-size: 0.9rem; letter-spacing: normal; text-transform: none; } @@ -89,7 +101,7 @@ .ds-row-activation :where(tbody > tr:has(.ds-row-primary:not(:disabled, [aria-disabled="true"])):hover) { background-color: var(--token-colorFillQuaternary); } .ds-row-activation tbody > tr:has(.ds-row-primary:focus-visible) { outline: 2px solid var(--color-focus); outline-offset: -2px; } @media (max-width: 560px), (pointer: coarse) { .app-toolbar .button.ds-icon-button.button--inline { min-width: 44px; min-height: 44px; } } -:root[data-high-contrast="on"] .button.ds-button, :root[data-high-contrast="on"] .button.ds-icon-button { border-width: 2px; } -@media (prefers-contrast: more) { :root:not([data-high-contrast="off"]) .button.ds-button, :root:not([data-high-contrast="off"]) .button.ds-icon-button { border-width: 2px; } } +:root[data-high-contrast="on"] .button.ds-button, :root[data-high-contrast="on"] .button.ds-icon-button, :root[data-high-contrast="on"] .ds-page-header .button.page-header__error-retry, :root[data-high-contrast="on"] .ds-page-header .page-header__error { border-width: 2px; } +@media (prefers-contrast: more) { :root:not([data-high-contrast="off"]) .button.ds-button, :root:not([data-high-contrast="off"]) .button.ds-icon-button, :root:not([data-high-contrast="off"]) .ds-page-header .button.page-header__error-retry, :root:not([data-high-contrast="off"]) .ds-page-header .page-header__error { border-width: 2px; } } .gallery-progress-samples { min-width: 0; display: grid; align-content: start; gap: var(--space-4); } diff --git a/webui/src/design-system/common-layout.tsx b/webui/src/design-system/common-layout.tsx index 2b4b4736b..f802ea1a0 100644 --- a/webui/src/design-system/common-layout.tsx +++ b/webui/src/design-system/common-layout.tsx @@ -18,21 +18,45 @@ export function PageLayout(props: { children: React.ReactNode; className?: strin return {props.children}; } -// PageHeader forwards only className, and its h1 and description take no other -// attributes. The bridge restores the product test ids and, when asked, makes the h1 -// the route's dialog focus fallback: a named page heading is a better landing target -// than an unnamed layout container. It has no eyebrow slot (#1914 removes those keys). -export function PageHeader(props: { title: string; description?: string; titleTestId?: string; descriptionTestId?: string; focusFallback?: boolean; className?: string }): React.JSX.Element { +// A Retry button always carries a localized label: the package default is English. +type PageHeaderRetry = { onRetry?: undefined; retryLabel?: undefined } | { onRetry: () => void; retryLabel: string }; + +export type PageHeaderProps = { + title: string; + description?: string; + titleTestId?: string; + descriptionTestId?: string; + className?: string; + /** Route actions, rendered in the header's action slot beside the title. */ + actions?: React.ReactNode; + /** The route's stale or action error, shown in the header's alert block. */ + error?: string | null; + errorDetail?: string | null; + /** Test id for the `.page-header__error` alert block. */ + errorTestId?: string; +} & PageHeaderRetry; + +// Shell contract: every route renders exactly one PageHeader as the first child of the +// shell's PageLayout, and its h1 is always the route's dialog focus fallback +// (tabIndex=-1 plus data-dialog-focus-fallback), so restoreModalFocus always finds one +// named landing target when a dialog closes after its opener is gone. PageHeader +// forwards only className, and its h1, description and error block take no other +// attributes, so the ref bridge applies the fallback and the product test ids. It runs +// on every render because the error block mounts and unmounts with `error`. There is no +// eyebrow slot and no dismiss control (the package's dismiss label is English). +export function PageHeader(props: PageHeaderProps): React.JSX.Element { return
{ const heading = element?.querySelector('.page-header__title'); const description = element?.querySelector('.page-header__description'); - if (heading && props.titleTestId) heading.dataset.testid = props.titleTestId; - if (description && props.descriptionTestId) description.dataset.testid = props.descriptionTestId; - if (heading && props.focusFallback) { + const error = element?.querySelector('.page-header__error'); + if (heading) { heading.tabIndex = -1; heading.setAttribute('data-dialog-focus-fallback', ''); + if (props.titleTestId) heading.dataset.testid = props.titleTestId; } - }}>
; + if (description && props.descriptionTestId) description.dataset.testid = props.descriptionTestId; + if (error && props.errorTestId) error.dataset.testid = props.errorTestId; + }}>; } // Covers the package transition (motion-standard) with margin for the last change. diff --git a/webui/src/design-system/components.css b/webui/src/design-system/components.css index b9ecd0568..3ae2022f3 100644 --- a/webui/src/design-system/components.css +++ b/webui/src/design-system/components.css @@ -61,7 +61,8 @@ .ds-table .truncate { max-width: 100%; } .ds-list { display: grid; gap: var(--space-2); list-style: none; padding: var(--space-4); margin: 0; } .ds-login { display: grid; gap: var(--space-3); padding: var(--space-4); } -.ds-login h2, .ds-login p { margin: 0; } +/* A long word (the "Authentication" heading in a wide font such as DejaVu Sans) must not set the form's min-content above a 195 CSS px viewport. */ +.ds-login h2, .ds-login p { margin: 0; overflow-wrap: anywhere; } @keyframes spin { to { transform: rotate(360deg); } } @keyframes pulse { to { opacity: 0.45; } } @keyframes slide { from { transform: translateX(-60%); } to { transform: translateX(120%); } } diff --git a/webui/src/design-system/keyboard.test.ts b/webui/src/design-system/keyboard.test.ts new file mode 100644 index 000000000..c1909e5df --- /dev/null +++ b/webui/src/design-system/keyboard.test.ts @@ -0,0 +1,70 @@ +// Copyright 2026 Lablup Inc. Licensed under Apache-2.0. +import { afterEach, describe, expect, it, vi } from 'vitest'; +import { isApplePlatform, isPrimaryModifier } from './keyboard'; + +function stubPlatform(platform: string): void { + vi.spyOn(window.navigator, 'platform', 'get').mockReturnValue(platform); +} + +afterEach(() => { + vi.restoreAllMocks(); +}); + +describe('isApplePlatform', () => { + it('is false in this jsdom test environment, which reports no Apple platform hint', () => { + expect(isApplePlatform()).toBe(false); + }); + + it('reads navigator.platform, case-insensitively, for macOS and iOS device strings', () => { + stubPlatform('MacIntel'); + expect(isApplePlatform()).toBe(true); + stubPlatform('iPhone'); + expect(isApplePlatform()).toBe(true); + stubPlatform('iPad'); + expect(isApplePlatform()).toBe(true); + stubPlatform('iPod touch'); + expect(isApplePlatform()).toBe(true); + stubPlatform('Win32'); + expect(isApplePlatform()).toBe(false); + stubPlatform('Linux x86_64'); + expect(isApplePlatform()).toBe(false); + }); + + it('prefers userAgentData.platform over the legacy properties when present', () => { + const withUaData = window.navigator as Navigator & { userAgentData?: { platform: string } }; + const original = withUaData.userAgentData; + stubPlatform('Win32'); + Object.defineProperty(withUaData, 'userAgentData', { value: { platform: 'macOS' }, configurable: true }); + expect(isApplePlatform()).toBe(true); + if (original === undefined) { + Object.defineProperty(withUaData, 'userAgentData', { value: undefined, configurable: true }); + } else { + Object.defineProperty(withUaData, 'userAgentData', { value: original, configurable: true }); + } + }); + + it('returns false when navigator is unavailable', () => { + const original = globalThis.navigator; + // @ts-expect-error deleting a required global to exercise the SSR / missing-navigator guard + delete globalThis.navigator; + try { + expect(isApplePlatform()).toBe(false); + } finally { + globalThis.navigator = original; + } + }); +}); + +describe('isPrimaryModifier', () => { + it('is the meta key on Apple platforms', () => { + stubPlatform('MacIntel'); + expect(isPrimaryModifier({ metaKey: true, ctrlKey: false })).toBe(true); + expect(isPrimaryModifier({ metaKey: false, ctrlKey: true })).toBe(false); + }); + + it('is the ctrl key on non-Apple platforms', () => { + stubPlatform('Win32'); + expect(isPrimaryModifier({ metaKey: true, ctrlKey: false })).toBe(false); + expect(isPrimaryModifier({ metaKey: false, ctrlKey: true })).toBe(true); + }); +}); diff --git a/webui/src/design-system/keyboard.ts b/webui/src/design-system/keyboard.ts new file mode 100644 index 000000000..86e9d9ac4 --- /dev/null +++ b/webui/src/design-system/keyboard.ts @@ -0,0 +1,26 @@ +// Copyright 2026 Lablup Inc. Licensed under Apache-2.0. + +/** The navigator surface this module reads; `userAgentData` is not yet in lib.dom.d.ts. */ +interface NavigatorPlatformHint { + readonly userAgentData?: { readonly platform?: string }; + readonly platform?: string; + readonly userAgent?: string; +} + +/** + * True on macOS, iOS, iPadOS and iPodOS, false everywhere else, including when `navigator` + * does not exist. A shortcut handler uses this to pick the platform's own modifier instead of + * accepting both Cmd and Ctrl everywhere, which would otherwise steal a native text-editing + * binding such as Ctrl+N ("move down a line") inside a macOS textarea. + */ +export function isApplePlatform(): boolean { + if (typeof navigator === 'undefined') return false; + const hint = navigator as NavigatorPlatformHint; + const platform = hint.userAgentData?.platform ?? hint.platform ?? hint.userAgent ?? ''; + return /mac|iphone|ipad|ipod/i.test(platform); +} + +/** The platform's primary shortcut modifier: Cmd on Apple platforms, Ctrl elsewhere. */ +export function isPrimaryModifier(event: { readonly metaKey: boolean; readonly ctrlKey: boolean }): boolean { + return isApplePlatform() ? event.metaKey : event.ctrlKey; +} diff --git a/webui/src/design-system/shell.tsx b/webui/src/design-system/shell.tsx index eec266e19..3a3e0f902 100644 --- a/webui/src/design-system/shell.tsx +++ b/webui/src/design-system/shell.tsx @@ -1,8 +1,8 @@ import React, { useEffect, useRef, useState } from 'react'; import { Icon } from './icons'; -import { Drawer, IconButton, PageLayout } from './primitives'; +import { Button, Drawer, IconButton, PageLayout, StatusBadge } from './primitives'; import type { StringKey, Locale } from '../i18n/catalog'; -import type { ConnectionPhase } from '../api/types'; +import type { ConnectionPhase, ModelId, ModelLifecycleState } from '../api/types'; import { t, testId } from '../i18n/catalog'; export type RouteId = 'models' | 'chat' | 'activity' | 'settings' | 'gallery'; @@ -16,15 +16,80 @@ export const navItems: NavItem[] = [ { id: 'settings', key: 'nav.settings', icon: 'settings' }, ]; -export function AppShell(props: { locale: Locale; route: RouteId; onRouteChange: (route: RouteId) => void; onCommand: () => void; onHelp: () => void; children: React.ReactNode; inspector?: React.ReactNode; selectedModel: string; connectionLabel: string; connectionState: ConnectionPhase; sessionAction?: React.ReactNode }): React.JSX.Element { +/** A model the server holds, as the toolbar shows it. App maps catalog entries to this, so the shell imports neither the provider nor the catalog. */ +export interface ShellLoadedModel { + readonly id: ModelId; + readonly name: string; + readonly state: ModelLifecycleState; + /** The localized lifecycle label for `state`. */ + readonly stateLabel: string; +} + +/** The sidebar footer: the connection summary, plus internal identifiers kept in a collapsed disclosure (null before bootstrap). */ +export interface ShellConnection { + readonly label: string; + readonly state: ConnectionPhase; + readonly details: { readonly instance: string; readonly sequence: string } | null; +} + +/** Chips shown before the rest collapse into a "+n" chip that opens the command palette. */ +export const TOOLBAR_CHIP_LIMIT = 3; + +/** One keyboard shortcut as the help dialog lists it. `keys` are symbols, not translated. */ +export interface GlobalShortcut { + readonly id: 'command' | 'new-chat' | 'send' | 'escape' | 'navigate' | 'help'; + readonly keys: ReadonlyArray; + readonly separator: '+' | '/'; + readonly key: StringKey; +} + +/** + * The single source for the help dialog. Cmd/Ctrl+K, Cmd/Ctrl+N and ? are handled by + * AppShell below; Cmd/Ctrl+Enter (and Cmd/Ctrl+N again) by the chat composer; Esc by + * Dialog and Drawer; [ and ] by the sidebar. Add an entry here when a handler changes. + */ +export const globalShortcuts: ReadonlyArray = [ + { id: 'command', keys: ['⌘/Ctrl', 'K'], separator: '+', key: 'help.shortcut.command' }, + { id: 'new-chat', keys: ['⌘/Ctrl', 'N'], separator: '+', key: 'help.shortcut.new_chat' }, + { id: 'send', keys: ['⌘/Ctrl', 'Enter'], separator: '+', key: 'help.shortcut.send' }, + { id: 'escape', keys: ['Esc'], separator: '+', key: 'help.shortcut.escape' }, + { id: 'navigate', keys: ['[', ']'], separator: '/', key: 'help.shortcut.navigate' }, + { id: 'help', keys: ['?'], separator: '+', key: 'help.shortcut.help' }, +]; + +export interface AppShellProps { + readonly locale: Locale; + readonly route: RouteId; + readonly onRouteChange: (route: RouteId) => void; + readonly onCommand: () => void; + readonly onHelp: () => void; + /** Cmd/Ctrl+N outside edit fields and dialogs. */ + readonly onNewChat: () => void; + /** A loaded-model chip was activated; App selects it and opens Models. */ + readonly onOpenModel: (id: ModelId) => void; + readonly children: React.ReactNode; + readonly inspector?: React.ReactNode; + /** + * The server's loaded models in display order (never the browser's selection). `null` means + * the shell does not know them (signed out, or no catalog snapshot yet), and the toolbar says + * so instead of claiming that nothing is loaded; an empty array means none is loaded. + */ + readonly loadedModels: ReadonlyArray | null; + readonly connection: ShellConnection; + readonly sessionAction?: React.ReactNode; +} + +export function AppShell(props: AppShellProps): React.JSX.Element { const sidebarRef = useRef(null); const onCommandRef = useRef(props.onCommand); const onHelpRef = useRef(props.onHelp); + const onNewChatRef = useRef(props.onNewChat); const [navOpen, setNavOpen] = useState(false); useEffect(() => { onCommandRef.current = props.onCommand; onHelpRef.current = props.onHelp; - }, [props.onCommand, props.onHelp]); + onNewChatRef.current = props.onNewChat; + }, [props.onCommand, props.onHelp, props.onNewChat]); useEffect(() => { const handleKeyDown = (event: KeyboardEvent): void => { const target = event.target; @@ -32,11 +97,21 @@ export function AppShell(props: { locale: Locale; route: RouteId; onRouteChange: // The navigation Drawer is a modal aside, not a native dialog, so match both. const inModal = target instanceof HTMLElement && Boolean(target.closest('dialog[open], [role="dialog"][aria-modal="true"]')); if (event.isComposing || event.altKey || editable || inModal) return; - if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === 'k') { + const command = event.metaKey || event.ctrlKey; + if (command && event.key.toLowerCase() === 'k') { event.preventDefault(); setNavOpen(false); onCommandRef.current(); } + // Browsers reserve Cmd/Ctrl+N for a new window and usually never deliver it to the + // page; preventDefault still stops it wherever it does arrive. A held key still repeats + // this keydown, so preventDefault runs every time but a new conversation is opened once. + if (command && !event.shiftKey && event.key.toLowerCase() === 'n') { + event.preventDefault(); + if (event.repeat) return; + setNavOpen(false); + onNewChatRef.current(); + } if (event.key === '?' || (event.key === '/' && event.shiftKey)) { event.preventDefault(); setNavOpen(false); @@ -83,9 +158,9 @@ export function AppShell(props: { locale: Locale; route: RouteId; onRouteChange: }; return (
- + setNavOpen(false)} closeLabel={t(props.locale, 'common.close')} testId="mobile-nav-sheet"> - + {/* The shared Drawer traps Tab only from inside its panel. Like the native modal sheet before it, keep the page behind the open drawer inert so focus cannot reach it. */} @@ -93,10 +168,10 @@ export function AppShell(props: { locale: Locale; route: RouteId; onRouteChange:
setNavOpen(true)} data-testid={testId('toolbar.menu')} />
-

{t(props.locale, 'app.title')}

- {t(props.locale, 'app.subtitle')} +

{t(props.locale, 'app.title')}

+ {t(props.locale, 'app.subtitle')}
-
{props.selectedModel}
+
{props.sessionAction} @@ -112,7 +187,42 @@ export function AppShell(props: { locale: Locale; route: RouteId; onRouteChange: ); } -const Sidebar = React.forwardRef void; onKeyDown: (event: React.KeyboardEvent) => void; className: string; connectionLabel: string; connectionState: ConnectionPhase }>((props, ref) => ( +// The server's loaded models: a count and up to TOOLBAR_CHIP_LIMIT chips, then a "+n" +// chip that opens the command palette, whose empty query lists every loaded model. A chip +// only selects and inspects; it never loads or unloads. Its accessible name is its +// visible text (name and lifecycle), so it takes no aria-label (WCAG 2.5.3). Unknown +// (null) and none loaded (empty) are different claims, so each has its own text. +function LoadedModels(props: { locale: Locale; models: ReadonlyArray | null; onOpenModel: (id: ModelId) => void; onMore: () => void }): React.JSX.Element { + const models = props.models ?? []; + const shown = models.slice(0, TOOLBAR_CHIP_LIMIT); + const hidden = models.length - shown.length; + const status = props.models === null ? 'toolbar.loaded.unknown' : models.length === 0 ? 'toolbar.loaded.none' : null; + return ( +
+ {status !== null ? {t(props.locale, status)} : <> + {t(props.locale, 'toolbar.loaded.count', { count: String(models.length) })} + {shown.map((model) => ( + + ))} + {hidden > 0 ? : null} + } +
+ ); +} + +// Below 960 px the chip row scrolls sideways. Chromium's own focus scrolling leaves an element +// that is already partly visible where it is, so a keyboard-focused chip half past the row's +// edge stays clipped; scroll it fully into view. Pointer focus is left alone, so a chip never +// moves between mousedown and mouseup. +function revealFocusedChip(event: React.FocusEvent): void { + const target = event.target; + if (target instanceof HTMLElement && typeof target.scrollIntoView === 'function' && target.matches(':focus-visible')) target.scrollIntoView({ block: 'nearest', inline: 'nearest' }); +} + +const Sidebar = React.forwardRef void; onKeyDown: (event: React.KeyboardEvent) => void; className: string; connection: ShellConnection }>((props, ref) => ( )); diff --git a/webui/src/design-system/ui-common-drawer.test.tsx b/webui/src/design-system/ui-common-drawer.test.tsx index 84a31c79a..e351a5bdd 100644 --- a/webui/src/design-system/ui-common-drawer.test.tsx +++ b/webui/src/design-system/ui-common-drawer.test.tsx @@ -37,7 +37,7 @@ const expectSharedDrawer = (): void => { expect(panel().matches('aside.drawer[ro const isPanelOpen = (): boolean => panel().classList.contains('drawer--open'); function Shell({ connectionLabel }: { connectionLabel: string }): React.JSX.Element { - return undefined} onCommand={() => undefined} onHelp={() => undefined} selectedModel="none" connectionLabel={connectionLabel} connectionState="streaming">

Route content

; + return undefined} onCommand={() => undefined} onHelp={() => undefined} onNewChat={() => undefined} onOpenModel={() => undefined} loadedModels={[]} connection={{ label: connectionLabel, state: 'streaming', details: null }}>

Route content

; } describe('navigation drawer adoption', () => { diff --git a/webui/src/design-system/ui-common-page-header.test.tsx b/webui/src/design-system/ui-common-page-header.test.tsx index 69a97f495..6e9bb1193 100644 --- a/webui/src/design-system/ui-common-page-header.test.tsx +++ b/webui/src/design-system/ui-common-page-header.test.tsx @@ -8,6 +8,7 @@ import { t } from '../i18n/catalog'; import { ProductConnectionSurface } from '../provider-surfaces'; import { WebUiProvider } from '../state'; import { initialSnapshot } from '../state/reducer'; +import { PageHeader } from './primitives'; let host: HTMLDivElement; let root: Root; @@ -82,9 +83,27 @@ describe('PageHeader adoption', () => { it.each([['offline', 'connection-authenticated-body'], ['schema-mismatch', undefined]] as const)('keeps the %s connection surface title', (connection, descriptionId) => { const snapshot: WebUiSnapshot = { ...initialSnapshot(), auth: { status: 'authenticated', tokenPresent: true }, connection }; - // eyebrow goes through a spread so this compiles both before and after the prop is dropped. - act(() => root.render( undefined} onLogout={() => undefined} onRetry={() => undefined} onRecoverSchema={() => undefined} {...{ eyebrow: t('en', 'routes.activity.eyebrow') }} />)); + act(() => root.render( undefined} onLogout={() => undefined} onRetry={() => undefined} onRecoverSchema={() => undefined} />)); expectPageTitle('activity-title', t('en', 'activity.title'), descriptionId, descriptionId ? t('en', 'connection.authenticated.body') : undefined); expectSharedHeader('activity-title', descriptionId); }); + + it('always makes the title the focus fallback and re-applies the error test id each time the error mounts', () => { + const retry = vi.fn(); + const header = (error: string | null): React.JSX.Element => Act} error={error} errorDetail="detail" errorTestId="route-error" onRetry={retry} retryLabel="Refresh route" />; + act(() => root.render(header(null))); + expect(byTestId('route-title').hasAttribute('data-dialog-focus-fallback')).toBe(true); + expect(byTestId('route-title').tabIndex).toBe(-1); + expect(document.querySelector('.page-header__actions')?.textContent).toBe('Act'); + expect(document.querySelector('.page-header__error')).toBeNull(); + for (const message of ['First failure', 'Second failure']) { + act(() => root.render(header(message))); + expect(byTestId('route-error').matches('.page-header__error[role="alert"]')).toBe(true); + expect(byTestId('route-error').textContent).toContain(message); + act(() => byTestId('route-error').querySelector('button')?.click()); + act(() => root.render(header(null))); + expect(document.querySelector('[data-testid="route-error"]')).toBeNull(); + } + expect(retry).toHaveBeenCalledTimes(2); + }); }); diff --git a/webui/src/features/activity/activity.css b/webui/src/features/activity/activity.css index bfd69dfdd..92f0ca746 100644 --- a/webui/src/features/activity/activity.css +++ b/webui/src/features/activity/activity.css @@ -1,7 +1,7 @@ .activity-operations { list-style: none; margin: 0; padding: 0; } .activity-operation { padding: var(--space-4); border-bottom: 1px solid var(--color-separator); overflow-wrap: anywhere; } .activity-operation header { display: flex; gap: var(--space-3); align-items: center; justify-content: space-between; flex-wrap: wrap; } -.activity-toolbar { display: flex; gap: var(--space-3); flex-wrap: wrap; } +.activity-updated { margin: 0; color: var(--color-muted); overflow-wrap: anywhere; } .activity-metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); gap: var(--space-4); } .activity-metric { margin: 0; padding: var(--space-4); border-bottom: 1px solid var(--color-separator); overflow-wrap: anywhere; } .activity-metric dt { font-weight: 600; } diff --git a/webui/src/features/activity/index.tsx b/webui/src/features/activity/index.tsx index 687c9c6b3..5a1b2cf74 100644 --- a/webui/src/features/activity/index.tsx +++ b/webui/src/features/activity/index.tsx @@ -1,6 +1,6 @@ // Copyright 2026 Lablup Inc. Licensed under the Apache License, Version 2.0. import React, { lazy, Suspense, useState } from 'react'; -import { Button, EmptyState, ErrorBanner, Select } from '../../design-system/primitives'; +import { Button, EmptyState, PageHeader, Select } from '../../design-system/primitives'; import { t, testId, type Locale } from '../../i18n/catalog'; import { useWebUi, useWebUiActions } from '../../state'; import { downloadDiagnostics } from './format'; @@ -19,10 +19,18 @@ export function ActivityPage({ locale }: { locale: Locale }): React.JSX.Element const runtimeStale = stale || latestRuntimeAt === null || (snapshot.lastUpdatedAt !== null && snapshot.lastUpdatedAt - latestRuntimeAt > 4_000); const runtime = snapshot.selectedModelId === null ? undefined : snapshot.runtimes.get(snapshot.selectedModelId); return
-

{t(locale, 'activity.title')}

{t(locale, 'activity.intro')}

{t(locale, 'activity.updated')}: {snapshot.lastSuccessfulAt === null ? t(locale, 'activity.pending') : }

+ } + error={stale ? t(locale, 'activity.stale') : null} + errorTestId={testId('activity.stale')} + onRetry={() => { void actions.refresh(); }} + retryLabel={t(locale, 'activity.refresh')} + /> +

{t(locale, 'activity.updated')}: {snapshot.lastSuccessfulAt === null ? t(locale, 'activity.pending') : }

{ setCurrentId(id); setDraft(''); setImages([]); }} options={[{ value: '', label: t(locale, 'chat.conversation.choose') }, ...conversations.map((item) => ({ value: item.id, label: item.title }))]} /> { setCurrentId(id); setDraft(''); setImages([]); }} options={[{ value: '', label: t(locale, 'chat.conversation.choose') }, ...conversations.map((item) => ({ value: item.id, label: item.title }))]} />