dsh-model-extension 0.3.3 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -40
- package/assets/models-plus-demo-models-tab.png +0 -0
- package/assets/models-plus-demo-provider-tab.png +0 -0
- package/cordis.patch.yml +12 -0
- package/lib/client.js +1764 -1982
- package/lib/client.js.map +1 -1
- package/lib/index.js +182 -14
- package/lib/index.js.map +1 -1
- package/package.json +4 -3
- package/assets/model-extension-mockup.html +0 -105
- package/assets/model-extension-mockup.png +0 -0
package/lib/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["styles","useState","styles","IconChevronDownOutline14","IconChevronRightOutline14","IconTrashOutline16","IconPlusOutline16","extensionZh","extensionEn","styles","useState","styles","Modal","Button","createSnapshotStore","useState","styles","useState","useMemo","styles","useState","styles","IconPlusOutline16","Modal","Button","extensionZh","extensionEn"],"sources":["packages/client/ui-settings-models/src/client/apiKey.ts","packages/client/ui-settings-models/src/client/ModelsSection.module.css","packages/client/ui-settings-models/src/client/EditorFooter.tsx","packages/client/ui-settings-models/src/client/DeepSeekModelsEditor.tsx","official/src/client/ModelsSection.ext.module.css","official/src/client/extension-meta.ts","official/src/client/ModelExtensionFields.tsx","official/src/client/ModelListEditor.ext.tsx","packages/client/ui-settings-models/src/client/store.ts","packages/client/ui-settings-models/src/client/CustomProviderCard.tsx","packages/client/ui-settings-models/src/client/ProviderEditor.tsx","official/src/client/ModelsSection.ext.tsx","packages/client/ui-settings-models/src/client/operations.ts","packages/client/ui-settings-models/src/client/schema-operations.ts","official/src/client/index-extension.ts"],"sourcesContent":["/**\n * Browser-side judgement of a typed API key.\n * @module @deepseek-ai/dsh-client-ui-settings-models/apiKey\n */\n\n/**\n * Twin of `normalizeApiKey` in `@deepseek-ai/dsh-llm`: printable ASCII, space\n * excluded. Client packages reference only client packages, so the charset\n * rule is mirrored here rather than imported; keep the two in step, as\n * `validateDeepSeekModels` is kept in step with the host's `catalogModel`.\n */\nconst LEGAL_API_KEY = /^[\\x21-\\x7E]+$/\n\n/**\n * A pasted `NAME=value` environment line. Two narrowings keep real keys clear\n * of it: the name must be upper-case, so `sk-` forms break at the hyphen, and\n * the `=` must be followed by something other than another `=`, so base64\n * padding on an all-upper-case key (`ABCD==`) is not mistaken for an\n * assignment. This heuristic runs only here — a resolver applying it could\n * lock a user out of a gateway whose key legitimately takes this shape, with\n * the environment refusing it too and no way through.\n */\nconst ENV_LINE = /^[A-Z][A-Z0-9_]*=[^=]/\n\n/**\n * Copy key naming why a typed key cannot be saved. A wrapped paste reports the\n * same format failure as an illegal character: the reader's next move is the\n * same either way — look at the key and paste it again — so naming the two\n * causes apart would spend the field's one line on a distinction that changes\n * nothing about what to do.\n */\nexport type ApiKeyFailureKey = 'keyBlank' | 'keyIllegalCharacters'\n\n/** Whether a value is wrapped in one matching pair of quotes. */\nfunction isQuoted(value: string): boolean {\n const first = value[0]\n if (first !== '\"' && first !== '\\'' && first !== '`') return false\n return value.length > 1 && value.endsWith(first)\n}\n\n/**\n * Judge the key input's current value.\n *\n * An empty field is not a failure: every card opens with it empty even when a\n * key is already stored, where it means keep that one. A field holding only\n * whitespace is a failure rather than an empty field, so typed input is never\n * silently discarded.\n * @param draft - the key input's current value, untrimmed.\n * @returns the copy key for a field-level failure, or `undefined` to allow submit.\n */\nexport function apiKeyFailure(draft: string): ApiKeyFailureKey | undefined {\n if (draft.length === 0) return undefined\n const value = draft.trim()\n if (value.length === 0) return 'keyBlank'\n if (ENV_LINE.test(value) || isQuoted(value)) return 'keyIllegalCharacters'\n if (!LEGAL_API_KEY.test(value)) return 'keyIllegalCharacters'\n return undefined\n}\n","/* Every color resolves through a `--dsw-alias-*` token. Bare `--border` /\n * `--surface` / `--text-*` names, which nothing in this app defines, would\n * render the light-mode literals written as their fallbacks and stay light\n * under the dark theme. */\n\n.section {\n display: flex;\n flex-direction: column;\n gap: 12px;\n max-width: 720px;\n color: var(--dsw-alias-label-primary);\n}\n\n.title {\n margin: 0;\n font-size: 16px;\n line-height: 24px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n}\n\n.intro {\n margin: 0;\n font-size: 14px;\n line-height: 22px;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.notice {\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-state-warn-label);\n}\n\n.savedNotice {\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-state-success-primary);\n}\n\n.rows {\n list-style: none;\n /* Extra air between the title/intro block and the first provider card. */\n margin: 12px 0 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n/* A configured provider: outlined on the panel fill, so the filled editor\n card it expands into reads as the nested object. */\n.rowCard {\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 16px;\n padding: 12px 14px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.rowHead {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.rowIdentity {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n}\n\n.rowName {\n font-size: 14px;\n line-height: 22px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n}\n\n/* Reads as an annotation on the name, not as a second name: caption size and\n the secondary label tone, so it never competes with the row's own title. It\n sits inside `rowIdentity` with the credential dot, which is what keeps it\n beside the name rather than drifting toward the actions. */\n.rowTag {\n flex: none;\n padding: 1px 6px;\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: 4px;\n font-size: 11px;\n line-height: 16px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.credentialDot {\n box-sizing: border-box;\n display: inline-block;\n flex: none;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n corner-shape: round;\n}\n\n.credentialDotConfigured {\n background: var(--dsw-alias-state-success-primary);\n}\n\n.credentialDotMissing {\n background: var(--dsw-alias-state-error-primary);\n}\n\n.rowActions {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n margin-left: auto;\n}\n\n/* `box-sizing` on every control here: the app has no global border-box reset,\n so without it the outlined variants stand 2px taller than the filled ones\n they sit beside (Cancel next to Apply, Edit next to Delete). */\n.primaryButton,\n.secondaryButton,\n.addButton {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n height: 36px;\n padding: 0 14px;\n border: none;\n border-radius: 18px;\n font: inherit;\n font-size: 14px;\n line-height: 22px;\n cursor: pointer;\n}\n\n.primaryButton {\n background: var(--dsw-alias-button-primary-fill);\n color: var(--dsw-alias-label-primary-foreground);\n}\n\n.primaryButton:hover:not(:disabled) {\n background: var(--dsw-alias-button-primary-hover);\n}\n\n.secondaryButton,\n.addButton {\n border: 0.5px solid var(--dsw-alias-border-l3);\n background: transparent;\n color: var(--dsw-alias-label-primary);\n}\n\n.secondaryButton:hover:not(:disabled),\n.addButton:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.secondaryButton:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover-solid);\n}\n\n.dangerButton {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: 36px;\n padding: 0 14px;\n border: none;\n border-radius: 18px;\n background: transparent;\n color: var(--dsw-alias-state-error-primary);\n font: inherit;\n font-size: 14px;\n line-height: 22px;\n cursor: pointer;\n}\n\n.dangerButton:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover-danger);\n}\n\n/* Provider-row controls take the dense capsule (Button `.sm`). */\n.rowActions .secondaryButton,\n.rowActions .dangerButton {\n height: 28px;\n padding: 0 10px;\n border-radius: 14px;\n font-size: 12px;\n line-height: 18px;\n}\n\n.primaryButton:disabled,\n.secondaryButton:disabled,\n.dangerButton:disabled,\n.addButton:disabled,\n.linkButton:disabled,\n.addModelButton:disabled {\n opacity: 0.4;\n cursor: default;\n}\n\n.primaryButton:focus-visible,\n.secondaryButton:focus-visible,\n.dangerButton:focus-visible,\n.addButton:focus-visible,\n.linkButton:focus-visible,\n.addModelButton:focus-visible,\n.iconButton:focus-visible,\n.customizedSummary:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--dsw-alias-border-l3);\n}\n\n/* Editing surface: a filled module on the panel, matching the settings\n selector fill rather than adding another outline inside the row. */\n.editor {\n border-radius: 12px;\n background: var(--dsw-alias-bg-module-platform);\n padding: 14px 16px;\n display: flex;\n flex-direction: column;\n gap: 14px;\n}\n\n.editorHeader {\n display: flex;\n align-items: baseline;\n gap: 8px;\n}\n\n.editorTitle {\n font-size: 14px;\n line-height: 22px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n}\n\n.editorRoute {\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.fieldLabel {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n font-size: 12px;\n line-height: 18px;\n font-weight: 500;\n color: var(--dsw-alias-label-secondary);\n}\n\n.linkButton {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n height: 28px;\n padding: 0 10px;\n border: none;\n border-radius: 14px;\n background: transparent;\n color: var(--dsw-alias-label-tertiary);\n font: inherit;\n font-size: 12px;\n line-height: 18px;\n cursor: pointer;\n}\n\n.linkButton:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-secondary);\n}\n\n.advancedHint {\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.editorActions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n}\n\n.addBlock {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n/* The two ways to gain a provider, as equal siblings spanning the same width\n as the rows above. Wraps rather than shrinking below a legible label. */\n.addActions {\n display: flex;\n flex-wrap: wrap;\n gap: 10px;\n}\n\n.addButton {\n /* Overrides the shared button base above: these two are not pills sitting in\n a footer but the last slot of the provider list, so they split the row\n evenly and repeat the row cards' corner. Dashed, like every other \"nothing\n here yet\" affordance on this page, to read as a place rather than a\n command. */\n flex: 1 1 0;\n min-width: 180px;\n gap: 6px;\n height: 44px;\n border: 1px dashed var(--dsw-alias-border-l3);\n border-radius: 16px;\n}\n\n.addCard,\n.setupCard {\n border-radius: 12px;\n background: var(--dsw-alias-bg-module-platform);\n padding: 14px 16px;\n display: flex;\n flex-direction: column;\n gap: 14px;\n list-style: none;\n}\n\n/* Nested in a card that already carries the module chrome. */\n.addCard .editor,\n.setupCard .editor {\n background: none;\n padding: 0;\n}\n\n.customized {\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n padding-top: 10px;\n}\n\n/* Native disclosure marker replaced by a rotating chevron: the built-in\n triangle differs per engine and cannot take the label color. */\n.customizedSummary {\n display: flex;\n align-items: center;\n gap: 6px;\n width: fit-content;\n padding: 2px 4px;\n margin-left: -4px;\n border-radius: 6px;\n cursor: pointer;\n font-size: 12px;\n line-height: 18px;\n font-weight: 500;\n color: var(--dsw-alias-label-secondary);\n list-style: none;\n}\n\n.customizedSummary::-webkit-details-marker {\n display: none;\n}\n\n.customizedSummary::before {\n content: '';\n width: 5px;\n height: 5px;\n border-right: 1.5px solid currentcolor;\n border-bottom: 1.5px solid currentcolor;\n transform: rotate(-45deg) translate(-1px, -1px);\n transition: transform 120ms ease;\n}\n\n.customized[open] > .customizedSummary::before {\n transform: rotate(45deg) translate(-1px, -1px);\n}\n\n.customizedSummary:hover {\n color: var(--dsw-alias-label-primary);\n}\n\n.customizedBody {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding-top: 12px;\n}\n\n/* Model catalog: a table, not a stack of cards. The column captions are\n written once above the rows, so a row is one line of fields plus its\n delete control; each field still carries the indexed `aria-label` that\n names it, and the caption strip is hidden from assistive tech to keep\n that name from being announced twice. */\n.modelCatalog {\n display: flex;\n flex-direction: column;\n gap: 10px;\n padding-top: 12px;\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n}\n\n.modelCatalogHeading {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.modelCatalogTitle {\n font-size: 12px;\n line-height: 18px;\n font-weight: 500;\n color: var(--dsw-alias-label-secondary);\n}\n\n.modelCatalogMeta,\n.modelEmpty {\n margin: 0;\n color: var(--dsw-alias-label-tertiary);\n font-size: 12px;\n line-height: 18px;\n}\n\n/* Model list, shared with the pi-ai provider form: one bordered\n entry per model, id and display name on the row, capacities behind the\n row's own disclosure. The rules use this stylesheet's token vocabulary —\n `--dsw-alias-border-subtle`, `--dsw-alias-text-tertiary`, and\n `--dsw-alias-text-primary` are undefined here and would resolve to their\n light-mode literals. */\n.modelList {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.modelListHead {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 12px;\n}\n\n.modelEntry {\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 10px;\n padding: 6px;\n}\n\n.modelRow {\n display: grid;\n grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) auto auto;\n align-items: center;\n gap: 6px;\n}\n\n/* Square, label-free affordances: the row's own inputs carry the meaning, so\n the actions stay glyphs and announce themselves through aria-label. */\n.iconButton {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n border-radius: 6px;\n background: transparent;\n color: var(--dsw-alias-label-tertiary);\n cursor: pointer;\n}\n\n.iconButton:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n.iconButton:disabled {\n cursor: default;\n opacity: 0.4;\n}\n\n/* The delete glyph keeps the danger tint the rest of the section uses. */\n.iconButtonDanger:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover-danger);\n color: var(--dsw-alias-state-error-primary);\n}\n\n.modelAdvanced {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 8px;\n padding: 8px 4px 2px;\n}\n\n.modelField {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.modelFieldLabel {\n color: var(--dsw-alias-label-tertiary);\n font-size: 12px;\n line-height: 18px;\n}\n\n.modelEmpty {\n padding: 12px;\n border: 1px dashed var(--dsw-alias-border-l3);\n border-radius: 8px;\n text-align: center;\n}\n\n.addModelButton {\n box-sizing: border-box;\n align-self: flex-start;\n display: inline-flex;\n align-items: center;\n gap: 4px;\n height: 28px;\n padding: 0 10px;\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: 14px;\n background: transparent;\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 12px;\n line-height: 18px;\n cursor: pointer;\n}\n\n.addModelButton:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.input {\n box-sizing: border-box;\n width: 100%;\n height: 32px;\n padding: 0 10px;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 8px;\n font: inherit;\n font-size: 14px;\n line-height: 22px;\n background: var(--dsw-alias-bg-layer-1);\n color: var(--dsw-alias-label-primary);\n}\n\n/* Enum pickers hold a handful of short options; a field-width dropdown reads\n as a text field the user is expected to fill. */\nselect.input {\n max-width: 240px;\n cursor: pointer;\n}\n\n.input:focus {\n outline: none;\n border-color: var(--dsw-alias-brand-primary);\n}\n\n.input::placeholder {\n color: var(--dsw-alias-label-dimmed);\n}\n\n.input:disabled {\n opacity: 0.6;\n cursor: default;\n}\n\n/* Select variant of .input: replaces the OS arrow (which sits flush against\n the right edge) with the shared 12px chevron inset like the composer's\n .select chips; the right pad reserves its cell. */\n.selectInput {\n appearance: none;\n padding-right: 32px;\n /* Data-URI SVGs cannot resolve CSS variables; #81858C is the caption gray\n shared by both themes. */\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%2381858C' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 12px center;\n background-size: 12px 12px;\n}\n\n.error {\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-state-error-primary);\n}\n\n.deleteDialog {\n width: min(480px, 100%);\n}\n\n.deleteConfirm:not(:disabled) {\n border-color: var(--dsw-alias-state-error-primary);\n color: var(--dsw-alias-state-error-primary);\n}\n\n.deleteConfirm:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover-danger);\n}\n\n/* Icon-button label seat: named for assistive tech and for the tests that\n query these controls by their text. */\n.hiddenLabel {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip: rect(0 0 0 0);\n white-space: nowrap;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .customizedSummary::before,\n .switchThumb {\n transition: none;\n }\n}\n\n.fetchDialog {\n max-width: 520px;\n\n /* The candidate list scrolls inside this dialog, an elevated surface, so the\n scrollbar indirection is rebound here rather than on the scrolling child:\n the elevation choice belongs with the surface and inherits down (see\n ui-theme styles/scrollbar.css for the contract). */\n --dsh-scrollbar-thumb: var(--dsw-alias-scrollbar-bg-l2);\n --dsh-scrollbar-thumb-hover: var(--dsw-alias-scrollbar-hover-l2);\n}\n\n.candidateToolbar {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 6px;\n}\n\n.candidateSearch {\n min-width: 0;\n flex: 1 1 240px;\n}\n\n.candidateList {\n display: flex;\n flex-direction: column;\n gap: 2px;\n max-height: 320px;\n margin: 0;\n overflow-y: auto;\n padding: 0;\n list-style: none;\n}\n\n.candidate {\n border-radius: 6px;\n}\n\n.candidateLabel {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 8px;\n cursor: pointer;\n}\n\n.candidateId {\n flex: 1 1 auto;\n font-family: var(--ds-font-family-code);\n font-size: 13px;\n overflow-wrap: anywhere;\n}\n\n.candidateEmpty {\n margin: 24px 0;\n color: var(--dsw-alias-label-secondary);\n font-size: 13px;\n line-height: 20px;\n text-align: center;\n}\n","/**\n * The action row every provider card ends with: dismiss on the left, commit on\n * the right.\n *\n * The two cards commit different things — one creates a route, one edits an\n * existing profile — but the row itself carries no such knowledge. It renders\n * what it is handed, so the cards keep sole ownership of when a commit is\n * allowed and what the in-flight wording is.\n *\n * Cancel refuses input only while a commit is in flight, never because the card\n * is disabled: a card the deployment cannot write to must still be dismissable.\n *\n * @module dsh-client-ui-settings-models/client/EditorFooter\n */\n\nimport type { ReactNode } from 'react'\nimport type { en } from './locales.ts'\nimport styles from './ModelsSection.module.css'\n\n/** Props of {@link EditorFooter}. */\nexport interface EditorFooterProps {\n /** Localizer for the row's own labels. */\n t: (key: keyof typeof en) => string\n /** Whether a commit is in flight; holds Cancel and swaps the commit label. */\n busy: boolean\n /** Whether the commit is refused, as judged by the owning card. */\n submitDisabled: boolean\n /** Commit label while idle. */\n submitLabelKey: keyof typeof en\n /** Commit label while a commit is in flight. */\n submitBusyLabelKey: keyof typeof en\n /** Dismiss label; defaults to the settings editor copy. */\n cancelLabelKey?: keyof typeof en\n /** Dismiss the card without committing. */\n onCancel: () => void\n /** Run the card's commit. */\n onSubmit: () => void\n}\n\n/**\n * Render one provider card's action row.\n * @param props - the labels, commit gating, and handlers the owning card supplies.\n * @returns the cancel/commit row.\n */\nexport function EditorFooter(props: EditorFooterProps): ReactNode {\n const { t } = props\n return (\n <div className={styles['editorActions']}>\n <button\n type=\"button\"\n className={styles['secondaryButton']}\n disabled={props.busy}\n onClick={props.onCancel}\n >\n {t(props.cancelLabelKey ?? 'cancel')}\n </button>\n <button\n type=\"button\"\n className={styles['primaryButton']}\n disabled={props.submitDisabled}\n onClick={props.onSubmit}\n >\n {props.busy ? t(props.submitBusyLabelKey) : t(props.submitLabelKey)}\n </button>\n </div>\n )\n}\n","/**\n * Curated editor for the direct DeepSeek adapter's advisory model catalog.\n * The settings layer replaces `models` as one array, so the parent supplies\n * the effective inherited rows until the first edit materializes a user\n * override; reset removes that override instead of copying defaults into it.\n */\n\nimport { useState } from 'react'\nimport type { ReactNode } from 'react'\nimport {\n IconChevronDownOutline14, IconChevronRightOutline14, IconPlusOutline16, IconTrashOutline16,\n} from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { en } from './locales.ts'\nimport styles from './ModelsSection.module.css'\n\n/** One catalog entry kept structurally open so hidden or future fields survive an edit. */\nexport type DeepSeekModelDraft = Record<string, unknown>\n\n/** The catalog fields this editor writes. */\ntype CatalogField = 'id' | 'name' | 'contextWindow' | 'maxTokens'\n\n/** The two token counts edited as K/M-suffixed text behind a row's disclosure. */\ntype CapacityField = 'contextWindow' | 'maxTokens'\n\n/** Row index encoded in an editing-buffer key. */\nfunction rowOf(key: string): number {\n return Number(key.slice(0, key.indexOf(':')))\n}\n\n/** Accepted capacity spellings: a decimal count with an optional K/M suffix. */\nconst CAPACITY_PATTERN = /^(\\d+(?:\\.\\d+)?)([km])?$/i\n\n/** Decimal suffix scales — `1M` is 1000K, matching how model capacities are quoted. */\nconst CAPACITY_SCALE = { k: 1_000, m: 1_000_000 } as const\n\n/**\n * Read a typed capacity, so a user can write `256K` or `1M` instead of counting\n * zeroes. The stored value stays a plain token count.\n * @param text - raw field text.\n * @returns the count; `undefined` when blank (inherit), `NaN` when unreadable\n * (rejected by {@link validateDeepSeekModels} before any write).\n */\nexport function parseCapacity(text: string): number | undefined {\n const trimmed = text.trim()\n if (trimmed.length === 0) return undefined\n const match = CAPACITY_PATTERN.exec(trimmed)\n if (match === null) return Number.NaN\n const suffix = match[2]?.toLowerCase()\n const scale = suffix === 'k' || suffix === 'm' ? CAPACITY_SCALE[suffix] : 1\n const scaled = Number(match[1]) * scale\n // A decimal multiple is exact in intent but not in binary floating point\n // (2.3 * 1e6 lands a few ULPs high), so an integral intent snaps back.\n const rounded = Math.round(scaled)\n return Math.abs(scaled - rounded) < 1e-6 ? rounded : scaled\n}\n\n/**\n * Spell a stored count back in the shortest form that survives a round trip\n * through {@link parseCapacity}; a count that is not a whole number of\n * thousands stays written out.\n * @param value - stored capacity.\n * @returns the field text.\n */\nexport function formatCapacity(value: number): string {\n if (!Number.isInteger(value) || value <= 0) return String(value)\n if (value % CAPACITY_SCALE.m === 0) return `${String(value / CAPACITY_SCALE.m)}M`\n if (value % CAPACITY_SCALE.k === 0) return `${String(value / CAPACITY_SCALE.k)}K`\n return String(value)\n}\n\n/** A localized validation failure for one user-owned model array. */\nexport interface DeepSeekModelsValidationFailure {\n /** Zero-based model position. */\n index: number\n /** Message key owned by the Models settings section. */\n key: 'modelIdRequired' | 'modelIdDuplicate' | 'modelNameInvalid' | 'modelContextInvalid'\n | 'modelMaxTokensInvalid'\n}\n\n/** Convert a schema-validated catalog value into records without dropping hidden fields. */\nexport function modelDrafts(value: unknown): DeepSeekModelDraft[] {\n if (!Array.isArray(value)) return []\n return value.map(entry =>\n typeof entry === 'object' && entry !== null && !Array.isArray(entry)\n ? entry as DeepSeekModelDraft\n : {})\n}\n\n/**\n * Validate adapter constraints that the serialized schema cannot express.\n * @param value - user-owned `models` value, or undefined while inherited.\n * @returns the first invalid row, or undefined when the adapter will accept it.\n */\nexport function validateDeepSeekModels(value: unknown): DeepSeekModelsValidationFailure | undefined {\n if (value === undefined) return undefined\n const models = modelDrafts(value)\n const seen = new Set<string>()\n for (const [index, model] of models.entries()) {\n // Compared trimmed: surrounding whitespace is a paste artifact the adapter\n // would never match, and an untrimmed compare lets `model ` slip past the\n // duplicate check against its own twin.\n const id = model['id']\n const trimmed = typeof id === 'string' ? id.trim() : undefined\n if (trimmed === undefined || trimmed.length === 0) return { index, key: 'modelIdRequired' }\n if (seen.has(trimmed)) return { index, key: 'modelIdDuplicate' }\n seen.add(trimmed)\n const name = model['name']\n if (name !== undefined && (typeof name !== 'string' || name.length === 0)) {\n return { index, key: 'modelNameInvalid' }\n }\n const contextWindow = model['contextWindow']\n if (contextWindow !== undefined\n && (typeof contextWindow !== 'number' || !Number.isInteger(contextWindow) || contextWindow <= 0)) {\n return { index, key: 'modelContextInvalid' }\n }\n const maxTokens = model['maxTokens']\n if (maxTokens !== undefined\n && (typeof maxTokens !== 'number' || !Number.isInteger(maxTokens) || maxTokens <= 0)) {\n return { index, key: 'modelMaxTokensInvalid' }\n }\n }\n return undefined\n}\n\n/** Props of {@link DeepSeekModelsEditor}. */\nexport interface DeepSeekModelsEditorProps {\n /** Effective rows: inherited until the parent materializes an override. */\n models: readonly DeepSeekModelDraft[]\n /** Whether the user layer currently owns the whole array. */\n overridden: boolean\n /** Fallback context capacity used when a row omits its exact value. */\n defaultContextWindow: number | undefined\n /** Fallback output cap used when a row omits its exact value. */\n defaultMaxTokens: number | undefined\n /** Section copy. */\n t: (key: keyof typeof en) => string\n /** Disable every mutation. */\n disabled: boolean\n /** Replace the user-owned array after one visible edit. */\n onChange: (models: DeepSeekModelDraft[]) => void\n /** Remove the user-owned array and return to inheritance. */\n onReset: () => void\n}\n\n/**\n * Render the direct DeepSeek adapter's model catalog: id and display name on\n * each row, capacities behind the row's own disclosure.\n * @param props - effective rows plus the array-level override actions.\n * @returns the catalog editor.\n */\nexport function DeepSeekModelsEditor(props: DeepSeekModelsEditorProps): ReactNode {\n // Capacities are edited as text, so a field's keystrokes are held here\n // rather than re-derived from the parsed count on every change, which would\n // rewrite `1000` to `1K` mid-word. Unreadable text is kept past blur so the\n // save-time rejection names a row the user can still see — which is why\n // this is one entry PER FIELD: a single active buffer would be displaced by\n // editing any other field, and the abandoned one would fall back to\n // rendering its stored NaN as the literal `NaN`.\n //\n // Keys carry the row index, so the two operations that move indexes maintain\n // them: `remove` re-keys around the dropped row, and reset clears them all\n // because the rows they annotated are gone.\n const [editing, setEditing] = useState<ReadonlyMap<string, string>>(() => new Map())\n const [expanded, setExpanded] = useState<ReadonlySet<number>>(() => new Set())\n\n const update = (index: number, key: CatalogField, value: unknown): void => {\n const next = props.models.map((model, at) => {\n const copy = { ...model }\n if (at !== index) return copy\n if (value === undefined) Reflect.deleteProperty(copy, key)\n else copy[key] = value\n return copy\n })\n props.onChange(next)\n }\n\n const remove = (index: number): void => {\n setEditing((current) => {\n const next = new Map<string, string>()\n for (const [key, text] of current) {\n const at = rowOf(key)\n if (at === index) continue\n // Only the row number moves; the field half of the key is untouched.\n next.set(at > index ? key.replace(/^\\d+/, String(at - 1)) : key, text)\n }\n return next\n })\n setExpanded((current) => {\n const next = new Set<number>()\n for (const at of current) {\n if (at === index) continue\n next.add(at > index ? at - 1 : at)\n }\n return next\n })\n props.onChange(props.models.filter((_model, at) => at !== index).map(model => ({ ...model })))\n }\n\n const reset = (): void => {\n setEditing(new Map())\n setExpanded(new Set())\n props.onReset()\n }\n\n const toggle = (index: number): void => {\n setExpanded((current) => {\n const next = new Set(current)\n if (!next.delete(index)) next.add(index)\n return next\n })\n }\n\n /** The field's text: its live keystrokes, else the stored count spelled short. */\n const capacityText = (model: DeepSeekModelDraft, index: number, field: CapacityField): string => {\n const typed = editing.get(`${String(index)}:${field}`)\n if (typed !== undefined) return typed\n const value = model[field]\n return typeof value === 'number' ? formatCapacity(value) : ''\n }\n\n const settleCapacity = (index: number, field: CapacityField): void => {\n const key = `${String(index)}:${field}`\n const typed = editing.get(key)\n if (typed === undefined) return\n // Unreadable text stays on screen: the save-time rejection names a row the\n // user can still see and correct.\n const parsed = parseCapacity(typed)\n if (parsed !== undefined && Number.isNaN(parsed)) return\n setEditing((current) => {\n const next = new Map(current)\n next.delete(key)\n return next\n })\n }\n\n /** One capacity field of one row, rendered inside the row's disclosure. */\n const capacityField = (\n model: DeepSeekModelDraft,\n index: number,\n field: CapacityField,\n fallback: number | undefined,\n ): ReactNode => (\n <label className={styles['modelField']}>\n <span className={styles['modelFieldLabel']}>{props.t(field === 'contextWindow' ? 'contextWindow' : 'maxTokens')}</span>\n <input\n className={styles['input']}\n type=\"text\"\n inputMode=\"numeric\"\n value={capacityText(model, index, field)}\n placeholder={fallback === undefined\n ? props.t(field === 'contextWindow' ? 'contextWindowPlaceholder' : 'maxTokensPlaceholder')\n : formatCapacity(fallback)}\n aria-label={`${props.t(field === 'contextWindow' ? 'contextWindow' : 'maxTokens')} ${String(index + 1)}`}\n disabled={props.disabled}\n onChange={(event) => {\n const text = event.target.value\n setEditing(current => new Map(current).set(`${String(index)}:${field}`, text))\n update(index, field, parseCapacity(text))\n }}\n onBlur={() => { settleCapacity(index, field) }}\n />\n </label>\n )\n\n return (\n <section className={styles['modelCatalog']} aria-label={props.t('models')}>\n <div className={styles['modelListHead']}>\n <div className={styles['modelCatalogHeading']}>\n <span className={styles['modelCatalogTitle']}>{props.t('models')}</span>\n <span className={styles['modelCatalogMeta']}>\n {props.overridden ? props.t('modelsCustomized') : props.t('modelsInherited')}\n </span>\n </div>\n {props.overridden\n ? (\n <button\n type=\"button\"\n className={styles['linkButton']}\n disabled={props.disabled}\n onClick={reset}\n >\n {props.t('resetModels')}\n </button>\n )\n : null}\n </div>\n {props.models.length === 0\n ? <p className={styles['modelEmpty']}>{props.t('modelsEmpty')}</p>\n : (\n <div className={styles['modelList']}>\n {props.models.map((model, index) => (\n <div className={styles['modelEntry']} key={index}>\n <div className={styles['modelRow']}>\n <input\n className={styles['input']}\n type=\"text\"\n value={typeof model['id'] === 'string' ? model['id'] : ''}\n placeholder={props.t('modelId')}\n aria-label={`${props.t('modelId')} ${String(index + 1)}`}\n disabled={props.disabled}\n onChange={(event) => { update(index, 'id', event.target.value) }}\n onBlur={(event) => {\n // Settle a pasted id rather than trimming per keystroke,\n // which would stop the user typing an interior space.\n const trimmed = event.target.value.trim()\n if (trimmed !== event.target.value) update(index, 'id', trimmed)\n }}\n />\n <input\n className={styles['input']}\n type=\"text\"\n value={typeof model['name'] === 'string' ? model['name'] : ''}\n placeholder={props.t('modelName')}\n aria-label={`${props.t('modelName')} ${String(index + 1)}`}\n disabled={props.disabled}\n onChange={(event) => {\n update(index, 'name', event.target.value === '' ? undefined : event.target.value)\n }}\n />\n <button\n type=\"button\"\n className={styles['iconButton']}\n aria-label={`${props.t('modelAdvanced')} ${String(index + 1)}`}\n aria-expanded={expanded.has(index)}\n title={props.t('modelAdvanced')}\n onClick={() => { toggle(index) }}\n >\n {expanded.has(index) ? <IconChevronDownOutline14 /> : <IconChevronRightOutline14 />}\n </button>\n <button\n type=\"button\"\n className={`${styles['iconButton']} ${styles['iconButtonDanger']}`}\n aria-label={`${props.t('removeModel')} ${String(index + 1)}`}\n title={props.t('removeModel')}\n disabled={props.disabled}\n onClick={() => { remove(index) }}\n >\n <IconTrashOutline16 size={14} />\n </button>\n </div>\n {expanded.has(index)\n ? (\n <div className={styles['modelAdvanced']}>\n {capacityField(model, index, 'contextWindow', props.defaultContextWindow)}\n {capacityField(model, index, 'maxTokens', props.defaultMaxTokens)}\n </div>\n )\n : null}\n </div>\n ))}\n </div>\n )}\n <button\n type=\"button\"\n className={styles['addModelButton']}\n disabled={props.disabled}\n onClick={() => { props.onChange([...props.models.map(model => ({ ...model })), { id: '' }]) }}\n >\n <IconPlusOutline16 size={14} />\n {props.t('addModel')}\n </button>\n </section>\n )\n}\n","/* Models settings section, in the settings-panel design language: 14/22 body,\r\n * 12/18 caption, capsule controls (h36 r18; h28 r14 where a row is dense),\r\n * 32px fields, and `border-l2` hairlines — the vocabulary GeneralSection and\r\n * the Button/Input primitives already use.\r\n *\r\n/* Every color resolves through a `--dsw-alias-*` token. Bare `--border` /\r\n * `--surface` / `--text-*` names, which nothing in this app defines, would\r\n * render the light-mode literals written as their fallbacks and stay light\r\n * under the dark theme. */\r\n\r\n.section {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n max-width: 720px;\r\n color: var(--dsw-alias-label-primary);\r\n}\r\n\r\n.title {\r\n margin: 0;\r\n font-size: 16px;\r\n line-height: 24px;\r\n font-weight: 500;\r\n color: var(--dsw-alias-label-primary);\r\n}\r\n\r\n.intro {\r\n margin: 0;\r\n font-size: 14px;\r\n line-height: 22px;\r\n color: var(--dsw-alias-label-tertiary);\r\n}\r\n\r\n.notice {\r\n margin: 0;\r\n font-size: 12px;\r\n line-height: 18px;\r\n color: var(--dsw-alias-state-warn-label);\r\n}\r\n\r\n.savedNotice {\r\n margin: 0;\r\n font-size: 12px;\r\n line-height: 18px;\r\n color: var(--dsw-alias-state-success-primary);\r\n}\r\n\r\n.rows {\r\n list-style: none;\r\n /* Extra air between the title/intro block and the first provider card. */\r\n margin: 12px 0 0;\r\n padding: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n}\r\n\r\n/* A configured provider: outlined on the panel fill, so the filled editor\r\n card it expands into reads as the nested object. */\r\n.rowCard {\r\n border: 0.5px solid var(--dsw-alias-border-l4);\r\n border-radius: 16px;\r\n padding: 12px 14px;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n}\r\n\r\n.rowHead {\r\n display: flex;\r\n align-items: center;\r\n gap: 10px;\r\n}\r\n\r\n.rowIdentity {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 6px;\r\n min-width: 0;\r\n}\r\n\r\n.rowName {\r\n font-size: 14px;\r\n line-height: 22px;\r\n font-weight: 500;\r\n color: var(--dsw-alias-label-primary);\r\n}\r\n\r\n/* Reads as an annotation on the name, not as a second name: caption size and\r\n the secondary label tone, so it never competes with the row's own title. It\r\n sits inside `rowIdentity` with the credential dot, which is what keeps it\r\n beside the name rather than drifting toward the actions. */\r\n.rowTag {\r\n flex: none;\r\n padding: 1px 6px;\r\n border: 0.5px solid var(--dsw-alias-border-l3);\r\n border-radius: 4px;\r\n font-size: 11px;\r\n line-height: 16px;\r\n color: var(--dsw-alias-label-secondary);\r\n}\r\n\r\n.credentialDot {\r\n box-sizing: border-box;\r\n display: inline-block;\r\n flex: none;\r\n width: 8px;\r\n height: 8px;\r\n border-radius: 50%;\r\n corner-shape: round;\r\n}\r\n\r\n.credentialDotConfigured {\r\n background: var(--dsw-alias-state-success-primary);\r\n}\r\n\r\n.credentialDotMissing {\r\n background: var(--dsw-alias-state-error-primary);\r\n}\r\n\r\n.rowActions {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 4px;\r\n margin-left: auto;\r\n}\r\n\r\n/* `box-sizing` on every control here: the app has no global border-box reset,\r\n so without it the outlined variants stand 2px taller than the filled ones\r\n they sit beside (Cancel next to Apply, Edit next to Delete). */\r\n.primaryButton,\r\n.secondaryButton,\r\n.addButton {\r\n box-sizing: border-box;\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 4px;\r\n height: 36px;\r\n padding: 0 14px;\r\n border: none;\r\n border-radius: 18px;\r\n font: inherit;\r\n font-size: 14px;\r\n line-height: 22px;\r\n cursor: pointer;\r\n}\r\n\r\n.primaryButton {\r\n background: var(--dsw-alias-button-primary-fill);\r\n color: var(--dsw-alias-label-primary-foreground);\r\n}\r\n\r\n.primaryButton:hover:not(:disabled) {\r\n background: var(--dsw-alias-button-primary-hover);\r\n}\r\n\r\n.secondaryButton,\r\n.addButton {\r\n border: 0.5px solid var(--dsw-alias-border-l3);\r\n background: transparent;\r\n color: var(--dsw-alias-label-primary);\r\n}\r\n\r\n.secondaryButton:hover:not(:disabled),\r\n.addButton:hover:not(:disabled) {\r\n background: var(--dsw-alias-interactive-bg-hover);\r\n}\r\n\r\n.secondaryButton:hover:not(:disabled) {\r\n background: var(--dsw-alias-interactive-bg-hover-solid);\r\n}\r\n\r\n.dangerButton {\r\n box-sizing: border-box;\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n height: 36px;\r\n padding: 0 14px;\r\n border: none;\r\n border-radius: 18px;\r\n background: transparent;\r\n color: var(--dsw-alias-state-error-primary);\r\n font: inherit;\r\n font-size: 14px;\r\n line-height: 22px;\r\n cursor: pointer;\r\n}\r\n\r\n.dangerButton:hover:not(:disabled) {\r\n background: var(--dsw-alias-interactive-bg-hover-danger);\r\n}\r\n\r\n/* Provider-row controls take the dense capsule (Button `.sm`). */\r\n.rowActions .secondaryButton,\r\n.rowActions .dangerButton {\r\n height: 28px;\r\n padding: 0 10px;\r\n border-radius: 14px;\r\n font-size: 12px;\r\n line-height: 18px;\r\n}\r\n\r\n.primaryButton:disabled,\r\n.secondaryButton:disabled,\r\n.dangerButton:disabled,\r\n.addButton:disabled,\r\n.linkButton:disabled,\r\n.addModelButton:disabled {\r\n opacity: 0.4;\r\n cursor: default;\r\n}\r\n\r\n.primaryButton:focus-visible,\r\n.secondaryButton:focus-visible,\r\n.dangerButton:focus-visible,\r\n.addButton:focus-visible,\r\n.linkButton:focus-visible,\r\n.addModelButton:focus-visible,\r\n.iconButton:focus-visible,\r\n.customizedSummary:focus-visible {\r\n outline: none;\r\n box-shadow: 0 0 0 2px var(--dsw-alias-border-l3);\r\n}\r\n\r\n/* Editing surface: a filled module on the panel, matching the settings\r\n selector fill rather than adding another outline inside the row. */\r\n.editor {\r\n border-radius: 12px;\r\n background: var(--dsw-alias-bg-module-platform);\r\n padding: 14px 16px;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 14px;\r\n}\r\n\r\n.editorHeader {\r\n display: flex;\r\n align-items: baseline;\r\n gap: 8px;\r\n}\r\n\r\n.editorTitle {\r\n font-size: 14px;\r\n line-height: 22px;\r\n font-weight: 500;\r\n color: var(--dsw-alias-label-primary);\r\n}\r\n\r\n.editorRoute {\r\n font-size: 12px;\r\n line-height: 18px;\r\n color: var(--dsw-alias-label-tertiary);\r\n}\r\n\r\n.field {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 6px;\r\n}\r\n\r\n.fieldLabel {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 10px;\r\n font-size: 12px;\r\n line-height: 18px;\r\n font-weight: 500;\r\n color: var(--dsw-alias-label-secondary);\r\n}\r\n\r\n.linkButton {\r\n box-sizing: border-box;\r\n display: inline-flex;\r\n align-items: center;\r\n height: 28px;\r\n padding: 0 10px;\r\n border: none;\r\n border-radius: 14px;\r\n background: transparent;\r\n color: var(--dsw-alias-label-tertiary);\r\n font: inherit;\r\n font-size: 12px;\r\n line-height: 18px;\r\n cursor: pointer;\r\n}\r\n\r\n.linkButton:hover:not(:disabled) {\r\n background: var(--dsw-alias-interactive-bg-hover);\r\n color: var(--dsw-alias-label-secondary);\r\n}\r\n\r\n.advancedHint {\r\n margin: 0;\r\n font-size: 12px;\r\n line-height: 18px;\r\n color: var(--dsw-alias-label-tertiary);\r\n}\r\n\r\n.editorActions {\r\n display: flex;\r\n justify-content: flex-end;\r\n gap: 8px;\r\n}\r\n\r\n.addBlock {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n}\r\n\r\n/* The two ways to gain a provider, as equal siblings spanning the same width\r\n as the rows above. Wraps rather than shrinking below a legible label. */\r\n.addActions {\r\n display: flex;\r\n flex-wrap: wrap;\r\n gap: 10px;\r\n}\r\n\r\n.addButton {\r\n /* Overrides the shared button base above: these two are not pills sitting in\r\n a footer but the last slot of the provider list, so they split the row\r\n evenly and repeat the row cards' corner. Dashed, like every other \"nothing\r\n here yet\" affordance on this page, to read as a place rather than a\r\n command. */\r\n flex: 1 1 0;\r\n min-width: 180px;\r\n gap: 6px;\r\n height: 44px;\r\n border: 1px dashed var(--dsw-alias-border-l3);\r\n border-radius: 16px;\r\n}\r\n\r\n.addCard,\r\n.setupCard {\r\n border-radius: 12px;\r\n background: var(--dsw-alias-bg-module-platform);\r\n padding: 14px 16px;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 14px;\r\n list-style: none;\r\n}\r\n\r\n/* Nested in a card that already carries the module chrome. */\r\n.addCard .editor,\r\n.setupCard .editor {\r\n background: none;\r\n padding: 0;\r\n}\r\n\r\n.customized {\r\n border-top: 0.5px solid var(--dsw-alias-border-l2);\r\n padding-top: 10px;\r\n}\r\n\r\n/* Native disclosure marker replaced by a rotating chevron: the built-in\r\n triangle differs per engine and cannot take the label color. */\r\n.customizedSummary {\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n width: fit-content;\r\n padding: 2px 4px;\r\n margin-left: -4px;\r\n border-radius: 6px;\r\n cursor: pointer;\r\n font-size: 12px;\r\n line-height: 18px;\r\n font-weight: 500;\r\n color: var(--dsw-alias-label-secondary);\r\n list-style: none;\r\n}\r\n\r\n.customizedSummary::-webkit-details-marker {\r\n display: none;\r\n}\r\n\r\n.customizedSummary::before {\r\n content: '';\r\n width: 5px;\r\n height: 5px;\r\n border-right: 1.5px solid currentcolor;\r\n border-bottom: 1.5px solid currentcolor;\r\n transform: rotate(-45deg) translate(-1px, -1px);\r\n transition: transform 120ms ease;\r\n}\r\n\r\n.customized[open] > .customizedSummary::before {\r\n transform: rotate(45deg) translate(-1px, -1px);\r\n}\r\n\r\n.customizedSummary:hover {\r\n color: var(--dsw-alias-label-primary);\r\n}\r\n\r\n.customizedBody {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n padding-top: 12px;\r\n}\r\n\r\n/* Model catalog: a table, not a stack of cards. The column captions are\r\n written once above the rows, so a row is one line of fields plus its\r\n delete control; each field still carries the indexed `aria-label` that\r\n names it, and the caption strip is hidden from assistive tech to keep\r\n that name from being announced twice. */\r\n.modelCatalog {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 10px;\r\n padding-top: 12px;\r\n border-top: 0.5px solid var(--dsw-alias-border-l2);\r\n}\r\n\r\n.modelCatalogHeading {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 2px;\r\n}\r\n\r\n.modelCatalogTitle {\r\n font-size: 12px;\r\n line-height: 18px;\r\n font-weight: 500;\r\n color: var(--dsw-alias-label-secondary);\r\n}\r\n\r\n.modelCatalogMeta,\r\n.modelEmpty {\r\n margin: 0;\r\n color: var(--dsw-alias-label-tertiary);\r\n font-size: 12px;\r\n line-height: 18px;\r\n}\r\n\r\n/* Model list, shared with the pi-ai provider form: one bordered\r\n entry per model, id and display name on the row, capacities behind the\r\n row's own disclosure. The rules use this stylesheet's token vocabulary —\r\n `--dsw-alias-border-subtle`, `--dsw-alias-text-tertiary`, and\r\n `--dsw-alias-text-primary` are undefined here and would resolve to their\r\n light-mode literals. */\r\n.modelList {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n}\r\n\r\n.modelListHead {\r\n display: flex;\r\n align-items: flex-start;\r\n justify-content: space-between;\r\n gap: 12px;\r\n}\r\n\r\n.modelEntry {\r\n border: 0.5px solid var(--dsw-alias-border-l4);\r\n border-radius: 10px;\r\n padding: 6px;\r\n}\r\n\r\n.modelRow {\r\n display: grid;\r\n grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) auto auto;\r\n align-items: center;\r\n gap: 6px;\r\n}\r\n\r\n/* Square, label-free affordances: the row's own inputs carry the meaning, so\r\n the actions stay glyphs and announce themselves through aria-label. */\r\n.iconButton {\r\n box-sizing: border-box;\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 28px;\r\n height: 28px;\r\n border: none;\r\n border-radius: 6px;\r\n background: transparent;\r\n color: var(--dsw-alias-label-tertiary);\r\n cursor: pointer;\r\n}\r\n\r\n.iconButton:hover:not(:disabled) {\r\n background: var(--dsw-alias-interactive-bg-hover);\r\n color: var(--dsw-alias-label-primary);\r\n}\r\n\r\n.iconButton:disabled {\r\n cursor: default;\r\n opacity: 0.4;\r\n}\r\n\r\n/* The delete glyph keeps the danger tint the rest of the section uses. */\r\n.iconButtonDanger:hover:not(:disabled) {\r\n background: var(--dsw-alias-interactive-bg-hover-danger);\r\n color: var(--dsw-alias-state-error-primary);\r\n}\r\n\r\n.modelAdvanced {\r\n display: grid;\r\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\r\n gap: 8px;\r\n padding: 8px 4px 2px;\r\n}\r\n\r\n/* EXT-only: sibling of `.modelAdvanced` (NOT a child of it). Must break out\r\n of any grid/flex on an ancestor and span the full entry width, otherwise a\r\n deep grid context would squeeze this block into a narrow column. */\r\n.modelExtensionFields {\r\n display: block;\r\n width: 100%;\r\n box-sizing: border-box;\r\n}\r\n\r\n.modelField {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 4px;\r\n}\r\n\r\n.modelFieldLabel {\r\n color: var(--dsw-alias-label-tertiary);\r\n font-size: 12px;\r\n line-height: 18px;\r\n}\r\n\r\n.modelEmpty {\r\n padding: 12px;\r\n border: 1px dashed var(--dsw-alias-border-l3);\r\n border-radius: 8px;\r\n text-align: center;\r\n}\r\n\r\n.addModelButton {\r\n box-sizing: border-box;\r\n align-self: flex-start;\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 4px;\r\n height: 28px;\r\n padding: 0 10px;\r\n border: 0.5px solid var(--dsw-alias-border-l3);\r\n border-radius: 14px;\r\n background: transparent;\r\n color: var(--dsw-alias-label-primary);\r\n font: inherit;\r\n font-size: 12px;\r\n line-height: 18px;\r\n cursor: pointer;\r\n}\r\n\r\n.addModelButton:hover:not(:disabled) {\r\n background: var(--dsw-alias-interactive-bg-hover);\r\n}\r\n\r\n.input {\r\n box-sizing: border-box;\r\n width: 100%;\r\n height: 32px;\r\n padding: 0 10px;\r\n border: 0.5px solid var(--dsw-alias-border-l4);\r\n border-radius: 8px;\r\n font: inherit;\r\n font-size: 14px;\r\n line-height: 22px;\r\n background: var(--dsw-alias-bg-layer-1);\r\n color: var(--dsw-alias-label-primary);\r\n}\r\n\r\n/* Enum pickers hold a handful of short options; a field-width dropdown reads\r\n as a text field the user is expected to fill. */\r\nselect.input {\r\n max-width: 240px;\r\n cursor: pointer;\r\n}\r\n\r\n.input:focus {\r\n outline: none;\r\n border-color: var(--dsw-alias-brand-primary);\r\n}\r\n\r\n.input::placeholder {\r\n color: var(--dsw-alias-label-dimmed);\r\n}\r\n\r\n.input:disabled {\r\n opacity: 0.6;\r\n cursor: default;\r\n}\r\n\r\n/* Select variant of .input: replaces the OS arrow (which sits flush against\r\n the right edge) with the shared 12px chevron inset like the composer's\r\n .select chips; the right pad reserves its cell. */\r\n.selectInput {\r\n appearance: none;\r\n padding-right: 32px;\r\n /* Data-URI SVGs cannot resolve CSS variables; #81858C is the caption gray\r\n shared by both themes. */\r\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%2381858C' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\");\r\n background-repeat: no-repeat;\r\n background-position: right 12px center;\r\n background-size: 12px 12px;\r\n}\r\n\r\n.error {\r\n margin: 0;\r\n font-size: 12px;\r\n line-height: 18px;\r\n color: var(--dsw-alias-state-error-primary);\r\n}\r\n\r\n.deleteDialog {\r\n width: min(480px, 100%);\r\n}\r\n\r\n.deleteConfirm:not(:disabled) {\r\n border-color: var(--dsw-alias-state-error-primary);\r\n color: var(--dsw-alias-state-error-primary);\r\n}\r\n\r\n.deleteConfirm:hover:not(:disabled) {\r\n background: var(--dsw-alias-interactive-bg-hover-danger);\r\n}\r\n\r\n/* Icon-button label seat: named for assistive tech and for the tests that\r\n query these controls by their text. */\r\n.hiddenLabel {\r\n position: absolute;\r\n width: 1px;\r\n height: 1px;\r\n overflow: hidden;\r\n clip: rect(0 0 0 0);\r\n white-space: nowrap;\r\n}\r\n\r\n@media (prefers-reduced-motion: reduce) {\r\n .customizedSummary::before,\r\n .switchThumb {\r\n transition: none;\r\n }\r\n}\r\n\r\n.fetchDialog {\r\n max-width: 520px;\r\n\r\n /* The candidate list scrolls inside this dialog, an elevated surface, so the\r\n scrollbar indirection is rebound here rather than on the scrolling child:\r\n the elevation choice belongs with the surface and inherits down (see\r\n ui-theme styles/scrollbar.css for the contract). */\r\n --dsh-scrollbar-thumb: var(--dsw-alias-scrollbar-bg-l2);\r\n --dsh-scrollbar-thumb-hover: var(--dsw-alias-scrollbar-hover-l2);\r\n}\r\n\r\n.candidateToolbar {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n margin-bottom: 6px;\r\n}\r\n\r\n.candidateSearch {\r\n min-width: 0;\r\n flex: 1 1 240px;\r\n}\r\n\r\n.candidateList {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 2px;\r\n max-height: 320px;\r\n margin: 0;\r\n overflow-y: auto;\r\n padding: 0;\r\n list-style: none;\r\n}\r\n\r\n.candidate {\r\n border-radius: 6px;\r\n}\r\n\r\n.candidateLabel {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n padding: 6px 8px;\r\n cursor: pointer;\r\n}\r\n\r\n.candidateId {\r\n flex: 1 1 auto;\r\n font-family: var(--ds-font-family-code);\r\n font-size: 13px;\r\n overflow-wrap: anywhere;\r\n}\r\n\r\n.candidateEmpty {\r\n margin: 24px 0;\r\n color: var(--dsw-alias-label-secondary);\r\n font-size: 13px;\r\n line-height: 20px;\r\n text-align: center;\r\n}\r\n","/**\n * Shared extension metadata: enums pinned to the adapter anchor version, and\n * the extra locale keys the extension adds on top of the official Models page\n * dictionaries. The anchor constant itself is injected at build time.\n */\n\n/** Adapter anchor (build-time define from package.json dsh.adapter). */\ndeclare const __DSH_ADAPTER_VERSION__: string\nexport const ADAPTER_VERSION: string =\n typeof __DSH_ADAPTER_VERSION__ === 'string' ? __DSH_ADAPTER_VERSION__ : '0.0.0-unknown'\n\n/** Thinking levels offered by llm-pi-ai (THINKING_LEVEL_GATE @ 0.1.2-alpha.4). Only `off` may carry an empty wire value. */\nexport const THINKING_LEVELS = ['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'] as const\nexport type ThinkingLevel = (typeof THINKING_LEVELS)[number]\n\n/** Input modalities accepted by llm-pi-ai (MODALITY_GATE @ 0.1.2-alpha.4). */\nexport const MODALITIES = ['text', 'image'] as const\nexport type Modality = (typeof MODALITIES)[number]\n\n/** Reasoning wire formats understood by llm-pi-ai (SUPPORTED_THINKING_FORMATS @ 0.1.2-alpha.4). */\nexport const THINKING_FORMATS = [\n 'openai',\n 'deepseek',\n 'openrouter',\n 'together',\n 'baseten',\n 'zai',\n 'qwen',\n 'chat-template',\n 'qwen-chat-template',\n 'string-thinking',\n 'ant-ling',\n] as const\nexport type ThinkingFormat = (typeof THINKING_FORMATS)[number]\n\n/** Extra copy for the extension, keyed like the official dictionaries (en is authoritative). */\nexport const en = {\n // --- official Models-page keys the forked components still render -------\n nav: 'Models+',\n title: 'Models+',\n intro: 'Enter your API keys to use models from the following providers.',\n edit: 'Edit',\n editProvider: 'Edit {provider}',\n remove: 'Delete',\n removeProvider: 'Delete {provider}',\n deleteTitle: 'Delete {provider}?',\n deleteDescription: 'Deleting {provider} removes its configuration. Any credential it uses is managed elsewhere and will be kept.',\n deleteDescriptionWithCredential: 'Deleting {provider} removes its configuration and stored API key.',\n deleteConfirm: 'Delete {provider}',\n deleting: 'Deleting {provider}…',\n add: 'Add provider',\n provider: 'Provider',\n close: 'Close',\n cancel: 'Cancel',\n apply: 'Apply',\n applying: 'Applying…',\n savedProvider: 'Saved {provider}.',\n credentialConfigured: 'API key configured',\n credentialMissing: 'API key missing',\n readOnly: 'The settings document is read-only in this deployment.',\n loadFailed: 'Loading the provider directory failed',\n conflict: 'Someone else changed these settings while this card was open. Close it and reopen to edit the current values.',\n retry: 'Retry',\n keyInput: 'API key',\n keyPlaceholder: 'Enter your API key',\n keyPlaceholderNative: 'Enter an API key, or leave blank to use environment authentication',\n keyStored: 'Configured — enter a new value to replace',\n keyEnvLocked: 'Provided by the launch environment (read-only)',\n customized: 'Customized settings',\n baseUrl: 'Base URL',\n baseUrlDefault: 'Provider default',\n models: 'Models',\n modelsInherited: 'Using the adapter defaults',\n modelsCustomized: 'Customized model catalog',\n resetModels: 'Restore defaults',\n model: 'Model',\n modelId: 'Model ID',\n modelName: 'Display name',\n modelNamePlaceholder: 'Uses the model ID when empty',\n contextWindow: 'Context window',\n contextWindowPlaceholder: 'Uses the provider default',\n maxTokens: 'Max output tokens',\n maxTokensPlaceholder: 'Uses the provider default',\n modelAdvanced: 'Capacities',\n addModel: 'Add model',\n removeModel: 'Delete model',\n modelsEmpty: 'No models will be shown in the selector. Unlisted IDs can still be sent directly.',\n keyBlank: 'Enter the API key, or leave the field empty to keep the stored one.',\n keyBlankNew: 'Enter the API key, or leave the field empty if this provider authenticates another way.',\n keyIllegalCharacters: 'This API key is not in a valid format. Please check it.',\n modelIdRequired: 'Model ID is required.',\n modelIdDuplicate: 'Model ID must be unique.',\n modelNameInvalid: 'Display name cannot be empty.',\n modelContextInvalid: 'Context window must be a positive count, like 131072, 256K, or 1M.',\n modelMaxTokensInvalid: 'Max output tokens must be a positive count, like 8192, 64K, or 1M.',\n advancedHint: 'Other fields live in settings.yaml; edit that section directly.',\n modelCapacityInvalid: 'A capacity must be a number, optionally suffixed K or M.',\n modelDuplicate: 'Each model ID may appear once.',\n modelContextWindow: 'Context window',\n modelMaxTokens: 'Max output tokens',\n fetchModels: 'Fetch available models',\n fetching: 'Asking the provider…',\n fetchNeedsBaseUrl: 'Enter the base URL first, then fetch.',\n fetchEmpty: 'The provider listed no models. Add them by hand.',\n fetchTitle: 'Choose models to add',\n fetchDescription: 'These are the models this provider has available. Choose the ones to add.',\n fetchSelectAll: 'Select all',\n fetchDeselectAll: 'Deselect all',\n fetchAdopt: 'Add selected',\n customAdd: 'Add a custom provider',\n customTitle: 'Custom provider',\n customTag: 'Custom',\n customRoute: 'Provider ID',\n customRouteHint: 'Lowercase identifier, starting with a letter, that uniquely names this provider in requests and as its credential name.',\n customRouteInvalid: 'Start with a lowercase letter; then lowercase letters, digits, and dashes.',\n customRouteTaken: 'A provider already uses this ID.',\n customDisplayName: 'Display name',\n customApi: 'API protocol',\n customApiUnset: 'Not selected',\n customNeedsBaseUrl: 'A custom provider needs a base URL.',\n customNeedsModels: 'A custom provider needs at least one model.',\n customBaseUrlPlaceholder: 'https://gateway.example/v1',\n settingsPathUnresolvable: 'unresolvable settings path',\n create: 'Create provider',\n creating: 'Creating…',\n onboardingTitle: 'Add an API key to get started',\n onboardingDescription: 'Configure the official DeepSeek provider to start building.',\n onboardingLater: 'Configure later',\n onboardingSave: 'Save and continue',\n onboardingSaving: 'Saving…',\n keyRequired: 'Enter an API key to continue.',\n\n // --- extension-only keys ------------------------------------------------\n adapterVersion: 'Current adapter: {version}',\n extDeclare: 'Declared',\n extSection: 'Model extensions',\n extSectionHint: 'Extra per-model fields that live in settings.yaml.',\n supportsReasoningEffort: 'Endpoint accepts reasoning effort',\n supportsDeveloperRole: 'System prompt may use the developer role',\n supportsDeveloperRoleHint: 'Reasoning-model system prompts go out as \"developer\"; uncheck to keep \"system\" for gateways that reject it.',\n reasoningEfforts: 'Reasoning efforts',\n reasoningEffortLevel: 'Level',\n reasoningEffortWire: 'Wire value',\n reasoningEffortOffHint: '\"off\" takes no wire value.',\n reasoningEffortEmptyWire: 'A checked level other than \"off\" needs a wire value.',\n reasoningEffortsNeedNonOff: 'Declare at least one level beyond \"off\".',\n inputModalities: 'Input modalities',\n inputNeedOne: 'Keep at least one modality checked.',\n thinkingFormat: 'Thinking format',\n} as const\n\nexport type ExtensionKey = keyof typeof en\n\n/** Chinese strings — same key set as {@link en}. */\nexport const zh: { [K in ExtensionKey]: string } = {\n // --- official Models-page keys (upstream zh values) ----------------------\n nav: '模型+',\n title: '模型+',\n intro: '填入各提供方的 API 密钥即可使用其模型。',\n edit: '编辑',\n editProvider: '编辑 {provider}',\n remove: '删除',\n removeProvider: '删除 {provider}',\n deleteTitle: '删除 {provider}?',\n deleteDescription: '删除 {provider} 会移除其配置;其使用的凭证(如有)由其他位置管理,将会保留。',\n deleteDescriptionWithCredential: '删除 {provider} 会移除其配置和存储的 API 密钥。',\n deleteConfirm: '删除 {provider}',\n deleting: '正在删除 {provider}…',\n add: '添加提供方',\n provider: '提供方',\n close: '关闭',\n cancel: '取消',\n apply: '保存',\n applying: '保存中…',\n savedProvider: '已保存 {provider}。',\n credentialConfigured: 'API 密钥已配置',\n credentialMissing: 'API 密钥缺失',\n readOnly: '当前部署的设置文档为只读。',\n loadFailed: '加载提供方目录失败',\n conflict: '这张卡片打开期间,这些设置已被其他地方改动。请关闭后重新打开,在当前值上编辑。',\n retry: '重试',\n keyInput: 'API 密钥',\n keyPlaceholder: '输入 API 密钥',\n keyPlaceholderNative: '输入 API 密钥,或留空使用环境认证',\n keyStored: '已配置——输入新值可替换',\n keyEnvLocked: '由启动环境提供(只读)',\n customized: '自定义设置',\n baseUrl: 'API 地址',\n baseUrlDefault: '提供方默认',\n models: '模型目录',\n modelsInherited: '正在使用适配器默认模型',\n modelsCustomized: '已自定义模型目录',\n resetModels: '恢复默认模型',\n model: '模型',\n modelId: '模型 ID',\n modelName: '显示名称',\n modelNamePlaceholder: '留空时使用模型 ID',\n contextWindow: '上下文窗口',\n contextWindowPlaceholder: '使用提供方默认值',\n maxTokens: '最大输出 token 数',\n maxTokensPlaceholder: '使用提供方默认值',\n modelAdvanced: '容量',\n addModel: '添加模型',\n removeModel: '删除模型',\n modelsEmpty: '模型选择器中将不显示任何模型;目录外 ID 仍可直接发送。',\n keyBlank: '请输入 API 密钥;留空则保持已存储的密钥。',\n keyBlankNew: '请输入 API 密钥;若该提供方以其他方式鉴权,可以留空。',\n keyIllegalCharacters: '此 API 密钥格式无效,请检查。',\n modelIdRequired: '模型 ID 必填。',\n modelIdDuplicate: '模型 ID 不能重复。',\n modelNameInvalid: '显示名称不能为空。',\n modelContextInvalid: '上下文窗口须为正数,如 131072、256K、1M。',\n modelMaxTokensInvalid: '最大输出 token 数须为正数,如 8192、64K、1M。',\n advancedHint: '其余字段存于 settings.yaml;请直接编辑该节。',\n modelCapacityInvalid: '容量须为数字,可带 K 或 M 后缀。',\n modelDuplicate: '每个模型 ID 只能出现一次。',\n modelContextWindow: '上下文窗口',\n modelMaxTokens: '最大输出 token 数',\n fetchModels: '获取可用模型',\n fetching: '正在询问提供方…',\n fetchNeedsBaseUrl: '请先填写 API 地址再获取。',\n fetchEmpty: '该提供方未列出任何模型,请手动添加。',\n fetchTitle: '选择要添加的模型',\n fetchDescription: '这些是该提供方可用的模型,选择要添加的项。',\n fetchSelectAll: '全选',\n fetchDeselectAll: '取消全选',\n fetchAdopt: '添加所选',\n customAdd: '添加自定义提供方',\n customTitle: '自定义提供方',\n customTag: '自定义',\n customRoute: '提供方 ID',\n customRouteHint: '小写字母开头的唯一标识符,用于请求与凭证命名。',\n customRouteInvalid: '以小写字母开头;其后为小写字母、数字和短横线。',\n customRouteTaken: '已有提供方使用此 ID。',\n customDisplayName: '显示名称',\n customApi: 'API 协议',\n customApiUnset: '未选择',\n customNeedsBaseUrl: '自定义提供方需要 API 地址。',\n customNeedsModels: '自定义提供方至少需要一个模型。',\n customBaseUrlPlaceholder: 'https://gateway.example/v1',\n settingsPathUnresolvable: '无法解析设置路径',\n create: '创建提供方',\n creating: '创建中…',\n onboardingTitle: '先添加一个 API 密钥即可开始',\n onboardingDescription: '配置官方 DeepSeek 提供方以开始构建。',\n onboardingLater: '稍后配置',\n onboardingSave: '保存并继续',\n onboardingSaving: '保存中…',\n keyRequired: '请输入 API 密钥以继续。',\n\n // --- extension-only keys ------------------------------------------------\n adapterVersion: '当前适配器:{version}',\n extDeclare: '声明',\n extSection: '模型扩展',\n extSectionHint: 'settings.yaml 中按模型生效的扩展字段。',\n supportsReasoningEffort: '端点接受推理挡位参数(reasoning_effort)',\n supportsDeveloperRole: '允许以 developer 角色发送系统提示',\n supportsDeveloperRoleHint: '推理模型的系统提示将以 developer 角色发出;网关拒绝该角色时取消勾选,改用 system。',\n reasoningEfforts: '推理挡位',\n reasoningEffortLevel: '挡位',\n reasoningEffortWire: '线上取值',\n reasoningEffortOffHint: '“off”不需要线上取值。',\n reasoningEffortEmptyWire: '除 off 外勾选的挡位必须填写线上取值。',\n reasoningEffortsNeedNonOff: '至少声明一个 off 以外的挡位。',\n inputModalities: '输入模态',\n inputNeedOne: '至少保留一个模态。',\n thinkingFormat: '思考格式',\n}\n","/**\r\n * Per-model extension fields for the Models+ page (dsh-model-extension only).\r\n *\r\n * Edits one model draft object in place — the same record the official\r\n * ModelListEditor card holds — so persistence rides the card's existing\r\n * `applyOnce()` path-ops save with no extra wire calls. Fields written:\r\n *\r\n * reasoningEfforts { [level]: wire | null } declared thinking levels\r\n * input Modality[] accepted input modalities\r\n * compat.supportsReasoningEffort boolean endpoint accepts reasoning_effort\r\n * compat.thinkingFormat wire format how reasoning is serialised\r\n * compat.supportsDeveloperRole boolean system prompt role for reasoning models\r\n * (unset reads as checked = catalog/detection default)\r\n *\r\n * NOTE: there is deliberately NO \"default effort\" (model-level reasoningEffort)\r\n * control here. DSH's `modelFields` schema has no such key — the runtime derives\r\n * `model.reasoning.defaultEffort` from `reasoningEfforts` + the route-level\r\n * `reasoning` default, so a hand-written `reasoningEffort` is silently stripped\r\n * (or, if written without an `id`, fails `modelProfile.id:required` and rejects\r\n * the whole `llm-pi-ai` block). Default effort is observable, never persisted,\r\n * from this extension. See dsh-compatibility-check/llm-pi-ai-config-nodes_*.md.\r\n *\r\n * Linkage: `supportsReasoningEffort` gates the visibility (and presence in the\r\n * draft) of reasoningEfforts / thinkingFormat. Clearing it removes those nodes\r\n * from the draft IN ONE onChange commit, so partial updates never overwrite\r\n * each other.\r\n */\r\nimport type { ReactNode } from 'react'\r\nimport styles from './ModelsSection.ext.module.css'\r\nimport {\r\n MODALITIES, THINKING_FORMATS, THINKING_LEVELS, en as extensionEn, zh as extensionZh,\r\n} from './extension-meta.ts'\r\nimport type { ThinkingFormat, ThinkingLevel } from './extension-meta.ts'\r\n\r\n/** One models[] entry as the card holds it (structurally open). */\r\ntype ModelDraft = Record<string, unknown>\r\n\r\n/** Row-level field writer: merge/clear keys on this row's draft object. */\r\ntype PatchModel = (next: Record<string, unknown>) => void\r\n\r\n/** Chinese display names for the thinking levels (wire value stays in parentheses). */\r\nconst LEVEL_LABELS: Record<ThinkingLevel, { zh: string; en: string }> = {\r\n off: { zh: '关闭', en: 'Off' },\r\n minimal: { zh: '极小', en: 'Minimal' },\r\n low: { zh: '低', en: 'Low' },\r\n medium: { zh: '中', en: 'Medium' },\r\n high: { zh: '高', en: 'High' },\r\n xhigh: { zh: '超高', en: 'Extra High' },\r\n max: { zh: '最大', en: 'Max' },\r\n}\r\n\r\n/** Chinese display names for the input modalities. */\r\nconst MODALITY_LABELS: Record<string, { zh: string; en: string }> = {\r\n text: { zh: '文本', en: 'Text' },\r\n image: { zh: '图像', en: 'Image' },\r\n}\r\n\r\n/** Shared checkbox inline style (matches the host's checkbox look). */\r\nconst checkboxStyle: React.CSSProperties = {\r\n width: '15px',\r\n height: '15px',\r\n margin: 0,\r\n accentColor: 'var(--dsw-alias-brand-primary)',\r\n flex: 'none',\r\n}\r\n\r\nexport interface ModelExtensionFieldsProps {\r\n /** The row's current draft object (read). */\r\n model: ModelDraft\r\n /** Merge these keys into the row; `undefined` values clear them. */\r\n onChange: PatchModel\r\n /** Disable every control (read-only deployment or pending write). */\r\n disabled?: boolean\r\n}\r\n\r\n/** The row's compat sub-object as a plain record (absent → empty). */\r\nfunction compatOf(model: ModelDraft): Record<string, unknown> {\r\n const value = model['compat']\r\n return typeof value === 'object' && value !== null && !Array.isArray(value)\r\n ? value as Record<string, unknown>\r\n : {}\r\n}\r\n\r\n/** The row's reasoningEfforts dict (absent/false/invalid → undefined = not declared). */\r\nfunction effortsOf(model: ModelDraft): Record<string, string | null> | undefined {\r\n const value = model['reasoningEfforts']\r\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return undefined\r\n return value as Record<string, string | null>\r\n}\r\n\r\n/**\r\n * Render the extension block for one model row.\r\n * @param props - the row draft, its writer, and the disabled flag.\r\n * @returns the extension fields section.\r\n */\r\nexport function ModelExtensionFields(props: ModelExtensionFieldsProps): ReactNode {\r\n const { model, onChange, disabled = false } = props\r\n // Extension copy is bilingual static (not the slot `t` seat): this block\r\n // renders inside the official card whose translate speaks only upstream\r\n // keys. Language follows the host UI via document lang, read per render.\r\n const isZh = typeof document !== 'undefined' && document.documentElement.lang.startsWith('zh')\r\n const t = (key: keyof typeof extensionEn): string =>\r\n (isZh ? extensionZh : extensionEn)[key]\r\n const levelLabel = (level: ThinkingLevel): string =>\r\n isZh ? `${LEVEL_LABELS[level].zh} (${level})` : `${LEVEL_LABELS[level].en} (${level})`\r\n const modalityLabel = (modality: string): string =>\r\n isZh ? MODALITY_LABELS[modality]?.zh ?? modality : MODALITY_LABELS[modality]?.en ?? modality\r\n\r\n const compat = compatOf(model)\r\n const supportsReasoningEffort = compat['supportsReasoningEffort'] === true\r\n // Unset reads as the default (checked): the installed catalog / pi-ai's own\r\n // URL detection stays in charge unless the deployment writes an explicit\r\n // boolean. Only an explicit `false` renders the box unchecked.\r\n const supportsDeveloperRole = compat['supportsDeveloperRole'] !== false\r\n\r\n /** Write one key into `compat`, merging into the row's existing compat and\r\n * clearing the whole `compat` node when it would become empty. Used for\r\n * `supportsReasoningEffort`, `thinkingFormat` and `supportsDeveloperRole`\r\n * ONLY — those are the only model extension fields that live under `compat`. */\r\n const setCompatKey = (key: string, value: unknown): void => {\r\n const next = { ...compat }\r\n if (value === undefined) delete next[key]\r\n else next[key] = value\r\n // An emptied compat object leaves no trace, like any cleared optional field.\r\n onChange({ compat: Object.keys(next).length === 0 ? undefined : next })\r\n }\r\n\r\n const setEfforts = (efforts: Record<string, string | null> | undefined): void => {\r\n onChange({ reasoningEfforts: efforts })\r\n }\r\n\r\n const setInput = (modalities: string[]): void => {\r\n onChange({ input: modalities.length === 0 ? undefined : modalities })\r\n }\r\n\r\n const toggleLevel = (level: ThinkingLevel, checked: boolean): void => {\r\n const efforts = { ...(effortsOf(model) ?? {}) }\r\n if (checked) {\r\n // off carries no wire value; every other level defaults to its own name.\r\n efforts[level] = level === 'off' ? null : level\r\n } else {\r\n delete efforts[level]\r\n }\r\n const next: Record<string, unknown> = {\r\n reasoningEfforts: Object.keys(efforts).length === 0 ? undefined : efforts,\r\n }\r\n onChange(next)\r\n }\r\n\r\n const setWireValue = (level: ThinkingLevel, text: string): void => {\r\n const efforts = { ...(effortsOf(model) ?? {}) }\r\n if (!(level in efforts)) return\r\n efforts[level] = text.trim().length === 0 ? null : text.trim()\r\n setEfforts(efforts)\r\n }\r\n\r\n const toggleModality = (modality: string, checked: boolean): void => {\r\n const current = Array.isArray(model['input'])\r\n ? (model['input'] as string[])\r\n : ['text']\r\n setInput(checked\r\n ? [...new Set([...current, modality])]\r\n : current.filter(entry => entry !== modality))\r\n }\r\n\r\n const efforts = effortsOf(model)\r\n const declaredLevels = efforts === undefined ? [] : THINKING_LEVELS.filter(level => level in efforts)\r\n const inputList = Array.isArray(model['input']) ? model['input'] as string[] : []\r\n const thinkingFormat = typeof compat['thinkingFormat'] === 'string'\r\n ? compat['thinkingFormat'] as ThinkingFormat\r\n : undefined\r\n // Validation mirrors the host's own checks: only `off` may carry an empty\r\n // wire value, and a declaration needs at least one non-off level.\r\n const hasEmptyWire = declaredLevels.some(level =>\r\n level !== 'off' && String(efforts?.[level] ?? '').trim().length === 0)\r\n const onlyOffDeclared = efforts !== undefined\r\n && declaredLevels.length > 0\r\n && !declaredLevels.some(level => level !== 'off')\r\n\r\n /** One declared level's wire-value row inside the levels table. */\r\n const wireRow = (level: ThinkingLevel): ReactNode => {\r\n const isOff = level === 'off'\r\n return isOff\r\n ? <span style={{ fontSize: 12, color: 'var(--color-text-tertiary, #999)' }}>—</span>\r\n : (\r\n <input\r\n className={styles['input']}\r\n type=\"text\"\r\n value={String(efforts?.[level] ?? '')}\r\n aria-label={`${t('reasoningEffortWire')} ${level}`}\r\n placeholder={level}\r\n disabled={disabled}\r\n onChange={event => { setWireValue(level, event.target.value) }}\r\n />\r\n )\r\n }\r\n\r\n return (\r\n <fieldset style={{ border: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: 14 }}>\r\n {/* --- compat: supportsDeveloperRole ---------------------------------- */}\r\n <div style={{ borderTop: '0.5px solid var(--color-border-tertiary, rgba(0,0,0,0.15))', paddingTop: 12 }}>\r\n <label style={{ display: 'flex', alignItems: 'flex-start', gap: 8, cursor: 'pointer' }}>\r\n <input\r\n type=\"checkbox\"\r\n style={checkboxStyle}\r\n checked={supportsDeveloperRole}\r\n disabled={disabled}\r\n onChange={(event) => {\r\n // Checked is the natural default, so a check REMOVES the key:\r\n // the wire then follows the installed catalog / pi-ai detection\r\n // instead of pinning `true` over a catalog's known `false`.\r\n setCompatKey('supportsDeveloperRole', event.target.checked ? undefined : false)\r\n }}\r\n />\r\n <span style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\r\n <span className={styles['modelFieldLabel']}>{t('supportsDeveloperRole')}</span>\r\n <span style={{ fontSize: 12, color: 'var(--color-text-tertiary, #999)' }}>{t('supportsDeveloperRoleHint')}</span>\r\n </span>\r\n </label>\r\n </div>\r\n\r\n {/* --- compat: supportsReasoningEffort ------------------------------ */}\r\n <div style={{ borderTop: '0.5px solid var(--color-border-tertiary, rgba(0,0,0,0.15))', paddingTop: 12 }}>\r\n <label style={{ display: 'inline-flex', alignItems: 'center', gap: 8, cursor: 'pointer' }}>\r\n <input\r\n type=\"checkbox\"\r\n style={checkboxStyle}\r\n checked={supportsReasoningEffort}\r\n disabled={disabled}\r\n onChange={(event) => {\r\n if (event.target.checked) {\r\n // Turning the gate on declares the compat flag alone; the\r\n // levels table below appears empty for the user to fill in.\r\n setCompatKey('supportsReasoningEffort', true)\r\n } else {\r\n // Turning it off clears the flag AND every gated node in ONE\r\n // commit — two separate onChange calls would each start from\r\n // the same stale draft and overwrite each other. `reasoningEfforts`\r\n // and `thinkingFormat` are dropped together; there is no\r\n // model-level default-effort key to clear (DSH derives it).\r\n const nextCompat = { ...compat }\r\n delete nextCompat['supportsReasoningEffort']\r\n delete nextCompat['thinkingFormat']\r\n onChange({\r\n compat: Object.keys(nextCompat).length === 0 ? undefined : nextCompat,\r\n reasoningEfforts: undefined,\r\n })\r\n }\r\n }}\r\n />\r\n <span className={styles['modelFieldLabel']}>{t('supportsReasoningEffort')}</span>\r\n </label>\r\n </div>\r\n\r\n {/* --- gated by supportsReasoningEffort ------------------------------- */}\r\n {!supportsReasoningEffort ? null : (\r\n <>\r\n <div>\r\n <div className={styles['modelFieldLabel']} style={{ marginBottom: 6 }}>{t('reasoningEfforts')}</div>\r\n <div style={{\r\n border: '0.5px solid var(--color-border-tertiary, rgba(0,0,0,0.15))',\r\n borderRadius: 'var(--border-radius-md, 8px)',\r\n overflow: 'hidden',\r\n }}>\r\n {/* table header */}\r\n <div style={{\r\n display: 'grid',\r\n gridTemplateColumns: '56px 1fr 1fr',\r\n fontSize: 12,\r\n color: 'var(--color-text-secondary, #666)',\r\n background: 'var(--color-background-secondary, #f5f5f5)',\r\n }}>\r\n <div style={{ padding: '5px 10px' }}>{t('extDeclare')}</div>\r\n <div style={{ padding: '5px 10px', borderLeft: '0.5px solid var(--color-border-tertiary, rgba(0,0,0,0.15))' }}>{t('reasoningEffortLevel')}</div>\r\n <div style={{ padding: '5px 10px', borderLeft: '0.5px solid var(--color-border-tertiary, rgba(0,0,0,0.15))' }}>{t('reasoningEffortWire')}</div>\r\n </div>\r\n {/* one row per level, all levels always visible */}\r\n {THINKING_LEVELS.map((level, at) => (\r\n <div\r\n key={level}\r\n style={{\r\n display: 'grid',\r\n gridTemplateColumns: '56px 1fr 1fr',\r\n alignItems: 'center',\r\n borderTop: at === 0 ? 'none' : '0.5px solid var(--color-border-tertiary, rgba(0,0,0,0.15))',\r\n }}\r\n >\r\n <div style={{ padding: '5px 10px', display: 'flex', justifyContent: 'center' }}>\r\n <input\r\n type=\"checkbox\"\r\n style={checkboxStyle}\r\n checked={level in (efforts ?? {})}\r\n disabled={disabled}\r\n onChange={(event) => { toggleLevel(level, event.target.checked) }}\r\n />\r\n </div>\r\n <div style={{\r\n padding: '5px 10px',\r\n fontSize: 13,\r\n borderLeft: '0.5px solid var(--color-border-tertiary, rgba(0,0,0,0.15))',\r\n opacity: level in (efforts ?? {}) ? 1 : 0.5,\r\n }}>\r\n {levelLabel(level)}\r\n </div>\r\n <div style={{\r\n padding: '5px 10px',\r\n borderLeft: '0.5px solid var(--color-border-tertiary, rgba(0,0,0,0.15))',\r\n opacity: level in (efforts ?? {}) ? 1 : 0.4,\r\n }}>\r\n {level in (efforts ?? {}) ? wireRow(level) : <span style={{ fontSize: 12, color: 'var(--color-text-tertiary, #999)' }}>—</span>}\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n {(hasEmptyWire || onlyOffDeclared)\r\n ? (\r\n <p className={styles['error']} style={{ marginTop: 6 }}>\r\n {hasEmptyWire ? t('reasoningEffortEmptyWire') : t('reasoningEffortsNeedNonOff')}\r\n </p>\r\n )\r\n : null}\r\n </div>\r\n\r\n <label className={styles['modelField']} style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>\r\n <span className={styles['modelFieldLabel']}>{t('thinkingFormat')}</span>\r\n <select\r\n className={styles['input']}\r\n value={thinkingFormat ?? ''}\r\n disabled={disabled}\r\n onChange={(event) => {\r\n const value = event.target.value\r\n setCompatKey('thinkingFormat', value === '' ? undefined : value)\r\n }}\r\n >\r\n <option value=\"\">—</option>\r\n {THINKING_FORMATS.map(format => <option key={format} value={format}>{format}</option>)}\r\n </select>\r\n </label>\r\n </>\r\n )}\r\n\r\n {/* --- input modalities ------------------------------------------------ */}\r\n <div style={{ borderTop: '0.5px solid var(--color-border-tertiary, rgba(0,0,0,0.15))', paddingTop: 12 }}>\r\n <div className={styles['modelFieldLabel']} style={{ marginBottom: 6 }}>{t('inputModalities')}</div>\r\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 16 }}>\r\n {MODALITIES.map(modality => (\r\n <label key={modality} style={{ display: 'inline-flex', alignItems: 'center', gap: 6, cursor: 'pointer', fontSize: 13 }}>\r\n <input\r\n type=\"checkbox\"\r\n style={checkboxStyle}\r\n checked={inputList.includes(modality)}\r\n disabled={disabled}\r\n onChange={(event) => { toggleModality(modality, event.target.checked) }}\r\n />\r\n {modalityLabel(modality)}\r\n </label>\r\n ))}\r\n </div>\r\n </div>\r\n </fieldset>\r\n )\r\n}\r\n","/**\r\n * The model list of one pi-ai provider profile (EXT fork for dsh-model-extension).\r\n *\r\n * Forked from deepseek-harness packages/client/ui-settings-models\r\n * src/client/ModelListEditor.tsx @ 0.1.2-alpha.4.\r\n * Only difference vs upstream: each row's expanded capacities area additionally\r\n * renders <ModelExtensionFields>, which edits the same draft object in place —\r\n * the extension fields ride the card's existing save path untouched.\r\n *\r\n * The list is the profile's `models` array as the card holds it: an empty list\r\n * means \"serve this route's built-in catalog\", and any entry replaces that\r\n * catalog, so a row is only ever added deliberately. Fetching asks the endpoint\r\n * **the form currently shows** — including a key typed but not yet saved — so\r\n * adding a provider is one pass instead of save-then-return; the reply is\r\n * candidates the user picks from, never configuration written behind them.\r\n *\r\n * A provider that cannot be interrogated (an unreachable endpoint, a protocol\r\n * with no readable listing) is not a dead end: the failure is shown next to the\r\n * rows the user can still fill in by hand.\r\n */\r\n\r\nimport { useState } from 'react'\r\nimport type { ReactNode } from 'react'\r\nimport type { LlmDiscoveredModel } from '@deepseek-ai/dsh-api-remotes/client'\r\nimport { Button, Modal } from '@deepseek-ai/dsh-client-ui-primitives'\r\nimport { formatCapacity, parseCapacity } from './DeepSeekModelsEditor.tsx'\r\nimport type { ModelsOperations } from './operations.ts'\r\nimport type { DeepSeekModelDraft } from './DeepSeekModelsEditor.tsx'\r\nimport type { en } from './locales.ts'\r\nimport { ModelExtensionFields } from './ModelExtensionFields.tsx'\r\nimport styles from './ModelsSection.ext.module.css'\r\n\r\n/**\r\n * One configured model row. Fields this card does not edit must survive an\r\n * edit rather than being dropped by a rebuild.\r\n */\r\nexport type ModelDraft = DeepSeekModelDraft\r\n\r\n/** A row's text field, or the empty string when unset or not a string. */\r\nfunction textOf(model: ModelDraft, key: string): string {\r\n const value = model[key]\r\n return typeof value === 'string' ? value : ''\r\n}\r\n\r\n/** A row's numeric field, or `undefined` when unset or not a number. */\r\nfunction numberOf(model: ModelDraft, key: string): number | undefined {\r\n const value = model[key]\r\n return typeof value === 'number' ? value : undefined\r\n}\r\n\r\n/** What an interrogation needs, taken from the live form. */\r\nexport interface ProbeTarget {\r\n /** Settings namespace whose adapter family answers. */\r\n settingsNs: string\r\n /**\r\n * Route being edited, when the card edits one. An adapter that already\r\n * describes it answers from its own registry, so such a card can ask without\r\n * an endpoint at all.\r\n */\r\n provider?: string\r\n /** Endpoint as the form currently shows it. */\r\n baseURL?: string\r\n /** Wire protocol the form names, when it names one. */\r\n api?: string\r\n /** Key typed into the form and not yet stored, when there is one. */\r\n apiKey?: string\r\n}\r\n\r\n/** Props of {@link ModelListEditor}. */\r\nexport interface ModelListEditorProps {\r\n /** The rows as currently drafted. */\r\n models: readonly ModelDraft[]\r\n /** Whether the user layer currently owns the whole array; absent on a create. */\r\n overridden?: boolean\r\n /** Replace the drafted rows. */\r\n onChange: (models: ModelDraft[]) => void\r\n /** Remove the user-owned array and return to inheritance; absent on a create. */\r\n onReset?: () => void\r\n /** Endpoint facts for the fetch action. */\r\n probe: ProbeTarget\r\n /**\r\n * Copy key naming why the fetch action is unavailable, or `undefined` when\r\n * it is. The card owns this because the key it would send is judged there:\r\n * asking with a key the form has already refused spends a round trip to be\r\n * told what the field already says.\r\n */\r\n probeBlocked?: keyof typeof en | undefined\r\n /** The Host operations whose interrogation answers the fetch action. */\r\n operations: ModelsOperations\r\n /** Section copy. */\r\n t: (key: keyof typeof en) => string\r\n /** Disable every control (read-only deployment or a pending write). */\r\n disabled: boolean\r\n}\r\n\r\n/** Disclosure chevron; rotates to point down while its row is open. */\r\nfunction IconChevron({ open }: { open: boolean }): ReactNode {\r\n return (\r\n <svg\r\n width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden\r\n style={{ transform: open ? 'rotate(90deg)' : undefined, transition: 'transform 120ms ease' }}\r\n >\r\n <path d=\"M6 3.5L10.5 8L6 12.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\r\n </svg>\r\n )\r\n}\r\n\r\n/** Removal glyph for one model row. */\r\nfunction IconTrash(): ReactNode {\r\n return (\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden>\r\n <path\r\n d=\"M2.5 4h11M6.5 4V2.5h3V4M4 4l.7 9a1 1 0 001 .9h4.6a1 1 0 001-.9L12 4M6.5 6.8v4.4M9.5 6.8v4.4\"\r\n stroke=\"currentColor\" strokeWidth=\"1.3\" strokeLinecap=\"round\" strokeLinejoin=\"round\"\r\n />\r\n </svg>\r\n )\r\n}\r\n\r\n/** The two token counts edited as K/M-suffixed text behind a row's disclosure. */\r\ntype CapacityField = 'contextWindow' | 'maxTokens'\r\n\r\n/**\r\n * What an empty capacity field is worth, shown as its placeholder so a row left\r\n * blank does not read as a model with no capacity at all.\r\n *\r\n * The magnitudes are the adapter's own route-level fallbacks (`llm-pi-ai`'s\r\n * `defaultContextWindow` and `defaultMaxTokens`), spelled the way a person\r\n * would say them. They are a hint, not a mirror: this page counts `K` as 1000,\r\n * so typing `256K` stores 256000 while leaving the field blank keeps the\r\n * adapter's 262144. A deployment that overrides those defaults is not\r\n * reflected here — nothing on this page can read them.\r\n */\r\nconst CAPACITY_HINT: Readonly<Record<CapacityField, string>> = {\r\n contextWindow: '256K',\r\n maxTokens: '32K',\r\n}\r\n\r\n/**\r\n * Spell a stored count for a field that may be unset. The spelling itself is\r\n * {@link formatCapacity}, shared with the DeepSeek catalog editor so both\r\n * surfaces read and write one K/M vocabulary.\r\n * @param value - stored capacity, or `undefined` for an unset field.\r\n * @returns the field text, empty when unset.\r\n */\r\nfunction capacitySpelling(value: number | undefined): string {\r\n return value === undefined ? '' : formatCapacity(value)\r\n}\r\n\r\n/** Adopt a candidate, keeping whatever capacities the provider disclosed. */\r\nfunction adopt(candidate: LlmDiscoveredModel): ModelDraft {\r\n return {\r\n id: candidate.id,\r\n ...candidate.name === undefined ? {} : { name: candidate.name },\r\n ...candidate.contextWindow === undefined ? {} : { contextWindow: candidate.contextWindow },\r\n ...candidate.maxTokens === undefined ? {} : { maxTokens: candidate.maxTokens },\r\n }\r\n}\r\n\r\n/**\r\n * Render the model list with its fetch action.\r\n * @param props - the drafted rows, probe target, wire face, and copy.\r\n * @returns the model-list editor.\r\n */\r\nexport function ModelListEditor(props: ModelListEditorProps): ReactNode {\r\n const { models, onChange, probe, operations, t, disabled } = props\r\n const [busy, setBusy] = useState(false)\r\n const [failure, setFailure] = useState<string | undefined>(undefined)\r\n const [candidates, setCandidates] = useState<readonly LlmDiscoveredModel[] | undefined>(undefined)\r\n const [picked, setPicked] = useState<ReadonlySet<string>>(new Set())\r\n const [candidateQuery, setCandidateQuery] = useState('')\r\n // Rows carry an id and a name; capacities are the exception, so they stay\r\n // folded until asked for rather than crowding every row with four inputs.\r\n const [expanded, setExpanded] = useState<ReadonlySet<number>>(new Set())\r\n // Capacities are edited as text, so a field's keystrokes are held here rather\r\n // than re-derived from the parsed count on every change — that would rewrite\r\n // `1000` to `1K` mid-word. Unreadable text is kept past blur so the refusal\r\n // names a row the user can still see, which is why this is one entry PER\r\n // FIELD: a single buffer would be displaced by editing any other field, and\r\n // the abandoned one would render its stored NaN as the literal `NaN`.\r\n const [editing, setEditing] = useState<ReadonlyMap<string, string>>(new Map())\r\n\r\n /** Buffer key for one capacity field; the row half moves when rows do. */\r\n const bufferKey = (index: number, field: CapacityField): string => `${String(index)}:${field}`\r\n\r\n const editCapacity = (index: number, field: CapacityField, text: string): void => {\r\n setEditing(current => new Map(current).set(bufferKey(index, field), text))\r\n patch(index, { [field]: parseCapacity(text) })\r\n }\r\n\r\n /** What a capacity field shows: the buffer while typing, else the stored count. */\r\n const capacityText = (model: ModelDraft, index: number, field: CapacityField): string =>\r\n editing.get(bufferKey(index, field)) ?? capacitySpelling(numberOf(model, field))\r\n\r\n /** Drop one row's entries and shift the rows after it down, in one pass. */\r\n const reindexOnRemove = (\r\n current: ReadonlyMap<string, string>,\r\n index: number,\r\n ): Map<string, string> => {\r\n const next = new Map<string, string>()\r\n for (const [key, value] of current) {\r\n const at = Number(key.slice(0, key.indexOf(':')))\r\n if (at === index) continue\r\n // Only the row number moves; the field half of the key is untouched.\r\n next.set(at > index ? key.replace(/^\\d+/, String(at - 1)) : key, value)\r\n }\r\n return next\r\n }\r\n\r\n const toggleExpanded = (index: number): void => {\r\n setExpanded((current) => {\r\n const next = new Set(current)\r\n if (!next.delete(index)) next.add(index)\r\n return next\r\n })\r\n }\r\n\r\n const patch = (index: number, next: Record<string, string | number | undefined>): void => {\r\n onChange(models.map((model, at) => {\r\n if (at !== index) return model\r\n // Rebuilt rather than spread over: an emptied optional field has to leave\r\n // the profile, not be stored as a value its schema would reject.\r\n // Spread first so a field this card does not edit survives; an emptied\r\n // optional field is then dropped rather than stored as a value its\r\n // schema would reject.\r\n const cleared = new Set(\r\n Object.entries(next).filter(([, value]) => value === undefined || value === '').map(([key]) => key),\r\n )\r\n return Object.fromEntries(\r\n Object.entries({ ...model, ...next }).filter(([key]) => !cleared.has(key)),\r\n )\r\n }))\r\n }\r\n\r\n const fetchModels = async (): Promise<void> => {\r\n setBusy(true)\r\n setFailure(undefined)\r\n try {\r\n const answer = await operations.discoverModels(probe.settingsNs, {\r\n ...probe.provider === undefined ? {} : { provider: probe.provider },\r\n ...probe.baseURL === undefined || probe.baseURL.length === 0 ? {} : { baseURL: probe.baseURL },\r\n ...probe.api === undefined ? {} : { api: probe.api },\r\n ...probe.apiKey === undefined ? {} : { apiKey: probe.apiKey },\r\n })\r\n if (answer.kind === 'refused') {\r\n setFailure(answer.message)\r\n return\r\n }\r\n const found = answer.models\r\n if (found.length === 0) {\r\n setFailure(t('fetchEmpty'))\r\n return\r\n }\r\n // Everything already configured starts unchecked, so adopting a\r\n // selection never silently rewrites a capacity the user corrected.\r\n const known = new Set(models.map(model => textOf(model, 'id')))\r\n setCandidateQuery('')\r\n setCandidates(found)\r\n setPicked(new Set(found.filter(model => !known.has(model.id)).map(model => model.id)))\r\n } finally {\r\n setBusy(false)\r\n }\r\n }\r\n\r\n const closePicker = (): void => {\r\n setCandidates(undefined)\r\n setPicked(new Set())\r\n setCandidateQuery('')\r\n }\r\n\r\n const adoptPicked = (): void => {\r\n /* v8 ignore next -- the dialog only renders with candidates loaded */\r\n if (candidates === undefined) return\r\n const byId = new Map(models.map(model => [textOf(model, 'id'), model]))\r\n for (const candidate of candidates) {\r\n if (!picked.has(candidate.id)) continue\r\n // A row the user already tuned wins over the provider's own numbers.\r\n // Keyed by id, so a half-typed row whose id is still empty is not a\r\n // match and the candidate joins as its own row — correct, since a row\r\n // without an id is not yet a model and the create/apply gates refuse it.\r\n byId.set(candidate.id, byId.get(candidate.id) ?? adopt(candidate))\r\n }\r\n onChange([...byId.values()])\r\n closePicker()\r\n }\r\n\r\n const toggle = (id: string): void => {\r\n setPicked((current) => {\r\n const next = new Set(current)\r\n if (!next.delete(id)) next.add(id)\r\n return next\r\n })\r\n }\r\n\r\n const activeCandidates = candidates ?? []\r\n const normalizedCandidateQuery = candidateQuery.trim().toLowerCase()\r\n const visibleCandidates = normalizedCandidateQuery.length === 0\r\n ? activeCandidates\r\n : activeCandidates.filter(candidate => candidate.id.toLowerCase().includes(normalizedCandidateQuery)\r\n || candidate.name?.toLowerCase().includes(normalizedCandidateQuery) === true)\r\n const allVisibleCandidatesPicked = visibleCandidates.length > 0\r\n && visibleCandidates.every(candidate => picked.has(candidate.id))\r\n\r\n const toggleVisibleCandidates = (): void => {\r\n setPicked((current) => {\r\n const next = new Set(current)\r\n if (visibleCandidates.every(candidate => current.has(candidate.id))) {\r\n for (const candidate of visibleCandidates) next.delete(candidate.id)\r\n } else {\r\n for (const candidate of visibleCandidates) next.add(candidate.id)\r\n }\r\n return next\r\n })\r\n }\r\n\r\n // A route the adapter already describes answers without an endpoint; only a\r\n // draft with neither has nothing to ask about.\r\n const askable = probe.provider !== undefined || (probe.baseURL !== undefined && probe.baseURL.length > 0)\r\n return (\r\n <section className={styles['modelCatalog']} aria-label={t('models')}>\r\n <div className={styles['modelListHead']}>\r\n <div className={styles['modelCatalogHeading']}>\r\n <span className={styles['modelCatalogTitle']}>{t('models')}</span>\r\n {props.overridden === undefined\r\n ? null\r\n : (\r\n <span className={styles['modelCatalogMeta']}>\r\n {props.overridden ? t('modelsCustomized') : t('modelsInherited')}\r\n </span>\r\n )}\r\n </div>\r\n {props.overridden === true && props.onReset !== undefined\r\n ? (\r\n <button\r\n type=\"button\"\r\n className={styles['linkButton']}\r\n disabled={disabled}\r\n onClick={props.onReset}\r\n >\r\n {t('resetModels')}\r\n </button>\r\n )\r\n : null}\r\n <button\r\n type=\"button\"\r\n className={styles['linkButton']}\r\n disabled={disabled || busy || !askable || props.probeBlocked !== undefined}\r\n title={props.probeBlocked !== undefined\r\n ? t(props.probeBlocked)\r\n : askable ? undefined : t('fetchNeedsBaseUrl')}\r\n onClick={() => { void fetchModels() }}\r\n >\r\n {busy ? t('fetching') : t('fetchModels')}\r\n </button>\r\n </div>\r\n {models.length === 0 ? <p className={styles['modelEmpty']}>{t('modelsEmpty')}</p> : null}\r\n {models.map((model, index) => (\r\n <div key={index} className={styles['modelEntry']}>\r\n <div className={styles['modelRow']}>\r\n <input\r\n className={styles['input']}\r\n type=\"text\"\r\n value={textOf(model, 'id')}\r\n placeholder={t('modelId')}\r\n aria-label={`${t('modelId')} ${index + 1}`}\r\n disabled={disabled}\r\n onChange={(event) => { patch(index, { id: event.target.value }) }}\r\n />\r\n <input\r\n className={styles['input']}\r\n type=\"text\"\r\n value={textOf(model, 'name')}\r\n placeholder={t('modelName')}\r\n aria-label={`${t('modelName')} ${index + 1}`}\r\n disabled={disabled}\r\n onChange={(event) => { patch(index, { name: event.target.value === '' ? undefined : event.target.value }) }}\r\n />\r\n <button\r\n type=\"button\"\r\n className={styles['iconButton']}\r\n aria-label={`${t('modelAdvanced')} ${index + 1}`}\r\n aria-expanded={expanded.has(index)}\r\n title={t('modelAdvanced')}\r\n onClick={() => { toggleExpanded(index) }}\r\n >\r\n <IconChevron open={expanded.has(index)} />\r\n </button>\r\n <button\r\n type=\"button\"\r\n className={`${styles['iconButton']} ${styles['iconButtonDanger']}`}\r\n aria-label={`${t('removeModel')} ${index + 1}`}\r\n title={t('removeModel')}\r\n disabled={disabled}\r\n onClick={() => {\r\n onChange(models.filter((_model, at) => at !== index))\r\n // Both stores are keyed by position, so every row after this\r\n // one shifts down and would otherwise inherit its neighbour's\r\n // state — a different row's capacities popping open, or its\r\n // half-typed text appearing in another row's field.\r\n setExpanded((current) => {\r\n const next = new Set<number>()\r\n for (const at of current) {\r\n if (at < index) next.add(at)\r\n else if (at > index) next.add(at - 1)\r\n }\r\n return next\r\n })\r\n setEditing(current => reindexOnRemove(current, index))\r\n }}\r\n >\r\n <IconTrash />\r\n </button>\r\n </div>\r\n {expanded.has(index)\r\n ? (\r\n <>\r\n {/* Host `.modelAdvanced` is `display:grid` with\r\n `repeat(auto-fit, minmax(160px, 1fr))`; any child placed\r\n INSIDE it is squeezed into one narrow grid column. The\r\n extension fields need the full entry width, so they render\r\n as a SIBLING of `.modelAdvanced` — a direct child of the\r\n block-level `.modelEntry` — rather than inside its grid. */}\r\n <div className={styles['modelAdvanced']}>\r\n <label className={styles['modelField']}>\r\n <span className={styles['modelFieldLabel']}>{t('modelContextWindow')}</span>\r\n <input\r\n className={styles['input']}\r\n type=\"text\"\r\n inputMode=\"numeric\"\r\n value={capacityText(model, index, 'contextWindow')}\r\n placeholder={CAPACITY_HINT.contextWindow}\r\n aria-label={`${t('modelContextWindow')} ${index + 1}`}\r\n disabled={disabled}\r\n onChange={(event) => { editCapacity(index, 'contextWindow', event.target.value) }}\r\n />\r\n </label>\r\n <label className={styles['modelField']}>\r\n <span className={styles['modelFieldLabel']}>{t('modelMaxTokens')}</span>\r\n <input\r\n className={styles['input']}\r\n type=\"text\"\r\n inputMode=\"numeric\"\r\n value={capacityText(model, index, 'maxTokens')}\r\n placeholder={CAPACITY_HINT.maxTokens}\r\n aria-label={`${t('modelMaxTokens')} ${index + 1}`}\r\n disabled={disabled}\r\n onChange={(event) => { editCapacity(index, 'maxTokens', event.target.value) }}\r\n />\r\n </label>\r\n </div>\r\n {/* EXT-only: extension fields edit the same draft object in\r\n place; the card's own save path persists them untouched.\r\n patch is (index, next) — bind this row's index here. */}\r\n <div className={styles['modelExtensionFields']}>\r\n <ModelExtensionFields\r\n model={model}\r\n onChange={(next) => { patch(index, next) }}\r\n disabled={disabled}\r\n />\r\n </div>\r\n </>\r\n )\r\n : null}\r\n </div>\r\n ))}\r\n <button\r\n type=\"button\"\r\n className={styles['addModelButton']}\r\n disabled={disabled}\r\n onClick={() => { onChange([...models, { id: '' }]) }}\r\n >\r\n {t('addModel')}\r\n </button>\r\n {failure !== undefined ? <p className={styles['error']}>{failure}</p> : null}\r\n <Modal\r\n open={candidates !== undefined}\r\n onClose={closePicker}\r\n title={t('fetchTitle')}\r\n closeLabel={t('close')}\r\n description={t('fetchDescription')}\r\n className={styles['fetchDialog'] as string}\r\n footer={(\r\n <>\r\n <Button variant=\"outline\" onClick={closePicker}>{t('cancel')}</Button>\r\n <Button variant=\"outline\" onClick={adoptPicked}>{t('fetchAdopt')}</Button>\r\n </>\r\n )}\r\n >\r\n <div className={styles['candidateToolbar']}>\r\n <input\r\n className={`${styles['input']} ${styles['candidateSearch']}`}\r\n type=\"search\"\r\n value={candidateQuery}\r\n placeholder={t('fetchSearch')}\r\n aria-label={t('fetchSearch')}\r\n onChange={(event) => { setCandidateQuery(event.target.value) }}\r\n />\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n disabled={visibleCandidates.length === 0}\r\n onClick={toggleVisibleCandidates}\r\n >\r\n {t(allVisibleCandidatesPicked ? 'fetchDeselectAll' : 'fetchSelectAll')}\r\n </Button>\r\n </div>\r\n {visibleCandidates.length === 0\r\n ? <p className={styles['candidateEmpty']} role=\"status\">{t('fetchNoMatches')}</p>\r\n : (\r\n <ul className={styles['candidateList']}>\r\n {visibleCandidates.map(candidate => (\r\n <li key={candidate.id} className={styles['candidate']}>\r\n <label className={styles['candidateLabel']}>\r\n <input\r\n type=\"checkbox\"\r\n checked={picked.has(candidate.id)}\r\n onChange={() => { toggle(candidate.id) }}\r\n />\r\n {/* The id alone: it is the string adoption writes, and the\r\n capacities the endpoint reported are adopted with it and\r\n editable in the row that appears. */}\r\n <span className={styles['candidateId']}>{candidate.id}</span>\r\n </label>\r\n </li>\r\n ))}\r\n </ul>\r\n )}\r\n </Modal>\r\n </section>\r\n )\r\n}\r\n","/**\n * Models settings page store: one snapshot joining the configurable-provider\n * directory (`llm/listProviders` joined with `llm/listConfigurableProviders`),\n * the settings namespaces (shared settings mirror),\n * and the referenced credentials (`credentials/describe`). The host stays the\n * single fact source — every mutation writes through the wire and the page\n * re-renders from the next describe, pushed or refetched.\n */\n\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type {\n CredentialInfo, LlmConfigurableProvider, LlmProviderInfo, SettingsNamespaceView,\n} from '@deepseek-ai/dsh-api-remotes/client'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport { createSnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport type { SettingsDescribeFace } from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type { SettingsSchemaOperations } from './schema-operations.ts'\n\n/**\n * Any route key walks a dict schema to the same profile node, so the lookup\n * names one that cannot collide with a configured route.\n */\nconst PROBE_ROUTE = '\\u0000probe'\n\n/** One provider row after joining the configurable directory with live routes. */\nexport interface ProviderDirectoryEntry {\n readonly provider: string\n readonly displayName: string\n readonly settingsNs: string\n readonly settingsPath: readonly string[]\n readonly active: boolean\n readonly declared?: boolean\n}\n\n/**\n * Join declared configurable providers with the currently registered routes.\n * @param registered - live provider routes in registration order.\n * @param directory - declared configurable providers in declaration order.\n * @returns declared rows followed by live routes with no declaration.\n */\nexport function joinProviderDirectory(\n registered: readonly LlmProviderInfo[],\n directory: readonly LlmConfigurableProvider[],\n): ProviderDirectoryEntry[] {\n const active = new Set(registered.map(provider => provider.id))\n const declared = new Set(directory.map(entry => entry.provider))\n const rows: ProviderDirectoryEntry[] = directory.map(entry => ({\n provider: entry.provider,\n displayName: entry.displayName,\n settingsNs: entry.settingsNs,\n settingsPath: [...entry.settingsPath],\n active: active.has(entry.provider),\n ...entry.declared === undefined ? {} : { declared: entry.declared },\n }))\n for (const provider of registered) {\n if (declared.has(provider.id)) continue\n rows.push({\n provider: provider.id,\n displayName: provider.name,\n settingsNs: '',\n settingsPath: [],\n active: true,\n })\n }\n return rows\n}\n\n/** One provider row the page renders. */\nexport interface ProviderRow {\n /** The directory entry (route id, display name, settings address, live state). */\n entry: ProviderDirectoryEntry\n /** Whether any layer configures this provider (its profile resolves). */\n configured: boolean\n /** Whether the user layer alone carries the profile (removal restores the base). */\n removable: boolean\n /** The credential reference the resolved profile names, when one does. */\n apiKeyEnv: string | undefined\n /** Credential state for {@link apiKeyEnv}, once described. */\n credential: CredentialInfo | undefined\n /**\n * Credential state for the page's derived `<ROUTE>_API_KEY`, described only\n * while the profile names no reference — the provider-card seat's\n * `keyConfigured` fact for dormant and keyless rows, matching the editor's\n * own derivation rule.\n */\n derivedCredential?: CredentialInfo\n}\n\n/** Page snapshot. */\nexport interface ModelsSettingsState {\n status: 'idle' | 'loading' | 'ready' | 'error'\n /** Whole-load failure text; row-level write failures stay in the editor. */\n error: string | null\n /** Credential enrichment failure; provider/settings rows remain usable. */\n credentialError: string | null\n /** Whether the settings provider accepts writes. */\n writable: boolean\n /** Every configurable provider joined with its configured/credential state. */\n rows: readonly ProviderRow[]\n /** Namespace views by ns, for the editor's schema/layers/secrets. */\n namespaces: ReadonlyMap<string, SettingsNamespaceView>\n}\n\n/**\n * Derive the conventional credential reference for a provider route: the v1\n * page never asks for an environment-variable name, so a typed key stores\n * under this derived reference and the profile records it as `apiKeyEnv`.\n * @param provider - provider route id (e.g. `anthropic`, `minimax-cn`).\n * @returns the derived reference name (e.g. `MINIMAX_CN_API_KEY`).\n */\nexport function deriveKeyRef(provider: string): string {\n return `${provider.toUpperCase().replace(/[^A-Z0-9]+/g, '_')}_API_KEY`\n}\n\n/**\n * The wire protocols a hand-declared route may name, read out of the owning\n * namespace's own schema. This stays a schema read rather than a wire field so\n * the choices the page offers cannot drift from the ones the adapter accepts:\n * both come from the same `Config`.\n * @param namespace - the namespace view whose schema declares the profile shape.\n * @param schema - settings schema operations.\n * @returns the protocol identifiers, or an empty list when the schema has none.\n */\nexport function protocolChoices(\n namespace: SettingsNamespaceView | undefined,\n schema: SettingsSchemaOperations,\n): string[] {\n if (namespace === undefined) return []\n const node = schema.nodeAtPath(schema.rehydrate(namespace.schema), ['providers', PROBE_ROUTE, 'api'])\n const list = (node as { type?: string; list?: readonly { value?: unknown }[] } | undefined)\n if (list?.type !== 'union' || list.list === undefined) return []\n return list.list.map(entry => entry.value).filter((value): value is string => typeof value === 'string')\n}\n\n/** The credential reference a resolved profile names (its `apiKeyEnv` field). */\nfunction apiKeyEnvOf(\n namespace: SettingsNamespaceView | undefined,\n path: readonly string[],\n schema: SettingsSchemaOperations,\n): string | undefined {\n if (namespace === undefined) return undefined\n const profile = schema.getPath(namespace.value, path)\n if (typeof profile !== 'object' || profile === null) return undefined\n const ref = (profile as { apiKeyEnv?: unknown }).apiKeyEnv\n return typeof ref === 'string' && ref.length > 0 ? ref : undefined\n}\n\n/** The models settings page controller (one per settings surface). */\nexport class ModelsSettingsStore {\n /** The snapshot the section renders from (uSES-safe store). */\n readonly store: SnapshotStore<ModelsSettingsState> = createSnapshotStore<ModelsSettingsState>({\n status: 'idle', error: null, credentialError: null, writable: false, rows: [], namespaces: new Map(),\n })\n\n /** Latest load wins; an older response never overwrites a newer one. */\n private generation = 0\n\n /**\n * @param ctx - the page plugin's context, whose `remote.llm` and\n * `remote.credentials` namespaces carry the directory and credential reads.\n * @param schema - settings-owned schema and immutable path operations.\n * @param describeFace - the shared mirror's describe face (namespace views and writability).\n */\n constructor(\n private readonly ctx: ClientContext,\n private readonly schema: SettingsSchemaOperations,\n private readonly describeFace: SettingsDescribeFace,\n ) {}\n\n /**\n * Refresh the whole page snapshot: the provider directory and the mirror's\n * settings answer in parallel, then one batched credential describe over\n * every referenced ref. Provider failure or absence of an initial settings\n * answer keeps the last good rows and surfaces an error; a failed settings\n * refresh reuses the mirror's held view.\n * @returns nothing; the snapshot carries the outcome.\n */\n async load(): Promise<void> {\n const generation = ++this.generation\n this.store.update((s) => { s.status = 'loading'; s.error = null })\n const [registered, declared] = await Promise.all([\n this.ctx.remote.llm.listProviders(),\n this.ctx.remote.llm.listConfigurableProviders(),\n this.describeFace.ensure(),\n ])\n if (!registered.ok) { this.failLoad(generation, registered.error.message); return }\n if (!declared.ok) { this.failLoad(generation, declared.error.message); return }\n const mirrored = this.describeFace.getSnapshot()\n if (mirrored.view === undefined) {\n this.failLoad(generation, mirrored.error ?? 'settings are unavailable in this browser')\n return\n }\n const providers = joinProviderDirectory(registered.value, declared.value)\n const writable = mirrored.view.writable\n const views: readonly SettingsNamespaceView[] = mirrored.view.namespaces\n const namespaces = new Map(views.map(view => [view.ns, view]))\n const rows: ProviderRow[] = providers.map((entry) => {\n const namespace = namespaces.get(entry.settingsNs)\n const configured = namespace !== undefined\n && (entry.settingsPath.length === 0 || this.schema.getPath(namespace.value, entry.settingsPath) !== undefined)\n const removable = namespace !== undefined\n && entry.settingsPath.length > 0\n && this.schema.hasPath(namespace.user, entry.settingsPath)\n && !this.schema.hasPath(namespace.base, entry.settingsPath)\n return {\n entry,\n configured,\n removable,\n apiKeyEnv: apiKeyEnvOf(namespace, entry.settingsPath, this.schema),\n credential: undefined,\n }\n })\n const refs = [...new Set(rows.map(row => row.apiKeyEnv ?? deriveKeyRef(row.entry.provider)))]\n let credentials: Record<string, CredentialInfo> = {}\n let credentialError: string | null = null\n if (refs.length > 0) {\n const response = await this.ctx.remote.credentials.describe(refs)\n // Credential state is an enrichment for the Models page: a failure\n // degrades the badge instead of failing the load. The onboarding\n // projection below retains the failure distinction.\n if (response.ok) credentials = response.value\n else credentialError = response.error.message\n }\n if (generation !== this.generation) return\n this.store.update((s) => {\n s.status = 'ready'\n s.error = null\n s.credentialError = credentialError\n s.writable = writable\n s.rows = rows.map((row) => {\n const named = row.apiKeyEnv === undefined ? undefined : credentials[row.apiKeyEnv]\n const derived = row.apiKeyEnv !== undefined ? undefined : credentials[deriveKeyRef(row.entry.provider)]\n return {\n ...row,\n ...named === undefined ? {} : { credential: named },\n ...derived === undefined ? {} : { derivedCredential: derived },\n }\n })\n s.namespaces = namespaces\n })\n }\n\n /** Publish one load's failure text, unless a newer load already took over. */\n private failLoad(generation: number, message: string): void {\n if (generation !== this.generation) return\n this.store.update((s) => {\n s.status = 'error'\n s.error = message\n })\n }\n}\n\n/**\n * Whether a joined row can serve model requests as it stands: the route is\n * registered with the adapter registry, and whatever credential its resolved\n * profile names is stored. A profile naming no reference authenticates through\n * the provider's own path (the Bedrock chain, Vertex ADC, a gateway that needs\n * nothing), as does a live route with no settings address at all, so neither\n * owes this page a key.\n * @param row - one joined provider row.\n * @returns whether the user already has this provider to talk to.\n */\nexport function providerUsable(row: ProviderRow): boolean {\n if (!row.entry.active) return false\n if (row.apiKeyEnv === undefined) return true\n return row.credential?.configured === true\n}\n\n/** First-run onboarding readiness derived only from the shared Models join. */\nexport type OnboardingReadiness =\n | { kind: 'loading' }\n | { kind: 'adapter-absent' }\n | { kind: 'provider-ready' }\n | { kind: 'credential-missing' }\n | {\n kind: 'unavailable'\n reason:\n | 'load-failed'\n | 'provider-inactive'\n | 'credentials-unavailable'\n | 'settings-read-only'\n | 'credential-read-only'\n }\n\n/**\n * Project first-run readiness from the provider/settings/credential join used\n * by the Models page. The step exists to leave the user with a model to talk\n * to, so ANY usable provider ends it; only when none exists does the official\n * DeepSeek route — the one route the prompt can offer a key field for — decide\n * whether prompting can help. A missing official configurable-provider\n * declaration means the adapter is not repairable by navigating to Models.\n * @param state - current shared Models join snapshot.\n * @returns the onboarding state without reading a parallel fact source.\n */\nexport function onboardingReadiness(state: ModelsSettingsState): OnboardingReadiness {\n if ((state.status === 'idle' || state.status === 'loading') && state.rows.length === 0) {\n return { kind: 'loading' }\n }\n if (state.status === 'error') {\n return {\n kind: 'unavailable',\n reason: 'load-failed',\n }\n }\n if (state.rows.some(providerUsable)) return { kind: 'provider-ready' }\n const row = state.rows.find(candidate =>\n candidate.entry.provider === 'deepseek-official'\n && candidate.entry.settingsNs === 'llm-deepseek'\n && candidate.entry.settingsPath.length === 0)\n if (row === undefined) return { kind: 'adapter-absent' }\n if (!row.entry.active) {\n return {\n kind: 'unavailable',\n reason: 'provider-inactive',\n }\n }\n // Past the usable gate an active route names a reference it has no stored\n // credential for, so the remaining questions are all about that credential.\n if (state.credentialError !== null || row.credential === undefined) {\n return {\n kind: 'unavailable',\n reason: 'credentials-unavailable',\n }\n }\n if (!state.writable) {\n return {\n kind: 'unavailable',\n reason: 'settings-read-only',\n }\n }\n if (!row.credential.writable) {\n return {\n kind: 'unavailable',\n reason: 'credential-read-only',\n }\n }\n return { kind: 'credential-missing' }\n}\n","/**\n * The card that declares a provider pi-ai does not ship — an OpenAI-compatible\n * gateway, a self-hosted server, or a provider newer than the installed\n * catalog.\n *\n * This is a create, not an edit, which is why it is its own card rather than\n * the provider editor with extra fields: the route id is being *chosen* here,\n * and the settings address does not exist until it is. One `settings.mutate`\n * sets the whole profile at `providers.<route>`; the key travels separately\n * through `credentials/set` under the reference the profile records, exactly as\n * an existing provider's key does.\n *\n * The three fields a hand-declared route cannot default — endpoint, protocol,\n * and at least one model — are required here rather than at load, so the\n * failure names the field while the user is still looking at it.\n *\n * There is deliberately no reasoning-effort control, here or on the editor\n * card: effort is a per-MODEL capability, and the models under one provider\n * disagree about it, so a provider-scoped control can only be set to a value\n * some of them reject. The composer's model picker offers each model its own\n * levels instead.\n */\n\nimport { useState } from 'react'\nimport type { ReactNode } from 'react'\nimport type { JsonValue } from '@deepseek-ai/dsh-util-values'\nimport { apiKeyFailure } from './apiKey.ts'\nimport { EditorFooter } from './EditorFooter.tsx'\nimport { validateDeepSeekModels } from './DeepSeekModelsEditor.tsx'\nimport { ModelListEditor } from './ModelListEditor.tsx'\nimport type { ModelDraft } from './ModelListEditor.tsx'\nimport { deriveKeyRef } from './store.ts'\nimport type { ModelsOperations } from './operations.ts'\nimport type { en } from './locales.ts'\nimport styles from './ModelsSection.module.css'\n\n/** The settings namespace a hand-declared provider is written into. */\nconst NS = 'llm-pi-ai'\n\n/**\n * A route id usable as a settings key AND as the stem of a credential name.\n * The leading letter is the second half of that: `deriveKeyRef` uppercases the\n * id and replaces every non-alphanumeric run with `_`, and a credential\n * reference is a POSIX shell identifier, which cannot start with a digit. A\n * digit-leading id passes every check this card makes and then fails at the\n * credential seam with a raw regular expression the user cannot act on.\n */\nconst ROUTE_PATTERN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/\n\n/** Props of {@link CustomProviderCard}. */\nexport interface CustomProviderCardProps {\n /** Route ids already declared, so the card refuses to shadow one. */\n taken: readonly string[]\n /** Wire protocols the adapter can serve, in the order it reports them. */\n protocols: readonly string[]\n /**\n * Revision of the `llm-pi-ai` user section this card opened at, sent with\n * the create so a route another tab declared meanwhile is a refusal rather\n * than a silent overwrite of its whole profile.\n */\n revision: number\n /** The Host operations this card writes and interrogates through. */\n operations: ModelsOperations\n /** Section copy. */\n t: (key: keyof typeof en) => string\n /** Disable writes (read-only settings provider). */\n readOnly: boolean\n /** Close the card; `changed` reports whether a provider was created. */\n onClose: (changed: boolean) => void\n}\n\n/**\n * Render the custom-provider creation card.\n * @param props - existing routes, protocol choices, wire faces, and copy.\n * @returns the creation card.\n */\nexport function CustomProviderCard(props: CustomProviderCardProps): ReactNode {\n const { taken, protocols, operations, t } = props\n // The write is checked against the revision on which this draft was opened.\n const [openedAt] = useState(() => props.revision)\n const [route, setRoute] = useState('')\n const [displayName, setDisplayName] = useState('')\n const [baseURL, setBaseURL] = useState('')\n const [protocol, setProtocol] = useState(protocols[0] ?? '')\n const [keyDraft, setKeyDraft] = useState('')\n const [models, setModels] = useState<readonly ModelDraft[]>([])\n const [busy, setBusy] = useState(false)\n const [failure, setFailure] = useState<string | undefined>(undefined)\n /**\n * The profile write landed. Only the key write can still be outstanding, so\n * the fields that describe the provider are settled and the retry path is\n * the credential alone.\n */\n const [committed, setCommitted] = useState(false)\n const disabled = props.readOnly || busy\n /** Everything but the key stops being editable once the provider exists. */\n const profileDisabled = disabled || committed\n\n const routeInvalid = route.length > 0 && !ROUTE_PATTERN.test(route)\n const routeTaken = taken.includes(route)\n // Rows are checked by the same per-row validator the editor cards use, so a\n // bad row is named by its position here too. Capacities have route-level\n // fallbacks; what a route cannot default is at least one model.\n const modelFailure = validateDeepSeekModels(models)\n const keyFailure = apiKeyFailure(keyDraft)\n // The typed key with paste whitespace removed. A blank field yields an empty\n // string, which the create path reads as \"no key supplied\" — a route may\n // legitimately authenticate through the provider's own ambient discovery.\n const keyValue = keyDraft.trim()\n const ready = route.length > 0 && !routeInvalid && !routeTaken\n && baseURL.length > 0 && models.length > 0 && modelFailure === undefined\n && keyFailure === undefined\n // The one blocked gate worth a line under the form. A satisfied card says\n // nothing at all rather than printing an empty paragraph.\n const hint = failure !== undefined || ready\n // The key field prints its own failure directly beneath itself, so a card\n // blocked only by the key stays silent here rather than answering with the\n // next unmet gate — which is satisfied, and reads as a second, false fault.\n || keyFailure !== undefined\n // Same for the route id, and it must be tested rather than assumed: the\n // fallback arm below reads \"no models yet\", so an unmet route gate would\n // fall through to it and contradict the filled-in list right above.\n || route.length === 0 || routeInvalid || routeTaken\n ? undefined\n : baseURL.length === 0\n ? t('customNeedsBaseUrl')\n : modelFailure !== undefined\n ? `${t('model')} ${String(modelFailure.index + 1)}: ${t(modelFailure.key)}`\n : t('customNeedsModels')\n\n /** Perform the create, returning a failure message or undefined. */\n const createOnce = async (): Promise<string | undefined> => {\n const keyRef = deriveKeyRef(route)\n const storesKey = keyValue.length > 0\n if (!committed) {\n const profile = {\n ...displayName.length === 0 ? {} : { displayName },\n // The profile names the conventional reference only when this card is\n // about to store a key, matching the editor: a route declared with the\n // key left blank keeps its provider-native auth path (a credential\n // chain, ADC) instead of resolving a reference nothing ever sets.\n ...storesKey ? { apiKeyEnv: keyRef } : {},\n api: protocol,\n baseURL,\n models: models.map(model => ({ ...model })),\n }\n // `taken` is a snapshot too, so the id check alone cannot see a route\n // declared after this card opened; the revision makes that race a\n // `settings-conflict` instead of a write over the other profile.\n const written = await operations.writeSettings(\n NS,\n [{ op: 'set', path: ['providers', route], value: profile as JsonValue }],\n openedAt,\n )\n if (written.kind !== 'written') {\n return written.kind === 'conflict' ? t('conflict') : written.message\n }\n // The provider now exists. A retry after the key write below fails must\n // not re-run this mutate: the revision it holds is the one this write\n // just superseded, so the Host would answer `settings-conflict` and the\n // key could never be stored from this card at all.\n setCommitted(true)\n }\n if (storesKey) {\n const stored = await operations.storeCredential(keyRef, keyValue)\n // The profile landed; saying the key did not is the only honest report,\n // and the retry above now goes straight back to this write.\n if (stored !== undefined) return stored\n }\n return undefined\n }\n\n const create = async (): Promise<void> => {\n setBusy(true)\n setFailure(undefined)\n try {\n const outcome = await createOnce()\n if (outcome !== undefined) {\n setFailure(outcome)\n return\n }\n props.onClose(true)\n } finally {\n setBusy(false)\n }\n }\n\n return (\n <div className={styles['editor']}>\n <div className={styles['editorHeader']}>\n <span className={styles['editorTitle']}>{t('customTitle')}</span>\n </div>\n <div className={styles['field']}>\n <span className={styles['fieldLabel']}>{t('customRoute')}</span>\n <input\n className={styles['input']}\n type=\"text\"\n value={route}\n placeholder=\"acme-gateway\"\n aria-label={t('customRoute')}\n disabled={profileDisabled}\n onChange={(event) => { setRoute(event.target.value) }}\n />\n </div>\n {/* A rejected id reads as a fault, not as guidance — the same split the\n key field below already makes between its failure and its hint. */}\n {routeInvalid || routeTaken\n ? <p className={styles['error']}>{t(routeInvalid ? 'customRouteInvalid' : 'customRouteTaken')}</p>\n : <p className={styles['advancedHint']}>{t('customRouteHint')}</p>}\n <div className={styles['field']}>\n <span className={styles['fieldLabel']}>{t('customDisplayName')}</span>\n <input\n className={styles['input']}\n type=\"text\"\n value={displayName}\n placeholder={route.length === 0 ? t('customDisplayName') : route}\n aria-label={t('customDisplayName')}\n disabled={profileDisabled}\n onChange={(event) => { setDisplayName(event.target.value) }}\n />\n </div>\n <div className={styles['field']}>\n <span className={styles['fieldLabel']}>{t('baseUrl')}</span>\n <input\n className={styles['input']}\n type=\"text\"\n value={baseURL}\n placeholder={t('customBaseUrlPlaceholder')}\n aria-label={t('baseUrl')}\n disabled={profileDisabled}\n onChange={(event) => { setBaseURL(event.target.value) }}\n />\n </div>\n <div className={styles['field']}>\n <span className={styles['fieldLabel']}>{t('customApi')}</span>\n <select\n className={`${styles['input']} ${styles['selectInput']}`}\n value={protocol}\n aria-label={t('customApi')}\n disabled={profileDisabled}\n onChange={(event) => { setProtocol(event.target.value) }}\n >\n {protocols.map(choice => <option key={choice} value={choice}>{choice}</option>)}\n </select>\n </div>\n <div className={styles['field']}>\n <span className={styles['fieldLabel']}>{t('keyInput')}</span>\n <input\n className={styles['input']}\n type=\"password\"\n autoComplete=\"off\"\n value={keyDraft}\n placeholder={t('keyPlaceholder')}\n aria-label={t('keyInput')}\n disabled={disabled}\n onChange={(event) => { setKeyDraft(event.target.value) }}\n />\n {/* A create card has no stored key to keep, so the blank case says\n what a blank field means here instead: this route may authenticate\n through the provider's own ambient discovery or OAuth. */}\n {keyFailure === undefined\n ? null\n : <p className={styles['error']}>{t(keyFailure === 'keyBlank' ? 'keyBlankNew' : keyFailure)}</p>}\n </div>\n <ModelListEditor\n models={models}\n onChange={setModels}\n probe={{\n settingsNs: NS,\n baseURL,\n api: protocol,\n ...keyValue.length === 0 ? {} : { apiKey: keyValue },\n }}\n probeBlocked={keyFailure === 'keyBlank' ? 'keyBlankNew' : keyFailure}\n operations={operations}\n t={t}\n disabled={profileDisabled}\n />\n {failure !== undefined ? <p className={styles['error']}>{failure}</p> : null}\n {/* Only the gates with something to say render; the route-id gate has its\n own field-level hint, so its blocked state would print an empty line. */}\n {hint === undefined ? null : <p className={styles['advancedHint']}>{hint}</p>}\n <EditorFooter\n t={t}\n busy={busy}\n submitDisabled={disabled || !ready}\n submitLabelKey=\"create\"\n submitBusyLabelKey=\"creating\"\n onCancel={() => { props.onClose(committed) }}\n onSubmit={() => { void create() }}\n />\n </div>\n )\n}\n","/**\n * One provider's editor card, hand-written per adapter family: the primary\n * field is a single write-only **API key** input (the page never asks for an\n * environment-variable name — a typed key stores through `credentials/set`\n * under the profile's reference, deriving `<ROUTE>_API_KEY` when the profile\n * has none. The pi-ai profile records that derivation as `apiKeyEnv` only when\n * a key is entered; a blank key materializes a reference-free profile for\n * provider-native authentication);\n * the collapsed 自定义设置 area carries the per-family extras (`baseURL` for\n * both families, DeepSeek's id/name/context-window model catalog, and the\n * display name and wire protocol of a pi-ai route the adapter does not ship —\n * the two fields the create card asked that route for, editable here for the\n * same reason).\n * Reasoning effort is deliberately absent: it is a per-MODEL capability, and\n * the models under one provider disagree about it, so a provider-scoped\n * control can only be set to a value some of them reject. The composer's\n * model picker offers each model its own levels; `settings.yaml` keeps the\n * profile field for a deployment that knows its route. Everything else stays\n * owned by `settings.yaml`. Profile edits land as minimal `settings.mutate`\n * path ops against the stored section — the card names only the fields it can\n * see instead of rebuilding the whole subtree from a partial descriptor.\n */\n\nimport { useEffect, useMemo, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport type {\n CredentialInfo, SettingsNamespaceView, SettingsPathOpView,\n} from '@deepseek-ai/dsh-api-remotes/client'\nimport type { JsonValue } from '@deepseek-ai/dsh-util-values'\nimport {\n DeepSeekModelsEditor, modelDrafts, validateDeepSeekModels,\n} from './DeepSeekModelsEditor.tsx'\nimport { apiKeyFailure } from './apiKey.ts'\nimport { EditorFooter } from './EditorFooter.tsx'\nimport { ModelListEditor } from './ModelListEditor.tsx'\nimport { deriveKeyRef, protocolChoices } from './store.ts'\nimport type { ModelsOperations } from './operations.ts'\nimport type { SettingsSchemaOperations } from './schema-operations.ts'\nimport type { en } from './locales.ts'\nimport styles from './ModelsSection.module.css'\n\n/** Per-adapter-family curated field sets (unknown namespaces get the hint alone). */\ntype EditorLayout = 'deepseek' | 'pi-ai' | 'unknown'\n\n/** The public DeepSeek endpoint shown as the deepseek base-URL placeholder. */\nconst DEEPSEEK_PUBLIC_BASE_URL = 'https://api.deepseek.com'\n\n/** Props of {@link ProviderEditor}. */\nexport interface ProviderEditorProps {\n /** Provider route id. */\n provider: string\n /** Display name for the card title. */\n displayName: string\n /** Hide the title row (the add card renders its own provider select). */\n hideTitle?: boolean\n /**\n * Whether the adapter reports this route as hand-declared — absent from its\n * installed catalog. Such a route carries its own wire protocol, chosen when\n * it was created and editable here for the same reason; a catalog route's\n * models each carry theirs, so a route-level protocol there could only\n * override every one of them and the card does not offer it.\n */\n declared?: boolean\n /** The owning namespace view (schema, layers, secrets). */\n namespace: SettingsNamespaceView\n /** Settings-owned synchronous schema and immutable path operations. */\n schema: SettingsSchemaOperations\n /** Path from the section root to this provider's profile. */\n settingsPath: readonly string[]\n /** The Host operations this card writes and interrogates through. */\n operations: ModelsOperations\n /** Section copy. */\n t: (key: keyof typeof en) => string\n /** Disable writes (read-only settings provider). */\n readOnly: boolean\n /** Render only the credential field and actions, without provider settings. */\n credentialOnly?: boolean\n /** Require a newly entered credential before this editor can submit. */\n credentialRequired?: boolean\n /** Give the credential field initial focus when this editor mounts. */\n autoFocusCredential?: boolean\n /** Override the dismiss action copy. */\n cancelLabelKey?: keyof typeof en\n /** Override the idle commit action copy. */\n submitLabelKey?: keyof typeof en\n /** Override the in-flight commit action copy. */\n submitBusyLabelKey?: keyof typeof en\n /** Close the editor; `changed` reports whether an Apply committed. */\n onClose: (changed: boolean) => void\n}\n\n/** A user-section subtree as a plain draft object (absent → empty). */\nfunction draftAt(\n schema: SettingsSchemaOperations,\n namespace: SettingsNamespaceView,\n path: readonly string[],\n): Record<string, unknown> {\n const subtree = schema.getPath(namespace.user, path)\n if (typeof subtree !== 'object' || subtree === null || Array.isArray(subtree)) return {}\n return structuredClone(subtree) as Record<string, unknown>\n}\n\n/**\n * The minimal path ops carrying `after` over `before`, both as the card sees\n * them. Only keys the card observed are named; fields absent from both sides\n * produce no op, which is why edits are path-addressed rather than a rebuilt\n * section.\n * @param base - path of the edited subtree inside the user section.\n * @param before - the subtree as loaded, or undefined when it is new.\n * @param after - the subtree as edited.\n * @returns ordered set/unset ops; empty when nothing changed.\n */\nexport function pathOps(\n base: readonly string[],\n before: unknown,\n after: Record<string, unknown>,\n): SettingsPathOpView[] {\n const previous = typeof before === 'object' && before !== null && !Array.isArray(before)\n ? before as Record<string, unknown>\n : {}\n const ops: SettingsPathOpView[] = []\n for (const [key, value] of Object.entries(after)) {\n if (JSON.stringify(previous[key]) === JSON.stringify(value)) continue\n ops.push({ op: 'set', path: [...base, key], value: value as JsonValue })\n }\n for (const key of Object.keys(previous)) {\n if (!(key in after)) ops.push({ op: 'unset', path: [...base, key] })\n }\n return ops\n}\n\n/** The editor layout the owning namespace selects. */\nfunction layoutOf(ns: string): EditorLayout {\n if (ns === 'llm-deepseek') return 'deepseek'\n if (ns === 'llm-pi-ai') return 'pi-ai'\n return 'unknown'\n}\n\n/** The credential reference this profile resolves keys through. */\nfunction refFor(\n schema: SettingsSchemaOperations,\n namespace: SettingsNamespaceView,\n path: readonly string[],\n provider: string,\n): string {\n const profile = schema.getPath(namespace.value, path)\n const named = typeof profile === 'object' && profile !== null\n ? (profile as { apiKeyEnv?: unknown }).apiKeyEnv\n : undefined\n return typeof named === 'string' && named.length > 0 ? named : deriveKeyRef(provider)\n}\n\n/**\n * Render one provider's editing card.\n * @param props - the addressed profile plus wire faces and copy.\n * @returns the editor card.\n */\nexport function ProviderEditor(props: ProviderEditorProps): ReactNode {\n const { namespace, schema, settingsPath, operations, t } = props\n const [draft, setDraft] = useState<Record<string, unknown>>(() => draftAt(schema, namespace, settingsPath))\n const [keyDraft, setKeyDraft] = useState('')\n const [keyState, setKeyState] = useState<CredentialInfo | undefined>(undefined)\n const [busy, setBusy] = useState(false)\n const [failure, setFailure] = useState<string | undefined>(undefined)\n // A settings success advances both retry baselines immediately. Keeping the\n // derived fields in the draft prevents a pushed namespace refresh from\n // turning them into deletions when the following credential write is retried.\n const [committedOriginal, setCommittedOriginal] = useState<unknown>(\n () => schema.getPath(namespace.user, settingsPath),\n )\n const [expectedRevision, setExpectedRevision] = useState(() => namespace.revision)\n const root = useMemo(() => schema.rehydrate(namespace.schema), [namespace.schema, schema])\n const node = useMemo(() => schema.nodeAtPath(root, settingsPath), [root, schema, settingsPath])\n const fallback = schema.getPath(namespace.value, settingsPath)\n const disabled = props.readOnly || busy\n const layout = layoutOf(namespace.ns)\n const keyRef = refFor(schema, namespace, settingsPath, props.provider)\n // The same schema read the create card makes, so the choices offered here\n // and there cannot drift apart: both come from the adapter's own `Config`.\n // Only the pi-ai layout has a per-route protocol for the read to find, and\n // it rehydrates the whole section schema, so the other layouts skip it.\n const protocols = useMemo(\n () => layout === 'pi-ai' ? protocolChoices(namespace, schema) : [],\n [layout, namespace, schema],\n )\n\n useEffect(() => {\n let stale = false\n setKeyState(undefined)\n // The key state is a placeholder hint, not a precondition for editing: a\n // refused describe leaves the card without the \"already configured\" hint.\n void operations.describeCredential(keyRef).then((described) => {\n if (stale) return\n setKeyState(described)\n })\n return () => { stale = true }\n }, [operations, keyRef])\n\n const stringAt = (source: unknown, key: string): string | undefined => {\n const value = schema.getPath(source, [key])\n return typeof value === 'string' && value.trim().length > 0 ? value : undefined\n }\n const setField = (key: string, next: string | undefined): void => {\n // A value of nothing but whitespace is cleared, not stored: `stringAt`\n // already reports it as absent, so the field would otherwise render empty\n // while the draft still carried the spaces into `settings.yaml`, where\n // both adapters would accept that non-empty string as a real value.\n const value = next === undefined || next.trim().length === 0 ? undefined : next\n setDraft(current => value === undefined\n ? schema.deletePath(current, [key])\n : schema.setPath(current, [key], value))\n }\n\n // The model list is validated by the same per-row checker for both families,\n // so a bad row is named by its position rather than by a blanket message.\n const modelFailure = validateDeepSeekModels(schema.getPath(draft, ['models']))\n const keyFailure = apiKeyFailure(keyDraft)\n // What a probe or a write must carry: the typed key with paste whitespace\n // removed. A blank field yields an empty string, which both call sites read\n // as \"no key supplied\" rather than as a key — that is how a card whose\n // provider already has a stored key is edited without re-entering it.\n const keyValue = keyDraft.trim()\n const credentialRequiredFailure = props.credentialRequired === true\n && keyDraft.length > 0 && keyValue.length === 0\n ? 'keyRequired' as const\n : undefined\n const shownKeyFailure = credentialRequiredFailure ?? keyFailure\n // What the form currently shows, which is what an interrogation must ask:\n // an edited-but-unsaved endpoint, and a key typed but not yet stored.\n const probeApi = stringAt(draft, 'api') ?? stringAt(fallback, 'api')\n const probeBaseURL = stringAt(draft, 'baseURL') ?? stringAt(fallback, 'baseURL')\n const probe = {\n settingsNs: namespace.ns,\n // Naming the route lets an adapter that already describes it answer from\n // its own registry — better metadata, no network call, no endpoint needed.\n provider: props.provider,\n ...probeBaseURL === undefined ? {} : { baseURL: probeBaseURL },\n ...probeApi === undefined ? {} : { api: probeApi },\n ...keyValue.length === 0 ? {} : { apiKey: keyValue },\n }\n /**\n * The write for this card, or a failure message. Every edit travels as\n * path ops against the STORED section: the draft comes from the redacted\n * descriptor, so a wholesale replace rebuilt from it could delete fields\n * outside the card. Ops name only the fields this card can see.\n */\n const applyOnce = async (): Promise<string | undefined> => {\n const ns = namespace.ns\n // A pi-ai profile names the conventional reference only when this page is\n // about to store a key. Otherwise the provider keeps its native auth path.\n const next = layout === 'pi-ai' && stringAt(draft, 'apiKeyEnv') === undefined\n && stringAt(fallback, 'apiKeyEnv') === undefined && keyValue.length > 0\n ? schema.setPath(draft, ['apiKeyEnv'], keyRef)\n : draft\n if (props.credentialOnly !== true) {\n // The same checker gates the submit button, so a card cannot reach this\n // with a bad row; it stays because the schema check below would refuse\n // the write with a message naming a path instead of the row, and because\n // nothing but this function decides what is written.\n const failure = validateDeepSeekModels(schema.getPath(next, ['models']))\n /* v8 ignore next 3 -- unreachable from the card: the same failure disables submit */\n if (failure !== undefined) {\n return `${t('model')} ${String(failure.index + 1)}: ${t(failure.key)}`\n }\n }\n /* v8 ignore next -- apply is only reachable from the rendered card, which required a resolved node */\n if (props.credentialOnly !== true && node !== undefined && settingsPath.length === 0) {\n const sectionError = schema.validate(node, next)\n if (sectionError !== undefined) return sectionError\n }\n const materializesNativeProfile = layout === 'pi-ai'\n && fallback === undefined\n && committedOriginal === undefined\n && Object.keys(next).length === 0\n const ops: SettingsPathOpView[] = props.credentialOnly === true\n ? []\n : materializesNativeProfile\n ? [{ op: 'set', path: [...settingsPath], value: {} }]\n : pathOps(settingsPath, committedOriginal, next)\n if (ops.length > 0) {\n const written = await operations.writeSettings(ns, ops, expectedRevision)\n if (written.kind !== 'written') return written.kind === 'conflict' ? t('conflict') : written.message\n setCommittedOriginal(schema.getPath(written.view.user, settingsPath))\n setExpectedRevision(written.view.revision)\n setDraft(next)\n }\n if (keyValue.length > 0) {\n const stored = await operations.storeCredential(keyRef, keyValue)\n if (stored !== undefined) return stored\n }\n setKeyDraft('')\n return undefined\n }\n\n const apply = async (): Promise<void> => {\n setBusy(true)\n setFailure(undefined)\n try {\n const failure = await applyOnce()\n if (failure !== undefined) {\n setFailure(failure)\n return\n }\n props.onClose(true)\n } finally {\n setBusy(false)\n }\n }\n\n if (node === undefined) {\n // A directory entry addressing a position its schema cannot resolve is a\n // host-side inconsistency; showing it beats a blank card.\n return <p className={styles['error']}>{props.provider}: {props.t('settingsPathUnresolvable')}</p>\n }\n\n const keyLocked = keyState?.writable === false\n\n /**\n * The catalog beneath the user layer: what the composition entry pinned, or\n * else the schema default that `resolve` would supply. The effective value\n * cannot answer this — it still carries the stored override until the unset\n * is applied, so reading it would echo that override straight back the\n * moment reset drops it, leaving the rows unchanged until a reload.\n */\n const inheritedModels = (): unknown => {\n const pinned = schema.getPath(namespace.base, [...settingsPath, 'models'])\n return pinned ?? schema.nodeAtPath(root, [...settingsPath, 'models'])?.meta.default\n }\n\n /**\n * The curated fields of one known adapter family. The family arrives\n * narrowed so the per-family branches below are total: an unknown namespace\n * renders the hint instead and never reaches this body.\n */\n const curatedFields = (family: 'deepseek' | 'pi-ai'): ReactNode => {\n // What a hand-declared route names for itself and nothing else can supply.\n // A whole-section `llm-deepseek` profile is a composition fact with no\n // per-route identity for its schema to carry, hence the family test.\n const ownsIdentity = family === 'pi-ai' && props.declared === true\n const customModels = schema.getPath(draft, ['models'])\n const modelsOverridden = schema.hasPath(draft, ['models'])\n const models = modelDrafts(modelsOverridden ? customModels : inheritedModels())\n const defaultContextWindow = schema.getPath(fallback, ['defaultContextWindow'])\n const defaultMaxTokens = schema.getPath(fallback, ['maxTokens'])\n const keyPlaceholder = keyLocked\n ? t('keyEnvLocked')\n : keyState?.configured === true && props.credentialRequired !== true\n ? t('keyStored')\n : family === 'pi-ai' ? t('keyPlaceholderNative') : t('keyPlaceholder')\n /** What both family editors take: the rows, whose layer owns them, and the two writes. */\n const catalogProps = {\n models,\n overridden: modelsOverridden,\n t,\n disabled,\n onChange: (next: Record<string, unknown>[]) => {\n setDraft(current => schema.setPath(current, ['models'], next))\n },\n onReset: () => { setDraft(current => schema.deletePath(current, ['models'])) },\n }\n return (\n <>\n <div className={styles['field']}>\n <span className={styles['fieldLabel']}>{t('keyInput')}</span>\n <input\n className={styles['input']}\n type=\"password\"\n autoComplete=\"off\"\n value={keyDraft}\n placeholder={keyPlaceholder}\n aria-label={t('keyInput')}\n aria-invalid={shownKeyFailure !== undefined}\n required={props.credentialRequired === true}\n autoFocus={props.autoFocusCredential === true}\n disabled={disabled || keyLocked}\n onChange={(event) => { setKeyDraft(event.target.value) }}\n />\n {shownKeyFailure === undefined ? null : <p className={styles['error']}>{t(shownKeyFailure)}</p>}\n </div>\n {props.credentialOnly === true ? null : <details className={styles['customized']}>\n <summary className={styles['customizedSummary']}>{t('customized')}</summary>\n <div className={styles['customizedBody']}>\n {/* The name and the protocol are the create card's two remaining\n profile fields; a route the adapter ships defaults both from\n its catalog entry and neither belongs on its card. */}\n {ownsIdentity\n ? (\n <div className={styles['field']}>\n <span className={styles['fieldLabel']}>{t('customDisplayName')}</span>\n <input\n className={styles['input']}\n type=\"text\"\n value={stringAt(draft, 'displayName') ?? ''}\n // What this route is called the moment the field is\n // cleared, which is the layer beneath the one this field\n // edits: a `cordis.yml` may pin a name for a route the\n // catalog does not ship, and only when nothing does is\n // the answer the route id. Reading the effective value\n // instead would echo the stored override back as the\n // thing clearing restores.\n placeholder={stringAt(schema.getPath(namespace.base, settingsPath), 'displayName')\n ?? props.provider}\n aria-label={t('customDisplayName')}\n disabled={disabled}\n onChange={(event) => { setField('displayName', event.target.value) }}\n />\n </div>\n )\n : null}\n <div className={styles['field']}>\n <span className={styles['fieldLabel']}>{t('baseUrl')}</span>\n <input\n className={styles['input']}\n type=\"text\"\n value={stringAt(draft, 'baseURL') ?? ''}\n placeholder={family === 'deepseek'\n ? DEEPSEEK_PUBLIC_BASE_URL\n : stringAt(fallback, 'baseURL') ?? t('baseUrlDefault')}\n aria-label={t('baseUrl')}\n disabled={disabled}\n onChange={(event) => {\n setField('baseURL', event.target.value === '' ? undefined : event.target.value)\n }}\n />\n </div>\n {/* The protocol sits beside the endpoint it describes, as it does\n on the create card. */}\n {ownsIdentity\n ? (\n <div className={styles['field']}>\n <span className={styles['fieldLabel']}>{t('customApi')}</span>\n <select\n className={`${styles['input']} ${styles['selectInput']}`}\n value={probeApi ?? ''}\n aria-label={t('customApi')}\n disabled={disabled}\n onChange={(event) => { setField('api', event.target.value) }}\n >\n {/* A profile naming no protocol — hand-written into\n settings.yaml with no model to need one — selects\n nothing rather than reading as if it had picked the\n first choice. The option is named because a screen\n reader announces it either way, and an empty one is\n announced as a choice with no identity. */}\n {probeApi === undefined ? <option value=\"\">{t('customApiUnset')}</option> : null}\n {protocols.map(choice => <option key={choice} value={choice}>{choice}</option>)}\n </select>\n </div>\n )\n : null}\n {/* Both families edit the same rows through the same contract; only\n the extras differ — DeepSeek's inherited capacities, pi-ai's\n endpoint interrogation. */}\n {family === 'deepseek'\n ? (\n <DeepSeekModelsEditor\n {...catalogProps}\n defaultContextWindow={typeof defaultContextWindow === 'number'\n ? defaultContextWindow\n : undefined}\n defaultMaxTokens={typeof defaultMaxTokens === 'number' ? defaultMaxTokens : undefined}\n />\n )\n : (\n <ModelListEditor\n {...catalogProps}\n probe={probe}\n probeBlocked={keyFailure}\n operations={operations}\n />\n )}\n </div>\n </details>}\n </>\n )\n }\n\n return (\n <div className={props.credentialOnly === true ? styles['addBlock'] : styles['editor']}>\n {props.hideTitle === true\n ? null\n : (\n <div className={styles['editorHeader']}>\n <span className={styles['editorTitle']}>{props.displayName}</span>\n {props.provider !== props.displayName\n ? <span className={styles['editorRoute']}>{props.provider}</span>\n : null}\n </div>\n )}\n {layout === 'unknown'\n ? <p className={styles['advancedHint']}>{`${t('advancedHint')} (${namespace.ns})`}</p>\n : curatedFields(layout)}\n {failure !== undefined ? <p className={styles['error']}>{failure}</p> : null}\n {props.credentialOnly === true || modelFailure === undefined\n ? null\n : (\n <p className={styles['advancedHint']}>\n {`${t('model')} ${String(modelFailure.index + 1)}: ${t(modelFailure.key)}`}\n </p>\n )}\n <EditorFooter\n t={t}\n busy={busy}\n submitDisabled={disabled || layout === 'unknown'\n || (props.credentialOnly !== true && modelFailure !== undefined)\n || shownKeyFailure !== undefined\n || (props.credentialRequired === true && keyValue.length === 0)}\n submitLabelKey={props.submitLabelKey ?? 'apply'}\n submitBusyLabelKey={props.submitBusyLabelKey ?? 'applying'}\n {...props.cancelLabelKey === undefined ? {} : { cancelLabelKey: props.cancelLabelKey }}\n onCancel={() => { props.onClose(false) }}\n onSubmit={() => { void apply() }}\n />\n </div>\n )\n}\n","/**\n * Models settings section (EXT fork for dsh-model-extension).\n *\n * Forked from deepseek-harness packages/client/ui-settings-models\n * src/client/ModelsSection.tsx @ 0.1.2-alpha.4.\n * Differences vs upstream (keep this list exhaustive when merging drift):\n * 1. The h2 title row carries an adapter-version badge.\n * 2. No child-slot machinery: this is a standalone section (id\n * 'models-extension'), and the 'settings.models.provider-card' /\n * 'settings.models.footer' children are already declared globally by the\n * official Models section — redeclaring them throws, so every renderSlot\n * call (and the addRow/keyConfiguredOf helpers serving only the seat) is\n * removed. Third-party provider-card/footer extensions therefore render on\n * the official Models page only; that is an accepted trade-off of the fork.\n * 3. Styles come from the plugin's own ModelsSection.ext.module.css.\n * Everything else is upstream verbatim — keep this file minimal when merging\n * drift after a host upgrade.\n *\n * Models settings section: the provider rows joined from the configurable\n * directory, settings namespaces, and credential states, with one editor\n * card at a time. Rows expose only confirmed API-key state through accessible\n * solid configured or missing dots. A whole-section provider without a\n * configured key renders as its open setup card instead of a row, but only in\n * the first-run posture — no provider on the page can serve requests yet — and\n * only until the user closes that card; the add flow is a card carrying the\n * dormant-provider select. Each card kind owns its own open state, so closing\n * one never discards a draft in another. Every mutation writes through the\n * wire, while a provider removal first requires confirmation; the page\n * re-renders from pushed invalidations or the post-apply reload.\n */\n\nimport { useState } from 'react'\nimport type { ReactNode } from 'react'\nimport { Button, IconPlusOutline16, Modal } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { InjectFace } from '@deepseek-ai/dsh-client-ui-slots'\nimport { CustomProviderCard } from './CustomProviderCard.tsx'\nimport { deriveKeyRef, protocolChoices, providerUsable } from './store.ts'\nimport type { ModelsSettingsStore, ProviderRow } from './store.ts'\nimport type { ModelsOperations } from './operations.ts'\nimport type { SettingsSchemaOperations } from './schema-operations.ts'\nimport { ProviderEditor, type ProviderEditorProps } from './ProviderEditor.tsx'\nimport type { en } from './locales.ts'\nimport { ADAPTER_VERSION } from './extension-meta.ts'\nimport styles from './ModelsSection.ext.module.css'\n\n/** Injected dependencies of {@link ModelsSection} (slot `inject`). */\nexport interface ModelsSectionInjected {\n /** The page store (loaded on mount, refreshed on pushed invalidations). */\n controller: ModelsSettingsStore\n hooks: {\n /** Page snapshot bound by the UI renderer as useSnapshot. */\n snapshot: ModelsSettingsStore['store']\n }\n /** The Host operations the section and its cards invoke. */\n operations: ModelsOperations\n /** Settings schema and immutable path callbacks. */\n schema: SettingsSchemaOperations\n /** Section copy. */\n t: (key: keyof typeof en) => string\n}\n\n/**\n * Props delivered by the slot outlet: the inject face spread flat (the\n * renderer erases the share boundary at the render call). EXT: no child-slot\n * dispatch seat — see the header note.\n */\nexport type ModelsSectionProps = Partial<InjectFace<ModelsSectionInjected>>\n\ntype ModelsSectionFace = InjectFace<ModelsSectionInjected>\n\n/** Provider identity shared by row actions and confirmation copy. */\nexport interface ProviderIdentity {\n /** Stable provider route id. */\n provider: string\n /** Human-facing provider name. */\n displayName: string\n}\n\n/** One existing row or dormant directory entry addressed by an editor action. */\ninterface EditorTarget extends ProviderIdentity {\n settingsNs: string\n settingsPath: readonly string[]\n /** Writable credential identified under this page's conventional reference. */\n credentialRef?: string\n /** The adapter reports this route as one it does not ship (see {@link ProviderEditorProps.declared}). */\n declared?: boolean\n}\n\n/** Values that vary around the shared provider-editor rendering. */\ninterface ProviderEditorRenderProps extends Pick<\n ProviderEditorProps,\n 'namespace' | 'schema' | 'operations' | 't' | 'readOnly' | 'onClose'\n> {\n target: EditorTarget\n}\n\n/** Render an editor for either the setup posture or an expanded provider row. */\nfunction renderProviderEditor({ target, ...props }: ProviderEditorRenderProps): ReactNode {\n return (\n <ProviderEditor\n provider={target.provider}\n displayName={target.displayName}\n settingsPath={target.settingsPath}\n {...target.declared === true ? { declared: true } : {}}\n {...props}\n />\n )\n}\n\n/**\n * Remove one user-added provider and its page-managed credential. Credential\n * removal comes first so a second-step failure leaves the provider row visible\n * and the whole operation safely retryable; both unsets are idempotent.\n * The settings removal names the profile rather than rebuilding its whole\n * namespace from a partial view.\n * @param operations - the page's Host operations.\n * @param controller - the page store to refresh.\n * @param target - the provider's settings address and optional managed credential.\n * @returns the failure message, or undefined once the write and reload landed.\n */\nexport async function removeProviderProfile(\n operations: ModelsOperations,\n controller: ModelsSettingsStore,\n target: { settingsNs: string; settingsPath: readonly string[]; credentialRef?: string },\n): Promise<string | undefined> {\n if (target.credentialRef !== undefined) {\n const credential = await operations.removeCredential(target.credentialRef)\n if (credential !== undefined) return credential\n }\n const written = await operations.writeSettings(\n target.settingsNs,\n [{ op: 'unset', path: [...target.settingsPath] }],\n undefined,\n )\n if (written.kind !== 'written') return written.message\n await controller.load()\n return undefined\n}\n\n/**\n * Whether a whole-section provider still needs its first key: an unconfigured\n * credential opens the setup card instead of showing a row. This is the\n * first-run posture alone — a user who can already reach some provider gets an\n * ordinary row with the missing-key dot, since nothing here is blocking them.\n * @param row - the joined provider row.\n * @param anyUsable - whether any joined row can already serve requests.\n * @returns whether to render the setup card.\n */\nexport function needsSetup(row: ProviderRow, anyUsable: boolean): boolean {\n if (anyUsable) return false\n if (row.entry.settingsPath.length > 0) return false\n return row.credential?.configured !== true\n}\n\nfunction targetOf(row: ProviderRow): EditorTarget {\n const managedRef = deriveKeyRef(row.entry.provider)\n const credentialRef = row.apiKeyEnv === managedRef\n && row.credential?.configured === true\n && row.credential.writable\n ? managedRef\n : undefined\n return {\n provider: row.entry.provider,\n displayName: row.entry.displayName,\n settingsNs: row.entry.settingsNs,\n settingsPath: row.entry.settingsPath,\n ...credentialRef === undefined ? {} : { credentialRef },\n // Only declared routes may expose route-owned fields.\n ...row.entry.declared === true ? { declared: true } : {},\n }\n}\n\n/** Stable visible and accessible identity for one provider target. */\nexport function providerTargetLabel(target: ProviderIdentity): string {\n return target.provider === target.displayName\n ? target.provider\n : `${target.displayName} (${target.provider})`\n}\n\n/** Replace the one provider placeholder in localized destructive-action copy. */\nexport function providerCopy(template: string, target: ProviderIdentity): string {\n return template.replace('{provider}', () => providerTargetLabel(target))\n}\n\n/**\n * Render the Models section content column.\n * @param props - slot-delivered injected dependencies.\n * @returns the section, or null while the shell has not injected yet.\n */\nexport function ModelsSection(props: ModelsSectionProps): ReactNode {\n const { controller, useSnapshot, operations, schema, t } = props\n if (\n controller === undefined || useSnapshot === undefined || operations === undefined\n || schema === undefined || t === undefined\n ) return null\n return <Loaded injected={{ controller, useSnapshot, operations, schema, t }} />\n}\n\nfunction Loaded({ injected }: { injected: ModelsSectionFace }): ReactNode {\n const { controller, operations, schema, t } = injected\n const state = injected.useSnapshot(snapshot => snapshot)\n const [editing, setEditing] = useState<EditorTarget | undefined>(undefined)\n const [adding, setAdding] = useState(false)\n const [deleteTarget, setDeleteTarget] = useState<EditorTarget | undefined>(undefined)\n const [deleting, setDeleting] = useState(false)\n const [deleteFailure, setDeleteFailure] = useState<string | undefined>(undefined)\n const [savedTarget, setSavedTarget] = useState<ProviderIdentity | undefined>(undefined)\n const [declaring, setDeclaring] = useState(false)\n const [dismissedSetup, setDismissedSetup] = useState<ReadonlySet<string>>(() => new Set())\n\n const announceSaved = (target: ProviderIdentity): void => {\n // Announced only once the refreshed directory is in the snapshot the\n // notice reads its name from: an apply can rename the route, and the\n // target captured when the card opened still carries the old name.\n void controller.load().then(() => { setSavedTarget(target) })\n }\n\n const closeEditor = (changed: boolean, target: ProviderIdentity): void => {\n setEditing(undefined)\n setAdding(false)\n setDeclaring(false)\n if (changed) announceSaved(target)\n }\n\n /**\n * Close a setup card, which owns none of the state above: the row-editor,\n * add, and declare cards each own one of those, so clearing them here would\n * discard a draft the user opened beside this card. Dismissal is this card's\n * own — the provider falls back to an ordinary row for the rest of the\n * session, and reopens through Edit.\n */\n const closeSetup = (changed: boolean, target: ProviderIdentity): void => {\n setDismissedSetup(previous => new Set([...previous, target.provider]))\n if (changed) announceSaved(target)\n }\n\n const closeDelete = (): void => {\n if (deleting) return\n setDeleteTarget(undefined)\n setDeleteFailure(undefined)\n }\n\n const confirmDelete = (): void => {\n /* v8 ignore next -- the action only renders with a target and is disabled while a deletion is pending */\n if (deleteTarget === undefined || deleting) return\n setDeleting(true)\n setDeleteFailure(undefined)\n void removeProviderProfile(operations, controller, deleteTarget)\n .then((failure) => {\n if (failure !== undefined) {\n setDeleteFailure(failure)\n return\n }\n setDeleteTarget(undefined)\n })\n .finally(() => { setDeleting(false) })\n }\n\n if (state.status === 'idle') void controller.load()\n if (state.status === 'error') {\n /* v8 ignore next -- an error status always carries text; the fallback satisfies the nullable type */\n const errorText = state.error ?? ''\n return (\n <div className={styles['section']}>\n <p className={styles['error']}>{`${t('loadFailed')}: ${errorText}`}</p>\n <button type=\"button\" className={styles['secondaryButton']} onClick={() => { void controller.load() }}>\n {t('retry')}\n </button>\n </div>\n )\n }\n\n // The saved provider as the directory currently names it. The route id is\n // what the apply cannot change, so it is what the notice is keyed by; a row\n // the same apply removed keeps the captured identity, since nothing newer\n // exists to name it with.\n const savedRow = savedTarget === undefined\n ? undefined\n : state.rows.find(row => row.entry.provider === savedTarget.provider)\n const savedIdentity = savedRow === undefined\n ? savedTarget\n : { provider: savedRow.entry.provider, displayName: savedRow.entry.displayName }\n\n // One fact decides both first-run postures on this page and the onboarding\n // step: whether the user already has a provider to talk to.\n const anyUsable = state.rows.some(providerUsable)\n const configured = state.rows.filter(row => row.configured)\n const addable = state.rows.filter(row => !row.configured && row.entry.settingsNs !== '')\n const addTarget = adding ? editing : undefined\n const addNamespace = addTarget === undefined ? undefined : state.namespaces.get(addTarget.settingsNs)\n // Hand-declared routes live in the pi-ai namespace, which is also the only\n // one whose schema names the protocols one may speak; without it mounted\n // there is nothing to declare and the entry point stays disabled.\n const protocols = protocolChoices(state.namespaces.get('llm-pi-ai'), schema)\n\n return (\n <div className={styles['section']}>\n <h2 className={styles['title']}>\n {t('title')}\n {/* EXT-only: adapter anchor badge (upstream has no counterpart). */}\n <span className={styles['intro']}>{` — ${t('adapterVersion').replace('{version}', ADAPTER_VERSION)}`}</span>\n </h2>\n <p className={styles['intro']}>{t('intro')}</p>\n {!state.writable && state.status === 'ready' ? <p className={styles['notice']}>{t('readOnly')}</p> : null}\n {savedIdentity === undefined\n ? null\n : (\n <p className={styles['savedNotice']} role=\"status\" aria-live=\"polite\">\n {providerCopy(t('savedProvider'), savedIdentity)}\n </p>\n )}\n <ul className={styles['rows']}>\n {configured.map((row) => {\n const target = targetOf(row)\n const namespace = state.namespaces.get(target.settingsNs)\n /* v8 ignore next -- the join marks a row configured only when its namespace resolved */\n if (namespace === undefined) return null\n if (needsSetup(row, anyUsable) && !dismissedSetup.has(row.entry.provider)) {\n // First-run posture: the provider exists but has no key — the\n // setup card IS its presence on the page, until the user closes it.\n return (\n <li key={row.entry.provider} className={styles['setupCard']}>\n {renderProviderEditor({\n target,\n namespace,\n schema,\n operations,\n t,\n readOnly: !state.writable,\n onClose: (changed) => { closeSetup(changed, target) },\n })}\n </li>\n )\n }\n const open = !adding && editing?.provider === row.entry.provider\n const credentialConfigured = row.credential?.configured === true\n const credentialMissing = !credentialConfigured\n && row.apiKeyEnv !== undefined\n && row.credential?.configured === false\n return (\n <li key={row.entry.provider} className={styles['rowCard']}>\n <div className={styles['rowHead']}>\n <span className={styles['rowIdentity']}>\n <span className={styles['rowName']}>{row.entry.displayName}</span>\n {/* Only the adapter can tell a hand-declared route from a\n shipped one it also has a stored profile for, so the tag\n follows its answer and stays off when it gives none. */}\n {row.entry.declared === true\n ? <span className={styles['rowTag']}>{t('customTag')}</span>\n : null}\n {credentialConfigured\n ? (\n <span\n className={`${styles['credentialDot']} ${styles['credentialDotConfigured']}`}\n role=\"img\"\n aria-label={t('credentialConfigured')}\n title={t('credentialConfigured')}\n />\n )\n : credentialMissing\n ? (\n <span\n className={`${styles['credentialDot']} ${styles['credentialDotMissing']}`}\n role=\"img\"\n aria-label={t('credentialMissing')}\n title={t('credentialMissing')}\n />\n )\n : null}\n </span>\n <span className={styles['rowActions']}>\n <button\n type=\"button\"\n className={styles['secondaryButton']}\n aria-label={providerCopy(t('editProvider'), target)}\n onClick={() => {\n setSavedTarget(undefined)\n // One card at a time: leaving `declaring` set would show\n // the create card beside this editor, and closing either\n // one discards the other's draft.\n setDeclaring(false)\n setAdding(false)\n setEditing(open ? undefined : target)\n }}\n >\n {t('edit')}\n </button>\n {row.removable\n ? (\n <button\n type=\"button\"\n className={styles['dangerButton']}\n aria-label={providerCopy(t('removeProvider'), target)}\n disabled={!state.writable}\n onClick={() => {\n setSavedTarget(undefined)\n setDeleteFailure(undefined)\n setDeleteTarget(target)\n }}\n >\n {t('remove')}\n </button>\n )\n : null}\n </span>\n </div>\n {open\n ? renderProviderEditor({\n target,\n namespace,\n schema,\n operations,\n t,\n readOnly: !state.writable,\n onClose: (changed) => { closeEditor(changed, target) },\n })\n : null}\n </li>\n )\n })}\n </ul>\n <div className={styles['addBlock']}>\n {addTarget !== undefined && addNamespace !== undefined\n ? (\n <div className={styles['addCard']}>\n <div className={styles['field']}>\n <span className={styles['fieldLabel']}>{t('provider')}</span>\n <select\n className={`${styles['input']} ${styles['selectInput']}`}\n value={addTarget.provider}\n aria-label={t('provider')}\n onChange={(event) => {\n const row = addable.find(candidate => candidate.entry.provider === event.target.value)\n /* v8 ignore next -- the select only lists addable rows */\n if (row === undefined) return\n setEditing(targetOf(row))\n }}\n >\n {addable.map(row => (\n <option key={row.entry.provider} value={row.entry.provider}>{row.entry.displayName}</option>\n ))}\n </select>\n </div>\n <ProviderEditor\n key={addTarget.provider}\n provider={addTarget.provider}\n displayName={addTarget.displayName}\n hideTitle\n namespace={addNamespace}\n schema={schema}\n settingsPath={addTarget.settingsPath}\n operations={operations}\n t={t}\n readOnly={!state.writable}\n onClose={(changed) => { closeEditor(changed, addTarget) }}\n />\n </div>\n )\n : declaring\n ? (\n <div className={styles['addCard']}>\n <CustomProviderCard\n taken={state.rows.map(row => row.entry.provider)}\n protocols={protocols}\n /* v8 ignore next -- the card only opens from a button disabled without this namespace */\n revision={state.namespaces.get('llm-pi-ai')?.revision ?? 0}\n operations={operations}\n t={t}\n readOnly={!state.writable}\n onClose={(changed) => {\n setDeclaring(false)\n if (changed) void controller.load()\n }}\n />\n </div>\n )\n : (\n // One row for the two ways to gain a provider: adopt one the\n // adapter already knows, or declare one it does not. Side by side\n // and equal-width so they read as siblings and line up with the\n // rows above, rather than two pills of different lengths.\n <div className={styles['addActions']}>\n <button\n type=\"button\"\n className={styles['addButton']}\n disabled={addable.length === 0 || !state.writable}\n onClick={() => {\n const first = addable[0]\n /* v8 ignore next -- the button is disabled while nothing is addable */\n if (first === undefined) return\n setSavedTarget(undefined)\n setDeclaring(false)\n setAdding(true)\n setEditing(targetOf(first))\n }}\n >\n <IconPlusOutline16 size={14} />\n {t('add')}\n </button>\n <button\n type=\"button\"\n className={styles['addButton']}\n disabled={protocols.length === 0 || !state.writable}\n onClick={() => {\n setSavedTarget(undefined)\n setAdding(false)\n setEditing(undefined)\n setDeclaring(true)\n }}\n >\n <IconPlusOutline16 size={14} />\n {t('customAdd')}\n </button>\n </div>\n )}\n </div>\n <Modal\n open={deleteTarget !== undefined}\n onClose={closeDelete}\n title={deleteTarget === undefined ? '' : providerCopy(t('deleteTitle'), deleteTarget)}\n closeLabel={t('close')}\n description={deleteTarget === undefined\n ? ''\n : providerCopy(\n deleteTarget.credentialRef === undefined\n ? t('deleteDescription')\n : t('deleteDescriptionWithCredential'),\n deleteTarget,\n )}\n className={styles['deleteDialog'] as string}\n footer={(\n <>\n <Button variant=\"outline\" autoFocus disabled={deleting} onClick={closeDelete}>\n {t('cancel')}\n </Button>\n <Button\n variant=\"outline\"\n className={styles['deleteConfirm']}\n disabled={deleting}\n onClick={confirmDelete}\n >\n {deleteTarget === undefined\n ? ''\n : providerCopy(deleting ? t('deleting') : t('deleteConfirm'), deleteTarget)}\n </Button>\n </>\n )}\n >\n {deleteFailure === undefined ? null : <p className={styles['error']}>{deleteFailure}</p>}\n </Modal>\n </div>\n )\n}\n","/**\n * The Host reads and writes the Models cards perform, as callbacks built in the\n * plugin body. Cards receive these instead of a context: the outcomes name what\n * a card renders — a stored view, a stale revision, a refusal message — so the\n * failure codes and Remote namespaces stay in the apply world.\n */\n\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type {\n CredentialInfo, LlmDiscoveredModel, LlmModelDiscoveryRequest,\n SettingsNamespaceView, SettingsPathOpView,\n} from '@deepseek-ai/dsh-api-remotes/client'\n\n/** What one namespace write answered. */\nexport type SettingsWriteOutcome =\n /** Committed; the view carries the stored user subtree and the new revision. */\n | { readonly kind: 'written'; readonly view: SettingsNamespaceView }\n /**\n * The stored revision moved after the card read it, so the draft is stale.\n * The message stays for callers that report the Host diagnostic as it is.\n */\n | { readonly kind: 'conflict'; readonly message: string }\n /** Any other refusal, with the Host's own diagnostic. */\n | { readonly kind: 'refused'; readonly message: string }\n\n/** What one endpoint interrogation answered. */\nexport type ModelDiscoveryOutcome =\n /** The candidates the provider disclosed, in its own order. */\n | { readonly kind: 'found'; readonly models: readonly LlmDiscoveredModel[] }\n /** The interrogation was refused, with the Host's own diagnostic. */\n | { readonly kind: 'refused'; readonly message: string }\n\n/** The Host operations the Models page and its cards invoke. */\nexport interface ModelsOperations {\n /**\n * Read one credential reference's state.\n * @param ref - credential reference name.\n * @returns the state, or undefined when the reference is unknown or the read was refused.\n */\n describeCredential(ref: string): Promise<CredentialInfo | undefined>\n /**\n * Store one credential literal under its reference.\n * @param ref - credential reference name.\n * @param value - the literal to store.\n * @returns the refusal message, or undefined once stored.\n */\n storeCredential(ref: string, value: string): Promise<string | undefined>\n /**\n * Remove one credential reference (idempotent).\n * @param ref - credential reference name.\n * @returns the refusal message, or undefined once removed.\n */\n removeCredential(ref: string): Promise<string | undefined>\n /**\n * Apply path operations to one settings namespace.\n * @param ns - settings namespace identity.\n * @param ops - ordered path operations against the stored section, as the\n * wire takes them (the Remote signature owns the array).\n * @param expectedRevision - revision the draft was opened at, or undefined to write unfenced.\n * @returns the write outcome the card renders from.\n */\n writeSettings(\n ns: string,\n ops: SettingsPathOpView[],\n expectedRevision: number | undefined,\n ): Promise<SettingsWriteOutcome>\n /**\n * Ask a provider endpoint what models it serves.\n * @param settingsNs - namespace whose adapter family answers.\n * @param request - endpoint facts as the form currently shows them.\n * @returns the candidates, or the refusal.\n */\n discoverModels(settingsNs: string, request: LlmModelDiscoveryRequest): Promise<ModelDiscoveryOutcome>\n}\n\n/**\n * Bind the page's Host operations to the plugin's own Remote namespaces.\n * @param ctx - the page plugin's context, which declares `remote.credentials`,\n * `remote.llm`, and `remote.settings` in its own `inject`.\n * @returns the callbacks the section and its cards are injected with.\n */\nexport function createModelsOperations(ctx: ClientContext): ModelsOperations {\n return {\n describeCredential: async (ref) => {\n const response = await ctx.remote.credentials.describe([ref])\n return response.ok ? response.value[ref] : undefined\n },\n storeCredential: async (ref, value) => {\n const response = await ctx.remote.credentials.set(ref, value)\n return response.ok ? undefined : response.error.message\n },\n removeCredential: async (ref) => {\n const response = await ctx.remote.credentials.unset(ref)\n return response.ok ? undefined : response.error.message\n },\n writeSettings: async (ns, ops, expectedRevision) => {\n const response = await ctx.remote.settings.mutate(ns, ops, expectedRevision)\n if (response.ok) return { kind: 'written', view: response.value }\n const { code, message } = response.error\n return code === 'settings/conflict' ? { kind: 'conflict', message } : { kind: 'refused', message }\n },\n discoverModels: async (settingsNs, request) => {\n const response = await ctx.remote.llm.discoverModels(settingsNs, request)\n return response.ok\n ? { kind: 'found', models: response.value }\n : { kind: 'refused', message: response.error.message }\n },\n }\n}\n","import type {\n SettingsSchemaService,\n} from '@deepseek-ai/dsh-client-ui-settings/client'\n\n/** Plain schema callbacks exposed to Models stores and presentation components. */\nexport type SettingsSchemaOperations = Pick<\n SettingsSchemaService,\n 'rehydrate' | 'validate' | 'nodeAtPath' | 'getPath' | 'hasPath' | 'setPath' | 'deletePath'\n>\n\n/**\n * Hide the Cordis service identity behind bound schema callbacks.\n * @param service - settings-owned schema service available in the apply context.\n * @returns callbacks that cannot expose the service context to React components.\n */\nexport function createSettingsSchemaOperations(service: SettingsSchemaService): SettingsSchemaOperations {\n return {\n rehydrate: serialized => service.rehydrate(serialized),\n validate: (schema, draft) => service.validate(schema, draft),\n nodeAtPath: (root, path) => service.nodeAtPath(root, path),\n getPath: (value, path) => service.getPath(value, path),\n hasPath: (value, path) => service.hasPath(value, path),\n setPath: (root, path, value) => service.setPath(root, path, value),\n deletePath: (root, path) => service.deletePath(root, path),\n }\n}\n","/**\n * dsh-model-extension — client entry.\n *\n * Registers a \"Models+\" settings section that renders the official Models\n * page (inlined from the host's ui-settings-models sources at build time,\n * with our .ext touch-point replacements) under its own nav id. The store,\n * schema operations, Host operations, dictionaries, and invalidation wiring\n * mirror the upstream ui-settings-models client/index.ts @ 0.1.2-alpha.4\n * exactly — the forked components run unmodified, so the wiring must too.\n */\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\n// Type-only: pulls the shell's SlotMap merge ('settings.section') into this program.\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\n// Type-only: pulls the locale plugin's Context merge (ctx.locale).\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\n// Type-only: pulls the ui renderer's Context merge (useSnapshot and friends on inject faces).\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\n// Type-only: pulls the ctx.remote merge and forwarded-event key face.\nimport type {} from '@deepseek-ai/dsh-api-remotes/client'\nimport { ModelsSection } from './ModelsSection.ext.tsx'\nimport type { ModelsSectionInjected } from './ModelsSection.ext.tsx'\nimport { ModelsSettingsStore } from './store.ts'\nimport { createModelsOperations } from './operations.ts'\nimport { createSettingsSchemaOperations } from './schema-operations.ts'\nimport { en as extensionEn, zh as extensionZh } from './extension-meta.ts'\n\n/** Cordis service name (distinct from the npm package name). */\nexport const name = 'model-extension-client'\n\n/** Required services — mirrors the upstream Models section registration @ 0.1.2-alpha.4. */\nexport const inject = [\n 'slots', 'locale', 'remote', 'remote.credentials', 'remote.llm', 'remote.settings',\n 'settingsScope', 'settingsSchema',\n]\n\n/** Refetch the page snapshot only after its first load (upstream helper, inlined). */\nfunction refreshIfLoaded(controller: ModelsSettingsStore): void {\n if (controller.store.getSnapshot().status === 'idle') return\n void controller.load()\n}\n\n/**\n * Apply: register the Models+ section once slot/locale services are up.\n * @param ctx - client root context.\n */\nexport function apply(ctx: ClientContext): void {\n // Extension copy rides its own namespace; the section declares it via\n // `locale:` so the framework synthesizes the `t` seat for both the official\n // keys (resolved through our merged dictionary) and the extension keys.\n const NS = 'settings.models-extension'\n ctx.effect(() => ctx.locale.register(NS, {\n zh: { ...extensionZh },\n en: { ...extensionEn },\n }), 'dsh-model-extension: copy dictionaries')\n\n const schema = createSettingsSchemaOperations(ctx.settingsSchema)\n const operations = createModelsOperations(ctx)\n const controller = new ModelsSettingsStore(ctx, schema, ctx.settingsScope.describe())\n // Registration-time text (the nav label thunk) shares one bound translate.\n const t = ctx.locale.bind(NS) as ModelsSectionInjected['t']\n const injected = (): ModelsSectionInjected => ({\n controller,\n hooks: { snapshot: controller.store },\n operations,\n schema,\n t,\n })\n\n // Pushed invalidations converge every open surface without polling.\n ctx.effect(() => {\n const refreshModels = (): void => { refreshIfLoaded(controller) }\n return () => [\n ctx.remote.$on('settings/document-updated', () => { refreshModels() }),\n ctx.remote.$on('credentials/reference-updated', refreshModels),\n ctx.remote.$on('llm/adapters-updated', refreshModels),\n ctx.on('connection/reset', refreshModels),\n ]\n }, 'dsh-model-extension: pushed invalidations')\n\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'models-extension',\n order: 11,\n label: () => t('nav'),\n inject: injected,\n }, ModelsSection))\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;EAWA,MAAM,gBAAgB;;;;;;;;;;EAWtB,MAAM,WAAW;;EAYjB,SAAS,SAAS,OAAwB;GACxC,MAAM,QAAQ,MAAM;GACpB,IAAI,UAAU,QAAO,UAAU,OAAQ,UAAU,KAAK,OAAO;GAC7D,OAAO,MAAM,SAAS,KAAK,MAAM,SAAS,KAAK;EACjD;;;;;;;;;;;EAYA,SAAgB,cAAc,OAA6C;GACzE,IAAI,MAAM,WAAW,GAAG,OAAO,KAAA;GAC/B,MAAM,QAAQ,MAAM,KAAK;GACzB,IAAI,MAAM,WAAW,GAAG,OAAO;GAC/B,IAAI,SAAS,KAAK,KAAK,KAAK,SAAS,KAAK,GAAG,OAAO;GACpD,IAAI,CAAC,cAAc,KAAK,KAAK,GAAG,OAAO;EAEzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EEbA,SAAgB,aAAa,OAAqC;GAChE,MAAM,EAAE,MAAM;GACd,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWA,6BAAO;IAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KACE,MAAK;KACL,WAAWA,6BAAO;KAClB,UAAU,MAAM;KAChB,SAAS,MAAM;KAEd,UAAA,EAAE,MAAM,kBAAkB,QAAQ;IAC7B,CAAA,GACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KACE,MAAK;KACL,WAAWA,6BAAO;KAClB,UAAU,MAAM;KAChB,SAAS,MAAM;KAEd,UAAA,MAAM,OAAO,EAAE,MAAM,kBAAkB,IAAI,EAAE,MAAM,cAAc;IAC5D,CAAA,CACL;;EAET;;;;;;;;;;ECzCA,SAAS,MAAM,KAAqB;GAClC,OAAO,OAAO,IAAI,MAAM,GAAG,IAAI,QAAQ,GAAG,CAAC,CAAC;EAC9C;;EAGA,MAAM,mBAAmB;;EAGzB,MAAM,iBAAiB;GAAE,GAAG;GAAO,GAAG;EAAU;;;;;;;;EAShD,SAAgB,cAAc,MAAkC;GAC9D,MAAM,UAAU,KAAK,KAAK;GAC1B,IAAI,QAAQ,WAAW,GAAG,OAAO,KAAA;GACjC,MAAM,QAAQ,iBAAiB,KAAK,OAAO;GAC3C,IAAI,UAAU,MAAM,OAAO;GAC3B,MAAM,SAAS,MAAM,EAAE,EAAE,YAAY;GACrC,MAAM,QAAQ,WAAW,OAAO,WAAW,MAAM,eAAe,UAAU;GAC1E,MAAM,SAAS,OAAO,MAAM,EAAE,IAAI;GAGlC,MAAM,UAAU,KAAK,MAAM,MAAM;GACjC,OAAO,KAAK,IAAI,SAAS,OAAO,IAAI,OAAO,UAAU;EACvD;;;;;;;;EASA,SAAgB,eAAe,OAAuB;GACpD,IAAI,CAAC,OAAO,UAAU,KAAK,KAAK,SAAS,GAAG,OAAO,OAAO,KAAK;GAC/D,IAAI,QAAQ,eAAe,MAAM,GAAG,OAAO,GAAG,OAAO,QAAQ,eAAe,CAAC,EAAE;GAC/E,IAAI,QAAQ,eAAe,MAAM,GAAG,OAAO,GAAG,OAAO,QAAQ,eAAe,CAAC,EAAE;GAC/E,OAAO,OAAO,KAAK;EACrB;;EAYA,SAAgB,YAAY,OAAsC;GAChE,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,OAAO,CAAC;GACnC,OAAO,MAAM,KAAI,UACf,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK,IAC/D,QACA,CAAC,CAAC;EACV;;;;;;EAOA,SAAgB,uBAAuB,OAA6D;GAClG,IAAI,UAAU,KAAA,GAAW,OAAO,KAAA;GAChC,MAAM,SAAS,YAAY,KAAK;GAChC,MAAM,uBAAO,IAAI,IAAY;GAC7B,KAAK,MAAM,CAAC,OAAO,UAAU,OAAO,QAAQ,GAAG;IAI7C,MAAM,KAAK,MAAM;IACjB,MAAM,UAAU,OAAO,OAAO,WAAW,GAAG,KAAK,IAAI,KAAA;IACrD,IAAI,YAAY,KAAA,KAAa,QAAQ,WAAW,GAAG,OAAO;KAAE;KAAO,KAAK;IAAkB;IAC1F,IAAI,KAAK,IAAI,OAAO,GAAG,OAAO;KAAE;KAAO,KAAK;IAAmB;IAC/D,KAAK,IAAI,OAAO;IAChB,MAAM,OAAO,MAAM;IACnB,IAAI,SAAS,KAAA,MAAc,OAAO,SAAS,YAAY,KAAK,WAAW,IACrE,OAAO;KAAE;KAAO,KAAK;IAAmB;IAE1C,MAAM,gBAAgB,MAAM;IAC5B,IAAI,kBAAkB,KAAA,MAChB,OAAO,kBAAkB,YAAY,CAAC,OAAO,UAAU,aAAa,KAAK,iBAAiB,IAC9F,OAAO;KAAE;KAAO,KAAK;IAAsB;IAE7C,MAAM,YAAY,MAAM;IACxB,IAAI,cAAc,KAAA,MACZ,OAAO,cAAc,YAAY,CAAC,OAAO,UAAU,SAAS,KAAK,aAAa,IAClF,OAAO;KAAE;KAAO,KAAK;IAAwB;GAEjD;EAEF;;;;;;;EA4BA,SAAgB,qBAAqB,OAA6C;GAYhF,MAAM,CAAC,SAAS,eAAA,GAAcC,MAAAA,SAAAA,uBAA4C,IAAI,IAAI,CAAC;GACnF,MAAM,CAAC,UAAU,gBAAA,GAAeA,MAAAA,SAAAA,uBAAoC,IAAI,IAAI,CAAC;GAE7E,MAAM,UAAU,OAAe,KAAmB,UAAyB;IACzE,MAAM,OAAO,MAAM,OAAO,KAAK,OAAO,OAAO;KAC3C,MAAM,OAAO,EAAE,GAAG,MAAM;KACxB,IAAI,OAAO,OAAO,OAAO;KACzB,IAAI,UAAU,KAAA,GAAW,QAAQ,eAAe,MAAM,GAAG;UACpD,KAAK,OAAO;KACjB,OAAO;IACT,CAAC;IACD,MAAM,SAAS,IAAI;GACrB;GAEA,MAAM,UAAU,UAAwB;IACtC,YAAY,YAAY;KACtB,MAAM,uBAAO,IAAI,IAAoB;KACrC,KAAK,MAAM,CAAC,KAAK,SAAS,SAAS;MACjC,MAAM,KAAK,MAAM,GAAG;MACpB,IAAI,OAAO,OAAO;MAElB,KAAK,IAAI,KAAK,QAAQ,IAAI,QAAQ,QAAQ,OAAO,KAAK,CAAC,CAAC,IAAI,KAAK,IAAI;KACvE;KACA,OAAO;IACT,CAAC;IACD,aAAa,YAAY;KACvB,MAAM,uBAAO,IAAI,IAAY;KAC7B,KAAK,MAAM,MAAM,SAAS;MACxB,IAAI,OAAO,OAAO;MAClB,KAAK,IAAI,KAAK,QAAQ,KAAK,IAAI,EAAE;KACnC;KACA,OAAO;IACT,CAAC;IACD,MAAM,SAAS,MAAM,OAAO,QAAQ,QAAQ,OAAO,OAAO,KAAK,CAAC,CAAC,KAAI,WAAU,EAAE,GAAG,MAAM,EAAE,CAAC;GAC/F;GAEA,MAAM,cAAoB;IACxB,2BAAW,IAAI,IAAI,CAAC;IACpB,4BAAY,IAAI,IAAI,CAAC;IACrB,MAAM,QAAQ;GAChB;GAEA,MAAM,UAAU,UAAwB;IACtC,aAAa,YAAY;KACvB,MAAM,OAAO,IAAI,IAAI,OAAO;KAC5B,IAAI,CAAC,KAAK,OAAO,KAAK,GAAG,KAAK,IAAI,KAAK;KACvC,OAAO;IACT,CAAC;GACH;;GAGA,MAAM,gBAAgB,OAA2B,OAAe,UAAiC;IAC/F,MAAM,QAAQ,QAAQ,IAAI,GAAG,OAAO,KAAK,EAAE,GAAG,OAAO;IACrD,IAAI,UAAU,KAAA,GAAW,OAAO;IAChC,MAAM,QAAQ,MAAM;IACpB,OAAO,OAAO,UAAU,WAAW,eAAe,KAAK,IAAI;GAC7D;GAEA,MAAM,kBAAkB,OAAe,UAA+B;IACpE,MAAM,MAAM,GAAG,OAAO,KAAK,EAAE,GAAG;IAChC,MAAM,QAAQ,QAAQ,IAAI,GAAG;IAC7B,IAAI,UAAU,KAAA,GAAW;IAGzB,MAAM,SAAS,cAAc,KAAK;IAClC,IAAI,WAAW,KAAA,KAAa,OAAO,MAAM,MAAM,GAAG;IAClD,YAAY,YAAY;KACtB,MAAM,OAAO,IAAI,IAAI,OAAO;KAC5B,KAAK,OAAO,GAAG;KACf,OAAO;IACT,CAAC;GACH;;GAGA,MAAM,iBACJ,OACA,OACA,OACA,aAEA,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;IAAO,WAAWC,6BAAO;IAAzB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAWA,6BAAO;KAAqB,UAAA,MAAM,EAAE,UAAU,kBAAkB,kBAAkB,WAAW;IAAQ,CAAA,GACtH,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;KACE,WAAWA,6BAAO;KAClB,MAAK;KACL,WAAU;KACV,OAAO,aAAa,OAAO,OAAO,KAAK;KACvC,aAAa,aAAa,KAAA,IACtB,MAAM,EAAE,UAAU,kBAAkB,6BAA6B,sBAAsB,IACvF,eAAe,QAAQ;KAC3B,cAAY,GAAG,MAAM,EAAE,UAAU,kBAAkB,kBAAkB,WAAW,EAAE,GAAG,OAAO,QAAQ,CAAC;KACrG,UAAU,MAAM;KAChB,WAAW,UAAU;MACnB,MAAM,OAAO,MAAM,OAAO;MAC1B,YAAW,YAAW,IAAI,IAAI,OAAO,CAAC,CAAC,IAAI,GAAG,OAAO,KAAK,EAAE,GAAG,SAAS,IAAI,CAAC;MAC7E,OAAO,OAAO,OAAO,cAAc,IAAI,CAAC;KAC1C;KACA,cAAc;MAAE,eAAe,OAAO,KAAK;KAAE;IAC9C,CAAA,CACI;;GAGT,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;IAAS,WAAWA,6BAAO;IAAiB,cAAY,MAAM,EAAE,QAAQ;IAAxE,UAAA;KACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,6BAAO;MAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,6BAAO;OAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,6BAAO;QAAuB,UAAA,MAAM,EAAE,QAAQ;OAAQ,CAAA,GACvE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,6BAAO;QACrB,UAAA,MAAM,aAAa,MAAM,EAAE,kBAAkB,IAAI,MAAM,EAAE,iBAAiB;OACvE,CAAA,CACH;MACJ,CAAA,GAAA,MAAM,aAEH,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OACE,MAAK;OACL,WAAWA,6BAAO;OAClB,UAAU,MAAM;OAChB,SAAS;OAER,UAAA,MAAM,EAAE,aAAa;MAChB,CAAA,IAER,IACD;;KACJ,MAAM,OAAO,WAAW,IACrB,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,6BAAO;MAAgB,UAAA,MAAM,EAAE,aAAa;KAAK,CAAA,IAE/D,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWA,6BAAO;MACpB,UAAA,MAAM,OAAO,KAAK,OAAO,UACxB,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,6BAAO;OAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,6BAAO;QAAvB,UAAA;SACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;UACE,WAAWA,6BAAO;UAClB,MAAK;UACL,OAAO,OAAO,MAAM,UAAU,WAAW,MAAM,QAAQ;UACvD,aAAa,MAAM,EAAE,SAAS;UAC9B,cAAY,GAAG,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,QAAQ,CAAC;UACrD,UAAU,MAAM;UAChB,WAAW,UAAU;WAAE,OAAO,OAAO,MAAM,MAAM,OAAO,KAAK;UAAE;UAC/D,SAAS,UAAU;WAGjB,MAAM,UAAU,MAAM,OAAO,MAAM,KAAK;WACxC,IAAI,YAAY,MAAM,OAAO,OAAO,OAAO,OAAO,MAAM,OAAO;UACjE;SACD,CAAA;SACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;UACE,WAAWA,6BAAO;UAClB,MAAK;UACL,OAAO,OAAO,MAAM,YAAY,WAAW,MAAM,UAAU;UAC3D,aAAa,MAAM,EAAE,WAAW;UAChC,cAAY,GAAG,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,QAAQ,CAAC;UACvD,UAAU,MAAM;UAChB,WAAW,UAAU;WACnB,OAAO,OAAO,QAAQ,MAAM,OAAO,UAAU,KAAK,KAAA,IAAY,MAAM,OAAO,KAAK;UAClF;SACD,CAAA;SACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UACE,MAAK;UACL,WAAWA,6BAAO;UAClB,cAAY,GAAG,MAAM,EAAE,eAAe,EAAE,GAAG,OAAO,QAAQ,CAAC;UAC3D,iBAAe,SAAS,IAAI,KAAK;UACjC,OAAO,MAAM,EAAE,eAAe;UAC9B,eAAe;WAAE,OAAO,KAAK;UAAE;UAE9B,UAAA,SAAS,IAAI,KAAK,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,0BAAD,CAA2B,CAAA,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,2BAAD,CAA4B,CAAA;SAC5E,CAAA;SACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UACE,MAAK;UACL,WAAW,GAAGF,6BAAO,cAAc,GAAGA,6BAAO;UAC7C,cAAY,GAAG,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,QAAQ,CAAC;UACzD,OAAO,MAAM,EAAE,aAAa;UAC5B,UAAU,MAAM;UAChB,eAAe;WAAE,OAAO,KAAK;UAAE;UAE/B,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACG,sCAAAA,oBAAD,EAAoB,MAAM,GAAK,CAAA;SACzB,CAAA;QACL;OACJ,CAAA,GAAA,SAAS,IAAI,KAAK,IAEf,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWH,6BAAO;QAAvB,UAAA,CACG,cAAc,OAAO,OAAO,iBAAiB,MAAM,oBAAoB,GACvE,cAAc,OAAO,OAAO,aAAa,MAAM,gBAAgB,CAC7D;OAEL,CAAA,IAAA,IACD;MAzDsC,GAAA,KAyDtC,CACN;KACE,CAAA;KAET,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;MACE,MAAK;MACL,WAAWA,6BAAO;MAClB,UAAU,MAAM;MAChB,eAAe;OAAE,MAAM,SAAS,CAAC,GAAG,MAAM,OAAO,KAAI,WAAU,EAAE,GAAG,MAAM,EAAE,GAAG,EAAE,IAAI,GAAG,CAAC,CAAC;MAAE;MAJ9F,UAAA,CAME,iBAAA,GAAA,kBAAA,IAAA,CAACI,sCAAAA,mBAAD,EAAmB,MAAM,GAAK,CAAA,GAC7B,MAAM,EAAE,UAAU,CACb;;IACD;;EAEb;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EEnWA,MAAa,kBAAA;;EAIb,MAAa,kBAAkB;GAAC;GAAO;GAAW;GAAO;GAAU;GAAQ;GAAS;EAAK;;EAIzF,MAAa,aAAa,CAAC,QAAQ,OAAO;;EAI1C,MAAa,mBAAmB;GAC9B;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;;EAIA,MAAa,KAAK;GAEhB,KAAK;GACL,OAAO;GACP,OAAO;GACP,MAAM;GACN,cAAc;GACd,QAAQ;GACR,gBAAgB;GAChB,aAAa;GACb,mBAAmB;GACnB,iCAAiC;GACjC,eAAe;GACf,UAAU;GACV,KAAK;GACL,UAAU;GACV,OAAO;GACP,QAAQ;GACR,OAAO;GACP,UAAU;GACV,eAAe;GACf,sBAAsB;GACtB,mBAAmB;GACnB,UAAU;GACV,YAAY;GACZ,UAAU;GACV,OAAO;GACP,UAAU;GACV,gBAAgB;GAChB,sBAAsB;GACtB,WAAW;GACX,cAAc;GACd,YAAY;GACZ,SAAS;GACT,gBAAgB;GAChB,QAAQ;GACR,iBAAiB;GACjB,kBAAkB;GAClB,aAAa;GACb,OAAO;GACP,SAAS;GACT,WAAW;GACX,sBAAsB;GACtB,eAAe;GACf,0BAA0B;GAC1B,WAAW;GACX,sBAAsB;GACtB,eAAe;GACf,UAAU;GACV,aAAa;GACb,aAAa;GACb,UAAU;GACV,aAAa;GACb,sBAAsB;GACtB,iBAAiB;GACjB,kBAAkB;GAClB,kBAAkB;GAClB,qBAAqB;GACrB,uBAAuB;GACvB,cAAc;GACd,sBAAsB;GACtB,gBAAgB;GAChB,oBAAoB;GACpB,gBAAgB;GAChB,aAAa;GACb,UAAU;GACV,mBAAmB;GACnB,YAAY;GACZ,YAAY;GACZ,kBAAkB;GAClB,gBAAgB;GAChB,kBAAkB;GAClB,YAAY;GACZ,WAAW;GACX,aAAa;GACb,WAAW;GACX,aAAa;GACb,iBAAiB;GACjB,oBAAoB;GACpB,kBAAkB;GAClB,mBAAmB;GACnB,WAAW;GACX,gBAAgB;GAChB,oBAAoB;GACpB,mBAAmB;GACnB,0BAA0B;GAC1B,0BAA0B;GAC1B,QAAQ;GACR,UAAU;GACV,iBAAiB;GACjB,uBAAuB;GACvB,iBAAiB;GACjB,gBAAgB;GAChB,kBAAkB;GAClB,aAAa;GAGb,gBAAgB;GAChB,YAAY;GACZ,YAAY;GACZ,gBAAgB;GAChB,yBAAyB;GACzB,uBAAuB;GACvB,2BAA2B;GAC3B,kBAAkB;GAClB,sBAAsB;GACtB,qBAAqB;GACrB,wBAAwB;GACxB,0BAA0B;GAC1B,4BAA4B;GAC5B,iBAAiB;GACjB,cAAc;GACd,gBAAgB;EAClB;;EAKA,MAAa,KAAsC;GAEjD,KAAK;GACL,OAAO;GACP,OAAO;GACP,MAAM;GACN,cAAc;GACd,QAAQ;GACR,gBAAgB;GAChB,aAAa;GACb,mBAAmB;GACnB,iCAAiC;GACjC,eAAe;GACf,UAAU;GACV,KAAK;GACL,UAAU;GACV,OAAO;GACP,QAAQ;GACR,OAAO;GACP,UAAU;GACV,eAAe;GACf,sBAAsB;GACtB,mBAAmB;GACnB,UAAU;GACV,YAAY;GACZ,UAAU;GACV,OAAO;GACP,UAAU;GACV,gBAAgB;GAChB,sBAAsB;GACtB,WAAW;GACX,cAAc;GACd,YAAY;GACZ,SAAS;GACT,gBAAgB;GAChB,QAAQ;GACR,iBAAiB;GACjB,kBAAkB;GAClB,aAAa;GACb,OAAO;GACP,SAAS;GACT,WAAW;GACX,sBAAsB;GACtB,eAAe;GACf,0BAA0B;GAC1B,WAAW;GACX,sBAAsB;GACtB,eAAe;GACf,UAAU;GACV,aAAa;GACb,aAAa;GACb,UAAU;GACV,aAAa;GACb,sBAAsB;GACtB,iBAAiB;GACjB,kBAAkB;GAClB,kBAAkB;GAClB,qBAAqB;GACrB,uBAAuB;GACvB,cAAc;GACd,sBAAsB;GACtB,gBAAgB;GAChB,oBAAoB;GACpB,gBAAgB;GAChB,aAAa;GACb,UAAU;GACV,mBAAmB;GACnB,YAAY;GACZ,YAAY;GACZ,kBAAkB;GAClB,gBAAgB;GAChB,kBAAkB;GAClB,YAAY;GACZ,WAAW;GACX,aAAa;GACb,WAAW;GACX,aAAa;GACb,iBAAiB;GACjB,oBAAoB;GACpB,kBAAkB;GAClB,mBAAmB;GACnB,WAAW;GACX,gBAAgB;GAChB,oBAAoB;GACpB,mBAAmB;GACnB,0BAA0B;GAC1B,0BAA0B;GAC1B,QAAQ;GACR,UAAU;GACV,iBAAiB;GACjB,uBAAuB;GACvB,iBAAiB;GACjB,gBAAgB;GAChB,kBAAkB;GAClB,aAAa;GAGb,gBAAgB;GAChB,YAAY;GACZ,YAAY;GACZ,gBAAgB;GAChB,yBAAyB;GACzB,uBAAuB;GACvB,2BAA2B;GAC3B,kBAAkB;GAClB,sBAAsB;GACtB,qBAAqB;GACrB,wBAAwB;GACxB,0BAA0B;GAC1B,4BAA4B;GAC5B,iBAAiB;GACjB,cAAc;GACd,gBAAgB;EAClB;;;;EClOA,MAAM,eAAkE;GACtE,KAAK;IAAE,IAAI;IAAM,IAAI;GAAM;GAC3B,SAAS;IAAE,IAAI;IAAM,IAAI;GAAU;GACnC,KAAK;IAAE,IAAI;IAAK,IAAI;GAAM;GAC1B,QAAQ;IAAE,IAAI;IAAK,IAAI;GAAS;GAChC,MAAM;IAAE,IAAI;IAAK,IAAI;GAAO;GAC5B,OAAO;IAAE,IAAI;IAAM,IAAI;GAAa;GACpC,KAAK;IAAE,IAAI;IAAM,IAAI;GAAM;EAC7B;;EAGA,MAAM,kBAA8D;GAClE,MAAM;IAAE,IAAI;IAAM,IAAI;GAAO;GAC7B,OAAO;IAAE,IAAI;IAAM,IAAI;GAAQ;EACjC;;EAGA,MAAM,gBAAqC;GACzC,OAAO;GACP,QAAQ;GACR,QAAQ;GACR,aAAa;GACb,MAAM;EACR;;EAYA,SAAS,SAAS,OAA4C;GAC5D,MAAM,QAAQ,MAAM;GACpB,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK,IACtE,QACA,CAAC;EACP;;EAGA,SAAS,UAAU,OAA8D;GAC/E,MAAM,QAAQ,MAAM;GACpB,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,GAAG,OAAO,KAAA;GAChF,OAAO;EACT;;;;;;EAOA,SAAgB,qBAAqB,OAA6C;GAChF,MAAM,EAAE,OAAO,UAAU,WAAW,UAAU;GAI9C,MAAM,OAAO,OAAO,aAAa,eAAe,SAAS,gBAAgB,KAAK,WAAW,IAAI;GAC7F,MAAM,KAAK,SACR,OAAOC,KAAcC,GAAAA,CAAa;GACrC,MAAM,cAAc,UAClB,OAAO,GAAG,aAAa,MAAM,CAAC,GAAG,IAAI,MAAM,KAAK,GAAG,aAAa,MAAM,CAAC,GAAG,IAAI,MAAM;GACtF,MAAM,iBAAiB,aACrB,OAAO,gBAAgB,SAAS,EAAE,MAAM,WAAW,gBAAgB,SAAS,EAAE,MAAM;GAEtF,MAAM,SAAS,SAAS,KAAK;GAC7B,MAAM,0BAA0B,OAAO,+BAA+B;GAItE,MAAM,wBAAwB,OAAO,6BAA6B;;;;;GAMlE,MAAM,gBAAgB,KAAa,UAAyB;IAC1D,MAAM,OAAO,EAAE,GAAG,OAAO;IACzB,IAAI,UAAU,KAAA,GAAW,OAAO,KAAK;SAChC,KAAK,OAAO;IAEjB,SAAS,EAAE,QAAQ,OAAO,KAAK,IAAI,CAAC,CAAC,WAAW,IAAI,KAAA,IAAY,KAAK,CAAC;GACxE;GAEA,MAAM,cAAc,YAA6D;IAC/E,SAAS,EAAE,kBAAkB,QAAQ,CAAC;GACxC;GAEA,MAAM,YAAY,eAA+B;IAC/C,SAAS,EAAE,OAAO,WAAW,WAAW,IAAI,KAAA,IAAY,WAAW,CAAC;GACtE;GAEA,MAAM,eAAe,OAAsB,YAA2B;IACpE,MAAM,UAAU,EAAE,GAAI,UAAU,KAAK,KAAK,CAAC,EAAG;IAC9C,IAAI,SAEF,QAAQ,SAAS,UAAU,QAAQ,OAAO;SAE1C,OAAO,QAAQ;IAEjB,MAAM,OAAgC,EACpC,kBAAkB,OAAO,KAAK,OAAO,CAAC,CAAC,WAAW,IAAI,KAAA,IAAY,QACpE;IACA,SAAS,IAAI;GACf;GAEA,MAAM,gBAAgB,OAAsB,SAAuB;IACjE,MAAM,UAAU,EAAE,GAAI,UAAU,KAAK,KAAK,CAAC,EAAG;IAC9C,IAAI,EAAE,SAAS,UAAU;IACzB,QAAQ,SAAS,KAAK,KAAK,CAAC,CAAC,WAAW,IAAI,OAAO,KAAK,KAAK;IAC7D,WAAW,OAAO;GACpB;GAEA,MAAM,kBAAkB,UAAkB,YAA2B;IACnE,MAAM,UAAU,MAAM,QAAQ,MAAM,QAAQ,IACvC,MAAM,WACP,CAAC,MAAM;IACX,SAAS,UACL,CAAC,mBAAG,IAAI,IAAI,CAAC,GAAG,SAAS,QAAQ,CAAC,CAAC,IACnC,QAAQ,QAAO,UAAS,UAAU,QAAQ,CAAC;GACjD;GAEA,MAAM,UAAU,UAAU,KAAK;GAC/B,MAAM,iBAAiB,YAAY,KAAA,IAAY,CAAC,IAAI,gBAAgB,QAAO,UAAS,SAAS,OAAO;GACpG,MAAM,YAAY,MAAM,QAAQ,MAAM,QAAQ,IAAI,MAAM,WAAuB,CAAC;GAChF,MAAM,iBAAiB,OAAO,OAAO,sBAAsB,WACvD,OAAO,oBACP,KAAA;GAGJ,MAAM,eAAe,eAAe,MAAK,UACvC,UAAU,SAAS,OAAO,UAAU,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC;GACvE,MAAM,kBAAkB,YAAY,KAAA,KAC/B,eAAe,SAAS,KACxB,CAAC,eAAe,MAAK,UAAS,UAAU,KAAK;;GAGlD,MAAM,WAAW,UAAoC;IAEnD,OADc,UAAU,QAEpB,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,OAAO;MAAE,UAAU;MAAI,OAAO;KAAmC;KAAG,UAAA;IAAO,CAAA,IAE/E,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;KACE,WAAWC,iCAAO;KAClB,MAAK;KACL,OAAO,OAAO,UAAU,UAAU,EAAE;KACpC,cAAY,GAAG,EAAE,qBAAqB,EAAE,GAAG;KAC3C,aAAa;KACH;KACV,WAAU,UAAS;MAAE,aAAa,OAAO,MAAM,OAAO,KAAK;KAAE;IAC9D,CAAA;GAET;GAEA,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,YAAD;IAAU,OAAO;KAAE,QAAQ;KAAQ,SAAS;KAAG,QAAQ;KAAG,SAAS;KAAQ,eAAe;KAAU,KAAK;IAAG;IAA5G,UAAA;KAEE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,OAAO;OAAE,WAAW;OAA8D,YAAY;MAAG;MACpG,UAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;OAAO,OAAO;QAAE,SAAS;QAAQ,YAAY;QAAc,KAAK;QAAG,QAAQ;OAAU;OAArF,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;QACE,MAAK;QACL,OAAO;QACP,SAAS;QACC;QACV,WAAW,UAAU;SAInB,aAAa,yBAAyB,MAAM,OAAO,UAAU,KAAA,IAAY,KAAK;QAChF;OACD,CAAA,GACD,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;QAAM,OAAO;SAAE,SAAS;SAAQ,eAAe;SAAU,KAAK;QAAE;QAAhE,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWA,iCAAO;SAAqB,UAAA,EAAE,uBAAuB;QAAQ,CAAA,GAC9E,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,OAAO;UAAE,UAAU;UAAI,OAAO;SAAmC;SAAI,UAAA,EAAE,2BAA2B;QAAQ,CAAA,CAC5G;OACD,CAAA,CAAA;;KACJ,CAAA;KAGL,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,OAAO;OAAE,WAAW;OAA8D,YAAY;MAAG;MACpG,UAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;OAAO,OAAO;QAAE,SAAS;QAAe,YAAY;QAAU,KAAK;QAAG,QAAQ;OAAU;OAAxF,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;QACE,MAAK;QACL,OAAO;QACP,SAAS;QACC;QACV,WAAW,UAAU;SACnB,IAAI,MAAM,OAAO,SAGf,aAAa,2BAA2B,IAAI;cACvC;UAML,MAAM,aAAa,EAAE,GAAG,OAAO;UAC/B,OAAO,WAAW;UAClB,OAAO,WAAW;UAClB,SAAS;WACP,QAAQ,OAAO,KAAK,UAAU,CAAC,CAAC,WAAW,IAAI,KAAA,IAAY;WAC3D,kBAAkB,KAAA;UACpB,CAAC;SACH;QACF;OACD,CAAA,GACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,iCAAO;QAAqB,UAAA,EAAE,yBAAyB;OAAQ,CAAA,CAC3E;;KACJ,CAAA;KAGJ,CAAC,0BAA0B,OAC1B,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD,EAAA,UAAA;MACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAWA,iCAAO;OAAoB,OAAO,EAAE,cAAc,EAAE;OAAI,UAAA,EAAE,kBAAkB;MAAO,CAAA;MACnG,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,OAAO;QACV,QAAQ;QACR,cAAc;QACd,UAAU;OACZ;OAJA,UAAA,CAME,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,OAAO;SACV,SAAS;SACT,qBAAqB;SACrB,UAAU;SACV,OAAO;SACP,YAAY;QACd;QANA,UAAA;SAOE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;UAAK,OAAO,EAAE,SAAS,WAAW;UAAI,UAAA,EAAE,YAAY;SAAO,CAAA;SAC3D,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;UAAK,OAAO;WAAE,SAAS;WAAY,YAAY;UAA6D;UAAI,UAAA,EAAE,sBAAsB;SAAO,CAAA;SAC/I,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;UAAK,OAAO;WAAE,SAAS;WAAY,YAAY;UAA6D;UAAI,UAAA,EAAE,qBAAqB;SAAO,CAAA;QAC3I;OAEJ,CAAA,GAAA,gBAAgB,KAAK,OAAO,OAC3B,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAEE,OAAO;SACL,SAAS;SACT,qBAAqB;SACrB,YAAY;SACZ,WAAW,OAAO,IAAI,SAAS;QACjC;QAPF,UAAA;SASE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;UAAK,OAAO;WAAE,SAAS;WAAY,SAAS;WAAQ,gBAAgB;UAAS;UAC3E,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;WACE,MAAK;WACL,OAAO;WACP,SAAS,UAAU,WAAW,CAAC;WACrB;WACV,WAAW,UAAU;YAAE,YAAY,OAAO,MAAM,OAAO,OAAO;WAAE;UACjE,CAAA;SACE,CAAA;SACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;UAAK,OAAO;WACV,SAAS;WACT,UAAU;WACV,YAAY;WACZ,SAAS,UAAU,WAAW,CAAC,KAAK,IAAI;UAC1C;UACG,UAAA,WAAW,KAAK;SACd,CAAA;SACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;UAAK,OAAO;WACV,SAAS;WACT,YAAY;WACZ,SAAS,UAAU,WAAW,CAAC,KAAK,IAAI;UAC1C;UACG,UAAA,UAAU,WAAW,CAAC,KAAK,QAAQ,KAAK,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;WAAM,OAAO;YAAE,UAAU;YAAI,OAAO;WAAmC;WAAG,UAAA;UAAO,CAAA;SAC3H,CAAA;QACF;OAhCE,GAAA,KAgCF,CACN,CACE;;MACH,gBAAgB,kBAEZ,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;OAAG,WAAWA,iCAAO;OAAU,OAAO,EAAE,WAAW,EAAE;OAClD,UAAA,eAAe,EAAE,0BAA0B,IAAI,EAAE,4BAA4B;MAC7E,CAAA,IAEL;KACD,EAAA,CAAA,GAEL,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;MAAO,WAAWA,iCAAO;MAAe,OAAO;OAAE,SAAS;OAAQ,eAAe;OAAU,KAAK;MAAE;MAAlG,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,WAAWA,iCAAO;OAAqB,UAAA,EAAE,gBAAgB;MAAQ,CAAA,GACvE,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;OACE,WAAWA,iCAAO;OAClB,OAAO,kBAAkB;OACf;OACV,WAAW,UAAU;QACnB,MAAM,QAAQ,MAAM,OAAO;QAC3B,aAAa,kBAAkB,UAAU,KAAK,KAAA,IAAY,KAAK;OACjE;OAPF,UAAA,CASE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,OAAM;QAAG,UAAA;OAAS,CAAA,GACzB,iBAAiB,KAAI,WAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAqB,OAAO;QAAS,UAAA;OAAe,GAAvC,MAAuC,CAAC,CAC/E;MACH,CAAA,CAAA;KACP,CAAA,CAAA,EAAA,CAAA;KAIJ,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,OAAO;OAAE,WAAW;OAA8D,YAAY;MAAG;MAAtG,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAWA,iCAAO;OAAoB,OAAO,EAAE,cAAc,EAAE;OAAI,UAAA,EAAE,iBAAiB;MAAO,CAAA,GAClG,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,OAAO;QAAE,SAAS;QAAQ,UAAU;QAAQ,KAAK;OAAG;OACtD,UAAA,WAAW,KAAI,aACd,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;QAAsB,OAAO;SAAE,SAAS;SAAe,YAAY;SAAU,KAAK;SAAG,QAAQ;SAAW,UAAU;QAAG;QAArH,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SACE,MAAK;SACL,OAAO;SACP,SAAS,UAAU,SAAS,QAAQ;SAC1B;SACV,WAAW,UAAU;UAAE,eAAe,UAAU,MAAM,OAAO,OAAO;SAAE;QACvE,CAAA,GACA,cAAc,QAAQ,CAClB;OATK,GAAA,QASL,CACR;MACE,CAAA,CACF;;IACG;;EAEd;;;;;;;;;;;;;;;;;;;;;;;;EClUA,SAAS,OAAO,OAAmB,KAAqB;GACtD,MAAM,QAAQ,MAAM;GACpB,OAAO,OAAO,UAAU,WAAW,QAAQ;EAC7C;;EAGA,SAAS,SAAS,OAAmB,KAAiC;GACpE,MAAM,QAAQ,MAAM;GACpB,OAAO,OAAO,UAAU,WAAW,QAAQ,KAAA;EAC7C;;EAgDA,SAAS,YAAY,EAAE,QAAsC;GAC3D,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IACE,OAAM;IAAK,QAAO;IAAK,SAAQ;IAAY,MAAK;IAAO,eAAA;IACvD,OAAO;KAAE,WAAW,OAAO,kBAAkB,KAAA;KAAW,YAAY;IAAuB;IAE3F,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,GAAE;KAAuB,QAAO;KAAe,aAAY;KAAM,eAAc;KAAQ,gBAAe;IAAS,CAAA;GAClH,CAAA;EAET;;EAGA,SAAS,YAAuB;GAC9B,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,OAAM;IAAK,QAAO;IAAK,SAAQ;IAAY,MAAK;IAAO,eAAA;IAC1D,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KACE,GAAE;KACF,QAAO;KAAe,aAAY;KAAM,eAAc;KAAQ,gBAAe;IAC9E,CAAA;GACE,CAAA;EAET;;;;;;;;;;;;EAgBA,MAAM,gBAAyD;GAC7D,eAAe;GACf,WAAW;EACb;;;;;;;;EASA,SAAS,iBAAiB,OAAmC;GAC3D,OAAO,UAAU,KAAA,IAAY,KAAK,eAAe,KAAK;EACxD;;EAGA,SAAS,MAAM,WAA2C;GACxD,OAAO;IACL,IAAI,UAAU;IACd,GAAG,UAAU,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM,UAAU,KAAK;IAC9D,GAAG,UAAU,kBAAkB,KAAA,IAAY,CAAC,IAAI,EAAE,eAAe,UAAU,cAAc;IACzF,GAAG,UAAU,cAAc,KAAA,IAAY,CAAC,IAAI,EAAE,WAAW,UAAU,UAAU;GAC/E;EACF;;;;;;EAOA,SAAgB,gBAAgB,OAAwC;GACtE,MAAM,EAAE,QAAQ,UAAU,OAAO,YAAY,GAAG,aAAa;GAC7D,MAAM,CAAC,MAAM,YAAA,GAAWC,MAAAA,SAAAA,CAAS,KAAK;GACtC,MAAM,CAAC,SAAS,eAAA,GAAcA,MAAAA,SAAAA,CAA6B,KAAA,CAAS;GACpE,MAAM,CAAC,YAAY,kBAAA,GAAiBA,MAAAA,SAAAA,CAAoD,KAAA,CAAS;GACjG,MAAM,CAAC,QAAQ,cAAA,GAAaA,MAAAA,SAAAA,iBAA8B,IAAI,IAAI,CAAC;GACnE,MAAM,CAAC,gBAAgB,sBAAA,GAAqBA,MAAAA,SAAAA,CAAS,EAAE;GAGvD,MAAM,CAAC,UAAU,gBAAA,GAAeA,MAAAA,SAAAA,iBAA8B,IAAI,IAAI,CAAC;GAOvE,MAAM,CAAC,SAAS,eAAA,GAAcA,MAAAA,SAAAA,iBAAsC,IAAI,IAAI,CAAC;;GAG7E,MAAM,aAAa,OAAe,UAAiC,GAAG,OAAO,KAAK,EAAE,GAAG;GAEvF,MAAM,gBAAgB,OAAe,OAAsB,SAAuB;IAChF,YAAW,YAAW,IAAI,IAAI,OAAO,CAAC,CAAC,IAAI,UAAU,OAAO,KAAK,GAAG,IAAI,CAAC;IACzE,MAAM,OAAO,GAAG,QAAQ,cAAc,IAAI,EAAE,CAAC;GAC/C;;GAGA,MAAM,gBAAgB,OAAmB,OAAe,UACtD,QAAQ,IAAI,UAAU,OAAO,KAAK,CAAC,KAAK,iBAAiB,SAAS,OAAO,KAAK,CAAC;;GAGjF,MAAM,mBACJ,SACA,UACwB;IACxB,MAAM,uBAAO,IAAI,IAAoB;IACrC,KAAK,MAAM,CAAC,KAAK,UAAU,SAAS;KAClC,MAAM,KAAK,OAAO,IAAI,MAAM,GAAG,IAAI,QAAQ,GAAG,CAAC,CAAC;KAChD,IAAI,OAAO,OAAO;KAElB,KAAK,IAAI,KAAK,QAAQ,IAAI,QAAQ,QAAQ,OAAO,KAAK,CAAC,CAAC,IAAI,KAAK,KAAK;IACxE;IACA,OAAO;GACT;GAEA,MAAM,kBAAkB,UAAwB;IAC9C,aAAa,YAAY;KACvB,MAAM,OAAO,IAAI,IAAI,OAAO;KAC5B,IAAI,CAAC,KAAK,OAAO,KAAK,GAAG,KAAK,IAAI,KAAK;KACvC,OAAO;IACT,CAAC;GACH;GAEA,MAAM,SAAS,OAAe,SAA4D;IACxF,SAAS,OAAO,KAAK,OAAO,OAAO;KACjC,IAAI,OAAO,OAAO,OAAO;KAMzB,MAAM,UAAU,IAAI,IAClB,OAAO,QAAQ,IAAI,CAAC,CAAC,QAAQ,GAAG,WAAW,UAAU,KAAA,KAAa,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,GAAG,CACpG;KACA,OAAO,OAAO,YACZ,OAAO,QAAQ;MAAE,GAAG;MAAO,GAAG;KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,IAAI,GAAG,CAAC,CAC3E;IACF,CAAC,CAAC;GACJ;GAEA,MAAM,cAAc,YAA2B;IAC7C,QAAQ,IAAI;IACZ,WAAW,KAAA,CAAS;IACpB,IAAI;KACF,MAAM,SAAS,MAAM,WAAW,eAAe,MAAM,YAAY;MAC/D,GAAG,MAAM,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU,MAAM,SAAS;MAClE,GAAG,MAAM,YAAY,KAAA,KAAa,MAAM,QAAQ,WAAW,IAAI,CAAC,IAAI,EAAE,SAAS,MAAM,QAAQ;MAC7F,GAAG,MAAM,QAAQ,KAAA,IAAY,CAAC,IAAI,EAAE,KAAK,MAAM,IAAI;MACnD,GAAG,MAAM,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,MAAM,OAAO;KAC9D,CAAC;KACD,IAAI,OAAO,SAAS,WAAW;MAC7B,WAAW,OAAO,OAAO;MACzB;KACF;KACA,MAAM,QAAQ,OAAO;KACrB,IAAI,MAAM,WAAW,GAAG;MACtB,WAAW,EAAE,YAAY,CAAC;MAC1B;KACF;KAGA,MAAM,QAAQ,IAAI,IAAI,OAAO,KAAI,UAAS,OAAO,OAAO,IAAI,CAAC,CAAC;KAC9D,kBAAkB,EAAE;KACpB,cAAc,KAAK;KACnB,UAAU,IAAI,IAAI,MAAM,QAAO,UAAS,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC,CAAC,CAAC,KAAI,UAAS,MAAM,EAAE,CAAC,CAAC;IACvF,UAAU;KACR,QAAQ,KAAK;IACf;GACF;GAEA,MAAM,oBAA0B;IAC9B,cAAc,KAAA,CAAS;IACvB,0BAAU,IAAI,IAAI,CAAC;IACnB,kBAAkB,EAAE;GACtB;GAEA,MAAM,oBAA0B;;IAE9B,IAAI,eAAe,KAAA,GAAW;IAC9B,MAAM,OAAO,IAAI,IAAI,OAAO,KAAI,UAAS,CAAC,OAAO,OAAO,IAAI,GAAG,KAAK,CAAC,CAAC;IACtE,KAAK,MAAM,aAAa,YAAY;KAClC,IAAI,CAAC,OAAO,IAAI,UAAU,EAAE,GAAG;KAK/B,KAAK,IAAI,UAAU,IAAI,KAAK,IAAI,UAAU,EAAE,KAAK,MAAM,SAAS,CAAC;IACnE;IACA,SAAS,CAAC,GAAG,KAAK,OAAO,CAAC,CAAC;IAC3B,YAAY;GACd;GAEA,MAAM,UAAU,OAAqB;IACnC,WAAW,YAAY;KACrB,MAAM,OAAO,IAAI,IAAI,OAAO;KAC5B,IAAI,CAAC,KAAK,OAAO,EAAE,GAAG,KAAK,IAAI,EAAE;KACjC,OAAO;IACT,CAAC;GACH;GAEA,MAAM,mBAAmB,cAAc,CAAC;GACxC,MAAM,2BAA2B,eAAe,KAAK,CAAC,CAAC,YAAY;GACnE,MAAM,oBAAoB,yBAAyB,WAAW,IAC1D,mBACA,iBAAiB,QAAO,cAAa,UAAU,GAAG,YAAY,CAAC,CAAC,SAAS,wBAAwB,KAC9F,UAAU,MAAM,YAAY,CAAC,CAAC,SAAS,wBAAwB,MAAM,IAAI;GAChF,MAAM,6BAA6B,kBAAkB,SAAS,KACzD,kBAAkB,OAAM,cAAa,OAAO,IAAI,UAAU,EAAE,CAAC;GAElE,MAAM,gCAAsC;IAC1C,WAAW,YAAY;KACrB,MAAM,OAAO,IAAI,IAAI,OAAO;KAC5B,IAAI,kBAAkB,OAAM,cAAa,QAAQ,IAAI,UAAU,EAAE,CAAC,GAChE,KAAK,MAAM,aAAa,mBAAmB,KAAK,OAAO,UAAU,EAAE;UAEnE,KAAK,MAAM,aAAa,mBAAmB,KAAK,IAAI,UAAU,EAAE;KAElE,OAAO;IACT,CAAC;GACH;GAIA,MAAM,UAAU,MAAM,aAAa,KAAA,KAAc,MAAM,YAAY,KAAA,KAAa,MAAM,QAAQ,SAAS;GACvG,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;IAAS,WAAWC,iCAAO;IAAiB,cAAY,EAAE,QAAQ;IAAlE,UAAA;KACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,iCAAO;MAAvB,UAAA;OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,iCAAO;QAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWA,iCAAO;SAAuB,UAAA,EAAE,QAAQ;QAAQ,CAAA,GAChE,MAAM,eAAe,KAAA,IAClB,OAEA,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWA,iCAAO;SACrB,UAAA,MAAM,aAAa,EAAE,kBAAkB,IAAI,EAAE,iBAAiB;QAC3D,CAAA,CAEP;;OACJ,MAAM,eAAe,QAAQ,MAAM,YAAY,KAAA,IAE5C,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QACE,MAAK;QACL,WAAWA,iCAAO;QACR;QACV,SAAS,MAAM;QAEd,UAAA,EAAE,aAAa;OACV,CAAA,IAER;OACJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QACE,MAAK;QACL,WAAWA,iCAAO;QAClB,UAAU,YAAY,QAAQ,CAAC,WAAW,MAAM,iBAAiB,KAAA;QACjE,OAAO,MAAM,iBAAiB,KAAA,IAC1B,EAAE,MAAM,YAAY,IACpB,UAAU,KAAA,IAAY,EAAE,mBAAmB;QAC/C,eAAe;SAAE,YAAiB;QAAE;QAEnC,UAAA,OAAO,EAAE,UAAU,IAAI,EAAE,aAAa;OACjC,CAAA;MACL;;KACJ,OAAO,WAAW,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,iCAAO;MAAgB,UAAA,EAAE,aAAa;KAAK,CAAA,IAAI;KACnF,OAAO,KAAK,OAAO,UAClB,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAiB,WAAWA,iCAAO;MAAnC,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,iCAAO;OAAvB,UAAA;QACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SACE,WAAWA,iCAAO;SAClB,MAAK;SACL,OAAO,OAAO,OAAO,IAAI;SACzB,aAAa,EAAE,SAAS;SACxB,cAAY,GAAG,EAAE,SAAS,EAAE,GAAG,QAAQ;SAC7B;SACV,WAAW,UAAU;UAAE,MAAM,OAAO,EAAE,IAAI,MAAM,OAAO,MAAM,CAAC;SAAE;QACjE,CAAA;QACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SACE,WAAWA,iCAAO;SAClB,MAAK;SACL,OAAO,OAAO,OAAO,MAAM;SAC3B,aAAa,EAAE,WAAW;SAC1B,cAAY,GAAG,EAAE,WAAW,EAAE,GAAG,QAAQ;SAC/B;SACV,WAAW,UAAU;UAAE,MAAM,OAAO,EAAE,MAAM,MAAM,OAAO,UAAU,KAAK,KAAA,IAAY,MAAM,OAAO,MAAM,CAAC;SAAE;QAC3G,CAAA;QACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SACE,MAAK;SACL,WAAWA,iCAAO;SAClB,cAAY,GAAG,EAAE,eAAe,EAAE,GAAG,QAAQ;SAC7C,iBAAe,SAAS,IAAI,KAAK;SACjC,OAAO,EAAE,eAAe;SACxB,eAAe;UAAE,eAAe,KAAK;SAAE;SAEvC,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD,EAAa,MAAM,SAAS,IAAI,KAAK,EAAI,CAAA;QACnC,CAAA;QACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SACE,MAAK;SACL,WAAW,GAAGA,iCAAO,cAAc,GAAGA,iCAAO;SAC7C,cAAY,GAAG,EAAE,aAAa,EAAE,GAAG,QAAQ;SAC3C,OAAO,EAAE,aAAa;SACZ;SACV,eAAe;UACb,SAAS,OAAO,QAAQ,QAAQ,OAAO,OAAO,KAAK,CAAC;UAKpD,aAAa,YAAY;WACvB,MAAM,uBAAO,IAAI,IAAY;WAC7B,KAAK,MAAM,MAAM,SACf,IAAI,KAAK,OAAO,KAAK,IAAI,EAAE;gBACtB,IAAI,KAAK,OAAO,KAAK,IAAI,KAAK,CAAC;WAEtC,OAAO;UACT,CAAC;UACD,YAAW,YAAW,gBAAgB,SAAS,KAAK,CAAC;SACvD;SAEA,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,WAAD,CAAY,CAAA;QACN,CAAA;OACL;MACJ,CAAA,GAAA,SAAS,IAAI,KAAK,IAEf,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CAOE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,iCAAO;OAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;QAAO,WAAWA,iCAAO;QAAzB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWA,iCAAO;SAAqB,UAAA,EAAE,oBAAoB;QAAQ,CAAA,GAC3E,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SACE,WAAWA,iCAAO;SAClB,MAAK;SACL,WAAU;SACV,OAAO,aAAa,OAAO,OAAO,eAAe;SACjD,aAAa,cAAc;SAC3B,cAAY,GAAG,EAAE,oBAAoB,EAAE,GAAG,QAAQ;SACxC;SACV,WAAW,UAAU;UAAE,aAAa,OAAO,iBAAiB,MAAM,OAAO,KAAK;SAAE;QACjF,CAAA,CACI;OACP,CAAA,GAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;QAAO,WAAWA,iCAAO;QAAzB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWA,iCAAO;SAAqB,UAAA,EAAE,gBAAgB;QAAQ,CAAA,GACvE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SACE,WAAWA,iCAAO;SAClB,MAAK;SACL,WAAU;SACV,OAAO,aAAa,OAAO,OAAO,WAAW;SAC7C,aAAa,cAAc;SAC3B,cAAY,GAAG,EAAE,gBAAgB,EAAE,GAAG,QAAQ;SACpC;SACV,WAAW,UAAU;UAAE,aAAa,OAAO,aAAa,MAAM,OAAO,KAAK;SAAE;QAC7E,CAAA,CACI;OACJ,CAAA,CAAA;MAIL,CAAA,GAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAWA,iCAAO;OACrB,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,sBAAD;QACS;QACP,WAAW,SAAS;SAAE,MAAM,OAAO,IAAI;QAAE;QAC/B;OACX,CAAA;MACE,CAAA,CACL,EAAA,CAAA,IAEF,IACD;KA1GK,GAAA,KA0GL,CACN;KACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;MACE,MAAK;MACL,WAAWA,iCAAO;MACR;MACV,eAAe;OAAE,SAAS,CAAC,GAAG,QAAQ,EAAE,IAAI,GAAG,CAAC,CAAC;MAAE;MAElD,UAAA,EAAE,UAAU;KACP,CAAA;KACP,YAAY,KAAA,IAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,iCAAO;MAAW,UAAA;KAAW,CAAA,IAAI;KACxE,iBAAA,GAAA,kBAAA,KAAA,CAACC,sCAAAA,OAAD;MACE,MAAM,eAAe,KAAA;MACrB,SAAS;MACT,OAAO,EAAE,YAAY;MACrB,YAAY,EAAE,OAAO;MACrB,aAAa,EAAE,kBAAkB;MACjC,WAAWD,iCAAO;MAClB,QACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAACE,sCAAAA,QAAD;OAAQ,SAAQ;OAAU,SAAS;OAAc,UAAA,EAAE,QAAQ;MAAU,CAAA,GACrE,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;OAAQ,SAAQ;OAAU,SAAS;OAAc,UAAA,EAAE,YAAY;MAAU,CAAA,CACzE,EAAA,CAAA;MAXN,UAAA,CAcE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWF,iCAAO;OAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;QACE,WAAW,GAAGA,iCAAO,SAAS,GAAGA,iCAAO;QACxC,MAAK;QACL,OAAO;QACP,aAAa,EAAE,aAAa;QAC5B,cAAY,EAAE,aAAa;QAC3B,WAAW,UAAU;SAAE,kBAAkB,MAAM,OAAO,KAAK;QAAE;OAC9D,CAAA,GACD,iBAAA,GAAA,kBAAA,IAAA,CAACE,sCAAAA,QAAD;QACE,SAAQ;QACR,MAAK;QACL,UAAU,kBAAkB,WAAW;QACvC,SAAS;QAER,UAAA,EAAE,6BAA6B,qBAAqB,gBAAgB;OAC/D,CAAA,CACL;MACJ,CAAA,GAAA,kBAAkB,WAAW,IAC1B,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;OAAG,WAAWF,iCAAO;OAAmB,MAAK;OAAU,UAAA,EAAE,gBAAgB;MAAK,CAAA,IAE9E,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;OAAI,WAAWA,iCAAO;OACnB,UAAA,kBAAkB,KAAI,cACrB,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;QAAuB,WAAWA,iCAAO;QACvC,UAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;SAAO,WAAWA,iCAAO;SAAzB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;UACE,MAAK;UACL,SAAS,OAAO,IAAI,UAAU,EAAE;UAChC,gBAAgB;WAAE,OAAO,UAAU,EAAE;UAAE;SACxC,CAAA,GAID,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,iCAAO;UAAiB,UAAA,UAAU;SAAS,CAAA,CACvD;;OACL,GAZK,UAAU,EAYf,CACL;MACC,CAAA,CAEH;;IACA;;EAEb;;;;;;;EC5fA,MAAM,cAAc;;;;;;;EAkBpB,SAAgB,sBACd,YACA,WAC0B;GAC1B,MAAM,SAAS,IAAI,IAAI,WAAW,KAAI,aAAY,SAAS,EAAE,CAAC;GAC9D,MAAM,WAAW,IAAI,IAAI,UAAU,KAAI,UAAS,MAAM,QAAQ,CAAC;GAC/D,MAAM,OAAiC,UAAU,KAAI,WAAU;IAC7D,UAAU,MAAM;IAChB,aAAa,MAAM;IACnB,YAAY,MAAM;IAClB,cAAc,CAAC,GAAG,MAAM,YAAY;IACpC,QAAQ,OAAO,IAAI,MAAM,QAAQ;IACjC,GAAG,MAAM,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU,MAAM,SAAS;GACpE,EAAE;GACF,KAAK,MAAM,YAAY,YAAY;IACjC,IAAI,SAAS,IAAI,SAAS,EAAE,GAAG;IAC/B,KAAK,KAAK;KACR,UAAU,SAAS;KACnB,aAAa,SAAS;KACtB,YAAY;KACZ,cAAc,CAAC;KACf,QAAQ;IACV,CAAC;GACH;GACA,OAAO;EACT;;;;;;;;EA6CA,SAAgB,aAAa,UAA0B;GACrD,OAAO,GAAG,SAAS,YAAY,CAAC,CAAC,QAAQ,eAAe,GAAG,EAAE;EAC/D;;;;;;;;;;EAWA,SAAgB,gBACd,WACA,QACU;GACV,IAAI,cAAc,KAAA,GAAW,OAAO,CAAC;GAErC,MAAM,OADO,OAAO,WAAW,OAAO,UAAU,UAAU,MAAM,GAAG;IAAC;IAAa;IAAa;GAAK,CAClF;GACjB,IAAI,MAAM,SAAS,WAAW,KAAK,SAAS,KAAA,GAAW,OAAO,CAAC;GAC/D,OAAO,KAAK,KAAK,KAAI,UAAS,MAAM,KAAK,CAAC,CAAC,QAAQ,UAA2B,OAAO,UAAU,QAAQ;EACzG;;EAGA,SAAS,YACP,WACA,MACA,QACoB;GACpB,IAAI,cAAc,KAAA,GAAW,OAAO,KAAA;GACpC,MAAM,UAAU,OAAO,QAAQ,UAAU,OAAO,IAAI;GACpD,IAAI,OAAO,YAAY,YAAY,YAAY,MAAM,OAAO,KAAA;GAC5D,MAAM,MAAO,QAAoC;GACjD,OAAO,OAAO,QAAQ,YAAY,IAAI,SAAS,IAAI,MAAM,KAAA;EAC3D;;EAGA,IAAa,sBAAb,MAAiC;GAgBZ;GACA;GACA;;GAhBnB,SAAS,GAA4CG,8BAAAA,oBAAAA,CAAyC;IAC5F,QAAQ;IAAQ,OAAO;IAAM,iBAAiB;IAAM,UAAU;IAAO,MAAM,CAAC;IAAG,4BAAY,IAAI,IAAI;GACrG,CAAC;;GAGD,aAAqB;;;;;;;GAQrB,YACE,KACA,QACA,cACA;IAHiB,KAAA,MAAA;IACA,KAAA,SAAA;IACA,KAAA,eAAA;GAChB;;;;;;;;;GAUH,MAAM,OAAsB;IAC1B,MAAM,aAAa,EAAE,KAAK;IAC1B,KAAK,MAAM,QAAQ,MAAM;KAAE,EAAE,SAAS;KAAW,EAAE,QAAQ;IAAK,CAAC;IACjE,MAAM,CAAC,YAAY,YAAY,MAAM,QAAQ,IAAI;KAC/C,KAAK,IAAI,OAAO,IAAI,cAAc;KAClC,KAAK,IAAI,OAAO,IAAI,0BAA0B;KAC9C,KAAK,aAAa,OAAO;IAC3B,CAAC;IACD,IAAI,CAAC,WAAW,IAAI;KAAE,KAAK,SAAS,YAAY,WAAW,MAAM,OAAO;KAAG;IAAO;IAClF,IAAI,CAAC,SAAS,IAAI;KAAE,KAAK,SAAS,YAAY,SAAS,MAAM,OAAO;KAAG;IAAO;IAC9E,MAAM,WAAW,KAAK,aAAa,YAAY;IAC/C,IAAI,SAAS,SAAS,KAAA,GAAW;KAC/B,KAAK,SAAS,YAAY,SAAS,SAAS,0CAA0C;KACtF;IACF;IACA,MAAM,YAAY,sBAAsB,WAAW,OAAO,SAAS,KAAK;IACxE,MAAM,WAAW,SAAS,KAAK;IAC/B,MAAM,QAA0C,SAAS,KAAK;IAC9D,MAAM,aAAa,IAAI,IAAI,MAAM,KAAI,SAAQ,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC;IAC7D,MAAM,OAAsB,UAAU,KAAK,UAAU;KACnD,MAAM,YAAY,WAAW,IAAI,MAAM,UAAU;KAOjD,OAAO;MACL;MACA,YARiB,cAAc,KAAA,MAC3B,MAAM,aAAa,WAAW,KAAK,KAAK,OAAO,QAAQ,UAAU,OAAO,MAAM,YAAY,MAAM,KAAA;MAQpG,WAPgB,cAAc,KAAA,KAC3B,MAAM,aAAa,SAAS,KAC5B,KAAK,OAAO,QAAQ,UAAU,MAAM,MAAM,YAAY,KACtD,CAAC,KAAK,OAAO,QAAQ,UAAU,MAAM,MAAM,YAAY;MAK1D,WAAW,YAAY,WAAW,MAAM,cAAc,KAAK,MAAM;MACjE,YAAY,KAAA;KACd;IACF,CAAC;IACD,MAAM,OAAO,CAAC,GAAG,IAAI,IAAI,KAAK,KAAI,QAAO,IAAI,aAAa,aAAa,IAAI,MAAM,QAAQ,CAAC,CAAC,CAAC;IAC5F,IAAI,cAA8C,CAAC;IACnD,IAAI,kBAAiC;IACrC,IAAI,KAAK,SAAS,GAAG;KACnB,MAAM,WAAW,MAAM,KAAK,IAAI,OAAO,YAAY,SAAS,IAAI;KAIhE,IAAI,SAAS,IAAI,cAAc,SAAS;UACnC,kBAAkB,SAAS,MAAM;IACxC;IACA,IAAI,eAAe,KAAK,YAAY;IACpC,KAAK,MAAM,QAAQ,MAAM;KACvB,EAAE,SAAS;KACX,EAAE,QAAQ;KACV,EAAE,kBAAkB;KACpB,EAAE,WAAW;KACb,EAAE,OAAO,KAAK,KAAK,QAAQ;MACzB,MAAM,QAAQ,IAAI,cAAc,KAAA,IAAY,KAAA,IAAY,YAAY,IAAI;MACxE,MAAM,UAAU,IAAI,cAAc,KAAA,IAAY,KAAA,IAAY,YAAY,aAAa,IAAI,MAAM,QAAQ;MACrG,OAAO;OACL,GAAG;OACH,GAAG,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,YAAY,MAAM;OAClD,GAAG,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,mBAAmB,QAAQ;MAC/D;KACF,CAAC;KACD,EAAE,aAAa;IACjB,CAAC;GACH;;GAGA,SAAiB,YAAoB,SAAuB;IAC1D,IAAI,eAAe,KAAK,YAAY;IACpC,KAAK,MAAM,QAAQ,MAAM;KACvB,EAAE,SAAS;KACX,EAAE,QAAQ;IACZ,CAAC;GACH;EACF;;;;;;;;;;;EAYA,SAAgB,eAAe,KAA2B;GACxD,IAAI,CAAC,IAAI,MAAM,QAAQ,OAAO;GAC9B,IAAI,IAAI,cAAc,KAAA,GAAW,OAAO;GACxC,OAAO,IAAI,YAAY,eAAe;EACxC;;;;;;;;;;;;;;;;;;;;;;;;;;ECrOA,MAAM,KAAK;;;;;;;;;EAUX,MAAM,gBAAgB;;;;;;EA6BtB,SAAgB,mBAAmB,OAA2C;GAC5E,MAAM,EAAE,OAAO,WAAW,YAAY,MAAM;GAE5C,MAAM,CAAC,aAAA,GAAYC,MAAAA,SAAAA,OAAe,MAAM,QAAQ;GAChD,MAAM,CAAC,OAAO,aAAA,GAAYA,MAAAA,SAAAA,CAAS,EAAE;GACrC,MAAM,CAAC,aAAa,mBAAA,GAAkBA,MAAAA,SAAAA,CAAS,EAAE;GACjD,MAAM,CAAC,SAAS,eAAA,GAAcA,MAAAA,SAAAA,CAAS,EAAE;GACzC,MAAM,CAAC,UAAU,gBAAA,GAAeA,MAAAA,SAAAA,CAAS,UAAU,MAAM,EAAE;GAC3D,MAAM,CAAC,UAAU,gBAAA,GAAeA,MAAAA,SAAAA,CAAS,EAAE;GAC3C,MAAM,CAAC,QAAQ,cAAA,GAAaA,MAAAA,SAAAA,CAAgC,CAAC,CAAC;GAC9D,MAAM,CAAC,MAAM,YAAA,GAAWA,MAAAA,SAAAA,CAAS,KAAK;GACtC,MAAM,CAAC,SAAS,eAAA,GAAcA,MAAAA,SAAAA,CAA6B,KAAA,CAAS;;;;;;GAMpE,MAAM,CAAC,WAAW,iBAAA,GAAgBA,MAAAA,SAAAA,CAAS,KAAK;GAChD,MAAM,WAAW,MAAM,YAAY;;GAEnC,MAAM,kBAAkB,YAAY;GAEpC,MAAM,eAAe,MAAM,SAAS,KAAK,CAAC,cAAc,KAAK,KAAK;GAClE,MAAM,aAAa,MAAM,SAAS,KAAK;GAIvC,MAAM,eAAe,uBAAuB,MAAM;GAClD,MAAM,aAAa,cAAc,QAAQ;GAIzC,MAAM,WAAW,SAAS,KAAK;GAC/B,MAAM,QAAQ,MAAM,SAAS,KAAK,CAAC,gBAAgB,CAAC,cAC/C,QAAQ,SAAS,KAAK,OAAO,SAAS,KAAK,iBAAiB,KAAA,KAC5D,eAAe,KAAA;GAGpB,MAAM,OAAO,YAAY,KAAA,KAAa,SAIjC,eAAe,KAAA,KAIf,MAAM,WAAW,KAAK,gBAAgB,aACvC,KAAA,IACA,QAAQ,WAAW,IACjB,EAAE,oBAAoB,IACtB,iBAAiB,KAAA,IACf,GAAG,EAAE,OAAO,EAAE,GAAG,OAAO,aAAa,QAAQ,CAAC,EAAE,IAAI,EAAE,aAAa,GAAG,MACtE,EAAE,mBAAmB;;GAG7B,MAAM,aAAa,YAAyC;IAC1D,MAAM,SAAS,aAAa,KAAK;IACjC,MAAM,YAAY,SAAS,SAAS;IACpC,IAAI,CAAC,WAAW;KACd,MAAM,UAAU;MACd,GAAG,YAAY,WAAW,IAAI,CAAC,IAAI,EAAE,YAAY;MAKjD,GAAG,YAAY,EAAE,WAAW,OAAO,IAAI,CAAC;MACxC,KAAK;MACL;MACA,QAAQ,OAAO,KAAI,WAAU,EAAE,GAAG,MAAM,EAAE;KAC5C;KAIA,MAAM,UAAU,MAAM,WAAW,cAC/B,IACA,CAAC;MAAE,IAAI;MAAO,MAAM,CAAC,aAAa,KAAK;MAAG,OAAO;KAAqB,CAAC,GACvE,QACF;KACA,IAAI,QAAQ,SAAS,WACnB,OAAO,QAAQ,SAAS,aAAa,EAAE,UAAU,IAAI,QAAQ;KAM/D,aAAa,IAAI;IACnB;IACA,IAAI,WAAW;KACb,MAAM,SAAS,MAAM,WAAW,gBAAgB,QAAQ,QAAQ;KAGhE,IAAI,WAAW,KAAA,GAAW,OAAO;IACnC;GAEF;GAEA,MAAM,SAAS,YAA2B;IACxC,QAAQ,IAAI;IACZ,WAAW,KAAA,CAAS;IACpB,IAAI;KACF,MAAM,UAAU,MAAM,WAAW;KACjC,IAAI,YAAY,KAAA,GAAW;MACzB,WAAW,OAAO;MAClB;KACF;KACA,MAAM,QAAQ,IAAI;IACpB,UAAU;KACR,QAAQ,KAAK;IACf;GACF;GAEA,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWC,6BAAO;IAAvB,UAAA;KACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWA,6BAAO;MACrB,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,WAAWA,6BAAO;OAAiB,UAAA,EAAE,aAAa;MAAQ,CAAA;KAC7D,CAAA;KACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,6BAAO;MAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,WAAWA,6BAAO;OAAgB,UAAA,EAAE,aAAa;MAAQ,CAAA,GAC/D,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;OACE,WAAWA,6BAAO;OAClB,MAAK;OACL,OAAO;OACP,aAAY;OACZ,cAAY,EAAE,aAAa;OAC3B,UAAU;OACV,WAAW,UAAU;QAAE,SAAS,MAAM,OAAO,KAAK;OAAE;MACrD,CAAA,CACE;;KAGJ,gBAAgB,aACb,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,6BAAO;MAAW,UAAA,EAAE,eAAe,uBAAuB,kBAAkB;KAAK,CAAA,IAC/F,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,6BAAO;MAAkB,UAAA,EAAE,iBAAiB;KAAK,CAAA;KACnE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,6BAAO;MAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,WAAWA,6BAAO;OAAgB,UAAA,EAAE,mBAAmB;MAAQ,CAAA,GACrE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;OACE,WAAWA,6BAAO;OAClB,MAAK;OACL,OAAO;OACP,aAAa,MAAM,WAAW,IAAI,EAAE,mBAAmB,IAAI;OAC3D,cAAY,EAAE,mBAAmB;OACjC,UAAU;OACV,WAAW,UAAU;QAAE,eAAe,MAAM,OAAO,KAAK;OAAE;MAC3D,CAAA,CACE;;KACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,6BAAO;MAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,WAAWA,6BAAO;OAAgB,UAAA,EAAE,SAAS;MAAQ,CAAA,GAC3D,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;OACE,WAAWA,6BAAO;OAClB,MAAK;OACL,OAAO;OACP,aAAa,EAAE,0BAA0B;OACzC,cAAY,EAAE,SAAS;OACvB,UAAU;OACV,WAAW,UAAU;QAAE,WAAW,MAAM,OAAO,KAAK;OAAE;MACvD,CAAA,CACE;;KACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,6BAAO;MAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,WAAWA,6BAAO;OAAgB,UAAA,EAAE,WAAW;MAAQ,CAAA,GAC7D,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OACE,WAAW,GAAGA,6BAAO,SAAS,GAAGA,6BAAO;OACxC,OAAO;OACP,cAAY,EAAE,WAAW;OACzB,UAAU;OACV,WAAW,UAAU;QAAE,YAAY,MAAM,OAAO,KAAK;OAAE;OAEtD,UAAA,UAAU,KAAI,WAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAqB,OAAO;QAAS,UAAA;OAAe,GAAvC,MAAuC,CAAC;MACxE,CAAA,CACL;;KACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,6BAAO;MAAvB,UAAA;OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,6BAAO;QAAgB,UAAA,EAAE,UAAU;OAAQ,CAAA;OAC5D,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;QACE,WAAWA,6BAAO;QAClB,MAAK;QACL,cAAa;QACb,OAAO;QACP,aAAa,EAAE,gBAAgB;QAC/B,cAAY,EAAE,UAAU;QACd;QACV,WAAW,UAAU;SAAE,YAAY,MAAM,OAAO,KAAK;QAAE;OACxD,CAAA;OAIA,eAAe,KAAA,IACZ,OACA,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;QAAG,WAAWA,6BAAO;QAAW,UAAA,EAAE,eAAe,aAAa,gBAAgB,UAAU;OAAK,CAAA;MAC9F;;KACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,iBAAD;MACU;MACR,UAAU;MACV,OAAO;OACL,YAAY;OACZ;OACA,KAAK;OACL,GAAG,SAAS,WAAW,IAAI,CAAC,IAAI,EAAE,QAAQ,SAAS;MACrD;MACA,cAAc,eAAe,aAAa,gBAAgB;MAC9C;MACT;MACH,UAAU;KACX,CAAA;KACA,YAAY,KAAA,IAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,6BAAO;MAAW,UAAA;KAAW,CAAA,IAAI;KAGvE,SAAS,KAAA,IAAY,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,6BAAO;MAAkB,UAAA;KAAQ,CAAA;KAC5E,iBAAA,GAAA,kBAAA,IAAA,CAAC,cAAD;MACK;MACG;MACN,gBAAgB,YAAY,CAAC;MAC7B,gBAAe;MACf,oBAAmB;MACnB,gBAAgB;OAAE,MAAM,QAAQ,SAAS;MAAE;MAC3C,gBAAgB;OAAE,OAAY;MAAE;KACjC,CAAA;IACE;;EAET;;;;;;;;;;;;;;;;;;;;;;;;;;ECxPA,MAAM,2BAA2B;;EA+CjC,SAAS,QACP,QACA,WACA,MACyB;GACzB,MAAM,UAAU,OAAO,QAAQ,UAAU,MAAM,IAAI;GACnD,IAAI,OAAO,YAAY,YAAY,YAAY,QAAQ,MAAM,QAAQ,OAAO,GAAG,OAAO,CAAC;GACvF,OAAO,gBAAgB,OAAO;EAChC;;;;;;;;;;;EAYA,SAAgB,QACd,MACA,QACA,OACsB;GACtB,MAAM,WAAW,OAAO,WAAW,YAAY,WAAW,QAAQ,CAAC,MAAM,QAAQ,MAAM,IACnF,SACA,CAAC;GACL,MAAM,MAA4B,CAAC;GACnC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,GAAG;IAChD,IAAI,KAAK,UAAU,SAAS,IAAI,MAAM,KAAK,UAAU,KAAK,GAAG;IAC7D,IAAI,KAAK;KAAE,IAAI;KAAO,MAAM,CAAC,GAAG,MAAM,GAAG;KAAU;IAAmB,CAAC;GACzE;GACA,KAAK,MAAM,OAAO,OAAO,KAAK,QAAQ,GACpC,IAAI,EAAE,OAAO,QAAQ,IAAI,KAAK;IAAE,IAAI;IAAS,MAAM,CAAC,GAAG,MAAM,GAAG;GAAE,CAAC;GAErE,OAAO;EACT;;EAGA,SAAS,SAAS,IAA0B;GAC1C,IAAI,OAAO,gBAAgB,OAAO;GAClC,IAAI,OAAO,aAAa,OAAO;GAC/B,OAAO;EACT;;EAGA,SAAS,OACP,QACA,WACA,MACA,UACQ;GACR,MAAM,UAAU,OAAO,QAAQ,UAAU,OAAO,IAAI;GACpD,MAAM,QAAQ,OAAO,YAAY,YAAY,YAAY,OACpD,QAAoC,YACrC,KAAA;GACJ,OAAO,OAAO,UAAU,YAAY,MAAM,SAAS,IAAI,QAAQ,aAAa,QAAQ;EACtF;;;;;;EAOA,SAAgB,eAAe,OAAuC;GACpE,MAAM,EAAE,WAAW,QAAQ,cAAc,YAAY,MAAM;GAC3D,MAAM,CAAC,OAAO,aAAA,GAAYC,MAAAA,SAAAA,OAAwC,QAAQ,QAAQ,WAAW,YAAY,CAAC;GAC1G,MAAM,CAAC,UAAU,gBAAA,GAAeA,MAAAA,SAAAA,CAAS,EAAE;GAC3C,MAAM,CAAC,UAAU,gBAAA,GAAeA,MAAAA,SAAAA,CAAqC,KAAA,CAAS;GAC9E,MAAM,CAAC,MAAM,YAAA,GAAWA,MAAAA,SAAAA,CAAS,KAAK;GACtC,MAAM,CAAC,SAAS,eAAA,GAAcA,MAAAA,SAAAA,CAA6B,KAAA,CAAS;GAIpE,MAAM,CAAC,mBAAmB,yBAAA,GAAwBA,MAAAA,SAAAA,OAC1C,OAAO,QAAQ,UAAU,MAAM,YAAY,CACnD;GACA,MAAM,CAAC,kBAAkB,wBAAA,GAAuBA,MAAAA,SAAAA,OAAe,UAAU,QAAQ;GACjF,MAAM,QAAA,GAAOC,MAAAA,QAAAA,OAAc,OAAO,UAAU,UAAU,MAAM,GAAG,CAAC,UAAU,QAAQ,MAAM,CAAC;GACzF,MAAM,QAAA,GAAOA,MAAAA,QAAAA,OAAc,OAAO,WAAW,MAAM,YAAY,GAAG;IAAC;IAAM;IAAQ;GAAY,CAAC;GAC9F,MAAM,WAAW,OAAO,QAAQ,UAAU,OAAO,YAAY;GAC7D,MAAM,WAAW,MAAM,YAAY;GACnC,MAAM,SAAS,SAAS,UAAU,EAAE;GACpC,MAAM,SAAS,OAAO,QAAQ,WAAW,cAAc,MAAM,QAAQ;GAKrE,MAAM,aAAA,GAAYA,MAAAA,QAAAA,OACV,WAAW,UAAU,gBAAgB,WAAW,MAAM,IAAI,CAAC,GACjE;IAAC;IAAQ;IAAW;GAAM,CAC5B;GAEA,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,IAAI,QAAQ;IACZ,YAAY,KAAA,CAAS;IAGrB,WAAgB,mBAAmB,MAAM,CAAC,CAAC,MAAM,cAAc;KAC7D,IAAI,OAAO;KACX,YAAY,SAAS;IACvB,CAAC;IACD,aAAa;KAAE,QAAQ;IAAK;GAC9B,GAAG,CAAC,YAAY,MAAM,CAAC;GAEvB,MAAM,YAAY,QAAiB,QAAoC;IACrE,MAAM,QAAQ,OAAO,QAAQ,QAAQ,CAAC,GAAG,CAAC;IAC1C,OAAO,OAAO,UAAU,YAAY,MAAM,KAAK,CAAC,CAAC,SAAS,IAAI,QAAQ,KAAA;GACxE;GACA,MAAM,YAAY,KAAa,SAAmC;IAKhE,MAAM,QAAQ,SAAS,KAAA,KAAa,KAAK,KAAK,CAAC,CAAC,WAAW,IAAI,KAAA,IAAY;IAC3E,UAAS,YAAW,UAAU,KAAA,IAC1B,OAAO,WAAW,SAAS,CAAC,GAAG,CAAC,IAChC,OAAO,QAAQ,SAAS,CAAC,GAAG,GAAG,KAAK,CAAC;GAC3C;GAIA,MAAM,eAAe,uBAAuB,OAAO,QAAQ,OAAO,CAAC,QAAQ,CAAC,CAAC;GAC7E,MAAM,aAAa,cAAc,QAAQ;GAKzC,MAAM,WAAW,SAAS,KAAK;GAK/B,MAAM,mBAJ4B,MAAM,uBAAuB,QAC1D,SAAS,SAAS,KAAK,SAAS,WAAW,IAC5C,gBACA,KAAA,MACiD;GAGrD,MAAM,WAAW,SAAS,OAAO,KAAK,KAAK,SAAS,UAAU,KAAK;GACnE,MAAM,eAAe,SAAS,OAAO,SAAS,KAAK,SAAS,UAAU,SAAS;GAC/E,MAAM,QAAQ;IACZ,YAAY,UAAU;IAGtB,UAAU,MAAM;IAChB,GAAG,iBAAiB,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,aAAa;IAC7D,GAAG,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,KAAK,SAAS;IACjD,GAAG,SAAS,WAAW,IAAI,CAAC,IAAI,EAAE,QAAQ,SAAS;GACrD;;;;;;;GAOA,MAAM,YAAY,YAAyC;IACzD,MAAM,KAAK,UAAU;IAGrB,MAAM,OAAO,WAAW,WAAW,SAAS,OAAO,WAAW,MAAM,KAAA,KAC/D,SAAS,UAAU,WAAW,MAAM,KAAA,KAAa,SAAS,SAAS,IACpE,OAAO,QAAQ,OAAO,CAAC,WAAW,GAAG,MAAM,IAC3C;IACJ,IAAI,MAAM,mBAAmB,MAAM;KAKjC,MAAM,UAAU,uBAAuB,OAAO,QAAQ,MAAM,CAAC,QAAQ,CAAC,CAAC;;KAEvE,IAAI,YAAY,KAAA,GACd,OAAO,GAAG,EAAE,OAAO,EAAE,GAAG,OAAO,QAAQ,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,GAAG;IAEvE;;IAEA,IAAI,MAAM,mBAAmB,QAAQ,SAAS,KAAA,KAAa,aAAa,WAAW,GAAG;KACpF,MAAM,eAAe,OAAO,SAAS,MAAM,IAAI;KAC/C,IAAI,iBAAiB,KAAA,GAAW,OAAO;IACzC;IACA,MAAM,4BAA4B,WAAW,WACxC,aAAa,KAAA,KACb,sBAAsB,KAAA,KACtB,OAAO,KAAK,IAAI,CAAC,CAAC,WAAW;IAClC,MAAM,MAA4B,MAAM,mBAAmB,OACvD,CAAC,IACD,4BACE,CAAC;KAAE,IAAI;KAAO,MAAM,CAAC,GAAG,YAAY;KAAG,OAAO,CAAC;IAAE,CAAC,IAClD,QAAQ,cAAc,mBAAmB,IAAI;IACnD,IAAI,IAAI,SAAS,GAAG;KAClB,MAAM,UAAU,MAAM,WAAW,cAAc,IAAI,KAAK,gBAAgB;KACxE,IAAI,QAAQ,SAAS,WAAW,OAAO,QAAQ,SAAS,aAAa,EAAE,UAAU,IAAI,QAAQ;KAC7F,qBAAqB,OAAO,QAAQ,QAAQ,KAAK,MAAM,YAAY,CAAC;KACpE,oBAAoB,QAAQ,KAAK,QAAQ;KACzC,SAAS,IAAI;IACf;IACA,IAAI,SAAS,SAAS,GAAG;KACvB,MAAM,SAAS,MAAM,WAAW,gBAAgB,QAAQ,QAAQ;KAChE,IAAI,WAAW,KAAA,GAAW,OAAO;IACnC;IACA,YAAY,EAAE;GAEhB;GAEA,MAAM,QAAQ,YAA2B;IACvC,QAAQ,IAAI;IACZ,WAAW,KAAA,CAAS;IACpB,IAAI;KACF,MAAM,UAAU,MAAM,UAAU;KAChC,IAAI,YAAY,KAAA,GAAW;MACzB,WAAW,OAAO;MAClB;KACF;KACA,MAAM,QAAQ,IAAI;IACpB,UAAU;KACR,QAAQ,KAAK;IACf;GACF;GAEA,IAAI,SAAS,KAAA,GAGX,OAAO,iBAAA,GAAA,kBAAA,KAAA,CAAC,KAAD;IAAG,WAAWC,6BAAO;IAArB,UAAA;KAAgC,MAAM;KAAS;KAAG,MAAM,EAAE,0BAA0B;IAAK;;GAGlG,MAAM,YAAY,UAAU,aAAa;;;;;;;;GASzC,MAAM,wBAAiC;IAErC,OADe,OAAO,QAAQ,UAAU,MAAM,CAAC,GAAG,cAAc,QAAQ,CAC5D,KAAK,OAAO,WAAW,MAAM,CAAC,GAAG,cAAc,QAAQ,CAAC,CAAC,EAAE,KAAK;GAC9E;;;;;;GAOA,MAAM,iBAAiB,WAA4C;IAIjE,MAAM,eAAe,WAAW,WAAW,MAAM,aAAa;IAC9D,MAAM,eAAe,OAAO,QAAQ,OAAO,CAAC,QAAQ,CAAC;IACrD,MAAM,mBAAmB,OAAO,QAAQ,OAAO,CAAC,QAAQ,CAAC;IACzD,MAAM,SAAS,YAAY,mBAAmB,eAAe,gBAAgB,CAAC;IAC9E,MAAM,uBAAuB,OAAO,QAAQ,UAAU,CAAC,sBAAsB,CAAC;IAC9E,MAAM,mBAAmB,OAAO,QAAQ,UAAU,CAAC,WAAW,CAAC;IAC/D,MAAM,iBAAiB,YACnB,EAAE,cAAc,IAChB,UAAU,eAAe,QAAQ,MAAM,uBAAuB,OAC5D,EAAE,WAAW,IACb,WAAW,UAAU,EAAE,sBAAsB,IAAI,EAAE,gBAAgB;;IAEzE,MAAM,eAAe;KACnB;KACA,YAAY;KACZ;KACA;KACA,WAAW,SAAoC;MAC7C,UAAS,YAAW,OAAO,QAAQ,SAAS,CAAC,QAAQ,GAAG,IAAI,CAAC;KAC/D;KACA,eAAe;MAAE,UAAS,YAAW,OAAO,WAAW,SAAS,CAAC,QAAQ,CAAC,CAAC;KAAE;IAC/E;IACA,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,WAAWA,6BAAO;KAAvB,UAAA;MACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,WAAWA,6BAAO;OAAgB,UAAA,EAAE,UAAU;MAAQ,CAAA;MAC5D,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;OACE,WAAWA,6BAAO;OAClB,MAAK;OACL,cAAa;OACb,OAAO;OACP,aAAa;OACb,cAAY,EAAE,UAAU;OACxB,gBAAc,oBAAoB,KAAA;OAClC,UAAU,MAAM,uBAAuB;OACvC,WAAW,MAAM,wBAAwB;OACzC,UAAU,YAAY;OACtB,WAAW,UAAU;QAAE,YAAY,MAAM,OAAO,KAAK;OAAE;MACxD,CAAA;MACA,oBAAoB,KAAA,IAAY,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;OAAG,WAAWA,6BAAO;OAAW,UAAA,EAAE,eAAe;MAAK,CAAA;KAC3F;IACJ,CAAA,GAAA,MAAM,mBAAmB,OAAO,OAAO,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;KAAS,WAAWA,6BAAO;KAA3B,UAAA,CACtC,iBAAA,GAAA,kBAAA,IAAA,CAAC,WAAD;MAAS,WAAWA,6BAAO;MAAuB,UAAA,EAAE,YAAY;KAAW,CAAA,GAC3E,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,6BAAO;MAAvB,UAAA;OAIG,eAEG,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,6BAAO;QAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWA,6BAAO;SAAgB,UAAA,EAAE,mBAAmB;QAAQ,CAAA,GACrE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SACE,WAAWA,6BAAO;SAClB,MAAK;SACL,OAAO,SAAS,OAAO,aAAa,KAAK;SAQzC,aAAa,SAAS,OAAO,QAAQ,UAAU,MAAM,YAAY,GAAG,aAAa,KAC5E,MAAM;SACX,cAAY,EAAE,mBAAmB;SACvB;SACV,WAAW,UAAU;UAAE,SAAS,eAAe,MAAM,OAAO,KAAK;SAAE;QACpE,CAAA,CACE;OAEL,CAAA,IAAA;OACJ,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,6BAAO;QAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWA,6BAAO;SAAgB,UAAA,EAAE,SAAS;QAAQ,CAAA,GAC3D,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SACE,WAAWA,6BAAO;SAClB,MAAK;SACL,OAAO,SAAS,OAAO,SAAS,KAAK;SACrC,aAAa,WAAW,aACpB,2BACA,SAAS,UAAU,SAAS,KAAK,EAAE,gBAAgB;SACvD,cAAY,EAAE,SAAS;SACb;SACV,WAAW,UAAU;UACnB,SAAS,WAAW,MAAM,OAAO,UAAU,KAAK,KAAA,IAAY,MAAM,OAAO,KAAK;SAChF;QACD,CAAA,CACE;;OAGJ,eAEG,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,6BAAO;QAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWA,6BAAO;SAAgB,UAAA,EAAE,WAAW;QAAQ,CAAA,GAC7D,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;SACE,WAAW,GAAGA,6BAAO,SAAS,GAAGA,6BAAO;SACxC,OAAO,YAAY;SACnB,cAAY,EAAE,WAAW;SACf;SACV,WAAW,UAAU;UAAE,SAAS,OAAO,MAAM,OAAO,KAAK;SAAE;SAL7D,UAAA,CAaG,aAAa,KAAA,IAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,OAAM;UAAI,UAAA,EAAE,gBAAgB;SAAU,CAAA,IAAI,MAC3E,UAAU,KAAI,WAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAqB,OAAO;UAAS,UAAA;SAAe,GAAvC,MAAuC,CAAC,CACxE;QACL,CAAA,CAAA;OAEL,CAAA,IAAA;OAIH,WAAW,aAER,iBAAA,GAAA,kBAAA,IAAA,CAAC,sBAAD;QACE,GAAI;QACJ,sBAAsB,OAAO,yBAAyB,WAClD,uBACA,KAAA;QACJ,kBAAkB,OAAO,qBAAqB,WAAW,mBAAmB,KAAA;OAC7E,CAAA,IAGD,iBAAA,GAAA,kBAAA,IAAA,CAAC,iBAAD;QACE,GAAI;QACG;QACP,cAAc;QACF;OACb,CAAA;MAEF;KACE,CAAA,CAAA;IACT,CAAA,CAAA,EAAA,CAAA;GAEN;GAEA,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAW,MAAM,mBAAmB,OAAOA,6BAAO,cAAcA,6BAAO;IAA5E,UAAA;KACG,MAAM,cAAc,OACjB,OAEA,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,6BAAO;MAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,WAAWA,6BAAO;OAAiB,UAAA,MAAM;MAAkB,CAAA,GAChE,MAAM,aAAa,MAAM,cACtB,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,WAAWA,6BAAO;OAAiB,UAAA,MAAM;MAAe,CAAA,IAC9D,IACD;;KAER,WAAW,YACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,6BAAO;MAAkB,UAAA,GAAG,EAAE,cAAc,EAAE,IAAI,UAAU,GAAG;KAAM,CAAA,IACnF,cAAc,MAAM;KACvB,YAAY,KAAA,IAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,6BAAO;MAAW,UAAA;KAAW,CAAA,IAAI;KACvE,MAAM,mBAAmB,QAAQ,iBAAiB,KAAA,IAC/C,OAEA,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,6BAAO;MAClB,UAAA,GAAG,EAAE,OAAO,EAAE,GAAG,OAAO,aAAa,QAAQ,CAAC,EAAE,IAAI,EAAE,aAAa,GAAG;KACtE,CAAA;KAEP,iBAAA,GAAA,kBAAA,IAAA,CAAC,cAAD;MACK;MACG;MACN,gBAAgB,YAAY,WAAW,aACjC,MAAM,mBAAmB,QAAQ,iBAAiB,KAAA,KACnD,oBAAoB,KAAA,KACnB,MAAM,uBAAuB,QAAQ,SAAS,WAAW;MAC/D,gBAAgB,MAAM,kBAAkB;MACxC,oBAAoB,MAAM,sBAAsB;MAChD,GAAI,MAAM,mBAAmB,KAAA,IAAY,CAAC,IAAI,EAAE,gBAAgB,MAAM,eAAe;MACrF,gBAAgB;OAAE,MAAM,QAAQ,KAAK;MAAE;MACvC,gBAAgB;OAAE,MAAW;MAAE;KAChC,CAAA;IACE;;EAET;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EClaA,SAAS,qBAAqB,EAAE,QAAQ,GAAG,SAA+C;GACxF,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,gBAAD;IACE,UAAU,OAAO;IACjB,aAAa,OAAO;IACpB,cAAc,OAAO;IACrB,GAAI,OAAO,aAAa,OAAO,EAAE,UAAU,KAAK,IAAI,CAAC;IACrD,GAAI;GACL,CAAA;EAEL;;;;;;;;;;;;EAaA,eAAsB,sBACpB,YACA,YACA,QAC6B;GAC7B,IAAI,OAAO,kBAAkB,KAAA,GAAW;IACtC,MAAM,aAAa,MAAM,WAAW,iBAAiB,OAAO,aAAa;IACzE,IAAI,eAAe,KAAA,GAAW,OAAO;GACvC;GACA,MAAM,UAAU,MAAM,WAAW,cAC/B,OAAO,YACP,CAAC;IAAE,IAAI;IAAS,MAAM,CAAC,GAAG,OAAO,YAAY;GAAE,CAAC,GAChD,KAAA,CACF;GACA,IAAI,QAAQ,SAAS,WAAW,OAAO,QAAQ;GAC/C,MAAM,WAAW,KAAK;EAExB;;;;;;;;;;EAWA,SAAgB,WAAW,KAAkB,WAA6B;GACxE,IAAI,WAAW,OAAO;GACtB,IAAI,IAAI,MAAM,aAAa,SAAS,GAAG,OAAO;GAC9C,OAAO,IAAI,YAAY,eAAe;EACxC;EAEA,SAAS,SAAS,KAAgC;GAChD,MAAM,aAAa,aAAa,IAAI,MAAM,QAAQ;GAClD,MAAM,gBAAgB,IAAI,cAAc,cACnC,IAAI,YAAY,eAAe,QAC/B,IAAI,WAAW,WAChB,aACA,KAAA;GACJ,OAAO;IACL,UAAU,IAAI,MAAM;IACpB,aAAa,IAAI,MAAM;IACvB,YAAY,IAAI,MAAM;IACtB,cAAc,IAAI,MAAM;IACxB,GAAG,kBAAkB,KAAA,IAAY,CAAC,IAAI,EAAE,cAAc;IAEtD,GAAG,IAAI,MAAM,aAAa,OAAO,EAAE,UAAU,KAAK,IAAI,CAAC;GACzD;EACF;;EAGA,SAAgB,oBAAoB,QAAkC;GACpE,OAAO,OAAO,aAAa,OAAO,cAC9B,OAAO,WACP,GAAG,OAAO,YAAY,IAAI,OAAO,SAAS;EAChD;;EAGA,SAAgB,aAAa,UAAkB,QAAkC;GAC/E,OAAO,SAAS,QAAQ,oBAAoB,oBAAoB,MAAM,CAAC;EACzE;;;;;;EAOA,SAAgB,cAAc,OAAsC;GAClE,MAAM,EAAE,YAAY,aAAa,YAAY,QAAQ,MAAM;GAC3D,IACE,eAAe,KAAA,KAAa,gBAAgB,KAAA,KAAa,eAAe,KAAA,KACrE,WAAW,KAAA,KAAa,MAAM,KAAA,GACjC,OAAO;GACT,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAQ,UAAU;IAAE;IAAY;IAAa;IAAY;IAAQ;GAAE,EAAI,CAAA;EAChF;EAEA,SAAS,OAAO,EAAE,YAAwD;GACxE,MAAM,EAAE,YAAY,YAAY,QAAQ,MAAM;GAC9C,MAAM,QAAQ,SAAS,aAAY,aAAY,QAAQ;GACvD,MAAM,CAAC,SAAS,eAAA,GAAcC,MAAAA,SAAAA,CAAmC,KAAA,CAAS;GAC1E,MAAM,CAAC,QAAQ,cAAA,GAAaA,MAAAA,SAAAA,CAAS,KAAK;GAC1C,MAAM,CAAC,cAAc,oBAAA,GAAmBA,MAAAA,SAAAA,CAAmC,KAAA,CAAS;GACpF,MAAM,CAAC,UAAU,gBAAA,GAAeA,MAAAA,SAAAA,CAAS,KAAK;GAC9C,MAAM,CAAC,eAAe,qBAAA,GAAoBA,MAAAA,SAAAA,CAA6B,KAAA,CAAS;GAChF,MAAM,CAAC,aAAa,mBAAA,GAAkBA,MAAAA,SAAAA,CAAuC,KAAA,CAAS;GACtF,MAAM,CAAC,WAAW,iBAAA,GAAgBA,MAAAA,SAAAA,CAAS,KAAK;GAChD,MAAM,CAAC,gBAAgB,sBAAA,GAAqBA,MAAAA,SAAAA,uBAAoC,IAAI,IAAI,CAAC;GAEzF,MAAM,iBAAiB,WAAmC;IAIxD,WAAgB,KAAK,CAAC,CAAC,WAAW;KAAE,eAAe,MAAM;IAAE,CAAC;GAC9D;GAEA,MAAM,eAAe,SAAkB,WAAmC;IACxE,WAAW,KAAA,CAAS;IACpB,UAAU,KAAK;IACf,aAAa,KAAK;IAClB,IAAI,SAAS,cAAc,MAAM;GACnC;;;;;;;;GASA,MAAM,cAAc,SAAkB,WAAmC;IACvE,mBAAkB,6BAAY,IAAI,IAAI,CAAC,GAAG,UAAU,OAAO,QAAQ,CAAC,CAAC;IACrE,IAAI,SAAS,cAAc,MAAM;GACnC;GAEA,MAAM,oBAA0B;IAC9B,IAAI,UAAU;IACd,gBAAgB,KAAA,CAAS;IACzB,iBAAiB,KAAA,CAAS;GAC5B;GAEA,MAAM,sBAA4B;;IAEhC,IAAI,iBAAiB,KAAA,KAAa,UAAU;IAC5C,YAAY,IAAI;IAChB,iBAAiB,KAAA,CAAS;IAC1B,sBAA2B,YAAY,YAAY,YAAY,CAAC,CAC7D,MAAM,YAAY;KACjB,IAAI,YAAY,KAAA,GAAW;MACzB,iBAAiB,OAAO;MACxB;KACF;KACA,gBAAgB,KAAA,CAAS;IAC3B,CAAC,CAAC,CACD,cAAc;KAAE,YAAY,KAAK;IAAE,CAAC;GACzC;GAEA,IAAI,MAAM,WAAW,QAAQ,WAAgB,KAAK;GAClD,IAAI,MAAM,WAAW,SAAS;;IAE5B,MAAM,YAAY,MAAM,SAAS;IACjC,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,WAAWC,iCAAO;KAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,iCAAO;MAAW,UAAA,GAAG,EAAE,YAAY,EAAE,IAAI;KAAe,CAAA,GACtE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;MAAQ,MAAK;MAAS,WAAWA,iCAAO;MAAoB,eAAe;OAAE,WAAgB,KAAK;MAAE;MACjG,UAAA,EAAE,OAAO;KACJ,CAAA,CACL;;GAET;GAMA,MAAM,WAAW,gBAAgB,KAAA,IAC7B,KAAA,IACA,MAAM,KAAK,MAAK,QAAO,IAAI,MAAM,aAAa,YAAY,QAAQ;GACtE,MAAM,gBAAgB,aAAa,KAAA,IAC/B,cACA;IAAE,UAAU,SAAS,MAAM;IAAU,aAAa,SAAS,MAAM;GAAY;GAIjF,MAAM,YAAY,MAAM,KAAK,KAAK,cAAc;GAChD,MAAM,aAAa,MAAM,KAAK,QAAO,QAAO,IAAI,UAAU;GAC1D,MAAM,UAAU,MAAM,KAAK,QAAO,QAAO,CAAC,IAAI,cAAc,IAAI,MAAM,eAAe,EAAE;GACvF,MAAM,YAAY,SAAS,UAAU,KAAA;GACrC,MAAM,eAAe,cAAc,KAAA,IAAY,KAAA,IAAY,MAAM,WAAW,IAAI,UAAU,UAAU;GAIpG,MAAM,YAAY,gBAAgB,MAAM,WAAW,IAAI,WAAW,GAAG,MAAM;GAE3E,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWA,iCAAO;IAAvB,UAAA;KACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;MAAI,WAAWA,iCAAO;MAAtB,UAAA,CACG,EAAE,OAAO,GAEV,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,WAAWA,iCAAO;OAAW,UAAA,MAAM,EAAE,gBAAgB,CAAC,CAAC,QAAQ,aAAa,eAAe;MAAU,CAAA,CACzG;;KACJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,iCAAO;MAAW,UAAA,EAAE,OAAO;KAAK,CAAA;KAC7C,CAAC,MAAM,YAAY,MAAM,WAAW,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,iCAAO;MAAY,UAAA,EAAE,UAAU;KAAK,CAAA,IAAI;KACpG,kBAAkB,KAAA,IACf,OAEA,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,iCAAO;MAAgB,MAAK;MAAS,aAAU;MAC1D,UAAA,aAAa,EAAE,eAAe,GAAG,aAAa;KAC9C,CAAA;KAEP,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;MAAI,WAAWA,iCAAO;MACnB,UAAA,WAAW,KAAK,QAAQ;OACvB,MAAM,SAAS,SAAS,GAAG;OAC3B,MAAM,YAAY,MAAM,WAAW,IAAI,OAAO,UAAU;;OAExD,IAAI,cAAc,KAAA,GAAW,OAAO;OACpC,IAAI,WAAW,KAAK,SAAS,KAAK,CAAC,eAAe,IAAI,IAAI,MAAM,QAAQ,GAGtE,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;QAA6B,WAAWA,iCAAO;QAC5C,UAAA,qBAAqB;SACpB;SACA;SACA;SACA;SACA;SACA,UAAU,CAAC,MAAM;SACjB,UAAU,YAAY;UAAE,WAAW,SAAS,MAAM;SAAE;QACtD,CAAC;OACC,GAVK,IAAI,MAAM,QAUf;OAGR,MAAM,OAAO,CAAC,UAAU,SAAS,aAAa,IAAI,MAAM;OACxD,MAAM,uBAAuB,IAAI,YAAY,eAAe;OAC5D,MAAM,oBAAoB,CAAC,wBACtB,IAAI,cAAc,KAAA,KAClB,IAAI,YAAY,eAAe;OACpC,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;QAA6B,WAAWA,iCAAO;QAA/C,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAK,WAAWA,iCAAO;SAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;UAAM,WAAWA,iCAAO;UAAxB,UAAA;WACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;YAAM,WAAWA,iCAAO;YAAa,UAAA,IAAI,MAAM;WAAkB,CAAA;WAIhE,IAAI,MAAM,aAAa,OACpB,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;YAAM,WAAWA,iCAAO;YAAY,UAAA,EAAE,WAAW;WAAQ,CAAA,IACzD;WACH,uBAEG,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;YACE,WAAW,GAAGA,iCAAO,iBAAiB,GAAGA,iCAAO;YAChD,MAAK;YACL,cAAY,EAAE,sBAAsB;YACpC,OAAO,EAAE,sBAAsB;WAChC,CAAA,IAED,oBAEE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;YACE,WAAW,GAAGA,iCAAO,iBAAiB,GAAGA,iCAAO;YAChD,MAAK;YACL,cAAY,EAAE,mBAAmB;YACjC,OAAO,EAAE,mBAAmB;WAC7B,CAAA,IAED;UACF;SACN,CAAA,GAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;UAAM,WAAWA,iCAAO;UAAxB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WACE,MAAK;WACL,WAAWA,iCAAO;WAClB,cAAY,aAAa,EAAE,cAAc,GAAG,MAAM;WAClD,eAAe;YACb,eAAe,KAAA,CAAS;YAIxB,aAAa,KAAK;YAClB,UAAU,KAAK;YACf,WAAW,OAAO,KAAA,IAAY,MAAM;WACtC;WAEC,UAAA,EAAE,MAAM;UACH,CAAA,GACP,IAAI,YAED,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WACE,MAAK;WACL,WAAWA,iCAAO;WAClB,cAAY,aAAa,EAAE,gBAAgB,GAAG,MAAM;WACpD,UAAU,CAAC,MAAM;WACjB,eAAe;YACb,eAAe,KAAA,CAAS;YACxB,iBAAiB,KAAA,CAAS;YAC1B,gBAAgB,MAAM;WACxB;WAEC,UAAA,EAAE,QAAQ;UACL,CAAA,IAER,IACA;SACH,CAAA,CAAA;QACJ,CAAA,GAAA,OACG,qBAAqB;SACrB;SACA;SACA;SACA;SACA;SACA,UAAU,CAAC,MAAM;SACjB,UAAU,YAAY;UAAE,YAAY,SAAS,MAAM;SAAE;QACvD,CAAC,IACC,IACF;OA7EK,GAAA,IAAI,MAAM,QA6Ef;MAER,CAAC;KACC,CAAA;KACJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWA,iCAAO;MACpB,UAAA,cAAc,KAAA,KAAa,iBAAiB,KAAA,IAEzC,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,iCAAO;OAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,iCAAO;QAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWA,iCAAO;SAAgB,UAAA,EAAE,UAAU;QAAQ,CAAA,GAC5D,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SACE,WAAW,GAAGA,iCAAO,SAAS,GAAGA,iCAAO;SACxC,OAAO,UAAU;SACjB,cAAY,EAAE,UAAU;SACxB,WAAW,UAAU;UACnB,MAAM,MAAM,QAAQ,MAAK,cAAa,UAAU,MAAM,aAAa,MAAM,OAAO,KAAK;;UAErF,IAAI,QAAQ,KAAA,GAAW;UACvB,WAAW,SAAS,GAAG,CAAC;SAC1B;SAEC,UAAA,QAAQ,KAAI,QACX,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAiC,OAAO,IAAI,MAAM;UAAW,UAAA,IAAI,MAAM;SAAoB,GAA9E,IAAI,MAAM,QAAoE,CAC5F;QACK,CAAA,CACL;OACL,CAAA,GAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,gBAAD;QAEE,UAAU,UAAU;QACpB,aAAa,UAAU;QACvB,WAAA;QACA,WAAW;QACH;QACR,cAAc,UAAU;QACZ;QACT;QACH,UAAU,CAAC,MAAM;QACjB,UAAU,YAAY;SAAE,YAAY,SAAS,SAAS;QAAE;OACzD,GAXM,UAAU,QAWhB,CACE;MAEL,CAAA,IAAA,YAEE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAWA,iCAAO;OACrB,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,oBAAD;QACE,OAAO,MAAM,KAAK,KAAI,QAAO,IAAI,MAAM,QAAQ;QACpC;;QAEX,UAAU,MAAM,WAAW,IAAI,WAAW,CAAC,EAAE,YAAY;QAC7C;QACT;QACH,UAAU,CAAC,MAAM;QACjB,UAAU,YAAY;SACpB,aAAa,KAAK;SAClB,IAAI,SAAS,WAAgB,KAAK;QACpC;OACD,CAAA;MACE,CAAA,IAOL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,iCAAO;OAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;QACE,MAAK;QACL,WAAWA,iCAAO;QAClB,UAAU,QAAQ,WAAW,KAAK,CAAC,MAAM;QACzC,eAAe;SACb,MAAM,QAAQ,QAAQ;;SAEtB,IAAI,UAAU,KAAA,GAAW;SACzB,eAAe,KAAA,CAAS;SACxB,aAAa,KAAK;SAClB,UAAU,IAAI;SACd,WAAW,SAAS,KAAK,CAAC;QAC5B;QAZF,UAAA,CAcE,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,mBAAD,EAAmB,MAAM,GAAK,CAAA,GAC7B,EAAE,KAAK,CACF;OACR,CAAA,GAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;QACE,MAAK;QACL,WAAWD,iCAAO;QAClB,UAAU,UAAU,WAAW,KAAK,CAAC,MAAM;QAC3C,eAAe;SACb,eAAe,KAAA,CAAS;SACxB,UAAU,KAAK;SACf,WAAW,KAAA,CAAS;SACpB,aAAa,IAAI;QACnB;QATF,UAAA,CAWE,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,mBAAD,EAAmB,MAAM,GAAK,CAAA,GAC7B,EAAE,WAAW,CACR;OACL,CAAA,CAAA;;KAER,CAAA;KACL,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,OAAD;MACE,MAAM,iBAAiB,KAAA;MACvB,SAAS;MACT,OAAO,iBAAiB,KAAA,IAAY,KAAK,aAAa,EAAE,aAAa,GAAG,YAAY;MACpF,YAAY,EAAE,OAAO;MACrB,aAAa,iBAAiB,KAAA,IAC1B,KACA,aACA,aAAa,kBAAkB,KAAA,IAC3B,EAAE,mBAAmB,IACrB,EAAE,iCAAiC,GACvC,YACF;MACF,WAAWF,iCAAO;MAClB,QACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAACG,sCAAAA,QAAD;OAAQ,SAAQ;OAAU,WAAA;OAAU,UAAU;OAAU,SAAS;OAC9D,UAAA,EAAE,QAAQ;MACL,CAAA,GACR,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;OACE,SAAQ;OACR,WAAWH,iCAAO;OAClB,UAAU;OACV,SAAS;OAER,UAAA,iBAAiB,KAAA,IACd,KACA,aAAa,WAAW,EAAE,UAAU,IAAI,EAAE,eAAe,GAAG,YAAY;MACtE,CAAA,CACR,EAAA,CAAA;MAGH,UAAA,kBAAkB,KAAA,IAAY,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;OAAG,WAAWA,iCAAO;OAAW,UAAA;MAAiB,CAAA;KAClF,CAAA;IACJ;;EAET;;;;;;;;;ECvdA,SAAgB,uBAAuB,KAAsC;GAC3E,OAAO;IACL,oBAAoB,OAAO,QAAQ;KACjC,MAAM,WAAW,MAAM,IAAI,OAAO,YAAY,SAAS,CAAC,GAAG,CAAC;KAC5D,OAAO,SAAS,KAAK,SAAS,MAAM,OAAO,KAAA;IAC7C;IACA,iBAAiB,OAAO,KAAK,UAAU;KACrC,MAAM,WAAW,MAAM,IAAI,OAAO,YAAY,IAAI,KAAK,KAAK;KAC5D,OAAO,SAAS,KAAK,KAAA,IAAY,SAAS,MAAM;IAClD;IACA,kBAAkB,OAAO,QAAQ;KAC/B,MAAM,WAAW,MAAM,IAAI,OAAO,YAAY,MAAM,GAAG;KACvD,OAAO,SAAS,KAAK,KAAA,IAAY,SAAS,MAAM;IAClD;IACA,eAAe,OAAO,IAAI,KAAK,qBAAqB;KAClD,MAAM,WAAW,MAAM,IAAI,OAAO,SAAS,OAAO,IAAI,KAAK,gBAAgB;KAC3E,IAAI,SAAS,IAAI,OAAO;MAAE,MAAM;MAAW,MAAM,SAAS;KAAM;KAChE,MAAM,EAAE,MAAM,YAAY,SAAS;KACnC,OAAO,SAAS,sBAAsB;MAAE,MAAM;MAAY;KAAQ,IAAI;MAAE,MAAM;MAAW;KAAQ;IACnG;IACA,gBAAgB,OAAO,YAAY,YAAY;KAC7C,MAAM,WAAW,MAAM,IAAI,OAAO,IAAI,eAAe,YAAY,OAAO;KACxE,OAAO,SAAS,KACZ;MAAE,MAAM;MAAS,QAAQ,SAAS;KAAM,IACxC;MAAE,MAAM;MAAW,SAAS,SAAS,MAAM;KAAQ;IACzD;GACF;EACF;;;;;;;;EC7FA,SAAgB,+BAA+B,SAA0D;GACvG,OAAO;IACL,YAAW,eAAc,QAAQ,UAAU,UAAU;IACrD,WAAW,QAAQ,UAAU,QAAQ,SAAS,QAAQ,KAAK;IAC3D,aAAa,MAAM,SAAS,QAAQ,WAAW,MAAM,IAAI;IACzD,UAAU,OAAO,SAAS,QAAQ,QAAQ,OAAO,IAAI;IACrD,UAAU,OAAO,SAAS,QAAQ,QAAQ,OAAO,IAAI;IACrD,UAAU,MAAM,MAAM,UAAU,QAAQ,QAAQ,MAAM,MAAM,KAAK;IACjE,aAAa,MAAM,SAAS,QAAQ,WAAW,MAAM,IAAI;GAC3D;EACF;;;;ECEA,MAAa,OAAO;;EAGpB,MAAa,SAAS;GACpB;GAAS;GAAU;GAAU;GAAsB;GAAc;GACjE;GAAiB;EACnB;;EAGA,SAAS,gBAAgB,YAAuC;GAC9D,IAAI,WAAW,MAAM,YAAY,CAAC,CAAC,WAAW,QAAQ;GACtD,WAAgB,KAAK;EACvB;;;;;EAMA,SAAgB,MAAM,KAA0B;GAI9C,MAAM,KAAK;GACX,IAAI,aAAa,IAAI,OAAO,SAAS,IAAI;IACvC,IAAI,EAAE,GAAGI,GAAY;IACrB,IAAI,EAAE,GAAGC,GAAY;GACvB,CAAC,GAAG,wCAAwC;GAE5C,MAAM,SAAS,+BAA+B,IAAI,cAAc;GAChE,MAAM,aAAa,uBAAuB,GAAG;GAC7C,MAAM,aAAa,IAAI,oBAAoB,KAAK,QAAQ,IAAI,cAAc,SAAS,CAAC;GAEpF,MAAM,IAAI,IAAI,OAAO,KAAK,EAAE;GAC5B,MAAM,kBAAyC;IAC7C;IACA,OAAO,EAAE,UAAU,WAAW,MAAM;IACpC;IACA;IACA;GACF;GAGA,IAAI,aAAa;IACf,MAAM,sBAA4B;KAAE,gBAAgB,UAAU;IAAE;IAChE,aAAa;KACX,IAAI,OAAO,IAAI,mCAAmC;MAAE,cAAc;KAAE,CAAC;KACrE,IAAI,OAAO,IAAI,iCAAiC,aAAa;KAC7D,IAAI,OAAO,IAAI,wBAAwB,aAAa;KACpD,IAAI,GAAG,oBAAoB,aAAa;IAC1C;GACF,GAAG,2CAA2C;GAE9C,IAAI,MAAM,OAAO,0BAA0B,IAAI,MAAM,SAAS;IAC5D,MAAM;IACN,IAAI;IACJ,OAAO;IACP,aAAa,EAAE,KAAK;IACpB,QAAQ;GACV,GAAG,aAAa,CAAC;EACnB"}
|
|
1
|
+
{"version":3,"file":"client.js","names":["createSnapshotStore","useState","styles","useState","styles","useState","styles","Modal","useState","useMemo","styles","useState","styles","useState","styles","Modal","extensionZh","extensionEn"],"sources":["official/src/client/vendor/store.ts","official/src/client/models-plus/models-index.ts","official/src/client/models-plus/compat.ts","official/src/client/models-plus/presets.ts","official/src/client/extension-meta.ts","official/src/client/models-plus/models-plus.module.css","official/src/client/models-plus/QuickLoad.tsx","official/src/client/models-plus/ModelEntryPanel.tsx","official/src/client/models-plus/ModelCatalog.tsx","official/src/client/models-plus/ProviderEditor.tsx","official/src/client/models-plus/CreateProviderCard.tsx","official/src/client/models-plus/ModelsPlusSection.tsx","official/src/client/vendor/operations.ts","official/src/client/vendor/schema-operations.ts","official/src/client/index-extension.ts"],"sourcesContent":["/**\n * VENDORED from @deepseek-ai/dsh-client-ui-settings-models @ 0.1.2-rc.1\n * (host tree packages/client/ui-settings-models/src/client/store.ts) — copied\n * VERBATIM so the build is self-contained (no host checkout required).\n * Re-diff against the host source on every adapter-anchor bump.\n */\n/**\n * Models settings page store: one snapshot joining the configurable-provider\n * directory (`llm/listProviders` joined with `llm/listConfigurableProviders`),\n * the settings namespaces (shared settings mirror),\n * and the referenced credentials (`credentials/describe`). The host stays the\n * single fact source — every mutation writes through the wire and the page\n * re-renders from the next describe, pushed or refetched.\n */\n\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type {\n CredentialInfo, LlmConfigurableProvider, LlmProviderInfo, SettingsNamespaceView,\n} from '@deepseek-ai/dsh-api-remotes/client'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport { createSnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport type { SettingsDescribeFace } from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type { SettingsSchemaOperations } from './schema-operations.ts'\n\n/**\n * Any route key walks a dict schema to the same profile node, so the lookup\n * names one that cannot collide with a configured route.\n */\nconst PROBE_ROUTE = '\\u0000probe'\n\n/** One provider row after joining the configurable directory with live routes. */\nexport interface ProviderDirectoryEntry {\n readonly provider: string\n readonly displayName: string\n readonly settingsNs: string\n readonly settingsPath: readonly string[]\n readonly active: boolean\n readonly declared?: boolean\n}\n\n/**\n * Join declared configurable providers with the currently registered routes.\n * @param registered - live provider routes in registration order.\n * @param directory - declared configurable providers in declaration order.\n * @returns declared rows followed by live routes with no declaration.\n */\nexport function joinProviderDirectory(\n registered: readonly LlmProviderInfo[],\n directory: readonly LlmConfigurableProvider[],\n): ProviderDirectoryEntry[] {\n const active = new Set(registered.map(provider => provider.id))\n const declared = new Set(directory.map(entry => entry.provider))\n const rows: ProviderDirectoryEntry[] = directory.map(entry => ({\n provider: entry.provider,\n displayName: entry.displayName,\n settingsNs: entry.settingsNs,\n settingsPath: [...entry.settingsPath],\n active: active.has(entry.provider),\n ...entry.declared === undefined ? {} : { declared: entry.declared },\n }))\n for (const provider of registered) {\n if (declared.has(provider.id)) continue\n rows.push({\n provider: provider.id,\n displayName: provider.name,\n settingsNs: '',\n settingsPath: [],\n active: true,\n })\n }\n return rows\n}\n\n/** One provider row the page renders. */\nexport interface ProviderRow {\n /** The directory entry (route id, display name, settings address, live state). */\n entry: ProviderDirectoryEntry\n /** Whether any layer configures this provider (its profile resolves). */\n configured: boolean\n /** Whether the user layer alone carries the profile (removal restores the base). */\n removable: boolean\n /** The credential reference the resolved profile names, when one does. */\n apiKeyEnv: string | undefined\n /** Credential state for {@link apiKeyEnv}, once described. */\n credential: CredentialInfo | undefined\n /**\n * Credential state for the page's derived `<ROUTE>_API_KEY`, described only\n * while the profile names no reference — the provider-card seat's\n * `keyConfigured` fact for dormant and keyless rows, matching the editor's\n * own derivation rule.\n */\n derivedCredential?: CredentialInfo\n}\n\n/** Page snapshot. */\nexport interface ModelsSettingsState {\n status: 'idle' | 'loading' | 'ready' | 'error'\n /** Whole-load failure text; row-level write failures stay in the editor. */\n error: string | null\n /** Credential enrichment failure; provider/settings rows remain usable. */\n credentialError: string | null\n /** Whether the settings provider accepts writes. */\n writable: boolean\n /** Every configurable provider joined with its configured/credential state. */\n rows: readonly ProviderRow[]\n /** Namespace views by ns, for the editor's schema/layers/secrets. */\n namespaces: ReadonlyMap<string, SettingsNamespaceView>\n}\n\n/**\n * Derive the conventional credential reference for a provider route: the v1\n * page never asks for an environment-variable name, so a typed key stores\n * under this derived reference and the profile records it as `apiKeyEnv`.\n * @param provider - provider route id (e.g. `anthropic`, `minimax-cn`).\n * @returns the derived reference name (e.g. `MINIMAX_CN_API_KEY`).\n */\nexport function deriveKeyRef(provider: string): string {\n return `${provider.toUpperCase().replace(/[^A-Z0-9]+/g, '_')}_API_KEY`\n}\n\n/**\n * The wire protocols a hand-declared route may name, read out of the owning\n * namespace's own schema. This stays a schema read rather than a wire field so\n * the choices the page offers cannot drift from the ones the adapter accepts:\n * both come from the same `Config`.\n * @param namespace - the namespace view whose schema declares the profile shape.\n * @param schema - settings schema operations.\n * @returns the protocol identifiers, or an empty list when the schema has none.\n */\nexport function protocolChoices(\n namespace: SettingsNamespaceView | undefined,\n schema: SettingsSchemaOperations,\n): string[] {\n if (namespace === undefined) return []\n const node = schema.nodeAtPath(schema.rehydrate(namespace.schema), ['providers', PROBE_ROUTE, 'api'])\n const list = (node as { type?: string; list?: readonly { value?: unknown }[] } | undefined)\n if (list?.type !== 'union' || list.list === undefined) return []\n return list.list.map(entry => entry.value).filter((value): value is string => typeof value === 'string')\n}\n\n/** The credential reference a resolved profile names (its `apiKeyEnv` field). */\nfunction apiKeyEnvOf(\n namespace: SettingsNamespaceView | undefined,\n path: readonly string[],\n schema: SettingsSchemaOperations,\n): string | undefined {\n if (namespace === undefined) return undefined\n const profile = schema.getPath(namespace.value, path)\n if (typeof profile !== 'object' || profile === null) return undefined\n const ref = (profile as { apiKeyEnv?: unknown }).apiKeyEnv\n return typeof ref === 'string' && ref.length > 0 ? ref : undefined\n}\n\n/** The models settings page controller (one per settings surface). */\nexport class ModelsSettingsStore {\n /** The snapshot the section renders from (uSES-safe store). */\n readonly store: SnapshotStore<ModelsSettingsState> = createSnapshotStore<ModelsSettingsState>({\n status: 'idle', error: null, credentialError: null, writable: false, rows: [], namespaces: new Map(),\n })\n\n /** Latest load wins; an older response never overwrites a newer one. */\n private generation = 0\n\n /**\n * @param ctx - the page plugin's context, whose `remote.llm` and\n * `remote.credentials` namespaces carry the directory and credential reads.\n * @param schema - settings-owned schema and immutable path operations.\n * @param describeFace - the shared mirror's describe face (namespace views and writability).\n */\n constructor(\n private readonly ctx: ClientContext,\n private readonly schema: SettingsSchemaOperations,\n private readonly describeFace: SettingsDescribeFace,\n ) {}\n\n /**\n * Refresh the whole page snapshot: the provider directory and the mirror's\n * settings answer in parallel, then one batched credential describe over\n * every referenced ref. Provider failure or absence of an initial settings\n * answer keeps the last good rows and surfaces an error; a failed settings\n * refresh reuses the mirror's held view.\n * @returns nothing; the snapshot carries the outcome.\n */\n async load(): Promise<void> {\n const generation = ++this.generation\n this.store.update((s) => { s.status = 'loading'; s.error = null })\n const [registered, declared] = await Promise.all([\n this.ctx.remote.llm.listProviders(),\n this.ctx.remote.llm.listConfigurableProviders(),\n this.describeFace.ensure(),\n ])\n if (!registered.ok) { this.failLoad(generation, registered.error.message); return }\n if (!declared.ok) { this.failLoad(generation, declared.error.message); return }\n const mirrored = this.describeFace.getSnapshot()\n if (mirrored.view === undefined) {\n this.failLoad(generation, mirrored.error ?? 'settings are unavailable in this browser')\n return\n }\n const providers = joinProviderDirectory(registered.value, declared.value)\n const writable = mirrored.view.writable\n const views: readonly SettingsNamespaceView[] = mirrored.view.namespaces\n const namespaces = new Map(views.map(view => [view.ns, view]))\n const rows: ProviderRow[] = providers.map((entry) => {\n const namespace = namespaces.get(entry.settingsNs)\n const configured = namespace !== undefined\n && (entry.settingsPath.length === 0 || this.schema.getPath(namespace.value, entry.settingsPath) !== undefined)\n const removable = namespace !== undefined\n && entry.settingsPath.length > 0\n && this.schema.hasPath(namespace.user, entry.settingsPath)\n && !this.schema.hasPath(namespace.base, entry.settingsPath)\n return {\n entry,\n configured,\n removable,\n apiKeyEnv: apiKeyEnvOf(namespace, entry.settingsPath, this.schema),\n credential: undefined,\n }\n })\n const refs = [...new Set(rows.map(row => row.apiKeyEnv ?? deriveKeyRef(row.entry.provider)))]\n let credentials: Record<string, CredentialInfo> = {}\n let credentialError: string | null = null\n if (refs.length > 0) {\n const response = await this.ctx.remote.credentials.describe(refs)\n // Credential state is an enrichment for the Models page: a failure\n // degrades the badge instead of failing the load. The onboarding\n // projection below retains the failure distinction.\n if (response.ok) credentials = response.value\n else credentialError = response.error.message\n }\n if (generation !== this.generation) return\n this.store.update((s) => {\n s.status = 'ready'\n s.error = null\n s.credentialError = credentialError\n s.writable = writable\n s.rows = rows.map((row) => {\n const named = row.apiKeyEnv === undefined ? undefined : credentials[row.apiKeyEnv]\n const derived = row.apiKeyEnv !== undefined ? undefined : credentials[deriveKeyRef(row.entry.provider)]\n return {\n ...row,\n ...named === undefined ? {} : { credential: named },\n ...derived === undefined ? {} : { derivedCredential: derived },\n }\n })\n s.namespaces = namespaces\n })\n }\n\n /** Publish one load's failure text, unless a newer load already took over. */\n private failLoad(generation: number, message: string): void {\n if (generation !== this.generation) return\n this.store.update((s) => {\n s.status = 'error'\n s.error = message\n })\n }\n}\n\n/**\n * Whether a joined row can serve model requests as it stands: the route is\n * registered with the adapter registry, and whatever credential its resolved\n * profile names is stored. A profile naming no reference authenticates through\n * the provider's own path (the Bedrock chain, Vertex ADC, a gateway that needs\n * nothing), as does a live route with no settings address at all, so neither\n * owes this page a key.\n * @param row - one joined provider row.\n * @returns whether the user already has this provider to talk to.\n */\nexport function providerUsable(row: ProviderRow): boolean {\n if (!row.entry.active) return false\n if (row.apiKeyEnv === undefined) return true\n return row.credential?.configured === true\n}\n\n/** First-run onboarding readiness derived only from the shared Models join. */\nexport type OnboardingReadiness =\n | { kind: 'loading' }\n | { kind: 'adapter-absent' }\n | { kind: 'provider-ready' }\n | { kind: 'credential-missing' }\n | {\n kind: 'unavailable'\n reason:\n | 'load-failed'\n | 'provider-inactive'\n | 'credentials-unavailable'\n | 'settings-read-only'\n | 'credential-read-only'\n }\n\n/**\n * Project first-run readiness from the provider/settings/credential join used\n * by the Models page. The step exists to leave the user with a model to talk\n * to, so ANY usable provider ends it; only when none exists does the official\n * DeepSeek route — the one route the prompt can offer a key field for — decide\n * whether prompting can help. A missing official configurable-provider\n * declaration means the adapter is not repairable by navigating to Models.\n * @param state - current shared Models join snapshot.\n * @returns the onboarding state without reading a parallel fact source.\n */\nexport function onboardingReadiness(state: ModelsSettingsState): OnboardingReadiness {\n if ((state.status === 'idle' || state.status === 'loading') && state.rows.length === 0) {\n return { kind: 'loading' }\n }\n if (state.status === 'error') {\n return {\n kind: 'unavailable',\n reason: 'load-failed',\n }\n }\n if (state.rows.some(providerUsable)) return { kind: 'provider-ready' }\n const row = state.rows.find(candidate =>\n candidate.entry.provider === 'deepseek-official'\n && candidate.entry.settingsNs === 'llm-deepseek'\n && candidate.entry.settingsPath.length === 0)\n if (row === undefined) return { kind: 'adapter-absent' }\n if (!row.entry.active) {\n return {\n kind: 'unavailable',\n reason: 'provider-inactive',\n }\n }\n // Past the usable gate an active route names a reference it has no stored\n // credential for, so the remaining questions are all about that credential.\n if (state.credentialError !== null || row.credential === undefined) {\n return {\n kind: 'unavailable',\n reason: 'credentials-unavailable',\n }\n }\n if (!state.writable) {\n return {\n kind: 'unavailable',\n reason: 'settings-read-only',\n }\n }\n if (!row.credential.writable) {\n return {\n kind: 'unavailable',\n reason: 'credential-read-only',\n }\n }\n return { kind: 'credential-missing' }\n}\n","/**\n * Client access to the models.dev metadata index. The index is served by this\n * plugin's own server route (same origin); the raw models.json lives next to\n * settings.yaml under DSH home and is fetched from models.dev ONLY when the\n * user clicks the title-row button — nothing downloads automatically.\n *\n * The search surface is deliberately minimal (per plan): match model ids with\n * a case-insensitive substring test and show ids only, at most 10 candidates.\n * The full index is never handed to a static <datalist>.\n */\n\n/** Precise entry the metadata search returns (a subset of the raw models.dev record). */\nexport interface MetadataEntry {\n readonly id: string\n readonly context: number | undefined\n readonly output: number | undefined\n readonly input: readonly string[]\n readonly reasoning: boolean\n}\n\n/** Same-origin routes served by the server half. */\nconst INDEX_URL = '/plugins/dsh-model-extension/models-index'\nconst DOWNLOAD_URL = '/plugins/dsh-model-extension/models-download'\n\n/** Module-level cache: one page load fetches the index at most once. */\nlet cached: readonly MetadataEntry[] | undefined\n\nfunction normalize(raw: unknown): readonly MetadataEntry[] {\n if (!Array.isArray(raw)) return []\n const entries: MetadataEntry[] = []\n for (const item of raw) {\n if (typeof item !== 'object' || item === null) continue\n const row = item as Record<string, unknown>\n if (typeof row['id'] !== 'string' || row['id'].length === 0) continue\n const modalities = Array.isArray(row['input'])\n ? row['input'].filter((m): m is string => typeof m === 'string')\n : []\n entries.push({\n id: row['id'],\n context: typeof row['context'] === 'number' ? row['context'] : undefined,\n output: typeof row['output'] === 'number' ? row['output'] : undefined,\n input: modalities,\n reasoning: row['reasoning'] === true,\n })\n }\n return entries\n}\n\n/**\n * The metadata index, fetched once per page load; `undefined` while the\n * server has no metadata file (the caller shows the not-ready hint).\n */\nexport async function getMetadataIndex(): Promise<readonly MetadataEntry[] | undefined> {\n if (cached !== undefined) return cached\n try {\n const response = await fetch(INDEX_URL)\n if (!response.ok) return undefined\n cached = normalize(await response.json())\n return cached\n } catch {\n return undefined\n }\n}\n\n/** The outcome of an explicit user-triggered download. */\nexport type MetadataDownload = { readonly ok: true } | { readonly ok: false; readonly message: string }\n\n/**\n * Download/refresh the metadata file through the server half (user-triggered\n * from the title-row button). A success also refreshes the local cache.\n */\nexport async function downloadMetadata(): Promise<MetadataDownload> {\n try {\n const response = await fetch(DOWNLOAD_URL, { method: 'POST' })\n const body = await response.json().catch(() => undefined) as\n | { ok?: boolean; message?: string }\n | undefined\n if (!response.ok || body?.ok !== true) {\n return { ok: false, message: body?.message ?? `HTTP ${String(response.status)}` }\n }\n cached = normalize(body['index'])\n return { ok: true }\n } catch (error) {\n return { ok: false, message: error instanceof Error ? error.message : String(error) }\n }\n}\n\n/**\n * Case-insensitive substring match over model ids, at most {@link limit}\n * candidates (plan: show ids only, never the whole list).\n * @param index - the metadata index, or undefined while unavailable.\n * @param query - the user's typed text.\n * @param limit - maximum candidates to return.\n * @returns the matching ids; empty when the index is unavailable.\n */\nexport function searchModelIds(\n index: readonly MetadataEntry[] | undefined,\n query: string,\n limit = 10,\n): readonly string[] {\n if (index === undefined) return []\n const needle = query.trim().toLowerCase()\n if (needle.length === 0) return []\n const hits: string[] = []\n for (const entry of index) {\n if (!entry.id.toLowerCase().includes(needle)) continue\n hits.push(entry.id)\n if (hits.length >= limit) break\n }\n return hits\n}\n","/**\n * Pure helpers copied from the host's ui-settings-models UI component files\n * (they live inside components there, so they cannot be inlined as standalone\n * modules like operations/store/schema-operations are).\n *\n * ⚠️ Fork-copy risk: these must be re-checked against the pinned host sources\n * (packages/client/ui-settings-models/src/client/{ProviderEditor,DeepSeekModelsEditor}.tsx\n * @ 0.1.2-rc.1) on every adapter-anchor bump.\n */\n\n/** One model entry kept structurally open so hidden or future fields survive an edit. */\nexport type ModelDraft = Record<string, unknown>\n\n// ---------------------------------------------------------------------------\n// pathOps — copied from ProviderEditor.tsx @ 0.1.2-rc.1\n// ---------------------------------------------------------------------------\n\nimport type { JsonValue } from '@deepseek-ai/dsh-util-values'\nimport type { SettingsPathOpView } from '@deepseek-ai/dsh-api-remotes/client'\n\n/**\n * The minimal path ops carrying `after` over `before`, both as the card sees\n * them. Only keys the card observed are named; fields absent from both sides\n * produce no op, which is why edits are path-addressed rather than a rebuilt\n * section.\n * @param base - path of the edited subtree inside the user section.\n * @param before - the subtree as loaded, or undefined when it is new.\n * @param after - the subtree as edited.\n * @returns ordered set/unset ops; empty when nothing changed.\n */\nexport function pathOps(\n base: readonly string[],\n before: unknown,\n after: Record<string, unknown>,\n): SettingsPathOpView[] {\n const previous = typeof before === 'object' && before !== null && !Array.isArray(before)\n ? before as Record<string, unknown>\n : {}\n const ops: SettingsPathOpView[] = []\n for (const [key, value] of Object.entries(after)) {\n if (JSON.stringify(previous[key]) === JSON.stringify(value)) continue\n ops.push({ op: 'set', path: [...base, key], value: value as JsonValue })\n }\n for (const key of Object.keys(previous)) {\n if (!(key in after)) ops.push({ op: 'unset', path: [...base, key] })\n }\n return ops\n}\n\n// ---------------------------------------------------------------------------\n// capacity parsing/formatting — copied from DeepSeekModelsEditor.tsx @ 0.1.2-rc.1\n// ---------------------------------------------------------------------------\n\n/** Accepted capacity spellings: a decimal count with an optional K/M suffix. */\nconst CAPACITY_PATTERN = /^(\\d+(?:\\.\\d+)?)([km])?$/i\n\n/** Decimal suffix scales — `1M` is 1000K, matching how model capacities are quoted. */\nconst CAPACITY_SCALE = { k: 1_000, m: 1_000_000 } as const\n\n/**\n * Read a typed capacity, so a user can write `256K` or `1M` instead of counting\n * zeroes. The stored value stays a plain token count.\n * @param text - raw field text.\n * @returns the count; `undefined` when blank (inherit), `NaN` when unreadable\n * (rejected by {@link validateModelRows} before any write).\n */\nexport function parseCapacity(text: string): number | undefined {\n const trimmed = text.trim()\n if (trimmed.length === 0) return undefined\n const match = CAPACITY_PATTERN.exec(trimmed)\n if (match === null) return Number.NaN\n const suffix = match[2]?.toLowerCase()\n const scale = suffix === 'k' || suffix === 'm' ? CAPACITY_SCALE[suffix] : 1\n const scaled = Number(match[1]) * scale\n // A decimal multiple is exact in intent but not in binary floating point\n // (2.3 * 1e6 lands a few ULPs high), so an integral intent snaps back.\n const rounded = Math.round(scaled)\n return Math.abs(scaled - rounded) < 1e-6 ? rounded : scaled\n}\n\n/**\n * Spell a stored count back in the shortest form that survives a round trip\n * through {@link parseCapacity}; a count that is not a whole number of\n * thousands stays written out.\n * @param value - stored capacity.\n * @returns the field text.\n */\nexport function formatCapacity(value: number): string {\n if (!Number.isInteger(value) || value <= 0) return String(value)\n if (value % CAPACITY_SCALE.m === 0) return `${String(value / CAPACITY_SCALE.m)}M`\n if (value % CAPACITY_SCALE.k === 0) return `${String(value / CAPACITY_SCALE.k)}K`\n return String(value)\n}\n\n// ---------------------------------------------------------------------------\n// model-row validation — copied from DeepSeekModelsEditor.tsx @ 0.1.2-rc.1\n// ---------------------------------------------------------------------------\n\n/** A localized validation failure for one user-owned model array. */\nexport interface ModelRowsValidationFailure {\n /** Zero-based model position. */\n index: number\n /** Message key owned by the Models+ dictionary. */\n key: 'modelIdRequired' | 'modelIdDuplicate' | 'modelNameInvalid' | 'modelContextInvalid'\n | 'modelMaxTokensInvalid'\n}\n\n/** Convert a schema-validated catalog value into records without dropping hidden fields. */\nexport function modelDrafts(value: unknown): ModelDraft[] {\n if (!Array.isArray(value)) return []\n return value.map(entry =>\n typeof entry === 'object' && entry !== null && !Array.isArray(entry)\n ? entry as ModelDraft\n : {})\n}\n\n// ---------------------------------------------------------------------------\n// row key-order normalization (plugin addition, v1.0.0: stable YAML key order)\n// ---------------------------------------------------------------------------\n\n/** Canonical key order for one models[] row (plugin-known fields first). */\nconst ROW_KEY_ORDER = ['id', 'name', 'contextWindow', 'maxTokens', 'input', 'reasoningEfforts', 'compat']\n\n/** Canonical key order for the row's compat sub-object. */\nconst COMPAT_KEY_ORDER = ['supportsDeveloperRole', 'supportsReasoningEffort', 'thinkingFormat']\n\n/**\n * Re-key one model row into the canonical order (plugin-known fields in\n * order, unknown/future fields kept at the tail so nothing is dropped).\n * YAML emits keys in object insertion order, and interactive edits append\n * keys at the tail — without this, rows saved after quick-load or gated-key\n * removals come out with scrambled key orders (purely cosmetic, but noisy\n * in settings.yaml diffs).\n * @param row - the drafted row.\n * @returns the re-keyed row (shallow copy).\n */\nexport function normalizeModelRow(row: ModelDraft): ModelDraft {\n const next: ModelDraft = {}\n for (const key of ROW_KEY_ORDER) {\n if (key in row) next[key] = row[key]\n }\n for (const key of Object.keys(row)) {\n if (!ROW_KEY_ORDER.includes(key)) next[key] = row[key]\n }\n const compat = next['compat']\n if (typeof compat === 'object' && compat !== null && !Array.isArray(compat)) {\n const source = compat as Record<string, unknown>\n const normalized: Record<string, unknown> = {}\n for (const key of COMPAT_KEY_ORDER) {\n if (key in source) normalized[key] = source[key]\n }\n for (const key of Object.keys(source)) {\n if (!COMPAT_KEY_ORDER.includes(key)) normalized[key] = source[key]\n }\n next['compat'] = normalized\n }\n return next\n}\n\n/**\n * Validate adapter constraints that the serialized schema cannot express.\n * @param value - user-owned `models` value, or undefined while inherited.\n * @returns the first invalid row, or undefined when the adapter will accept it.\n */\nexport function validateModelRows(value: unknown): ModelRowsValidationFailure | undefined {\n if (value === undefined) return undefined\n const models = modelDrafts(value)\n const seen = new Set<string>()\n for (const [index, model] of models.entries()) {\n // Compared trimmed: surrounding whitespace is a paste artifact the adapter\n // would never match, and an untrimmed compare lets `model ` slip past the\n // duplicate check against its own twin.\n const id = model['id']\n const trimmed = typeof id === 'string' ? id.trim() : undefined\n if (trimmed === undefined || trimmed.length === 0) return { index, key: 'modelIdRequired' }\n if (seen.has(trimmed)) return { index, key: 'modelIdDuplicate' }\n seen.add(trimmed)\n const name = model['name']\n if (name !== undefined && (typeof name !== 'string' || name.length === 0)) {\n return { index, key: 'modelNameInvalid' }\n }\n const contextWindow = model['contextWindow']\n if (contextWindow !== undefined\n && (typeof contextWindow !== 'number' || !Number.isInteger(contextWindow) || contextWindow <= 0)) {\n return { index, key: 'modelContextInvalid' }\n }\n const maxTokens = model['maxTokens']\n if (maxTokens !== undefined\n && (typeof maxTokens !== 'number' || !Number.isInteger(maxTokens) || maxTokens <= 0)) {\n return { index, key: 'modelMaxTokensInvalid' }\n }\n }\n return undefined\n}\n","/**\n * Draft defaults for a NEW model row (added by hand or adopted from a fetch),\n * per the v1.0.0 plan: reasoning effort ON with every level declared, thinking\n * format `openai`, both input modalities checked. These are draft seeds that\n * land in settings.yaml when the row is saved — they are not inherited-state\n * sentinels, except `supportsDeveloperRole`, which stays UNWRITTEN (its\n * tri-state reads an absent key as checked, so only an explicit user uncheck\n * ever writes `false`).\n */\n\nimport type { ModelDraft } from './compat.ts'\n\n/** The tri-state `compat.supportsDeveloperRole` seed: absent (reads checked). */\nconst DEVELOPER_ROLE_SEED: Record<string, unknown> = {}\n\n/** Draft seed for one new model row. */\nexport function newModelDraft(): ModelDraft {\n return {\n id: '',\n input: ['text', 'image'],\n reasoningEfforts: {\n off: null,\n minimal: 'minimal',\n low: 'low',\n medium: 'medium',\n high: 'high',\n xhigh: 'xhigh',\n max: 'max',\n },\n compat: {\n ...DEVELOPER_ROLE_SEED,\n supportsReasoningEffort: true,\n thinkingFormat: 'openai',\n },\n }\n}\n","/**\n * Shared extension metadata: enums pinned to the adapter anchor version, and\n * the extra locale keys the extension adds on top of the official Models page\n * dictionaries. The anchor constant itself is injected at build time.\n */\n\n/** Adapter anchor (build-time define from package.json dsh.adapter). */\ndeclare const __DSH_ADAPTER_VERSION__: string\nexport const ADAPTER_VERSION: string =\n typeof __DSH_ADAPTER_VERSION__ === 'string' ? __DSH_ADAPTER_VERSION__ : '0.0.0-unknown'\n\n/** Thinking levels offered by llm-pi-ai (THINKING_LEVEL_GATE @ 0.1.2-alpha.4). Only `off` may carry an empty wire value. */\nexport const THINKING_LEVELS = ['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'] as const\nexport type ThinkingLevel = (typeof THINKING_LEVELS)[number]\n\n/** Input modalities accepted by llm-pi-ai (MODALITY_GATE @ 0.1.2-alpha.4). */\nexport const MODALITIES = ['text', 'image'] as const\nexport type Modality = (typeof MODALITIES)[number]\n\n/** Reasoning wire formats understood by llm-pi-ai (SUPPORTED_THINKING_FORMATS @ 0.1.2-alpha.4). */\nexport const THINKING_FORMATS = [\n 'openai',\n 'deepseek',\n 'openrouter',\n 'together',\n 'baseten',\n 'zai',\n 'qwen',\n 'chat-template',\n 'qwen-chat-template',\n 'string-thinking',\n 'ant-ling',\n] as const\nexport type ThinkingFormat = (typeof THINKING_FORMATS)[number]\n\n/** Extra copy for the extension, keyed like the official dictionaries (en is authoritative). */\nexport const en = {\n // --- official Models-page keys the forked components still render -------\n nav: 'Models+',\n title: 'Models+',\n intro: 'Enter your API keys to use models from the following providers.',\n edit: 'Edit',\n editProvider: 'Edit {provider}',\n remove: 'Delete',\n removeProvider: 'Delete {provider}',\n deleteTitle: 'Delete {provider}?',\n deleteDescription: 'Deleting {provider} removes its configuration. Any credential it uses is managed elsewhere and will be kept.',\n deleteDescriptionWithCredential: 'Deleting {provider} removes its configuration and stored API key.',\n deleteConfirm: 'Delete {provider}',\n deleting: 'Deleting {provider}…',\n add: 'Add provider',\n provider: 'Provider',\n close: 'Close',\n cancel: 'Cancel',\n apply: 'Apply',\n applying: 'Applying…',\n savedProvider: 'Saved {provider}.',\n credentialConfigured: 'API key configured',\n credentialMissing: 'API key missing',\n readOnly: 'The settings document is read-only in this deployment.',\n loadFailed: 'Loading the provider directory failed',\n conflict: 'Someone else changed these settings while this card was open. Close it and reopen to edit the current values.',\n retry: 'Retry',\n keyInput: 'API key',\n keyPlaceholder: 'Enter your API key',\n keyPlaceholderNative: 'Enter an API key, or leave blank to use environment authentication',\n keyStored: 'Configured — enter a new value to replace',\n keyEnvLocked: 'Provided by the launch environment (read-only)',\n customized: 'Customized settings',\n baseUrl: 'Base URL',\n baseUrlDefault: 'Provider default',\n models: 'Models',\n modelsInherited: 'Using the adapter defaults',\n modelsCustomized: 'Customized model catalog',\n resetModels: 'Restore defaults',\n model: 'Model',\n modelId: 'Model ID',\n modelName: 'Display name',\n modelNamePlaceholder: 'Uses the model ID when empty',\n contextWindow: 'Context window',\n contextWindowPlaceholder: 'Uses the provider default',\n maxTokens: 'Max output tokens',\n maxTokensPlaceholder: 'Uses the provider default',\n modelAdvanced: 'Capacities',\n addModel: 'Add model',\n removeModel: 'Delete model',\n modelsEmpty: 'No models will be shown in the selector. Unlisted IDs can still be sent directly.',\n keyBlank: 'Enter the API key, or leave the field empty to keep the stored one.',\n keyBlankNew: 'Enter the API key, or leave the field empty if this provider authenticates another way.',\n keyIllegalCharacters: 'This API key is not in a valid format. Please check it.',\n modelIdRequired: 'Model ID is required.',\n modelIdDuplicate: 'Model ID must be unique.',\n modelNameInvalid: 'Display name cannot be empty.',\n modelContextInvalid: 'Context window must be a positive count, like 131072, 256K, or 1M.',\n modelMaxTokensInvalid: 'Max output tokens must be a positive count, like 8192, 64K, or 1M.',\n advancedHint: 'Other fields live in settings.yaml; edit that section directly.',\n modelCapacityInvalid: 'A capacity must be a number, optionally suffixed K or M.',\n modelDuplicate: 'Each model ID may appear once.',\n modelContextWindow: 'Context window',\n modelMaxTokens: 'Max output tokens',\n fetchModels: 'Fetch available models',\n fetching: 'Asking the provider…',\n fetchNeedsBaseUrl: 'Enter the base URL first, then fetch.',\n fetchEmpty: 'The provider listed no models. Add them by hand.',\n fetchTitle: 'Choose models to add',\n fetchDescription: 'These are the models this provider has available. Choose the ones to add.',\n fetchSelectAll: 'Select all',\n fetchDeselectAll: 'Deselect all',\n fetchAdopt: 'Add selected',\n customAdd: 'Add a custom provider',\n customTitle: 'Custom provider',\n customTag: 'Custom',\n customRoute: 'Provider ID',\n customRouteHint: 'Lowercase identifier, starting with a letter, that uniquely names this provider in requests and as its credential name.',\n customRouteInvalid: 'Start with a lowercase letter; then lowercase letters, digits, and dashes.',\n customRouteTaken: 'A provider already uses this ID.',\n customDisplayName: 'Display name',\n customApi: 'API protocol',\n customApiUnset: 'Not selected',\n customNeedsBaseUrl: 'A custom provider needs a base URL.',\n customNeedsModels: 'A custom provider needs at least one model.',\n customBaseUrlPlaceholder: 'https://gateway.example/v1',\n settingsPathUnresolvable: 'unresolvable settings path',\n create: 'Create provider',\n creating: 'Creating…',\n onboardingTitle: 'Add an API key to get started',\n onboardingDescription: 'Configure the official DeepSeek provider to start building.',\n onboardingLater: 'Configure later',\n onboardingSave: 'Save and continue',\n onboardingSaving: 'Saving…',\n keyRequired: 'Enter an API key to continue.',\n\n // --- extension-only keys ------------------------------------------------\n extDeclare: 'Declared',\n extSection: 'Model extensions',\n extSectionHint: 'Extra per-model fields that live in settings.yaml.',\n supportsReasoningEffort: 'Endpoint accepts reasoning effort',\n supportsDeveloperRole: 'System prompt may use the developer role',\n supportsDeveloperRoleHint: 'Reasoning-model system prompts go out as \"developer\"; uncheck to keep \"system\" for gateways that reject it.',\n reasoningEfforts: 'Reasoning efforts',\n reasoningEffortLevel: 'Level',\n reasoningEffortWire: 'Wire value',\n reasoningEffortOffHint: '\"off\" takes no wire value.',\n reasoningEffortEmptyWire: 'A checked level other than \"off\" needs a wire value.',\n reasoningEffortsNeedNonOff: 'Declare at least one level beyond \"off\".',\n inputModalities: 'Input modalities',\n inputNeedOne: 'Keep at least one modality checked.',\n thinkingFormat: 'Thinking format',\n} as const\n\nexport type ExtensionKey = keyof typeof en\n\n/** Chinese strings — same key set as {@link en}. */\nexport const zh: { [K in ExtensionKey]: string } = {\n // --- official Models-page keys (upstream zh values) ----------------------\n nav: '模型+',\n title: '模型+',\n intro: '填入各提供方的 API 密钥即可使用其模型。',\n edit: '编辑',\n editProvider: '编辑 {provider}',\n remove: '删除',\n removeProvider: '删除 {provider}',\n deleteTitle: '删除 {provider}?',\n deleteDescription: '删除 {provider} 会移除其配置;其使用的凭证(如有)由其他位置管理,将会保留。',\n deleteDescriptionWithCredential: '删除 {provider} 会移除其配置和存储的 API 密钥。',\n deleteConfirm: '删除 {provider}',\n deleting: '正在删除 {provider}…',\n add: '添加提供方',\n provider: '提供方',\n close: '关闭',\n cancel: '取消',\n apply: '保存',\n applying: '保存中…',\n savedProvider: '已保存 {provider}。',\n credentialConfigured: 'API 密钥已配置',\n credentialMissing: 'API 密钥缺失',\n readOnly: '当前部署的设置文档为只读。',\n loadFailed: '加载提供方目录失败',\n conflict: '这张卡片打开期间,这些设置已被其他地方改动。请关闭后重新打开,在当前值上编辑。',\n retry: '重试',\n keyInput: 'API 密钥',\n keyPlaceholder: '输入 API 密钥',\n keyPlaceholderNative: '输入 API 密钥,或留空使用环境认证',\n keyStored: '已配置——输入新值可替换',\n keyEnvLocked: '由启动环境提供(只读)',\n customized: '自定义设置',\n baseUrl: 'API 地址',\n baseUrlDefault: '提供方默认',\n models: '模型目录',\n modelsInherited: '正在使用适配器默认模型',\n modelsCustomized: '已自定义模型目录',\n resetModels: '恢复默认模型',\n model: '模型',\n modelId: '模型 ID',\n modelName: '显示名称',\n modelNamePlaceholder: '留空时使用模型 ID',\n contextWindow: '上下文窗口',\n contextWindowPlaceholder: '使用提供方默认值',\n maxTokens: '最大输出 token 数',\n maxTokensPlaceholder: '使用提供方默认值',\n modelAdvanced: '容量',\n addModel: '添加模型',\n removeModel: '删除模型',\n modelsEmpty: '模型选择器中将不显示任何模型;目录外 ID 仍可直接发送。',\n keyBlank: '请输入 API 密钥;留空则保持已存储的密钥。',\n keyBlankNew: '请输入 API 密钥;若该提供方以其他方式鉴权,可以留空。',\n keyIllegalCharacters: '此 API 密钥格式无效,请检查。',\n modelIdRequired: '模型 ID 必填。',\n modelIdDuplicate: '模型 ID 不能重复。',\n modelNameInvalid: '显示名称不能为空。',\n modelContextInvalid: '上下文窗口须为正数,如 131072、256K、1M。',\n modelMaxTokensInvalid: '最大输出 token 数须为正数,如 8192、64K、1M。',\n advancedHint: '其余字段存于 settings.yaml;请直接编辑该节。',\n modelCapacityInvalid: '容量须为数字,可带 K 或 M 后缀。',\n modelDuplicate: '每个模型 ID 只能出现一次。',\n modelContextWindow: '上下文窗口',\n modelMaxTokens: '最大输出 token 数',\n fetchModels: '获取可用模型',\n fetching: '正在询问提供方…',\n fetchNeedsBaseUrl: '请先填写 API 地址再获取。',\n fetchEmpty: '该提供方未列出任何模型,请手动添加。',\n fetchTitle: '选择要添加的模型',\n fetchDescription: '这些是该提供方可用的模型,选择要添加的项。',\n fetchSelectAll: '全选',\n fetchDeselectAll: '取消全选',\n fetchAdopt: '添加所选',\n customAdd: '添加自定义提供方',\n customTitle: '自定义提供方',\n customTag: '自定义',\n customRoute: '提供方 ID',\n customRouteHint: '小写字母开头的唯一标识符,用于请求与凭证命名。',\n customRouteInvalid: '以小写字母开头;其后为小写字母、数字和短横线。',\n customRouteTaken: '已有提供方使用此 ID。',\n customDisplayName: '显示名称',\n customApi: 'API 协议',\n customApiUnset: '未选择',\n customNeedsBaseUrl: '自定义提供方需要 API 地址。',\n customNeedsModels: '自定义提供方至少需要一个模型。',\n customBaseUrlPlaceholder: 'https://gateway.example/v1',\n settingsPathUnresolvable: '无法解析设置路径',\n create: '创建提供方',\n creating: '创建中…',\n onboardingTitle: '先添加一个 API 密钥即可开始',\n onboardingDescription: '配置官方 DeepSeek 提供方以开始构建。',\n onboardingLater: '稍后配置',\n onboardingSave: '保存并继续',\n onboardingSaving: '保存中…',\n keyRequired: '请输入 API 密钥以继续。',\n\n // --- extension-only keys ------------------------------------------------\n extDeclare: '声明',\n extSection: '模型扩展',\n extSectionHint: 'settings.yaml 中按模型生效的扩展字段。',\n supportsReasoningEffort: '端点接受推理挡位参数(reasoning_effort)',\n supportsDeveloperRole: '允许以 developer 角色发送系统提示',\n supportsDeveloperRoleHint: '推理模型的系统提示将以 developer 角色发出;网关拒绝该角色时取消勾选,改用 system。',\n reasoningEfforts: '推理挡位',\n reasoningEffortLevel: '挡位',\n reasoningEffortWire: '线上取值',\n reasoningEffortOffHint: '“off”不需要线上取值。',\n reasoningEffortEmptyWire: '除 off 外勾选的挡位必须填写线上取值。',\n reasoningEffortsNeedNonOff: '至少声明一个 off 以外的挡位。',\n inputModalities: '输入模态',\n inputNeedOne: '至少保留一个模态。',\n thinkingFormat: '思考格式',\n}\n","/* models-plus styles — the official ModelsSection.module.css classes (as\n * transcribed and verified in docs/models-settings-demo.html) plus the\n * extension-block styles, all on --dsw-alias tokens. */\n\n.section { display: flex; flex-direction: column; gap: 12px; max-width: 720px; color: var(--dsw-alias-label-primary); }\n.titleRow { display: flex; align-items: center; gap: 10px; }\n.title { margin: 0; font-size: 16px; line-height: 24px; font-weight: 500; color: var(--dsw-alias-label-primary); }\n.intro { margin: 0; font-size: 14px; line-height: 22px; color: var(--dsw-alias-label-tertiary); }\n.savedNotice { margin: 0; font-size: 12px; line-height: 18px; color: var(--dsw-alias-state-success-primary); }\n.error { margin: 0; font-size: 12px; line-height: 18px; color: var(--dsw-alias-state-error-primary); }\n\n.rows { list-style: none; margin: 12px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }\n.rowCard { border: 0.5px solid var(--dsw-alias-border-l4); border-radius: 16px; padding: 12px 14px; display: flex; flex-direction: column; gap: 12px; }\n.rowHead { display: flex; align-items: center; gap: 10px; }\n.rowIdentity { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }\n.rowName { font-size: 14px; line-height: 22px; font-weight: 500; color: var(--dsw-alias-label-primary); }\n.rowTag { flex: none; padding: 1px 6px; border: 0.5px solid var(--dsw-alias-border-l3); border-radius: 4px; font-size: 11px; line-height: 16px; color: var(--dsw-alias-label-secondary); }\n.credentialDot { box-sizing: border-box; display: inline-block; flex: none; width: 8px; height: 8px; border-radius: 50%; }\n.credentialDotConfigured { background: var(--dsw-alias-state-success-primary); }\n.credentialDotMissing { background: var(--dsw-alias-state-error-primary); }\n.rowActions { display: inline-flex; align-items: center; gap: 4px; margin-left: auto; }\n\n.primaryButton, .secondaryButton, .addButton { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; gap: 4px; height: 36px; padding: 0 14px; border: none; border-radius: 18px; font: inherit; font-size: 14px; line-height: 22px; cursor: pointer; }\n.primaryButton { background: var(--dsw-alias-button-primary-fill); color: var(--dsw-alias-label-primary-foreground); }\n.primaryButton:hover:not(:disabled) { background: var(--dsw-alias-button-primary-hover); }\n.secondaryButton, .addButton { border: 0.5px solid var(--dsw-alias-border-l3); background: transparent; color: var(--dsw-alias-label-primary); }\n.secondaryButton:hover:not(:disabled), .addButton:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); }\n.secondaryButton:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover-solid); }\n.dangerButton { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; height: 36px; padding: 0 14px; border: none; border-radius: 18px; background: transparent; color: var(--dsw-alias-state-error-primary); font: inherit; font-size: 14px; line-height: 22px; cursor: pointer; }\n.dangerButton:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover-danger); }\n.rowActions .secondaryButton, .rowActions .dangerButton { height: 28px; padding: 0 10px; border-radius: 14px; font-size: 12px; line-height: 18px; }\n.primaryButton:disabled, .secondaryButton:disabled, .dangerButton:disabled, .addButton:disabled, .linkButton:disabled, .addModelButton:disabled { opacity: 0.4; cursor: default; }\n.primaryButton:focus-visible, .secondaryButton:focus-visible, .dangerButton:focus-visible, .addButton:focus-visible, .linkButton:focus-visible, .addModelButton:focus-visible, .iconButton:focus-visible, .customizedSummary:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--dsw-alias-border-l3); }\n\n.editor { border-radius: 12px; background: var(--dsw-alias-bg-module-platform); padding: 14px 16px; display: flex; flex-direction: column; gap: 14px; }\n.field { display: flex; flex-direction: column; gap: 6px; }\n.fieldLabel { display: inline-flex; align-items: center; gap: 10px; font-size: 12px; line-height: 18px; font-weight: 500; color: var(--dsw-alias-label-secondary); }\n.linkButton { box-sizing: border-box; display: inline-flex; align-items: center; height: 28px; padding: 0 10px; border: none; border-radius: 14px; background: transparent; color: var(--dsw-alias-label-tertiary); font: inherit; font-size: 12px; line-height: 18px; cursor: pointer; }\n.linkButton:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); color: var(--dsw-alias-label-secondary); }\n.advancedHint { margin: 0; font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-tertiary); }\n.editorActions { display: flex; justify-content: flex-end; gap: 8px; }\n\n.addBlock { display: flex; flex-direction: column; gap: 12px; }\n.addActions { display: flex; flex-wrap: wrap; gap: 10px; }\n.addButton { flex: 1 1 0; min-width: 180px; gap: 6px; height: 44px; border: 1px dashed var(--dsw-alias-border-l3); border-radius: 16px; }\n.addCard { border-radius: 12px; background: var(--dsw-alias-bg-module-platform); padding: 14px 16px; display: flex; flex-direction: column; gap: 14px; list-style: none; }\n.addCard .editor, .setupCard .editor { background: none; padding: 0; }\n\n\n.tabs { display: flex; flex-direction: column; gap: 12px; }\n.tabBar { display: flex; gap: 4px; border-bottom: 0.5px solid var(--dsw-alias-border-l2); }\n.tabButton { appearance: none; border: none; background: transparent; padding: 6px 12px 8px; font: inherit; font-size: 13px; line-height: 20px; color: var(--dsw-alias-label-tertiary); cursor: pointer; position: relative; }\n.tabButton:hover { color: var(--dsw-alias-label-primary); }\n.tabButton:disabled { opacity: 0.4; cursor: default; }\n.tabButtonActive { color: var(--dsw-alias-label-primary); font-weight: 500; }\n.tabButtonActive::after { content: ''; position: absolute; left: 10px; right: 10px; bottom: -1px; height: 2px; border-radius: 2px; background: var(--dsw-alias-brand-primary); }\n.tabPanel { display: flex; flex-direction: column; gap: 12px; }\n.modelCatalog { display: flex; flex-direction: column; gap: 10px; }\n.modelCatalogHeading { display: flex; flex-direction: column; gap: 2px; }\n.modelCatalogTitle { font-size: 12px; line-height: 18px; font-weight: 500; color: var(--dsw-alias-label-secondary); }\n.modelCatalogMeta, .modelEmpty { margin: 0; color: var(--dsw-alias-label-tertiary); font-size: 12px; line-height: 18px; }\n.modelList { display: flex; flex-direction: column; gap: 8px; }\n.modelListHead { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }\n.modelEntry { border: 0.5px solid var(--dsw-alias-border-l4); border-radius: 10px; padding: 6px; }\n.modelRow { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) auto auto; align-items: center; gap: 6px; }\n.iconButton { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-tertiary); cursor: pointer; }\n.iconButton:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); color: var(--dsw-alias-label-primary); }\n.iconButton:disabled { cursor: default; opacity: 0.4; }\n.iconButtonDanger:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover-danger); color: var(--dsw-alias-state-error-primary); }\n.modelAdvanced { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 8px; padding: 8px 4px 2px; }\n.modelField { display: flex; flex-direction: column; gap: 4px; }\n.modelFieldLabel { color: var(--dsw-alias-label-tertiary); font-size: 12px; line-height: 18px; }\n.modelEmpty { padding: 12px; border: 1px dashed var(--dsw-alias-border-l3); border-radius: 8px; text-align: center; }\n.addModelButton { box-sizing: border-box; align-self: flex-start; display: inline-flex; align-items: center; gap: 4px; height: 28px; padding: 0 10px; border: 0.5px solid var(--dsw-alias-border-l3); border-radius: 14px; background: transparent; color: var(--dsw-alias-label-primary); font: inherit; font-size: 12px; line-height: 18px; cursor: pointer; }\n.addModelButton:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); }\n\n.input { box-sizing: border-box; width: 100%; height: 32px; padding: 0 10px; border: 0.5px solid var(--dsw-alias-border-l4); border-radius: 8px; font: inherit; font-size: 14px; line-height: 22px; background: var(--dsw-alias-bg-layer-1); color: var(--dsw-alias-label-primary); }\nselect.input { max-width: 240px; cursor: pointer; }\n.input:focus { outline: none; border-color: var(--dsw-alias-brand-primary); }\n.input::placeholder { color: var(--dsw-alias-label-dimmed); }\n.input:disabled { opacity: 0.6; cursor: default; }\n.selectInput { appearance: none; padding-right: 32px; background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%2381858C' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\"); background-repeat: no-repeat; background-position: right 12px center; background-size: 12px 12px; }\n\n.deleteDialog { width: min(480px, 100%); }\n.deleteConfirm:not(:disabled) { border-color: var(--dsw-alias-state-error-primary); color: var(--dsw-alias-state-error-primary); }\n.deleteConfirm:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover-danger); }\n\n.fetchDialog { max-width: 520px; }\n.candidateToolbar { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }\n.candidateSearch { min-width: 0; flex: 1 1 240px; }\n.candidateList { display: flex; flex-direction: column; gap: 2px; max-height: 320px; margin: 0; overflow-y: auto; padding: 0; list-style: none; }\n.candidate { border-radius: 6px; }\n.candidateLabel { display: flex; align-items: center; gap: 8px; padding: 6px 8px; cursor: pointer; }\n.candidateId { flex: 1 1 auto; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; overflow-wrap: anywhere; }\n.candidateEmpty { margin: 24px 0; color: var(--dsw-alias-label-secondary); font-size: 13px; line-height: 20px; text-align: center; }\n\n/* ---- extension block (plugin-owned; official token palette) ---- */\n[hidden] { display: none !important; }\n.extBlock { border: 0.5px solid var(--dsw-alias-border-l3); border-radius: 10px; padding: 10px; margin: 8px 4px 2px; background: var(--dsw-alias-bg-layer-1); display: flex; flex-direction: column; gap: 10px; }\n.extGroup { border-top: 0.5px solid var(--dsw-alias-border-l2); padding-top: 12px; }\n.extGroupFirst { border-top: none; padding-top: 0; }\n.extCheck { display: flex; align-items: flex-start; gap: 8px; cursor: pointer; }\n.extCheckLabel { font-size: 14px; line-height: 22px; color: var(--dsw-alias-label-primary); }\n.extHint { font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-tertiary); }\n.extGated { display: flex; flex-direction: column; gap: 12px; padding-left: 2px; }\n.extField { display: flex; flex-direction: column; gap: 6px; }\n.extLabel { font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-tertiary); }\n.extTable { border: 0.5px solid var(--dsw-alias-border-l4); border-radius: 8px; overflow: hidden; }\n.extTHead { display: grid; grid-template-columns: 64px minmax(0,1fr) minmax(0,1.2fr); font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-tertiary); background: var(--dsw-alias-bg-module-platform); }\n.extTHead > div { padding: 6px 10px; }\n.extTHead > div + div { border-left: 0.5px solid var(--dsw-alias-border-l2); }\n.extTRow { display: grid; grid-template-columns: 64px minmax(0,1fr) minmax(0,1.2fr); align-items: center; border-top: 0.5px solid var(--dsw-alias-border-l2); }\n.extTRow > div { padding: 6px 10px; font-size: 14px; }\n.extTRow > div + div { border-left: 0.5px solid var(--dsw-alias-border-l2); }\n.extTRow input[type=\"text\"] { box-sizing: border-box; width: 100%; height: 32px; padding: 0 10px; border: 0.5px solid var(--dsw-alias-border-l4); border-radius: 8px; font: inherit; font-size: 14px; background: var(--dsw-alias-bg-layer-1); color: var(--dsw-alias-label-primary); }\n.extTRow input[type=\"text\"]:disabled { opacity: 0.6; cursor: default; }\n.extCheckbox { accent-color: var(--dsw-alias-brand-primary); width: 15px; height: 15px; flex: none; }\n.switchRow { display: flex; align-items: center; gap: 8px; font-size: 14px; line-height: 22px; cursor: pointer; }\n.extTag { flex: none; padding: 1px 6px; border: 0.5px solid rgba(65,118,230,0.35); border-radius: 4px; background: var(--dsw-static-deepseek-100); color: var(--dsw-static-deepseek-600); font-size: 11px; line-height: 16px; font-weight: 500; }\n\n/* ---- modal (matches the ui-primitives look closely enough for these two dialogs) ---- */\n.modalMask { position: fixed; inset: 0; background: var(--dsw-alias-bg-mask-1); display: flex; align-items: center; justify-content: center; z-index: 100; padding: 24px; }\n.modal { background: var(--dsw-specific-menu); border-radius: 16px; padding: 20px; width: 100%; box-shadow: 0 12px 40px rgba(0,0,0,0.18); }\n.modalTitle { font-size: 16px; line-height: 24px; font-weight: 500; margin-bottom: 8px; color: var(--dsw-alias-label-primary); }\n.modalDesc { font-size: 14px; line-height: 22px; color: var(--dsw-alias-label-secondary); margin-bottom: 16px; }\n.modalFoot { display: flex; justify-content: flex-end; gap: 8px; }\n\n/* ---- quick-load dropdown (filtered, max 10 candidates, never a static datalist) ---- */\n.quickWrap { position: relative; display: flex; flex-direction: column; gap: 6px; }\n.quickList { position: absolute; top: 100%; left: 0; right: 0; z-index: 20; margin-top: 2px; padding: 4px; border: 0.5px solid var(--dsw-alias-border-l3); border-radius: 8px; background: var(--dsw-specific-menu); box-shadow: 0 8px 24px rgba(0,0,0,0.12); max-height: 264px; overflow-y: auto; }\n.quickItem { display: block; width: 100%; padding: 6px 8px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-primary); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; text-align: left; cursor: pointer; overflow-wrap: anywhere; }\n.quickItem:hover { background: var(--dsw-alias-interactive-bg-hover); }\n.quickEmpty { padding: 6px 8px; font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-tertiary); }\n\n@media (prefers-reduced-motion: reduce) {\n .customizedSummary::before { transition: none; }\n}\n","/**\n * Quick-load: a searchable dropdown over the models.dev metadata index.\n * Plan constraints: ids only, case-insensitive substring match, at most 10\n * candidates rendered — the index is filtered on every keystroke and the\n * candidate list is only mounted while open, so a 370-row index never lands\n * in the DOM wholesale.\n */\n\nimport { useState } from 'react'\nimport type { ReactNode } from 'react'\nimport { getMetadataIndex, searchModelIds } from './models-index.ts'\nimport type { MetadataEntry } from './models-index.ts'\nimport styles from './models-plus.module.css'\n\n/** Props of {@link QuickLoad}. */\nexport interface QuickLoadProps {\n /** Apply one metadata entry to the current model draft. */\n onPick: (entry: MetadataEntry) => void\n /** Disable while a write is in flight. */\n disabled: boolean\n}\n\n/**\n * Render the quick-load input with its filtered candidate dropdown.\n * @param props - the pick handler and disabled flag.\n * @returns the quick-load field.\n */\nexport function QuickLoad(props: QuickLoadProps): ReactNode {\n const [query, setQuery] = useState('')\n const [open, setOpen] = useState(false)\n const [index, setIndex] = useState<readonly MetadataEntry[] | undefined>(undefined)\n\n const ensureIndex = (): void => {\n if (index !== undefined) return\n void getMetadataIndex().then((loaded) => { setIndex(loaded) })\n }\n\n const hits = searchModelIds(index, query, 10)\n\n const pick = (id: string): void => {\n const entry = index?.find(candidate => candidate.id === id)\n setOpen(false)\n setQuery('')\n if (entry !== undefined) props.onPick(entry)\n }\n\n return (\n <div className={styles['quickWrap']}>\n <span className={styles['extLabel']}>快速装入</span>\n <input\n className={styles['input']}\n type=\"text\"\n value={query}\n placeholder=\"搜索模型 id(如 aper)…\"\n aria-label=\"快速装入\"\n disabled={props.disabled}\n onFocus={() => { ensureIndex(); setOpen(true) }}\n onBlur={() => { setOpen(false) }}\n onChange={(event) => { setQuery(event.target.value); setOpen(true) }}\n />\n {open\n ? (\n <div className={styles['quickList']}>\n {index === undefined\n ? <span className={styles['quickEmpty']}>元数据预填不可用——点击页首「下载/更新元数据」</span>\n : hits.length === 0\n ? <span className={styles['quickEmpty']}>{query.trim().length === 0 ? '输入关键字搜索模型 id' : '没有匹配的模型'}</span>\n : hits.map(id => (\n <button\n type=\"button\"\n key={id}\n className={styles['quickItem']}\n onMouseDown={(event) => {\n // mousedown beats the input's blur handler.\n event.preventDefault()\n pick(id)\n }}\n >\n {id}\n </button>\n ))}\n </div>\n )\n : null}\n </div>\n )\n}\n","/**\n * One model entry's expanded panel: quick-load, capacities (the official\n * modelAdvanced fields, merged into this block per the v1.0.0 design), input\n * modalities, the developer-role tri-state, the reasoning-effort gate and its\n * gated area (thinking format, then the seven-level effort table).\n *\n * Every edit patches the row's draft object through `onChange` — persistence\n * rides the card's existing path-ops save with no extra wire calls. Clearing\n * the effort gate drops `reasoningEfforts` AND `compat.thinkingFormat` in ONE\n * commit so partial updates never overwrite each other (no orphan settings).\n */\n\nimport { useState } from 'react'\nimport type { ReactNode } from 'react'\nimport { THINKING_FORMATS, THINKING_LEVELS } from '../extension-meta.ts'\nimport type { ModelDraft } from './compat.ts'\nimport { formatCapacity, parseCapacity } from './compat.ts'\nimport { QuickLoad } from './QuickLoad.tsx'\nimport type { MetadataEntry } from './models-index.ts'\nimport styles from './models-plus.module.css'\n\n/** The row's compat sub-object as a plain record (absent → empty). */\nfunction compatOf(model: ModelDraft): Record<string, unknown> {\n const value = model['compat']\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? value as Record<string, unknown>\n : {}\n}\n\n/** The row's reasoningEfforts dict (absent/invalid → undefined = not declared). */\nfunction effortsOf(model: ModelDraft): Record<string, string | null> | undefined {\n const value = model['reasoningEfforts']\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return undefined\n return value as Record<string, string | null>\n}\n\n/** The row's input modality list (absent → empty, matching the host reader). */\nfunction inputsOf(model: ModelDraft): readonly string[] {\n const value = model['input']\n return Array.isArray(value) ? value.filter((m): m is string => typeof m === 'string') : []\n}\n\n/** Props of {@link ModelEntryPanel}. */\nexport interface ModelEntryPanelProps {\n /** The row's current draft (read). */\n model: ModelDraft\n /** Replace the row with this next draft; `undefined`-valued keys clear them. */\n onChange: (next: ModelDraft) => void\n /** Disable every control (read-only deployment or a pending write). */\n disabled: boolean\n}\n\n/**\n * Render one model entry's expanded panel.\n * @param props - the row draft, its writer, and the disabled flag.\n * @returns the expanded panel.\n */\nexport function ModelEntryPanel(props: ModelEntryPanelProps): ReactNode {\n const { model, onChange, disabled } = props\n\n // Capacities are text-edited, so keystrokes live in this buffer rather than\n // being re-derived from the parsed count (which would rewrite `1000` to\n // `1K` mid-word). Unreadable text stays on screen for the save-time check.\n const [capacityText, setCapacityText] = useState<ReadonlyMap<string, string>>(() => new Map())\n\n /** Patch one key onto the row; `undefined` clears it. */\n const setKey = (key: string, value: unknown): void => {\n const next = { ...model }\n if (value === undefined) Reflect.deleteProperty(next, key)\n else next[key] = value\n onChange(next)\n }\n\n /** Patch one key inside `compat`; an emptied compat leaves no trace. */\n const setCompatKey = (key: string, value: unknown): void => {\n const compat = { ...compatOf(model) }\n if (value === undefined) Reflect.deleteProperty(compat, key)\n else compat[key] = value\n setKey('compat', Object.keys(compat).length === 0 ? undefined : compat)\n }\n\n const setEfforts = (efforts: Record<string, string | null> | undefined): void => {\n setKey('reasoningEfforts', efforts)\n }\n\n const setInput = (modalities: readonly string[]): void => {\n setKey('input', modalities.length === 0 ? undefined : [...modalities])\n }\n\n // --- quick load ----------------------------------------------------------\n const applyMetadata = (entry: MetadataEntry): void => {\n // Only the four metadata fields are overwritten; everything else keeps\n // its draft value (a fresh row already carries the v1.0.0 defaults).\n const next = { ...model }\n if (entry.context === undefined) Reflect.deleteProperty(next, 'contextWindow')\n else next['contextWindow'] = entry.context\n if (entry.output === undefined) Reflect.deleteProperty(next, 'maxTokens')\n else next['maxTokens'] = entry.output\n const compat = { ...compatOf(model) }\n compat['supportsReasoningEffort'] = entry.reasoning\n if (!entry.reasoning) {\n // A non-reasoning model: keep the draft free of orphan gated values.\n Reflect.deleteProperty(compat, 'thinkingFormat')\n Reflect.deleteProperty(next, 'reasoningEfforts')\n }\n setKey('compat', Object.keys(compat).length === 0 ? undefined : compat)\n const supported = entry.input.filter(m => m === 'text' || m === 'image')\n if (supported.length > 0) next['input'] = supported\n onChange(next)\n setCapacityText(new Map())\n }\n\n // --- capacities ----------------------------------------------------------\n const capacityField = (field: 'contextWindow' | 'maxTokens', label: string): ReactNode => {\n const stored = model[field]\n const typed = capacityText.get(field)\n const text = typed ?? (typeof stored === 'number' ? formatCapacity(stored) : '')\n return (\n <label className={styles['modelField']}>\n <span className={styles['modelFieldLabel']}>{label}</span>\n <input\n className={styles['input']}\n type=\"text\"\n inputMode=\"numeric\"\n value={text}\n placeholder=\"使用提供方默认值\"\n aria-label={label}\n disabled={disabled}\n onChange={(event) => {\n setCapacityText(current => new Map(current).set(field, event.target.value))\n setKey(field, parseCapacity(event.target.value))\n }}\n onBlur={() => {\n const raw = capacityText.get(field)\n if (raw === undefined) return\n const parsed = parseCapacity(raw)\n // Unreadable text stays on screen; the save-time check names it.\n if (parsed !== undefined && Number.isNaN(parsed)) return\n setCapacityText(current => {\n const next = new Map(current)\n next.delete(field)\n return next\n })\n }}\n />\n </label>\n )\n }\n\n // --- developer role (tri-state, NOT gated) -------------------------------\n const compat = compatOf(model)\n const developerRole = compat['supportsDeveloperRole'] !== false\n\n // --- effort gate ----------------------------------------------------------\n const supportsReasoningEffort = compat['supportsReasoningEffort'] === true\n const efforts = effortsOf(model)\n\n const toggleGate = (checked: boolean): void => {\n if (checked) {\n setCompatKey('supportsReasoningEffort', true)\n return\n }\n // One commit clears the flag AND every gated node — no orphan settings.\n const nextCompat = { ...compat }\n Reflect.deleteProperty(nextCompat, 'supportsReasoningEffort')\n Reflect.deleteProperty(nextCompat, 'thinkingFormat')\n const next = { ...model, compat: Object.keys(nextCompat).length === 0 ? undefined : nextCompat }\n Reflect.deleteProperty(next, 'reasoningEfforts')\n onChange(next)\n }\n\n const toggleLevel = (level: string, checked: boolean): void => {\n const current = { ...(efforts ?? {}) }\n if (checked) current[level] = level === 'off' ? null : level\n else Reflect.deleteProperty(current, level)\n setEfforts(Object.keys(current).length === 0 ? undefined : current)\n }\n\n const setWireValue = (level: string, text: string): void => {\n if (efforts === undefined || !(level in efforts)) return\n const current = { ...efforts }\n current[level] = text.trim().length === 0 ? null : text.trim()\n setEfforts(current)\n }\n\n // --- validation (mirrors the host checks) --------------------------------\n const declaredLevels = efforts === undefined ? [] : THINKING_LEVELS.filter(level => level in efforts)\n const hasEmptyWire = declaredLevels.some(level =>\n level !== 'off' && String(efforts?.[level] ?? '').trim().length === 0)\n const onlyOffDeclared = efforts !== undefined\n && declaredLevels.length > 0\n && !declaredLevels.some(level => level !== 'off')\n\n // --- input modalities ------------------------------------------------------\n const inputList = inputsOf(model)\n const toggleModality = (modality: string, checked: boolean): void => {\n // Reading defaults to text-bearing rows; an explicit list wins.\n const base = inputList.length === 0 && model['input'] === undefined ? ['text'] : [...inputList]\n setInput(checked ? [...new Set([...base, modality])] : base.filter(m => m !== modality))\n }\n\n return (\n <div className={styles['extBlock']}>\n <div className={`${styles['extGroup']} ${styles['extGroupFirst']}`}>\n <QuickLoad onPick={applyMetadata} disabled={disabled} />\n </div>\n\n <div className={styles['extGroup']}>\n <div className={styles['modelField']} style={{ padding: '0 4px' }}>\n {capacityField('contextWindow', '上下文窗口')}\n {capacityField('maxTokens', '最大输出 token')}\n </div>\n </div>\n\n <div className={styles['extGroup']}>\n <span className={styles['extLabel']} style={{ marginBottom: 6 }}>输入模态</span>\n <div style={{ display: 'flex', gap: 18 }}>\n {['text', 'image'].map(modality => (\n <label key={modality} className={styles['switchRow']}>\n <input\n type=\"checkbox\"\n className={styles['extCheckbox']}\n checked={inputList.includes(modality)}\n disabled={disabled}\n onChange={(event) => { toggleModality(modality, event.target.checked) }}\n />\n {modality === 'text' ? '文本' : '图像'}\n </label>\n ))}\n </div>\n </div>\n\n <div className={styles['extGroup']}>\n <label className={styles['extCheck']}>\n <input\n type=\"checkbox\"\n className={styles['extCheckbox']}\n style={{ marginTop: 3 }}\n checked={developerRole}\n disabled={disabled}\n onChange={(event) => {\n // Checked is the natural default, so a check REMOVES the key;\n // only an explicit uncheck writes `false`.\n setCompatKey('supportsDeveloperRole', event.target.checked ? undefined : false)\n }}\n />\n <span style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\n <span className={styles['extCheckLabel']}>允许以 developer 角色发送系统提示</span>\n <span className={styles['extHint']}>\n 推理模型的系统提示将以 developer 角色发出;网关拒绝该角色时取消勾选,改用 system。\n </span>\n </span>\n </label>\n </div>\n\n <div className={styles['extGroup']}>\n <label className={styles['switchRow']}>\n <input\n type=\"checkbox\"\n className={styles['extCheckbox']}\n checked={supportsReasoningEffort}\n disabled={disabled}\n onChange={(event) => { toggleGate(event.target.checked) }}\n />\n 端点接受推理挡位参数(reasoning_effort)\n </label>\n </div>\n\n {/* Gated area: HIDDEN (not dimmed) while the gate is off. */}\n <div className={styles['extGated']} hidden={!supportsReasoningEffort}>\n <div className={styles['extField']}>\n <span className={styles['extLabel']}>思考格式</span>\n <select\n className={`${styles['input']} ${styles['selectInput']}`}\n value={typeof compat['thinkingFormat'] === 'string' ? compat['thinkingFormat'] : ''}\n disabled={disabled}\n onChange={(event) => { setCompatKey('thinkingFormat', event.target.value === '' ? undefined : event.target.value) }}\n >\n <option value=\"\">—</option>\n {THINKING_FORMATS.map(format => <option key={format} value={format}>{format}</option>)}\n </select>\n </div>\n\n <div className={styles['extField']}>\n <span className={styles['extLabel']}>推理挡位</span>\n <div className={styles['extTable']}>\n <div className={styles['extTHead']}>\n <div>声明</div><div>挡位</div><div>线上取值</div>\n </div>\n {THINKING_LEVELS.map((level) => {\n const declared = efforts !== undefined && level in efforts\n const isOff = level === 'off'\n const wire = declared ? String(efforts?.[level] ?? '') : ''\n return (\n <div key={level} className={styles['extTRow']}>\n <div style={{ display: 'flex', justifyContent: 'center' }}>\n <input\n type=\"checkbox\"\n className={styles['extCheckbox']}\n checked={declared}\n disabled={disabled}\n aria-label={`声明 ${level}`}\n onChange={(event) => { toggleLevel(level, event.target.checked) }}\n />\n </div>\n <div style={{ opacity: declared ? 1 : 0.5 }}>{level}</div>\n <div style={{ opacity: declared ? 1 : 0.4 }}>\n {declared && !isOff\n ? (\n <input\n type=\"text\"\n value={wire}\n placeholder={level}\n aria-label={`${level} 线上取值`}\n disabled={disabled}\n onChange={(event) => { setWireValue(level, event.target.value) }}\n />\n )\n : <span style={{ fontSize: 12, color: 'var(--dsw-alias-label-tertiary)' }}>—</span>}\n </div>\n </div>\n )\n })}\n </div>\n {hasEmptyWire || onlyOffDeclared\n ? (\n <p className={styles['error']} style={{ marginTop: 6 }}>\n {hasEmptyWire ? '除 off 外勾选的挡位必须填写线上取值。' : '至少声明一个 off 以外的挡位。'}\n </p>\n )\n : null}\n </div>\n </div>\n </div>\n )\n}\n\n","/**\n * One provider profile's model catalog: rows joined from the draft's `models`\n * array, the fetch action (interrogating the endpoint the form currently\n * shows), and the candidate-picker modal. Each row's expanded panel is the\n * plugin's ModelEntryPanel — capacities and extension fields in one block.\n */\n\nimport { useState } from 'react'\nimport type { ReactNode } from 'react'\nimport type { LlmDiscoveredModel } from '@deepseek-ai/dsh-api-remotes/client'\nimport { Modal } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { ModelDraft } from './compat.ts'\nimport { newModelDraft } from './presets.ts'\nimport { ModelEntryPanel } from './ModelEntryPanel.tsx'\nimport type { ModelsOperations } from '../vendor/operations.ts'\nimport styles from './models-plus.module.css'\n\n/** Endpoint facts for the fetch action, taken from the live form. */\nexport interface ProbeTarget {\n readonly settingsNs: string\n readonly provider?: string\n readonly baseURL?: string\n readonly api?: string\n readonly apiKey?: string\n}\n\n/** Props of {@link ModelCatalog}. */\nexport interface ModelCatalogProps {\n /** The drafted rows (inherited rows until the first edit materializes an override). */\n models: readonly ModelDraft[]\n /** Whether the user layer owns the whole array. */\n overridden: boolean\n /** DeepSeek-family route-level fallbacks (undefined on the pi-ai family). */\n defaultContextWindow: number | undefined\n defaultMaxTokens: number | undefined\n /** Endpoint facts for the fetch action. */\n probe: ProbeTarget\n /** Why the fetch action is unavailable, or undefined when it is. */\n probeBlocked?: string\n /** The Host operations whose interrogation answers the fetch action. */\n operations: ModelsOperations\n /** Disable every control (read-only deployment or a pending write). */\n disabled: boolean\n /** Replace the drafted rows. */\n onChange: (models: ModelDraft[]) => void\n /** Remove the user-owned array and return to inheritance. */\n onReset?: () => void\n}\n\n/** A row's text field, or the empty string when unset or not a string. */\nfunction textOf(model: ModelDraft, key: string): string {\n const value = model[key]\n return typeof value === 'string' ? value : ''\n}\n\n/** Adopt one candidate, v1.0.0 defaults + the endpoint's disclosed capacities. */\nfunction adopt(candidate: LlmDiscoveredModel): ModelDraft {\n const row = newModelDraft()\n row['id'] = candidate.id\n row['name'] = candidate.name ?? candidate.id\n if (candidate.contextWindow !== undefined) row['contextWindow'] = candidate.contextWindow\n if (candidate.maxTokens !== undefined) row['maxTokens'] = candidate.maxTokens\n return row\n}\n\n/**\n * Render the model catalog with its fetch action.\n * @param props - the drafted rows, probe target, wire face, and mutators.\n * @returns the catalog editor.\n */\nexport function ModelCatalog(props: ModelCatalogProps): ReactNode {\n const { models, onChange, probe, operations, disabled } = props\n\n const [busy, setBusy] = useState(false)\n const [failure, setFailure] = useState<string | undefined>(undefined)\n const [candidates, setCandidates] = useState<readonly LlmDiscoveredModel[] | undefined>(undefined)\n const [picked, setPicked] = useState<ReadonlySet<string>>(() => new Set())\n const [query, setQuery] = useState('')\n const [expanded, setExpanded] = useState<ReadonlySet<number>>(() => new Set())\n\n const patch = (index: number, next: Record<string, string | number | undefined>): void => {\n onChange(models.map((model, at) => {\n if (at !== index) return model\n const cleared = new Set(\n Object.entries(next).filter(([, value]) => value === undefined || value === '').map(([key]) => key),\n )\n return Object.fromEntries(\n Object.entries({ ...model, ...next }).filter(([key]) => !cleared.has(key)),\n )\n }))\n }\n\n const toggleExpanded = (index: number): void => {\n setExpanded((current) => {\n const next = new Set(current)\n if (!next.delete(index)) next.add(index)\n return next\n })\n }\n\n const removeRow = (index: number): void => {\n onChange(models.filter((_model, at) => at !== index))\n // Both stores are keyed by position; shift the rows after this one down.\n setExpanded((current) => {\n const next = new Set<number>()\n for (const at of current) {\n if (at < index) next.add(at)\n else if (at > index) next.add(at - 1)\n }\n return next\n })\n }\n\n const fetchModels = async (): Promise<void> => {\n setBusy(true)\n setFailure(undefined)\n try {\n const answer = await operations.discoverModels(probe.settingsNs, {\n ...probe.provider === undefined ? {} : { provider: probe.provider },\n ...probe.baseURL === undefined || probe.baseURL.length === 0 ? {} : { baseURL: probe.baseURL },\n ...probe.api === undefined ? {} : { api: probe.api },\n ...probe.apiKey === undefined ? {} : { apiKey: probe.apiKey },\n })\n if (answer.kind === 'refused') {\n setFailure(answer.message)\n return\n }\n const found = answer.models\n if (found.length === 0) {\n setFailure('该提供方没有列出任何模型,请手动添加。')\n return\n }\n const known = new Set(models.map(model => textOf(model, 'id')))\n setQuery('')\n setCandidates(found)\n setPicked(new Set(found.filter(model => !known.has(model.id)).map(model => model.id)))\n } finally {\n setBusy(false)\n }\n }\n\n const closePicker = (): void => {\n setCandidates(undefined)\n setPicked(new Set())\n setQuery('')\n }\n\n const adoptPicked = (): void => {\n if (candidates === undefined) return\n const byId = new Map(models.map(model => [textOf(model, 'id'), model]))\n for (const candidate of candidates) {\n if (!picked.has(candidate.id)) continue\n // A row the user already tuned wins over the provider's own numbers.\n byId.set(candidate.id, byId.get(candidate.id) ?? adopt(candidate))\n }\n onChange([...byId.values()])\n closePicker()\n }\n\n const toggle = (id: string): void => {\n setPicked((current) => {\n const next = new Set(current)\n if (!next.delete(id)) next.add(id)\n return next\n })\n }\n\n const activeCandidates = candidates ?? []\n const needle = query.trim().toLowerCase()\n const visible = needle.length === 0\n ? activeCandidates\n : activeCandidates.filter(candidate => candidate.id.toLowerCase().includes(needle))\n const allPicked = visible.length > 0 && visible.every(candidate => picked.has(candidate.id))\n\n // A route the adapter already describes answers without an endpoint.\n const askable = probe.provider !== undefined || (probe.baseURL !== undefined && probe.baseURL.length > 0)\n\n return (\n <section className={styles['modelCatalog']} aria-label=\"模型目录\">\n <div className={styles['modelListHead']}>\n <div className={styles['modelCatalogHeading']}>\n <span className={styles['modelCatalogTitle']}>模型目录</span>\n <span className={styles['modelCatalogMeta']}>\n {props.overridden ? '已自定义模型目录' : '正在使用适配器默认模型'}\n </span>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>\n {props.overridden && props.onReset !== undefined\n ? (\n <button\n type=\"button\"\n className={styles['linkButton']}\n disabled={disabled}\n onClick={props.onReset}\n >\n 恢复默认模型\n </button>\n )\n : null}\n <button\n type=\"button\"\n className={styles['linkButton']}\n disabled={disabled || busy || !askable || props.probeBlocked !== undefined}\n title={props.probeBlocked !== undefined\n ? props.probeBlocked\n : askable ? undefined : '请先填写 API 地址,再获取。'}\n onClick={() => { void fetchModels() }}\n >\n {busy ? '正在询问提供方…' : '获取可用模型'}\n </button>\n </div>\n </div>\n\n {models.length === 0\n ? <p className={styles['modelEmpty']}>模型选择器中将不显示任何模型;目录外 ID 仍可直接发送。</p>\n : (\n <div className={styles['modelList']}>\n {models.map((model, index) => (\n <div\n key={`${String(index)}:${textOf(model, 'id')}`}\n className={styles['modelEntry']}\n >\n <div className={styles['modelRow']}>\n <input\n className={styles['input']}\n type=\"text\"\n value={textOf(model, 'id')}\n placeholder=\"模型 ID\"\n aria-label={`模型 ID ${String(index + 1)}`}\n disabled={disabled}\n onChange={(event) => { patch(index, { id: event.target.value }) }}\n />\n <input\n className={styles['input']}\n type=\"text\"\n value={textOf(model, 'name')}\n placeholder=\"显示名称\"\n aria-label={`显示名称 ${String(index + 1)}`}\n disabled={disabled}\n onChange={(event) => { patch(index, { name: event.target.value === '' ? undefined : event.target.value }) }}\n />\n <button\n type=\"button\"\n className={styles['iconButton']}\n aria-label={`容量 ${String(index + 1)}`}\n aria-expanded={expanded.has(index)}\n title=\"容量\"\n onClick={() => { toggleExpanded(index) }}\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\" style={{ transform: expanded.has(index) ? 'rotate(90deg)' : undefined, transition: 'transform 120ms ease' }}>\n <path d=\"M6 3.5L10.5 8L6 12.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n <button\n type=\"button\"\n className={`${styles['iconButton']} ${styles['iconButtonDanger']}`}\n aria-label={`删除模型 ${String(index + 1)}`}\n title=\"删除模型\"\n disabled={disabled}\n onClick={() => { removeRow(index) }}\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M2.5 4h11M6.5 4V2.5h3V4M4 4l.7 9a1 1 0 001 .9h4.6a1 1 0 001-.9L12 4M6.5 6.8v4.4M9.5 6.8v4.4\" stroke=\"currentColor\" strokeWidth=\"1.3\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n </div>\n {expanded.has(index)\n ? (\n <ModelEntryPanel\n model={model}\n disabled={disabled}\n onChange={(next) => {\n onChange(models.map((row, at) => (at === index ? next : row)))\n }}\n />\n )\n : null}\n </div>\n ))}\n </div>\n )}\n\n <button\n type=\"button\"\n className={styles['addModelButton']}\n disabled={disabled}\n onClick={() => { onChange([...models, newModelDraft()]) }}\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M8 3.5v9M3.5 8h9\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n 添加模型\n </button>\n\n {failure !== undefined ? <p className={styles['error']}>{failure}</p> : null}\n\n <Modal\n open={candidates !== undefined}\n onClose={closePicker}\n title=\"选择要添加的模型\"\n closeLabel=\"关闭\"\n description=\"以下是模型提供方的可用模型,勾选要添加的模型。\"\n className={styles['fetchDialog'] as string}\n footer={(\n <>\n <button type=\"button\" className={styles['secondaryButton']} onClick={closePicker}>取消</button>\n <button type=\"button\" className={styles['primaryButton']} onClick={adoptPicked}>添加所选</button>\n </>\n )}\n >\n <div className={styles['candidateToolbar']}>\n <input\n className={`${styles['input']} ${styles['candidateSearch']}`}\n type=\"search\"\n value={query}\n placeholder=\"搜索模型\"\n aria-label=\"搜索模型\"\n onChange={(event) => { setQuery(event.target.value) }}\n />\n <button\n type=\"button\"\n className={styles['linkButton']}\n disabled={visible.length === 0}\n onClick={() => {\n setPicked(current => {\n if (visible.every(candidate => current.has(candidate.id))) {\n return new Set([...current].filter(id => !visible.some(candidate => candidate.id === id)))\n }\n return new Set([...current, ...visible.map(candidate => candidate.id)])\n })\n }}\n >\n {allPicked ? '取消全选' : '全选'}\n </button>\n </div>\n {visible.length === 0\n ? <p className={styles['candidateEmpty']} role=\"status\">没有匹配的模型。</p>\n : (\n <ul className={styles['candidateList']}>\n {visible.map(candidate => (\n <li key={candidate.id} className={styles['candidate']}>\n <label className={styles['candidateLabel']}>\n <input\n type=\"checkbox\"\n checked={picked.has(candidate.id)}\n onChange={() => { toggle(candidate.id) }}\n />\n <span className={styles['candidateId']}>{candidate.id}</span>\n </label>\n </li>\n ))}\n </ul>\n )}\n </Modal>\n </section>\n )\n}\n\n","/**\n * One existing provider's editor card, fully plugin-owned (v1.0.0 rewrite).\n * Primary field: a single write-only API key input; the collapsed\n * 「供应商」 section carries baseURL (plus displayName/protocol for a\n * hand-declared route), the 「模型」 section the model catalog with the\n * extension panel. Save semantics mirror the host card: minimal path ops\n * against the stored section with a revision fence, then the credential\n * write — the draft comes from the user layer, so a wholesale replace can\n * never delete fields outside the card.\n */\n\nimport { useEffect, useMemo, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport type { CredentialInfo, SettingsNamespaceView } from '@deepseek-ai/dsh-api-remotes/client'\nimport { deriveKeyRef, protocolChoices } from '../vendor/store.ts'\nimport type { ModelsOperations } from '../vendor/operations.ts'\nimport type { SettingsSchemaOperations } from '../vendor/schema-operations.ts'\nimport type { ModelDraft } from './compat.ts'\nimport { modelDrafts, normalizeModelRow, pathOps, validateModelRows } from './compat.ts'\nimport { ModelCatalog } from './ModelCatalog.tsx'\nimport styles from './models-plus.module.css'\n\n/** The public DeepSeek endpoint shown as the deepseek base-URL placeholder. */\nconst DEEPSEEK_PUBLIC_BASE_URL = 'https://api.deepseek.com'\n\n/** Per-adapter-family curated field sets (unknown namespaces get the hint alone). */\nexport type EditorLayout = 'deepseek' | 'pi-ai' | 'unknown'\n\n/** The editor layout the owning namespace selects. */\nexport function layoutOf(ns: string): EditorLayout {\n if (ns === 'llm-deepseek') return 'deepseek'\n if (ns === 'llm-pi-ai') return 'pi-ai'\n return 'unknown'\n}\n\n/** A user-section subtree as a plain draft object (absent → empty). */\nexport function draftAt(\n schema: SettingsSchemaOperations,\n namespace: SettingsNamespaceView,\n path: readonly string[],\n): Record<string, unknown> {\n const subtree = schema.getPath(namespace.user, path)\n if (typeof subtree !== 'object' || subtree === null || Array.isArray(subtree)) return {}\n return structuredClone(subtree) as Record<string, unknown>\n}\n\n/** The credential reference this profile resolves keys through. */\nfunction refFor(\n schema: SettingsSchemaOperations,\n namespace: SettingsNamespaceView,\n path: readonly string[],\n provider: string,\n): string {\n const profile = schema.getPath(namespace.value, path)\n const named = typeof profile === 'object' && profile !== null\n ? (profile as { apiKeyEnv?: unknown }).apiKeyEnv\n : undefined\n return typeof named === 'string' && named.length > 0 ? named : deriveKeyRef(provider)\n}\n\n/** Props of {@link ProviderEditor}. */\nexport interface ProviderEditorProps {\n /** Provider route id. */\n provider: string\n /** Display name for the card title. */\n displayName: string\n /** Whether the adapter reports this route as hand-declared. */\n declared?: boolean\n /** The owning namespace view (schema, layers, secrets). */\n namespace: SettingsNamespaceView\n /** Settings-owned synchronous schema and immutable path operations. */\n schema: SettingsSchemaOperations\n /** Path from the section root to this provider's profile. */\n settingsPath: readonly string[]\n /** The Host operations this card writes and interrogates through. */\n operations: ModelsOperations\n /** Disable writes (read-only settings provider). */\n readOnly: boolean\n /** Close the editor; `changed` reports whether an Apply committed. */\n onClose: (changed: boolean) => void\n}\n\n/**\n * Render one existing provider's editing card.\n * @param props - the addressed profile plus wire faces.\n * @returns the editor card.\n */\nexport function ProviderEditor(props: ProviderEditorProps): ReactNode {\n const { namespace, schema, settingsPath, operations } = props\n const [draft, setDraft] = useState<Record<string, unknown>>(() => draftAt(schema, namespace, settingsPath))\n const [tab, setTab] = useState<'provider' | 'models'>('provider')\n const [keyDraft, setKeyDraft] = useState('')\n const [keyState, setKeyState] = useState<CredentialInfo | undefined>(undefined)\n const [busy, setBusy] = useState(false)\n const [failure, setFailure] = useState<string | undefined>(undefined)\n const [committedOriginal, setCommittedOriginal] = useState<unknown>(\n () => schema.getPath(namespace.user, settingsPath),\n )\n const [expectedRevision, setExpectedRevision] = useState(() => namespace.revision)\n const root = useMemo(() => schema.rehydrate(namespace.schema), [namespace.schema, schema])\n const node = useMemo(() => schema.nodeAtPath(root, settingsPath), [root, schema, settingsPath])\n const fallback = schema.getPath(namespace.value, settingsPath)\n const disabled = props.readOnly || busy\n const layout = layoutOf(namespace.ns)\n const keyRef = refFor(schema, namespace, settingsPath, props.provider)\n const protocols = useMemo(\n () => layout === 'pi-ai' ? protocolChoices(namespace, schema) : [],\n [layout, namespace, schema],\n )\n\n useEffect(() => {\n let stale = false\n setKeyState(undefined)\n void operations.describeCredential(keyRef).then((described) => {\n if (stale) return\n setKeyState(described)\n })\n return () => { stale = true }\n }, [operations, keyRef])\n\n const stringAt = (source: unknown, key: string): string | undefined => {\n const value = schema.getPath(source, [key])\n return typeof value === 'string' && value.trim().length > 0 ? value : undefined\n }\n const setField = (key: string, next: string | undefined): void => {\n const value = next === undefined || next.trim().length === 0 ? undefined : next\n setDraft((current) => value === undefined\n ? schema.deletePath(current, [key])\n : schema.setPath(current, [key], value))\n }\n\n const modelFailure = validateModelRows(schema.getPath(draft, ['models']))\n const keyFailure = ((): 'keyBlank' | 'keyIllegalCharacters' | undefined => {\n if (keyDraft.length === 0) return undefined\n const value = keyDraft.trim()\n if (value.length === 0) return 'keyBlank'\n // Mirrors the host's apiKeyFailure heuristics (env line / quoted / charset).\n if (/^[A-Z][A-Z0-9_]*=[^=]/.test(value)) return 'keyIllegalCharacters'\n const first = value[0]\n if ((first === '\"' || first === '\\'' || first === '`') && value.length > 1 && value.endsWith(first)) {\n return 'keyIllegalCharacters'\n }\n return /^[\\x21-\\x7E]+$/.test(value) ? undefined : 'keyIllegalCharacters'\n })()\n const keyValue = keyDraft.trim()\n\n const probe = {\n settingsNs: namespace.ns,\n provider: props.provider,\n ...(() => {\n const baseURL = stringAt(draft, 'baseURL') ?? stringAt(fallback, 'baseURL')\n return baseURL === undefined ? {} : { baseURL }\n })(),\n ...(() => {\n const api = layout === 'pi-ai' && props.declared === true\n ? stringAt(draft, 'api') ?? stringAt(fallback, 'api')\n : undefined\n return api === undefined ? {} : { api }\n })(),\n ...keyValue.length === 0 ? {} : { apiKey: keyValue },\n }\n\n /** The write for this card, or a failure message. */\n const applyOnce = async (): Promise<string | undefined> => {\n const ns = namespace.ns\n let next = layout === 'pi-ai' && stringAt(draft, 'apiKeyEnv') === undefined\n && stringAt(fallback, 'apiKeyEnv') === undefined && keyValue.length > 0\n ? schema.setPath(draft, ['apiKeyEnv'], keyRef)\n : draft\n const rowFailure = validateModelRows(schema.getPath(next, ['models']))\n if (rowFailure !== undefined) {\n return `模型 ${String(rowFailure.index + 1)}:${{\n modelIdRequired: '模型 ID 不能为空。',\n modelIdDuplicate: '模型 ID 不能重复。',\n modelNameInvalid: '显示名称不能为空。',\n modelContextInvalid: '上下文窗口须为正数,如 131072、256K、1M。',\n modelMaxTokensInvalid: '最大输出 token 数须为正数,如 8192、64K、1M。',\n }[rowFailure.key]}`\n }\n if (node !== undefined && settingsPath.length === 0) {\n const sectionError = schema.validate(node, next)\n if (sectionError !== undefined) return sectionError\n }\n // Stable YAML key order: normalize every drafted row before diffing.\n if (schema.hasPath(next, ['models'])) {\n next = schema.setPath(\n next,\n ['models'],\n modelDrafts(schema.getPath(next, ['models'])).map(normalizeModelRow),\n )\n }\n // Official semantic: a pi-ai route whose only act is activating the route\n // (no fields the card can see, no key yet) still writes an empty profile\n // so the route exists in the directory at all.\n const materializesNativeProfile = layout === 'pi-ai'\n && fallback === undefined\n && committedOriginal === undefined\n && Object.keys(next).length === 0\n const ops = materializesNativeProfile\n ? [{ op: 'set', path: [...settingsPath], value: {} }]\n : pathOps(settingsPath, committedOriginal, next)\n if (ops.length > 0) {\n const written = await operations.writeSettings(ns, ops, expectedRevision)\n if (written.kind !== 'written') return written.kind === 'conflict'\n ? '这张卡片打开期间,这些设置已被其他地方改动。请关闭后重新打开,在当前值上编辑。'\n : written.message\n setCommittedOriginal(schema.getPath(written.view.user, settingsPath))\n setExpectedRevision(written.view.revision)\n setDraft(next)\n }\n if (keyValue.length > 0) {\n const stored = await operations.storeCredential(keyRef, keyValue)\n if (stored !== undefined) return stored\n }\n setKeyDraft('')\n return undefined\n }\n\n const apply = async (): Promise<void> => {\n setBusy(true)\n setFailure(undefined)\n try {\n const applyFailure = await applyOnce()\n if (applyFailure !== undefined) {\n setFailure(applyFailure)\n return\n }\n props.onClose(true)\n } finally {\n setBusy(false)\n }\n }\n\n if (node === undefined) {\n return <p className={styles['error']}>{props.provider}: 无法解析设置路径</p>\n }\n\n /**\n * The catalog beneath the user layer: the composition entry's pin, or the\n * schema default — reading the effective value would echo the stored\n * override back the moment reset drops it.\n */\n const inheritedModels = (): unknown => {\n const pinned = schema.getPath(namespace.base, [...settingsPath, 'models'])\n return pinned ?? schema.nodeAtPath(root, [...settingsPath, 'models'])?.meta.default\n }\n const customModels = schema.getPath(draft, ['models'])\n const modelsOverridden = schema.hasPath(draft, ['models'])\n const models = modelDrafts(modelsOverridden ? customModels : inheritedModels())\n const defaultContextWindow = schema.getPath(fallback, ['defaultContextWindow'])\n const defaultMaxTokens = schema.getPath(fallback, ['maxTokens'])\n\n const keyPlaceholder = keyState?.writable === false\n ? '由启动环境提供(只读)'\n : keyState?.configured === true\n ? '已配置——输入新值可替换'\n : layout === 'pi-ai' && props.declared === true\n ? '输入 API 密钥,或留空使用环境认证'\n : '输入 API 密钥'\n const keyLocked = keyState?.writable === false\n\n return (\n <div className={styles['editor']}>\n {layout === 'unknown'\n ? <p className={styles['advancedHint']}>其余字段存于 settings.yaml;请直接编辑对应段。({namespace.ns})</p>\n : (\n <>\n <div className={styles['tabs']}>\n <div className={styles['tabBar']} role=\"tablist\">\n <button type=\"button\" role=\"tab\" aria-selected={tab === 'provider'} className={tab === 'provider' ? `${styles['tabButton']} ${styles['tabButtonActive']}` : styles['tabButton']} onClick={() => { setTab('provider') }}>供应商</button>\n <button type=\"button\" role=\"tab\" aria-selected={tab === 'models'} className={tab === 'models' ? `${styles['tabButton']} ${styles['tabButtonActive']}` : styles['tabButton']} onClick={() => { setTab('models') }}>模型</button>\n </div> <div className={styles['tabPanel']} role=\"tabpanel\" hidden={tab !== 'provider'}>\n {layout === 'pi-ai' && props.declared === true\n ? (\n <div className={styles['field']}>\n <label className={styles['fieldLabel']}>显示名称</label>\n <input\n className={styles['input']}\n type=\"text\"\n value={stringAt(draft, 'displayName') ?? ''}\n placeholder={stringAt(schema.getPath(namespace.base, settingsPath), 'displayName')\n ?? props.provider}\n aria-label=\"显示名称\"\n disabled={disabled}\n onChange={(event) => { setField('displayName', event.target.value) }}\n />\n </div>\n )\n : null}\n <div className={styles['field']}>\n <label className={styles['fieldLabel']}>API 密钥</label>\n <input\n className={styles['input']}\n type=\"password\"\n autoComplete=\"off\"\n value={keyDraft}\n placeholder={keyPlaceholder}\n aria-label=\"API 密钥\"\n disabled={disabled || keyLocked}\n onChange={(event) => { setKeyDraft(event.target.value) }}\n />\n {keyFailure === undefined\n ? null\n : <p className={styles['error']}>{keyFailure === 'keyBlank' ? '请输入 API 密钥;留空则保持已存储的密钥。' : '此 API 密钥格式无效,请检查。'}</p>}\n </div>\n <div className={styles['field']}>\n <label className={styles['fieldLabel']}>API 地址</label>\n <input\n className={styles['input']}\n type=\"text\"\n value={stringAt(draft, 'baseURL') ?? ''}\n placeholder={layout === 'deepseek'\n ? DEEPSEEK_PUBLIC_BASE_URL\n : stringAt(fallback, 'baseURL') ?? '提供方默认'}\n aria-label=\"API 地址\"\n disabled={disabled}\n onChange={(event) => { setField('baseURL', event.target.value === '' ? undefined : event.target.value) }}\n />\n </div>\n {layout === 'pi-ai' && props.declared === true\n ? (\n <div className={styles['field']}>\n <label className={styles['fieldLabel']}>API 协议</label>\n <select\n className={`${styles['input']} ${styles['selectInput']}`}\n value={stringAt(draft, 'api') ?? stringAt(fallback, 'api') ?? ''}\n aria-label=\"API 协议\"\n disabled={disabled}\n onChange={(event) => { setField('api', event.target.value) }}\n >\n {(stringAt(draft, 'api') ?? stringAt(fallback, 'api')) === undefined\n ? <option value=\"\">未选择</option>\n : null}\n {protocols.map(choice => <option key={choice} value={choice}>{choice}</option>)}\n </select>\n </div>\n )\n : null}\n </div>\n <div className={styles['tabPanel']} role=\"tabpanel\" hidden={tab !== 'models'}>\n <ModelCatalog\n models={models}\n overridden={modelsOverridden}\n defaultContextWindow={typeof defaultContextWindow === 'number' ? defaultContextWindow : undefined}\n defaultMaxTokens={typeof defaultMaxTokens === 'number' ? defaultMaxTokens : undefined}\n probe={probe}\n probeBlocked={keyFailure}\n operations={operations}\n disabled={disabled}\n onChange={(rows: ModelDraft[]) => {\n setDraft(current => schema.setPath(current, ['models'], rows))\n }}\n onReset={() => { setDraft(current => schema.deletePath(current, ['models'])) }}\n />\n </div>\n </div>\n </>\n )}\n\n {failure !== undefined ? <p className={styles['error']}>{failure}</p> : null}\n {modelFailure === undefined\n ? null\n : (\n <p className={styles['advancedHint']}>\n {`模型 ${String(modelFailure.index + 1)}:${modelFailure.key}`}\n </p>\n )}\n\n <div className={styles['editorActions']}>\n <button\n type=\"button\"\n className={styles['secondaryButton']}\n disabled={busy}\n onClick={() => { props.onClose(false) }}\n >\n 取消\n </button>\n <button\n type=\"button\"\n className={styles['primaryButton']}\n disabled={disabled || layout === 'unknown' || modelFailure !== undefined\n || keyFailure !== undefined}\n onClick={() => { void apply() }}\n >\n {busy ? '保存中…' : '保存'}\n </button>\n </div>\n </div>\n )\n}\n","/**\n * The card that declares a provider pi-ai does not ship — an OpenAI-compatible\n * gateway, a self-hosted server, or a provider newer than the installed\n * catalog. One `settings.mutate` sets the whole profile at `providers.<route>`;\n * the key travels separately through `credentials/set` under the reference\n * the profile records. The three fields a hand-declared route cannot default\n * (endpoint, protocol, at least one model) are required here.\n */\n\nimport { useState } from 'react'\nimport type { ReactNode } from 'react'\nimport type { JsonValue } from '@deepseek-ai/dsh-util-values'\nimport { deriveKeyRef } from '../vendor/store.ts'\nimport type { ModelsOperations } from '../vendor/operations.ts'\nimport type { ModelDraft } from './compat.ts'\nimport { normalizeModelRow, validateModelRows } from './compat.ts'\nimport { ModelCatalog } from './ModelCatalog.tsx'\nimport styles from './models-plus.module.css'\n\n/** The settings namespace a hand-declared provider is written into. */\nconst NS = 'llm-pi-ai'\n\n/**\n * A route id usable as a settings key AND as the stem of a credential name.\n */\nconst ROUTE_PATTERN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/\n\n/** Props of {@link CreateProviderCard}. */\nexport interface CreateProviderCardProps {\n /** Route ids already declared, so the card refuses to shadow one. */\n taken: readonly string[]\n /** Wire protocols the adapter can serve, in the order it reports them. */\n protocols: readonly string[]\n /** Revision of the `llm-pi-ai` user section this card opened at. */\n revision: number\n /** The Host operations this card writes and interrogates through. */\n operations: ModelsOperations\n /** Disable writes (read-only settings provider). */\n readOnly: boolean\n /** Close the card; `changed` reports whether a provider was created. */\n onClose: (changed: boolean) => void\n}\n\n/**\n * Render the custom-provider creation card.\n * @param props - existing routes, protocol choices, wire faces.\n * @returns the creation card.\n */\nexport function CreateProviderCard(props: CreateProviderCardProps): ReactNode {\n const { taken, protocols, operations } = props\n const [openedAt] = useState(() => props.revision)\n const [route, setRoute] = useState('')\n const [displayName, setDisplayName] = useState('')\n const [baseURL, setBaseURL] = useState('')\n const [protocol, setProtocol] = useState(protocols[0] ?? '')\n const [tab, setTab] = useState<'provider' | 'models'>('provider')\n const [keyDraft, setKeyDraft] = useState('')\n const [models, setModels] = useState<readonly ModelDraft[]>([])\n const [busy, setBusy] = useState(false)\n const [failure, setFailure] = useState<string | undefined>(undefined)\n /** The profile write landed; only the key write can still be outstanding. */\n const [committed, setCommitted] = useState(false)\n const disabled = props.readOnly || busy\n const profileDisabled = disabled || committed\n\n const routeInvalid = route.length > 0 && !ROUTE_PATTERN.test(route)\n const routeTaken = taken.includes(route)\n const modelFailure = validateModelRows(models)\n const keyFailure = ((): 'keyBlank' | 'keyIllegalCharacters' | undefined => {\n if (keyDraft.length === 0) return undefined\n const value = keyDraft.trim()\n if (value.length === 0) return 'keyBlank'\n if (/^[A-Z][A-Z0-9_]*=[^=]/.test(value)) return 'keyIllegalCharacters'\n const first = value[0]\n if ((first === '\"' || first === '\\'' || first === '`') && value.length > 1 && value.endsWith(first)) {\n return 'keyIllegalCharacters'\n }\n return /^[\\x21-\\x7E]+$/.test(value) ? undefined : 'keyIllegalCharacters'\n })()\n const keyValue = keyDraft.trim()\n const ready = route.length > 0 && !routeInvalid && !routeTaken\n && baseURL.length > 0 && models.length > 0 && modelFailure === undefined\n && keyFailure === undefined\n const hint = failure !== undefined || ready || keyFailure !== undefined\n || route.length === 0 || routeInvalid || routeTaken\n ? undefined\n : baseURL.length === 0\n ? '自定义提供方需要填写 API 地址。'\n : modelFailure !== undefined\n ? `模型 ${String(modelFailure.index + 1)}:${modelFailure.key}`\n : '自定义提供方至少需要一个模型。'\n\n /** Perform the create, returning a failure message or undefined. */\n const createOnce = async (): Promise<string | undefined> => {\n const keyRef = deriveKeyRef(route)\n const storesKey = keyValue.length > 0\n if (!committed) {\n const profile = {\n ...displayName.length === 0 ? {} : { displayName },\n ...storesKey ? { apiKeyEnv: keyRef } : {},\n api: protocol,\n baseURL,\n models: models.map(normalizeModelRow),\n }\n const written = await operations.writeSettings(\n NS,\n [{ op: 'set', path: ['providers', route], value: profile as JsonValue }],\n openedAt,\n )\n if (written.kind !== 'written') {\n return written.kind === 'conflict'\n ? '这张卡片打开期间,这些设置已被其他地方改动。请关闭后重新打开,在当前值上编辑。'\n : written.message\n }\n // A retry after a failed key write must not re-run this mutate.\n setCommitted(true)\n }\n if (storesKey) {\n const stored = await operations.storeCredential(keyRef, keyValue)\n if (stored !== undefined) return stored\n }\n return undefined\n }\n\n const create = async (): Promise<void> => {\n setBusy(true)\n setFailure(undefined)\n try {\n const outcome = await createOnce()\n if (outcome !== undefined) {\n setFailure(outcome)\n return\n }\n props.onClose(true)\n } finally {\n setBusy(false)\n }\n }\n\n return (\n <div className={styles['editor']}>\n <div className={styles['field']} style={{ paddingTop: 12, borderTop: '0.5px solid var(--dsw-alias-border-l2)' }}>\n <label className={styles['fieldLabel']}>Provider ID</label>\n <input\n className={styles['input']}\n type=\"text\"\n value={route}\n placeholder=\"acme-gateway\"\n aria-label=\"Provider ID\"\n disabled={profileDisabled}\n onChange={(event) => { setRoute(event.target.value) }}\n />\n {routeInvalid || routeTaken\n ? <p className={styles['error']}>{routeInvalid ? '需以小写字母开头,之后可用小写字母、数字和短横线。' : '已有提供方使用了这个 ID。'}</p>\n : <p className={styles['advancedHint']}>以小写字母开头的标识,在请求中唯一标识该提供方,并用于派生凭据名。</p>}\n </div>\n\n <div className={styles['tabs']}>\n <div className={styles['tabBar']} role=\"tablist\">\n <button type=\"button\" role=\"tab\" aria-selected={tab === 'provider'} className={tab === 'provider' ? `${styles['tabButton']} ${styles['tabButtonActive']}` : styles['tabButton']} onClick={() => { setTab('provider') }}>供应商</button>\n <button type=\"button\" role=\"tab\" aria-selected={tab === 'models'} className={tab === 'models' ? `${styles['tabButton']} ${styles['tabButtonActive']}` : styles['tabButton']} onClick={() => { setTab('models') }}>模型</button>\n </div>\n <div className={styles['tabPanel']} role=\"tabpanel\" hidden={tab !== 'provider'}>\n <div className={styles['field']}>\n <label className={styles['fieldLabel']}>显示名称</label>\n <input\n className={styles['input']}\n type=\"text\"\n value={displayName}\n placeholder={route.length === 0 ? '显示名称' : route}\n aria-label=\"显示名称\"\n disabled={profileDisabled}\n onChange={(event) => { setDisplayName(event.target.value) }}\n />\n </div>\n <div className={styles['field']}>\n <label className={styles['fieldLabel']}>API 地址</label>\n <input\n className={styles['input']}\n type=\"text\"\n value={baseURL}\n placeholder=\"https://gateway.example/v1\"\n aria-label=\"API 地址\"\n disabled={profileDisabled}\n onChange={(event) => { setBaseURL(event.target.value) }}\n />\n </div>\n <div className={styles['field']}>\n <label className={styles['fieldLabel']}>API 协议</label>\n <select\n className={`${styles['input']} ${styles['selectInput']}`}\n value={protocol}\n aria-label=\"API 协议\"\n disabled={profileDisabled}\n onChange={(event) => { setProtocol(event.target.value) }}\n >\n {protocols.map(choice => <option key={choice} value={choice}>{choice}</option>)}\n </select>\n </div>\n <div className={styles['field']}>\n <label className={styles['fieldLabel']}>API 密钥</label>\n <input\n className={styles['input']}\n type=\"password\"\n autoComplete=\"off\"\n value={keyDraft}\n placeholder=\"输入 API 密钥,或留空使用环境认证\"\n aria-label=\"API 密钥\"\n disabled={disabled}\n onChange={(event) => { setKeyDraft(event.target.value) }}\n />\n {keyFailure === undefined\n ? null\n : <p className={styles['error']}>{keyFailure === 'keyBlank' ? '请输入 API 密钥;若该提供方以其他方式鉴权,可以留空。' : '此 API 密钥格式无效,请检查。'}</p>}\n </div>\n </div>\n <div className={styles['tabPanel']} role=\"tabpanel\" hidden={tab !== 'models'}>\n <ModelCatalog\n models={models}\n overridden={true}\n defaultContextWindow={undefined}\n defaultMaxTokens={undefined}\n probe={{\n settingsNs: NS,\n baseURL,\n api: protocol,\n ...keyValue.length === 0 ? {} : { apiKey: keyValue },\n }}\n probeBlocked={keyFailure === 'keyBlank' ? '请输入 API 密钥;若该提供方以其他方式鉴权,可以留空。' : keyFailure}\n operations={operations}\n disabled={profileDisabled}\n onChange={setModels}\n />\n </div>\n </div>\n\n {failure !== undefined ? <p className={styles['error']}>{failure}</p> : null}\n {hint === undefined ? null : <p className={styles['advancedHint']}>{hint}</p>}\n\n <div className={styles['editorActions']}>\n <button\n type=\"button\"\n className={styles['secondaryButton']}\n disabled={busy}\n onClick={() => { props.onClose(committed) }}\n >\n 取消\n </button>\n <button\n type=\"button\"\n className={styles['primaryButton']}\n disabled={disabled || !ready}\n onClick={() => { void create() }}\n >\n {busy ? '创建中…' : '创建提供方'}\n </button>\n </div>\n </div>\n )\n}\n\n","/**\n * The Models+ settings section (v1.0.0, fully plugin-owned UI): provider rows\n * joined from the configurable directory, settings namespaces, and credential\n * states, one editor card at a time. The title row carries the adapter badge\n * and the metadata download button — the only place models.dev data is ever\n * fetched, on an explicit user click.\n */\n\nimport { useState } from 'react'\nimport type { ReactNode } from 'react'\nimport { Modal } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { ModelsSettingsStore, ProviderRow } from '../vendor/store.ts'\nimport { deriveKeyRef, protocolChoices, providerUsable } from '../vendor/store.ts'\nimport type { ModelsOperations } from './operations.ts'\nimport type { SettingsSchemaOperations } from './schema-operations.ts'\nimport { downloadMetadata } from './models-index.ts'\nimport { ProviderEditor } from './ProviderEditor.tsx'\nimport { CreateProviderCard } from './CreateProviderCard.tsx'\nimport styles from './models-plus.module.css'\n\n/** One existing row or dormant directory entry addressed by an editor action. */\nexport interface EditorTarget {\n readonly provider: string\n readonly displayName: string\n readonly settingsNs: string\n readonly settingsPath: readonly string[]\n /** Writable credential identified under this page's conventional reference. */\n credentialRef?: string\n readonly declared?: boolean\n}\n\n/** Injected dependencies of {@link ModelsPlusSection} (slot `inject`). */\nexport interface ModelsPlusInjected {\n controller: ModelsSettingsStore\n hooks: {\n snapshot: ModelsSettingsStore['store']\n }\n operations: ModelsOperations\n schema: SettingsSchemaOperations\n t: (key: string) => string\n}\n\n/** One fact decides the first-run posture: whether any provider is usable. */\nfunction needsSetup(row: ProviderRow, anyUsable: boolean): boolean {\n if (anyUsable) return false\n if (row.entry.settingsPath.length > 0) return false\n return row.credential?.configured !== true\n}\n\n/** The credential reference a row resolves keys through, confirmed configured. */\nfunction keyConfiguredOf(row: ProviderRow): boolean {\n return row.apiKeyEnv !== undefined\n ? row.credential?.configured === true\n : row.derivedCredential?.configured === true\n}\n\nfunction targetOf(row: ProviderRow): EditorTarget {\n const managedRef = deriveKeyRef(row.entry.provider)\n const credentialRef = row.apiKeyEnv === managedRef\n && row.credential?.configured === true\n && row.credential.writable\n ? managedRef\n : undefined\n return {\n provider: row.entry.provider,\n displayName: row.entry.displayName,\n settingsNs: row.entry.settingsNs,\n settingsPath: row.entry.settingsPath,\n ...credentialRef === undefined ? {} : { credentialRef },\n ...row.entry.declared === true ? { declared: true } : {},\n }\n}\n\n/**\n * Remove one user-added provider and its page-managed credential. Credential\n * removal comes first so a second-step failure leaves the row retryable.\n */\nasync function removeProviderProfile(\n operations: ModelsOperations,\n controller: ModelsSettingsStore,\n target: { settingsNs: string; settingsPath: readonly string[]; credentialRef?: string },\n): Promise<string | undefined> {\n if (target.credentialRef !== undefined) {\n const credential = await operations.removeCredential(target.credentialRef)\n if (credential !== undefined) return credential\n }\n const written = await operations.writeSettings(\n target.settingsNs,\n [{ op: 'unset', path: [...target.settingsPath] }],\n undefined,\n )\n if (written.kind !== 'written') return written.message\n await controller.load()\n return undefined\n}\n\n/** Replace the one provider placeholder in localized destructive copy. */\nfunction providerCopy(template: string, target: { displayName: string; provider: string }): string {\n const label = target.provider === target.displayName\n ? target.provider\n : `${target.displayName} (${target.provider})`\n return template.replace('{provider}', () => label)\n}\n\n/**\n * Render the Models+ section content column.\n * @param props - slot-delivered injected dependencies.\n * @returns the section, or null while the shell has not injected yet.\n */\nexport function ModelsPlusSection(props: {\n controller?: ModelsPlusInjected['controller']\n useSnapshot?: ModelsPlusInjected['hooks']['snapshot']\n operations?: ModelsPlusInjected['operations']\n schema?: ModelsPlusInjected['schema']\n t?: ModelsPlusInjected['t']\n}): ReactNode {\n const { controller, useSnapshot, operations, schema, t } = props\n if (\n controller === undefined || useSnapshot === undefined || operations === undefined\n || schema === undefined || t === undefined\n ) return null\n // Hooks live in the Loaded child (mirrors the host section): the null check\n // above must not change this component's hook count between renders.\n return <Loaded injected={{ controller, useSnapshot, operations, schema, t }} />\n}\n\nfunction Loaded({ injected }: { injected: ModelsPlusInjected }): ReactNode {\n const { controller, operations, schema, t } = injected\n const useSnapshot = injected.useSnapshot\n\n const state = useSnapshot(snapshot => snapshot)\n const [editing, setEditing] = useState<EditorTarget | undefined>(undefined)\n const [adding, setAdding] = useState(false)\n const [declaring, setDeclaring] = useState(false)\n const [deleteTarget, setDeleteTarget] = useState<EditorTarget | undefined>(undefined)\n const [deleting, setDeleting] = useState(false)\n const [deleteFailure, setDeleteFailure] = useState<string | undefined>(undefined)\n const [savedTarget, setSavedTarget] = useState<{ displayName: string; provider: string } | undefined>(undefined)\n const [dismissedSetup, setDismissedSetup] = useState<ReadonlySet<string>>(() => new Set())\n const [metaBusy, setMetaBusy] = useState(false)\n const [metaMessage, setMetaMessage] = useState<{ ok: boolean; text: string } | undefined>(undefined)\n\n const announceSaved = (target: { displayName: string; provider: string }): void => {\n void controller.load().then(() => { setSavedTarget(target) })\n }\n\n const closeEditor = (changed: boolean, target: { displayName: string; provider: string }): void => {\n setEditing(undefined)\n setAdding(false)\n setDeclaring(false)\n if (changed) announceSaved(target)\n }\n\n const closeSetup = (changed: boolean, target: { displayName: string; provider: string }): void => {\n setDismissedSetup(previous => new Set([...previous, target.provider]))\n if (changed) announceSaved(target)\n }\n\n const downloadMeta = async (): Promise<void> => {\n setMetaBusy(true)\n setMetaMessage(undefined)\n try {\n const outcome = await downloadMetadata()\n setMetaMessage(outcome.ok\n ? { ok: true, text: 'models.dev 元数据已下载并就绪。' }\n : { ok: false, text: `元数据下载失败:${outcome.message}` })\n } finally {\n setMetaBusy(false)\n }\n }\n\n if (state.status === 'idle') void controller.load()\n if (state.status === 'error') {\n const errorText = state.error ?? ''\n return (\n <div className={styles['section']}>\n <p className={styles['error']}>{`加载提供方目录失败: ${errorText}`}</p>\n <button type=\"button\" className={styles['secondaryButton']} onClick={() => { void controller.load() }}>\n 重试\n </button>\n </div>\n )\n }\n\n const savedRow = savedTarget === undefined\n ? undefined\n : state.rows.find(row => row.entry.provider === savedTarget.provider)\n const savedIdentity = savedRow === undefined\n ? savedTarget\n : { displayName: savedRow.entry.displayName, provider: savedRow.entry.provider }\n\n const anyUsable = state.rows.some(providerUsable)\n const configured = state.rows.filter(row => row.configured)\n const addable = state.rows.filter(row => !row.configured && row.entry.settingsNs !== '')\n const addTarget = adding ? editing : undefined\n const addNamespace = addTarget === undefined ? undefined : state.namespaces.get(addTarget.settingsNs)\n const protocols = (() => {\n // The protocol choices a hand-declared route may name (schema read).\n return protocolChoices(state.namespaces.get('llm-pi-ai'), schema)\n })()\n\n const renderEditor = (\n target: EditorTarget,\n namespace: Parameters<typeof ProviderEditor>[0]['namespace'] | undefined,\n onClose: (changed: boolean) => void,\n ): ReactNode => {\n if (namespace === undefined) return null\n return (\n <ProviderEditor\n provider={target.provider}\n displayName={target.displayName}\n settingsPath={target.settingsPath}\n {...target.declared === true ? { declared: true } : {}}\n namespace={namespace}\n schema={schema}\n operations={operations}\n readOnly={!state.writable}\n onClose={onClose}\n />\n )\n }\n\n return (\n <div className={styles['section']}>\n {/* Title row: heading + metadata download button */}\n <div className={styles['titleRow']}>\n <h2 className={styles['title']}>{t('nav')}</h2>\n <span className={styles['rowActions']}>\n <button\n type=\"button\"\n className={styles['linkButton']}\n disabled={metaBusy}\n title=\"下载/更新 models.dev 元数据(供快速装入预填)\"\n onClick={() => { void downloadMeta() }}\n >\n {metaBusy ? '正在下载元数据…' : '下载/更新元数据'}\n </button>\n </span>\n </div>\n {metaMessage === undefined\n ? null\n : <p className={metaMessage.ok ? styles['savedNotice'] : styles['error']}>{metaMessage.text}</p>}\n\n <p className={styles['intro']}>{t('intro')}</p>\n\n {savedIdentity === undefined\n ? null\n : (\n <p className={styles['savedNotice']} role=\"status\" aria-live=\"polite\">\n {providerCopy('已保存 {provider}。', savedIdentity)}\n </p>\n )}\n\n <ul className={styles['rows']}>\n {configured.map((row) => {\n const target = targetOf(row)\n const namespace = state.namespaces.get(target.settingsNs)\n if (namespace === undefined) return null\n if (needsSetup(row, anyUsable) && !dismissedSetup.has(row.entry.provider)) {\n return (\n <li key={row.entry.provider} className={styles['rowCard']}>\n {renderEditor(target, namespace, (changed) => { closeSetup(changed, target) })}\n </li>\n )\n }\n const open = !adding && !declaring && editing?.provider === row.entry.provider\n const credentialConfigured = row.credential?.configured === true\n const credentialMissing = !credentialConfigured\n && row.apiKeyEnv !== undefined\n && row.credential?.configured === false\n return (\n <li key={row.entry.provider} className={styles['rowCard']}>\n <div className={styles['rowHead']}>\n <span className={styles['rowIdentity']}>\n <span className={styles['rowName']}>{row.entry.displayName}</span>\n {row.entry.declared === true\n ? <span className={styles['rowTag']}>自定义</span>\n : null}\n {credentialConfigured\n ? (\n <span\n className={`${styles['credentialDot']} ${styles['credentialDotConfigured']}`}\n role=\"img\"\n aria-label=\"API 密钥已配置\"\n title=\"API 密钥已配置\"\n />\n )\n : credentialMissing\n ? (\n <span\n className={`${styles['credentialDot']} ${styles['credentialDotMissing']}`}\n role=\"img\"\n aria-label=\"API 密钥缺失\"\n title=\"API 密钥缺失\"\n />\n )\n : null}\n </span>\n <span className={styles['rowActions']}>\n <button\n type=\"button\"\n className={styles['secondaryButton']}\n aria-label={providerCopy('编辑 {provider}', target)}\n onClick={() => {\n setSavedTarget(undefined)\n setDeclaring(false)\n setAdding(false)\n setEditing(open ? undefined : target)\n }}\n >\n 编辑\n </button>\n {row.removable\n ? (\n <button\n type=\"button\"\n className={styles['dangerButton']}\n aria-label={providerCopy('删除 {provider}', target)}\n disabled={!state.writable}\n onClick={() => {\n setSavedTarget(undefined)\n setDeleteFailure(undefined)\n setDeleteTarget(target)\n }}\n >\n 删除\n </button>\n )\n : null}\n </span>\n </div>\n {open\n ? renderEditor(target, namespace, (changed) => { closeEditor(changed, target) })\n : null}\n </li>\n )\n })}\n </ul>\n\n <div className={styles['addBlock']}>\n {addTarget !== undefined && addNamespace !== undefined\n ? (\n <div className={styles['addCard']}>\n <div className={styles['field']}>\n <label className={styles['fieldLabel']}>提供方</label>\n <select\n className={`${styles['input']} ${styles['selectInput']}`}\n value={addTarget.provider}\n aria-label=\"提供方\"\n onChange={(event) => {\n const row = addable.find(candidate => candidate.entry.provider === event.target.value)\n if (row === undefined) return\n setEditing(targetOf(row))\n }}\n >\n {addable.map(row => (\n <option key={row.entry.provider} value={row.entry.provider}>\n {row.entry.displayName}\n </option>\n ))}\n </select>\n </div>\n <ProviderEditor\n key={addTarget.provider}\n provider={addTarget.provider}\n displayName={addTarget.displayName}\n namespace={addNamespace}\n schema={schema}\n settingsPath={addTarget.settingsPath}\n operations={operations}\n readOnly={!state.writable}\n onClose={(changed) => { closeEditor(changed, addTarget) }}\n />\n </div>\n )\n : declaring\n ? (\n <div className={styles['addCard']}>\n <CreateProviderCard\n taken={state.rows.map(row => row.entry.provider)}\n protocols={protocols}\n revision={state.namespaces.get('llm-pi-ai')?.revision ?? 0}\n operations={operations}\n readOnly={!state.writable}\n onClose={(changed) => {\n setDeclaring(false)\n if (changed) void controller.load()\n }}\n />\n </div>\n )\n : (\n <div className={styles['addActions']}>\n <button\n type=\"button\"\n className={styles['addButton']}\n disabled={addable.length === 0 || !state.writable}\n onClick={() => {\n const first = addable[0]\n if (first === undefined) return\n setSavedTarget(undefined)\n setDeclaring(false)\n setAdding(true)\n setEditing(targetOf(first))\n }}\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M8 3.5v9M3.5 8h9\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n 添加提供方\n </button>\n <button\n type=\"button\"\n className={styles['addButton']}\n disabled={protocols.length === 0 || !state.writable}\n onClick={() => {\n setSavedTarget(undefined)\n setAdding(false)\n setEditing(undefined)\n setDeclaring(true)\n }}\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M8 3.5v9M3.5 8h9\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n 添加自定义提供方\n </button>\n </div>\n )}\n </div>\n\n <Modal\n open={deleteTarget !== undefined}\n onClose={() => {\n if (deleting) return\n setDeleteTarget(undefined)\n setDeleteFailure(undefined)\n }}\n title={deleteTarget === undefined ? '' : providerCopy('删除 {provider}?', deleteTarget)}\n closeLabel=\"关闭\"\n description={deleteTarget === undefined\n ? ''\n : providerCopy(\n deleteTarget.credentialRef === undefined\n ? '删除 {provider} 会移除其配置;其使用的凭证(如有)由其他位置管理,将会保留。'\n : '删除 {provider} 会移除其配置和存储的 API 密钥。',\n deleteTarget,\n )}\n className={styles['deleteDialog'] as string}\n footer={(\n <>\n <button\n type=\"button\"\n className={styles['secondaryButton']}\n disabled={deleting}\n onClick={() => {\n setDeleteTarget(undefined)\n setDeleteFailure(undefined)\n }}\n >\n 取消\n </button>\n <button\n type=\"button\"\n className={`${styles['secondaryButton']} ${styles['deleteConfirm']}`}\n disabled={deleting}\n onClick={() => {\n if (deleteTarget === undefined || deleting) return\n setDeleting(true)\n setDeleteFailure(undefined)\n void removeProviderProfile(operations, controller, deleteTarget)\n .then((removeFailure) => {\n if (removeFailure !== undefined) {\n setDeleteFailure(removeFailure)\n return\n }\n setDeleteTarget(undefined)\n })\n .finally(() => { setDeleting(false) })\n }}\n >\n {deleteTarget === undefined ? '' : providerCopy(deleting ? '正在删除 {provider}…' : '删除 {provider}', deleteTarget)}\n </button>\n </>\n )}\n >\n {deleteFailure === undefined ? null : <p className={styles['error']}>{deleteFailure}</p>}\n </Modal>\n </div>\n )\n}\n\n","/**\n * VENDORED from @deepseek-ai/dsh-client-ui-settings-models @ 0.1.2-rc.1\n * (host tree packages/client/ui-settings-models/src/client/operations.ts) — copied\n * VERBATIM so the build is self-contained (no host checkout required).\n * Re-diff against the host source on every adapter-anchor bump.\n */\n/**\n * The Host reads and writes the Models cards perform, as callbacks built in the\n * plugin body. Cards receive these instead of a context: the outcomes name what\n * a card renders — a stored view, a stale revision, a refusal message — so the\n * failure codes and Remote namespaces stay in the apply world.\n */\n\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type {\n CredentialInfo, LlmDiscoveredModel, LlmModelDiscoveryRequest,\n SettingsNamespaceView, SettingsPathOpView,\n} from '@deepseek-ai/dsh-api-remotes/client'\n\n/** What one namespace write answered. */\nexport type SettingsWriteOutcome =\n /** Committed; the view carries the stored user subtree and the new revision. */\n | { readonly kind: 'written'; readonly view: SettingsNamespaceView }\n /**\n * The stored revision moved after the card read it, so the draft is stale.\n * The message stays for callers that report the Host diagnostic as it is.\n */\n | { readonly kind: 'conflict'; readonly message: string }\n /** Any other refusal, with the Host's own diagnostic. */\n | { readonly kind: 'refused'; readonly message: string }\n\n/** What one endpoint interrogation answered. */\nexport type ModelDiscoveryOutcome =\n /** The candidates the provider disclosed, in its own order. */\n | { readonly kind: 'found'; readonly models: readonly LlmDiscoveredModel[] }\n /** The interrogation was refused, with the Host's own diagnostic. */\n | { readonly kind: 'refused'; readonly message: string }\n\n/** The Host operations the Models page and its cards invoke. */\nexport interface ModelsOperations {\n /**\n * Read one credential reference's state.\n * @param ref - credential reference name.\n * @returns the state, or undefined when the reference is unknown or the read was refused.\n */\n describeCredential(ref: string): Promise<CredentialInfo | undefined>\n /**\n * Store one credential literal under its reference.\n * @param ref - credential reference name.\n * @param value - the literal to store.\n * @returns the refusal message, or undefined once stored.\n */\n storeCredential(ref: string, value: string): Promise<string | undefined>\n /**\n * Remove one credential reference (idempotent).\n * @param ref - credential reference name.\n * @returns the refusal message, or undefined once removed.\n */\n removeCredential(ref: string): Promise<string | undefined>\n /**\n * Apply path operations to one settings namespace.\n * @param ns - settings namespace identity.\n * @param ops - ordered path operations against the stored section, as the\n * wire takes them (the Remote signature owns the array).\n * @param expectedRevision - revision the draft was opened at, or undefined to write unfenced.\n * @returns the write outcome the card renders from.\n */\n writeSettings(\n ns: string,\n ops: SettingsPathOpView[],\n expectedRevision: number | undefined,\n ): Promise<SettingsWriteOutcome>\n /**\n * Ask a provider endpoint what models it serves.\n * @param settingsNs - namespace whose adapter family answers.\n * @param request - endpoint facts as the form currently shows them.\n * @returns the candidates, or the refusal.\n */\n discoverModels(settingsNs: string, request: LlmModelDiscoveryRequest): Promise<ModelDiscoveryOutcome>\n}\n\n/**\n * Bind the page's Host operations to the plugin's own Remote namespaces.\n * @param ctx - the page plugin's context, which declares `remote.credentials`,\n * `remote.llm`, and `remote.settings` in its own `inject`.\n * @returns the callbacks the section and its cards are injected with.\n */\nexport function createModelsOperations(ctx: ClientContext): ModelsOperations {\n return {\n describeCredential: async (ref) => {\n const response = await ctx.remote.credentials.describe([ref])\n return response.ok ? response.value[ref] : undefined\n },\n storeCredential: async (ref, value) => {\n const response = await ctx.remote.credentials.set(ref, value)\n return response.ok ? undefined : response.error.message\n },\n removeCredential: async (ref) => {\n const response = await ctx.remote.credentials.unset(ref)\n return response.ok ? undefined : response.error.message\n },\n writeSettings: async (ns, ops, expectedRevision) => {\n const response = await ctx.remote.settings.mutate(ns, ops, expectedRevision)\n if (response.ok) return { kind: 'written', view: response.value }\n const { code, message } = response.error\n return code === 'settings/conflict' ? { kind: 'conflict', message } : { kind: 'refused', message }\n },\n discoverModels: async (settingsNs, request) => {\n const response = await ctx.remote.llm.discoverModels(settingsNs, request)\n return response.ok\n ? { kind: 'found', models: response.value }\n : { kind: 'refused', message: response.error.message }\n },\n }\n}\n","/**\n * VENDORED from @deepseek-ai/dsh-client-ui-settings-models @ 0.1.2-rc.1\n * (host tree packages/client/ui-settings-models/src/client/schema-operations.ts) — copied\n * VERBATIM so the build is self-contained (no host checkout required).\n * Re-diff against the host source on every adapter-anchor bump.\n */\nimport type {\n SettingsSchemaService,\n} from '@deepseek-ai/dsh-client-ui-settings/client'\n\n/** Plain schema callbacks exposed to Models stores and presentation components. */\nexport type SettingsSchemaOperations = Pick<\n SettingsSchemaService,\n 'rehydrate' | 'validate' | 'nodeAtPath' | 'getPath' | 'hasPath' | 'setPath' | 'deletePath'\n>\n\n/**\n * Hide the Cordis service identity behind bound schema callbacks.\n * @param service - settings-owned schema service available in the apply context.\n * @returns callbacks that cannot expose the service context to React components.\n */\nexport function createSettingsSchemaOperations(service: SettingsSchemaService): SettingsSchemaOperations {\n return {\n rehydrate: serialized => service.rehydrate(serialized),\n validate: (schema, draft) => service.validate(schema, draft),\n nodeAtPath: (root, path) => service.nodeAtPath(root, path),\n getPath: (value, path) => service.getPath(value, path),\n hasPath: (value, path) => service.hasPath(value, path),\n setPath: (root, path, value) => service.setPath(root, path, value),\n deletePath: (root, path) => service.deletePath(root, path),\n }\n}\n","/**\n * dsh-model-extension — client entry (v1.0.0).\n *\n * Registers the Models+ settings section rendering the fully plugin-owned\n * models-plus component tree (no host component code is bundled). The store,\n * schema operations, Host operations, dictionaries, and invalidation wiring\n * keep the upstream ui-settings-models contracts @ 0.1.2-rc.1 — the logic\n * modules (store/operations/schema-operations) are still inlined from the\n * host tree at build time, only the presentation is ours.\n */\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\n// Type-only: pulls the shell's SlotMap merge ('settings.section') into this program.\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\n// Type-only: pulls the locale plugin's Context merge (ctx.locale).\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\n// Type-only: pulls the ui renderer's Context merge (useSnapshot and friends on inject faces).\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\n// Type-only: pulls the ctx.remote merge and forwarded-event key face.\nimport type {} from '@deepseek-ai/dsh-api-remotes/client'\nimport { ModelsPlusSection } from './models-plus/ModelsPlusSection.tsx'\nimport type { ModelsPlusInjected } from './models-plus/ModelsPlusSection.tsx'\nimport { ModelsSettingsStore } from './vendor/store.ts'\nimport { createModelsOperations } from './vendor/operations.ts'\nimport { createSettingsSchemaOperations } from './vendor/schema-operations.ts'\nimport { en as extensionEn, zh as extensionZh } from './extension-meta.ts'\n\n/** Cordis service name (distinct from the npm package name). */\nexport const name = 'model-extension-client'\n\n/** Required services — mirrors the upstream Models section registration @ 0.1.2-rc.1. */\nexport const inject = [\n 'slots', 'locale', 'remote', 'remote.credentials', 'remote.llm', 'remote.settings',\n 'settingsScope', 'settingsSchema',\n]\n\n/** Refetch the page snapshot only after its first load (upstream helper, inlined). */\nfunction refreshIfLoaded(controller: ModelsSettingsStore): void {\n if (controller.store.getSnapshot().status === 'idle') return\n void controller.load()\n}\n\n/**\n * Apply: register the Models+ section once slot/locale services are up.\n * @param ctx - client root context.\n */\nexport function apply(ctx: ClientContext): void {\n const NS = 'settings.models-extension'\n ctx.effect(() => ctx.locale.register(NS, {\n zh: { ...extensionZh },\n en: { ...extensionEn },\n }), 'dsh-model-extension: copy dictionaries')\n\n const schema = createSettingsSchemaOperations(ctx.settingsSchema)\n const operations = createModelsOperations(ctx)\n const controller = new ModelsSettingsStore(ctx, schema, ctx.settingsScope.describe())\n const t = ctx.locale.bind(NS) as ModelsPlusInjected['t']\n const injected = (): ModelsPlusInjected => ({\n controller,\n hooks: { snapshot: controller.store },\n operations,\n schema,\n t,\n })\n\n // Pushed invalidations converge every open surface without polling.\n ctx.effect(() => {\n const refreshModels = (): void => { refreshIfLoaded(controller) }\n return () => [\n ctx.remote.$on('settings/document-updated', () => { refreshModels() }),\n ctx.remote.$on('credentials/reference-updated', refreshModels),\n ctx.remote.$on('llm/adapters-updated', refreshModels),\n ctx.on('connection/reset', refreshModels),\n ]\n }, 'dsh-model-extension: pushed invalidations')\n\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'models-extension',\n order: 11,\n label: () => t('nav'),\n inject: injected,\n }, ModelsPlusSection))\n}\n"],"mappings":"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"}
|