From f75f9844812be078e2cb54c289b4a210258fb05e Mon Sep 17 00:00:00 2001 From: Jeongkyu Shin Date: Sat, 19 Sep 2026 13:47:15 +0900 Subject: [PATCH 1/6] feat(webui): adopt the ui-common theme system and add a glass theme The WebUI wrote the raw preference into data-theme, so the default `system` matched neither the light nor the dark selector, and the --token-* contract was configured by hand on :root, where no theme file could take effect. data-theme now always holds a - id (mlxcel-light, mlxcel-dark, glass-light, glass-dark) resolved by theme.ts, with the stored family and scheme kept apart and the pre-change flat `theme` field migrated. main.tsx imports one theme entry after ui-common base.css; the baseline values moved into mlxcel theme blocks unchanged, and a glass family reads the existing intensity, transparency, contrast and motion switches. A classic script in index.html applies the id before first paint, since the CSP forbids inline scripts. check-theme-selectors fails on any theme selector no shipped id matches and runs in the webui-bundle job. The glass tokens derive from lablup/backend.ai-go, recorded in NOTICE. The .material-glass rule now writes -webkit-backdrop-filter first: the minifier kept only the prefixed form, so the chrome blur never rendered in Chromium or Firefox. models.css read two tokens no theme defines. Validated with typecheck, lint, the new gate, unit (32 node, 401 Vitest), the Chromium browser suite (59), the three-engine smoke, and build_bundle.py --verify. Refs #1903 --- .github/workflows/ci.yml | 5 + Makefile | 3 +- NOTICE | 16 + README.md | 1 + docs/webui/bundling.ko.md | 2 +- docs/webui/bundling.md | 2 +- docs/webui/design-system.md | 29 +- docs/webui/ui-common.md | 2 +- docs/webui/ux-contract.md | 2 +- scripts/webui/build_bundle.py | 11 + ...DYgjCuFT.js => code-highlight-B7JRfpaI.js} | 2 +- ...istory-BhdDGTqa.js => history-DIlBLmUk.js} | 2 +- .../{index-CW0N8nOa.js => index-C5rxJd1U.js} | 12 +- src/webui/assets/assets/index-D2RzuY00.css | 1 - src/webui/assets/assets/index-jceAf1an.css | 1 + src/webui/assets/index.html | 5 +- src/webui/assets/mlxcel-webui-manifest.json | 46 +-- src/webui/assets/theme-bootstrap.js | 44 +++ tests/fixtures/webui/strings.json | 30 +- webui/index.html | 1 + webui/package.json | 3 +- webui/public/theme-bootstrap.js | 44 +++ webui/scripts/check-theme-selectors.mjs | 278 ++++++++++++++++++ webui/scripts/check-theme-selectors.spec.mjs | 164 +++++++++++ webui/src/app.tsx | 8 +- webui/src/design-system/common-tokens.css | 88 +----- webui/src/design-system/components.css | 2 +- webui/src/design-system/glass-intensity.css | 10 + webui/src/design-system/preferences.test.ts | 58 ++++ webui/src/design-system/preferences.ts | 56 +++- .../src/design-system/theme-bootstrap.test.ts | 113 +++++++ .../design-system/theme-stylesheets.test.ts | 156 ++++++++++ webui/src/design-system/theme.test.ts | 92 ++++++ webui/src/design-system/theme.ts | 100 +++++++ webui/src/design-system/themes/contract.css | 101 +++++++ webui/src/design-system/themes/glass.css | 154 ++++++++++ webui/src/design-system/themes/index.css | 26 ++ webui/src/design-system/themes/mlxcel.css | 60 ++++ webui/src/design-system/tokens.css | 88 +----- webui/src/features/chat/style.test.ts | 23 +- webui/src/features/models/models.css | 4 +- webui/src/i18n/catalog.ts | 18 +- webui/src/main.tsx | 3 + webui/tests/browser-fixtures.ts | 28 +- webui/tests/theme.spec.ts | 212 +++++++++++++ 45 files changed, 1877 insertions(+), 229 deletions(-) rename src/webui/assets/assets/{code-highlight-DYgjCuFT.js => code-highlight-B7JRfpaI.js} (93%) rename src/webui/assets/assets/{history-BhdDGTqa.js => history-DIlBLmUk.js} (94%) rename src/webui/assets/assets/{index-CW0N8nOa.js => index-C5rxJd1U.js} (74%) delete mode 100644 src/webui/assets/assets/index-D2RzuY00.css create mode 100644 src/webui/assets/assets/index-jceAf1an.css create mode 100644 src/webui/assets/theme-bootstrap.js create mode 100644 webui/public/theme-bootstrap.js create mode 100644 webui/scripts/check-theme-selectors.mjs create mode 100644 webui/scripts/check-theme-selectors.spec.mjs create mode 100644 webui/src/design-system/preferences.test.ts create mode 100644 webui/src/design-system/theme-bootstrap.test.ts create mode 100644 webui/src/design-system/theme-stylesheets.test.ts create mode 100644 webui/src/design-system/theme.test.ts create mode 100644 webui/src/design-system/theme.ts create mode 100644 webui/src/design-system/themes/contract.css create mode 100644 webui/src/design-system/themes/glass.css create mode 100644 webui/src/design-system/themes/index.css create mode 100644 webui/src/design-system/themes/mlxcel.css create mode 100644 webui/tests/theme.spec.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5d67947d3..36c99526b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -432,6 +432,11 @@ jobs: run: pnpm --dir webui run typecheck - name: Lint WebUI run: pnpm --dir webui run lint + # Issue #1903: data-theme is always -, so a selector keyed + # on a bare mode (or on the host OS scheme) silently stops applying. The + # gate evaluates every theme selector against the ids theme.ts ships. + - name: Check WebUI theme selectors + run: pnpm --dir webui run check:theme-selectors - name: Test WebUI scaffold run: pnpm --dir webui run unit - name: Install browser runtime diff --git a/Makefile b/Makefile index 1e05995f0..885a38953 100644 --- a/Makefile +++ b/Makefile @@ -806,10 +806,11 @@ verify-webui-bundle: ## Rebuild the bundled WebUI twice and compare it with chec @$(WEBUI_BUNDLE_PY) scripts/webui/build_bundle.py --verify .PHONY: verify-webui-frontend -verify-webui-frontend: ## Run WebUI lint, typecheck, unit tests, Chromium layout/accessibility gate, and multi-engine browser smoke (issue #1848) +verify-webui-frontend: ## Run WebUI lint, typecheck, theme-selector gate, unit tests, Chromium layout/accessibility gate, and multi-engine browser smoke (issue #1848) @echo "$(CYAN)[verify] WebUI frontend lint/type/unit/browser matrix...$(RESET)" @pnpm --dir webui run typecheck @pnpm --dir webui run lint + @pnpm --dir webui run check:theme-selectors @pnpm --dir webui run unit @pnpm --dir webui run browser @pnpm --dir webui run browser:all diff --git a/NOTICE b/NOTICE index 957a4e325..fae5839ce 100644 --- a/NOTICE +++ b/NOTICE @@ -136,6 +136,22 @@ The bundled WebUI assets under src/webui/assets/ include production runtime code SOFTWARE. +backend.ai-go (WebUI glass theme) +--------------------------------- + +Portions of the WebUI glass theme in +webui/src/design-system/themes/glass.css (its system-color palette, the +filled-button highlight gradients, and the translucent surface, fill and +chrome-highlight values) are derived from the glass theme tokens of +backend.ai-go (https://github.com/lablup/backend.ai-go), Copyright 2025-2026 +Lablup Inc., licensed under the Apache License, Version 2.0. Colors were +adjusted where needed to meet WCAG 2.2 AA against mlxcel's own surfaces. The +theme is compiled into the bundled WebUI assets under src/webui/assets/. +backend.ai-go ships no NOTICE file, so there is no upstream notice text to +carry forward under Section 4(d); the Apache License, Version 2.0 text is in +this repository's LICENSE. + + mlx ROCm backend (NripeshN/mlx, rocm-support branch) ---------------------------------------------------- diff --git a/README.md b/README.md index db5754fb1..bd7684e21 100644 --- a/README.md +++ b/README.md @@ -332,6 +332,7 @@ Apache License 2.0 unless otherwise noted. See [LICENSE](LICENSE). Third-party a - [mlx-lm](https://github.com/ml-explore/mlx-lm), [mlx-vlm](https://github.com/Blaizzy/mlx-vlm), and [mlx-audio](https://github.com/Blaizzy/mlx-audio), whose model coverage and behavior mlxcel ports and mirrors. See [NOTICE](NOTICE). - [MLX Community](https://huggingface.co/mlx-community), pre-converted MLX checkpoints. - [turboquant_plus](https://github.com/TheTom/turboquant_plus), whose TurboQuant KV-cache algorithms are ported under Apache-2.0. See [NOTICE](NOTICE). +- [backend.ai-go](https://github.com/lablup/backend.ai-go), whose glass theme tokens the bundled WebUI's glass theme is derived from under Apache-2.0. See [NOTICE](NOTICE). - [moonshotai/Kimi-K3](https://huggingface.co/moonshotai/Kimi-K3), whose tiktoken pre-tokenization pattern and XTML chat grammar are reimplemented in Rust under the Kimi K3 License. See [NOTICE](NOTICE). - [FlashInfer](https://github.com/flashinfer-ai/flashinfer), whose paged-attention, split-KV, cascade state-merge, and sampling designs inform mlxcel's serving kernels. - [IREE](https://github.com/iree-org/iree) and [StableHLO](https://github.com/openxla/stablehlo), the runtime and graph format behind the alpha OpenXLA backend: mlxcel emits StableHLO, `iree-compile` lowers it, and the IREE runtime executes it under the opt-in `xla-iree` build. See [NOTICE](NOTICE). diff --git a/docs/webui/bundling.ko.md b/docs/webui/bundling.ko.md index 55ff98632..78336f8f8 100644 --- a/docs/webui/bundling.ko.md +++ b/docs/webui/bundling.ko.md @@ -50,7 +50,7 @@ cargo build --release --features cuda `mlxcel::server::webui::router::()`의 라우트에는 이미 `/webui`가 포함됩니다. 루트에 병합하거나 **검증된 서버 API 접두사** 아래 한 번 중첩하세요. `/webui` 아래 다시 중첩하지 마세요. 부모 라우터의 루트 상태 확인·추론 경로는 유지됩니다. `/webui`는 `/webui/`로 리디렉션되고, `#models` 형태의 탐색은 클라이언트 안에서 처리됩니다. 없는 정적 경로는 API 라우팅 오류를 감출 수 있는 HTML 대체 응답 대신 404를 반환합니다. -정적 응답은 GET/HEAD와 조건부 ETag를 지원하고, 다른 메서드는 `Allow: GET, HEAD`와 함께 405를 반환합니다. HTML·매니페스트는 재검증하며 콘텐츠 해시 자산에는 immutable 캐시를 허용합니다. 라우터는 인코딩·경로 탐색 표현을 거부하며 일반·오류·리디렉션·304 응답에 동일 출처 CSP, `nosniff`, no-referrer 헤더를 설정합니다. 이 정적 정책이 후속 관리 API의 Host/Origin/인증 검사를 대신하지는 않습니다. +정적 응답은 GET/HEAD와 조건부 ETag를 지원하고, 다른 메서드는 `Allow: GET, HEAD`와 함께 405를 반환합니다. HTML·매니페스트·`theme-bootstrap.js`(`webui/public/`에서 복사되는 마운트 전 테마 스크립트로, 콘텐츠 해시가 없는 유일한 스크립트)는 재검증하며 콘텐츠 해시 자산에는 immutable 캐시를 허용합니다. 라우터는 인코딩·경로 탐색 표현을 거부하며 일반·오류·리디렉션·304 응답에 동일 출처 CSP, `nosniff`, no-referrer 헤더를 설정합니다. 이 정적 정책이 후속 관리 API의 Host/Origin/인증 검사를 대신하지는 않습니다. ## 정적 자산과 운영 시작 경로의 분리 검증 diff --git a/docs/webui/bundling.md b/docs/webui/bundling.md index 08b779c70..734496de3 100644 --- a/docs/webui/bundling.md +++ b/docs/webui/bundling.md @@ -50,7 +50,7 @@ cargo build --release --features cuda `mlxcel::server::webui::router::()` returns a router whose routes already include `/webui`. Merge it at the root, or nest it once under the **validated server API prefix**, not under a second `/webui`. The parent router retains its root health and inference routes. `/webui` redirects to `/webui/`; the shell's `#models`-style navigation stays client-side. A missing static path returns 404 rather than an HTML fallback that could hide an API-routing error. -Static responses support GET/HEAD and conditional ETags; other methods return 405 with `Allow: GET, HEAD`. HTML and the manifest revalidate; content-hashed assets may be cached immutably. The router rejects encoded/traversal path spellings and sets same-origin CSP, `nosniff`, and no-referrer headers on ordinary, error, redirect, and 304 responses. This static policy does not replace the later Host/Origin/authentication checks on administrative APIs. +Static responses support GET/HEAD and conditional ETags; other methods return 405 with `Allow: GET, HEAD`. HTML, the manifest and `theme-bootstrap.js` (the pre-mount theme script copied from `webui/public/`, the one script without a content hash) revalidate; content-hashed assets may be cached immutably. The router rejects encoded/traversal path spellings and sets same-origin CSP, `nosniff`, and no-referrer headers on ordinary, error, redirect, and 304 responses. This static policy does not replace the later Host/Origin/authentication checks on administrative APIs. ## Testing static assets and production startup separately diff --git a/docs/webui/design-system.md b/docs/webui/design-system.md index 32f6d54d4..e3d4b4235 100644 --- a/docs/webui/design-system.md +++ b/docs/webui/design-system.md @@ -12,9 +12,32 @@ The WebUI is a browser application that follows the macOS 27 hierarchy without c ## Tokens -Tokens live in `webui/src/design-system/tokens.css` and `glass-intensity.css`. Pages must use these semantic names instead of hard-coded hex values: `--color-bg`, `--color-bg-elevated`, `--color-bg-neutral`, `--color-text`, `--color-muted`, `--color-separator`, `--color-focus`, `--color-selection`, `--color-warning`, `--color-error`, `--color-success`, `--material-glass-bg`, `--material-content-bg`, `--shadow-chrome`, `--shadow-card`, `--radius-*`, `--space-*` and `--motion-*`. +Theme-independent tokens (spacing, radius, motion, focus ring) and the accessibility overrides live in `webui/src/design-system/tokens.css`, the glass intensity scale in `glass-intensity.css`, and every color, material and shadow value per theme under `webui/src/design-system/themes/` (see [Themes](#themes)). Pages must use these semantic names instead of hard-coded hex values: `--color-bg`, `--color-bg-elevated`, `--color-bg-neutral`, `--color-text`, `--color-muted`, `--color-separator`, `--color-focus`, `--color-selection`, `--color-warning`, `--color-error`, `--color-success`, `--material-glass-bg`, `--material-content-bg`, `--material-control-bg`, `--shadow-chrome`, `--shadow-card`, `--radius-*`, `--space-*` and `--motion-*`. Every shipped theme defines each of them; `src/design-system/theme-stylesheets.test.ts` fails when a stylesheet reads a custom property some theme leaves undefined. -`data-theme`, `data-material`, `data-high-contrast`, `data-reduce-transparency`, `data-reduce-motion`, `data-backdrop-filter` and `data-glass-intensity` are the only supported appearance switches. The 0-100 glass intensity preference is represented by discrete CSS rules, not inline styles, so the future CSP can continue to reject unsafe inline styles. High contrast is `system` by default, can be explicitly `on` or `off`, and overrides decorative transparency when enabled by either the browser preference or the explicit setting. +`data-theme`, `data-theme-family`, `data-color-scheme`, `data-material`, `data-high-contrast`, `data-reduce-transparency`, `data-reduce-motion`, `data-backdrop-filter` and `data-glass-intensity` are the only supported appearance switches. The 0-100 glass intensity preference is represented by discrete CSS rules, not inline styles, so the CSP can continue to reject unsafe inline styles. High contrast is `system` by default, can be explicitly `on` or `off`, and overrides decorative transparency when enabled by either the browser preference or the explicit setting. The overrides are written with more specificity than the theme blocks, and the blur and saturation resets sit after the intensity steps, so an opaque material, reduced transparency, a browser without `backdrop-filter` or raised contrast wins over any intensity and any theme. + +## Themes + +The WebUI takes its theming from the `@lablup/ui-common` theme mechanism. The package's `base.css` declares the `--token-*` contract on `:root`, and a theme is a block of those tokens keyed on one `data-theme` value. `src/main.tsx` imports exactly one theme stylesheet, `design-system/themes/index.css`, directly after `base.css`, which is the package rule (at most one theme file alongside `base.css`, never imported by a component). No ui-common theme file is loaded: the package ships only its orange family, and its `base.css` leaves a product with its own identity to ship its own `[data-theme]` blocks. + +`data-theme` always holds a family-scoped id, `-`: + +| Family | Settings label | Ids | Notes | +|---|---|---|---| +| `mlxcel` (default) | Standard / 표준 | `mlxcel-light`, `mlxcel-dark` | The approved 4185 baseline. Its values moved from `tokens.css` and `common-tokens.css` into theme blocks unchanged. | +| `glass` | Glass / 글래스 | `glass-light`, `glass-dark` | Frosted glass in the macOS 27 language: translucent chrome with a top light reflection, tinted glass controls and highlighted button fills, near-opaque content surfaces. | + +The stored preference is kept apart from the applied id. `mlxcel.webui.appearance` stores `themeFamily` and `colorScheme` (`system`, `light` or `dark`). `src/design-system/theme.ts` resolves `system` against the host scheme, and `applyAppearance` writes the id to `data-theme`, the family to `data-theme-family` and the raw preference to `data-color-scheme`, so `data-theme` never holds `system`, `light` or `dark` on its own. A `system` preference follows host changes live. Appearance saved before the family existed carried the scheme in a flat `theme` field and is still read as the color scheme. + +Files: `themes/contract.css` binds the scheme-dependent half of the token contract (colors, shadows, button fills, focus color, tab surfaces) to the semantic tokens above for every shipped id; `themes/mlxcel.css` and `themes/glass.css` set the per-id values and any contract token a family styles differently; `common-tokens.css` keeps the theme-independent half (type scale, spacing, radius, control heights, motion, z-index) on `:root`, as ui-common's own `base.css` does. + +The theme is applied before the first paint. `webui/public/theme-bootstrap.js` is a classic, render-blocking script in the `` of `webui/index.html`; it reads the same storage key, resolves the id and writes the three theme attributes before the stylesheet paints or the app module runs, so a cold load never shows the wrong theme. It is an external file because the served CSP is `script-src 'self'`. `scripts/webui/build_bundle.py` refuses a bundle whose `index.html` lacks it, loads it after the app module or carries any inline script, and `src/design-system/theme-bootstrap.test.ts` runs the file against `applyAppearance` over stored-value and host-scheme combinations so the two cannot drift. It is the one script in the bundle without a content hash and revalidates like `index.html`. + +The glass family reads only the existing switches. Glass intensity sizes the chrome and control blur, saturation and translucency. `data-material="opaque"`, reduced transparency (setting or `prefers-reduced-transparency`), `data-backdrop-filter="unsupported"` and raised contrast (setting or `prefers-contrast: more`) turn every glass surface opaque, drop the control backdrop and the button highlight, at any intensity. Reduced motion drops the press transform. The glass tokens live in this repository rather than in `@lablup/ui-common`: they are bound to this product's semantic token layer, which the package does not have, and proposing a glass family to the package is a separate decision for that package. The glass values derive from lablup/backend.ai-go's glass theme under Apache-2.0; see [NOTICE](../../NOTICE). + +Two engine limits apply. `@lablup/ui-common` alpha.19's Button stylesheet declares its backdrop only as `-webkit-backdrop-filter`, so glass button blur renders in WebKit and the buttons elsewhere stay translucent without blur. The product's own `.material-glass` chrome writes the prefixed declaration first, because Lightning CSS, which minifies the bundle, keeps only the prefixed form when it follows the standard one, and Chromium and Firefox ignore that form; `theme-stylesheets.test.ts` keeps the order. + +`pnpm --dir webui run check:theme-selectors` (`webui/scripts/check-theme-selectors.mjs`, run by the `webui-bundle` CI job and `make verify-webui-frontend`) is the gate that keeps this from rotting. It evaluates every `data-theme` and `data-theme-family` attribute selector in `webui/src`, `webui/public`, `webui/tests` and `index.html` against the ids `theme.ts` exports, whatever the operator, and fails on one that matches none, since such a rule compiles, renders and silently never applies. It also rejects `data-color-scheme` selectors (the raw preference), `@media (prefers-color-scheme)` in stylesheets and `prefers-color-scheme` queries in app code outside the resolver and the bootstrap (the host OS, not the applied theme), literal non-id values compared with or written to `data-theme`, theme stylesheet imports outside the single entry, and a shipped id with no theme block. A genuine host-OS concern keeps its query only with a written `theme-selector-allow: ` on the same or the preceding line. ## Components @@ -34,7 +57,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 node:test spec and 316 Vitest tests across 36 files, covering the shared client/provider and shell behavior. `pnpm --dir webui run browser` executes 28 Playwright tests, 29 with `MLXCEL_WEBUI_FONT_DIAGNOSTICS=1`: 12 layout and accessibility cases (8 gallery and 4 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, and the Activity, Chat, Models and Settings route specs. The variants in `webui/tests/browser-fixtures.ts` cover 390/1024/1440 widths, light/dark, tinted/opaque, high contrast and CJK labels. Each of the 12 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 (32 tests) and 401 Vitest tests across 40 files, covering the shared client/provider, shell and theme behavior. `pnpm --dir webui run browser` executes 59 Playwright tests, 60 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, and 22 `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 4e861ac30..0c5af679b 100644 --- a/docs/webui/ui-common.md +++ b/docs/webui/ui-common.md @@ -23,7 +23,7 @@ The semantic ref bridges are narrowly scoped compatibility workarounds for the p ## Theme authority -Only the library base stylesheet and component subpath styles are imported. `common-tokens.css` maps the full published token contract to product colors, typography, spacing, radii and motion. `common-components.css` scopes necessary DOM/geometry overrides to adapters, including primary/danger foregrounds, compact 44px targets and wrapped controls. No orange theme stylesheet or remote font/resource is loaded. Keep the approved macOS 27 shell topology, continuous toolbar and neutral content surfaces; package adoption is not approval to substitute its default PageLayout or theme. +Only the library base stylesheet, one product theme stylesheet and component subpath styles are imported. `src/main.tsx` imports `@lablup/ui-common/styles/base.css` and then `design-system/themes/index.css`, the single theme entry, following the package rule of at most one theme file alongside `base.css`; no component imports a theme file. The product themes (`mlxcel-light`, `mlxcel-dark`, `glass-light`, `glass-dark`) are `[data-theme]` blocks over the published token contract, selected by the applied theme id; see [Themes](design-system.md#themes). `common-tokens.css` keeps the theme-independent half of the contract (typography, spacing, radii, control heights, motion, z-index) on `:root`. `common-components.css` scopes necessary DOM/geometry overrides to adapters, including primary/danger foregrounds, compact 44px targets and wrapped controls. No orange theme stylesheet or remote font/resource is loaded. Keep the approved macOS 27 shell topology, continuous toolbar and neutral content surfaces; package adoption is not approval to substitute its default PageLayout or theme. ## Verification boundary diff --git a/docs/webui/ux-contract.md b/docs/webui/ux-contract.md index b4aef23ce..7ab5b4963 100644 --- a/docs/webui/ux-contract.md +++ b/docs/webui/ux-contract.md @@ -24,7 +24,7 @@ Use IEC bytes for file/model sizes, decimal tokens/s for throughput, millisecond ## Visual and viewport contract -Use system fonts, 4 px spacing, semantic color/material/elevation/radius/motion tokens, default light/dark following the OS, explicit theme override, 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. +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. 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. diff --git a/scripts/webui/build_bundle.py b/scripts/webui/build_bundle.py index b63603f34..e00049d7e 100755 --- a/scripts/webui/build_bundle.py +++ b/scripts/webui/build_bundle.py @@ -222,6 +222,17 @@ def assert_index_html(root: Path) -> None: raise SystemExit("index.html must not reference external origins") if 'id="root"' not in html or 'type="module"' not in html or './assets/' not in html: raise SystemExit("index.html must contain the WebUI root and relative module assets") + # The served CSP is script-src 'self', so every script is an external file. + for match in re.finditer(r"]*)>(.*?)", html, re.S): + if 'src="' not in match.group(1) or match.group(2).strip(): + raise SystemExit("index.html must not carry an inline script; the WebUI CSP blocks it") + # Issue #1903: the theme is applied before first paint by a classic, + # render-blocking script that runs ahead of the app module. + bootstrap = re.search(r']*\bsrc="\./theme-bootstrap\.js"[^>]*>', html) + if bootstrap is None or re.search(r'\b(type="module"|async|defer)\b', bootstrap.group(0)): + raise SystemExit("index.html must load ./theme-bootstrap.js as a classic, blocking script") + if bootstrap.start() > html.index('type="module"'): + raise SystemExit("index.html must run ./theme-bootstrap.js before the app module") for token in html.replace('>', '>\n').splitlines(): for attr in ('src="./', 'href="./'): if attr in token: diff --git a/src/webui/assets/assets/code-highlight-DYgjCuFT.js b/src/webui/assets/assets/code-highlight-B7JRfpaI.js similarity index 93% rename from src/webui/assets/assets/code-highlight-DYgjCuFT.js rename to src/webui/assets/assets/code-highlight-B7JRfpaI.js index 9a517cd0c..7341f7da1 100644 --- a/src/webui/assets/assets/code-highlight-DYgjCuFT.js +++ b/src/webui/assets/assets/code-highlight-B7JRfpaI.js @@ -1 +1 @@ -import{i as e,n as t,r as n}from"./index-CW0N8nOa.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-C5rxJd1U.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-BhdDGTqa.js b/src/webui/assets/assets/history-DIlBLmUk.js similarity index 94% rename from src/webui/assets/assets/history-BhdDGTqa.js rename to src/webui/assets/assets/history-DIlBLmUk.js index 42517ac9b..2a7ba12f3 100644 --- a/src/webui/assets/assets/history-BhdDGTqa.js +++ b/src/webui/assets/assets/history-DIlBLmUk.js @@ -1 +1 @@ -import{n as e,r as t,t as n}from"./index-CW0N8nOa.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-C5rxJd1U.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-CW0N8nOa.js b/src/webui/assets/assets/index-C5rxJd1U.js similarity index 74% rename from src/webui/assets/assets/index-CW0N8nOa.js rename to src/webui/assets/assets/index-C5rxJd1U.js index 399ec4726..212ea9cc5 100644 --- a/src/webui/assets/assets/index-CW0N8nOa.js +++ b/src/webui/assets/assets/index-C5rxJd1U.js @@ -5,8 +5,8 @@ var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r= `);for(i=r=0;ri||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{ke=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:``)?Oe(n):``}function je(e,t){switch(e.tag){case 26:case 27:case 5:return Oe(e.type);case 16:return Oe(`Lazy`);case 13:return e.child!==t&&t!==null?Oe(`Suspense Fallback`):Oe(`Suspense`);case 19:return Oe(`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 Oe(`Activity`);case 30:return Oe(`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),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,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),W&&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),W&&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 W&&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)}),W&&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),io(c,o),c.return=e,e=c;break a}}else if(r.elementType===l||typeof l==`object`&&l&&l.$$typeof===se&&Za(l)===r.type){n(e,r.sibling),c=a(r,o.props),io(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),io(c,o),c.return=e,e=c):(c=Pi(o.type,o.key,o.props,null,e.mode,c),io(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=Za(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,ro(o),c);if(o.$$typeof===M)return _(e,r,Sa(e,o),c);ao(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{no=0;var i=_(e,t,n,r);return to=null,i}catch(t){if(t===Ga||t===qa)throw t;var a=Ai(29,t,null,e.mode);return a.lanes=r,a.return=e,a}}}var so=oo(!0),co=oo(!1),lo=!1;function uo(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function fo(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 po(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function mo(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 ho(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 go(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 _o=!1;function vo(){if(_o){var e=Ia;if(e!==null)throw e}}function yo(e,t,n,r){_o=!1;var i=e.updateQueue;lo=!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===Fa&&(_o=!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:lo=!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 bo(e,t){if(typeof e!=`function`)throw Error(i(191,e));e.call(t)}function xo(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,za(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 xa(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=po(n);var r=mo(t,e,n);r!==null&&(Pd(r,t,n),ho(r,t,n)),t={cache:Oa()},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===G||t!==null&&t===G}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:xa,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:xa,use:ss,useCallback:function(e,t){return rs().memoizedState=[e,t===void 0?null:t],e},useContext:xa,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,G,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,G,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,G,e.queue,!0,!1),rs().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var r=G,a=rs();if(W){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(W){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=z.current,sa(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||ia(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=sa(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 ca(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;gl(t),e=!1}else n=la(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),e=!0;if(!e)return t.flags&256?(No(t),t):(No(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=sa(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 ca(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;gl(t),a=!1}else a=la(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=a),a=!0;if(!a)return t.flags&256?(No(t),t):(No(t),null)}return No(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 B(),e===null&&Wf(t.stateNode.containerInfo),t.flags|=67108864,gl(t),null;case 10:return ha(t.type),gl(t),null;case 19:if(Io(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=Lo(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 Fo(t,Po.current&1|2),W&&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=Lo(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&&!W)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=Po.current,o=a?o&1|2:o&1,r.tailMode===`visible`||r.tailMode===`collapsed`||!n||W?Fo(t,o):(n=o,L(Do,t),L(Po,n),Oo===null&&(Oo=t)),W&&Yi(t,r.treeForkCount),e}return gl(t),null;case 22:case 23:return No(t),Eo(),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(Va),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),ha(Da),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 ha(Da),B(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return Te(t),null;case 31:if(t.memoizedState!==null){if(No(t),t.alternate===null)throw Error(i(340));ca()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(No(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(i(340));ca()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return Io(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 B(),null;case 10:return ha(t.type),null;case 22:case 23:return No(t),Eo(),e!==null&&be(Va),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return ha(Da),null;case 25:return null;default:return null}}function yl(e,t){switch(Qi(t),t.tag){case 3:ha(Da),B();break;case 26:case 27:case 5:Te(t);break;case 4:B();break;case 31:t.memoizedState!==null&&No(t);break;case 13:No(t);break;case 19:Io(t);break;case 10:ha(t.type);break;case 22:case 23:No(t),Eo(),e!==null&&be(Va);break;case 24:ha(Da)}}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{xo(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[bt]=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),Je&&typeof Je.onPostCommitFiberRoot==`function`)try{Je.onPostCommitFiberRoot(qe,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=mo(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=Bi(n,e),n=Dc(2),r=mo(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=Ti(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=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[Ot]=!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=Nt(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=Nt(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=Nt(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=z.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=Nt(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=Nt(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=Nt(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[Ot]){r.loading=1;return}}else t=e.createElement(`link`),t[Ot]=!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]),R=(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 z=e.find(e=>e.id===P)?.content,Se=e.find(e=>e.id===P)?.label,Ce=t.length>0;se.current=[];let B=(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)},we=()=>Ce?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 B(t,n)})})]},t?.id||`default`)):e.map((e,t)=>B(e,t)),Te=()=>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:R,"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`))})]}),Ee=d===`segmented`||d===`compact`;return y===`dropdown`&&D&&!Ee?(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:Se}),(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:z})]}):(0,x.jsxs)(`div`,{className:`tabs ${y===`menu`?`tabs--overflow-menu`:``} ${d===`segmented`?`tabs--variant-segmented`:d===`compact`?`tabs--variant-compact`:``} ${Ee&&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:we()}),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`})})}),Te()]}),p&&(0,x.jsx)(`div`,{id:`tabpanel-${P}`,role:`tabpanel`,"aria-labelledby":`tab-${P}`,className:`tabs__panel ${o}`.trim(),tabIndex:0,children:z})]})}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})})}function he(e){return(0,x.jsx)(le,{...e,className:`ds-common-table ${e.className??``}`.trim()})}var F=(0,_.createContext)(!1),I=m();function ge({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,I.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 _e=[{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. Type the model name to confirm.`,ko:`관리 캐시 항목 {name} ({source})을 영구 삭제합니다. 언로드와 달리 디스크 파일을 제거합니다. 모델 이름을 입력하여 확인하세요.`,test_id:`models-library-delete-body`},{key:`models.library.confirm_name`,en:`Exact cache model ID to confirm`,ko:`확인용 정확한 캐시 모델 ID`,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`}],ve=[{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`}],ye=[{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`}],be=[{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`}],L=[{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 매우 긴 로컬 체크포인트 이름과 한국어 모델 이름`,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.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.system`,en:`System`,ko:`시스템`,test_id:`settings-theme-system`},{key:`settings.theme.light`,en:`Light`,ko:`라이트`,test_id:`settings-theme-light`},{key:`settings.theme.dark`,en:`Dark`,ko:`다크`,test_id:`settings-theme-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`},..._e,...ve,...ye,...be],xe=new Map(L.map(e=>[e.key,e]));function R(e,t,n={}){let r=xe.get(t);return r?r[e].replace(/\{(\w+)\}/g,(e,t)=>Object.hasOwn(n,t)?n[t]:`{${t}}`):t}function z(e){return xe.get(e)?.test_id??e.replaceAll(`.`,`-`)}function Se(e){let t=(0,_.useContext)(F),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)(ge,{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]})}function Ce(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 B(e){return(0,x.jsxs)(`section`,{className:`ds-banner`,"data-tone":e.tone??`error`,role:e.tone===`info`?`status`:`alert`,"data-testid":e.testId,children:[(0,x.jsx)(`strong`,{children:e.title}),(0,x.jsx)(`p`,{children:e.body}),e.action]})}function we(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;Te(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(()=>Te(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&&Te(n,e)},0)},"data-testid":`dialog-close`})]}),(0,x.jsx)(`div`,{children:(0,x.jsx)(F.Provider,{value:!0,children:e.children})})]})}function Te(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 Ee(e){return(0,x.jsx)(we,{...e})}function De(e){return(0,x.jsxs)(Ee,{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 Oe(e){return(0,x.jsx)(we,{...e,position:`left`,className:`ds-sheet ${e.className??``}`.trim()})}function ke(e){let t=(0,_.useId)();return(0,x.jsxs)(`span`,{className:`ds-tooltip-wrap`,children:[_.cloneElement(e.children,{"aria-describedby":t}),(0,x.jsx)(`span`,{className:`ds-tooltip`,role:`tooltip`,id:t,children:e.label})]})}function Ae(e){return(0,x.jsxs)(`aside`,{className:`ds-inspector`,"aria-label":e.title,children:[(0,x.jsx)(`h2`,{children:e.title}),e.children]})}function je(e){return(0,x.jsxs)(`table`,{className:`ds-table`,children:[(0,x.jsx)(`caption`,{children:e.caption}),e.children]})}function Me(e){return(0,x.jsx)(`ul`,{className:`ds-list`,"aria-label":e.label,children:e.children})}function Ne(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 Pe(e){return(0,x.jsx)(B,{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 Fe(e){if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Malformed settings response.`);return e}function Ie(e){if(typeof e!=`string`||!/^[0-9a-f]{64}$/.test(e))throw Error(`Malformed settings fingerprint.`);return e}function Le(e){let t=Fe(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=Fe(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:Fe(t.current),fingerprint:Ie(t.fingerprint)}}function Re(e){let t=Fe(e);if(!Array.isArray(t.rejected)||!t.rejected.every(e=>{let t=Fe(e);return typeof t.name==`string`&&typeof t.reason==`string`}))throw Error(`Malformed settings rejection list.`);return{applied:Fe(t.applied),rejected:t.rejected,current:Fe(t.current),fingerprint:Ie(t.fingerprint)}}function ze(e){let t=Fe(e),n=Fe(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:Fe(t.geometry)}}function Be(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 Ve(e,t){return typeof t==`string`&&[`str`,`str_or_null`].includes(e.type)?t:JSON.stringify(t)??``}function He(e){let t=Fe(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 Ue=1048576,We=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??Ue,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(` +`+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),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-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&&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),io(c,o),c.return=e,e=c;break a}}else if(r.elementType===l||typeof l==`object`&&l&&l.$$typeof===se&&Za(l)===r.type){n(e,r.sibling),c=a(r,o.props),io(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),io(c,o),c.return=e,e=c):(c=Pi(o.type,o.key,o.props,null,e.mode,c),io(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=Za(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,ro(o),c);if(o.$$typeof===M)return _(e,r,Sa(e,o),c);ao(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{no=0;var i=_(e,t,n,r);return to=null,i}catch(t){if(t===Ga||t===qa)throw t;var a=Ai(29,t,null,e.mode);return a.lanes=r,a.return=e,a}}}var so=oo(!0),co=oo(!1),lo=!1;function uo(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function fo(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 po(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function mo(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 ho(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 go(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 _o=!1;function vo(){if(_o){var e=Ia;if(e!==null)throw e}}function yo(e,t,n,r){_o=!1;var i=e.updateQueue;lo=!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===Fa&&(_o=!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:lo=!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 bo(e,t){if(typeof e!=`function`)throw Error(i(191,e));e.call(t)}function xo(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,za(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 xa(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=po(n);var r=mo(t,e,n);r!==null&&(Pd(r,t,n),ho(r,t,n)),t={cache:Oa()},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===G||t!==null&&t===G}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:xa,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:xa,use:ss,useCallback:function(e,t){return rs().memoizedState=[e,t===void 0?null:t],e},useContext:xa,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,G,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,G,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,G,e.queue,!0,!1),rs().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var r=G,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-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=z.current,sa(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[bt]=t,e=!!(e.nodeValue===n||r!==null&&!0===r.suppressHydrationWarning||ep(e.nodeValue,n)),e||ia(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=sa(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 ca(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;gl(t),e=!1}else n=la(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),e=!0;if(!e)return t.flags&256?(No(t),t):(No(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=sa(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 ca(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;gl(t),a=!1}else a=la(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=a),a=!0;if(!a)return t.flags&256?(No(t),t):(No(t),null)}return No(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 B(),e===null&&Wf(t.stateNode.containerInfo),t.flags|=67108864,gl(t),null;case 10:return ha(t.type),gl(t),null;case 19:if(Io(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=Lo(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 Fo(t,Po.current&1|2),U&&Xi(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=Lo(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=Po.current,o=a?o&1|2:o&1,r.tailMode===`visible`||r.tailMode===`collapsed`||!n||U?Fo(t,o):(n=o,L(Do,t),L(Po,n),Oo===null&&(Oo=t)),U&&Xi(t,r.treeForkCount),e}return gl(t),null;case 22:case 23:return No(t),Eo(),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(Va),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),ha(Da),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 ha(Da),B(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return Te(t),null;case 31:if(t.memoizedState!==null){if(No(t),t.alternate===null)throw Error(i(340));ca()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(No(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(i(340));ca()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return Io(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 B(),null;case 10:return ha(t.type),null;case 22:case 23:return No(t),Eo(),e!==null&&be(Va),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return ha(Da),null;case 25:return null;default:return null}}function yl(e,t){switch($i(t),t.tag){case 3:ha(Da),B();break;case 26:case 27:case 5:Te(t);break;case 4:B();break;case 31:t.memoizedState!==null&&No(t);break;case 13:No(t);break;case 19:Io(t);break;case 10:ha(t.type);break;case 22:case 23:No(t),Eo(),e!==null&&be(Va);break;case 24:ha(Da)}}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{xo(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[bt]=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),Je&&typeof Je.onPostCommitFiberRoot==`function`)try{Je.onPostCommitFiberRoot(qe,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=mo(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=Bi(n,e),n=Dc(2),r=mo(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=Ti(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=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[Ot]=!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=Nt(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=Nt(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=Nt(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=z.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=Nt(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=Nt(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=Nt(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[Ot]){r.loading=1;return}}else t=e.createElement(`link`),t[Ot]=!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]),R=(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 z=e.find(e=>e.id===P)?.content,Se=e.find(e=>e.id===P)?.label,Ce=t.length>0;se.current=[];let B=(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)},we=()=>Ce?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 B(t,n)})})]},t?.id||`default`)):e.map((e,t)=>B(e,t)),Te=()=>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:R,"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`))})]}),Ee=d===`segmented`||d===`compact`;return y===`dropdown`&&D&&!Ee?(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:Se}),(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:z})]}):(0,x.jsxs)(`div`,{className:`tabs ${y===`menu`?`tabs--overflow-menu`:``} ${d===`segmented`?`tabs--variant-segmented`:d===`compact`?`tabs--variant-compact`:``} ${Ee&&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:we()}),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`})})}),Te()]}),p&&(0,x.jsx)(`div`,{id:`tabpanel-${P}`,role:`tabpanel`,"aria-labelledby":`tab-${P}`,className:`tabs__panel ${o}`.trim(),tabIndex:0,children:z})]})}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})})}function he(e){return(0,x.jsx)(le,{...e,className:`ds-common-table ${e.className??``}`.trim()})}var F=(0,_.createContext)(!1),I=m();function ge({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,I.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 _e=[{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. Type the model name to confirm.`,ko:`관리 캐시 항목 {name} ({source})을 영구 삭제합니다. 언로드와 달리 디스크 파일을 제거합니다. 모델 이름을 입력하여 확인하세요.`,test_id:`models-library-delete-body`},{key:`models.library.confirm_name`,en:`Exact cache model ID to confirm`,ko:`확인용 정확한 캐시 모델 ID`,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`}],ve=[{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`}],ye=[{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`}],be=[{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`}],L=[{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 매우 긴 로컬 체크포인트 이름과 한국어 모델 이름`,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`},..._e,...ve,...ye,...be],xe=new Map(L.map(e=>[e.key,e]));function R(e,t,n={}){let r=xe.get(t);return r?r[e].replace(/\{(\w+)\}/g,(e,t)=>Object.hasOwn(n,t)?n[t]:`{${t}}`):t}function z(e){return xe.get(e)?.test_id??e.replaceAll(`.`,`-`)}function Se(e){let t=(0,_.useContext)(F),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)(ge,{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]})}function Ce(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 B(e){return(0,x.jsxs)(`section`,{className:`ds-banner`,"data-tone":e.tone??`error`,role:e.tone===`info`?`status`:`alert`,"data-testid":e.testId,children:[(0,x.jsx)(`strong`,{children:e.title}),(0,x.jsx)(`p`,{children:e.body}),e.action]})}function we(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;Te(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(()=>Te(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&&Te(n,e)},0)},"data-testid":`dialog-close`})]}),(0,x.jsx)(`div`,{children:(0,x.jsx)(F.Provider,{value:!0,children:e.children})})]})}function Te(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 Ee(e){return(0,x.jsx)(we,{...e})}function De(e){return(0,x.jsxs)(Ee,{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 Oe(e){return(0,x.jsx)(we,{...e,position:`left`,className:`ds-sheet ${e.className??``}`.trim()})}function ke(e){let t=(0,_.useId)();return(0,x.jsxs)(`span`,{className:`ds-tooltip-wrap`,children:[_.cloneElement(e.children,{"aria-describedby":t}),(0,x.jsx)(`span`,{className:`ds-tooltip`,role:`tooltip`,id:t,children:e.label})]})}function Ae(e){return(0,x.jsxs)(`aside`,{className:`ds-inspector`,"aria-label":e.title,children:[(0,x.jsx)(`h2`,{children:e.title}),e.children]})}function je(e){return(0,x.jsxs)(`table`,{className:`ds-table`,children:[(0,x.jsx)(`caption`,{children:e.caption}),e.children]})}function Me(e){return(0,x.jsx)(`ul`,{className:`ds-list`,"aria-label":e.label,children:e.children})}function Ne(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 Pe(e){return(0,x.jsx)(B,{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 Fe(e){if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Malformed settings response.`);return e}function Ie(e){if(typeof e!=`string`||!/^[0-9a-f]{64}$/.test(e))throw Error(`Malformed settings fingerprint.`);return e}function Le(e){let t=Fe(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=Fe(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:Fe(t.current),fingerprint:Ie(t.fingerprint)}}function Re(e){let t=Fe(e);if(!Array.isArray(t.rejected)||!t.rejected.every(e=>{let t=Fe(e);return typeof t.name==`string`&&typeof t.reason==`string`}))throw Error(`Malformed settings rejection list.`);return{applied:Fe(t.applied),rejected:t.rejected,current:Fe(t.current),fingerprint:Ie(t.fingerprint)}}function ze(e){let t=Fe(e),n=Fe(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:Fe(t.geometry)}}function Be(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 Ve(e,t){return typeof t==`string`&&[`str`,`str_or_null`].includes(e.type)?t:JSON.stringify(t)??``}function He(e){let t=Fe(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 Ue=1048576,We=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??Ue,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 Ge(e){return Array.from(e).some(e=>{let t=e.charCodeAt(0);return t<=32||t>=127&&t<=159})}function Ke(e){if(/[\\?#]/.test(e)||Ge(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)||Ge(e))throw Error(`WebUI API base contains an ambiguous encoded path segment.`)}}function qe(e){let t=e??Ye();if(t===``)return``;if(!t.startsWith(`/`)||t.startsWith(`//`))throw Error(`WebUI API base must be a same-origin absolute path.`);return Ke(t),new URL(t,`http://webui.invalid`).pathname.replace(/\/$/,``)}function Je(e){return/^(.*)\/webui(?:\/(?:index\.html)?)?$/.exec(e)?.[1]??null}function Ye(){if(typeof document>`u`)return``;let e=document.querySelector(`meta[name="mlxcel-ui-api-base"]`)?.content;if(e!==void 0&&e.length>0)return qe(e);let t=document.querySelector(`base`)?.getAttribute(`href`);if(t!=null&&t.length>0){let e=t.replace(/^[a-z][a-z\d+.-]*:\/\/[^/]*/i,``);Ke(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 qe(Je(n.pathname)??n.pathname)}let n=window.location.pathname,r=Je(n);return r===null?``:(Ke(n),qe(r))}function Xe(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 Ze(e){if(e.length===0)throw Error(`Opaque path segment must not be empty.`);return encodeURIComponent(e)}var Qe=`{ @@ -3733,8 +3733,8 @@ Error generating stack: `+e.message+` } } } -`,$e=class extends Error{path;constructor(e,t){super(`${e}: ${t}`),this.path=e,this.name=`ValidationError`}},et=rt(Qe);function tt(e,t,n=`$`){let r=ht(et,[`components`,`schemas`],`#/components/schemas`)[e];if(r===void 0)throw new $e(n,`unknown schema ${e}`);it(r,t,n)}function nt(e){return JSON.parse(e)}function rt(e){return mt(nt(e),`$contract`)}function it(e,t,n){let r=mt(e,`${n}#schema`);if(typeof r.$ref==`string`){it(ft(r.$ref),t,n);return}if(r.anyOf!==void 0){if(!Array.isArray(r.anyOf)||!r.anyOf.some(e=>pt(e,t,n)))throw new $e(n,`did not match any allowed schema`);return}if(r.oneOf!==void 0){if(!Array.isArray(r.oneOf))throw new $e(n,`schema oneOf must be an array`);let e=r.oneOf.filter(e=>pt(e,t,n)).length;if(e!==1)throw new $e(n,`matched ${e} oneOf schemas`);return}if(r.const!==void 0&&t!==r.const)throw new $e(n,`expected constant ${String(r.const)}`);if(Array.isArray(r.enum)&&!r.enum.some(e=>e===t))throw new $e(n,`unexpected enum value ${String(t)}`);let i=r.type;if(Array.isArray(i)){if(!i.some(e=>dt(e,t)))throw new $e(n,`expected one of ${i.join(`, `)}`)}else if(typeof i==`string`&&!dt(i,t))throw new $e(n,`expected ${i}`);typeof t==`string`&&ct(r,t,n),typeof t==`number`&&ut(r,t,n),Array.isArray(t)&&ot(r,t,n),gt(t)&&at(r,t,n)}function at(e,t,n){let r=_t(e.required,`${n}#schema.required`,!1),i=e.properties===void 0?{}:mt(e.properties,`${n}#schema.properties`);for(let e of r)if(!(e in t))throw new $e(`${n}.${e}`,`missing required property`);if(e.maxProperties!==void 0&&Object.keys(t).length>vt(e.maxProperties,`${n}#schema.maxProperties`))throw new $e(n,`too many object properties`);for(let[r,a]of Object.entries(t)){let t=i[r];if(t!==void 0)it(t,a,`${n}.${r}`);else if(e.additionalProperties===!1)throw new $e(`${n}.${r}`,`unexpected property`);else gt(e.additionalProperties)&&it(e.additionalProperties,a,`${n}.${r}`)}}function ot(e,t,n){if(e.minItems!==void 0&&t.lengthvt(e.maxItems,`${n}#schema.maxItems`))throw new $e(n,`array longer than maximum`);e.items!==void 0&&t.forEach((t,r)=>it(e.items,t,`${n}[${r}]`))}function st(e){let t=0;for(let n=0;n65535?2:1;return t}function ct(e,t,n){let r=st(t);if(e.minLength!==void 0&&rvt(e.maxLength,`${n}#schema.maxLength`))throw new $e(n,`string longer than maximum`);if(typeof e.pattern==`string`&&!new RegExp(e.pattern,`u`).test(t))throw new $e(n,`string does not match pattern`);if(e.format===`date-time`&&!lt(t))throw new $e(n,`invalid RFC3339 date-time`)}function lt(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 ut(e,t,n){if(!Number.isFinite(t))throw new $e(n,`expected finite number`);if(e.type===`integer`&&!Number.isInteger(t))throw new $e(n,`expected integer`);if(e.minimum!==void 0&&tvt(e.maximum,`${n}#schema.maximum`))throw new $e(n,`number above maximum`)}function dt(e,t){return e===`null`?t===null:e===`array`?Array.isArray(t):e===`object`?gt(t):e===`integer`?typeof t==`number`&&Number.isInteger(t):e===`number`?typeof t==`number`&&Number.isFinite(t):typeof t===e}function ft(e){if(!e.startsWith(`#/`))throw new $e(`$ref`,`unsupported external ref ${e}`);return e.slice(2).split(`/`).map(e=>e.replace(/~1/g,`/`).replace(/~0/g,`~`)).reduce((t,n)=>mt(t,e)[n],et)}function pt(e,t,n){try{return it(e,t,n),!0}catch(e){if(e instanceof $e)return!1;throw e}}function mt(e,t){if(!gt(e))throw new $e(t,`expected object`);return e}function ht(e,t,n){return t.reduce((e,t)=>mt(e,n)[t],e)}function gt(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function _t(e,t,n){if(e===void 0&&!n)return[];if(!Array.isArray(e)||!e.every(e=>typeof e==`string`))throw new $e(t,`expected string array`);return e}function vt(e,t){if(typeof e!=`number`||!Number.isFinite(e))throw new $e(t,`expected numeric schema bound`);return e}function yt(e,t,n){return tt(e,t,n),t}function bt(e,t=`$`){return yt(`ErrorEnvelope`,e,t)}function xt(e,t=`$`){return yt(`BootstrapResponse`,e,t)}function St(e,t=`$`){return yt(`CatalogEntry`,e,t)}function Ct(e,t=`$`){return yt(`CatalogListResponse`,e,t)}function wt(e,t=`$`){return yt(`OperationsListResponse`,e,t)}function Tt(e,t=`$`){return yt(`Operation`,e,t)}function Et(e,t=`$`){return yt(`OperationAccepted`,e,t)}function Dt(e,t=`$`){return yt(`RuntimeSnapshot`,e,t)}function Ot(e,t=`$`){return yt(`UiEvent`,e,t)}var kt=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`}},At=2097152,jt=class{apiBase;fetchImpl;bearerToken=null;onUnauthorized;controllers=new Set;constructor(e={}){this.apiBase=qe(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`,xt,{method:`GET`,signal:e})}async catalog(e={},t){return this.request(`/ui-api/v1/catalog`,Ct,{method:`GET`,query:{...e},signal:t})}async catalogEntry(e,t){return this.request(`/ui-api/v1/catalog/${Ze(e)}`,St,{method:`GET`,signal:t})}async refreshCatalog(e,t){return this.request(`/ui-api/v1/catalog/refresh`,Et,{method:`POST`,body:{idempotency_key:e},signal:t})}async modelAction(e,t){return this.request(`/ui-api/v1/model-actions`,Et,{method:`POST`,body:e,signal:t})}async download(e,t){return this.request(`/ui-api/v1/downloads`,Et,{method:`POST`,body:e,signal:t})}async removeModel(e,t){return this.request(`/ui-api/v1/model-removals`,Et,{method:`POST`,body:e,signal:t})}async operationsPage(e={},t){return this.request(`/ui-api/v1/operations`,wt,{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/${Ze(e)}`,Tt,{method:`GET`,signal:t})}async cancelOperation(e,t){return this.request(`/ui-api/v1/operations/${Ze(e)}/cancel`,Et,{method:`POST`,body:{},signal:t})}async runtime(e,t){let n=await this.request(`/ui-api/v1/runtime`,Dt,{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`,He,{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`,Le,{method:`GET`,query:{model:e,autoload:!1},signal:t})}async patchSettings(e,t,n){return this.request(`/settings`,Re,{method:`PATCH`,query:{model:e,autoload:!1},body:{op:`merge`,values:t},signal:n})}async modelProps(e,t){return this.request(`/props`,ze,{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(Xe(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(Ot(nt(t.data)))}})}async chatCompletions(e,t,n,r){await this.sse(Xe(this.apiBase,`/v1/chat/completions`,{autoload:!1}),{method:`POST`,body:Pt(t,e),signal:r,headers:{Accept:`text/event-stream`}},n)}async responses(e,t,n,r){await this.sse(Xe(this.apiBase,`/v1/responses`,{autoload:!1}),{method:`POST`,body:Pt(t,e),signal:r,headers:{Accept:`text/event-stream`}},n)}async request(e,t,n){let r=await this.fetchWithAuth(Xe(this.apiBase,e,n.query),n);try{return r.response.ok||await this.throwHttp(r.response,r.signal),t(nt(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 We({onDone:n.onDone,onMessage:n.onFrame}),i=e.body.getReader();try{for(;;){let e=await Ft(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}=It(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=bt(nt(n)))}catch{r=null}throw new kt(e.status,Mt(r,n),Nt(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 Ft(n,t);if(e.done)break;if(i+=e.value.byteLength,i>At)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 Mt(e,t){return e===null?null:{...e,error:{...e.error,message:Nt(e.error.message,t),field_errors:e.error.field_errors?.map(e=>({...e,message:Nt(e.message,t)}))}}}function Nt(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 Pt(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 Ft(e,t){if(t.aborted)throw await e.cancel().catch(()=>void 0),Lt();let n=null;try{let r=await Promise.race([e.read(),new Promise((r,i)=>{n=()=>{e.cancel().catch(()=>void 0),i(Lt())},t.addEventListener(`abort`,n,{once:!0})})]);if(t.aborted)throw Lt();return r}finally{n!==null&&t.removeEventListener(`abort`,n)}}function It(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 Lt(){return typeof DOMException==`function`?new DOMException(`The WebUI request was aborted.`,`AbortError`):Error(`The WebUI request was aborted.`)}function Rt(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 zt(e,t){let n=[...e.values()].sort((e,t)=>t.updated_at.localeCompare(e.updated_at)),r=n.filter(e=>!Bt(e)),i=n.filter(e=>Bt(e)&&Date.parse(e.updated_at)>t-36e5).slice(0,200);return new Map([...r,...i].map(e=>[e.operation_id,e]))}function Bt(e){return[`succeeded`,`failed`,`cancelled`].includes(e.state)}var Vt=`webui.ui-api.v1`;function Ht(){return{schemaVersion:Vt,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 Ut(e,t){return t.type===`login-start`?{...e,auth:{status:`authenticating`,tokenPresent:!0},connection:`bootstrapping`,error:null}:t.type===`login-success`?V(e,t.bootstrap,t.now):t.type===`logout`?{...Ht(),lastUpdatedAt:t.now}:t.type===`select-model`?{...e,selectedModelId:t.modelId,runtimeHistory:[]}:t.type===`catalog`?Wt(e,t.response,t.now):t.type===`operations-snapshot`?Gt(e,t.response,t.now):t.type===`operation`?Kt(e,t.operation,t.sequence,t.now):t.type===`runtime`?qt(e,t.runtime,t.sequence,t.now):t.type===`event`?Jt(e,t.event,t.now):t.type===`pending`?{...e,pendingReconciliations:nn(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 V(e,t,n){let r=t.server.server_instance_id;return e.serverInstanceId!==null&&e.serverInstanceId!==r?{...Ht(),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 Wt(e,t,n){if(e.serverInstanceId!==null&&t.server_instance_id!==e.serverInstanceId)return Qt(e,t.server_instance_id,n);if(e.catalogSequence!==null&&t.snapshot_sequenceo.has(e)))};return $t({...e,operations:o,serverInstanceId:t.server_instance_id,lastSequence:tn(s),error:null,resourceFences:s},n)}function Kt(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=zt(nn(e.operations,t.operation_id,t),r),o=n===null?e.resourceFences.operations:nn(e.resourceFences.operations,t.operation_id,n),s={...e.resourceFences,operations:new Map([...o].filter(([e])=>a.has(e)))};return $t({...e,operations:a,lastSequence:tn(s),error:null,resourceFences:s},r)}function qt(e,t,n,r){if(e.serverInstanceId!==null&&t.server_instance_id!==e.serverInstanceId)return Qt(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:nn(e.resourceFences.models,r,t.sequence)};return $t({...e,catalog:a,serverInstanceId:t.server_instance_id,lastEventId:t.event_id,lastSequence:tn(o),connection:`streaming`,resourceFences:o},n)}function Xt(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:nn(e.resourceFences.runtimes,r.model_id,t.sequence)};return $t({...e,runtimes:nn(e.runtimes,r.model_id,r),runtimeHistory:r.model_id===e.selectedModelId?Rt(e.runtimeHistory,r,n):e.runtimeHistory,serverInstanceId:t.server_instance_id,lastEventId:t.event_id,lastSequence:tn(a),connection:`streaming`,resourceFences:a},n)}function Zt(e,t,n){let r=t.type===`server_restart`?null:e.lastSuccessfulAt;return{...Ht(),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 Qt(e,t,n){return{...Ht(),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 $t(e,t){return{...e,lastUpdatedAt:t,lastSuccessfulAt:t}}function en(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 tn(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 nn(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 an=2e3,on=1e4,sn=3e4,cn=6e4,ln=6e4,un=new Set([`snapshot`,`model_revision`]),dn=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??_n,this.visibility=e.visibility??vn,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>=ln}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()})},on);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:pn(n),error:mn(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=fn(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:pn(n),error:mn(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:gn(`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:gn(`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 hn(`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>=cn&&(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 an}backoffDelay(){let e=Math.min(sn,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 fn(e){let t=tn(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 pn(e){if(e instanceof hn)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 mn(e){return e instanceof hn?{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 hn=class extends Error{code=`snapshot_mismatch`;constructor(e){super(e),this.name=`SnapshotConsistencyError`}};function gn(e,t,n){if(n.server_instance_id!==t.server_instance_id)throw new hn(`${e} pagination crossed a server restart; refresh the authoritative snapshot.`);if(n.snapshot_sequence!==t.snapshot_sequence)throw new hn(`${e} pagination crossed snapshot sequence boundaries; refresh the authoritative snapshot.`)}var _n={setTimeout:(e,t)=>globalThis.setTimeout(e,t),clearTimeout:e=>globalThis.clearTimeout(e),now:()=>Date.now()},vn={hidden:()=>typeof document<`u`&&document.hidden,subscribe:e=>typeof document>`u`?()=>void 0:(document.addEventListener(`visibilitychange`,e),()=>document.removeEventListener(`visibilitychange`,e))},yn=_.createContext(null),bn=_.createContext(null);function xn({children:e,apiBase:t,fetchImpl:n}){let[r,i]=_.useReducer(Ut,void 0,Ht),a=_.useRef(r);a.current=r;let o=_.useRef(0),s=_.useRef(null),c=_.useMemo(()=>new jt({apiBase:t,fetchImpl:n,onUnauthorized:()=>{o.current+=1,s.current?.stop(),i({type:`logout`,now:Date.now()})}}),[t,n]);_.useEffect(()=>{let e=new dn({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 kt)&&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)(bn.Provider,{value:l,children:(0,x.jsx)(yn.Provider,{value:r,children:e})})}function Sn(){let e=_.useContext(yn);if(e===null)throw Error(`useWebUi must be used within WebUiProvider.`);return e}function Cn(){let e=_.useContext(bn);if(e===null)throw Error(`useWebUiActions must be used within WebUiProvider.`);return e}var wn=Object.freeze({}),Tn=[`max_tokens`,`temperature`,`top_p`,`top_k`,`min_p`,`repetition_penalty`,`seed`];function En(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(!Tn.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 Dn=wn,On=new Set;function kn(e){return On.add(e),()=>On.delete(e)}function An(e){Dn=En(e);for(let e of On)e()}function jn(){An(wn)}function Mn(){return{defaults:(0,_.useSyncExternalStore)(kn,()=>Dn,()=>wn),setDefaults:An,reset:jn}}function Nn(e,t,n){return e===null||e<=0||t===null||n===void 0?`unknown`:t+n>e?`exceeds`:`raw-fits`}function Pn({modelId:e,nCtx:t,locale:n}){let r=Cn(),{defaults:i}=Mn(),[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=Nn(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)(Ce,{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 Fn(e){return e instanceof kt?e.status===401?`wrong-key`:e.status===403?`forbidden`:`generic`:e instanceof $e||e instanceof Error&&e.name===`ValidationError`?`schema`:e instanceof TypeError||e instanceof Error&&/fetch|network|offline|connection/i.test(e.message)?`offline`:`generic`}function In(e,t){let n=Kn(t);return n===null?R(e,`model.selected.none`):`${n.identity.display_name} · ${qn(e,n.lifecycle.state)}`}function Ln(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,sequence:Jn(e,t),status:Rn(e,t.connection)})}function Rn(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 zn(e){return e.snapshot.auth.status===`authenticated`?e.snapshot.connection===`schema-mismatch`?(0,x.jsx)(Hn,{...e}):(0,x.jsx)(Vn,{...e}):(0,x.jsx)(Bn,{...e})}function Bn(e){return e.authFailure===`schema`?(0,x.jsx)(Hn,{...e}):(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsxs)(`section`,{className:`screen-heading connection-prompt`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:e.eyebrow}),(0,x.jsx)(`h1`,{"data-testid":e.titleTestId,children:e.title}),(0,x.jsx)(`p`,{"data-testid":z(`connection.prompt.body`),children:R(e.locale,`connection.prompt.body`)})]}),(0,x.jsx)(Ne,{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:Gn(e.locale,e.authFailure),busy:e.snapshot.auth.status===`authenticating`,onSubmit:e.onLogin,onLogout:e.onLogout,testId:z(`auth.login`)})]})}function Vn(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.jsxs)(`section`,{className:`screen-heading connection-prompt`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:e.eyebrow}),(0,x.jsx)(`h1`,{"data-testid":e.titleTestId,children:e.title}),(0,x.jsx)(`p`,{"data-testid":z(`connection.authenticated.body`),children:R(e.locale,`connection.authenticated.body`)})]}),(0,x.jsx)(B,{tone:`info`,title:R(e.locale,`connection.authenticated.title`),body:Un(e.locale,e.snapshot),testId:z(`connection.authenticated.detail`)}),t?(0,x.jsx)(B,{title:R(e.locale,`connection.error.title`),body:Wn(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 Hn(e){return(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsxs)(`section`,{className:`screen-heading connection-prompt`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:e.eyebrow}),(0,x.jsx)(`h1`,{"data-testid":e.titleTestId,children:e.title})]}),(0,x.jsx)(Pe,{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 Un(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:Rn(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:Jn(e,t)})}function Wn(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 Gn(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 Kn(e){return e.selectedModelId===null?null:e.catalog.find(t=>t.identity.id===e.selectedModelId)??null}function qn(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 Jn(e,t){return String(t.lastSequence??t.catalogSequence??t.resourceFences.operationsSnapshot??R(e,`connection.snapshot.pending`))}function Yn({locale:e}){let{defaults:t,setDefaults:n,reset:r}=Mn(),[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:Tn.map(n=>(0,x.jsx)(Ce,{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)(B,{title:R(e,`settings.generation.error_title`),body:o}):null,(0,x.jsxs)(`div`,{children:[(0,x.jsx)(N,{onClick:()=>{try{n(En(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)(Ce,{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)(Ee,{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 Xn({modelId:e,locale:t}){let n=Cn(),[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]=Be(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:Ve(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)(B,{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)(Ce,{label:e.name,value:a[e.name]??Ve(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)(Ce,{label:e.name,value:Ve(e,r.current[e.name]),disabled:!0,hint:e.reason??e.help},e.name))]}),(0,x.jsxs)(Ee,{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,Ve(e,e.default)]))),c({}),m(!1)},children:R(t,`settings.live.reset.confirm`)})]})]})}var Zn=[`fp16`,`float16`,`int8`,`i8`,`turbo4-asym`,`fp16+turbo4`,`turbo3-asym`,`fp16+turbo3`,`turbo3`,`turbo4`,`turbo4-sym`,`turbo4-delegated`,`fp16+turbo4-delegated`],Qn=Object.freeze({});function $n(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`||!Zn.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 er(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:$n(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]=$n(t)}return{version:1,reusable:$n(n.reusable),models:r}}var tr=`mlxcel.webui.load-profiles.v1`,nr={version:1,reusable:Qn,models:{}},rr=!1,ir=new Set;function ar(e){return ir.add(e),()=>ir.delete(e)}function or(){if(!rr){rr=!0;try{let e=localStorage.getItem(tr);e!==null&&(nr=er(e))}catch{}}}function sr(e){let t=JSON.stringify(e),n=er(t);localStorage.setItem(tr,t),nr=n;for(let e of ir)e()}function cr(e){or();let t=(0,_.useSyncExternalStore)(ar,()=>nr);return{reusable:t.reusable,modelProfile:e===null?Qn:t.models[e]??Qn,profile:e!==null&&Object.hasOwn(t.models,e)?t.models[e]:t.reusable,save:(t,n)=>{let r=$n(t);if(n===`model`&&e===null)throw Error(`Select a model first.`);sr(n===`reusable`?{...nr,reusable:r}:{...nr,models:{...nr.models,[e]:r}})},reset:(t=e===null?`reusable`:`model`)=>{let n=Object.fromEntries(Object.entries(nr.models).filter(([t])=>t!==e));sr(t===`reusable`?{...nr,reusable:Qn}:{...nr,models:n})},exportJson:()=>JSON.stringify(nr,null,2),importJson:e=>sr(er(e))}}function lr(e){let t=$n(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=cr(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)(B,{tone:`info`,title:R(t,`settings.profile.single.title`),body:R(t,`settings.profile.single.body`)}):null,(0,x.jsx)(Se,{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)(Ce,{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)(Ce,{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)(Se,{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`)},...Zn.map(e=>({value:e,label:e}))]})]}),(0,x.jsx)(`p`,{children:R(t,`settings.profile.restrictions`)}),u?(0,x.jsx)(B,{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($n(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:lr(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)(Ee,{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 dr({locale:e}){let t=Sn(),n=Cn(),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)(Yn,{locale:e}),o?(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(Se,{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} · ${qn(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)(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:R(e,`settings.server.context.title`)}),(0,x.jsx)(Ce,{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)(Ce,{label:R(e,`settings.server.context.slots`),value:i?.totalSlots?.toString()??c,disabled:!0}),(0,x.jsx)(Ce,{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)(Pn,{modelId:s,nCtx:i?.nCtx??null,locale:e},s)]}),s===null?(0,x.jsx)(B,{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)(Xn,{modelId:s,locale:e},s):(0,x.jsx)(B,{tone:`info`,title:R(e,`settings.server.live_disabled.title`),body:R(e,`settings.server.live_disabled.body`)})]}):(0,x.jsx)(B,{tone:`warning`,title:R(e,`settings.server.unavailable.title`),body:R(e,`settings.server.unavailable.body`)})]})}var fr=[{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 pr(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]`);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)},[]);let o=n=>{let r=fr[(fr.findIndex(t=>t.id===e.route)+n+fr.length)%fr.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)(mr,{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)(Oe,{open:i,title:R(e.locale,`nav.primary`),onClose:()=>a(!1),closeLabel:R(e.locale,`common.close`),testId:`mobile-nav-sheet`,children:(0,x.jsx)(mr,{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`,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:()=>a(!0),"data-testid":z(`toolbar.menu`)}),(0,x.jsxs)(`div`,{className:`toolbar-title`,children:[(0,x.jsx)(`p`,{id:`app-title`,"data-testid":z(`app.title`),children:R(e.locale,`app.title`)}),(0,x.jsx)(`span`,{"data-testid":z(`app.subtitle`),children:R(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)(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)(`section`,{className:`app-content`,children:e.children}),e.inspector]})]})]})}var mr=_.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:fr.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.jsx)(`span`,{className:`connection-dot`,"data-state":e.connectionState,"aria-hidden":`true`}),(0,x.jsx)(`span`,{"data-testid":z(`connection.ready`),children:e.connectionLabel})]})]}));mr.displayName=`Sidebar`;var hr={theme:`system`,material:`glass`,glassIntensity:35,reduceMotion:!1,reduceTransparency:!1,highContrast:`system`,locale:`en`},gr=`mlxcel.webui.appearance`;function _r(e){let t=typeof e==`number`&&Number.isFinite(e)?e:hr.glassIntensity;return Math.max(0,Math.min(100,Math.round(t)))}function vr(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function yr(e){return e===`system`||e===`light`||e===`dark`}function br(e){return e===`glass`||e===`tinted`||e===`opaque`}function xr(e){return e===`system`||e===`on`||e===`off`}function Sr(e){return xr(e)?e:e===!0?`on`:e===!1?`off`:hr.highContrast}function Cr(e){return e===`en`||e===`ko`}function wr(){if(typeof window>`u`)return hr;let e;try{e=window.localStorage.getItem(gr)}catch{return hr}if(!e)return hr;try{let t=JSON.parse(e);return vr(t)?{theme:yr(t.theme)?t.theme:hr.theme,material:br(t.material)?t.material:hr.material,glassIntensity:_r(t.glassIntensity),reduceMotion:t.reduceMotion===!0,reduceTransparency:t.reduceTransparency===!0,highContrast:Sr(t.highContrast),locale:Cr(t.locale)?t.locale:hr.locale}:hr}catch{return hr}}function Tr(e){try{window.localStorage.setItem(gr,JSON.stringify(e))}catch{}}function Er(){return typeof CSS>`u`||typeof CSS.supports!=`function`?!1:CSS.supports(`backdrop-filter: blur(1px)`)||CSS.supports(`-webkit-backdrop-filter: blur(1px)`)}function Dr(e,t){e.dataset.theme=t.theme,e.dataset.material=t.reduceTransparency?`opaque`:t.material,e.dataset.glassIntensity=String(_r(t.glassIntensity)),e.dataset.reduceMotion=String(t.reduceMotion),e.dataset.reduceTransparency=String(t.reduceTransparency),e.dataset.highContrast=t.highContrast,e.dataset.backdropFilter=Er()?`supported`:`unsupported`,e.lang=t.locale}function Or(e){return e.value===null||!Number.isFinite(e.value)?`N/A`:`${new Intl.NumberFormat(void 0,{maximumFractionDigits:2}).format(e.value)} ${e.unit}`}function kr(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 Ar(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 jr(e){let t=URL.createObjectURL(new Blob([Ar(e)],{type:`application/json`})),n=document.createElement(`a`);n.href=t,n.download=`mlxcel-diagnostics.json`,n.click(),URL.revokeObjectURL(t)}function Mr({operations:e,locale:t,stale:n}){let r=[...e.values()].sort((e,t)=>Number(Bt(e))-Number(Bt(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=>!Bt(e)).length),failed:String(r.filter(e=>e.state===`failed`).length)})}),(0,x.jsx)(`p`,{children:R(t,`activity.session`)}),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)(Nr,{operation:e,locale:t,stale:n})},e.operation_id))})]})}function Nr({operation:e,locale:t,stale:n}){let r=Cn(),i=Sn(),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=Bt(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:kr(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)(B,{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)(B,{title:R(t,`activity.cancel_failed`),body:R(t,`activity.refresh`)}):null]})}var Pr=new Set(be.map(e=>e.key).filter(e=>e.startsWith(`activity.metric.`))),Fr=e=>Pr.has(e);function Ir({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 Fr(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)(B,{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.jsxs)(`dl`,{className:`activity-metric`,children:[(0,x.jsx)(`dt`,{children:s(e)}),(0,x.jsx)(`dd`,{children:Or(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.jsxs)(`dl`,{className:`activity-metric`,children:[(0,x.jsx)(`dt`,{children:s(e)}),(0,x.jsx)(`dd`,{children:Or(n)}),(0,x.jsxs)(`dd`,{children:[R(t,`activity.scope`),`: `,n.scope]}),(0,x.jsxs)(`dd`,{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)(`dd`,{children:n.reason})]},e))})]})]})}var Lr=(function(){let e=typeof document<`u`&&document.createElement(`link`).relList;return e&&e.supports&&e.supports(`modulepreload`)?`modulepreload`:`preload`})(),Rr=function(e,t){return new URL(e,t).href},zr={},Br=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=Rr(t,n),t=s(t),t in zr)return;zr[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`:Lr,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)})},Vr=(0,_.lazy)(()=>Br(()=>import(`./history-BhdDGTqa.js`),[],import.meta.url));function Hr({locale:e}){let t=Sn(),n=Cn(),[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":z(`activity.title`),children:R(e,`activity.title`)}),(0,x.jsx)(`p`,{children:R(e,`activity.intro`)}),(0,x.jsxs)(`p`,{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)(Se,{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.jsxs)(`div`,{className:`activity-toolbar`,children:[(0,x.jsx)(N,{onClick:()=>{n.refresh()},children:R(e,`activity.refresh`)}),(0,x.jsx)(N,{onClick:()=>jr(t),children:R(e,`activity.export`)})]}),a?(0,x.jsx)(B,{tone:`warning`,title:R(e,`activity.stale`),body:R(e,`activity.refresh`)}):null,(0,x.jsx)(Mr,{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)(Ir,{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)(Vr,{samples:t.runtimeHistory,locale:e})}):null]})}var Ur=e=>[`succeeded`,`failed`,`cancelled`].includes(e.state),Wr=e=>e.auth.status===`authenticated`&&e.bootstrap!==null&&e.catalogSequence!==null&&[`ready`,`streaming`,`polling`].includes(e.connection);function Gr(e,t){return Wr(e)&&e.bootstrap?.actions[t]?.state===`enabled`}function Kr(e,t){return[...e.operations.values()].some(e=>!Ur(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 qr(e,t){return Gr(e,`load`)&&t.supported&&t.complete&&t.metadata.support.runnable_on_backend&&!t.lifecycle.busy&&[`unloaded`,`failed`].includes(t.lifecycle.state)&&!Kr(e,t.identity.id)}function Jr(e,t){return Gr(e,`unload`)&&t.lifecycle.state===`ready`&&!Kr(e,t.identity.id)}function Yr(e,t){return Gr(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)&&!Kr(e,t.identity.id)}function Xr(e,t){return Wr(e)&&t.lifecycle.state===`ready`&&t.capabilities.some(e=>e.task===`chat`&&e.phase===`provider_ready`&&e.available)}function Zr(e,t){return e.catalog.filter(n=>n.identity.id!==t&&Jr(e,n)&&!n.lifecycle.busy&&n.lifecycle.active_requests===0&&n.lifecycle.draining_requests===0)}function Qr(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 $r(e,t){return e instanceof kt?e.envelope?.error.code===`stale_revision`?R(t,`models.library.stale`):e.message:R(t,`models.library.pending`)}function ei(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 ti(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 ni(e){return e.length===0||e.length<=128&&e.split(`/`).every(e=>e!==`.`&&e!==`..`&&/^[A-Za-z0-9._~+-]+$/.test(e))}function ri({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`?Zr(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)(Ee,{open:!0,title:f,onClose:i,closeLabel:R(n,`common.close`),testId:`models-confirm`,children:[(0,x.jsx)(`p`,{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)(Ce,{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`,{children:[e.identity.display_name,` · `,e.lifecycle.state,` · `,R(n,`models.library.active`),`:`,` `,e.lifecycle.active_requests]},e.identity.id))}),(0,x.jsx)(Se,{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 ii({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=ti(s.trim())&&ni(l.trim());return(0,x.jsx)(Ee,{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)(Ce,{label:R(e,`models.library.repo`),value:s,onChange:c,testId:`models-repo`,error:s&&!ti(s.trim())?R(e,`models.library.repo_invalid`):void 0}),(0,x.jsx)(Ce,{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 ai({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 oi({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`),Qr(s.disk_bytes,r)],[R(r,`models.library.memory`),Qr(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)(Ae,{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:qn(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)(ai,{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||!qr(n,e),onClick:()=>a(`load`),children:R(r,`models.load`)}),(0,x.jsx)(N,{"data-testid":`models-use-chat`,disabled:i||!Xr(n,e),onClick:o,children:R(r,`models.library.chat`)}),(0,x.jsx)(N,{"data-testid":`models-unload`,disabled:i||!Jr(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||!Yr(n,e),onClick:()=>a(`delete`),children:R(r,`models.library.delete`)}):null]}),Xr(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 si({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(Ur(e))-Number(Ur(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:li(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:`${Qr(s.progress.completed_bytes,t)} / ${Qr(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===ci(s)&&qr(e,t)),onClick:()=>o(ci(s)),children:R(t,`models.library.capacity`)}):null,s.kind===`download`&&!Ur(s)?(0,x.jsx)(N,{disabled:n||!Wr(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||!Gr(e,`download`),onClick:()=>a(s),children:R(t,`models.library.retry_download`)}):null]})]})},s.operation_id))})]})}function ci(e){return e.target.target_kind===`model`?e.target.model_id:``}function li(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 ui=25;function di({locale:e}){let t=Sn(),n=Cn(),[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}=cr(y?.identity.id??null),{profile:S}=cr(f?.kind===`capacity`?f.entry.identity.id:null),C=ei(t.catalog,r),w=Math.max(1,Math.ceil(C.length/ui)),T=Math.min(a,w-1),E=[...t.operations.values()].some(e=>e.kind===`download`&&!Ur(e))||[...t.pendingReconciliations.values()].some(e=>e.kind===`download`),D=[...t.operations.values()].some(e=>e.kind===`catalog_refresh`&&!Ur(e))||[...t.pendingReconciliations.values()].some(e=>e.kind===`catalog-refresh`),O=e=>{i({...r,...e}),o(0)},k=async(n,r)=>{if(l.current||!Wr(t))return!1;l.current=!0,c(!0),d(null);try{return await n(),!0}catch(t){return d($r(t,e)),r?.(t),!1}finally{l.current=!1,c(!1)}},ee=(r,i,a=b)=>{if(!qr(t,r)){d(R(e,`models.library.stale`));return}if(i&&!Zr(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 kt&&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||Ur(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(!Zr(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`&&Jr(t,o)?k(()=>n.unloadModel({action:`unload`,model_id:o.identity.id,expected_revision:o.identity.revision,idempotency_key:crypto.randomUUID()})):a.kind===`delete`&&Yr(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`,"aria-label":R(e,`models.library.inspect`,{name:r.identity.display_name}),onClick:()=>n.selectModel(r.identity.id),children:r.identity.display_name}),r.identity.id===t.selectedModelId?(0,x.jsx)(`small`,{children:R(e,`models.library.selected`)}):null,(0,x.jsxs)(`p`,{children:[r.identity.source,` · `,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:qn(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.jsxs)(`section`,{className:`screen-heading`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:R(e,`routes.models.eyebrow`)}),(0,x.jsx)(`h1`,{tabIndex:-1,"data-dialog-focus-fallback":!0,"data-testid":z(`models.title`),children:R(e,`models.title`)}),(0,x.jsx)(`p`,{children:R(e,`models.library.subtitle`)})]}),Wr(t)?null:(0,x.jsx)(B,{title:R(e,`models.library.stale`),body:t.error?.message??R(e,`models.library.waiting`),action:(0,x.jsx)(N,{onClick:()=>{n.refresh()},children:R(e,`models.library.refresh`)}),testId:`connection-error-title`}),u?(0,x.jsx)(B,{title:R(e,`models.library.error`),body:u,action:(0,x.jsx)(N,{onClick:()=>{d(null),n.refresh()},children:R(e,`models.library.refresh`)}),testId:`models-action-error`}):null,t.bootstrap?.server.mode===`single_model`?(0,x.jsx)(B,{tone:`info`,title:R(e,`models.library.single`),body:`mlxcel-server --webui`,testId:`models-read-only`}):null,(0,x.jsxs)(`div`,{className:`button-row`,children:[(0,x.jsx)(N,{tone:`primary`,onClick:()=>h({repo:``,revision:``}),disabled:s||E||!Gr(t,`download`),"data-testid":`models-add`,children:R(e,`models.library.add`)}),(0,x.jsx)(N,{disabled:s||D||!Wr(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`)})]}),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:Un(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)(Ce,{label:R(e,`models.library.search`),value:r.query,onChange:e=>O({query:e}),testId:`models-search`}),(0,x.jsx)(Se,{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)(Se,{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)(Se,{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:qn(e,t)}))]}),(0,x.jsx)(Se,{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)(he,{columns:M,rows:C.slice(T*ui,(T+1)*ui),getRowKey:e=>e.identity.id,ariaLabel:R(e,`models.title`),testId:`models-table`,rowClassName:e=>e.identity.id===t.selectedModelId?`models-selected`:void 0,loading:t.catalogSequence===null,loadingState:(0,x.jsx)(`p`,{role:`status`,children: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)(oi,{entry:y,profile:b,state:t,locale:e,busy:s,onAction:A,onChat:()=>{Xr(t,y)&&(n.selectModel(y.identity.id),window.location.hash=`chat`)}}):null]}),(0,x.jsx)(si,{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&&qr(t,n)&&p({kind:`capacity`,entry:n,instance:t.serverInstanceId})}}),f?(0,x.jsx)(ri,{value:f,state:t,locale:e,busy:s,onClose:()=>p(null),onConfirm:te},f.kind):null,m?(0,x.jsx)(ii,{locale:e,state:t,initial:m,error:u,busy:s||E||!Gr(t,`download`),onClose:()=>h(null),onDownload:(e,r)=>{Gr(t,`download`)&&!E&&k(()=>n.downloadModel({repo_id:e,revision:r||null,idempotency_key:crypto.randomUUID()})).then(e=>{e&&h(null)})}}):null]})}var fi={en:`en-US`,ko:`ko-KR`},pi=e=>fi[e];function mi(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)(vi,{locale:e.locale})},{id:`data`,label:R(e.locale,`gallery.tab.data`),panel:(0,x.jsx)(yi,{locale:e.locale})}]}),(0,x.jsxs)(Ee,{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)(Ce,{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 _i(e){return(0,x.jsxs)(`div`,{className:`gallery-grid`,children:[(0,x.jsxs)(`article`,{className:`surface-card`,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)(Ce,{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)(Se,{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)(`article`,{className:`surface-card`,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)(ke,{label: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 vi(e){return(0,x.jsxs)(`div`,{className:`gallery-grid`,children:[(0,x.jsx)(Ne,{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)(Pe,{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)(B,{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:mi(67108864,e.locale)})}),(0,x.jsx)(fe,{label:R(e.locale,`gallery.progress.measured`),value:37})]}),(0,x.jsxs)(Me,{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 yi(e){return(0,x.jsxs)(`div`,{className:`gallery-grid dense-gallery`,children:[(0,x.jsxs)(`article`,{className:`surface-card table-card`,tabIndex:0,"aria-label":R(e.locale,`gallery.sample.caption`),children:[(0,x.jsx)(`h2`,{children:R(e.locale,`gallery.data.title`)}),(0,x.jsxs)(je,{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:hi(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:hi(null,e.locale)})]})]})]})]}),(0,x.jsxs)(Ae,{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`)})]})]})}var bi={count:4,bytes:8388608,dimension:4096,pixels:16e6},xi=new Set([`image/png`,`image/jpeg`,`image/webp`]);function Si(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 +`,$e=class extends Error{path;constructor(e,t){super(`${e}: ${t}`),this.path=e,this.name=`ValidationError`}},et=rt(Qe);function tt(e,t,n=`$`){let r=ht(et,[`components`,`schemas`],`#/components/schemas`)[e];if(r===void 0)throw new $e(n,`unknown schema ${e}`);it(r,t,n)}function nt(e){return JSON.parse(e)}function rt(e){return mt(nt(e),`$contract`)}function it(e,t,n){let r=mt(e,`${n}#schema`);if(typeof r.$ref==`string`){it(ft(r.$ref),t,n);return}if(r.anyOf!==void 0){if(!Array.isArray(r.anyOf)||!r.anyOf.some(e=>pt(e,t,n)))throw new $e(n,`did not match any allowed schema`);return}if(r.oneOf!==void 0){if(!Array.isArray(r.oneOf))throw new $e(n,`schema oneOf must be an array`);let e=r.oneOf.filter(e=>pt(e,t,n)).length;if(e!==1)throw new $e(n,`matched ${e} oneOf schemas`);return}if(r.const!==void 0&&t!==r.const)throw new $e(n,`expected constant ${String(r.const)}`);if(Array.isArray(r.enum)&&!r.enum.some(e=>e===t))throw new $e(n,`unexpected enum value ${String(t)}`);let i=r.type;if(Array.isArray(i)){if(!i.some(e=>dt(e,t)))throw new $e(n,`expected one of ${i.join(`, `)}`)}else if(typeof i==`string`&&!dt(i,t))throw new $e(n,`expected ${i}`);typeof t==`string`&&ct(r,t,n),typeof t==`number`&&ut(r,t,n),Array.isArray(t)&&ot(r,t,n),gt(t)&&at(r,t,n)}function at(e,t,n){let r=_t(e.required,`${n}#schema.required`,!1),i=e.properties===void 0?{}:mt(e.properties,`${n}#schema.properties`);for(let e of r)if(!(e in t))throw new $e(`${n}.${e}`,`missing required property`);if(e.maxProperties!==void 0&&Object.keys(t).length>vt(e.maxProperties,`${n}#schema.maxProperties`))throw new $e(n,`too many object properties`);for(let[r,a]of Object.entries(t)){let t=i[r];if(t!==void 0)it(t,a,`${n}.${r}`);else if(e.additionalProperties===!1)throw new $e(`${n}.${r}`,`unexpected property`);else gt(e.additionalProperties)&&it(e.additionalProperties,a,`${n}.${r}`)}}function ot(e,t,n){if(e.minItems!==void 0&&t.lengthvt(e.maxItems,`${n}#schema.maxItems`))throw new $e(n,`array longer than maximum`);e.items!==void 0&&t.forEach((t,r)=>it(e.items,t,`${n}[${r}]`))}function st(e){let t=0;for(let n=0;n65535?2:1;return t}function ct(e,t,n){let r=st(t);if(e.minLength!==void 0&&rvt(e.maxLength,`${n}#schema.maxLength`))throw new $e(n,`string longer than maximum`);if(typeof e.pattern==`string`&&!new RegExp(e.pattern,`u`).test(t))throw new $e(n,`string does not match pattern`);if(e.format===`date-time`&&!lt(t))throw new $e(n,`invalid RFC3339 date-time`)}function lt(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 ut(e,t,n){if(!Number.isFinite(t))throw new $e(n,`expected finite number`);if(e.type===`integer`&&!Number.isInteger(t))throw new $e(n,`expected integer`);if(e.minimum!==void 0&&tvt(e.maximum,`${n}#schema.maximum`))throw new $e(n,`number above maximum`)}function dt(e,t){return e===`null`?t===null:e===`array`?Array.isArray(t):e===`object`?gt(t):e===`integer`?typeof t==`number`&&Number.isInteger(t):e===`number`?typeof t==`number`&&Number.isFinite(t):typeof t===e}function ft(e){if(!e.startsWith(`#/`))throw new $e(`$ref`,`unsupported external ref ${e}`);return e.slice(2).split(`/`).map(e=>e.replace(/~1/g,`/`).replace(/~0/g,`~`)).reduce((t,n)=>mt(t,e)[n],et)}function pt(e,t,n){try{return it(e,t,n),!0}catch(e){if(e instanceof $e)return!1;throw e}}function mt(e,t){if(!gt(e))throw new $e(t,`expected object`);return e}function ht(e,t,n){return t.reduce((e,t)=>mt(e,n)[t],e)}function gt(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function _t(e,t,n){if(e===void 0&&!n)return[];if(!Array.isArray(e)||!e.every(e=>typeof e==`string`))throw new $e(t,`expected string array`);return e}function vt(e,t){if(typeof e!=`number`||!Number.isFinite(e))throw new $e(t,`expected numeric schema bound`);return e}function yt(e,t,n){return tt(e,t,n),t}function bt(e,t=`$`){return yt(`ErrorEnvelope`,e,t)}function xt(e,t=`$`){return yt(`BootstrapResponse`,e,t)}function St(e,t=`$`){return yt(`CatalogEntry`,e,t)}function Ct(e,t=`$`){return yt(`CatalogListResponse`,e,t)}function wt(e,t=`$`){return yt(`OperationsListResponse`,e,t)}function Tt(e,t=`$`){return yt(`Operation`,e,t)}function Et(e,t=`$`){return yt(`OperationAccepted`,e,t)}function Dt(e,t=`$`){return yt(`RuntimeSnapshot`,e,t)}function Ot(e,t=`$`){return yt(`UiEvent`,e,t)}var kt=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`}},At=2097152,jt=class{apiBase;fetchImpl;bearerToken=null;onUnauthorized;controllers=new Set;constructor(e={}){this.apiBase=qe(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`,xt,{method:`GET`,signal:e})}async catalog(e={},t){return this.request(`/ui-api/v1/catalog`,Ct,{method:`GET`,query:{...e},signal:t})}async catalogEntry(e,t){return this.request(`/ui-api/v1/catalog/${Ze(e)}`,St,{method:`GET`,signal:t})}async refreshCatalog(e,t){return this.request(`/ui-api/v1/catalog/refresh`,Et,{method:`POST`,body:{idempotency_key:e},signal:t})}async modelAction(e,t){return this.request(`/ui-api/v1/model-actions`,Et,{method:`POST`,body:e,signal:t})}async download(e,t){return this.request(`/ui-api/v1/downloads`,Et,{method:`POST`,body:e,signal:t})}async removeModel(e,t){return this.request(`/ui-api/v1/model-removals`,Et,{method:`POST`,body:e,signal:t})}async operationsPage(e={},t){return this.request(`/ui-api/v1/operations`,wt,{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/${Ze(e)}`,Tt,{method:`GET`,signal:t})}async cancelOperation(e,t){return this.request(`/ui-api/v1/operations/${Ze(e)}/cancel`,Et,{method:`POST`,body:{},signal:t})}async runtime(e,t){let n=await this.request(`/ui-api/v1/runtime`,Dt,{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`,He,{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`,Le,{method:`GET`,query:{model:e,autoload:!1},signal:t})}async patchSettings(e,t,n){return this.request(`/settings`,Re,{method:`PATCH`,query:{model:e,autoload:!1},body:{op:`merge`,values:t},signal:n})}async modelProps(e,t){return this.request(`/props`,ze,{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(Xe(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(Ot(nt(t.data)))}})}async chatCompletions(e,t,n,r){await this.sse(Xe(this.apiBase,`/v1/chat/completions`,{autoload:!1}),{method:`POST`,body:Pt(t,e),signal:r,headers:{Accept:`text/event-stream`}},n)}async responses(e,t,n,r){await this.sse(Xe(this.apiBase,`/v1/responses`,{autoload:!1}),{method:`POST`,body:Pt(t,e),signal:r,headers:{Accept:`text/event-stream`}},n)}async request(e,t,n){let r=await this.fetchWithAuth(Xe(this.apiBase,e,n.query),n);try{return r.response.ok||await this.throwHttp(r.response,r.signal),t(nt(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 We({onDone:n.onDone,onMessage:n.onFrame}),i=e.body.getReader();try{for(;;){let e=await Ft(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}=It(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=bt(nt(n)))}catch{r=null}throw new kt(e.status,Mt(r,n),Nt(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 Ft(n,t);if(e.done)break;if(i+=e.value.byteLength,i>At)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 Mt(e,t){return e===null?null:{...e,error:{...e.error,message:Nt(e.error.message,t),field_errors:e.error.field_errors?.map(e=>({...e,message:Nt(e.message,t)}))}}}function Nt(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 Pt(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 Ft(e,t){if(t.aborted)throw await e.cancel().catch(()=>void 0),Lt();let n=null;try{let r=await Promise.race([e.read(),new Promise((r,i)=>{n=()=>{e.cancel().catch(()=>void 0),i(Lt())},t.addEventListener(`abort`,n,{once:!0})})]);if(t.aborted)throw Lt();return r}finally{n!==null&&t.removeEventListener(`abort`,n)}}function It(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 Lt(){return typeof DOMException==`function`?new DOMException(`The WebUI request was aborted.`,`AbortError`):Error(`The WebUI request was aborted.`)}function Rt(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 zt(e,t){let n=[...e.values()].sort((e,t)=>t.updated_at.localeCompare(e.updated_at)),r=n.filter(e=>!Bt(e)),i=n.filter(e=>Bt(e)&&Date.parse(e.updated_at)>t-36e5).slice(0,200);return new Map([...r,...i].map(e=>[e.operation_id,e]))}function Bt(e){return[`succeeded`,`failed`,`cancelled`].includes(e.state)}var Vt=`webui.ui-api.v1`;function Ht(){return{schemaVersion:Vt,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 Ut(e,t){return t.type===`login-start`?{...e,auth:{status:`authenticating`,tokenPresent:!0},connection:`bootstrapping`,error:null}:t.type===`login-success`?V(e,t.bootstrap,t.now):t.type===`logout`?{...Ht(),lastUpdatedAt:t.now}:t.type===`select-model`?{...e,selectedModelId:t.modelId,runtimeHistory:[]}:t.type===`catalog`?Wt(e,t.response,t.now):t.type===`operations-snapshot`?Gt(e,t.response,t.now):t.type===`operation`?Kt(e,t.operation,t.sequence,t.now):t.type===`runtime`?qt(e,t.runtime,t.sequence,t.now):t.type===`event`?Jt(e,t.event,t.now):t.type===`pending`?{...e,pendingReconciliations:nn(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 V(e,t,n){let r=t.server.server_instance_id;return e.serverInstanceId!==null&&e.serverInstanceId!==r?{...Ht(),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 Wt(e,t,n){if(e.serverInstanceId!==null&&t.server_instance_id!==e.serverInstanceId)return Qt(e,t.server_instance_id,n);if(e.catalogSequence!==null&&t.snapshot_sequenceo.has(e)))};return $t({...e,operations:o,serverInstanceId:t.server_instance_id,lastSequence:tn(s),error:null,resourceFences:s},n)}function Kt(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=zt(nn(e.operations,t.operation_id,t),r),o=n===null?e.resourceFences.operations:nn(e.resourceFences.operations,t.operation_id,n),s={...e.resourceFences,operations:new Map([...o].filter(([e])=>a.has(e)))};return $t({...e,operations:a,lastSequence:tn(s),error:null,resourceFences:s},r)}function qt(e,t,n,r){if(e.serverInstanceId!==null&&t.server_instance_id!==e.serverInstanceId)return Qt(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:nn(e.resourceFences.models,r,t.sequence)};return $t({...e,catalog:a,serverInstanceId:t.server_instance_id,lastEventId:t.event_id,lastSequence:tn(o),connection:`streaming`,resourceFences:o},n)}function Xt(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:nn(e.resourceFences.runtimes,r.model_id,t.sequence)};return $t({...e,runtimes:nn(e.runtimes,r.model_id,r),runtimeHistory:r.model_id===e.selectedModelId?Rt(e.runtimeHistory,r,n):e.runtimeHistory,serverInstanceId:t.server_instance_id,lastEventId:t.event_id,lastSequence:tn(a),connection:`streaming`,resourceFences:a},n)}function Zt(e,t,n){let r=t.type===`server_restart`?null:e.lastSuccessfulAt;return{...Ht(),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 Qt(e,t,n){return{...Ht(),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 $t(e,t){return{...e,lastUpdatedAt:t,lastSuccessfulAt:t}}function en(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 tn(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 nn(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 an=2e3,on=1e4,sn=3e4,cn=6e4,ln=6e4,un=new Set([`snapshot`,`model_revision`]),dn=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??_n,this.visibility=e.visibility??vn,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>=ln}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()})},on);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:pn(n),error:mn(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=fn(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:pn(n),error:mn(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:gn(`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:gn(`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 hn(`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>=cn&&(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 an}backoffDelay(){let e=Math.min(sn,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 fn(e){let t=tn(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 pn(e){if(e instanceof hn)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 mn(e){return e instanceof hn?{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 hn=class extends Error{code=`snapshot_mismatch`;constructor(e){super(e),this.name=`SnapshotConsistencyError`}};function gn(e,t,n){if(n.server_instance_id!==t.server_instance_id)throw new hn(`${e} pagination crossed a server restart; refresh the authoritative snapshot.`);if(n.snapshot_sequence!==t.snapshot_sequence)throw new hn(`${e} pagination crossed snapshot sequence boundaries; refresh the authoritative snapshot.`)}var _n={setTimeout:(e,t)=>globalThis.setTimeout(e,t),clearTimeout:e=>globalThis.clearTimeout(e),now:()=>Date.now()},vn={hidden:()=>typeof document<`u`&&document.hidden,subscribe:e=>typeof document>`u`?()=>void 0:(document.addEventListener(`visibilitychange`,e),()=>document.removeEventListener(`visibilitychange`,e))},yn=_.createContext(null),bn=_.createContext(null);function xn({children:e,apiBase:t,fetchImpl:n}){let[r,i]=_.useReducer(Ut,void 0,Ht),a=_.useRef(r);a.current=r;let o=_.useRef(0),s=_.useRef(null),c=_.useMemo(()=>new jt({apiBase:t,fetchImpl:n,onUnauthorized:()=>{o.current+=1,s.current?.stop(),i({type:`logout`,now:Date.now()})}}),[t,n]);_.useEffect(()=>{let e=new dn({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 kt)&&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)(bn.Provider,{value:l,children:(0,x.jsx)(yn.Provider,{value:r,children:e})})}function Sn(){let e=_.useContext(yn);if(e===null)throw Error(`useWebUi must be used within WebUiProvider.`);return e}function Cn(){let e=_.useContext(bn);if(e===null)throw Error(`useWebUiActions must be used within WebUiProvider.`);return e}var wn=Object.freeze({}),Tn=[`max_tokens`,`temperature`,`top_p`,`top_k`,`min_p`,`repetition_penalty`,`seed`];function En(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(!Tn.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 Dn=wn,On=new Set;function kn(e){return On.add(e),()=>On.delete(e)}function An(e){Dn=En(e);for(let e of On)e()}function jn(){An(wn)}function Mn(){return{defaults:(0,_.useSyncExternalStore)(kn,()=>Dn,()=>wn),setDefaults:An,reset:jn}}function Nn(e,t,n){return e===null||e<=0||t===null||n===void 0?`unknown`:t+n>e?`exceeds`:`raw-fits`}function Pn({modelId:e,nCtx:t,locale:n}){let r=Cn(),{defaults:i}=Mn(),[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=Nn(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)(Ce,{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 Fn(e){return e instanceof kt?e.status===401?`wrong-key`:e.status===403?`forbidden`:`generic`:e instanceof $e||e instanceof Error&&e.name===`ValidationError`?`schema`:e instanceof TypeError||e instanceof Error&&/fetch|network|offline|connection/i.test(e.message)?`offline`:`generic`}function In(e,t){let n=Kn(t);return n===null?R(e,`model.selected.none`):`${n.identity.display_name} · ${qn(e,n.lifecycle.state)}`}function Ln(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,sequence:Jn(e,t),status:Rn(e,t.connection)})}function Rn(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 zn(e){return e.snapshot.auth.status===`authenticated`?e.snapshot.connection===`schema-mismatch`?(0,x.jsx)(Hn,{...e}):(0,x.jsx)(Vn,{...e}):(0,x.jsx)(Bn,{...e})}function Bn(e){return e.authFailure===`schema`?(0,x.jsx)(Hn,{...e}):(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsxs)(`section`,{className:`screen-heading connection-prompt`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:e.eyebrow}),(0,x.jsx)(`h1`,{"data-testid":e.titleTestId,children:e.title}),(0,x.jsx)(`p`,{"data-testid":z(`connection.prompt.body`),children:R(e.locale,`connection.prompt.body`)})]}),(0,x.jsx)(Ne,{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:Gn(e.locale,e.authFailure),busy:e.snapshot.auth.status===`authenticating`,onSubmit:e.onLogin,onLogout:e.onLogout,testId:z(`auth.login`)})]})}function Vn(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.jsxs)(`section`,{className:`screen-heading connection-prompt`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:e.eyebrow}),(0,x.jsx)(`h1`,{"data-testid":e.titleTestId,children:e.title}),(0,x.jsx)(`p`,{"data-testid":z(`connection.authenticated.body`),children:R(e.locale,`connection.authenticated.body`)})]}),(0,x.jsx)(B,{tone:`info`,title:R(e.locale,`connection.authenticated.title`),body:Un(e.locale,e.snapshot),testId:z(`connection.authenticated.detail`)}),t?(0,x.jsx)(B,{title:R(e.locale,`connection.error.title`),body:Wn(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 Hn(e){return(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsxs)(`section`,{className:`screen-heading connection-prompt`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:e.eyebrow}),(0,x.jsx)(`h1`,{"data-testid":e.titleTestId,children:e.title})]}),(0,x.jsx)(Pe,{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 Un(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:Rn(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:Jn(e,t)})}function Wn(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 Gn(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 Kn(e){return e.selectedModelId===null?null:e.catalog.find(t=>t.identity.id===e.selectedModelId)??null}function qn(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 Jn(e,t){return String(t.lastSequence??t.catalogSequence??t.resourceFences.operationsSnapshot??R(e,`connection.snapshot.pending`))}function Yn({locale:e}){let{defaults:t,setDefaults:n,reset:r}=Mn(),[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:Tn.map(n=>(0,x.jsx)(Ce,{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)(B,{title:R(e,`settings.generation.error_title`),body:o}):null,(0,x.jsxs)(`div`,{children:[(0,x.jsx)(N,{onClick:()=>{try{n(En(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)(Ce,{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)(Ee,{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 Xn({modelId:e,locale:t}){let n=Cn(),[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]=Be(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:Ve(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)(B,{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)(Ce,{label:e.name,value:a[e.name]??Ve(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)(Ce,{label:e.name,value:Ve(e,r.current[e.name]),disabled:!0,hint:e.reason??e.help},e.name))]}),(0,x.jsxs)(Ee,{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,Ve(e,e.default)]))),c({}),m(!1)},children:R(t,`settings.live.reset.confirm`)})]})]})}var Zn=[`fp16`,`float16`,`int8`,`i8`,`turbo4-asym`,`fp16+turbo4`,`turbo3-asym`,`fp16+turbo3`,`turbo3`,`turbo4`,`turbo4-sym`,`turbo4-delegated`,`fp16+turbo4-delegated`],Qn=Object.freeze({});function $n(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`||!Zn.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 er(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:$n(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]=$n(t)}return{version:1,reusable:$n(n.reusable),models:r}}var tr=`mlxcel.webui.load-profiles.v1`,nr={version:1,reusable:Qn,models:{}},rr=!1,ir=new Set;function ar(e){return ir.add(e),()=>ir.delete(e)}function or(){if(!rr){rr=!0;try{let e=localStorage.getItem(tr);e!==null&&(nr=er(e))}catch{}}}function sr(e){let t=JSON.stringify(e),n=er(t);localStorage.setItem(tr,t),nr=n;for(let e of ir)e()}function cr(e){or();let t=(0,_.useSyncExternalStore)(ar,()=>nr);return{reusable:t.reusable,modelProfile:e===null?Qn:t.models[e]??Qn,profile:e!==null&&Object.hasOwn(t.models,e)?t.models[e]:t.reusable,save:(t,n)=>{let r=$n(t);if(n===`model`&&e===null)throw Error(`Select a model first.`);sr(n===`reusable`?{...nr,reusable:r}:{...nr,models:{...nr.models,[e]:r}})},reset:(t=e===null?`reusable`:`model`)=>{let n=Object.fromEntries(Object.entries(nr.models).filter(([t])=>t!==e));sr(t===`reusable`?{...nr,reusable:Qn}:{...nr,models:n})},exportJson:()=>JSON.stringify(nr,null,2),importJson:e=>sr(er(e))}}function lr(e){let t=$n(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=cr(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)(B,{tone:`info`,title:R(t,`settings.profile.single.title`),body:R(t,`settings.profile.single.body`)}):null,(0,x.jsx)(Se,{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)(Ce,{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)(Ce,{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)(Se,{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`)},...Zn.map(e=>({value:e,label:e}))]})]}),(0,x.jsx)(`p`,{children:R(t,`settings.profile.restrictions`)}),u?(0,x.jsx)(B,{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($n(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:lr(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)(Ee,{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 dr({locale:e}){let t=Sn(),n=Cn(),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)(Yn,{locale:e}),o?(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(Se,{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} · ${qn(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)(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:R(e,`settings.server.context.title`)}),(0,x.jsx)(Ce,{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)(Ce,{label:R(e,`settings.server.context.slots`),value:i?.totalSlots?.toString()??c,disabled:!0}),(0,x.jsx)(Ce,{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)(Pn,{modelId:s,nCtx:i?.nCtx??null,locale:e},s)]}),s===null?(0,x.jsx)(B,{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)(Xn,{modelId:s,locale:e},s):(0,x.jsx)(B,{tone:`info`,title:R(e,`settings.server.live_disabled.title`),body:R(e,`settings.server.live_disabled.body`)})]}):(0,x.jsx)(B,{tone:`warning`,title:R(e,`settings.server.unavailable.title`),body:R(e,`settings.server.unavailable.body`)})]})}var fr=[{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 pr(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]`);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)},[]);let o=n=>{let r=fr[(fr.findIndex(t=>t.id===e.route)+n+fr.length)%fr.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)(mr,{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)(Oe,{open:i,title:R(e.locale,`nav.primary`),onClose:()=>a(!1),closeLabel:R(e.locale,`common.close`),testId:`mobile-nav-sheet`,children:(0,x.jsx)(mr,{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`,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:()=>a(!0),"data-testid":z(`toolbar.menu`)}),(0,x.jsxs)(`div`,{className:`toolbar-title`,children:[(0,x.jsx)(`p`,{id:`app-title`,"data-testid":z(`app.title`),children:R(e.locale,`app.title`)}),(0,x.jsx)(`span`,{"data-testid":z(`app.subtitle`),children:R(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)(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)(`section`,{className:`app-content`,children:e.children}),e.inspector]})]})]})}var mr=_.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:fr.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.jsx)(`span`,{className:`connection-dot`,"data-state":e.connectionState,"aria-hidden":`true`}),(0,x.jsx)(`span`,{"data-testid":z(`connection.ready`),children:e.connectionLabel})]})]}));mr.displayName=`Sidebar`;var hr=[`mlxcel`,`glass`],gr=[`light`,`dark`],_r=[`system`,`light`,`dark`],vr=`mlxcel`,yr=`system`;hr.flatMap(e=>gr.map(t=>`${e}-${t}`));var br=`(prefers-color-scheme: dark)`;function xr(e){return typeof e==`string`&&hr.includes(e)}function Sr(e){return typeof e==`string`&&_r.includes(e)}function Cr(e,t){return`${e}-${t}`}function wr(){try{return typeof window>`u`||typeof window.matchMedia!=`function`?`light`:window.matchMedia(`(prefers-color-scheme: dark)`).matches?`dark`:`light`}catch{return`light`}}function Tr(e,t=wr()){return e===`system`?t:e}function Er(e,t,n=wr()){let r=Tr(t,n);return{id:Cr(e,r),family:e,scheme:r,preference:t}}function Dr(e){if(typeof window>`u`||typeof window.matchMedia!=`function`)return()=>void 0;let t;try{t=window.matchMedia(br)}catch{return()=>void 0}let n=t=>e(t.matches?`dark`:`light`);return t.addEventListener(`change`,n),()=>t.removeEventListener(`change`,n)}var Or={themeFamily:vr,colorScheme:yr,material:`glass`,glassIntensity:35,reduceMotion:!1,reduceTransparency:!1,highContrast:`system`,locale:`en`},kr=`mlxcel.webui.appearance`;function Ar(e){let t=typeof e==`number`&&Number.isFinite(e)?e:Or.glassIntensity;return Math.max(0,Math.min(100,Math.round(t)))}function jr(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Mr(e){return e===`glass`||e===`tinted`||e===`opaque`}function Nr(e){return e===`system`||e===`on`||e===`off`}function Pr(e){return Nr(e)?e:e===!0?`on`:e===!1?`off`:Or.highContrast}function Fr(e){return Sr(e.colorScheme)?e.colorScheme:e.colorScheme===void 0&&Sr(e.theme)?e.theme:Or.colorScheme}function Ir(e){return e===`en`||e===`ko`}function Lr(){if(typeof window>`u`)return Or;let e;try{e=window.localStorage.getItem(kr)}catch{return Or}if(!e)return Or;try{let t=JSON.parse(e);return jr(t)?{themeFamily:xr(t.themeFamily)?t.themeFamily:Or.themeFamily,colorScheme:Fr(t),material:Mr(t.material)?t.material:Or.material,glassIntensity:Ar(t.glassIntensity),reduceMotion:t.reduceMotion===!0,reduceTransparency:t.reduceTransparency===!0,highContrast:Pr(t.highContrast),locale:Ir(t.locale)?t.locale:Or.locale}:Or}catch{return Or}}function Rr(e){try{window.localStorage.setItem(kr,JSON.stringify(e))}catch{}}function zr(){return typeof CSS>`u`||typeof CSS.supports!=`function`?!1:CSS.supports(`backdrop-filter: blur(1px)`)||CSS.supports(`-webkit-backdrop-filter: blur(1px)`)}function Br(e,t,n=wr()){let r=Er(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(Ar(t.glassIntensity)),e.dataset.reduceMotion=String(t.reduceMotion),e.dataset.reduceTransparency=String(t.reduceTransparency),e.dataset.highContrast=t.highContrast,e.dataset.backdropFilter=zr()?`supported`:`unsupported`,e.lang=t.locale}function Vr(e){return e.value===null||!Number.isFinite(e.value)?`N/A`:`${new Intl.NumberFormat(void 0,{maximumFractionDigits:2}).format(e.value)} ${e.unit}`}function Hr(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 Ur(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 Wr(e){let t=URL.createObjectURL(new Blob([Ur(e)],{type:`application/json`})),n=document.createElement(`a`);n.href=t,n.download=`mlxcel-diagnostics.json`,n.click(),URL.revokeObjectURL(t)}function Gr({operations:e,locale:t,stale:n}){let r=[...e.values()].sort((e,t)=>Number(Bt(e))-Number(Bt(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=>!Bt(e)).length),failed:String(r.filter(e=>e.state===`failed`).length)})}),(0,x.jsx)(`p`,{children:R(t,`activity.session`)}),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)(Kr,{operation:e,locale:t,stale:n})},e.operation_id))})]})}function Kr({operation:e,locale:t,stale:n}){let r=Cn(),i=Sn(),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=Bt(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:Hr(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)(B,{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)(B,{title:R(t,`activity.cancel_failed`),body:R(t,`activity.refresh`)}):null]})}var qr=new Set(be.map(e=>e.key).filter(e=>e.startsWith(`activity.metric.`))),Jr=e=>qr.has(e);function Yr({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 Jr(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)(B,{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.jsxs)(`dl`,{className:`activity-metric`,children:[(0,x.jsx)(`dt`,{children:s(e)}),(0,x.jsx)(`dd`,{children:Vr(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.jsxs)(`dl`,{className:`activity-metric`,children:[(0,x.jsx)(`dt`,{children:s(e)}),(0,x.jsx)(`dd`,{children:Vr(n)}),(0,x.jsxs)(`dd`,{children:[R(t,`activity.scope`),`: `,n.scope]}),(0,x.jsxs)(`dd`,{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)(`dd`,{children:n.reason})]},e))})]})]})}var Xr=(function(){let e=typeof document<`u`&&document.createElement(`link`).relList;return e&&e.supports&&e.supports(`modulepreload`)?`modulepreload`:`preload`})(),Zr=function(e,t){return new URL(e,t).href},Qr={},$r=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=Zr(t,n),t=s(t),t in Qr)return;Qr[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`:Xr,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)})},ei=(0,_.lazy)(()=>$r(()=>import(`./history-DIlBLmUk.js`),[],import.meta.url));function ti({locale:e}){let t=Sn(),n=Cn(),[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":z(`activity.title`),children:R(e,`activity.title`)}),(0,x.jsx)(`p`,{children:R(e,`activity.intro`)}),(0,x.jsxs)(`p`,{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)(Se,{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.jsxs)(`div`,{className:`activity-toolbar`,children:[(0,x.jsx)(N,{onClick:()=>{n.refresh()},children:R(e,`activity.refresh`)}),(0,x.jsx)(N,{onClick:()=>Wr(t),children:R(e,`activity.export`)})]}),a?(0,x.jsx)(B,{tone:`warning`,title:R(e,`activity.stale`),body:R(e,`activity.refresh`)}):null,(0,x.jsx)(Gr,{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)(Yr,{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)(ei,{samples:t.runtimeHistory,locale:e})}):null]})}var ni=e=>[`succeeded`,`failed`,`cancelled`].includes(e.state),ri=e=>e.auth.status===`authenticated`&&e.bootstrap!==null&&e.catalogSequence!==null&&[`ready`,`streaming`,`polling`].includes(e.connection);function ii(e,t){return ri(e)&&e.bootstrap?.actions[t]?.state===`enabled`}function ai(e,t){return[...e.operations.values()].some(e=>!ni(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 oi(e,t){return ii(e,`load`)&&t.supported&&t.complete&&t.metadata.support.runnable_on_backend&&!t.lifecycle.busy&&[`unloaded`,`failed`].includes(t.lifecycle.state)&&!ai(e,t.identity.id)}function si(e,t){return ii(e,`unload`)&&t.lifecycle.state===`ready`&&!ai(e,t.identity.id)}function ci(e,t){return ii(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)&&!ai(e,t.identity.id)}function li(e,t){return ri(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&&si(e,n)&&!n.lifecycle.busy&&n.lifecycle.active_requests===0&&n.lifecycle.draining_requests===0)}function di(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 fi(e,t){return e instanceof kt?e.envelope?.error.code===`stale_revision`?R(t,`models.library.stale`):e.message:R(t,`models.library.pending`)}function pi(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 mi(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 hi(e){return e.length===0||e.length<=128&&e.split(`/`).every(e=>e!==`.`&&e!==`..`&&/^[A-Za-z0-9._~+-]+$/.test(e))}function gi({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=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)(Ee,{open:!0,title:f,onClose:i,closeLabel:R(n,`common.close`),testId:`models-confirm`,children:[(0,x.jsx)(`p`,{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)(Ce,{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`,{children:[e.identity.display_name,` · `,e.lifecycle.state,` · `,R(n,`models.library.active`),`:`,` `,e.lifecycle.active_requests]},e.identity.id))}),(0,x.jsx)(Se,{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 _i({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=mi(s.trim())&&hi(l.trim());return(0,x.jsx)(Ee,{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)(Ce,{label:R(e,`models.library.repo`),value:s,onChange:c,testId:`models-repo`,error:s&&!mi(s.trim())?R(e,`models.library.repo_invalid`):void 0}),(0,x.jsx)(Ce,{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 vi({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 yi({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`),di(s.disk_bytes,r)],[R(r,`models.library.memory`),di(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)(Ae,{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:qn(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)(vi,{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||!oi(n,e),onClick:()=>a(`load`),children:R(r,`models.load`)}),(0,x.jsx)(N,{"data-testid":`models-use-chat`,disabled:i||!li(n,e),onClick:o,children:R(r,`models.library.chat`)}),(0,x.jsx)(N,{"data-testid":`models-unload`,disabled:i||!si(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||!ci(n,e),onClick:()=>a(`delete`),children:R(r,`models.library.delete`)}):null]}),li(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 bi({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(ni(e))-Number(ni(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:Si(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:`${di(s.progress.completed_bytes,t)} / ${di(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===xi(s)&&oi(e,t)),onClick:()=>o(xi(s)),children:R(t,`models.library.capacity`)}):null,s.kind===`download`&&!ni(s)?(0,x.jsx)(N,{disabled:n||!ri(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||!ii(e,`download`),onClick:()=>a(s),children:R(t,`models.library.retry_download`)}):null]})]})},s.operation_id))})]})}function xi(e){return e.target.target_kind===`model`?e.target.model_id:``}function Si(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 Ci=25;function wi({locale:e}){let t=Sn(),n=Cn(),[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}=cr(y?.identity.id??null),{profile:S}=cr(f?.kind===`capacity`?f.entry.identity.id:null),C=pi(t.catalog,r),w=Math.max(1,Math.ceil(C.length/Ci)),T=Math.min(a,w-1),E=[...t.operations.values()].some(e=>e.kind===`download`&&!ni(e))||[...t.pendingReconciliations.values()].some(e=>e.kind===`download`),D=[...t.operations.values()].some(e=>e.kind===`catalog_refresh`&&!ni(e))||[...t.pendingReconciliations.values()].some(e=>e.kind===`catalog-refresh`),O=e=>{i({...r,...e}),o(0)},k=async(n,r)=>{if(l.current||!ri(t))return!1;l.current=!0,c(!0),d(null);try{return await n(),!0}catch(t){return d(fi(t,e)),r?.(t),!1}finally{l.current=!1,c(!1)}},ee=(r,i,a=b)=>{if(!oi(t,r)){d(R(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(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 kt&&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||ni(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(!ui(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`&&si(t,o)?k(()=>n.unloadModel({action:`unload`,model_id:o.identity.id,expected_revision:o.identity.revision,idempotency_key:crypto.randomUUID()})):a.kind===`delete`&&ci(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`,"aria-label":R(e,`models.library.inspect`,{name:r.identity.display_name}),onClick:()=>n.selectModel(r.identity.id),children:r.identity.display_name}),r.identity.id===t.selectedModelId?(0,x.jsx)(`small`,{children:R(e,`models.library.selected`)}):null,(0,x.jsxs)(`p`,{children:[r.identity.source,` · `,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:qn(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.jsxs)(`section`,{className:`screen-heading`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:R(e,`routes.models.eyebrow`)}),(0,x.jsx)(`h1`,{tabIndex:-1,"data-dialog-focus-fallback":!0,"data-testid":z(`models.title`),children:R(e,`models.title`)}),(0,x.jsx)(`p`,{children:R(e,`models.library.subtitle`)})]}),ri(t)?null:(0,x.jsx)(B,{title:R(e,`models.library.stale`),body:t.error?.message??R(e,`models.library.waiting`),action:(0,x.jsx)(N,{onClick:()=>{n.refresh()},children:R(e,`models.library.refresh`)}),testId:`connection-error-title`}),u?(0,x.jsx)(B,{title:R(e,`models.library.error`),body:u,action:(0,x.jsx)(N,{onClick:()=>{d(null),n.refresh()},children:R(e,`models.library.refresh`)}),testId:`models-action-error`}):null,t.bootstrap?.server.mode===`single_model`?(0,x.jsx)(B,{tone:`info`,title:R(e,`models.library.single`),body:`mlxcel-server --webui`,testId:`models-read-only`}):null,(0,x.jsxs)(`div`,{className:`button-row`,children:[(0,x.jsx)(N,{tone:`primary`,onClick:()=>h({repo:``,revision:``}),disabled:s||E||!ii(t,`download`),"data-testid":`models-add`,children:R(e,`models.library.add`)}),(0,x.jsx)(N,{disabled:s||D||!ri(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`)})]}),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:Un(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)(Ce,{label:R(e,`models.library.search`),value:r.query,onChange:e=>O({query:e}),testId:`models-search`}),(0,x.jsx)(Se,{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)(Se,{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)(Se,{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:qn(e,t)}))]}),(0,x.jsx)(Se,{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)(he,{columns:M,rows:C.slice(T*Ci,(T+1)*Ci),getRowKey:e=>e.identity.id,ariaLabel:R(e,`models.title`),testId:`models-table`,rowClassName:e=>e.identity.id===t.selectedModelId?`models-selected`:void 0,loading:t.catalogSequence===null,loadingState:(0,x.jsx)(`p`,{role:`status`,children: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)(yi,{entry:y,profile:b,state:t,locale:e,busy:s,onAction:A,onChat:()=>{li(t,y)&&(n.selectModel(y.identity.id),window.location.hash=`chat`)}}):null]}),(0,x.jsx)(bi,{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&&oi(t,n)&&p({kind:`capacity`,entry:n,instance:t.serverInstanceId})}}),f?(0,x.jsx)(gi,{value:f,state:t,locale:e,busy:s,onClose:()=>p(null),onConfirm:te},f.kind):null,m?(0,x.jsx)(_i,{locale:e,state:t,initial:m,error:u,busy:s||E||!ii(t,`download`),onClose:()=>h(null),onDownload:(e,r)=>{ii(t,`download`)&&!E&&k(()=>n.downloadModel({repo_id:e,revision:r||null,idempotency_key:crypto.randomUUID()})).then(e=>{e&&h(null)})}}):null]})}var Ti={en:`en-US`,ko:`ko-KR`},Ei=e=>Ti[e];function Di(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)(ji,{locale:e.locale})},{id:`data`,label:R(e.locale,`gallery.tab.data`),panel:(0,x.jsx)(Mi,{locale:e.locale})}]}),(0,x.jsxs)(Ee,{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)(Ce,{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 Ai(e){return(0,x.jsxs)(`div`,{className:`gallery-grid`,children:[(0,x.jsxs)(`article`,{className:`surface-card`,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)(Ce,{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)(Se,{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)(`article`,{className:`surface-card`,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)(ke,{label: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 ji(e){return(0,x.jsxs)(`div`,{className:`gallery-grid`,children:[(0,x.jsx)(Ne,{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)(Pe,{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)(B,{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:Di(67108864,e.locale)})}),(0,x.jsx)(fe,{label:R(e.locale,`gallery.progress.measured`),value:37})]}),(0,x.jsxs)(Me,{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 Mi(e){return(0,x.jsxs)(`div`,{className:`gallery-grid dense-gallery`,children:[(0,x.jsxs)(`article`,{className:`surface-card table-card`,tabIndex:0,"aria-label":R(e.locale,`gallery.sample.caption`),children:[(0,x.jsx)(`h2`,{children:R(e.locale,`gallery.data.title`)}),(0,x.jsxs)(je,{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:Oi(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:Oi(null,e.locale)})]})]})]})]}),(0,x.jsxs)(Ae,{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`)})]})]})}var Ni={count:4,bytes:8388608,dimension:4096,pixels:16e6},Pi=new Set([`image/png`,`image/jpeg`,`image/webp`]);function Fi(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 Ci(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 wi(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 Ti(e,t,n){if(!e||!t||e>Math.min(bi.dimension,n.max_width)||t>Math.min(bi.dimension,n.max_height)||e*t>bi.pixels||e*t*4>n.max_decoded_bytes)throw Error(`Image dimensions exceed the server or browser decode budget.`)}function Ei(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(wi(t),e.length>t.max_images)throw Error(`Conversation images exceed the server image count limit.`);let n=0,r=Math.min(bi.bytes,t.max_image_bytes);for(let i of e){if(!i||!xi.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)||!xi.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 Ci(e),[r,i]=Si(t,e.type);if(Ti(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 Ai(e){if(e==null)return``;if(typeof e!=`string`)throw Error(`Malformed text delta.`);return e}function ji(e){if(typeof e!=`number`||!Number.isSafeInteger(e)||e<0)throw Error(`Malformed usage.`);return e}function Mi(e,t,n){if(t.length>256e3)throw Error(`Chat frame exceeds the display limit.`);let r=ki(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=ki(r.usage);i={...i,usage:{prompt_tokens:ji(e.prompt_tokens),completion_tokens:ji(e.completion_tokens),total_tokens:ji(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=ki(e);if(t.index!==0)throw Error(`Unexpected chat choice index.`);let r=ki(t.delta),a=Ai(r.content),o=Ai(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=ki(e),n=ji(t.index);if(n>=32)throw Error(`Tool index exceeds the display limit.`);let r=t.function===void 0?{}:ki(t.function),i=s.find(e=>e.index===n)??{index:n,id:``,name:``,arguments:``},a={index:n,id:i.id+Ai(t.id),name:i.name+Ai(r.name),arguments:i.arguments+Ai(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=Ai(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 Ni(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 Pi(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 Fi(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 Ii=Object.freeze({conversations:50,turnsPerConversation:200,totalTurns:1e3,textCharacters:262144,jsonBytes:16777216,imageBytes:8388608,imagesPerTurn:8,toolsPerTurn:128}),Li=`mlxcel.webui.chat.v1`,Ri=`history`,zi=`conversations`,Bi=1,Vi=new Set([`temperature`,`top_p`,`top_k`,`min_p`,`max_tokens`,`seed`,`repetition_penalty`,`presence_penalty`,`frequency_penalty`]),Hi=class extends Error{constructor(e=`Conversation history is invalid or exceeds the local history limits.`){super(e),this.name=`HistoryValidationError`}},Ui=class extends Error{constructor(e,t){super(e,t),this.name=`HistoryStorageError`}};function Wi(){throw new Hi}function Gi(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return Wi();let n=Object.getPrototypeOf(e);if(n!==Object.prototype&&n!==null)return Wi();let r=Object.keys(e);return r.length!==t.length||r.some(e=>!t.includes(e))?Wi():e}function H(e,t=Ii.textCharacters){return typeof e!=`string`||e.length>t?Wi():e}function Ki(e){let t=H(e,512);return!t||Array.from(t).some(e=>e.charCodeAt(0)<32||e.charCodeAt(0)===127)?Wi():t}function qi(e,t=!1){return typeof e!=`number`||!Number.isFinite(e)||e<0||t&&!Number.isSafeInteger(e)?Wi():e}function Ji(e,t){return e===null?null:t(e)}function Yi(e,t){return!Array.isArray(e)||e.length>t?Wi():e}function Xi(e){return new TextEncoder().encode(e).byteLength}function Zi(e,t){let n=0,r=0,i=0,a=new Set;return Yi(e,Ii.conversations).map(e=>{let o=Gi(e,[`id`,`title`,`systemPrompt`,`turns`,`updatedAt`]),s=Ki(o.id);if(a.has(s))return Wi();a.add(s);let c=new Set,l=Yi(o.turns,Ii.turnsPerConversation).map(e=>{if(++n>Ii.totalTurns)return Wi();let a=Gi(e,[`id`,`modelId`,`modelRevision`,`inferenceId`,`modelName`,`prompt`,`content`,`reasoning`,`tools`,`status`,`finishReason`,`usage`,`ttftMs`,`elapsedMs`,`error`,`parameters`,`images`]),o=Ki(a.id);if(c.has(o))return Wi();c.add(o);let s=H(a.status,32);if(![`streaming`,`complete`,`cancelled`,`interrupted`,`error`].includes(s))return Wi();let l={};if(!a.parameters||typeof a.parameters!=`object`||Array.isArray(a.parameters)||![Object.prototype,null].includes(Object.getPrototypeOf(a.parameters)))return Wi();for(let[e,t]of Object.entries(a.parameters)){if(!Vi.has(e)||typeof t!=`number`||!Number.isFinite(t))return Wi();l[e]=t}let u=new Set,d=Yi(a.tools,Ii.toolsPerTurn).map(e=>{let t=Gi(e,[`index`,`id`,`name`,`arguments`]),n=qi(t.index,!0);return u.has(n)?Wi():(u.add(n),{index:n,id:H(t.id,512),name:H(t.name,512),arguments:H(t.arguments)})}),f=Yi(a.images,Ii.imagesPerTurn).map(e=>{let t=Gi(e,[`name`,`type`,`dataUrl`]),n=H(t.type,64);if(![`image/png`,`image/jpeg`,`image/webp`].includes(n))return Wi();let i=H(t.dataUrl,Ii.imageBytes*2),a=`data:${n};base64,`;if(!i.startsWith(a))return Wi();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>Ii.imageBytes)?Wi():{name:H(t.name,512),type:n,dataUrl:i}}),p={id:o,modelId:Ki(a.modelId),modelRevision:qi(a.modelRevision,!0),inferenceId:Ki(a.inferenceId),modelName:H(a.modelName,512),prompt:H(a.prompt),content:H(a.content),reasoning:H(a.reasoning),tools:d,status:s===`streaming`?`interrupted`:s,finishReason:Ji(a.finishReason,H),usage:Ji(a.usage,e=>{let t=Gi(e,[`prompt_tokens`,`completion_tokens`,`total_tokens`]);return{prompt_tokens:qi(t.prompt_tokens,!0),completion_tokens:qi(t.completion_tokens,!0),total_tokens:qi(t.total_tokens,!0)}}),ttftMs:Ji(a.ttftMs,qi),elapsedMs:Ji(a.elapsedMs,qi),error:Ji(a.error,H),parameters:l,images:t.includeImages?f:[]};return p.status===`complete`&&(!p.finishReason||!p.content&&!p.reasoning&&!p.tools.length)||(i+=Xi(JSON.stringify(p)),i>Ii.jsonBytes)?Wi():p});return{id:s,title:H(o.title,512),systemPrompt:H(o.systemPrompt),turns:l,updatedAt:qi(o.updatedAt,!0)}})}function Qi(e,t={}){let n=Zi(e,t);return Xi(JSON.stringify(n))>Ii.jsonBytes?Wi():n}function $i(e,t={}){let n=JSON.stringify({version:Bi,conversations:Qi(e,t)});return Xi(n)>Ii.jsonBytes?Wi():n}function ea(e,t={}){if(Xi(e)>Ii.jsonBytes)return Wi();let n;try{n=JSON.parse(e)}catch{return Wi()}let r=Gi(n,[`version`,`conversations`]);return r.version===Bi?Qi(r.conversations,t):Wi()}function U(e){return new Ui(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 W(e={}){let t=!1,n=!1,r=0,i,a,o=new Set,s=()=>{let t=e.indexedDB??globalThis.indexedDB;if(!t)throw new Ui(`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(Li,Bi);o.onupgradeneeded=()=>{o.result.objectStoreNames.contains(Ri)||o.result.createObjectStore(Ri)},o.onerror=()=>a(U(o.error));let l=!1;o.onblocked=()=>{l=!0,a(new Ui(`Close other WebUI tabs to access local history.`))},o.onsuccess=()=>{if(l||!t||e!==r){o.result.close(),a(new Ui(`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(Ri,e);o.add(r);let a=i(r.objectStore(Ri));r.oncomplete=()=>{o.delete(r),t(a.result)},r.onabort=r.onerror=()=>{o.delete(r),n(U(r.error??a.error))}})}catch(e){throw e instanceof Ui?e:U(e)}}return{setEnabled(e){t!==e&&(t=e,e||c())},async load(e={}){let t=await u(`readonly`,e=>e.get(zi));return t===void 0?[]:ea(H(t,Ii.jsonBytes),e)},async save(e,n={}){if(!t)return;let r=$i(e,n);await u(`readwrite`,e=>e.put(r,zi))},async clear(){if(n)throw new Ui(`Local history is already being cleared.`);n=!0;let e=!1;c();try{await new Promise((t,r)=>{let i=s().deleteDatabase(Li);i.onsuccess=()=>{n=!1,t()},i.onerror=()=>{n=!1,r(U(i.error))},i.onblocked=()=>{e=!0,r(new Ui(`Close other WebUI tabs to clear local history.`))}})}catch(t){throw e||(n=!1),t instanceof Ui?t:U(t)}},close:c}}var ta=[],na=0,ra=new Set;function ia(){return na}function aa(e){return{id:crypto.randomUUID(),title:e,systemPrompt:``,turns:[],updatedAt:Date.now()}}var oa=new WeakMap;function sa(e){let t=oa.get(e);if(t!==void 0)return t;let n=new TextEncoder().encode(JSON.stringify(e)).byteLength;return oa.set(e,n),n}function ca(e){return e.length>Ii.conversations||e.reduce((e,t)=>e+t.turns.length,0)>Ii.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+sa(t),0)+Math.max(0,t.turns.length-1),0)<=Ii.jsonBytes}function la(e){ta=e;for(let e of ra)e()}function ua(e){if(!ca(e))throw Error(`Conversation memory limit exceeded.`);na++,la(e)}function da(e){let t=ta.some(t=>t.id===e.id)?ta.map(t=>t.id===e.id?e:t):[...ta,e];return ca(t)?(la(t),!0):!1}function fa(){return(0,_.useSyncExternalStore)(e=>(ra.add(e),()=>ra.delete(e)),()=>ta)}var pa=(0,_.lazy)(()=>Br(()=>import(`./code-highlight-DYgjCuFT.js`),[],import.meta.url)),ma=65536,ha=512;function ga(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)(pa,{code:e,language:t})}):(0,x.jsx)(`code`,{children:e})})]})}),ya=(0,_.memo)(function({text:e,streaming:t=!1}){let n=e.slice(0,ma).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)(va,{code:o.join(` -`),language:s[2].slice(0,40),complete:c||!t&&e.length<=ma},a))}else if(/^#{1,6} /.test(o))r.push((0,x.jsx)(`p`,{className:`chat-markdown-heading`,children:(0,x.jsx)(`strong`,{children:ga(o.replace(/^#{1,6} /,``))})},a));else if(/^[-*] /.test(o)){let e=[o.slice(2)];for(;i(0,x.jsx)(`li`,{children:ga(e)},t))},a))}else o.trim()&&r.push((0,x.jsx)(`p`,{children:ga(o)},a))}return(0,x.jsxs)(`div`,{className:`chat-markdown`,children:[r,(e.length>ma||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)(ya,{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 Sa({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)(xa,{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 Ca({conversations:e,busy:t,onPending:n,limits:r,onReplace:i,locale:a}){let o=(0,_.useRef)(W()),[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 wa(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)(De,{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([$i(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=ea(e,{includeImages:p});await wa(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)(B,{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 wa(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 Di(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 Ta(e,t){let n=Object.fromEntries(Object.entries(t).filter(([,e])=>e!==void 0&&e.trim()!==``).map(([e,t])=>[e,Number(t)]));return{...En({...e,...n})}}function Ea({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:Tn.map(i=>(0,x.jsx)(Ce,{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 Da=new Set([`en`,`ko`].map(e=>R(e,`chat.conversation.default_title`)));function Oa({locale:e}){let t=Sn(),n=Cn(),{defaults:r}=Mn(),[i,a]=(0,_.useState)({}),o=fa(),[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=aa(O(`chat.conversation.default_title`));da(e),c(e.id),u(``),f([])},oe=()=>{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`))})},se=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=Ta(r,i)}catch(e){m(e instanceof Error?e.message:O(`chat.error.invalid_parameters`));return}let s=j??aa(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&&Da.has(s.title)?l.slice(0,80):s.title,turns:[...s.turns,_],updatedAt:Date.now()};try{if(!t.bootstrap)throw Error(`Limits unavailable`);Ei(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:Pi(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(!da(s)){m(O(`chat.error.memory_budget`));return}let S=null,w=ia(),T={controller:p,turn:_,conversation:s,flush:()=>{if(S!==null&&clearTimeout(S),S=null,ia()!==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()},da(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)},da(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=Mi(T.turn,e.data,performance.now()-h),S===null&&(S=setTimeout(T.flush,50)))}},p.signal),p.signal.aborted||(T.turn=Ni(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)}},ce=()=>{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),da({...j,turns:j.turns.slice(0,t)}),window.setTimeout(()=>k.current?.focus(),0)},[le,P=``]=R(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:R(e,`chat.eyebrow`)}),(0,x.jsx)(`h1`,{tabIndex:-1,"data-dialog-focus-fallback":!0,"data-testid":z(`chat.title`),children:R(e,`chat.title`)}),(0,x.jsx)(`p`,{children:R(e,`chat.intro`)})]}),(0,x.jsxs)(`div`,{className:`chat-toolbar`,children:[(0,x.jsx)(N,{onClick:ae,disabled:v||b||C||o.length>=50,children:R(e,`chat.new_conversation`)}),(0,x.jsx)(Se,{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)(Se,{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} · ${qn(e,t.lifecycle.state)}`}))]})]}),re?null:(0,x.jsx)(B,{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)(Ce,{label:R(e,`chat.settings.name`),value:j.title,disabled:v||b||C,onChange:e=>da({...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:Oi,disabled:v||b||C,onChange:e=>da({...j,systemPrompt:e.target.value})})]}),(0,x.jsxs)(`p`,{children:[le,(0,x.jsx)(`a`,{href:`#settings`,children:R(e,`nav.settings`)}),P]}),(0,x.jsx)(N,{disabled:v||b||C,onClick:()=>{ua(o.filter(e=>e.id!==j.id)),c(null)},children:R(e,`chat.settings.delete`)})]}):null,(0,x.jsx)(Ea,{defaults:r,draft:i,onChange:a,locale:e}),(0,x.jsx)(Sa,{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)(De,{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:ce,onClose:()=>E(null)}),p?(0,x.jsx)(B,{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:Oi,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(),se())}})]}),(0,x.jsx)(`p`,{children:R(e,`chat.composer.hint`,{count:String(l.length),max:String(Oi)})}),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),Di(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:()=>{se()},children:R(e,`common.send`)}),(0,x.jsx)(N,{disabled:!v,onClick:oe,children:R(e,`chat.stop`)})]})]}),(0,x.jsx)(`p`,{role:`status`,"aria-live":`polite`,"aria-atomic":`true`,children:h}),(0,x.jsx)(Ca,{conversations:o,busy:v||C,onPending:S,limits:t.bootstrap?.media_limits,onReplace:e=>{ua(e),c(null)},locale:e})]})}var ka=[`models`,`chat`,`activity`,`settings`,`gallery`],Aa=[`models`,`chat`,`activity`,`settings`];function ja(){let e=window.location.hash.slice(1).replace(/^\//,``);return ka.includes(e)?e:`models`}function Ma(){let e=Sn(),t=Cn(),[n,r]=(0,_.useState)(ja),[i,a]=(0,_.useState)(wr),[o,s]=(0,_.useState)(null),[c,l]=(0,_.useState)(null),u=(0,_.useRef)(0);(0,_.useEffect)(()=>()=>{u.current+=1},[]),(0,_.useEffect)(()=>{let e=()=>r(ja());return window.addEventListener(`hashchange`,e),()=>window.removeEventListener(`hashchange`,e)},[]),(0,_.useEffect)(()=>{Dr(document.documentElement,i),Tr(i)},[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`&&ua([])},[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(Fn(e)))})},p=()=>{u.current+=1,l(null),t.logout()},m=Na(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)(pr,{locale:i.locale,route:n,onRouteChange:d,onCommand:()=>s(`command`),onHelp:()=>s(`help`),selectedModel:In(i.locale,e),connectionLabel:Ln(i.locale,e),connectionState:e.connection,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:m}),(0,x.jsx)(za,{open:o===`command`,locale:i.locale,onClose:()=>s(null),onNavigate:e=>{d(e),s(null)}}),(0,x.jsxs)(Ee,{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.jsxs)(`ul`,{className:`shortcut-list`,children:[(0,x.jsxs)(`li`,{children:[(0,x.jsx)(`kbd`,{children:`⌘/Ctrl`}),` + `,(0,x.jsx)(`kbd`,{children:`K`}),` `,R(i.locale,`command.search`)]}),(0,x.jsxs)(`li`,{children:[(0,x.jsx)(`kbd`,{children:`Esc`}),` `,R(i.locale,`common.cancel`)]}),(0,x.jsxs)(`li`,{children:[(0,x.jsx)(`kbd`,{children:`[`}),` / `,(0,x.jsx)(`kbd`,{children:`]`}),` `,R(i.locale,`nav.models`)]})]})]})]})}function Na(e,t,n,r){return e===`models`?(0,x.jsx)(Pa,{locale:t.locale,context:r}):e===`chat`?(0,x.jsx)(Fa,{locale:t.locale,context:r}):e===`activity`?(0,x.jsx)(Ia,{locale:t.locale,context:r}):e===`settings`?(0,x.jsx)(La,{appearance:t,setAppearance:n}):(0,x.jsx)(gi,{locale:t.locale})}function Pa(e){return e.context.snapshot.auth.status===`authenticated`&&e.context.snapshot.connection!==`schema-mismatch`?(0,x.jsx)(di,{locale:e.locale}):(0,x.jsx)(zn,{locale:e.locale,eyebrow:R(e.locale,`routes.models.eyebrow`),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 Fa(e){return e.context.snapshot.auth.status===`authenticated`&&e.context.snapshot.connection!==`schema-mismatch`?(0,x.jsx)(Oa,{locale:e.locale}):(0,x.jsx)(zn,{locale:e.locale,eyebrow:R(e.locale,`routes.chat.eyebrow`),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 Ia(e){return e.context.snapshot.auth.status===`authenticated`&&![`schema-mismatch`,`forbidden`,`unauthorized`].includes(e.context.snapshot.connection)?(0,x.jsx)(Hr,{locale:e.locale}):(0,x.jsx)(zn,{locale:e.locale,eyebrow:R(e.locale,`routes.activity.eyebrow`),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 La(e){let t=t=>e.setAppearance({...e.appearance,...t});return(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsxs)(`section`,{className:`screen-heading`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:R(e.appearance.locale,`routes.settings.eyebrow`)}),(0,x.jsx)(`h1`,{tabIndex:-1,"data-dialog-focus-fallback":!0,"data-testid":z(`settings.title`),children:R(e.appearance.locale,`settings.title`)}),(0,x.jsx)(`p`,{"data-testid":z(`settings.appearance`),children:R(e.appearance.locale,`settings.browser_only`)})]}),(0,x.jsxs)(`div`,{className:`settings-grid`,children:[(0,x.jsx)(Se,{locale:e.appearance.locale,label:R(e.appearance.locale,`settings.theme`),value:e.appearance.theme,onChange:e=>t({theme:e}),options:[{value:`system`,label:R(e.appearance.locale,`settings.theme.system`)},{value:`light`,label:R(e.appearance.locale,`settings.theme.light`)},{value:`dark`,label:R(e.appearance.locale,`settings.theme.dark`)}],testId:z(`settings.theme`)}),(0,x.jsx)(Se,{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)(Se,{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)(Se,{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)(Ra,{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)(Ra,{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)(B,{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)(dr,{locale:e.appearance.locale})]})}function Ra(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 za(e){let[t,n]=(0,_.useState)(``),r=(e.locale&&window.location.hash.includes(`gallery`)?ka:Aa).filter(e=>e.includes(t.toLowerCase()));return(0,x.jsxs)(Ee,{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)(Ce,{label:R(e.locale,`command.search`),value:t,onChange:n,testId:z(`command.search`)}),r.length===0?(0,x.jsx)(`p`,{"data-testid":z(`command.no_results`),children:R(e.locale,`command.no_results`)}):(0,x.jsx)(`div`,{className:`command-list`,children:r.map(t=>(0,x.jsx)(N,{onClick:()=>e.onNavigate(t),children:R(e.locale,t===`models`?`nav.models`:t===`chat`?`nav.chat`:t===`activity`?`nav.activity`:t===`settings`?`nav.settings`:`nav.gallery`)},t))})]})}var Ba=document.getElementById(`root`);if(Ba===null)throw Error(`Missing #root element for mlxcel WebUI.`);(0,v.createRoot)(Ba).render((0,x.jsx)(_.StrictMode,{children:(0,x.jsx)(xn,{children:(0,x.jsx)(Ma,{})})}));export{c as i,b as n,u as r,R as t}; \ No newline at end of file +`&&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 Ii(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 Li(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 Ri(e,t,n){if(!e||!t||e>Math.min(Ni.dimension,n.max_width)||t>Math.min(Ni.dimension,n.max_height)||e*t>Ni.pixels||e*t*4>n.max_decoded_bytes)throw Error(`Image dimensions exceed the server or browser decode budget.`)}function zi(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(Li(t),e.length>t.max_images)throw Error(`Conversation images exceed the server image count limit.`);let n=0,r=Math.min(Ni.bytes,t.max_image_bytes);for(let i of e){if(!i||!Pi.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)||!Pi.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 Ii(e),[r,i]=Fi(t,e.type);if(Ri(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 Ui(e){if(e==null)return``;if(typeof e!=`string`)throw Error(`Malformed text delta.`);return e}function Wi(e){if(typeof e!=`number`||!Number.isSafeInteger(e)||e<0)throw Error(`Malformed usage.`);return e}function Gi(e,t,n){if(t.length>256e3)throw Error(`Chat frame exceeds the display limit.`);let r=Hi(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=Hi(r.usage);i={...i,usage:{prompt_tokens:Wi(e.prompt_tokens),completion_tokens:Wi(e.completion_tokens),total_tokens:Wi(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=Hi(e);if(t.index!==0)throw Error(`Unexpected chat choice index.`);let r=Hi(t.delta),a=Ui(r.content),o=Ui(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=Hi(e),n=Wi(t.index);if(n>=32)throw Error(`Tool index exceeds the display limit.`);let r=t.function===void 0?{}:Hi(t.function),i=s.find(e=>e.index===n)??{index:n,id:``,name:``,arguments:``},a={index:n,id:i.id+Ui(t.id),name:i.name+Ui(r.name),arguments:i.arguments+Ui(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=Ui(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 Ki(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 qi(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 Ji(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 Yi=Object.freeze({conversations:50,turnsPerConversation:200,totalTurns:1e3,textCharacters:262144,jsonBytes:16777216,imageBytes:8388608,imagesPerTurn:8,toolsPerTurn:128}),Xi=`mlxcel.webui.chat.v1`,Zi=`history`,Qi=`conversations`,$i=1,ea=new Set([`temperature`,`top_p`,`top_k`,`min_p`,`max_tokens`,`seed`,`repetition_penalty`,`presence_penalty`,`frequency_penalty`]),ta=class extends Error{constructor(e=`Conversation history is invalid or exceeds the local history limits.`){super(e),this.name=`HistoryValidationError`}},H=class extends Error{constructor(e,t){super(e,t),this.name=`HistoryStorageError`}};function U(){throw new ta}function na(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return U();let n=Object.getPrototypeOf(e);if(n!==Object.prototype&&n!==null)return U();let r=Object.keys(e);return r.length!==t.length||r.some(e=>!t.includes(e))?U():e}function W(e,t=Yi.textCharacters){return typeof e!=`string`||e.length>t?U():e}function ra(e){let t=W(e,512);return!t||Array.from(t).some(e=>e.charCodeAt(0)<32||e.charCodeAt(0)===127)?U():t}function ia(e,t=!1){return typeof e!=`number`||!Number.isFinite(e)||e<0||t&&!Number.isSafeInteger(e)?U():e}function aa(e,t){return e===null?null:t(e)}function oa(e,t){return!Array.isArray(e)||e.length>t?U():e}function sa(e){return new TextEncoder().encode(e).byteLength}function ca(e,t){let n=0,r=0,i=0,a=new Set;return oa(e,Yi.conversations).map(e=>{let o=na(e,[`id`,`title`,`systemPrompt`,`turns`,`updatedAt`]),s=ra(o.id);if(a.has(s))return U();a.add(s);let c=new Set,l=oa(o.turns,Yi.turnsPerConversation).map(e=>{if(++n>Yi.totalTurns)return U();let a=na(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 U();c.add(o);let s=W(a.status,32);if(![`streaming`,`complete`,`cancelled`,`interrupted`,`error`].includes(s))return U();let l={};if(!a.parameters||typeof a.parameters!=`object`||Array.isArray(a.parameters)||![Object.prototype,null].includes(Object.getPrototypeOf(a.parameters)))return U();for(let[e,t]of Object.entries(a.parameters)){if(!ea.has(e)||typeof t!=`number`||!Number.isFinite(t))return U();l[e]=t}let u=new Set,d=oa(a.tools,Yi.toolsPerTurn).map(e=>{let t=na(e,[`index`,`id`,`name`,`arguments`]),n=ia(t.index,!0);return u.has(n)?U():(u.add(n),{index:n,id:W(t.id,512),name:W(t.name,512),arguments:W(t.arguments)})}),f=oa(a.images,Yi.imagesPerTurn).map(e=>{let t=na(e,[`name`,`type`,`dataUrl`]),n=W(t.type,64);if(![`image/png`,`image/jpeg`,`image/webp`].includes(n))return U();let i=W(t.dataUrl,Yi.imageBytes*2),a=`data:${n};base64,`;if(!i.startsWith(a))return U();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>Yi.imageBytes)?U():{name:W(t.name,512),type:n,dataUrl:i}}),p={id:o,modelId:ra(a.modelId),modelRevision:ia(a.modelRevision,!0),inferenceId:ra(a.inferenceId),modelName:W(a.modelName,512),prompt:W(a.prompt),content:W(a.content),reasoning:W(a.reasoning),tools:d,status:s===`streaming`?`interrupted`:s,finishReason:aa(a.finishReason,W),usage:aa(a.usage,e=>{let t=na(e,[`prompt_tokens`,`completion_tokens`,`total_tokens`]);return{prompt_tokens:ia(t.prompt_tokens,!0),completion_tokens:ia(t.completion_tokens,!0),total_tokens:ia(t.total_tokens,!0)}}),ttftMs:aa(a.ttftMs,ia),elapsedMs:aa(a.elapsedMs,ia),error:aa(a.error,W),parameters:l,images:t.includeImages?f:[]};return p.status===`complete`&&(!p.finishReason||!p.content&&!p.reasoning&&!p.tools.length)||(i+=sa(JSON.stringify(p)),i>Yi.jsonBytes)?U():p});return{id:s,title:W(o.title,512),systemPrompt:W(o.systemPrompt),turns:l,updatedAt:ia(o.updatedAt,!0)}})}function la(e,t={}){let n=ca(e,t);return sa(JSON.stringify(n))>Yi.jsonBytes?U():n}function ua(e,t={}){let n=JSON.stringify({version:$i,conversations:la(e,t)});return sa(n)>Yi.jsonBytes?U():n}function da(e,t={}){if(sa(e)>Yi.jsonBytes)return U();let n;try{n=JSON.parse(e)}catch{return U()}let r=na(n,[`version`,`conversations`]);return r.version===$i?la(r.conversations,t):U()}function fa(e){return new H(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 pa(e={}){let t=!1,n=!1,r=0,i,a,o=new Set,s=()=>{let t=e.indexedDB??globalThis.indexedDB;if(!t)throw new H(`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(Xi,$i);o.onupgradeneeded=()=>{o.result.objectStoreNames.contains(Zi)||o.result.createObjectStore(Zi)},o.onerror=()=>a(fa(o.error));let l=!1;o.onblocked=()=>{l=!0,a(new H(`Close other WebUI tabs to access local history.`))},o.onsuccess=()=>{if(l||!t||e!==r){o.result.close(),a(new H(`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(Zi,e);o.add(r);let a=i(r.objectStore(Zi));r.oncomplete=()=>{o.delete(r),t(a.result)},r.onabort=r.onerror=()=>{o.delete(r),n(fa(r.error??a.error))}})}catch(e){throw e instanceof H?e:fa(e)}}return{setEnabled(e){t!==e&&(t=e,e||c())},async load(e={}){let t=await u(`readonly`,e=>e.get(Qi));return t===void 0?[]:da(W(t,Yi.jsonBytes),e)},async save(e,n={}){if(!t)return;let r=ua(e,n);await u(`readwrite`,e=>e.put(r,Qi))},async clear(){if(n)throw new H(`Local history is already being cleared.`);n=!0;let e=!1;c();try{await new Promise((t,r)=>{let i=s().deleteDatabase(Xi);i.onsuccess=()=>{n=!1,t()},i.onerror=()=>{n=!1,r(fa(i.error))},i.onblocked=()=>{e=!0,r(new H(`Close other WebUI tabs to clear local history.`))}})}catch(t){throw e||(n=!1),t instanceof H?t:fa(t)}},close:c}}var ma=[],ha=0,ga=new Set;function _a(){return ha}function va(e){return{id:crypto.randomUUID(),title:e,systemPrompt:``,turns:[],updatedAt:Date.now()}}var ya=new WeakMap;function ba(e){let t=ya.get(e);if(t!==void 0)return t;let n=new TextEncoder().encode(JSON.stringify(e)).byteLength;return ya.set(e,n),n}function xa(e){return e.length>Yi.conversations||e.reduce((e,t)=>e+t.turns.length,0)>Yi.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+ba(t),0)+Math.max(0,t.turns.length-1),0)<=Yi.jsonBytes}function Sa(e){ma=e;for(let e of ga)e()}function Ca(e){if(!xa(e))throw Error(`Conversation memory limit exceeded.`);ha++,Sa(e)}function wa(e){let t=ma.some(t=>t.id===e.id)?ma.map(t=>t.id===e.id?e:t):[...ma,e];return xa(t)?(Sa(t),!0):!1}function Ta(){return(0,_.useSyncExternalStore)(e=>(ga.add(e),()=>ga.delete(e)),()=>ma)}var Ea=(0,_.lazy)(()=>$r(()=>import(`./code-highlight-B7JRfpaI.js`),[],import.meta.url)),Da=65536,Oa=512;function ka(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)(Ea,{code:e,language:t})}):(0,x.jsx)(`code`,{children:e})})]})}),Ma=(0,_.memo)(function({text:e,streaming:t=!1}){let n=e.slice(0,Da).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)(ja,{code:o.join(` +`),language:s[2].slice(0,40),complete:c||!t&&e.length<=Da},a))}else if(/^#{1,6} /.test(o))r.push((0,x.jsx)(`p`,{className:`chat-markdown-heading`,children:(0,x.jsx)(`strong`,{children:ka(o.replace(/^#{1,6} /,``))})},a));else if(/^[-*] /.test(o)){let e=[o.slice(2)];for(;i(0,x.jsx)(`li`,{children:ka(e)},t))},a))}else o.trim()&&r.push((0,x.jsx)(`p`,{children:ka(o)},a))}return(0,x.jsxs)(`div`,{className:`chat-markdown`,children:[r,(e.length>Da||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)(Ma,{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 Fa({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)(Pa,{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 Ia({conversations:e,busy:t,onPending:n,limits:r,onReplace:i,locale:a}){let o=(0,_.useRef)(pa()),[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 La(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)(De,{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([ua(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=da(e,{includeImages:p});await La(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)(B,{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 La(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 Bi(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 Ra(e,t){let n=Object.fromEntries(Object.entries(t).filter(([,e])=>e!==void 0&&e.trim()!==``).map(([e,t])=>[e,Number(t)]));return{...En({...e,...n})}}function za({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:Tn.map(i=>(0,x.jsx)(Ce,{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 Ba=new Set([`en`,`ko`].map(e=>R(e,`chat.conversation.default_title`)));function Va({locale:e}){let t=Sn(),n=Cn(),{defaults:r}=Mn(),[i,a]=(0,_.useState)({}),o=Ta(),[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=va(O(`chat.conversation.default_title`));wa(e),c(e.id),u(``),f([])},oe=()=>{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`))})},se=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=Ra(r,i)}catch(e){m(e instanceof Error?e.message:O(`chat.error.invalid_parameters`));return}let s=j??va(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&&Ba.has(s.title)?l.slice(0,80):s.title,turns:[...s.turns,_],updatedAt:Date.now()};try{if(!t.bootstrap)throw Error(`Limits unavailable`);zi(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:qi(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(!wa(s)){m(O(`chat.error.memory_budget`));return}let S=null,w=_a(),T={controller:p,turn:_,conversation:s,flush:()=>{if(S!==null&&clearTimeout(S),S=null,_a()!==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()},wa(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)},wa(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=Gi(T.turn,e.data,performance.now()-h),S===null&&(S=setTimeout(T.flush,50)))}},p.signal),p.signal.aborted||(T.turn=Ki(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)}},ce=()=>{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),wa({...j,turns:j.turns.slice(0,t)}),window.setTimeout(()=>k.current?.focus(),0)},[le,P=``]=R(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:R(e,`chat.eyebrow`)}),(0,x.jsx)(`h1`,{tabIndex:-1,"data-dialog-focus-fallback":!0,"data-testid":z(`chat.title`),children:R(e,`chat.title`)}),(0,x.jsx)(`p`,{children:R(e,`chat.intro`)})]}),(0,x.jsxs)(`div`,{className:`chat-toolbar`,children:[(0,x.jsx)(N,{onClick:ae,disabled:v||b||C||o.length>=50,children:R(e,`chat.new_conversation`)}),(0,x.jsx)(Se,{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)(Se,{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} · ${qn(e,t.lifecycle.state)}`}))]})]}),re?null:(0,x.jsx)(B,{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)(Ce,{label:R(e,`chat.settings.name`),value:j.title,disabled:v||b||C,onChange:e=>wa({...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:Vi,disabled:v||b||C,onChange:e=>wa({...j,systemPrompt:e.target.value})})]}),(0,x.jsxs)(`p`,{children:[le,(0,x.jsx)(`a`,{href:`#settings`,children:R(e,`nav.settings`)}),P]}),(0,x.jsx)(N,{disabled:v||b||C,onClick:()=>{Ca(o.filter(e=>e.id!==j.id)),c(null)},children:R(e,`chat.settings.delete`)})]}):null,(0,x.jsx)(za,{defaults:r,draft:i,onChange:a,locale:e}),(0,x.jsx)(Fa,{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)(De,{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:ce,onClose:()=>E(null)}),p?(0,x.jsx)(B,{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:Vi,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(),se())}})]}),(0,x.jsx)(`p`,{children:R(e,`chat.composer.hint`,{count:String(l.length),max:String(Vi)})}),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),Bi(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:()=>{se()},children:R(e,`common.send`)}),(0,x.jsx)(N,{disabled:!v,onClick:oe,children:R(e,`chat.stop`)})]})]}),(0,x.jsx)(`p`,{role:`status`,"aria-live":`polite`,"aria-atomic":`true`,children:h}),(0,x.jsx)(Ia,{conversations:o,busy:v||C,onPending:S,limits:t.bootstrap?.media_limits,onReplace:e=>{Ca(e),c(null)},locale:e})]})}var Ha=[`models`,`chat`,`activity`,`settings`,`gallery`],Ua=[`models`,`chat`,`activity`,`settings`];function Wa(){let e=window.location.hash.slice(1).replace(/^\//,``);return Ha.includes(e)?e:`models`}function Ga(){let e=Sn(),t=Cn(),[n,r]=(0,_.useState)(Wa),[i,a]=(0,_.useState)(Lr),[o,s]=(0,_.useState)(null),[c,l]=(0,_.useState)(null),u=(0,_.useRef)(0);(0,_.useEffect)(()=>()=>{u.current+=1},[]),(0,_.useEffect)(()=>{let e=()=>r(Wa());return window.addEventListener(`hashchange`,e),()=>window.removeEventListener(`hashchange`,e)},[]),(0,_.useEffect)(()=>{if(Br(document.documentElement,i),Rr(i),i.colorScheme===`system`)return Dr(e=>Br(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`&&Ca([])},[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(Fn(e)))})},p=()=>{u.current+=1,l(null),t.logout()},m=Ka(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)(pr,{locale:i.locale,route:n,onRouteChange:d,onCommand:()=>s(`command`),onHelp:()=>s(`help`),selectedModel:In(i.locale,e),connectionLabel:Ln(i.locale,e),connectionState:e.connection,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:m}),(0,x.jsx)(Qa,{open:o===`command`,locale:i.locale,onClose:()=>s(null),onNavigate:e=>{d(e),s(null)}}),(0,x.jsxs)(Ee,{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.jsxs)(`ul`,{className:`shortcut-list`,children:[(0,x.jsxs)(`li`,{children:[(0,x.jsx)(`kbd`,{children:`⌘/Ctrl`}),` + `,(0,x.jsx)(`kbd`,{children:`K`}),` `,R(i.locale,`command.search`)]}),(0,x.jsxs)(`li`,{children:[(0,x.jsx)(`kbd`,{children:`Esc`}),` `,R(i.locale,`common.cancel`)]}),(0,x.jsxs)(`li`,{children:[(0,x.jsx)(`kbd`,{children:`[`}),` / `,(0,x.jsx)(`kbd`,{children:`]`}),` `,R(i.locale,`nav.models`)]})]})]})]})}function Ka(e,t,n,r){return e===`models`?(0,x.jsx)(qa,{locale:t.locale,context:r}):e===`chat`?(0,x.jsx)(Ja,{locale:t.locale,context:r}):e===`activity`?(0,x.jsx)(Ya,{locale:t.locale,context:r}):e===`settings`?(0,x.jsx)(Xa,{appearance:t,setAppearance:n}):(0,x.jsx)(ki,{locale:t.locale})}function qa(e){return e.context.snapshot.auth.status===`authenticated`&&e.context.snapshot.connection!==`schema-mismatch`?(0,x.jsx)(wi,{locale:e.locale}):(0,x.jsx)(zn,{locale:e.locale,eyebrow:R(e.locale,`routes.models.eyebrow`),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 Ja(e){return e.context.snapshot.auth.status===`authenticated`&&e.context.snapshot.connection!==`schema-mismatch`?(0,x.jsx)(Va,{locale:e.locale}):(0,x.jsx)(zn,{locale:e.locale,eyebrow:R(e.locale,`routes.chat.eyebrow`),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 Ya(e){return e.context.snapshot.auth.status===`authenticated`&&![`schema-mismatch`,`forbidden`,`unauthorized`].includes(e.context.snapshot.connection)?(0,x.jsx)(ti,{locale:e.locale}):(0,x.jsx)(zn,{locale:e.locale,eyebrow:R(e.locale,`routes.activity.eyebrow`),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 Xa(e){let t=t=>e.setAppearance({...e.appearance,...t});return(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsxs)(`section`,{className:`screen-heading`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:R(e.appearance.locale,`routes.settings.eyebrow`)}),(0,x.jsx)(`h1`,{tabIndex:-1,"data-dialog-focus-fallback":!0,"data-testid":z(`settings.title`),children:R(e.appearance.locale,`settings.title`)}),(0,x.jsx)(`p`,{"data-testid":z(`settings.appearance`),children:R(e.appearance.locale,`settings.browser_only`)})]}),(0,x.jsxs)(`div`,{className:`settings-grid`,children:[(0,x.jsx)(Se,{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)(Se,{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)(Se,{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)(Se,{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)(Se,{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)(Za,{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)(Za,{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)(B,{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)(dr,{locale:e.appearance.locale})]})}function Za(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 Qa(e){let[t,n]=(0,_.useState)(``),r=(e.locale&&window.location.hash.includes(`gallery`)?Ha:Ua).filter(e=>e.includes(t.toLowerCase()));return(0,x.jsxs)(Ee,{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)(Ce,{label:R(e.locale,`command.search`),value:t,onChange:n,testId:z(`command.search`)}),r.length===0?(0,x.jsx)(`p`,{"data-testid":z(`command.no_results`),children:R(e.locale,`command.no_results`)}):(0,x.jsx)(`div`,{className:`command-list`,children:r.map(t=>(0,x.jsx)(N,{onClick:()=>e.onNavigate(t),children:R(e.locale,t===`models`?`nav.models`:t===`chat`?`nav.chat`:t===`activity`?`nav.activity`:t===`settings`?`nav.settings`:`nav.gallery`)},t))})]})}var $a=document.getElementById(`root`);if($a===null)throw Error(`Missing #root element for mlxcel WebUI.`);(0,v.createRoot)($a).render((0,x.jsx)(_.StrictMode,{children:(0,x.jsx)(xn,{children:(0,x.jsx)(Ga,{})})}));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-D2RzuY00.css b/src/webui/assets/assets/index-D2RzuY00.css deleted file mode 100644 index 89aa0c120..000000000 --- a/src/webui/assets/assets/index-D2RzuY00.css +++ /dev/null @@ -1 +0,0 @@ -: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)}.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}}.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)}.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(--text-secondary);font-size:.85rem}.models-library .models-selected{background:var(--surface-selected,var(--surface-hover))}.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}.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);--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-tint:#4c5d870f;--material-glass-alpha:.72;--material-glass-blur:18px;--material-glass-saturation:118%;--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;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=dark]{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}:root[data-theme=light]{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light}@media (prefers-color-scheme:dark){:root:not([data-theme=light]){--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-tint:#6b89d21a;--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}}:root[data-theme=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-tint:#6b89d21a;--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}: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);--material-glass-blur:0px;--material-glass-saturation:100%}: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{--material-glass-bg:var(--color-bg-elevated);--material-glass-blur:0px}}@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))}@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,.ds-icon-button:hover{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:#245bd8;border-color:#245bd8}.ds-button-danger{color:#fff;background:#c6352b;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-sheet[data-position=left]{width:min(320px,100vw - 32px);min-height:calc(100vh - 24px);margin:12px auto 12px 12px}.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{--token-borderRadius:var(--radius-sm);--token-borderRadiusLG:var(--radius-lg);--token-borderRadiusSM:var(--radius-xs);--token-borderRadiusXL:var(--radius-xl);--token-boxShadow:var(--shadow-card);--token-boxShadowDrawerRight:var(--shadow-card);--token-boxShadowSecondary:var(--shadow-card);--token-boxShadowTertiary:var(--shadow-chrome);--token-buttonActiveTransform:none;--token-buttonBorderRadius:999px;--token-buttonDangerBg:#c6352b;--token-buttonDangerBgActive:#aa2b23;--token-buttonDangerBgHover:#aa2b23;--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:#245bd8;--token-buttonPrimaryBgActive:#1c4dbc;--token-buttonPrimaryBgHover:#1c4dbc;--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-controlHeight:36px;--token-controlHeightLG:44px;--token-controlHeightSM:32px;--token-focusRingColor:var(--color-focus);--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-tabActiveBg:var(--color-bg-elevated);--token-tabFocusShadow:var(--focus-ring);--token-tabHoverBg:var(--color-selection);--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)}.ds-common-table{color:var(--color-text);background:var(--material-content-bg);border-radius:var(--radius-lg)}@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} diff --git a/src/webui/assets/assets/index-jceAf1an.css b/src/webui/assets/assets/index-jceAf1an.css new file mode 100644 index 000000000..754e42231 --- /dev/null +++ b/src/webui/assets/assets/index-jceAf1an.css @@ -0,0 +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;--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;--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]{--material-control-backdrop:blur(calc(var(--material-glass-blur) / 2)) saturate(var(--material-glass-saturation));--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-button-shadow);--token-buttonDangerShadowHover:var(--glass-button-shadow);--token-buttonPrimaryBorder:1px solid var(--glass-edge);--token-buttonPrimaryShadow:var(--glass-button-shadow);--token-buttonPrimaryShadowHover:var(--glass-button-shadow);--token-buttonSecondaryBackdrop:var(--material-control-backdrop);--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);--material-control-backdrop:none;--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);--material-control-backdrop:none;--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);--material-control-backdrop:none;--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}}.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)}.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}.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,.ds-icon-button:hover{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:#245bd8;border-color:#245bd8}.ds-button-danger{color:#fff;background:#c6352b;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-sheet[data-position=left]{width:min(320px,100vw - 32px);min-height:calc(100vh - 24px);margin:12px auto 12px 12px}.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)}.ds-common-table{color:var(--color-text);background:var(--material-content-bg);border-radius:var(--radius-lg)}@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} diff --git a/src/webui/assets/index.html b/src/webui/assets/index.html index 66d802b14..74d47d0dd 100644 --- a/src/webui/assets/index.html +++ b/src/webui/assets/index.html @@ -5,8 +5,9 @@ mlxcel WebUI - - + + +
diff --git a/src/webui/assets/mlxcel-webui-manifest.json b/src/webui/assets/mlxcel-webui-manifest.json index 09674f9d4..148442008 100644 --- a/src/webui/assets/mlxcel-webui-manifest.json +++ b/src/webui/assets/mlxcel-webui-manifest.json @@ -1,42 +1,48 @@ { "budgets": { - "embedded_asset_bytes": 701121, + "embedded_asset_bytes": 709847, "embedded_asset_limit_bytes": 5242880, - "initial_js_gzip_bytes": 151627, + "initial_js_gzip_bytes": 153101, "initial_js_gzip_limit_bytes": 204800, - "total_js_gzip_bytes": 152805, + "total_js_gzip_bytes": 154278, "total_js_gzip_limit_bytes": 716800 }, "files": [ { "bytes": 951, "gzip_bytes": 613, - "path": "assets/code-highlight-DYgjCuFT.js", - "sha256": "0728c7d4379f474c6448d4b9c9fd18525ce6c5aef9cfe3d5b59d92038b167d1d" + "path": "assets/code-highlight-B7JRfpaI.js", + "sha256": "2bd5cc50017fba75d668f64f46b301623cf9ee326f7900aa3b5563e7313698ec" }, { "bytes": 1134, - "gzip_bytes": 565, - "path": "assets/history-BhdDGTqa.js", - "sha256": "60f6d27247051c462b179e3c4f69e48d4581274fc9ee10165f00816a64d9f00b" + "gzip_bytes": 564, + "path": "assets/history-DIlBLmUk.js", + "sha256": "effb9ea9109ad0a30ebe6d6d59259d697bf212813cbbee1600df260fdb237393" }, { - "bytes": 590691, - "gzip_bytes": 151627, - "path": "assets/index-CW0N8nOa.js", - "sha256": "f9ace454ed16b978e6b5e1c248f7c62dbc8cf9e000c675807b4c1b4a65c6d806" + "bytes": 592551, + "gzip_bytes": 152112, + "path": "assets/index-C5rxJd1U.js", + "sha256": "b37d59059bf5ee3ad19a9c6bd81cfe6897312d2d337b68198ac8d4814e401bb2" }, { - "bytes": 92565, - "gzip_bytes": 15068, - "path": "assets/index-D2RzuY00.css", - "sha256": "753e82fed30cca52c47eb6d460336a564ceaee389d32653c016d67775658ef21" + "bytes": 97074, + "gzip_bytes": 15758, + "path": "assets/index-jceAf1an.css", + "sha256": "c837f22d8238d1eea1ac7d8af56c1e59ece112f22c977f702d0fecf35f2ffbad" }, { - "bytes": 453, - "gzip_bytes": 289, + "bytes": 503, + "gzip_bytes": 301, "path": "index.html", - "sha256": "b61c1196f414620d76cf8871e4287fcd99b44d7b71639a9715f55041689f7f80" + "sha256": "d4483ba260e75a30c9a1f6cf9f1869453262884d9edf39bdcfc42f2ac1c5c844" + }, + { + "bytes": 2129, + "gzip_bytes": 989, + "path": "theme-bootstrap.js", + "sha256": "731929d04a3407095caf1e6ee8cf6c6c1c8ddc31e592b45931322e94a9352b49" }, { "bytes": 13233, @@ -67,5 +73,5 @@ }, "pnpm_version": "11.18.0", "schema_version": 1, - "source_digest_sha256": "64a3f8c671cade1bbe86e517beee85f347b19ebb3719de5901733eae21182daf" + "source_digest_sha256": "9ea251b8fceace39c70542e3d6f2277b28e4690a7889da58a6ca4636d54c7550" } diff --git a/src/webui/assets/theme-bootstrap.js b/src/webui/assets/theme-bootstrap.js new file mode 100644 index 000000000..d1ff42c50 --- /dev/null +++ b/src/webui/assets/theme-bootstrap.js @@ -0,0 +1,44 @@ +/* Copyright 2025-2026 Lablup Inc. Licensed under the Apache License, Version 2.0. */ +/* global window, document */ +// Early theme bootstrap. index.html loads this as a classic, render-blocking +// script ahead of the stylesheet and the app module, so the document root +// carries the applied `-` id before the first paint and the page +// never flashes the wrong theme while the app boots. It is an external file +// rather than an inline script because the served CSP is `script-src 'self'`. +// +// It mirrors resolveThemeSelection() in src/design-system/theme.ts and the +// stored-preference rules in src/design-system/preferences.ts, including the +// pre-#1903 flat `theme` field. src/design-system/theme-bootstrap.test.ts runs +// this file against applyAppearance() over a matrix of stored values, so a +// change on one side without the other fails the unit gate. +(function () { + 'use strict'; + var families = ['mlxcel', 'glass']; + var preferences = ['system', 'light', 'dark']; + var family = 'mlxcel'; + var preference = 'system'; + try { + var raw = window.localStorage.getItem('mlxcel.webui.appearance'); + var stored = raw ? JSON.parse(raw) : null; + if (stored && typeof stored === 'object' && !Array.isArray(stored)) { + if (families.indexOf(stored.themeFamily) !== -1) family = stored.themeFamily; + if (preferences.indexOf(stored.colorScheme) !== -1) preference = stored.colorScheme; + else if (stored.colorScheme === undefined && preferences.indexOf(stored.theme) !== -1) preference = stored.theme; + } + } catch { + // Blocked or corrupt storage keeps the defaults, exactly as loadAppearance() does. + } + var scheme = preference; + if (scheme === 'system') { + scheme = 'light'; + try { + if (typeof window.matchMedia === 'function' && window.matchMedia('(prefers-color-scheme: dark)').matches) scheme = 'dark'; + } catch { + scheme = 'light'; + } + } + var root = document.documentElement; + root.setAttribute('data-theme', family + '-' + scheme); + root.setAttribute('data-theme-family', family); + root.setAttribute('data-color-scheme', preference); +})(); diff --git a/tests/fixtures/webui/strings.json b/tests/fixtures/webui/strings.json index 55013681d..82909d03d 100644 --- a/tests/fixtures/webui/strings.json +++ b/tests/fixtures/webui/strings.json @@ -414,6 +414,12 @@ "ko": "테마", "test_id": "settings-theme" }, + { + "key": "settings.color_scheme", + "en": "Color scheme", + "ko": "색상 모드", + "test_id": "settings-color-scheme" + }, { "key": "settings.material", "en": "Material", @@ -841,22 +847,34 @@ "test_id": "common-close" }, { - "key": "settings.theme.system", + "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-theme-system" + "test_id": "settings-color-scheme-system" }, { - "key": "settings.theme.light", + "key": "settings.color_scheme.light", "en": "Light", "ko": "라이트", - "test_id": "settings-theme-light" + "test_id": "settings-color-scheme-light" }, { - "key": "settings.theme.dark", + "key": "settings.color_scheme.dark", "en": "Dark", "ko": "다크", - "test_id": "settings-theme-dark" + "test_id": "settings-color-scheme-dark" }, { "key": "settings.material.glass", diff --git a/webui/index.html b/webui/index.html index 664f2d96e..263e6b86a 100644 --- a/webui/index.html +++ b/webui/index.html @@ -5,6 +5,7 @@ mlxcel WebUI +
diff --git a/webui/package.json b/webui/package.json index 9e6fe0439..71d3e7b9a 100644 --- a/webui/package.json +++ b/webui/package.json @@ -8,7 +8,8 @@ "build": "vite build", "typecheck": "tsc --noEmit", "lint": "eslint . --max-warnings=0", - "unit": "node --test scripts/activity-stream.spec.mjs && vitest run", + "unit": "node --test scripts/activity-stream.spec.mjs scripts/check-theme-selectors.spec.mjs && vitest run", + "check:theme-selectors": "node scripts/check-theme-selectors.mjs", "browser": "playwright test --project=chromium", "browser:all": "playwright test --config playwright.engines.config.ts", "browser:rust-router": "playwright test --config playwright.rust-router.config.ts", diff --git a/webui/public/theme-bootstrap.js b/webui/public/theme-bootstrap.js new file mode 100644 index 000000000..d1ff42c50 --- /dev/null +++ b/webui/public/theme-bootstrap.js @@ -0,0 +1,44 @@ +/* Copyright 2025-2026 Lablup Inc. Licensed under the Apache License, Version 2.0. */ +/* global window, document */ +// Early theme bootstrap. index.html loads this as a classic, render-blocking +// script ahead of the stylesheet and the app module, so the document root +// carries the applied `-` id before the first paint and the page +// never flashes the wrong theme while the app boots. It is an external file +// rather than an inline script because the served CSP is `script-src 'self'`. +// +// It mirrors resolveThemeSelection() in src/design-system/theme.ts and the +// stored-preference rules in src/design-system/preferences.ts, including the +// pre-#1903 flat `theme` field. src/design-system/theme-bootstrap.test.ts runs +// this file against applyAppearance() over a matrix of stored values, so a +// change on one side without the other fails the unit gate. +(function () { + 'use strict'; + var families = ['mlxcel', 'glass']; + var preferences = ['system', 'light', 'dark']; + var family = 'mlxcel'; + var preference = 'system'; + try { + var raw = window.localStorage.getItem('mlxcel.webui.appearance'); + var stored = raw ? JSON.parse(raw) : null; + if (stored && typeof stored === 'object' && !Array.isArray(stored)) { + if (families.indexOf(stored.themeFamily) !== -1) family = stored.themeFamily; + if (preferences.indexOf(stored.colorScheme) !== -1) preference = stored.colorScheme; + else if (stored.colorScheme === undefined && preferences.indexOf(stored.theme) !== -1) preference = stored.theme; + } + } catch { + // Blocked or corrupt storage keeps the defaults, exactly as loadAppearance() does. + } + var scheme = preference; + if (scheme === 'system') { + scheme = 'light'; + try { + if (typeof window.matchMedia === 'function' && window.matchMedia('(prefers-color-scheme: dark)').matches) scheme = 'dark'; + } catch { + scheme = 'light'; + } + } + var root = document.documentElement; + root.setAttribute('data-theme', family + '-' + scheme); + root.setAttribute('data-theme-family', family); + root.setAttribute('data-color-scheme', preference); +})(); diff --git a/webui/scripts/check-theme-selectors.mjs b/webui/scripts/check-theme-selectors.mjs new file mode 100644 index 000000000..c7b759b7d --- /dev/null +++ b/webui/scripts/check-theme-selectors.mjs @@ -0,0 +1,278 @@ +#!/usr/bin/env node +// Copyright 2025-2026 Lablup Inc. Licensed under the Apache License, Version 2.0. +/* global process, console, URL */ +/** + * Theme-selector gate (#1903). Fails when WebUI code gates on a theme id no + * shipped theme can produce, or on a signal that is not the applied theme. + * + * The app writes `data-theme` from a ThemeId, which is always + * `-` (src/design-system/theme.ts: mlxcel-light, glass-dark, + * and so on). A bare light or dark value therefore never matches. It is not a + * parse error, nothing warns, and the page still renders: dark mode simply + * stops applying. The same silent failure follows from: + * + * - a `data-color-scheme` selector: that attribute carries the stored + * preference verbatim, so it reads `system` unless the user pinned a + * scheme, and the rule fires with no relationship to what is on screen; + * - `@media (prefers-color-scheme: ...)` in a stylesheet, or a + * `prefers-color-scheme` query in app code: it reflects the host OS, while + * the applied theme reflects the in-app choice. Only the resolver + * (src/design-system/theme.ts) and the pre-mount bootstrap + * (public/theme-bootstrap.js) consult it, to resolve `system` before + * `data-theme` is written; + * - a theme stylesheet imported anywhere but the single entry: ui-common's + * rule is at most one theme file alongside base.css, and components never + * import a theme file themselves. + * + * Working selectors are the explicit id (`[data-theme="glass-dark"]`), or a + * prefix or suffix that matches at least one shipped id (`[data-theme$="-dark"]` + * for every family). The gate evaluates every data-theme attribute selector, + * whatever its operator, against the ids theme.ts exports, and it also checks + * that every shipped id has a theme block under src/design-system/themes/. + * + * Escape hatch: a genuine host-OS concern can keep its query by carrying a + * written reason on the same line or the line before it, for example + * + * theme-selector-allow: print stylesheet, the document has no data-theme + * + * inside a comment. The reason is mandatory, so an exemption is a sentence + * someone defends in review rather than a silent bypass. + * + * Usage: + * pnpm --dir webui run check:theme-selectors + * + * Exit code 1 on any violation; under CI each violation is also printed as a + * GitHub ::error annotation on the offending line. + */ + +import { readdirSync, readFileSync, statSync } from 'node:fs'; +import { dirname, extname, join, relative, resolve, sep } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +import { THEME_FAMILIES, THEME_IDS } from '../src/design-system/theme.ts'; + +const SCANNED_EXTENSIONS = new Set(['.css', '.ts', '.tsx', '.js', '.mjs', '.html']); +const SCRIPT_EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.mjs']); +const THEMES_DIR = 'src/design-system/themes'; +const THEME_ENTRY_CSS = `${THEMES_DIR}/index.css`; +const THEME_ENTRY_IMPORTER = 'src/main.tsx'; +const UI_COMMON_THEMES = '@lablup/ui-common/styles/themes/'; +/** The only app files allowed to ask the host for its color scheme. */ +const SYSTEM_SCHEME_RESOLVERS = new Set(['src/design-system/theme.ts', 'public/theme-bootstrap.js']); + +/** + * A reason must start with something other than a comment delimiter, so that a + * bare marker does not read its own closing delimiter as the reason. + */ +const ALLOW_RE = /theme-selector-allow:\s*([^\s*/][^*\n]*)/; + +/** `[attr]`, `[attr="v"]`, `[attr^='v' i]`, `[attr=v]` for the three theme attributes. */ +const ATTRIBUTE_SELECTOR_RE = /\[\s*(data-theme-family|data-color-scheme|data-theme)\s*(?:([~|^$*]?=)\s*(?:"([^"]*)"|'([^']*)'|([^\s\]"'`]+))\s*([iIsS])?\s*)?\]/g; +const MEDIA_COLOR_SCHEME_RE = /@media[^{;]*prefers-color-scheme/g; +const ANY_COLOR_SCHEME_RE = /prefers-color-scheme/g; +/** Literal values compared with, or written to, data-theme in script code. */ +const SCRIPT_THEME_VALUE_RES = [ + /\.dataset\.theme\s*(?:===?|!==?)\s*(['"])([^'"\n]*)\1/g, + /(['"])([^'"\n]*)\1\s*(?:===?|!==?)\s*[\w$.?]*\.dataset\.theme\b/g, + /\.dataset\.theme\s*=(?!=)\s*(['"])([^'"\n]*)\1/g, + /getAttribute\(\s*['"]data-theme['"]\s*\)\s*(?:===?|!==?)\s*(['"])([^'"\n]*)\1/g, + /setAttribute\(\s*['"]data-theme['"]\s*,\s*(['"])([^'"\n]*)\1/g, + /toHaveAttribute\(\s*['"]data-theme['"]\s*,\s*(['"])([^'"\n]*)\1/g, +]; +const CSS_IMPORT_RE = /@import\s+(?:url\(\s*)?(['"]?)([^'")\s;]+)\1/g; +const SCRIPT_IMPORT_RE = /(?:\bimport\s+(?:[\w$*{}\s,]+\s+from\s+)?|\bimport\(\s*|\brequire\(\s*)(['"])([^'"\n]+)\1/g; + +/** Evaluates one attribute selector against a candidate value, per Selectors Level 4. */ +export function attributeMatches(operator, value, caseInsensitive, candidate) { + const wanted = caseInsensitive ? value.toLowerCase() : value; + const actual = caseInsensitive ? candidate.toLowerCase() : candidate; + switch (operator) { + case '=': + return actual === wanted; + case '^=': + return wanted !== '' && actual.startsWith(wanted); + case '$=': + return wanted !== '' && actual.endsWith(wanted); + case '*=': + return wanted !== '' && actual.includes(wanted); + case '~=': + return wanted !== '' && !/\s/.test(wanted) && actual.split(/\s+/).includes(wanted); + case '|=': + return actual === wanted || actual.startsWith(`${wanted}-`); + default: + return false; + } +} + +/** Byte offset to 1-indexed line, via binary search over precomputed starts. */ +function lineIndex(source) { + const starts = [0]; + for (let index = 0; index < source.length; index += 1) { + if (source[index] === '\n') starts.push(index + 1); + } + return (offset) => { + let low = 0; + let high = starts.length - 1; + while (low < high) { + const middle = (low + high + 1) >> 1; + if (starts[middle] <= offset) low = middle; + else high = middle - 1; + } + return low + 1; + }; +} + +/** True when the line, or the one above it, carries a non-empty allow reason. */ +function isAllowed(lines, line) { + const own = lines[line - 1] ?? ''; + const above = lines[line - 2] ?? ''; + const match = ALLOW_RE.exec(own) ?? ALLOW_RE.exec(above); + return Boolean(match && match[1].trim().length > 0); +} + +function describeIds(ids) { + return ids.join(', '); +} + +function isThemeStylesheetSpecifier(fromPath, specifier) { + if (specifier.startsWith(UI_COMMON_THEMES)) return true; + if (!specifier.startsWith('.')) return false; + const target = join(dirname(fromPath), specifier).split(sep).join('/'); + return target === THEMES_DIR || target.startsWith(`${THEMES_DIR}/`); +} + +/** + * Finds every violation across the given sources. Paths are relative to the + * webui/ directory with forward slashes. Exported so the spec can drive it + * without touching the filesystem. + */ +export function findThemeSelectorViolations(sources, options = {}) { + const themeIds = options.themeIds ?? THEME_IDS; + const families = options.families ?? THEME_FAMILIES; + const violations = []; + const declaredIds = new Set(); + let entryImports = 0; + + for (const { path, source } of sources) { + const lines = source.split('\n'); + const toLine = lineIndex(source); + const extension = extname(path); + const isScript = SCRIPT_EXTENSIONS.has(extension); + const report = (offset, rule, message) => { + const line = toLine(offset); + if (isAllowed(lines, line)) return; + violations.push({ path, line, rule, message, text: (lines[line - 1] ?? '').trim() }); + }; + + for (const match of source.matchAll(ATTRIBUTE_SELECTOR_RE)) { + const [, attribute, operator] = match; + if (operator === undefined) continue; + const value = match[3] ?? match[4] ?? match[5] ?? ''; + if (value.includes('${')) continue; + const caseInsensitive = match[6] === 'i' || match[6] === 'I'; + if (attribute === 'data-color-scheme') { + report(match.index, 'data-color-scheme', `${match[0]} reads the stored preference, which holds "system" unless the user pinned a scheme. Gate on the applied theme instead, for example [data-theme$="-dark"].`); + continue; + } + const candidates = attribute === 'data-theme' ? themeIds : families; + if (!candidates.some((candidate) => attributeMatches(operator, value, caseInsensitive, candidate))) { + const kind = attribute === 'data-theme' ? 'theme id' : 'theme family'; + report(match.index, 'dead-theme-selector', `${match[0]} matches no shipped ${kind} (${describeIds(candidates)}), so the rule never applies. data-theme is always -; use [data-theme$="-dark"] or an explicit id.`); + } else if (attribute === 'data-theme' && operator === '=' && path.startsWith(`${THEMES_DIR}/`)) { + declaredIds.add(caseInsensitive ? value.toLowerCase() : value); + } + } + + if (extension === '.css') { + for (const match of source.matchAll(MEDIA_COLOR_SCHEME_RE)) { + report(match.index, 'prefers-color-scheme', '@media (prefers-color-scheme) follows the host OS, not the applied theme: it lands on a light surface under a dark OS and never fires for a dark theme under a light OS. Gate on [data-theme$="-dark"] or [data-theme$="-light"], or annotate a genuine OS-level concern with "theme-selector-allow: ".'); + } + for (const match of source.matchAll(CSS_IMPORT_RE)) { + if (isThemeStylesheetSpecifier(path, match[2]) && path !== THEME_ENTRY_CSS) { + report(match.index, 'theme-import', `${match[2]} is a theme stylesheet; only ${THEME_ENTRY_CSS} may import one.`); + } + } + } + + if (isScript) { + if ((path.startsWith('src/') || path.startsWith('public/')) && !SYSTEM_SCHEME_RESOLVERS.has(path)) { + for (const match of source.matchAll(ANY_COLOR_SCHEME_RE)) { + report(match.index, 'prefers-color-scheme', `prefers-color-scheme is consulted only by ${[...SYSTEM_SCHEME_RESOLVERS].join(' and ')}; read the applied theme (data-theme) or use resolveThemeSelection() instead.`); + } + } + for (const pattern of SCRIPT_THEME_VALUE_RES) { + for (const match of source.matchAll(pattern)) { + const value = match[2]; + if (value === '' || themeIds.includes(value)) continue; + report(match.index, 'dead-theme-value', `"${value}" is not a shipped theme id (${describeIds(themeIds)}); data-theme is always -.`); + } + } + for (const match of source.matchAll(SCRIPT_IMPORT_RE)) { + if (!isThemeStylesheetSpecifier(path, match[2])) continue; + if (path !== THEME_ENTRY_IMPORTER) { + report(match.index, 'theme-import', `${match[2]} is a theme stylesheet; components never import one, only ${THEME_ENTRY_IMPORTER} imports the single theme entry.`); + } else { + entryImports += 1; + if (entryImports > 1) report(match.index, 'theme-import', `${THEME_ENTRY_IMPORTER} imports more than one theme stylesheet; ui-common allows at most one alongside base.css (${THEME_ENTRY_CSS}).`); + } + } + } + } + + if (options.requireCoverage !== false) { + for (const id of themeIds) { + if (!declaredIds.has(id)) { + violations.push({ path: THEMES_DIR, line: 0, rule: 'missing-theme', message: `Theme id "${id}" is shipped by theme.ts but no [data-theme="${id}"] block exists under ${THEMES_DIR}/, so selecting it would render ui-common's defaults.`, text: '' }); + } + } + } + + return violations.sort((left, right) => (left.path === right.path ? left.line - right.line : left.path < right.path ? -1 : 1)); +} + +function collectFiles(root, directory, files) { + for (const entry of readdirSync(directory)) { + if (entry === 'node_modules' || entry.startsWith('.')) continue; + const full = join(directory, entry); + if (statSync(full).isDirectory()) collectFiles(root, full, files); + else if (SCANNED_EXTENSIONS.has(extname(entry))) files.push(full); + } + return files; +} + +/** Reads every scanned WebUI source; paths come back relative to webui/. */ +export function collectSources(webuiRoot) { + const files = []; + for (const directory of ['src', 'public', 'tests']) collectFiles(webuiRoot, join(webuiRoot, directory), files); + files.push(join(webuiRoot, 'index.html')); + return files.map((full) => ({ path: relative(webuiRoot, full).split(sep).join('/'), source: readFileSync(full, 'utf8') })); +} + +function main() { + const webuiRoot = resolve(fileURLToPath(new URL('.', import.meta.url)), '..'); + const sources = collectSources(webuiRoot); + const stylesheets = sources.filter((source) => source.path.endsWith('.css')); + if (stylesheets.length === 0 || !sources.some((source) => source.path.startsWith(`${THEMES_DIR}/`))) { + console.error(`Theme-selector check: no stylesheets under ${THEMES_DIR}/. Refusing to pass, since every dead gate would look absent.`); + process.exit(1); + } + const violations = findThemeSelectorViolations(sources); + if (violations.length === 0) { + console.log(`Theme selectors: ${sources.length} WebUI file(s) checked against ${THEME_IDS.length} theme ids (${describeIds(THEME_IDS)}); no dead theme gate.`); + process.exit(0); + } + console.error(`\nTheme-selector check failed: ${violations.length} violation(s).\n`); + for (const violation of violations) { + console.error(` webui/${violation.path}${violation.line ? `:${violation.line}` : ''} [${violation.rule}] ${violation.text}`); + console.error(` ${violation.message}\n`); + } + if (process.env.CI === 'true' || process.env.CI === '1') { + for (const violation of violations) { + console.error(`::error file=webui/${violation.path}${violation.line ? `,line=${violation.line}` : ''}::${violation.message}`); + } + } + process.exit(1); +} + +const invokedDirectly = import.meta.url.startsWith('file:') && process.argv[1] && resolve(process.argv[1]) === resolve(fileURLToPath(import.meta.url)); +if (invokedDirectly) main(); diff --git a/webui/scripts/check-theme-selectors.spec.mjs b/webui/scripts/check-theme-selectors.spec.mjs new file mode 100644 index 000000000..59c0a5c66 --- /dev/null +++ b/webui/scripts/check-theme-selectors.spec.mjs @@ -0,0 +1,164 @@ +// Copyright 2025-2026 Lablup Inc. Licensed under the Apache License, Version 2.0. +/* global URL */ +import assert from 'node:assert/strict'; +import { readFileSync } from 'node:fs'; +import { resolve } from 'node:path'; +import { test } from 'node:test'; +import { fileURLToPath } from 'node:url'; + +import { attributeMatches, collectSources, findThemeSelectorViolations } from './check-theme-selectors.mjs'; + +const webuiRoot = resolve(fileURLToPath(new URL('.', import.meta.url)), '..'); +const THEME_BLOCKS = { + path: 'src/design-system/themes/fixture.css', + source: ['mlxcel-light', 'mlxcel-dark', 'glass-light', 'glass-dark'].map((id) => `[data-theme="${id}"] { --x: 1; }`).join('\n'), +}; + +function scan(path, source) { + return findThemeSelectorViolations([THEME_BLOCKS, { path, source }]); +} + +function rules(violations) { + return violations.map((violation) => `${violation.rule}@${violation.line}`); +} + +test('the checked-in WebUI tree passes', () => { + assert.deepEqual(findThemeSelectorViolations(collectSources(webuiRoot)), []); +}); + +test('reintroducing a bare dark selector into the real tokens.css fails the gate', () => { + const sources = collectSources(webuiRoot); + const tokens = sources.find((source) => source.path === 'src/design-system/tokens.css'); + assert.ok(tokens, 'tokens.css is scanned'); + tokens.source += '\n:root[data-theme="dark"] { color-scheme: dark; }\n'; + const violations = findThemeSelectorViolations(sources); + assert.equal(violations.length, 1); + assert.equal(violations[0].rule, 'dead-theme-selector'); + assert.equal(violations[0].path, 'src/design-system/tokens.css'); +}); + +test('the pre-#1903 selectors are all dead under family-scoped ids', () => { + const legacy = [ + ':root[data-theme="dark"] { color-scheme: dark; }', + ':root[data-theme="light"] { color-scheme: light; }', + '@media (prefers-color-scheme: dark) {', + ' :root:not([data-theme="light"]) { --color-bg: #0e1117; }', + '}', + ':root[data-theme="system"] { --x: 1; }', + ].join('\n'); + assert.deepEqual(rules(scan('src/design-system/tokens.css', legacy)), [ + 'dead-theme-selector@1', + 'dead-theme-selector@2', + 'prefers-color-scheme@3', + 'dead-theme-selector@4', + 'dead-theme-selector@6', + ]); +}); + +test('selectors that match a shipped id pass, whatever the operator', () => { + const live = [ + ':root[data-theme$="-dark"] { color-scheme: dark; }', + ':root[data-theme$=\'-light\'] { color-scheme: light; }', + '[data-theme^="glass-"] { --x: 1; }', + '[data-theme|="mlxcel"] { --x: 1; }', + '[data-theme*="ass-da"] { --x: 1; }', + '[data-theme~="glass-dark"] { --x: 1; }', + '[data-theme="GLASS-DARK" i] { --x: 1; }', + '[data-theme=mlxcel-light] { --x: 1; }', + '[data-theme] { --x: 1; }', + '[data-theme-family="glass"] { --x: 1; }', + ].join('\n'); + assert.deepEqual(scan('src/features/example.css', live), []); +}); + +test('selectors that match no shipped id or family fail, including case and prefix slips', () => { + const dead = [ + '[data-theme="GLASS-DARK"] { --x: 1; }', + '[data-theme^="orange-"] { --x: 1; }', + '[data-theme$="-dim"] { --x: 1; }', + '[data-theme|="glass-legacy"] { --x: 1; }', + '[data-theme^=""] { --x: 1; }', + '[data-theme-family="orange"] { --x: 1; }', + ].join('\n'); + assert.deepEqual(rules(scan('src/features/example.css', dead)), ['dead-theme-selector@1', 'dead-theme-selector@2', 'dead-theme-selector@3', 'dead-theme-selector@4', 'dead-theme-selector@5', 'dead-theme-selector@6']); +}); + +test('a data-color-scheme value selector is rejected because it holds the raw preference', () => { + assert.deepEqual(rules(scan('src/example.css', '[data-color-scheme="dark"] .x { color: red; }')), ['data-color-scheme@1']); +}); + +test('a selector split across lines is still evaluated', () => { + const wrapped = '.a,\n:root[data-theme\n ="dark"] .b { color: red; }'; + assert.deepEqual(rules(scan('src/example.css', wrapped)), ['dead-theme-selector@2']); +}); + +test('the escape hatch needs a written reason on the same or the preceding line', () => { + const withReason = '/* theme-selector-allow: print stylesheet, the printed document has no data-theme */\n@media (prefers-color-scheme: dark) { .x { color: red; } }'; + assert.deepEqual(scan('src/example.css', withReason), []); + const sameLine = '@media (prefers-color-scheme: dark) { .x { color: red; } } /* theme-selector-allow: host OS overlay */'; + assert.deepEqual(scan('src/example.css', sameLine), []); + const bare = '/* theme-selector-allow: */\n@media (prefers-color-scheme: dark) { .x { color: red; } }'; + assert.deepEqual(rules(scan('src/example.css', bare)), ['prefers-color-scheme@2']); + const tooFar = '/* theme-selector-allow: a reason two lines up */\n\n@media (prefers-color-scheme: dark) { .x { color: red; } }'; + assert.deepEqual(rules(scan('src/example.css', tooFar)), ['prefers-color-scheme@3']); +}); + +test('app code may consult prefers-color-scheme only in the resolver and the bootstrap', () => { + const query = "window.matchMedia('(prefers-color-scheme: dark)');"; + assert.deepEqual(scan('src/design-system/theme.ts', query), []); + assert.deepEqual(scan('public/theme-bootstrap.js', query), []); + assert.deepEqual(rules(scan('src/features/chat/chat.tsx', query)), ['prefers-color-scheme@1']); + // Browser tests emulate the host scheme on purpose. + assert.deepEqual(scan('tests/theme.spec.ts', "await client.send('Emulation.setEmulatedMedia', { features: [{ name: 'prefers-color-scheme', value: 'dark' }] });"), []); +}); + +test('script literals compared with or written to data-theme must be shipped ids', () => { + const source = [ + "if (root.dataset.theme === 'dark') {}", + "if ('light' !== document.documentElement.dataset.theme) {}", + "root.dataset.theme = 'system';", + "root.setAttribute('data-theme', 'dark');", + "await expect(page.locator('html')).toHaveAttribute('data-theme', 'light');", + "if (root.getAttribute('data-theme') === 'glass-dark') {}", + "root.dataset.theme = '';", + "await expect(page.locator('html')).toHaveAttribute('data-theme', 'mlxcel-dark');", + ].join('\n'); + assert.deepEqual(rules(scan('tests/example.spec.ts', source)), ['dead-theme-value@1', 'dead-theme-value@2', 'dead-theme-value@3', 'dead-theme-value@4', 'dead-theme-value@5']); +}); + +test('only main.tsx imports the single theme entry and only themes/index.css imports theme files', () => { + assert.deepEqual(scan('src/main.tsx', "import '@lablup/ui-common/styles/base.css';\nimport './design-system/themes/index.css';"), []); + assert.deepEqual(rules(scan('src/main.tsx', "import './design-system/themes/index.css';\nimport '@lablup/ui-common/styles/themes/orange-light.css';")), ['theme-import@2']); + assert.deepEqual(rules(scan('src/features/chat/chat.tsx', "import '../../design-system/themes/glass.css';")), ['theme-import@1']); + assert.deepEqual(rules(scan('src/features/models/models.tsx', "import '@lablup/ui-common/styles/themes/orange-dark.css';")), ['theme-import@1']); + assert.deepEqual(scan('src/design-system/themes/index.css', '@import "./contract.css";\n@import "./glass.css";'), []); + assert.deepEqual(rules(scan('src/styles.css', '@import "./design-system/themes/glass.css";')), ['theme-import@1']); + // theme.ts is the resolver module, not a theme stylesheet. + assert.deepEqual(scan('src/features/chat/chat.tsx', "import { THEME_IDS } from '../../design-system/theme';"), []); +}); + +test('every shipped id needs a theme block under themes/', () => { + const partial = { path: 'src/design-system/themes/partial.css', source: '[data-theme="mlxcel-light"] { --x: 1; }\n[data-theme="mlxcel-dark"] { --x: 1; }' }; + const violations = findThemeSelectorViolations([partial]); + assert.deepEqual(violations.map((violation) => violation.message.match(/"([a-z-]+)"/)?.[1]), ['glass-light', 'glass-dark']); + assert.ok(violations.every((violation) => violation.rule === 'missing-theme')); +}); + +test('attribute operators follow Selectors Level 4', () => { + assert.equal(attributeMatches('=', 'glass-dark', false, 'glass-dark'), true); + assert.equal(attributeMatches('=', 'Glass-Dark', true, 'glass-dark'), true); + assert.equal(attributeMatches('^=', '', false, 'glass-dark'), false); + assert.equal(attributeMatches('$=', '-dark', false, 'glass-dark'), true); + assert.equal(attributeMatches('*=', 'ss-d', false, 'glass-dark'), true); + assert.equal(attributeMatches('~=', 'glass-dark', false, 'glass-dark'), true); + assert.equal(attributeMatches('~=', 'glass dark', false, 'glass-dark'), false); + assert.equal(attributeMatches('|=', 'glass', false, 'glass-dark'), true); + assert.equal(attributeMatches('|=', 'glass-dark', false, 'glass-dark'), true); + assert.equal(attributeMatches('|=', 'gla', false, 'glass-dark'), false); +}); + +test('the gate reads its theme ids from theme.ts, not a private copy', () => { + const gate = readFileSync(new URL('./check-theme-selectors.mjs', import.meta.url), 'utf8'); + assert.match(gate, /from '\.\.\/src\/design-system\/theme\.ts'/); + assert.doesNotMatch(gate, /\['mlxcel', 'glass'\]/); +}); diff --git a/webui/src/app.tsx b/webui/src/app.tsx index 31c468cd0..70f7e24ac 100644 --- a/webui/src/app.tsx +++ b/webui/src/app.tsx @@ -2,7 +2,8 @@ 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 { applyAppearance, DEFAULT_APPEARANCE, loadAppearance, saveAppearance, type AppearancePreferences, type ContrastPreference } from './design-system/preferences'; +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, Select } from './design-system/primitives'; import { ActivityPage } from './features/activity'; import { ModelsLibrary } from './features/models/screen'; @@ -43,6 +44,9 @@ export function App(): React.JSX.Element { useEffect(() => { applyAppearance(document.documentElement, appearance); saveAppearance(appearance); + // A `system` preference follows the host scheme live; data-theme is re-resolved, never set to `system`. + if (appearance.colorScheme !== 'system') return undefined; + return onSystemColorSchemeChange((scheme) => applyAppearance(document.documentElement, appearance, scheme)); }, [appearance]); useEffect(() => { const applyVisibility = (): void => { @@ -134,7 +138,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 ( -

{t(props.appearance.locale, 'routes.settings.eyebrow')}

{t(props.appearance.locale, 'settings.title')}

{t(props.appearance.locale, 'settings.browser_only')}

set({ material: value as AppearancePreferences['material'] })} options={[{ value: 'glass', label: t(props.appearance.locale, 'settings.material.glass') }, { value: 'tinted', label: t(props.appearance.locale, 'settings.material.tinted') }, { value: 'opaque', label: t(props.appearance.locale, 'settings.material.opaque') }]} testId={testId('settings.material')} /> set({ highContrast: value as ContrastPreference })} options={[{ value: 'system', label: t(props.appearance.locale, 'settings.high_contrast.system') }, { value: 'on', label: t(props.appearance.locale, 'settings.high_contrast.on') }, { value: 'off', label: t(props.appearance.locale, 'settings.high_contrast.off') }]} testId={testId('settings.high_contrast')} /> set({ reduceMotion: checked })} testId={testId('settings.reduce_motion')} /> set({ reduceTransparency: checked })} testId={testId('settings.reduce_transparency')} />
+

{t(props.appearance.locale, 'routes.settings.eyebrow')}

{t(props.appearance.locale, 'settings.title')}

{t(props.appearance.locale, 'settings.browser_only')}

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')} />
); } diff --git a/webui/src/design-system/common-tokens.css b/webui/src/design-system/common-tokens.css index ce94a0375..c4b24b302 100644 --- a/webui/src/design-system/common-tokens.css +++ b/webui/src/design-system/common-tokens.css @@ -1,91 +1,20 @@ /* Copyright 2025-2026 Lablup Inc. Licensed under the Apache License, Version 2.0. */ -/* Product configuration of the published alpha.19 token API; also reaches body portals. */ +/* + * The theme-independent half of the published alpha.19 token API: radius, type + * scale, spacing, control heights, focus-ring geometry, motion and z-index, set + * once on :root like ui-common's base.css does, so it also reaches body + * portals. Every color, shadow and button-fill token is per theme and lives in + * themes/contract.css and the family files next to it. + */ :root { --token-borderRadius: var(--radius-sm); --token-borderRadiusLG: var(--radius-lg); --token-borderRadiusSM: var(--radius-xs); --token-borderRadiusXL: var(--radius-xl); - --token-boxShadow: var(--shadow-card); - --token-boxShadowDrawerRight: var(--shadow-card); - --token-boxShadowSecondary: var(--shadow-card); - --token-boxShadowTertiary: var(--shadow-chrome); - --token-buttonActiveTransform: none; --token-buttonBorderRadius: 999px; - --token-buttonDangerBg: #c6352b; - --token-buttonDangerBgActive: #aa2b23; - --token-buttonDangerBgHover: #aa2b23; - --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: #245bd8; - --token-buttonPrimaryBgActive: #1c4dbc; - --token-buttonPrimaryBgHover: #1c4dbc; - --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: rgba(8, 10, 14, 0.42); - --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-controlHeight: 36px; --token-controlHeightLG: 44px; --token-controlHeightSM: 32px; - --token-focusRingColor: var(--color-focus); --token-focusRingOffset: 2px; --token-focusRingStyle: solid; --token-focusRingWidth: 2px; @@ -114,9 +43,6 @@ --token-paddingXXS: var(--space-1); --token-scrollbarRadius: 999px; --token-scrollbarSize: 6px; - --token-tabActiveBg: var(--color-bg-elevated); - --token-tabFocusShadow: var(--focus-ring); - --token-tabHoverBg: var(--color-selection); --token-themeTransitionDuration: var(--motion-standard); --token-themeTransitionTiming: ease; --token-zIndexDrawer: 90; diff --git a/webui/src/design-system/components.css b/webui/src/design-system/components.css index 7dc3b14f6..e58032ec2 100644 --- a/webui/src/design-system/components.css +++ b/webui/src/design-system/components.css @@ -1,5 +1,5 @@ /* Copyright 2025-2026 Lablup Inc. Licensed under the Apache License, Version 2.0. */ -.material-glass { background: var(--material-glass-bg); border: 1px solid var(--color-separator); box-shadow: var(--shadow-chrome); backdrop-filter: blur(var(--material-glass-blur)) saturate(var(--material-glass-saturation)); -webkit-backdrop-filter: blur(var(--material-glass-blur)) saturate(var(--material-glass-saturation)); } +.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 ((backdrop-filter: blur(1px)) or (-webkit-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 { min-width: 32px; min-height: 32px; border: 1px solid var(--color-separator); color: var(--color-text); border-radius: 999px; background: var(--material-control-bg); transition: background var(--motion-fast), transform var(--motion-fast), border-color var(--motion-fast); } diff --git a/webui/src/design-system/glass-intensity.css b/webui/src/design-system/glass-intensity.css index df21efa56..fd57b8aea 100644 --- a/webui/src/design-system/glass-intensity.css +++ b/webui/src/design-system/glass-intensity.css @@ -100,3 +100,13 @@ :root[data-glass-intensity="98"] { --material-glass-alpha: 0.633; --material-glass-blur: 35.52px; --material-glass-saturation: 147.28%; } :root[data-glass-intensity="99"] { --material-glass-alpha: 0.637; --material-glass-blur: 35.76px; --material-glass-saturation: 147.64%; } :root[data-glass-intensity="100"] { --material-glass-alpha: 0.64; --material-glass-blur: 36.0px; --material-glass-saturation: 148.0%; } + +/* + * Contrast and transparency preferences outrank decorative intensity. These + * resets tie the steps above on specificity, so they must stay after them: an + * opaque material, reduced transparency, a browser without backdrop-filter or + * raised contrast leaves no blur and no saturation boost at any intensity. + */ +: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%; } } diff --git a/webui/src/design-system/preferences.test.ts b/webui/src/design-system/preferences.test.ts new file mode 100644 index 000000000..2b3cebf71 --- /dev/null +++ b/webui/src/design-system/preferences.test.ts @@ -0,0 +1,58 @@ +import { afterEach, describe, expect, it } from 'vitest'; +import { APPEARANCE_STORAGE_KEY, DEFAULT_APPEARANCE, applyAppearance, loadAppearance, saveAppearance } from './preferences'; + +afterEach(() => { + localStorage.clear(); + for (const attribute of ['data-theme', 'data-theme-family', 'data-color-scheme']) document.documentElement.removeAttribute(attribute); +}); + +describe('appearance preferences', () => { + it('default to the mlxcel family following the host scheme', () => { + expect(DEFAULT_APPEARANCE.themeFamily).toBe('mlxcel'); + expect(DEFAULT_APPEARANCE.colorScheme).toBe('system'); + expect(loadAppearance()).toEqual(DEFAULT_APPEARANCE); + }); + + it('migrate the pre-#1903 flat theme field into the color scheme', () => { + localStorage.setItem(APPEARANCE_STORAGE_KEY, JSON.stringify({ theme: 'dark', material: 'tinted', glassIntensity: 60 })); + expect(loadAppearance()).toMatchObject({ themeFamily: 'mlxcel', colorScheme: 'dark', material: 'tinted', glassIntensity: 60 }); + localStorage.setItem(APPEARANCE_STORAGE_KEY, JSON.stringify({ colorScheme: 'light', theme: 'dark' })); + expect(loadAppearance().colorScheme).toBe('light'); + localStorage.setItem(APPEARANCE_STORAGE_KEY, JSON.stringify({ theme: 'glass-dark' })); + expect(loadAppearance()).toMatchObject({ themeFamily: 'mlxcel', colorScheme: 'system' }); + }); + + it('round-trip the family and scheme and drop unknown values', () => { + saveAppearance({ ...DEFAULT_APPEARANCE, themeFamily: 'glass', colorScheme: 'dark' }); + expect(JSON.parse(localStorage.getItem(APPEARANCE_STORAGE_KEY) ?? '{}')).toMatchObject({ themeFamily: 'glass', colorScheme: 'dark' }); + expect(loadAppearance()).toMatchObject({ themeFamily: 'glass', colorScheme: 'dark' }); + localStorage.setItem(APPEARANCE_STORAGE_KEY, JSON.stringify({ themeFamily: 'orange', colorScheme: 'sepia' })); + expect(loadAppearance()).toMatchObject({ themeFamily: 'mlxcel', colorScheme: 'system' }); + }); + + it('write the applied id to data-theme and keep the raw preference apart', () => { + const root = document.documentElement; + applyAppearance(root, { ...DEFAULT_APPEARANCE, themeFamily: 'glass', colorScheme: 'system' }, 'dark'); + expect(root.dataset.theme).toBe('glass-dark'); + expect(root.dataset.themeFamily).toBe('glass'); + expect(root.dataset.colorScheme).toBe('system'); + applyAppearance(root, { ...DEFAULT_APPEARANCE, colorScheme: 'system' }, 'light'); + expect(root.dataset.theme).toBe('mlxcel-light'); + applyAppearance(root, { ...DEFAULT_APPEARANCE, colorScheme: 'light' }, 'dark'); + expect(root.dataset.theme).toBe('mlxcel-light'); + expect(root.dataset.colorScheme).toBe('light'); + }); + + it('never write a bare mode into data-theme, whatever the host reports', () => { + const root = document.documentElement; + for (const colorScheme of ['system', 'light', 'dark'] as const) { + for (const host of ['light', 'dark'] as const) { + applyAppearance(root, { ...DEFAULT_APPEARANCE, colorScheme }, host); + expect(['system', 'light', 'dark']).not.toContain(root.dataset.theme); + } + } + // jsdom has no matchMedia, which must resolve to light rather than throw. + applyAppearance(root, DEFAULT_APPEARANCE); + expect(root.dataset.theme).toBe('mlxcel-light'); + }); +}); diff --git a/webui/src/design-system/preferences.ts b/webui/src/design-system/preferences.ts index 1c9178601..58871b4dd 100644 --- a/webui/src/design-system/preferences.ts +++ b/webui/src/design-system/preferences.ts @@ -1,11 +1,23 @@ import type { Locale } from '../i18n/catalog'; +import { + DEFAULT_COLOR_SCHEME, + DEFAULT_THEME_FAMILY, + getSystemColorScheme, + isColorSchemePreference, + isThemeFamily, + resolveThemeSelection, + type ColorScheme, + type ColorSchemePreference, + type ThemeFamily, +} from './theme'; -export type ThemePreference = 'system' | 'light' | 'dark'; +export type { ColorSchemePreference, ThemeFamily } from './theme'; export type MaterialPreference = 'glass' | 'tinted' | 'opaque'; export type ContrastPreference = 'system' | 'on' | 'off'; export type AppearancePreferences = { - theme: ThemePreference; + themeFamily: ThemeFamily; + colorScheme: ColorSchemePreference; material: MaterialPreference; glassIntensity: number; reduceMotion: boolean; @@ -15,7 +27,8 @@ export type AppearancePreferences = { }; export const DEFAULT_APPEARANCE: AppearancePreferences = { - theme: 'system', + themeFamily: DEFAULT_THEME_FAMILY, + colorScheme: DEFAULT_COLOR_SCHEME, material: 'glass', glassIntensity: 35, reduceMotion: false, @@ -24,7 +37,9 @@ export const DEFAULT_APPEARANCE: AppearancePreferences = { locale: 'en', }; -const STORAGE_KEY = 'mlxcel.webui.appearance'; +// Also read by public/theme-bootstrap.js before the app mounts; keep the key and +// the family/scheme fields in step with it (theme-bootstrap.test.ts checks). +export const APPEARANCE_STORAGE_KEY = 'mlxcel.webui.appearance'; function clampIntensity(value: unknown): number { const numeric = typeof value === 'number' && Number.isFinite(value) ? value : DEFAULT_APPEARANCE.glassIntensity; @@ -35,10 +50,6 @@ function isRecord(value: unknown): value is Record { return typeof value === 'object' && value !== null && !Array.isArray(value); } -function isTheme(value: unknown): value is ThemePreference { - return value === 'system' || value === 'light' || value === 'dark'; -} - function isMaterial(value: unknown): value is MaterialPreference { return value === 'glass' || value === 'tinted' || value === 'opaque'; } @@ -54,6 +65,15 @@ function normalizeContrast(value: unknown): ContrastPreference { return DEFAULT_APPEARANCE.highContrast; } +// Stored appearance written before #1903 carried the color scheme in a flat +// `theme` field ('system' | 'light' | 'dark') and had no family. It is still +// honored when `colorScheme` is absent, so an upgrade keeps the user's choice. +function normalizeColorScheme(parsed: Record): ColorSchemePreference { + if (isColorSchemePreference(parsed.colorScheme)) return parsed.colorScheme; + if (parsed.colorScheme === undefined && isColorSchemePreference(parsed.theme)) return parsed.theme; + return DEFAULT_APPEARANCE.colorScheme; +} + function isLocale(value: unknown): value is Locale { return value === 'en' || value === 'ko'; } @@ -62,7 +82,7 @@ export function loadAppearance(): AppearancePreferences { if (typeof window === 'undefined') return DEFAULT_APPEARANCE; let raw: string | null; try { - raw = window.localStorage.getItem(STORAGE_KEY); + raw = window.localStorage.getItem(APPEARANCE_STORAGE_KEY); } catch { return DEFAULT_APPEARANCE; } @@ -71,7 +91,8 @@ export function loadAppearance(): AppearancePreferences { const parsed: unknown = JSON.parse(raw); if (!isRecord(parsed)) return DEFAULT_APPEARANCE; return { - theme: isTheme(parsed.theme) ? parsed.theme : DEFAULT_APPEARANCE.theme, + themeFamily: isThemeFamily(parsed.themeFamily) ? parsed.themeFamily : DEFAULT_APPEARANCE.themeFamily, + colorScheme: normalizeColorScheme(parsed), material: isMaterial(parsed.material) ? parsed.material : DEFAULT_APPEARANCE.material, glassIntensity: clampIntensity(parsed.glassIntensity), reduceMotion: parsed.reduceMotion === true, @@ -86,7 +107,7 @@ export function loadAppearance(): AppearancePreferences { export function saveAppearance(preferences: AppearancePreferences): void { try { - window.localStorage.setItem(STORAGE_KEY, JSON.stringify(preferences)); + window.localStorage.setItem(APPEARANCE_STORAGE_KEY, JSON.stringify(preferences)); } catch { // Browser appearance preferences remain functional in memory when storage is blocked or full. } @@ -97,8 +118,17 @@ function supportsBackdropFilter(): boolean { return CSS.supports('backdrop-filter: blur(1px)') || CSS.supports('-webkit-backdrop-filter: blur(1px)'); } -export function applyAppearance(root: HTMLElement, preferences: AppearancePreferences): void { - root.dataset.theme = preferences.theme; +/** + * Writes the appearance switches onto the document root. `data-theme` receives + * the applied `-` id, resolved against the host scheme when the + * preference is `system`; `data-color-scheme` keeps the raw preference, which is + * why no stylesheet may gate on it (scripts/check-theme-selectors.mjs). + */ +export function applyAppearance(root: HTMLElement, preferences: AppearancePreferences, systemScheme: ColorScheme = getSystemColorScheme()): void { + const theme = resolveThemeSelection(preferences.themeFamily, preferences.colorScheme, systemScheme); + root.dataset.theme = theme.id; + root.dataset.themeFamily = theme.family; + root.dataset.colorScheme = theme.preference; root.dataset.material = preferences.reduceTransparency ? 'opaque' : preferences.material; root.dataset.glassIntensity = String(clampIntensity(preferences.glassIntensity)); root.dataset.reduceMotion = String(preferences.reduceMotion); diff --git a/webui/src/design-system/theme-bootstrap.test.ts b/webui/src/design-system/theme-bootstrap.test.ts new file mode 100644 index 000000000..ea62241cc --- /dev/null +++ b/webui/src/design-system/theme-bootstrap.test.ts @@ -0,0 +1,113 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import indexHtml from '../../index.html?raw'; +import bootstrapSource from '../../public/theme-bootstrap.js?raw'; +import { APPEARANCE_STORAGE_KEY, applyAppearance, loadAppearance } from './preferences'; + +const THEME_ATTRIBUTES = ['data-theme', 'data-theme-family', 'data-color-scheme'] as const; + +type HostScheme = 'light' | 'dark' | 'missing' | 'throws'; + +function clearThemeAttributes(): void { + for (const attribute of THEME_ATTRIBUTES) document.documentElement.removeAttribute(attribute); +} + +function readThemeAttributes(): Record { + return Object.fromEntries(THEME_ATTRIBUTES.map((attribute) => [attribute, document.documentElement.getAttribute(attribute)])); +} + +function setHostScheme(host: HostScheme): void { + if (host === 'missing') vi.stubGlobal('matchMedia', undefined); + else if (host === 'throws') vi.stubGlobal('matchMedia', () => { throw new Error('blocked'); }); + else vi.stubGlobal('matchMedia', () => ({ matches: host === 'dark', addEventListener: () => undefined, removeEventListener: () => undefined })); +} + +function runBootstrap(): Record { + clearThemeAttributes(); + new Function(bootstrapSource)(); + return readThemeAttributes(); +} + +function runApp(): Record { + clearThemeAttributes(); + applyAppearance(document.documentElement, loadAppearance()); + return readThemeAttributes(); +} + +const STORED: Array<[string, string | null]> = [ + ['nothing stored', null], + ['corrupt JSON', '{'], + ['an array', '[]'], + ['an empty object', '{}'], + ['legacy flat theme: dark', JSON.stringify({ theme: 'dark', material: 'glass' })], + ['legacy flat theme: light', JSON.stringify({ theme: 'light' })], + ['legacy flat theme: system', JSON.stringify({ theme: 'system' })], + ['glass, dark', JSON.stringify({ themeFamily: 'glass', colorScheme: 'dark' })], + ['glass, system', JSON.stringify({ themeFamily: 'glass', colorScheme: 'system' })], + ['glass family only', JSON.stringify({ themeFamily: 'glass' })], + ['mlxcel, light', JSON.stringify({ themeFamily: 'mlxcel', colorScheme: 'light' })], + ['colorScheme wins over the legacy field', JSON.stringify({ colorScheme: 'light', theme: 'dark' })], + ['an invalid colorScheme does not fall back to the legacy field', JSON.stringify({ colorScheme: 'sepia', theme: 'dark' })], + ['unknown family and scheme', JSON.stringify({ themeFamily: 'orange', colorScheme: 'glass-dark' })], + ['a full theme id in the legacy field', JSON.stringify({ theme: 'glass-dark' })], +]; + +beforeEach(() => { + localStorage.clear(); +}); + +afterEach(() => { + vi.restoreAllMocks(); + vi.unstubAllGlobals(); + localStorage.clear(); + clearThemeAttributes(); +}); + +describe('pre-mount theme bootstrap (public/theme-bootstrap.js)', () => { + for (const host of ['light', 'dark', 'missing', 'throws'] as const) { + it.each(STORED)(`matches applyAppearance for %s under a ${host} host`, (_label, stored) => { + if (stored !== null) localStorage.setItem(APPEARANCE_STORAGE_KEY, stored); + setHostScheme(host); + const early = runBootstrap(); + expect(early['data-theme']).toMatch(/^(mlxcel|glass)-(light|dark)$/); + expect(early).toEqual(runApp()); + }); + } + + it('keeps the defaults when storage access throws', () => { + setHostScheme('dark'); + vi.spyOn(Storage.prototype, 'getItem').mockImplementation(() => { throw new DOMException('blocked', 'SecurityError'); }); + const early = runBootstrap(); + expect(early).toEqual({ 'data-theme': 'mlxcel-dark', 'data-theme-family': 'mlxcel', 'data-color-scheme': 'system' }); + expect(early).toEqual(runApp()); + }); + + it('never writes system, light or dark alone into data-theme', () => { + for (const theme of ['system', 'light', 'dark']) { + localStorage.setItem(APPEARANCE_STORAGE_KEY, JSON.stringify({ theme })); + setHostScheme('light'); + expect(runBootstrap()['data-theme']).toMatch(/^mlxcel-(light|dark)$/); + } + }); +}); + +describe('index.html', () => { + const head = indexHtml.slice(0, indexHtml.indexOf('')); + + it('loads the bootstrap as a classic, render-blocking script in ', () => { + const tag = head.match(/]*\bsrc="\.\/theme-bootstrap\.js"[^>]*><\/script>/); + expect(tag).not.toBeNull(); + expect(tag?.[0]).not.toMatch(/\b(type="module"|async|defer)\b/); + }); + + it('carries no inline script, which the served CSP (script-src self) would block', () => { + for (const match of indexHtml.matchAll(/]*)>([\s\S]*?)<\/script>/g)) { + expect(match[1]).toMatch(/\bsrc="/); + expect(match[2].trim()).toBe(''); + } + }); + + it('runs the bootstrap before the app module', () => { + expect(indexHtml.indexOf('./theme-bootstrap.js')).toBeGreaterThan(-1); + expect(indexHtml.indexOf('./theme-bootstrap.js')).toBeLessThan(indexHtml.indexOf('type="module"')); + }); +}); diff --git a/webui/src/design-system/theme-stylesheets.test.ts b/webui/src/design-system/theme-stylesheets.test.ts new file mode 100644 index 000000000..df84f837c --- /dev/null +++ b/webui/src/design-system/theme-stylesheets.test.ts @@ -0,0 +1,156 @@ +import { readdirSync, readFileSync } from 'node:fs'; +import { dirname, join } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { describe, expect, it } from 'vitest'; +import mainSource from '../main.tsx?raw'; +import { THEME_IDS } from './theme'; + +// Stylesheets are read from disk: Vitest blanks CSS modules, `?raw` included, +// so an imported stylesheet would be an empty string and every check below +// would pass without looking. +// Paths are joined by hand: Vite rewrites `new URL(literal, import.meta.url)` into a served asset URL. +const srcRoot = join(dirname(fileURLToPath(import.meta.url)), '..'); +const read = (path: string): string => readFileSync(join(srcRoot, path), 'utf8'); +const uiCommonBase = read('../node_modules/@lablup/ui-common/dist/styles/base.css'); +const commonTokens = read('design-system/common-tokens.css'); +const glassIntensity = read('design-system/glass-intensity.css'); +const themeEntry = read('design-system/themes/index.css'); +const tokens = read('design-system/tokens.css'); +// Every product stylesheet, theme files included, keyed by path relative to src/. +const productCss: Record = Object.fromEntries( + readdirSync(srcRoot, { recursive: true, encoding: 'utf8' }) + .filter((path) => path.endsWith('.css')) + .map((path) => [path.split('\\').join('/'), read(path)]), +); +const themeCss = Object.fromEntries(Object.entries(productCss).filter(([path]) => path.startsWith('design-system/themes/'))); + +type Rule = { selectors: string[]; body: string }; + +function stripComments(css: string): string { + return css.replace(/\/\*[\s\S]*?\*\//g, ''); +} + +/** Top-level style rules only; at-rule blocks (@media, @supports, @import) are skipped. */ +function topLevelRules(css: string): Rule[] { + const source = stripComments(css); + const rules: Rule[] = []; + let index = 0; + while (index < source.length) { + const open = source.indexOf('{', index); + const semicolon = source.indexOf(';', index); + if (open === -1) break; + if (semicolon !== -1 && semicolon < open && source.slice(index, semicolon).trim().startsWith('@')) { + index = semicolon + 1; + continue; + } + const prelude = source.slice(index, open).trim(); + let depth = 1; + let cursor = open + 1; + while (cursor < source.length && depth > 0) { + if (source[cursor] === '{') depth += 1; + else if (source[cursor] === '}') depth -= 1; + cursor += 1; + } + if (!prelude.startsWith('@')) rules.push({ selectors: prelude.split(',').map((selector) => selector.trim()), body: source.slice(open + 1, cursor - 1) }); + index = cursor; + } + return rules; +} + +function declaredProperties(body: string): Set { + return new Set(Array.from(body.matchAll(/(--[A-Za-z0-9-]+)\s*:/g), (match) => match[1])); +} + +function referencedProperties(body: string): Set { + return new Set(Array.from(body.matchAll(/var\(\s*(--[A-Za-z0-9-]+)/g), (match) => match[1])); +} + +function rootDeclarations(css: string): Set { + const declared = new Set(); + for (const rule of topLevelRules(css)) if (rule.selectors.includes(':root')) for (const name of declaredProperties(rule.body)) declared.add(name); + return declared; +} + +/** Custom properties a theme id declares across every theme file, through exact-id selectors. */ +function themeDeclarations(id: string): { declared: Set; referenced: Set } { + const declared = new Set(); + const referenced = new Set(); + for (const css of Object.values(themeCss)) { + for (const rule of topLevelRules(css)) { + if (!rule.selectors.includes(`[data-theme="${id}"]`)) continue; + for (const name of declaredProperties(rule.body)) declared.add(name); + for (const name of referencedProperties(rule.body)) referenced.add(name); + } + } + return { declared, referenced }; +} + +const baseContract = new Set(Array.from(uiCommonBase.matchAll(/(--token-[A-Za-z0-9]+)\s*:/g), (match) => match[1])); +const structural = rootDeclarations(commonTokens); +const rootLevel = new Set([...rootDeclarations(tokens), ...structural]); +const intensityInputs = new Set(Array.from(glassIntensity.matchAll(/(--material-glass-[a-z]+)\s*:/g), (match) => match[1])); + +describe('theme stylesheets', () => { + it('reads real stylesheets', () => { + expect(baseContract.size).toBeGreaterThanOrEqual(119); + expect(Object.keys(themeCss).sort()).toEqual(['design-system/themes/contract.css', 'design-system/themes/glass.css', 'design-system/themes/index.css', 'design-system/themes/mlxcel.css']); + expect(Object.keys(productCss)).toContain('design-system/components.css'); + }); + + it('split the ui-common token contract between :root structure and per-theme values without overlap', () => { + for (const id of THEME_IDS) { + const themed = new Set([...themeDeclarations(id).declared].filter((name) => name.startsWith('--token-'))); + expect([...themed].filter((name) => structural.has(name)), `${id} re-declares structural tokens`).toEqual([]); + const covered = new Set([...structural, ...themed]); + expect([...baseContract].filter((name) => !covered.has(name)), `${id} leaves contract tokens at ui-common defaults`).toEqual([]); + expect([...themed].filter((name) => !baseContract.has(name)), `${id} sets names outside the contract`).toEqual([]); + } + }); + + it('keep no color, shadow or button-fill token on :root, where it would outlive a theme switch', () => { + expect([...structural].filter((name) => /color|shadow|button(?!BorderRadius)|focusRingColor|tab(Active|Hover|Focus)/i.test(name))).toEqual([]); + }); + + it('define every custom property a theme block reads, for every shipped id', () => { + for (const id of THEME_IDS) { + const { declared, referenced } = themeDeclarations(id); + const missing = [...referenced].filter((name) => !declared.has(name) && !rootLevel.has(name) && !intensityInputs.has(name)); + expect(missing, id).toEqual([]); + } + }); + + it('define every semantic token the product stylesheets read, for every shipped id', () => { + const locallyDeclared = new Set(); + const referenced = new Set(); + for (const [path, css] of Object.entries(productCss)) { + if (path.startsWith('design-system/themes/')) continue; + for (const name of declaredProperties(stripComments(css))) locallyDeclared.add(name); + for (const name of referencedProperties(stripComments(css))) referenced.add(name); + } + for (const id of THEME_IDS) { + const { declared } = themeDeclarations(id); + const missing = [...referenced].filter((name) => !declared.has(name) && !locallyDeclared.has(name) && !name.startsWith('--token-')); + expect(missing, id).toEqual([]); + } + }); + + it('import one theme entry directly after ui-common base.css, and no ui-common theme file', () => { + const imports = Array.from(mainSource.matchAll(/^import\s+'([^']+\.css)';/gm), (match) => match[1]); + expect(imports.slice(0, 2)).toEqual(['@lablup/ui-common/styles/base.css', './design-system/themes/index.css']); + expect(imports.filter((path) => path.includes('/themes/'))).toEqual(['./design-system/themes/index.css']); + expect(Array.from(themeEntry.matchAll(/@import\s+"([^"]+)"/g), (match) => match[1])).toEqual(['./contract.css', './mlxcel.css', './glass.css']); + }); + + it('write -webkit-backdrop-filter before backdrop-filter, or the minifier drops the standard property', () => { + // Lightning CSS treats a prefixed declaration that follows the standard one + // as the winner and emits only the prefixed form, which Chromium and + // Firefox ignore. That silently disabled the glass blur in shipped builds. + for (const [path, css] of Object.entries(productCss)) { + for (const rule of topLevelRules(css)) { + const standard = rule.body.search(/(^|[;\s])backdrop-filter\s*:/); + const prefixed = rule.body.search(/-webkit-backdrop-filter\s*:/); + if (standard !== -1 && prefixed !== -1) expect(prefixed, `${path} ${rule.selectors.join(', ')}`).toBeLessThan(standard); + } + } + }); +}); diff --git a/webui/src/design-system/theme.test.ts b/webui/src/design-system/theme.test.ts new file mode 100644 index 000000000..b44d2423a --- /dev/null +++ b/webui/src/design-system/theme.test.ts @@ -0,0 +1,92 @@ +import { afterEach, describe, expect, it, vi } from 'vitest'; +import { + COLOR_SCHEME_PREFERENCES, + THEME_FAMILIES, + SYSTEM_DARK_QUERY, + THEME_IDS, + getSystemColorScheme, + isColorSchemePreference, + isThemeFamily, + isThemeId, + onSystemColorSchemeChange, + resolveThemeSelection, +} from './theme'; + +type Listener = (event: MediaQueryListEvent) => void; + +function installMatchMedia(dark: boolean): { flip: (next: boolean) => void; listeners: Set } { + const listeners = new Set(); + const query = { + matches: dark, + media: SYSTEM_DARK_QUERY, + addEventListener: (_type: string, listener: Listener) => listeners.add(listener), + removeEventListener: (_type: string, listener: Listener) => listeners.delete(listener), + }; + vi.stubGlobal('matchMedia', vi.fn(() => query)); + return { + listeners, + flip: (next: boolean) => { + query.matches = next; + for (const listener of listeners) listener({ matches: next } as MediaQueryListEvent); + }, + }; +} + +afterEach(() => { + vi.unstubAllGlobals(); +}); + +describe('theme ids', () => { + it('are always - and never a bare mode', () => { + expect(THEME_IDS).toEqual(['mlxcel-light', 'mlxcel-dark', 'glass-light', 'glass-dark']); + for (const id of ['light', 'dark', 'system', '', 'orange-light', 'glass']) expect(isThemeId(id)).toBe(false); + for (const id of THEME_IDS) expect(isThemeId(id)).toBe(true); + }); + + it('validates the stored preference separately from the applied id', () => { + expect(THEME_FAMILIES).toEqual(['mlxcel', 'glass']); + expect(COLOR_SCHEME_PREFERENCES).toEqual(['system', 'light', 'dark']); + expect(isThemeFamily('glass')).toBe(true); + expect(isThemeFamily('glass-dark')).toBe(false); + expect(isThemeFamily(undefined)).toBe(false); + expect(isColorSchemePreference('system')).toBe(true); + expect(isColorSchemePreference('mlxcel-dark')).toBe(false); + }); + + it('resolves a system preference against the host scheme and keeps the raw preference', () => { + expect(resolveThemeSelection('glass', 'system', 'dark')).toEqual({ id: 'glass-dark', family: 'glass', scheme: 'dark', preference: 'system' }); + expect(resolveThemeSelection('mlxcel', 'system', 'light')).toEqual({ id: 'mlxcel-light', family: 'mlxcel', scheme: 'light', preference: 'system' }); + expect(resolveThemeSelection('mlxcel', 'dark', 'light').id).toBe('mlxcel-dark'); + expect(resolveThemeSelection('glass', 'light', 'dark').id).toBe('glass-light'); + }); +}); + +describe('host color scheme', () => { + it('reads matchMedia and treats a missing or throwing implementation as light', () => { + installMatchMedia(true); + expect(getSystemColorScheme()).toBe('dark'); + vi.unstubAllGlobals(); + vi.stubGlobal('matchMedia', undefined); + expect(getSystemColorScheme()).toBe('light'); + vi.stubGlobal('matchMedia', () => { throw new Error('blocked'); }); + expect(getSystemColorScheme()).toBe('light'); + }); + + it('reports host scheme flips until unsubscribed', () => { + const media = installMatchMedia(false); + const seen: string[] = []; + const unsubscribe = onSystemColorSchemeChange((scheme) => seen.push(scheme)); + media.flip(true); + media.flip(false); + unsubscribe(); + media.flip(true); + expect(seen).toEqual(['dark', 'light']); + expect(media.listeners.size).toBe(0); + }); + + it('is a no-op without matchMedia', () => { + vi.stubGlobal('matchMedia', undefined); + const unsubscribe = onSystemColorSchemeChange(() => undefined); + expect(() => unsubscribe()).not.toThrow(); + }); +}); diff --git a/webui/src/design-system/theme.ts b/webui/src/design-system/theme.ts new file mode 100644 index 000000000..899bdd5fe --- /dev/null +++ b/webui/src/design-system/theme.ts @@ -0,0 +1,100 @@ +// Copyright 2025-2026 Lablup Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Theme identity for the WebUI, in the `@lablup/ui-common` convention: a theme +// is a block of `--token-*` values keyed on one `data-theme` value, and that +// value is always `-`. The stored preference (a family plus a +// color scheme that may be `system`) is kept apart from the applied id, so +// `data-theme` never holds `system`, `light` or `dark` on its own. +// +// This module is dependency-free on purpose: `scripts/check-theme-selectors.mjs` +// imports it directly under Node to learn which ids exist, and +// `public/theme-bootstrap.js` mirrors `resolveThemeSelection` before the app +// mounts (a parity test keeps the two in step). + +export const THEME_FAMILIES = ['mlxcel', 'glass'] as const; +export type ThemeFamily = (typeof THEME_FAMILIES)[number]; + +export const COLOR_SCHEMES = ['light', 'dark'] as const; +export type ColorScheme = (typeof COLOR_SCHEMES)[number]; + +export const COLOR_SCHEME_PREFERENCES = ['system', 'light', 'dark'] as const; +export type ColorSchemePreference = (typeof COLOR_SCHEME_PREFERENCES)[number]; + +export type ThemeId = `${ThemeFamily}-${ColorScheme}`; + +export const DEFAULT_THEME_FAMILY: ThemeFamily = 'mlxcel'; +export const DEFAULT_COLOR_SCHEME: ColorSchemePreference = 'system'; + +/** Every value `data-theme` can hold. */ +export const THEME_IDS: readonly ThemeId[] = THEME_FAMILIES.flatMap((family) => COLOR_SCHEMES.map((scheme): ThemeId => `${family}-${scheme}`)); + +/** The one media query the app consults for the host scheme; nothing else may gate on it. */ +export const SYSTEM_DARK_QUERY = '(prefers-color-scheme: dark)'; + +export function isThemeFamily(value: unknown): value is ThemeFamily { + return typeof value === 'string' && (THEME_FAMILIES as readonly string[]).includes(value); +} + +export function isColorSchemePreference(value: unknown): value is ColorSchemePreference { + return typeof value === 'string' && (COLOR_SCHEME_PREFERENCES as readonly string[]).includes(value); +} + +export function isThemeId(value: unknown): value is ThemeId { + return typeof value === 'string' && (THEME_IDS as readonly string[]).includes(value); +} + +export function themeIdFor(family: ThemeFamily, scheme: ColorScheme): ThemeId { + return `${family}-${scheme}`; +} + +/** Reads the host scheme; a browser without `matchMedia` (or one that throws) counts as light. */ +export function getSystemColorScheme(): ColorScheme { + try { + if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return 'light'; + return window.matchMedia(SYSTEM_DARK_QUERY).matches ? 'dark' : 'light'; + } catch { + return 'light'; + } +} + +export function resolveColorScheme(preference: ColorSchemePreference, system: ColorScheme = getSystemColorScheme()): ColorScheme { + return preference === 'system' ? system : preference; +} + +export type ThemeSelection = { + id: ThemeId; + family: ThemeFamily; + scheme: ColorScheme; + preference: ColorSchemePreference; +}; + +export function resolveThemeSelection(family: ThemeFamily, preference: ColorSchemePreference, system: ColorScheme = getSystemColorScheme()): ThemeSelection { + const scheme = resolveColorScheme(preference, system); + return { id: themeIdFor(family, scheme), family, scheme, preference }; +} + +/** Calls back when the host scheme flips; returns the unsubscribe function. */ +export function onSystemColorSchemeChange(callback: (scheme: ColorScheme) => void): () => void { + if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return () => undefined; + let query: MediaQueryList; + try { + query = window.matchMedia(SYSTEM_DARK_QUERY); + } catch { + return () => undefined; + } + const handler = (event: MediaQueryListEvent): void => callback(event.matches ? 'dark' : 'light'); + query.addEventListener('change', handler); + return () => query.removeEventListener('change', handler); +} diff --git a/webui/src/design-system/themes/contract.css b/webui/src/design-system/themes/contract.css new file mode 100644 index 000000000..14e97cf73 --- /dev/null +++ b/webui/src/design-system/themes/contract.css @@ -0,0 +1,101 @@ +/* Copyright 2025-2026 Lablup Inc. Licensed under the Apache License, Version 2.0. */ +/* + * Binds the scheme-dependent half of the @lablup/ui-common token contract + * (colors, shadows, button fills, focus color, tab surfaces) to the product's + * semantic tokens (--color-*, --material-*, --shadow-*), for every theme this + * product ships. The family files after it (mlxcel.css, glass.css) set those + * semantic tokens per theme id and override a contract token only where the + * family genuinely differs. The theme-independent half of the contract (radius, + * type scale, spacing, control heights, motion, z-index) stays on :root in + * ../common-tokens.css, the way ui-common's own base.css keeps it. + * + * The selector lists every shipped id explicitly, never a bare [data-theme], + * so a future ui-common theme (orange-light, say) is not silently rebound to + * mlxcel's palette. scripts/check-theme-selectors.mjs fails when a shipped id + * is missing from a theme stylesheet or a listed id matches nothing. + */ +[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: rgba(8, 10, 14, 0.42); + --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); +} diff --git a/webui/src/design-system/themes/glass.css b/webui/src/design-system/themes/glass.css new file mode 100644 index 000000000..262183485 --- /dev/null +++ b/webui/src/design-system/themes/glass.css @@ -0,0 +1,154 @@ +/* Copyright 2025-2026 Lablup Inc. Licensed under the Apache License, Version 2.0. */ +/* Portions of this file are derived from backend.ai-go + * (https://github.com/lablup/backend.ai-go), Copyright 2025-2026 Lablup Inc., + * licensed under the Apache License, Version 2.0. See the top-level NOTICE + * file for the attribution. */ +/* + * glass family (glass-light, glass-dark): a frosted-glass look in the macOS 27 + * design language epic #1834 set. Translucent chrome with a top light + * reflection, soft translucent borders, tinted glass controls and gradient + * highlights on filled buttons, while transcript, table and form surfaces stay + * near-opaque so they remain readable. The system-color palette and the + * highlight and fill values follow backend.ai-go's glass theme + * (src/themes/tokens/glass-light.css and glass-dark.css there), with the text, + * accent and status colors darkened or lightened where needed to clear WCAG 2.2 + * AA against this product's surfaces. + * + * It reads the appearance switches the product already has and adds none: + * - glass intensity: --material-glass-alpha, --material-glass-blur and + * --material-glass-saturation from ../glass-intensity.css + * (data-glass-intensity 0..100), which size the chrome and control glass; + * - data-material, data-reduce-transparency, data-backdrop-filter and + * data-high-contrast, plus prefers-reduced-transparency and + * prefers-contrast: any of them turns every translucent glass surface in + * this file opaque (../tokens.css does the same for the chrome material), + * so contrast settings always outrank decorative intensity; + * - data-reduce-motion and prefers-reduced-motion: drop the press transform. + */ +[data-theme="glass-light"] { + --color-bg: #e6ebf3; + --color-bg-elevated: #fbfbfd; + --color-bg-neutral: #f1f2f6; + --color-text: #1d1d1f; + --color-muted: #545458; + --color-separator: rgba(60, 60, 67, 0.14); + --color-focus: #0058b9; + --color-selection: rgba(0, 88, 185, 0.10); + --color-warning: #8a4f00; + --color-warning-bg: rgba(255, 149, 0, 0.12); + --color-error: #b3261e; + --color-error-bg: rgba(255, 59, 48, 0.10); + --color-success: #1b6f3c; + --color-success-bg: rgba(52, 199, 89, 0.12); + --material-glass-bg: linear-gradient(180deg, rgba(255, 255, 255, 0.36), rgba(255, 255, 255, 0) 64px), rgba(248, 249, 252, var(--material-glass-alpha)); + --material-content-bg: rgba(255, 255, 255, 0.94); + --material-control-bg: linear-gradient(180deg, rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0) 60%), rgba(120, 120, 128, 0.12); + --shadow-chrome: inset 0 1px 0 rgba(255, 255, 255, 0.72); + --shadow-card: 0 1px 2px rgba(15, 23, 42, 0.04), 0 10px 30px rgba(15, 23, 42, 0.07); + --shadow-popover: 0 12px 40px rgba(0, 0, 0, 0.12), 0 4px 12px rgba(0, 0, 0, 0.06); + --glass-edge: rgba(255, 255, 255, 0.15); + --glass-highlight: linear-gradient(180deg, rgba(255, 255, 255, 0.18) 0%, rgba(255, 255, 255, 0.05) 40%, transparent 100%); + --glass-button-shadow: 0 1px 3px rgba(0, 88, 185, 0.2); + --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: rgba(255, 255, 255, 0.12); + --color-focus: #6cb2ff; + --color-selection: rgba(64, 156, 255, 0.18); + --color-warning: #ffb340; + --color-warning-bg: rgba(255, 159, 10, 0.14); + --color-error: #ff7b72; + --color-error-bg: rgba(255, 69, 58, 0.16); + --color-success: #4cd964; + --color-success-bg: rgba(50, 215, 75, 0.14); + --material-glass-bg: linear-gradient(180deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0) 64px), rgba(30, 30, 34, var(--material-glass-alpha)); + --material-content-bg: rgba(36, 36, 40, 0.94); + --material-control-bg: linear-gradient(180deg, rgba(255, 255, 255, 0.10), rgba(255, 255, 255, 0) 60%), rgba(255, 255, 255, 0.10); + --shadow-chrome: inset 0 1px 0 rgba(255, 255, 255, 0.14); + --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.3), 0 12px 32px rgba(0, 0, 0, 0.28); + --shadow-popover: 0 12px 40px rgba(0, 0, 0, 0.45), 0 4px 12px rgba(0, 0, 0, 0.3); + --glass-edge: rgba(255, 255, 255, 0.1); + --glass-highlight: linear-gradient(180deg, rgba(255, 255, 255, 0.15) 0%, rgba(255, 255, 255, 0.04) 40%, transparent 100%); + --glass-button-shadow: 0 1px 3px rgba(0, 0, 0, 0.35); + --button-primary-solid: #0a5bc0; + --button-primary-fill-active: #0a4ea6; + --button-danger-solid: #b3261e; + --button-danger-fill-active: #99201a; +} + +/* Family-wide glass bindings over contract.css. */ +[data-theme="glass-light"], +[data-theme="glass-dark"] { + --material-control-backdrop: blur(calc(var(--material-glass-blur) / 2)) saturate(var(--material-glass-saturation)); + --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(0.985); + --token-buttonDangerBorder: 1px solid var(--glass-edge); + --token-buttonDangerShadow: var(--glass-button-shadow); + --token-buttonDangerShadowHover: var(--glass-button-shadow); + --token-buttonPrimaryBorder: 1px solid var(--glass-edge); + --token-buttonPrimaryShadow: var(--glass-button-shadow); + --token-buttonPrimaryShadowHover: var(--glass-button-shadow); + --token-buttonSecondaryBackdrop: var(--material-control-backdrop); + --token-buttonSecondaryShadow: var(--shadow-chrome); + --token-buttonSecondaryShadowHover: var(--shadow-chrome); + --token-colorBgMask: rgba(8, 10, 14, 0.32); +} + +/* + * Opaque glass. Transparency is dropped whenever the user asked for an opaque + * material or less transparency, the browser cannot blur, or contrast is + * raised, whatever the decorative intensity says. Every rule below is keyed + * on :root plus an attribute, so it outranks the single-attribute palettes + * above regardless of order. + */ +: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); + --material-control-backdrop: none; + --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); + --material-control-backdrop: none; + --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); + --material-control-backdrop: none; + --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; + } +} diff --git a/webui/src/design-system/themes/index.css b/webui/src/design-system/themes/index.css new file mode 100644 index 000000000..90d8836ed --- /dev/null +++ b/webui/src/design-system/themes/index.css @@ -0,0 +1,26 @@ +/* Copyright 2025-2026 Lablup Inc. Licensed under the Apache License, Version 2.0. */ +/* + * The WebUI's one theme stylesheet. src/main.tsx imports it directly after + * @lablup/ui-common/styles/base.css, following the package rule that an app + * imports at most one theme file alongside base.css and that components never + * import a theme file themselves. No ui-common theme file (orange-light, + * orange-dark) is loaded; this product ships its own [data-theme] blocks over + * the same --token-* contract, as base.css describes. + * + * Every block is keyed on the applied theme id, `-`, which + * src/design-system/theme.ts resolves and public/theme-bootstrap.js writes onto + * before the first paint: + * + * mlxcel-light, mlxcel-dark the approved baseline and the default family + * glass-light, glass-dark the glass family + * + * The blocks are single-attribute selectors that rely on following base.css, + * exactly like ui-common's own theme files. Accessibility overrides elsewhere + * (tokens.css, glass-intensity.css and the tail of glass.css) are written with + * higher specificity so they win whatever the import order. + * scripts/check-theme-selectors.mjs is the CI gate that keeps every + * data-theme selector matching a shipped id. + */ +@import "./contract.css"; +@import "./mlxcel.css"; +@import "./glass.css"; diff --git a/webui/src/design-system/themes/mlxcel.css b/webui/src/design-system/themes/mlxcel.css new file mode 100644 index 000000000..e65c8de56 --- /dev/null +++ b/webui/src/design-system/themes/mlxcel.css @@ -0,0 +1,60 @@ +/* Copyright 2025-2026 Lablup Inc. Licensed under the Apache License, Version 2.0. */ +/* + * mlxcel family (mlxcel-light, mlxcel-dark): the approved 4185 baseline and the + * default family. Neutral content surfaces with glass reserved for the sidebar, + * the toolbar and transient overlays. These values are the ones tokens.css and + * common-tokens.css carried on :root before #1903, moved here unchanged so the + * default appearance does not move. + */ +[data-theme="mlxcel-light"] { + --color-bg: #f3f4f6; + --color-bg-elevated: #ffffff; + --color-bg-neutral: #f8f8fa; + --color-text: #151a24; + --color-muted: #59647a; + --color-separator: rgba(33, 42, 61, 0.12); + --color-focus: #245bd8; + --color-selection: rgba(36, 42, 55, 0.08); + --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: rgba(255, 255, 255, 0.82); + --material-control-bg: rgba(255, 255, 255, 0.58); + --shadow-chrome: 0 1px 0 rgba(255, 255, 255, 0.62) inset; + --shadow-card: 0 12px 36px rgba(31, 37, 52, 0.07); +} + +[data-theme="mlxcel-dark"] { + --color-bg: #0e1117; + --color-bg-elevated: #181d27; + --color-bg-neutral: #111722; + --color-text: #f5f7fb; + --color-muted: #aeb8c9; + --color-separator: rgba(255, 255, 255, 0.12); + --color-focus: #9dbdff; + --color-selection: rgba(255, 255, 255, 0.10); + --color-warning: #ffd28a; + --color-warning-bg: rgba(139, 92, 0, 0.22); + --color-error: #ffb4a8; + --color-error-bg: rgba(152, 43, 28, 0.24); + --color-success: #9be6b0; + --color-success-bg: rgba(25, 108, 55, 0.22); + --material-glass-bg: rgba(24, 28, 36, var(--material-glass-alpha)); + --material-content-bg: rgba(25, 29, 38, 0.84); + --material-control-bg: rgba(255, 255, 255, 0.08); + --shadow-chrome: 0 1px 0 rgba(255, 255, 255, 0.08) inset; + --shadow-card: 0 14px 40px rgba(0, 0, 0, 0.22); +} + +/* Both schemes keep the same solid button fills, as before. */ +[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; +} diff --git a/webui/src/design-system/tokens.css b/webui/src/design-system/tokens.css index bcfc1f9e9..29fa309db 100644 --- a/webui/src/design-system/tokens.css +++ b/webui/src/design-system/tokens.css @@ -1,4 +1,9 @@ /* Copyright 2025-2026 Lablup Inc. Licensed under the Apache License, Version 2.0. */ +/* + * Theme-independent product tokens and the accessibility overrides every theme + * obeys. Color, material and shadow values are per theme and live in + * themes/*.css, keyed on the applied `-` id. + */ :root { color-scheme: light dark; font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", system-ui, sans-serif; @@ -19,88 +24,27 @@ --motion-standard: 160ms; --motion-slow: 180ms; --focus-ring: 0 0 0 3px color-mix(in srgb, var(--color-focus) 42%, transparent); - --color-bg: #f3f4f6; - --color-bg-elevated: #ffffff; - --color-bg-neutral: #f8f8fa; - --color-text: #151a24; - --color-muted: #59647a; - --color-separator: rgba(33, 42, 61, 0.12); - --color-focus: #245bd8; - --color-selection: rgba(36, 42, 55, 0.08); - --color-warning: #8a5200; - --color-warning-bg: #fff4d8; - --color-error: #b42318; - --color-error-bg: #fff0ed; - --color-success: #137333; - --color-success-bg: #eaf7ee; - --material-tint: rgba(76, 93, 135, 0.06); --material-glass-alpha: 0.72; --material-glass-blur: 18px; --material-glass-saturation: 118%; - --material-glass-bg: rgba(248, 249, 251, var(--material-glass-alpha)); - --material-content-bg: rgba(255, 255, 255, 0.82); - --material-control-bg: rgba(255, 255, 255, 0.58); - --shadow-chrome: 0 1px 0 rgba(255, 255, 255, 0.62) inset; - --shadow-card: 0 12px 36px rgba(31, 37, 52, 0.07); } -:root[data-theme="dark"] { color-scheme: dark; } -:root[data-theme="light"] { color-scheme: light; } - -@media (prefers-color-scheme: dark) { - :root:not([data-theme="light"]) { - --color-bg: #0e1117; - --color-bg-elevated: #181d27; - --color-bg-neutral: #111722; - --color-text: #f5f7fb; - --color-muted: #aeb8c9; - --color-separator: rgba(255, 255, 255, 0.12); - --color-focus: #9dbdff; - --color-selection: rgba(255, 255, 255, 0.10); - --color-warning: #ffd28a; - --color-warning-bg: rgba(139, 92, 0, 0.22); - --color-error: #ffb4a8; - --color-error-bg: rgba(152, 43, 28, 0.24); - --color-success: #9be6b0; - --color-success-bg: rgba(25, 108, 55, 0.22); - --material-tint: rgba(107, 137, 210, 0.10); - --material-glass-bg: rgba(24, 28, 36, var(--material-glass-alpha)); - --material-content-bg: rgba(25, 29, 38, 0.84); - --material-control-bg: rgba(255, 255, 255, 0.08); - --shadow-chrome: 0 1px 0 rgba(255, 255, 255, 0.08) inset; - --shadow-card: 0 14px 40px rgba(0, 0, 0, 0.22); - } -} - -:root[data-theme="dark"] { - --color-bg: #0e1117; - --color-bg-elevated: #181d27; - --color-bg-neutral: #111722; - --color-text: #f5f7fb; - --color-muted: #aeb8c9; - --color-separator: rgba(255, 255, 255, 0.12); - --color-focus: #9dbdff; - --color-selection: rgba(255, 255, 255, 0.10); - --color-warning: #ffd28a; - --color-warning-bg: rgba(139, 92, 0, 0.22); - --color-error: #ffb4a8; - --color-error-bg: rgba(152, 43, 28, 0.24); - --color-success: #9be6b0; - --color-success-bg: rgba(25, 108, 55, 0.22); - --material-tint: rgba(107, 137, 210, 0.10); - --material-glass-bg: rgba(24, 28, 36, var(--material-glass-alpha)); - --material-content-bg: rgba(25, 29, 38, 0.84); - --material-control-bg: rgba(255, 255, 255, 0.08); - --shadow-chrome: 0 1px 0 rgba(255, 255, 255, 0.08) inset; - --shadow-card: 0 14px 40px rgba(0, 0, 0, 0.22); -} +/* The applied theme, never the host OS, decides the UA color scheme. */ +:root[data-theme$="-light"] { color-scheme: light; } +:root[data-theme$="-dark"] { color-scheme: dark; } +/* + * Accessibility overrides. Each is keyed on :root plus an attribute, which + * outranks the single-attribute theme palettes whatever the import order. The + * matching blur and saturation resets sit at the end of glass-intensity.css so + * they also win the tie with the intensity steps. + */ :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); --material-glass-blur: 0px; --material-glass-saturation: 100%; } +: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 { --material-glass-bg: var(--color-bg-elevated); --material-glass-blur: 0px; } } +@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%; } diff --git a/webui/src/features/chat/style.test.ts b/webui/src/features/chat/style.test.ts index 9760af9e5..cdd713ab7 100644 --- a/webui/src/features/chat/style.test.ts +++ b/webui/src/features/chat/style.test.ts @@ -1,9 +1,24 @@ -import tokens from '../../design-system/tokens.css?raw'; -import css from './chat.css?raw'; +import { readFileSync } from 'node:fs'; +import { dirname, join } from 'node:path'; +import { fileURLToPath } from 'node:url'; import { describe, expect, it } from 'vitest'; + +// Read from disk: Vitest blanks CSS modules, `?raw` included, so an imported +// stylesheet is an empty string and a check over it passes without looking. +const here = dirname(fileURLToPath(import.meta.url)); +const read = (path: string): string => readFileSync(join(here, path), 'utf8'); +const tokens = read('../../design-system/tokens.css'); +const css = read('./chat.css'); + describe('chat shared theme authority', () => { - it('only references defined shared semantic tokens', () => { - const declared = new Set(Array.from(tokens.matchAll(/(--[a-z0-9-]+):/g), (match) => match[1])); + it('reads real stylesheets', () => { + expect(tokens).toContain('--space-1'); + expect(css).toMatch(/var\(--/); + }); + + it.each(['mlxcel', 'glass'])('only references shared semantic tokens the %s theme defines', (family) => { + const theme = read(`../../design-system/themes/${family}.css`); + const declared = new Set(Array.from(`${tokens}\n${theme}`.matchAll(/(--[a-z0-9-]+):/g), (match) => match[1])); for (const match of css.matchAll(/var\((--[a-z0-9-]+)/g)) expect(declared.has(match[1]), match[1]).toBe(true); }); }); diff --git a/webui/src/features/models/models.css b/webui/src/features/models/models.css index 27bef59c0..cc605282f 100644 --- a/webui/src/features/models/models.css +++ b/webui/src/features/models/models.css @@ -35,11 +35,11 @@ margin: 4px 0 16px; } .models-library .ds-inspector dt { - color: var(--text-secondary); + color: var(--color-muted); font-size: 0.85rem; } .models-library .models-selected { - background: var(--surface-selected, var(--surface-hover)); + background: var(--color-selection); } .models-library .data-table__cell { vertical-align: top; diff --git a/webui/src/i18n/catalog.ts b/webui/src/i18n/catalog.ts index d42d214ae..b689e54a4 100644 --- a/webui/src/i18n/catalog.ts +++ b/webui/src/i18n/catalog.ts @@ -49,6 +49,7 @@ export type StringKey = typeof modelStrings[number]['key'] | 'settings.title' | 'settings.appearance' | 'settings.theme' + | 'settings.color_scheme' | 'settings.material' | 'settings.glass_intensity' | 'settings.reduce_motion' @@ -114,9 +115,11 @@ export type StringKey = typeof modelStrings[number]['key'] | 'gallery.sample.reasoning_body' | 'gallery.sample.tool_preview' | 'common.close' - | 'settings.theme.system' - | 'settings.theme.light' - | 'settings.theme.dark' + | 'settings.theme.mlxcel' + | 'settings.theme.glass' + | 'settings.color_scheme.system' + | 'settings.color_scheme.light' + | 'settings.color_scheme.dark' | 'settings.material.glass' | 'settings.material.tinted' | 'settings.material.opaque' @@ -255,6 +258,7 @@ export const entries: Entry[] = [ { 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' }, @@ -328,9 +332,11 @@ export const entries: Entry[] = [ { 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.system', en: 'System', ko: '시스템', test_id: 'settings-theme-system' }, - { key: 'settings.theme.light', en: 'Light', ko: '라이트', test_id: 'settings-theme-light' }, - { key: 'settings.theme.dark', en: 'Dark', ko: '다크', test_id: 'settings-theme-dark' }, + { 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' }, diff --git a/webui/src/main.tsx b/webui/src/main.tsx index 55b8b49b3..efb26e239 100644 --- a/webui/src/main.tsx +++ b/webui/src/main.tsx @@ -15,6 +15,9 @@ import React from 'react'; import { createRoot } from 'react-dom/client'; import '@lablup/ui-common/styles/base.css'; +// The one theme stylesheet, directly after base.css (ui-common: at most one theme +// file alongside base.css, never imported by a component). See themes/index.css. +import './design-system/themes/index.css'; import { App } from './app'; import { WebUiProvider } from './state'; import './styles.css'; diff --git a/webui/tests/browser-fixtures.ts b/webui/tests/browser-fixtures.ts index 27e4660eb..49fab26cd 100644 --- a/webui/tests/browser-fixtures.ts +++ b/webui/tests/browser-fixtures.ts @@ -32,6 +32,13 @@ export const variants: Variant[] = [ { name: '390-opaque-gallery-controls-drawer-cjk', width: 390, height: 844, tab: 'controls', openDrawer: true, appearance: { theme: 'light', material: 'opaque', locale: 'ko', glassIntensity: 0, highContrast: 'system' } }, { name: '1440-highcontrast-gallery-states', width: 1440, height: 900, tab: 'states', appearance: { theme: 'light', material: 'opaque', highContrast: 'on', locale: 'en', glassIntensity: 0 } }, { name: '390-dark-opaque-textscale200-gallery-controls', width: 390, height: 844, tab: 'controls', appearance: { theme: 'dark', material: 'opaque', reduceTransparency: true, reduceMotion: true, locale: 'ko', glassIntensity: 100, highContrast: 'off' }, textScale: '200' }, + // Glass family (#1903): every shipped theme id runs the same axe, layout and reflow checks. + { name: '1440-glass-light-gallery-controls', width: 1440, height: 900, tab: 'controls', appearance: { themeFamily: 'glass', colorScheme: 'light', material: 'glass', locale: 'en', glassIntensity: 35, highContrast: 'system' } }, + { name: '1440-glass-dark-gallery-states', width: 1440, height: 900, tab: 'states', appearance: { themeFamily: 'glass', colorScheme: 'dark', material: 'glass', locale: 'en', glassIntensity: 60, highContrast: 'system' } }, + { name: '1024-glass-light-gallery-data-tinted', width: 1024, height: 768, tab: 'data', appearance: { themeFamily: 'glass', colorScheme: 'light', material: 'tinted', locale: 'ko', glassIntensity: 45, highContrast: 'system' } }, + { name: '1024-glass-dark-gallery-data', width: 1024, height: 768, tab: 'data', appearance: { themeFamily: 'glass', colorScheme: 'dark', material: 'glass', locale: 'en', glassIntensity: 100, highContrast: 'system' } }, + { name: '1440-glass-light-highcontrast-gallery-states', width: 1440, height: 900, tab: 'states', appearance: { themeFamily: 'glass', colorScheme: 'light', material: 'glass', highContrast: 'on', locale: 'en', glassIntensity: 100 } }, + { name: '390-glass-dark-textscale200-gallery-controls-drawer', width: 390, height: 844, tab: 'controls', openDrawer: true, appearance: { themeFamily: 'glass', colorScheme: 'dark', material: 'glass', reduceMotion: true, locale: 'ko', glassIntensity: 100, highContrast: 'system' }, textScale: '200' }, ]; export const productVariants: ProductVariant[] = [ @@ -39,8 +46,23 @@ export const productVariants: ProductVariant[] = [ { name: '1440-light-product-signed-in', width: 1440, height: 900, signedIn: true, appearance: { theme: 'light', material: 'glass', locale: 'en', glassIntensity: 35, highContrast: 'system' } }, { name: '390-dark-product-login', width: 390, height: 844, signedIn: false, appearance: { theme: 'dark', material: 'glass', reduceTransparency: false, reduceMotion: true, locale: 'ko', glassIntensity: 45, highContrast: 'system' } }, { name: '390-dark-product-signed-in', width: 390, height: 844, signedIn: true, appearance: { theme: 'dark', material: 'glass', reduceTransparency: false, reduceMotion: true, locale: 'ko', glassIntensity: 45, highContrast: 'system' } }, + { name: '1440-glass-light-product-signed-in', width: 1440, height: 900, signedIn: true, appearance: { themeFamily: 'glass', colorScheme: 'light', material: 'glass', locale: 'en', glassIntensity: 35, highContrast: 'system' } }, + { name: '390-glass-dark-product-login', width: 390, height: 844, signedIn: false, appearance: { themeFamily: 'glass', colorScheme: 'dark', material: 'glass', reduceMotion: true, locale: 'ko', glassIntensity: 45, highContrast: 'system' } }, + { name: '390-glass-dark-product-signed-in', width: 390, height: 844, signedIn: true, appearance: { themeFamily: 'glass', colorScheme: 'dark', material: 'glass', reduceMotion: true, locale: 'ko', glassIntensity: 45, highContrast: 'system' } }, ]; +/** + * The data-theme id a stored appearance should produce once a scheme is pinned, + * or null for `system` (which depends on the emulated host). Appearance written + * before #1903 carried the scheme in a flat `theme` field; fixtures that still + * use it exercise that migration. + */ +export function expectedThemeId(appearance: Record): string | null { + const family = appearance.themeFamily === 'glass' ? 'glass' : 'mlxcel'; + const scheme = appearance.colorScheme ?? appearance.theme; + return scheme === 'light' || scheme === 'dark' ? `${family}-${scheme}` : null; +} + function withoutSchemaName(value: T): T { const copy = structuredClone(value); if (typeof copy === 'object' && copy !== null && '$schemaName' in copy) delete (copy as Record).$schemaName; @@ -151,7 +173,8 @@ export async function bootGallery(page: Page, variant: Variant): Promise { await page.addInitScript((appearance) => localStorage.setItem('mlxcel.webui.appearance', JSON.stringify(appearance)), variant.appearance); await page.goto('/#gallery'); await expect(page.getByTestId('app-title')).toBeVisible(); - if (typeof variant.appearance.theme === 'string') await expect(page.locator('html')).toHaveAttribute('data-theme', variant.appearance.theme); + const themeId = expectedThemeId(variant.appearance); + if (themeId) await expect(page.locator('html')).toHaveAttribute('data-theme', themeId); if (variant.textScale) await page.evaluate((scale) => { document.documentElement.dataset.testTextScale = scale; }, variant.textScale); await selectGalleryTab(page, variant.tab); if (variant.openDrawer) await page.getByRole('button', { name: /navigation|내비게이션/i }).click(); @@ -162,7 +185,8 @@ export async function bootProduct(page: Page, variant: ProductVariant): Promise< await page.addInitScript((appearance) => localStorage.setItem('mlxcel.webui.appearance', JSON.stringify(appearance)), variant.appearance); await page.goto('/#models'); await expect(page.getByTestId('app-title')).toBeVisible(); - if (typeof variant.appearance.theme === 'string') await expect(page.locator('html')).toHaveAttribute('data-theme', variant.appearance.theme); + const themeId = expectedThemeId(variant.appearance); + if (themeId) await expect(page.locator('html')).toHaveAttribute('data-theme', themeId); } export async function submitSessionKey(page: Page, token: string): Promise { diff --git a/webui/tests/theme.spec.ts b/webui/tests/theme.spec.ts new file mode 100644 index 000000000..5e963f27a --- /dev/null +++ b/webui/tests/theme.spec.ts @@ -0,0 +1,212 @@ +// Copyright 2025-2026 Lablup Inc. Licensed under the Apache License, Version 2.0. +import { expect, test, type Page } from '@playwright/test'; +import { expectAxeClean, expectSafeLayout } from './browser-assertions'; +import { bootGallery, installMockApi } from './browser-fixtures'; + +const STORAGE_KEY = 'mlxcel.webui.appearance'; + +// The color each theme paints on before anything mounts (--color-bg). +const CANVAS: Record = { + 'mlxcel-light': 'rgb(243, 244, 246)', + 'mlxcel-dark': 'rgb(14, 17, 23)', + 'glass-light': 'rgb(230, 235, 243)', + 'glass-dark': 'rgb(11, 13, 18)', +}; + +/** Seeds the stored appearance once per tab, so a later reload reads what the app saved instead. */ +async function storeAppearance(page: Page, appearance: Record): Promise { + await page.addInitScript(([key, value]) => { + if (sessionStorage.getItem('theme-spec-seeded') === '1') return; + sessionStorage.setItem('theme-spec-seeded', '1'); + localStorage.setItem(key, value); + }, [STORAGE_KEY, JSON.stringify(appearance)] as const); +} + +/** Holds the app entry module so the page can be inspected in its pre-mount state. */ +async function holdAppModule(page: Page): Promise<() => void> { + let release = (): void => undefined; + const released = new Promise((resolve) => { release = resolve; }); + await page.route(/\/assets\/index-[^/]+\.js$/, async (route) => { + await released; + await route.continue(); + }); + return release; +} + +async function preMountState(page: Page): Promise<{ theme: string | null; family: string | null; preference: string | null; canvas: string; colorScheme: string; mounted: number }> { + // Wait for the stylesheet (a theme-independent :root token), not for a theme to apply. + await page.waitForFunction(() => getComputedStyle(document.documentElement).getPropertyValue('--space-1').trim() !== ''); + return page.evaluate(() => ({ + theme: document.documentElement.getAttribute('data-theme'), + family: document.documentElement.getAttribute('data-theme-family'), + preference: document.documentElement.getAttribute('data-color-scheme'), + canvas: getComputedStyle(document.documentElement).backgroundColor, + colorScheme: getComputedStyle(document.documentElement).colorScheme, + mounted: document.getElementById('root')?.childElementCount ?? -1, + })); +} + +async function emulate(page: Page, features: { name: string; value: string }[]): Promise { + const client = await page.context().newCDPSession(page); + await client.send('Emulation.setEmulatedMedia', { features }); +} + +/** Boots the gallery from a blank page, so the stored appearance is re-read by a real load. */ +async function bootFresh(page: Page, name: string, appearance: Record): Promise { + await page.goto('about:blank'); + await bootGallery(page, { name, width: 1440, height: 900, tab: 'controls', appearance }); +} + +/** Resolves color tokens through a probe element, so minified spellings (#fff, #rrggbbaa) compare equal. */ +async function resolvedColors(page: Page, names: string[]): Promise> { + return page.evaluate((keys) => { + const probe = document.createElement('div'); + document.body.append(probe); + const result = Object.fromEntries(keys.map((key) => { + probe.style.backgroundColor = `var(${key})`; + return [key, getComputedStyle(probe).backgroundColor]; + })); + probe.remove(); + return result; + }, names); +} + +function milliseconds(value: string): number { + return value.endsWith('ms') ? Number.parseFloat(value) : Number.parseFloat(value) * 1000; +} + +async function rootValues(page: Page, names: string[]): Promise> { + return page.evaluate((keys) => Object.fromEntries(keys.map((key) => [key, getComputedStyle(document.documentElement).getPropertyValue(key).trim()])), names); +} + +test.describe('theme system', () => { + const cases: { stored: Record; host: 'light' | 'dark'; id: string; preference: string }[] = [ + { stored: { themeFamily: 'mlxcel', colorScheme: 'dark' }, host: 'light', id: 'mlxcel-dark', preference: 'dark' }, + { stored: { themeFamily: 'glass', colorScheme: 'light' }, host: 'dark', id: 'glass-light', preference: 'light' }, + { stored: { themeFamily: 'glass', colorScheme: 'system' }, host: 'dark', id: 'glass-dark', preference: 'system' }, + { stored: { theme: 'dark' }, host: 'light', id: 'mlxcel-dark', preference: 'dark' }, + { stored: {}, host: 'light', id: 'mlxcel-light', preference: 'system' }, + ]; + for (const { stored, host, id, preference } of cases) { + test(`applies ${id} before the app mounts (stored ${JSON.stringify(stored)}, ${host} host)`, async ({ page }) => { + await page.emulateMedia({ colorScheme: host }); + await storeAppearance(page, stored); + const release = await holdAppModule(page); + await page.goto('/#models', { waitUntil: 'commit' }); + const early = await preMountState(page); + expect(early).toEqual({ theme: id, family: id.split('-')[0], preference, canvas: CANVAS[id], colorScheme: id.endsWith('-dark') ? 'dark' : 'light', mounted: 0 }); + release(); + await expect(page.getByTestId('app-title')).toBeVisible(); + await expect(page.locator('html')).toHaveAttribute('data-theme', id); + expect(await page.evaluate(() => getComputedStyle(document.documentElement).backgroundColor)).toBe(CANVAS[id]); + }); + } + + test('follows a system preference live and leaves a pinned scheme alone', async ({ page }) => { + await page.emulateMedia({ colorScheme: 'light' }); + await storeAppearance(page, { themeFamily: 'glass', colorScheme: 'system' }); + await page.goto('/#gallery'); + await expect(page.getByTestId('gallery-title')).toBeVisible(); + await expect(page.locator('html')).toHaveAttribute('data-theme', 'glass-light'); + await page.emulateMedia({ colorScheme: 'dark' }); + await expect(page.locator('html')).toHaveAttribute('data-theme', 'glass-dark'); + await expect(page.locator('html')).toHaveAttribute('data-color-scheme', 'system'); + await page.evaluate((key) => localStorage.setItem(key, JSON.stringify({ themeFamily: 'glass', colorScheme: 'light' })), STORAGE_KEY); + await page.reload(); + await expect(page.getByTestId('gallery-title')).toBeVisible(); + await expect(page.locator('html')).toHaveAttribute('data-theme', 'glass-light'); + await page.emulateMedia({ colorScheme: 'light' }); + await page.emulateMedia({ colorScheme: 'dark' }); + await expect(page.locator('html')).toHaveAttribute('data-theme', 'glass-light'); + }); + + test('switches family and scheme from Settings, persists them, and restores them before mount', async ({ page }) => { + await installMockApi(page, 'happy'); + await page.emulateMedia({ colorScheme: 'light' }); + await page.setViewportSize({ width: 1440, height: 900 }); + await page.goto('/#settings'); + await expect(page.getByTestId('settings-title')).toBeVisible(); + await expect(page.locator('html')).toHaveAttribute('data-theme', 'mlxcel-light'); + await page.getByRole('combobox', { name: 'Theme' }).click(); + await page.getByRole('option', { name: 'Glass' }).click(); + await expect(page.locator('html')).toHaveAttribute('data-theme', 'glass-light'); + await page.getByRole('combobox', { name: 'Color scheme' }).click(); + await page.getByRole('option', { name: 'Dark' }).click(); + await expect(page.locator('html')).toHaveAttribute('data-theme', 'glass-dark'); + await expect(page.locator('html')).toHaveAttribute('data-color-scheme', 'dark'); + const stored = await page.evaluate((key) => JSON.parse(localStorage.getItem(key) ?? '{}') as Record, STORAGE_KEY); + expect(stored).toMatchObject({ themeFamily: 'glass', colorScheme: 'dark' }); + expect(stored).not.toHaveProperty('theme'); + await expectAxeClean(page); + await expectSafeLayout(page); + const release = await holdAppModule(page); + await page.reload({ waitUntil: 'commit' }); + expect((await preMountState(page)).theme).toBe('glass-dark'); + release(); + await expect(page.getByTestId('settings-title')).toBeVisible(); + }); + + test('keeps the mlxcel baseline values unchanged', async ({ page }) => { + for (const [scheme, expected] of [ + // Pre-#1903 values from tokens.css and common-tokens.css on :root. + ['light', { '--color-bg': 'rgb(243, 244, 246)', '--color-text': 'rgb(21, 26, 36)', '--color-focus': 'rgb(36, 91, 216)', '--token-colorPrimary': 'rgb(36, 91, 216)', '--token-buttonPrimaryBg': 'rgb(36, 91, 216)', '--token-buttonDangerBg': 'rgb(198, 53, 43)', '--token-colorBgContainer': 'rgb(255, 255, 255)', '--token-colorBorder': 'rgba(33, 42, 61, 0.12)', '--material-content-bg': 'rgba(255, 255, 255, 0.82)' }], + ['dark', { '--color-bg': 'rgb(14, 17, 23)', '--color-text': 'rgb(245, 247, 251)', '--color-focus': 'rgb(157, 189, 255)', '--token-colorPrimary': 'rgb(157, 189, 255)', '--token-buttonPrimaryBg': 'rgb(36, 91, 216)', '--token-buttonDangerBg': 'rgb(198, 53, 43)', '--token-colorBgContainer': 'rgb(24, 29, 39)', '--token-colorBorder': 'rgba(255, 255, 255, 0.12)', '--material-content-bg': 'rgba(25, 29, 38, 0.84)' }], + ] as const) { + await bootFresh(page, `baseline-${scheme}`, { colorScheme: scheme, material: 'glass', locale: 'en', glassIntensity: 35, highContrast: 'off' }); + expect(await resolvedColors(page, Object.keys(expected))).toEqual(expected); + } + }); + + test('glass chrome follows the intensity scale in Chromium', async ({ page }) => { + const blurAt = async (glassIntensity: number): Promise<{ filter: string; image: string }> => { + await bootFresh(page, `glass-${glassIntensity}`, { themeFamily: 'glass', colorScheme: 'light', material: 'glass', locale: 'en', glassIntensity, highContrast: 'off' }); + return page.locator('.material-glass').first().evaluate((element) => ({ filter: getComputedStyle(element).backdropFilter, image: getComputedStyle(element).backgroundImage })); + }; + const low = await blurAt(0); + const high = await blurAt(100); + // A standard backdrop-filter must survive minification (the prefixed form alone is ignored here). + expect(low.filter).toBe('blur(12px) saturate(1.12)'); + expect(high.filter).toBe('blur(36px) saturate(1.48)'); + expect(low.image).toContain('linear-gradient'); + }); + + const opaqueCases: { label: string; appearance: Record; media: { name: string; value: string }[] }[] = [ + { label: 'reduce transparency setting', appearance: { reduceTransparency: true }, media: [] }, + { label: 'opaque material', appearance: { material: 'opaque' }, media: [] }, + { label: 'high contrast setting', appearance: { highContrast: 'on' }, media: [] }, + { label: 'prefers-contrast: more', appearance: {}, media: [{ name: 'prefers-contrast', value: 'more' }] }, + { label: 'prefers-reduced-transparency: reduce', appearance: {}, media: [{ name: 'prefers-reduced-transparency', value: 'reduce' }] }, + { label: 'both OS preferences at full intensity', appearance: {}, media: [{ name: 'prefers-contrast', value: 'more' }, { name: 'prefers-reduced-transparency', value: 'reduce' }] }, + ]; + for (const { label, appearance, media } of opaqueCases) { + for (const colorScheme of ['light', 'dark'] as const) { + test(`glass-${colorScheme} turns opaque under ${label}, whatever the intensity`, async ({ page }) => { + if (media.length) await emulate(page, media); + await bootFresh(page, label, { themeFamily: 'glass', colorScheme, material: 'glass', locale: 'en', glassIntensity: 100, highContrast: 'system', ...appearance }); + const chrome = await page.locator('.material-glass').first().evaluate((element) => ({ filter: getComputedStyle(element).backdropFilter, image: getComputedStyle(element).backgroundImage, color: getComputedStyle(element).backgroundColor })); + expect(chrome.filter).toMatch(/^(none|blur\(0px\)( saturate\(1\))?)$/); + expect(chrome.image).toBe('none'); + expect(chrome.color).not.toMatch(/rgba\(.*, 0\.\d+\)$/); + const values = await rootValues(page, ['--material-control-backdrop', '--token-buttonPrimaryBg', '--material-content-bg', '--color-bg-elevated']); + expect(values['--material-control-backdrop']).toBe('none'); + expect(values['--token-buttonPrimaryBg']).not.toContain('gradient'); + expect(values['--material-content-bg']).toBe(values['--color-bg-elevated']); + await expectAxeClean(page); + }); + } + } + + test('glass drops the press transform under reduced motion', async ({ page }) => { + const transform = async (reduceMotion: boolean): Promise<{ press: string; fast: number }> => { + await bootFresh(page, 'glass-motion', { themeFamily: 'glass', colorScheme: 'light', material: 'glass', locale: 'en', glassIntensity: 35, reduceMotion }); + const values = await rootValues(page, ['--token-buttonActiveTransform', '--motion-fast']); + return { press: values['--token-buttonActiveTransform'], fast: milliseconds(values['--motion-fast']) }; + }; + const moving = await transform(false); + expect(moving.press).toMatch(/^scale\(0?\.985\)$/); + expect(moving.fast).toBe(120); + expect(await transform(true)).toEqual({ press: 'none', fast: 1 }); + await page.emulateMedia({ reducedMotion: 'reduce' }); + expect(await transform(false)).toEqual({ press: 'none', fast: 1 }); + }); +}); From 393a08d202362ebff4a3b716593b5e57f5915b31 Mon Sep 17 00:00:00 2001 From: Jeongkyu Shin Date: Sat, 19 Sep 2026 14:05:55 +0900 Subject: [PATCH 2/6] fix(webui): paint the glass button fills on rendered buttons The glass theme binds a highlighted gradient fill to --token-buttonPrimaryBg and --token-buttonDangerBg, but the rendered primary and danger buttons never showed it. components.css hard-coded #245bd8 and #c6352b on .ds-button-primary and .ds-button-danger with the same specificity as ui-common's .button--primary and later in the bundle, so both glass schemes painted the mlxcel fill at rest and switched to the glass hue only on hover. The two rules now read the theme tokens. The mlxcel tokens resolve to the same two colors, so the baseline does not move. theme.spec.ts now checks the computed fill of the rendered buttons rather than only the tokens: the mlxcel baseline stays flat, both glass schemes paint the gradient over their own solid, and every opaque case paints no gradient. Put the two hex values back and the new glass case fails, because it receives background-image none. Typecheck, lint, the theme-selector gate, unit (32 node:test, 401 Vitest), the Chromium suite (60) and build_bundle.py --verify pass. The committed bundle is regenerated. Refs #1903 --- docs/webui/design-system.md | 2 +- ...B7JRfpaI.js => code-highlight-CLL7D9Tw.js} | 2 +- ...istory-DIlBLmUk.js => history-U2uX7mu1.js} | 2 +- .../{index-C5rxJd1U.js => index-C7P01FJ4.js} | 4 +- ...{index-jceAf1an.css => index-tKjNOHbY.css} | 2 +- src/webui/assets/index.html | 4 +- src/webui/assets/mlxcel-webui-manifest.json | 38 +++++++++---------- webui/src/design-system/components.css | 4 +- webui/tests/theme.spec.ts | 20 ++++++++++ 9 files changed, 49 insertions(+), 29 deletions(-) rename src/webui/assets/assets/{code-highlight-B7JRfpaI.js => code-highlight-CLL7D9Tw.js} (93%) rename src/webui/assets/assets/{history-DIlBLmUk.js => history-U2uX7mu1.js} (94%) rename src/webui/assets/assets/{index-C5rxJd1U.js => index-C7P01FJ4.js} (99%) rename src/webui/assets/assets/{index-jceAf1an.css => index-tKjNOHbY.css} (73%) diff --git a/docs/webui/design-system.md b/docs/webui/design-system.md index e3d4b4235..d2e251f02 100644 --- a/docs/webui/design-system.md +++ b/docs/webui/design-system.md @@ -57,7 +57,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 (32 tests) and 401 Vitest tests across 40 files, covering the shared client/provider, shell and theme behavior. `pnpm --dir webui run browser` executes 59 Playwright tests, 60 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, and 22 `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 (32 tests) and 401 Vitest tests across 40 files, covering the shared client/provider, shell and theme behavior. `pnpm --dir webui run browser` executes 60 Playwright tests, 61 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, 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/src/webui/assets/assets/code-highlight-B7JRfpaI.js b/src/webui/assets/assets/code-highlight-CLL7D9Tw.js similarity index 93% rename from src/webui/assets/assets/code-highlight-B7JRfpaI.js rename to src/webui/assets/assets/code-highlight-CLL7D9Tw.js index 7341f7da1..1925dc1f2 100644 --- a/src/webui/assets/assets/code-highlight-B7JRfpaI.js +++ b/src/webui/assets/assets/code-highlight-CLL7D9Tw.js @@ -1 +1 @@ -import{i as e,n as t,r as n}from"./index-C5rxJd1U.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-C7P01FJ4.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-DIlBLmUk.js b/src/webui/assets/assets/history-U2uX7mu1.js similarity index 94% rename from src/webui/assets/assets/history-DIlBLmUk.js rename to src/webui/assets/assets/history-U2uX7mu1.js index 2a7ba12f3..c53ef18fb 100644 --- a/src/webui/assets/assets/history-DIlBLmUk.js +++ b/src/webui/assets/assets/history-U2uX7mu1.js @@ -1 +1 @@ -import{n as e,r as t,t as n}from"./index-C5rxJd1U.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-C7P01FJ4.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-C5rxJd1U.js b/src/webui/assets/assets/index-C7P01FJ4.js similarity index 99% rename from src/webui/assets/assets/index-C5rxJd1U.js rename to src/webui/assets/assets/index-C7P01FJ4.js index 212ea9cc5..05e2c2a30 100644 --- a/src/webui/assets/assets/index-C5rxJd1U.js +++ b/src/webui/assets/assets/index-C7P01FJ4.js @@ -3733,8 +3733,8 @@ Error generating stack: `+e.message+` } } } -`,$e=class extends Error{path;constructor(e,t){super(`${e}: ${t}`),this.path=e,this.name=`ValidationError`}},et=rt(Qe);function tt(e,t,n=`$`){let r=ht(et,[`components`,`schemas`],`#/components/schemas`)[e];if(r===void 0)throw new $e(n,`unknown schema ${e}`);it(r,t,n)}function nt(e){return JSON.parse(e)}function rt(e){return mt(nt(e),`$contract`)}function it(e,t,n){let r=mt(e,`${n}#schema`);if(typeof r.$ref==`string`){it(ft(r.$ref),t,n);return}if(r.anyOf!==void 0){if(!Array.isArray(r.anyOf)||!r.anyOf.some(e=>pt(e,t,n)))throw new $e(n,`did not match any allowed schema`);return}if(r.oneOf!==void 0){if(!Array.isArray(r.oneOf))throw new $e(n,`schema oneOf must be an array`);let e=r.oneOf.filter(e=>pt(e,t,n)).length;if(e!==1)throw new $e(n,`matched ${e} oneOf schemas`);return}if(r.const!==void 0&&t!==r.const)throw new $e(n,`expected constant ${String(r.const)}`);if(Array.isArray(r.enum)&&!r.enum.some(e=>e===t))throw new $e(n,`unexpected enum value ${String(t)}`);let i=r.type;if(Array.isArray(i)){if(!i.some(e=>dt(e,t)))throw new $e(n,`expected one of ${i.join(`, `)}`)}else if(typeof i==`string`&&!dt(i,t))throw new $e(n,`expected ${i}`);typeof t==`string`&&ct(r,t,n),typeof t==`number`&&ut(r,t,n),Array.isArray(t)&&ot(r,t,n),gt(t)&&at(r,t,n)}function at(e,t,n){let r=_t(e.required,`${n}#schema.required`,!1),i=e.properties===void 0?{}:mt(e.properties,`${n}#schema.properties`);for(let e of r)if(!(e in t))throw new $e(`${n}.${e}`,`missing required property`);if(e.maxProperties!==void 0&&Object.keys(t).length>vt(e.maxProperties,`${n}#schema.maxProperties`))throw new $e(n,`too many object properties`);for(let[r,a]of Object.entries(t)){let t=i[r];if(t!==void 0)it(t,a,`${n}.${r}`);else if(e.additionalProperties===!1)throw new $e(`${n}.${r}`,`unexpected property`);else gt(e.additionalProperties)&&it(e.additionalProperties,a,`${n}.${r}`)}}function ot(e,t,n){if(e.minItems!==void 0&&t.lengthvt(e.maxItems,`${n}#schema.maxItems`))throw new $e(n,`array longer than maximum`);e.items!==void 0&&t.forEach((t,r)=>it(e.items,t,`${n}[${r}]`))}function st(e){let t=0;for(let n=0;n65535?2:1;return t}function ct(e,t,n){let r=st(t);if(e.minLength!==void 0&&rvt(e.maxLength,`${n}#schema.maxLength`))throw new $e(n,`string longer than maximum`);if(typeof e.pattern==`string`&&!new RegExp(e.pattern,`u`).test(t))throw new $e(n,`string does not match pattern`);if(e.format===`date-time`&&!lt(t))throw new $e(n,`invalid RFC3339 date-time`)}function lt(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 ut(e,t,n){if(!Number.isFinite(t))throw new $e(n,`expected finite number`);if(e.type===`integer`&&!Number.isInteger(t))throw new $e(n,`expected integer`);if(e.minimum!==void 0&&tvt(e.maximum,`${n}#schema.maximum`))throw new $e(n,`number above maximum`)}function dt(e,t){return e===`null`?t===null:e===`array`?Array.isArray(t):e===`object`?gt(t):e===`integer`?typeof t==`number`&&Number.isInteger(t):e===`number`?typeof t==`number`&&Number.isFinite(t):typeof t===e}function ft(e){if(!e.startsWith(`#/`))throw new $e(`$ref`,`unsupported external ref ${e}`);return e.slice(2).split(`/`).map(e=>e.replace(/~1/g,`/`).replace(/~0/g,`~`)).reduce((t,n)=>mt(t,e)[n],et)}function pt(e,t,n){try{return it(e,t,n),!0}catch(e){if(e instanceof $e)return!1;throw e}}function mt(e,t){if(!gt(e))throw new $e(t,`expected object`);return e}function ht(e,t,n){return t.reduce((e,t)=>mt(e,n)[t],e)}function gt(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function _t(e,t,n){if(e===void 0&&!n)return[];if(!Array.isArray(e)||!e.every(e=>typeof e==`string`))throw new $e(t,`expected string array`);return e}function vt(e,t){if(typeof e!=`number`||!Number.isFinite(e))throw new $e(t,`expected numeric schema bound`);return e}function yt(e,t,n){return tt(e,t,n),t}function bt(e,t=`$`){return yt(`ErrorEnvelope`,e,t)}function xt(e,t=`$`){return yt(`BootstrapResponse`,e,t)}function St(e,t=`$`){return yt(`CatalogEntry`,e,t)}function Ct(e,t=`$`){return yt(`CatalogListResponse`,e,t)}function wt(e,t=`$`){return yt(`OperationsListResponse`,e,t)}function Tt(e,t=`$`){return yt(`Operation`,e,t)}function Et(e,t=`$`){return yt(`OperationAccepted`,e,t)}function Dt(e,t=`$`){return yt(`RuntimeSnapshot`,e,t)}function Ot(e,t=`$`){return yt(`UiEvent`,e,t)}var kt=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`}},At=2097152,jt=class{apiBase;fetchImpl;bearerToken=null;onUnauthorized;controllers=new Set;constructor(e={}){this.apiBase=qe(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`,xt,{method:`GET`,signal:e})}async catalog(e={},t){return this.request(`/ui-api/v1/catalog`,Ct,{method:`GET`,query:{...e},signal:t})}async catalogEntry(e,t){return this.request(`/ui-api/v1/catalog/${Ze(e)}`,St,{method:`GET`,signal:t})}async refreshCatalog(e,t){return this.request(`/ui-api/v1/catalog/refresh`,Et,{method:`POST`,body:{idempotency_key:e},signal:t})}async modelAction(e,t){return this.request(`/ui-api/v1/model-actions`,Et,{method:`POST`,body:e,signal:t})}async download(e,t){return this.request(`/ui-api/v1/downloads`,Et,{method:`POST`,body:e,signal:t})}async removeModel(e,t){return this.request(`/ui-api/v1/model-removals`,Et,{method:`POST`,body:e,signal:t})}async operationsPage(e={},t){return this.request(`/ui-api/v1/operations`,wt,{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/${Ze(e)}`,Tt,{method:`GET`,signal:t})}async cancelOperation(e,t){return this.request(`/ui-api/v1/operations/${Ze(e)}/cancel`,Et,{method:`POST`,body:{},signal:t})}async runtime(e,t){let n=await this.request(`/ui-api/v1/runtime`,Dt,{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`,He,{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`,Le,{method:`GET`,query:{model:e,autoload:!1},signal:t})}async patchSettings(e,t,n){return this.request(`/settings`,Re,{method:`PATCH`,query:{model:e,autoload:!1},body:{op:`merge`,values:t},signal:n})}async modelProps(e,t){return this.request(`/props`,ze,{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(Xe(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(Ot(nt(t.data)))}})}async chatCompletions(e,t,n,r){await this.sse(Xe(this.apiBase,`/v1/chat/completions`,{autoload:!1}),{method:`POST`,body:Pt(t,e),signal:r,headers:{Accept:`text/event-stream`}},n)}async responses(e,t,n,r){await this.sse(Xe(this.apiBase,`/v1/responses`,{autoload:!1}),{method:`POST`,body:Pt(t,e),signal:r,headers:{Accept:`text/event-stream`}},n)}async request(e,t,n){let r=await this.fetchWithAuth(Xe(this.apiBase,e,n.query),n);try{return r.response.ok||await this.throwHttp(r.response,r.signal),t(nt(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 We({onDone:n.onDone,onMessage:n.onFrame}),i=e.body.getReader();try{for(;;){let e=await Ft(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}=It(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=bt(nt(n)))}catch{r=null}throw new kt(e.status,Mt(r,n),Nt(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 Ft(n,t);if(e.done)break;if(i+=e.value.byteLength,i>At)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 Mt(e,t){return e===null?null:{...e,error:{...e.error,message:Nt(e.error.message,t),field_errors:e.error.field_errors?.map(e=>({...e,message:Nt(e.message,t)}))}}}function Nt(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 Pt(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 Ft(e,t){if(t.aborted)throw await e.cancel().catch(()=>void 0),Lt();let n=null;try{let r=await Promise.race([e.read(),new Promise((r,i)=>{n=()=>{e.cancel().catch(()=>void 0),i(Lt())},t.addEventListener(`abort`,n,{once:!0})})]);if(t.aborted)throw Lt();return r}finally{n!==null&&t.removeEventListener(`abort`,n)}}function It(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 Lt(){return typeof DOMException==`function`?new DOMException(`The WebUI request was aborted.`,`AbortError`):Error(`The WebUI request was aborted.`)}function Rt(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 zt(e,t){let n=[...e.values()].sort((e,t)=>t.updated_at.localeCompare(e.updated_at)),r=n.filter(e=>!Bt(e)),i=n.filter(e=>Bt(e)&&Date.parse(e.updated_at)>t-36e5).slice(0,200);return new Map([...r,...i].map(e=>[e.operation_id,e]))}function Bt(e){return[`succeeded`,`failed`,`cancelled`].includes(e.state)}var Vt=`webui.ui-api.v1`;function Ht(){return{schemaVersion:Vt,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 Ut(e,t){return t.type===`login-start`?{...e,auth:{status:`authenticating`,tokenPresent:!0},connection:`bootstrapping`,error:null}:t.type===`login-success`?V(e,t.bootstrap,t.now):t.type===`logout`?{...Ht(),lastUpdatedAt:t.now}:t.type===`select-model`?{...e,selectedModelId:t.modelId,runtimeHistory:[]}:t.type===`catalog`?Wt(e,t.response,t.now):t.type===`operations-snapshot`?Gt(e,t.response,t.now):t.type===`operation`?Kt(e,t.operation,t.sequence,t.now):t.type===`runtime`?qt(e,t.runtime,t.sequence,t.now):t.type===`event`?Jt(e,t.event,t.now):t.type===`pending`?{...e,pendingReconciliations:nn(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 V(e,t,n){let r=t.server.server_instance_id;return e.serverInstanceId!==null&&e.serverInstanceId!==r?{...Ht(),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 Wt(e,t,n){if(e.serverInstanceId!==null&&t.server_instance_id!==e.serverInstanceId)return Qt(e,t.server_instance_id,n);if(e.catalogSequence!==null&&t.snapshot_sequenceo.has(e)))};return $t({...e,operations:o,serverInstanceId:t.server_instance_id,lastSequence:tn(s),error:null,resourceFences:s},n)}function Kt(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=zt(nn(e.operations,t.operation_id,t),r),o=n===null?e.resourceFences.operations:nn(e.resourceFences.operations,t.operation_id,n),s={...e.resourceFences,operations:new Map([...o].filter(([e])=>a.has(e)))};return $t({...e,operations:a,lastSequence:tn(s),error:null,resourceFences:s},r)}function qt(e,t,n,r){if(e.serverInstanceId!==null&&t.server_instance_id!==e.serverInstanceId)return Qt(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:nn(e.resourceFences.models,r,t.sequence)};return $t({...e,catalog:a,serverInstanceId:t.server_instance_id,lastEventId:t.event_id,lastSequence:tn(o),connection:`streaming`,resourceFences:o},n)}function Xt(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:nn(e.resourceFences.runtimes,r.model_id,t.sequence)};return $t({...e,runtimes:nn(e.runtimes,r.model_id,r),runtimeHistory:r.model_id===e.selectedModelId?Rt(e.runtimeHistory,r,n):e.runtimeHistory,serverInstanceId:t.server_instance_id,lastEventId:t.event_id,lastSequence:tn(a),connection:`streaming`,resourceFences:a},n)}function Zt(e,t,n){let r=t.type===`server_restart`?null:e.lastSuccessfulAt;return{...Ht(),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 Qt(e,t,n){return{...Ht(),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 $t(e,t){return{...e,lastUpdatedAt:t,lastSuccessfulAt:t}}function en(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 tn(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 nn(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 an=2e3,on=1e4,sn=3e4,cn=6e4,ln=6e4,un=new Set([`snapshot`,`model_revision`]),dn=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??_n,this.visibility=e.visibility??vn,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>=ln}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()})},on);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:pn(n),error:mn(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=fn(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:pn(n),error:mn(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:gn(`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:gn(`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 hn(`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>=cn&&(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 an}backoffDelay(){let e=Math.min(sn,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 fn(e){let t=tn(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 pn(e){if(e instanceof hn)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 mn(e){return e instanceof hn?{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 hn=class extends Error{code=`snapshot_mismatch`;constructor(e){super(e),this.name=`SnapshotConsistencyError`}};function gn(e,t,n){if(n.server_instance_id!==t.server_instance_id)throw new hn(`${e} pagination crossed a server restart; refresh the authoritative snapshot.`);if(n.snapshot_sequence!==t.snapshot_sequence)throw new hn(`${e} pagination crossed snapshot sequence boundaries; refresh the authoritative snapshot.`)}var _n={setTimeout:(e,t)=>globalThis.setTimeout(e,t),clearTimeout:e=>globalThis.clearTimeout(e),now:()=>Date.now()},vn={hidden:()=>typeof document<`u`&&document.hidden,subscribe:e=>typeof document>`u`?()=>void 0:(document.addEventListener(`visibilitychange`,e),()=>document.removeEventListener(`visibilitychange`,e))},yn=_.createContext(null),bn=_.createContext(null);function xn({children:e,apiBase:t,fetchImpl:n}){let[r,i]=_.useReducer(Ut,void 0,Ht),a=_.useRef(r);a.current=r;let o=_.useRef(0),s=_.useRef(null),c=_.useMemo(()=>new jt({apiBase:t,fetchImpl:n,onUnauthorized:()=>{o.current+=1,s.current?.stop(),i({type:`logout`,now:Date.now()})}}),[t,n]);_.useEffect(()=>{let e=new dn({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 kt)&&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)(bn.Provider,{value:l,children:(0,x.jsx)(yn.Provider,{value:r,children:e})})}function Sn(){let e=_.useContext(yn);if(e===null)throw Error(`useWebUi must be used within WebUiProvider.`);return e}function Cn(){let e=_.useContext(bn);if(e===null)throw Error(`useWebUiActions must be used within WebUiProvider.`);return e}var wn=Object.freeze({}),Tn=[`max_tokens`,`temperature`,`top_p`,`top_k`,`min_p`,`repetition_penalty`,`seed`];function En(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(!Tn.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 Dn=wn,On=new Set;function kn(e){return On.add(e),()=>On.delete(e)}function An(e){Dn=En(e);for(let e of On)e()}function jn(){An(wn)}function Mn(){return{defaults:(0,_.useSyncExternalStore)(kn,()=>Dn,()=>wn),setDefaults:An,reset:jn}}function Nn(e,t,n){return e===null||e<=0||t===null||n===void 0?`unknown`:t+n>e?`exceeds`:`raw-fits`}function Pn({modelId:e,nCtx:t,locale:n}){let r=Cn(),{defaults:i}=Mn(),[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=Nn(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)(Ce,{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 Fn(e){return e instanceof kt?e.status===401?`wrong-key`:e.status===403?`forbidden`:`generic`:e instanceof $e||e instanceof Error&&e.name===`ValidationError`?`schema`:e instanceof TypeError||e instanceof Error&&/fetch|network|offline|connection/i.test(e.message)?`offline`:`generic`}function In(e,t){let n=Kn(t);return n===null?R(e,`model.selected.none`):`${n.identity.display_name} · ${qn(e,n.lifecycle.state)}`}function Ln(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,sequence:Jn(e,t),status:Rn(e,t.connection)})}function Rn(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 zn(e){return e.snapshot.auth.status===`authenticated`?e.snapshot.connection===`schema-mismatch`?(0,x.jsx)(Hn,{...e}):(0,x.jsx)(Vn,{...e}):(0,x.jsx)(Bn,{...e})}function Bn(e){return e.authFailure===`schema`?(0,x.jsx)(Hn,{...e}):(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsxs)(`section`,{className:`screen-heading connection-prompt`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:e.eyebrow}),(0,x.jsx)(`h1`,{"data-testid":e.titleTestId,children:e.title}),(0,x.jsx)(`p`,{"data-testid":z(`connection.prompt.body`),children:R(e.locale,`connection.prompt.body`)})]}),(0,x.jsx)(Ne,{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:Gn(e.locale,e.authFailure),busy:e.snapshot.auth.status===`authenticating`,onSubmit:e.onLogin,onLogout:e.onLogout,testId:z(`auth.login`)})]})}function Vn(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.jsxs)(`section`,{className:`screen-heading connection-prompt`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:e.eyebrow}),(0,x.jsx)(`h1`,{"data-testid":e.titleTestId,children:e.title}),(0,x.jsx)(`p`,{"data-testid":z(`connection.authenticated.body`),children:R(e.locale,`connection.authenticated.body`)})]}),(0,x.jsx)(B,{tone:`info`,title:R(e.locale,`connection.authenticated.title`),body:Un(e.locale,e.snapshot),testId:z(`connection.authenticated.detail`)}),t?(0,x.jsx)(B,{title:R(e.locale,`connection.error.title`),body:Wn(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 Hn(e){return(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsxs)(`section`,{className:`screen-heading connection-prompt`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:e.eyebrow}),(0,x.jsx)(`h1`,{"data-testid":e.titleTestId,children:e.title})]}),(0,x.jsx)(Pe,{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 Un(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:Rn(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:Jn(e,t)})}function Wn(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 Gn(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 Kn(e){return e.selectedModelId===null?null:e.catalog.find(t=>t.identity.id===e.selectedModelId)??null}function qn(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 Jn(e,t){return String(t.lastSequence??t.catalogSequence??t.resourceFences.operationsSnapshot??R(e,`connection.snapshot.pending`))}function Yn({locale:e}){let{defaults:t,setDefaults:n,reset:r}=Mn(),[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:Tn.map(n=>(0,x.jsx)(Ce,{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)(B,{title:R(e,`settings.generation.error_title`),body:o}):null,(0,x.jsxs)(`div`,{children:[(0,x.jsx)(N,{onClick:()=>{try{n(En(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)(Ce,{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)(Ee,{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 Xn({modelId:e,locale:t}){let n=Cn(),[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]=Be(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:Ve(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)(B,{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)(Ce,{label:e.name,value:a[e.name]??Ve(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)(Ce,{label:e.name,value:Ve(e,r.current[e.name]),disabled:!0,hint:e.reason??e.help},e.name))]}),(0,x.jsxs)(Ee,{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,Ve(e,e.default)]))),c({}),m(!1)},children:R(t,`settings.live.reset.confirm`)})]})]})}var Zn=[`fp16`,`float16`,`int8`,`i8`,`turbo4-asym`,`fp16+turbo4`,`turbo3-asym`,`fp16+turbo3`,`turbo3`,`turbo4`,`turbo4-sym`,`turbo4-delegated`,`fp16+turbo4-delegated`],Qn=Object.freeze({});function $n(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`||!Zn.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 er(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:$n(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]=$n(t)}return{version:1,reusable:$n(n.reusable),models:r}}var tr=`mlxcel.webui.load-profiles.v1`,nr={version:1,reusable:Qn,models:{}},rr=!1,ir=new Set;function ar(e){return ir.add(e),()=>ir.delete(e)}function or(){if(!rr){rr=!0;try{let e=localStorage.getItem(tr);e!==null&&(nr=er(e))}catch{}}}function sr(e){let t=JSON.stringify(e),n=er(t);localStorage.setItem(tr,t),nr=n;for(let e of ir)e()}function cr(e){or();let t=(0,_.useSyncExternalStore)(ar,()=>nr);return{reusable:t.reusable,modelProfile:e===null?Qn:t.models[e]??Qn,profile:e!==null&&Object.hasOwn(t.models,e)?t.models[e]:t.reusable,save:(t,n)=>{let r=$n(t);if(n===`model`&&e===null)throw Error(`Select a model first.`);sr(n===`reusable`?{...nr,reusable:r}:{...nr,models:{...nr.models,[e]:r}})},reset:(t=e===null?`reusable`:`model`)=>{let n=Object.fromEntries(Object.entries(nr.models).filter(([t])=>t!==e));sr(t===`reusable`?{...nr,reusable:Qn}:{...nr,models:n})},exportJson:()=>JSON.stringify(nr,null,2),importJson:e=>sr(er(e))}}function lr(e){let t=$n(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=cr(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)(B,{tone:`info`,title:R(t,`settings.profile.single.title`),body:R(t,`settings.profile.single.body`)}):null,(0,x.jsx)(Se,{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)(Ce,{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)(Ce,{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)(Se,{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`)},...Zn.map(e=>({value:e,label:e}))]})]}),(0,x.jsx)(`p`,{children:R(t,`settings.profile.restrictions`)}),u?(0,x.jsx)(B,{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($n(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:lr(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)(Ee,{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 dr({locale:e}){let t=Sn(),n=Cn(),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)(Yn,{locale:e}),o?(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(Se,{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} · ${qn(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)(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:R(e,`settings.server.context.title`)}),(0,x.jsx)(Ce,{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)(Ce,{label:R(e,`settings.server.context.slots`),value:i?.totalSlots?.toString()??c,disabled:!0}),(0,x.jsx)(Ce,{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)(Pn,{modelId:s,nCtx:i?.nCtx??null,locale:e},s)]}),s===null?(0,x.jsx)(B,{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)(Xn,{modelId:s,locale:e},s):(0,x.jsx)(B,{tone:`info`,title:R(e,`settings.server.live_disabled.title`),body:R(e,`settings.server.live_disabled.body`)})]}):(0,x.jsx)(B,{tone:`warning`,title:R(e,`settings.server.unavailable.title`),body:R(e,`settings.server.unavailable.body`)})]})}var fr=[{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 pr(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]`);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)},[]);let o=n=>{let r=fr[(fr.findIndex(t=>t.id===e.route)+n+fr.length)%fr.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)(mr,{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)(Oe,{open:i,title:R(e.locale,`nav.primary`),onClose:()=>a(!1),closeLabel:R(e.locale,`common.close`),testId:`mobile-nav-sheet`,children:(0,x.jsx)(mr,{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`,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:()=>a(!0),"data-testid":z(`toolbar.menu`)}),(0,x.jsxs)(`div`,{className:`toolbar-title`,children:[(0,x.jsx)(`p`,{id:`app-title`,"data-testid":z(`app.title`),children:R(e.locale,`app.title`)}),(0,x.jsx)(`span`,{"data-testid":z(`app.subtitle`),children:R(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)(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)(`section`,{className:`app-content`,children:e.children}),e.inspector]})]})]})}var mr=_.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:fr.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.jsx)(`span`,{className:`connection-dot`,"data-state":e.connectionState,"aria-hidden":`true`}),(0,x.jsx)(`span`,{"data-testid":z(`connection.ready`),children:e.connectionLabel})]})]}));mr.displayName=`Sidebar`;var hr=[`mlxcel`,`glass`],gr=[`light`,`dark`],_r=[`system`,`light`,`dark`],vr=`mlxcel`,yr=`system`;hr.flatMap(e=>gr.map(t=>`${e}-${t}`));var br=`(prefers-color-scheme: dark)`;function xr(e){return typeof e==`string`&&hr.includes(e)}function Sr(e){return typeof e==`string`&&_r.includes(e)}function Cr(e,t){return`${e}-${t}`}function wr(){try{return typeof window>`u`||typeof window.matchMedia!=`function`?`light`:window.matchMedia(`(prefers-color-scheme: dark)`).matches?`dark`:`light`}catch{return`light`}}function Tr(e,t=wr()){return e===`system`?t:e}function Er(e,t,n=wr()){let r=Tr(t,n);return{id:Cr(e,r),family:e,scheme:r,preference:t}}function Dr(e){if(typeof window>`u`||typeof window.matchMedia!=`function`)return()=>void 0;let t;try{t=window.matchMedia(br)}catch{return()=>void 0}let n=t=>e(t.matches?`dark`:`light`);return t.addEventListener(`change`,n),()=>t.removeEventListener(`change`,n)}var Or={themeFamily:vr,colorScheme:yr,material:`glass`,glassIntensity:35,reduceMotion:!1,reduceTransparency:!1,highContrast:`system`,locale:`en`},kr=`mlxcel.webui.appearance`;function Ar(e){let t=typeof e==`number`&&Number.isFinite(e)?e:Or.glassIntensity;return Math.max(0,Math.min(100,Math.round(t)))}function jr(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Mr(e){return e===`glass`||e===`tinted`||e===`opaque`}function Nr(e){return e===`system`||e===`on`||e===`off`}function Pr(e){return Nr(e)?e:e===!0?`on`:e===!1?`off`:Or.highContrast}function Fr(e){return Sr(e.colorScheme)?e.colorScheme:e.colorScheme===void 0&&Sr(e.theme)?e.theme:Or.colorScheme}function Ir(e){return e===`en`||e===`ko`}function Lr(){if(typeof window>`u`)return Or;let e;try{e=window.localStorage.getItem(kr)}catch{return Or}if(!e)return Or;try{let t=JSON.parse(e);return jr(t)?{themeFamily:xr(t.themeFamily)?t.themeFamily:Or.themeFamily,colorScheme:Fr(t),material:Mr(t.material)?t.material:Or.material,glassIntensity:Ar(t.glassIntensity),reduceMotion:t.reduceMotion===!0,reduceTransparency:t.reduceTransparency===!0,highContrast:Pr(t.highContrast),locale:Ir(t.locale)?t.locale:Or.locale}:Or}catch{return Or}}function Rr(e){try{window.localStorage.setItem(kr,JSON.stringify(e))}catch{}}function zr(){return typeof CSS>`u`||typeof CSS.supports!=`function`?!1:CSS.supports(`backdrop-filter: blur(1px)`)||CSS.supports(`-webkit-backdrop-filter: blur(1px)`)}function Br(e,t,n=wr()){let r=Er(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(Ar(t.glassIntensity)),e.dataset.reduceMotion=String(t.reduceMotion),e.dataset.reduceTransparency=String(t.reduceTransparency),e.dataset.highContrast=t.highContrast,e.dataset.backdropFilter=zr()?`supported`:`unsupported`,e.lang=t.locale}function Vr(e){return e.value===null||!Number.isFinite(e.value)?`N/A`:`${new Intl.NumberFormat(void 0,{maximumFractionDigits:2}).format(e.value)} ${e.unit}`}function Hr(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 Ur(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 Wr(e){let t=URL.createObjectURL(new Blob([Ur(e)],{type:`application/json`})),n=document.createElement(`a`);n.href=t,n.download=`mlxcel-diagnostics.json`,n.click(),URL.revokeObjectURL(t)}function Gr({operations:e,locale:t,stale:n}){let r=[...e.values()].sort((e,t)=>Number(Bt(e))-Number(Bt(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=>!Bt(e)).length),failed:String(r.filter(e=>e.state===`failed`).length)})}),(0,x.jsx)(`p`,{children:R(t,`activity.session`)}),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)(Kr,{operation:e,locale:t,stale:n})},e.operation_id))})]})}function Kr({operation:e,locale:t,stale:n}){let r=Cn(),i=Sn(),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=Bt(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:Hr(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)(B,{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)(B,{title:R(t,`activity.cancel_failed`),body:R(t,`activity.refresh`)}):null]})}var qr=new Set(be.map(e=>e.key).filter(e=>e.startsWith(`activity.metric.`))),Jr=e=>qr.has(e);function Yr({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 Jr(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)(B,{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.jsxs)(`dl`,{className:`activity-metric`,children:[(0,x.jsx)(`dt`,{children:s(e)}),(0,x.jsx)(`dd`,{children:Vr(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.jsxs)(`dl`,{className:`activity-metric`,children:[(0,x.jsx)(`dt`,{children:s(e)}),(0,x.jsx)(`dd`,{children:Vr(n)}),(0,x.jsxs)(`dd`,{children:[R(t,`activity.scope`),`: `,n.scope]}),(0,x.jsxs)(`dd`,{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)(`dd`,{children:n.reason})]},e))})]})]})}var Xr=(function(){let e=typeof document<`u`&&document.createElement(`link`).relList;return e&&e.supports&&e.supports(`modulepreload`)?`modulepreload`:`preload`})(),Zr=function(e,t){return new URL(e,t).href},Qr={},$r=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=Zr(t,n),t=s(t),t in Qr)return;Qr[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`:Xr,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)})},ei=(0,_.lazy)(()=>$r(()=>import(`./history-DIlBLmUk.js`),[],import.meta.url));function ti({locale:e}){let t=Sn(),n=Cn(),[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":z(`activity.title`),children:R(e,`activity.title`)}),(0,x.jsx)(`p`,{children:R(e,`activity.intro`)}),(0,x.jsxs)(`p`,{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)(Se,{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.jsxs)(`div`,{className:`activity-toolbar`,children:[(0,x.jsx)(N,{onClick:()=>{n.refresh()},children:R(e,`activity.refresh`)}),(0,x.jsx)(N,{onClick:()=>Wr(t),children:R(e,`activity.export`)})]}),a?(0,x.jsx)(B,{tone:`warning`,title:R(e,`activity.stale`),body:R(e,`activity.refresh`)}):null,(0,x.jsx)(Gr,{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)(Yr,{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)(ei,{samples:t.runtimeHistory,locale:e})}):null]})}var ni=e=>[`succeeded`,`failed`,`cancelled`].includes(e.state),ri=e=>e.auth.status===`authenticated`&&e.bootstrap!==null&&e.catalogSequence!==null&&[`ready`,`streaming`,`polling`].includes(e.connection);function ii(e,t){return ri(e)&&e.bootstrap?.actions[t]?.state===`enabled`}function ai(e,t){return[...e.operations.values()].some(e=>!ni(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 oi(e,t){return ii(e,`load`)&&t.supported&&t.complete&&t.metadata.support.runnable_on_backend&&!t.lifecycle.busy&&[`unloaded`,`failed`].includes(t.lifecycle.state)&&!ai(e,t.identity.id)}function si(e,t){return ii(e,`unload`)&&t.lifecycle.state===`ready`&&!ai(e,t.identity.id)}function ci(e,t){return ii(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)&&!ai(e,t.identity.id)}function li(e,t){return ri(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&&si(e,n)&&!n.lifecycle.busy&&n.lifecycle.active_requests===0&&n.lifecycle.draining_requests===0)}function di(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 fi(e,t){return e instanceof kt?e.envelope?.error.code===`stale_revision`?R(t,`models.library.stale`):e.message:R(t,`models.library.pending`)}function pi(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 mi(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 hi(e){return e.length===0||e.length<=128&&e.split(`/`).every(e=>e!==`.`&&e!==`..`&&/^[A-Za-z0-9._~+-]+$/.test(e))}function gi({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=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)(Ee,{open:!0,title:f,onClose:i,closeLabel:R(n,`common.close`),testId:`models-confirm`,children:[(0,x.jsx)(`p`,{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)(Ce,{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`,{children:[e.identity.display_name,` · `,e.lifecycle.state,` · `,R(n,`models.library.active`),`:`,` `,e.lifecycle.active_requests]},e.identity.id))}),(0,x.jsx)(Se,{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 _i({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=mi(s.trim())&&hi(l.trim());return(0,x.jsx)(Ee,{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)(Ce,{label:R(e,`models.library.repo`),value:s,onChange:c,testId:`models-repo`,error:s&&!mi(s.trim())?R(e,`models.library.repo_invalid`):void 0}),(0,x.jsx)(Ce,{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 vi({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 yi({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`),di(s.disk_bytes,r)],[R(r,`models.library.memory`),di(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)(Ae,{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:qn(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)(vi,{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||!oi(n,e),onClick:()=>a(`load`),children:R(r,`models.load`)}),(0,x.jsx)(N,{"data-testid":`models-use-chat`,disabled:i||!li(n,e),onClick:o,children:R(r,`models.library.chat`)}),(0,x.jsx)(N,{"data-testid":`models-unload`,disabled:i||!si(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||!ci(n,e),onClick:()=>a(`delete`),children:R(r,`models.library.delete`)}):null]}),li(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 bi({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(ni(e))-Number(ni(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:Si(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:`${di(s.progress.completed_bytes,t)} / ${di(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===xi(s)&&oi(e,t)),onClick:()=>o(xi(s)),children:R(t,`models.library.capacity`)}):null,s.kind===`download`&&!ni(s)?(0,x.jsx)(N,{disabled:n||!ri(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||!ii(e,`download`),onClick:()=>a(s),children:R(t,`models.library.retry_download`)}):null]})]})},s.operation_id))})]})}function xi(e){return e.target.target_kind===`model`?e.target.model_id:``}function Si(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 Ci=25;function wi({locale:e}){let t=Sn(),n=Cn(),[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}=cr(y?.identity.id??null),{profile:S}=cr(f?.kind===`capacity`?f.entry.identity.id:null),C=pi(t.catalog,r),w=Math.max(1,Math.ceil(C.length/Ci)),T=Math.min(a,w-1),E=[...t.operations.values()].some(e=>e.kind===`download`&&!ni(e))||[...t.pendingReconciliations.values()].some(e=>e.kind===`download`),D=[...t.operations.values()].some(e=>e.kind===`catalog_refresh`&&!ni(e))||[...t.pendingReconciliations.values()].some(e=>e.kind===`catalog-refresh`),O=e=>{i({...r,...e}),o(0)},k=async(n,r)=>{if(l.current||!ri(t))return!1;l.current=!0,c(!0),d(null);try{return await n(),!0}catch(t){return d(fi(t,e)),r?.(t),!1}finally{l.current=!1,c(!1)}},ee=(r,i,a=b)=>{if(!oi(t,r)){d(R(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(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 kt&&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||ni(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(!ui(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`&&si(t,o)?k(()=>n.unloadModel({action:`unload`,model_id:o.identity.id,expected_revision:o.identity.revision,idempotency_key:crypto.randomUUID()})):a.kind===`delete`&&ci(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`,"aria-label":R(e,`models.library.inspect`,{name:r.identity.display_name}),onClick:()=>n.selectModel(r.identity.id),children:r.identity.display_name}),r.identity.id===t.selectedModelId?(0,x.jsx)(`small`,{children:R(e,`models.library.selected`)}):null,(0,x.jsxs)(`p`,{children:[r.identity.source,` · `,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:qn(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.jsxs)(`section`,{className:`screen-heading`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:R(e,`routes.models.eyebrow`)}),(0,x.jsx)(`h1`,{tabIndex:-1,"data-dialog-focus-fallback":!0,"data-testid":z(`models.title`),children:R(e,`models.title`)}),(0,x.jsx)(`p`,{children:R(e,`models.library.subtitle`)})]}),ri(t)?null:(0,x.jsx)(B,{title:R(e,`models.library.stale`),body:t.error?.message??R(e,`models.library.waiting`),action:(0,x.jsx)(N,{onClick:()=>{n.refresh()},children:R(e,`models.library.refresh`)}),testId:`connection-error-title`}),u?(0,x.jsx)(B,{title:R(e,`models.library.error`),body:u,action:(0,x.jsx)(N,{onClick:()=>{d(null),n.refresh()},children:R(e,`models.library.refresh`)}),testId:`models-action-error`}):null,t.bootstrap?.server.mode===`single_model`?(0,x.jsx)(B,{tone:`info`,title:R(e,`models.library.single`),body:`mlxcel-server --webui`,testId:`models-read-only`}):null,(0,x.jsxs)(`div`,{className:`button-row`,children:[(0,x.jsx)(N,{tone:`primary`,onClick:()=>h({repo:``,revision:``}),disabled:s||E||!ii(t,`download`),"data-testid":`models-add`,children:R(e,`models.library.add`)}),(0,x.jsx)(N,{disabled:s||D||!ri(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`)})]}),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:Un(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)(Ce,{label:R(e,`models.library.search`),value:r.query,onChange:e=>O({query:e}),testId:`models-search`}),(0,x.jsx)(Se,{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)(Se,{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)(Se,{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:qn(e,t)}))]}),(0,x.jsx)(Se,{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)(he,{columns:M,rows:C.slice(T*Ci,(T+1)*Ci),getRowKey:e=>e.identity.id,ariaLabel:R(e,`models.title`),testId:`models-table`,rowClassName:e=>e.identity.id===t.selectedModelId?`models-selected`:void 0,loading:t.catalogSequence===null,loadingState:(0,x.jsx)(`p`,{role:`status`,children: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)(yi,{entry:y,profile:b,state:t,locale:e,busy:s,onAction:A,onChat:()=>{li(t,y)&&(n.selectModel(y.identity.id),window.location.hash=`chat`)}}):null]}),(0,x.jsx)(bi,{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&&oi(t,n)&&p({kind:`capacity`,entry:n,instance:t.serverInstanceId})}}),f?(0,x.jsx)(gi,{value:f,state:t,locale:e,busy:s,onClose:()=>p(null),onConfirm:te},f.kind):null,m?(0,x.jsx)(_i,{locale:e,state:t,initial:m,error:u,busy:s||E||!ii(t,`download`),onClose:()=>h(null),onDownload:(e,r)=>{ii(t,`download`)&&!E&&k(()=>n.downloadModel({repo_id:e,revision:r||null,idempotency_key:crypto.randomUUID()})).then(e=>{e&&h(null)})}}):null]})}var Ti={en:`en-US`,ko:`ko-KR`},Ei=e=>Ti[e];function Di(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)(ji,{locale:e.locale})},{id:`data`,label:R(e.locale,`gallery.tab.data`),panel:(0,x.jsx)(Mi,{locale:e.locale})}]}),(0,x.jsxs)(Ee,{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)(Ce,{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 Ai(e){return(0,x.jsxs)(`div`,{className:`gallery-grid`,children:[(0,x.jsxs)(`article`,{className:`surface-card`,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)(Ce,{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)(Se,{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)(`article`,{className:`surface-card`,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)(ke,{label: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 ji(e){return(0,x.jsxs)(`div`,{className:`gallery-grid`,children:[(0,x.jsx)(Ne,{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)(Pe,{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)(B,{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:Di(67108864,e.locale)})}),(0,x.jsx)(fe,{label:R(e.locale,`gallery.progress.measured`),value:37})]}),(0,x.jsxs)(Me,{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 Mi(e){return(0,x.jsxs)(`div`,{className:`gallery-grid dense-gallery`,children:[(0,x.jsxs)(`article`,{className:`surface-card table-card`,tabIndex:0,"aria-label":R(e.locale,`gallery.sample.caption`),children:[(0,x.jsx)(`h2`,{children:R(e.locale,`gallery.data.title`)}),(0,x.jsxs)(je,{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:Oi(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:Oi(null,e.locale)})]})]})]})]}),(0,x.jsxs)(Ae,{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`)})]})]})}var Ni={count:4,bytes:8388608,dimension:4096,pixels:16e6},Pi=new Set([`image/png`,`image/jpeg`,`image/webp`]);function Fi(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 +`,$e=class extends Error{path;constructor(e,t){super(`${e}: ${t}`),this.path=e,this.name=`ValidationError`}},et=rt(Qe);function tt(e,t,n=`$`){let r=ht(et,[`components`,`schemas`],`#/components/schemas`)[e];if(r===void 0)throw new $e(n,`unknown schema ${e}`);it(r,t,n)}function nt(e){return JSON.parse(e)}function rt(e){return mt(nt(e),`$contract`)}function it(e,t,n){let r=mt(e,`${n}#schema`);if(typeof r.$ref==`string`){it(ft(r.$ref),t,n);return}if(r.anyOf!==void 0){if(!Array.isArray(r.anyOf)||!r.anyOf.some(e=>pt(e,t,n)))throw new $e(n,`did not match any allowed schema`);return}if(r.oneOf!==void 0){if(!Array.isArray(r.oneOf))throw new $e(n,`schema oneOf must be an array`);let e=r.oneOf.filter(e=>pt(e,t,n)).length;if(e!==1)throw new $e(n,`matched ${e} oneOf schemas`);return}if(r.const!==void 0&&t!==r.const)throw new $e(n,`expected constant ${String(r.const)}`);if(Array.isArray(r.enum)&&!r.enum.some(e=>e===t))throw new $e(n,`unexpected enum value ${String(t)}`);let i=r.type;if(Array.isArray(i)){if(!i.some(e=>dt(e,t)))throw new $e(n,`expected one of ${i.join(`, `)}`)}else if(typeof i==`string`&&!dt(i,t))throw new $e(n,`expected ${i}`);typeof t==`string`&&ct(r,t,n),typeof t==`number`&&ut(r,t,n),Array.isArray(t)&&ot(r,t,n),gt(t)&&at(r,t,n)}function at(e,t,n){let r=_t(e.required,`${n}#schema.required`,!1),i=e.properties===void 0?{}:mt(e.properties,`${n}#schema.properties`);for(let e of r)if(!(e in t))throw new $e(`${n}.${e}`,`missing required property`);if(e.maxProperties!==void 0&&Object.keys(t).length>vt(e.maxProperties,`${n}#schema.maxProperties`))throw new $e(n,`too many object properties`);for(let[r,a]of Object.entries(t)){let t=i[r];if(t!==void 0)it(t,a,`${n}.${r}`);else if(e.additionalProperties===!1)throw new $e(`${n}.${r}`,`unexpected property`);else gt(e.additionalProperties)&&it(e.additionalProperties,a,`${n}.${r}`)}}function ot(e,t,n){if(e.minItems!==void 0&&t.lengthvt(e.maxItems,`${n}#schema.maxItems`))throw new $e(n,`array longer than maximum`);e.items!==void 0&&t.forEach((t,r)=>it(e.items,t,`${n}[${r}]`))}function st(e){let t=0;for(let n=0;n65535?2:1;return t}function ct(e,t,n){let r=st(t);if(e.minLength!==void 0&&rvt(e.maxLength,`${n}#schema.maxLength`))throw new $e(n,`string longer than maximum`);if(typeof e.pattern==`string`&&!new RegExp(e.pattern,`u`).test(t))throw new $e(n,`string does not match pattern`);if(e.format===`date-time`&&!lt(t))throw new $e(n,`invalid RFC3339 date-time`)}function lt(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 ut(e,t,n){if(!Number.isFinite(t))throw new $e(n,`expected finite number`);if(e.type===`integer`&&!Number.isInteger(t))throw new $e(n,`expected integer`);if(e.minimum!==void 0&&tvt(e.maximum,`${n}#schema.maximum`))throw new $e(n,`number above maximum`)}function dt(e,t){return e===`null`?t===null:e===`array`?Array.isArray(t):e===`object`?gt(t):e===`integer`?typeof t==`number`&&Number.isInteger(t):e===`number`?typeof t==`number`&&Number.isFinite(t):typeof t===e}function ft(e){if(!e.startsWith(`#/`))throw new $e(`$ref`,`unsupported external ref ${e}`);return e.slice(2).split(`/`).map(e=>e.replace(/~1/g,`/`).replace(/~0/g,`~`)).reduce((t,n)=>mt(t,e)[n],et)}function pt(e,t,n){try{return it(e,t,n),!0}catch(e){if(e instanceof $e)return!1;throw e}}function mt(e,t){if(!gt(e))throw new $e(t,`expected object`);return e}function ht(e,t,n){return t.reduce((e,t)=>mt(e,n)[t],e)}function gt(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function _t(e,t,n){if(e===void 0&&!n)return[];if(!Array.isArray(e)||!e.every(e=>typeof e==`string`))throw new $e(t,`expected string array`);return e}function vt(e,t){if(typeof e!=`number`||!Number.isFinite(e))throw new $e(t,`expected numeric schema bound`);return e}function yt(e,t,n){return tt(e,t,n),t}function bt(e,t=`$`){return yt(`ErrorEnvelope`,e,t)}function xt(e,t=`$`){return yt(`BootstrapResponse`,e,t)}function St(e,t=`$`){return yt(`CatalogEntry`,e,t)}function Ct(e,t=`$`){return yt(`CatalogListResponse`,e,t)}function wt(e,t=`$`){return yt(`OperationsListResponse`,e,t)}function Tt(e,t=`$`){return yt(`Operation`,e,t)}function Et(e,t=`$`){return yt(`OperationAccepted`,e,t)}function Dt(e,t=`$`){return yt(`RuntimeSnapshot`,e,t)}function Ot(e,t=`$`){return yt(`UiEvent`,e,t)}var kt=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`}},At=2097152,jt=class{apiBase;fetchImpl;bearerToken=null;onUnauthorized;controllers=new Set;constructor(e={}){this.apiBase=qe(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`,xt,{method:`GET`,signal:e})}async catalog(e={},t){return this.request(`/ui-api/v1/catalog`,Ct,{method:`GET`,query:{...e},signal:t})}async catalogEntry(e,t){return this.request(`/ui-api/v1/catalog/${Ze(e)}`,St,{method:`GET`,signal:t})}async refreshCatalog(e,t){return this.request(`/ui-api/v1/catalog/refresh`,Et,{method:`POST`,body:{idempotency_key:e},signal:t})}async modelAction(e,t){return this.request(`/ui-api/v1/model-actions`,Et,{method:`POST`,body:e,signal:t})}async download(e,t){return this.request(`/ui-api/v1/downloads`,Et,{method:`POST`,body:e,signal:t})}async removeModel(e,t){return this.request(`/ui-api/v1/model-removals`,Et,{method:`POST`,body:e,signal:t})}async operationsPage(e={},t){return this.request(`/ui-api/v1/operations`,wt,{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/${Ze(e)}`,Tt,{method:`GET`,signal:t})}async cancelOperation(e,t){return this.request(`/ui-api/v1/operations/${Ze(e)}/cancel`,Et,{method:`POST`,body:{},signal:t})}async runtime(e,t){let n=await this.request(`/ui-api/v1/runtime`,Dt,{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`,He,{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`,Le,{method:`GET`,query:{model:e,autoload:!1},signal:t})}async patchSettings(e,t,n){return this.request(`/settings`,Re,{method:`PATCH`,query:{model:e,autoload:!1},body:{op:`merge`,values:t},signal:n})}async modelProps(e,t){return this.request(`/props`,ze,{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(Xe(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(Ot(nt(t.data)))}})}async chatCompletions(e,t,n,r){await this.sse(Xe(this.apiBase,`/v1/chat/completions`,{autoload:!1}),{method:`POST`,body:Pt(t,e),signal:r,headers:{Accept:`text/event-stream`}},n)}async responses(e,t,n,r){await this.sse(Xe(this.apiBase,`/v1/responses`,{autoload:!1}),{method:`POST`,body:Pt(t,e),signal:r,headers:{Accept:`text/event-stream`}},n)}async request(e,t,n){let r=await this.fetchWithAuth(Xe(this.apiBase,e,n.query),n);try{return r.response.ok||await this.throwHttp(r.response,r.signal),t(nt(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 We({onDone:n.onDone,onMessage:n.onFrame}),i=e.body.getReader();try{for(;;){let e=await Ft(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}=It(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=bt(nt(n)))}catch{r=null}throw new kt(e.status,Mt(r,n),Nt(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 Ft(n,t);if(e.done)break;if(i+=e.value.byteLength,i>At)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 Mt(e,t){return e===null?null:{...e,error:{...e.error,message:Nt(e.error.message,t),field_errors:e.error.field_errors?.map(e=>({...e,message:Nt(e.message,t)}))}}}function Nt(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 Pt(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 Ft(e,t){if(t.aborted)throw await e.cancel().catch(()=>void 0),Lt();let n=null;try{let r=await Promise.race([e.read(),new Promise((r,i)=>{n=()=>{e.cancel().catch(()=>void 0),i(Lt())},t.addEventListener(`abort`,n,{once:!0})})]);if(t.aborted)throw Lt();return r}finally{n!==null&&t.removeEventListener(`abort`,n)}}function It(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 Lt(){return typeof DOMException==`function`?new DOMException(`The WebUI request was aborted.`,`AbortError`):Error(`The WebUI request was aborted.`)}function Rt(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 zt(e,t){let n=[...e.values()].sort((e,t)=>t.updated_at.localeCompare(e.updated_at)),r=n.filter(e=>!Bt(e)),i=n.filter(e=>Bt(e)&&Date.parse(e.updated_at)>t-36e5).slice(0,200);return new Map([...r,...i].map(e=>[e.operation_id,e]))}function Bt(e){return[`succeeded`,`failed`,`cancelled`].includes(e.state)}var Vt=`webui.ui-api.v1`;function Ht(){return{schemaVersion:Vt,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 Ut(e,t){return t.type===`login-start`?{...e,auth:{status:`authenticating`,tokenPresent:!0},connection:`bootstrapping`,error:null}:t.type===`login-success`?V(e,t.bootstrap,t.now):t.type===`logout`?{...Ht(),lastUpdatedAt:t.now}:t.type===`select-model`?{...e,selectedModelId:t.modelId,runtimeHistory:[]}:t.type===`catalog`?Wt(e,t.response,t.now):t.type===`operations-snapshot`?Gt(e,t.response,t.now):t.type===`operation`?Kt(e,t.operation,t.sequence,t.now):t.type===`runtime`?qt(e,t.runtime,t.sequence,t.now):t.type===`event`?Jt(e,t.event,t.now):t.type===`pending`?{...e,pendingReconciliations:nn(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 V(e,t,n){let r=t.server.server_instance_id;return e.serverInstanceId!==null&&e.serverInstanceId!==r?{...Ht(),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 Wt(e,t,n){if(e.serverInstanceId!==null&&t.server_instance_id!==e.serverInstanceId)return Qt(e,t.server_instance_id,n);if(e.catalogSequence!==null&&t.snapshot_sequenceo.has(e)))};return $t({...e,operations:o,serverInstanceId:t.server_instance_id,lastSequence:tn(s),error:null,resourceFences:s},n)}function Kt(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=zt(nn(e.operations,t.operation_id,t),r),o=n===null?e.resourceFences.operations:nn(e.resourceFences.operations,t.operation_id,n),s={...e.resourceFences,operations:new Map([...o].filter(([e])=>a.has(e)))};return $t({...e,operations:a,lastSequence:tn(s),error:null,resourceFences:s},r)}function qt(e,t,n,r){if(e.serverInstanceId!==null&&t.server_instance_id!==e.serverInstanceId)return Qt(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:nn(e.resourceFences.models,r,t.sequence)};return $t({...e,catalog:a,serverInstanceId:t.server_instance_id,lastEventId:t.event_id,lastSequence:tn(o),connection:`streaming`,resourceFences:o},n)}function Xt(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:nn(e.resourceFences.runtimes,r.model_id,t.sequence)};return $t({...e,runtimes:nn(e.runtimes,r.model_id,r),runtimeHistory:r.model_id===e.selectedModelId?Rt(e.runtimeHistory,r,n):e.runtimeHistory,serverInstanceId:t.server_instance_id,lastEventId:t.event_id,lastSequence:tn(a),connection:`streaming`,resourceFences:a},n)}function Zt(e,t,n){let r=t.type===`server_restart`?null:e.lastSuccessfulAt;return{...Ht(),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 Qt(e,t,n){return{...Ht(),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 $t(e,t){return{...e,lastUpdatedAt:t,lastSuccessfulAt:t}}function en(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 tn(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 nn(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 an=2e3,on=1e4,sn=3e4,cn=6e4,ln=6e4,un=new Set([`snapshot`,`model_revision`]),dn=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??_n,this.visibility=e.visibility??vn,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>=ln}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()})},on);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:pn(n),error:mn(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=fn(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:pn(n),error:mn(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:gn(`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:gn(`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 hn(`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>=cn&&(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 an}backoffDelay(){let e=Math.min(sn,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 fn(e){let t=tn(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 pn(e){if(e instanceof hn)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 mn(e){return e instanceof hn?{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 hn=class extends Error{code=`snapshot_mismatch`;constructor(e){super(e),this.name=`SnapshotConsistencyError`}};function gn(e,t,n){if(n.server_instance_id!==t.server_instance_id)throw new hn(`${e} pagination crossed a server restart; refresh the authoritative snapshot.`);if(n.snapshot_sequence!==t.snapshot_sequence)throw new hn(`${e} pagination crossed snapshot sequence boundaries; refresh the authoritative snapshot.`)}var _n={setTimeout:(e,t)=>globalThis.setTimeout(e,t),clearTimeout:e=>globalThis.clearTimeout(e),now:()=>Date.now()},vn={hidden:()=>typeof document<`u`&&document.hidden,subscribe:e=>typeof document>`u`?()=>void 0:(document.addEventListener(`visibilitychange`,e),()=>document.removeEventListener(`visibilitychange`,e))},yn=_.createContext(null),bn=_.createContext(null);function xn({children:e,apiBase:t,fetchImpl:n}){let[r,i]=_.useReducer(Ut,void 0,Ht),a=_.useRef(r);a.current=r;let o=_.useRef(0),s=_.useRef(null),c=_.useMemo(()=>new jt({apiBase:t,fetchImpl:n,onUnauthorized:()=>{o.current+=1,s.current?.stop(),i({type:`logout`,now:Date.now()})}}),[t,n]);_.useEffect(()=>{let e=new dn({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 kt)&&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)(bn.Provider,{value:l,children:(0,x.jsx)(yn.Provider,{value:r,children:e})})}function Sn(){let e=_.useContext(yn);if(e===null)throw Error(`useWebUi must be used within WebUiProvider.`);return e}function Cn(){let e=_.useContext(bn);if(e===null)throw Error(`useWebUiActions must be used within WebUiProvider.`);return e}var wn=Object.freeze({}),Tn=[`max_tokens`,`temperature`,`top_p`,`top_k`,`min_p`,`repetition_penalty`,`seed`];function En(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(!Tn.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 Dn=wn,On=new Set;function kn(e){return On.add(e),()=>On.delete(e)}function An(e){Dn=En(e);for(let e of On)e()}function jn(){An(wn)}function Mn(){return{defaults:(0,_.useSyncExternalStore)(kn,()=>Dn,()=>wn),setDefaults:An,reset:jn}}function Nn(e,t,n){return e===null||e<=0||t===null||n===void 0?`unknown`:t+n>e?`exceeds`:`raw-fits`}function Pn({modelId:e,nCtx:t,locale:n}){let r=Cn(),{defaults:i}=Mn(),[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=Nn(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)(Ce,{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 Fn(e){return e instanceof kt?e.status===401?`wrong-key`:e.status===403?`forbidden`:`generic`:e instanceof $e||e instanceof Error&&e.name===`ValidationError`?`schema`:e instanceof TypeError||e instanceof Error&&/fetch|network|offline|connection/i.test(e.message)?`offline`:`generic`}function In(e,t){let n=Kn(t);return n===null?R(e,`model.selected.none`):`${n.identity.display_name} · ${qn(e,n.lifecycle.state)}`}function Ln(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,sequence:Jn(e,t),status:Rn(e,t.connection)})}function Rn(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 zn(e){return e.snapshot.auth.status===`authenticated`?e.snapshot.connection===`schema-mismatch`?(0,x.jsx)(Hn,{...e}):(0,x.jsx)(Vn,{...e}):(0,x.jsx)(Bn,{...e})}function Bn(e){return e.authFailure===`schema`?(0,x.jsx)(Hn,{...e}):(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsxs)(`section`,{className:`screen-heading connection-prompt`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:e.eyebrow}),(0,x.jsx)(`h1`,{"data-testid":e.titleTestId,children:e.title}),(0,x.jsx)(`p`,{"data-testid":z(`connection.prompt.body`),children:R(e.locale,`connection.prompt.body`)})]}),(0,x.jsx)(Ne,{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:Gn(e.locale,e.authFailure),busy:e.snapshot.auth.status===`authenticating`,onSubmit:e.onLogin,onLogout:e.onLogout,testId:z(`auth.login`)})]})}function Vn(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.jsxs)(`section`,{className:`screen-heading connection-prompt`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:e.eyebrow}),(0,x.jsx)(`h1`,{"data-testid":e.titleTestId,children:e.title}),(0,x.jsx)(`p`,{"data-testid":z(`connection.authenticated.body`),children:R(e.locale,`connection.authenticated.body`)})]}),(0,x.jsx)(B,{tone:`info`,title:R(e.locale,`connection.authenticated.title`),body:Un(e.locale,e.snapshot),testId:z(`connection.authenticated.detail`)}),t?(0,x.jsx)(B,{title:R(e.locale,`connection.error.title`),body:Wn(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 Hn(e){return(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsxs)(`section`,{className:`screen-heading connection-prompt`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:e.eyebrow}),(0,x.jsx)(`h1`,{"data-testid":e.titleTestId,children:e.title})]}),(0,x.jsx)(Pe,{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 Un(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:Rn(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:Jn(e,t)})}function Wn(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 Gn(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 Kn(e){return e.selectedModelId===null?null:e.catalog.find(t=>t.identity.id===e.selectedModelId)??null}function qn(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 Jn(e,t){return String(t.lastSequence??t.catalogSequence??t.resourceFences.operationsSnapshot??R(e,`connection.snapshot.pending`))}function Yn({locale:e}){let{defaults:t,setDefaults:n,reset:r}=Mn(),[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:Tn.map(n=>(0,x.jsx)(Ce,{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)(B,{title:R(e,`settings.generation.error_title`),body:o}):null,(0,x.jsxs)(`div`,{children:[(0,x.jsx)(N,{onClick:()=>{try{n(En(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)(Ce,{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)(Ee,{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 Xn({modelId:e,locale:t}){let n=Cn(),[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]=Be(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:Ve(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)(B,{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)(Ce,{label:e.name,value:a[e.name]??Ve(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)(Ce,{label:e.name,value:Ve(e,r.current[e.name]),disabled:!0,hint:e.reason??e.help},e.name))]}),(0,x.jsxs)(Ee,{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,Ve(e,e.default)]))),c({}),m(!1)},children:R(t,`settings.live.reset.confirm`)})]})]})}var Zn=[`fp16`,`float16`,`int8`,`i8`,`turbo4-asym`,`fp16+turbo4`,`turbo3-asym`,`fp16+turbo3`,`turbo3`,`turbo4`,`turbo4-sym`,`turbo4-delegated`,`fp16+turbo4-delegated`],Qn=Object.freeze({});function $n(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`||!Zn.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 er(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:$n(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]=$n(t)}return{version:1,reusable:$n(n.reusable),models:r}}var tr=`mlxcel.webui.load-profiles.v1`,nr={version:1,reusable:Qn,models:{}},rr=!1,ir=new Set;function ar(e){return ir.add(e),()=>ir.delete(e)}function or(){if(!rr){rr=!0;try{let e=localStorage.getItem(tr);e!==null&&(nr=er(e))}catch{}}}function sr(e){let t=JSON.stringify(e),n=er(t);localStorage.setItem(tr,t),nr=n;for(let e of ir)e()}function cr(e){or();let t=(0,_.useSyncExternalStore)(ar,()=>nr);return{reusable:t.reusable,modelProfile:e===null?Qn:t.models[e]??Qn,profile:e!==null&&Object.hasOwn(t.models,e)?t.models[e]:t.reusable,save:(t,n)=>{let r=$n(t);if(n===`model`&&e===null)throw Error(`Select a model first.`);sr(n===`reusable`?{...nr,reusable:r}:{...nr,models:{...nr.models,[e]:r}})},reset:(t=e===null?`reusable`:`model`)=>{let n=Object.fromEntries(Object.entries(nr.models).filter(([t])=>t!==e));sr(t===`reusable`?{...nr,reusable:Qn}:{...nr,models:n})},exportJson:()=>JSON.stringify(nr,null,2),importJson:e=>sr(er(e))}}function lr(e){let t=$n(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=cr(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)(B,{tone:`info`,title:R(t,`settings.profile.single.title`),body:R(t,`settings.profile.single.body`)}):null,(0,x.jsx)(Se,{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)(Ce,{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)(Ce,{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)(Se,{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`)},...Zn.map(e=>({value:e,label:e}))]})]}),(0,x.jsx)(`p`,{children:R(t,`settings.profile.restrictions`)}),u?(0,x.jsx)(B,{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($n(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:lr(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)(Ee,{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 dr({locale:e}){let t=Sn(),n=Cn(),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)(Yn,{locale:e}),o?(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(Se,{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} · ${qn(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)(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:R(e,`settings.server.context.title`)}),(0,x.jsx)(Ce,{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)(Ce,{label:R(e,`settings.server.context.slots`),value:i?.totalSlots?.toString()??c,disabled:!0}),(0,x.jsx)(Ce,{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)(Pn,{modelId:s,nCtx:i?.nCtx??null,locale:e},s)]}),s===null?(0,x.jsx)(B,{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)(Xn,{modelId:s,locale:e},s):(0,x.jsx)(B,{tone:`info`,title:R(e,`settings.server.live_disabled.title`),body:R(e,`settings.server.live_disabled.body`)})]}):(0,x.jsx)(B,{tone:`warning`,title:R(e,`settings.server.unavailable.title`),body:R(e,`settings.server.unavailable.body`)})]})}var fr=[{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 pr(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]`);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)},[]);let o=n=>{let r=fr[(fr.findIndex(t=>t.id===e.route)+n+fr.length)%fr.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)(mr,{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)(Oe,{open:i,title:R(e.locale,`nav.primary`),onClose:()=>a(!1),closeLabel:R(e.locale,`common.close`),testId:`mobile-nav-sheet`,children:(0,x.jsx)(mr,{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`,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:()=>a(!0),"data-testid":z(`toolbar.menu`)}),(0,x.jsxs)(`div`,{className:`toolbar-title`,children:[(0,x.jsx)(`p`,{id:`app-title`,"data-testid":z(`app.title`),children:R(e.locale,`app.title`)}),(0,x.jsx)(`span`,{"data-testid":z(`app.subtitle`),children:R(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)(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)(`section`,{className:`app-content`,children:e.children}),e.inspector]})]})]})}var mr=_.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:fr.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.jsx)(`span`,{className:`connection-dot`,"data-state":e.connectionState,"aria-hidden":`true`}),(0,x.jsx)(`span`,{"data-testid":z(`connection.ready`),children:e.connectionLabel})]})]}));mr.displayName=`Sidebar`;var hr=[`mlxcel`,`glass`],gr=[`light`,`dark`],_r=[`system`,`light`,`dark`],vr=`mlxcel`,yr=`system`;hr.flatMap(e=>gr.map(t=>`${e}-${t}`));var br=`(prefers-color-scheme: dark)`;function xr(e){return typeof e==`string`&&hr.includes(e)}function Sr(e){return typeof e==`string`&&_r.includes(e)}function Cr(e,t){return`${e}-${t}`}function wr(){try{return typeof window>`u`||typeof window.matchMedia!=`function`?`light`:window.matchMedia(`(prefers-color-scheme: dark)`).matches?`dark`:`light`}catch{return`light`}}function Tr(e,t=wr()){return e===`system`?t:e}function Er(e,t,n=wr()){let r=Tr(t,n);return{id:Cr(e,r),family:e,scheme:r,preference:t}}function Dr(e){if(typeof window>`u`||typeof window.matchMedia!=`function`)return()=>void 0;let t;try{t=window.matchMedia(br)}catch{return()=>void 0}let n=t=>e(t.matches?`dark`:`light`);return t.addEventListener(`change`,n),()=>t.removeEventListener(`change`,n)}var Or={themeFamily:vr,colorScheme:yr,material:`glass`,glassIntensity:35,reduceMotion:!1,reduceTransparency:!1,highContrast:`system`,locale:`en`},kr=`mlxcel.webui.appearance`;function Ar(e){let t=typeof e==`number`&&Number.isFinite(e)?e:Or.glassIntensity;return Math.max(0,Math.min(100,Math.round(t)))}function jr(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Mr(e){return e===`glass`||e===`tinted`||e===`opaque`}function Nr(e){return e===`system`||e===`on`||e===`off`}function Pr(e){return Nr(e)?e:e===!0?`on`:e===!1?`off`:Or.highContrast}function Fr(e){return Sr(e.colorScheme)?e.colorScheme:e.colorScheme===void 0&&Sr(e.theme)?e.theme:Or.colorScheme}function Ir(e){return e===`en`||e===`ko`}function Lr(){if(typeof window>`u`)return Or;let e;try{e=window.localStorage.getItem(kr)}catch{return Or}if(!e)return Or;try{let t=JSON.parse(e);return jr(t)?{themeFamily:xr(t.themeFamily)?t.themeFamily:Or.themeFamily,colorScheme:Fr(t),material:Mr(t.material)?t.material:Or.material,glassIntensity:Ar(t.glassIntensity),reduceMotion:t.reduceMotion===!0,reduceTransparency:t.reduceTransparency===!0,highContrast:Pr(t.highContrast),locale:Ir(t.locale)?t.locale:Or.locale}:Or}catch{return Or}}function Rr(e){try{window.localStorage.setItem(kr,JSON.stringify(e))}catch{}}function zr(){return typeof CSS>`u`||typeof CSS.supports!=`function`?!1:CSS.supports(`backdrop-filter: blur(1px)`)||CSS.supports(`-webkit-backdrop-filter: blur(1px)`)}function Br(e,t,n=wr()){let r=Er(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(Ar(t.glassIntensity)),e.dataset.reduceMotion=String(t.reduceMotion),e.dataset.reduceTransparency=String(t.reduceTransparency),e.dataset.highContrast=t.highContrast,e.dataset.backdropFilter=zr()?`supported`:`unsupported`,e.lang=t.locale}function Vr(e){return e.value===null||!Number.isFinite(e.value)?`N/A`:`${new Intl.NumberFormat(void 0,{maximumFractionDigits:2}).format(e.value)} ${e.unit}`}function Hr(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 Ur(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 Wr(e){let t=URL.createObjectURL(new Blob([Ur(e)],{type:`application/json`})),n=document.createElement(`a`);n.href=t,n.download=`mlxcel-diagnostics.json`,n.click(),URL.revokeObjectURL(t)}function Gr({operations:e,locale:t,stale:n}){let r=[...e.values()].sort((e,t)=>Number(Bt(e))-Number(Bt(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=>!Bt(e)).length),failed:String(r.filter(e=>e.state===`failed`).length)})}),(0,x.jsx)(`p`,{children:R(t,`activity.session`)}),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)(Kr,{operation:e,locale:t,stale:n})},e.operation_id))})]})}function Kr({operation:e,locale:t,stale:n}){let r=Cn(),i=Sn(),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=Bt(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:Hr(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)(B,{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)(B,{title:R(t,`activity.cancel_failed`),body:R(t,`activity.refresh`)}):null]})}var qr=new Set(be.map(e=>e.key).filter(e=>e.startsWith(`activity.metric.`))),Jr=e=>qr.has(e);function Yr({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 Jr(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)(B,{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.jsxs)(`dl`,{className:`activity-metric`,children:[(0,x.jsx)(`dt`,{children:s(e)}),(0,x.jsx)(`dd`,{children:Vr(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.jsxs)(`dl`,{className:`activity-metric`,children:[(0,x.jsx)(`dt`,{children:s(e)}),(0,x.jsx)(`dd`,{children:Vr(n)}),(0,x.jsxs)(`dd`,{children:[R(t,`activity.scope`),`: `,n.scope]}),(0,x.jsxs)(`dd`,{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)(`dd`,{children:n.reason})]},e))})]})]})}var Xr=(function(){let e=typeof document<`u`&&document.createElement(`link`).relList;return e&&e.supports&&e.supports(`modulepreload`)?`modulepreload`:`preload`})(),Zr=function(e,t){return new URL(e,t).href},Qr={},$r=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=Zr(t,n),t=s(t),t in Qr)return;Qr[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`:Xr,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)})},ei=(0,_.lazy)(()=>$r(()=>import(`./history-U2uX7mu1.js`),[],import.meta.url));function ti({locale:e}){let t=Sn(),n=Cn(),[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":z(`activity.title`),children:R(e,`activity.title`)}),(0,x.jsx)(`p`,{children:R(e,`activity.intro`)}),(0,x.jsxs)(`p`,{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)(Se,{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.jsxs)(`div`,{className:`activity-toolbar`,children:[(0,x.jsx)(N,{onClick:()=>{n.refresh()},children:R(e,`activity.refresh`)}),(0,x.jsx)(N,{onClick:()=>Wr(t),children:R(e,`activity.export`)})]}),a?(0,x.jsx)(B,{tone:`warning`,title:R(e,`activity.stale`),body:R(e,`activity.refresh`)}):null,(0,x.jsx)(Gr,{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)(Yr,{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)(ei,{samples:t.runtimeHistory,locale:e})}):null]})}var ni=e=>[`succeeded`,`failed`,`cancelled`].includes(e.state),ri=e=>e.auth.status===`authenticated`&&e.bootstrap!==null&&e.catalogSequence!==null&&[`ready`,`streaming`,`polling`].includes(e.connection);function ii(e,t){return ri(e)&&e.bootstrap?.actions[t]?.state===`enabled`}function ai(e,t){return[...e.operations.values()].some(e=>!ni(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 oi(e,t){return ii(e,`load`)&&t.supported&&t.complete&&t.metadata.support.runnable_on_backend&&!t.lifecycle.busy&&[`unloaded`,`failed`].includes(t.lifecycle.state)&&!ai(e,t.identity.id)}function si(e,t){return ii(e,`unload`)&&t.lifecycle.state===`ready`&&!ai(e,t.identity.id)}function ci(e,t){return ii(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)&&!ai(e,t.identity.id)}function li(e,t){return ri(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&&si(e,n)&&!n.lifecycle.busy&&n.lifecycle.active_requests===0&&n.lifecycle.draining_requests===0)}function di(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 fi(e,t){return e instanceof kt?e.envelope?.error.code===`stale_revision`?R(t,`models.library.stale`):e.message:R(t,`models.library.pending`)}function pi(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 mi(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 hi(e){return e.length===0||e.length<=128&&e.split(`/`).every(e=>e!==`.`&&e!==`..`&&/^[A-Za-z0-9._~+-]+$/.test(e))}function gi({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=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)(Ee,{open:!0,title:f,onClose:i,closeLabel:R(n,`common.close`),testId:`models-confirm`,children:[(0,x.jsx)(`p`,{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)(Ce,{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`,{children:[e.identity.display_name,` · `,e.lifecycle.state,` · `,R(n,`models.library.active`),`:`,` `,e.lifecycle.active_requests]},e.identity.id))}),(0,x.jsx)(Se,{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 _i({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=mi(s.trim())&&hi(l.trim());return(0,x.jsx)(Ee,{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)(Ce,{label:R(e,`models.library.repo`),value:s,onChange:c,testId:`models-repo`,error:s&&!mi(s.trim())?R(e,`models.library.repo_invalid`):void 0}),(0,x.jsx)(Ce,{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 vi({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 yi({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`),di(s.disk_bytes,r)],[R(r,`models.library.memory`),di(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)(Ae,{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:qn(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)(vi,{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||!oi(n,e),onClick:()=>a(`load`),children:R(r,`models.load`)}),(0,x.jsx)(N,{"data-testid":`models-use-chat`,disabled:i||!li(n,e),onClick:o,children:R(r,`models.library.chat`)}),(0,x.jsx)(N,{"data-testid":`models-unload`,disabled:i||!si(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||!ci(n,e),onClick:()=>a(`delete`),children:R(r,`models.library.delete`)}):null]}),li(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 bi({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(ni(e))-Number(ni(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:Si(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:`${di(s.progress.completed_bytes,t)} / ${di(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===xi(s)&&oi(e,t)),onClick:()=>o(xi(s)),children:R(t,`models.library.capacity`)}):null,s.kind===`download`&&!ni(s)?(0,x.jsx)(N,{disabled:n||!ri(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||!ii(e,`download`),onClick:()=>a(s),children:R(t,`models.library.retry_download`)}):null]})]})},s.operation_id))})]})}function xi(e){return e.target.target_kind===`model`?e.target.model_id:``}function Si(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 Ci=25;function wi({locale:e}){let t=Sn(),n=Cn(),[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}=cr(y?.identity.id??null),{profile:S}=cr(f?.kind===`capacity`?f.entry.identity.id:null),C=pi(t.catalog,r),w=Math.max(1,Math.ceil(C.length/Ci)),T=Math.min(a,w-1),E=[...t.operations.values()].some(e=>e.kind===`download`&&!ni(e))||[...t.pendingReconciliations.values()].some(e=>e.kind===`download`),D=[...t.operations.values()].some(e=>e.kind===`catalog_refresh`&&!ni(e))||[...t.pendingReconciliations.values()].some(e=>e.kind===`catalog-refresh`),O=e=>{i({...r,...e}),o(0)},k=async(n,r)=>{if(l.current||!ri(t))return!1;l.current=!0,c(!0),d(null);try{return await n(),!0}catch(t){return d(fi(t,e)),r?.(t),!1}finally{l.current=!1,c(!1)}},ee=(r,i,a=b)=>{if(!oi(t,r)){d(R(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(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 kt&&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||ni(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(!ui(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`&&si(t,o)?k(()=>n.unloadModel({action:`unload`,model_id:o.identity.id,expected_revision:o.identity.revision,idempotency_key:crypto.randomUUID()})):a.kind===`delete`&&ci(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`,"aria-label":R(e,`models.library.inspect`,{name:r.identity.display_name}),onClick:()=>n.selectModel(r.identity.id),children:r.identity.display_name}),r.identity.id===t.selectedModelId?(0,x.jsx)(`small`,{children:R(e,`models.library.selected`)}):null,(0,x.jsxs)(`p`,{children:[r.identity.source,` · `,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:qn(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.jsxs)(`section`,{className:`screen-heading`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:R(e,`routes.models.eyebrow`)}),(0,x.jsx)(`h1`,{tabIndex:-1,"data-dialog-focus-fallback":!0,"data-testid":z(`models.title`),children:R(e,`models.title`)}),(0,x.jsx)(`p`,{children:R(e,`models.library.subtitle`)})]}),ri(t)?null:(0,x.jsx)(B,{title:R(e,`models.library.stale`),body:t.error?.message??R(e,`models.library.waiting`),action:(0,x.jsx)(N,{onClick:()=>{n.refresh()},children:R(e,`models.library.refresh`)}),testId:`connection-error-title`}),u?(0,x.jsx)(B,{title:R(e,`models.library.error`),body:u,action:(0,x.jsx)(N,{onClick:()=>{d(null),n.refresh()},children:R(e,`models.library.refresh`)}),testId:`models-action-error`}):null,t.bootstrap?.server.mode===`single_model`?(0,x.jsx)(B,{tone:`info`,title:R(e,`models.library.single`),body:`mlxcel-server --webui`,testId:`models-read-only`}):null,(0,x.jsxs)(`div`,{className:`button-row`,children:[(0,x.jsx)(N,{tone:`primary`,onClick:()=>h({repo:``,revision:``}),disabled:s||E||!ii(t,`download`),"data-testid":`models-add`,children:R(e,`models.library.add`)}),(0,x.jsx)(N,{disabled:s||D||!ri(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`)})]}),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:Un(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)(Ce,{label:R(e,`models.library.search`),value:r.query,onChange:e=>O({query:e}),testId:`models-search`}),(0,x.jsx)(Se,{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)(Se,{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)(Se,{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:qn(e,t)}))]}),(0,x.jsx)(Se,{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)(he,{columns:M,rows:C.slice(T*Ci,(T+1)*Ci),getRowKey:e=>e.identity.id,ariaLabel:R(e,`models.title`),testId:`models-table`,rowClassName:e=>e.identity.id===t.selectedModelId?`models-selected`:void 0,loading:t.catalogSequence===null,loadingState:(0,x.jsx)(`p`,{role:`status`,children: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)(yi,{entry:y,profile:b,state:t,locale:e,busy:s,onAction:A,onChat:()=>{li(t,y)&&(n.selectModel(y.identity.id),window.location.hash=`chat`)}}):null]}),(0,x.jsx)(bi,{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&&oi(t,n)&&p({kind:`capacity`,entry:n,instance:t.serverInstanceId})}}),f?(0,x.jsx)(gi,{value:f,state:t,locale:e,busy:s,onClose:()=>p(null),onConfirm:te},f.kind):null,m?(0,x.jsx)(_i,{locale:e,state:t,initial:m,error:u,busy:s||E||!ii(t,`download`),onClose:()=>h(null),onDownload:(e,r)=>{ii(t,`download`)&&!E&&k(()=>n.downloadModel({repo_id:e,revision:r||null,idempotency_key:crypto.randomUUID()})).then(e=>{e&&h(null)})}}):null]})}var Ti={en:`en-US`,ko:`ko-KR`},Ei=e=>Ti[e];function Di(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)(ji,{locale:e.locale})},{id:`data`,label:R(e.locale,`gallery.tab.data`),panel:(0,x.jsx)(Mi,{locale:e.locale})}]}),(0,x.jsxs)(Ee,{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)(Ce,{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 Ai(e){return(0,x.jsxs)(`div`,{className:`gallery-grid`,children:[(0,x.jsxs)(`article`,{className:`surface-card`,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)(Ce,{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)(Se,{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)(`article`,{className:`surface-card`,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)(ke,{label: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 ji(e){return(0,x.jsxs)(`div`,{className:`gallery-grid`,children:[(0,x.jsx)(Ne,{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)(Pe,{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)(B,{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:Di(67108864,e.locale)})}),(0,x.jsx)(fe,{label:R(e.locale,`gallery.progress.measured`),value:37})]}),(0,x.jsxs)(Me,{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 Mi(e){return(0,x.jsxs)(`div`,{className:`gallery-grid dense-gallery`,children:[(0,x.jsxs)(`article`,{className:`surface-card table-card`,tabIndex:0,"aria-label":R(e.locale,`gallery.sample.caption`),children:[(0,x.jsx)(`h2`,{children:R(e.locale,`gallery.data.title`)}),(0,x.jsxs)(je,{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:Oi(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:Oi(null,e.locale)})]})]})]})]}),(0,x.jsxs)(Ae,{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`)})]})]})}var Ni={count:4,bytes:8388608,dimension:4096,pixels:16e6},Pi=new Set([`image/png`,`image/jpeg`,`image/webp`]);function Fi(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 Ii(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 Li(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 Ri(e,t,n){if(!e||!t||e>Math.min(Ni.dimension,n.max_width)||t>Math.min(Ni.dimension,n.max_height)||e*t>Ni.pixels||e*t*4>n.max_decoded_bytes)throw Error(`Image dimensions exceed the server or browser decode budget.`)}function zi(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(Li(t),e.length>t.max_images)throw Error(`Conversation images exceed the server image count limit.`);let n=0,r=Math.min(Ni.bytes,t.max_image_bytes);for(let i of e){if(!i||!Pi.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)||!Pi.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 Ii(e),[r,i]=Fi(t,e.type);if(Ri(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 Ui(e){if(e==null)return``;if(typeof e!=`string`)throw Error(`Malformed text delta.`);return e}function Wi(e){if(typeof e!=`number`||!Number.isSafeInteger(e)||e<0)throw Error(`Malformed usage.`);return e}function Gi(e,t,n){if(t.length>256e3)throw Error(`Chat frame exceeds the display limit.`);let r=Hi(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=Hi(r.usage);i={...i,usage:{prompt_tokens:Wi(e.prompt_tokens),completion_tokens:Wi(e.completion_tokens),total_tokens:Wi(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=Hi(e);if(t.index!==0)throw Error(`Unexpected chat choice index.`);let r=Hi(t.delta),a=Ui(r.content),o=Ui(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=Hi(e),n=Wi(t.index);if(n>=32)throw Error(`Tool index exceeds the display limit.`);let r=t.function===void 0?{}:Hi(t.function),i=s.find(e=>e.index===n)??{index:n,id:``,name:``,arguments:``},a={index:n,id:i.id+Ui(t.id),name:i.name+Ui(r.name),arguments:i.arguments+Ui(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=Ui(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 Ki(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 qi(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 Ji(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 Yi=Object.freeze({conversations:50,turnsPerConversation:200,totalTurns:1e3,textCharacters:262144,jsonBytes:16777216,imageBytes:8388608,imagesPerTurn:8,toolsPerTurn:128}),Xi=`mlxcel.webui.chat.v1`,Zi=`history`,Qi=`conversations`,$i=1,ea=new Set([`temperature`,`top_p`,`top_k`,`min_p`,`max_tokens`,`seed`,`repetition_penalty`,`presence_penalty`,`frequency_penalty`]),ta=class extends Error{constructor(e=`Conversation history is invalid or exceeds the local history limits.`){super(e),this.name=`HistoryValidationError`}},H=class extends Error{constructor(e,t){super(e,t),this.name=`HistoryStorageError`}};function U(){throw new ta}function na(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return U();let n=Object.getPrototypeOf(e);if(n!==Object.prototype&&n!==null)return U();let r=Object.keys(e);return r.length!==t.length||r.some(e=>!t.includes(e))?U():e}function W(e,t=Yi.textCharacters){return typeof e!=`string`||e.length>t?U():e}function ra(e){let t=W(e,512);return!t||Array.from(t).some(e=>e.charCodeAt(0)<32||e.charCodeAt(0)===127)?U():t}function ia(e,t=!1){return typeof e!=`number`||!Number.isFinite(e)||e<0||t&&!Number.isSafeInteger(e)?U():e}function aa(e,t){return e===null?null:t(e)}function oa(e,t){return!Array.isArray(e)||e.length>t?U():e}function sa(e){return new TextEncoder().encode(e).byteLength}function ca(e,t){let n=0,r=0,i=0,a=new Set;return oa(e,Yi.conversations).map(e=>{let o=na(e,[`id`,`title`,`systemPrompt`,`turns`,`updatedAt`]),s=ra(o.id);if(a.has(s))return U();a.add(s);let c=new Set,l=oa(o.turns,Yi.turnsPerConversation).map(e=>{if(++n>Yi.totalTurns)return U();let a=na(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 U();c.add(o);let s=W(a.status,32);if(![`streaming`,`complete`,`cancelled`,`interrupted`,`error`].includes(s))return U();let l={};if(!a.parameters||typeof a.parameters!=`object`||Array.isArray(a.parameters)||![Object.prototype,null].includes(Object.getPrototypeOf(a.parameters)))return U();for(let[e,t]of Object.entries(a.parameters)){if(!ea.has(e)||typeof t!=`number`||!Number.isFinite(t))return U();l[e]=t}let u=new Set,d=oa(a.tools,Yi.toolsPerTurn).map(e=>{let t=na(e,[`index`,`id`,`name`,`arguments`]),n=ia(t.index,!0);return u.has(n)?U():(u.add(n),{index:n,id:W(t.id,512),name:W(t.name,512),arguments:W(t.arguments)})}),f=oa(a.images,Yi.imagesPerTurn).map(e=>{let t=na(e,[`name`,`type`,`dataUrl`]),n=W(t.type,64);if(![`image/png`,`image/jpeg`,`image/webp`].includes(n))return U();let i=W(t.dataUrl,Yi.imageBytes*2),a=`data:${n};base64,`;if(!i.startsWith(a))return U();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>Yi.imageBytes)?U():{name:W(t.name,512),type:n,dataUrl:i}}),p={id:o,modelId:ra(a.modelId),modelRevision:ia(a.modelRevision,!0),inferenceId:ra(a.inferenceId),modelName:W(a.modelName,512),prompt:W(a.prompt),content:W(a.content),reasoning:W(a.reasoning),tools:d,status:s===`streaming`?`interrupted`:s,finishReason:aa(a.finishReason,W),usage:aa(a.usage,e=>{let t=na(e,[`prompt_tokens`,`completion_tokens`,`total_tokens`]);return{prompt_tokens:ia(t.prompt_tokens,!0),completion_tokens:ia(t.completion_tokens,!0),total_tokens:ia(t.total_tokens,!0)}}),ttftMs:aa(a.ttftMs,ia),elapsedMs:aa(a.elapsedMs,ia),error:aa(a.error,W),parameters:l,images:t.includeImages?f:[]};return p.status===`complete`&&(!p.finishReason||!p.content&&!p.reasoning&&!p.tools.length)||(i+=sa(JSON.stringify(p)),i>Yi.jsonBytes)?U():p});return{id:s,title:W(o.title,512),systemPrompt:W(o.systemPrompt),turns:l,updatedAt:ia(o.updatedAt,!0)}})}function la(e,t={}){let n=ca(e,t);return sa(JSON.stringify(n))>Yi.jsonBytes?U():n}function ua(e,t={}){let n=JSON.stringify({version:$i,conversations:la(e,t)});return sa(n)>Yi.jsonBytes?U():n}function da(e,t={}){if(sa(e)>Yi.jsonBytes)return U();let n;try{n=JSON.parse(e)}catch{return U()}let r=na(n,[`version`,`conversations`]);return r.version===$i?la(r.conversations,t):U()}function fa(e){return new H(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 pa(e={}){let t=!1,n=!1,r=0,i,a,o=new Set,s=()=>{let t=e.indexedDB??globalThis.indexedDB;if(!t)throw new H(`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(Xi,$i);o.onupgradeneeded=()=>{o.result.objectStoreNames.contains(Zi)||o.result.createObjectStore(Zi)},o.onerror=()=>a(fa(o.error));let l=!1;o.onblocked=()=>{l=!0,a(new H(`Close other WebUI tabs to access local history.`))},o.onsuccess=()=>{if(l||!t||e!==r){o.result.close(),a(new H(`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(Zi,e);o.add(r);let a=i(r.objectStore(Zi));r.oncomplete=()=>{o.delete(r),t(a.result)},r.onabort=r.onerror=()=>{o.delete(r),n(fa(r.error??a.error))}})}catch(e){throw e instanceof H?e:fa(e)}}return{setEnabled(e){t!==e&&(t=e,e||c())},async load(e={}){let t=await u(`readonly`,e=>e.get(Qi));return t===void 0?[]:da(W(t,Yi.jsonBytes),e)},async save(e,n={}){if(!t)return;let r=ua(e,n);await u(`readwrite`,e=>e.put(r,Qi))},async clear(){if(n)throw new H(`Local history is already being cleared.`);n=!0;let e=!1;c();try{await new Promise((t,r)=>{let i=s().deleteDatabase(Xi);i.onsuccess=()=>{n=!1,t()},i.onerror=()=>{n=!1,r(fa(i.error))},i.onblocked=()=>{e=!0,r(new H(`Close other WebUI tabs to clear local history.`))}})}catch(t){throw e||(n=!1),t instanceof H?t:fa(t)}},close:c}}var ma=[],ha=0,ga=new Set;function _a(){return ha}function va(e){return{id:crypto.randomUUID(),title:e,systemPrompt:``,turns:[],updatedAt:Date.now()}}var ya=new WeakMap;function ba(e){let t=ya.get(e);if(t!==void 0)return t;let n=new TextEncoder().encode(JSON.stringify(e)).byteLength;return ya.set(e,n),n}function xa(e){return e.length>Yi.conversations||e.reduce((e,t)=>e+t.turns.length,0)>Yi.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+ba(t),0)+Math.max(0,t.turns.length-1),0)<=Yi.jsonBytes}function Sa(e){ma=e;for(let e of ga)e()}function Ca(e){if(!xa(e))throw Error(`Conversation memory limit exceeded.`);ha++,Sa(e)}function wa(e){let t=ma.some(t=>t.id===e.id)?ma.map(t=>t.id===e.id?e:t):[...ma,e];return xa(t)?(Sa(t),!0):!1}function Ta(){return(0,_.useSyncExternalStore)(e=>(ga.add(e),()=>ga.delete(e)),()=>ma)}var Ea=(0,_.lazy)(()=>$r(()=>import(`./code-highlight-B7JRfpaI.js`),[],import.meta.url)),Da=65536,Oa=512;function ka(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)(Ea,{code:e,language:t})}):(0,x.jsx)(`code`,{children:e})})]})}),Ma=(0,_.memo)(function({text:e,streaming:t=!1}){let n=e.slice(0,Da).split(` +`&&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 Ii(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 Li(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 Ri(e,t,n){if(!e||!t||e>Math.min(Ni.dimension,n.max_width)||t>Math.min(Ni.dimension,n.max_height)||e*t>Ni.pixels||e*t*4>n.max_decoded_bytes)throw Error(`Image dimensions exceed the server or browser decode budget.`)}function zi(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(Li(t),e.length>t.max_images)throw Error(`Conversation images exceed the server image count limit.`);let n=0,r=Math.min(Ni.bytes,t.max_image_bytes);for(let i of e){if(!i||!Pi.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)||!Pi.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 Ii(e),[r,i]=Fi(t,e.type);if(Ri(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 Ui(e){if(e==null)return``;if(typeof e!=`string`)throw Error(`Malformed text delta.`);return e}function Wi(e){if(typeof e!=`number`||!Number.isSafeInteger(e)||e<0)throw Error(`Malformed usage.`);return e}function Gi(e,t,n){if(t.length>256e3)throw Error(`Chat frame exceeds the display limit.`);let r=Hi(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=Hi(r.usage);i={...i,usage:{prompt_tokens:Wi(e.prompt_tokens),completion_tokens:Wi(e.completion_tokens),total_tokens:Wi(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=Hi(e);if(t.index!==0)throw Error(`Unexpected chat choice index.`);let r=Hi(t.delta),a=Ui(r.content),o=Ui(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=Hi(e),n=Wi(t.index);if(n>=32)throw Error(`Tool index exceeds the display limit.`);let r=t.function===void 0?{}:Hi(t.function),i=s.find(e=>e.index===n)??{index:n,id:``,name:``,arguments:``},a={index:n,id:i.id+Ui(t.id),name:i.name+Ui(r.name),arguments:i.arguments+Ui(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=Ui(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 Ki(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 qi(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 Ji(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 Yi=Object.freeze({conversations:50,turnsPerConversation:200,totalTurns:1e3,textCharacters:262144,jsonBytes:16777216,imageBytes:8388608,imagesPerTurn:8,toolsPerTurn:128}),Xi=`mlxcel.webui.chat.v1`,Zi=`history`,Qi=`conversations`,$i=1,ea=new Set([`temperature`,`top_p`,`top_k`,`min_p`,`max_tokens`,`seed`,`repetition_penalty`,`presence_penalty`,`frequency_penalty`]),ta=class extends Error{constructor(e=`Conversation history is invalid or exceeds the local history limits.`){super(e),this.name=`HistoryValidationError`}},H=class extends Error{constructor(e,t){super(e,t),this.name=`HistoryStorageError`}};function U(){throw new ta}function na(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return U();let n=Object.getPrototypeOf(e);if(n!==Object.prototype&&n!==null)return U();let r=Object.keys(e);return r.length!==t.length||r.some(e=>!t.includes(e))?U():e}function W(e,t=Yi.textCharacters){return typeof e!=`string`||e.length>t?U():e}function ra(e){let t=W(e,512);return!t||Array.from(t).some(e=>e.charCodeAt(0)<32||e.charCodeAt(0)===127)?U():t}function ia(e,t=!1){return typeof e!=`number`||!Number.isFinite(e)||e<0||t&&!Number.isSafeInteger(e)?U():e}function aa(e,t){return e===null?null:t(e)}function oa(e,t){return!Array.isArray(e)||e.length>t?U():e}function sa(e){return new TextEncoder().encode(e).byteLength}function ca(e,t){let n=0,r=0,i=0,a=new Set;return oa(e,Yi.conversations).map(e=>{let o=na(e,[`id`,`title`,`systemPrompt`,`turns`,`updatedAt`]),s=ra(o.id);if(a.has(s))return U();a.add(s);let c=new Set,l=oa(o.turns,Yi.turnsPerConversation).map(e=>{if(++n>Yi.totalTurns)return U();let a=na(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 U();c.add(o);let s=W(a.status,32);if(![`streaming`,`complete`,`cancelled`,`interrupted`,`error`].includes(s))return U();let l={};if(!a.parameters||typeof a.parameters!=`object`||Array.isArray(a.parameters)||![Object.prototype,null].includes(Object.getPrototypeOf(a.parameters)))return U();for(let[e,t]of Object.entries(a.parameters)){if(!ea.has(e)||typeof t!=`number`||!Number.isFinite(t))return U();l[e]=t}let u=new Set,d=oa(a.tools,Yi.toolsPerTurn).map(e=>{let t=na(e,[`index`,`id`,`name`,`arguments`]),n=ia(t.index,!0);return u.has(n)?U():(u.add(n),{index:n,id:W(t.id,512),name:W(t.name,512),arguments:W(t.arguments)})}),f=oa(a.images,Yi.imagesPerTurn).map(e=>{let t=na(e,[`name`,`type`,`dataUrl`]),n=W(t.type,64);if(![`image/png`,`image/jpeg`,`image/webp`].includes(n))return U();let i=W(t.dataUrl,Yi.imageBytes*2),a=`data:${n};base64,`;if(!i.startsWith(a))return U();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>Yi.imageBytes)?U():{name:W(t.name,512),type:n,dataUrl:i}}),p={id:o,modelId:ra(a.modelId),modelRevision:ia(a.modelRevision,!0),inferenceId:ra(a.inferenceId),modelName:W(a.modelName,512),prompt:W(a.prompt),content:W(a.content),reasoning:W(a.reasoning),tools:d,status:s===`streaming`?`interrupted`:s,finishReason:aa(a.finishReason,W),usage:aa(a.usage,e=>{let t=na(e,[`prompt_tokens`,`completion_tokens`,`total_tokens`]);return{prompt_tokens:ia(t.prompt_tokens,!0),completion_tokens:ia(t.completion_tokens,!0),total_tokens:ia(t.total_tokens,!0)}}),ttftMs:aa(a.ttftMs,ia),elapsedMs:aa(a.elapsedMs,ia),error:aa(a.error,W),parameters:l,images:t.includeImages?f:[]};return p.status===`complete`&&(!p.finishReason||!p.content&&!p.reasoning&&!p.tools.length)||(i+=sa(JSON.stringify(p)),i>Yi.jsonBytes)?U():p});return{id:s,title:W(o.title,512),systemPrompt:W(o.systemPrompt),turns:l,updatedAt:ia(o.updatedAt,!0)}})}function la(e,t={}){let n=ca(e,t);return sa(JSON.stringify(n))>Yi.jsonBytes?U():n}function ua(e,t={}){let n=JSON.stringify({version:$i,conversations:la(e,t)});return sa(n)>Yi.jsonBytes?U():n}function da(e,t={}){if(sa(e)>Yi.jsonBytes)return U();let n;try{n=JSON.parse(e)}catch{return U()}let r=na(n,[`version`,`conversations`]);return r.version===$i?la(r.conversations,t):U()}function fa(e){return new H(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 pa(e={}){let t=!1,n=!1,r=0,i,a,o=new Set,s=()=>{let t=e.indexedDB??globalThis.indexedDB;if(!t)throw new H(`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(Xi,$i);o.onupgradeneeded=()=>{o.result.objectStoreNames.contains(Zi)||o.result.createObjectStore(Zi)},o.onerror=()=>a(fa(o.error));let l=!1;o.onblocked=()=>{l=!0,a(new H(`Close other WebUI tabs to access local history.`))},o.onsuccess=()=>{if(l||!t||e!==r){o.result.close(),a(new H(`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(Zi,e);o.add(r);let a=i(r.objectStore(Zi));r.oncomplete=()=>{o.delete(r),t(a.result)},r.onabort=r.onerror=()=>{o.delete(r),n(fa(r.error??a.error))}})}catch(e){throw e instanceof H?e:fa(e)}}return{setEnabled(e){t!==e&&(t=e,e||c())},async load(e={}){let t=await u(`readonly`,e=>e.get(Qi));return t===void 0?[]:da(W(t,Yi.jsonBytes),e)},async save(e,n={}){if(!t)return;let r=ua(e,n);await u(`readwrite`,e=>e.put(r,Qi))},async clear(){if(n)throw new H(`Local history is already being cleared.`);n=!0;let e=!1;c();try{await new Promise((t,r)=>{let i=s().deleteDatabase(Xi);i.onsuccess=()=>{n=!1,t()},i.onerror=()=>{n=!1,r(fa(i.error))},i.onblocked=()=>{e=!0,r(new H(`Close other WebUI tabs to clear local history.`))}})}catch(t){throw e||(n=!1),t instanceof H?t:fa(t)}},close:c}}var ma=[],ha=0,ga=new Set;function _a(){return ha}function va(e){return{id:crypto.randomUUID(),title:e,systemPrompt:``,turns:[],updatedAt:Date.now()}}var ya=new WeakMap;function ba(e){let t=ya.get(e);if(t!==void 0)return t;let n=new TextEncoder().encode(JSON.stringify(e)).byteLength;return ya.set(e,n),n}function xa(e){return e.length>Yi.conversations||e.reduce((e,t)=>e+t.turns.length,0)>Yi.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+ba(t),0)+Math.max(0,t.turns.length-1),0)<=Yi.jsonBytes}function Sa(e){ma=e;for(let e of ga)e()}function Ca(e){if(!xa(e))throw Error(`Conversation memory limit exceeded.`);ha++,Sa(e)}function wa(e){let t=ma.some(t=>t.id===e.id)?ma.map(t=>t.id===e.id?e:t):[...ma,e];return xa(t)?(Sa(t),!0):!1}function Ta(){return(0,_.useSyncExternalStore)(e=>(ga.add(e),()=>ga.delete(e)),()=>ma)}var Ea=(0,_.lazy)(()=>$r(()=>import(`./code-highlight-CLL7D9Tw.js`),[],import.meta.url)),Da=65536,Oa=512;function ka(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)(Ea,{code:e,language:t})}):(0,x.jsx)(`code`,{children:e})})]})}),Ma=(0,_.memo)(function({text:e,streaming:t=!1}){let n=e.slice(0,Da).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)(ja,{code:o.join(` `),language:s[2].slice(0,40),complete:c||!t&&e.length<=Da},a))}else if(/^#{1,6} /.test(o))r.push((0,x.jsx)(`p`,{className:`chat-markdown-heading`,children:(0,x.jsx)(`strong`,{children:ka(o.replace(/^#{1,6} /,``))})},a));else if(/^[-*] /.test(o)){let e=[o.slice(2)];for(;i(0,x.jsx)(`li`,{children:ka(e)},t))},a))}else o.trim()&&r.push((0,x.jsx)(`p`,{children:ka(o)},a))}return(0,x.jsxs)(`div`,{className:`chat-markdown`,children:[r,(e.length>Da||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)(Ma,{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 Fa({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)(Pa,{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 Ia({conversations:e,busy:t,onPending:n,limits:r,onReplace:i,locale:a}){let o=(0,_.useRef)(pa()),[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 La(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)(De,{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([ua(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=da(e,{includeImages:p});await La(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)(B,{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 La(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 Bi(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 Ra(e,t){let n=Object.fromEntries(Object.entries(t).filter(([,e])=>e!==void 0&&e.trim()!==``).map(([e,t])=>[e,Number(t)]));return{...En({...e,...n})}}function za({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:Tn.map(i=>(0,x.jsx)(Ce,{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 Ba=new Set([`en`,`ko`].map(e=>R(e,`chat.conversation.default_title`)));function Va({locale:e}){let t=Sn(),n=Cn(),{defaults:r}=Mn(),[i,a]=(0,_.useState)({}),o=Ta(),[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=va(O(`chat.conversation.default_title`));wa(e),c(e.id),u(``),f([])},oe=()=>{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`))})},se=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=Ra(r,i)}catch(e){m(e instanceof Error?e.message:O(`chat.error.invalid_parameters`));return}let s=j??va(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&&Ba.has(s.title)?l.slice(0,80):s.title,turns:[...s.turns,_],updatedAt:Date.now()};try{if(!t.bootstrap)throw Error(`Limits unavailable`);zi(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:qi(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(!wa(s)){m(O(`chat.error.memory_budget`));return}let S=null,w=_a(),T={controller:p,turn:_,conversation:s,flush:()=>{if(S!==null&&clearTimeout(S),S=null,_a()!==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()},wa(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)},wa(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=Gi(T.turn,e.data,performance.now()-h),S===null&&(S=setTimeout(T.flush,50)))}},p.signal),p.signal.aborted||(T.turn=Ki(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)}},ce=()=>{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),wa({...j,turns:j.turns.slice(0,t)}),window.setTimeout(()=>k.current?.focus(),0)},[le,P=``]=R(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:R(e,`chat.eyebrow`)}),(0,x.jsx)(`h1`,{tabIndex:-1,"data-dialog-focus-fallback":!0,"data-testid":z(`chat.title`),children:R(e,`chat.title`)}),(0,x.jsx)(`p`,{children:R(e,`chat.intro`)})]}),(0,x.jsxs)(`div`,{className:`chat-toolbar`,children:[(0,x.jsx)(N,{onClick:ae,disabled:v||b||C||o.length>=50,children:R(e,`chat.new_conversation`)}),(0,x.jsx)(Se,{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)(Se,{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} · ${qn(e,t.lifecycle.state)}`}))]})]}),re?null:(0,x.jsx)(B,{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)(Ce,{label:R(e,`chat.settings.name`),value:j.title,disabled:v||b||C,onChange:e=>wa({...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:Vi,disabled:v||b||C,onChange:e=>wa({...j,systemPrompt:e.target.value})})]}),(0,x.jsxs)(`p`,{children:[le,(0,x.jsx)(`a`,{href:`#settings`,children:R(e,`nav.settings`)}),P]}),(0,x.jsx)(N,{disabled:v||b||C,onClick:()=>{Ca(o.filter(e=>e.id!==j.id)),c(null)},children:R(e,`chat.settings.delete`)})]}):null,(0,x.jsx)(za,{defaults:r,draft:i,onChange:a,locale:e}),(0,x.jsx)(Fa,{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)(De,{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:ce,onClose:()=>E(null)}),p?(0,x.jsx)(B,{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:Vi,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(),se())}})]}),(0,x.jsx)(`p`,{children:R(e,`chat.composer.hint`,{count:String(l.length),max:String(Vi)})}),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),Bi(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:()=>{se()},children:R(e,`common.send`)}),(0,x.jsx)(N,{disabled:!v,onClick:oe,children:R(e,`chat.stop`)})]})]}),(0,x.jsx)(`p`,{role:`status`,"aria-live":`polite`,"aria-atomic":`true`,children:h}),(0,x.jsx)(Ia,{conversations:o,busy:v||C,onPending:S,limits:t.bootstrap?.media_limits,onReplace:e=>{Ca(e),c(null)},locale:e})]})}var Ha=[`models`,`chat`,`activity`,`settings`,`gallery`],Ua=[`models`,`chat`,`activity`,`settings`];function Wa(){let e=window.location.hash.slice(1).replace(/^\//,``);return Ha.includes(e)?e:`models`}function Ga(){let e=Sn(),t=Cn(),[n,r]=(0,_.useState)(Wa),[i,a]=(0,_.useState)(Lr),[o,s]=(0,_.useState)(null),[c,l]=(0,_.useState)(null),u=(0,_.useRef)(0);(0,_.useEffect)(()=>()=>{u.current+=1},[]),(0,_.useEffect)(()=>{let e=()=>r(Wa());return window.addEventListener(`hashchange`,e),()=>window.removeEventListener(`hashchange`,e)},[]),(0,_.useEffect)(()=>{if(Br(document.documentElement,i),Rr(i),i.colorScheme===`system`)return Dr(e=>Br(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`&&Ca([])},[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(Fn(e)))})},p=()=>{u.current+=1,l(null),t.logout()},m=Ka(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)(pr,{locale:i.locale,route:n,onRouteChange:d,onCommand:()=>s(`command`),onHelp:()=>s(`help`),selectedModel:In(i.locale,e),connectionLabel:Ln(i.locale,e),connectionState:e.connection,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:m}),(0,x.jsx)(Qa,{open:o===`command`,locale:i.locale,onClose:()=>s(null),onNavigate:e=>{d(e),s(null)}}),(0,x.jsxs)(Ee,{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.jsxs)(`ul`,{className:`shortcut-list`,children:[(0,x.jsxs)(`li`,{children:[(0,x.jsx)(`kbd`,{children:`⌘/Ctrl`}),` + `,(0,x.jsx)(`kbd`,{children:`K`}),` `,R(i.locale,`command.search`)]}),(0,x.jsxs)(`li`,{children:[(0,x.jsx)(`kbd`,{children:`Esc`}),` `,R(i.locale,`common.cancel`)]}),(0,x.jsxs)(`li`,{children:[(0,x.jsx)(`kbd`,{children:`[`}),` / `,(0,x.jsx)(`kbd`,{children:`]`}),` `,R(i.locale,`nav.models`)]})]})]})]})}function Ka(e,t,n,r){return e===`models`?(0,x.jsx)(qa,{locale:t.locale,context:r}):e===`chat`?(0,x.jsx)(Ja,{locale:t.locale,context:r}):e===`activity`?(0,x.jsx)(Ya,{locale:t.locale,context:r}):e===`settings`?(0,x.jsx)(Xa,{appearance:t,setAppearance:n}):(0,x.jsx)(ki,{locale:t.locale})}function qa(e){return e.context.snapshot.auth.status===`authenticated`&&e.context.snapshot.connection!==`schema-mismatch`?(0,x.jsx)(wi,{locale:e.locale}):(0,x.jsx)(zn,{locale:e.locale,eyebrow:R(e.locale,`routes.models.eyebrow`),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 Ja(e){return e.context.snapshot.auth.status===`authenticated`&&e.context.snapshot.connection!==`schema-mismatch`?(0,x.jsx)(Va,{locale:e.locale}):(0,x.jsx)(zn,{locale:e.locale,eyebrow:R(e.locale,`routes.chat.eyebrow`),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 Ya(e){return e.context.snapshot.auth.status===`authenticated`&&![`schema-mismatch`,`forbidden`,`unauthorized`].includes(e.context.snapshot.connection)?(0,x.jsx)(ti,{locale:e.locale}):(0,x.jsx)(zn,{locale:e.locale,eyebrow:R(e.locale,`routes.activity.eyebrow`),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 Xa(e){let t=t=>e.setAppearance({...e.appearance,...t});return(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsxs)(`section`,{className:`screen-heading`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:R(e.appearance.locale,`routes.settings.eyebrow`)}),(0,x.jsx)(`h1`,{tabIndex:-1,"data-dialog-focus-fallback":!0,"data-testid":z(`settings.title`),children:R(e.appearance.locale,`settings.title`)}),(0,x.jsx)(`p`,{"data-testid":z(`settings.appearance`),children:R(e.appearance.locale,`settings.browser_only`)})]}),(0,x.jsxs)(`div`,{className:`settings-grid`,children:[(0,x.jsx)(Se,{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)(Se,{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)(Se,{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)(Se,{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)(Se,{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)(Za,{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)(Za,{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)(B,{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)(dr,{locale:e.appearance.locale})]})}function Za(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 Qa(e){let[t,n]=(0,_.useState)(``),r=(e.locale&&window.location.hash.includes(`gallery`)?Ha:Ua).filter(e=>e.includes(t.toLowerCase()));return(0,x.jsxs)(Ee,{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)(Ce,{label:R(e.locale,`command.search`),value:t,onChange:n,testId:z(`command.search`)}),r.length===0?(0,x.jsx)(`p`,{"data-testid":z(`command.no_results`),children:R(e.locale,`command.no_results`)}):(0,x.jsx)(`div`,{className:`command-list`,children:r.map(t=>(0,x.jsx)(N,{onClick:()=>e.onNavigate(t),children:R(e.locale,t===`models`?`nav.models`:t===`chat`?`nav.chat`:t===`activity`?`nav.activity`:t===`settings`?`nav.settings`:`nav.gallery`)},t))})]})}var $a=document.getElementById(`root`);if($a===null)throw Error(`Missing #root element for mlxcel WebUI.`);(0,v.createRoot)($a).render((0,x.jsx)(_.StrictMode,{children:(0,x.jsx)(xn,{children:(0,x.jsx)(Ga,{})})}));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-jceAf1an.css b/src/webui/assets/assets/index-tKjNOHbY.css similarity index 73% rename from src/webui/assets/assets/index-jceAf1an.css rename to src/webui/assets/assets/index-tKjNOHbY.css index 754e42231..ec9a17fe5 100644 --- a/src/webui/assets/assets/index-jceAf1an.css +++ b/src/webui/assets/assets/index-tKjNOHbY.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;--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;--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]{--material-control-backdrop:blur(calc(var(--material-glass-blur) / 2)) saturate(var(--material-glass-saturation));--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-button-shadow);--token-buttonDangerShadowHover:var(--glass-button-shadow);--token-buttonPrimaryBorder:1px solid var(--glass-edge);--token-buttonPrimaryShadow:var(--glass-button-shadow);--token-buttonPrimaryShadowHover:var(--glass-button-shadow);--token-buttonSecondaryBackdrop:var(--material-control-backdrop);--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);--material-control-backdrop:none;--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);--material-control-backdrop:none;--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);--material-control-backdrop:none;--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}}.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)}.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}.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,.ds-icon-button:hover{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:#245bd8;border-color:#245bd8}.ds-button-danger{color:#fff;background:#c6352b;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-sheet[data-position=left]{width:min(320px,100vw - 32px);min-height:calc(100vh - 24px);margin:12px auto 12px 12px}.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)}.ds-common-table{color:var(--color-text);background:var(--material-content-bg);border-radius:var(--radius-lg)}@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;--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;--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]{--material-control-backdrop:blur(calc(var(--material-glass-blur) / 2)) saturate(var(--material-glass-saturation));--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-button-shadow);--token-buttonDangerShadowHover:var(--glass-button-shadow);--token-buttonPrimaryBorder:1px solid var(--glass-edge);--token-buttonPrimaryShadow:var(--glass-button-shadow);--token-buttonPrimaryShadowHover:var(--glass-button-shadow);--token-buttonSecondaryBackdrop:var(--material-control-backdrop);--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);--material-control-backdrop:none;--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);--material-control-backdrop:none;--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);--material-control-backdrop:none;--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}}.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)}.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}.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,.ds-icon-button:hover{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-sheet[data-position=left]{width:min(320px,100vw - 32px);min-height:calc(100vh - 24px);margin:12px auto 12px 12px}.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)}.ds-common-table{color:var(--color-text);background:var(--material-content-bg);border-radius:var(--radius-lg)}@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} diff --git a/src/webui/assets/index.html b/src/webui/assets/index.html index 74d47d0dd..13d53a736 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 148442008..b7e846f10 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": 709847, + "embedded_asset_bytes": 709888, "embedded_asset_limit_bytes": 5242880, - "initial_js_gzip_bytes": 153101, + "initial_js_gzip_bytes": 153102, "initial_js_gzip_limit_bytes": 204800, - "total_js_gzip_bytes": 154278, + "total_js_gzip_bytes": 154282, "total_js_gzip_limit_bytes": 716800 }, "files": [ { "bytes": 951, - "gzip_bytes": 613, - "path": "assets/code-highlight-B7JRfpaI.js", - "sha256": "2bd5cc50017fba75d668f64f46b301623cf9ee326f7900aa3b5563e7313698ec" + "gzip_bytes": 614, + "path": "assets/code-highlight-CLL7D9Tw.js", + "sha256": "2ae6bc70e5a4a093bba721b7c3c7f0447844cc5a0d7ee9b9ff7bd0f57ec1c4e6" }, { "bytes": 1134, - "gzip_bytes": 564, - "path": "assets/history-DIlBLmUk.js", - "sha256": "effb9ea9109ad0a30ebe6d6d59259d697bf212813cbbee1600df260fdb237393" + "gzip_bytes": 566, + "path": "assets/history-U2uX7mu1.js", + "sha256": "5b14d4a37e1d8fb81b2bee33dfe3a299d1d5d9c370ed246bd0d5406d30ed57d7" }, { "bytes": 592551, - "gzip_bytes": 152112, - "path": "assets/index-C5rxJd1U.js", - "sha256": "b37d59059bf5ee3ad19a9c6bd81cfe6897312d2d337b68198ac8d4814e401bb2" + "gzip_bytes": 152113, + "path": "assets/index-C7P01FJ4.js", + "sha256": "2931ce946f7f2eb7aaf6e0f7c50b802e0b292c1b340b5bf9c99356910660c1e9" }, { - "bytes": 97074, - "gzip_bytes": 15758, - "path": "assets/index-jceAf1an.css", - "sha256": "c837f22d8238d1eea1ac7d8af56c1e59ece112f22c977f702d0fecf35f2ffbad" + "bytes": 97115, + "gzip_bytes": 15756, + "path": "assets/index-tKjNOHbY.css", + "sha256": "049fa2425fea78bc5a6ea2658eab4df0a920c47330ef276b8e912c1d01fc61ce" }, { "bytes": 503, - "gzip_bytes": 301, + "gzip_bytes": 306, "path": "index.html", - "sha256": "d4483ba260e75a30c9a1f6cf9f1869453262884d9edf39bdcfc42f2ac1c5c844" + "sha256": "72f2c9908b2d7d91e2ba83e94dc3f0a1e653f410a3e1154fafd97c32e8975adf" }, { "bytes": 2129, @@ -73,5 +73,5 @@ }, "pnpm_version": "11.18.0", "schema_version": 1, - "source_digest_sha256": "9ea251b8fceace39c70542e3d6f2277b28e4690a7889da58a6ca4636d54c7550" + "source_digest_sha256": "a12bb0c143f213969240b4f6b24a5862fcef36b75fcb4240f090809ef1fb3e3e" } diff --git a/webui/src/design-system/components.css b/webui/src/design-system/components.css index e58032ec2..4bdb36a51 100644 --- a/webui/src/design-system/components.css +++ b/webui/src/design-system/components.css @@ -10,8 +10,8 @@ .ds-button:active, .ds-icon-button:active { transform: scale(0.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 { outline: none; box-shadow: var(--focus-ring); } .ds-button:disabled, .ds-icon-button:disabled, .ds-field[data-disabled="true"] { opacity: 0.56; cursor: not-allowed; } -.ds-button-primary { color: white; background: #245bd8; border-color: #245bd8; } -.ds-button-danger { color: white; background: #c6352b; border-color: #c6352b; } +.ds-button-primary { color: white; background: var(--token-buttonPrimaryBg); border-color: #245bd8; } +.ds-button-danger { color: white; background: var(--token-buttonDangerBg); border-color: #c6352b; } .ds-button-ghost { background: transparent; } .ds-spinner { width: 14px; height: 14px; border-radius: 50%; border: 2px solid currentColor; border-right-color: transparent; animation: spin var(--motion-slow) linear infinite; } .ds-field { display: grid; gap: var(--space-2); color: var(--color-muted); } diff --git a/webui/tests/theme.spec.ts b/webui/tests/theme.spec.ts index 5e963f27a..35657d3f3 100644 --- a/webui/tests/theme.spec.ts +++ b/webui/tests/theme.spec.ts @@ -71,6 +71,11 @@ async function resolvedColors(page: Page, names: string[]): Promise { + return page.locator(selector).first().evaluate((element) => ({ color: getComputedStyle(element).backgroundColor, image: getComputedStyle(element).backgroundImage })); +} + function milliseconds(value: string): number { return value.endsWith('ms') ? Number.parseFloat(value) : Number.parseFloat(value) * 1000; } @@ -154,6 +159,20 @@ test.describe('theme system', () => { ] as const) { await bootFresh(page, `baseline-${scheme}`, { colorScheme: scheme, material: 'glass', locale: 'en', glassIntensity: 35, highContrast: 'off' }); expect(await resolvedColors(page, Object.keys(expected))).toEqual(expected); + expect(await buttonFill(page, '.ds-button-primary')).toEqual({ color: 'rgb(36, 91, 216)', image: 'none' }); + expect(await buttonFill(page, '.ds-button-danger')).toEqual({ color: 'rgb(198, 53, 43)', image: 'none' }); + } + }); + + test('glass paints its highlighted fill on the rendered filled buttons', async ({ page }) => { + for (const [colorScheme, primary] of [['light', 'rgb(0, 88, 185)'], ['dark', 'rgb(10, 91, 192)']] as const) { + await bootFresh(page, `glass-fill-${colorScheme}`, { themeFamily: 'glass', colorScheme, material: 'glass', locale: 'en', glassIntensity: 35, highContrast: 'off' }); + const primaryFill = await buttonFill(page, '.ds-button-primary'); + const dangerFill = await buttonFill(page, '.ds-button-danger'); + expect(primaryFill.image).toContain('linear-gradient'); + expect(primaryFill.color).toBe(primary); + expect(dangerFill.image).toContain('linear-gradient'); + expect(dangerFill.color).toBe('rgb(179, 38, 30)'); } }); @@ -190,6 +209,7 @@ test.describe('theme system', () => { const values = await rootValues(page, ['--material-control-backdrop', '--token-buttonPrimaryBg', '--material-content-bg', '--color-bg-elevated']); expect(values['--material-control-backdrop']).toBe('none'); expect(values['--token-buttonPrimaryBg']).not.toContain('gradient'); + expect((await buttonFill(page, '.ds-button-primary')).image).toBe('none'); expect(values['--material-content-bg']).toBe(values['--color-bg-elevated']); await expectAxeClean(page); }); From 2ded38b35c4917fe559dee0173174061c6fa4c57 Mon Sep 17 00:00:00 2001 From: Jeongkyu Shin Date: Sat, 19 Sep 2026 14:11:54 +0900 Subject: [PATCH 3/6] fix(webui): tighten the theme bootstrap checks and glass danger shadow The classic-script checks in build_bundle.py and theme-bootstrap.test.ts used `\b(type="module"|async|defer)\b`, whose trailing word boundary after a quote never matches, so a `type="module"` bootstrap passed, and the ordering check then found the bootstrap's own module attribute. Both now reject any type, async or defer attribute and locate the app module by its src. Feeding build_bundle.py a module, deferred, late, missing or inline variant of index.html rejects each. The bootstrap parity cases now cover every family and scheme theme.ts ships, so a family added there but not to theme-bootstrap.js fails the unit gate (checked by adding one). The glass danger button gets its own red-tinted shadow instead of the primary blue, and glass.css cites the upstream files by URL. Refs #1903 --- scripts/webui/build_bundle.py | 5 ++- ...CLL7D9Tw.js => code-highlight-CPbBnAiM.js} | 2 +- ...istory-U2uX7mu1.js => history-D3yl7FGt.js} | 2 +- src/webui/assets/assets/index-BhcZpYw7.css | 1 + .../{index-C7P01FJ4.js => index-D8jBk5_a.js} | 4 +- src/webui/assets/assets/index-tKjNOHbY.css | 1 - src/webui/assets/index.html | 4 +- src/webui/assets/mlxcel-webui-manifest.json | 40 +++++++++---------- .../src/design-system/theme-bootstrap.test.ts | 17 +++++--- webui/src/design-system/themes/glass.css | 13 +++--- 10 files changed, 50 insertions(+), 39 deletions(-) rename src/webui/assets/assets/{code-highlight-CLL7D9Tw.js => code-highlight-CPbBnAiM.js} (93%) rename src/webui/assets/assets/{history-U2uX7mu1.js => history-D3yl7FGt.js} (94%) create mode 100644 src/webui/assets/assets/index-BhcZpYw7.css rename src/webui/assets/assets/{index-C7P01FJ4.js => index-D8jBk5_a.js} (99%) delete mode 100644 src/webui/assets/assets/index-tKjNOHbY.css diff --git a/scripts/webui/build_bundle.py b/scripts/webui/build_bundle.py index e00049d7e..5a371a158 100755 --- a/scripts/webui/build_bundle.py +++ b/scripts/webui/build_bundle.py @@ -229,9 +229,10 @@ def assert_index_html(root: Path) -> None: # Issue #1903: the theme is applied before first paint by a classic, # render-blocking script that runs ahead of the app module. bootstrap = re.search(r']*\bsrc="\./theme-bootstrap\.js"[^>]*>', html) - if bootstrap is None or re.search(r'\b(type="module"|async|defer)\b', bootstrap.group(0)): + if bootstrap is None or re.search(r'\btype=|\basync\b|\bdefer\b', bootstrap.group(0)): raise SystemExit("index.html must load ./theme-bootstrap.js as a classic, blocking script") - if bootstrap.start() > html.index('type="module"'): + app_module = re.search(r']*\bsrc="\./assets/[^"]+\.js"[^>]*>', html) + if app_module is None or bootstrap.start() > app_module.start(): raise SystemExit("index.html must run ./theme-bootstrap.js before the app module") for token in html.replace('>', '>\n').splitlines(): for attr in ('src="./', 'href="./'): diff --git a/src/webui/assets/assets/code-highlight-CLL7D9Tw.js b/src/webui/assets/assets/code-highlight-CPbBnAiM.js similarity index 93% rename from src/webui/assets/assets/code-highlight-CLL7D9Tw.js rename to src/webui/assets/assets/code-highlight-CPbBnAiM.js index 1925dc1f2..4abcb0b76 100644 --- a/src/webui/assets/assets/code-highlight-CLL7D9Tw.js +++ b/src/webui/assets/assets/code-highlight-CPbBnAiM.js @@ -1 +1 @@ -import{i as e,n as t,r as n}from"./index-C7P01FJ4.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-D8jBk5_a.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-U2uX7mu1.js b/src/webui/assets/assets/history-D3yl7FGt.js similarity index 94% rename from src/webui/assets/assets/history-U2uX7mu1.js rename to src/webui/assets/assets/history-D3yl7FGt.js index c53ef18fb..f64578194 100644 --- a/src/webui/assets/assets/history-U2uX7mu1.js +++ b/src/webui/assets/assets/history-D3yl7FGt.js @@ -1 +1 @@ -import{n as e,r as t,t as n}from"./index-C7P01FJ4.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-D8jBk5_a.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-BhcZpYw7.css b/src/webui/assets/assets/index-BhcZpYw7.css new file mode 100644 index 000000000..a0b9ee4c4 --- /dev/null +++ b/src/webui/assets/assets/index-BhcZpYw7.css @@ -0,0 +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]{--material-control-backdrop:blur(calc(var(--material-glass-blur) / 2)) saturate(var(--material-glass-saturation));--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-buttonSecondaryBackdrop:var(--material-control-backdrop);--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);--material-control-backdrop:none;--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);--material-control-backdrop:none;--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);--material-control-backdrop:none;--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}}.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)}.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}.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,.ds-icon-button:hover{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-sheet[data-position=left]{width:min(320px,100vw - 32px);min-height:calc(100vh - 24px);margin:12px auto 12px 12px}.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)}.ds-common-table{color:var(--color-text);background:var(--material-content-bg);border-radius:var(--radius-lg)}@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} diff --git a/src/webui/assets/assets/index-C7P01FJ4.js b/src/webui/assets/assets/index-D8jBk5_a.js similarity index 99% rename from src/webui/assets/assets/index-C7P01FJ4.js rename to src/webui/assets/assets/index-D8jBk5_a.js index 05e2c2a30..88bbf37a4 100644 --- a/src/webui/assets/assets/index-C7P01FJ4.js +++ b/src/webui/assets/assets/index-D8jBk5_a.js @@ -3733,8 +3733,8 @@ Error generating stack: `+e.message+` } } } -`,$e=class extends Error{path;constructor(e,t){super(`${e}: ${t}`),this.path=e,this.name=`ValidationError`}},et=rt(Qe);function tt(e,t,n=`$`){let r=ht(et,[`components`,`schemas`],`#/components/schemas`)[e];if(r===void 0)throw new $e(n,`unknown schema ${e}`);it(r,t,n)}function nt(e){return JSON.parse(e)}function rt(e){return mt(nt(e),`$contract`)}function it(e,t,n){let r=mt(e,`${n}#schema`);if(typeof r.$ref==`string`){it(ft(r.$ref),t,n);return}if(r.anyOf!==void 0){if(!Array.isArray(r.anyOf)||!r.anyOf.some(e=>pt(e,t,n)))throw new $e(n,`did not match any allowed schema`);return}if(r.oneOf!==void 0){if(!Array.isArray(r.oneOf))throw new $e(n,`schema oneOf must be an array`);let e=r.oneOf.filter(e=>pt(e,t,n)).length;if(e!==1)throw new $e(n,`matched ${e} oneOf schemas`);return}if(r.const!==void 0&&t!==r.const)throw new $e(n,`expected constant ${String(r.const)}`);if(Array.isArray(r.enum)&&!r.enum.some(e=>e===t))throw new $e(n,`unexpected enum value ${String(t)}`);let i=r.type;if(Array.isArray(i)){if(!i.some(e=>dt(e,t)))throw new $e(n,`expected one of ${i.join(`, `)}`)}else if(typeof i==`string`&&!dt(i,t))throw new $e(n,`expected ${i}`);typeof t==`string`&&ct(r,t,n),typeof t==`number`&&ut(r,t,n),Array.isArray(t)&&ot(r,t,n),gt(t)&&at(r,t,n)}function at(e,t,n){let r=_t(e.required,`${n}#schema.required`,!1),i=e.properties===void 0?{}:mt(e.properties,`${n}#schema.properties`);for(let e of r)if(!(e in t))throw new $e(`${n}.${e}`,`missing required property`);if(e.maxProperties!==void 0&&Object.keys(t).length>vt(e.maxProperties,`${n}#schema.maxProperties`))throw new $e(n,`too many object properties`);for(let[r,a]of Object.entries(t)){let t=i[r];if(t!==void 0)it(t,a,`${n}.${r}`);else if(e.additionalProperties===!1)throw new $e(`${n}.${r}`,`unexpected property`);else gt(e.additionalProperties)&&it(e.additionalProperties,a,`${n}.${r}`)}}function ot(e,t,n){if(e.minItems!==void 0&&t.lengthvt(e.maxItems,`${n}#schema.maxItems`))throw new $e(n,`array longer than maximum`);e.items!==void 0&&t.forEach((t,r)=>it(e.items,t,`${n}[${r}]`))}function st(e){let t=0;for(let n=0;n65535?2:1;return t}function ct(e,t,n){let r=st(t);if(e.minLength!==void 0&&rvt(e.maxLength,`${n}#schema.maxLength`))throw new $e(n,`string longer than maximum`);if(typeof e.pattern==`string`&&!new RegExp(e.pattern,`u`).test(t))throw new $e(n,`string does not match pattern`);if(e.format===`date-time`&&!lt(t))throw new $e(n,`invalid RFC3339 date-time`)}function lt(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 ut(e,t,n){if(!Number.isFinite(t))throw new $e(n,`expected finite number`);if(e.type===`integer`&&!Number.isInteger(t))throw new $e(n,`expected integer`);if(e.minimum!==void 0&&tvt(e.maximum,`${n}#schema.maximum`))throw new $e(n,`number above maximum`)}function dt(e,t){return e===`null`?t===null:e===`array`?Array.isArray(t):e===`object`?gt(t):e===`integer`?typeof t==`number`&&Number.isInteger(t):e===`number`?typeof t==`number`&&Number.isFinite(t):typeof t===e}function ft(e){if(!e.startsWith(`#/`))throw new $e(`$ref`,`unsupported external ref ${e}`);return e.slice(2).split(`/`).map(e=>e.replace(/~1/g,`/`).replace(/~0/g,`~`)).reduce((t,n)=>mt(t,e)[n],et)}function pt(e,t,n){try{return it(e,t,n),!0}catch(e){if(e instanceof $e)return!1;throw e}}function mt(e,t){if(!gt(e))throw new $e(t,`expected object`);return e}function ht(e,t,n){return t.reduce((e,t)=>mt(e,n)[t],e)}function gt(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function _t(e,t,n){if(e===void 0&&!n)return[];if(!Array.isArray(e)||!e.every(e=>typeof e==`string`))throw new $e(t,`expected string array`);return e}function vt(e,t){if(typeof e!=`number`||!Number.isFinite(e))throw new $e(t,`expected numeric schema bound`);return e}function yt(e,t,n){return tt(e,t,n),t}function bt(e,t=`$`){return yt(`ErrorEnvelope`,e,t)}function xt(e,t=`$`){return yt(`BootstrapResponse`,e,t)}function St(e,t=`$`){return yt(`CatalogEntry`,e,t)}function Ct(e,t=`$`){return yt(`CatalogListResponse`,e,t)}function wt(e,t=`$`){return yt(`OperationsListResponse`,e,t)}function Tt(e,t=`$`){return yt(`Operation`,e,t)}function Et(e,t=`$`){return yt(`OperationAccepted`,e,t)}function Dt(e,t=`$`){return yt(`RuntimeSnapshot`,e,t)}function Ot(e,t=`$`){return yt(`UiEvent`,e,t)}var kt=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`}},At=2097152,jt=class{apiBase;fetchImpl;bearerToken=null;onUnauthorized;controllers=new Set;constructor(e={}){this.apiBase=qe(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`,xt,{method:`GET`,signal:e})}async catalog(e={},t){return this.request(`/ui-api/v1/catalog`,Ct,{method:`GET`,query:{...e},signal:t})}async catalogEntry(e,t){return this.request(`/ui-api/v1/catalog/${Ze(e)}`,St,{method:`GET`,signal:t})}async refreshCatalog(e,t){return this.request(`/ui-api/v1/catalog/refresh`,Et,{method:`POST`,body:{idempotency_key:e},signal:t})}async modelAction(e,t){return this.request(`/ui-api/v1/model-actions`,Et,{method:`POST`,body:e,signal:t})}async download(e,t){return this.request(`/ui-api/v1/downloads`,Et,{method:`POST`,body:e,signal:t})}async removeModel(e,t){return this.request(`/ui-api/v1/model-removals`,Et,{method:`POST`,body:e,signal:t})}async operationsPage(e={},t){return this.request(`/ui-api/v1/operations`,wt,{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/${Ze(e)}`,Tt,{method:`GET`,signal:t})}async cancelOperation(e,t){return this.request(`/ui-api/v1/operations/${Ze(e)}/cancel`,Et,{method:`POST`,body:{},signal:t})}async runtime(e,t){let n=await this.request(`/ui-api/v1/runtime`,Dt,{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`,He,{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`,Le,{method:`GET`,query:{model:e,autoload:!1},signal:t})}async patchSettings(e,t,n){return this.request(`/settings`,Re,{method:`PATCH`,query:{model:e,autoload:!1},body:{op:`merge`,values:t},signal:n})}async modelProps(e,t){return this.request(`/props`,ze,{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(Xe(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(Ot(nt(t.data)))}})}async chatCompletions(e,t,n,r){await this.sse(Xe(this.apiBase,`/v1/chat/completions`,{autoload:!1}),{method:`POST`,body:Pt(t,e),signal:r,headers:{Accept:`text/event-stream`}},n)}async responses(e,t,n,r){await this.sse(Xe(this.apiBase,`/v1/responses`,{autoload:!1}),{method:`POST`,body:Pt(t,e),signal:r,headers:{Accept:`text/event-stream`}},n)}async request(e,t,n){let r=await this.fetchWithAuth(Xe(this.apiBase,e,n.query),n);try{return r.response.ok||await this.throwHttp(r.response,r.signal),t(nt(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 We({onDone:n.onDone,onMessage:n.onFrame}),i=e.body.getReader();try{for(;;){let e=await Ft(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}=It(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=bt(nt(n)))}catch{r=null}throw new kt(e.status,Mt(r,n),Nt(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 Ft(n,t);if(e.done)break;if(i+=e.value.byteLength,i>At)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 Mt(e,t){return e===null?null:{...e,error:{...e.error,message:Nt(e.error.message,t),field_errors:e.error.field_errors?.map(e=>({...e,message:Nt(e.message,t)}))}}}function Nt(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 Pt(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 Ft(e,t){if(t.aborted)throw await e.cancel().catch(()=>void 0),Lt();let n=null;try{let r=await Promise.race([e.read(),new Promise((r,i)=>{n=()=>{e.cancel().catch(()=>void 0),i(Lt())},t.addEventListener(`abort`,n,{once:!0})})]);if(t.aborted)throw Lt();return r}finally{n!==null&&t.removeEventListener(`abort`,n)}}function It(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 Lt(){return typeof DOMException==`function`?new DOMException(`The WebUI request was aborted.`,`AbortError`):Error(`The WebUI request was aborted.`)}function Rt(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 zt(e,t){let n=[...e.values()].sort((e,t)=>t.updated_at.localeCompare(e.updated_at)),r=n.filter(e=>!Bt(e)),i=n.filter(e=>Bt(e)&&Date.parse(e.updated_at)>t-36e5).slice(0,200);return new Map([...r,...i].map(e=>[e.operation_id,e]))}function Bt(e){return[`succeeded`,`failed`,`cancelled`].includes(e.state)}var Vt=`webui.ui-api.v1`;function Ht(){return{schemaVersion:Vt,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 Ut(e,t){return t.type===`login-start`?{...e,auth:{status:`authenticating`,tokenPresent:!0},connection:`bootstrapping`,error:null}:t.type===`login-success`?V(e,t.bootstrap,t.now):t.type===`logout`?{...Ht(),lastUpdatedAt:t.now}:t.type===`select-model`?{...e,selectedModelId:t.modelId,runtimeHistory:[]}:t.type===`catalog`?Wt(e,t.response,t.now):t.type===`operations-snapshot`?Gt(e,t.response,t.now):t.type===`operation`?Kt(e,t.operation,t.sequence,t.now):t.type===`runtime`?qt(e,t.runtime,t.sequence,t.now):t.type===`event`?Jt(e,t.event,t.now):t.type===`pending`?{...e,pendingReconciliations:nn(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 V(e,t,n){let r=t.server.server_instance_id;return e.serverInstanceId!==null&&e.serverInstanceId!==r?{...Ht(),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 Wt(e,t,n){if(e.serverInstanceId!==null&&t.server_instance_id!==e.serverInstanceId)return Qt(e,t.server_instance_id,n);if(e.catalogSequence!==null&&t.snapshot_sequenceo.has(e)))};return $t({...e,operations:o,serverInstanceId:t.server_instance_id,lastSequence:tn(s),error:null,resourceFences:s},n)}function Kt(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=zt(nn(e.operations,t.operation_id,t),r),o=n===null?e.resourceFences.operations:nn(e.resourceFences.operations,t.operation_id,n),s={...e.resourceFences,operations:new Map([...o].filter(([e])=>a.has(e)))};return $t({...e,operations:a,lastSequence:tn(s),error:null,resourceFences:s},r)}function qt(e,t,n,r){if(e.serverInstanceId!==null&&t.server_instance_id!==e.serverInstanceId)return Qt(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:nn(e.resourceFences.models,r,t.sequence)};return $t({...e,catalog:a,serverInstanceId:t.server_instance_id,lastEventId:t.event_id,lastSequence:tn(o),connection:`streaming`,resourceFences:o},n)}function Xt(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:nn(e.resourceFences.runtimes,r.model_id,t.sequence)};return $t({...e,runtimes:nn(e.runtimes,r.model_id,r),runtimeHistory:r.model_id===e.selectedModelId?Rt(e.runtimeHistory,r,n):e.runtimeHistory,serverInstanceId:t.server_instance_id,lastEventId:t.event_id,lastSequence:tn(a),connection:`streaming`,resourceFences:a},n)}function Zt(e,t,n){let r=t.type===`server_restart`?null:e.lastSuccessfulAt;return{...Ht(),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 Qt(e,t,n){return{...Ht(),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 $t(e,t){return{...e,lastUpdatedAt:t,lastSuccessfulAt:t}}function en(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 tn(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 nn(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 an=2e3,on=1e4,sn=3e4,cn=6e4,ln=6e4,un=new Set([`snapshot`,`model_revision`]),dn=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??_n,this.visibility=e.visibility??vn,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>=ln}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()})},on);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:pn(n),error:mn(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=fn(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:pn(n),error:mn(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:gn(`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:gn(`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 hn(`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>=cn&&(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 an}backoffDelay(){let e=Math.min(sn,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 fn(e){let t=tn(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 pn(e){if(e instanceof hn)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 mn(e){return e instanceof hn?{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 hn=class extends Error{code=`snapshot_mismatch`;constructor(e){super(e),this.name=`SnapshotConsistencyError`}};function gn(e,t,n){if(n.server_instance_id!==t.server_instance_id)throw new hn(`${e} pagination crossed a server restart; refresh the authoritative snapshot.`);if(n.snapshot_sequence!==t.snapshot_sequence)throw new hn(`${e} pagination crossed snapshot sequence boundaries; refresh the authoritative snapshot.`)}var _n={setTimeout:(e,t)=>globalThis.setTimeout(e,t),clearTimeout:e=>globalThis.clearTimeout(e),now:()=>Date.now()},vn={hidden:()=>typeof document<`u`&&document.hidden,subscribe:e=>typeof document>`u`?()=>void 0:(document.addEventListener(`visibilitychange`,e),()=>document.removeEventListener(`visibilitychange`,e))},yn=_.createContext(null),bn=_.createContext(null);function xn({children:e,apiBase:t,fetchImpl:n}){let[r,i]=_.useReducer(Ut,void 0,Ht),a=_.useRef(r);a.current=r;let o=_.useRef(0),s=_.useRef(null),c=_.useMemo(()=>new jt({apiBase:t,fetchImpl:n,onUnauthorized:()=>{o.current+=1,s.current?.stop(),i({type:`logout`,now:Date.now()})}}),[t,n]);_.useEffect(()=>{let e=new dn({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 kt)&&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)(bn.Provider,{value:l,children:(0,x.jsx)(yn.Provider,{value:r,children:e})})}function Sn(){let e=_.useContext(yn);if(e===null)throw Error(`useWebUi must be used within WebUiProvider.`);return e}function Cn(){let e=_.useContext(bn);if(e===null)throw Error(`useWebUiActions must be used within WebUiProvider.`);return e}var wn=Object.freeze({}),Tn=[`max_tokens`,`temperature`,`top_p`,`top_k`,`min_p`,`repetition_penalty`,`seed`];function En(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(!Tn.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 Dn=wn,On=new Set;function kn(e){return On.add(e),()=>On.delete(e)}function An(e){Dn=En(e);for(let e of On)e()}function jn(){An(wn)}function Mn(){return{defaults:(0,_.useSyncExternalStore)(kn,()=>Dn,()=>wn),setDefaults:An,reset:jn}}function Nn(e,t,n){return e===null||e<=0||t===null||n===void 0?`unknown`:t+n>e?`exceeds`:`raw-fits`}function Pn({modelId:e,nCtx:t,locale:n}){let r=Cn(),{defaults:i}=Mn(),[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=Nn(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)(Ce,{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 Fn(e){return e instanceof kt?e.status===401?`wrong-key`:e.status===403?`forbidden`:`generic`:e instanceof $e||e instanceof Error&&e.name===`ValidationError`?`schema`:e instanceof TypeError||e instanceof Error&&/fetch|network|offline|connection/i.test(e.message)?`offline`:`generic`}function In(e,t){let n=Kn(t);return n===null?R(e,`model.selected.none`):`${n.identity.display_name} · ${qn(e,n.lifecycle.state)}`}function Ln(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,sequence:Jn(e,t),status:Rn(e,t.connection)})}function Rn(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 zn(e){return e.snapshot.auth.status===`authenticated`?e.snapshot.connection===`schema-mismatch`?(0,x.jsx)(Hn,{...e}):(0,x.jsx)(Vn,{...e}):(0,x.jsx)(Bn,{...e})}function Bn(e){return e.authFailure===`schema`?(0,x.jsx)(Hn,{...e}):(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsxs)(`section`,{className:`screen-heading connection-prompt`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:e.eyebrow}),(0,x.jsx)(`h1`,{"data-testid":e.titleTestId,children:e.title}),(0,x.jsx)(`p`,{"data-testid":z(`connection.prompt.body`),children:R(e.locale,`connection.prompt.body`)})]}),(0,x.jsx)(Ne,{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:Gn(e.locale,e.authFailure),busy:e.snapshot.auth.status===`authenticating`,onSubmit:e.onLogin,onLogout:e.onLogout,testId:z(`auth.login`)})]})}function Vn(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.jsxs)(`section`,{className:`screen-heading connection-prompt`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:e.eyebrow}),(0,x.jsx)(`h1`,{"data-testid":e.titleTestId,children:e.title}),(0,x.jsx)(`p`,{"data-testid":z(`connection.authenticated.body`),children:R(e.locale,`connection.authenticated.body`)})]}),(0,x.jsx)(B,{tone:`info`,title:R(e.locale,`connection.authenticated.title`),body:Un(e.locale,e.snapshot),testId:z(`connection.authenticated.detail`)}),t?(0,x.jsx)(B,{title:R(e.locale,`connection.error.title`),body:Wn(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 Hn(e){return(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsxs)(`section`,{className:`screen-heading connection-prompt`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:e.eyebrow}),(0,x.jsx)(`h1`,{"data-testid":e.titleTestId,children:e.title})]}),(0,x.jsx)(Pe,{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 Un(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:Rn(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:Jn(e,t)})}function Wn(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 Gn(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 Kn(e){return e.selectedModelId===null?null:e.catalog.find(t=>t.identity.id===e.selectedModelId)??null}function qn(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 Jn(e,t){return String(t.lastSequence??t.catalogSequence??t.resourceFences.operationsSnapshot??R(e,`connection.snapshot.pending`))}function Yn({locale:e}){let{defaults:t,setDefaults:n,reset:r}=Mn(),[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:Tn.map(n=>(0,x.jsx)(Ce,{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)(B,{title:R(e,`settings.generation.error_title`),body:o}):null,(0,x.jsxs)(`div`,{children:[(0,x.jsx)(N,{onClick:()=>{try{n(En(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)(Ce,{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)(Ee,{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 Xn({modelId:e,locale:t}){let n=Cn(),[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]=Be(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:Ve(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)(B,{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)(Ce,{label:e.name,value:a[e.name]??Ve(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)(Ce,{label:e.name,value:Ve(e,r.current[e.name]),disabled:!0,hint:e.reason??e.help},e.name))]}),(0,x.jsxs)(Ee,{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,Ve(e,e.default)]))),c({}),m(!1)},children:R(t,`settings.live.reset.confirm`)})]})]})}var Zn=[`fp16`,`float16`,`int8`,`i8`,`turbo4-asym`,`fp16+turbo4`,`turbo3-asym`,`fp16+turbo3`,`turbo3`,`turbo4`,`turbo4-sym`,`turbo4-delegated`,`fp16+turbo4-delegated`],Qn=Object.freeze({});function $n(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`||!Zn.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 er(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:$n(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]=$n(t)}return{version:1,reusable:$n(n.reusable),models:r}}var tr=`mlxcel.webui.load-profiles.v1`,nr={version:1,reusable:Qn,models:{}},rr=!1,ir=new Set;function ar(e){return ir.add(e),()=>ir.delete(e)}function or(){if(!rr){rr=!0;try{let e=localStorage.getItem(tr);e!==null&&(nr=er(e))}catch{}}}function sr(e){let t=JSON.stringify(e),n=er(t);localStorage.setItem(tr,t),nr=n;for(let e of ir)e()}function cr(e){or();let t=(0,_.useSyncExternalStore)(ar,()=>nr);return{reusable:t.reusable,modelProfile:e===null?Qn:t.models[e]??Qn,profile:e!==null&&Object.hasOwn(t.models,e)?t.models[e]:t.reusable,save:(t,n)=>{let r=$n(t);if(n===`model`&&e===null)throw Error(`Select a model first.`);sr(n===`reusable`?{...nr,reusable:r}:{...nr,models:{...nr.models,[e]:r}})},reset:(t=e===null?`reusable`:`model`)=>{let n=Object.fromEntries(Object.entries(nr.models).filter(([t])=>t!==e));sr(t===`reusable`?{...nr,reusable:Qn}:{...nr,models:n})},exportJson:()=>JSON.stringify(nr,null,2),importJson:e=>sr(er(e))}}function lr(e){let t=$n(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=cr(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)(B,{tone:`info`,title:R(t,`settings.profile.single.title`),body:R(t,`settings.profile.single.body`)}):null,(0,x.jsx)(Se,{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)(Ce,{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)(Ce,{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)(Se,{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`)},...Zn.map(e=>({value:e,label:e}))]})]}),(0,x.jsx)(`p`,{children:R(t,`settings.profile.restrictions`)}),u?(0,x.jsx)(B,{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($n(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:lr(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)(Ee,{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 dr({locale:e}){let t=Sn(),n=Cn(),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)(Yn,{locale:e}),o?(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(Se,{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} · ${qn(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)(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:R(e,`settings.server.context.title`)}),(0,x.jsx)(Ce,{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)(Ce,{label:R(e,`settings.server.context.slots`),value:i?.totalSlots?.toString()??c,disabled:!0}),(0,x.jsx)(Ce,{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)(Pn,{modelId:s,nCtx:i?.nCtx??null,locale:e},s)]}),s===null?(0,x.jsx)(B,{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)(Xn,{modelId:s,locale:e},s):(0,x.jsx)(B,{tone:`info`,title:R(e,`settings.server.live_disabled.title`),body:R(e,`settings.server.live_disabled.body`)})]}):(0,x.jsx)(B,{tone:`warning`,title:R(e,`settings.server.unavailable.title`),body:R(e,`settings.server.unavailable.body`)})]})}var fr=[{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 pr(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]`);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)},[]);let o=n=>{let r=fr[(fr.findIndex(t=>t.id===e.route)+n+fr.length)%fr.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)(mr,{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)(Oe,{open:i,title:R(e.locale,`nav.primary`),onClose:()=>a(!1),closeLabel:R(e.locale,`common.close`),testId:`mobile-nav-sheet`,children:(0,x.jsx)(mr,{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`,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:()=>a(!0),"data-testid":z(`toolbar.menu`)}),(0,x.jsxs)(`div`,{className:`toolbar-title`,children:[(0,x.jsx)(`p`,{id:`app-title`,"data-testid":z(`app.title`),children:R(e.locale,`app.title`)}),(0,x.jsx)(`span`,{"data-testid":z(`app.subtitle`),children:R(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)(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)(`section`,{className:`app-content`,children:e.children}),e.inspector]})]})]})}var mr=_.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:fr.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.jsx)(`span`,{className:`connection-dot`,"data-state":e.connectionState,"aria-hidden":`true`}),(0,x.jsx)(`span`,{"data-testid":z(`connection.ready`),children:e.connectionLabel})]})]}));mr.displayName=`Sidebar`;var hr=[`mlxcel`,`glass`],gr=[`light`,`dark`],_r=[`system`,`light`,`dark`],vr=`mlxcel`,yr=`system`;hr.flatMap(e=>gr.map(t=>`${e}-${t}`));var br=`(prefers-color-scheme: dark)`;function xr(e){return typeof e==`string`&&hr.includes(e)}function Sr(e){return typeof e==`string`&&_r.includes(e)}function Cr(e,t){return`${e}-${t}`}function wr(){try{return typeof window>`u`||typeof window.matchMedia!=`function`?`light`:window.matchMedia(`(prefers-color-scheme: dark)`).matches?`dark`:`light`}catch{return`light`}}function Tr(e,t=wr()){return e===`system`?t:e}function Er(e,t,n=wr()){let r=Tr(t,n);return{id:Cr(e,r),family:e,scheme:r,preference:t}}function Dr(e){if(typeof window>`u`||typeof window.matchMedia!=`function`)return()=>void 0;let t;try{t=window.matchMedia(br)}catch{return()=>void 0}let n=t=>e(t.matches?`dark`:`light`);return t.addEventListener(`change`,n),()=>t.removeEventListener(`change`,n)}var Or={themeFamily:vr,colorScheme:yr,material:`glass`,glassIntensity:35,reduceMotion:!1,reduceTransparency:!1,highContrast:`system`,locale:`en`},kr=`mlxcel.webui.appearance`;function Ar(e){let t=typeof e==`number`&&Number.isFinite(e)?e:Or.glassIntensity;return Math.max(0,Math.min(100,Math.round(t)))}function jr(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Mr(e){return e===`glass`||e===`tinted`||e===`opaque`}function Nr(e){return e===`system`||e===`on`||e===`off`}function Pr(e){return Nr(e)?e:e===!0?`on`:e===!1?`off`:Or.highContrast}function Fr(e){return Sr(e.colorScheme)?e.colorScheme:e.colorScheme===void 0&&Sr(e.theme)?e.theme:Or.colorScheme}function Ir(e){return e===`en`||e===`ko`}function Lr(){if(typeof window>`u`)return Or;let e;try{e=window.localStorage.getItem(kr)}catch{return Or}if(!e)return Or;try{let t=JSON.parse(e);return jr(t)?{themeFamily:xr(t.themeFamily)?t.themeFamily:Or.themeFamily,colorScheme:Fr(t),material:Mr(t.material)?t.material:Or.material,glassIntensity:Ar(t.glassIntensity),reduceMotion:t.reduceMotion===!0,reduceTransparency:t.reduceTransparency===!0,highContrast:Pr(t.highContrast),locale:Ir(t.locale)?t.locale:Or.locale}:Or}catch{return Or}}function Rr(e){try{window.localStorage.setItem(kr,JSON.stringify(e))}catch{}}function zr(){return typeof CSS>`u`||typeof CSS.supports!=`function`?!1:CSS.supports(`backdrop-filter: blur(1px)`)||CSS.supports(`-webkit-backdrop-filter: blur(1px)`)}function Br(e,t,n=wr()){let r=Er(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(Ar(t.glassIntensity)),e.dataset.reduceMotion=String(t.reduceMotion),e.dataset.reduceTransparency=String(t.reduceTransparency),e.dataset.highContrast=t.highContrast,e.dataset.backdropFilter=zr()?`supported`:`unsupported`,e.lang=t.locale}function Vr(e){return e.value===null||!Number.isFinite(e.value)?`N/A`:`${new Intl.NumberFormat(void 0,{maximumFractionDigits:2}).format(e.value)} ${e.unit}`}function Hr(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 Ur(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 Wr(e){let t=URL.createObjectURL(new Blob([Ur(e)],{type:`application/json`})),n=document.createElement(`a`);n.href=t,n.download=`mlxcel-diagnostics.json`,n.click(),URL.revokeObjectURL(t)}function Gr({operations:e,locale:t,stale:n}){let r=[...e.values()].sort((e,t)=>Number(Bt(e))-Number(Bt(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=>!Bt(e)).length),failed:String(r.filter(e=>e.state===`failed`).length)})}),(0,x.jsx)(`p`,{children:R(t,`activity.session`)}),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)(Kr,{operation:e,locale:t,stale:n})},e.operation_id))})]})}function Kr({operation:e,locale:t,stale:n}){let r=Cn(),i=Sn(),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=Bt(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:Hr(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)(B,{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)(B,{title:R(t,`activity.cancel_failed`),body:R(t,`activity.refresh`)}):null]})}var qr=new Set(be.map(e=>e.key).filter(e=>e.startsWith(`activity.metric.`))),Jr=e=>qr.has(e);function Yr({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 Jr(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)(B,{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.jsxs)(`dl`,{className:`activity-metric`,children:[(0,x.jsx)(`dt`,{children:s(e)}),(0,x.jsx)(`dd`,{children:Vr(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.jsxs)(`dl`,{className:`activity-metric`,children:[(0,x.jsx)(`dt`,{children:s(e)}),(0,x.jsx)(`dd`,{children:Vr(n)}),(0,x.jsxs)(`dd`,{children:[R(t,`activity.scope`),`: `,n.scope]}),(0,x.jsxs)(`dd`,{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)(`dd`,{children:n.reason})]},e))})]})]})}var Xr=(function(){let e=typeof document<`u`&&document.createElement(`link`).relList;return e&&e.supports&&e.supports(`modulepreload`)?`modulepreload`:`preload`})(),Zr=function(e,t){return new URL(e,t).href},Qr={},$r=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=Zr(t,n),t=s(t),t in Qr)return;Qr[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`:Xr,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)})},ei=(0,_.lazy)(()=>$r(()=>import(`./history-U2uX7mu1.js`),[],import.meta.url));function ti({locale:e}){let t=Sn(),n=Cn(),[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":z(`activity.title`),children:R(e,`activity.title`)}),(0,x.jsx)(`p`,{children:R(e,`activity.intro`)}),(0,x.jsxs)(`p`,{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)(Se,{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.jsxs)(`div`,{className:`activity-toolbar`,children:[(0,x.jsx)(N,{onClick:()=>{n.refresh()},children:R(e,`activity.refresh`)}),(0,x.jsx)(N,{onClick:()=>Wr(t),children:R(e,`activity.export`)})]}),a?(0,x.jsx)(B,{tone:`warning`,title:R(e,`activity.stale`),body:R(e,`activity.refresh`)}):null,(0,x.jsx)(Gr,{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)(Yr,{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)(ei,{samples:t.runtimeHistory,locale:e})}):null]})}var ni=e=>[`succeeded`,`failed`,`cancelled`].includes(e.state),ri=e=>e.auth.status===`authenticated`&&e.bootstrap!==null&&e.catalogSequence!==null&&[`ready`,`streaming`,`polling`].includes(e.connection);function ii(e,t){return ri(e)&&e.bootstrap?.actions[t]?.state===`enabled`}function ai(e,t){return[...e.operations.values()].some(e=>!ni(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 oi(e,t){return ii(e,`load`)&&t.supported&&t.complete&&t.metadata.support.runnable_on_backend&&!t.lifecycle.busy&&[`unloaded`,`failed`].includes(t.lifecycle.state)&&!ai(e,t.identity.id)}function si(e,t){return ii(e,`unload`)&&t.lifecycle.state===`ready`&&!ai(e,t.identity.id)}function ci(e,t){return ii(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)&&!ai(e,t.identity.id)}function li(e,t){return ri(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&&si(e,n)&&!n.lifecycle.busy&&n.lifecycle.active_requests===0&&n.lifecycle.draining_requests===0)}function di(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 fi(e,t){return e instanceof kt?e.envelope?.error.code===`stale_revision`?R(t,`models.library.stale`):e.message:R(t,`models.library.pending`)}function pi(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 mi(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 hi(e){return e.length===0||e.length<=128&&e.split(`/`).every(e=>e!==`.`&&e!==`..`&&/^[A-Za-z0-9._~+-]+$/.test(e))}function gi({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=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)(Ee,{open:!0,title:f,onClose:i,closeLabel:R(n,`common.close`),testId:`models-confirm`,children:[(0,x.jsx)(`p`,{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)(Ce,{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`,{children:[e.identity.display_name,` · `,e.lifecycle.state,` · `,R(n,`models.library.active`),`:`,` `,e.lifecycle.active_requests]},e.identity.id))}),(0,x.jsx)(Se,{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 _i({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=mi(s.trim())&&hi(l.trim());return(0,x.jsx)(Ee,{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)(Ce,{label:R(e,`models.library.repo`),value:s,onChange:c,testId:`models-repo`,error:s&&!mi(s.trim())?R(e,`models.library.repo_invalid`):void 0}),(0,x.jsx)(Ce,{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 vi({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 yi({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`),di(s.disk_bytes,r)],[R(r,`models.library.memory`),di(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)(Ae,{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:qn(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)(vi,{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||!oi(n,e),onClick:()=>a(`load`),children:R(r,`models.load`)}),(0,x.jsx)(N,{"data-testid":`models-use-chat`,disabled:i||!li(n,e),onClick:o,children:R(r,`models.library.chat`)}),(0,x.jsx)(N,{"data-testid":`models-unload`,disabled:i||!si(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||!ci(n,e),onClick:()=>a(`delete`),children:R(r,`models.library.delete`)}):null]}),li(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 bi({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(ni(e))-Number(ni(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:Si(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:`${di(s.progress.completed_bytes,t)} / ${di(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===xi(s)&&oi(e,t)),onClick:()=>o(xi(s)),children:R(t,`models.library.capacity`)}):null,s.kind===`download`&&!ni(s)?(0,x.jsx)(N,{disabled:n||!ri(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||!ii(e,`download`),onClick:()=>a(s),children:R(t,`models.library.retry_download`)}):null]})]})},s.operation_id))})]})}function xi(e){return e.target.target_kind===`model`?e.target.model_id:``}function Si(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 Ci=25;function wi({locale:e}){let t=Sn(),n=Cn(),[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}=cr(y?.identity.id??null),{profile:S}=cr(f?.kind===`capacity`?f.entry.identity.id:null),C=pi(t.catalog,r),w=Math.max(1,Math.ceil(C.length/Ci)),T=Math.min(a,w-1),E=[...t.operations.values()].some(e=>e.kind===`download`&&!ni(e))||[...t.pendingReconciliations.values()].some(e=>e.kind===`download`),D=[...t.operations.values()].some(e=>e.kind===`catalog_refresh`&&!ni(e))||[...t.pendingReconciliations.values()].some(e=>e.kind===`catalog-refresh`),O=e=>{i({...r,...e}),o(0)},k=async(n,r)=>{if(l.current||!ri(t))return!1;l.current=!0,c(!0),d(null);try{return await n(),!0}catch(t){return d(fi(t,e)),r?.(t),!1}finally{l.current=!1,c(!1)}},ee=(r,i,a=b)=>{if(!oi(t,r)){d(R(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(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 kt&&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||ni(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(!ui(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`&&si(t,o)?k(()=>n.unloadModel({action:`unload`,model_id:o.identity.id,expected_revision:o.identity.revision,idempotency_key:crypto.randomUUID()})):a.kind===`delete`&&ci(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`,"aria-label":R(e,`models.library.inspect`,{name:r.identity.display_name}),onClick:()=>n.selectModel(r.identity.id),children:r.identity.display_name}),r.identity.id===t.selectedModelId?(0,x.jsx)(`small`,{children:R(e,`models.library.selected`)}):null,(0,x.jsxs)(`p`,{children:[r.identity.source,` · `,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:qn(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.jsxs)(`section`,{className:`screen-heading`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:R(e,`routes.models.eyebrow`)}),(0,x.jsx)(`h1`,{tabIndex:-1,"data-dialog-focus-fallback":!0,"data-testid":z(`models.title`),children:R(e,`models.title`)}),(0,x.jsx)(`p`,{children:R(e,`models.library.subtitle`)})]}),ri(t)?null:(0,x.jsx)(B,{title:R(e,`models.library.stale`),body:t.error?.message??R(e,`models.library.waiting`),action:(0,x.jsx)(N,{onClick:()=>{n.refresh()},children:R(e,`models.library.refresh`)}),testId:`connection-error-title`}),u?(0,x.jsx)(B,{title:R(e,`models.library.error`),body:u,action:(0,x.jsx)(N,{onClick:()=>{d(null),n.refresh()},children:R(e,`models.library.refresh`)}),testId:`models-action-error`}):null,t.bootstrap?.server.mode===`single_model`?(0,x.jsx)(B,{tone:`info`,title:R(e,`models.library.single`),body:`mlxcel-server --webui`,testId:`models-read-only`}):null,(0,x.jsxs)(`div`,{className:`button-row`,children:[(0,x.jsx)(N,{tone:`primary`,onClick:()=>h({repo:``,revision:``}),disabled:s||E||!ii(t,`download`),"data-testid":`models-add`,children:R(e,`models.library.add`)}),(0,x.jsx)(N,{disabled:s||D||!ri(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`)})]}),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:Un(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)(Ce,{label:R(e,`models.library.search`),value:r.query,onChange:e=>O({query:e}),testId:`models-search`}),(0,x.jsx)(Se,{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)(Se,{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)(Se,{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:qn(e,t)}))]}),(0,x.jsx)(Se,{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)(he,{columns:M,rows:C.slice(T*Ci,(T+1)*Ci),getRowKey:e=>e.identity.id,ariaLabel:R(e,`models.title`),testId:`models-table`,rowClassName:e=>e.identity.id===t.selectedModelId?`models-selected`:void 0,loading:t.catalogSequence===null,loadingState:(0,x.jsx)(`p`,{role:`status`,children: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)(yi,{entry:y,profile:b,state:t,locale:e,busy:s,onAction:A,onChat:()=>{li(t,y)&&(n.selectModel(y.identity.id),window.location.hash=`chat`)}}):null]}),(0,x.jsx)(bi,{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&&oi(t,n)&&p({kind:`capacity`,entry:n,instance:t.serverInstanceId})}}),f?(0,x.jsx)(gi,{value:f,state:t,locale:e,busy:s,onClose:()=>p(null),onConfirm:te},f.kind):null,m?(0,x.jsx)(_i,{locale:e,state:t,initial:m,error:u,busy:s||E||!ii(t,`download`),onClose:()=>h(null),onDownload:(e,r)=>{ii(t,`download`)&&!E&&k(()=>n.downloadModel({repo_id:e,revision:r||null,idempotency_key:crypto.randomUUID()})).then(e=>{e&&h(null)})}}):null]})}var Ti={en:`en-US`,ko:`ko-KR`},Ei=e=>Ti[e];function Di(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)(ji,{locale:e.locale})},{id:`data`,label:R(e.locale,`gallery.tab.data`),panel:(0,x.jsx)(Mi,{locale:e.locale})}]}),(0,x.jsxs)(Ee,{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)(Ce,{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 Ai(e){return(0,x.jsxs)(`div`,{className:`gallery-grid`,children:[(0,x.jsxs)(`article`,{className:`surface-card`,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)(Ce,{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)(Se,{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)(`article`,{className:`surface-card`,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)(ke,{label: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 ji(e){return(0,x.jsxs)(`div`,{className:`gallery-grid`,children:[(0,x.jsx)(Ne,{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)(Pe,{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)(B,{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:Di(67108864,e.locale)})}),(0,x.jsx)(fe,{label:R(e.locale,`gallery.progress.measured`),value:37})]}),(0,x.jsxs)(Me,{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 Mi(e){return(0,x.jsxs)(`div`,{className:`gallery-grid dense-gallery`,children:[(0,x.jsxs)(`article`,{className:`surface-card table-card`,tabIndex:0,"aria-label":R(e.locale,`gallery.sample.caption`),children:[(0,x.jsx)(`h2`,{children:R(e.locale,`gallery.data.title`)}),(0,x.jsxs)(je,{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:Oi(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:Oi(null,e.locale)})]})]})]})]}),(0,x.jsxs)(Ae,{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`)})]})]})}var Ni={count:4,bytes:8388608,dimension:4096,pixels:16e6},Pi=new Set([`image/png`,`image/jpeg`,`image/webp`]);function Fi(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 +`,$e=class extends Error{path;constructor(e,t){super(`${e}: ${t}`),this.path=e,this.name=`ValidationError`}},et=rt(Qe);function tt(e,t,n=`$`){let r=ht(et,[`components`,`schemas`],`#/components/schemas`)[e];if(r===void 0)throw new $e(n,`unknown schema ${e}`);it(r,t,n)}function nt(e){return JSON.parse(e)}function rt(e){return mt(nt(e),`$contract`)}function it(e,t,n){let r=mt(e,`${n}#schema`);if(typeof r.$ref==`string`){it(ft(r.$ref),t,n);return}if(r.anyOf!==void 0){if(!Array.isArray(r.anyOf)||!r.anyOf.some(e=>pt(e,t,n)))throw new $e(n,`did not match any allowed schema`);return}if(r.oneOf!==void 0){if(!Array.isArray(r.oneOf))throw new $e(n,`schema oneOf must be an array`);let e=r.oneOf.filter(e=>pt(e,t,n)).length;if(e!==1)throw new $e(n,`matched ${e} oneOf schemas`);return}if(r.const!==void 0&&t!==r.const)throw new $e(n,`expected constant ${String(r.const)}`);if(Array.isArray(r.enum)&&!r.enum.some(e=>e===t))throw new $e(n,`unexpected enum value ${String(t)}`);let i=r.type;if(Array.isArray(i)){if(!i.some(e=>dt(e,t)))throw new $e(n,`expected one of ${i.join(`, `)}`)}else if(typeof i==`string`&&!dt(i,t))throw new $e(n,`expected ${i}`);typeof t==`string`&&ct(r,t,n),typeof t==`number`&&ut(r,t,n),Array.isArray(t)&&ot(r,t,n),gt(t)&&at(r,t,n)}function at(e,t,n){let r=_t(e.required,`${n}#schema.required`,!1),i=e.properties===void 0?{}:mt(e.properties,`${n}#schema.properties`);for(let e of r)if(!(e in t))throw new $e(`${n}.${e}`,`missing required property`);if(e.maxProperties!==void 0&&Object.keys(t).length>vt(e.maxProperties,`${n}#schema.maxProperties`))throw new $e(n,`too many object properties`);for(let[r,a]of Object.entries(t)){let t=i[r];if(t!==void 0)it(t,a,`${n}.${r}`);else if(e.additionalProperties===!1)throw new $e(`${n}.${r}`,`unexpected property`);else gt(e.additionalProperties)&&it(e.additionalProperties,a,`${n}.${r}`)}}function ot(e,t,n){if(e.minItems!==void 0&&t.lengthvt(e.maxItems,`${n}#schema.maxItems`))throw new $e(n,`array longer than maximum`);e.items!==void 0&&t.forEach((t,r)=>it(e.items,t,`${n}[${r}]`))}function st(e){let t=0;for(let n=0;n65535?2:1;return t}function ct(e,t,n){let r=st(t);if(e.minLength!==void 0&&rvt(e.maxLength,`${n}#schema.maxLength`))throw new $e(n,`string longer than maximum`);if(typeof e.pattern==`string`&&!new RegExp(e.pattern,`u`).test(t))throw new $e(n,`string does not match pattern`);if(e.format===`date-time`&&!lt(t))throw new $e(n,`invalid RFC3339 date-time`)}function lt(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 ut(e,t,n){if(!Number.isFinite(t))throw new $e(n,`expected finite number`);if(e.type===`integer`&&!Number.isInteger(t))throw new $e(n,`expected integer`);if(e.minimum!==void 0&&tvt(e.maximum,`${n}#schema.maximum`))throw new $e(n,`number above maximum`)}function dt(e,t){return e===`null`?t===null:e===`array`?Array.isArray(t):e===`object`?gt(t):e===`integer`?typeof t==`number`&&Number.isInteger(t):e===`number`?typeof t==`number`&&Number.isFinite(t):typeof t===e}function ft(e){if(!e.startsWith(`#/`))throw new $e(`$ref`,`unsupported external ref ${e}`);return e.slice(2).split(`/`).map(e=>e.replace(/~1/g,`/`).replace(/~0/g,`~`)).reduce((t,n)=>mt(t,e)[n],et)}function pt(e,t,n){try{return it(e,t,n),!0}catch(e){if(e instanceof $e)return!1;throw e}}function mt(e,t){if(!gt(e))throw new $e(t,`expected object`);return e}function ht(e,t,n){return t.reduce((e,t)=>mt(e,n)[t],e)}function gt(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function _t(e,t,n){if(e===void 0&&!n)return[];if(!Array.isArray(e)||!e.every(e=>typeof e==`string`))throw new $e(t,`expected string array`);return e}function vt(e,t){if(typeof e!=`number`||!Number.isFinite(e))throw new $e(t,`expected numeric schema bound`);return e}function yt(e,t,n){return tt(e,t,n),t}function bt(e,t=`$`){return yt(`ErrorEnvelope`,e,t)}function xt(e,t=`$`){return yt(`BootstrapResponse`,e,t)}function St(e,t=`$`){return yt(`CatalogEntry`,e,t)}function Ct(e,t=`$`){return yt(`CatalogListResponse`,e,t)}function wt(e,t=`$`){return yt(`OperationsListResponse`,e,t)}function Tt(e,t=`$`){return yt(`Operation`,e,t)}function Et(e,t=`$`){return yt(`OperationAccepted`,e,t)}function Dt(e,t=`$`){return yt(`RuntimeSnapshot`,e,t)}function Ot(e,t=`$`){return yt(`UiEvent`,e,t)}var kt=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`}},At=2097152,jt=class{apiBase;fetchImpl;bearerToken=null;onUnauthorized;controllers=new Set;constructor(e={}){this.apiBase=qe(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`,xt,{method:`GET`,signal:e})}async catalog(e={},t){return this.request(`/ui-api/v1/catalog`,Ct,{method:`GET`,query:{...e},signal:t})}async catalogEntry(e,t){return this.request(`/ui-api/v1/catalog/${Ze(e)}`,St,{method:`GET`,signal:t})}async refreshCatalog(e,t){return this.request(`/ui-api/v1/catalog/refresh`,Et,{method:`POST`,body:{idempotency_key:e},signal:t})}async modelAction(e,t){return this.request(`/ui-api/v1/model-actions`,Et,{method:`POST`,body:e,signal:t})}async download(e,t){return this.request(`/ui-api/v1/downloads`,Et,{method:`POST`,body:e,signal:t})}async removeModel(e,t){return this.request(`/ui-api/v1/model-removals`,Et,{method:`POST`,body:e,signal:t})}async operationsPage(e={},t){return this.request(`/ui-api/v1/operations`,wt,{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/${Ze(e)}`,Tt,{method:`GET`,signal:t})}async cancelOperation(e,t){return this.request(`/ui-api/v1/operations/${Ze(e)}/cancel`,Et,{method:`POST`,body:{},signal:t})}async runtime(e,t){let n=await this.request(`/ui-api/v1/runtime`,Dt,{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`,He,{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`,Le,{method:`GET`,query:{model:e,autoload:!1},signal:t})}async patchSettings(e,t,n){return this.request(`/settings`,Re,{method:`PATCH`,query:{model:e,autoload:!1},body:{op:`merge`,values:t},signal:n})}async modelProps(e,t){return this.request(`/props`,ze,{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(Xe(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(Ot(nt(t.data)))}})}async chatCompletions(e,t,n,r){await this.sse(Xe(this.apiBase,`/v1/chat/completions`,{autoload:!1}),{method:`POST`,body:Pt(t,e),signal:r,headers:{Accept:`text/event-stream`}},n)}async responses(e,t,n,r){await this.sse(Xe(this.apiBase,`/v1/responses`,{autoload:!1}),{method:`POST`,body:Pt(t,e),signal:r,headers:{Accept:`text/event-stream`}},n)}async request(e,t,n){let r=await this.fetchWithAuth(Xe(this.apiBase,e,n.query),n);try{return r.response.ok||await this.throwHttp(r.response,r.signal),t(nt(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 We({onDone:n.onDone,onMessage:n.onFrame}),i=e.body.getReader();try{for(;;){let e=await Ft(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}=It(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=bt(nt(n)))}catch{r=null}throw new kt(e.status,Mt(r,n),Nt(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 Ft(n,t);if(e.done)break;if(i+=e.value.byteLength,i>At)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 Mt(e,t){return e===null?null:{...e,error:{...e.error,message:Nt(e.error.message,t),field_errors:e.error.field_errors?.map(e=>({...e,message:Nt(e.message,t)}))}}}function Nt(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 Pt(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 Ft(e,t){if(t.aborted)throw await e.cancel().catch(()=>void 0),Lt();let n=null;try{let r=await Promise.race([e.read(),new Promise((r,i)=>{n=()=>{e.cancel().catch(()=>void 0),i(Lt())},t.addEventListener(`abort`,n,{once:!0})})]);if(t.aborted)throw Lt();return r}finally{n!==null&&t.removeEventListener(`abort`,n)}}function It(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 Lt(){return typeof DOMException==`function`?new DOMException(`The WebUI request was aborted.`,`AbortError`):Error(`The WebUI request was aborted.`)}function Rt(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 zt(e,t){let n=[...e.values()].sort((e,t)=>t.updated_at.localeCompare(e.updated_at)),r=n.filter(e=>!Bt(e)),i=n.filter(e=>Bt(e)&&Date.parse(e.updated_at)>t-36e5).slice(0,200);return new Map([...r,...i].map(e=>[e.operation_id,e]))}function Bt(e){return[`succeeded`,`failed`,`cancelled`].includes(e.state)}var Vt=`webui.ui-api.v1`;function Ht(){return{schemaVersion:Vt,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 Ut(e,t){return t.type===`login-start`?{...e,auth:{status:`authenticating`,tokenPresent:!0},connection:`bootstrapping`,error:null}:t.type===`login-success`?V(e,t.bootstrap,t.now):t.type===`logout`?{...Ht(),lastUpdatedAt:t.now}:t.type===`select-model`?{...e,selectedModelId:t.modelId,runtimeHistory:[]}:t.type===`catalog`?Wt(e,t.response,t.now):t.type===`operations-snapshot`?Gt(e,t.response,t.now):t.type===`operation`?Kt(e,t.operation,t.sequence,t.now):t.type===`runtime`?qt(e,t.runtime,t.sequence,t.now):t.type===`event`?Jt(e,t.event,t.now):t.type===`pending`?{...e,pendingReconciliations:nn(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 V(e,t,n){let r=t.server.server_instance_id;return e.serverInstanceId!==null&&e.serverInstanceId!==r?{...Ht(),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 Wt(e,t,n){if(e.serverInstanceId!==null&&t.server_instance_id!==e.serverInstanceId)return Qt(e,t.server_instance_id,n);if(e.catalogSequence!==null&&t.snapshot_sequenceo.has(e)))};return $t({...e,operations:o,serverInstanceId:t.server_instance_id,lastSequence:tn(s),error:null,resourceFences:s},n)}function Kt(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=zt(nn(e.operations,t.operation_id,t),r),o=n===null?e.resourceFences.operations:nn(e.resourceFences.operations,t.operation_id,n),s={...e.resourceFences,operations:new Map([...o].filter(([e])=>a.has(e)))};return $t({...e,operations:a,lastSequence:tn(s),error:null,resourceFences:s},r)}function qt(e,t,n,r){if(e.serverInstanceId!==null&&t.server_instance_id!==e.serverInstanceId)return Qt(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:nn(e.resourceFences.models,r,t.sequence)};return $t({...e,catalog:a,serverInstanceId:t.server_instance_id,lastEventId:t.event_id,lastSequence:tn(o),connection:`streaming`,resourceFences:o},n)}function Xt(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:nn(e.resourceFences.runtimes,r.model_id,t.sequence)};return $t({...e,runtimes:nn(e.runtimes,r.model_id,r),runtimeHistory:r.model_id===e.selectedModelId?Rt(e.runtimeHistory,r,n):e.runtimeHistory,serverInstanceId:t.server_instance_id,lastEventId:t.event_id,lastSequence:tn(a),connection:`streaming`,resourceFences:a},n)}function Zt(e,t,n){let r=t.type===`server_restart`?null:e.lastSuccessfulAt;return{...Ht(),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 Qt(e,t,n){return{...Ht(),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 $t(e,t){return{...e,lastUpdatedAt:t,lastSuccessfulAt:t}}function en(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 tn(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 nn(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 an=2e3,on=1e4,sn=3e4,cn=6e4,ln=6e4,un=new Set([`snapshot`,`model_revision`]),dn=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??_n,this.visibility=e.visibility??vn,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>=ln}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()})},on);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:pn(n),error:mn(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=fn(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:pn(n),error:mn(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:gn(`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:gn(`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 hn(`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>=cn&&(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 an}backoffDelay(){let e=Math.min(sn,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 fn(e){let t=tn(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 pn(e){if(e instanceof hn)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 mn(e){return e instanceof hn?{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 hn=class extends Error{code=`snapshot_mismatch`;constructor(e){super(e),this.name=`SnapshotConsistencyError`}};function gn(e,t,n){if(n.server_instance_id!==t.server_instance_id)throw new hn(`${e} pagination crossed a server restart; refresh the authoritative snapshot.`);if(n.snapshot_sequence!==t.snapshot_sequence)throw new hn(`${e} pagination crossed snapshot sequence boundaries; refresh the authoritative snapshot.`)}var _n={setTimeout:(e,t)=>globalThis.setTimeout(e,t),clearTimeout:e=>globalThis.clearTimeout(e),now:()=>Date.now()},vn={hidden:()=>typeof document<`u`&&document.hidden,subscribe:e=>typeof document>`u`?()=>void 0:(document.addEventListener(`visibilitychange`,e),()=>document.removeEventListener(`visibilitychange`,e))},yn=_.createContext(null),bn=_.createContext(null);function xn({children:e,apiBase:t,fetchImpl:n}){let[r,i]=_.useReducer(Ut,void 0,Ht),a=_.useRef(r);a.current=r;let o=_.useRef(0),s=_.useRef(null),c=_.useMemo(()=>new jt({apiBase:t,fetchImpl:n,onUnauthorized:()=>{o.current+=1,s.current?.stop(),i({type:`logout`,now:Date.now()})}}),[t,n]);_.useEffect(()=>{let e=new dn({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 kt)&&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)(bn.Provider,{value:l,children:(0,x.jsx)(yn.Provider,{value:r,children:e})})}function Sn(){let e=_.useContext(yn);if(e===null)throw Error(`useWebUi must be used within WebUiProvider.`);return e}function Cn(){let e=_.useContext(bn);if(e===null)throw Error(`useWebUiActions must be used within WebUiProvider.`);return e}var wn=Object.freeze({}),Tn=[`max_tokens`,`temperature`,`top_p`,`top_k`,`min_p`,`repetition_penalty`,`seed`];function En(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(!Tn.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 Dn=wn,On=new Set;function kn(e){return On.add(e),()=>On.delete(e)}function An(e){Dn=En(e);for(let e of On)e()}function jn(){An(wn)}function Mn(){return{defaults:(0,_.useSyncExternalStore)(kn,()=>Dn,()=>wn),setDefaults:An,reset:jn}}function Nn(e,t,n){return e===null||e<=0||t===null||n===void 0?`unknown`:t+n>e?`exceeds`:`raw-fits`}function Pn({modelId:e,nCtx:t,locale:n}){let r=Cn(),{defaults:i}=Mn(),[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=Nn(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)(Ce,{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 Fn(e){return e instanceof kt?e.status===401?`wrong-key`:e.status===403?`forbidden`:`generic`:e instanceof $e||e instanceof Error&&e.name===`ValidationError`?`schema`:e instanceof TypeError||e instanceof Error&&/fetch|network|offline|connection/i.test(e.message)?`offline`:`generic`}function In(e,t){let n=Kn(t);return n===null?R(e,`model.selected.none`):`${n.identity.display_name} · ${qn(e,n.lifecycle.state)}`}function Ln(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,sequence:Jn(e,t),status:Rn(e,t.connection)})}function Rn(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 zn(e){return e.snapshot.auth.status===`authenticated`?e.snapshot.connection===`schema-mismatch`?(0,x.jsx)(Hn,{...e}):(0,x.jsx)(Vn,{...e}):(0,x.jsx)(Bn,{...e})}function Bn(e){return e.authFailure===`schema`?(0,x.jsx)(Hn,{...e}):(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsxs)(`section`,{className:`screen-heading connection-prompt`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:e.eyebrow}),(0,x.jsx)(`h1`,{"data-testid":e.titleTestId,children:e.title}),(0,x.jsx)(`p`,{"data-testid":z(`connection.prompt.body`),children:R(e.locale,`connection.prompt.body`)})]}),(0,x.jsx)(Ne,{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:Gn(e.locale,e.authFailure),busy:e.snapshot.auth.status===`authenticating`,onSubmit:e.onLogin,onLogout:e.onLogout,testId:z(`auth.login`)})]})}function Vn(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.jsxs)(`section`,{className:`screen-heading connection-prompt`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:e.eyebrow}),(0,x.jsx)(`h1`,{"data-testid":e.titleTestId,children:e.title}),(0,x.jsx)(`p`,{"data-testid":z(`connection.authenticated.body`),children:R(e.locale,`connection.authenticated.body`)})]}),(0,x.jsx)(B,{tone:`info`,title:R(e.locale,`connection.authenticated.title`),body:Un(e.locale,e.snapshot),testId:z(`connection.authenticated.detail`)}),t?(0,x.jsx)(B,{title:R(e.locale,`connection.error.title`),body:Wn(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 Hn(e){return(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsxs)(`section`,{className:`screen-heading connection-prompt`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:e.eyebrow}),(0,x.jsx)(`h1`,{"data-testid":e.titleTestId,children:e.title})]}),(0,x.jsx)(Pe,{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 Un(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:Rn(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:Jn(e,t)})}function Wn(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 Gn(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 Kn(e){return e.selectedModelId===null?null:e.catalog.find(t=>t.identity.id===e.selectedModelId)??null}function qn(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 Jn(e,t){return String(t.lastSequence??t.catalogSequence??t.resourceFences.operationsSnapshot??R(e,`connection.snapshot.pending`))}function Yn({locale:e}){let{defaults:t,setDefaults:n,reset:r}=Mn(),[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:Tn.map(n=>(0,x.jsx)(Ce,{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)(B,{title:R(e,`settings.generation.error_title`),body:o}):null,(0,x.jsxs)(`div`,{children:[(0,x.jsx)(N,{onClick:()=>{try{n(En(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)(Ce,{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)(Ee,{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 Xn({modelId:e,locale:t}){let n=Cn(),[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]=Be(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:Ve(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)(B,{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)(Ce,{label:e.name,value:a[e.name]??Ve(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)(Ce,{label:e.name,value:Ve(e,r.current[e.name]),disabled:!0,hint:e.reason??e.help},e.name))]}),(0,x.jsxs)(Ee,{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,Ve(e,e.default)]))),c({}),m(!1)},children:R(t,`settings.live.reset.confirm`)})]})]})}var Zn=[`fp16`,`float16`,`int8`,`i8`,`turbo4-asym`,`fp16+turbo4`,`turbo3-asym`,`fp16+turbo3`,`turbo3`,`turbo4`,`turbo4-sym`,`turbo4-delegated`,`fp16+turbo4-delegated`],Qn=Object.freeze({});function $n(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`||!Zn.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 er(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:$n(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]=$n(t)}return{version:1,reusable:$n(n.reusable),models:r}}var tr=`mlxcel.webui.load-profiles.v1`,nr={version:1,reusable:Qn,models:{}},rr=!1,ir=new Set;function ar(e){return ir.add(e),()=>ir.delete(e)}function or(){if(!rr){rr=!0;try{let e=localStorage.getItem(tr);e!==null&&(nr=er(e))}catch{}}}function sr(e){let t=JSON.stringify(e),n=er(t);localStorage.setItem(tr,t),nr=n;for(let e of ir)e()}function cr(e){or();let t=(0,_.useSyncExternalStore)(ar,()=>nr);return{reusable:t.reusable,modelProfile:e===null?Qn:t.models[e]??Qn,profile:e!==null&&Object.hasOwn(t.models,e)?t.models[e]:t.reusable,save:(t,n)=>{let r=$n(t);if(n===`model`&&e===null)throw Error(`Select a model first.`);sr(n===`reusable`?{...nr,reusable:r}:{...nr,models:{...nr.models,[e]:r}})},reset:(t=e===null?`reusable`:`model`)=>{let n=Object.fromEntries(Object.entries(nr.models).filter(([t])=>t!==e));sr(t===`reusable`?{...nr,reusable:Qn}:{...nr,models:n})},exportJson:()=>JSON.stringify(nr,null,2),importJson:e=>sr(er(e))}}function lr(e){let t=$n(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=cr(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)(B,{tone:`info`,title:R(t,`settings.profile.single.title`),body:R(t,`settings.profile.single.body`)}):null,(0,x.jsx)(Se,{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)(Ce,{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)(Ce,{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)(Se,{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`)},...Zn.map(e=>({value:e,label:e}))]})]}),(0,x.jsx)(`p`,{children:R(t,`settings.profile.restrictions`)}),u?(0,x.jsx)(B,{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($n(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:lr(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)(Ee,{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 dr({locale:e}){let t=Sn(),n=Cn(),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)(Yn,{locale:e}),o?(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(Se,{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} · ${qn(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)(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:R(e,`settings.server.context.title`)}),(0,x.jsx)(Ce,{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)(Ce,{label:R(e,`settings.server.context.slots`),value:i?.totalSlots?.toString()??c,disabled:!0}),(0,x.jsx)(Ce,{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)(Pn,{modelId:s,nCtx:i?.nCtx??null,locale:e},s)]}),s===null?(0,x.jsx)(B,{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)(Xn,{modelId:s,locale:e},s):(0,x.jsx)(B,{tone:`info`,title:R(e,`settings.server.live_disabled.title`),body:R(e,`settings.server.live_disabled.body`)})]}):(0,x.jsx)(B,{tone:`warning`,title:R(e,`settings.server.unavailable.title`),body:R(e,`settings.server.unavailable.body`)})]})}var fr=[{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 pr(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]`);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)},[]);let o=n=>{let r=fr[(fr.findIndex(t=>t.id===e.route)+n+fr.length)%fr.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)(mr,{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)(Oe,{open:i,title:R(e.locale,`nav.primary`),onClose:()=>a(!1),closeLabel:R(e.locale,`common.close`),testId:`mobile-nav-sheet`,children:(0,x.jsx)(mr,{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`,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:()=>a(!0),"data-testid":z(`toolbar.menu`)}),(0,x.jsxs)(`div`,{className:`toolbar-title`,children:[(0,x.jsx)(`p`,{id:`app-title`,"data-testid":z(`app.title`),children:R(e.locale,`app.title`)}),(0,x.jsx)(`span`,{"data-testid":z(`app.subtitle`),children:R(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)(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)(`section`,{className:`app-content`,children:e.children}),e.inspector]})]})]})}var mr=_.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:fr.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.jsx)(`span`,{className:`connection-dot`,"data-state":e.connectionState,"aria-hidden":`true`}),(0,x.jsx)(`span`,{"data-testid":z(`connection.ready`),children:e.connectionLabel})]})]}));mr.displayName=`Sidebar`;var hr=[`mlxcel`,`glass`],gr=[`light`,`dark`],_r=[`system`,`light`,`dark`],vr=`mlxcel`,yr=`system`;hr.flatMap(e=>gr.map(t=>`${e}-${t}`));var br=`(prefers-color-scheme: dark)`;function xr(e){return typeof e==`string`&&hr.includes(e)}function Sr(e){return typeof e==`string`&&_r.includes(e)}function Cr(e,t){return`${e}-${t}`}function wr(){try{return typeof window>`u`||typeof window.matchMedia!=`function`?`light`:window.matchMedia(`(prefers-color-scheme: dark)`).matches?`dark`:`light`}catch{return`light`}}function Tr(e,t=wr()){return e===`system`?t:e}function Er(e,t,n=wr()){let r=Tr(t,n);return{id:Cr(e,r),family:e,scheme:r,preference:t}}function Dr(e){if(typeof window>`u`||typeof window.matchMedia!=`function`)return()=>void 0;let t;try{t=window.matchMedia(br)}catch{return()=>void 0}let n=t=>e(t.matches?`dark`:`light`);return t.addEventListener(`change`,n),()=>t.removeEventListener(`change`,n)}var Or={themeFamily:vr,colorScheme:yr,material:`glass`,glassIntensity:35,reduceMotion:!1,reduceTransparency:!1,highContrast:`system`,locale:`en`},kr=`mlxcel.webui.appearance`;function Ar(e){let t=typeof e==`number`&&Number.isFinite(e)?e:Or.glassIntensity;return Math.max(0,Math.min(100,Math.round(t)))}function jr(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Mr(e){return e===`glass`||e===`tinted`||e===`opaque`}function Nr(e){return e===`system`||e===`on`||e===`off`}function Pr(e){return Nr(e)?e:e===!0?`on`:e===!1?`off`:Or.highContrast}function Fr(e){return Sr(e.colorScheme)?e.colorScheme:e.colorScheme===void 0&&Sr(e.theme)?e.theme:Or.colorScheme}function Ir(e){return e===`en`||e===`ko`}function Lr(){if(typeof window>`u`)return Or;let e;try{e=window.localStorage.getItem(kr)}catch{return Or}if(!e)return Or;try{let t=JSON.parse(e);return jr(t)?{themeFamily:xr(t.themeFamily)?t.themeFamily:Or.themeFamily,colorScheme:Fr(t),material:Mr(t.material)?t.material:Or.material,glassIntensity:Ar(t.glassIntensity),reduceMotion:t.reduceMotion===!0,reduceTransparency:t.reduceTransparency===!0,highContrast:Pr(t.highContrast),locale:Ir(t.locale)?t.locale:Or.locale}:Or}catch{return Or}}function Rr(e){try{window.localStorage.setItem(kr,JSON.stringify(e))}catch{}}function zr(){return typeof CSS>`u`||typeof CSS.supports!=`function`?!1:CSS.supports(`backdrop-filter: blur(1px)`)||CSS.supports(`-webkit-backdrop-filter: blur(1px)`)}function Br(e,t,n=wr()){let r=Er(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(Ar(t.glassIntensity)),e.dataset.reduceMotion=String(t.reduceMotion),e.dataset.reduceTransparency=String(t.reduceTransparency),e.dataset.highContrast=t.highContrast,e.dataset.backdropFilter=zr()?`supported`:`unsupported`,e.lang=t.locale}function Vr(e){return e.value===null||!Number.isFinite(e.value)?`N/A`:`${new Intl.NumberFormat(void 0,{maximumFractionDigits:2}).format(e.value)} ${e.unit}`}function Hr(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 Ur(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 Wr(e){let t=URL.createObjectURL(new Blob([Ur(e)],{type:`application/json`})),n=document.createElement(`a`);n.href=t,n.download=`mlxcel-diagnostics.json`,n.click(),URL.revokeObjectURL(t)}function Gr({operations:e,locale:t,stale:n}){let r=[...e.values()].sort((e,t)=>Number(Bt(e))-Number(Bt(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=>!Bt(e)).length),failed:String(r.filter(e=>e.state===`failed`).length)})}),(0,x.jsx)(`p`,{children:R(t,`activity.session`)}),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)(Kr,{operation:e,locale:t,stale:n})},e.operation_id))})]})}function Kr({operation:e,locale:t,stale:n}){let r=Cn(),i=Sn(),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=Bt(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:Hr(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)(B,{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)(B,{title:R(t,`activity.cancel_failed`),body:R(t,`activity.refresh`)}):null]})}var qr=new Set(be.map(e=>e.key).filter(e=>e.startsWith(`activity.metric.`))),Jr=e=>qr.has(e);function Yr({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 Jr(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)(B,{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.jsxs)(`dl`,{className:`activity-metric`,children:[(0,x.jsx)(`dt`,{children:s(e)}),(0,x.jsx)(`dd`,{children:Vr(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.jsxs)(`dl`,{className:`activity-metric`,children:[(0,x.jsx)(`dt`,{children:s(e)}),(0,x.jsx)(`dd`,{children:Vr(n)}),(0,x.jsxs)(`dd`,{children:[R(t,`activity.scope`),`: `,n.scope]}),(0,x.jsxs)(`dd`,{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)(`dd`,{children:n.reason})]},e))})]})]})}var Xr=(function(){let e=typeof document<`u`&&document.createElement(`link`).relList;return e&&e.supports&&e.supports(`modulepreload`)?`modulepreload`:`preload`})(),Zr=function(e,t){return new URL(e,t).href},Qr={},$r=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=Zr(t,n),t=s(t),t in Qr)return;Qr[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`:Xr,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)})},ei=(0,_.lazy)(()=>$r(()=>import(`./history-D3yl7FGt.js`),[],import.meta.url));function ti({locale:e}){let t=Sn(),n=Cn(),[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":z(`activity.title`),children:R(e,`activity.title`)}),(0,x.jsx)(`p`,{children:R(e,`activity.intro`)}),(0,x.jsxs)(`p`,{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)(Se,{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.jsxs)(`div`,{className:`activity-toolbar`,children:[(0,x.jsx)(N,{onClick:()=>{n.refresh()},children:R(e,`activity.refresh`)}),(0,x.jsx)(N,{onClick:()=>Wr(t),children:R(e,`activity.export`)})]}),a?(0,x.jsx)(B,{tone:`warning`,title:R(e,`activity.stale`),body:R(e,`activity.refresh`)}):null,(0,x.jsx)(Gr,{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)(Yr,{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)(ei,{samples:t.runtimeHistory,locale:e})}):null]})}var ni=e=>[`succeeded`,`failed`,`cancelled`].includes(e.state),ri=e=>e.auth.status===`authenticated`&&e.bootstrap!==null&&e.catalogSequence!==null&&[`ready`,`streaming`,`polling`].includes(e.connection);function ii(e,t){return ri(e)&&e.bootstrap?.actions[t]?.state===`enabled`}function ai(e,t){return[...e.operations.values()].some(e=>!ni(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 oi(e,t){return ii(e,`load`)&&t.supported&&t.complete&&t.metadata.support.runnable_on_backend&&!t.lifecycle.busy&&[`unloaded`,`failed`].includes(t.lifecycle.state)&&!ai(e,t.identity.id)}function si(e,t){return ii(e,`unload`)&&t.lifecycle.state===`ready`&&!ai(e,t.identity.id)}function ci(e,t){return ii(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)&&!ai(e,t.identity.id)}function li(e,t){return ri(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&&si(e,n)&&!n.lifecycle.busy&&n.lifecycle.active_requests===0&&n.lifecycle.draining_requests===0)}function di(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 fi(e,t){return e instanceof kt?e.envelope?.error.code===`stale_revision`?R(t,`models.library.stale`):e.message:R(t,`models.library.pending`)}function pi(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 mi(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 hi(e){return e.length===0||e.length<=128&&e.split(`/`).every(e=>e!==`.`&&e!==`..`&&/^[A-Za-z0-9._~+-]+$/.test(e))}function gi({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=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)(Ee,{open:!0,title:f,onClose:i,closeLabel:R(n,`common.close`),testId:`models-confirm`,children:[(0,x.jsx)(`p`,{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)(Ce,{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`,{children:[e.identity.display_name,` · `,e.lifecycle.state,` · `,R(n,`models.library.active`),`:`,` `,e.lifecycle.active_requests]},e.identity.id))}),(0,x.jsx)(Se,{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 _i({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=mi(s.trim())&&hi(l.trim());return(0,x.jsx)(Ee,{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)(Ce,{label:R(e,`models.library.repo`),value:s,onChange:c,testId:`models-repo`,error:s&&!mi(s.trim())?R(e,`models.library.repo_invalid`):void 0}),(0,x.jsx)(Ce,{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 vi({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 yi({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`),di(s.disk_bytes,r)],[R(r,`models.library.memory`),di(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)(Ae,{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:qn(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)(vi,{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||!oi(n,e),onClick:()=>a(`load`),children:R(r,`models.load`)}),(0,x.jsx)(N,{"data-testid":`models-use-chat`,disabled:i||!li(n,e),onClick:o,children:R(r,`models.library.chat`)}),(0,x.jsx)(N,{"data-testid":`models-unload`,disabled:i||!si(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||!ci(n,e),onClick:()=>a(`delete`),children:R(r,`models.library.delete`)}):null]}),li(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 bi({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(ni(e))-Number(ni(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:Si(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:`${di(s.progress.completed_bytes,t)} / ${di(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===xi(s)&&oi(e,t)),onClick:()=>o(xi(s)),children:R(t,`models.library.capacity`)}):null,s.kind===`download`&&!ni(s)?(0,x.jsx)(N,{disabled:n||!ri(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||!ii(e,`download`),onClick:()=>a(s),children:R(t,`models.library.retry_download`)}):null]})]})},s.operation_id))})]})}function xi(e){return e.target.target_kind===`model`?e.target.model_id:``}function Si(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 Ci=25;function wi({locale:e}){let t=Sn(),n=Cn(),[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}=cr(y?.identity.id??null),{profile:S}=cr(f?.kind===`capacity`?f.entry.identity.id:null),C=pi(t.catalog,r),w=Math.max(1,Math.ceil(C.length/Ci)),T=Math.min(a,w-1),E=[...t.operations.values()].some(e=>e.kind===`download`&&!ni(e))||[...t.pendingReconciliations.values()].some(e=>e.kind===`download`),D=[...t.operations.values()].some(e=>e.kind===`catalog_refresh`&&!ni(e))||[...t.pendingReconciliations.values()].some(e=>e.kind===`catalog-refresh`),O=e=>{i({...r,...e}),o(0)},k=async(n,r)=>{if(l.current||!ri(t))return!1;l.current=!0,c(!0),d(null);try{return await n(),!0}catch(t){return d(fi(t,e)),r?.(t),!1}finally{l.current=!1,c(!1)}},ee=(r,i,a=b)=>{if(!oi(t,r)){d(R(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(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 kt&&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||ni(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(!ui(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`&&si(t,o)?k(()=>n.unloadModel({action:`unload`,model_id:o.identity.id,expected_revision:o.identity.revision,idempotency_key:crypto.randomUUID()})):a.kind===`delete`&&ci(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`,"aria-label":R(e,`models.library.inspect`,{name:r.identity.display_name}),onClick:()=>n.selectModel(r.identity.id),children:r.identity.display_name}),r.identity.id===t.selectedModelId?(0,x.jsx)(`small`,{children:R(e,`models.library.selected`)}):null,(0,x.jsxs)(`p`,{children:[r.identity.source,` · `,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:qn(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.jsxs)(`section`,{className:`screen-heading`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:R(e,`routes.models.eyebrow`)}),(0,x.jsx)(`h1`,{tabIndex:-1,"data-dialog-focus-fallback":!0,"data-testid":z(`models.title`),children:R(e,`models.title`)}),(0,x.jsx)(`p`,{children:R(e,`models.library.subtitle`)})]}),ri(t)?null:(0,x.jsx)(B,{title:R(e,`models.library.stale`),body:t.error?.message??R(e,`models.library.waiting`),action:(0,x.jsx)(N,{onClick:()=>{n.refresh()},children:R(e,`models.library.refresh`)}),testId:`connection-error-title`}),u?(0,x.jsx)(B,{title:R(e,`models.library.error`),body:u,action:(0,x.jsx)(N,{onClick:()=>{d(null),n.refresh()},children:R(e,`models.library.refresh`)}),testId:`models-action-error`}):null,t.bootstrap?.server.mode===`single_model`?(0,x.jsx)(B,{tone:`info`,title:R(e,`models.library.single`),body:`mlxcel-server --webui`,testId:`models-read-only`}):null,(0,x.jsxs)(`div`,{className:`button-row`,children:[(0,x.jsx)(N,{tone:`primary`,onClick:()=>h({repo:``,revision:``}),disabled:s||E||!ii(t,`download`),"data-testid":`models-add`,children:R(e,`models.library.add`)}),(0,x.jsx)(N,{disabled:s||D||!ri(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`)})]}),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:Un(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)(Ce,{label:R(e,`models.library.search`),value:r.query,onChange:e=>O({query:e}),testId:`models-search`}),(0,x.jsx)(Se,{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)(Se,{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)(Se,{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:qn(e,t)}))]}),(0,x.jsx)(Se,{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)(he,{columns:M,rows:C.slice(T*Ci,(T+1)*Ci),getRowKey:e=>e.identity.id,ariaLabel:R(e,`models.title`),testId:`models-table`,rowClassName:e=>e.identity.id===t.selectedModelId?`models-selected`:void 0,loading:t.catalogSequence===null,loadingState:(0,x.jsx)(`p`,{role:`status`,children: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)(yi,{entry:y,profile:b,state:t,locale:e,busy:s,onAction:A,onChat:()=>{li(t,y)&&(n.selectModel(y.identity.id),window.location.hash=`chat`)}}):null]}),(0,x.jsx)(bi,{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&&oi(t,n)&&p({kind:`capacity`,entry:n,instance:t.serverInstanceId})}}),f?(0,x.jsx)(gi,{value:f,state:t,locale:e,busy:s,onClose:()=>p(null),onConfirm:te},f.kind):null,m?(0,x.jsx)(_i,{locale:e,state:t,initial:m,error:u,busy:s||E||!ii(t,`download`),onClose:()=>h(null),onDownload:(e,r)=>{ii(t,`download`)&&!E&&k(()=>n.downloadModel({repo_id:e,revision:r||null,idempotency_key:crypto.randomUUID()})).then(e=>{e&&h(null)})}}):null]})}var Ti={en:`en-US`,ko:`ko-KR`},Ei=e=>Ti[e];function Di(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)(ji,{locale:e.locale})},{id:`data`,label:R(e.locale,`gallery.tab.data`),panel:(0,x.jsx)(Mi,{locale:e.locale})}]}),(0,x.jsxs)(Ee,{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)(Ce,{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 Ai(e){return(0,x.jsxs)(`div`,{className:`gallery-grid`,children:[(0,x.jsxs)(`article`,{className:`surface-card`,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)(Ce,{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)(Se,{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)(`article`,{className:`surface-card`,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)(ke,{label: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 ji(e){return(0,x.jsxs)(`div`,{className:`gallery-grid`,children:[(0,x.jsx)(Ne,{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)(Pe,{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)(B,{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:Di(67108864,e.locale)})}),(0,x.jsx)(fe,{label:R(e.locale,`gallery.progress.measured`),value:37})]}),(0,x.jsxs)(Me,{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 Mi(e){return(0,x.jsxs)(`div`,{className:`gallery-grid dense-gallery`,children:[(0,x.jsxs)(`article`,{className:`surface-card table-card`,tabIndex:0,"aria-label":R(e.locale,`gallery.sample.caption`),children:[(0,x.jsx)(`h2`,{children:R(e.locale,`gallery.data.title`)}),(0,x.jsxs)(je,{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:Oi(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:Oi(null,e.locale)})]})]})]})]}),(0,x.jsxs)(Ae,{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`)})]})]})}var Ni={count:4,bytes:8388608,dimension:4096,pixels:16e6},Pi=new Set([`image/png`,`image/jpeg`,`image/webp`]);function Fi(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 Ii(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 Li(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 Ri(e,t,n){if(!e||!t||e>Math.min(Ni.dimension,n.max_width)||t>Math.min(Ni.dimension,n.max_height)||e*t>Ni.pixels||e*t*4>n.max_decoded_bytes)throw Error(`Image dimensions exceed the server or browser decode budget.`)}function zi(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(Li(t),e.length>t.max_images)throw Error(`Conversation images exceed the server image count limit.`);let n=0,r=Math.min(Ni.bytes,t.max_image_bytes);for(let i of e){if(!i||!Pi.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)||!Pi.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 Ii(e),[r,i]=Fi(t,e.type);if(Ri(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 Ui(e){if(e==null)return``;if(typeof e!=`string`)throw Error(`Malformed text delta.`);return e}function Wi(e){if(typeof e!=`number`||!Number.isSafeInteger(e)||e<0)throw Error(`Malformed usage.`);return e}function Gi(e,t,n){if(t.length>256e3)throw Error(`Chat frame exceeds the display limit.`);let r=Hi(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=Hi(r.usage);i={...i,usage:{prompt_tokens:Wi(e.prompt_tokens),completion_tokens:Wi(e.completion_tokens),total_tokens:Wi(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=Hi(e);if(t.index!==0)throw Error(`Unexpected chat choice index.`);let r=Hi(t.delta),a=Ui(r.content),o=Ui(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=Hi(e),n=Wi(t.index);if(n>=32)throw Error(`Tool index exceeds the display limit.`);let r=t.function===void 0?{}:Hi(t.function),i=s.find(e=>e.index===n)??{index:n,id:``,name:``,arguments:``},a={index:n,id:i.id+Ui(t.id),name:i.name+Ui(r.name),arguments:i.arguments+Ui(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=Ui(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 Ki(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 qi(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 Ji(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 Yi=Object.freeze({conversations:50,turnsPerConversation:200,totalTurns:1e3,textCharacters:262144,jsonBytes:16777216,imageBytes:8388608,imagesPerTurn:8,toolsPerTurn:128}),Xi=`mlxcel.webui.chat.v1`,Zi=`history`,Qi=`conversations`,$i=1,ea=new Set([`temperature`,`top_p`,`top_k`,`min_p`,`max_tokens`,`seed`,`repetition_penalty`,`presence_penalty`,`frequency_penalty`]),ta=class extends Error{constructor(e=`Conversation history is invalid or exceeds the local history limits.`){super(e),this.name=`HistoryValidationError`}},H=class extends Error{constructor(e,t){super(e,t),this.name=`HistoryStorageError`}};function U(){throw new ta}function na(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return U();let n=Object.getPrototypeOf(e);if(n!==Object.prototype&&n!==null)return U();let r=Object.keys(e);return r.length!==t.length||r.some(e=>!t.includes(e))?U():e}function W(e,t=Yi.textCharacters){return typeof e!=`string`||e.length>t?U():e}function ra(e){let t=W(e,512);return!t||Array.from(t).some(e=>e.charCodeAt(0)<32||e.charCodeAt(0)===127)?U():t}function ia(e,t=!1){return typeof e!=`number`||!Number.isFinite(e)||e<0||t&&!Number.isSafeInteger(e)?U():e}function aa(e,t){return e===null?null:t(e)}function oa(e,t){return!Array.isArray(e)||e.length>t?U():e}function sa(e){return new TextEncoder().encode(e).byteLength}function ca(e,t){let n=0,r=0,i=0,a=new Set;return oa(e,Yi.conversations).map(e=>{let o=na(e,[`id`,`title`,`systemPrompt`,`turns`,`updatedAt`]),s=ra(o.id);if(a.has(s))return U();a.add(s);let c=new Set,l=oa(o.turns,Yi.turnsPerConversation).map(e=>{if(++n>Yi.totalTurns)return U();let a=na(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 U();c.add(o);let s=W(a.status,32);if(![`streaming`,`complete`,`cancelled`,`interrupted`,`error`].includes(s))return U();let l={};if(!a.parameters||typeof a.parameters!=`object`||Array.isArray(a.parameters)||![Object.prototype,null].includes(Object.getPrototypeOf(a.parameters)))return U();for(let[e,t]of Object.entries(a.parameters)){if(!ea.has(e)||typeof t!=`number`||!Number.isFinite(t))return U();l[e]=t}let u=new Set,d=oa(a.tools,Yi.toolsPerTurn).map(e=>{let t=na(e,[`index`,`id`,`name`,`arguments`]),n=ia(t.index,!0);return u.has(n)?U():(u.add(n),{index:n,id:W(t.id,512),name:W(t.name,512),arguments:W(t.arguments)})}),f=oa(a.images,Yi.imagesPerTurn).map(e=>{let t=na(e,[`name`,`type`,`dataUrl`]),n=W(t.type,64);if(![`image/png`,`image/jpeg`,`image/webp`].includes(n))return U();let i=W(t.dataUrl,Yi.imageBytes*2),a=`data:${n};base64,`;if(!i.startsWith(a))return U();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>Yi.imageBytes)?U():{name:W(t.name,512),type:n,dataUrl:i}}),p={id:o,modelId:ra(a.modelId),modelRevision:ia(a.modelRevision,!0),inferenceId:ra(a.inferenceId),modelName:W(a.modelName,512),prompt:W(a.prompt),content:W(a.content),reasoning:W(a.reasoning),tools:d,status:s===`streaming`?`interrupted`:s,finishReason:aa(a.finishReason,W),usage:aa(a.usage,e=>{let t=na(e,[`prompt_tokens`,`completion_tokens`,`total_tokens`]);return{prompt_tokens:ia(t.prompt_tokens,!0),completion_tokens:ia(t.completion_tokens,!0),total_tokens:ia(t.total_tokens,!0)}}),ttftMs:aa(a.ttftMs,ia),elapsedMs:aa(a.elapsedMs,ia),error:aa(a.error,W),parameters:l,images:t.includeImages?f:[]};return p.status===`complete`&&(!p.finishReason||!p.content&&!p.reasoning&&!p.tools.length)||(i+=sa(JSON.stringify(p)),i>Yi.jsonBytes)?U():p});return{id:s,title:W(o.title,512),systemPrompt:W(o.systemPrompt),turns:l,updatedAt:ia(o.updatedAt,!0)}})}function la(e,t={}){let n=ca(e,t);return sa(JSON.stringify(n))>Yi.jsonBytes?U():n}function ua(e,t={}){let n=JSON.stringify({version:$i,conversations:la(e,t)});return sa(n)>Yi.jsonBytes?U():n}function da(e,t={}){if(sa(e)>Yi.jsonBytes)return U();let n;try{n=JSON.parse(e)}catch{return U()}let r=na(n,[`version`,`conversations`]);return r.version===$i?la(r.conversations,t):U()}function fa(e){return new H(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 pa(e={}){let t=!1,n=!1,r=0,i,a,o=new Set,s=()=>{let t=e.indexedDB??globalThis.indexedDB;if(!t)throw new H(`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(Xi,$i);o.onupgradeneeded=()=>{o.result.objectStoreNames.contains(Zi)||o.result.createObjectStore(Zi)},o.onerror=()=>a(fa(o.error));let l=!1;o.onblocked=()=>{l=!0,a(new H(`Close other WebUI tabs to access local history.`))},o.onsuccess=()=>{if(l||!t||e!==r){o.result.close(),a(new H(`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(Zi,e);o.add(r);let a=i(r.objectStore(Zi));r.oncomplete=()=>{o.delete(r),t(a.result)},r.onabort=r.onerror=()=>{o.delete(r),n(fa(r.error??a.error))}})}catch(e){throw e instanceof H?e:fa(e)}}return{setEnabled(e){t!==e&&(t=e,e||c())},async load(e={}){let t=await u(`readonly`,e=>e.get(Qi));return t===void 0?[]:da(W(t,Yi.jsonBytes),e)},async save(e,n={}){if(!t)return;let r=ua(e,n);await u(`readwrite`,e=>e.put(r,Qi))},async clear(){if(n)throw new H(`Local history is already being cleared.`);n=!0;let e=!1;c();try{await new Promise((t,r)=>{let i=s().deleteDatabase(Xi);i.onsuccess=()=>{n=!1,t()},i.onerror=()=>{n=!1,r(fa(i.error))},i.onblocked=()=>{e=!0,r(new H(`Close other WebUI tabs to clear local history.`))}})}catch(t){throw e||(n=!1),t instanceof H?t:fa(t)}},close:c}}var ma=[],ha=0,ga=new Set;function _a(){return ha}function va(e){return{id:crypto.randomUUID(),title:e,systemPrompt:``,turns:[],updatedAt:Date.now()}}var ya=new WeakMap;function ba(e){let t=ya.get(e);if(t!==void 0)return t;let n=new TextEncoder().encode(JSON.stringify(e)).byteLength;return ya.set(e,n),n}function xa(e){return e.length>Yi.conversations||e.reduce((e,t)=>e+t.turns.length,0)>Yi.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+ba(t),0)+Math.max(0,t.turns.length-1),0)<=Yi.jsonBytes}function Sa(e){ma=e;for(let e of ga)e()}function Ca(e){if(!xa(e))throw Error(`Conversation memory limit exceeded.`);ha++,Sa(e)}function wa(e){let t=ma.some(t=>t.id===e.id)?ma.map(t=>t.id===e.id?e:t):[...ma,e];return xa(t)?(Sa(t),!0):!1}function Ta(){return(0,_.useSyncExternalStore)(e=>(ga.add(e),()=>ga.delete(e)),()=>ma)}var Ea=(0,_.lazy)(()=>$r(()=>import(`./code-highlight-CLL7D9Tw.js`),[],import.meta.url)),Da=65536,Oa=512;function ka(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)(Ea,{code:e,language:t})}):(0,x.jsx)(`code`,{children:e})})]})}),Ma=(0,_.memo)(function({text:e,streaming:t=!1}){let n=e.slice(0,Da).split(` +`&&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 Ii(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 Li(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 Ri(e,t,n){if(!e||!t||e>Math.min(Ni.dimension,n.max_width)||t>Math.min(Ni.dimension,n.max_height)||e*t>Ni.pixels||e*t*4>n.max_decoded_bytes)throw Error(`Image dimensions exceed the server or browser decode budget.`)}function zi(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(Li(t),e.length>t.max_images)throw Error(`Conversation images exceed the server image count limit.`);let n=0,r=Math.min(Ni.bytes,t.max_image_bytes);for(let i of e){if(!i||!Pi.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)||!Pi.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 Ii(e),[r,i]=Fi(t,e.type);if(Ri(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 Ui(e){if(e==null)return``;if(typeof e!=`string`)throw Error(`Malformed text delta.`);return e}function Wi(e){if(typeof e!=`number`||!Number.isSafeInteger(e)||e<0)throw Error(`Malformed usage.`);return e}function Gi(e,t,n){if(t.length>256e3)throw Error(`Chat frame exceeds the display limit.`);let r=Hi(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=Hi(r.usage);i={...i,usage:{prompt_tokens:Wi(e.prompt_tokens),completion_tokens:Wi(e.completion_tokens),total_tokens:Wi(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=Hi(e);if(t.index!==0)throw Error(`Unexpected chat choice index.`);let r=Hi(t.delta),a=Ui(r.content),o=Ui(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=Hi(e),n=Wi(t.index);if(n>=32)throw Error(`Tool index exceeds the display limit.`);let r=t.function===void 0?{}:Hi(t.function),i=s.find(e=>e.index===n)??{index:n,id:``,name:``,arguments:``},a={index:n,id:i.id+Ui(t.id),name:i.name+Ui(r.name),arguments:i.arguments+Ui(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=Ui(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 Ki(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 qi(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 Ji(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 Yi=Object.freeze({conversations:50,turnsPerConversation:200,totalTurns:1e3,textCharacters:262144,jsonBytes:16777216,imageBytes:8388608,imagesPerTurn:8,toolsPerTurn:128}),Xi=`mlxcel.webui.chat.v1`,Zi=`history`,Qi=`conversations`,$i=1,ea=new Set([`temperature`,`top_p`,`top_k`,`min_p`,`max_tokens`,`seed`,`repetition_penalty`,`presence_penalty`,`frequency_penalty`]),ta=class extends Error{constructor(e=`Conversation history is invalid or exceeds the local history limits.`){super(e),this.name=`HistoryValidationError`}},H=class extends Error{constructor(e,t){super(e,t),this.name=`HistoryStorageError`}};function U(){throw new ta}function na(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return U();let n=Object.getPrototypeOf(e);if(n!==Object.prototype&&n!==null)return U();let r=Object.keys(e);return r.length!==t.length||r.some(e=>!t.includes(e))?U():e}function W(e,t=Yi.textCharacters){return typeof e!=`string`||e.length>t?U():e}function ra(e){let t=W(e,512);return!t||Array.from(t).some(e=>e.charCodeAt(0)<32||e.charCodeAt(0)===127)?U():t}function ia(e,t=!1){return typeof e!=`number`||!Number.isFinite(e)||e<0||t&&!Number.isSafeInteger(e)?U():e}function aa(e,t){return e===null?null:t(e)}function oa(e,t){return!Array.isArray(e)||e.length>t?U():e}function sa(e){return new TextEncoder().encode(e).byteLength}function ca(e,t){let n=0,r=0,i=0,a=new Set;return oa(e,Yi.conversations).map(e=>{let o=na(e,[`id`,`title`,`systemPrompt`,`turns`,`updatedAt`]),s=ra(o.id);if(a.has(s))return U();a.add(s);let c=new Set,l=oa(o.turns,Yi.turnsPerConversation).map(e=>{if(++n>Yi.totalTurns)return U();let a=na(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 U();c.add(o);let s=W(a.status,32);if(![`streaming`,`complete`,`cancelled`,`interrupted`,`error`].includes(s))return U();let l={};if(!a.parameters||typeof a.parameters!=`object`||Array.isArray(a.parameters)||![Object.prototype,null].includes(Object.getPrototypeOf(a.parameters)))return U();for(let[e,t]of Object.entries(a.parameters)){if(!ea.has(e)||typeof t!=`number`||!Number.isFinite(t))return U();l[e]=t}let u=new Set,d=oa(a.tools,Yi.toolsPerTurn).map(e=>{let t=na(e,[`index`,`id`,`name`,`arguments`]),n=ia(t.index,!0);return u.has(n)?U():(u.add(n),{index:n,id:W(t.id,512),name:W(t.name,512),arguments:W(t.arguments)})}),f=oa(a.images,Yi.imagesPerTurn).map(e=>{let t=na(e,[`name`,`type`,`dataUrl`]),n=W(t.type,64);if(![`image/png`,`image/jpeg`,`image/webp`].includes(n))return U();let i=W(t.dataUrl,Yi.imageBytes*2),a=`data:${n};base64,`;if(!i.startsWith(a))return U();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>Yi.imageBytes)?U():{name:W(t.name,512),type:n,dataUrl:i}}),p={id:o,modelId:ra(a.modelId),modelRevision:ia(a.modelRevision,!0),inferenceId:ra(a.inferenceId),modelName:W(a.modelName,512),prompt:W(a.prompt),content:W(a.content),reasoning:W(a.reasoning),tools:d,status:s===`streaming`?`interrupted`:s,finishReason:aa(a.finishReason,W),usage:aa(a.usage,e=>{let t=na(e,[`prompt_tokens`,`completion_tokens`,`total_tokens`]);return{prompt_tokens:ia(t.prompt_tokens,!0),completion_tokens:ia(t.completion_tokens,!0),total_tokens:ia(t.total_tokens,!0)}}),ttftMs:aa(a.ttftMs,ia),elapsedMs:aa(a.elapsedMs,ia),error:aa(a.error,W),parameters:l,images:t.includeImages?f:[]};return p.status===`complete`&&(!p.finishReason||!p.content&&!p.reasoning&&!p.tools.length)||(i+=sa(JSON.stringify(p)),i>Yi.jsonBytes)?U():p});return{id:s,title:W(o.title,512),systemPrompt:W(o.systemPrompt),turns:l,updatedAt:ia(o.updatedAt,!0)}})}function la(e,t={}){let n=ca(e,t);return sa(JSON.stringify(n))>Yi.jsonBytes?U():n}function ua(e,t={}){let n=JSON.stringify({version:$i,conversations:la(e,t)});return sa(n)>Yi.jsonBytes?U():n}function da(e,t={}){if(sa(e)>Yi.jsonBytes)return U();let n;try{n=JSON.parse(e)}catch{return U()}let r=na(n,[`version`,`conversations`]);return r.version===$i?la(r.conversations,t):U()}function fa(e){return new H(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 pa(e={}){let t=!1,n=!1,r=0,i,a,o=new Set,s=()=>{let t=e.indexedDB??globalThis.indexedDB;if(!t)throw new H(`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(Xi,$i);o.onupgradeneeded=()=>{o.result.objectStoreNames.contains(Zi)||o.result.createObjectStore(Zi)},o.onerror=()=>a(fa(o.error));let l=!1;o.onblocked=()=>{l=!0,a(new H(`Close other WebUI tabs to access local history.`))},o.onsuccess=()=>{if(l||!t||e!==r){o.result.close(),a(new H(`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(Zi,e);o.add(r);let a=i(r.objectStore(Zi));r.oncomplete=()=>{o.delete(r),t(a.result)},r.onabort=r.onerror=()=>{o.delete(r),n(fa(r.error??a.error))}})}catch(e){throw e instanceof H?e:fa(e)}}return{setEnabled(e){t!==e&&(t=e,e||c())},async load(e={}){let t=await u(`readonly`,e=>e.get(Qi));return t===void 0?[]:da(W(t,Yi.jsonBytes),e)},async save(e,n={}){if(!t)return;let r=ua(e,n);await u(`readwrite`,e=>e.put(r,Qi))},async clear(){if(n)throw new H(`Local history is already being cleared.`);n=!0;let e=!1;c();try{await new Promise((t,r)=>{let i=s().deleteDatabase(Xi);i.onsuccess=()=>{n=!1,t()},i.onerror=()=>{n=!1,r(fa(i.error))},i.onblocked=()=>{e=!0,r(new H(`Close other WebUI tabs to clear local history.`))}})}catch(t){throw e||(n=!1),t instanceof H?t:fa(t)}},close:c}}var ma=[],ha=0,ga=new Set;function _a(){return ha}function va(e){return{id:crypto.randomUUID(),title:e,systemPrompt:``,turns:[],updatedAt:Date.now()}}var ya=new WeakMap;function ba(e){let t=ya.get(e);if(t!==void 0)return t;let n=new TextEncoder().encode(JSON.stringify(e)).byteLength;return ya.set(e,n),n}function xa(e){return e.length>Yi.conversations||e.reduce((e,t)=>e+t.turns.length,0)>Yi.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+ba(t),0)+Math.max(0,t.turns.length-1),0)<=Yi.jsonBytes}function Sa(e){ma=e;for(let e of ga)e()}function Ca(e){if(!xa(e))throw Error(`Conversation memory limit exceeded.`);ha++,Sa(e)}function wa(e){let t=ma.some(t=>t.id===e.id)?ma.map(t=>t.id===e.id?e:t):[...ma,e];return xa(t)?(Sa(t),!0):!1}function Ta(){return(0,_.useSyncExternalStore)(e=>(ga.add(e),()=>ga.delete(e)),()=>ma)}var Ea=(0,_.lazy)(()=>$r(()=>import(`./code-highlight-CPbBnAiM.js`),[],import.meta.url)),Da=65536,Oa=512;function ka(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)(Ea,{code:e,language:t})}):(0,x.jsx)(`code`,{children:e})})]})}),Ma=(0,_.memo)(function({text:e,streaming:t=!1}){let n=e.slice(0,Da).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)(ja,{code:o.join(` `),language:s[2].slice(0,40),complete:c||!t&&e.length<=Da},a))}else if(/^#{1,6} /.test(o))r.push((0,x.jsx)(`p`,{className:`chat-markdown-heading`,children:(0,x.jsx)(`strong`,{children:ka(o.replace(/^#{1,6} /,``))})},a));else if(/^[-*] /.test(o)){let e=[o.slice(2)];for(;i(0,x.jsx)(`li`,{children:ka(e)},t))},a))}else o.trim()&&r.push((0,x.jsx)(`p`,{children:ka(o)},a))}return(0,x.jsxs)(`div`,{className:`chat-markdown`,children:[r,(e.length>Da||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)(Ma,{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 Fa({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)(Pa,{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 Ia({conversations:e,busy:t,onPending:n,limits:r,onReplace:i,locale:a}){let o=(0,_.useRef)(pa()),[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 La(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)(De,{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([ua(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=da(e,{includeImages:p});await La(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)(B,{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 La(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 Bi(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 Ra(e,t){let n=Object.fromEntries(Object.entries(t).filter(([,e])=>e!==void 0&&e.trim()!==``).map(([e,t])=>[e,Number(t)]));return{...En({...e,...n})}}function za({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:Tn.map(i=>(0,x.jsx)(Ce,{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 Ba=new Set([`en`,`ko`].map(e=>R(e,`chat.conversation.default_title`)));function Va({locale:e}){let t=Sn(),n=Cn(),{defaults:r}=Mn(),[i,a]=(0,_.useState)({}),o=Ta(),[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=va(O(`chat.conversation.default_title`));wa(e),c(e.id),u(``),f([])},oe=()=>{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`))})},se=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=Ra(r,i)}catch(e){m(e instanceof Error?e.message:O(`chat.error.invalid_parameters`));return}let s=j??va(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&&Ba.has(s.title)?l.slice(0,80):s.title,turns:[...s.turns,_],updatedAt:Date.now()};try{if(!t.bootstrap)throw Error(`Limits unavailable`);zi(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:qi(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(!wa(s)){m(O(`chat.error.memory_budget`));return}let S=null,w=_a(),T={controller:p,turn:_,conversation:s,flush:()=>{if(S!==null&&clearTimeout(S),S=null,_a()!==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()},wa(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)},wa(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=Gi(T.turn,e.data,performance.now()-h),S===null&&(S=setTimeout(T.flush,50)))}},p.signal),p.signal.aborted||(T.turn=Ki(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)}},ce=()=>{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),wa({...j,turns:j.turns.slice(0,t)}),window.setTimeout(()=>k.current?.focus(),0)},[le,P=``]=R(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:R(e,`chat.eyebrow`)}),(0,x.jsx)(`h1`,{tabIndex:-1,"data-dialog-focus-fallback":!0,"data-testid":z(`chat.title`),children:R(e,`chat.title`)}),(0,x.jsx)(`p`,{children:R(e,`chat.intro`)})]}),(0,x.jsxs)(`div`,{className:`chat-toolbar`,children:[(0,x.jsx)(N,{onClick:ae,disabled:v||b||C||o.length>=50,children:R(e,`chat.new_conversation`)}),(0,x.jsx)(Se,{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)(Se,{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} · ${qn(e,t.lifecycle.state)}`}))]})]}),re?null:(0,x.jsx)(B,{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)(Ce,{label:R(e,`chat.settings.name`),value:j.title,disabled:v||b||C,onChange:e=>wa({...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:Vi,disabled:v||b||C,onChange:e=>wa({...j,systemPrompt:e.target.value})})]}),(0,x.jsxs)(`p`,{children:[le,(0,x.jsx)(`a`,{href:`#settings`,children:R(e,`nav.settings`)}),P]}),(0,x.jsx)(N,{disabled:v||b||C,onClick:()=>{Ca(o.filter(e=>e.id!==j.id)),c(null)},children:R(e,`chat.settings.delete`)})]}):null,(0,x.jsx)(za,{defaults:r,draft:i,onChange:a,locale:e}),(0,x.jsx)(Fa,{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)(De,{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:ce,onClose:()=>E(null)}),p?(0,x.jsx)(B,{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:Vi,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(),se())}})]}),(0,x.jsx)(`p`,{children:R(e,`chat.composer.hint`,{count:String(l.length),max:String(Vi)})}),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),Bi(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:()=>{se()},children:R(e,`common.send`)}),(0,x.jsx)(N,{disabled:!v,onClick:oe,children:R(e,`chat.stop`)})]})]}),(0,x.jsx)(`p`,{role:`status`,"aria-live":`polite`,"aria-atomic":`true`,children:h}),(0,x.jsx)(Ia,{conversations:o,busy:v||C,onPending:S,limits:t.bootstrap?.media_limits,onReplace:e=>{Ca(e),c(null)},locale:e})]})}var Ha=[`models`,`chat`,`activity`,`settings`,`gallery`],Ua=[`models`,`chat`,`activity`,`settings`];function Wa(){let e=window.location.hash.slice(1).replace(/^\//,``);return Ha.includes(e)?e:`models`}function Ga(){let e=Sn(),t=Cn(),[n,r]=(0,_.useState)(Wa),[i,a]=(0,_.useState)(Lr),[o,s]=(0,_.useState)(null),[c,l]=(0,_.useState)(null),u=(0,_.useRef)(0);(0,_.useEffect)(()=>()=>{u.current+=1},[]),(0,_.useEffect)(()=>{let e=()=>r(Wa());return window.addEventListener(`hashchange`,e),()=>window.removeEventListener(`hashchange`,e)},[]),(0,_.useEffect)(()=>{if(Br(document.documentElement,i),Rr(i),i.colorScheme===`system`)return Dr(e=>Br(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`&&Ca([])},[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(Fn(e)))})},p=()=>{u.current+=1,l(null),t.logout()},m=Ka(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)(pr,{locale:i.locale,route:n,onRouteChange:d,onCommand:()=>s(`command`),onHelp:()=>s(`help`),selectedModel:In(i.locale,e),connectionLabel:Ln(i.locale,e),connectionState:e.connection,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:m}),(0,x.jsx)(Qa,{open:o===`command`,locale:i.locale,onClose:()=>s(null),onNavigate:e=>{d(e),s(null)}}),(0,x.jsxs)(Ee,{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.jsxs)(`ul`,{className:`shortcut-list`,children:[(0,x.jsxs)(`li`,{children:[(0,x.jsx)(`kbd`,{children:`⌘/Ctrl`}),` + `,(0,x.jsx)(`kbd`,{children:`K`}),` `,R(i.locale,`command.search`)]}),(0,x.jsxs)(`li`,{children:[(0,x.jsx)(`kbd`,{children:`Esc`}),` `,R(i.locale,`common.cancel`)]}),(0,x.jsxs)(`li`,{children:[(0,x.jsx)(`kbd`,{children:`[`}),` / `,(0,x.jsx)(`kbd`,{children:`]`}),` `,R(i.locale,`nav.models`)]})]})]})]})}function Ka(e,t,n,r){return e===`models`?(0,x.jsx)(qa,{locale:t.locale,context:r}):e===`chat`?(0,x.jsx)(Ja,{locale:t.locale,context:r}):e===`activity`?(0,x.jsx)(Ya,{locale:t.locale,context:r}):e===`settings`?(0,x.jsx)(Xa,{appearance:t,setAppearance:n}):(0,x.jsx)(ki,{locale:t.locale})}function qa(e){return e.context.snapshot.auth.status===`authenticated`&&e.context.snapshot.connection!==`schema-mismatch`?(0,x.jsx)(wi,{locale:e.locale}):(0,x.jsx)(zn,{locale:e.locale,eyebrow:R(e.locale,`routes.models.eyebrow`),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 Ja(e){return e.context.snapshot.auth.status===`authenticated`&&e.context.snapshot.connection!==`schema-mismatch`?(0,x.jsx)(Va,{locale:e.locale}):(0,x.jsx)(zn,{locale:e.locale,eyebrow:R(e.locale,`routes.chat.eyebrow`),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 Ya(e){return e.context.snapshot.auth.status===`authenticated`&&![`schema-mismatch`,`forbidden`,`unauthorized`].includes(e.context.snapshot.connection)?(0,x.jsx)(ti,{locale:e.locale}):(0,x.jsx)(zn,{locale:e.locale,eyebrow:R(e.locale,`routes.activity.eyebrow`),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 Xa(e){let t=t=>e.setAppearance({...e.appearance,...t});return(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsxs)(`section`,{className:`screen-heading`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:R(e.appearance.locale,`routes.settings.eyebrow`)}),(0,x.jsx)(`h1`,{tabIndex:-1,"data-dialog-focus-fallback":!0,"data-testid":z(`settings.title`),children:R(e.appearance.locale,`settings.title`)}),(0,x.jsx)(`p`,{"data-testid":z(`settings.appearance`),children:R(e.appearance.locale,`settings.browser_only`)})]}),(0,x.jsxs)(`div`,{className:`settings-grid`,children:[(0,x.jsx)(Se,{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)(Se,{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)(Se,{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)(Se,{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)(Se,{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)(Za,{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)(Za,{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)(B,{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)(dr,{locale:e.appearance.locale})]})}function Za(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 Qa(e){let[t,n]=(0,_.useState)(``),r=(e.locale&&window.location.hash.includes(`gallery`)?Ha:Ua).filter(e=>e.includes(t.toLowerCase()));return(0,x.jsxs)(Ee,{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)(Ce,{label:R(e.locale,`command.search`),value:t,onChange:n,testId:z(`command.search`)}),r.length===0?(0,x.jsx)(`p`,{"data-testid":z(`command.no_results`),children:R(e.locale,`command.no_results`)}):(0,x.jsx)(`div`,{className:`command-list`,children:r.map(t=>(0,x.jsx)(N,{onClick:()=>e.onNavigate(t),children:R(e.locale,t===`models`?`nav.models`:t===`chat`?`nav.chat`:t===`activity`?`nav.activity`:t===`settings`?`nav.settings`:`nav.gallery`)},t))})]})}var $a=document.getElementById(`root`);if($a===null)throw Error(`Missing #root element for mlxcel WebUI.`);(0,v.createRoot)($a).render((0,x.jsx)(_.StrictMode,{children:(0,x.jsx)(xn,{children:(0,x.jsx)(Ga,{})})}));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-tKjNOHbY.css b/src/webui/assets/assets/index-tKjNOHbY.css deleted file mode 100644 index ec9a17fe5..000000000 --- a/src/webui/assets/assets/index-tKjNOHbY.css +++ /dev/null @@ -1 +0,0 @@ -: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;--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;--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]{--material-control-backdrop:blur(calc(var(--material-glass-blur) / 2)) saturate(var(--material-glass-saturation));--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-button-shadow);--token-buttonDangerShadowHover:var(--glass-button-shadow);--token-buttonPrimaryBorder:1px solid var(--glass-edge);--token-buttonPrimaryShadow:var(--glass-button-shadow);--token-buttonPrimaryShadowHover:var(--glass-button-shadow);--token-buttonSecondaryBackdrop:var(--material-control-backdrop);--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);--material-control-backdrop:none;--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);--material-control-backdrop:none;--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);--material-control-backdrop:none;--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}}.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)}.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}.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,.ds-icon-button:hover{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-sheet[data-position=left]{width:min(320px,100vw - 32px);min-height:calc(100vh - 24px);margin:12px auto 12px 12px}.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)}.ds-common-table{color:var(--color-text);background:var(--material-content-bg);border-radius:var(--radius-lg)}@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} diff --git a/src/webui/assets/index.html b/src/webui/assets/index.html index 13d53a736..5c700092f 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 b7e846f10..f3059f42b 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": 709888, + "embedded_asset_bytes": 709972, "embedded_asset_limit_bytes": 5242880, - "initial_js_gzip_bytes": 153102, + "initial_js_gzip_bytes": 153100, "initial_js_gzip_limit_bytes": 204800, - "total_js_gzip_bytes": 154282, + "total_js_gzip_bytes": 154276, "total_js_gzip_limit_bytes": 716800 }, "files": [ { "bytes": 951, - "gzip_bytes": 614, - "path": "assets/code-highlight-CLL7D9Tw.js", - "sha256": "2ae6bc70e5a4a093bba721b7c3c7f0447844cc5a0d7ee9b9ff7bd0f57ec1c4e6" + "gzip_bytes": 612, + "path": "assets/code-highlight-CPbBnAiM.js", + "sha256": "e3b8b63aa9ec6be412b0cadc01521c38a2fe5513369f68adf1e2e00e9cc35b03" }, { "bytes": 1134, - "gzip_bytes": 566, - "path": "assets/history-U2uX7mu1.js", - "sha256": "5b14d4a37e1d8fb81b2bee33dfe3a299d1d5d9c370ed246bd0d5406d30ed57d7" + "gzip_bytes": 564, + "path": "assets/history-D3yl7FGt.js", + "sha256": "31919fc0639f4fcad044049f45c4a4bf858a7f5e75c8c9ab45c1809ca85aed32" }, { - "bytes": 592551, - "gzip_bytes": 152113, - "path": "assets/index-C7P01FJ4.js", - "sha256": "2931ce946f7f2eb7aaf6e0f7c50b802e0b292c1b340b5bf9c99356910660c1e9" + "bytes": 97199, + "gzip_bytes": 15798, + "path": "assets/index-BhcZpYw7.css", + "sha256": "fb6ef3ad583c3bab7b02150b9f9c3bbb3067f63ec861140e9b485deaf16e51be" }, { - "bytes": 97115, - "gzip_bytes": 15756, - "path": "assets/index-tKjNOHbY.css", - "sha256": "049fa2425fea78bc5a6ea2658eab4df0a920c47330ef276b8e912c1d01fc61ce" + "bytes": 592551, + "gzip_bytes": 152111, + "path": "assets/index-D8jBk5_a.js", + "sha256": "d3d12dd8aa5de4539f217c69c2077fac5948bf94b09da30d482abbf4b4fd3250" }, { "bytes": 503, - "gzip_bytes": 306, + "gzip_bytes": 303, "path": "index.html", - "sha256": "72f2c9908b2d7d91e2ba83e94dc3f0a1e653f410a3e1154fafd97c32e8975adf" + "sha256": "434c5e4733a5d4b1954e73d44e71b5cff05c8a23d3d79cc2b3cf0b1c471bf1bb" }, { "bytes": 2129, @@ -73,5 +73,5 @@ }, "pnpm_version": "11.18.0", "schema_version": 1, - "source_digest_sha256": "a12bb0c143f213969240b4f6b24a5862fcef36b75fcb4240f090809ef1fb3e3e" + "source_digest_sha256": "0dc47e6a66d6478bce27b7ee26f7402752ab9ee9799202ce2d73305fdd65e3d4" } diff --git a/webui/src/design-system/theme-bootstrap.test.ts b/webui/src/design-system/theme-bootstrap.test.ts index ea62241cc..b1f8b6545 100644 --- a/webui/src/design-system/theme-bootstrap.test.ts +++ b/webui/src/design-system/theme-bootstrap.test.ts @@ -2,6 +2,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import indexHtml from '../../index.html?raw'; import bootstrapSource from '../../public/theme-bootstrap.js?raw'; import { APPEARANCE_STORAGE_KEY, applyAppearance, loadAppearance } from './preferences'; +import { COLOR_SCHEME_PREFERENCES, THEME_FAMILIES, isThemeId } from './theme'; const THEME_ATTRIBUTES = ['data-theme', 'data-theme-family', 'data-color-scheme'] as const; @@ -49,6 +50,8 @@ const STORED: Array<[string, string | null]> = [ ['an invalid colorScheme does not fall back to the legacy field', JSON.stringify({ colorScheme: 'sepia', theme: 'dark' })], ['unknown family and scheme', JSON.stringify({ themeFamily: 'orange', colorScheme: 'glass-dark' })], ['a full theme id in the legacy field', JSON.stringify({ theme: 'glass-dark' })], + // Every family theme.ts ships, so a family added there but not to the bootstrap fails here. + ...THEME_FAMILIES.flatMap((themeFamily) => COLOR_SCHEME_PREFERENCES.map((colorScheme): [string, string] => [`${themeFamily}, ${colorScheme}`, JSON.stringify({ themeFamily, colorScheme })])), ]; beforeEach(() => { @@ -68,7 +71,7 @@ describe('pre-mount theme bootstrap (public/theme-bootstrap.js)', () => { if (stored !== null) localStorage.setItem(APPEARANCE_STORAGE_KEY, stored); setHostScheme(host); const early = runBootstrap(); - expect(early['data-theme']).toMatch(/^(mlxcel|glass)-(light|dark)$/); + expect(isThemeId(early['data-theme'])).toBe(true); expect(early).toEqual(runApp()); }); } @@ -85,7 +88,7 @@ describe('pre-mount theme bootstrap (public/theme-bootstrap.js)', () => { for (const theme of ['system', 'light', 'dark']) { localStorage.setItem(APPEARANCE_STORAGE_KEY, JSON.stringify({ theme })); setHostScheme('light'); - expect(runBootstrap()['data-theme']).toMatch(/^mlxcel-(light|dark)$/); + expect(isThemeId(runBootstrap()['data-theme'])).toBe(true); } }); }); @@ -96,7 +99,8 @@ describe('index.html', () => { it('loads the bootstrap as a classic, render-blocking script in ', () => { const tag = head.match(/]*\bsrc="\.\/theme-bootstrap\.js"[^>]*><\/script>/); expect(tag).not.toBeNull(); - expect(tag?.[0]).not.toMatch(/\b(type="module"|async|defer)\b/); + // Any type attribute (module included), async or defer would stop it blocking the first paint. + expect(tag?.[0]).not.toMatch(/\btype=|\basync\b|\bdefer\b/); }); it('carries no inline script, which the served CSP (script-src self) would block', () => { @@ -107,7 +111,10 @@ describe('index.html', () => { }); it('runs the bootstrap before the app module', () => { - expect(indexHtml.indexOf('./theme-bootstrap.js')).toBeGreaterThan(-1); - expect(indexHtml.indexOf('./theme-bootstrap.js')).toBeLessThan(indexHtml.indexOf('type="module"')); + const bootstrap = indexHtml.indexOf('./theme-bootstrap.js'); + const app = indexHtml.search(/]*\bsrc="\/src\/main\.tsx"/); + expect(bootstrap).toBeGreaterThan(-1); + expect(app).toBeGreaterThan(-1); + expect(bootstrap).toBeLessThan(app); }); }); diff --git a/webui/src/design-system/themes/glass.css b/webui/src/design-system/themes/glass.css index 262183485..72d112977 100644 --- a/webui/src/design-system/themes/glass.css +++ b/webui/src/design-system/themes/glass.css @@ -10,9 +10,10 @@ * highlights on filled buttons, while transcript, table and form surfaces stay * near-opaque so they remain readable. The system-color palette and the * highlight and fill values follow backend.ai-go's glass theme - * (src/themes/tokens/glass-light.css and glass-dark.css there), with the text, - * accent and status colors darkened or lightened where needed to clear WCAG 2.2 - * AA against this product's surfaces. + * (https://github.com/lablup/backend.ai-go/blob/main/src/themes/tokens/glass-light.css + * and https://github.com/lablup/backend.ai-go/blob/main/src/themes/tokens/glass-dark.css), + * with the text, accent and status colors darkened or lightened where needed to + * clear WCAG 2.2 AA against this product's surfaces. * * It reads the appearance switches the product already has and adds none: * - glass intensity: --material-glass-alpha, --material-glass-blur and @@ -49,6 +50,7 @@ --glass-edge: rgba(255, 255, 255, 0.15); --glass-highlight: linear-gradient(180deg, rgba(255, 255, 255, 0.18) 0%, rgba(255, 255, 255, 0.05) 40%, transparent 100%); --glass-button-shadow: 0 1px 3px rgba(0, 88, 185, 0.2); + --glass-danger-shadow: 0 1px 3px rgba(179, 38, 30, 0.2); --button-primary-solid: #0058b9; --button-primary-fill-active: #004a9c; --button-danger-solid: #b3261e; @@ -79,6 +81,7 @@ --glass-edge: rgba(255, 255, 255, 0.1); --glass-highlight: linear-gradient(180deg, rgba(255, 255, 255, 0.15) 0%, rgba(255, 255, 255, 0.04) 40%, transparent 100%); --glass-button-shadow: 0 1px 3px rgba(0, 0, 0, 0.35); + --glass-danger-shadow: 0 1px 3px rgba(0, 0, 0, 0.35); --button-primary-solid: #0a5bc0; --button-primary-fill-active: #0a4ea6; --button-danger-solid: #b3261e; @@ -94,8 +97,8 @@ --token-boxShadowSecondary: var(--shadow-popover); --token-buttonActiveTransform: scale(0.985); --token-buttonDangerBorder: 1px solid var(--glass-edge); - --token-buttonDangerShadow: var(--glass-button-shadow); - --token-buttonDangerShadowHover: var(--glass-button-shadow); + --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); From 28c7fa51b675ac4e995635a3f4c1a2164fa33fab Mon Sep 17 00:00:00 2001 From: Jeongkyu Shin Date: Sat, 19 Sep 2026 14:26:55 +0900 Subject: [PATCH 4/6] fix(webui): harden the theme gate and keep glass off content controls From the security review. The gate compared a resolved argv path with import.meta.url, which Node resolves through symlinks, so running it through a symlinked path exited 0 without checking anything; it now compares real paths. The import and attribute-selector patterns backtracked cubically and quadratically on long whitespace runs and are now linear, attribute names match case-insensitively as they do in HTML, and .jsx, .cjs, .mts and .cts files are scanned. build_bundle.py and the unit test also reject a nomodule or duplicated bootstrap tag. Each new spec case fails against the old code. Glass no longer gives ui-common secondary buttons a backdrop blur. Those buttons sit on transcript, table and form surfaces, which the epic keeps stable, and in WebKit each one became its own blur layer repainted during streaming. They keep the tinted translucent fill. Refs #1903 --- docs/webui/design-system.md | 6 +-- scripts/webui/build_bundle.py | 3 +- ...CPbBnAiM.js => code-highlight-DRHjgY60.js} | 2 +- ...istory-D3yl7FGt.js => history-DZcGwKDZ.js} | 2 +- src/webui/assets/assets/index-BhcZpYw7.css | 1 - .../{index-D8jBk5_a.js => index-CB18JmW6.js} | 4 +- src/webui/assets/assets/index-D9efccbm.css | 1 + src/webui/assets/index.html | 4 +- src/webui/assets/mlxcel-webui-manifest.json | 40 +++++++++---------- webui/scripts/check-theme-selectors.mjs | 30 ++++++++++---- webui/scripts/check-theme-selectors.spec.mjs | 35 ++++++++++++++-- .../src/design-system/theme-bootstrap.test.ts | 5 ++- webui/src/design-system/themes/glass.css | 10 ++--- webui/tests/theme.spec.ts | 4 +- 14 files changed, 95 insertions(+), 52 deletions(-) rename src/webui/assets/assets/{code-highlight-CPbBnAiM.js => code-highlight-DRHjgY60.js} (93%) rename src/webui/assets/assets/{history-D3yl7FGt.js => history-DZcGwKDZ.js} (94%) delete mode 100644 src/webui/assets/assets/index-BhcZpYw7.css rename src/webui/assets/assets/{index-D8jBk5_a.js => index-CB18JmW6.js} (99%) create mode 100644 src/webui/assets/assets/index-D9efccbm.css diff --git a/docs/webui/design-system.md b/docs/webui/design-system.md index d2e251f02..5606ee742 100644 --- a/docs/webui/design-system.md +++ b/docs/webui/design-system.md @@ -33,9 +33,9 @@ Files: `themes/contract.css` binds the scheme-dependent half of the token contra The theme is applied before the first paint. `webui/public/theme-bootstrap.js` is a classic, render-blocking script in the `` of `webui/index.html`; it reads the same storage key, resolves the id and writes the three theme attributes before the stylesheet paints or the app module runs, so a cold load never shows the wrong theme. It is an external file because the served CSP is `script-src 'self'`. `scripts/webui/build_bundle.py` refuses a bundle whose `index.html` lacks it, loads it after the app module or carries any inline script, and `src/design-system/theme-bootstrap.test.ts` runs the file against `applyAppearance` over stored-value and host-scheme combinations so the two cannot drift. It is the one script in the bundle without a content hash and revalidates like `index.html`. -The glass family reads only the existing switches. Glass intensity sizes the chrome and control blur, saturation and translucency. `data-material="opaque"`, reduced transparency (setting or `prefers-reduced-transparency`), `data-backdrop-filter="unsupported"` and raised contrast (setting or `prefers-contrast: more`) turn every glass surface opaque, drop the control backdrop and the button highlight, at any intensity. Reduced motion drops the press transform. The glass tokens live in this repository rather than in `@lablup/ui-common`: they are bound to this product's semantic token layer, which the package does not have, and proposing a glass family to the package is a separate decision for that package. The glass values derive from lablup/backend.ai-go's glass theme under Apache-2.0; see [NOTICE](../../NOTICE). +The glass family reads only the existing switches. Glass intensity sizes the chrome blur, saturation and translucency. Buttons get a tinted translucent fill but no backdrop blur of their own, because they sit on transcript, table and form surfaces, which stay stable, and a blur layer per button would be repainted on every streamed token. `data-material="opaque"`, reduced transparency (setting or `prefers-reduced-transparency`), `data-backdrop-filter="unsupported"` and raised contrast (setting or `prefers-contrast: more`) turn every glass surface opaque and drop the button highlight, at any intensity. Reduced motion drops the press transform. The glass tokens live in this repository rather than in `@lablup/ui-common`: they are bound to this product's semantic token layer, which the package does not have, and proposing a glass family to the package is a separate decision for that package. The glass values derive from lablup/backend.ai-go's glass theme under Apache-2.0; see [NOTICE](../../NOTICE). -Two engine limits apply. `@lablup/ui-common` alpha.19's Button stylesheet declares its backdrop only as `-webkit-backdrop-filter`, so glass button blur renders in WebKit and the buttons elsewhere stay translucent without blur. The product's own `.material-glass` chrome writes the prefixed declaration first, because Lightning CSS, which minifies the bundle, keeps only the prefixed form when it follows the standard one, and Chromium and Firefox ignore that form; `theme-stylesheets.test.ts` keeps the order. +The product's own `.material-glass` chrome writes `-webkit-backdrop-filter` before `backdrop-filter`, because Lightning CSS, which minifies the bundle, keeps only the prefixed form when it follows the standard one, and Chromium and Firefox ignore that form; `theme-stylesheets.test.ts` keeps the order. `pnpm --dir webui run check:theme-selectors` (`webui/scripts/check-theme-selectors.mjs`, run by the `webui-bundle` CI job and `make verify-webui-frontend`) is the gate that keeps this from rotting. It evaluates every `data-theme` and `data-theme-family` attribute selector in `webui/src`, `webui/public`, `webui/tests` and `index.html` against the ids `theme.ts` exports, whatever the operator, and fails on one that matches none, since such a rule compiles, renders and silently never applies. It also rejects `data-color-scheme` selectors (the raw preference), `@media (prefers-color-scheme)` in stylesheets and `prefers-color-scheme` queries in app code outside the resolver and the bootstrap (the host OS, not the applied theme), literal non-id values compared with or written to `data-theme`, theme stylesheet imports outside the single entry, and a shipped id with no theme block. A genuine host-OS concern keeps its query only with a written `theme-selector-allow: ` on the same or the preceding line. @@ -57,7 +57,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 (32 tests) and 401 Vitest tests across 40 files, covering the shared client/provider, shell and theme behavior. `pnpm --dir webui run browser` executes 60 Playwright tests, 61 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, 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 425 Vitest tests across 40 files, covering the shared client/provider, shell and theme behavior. `pnpm --dir webui run browser` executes 60 Playwright tests, 61 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, 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/scripts/webui/build_bundle.py b/scripts/webui/build_bundle.py index 5a371a158..bbe1ecec2 100755 --- a/scripts/webui/build_bundle.py +++ b/scripts/webui/build_bundle.py @@ -228,8 +228,9 @@ def assert_index_html(root: Path) -> None: raise SystemExit("index.html must not carry an inline script; the WebUI CSP blocks it") # Issue #1903: the theme is applied before first paint by a classic, # render-blocking script that runs ahead of the app module. + bootstraps = re.findall(r']*\bsrc="\./theme-bootstrap\.js"[^>]*>', html) bootstrap = re.search(r']*\bsrc="\./theme-bootstrap\.js"[^>]*>', html) - if bootstrap is None or re.search(r'\btype=|\basync\b|\bdefer\b', bootstrap.group(0)): + if bootstrap is None or len(bootstraps) != 1 or re.search(r'\btype=|\basync\b|\bdefer\b|\bnomodule\b', bootstrap.group(0)): raise SystemExit("index.html must load ./theme-bootstrap.js as a classic, blocking script") app_module = re.search(r']*\bsrc="\./assets/[^"]+\.js"[^>]*>', html) if app_module is None or bootstrap.start() > app_module.start(): diff --git a/src/webui/assets/assets/code-highlight-CPbBnAiM.js b/src/webui/assets/assets/code-highlight-DRHjgY60.js similarity index 93% rename from src/webui/assets/assets/code-highlight-CPbBnAiM.js rename to src/webui/assets/assets/code-highlight-DRHjgY60.js index 4abcb0b76..58236532c 100644 --- a/src/webui/assets/assets/code-highlight-CPbBnAiM.js +++ b/src/webui/assets/assets/code-highlight-DRHjgY60.js @@ -1 +1 @@ -import{i as e,n as t,r as n}from"./index-D8jBk5_a.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-CB18JmW6.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-D3yl7FGt.js b/src/webui/assets/assets/history-DZcGwKDZ.js similarity index 94% rename from src/webui/assets/assets/history-D3yl7FGt.js rename to src/webui/assets/assets/history-DZcGwKDZ.js index f64578194..8563df363 100644 --- a/src/webui/assets/assets/history-D3yl7FGt.js +++ b/src/webui/assets/assets/history-DZcGwKDZ.js @@ -1 +1 @@ -import{n as e,r as t,t as n}from"./index-D8jBk5_a.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-CB18JmW6.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-BhcZpYw7.css b/src/webui/assets/assets/index-BhcZpYw7.css deleted file mode 100644 index a0b9ee4c4..000000000 --- a/src/webui/assets/assets/index-BhcZpYw7.css +++ /dev/null @@ -1 +0,0 @@ -: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]{--material-control-backdrop:blur(calc(var(--material-glass-blur) / 2)) saturate(var(--material-glass-saturation));--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-buttonSecondaryBackdrop:var(--material-control-backdrop);--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);--material-control-backdrop:none;--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);--material-control-backdrop:none;--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);--material-control-backdrop:none;--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}}.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)}.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}.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,.ds-icon-button:hover{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-sheet[data-position=left]{width:min(320px,100vw - 32px);min-height:calc(100vh - 24px);margin:12px auto 12px 12px}.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)}.ds-common-table{color:var(--color-text);background:var(--material-content-bg);border-radius:var(--radius-lg)}@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} diff --git a/src/webui/assets/assets/index-D8jBk5_a.js b/src/webui/assets/assets/index-CB18JmW6.js similarity index 99% rename from src/webui/assets/assets/index-D8jBk5_a.js rename to src/webui/assets/assets/index-CB18JmW6.js index 88bbf37a4..2c07e3cba 100644 --- a/src/webui/assets/assets/index-D8jBk5_a.js +++ b/src/webui/assets/assets/index-CB18JmW6.js @@ -3733,8 +3733,8 @@ Error generating stack: `+e.message+` } } } -`,$e=class extends Error{path;constructor(e,t){super(`${e}: ${t}`),this.path=e,this.name=`ValidationError`}},et=rt(Qe);function tt(e,t,n=`$`){let r=ht(et,[`components`,`schemas`],`#/components/schemas`)[e];if(r===void 0)throw new $e(n,`unknown schema ${e}`);it(r,t,n)}function nt(e){return JSON.parse(e)}function rt(e){return mt(nt(e),`$contract`)}function it(e,t,n){let r=mt(e,`${n}#schema`);if(typeof r.$ref==`string`){it(ft(r.$ref),t,n);return}if(r.anyOf!==void 0){if(!Array.isArray(r.anyOf)||!r.anyOf.some(e=>pt(e,t,n)))throw new $e(n,`did not match any allowed schema`);return}if(r.oneOf!==void 0){if(!Array.isArray(r.oneOf))throw new $e(n,`schema oneOf must be an array`);let e=r.oneOf.filter(e=>pt(e,t,n)).length;if(e!==1)throw new $e(n,`matched ${e} oneOf schemas`);return}if(r.const!==void 0&&t!==r.const)throw new $e(n,`expected constant ${String(r.const)}`);if(Array.isArray(r.enum)&&!r.enum.some(e=>e===t))throw new $e(n,`unexpected enum value ${String(t)}`);let i=r.type;if(Array.isArray(i)){if(!i.some(e=>dt(e,t)))throw new $e(n,`expected one of ${i.join(`, `)}`)}else if(typeof i==`string`&&!dt(i,t))throw new $e(n,`expected ${i}`);typeof t==`string`&&ct(r,t,n),typeof t==`number`&&ut(r,t,n),Array.isArray(t)&&ot(r,t,n),gt(t)&&at(r,t,n)}function at(e,t,n){let r=_t(e.required,`${n}#schema.required`,!1),i=e.properties===void 0?{}:mt(e.properties,`${n}#schema.properties`);for(let e of r)if(!(e in t))throw new $e(`${n}.${e}`,`missing required property`);if(e.maxProperties!==void 0&&Object.keys(t).length>vt(e.maxProperties,`${n}#schema.maxProperties`))throw new $e(n,`too many object properties`);for(let[r,a]of Object.entries(t)){let t=i[r];if(t!==void 0)it(t,a,`${n}.${r}`);else if(e.additionalProperties===!1)throw new $e(`${n}.${r}`,`unexpected property`);else gt(e.additionalProperties)&&it(e.additionalProperties,a,`${n}.${r}`)}}function ot(e,t,n){if(e.minItems!==void 0&&t.lengthvt(e.maxItems,`${n}#schema.maxItems`))throw new $e(n,`array longer than maximum`);e.items!==void 0&&t.forEach((t,r)=>it(e.items,t,`${n}[${r}]`))}function st(e){let t=0;for(let n=0;n65535?2:1;return t}function ct(e,t,n){let r=st(t);if(e.minLength!==void 0&&rvt(e.maxLength,`${n}#schema.maxLength`))throw new $e(n,`string longer than maximum`);if(typeof e.pattern==`string`&&!new RegExp(e.pattern,`u`).test(t))throw new $e(n,`string does not match pattern`);if(e.format===`date-time`&&!lt(t))throw new $e(n,`invalid RFC3339 date-time`)}function lt(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 ut(e,t,n){if(!Number.isFinite(t))throw new $e(n,`expected finite number`);if(e.type===`integer`&&!Number.isInteger(t))throw new $e(n,`expected integer`);if(e.minimum!==void 0&&tvt(e.maximum,`${n}#schema.maximum`))throw new $e(n,`number above maximum`)}function dt(e,t){return e===`null`?t===null:e===`array`?Array.isArray(t):e===`object`?gt(t):e===`integer`?typeof t==`number`&&Number.isInteger(t):e===`number`?typeof t==`number`&&Number.isFinite(t):typeof t===e}function ft(e){if(!e.startsWith(`#/`))throw new $e(`$ref`,`unsupported external ref ${e}`);return e.slice(2).split(`/`).map(e=>e.replace(/~1/g,`/`).replace(/~0/g,`~`)).reduce((t,n)=>mt(t,e)[n],et)}function pt(e,t,n){try{return it(e,t,n),!0}catch(e){if(e instanceof $e)return!1;throw e}}function mt(e,t){if(!gt(e))throw new $e(t,`expected object`);return e}function ht(e,t,n){return t.reduce((e,t)=>mt(e,n)[t],e)}function gt(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function _t(e,t,n){if(e===void 0&&!n)return[];if(!Array.isArray(e)||!e.every(e=>typeof e==`string`))throw new $e(t,`expected string array`);return e}function vt(e,t){if(typeof e!=`number`||!Number.isFinite(e))throw new $e(t,`expected numeric schema bound`);return e}function yt(e,t,n){return tt(e,t,n),t}function bt(e,t=`$`){return yt(`ErrorEnvelope`,e,t)}function xt(e,t=`$`){return yt(`BootstrapResponse`,e,t)}function St(e,t=`$`){return yt(`CatalogEntry`,e,t)}function Ct(e,t=`$`){return yt(`CatalogListResponse`,e,t)}function wt(e,t=`$`){return yt(`OperationsListResponse`,e,t)}function Tt(e,t=`$`){return yt(`Operation`,e,t)}function Et(e,t=`$`){return yt(`OperationAccepted`,e,t)}function Dt(e,t=`$`){return yt(`RuntimeSnapshot`,e,t)}function Ot(e,t=`$`){return yt(`UiEvent`,e,t)}var kt=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`}},At=2097152,jt=class{apiBase;fetchImpl;bearerToken=null;onUnauthorized;controllers=new Set;constructor(e={}){this.apiBase=qe(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`,xt,{method:`GET`,signal:e})}async catalog(e={},t){return this.request(`/ui-api/v1/catalog`,Ct,{method:`GET`,query:{...e},signal:t})}async catalogEntry(e,t){return this.request(`/ui-api/v1/catalog/${Ze(e)}`,St,{method:`GET`,signal:t})}async refreshCatalog(e,t){return this.request(`/ui-api/v1/catalog/refresh`,Et,{method:`POST`,body:{idempotency_key:e},signal:t})}async modelAction(e,t){return this.request(`/ui-api/v1/model-actions`,Et,{method:`POST`,body:e,signal:t})}async download(e,t){return this.request(`/ui-api/v1/downloads`,Et,{method:`POST`,body:e,signal:t})}async removeModel(e,t){return this.request(`/ui-api/v1/model-removals`,Et,{method:`POST`,body:e,signal:t})}async operationsPage(e={},t){return this.request(`/ui-api/v1/operations`,wt,{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/${Ze(e)}`,Tt,{method:`GET`,signal:t})}async cancelOperation(e,t){return this.request(`/ui-api/v1/operations/${Ze(e)}/cancel`,Et,{method:`POST`,body:{},signal:t})}async runtime(e,t){let n=await this.request(`/ui-api/v1/runtime`,Dt,{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`,He,{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`,Le,{method:`GET`,query:{model:e,autoload:!1},signal:t})}async patchSettings(e,t,n){return this.request(`/settings`,Re,{method:`PATCH`,query:{model:e,autoload:!1},body:{op:`merge`,values:t},signal:n})}async modelProps(e,t){return this.request(`/props`,ze,{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(Xe(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(Ot(nt(t.data)))}})}async chatCompletions(e,t,n,r){await this.sse(Xe(this.apiBase,`/v1/chat/completions`,{autoload:!1}),{method:`POST`,body:Pt(t,e),signal:r,headers:{Accept:`text/event-stream`}},n)}async responses(e,t,n,r){await this.sse(Xe(this.apiBase,`/v1/responses`,{autoload:!1}),{method:`POST`,body:Pt(t,e),signal:r,headers:{Accept:`text/event-stream`}},n)}async request(e,t,n){let r=await this.fetchWithAuth(Xe(this.apiBase,e,n.query),n);try{return r.response.ok||await this.throwHttp(r.response,r.signal),t(nt(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 We({onDone:n.onDone,onMessage:n.onFrame}),i=e.body.getReader();try{for(;;){let e=await Ft(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}=It(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=bt(nt(n)))}catch{r=null}throw new kt(e.status,Mt(r,n),Nt(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 Ft(n,t);if(e.done)break;if(i+=e.value.byteLength,i>At)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 Mt(e,t){return e===null?null:{...e,error:{...e.error,message:Nt(e.error.message,t),field_errors:e.error.field_errors?.map(e=>({...e,message:Nt(e.message,t)}))}}}function Nt(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 Pt(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 Ft(e,t){if(t.aborted)throw await e.cancel().catch(()=>void 0),Lt();let n=null;try{let r=await Promise.race([e.read(),new Promise((r,i)=>{n=()=>{e.cancel().catch(()=>void 0),i(Lt())},t.addEventListener(`abort`,n,{once:!0})})]);if(t.aborted)throw Lt();return r}finally{n!==null&&t.removeEventListener(`abort`,n)}}function It(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 Lt(){return typeof DOMException==`function`?new DOMException(`The WebUI request was aborted.`,`AbortError`):Error(`The WebUI request was aborted.`)}function Rt(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 zt(e,t){let n=[...e.values()].sort((e,t)=>t.updated_at.localeCompare(e.updated_at)),r=n.filter(e=>!Bt(e)),i=n.filter(e=>Bt(e)&&Date.parse(e.updated_at)>t-36e5).slice(0,200);return new Map([...r,...i].map(e=>[e.operation_id,e]))}function Bt(e){return[`succeeded`,`failed`,`cancelled`].includes(e.state)}var Vt=`webui.ui-api.v1`;function Ht(){return{schemaVersion:Vt,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 Ut(e,t){return t.type===`login-start`?{...e,auth:{status:`authenticating`,tokenPresent:!0},connection:`bootstrapping`,error:null}:t.type===`login-success`?V(e,t.bootstrap,t.now):t.type===`logout`?{...Ht(),lastUpdatedAt:t.now}:t.type===`select-model`?{...e,selectedModelId:t.modelId,runtimeHistory:[]}:t.type===`catalog`?Wt(e,t.response,t.now):t.type===`operations-snapshot`?Gt(e,t.response,t.now):t.type===`operation`?Kt(e,t.operation,t.sequence,t.now):t.type===`runtime`?qt(e,t.runtime,t.sequence,t.now):t.type===`event`?Jt(e,t.event,t.now):t.type===`pending`?{...e,pendingReconciliations:nn(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 V(e,t,n){let r=t.server.server_instance_id;return e.serverInstanceId!==null&&e.serverInstanceId!==r?{...Ht(),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 Wt(e,t,n){if(e.serverInstanceId!==null&&t.server_instance_id!==e.serverInstanceId)return Qt(e,t.server_instance_id,n);if(e.catalogSequence!==null&&t.snapshot_sequenceo.has(e)))};return $t({...e,operations:o,serverInstanceId:t.server_instance_id,lastSequence:tn(s),error:null,resourceFences:s},n)}function Kt(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=zt(nn(e.operations,t.operation_id,t),r),o=n===null?e.resourceFences.operations:nn(e.resourceFences.operations,t.operation_id,n),s={...e.resourceFences,operations:new Map([...o].filter(([e])=>a.has(e)))};return $t({...e,operations:a,lastSequence:tn(s),error:null,resourceFences:s},r)}function qt(e,t,n,r){if(e.serverInstanceId!==null&&t.server_instance_id!==e.serverInstanceId)return Qt(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:nn(e.resourceFences.models,r,t.sequence)};return $t({...e,catalog:a,serverInstanceId:t.server_instance_id,lastEventId:t.event_id,lastSequence:tn(o),connection:`streaming`,resourceFences:o},n)}function Xt(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:nn(e.resourceFences.runtimes,r.model_id,t.sequence)};return $t({...e,runtimes:nn(e.runtimes,r.model_id,r),runtimeHistory:r.model_id===e.selectedModelId?Rt(e.runtimeHistory,r,n):e.runtimeHistory,serverInstanceId:t.server_instance_id,lastEventId:t.event_id,lastSequence:tn(a),connection:`streaming`,resourceFences:a},n)}function Zt(e,t,n){let r=t.type===`server_restart`?null:e.lastSuccessfulAt;return{...Ht(),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 Qt(e,t,n){return{...Ht(),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 $t(e,t){return{...e,lastUpdatedAt:t,lastSuccessfulAt:t}}function en(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 tn(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 nn(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 an=2e3,on=1e4,sn=3e4,cn=6e4,ln=6e4,un=new Set([`snapshot`,`model_revision`]),dn=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??_n,this.visibility=e.visibility??vn,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>=ln}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()})},on);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:pn(n),error:mn(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=fn(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:pn(n),error:mn(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:gn(`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:gn(`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 hn(`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>=cn&&(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 an}backoffDelay(){let e=Math.min(sn,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 fn(e){let t=tn(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 pn(e){if(e instanceof hn)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 mn(e){return e instanceof hn?{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 hn=class extends Error{code=`snapshot_mismatch`;constructor(e){super(e),this.name=`SnapshotConsistencyError`}};function gn(e,t,n){if(n.server_instance_id!==t.server_instance_id)throw new hn(`${e} pagination crossed a server restart; refresh the authoritative snapshot.`);if(n.snapshot_sequence!==t.snapshot_sequence)throw new hn(`${e} pagination crossed snapshot sequence boundaries; refresh the authoritative snapshot.`)}var _n={setTimeout:(e,t)=>globalThis.setTimeout(e,t),clearTimeout:e=>globalThis.clearTimeout(e),now:()=>Date.now()},vn={hidden:()=>typeof document<`u`&&document.hidden,subscribe:e=>typeof document>`u`?()=>void 0:(document.addEventListener(`visibilitychange`,e),()=>document.removeEventListener(`visibilitychange`,e))},yn=_.createContext(null),bn=_.createContext(null);function xn({children:e,apiBase:t,fetchImpl:n}){let[r,i]=_.useReducer(Ut,void 0,Ht),a=_.useRef(r);a.current=r;let o=_.useRef(0),s=_.useRef(null),c=_.useMemo(()=>new jt({apiBase:t,fetchImpl:n,onUnauthorized:()=>{o.current+=1,s.current?.stop(),i({type:`logout`,now:Date.now()})}}),[t,n]);_.useEffect(()=>{let e=new dn({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 kt)&&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)(bn.Provider,{value:l,children:(0,x.jsx)(yn.Provider,{value:r,children:e})})}function Sn(){let e=_.useContext(yn);if(e===null)throw Error(`useWebUi must be used within WebUiProvider.`);return e}function Cn(){let e=_.useContext(bn);if(e===null)throw Error(`useWebUiActions must be used within WebUiProvider.`);return e}var wn=Object.freeze({}),Tn=[`max_tokens`,`temperature`,`top_p`,`top_k`,`min_p`,`repetition_penalty`,`seed`];function En(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(!Tn.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 Dn=wn,On=new Set;function kn(e){return On.add(e),()=>On.delete(e)}function An(e){Dn=En(e);for(let e of On)e()}function jn(){An(wn)}function Mn(){return{defaults:(0,_.useSyncExternalStore)(kn,()=>Dn,()=>wn),setDefaults:An,reset:jn}}function Nn(e,t,n){return e===null||e<=0||t===null||n===void 0?`unknown`:t+n>e?`exceeds`:`raw-fits`}function Pn({modelId:e,nCtx:t,locale:n}){let r=Cn(),{defaults:i}=Mn(),[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=Nn(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)(Ce,{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 Fn(e){return e instanceof kt?e.status===401?`wrong-key`:e.status===403?`forbidden`:`generic`:e instanceof $e||e instanceof Error&&e.name===`ValidationError`?`schema`:e instanceof TypeError||e instanceof Error&&/fetch|network|offline|connection/i.test(e.message)?`offline`:`generic`}function In(e,t){let n=Kn(t);return n===null?R(e,`model.selected.none`):`${n.identity.display_name} · ${qn(e,n.lifecycle.state)}`}function Ln(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,sequence:Jn(e,t),status:Rn(e,t.connection)})}function Rn(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 zn(e){return e.snapshot.auth.status===`authenticated`?e.snapshot.connection===`schema-mismatch`?(0,x.jsx)(Hn,{...e}):(0,x.jsx)(Vn,{...e}):(0,x.jsx)(Bn,{...e})}function Bn(e){return e.authFailure===`schema`?(0,x.jsx)(Hn,{...e}):(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsxs)(`section`,{className:`screen-heading connection-prompt`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:e.eyebrow}),(0,x.jsx)(`h1`,{"data-testid":e.titleTestId,children:e.title}),(0,x.jsx)(`p`,{"data-testid":z(`connection.prompt.body`),children:R(e.locale,`connection.prompt.body`)})]}),(0,x.jsx)(Ne,{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:Gn(e.locale,e.authFailure),busy:e.snapshot.auth.status===`authenticating`,onSubmit:e.onLogin,onLogout:e.onLogout,testId:z(`auth.login`)})]})}function Vn(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.jsxs)(`section`,{className:`screen-heading connection-prompt`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:e.eyebrow}),(0,x.jsx)(`h1`,{"data-testid":e.titleTestId,children:e.title}),(0,x.jsx)(`p`,{"data-testid":z(`connection.authenticated.body`),children:R(e.locale,`connection.authenticated.body`)})]}),(0,x.jsx)(B,{tone:`info`,title:R(e.locale,`connection.authenticated.title`),body:Un(e.locale,e.snapshot),testId:z(`connection.authenticated.detail`)}),t?(0,x.jsx)(B,{title:R(e.locale,`connection.error.title`),body:Wn(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 Hn(e){return(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsxs)(`section`,{className:`screen-heading connection-prompt`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:e.eyebrow}),(0,x.jsx)(`h1`,{"data-testid":e.titleTestId,children:e.title})]}),(0,x.jsx)(Pe,{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 Un(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:Rn(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:Jn(e,t)})}function Wn(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 Gn(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 Kn(e){return e.selectedModelId===null?null:e.catalog.find(t=>t.identity.id===e.selectedModelId)??null}function qn(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 Jn(e,t){return String(t.lastSequence??t.catalogSequence??t.resourceFences.operationsSnapshot??R(e,`connection.snapshot.pending`))}function Yn({locale:e}){let{defaults:t,setDefaults:n,reset:r}=Mn(),[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:Tn.map(n=>(0,x.jsx)(Ce,{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)(B,{title:R(e,`settings.generation.error_title`),body:o}):null,(0,x.jsxs)(`div`,{children:[(0,x.jsx)(N,{onClick:()=>{try{n(En(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)(Ce,{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)(Ee,{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 Xn({modelId:e,locale:t}){let n=Cn(),[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]=Be(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:Ve(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)(B,{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)(Ce,{label:e.name,value:a[e.name]??Ve(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)(Ce,{label:e.name,value:Ve(e,r.current[e.name]),disabled:!0,hint:e.reason??e.help},e.name))]}),(0,x.jsxs)(Ee,{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,Ve(e,e.default)]))),c({}),m(!1)},children:R(t,`settings.live.reset.confirm`)})]})]})}var Zn=[`fp16`,`float16`,`int8`,`i8`,`turbo4-asym`,`fp16+turbo4`,`turbo3-asym`,`fp16+turbo3`,`turbo3`,`turbo4`,`turbo4-sym`,`turbo4-delegated`,`fp16+turbo4-delegated`],Qn=Object.freeze({});function $n(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`||!Zn.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 er(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:$n(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]=$n(t)}return{version:1,reusable:$n(n.reusable),models:r}}var tr=`mlxcel.webui.load-profiles.v1`,nr={version:1,reusable:Qn,models:{}},rr=!1,ir=new Set;function ar(e){return ir.add(e),()=>ir.delete(e)}function or(){if(!rr){rr=!0;try{let e=localStorage.getItem(tr);e!==null&&(nr=er(e))}catch{}}}function sr(e){let t=JSON.stringify(e),n=er(t);localStorage.setItem(tr,t),nr=n;for(let e of ir)e()}function cr(e){or();let t=(0,_.useSyncExternalStore)(ar,()=>nr);return{reusable:t.reusable,modelProfile:e===null?Qn:t.models[e]??Qn,profile:e!==null&&Object.hasOwn(t.models,e)?t.models[e]:t.reusable,save:(t,n)=>{let r=$n(t);if(n===`model`&&e===null)throw Error(`Select a model first.`);sr(n===`reusable`?{...nr,reusable:r}:{...nr,models:{...nr.models,[e]:r}})},reset:(t=e===null?`reusable`:`model`)=>{let n=Object.fromEntries(Object.entries(nr.models).filter(([t])=>t!==e));sr(t===`reusable`?{...nr,reusable:Qn}:{...nr,models:n})},exportJson:()=>JSON.stringify(nr,null,2),importJson:e=>sr(er(e))}}function lr(e){let t=$n(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=cr(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)(B,{tone:`info`,title:R(t,`settings.profile.single.title`),body:R(t,`settings.profile.single.body`)}):null,(0,x.jsx)(Se,{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)(Ce,{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)(Ce,{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)(Se,{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`)},...Zn.map(e=>({value:e,label:e}))]})]}),(0,x.jsx)(`p`,{children:R(t,`settings.profile.restrictions`)}),u?(0,x.jsx)(B,{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($n(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:lr(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)(Ee,{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 dr({locale:e}){let t=Sn(),n=Cn(),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)(Yn,{locale:e}),o?(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(Se,{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} · ${qn(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)(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:R(e,`settings.server.context.title`)}),(0,x.jsx)(Ce,{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)(Ce,{label:R(e,`settings.server.context.slots`),value:i?.totalSlots?.toString()??c,disabled:!0}),(0,x.jsx)(Ce,{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)(Pn,{modelId:s,nCtx:i?.nCtx??null,locale:e},s)]}),s===null?(0,x.jsx)(B,{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)(Xn,{modelId:s,locale:e},s):(0,x.jsx)(B,{tone:`info`,title:R(e,`settings.server.live_disabled.title`),body:R(e,`settings.server.live_disabled.body`)})]}):(0,x.jsx)(B,{tone:`warning`,title:R(e,`settings.server.unavailable.title`),body:R(e,`settings.server.unavailable.body`)})]})}var fr=[{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 pr(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]`);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)},[]);let o=n=>{let r=fr[(fr.findIndex(t=>t.id===e.route)+n+fr.length)%fr.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)(mr,{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)(Oe,{open:i,title:R(e.locale,`nav.primary`),onClose:()=>a(!1),closeLabel:R(e.locale,`common.close`),testId:`mobile-nav-sheet`,children:(0,x.jsx)(mr,{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`,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:()=>a(!0),"data-testid":z(`toolbar.menu`)}),(0,x.jsxs)(`div`,{className:`toolbar-title`,children:[(0,x.jsx)(`p`,{id:`app-title`,"data-testid":z(`app.title`),children:R(e.locale,`app.title`)}),(0,x.jsx)(`span`,{"data-testid":z(`app.subtitle`),children:R(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)(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)(`section`,{className:`app-content`,children:e.children}),e.inspector]})]})]})}var mr=_.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:fr.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.jsx)(`span`,{className:`connection-dot`,"data-state":e.connectionState,"aria-hidden":`true`}),(0,x.jsx)(`span`,{"data-testid":z(`connection.ready`),children:e.connectionLabel})]})]}));mr.displayName=`Sidebar`;var hr=[`mlxcel`,`glass`],gr=[`light`,`dark`],_r=[`system`,`light`,`dark`],vr=`mlxcel`,yr=`system`;hr.flatMap(e=>gr.map(t=>`${e}-${t}`));var br=`(prefers-color-scheme: dark)`;function xr(e){return typeof e==`string`&&hr.includes(e)}function Sr(e){return typeof e==`string`&&_r.includes(e)}function Cr(e,t){return`${e}-${t}`}function wr(){try{return typeof window>`u`||typeof window.matchMedia!=`function`?`light`:window.matchMedia(`(prefers-color-scheme: dark)`).matches?`dark`:`light`}catch{return`light`}}function Tr(e,t=wr()){return e===`system`?t:e}function Er(e,t,n=wr()){let r=Tr(t,n);return{id:Cr(e,r),family:e,scheme:r,preference:t}}function Dr(e){if(typeof window>`u`||typeof window.matchMedia!=`function`)return()=>void 0;let t;try{t=window.matchMedia(br)}catch{return()=>void 0}let n=t=>e(t.matches?`dark`:`light`);return t.addEventListener(`change`,n),()=>t.removeEventListener(`change`,n)}var Or={themeFamily:vr,colorScheme:yr,material:`glass`,glassIntensity:35,reduceMotion:!1,reduceTransparency:!1,highContrast:`system`,locale:`en`},kr=`mlxcel.webui.appearance`;function Ar(e){let t=typeof e==`number`&&Number.isFinite(e)?e:Or.glassIntensity;return Math.max(0,Math.min(100,Math.round(t)))}function jr(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Mr(e){return e===`glass`||e===`tinted`||e===`opaque`}function Nr(e){return e===`system`||e===`on`||e===`off`}function Pr(e){return Nr(e)?e:e===!0?`on`:e===!1?`off`:Or.highContrast}function Fr(e){return Sr(e.colorScheme)?e.colorScheme:e.colorScheme===void 0&&Sr(e.theme)?e.theme:Or.colorScheme}function Ir(e){return e===`en`||e===`ko`}function Lr(){if(typeof window>`u`)return Or;let e;try{e=window.localStorage.getItem(kr)}catch{return Or}if(!e)return Or;try{let t=JSON.parse(e);return jr(t)?{themeFamily:xr(t.themeFamily)?t.themeFamily:Or.themeFamily,colorScheme:Fr(t),material:Mr(t.material)?t.material:Or.material,glassIntensity:Ar(t.glassIntensity),reduceMotion:t.reduceMotion===!0,reduceTransparency:t.reduceTransparency===!0,highContrast:Pr(t.highContrast),locale:Ir(t.locale)?t.locale:Or.locale}:Or}catch{return Or}}function Rr(e){try{window.localStorage.setItem(kr,JSON.stringify(e))}catch{}}function zr(){return typeof CSS>`u`||typeof CSS.supports!=`function`?!1:CSS.supports(`backdrop-filter: blur(1px)`)||CSS.supports(`-webkit-backdrop-filter: blur(1px)`)}function Br(e,t,n=wr()){let r=Er(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(Ar(t.glassIntensity)),e.dataset.reduceMotion=String(t.reduceMotion),e.dataset.reduceTransparency=String(t.reduceTransparency),e.dataset.highContrast=t.highContrast,e.dataset.backdropFilter=zr()?`supported`:`unsupported`,e.lang=t.locale}function Vr(e){return e.value===null||!Number.isFinite(e.value)?`N/A`:`${new Intl.NumberFormat(void 0,{maximumFractionDigits:2}).format(e.value)} ${e.unit}`}function Hr(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 Ur(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 Wr(e){let t=URL.createObjectURL(new Blob([Ur(e)],{type:`application/json`})),n=document.createElement(`a`);n.href=t,n.download=`mlxcel-diagnostics.json`,n.click(),URL.revokeObjectURL(t)}function Gr({operations:e,locale:t,stale:n}){let r=[...e.values()].sort((e,t)=>Number(Bt(e))-Number(Bt(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=>!Bt(e)).length),failed:String(r.filter(e=>e.state===`failed`).length)})}),(0,x.jsx)(`p`,{children:R(t,`activity.session`)}),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)(Kr,{operation:e,locale:t,stale:n})},e.operation_id))})]})}function Kr({operation:e,locale:t,stale:n}){let r=Cn(),i=Sn(),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=Bt(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:Hr(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)(B,{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)(B,{title:R(t,`activity.cancel_failed`),body:R(t,`activity.refresh`)}):null]})}var qr=new Set(be.map(e=>e.key).filter(e=>e.startsWith(`activity.metric.`))),Jr=e=>qr.has(e);function Yr({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 Jr(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)(B,{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.jsxs)(`dl`,{className:`activity-metric`,children:[(0,x.jsx)(`dt`,{children:s(e)}),(0,x.jsx)(`dd`,{children:Vr(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.jsxs)(`dl`,{className:`activity-metric`,children:[(0,x.jsx)(`dt`,{children:s(e)}),(0,x.jsx)(`dd`,{children:Vr(n)}),(0,x.jsxs)(`dd`,{children:[R(t,`activity.scope`),`: `,n.scope]}),(0,x.jsxs)(`dd`,{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)(`dd`,{children:n.reason})]},e))})]})]})}var Xr=(function(){let e=typeof document<`u`&&document.createElement(`link`).relList;return e&&e.supports&&e.supports(`modulepreload`)?`modulepreload`:`preload`})(),Zr=function(e,t){return new URL(e,t).href},Qr={},$r=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=Zr(t,n),t=s(t),t in Qr)return;Qr[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`:Xr,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)})},ei=(0,_.lazy)(()=>$r(()=>import(`./history-D3yl7FGt.js`),[],import.meta.url));function ti({locale:e}){let t=Sn(),n=Cn(),[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":z(`activity.title`),children:R(e,`activity.title`)}),(0,x.jsx)(`p`,{children:R(e,`activity.intro`)}),(0,x.jsxs)(`p`,{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)(Se,{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.jsxs)(`div`,{className:`activity-toolbar`,children:[(0,x.jsx)(N,{onClick:()=>{n.refresh()},children:R(e,`activity.refresh`)}),(0,x.jsx)(N,{onClick:()=>Wr(t),children:R(e,`activity.export`)})]}),a?(0,x.jsx)(B,{tone:`warning`,title:R(e,`activity.stale`),body:R(e,`activity.refresh`)}):null,(0,x.jsx)(Gr,{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)(Yr,{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)(ei,{samples:t.runtimeHistory,locale:e})}):null]})}var ni=e=>[`succeeded`,`failed`,`cancelled`].includes(e.state),ri=e=>e.auth.status===`authenticated`&&e.bootstrap!==null&&e.catalogSequence!==null&&[`ready`,`streaming`,`polling`].includes(e.connection);function ii(e,t){return ri(e)&&e.bootstrap?.actions[t]?.state===`enabled`}function ai(e,t){return[...e.operations.values()].some(e=>!ni(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 oi(e,t){return ii(e,`load`)&&t.supported&&t.complete&&t.metadata.support.runnable_on_backend&&!t.lifecycle.busy&&[`unloaded`,`failed`].includes(t.lifecycle.state)&&!ai(e,t.identity.id)}function si(e,t){return ii(e,`unload`)&&t.lifecycle.state===`ready`&&!ai(e,t.identity.id)}function ci(e,t){return ii(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)&&!ai(e,t.identity.id)}function li(e,t){return ri(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&&si(e,n)&&!n.lifecycle.busy&&n.lifecycle.active_requests===0&&n.lifecycle.draining_requests===0)}function di(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 fi(e,t){return e instanceof kt?e.envelope?.error.code===`stale_revision`?R(t,`models.library.stale`):e.message:R(t,`models.library.pending`)}function pi(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 mi(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 hi(e){return e.length===0||e.length<=128&&e.split(`/`).every(e=>e!==`.`&&e!==`..`&&/^[A-Za-z0-9._~+-]+$/.test(e))}function gi({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=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)(Ee,{open:!0,title:f,onClose:i,closeLabel:R(n,`common.close`),testId:`models-confirm`,children:[(0,x.jsx)(`p`,{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)(Ce,{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`,{children:[e.identity.display_name,` · `,e.lifecycle.state,` · `,R(n,`models.library.active`),`:`,` `,e.lifecycle.active_requests]},e.identity.id))}),(0,x.jsx)(Se,{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 _i({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=mi(s.trim())&&hi(l.trim());return(0,x.jsx)(Ee,{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)(Ce,{label:R(e,`models.library.repo`),value:s,onChange:c,testId:`models-repo`,error:s&&!mi(s.trim())?R(e,`models.library.repo_invalid`):void 0}),(0,x.jsx)(Ce,{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 vi({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 yi({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`),di(s.disk_bytes,r)],[R(r,`models.library.memory`),di(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)(Ae,{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:qn(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)(vi,{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||!oi(n,e),onClick:()=>a(`load`),children:R(r,`models.load`)}),(0,x.jsx)(N,{"data-testid":`models-use-chat`,disabled:i||!li(n,e),onClick:o,children:R(r,`models.library.chat`)}),(0,x.jsx)(N,{"data-testid":`models-unload`,disabled:i||!si(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||!ci(n,e),onClick:()=>a(`delete`),children:R(r,`models.library.delete`)}):null]}),li(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 bi({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(ni(e))-Number(ni(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:Si(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:`${di(s.progress.completed_bytes,t)} / ${di(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===xi(s)&&oi(e,t)),onClick:()=>o(xi(s)),children:R(t,`models.library.capacity`)}):null,s.kind===`download`&&!ni(s)?(0,x.jsx)(N,{disabled:n||!ri(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||!ii(e,`download`),onClick:()=>a(s),children:R(t,`models.library.retry_download`)}):null]})]})},s.operation_id))})]})}function xi(e){return e.target.target_kind===`model`?e.target.model_id:``}function Si(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 Ci=25;function wi({locale:e}){let t=Sn(),n=Cn(),[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}=cr(y?.identity.id??null),{profile:S}=cr(f?.kind===`capacity`?f.entry.identity.id:null),C=pi(t.catalog,r),w=Math.max(1,Math.ceil(C.length/Ci)),T=Math.min(a,w-1),E=[...t.operations.values()].some(e=>e.kind===`download`&&!ni(e))||[...t.pendingReconciliations.values()].some(e=>e.kind===`download`),D=[...t.operations.values()].some(e=>e.kind===`catalog_refresh`&&!ni(e))||[...t.pendingReconciliations.values()].some(e=>e.kind===`catalog-refresh`),O=e=>{i({...r,...e}),o(0)},k=async(n,r)=>{if(l.current||!ri(t))return!1;l.current=!0,c(!0),d(null);try{return await n(),!0}catch(t){return d(fi(t,e)),r?.(t),!1}finally{l.current=!1,c(!1)}},ee=(r,i,a=b)=>{if(!oi(t,r)){d(R(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(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 kt&&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||ni(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(!ui(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`&&si(t,o)?k(()=>n.unloadModel({action:`unload`,model_id:o.identity.id,expected_revision:o.identity.revision,idempotency_key:crypto.randomUUID()})):a.kind===`delete`&&ci(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`,"aria-label":R(e,`models.library.inspect`,{name:r.identity.display_name}),onClick:()=>n.selectModel(r.identity.id),children:r.identity.display_name}),r.identity.id===t.selectedModelId?(0,x.jsx)(`small`,{children:R(e,`models.library.selected`)}):null,(0,x.jsxs)(`p`,{children:[r.identity.source,` · `,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:qn(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.jsxs)(`section`,{className:`screen-heading`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:R(e,`routes.models.eyebrow`)}),(0,x.jsx)(`h1`,{tabIndex:-1,"data-dialog-focus-fallback":!0,"data-testid":z(`models.title`),children:R(e,`models.title`)}),(0,x.jsx)(`p`,{children:R(e,`models.library.subtitle`)})]}),ri(t)?null:(0,x.jsx)(B,{title:R(e,`models.library.stale`),body:t.error?.message??R(e,`models.library.waiting`),action:(0,x.jsx)(N,{onClick:()=>{n.refresh()},children:R(e,`models.library.refresh`)}),testId:`connection-error-title`}),u?(0,x.jsx)(B,{title:R(e,`models.library.error`),body:u,action:(0,x.jsx)(N,{onClick:()=>{d(null),n.refresh()},children:R(e,`models.library.refresh`)}),testId:`models-action-error`}):null,t.bootstrap?.server.mode===`single_model`?(0,x.jsx)(B,{tone:`info`,title:R(e,`models.library.single`),body:`mlxcel-server --webui`,testId:`models-read-only`}):null,(0,x.jsxs)(`div`,{className:`button-row`,children:[(0,x.jsx)(N,{tone:`primary`,onClick:()=>h({repo:``,revision:``}),disabled:s||E||!ii(t,`download`),"data-testid":`models-add`,children:R(e,`models.library.add`)}),(0,x.jsx)(N,{disabled:s||D||!ri(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`)})]}),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:Un(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)(Ce,{label:R(e,`models.library.search`),value:r.query,onChange:e=>O({query:e}),testId:`models-search`}),(0,x.jsx)(Se,{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)(Se,{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)(Se,{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:qn(e,t)}))]}),(0,x.jsx)(Se,{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)(he,{columns:M,rows:C.slice(T*Ci,(T+1)*Ci),getRowKey:e=>e.identity.id,ariaLabel:R(e,`models.title`),testId:`models-table`,rowClassName:e=>e.identity.id===t.selectedModelId?`models-selected`:void 0,loading:t.catalogSequence===null,loadingState:(0,x.jsx)(`p`,{role:`status`,children: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)(yi,{entry:y,profile:b,state:t,locale:e,busy:s,onAction:A,onChat:()=>{li(t,y)&&(n.selectModel(y.identity.id),window.location.hash=`chat`)}}):null]}),(0,x.jsx)(bi,{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&&oi(t,n)&&p({kind:`capacity`,entry:n,instance:t.serverInstanceId})}}),f?(0,x.jsx)(gi,{value:f,state:t,locale:e,busy:s,onClose:()=>p(null),onConfirm:te},f.kind):null,m?(0,x.jsx)(_i,{locale:e,state:t,initial:m,error:u,busy:s||E||!ii(t,`download`),onClose:()=>h(null),onDownload:(e,r)=>{ii(t,`download`)&&!E&&k(()=>n.downloadModel({repo_id:e,revision:r||null,idempotency_key:crypto.randomUUID()})).then(e=>{e&&h(null)})}}):null]})}var Ti={en:`en-US`,ko:`ko-KR`},Ei=e=>Ti[e];function Di(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)(ji,{locale:e.locale})},{id:`data`,label:R(e.locale,`gallery.tab.data`),panel:(0,x.jsx)(Mi,{locale:e.locale})}]}),(0,x.jsxs)(Ee,{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)(Ce,{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 Ai(e){return(0,x.jsxs)(`div`,{className:`gallery-grid`,children:[(0,x.jsxs)(`article`,{className:`surface-card`,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)(Ce,{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)(Se,{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)(`article`,{className:`surface-card`,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)(ke,{label: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 ji(e){return(0,x.jsxs)(`div`,{className:`gallery-grid`,children:[(0,x.jsx)(Ne,{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)(Pe,{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)(B,{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:Di(67108864,e.locale)})}),(0,x.jsx)(fe,{label:R(e.locale,`gallery.progress.measured`),value:37})]}),(0,x.jsxs)(Me,{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 Mi(e){return(0,x.jsxs)(`div`,{className:`gallery-grid dense-gallery`,children:[(0,x.jsxs)(`article`,{className:`surface-card table-card`,tabIndex:0,"aria-label":R(e.locale,`gallery.sample.caption`),children:[(0,x.jsx)(`h2`,{children:R(e.locale,`gallery.data.title`)}),(0,x.jsxs)(je,{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:Oi(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:Oi(null,e.locale)})]})]})]})]}),(0,x.jsxs)(Ae,{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`)})]})]})}var Ni={count:4,bytes:8388608,dimension:4096,pixels:16e6},Pi=new Set([`image/png`,`image/jpeg`,`image/webp`]);function Fi(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 +`,$e=class extends Error{path;constructor(e,t){super(`${e}: ${t}`),this.path=e,this.name=`ValidationError`}},et=rt(Qe);function tt(e,t,n=`$`){let r=ht(et,[`components`,`schemas`],`#/components/schemas`)[e];if(r===void 0)throw new $e(n,`unknown schema ${e}`);it(r,t,n)}function nt(e){return JSON.parse(e)}function rt(e){return mt(nt(e),`$contract`)}function it(e,t,n){let r=mt(e,`${n}#schema`);if(typeof r.$ref==`string`){it(ft(r.$ref),t,n);return}if(r.anyOf!==void 0){if(!Array.isArray(r.anyOf)||!r.anyOf.some(e=>pt(e,t,n)))throw new $e(n,`did not match any allowed schema`);return}if(r.oneOf!==void 0){if(!Array.isArray(r.oneOf))throw new $e(n,`schema oneOf must be an array`);let e=r.oneOf.filter(e=>pt(e,t,n)).length;if(e!==1)throw new $e(n,`matched ${e} oneOf schemas`);return}if(r.const!==void 0&&t!==r.const)throw new $e(n,`expected constant ${String(r.const)}`);if(Array.isArray(r.enum)&&!r.enum.some(e=>e===t))throw new $e(n,`unexpected enum value ${String(t)}`);let i=r.type;if(Array.isArray(i)){if(!i.some(e=>dt(e,t)))throw new $e(n,`expected one of ${i.join(`, `)}`)}else if(typeof i==`string`&&!dt(i,t))throw new $e(n,`expected ${i}`);typeof t==`string`&&ct(r,t,n),typeof t==`number`&&ut(r,t,n),Array.isArray(t)&&ot(r,t,n),gt(t)&&at(r,t,n)}function at(e,t,n){let r=_t(e.required,`${n}#schema.required`,!1),i=e.properties===void 0?{}:mt(e.properties,`${n}#schema.properties`);for(let e of r)if(!(e in t))throw new $e(`${n}.${e}`,`missing required property`);if(e.maxProperties!==void 0&&Object.keys(t).length>vt(e.maxProperties,`${n}#schema.maxProperties`))throw new $e(n,`too many object properties`);for(let[r,a]of Object.entries(t)){let t=i[r];if(t!==void 0)it(t,a,`${n}.${r}`);else if(e.additionalProperties===!1)throw new $e(`${n}.${r}`,`unexpected property`);else gt(e.additionalProperties)&&it(e.additionalProperties,a,`${n}.${r}`)}}function ot(e,t,n){if(e.minItems!==void 0&&t.lengthvt(e.maxItems,`${n}#schema.maxItems`))throw new $e(n,`array longer than maximum`);e.items!==void 0&&t.forEach((t,r)=>it(e.items,t,`${n}[${r}]`))}function st(e){let t=0;for(let n=0;n65535?2:1;return t}function ct(e,t,n){let r=st(t);if(e.minLength!==void 0&&rvt(e.maxLength,`${n}#schema.maxLength`))throw new $e(n,`string longer than maximum`);if(typeof e.pattern==`string`&&!new RegExp(e.pattern,`u`).test(t))throw new $e(n,`string does not match pattern`);if(e.format===`date-time`&&!lt(t))throw new $e(n,`invalid RFC3339 date-time`)}function lt(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 ut(e,t,n){if(!Number.isFinite(t))throw new $e(n,`expected finite number`);if(e.type===`integer`&&!Number.isInteger(t))throw new $e(n,`expected integer`);if(e.minimum!==void 0&&tvt(e.maximum,`${n}#schema.maximum`))throw new $e(n,`number above maximum`)}function dt(e,t){return e===`null`?t===null:e===`array`?Array.isArray(t):e===`object`?gt(t):e===`integer`?typeof t==`number`&&Number.isInteger(t):e===`number`?typeof t==`number`&&Number.isFinite(t):typeof t===e}function ft(e){if(!e.startsWith(`#/`))throw new $e(`$ref`,`unsupported external ref ${e}`);return e.slice(2).split(`/`).map(e=>e.replace(/~1/g,`/`).replace(/~0/g,`~`)).reduce((t,n)=>mt(t,e)[n],et)}function pt(e,t,n){try{return it(e,t,n),!0}catch(e){if(e instanceof $e)return!1;throw e}}function mt(e,t){if(!gt(e))throw new $e(t,`expected object`);return e}function ht(e,t,n){return t.reduce((e,t)=>mt(e,n)[t],e)}function gt(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function _t(e,t,n){if(e===void 0&&!n)return[];if(!Array.isArray(e)||!e.every(e=>typeof e==`string`))throw new $e(t,`expected string array`);return e}function vt(e,t){if(typeof e!=`number`||!Number.isFinite(e))throw new $e(t,`expected numeric schema bound`);return e}function yt(e,t,n){return tt(e,t,n),t}function bt(e,t=`$`){return yt(`ErrorEnvelope`,e,t)}function xt(e,t=`$`){return yt(`BootstrapResponse`,e,t)}function St(e,t=`$`){return yt(`CatalogEntry`,e,t)}function Ct(e,t=`$`){return yt(`CatalogListResponse`,e,t)}function wt(e,t=`$`){return yt(`OperationsListResponse`,e,t)}function Tt(e,t=`$`){return yt(`Operation`,e,t)}function Et(e,t=`$`){return yt(`OperationAccepted`,e,t)}function Dt(e,t=`$`){return yt(`RuntimeSnapshot`,e,t)}function Ot(e,t=`$`){return yt(`UiEvent`,e,t)}var kt=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`}},At=2097152,jt=class{apiBase;fetchImpl;bearerToken=null;onUnauthorized;controllers=new Set;constructor(e={}){this.apiBase=qe(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`,xt,{method:`GET`,signal:e})}async catalog(e={},t){return this.request(`/ui-api/v1/catalog`,Ct,{method:`GET`,query:{...e},signal:t})}async catalogEntry(e,t){return this.request(`/ui-api/v1/catalog/${Ze(e)}`,St,{method:`GET`,signal:t})}async refreshCatalog(e,t){return this.request(`/ui-api/v1/catalog/refresh`,Et,{method:`POST`,body:{idempotency_key:e},signal:t})}async modelAction(e,t){return this.request(`/ui-api/v1/model-actions`,Et,{method:`POST`,body:e,signal:t})}async download(e,t){return this.request(`/ui-api/v1/downloads`,Et,{method:`POST`,body:e,signal:t})}async removeModel(e,t){return this.request(`/ui-api/v1/model-removals`,Et,{method:`POST`,body:e,signal:t})}async operationsPage(e={},t){return this.request(`/ui-api/v1/operations`,wt,{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/${Ze(e)}`,Tt,{method:`GET`,signal:t})}async cancelOperation(e,t){return this.request(`/ui-api/v1/operations/${Ze(e)}/cancel`,Et,{method:`POST`,body:{},signal:t})}async runtime(e,t){let n=await this.request(`/ui-api/v1/runtime`,Dt,{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`,He,{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`,Le,{method:`GET`,query:{model:e,autoload:!1},signal:t})}async patchSettings(e,t,n){return this.request(`/settings`,Re,{method:`PATCH`,query:{model:e,autoload:!1},body:{op:`merge`,values:t},signal:n})}async modelProps(e,t){return this.request(`/props`,ze,{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(Xe(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(Ot(nt(t.data)))}})}async chatCompletions(e,t,n,r){await this.sse(Xe(this.apiBase,`/v1/chat/completions`,{autoload:!1}),{method:`POST`,body:Pt(t,e),signal:r,headers:{Accept:`text/event-stream`}},n)}async responses(e,t,n,r){await this.sse(Xe(this.apiBase,`/v1/responses`,{autoload:!1}),{method:`POST`,body:Pt(t,e),signal:r,headers:{Accept:`text/event-stream`}},n)}async request(e,t,n){let r=await this.fetchWithAuth(Xe(this.apiBase,e,n.query),n);try{return r.response.ok||await this.throwHttp(r.response,r.signal),t(nt(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 We({onDone:n.onDone,onMessage:n.onFrame}),i=e.body.getReader();try{for(;;){let e=await Ft(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}=It(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=bt(nt(n)))}catch{r=null}throw new kt(e.status,Mt(r,n),Nt(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 Ft(n,t);if(e.done)break;if(i+=e.value.byteLength,i>At)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 Mt(e,t){return e===null?null:{...e,error:{...e.error,message:Nt(e.error.message,t),field_errors:e.error.field_errors?.map(e=>({...e,message:Nt(e.message,t)}))}}}function Nt(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 Pt(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 Ft(e,t){if(t.aborted)throw await e.cancel().catch(()=>void 0),Lt();let n=null;try{let r=await Promise.race([e.read(),new Promise((r,i)=>{n=()=>{e.cancel().catch(()=>void 0),i(Lt())},t.addEventListener(`abort`,n,{once:!0})})]);if(t.aborted)throw Lt();return r}finally{n!==null&&t.removeEventListener(`abort`,n)}}function It(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 Lt(){return typeof DOMException==`function`?new DOMException(`The WebUI request was aborted.`,`AbortError`):Error(`The WebUI request was aborted.`)}function Rt(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 zt(e,t){let n=[...e.values()].sort((e,t)=>t.updated_at.localeCompare(e.updated_at)),r=n.filter(e=>!Bt(e)),i=n.filter(e=>Bt(e)&&Date.parse(e.updated_at)>t-36e5).slice(0,200);return new Map([...r,...i].map(e=>[e.operation_id,e]))}function Bt(e){return[`succeeded`,`failed`,`cancelled`].includes(e.state)}var Vt=`webui.ui-api.v1`;function Ht(){return{schemaVersion:Vt,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 Ut(e,t){return t.type===`login-start`?{...e,auth:{status:`authenticating`,tokenPresent:!0},connection:`bootstrapping`,error:null}:t.type===`login-success`?V(e,t.bootstrap,t.now):t.type===`logout`?{...Ht(),lastUpdatedAt:t.now}:t.type===`select-model`?{...e,selectedModelId:t.modelId,runtimeHistory:[]}:t.type===`catalog`?Wt(e,t.response,t.now):t.type===`operations-snapshot`?Gt(e,t.response,t.now):t.type===`operation`?Kt(e,t.operation,t.sequence,t.now):t.type===`runtime`?qt(e,t.runtime,t.sequence,t.now):t.type===`event`?Jt(e,t.event,t.now):t.type===`pending`?{...e,pendingReconciliations:nn(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 V(e,t,n){let r=t.server.server_instance_id;return e.serverInstanceId!==null&&e.serverInstanceId!==r?{...Ht(),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 Wt(e,t,n){if(e.serverInstanceId!==null&&t.server_instance_id!==e.serverInstanceId)return Qt(e,t.server_instance_id,n);if(e.catalogSequence!==null&&t.snapshot_sequenceo.has(e)))};return $t({...e,operations:o,serverInstanceId:t.server_instance_id,lastSequence:tn(s),error:null,resourceFences:s},n)}function Kt(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=zt(nn(e.operations,t.operation_id,t),r),o=n===null?e.resourceFences.operations:nn(e.resourceFences.operations,t.operation_id,n),s={...e.resourceFences,operations:new Map([...o].filter(([e])=>a.has(e)))};return $t({...e,operations:a,lastSequence:tn(s),error:null,resourceFences:s},r)}function qt(e,t,n,r){if(e.serverInstanceId!==null&&t.server_instance_id!==e.serverInstanceId)return Qt(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:nn(e.resourceFences.models,r,t.sequence)};return $t({...e,catalog:a,serverInstanceId:t.server_instance_id,lastEventId:t.event_id,lastSequence:tn(o),connection:`streaming`,resourceFences:o},n)}function Xt(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:nn(e.resourceFences.runtimes,r.model_id,t.sequence)};return $t({...e,runtimes:nn(e.runtimes,r.model_id,r),runtimeHistory:r.model_id===e.selectedModelId?Rt(e.runtimeHistory,r,n):e.runtimeHistory,serverInstanceId:t.server_instance_id,lastEventId:t.event_id,lastSequence:tn(a),connection:`streaming`,resourceFences:a},n)}function Zt(e,t,n){let r=t.type===`server_restart`?null:e.lastSuccessfulAt;return{...Ht(),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 Qt(e,t,n){return{...Ht(),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 $t(e,t){return{...e,lastUpdatedAt:t,lastSuccessfulAt:t}}function en(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 tn(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 nn(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 an=2e3,on=1e4,sn=3e4,cn=6e4,ln=6e4,un=new Set([`snapshot`,`model_revision`]),dn=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??_n,this.visibility=e.visibility??vn,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>=ln}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()})},on);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:pn(n),error:mn(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=fn(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:pn(n),error:mn(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:gn(`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:gn(`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 hn(`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>=cn&&(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 an}backoffDelay(){let e=Math.min(sn,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 fn(e){let t=tn(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 pn(e){if(e instanceof hn)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 mn(e){return e instanceof hn?{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 hn=class extends Error{code=`snapshot_mismatch`;constructor(e){super(e),this.name=`SnapshotConsistencyError`}};function gn(e,t,n){if(n.server_instance_id!==t.server_instance_id)throw new hn(`${e} pagination crossed a server restart; refresh the authoritative snapshot.`);if(n.snapshot_sequence!==t.snapshot_sequence)throw new hn(`${e} pagination crossed snapshot sequence boundaries; refresh the authoritative snapshot.`)}var _n={setTimeout:(e,t)=>globalThis.setTimeout(e,t),clearTimeout:e=>globalThis.clearTimeout(e),now:()=>Date.now()},vn={hidden:()=>typeof document<`u`&&document.hidden,subscribe:e=>typeof document>`u`?()=>void 0:(document.addEventListener(`visibilitychange`,e),()=>document.removeEventListener(`visibilitychange`,e))},yn=_.createContext(null),bn=_.createContext(null);function xn({children:e,apiBase:t,fetchImpl:n}){let[r,i]=_.useReducer(Ut,void 0,Ht),a=_.useRef(r);a.current=r;let o=_.useRef(0),s=_.useRef(null),c=_.useMemo(()=>new jt({apiBase:t,fetchImpl:n,onUnauthorized:()=>{o.current+=1,s.current?.stop(),i({type:`logout`,now:Date.now()})}}),[t,n]);_.useEffect(()=>{let e=new dn({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 kt)&&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)(bn.Provider,{value:l,children:(0,x.jsx)(yn.Provider,{value:r,children:e})})}function Sn(){let e=_.useContext(yn);if(e===null)throw Error(`useWebUi must be used within WebUiProvider.`);return e}function Cn(){let e=_.useContext(bn);if(e===null)throw Error(`useWebUiActions must be used within WebUiProvider.`);return e}var wn=Object.freeze({}),Tn=[`max_tokens`,`temperature`,`top_p`,`top_k`,`min_p`,`repetition_penalty`,`seed`];function En(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(!Tn.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 Dn=wn,On=new Set;function kn(e){return On.add(e),()=>On.delete(e)}function An(e){Dn=En(e);for(let e of On)e()}function jn(){An(wn)}function Mn(){return{defaults:(0,_.useSyncExternalStore)(kn,()=>Dn,()=>wn),setDefaults:An,reset:jn}}function Nn(e,t,n){return e===null||e<=0||t===null||n===void 0?`unknown`:t+n>e?`exceeds`:`raw-fits`}function Pn({modelId:e,nCtx:t,locale:n}){let r=Cn(),{defaults:i}=Mn(),[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=Nn(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)(Ce,{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 Fn(e){return e instanceof kt?e.status===401?`wrong-key`:e.status===403?`forbidden`:`generic`:e instanceof $e||e instanceof Error&&e.name===`ValidationError`?`schema`:e instanceof TypeError||e instanceof Error&&/fetch|network|offline|connection/i.test(e.message)?`offline`:`generic`}function In(e,t){let n=Kn(t);return n===null?R(e,`model.selected.none`):`${n.identity.display_name} · ${qn(e,n.lifecycle.state)}`}function Ln(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,sequence:Jn(e,t),status:Rn(e,t.connection)})}function Rn(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 zn(e){return e.snapshot.auth.status===`authenticated`?e.snapshot.connection===`schema-mismatch`?(0,x.jsx)(Hn,{...e}):(0,x.jsx)(Vn,{...e}):(0,x.jsx)(Bn,{...e})}function Bn(e){return e.authFailure===`schema`?(0,x.jsx)(Hn,{...e}):(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsxs)(`section`,{className:`screen-heading connection-prompt`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:e.eyebrow}),(0,x.jsx)(`h1`,{"data-testid":e.titleTestId,children:e.title}),(0,x.jsx)(`p`,{"data-testid":z(`connection.prompt.body`),children:R(e.locale,`connection.prompt.body`)})]}),(0,x.jsx)(Ne,{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:Gn(e.locale,e.authFailure),busy:e.snapshot.auth.status===`authenticating`,onSubmit:e.onLogin,onLogout:e.onLogout,testId:z(`auth.login`)})]})}function Vn(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.jsxs)(`section`,{className:`screen-heading connection-prompt`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:e.eyebrow}),(0,x.jsx)(`h1`,{"data-testid":e.titleTestId,children:e.title}),(0,x.jsx)(`p`,{"data-testid":z(`connection.authenticated.body`),children:R(e.locale,`connection.authenticated.body`)})]}),(0,x.jsx)(B,{tone:`info`,title:R(e.locale,`connection.authenticated.title`),body:Un(e.locale,e.snapshot),testId:z(`connection.authenticated.detail`)}),t?(0,x.jsx)(B,{title:R(e.locale,`connection.error.title`),body:Wn(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 Hn(e){return(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsxs)(`section`,{className:`screen-heading connection-prompt`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:e.eyebrow}),(0,x.jsx)(`h1`,{"data-testid":e.titleTestId,children:e.title})]}),(0,x.jsx)(Pe,{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 Un(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:Rn(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:Jn(e,t)})}function Wn(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 Gn(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 Kn(e){return e.selectedModelId===null?null:e.catalog.find(t=>t.identity.id===e.selectedModelId)??null}function qn(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 Jn(e,t){return String(t.lastSequence??t.catalogSequence??t.resourceFences.operationsSnapshot??R(e,`connection.snapshot.pending`))}function Yn({locale:e}){let{defaults:t,setDefaults:n,reset:r}=Mn(),[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:Tn.map(n=>(0,x.jsx)(Ce,{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)(B,{title:R(e,`settings.generation.error_title`),body:o}):null,(0,x.jsxs)(`div`,{children:[(0,x.jsx)(N,{onClick:()=>{try{n(En(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)(Ce,{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)(Ee,{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 Xn({modelId:e,locale:t}){let n=Cn(),[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]=Be(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:Ve(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)(B,{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)(Ce,{label:e.name,value:a[e.name]??Ve(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)(Ce,{label:e.name,value:Ve(e,r.current[e.name]),disabled:!0,hint:e.reason??e.help},e.name))]}),(0,x.jsxs)(Ee,{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,Ve(e,e.default)]))),c({}),m(!1)},children:R(t,`settings.live.reset.confirm`)})]})]})}var Zn=[`fp16`,`float16`,`int8`,`i8`,`turbo4-asym`,`fp16+turbo4`,`turbo3-asym`,`fp16+turbo3`,`turbo3`,`turbo4`,`turbo4-sym`,`turbo4-delegated`,`fp16+turbo4-delegated`],Qn=Object.freeze({});function $n(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`||!Zn.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 er(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:$n(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]=$n(t)}return{version:1,reusable:$n(n.reusable),models:r}}var tr=`mlxcel.webui.load-profiles.v1`,nr={version:1,reusable:Qn,models:{}},rr=!1,ir=new Set;function ar(e){return ir.add(e),()=>ir.delete(e)}function or(){if(!rr){rr=!0;try{let e=localStorage.getItem(tr);e!==null&&(nr=er(e))}catch{}}}function sr(e){let t=JSON.stringify(e),n=er(t);localStorage.setItem(tr,t),nr=n;for(let e of ir)e()}function cr(e){or();let t=(0,_.useSyncExternalStore)(ar,()=>nr);return{reusable:t.reusable,modelProfile:e===null?Qn:t.models[e]??Qn,profile:e!==null&&Object.hasOwn(t.models,e)?t.models[e]:t.reusable,save:(t,n)=>{let r=$n(t);if(n===`model`&&e===null)throw Error(`Select a model first.`);sr(n===`reusable`?{...nr,reusable:r}:{...nr,models:{...nr.models,[e]:r}})},reset:(t=e===null?`reusable`:`model`)=>{let n=Object.fromEntries(Object.entries(nr.models).filter(([t])=>t!==e));sr(t===`reusable`?{...nr,reusable:Qn}:{...nr,models:n})},exportJson:()=>JSON.stringify(nr,null,2),importJson:e=>sr(er(e))}}function lr(e){let t=$n(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=cr(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)(B,{tone:`info`,title:R(t,`settings.profile.single.title`),body:R(t,`settings.profile.single.body`)}):null,(0,x.jsx)(Se,{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)(Ce,{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)(Ce,{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)(Se,{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`)},...Zn.map(e=>({value:e,label:e}))]})]}),(0,x.jsx)(`p`,{children:R(t,`settings.profile.restrictions`)}),u?(0,x.jsx)(B,{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($n(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:lr(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)(Ee,{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 dr({locale:e}){let t=Sn(),n=Cn(),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)(Yn,{locale:e}),o?(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(Se,{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} · ${qn(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)(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:R(e,`settings.server.context.title`)}),(0,x.jsx)(Ce,{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)(Ce,{label:R(e,`settings.server.context.slots`),value:i?.totalSlots?.toString()??c,disabled:!0}),(0,x.jsx)(Ce,{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)(Pn,{modelId:s,nCtx:i?.nCtx??null,locale:e},s)]}),s===null?(0,x.jsx)(B,{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)(Xn,{modelId:s,locale:e},s):(0,x.jsx)(B,{tone:`info`,title:R(e,`settings.server.live_disabled.title`),body:R(e,`settings.server.live_disabled.body`)})]}):(0,x.jsx)(B,{tone:`warning`,title:R(e,`settings.server.unavailable.title`),body:R(e,`settings.server.unavailable.body`)})]})}var fr=[{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 pr(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]`);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)},[]);let o=n=>{let r=fr[(fr.findIndex(t=>t.id===e.route)+n+fr.length)%fr.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)(mr,{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)(Oe,{open:i,title:R(e.locale,`nav.primary`),onClose:()=>a(!1),closeLabel:R(e.locale,`common.close`),testId:`mobile-nav-sheet`,children:(0,x.jsx)(mr,{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`,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:()=>a(!0),"data-testid":z(`toolbar.menu`)}),(0,x.jsxs)(`div`,{className:`toolbar-title`,children:[(0,x.jsx)(`p`,{id:`app-title`,"data-testid":z(`app.title`),children:R(e.locale,`app.title`)}),(0,x.jsx)(`span`,{"data-testid":z(`app.subtitle`),children:R(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)(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)(`section`,{className:`app-content`,children:e.children}),e.inspector]})]})]})}var mr=_.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:fr.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.jsx)(`span`,{className:`connection-dot`,"data-state":e.connectionState,"aria-hidden":`true`}),(0,x.jsx)(`span`,{"data-testid":z(`connection.ready`),children:e.connectionLabel})]})]}));mr.displayName=`Sidebar`;var hr=[`mlxcel`,`glass`],gr=[`light`,`dark`],_r=[`system`,`light`,`dark`],vr=`mlxcel`,yr=`system`;hr.flatMap(e=>gr.map(t=>`${e}-${t}`));var br=`(prefers-color-scheme: dark)`;function xr(e){return typeof e==`string`&&hr.includes(e)}function Sr(e){return typeof e==`string`&&_r.includes(e)}function Cr(e,t){return`${e}-${t}`}function wr(){try{return typeof window>`u`||typeof window.matchMedia!=`function`?`light`:window.matchMedia(`(prefers-color-scheme: dark)`).matches?`dark`:`light`}catch{return`light`}}function Tr(e,t=wr()){return e===`system`?t:e}function Er(e,t,n=wr()){let r=Tr(t,n);return{id:Cr(e,r),family:e,scheme:r,preference:t}}function Dr(e){if(typeof window>`u`||typeof window.matchMedia!=`function`)return()=>void 0;let t;try{t=window.matchMedia(br)}catch{return()=>void 0}let n=t=>e(t.matches?`dark`:`light`);return t.addEventListener(`change`,n),()=>t.removeEventListener(`change`,n)}var Or={themeFamily:vr,colorScheme:yr,material:`glass`,glassIntensity:35,reduceMotion:!1,reduceTransparency:!1,highContrast:`system`,locale:`en`},kr=`mlxcel.webui.appearance`;function Ar(e){let t=typeof e==`number`&&Number.isFinite(e)?e:Or.glassIntensity;return Math.max(0,Math.min(100,Math.round(t)))}function jr(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Mr(e){return e===`glass`||e===`tinted`||e===`opaque`}function Nr(e){return e===`system`||e===`on`||e===`off`}function Pr(e){return Nr(e)?e:e===!0?`on`:e===!1?`off`:Or.highContrast}function Fr(e){return Sr(e.colorScheme)?e.colorScheme:e.colorScheme===void 0&&Sr(e.theme)?e.theme:Or.colorScheme}function Ir(e){return e===`en`||e===`ko`}function Lr(){if(typeof window>`u`)return Or;let e;try{e=window.localStorage.getItem(kr)}catch{return Or}if(!e)return Or;try{let t=JSON.parse(e);return jr(t)?{themeFamily:xr(t.themeFamily)?t.themeFamily:Or.themeFamily,colorScheme:Fr(t),material:Mr(t.material)?t.material:Or.material,glassIntensity:Ar(t.glassIntensity),reduceMotion:t.reduceMotion===!0,reduceTransparency:t.reduceTransparency===!0,highContrast:Pr(t.highContrast),locale:Ir(t.locale)?t.locale:Or.locale}:Or}catch{return Or}}function Rr(e){try{window.localStorage.setItem(kr,JSON.stringify(e))}catch{}}function zr(){return typeof CSS>`u`||typeof CSS.supports!=`function`?!1:CSS.supports(`backdrop-filter: blur(1px)`)||CSS.supports(`-webkit-backdrop-filter: blur(1px)`)}function Br(e,t,n=wr()){let r=Er(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(Ar(t.glassIntensity)),e.dataset.reduceMotion=String(t.reduceMotion),e.dataset.reduceTransparency=String(t.reduceTransparency),e.dataset.highContrast=t.highContrast,e.dataset.backdropFilter=zr()?`supported`:`unsupported`,e.lang=t.locale}function Vr(e){return e.value===null||!Number.isFinite(e.value)?`N/A`:`${new Intl.NumberFormat(void 0,{maximumFractionDigits:2}).format(e.value)} ${e.unit}`}function Hr(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 Ur(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 Wr(e){let t=URL.createObjectURL(new Blob([Ur(e)],{type:`application/json`})),n=document.createElement(`a`);n.href=t,n.download=`mlxcel-diagnostics.json`,n.click(),URL.revokeObjectURL(t)}function Gr({operations:e,locale:t,stale:n}){let r=[...e.values()].sort((e,t)=>Number(Bt(e))-Number(Bt(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=>!Bt(e)).length),failed:String(r.filter(e=>e.state===`failed`).length)})}),(0,x.jsx)(`p`,{children:R(t,`activity.session`)}),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)(Kr,{operation:e,locale:t,stale:n})},e.operation_id))})]})}function Kr({operation:e,locale:t,stale:n}){let r=Cn(),i=Sn(),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=Bt(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:Hr(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)(B,{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)(B,{title:R(t,`activity.cancel_failed`),body:R(t,`activity.refresh`)}):null]})}var qr=new Set(be.map(e=>e.key).filter(e=>e.startsWith(`activity.metric.`))),Jr=e=>qr.has(e);function Yr({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 Jr(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)(B,{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.jsxs)(`dl`,{className:`activity-metric`,children:[(0,x.jsx)(`dt`,{children:s(e)}),(0,x.jsx)(`dd`,{children:Vr(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.jsxs)(`dl`,{className:`activity-metric`,children:[(0,x.jsx)(`dt`,{children:s(e)}),(0,x.jsx)(`dd`,{children:Vr(n)}),(0,x.jsxs)(`dd`,{children:[R(t,`activity.scope`),`: `,n.scope]}),(0,x.jsxs)(`dd`,{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)(`dd`,{children:n.reason})]},e))})]})]})}var Xr=(function(){let e=typeof document<`u`&&document.createElement(`link`).relList;return e&&e.supports&&e.supports(`modulepreload`)?`modulepreload`:`preload`})(),Zr=function(e,t){return new URL(e,t).href},Qr={},$r=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=Zr(t,n),t=s(t),t in Qr)return;Qr[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`:Xr,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)})},ei=(0,_.lazy)(()=>$r(()=>import(`./history-DZcGwKDZ.js`),[],import.meta.url));function ti({locale:e}){let t=Sn(),n=Cn(),[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":z(`activity.title`),children:R(e,`activity.title`)}),(0,x.jsx)(`p`,{children:R(e,`activity.intro`)}),(0,x.jsxs)(`p`,{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)(Se,{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.jsxs)(`div`,{className:`activity-toolbar`,children:[(0,x.jsx)(N,{onClick:()=>{n.refresh()},children:R(e,`activity.refresh`)}),(0,x.jsx)(N,{onClick:()=>Wr(t),children:R(e,`activity.export`)})]}),a?(0,x.jsx)(B,{tone:`warning`,title:R(e,`activity.stale`),body:R(e,`activity.refresh`)}):null,(0,x.jsx)(Gr,{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)(Yr,{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)(ei,{samples:t.runtimeHistory,locale:e})}):null]})}var ni=e=>[`succeeded`,`failed`,`cancelled`].includes(e.state),ri=e=>e.auth.status===`authenticated`&&e.bootstrap!==null&&e.catalogSequence!==null&&[`ready`,`streaming`,`polling`].includes(e.connection);function ii(e,t){return ri(e)&&e.bootstrap?.actions[t]?.state===`enabled`}function ai(e,t){return[...e.operations.values()].some(e=>!ni(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 oi(e,t){return ii(e,`load`)&&t.supported&&t.complete&&t.metadata.support.runnable_on_backend&&!t.lifecycle.busy&&[`unloaded`,`failed`].includes(t.lifecycle.state)&&!ai(e,t.identity.id)}function si(e,t){return ii(e,`unload`)&&t.lifecycle.state===`ready`&&!ai(e,t.identity.id)}function ci(e,t){return ii(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)&&!ai(e,t.identity.id)}function li(e,t){return ri(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&&si(e,n)&&!n.lifecycle.busy&&n.lifecycle.active_requests===0&&n.lifecycle.draining_requests===0)}function di(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 fi(e,t){return e instanceof kt?e.envelope?.error.code===`stale_revision`?R(t,`models.library.stale`):e.message:R(t,`models.library.pending`)}function pi(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 mi(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 hi(e){return e.length===0||e.length<=128&&e.split(`/`).every(e=>e!==`.`&&e!==`..`&&/^[A-Za-z0-9._~+-]+$/.test(e))}function gi({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=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)(Ee,{open:!0,title:f,onClose:i,closeLabel:R(n,`common.close`),testId:`models-confirm`,children:[(0,x.jsx)(`p`,{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)(Ce,{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`,{children:[e.identity.display_name,` · `,e.lifecycle.state,` · `,R(n,`models.library.active`),`:`,` `,e.lifecycle.active_requests]},e.identity.id))}),(0,x.jsx)(Se,{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 _i({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=mi(s.trim())&&hi(l.trim());return(0,x.jsx)(Ee,{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)(Ce,{label:R(e,`models.library.repo`),value:s,onChange:c,testId:`models-repo`,error:s&&!mi(s.trim())?R(e,`models.library.repo_invalid`):void 0}),(0,x.jsx)(Ce,{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 vi({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 yi({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`),di(s.disk_bytes,r)],[R(r,`models.library.memory`),di(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)(Ae,{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:qn(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)(vi,{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||!oi(n,e),onClick:()=>a(`load`),children:R(r,`models.load`)}),(0,x.jsx)(N,{"data-testid":`models-use-chat`,disabled:i||!li(n,e),onClick:o,children:R(r,`models.library.chat`)}),(0,x.jsx)(N,{"data-testid":`models-unload`,disabled:i||!si(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||!ci(n,e),onClick:()=>a(`delete`),children:R(r,`models.library.delete`)}):null]}),li(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 bi({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(ni(e))-Number(ni(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:Si(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:`${di(s.progress.completed_bytes,t)} / ${di(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===xi(s)&&oi(e,t)),onClick:()=>o(xi(s)),children:R(t,`models.library.capacity`)}):null,s.kind===`download`&&!ni(s)?(0,x.jsx)(N,{disabled:n||!ri(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||!ii(e,`download`),onClick:()=>a(s),children:R(t,`models.library.retry_download`)}):null]})]})},s.operation_id))})]})}function xi(e){return e.target.target_kind===`model`?e.target.model_id:``}function Si(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 Ci=25;function wi({locale:e}){let t=Sn(),n=Cn(),[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}=cr(y?.identity.id??null),{profile:S}=cr(f?.kind===`capacity`?f.entry.identity.id:null),C=pi(t.catalog,r),w=Math.max(1,Math.ceil(C.length/Ci)),T=Math.min(a,w-1),E=[...t.operations.values()].some(e=>e.kind===`download`&&!ni(e))||[...t.pendingReconciliations.values()].some(e=>e.kind===`download`),D=[...t.operations.values()].some(e=>e.kind===`catalog_refresh`&&!ni(e))||[...t.pendingReconciliations.values()].some(e=>e.kind===`catalog-refresh`),O=e=>{i({...r,...e}),o(0)},k=async(n,r)=>{if(l.current||!ri(t))return!1;l.current=!0,c(!0),d(null);try{return await n(),!0}catch(t){return d(fi(t,e)),r?.(t),!1}finally{l.current=!1,c(!1)}},ee=(r,i,a=b)=>{if(!oi(t,r)){d(R(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(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 kt&&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||ni(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(!ui(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`&&si(t,o)?k(()=>n.unloadModel({action:`unload`,model_id:o.identity.id,expected_revision:o.identity.revision,idempotency_key:crypto.randomUUID()})):a.kind===`delete`&&ci(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`,"aria-label":R(e,`models.library.inspect`,{name:r.identity.display_name}),onClick:()=>n.selectModel(r.identity.id),children:r.identity.display_name}),r.identity.id===t.selectedModelId?(0,x.jsx)(`small`,{children:R(e,`models.library.selected`)}):null,(0,x.jsxs)(`p`,{children:[r.identity.source,` · `,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:qn(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.jsxs)(`section`,{className:`screen-heading`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:R(e,`routes.models.eyebrow`)}),(0,x.jsx)(`h1`,{tabIndex:-1,"data-dialog-focus-fallback":!0,"data-testid":z(`models.title`),children:R(e,`models.title`)}),(0,x.jsx)(`p`,{children:R(e,`models.library.subtitle`)})]}),ri(t)?null:(0,x.jsx)(B,{title:R(e,`models.library.stale`),body:t.error?.message??R(e,`models.library.waiting`),action:(0,x.jsx)(N,{onClick:()=>{n.refresh()},children:R(e,`models.library.refresh`)}),testId:`connection-error-title`}),u?(0,x.jsx)(B,{title:R(e,`models.library.error`),body:u,action:(0,x.jsx)(N,{onClick:()=>{d(null),n.refresh()},children:R(e,`models.library.refresh`)}),testId:`models-action-error`}):null,t.bootstrap?.server.mode===`single_model`?(0,x.jsx)(B,{tone:`info`,title:R(e,`models.library.single`),body:`mlxcel-server --webui`,testId:`models-read-only`}):null,(0,x.jsxs)(`div`,{className:`button-row`,children:[(0,x.jsx)(N,{tone:`primary`,onClick:()=>h({repo:``,revision:``}),disabled:s||E||!ii(t,`download`),"data-testid":`models-add`,children:R(e,`models.library.add`)}),(0,x.jsx)(N,{disabled:s||D||!ri(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`)})]}),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:Un(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)(Ce,{label:R(e,`models.library.search`),value:r.query,onChange:e=>O({query:e}),testId:`models-search`}),(0,x.jsx)(Se,{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)(Se,{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)(Se,{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:qn(e,t)}))]}),(0,x.jsx)(Se,{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)(he,{columns:M,rows:C.slice(T*Ci,(T+1)*Ci),getRowKey:e=>e.identity.id,ariaLabel:R(e,`models.title`),testId:`models-table`,rowClassName:e=>e.identity.id===t.selectedModelId?`models-selected`:void 0,loading:t.catalogSequence===null,loadingState:(0,x.jsx)(`p`,{role:`status`,children: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)(yi,{entry:y,profile:b,state:t,locale:e,busy:s,onAction:A,onChat:()=>{li(t,y)&&(n.selectModel(y.identity.id),window.location.hash=`chat`)}}):null]}),(0,x.jsx)(bi,{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&&oi(t,n)&&p({kind:`capacity`,entry:n,instance:t.serverInstanceId})}}),f?(0,x.jsx)(gi,{value:f,state:t,locale:e,busy:s,onClose:()=>p(null),onConfirm:te},f.kind):null,m?(0,x.jsx)(_i,{locale:e,state:t,initial:m,error:u,busy:s||E||!ii(t,`download`),onClose:()=>h(null),onDownload:(e,r)=>{ii(t,`download`)&&!E&&k(()=>n.downloadModel({repo_id:e,revision:r||null,idempotency_key:crypto.randomUUID()})).then(e=>{e&&h(null)})}}):null]})}var Ti={en:`en-US`,ko:`ko-KR`},Ei=e=>Ti[e];function Di(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)(ji,{locale:e.locale})},{id:`data`,label:R(e.locale,`gallery.tab.data`),panel:(0,x.jsx)(Mi,{locale:e.locale})}]}),(0,x.jsxs)(Ee,{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)(Ce,{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 Ai(e){return(0,x.jsxs)(`div`,{className:`gallery-grid`,children:[(0,x.jsxs)(`article`,{className:`surface-card`,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)(Ce,{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)(Se,{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)(`article`,{className:`surface-card`,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)(ke,{label: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 ji(e){return(0,x.jsxs)(`div`,{className:`gallery-grid`,children:[(0,x.jsx)(Ne,{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)(Pe,{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)(B,{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:Di(67108864,e.locale)})}),(0,x.jsx)(fe,{label:R(e.locale,`gallery.progress.measured`),value:37})]}),(0,x.jsxs)(Me,{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 Mi(e){return(0,x.jsxs)(`div`,{className:`gallery-grid dense-gallery`,children:[(0,x.jsxs)(`article`,{className:`surface-card table-card`,tabIndex:0,"aria-label":R(e.locale,`gallery.sample.caption`),children:[(0,x.jsx)(`h2`,{children:R(e.locale,`gallery.data.title`)}),(0,x.jsxs)(je,{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:Oi(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:Oi(null,e.locale)})]})]})]})]}),(0,x.jsxs)(Ae,{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`)})]})]})}var Ni={count:4,bytes:8388608,dimension:4096,pixels:16e6},Pi=new Set([`image/png`,`image/jpeg`,`image/webp`]);function Fi(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 Ii(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 Li(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 Ri(e,t,n){if(!e||!t||e>Math.min(Ni.dimension,n.max_width)||t>Math.min(Ni.dimension,n.max_height)||e*t>Ni.pixels||e*t*4>n.max_decoded_bytes)throw Error(`Image dimensions exceed the server or browser decode budget.`)}function zi(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(Li(t),e.length>t.max_images)throw Error(`Conversation images exceed the server image count limit.`);let n=0,r=Math.min(Ni.bytes,t.max_image_bytes);for(let i of e){if(!i||!Pi.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)||!Pi.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 Ii(e),[r,i]=Fi(t,e.type);if(Ri(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 Ui(e){if(e==null)return``;if(typeof e!=`string`)throw Error(`Malformed text delta.`);return e}function Wi(e){if(typeof e!=`number`||!Number.isSafeInteger(e)||e<0)throw Error(`Malformed usage.`);return e}function Gi(e,t,n){if(t.length>256e3)throw Error(`Chat frame exceeds the display limit.`);let r=Hi(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=Hi(r.usage);i={...i,usage:{prompt_tokens:Wi(e.prompt_tokens),completion_tokens:Wi(e.completion_tokens),total_tokens:Wi(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=Hi(e);if(t.index!==0)throw Error(`Unexpected chat choice index.`);let r=Hi(t.delta),a=Ui(r.content),o=Ui(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=Hi(e),n=Wi(t.index);if(n>=32)throw Error(`Tool index exceeds the display limit.`);let r=t.function===void 0?{}:Hi(t.function),i=s.find(e=>e.index===n)??{index:n,id:``,name:``,arguments:``},a={index:n,id:i.id+Ui(t.id),name:i.name+Ui(r.name),arguments:i.arguments+Ui(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=Ui(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 Ki(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 qi(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 Ji(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 Yi=Object.freeze({conversations:50,turnsPerConversation:200,totalTurns:1e3,textCharacters:262144,jsonBytes:16777216,imageBytes:8388608,imagesPerTurn:8,toolsPerTurn:128}),Xi=`mlxcel.webui.chat.v1`,Zi=`history`,Qi=`conversations`,$i=1,ea=new Set([`temperature`,`top_p`,`top_k`,`min_p`,`max_tokens`,`seed`,`repetition_penalty`,`presence_penalty`,`frequency_penalty`]),ta=class extends Error{constructor(e=`Conversation history is invalid or exceeds the local history limits.`){super(e),this.name=`HistoryValidationError`}},H=class extends Error{constructor(e,t){super(e,t),this.name=`HistoryStorageError`}};function U(){throw new ta}function na(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return U();let n=Object.getPrototypeOf(e);if(n!==Object.prototype&&n!==null)return U();let r=Object.keys(e);return r.length!==t.length||r.some(e=>!t.includes(e))?U():e}function W(e,t=Yi.textCharacters){return typeof e!=`string`||e.length>t?U():e}function ra(e){let t=W(e,512);return!t||Array.from(t).some(e=>e.charCodeAt(0)<32||e.charCodeAt(0)===127)?U():t}function ia(e,t=!1){return typeof e!=`number`||!Number.isFinite(e)||e<0||t&&!Number.isSafeInteger(e)?U():e}function aa(e,t){return e===null?null:t(e)}function oa(e,t){return!Array.isArray(e)||e.length>t?U():e}function sa(e){return new TextEncoder().encode(e).byteLength}function ca(e,t){let n=0,r=0,i=0,a=new Set;return oa(e,Yi.conversations).map(e=>{let o=na(e,[`id`,`title`,`systemPrompt`,`turns`,`updatedAt`]),s=ra(o.id);if(a.has(s))return U();a.add(s);let c=new Set,l=oa(o.turns,Yi.turnsPerConversation).map(e=>{if(++n>Yi.totalTurns)return U();let a=na(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 U();c.add(o);let s=W(a.status,32);if(![`streaming`,`complete`,`cancelled`,`interrupted`,`error`].includes(s))return U();let l={};if(!a.parameters||typeof a.parameters!=`object`||Array.isArray(a.parameters)||![Object.prototype,null].includes(Object.getPrototypeOf(a.parameters)))return U();for(let[e,t]of Object.entries(a.parameters)){if(!ea.has(e)||typeof t!=`number`||!Number.isFinite(t))return U();l[e]=t}let u=new Set,d=oa(a.tools,Yi.toolsPerTurn).map(e=>{let t=na(e,[`index`,`id`,`name`,`arguments`]),n=ia(t.index,!0);return u.has(n)?U():(u.add(n),{index:n,id:W(t.id,512),name:W(t.name,512),arguments:W(t.arguments)})}),f=oa(a.images,Yi.imagesPerTurn).map(e=>{let t=na(e,[`name`,`type`,`dataUrl`]),n=W(t.type,64);if(![`image/png`,`image/jpeg`,`image/webp`].includes(n))return U();let i=W(t.dataUrl,Yi.imageBytes*2),a=`data:${n};base64,`;if(!i.startsWith(a))return U();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>Yi.imageBytes)?U():{name:W(t.name,512),type:n,dataUrl:i}}),p={id:o,modelId:ra(a.modelId),modelRevision:ia(a.modelRevision,!0),inferenceId:ra(a.inferenceId),modelName:W(a.modelName,512),prompt:W(a.prompt),content:W(a.content),reasoning:W(a.reasoning),tools:d,status:s===`streaming`?`interrupted`:s,finishReason:aa(a.finishReason,W),usage:aa(a.usage,e=>{let t=na(e,[`prompt_tokens`,`completion_tokens`,`total_tokens`]);return{prompt_tokens:ia(t.prompt_tokens,!0),completion_tokens:ia(t.completion_tokens,!0),total_tokens:ia(t.total_tokens,!0)}}),ttftMs:aa(a.ttftMs,ia),elapsedMs:aa(a.elapsedMs,ia),error:aa(a.error,W),parameters:l,images:t.includeImages?f:[]};return p.status===`complete`&&(!p.finishReason||!p.content&&!p.reasoning&&!p.tools.length)||(i+=sa(JSON.stringify(p)),i>Yi.jsonBytes)?U():p});return{id:s,title:W(o.title,512),systemPrompt:W(o.systemPrompt),turns:l,updatedAt:ia(o.updatedAt,!0)}})}function la(e,t={}){let n=ca(e,t);return sa(JSON.stringify(n))>Yi.jsonBytes?U():n}function ua(e,t={}){let n=JSON.stringify({version:$i,conversations:la(e,t)});return sa(n)>Yi.jsonBytes?U():n}function da(e,t={}){if(sa(e)>Yi.jsonBytes)return U();let n;try{n=JSON.parse(e)}catch{return U()}let r=na(n,[`version`,`conversations`]);return r.version===$i?la(r.conversations,t):U()}function fa(e){return new H(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 pa(e={}){let t=!1,n=!1,r=0,i,a,o=new Set,s=()=>{let t=e.indexedDB??globalThis.indexedDB;if(!t)throw new H(`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(Xi,$i);o.onupgradeneeded=()=>{o.result.objectStoreNames.contains(Zi)||o.result.createObjectStore(Zi)},o.onerror=()=>a(fa(o.error));let l=!1;o.onblocked=()=>{l=!0,a(new H(`Close other WebUI tabs to access local history.`))},o.onsuccess=()=>{if(l||!t||e!==r){o.result.close(),a(new H(`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(Zi,e);o.add(r);let a=i(r.objectStore(Zi));r.oncomplete=()=>{o.delete(r),t(a.result)},r.onabort=r.onerror=()=>{o.delete(r),n(fa(r.error??a.error))}})}catch(e){throw e instanceof H?e:fa(e)}}return{setEnabled(e){t!==e&&(t=e,e||c())},async load(e={}){let t=await u(`readonly`,e=>e.get(Qi));return t===void 0?[]:da(W(t,Yi.jsonBytes),e)},async save(e,n={}){if(!t)return;let r=ua(e,n);await u(`readwrite`,e=>e.put(r,Qi))},async clear(){if(n)throw new H(`Local history is already being cleared.`);n=!0;let e=!1;c();try{await new Promise((t,r)=>{let i=s().deleteDatabase(Xi);i.onsuccess=()=>{n=!1,t()},i.onerror=()=>{n=!1,r(fa(i.error))},i.onblocked=()=>{e=!0,r(new H(`Close other WebUI tabs to clear local history.`))}})}catch(t){throw e||(n=!1),t instanceof H?t:fa(t)}},close:c}}var ma=[],ha=0,ga=new Set;function _a(){return ha}function va(e){return{id:crypto.randomUUID(),title:e,systemPrompt:``,turns:[],updatedAt:Date.now()}}var ya=new WeakMap;function ba(e){let t=ya.get(e);if(t!==void 0)return t;let n=new TextEncoder().encode(JSON.stringify(e)).byteLength;return ya.set(e,n),n}function xa(e){return e.length>Yi.conversations||e.reduce((e,t)=>e+t.turns.length,0)>Yi.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+ba(t),0)+Math.max(0,t.turns.length-1),0)<=Yi.jsonBytes}function Sa(e){ma=e;for(let e of ga)e()}function Ca(e){if(!xa(e))throw Error(`Conversation memory limit exceeded.`);ha++,Sa(e)}function wa(e){let t=ma.some(t=>t.id===e.id)?ma.map(t=>t.id===e.id?e:t):[...ma,e];return xa(t)?(Sa(t),!0):!1}function Ta(){return(0,_.useSyncExternalStore)(e=>(ga.add(e),()=>ga.delete(e)),()=>ma)}var Ea=(0,_.lazy)(()=>$r(()=>import(`./code-highlight-CPbBnAiM.js`),[],import.meta.url)),Da=65536,Oa=512;function ka(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)(Ea,{code:e,language:t})}):(0,x.jsx)(`code`,{children:e})})]})}),Ma=(0,_.memo)(function({text:e,streaming:t=!1}){let n=e.slice(0,Da).split(` +`&&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 Ii(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 Li(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 Ri(e,t,n){if(!e||!t||e>Math.min(Ni.dimension,n.max_width)||t>Math.min(Ni.dimension,n.max_height)||e*t>Ni.pixels||e*t*4>n.max_decoded_bytes)throw Error(`Image dimensions exceed the server or browser decode budget.`)}function zi(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(Li(t),e.length>t.max_images)throw Error(`Conversation images exceed the server image count limit.`);let n=0,r=Math.min(Ni.bytes,t.max_image_bytes);for(let i of e){if(!i||!Pi.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)||!Pi.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 Ii(e),[r,i]=Fi(t,e.type);if(Ri(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 Ui(e){if(e==null)return``;if(typeof e!=`string`)throw Error(`Malformed text delta.`);return e}function Wi(e){if(typeof e!=`number`||!Number.isSafeInteger(e)||e<0)throw Error(`Malformed usage.`);return e}function Gi(e,t,n){if(t.length>256e3)throw Error(`Chat frame exceeds the display limit.`);let r=Hi(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=Hi(r.usage);i={...i,usage:{prompt_tokens:Wi(e.prompt_tokens),completion_tokens:Wi(e.completion_tokens),total_tokens:Wi(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=Hi(e);if(t.index!==0)throw Error(`Unexpected chat choice index.`);let r=Hi(t.delta),a=Ui(r.content),o=Ui(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=Hi(e),n=Wi(t.index);if(n>=32)throw Error(`Tool index exceeds the display limit.`);let r=t.function===void 0?{}:Hi(t.function),i=s.find(e=>e.index===n)??{index:n,id:``,name:``,arguments:``},a={index:n,id:i.id+Ui(t.id),name:i.name+Ui(r.name),arguments:i.arguments+Ui(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=Ui(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 Ki(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 qi(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 Ji(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 Yi=Object.freeze({conversations:50,turnsPerConversation:200,totalTurns:1e3,textCharacters:262144,jsonBytes:16777216,imageBytes:8388608,imagesPerTurn:8,toolsPerTurn:128}),Xi=`mlxcel.webui.chat.v1`,Zi=`history`,Qi=`conversations`,$i=1,ea=new Set([`temperature`,`top_p`,`top_k`,`min_p`,`max_tokens`,`seed`,`repetition_penalty`,`presence_penalty`,`frequency_penalty`]),ta=class extends Error{constructor(e=`Conversation history is invalid or exceeds the local history limits.`){super(e),this.name=`HistoryValidationError`}},H=class extends Error{constructor(e,t){super(e,t),this.name=`HistoryStorageError`}};function U(){throw new ta}function na(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return U();let n=Object.getPrototypeOf(e);if(n!==Object.prototype&&n!==null)return U();let r=Object.keys(e);return r.length!==t.length||r.some(e=>!t.includes(e))?U():e}function W(e,t=Yi.textCharacters){return typeof e!=`string`||e.length>t?U():e}function ra(e){let t=W(e,512);return!t||Array.from(t).some(e=>e.charCodeAt(0)<32||e.charCodeAt(0)===127)?U():t}function ia(e,t=!1){return typeof e!=`number`||!Number.isFinite(e)||e<0||t&&!Number.isSafeInteger(e)?U():e}function aa(e,t){return e===null?null:t(e)}function oa(e,t){return!Array.isArray(e)||e.length>t?U():e}function sa(e){return new TextEncoder().encode(e).byteLength}function ca(e,t){let n=0,r=0,i=0,a=new Set;return oa(e,Yi.conversations).map(e=>{let o=na(e,[`id`,`title`,`systemPrompt`,`turns`,`updatedAt`]),s=ra(o.id);if(a.has(s))return U();a.add(s);let c=new Set,l=oa(o.turns,Yi.turnsPerConversation).map(e=>{if(++n>Yi.totalTurns)return U();let a=na(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 U();c.add(o);let s=W(a.status,32);if(![`streaming`,`complete`,`cancelled`,`interrupted`,`error`].includes(s))return U();let l={};if(!a.parameters||typeof a.parameters!=`object`||Array.isArray(a.parameters)||![Object.prototype,null].includes(Object.getPrototypeOf(a.parameters)))return U();for(let[e,t]of Object.entries(a.parameters)){if(!ea.has(e)||typeof t!=`number`||!Number.isFinite(t))return U();l[e]=t}let u=new Set,d=oa(a.tools,Yi.toolsPerTurn).map(e=>{let t=na(e,[`index`,`id`,`name`,`arguments`]),n=ia(t.index,!0);return u.has(n)?U():(u.add(n),{index:n,id:W(t.id,512),name:W(t.name,512),arguments:W(t.arguments)})}),f=oa(a.images,Yi.imagesPerTurn).map(e=>{let t=na(e,[`name`,`type`,`dataUrl`]),n=W(t.type,64);if(![`image/png`,`image/jpeg`,`image/webp`].includes(n))return U();let i=W(t.dataUrl,Yi.imageBytes*2),a=`data:${n};base64,`;if(!i.startsWith(a))return U();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>Yi.imageBytes)?U():{name:W(t.name,512),type:n,dataUrl:i}}),p={id:o,modelId:ra(a.modelId),modelRevision:ia(a.modelRevision,!0),inferenceId:ra(a.inferenceId),modelName:W(a.modelName,512),prompt:W(a.prompt),content:W(a.content),reasoning:W(a.reasoning),tools:d,status:s===`streaming`?`interrupted`:s,finishReason:aa(a.finishReason,W),usage:aa(a.usage,e=>{let t=na(e,[`prompt_tokens`,`completion_tokens`,`total_tokens`]);return{prompt_tokens:ia(t.prompt_tokens,!0),completion_tokens:ia(t.completion_tokens,!0),total_tokens:ia(t.total_tokens,!0)}}),ttftMs:aa(a.ttftMs,ia),elapsedMs:aa(a.elapsedMs,ia),error:aa(a.error,W),parameters:l,images:t.includeImages?f:[]};return p.status===`complete`&&(!p.finishReason||!p.content&&!p.reasoning&&!p.tools.length)||(i+=sa(JSON.stringify(p)),i>Yi.jsonBytes)?U():p});return{id:s,title:W(o.title,512),systemPrompt:W(o.systemPrompt),turns:l,updatedAt:ia(o.updatedAt,!0)}})}function la(e,t={}){let n=ca(e,t);return sa(JSON.stringify(n))>Yi.jsonBytes?U():n}function ua(e,t={}){let n=JSON.stringify({version:$i,conversations:la(e,t)});return sa(n)>Yi.jsonBytes?U():n}function da(e,t={}){if(sa(e)>Yi.jsonBytes)return U();let n;try{n=JSON.parse(e)}catch{return U()}let r=na(n,[`version`,`conversations`]);return r.version===$i?la(r.conversations,t):U()}function fa(e){return new H(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 pa(e={}){let t=!1,n=!1,r=0,i,a,o=new Set,s=()=>{let t=e.indexedDB??globalThis.indexedDB;if(!t)throw new H(`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(Xi,$i);o.onupgradeneeded=()=>{o.result.objectStoreNames.contains(Zi)||o.result.createObjectStore(Zi)},o.onerror=()=>a(fa(o.error));let l=!1;o.onblocked=()=>{l=!0,a(new H(`Close other WebUI tabs to access local history.`))},o.onsuccess=()=>{if(l||!t||e!==r){o.result.close(),a(new H(`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(Zi,e);o.add(r);let a=i(r.objectStore(Zi));r.oncomplete=()=>{o.delete(r),t(a.result)},r.onabort=r.onerror=()=>{o.delete(r),n(fa(r.error??a.error))}})}catch(e){throw e instanceof H?e:fa(e)}}return{setEnabled(e){t!==e&&(t=e,e||c())},async load(e={}){let t=await u(`readonly`,e=>e.get(Qi));return t===void 0?[]:da(W(t,Yi.jsonBytes),e)},async save(e,n={}){if(!t)return;let r=ua(e,n);await u(`readwrite`,e=>e.put(r,Qi))},async clear(){if(n)throw new H(`Local history is already being cleared.`);n=!0;let e=!1;c();try{await new Promise((t,r)=>{let i=s().deleteDatabase(Xi);i.onsuccess=()=>{n=!1,t()},i.onerror=()=>{n=!1,r(fa(i.error))},i.onblocked=()=>{e=!0,r(new H(`Close other WebUI tabs to clear local history.`))}})}catch(t){throw e||(n=!1),t instanceof H?t:fa(t)}},close:c}}var ma=[],ha=0,ga=new Set;function _a(){return ha}function va(e){return{id:crypto.randomUUID(),title:e,systemPrompt:``,turns:[],updatedAt:Date.now()}}var ya=new WeakMap;function ba(e){let t=ya.get(e);if(t!==void 0)return t;let n=new TextEncoder().encode(JSON.stringify(e)).byteLength;return ya.set(e,n),n}function xa(e){return e.length>Yi.conversations||e.reduce((e,t)=>e+t.turns.length,0)>Yi.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+ba(t),0)+Math.max(0,t.turns.length-1),0)<=Yi.jsonBytes}function Sa(e){ma=e;for(let e of ga)e()}function Ca(e){if(!xa(e))throw Error(`Conversation memory limit exceeded.`);ha++,Sa(e)}function wa(e){let t=ma.some(t=>t.id===e.id)?ma.map(t=>t.id===e.id?e:t):[...ma,e];return xa(t)?(Sa(t),!0):!1}function Ta(){return(0,_.useSyncExternalStore)(e=>(ga.add(e),()=>ga.delete(e)),()=>ma)}var Ea=(0,_.lazy)(()=>$r(()=>import(`./code-highlight-DRHjgY60.js`),[],import.meta.url)),Da=65536,Oa=512;function ka(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)(Ea,{code:e,language:t})}):(0,x.jsx)(`code`,{children:e})})]})}),Ma=(0,_.memo)(function({text:e,streaming:t=!1}){let n=e.slice(0,Da).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)(ja,{code:o.join(` `),language:s[2].slice(0,40),complete:c||!t&&e.length<=Da},a))}else if(/^#{1,6} /.test(o))r.push((0,x.jsx)(`p`,{className:`chat-markdown-heading`,children:(0,x.jsx)(`strong`,{children:ka(o.replace(/^#{1,6} /,``))})},a));else if(/^[-*] /.test(o)){let e=[o.slice(2)];for(;i(0,x.jsx)(`li`,{children:ka(e)},t))},a))}else o.trim()&&r.push((0,x.jsx)(`p`,{children:ka(o)},a))}return(0,x.jsxs)(`div`,{className:`chat-markdown`,children:[r,(e.length>Da||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)(Ma,{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 Fa({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)(Pa,{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 Ia({conversations:e,busy:t,onPending:n,limits:r,onReplace:i,locale:a}){let o=(0,_.useRef)(pa()),[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 La(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)(De,{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([ua(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=da(e,{includeImages:p});await La(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)(B,{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 La(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 Bi(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 Ra(e,t){let n=Object.fromEntries(Object.entries(t).filter(([,e])=>e!==void 0&&e.trim()!==``).map(([e,t])=>[e,Number(t)]));return{...En({...e,...n})}}function za({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:Tn.map(i=>(0,x.jsx)(Ce,{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 Ba=new Set([`en`,`ko`].map(e=>R(e,`chat.conversation.default_title`)));function Va({locale:e}){let t=Sn(),n=Cn(),{defaults:r}=Mn(),[i,a]=(0,_.useState)({}),o=Ta(),[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=va(O(`chat.conversation.default_title`));wa(e),c(e.id),u(``),f([])},oe=()=>{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`))})},se=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=Ra(r,i)}catch(e){m(e instanceof Error?e.message:O(`chat.error.invalid_parameters`));return}let s=j??va(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&&Ba.has(s.title)?l.slice(0,80):s.title,turns:[...s.turns,_],updatedAt:Date.now()};try{if(!t.bootstrap)throw Error(`Limits unavailable`);zi(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:qi(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(!wa(s)){m(O(`chat.error.memory_budget`));return}let S=null,w=_a(),T={controller:p,turn:_,conversation:s,flush:()=>{if(S!==null&&clearTimeout(S),S=null,_a()!==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()},wa(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)},wa(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=Gi(T.turn,e.data,performance.now()-h),S===null&&(S=setTimeout(T.flush,50)))}},p.signal),p.signal.aborted||(T.turn=Ki(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)}},ce=()=>{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),wa({...j,turns:j.turns.slice(0,t)}),window.setTimeout(()=>k.current?.focus(),0)},[le,P=``]=R(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:R(e,`chat.eyebrow`)}),(0,x.jsx)(`h1`,{tabIndex:-1,"data-dialog-focus-fallback":!0,"data-testid":z(`chat.title`),children:R(e,`chat.title`)}),(0,x.jsx)(`p`,{children:R(e,`chat.intro`)})]}),(0,x.jsxs)(`div`,{className:`chat-toolbar`,children:[(0,x.jsx)(N,{onClick:ae,disabled:v||b||C||o.length>=50,children:R(e,`chat.new_conversation`)}),(0,x.jsx)(Se,{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)(Se,{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} · ${qn(e,t.lifecycle.state)}`}))]})]}),re?null:(0,x.jsx)(B,{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)(Ce,{label:R(e,`chat.settings.name`),value:j.title,disabled:v||b||C,onChange:e=>wa({...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:Vi,disabled:v||b||C,onChange:e=>wa({...j,systemPrompt:e.target.value})})]}),(0,x.jsxs)(`p`,{children:[le,(0,x.jsx)(`a`,{href:`#settings`,children:R(e,`nav.settings`)}),P]}),(0,x.jsx)(N,{disabled:v||b||C,onClick:()=>{Ca(o.filter(e=>e.id!==j.id)),c(null)},children:R(e,`chat.settings.delete`)})]}):null,(0,x.jsx)(za,{defaults:r,draft:i,onChange:a,locale:e}),(0,x.jsx)(Fa,{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)(De,{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:ce,onClose:()=>E(null)}),p?(0,x.jsx)(B,{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:Vi,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(),se())}})]}),(0,x.jsx)(`p`,{children:R(e,`chat.composer.hint`,{count:String(l.length),max:String(Vi)})}),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),Bi(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:()=>{se()},children:R(e,`common.send`)}),(0,x.jsx)(N,{disabled:!v,onClick:oe,children:R(e,`chat.stop`)})]})]}),(0,x.jsx)(`p`,{role:`status`,"aria-live":`polite`,"aria-atomic":`true`,children:h}),(0,x.jsx)(Ia,{conversations:o,busy:v||C,onPending:S,limits:t.bootstrap?.media_limits,onReplace:e=>{Ca(e),c(null)},locale:e})]})}var Ha=[`models`,`chat`,`activity`,`settings`,`gallery`],Ua=[`models`,`chat`,`activity`,`settings`];function Wa(){let e=window.location.hash.slice(1).replace(/^\//,``);return Ha.includes(e)?e:`models`}function Ga(){let e=Sn(),t=Cn(),[n,r]=(0,_.useState)(Wa),[i,a]=(0,_.useState)(Lr),[o,s]=(0,_.useState)(null),[c,l]=(0,_.useState)(null),u=(0,_.useRef)(0);(0,_.useEffect)(()=>()=>{u.current+=1},[]),(0,_.useEffect)(()=>{let e=()=>r(Wa());return window.addEventListener(`hashchange`,e),()=>window.removeEventListener(`hashchange`,e)},[]),(0,_.useEffect)(()=>{if(Br(document.documentElement,i),Rr(i),i.colorScheme===`system`)return Dr(e=>Br(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`&&Ca([])},[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(Fn(e)))})},p=()=>{u.current+=1,l(null),t.logout()},m=Ka(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)(pr,{locale:i.locale,route:n,onRouteChange:d,onCommand:()=>s(`command`),onHelp:()=>s(`help`),selectedModel:In(i.locale,e),connectionLabel:Ln(i.locale,e),connectionState:e.connection,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:m}),(0,x.jsx)(Qa,{open:o===`command`,locale:i.locale,onClose:()=>s(null),onNavigate:e=>{d(e),s(null)}}),(0,x.jsxs)(Ee,{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.jsxs)(`ul`,{className:`shortcut-list`,children:[(0,x.jsxs)(`li`,{children:[(0,x.jsx)(`kbd`,{children:`⌘/Ctrl`}),` + `,(0,x.jsx)(`kbd`,{children:`K`}),` `,R(i.locale,`command.search`)]}),(0,x.jsxs)(`li`,{children:[(0,x.jsx)(`kbd`,{children:`Esc`}),` `,R(i.locale,`common.cancel`)]}),(0,x.jsxs)(`li`,{children:[(0,x.jsx)(`kbd`,{children:`[`}),` / `,(0,x.jsx)(`kbd`,{children:`]`}),` `,R(i.locale,`nav.models`)]})]})]})]})}function Ka(e,t,n,r){return e===`models`?(0,x.jsx)(qa,{locale:t.locale,context:r}):e===`chat`?(0,x.jsx)(Ja,{locale:t.locale,context:r}):e===`activity`?(0,x.jsx)(Ya,{locale:t.locale,context:r}):e===`settings`?(0,x.jsx)(Xa,{appearance:t,setAppearance:n}):(0,x.jsx)(ki,{locale:t.locale})}function qa(e){return e.context.snapshot.auth.status===`authenticated`&&e.context.snapshot.connection!==`schema-mismatch`?(0,x.jsx)(wi,{locale:e.locale}):(0,x.jsx)(zn,{locale:e.locale,eyebrow:R(e.locale,`routes.models.eyebrow`),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 Ja(e){return e.context.snapshot.auth.status===`authenticated`&&e.context.snapshot.connection!==`schema-mismatch`?(0,x.jsx)(Va,{locale:e.locale}):(0,x.jsx)(zn,{locale:e.locale,eyebrow:R(e.locale,`routes.chat.eyebrow`),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 Ya(e){return e.context.snapshot.auth.status===`authenticated`&&![`schema-mismatch`,`forbidden`,`unauthorized`].includes(e.context.snapshot.connection)?(0,x.jsx)(ti,{locale:e.locale}):(0,x.jsx)(zn,{locale:e.locale,eyebrow:R(e.locale,`routes.activity.eyebrow`),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 Xa(e){let t=t=>e.setAppearance({...e.appearance,...t});return(0,x.jsxs)(`div`,{className:`screen-stack`,children:[(0,x.jsxs)(`section`,{className:`screen-heading`,children:[(0,x.jsx)(`p`,{className:`eyebrow`,children:R(e.appearance.locale,`routes.settings.eyebrow`)}),(0,x.jsx)(`h1`,{tabIndex:-1,"data-dialog-focus-fallback":!0,"data-testid":z(`settings.title`),children:R(e.appearance.locale,`settings.title`)}),(0,x.jsx)(`p`,{"data-testid":z(`settings.appearance`),children:R(e.appearance.locale,`settings.browser_only`)})]}),(0,x.jsxs)(`div`,{className:`settings-grid`,children:[(0,x.jsx)(Se,{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)(Se,{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)(Se,{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)(Se,{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)(Se,{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)(Za,{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)(Za,{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)(B,{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)(dr,{locale:e.appearance.locale})]})}function Za(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 Qa(e){let[t,n]=(0,_.useState)(``),r=(e.locale&&window.location.hash.includes(`gallery`)?Ha:Ua).filter(e=>e.includes(t.toLowerCase()));return(0,x.jsxs)(Ee,{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)(Ce,{label:R(e.locale,`command.search`),value:t,onChange:n,testId:z(`command.search`)}),r.length===0?(0,x.jsx)(`p`,{"data-testid":z(`command.no_results`),children:R(e.locale,`command.no_results`)}):(0,x.jsx)(`div`,{className:`command-list`,children:r.map(t=>(0,x.jsx)(N,{onClick:()=>e.onNavigate(t),children:R(e.locale,t===`models`?`nav.models`:t===`chat`?`nav.chat`:t===`activity`?`nav.activity`:t===`settings`?`nav.settings`:`nav.gallery`)},t))})]})}var $a=document.getElementById(`root`);if($a===null)throw Error(`Missing #root element for mlxcel WebUI.`);(0,v.createRoot)($a).render((0,x.jsx)(_.StrictMode,{children:(0,x.jsx)(xn,{children:(0,x.jsx)(Ga,{})})}));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-D9efccbm.css b/src/webui/assets/assets/index-D9efccbm.css new file mode 100644 index 000000000..2954b4520 --- /dev/null +++ b/src/webui/assets/assets/index-D9efccbm.css @@ -0,0 +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}}.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)}.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}.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,.ds-icon-button:hover{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-sheet[data-position=left]{width:min(320px,100vw - 32px);min-height:calc(100vh - 24px);margin:12px auto 12px 12px}.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)}.ds-common-table{color:var(--color-text);background:var(--material-content-bg);border-radius:var(--radius-lg)}@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} diff --git a/src/webui/assets/index.html b/src/webui/assets/index.html index 5c700092f..7015a7f2e 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 f3059f42b..aecab75a6 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": 709972, + "embedded_asset_bytes": 709694, "embedded_asset_limit_bytes": 5242880, - "initial_js_gzip_bytes": 153100, + "initial_js_gzip_bytes": 153102, "initial_js_gzip_limit_bytes": 204800, - "total_js_gzip_bytes": 154276, + "total_js_gzip_bytes": 154282, "total_js_gzip_limit_bytes": 716800 }, "files": [ { "bytes": 951, - "gzip_bytes": 612, - "path": "assets/code-highlight-CPbBnAiM.js", - "sha256": "e3b8b63aa9ec6be412b0cadc01521c38a2fe5513369f68adf1e2e00e9cc35b03" + "gzip_bytes": 614, + "path": "assets/code-highlight-DRHjgY60.js", + "sha256": "d882ba75ca5f4fec291f39b60e61b3291cff17a7fc15540dded2e57994fa701e" }, { "bytes": 1134, - "gzip_bytes": 564, - "path": "assets/history-D3yl7FGt.js", - "sha256": "31919fc0639f4fcad044049f45c4a4bf858a7f5e75c8c9ab45c1809ca85aed32" + "gzip_bytes": 566, + "path": "assets/history-DZcGwKDZ.js", + "sha256": "70acd3c453273fb918d9dbbcc13d25429b26bc95385b6e6f42843c83259c8c25" }, { - "bytes": 97199, - "gzip_bytes": 15798, - "path": "assets/index-BhcZpYw7.css", - "sha256": "fb6ef3ad583c3bab7b02150b9f9c3bbb3067f63ec861140e9b485deaf16e51be" + "bytes": 592551, + "gzip_bytes": 152113, + "path": "assets/index-CB18JmW6.js", + "sha256": "7226f9f9bb5f3471730d8e9c5be2ee9feaccbd8de0ddfcfcd58907af40fc123b" }, { - "bytes": 592551, - "gzip_bytes": 152111, - "path": "assets/index-D8jBk5_a.js", - "sha256": "d3d12dd8aa5de4539f217c69c2077fac5948bf94b09da30d482abbf4b4fd3250" + "bytes": 96921, + "gzip_bytes": 15730, + "path": "assets/index-D9efccbm.css", + "sha256": "af755fdc7ec60b3a5aa5ceb88a92379500544dc6807bdad755a87ff100f5f155" }, { "bytes": 503, - "gzip_bytes": 303, + "gzip_bytes": 301, "path": "index.html", - "sha256": "434c5e4733a5d4b1954e73d44e71b5cff05c8a23d3d79cc2b3cf0b1c471bf1bb" + "sha256": "34c9c1fbe12d9d9fcfa9a6b37f287092391e72adfc77d8e3269c993433ea0c22" }, { "bytes": 2129, @@ -73,5 +73,5 @@ }, "pnpm_version": "11.18.0", "schema_version": 1, - "source_digest_sha256": "0dc47e6a66d6478bce27b7ee26f7402752ab9ee9799202ce2d73305fdd65e3d4" + "source_digest_sha256": "bf0835e8cf1fbff29f4d9b20f28b1e597127d52a501ce42d97a3a9c05794ee93" } diff --git a/webui/scripts/check-theme-selectors.mjs b/webui/scripts/check-theme-selectors.mjs index c7b759b7d..bc1eafcda 100644 --- a/webui/scripts/check-theme-selectors.mjs +++ b/webui/scripts/check-theme-selectors.mjs @@ -45,14 +45,14 @@ * GitHub ::error annotation on the offending line. */ -import { readdirSync, readFileSync, statSync } from 'node:fs'; +import { readdirSync, readFileSync, realpathSync, statSync } from 'node:fs'; import { dirname, extname, join, relative, resolve, sep } from 'node:path'; import { fileURLToPath } from 'node:url'; import { THEME_FAMILIES, THEME_IDS } from '../src/design-system/theme.ts'; -const SCANNED_EXTENSIONS = new Set(['.css', '.ts', '.tsx', '.js', '.mjs', '.html']); -const SCRIPT_EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.mjs']); +const SCRIPT_EXTENSIONS = new Set(['.ts', '.tsx', '.mts', '.cts', '.js', '.jsx', '.mjs', '.cjs']); +const SCANNED_EXTENSIONS = new Set(['.css', '.html', ...SCRIPT_EXTENSIONS]); const THEMES_DIR = 'src/design-system/themes'; const THEME_ENTRY_CSS = `${THEMES_DIR}/index.css`; const THEME_ENTRY_IMPORTER = 'src/main.tsx'; @@ -66,8 +66,12 @@ const SYSTEM_SCHEME_RESOLVERS = new Set(['src/design-system/theme.ts', 'public/t */ const ALLOW_RE = /theme-selector-allow:\s*([^\s*/][^*\n]*)/; -/** `[attr]`, `[attr="v"]`, `[attr^='v' i]`, `[attr=v]` for the three theme attributes. */ -const ATTRIBUTE_SELECTOR_RE = /\[\s*(data-theme-family|data-color-scheme|data-theme)\s*(?:([~|^$*]?=)\s*(?:"([^"]*)"|'([^']*)'|([^\s\]"'`]+))\s*([iIsS])?\s*)?\]/g; +/** + * `[attr]`, `[attr="v"]`, `[attr^='v' i]`, `[attr=v]` for the three theme + * attributes. Attribute names match case-insensitively, as they do in HTML + * documents; each whitespace run has one quantifier so matching stays linear. + */ +const ATTRIBUTE_SELECTOR_RE = /\[\s*(data-theme-family|data-color-scheme|data-theme)\s*(?:([~|^$*]?=)\s*(?:"([^"]*)"|'([^']*)'|([^\s\]"'`]+))\s*(?:([iIsS])\s*)?)?\]/gi; const MEDIA_COLOR_SCHEME_RE = /@media[^{;]*prefers-color-scheme/g; const ANY_COLOR_SCHEME_RE = /prefers-color-scheme/g; /** Literal values compared with, or written to, data-theme in script code. */ @@ -80,7 +84,8 @@ const SCRIPT_THEME_VALUE_RES = [ /toHaveAttribute\(\s*['"]data-theme['"]\s*,\s*(['"])([^'"\n]*)\1/g, ]; const CSS_IMPORT_RE = /@import\s+(?:url\(\s*)?(['"]?)([^'")\s;]+)\1/g; -const SCRIPT_IMPORT_RE = /(?:\bimport\s+(?:[\w$*{}\s,]+\s+from\s+)?|\bimport\(\s*|\brequire\(\s*)(['"])([^'"\n]+)\1/g; +/** `import x from 'm'`, `import 'm'`, `import('m')`, `require('m')`: the first string after the keyword, lazily, so the scan is linear. */ +const SCRIPT_IMPORT_RE = /\b(?:import|require)\b[^'";]*?(['"])([^'"\n]+)\1/g; /** Evaluates one attribute selector against a candidate value, per Selectors Level 4. */ export function attributeMatches(operator, value, caseInsensitive, candidate) { @@ -165,7 +170,8 @@ export function findThemeSelectorViolations(sources, options = {}) { }; for (const match of source.matchAll(ATTRIBUTE_SELECTOR_RE)) { - const [, attribute, operator] = match; + const attribute = match[1].toLowerCase(); + const operator = match[2]; if (operator === undefined) continue; const value = match[3] ?? match[4] ?? match[5] ?? ''; if (value.includes('${')) continue; @@ -274,5 +280,13 @@ function main() { process.exit(1); } -const invokedDirectly = import.meta.url.startsWith('file:') && process.argv[1] && resolve(process.argv[1]) === resolve(fileURLToPath(import.meta.url)); +// Node resolves symlinks for import.meta.url, so compare real paths: a run through a symlinked path must not skip the check silently. +function realPath(path) { + try { + return realpathSync(path); + } catch { + return resolve(path); + } +} +const invokedDirectly = import.meta.url.startsWith('file:') && Boolean(process.argv[1]) && realPath(process.argv[1]) === realPath(fileURLToPath(import.meta.url)); if (invokedDirectly) main(); diff --git a/webui/scripts/check-theme-selectors.spec.mjs b/webui/scripts/check-theme-selectors.spec.mjs index 59c0a5c66..7f168630f 100644 --- a/webui/scripts/check-theme-selectors.spec.mjs +++ b/webui/scripts/check-theme-selectors.spec.mjs @@ -1,8 +1,10 @@ // Copyright 2025-2026 Lablup Inc. Licensed under the Apache License, Version 2.0. -/* global URL */ +/* global URL, process */ import assert from 'node:assert/strict'; -import { readFileSync } from 'node:fs'; -import { resolve } from 'node:path'; +import { execFileSync } from 'node:child_process'; +import { cpSync, mkdtempSync, readFileSync, rmSync, symlinkSync, writeFileSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join, resolve } from 'node:path'; import { test } from 'node:test'; import { fileURLToPath } from 'node:url'; @@ -83,6 +85,33 @@ test('selectors that match no shipped id or family fail, including case and pref assert.deepEqual(rules(scan('src/features/example.css', dead)), ['dead-theme-selector@1', 'dead-theme-selector@2', 'dead-theme-selector@3', 'dead-theme-selector@4', 'dead-theme-selector@5', 'dead-theme-selector@6']); }); +test('attribute names match case-insensitively, as in HTML documents', () => { + assert.deepEqual(rules(scan('src/example.css', '[DATA-THEME="dark"] .x { color: red; }\n[Data-Theme$="-dark"] .y { color: red; }')), ['dead-theme-selector@1']); +}); + +test('pathological whitespace does not make the scan super-linear', () => { + const started = Date.now(); + // Neither input matches; the old patterns backtracked cubically and quadratically on them. + scan('src/example.ts', `import${' '.repeat(3000)};\n[data-theme="glass-dark"${' '.repeat(40000)}x`); + assert.ok(Date.now() - started < 1000, `scan took ${Date.now() - started} ms`); +}); + +test('a symlinked invocation still runs the check', () => { + const scratch = mkdtempSync(join(tmpdir(), 'theme-gate-')); + try { + const copy = join(scratch, 'webui'); + for (const directory of ['scripts', 'src', 'public', 'tests']) cpSync(join(webuiRoot, directory), join(copy, directory), { recursive: true }); + cpSync(join(webuiRoot, 'index.html'), join(copy, 'index.html')); + const tokens = join(copy, 'src/design-system/tokens.css'); + writeFileSync(tokens, `${readFileSync(tokens, 'utf8')}\n:root[data-theme="dark"] { color-scheme: dark; }\n`); + const link = join(scratch, 'gate.mjs'); + symlinkSync(join(copy, 'scripts/check-theme-selectors.mjs'), link); + assert.throws(() => execFileSync(process.execPath, [link], { stdio: 'pipe' }), (error) => error.status === 1 && String(error.stderr).includes('dead-theme-selector')); + } finally { + rmSync(scratch, { recursive: true, force: true }); + } +}); + test('a data-color-scheme value selector is rejected because it holds the raw preference', () => { assert.deepEqual(rules(scan('src/example.css', '[data-color-scheme="dark"] .x { color: red; }')), ['data-color-scheme@1']); }); diff --git a/webui/src/design-system/theme-bootstrap.test.ts b/webui/src/design-system/theme-bootstrap.test.ts index b1f8b6545..4728f8280 100644 --- a/webui/src/design-system/theme-bootstrap.test.ts +++ b/webui/src/design-system/theme-bootstrap.test.ts @@ -99,8 +99,9 @@ describe('index.html', () => { it('loads the bootstrap as a classic, render-blocking script in ', () => { const tag = head.match(/]*\bsrc="\.\/theme-bootstrap\.js"[^>]*><\/script>/); expect(tag).not.toBeNull(); - // Any type attribute (module included), async or defer would stop it blocking the first paint. - expect(tag?.[0]).not.toMatch(/\btype=|\basync\b|\bdefer\b/); + // Any type attribute (module included), async or defer would stop it blocking the first paint, and nomodule would skip it. + expect(tag?.[0]).not.toMatch(/\btype=|\basync\b|\bdefer\b|\bnomodule\b/); + expect(indexHtml.split('./theme-bootstrap.js').length - 1).toBe(1); }); it('carries no inline script, which the served CSP (script-src self) would block', () => { diff --git a/webui/src/design-system/themes/glass.css b/webui/src/design-system/themes/glass.css index 72d112977..bd9b8fd0b 100644 --- a/webui/src/design-system/themes/glass.css +++ b/webui/src/design-system/themes/glass.css @@ -18,7 +18,10 @@ * It reads the appearance switches the product already has and adds none: * - glass intensity: --material-glass-alpha, --material-glass-blur and * --material-glass-saturation from ../glass-intensity.css - * (data-glass-intensity 0..100), which size the chrome and control glass; + * (data-glass-intensity 0..100), which size the chrome glass. Buttons get + * a tinted translucent fill but no backdrop blur of their own: they sit on + * transcript, table and form surfaces, which stay stable, and a blur layer + * per button would be re-rendered on every streamed token; * - data-material, data-reduce-transparency, data-backdrop-filter and * data-high-contrast, plus prefers-reduced-transparency and * prefers-contrast: any of them turns every translucent glass surface in @@ -91,7 +94,6 @@ /* Family-wide glass bindings over contract.css. */ [data-theme="glass-light"], [data-theme="glass-dark"] { - --material-control-backdrop: blur(calc(var(--material-glass-blur) / 2)) saturate(var(--material-glass-saturation)); --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); @@ -102,7 +104,6 @@ --token-buttonPrimaryBorder: 1px solid var(--glass-edge); --token-buttonPrimaryShadow: var(--glass-button-shadow); --token-buttonPrimaryShadowHover: var(--glass-button-shadow); - --token-buttonSecondaryBackdrop: var(--material-control-backdrop); --token-buttonSecondaryShadow: var(--shadow-chrome); --token-buttonSecondaryShadowHover: var(--shadow-chrome); --token-colorBgMask: rgba(8, 10, 14, 0.32); @@ -121,7 +122,6 @@ :root[data-theme-family="glass"][data-high-contrast="on"] { --material-content-bg: var(--color-bg-elevated); --material-control-bg: var(--color-bg-neutral); - --material-control-backdrop: none; --button-primary-fill: var(--button-primary-solid); --button-danger-fill: var(--button-danger-solid); } @@ -130,7 +130,6 @@ :root[data-theme-family="glass"] { --material-content-bg: var(--color-bg-elevated); --material-control-bg: var(--color-bg-neutral); - --material-control-backdrop: none; --button-primary-fill: var(--button-primary-solid); --button-danger-fill: var(--button-danger-solid); } @@ -140,7 +139,6 @@ :root[data-theme-family="glass"]:not([data-high-contrast="off"]) { --material-content-bg: var(--color-bg-elevated); --material-control-bg: var(--color-bg-neutral); - --material-control-backdrop: none; --button-primary-fill: var(--button-primary-solid); --button-danger-fill: var(--button-danger-solid); } diff --git a/webui/tests/theme.spec.ts b/webui/tests/theme.spec.ts index 35657d3f3..39b5f3882 100644 --- a/webui/tests/theme.spec.ts +++ b/webui/tests/theme.spec.ts @@ -206,8 +206,8 @@ test.describe('theme system', () => { expect(chrome.filter).toMatch(/^(none|blur\(0px\)( saturate\(1\))?)$/); expect(chrome.image).toBe('none'); expect(chrome.color).not.toMatch(/rgba\(.*, 0\.\d+\)$/); - const values = await rootValues(page, ['--material-control-backdrop', '--token-buttonPrimaryBg', '--material-content-bg', '--color-bg-elevated']); - expect(values['--material-control-backdrop']).toBe('none'); + const values = await rootValues(page, ['--token-buttonSecondaryBackdrop', '--token-buttonPrimaryBg', '--material-content-bg', '--color-bg-elevated']); + expect(values['--token-buttonSecondaryBackdrop']).toBe('none'); expect(values['--token-buttonPrimaryBg']).not.toContain('gradient'); expect((await buttonFill(page, '.ds-button-primary')).image).toBe('none'); expect(values['--material-content-bg']).toBe(values['--color-bg-elevated']); From f3266c391cd1c6b117e354a8283628e20dc2a3a6 Mon Sep 17 00:00:00 2001 From: Jeongkyu Shin Date: Sat, 19 Sep 2026 14:37:43 +0900 Subject: [PATCH 5/6] test(webui): cover glass intensity clamping in appearance preferences data-glass-intensity has one discrete CSS rule per integer 0-100 in glass-intensity.css, so a value outside that range or shape (negative, over 100, a fraction, a non-finite number, a non-numeric string) previously reached loadAppearance and applyAppearance untested; an unclamped write there would silently drop the glass blur and saturation with no visible error. Adds two preferences.test.ts cases covering clampIntensity's boundary behavior through both entry points, and updates the Vitest count in docs/webui/design-system.md's Verification section from 425 to 427. Regenerates src/webui/assets/mlxcel-webui-manifest.json (source_digest_sha256 only; asset bytes are unchanged) since the test file lives under webui/src. Validation: pnpm --dir webui run typecheck/lint/check:theme-selectors/unit (35 node:test, 427 Vitest across 40 files), pnpm exec playwright test against the full theme/browser/activity/chat/models/settings suite (60 passed), python3 scripts/webui/build_bundle.py --verify, check_webui_contract.py --self-test, check_binary_assets.py and check_cross_repo_refs.py. --- docs/webui/design-system.md | 2 +- src/webui/assets/mlxcel-webui-manifest.json | 2 +- webui/src/design-system/preferences.test.ts | 25 +++++++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/docs/webui/design-system.md b/docs/webui/design-system.md index 5606ee742..6267bb61b 100644 --- a/docs/webui/design-system.md +++ b/docs/webui/design-system.md @@ -57,7 +57,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 425 Vitest tests across 40 files, covering the shared client/provider, shell and theme behavior. `pnpm --dir webui run browser` executes 60 Playwright tests, 61 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, 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 427 Vitest tests across 40 files, covering the shared client/provider, shell and theme behavior. `pnpm --dir webui run browser` executes 60 Playwright tests, 61 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, 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/src/webui/assets/mlxcel-webui-manifest.json b/src/webui/assets/mlxcel-webui-manifest.json index aecab75a6..a5a048728 100644 --- a/src/webui/assets/mlxcel-webui-manifest.json +++ b/src/webui/assets/mlxcel-webui-manifest.json @@ -73,5 +73,5 @@ }, "pnpm_version": "11.18.0", "schema_version": 1, - "source_digest_sha256": "bf0835e8cf1fbff29f4d9b20f28b1e597127d52a501ce42d97a3a9c05794ee93" + "source_digest_sha256": "e8c3bf5e4d39d8341f74e0bf87938732343dd9e03d248c05f0ce85d4b2fa64ed" } diff --git a/webui/src/design-system/preferences.test.ts b/webui/src/design-system/preferences.test.ts index 2b3cebf71..e77dbadb2 100644 --- a/webui/src/design-system/preferences.test.ts +++ b/webui/src/design-system/preferences.test.ts @@ -30,6 +30,31 @@ describe('appearance preferences', () => { expect(loadAppearance()).toMatchObject({ themeFamily: 'mlxcel', colorScheme: 'system' }); }); + // glass-intensity.css has one discrete [data-glass-intensity="N"] rule per integer 0-100; a value outside that + // range or shape matches none of them, so an unclamped write would silently drop the glass blur and saturation. + it('clamps stored glass intensity into 0-100, rounds fractions, and falls back to the default for non-numeric input', () => { + localStorage.setItem(APPEARANCE_STORAGE_KEY, JSON.stringify({ glassIntensity: -20 })); + expect(loadAppearance().glassIntensity).toBe(0); + localStorage.setItem(APPEARANCE_STORAGE_KEY, JSON.stringify({ glassIntensity: 250 })); + expect(loadAppearance().glassIntensity).toBe(100); + localStorage.setItem(APPEARANCE_STORAGE_KEY, JSON.stringify({ glassIntensity: 12.6 })); + expect(loadAppearance().glassIntensity).toBe(13); + localStorage.setItem(APPEARANCE_STORAGE_KEY, '{"glassIntensity": 1e999}'); + expect(loadAppearance().glassIntensity).toBe(35); + localStorage.setItem(APPEARANCE_STORAGE_KEY, JSON.stringify({ glassIntensity: '70' })); + expect(loadAppearance().glassIntensity).toBe(35); + }); + + it('clamps a glass intensity passed straight to applyAppearance, not only a value read from storage', () => { + const root = document.documentElement; + applyAppearance(root, { ...DEFAULT_APPEARANCE, glassIntensity: -25 }); + expect(root.dataset.glassIntensity).toBe('0'); + applyAppearance(root, { ...DEFAULT_APPEARANCE, glassIntensity: 340 }); + expect(root.dataset.glassIntensity).toBe('100'); + applyAppearance(root, { ...DEFAULT_APPEARANCE, glassIntensity: 12.4 }); + expect(root.dataset.glassIntensity).toBe('12'); + }); + it('write the applied id to data-theme and keep the raw preference apart', () => { const root = document.documentElement; applyAppearance(root, { ...DEFAULT_APPEARANCE, themeFamily: 'glass', colorScheme: 'system' }, 'dark'); From 1f28f7d88ee96c9846a54b3b7fd550640c11e1d3 Mon Sep 17 00:00:00 2001 From: Jeongkyu Shin Date: Sat, 19 Sep 2026 15:06:56 +0900 Subject: [PATCH 6/6] docs(webui): refresh WebUI test counts after rebasing on main The rebase onto main picked up #1922, which adds Vitest files and Activity and Settings browser cases, so the Verification section now reads 448 Vitest tests across 43 files and 62 Chromium tests (63 with font diagnostics). Refs #1903 --- docs/webui/design-system.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/webui/design-system.md b/docs/webui/design-system.md index 6267bb61b..ec1692057 100644 --- a/docs/webui/design-system.md +++ b/docs/webui/design-system.md @@ -57,7 +57,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 427 Vitest tests across 40 files, covering the shared client/provider, shell and theme behavior. `pnpm --dir webui run browser` executes 60 Playwright tests, 61 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, 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 448 Vitest tests across 43 files, covering the shared client/provider, shell and theme behavior. `pnpm --dir webui run browser` executes 62 Playwright tests, 63 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, 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.