agent-relay-server 0.127.3 → 0.127.4
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/docs/openapi.json +1 -1
- package/package.json +3 -3
- package/public/assets/{MessageBubble-DnXnkt4a.js → MessageBubble-D2Wzxied.js} +2 -2
- package/public/assets/{MessageBubble-DnXnkt4a.js.map → MessageBubble-D2Wzxied.js.map} +1 -1
- package/public/assets/{PlanGraphPanel-D6CPEpQD.js → PlanGraphPanel-DH_xoWZi.js} +2 -2
- package/public/assets/{PlanGraphPanel-D6CPEpQD.js.map → PlanGraphPanel-DH_xoWZi.js.map} +1 -1
- package/public/assets/{activity-ZPwHcPLK.js → activity-B-ozOwNq.js} +2 -2
- package/public/assets/{activity-ZPwHcPLK.js.map → activity-B-ozOwNq.js.map} +1 -1
- package/public/assets/{agent-profiles-CT0E9LV1.js → agent-profiles-DZgjO25A.js} +2 -2
- package/public/assets/{agent-profiles-CT0E9LV1.js.map → agent-profiles-DZgjO25A.js.map} +1 -1
- package/public/assets/{agent-type-icon-BmBR-9CH.js → agent-type-icon-B9cLaOoz.js} +2 -2
- package/public/assets/{agent-type-icon-BmBR-9CH.js.map → agent-type-icon-B9cLaOoz.js.map} +1 -1
- package/public/assets/agents-mXBLSY6O.js +2 -0
- package/public/assets/{agents-Dt5TncjC.js.map → agents-mXBLSY6O.js.map} +1 -1
- package/public/assets/{analytics-BZtRycyL.js → analytics-5Ize_UL5.js} +3 -3
- package/public/assets/{analytics-BZtRycyL.js.map → analytics-5Ize_UL5.js.map} +1 -1
- package/public/assets/{automation-yzUJbvT2.js → automation-CidMvW2e.js} +2 -2
- package/public/assets/{automation-yzUJbvT2.js.map → automation-CidMvW2e.js.map} +1 -1
- package/public/assets/{badge-BCvp7LK3.js → badge-BkNNvFNa.js} +2 -2
- package/public/assets/{badge-BCvp7LK3.js.map → badge-BkNNvFNa.js.map} +1 -1
- package/public/assets/{branch-state-badge-Cscjqf-E.js → branch-state-badge-DnS40KCb.js} +2 -2
- package/public/assets/{branch-state-badge-Cscjqf-E.js.map → branch-state-badge-DnS40KCb.js.map} +1 -1
- package/public/assets/{button-DyHjsHY3.js → button-DUaC2wSQ.js} +2 -2
- package/public/assets/{button-DyHjsHY3.js.map → button-DUaC2wSQ.js.map} +1 -1
- package/public/assets/{card-BoqYxpVW.js → card-r-yAV4cH.js} +2 -2
- package/public/assets/{card-BoqYxpVW.js.map → card-r-yAV4cH.js.map} +1 -1
- package/public/assets/{channels-DAtOnA6o.js → channels-MPO2FOBv.js} +2 -2
- package/public/assets/{channels-DAtOnA6o.js.map → channels-MPO2FOBv.js.map} +1 -1
- package/public/assets/chat-Ca4ERso5.js +2 -0
- package/public/assets/chat-Ca4ERso5.js.map +1 -0
- package/public/assets/{connectors-B2grC-hl.js → connectors-BbYdtRkW.js} +2 -2
- package/public/assets/{connectors-B2grC-hl.js.map → connectors-BbYdtRkW.js.map} +1 -1
- package/public/assets/copy-button-u463GPZR.js +2 -0
- package/public/assets/{copy-button-C67FUG3E.js.map → copy-button-u463GPZR.js.map} +1 -1
- package/public/assets/{display-aTnwsqQh.js → display-BNI-7rdq.js} +2 -2
- package/public/assets/{display-aTnwsqQh.js.map → display-BNI-7rdq.js.map} +1 -1
- package/public/assets/{dist-D5w04z0l.js → dist-5e_is3Xr.js} +2 -2
- package/public/assets/{dist-D5w04z0l.js.map → dist-5e_is3Xr.js.map} +1 -1
- package/public/assets/{dist-BD4Xc13v.js → dist-ActI2qb5.js} +2 -2
- package/public/assets/{dist-BD4Xc13v.js.map → dist-ActI2qb5.js.map} +1 -1
- package/public/assets/dist-B-FQ0-X3.js +2 -0
- package/public/assets/{dist-G8YBD-wp.js.map → dist-B-FQ0-X3.js.map} +1 -1
- package/public/assets/{dist-f6MW74eX.js → dist-BduURKro.js} +2 -2
- package/public/assets/{dist-f6MW74eX.js.map → dist-BduURKro.js.map} +1 -1
- package/public/assets/{dist-BFDfbfNC.js → dist-Bp0-OBcd.js} +2 -2
- package/public/assets/{dist-BFDfbfNC.js.map → dist-Bp0-OBcd.js.map} +1 -1
- package/public/assets/{dist-C_VOBSaK.js → dist-CJ7e7uqU.js} +2 -2
- package/public/assets/{dist-C_VOBSaK.js.map → dist-CJ7e7uqU.js.map} +1 -1
- package/public/assets/{dist-BNB3fTO-.js → dist-CYzOsD_n.js} +2 -2
- package/public/assets/{dist-BNB3fTO-.js.map → dist-CYzOsD_n.js.map} +1 -1
- package/public/assets/{dist-CQMQ5iku.js → dist-CpcQJrKV.js} +2 -2
- package/public/assets/{dist-CQMQ5iku.js.map → dist-CpcQJrKV.js.map} +1 -1
- package/public/assets/dist-DFgmDjLv.js +2 -0
- package/public/assets/{dist-CHKra2JV.js.map → dist-DFgmDjLv.js.map} +1 -1
- package/public/assets/{dist-DG75bvPp.js → dist-DrpSpMKL.js} +2 -2
- package/public/assets/{dist-DG75bvPp.js.map → dist-DrpSpMKL.js.map} +1 -1
- package/public/assets/dist-DzWoiN2z.js +2 -0
- package/public/assets/{dist-BJKxqIQd.js.map → dist-DzWoiN2z.js.map} +1 -1
- package/public/assets/{es2015-a6fysEVz.js → es2015-DNuudVtQ.js} +2 -2
- package/public/assets/{es2015-a6fysEVz.js.map → es2015-DNuudVtQ.js.map} +1 -1
- package/public/assets/formatted-body-BEI1zP7i.js +3 -0
- package/public/assets/{formatted-body-D5-1aiyB.js.map → formatted-body-BEI1zP7i.js.map} +1 -1
- package/public/assets/{formatted-body-impl-Do5NbJUA.js → formatted-body-impl-CNQ5sqwK.js} +2 -2
- package/public/assets/{formatted-body-impl-Do5NbJUA.js.map → formatted-body-impl-CNQ5sqwK.js.map} +1 -1
- package/public/assets/index-D2Mpzpft.js +26 -0
- package/public/assets/{index-BdNafiPz.js.map → index-D2Mpzpft.js.map} +1 -1
- package/public/assets/{input-Rc4oWv4q.js → input-BvNUEkDd.js} +2 -2
- package/public/assets/{input-Rc4oWv4q.js.map → input-BvNUEkDd.js.map} +1 -1
- package/public/assets/{insights-i6AEZT_a.js → insights-5rkMFRgf.js} +2 -2
- package/public/assets/{insights-i6AEZT_a.js.map → insights-5rkMFRgf.js.map} +1 -1
- package/public/assets/{integrations-9c6IdRU4.js → integrations-BEaqjfP4.js} +2 -2
- package/public/assets/{integrations-9c6IdRU4.js.map → integrations-BEaqjfP4.js.map} +1 -1
- package/public/assets/{lib-BZ6WPg2t.js → lib-BvrbNA2I.js} +2 -2
- package/public/assets/{lib-BZ6WPg2t.js.map → lib-BvrbNA2I.js.map} +1 -1
- package/public/assets/{lucide-react-NXHPIMsX.js → lucide-react-DD_zIava.js} +2 -2
- package/public/assets/{lucide-react-NXHPIMsX.js.map → lucide-react-DD_zIava.js.map} +1 -1
- package/public/assets/maintenance-CEiURaYZ.js +2 -0
- package/public/assets/{maintenance-CJ6wikpg.js.map → maintenance-CEiURaYZ.js.map} +1 -1
- package/public/assets/{managed-agents-JZn0xNJR.js → managed-agents-CetHyuQW.js} +4 -4
- package/public/assets/{managed-agents-JZn0xNJR.js.map → managed-agents-CetHyuQW.js.map} +1 -1
- package/public/assets/{markdown-preview-impl-BsvAkpR4.js → markdown-preview-impl-ZwGYvObh.js} +2 -2
- package/public/assets/{markdown-preview-impl-BsvAkpR4.js.map → markdown-preview-impl-ZwGYvObh.js.map} +1 -1
- package/public/assets/memory-BTm8XzCg.js +2 -0
- package/public/assets/{memory-BE9IwCdC.js.map → memory-BTm8XzCg.js.map} +1 -1
- package/public/assets/{messages-vXgdc3H4.js → messages-fJd17pzv.js} +2 -2
- package/public/assets/{messages-vXgdc3H4.js.map → messages-fJd17pzv.js.map} +1 -1
- package/public/assets/{orchestrators-CribhLg-.js → orchestrators-C5XQ2UYy.js} +2 -2
- package/public/assets/{orchestrators-CribhLg-.js.map → orchestrators-C5XQ2UYy.js.map} +1 -1
- package/public/assets/overview-Bhk-tqKc.js +2 -0
- package/public/assets/{overview-q3O9K9VK.js.map → overview-Bhk-tqKc.js.map} +1 -1
- package/public/assets/{pairs-BNOnd0IE.js → pairs-CBrszSZh.js} +2 -2
- package/public/assets/{pairs-BNOnd0IE.js.map → pairs-CBrszSZh.js.map} +1 -1
- package/public/assets/{projects-iDkxAGBW.js → projects-DXy9JviE.js} +2 -2
- package/public/assets/{projects-iDkxAGBW.js.map → projects-DXy9JviE.js.map} +1 -1
- package/public/assets/prompt-settings-DEQhAt2X.js +2 -0
- package/public/assets/{prompt-settings-Bdz_xCgD.js.map → prompt-settings-DEQhAt2X.js.map} +1 -1
- package/public/assets/{react-dom-8yaD9iJG.js → react-dom-CADlISeR.js} +2 -2
- package/public/assets/{react-dom-8yaD9iJG.js.map → react-dom-CADlISeR.js.map} +1 -1
- package/public/assets/{registry-DPcyGypi.js → registry-DsZILce1.js} +4 -4
- package/public/assets/{registry-DPcyGypi.js.map → registry-DsZILce1.js.map} +1 -1
- package/public/assets/{security-Z3l3u-Pl.js → security-C-wVZm5k.js} +2 -2
- package/public/assets/{security-Z3l3u-Pl.js.map → security-C-wVZm5k.js.map} +1 -1
- package/public/assets/{select-BX_lW49D.js → select-DsEGBLJk.js} +2 -2
- package/public/assets/{select-BX_lW49D.js.map → select-DsEGBLJk.js.map} +1 -1
- package/public/assets/settings-D3_r5IGA.js +6 -0
- package/public/assets/{settings-Y381jZt7.js.map → settings-D3_r5IGA.js.map} +1 -1
- package/public/assets/{store-D-Frk_EC.js → store-DKTb9O0v.js} +5 -5
- package/public/assets/{store-D-Frk_EC.js.map → store-DKTb9O0v.js.map} +1 -1
- package/public/assets/{task-chip-CeujtXYT.js → task-chip-DwdauC08.js} +2 -2
- package/public/assets/{task-chip-CeujtXYT.js.map → task-chip-DwdauC08.js.map} +1 -1
- package/public/assets/{tasks-Di6d0_Ch.js → tasks-DnEzBku4.js} +2 -2
- package/public/assets/{tasks-Di6d0_Ch.js.map → tasks-DnEzBku4.js.map} +1 -1
- package/public/assets/{teams-DJv4l-_l.js → teams-DpAbZ3ye.js} +2 -2
- package/public/assets/{teams-DJv4l-_l.js.map → teams-DpAbZ3ye.js.map} +1 -1
- package/public/assets/{terminal-viewer-impl-3zBLpRel.js → terminal-viewer-impl-_IU5o8ya.js} +3 -3
- package/public/assets/{terminal-viewer-impl-3zBLpRel.js.map → terminal-viewer-impl-_IU5o8ya.js.map} +1 -1
- package/public/assets/types-BqeSkWrv.js.map +1 -1
- package/public/assets/{use-keyboard-viewport-cGEmrGE7.js → use-keyboard-viewport-wTh5CR4-.js} +2 -2
- package/public/assets/{use-keyboard-viewport-cGEmrGE7.js.map → use-keyboard-viewport-wTh5CR4-.js.map} +1 -1
- package/public/assets/user-avatar-CZ3XO8ml.js +2 -0
- package/public/assets/{user-avatar-qbo-B3dQ.js.map → user-avatar-CZ3XO8ml.js.map} +1 -1
- package/public/assets/{work-queue-D73-hP0c.js → work-queue-DKcLZWRl.js} +2 -2
- package/public/assets/{work-queue-D73-hP0c.js.map → work-queue-DKcLZWRl.js.map} +1 -1
- package/public/assets/workspaces-Cs2IZZOI.js +3 -0
- package/public/assets/{workspaces-CoDz-iZd.js.map → workspaces-Cs2IZZOI.js.map} +1 -1
- package/public/index.html +24 -24
- package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/runner/src/adapters/claude-transcript.ts +52 -3
- package/runner/src/control-server.ts +34 -17
- package/runner/src/runner-core.ts +64 -30
- package/src/db/messages.ts +20 -8
- package/public/assets/agents-Dt5TncjC.js +0 -2
- package/public/assets/chat-DhYX9BDG.js +0 -2
- package/public/assets/chat-DhYX9BDG.js.map +0 -1
- package/public/assets/copy-button-C67FUG3E.js +0 -2
- package/public/assets/dist-BJKxqIQd.js +0 -2
- package/public/assets/dist-CHKra2JV.js +0 -2
- package/public/assets/dist-G8YBD-wp.js +0 -2
- package/public/assets/formatted-body-D5-1aiyB.js +0 -3
- package/public/assets/index-BdNafiPz.js +0 -26
- package/public/assets/maintenance-CJ6wikpg.js +0 -2
- package/public/assets/memory-BE9IwCdC.js +0 -2
- package/public/assets/overview-q3O9K9VK.js +0 -2
- package/public/assets/prompt-settings-Bdz_xCgD.js +0 -2
- package/public/assets/settings-Y381jZt7.js +0 -6
- package/public/assets/user-avatar-qbo-B3dQ.js +0 -2
- package/public/assets/workspaces-CoDz-iZd.js +0 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-Y381jZt7.js","names":[],"sources":["../../dashboard/src/components/settings/schema-utils.ts","../../dashboard/src/components/settings/schema-form.tsx","../../dashboard/src/components/settings/browser-settings.tsx","../../dashboard/src/components/settings/model-catalog-settings.tsx","../../dashboard/src/components/settings/quota-settings.tsx","../../dashboard/src/components/settings/routing-coordinator-panel.tsx","../../dashboard/src/components/settings/routing-settings.tsx","../../dashboard/src/components/views/settings.tsx"],"sourcesContent":["import { isRecord, type JSONSchema, type SettingEntry } from 'agent-relay-sdk/types'\n\nexport { hasScope } from 'agent-relay-sdk/types'\nexport type { SettingEntry }\n\ninterface SettingGroup {\n group: string\n slug: string\n settings: SettingEntry[]\n}\n\nexport type Path = Array<string | number>\n\nexport function settingId(setting: Pick<SettingEntry, 'namespace' | 'key'>): string {\n return `${setting.namespace}/${setting.key}`\n}\n\nexport function settingPath(setting: Pick<SettingEntry, 'namespace' | 'key'>): string {\n return `/settings/${encodeURIComponent(setting.namespace)}/${encodeURIComponent(setting.key)}`\n}\n\nexport function slugify(value: string): string {\n return value.trim().toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '') || 'settings'\n}\n\nexport function groupSettings(settings: SettingEntry[]): SettingGroup[] {\n const groups = new Map<string, SettingEntry[]>()\n for (const setting of settings.filter((entry) => entry.readable)) {\n const group = setting.display?.group?.trim() || setting.namespace\n groups.set(group, [...(groups.get(group) ?? []), setting])\n }\n return [...groups.entries()]\n .map(([group, items]) => ({\n group,\n slug: slugify(group),\n settings: items.sort(compareSettings),\n }))\n .sort((a, b) => groupOrder(a.settings) - groupOrder(b.settings) || a.group.localeCompare(b.group))\n}\n\nfunction compareSettings(a: SettingEntry, b: SettingEntry): number {\n return (a.display?.order ?? Number.MAX_SAFE_INTEGER) - (b.display?.order ?? Number.MAX_SAFE_INTEGER)\n || a.display?.label?.localeCompare(b.display?.label ?? '') || 0\n || settingId(a).localeCompare(settingId(b))\n}\n\nfunction groupOrder(settings: SettingEntry[]): number {\n return Math.min(...settings.map((setting) => setting.display?.order ?? Number.MAX_SAFE_INTEGER))\n}\n\nexport function schemaType(schema: JSONSchema): string | undefined {\n return Array.isArray(schema.type) ? schema.type.find((type) => type !== 'null') : schema.type\n}\n\nexport function valueAtPath(value: unknown, path: Path): unknown {\n let current = value\n for (const part of path) {\n if (typeof part === 'number') {\n if (!Array.isArray(current)) return undefined\n current = current[part]\n } else {\n if (!isRecord(current)) return undefined\n current = current[part]\n }\n }\n return current\n}\n\nexport function setValueAtPath(value: unknown, path: Path, next: unknown): unknown {\n if (!path.length) return next\n const [head, ...tail] = path\n if (head === undefined) return next\n if (typeof head === 'number') {\n const array = Array.isArray(value) ? [...value] : []\n array[head] = setValueAtPath(array[head], tail, next)\n return array\n }\n const record = isRecord(value) ? { ...value } : {}\n const updated = setValueAtPath(record[head], tail, next)\n if (updated === undefined) delete record[head]\n else record[head] = updated\n return record\n}\n\nexport function defaultValueForSchema(schema: JSONSchema): unknown {\n if (schema.default !== undefined) return schema.default\n if (schema.const !== undefined) return schema.const\n if (schema.enum?.length) return schema.enum[0]\n switch (schemaType(schema)) {\n case 'boolean': return false\n case 'integer':\n case 'number': return 0\n case 'array': return []\n case 'object': return {}\n case 'string': return ''\n default: return undefined\n }\n}\n\nexport function lines(value: string): string[] {\n return value.split(/\\r?\\n|,/).map((line) => line.trim()).filter(Boolean)\n}\n\nexport function arrayText(value: unknown): string {\n return Array.isArray(value) ? value.map((item) => String(item)).join('\\n') : ''\n}\n\nexport function recordText(value: unknown): string {\n if (!isRecord(value)) return ''\n return Object.entries(value).map(([key, item]) => `${key}=${String(item ?? '')}`).join('\\n')\n}\n\nexport function parseRecordText(value: string): Record<string, string> {\n return Object.fromEntries(value.split(/\\r?\\n/).map((raw) => raw.trim()).filter(Boolean).map((line) => {\n const idx = line.indexOf('=')\n return idx >= 0 ? [line.slice(0, idx).trim(), line.slice(idx + 1)] : [line, '']\n }))\n}\n\nexport { isRecord }\n","import { useState, type ReactNode } from 'react'\nimport type { JSONSchema, SettingTier } from 'agent-relay-sdk/types'\nimport { api, type ApiError } from '@/lib/api'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Textarea } from '@/components/ui/textarea'\nimport { Switch } from '@/components/ui/switch'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport { Badge } from '@/components/ui/badge'\nimport { Card, CardAction, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'\nimport { AlertCircle, CheckCircle2, MonitorCog, Save, ServerCog } from 'lucide-react'\nimport {\n arrayText,\n defaultValueForSchema,\n isRecord,\n lines,\n parseRecordText,\n recordText,\n schemaType,\n setValueAtPath,\n settingId,\n settingPath,\n type Path,\n type SettingEntry,\n} from './schema-utils'\n\nexport const UNSET = '__unset__'\n\nfunction tierLabel(tier: SettingTier): string {\n if (tier === 'server-runtime') return 'Server runtime'\n if (tier === 'bootstrap') return 'Bootstrap'\n return 'Browser'\n}\n\nfunction tierDescription(tier: SettingTier): string {\n if (tier === 'server-runtime') return 'Stored by Relay and mutable while the server is running.'\n if (tier === 'bootstrap') return 'Read from startup configuration; restart or host config changes are required.'\n return 'Stored only in this browser profile.'\n}\n\nfunction tierIcon(tier: SettingTier) {\n if (tier === 'browser') return <MonitorCog className=\"size-3.5\" />\n return <ServerCog className=\"size-3.5\" />\n}\n\nexport function errorDetails(error: unknown): string[] {\n return (error as ApiError).details ?? []\n}\n\nexport function SchemaGroup({ group, settings, onSaved }: { group: string; settings: SettingEntry[]; onSaved: (setting: SettingEntry) => void }) {\n const tiers = [...new Set(settings.map((setting) => setting.tier))]\n return (\n <section className=\"space-y-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <h2 className=\"text-base font-semibold\">{group}</h2>\n <div className=\"flex flex-wrap gap-1\">\n {tiers.map((tier) => (\n <Badge key={tier} variant=\"outline\" className=\"gap-1\" title={tierDescription(tier)}>\n {tierIcon(tier)}\n {tierLabel(tier)}\n </Badge>\n ))}\n </div>\n </div>\n {settings.length === 0 ? (\n <Card size=\"sm\">\n <CardContent className=\"text-sm text-muted-foreground\">No settings in this group.</CardContent>\n </Card>\n ) : (\n <div className=\"space-y-3\">\n {settings.map((setting) => (\n <SettingCard key={settingId(setting)} setting={setting} onSaved={onSaved} />\n ))}\n </div>\n )}\n </section>\n )\n}\n\nfunction SettingCard({ setting, onSaved }: { setting: SettingEntry; onSaved: (setting: SettingEntry) => void }) {\n const [draft, setDraft] = useState<unknown>(() => setting.value ?? setting.defaults ?? defaultValueForSchema(setting.schema))\n const [saving, setSaving] = useState(false)\n const [status, setStatus] = useState('')\n const [errors, setErrors] = useState<string[]>([])\n const isWritable = setting.writable && setting.tier === 'server-runtime'\n\n function update(path: Path, value: unknown) {\n setDraft((current: unknown) => setValueAtPath(current, path, value))\n setErrors([])\n setStatus('')\n }\n\n async function save() {\n if (!isWritable) return\n setSaving(true)\n setErrors([])\n setStatus('')\n try {\n const saved = await api<SettingEntry>('PUT', settingPath(setting), { value: draft, updatedBy: 'dashboard' })\n setDraft(saved.value)\n onSaved(saved)\n setStatus('Saved')\n } catch (e) {\n const details = errorDetails(e)\n setErrors(details.length ? details : [(e as Error).message])\n } finally {\n setSaving(false)\n }\n }\n\n return (\n <Card size=\"sm\">\n <CardHeader>\n <CardTitle className=\"flex flex-wrap items-center gap-2 text-sm\">\n {setting.display.label}\n <Badge variant=\"outline\" className=\"gap-1\" title={tierDescription(setting.tier)}>{tierIcon(setting.tier)}{tierLabel(setting.tier)}</Badge>\n {!setting.writable && <Badge variant=\"secondary\">Read only</Badge>}\n </CardTitle>\n {setting.display.description && <CardDescription>{setting.display.description}</CardDescription>}\n <CardAction>\n <Button size=\"sm\" onClick={save} disabled={!isWritable || saving}>\n <Save className=\"size-4\" />\n {saving ? 'Saving' : 'Save'}\n </Button>\n </CardAction>\n </CardHeader>\n\n <CardContent className=\"space-y-3\">\n <SchemaField\n schema={setting.schema}\n value={draft}\n path={[]}\n label={setting.display.label}\n required\n disabled={!isWritable || saving}\n onChange={update}\n />\n\n <p className=\"flex flex-wrap items-center gap-x-2 text-[11px] text-muted-foreground\">\n <code className=\"rounded bg-muted px-1.5 py-0.5 font-mono\">{setting.namespace}/{setting.key}</code>\n <span>read <span className=\"text-foreground/70\">{setting.scope.read}</span></span>\n <span aria-hidden>·</span>\n <span>write <span className=\"text-foreground/70\">{setting.scope.write}</span></span>\n </p>\n\n {errors.length > 0 && (\n <div className=\"rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive\">\n <div className=\"mb-1 flex items-center gap-2 font-medium\"><AlertCircle className=\"size-4\" />Save failed</div>\n <ul className=\"list-disc space-y-1 pl-5\">\n {errors.map((detail) => <li key={detail}>{detail}</li>)}\n </ul>\n </div>\n )}\n {status && <p className=\"flex items-center gap-1 text-sm text-emerald-500\"><CheckCircle2 className=\"size-4\" />{status}</p>}\n </CardContent>\n </Card>\n )\n}\n\nfunction SchemaField(props: {\n schema: JSONSchema\n value: unknown\n path: Path\n label: string\n required: boolean\n disabled: boolean\n onChange: (path: Path, value: unknown) => void\n}) {\n const { schema, value, path, label, required, disabled, onChange } = props\n const type = schemaType(schema)\n\n if (schema.enum?.length) {\n const current = value === undefined || value === null || value === '' ? UNSET : String(value)\n return (\n <Field label={label} description={schema.description}>\n <Select value={current} onValueChange={(next) => onChange(path, next === UNSET ? undefined : next)} disabled={disabled}>\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n {!required && <SelectItem value={UNSET}>Not set</SelectItem>}\n {schema.enum.map((item) => <SelectItem key={String(item)} value={String(item)}>{String(item)}</SelectItem>)}\n </SelectContent>\n </Select>\n </Field>\n )\n }\n\n if (type === 'boolean') {\n return (\n <div className=\"flex items-center justify-between gap-3 rounded-md border bg-muted/20 p-3\">\n <div>\n <div className=\"text-sm font-medium\">{label}</div>\n {schema.description && <div className=\"text-xs text-muted-foreground\">{schema.description}</div>}\n </div>\n <Switch checked={Boolean(value)} onCheckedChange={(next) => onChange(path, next)} disabled={disabled} />\n </div>\n )\n }\n\n if (type === 'integer' || type === 'number') {\n return (\n <Field label={label} description={schema.description}>\n <Input\n type=\"number\"\n min={typeof schema.minimum === 'number' ? schema.minimum : undefined}\n max={typeof schema.maximum === 'number' ? schema.maximum : undefined}\n step={type === 'integer' ? 1 : 'any'}\n value={typeof value === 'number' ? value : ''}\n disabled={disabled}\n onChange={(e) => onChange(path, e.target.value === '' && !required ? undefined : Number(e.target.value))}\n />\n </Field>\n )\n }\n\n if (type === 'array') {\n return (\n <Field label={label} description={schema.description ?? 'One item per line.'}>\n <Textarea\n rows={Math.min(8, Math.max(3, Array.isArray(value) ? value.length + 1 : 3))}\n value={arrayText(value)}\n disabled={disabled}\n onChange={(e) => onChange(path, lines(e.target.value))}\n />\n </Field>\n )\n }\n\n if (type === 'object') {\n const properties = schema.properties ?? {}\n const requiredKeys = new Set(schema.required ?? [])\n if (Object.keys(properties).length === 0 && schema.additionalProperties) {\n return (\n <Field label={label} description={schema.description ?? 'KEY=value, one entry per line.'}>\n <Textarea rows={5} value={recordText(value)} disabled={disabled} onChange={(e) => onChange(path, parseRecordText(e.target.value))} />\n </Field>\n )\n }\n return (\n <div className=\"space-y-3\">\n {path.length > 0 && (\n <div>\n <div className=\"text-sm font-medium\">{label}</div>\n {schema.description && <div className=\"text-xs text-muted-foreground\">{schema.description}</div>}\n </div>\n )}\n <div className=\"grid gap-3 md:grid-cols-2\">\n {Object.entries(properties).map(([key, child]) => {\n const childValue = isRecord(value) ? value[key] : undefined\n return (\n <SchemaField\n key={key}\n schema={child}\n value={childValue === undefined && requiredKeys.has(key) ? defaultValueForSchema(child) : childValue}\n path={[...path, key]}\n label={child.title || labelForKey(key)}\n required={requiredKeys.has(key)}\n disabled={disabled}\n onChange={onChange}\n />\n )\n })}\n </div>\n </div>\n )\n }\n\n return (\n <Field label={label} description={schema.description}>\n <Input\n value={typeof value === 'string' ? value : value == null ? '' : String(value)}\n disabled={disabled}\n onChange={(e) => onChange(path, e.target.value === '' && !required ? undefined : e.target.value)}\n />\n </Field>\n )\n}\n\nexport function Field({ label, description, children }: { label: string; description?: string; children: ReactNode }) {\n return (\n <label className=\"block space-y-1.5 text-sm\">\n <span className=\"text-muted-foreground\">{label}</span>\n {children}\n {description && <span className=\"block text-xs text-muted-foreground\">{description}</span>}\n </label>\n )\n}\n\nfunction labelForKey(key: string): string {\n return key.replace(/([a-z0-9])([A-Z])/g, '$1 $2').replace(/[-_]+/g, ' ').replace(/^\\w/, (char) => char.toUpperCase())\n}\n","import { useEffect, useState } from 'react'\nimport { THEMES } from '@/lib/themes'\nimport { KOKORO_VOICES, availableSpeechVoices } from '@/lib/voice'\nimport { useRelayStore } from '@/store'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport { Switch } from '@/components/ui/switch'\nimport { Badge } from '@/components/ui/badge'\nimport { Card, CardAction, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'\nimport { Brain, MonitorCog, Volume2 } from 'lucide-react'\nimport type { ThemeId } from '@/types'\nimport { Field, UNSET } from './schema-form'\n\nexport function BrowserSettings() {\n const theme = useRelayStore((s) => s.theme)\n const showReasoning = useRelayStore((s) => s.showReasoning)\n const set = useRelayStore((s) => s.set)\n return (\n <section className=\"space-y-4\">\n <div>\n <h2 className=\"text-base font-semibold\">Browser preferences</h2>\n <p className=\"text-sm text-muted-foreground\">These are stored in local dashboard state, not in Relay server config.</p>\n </div>\n <Card size=\"sm\">\n <CardHeader>\n <CardTitle className=\"text-sm\">Dashboard display</CardTitle>\n <CardDescription className=\"text-xs\">Browser tier · persisted in this browser profile.</CardDescription>\n <CardAction>\n <Badge variant=\"outline\" className=\"gap-1\"><MonitorCog className=\"size-3.5\" />Browser</Badge>\n </CardAction>\n </CardHeader>\n <CardContent className=\"grid gap-3 md:grid-cols-2\">\n <Field label=\"Theme\">\n <Select value={theme} onValueChange={(value) => set({ theme: value as ThemeId })}>\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n {THEMES.map((item) => <SelectItem key={item.id} value={item.id}>{item.label}</SelectItem>)}\n </SelectContent>\n </Select>\n </Field>\n <div className=\"flex items-center justify-between gap-3 rounded-md border bg-muted/20 p-3\">\n <div className=\"flex items-center gap-2\">\n <Brain className=\"size-4\" />\n <div>\n <div className=\"text-sm font-medium\">Show reasoning details</div>\n <div className=\"text-xs text-muted-foreground\">Display captured reasoning/tool steps in chat. Server capture is controlled separately by provider reasoningCapture.</div>\n </div>\n </div>\n <Switch checked={showReasoning} onCheckedChange={(value) => set({ showReasoning: value })} />\n </div>\n </CardContent>\n </Card>\n <VoiceSettings />\n </section>\n )\n}\n\nfunction VoiceSettings() {\n const voiceTtsEnabled = useRelayStore((s) => s.voiceTtsEnabled)\n const setVoiceTtsEnabled = useRelayStore((s) => s.setVoiceTtsEnabled)\n const voiceTtsMode = useRelayStore((s) => s.voiceTtsMode)\n const setVoiceTtsMode = useRelayStore((s) => s.setVoiceTtsMode)\n const voiceTtsKokoroVoice = useRelayStore((s) => s.voiceTtsKokoroVoice)\n const setVoiceTtsKokoroVoice = useRelayStore((s) => s.setVoiceTtsKokoroVoice)\n const voiceTtsBrowserVoice = useRelayStore((s) => s.voiceTtsBrowserVoice)\n const setVoiceTtsBrowserVoice = useRelayStore((s) => s.setVoiceTtsBrowserVoice)\n const voiceInputMode = useRelayStore((s) => s.voiceInputMode)\n const setVoiceInputMode = useRelayStore((s) => s.setVoiceInputMode)\n\n // External sync: the browser loads speech voices asynchronously.\n const [browserVoices, setBrowserVoices] = useState(() => availableSpeechVoices())\n useEffect(() => {\n if (typeof window === 'undefined' || !('speechSynthesis' in window)) return\n const refresh = () => setBrowserVoices(availableSpeechVoices())\n refresh()\n window.speechSynthesis.addEventListener?.('voiceschanged', refresh)\n return () => window.speechSynthesis.removeEventListener?.('voiceschanged', refresh)\n }, [])\n\n const kokoroOptions = KOKORO_VOICES.some((voice) => voice.id === voiceTtsKokoroVoice)\n ? KOKORO_VOICES\n : [...KOKORO_VOICES, { id: voiceTtsKokoroVoice, label: voiceTtsKokoroVoice }]\n\n return (\n <Card size=\"sm\">\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2 text-sm\"><Volume2 className=\"size-4\" />Voice</CardTitle>\n <CardDescription className=\"text-xs\">Browser tier TTS and push-to-talk behavior.</CardDescription>\n <CardAction>\n <Switch checked={voiceTtsEnabled} onCheckedChange={setVoiceTtsEnabled} />\n </CardAction>\n </CardHeader>\n <CardContent className=\"grid gap-3 md:grid-cols-2\">\n <Field label=\"Speech engine\">\n <Select value={voiceTtsMode} onValueChange={(value) => setVoiceTtsMode(value as 'kokoro' | 'browser')}>\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n <SelectItem value=\"kokoro\">Kokoro (server, fallback to browser)</SelectItem>\n <SelectItem value=\"browser\">Browser Web Speech API</SelectItem>\n </SelectContent>\n </Select>\n </Field>\n <Field label=\"Kokoro voice\">\n <Select value={voiceTtsKokoroVoice} onValueChange={setVoiceTtsKokoroVoice}>\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n {kokoroOptions.map((voice) => <SelectItem key={voice.id} value={voice.id}>{voice.label}</SelectItem>)}\n </SelectContent>\n </Select>\n </Field>\n <Field label=\"Browser voice\">\n <Select value={voiceTtsBrowserVoice || UNSET} onValueChange={(value) => setVoiceTtsBrowserVoice(value === UNSET ? '' : value)}>\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n <SelectItem value={UNSET}>System default</SelectItem>\n {browserVoices.map((voice) => <SelectItem key={voice.uri} value={voice.uri}>{voice.label}</SelectItem>)}\n </SelectContent>\n </Select>\n </Field>\n <Field label=\"Push-to-talk input\">\n <Select value={voiceInputMode} onValueChange={(value) => setVoiceInputMode(value as 'compose' | 'autosend' | 'handsfree')}>\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n <SelectItem value=\"compose\">Fill message box</SelectItem>\n <SelectItem value=\"autosend\">Send immediately</SelectItem>\n </SelectContent>\n </Select>\n </Field>\n </CardContent>\n </Card>\n )\n}\n","import { useState } from 'react'\nimport type { SpawnProvider } from 'agent-relay-sdk/types'\nimport { deriveContextThresholdFromWindowTokens, type ProviderCatalogEntry, type ProviderModelCatalogEntry } from 'agent-relay-sdk/provider-catalog'\nimport { api } from '@/lib/api'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Switch } from '@/components/ui/switch'\nimport { Badge } from '@/components/ui/badge'\nimport { Card, CardAction, CardContent, CardHeader, CardTitle } from '@/components/ui/card'\nimport { CheckCircle2, Eye, EyeOff, Pencil, Plus, ServerCog, SlidersHorizontal, Trash2 } from 'lucide-react'\nimport { errorDetails, Field } from './schema-form'\nimport { lines } from './schema-utils'\n\ninterface ProvidersResponse {\n catalog: ProviderCatalogEntry[]\n}\n\ninterface ModelForm {\n provider: SpawnProvider\n alias: string\n label: string\n providerModel: string\n efforts: string\n defaultEffort: string\n selfCompactUtilization: string\n warnUtilization: string\n hardBackstopUtilization: string\n disabled: boolean\n limits?: ProviderModelCatalogEntry['limits']\n capabilities?: ProviderModelCatalogEntry['capabilities']\n}\n\nexport function ModelCatalogSettings({\n catalog,\n error,\n canWrite,\n onCatalog,\n}: {\n catalog: ProviderCatalogEntry[]\n error: string\n canWrite: boolean\n onCatalog: (catalog: ProviderCatalogEntry[]) => void\n}) {\n const firstProvider = catalog[0]?.provider ?? ''\n const [provider, setProvider] = useState<SpawnProvider>(firstProvider)\n const [form, setForm] = useState<ModelForm>(() => emptyModelForm(firstProvider))\n const [status, setStatus] = useState('')\n const [errors, setErrors] = useState<string[]>([])\n\n const selectedProvider = catalog.some((entry) => entry.provider === provider) ? provider : firstProvider\n const selectedCatalog = catalog.find((entry) => entry.provider === selectedProvider) ?? catalog[0]\n const providers = catalog.map((entry) => entry.provider)\n\n function updateForm(patch: Partial<ModelForm>) {\n setForm((current) => ({ ...current, ...patch }))\n setErrors([])\n setStatus('')\n }\n\n function switchProvider(next: SpawnProvider) {\n setProvider(next)\n setForm(emptyModelForm(next))\n setErrors([])\n setStatus('')\n }\n\n async function reloadCatalog() {\n const res = await api<ProvidersResponse>('GET', '/providers')\n onCatalog(res.catalog)\n }\n\n async function saveModel() {\n if (!canWrite) return\n setErrors([])\n setStatus('')\n try {\n await api('PUT', `/providers/${encodeURIComponent(form.provider)}/models/${encodeURIComponent(form.alias)}`, {\n label: form.label,\n providerModel: form.providerModel,\n efforts: lines(form.efforts),\n defaultEffort: form.defaultEffort.trim() || undefined,\n limits: form.limits,\n capabilities: form.capabilities,\n contextThreshold: contextThresholdFromForm(form),\n disabled: form.disabled,\n updatedBy: 'dashboard',\n })\n await reloadCatalog()\n setStatus(`${form.alias} saved`)\n setForm(emptyModelForm(form.provider))\n } catch (e) {\n const details = errorDetails(e)\n setErrors(details.length ? details : [(e as Error).message])\n }\n }\n\n async function setDisabled(model: ProviderModelCatalogEntry, disabled: boolean) {\n if (!canWrite) return\n setErrors([])\n setStatus('')\n try {\n await api('PATCH', `/providers/${encodeURIComponent(selectedProvider)}/models/${encodeURIComponent(model.alias)}`, { disabled, updatedBy: 'dashboard' })\n await reloadCatalog()\n setStatus(`${model.alias} ${disabled ? 'disabled' : 'enabled'}`)\n } catch (e) {\n const details = errorDetails(e)\n setErrors(details.length ? details : [(e as Error).message])\n }\n }\n\n async function removeModel(model: ProviderModelCatalogEntry) {\n if (!canWrite) return\n setErrors([])\n setStatus('')\n try {\n await api('DELETE', `/providers/${encodeURIComponent(selectedProvider)}/models/${encodeURIComponent(model.alias)}`)\n await reloadCatalog()\n setStatus(`${model.alias} removed`)\n } catch (e) {\n const details = errorDetails(e)\n setErrors(details.length ? details : [(e as Error).message])\n }\n }\n\n function editModel(model: ProviderModelCatalogEntry) {\n setForm({\n provider: selectedProvider,\n alias: model.alias,\n label: model.label,\n providerModel: model.providerModel,\n efforts: model.efforts.join(', '),\n defaultEffort: model.defaultEffort ?? '',\n selfCompactUtilization: model.contextThreshold?.selfCompactUtilization?.toString() ?? '',\n warnUtilization: model.contextThreshold?.warnUtilization?.toString() ?? '',\n hardBackstopUtilization: model.contextThreshold?.hardBackstopUtilization?.toString() ?? '',\n disabled: Boolean(model.disabled),\n limits: model.limits,\n capabilities: model.capabilities,\n })\n setErrors([])\n setStatus('')\n }\n\n if (error) {\n return (\n <Card size=\"sm\">\n <CardContent className=\"text-sm text-muted-foreground\">\n <div className=\"mb-1 flex items-center gap-2 font-medium text-foreground\"><SlidersHorizontal className=\"size-4\" />Model catalog</div>\n {error}\n </CardContent>\n </Card>\n )\n }\n\n return (\n <section className=\"space-y-4\">\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div>\n <h2 className=\"text-base font-semibold\">Model catalog</h2>\n <p className=\"text-sm text-muted-foreground\">Add override models, disable unavailable models, or remove custom entries from the provider catalog.</p>\n </div>\n {!canWrite && <Badge variant=\"secondary\">Read only: needs settings:write:provider</Badge>}\n </div>\n\n <div className=\"flex flex-wrap gap-2\">\n {providers.map((item) => (\n <Button key={item} variant={item === selectedProvider ? 'default' : 'outline'} size=\"sm\" onClick={() => switchProvider(item)}>\n {item}\n </Button>\n ))}\n </div>\n\n <Card size=\"sm\">\n <CardHeader>\n <CardTitle className=\"text-sm\">Add or edit model</CardTitle>\n <CardAction>\n <Badge variant=\"outline\" className=\"gap-1\"><ServerCog className=\"size-3.5\" />Server runtime</Badge>\n </CardAction>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n <div className=\"grid gap-3 md:grid-cols-2\">\n <Field label=\"Alias\">\n <Input value={form.alias} disabled={!canWrite} placeholder=\"nightly\" onChange={(e) => updateForm({ alias: e.target.value.trim() })} />\n </Field>\n <Field label=\"Label\">\n <Input value={form.label} disabled={!canWrite} placeholder=\"Nightly Codex\" onChange={(e) => updateForm({ label: e.target.value })} />\n </Field>\n <Field label=\"Provider model\">\n <Input value={form.providerModel} disabled={!canWrite} placeholder=\"codex-nightly\" onChange={(e) => updateForm({ providerModel: e.target.value })} />\n </Field>\n <Field label=\"Efforts\">\n <Input value={form.efforts} disabled={!canWrite} placeholder=\"low, medium, high\" onChange={(e) => updateForm({ efforts: e.target.value })} />\n </Field>\n <Field label=\"Default effort\">\n <Input value={form.defaultEffort} disabled={!canWrite} placeholder=\"medium\" onChange={(e) => updateForm({ defaultEffort: e.target.value })} />\n </Field>\n <Field label=\"Self compact utilization\">\n <Input value={form.selfCompactUtilization} disabled={!canWrite} placeholder=\"0.80\" inputMode=\"decimal\" onChange={(e) => updateForm({ selfCompactUtilization: e.target.value })} />\n </Field>\n <Field label=\"Warn utilization\">\n <Input value={form.warnUtilization} disabled={!canWrite} placeholder=\"default: self - 0.10\" inputMode=\"decimal\" onChange={(e) => updateForm({ warnUtilization: e.target.value })} />\n </Field>\n <Field label=\"Hard backstop utilization\">\n <Input value={form.hardBackstopUtilization} disabled={!canWrite} placeholder=\"0.90\" inputMode=\"decimal\" onChange={(e) => updateForm({ hardBackstopUtilization: e.target.value })} />\n </Field>\n <div className=\"flex items-center justify-between gap-3 rounded-md border bg-muted/20 p-3\">\n <div>\n <div className=\"text-sm font-medium\">Disabled</div>\n <div className=\"text-xs text-muted-foreground\">Keep visible but unavailable for new launches.</div>\n </div>\n <Switch checked={form.disabled} disabled={!canWrite} onCheckedChange={(disabled) => updateForm({ disabled })} />\n </div>\n </div>\n <Button onClick={saveModel} disabled={!canWrite || !form.alias || !form.label || !form.providerModel}>\n <Plus className=\"size-4\" />\n Save model\n </Button>\n </CardContent>\n </Card>\n\n <div className=\"space-y-2\">\n {selectedCatalog && selectedCatalog.models.length === 0 && (\n <Card size=\"sm\">\n <CardContent className=\"text-sm text-muted-foreground\">No models in this provider catalog yet.</CardContent>\n </Card>\n )}\n {selectedCatalog?.models.map((model) => (\n <Card key={model.alias} size=\"sm\">\n <CardContent className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"min-w-0\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"font-medium\">{model.label}</span>\n <code className=\"rounded bg-muted px-1.5 py-0.5 font-mono text-xs\">{model.alias}</code>\n {model.disabled && <Badge variant=\"secondary\">Disabled</Badge>}\n </div>\n <p className=\"mt-1 text-xs text-muted-foreground\">\n {model.providerModel}\n {model.efforts.length > 0 ? ` · efforts ${model.efforts.join(', ')}` : ' · no effort levels'}\n {model.defaultEffort ? ` · default ${model.defaultEffort}` : ''}\n {` · context ${thresholdLabel(model)}`}\n </p>\n </div>\n <div className=\"flex flex-wrap gap-2\">\n <Button variant=\"outline\" size=\"sm\" onClick={() => editModel(model)}>\n <Pencil className=\"size-4\" />\n Edit\n </Button>\n <Button variant=\"outline\" size=\"sm\" disabled={!canWrite} onClick={() => void setDisabled(model, !model.disabled)}>\n {model.disabled ? <Eye className=\"size-4\" /> : <EyeOff className=\"size-4\" />}\n {model.disabled ? 'Enable' : 'Disable'}\n </Button>\n <Button variant=\"outline\" size=\"sm\" disabled={!canWrite} onClick={() => void removeModel(model)}>\n <Trash2 className=\"size-4\" />\n Remove\n </Button>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n\n {errors.length > 0 && (\n <div className=\"rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive\">\n <ul className=\"list-disc space-y-1 pl-5\">\n {errors.map((detail) => <li key={detail}>{detail}</li>)}\n </ul>\n </div>\n )}\n {status && <p className=\"flex items-center gap-1 text-sm text-emerald-500\"><CheckCircle2 className=\"size-4\" />{status}</p>}\n </section>\n )\n}\n\nfunction emptyModelForm(provider: SpawnProvider): ModelForm {\n return { provider, alias: '', label: '', providerModel: '', efforts: '', defaultEffort: '', selfCompactUtilization: '', warnUtilization: '', hardBackstopUtilization: '', disabled: false }\n}\n\nfunction contextThresholdFromForm(form: ModelForm): ProviderModelCatalogEntry['contextThreshold'] | undefined {\n const selfCompactUtilization = optionalNumber(form.selfCompactUtilization, 'Self compact utilization')\n const warnUtilization = optionalNumber(form.warnUtilization, 'Warn utilization')\n const hardBackstopUtilization = optionalNumber(form.hardBackstopUtilization, 'Hard backstop utilization')\n if (selfCompactUtilization === undefined && warnUtilization === undefined && hardBackstopUtilization === undefined) return undefined\n if (selfCompactUtilization === undefined) throw new Error('Self compact utilization is required when setting context thresholds')\n return {\n selfCompactUtilization,\n ...(warnUtilization !== undefined ? { warnUtilization } : {}),\n ...(hardBackstopUtilization !== undefined ? { hardBackstopUtilization } : {}),\n }\n}\n\nfunction optionalNumber(value: string, label: string): number | undefined {\n const trimmed = value.trim()\n if (!trimmed) return undefined\n const parsed = Number(trimmed)\n if (!Number.isFinite(parsed)) throw new Error(`${label} must be a number`)\n return parsed\n}\n\nfunction thresholdLabel(model: ProviderModelCatalogEntry): string {\n if (model.contextThreshold) {\n const self = percent(model.contextThreshold.selfCompactUtilization)\n const warn = percent(model.contextThreshold.warnUtilization ?? Math.max(0, model.contextThreshold.selfCompactUtilization - 0.1))\n return `self ${self}, warn ${warn}`\n }\n const derived = deriveContextThresholdFromWindowTokens(model.limits?.contextWindowTokens?.value)\n return `derived self ${percent(derived.selfCompactUtilization)}, warn ${percent(derived.warnUtilization)}`\n}\n\nfunction percent(value: number): string {\n return `${Math.round(value * 100)}%`\n}\n","import { useEffect, useState } from 'react'\nimport type { ProviderQuotaConfig, ProviderQuotaConfigMap } from 'agent-relay-sdk/types'\nimport { api } from '@/lib/api'\nimport { Switch } from '@/components/ui/switch'\nimport { Badge } from '@/components/ui/badge'\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'\nimport { AlertCircle, Gauge, Loader2 } from 'lucide-react'\n\n// Quota config block under Settings → Providers (#605). Per provider: enable\n// collection, poll cadence (5m–15m), and show-in-widget. enabled = collect,\n// showInWidget = display — disabling collection stops the orchestrator polling\n// that provider entirely; hiding only removes it from the dashboard widget.\nconst MIN_MINUTES = 5\nconst MAX_MINUTES = 15\n\nconst PROVIDER_LABELS: Record<string, string> = { claude: 'Claude', codex: 'Codex' }\n\nfunction minutesOf(pollIntervalMs: number): number {\n return Math.round(pollIntervalMs / 60_000)\n}\n\nfunction intervalLabel(pollIntervalMs: number): string {\n return `${minutesOf(pollIntervalMs)} min`\n}\n\nexport function QuotaSettings({ canWrite }: { canWrite: boolean }) {\n const [config, setConfig] = useState<ProviderQuotaConfigMap | null>(null)\n const [loadError, setLoadError] = useState('')\n const [saveError, setSaveError] = useState('')\n const [savingProvider, setSavingProvider] = useState<string | null>(null)\n\n // External data load on mount — mirrors the SettingsView reload() pattern.\n useEffect(() => {\n let cancelled = false\n void (async () => {\n try {\n const data = await api<ProviderQuotaConfigMap>('GET', '/providers/quota-config')\n if (!cancelled) setConfig(data)\n } catch (e) {\n if (!cancelled) setLoadError((e as Error).message)\n }\n })()\n return () => { cancelled = true }\n }, [])\n\n async function save(provider: string, next: ProviderQuotaConfig) {\n setConfig((current) => ({ ...(current ?? {}), [provider]: next }))\n setSaveError('')\n setSavingProvider(provider)\n try {\n const saved = await api<ProviderQuotaConfig>('PUT', `/providers/${provider}/quota-config`, next)\n setConfig((current) => ({ ...(current ?? {}), [provider]: saved }))\n } catch (e) {\n setSaveError(`${PROVIDER_LABELS[provider] ?? provider}: ${(e as Error).message}`)\n } finally {\n setSavingProvider(null)\n }\n }\n\n const providers = config ? Object.keys(config).sort() : []\n\n return (\n <section className=\"space-y-4\">\n <div>\n <h2 className=\"text-base font-semibold\">Quota</h2>\n <p className=\"text-sm text-muted-foreground\">\n Per-provider quota collection and display. <strong>Enabled</strong> governs collection (disabled stops polling — no API calls);\n <strong> Show in widget</strong> governs display only.\n </p>\n </div>\n\n {loadError && (\n <div className=\"flex items-start gap-2 rounded-lg border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive\">\n <AlertCircle className=\"mt-0.5 size-4\" />\n <span>{loadError}</span>\n </div>\n )}\n {saveError && (\n <div className=\"flex items-start gap-2 rounded-lg border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive\">\n <AlertCircle className=\"mt-0.5 size-4\" />\n <span>{saveError}</span>\n </div>\n )}\n\n {!config && !loadError && (\n <Card size=\"sm\"><CardContent className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <Loader2 className=\"size-4 animate-spin\" />Loading quota config…\n </CardContent></Card>\n )}\n\n {providers.map((provider) => {\n const cfg = config![provider]!\n const disabled = !canWrite || savingProvider === provider\n return (\n <Card key={provider} size=\"sm\">\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2 text-sm\">\n <Gauge className=\"size-4\" />\n {PROVIDER_LABELS[provider] ?? provider}\n {savingProvider === provider && <Loader2 className=\"size-3 animate-spin text-muted-foreground\" />}\n </CardTitle>\n <CardDescription className=\"text-xs\">\n {cfg.enabled ? `Polled every ${intervalLabel(cfg.pollIntervalMs)}` : 'Collection disabled'}\n {cfg.enabled && !cfg.showInWidget ? ' · hidden from widget' : ''}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"flex items-center justify-between gap-3 rounded-md border bg-muted/20 p-3\">\n <div>\n <div className=\"text-sm font-medium\">Enabled</div>\n <div className=\"text-xs text-muted-foreground\">Collect quota for this provider. Off stops all polling (no API calls, no token spend).</div>\n </div>\n <Switch\n checked={cfg.enabled}\n disabled={disabled}\n onCheckedChange={(enabled) => void save(provider, { ...cfg, enabled })}\n />\n </div>\n\n <div className=\"rounded-md border bg-muted/20 p-3 space-y-2\">\n <div className=\"flex items-center justify-between\">\n <div className=\"text-sm font-medium\">Polling interval</div>\n <Badge variant=\"outline\" className=\"tabular-nums\">{intervalLabel(cfg.pollIntervalMs)}</Badge>\n </div>\n <input\n type=\"range\"\n min={MIN_MINUTES}\n max={MAX_MINUTES}\n step={1}\n value={minutesOf(cfg.pollIntervalMs)}\n disabled={disabled || !cfg.enabled}\n // Live label update while dragging; persist on pointer/key release.\n onChange={(e) => {\n const pollIntervalMs = Number(e.target.value) * 60_000\n setConfig((current) => ({ ...(current ?? {}), [provider]: { ...cfg, pollIntervalMs } }))\n }}\n onPointerUp={(e) => void save(provider, { ...cfg, pollIntervalMs: Number((e.target as HTMLInputElement).value) * 60_000 })}\n onKeyUp={(e) => void save(provider, { ...cfg, pollIntervalMs: Number((e.target as HTMLInputElement).value) * 60_000 })}\n className=\"w-full accent-primary disabled:opacity-50\"\n />\n <div className=\"flex justify-between text-[10px] text-muted-foreground\">\n <span>{MIN_MINUTES} min</span>\n <span>{MAX_MINUTES} min</span>\n </div>\n </div>\n\n <div className=\"flex items-center justify-between gap-3 rounded-md border bg-muted/20 p-3\">\n <div>\n <div className=\"text-sm font-medium\">Show in quota widget</div>\n <div className=\"text-xs text-muted-foreground\">Display only. Off hides this provider from the dashboard widget; collection continues if enabled.</div>\n </div>\n <Switch\n checked={cfg.showInWidget}\n disabled={disabled}\n onCheckedChange={(showInWidget) => void save(provider, { ...cfg, showInWidget })}\n />\n </div>\n\n <div className=\"flex items-center justify-between gap-3 rounded-md border bg-muted/20 p-3\">\n <div>\n <div className=\"text-sm font-medium\">Burn-rate sparkline</div>\n <div className=\"text-xs text-muted-foreground\">Show a mini utilization chart per window in the expanded widget.</div>\n </div>\n <Switch\n checked={cfg.sparklineEnabled ?? true}\n disabled={disabled}\n onCheckedChange={(sparklineEnabled) => void save(provider, { ...cfg, sparklineEnabled })}\n />\n </div>\n\n <div className=\"rounded-md border bg-muted/20 p-3 space-y-2\">\n <div className=\"flex items-center justify-between\">\n <div className=\"text-sm font-medium\">Sparkline range</div>\n <Badge variant=\"outline\" className=\"tabular-nums\">{cfg.sparklineRangeHours ?? 8}h</Badge>\n </div>\n <input\n type=\"range\"\n min={1}\n max={8}\n step={1}\n value={cfg.sparklineRangeHours ?? 8}\n disabled={disabled || !(cfg.sparklineEnabled ?? true)}\n onChange={(e) => {\n const sparklineRangeHours = Number(e.target.value)\n setConfig((current) => ({ ...(current ?? {}), [provider]: { ...cfg, sparklineRangeHours } }))\n }}\n onPointerUp={(e) => void save(provider, { ...cfg, sparklineRangeHours: Number((e.target as HTMLInputElement).value) })}\n onKeyUp={(e) => void save(provider, { ...cfg, sparklineRangeHours: Number((e.target as HTMLInputElement).value) })}\n className=\"w-full accent-primary disabled:opacity-50\"\n />\n <div className=\"flex justify-between text-[10px] text-muted-foreground\">\n <span>1h</span>\n <span>8h</span>\n </div>\n </div>\n </CardContent>\n </Card>\n )\n })}\n </section>\n )\n}\n","import { useState } from 'react'\nimport type { ProviderQuotaRoutingConfig, QuotaBandThresholds, RoutingPolicy } from 'agent-relay-sdk/types'\nimport type { AgentProfile } from '@/types'\nimport { api } from '@/lib/api'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Badge } from '@/components/ui/badge'\nimport { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card'\nimport { AlertCircle, ChevronDown, ChevronRight, Eye, Loader2, RefreshCw, Save } from 'lucide-react'\nimport { cn } from '@/lib/utils'\nimport { getKnownProviderIds, getProviderLabel } from '@/lib/provider-display'\n\nfunction ErrorBanner({ message }: { message: string }) {\n return (\n <div className=\"flex items-start gap-2 rounded-lg border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive\">\n <AlertCircle className=\"mt-0.5 size-4 shrink-0\" />\n <span>{message}</span>\n </div>\n )\n}\n\nconst PROVIDERS = getKnownProviderIds()\n\nconst BAND_DEFAULTS = { cautionAt: 0.15, avoidLargeAt: 0.5, hardAvoidAt: 1.0 }\nconst BACKSTOP_DEFAULT = 0.99\nconst FLOOR_DEFAULT = 0.5\n\nfunction pctStr(v: number | undefined, def: number) {\n return ((v ?? def) * 100).toFixed(0)\n}\n\nfunction parseFraction(s: string): number | null {\n const trimmed = s.trim()\n if (!trimmed) return null\n const n = Number(trimmed)\n if (!Number.isFinite(n) || n < 0 || n > 100) return null\n return n / 100\n}\n\nfunction parseFractionWithBlankDefault(s: string, def: number): number | null {\n return s.trim() ? parseFraction(s) : def\n}\n\n// ─── QuotaThresholdsEditor ────────────────────────────────────────────────────\n\nexport function QuotaThresholdsEditor({\n policy,\n canWrite,\n onPolicy,\n}: {\n policy: RoutingPolicy\n canWrite: boolean\n onPolicy: (p: RoutingPolicy) => void\n}) {\n const bands = policy.quotaBands\n const providerQuota = policy.providerQuota ?? {}\n\n const [cautionPct, setCautionPct] = useState(pctStr(bands?.cautionAt, BAND_DEFAULTS.cautionAt))\n const [avoidLargePct, setAvoidLargePct] = useState(pctStr(bands?.avoidLargeAt, BAND_DEFAULTS.avoidLargeAt))\n const [hardAvoidPct, setHardAvoidPct] = useState(pctStr(bands?.hardAvoidAt, BAND_DEFAULTS.hardAvoidAt))\n\n const [providerForms, setProviderForms] = useState<Record<string, { backstop: string; floor: string }>>(() => {\n const out: Record<string, { backstop: string; floor: string }> = {}\n for (const p of PROVIDERS) {\n const cfg = providerQuota[p] ?? {}\n out[p] = {\n backstop: pctStr(cfg.hardBackstopUtilization, BACKSTOP_DEFAULT),\n floor: pctStr(cfg.burnPenaltyUtilizationFloor, FLOOR_DEFAULT),\n }\n }\n return out\n })\n\n const [saving, setSaving] = useState(false)\n const [saveError, setSaveError] = useState('')\n const [saveOk, setSaveOk] = useState(false)\n const [validationError, setValidationError] = useState('')\n\n async function save() {\n const caution = parseFraction(cautionPct)\n const avoidLarge = parseFraction(avoidLargePct)\n const hardAvoid = parseFraction(hardAvoidPct)\n\n if (caution === null) { setValidationError('Caution threshold must be 0–100%.'); return }\n if (avoidLarge === null) { setValidationError('Avoid-large threshold must be 0–100%.'); return }\n if (hardAvoid === null) { setValidationError('Hard-avoid threshold must be 0–100%.'); return }\n if (caution >= avoidLarge) { setValidationError('Caution must be less than avoid-large.'); return }\n if (avoidLarge >= hardAvoid) { setValidationError('Avoid-large must be less than hard-avoid.'); return }\n\n const nextProviderQuota: Partial<Record<string, ProviderQuotaRoutingConfig>> = {}\n for (const p of PROVIDERS) {\n const f = providerForms[p]!\n const backstop = parseFractionWithBlankDefault(f.backstop, BACKSTOP_DEFAULT)\n const floor = parseFraction(f.floor)\n if (backstop === null) { setValidationError(`${getProviderLabel(p)}: hard-backstop must be 0–100%.`); return }\n if (floor === null) { setValidationError(`${getProviderLabel(p)}: burn-penalty floor must be 0–100%.`); return }\n nextProviderQuota[p] = { hardBackstopUtilization: backstop, burnPenaltyUtilizationFloor: floor }\n }\n\n setValidationError('')\n setSaving(true)\n setSaveError('')\n setSaveOk(false)\n try {\n const saved = await api<RoutingPolicy>('PUT', '/routing-policy', {\n ...policy,\n quotaBands: { cautionAt: caution, avoidLargeAt: avoidLarge, hardAvoidAt: hardAvoid } satisfies QuotaBandThresholds,\n providerQuota: nextProviderQuota,\n })\n onPolicy(saved)\n setSaveOk(true)\n setTimeout(() => setSaveOk(false), 2000)\n } catch (e) {\n setSaveError((e as Error).message)\n } finally {\n setSaving(false)\n }\n }\n\n function patchProvider(provider: string, patch: { backstop?: string; floor?: string }) {\n setProviderForms((cur) => ({ ...cur, [provider]: { ...cur[provider]!, ...patch } }))\n setValidationError('')\n setSaveOk(false)\n }\n\n function markDirty() { setValidationError(''); setSaveOk(false) }\n\n return (\n <Card size=\"sm\">\n <CardHeader>\n <CardTitle className=\"text-sm\">Quota thresholds</CardTitle>\n <CardDescription className=\"text-xs\">\n Band cutoffs govern when the orchestrator starts penalising or blocking high-quota providers. Values are utilization percentages (0–100).\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {(saveError || validationError) && <ErrorBanner message={saveError || validationError} />}\n\n <div>\n <div className=\"mb-2 text-xs font-medium text-muted-foreground uppercase tracking-wide\">Band cutoffs</div>\n <QuotaBandDiagram caution={Number(cautionPct)} avoidLarge={Number(avoidLargePct)} hardAvoid={Number(hardAvoidPct)} />\n <div className=\"mt-3 grid gap-3 sm:grid-cols-3\">\n <FractionField label=\"Caution at\" hint={`Default: ${(BAND_DEFAULTS.cautionAt * 100).toFixed(0)}%`}\n value={cautionPct} disabled={!canWrite || saving} onChange={(v) => { setCautionPct(v); markDirty() }} />\n <FractionField label=\"Avoid-large at\" hint={`Default: ${(BAND_DEFAULTS.avoidLargeAt * 100).toFixed(0)}%`}\n value={avoidLargePct} disabled={!canWrite || saving} onChange={(v) => { setAvoidLargePct(v); markDirty() }} />\n <FractionField label=\"Hard-avoid at\" hint={`Default: ${(BAND_DEFAULTS.hardAvoidAt * 100).toFixed(0)}%`}\n value={hardAvoidPct} disabled={!canWrite || saving} onChange={(v) => { setHardAvoidPct(v); markDirty() }} />\n </div>\n </div>\n\n {PROVIDERS.map((p) => {\n const f = providerForms[p]!\n return (\n <div key={p}>\n <div className=\"mb-2 text-xs font-medium text-muted-foreground uppercase tracking-wide\">{getProviderLabel(p)} overrides</div>\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <FractionField label=\"Hard-backstop utilization\"\n hint={`0 = disable backstop (never block on this quota); blank uses the ${(BACKSTOP_DEFAULT * 100).toFixed(0)}% default.`}\n value={f.backstop} disabled={!canWrite || saving}\n onChange={(v) => patchProvider(p, { backstop: v })} />\n <FractionField label=\"Burn-penalty floor\"\n hint={`Penalties suppressed below this. Default: ${(FLOOR_DEFAULT * 100).toFixed(0)}%`}\n value={f.floor} disabled={!canWrite || saving}\n onChange={(v) => patchProvider(p, { floor: v })} />\n </div>\n </div>\n )\n })}\n\n {canWrite && (\n <Button size=\"sm\" onClick={() => void save()} disabled={saving}>\n {saving ? <Loader2 className=\"size-4 animate-spin\" /> : <Save className=\"size-4\" />}\n {saveOk ? 'Saved' : 'Save thresholds'}\n </Button>\n )}\n </CardContent>\n </Card>\n )\n}\n\n// Linear band diagram (#731): renders the four quota zones as proportional segments\n// on a 0–100% axis so the relationship between the three cutoffs is legible at a glance.\n// Driven live by the current input values — it reshapes as you edit the fields below.\nfunction QuotaBandDiagram({ caution, avoidLarge, hardAvoid }: { caution: number; avoidLarge: number; hardAvoid: number }) {\n const clamp = (n: number) => Math.max(0, Math.min(100, Number.isFinite(n) ? n : 0))\n const c = clamp(caution)\n // Keep boundaries monotonic for display even while a half-typed value is out of order.\n const a = Math.max(c, clamp(avoidLarge))\n const h = Math.max(a, clamp(hardAvoid))\n const fmt = (n: number) => `${n.toFixed(0)}%`\n const zones = [\n { key: 'normal', label: 'normal', color: 'bg-emerald-500', from: 0, to: c, range: `0–${fmt(c)}` },\n { key: 'caution', label: 'caution', color: 'bg-amber-500', from: c, to: a, range: `${fmt(c)}–${fmt(a)}` },\n { key: 'avoid-large', label: 'avoid large', color: 'bg-orange-500', from: a, to: h, range: `${fmt(a)}–${fmt(h)}` },\n { key: 'hard-avoid', label: 'hard avoid', color: 'bg-red-500', from: h, to: 100, range: `≥ ${fmt(h)}` },\n ]\n return (\n <div className=\"space-y-1.5\">\n <div className=\"flex h-2.5 overflow-hidden rounded-full bg-muted\" role=\"img\" aria-label=\"Quota penalty bands from 0 to 100 percent\">\n {zones.map((z) => (\n <div key={z.key} className={cn(z.color, 'transition-[width] duration-300')} style={{ width: `${z.to - z.from}%` }} title={`${z.label} · ${z.range}`} />\n ))}\n </div>\n <div className=\"flex flex-wrap gap-x-3 gap-y-1 text-[10px] text-muted-foreground\">\n {zones.map((z) => (\n <span key={z.key} className=\"flex items-center gap-1\">\n <span className={cn('size-2 shrink-0 rounded-full', z.color)} />\n {z.label} <span className=\"tabular-nums text-foreground/70\">{z.range}</span>\n </span>\n ))}\n </div>\n </div>\n )\n}\n\nfunction FractionField({ label, hint, value, disabled, onChange }: {\n label: string; hint: string; value: string; disabled: boolean; onChange: (v: string) => void\n}) {\n return (\n <label className=\"space-y-1\">\n <span className=\"text-[10px] font-medium text-muted-foreground\">{label}</span>\n <div className=\"relative\">\n <Input value={value} onChange={(e) => onChange(e.target.value)} disabled={disabled}\n className=\"h-8 pr-6 text-xs tabular-nums\" />\n <span className=\"pointer-events-none absolute inset-y-0 right-2.5 flex items-center text-xs text-muted-foreground\">%</span>\n </div>\n <span className=\"text-[10px] text-muted-foreground\">{hint}</span>\n </label>\n )\n}\n\n// ─── CoordinatorVisibilityPanel ───────────────────────────────────────────────\n\ninterface VisibilityData {\n policy: RoutingPolicy\n profile: AgentProfile | null\n}\n\nexport function CoordinatorVisibilityPanel() {\n const [data, setData] = useState<VisibilityData | null>(null)\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState('')\n const [open, setOpen] = useState(false)\n const [loaded, setLoaded] = useState(false)\n\n async function load() {\n if (loaded) return\n setLoading(true)\n setError('')\n try {\n const [policy, profile] = await Promise.all([\n api<RoutingPolicy>('GET', '/routing-policy'),\n api<AgentProfile>('GET', '/agent-profiles/coordinator').catch(() => null),\n ])\n setData({ policy, profile })\n setLoaded(true)\n } catch (e) {\n setError((e as Error).message)\n } finally {\n setLoading(false)\n }\n }\n\n async function reload() {\n setLoaded(false)\n setLoading(true)\n setError('')\n try {\n const [policy, profile] = await Promise.all([\n api<RoutingPolicy>('GET', '/routing-policy'),\n api<AgentProfile>('GET', '/agent-profiles/coordinator').catch(() => null),\n ])\n setData({ policy, profile })\n setLoaded(true)\n } catch (e) {\n setError((e as Error).message)\n } finally {\n setLoading(false)\n }\n }\n\n function toggle() {\n const next = !open\n setOpen(next)\n if (next && !loaded) void load()\n }\n\n return (\n <Card size=\"sm\">\n <CardContent className=\"space-y-3\">\n <button type=\"button\" className=\"flex w-full items-center gap-2 text-left\" onClick={toggle}>\n <Eye className=\"size-4 text-muted-foreground\" />\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm font-semibold\">What your coordinator knows</div>\n <div className=\"text-xs text-muted-foreground\">Active routing policy + coordinator profile instructions (read-only)</div>\n </div>\n {open ? <ChevronDown className=\"size-4 shrink-0 text-muted-foreground\" /> : <ChevronRight className=\"size-4 shrink-0 text-muted-foreground\" />}\n </button>\n\n {open && (\n <div className=\"space-y-4 pt-1\">\n <div className=\"flex justify-end\">\n <Button variant=\"outline\" size=\"sm\" onClick={() => void reload()} disabled={loading}>\n <RefreshCw className={cn('size-3.5', loading && 'animate-spin')} />\n Refresh\n </Button>\n </div>\n\n {error && <ErrorBanner message={error} />}\n\n {loading && !data && (\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground py-2\">\n <Loader2 className=\"size-3.5 animate-spin\" />Loading…\n </div>\n )}\n\n {data && (\n <>\n <ActivePolicyDisplay policy={data.policy} />\n {data.profile\n ? <CoordinatorProfileDisplay profile={data.profile} />\n : <div className=\"text-xs text-muted-foreground italic\">Coordinator profile not found.</div>\n }\n </>\n )}\n </div>\n )}\n </CardContent>\n </Card>\n )\n}\n\nfunction ActivePolicyDisplay({ policy }: { policy: RoutingPolicy }) {\n const bands = policy.quotaBands\n const providerQuota = policy.providerQuota ?? {}\n\n return (\n <div className=\"space-y-2\">\n <div className=\"text-xs font-semibold text-muted-foreground uppercase tracking-wide\">Active routing policy</div>\n\n {policy.rules.length === 0 ? (\n <div className=\"text-xs text-muted-foreground italic\">No rules — coordinators use their own heuristics.</div>\n ) : (\n <div className=\"overflow-hidden rounded-md border border-border text-xs\">\n <div className=\"grid grid-cols-[1.5rem_minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)] gap-px bg-border text-[10px] font-medium text-muted-foreground uppercase tracking-wide\">\n <div className=\"bg-muted/40 px-2 py-1.5\">#</div>\n <div className=\"bg-muted/40 px-2 py-1.5\">Match</div>\n <div className=\"bg-muted/40 px-2 py-1.5\">Target</div>\n <div className=\"bg-muted/40 px-2 py-1.5\">Status</div>\n </div>\n {policy.rules.map((rule, idx) => (\n <div key={idx}\n className={cn('grid grid-cols-[1.5rem_minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)] gap-px bg-border', rule.enabled === false && 'opacity-50')}>\n <div className=\"bg-card px-2 py-1.5 text-muted-foreground tabular-nums\">{idx + 1}</div>\n <div className=\"bg-card px-2 py-1.5\">\n {rule.label && <div className=\"font-medium\">{rule.label}</div>}\n {rule.match.taskType && <div className=\"font-mono\">task: {rule.match.taskType}</div>}\n {rule.match.capability && <div className=\"font-mono\">cap: {rule.match.capability}</div>}\n </div>\n <div className=\"bg-card px-2 py-1.5\">\n <span className=\"font-medium\">{rule.target.provider}</span>\n {rule.target.model && <span className=\"text-muted-foreground\"> / {rule.target.model}</span>}\n {rule.target.effort && <span className=\"text-muted-foreground\"> ({rule.target.effort})</span>}\n </div>\n <div className=\"bg-card px-2 py-1.5\">\n {rule.enabled === false ? <span className=\"text-muted-foreground\">disabled</span> : <span className=\"text-emerald-500\">active</span>}\n </div>\n </div>\n ))}\n </div>\n )}\n\n {(bands || Object.keys(providerQuota).length > 0) && (\n <div className=\"rounded-md border border-border bg-muted/10 px-3 py-2 text-xs space-y-1\">\n {bands && (\n <div className=\"flex flex-wrap gap-x-4 gap-y-0.5\">\n {bands.cautionAt !== undefined && <span>caution ≥ {(bands.cautionAt * 100).toFixed(0)}%</span>}\n {bands.avoidLargeAt !== undefined && <span>avoid-large ≥ {(bands.avoidLargeAt * 100).toFixed(0)}%</span>}\n {bands.hardAvoidAt !== undefined && <span>hard-avoid ≥ {(bands.hardAvoidAt * 100).toFixed(0)}%</span>}\n </div>\n )}\n {Object.entries(providerQuota).map(([provider, cfg]) => (\n <div key={provider} className=\"flex flex-wrap gap-x-4 gap-y-0.5 text-muted-foreground\">\n <span className=\"font-medium text-foreground\">{getProviderLabel(provider)}</span>\n {cfg?.hardBackstopUtilization !== undefined && <span>backstop: {(cfg.hardBackstopUtilization * 100).toFixed(0)}%</span>}\n {cfg?.burnPenaltyUtilizationFloor !== undefined && <span>floor: {(cfg.burnPenaltyUtilizationFloor * 100).toFixed(0)}%</span>}\n </div>\n ))}\n </div>\n )}\n </div>\n )\n}\n\n// Instruction text is prose (markdown), not code — render it in the prose font with\n// relaxed line-height so it reads as prose, while `whitespace-pre-wrap` preserves the\n// author's exact line breaks. A capped, scrollable height keeps a long system prompt\n// from running the whole panel off-screen (#731).\nfunction InstructionBlock({ text, index }: { text: string; index?: number }) {\n return (\n <div className=\"relative max-h-72 overflow-y-auto rounded-md border border-border bg-muted/20\">\n {index !== undefined && (\n <span className=\"sticky top-0 float-right m-1.5 rounded bg-muted px-1.5 py-0.5 text-[9px] font-medium tabular-nums text-muted-foreground\">\n #{index}\n </span>\n )}\n <pre className=\"whitespace-pre-wrap break-words px-3 py-2.5 font-sans text-[11px] leading-relaxed text-foreground/90\">\n {text}\n </pre>\n </div>\n )\n}\n\nfunction CoordinatorProfileDisplay({ profile }: { profile: AgentProfile }) {\n return (\n <div className=\"space-y-2\">\n <div className=\"text-xs font-semibold text-muted-foreground uppercase tracking-wide\">\n Coordinator profile instructions\n <Badge variant=\"secondary\" className=\"ml-2 text-[10px]\">{profile.name}</Badge>\n {profile.builtIn && <Badge variant=\"outline\" className=\"ml-1 text-[10px]\">built-in</Badge>}\n </div>\n\n {profile.description && <p className=\"text-xs text-muted-foreground\">{profile.description}</p>}\n\n <div className=\"flex flex-wrap gap-2 text-[10px]\">\n <Badge variant=\"outline\">base: {profile.base}</Badge>\n <Badge variant=\"outline\">repo: {profile.instructions.repoInstructions}</Badge>\n <Badge variant=\"outline\">global: {profile.instructions.globalInstructions}</Badge>\n {profile.provider && <Badge variant=\"outline\">provider: {profile.provider}</Badge>}\n </div>\n\n {profile.instructions.system && (\n <div className=\"space-y-1\">\n <div className=\"text-[10px] font-medium text-muted-foreground uppercase tracking-wide\">System prompt</div>\n <InstructionBlock text={profile.instructions.system} />\n </div>\n )}\n\n {profile.instructions.append.length > 0 && (\n <div className=\"space-y-2\">\n <div className=\"text-[10px] font-medium text-muted-foreground uppercase tracking-wide\">\n Appended instructions ({profile.instructions.append.length})\n </div>\n {profile.instructions.append.map((block, i) => (\n <InstructionBlock key={i} text={block} index={i + 1} />\n ))}\n </div>\n )}\n\n {profile.instructions.append.length === 0 && !profile.instructions.system && (\n <div className=\"text-xs text-muted-foreground italic\">No instruction blocks defined.</div>\n )}\n </div>\n )\n}\n","import { useState } from 'react'\nimport type { RoutingPolicy, RoutingRule } from 'agent-relay-sdk/types'\nimport { api } from '@/lib/api'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Switch } from '@/components/ui/switch'\nimport { Badge } from '@/components/ui/badge'\nimport { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport {\n AlertCircle,\n ArrowDown,\n ArrowUp,\n Loader2,\n Plus,\n RefreshCw,\n Route,\n Save,\n Trash2,\n} from 'lucide-react'\nimport { cn } from '@/lib/utils'\nimport { getKnownProviderIds, getProviderLabel } from '@/lib/provider-display'\nimport { QuotaThresholdsEditor, CoordinatorVisibilityPanel } from './routing-coordinator-panel'\n\nconst PROVIDERS = getKnownProviderIds()\n\n// ─── types ───────────────────────────────────────────────────────────────────\n\ninterface RuleForm {\n label: string\n matchTaskType: string\n matchCapability: string\n targetProvider: string\n targetModel: string\n targetEffort: string\n enabled: boolean\n}\n\nfunction emptyRuleForm(): RuleForm {\n return { label: '', matchTaskType: '', matchCapability: '', targetProvider: PROVIDERS[0] ?? '', targetModel: '', targetEffort: '', enabled: true }\n}\n\nfunction ruleToForm(rule: RoutingRule): RuleForm {\n return {\n label: rule.label ?? '',\n matchTaskType: rule.match.taskType ?? '',\n matchCapability: rule.match.capability ?? '',\n targetProvider: rule.target.provider,\n targetModel: rule.target.model ?? '',\n targetEffort: rule.target.effort ?? '',\n enabled: rule.enabled !== false,\n }\n}\n\nfunction formToRule(form: RuleForm): RoutingRule {\n return {\n ...(form.label.trim() ? { label: form.label.trim() } : {}),\n match: {\n ...(form.matchTaskType.trim() ? { taskType: form.matchTaskType.trim() } : {}),\n ...(form.matchCapability.trim() ? { capability: form.matchCapability.trim() } : {}),\n },\n target: {\n provider: form.targetProvider,\n ...(form.targetModel.trim() ? { model: form.targetModel.trim() } : {}),\n ...(form.targetEffort.trim() ? { effort: form.targetEffort.trim() } : {}),\n },\n enabled: form.enabled,\n }\n}\n\nfunction validateRuleForm(form: RuleForm): string | null {\n if (!form.matchTaskType.trim() && !form.matchCapability.trim()) {\n return 'At least one match criterion (task type or capability) is required.'\n }\n return null\n}\n\nfunction ErrorBanner({ message }: { message: string }) {\n return (\n <div className=\"flex items-start gap-2 rounded-lg border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive\">\n <AlertCircle className=\"mt-0.5 size-4 shrink-0\" />\n <span>{message}</span>\n </div>\n )\n}\n\n// ─── RoutingSettings (root) ───────────────────────────────────────────────────\n\nexport function RoutingSettings({ canWrite }: { canWrite: boolean }) {\n const [policy, setPolicy] = useState<RoutingPolicy | null>(null)\n const [loading, setLoading] = useState(false)\n const [loadError, setLoadError] = useState('')\n const [loaded, setLoaded] = useState(false)\n\n if (!loaded && !loading && !loadError) {\n setLoading(true)\n void (async () => {\n try {\n const data = await api<RoutingPolicy>('GET', '/routing-policy')\n setPolicy(data)\n setLoaded(true)\n } catch (e) {\n setLoadError((e as Error).message)\n } finally {\n setLoading(false)\n }\n })()\n }\n\n async function reload() {\n setLoading(true)\n setLoadError('')\n try {\n const data = await api<RoutingPolicy>('GET', '/routing-policy')\n setPolicy(data)\n setLoaded(true)\n } catch (e) {\n setLoadError((e as Error).message)\n } finally {\n setLoading(false)\n }\n }\n\n return (\n <div className=\"space-y-6\">\n <div className=\"flex items-center justify-between gap-3\">\n <div>\n <h2 className=\"text-base font-semibold\">Routing</h2>\n <p className=\"text-sm text-muted-foreground\">\n Declarative rules mapping task types and capabilities to providers. Rules are advisory — coordinators apply\n them; explicit per-spawn arguments always take precedence.\n </p>\n </div>\n <Button variant=\"outline\" size=\"sm\" onClick={() => void reload()} disabled={loading}>\n <RefreshCw className={cn('size-4', loading && 'animate-spin')} />\n Refresh\n </Button>\n </div>\n\n {loadError && <ErrorBanner message={loadError} />}\n\n {loading && !policy && (\n <Card size=\"sm\">\n <CardContent className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <Loader2 className=\"size-4 animate-spin\" />\n Loading routing policy…\n </CardContent>\n </Card>\n )}\n\n {policy && (\n <>\n <RoutingRulesEditor policy={policy} canWrite={canWrite} onPolicy={setPolicy} />\n <QuotaThresholdsEditor policy={policy} canWrite={canWrite} onPolicy={setPolicy} />\n </>\n )}\n\n <CoordinatorVisibilityPanel />\n </div>\n )\n}\n\n// ─── RoutingRulesEditor ───────────────────────────────────────────────────────\n\nfunction RoutingRulesEditor({\n policy,\n canWrite,\n onPolicy,\n}: {\n policy: RoutingPolicy\n canWrite: boolean\n onPolicy: (p: RoutingPolicy) => void\n}) {\n const [saving, setSaving] = useState(false)\n const [saveError, setSaveError] = useState('')\n const [addOpen, setAddOpen] = useState(false)\n const [addForm, setAddForm] = useState<RuleForm>(emptyRuleForm)\n const [addError, setAddError] = useState('')\n const [editIdx, setEditIdx] = useState<number | null>(null)\n const [editForm, setEditForm] = useState<RuleForm>(emptyRuleForm)\n const [editError, setEditError] = useState('')\n\n async function putPolicy(next: RoutingPolicy) {\n setSaving(true)\n setSaveError('')\n try {\n const saved = await api<RoutingPolicy>('PUT', '/routing-policy', next)\n onPolicy(saved)\n } catch (e) {\n setSaveError((e as Error).message)\n } finally {\n setSaving(false)\n }\n }\n\n function move(idx: number, dir: -1 | 1) {\n const rules = [...policy.rules]\n const target = idx + dir\n if (target < 0 || target >= rules.length) return\n ;[rules[idx], rules[target]] = [rules[target]!, rules[idx]!]\n void putPolicy({ ...policy, rules })\n }\n\n function toggleEnabled(idx: number) {\n const rules = policy.rules.map((r, i) => (i === idx ? { ...r, enabled: r.enabled === false ? true : false } : r))\n void putPolicy({ ...policy, rules })\n }\n\n function removeRule(idx: number) {\n void putPolicy({ ...policy, rules: policy.rules.filter((_, i) => i !== idx) })\n }\n\n function startAdd() { setAddForm(emptyRuleForm()); setAddError(''); setAddOpen(true) }\n function cancelAdd() { setAddOpen(false); setAddError('') }\n\n function commitAdd() {\n const err = validateRuleForm(addForm)\n if (err) { setAddError(err); return }\n setAddOpen(false)\n void putPolicy({ ...policy, rules: [...policy.rules, formToRule(addForm)] })\n }\n\n function startEdit(idx: number) {\n setEditIdx(idx); setEditForm(ruleToForm(policy.rules[idx]!)); setEditError('')\n }\n\n function cancelEdit() { setEditIdx(null); setEditError('') }\n\n function commitEdit() {\n if (editIdx === null) return\n const err = validateRuleForm(editForm)\n if (err) { setEditError(err); return }\n const rules = policy.rules.map((r, i) => (i === editIdx ? formToRule(editForm) : r))\n setEditIdx(null)\n void putPolicy({ ...policy, rules })\n }\n\n return (\n <Card size=\"sm\">\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2 text-sm\">\n <Route className=\"size-4\" />\n Rules\n <Badge variant=\"outline\" className=\"ml-auto text-[10px]\">\n {policy.rules.length} rule{policy.rules.length === 1 ? '' : 's'}\n </Badge>\n {saving && <Loader2 className=\"size-3 animate-spin text-muted-foreground\" />}\n </CardTitle>\n <CardDescription className=\"text-xs\">\n Evaluated in order — first matching enabled rule wins. Rules are advisory; explicit spawn arguments override them.\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-2\">\n {saveError && <ErrorBanner message={saveError} />}\n\n {policy.rules.length === 0 && !addOpen && (\n <div className=\"rounded-md border border-dashed border-border py-6 text-center text-xs text-muted-foreground\">\n No rules — coordinators fall back to their own heuristics.\n </div>\n )}\n\n {policy.rules.map((rule, idx) =>\n editIdx === idx ? (\n <RuleEditForm key={idx} form={editForm} error={editError} onChange={setEditForm} onSave={commitEdit} onCancel={cancelEdit} />\n ) : (\n <RuleRow\n key={idx}\n rule={rule}\n idx={idx}\n total={policy.rules.length}\n canWrite={canWrite}\n saving={saving}\n onMoveUp={() => move(idx, -1)}\n onMoveDown={() => move(idx, 1)}\n onToggle={() => toggleEnabled(idx)}\n onEdit={() => startEdit(idx)}\n onRemove={() => removeRule(idx)}\n />\n ),\n )}\n\n {addOpen && (\n <RuleEditForm form={addForm} error={addError} onChange={setAddForm} onSave={commitAdd} onCancel={cancelAdd} isNew />\n )}\n\n {canWrite && !addOpen && editIdx === null && (\n <Button variant=\"outline\" size=\"sm\" className=\"w-full gap-1\" onClick={startAdd} disabled={saving}>\n <Plus className=\"size-4\" />\n Add rule\n </Button>\n )}\n </CardContent>\n </Card>\n )\n}\n\nfunction RuleRow({\n rule, idx, total, canWrite, saving,\n onMoveUp, onMoveDown, onToggle, onEdit, onRemove,\n}: {\n rule: RoutingRule\n idx: number\n total: number\n canWrite: boolean\n saving: boolean\n onMoveUp: () => void\n onMoveDown: () => void\n onToggle: () => void\n onEdit: () => void\n onRemove: () => void\n}) {\n const disabled = rule.enabled === false\n return (\n <div className={cn('group flex items-start gap-3 rounded-md border bg-muted/20 p-3', disabled && 'opacity-60')}>\n <div className=\"flex flex-col items-center gap-0.5 pt-0.5\">\n <button type=\"button\" title=\"Move up\" onClick={onMoveUp} disabled={!canWrite || saving || idx === 0}\n className=\"rounded p-0.5 text-muted-foreground hover:bg-accent hover:text-foreground disabled:pointer-events-none disabled:opacity-30\">\n <ArrowUp className=\"size-3.5\" />\n </button>\n <button type=\"button\" title=\"Move down\" onClick={onMoveDown} disabled={!canWrite || saving || idx === total - 1}\n className=\"rounded p-0.5 text-muted-foreground hover:bg-accent hover:text-foreground disabled:pointer-events-none disabled:opacity-30\">\n <ArrowDown className=\"size-3.5\" />\n </button>\n </div>\n\n <div className=\"min-w-0 flex-1 space-y-1\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-[10px] tabular-nums text-muted-foreground\">#{idx + 1}</span>\n {rule.label && <span className=\"text-xs font-medium\">{rule.label}</span>}\n <Badge variant=\"outline\" className=\"text-[10px]\">{rule.target.provider}</Badge>\n {rule.target.model && <Badge variant=\"outline\" className=\"text-[10px] font-mono\">{rule.target.model}</Badge>}\n {rule.target.effort && <Badge variant=\"outline\" className=\"text-[10px]\">{rule.target.effort}</Badge>}\n </div>\n <div className=\"flex flex-wrap gap-x-3 gap-y-0.5 text-[10px] text-muted-foreground\">\n {rule.match.taskType && <span>task-type: <span className=\"font-mono text-foreground\">{rule.match.taskType}</span></span>}\n {rule.match.capability && <span>capability: <span className=\"font-mono text-foreground\">{rule.match.capability}</span></span>}\n </div>\n </div>\n\n <div className=\"flex shrink-0 items-center gap-1 opacity-70 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100\">\n <Switch checked={rule.enabled !== false} disabled={!canWrite || saving} onCheckedChange={onToggle}\n title={rule.enabled === false ? 'Enable rule' : 'Disable rule'} />\n {canWrite && (\n <>\n <button type=\"button\" title=\"Edit\" onClick={onEdit} disabled={saving}\n className=\"rounded p-1 text-muted-foreground hover:bg-accent hover:text-foreground disabled:pointer-events-none\">\n <svg className=\"size-3.5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2}>\n <path d=\"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\" />\n <path d=\"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z\" />\n </svg>\n </button>\n <button type=\"button\" title=\"Remove\" onClick={onRemove} disabled={saving}\n className=\"rounded p-1 text-destructive hover:bg-destructive/10 disabled:pointer-events-none\">\n <Trash2 className=\"size-3.5\" />\n </button>\n </>\n )}\n </div>\n </div>\n )\n}\n\nfunction RuleEditForm({\n form, error, onChange, onSave, onCancel, isNew,\n}: {\n form: RuleForm\n error: string\n onChange: (f: RuleForm) => void\n onSave: () => void\n onCancel: () => void\n isNew?: boolean\n}) {\n function patch(p: Partial<RuleForm>) { onChange({ ...form, ...p }) }\n return (\n <div className=\"rounded-md border border-primary/30 bg-primary/5 p-3 space-y-3\">\n <div className=\"text-xs font-semibold text-muted-foreground uppercase tracking-wide\">{isNew ? 'New rule' : 'Edit rule'}</div>\n\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <label className=\"space-y-1\">\n <span className=\"text-[10px] font-medium text-muted-foreground\">Label (optional)</span>\n <Input value={form.label} onChange={(e) => patch({ label: e.target.value })}\n placeholder=\"e.g. Route GUI tasks to Claude\" className=\"h-8 text-xs\" />\n </label>\n <label className=\"space-y-1\">\n <span className=\"text-[10px] font-medium text-muted-foreground\">Target provider</span>\n <Select value={form.targetProvider} onValueChange={(v) => patch({ targetProvider: v })}>\n <SelectTrigger className=\"h-8 text-xs\"><SelectValue /></SelectTrigger>\n <SelectContent>\n {PROVIDERS.map((p) => <SelectItem key={p} value={p} className=\"text-xs\">{getProviderLabel(p)}</SelectItem>)}\n </SelectContent>\n </Select>\n </label>\n </div>\n\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <label className=\"space-y-1\">\n <span className=\"text-[10px] font-medium text-muted-foreground\">Match task-type (prefix)</span>\n <Input value={form.matchTaskType} onChange={(e) => patch({ matchTaskType: e.target.value })}\n placeholder=\"e.g. gui, backend, mechanical\" className=\"h-8 font-mono text-xs\" />\n <span className=\"block text-[10px] leading-snug text-muted-foreground\">\n Prefix match — <span className=\"font-mono text-foreground\">gui</span> matches <span className=\"font-mono text-foreground\">gui/ux</span>, <span className=\"font-mono text-foreground\">gui/layout</span>.\n </span>\n </label>\n <label className=\"space-y-1\">\n <span className=\"text-[10px] font-medium text-muted-foreground\">Match capability (exact)</span>\n <Input value={form.matchCapability} onChange={(e) => patch({ matchCapability: e.target.value })}\n placeholder=\"e.g. code, research, bounded\" className=\"h-8 font-mono text-xs\" />\n <span className=\"block text-[10px] leading-snug text-muted-foreground\">\n Exact match against the agent's capability tag. Both fields are AND-ed.\n </span>\n </label>\n </div>\n\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <label className=\"space-y-1\">\n <span className=\"text-[10px] font-medium text-muted-foreground\">Model alias (optional)</span>\n <Input value={form.targetModel} onChange={(e) => patch({ targetModel: e.target.value })}\n placeholder=\"e.g. opus, gpt-5.4\" className=\"h-8 font-mono text-xs\" />\n </label>\n <label className=\"space-y-1\">\n <span className=\"text-[10px] font-medium text-muted-foreground\">Effort (optional)</span>\n <Input value={form.targetEffort} onChange={(e) => patch({ targetEffort: e.target.value })}\n placeholder=\"e.g. high, low\" className=\"h-8 text-xs\" />\n </label>\n </div>\n\n <div className=\"flex items-center gap-2\">\n <Switch checked={form.enabled} onCheckedChange={(enabled) => patch({ enabled })} />\n <span className=\"text-xs text-muted-foreground\">Enabled</span>\n </div>\n\n {error && <ErrorBanner message={error} />}\n\n <div className=\"flex gap-2\">\n <Button size=\"sm\" onClick={onSave}>\n <Save className=\"size-4\" />\n {isNew ? 'Add' : 'Save'}\n </Button>\n <Button size=\"sm\" variant=\"outline\" onClick={onCancel}>Cancel</Button>\n </div>\n </div>\n )\n}\n","import { useEffect, useMemo, useRef, useState } from 'react'\nimport type { ProviderCatalogEntry } from 'agent-relay-sdk/provider-catalog'\nimport { api, apiUpload } from '@/lib/api'\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/components/ui/button'\nimport { Badge } from '@/components/ui/badge'\nimport { Card, CardContent } from '@/components/ui/card'\nimport { AlertCircle, Camera, Globe2, RefreshCw, Route, Save, Trash2, Upload } from 'lucide-react'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport { Textarea } from '@/components/ui/textarea'\nimport { BrowserSettings } from '@/components/settings/browser-settings'\nimport { ModelCatalogSettings } from '@/components/settings/model-catalog-settings'\nimport { QuotaSettings } from '@/components/settings/quota-settings'\nimport { RoutingSettings } from '@/components/settings/routing-settings'\nimport { SchemaGroup } from '@/components/settings/schema-form'\nimport { UserAvatar } from '@/components/shared/user-avatar'\nimport { useRelayStore } from '@/store'\nimport {\n groupSettings,\n hasScope,\n settingId,\n type SettingEntry,\n} from '@/components/settings/schema-utils'\nimport type { Artifact, NotificationRoutingPreview, User } from '@/types'\n\ninterface SettingsResponse {\n settings: SettingEntry[]\n}\n\ninterface TokenMe {\n actor: string\n kind: string\n role?: string\n scopes: string[]\n}\n\ninterface ProvidersResponse {\n catalog: ProviderCatalogEntry[]\n}\n\ninterface NotificationPreviewResponse {\n preview: NotificationRoutingPreview\n}\n\nconst BROWSER_GROUP_SLUG = 'browser'\nconst MODELS_GROUP_SLUG = 'models'\nconst PROFILE_GROUP_SLUG = 'profile'\nconst ROUTING_GROUP_SLUG = 'routing'\nconst NOTIFICATION_TYPES = [\n 'branch.landed',\n 'landed-failure',\n 'agent.ready',\n 'agent.exited',\n 'agent.spawn_failed',\n 'agent.context_threshold',\n 'agent.quota_threshold',\n 'workspace.steward_task',\n 'workspace.conflict',\n 'workspace.review_request',\n]\n\nfunction settingsHash(): string {\n if (typeof window === 'undefined') return ''\n const hash = window.location.hash.replace(/^#/, '')\n if (!hash.startsWith('settings/')) return ''\n return decodeURIComponent(hash.slice('settings/'.length))\n}\n\nfunction writeSettingsHash(slug: string): void {\n if (typeof window === 'undefined') return\n const url = new URL(window.location.href)\n url.hash = `settings/${encodeURIComponent(slug)}`\n window.history.pushState({}, '', url)\n}\n\nexport function SettingsView() {\n const [settings, setSettings] = useState<SettingEntry[]>([])\n const [token, setToken] = useState<TokenMe | null>(null)\n const [catalog, setCatalog] = useState<ProviderCatalogEntry[]>([])\n const [active, setActive] = useState(() => settingsHash())\n const [loading, setLoading] = useState(true)\n const [loadError, setLoadError] = useState('')\n const [catalogError, setCatalogError] = useState('')\n\n async function reload() {\n setLoading(true)\n setLoadError('')\n setCatalogError('')\n try {\n const [settingsRes, tokenRes, providersRes] = await Promise.all([\n api<SettingsResponse>('GET', '/settings'),\n api<TokenMe>('GET', '/tokens/me'),\n api<ProvidersResponse>('GET', '/providers').catch((e) => {\n setCatalogError((e as Error).message)\n return { catalog: [] }\n }),\n ])\n setSettings(settingsRes.settings)\n setToken(tokenRes)\n setCatalog(providersRes.catalog)\n } catch (e) {\n setLoadError((e as Error).message)\n } finally {\n setLoading(false)\n }\n }\n\n useEffect(() => {\n void reload()\n }, [])\n\n // External sync: keep the selected settings group aligned with browser history.\n useEffect(() => {\n const sync = () => setActive(settingsHash())\n window.addEventListener('hashchange', sync)\n window.addEventListener('popstate', sync)\n return () => {\n window.removeEventListener('hashchange', sync)\n window.removeEventListener('popstate', sync)\n }\n }, [])\n\n const descriptorGroups = useMemo(() => groupSettings(settings), [settings])\n const groups = useMemo(() => [\n ...descriptorGroups.map((group) => ({\n slug: group.slug,\n label: group.group,\n description: `${group.settings.length} schema setting${group.settings.length === 1 ? '' : 's'}`,\n kind: 'descriptors' as const,\n settings: group.settings,\n })),\n {\n slug: ROUTING_GROUP_SLUG,\n label: 'Routing',\n description: 'Rules, quota thresholds, coordinator view',\n kind: 'routing' as const,\n settings: [],\n },\n {\n slug: PROFILE_GROUP_SLUG,\n label: 'Profile',\n description: 'Display name and avatar',\n kind: 'profile' as const,\n settings: [],\n },\n {\n slug: BROWSER_GROUP_SLUG,\n label: 'Browser',\n description: 'Local dashboard preferences',\n kind: 'browser' as const,\n settings: [],\n },\n {\n slug: MODELS_GROUP_SLUG,\n label: 'Models',\n description: 'Provider model catalog',\n kind: 'models' as const,\n settings: [],\n },\n ], [descriptorGroups])\n\n const activeGroup = groups.find((group) => group.slug === active) ?? groups[0]\n\n function selectGroup(slug: string) {\n setActive(slug)\n writeSettingsHash(slug)\n }\n\n function replaceSetting(updated: SettingEntry) {\n setSettings((current) => current.map((entry) => settingId(entry) === settingId(updated) ? updated : entry))\n }\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div>\n <h1 className=\"text-lg font-semibold\">Settings</h1>\n <p className=\"text-sm text-muted-foreground\">Schema-driven Relay settings, browser preferences, and model catalog controls.</p>\n </div>\n <div className=\"flex flex-wrap items-center gap-2\">\n {token && (\n <Badge variant=\"outline\" className=\"gap-1\">\n <Globe2 className=\"size-3\" />\n {token.kind}:{token.actor}\n </Badge>\n )}\n <Button variant=\"outline\" size=\"sm\" onClick={() => void reload()} disabled={loading}>\n <RefreshCw className={cn('size-4', loading && 'animate-spin')} />\n Refresh\n </Button>\n </div>\n </div>\n\n {loadError && (\n <div className=\"flex items-start gap-2 rounded-lg border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive\">\n <AlertCircle className=\"mt-0.5 size-4\" />\n <span>{loadError}</span>\n </div>\n )}\n\n <div className=\"grid gap-4 lg:grid-cols-[230px_minmax(0,1fr)]\">\n <nav className=\"space-y-1 lg:sticky lg:top-4 lg:self-start\">\n {groups.map((group) => (\n <button\n key={group.slug}\n type=\"button\"\n className={cn(\n 'w-full rounded-md border px-3 py-2 text-left text-sm transition-colors',\n activeGroup?.slug === group.slug ? 'border-primary/50 bg-primary/10 text-foreground' : 'border-transparent hover:border-border hover:bg-accent',\n )}\n onClick={() => selectGroup(group.slug)}\n >\n <span className=\"block font-medium\">{group.label}</span>\n <span className=\"block truncate text-xs text-muted-foreground\">{group.description}</span>\n </button>\n ))}\n </nav>\n\n <div className=\"min-w-0 space-y-4\">\n {loading && !settings.length ? (\n <Card size=\"sm\">\n <CardContent className=\"text-sm text-muted-foreground\">Loading settings…</CardContent>\n </Card>\n ) : activeGroup?.kind === 'routing' ? (\n <RoutingSettings canWrite={hasScope(token?.scopes, 'settings:write:routing')} />\n ) : activeGroup?.kind === 'descriptors' ? (\n <>\n <SchemaGroup\n group={activeGroup.label}\n settings={activeGroup.settings}\n onSaved={replaceSetting}\n />\n {/* Quota config block lives under the Providers group (#605). */}\n {activeGroup.label === 'Providers' && (\n <QuotaSettings canWrite={hasScope(token?.scopes, 'settings:write:provider')} />\n )}\n {activeGroup.label === 'Notifications' && (\n <NotificationRoutingPreviewPanel />\n )}\n </>\n ) : activeGroup?.kind === 'profile' ? (\n <ProfileSettings />\n ) : activeGroup?.kind === 'browser' ? (\n <BrowserSettings />\n ) : (\n <ModelCatalogSettings\n catalog={catalog}\n error={catalogError}\n canWrite={hasScope(token?.scopes, 'settings:write:provider')}\n onCatalog={setCatalog}\n />\n )}\n </div>\n </div>\n </div>\n )\n}\n\nfunction NotificationRoutingPreviewPanel() {\n const [type, setType] = useState('branch.landed')\n const [scopeText, setScopeText] = useState('{\\n \"repoRoot\": \"/repo\"\\n}')\n const [preview, setPreview] = useState<NotificationRoutingPreview | null>(null)\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState('')\n\n async function runPreview() {\n setLoading(true)\n setError('')\n try {\n const scope = JSON.parse(scopeText) as unknown\n if (!scope || typeof scope !== 'object' || Array.isArray(scope)) throw new Error('Scope must be a JSON object')\n const result = await api<NotificationPreviewResponse>('POST', '/notifications/preview', { type, scope })\n setPreview(result.preview)\n } catch (e) {\n setPreview(null)\n setError((e as Error).message)\n } finally {\n setLoading(false)\n }\n }\n\n return (\n <Card size=\"sm\">\n <CardContent className=\"space-y-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <div>\n <h2 className=\"text-sm font-semibold\">Who gets what</h2>\n <p className=\"text-xs text-muted-foreground\">Dry-run notification routing without sending.</p>\n </div>\n <Button size=\"sm\" onClick={() => void runPreview()} disabled={loading}>\n <Route className=\"size-4\" />\n Preview\n </Button>\n </div>\n <div className=\"grid gap-3 md:grid-cols-[240px_minmax(0,1fr)]\">\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium text-muted-foreground\">Type</label>\n <Select value={type} onValueChange={setType}>\n <SelectTrigger className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {NOTIFICATION_TYPES.map((item) => <SelectItem key={item} value={item}>{item}</SelectItem>)}\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium text-muted-foreground\">Scope</label>\n <Textarea value={scopeText} onChange={(e) => setScopeText(e.target.value)} rows={4} className=\"font-mono text-xs\" />\n </div>\n </div>\n {error && (\n <div className=\"flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/10 p-2 text-xs text-destructive\">\n <AlertCircle className=\"mt-0.5 size-3.5\" />\n <span>{error}</span>\n </div>\n )}\n {preview && (\n <div className=\"overflow-hidden rounded-md border border-border\">\n {preview.recipients.length === 0 ? (\n <div className=\"px-3 py-4 text-center text-xs text-muted-foreground\">No recipients</div>\n ) : preview.recipients.map((recipient) => (\n <div key={`${recipient.recipient}-${recipient.matchedRule}`} className=\"grid gap-1 border-b border-border px-3 py-2 text-xs last:border-b-0 md:grid-cols-[minmax(0,180px)_minmax(0,160px)_minmax(0,1fr)]\">\n <span className=\"truncate font-medium\">{recipient.recipient}</span>\n <span className=\"truncate font-mono text-muted-foreground\">{recipient.matchedRule}</span>\n <span className=\"truncate text-muted-foreground\">{recipient.reason}</span>\n </div>\n ))}\n </div>\n )}\n </CardContent>\n </Card>\n )\n}\n\nfunction ProfileSettings() {\n const fetchUsers = useRelayStore((s) => s.fetchUsers)\n const fileRef = useRef<HTMLInputElement>(null)\n const [user, setUser] = useState<User | null>(null)\n const [displayName, setDisplayName] = useState('')\n const [loading, setLoading] = useState(true)\n const [saving, setSaving] = useState(false)\n const [error, setError] = useState('')\n\n async function loadProfile() {\n setLoading(true)\n setError('')\n try {\n const next = await api<User>('GET', '/users/me')\n setUser(next)\n setDisplayName(next.displayName || next.handle)\n } catch (e) {\n setError((e as Error).message)\n } finally {\n setLoading(false)\n }\n }\n\n useEffect(() => {\n void loadProfile()\n }, [])\n\n async function saveProfile() {\n setSaving(true)\n setError('')\n try {\n const next = await api<User>('PATCH', '/users/me', { displayName })\n setUser(next)\n setDisplayName(next.displayName || next.handle)\n await fetchUsers()\n } catch (e) {\n setError((e as Error).message)\n } finally {\n setSaving(false)\n }\n }\n\n async function uploadAvatar(file: File | undefined) {\n if (!file) return\n setSaving(true)\n setError('')\n try {\n const res = await apiUpload<{ user: User; artifact: Artifact }>('/users/me/avatar', file)\n setUser(res.user)\n setDisplayName(res.user.displayName || res.user.handle)\n await fetchUsers()\n } catch (e) {\n setError((e as Error).message)\n } finally {\n setSaving(false)\n if (fileRef.current) fileRef.current.value = ''\n }\n }\n\n async function removeAvatar() {\n setSaving(true)\n setError('')\n try {\n const next = await api<User>('DELETE', '/users/me/avatar')\n setUser(next)\n await fetchUsers()\n } catch (e) {\n setError((e as Error).message)\n } finally {\n setSaving(false)\n }\n }\n\n return (\n <Card size=\"sm\">\n <CardContent className=\"space-y-4\">\n {error && (\n <div className=\"flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive\">\n <AlertCircle className=\"mt-0.5 size-4\" />\n <span>{error}</span>\n </div>\n )}\n <div className=\"flex flex-wrap items-center gap-4\">\n <UserAvatar user={user ?? undefined} distinct className=\"size-16 text-lg\" />\n <div className=\"min-w-0 flex-1 space-y-2\">\n <label className=\"block text-xs font-medium text-muted-foreground\" htmlFor=\"profile-display-name\">Display name</label>\n <input\n id=\"profile-display-name\"\n className=\"h-9 w-full rounded-md border border-input bg-background px-3 text-sm\"\n value={displayName}\n onChange={(e) => setDisplayName(e.target.value)}\n disabled={loading || saving}\n maxLength={120}\n />\n </div>\n </div>\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button size=\"sm\" onClick={() => void saveProfile()} disabled={loading || saving || !displayName.trim()}>\n <Save className=\"size-4\" />\n Save\n </Button>\n <Button size=\"sm\" variant=\"outline\" onClick={() => fileRef.current?.click()} disabled={loading || saving}>\n <Upload className=\"size-4\" />\n Upload\n </Button>\n <Button size=\"sm\" variant=\"outline\" onClick={() => void removeAvatar()} disabled={loading || saving || !user?.avatarArtifactId}>\n <Trash2 className=\"size-4\" />\n Remove\n </Button>\n {saving && <Camera className=\"size-4 animate-pulse text-muted-foreground\" />}\n <input\n ref={fileRef}\n type=\"file\"\n accept=\"image/png,image/jpeg,image/gif,image/webp\"\n className=\"hidden\"\n onChange={(e) => void uploadAvatar(e.target.files?.[0])}\n />\n </div>\n </CardContent>\n </Card>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"settings-D3_r5IGA.js","names":[],"sources":["../../dashboard/src/components/settings/schema-utils.ts","../../dashboard/src/components/settings/schema-form.tsx","../../dashboard/src/components/settings/browser-settings.tsx","../../dashboard/src/components/settings/model-catalog-settings.tsx","../../dashboard/src/components/settings/quota-settings.tsx","../../dashboard/src/components/settings/routing-coordinator-panel.tsx","../../dashboard/src/components/settings/routing-settings.tsx","../../dashboard/src/components/views/settings.tsx"],"sourcesContent":["import { isRecord, type JSONSchema, type SettingEntry } from 'agent-relay-sdk/types'\n\nexport { hasScope } from 'agent-relay-sdk/types'\nexport type { SettingEntry }\n\ninterface SettingGroup {\n group: string\n slug: string\n settings: SettingEntry[]\n}\n\nexport type Path = Array<string | number>\n\nexport function settingId(setting: Pick<SettingEntry, 'namespace' | 'key'>): string {\n return `${setting.namespace}/${setting.key}`\n}\n\nexport function settingPath(setting: Pick<SettingEntry, 'namespace' | 'key'>): string {\n return `/settings/${encodeURIComponent(setting.namespace)}/${encodeURIComponent(setting.key)}`\n}\n\nexport function slugify(value: string): string {\n return value.trim().toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '') || 'settings'\n}\n\nexport function groupSettings(settings: SettingEntry[]): SettingGroup[] {\n const groups = new Map<string, SettingEntry[]>()\n for (const setting of settings.filter((entry) => entry.readable)) {\n const group = setting.display?.group?.trim() || setting.namespace\n groups.set(group, [...(groups.get(group) ?? []), setting])\n }\n return [...groups.entries()]\n .map(([group, items]) => ({\n group,\n slug: slugify(group),\n settings: items.sort(compareSettings),\n }))\n .sort((a, b) => groupOrder(a.settings) - groupOrder(b.settings) || a.group.localeCompare(b.group))\n}\n\nfunction compareSettings(a: SettingEntry, b: SettingEntry): number {\n return (a.display?.order ?? Number.MAX_SAFE_INTEGER) - (b.display?.order ?? Number.MAX_SAFE_INTEGER)\n || a.display?.label?.localeCompare(b.display?.label ?? '') || 0\n || settingId(a).localeCompare(settingId(b))\n}\n\nfunction groupOrder(settings: SettingEntry[]): number {\n return Math.min(...settings.map((setting) => setting.display?.order ?? Number.MAX_SAFE_INTEGER))\n}\n\nexport function schemaType(schema: JSONSchema): string | undefined {\n return Array.isArray(schema.type) ? schema.type.find((type) => type !== 'null') : schema.type\n}\n\nexport function valueAtPath(value: unknown, path: Path): unknown {\n let current = value\n for (const part of path) {\n if (typeof part === 'number') {\n if (!Array.isArray(current)) return undefined\n current = current[part]\n } else {\n if (!isRecord(current)) return undefined\n current = current[part]\n }\n }\n return current\n}\n\nexport function setValueAtPath(value: unknown, path: Path, next: unknown): unknown {\n if (!path.length) return next\n const [head, ...tail] = path\n if (head === undefined) return next\n if (typeof head === 'number') {\n const array = Array.isArray(value) ? [...value] : []\n array[head] = setValueAtPath(array[head], tail, next)\n return array\n }\n const record = isRecord(value) ? { ...value } : {}\n const updated = setValueAtPath(record[head], tail, next)\n if (updated === undefined) delete record[head]\n else record[head] = updated\n return record\n}\n\nexport function defaultValueForSchema(schema: JSONSchema): unknown {\n if (schema.default !== undefined) return schema.default\n if (schema.const !== undefined) return schema.const\n if (schema.enum?.length) return schema.enum[0]\n switch (schemaType(schema)) {\n case 'boolean': return false\n case 'integer':\n case 'number': return 0\n case 'array': return []\n case 'object': return {}\n case 'string': return ''\n default: return undefined\n }\n}\n\nexport function lines(value: string): string[] {\n return value.split(/\\r?\\n|,/).map((line) => line.trim()).filter(Boolean)\n}\n\nexport function arrayText(value: unknown): string {\n return Array.isArray(value) ? value.map((item) => String(item)).join('\\n') : ''\n}\n\nexport function recordText(value: unknown): string {\n if (!isRecord(value)) return ''\n return Object.entries(value).map(([key, item]) => `${key}=${String(item ?? '')}`).join('\\n')\n}\n\nexport function parseRecordText(value: string): Record<string, string> {\n return Object.fromEntries(value.split(/\\r?\\n/).map((raw) => raw.trim()).filter(Boolean).map((line) => {\n const idx = line.indexOf('=')\n return idx >= 0 ? [line.slice(0, idx).trim(), line.slice(idx + 1)] : [line, '']\n }))\n}\n\nexport { isRecord }\n","import { useState, type ReactNode } from 'react'\nimport type { JSONSchema, SettingTier } from 'agent-relay-sdk/types'\nimport { api, type ApiError } from '@/lib/api'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Textarea } from '@/components/ui/textarea'\nimport { Switch } from '@/components/ui/switch'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport { Badge } from '@/components/ui/badge'\nimport { Card, CardAction, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'\nimport { AlertCircle, CheckCircle2, MonitorCog, Save, ServerCog } from 'lucide-react'\nimport {\n arrayText,\n defaultValueForSchema,\n isRecord,\n lines,\n parseRecordText,\n recordText,\n schemaType,\n setValueAtPath,\n settingId,\n settingPath,\n type Path,\n type SettingEntry,\n} from './schema-utils'\n\nexport const UNSET = '__unset__'\n\nfunction tierLabel(tier: SettingTier): string {\n if (tier === 'server-runtime') return 'Server runtime'\n if (tier === 'bootstrap') return 'Bootstrap'\n return 'Browser'\n}\n\nfunction tierDescription(tier: SettingTier): string {\n if (tier === 'server-runtime') return 'Stored by Relay and mutable while the server is running.'\n if (tier === 'bootstrap') return 'Read from startup configuration; restart or host config changes are required.'\n return 'Stored only in this browser profile.'\n}\n\nfunction tierIcon(tier: SettingTier) {\n if (tier === 'browser') return <MonitorCog className=\"size-3.5\" />\n return <ServerCog className=\"size-3.5\" />\n}\n\nexport function errorDetails(error: unknown): string[] {\n return (error as ApiError).details ?? []\n}\n\nexport function SchemaGroup({ group, settings, onSaved }: { group: string; settings: SettingEntry[]; onSaved: (setting: SettingEntry) => void }) {\n const tiers = [...new Set(settings.map((setting) => setting.tier))]\n return (\n <section className=\"space-y-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <h2 className=\"text-base font-semibold\">{group}</h2>\n <div className=\"flex flex-wrap gap-1\">\n {tiers.map((tier) => (\n <Badge key={tier} variant=\"outline\" className=\"gap-1\" title={tierDescription(tier)}>\n {tierIcon(tier)}\n {tierLabel(tier)}\n </Badge>\n ))}\n </div>\n </div>\n {settings.length === 0 ? (\n <Card size=\"sm\">\n <CardContent className=\"text-sm text-muted-foreground\">No settings in this group.</CardContent>\n </Card>\n ) : (\n <div className=\"space-y-3\">\n {settings.map((setting) => (\n <SettingCard key={settingId(setting)} setting={setting} onSaved={onSaved} />\n ))}\n </div>\n )}\n </section>\n )\n}\n\nfunction SettingCard({ setting, onSaved }: { setting: SettingEntry; onSaved: (setting: SettingEntry) => void }) {\n const [draft, setDraft] = useState<unknown>(() => setting.value ?? setting.defaults ?? defaultValueForSchema(setting.schema))\n const [saving, setSaving] = useState(false)\n const [status, setStatus] = useState('')\n const [errors, setErrors] = useState<string[]>([])\n const isWritable = setting.writable && setting.tier === 'server-runtime'\n\n function update(path: Path, value: unknown) {\n setDraft((current: unknown) => setValueAtPath(current, path, value))\n setErrors([])\n setStatus('')\n }\n\n async function save() {\n if (!isWritable) return\n setSaving(true)\n setErrors([])\n setStatus('')\n try {\n const saved = await api<SettingEntry>('PUT', settingPath(setting), { value: draft, updatedBy: 'dashboard' })\n setDraft(saved.value)\n onSaved(saved)\n setStatus('Saved')\n } catch (e) {\n const details = errorDetails(e)\n setErrors(details.length ? details : [(e as Error).message])\n } finally {\n setSaving(false)\n }\n }\n\n return (\n <Card size=\"sm\">\n <CardHeader>\n <CardTitle className=\"flex flex-wrap items-center gap-2 text-sm\">\n {setting.display.label}\n <Badge variant=\"outline\" className=\"gap-1\" title={tierDescription(setting.tier)}>{tierIcon(setting.tier)}{tierLabel(setting.tier)}</Badge>\n {!setting.writable && <Badge variant=\"secondary\">Read only</Badge>}\n </CardTitle>\n {setting.display.description && <CardDescription>{setting.display.description}</CardDescription>}\n <CardAction>\n <Button size=\"sm\" onClick={save} disabled={!isWritable || saving}>\n <Save className=\"size-4\" />\n {saving ? 'Saving' : 'Save'}\n </Button>\n </CardAction>\n </CardHeader>\n\n <CardContent className=\"space-y-3\">\n <SchemaField\n schema={setting.schema}\n value={draft}\n path={[]}\n label={setting.display.label}\n required\n disabled={!isWritable || saving}\n onChange={update}\n />\n\n <p className=\"flex flex-wrap items-center gap-x-2 text-[11px] text-muted-foreground\">\n <code className=\"rounded bg-muted px-1.5 py-0.5 font-mono\">{setting.namespace}/{setting.key}</code>\n <span>read <span className=\"text-foreground/70\">{setting.scope.read}</span></span>\n <span aria-hidden>·</span>\n <span>write <span className=\"text-foreground/70\">{setting.scope.write}</span></span>\n </p>\n\n {errors.length > 0 && (\n <div className=\"rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive\">\n <div className=\"mb-1 flex items-center gap-2 font-medium\"><AlertCircle className=\"size-4\" />Save failed</div>\n <ul className=\"list-disc space-y-1 pl-5\">\n {errors.map((detail) => <li key={detail}>{detail}</li>)}\n </ul>\n </div>\n )}\n {status && <p className=\"flex items-center gap-1 text-sm text-emerald-500\"><CheckCircle2 className=\"size-4\" />{status}</p>}\n </CardContent>\n </Card>\n )\n}\n\nfunction SchemaField(props: {\n schema: JSONSchema\n value: unknown\n path: Path\n label: string\n required: boolean\n disabled: boolean\n onChange: (path: Path, value: unknown) => void\n}) {\n const { schema, value, path, label, required, disabled, onChange } = props\n const type = schemaType(schema)\n\n if (schema.enum?.length) {\n const current = value === undefined || value === null || value === '' ? UNSET : String(value)\n return (\n <Field label={label} description={schema.description}>\n <Select value={current} onValueChange={(next) => onChange(path, next === UNSET ? undefined : next)} disabled={disabled}>\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n {!required && <SelectItem value={UNSET}>Not set</SelectItem>}\n {schema.enum.map((item) => <SelectItem key={String(item)} value={String(item)}>{String(item)}</SelectItem>)}\n </SelectContent>\n </Select>\n </Field>\n )\n }\n\n if (type === 'boolean') {\n return (\n <div className=\"flex items-center justify-between gap-3 rounded-md border bg-muted/20 p-3\">\n <div>\n <div className=\"text-sm font-medium\">{label}</div>\n {schema.description && <div className=\"text-xs text-muted-foreground\">{schema.description}</div>}\n </div>\n <Switch checked={Boolean(value)} onCheckedChange={(next) => onChange(path, next)} disabled={disabled} />\n </div>\n )\n }\n\n if (type === 'integer' || type === 'number') {\n return (\n <Field label={label} description={schema.description}>\n <Input\n type=\"number\"\n min={typeof schema.minimum === 'number' ? schema.minimum : undefined}\n max={typeof schema.maximum === 'number' ? schema.maximum : undefined}\n step={type === 'integer' ? 1 : 'any'}\n value={typeof value === 'number' ? value : ''}\n disabled={disabled}\n onChange={(e) => onChange(path, e.target.value === '' && !required ? undefined : Number(e.target.value))}\n />\n </Field>\n )\n }\n\n if (type === 'array') {\n return (\n <Field label={label} description={schema.description ?? 'One item per line.'}>\n <Textarea\n rows={Math.min(8, Math.max(3, Array.isArray(value) ? value.length + 1 : 3))}\n value={arrayText(value)}\n disabled={disabled}\n onChange={(e) => onChange(path, lines(e.target.value))}\n />\n </Field>\n )\n }\n\n if (type === 'object') {\n const properties = schema.properties ?? {}\n const requiredKeys = new Set(schema.required ?? [])\n if (Object.keys(properties).length === 0 && schema.additionalProperties) {\n return (\n <Field label={label} description={schema.description ?? 'KEY=value, one entry per line.'}>\n <Textarea rows={5} value={recordText(value)} disabled={disabled} onChange={(e) => onChange(path, parseRecordText(e.target.value))} />\n </Field>\n )\n }\n return (\n <div className=\"space-y-3\">\n {path.length > 0 && (\n <div>\n <div className=\"text-sm font-medium\">{label}</div>\n {schema.description && <div className=\"text-xs text-muted-foreground\">{schema.description}</div>}\n </div>\n )}\n <div className=\"grid gap-3 md:grid-cols-2\">\n {Object.entries(properties).map(([key, child]) => {\n const childValue = isRecord(value) ? value[key] : undefined\n return (\n <SchemaField\n key={key}\n schema={child}\n value={childValue === undefined && requiredKeys.has(key) ? defaultValueForSchema(child) : childValue}\n path={[...path, key]}\n label={child.title || labelForKey(key)}\n required={requiredKeys.has(key)}\n disabled={disabled}\n onChange={onChange}\n />\n )\n })}\n </div>\n </div>\n )\n }\n\n return (\n <Field label={label} description={schema.description}>\n <Input\n value={typeof value === 'string' ? value : value == null ? '' : String(value)}\n disabled={disabled}\n onChange={(e) => onChange(path, e.target.value === '' && !required ? undefined : e.target.value)}\n />\n </Field>\n )\n}\n\nexport function Field({ label, description, children }: { label: string; description?: string; children: ReactNode }) {\n return (\n <label className=\"block space-y-1.5 text-sm\">\n <span className=\"text-muted-foreground\">{label}</span>\n {children}\n {description && <span className=\"block text-xs text-muted-foreground\">{description}</span>}\n </label>\n )\n}\n\nfunction labelForKey(key: string): string {\n return key.replace(/([a-z0-9])([A-Z])/g, '$1 $2').replace(/[-_]+/g, ' ').replace(/^\\w/, (char) => char.toUpperCase())\n}\n","import { useEffect, useState } from 'react'\nimport { THEMES } from '@/lib/themes'\nimport { KOKORO_VOICES, availableSpeechVoices } from '@/lib/voice'\nimport { useRelayStore } from '@/store'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport { Switch } from '@/components/ui/switch'\nimport { Badge } from '@/components/ui/badge'\nimport { Card, CardAction, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'\nimport { Brain, MonitorCog, Volume2 } from 'lucide-react'\nimport type { ThemeId } from '@/types'\nimport { Field, UNSET } from './schema-form'\n\nexport function BrowserSettings() {\n const theme = useRelayStore((s) => s.theme)\n const showReasoning = useRelayStore((s) => s.showReasoning)\n const set = useRelayStore((s) => s.set)\n return (\n <section className=\"space-y-4\">\n <div>\n <h2 className=\"text-base font-semibold\">Browser preferences</h2>\n <p className=\"text-sm text-muted-foreground\">These are stored in local dashboard state, not in Relay server config.</p>\n </div>\n <Card size=\"sm\">\n <CardHeader>\n <CardTitle className=\"text-sm\">Dashboard display</CardTitle>\n <CardDescription className=\"text-xs\">Browser tier · persisted in this browser profile.</CardDescription>\n <CardAction>\n <Badge variant=\"outline\" className=\"gap-1\"><MonitorCog className=\"size-3.5\" />Browser</Badge>\n </CardAction>\n </CardHeader>\n <CardContent className=\"grid gap-3 md:grid-cols-2\">\n <Field label=\"Theme\">\n <Select value={theme} onValueChange={(value) => set({ theme: value as ThemeId })}>\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n {THEMES.map((item) => <SelectItem key={item.id} value={item.id}>{item.label}</SelectItem>)}\n </SelectContent>\n </Select>\n </Field>\n <div className=\"flex items-center justify-between gap-3 rounded-md border bg-muted/20 p-3\">\n <div className=\"flex items-center gap-2\">\n <Brain className=\"size-4\" />\n <div>\n <div className=\"text-sm font-medium\">Show reasoning details</div>\n <div className=\"text-xs text-muted-foreground\">Display captured reasoning/tool steps in chat. Server capture is controlled separately by provider reasoningCapture.</div>\n </div>\n </div>\n <Switch checked={showReasoning} onCheckedChange={(value) => set({ showReasoning: value })} />\n </div>\n </CardContent>\n </Card>\n <VoiceSettings />\n </section>\n )\n}\n\nfunction VoiceSettings() {\n const voiceTtsEnabled = useRelayStore((s) => s.voiceTtsEnabled)\n const setVoiceTtsEnabled = useRelayStore((s) => s.setVoiceTtsEnabled)\n const voiceTtsMode = useRelayStore((s) => s.voiceTtsMode)\n const setVoiceTtsMode = useRelayStore((s) => s.setVoiceTtsMode)\n const voiceTtsKokoroVoice = useRelayStore((s) => s.voiceTtsKokoroVoice)\n const setVoiceTtsKokoroVoice = useRelayStore((s) => s.setVoiceTtsKokoroVoice)\n const voiceTtsBrowserVoice = useRelayStore((s) => s.voiceTtsBrowserVoice)\n const setVoiceTtsBrowserVoice = useRelayStore((s) => s.setVoiceTtsBrowserVoice)\n const voiceInputMode = useRelayStore((s) => s.voiceInputMode)\n const setVoiceInputMode = useRelayStore((s) => s.setVoiceInputMode)\n\n // External sync: the browser loads speech voices asynchronously.\n const [browserVoices, setBrowserVoices] = useState(() => availableSpeechVoices())\n useEffect(() => {\n if (typeof window === 'undefined' || !('speechSynthesis' in window)) return\n const refresh = () => setBrowserVoices(availableSpeechVoices())\n refresh()\n window.speechSynthesis.addEventListener?.('voiceschanged', refresh)\n return () => window.speechSynthesis.removeEventListener?.('voiceschanged', refresh)\n }, [])\n\n const kokoroOptions = KOKORO_VOICES.some((voice) => voice.id === voiceTtsKokoroVoice)\n ? KOKORO_VOICES\n : [...KOKORO_VOICES, { id: voiceTtsKokoroVoice, label: voiceTtsKokoroVoice }]\n\n return (\n <Card size=\"sm\">\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2 text-sm\"><Volume2 className=\"size-4\" />Voice</CardTitle>\n <CardDescription className=\"text-xs\">Browser tier TTS and push-to-talk behavior.</CardDescription>\n <CardAction>\n <Switch checked={voiceTtsEnabled} onCheckedChange={setVoiceTtsEnabled} />\n </CardAction>\n </CardHeader>\n <CardContent className=\"grid gap-3 md:grid-cols-2\">\n <Field label=\"Speech engine\">\n <Select value={voiceTtsMode} onValueChange={(value) => setVoiceTtsMode(value as 'kokoro' | 'browser')}>\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n <SelectItem value=\"kokoro\">Kokoro (server, fallback to browser)</SelectItem>\n <SelectItem value=\"browser\">Browser Web Speech API</SelectItem>\n </SelectContent>\n </Select>\n </Field>\n <Field label=\"Kokoro voice\">\n <Select value={voiceTtsKokoroVoice} onValueChange={setVoiceTtsKokoroVoice}>\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n {kokoroOptions.map((voice) => <SelectItem key={voice.id} value={voice.id}>{voice.label}</SelectItem>)}\n </SelectContent>\n </Select>\n </Field>\n <Field label=\"Browser voice\">\n <Select value={voiceTtsBrowserVoice || UNSET} onValueChange={(value) => setVoiceTtsBrowserVoice(value === UNSET ? '' : value)}>\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n <SelectItem value={UNSET}>System default</SelectItem>\n {browserVoices.map((voice) => <SelectItem key={voice.uri} value={voice.uri}>{voice.label}</SelectItem>)}\n </SelectContent>\n </Select>\n </Field>\n <Field label=\"Push-to-talk input\">\n <Select value={voiceInputMode} onValueChange={(value) => setVoiceInputMode(value as 'compose' | 'autosend' | 'handsfree')}>\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n <SelectItem value=\"compose\">Fill message box</SelectItem>\n <SelectItem value=\"autosend\">Send immediately</SelectItem>\n </SelectContent>\n </Select>\n </Field>\n </CardContent>\n </Card>\n )\n}\n","import { useState } from 'react'\nimport type { SpawnProvider } from 'agent-relay-sdk/types'\nimport { deriveContextThresholdFromWindowTokens, type ProviderCatalogEntry, type ProviderModelCatalogEntry } from 'agent-relay-sdk/provider-catalog'\nimport { api } from '@/lib/api'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Switch } from '@/components/ui/switch'\nimport { Badge } from '@/components/ui/badge'\nimport { Card, CardAction, CardContent, CardHeader, CardTitle } from '@/components/ui/card'\nimport { CheckCircle2, Eye, EyeOff, Pencil, Plus, ServerCog, SlidersHorizontal, Trash2 } from 'lucide-react'\nimport { errorDetails, Field } from './schema-form'\nimport { lines } from './schema-utils'\n\ninterface ProvidersResponse {\n catalog: ProviderCatalogEntry[]\n}\n\ninterface ModelForm {\n provider: SpawnProvider\n alias: string\n label: string\n providerModel: string\n efforts: string\n defaultEffort: string\n selfCompactUtilization: string\n warnUtilization: string\n hardBackstopUtilization: string\n disabled: boolean\n limits?: ProviderModelCatalogEntry['limits']\n capabilities?: ProviderModelCatalogEntry['capabilities']\n}\n\nexport function ModelCatalogSettings({\n catalog,\n error,\n canWrite,\n onCatalog,\n}: {\n catalog: ProviderCatalogEntry[]\n error: string\n canWrite: boolean\n onCatalog: (catalog: ProviderCatalogEntry[]) => void\n}) {\n const firstProvider = catalog[0]?.provider ?? ''\n const [provider, setProvider] = useState<SpawnProvider>(firstProvider)\n const [form, setForm] = useState<ModelForm>(() => emptyModelForm(firstProvider))\n const [status, setStatus] = useState('')\n const [errors, setErrors] = useState<string[]>([])\n\n const selectedProvider = catalog.some((entry) => entry.provider === provider) ? provider : firstProvider\n const selectedCatalog = catalog.find((entry) => entry.provider === selectedProvider) ?? catalog[0]\n const providers = catalog.map((entry) => entry.provider)\n\n function updateForm(patch: Partial<ModelForm>) {\n setForm((current) => ({ ...current, ...patch }))\n setErrors([])\n setStatus('')\n }\n\n function switchProvider(next: SpawnProvider) {\n setProvider(next)\n setForm(emptyModelForm(next))\n setErrors([])\n setStatus('')\n }\n\n async function reloadCatalog() {\n const res = await api<ProvidersResponse>('GET', '/providers')\n onCatalog(res.catalog)\n }\n\n async function saveModel() {\n if (!canWrite) return\n setErrors([])\n setStatus('')\n try {\n await api('PUT', `/providers/${encodeURIComponent(form.provider)}/models/${encodeURIComponent(form.alias)}`, {\n label: form.label,\n providerModel: form.providerModel,\n efforts: lines(form.efforts),\n defaultEffort: form.defaultEffort.trim() || undefined,\n limits: form.limits,\n capabilities: form.capabilities,\n contextThreshold: contextThresholdFromForm(form),\n disabled: form.disabled,\n updatedBy: 'dashboard',\n })\n await reloadCatalog()\n setStatus(`${form.alias} saved`)\n setForm(emptyModelForm(form.provider))\n } catch (e) {\n const details = errorDetails(e)\n setErrors(details.length ? details : [(e as Error).message])\n }\n }\n\n async function setDisabled(model: ProviderModelCatalogEntry, disabled: boolean) {\n if (!canWrite) return\n setErrors([])\n setStatus('')\n try {\n await api('PATCH', `/providers/${encodeURIComponent(selectedProvider)}/models/${encodeURIComponent(model.alias)}`, { disabled, updatedBy: 'dashboard' })\n await reloadCatalog()\n setStatus(`${model.alias} ${disabled ? 'disabled' : 'enabled'}`)\n } catch (e) {\n const details = errorDetails(e)\n setErrors(details.length ? details : [(e as Error).message])\n }\n }\n\n async function removeModel(model: ProviderModelCatalogEntry) {\n if (!canWrite) return\n setErrors([])\n setStatus('')\n try {\n await api('DELETE', `/providers/${encodeURIComponent(selectedProvider)}/models/${encodeURIComponent(model.alias)}`)\n await reloadCatalog()\n setStatus(`${model.alias} removed`)\n } catch (e) {\n const details = errorDetails(e)\n setErrors(details.length ? details : [(e as Error).message])\n }\n }\n\n function editModel(model: ProviderModelCatalogEntry) {\n setForm({\n provider: selectedProvider,\n alias: model.alias,\n label: model.label,\n providerModel: model.providerModel,\n efforts: model.efforts.join(', '),\n defaultEffort: model.defaultEffort ?? '',\n selfCompactUtilization: model.contextThreshold?.selfCompactUtilization?.toString() ?? '',\n warnUtilization: model.contextThreshold?.warnUtilization?.toString() ?? '',\n hardBackstopUtilization: model.contextThreshold?.hardBackstopUtilization?.toString() ?? '',\n disabled: Boolean(model.disabled),\n limits: model.limits,\n capabilities: model.capabilities,\n })\n setErrors([])\n setStatus('')\n }\n\n if (error) {\n return (\n <Card size=\"sm\">\n <CardContent className=\"text-sm text-muted-foreground\">\n <div className=\"mb-1 flex items-center gap-2 font-medium text-foreground\"><SlidersHorizontal className=\"size-4\" />Model catalog</div>\n {error}\n </CardContent>\n </Card>\n )\n }\n\n return (\n <section className=\"space-y-4\">\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div>\n <h2 className=\"text-base font-semibold\">Model catalog</h2>\n <p className=\"text-sm text-muted-foreground\">Add override models, disable unavailable models, or remove custom entries from the provider catalog.</p>\n </div>\n {!canWrite && <Badge variant=\"secondary\">Read only: needs settings:write:provider</Badge>}\n </div>\n\n <div className=\"flex flex-wrap gap-2\">\n {providers.map((item) => (\n <Button key={item} variant={item === selectedProvider ? 'default' : 'outline'} size=\"sm\" onClick={() => switchProvider(item)}>\n {item}\n </Button>\n ))}\n </div>\n\n <Card size=\"sm\">\n <CardHeader>\n <CardTitle className=\"text-sm\">Add or edit model</CardTitle>\n <CardAction>\n <Badge variant=\"outline\" className=\"gap-1\"><ServerCog className=\"size-3.5\" />Server runtime</Badge>\n </CardAction>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n <div className=\"grid gap-3 md:grid-cols-2\">\n <Field label=\"Alias\">\n <Input value={form.alias} disabled={!canWrite} placeholder=\"nightly\" onChange={(e) => updateForm({ alias: e.target.value.trim() })} />\n </Field>\n <Field label=\"Label\">\n <Input value={form.label} disabled={!canWrite} placeholder=\"Nightly Codex\" onChange={(e) => updateForm({ label: e.target.value })} />\n </Field>\n <Field label=\"Provider model\">\n <Input value={form.providerModel} disabled={!canWrite} placeholder=\"codex-nightly\" onChange={(e) => updateForm({ providerModel: e.target.value })} />\n </Field>\n <Field label=\"Efforts\">\n <Input value={form.efforts} disabled={!canWrite} placeholder=\"low, medium, high\" onChange={(e) => updateForm({ efforts: e.target.value })} />\n </Field>\n <Field label=\"Default effort\">\n <Input value={form.defaultEffort} disabled={!canWrite} placeholder=\"medium\" onChange={(e) => updateForm({ defaultEffort: e.target.value })} />\n </Field>\n <Field label=\"Self compact utilization\">\n <Input value={form.selfCompactUtilization} disabled={!canWrite} placeholder=\"0.80\" inputMode=\"decimal\" onChange={(e) => updateForm({ selfCompactUtilization: e.target.value })} />\n </Field>\n <Field label=\"Warn utilization\">\n <Input value={form.warnUtilization} disabled={!canWrite} placeholder=\"default: self - 0.10\" inputMode=\"decimal\" onChange={(e) => updateForm({ warnUtilization: e.target.value })} />\n </Field>\n <Field label=\"Hard backstop utilization\">\n <Input value={form.hardBackstopUtilization} disabled={!canWrite} placeholder=\"0.90\" inputMode=\"decimal\" onChange={(e) => updateForm({ hardBackstopUtilization: e.target.value })} />\n </Field>\n <div className=\"flex items-center justify-between gap-3 rounded-md border bg-muted/20 p-3\">\n <div>\n <div className=\"text-sm font-medium\">Disabled</div>\n <div className=\"text-xs text-muted-foreground\">Keep visible but unavailable for new launches.</div>\n </div>\n <Switch checked={form.disabled} disabled={!canWrite} onCheckedChange={(disabled) => updateForm({ disabled })} />\n </div>\n </div>\n <Button onClick={saveModel} disabled={!canWrite || !form.alias || !form.label || !form.providerModel}>\n <Plus className=\"size-4\" />\n Save model\n </Button>\n </CardContent>\n </Card>\n\n <div className=\"space-y-2\">\n {selectedCatalog && selectedCatalog.models.length === 0 && (\n <Card size=\"sm\">\n <CardContent className=\"text-sm text-muted-foreground\">No models in this provider catalog yet.</CardContent>\n </Card>\n )}\n {selectedCatalog?.models.map((model) => (\n <Card key={model.alias} size=\"sm\">\n <CardContent className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"min-w-0\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"font-medium\">{model.label}</span>\n <code className=\"rounded bg-muted px-1.5 py-0.5 font-mono text-xs\">{model.alias}</code>\n {model.disabled && <Badge variant=\"secondary\">Disabled</Badge>}\n </div>\n <p className=\"mt-1 text-xs text-muted-foreground\">\n {model.providerModel}\n {model.efforts.length > 0 ? ` · efforts ${model.efforts.join(', ')}` : ' · no effort levels'}\n {model.defaultEffort ? ` · default ${model.defaultEffort}` : ''}\n {` · context ${thresholdLabel(model)}`}\n </p>\n </div>\n <div className=\"flex flex-wrap gap-2\">\n <Button variant=\"outline\" size=\"sm\" onClick={() => editModel(model)}>\n <Pencil className=\"size-4\" />\n Edit\n </Button>\n <Button variant=\"outline\" size=\"sm\" disabled={!canWrite} onClick={() => void setDisabled(model, !model.disabled)}>\n {model.disabled ? <Eye className=\"size-4\" /> : <EyeOff className=\"size-4\" />}\n {model.disabled ? 'Enable' : 'Disable'}\n </Button>\n <Button variant=\"outline\" size=\"sm\" disabled={!canWrite} onClick={() => void removeModel(model)}>\n <Trash2 className=\"size-4\" />\n Remove\n </Button>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n\n {errors.length > 0 && (\n <div className=\"rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive\">\n <ul className=\"list-disc space-y-1 pl-5\">\n {errors.map((detail) => <li key={detail}>{detail}</li>)}\n </ul>\n </div>\n )}\n {status && <p className=\"flex items-center gap-1 text-sm text-emerald-500\"><CheckCircle2 className=\"size-4\" />{status}</p>}\n </section>\n )\n}\n\nfunction emptyModelForm(provider: SpawnProvider): ModelForm {\n return { provider, alias: '', label: '', providerModel: '', efforts: '', defaultEffort: '', selfCompactUtilization: '', warnUtilization: '', hardBackstopUtilization: '', disabled: false }\n}\n\nfunction contextThresholdFromForm(form: ModelForm): ProviderModelCatalogEntry['contextThreshold'] | undefined {\n const selfCompactUtilization = optionalNumber(form.selfCompactUtilization, 'Self compact utilization')\n const warnUtilization = optionalNumber(form.warnUtilization, 'Warn utilization')\n const hardBackstopUtilization = optionalNumber(form.hardBackstopUtilization, 'Hard backstop utilization')\n if (selfCompactUtilization === undefined && warnUtilization === undefined && hardBackstopUtilization === undefined) return undefined\n if (selfCompactUtilization === undefined) throw new Error('Self compact utilization is required when setting context thresholds')\n return {\n selfCompactUtilization,\n ...(warnUtilization !== undefined ? { warnUtilization } : {}),\n ...(hardBackstopUtilization !== undefined ? { hardBackstopUtilization } : {}),\n }\n}\n\nfunction optionalNumber(value: string, label: string): number | undefined {\n const trimmed = value.trim()\n if (!trimmed) return undefined\n const parsed = Number(trimmed)\n if (!Number.isFinite(parsed)) throw new Error(`${label} must be a number`)\n return parsed\n}\n\nfunction thresholdLabel(model: ProviderModelCatalogEntry): string {\n if (model.contextThreshold) {\n const self = percent(model.contextThreshold.selfCompactUtilization)\n const warn = percent(model.contextThreshold.warnUtilization ?? Math.max(0, model.contextThreshold.selfCompactUtilization - 0.1))\n return `self ${self}, warn ${warn}`\n }\n const derived = deriveContextThresholdFromWindowTokens(model.limits?.contextWindowTokens?.value)\n return `derived self ${percent(derived.selfCompactUtilization)}, warn ${percent(derived.warnUtilization)}`\n}\n\nfunction percent(value: number): string {\n return `${Math.round(value * 100)}%`\n}\n","import { useEffect, useState } from 'react'\nimport type { ProviderQuotaConfig, ProviderQuotaConfigMap } from 'agent-relay-sdk/types'\nimport { api } from '@/lib/api'\nimport { Switch } from '@/components/ui/switch'\nimport { Badge } from '@/components/ui/badge'\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'\nimport { AlertCircle, Gauge, Loader2 } from 'lucide-react'\n\n// Quota config block under Settings → Providers (#605). Per provider: enable\n// collection, poll cadence (5m–15m), and show-in-widget. enabled = collect,\n// showInWidget = display — disabling collection stops the orchestrator polling\n// that provider entirely; hiding only removes it from the dashboard widget.\nconst MIN_MINUTES = 5\nconst MAX_MINUTES = 15\n\nconst PROVIDER_LABELS: Record<string, string> = { claude: 'Claude', codex: 'Codex' }\n\nfunction minutesOf(pollIntervalMs: number): number {\n return Math.round(pollIntervalMs / 60_000)\n}\n\nfunction intervalLabel(pollIntervalMs: number): string {\n return `${minutesOf(pollIntervalMs)} min`\n}\n\nexport function QuotaSettings({ canWrite }: { canWrite: boolean }) {\n const [config, setConfig] = useState<ProviderQuotaConfigMap | null>(null)\n const [loadError, setLoadError] = useState('')\n const [saveError, setSaveError] = useState('')\n const [savingProvider, setSavingProvider] = useState<string | null>(null)\n\n // External data load on mount — mirrors the SettingsView reload() pattern.\n useEffect(() => {\n let cancelled = false\n void (async () => {\n try {\n const data = await api<ProviderQuotaConfigMap>('GET', '/providers/quota-config')\n if (!cancelled) setConfig(data)\n } catch (e) {\n if (!cancelled) setLoadError((e as Error).message)\n }\n })()\n return () => { cancelled = true }\n }, [])\n\n async function save(provider: string, next: ProviderQuotaConfig) {\n setConfig((current) => ({ ...(current ?? {}), [provider]: next }))\n setSaveError('')\n setSavingProvider(provider)\n try {\n const saved = await api<ProviderQuotaConfig>('PUT', `/providers/${provider}/quota-config`, next)\n setConfig((current) => ({ ...(current ?? {}), [provider]: saved }))\n } catch (e) {\n setSaveError(`${PROVIDER_LABELS[provider] ?? provider}: ${(e as Error).message}`)\n } finally {\n setSavingProvider(null)\n }\n }\n\n const providers = config ? Object.keys(config).sort() : []\n\n return (\n <section className=\"space-y-4\">\n <div>\n <h2 className=\"text-base font-semibold\">Quota</h2>\n <p className=\"text-sm text-muted-foreground\">\n Per-provider quota collection and display. <strong>Enabled</strong> governs collection (disabled stops polling — no API calls);\n <strong> Show in widget</strong> governs display only.\n </p>\n </div>\n\n {loadError && (\n <div className=\"flex items-start gap-2 rounded-lg border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive\">\n <AlertCircle className=\"mt-0.5 size-4\" />\n <span>{loadError}</span>\n </div>\n )}\n {saveError && (\n <div className=\"flex items-start gap-2 rounded-lg border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive\">\n <AlertCircle className=\"mt-0.5 size-4\" />\n <span>{saveError}</span>\n </div>\n )}\n\n {!config && !loadError && (\n <Card size=\"sm\"><CardContent className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <Loader2 className=\"size-4 animate-spin\" />Loading quota config…\n </CardContent></Card>\n )}\n\n {providers.map((provider) => {\n const cfg = config![provider]!\n const disabled = !canWrite || savingProvider === provider\n return (\n <Card key={provider} size=\"sm\">\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2 text-sm\">\n <Gauge className=\"size-4\" />\n {PROVIDER_LABELS[provider] ?? provider}\n {savingProvider === provider && <Loader2 className=\"size-3 animate-spin text-muted-foreground\" />}\n </CardTitle>\n <CardDescription className=\"text-xs\">\n {cfg.enabled ? `Polled every ${intervalLabel(cfg.pollIntervalMs)}` : 'Collection disabled'}\n {cfg.enabled && !cfg.showInWidget ? ' · hidden from widget' : ''}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"flex items-center justify-between gap-3 rounded-md border bg-muted/20 p-3\">\n <div>\n <div className=\"text-sm font-medium\">Enabled</div>\n <div className=\"text-xs text-muted-foreground\">Collect quota for this provider. Off stops all polling (no API calls, no token spend).</div>\n </div>\n <Switch\n checked={cfg.enabled}\n disabled={disabled}\n onCheckedChange={(enabled) => void save(provider, { ...cfg, enabled })}\n />\n </div>\n\n <div className=\"rounded-md border bg-muted/20 p-3 space-y-2\">\n <div className=\"flex items-center justify-between\">\n <div className=\"text-sm font-medium\">Polling interval</div>\n <Badge variant=\"outline\" className=\"tabular-nums\">{intervalLabel(cfg.pollIntervalMs)}</Badge>\n </div>\n <input\n type=\"range\"\n min={MIN_MINUTES}\n max={MAX_MINUTES}\n step={1}\n value={minutesOf(cfg.pollIntervalMs)}\n disabled={disabled || !cfg.enabled}\n // Live label update while dragging; persist on pointer/key release.\n onChange={(e) => {\n const pollIntervalMs = Number(e.target.value) * 60_000\n setConfig((current) => ({ ...(current ?? {}), [provider]: { ...cfg, pollIntervalMs } }))\n }}\n onPointerUp={(e) => void save(provider, { ...cfg, pollIntervalMs: Number((e.target as HTMLInputElement).value) * 60_000 })}\n onKeyUp={(e) => void save(provider, { ...cfg, pollIntervalMs: Number((e.target as HTMLInputElement).value) * 60_000 })}\n className=\"w-full accent-primary disabled:opacity-50\"\n />\n <div className=\"flex justify-between text-[10px] text-muted-foreground\">\n <span>{MIN_MINUTES} min</span>\n <span>{MAX_MINUTES} min</span>\n </div>\n </div>\n\n <div className=\"flex items-center justify-between gap-3 rounded-md border bg-muted/20 p-3\">\n <div>\n <div className=\"text-sm font-medium\">Show in quota widget</div>\n <div className=\"text-xs text-muted-foreground\">Display only. Off hides this provider from the dashboard widget; collection continues if enabled.</div>\n </div>\n <Switch\n checked={cfg.showInWidget}\n disabled={disabled}\n onCheckedChange={(showInWidget) => void save(provider, { ...cfg, showInWidget })}\n />\n </div>\n\n <div className=\"flex items-center justify-between gap-3 rounded-md border bg-muted/20 p-3\">\n <div>\n <div className=\"text-sm font-medium\">Burn-rate sparkline</div>\n <div className=\"text-xs text-muted-foreground\">Show a mini utilization chart per window in the expanded widget.</div>\n </div>\n <Switch\n checked={cfg.sparklineEnabled ?? true}\n disabled={disabled}\n onCheckedChange={(sparklineEnabled) => void save(provider, { ...cfg, sparklineEnabled })}\n />\n </div>\n\n <div className=\"rounded-md border bg-muted/20 p-3 space-y-2\">\n <div className=\"flex items-center justify-between\">\n <div className=\"text-sm font-medium\">Sparkline range</div>\n <Badge variant=\"outline\" className=\"tabular-nums\">{cfg.sparklineRangeHours ?? 8}h</Badge>\n </div>\n <input\n type=\"range\"\n min={1}\n max={8}\n step={1}\n value={cfg.sparklineRangeHours ?? 8}\n disabled={disabled || !(cfg.sparklineEnabled ?? true)}\n onChange={(e) => {\n const sparklineRangeHours = Number(e.target.value)\n setConfig((current) => ({ ...(current ?? {}), [provider]: { ...cfg, sparklineRangeHours } }))\n }}\n onPointerUp={(e) => void save(provider, { ...cfg, sparklineRangeHours: Number((e.target as HTMLInputElement).value) })}\n onKeyUp={(e) => void save(provider, { ...cfg, sparklineRangeHours: Number((e.target as HTMLInputElement).value) })}\n className=\"w-full accent-primary disabled:opacity-50\"\n />\n <div className=\"flex justify-between text-[10px] text-muted-foreground\">\n <span>1h</span>\n <span>8h</span>\n </div>\n </div>\n </CardContent>\n </Card>\n )\n })}\n </section>\n )\n}\n","import { useState } from 'react'\nimport type { ProviderQuotaRoutingConfig, QuotaBandThresholds, RoutingPolicy } from 'agent-relay-sdk/types'\nimport type { AgentProfile } from '@/types'\nimport { api } from '@/lib/api'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Badge } from '@/components/ui/badge'\nimport { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card'\nimport { AlertCircle, ChevronDown, ChevronRight, Eye, Loader2, RefreshCw, Save } from 'lucide-react'\nimport { cn } from '@/lib/utils'\nimport { getKnownProviderIds, getProviderLabel } from '@/lib/provider-display'\n\nfunction ErrorBanner({ message }: { message: string }) {\n return (\n <div className=\"flex items-start gap-2 rounded-lg border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive\">\n <AlertCircle className=\"mt-0.5 size-4 shrink-0\" />\n <span>{message}</span>\n </div>\n )\n}\n\nconst PROVIDERS = getKnownProviderIds()\n\nconst BAND_DEFAULTS = { cautionAt: 0.15, avoidLargeAt: 0.5, hardAvoidAt: 1.0 }\nconst BACKSTOP_DEFAULT = 0.99\nconst FLOOR_DEFAULT = 0.5\n\nfunction pctStr(v: number | undefined, def: number) {\n return ((v ?? def) * 100).toFixed(0)\n}\n\nfunction parseFraction(s: string): number | null {\n const trimmed = s.trim()\n if (!trimmed) return null\n const n = Number(trimmed)\n if (!Number.isFinite(n) || n < 0 || n > 100) return null\n return n / 100\n}\n\nfunction parseFractionWithBlankDefault(s: string, def: number): number | null {\n return s.trim() ? parseFraction(s) : def\n}\n\n// ─── QuotaThresholdsEditor ────────────────────────────────────────────────────\n\nexport function QuotaThresholdsEditor({\n policy,\n canWrite,\n onPolicy,\n}: {\n policy: RoutingPolicy\n canWrite: boolean\n onPolicy: (p: RoutingPolicy) => void\n}) {\n const bands = policy.quotaBands\n const providerQuota = policy.providerQuota ?? {}\n\n const [cautionPct, setCautionPct] = useState(pctStr(bands?.cautionAt, BAND_DEFAULTS.cautionAt))\n const [avoidLargePct, setAvoidLargePct] = useState(pctStr(bands?.avoidLargeAt, BAND_DEFAULTS.avoidLargeAt))\n const [hardAvoidPct, setHardAvoidPct] = useState(pctStr(bands?.hardAvoidAt, BAND_DEFAULTS.hardAvoidAt))\n\n const [providerForms, setProviderForms] = useState<Record<string, { backstop: string; floor: string }>>(() => {\n const out: Record<string, { backstop: string; floor: string }> = {}\n for (const p of PROVIDERS) {\n const cfg = providerQuota[p] ?? {}\n out[p] = {\n backstop: pctStr(cfg.hardBackstopUtilization, BACKSTOP_DEFAULT),\n floor: pctStr(cfg.burnPenaltyUtilizationFloor, FLOOR_DEFAULT),\n }\n }\n return out\n })\n\n const [saving, setSaving] = useState(false)\n const [saveError, setSaveError] = useState('')\n const [saveOk, setSaveOk] = useState(false)\n const [validationError, setValidationError] = useState('')\n\n async function save() {\n const caution = parseFraction(cautionPct)\n const avoidLarge = parseFraction(avoidLargePct)\n const hardAvoid = parseFraction(hardAvoidPct)\n\n if (caution === null) { setValidationError('Caution threshold must be 0–100%.'); return }\n if (avoidLarge === null) { setValidationError('Avoid-large threshold must be 0–100%.'); return }\n if (hardAvoid === null) { setValidationError('Hard-avoid threshold must be 0–100%.'); return }\n if (caution >= avoidLarge) { setValidationError('Caution must be less than avoid-large.'); return }\n if (avoidLarge >= hardAvoid) { setValidationError('Avoid-large must be less than hard-avoid.'); return }\n\n const nextProviderQuota: Partial<Record<string, ProviderQuotaRoutingConfig>> = {}\n for (const p of PROVIDERS) {\n const f = providerForms[p]!\n const backstop = parseFractionWithBlankDefault(f.backstop, BACKSTOP_DEFAULT)\n const floor = parseFraction(f.floor)\n if (backstop === null) { setValidationError(`${getProviderLabel(p)}: hard-backstop must be 0–100%.`); return }\n if (floor === null) { setValidationError(`${getProviderLabel(p)}: burn-penalty floor must be 0–100%.`); return }\n nextProviderQuota[p] = { hardBackstopUtilization: backstop, burnPenaltyUtilizationFloor: floor }\n }\n\n setValidationError('')\n setSaving(true)\n setSaveError('')\n setSaveOk(false)\n try {\n const saved = await api<RoutingPolicy>('PUT', '/routing-policy', {\n ...policy,\n quotaBands: { cautionAt: caution, avoidLargeAt: avoidLarge, hardAvoidAt: hardAvoid } satisfies QuotaBandThresholds,\n providerQuota: nextProviderQuota,\n })\n onPolicy(saved)\n setSaveOk(true)\n setTimeout(() => setSaveOk(false), 2000)\n } catch (e) {\n setSaveError((e as Error).message)\n } finally {\n setSaving(false)\n }\n }\n\n function patchProvider(provider: string, patch: { backstop?: string; floor?: string }) {\n setProviderForms((cur) => ({ ...cur, [provider]: { ...cur[provider]!, ...patch } }))\n setValidationError('')\n setSaveOk(false)\n }\n\n function markDirty() { setValidationError(''); setSaveOk(false) }\n\n return (\n <Card size=\"sm\">\n <CardHeader>\n <CardTitle className=\"text-sm\">Quota thresholds</CardTitle>\n <CardDescription className=\"text-xs\">\n Band cutoffs govern when the orchestrator starts penalising or blocking high-quota providers. Values are utilization percentages (0–100).\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {(saveError || validationError) && <ErrorBanner message={saveError || validationError} />}\n\n <div>\n <div className=\"mb-2 text-xs font-medium text-muted-foreground uppercase tracking-wide\">Band cutoffs</div>\n <QuotaBandDiagram caution={Number(cautionPct)} avoidLarge={Number(avoidLargePct)} hardAvoid={Number(hardAvoidPct)} />\n <div className=\"mt-3 grid gap-3 sm:grid-cols-3\">\n <FractionField label=\"Caution at\" hint={`Default: ${(BAND_DEFAULTS.cautionAt * 100).toFixed(0)}%`}\n value={cautionPct} disabled={!canWrite || saving} onChange={(v) => { setCautionPct(v); markDirty() }} />\n <FractionField label=\"Avoid-large at\" hint={`Default: ${(BAND_DEFAULTS.avoidLargeAt * 100).toFixed(0)}%`}\n value={avoidLargePct} disabled={!canWrite || saving} onChange={(v) => { setAvoidLargePct(v); markDirty() }} />\n <FractionField label=\"Hard-avoid at\" hint={`Default: ${(BAND_DEFAULTS.hardAvoidAt * 100).toFixed(0)}%`}\n value={hardAvoidPct} disabled={!canWrite || saving} onChange={(v) => { setHardAvoidPct(v); markDirty() }} />\n </div>\n </div>\n\n {PROVIDERS.map((p) => {\n const f = providerForms[p]!\n return (\n <div key={p}>\n <div className=\"mb-2 text-xs font-medium text-muted-foreground uppercase tracking-wide\">{getProviderLabel(p)} overrides</div>\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <FractionField label=\"Hard-backstop utilization\"\n hint={`0 = disable backstop (never block on this quota); blank uses the ${(BACKSTOP_DEFAULT * 100).toFixed(0)}% default.`}\n value={f.backstop} disabled={!canWrite || saving}\n onChange={(v) => patchProvider(p, { backstop: v })} />\n <FractionField label=\"Burn-penalty floor\"\n hint={`Penalties suppressed below this. Default: ${(FLOOR_DEFAULT * 100).toFixed(0)}%`}\n value={f.floor} disabled={!canWrite || saving}\n onChange={(v) => patchProvider(p, { floor: v })} />\n </div>\n </div>\n )\n })}\n\n {canWrite && (\n <Button size=\"sm\" onClick={() => void save()} disabled={saving}>\n {saving ? <Loader2 className=\"size-4 animate-spin\" /> : <Save className=\"size-4\" />}\n {saveOk ? 'Saved' : 'Save thresholds'}\n </Button>\n )}\n </CardContent>\n </Card>\n )\n}\n\n// Linear band diagram (#731): renders the four quota zones as proportional segments\n// on a 0–100% axis so the relationship between the three cutoffs is legible at a glance.\n// Driven live by the current input values — it reshapes as you edit the fields below.\nfunction QuotaBandDiagram({ caution, avoidLarge, hardAvoid }: { caution: number; avoidLarge: number; hardAvoid: number }) {\n const clamp = (n: number) => Math.max(0, Math.min(100, Number.isFinite(n) ? n : 0))\n const c = clamp(caution)\n // Keep boundaries monotonic for display even while a half-typed value is out of order.\n const a = Math.max(c, clamp(avoidLarge))\n const h = Math.max(a, clamp(hardAvoid))\n const fmt = (n: number) => `${n.toFixed(0)}%`\n const zones = [\n { key: 'normal', label: 'normal', color: 'bg-emerald-500', from: 0, to: c, range: `0–${fmt(c)}` },\n { key: 'caution', label: 'caution', color: 'bg-amber-500', from: c, to: a, range: `${fmt(c)}–${fmt(a)}` },\n { key: 'avoid-large', label: 'avoid large', color: 'bg-orange-500', from: a, to: h, range: `${fmt(a)}–${fmt(h)}` },\n { key: 'hard-avoid', label: 'hard avoid', color: 'bg-red-500', from: h, to: 100, range: `≥ ${fmt(h)}` },\n ]\n return (\n <div className=\"space-y-1.5\">\n <div className=\"flex h-2.5 overflow-hidden rounded-full bg-muted\" role=\"img\" aria-label=\"Quota penalty bands from 0 to 100 percent\">\n {zones.map((z) => (\n <div key={z.key} className={cn(z.color, 'transition-[width] duration-300')} style={{ width: `${z.to - z.from}%` }} title={`${z.label} · ${z.range}`} />\n ))}\n </div>\n <div className=\"flex flex-wrap gap-x-3 gap-y-1 text-[10px] text-muted-foreground\">\n {zones.map((z) => (\n <span key={z.key} className=\"flex items-center gap-1\">\n <span className={cn('size-2 shrink-0 rounded-full', z.color)} />\n {z.label} <span className=\"tabular-nums text-foreground/70\">{z.range}</span>\n </span>\n ))}\n </div>\n </div>\n )\n}\n\nfunction FractionField({ label, hint, value, disabled, onChange }: {\n label: string; hint: string; value: string; disabled: boolean; onChange: (v: string) => void\n}) {\n return (\n <label className=\"space-y-1\">\n <span className=\"text-[10px] font-medium text-muted-foreground\">{label}</span>\n <div className=\"relative\">\n <Input value={value} onChange={(e) => onChange(e.target.value)} disabled={disabled}\n className=\"h-8 pr-6 text-xs tabular-nums\" />\n <span className=\"pointer-events-none absolute inset-y-0 right-2.5 flex items-center text-xs text-muted-foreground\">%</span>\n </div>\n <span className=\"text-[10px] text-muted-foreground\">{hint}</span>\n </label>\n )\n}\n\n// ─── CoordinatorVisibilityPanel ───────────────────────────────────────────────\n\ninterface VisibilityData {\n policy: RoutingPolicy\n profile: AgentProfile | null\n}\n\nexport function CoordinatorVisibilityPanel() {\n const [data, setData] = useState<VisibilityData | null>(null)\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState('')\n const [open, setOpen] = useState(false)\n const [loaded, setLoaded] = useState(false)\n\n async function load() {\n if (loaded) return\n setLoading(true)\n setError('')\n try {\n const [policy, profile] = await Promise.all([\n api<RoutingPolicy>('GET', '/routing-policy'),\n api<AgentProfile>('GET', '/agent-profiles/coordinator').catch(() => null),\n ])\n setData({ policy, profile })\n setLoaded(true)\n } catch (e) {\n setError((e as Error).message)\n } finally {\n setLoading(false)\n }\n }\n\n async function reload() {\n setLoaded(false)\n setLoading(true)\n setError('')\n try {\n const [policy, profile] = await Promise.all([\n api<RoutingPolicy>('GET', '/routing-policy'),\n api<AgentProfile>('GET', '/agent-profiles/coordinator').catch(() => null),\n ])\n setData({ policy, profile })\n setLoaded(true)\n } catch (e) {\n setError((e as Error).message)\n } finally {\n setLoading(false)\n }\n }\n\n function toggle() {\n const next = !open\n setOpen(next)\n if (next && !loaded) void load()\n }\n\n return (\n <Card size=\"sm\">\n <CardContent className=\"space-y-3\">\n <button type=\"button\" className=\"flex w-full items-center gap-2 text-left\" onClick={toggle}>\n <Eye className=\"size-4 text-muted-foreground\" />\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm font-semibold\">What your coordinator knows</div>\n <div className=\"text-xs text-muted-foreground\">Active routing policy + coordinator profile instructions (read-only)</div>\n </div>\n {open ? <ChevronDown className=\"size-4 shrink-0 text-muted-foreground\" /> : <ChevronRight className=\"size-4 shrink-0 text-muted-foreground\" />}\n </button>\n\n {open && (\n <div className=\"space-y-4 pt-1\">\n <div className=\"flex justify-end\">\n <Button variant=\"outline\" size=\"sm\" onClick={() => void reload()} disabled={loading}>\n <RefreshCw className={cn('size-3.5', loading && 'animate-spin')} />\n Refresh\n </Button>\n </div>\n\n {error && <ErrorBanner message={error} />}\n\n {loading && !data && (\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground py-2\">\n <Loader2 className=\"size-3.5 animate-spin\" />Loading…\n </div>\n )}\n\n {data && (\n <>\n <ActivePolicyDisplay policy={data.policy} />\n {data.profile\n ? <CoordinatorProfileDisplay profile={data.profile} />\n : <div className=\"text-xs text-muted-foreground italic\">Coordinator profile not found.</div>\n }\n </>\n )}\n </div>\n )}\n </CardContent>\n </Card>\n )\n}\n\nfunction ActivePolicyDisplay({ policy }: { policy: RoutingPolicy }) {\n const bands = policy.quotaBands\n const providerQuota = policy.providerQuota ?? {}\n\n return (\n <div className=\"space-y-2\">\n <div className=\"text-xs font-semibold text-muted-foreground uppercase tracking-wide\">Active routing policy</div>\n\n {policy.rules.length === 0 ? (\n <div className=\"text-xs text-muted-foreground italic\">No rules — coordinators use their own heuristics.</div>\n ) : (\n <div className=\"overflow-hidden rounded-md border border-border text-xs\">\n <div className=\"grid grid-cols-[1.5rem_minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)] gap-px bg-border text-[10px] font-medium text-muted-foreground uppercase tracking-wide\">\n <div className=\"bg-muted/40 px-2 py-1.5\">#</div>\n <div className=\"bg-muted/40 px-2 py-1.5\">Match</div>\n <div className=\"bg-muted/40 px-2 py-1.5\">Target</div>\n <div className=\"bg-muted/40 px-2 py-1.5\">Status</div>\n </div>\n {policy.rules.map((rule, idx) => (\n <div key={idx}\n className={cn('grid grid-cols-[1.5rem_minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)] gap-px bg-border', rule.enabled === false && 'opacity-50')}>\n <div className=\"bg-card px-2 py-1.5 text-muted-foreground tabular-nums\">{idx + 1}</div>\n <div className=\"bg-card px-2 py-1.5\">\n {rule.label && <div className=\"font-medium\">{rule.label}</div>}\n {rule.match.taskType && <div className=\"font-mono\">task: {rule.match.taskType}</div>}\n {rule.match.capability && <div className=\"font-mono\">cap: {rule.match.capability}</div>}\n </div>\n <div className=\"bg-card px-2 py-1.5\">\n <span className=\"font-medium\">{rule.target.provider}</span>\n {rule.target.model && <span className=\"text-muted-foreground\"> / {rule.target.model}</span>}\n {rule.target.effort && <span className=\"text-muted-foreground\"> ({rule.target.effort})</span>}\n </div>\n <div className=\"bg-card px-2 py-1.5\">\n {rule.enabled === false ? <span className=\"text-muted-foreground\">disabled</span> : <span className=\"text-emerald-500\">active</span>}\n </div>\n </div>\n ))}\n </div>\n )}\n\n {(bands || Object.keys(providerQuota).length > 0) && (\n <div className=\"rounded-md border border-border bg-muted/10 px-3 py-2 text-xs space-y-1\">\n {bands && (\n <div className=\"flex flex-wrap gap-x-4 gap-y-0.5\">\n {bands.cautionAt !== undefined && <span>caution ≥ {(bands.cautionAt * 100).toFixed(0)}%</span>}\n {bands.avoidLargeAt !== undefined && <span>avoid-large ≥ {(bands.avoidLargeAt * 100).toFixed(0)}%</span>}\n {bands.hardAvoidAt !== undefined && <span>hard-avoid ≥ {(bands.hardAvoidAt * 100).toFixed(0)}%</span>}\n </div>\n )}\n {Object.entries(providerQuota).map(([provider, cfg]) => (\n <div key={provider} className=\"flex flex-wrap gap-x-4 gap-y-0.5 text-muted-foreground\">\n <span className=\"font-medium text-foreground\">{getProviderLabel(provider)}</span>\n {cfg?.hardBackstopUtilization !== undefined && <span>backstop: {(cfg.hardBackstopUtilization * 100).toFixed(0)}%</span>}\n {cfg?.burnPenaltyUtilizationFloor !== undefined && <span>floor: {(cfg.burnPenaltyUtilizationFloor * 100).toFixed(0)}%</span>}\n </div>\n ))}\n </div>\n )}\n </div>\n )\n}\n\n// Instruction text is prose (markdown), not code — render it in the prose font with\n// relaxed line-height so it reads as prose, while `whitespace-pre-wrap` preserves the\n// author's exact line breaks. A capped, scrollable height keeps a long system prompt\n// from running the whole panel off-screen (#731).\nfunction InstructionBlock({ text, index }: { text: string; index?: number }) {\n return (\n <div className=\"relative max-h-72 overflow-y-auto rounded-md border border-border bg-muted/20\">\n {index !== undefined && (\n <span className=\"sticky top-0 float-right m-1.5 rounded bg-muted px-1.5 py-0.5 text-[9px] font-medium tabular-nums text-muted-foreground\">\n #{index}\n </span>\n )}\n <pre className=\"whitespace-pre-wrap break-words px-3 py-2.5 font-sans text-[11px] leading-relaxed text-foreground/90\">\n {text}\n </pre>\n </div>\n )\n}\n\nfunction CoordinatorProfileDisplay({ profile }: { profile: AgentProfile }) {\n return (\n <div className=\"space-y-2\">\n <div className=\"text-xs font-semibold text-muted-foreground uppercase tracking-wide\">\n Coordinator profile instructions\n <Badge variant=\"secondary\" className=\"ml-2 text-[10px]\">{profile.name}</Badge>\n {profile.builtIn && <Badge variant=\"outline\" className=\"ml-1 text-[10px]\">built-in</Badge>}\n </div>\n\n {profile.description && <p className=\"text-xs text-muted-foreground\">{profile.description}</p>}\n\n <div className=\"flex flex-wrap gap-2 text-[10px]\">\n <Badge variant=\"outline\">base: {profile.base}</Badge>\n <Badge variant=\"outline\">repo: {profile.instructions.repoInstructions}</Badge>\n <Badge variant=\"outline\">global: {profile.instructions.globalInstructions}</Badge>\n {profile.provider && <Badge variant=\"outline\">provider: {profile.provider}</Badge>}\n </div>\n\n {profile.instructions.system && (\n <div className=\"space-y-1\">\n <div className=\"text-[10px] font-medium text-muted-foreground uppercase tracking-wide\">System prompt</div>\n <InstructionBlock text={profile.instructions.system} />\n </div>\n )}\n\n {profile.instructions.append.length > 0 && (\n <div className=\"space-y-2\">\n <div className=\"text-[10px] font-medium text-muted-foreground uppercase tracking-wide\">\n Appended instructions ({profile.instructions.append.length})\n </div>\n {profile.instructions.append.map((block, i) => (\n <InstructionBlock key={i} text={block} index={i + 1} />\n ))}\n </div>\n )}\n\n {profile.instructions.append.length === 0 && !profile.instructions.system && (\n <div className=\"text-xs text-muted-foreground italic\">No instruction blocks defined.</div>\n )}\n </div>\n )\n}\n","import { useState } from 'react'\nimport type { RoutingPolicy, RoutingRule } from 'agent-relay-sdk/types'\nimport { api } from '@/lib/api'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Switch } from '@/components/ui/switch'\nimport { Badge } from '@/components/ui/badge'\nimport { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport {\n AlertCircle,\n ArrowDown,\n ArrowUp,\n Loader2,\n Plus,\n RefreshCw,\n Route,\n Save,\n Trash2,\n} from 'lucide-react'\nimport { cn } from '@/lib/utils'\nimport { getKnownProviderIds, getProviderLabel } from '@/lib/provider-display'\nimport { QuotaThresholdsEditor, CoordinatorVisibilityPanel } from './routing-coordinator-panel'\n\nconst PROVIDERS = getKnownProviderIds()\n\n// ─── types ───────────────────────────────────────────────────────────────────\n\ninterface RuleForm {\n label: string\n matchTaskType: string\n matchCapability: string\n targetProvider: string\n targetModel: string\n targetEffort: string\n enabled: boolean\n}\n\nfunction emptyRuleForm(): RuleForm {\n return { label: '', matchTaskType: '', matchCapability: '', targetProvider: PROVIDERS[0] ?? '', targetModel: '', targetEffort: '', enabled: true }\n}\n\nfunction ruleToForm(rule: RoutingRule): RuleForm {\n return {\n label: rule.label ?? '',\n matchTaskType: rule.match.taskType ?? '',\n matchCapability: rule.match.capability ?? '',\n targetProvider: rule.target.provider,\n targetModel: rule.target.model ?? '',\n targetEffort: rule.target.effort ?? '',\n enabled: rule.enabled !== false,\n }\n}\n\nfunction formToRule(form: RuleForm): RoutingRule {\n return {\n ...(form.label.trim() ? { label: form.label.trim() } : {}),\n match: {\n ...(form.matchTaskType.trim() ? { taskType: form.matchTaskType.trim() } : {}),\n ...(form.matchCapability.trim() ? { capability: form.matchCapability.trim() } : {}),\n },\n target: {\n provider: form.targetProvider,\n ...(form.targetModel.trim() ? { model: form.targetModel.trim() } : {}),\n ...(form.targetEffort.trim() ? { effort: form.targetEffort.trim() } : {}),\n },\n enabled: form.enabled,\n }\n}\n\nfunction validateRuleForm(form: RuleForm): string | null {\n if (!form.matchTaskType.trim() && !form.matchCapability.trim()) {\n return 'At least one match criterion (task type or capability) is required.'\n }\n return null\n}\n\nfunction ErrorBanner({ message }: { message: string }) {\n return (\n <div className=\"flex items-start gap-2 rounded-lg border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive\">\n <AlertCircle className=\"mt-0.5 size-4 shrink-0\" />\n <span>{message}</span>\n </div>\n )\n}\n\n// ─── RoutingSettings (root) ───────────────────────────────────────────────────\n\nexport function RoutingSettings({ canWrite }: { canWrite: boolean }) {\n const [policy, setPolicy] = useState<RoutingPolicy | null>(null)\n const [loading, setLoading] = useState(false)\n const [loadError, setLoadError] = useState('')\n const [loaded, setLoaded] = useState(false)\n\n if (!loaded && !loading && !loadError) {\n setLoading(true)\n void (async () => {\n try {\n const data = await api<RoutingPolicy>('GET', '/routing-policy')\n setPolicy(data)\n setLoaded(true)\n } catch (e) {\n setLoadError((e as Error).message)\n } finally {\n setLoading(false)\n }\n })()\n }\n\n async function reload() {\n setLoading(true)\n setLoadError('')\n try {\n const data = await api<RoutingPolicy>('GET', '/routing-policy')\n setPolicy(data)\n setLoaded(true)\n } catch (e) {\n setLoadError((e as Error).message)\n } finally {\n setLoading(false)\n }\n }\n\n return (\n <div className=\"space-y-6\">\n <div className=\"flex items-center justify-between gap-3\">\n <div>\n <h2 className=\"text-base font-semibold\">Routing</h2>\n <p className=\"text-sm text-muted-foreground\">\n Declarative rules mapping task types and capabilities to providers. Rules are advisory — coordinators apply\n them; explicit per-spawn arguments always take precedence.\n </p>\n </div>\n <Button variant=\"outline\" size=\"sm\" onClick={() => void reload()} disabled={loading}>\n <RefreshCw className={cn('size-4', loading && 'animate-spin')} />\n Refresh\n </Button>\n </div>\n\n {loadError && <ErrorBanner message={loadError} />}\n\n {loading && !policy && (\n <Card size=\"sm\">\n <CardContent className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <Loader2 className=\"size-4 animate-spin\" />\n Loading routing policy…\n </CardContent>\n </Card>\n )}\n\n {policy && (\n <>\n <RoutingRulesEditor policy={policy} canWrite={canWrite} onPolicy={setPolicy} />\n <QuotaThresholdsEditor policy={policy} canWrite={canWrite} onPolicy={setPolicy} />\n </>\n )}\n\n <CoordinatorVisibilityPanel />\n </div>\n )\n}\n\n// ─── RoutingRulesEditor ───────────────────────────────────────────────────────\n\nfunction RoutingRulesEditor({\n policy,\n canWrite,\n onPolicy,\n}: {\n policy: RoutingPolicy\n canWrite: boolean\n onPolicy: (p: RoutingPolicy) => void\n}) {\n const [saving, setSaving] = useState(false)\n const [saveError, setSaveError] = useState('')\n const [addOpen, setAddOpen] = useState(false)\n const [addForm, setAddForm] = useState<RuleForm>(emptyRuleForm)\n const [addError, setAddError] = useState('')\n const [editIdx, setEditIdx] = useState<number | null>(null)\n const [editForm, setEditForm] = useState<RuleForm>(emptyRuleForm)\n const [editError, setEditError] = useState('')\n\n async function putPolicy(next: RoutingPolicy) {\n setSaving(true)\n setSaveError('')\n try {\n const saved = await api<RoutingPolicy>('PUT', '/routing-policy', next)\n onPolicy(saved)\n } catch (e) {\n setSaveError((e as Error).message)\n } finally {\n setSaving(false)\n }\n }\n\n function move(idx: number, dir: -1 | 1) {\n const rules = [...policy.rules]\n const target = idx + dir\n if (target < 0 || target >= rules.length) return\n ;[rules[idx], rules[target]] = [rules[target]!, rules[idx]!]\n void putPolicy({ ...policy, rules })\n }\n\n function toggleEnabled(idx: number) {\n const rules = policy.rules.map((r, i) => (i === idx ? { ...r, enabled: r.enabled === false ? true : false } : r))\n void putPolicy({ ...policy, rules })\n }\n\n function removeRule(idx: number) {\n void putPolicy({ ...policy, rules: policy.rules.filter((_, i) => i !== idx) })\n }\n\n function startAdd() { setAddForm(emptyRuleForm()); setAddError(''); setAddOpen(true) }\n function cancelAdd() { setAddOpen(false); setAddError('') }\n\n function commitAdd() {\n const err = validateRuleForm(addForm)\n if (err) { setAddError(err); return }\n setAddOpen(false)\n void putPolicy({ ...policy, rules: [...policy.rules, formToRule(addForm)] })\n }\n\n function startEdit(idx: number) {\n setEditIdx(idx); setEditForm(ruleToForm(policy.rules[idx]!)); setEditError('')\n }\n\n function cancelEdit() { setEditIdx(null); setEditError('') }\n\n function commitEdit() {\n if (editIdx === null) return\n const err = validateRuleForm(editForm)\n if (err) { setEditError(err); return }\n const rules = policy.rules.map((r, i) => (i === editIdx ? formToRule(editForm) : r))\n setEditIdx(null)\n void putPolicy({ ...policy, rules })\n }\n\n return (\n <Card size=\"sm\">\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2 text-sm\">\n <Route className=\"size-4\" />\n Rules\n <Badge variant=\"outline\" className=\"ml-auto text-[10px]\">\n {policy.rules.length} rule{policy.rules.length === 1 ? '' : 's'}\n </Badge>\n {saving && <Loader2 className=\"size-3 animate-spin text-muted-foreground\" />}\n </CardTitle>\n <CardDescription className=\"text-xs\">\n Evaluated in order — first matching enabled rule wins. Rules are advisory; explicit spawn arguments override them.\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-2\">\n {saveError && <ErrorBanner message={saveError} />}\n\n {policy.rules.length === 0 && !addOpen && (\n <div className=\"rounded-md border border-dashed border-border py-6 text-center text-xs text-muted-foreground\">\n No rules — coordinators fall back to their own heuristics.\n </div>\n )}\n\n {policy.rules.map((rule, idx) =>\n editIdx === idx ? (\n <RuleEditForm key={idx} form={editForm} error={editError} onChange={setEditForm} onSave={commitEdit} onCancel={cancelEdit} />\n ) : (\n <RuleRow\n key={idx}\n rule={rule}\n idx={idx}\n total={policy.rules.length}\n canWrite={canWrite}\n saving={saving}\n onMoveUp={() => move(idx, -1)}\n onMoveDown={() => move(idx, 1)}\n onToggle={() => toggleEnabled(idx)}\n onEdit={() => startEdit(idx)}\n onRemove={() => removeRule(idx)}\n />\n ),\n )}\n\n {addOpen && (\n <RuleEditForm form={addForm} error={addError} onChange={setAddForm} onSave={commitAdd} onCancel={cancelAdd} isNew />\n )}\n\n {canWrite && !addOpen && editIdx === null && (\n <Button variant=\"outline\" size=\"sm\" className=\"w-full gap-1\" onClick={startAdd} disabled={saving}>\n <Plus className=\"size-4\" />\n Add rule\n </Button>\n )}\n </CardContent>\n </Card>\n )\n}\n\nfunction RuleRow({\n rule, idx, total, canWrite, saving,\n onMoveUp, onMoveDown, onToggle, onEdit, onRemove,\n}: {\n rule: RoutingRule\n idx: number\n total: number\n canWrite: boolean\n saving: boolean\n onMoveUp: () => void\n onMoveDown: () => void\n onToggle: () => void\n onEdit: () => void\n onRemove: () => void\n}) {\n const disabled = rule.enabled === false\n return (\n <div className={cn('group flex items-start gap-3 rounded-md border bg-muted/20 p-3', disabled && 'opacity-60')}>\n <div className=\"flex flex-col items-center gap-0.5 pt-0.5\">\n <button type=\"button\" title=\"Move up\" onClick={onMoveUp} disabled={!canWrite || saving || idx === 0}\n className=\"rounded p-0.5 text-muted-foreground hover:bg-accent hover:text-foreground disabled:pointer-events-none disabled:opacity-30\">\n <ArrowUp className=\"size-3.5\" />\n </button>\n <button type=\"button\" title=\"Move down\" onClick={onMoveDown} disabled={!canWrite || saving || idx === total - 1}\n className=\"rounded p-0.5 text-muted-foreground hover:bg-accent hover:text-foreground disabled:pointer-events-none disabled:opacity-30\">\n <ArrowDown className=\"size-3.5\" />\n </button>\n </div>\n\n <div className=\"min-w-0 flex-1 space-y-1\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-[10px] tabular-nums text-muted-foreground\">#{idx + 1}</span>\n {rule.label && <span className=\"text-xs font-medium\">{rule.label}</span>}\n <Badge variant=\"outline\" className=\"text-[10px]\">{rule.target.provider}</Badge>\n {rule.target.model && <Badge variant=\"outline\" className=\"text-[10px] font-mono\">{rule.target.model}</Badge>}\n {rule.target.effort && <Badge variant=\"outline\" className=\"text-[10px]\">{rule.target.effort}</Badge>}\n </div>\n <div className=\"flex flex-wrap gap-x-3 gap-y-0.5 text-[10px] text-muted-foreground\">\n {rule.match.taskType && <span>task-type: <span className=\"font-mono text-foreground\">{rule.match.taskType}</span></span>}\n {rule.match.capability && <span>capability: <span className=\"font-mono text-foreground\">{rule.match.capability}</span></span>}\n </div>\n </div>\n\n <div className=\"flex shrink-0 items-center gap-1 opacity-70 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100\">\n <Switch checked={rule.enabled !== false} disabled={!canWrite || saving} onCheckedChange={onToggle}\n title={rule.enabled === false ? 'Enable rule' : 'Disable rule'} />\n {canWrite && (\n <>\n <button type=\"button\" title=\"Edit\" onClick={onEdit} disabled={saving}\n className=\"rounded p-1 text-muted-foreground hover:bg-accent hover:text-foreground disabled:pointer-events-none\">\n <svg className=\"size-3.5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2}>\n <path d=\"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\" />\n <path d=\"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z\" />\n </svg>\n </button>\n <button type=\"button\" title=\"Remove\" onClick={onRemove} disabled={saving}\n className=\"rounded p-1 text-destructive hover:bg-destructive/10 disabled:pointer-events-none\">\n <Trash2 className=\"size-3.5\" />\n </button>\n </>\n )}\n </div>\n </div>\n )\n}\n\nfunction RuleEditForm({\n form, error, onChange, onSave, onCancel, isNew,\n}: {\n form: RuleForm\n error: string\n onChange: (f: RuleForm) => void\n onSave: () => void\n onCancel: () => void\n isNew?: boolean\n}) {\n function patch(p: Partial<RuleForm>) { onChange({ ...form, ...p }) }\n return (\n <div className=\"rounded-md border border-primary/30 bg-primary/5 p-3 space-y-3\">\n <div className=\"text-xs font-semibold text-muted-foreground uppercase tracking-wide\">{isNew ? 'New rule' : 'Edit rule'}</div>\n\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <label className=\"space-y-1\">\n <span className=\"text-[10px] font-medium text-muted-foreground\">Label (optional)</span>\n <Input value={form.label} onChange={(e) => patch({ label: e.target.value })}\n placeholder=\"e.g. Route GUI tasks to Claude\" className=\"h-8 text-xs\" />\n </label>\n <label className=\"space-y-1\">\n <span className=\"text-[10px] font-medium text-muted-foreground\">Target provider</span>\n <Select value={form.targetProvider} onValueChange={(v) => patch({ targetProvider: v })}>\n <SelectTrigger className=\"h-8 text-xs\"><SelectValue /></SelectTrigger>\n <SelectContent>\n {PROVIDERS.map((p) => <SelectItem key={p} value={p} className=\"text-xs\">{getProviderLabel(p)}</SelectItem>)}\n </SelectContent>\n </Select>\n </label>\n </div>\n\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <label className=\"space-y-1\">\n <span className=\"text-[10px] font-medium text-muted-foreground\">Match task-type (prefix)</span>\n <Input value={form.matchTaskType} onChange={(e) => patch({ matchTaskType: e.target.value })}\n placeholder=\"e.g. gui, backend, mechanical\" className=\"h-8 font-mono text-xs\" />\n <span className=\"block text-[10px] leading-snug text-muted-foreground\">\n Prefix match — <span className=\"font-mono text-foreground\">gui</span> matches <span className=\"font-mono text-foreground\">gui/ux</span>, <span className=\"font-mono text-foreground\">gui/layout</span>.\n </span>\n </label>\n <label className=\"space-y-1\">\n <span className=\"text-[10px] font-medium text-muted-foreground\">Match capability (exact)</span>\n <Input value={form.matchCapability} onChange={(e) => patch({ matchCapability: e.target.value })}\n placeholder=\"e.g. code, research, bounded\" className=\"h-8 font-mono text-xs\" />\n <span className=\"block text-[10px] leading-snug text-muted-foreground\">\n Exact match against the agent's capability tag. Both fields are AND-ed.\n </span>\n </label>\n </div>\n\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <label className=\"space-y-1\">\n <span className=\"text-[10px] font-medium text-muted-foreground\">Model alias (optional)</span>\n <Input value={form.targetModel} onChange={(e) => patch({ targetModel: e.target.value })}\n placeholder=\"e.g. opus, gpt-5.4\" className=\"h-8 font-mono text-xs\" />\n </label>\n <label className=\"space-y-1\">\n <span className=\"text-[10px] font-medium text-muted-foreground\">Effort (optional)</span>\n <Input value={form.targetEffort} onChange={(e) => patch({ targetEffort: e.target.value })}\n placeholder=\"e.g. high, low\" className=\"h-8 text-xs\" />\n </label>\n </div>\n\n <div className=\"flex items-center gap-2\">\n <Switch checked={form.enabled} onCheckedChange={(enabled) => patch({ enabled })} />\n <span className=\"text-xs text-muted-foreground\">Enabled</span>\n </div>\n\n {error && <ErrorBanner message={error} />}\n\n <div className=\"flex gap-2\">\n <Button size=\"sm\" onClick={onSave}>\n <Save className=\"size-4\" />\n {isNew ? 'Add' : 'Save'}\n </Button>\n <Button size=\"sm\" variant=\"outline\" onClick={onCancel}>Cancel</Button>\n </div>\n </div>\n )\n}\n","import { useEffect, useMemo, useRef, useState } from 'react'\nimport type { ProviderCatalogEntry } from 'agent-relay-sdk/provider-catalog'\nimport { api, apiUpload } from '@/lib/api'\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/components/ui/button'\nimport { Badge } from '@/components/ui/badge'\nimport { Card, CardContent } from '@/components/ui/card'\nimport { AlertCircle, Camera, Globe2, RefreshCw, Route, Save, Trash2, Upload } from 'lucide-react'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport { Textarea } from '@/components/ui/textarea'\nimport { BrowserSettings } from '@/components/settings/browser-settings'\nimport { ModelCatalogSettings } from '@/components/settings/model-catalog-settings'\nimport { QuotaSettings } from '@/components/settings/quota-settings'\nimport { RoutingSettings } from '@/components/settings/routing-settings'\nimport { SchemaGroup } from '@/components/settings/schema-form'\nimport { UserAvatar } from '@/components/shared/user-avatar'\nimport { useRelayStore } from '@/store'\nimport {\n groupSettings,\n hasScope,\n settingId,\n type SettingEntry,\n} from '@/components/settings/schema-utils'\nimport type { Artifact, NotificationRoutingPreview, User } from '@/types'\n\ninterface SettingsResponse {\n settings: SettingEntry[]\n}\n\ninterface TokenMe {\n actor: string\n kind: string\n role?: string\n scopes: string[]\n}\n\ninterface ProvidersResponse {\n catalog: ProviderCatalogEntry[]\n}\n\ninterface NotificationPreviewResponse {\n preview: NotificationRoutingPreview\n}\n\nconst BROWSER_GROUP_SLUG = 'browser'\nconst MODELS_GROUP_SLUG = 'models'\nconst PROFILE_GROUP_SLUG = 'profile'\nconst ROUTING_GROUP_SLUG = 'routing'\nconst NOTIFICATION_TYPES = [\n 'branch.landed',\n 'landed-failure',\n 'agent.ready',\n 'agent.exited',\n 'agent.spawn_failed',\n 'agent.context_threshold',\n 'agent.quota_threshold',\n 'workspace.steward_task',\n 'workspace.conflict',\n 'workspace.review_request',\n]\n\nfunction settingsHash(): string {\n if (typeof window === 'undefined') return ''\n const hash = window.location.hash.replace(/^#/, '')\n if (!hash.startsWith('settings/')) return ''\n return decodeURIComponent(hash.slice('settings/'.length))\n}\n\nfunction writeSettingsHash(slug: string): void {\n if (typeof window === 'undefined') return\n const url = new URL(window.location.href)\n url.hash = `settings/${encodeURIComponent(slug)}`\n window.history.pushState({}, '', url)\n}\n\nexport function SettingsView() {\n const [settings, setSettings] = useState<SettingEntry[]>([])\n const [token, setToken] = useState<TokenMe | null>(null)\n const [catalog, setCatalog] = useState<ProviderCatalogEntry[]>([])\n const [active, setActive] = useState(() => settingsHash())\n const [loading, setLoading] = useState(true)\n const [loadError, setLoadError] = useState('')\n const [catalogError, setCatalogError] = useState('')\n\n async function reload() {\n setLoading(true)\n setLoadError('')\n setCatalogError('')\n try {\n const [settingsRes, tokenRes, providersRes] = await Promise.all([\n api<SettingsResponse>('GET', '/settings'),\n api<TokenMe>('GET', '/tokens/me'),\n api<ProvidersResponse>('GET', '/providers').catch((e) => {\n setCatalogError((e as Error).message)\n return { catalog: [] }\n }),\n ])\n setSettings(settingsRes.settings)\n setToken(tokenRes)\n setCatalog(providersRes.catalog)\n } catch (e) {\n setLoadError((e as Error).message)\n } finally {\n setLoading(false)\n }\n }\n\n useEffect(() => {\n void reload()\n }, [])\n\n // External sync: keep the selected settings group aligned with browser history.\n useEffect(() => {\n const sync = () => setActive(settingsHash())\n window.addEventListener('hashchange', sync)\n window.addEventListener('popstate', sync)\n return () => {\n window.removeEventListener('hashchange', sync)\n window.removeEventListener('popstate', sync)\n }\n }, [])\n\n const descriptorGroups = useMemo(() => groupSettings(settings), [settings])\n const groups = useMemo(() => [\n ...descriptorGroups.map((group) => ({\n slug: group.slug,\n label: group.group,\n description: `${group.settings.length} schema setting${group.settings.length === 1 ? '' : 's'}`,\n kind: 'descriptors' as const,\n settings: group.settings,\n })),\n {\n slug: ROUTING_GROUP_SLUG,\n label: 'Routing',\n description: 'Rules, quota thresholds, coordinator view',\n kind: 'routing' as const,\n settings: [],\n },\n {\n slug: PROFILE_GROUP_SLUG,\n label: 'Profile',\n description: 'Display name and avatar',\n kind: 'profile' as const,\n settings: [],\n },\n {\n slug: BROWSER_GROUP_SLUG,\n label: 'Browser',\n description: 'Local dashboard preferences',\n kind: 'browser' as const,\n settings: [],\n },\n {\n slug: MODELS_GROUP_SLUG,\n label: 'Models',\n description: 'Provider model catalog',\n kind: 'models' as const,\n settings: [],\n },\n ], [descriptorGroups])\n\n const activeGroup = groups.find((group) => group.slug === active) ?? groups[0]\n\n function selectGroup(slug: string) {\n setActive(slug)\n writeSettingsHash(slug)\n }\n\n function replaceSetting(updated: SettingEntry) {\n setSettings((current) => current.map((entry) => settingId(entry) === settingId(updated) ? updated : entry))\n }\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div>\n <h1 className=\"text-lg font-semibold\">Settings</h1>\n <p className=\"text-sm text-muted-foreground\">Schema-driven Relay settings, browser preferences, and model catalog controls.</p>\n </div>\n <div className=\"flex flex-wrap items-center gap-2\">\n {token && (\n <Badge variant=\"outline\" className=\"gap-1\">\n <Globe2 className=\"size-3\" />\n {token.kind}:{token.actor}\n </Badge>\n )}\n <Button variant=\"outline\" size=\"sm\" onClick={() => void reload()} disabled={loading}>\n <RefreshCw className={cn('size-4', loading && 'animate-spin')} />\n Refresh\n </Button>\n </div>\n </div>\n\n {loadError && (\n <div className=\"flex items-start gap-2 rounded-lg border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive\">\n <AlertCircle className=\"mt-0.5 size-4\" />\n <span>{loadError}</span>\n </div>\n )}\n\n <div className=\"grid gap-4 lg:grid-cols-[230px_minmax(0,1fr)]\">\n <nav className=\"space-y-1 lg:sticky lg:top-4 lg:self-start\">\n {groups.map((group) => (\n <button\n key={group.slug}\n type=\"button\"\n className={cn(\n 'w-full rounded-md border px-3 py-2 text-left text-sm transition-colors',\n activeGroup?.slug === group.slug ? 'border-primary/50 bg-primary/10 text-foreground' : 'border-transparent hover:border-border hover:bg-accent',\n )}\n onClick={() => selectGroup(group.slug)}\n >\n <span className=\"block font-medium\">{group.label}</span>\n <span className=\"block truncate text-xs text-muted-foreground\">{group.description}</span>\n </button>\n ))}\n </nav>\n\n <div className=\"min-w-0 space-y-4\">\n {loading && !settings.length ? (\n <Card size=\"sm\">\n <CardContent className=\"text-sm text-muted-foreground\">Loading settings…</CardContent>\n </Card>\n ) : activeGroup?.kind === 'routing' ? (\n <RoutingSettings canWrite={hasScope(token?.scopes, 'settings:write:routing')} />\n ) : activeGroup?.kind === 'descriptors' ? (\n <>\n <SchemaGroup\n group={activeGroup.label}\n settings={activeGroup.settings}\n onSaved={replaceSetting}\n />\n {/* Quota config block lives under the Providers group (#605). */}\n {activeGroup.label === 'Providers' && (\n <QuotaSettings canWrite={hasScope(token?.scopes, 'settings:write:provider')} />\n )}\n {activeGroup.label === 'Notifications' && (\n <NotificationRoutingPreviewPanel />\n )}\n </>\n ) : activeGroup?.kind === 'profile' ? (\n <ProfileSettings />\n ) : activeGroup?.kind === 'browser' ? (\n <BrowserSettings />\n ) : (\n <ModelCatalogSettings\n catalog={catalog}\n error={catalogError}\n canWrite={hasScope(token?.scopes, 'settings:write:provider')}\n onCatalog={setCatalog}\n />\n )}\n </div>\n </div>\n </div>\n )\n}\n\nfunction NotificationRoutingPreviewPanel() {\n const [type, setType] = useState('branch.landed')\n const [scopeText, setScopeText] = useState('{\\n \"repoRoot\": \"/repo\"\\n}')\n const [preview, setPreview] = useState<NotificationRoutingPreview | null>(null)\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState('')\n\n async function runPreview() {\n setLoading(true)\n setError('')\n try {\n const scope = JSON.parse(scopeText) as unknown\n if (!scope || typeof scope !== 'object' || Array.isArray(scope)) throw new Error('Scope must be a JSON object')\n const result = await api<NotificationPreviewResponse>('POST', '/notifications/preview', { type, scope })\n setPreview(result.preview)\n } catch (e) {\n setPreview(null)\n setError((e as Error).message)\n } finally {\n setLoading(false)\n }\n }\n\n return (\n <Card size=\"sm\">\n <CardContent className=\"space-y-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <div>\n <h2 className=\"text-sm font-semibold\">Who gets what</h2>\n <p className=\"text-xs text-muted-foreground\">Dry-run notification routing without sending.</p>\n </div>\n <Button size=\"sm\" onClick={() => void runPreview()} disabled={loading}>\n <Route className=\"size-4\" />\n Preview\n </Button>\n </div>\n <div className=\"grid gap-3 md:grid-cols-[240px_minmax(0,1fr)]\">\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium text-muted-foreground\">Type</label>\n <Select value={type} onValueChange={setType}>\n <SelectTrigger className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {NOTIFICATION_TYPES.map((item) => <SelectItem key={item} value={item}>{item}</SelectItem>)}\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium text-muted-foreground\">Scope</label>\n <Textarea value={scopeText} onChange={(e) => setScopeText(e.target.value)} rows={4} className=\"font-mono text-xs\" />\n </div>\n </div>\n {error && (\n <div className=\"flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/10 p-2 text-xs text-destructive\">\n <AlertCircle className=\"mt-0.5 size-3.5\" />\n <span>{error}</span>\n </div>\n )}\n {preview && (\n <div className=\"overflow-hidden rounded-md border border-border\">\n {preview.recipients.length === 0 ? (\n <div className=\"px-3 py-4 text-center text-xs text-muted-foreground\">No recipients</div>\n ) : preview.recipients.map((recipient) => (\n <div key={`${recipient.recipient}-${recipient.matchedRule}`} className=\"grid gap-1 border-b border-border px-3 py-2 text-xs last:border-b-0 md:grid-cols-[minmax(0,180px)_minmax(0,160px)_minmax(0,1fr)]\">\n <span className=\"truncate font-medium\">{recipient.recipient}</span>\n <span className=\"truncate font-mono text-muted-foreground\">{recipient.matchedRule}</span>\n <span className=\"truncate text-muted-foreground\">{recipient.reason}</span>\n </div>\n ))}\n </div>\n )}\n </CardContent>\n </Card>\n )\n}\n\nfunction ProfileSettings() {\n const fetchUsers = useRelayStore((s) => s.fetchUsers)\n const fileRef = useRef<HTMLInputElement>(null)\n const [user, setUser] = useState<User | null>(null)\n const [displayName, setDisplayName] = useState('')\n const [loading, setLoading] = useState(true)\n const [saving, setSaving] = useState(false)\n const [error, setError] = useState('')\n\n async function loadProfile() {\n setLoading(true)\n setError('')\n try {\n const next = await api<User>('GET', '/users/me')\n setUser(next)\n setDisplayName(next.displayName || next.handle)\n } catch (e) {\n setError((e as Error).message)\n } finally {\n setLoading(false)\n }\n }\n\n useEffect(() => {\n void loadProfile()\n }, [])\n\n async function saveProfile() {\n setSaving(true)\n setError('')\n try {\n const next = await api<User>('PATCH', '/users/me', { displayName })\n setUser(next)\n setDisplayName(next.displayName || next.handle)\n await fetchUsers()\n } catch (e) {\n setError((e as Error).message)\n } finally {\n setSaving(false)\n }\n }\n\n async function uploadAvatar(file: File | undefined) {\n if (!file) return\n setSaving(true)\n setError('')\n try {\n const res = await apiUpload<{ user: User; artifact: Artifact }>('/users/me/avatar', file)\n setUser(res.user)\n setDisplayName(res.user.displayName || res.user.handle)\n await fetchUsers()\n } catch (e) {\n setError((e as Error).message)\n } finally {\n setSaving(false)\n if (fileRef.current) fileRef.current.value = ''\n }\n }\n\n async function removeAvatar() {\n setSaving(true)\n setError('')\n try {\n const next = await api<User>('DELETE', '/users/me/avatar')\n setUser(next)\n await fetchUsers()\n } catch (e) {\n setError((e as Error).message)\n } finally {\n setSaving(false)\n }\n }\n\n return (\n <Card size=\"sm\">\n <CardContent className=\"space-y-4\">\n {error && (\n <div className=\"flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive\">\n <AlertCircle className=\"mt-0.5 size-4\" />\n <span>{error}</span>\n </div>\n )}\n <div className=\"flex flex-wrap items-center gap-4\">\n <UserAvatar user={user ?? undefined} distinct className=\"size-16 text-lg\" />\n <div className=\"min-w-0 flex-1 space-y-2\">\n <label className=\"block text-xs font-medium text-muted-foreground\" htmlFor=\"profile-display-name\">Display name</label>\n <input\n id=\"profile-display-name\"\n className=\"h-9 w-full rounded-md border border-input bg-background px-3 text-sm\"\n value={displayName}\n onChange={(e) => setDisplayName(e.target.value)}\n disabled={loading || saving}\n maxLength={120}\n />\n </div>\n </div>\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button size=\"sm\" onClick={() => void saveProfile()} disabled={loading || saving || !displayName.trim()}>\n <Save className=\"size-4\" />\n Save\n </Button>\n <Button size=\"sm\" variant=\"outline\" onClick={() => fileRef.current?.click()} disabled={loading || saving}>\n <Upload className=\"size-4\" />\n Upload\n </Button>\n <Button size=\"sm\" variant=\"outline\" onClick={() => void removeAvatar()} disabled={loading || saving || !user?.avatarArtifactId}>\n <Trash2 className=\"size-4\" />\n Remove\n </Button>\n {saving && <Camera className=\"size-4 animate-pulse text-muted-foreground\" />}\n <input\n ref={fileRef}\n type=\"file\"\n accept=\"image/png,image/jpeg,image/gif,image/webp\"\n className=\"hidden\"\n onChange={(e) => void uploadAvatar(e.target.files?.[0])}\n />\n </div>\n </CardContent>\n </Card>\n )\n}\n"],"mappings":"g1BAaA,SAAA,EAAA,EAAA,iCAIA,SAAA,GAAA,EAAA,mFAIA,SAAA,GAAA,EAAA,6FAIA,SAAA,GAAA,EAAA,yRAeA,SAAA,GAAA,EAAA,EAAA,gJAMA,SAAA,GAAA,EAAA,yDAIA,SAAA,GAAA,EAAA,gEAkBA,SAAA,GAAA,EAAA,EAAA,EAAA,2NAgBA,SAAA,GAAA,EAAA,wQAeA,SAAA,GAAA,EAAA,4DAIA,SAAA,GAAA,EAAA;MAIA,SAAA,GAAA,EAAA;MAKA,SAAA,GAAA,EAAA,6KCtFa,GAAQ,YAErB,SAAS,GAAU,EAA2B,CAG5C,OAFI,IAAS,iBAAyB,iBAClC,IAAS,YAAoB,YAC1B,UAGT,SAAS,GAAgB,EAA2B,CAGlD,OAFI,IAAS,iBAAyB,2DAClC,IAAS,YAAoB,gFAC1B,uCAGT,SAAS,GAAS,EAAmB,CAEnC,OADI,IAAS,WAAkB,EAAA,EAAA,KAAC,EAAD,CAAY,UAAU,WAAa,CAAA,EAC3D,EAAA,EAAA,KAAC,EAAD,CAAW,UAAU,WAAa,CAAA,CAG3C,SAAgB,EAAa,EAA0B,CACrD,OAAQ,EAAmB,SAAW,EAAE,CAG1C,SAAgB,GAAY,CAAE,QAAO,WAAU,WAAkG,CAC/I,IAAM,EAAQ,CAAC,GAAG,IAAI,IAAI,EAAS,IAAK,GAAY,EAAQ,KAAK,CAAC,CAAC,CACnE,OACE,EAAA,EAAA,MAAC,UAAD,CAAS,UAAU,qBAAnB,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,6DAAf,EACE,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,mCAA2B,EAAW,CAAA,EACpD,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,gCACZ,EAAM,IAAK,IACV,EAAA,EAAA,MAAC,EAAD,CAAkB,QAAQ,UAAU,UAAU,QAAQ,MAAO,GAAgB,EAAK,UAAlF,CACG,GAAS,EAAK,CACd,GAAU,EAAK,CACV,EAHI,EAGJ,CACR,CACE,CAAA,CACF,GACL,EAAS,SAAW,GACnB,EAAA,EAAA,KAAC,EAAD,CAAM,KAAK,eACT,EAAA,EAAA,KAAC,EAAD,CAAa,UAAU,yCAAgC,6BAAwC,CAAA,CAC1F,CAAA,EAEP,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,qBACZ,EAAS,IAAK,IACb,EAAA,EAAA,KAAC,GAAD,CAA+C,UAAkB,UAAW,CAA1D,EAAU,EAAQ,CAAwC,CAC5E,CACE,CAAA,CAEA,GAId,SAAS,GAAY,CAAE,UAAS,WAAgF,CAC9G,GAAM,CAAC,EAAO,IAAA,EAAA,EAAA,cAAoC,EAAQ,OAAS,EAAQ,UAAY,GAAsB,EAAQ,OAAO,CAAC,CACvH,CAAC,EAAQ,IAAA,EAAA,EAAA,UAAsB,GAAM,CACrC,CAAC,EAAQ,IAAA,EAAA,EAAA,UAAsB,GAAG,CAClC,CAAC,EAAQ,IAAA,EAAA,EAAA,UAAgC,EAAE,CAAC,CAC5C,EAAa,EAAQ,UAAY,EAAQ,OAAS,iBAExD,SAAS,EAAO,EAAY,EAAgB,CAC1C,EAAU,GAAqB,GAAe,EAAS,EAAM,EAAM,CAAC,CACpE,EAAU,EAAE,CAAC,CACb,EAAU,GAAG,CAGf,eAAe,GAAO,CACf,KAGL,CAFA,EAAU,GAAK,CACf,EAAU,EAAE,CAAC,CACb,EAAU,GAAG,CACb,GAAI,CACF,IAAM,EAAQ,MAAM,EAAkB,MAAO,GAAY,EAAQ,CAAE,CAAE,MAAO,EAAO,UAAW,YAAa,CAAC,CAC5G,EAAS,EAAM,MAAM,CACrB,EAAQ,EAAM,CACd,EAAU,QAAQ,OACX,EAAG,CACV,IAAM,EAAU,EAAa,EAAE,CAC/B,EAAU,EAAQ,OAAS,EAAU,CAAE,EAAY,QAAQ,CAAC,QACpD,CACR,EAAU,GAAM,GAIpB,OACE,EAAA,EAAA,MAAC,EAAD,CAAM,KAAK,cAAX,EACE,EAAA,EAAA,MAAC,EAAD,CAAA,SAAA,EACE,EAAA,EAAA,MAAC,EAAD,CAAW,UAAU,qDAArB,CACG,EAAQ,QAAQ,OACjB,EAAA,EAAA,MAAC,EAAD,CAAO,QAAQ,UAAU,UAAU,QAAQ,MAAO,GAAgB,EAAQ,KAAK,UAA/E,CAAkF,GAAS,EAAQ,KAAK,CAAE,GAAU,EAAQ,KAAK,CAAS,GACzI,CAAC,EAAQ,WAAY,EAAA,EAAA,KAAC,EAAD,CAAO,QAAQ,qBAAY,YAAiB,CAAA,CACxD,GACX,EAAQ,QAAQ,cAAe,EAAA,EAAA,KAAC,EAAD,CAAA,SAAkB,EAAQ,QAAQ,YAA8B,CAAA,EAChG,EAAA,EAAA,KAAC,GAAD,CAAA,UACE,EAAA,EAAA,MAAC,EAAD,CAAQ,KAAK,KAAK,QAAS,EAAM,SAAU,CAAC,GAAc,WAA1D,EACE,EAAA,EAAA,KAAC,EAAD,CAAM,UAAU,SAAW,CAAA,CAC1B,EAAS,SAAW,OACd,GACE,CAAA,CACF,CAAA,CAAA,EAEb,EAAA,EAAA,MAAC,EAAD,CAAa,UAAU,qBAAvB,EACE,EAAA,EAAA,KAAC,GAAD,CACE,OAAQ,EAAQ,OAChB,MAAO,EACP,KAAM,EAAE,CACR,MAAO,EAAQ,QAAQ,MACvB,SAAA,GACA,SAAU,CAAC,GAAc,EACzB,SAAU,EACV,CAAA,EAEF,EAAA,EAAA,MAAC,IAAD,CAAG,UAAU,iFAAb,EACE,EAAA,EAAA,MAAC,OAAD,CAAM,UAAU,oDAAhB,CAA4D,EAAQ,UAAU,IAAE,EAAQ,IAAW,IACnG,EAAA,EAAA,MAAC,OAAD,CAAA,SAAA,CAAM,SAAK,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,8BAAsB,EAAQ,MAAM,KAAY,CAAA,CAAO,CAAA,CAAA,EAClF,EAAA,EAAA,KAAC,OAAD,CAAM,cAAA,YAAY,IAAQ,CAAA,EAC1B,EAAA,EAAA,MAAC,OAAD,CAAA,SAAA,CAAM,UAAM,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,8BAAsB,EAAQ,MAAM,MAAa,CAAA,CAAO,CAAA,CAAA,CAClF,GAEH,EAAO,OAAS,IACf,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,kGAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,oDAAf,EAA0D,EAAA,EAAA,KAAC,EAAD,CAAa,UAAU,SAAW,CAAA,CAAA,cAAiB,IAC7G,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,oCACX,EAAO,IAAK,IAAW,EAAA,EAAA,KAAC,KAAD,CAAA,SAAkB,EAAY,CAArB,EAAqB,CAAC,CACpD,CAAA,CACD,GAEP,IAAU,EAAA,EAAA,MAAC,IAAD,CAAG,UAAU,4DAAb,EAAgE,EAAA,EAAA,KAAC,EAAD,CAAc,UAAU,SAAW,CAAA,CAAC,EAAW,GAC9G,GACT,GAIX,SAAS,GAAY,EAQlB,CACD,GAAM,CAAE,SAAQ,QAAO,OAAM,QAAO,WAAU,WAAU,YAAa,EAC/D,EAAO,GAAW,EAAO,CAE/B,GAAI,EAAO,MAAM,OAAQ,CACvB,IAAM,EAAU,GAAiC,MAAQ,IAAU,GAAK,GAAQ,OAAO,EAAM,CAC7F,OACE,EAAA,EAAA,KAAC,EAAD,CAAc,QAAO,YAAa,EAAO,sBACvC,EAAA,EAAA,MAAC,EAAD,CAAQ,MAAO,EAAS,cAAgB,GAAS,EAAS,EAAM,IAAA,YAAiB,IAAA,GAAY,EAAK,CAAY,oBAA9G,EACE,EAAA,EAAA,KAAC,EAAD,CAAA,UAAe,EAAA,EAAA,KAAC,EAAD,EAAe,CAAA,CAAgB,CAAA,EAC9C,EAAA,EAAA,MAAC,EAAD,CAAA,SAAA,CACG,CAAC,IAAY,EAAA,EAAA,KAAC,EAAD,CAAY,MAAA,qBAAc,UAAoB,CAAA,CAC3D,EAAO,KAAK,IAAK,IAAS,EAAA,EAAA,KAAC,EAAD,CAA+B,MAAO,OAAO,EAAK,UAAG,OAAO,EAAK,CAAc,CAA9D,OAAO,EAAK,CAAkD,CAAC,CAC7F,CAAA,CAAA,CACT,GACH,CAAA,CAIZ,GAAI,IAAS,UACX,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,qFAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,+BAAuB,EAAY,CAAA,CACjD,EAAO,cAAe,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,yCAAiC,EAAO,YAAkB,CAAA,CAC5F,CAAA,CAAA,EACN,EAAA,EAAA,KAAC,EAAD,CAAQ,QAAS,EAAQ,EAAQ,gBAAkB,GAAS,EAAS,EAAM,EAAK,CAAY,WAAY,CAAA,CACpG,GAIV,GAAI,IAAS,WAAa,IAAS,SACjC,OACE,EAAA,EAAA,KAAC,EAAD,CAAc,QAAO,YAAa,EAAO,sBACvC,EAAA,EAAA,KAAC,EAAD,CACE,KAAK,SACL,IAAK,OAAO,EAAO,SAAY,SAAW,EAAO,QAAU,IAAA,GAC3D,IAAK,OAAO,EAAO,SAAY,SAAW,EAAO,QAAU,IAAA,GAC3D,KAAM,IAAS,UAAY,EAAI,MAC/B,MAAO,OAAO,GAAU,SAAW,EAAQ,GACjC,WACV,SAAW,GAAM,EAAS,EAAM,EAAE,OAAO,QAAU,IAAM,CAAC,EAAW,IAAA,GAAY,OAAO,EAAE,OAAO,MAAM,CAAC,CACxG,CAAA,CACI,CAAA,CAIZ,GAAI,IAAS,QACX,OACE,EAAA,EAAA,KAAC,EAAD,CAAc,QAAO,YAAa,EAAO,aAAe,+BACtD,EAAA,EAAA,KAAC,GAAD,CACE,KAAM,KAAK,IAAI,EAAG,KAAK,IAAI,EAAG,MAAM,QAAQ,EAAM,CAAG,EAAM,OAAS,EAAI,EAAE,CAAC,CAC3E,MAAO,GAAU,EAAM,CACb,WACV,SAAW,GAAM,EAAS,EAAM,GAAM,EAAE,OAAO,MAAM,CAAC,CACtD,CAAA,CACI,CAAA,CAIZ,GAAI,IAAS,SAAU,CACrB,IAAM,EAAa,EAAO,YAAc,EAAE,CACpC,EAAe,IAAI,IAAI,EAAO,UAAY,EAAE,CAAC,CAQnD,OAPI,OAAO,KAAK,EAAW,CAAC,SAAW,GAAK,EAAO,sBAE/C,EAAA,EAAA,KAAC,EAAD,CAAc,QAAO,YAAa,EAAO,aAAe,2CACtD,EAAA,EAAA,KAAC,GAAD,CAAU,KAAM,EAAG,MAAO,GAAW,EAAM,CAAY,WAAU,SAAW,GAAM,EAAS,EAAM,GAAgB,EAAE,OAAO,MAAM,CAAC,CAAI,CAAA,CAC/H,CAAA,EAIV,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,qBAAf,CACG,EAAK,OAAS,IACb,EAAA,EAAA,MAAC,MAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,+BAAuB,EAAY,CAAA,CACjD,EAAO,cAAe,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,yCAAiC,EAAO,YAAkB,CAAA,CAC5F,CAAA,CAAA,EAER,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,qCACZ,OAAO,QAAQ,EAAW,CAAC,KAAK,CAAC,EAAK,KAAW,CAChD,IAAM,EAAa,GAAS,EAAM,CAAG,EAAM,GAAO,IAAA,GAClD,OACE,EAAA,EAAA,KAAC,GAAD,CAEE,OAAQ,EACR,MAAO,IAAe,IAAA,IAAa,EAAa,IAAI,EAAI,CAAG,GAAsB,EAAM,CAAG,EAC1F,KAAM,CAAC,GAAG,EAAM,EAAI,CACpB,MAAO,EAAM,OAAS,GAAY,EAAI,CACtC,SAAU,EAAa,IAAI,EAAI,CACrB,WACA,WACV,CARK,EAQL,EAEJ,CACE,CAAA,CACF,GAIV,OACE,EAAA,EAAA,KAAC,EAAD,CAAc,QAAO,YAAa,EAAO,sBACvC,EAAA,EAAA,KAAC,EAAD,CACE,MAAO,OAAO,GAAU,SAAW,EAAQ,GAAS,KAAO,GAAK,OAAO,EAAM,CACnE,WACV,SAAW,GAAM,EAAS,EAAM,EAAE,OAAO,QAAU,IAAM,CAAC,EAAW,IAAA,GAAY,EAAE,OAAO,MAAM,CAChG,CAAA,CACI,CAAA,CAIZ,SAAgB,EAAM,CAAE,QAAO,cAAa,YAA0E,CACpH,OACE,EAAA,EAAA,MAAC,QAAD,CAAO,UAAU,qCAAjB,EACE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,iCAAyB,EAAa,CAAA,CACrD,EACA,IAAe,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,+CAAuC,EAAmB,CAAA,CACpF,GAIZ,SAAS,GAAY,EAAqB,CACxC,OAAO,EAAI,QAAQ,qBAAsB,QAAQ,CAAC,QAAQ,SAAU,IAAI,CAAC,QAAQ,MAAQ,GAAS,EAAK,aAAa,CAAC,CCpRvH,SAAgB,IAAkB,CAChC,IAAM,EAAQ,EAAe,GAAM,EAAE,MAAM,CACrC,EAAgB,EAAe,GAAM,EAAE,cAAc,CACrD,EAAM,EAAe,GAAM,EAAE,IAAI,CACvC,OACE,EAAA,EAAA,MAAC,UAAD,CAAS,UAAU,qBAAnB,EACE,EAAA,EAAA,MAAC,MAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,mCAA0B,sBAAwB,CAAA,EAChE,EAAA,EAAA,KAAC,IAAD,CAAG,UAAU,yCAAgC,yEAA0E,CAAA,CACnH,CAAA,CAAA,EACN,EAAA,EAAA,MAAC,EAAD,CAAM,KAAK,cAAX,EACE,EAAA,EAAA,MAAC,EAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,EAAD,CAAW,UAAU,mBAAU,oBAA6B,CAAA,EAC5D,EAAA,EAAA,KAAC,EAAD,CAAiB,UAAU,mBAAU,oDAAmE,CAAA,EACxG,EAAA,EAAA,KAAC,GAAD,CAAA,UACE,EAAA,EAAA,MAAC,EAAD,CAAO,QAAQ,UAAU,UAAU,iBAAnC,EAA2C,EAAA,EAAA,KAAC,EAAD,CAAY,UAAU,WAAa,CAAA,CAAA,UAAe,GAClF,CAAA,CACF,CAAA,CAAA,EACb,EAAA,EAAA,MAAC,EAAD,CAAa,UAAU,qCAAvB,EACE,EAAA,EAAA,KAAC,EAAD,CAAO,MAAM,kBACX,EAAA,EAAA,MAAC,EAAD,CAAQ,MAAO,EAAO,cAAgB,GAAU,EAAI,CAAE,MAAO,EAAkB,CAAC,UAAhF,EACE,EAAA,EAAA,KAAC,EAAD,CAAA,UAAe,EAAA,EAAA,KAAC,EAAD,EAAe,CAAA,CAAgB,CAAA,EAC9C,EAAA,EAAA,KAAC,EAAD,CAAA,SACG,GAAO,IAAK,IAAS,EAAA,EAAA,KAAC,EAAD,CAA0B,MAAO,EAAK,YAAK,EAAK,MAAmB,CAAlD,EAAK,GAA6C,CAAC,CAC5E,CAAA,CACT,GACH,CAAA,EACR,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,qFAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,mCAAf,EACE,EAAA,EAAA,KAAC,EAAD,CAAO,UAAU,SAAW,CAAA,EAC5B,EAAA,EAAA,MAAC,MAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,+BAAsB,yBAA4B,CAAA,EACjE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,yCAAgC,uHAA0H,CAAA,CACrK,CAAA,CAAA,CACF,IACN,EAAA,EAAA,KAAC,EAAD,CAAQ,QAAS,EAAe,gBAAkB,GAAU,EAAI,CAAE,cAAe,EAAO,CAAC,CAAI,CAAA,CACzF,GACM,GACT,IACP,EAAA,EAAA,KAAC,GAAD,EAAiB,CAAA,CACT,GAId,SAAS,IAAgB,CACvB,IAAM,EAAkB,EAAe,GAAM,EAAE,gBAAgB,CACzD,EAAqB,EAAe,GAAM,EAAE,mBAAmB,CAC/D,EAAe,EAAe,GAAM,EAAE,aAAa,CACnD,EAAkB,EAAe,GAAM,EAAE,gBAAgB,CACzD,EAAsB,EAAe,GAAM,EAAE,oBAAoB,CACjE,EAAyB,EAAe,GAAM,EAAE,uBAAuB,CACvE,EAAuB,EAAe,GAAM,EAAE,qBAAqB,CACnE,EAA0B,EAAe,GAAM,EAAE,wBAAwB,CACzE,EAAiB,EAAe,GAAM,EAAE,eAAe,CACvD,EAAoB,EAAe,GAAM,EAAE,kBAAkB,CAG7D,CAAC,EAAe,IAAA,EAAA,EAAA,cAAmC,GAAuB,CAAC,EACjF,EAAA,EAAA,eAAgB,CACd,GAAI,OAAO,OAAW,KAAe,EAAE,oBAAqB,QAAS,OACrE,IAAM,MAAgB,EAAiB,GAAuB,CAAC,CAG/D,OAFA,GAAS,CACT,OAAO,gBAAgB,mBAAmB,gBAAiB,EAAQ,KACtD,OAAO,gBAAgB,sBAAsB,gBAAiB,EAAQ,EAClF,EAAE,CAAC,CAEN,IAAM,EAAgB,GAAc,KAAM,GAAU,EAAM,KAAO,EAAoB,CACjF,GACA,CAAC,GAAG,GAAe,CAAE,GAAI,EAAqB,MAAO,EAAqB,CAAC,CAE/E,OACE,EAAA,EAAA,MAAC,EAAD,CAAM,KAAK,cAAX,EACE,EAAA,EAAA,MAAC,EAAD,CAAA,SAAA,EACE,EAAA,EAAA,MAAC,EAAD,CAAW,UAAU,2CAArB,EAAuD,EAAA,EAAA,KAAC,EAAD,CAAS,UAAU,SAAW,CAAA,CAAA,QAAiB,IACtG,EAAA,EAAA,KAAC,EAAD,CAAiB,UAAU,mBAAU,8CAA6D,CAAA,EAClG,EAAA,EAAA,KAAC,GAAD,CAAA,UACE,EAAA,EAAA,KAAC,EAAD,CAAQ,QAAS,EAAiB,gBAAiB,EAAsB,CAAA,CAC9D,CAAA,CACF,CAAA,CAAA,EACb,EAAA,EAAA,MAAC,EAAD,CAAa,UAAU,qCAAvB,EACE,EAAA,EAAA,KAAC,EAAD,CAAO,MAAM,0BACX,EAAA,EAAA,MAAC,EAAD,CAAQ,MAAO,EAAc,cAAgB,GAAU,EAAgB,EAA8B,UAArG,EACE,EAAA,EAAA,KAAC,EAAD,CAAA,UAAe,EAAA,EAAA,KAAC,EAAD,EAAe,CAAA,CAAgB,CAAA,EAC9C,EAAA,EAAA,MAAC,EAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,EAAD,CAAY,MAAM,kBAAS,uCAAiD,CAAA,EAC5E,EAAA,EAAA,KAAC,EAAD,CAAY,MAAM,mBAAU,yBAAmC,CAAA,CACjD,CAAA,CAAA,CACT,GACH,CAAA,EACR,EAAA,EAAA,KAAC,EAAD,CAAO,MAAM,yBACX,EAAA,EAAA,MAAC,EAAD,CAAQ,MAAO,EAAqB,cAAe,WAAnD,EACE,EAAA,EAAA,KAAC,EAAD,CAAA,UAAe,EAAA,EAAA,KAAC,EAAD,EAAe,CAAA,CAAgB,CAAA,EAC9C,EAAA,EAAA,KAAC,EAAD,CAAA,SACG,EAAc,IAAK,IAAU,EAAA,EAAA,KAAC,EAAD,CAA2B,MAAO,EAAM,YAAK,EAAM,MAAmB,CAArD,EAAM,GAA+C,CAAC,CACvF,CAAA,CACT,GACH,CAAA,EACR,EAAA,EAAA,KAAC,EAAD,CAAO,MAAM,0BACX,EAAA,EAAA,MAAC,EAAD,CAAQ,MAAO,GAAA,YAA+B,cAAgB,GAAU,EAAwB,IAAA,YAAkB,GAAK,EAAM,UAA7H,EACE,EAAA,EAAA,KAAC,EAAD,CAAA,UAAe,EAAA,EAAA,KAAC,EAAD,EAAe,CAAA,CAAgB,CAAA,EAC9C,EAAA,EAAA,MAAC,EAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,EAAD,CAAY,MAAO,YAAO,iBAA2B,CAAA,CACpD,EAAc,IAAK,IAAU,EAAA,EAAA,KAAC,EAAD,CAA4B,MAAO,EAAM,aAAM,EAAM,MAAmB,CAAvD,EAAM,IAAiD,CAAC,CACzF,CAAA,CAAA,CACT,GACH,CAAA,EACR,EAAA,EAAA,KAAC,EAAD,CAAO,MAAM,+BACX,EAAA,EAAA,MAAC,EAAD,CAAQ,MAAO,EAAgB,cAAgB,GAAU,EAAkB,EAA8C,UAAzH,EACE,EAAA,EAAA,KAAC,EAAD,CAAA,UAAe,EAAA,EAAA,KAAC,EAAD,EAAe,CAAA,CAAgB,CAAA,EAC9C,EAAA,EAAA,MAAC,EAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,EAAD,CAAY,MAAM,mBAAU,mBAA6B,CAAA,EACzD,EAAA,EAAA,KAAC,EAAD,CAAY,MAAM,oBAAW,mBAA6B,CAAA,CAC5C,CAAA,CAAA,CACT,GACH,CAAA,CACI,GACT,GChGX,SAAgB,GAAqB,CACnC,UACA,QACA,WACA,aAMC,CACD,IAAM,EAAgB,EAAQ,IAAI,UAAY,GACxC,CAAC,EAAU,IAAA,EAAA,EAAA,UAAuC,EAAc,CAChE,CAAC,EAAM,IAAA,EAAA,EAAA,cAAqC,GAAe,EAAc,CAAC,CAC1E,CAAC,EAAQ,IAAA,EAAA,EAAA,UAAsB,GAAG,CAClC,CAAC,EAAQ,IAAA,EAAA,EAAA,UAAgC,EAAE,CAAC,CAE5C,EAAmB,EAAQ,KAAM,GAAU,EAAM,WAAa,EAAS,CAAG,EAAW,EACrF,EAAkB,EAAQ,KAAM,GAAU,EAAM,WAAa,EAAiB,EAAI,EAAQ,GAC1F,EAAY,EAAQ,IAAK,GAAU,EAAM,SAAS,CAExD,SAAS,EAAW,EAA2B,CAC7C,EAAS,IAAa,CAAE,GAAG,EAAS,GAAG,EAAO,EAAE,CAChD,EAAU,EAAE,CAAC,CACb,EAAU,GAAG,CAGf,SAAS,EAAe,EAAqB,CAC3C,EAAY,EAAK,CACjB,EAAQ,GAAe,EAAK,CAAC,CAC7B,EAAU,EAAE,CAAC,CACb,EAAU,GAAG,CAGf,eAAe,GAAgB,CAE7B,GAAU,MADQ,EAAuB,MAAO,aAAa,EAC/C,QAAQ,CAGxB,eAAe,IAAY,CACpB,KAEL,CADA,EAAU,EAAE,CAAC,CACb,EAAU,GAAG,CACb,GAAI,CACF,MAAM,EAAI,MAAO,cAAc,mBAAmB,EAAK,SAAS,CAAC,UAAU,mBAAmB,EAAK,MAAM,GAAI,CAC3G,MAAO,EAAK,MACZ,cAAe,EAAK,cACpB,QAAS,GAAM,EAAK,QAAQ,CAC5B,cAAe,EAAK,cAAc,MAAM,EAAI,IAAA,GAC5C,OAAQ,EAAK,OACb,aAAc,EAAK,aACnB,iBAAkB,GAAyB,EAAK,CAChD,SAAU,EAAK,SACf,UAAW,YACZ,CAAC,CACF,MAAM,GAAe,CACrB,EAAU,GAAG,EAAK,MAAM,QAAQ,CAChC,EAAQ,GAAe,EAAK,SAAS,CAAC,OAC/B,EAAG,CACV,IAAM,EAAU,EAAa,EAAE,CAC/B,EAAU,EAAQ,OAAS,EAAU,CAAE,EAAY,QAAQ,CAAC,GAIhE,eAAe,GAAY,EAAkC,EAAmB,CACzE,KAEL,CADA,EAAU,EAAE,CAAC,CACb,EAAU,GAAG,CACb,GAAI,CACF,MAAM,EAAI,QAAS,cAAc,mBAAmB,EAAiB,CAAC,UAAU,mBAAmB,EAAM,MAAM,GAAI,CAAE,WAAU,UAAW,YAAa,CAAC,CACxJ,MAAM,GAAe,CACrB,EAAU,GAAG,EAAM,MAAM,GAAG,EAAW,WAAa,YAAY,OACzD,EAAG,CACV,IAAM,EAAU,EAAa,EAAE,CAC/B,EAAU,EAAQ,OAAS,EAAU,CAAE,EAAY,QAAQ,CAAC,GAIhE,eAAe,EAAY,EAAkC,CACtD,KAEL,CADA,EAAU,EAAE,CAAC,CACb,EAAU,GAAG,CACb,GAAI,CACF,MAAM,EAAI,SAAU,cAAc,mBAAmB,EAAiB,CAAC,UAAU,mBAAmB,EAAM,MAAM,GAAG,CACnH,MAAM,GAAe,CACrB,EAAU,GAAG,EAAM,MAAM,UAAU,OAC5B,EAAG,CACV,IAAM,EAAU,EAAa,EAAE,CAC/B,EAAU,EAAQ,OAAS,EAAU,CAAE,EAAY,QAAQ,CAAC,GAIhE,SAAS,GAAU,EAAkC,CACnD,EAAQ,CACN,SAAU,EACV,MAAO,EAAM,MACb,MAAO,EAAM,MACb,cAAe,EAAM,cACrB,QAAS,EAAM,QAAQ,KAAK,KAAK,CACjC,cAAe,EAAM,eAAiB,GACtC,uBAAwB,EAAM,kBAAkB,wBAAwB,UAAU,EAAI,GACtF,gBAAiB,EAAM,kBAAkB,iBAAiB,UAAU,EAAI,GACxE,wBAAyB,EAAM,kBAAkB,yBAAyB,UAAU,EAAI,GACxF,SAAU,EAAQ,EAAM,SACxB,OAAQ,EAAM,OACd,aAAc,EAAM,aACrB,CAAC,CACF,EAAU,EAAE,CAAC,CACb,EAAU,GAAG,CAcf,OAXI,GAEA,EAAA,EAAA,KAAC,EAAD,CAAM,KAAK,eACT,EAAA,EAAA,MAAC,EAAD,CAAa,UAAU,yCAAvB,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,oEAAf,EAA0E,EAAA,EAAA,KAAC,EAAD,CAAmB,UAAU,SAAW,CAAA,CAAA,gBAAmB,GACpI,EACW,GACT,CAAA,EAKT,EAAA,EAAA,MAAC,UAAD,CAAS,UAAU,qBAAnB,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,4DAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,mCAA0B,gBAAkB,CAAA,EAC1D,EAAA,EAAA,KAAC,IAAD,CAAG,UAAU,yCAAgC,uGAAwG,CAAA,CACjJ,CAAA,CAAA,CACL,CAAC,IAAY,EAAA,EAAA,KAAC,EAAD,CAAO,QAAQ,qBAAY,2CAAgD,CAAA,CACrF,IAEN,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,gCACZ,EAAU,IAAK,IACd,EAAA,EAAA,KAAC,EAAD,CAAmB,QAAS,IAAS,EAAmB,UAAY,UAAW,KAAK,KAAK,YAAe,EAAe,EAAK,UACzH,EACM,CAFI,EAEJ,CACT,CACE,CAAA,EAEN,EAAA,EAAA,MAAC,EAAD,CAAM,KAAK,cAAX,EACE,EAAA,EAAA,MAAC,EAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,EAAD,CAAW,UAAU,mBAAU,oBAA6B,CAAA,EAC5D,EAAA,EAAA,KAAC,GAAD,CAAA,UACE,EAAA,EAAA,MAAC,EAAD,CAAO,QAAQ,UAAU,UAAU,iBAAnC,EAA2C,EAAA,EAAA,KAAC,EAAD,CAAW,UAAU,WAAa,CAAA,CAAA,iBAAsB,GACxF,CAAA,CACF,CAAA,CAAA,EACb,EAAA,EAAA,MAAC,EAAD,CAAa,UAAU,qBAAvB,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,qCAAf,EACE,EAAA,EAAA,KAAC,EAAD,CAAO,MAAM,kBACb,EAAA,EAAA,KAAC,EAAD,CAAO,MAAO,EAAK,MAAO,SAAU,CAAC,EAAU,YAAY,UAAU,SAAW,GAAM,EAAW,CAAE,MAAO,EAAE,OAAO,MAAM,MAAM,CAAE,CAAC,CAAI,CAAA,CAChI,CAAA,EACR,EAAA,EAAA,KAAC,EAAD,CAAO,MAAM,kBACX,EAAA,EAAA,KAAC,EAAD,CAAO,MAAO,EAAK,MAAO,SAAU,CAAC,EAAU,YAAY,gBAAgB,SAAW,GAAM,EAAW,CAAE,MAAO,EAAE,OAAO,MAAO,CAAC,CAAI,CAAA,CAC/H,CAAA,EACR,EAAA,EAAA,KAAC,EAAD,CAAO,MAAM,2BACX,EAAA,EAAA,KAAC,EAAD,CAAO,MAAO,EAAK,cAAe,SAAU,CAAC,EAAU,YAAY,gBAAgB,SAAW,GAAM,EAAW,CAAE,cAAe,EAAE,OAAO,MAAO,CAAC,CAAI,CAAA,CAC/I,CAAA,EACR,EAAA,EAAA,KAAC,EAAD,CAAO,MAAM,oBACX,EAAA,EAAA,KAAC,EAAD,CAAO,MAAO,EAAK,QAAS,SAAU,CAAC,EAAU,YAAY,oBAAoB,SAAW,GAAM,EAAW,CAAE,QAAS,EAAE,OAAO,MAAO,CAAC,CAAI,CAAA,CACvI,CAAA,EACR,EAAA,EAAA,KAAC,EAAD,CAAO,MAAM,2BACX,EAAA,EAAA,KAAC,EAAD,CAAO,MAAO,EAAK,cAAe,SAAU,CAAC,EAAU,YAAY,SAAS,SAAW,GAAM,EAAW,CAAE,cAAe,EAAE,OAAO,MAAO,CAAC,CAAI,CAAA,CACxI,CAAA,EACR,EAAA,EAAA,KAAC,EAAD,CAAO,MAAM,qCACX,EAAA,EAAA,KAAC,EAAD,CAAO,MAAO,EAAK,uBAAwB,SAAU,CAAC,EAAU,YAAY,OAAO,UAAU,UAAU,SAAW,GAAM,EAAW,CAAE,uBAAwB,EAAE,OAAO,MAAO,CAAC,CAAI,CAAA,CAC5K,CAAA,EACR,EAAA,EAAA,KAAC,EAAD,CAAO,MAAM,6BACX,EAAA,EAAA,KAAC,EAAD,CAAO,MAAO,EAAK,gBAAiB,SAAU,CAAC,EAAU,YAAY,uBAAuB,UAAU,UAAU,SAAW,GAAM,EAAW,CAAE,gBAAiB,EAAE,OAAO,MAAO,CAAC,CAAI,CAAA,CAC9K,CAAA,EACR,EAAA,EAAA,KAAC,EAAD,CAAO,MAAM,sCACX,EAAA,EAAA,KAAC,EAAD,CAAO,MAAO,EAAK,wBAAyB,SAAU,CAAC,EAAU,YAAY,OAAO,UAAU,UAAU,SAAW,GAAM,EAAW,CAAE,wBAAyB,EAAE,OAAO,MAAO,CAAC,CAAI,CAAA,CAC9K,CAAA,EACN,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,qFAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,+BAAsB,WAAc,CAAA,EACnD,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,yCAAgC,iDAAoD,CAAA,CAC/F,CAAA,CAAA,EACN,EAAA,EAAA,KAAC,EAAD,CAAQ,QAAS,EAAK,SAAU,SAAU,CAAC,EAAU,gBAAkB,GAAa,EAAW,CAAE,WAAU,CAAC,CAAI,CAAA,CAC5G,GACF,IACN,EAAA,EAAA,MAAC,EAAD,CAAQ,QAAS,GAAW,SAAU,CAAC,GAAY,CAAC,EAAK,OAAS,CAAC,EAAK,OAAS,CAAC,EAAK,uBAAvF,EACE,EAAA,EAAA,KAAC,EAAD,CAAM,UAAU,SAAW,CAAA,CAAA,aAEpB,GACG,GACT,IAEP,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,qBAAf,CACG,GAAmB,EAAgB,OAAO,SAAW,IACpD,EAAA,EAAA,KAAC,EAAD,CAAM,KAAK,eACT,EAAA,EAAA,KAAC,EAAD,CAAa,UAAU,yCAAgC,0CAAqD,CAAA,CACvG,CAAA,CAER,GAAiB,OAAO,IAAK,IAC5B,EAAA,EAAA,KAAC,EAAD,CAAwB,KAAK,eAC3B,EAAA,EAAA,MAAC,EAAD,CAAa,UAAU,6DAAvB,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,mBAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,6CAAf,EACE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,uBAAe,EAAM,MAAa,CAAA,EAClD,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,4DAAoD,EAAM,MAAa,CAAA,CACtF,EAAM,WAAY,EAAA,EAAA,KAAC,EAAD,CAAO,QAAQ,qBAAY,WAAgB,CAAA,CAC1D,IACN,EAAA,EAAA,MAAC,IAAD,CAAG,UAAU,8CAAb,CACG,EAAM,cACN,EAAM,QAAQ,OAAS,EAAI,cAAc,EAAM,QAAQ,KAAK,KAAK,GAAK,sBACtE,EAAM,cAAgB,cAAc,EAAM,gBAAkB,GAC5D,cAAc,GAAe,EAAM,GAClC,GACA,IACN,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,gCAAf,EACE,EAAA,EAAA,MAAC,EAAD,CAAQ,QAAQ,UAAU,KAAK,KAAK,YAAe,GAAU,EAAM,UAAnE,EACE,EAAA,EAAA,KAAC,EAAD,CAAQ,UAAU,SAAW,CAAA,CAAA,OAEtB,IACT,EAAA,EAAA,MAAC,EAAD,CAAQ,QAAQ,UAAU,KAAK,KAAK,SAAU,CAAC,EAAU,YAAe,KAAK,GAAY,EAAO,CAAC,EAAM,SAAS,UAAhH,CACG,EAAM,UAAW,EAAA,EAAA,KAAC,EAAD,CAAK,UAAU,SAAW,CAAA,EAAG,EAAA,EAAA,KAAC,EAAD,CAAQ,UAAU,SAAW,CAAA,CAC3E,EAAM,SAAW,SAAW,UACtB,IACT,EAAA,EAAA,MAAC,EAAD,CAAQ,QAAQ,UAAU,KAAK,KAAK,SAAU,CAAC,EAAU,YAAe,KAAK,EAAY,EAAM,UAA/F,EACE,EAAA,EAAA,KAAC,EAAD,CAAQ,UAAU,SAAW,CAAA,CAAA,SAEtB,GACL,GACM,GACT,CA9BI,EAAM,MA8BV,CACP,CACE,GAEL,EAAO,OAAS,IACf,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,mGACb,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,oCACX,EAAO,IAAK,IAAW,EAAA,EAAA,KAAC,KAAD,CAAA,SAAkB,EAAY,CAArB,EAAqB,CAAC,CACpD,CAAA,CACD,CAAA,CAEP,IAAU,EAAA,EAAA,MAAC,IAAD,CAAG,UAAU,4DAAb,EAAgE,EAAA,EAAA,KAAC,EAAD,CAAc,UAAU,SAAW,CAAA,CAAC,EAAW,GAClH,GAId,SAAS,GAAe,EAAoC,CAC1D,MAAO,CAAE,WAAU,MAAO,GAAI,MAAO,GAAI,cAAe,GAAI,QAAS,GAAI,cAAe,GAAI,uBAAwB,GAAI,gBAAiB,GAAI,wBAAyB,GAAI,SAAU,GAAO,CAG7L,SAAS,GAAyB,EAA4E,CAC5G,IAAM,EAAyB,GAAe,EAAK,uBAAwB,2BAA2B,CAChG,EAAkB,GAAe,EAAK,gBAAiB,mBAAmB,CAC1E,EAA0B,GAAe,EAAK,wBAAyB,4BAA4B,CACrG,SAA2B,IAAA,IAAa,IAAoB,IAAA,IAAa,IAA4B,IAAA,IACzG,IAAI,IAA2B,IAAA,GAAW,MAAU,MAAM,uEAAuE,CACjI,MAAO,CACL,yBACA,GAAI,IAAoB,IAAA,GAAkC,EAAE,CAAxB,CAAE,kBAAiB,CACvD,GAAI,IAA4B,IAAA,GAA0C,EAAE,CAAhC,CAAE,0BAAyB,CACxE,EAGH,SAAS,GAAe,EAAe,EAAmC,CACxE,IAAM,EAAU,EAAM,MAAM,CAC5B,GAAI,CAAC,EAAS,OACd,IAAM,EAAS,OAAO,EAAQ,CAC9B,GAAI,CAAC,OAAO,SAAS,EAAO,CAAE,MAAU,MAAM,GAAG,EAAM,mBAAmB,CAC1E,OAAO,EAGT,SAAS,GAAe,EAA0C,CAChE,GAAI,EAAM,iBAGR,MAAO,QAFM,GAAQ,EAAM,iBAAiB,uBAE7B,CAAK,SADP,GAAQ,EAAM,iBAAiB,iBAAmB,KAAK,IAAI,EAAG,EAAM,iBAAiB,uBAAyB,GAAI,CAClG,GAE/B,IAAM,EAAU,GAAuC,EAAM,QAAQ,qBAAqB,MAAM,CAChG,MAAO,gBAAgB,GAAQ,EAAQ,uBAAuB,CAAC,SAAS,GAAQ,EAAQ,gBAAgB,GAG1G,SAAS,GAAQ,EAAuB,CACtC,MAAO,GAAG,KAAK,MAAM,EAAQ,IAAI,CAAC,GCzSpC,IAAM,GAAc,EACd,GAAc,GAEd,GAA0C,CAAE,OAAQ,SAAU,MAAO,QAAS,CAEpF,SAAS,GAAU,EAAgC,CACjD,OAAO,KAAK,MAAM,EAAiB,IAAO,CAG5C,SAAS,GAAc,EAAgC,CACrD,MAAO,GAAG,GAAU,EAAe,CAAC,MAGtC,SAAgB,GAAc,CAAE,YAAmC,CACjE,GAAM,CAAC,EAAQ,IAAA,EAAA,EAAA,UAAqD,KAAK,CACnE,CAAC,EAAW,IAAA,EAAA,EAAA,UAAyB,GAAG,CACxC,CAAC,EAAW,IAAA,EAAA,EAAA,UAAyB,GAAG,CACxC,CAAC,EAAgB,IAAA,EAAA,EAAA,UAA6C,KAAK,EAGzE,EAAA,EAAA,eAAgB,CACd,IAAI,EAAY,GAShB,OARM,SAAY,CAChB,GAAI,CACF,IAAM,EAAO,MAAM,EAA4B,MAAO,0BAA0B,CAC3E,GAAW,EAAU,EAAK,OACxB,EAAG,CACL,GAAW,EAAc,EAAY,QAAQ,KAElD,KACS,CAAE,EAAY,KAC1B,EAAE,CAAC,CAEN,eAAe,EAAK,EAAkB,EAA2B,CAC/D,EAAW,IAAa,CAAE,GAAI,GAAW,EAAE,EAAI,GAAW,EAAM,EAAE,CAClE,EAAa,GAAG,CAChB,EAAkB,EAAS,CAC3B,GAAI,CACF,IAAM,EAAQ,MAAM,EAAyB,MAAO,cAAc,EAAS,eAAgB,EAAK,CAChG,EAAW,IAAa,CAAE,GAAI,GAAW,EAAE,EAAI,GAAW,EAAO,EAAE,OAC5D,EAAG,CACV,EAAa,GAAG,GAAgB,IAAa,EAAS,IAAK,EAAY,UAAU,QACzE,CACR,EAAkB,KAAK,EAI3B,IAAM,EAAY,EAAS,OAAO,KAAK,EAAO,CAAC,MAAM,CAAG,EAAE,CAE1D,OACE,EAAA,EAAA,MAAC,UAAD,CAAS,UAAU,qBAAnB,EACE,EAAA,EAAA,MAAC,MAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,mCAA0B,QAAU,CAAA,EAClD,EAAA,EAAA,MAAC,IAAD,CAAG,UAAU,yCAAb,CAA6C,+CACA,EAAA,EAAA,KAAC,SAAD,CAAA,SAAQ,UAAgB,CAAA,iEACnE,EAAA,EAAA,KAAC,SAAD,CAAA,SAAQ,kBAAwB,CAAA,0BAC9B,GACA,CAAA,CAAA,CAEL,IACC,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,yHAAf,EACE,EAAA,EAAA,KAAC,EAAD,CAAa,UAAU,gBAAkB,CAAA,EACzC,EAAA,EAAA,KAAC,OAAD,CAAA,SAAO,EAAiB,CAAA,CACpB,GAEP,IACC,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,yHAAf,EACE,EAAA,EAAA,KAAC,EAAD,CAAa,UAAU,gBAAkB,CAAA,EACzC,EAAA,EAAA,KAAC,OAAD,CAAA,SAAO,EAAiB,CAAA,CACpB,GAGP,CAAC,GAAU,CAAC,IACX,EAAA,EAAA,KAAC,EAAD,CAAM,KAAK,eAAK,EAAA,EAAA,MAAC,EAAD,CAAa,UAAU,iEAAvB,EACd,EAAA,EAAA,KAAC,EAAD,CAAS,UAAU,sBAAwB,CAAA,CAAA,wBAC/B,GAAO,CAAA,CAGtB,EAAU,IAAK,GAAa,CAC3B,IAAM,EAAM,EAAQ,GACd,EAAW,CAAC,GAAY,IAAmB,EACjD,OACE,EAAA,EAAA,MAAC,EAAD,CAAqB,KAAK,cAA1B,EACE,EAAA,EAAA,MAAC,EAAD,CAAA,SAAA,EACE,EAAA,EAAA,MAAC,EAAD,CAAW,UAAU,2CAArB,EACE,EAAA,EAAA,KAAC,EAAD,CAAO,UAAU,SAAW,CAAA,CAC3B,GAAgB,IAAa,EAC7B,IAAmB,IAAY,EAAA,EAAA,KAAC,EAAD,CAAS,UAAU,4CAA8C,CAAA,CACvF,IACZ,EAAA,EAAA,MAAC,EAAD,CAAiB,UAAU,mBAA3B,CACG,EAAI,QAAU,gBAAgB,GAAc,EAAI,eAAe,GAAK,sBACpE,EAAI,SAAW,CAAC,EAAI,aAAe,wBAA0B,GAC9C,GACP,CAAA,CAAA,EACb,EAAA,EAAA,MAAC,EAAD,CAAa,UAAU,qBAAvB,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,qFAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,+BAAsB,UAAa,CAAA,EAClD,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,yCAAgC,yFAA4F,CAAA,CACvI,CAAA,CAAA,EACN,EAAA,EAAA,KAAC,EAAD,CACE,QAAS,EAAI,QACH,WACV,gBAAkB,GAAY,KAAK,EAAK,EAAU,CAAE,GAAG,EAAK,UAAS,CAAC,CACtE,CAAA,CACE,IAEN,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,uDAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,6CAAf,EACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,+BAAsB,mBAAsB,CAAA,EAC3D,EAAA,EAAA,KAAC,EAAD,CAAO,QAAQ,UAAU,UAAU,wBAAgB,GAAc,EAAI,eAAe,CAAS,CAAA,CACzF,IACN,EAAA,EAAA,KAAC,QAAD,CACE,KAAK,QACL,IAAK,GACL,IAAK,GACL,KAAM,EACN,MAAO,GAAU,EAAI,eAAe,CACpC,SAAU,GAAY,CAAC,EAAI,QAE3B,SAAW,GAAM,CACf,IAAM,EAAiB,OAAO,EAAE,OAAO,MAAM,CAAG,IAChD,EAAW,IAAa,CAAE,GAAI,GAAW,EAAE,EAAI,GAAW,CAAE,GAAG,EAAK,iBAAgB,CAAE,EAAE,EAE1F,YAAc,GAAM,KAAK,EAAK,EAAU,CAAE,GAAG,EAAK,eAAgB,OAAQ,EAAE,OAA4B,MAAM,CAAG,IAAQ,CAAC,CAC1H,QAAU,GAAM,KAAK,EAAK,EAAU,CAAE,GAAG,EAAK,eAAgB,OAAQ,EAAE,OAA4B,MAAM,CAAG,IAAQ,CAAC,CACtH,UAAU,4CACV,CAAA,EACF,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,kEAAf,EACE,EAAA,EAAA,MAAC,OAAD,CAAA,SAAA,CAAO,GAAY,OAAW,CAAA,CAAA,EAC9B,EAAA,EAAA,MAAC,OAAD,CAAA,SAAA,CAAO,GAAY,OAAW,CAAA,CAAA,CAC1B,GACF,IAEN,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,qFAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,+BAAsB,uBAA0B,CAAA,EAC/D,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,yCAAgC,oGAAuG,CAAA,CAClJ,CAAA,CAAA,EACN,EAAA,EAAA,KAAC,EAAD,CACE,QAAS,EAAI,aACH,WACV,gBAAkB,GAAiB,KAAK,EAAK,EAAU,CAAE,GAAG,EAAK,eAAc,CAAC,CAChF,CAAA,CACE,IAEN,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,qFAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,+BAAsB,sBAAyB,CAAA,EAC9D,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,yCAAgC,mEAAsE,CAAA,CACjH,CAAA,CAAA,EACN,EAAA,EAAA,KAAC,EAAD,CACE,QAAS,EAAI,kBAAoB,GACvB,WACV,gBAAkB,GAAqB,KAAK,EAAK,EAAU,CAAE,GAAG,EAAK,mBAAkB,CAAC,CACxF,CAAA,CACE,IAEN,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,uDAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,6CAAf,EACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,+BAAsB,kBAAqB,CAAA,EAC1D,EAAA,EAAA,MAAC,EAAD,CAAO,QAAQ,UAAU,UAAU,wBAAnC,CAAmD,EAAI,qBAAuB,EAAE,IAAS,GACrF,IACN,EAAA,EAAA,KAAC,QAAD,CACE,KAAK,QACL,IAAK,EACL,IAAK,EACL,KAAM,EACN,MAAO,EAAI,qBAAuB,EAClC,SAAU,GAAY,EAAE,EAAI,kBAAoB,IAChD,SAAW,GAAM,CACf,IAAM,EAAsB,OAAO,EAAE,OAAO,MAAM,CAClD,EAAW,IAAa,CAAE,GAAI,GAAW,EAAE,EAAI,GAAW,CAAE,GAAG,EAAK,sBAAqB,CAAE,EAAE,EAE/F,YAAc,GAAM,KAAK,EAAK,EAAU,CAAE,GAAG,EAAK,oBAAqB,OAAQ,EAAE,OAA4B,MAAM,CAAE,CAAC,CACtH,QAAU,GAAM,KAAK,EAAK,EAAU,CAAE,GAAG,EAAK,oBAAqB,OAAQ,EAAE,OAA4B,MAAM,CAAE,CAAC,CAClH,UAAU,4CACV,CAAA,EACF,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,kEAAf,EACE,EAAA,EAAA,KAAC,OAAD,CAAA,SAAM,KAAS,CAAA,EACf,EAAA,EAAA,KAAC,OAAD,CAAA,SAAM,KAAS,CAAA,CACX,GACF,GACM,GACT,EAtGI,EAsGJ,EAET,CACM,GC3Ld,SAAS,GAAY,CAAE,WAAgC,CACrD,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,yHAAf,EACE,EAAA,EAAA,KAAC,EAAD,CAAa,UAAU,yBAA2B,CAAA,EAClD,EAAA,EAAA,KAAC,OAAD,CAAA,SAAO,EAAe,CAAA,CAClB,GAIV,IAAM,GAAY,IAAqB,CAEjC,EAAgB,CAAE,UAAW,IAAM,aAAc,GAAK,YAAa,EAAK,CACxE,GAAmB,IACnB,GAAgB,GAEtB,SAAS,EAAO,EAAuB,EAAa,CAClD,QAAS,GAAK,GAAO,KAAK,QAAQ,EAAE,CAGtC,SAAS,EAAc,EAA0B,CAC/C,IAAM,EAAU,EAAE,MAAM,CACxB,GAAI,CAAC,EAAS,OAAO,KACrB,IAAM,EAAI,OAAO,EAAQ,CAEzB,MADI,CAAC,OAAO,SAAS,EAAE,EAAI,EAAI,GAAK,EAAI,IAAY,KAC7C,EAAI,IAGb,SAAS,GAA8B,EAAW,EAA4B,CAC5E,OAAO,EAAE,MAAM,CAAG,EAAc,EAAE,CAAG,EAKvC,SAAgB,GAAsB,CACpC,SACA,WACA,YAKC,CACD,IAAM,EAAQ,EAAO,WACf,EAAgB,EAAO,eAAiB,EAAE,CAE1C,CAAC,EAAY,IAAA,EAAA,EAAA,UAA0B,EAAO,GAAO,UAAW,EAAc,UAAU,CAAC,CACzF,CAAC,EAAe,IAAA,EAAA,EAAA,UAA6B,EAAO,GAAO,aAAc,EAAc,aAAa,CAAC,CACrG,CAAC,EAAc,IAAA,EAAA,EAAA,UAA4B,EAAO,GAAO,YAAa,EAAc,YAAY,CAAC,CAEjG,CAAC,EAAe,IAAA,EAAA,EAAA,cAAwF,CAC5G,IAAM,EAA2D,EAAE,CACnE,IAAK,IAAM,KAAK,GAAW,CACzB,IAAM,EAAM,EAAc,IAAM,EAAE,CAClC,EAAI,GAAK,CACP,SAAU,EAAO,EAAI,wBAAyB,GAAiB,CAC/D,MAAO,EAAO,EAAI,4BAA6B,GAAc,CAC9D,CAEH,OAAO,GACP,CAEI,CAAC,EAAQ,IAAA,EAAA,EAAA,UAAsB,GAAM,CACrC,CAAC,EAAW,IAAA,EAAA,EAAA,UAAyB,GAAG,CACxC,CAAC,EAAQ,IAAA,EAAA,EAAA,UAAsB,GAAM,CACrC,CAAC,EAAiB,IAAA,EAAA,EAAA,UAA+B,GAAG,CAE1D,eAAe,GAAO,CACpB,IAAM,EAAU,EAAc,EAAW,CACnC,EAAa,EAAc,EAAc,CACzC,EAAY,EAAc,EAAa,CAE7C,GAAI,IAAY,KAAM,CAAE,EAAmB,oCAAoC,CAAE,OACjF,GAAI,IAAe,KAAM,CAAE,EAAmB,wCAAwC,CAAE,OACxF,GAAI,IAAc,KAAM,CAAE,EAAmB,uCAAuC,CAAE,OACtF,GAAI,GAAW,EAAY,CAAE,EAAmB,yCAAyC,CAAE,OAC3F,GAAI,GAAc,EAAW,CAAE,EAAmB,4CAA4C,CAAE,OAEhG,IAAM,EAAyE,EAAE,CACjF,IAAK,IAAM,KAAK,GAAW,CACzB,IAAM,EAAI,EAAc,GAClB,EAAW,GAA8B,EAAE,SAAU,GAAiB,CACtE,EAAQ,EAAc,EAAE,MAAM,CACpC,GAAI,IAAa,KAAM,CAAE,EAAmB,GAAG,EAAiB,EAAE,CAAC,iCAAiC,CAAE,OACtG,GAAI,IAAU,KAAM,CAAE,EAAmB,GAAG,EAAiB,EAAE,CAAC,sCAAsC,CAAE,OACxG,EAAkB,GAAK,CAAE,wBAAyB,EAAU,4BAA6B,EAAO,CAGlG,EAAmB,GAAG,CACtB,EAAU,GAAK,CACf,EAAa,GAAG,CAChB,EAAU,GAAM,CAChB,GAAI,CAMF,EAAS,MALW,EAAmB,MAAO,kBAAmB,CAC/D,GAAG,EACH,WAAY,CAAE,UAAW,EAAS,aAAc,EAAY,YAAa,EAAW,CACpF,cAAe,EAChB,CAAC,CACa,CACf,EAAU,GAAK,CACf,eAAiB,EAAU,GAAM,CAAE,IAAK,OACjC,EAAG,CACV,EAAc,EAAY,QAAQ,QAC1B,CACR,EAAU,GAAM,EAIpB,SAAS,EAAc,EAAkB,EAA8C,CACrF,EAAkB,IAAS,CAAE,GAAG,GAAM,GAAW,CAAE,GAAG,EAAI,GAAY,GAAG,EAAO,CAAE,EAAE,CACpF,EAAmB,GAAG,CACtB,EAAU,GAAM,CAGlB,SAAS,GAAY,CAAE,EAAmB,GAAG,CAAE,EAAU,GAAM,CAE/D,OACE,EAAA,EAAA,MAAC,EAAD,CAAM,KAAK,cAAX,EACE,EAAA,EAAA,MAAC,EAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,EAAD,CAAW,UAAU,mBAAU,mBAA4B,CAAA,EAC3D,EAAA,EAAA,KAAC,EAAD,CAAiB,UAAU,mBAAU,4IAEnB,CAAA,CACP,CAAA,CAAA,EACb,EAAA,EAAA,MAAC,EAAD,CAAa,UAAU,qBAAvB,EACI,GAAa,KAAoB,EAAA,EAAA,KAAC,GAAD,CAAa,QAAS,GAAa,EAAmB,CAAA,EAEzF,EAAA,EAAA,MAAC,MAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,kFAAyE,eAAkB,CAAA,EAC1G,EAAA,EAAA,KAAC,GAAD,CAAkB,QAAS,OAAO,EAAW,CAAE,WAAY,OAAO,EAAc,CAAE,UAAW,OAAO,EAAa,CAAI,CAAA,EACrH,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,0CAAf,EACE,EAAA,EAAA,KAAC,EAAD,CAAe,MAAM,aAAa,KAAM,aAAa,EAAc,UAAY,KAAK,QAAQ,EAAE,CAAC,GAC7F,MAAO,EAAY,SAAU,CAAC,GAAY,EAAQ,SAAW,GAAM,CAAE,EAAc,EAAE,CAAE,GAAW,EAAM,CAAA,EAC1G,EAAA,EAAA,KAAC,EAAD,CAAe,MAAM,iBAAiB,KAAM,aAAa,EAAc,aAAe,KAAK,QAAQ,EAAE,CAAC,GACpG,MAAO,EAAe,SAAU,CAAC,GAAY,EAAQ,SAAW,GAAM,CAAE,EAAiB,EAAE,CAAE,GAAW,EAAM,CAAA,EAChH,EAAA,EAAA,KAAC,EAAD,CAAe,MAAM,gBAAgB,KAAM,aAAa,EAAc,YAAc,KAAK,QAAQ,EAAE,CAAC,GAClG,MAAO,EAAc,SAAU,CAAC,GAAY,EAAQ,SAAW,GAAM,CAAE,EAAgB,EAAE,CAAE,GAAW,EAAM,CAAA,CAC1G,GACF,CAAA,CAAA,CAEL,GAAU,IAAK,GAAM,CACpB,IAAM,EAAI,EAAc,GACxB,OACE,EAAA,EAAA,MAAC,MAAD,CAAA,SAAA,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,kFAAf,CAAyF,EAAiB,EAAE,CAAC,aAAgB,IAC7H,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,qCAAf,EACE,EAAA,EAAA,KAAC,EAAD,CAAe,MAAM,4BACnB,KAAM,qEAAqE,GAAmB,KAAK,QAAQ,EAAE,CAAC,YAC9G,MAAO,EAAE,SAAU,SAAU,CAAC,GAAY,EAC1C,SAAW,GAAM,EAAc,EAAG,CAAE,SAAU,EAAG,CAAC,CAAI,CAAA,EACxD,EAAA,EAAA,KAAC,EAAD,CAAe,MAAM,qBACnB,KAAM,8CAA8C,GAAgB,KAAK,QAAQ,EAAE,CAAC,GACpF,MAAO,EAAE,MAAO,SAAU,CAAC,GAAY,EACvC,SAAW,GAAM,EAAc,EAAG,CAAE,MAAO,EAAG,CAAC,CAAI,CAAA,CACjD,GACF,CAAA,CAZI,EAYJ,EAER,CAED,IACC,EAAA,EAAA,MAAC,EAAD,CAAQ,KAAK,KAAK,YAAe,KAAK,GAAM,CAAE,SAAU,WAAxD,CACG,GAAS,EAAA,EAAA,KAAC,EAAD,CAAS,UAAU,sBAAwB,CAAA,EAAG,EAAA,EAAA,KAAC,EAAD,CAAM,UAAU,SAAW,CAAA,CAClF,EAAS,QAAU,kBACb,GAEC,GACT,GAOX,SAAS,GAAiB,CAAE,UAAS,aAAY,aAAyE,CACxH,IAAM,EAAS,GAAc,KAAK,IAAI,EAAG,KAAK,IAAI,IAAK,OAAO,SAAS,EAAE,CAAG,EAAI,EAAE,CAAC,CAC7E,EAAI,EAAM,EAAQ,CAElB,EAAI,KAAK,IAAI,EAAG,EAAM,EAAW,CAAC,CAClC,EAAI,KAAK,IAAI,EAAG,EAAM,EAAU,CAAC,CACjC,EAAO,GAAc,GAAG,EAAE,QAAQ,EAAE,CAAC,GACrC,EAAQ,CACZ,CAAE,IAAK,SAAU,MAAO,SAAU,MAAO,iBAAkB,KAAM,EAAG,GAAI,EAAG,MAAO,KAAK,EAAI,EAAE,GAAI,CACjG,CAAE,IAAK,UAAW,MAAO,UAAW,MAAO,eAAgB,KAAM,EAAG,GAAI,EAAG,MAAO,GAAG,EAAI,EAAE,CAAC,GAAG,EAAI,EAAE,GAAI,CACzG,CAAE,IAAK,cAAe,MAAO,cAAe,MAAO,gBAAiB,KAAM,EAAG,GAAI,EAAG,MAAO,GAAG,EAAI,EAAE,CAAC,GAAG,EAAI,EAAE,GAAI,CAClH,CAAE,IAAK,aAAc,MAAO,aAAc,MAAO,aAAc,KAAM,EAAG,GAAI,IAAK,MAAO,KAAK,EAAI,EAAE,GAAI,CACxG,CACD,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,uBAAf,EACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,mDAAmD,KAAK,MAAM,aAAW,qDACrF,EAAM,IAAK,IACV,EAAA,EAAA,KAAC,MAAD,CAAiB,UAAW,EAAG,EAAE,MAAO,kCAAkC,CAAE,MAAO,CAAE,MAAO,GAAG,EAAE,GAAK,EAAE,KAAK,GAAI,CAAE,MAAO,GAAG,EAAE,MAAM,KAAK,EAAE,QAAW,CAA7I,EAAE,IAA2I,CACvJ,CACE,CAAA,EACN,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,4EACZ,EAAM,IAAK,IACV,EAAA,EAAA,MAAC,OAAD,CAAkB,UAAU,mCAA5B,EACE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAW,EAAG,+BAAgC,EAAE,MAAM,CAAI,CAAA,CAC/D,EAAE,MAAM,KAAC,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,2CAAmC,EAAE,MAAa,CAAA,CACvE,EAHI,EAAE,IAGN,CACP,CACE,CAAA,CACF,GAIV,SAAS,EAAc,CAAE,QAAO,OAAM,QAAO,WAAU,YAEpD,CACD,OACE,EAAA,EAAA,MAAC,QAAD,CAAO,UAAU,qBAAjB,EACE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,yDAAiD,EAAa,CAAA,EAC9E,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,oBAAf,EACE,EAAA,EAAA,KAAC,EAAD,CAAc,QAAO,SAAW,GAAM,EAAS,EAAE,OAAO,MAAM,CAAY,WACxE,UAAU,gCAAkC,CAAA,EAC9C,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,4GAAmG,IAAQ,CAAA,CACvH,IACN,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,6CAAqC,EAAY,CAAA,CAC3D,GAWZ,SAAgB,IAA6B,CAC3C,GAAM,CAAC,EAAM,IAAA,EAAA,EAAA,UAA2C,KAAK,CACvD,CAAC,EAAS,IAAA,EAAA,EAAA,UAAuB,GAAM,CACvC,CAAC,EAAO,IAAA,EAAA,EAAA,UAAqB,GAAG,CAChC,CAAC,EAAM,IAAA,EAAA,EAAA,UAAoB,GAAM,CACjC,CAAC,EAAQ,IAAA,EAAA,EAAA,UAAsB,GAAM,CAE3C,eAAe,GAAO,CAChB,MAEJ,CADA,EAAW,GAAK,CAChB,EAAS,GAAG,CACZ,GAAI,CACF,GAAM,CAAC,EAAQ,GAAW,MAAM,QAAQ,IAAI,CAC1C,EAAmB,MAAO,kBAAkB,CAC5C,EAAkB,MAAO,8BAA8B,CAAC,UAAY,KAAK,CAC1E,CAAC,CACF,EAAQ,CAAE,SAAQ,UAAS,CAAC,CAC5B,EAAU,GAAK,OACR,EAAG,CACV,EAAU,EAAY,QAAQ,QACtB,CACR,EAAW,GAAM,GAIrB,eAAe,GAAS,CACtB,EAAU,GAAM,CAChB,EAAW,GAAK,CAChB,EAAS,GAAG,CACZ,GAAI,CACF,GAAM,CAAC,EAAQ,GAAW,MAAM,QAAQ,IAAI,CAC1C,EAAmB,MAAO,kBAAkB,CAC5C,EAAkB,MAAO,8BAA8B,CAAC,UAAY,KAAK,CAC1E,CAAC,CACF,EAAQ,CAAE,SAAQ,UAAS,CAAC,CAC5B,EAAU,GAAK,OACR,EAAG,CACV,EAAU,EAAY,QAAQ,QACtB,CACR,EAAW,GAAM,EAIrB,SAAS,GAAS,CAChB,IAAM,EAAO,CAAC,EACd,EAAQ,EAAK,CACT,GAAQ,CAAC,GAAQ,GAAW,CAGlC,OACE,EAAA,EAAA,KAAC,EAAD,CAAM,KAAK,eACT,EAAA,EAAA,MAAC,EAAD,CAAa,UAAU,qBAAvB,EACE,EAAA,EAAA,MAAC,SAAD,CAAQ,KAAK,SAAS,UAAU,2CAA2C,QAAS,WAApF,EACE,EAAA,EAAA,KAAC,EAAD,CAAK,UAAU,+BAAiC,CAAA,EAChD,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,0BAAf,EACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,iCAAwB,8BAAiC,CAAA,EACxE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,yCAAgC,uEAA0E,CAAA,CACrH,GACL,GAAO,EAAA,EAAA,KAAC,EAAD,CAAa,UAAU,wCAA0C,CAAA,EAAG,EAAA,EAAA,KAAC,GAAD,CAAc,UAAU,wCAA0C,CAAA,CACvI,GAER,IACC,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,0BAAf,EACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,6BACb,EAAA,EAAA,MAAC,EAAD,CAAQ,QAAQ,UAAU,KAAK,KAAK,YAAe,KAAK,GAAQ,CAAE,SAAU,WAA5E,EACE,EAAA,EAAA,KAAC,EAAD,CAAW,UAAW,EAAG,WAAY,GAAW,eAAe,CAAI,CAAA,CAAA,UAE5D,GACL,CAAA,CAEL,IAAS,EAAA,EAAA,KAAC,GAAD,CAAa,QAAS,EAAS,CAAA,CAExC,GAAW,CAAC,IACX,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,sEAAf,EACE,EAAA,EAAA,KAAC,EAAD,CAAS,UAAU,wBAA0B,CAAA,CAAA,WACzC,GAGP,IACC,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,GAAD,CAAqB,OAAQ,EAAK,OAAU,CAAA,CAC3C,EAAK,SACF,EAAA,EAAA,KAAC,GAAD,CAA2B,QAAS,EAAK,QAAW,CAAA,EACpD,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,gDAAuC,iCAAoC,CAAA,CAE7F,CAAA,CAAA,CAED,GAEI,GACT,CAAA,CAIX,SAAS,GAAoB,CAAE,UAAqC,CAClE,IAAM,EAAQ,EAAO,WACf,EAAgB,EAAO,eAAiB,EAAE,CAEhD,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,qBAAf,EACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,+EAAsE,wBAA2B,CAAA,CAE/G,EAAO,MAAM,SAAW,GACvB,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,gDAAuC,oDAAuD,CAAA,EAE7G,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,mEAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,oKAAf,EACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,mCAA0B,IAAO,CAAA,EAChD,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,mCAA0B,QAAW,CAAA,EACpD,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,mCAA0B,SAAY,CAAA,EACrD,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,mCAA0B,SAAY,CAAA,CACjD,GACL,EAAO,MAAM,KAAK,EAAM,KACvB,EAAA,EAAA,MAAC,MAAD,CACE,UAAW,EAAG,qFAAsF,EAAK,UAAY,IAAS,aAAa,UAD7I,EAEE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,kEAA0D,EAAM,EAAQ,CAAA,EACvF,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,+BAAf,CACG,EAAK,QAAS,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,uBAAe,EAAK,MAAY,CAAA,CAC7D,EAAK,MAAM,WAAY,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,qBAAf,CAA2B,SAAO,EAAK,MAAM,SAAe,GACnF,EAAK,MAAM,aAAc,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,qBAAf,CAA2B,QAAM,EAAK,MAAM,WAAiB,GACnF,IACN,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,+BAAf,EACE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,uBAAe,EAAK,OAAO,SAAgB,CAAA,CAC1D,EAAK,OAAO,QAAS,EAAA,EAAA,MAAC,OAAD,CAAM,UAAU,iCAAhB,CAAwC,MAAI,EAAK,OAAO,MAAa,GAC1F,EAAK,OAAO,SAAU,EAAA,EAAA,MAAC,OAAD,CAAM,UAAU,iCAAhB,CAAwC,KAAG,EAAK,OAAO,OAAO,IAAQ,GACzF,IACN,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,+BACZ,EAAK,UAAY,IAAQ,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,iCAAwB,WAAe,CAAA,EAAG,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,4BAAmB,SAAa,CAAA,CAChI,CAAA,CACF,EAhBI,EAgBJ,CACN,CACE,IAGN,GAAS,OAAO,KAAK,EAAc,CAAC,OAAS,KAC7C,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,mFAAf,CACG,IACC,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,4CAAf,CACG,EAAM,YAAc,IAAA,KAAa,EAAA,EAAA,MAAC,OAAD,CAAA,SAAA,CAAM,cAAY,EAAM,UAAY,KAAK,QAAQ,EAAE,CAAC,IAAQ,CAAA,CAAA,CAC7F,EAAM,eAAiB,IAAA,KAAa,EAAA,EAAA,MAAC,OAAD,CAAA,SAAA,CAAM,kBAAgB,EAAM,aAAe,KAAK,QAAQ,EAAE,CAAC,IAAQ,CAAA,CAAA,CACvG,EAAM,cAAgB,IAAA,KAAa,EAAA,EAAA,MAAC,OAAD,CAAA,SAAA,CAAM,iBAAe,EAAM,YAAc,KAAK,QAAQ,EAAE,CAAC,IAAQ,CAAA,CAAA,CACjG,GAEP,OAAO,QAAQ,EAAc,CAAC,KAAK,CAAC,EAAU,MAC7C,EAAA,EAAA,MAAC,MAAD,CAAoB,UAAU,kEAA9B,EACE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,uCAA+B,EAAiB,EAAS,CAAQ,CAAA,CAChF,GAAK,0BAA4B,IAAA,KAAa,EAAA,EAAA,MAAC,OAAD,CAAA,SAAA,CAAM,cAAY,EAAI,wBAA0B,KAAK,QAAQ,EAAE,CAAC,IAAQ,CAAA,CAAA,CACtH,GAAK,8BAAgC,IAAA,KAAa,EAAA,EAAA,MAAC,OAAD,CAAA,SAAA,CAAM,WAAS,EAAI,4BAA8B,KAAK,QAAQ,EAAE,CAAC,IAAQ,CAAA,CAAA,CACxH,EAJI,EAIJ,CACN,CACE,GAEJ,GAQV,SAAS,GAAiB,CAAE,OAAM,SAA2C,CAC3E,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,yFAAf,CACG,IAAU,IAAA,KACT,EAAA,EAAA,MAAC,OAAD,CAAM,UAAU,mIAAhB,CAA0I,IACtI,EACG,IAET,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,gHACZ,EACG,CAAA,CACF,GAIV,SAAS,GAA0B,CAAE,WAAsC,CACzE,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,qBAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,+EAAf,CAAqF,oCAEnF,EAAA,EAAA,KAAC,EAAD,CAAO,QAAQ,YAAY,UAAU,4BAAoB,EAAQ,KAAa,CAAA,CAC7E,EAAQ,UAAW,EAAA,EAAA,KAAC,EAAD,CAAO,QAAQ,UAAU,UAAU,4BAAmB,WAAgB,CAAA,CACtF,GAEL,EAAQ,cAAe,EAAA,EAAA,KAAC,IAAD,CAAG,UAAU,yCAAiC,EAAQ,YAAgB,CAAA,EAE9F,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,4CAAf,EACE,EAAA,EAAA,MAAC,EAAD,CAAO,QAAQ,mBAAf,CAAyB,SAAO,EAAQ,KAAa,IACrD,EAAA,EAAA,MAAC,EAAD,CAAO,QAAQ,mBAAf,CAAyB,SAAO,EAAQ,aAAa,iBAAyB,IAC9E,EAAA,EAAA,MAAC,EAAD,CAAO,QAAQ,mBAAf,CAAyB,WAAS,EAAQ,aAAa,mBAA2B,GACjF,EAAQ,WAAY,EAAA,EAAA,MAAC,EAAD,CAAO,QAAQ,mBAAf,CAAyB,aAAW,EAAQ,SAAiB,GAC9E,GAEL,EAAQ,aAAa,SACpB,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,qBAAf,EACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,iFAAwE,gBAAmB,CAAA,EAC1G,EAAA,EAAA,KAAC,GAAD,CAAkB,KAAM,EAAQ,aAAa,OAAU,CAAA,CACnD,GAGP,EAAQ,aAAa,OAAO,OAAS,IACpC,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,qBAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,iFAAf,CAAuF,0BAC7D,EAAQ,aAAa,OAAO,OAAO,IACvD,GACL,EAAQ,aAAa,OAAO,KAAK,EAAO,KACvC,EAAA,EAAA,KAAC,GAAD,CAA0B,KAAM,EAAO,MAAO,EAAI,EAAK,CAAhC,EAAgC,CACvD,CACE,GAGP,EAAQ,aAAa,OAAO,SAAW,GAAK,CAAC,EAAQ,aAAa,SACjE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,gDAAuC,iCAAoC,CAAA,CAExF,GC7aV,IAAM,GAAY,IAAqB,CAcvC,SAAS,IAA0B,CACjC,MAAO,CAAE,MAAO,GAAI,cAAe,GAAI,gBAAiB,GAAI,eAAgB,GAAU,IAAM,GAAI,YAAa,GAAI,aAAc,GAAI,QAAS,GAAM,CAGpJ,SAAS,GAAW,EAA6B,CAC/C,MAAO,CACL,MAAO,EAAK,OAAS,GACrB,cAAe,EAAK,MAAM,UAAY,GACtC,gBAAiB,EAAK,MAAM,YAAc,GAC1C,eAAgB,EAAK,OAAO,SAC5B,YAAa,EAAK,OAAO,OAAS,GAClC,aAAc,EAAK,OAAO,QAAU,GACpC,QAAS,EAAK,UAAY,GAC3B,CAGH,SAAS,GAAW,EAA6B,CAC/C,MAAO,CACL,GAAI,EAAK,MAAM,MAAM,CAAG,CAAE,MAAO,EAAK,MAAM,MAAM,CAAE,CAAG,EAAE,CACzD,MAAO,CACL,GAAI,EAAK,cAAc,MAAM,CAAG,CAAE,SAAU,EAAK,cAAc,MAAM,CAAE,CAAG,EAAE,CAC5E,GAAI,EAAK,gBAAgB,MAAM,CAAG,CAAE,WAAY,EAAK,gBAAgB,MAAM,CAAE,CAAG,EAAE,CACnF,CACD,OAAQ,CACN,SAAU,EAAK,eACf,GAAI,EAAK,YAAY,MAAM,CAAG,CAAE,MAAO,EAAK,YAAY,MAAM,CAAE,CAAG,EAAE,CACrE,GAAI,EAAK,aAAa,MAAM,CAAG,CAAE,OAAQ,EAAK,aAAa,MAAM,CAAE,CAAG,EAAE,CACzE,CACD,QAAS,EAAK,QACf,CAGH,SAAS,GAAiB,EAA+B,CAIvD,MAHI,CAAC,EAAK,cAAc,MAAM,EAAI,CAAC,EAAK,gBAAgB,MAAM,CACrD,sEAEF,KAGT,SAAS,GAAY,CAAE,WAAgC,CACrD,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,yHAAf,EACE,EAAA,EAAA,KAAC,EAAD,CAAa,UAAU,yBAA2B,CAAA,EAClD,EAAA,EAAA,KAAC,OAAD,CAAA,SAAO,EAAe,CAAA,CAClB,GAMV,SAAgB,GAAgB,CAAE,YAAmC,CACnE,GAAM,CAAC,EAAQ,IAAA,EAAA,EAAA,UAA4C,KAAK,CAC1D,CAAC,EAAS,IAAA,EAAA,EAAA,UAAuB,GAAM,CACvC,CAAC,EAAW,IAAA,EAAA,EAAA,UAAyB,GAAG,CACxC,CAAC,EAAQ,IAAA,EAAA,EAAA,UAAsB,GAAM,CAEvC,CAAC,GAAU,CAAC,GAAW,CAAC,IAC1B,EAAW,GAAK,EACV,SAAY,CAChB,GAAI,CAEF,EAAU,MADS,EAAmB,MAAO,kBAAkB,CAChD,CACf,EAAU,GAAK,OACR,EAAG,CACV,EAAc,EAAY,QAAQ,QAC1B,CACR,EAAW,GAAM,KAEjB,EAGN,eAAe,GAAS,CACtB,EAAW,GAAK,CAChB,EAAa,GAAG,CAChB,GAAI,CAEF,EAAU,MADS,EAAmB,MAAO,kBAAkB,CAChD,CACf,EAAU,GAAK,OACR,EAAG,CACV,EAAc,EAAY,QAAQ,QAC1B,CACR,EAAW,GAAM,EAIrB,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,qBAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,mDAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,mCAA0B,UAAY,CAAA,EACpD,EAAA,EAAA,KAAC,IAAD,CAAG,UAAU,yCAAgC,yKAGzC,CAAA,CACA,CAAA,CAAA,EACN,EAAA,EAAA,MAAC,EAAD,CAAQ,QAAQ,UAAU,KAAK,KAAK,YAAe,KAAK,GAAQ,CAAE,SAAU,WAA5E,EACE,EAAA,EAAA,KAAC,EAAD,CAAW,UAAW,EAAG,SAAU,GAAW,eAAe,CAAI,CAAA,CAAA,UAE1D,GACL,GAEL,IAAa,EAAA,EAAA,KAAC,GAAD,CAAa,QAAS,EAAa,CAAA,CAEhD,GAAW,CAAC,IACX,EAAA,EAAA,KAAC,EAAD,CAAM,KAAK,eACT,EAAA,EAAA,MAAC,EAAD,CAAa,UAAU,iEAAvB,EACE,EAAA,EAAA,KAAC,EAAD,CAAS,UAAU,sBAAwB,CAAA,CAAA,0BAE/B,GACT,CAAA,CAGR,IACC,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,GAAD,CAA4B,SAAkB,WAAU,SAAU,EAAa,CAAA,EAC/E,EAAA,EAAA,KAAC,GAAD,CAA+B,SAAkB,WAAU,SAAU,EAAa,CAAA,CACjF,CAAA,CAAA,EAGL,EAAA,EAAA,KAAC,GAAD,EAA8B,CAAA,CAC1B,GAMV,SAAS,GAAmB,CAC1B,SACA,WACA,YAKC,CACD,GAAM,CAAC,EAAQ,IAAA,EAAA,EAAA,UAAsB,GAAM,CACrC,CAAC,EAAW,IAAA,EAAA,EAAA,UAAyB,GAAG,CACxC,CAAC,EAAS,IAAA,EAAA,EAAA,UAAuB,GAAM,CACvC,CAAC,EAAS,IAAA,EAAA,EAAA,UAAiC,GAAc,CACzD,CAAC,EAAU,IAAA,EAAA,EAAA,UAAwB,GAAG,CACtC,CAAC,EAAS,IAAA,EAAA,EAAA,UAAsC,KAAK,CACrD,CAAC,EAAU,IAAA,EAAA,EAAA,UAAkC,GAAc,CAC3D,CAAC,EAAW,IAAA,EAAA,EAAA,UAAyB,GAAG,CAE9C,eAAe,EAAU,EAAqB,CAC5C,EAAU,GAAK,CACf,EAAa,GAAG,CAChB,GAAI,CAEF,EAAS,MADW,EAAmB,MAAO,kBAAmB,EAAK,CACvD,OACR,EAAG,CACV,EAAc,EAAY,QAAQ,QAC1B,CACR,EAAU,GAAM,EAIpB,SAAS,EAAK,EAAa,EAAa,CACtC,IAAM,EAAQ,CAAC,GAAG,EAAO,MAAM,CACzB,EAAS,EAAM,EACjB,EAAS,GAAK,GAAU,EAAM,SACjC,CAAC,EAAM,GAAM,EAAM,IAAW,CAAC,EAAM,GAAU,EAAM,GAAM,CAC5D,EAAe,CAAE,GAAG,EAAQ,QAAO,CAAC,EAGtC,SAAS,EAAc,EAAa,CAClC,IAAM,EAAQ,EAAO,MAAM,KAAK,EAAG,IAAO,IAAM,EAAM,CAAE,GAAG,EAAG,QAAS,EAAE,UAAY,GAAsB,CAAG,EAAG,CACjH,EAAe,CAAE,GAAG,EAAQ,QAAO,CAAC,CAGtC,SAAS,EAAW,EAAa,CAC/B,EAAe,CAAE,GAAG,EAAQ,MAAO,EAAO,MAAM,QAAQ,EAAG,IAAM,IAAM,EAAI,CAAE,CAAC,CAGhF,SAAS,GAAW,CAAE,EAAW,IAAe,CAAC,CAAE,EAAY,GAAG,CAAE,EAAW,GAAK,CACpF,SAAS,IAAY,CAAE,EAAW,GAAM,CAAE,EAAY,GAAG,CAEzD,SAAS,IAAY,CACnB,IAAM,EAAM,GAAiB,EAAQ,CACrC,GAAI,EAAK,CAAE,EAAY,EAAI,CAAE,OAC7B,EAAW,GAAM,CACjB,EAAe,CAAE,GAAG,EAAQ,MAAO,CAAC,GAAG,EAAO,MAAO,GAAW,EAAQ,CAAC,CAAE,CAAC,CAG9E,SAAS,EAAU,EAAa,CAC9B,EAAW,EAAI,CAAE,EAAY,GAAW,EAAO,MAAM,GAAM,CAAC,CAAE,EAAa,GAAG,CAGhF,SAAS,IAAa,CAAE,EAAW,KAAK,CAAE,EAAa,GAAG,CAE1D,SAAS,IAAa,CACpB,GAAI,IAAY,KAAM,OACtB,IAAM,EAAM,GAAiB,EAAS,CACtC,GAAI,EAAK,CAAE,EAAa,EAAI,CAAE,OAC9B,IAAM,EAAQ,EAAO,MAAM,KAAK,EAAG,IAAO,IAAM,EAAU,GAAW,EAAS,CAAG,EAAG,CACpF,EAAW,KAAK,CAChB,EAAe,CAAE,GAAG,EAAQ,QAAO,CAAC,CAGtC,OACE,EAAA,EAAA,MAAC,EAAD,CAAM,KAAK,cAAX,EACE,EAAA,EAAA,MAAC,EAAD,CAAA,SAAA,EACE,EAAA,EAAA,MAAC,EAAD,CAAW,UAAU,2CAArB,EACE,EAAA,EAAA,KAAC,EAAD,CAAO,UAAU,SAAW,CAAA,UAE5B,EAAA,EAAA,MAAC,EAAD,CAAO,QAAQ,UAAU,UAAU,+BAAnC,CACG,EAAO,MAAM,OAAO,QAAM,EAAO,MAAM,SAAW,EAAI,GAAK,IACtD,GACP,IAAU,EAAA,EAAA,KAAC,EAAD,CAAS,UAAU,4CAA8C,CAAA,CAClE,IACZ,EAAA,EAAA,KAAC,EAAD,CAAiB,UAAU,mBAAU,qHAEnB,CAAA,CACP,CAAA,CAAA,EACb,EAAA,EAAA,MAAC,EAAD,CAAa,UAAU,qBAAvB,CACG,IAAa,EAAA,EAAA,KAAC,GAAD,CAAa,QAAS,EAAa,CAAA,CAEhD,EAAO,MAAM,SAAW,GAAK,CAAC,IAC7B,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,wGAA+F,6DAExG,CAAA,CAGP,EAAO,MAAM,KAAK,EAAM,IACvB,IAAY,GACV,EAAA,EAAA,KAAC,GAAD,CAAwB,KAAM,EAAU,MAAO,EAAW,SAAU,EAAa,OAAQ,GAAY,SAAU,GAAc,CAA1G,EAA0G,EAE7H,EAAA,EAAA,KAAC,GAAD,CAEQ,OACD,MACL,MAAO,EAAO,MAAM,OACV,WACF,SACR,aAAgB,EAAK,EAAK,GAAG,CAC7B,eAAkB,EAAK,EAAK,EAAE,CAC9B,aAAgB,EAAc,EAAI,CAClC,WAAc,EAAU,EAAI,CAC5B,aAAgB,EAAW,EAAI,CAC/B,CAXK,EAWL,CAEL,CAEA,IACC,EAAA,EAAA,KAAC,GAAD,CAAc,KAAM,EAAS,MAAO,EAAU,SAAU,EAAY,OAAQ,GAAW,SAAU,GAAW,MAAA,GAAQ,CAAA,CAGrH,GAAY,CAAC,GAAW,IAAY,OACnC,EAAA,EAAA,MAAC,EAAD,CAAQ,QAAQ,UAAU,KAAK,KAAK,UAAU,eAAe,QAAS,EAAU,SAAU,WAA1F,EACE,EAAA,EAAA,KAAC,EAAD,CAAM,UAAU,SAAW,CAAA,CAAA,WAEpB,GAEC,GACT,GAIX,SAAS,GAAQ,CACf,OAAM,MAAK,QAAO,WAAU,SAC5B,WAAU,aAAY,WAAU,SAAQ,YAYvC,CAED,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAW,EAAG,iEAFJ,EAAK,UAAY,IAEiE,aAAa,UAA9G,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,qDAAf,EACE,EAAA,EAAA,KAAC,SAAD,CAAQ,KAAK,SAAS,MAAM,UAAU,QAAS,EAAU,SAAU,CAAC,GAAY,GAAU,IAAQ,EAChG,UAAU,uIACV,EAAA,EAAA,KAAC,EAAD,CAAS,UAAU,WAAa,CAAA,CACzB,CAAA,EACT,EAAA,EAAA,KAAC,SAAD,CAAQ,KAAK,SAAS,MAAM,YAAY,QAAS,EAAY,SAAU,CAAC,GAAY,GAAU,IAAQ,EAAQ,EAC5G,UAAU,uIACV,EAAA,EAAA,KAAC,EAAD,CAAW,UAAU,WAAa,CAAA,CAC3B,CAAA,CACL,IAEN,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,oCAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,mCAAf,EACE,EAAA,EAAA,MAAC,OAAD,CAAM,UAAU,0DAAhB,CAAiE,IAAE,EAAM,EAAS,GACjF,EAAK,QAAS,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,+BAAuB,EAAK,MAAa,CAAA,EACxE,EAAA,EAAA,KAAC,EAAD,CAAO,QAAQ,UAAU,UAAU,uBAAe,EAAK,OAAO,SAAiB,CAAA,CAC9E,EAAK,OAAO,QAAS,EAAA,EAAA,KAAC,EAAD,CAAO,QAAQ,UAAU,UAAU,iCAAyB,EAAK,OAAO,MAAc,CAAA,CAC3G,EAAK,OAAO,SAAU,EAAA,EAAA,KAAC,EAAD,CAAO,QAAQ,UAAU,UAAU,uBAAe,EAAK,OAAO,OAAe,CAAA,CAChG,IACN,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,8EAAf,CACG,EAAK,MAAM,WAAY,EAAA,EAAA,MAAC,OAAD,CAAA,SAAA,CAAM,eAAW,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,qCAA6B,EAAK,MAAM,SAAgB,CAAA,CAAO,CAAA,CAAA,CACvH,EAAK,MAAM,aAAc,EAAA,EAAA,MAAC,OAAD,CAAA,SAAA,CAAM,gBAAY,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,qCAA6B,EAAK,MAAM,WAAkB,CAAA,CAAO,CAAA,CAAA,CACzH,GACF,IAEN,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,iIAAf,EACE,EAAA,EAAA,KAAC,EAAD,CAAQ,QAAS,EAAK,UAAY,GAAO,SAAU,CAAC,GAAY,EAAQ,gBAAiB,EACvF,MAAO,EAAK,UAAY,GAAQ,cAAgB,eAAkB,CAAA,CACnE,IACC,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,SAAD,CAAQ,KAAK,SAAS,MAAM,OAAO,QAAS,EAAQ,SAAU,EAC5D,UAAU,iHACV,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,WAAW,QAAQ,YAAY,KAAK,OAAO,OAAO,eAAe,YAAa,WAA7F,EACE,EAAA,EAAA,KAAC,OAAD,CAAM,EAAE,6DAA+D,CAAA,EACvE,EAAA,EAAA,KAAC,OAAD,CAAM,EAAE,0DAA4D,CAAA,CAChE,GACC,CAAA,EACT,EAAA,EAAA,KAAC,SAAD,CAAQ,KAAK,SAAS,MAAM,SAAS,QAAS,EAAU,SAAU,EAChE,UAAU,8FACV,EAAA,EAAA,KAAC,EAAD,CAAQ,UAAU,WAAa,CAAA,CACxB,CAAA,CACR,CAAA,CAAA,CAED,GACF,GAIV,SAAS,GAAa,CACpB,OAAM,QAAO,WAAU,SAAQ,WAAU,SAQxC,CACD,SAAS,EAAM,EAAsB,CAAE,EAAS,CAAE,GAAG,EAAM,GAAG,EAAG,CAAC,CAClE,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,0EAAf,EACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,+EAAuE,EAAQ,WAAa,YAAkB,CAAA,EAE7H,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,qCAAf,EACE,EAAA,EAAA,MAAC,QAAD,CAAO,UAAU,qBAAjB,EACE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,yDAAgD,mBAAuB,CAAA,EACvF,EAAA,EAAA,KAAC,EAAD,CAAO,MAAO,EAAK,MAAO,SAAW,GAAM,EAAM,CAAE,MAAO,EAAE,OAAO,MAAO,CAAC,CACzE,YAAY,iCAAiC,UAAU,cAAgB,CAAA,CACnE,IACR,EAAA,EAAA,MAAC,QAAD,CAAO,UAAU,qBAAjB,EACE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,yDAAgD,kBAAsB,CAAA,EACtF,EAAA,EAAA,MAAC,EAAD,CAAQ,MAAO,EAAK,eAAgB,cAAgB,GAAM,EAAM,CAAE,eAAgB,EAAG,CAAC,UAAtF,EACE,EAAA,EAAA,KAAC,EAAD,CAAe,UAAU,wBAAc,EAAA,EAAA,KAAC,EAAD,EAAe,CAAA,CAAgB,CAAA,EACtE,EAAA,EAAA,KAAC,EAAD,CAAA,SACG,GAAU,IAAK,IAAM,EAAA,EAAA,KAAC,EAAD,CAAoB,MAAO,EAAG,UAAU,mBAAW,EAAiB,EAAE,CAAc,CAAnE,EAAmE,CAAC,CAC7F,CAAA,CACT,GACH,GACJ,IAEN,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,qCAAf,EACE,EAAA,EAAA,MAAC,QAAD,CAAO,UAAU,qBAAjB,EACE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,yDAAgD,2BAA+B,CAAA,EAC/F,EAAA,EAAA,KAAC,EAAD,CAAO,MAAO,EAAK,cAAe,SAAW,GAAM,EAAM,CAAE,cAAe,EAAE,OAAO,MAAO,CAAC,CACzF,YAAY,gCAAgC,UAAU,wBAA0B,CAAA,EAClF,EAAA,EAAA,MAAC,OAAD,CAAM,UAAU,gEAAhB,CAAuE,mBACtD,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,qCAA4B,MAAU,CAAA,cAAS,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,qCAA4B,SAAa,CAAA,OAAE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,qCAA4B,aAAiB,CAAA,KACjM,GACD,IACR,EAAA,EAAA,MAAC,QAAD,CAAO,UAAU,qBAAjB,EACE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,yDAAgD,2BAA+B,CAAA,EAC/F,EAAA,EAAA,KAAC,EAAD,CAAO,MAAO,EAAK,gBAAiB,SAAW,GAAM,EAAM,CAAE,gBAAiB,EAAE,OAAO,MAAO,CAAC,CAC7F,YAAY,+BAA+B,UAAU,wBAA0B,CAAA,EACjF,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,gEAAuD,0EAEhE,CAAA,CACD,GACJ,IAEN,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,qCAAf,EACE,EAAA,EAAA,MAAC,QAAD,CAAO,UAAU,qBAAjB,EACE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,yDAAgD,yBAA6B,CAAA,EAC7F,EAAA,EAAA,KAAC,EAAD,CAAO,MAAO,EAAK,YAAa,SAAW,GAAM,EAAM,CAAE,YAAa,EAAE,OAAO,MAAO,CAAC,CACrF,YAAY,qBAAqB,UAAU,wBAA0B,CAAA,CACjE,IACR,EAAA,EAAA,MAAC,QAAD,CAAO,UAAU,qBAAjB,EACE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,yDAAgD,oBAAwB,CAAA,EACxF,EAAA,EAAA,KAAC,EAAD,CAAO,MAAO,EAAK,aAAc,SAAW,GAAM,EAAM,CAAE,aAAc,EAAE,OAAO,MAAO,CAAC,CACvF,YAAY,iBAAiB,UAAU,cAAgB,CAAA,CACnD,GACJ,IAEN,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,mCAAf,EACE,EAAA,EAAA,KAAC,EAAD,CAAQ,QAAS,EAAK,QAAS,gBAAkB,GAAY,EAAM,CAAE,UAAS,CAAC,CAAI,CAAA,EACnF,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,yCAAgC,UAAc,CAAA,CAC1D,GAEL,IAAS,EAAA,EAAA,KAAC,GAAD,CAAa,QAAS,EAAS,CAAA,EAEzC,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,sBAAf,EACE,EAAA,EAAA,MAAC,EAAD,CAAQ,KAAK,KAAK,QAAS,WAA3B,EACE,EAAA,EAAA,KAAC,EAAD,CAAM,UAAU,SAAW,CAAA,CAC1B,EAAQ,MAAQ,OACV,IACT,EAAA,EAAA,KAAC,EAAD,CAAQ,KAAK,KAAK,QAAQ,UAAU,QAAS,WAAU,SAAe,CAAA,CAClE,GACF,GC5YV,IAAM,GAAqB,UACrB,GAAoB,SACpB,GAAqB,UACrB,GAAqB,UACrB,GAAqB,CACzB,gBACA,iBACA,cACA,eACA,qBACA,0BACA,wBACA,yBACA,qBACA,2BACD,CAED,SAAS,IAAuB,CAC9B,GAAI,OAAO,OAAW,IAAa,MAAO,GAC1C,IAAM,EAAO,OAAO,SAAS,KAAK,QAAQ,KAAM,GAAG,CAEnD,OADK,EAAK,WAAW,YAAY,CAC1B,mBAAmB,EAAK,MAAM,EAAmB,CAAC,CADf,GAI5C,SAAS,GAAkB,EAAoB,CAC7C,GAAI,OAAO,OAAW,IAAa,OACnC,IAAM,EAAM,IAAI,IAAI,OAAO,SAAS,KAAK,CACzC,EAAI,KAAO,YAAY,mBAAmB,EAAK,GAC/C,OAAO,QAAQ,UAAU,EAAE,CAAE,GAAI,EAAI,CAGvC,SAAgB,IAAe,CAC7B,GAAM,CAAC,EAAU,IAAA,EAAA,EAAA,UAAwC,EAAE,CAAC,CACtD,CAAC,EAAO,IAAA,EAAA,EAAA,UAAqC,KAAK,CAClD,CAAC,EAAS,IAAA,EAAA,EAAA,UAA+C,EAAE,CAAC,CAC5D,CAAC,EAAQ,IAAA,EAAA,EAAA,cAA4B,IAAc,CAAC,CACpD,CAAC,EAAS,IAAA,EAAA,EAAA,UAAuB,GAAK,CACtC,CAAC,EAAW,IAAA,EAAA,EAAA,UAAyB,GAAG,CACxC,CAAC,EAAc,IAAA,EAAA,EAAA,UAA4B,GAAG,CAEpD,eAAe,GAAS,CACtB,EAAW,GAAK,CAChB,EAAa,GAAG,CAChB,EAAgB,GAAG,CACnB,GAAI,CACF,GAAM,CAAC,EAAa,EAAU,GAAgB,MAAM,QAAQ,IAAI,CAC9D,EAAsB,MAAO,YAAY,CACzC,EAAa,MAAO,aAAa,CACjC,EAAuB,MAAO,aAAa,CAAC,MAAO,IACjD,EAAiB,EAAY,QAAQ,CAC9B,CAAE,QAAS,EAAE,CAAE,EACtB,CACH,CAAC,CACF,EAAY,EAAY,SAAS,CACjC,EAAS,EAAS,CAClB,EAAW,EAAa,QAAQ,OACzB,EAAG,CACV,EAAc,EAAY,QAAQ,QAC1B,CACR,EAAW,GAAM,GAIrB,EAAA,EAAA,eAAgB,CACd,GAAa,EACZ,EAAE,CAAC,EAGN,EAAA,EAAA,eAAgB,CACd,IAAM,MAAa,EAAU,IAAc,CAAC,CAG5C,OAFA,OAAO,iBAAiB,aAAc,EAAK,CAC3C,OAAO,iBAAiB,WAAY,EAAK,KAC5B,CACX,OAAO,oBAAoB,aAAc,EAAK,CAC9C,OAAO,oBAAoB,WAAY,EAAK,GAE7C,EAAE,CAAC,CAEN,IAAM,GAAA,EAAA,EAAA,aAAiC,GAAc,EAAS,CAAE,CAAC,EAAS,CAAC,CACrE,GAAA,EAAA,EAAA,aAAuB,CAC3B,GAAG,EAAiB,IAAK,IAAW,CAClC,KAAM,EAAM,KACZ,MAAO,EAAM,MACb,YAAa,GAAG,EAAM,SAAS,OAAO,iBAAiB,EAAM,SAAS,SAAW,EAAI,GAAK,MAC1F,KAAM,cACN,SAAU,EAAM,SACjB,EAAE,CACH,CACE,KAAM,GACN,MAAO,UACP,YAAa,4CACb,KAAM,UACN,SAAU,EAAE,CACb,CACD,CACE,KAAM,GACN,MAAO,UACP,YAAa,0BACb,KAAM,UACN,SAAU,EAAE,CACb,CACD,CACE,KAAM,GACN,MAAO,UACP,YAAa,8BACb,KAAM,UACN,SAAU,EAAE,CACb,CACD,CACE,KAAM,GACN,MAAO,SACP,YAAa,yBACb,KAAM,SACN,SAAU,EAAE,CACb,CACF,CAAE,CAAC,EAAiB,CAAC,CAEhB,EAAc,EAAO,KAAM,GAAU,EAAM,OAAS,EAAO,EAAI,EAAO,GAE5E,SAAS,EAAY,EAAc,CACjC,EAAU,EAAK,CACf,GAAkB,EAAK,CAGzB,SAAS,EAAe,EAAuB,CAC7C,EAAa,GAAY,EAAQ,IAAK,GAAU,EAAU,EAAM,GAAK,EAAU,EAAQ,CAAG,EAAU,EAAM,CAAC,CAG7G,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,qBAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,4DAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,iCAAwB,WAAa,CAAA,EACnD,EAAA,EAAA,KAAC,IAAD,CAAG,UAAU,yCAAgC,iFAAkF,CAAA,CAC3H,CAAA,CAAA,EACN,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,6CAAf,CACG,IACC,EAAA,EAAA,MAAC,EAAD,CAAO,QAAQ,UAAU,UAAU,iBAAnC,EACE,EAAA,EAAA,KAAC,GAAD,CAAQ,UAAU,SAAW,CAAA,CAC5B,EAAM,KAAK,IAAE,EAAM,MACd,IAEV,EAAA,EAAA,MAAC,EAAD,CAAQ,QAAQ,UAAU,KAAK,KAAK,YAAe,KAAK,GAAQ,CAAE,SAAU,WAA5E,EACE,EAAA,EAAA,KAAC,EAAD,CAAW,UAAW,EAAG,SAAU,GAAW,eAAe,CAAI,CAAA,CAAA,UAE1D,GACL,GACF,GAEL,IACC,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,yHAAf,EACE,EAAA,EAAA,KAAC,EAAD,CAAa,UAAU,gBAAkB,CAAA,EACzC,EAAA,EAAA,KAAC,OAAD,CAAA,SAAO,EAAiB,CAAA,CACpB,IAGR,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,yDAAf,EACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,sDACZ,EAAO,IAAK,IACX,EAAA,EAAA,MAAC,SAAD,CAEE,KAAK,SACL,UAAW,EACT,yEACA,GAAa,OAAS,EAAM,KAAO,kDAAoD,yDACxF,CACD,YAAe,EAAY,EAAM,KAAK,UAPxC,EASE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,6BAAqB,EAAM,MAAa,CAAA,EACxD,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,wDAAgD,EAAM,YAAmB,CAAA,CAClF,EAVF,EAAM,KAUJ,CACT,CACE,CAAA,EAEN,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,6BACZ,GAAW,CAAC,EAAS,QACpB,EAAA,EAAA,KAAC,EAAD,CAAM,KAAK,eACT,EAAA,EAAA,KAAC,EAAD,CAAa,UAAU,yCAAgC,oBAA+B,CAAA,CACjF,CAAA,CACL,GAAa,OAAS,WACxB,EAAA,EAAA,KAAC,GAAD,CAAiB,SAAU,GAAS,GAAO,OAAQ,yBAAyB,CAAI,CAAA,CAC9E,GAAa,OAAS,eACxB,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,GAAD,CACE,MAAO,EAAY,MACnB,SAAU,EAAY,SACtB,QAAS,EACT,CAAA,CAED,EAAY,QAAU,cACrB,EAAA,EAAA,KAAC,GAAD,CAAe,SAAU,GAAS,GAAO,OAAQ,0BAA0B,CAAI,CAAA,CAEhF,EAAY,QAAU,kBACrB,EAAA,EAAA,KAAC,GAAD,EAAmC,CAAA,CAEpC,CAAA,CAAA,CACD,GAAa,OAAS,WACxB,EAAA,EAAA,KAAC,GAAD,EAAmB,CAAA,CACjB,GAAa,OAAS,WACxB,EAAA,EAAA,KAAC,GAAD,EAAmB,CAAA,EAEnB,EAAA,EAAA,KAAC,GAAD,CACW,UACT,MAAO,EACP,SAAU,GAAS,GAAO,OAAQ,0BAA0B,CAC5D,UAAW,EACX,CAAA,CAEA,CAAA,CACF,GACF,GAIV,SAAS,IAAkC,CACzC,GAAM,CAAC,EAAM,IAAA,EAAA,EAAA,UAAoB,gBAAgB,CAC3C,CAAC,EAAW,IAAA,EAAA,EAAA,UAAyB;;GAA8B,CACnE,CAAC,EAAS,IAAA,EAAA,EAAA,UAA0D,KAAK,CACzE,CAAC,EAAS,IAAA,EAAA,EAAA,UAAuB,GAAM,CACvC,CAAC,EAAO,IAAA,EAAA,EAAA,UAAqB,GAAG,CAEtC,eAAe,GAAa,CAC1B,EAAW,GAAK,CAChB,EAAS,GAAG,CACZ,GAAI,CACF,IAAM,EAAQ,KAAK,MAAM,EAAU,CACnC,GAAI,CAAC,GAAS,OAAO,GAAU,UAAY,MAAM,QAAQ,EAAM,CAAE,MAAU,MAAM,8BAA8B,CAE/G,GAAW,MADU,EAAiC,OAAQ,yBAA0B,CAAE,OAAM,QAAO,CAAC,EACtF,QAAQ,OACnB,EAAG,CACV,EAAW,KAAK,CAChB,EAAU,EAAY,QAAQ,QACtB,CACR,EAAW,GAAM,EAIrB,OACE,EAAA,EAAA,KAAC,EAAD,CAAM,KAAK,eACT,EAAA,EAAA,MAAC,EAAD,CAAa,UAAU,qBAAvB,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,6DAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,iCAAwB,gBAAkB,CAAA,EACxD,EAAA,EAAA,KAAC,IAAD,CAAG,UAAU,yCAAgC,gDAAiD,CAAA,CAC1F,CAAA,CAAA,EACN,EAAA,EAAA,MAAC,EAAD,CAAQ,KAAK,KAAK,YAAe,KAAK,GAAY,CAAE,SAAU,WAA9D,EACE,EAAA,EAAA,KAAC,EAAD,CAAO,UAAU,SAAW,CAAA,CAAA,UAErB,GACL,IACN,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,yDAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,uBAAf,EACE,EAAA,EAAA,KAAC,QAAD,CAAO,UAAU,qDAA4C,OAAY,CAAA,EACzE,EAAA,EAAA,MAAC,EAAD,CAAQ,MAAO,EAAM,cAAe,WAApC,EACE,EAAA,EAAA,KAAC,EAAD,CAAe,UAAU,mBACvB,EAAA,EAAA,KAAC,EAAD,EAAe,CAAA,CACD,CAAA,EAChB,EAAA,EAAA,KAAC,EAAD,CAAA,SACG,GAAmB,IAAK,IAAS,EAAA,EAAA,KAAC,EAAD,CAAuB,MAAO,WAAO,EAAkB,CAAtC,EAAsC,CAAC,CAC5E,CAAA,CACT,GACL,IACN,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,uBAAf,EACE,EAAA,EAAA,KAAC,QAAD,CAAO,UAAU,qDAA4C,QAAa,CAAA,EAC1E,EAAA,EAAA,KAAC,GAAD,CAAU,MAAO,EAAW,SAAW,GAAM,EAAa,EAAE,OAAO,MAAM,CAAE,KAAM,EAAG,UAAU,oBAAsB,CAAA,CAChH,GACF,GACL,IACC,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,yHAAf,EACE,EAAA,EAAA,KAAC,EAAD,CAAa,UAAU,kBAAoB,CAAA,EAC3C,EAAA,EAAA,KAAC,OAAD,CAAA,SAAO,EAAa,CAAA,CAChB,GAEP,IACC,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,2DACZ,EAAQ,WAAW,SAAW,GAC7B,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,+DAAsD,gBAAmB,CAAA,CACtF,EAAQ,WAAW,IAAK,IAC1B,EAAA,EAAA,MAAC,MAAD,CAA6D,UAAU,4IAAvE,EACE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,gCAAwB,EAAU,UAAiB,CAAA,EACnE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,oDAA4C,EAAU,YAAmB,CAAA,EACzF,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,0CAAkC,EAAU,OAAc,CAAA,CACtE,EAJI,GAAG,EAAU,UAAU,GAAG,EAAU,cAIxC,CACN,CACE,CAAA,CAEI,GACT,CAAA,CAIX,SAAS,IAAkB,CACzB,IAAM,EAAa,EAAe,GAAM,EAAE,WAAW,CAC/C,GAAA,EAAA,EAAA,QAAmC,KAAK,CACxC,CAAC,EAAM,IAAA,EAAA,EAAA,UAAiC,KAAK,CAC7C,CAAC,EAAa,IAAA,EAAA,EAAA,UAA2B,GAAG,CAC5C,CAAC,EAAS,IAAA,EAAA,EAAA,UAAuB,GAAK,CACtC,CAAC,EAAQ,IAAA,EAAA,EAAA,UAAsB,GAAM,CACrC,CAAC,EAAO,IAAA,EAAA,EAAA,UAAqB,GAAG,CAEtC,eAAe,GAAc,CAC3B,EAAW,GAAK,CAChB,EAAS,GAAG,CACZ,GAAI,CACF,IAAM,EAAO,MAAM,EAAU,MAAO,YAAY,CAChD,EAAQ,EAAK,CACb,EAAe,EAAK,aAAe,EAAK,OAAO,OACxC,EAAG,CACV,EAAU,EAAY,QAAQ,QACtB,CACR,EAAW,GAAM,GAIrB,EAAA,EAAA,eAAgB,CACd,GAAkB,EACjB,EAAE,CAAC,CAEN,eAAe,GAAc,CAC3B,EAAU,GAAK,CACf,EAAS,GAAG,CACZ,GAAI,CACF,IAAM,EAAO,MAAM,EAAU,QAAS,YAAa,CAAE,cAAa,CAAC,CACnE,EAAQ,EAAK,CACb,EAAe,EAAK,aAAe,EAAK,OAAO,CAC/C,MAAM,GAAY,OACX,EAAG,CACV,EAAU,EAAY,QAAQ,QACtB,CACR,EAAU,GAAM,EAIpB,eAAe,EAAa,EAAwB,CAC7C,KAEL,CADA,EAAU,GAAK,CACf,EAAS,GAAG,CACZ,GAAI,CACF,IAAM,EAAM,MAAM,EAA8C,mBAAoB,EAAK,CACzF,EAAQ,EAAI,KAAK,CACjB,EAAe,EAAI,KAAK,aAAe,EAAI,KAAK,OAAO,CACvD,MAAM,GAAY,OACX,EAAG,CACV,EAAU,EAAY,QAAQ,QACtB,CACR,EAAU,GAAM,CACZ,EAAQ,UAAS,EAAQ,QAAQ,MAAQ,MAIjD,eAAe,GAAe,CAC5B,EAAU,GAAK,CACf,EAAS,GAAG,CACZ,GAAI,CAEF,EAAQ,MADW,EAAU,SAAU,mBAAmB,CAC7C,CACb,MAAM,GAAY,OACX,EAAG,CACV,EAAU,EAAY,QAAQ,QACtB,CACR,EAAU,GAAM,EAIpB,OACE,EAAA,EAAA,KAAC,EAAD,CAAM,KAAK,eACT,EAAA,EAAA,MAAC,EAAD,CAAa,UAAU,qBAAvB,CACG,IACC,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,yHAAf,EACE,EAAA,EAAA,KAAC,EAAD,CAAa,UAAU,gBAAkB,CAAA,EACzC,EAAA,EAAA,KAAC,OAAD,CAAA,SAAO,EAAa,CAAA,CAChB,IAER,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,6CAAf,EACE,EAAA,EAAA,KAAC,GAAD,CAAY,KAAM,GAAQ,IAAA,GAAW,SAAA,GAAS,UAAU,kBAAoB,CAAA,EAC5E,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,oCAAf,EACE,EAAA,EAAA,KAAC,QAAD,CAAO,UAAU,kDAAkD,QAAQ,gCAAuB,eAAoB,CAAA,EACtH,EAAA,EAAA,KAAC,QAAD,CACE,GAAG,uBACH,UAAU,uEACV,MAAO,EACP,SAAW,GAAM,EAAe,EAAE,OAAO,MAAM,CAC/C,SAAU,GAAW,EACrB,UAAW,IACX,CAAA,CACE,GACF,IACN,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,6CAAf,EACE,EAAA,EAAA,MAAC,EAAD,CAAQ,KAAK,KAAK,YAAe,KAAK,GAAa,CAAE,SAAU,GAAW,GAAU,CAAC,EAAY,MAAM,UAAvG,EACE,EAAA,EAAA,KAAC,EAAD,CAAM,UAAU,SAAW,CAAA,CAAA,OAEpB,IACT,EAAA,EAAA,MAAC,EAAD,CAAQ,KAAK,KAAK,QAAQ,UAAU,YAAe,EAAQ,SAAS,OAAO,CAAE,SAAU,GAAW,WAAlG,EACE,EAAA,EAAA,KAAC,EAAD,CAAQ,UAAU,SAAW,CAAA,CAAA,SAEtB,IACT,EAAA,EAAA,MAAC,EAAD,CAAQ,KAAK,KAAK,QAAQ,UAAU,YAAe,KAAK,GAAc,CAAE,SAAU,GAAW,GAAU,CAAC,GAAM,0BAA9G,EACE,EAAA,EAAA,KAAC,EAAD,CAAQ,UAAU,SAAW,CAAA,CAAA,SAEtB,GACR,IAAU,EAAA,EAAA,KAAC,EAAD,CAAQ,UAAU,6CAA+C,CAAA,EAC5E,EAAA,EAAA,KAAC,QAAD,CACE,IAAK,EACL,KAAK,OACL,OAAO,4CACP,UAAU,SACV,SAAW,GAAM,KAAK,EAAa,EAAE,OAAO,QAAQ,GAAG,CACvD,CAAA,CACE,GACM,GACT,CAAA"}
|