@mackwan84/dsh-tool-ui-mockup 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","names":["useState","Button","useState","useId","useRef","panelCss","StateDot","IconNewChatOutline16","IconEditOutline16","IconCheckOutline16","useCallback","Button","Input","useMemo"],"sources":["../src/client/shared.ts","../src/client/toolview.tsx","../src/client/settings-panel.css?inline","../src/client/settings-panel.tsx","../src/client/locales.ts","../src/client/index.ts"],"sourcesContent":["/** 工具卡片与设置面板共享的客户端最小面:图片路由 URL 与 RPC 调用折叠。 */\n\n/** 图片文件名 → webServer 路由 URL(host 半区 /ui-mockup/images 服务资产库图片)。 */\nexport function imageUrl(name: string, cwd?: string): string {\n const base = `/ui-mockup/images/${encodeURIComponent(name)}`\n return cwd !== undefined && cwd !== '' ? `${base}?cwd=${encodeURIComponent(cwd)}` : base\n}\n\n/** connection 服务的客户端结构面(本包只用 rpc.call 与 isLoopback)。 */\nexport interface ConnectionFace {\n readonly isLoopback: boolean\n readonly rpc: {\n call(\n channel: string,\n endpoint: string,\n payload?: unknown,\n signal?: AbortSignal,\n ): Promise<RpcResultLike<unknown>>\n }\n}\n\n/** 与宿主半区同构的 RPC 结果形状。 */\nexport type RpcResultLike<T> =\n { ok: true; value: T } | { ok: false; error: { code: string; message: string } }\n\n/**\n * 把 RPC 结果折叠成「值或抛错」:错误信息面向用户可读,\n * 错误码保留在消息前缀便于排障。\n * 注意:宿主信封校验要求 payload 必填(clientRequestSchema 的 payload 为\n * z.unknown() 非可选),JSON.stringify 会丢弃值为 undefined 的字段,因此\n * 无参端点(overview / test-connection)也必须发送一个 {}。\n */\nexport async function callPanel<T>(\n connection: ConnectionFace,\n endpoint: string,\n payload: Record<string, unknown> = {},\n): Promise<T> {\n const result = await connection.rpc.call('/ui-mockup', endpoint, payload ?? {})\n if (!result.ok) throw new Error(`[${result.error.code}] ${result.error.message}`)\n return result.value as T\n}\n\n/**\n * settings 域的客户端结构面(bind 由 ui-settings 插件在运行时提供);\n * 面板经由它把同名命名空间镜像绑到本插件 fiber。\n */\nexport interface SettingsScopeBinderFace {\n bind<T>(spec: { namespace: string }): PrefScope<T>\n}\n\nexport interface ScopeSnapshot<T> {\n status: 'loading' | 'ready' | 'unavailable'\n value: T | undefined\n user: unknown\n base: unknown\n revision: number | undefined\n writable: boolean\n mode: 'host' | 'memory'\n}\n\nexport interface PrefScope<T> {\n getSnapshot(): ScopeSnapshot<T>\n subscribe(listener: () => void): () => void\n set(field: string, value: unknown): Promise<void>\n unset(field: string): Promise<void>\n}\n\n/**\n * 历史分页每页条数——与宿主 prefs.ts 的 HISTORY_PAGE_SIZE 必须保持一致\n * (两端各持一份纯常量,避免客户端 import 宿主模块带入 schemastery 等依赖)。\n */\nexport const HISTORY_PAGE_SIZE = 5\n\n/** 锚点在过滤后列表中的索引 → 所在页码(1-based);无锚点(-1)返回 null。 */\nexport function anchorPageOf(anchorIndex: number, pageSize: number): number | null {\n return anchorIndex < 0 ? null : Math.floor(anchorIndex / pageSize) + 1\n}\n","/**\n * ui_mockup 工具卡片:生成图内嵌展示 + 确认/选用/修改意见反馈按钮。\n * 纯展示组件,接收 tool.call.toolview 的 owner payload 与框架注入的\n * `t`(i18n)和 `inputActions`(反馈按钮通过 setDraft + submit 发送消息)。\n * 视觉与 DSH 原生一致:Button 原语 + --dsw-alias-* 主题令牌。\n */\nimport { useState } from 'react'\nimport { Button } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { ToolCallViewProps } from '@deepseek-ai/dsh-client-ui-tool/client'\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport { imageUrl } from './shared.js'\nimport type { NS } from './locales.js'\n\ntype Props = ToolCallViewProps & PropsLocale<typeof NS> & { anchor?: ToolviewAnchorFace }\n\n/** 卡片锚点注入面:由注册方闭包捕获 connection 提供,直连 RPC 不经 agent。 */\nexport interface ToolviewAnchorFace {\n set(file: string, cwd?: string): Promise<unknown>\n}\n\n/** 图片附件引用(会话附件块里的 image 块所携带的最小结构)。 */\ninterface ImageRef {\n readonly name?: string\n readonly mediaType?: string\n readonly width?: number\n readonly height?: number\n}\n\n/** 反馈按钮发送给 agent 的消息正文(中文固定,模型可见文本不随 UI 语言切换)。 */\nfunction buildFeedbackMessage(\n t: Props['t'],\n name: string,\n index: number,\n opinion?: string,\n): string {\n if (opinion !== undefined && opinion.trim() !== '') {\n return t('card.feedbackMessage', { opinion: opinion.trim(), name })\n }\n return t('card.selectMessage', { n: index + 1, name })\n}\n\nexport function UiMockupToolview({ block, inputActions, cwd, t, anchor }: Props) {\n const [showFeedback, setShowFeedback] = useState(false)\n const [opinion, setOpinion] = useState('')\n const [selected, setSelected] = useState('')\n // 多图设锚下拉的受控值(选完即复位,与「选用某一版」同款交互)\n const [anchorPicked, setAnchorPicked] = useState('')\n // 本卡已设为锚点的图名集合(点击即时反馈;权威状态在历史页/概览页)\n const [anchoredNames, setAnchoredNames] = useState<ReadonlySet<string>>(new Set())\n const [anchorError, setAnchorError] = useState('')\n\n const setAnchor = async (name: string) => {\n if (anchor === undefined) return\n setAnchorError('')\n try {\n await anchor.set(name, cwd)\n setAnchoredNames((prev) => new Set(prev).add(name))\n } catch (err) {\n setAnchorError(err instanceof Error ? err.message : String(err))\n }\n }\n\n if (!('kind' in block)) {\n return (\n <div style={{ padding: '8px 0', fontSize: 13, color: 'var(--dsw-alias-label-tertiary)' }}>\n {t('card.generating')}\n </div>\n )\n }\n\n const images = block.content.filter((item) => item.type === 'image')\n const message = block.content\n .filter((item) => item.type === 'text')\n .map((item) => item.text)\n .join('')\n\n if (images.length === 0) {\n return (\n <div\n style={{\n padding: '8px 0',\n whiteSpace: 'pre-wrap',\n fontSize: 13,\n lineHeight: '20px',\n color: 'var(--dsw-alias-label-primary)',\n }}\n >\n {message}\n </div>\n )\n }\n\n const send = (text: string) => {\n inputActions.setDraft(text)\n inputActions.submit()\n }\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 8, padding: '8px 0' }}>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>\n {images.map((image, index) => {\n const ref = image.attachment as ImageRef\n const name = ref.name ?? `mockup-${index + 1}.png`\n const anchored = anchoredNames.has(name)\n return (\n <figure key={`${name}:${index}`} style={{ margin: 0 }}>\n <img\n src={imageUrl(name, cwd)}\n alt={name}\n loading=\"lazy\"\n style={{\n maxWidth: 240,\n maxHeight: 240,\n borderRadius: 8,\n border: `1px solid ${anchored ? 'var(--dsw-alias-brand-primary)' : 'var(--dsw-alias-border-l2)'}`,\n objectFit: 'contain',\n background: 'var(--dsw-alias-bg-layer-3)',\n }}\n />\n <figcaption\n style={{\n fontSize: 12,\n lineHeight: '17px',\n color: 'var(--dsw-alias-label-tertiary)',\n marginTop: 2,\n }}\n >\n {name}\n {anchored ? ` · ${t('card.anchored')}` : ''}\n </figcaption>\n </figure>\n )\n })}\n </div>\n {anchorError !== '' && (\n <div style={{ fontSize: 12, color: 'var(--dsw-alias-label-error)' }}>{anchorError}</div>\n )}\n\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, alignItems: 'center' }}>\n <Button\n variant=\"primary\"\n size=\"sm\"\n onClick={() =>\n send(t('card.confirmMessage', { name: images[0]!.attachment.name ?? 'mockup-1.png' }))\n }\n >\n {t('card.confirm')}\n </Button>\n {images.length > 1 && (\n <select\n value={selected}\n onChange={(event) => {\n const raw = event.target.value\n // placeholder(空值)不可触发;Number('') === 0 会误发\"选用第 1 版\"\n if (raw === '') return\n const index = Number(raw)\n setSelected('')\n const name = (images[index]!.attachment as ImageRef).name ?? `mockup-${index + 1}.png`\n send(buildFeedbackMessage(t, name, index))\n }}\n style={{\n height: 28,\n padding: '0 8px',\n border: '1px solid var(--dsw-alias-border-l2)',\n borderRadius: 999,\n background: 'var(--dsw-alias-bg-layer-3)',\n font: 'inherit',\n fontSize: 13,\n color: 'var(--dsw-alias-label-primary)',\n }}\n >\n <option value=\"\" disabled>\n {t('card.selectPlaceholder')}\n </option>\n {images.map((image, index) => (\n <option key={index} value={index}>\n {t('card.select', { n: index + 1 })}\n </option>\n ))}\n </select>\n )}\n {/* 设锚入口:单图直接按钮;多图下拉选版本(与「选用某一版」同款胶囊) */}\n {anchor !== undefined &&\n (images.length === 1 ? (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n title={t('card.setAnchor')}\n onClick={() => void setAnchor(images[0]!.attachment.name ?? 'mockup-1.png')}\n >\n {t('card.setAnchorButton')}\n </Button>\n ) : (\n <select\n value={anchorPicked}\n onChange={(event) => {\n const raw = event.target.value\n // placeholder(空值)不可触发;Number('') === 0 会误设第 1 版\n if (raw === '') return\n const index = Number(raw)\n setAnchorPicked('')\n const name =\n (images[index]!.attachment as ImageRef).name ?? `mockup-${index + 1}.png`\n void setAnchor(name)\n }}\n title={t('card.setAnchor')}\n style={{\n height: 28,\n padding: '0 8px',\n border: '1px solid var(--dsw-alias-border-l2)',\n borderRadius: 999,\n background: 'var(--dsw-alias-bg-layer-3)',\n font: 'inherit',\n fontSize: 13,\n color: 'var(--dsw-alias-label-primary)',\n }}\n >\n <option value=\"\" disabled>\n {t('card.setAnchorSelect')}\n </option>\n {images.map((image, index) => (\n <option key={index} value={index}>\n {t('card.setAnchorOption', { n: index + 1 })}\n </option>\n ))}\n </select>\n ))}\n {/* 图片本体在资产库(不在工作区),打开原图走图片路由新开页 */}\n {(() => {\n const firstName = images[0]!.attachment.name ?? 'mockup-1.png'\n return (\n <a href={imageUrl(firstName, cwd)} target=\"_blank\" rel=\"noreferrer\">\n <Button variant=\"ghost\" size=\"sm\">\n {t('card.openOriginal')}\n </Button>\n </a>\n )\n })()}\n <Button variant=\"ghost\" size=\"sm\" onClick={() => setShowFeedback((value) => !value)}>\n {t('card.feedback')}\n </Button>\n </div>\n\n {showFeedback && (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>\n <textarea\n value={opinion}\n onChange={(event) => setOpinion(event.target.value)}\n placeholder={t('card.feedbackPlaceholder')}\n rows={2}\n style={{\n resize: 'vertical',\n padding: '6px 12px',\n border: '1px solid var(--dsw-alias-border-l2)',\n borderRadius: 8,\n background: 'var(--dsw-alias-bg-layer-3)',\n font: 'inherit',\n fontSize: 13,\n lineHeight: '20px',\n color: 'var(--dsw-alias-label-primary)',\n }}\n />\n <div style={{ display: 'flex', gap: 8 }}>\n <Button\n variant=\"primary\"\n size=\"sm\"\n onClick={() => {\n const name = images[0]!.attachment.name ?? 'mockup-1.png'\n send(buildFeedbackMessage(t, name, 0, opinion))\n setOpinion('')\n setShowFeedback(false)\n }}\n >\n {t('card.feedbackSubmit')}\n </Button>\n <Button variant=\"ghost\" size=\"sm\" onClick={() => setShowFeedback(false)}>\n {t('card.feedbackCancel')}\n </Button>\n </div>\n </div>\n )}\n </div>\n )\n}\n",".ui-mockup-section,\n.ui-mockup-tabpanel,\n.ui-mockup-history-toolbar,\n.ui-mockup-history-row,\n.ui-mockup-history-summary {\n min-width: 0;\n}\n\n.ui-mockup-history-summary {\n flex: 1 1 0;\n overflow-wrap: anywhere;\n}\n\n.ui-mockup-section {\n box-sizing: border-box;\n /* 面板作为容器查询上下文:窄屏断点跟随宿主分配的实际内容宽度,\n 而非视口宽度(宿主设置弹窗的固定侧栏会让两者相差上百像素)。 */\n container-type: inline-size;\n}\n\n.ui-mockup-card,\n.ui-mockup-provider-card,\n.ui-mockup-overview,\n.ui-mockup-overview-status,\n.ui-mockup-quick-step {\n box-sizing: border-box;\n min-width: 0;\n max-width: 100%;\n}\n\n.ui-mockup-tabs {\n gap: 22px;\n max-width: 100%;\n overflow-x: auto;\n overflow-y: hidden;\n scrollbar-width: thin;\n}\n\n.ui-mockup-tab {\n flex: 0 0 auto;\n white-space: nowrap;\n}\n\n.ui-mockup-field-label {\n min-width: 96px;\n}\n\n.ui-mockup-model-select {\n max-width: 100%;\n}\n\n.ui-mockup-field-row > * {\n max-width: 100%;\n}\n\n.ui-mockup-history-search {\n flex: 1 1 220px;\n min-width: 0;\n}\n\n.ui-mockup-history-pagination,\n.ui-mockup-history-pages,\n.ui-mockup-history-anchor-nav {\n min-width: 0;\n max-width: 100%;\n}\n\n.ui-mockup-history-page-number {\n min-width: 28px;\n}\n\n@container (max-width: 640px) {\n .ui-mockup-tabs {\n gap: 16px;\n }\n\n .ui-mockup-field-label {\n flex: 1 0 100%;\n min-width: 0;\n }\n\n .ui-mockup-card,\n .ui-mockup-provider-card,\n .ui-mockup-preferences-footer,\n .ui-mockup-overview,\n .ui-mockup-overview-status,\n .ui-mockup-quick-step {\n overflow: hidden;\n overflow-wrap: anywhere;\n }\n\n .ui-mockup-overview-status,\n .ui-mockup-quick-step {\n flex-wrap: wrap;\n }\n\n .ui-mockup-field-row > *,\n .ui-mockup-preferences-footer > *,\n .ui-mockup-preferences-actions > *,\n .ui-mockup-preferences-actions button {\n box-sizing: border-box;\n min-width: 0;\n max-width: 100%;\n }\n\n .ui-mockup-preferences-footer button,\n .ui-mockup-preferences-actions button {\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n\n .ui-mockup-preferences-footer,\n .ui-mockup-history-toolbar,\n .ui-mockup-history-row,\n .ui-mockup-history-anchor-nav {\n flex-wrap: wrap;\n }\n\n .ui-mockup-history-toolbar,\n .ui-mockup-history-row,\n .ui-mockup-history-actions,\n .ui-mockup-history-pagination,\n .ui-mockup-history-pages,\n .ui-mockup-history-anchor-nav {\n overflow: hidden;\n }\n\n .ui-mockup-history-pages {\n flex-wrap: wrap;\n }\n\n .ui-mockup-history-toolbar > *,\n .ui-mockup-history-actions > *,\n .ui-mockup-history-actions button,\n .ui-mockup-history-anchor-nav > * {\n box-sizing: border-box;\n min-width: 0;\n max-width: 100%;\n }\n\n .ui-mockup-history-toolbar button,\n .ui-mockup-history-actions button,\n .ui-mockup-history-pages button,\n .ui-mockup-history-anchor-nav button {\n min-width: 0;\n max-width: 100%;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n\n .ui-mockup-history-row > img {\n max-width: 100%;\n height: auto;\n }\n\n .ui-mockup-preferences-actions,\n .ui-mockup-history-actions {\n width: 100%;\n }\n\n .ui-mockup-preferences-actions {\n justify-content: flex-end;\n }\n\n .ui-mockup-history-summary {\n flex-basis: calc(100% - 70px);\n }\n}\n","/**\n * 「UI 草图」设置区块:单个 settings.section 挂四张子页(概览 / 提供方与模型 /\n * 生成偏好 / 生成历史),子页内切换与已确认线框一致。\n * 视觉完全使用 DSH 主题令牌(--dsw-*)与原生控件,浅/深色自适应;\n * 数据面:偏好经同名 settings 命名空间镜像读写,历史/锚点/测试连接走私有 RPC 频道。\n */\nimport {\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type KeyboardEvent,\n type ReactNode,\n} from 'react'\nimport {\n Button,\n IconCheckOutline16,\n IconEditOutline16,\n IconNewChatOutline16,\n Input,\n StateDot,\n} from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\nimport {\n callPanel,\n imageUrl,\n HISTORY_PAGE_SIZE,\n anchorPageOf,\n type ConnectionFace,\n type PrefScope,\n} from './shared.js'\nimport type { NS, UiMockupKey } from './locales.js'\nimport panelCss from './settings-panel.css?inline'\n\n/** 偏好形状的客户端本地副本(不引入宿主 prefs 模块,避免把 schemastery 打进浏览器包)。 */\nexport interface PanelPrefs {\n defaultFidelity: 'wireframe' | 'high-fidelity'\n defaultPlatform: 'web' | 'mobile'\n defaultCount: number\n outputDir: string\n pollTimeoutMinutes: number\n wireframeModel: string\n highFidelityModel: string\n defaultSize: string\n}\n\n/** 面板本地默认值:须与宿主 DEFAULT_PREFS 保持一致(改动时两侧同步)。 */\nconst PANEL_DEFAULTS: PanelPrefs = {\n defaultFidelity: 'wireframe',\n defaultPlatform: 'web',\n defaultCount: 2,\n outputDir: 'design/images',\n pollTimeoutMinutes: 10,\n wireframeModel: '',\n highFidelityModel: '',\n defaultSize: '',\n}\n\n/**\n * settings 域的客户端结构面(bind 由 ui-settings 插件在运行时提供)。\n * 面板经由它把同名命名空间镜像绑到本插件 fiber;ScopeSnapshot/PrefScope\n * 定义见 ./shared.js,客户端本地不再重复。\n */\n\n/** 注入给面板组件的运行时句柄。 */\nexport interface UiMockupPanelInjected {\n prefs: PrefScope<PanelPrefs>\n connection: ConnectionFace\n}\n\ntype PanelProps = PropsLocale<typeof NS> & UiMockupPanelInjected\n\nconst SUBPAGES = ['overview', 'provider', 'preferences', 'history'] as const\ntype SubPage = (typeof SUBPAGES)[number]\n\n/** 子页标题 key 表(i18n词条 panel.tab.*)。 */\nconst TAB_KEYS: Record<SubPage, `panel.tab.${SubPage}`> = {\n overview: 'panel.tab.overview',\n provider: 'panel.tab.provider',\n preferences: 'panel.tab.preferences',\n history: 'panel.tab.history',\n}\n\nexport function UiMockupSection({ t, prefs, connection }: PanelProps) {\n const [page, setPage] = useState<SubPage>('overview')\n const tabsId = useId()\n const tabRefs = useRef<Array<HTMLButtonElement | null>>([])\n\n const selectTabFromKeyboard = (event: KeyboardEvent<HTMLButtonElement>, index: number) => {\n const nextIndex =\n event.key === 'Home'\n ? 0\n : event.key === 'End'\n ? SUBPAGES.length - 1\n : event.key === 'ArrowRight'\n ? (index + 1) % SUBPAGES.length\n : event.key === 'ArrowLeft'\n ? (index - 1 + SUBPAGES.length) % SUBPAGES.length\n : null\n if (nextIndex === null) return\n const nextPage = SUBPAGES[nextIndex]\n if (nextPage === undefined) return\n event.preventDefault()\n setPage(nextPage)\n tabRefs.current[nextIndex]?.focus()\n }\n\n const activeTabId = `${tabsId}-tab-${page}`\n const activePanelId = `${tabsId}-panel-${page}`\n return (\n <div className=\"ui-mockup-section\" style={sectionStyle}>\n <style data-ui-mockup-styles>{panelCss}</style>\n {/* 子页切换:对齐原生 Plugins 设置区的 tab 范式(底边线 + active 下划线) */}\n <div role=\"tablist\" aria-label={t('panel.nav')} className=\"ui-mockup-tabs\" style={tabsStyle}>\n {SUBPAGES.map((key, index) => (\n <button\n key={key}\n id={`${tabsId}-tab-${key}`}\n ref={(element) => {\n tabRefs.current[index] = element\n }}\n type=\"button\"\n role=\"tab\"\n className=\"ui-mockup-tab\"\n aria-selected={page === key}\n aria-controls={`${tabsId}-panel-${key}`}\n tabIndex={page === key ? 0 : -1}\n data-active={page === key}\n onClick={() => setPage(key)}\n onKeyDown={(event) => selectTabFromKeyboard(event, index)}\n style={page === key ? { ...tabStyle, ...tabActiveStyle } : tabStyle}\n >\n {t(TAB_KEYS[key])}\n </button>\n ))}\n </div>\n <div\n id={activePanelId}\n role=\"tabpanel\"\n aria-labelledby={activeTabId}\n className=\"ui-mockup-tabpanel\"\n tabIndex={0}\n >\n {page === 'overview' && <OverviewPage t={t} connection={connection} />}\n {page === 'provider' && <ProviderPage t={t} prefs={prefs} connection={connection} />}\n {page === 'preferences' && <PreferencesPage t={t} prefs={prefs} />}\n {page === 'history' && <HistoryPage t={t} connection={connection} />}\n </div>\n </div>\n )\n}\n\n/* ---------------- 原生令牌与共享原子 ---------------- */\n\n/**\n * DSH 真实主题令牌(--dsw-alias-*,与 ui-theme / ui-settings-plugins 的\n * module.css 同名同用途)与原生设置区实测尺寸。布局仍用内联样式,但取值\n * 逐项对齐 fields.module.css / PluginsSettingsSection.module.css,不再自造。\n */\nconst tokens = {\n labelPrimary: 'var(--dsw-alias-label-primary)',\n labelSecondary: 'var(--dsw-alias-label-secondary)',\n labelTertiary: 'var(--dsw-alias-label-tertiary)',\n labelError: 'var(--dsw-alias-label-error)',\n border: 'var(--dsw-alias-border-l2)',\n bgLayer: 'var(--dsw-alias-bg-layer-3)',\n brand: 'var(--dsw-alias-brand-primary)',\n} as const\n\n/** 面板根容器:与原生设置 section 同宽(max-width 760px)。 */\nconst sectionStyle = {\n display: 'flex',\n flexDirection: 'column',\n gap: 12,\n maxWidth: 760,\n width: '100%',\n color: tokens.labelPrimary,\n} as const\n\nconst tabsStyle = {\n display: 'flex',\n alignItems: 'flex-end',\n borderBottom: `1px solid ${tokens.border}`,\n marginTop: 2,\n} as const\n\nconst tabStyle = {\n position: 'relative' as const,\n border: 0,\n padding: '7px 1px 9px',\n background: 'transparent',\n color: tokens.labelTertiary,\n font: 'inherit',\n fontSize: 13,\n lineHeight: '20px',\n cursor: 'pointer',\n}\n\nconst tabActiveStyle = {\n color: tokens.labelPrimary,\n} as const\n\n/** select 与原生 .input 同款(34px 高 / 8px 圆角 / layer-3 背景 / focus 品牌色边框)。 */\nconst selectStyle = {\n height: 34,\n padding: '0 12px',\n border: `1px solid ${tokens.border}`,\n borderRadius: 8,\n background: tokens.bgLayer,\n font: 'inherit',\n fontSize: 13,\n lineHeight: '20px',\n color: tokens.labelPrimary,\n} as const\n\n/** 状态点:直接复用原语 StateDot(done 绿 / warning 琥珀),观感与会话列表一致。 */\nfunction StatusDot({ ok, busy }: { ok: boolean; busy?: boolean }) {\n return <StateDot state={busy ? 'ongoing' : ok ? 'done' : 'warning'} className=\"ui-mockup-dot\" />\n}\n\n/**\n * 卡片容器:恢复已确认线框的圆角卡片布局,视觉用真实令牌\n * (border-l2 边框 / 8px 圆角 / 标题 15px·600 对齐原生 heading 层级)。\n */\nfunction Card({ title, children }: { title?: string; children: ReactNode }) {\n return (\n <div\n className=\"ui-mockup-card\"\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 8,\n border: `1px solid ${tokens.border}`,\n borderRadius: 8,\n padding: '10px 12px',\n }}\n >\n {title !== undefined && (\n <span style={{ fontSize: 15, fontWeight: 600, lineHeight: '22px' }}>{title}</span>\n )}\n {children}\n </div>\n )\n}\n\n/**\n * 字段行:横排(label 左 96px,控件右)。为对齐原生 `.field + .field { border-top }`\n * 的表单节奏,相邻字段行之间画 1px 分隔线;卡片内首行由调用方传 `first` 免除。\n * 内容区统一 min-height 34(控件基准高)并垂直居中,使 radio / 输入框 / 纯文字行\n * 各行等高、底边齐平,分隔线间距一致。\n * 无障碍:用 role=group + aria-labelledby 而非 <label> 包裹——单个 label 只能\n * 隐式关联一个可标记元素,多 radio 场景下其余选项会失去标签关联。\n */\nfunction FieldRow({\n label,\n children,\n first = false,\n}: {\n label: string\n children: ReactNode\n first?: boolean\n}) {\n const labelId = useId()\n return (\n <div\n role=\"group\"\n aria-labelledby={labelId}\n className=\"ui-mockup-field-row\"\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 10,\n flexWrap: 'wrap',\n minHeight: 34,\n paddingTop: 10,\n ...(first ? {} : { borderTop: `1px solid ${tokens.border}` }),\n }}\n >\n <span\n id={labelId}\n className=\"ui-mockup-field-label\"\n style={{ fontSize: 13, lineHeight: '20px', color: tokens.labelSecondary }}\n >\n {label}\n </span>\n {children}\n </div>\n )\n}\n\n/** 提示行:对齐原生 hint(12px tertiary)/ invalid(12px error),不带边框。 */\nfunction Notice({ children, danger }: { children: ReactNode; danger?: boolean }) {\n return (\n <p\n style={{\n margin: 0,\n fontSize: 12,\n lineHeight: '20px',\n color: danger ? tokens.labelError : tokens.labelTertiary,\n }}\n >\n {children}\n </p>\n )\n}\n\n/* ---------------- 概览 ---------------- */\n\n/** 快速使用三步的图标与词条键(显式常量,规避模板字面量推断不进字典联合)。 */\nconst QUICK_STEPS = [\n {\n Icon: IconNewChatOutline16,\n title: 'panel.overview.step1Title',\n body: 'panel.overview.step1Body',\n },\n { Icon: IconEditOutline16, title: 'panel.overview.step2Title', body: 'panel.overview.step2Body' },\n {\n Icon: IconCheckOutline16,\n title: 'panel.overview.step3Title',\n body: 'panel.overview.step3Body',\n },\n] as const\n\n/** 面板用的凭据状态(与宿主 CredentialStatus 同构):只有三个事实,永不携带值。 */\nexport interface PanelCredential {\n configured: boolean\n source?: string\n writable: boolean\n}\n\ninterface OverviewData {\n provider: string\n credential: PanelCredential\n anchor: string | null\n}\n\nfunction OverviewPage({ t, connection }: Omit<PanelProps, 'prefs'>) {\n const [data, setData] = useState<OverviewData>()\n const [error, setError] = useState('')\n useEffect(() => {\n let alive = true\n callPanel<OverviewData>(connection, 'overview')\n .then((value) => {\n if (alive) setData(value)\n })\n .catch((err: unknown) => {\n if (alive) setError(err instanceof Error ? err.message : String(err))\n })\n return () => {\n alive = false\n }\n }, [connection])\n\n if (error !== '') return <Notice danger>{t('panel.loadFailed', { error })}</Notice>\n if (data === undefined)\n return <div style={{ color: tokens.labelTertiary }}>{t('panel.loading')}</div>\n\n return (\n <div\n className=\"ui-mockup-overview\"\n style={{ display: 'flex', flexDirection: 'column', gap: 12 }}\n >\n <p style={{ margin: 0, fontSize: 13, lineHeight: '20px', color: tokens.labelTertiary }}>\n {t('panel.overview.intro')}\n </p>\n <Card title={t('panel.overview.quickTitle')}>\n {QUICK_STEPS.map(({ Icon, title, body }) => (\n <div key={title} className=\"ui-mockup-quick-step\" style={{ display: 'flex', gap: 8 }}>\n <span aria-hidden style={{ flex: 'none', color: tokens.labelSecondary, marginTop: 2 }}>\n <Icon size={16} />\n </span>\n <p style={{ margin: 0, lineHeight: '20px' }}>\n <strong style={{ fontSize: 13 }}>{t(title)}</strong>\n <br />\n <span style={{ fontSize: 13, color: tokens.labelSecondary }}>{t(body)}</span>\n </p>\n </div>\n ))}\n </Card>\n <div\n className=\"ui-mockup-overview-status\"\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n fontSize: 13,\n lineHeight: '20px',\n color: tokens.labelSecondary,\n }}\n >\n <StatusDot ok={data.credential.configured} />\n {t('panel.overview.statusLine', {\n // 生效提供方由宿主端点给出;unknown(未挂载 image 服务)单独措辞\n provider:\n data.provider === 'volcengine' || data.provider === 'dashscope'\n ? t(PROVIDER_NAME_KEYS[data.provider])\n : t('panel.provider.unknown'),\n credential: data.credential.configured\n ? t('panel.credential.ready')\n : t('panel.credential.missing', {\n credential:\n data.provider === 'volcengine'\n ? PROVIDER_CREDENTIALS.volcengine\n : PROVIDER_CREDENTIALS.dashscope,\n }),\n })}\n </div>\n </div>\n )\n}\n\n/* ---------------- 提供方与模型 ---------------- */\n\n/** 来源层 id → 词条键(显式映射,规避模板字面量推断不进字典联合)。 */\nconst SOURCE_LABELS: Record<string, UiMockupKey> = {\n env: 'panel.credential.source.env',\n file: 'panel.credential.source.file',\n 'project-env': 'panel.credential.source.project-env',\n 'user-env': 'panel.credential.source.user-env',\n ambient: 'panel.credential.source.ambient',\n}\n\nfunction sourceLabelText(t: PanelProps['t'], source: string | undefined): string | undefined {\n if (source === undefined) return undefined\n const key = SOURCE_LABELS[source]\n return key === undefined ? source : t(key)\n}\n\nconst WIREFRAME_MODEL_HINTS: Record<ProviderId, string[]> = {\n dashscope: ['', 'qwen-image-3.0', 'qwen-image-2.0', 'wan2.7-image'],\n volcengine: ['', 'doubao-seedream-4-5-251128', 'doubao-seedream-4-0-250828'],\n unknown: ['', 'qwen-image-3.0'],\n}\nconst HIGH_FIDELITY_MODEL_HINTS: Record<ProviderId, string[]> = {\n dashscope: ['', 'qwen-image-3.0-pro', 'qwen-image-2.0-pro', 'wan2.7-image-pro'],\n volcengine: ['', 'doubao-seedream-5-0-pro-260628', 'doubao-seedream-5-0-260128'],\n unknown: ['', 'qwen-image-3.0-pro'],\n}\n\n/** 生效提供方 id(宿主 provider/status 端点返回;unknown = 未挂载 image 服务)。 */\ntype ProviderId = 'dashscope' | 'volcengine' | 'unknown'\n\n/** 各提供方的凭据引用名(与 Provider Config 默认值一致)。 */\nconst PROVIDER_CREDENTIALS: Record<ProviderId, string> = {\n dashscope: 'DASHSCOPE_API_KEY',\n volcengine: 'ARK_API_KEY',\n unknown: 'DASHSCOPE_API_KEY',\n}\n\n/** 生效提供方 id → 本地化名称键;unknown 无名可显,调用方特判。 */\nconst PROVIDER_NAME_KEYS: Record<Exclude<ProviderId, 'unknown'>, UiMockupKey> = {\n dashscope: 'panel.provider.dashscopeName',\n volcengine: 'panel.provider.volcengineName',\n}\n\nfunction ProviderPage({ t, prefs, connection }: PanelProps) {\n const snap = prefs.getSnapshot()\n usePrefSync(prefs)\n const [testResult, setTestResult] = useState<string | null>(null)\n const [testing, setTesting] = useState(false)\n const [writeError, setWriteError] = useState('')\n // 生效提供方:provider/status 端点的唯一事实源,决定卡片选中态/凭据名/模型 hints\n const [providerId, setProviderId] = useState<ProviderId>('unknown')\n // 端点不可达(旧宿主/纯内存部署)时置位:面板按安装默认(DashScope)渲染并说明原因,\n // 而不是把\"检测不到\"误显示成\"未启用\"。\n const [statusUnknown, setStatusUnknown] = useState(true)\n // 切换请求进行中:期间两张卡禁点,完成后刷新状态\n const [switching, setSwitching] = useState(false)\n // 切换落位后的伴随提示(如模型分层默认被重置)\n const [providerNotice, setProviderNotice] = useState<string | null>(null)\n // 凭据状态(configured/source/writable,永不含值):写入/清除后刷新\n const [credential, setCredential] = useState<PanelCredential | undefined>()\n const [keyDraft, setKeyDraft] = useState('')\n const [keyBusy, setKeyBusy] = useState(false)\n const [keyNotice, setKeyNotice] = useState<{ kind: 'ok' | 'error'; text: string } | null>(null)\n\n const refreshProviderStatus = useCallback(async (): Promise<ProviderId> => {\n try {\n const value = await callPanel<{ active: ProviderId }>(connection, 'provider/status')\n setProviderId(value.active)\n setStatusUnknown(false)\n return value.active\n } catch {\n setProviderId('unknown')\n setStatusUnknown(true)\n return 'unknown'\n }\n }, [connection])\n\n useEffect(() => {\n void refreshProviderStatus()\n }, [refreshProviderStatus])\n\n const credentialName = PROVIDER_CREDENTIALS[providerId]\n\n /** 一键切换生效提供方:宿主改写 home 用户层 patch(DSH 热重载),完成后刷新状态。 */\n const switchProvider = async (target: Exclude<ProviderId, 'unknown'>) => {\n if (switching) return\n setSwitching(true)\n setProviderNotice(null)\n try {\n const result = await callPanel<{ active: ProviderId; pending?: boolean }>(\n connection,\n 'provider/switch',\n { provider: target },\n )\n // 切换落位后重置模型分层默认:模型 ID 是提供方私有的,旧提供方的值\n // 残留会被当作显式 model 直传新网关而必败(INVALID_PARAMETER)。\n // best-effort:只读/内存态偏好写不进时不阻断切换,用户可手动改回。\n if (result.active === target && result.pending !== true) {\n const current = prefs.getSnapshot().value\n if (\n current !== undefined &&\n (current.wireframeModel !== '' || current.highFidelityModel !== '')\n ) {\n try {\n await prefs.set('wireframeModel', '')\n await prefs.set('highFidelityModel', '')\n setProviderNotice(t('panel.provider.modelsReset'))\n } catch {\n // 偏好不可写:切换本身已成功,重置跳过\n }\n }\n }\n } catch (err) {\n setTestResult(err instanceof Error ? err.message : String(err))\n } finally {\n // 热重载是异步落位(宿主端点内已等待到位),刷新拿到最终状态\n await refreshProviderStatus()\n await refreshCredential()\n setSwitching(false)\n }\n }\n\n const refreshCredential = useCallback(async (): Promise<PanelCredential | undefined> => {\n try {\n const value = await callPanel<{ credential: PanelCredential }>(connection, 'overview')\n setCredential(value.credential)\n return value.credential\n } catch {\n setCredential(undefined)\n return undefined\n }\n }, [connection])\n\n useEffect(() => {\n void refreshCredential()\n }, [refreshCredential])\n\n /** 写入(覆盖)或清除存储中的密钥;成功后清空草稿并刷新状态。 */\n const applyKey = async (endpoint: 'credential/set' | 'credential/unset') => {\n setKeyBusy(true)\n setKeyNotice(null)\n try {\n const payload = endpoint === 'credential/set' ? { value: keyDraft } : {}\n const result = await callPanel<{ credential: PanelCredential }>(connection, endpoint, payload)\n setCredential(result.credential)\n setKeyDraft('')\n setKeyNotice({\n kind: 'ok',\n text:\n endpoint === 'credential/set'\n ? t('panel.credential.savedNotice')\n : t('panel.credential.clearedNotice', { credential: credentialName }),\n })\n } catch (err) {\n setKeyNotice({ kind: 'error', text: err instanceof Error ? err.message : String(err) })\n } finally {\n setKeyBusy(false)\n }\n }\n\n const runTest = async () => {\n setTesting(true)\n setTestResult(null)\n try {\n // 宿主只回机器可判的 reason + 原始 detail,用户可见文案由本端按语言渲染\n const result = await callPanel<{\n ok: boolean\n reason?: string\n detail?: string\n }>(connection, 'test-connection')\n setTestResult(\n result.ok\n ? t('panel.test.ok')\n : result.reason === 'missing-key'\n ? t('panel.test.missingKey', { credential: credentialName })\n : result.reason === 'invalid-key'\n ? t('panel.test.invalidKey', { credential: credentialName })\n : result.reason === 'unknown'\n ? t('panel.test.unknown', { detail: result.detail ?? '' })\n : t('panel.test.gatewayFail', { detail: result.detail ?? '' }),\n )\n } catch (err) {\n setTestResult(err instanceof Error ? err.message : String(err))\n } finally {\n setTesting(false)\n }\n }\n\n const sourceLabel = sourceLabelText(t, credential?.source)\n\n /** 纯状态文本(不含来源),供提供方选中卡第一行使用;来源另起一行淡化展示。 */\n const credentialStatus =\n credential === undefined\n ? t('panel.credential.checking')\n : credential.configured\n ? t('panel.credential.ready')\n : t('panel.credential.missing', { credential: credentialName })\n\n const credentialLine =\n credential === undefined\n ? t('panel.credential.checking')\n : credential.configured\n ? sourceLabel === undefined\n ? t('panel.credential.ready')\n : t('panel.credential.readyWithSource', { source: sourceLabel })\n : t('panel.credential.missing', { credential: credentialName })\n\n // unknown 有两种语义,渲染分流:\n // - statusUnknown(端点不可达,旧宿主等):按安装默认把 DashScope 渲染为选中,\n // 并说明原因——\"检测不到\"不等于\"未启用\";\n // - 端点可达但 active=unknown:image 服务确实未挂载,两卡都未选中。\n const statusReadable = !statusUnknown\n const dashscopeActive = providerId === 'dashscope' || (providerId === 'unknown' && statusUnknown)\n const volcengineActive = providerId === 'volcengine'\n /** 选中卡:中性蓝灰边框 + 浅灰填充(对齐 DSH 原生「外观」选项卡);未选中:border-l2 实线。 */\n const providerCardStyle = (active: boolean) => ({\n flex: '1 1 200px',\n boxSizing: 'border-box' as const,\n border: active\n ? '1px solid var(--dsw-static-neutral-bluish-400)'\n : `1px solid ${tokens.border}`,\n borderRadius: 16,\n background: active ? 'var(--dsw-alias-bg-module-platform)' : 'transparent',\n padding: '10px 14px',\n cursor: 'default',\n })\n const providerMetaStyle = {\n marginTop: 4,\n display: 'flex',\n flexDirection: 'column' as const,\n gap: 2,\n }\n const providerStatusStyle = {\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n fontSize: 12,\n lineHeight: '17px',\n color: tokens.labelSecondary,\n }\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>\n {snap.mode === 'memory' || !snap.writable ? (\n <Notice>{t('panel.readonlyBanner')}</Notice>\n ) : null}\n {writeError !== '' && <Notice danger>{writeError}</Notice>}\n\n <Card title={t('panel.provider.title')}>\n {/* 提供方卡可点击切换:宿主端点改写 home 用户层 patch(DSH 热重载即时生效),\n 面板不直接写 bundle 层——组合行仍是唯一事实源,这里只是代写它。 */}\n {statusUnknown && <Notice>{t('panel.provider.unknownHint')}</Notice>}\n {providerNotice !== null && <Notice>{providerNotice}</Notice>}\n <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>\n <label\n className=\"ui-mockup-provider-card\"\n style={{\n ...providerCardStyle(dashscopeActive),\n cursor: dashscopeActive || switching ? 'default' : 'pointer',\n }}\n onClick={() => {\n if (!dashscopeActive) void switchProvider('dashscope')\n }}\n >\n <input\n type=\"radio\"\n name=\"ui-mockup-provider\"\n checked={dashscopeActive}\n disabled={switching}\n readOnly\n aria-label={t('panel.provider.dashscopeName')}\n />{' '}\n <strong style={{ fontSize: 13 }}>{t('panel.provider.dashscopeName')}</strong>\n <div style={providerMetaStyle}>\n {dashscopeActive ? (\n <>\n <div style={providerStatusStyle}>\n <StatusDot ok={credential?.configured === true} busy={switching} />\n {statusUnknown && providerId === 'unknown'\n ? t('panel.provider.fallbackActive')\n : credentialStatus}\n </div>\n {credential?.configured && sourceLabel !== undefined && (\n <div\n style={{\n fontSize: 12,\n lineHeight: '17px',\n color: tokens.labelTertiary,\n paddingLeft: 14,\n }}\n >\n {sourceLabel}\n </div>\n )}\n </>\n ) : (\n <div style={providerStatusStyle}>\n <StatusDot ok={false} busy={switching} />\n {t('panel.provider.inactive')}\n </div>\n )}\n </div>\n </label>\n <label\n className=\"ui-mockup-provider-card\"\n style={{\n ...providerCardStyle(volcengineActive),\n cursor: volcengineActive || switching ? 'default' : 'pointer',\n }}\n onClick={() => {\n if (!volcengineActive) void switchProvider('volcengine')\n }}\n >\n <input\n type=\"radio\"\n name=\"ui-mockup-provider\"\n checked={volcengineActive}\n disabled={switching}\n readOnly\n aria-label={t('panel.provider.volcengineName')}\n />{' '}\n <strong style={{ fontSize: 13 }}>{t('panel.provider.volcengineName')}</strong>\n <div style={providerMetaStyle}>\n {volcengineActive ? (\n <div style={providerStatusStyle}>\n <StatusDot ok={credential?.configured === true} busy={switching} />\n {credentialStatus}\n </div>\n ) : (\n <div\n style={{\n fontSize: 12,\n lineHeight: '17px',\n color: tokens.labelTertiary,\n }}\n >\n {statusReadable\n ? t('panel.provider.volcengineDisabled')\n : t('panel.provider.inactive')}\n </div>\n )}\n </div>\n </label>\n </div>\n </Card>\n\n <Card title={t('panel.credential.title', { credential: credentialName })}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>\n <span\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n flex: 1,\n fontSize: 13,\n lineHeight: '20px',\n color: tokens.labelSecondary,\n }}\n >\n <StatusDot ok={credential?.configured === true} busy={testing} />\n {credentialLine}\n </span>\n <Button variant=\"outline\" size=\"sm\" onClick={() => void runTest()} disabled={testing}>\n {testing ? t('panel.testing') : t('panel.testConnection')}\n </Button>\n </div>\n {testResult !== null && <Notice>{testResult}</Notice>}\n {/* 写入即覆盖、永不回显:草稿只在本地 state,回显的永远只有三个状态事实 */}\n {credential?.writable === true ? (\n <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', alignItems: 'center' }}>\n <Input\n type=\"password\"\n aria-label={t('panel.credential.keyInputLabel', { credential: credentialName })}\n style={{ flex: '1 1 220px' }}\n value={keyDraft}\n autoComplete=\"off\"\n placeholder={t('panel.credential.writePlaceholder', { credential: credentialName })}\n onChange={(event) => setKeyDraft(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter' && keyDraft.trim() !== '') void applyKey('credential/set')\n }}\n />\n <Button\n variant=\"primary\"\n size=\"sm\"\n disabled={keyBusy || keyDraft.trim() === ''}\n onClick={() => void applyKey('credential/set')}\n >\n {t('panel.credential.save')}\n </Button>\n {credential.configured && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n disabled={keyBusy}\n onClick={() => void applyKey('credential/unset')}\n >\n {t('panel.credential.clear')}\n </Button>\n )}\n </div>\n ) : credential !== undefined && credential.configured ? (\n <Notice>{t('panel.credential.notWritable', { source: sourceLabel ?? '' })}</Notice>\n ) : null}\n {keyNotice !== null && (\n <Notice danger={keyNotice.kind === 'error'}>{keyNotice.text}</Notice>\n )}\n <div\n style={{\n fontSize: 12,\n lineHeight: '17px',\n color: tokens.labelTertiary,\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n marginTop: 2,\n }}\n >\n <span style={{ fontWeight: 500, color: tokens.labelSecondary }}>\n {t('panel.credential.howTitle')}\n </span>\n <ol style={{ margin: 0, paddingLeft: 18 }}>\n <li>{t('panel.credential.way1', { credential: credentialName })}</li>\n <li>{t('panel.credential.way2')}</li>\n <li>{t('panel.credential.way3', { credential: credentialName })}</li>\n <li>{t('panel.credential.way4', { credential: credentialName })}</li>\n </ol>\n </div>\n </Card>\n\n <Card title={t('panel.models.title')}>\n <FieldRow first label={t('panel.models.wireframe')}>\n <select\n aria-label={t('panel.models.wireframe')}\n className=\"ui-mockup-model-select\"\n value={snap.value?.wireframeModel ?? ''}\n onChange={(event) =>\n void writePref(prefs, 'wireframeModel', event.target.value.trim(), setWriteError)\n }\n style={{ ...selectStyle, width: 'min(260px, 100%)' }}\n >\n <option value=\"\">{t('panel.models.followDefault')}</option>\n {WIREFRAME_MODEL_HINTS[providerId].filter(Boolean).map((m) => (\n <option key={m} value={m}>\n {m}\n </option>\n ))}\n </select>\n </FieldRow>\n <FieldRow label={t('panel.models.highFidelity')}>\n <select\n aria-label={t('panel.models.highFidelity')}\n className=\"ui-mockup-model-select\"\n value={snap.value?.highFidelityModel ?? ''}\n onChange={(event) =>\n void writePref(prefs, 'highFidelityModel', event.target.value.trim(), setWriteError)\n }\n style={{ ...selectStyle, width: 'min(260px, 100%)' }}\n >\n <option value=\"\">{t('panel.models.followDefault')}</option>\n {HIGH_FIDELITY_MODEL_HINTS[providerId].filter(Boolean).map((m) => (\n <option key={m} value={m}>\n {m}\n </option>\n ))}\n </select>\n </FieldRow>\n <Notice>\n {`${t('panel.models.wireframe')}: ${WIREFRAME_MODEL_HINTS[providerId].filter(Boolean).join(', ')} · ${t('panel.models.highFidelity')}: ${HIGH_FIDELITY_MODEL_HINTS[providerId].filter(Boolean).join(', ')}`}\n </Notice>\n </Card>\n </div>\n )\n}\n\n/* ---------------- 生成偏好 ---------------- */\n\nconst EDITABLE_PREF_FIELDS = [\n 'defaultFidelity',\n 'defaultPlatform',\n 'defaultCount',\n 'pollTimeoutMinutes',\n 'defaultSize',\n] as const\n\n/** 只比较本页可编辑字段;Provider 模型偏好不应影响本页保存按钮。 */\nfunction editablePrefsEqual(left: PanelPrefs, right: PanelPrefs): boolean {\n return (\n left.defaultFidelity === right.defaultFidelity &&\n left.defaultPlatform === right.defaultPlatform &&\n left.defaultCount === right.defaultCount &&\n left.pollTimeoutMinutes === right.pollTimeoutMinutes &&\n left.defaultSize === right.defaultSize\n )\n}\n\n/** unset 成功以用户层字段消失为准;resolved value 可以来自自定义 composition base。 */\nfunction editableUserOverridesCleared(user: unknown): boolean {\n if (user === undefined) return true\n if (typeof user !== 'object' || user === null || Array.isArray(user)) return false\n return EDITABLE_PREF_FIELDS.every((field) => !Object.prototype.hasOwnProperty.call(user, field))\n}\n\nfunction PreferencesPage({ t, prefs }: Omit<PanelProps, 'connection'>) {\n const snap = prefs.getSnapshot()\n usePrefSync(prefs)\n const initial = useMemo(() => snap.value ?? PANEL_DEFAULTS, [snap.value])\n const [draft, setDraft] = useState<PanelPrefs>(initial)\n const [baseline, setBaseline] = useState<PanelPrefs>(initial)\n const [savedAt, setSavedAt] = useState(0)\n const [error, setError] = useState('')\n const [mutating, setMutating] = useState(false)\n const mutationLock = useRef(false)\n const dirty = !editablePrefsEqual(draft, baseline)\n\n useEffect(() => {\n // 外部值到达/变化且本地没有未保存修改时回填草稿;避免覆盖正在编辑的内容\n if (!dirty && !mutating && snap.value !== undefined) {\n setDraft(snap.value)\n setBaseline(snap.value)\n }\n }, [dirty, mutating, snap.value])\n\n const patch = (part: Partial<PanelPrefs>) => {\n if (mutationLock.current) return\n setDraft((prev) => ({ ...prev, ...part }))\n }\n\n const beginMutation = (): boolean => {\n if (mutationLock.current) return false\n mutationLock.current = true\n setMutating(true)\n setSavedAt(0)\n setError('')\n return true\n }\n\n const endMutation = () => {\n mutationLock.current = false\n setMutating(false)\n }\n\n const confirmApplied = (expected: PanelPrefs): PanelPrefs => {\n const actual = prefs.getSnapshot().value\n if (actual === undefined || !editablePrefsEqual(actual, expected)) {\n throw new Error(t('panel.prefs.writeNotApplied'))\n }\n return actual\n }\n\n /** 单字段写入后立即确认落盘;宿主 set 失败时静默恢复(不抛错),逐字段确认\n 能在第一时间中止后续写入,避免静默部分落盘。 */\n const setField = async (field: (typeof EDITABLE_PREF_FIELDS)[number], value: unknown) => {\n await prefs.set(field, value)\n const actual = prefs.getSnapshot().value\n if (actual === undefined || actual[field] !== value) {\n throw new Error(t('panel.prefs.writeNotAppliedField', { field }))\n }\n }\n\n const confirmResetApplied = (): PanelPrefs => {\n const current = prefs.getSnapshot()\n if (current.value === undefined || !editableUserOverridesCleared(current.user)) {\n throw new Error(t('panel.prefs.writeNotApplied'))\n }\n return current.value\n }\n\n const save = async () => {\n if (!beginMutation()) return\n try {\n const saved = {\n ...draft,\n defaultCount: Math.min(4, Math.max(1, Math.round(draft.defaultCount))),\n pollTimeoutMinutes: Math.max(1, Math.round(draft.pollTimeoutMinutes)),\n }\n await setField('defaultFidelity', saved.defaultFidelity)\n await setField('defaultPlatform', saved.defaultPlatform)\n await setField('defaultCount', saved.defaultCount)\n await setField('pollTimeoutMinutes', saved.pollTimeoutMinutes)\n await setField('defaultSize', saved.defaultSize)\n const applied = confirmApplied(saved)\n setDraft(applied)\n setBaseline(applied)\n setSavedAt(Date.now())\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n endMutation()\n }\n }\n\n const resetDefaults = async () => {\n if (!beginMutation()) return\n try {\n for (const field of EDITABLE_PREF_FIELDS) {\n await prefs.unset(field)\n }\n const applied = confirmResetApplied()\n setDraft(applied)\n setBaseline(applied)\n setSavedAt(Date.now())\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n endMutation()\n }\n }\n\n const readonlyNote = snap.mode === 'memory' || !snap.writable\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>\n {readonlyNote && <Notice>{t('panel.readonlyBanner')}</Notice>}\n {error !== '' && <Notice danger>{error}</Notice>}\n <Card>\n <FieldRow first label={t('panel.prefs.fidelity')}>\n <Radio\n label={t('panel.prefs.fidelityWireframe')}\n checked={draft.defaultFidelity === 'wireframe'}\n onChange={() => patch({ defaultFidelity: 'wireframe' })}\n name=\"pref-fidelity\"\n disabled={readonlyNote || mutating}\n />\n <Radio\n label={t('panel.prefs.fidelityHigh')}\n checked={draft.defaultFidelity === 'high-fidelity'}\n onChange={() => patch({ defaultFidelity: 'high-fidelity' })}\n name=\"pref-fidelity\"\n disabled={readonlyNote || mutating}\n />\n </FieldRow>\n <FieldRow label={t('panel.prefs.platform')}>\n <Radio\n label=\"Web\"\n checked={draft.defaultPlatform === 'web'}\n onChange={() => patch({ defaultPlatform: 'web' })}\n name=\"pref-platform\"\n disabled={readonlyNote || mutating}\n />\n <Radio\n label=\"Mobile\"\n checked={draft.defaultPlatform === 'mobile'}\n onChange={() => patch({ defaultPlatform: 'mobile' })}\n name=\"pref-platform\"\n disabled={readonlyNote || mutating}\n />\n </FieldRow>\n <FieldRow label={t('panel.prefs.count')}>\n {[1, 2, 3, 4].map((n) => (\n <Radio\n key={n}\n label={String(n)}\n checked={draft.defaultCount === n}\n onChange={() => patch({ defaultCount: n })}\n name=\"pref-count\"\n disabled={readonlyNote || mutating}\n />\n ))}\n </FieldRow>\n {/* 输出目录已由设计资产库接管($DSH_HOME/mockups/<工作区>/images),不再可配 */}\n <FieldRow label={t('panel.prefs.pollTimeout')}>\n <Input\n type=\"number\"\n aria-label={t('panel.prefs.pollTimeout')}\n min={1}\n max={60}\n style={{ width: 100 }}\n value={draft.pollTimeoutMinutes}\n onChange={(event) => patch({ pollTimeoutMinutes: Number(event.target.value) })}\n disabled={readonlyNote || mutating}\n />\n <span style={{ fontSize: 12, color: tokens.labelTertiary }}>\n {t('panel.prefs.minutes')}\n </span>\n </FieldRow>\n <FieldRow label={t('panel.prefs.backoff')}>\n <span style={{ fontSize: 13, lineHeight: '20px', color: tokens.labelTertiary }}>\n {t('panel.prefs.backoffFixed')}\n </span>\n </FieldRow>\n <FieldRow label={t('panel.prefs.size')}>\n <select\n aria-label={t('panel.prefs.size')}\n value={draft.defaultSize}\n onChange={(event) => patch({ defaultSize: event.target.value })}\n disabled={readonlyNote || mutating}\n style={selectStyle}\n >\n <option value=\"\">{t('panel.models.followDefault')}</option>\n <option value=\"1024*1024\">1024*1024</option>\n <option value=\"1280*720\">1280*720</option>\n <option value=\"720*1280\">720*1280</option>\n </select>\n </FieldRow>\n </Card>\n <div\n className=\"ui-mockup-preferences-footer\"\n style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}\n >\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => void resetDefaults()}\n disabled={readonlyNote || mutating}\n >\n {t('panel.prefs.reset')}\n </Button>\n <div\n className=\"ui-mockup-preferences-actions\"\n style={{ display: 'flex', gap: 10, alignItems: 'center' }}\n >\n {savedAt > 0 && !dirty && (\n <span\n role=\"status\"\n aria-live=\"polite\"\n style={{ fontSize: 12, color: tokens.labelTertiary }}\n >\n {t('panel.prefs.saved')}\n </span>\n )}\n <Button\n variant=\"primary\"\n size=\"sm\"\n onClick={() => void save()}\n disabled={readonlyNote || mutating || !dirty}\n >\n {t('panel.prefs.save')}\n </Button>\n </div>\n </div>\n </div>\n )\n}\n\n/* ---------------- 生成历史 ---------------- */\n\ninterface HistoryRow extends Record<string, unknown> {\n time: string\n description: string\n files: string[]\n model?: string\n fidelity?: string\n platform?: string\n size?: string\n anchored: boolean\n}\n\nfunction HistoryPage({ t, connection }: Omit<PanelProps, 'prefs'>) {\n // 客户端第三方插件拿不到会话服务(ctx.get('sessions') 恒 undefined),\n // 历史/缩略图/锚点请求一律不传 cwd,由宿主按「会话 cwd → 最近登记根 → 进程根」\n // 回退链解析工作区——这是已验证有效的唯一路径。\n const cwd: string | undefined = undefined\n const [rows, setRows] = useState<HistoryRow[]>()\n const [anchorFile, setAnchorFile] = useState<string | null>(null)\n const [anchorIndex, setAnchorIndex] = useState(-1)\n const [total, setTotal] = useState(0)\n const [page, setPage] = useState(1)\n const [queryDraft, setQueryDraft] = useState('')\n const [appliedQuery, setAppliedQuery] = useState('')\n const [error, setError] = useState('')\n const [confirmingClear, setConfirmingClear] = useState(false)\n // 并发防护:连续翻页/搜索时多个 history/list 在飞,单调序号丢弃过期响应,\n // 避免晚到的旧响应覆盖新页码(页码高亮与内容错位)\n const requestSeq = useRef(0)\n\n // 服务端分页:宿主按 page/pageSize 切片返回当前页 + total + 锚点索引;\n // 页码越界由宿主钳制后回传 data.page,客户端直接采用,无需本地 clamp。\n const reload = useCallback(\n async (needle: string, targetPage: number) => {\n const seq = ++requestSeq.current\n setError('')\n try {\n const data = await callPanel<{\n anchorFile: string | null\n anchorIndex: number\n total: number\n page: number\n pageSize: number\n entries: HistoryRow[]\n }>(connection, 'history/list', {\n cwd,\n query: needle,\n page: targetPage,\n pageSize: HISTORY_PAGE_SIZE,\n })\n if (seq !== requestSeq.current) return\n setRows(data.entries)\n setAnchorFile(data.anchorFile)\n setAnchorIndex(data.anchorIndex)\n setTotal(data.total)\n setPage(data.page)\n } catch (err) {\n if (seq !== requestSeq.current) return\n setError(err instanceof Error ? err.message : String(err))\n }\n },\n [connection, cwd],\n )\n\n useEffect(() => {\n void reload('', 1)\n // 列表仅在 cwd/连接变化(reload 标识)时自动重载;搜索/翻页由交互显式触发。\n }, [reload])\n\n const submitSearch = () => {\n setAppliedQuery(queryDraft)\n void reload(queryDraft, 1)\n }\n\n const totalPages = Math.max(1, Math.ceil(total / HISTORY_PAGE_SIZE))\n const anchorPage = anchorPageOf(anchorIndex, HISTORY_PAGE_SIZE)\n\n const act = async (endpoint: string, payload: Record<string, unknown>, stayPage = page) => {\n try {\n await callPanel(connection, endpoint, payload)\n await reload(appliedQuery, stayPage)\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n }\n }\n\n if (error !== '') return <Notice danger>{t('panel.loadFailed', { error })}</Notice>\n if (rows === undefined)\n return <div style={{ color: tokens.labelTertiary }}>{t('panel.loading')}</div>\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>\n <div\n role=\"search\"\n aria-label={t('panel.history.searchLabel')}\n className=\"ui-mockup-history-toolbar\"\n style={{ display: 'flex', gap: 8 }}\n >\n <Input\n type=\"search\"\n aria-label={t('panel.history.searchLabel')}\n className=\"ui-mockup-history-search\"\n placeholder={t('panel.history.searchPlaceholder')}\n value={queryDraft}\n onChange={(event) => setQueryDraft(event.target.value)}\n onKeyDown={(event) => {\n if (event.key !== 'Enter') return\n event.preventDefault()\n submitSearch()\n }}\n />\n <Button variant=\"outline\" size=\"sm\" onClick={submitSearch}>\n {t('panel.history.search')}\n </Button>\n {/* 两段确认拆为确认/取消双按钮:同按钮 onBlur 重置会让键盘用户\n Tab 离开时意外丢失确认态,双按钮语义明确且无障碍友好 */}\n {confirmingClear ? (\n <>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() =>\n void act('history/clear', { cwd }, 1).finally(() => setConfirmingClear(false))\n }\n style={{ color: tokens.labelError, borderColor: tokens.labelError }}\n >\n {t('panel.history.confirmClear')}\n </Button>\n <Button variant=\"ghost\" size=\"sm\" onClick={() => setConfirmingClear(false)}>\n {t('panel.history.cancelClear')}\n </Button>\n </>\n ) : (\n <Button variant=\"ghost\" size=\"sm\" onClick={() => setConfirmingClear(true)}>\n {t('panel.history.clear')}\n </Button>\n )}\n </div>\n {queryDraft !== appliedQuery && (\n <span\n role=\"status\"\n aria-live=\"polite\"\n style={{ fontSize: 12, lineHeight: '17px', color: tokens.labelTertiary }}\n >\n {t('panel.history.pendingSearch')}\n </span>\n )}\n\n {rows.length === 0 && (\n <div\n style={{\n color: tokens.labelTertiary,\n fontSize: 13,\n lineHeight: '20px',\n padding: '18px 0',\n textAlign: 'center',\n }}\n >\n {t('panel.history.empty')}\n </div>\n )}\n\n {rows.map((row, index) => {\n const first = row.files[0]\n const name = first === undefined ? '' : (first.split('/').pop() ?? '')\n return (\n /* 已确认线框:横向卡片行;锚点行整行边框加粗 + 右上角旗标徽标。\n key 用 time+首图文件名:同秒多条 / 翻页过滤后 index 会错位,不能作 key */\n <div\n key={`${row.time}:${row.files[0] ?? index}`}\n className=\"ui-mockup-history-row\"\n style={{\n display: 'flex',\n gap: 10,\n alignItems: 'center',\n border: `${row.anchored ? 2 : 1}px solid ${tokens.border}`,\n borderRadius: 8,\n padding: 8,\n position: 'relative',\n }}\n >\n {row.anchored && (\n <span\n style={{\n position: 'absolute',\n top: -9,\n right: 10,\n background: 'var(--dsw-alias-bg-module-platform)',\n borderRadius: 999,\n fontSize: 11,\n lineHeight: '17px',\n padding: '1px 8px',\n fontWeight: 500,\n color: tokens.labelSecondary,\n }}\n >\n 🚩 {t('panel.history.anchorTag')}\n </span>\n )}\n {name !== '' && (\n <img\n src={imageUrl(name, cwd)}\n alt={name}\n loading=\"lazy\"\n width={56}\n height={56}\n style={{\n borderRadius: 8,\n border: `1px solid ${tokens.border}`,\n objectFit: 'cover',\n background: tokens.bgLayer,\n flexShrink: 0,\n }}\n />\n )}\n <div\n className=\"ui-mockup-history-summary\"\n style={{ minWidth: 0, display: 'flex', flexDirection: 'column', gap: 2 }}\n >\n <div\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n fontSize: 13,\n lineHeight: '20px',\n fontWeight: row.anchored ? 600 : 400,\n }}\n >\n {row.description}\n </div>\n <div style={{ fontSize: 12, lineHeight: '17px', color: tokens.labelTertiary }}>\n {formatTime(row.time)} · {row.model ?? '—'} · {row.size ?? '—'} ·{' '}\n {t('panel.history.fileCount', { n: row.files.length })}\n </div>\n </div>\n <div\n className=\"ui-mockup-history-actions\"\n style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}\n >\n {/* 设锚入口在对话卡片(点哪张设哪张);历史页只保留解除与查看 */}\n {row.anchored && (\n <Button variant=\"ghost\" size=\"sm\" onClick={() => void act('anchor/unset', { cwd })}>\n {t('panel.history.unsetAnchor')}\n </Button>\n )}\n {name !== '' && (\n <a href={imageUrl(name, cwd)} target=\"_blank\" rel=\"noreferrer\">\n <Button variant=\"outline\" size=\"sm\">\n {t('card.openOriginal')}\n </Button>\n </a>\n )}\n </div>\n </div>\n )\n })}\n {anchorPage !== null && anchorPage !== page && (\n <div\n className=\"ui-mockup-history-anchor-nav\"\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n fontSize: 12,\n lineHeight: '17px',\n color: tokens.labelSecondary,\n }}\n >\n <span>🚩 {t('panel.history.anchorOnPage', { n: anchorPage })}</span>\n <Button variant=\"ghost\" size=\"sm\" onClick={() => void reload(appliedQuery, anchorPage)}>\n {t('panel.history.goToAnchor')}\n </Button>\n </div>\n )}\n\n {totalPages > 1 && (\n <div\n className=\"ui-mockup-history-pagination\"\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 8,\n flexWrap: 'wrap',\n }}\n >\n <span style={{ fontSize: 12, color: tokens.labelTertiary }}>\n {t('panel.history.totalCount', { n: total })}\n </span>\n <div\n className=\"ui-mockup-history-pages\"\n style={{ display: 'flex', alignItems: 'center', gap: 4 }}\n >\n <Button\n variant=\"ghost\"\n size=\"sm\"\n disabled={page <= 1}\n onClick={() => void reload(appliedQuery, page - 1)}\n >\n {t('panel.history.prev')}\n </Button>\n {Array.from({ length: totalPages }, (_, i) => i + 1).map((p) => (\n <Button\n key={p}\n variant={p === page ? 'primary' : 'ghost'}\n size=\"sm\"\n className=\"ui-mockup-history-page-number\"\n onClick={() => void reload(appliedQuery, p)}\n >\n {p}\n </Button>\n ))}\n <Button\n variant=\"ghost\"\n size=\"sm\"\n disabled={page >= totalPages}\n onClick={() => void reload(appliedQuery, page + 1)}\n >\n {t('panel.history.next')}\n </Button>\n </div>\n </div>\n )}\n\n {anchorFile !== null && rows.some((r) => r.anchored) && (\n <Notice>{t('panel.history.anchorHint')}</Notice>\n )}\n </div>\n )\n}\n\nfunction formatTime(iso: string): string {\n const date = new Date(iso)\n if (Number.isNaN(date.getTime())) return iso\n const pad = (n: number) => String(n).padStart(2, '0')\n return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}`\n}\n\n/* ---------------- 小部件与钩子 ---------------- */\n\nfunction Radio(props: {\n label: string\n checked: boolean\n onChange: () => void\n name: string\n disabled?: boolean\n}) {\n // 每个选项自带 label 包裹 input:点中文本即选中,屏幕阅读器可正确播报选项标签\n return (\n <label style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}>\n <input\n type=\"radio\"\n name={props.name}\n checked={props.checked}\n disabled={props.disabled}\n onChange={props.onChange}\n />\n {props.label}\n </label>\n )\n}\n\n/** 订阅偏好快照使面板随宿主文档变更刷新(写回后镜像更新 → re-render)。 */\nfunction usePrefSync(prefs: PrefScope<PanelPrefs>): void {\n const [, bump] = useState(0)\n useEffect(() => prefs.subscribe(() => bump((n) => n + 1)), [prefs])\n}\n\n/** 单字段写入并显示错误。 */\nasync function writePref(\n prefs: PrefScope<PanelPrefs>,\n field: string,\n value: unknown,\n onError: (message: string) => void,\n): Promise<void> {\n try {\n await prefs.set(field, value)\n onError('')\n } catch (err) {\n onError(err instanceof Error ? err.message : String(err))\n }\n}\n","/** ui_mockup 客户端 UI 文案(双语,跟随 DSH 语言切换):工具卡片 + 设置面板。 */\n\nexport const NS = 'ui-mockup'\n\n/** 简体中文 UI 文案。 */\nexport const zh = {\n // 工具卡片\n 'card.generating': '生成中…',\n 'card.confirm': '确认采用这版',\n 'card.select': '选用第 {n} 版',\n 'card.selectPlaceholder': '选用某一版…',\n 'card.openOriginal': '打开原图',\n 'card.feedback': '提交修改意见',\n 'card.feedbackPlaceholder': '描述要修改的地方…',\n 'card.feedbackSubmit': '提交并重新生成',\n 'card.feedbackCancel': '取消',\n 'card.confirmMessage': '确认采用这版设计(文件:{name})',\n 'card.selectMessage': '选用第 {n} 版(文件:{name})',\n 'card.feedbackMessage': '{opinion}(基于文件:{name},请按此意见重新生成)',\n 'card.setAnchor': '设为风格锚点:此后未显式传参考图的生成将自动引用这张图保持风格一致',\n 'card.setAnchorButton': '设为锚点',\n 'card.setAnchorSelect': '设为锚点某一版…',\n 'card.setAnchorOption': '第 {n} 版',\n 'card.anchored': '风格锚点',\n\n // 设置面板:通用\n 'panel.nav': 'UI 草图',\n 'panel.tab.overview': '概览',\n 'panel.tab.provider': '提供方与模型',\n 'panel.tab.preferences': '生成偏好',\n 'panel.tab.history': '生成历史',\n 'panel.loading': '加载中…',\n 'panel.loadFailed': '加载失败: {error}',\n 'panel.readonlyBanner': '当前连接的设置存储为进程内模式或只读,偏好修改不会持久保存。',\n 'panel.testConnection': '测试连接',\n 'panel.testing': '测试中…',\n\n // 概览页\n 'panel.overview.intro':\n '在研讨阶段生成 UI 线框图 / 高保真设计稿:先看图确认方向,再写实现代码,避免做完才发现界面不符合预期。',\n 'panel.overview.quickTitle': '快速使用',\n 'panel.overview.step1Title': '何时触发',\n 'panel.overview.step1Body': '需求研讨中助手会主动提议出草图,也可以直接说「出个草图」。',\n 'panel.overview.step2Title': '如何反馈',\n 'panel.overview.step2Body':\n '生成图下方直接点「确认采用 / 选用第 N 版 / 提交修改意见」,或直接打字说。',\n 'panel.overview.step3Title': '如何锁定',\n 'panel.overview.step3Body': '确认后自动提炼进 design/spec.md,无需手动操作。',\n 'panel.overview.statusLine': '当前提供方:{provider} · {credential}',\n\n // 提供方与模型页\n 'panel.provider.title': '提供方',\n 'panel.provider.dashscopeName': '阿里云百炼 DashScope',\n 'panel.provider.volcengineName': '火山方舟 Volcengine',\n 'panel.provider.unknown': '未挂载图像提供方',\n 'panel.provider.fallbackActive': '默认生效(DashScope)',\n 'panel.provider.unknownHint':\n '面板暂时读不到提供方状态(宿主可能仍是旧版本,请重启 DSH 后再试);已按安装默认显示为 DashScope 生效。',\n 'panel.provider.volcengineDisabled':\n '已安装未启用。点击本卡片即可切换——插件会改写 DSH 用户层 patch,组合热重载后立即生效。',\n 'panel.provider.inactive': '未启用',\n 'panel.provider.modelsReset':\n '已随切换把模型分层默认重置为「跟随提供方默认」——旧提供方的模型 ID 对新提供方无效。',\n 'panel.credential.title': '凭据({credential})',\n 'panel.credential.ready': '凭据已配置',\n 'panel.credential.missing': '未配置 {credential}',\n 'panel.credential.checking': '检测中…',\n 'panel.credential.howTitle': '配置方式(按读取优先级排序, 任选其一即可):',\n 'panel.credential.way1':\n '进程环境变量: 启动 DSH 前执行 export {credential}=sk-xxx(CI/容器同理)',\n 'panel.credential.way2':\n 'DSH 密钥存储: ~/.dsh/.credentials.yaml(可在本页下方直接写入,或在 DSH 设置 · 模型页写入)',\n 'panel.credential.way3':\n '项目 .env: 在启动目录(通常是项目根)的 .env 文件中写 {credential}=sk-xxx',\n 'panel.credential.way4': 'DSH 主目录 .env: ~/.dsh/.env 中写 {credential}=sk-xxx',\n 'panel.credential.readyWithSource': '凭据已配置 · 来源: {source}',\n 'panel.credential.keyInputLabel': '{credential} 密钥',\n 'panel.credential.source.env': '进程环境变量',\n 'panel.credential.source.file': 'DSH 密钥存储(~/.dsh/.credentials.yaml)',\n 'panel.credential.source.project-env': '项目 .env',\n 'panel.credential.source.user-env': '~/.dsh/.env',\n 'panel.credential.source.ambient': '启动环境',\n 'panel.credential.writePlaceholder': '输入新的 {credential}(写入即覆盖,不会回显)',\n 'panel.credential.save': '保存(覆盖)',\n 'panel.credential.clear': '清除已存密钥',\n 'panel.credential.savedNotice': '已写入 DSH 密钥存储 ✓',\n 'panel.credential.clearedNotice': '已清除 DSH 密钥存储中的 {credential} ✓',\n 'panel.credential.notWritable':\n '当前密钥由更高优先级的来源({source})提供,面板写入不会生效;如需在面板管理,请先移除该来源中的同名变量。',\n 'panel.test.ok': '凭据有效:鉴权通过,网关可达。',\n 'panel.test.missingKey': '未找到 {credential}——请按上方「配置方式」任选其一配置后重试。',\n 'panel.test.invalidKey':\n '网关拒绝了这把密钥(鉴权未通过)——请确认 {credential} 是否正确、是否已过期。',\n 'panel.test.gatewayFail': '网关不可达: {detail}',\n 'panel.test.unknown': '探测结果无法判定({detail})——网关行为有变化,请直接生成一张草图验证。',\n 'panel.models.title': '模型分层默认',\n 'panel.models.wireframe': '线框图',\n 'panel.models.highFidelity': '高保真',\n 'panel.models.followDefault': '跟随提供方默认',\n\n // 生成偏好页\n 'panel.prefs.fidelity': '保真度偏好',\n 'panel.prefs.fidelityWireframe': '线框图',\n 'panel.prefs.fidelityHigh': '高保真',\n 'panel.prefs.platform': '目标平台',\n 'panel.prefs.count': '一次生成数量',\n 'panel.prefs.pollTimeout': '轮询超时',\n 'panel.prefs.minutes': '分钟',\n 'panel.prefs.backoff': '限流退避策略',\n 'panel.prefs.backoffFixed': '25 秒 × 2 次(自动)',\n 'panel.prefs.size': '默认尺寸',\n 'panel.prefs.reset': '恢复默认',\n 'panel.prefs.save': '保存',\n 'panel.prefs.saved': '已保存 ✓',\n 'panel.prefs.writeNotApplied': '设置存储未确认本次更改,请重试。',\n 'panel.prefs.writeNotAppliedField':\n '「{field}」未写入设置存储,保存已中止;之前的字段可能已落盘,请核对后重试。',\n\n // 生成历史页\n 'panel.history.search': '搜索',\n 'panel.history.searchLabel': '搜索生成历史',\n 'panel.history.searchPlaceholder': '按描述搜索…',\n 'panel.history.pendingSearch': '搜索条件已更改,点击“搜索”更新结果。',\n 'panel.history.clear': '清空历史',\n 'panel.history.confirmClear': '确认清空?',\n 'panel.history.cancelClear': '取消',\n 'panel.history.empty': '暂无生成历史; 出一张草图试试。',\n 'panel.history.setAnchor': '设为锚点',\n 'panel.history.unsetAnchor': '解除锚点',\n 'panel.history.anchorTag': '风格锚点',\n 'panel.history.anchorHint':\n '设为锚点后, 调用 ui_mockup 未显式传 reference 时会自动引用该图保持多页风格一致。',\n 'panel.history.prev': '上一页',\n 'panel.history.next': '下一页',\n 'panel.history.totalCount': '共 {n} 条',\n 'panel.history.anchorOnPage': '风格锚点在第 {n} 页',\n 'panel.history.goToAnchor': '前往',\n 'panel.history.fileCount': '{n} 张图',\n} satisfies Record<string, string>\n\n/** 卡片命名空间的字典键联合。 */\nexport type UiMockupKey = keyof typeof zh\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** ui_mockup 工具卡片与设置面板文案。 */\n 'ui-mockup': UiMockupKey\n }\n}\n\n/** English UI copy. */\nexport const en = {\n 'card.generating': 'Generating…',\n 'card.confirm': 'Confirm this version',\n 'card.select': 'Use version {n}',\n 'card.selectPlaceholder': 'Pick a version…',\n 'card.openOriginal': 'Open original',\n 'card.feedback': 'Submit feedback',\n 'card.feedbackPlaceholder': 'Describe what to change…',\n 'card.feedbackSubmit': 'Submit & regenerate',\n 'card.feedbackCancel': 'Cancel',\n 'card.confirmMessage': 'Confirm this design (file: {name})',\n 'card.selectMessage': 'Use version {n} (file: {name})',\n 'card.feedbackMessage': '{opinion} (based on file: {name}, regenerate accordingly)',\n 'card.setAnchor':\n 'Set as style anchor: subsequent generations without an explicit reference will reuse this image for consistent style',\n 'card.setAnchorButton': 'Set as anchor',\n 'card.setAnchorSelect': 'Set a version as anchor…',\n 'card.setAnchorOption': 'Version {n}',\n 'card.anchored': 'Style anchor',\n\n 'panel.nav': 'UI Mockups',\n 'panel.tab.overview': 'Overview',\n 'panel.tab.provider': 'Provider & models',\n 'panel.tab.preferences': 'Preferences',\n 'panel.tab.history': 'History',\n 'panel.loading': 'Loading…',\n 'panel.loadFailed': 'Failed to load: {error}',\n 'panel.readonlyBanner':\n 'This connection uses in-process or read-only settings storage; preference changes will not persist.',\n 'panel.testConnection': 'Test connection',\n 'panel.testing': 'Testing…',\n\n 'panel.overview.intro':\n 'Generate wireframes / high-fidelity mockups during discussion: confirm direction from the picture before writing code.',\n 'panel.overview.quickTitle': 'Quick start',\n 'panel.overview.step1Title': 'When to trigger',\n 'panel.overview.step1Body':\n 'The agent offers a sketch during requirement talks; you can also just say \"sketch this\".',\n 'panel.overview.step2Title': 'How to give feedback',\n 'panel.overview.step2Body':\n 'Click \"confirm / use version N / submit feedback\" under the image, or type it directly.',\n 'panel.overview.step3Title': 'How to lock it in',\n 'panel.overview.step3Body':\n 'On confirmation the design is distilled into design/spec.md automatically.',\n 'panel.overview.statusLine': 'Provider: {provider} · {credential}',\n\n 'panel.provider.title': 'Provider',\n 'panel.provider.dashscopeName': 'Alibaba DashScope',\n 'panel.provider.volcengineName': 'Volcengine Ark',\n 'panel.provider.unknown': 'No image provider mounted',\n 'panel.provider.fallbackActive': 'Active by default (DashScope)',\n 'panel.provider.unknownHint':\n 'The panel cannot read the provider status right now (the host may still be an older build; restart DSH and retry). Shown as DashScope active per the install default.',\n 'panel.provider.volcengineDisabled':\n 'Installed but disabled. Click this card to switch — the plugin rewrites the home user patch layer and DSH hot-reloads the composition.',\n 'panel.provider.inactive': 'Disabled',\n 'panel.provider.modelsReset':\n \"Model defaults were reset to 'follow provider default' on switch — the previous provider's model IDs are not valid here.\",\n 'panel.credential.title': 'Credentials ({credential})',\n 'panel.credential.ready': 'API key configured',\n 'panel.credential.missing': '{credential} not configured',\n 'panel.credential.checking': 'Checking…',\n 'panel.credential.howTitle': 'How to configure (checked in this order; any one is enough):',\n 'panel.credential.way1':\n 'Process environment: export {credential}=sk-xxx before launching DSH (same for CI/containers)',\n 'panel.credential.way2':\n 'DSH credential store: ~/.dsh/.credentials.yaml (written from DSH Settings · Models)',\n 'panel.credential.way3':\n 'Project .env: add {credential}=sk-xxx to the .env in the launch directory (usually the project root)',\n 'panel.credential.way4': 'DSH home .env: add {credential}=sk-xxx to ~/.dsh/.env',\n 'panel.credential.readyWithSource': 'API key configured · source: {source}',\n 'panel.credential.keyInputLabel': '{credential} key',\n 'panel.credential.source.env': 'process environment',\n 'panel.credential.source.file': 'DSH credential store (~/.dsh/.credentials.yaml)',\n 'panel.credential.source.project-env': 'project .env',\n 'panel.credential.source.user-env': '~/.dsh/.env',\n 'panel.credential.source.ambient': 'launch environment',\n 'panel.credential.writePlaceholder': 'Enter a new {credential} (overwrites, never echoed back)',\n 'panel.credential.save': 'Save (overwrite)',\n 'panel.credential.clear': 'Clear stored key',\n 'panel.credential.savedNotice': 'Written to the DSH credential store ✓',\n 'panel.credential.clearedNotice': '{credential} removed from the DSH credential store ✓',\n 'panel.credential.notWritable':\n 'The key is currently supplied by a higher-priority source ({source}); panel writes would not take effect. Remove that variable first to manage it here.',\n 'panel.test.ok': 'Credential valid: authentication passed, gateway reachable.',\n 'panel.test.missingKey':\n '{credential} not found — configure it via any option above, then retry.',\n 'panel.test.invalidKey':\n 'The gateway rejected this key (authentication failed) — check that {credential} is correct and not expired.',\n 'panel.test.gatewayFail': 'Gateway unreachable: {detail}',\n 'panel.test.unknown':\n 'Probe result inconclusive ({detail}) — gateway behavior may have changed; verify by generating a sketch.',\n 'panel.models.title': 'Model defaults by fidelity',\n 'panel.models.wireframe': 'Wireframe',\n 'panel.models.highFidelity': 'High fidelity',\n 'panel.models.followDefault': 'Follow provider default',\n\n 'panel.prefs.fidelity': 'Fidelity preference',\n 'panel.prefs.fidelityWireframe': 'Wireframe',\n 'panel.prefs.fidelityHigh': 'High fidelity',\n 'panel.prefs.platform': 'Target platform',\n 'panel.prefs.count': 'Images per request',\n 'panel.prefs.pollTimeout': 'Polling timeout',\n 'panel.prefs.minutes': 'minutes',\n 'panel.prefs.backoff': 'Rate-limit backoff',\n 'panel.prefs.backoffFixed': '25s × 2 (automatic)',\n 'panel.prefs.size': 'Default size',\n 'panel.prefs.reset': 'Reset to defaults',\n 'panel.prefs.save': 'Save',\n 'panel.prefs.saved': 'Saved ✓',\n 'panel.prefs.writeNotApplied': 'The settings store did not confirm this change. Please retry.',\n 'panel.prefs.writeNotAppliedField':\n '\"{field}\" was not confirmed by the settings store; saving stopped. Earlier fields may already be applied — please verify and retry.',\n\n 'panel.history.search': 'Search',\n 'panel.history.searchLabel': 'Search generation history',\n 'panel.history.searchPlaceholder': 'Search by description…',\n 'panel.history.pendingSearch': 'Search criteria changed. Select Search to update the results.',\n 'panel.history.clear': 'Clear history',\n 'panel.history.confirmClear': 'Confirm clear?',\n 'panel.history.cancelClear': 'Cancel',\n 'panel.history.empty': 'No generations yet; ask for a sketch to get started.',\n 'panel.history.setAnchor': 'Set as anchor',\n 'panel.history.unsetAnchor': 'Unset anchor',\n 'panel.history.anchorTag': 'Style anchor',\n 'panel.history.anchorHint':\n 'Once set, ui_mockup calls without an explicit reference automatically reuse this image for consistent style.',\n 'panel.history.prev': 'Previous',\n 'panel.history.next': 'Next',\n 'panel.history.totalCount': '{n} entries',\n 'panel.history.anchorOnPage': 'Style anchor on page {n}',\n 'panel.history.goToAnchor': 'Go to anchor',\n 'panel.history.fileCount': '{n} images',\n} satisfies Record<UiMockupKey, string>\n","/**\n * ui_mockup 客户端半区:keyed 工具卡片 + 设置面板(M3)+ 双语字典。\n * 面板注册进 DSH 设置窗口的 settings.section 列表槽;偏好经 settings\n * 命名空间镜像读写,历史/锚点/测试连接走 /ui-mockup 私有 RPC 通道。\n */\n\nimport type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-tool/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport { callPanel, type ConnectionFace, type SettingsScopeBinderFace } from './shared.js'\nimport { UiMockupToolview, type ToolviewAnchorFace } from './toolview.js'\nimport { UiMockupSection, type PanelPrefs, type UiMockupPanelInjected } from './settings-panel.js'\nimport { en, NS, zh } from './locales.js'\n\n/**\n * 客户端半区硬依赖:卡片与设置槽注册、语言切换、connection 通道与设置域服务。\n */\nexport const inject = ['slots', 'locale', 'connection', 'settingsScope']\n\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'ui-mockup: dictionaries')\n\n // bind 在本插件 fiber 上登记镜像订阅:插件卸载时随之销毁\n const prefs = (ctx.get('settingsScope') as SettingsScopeBinderFace).bind<PanelPrefs>({\n namespace: 'ui-mockup',\n })\n const connection = ctx.get('connection') as ConnectionFace\n\n /**\n * 卡片锚点入口:设锚动作发生在「刚看完这版图」的瞬间,注入窄面\n * set/unset 闭包捕获 connection,直连 RPC 不绕 agent 消息流。\n */\n const anchorFace: ToolviewAnchorFace = {\n set: (file: string, cwd?: string) => callPanel(connection, 'anchor/set', { file, cwd }),\n }\n\n ctx.slots.inject('tool.call.toolview', () =>\n ctx.slots.register(\n {\n name: 'tool.call.toolview',\n key: 'ui_mockup',\n locale: NS,\n inject: () => ({ anchor: anchorFace }),\n },\n UiMockupToolview,\n ),\n )\n\n const panelInjected = (): UiMockupPanelInjected => ({ prefs, connection })\n\n ctx.slots.inject('settings.section', () =>\n ctx.slots.register(\n {\n name: 'settings.section',\n id: 'ui-mockup',\n order: 100,\n label: () => ctx.locale.bind(NS)('panel.nav'),\n locale: NS,\n inject: panelInjected,\n },\n UiMockupSection,\n ),\n )\n}\n"],"mappings":";;;;;;;;;;;;EAGA,SAAgB,SAAS,MAAc,KAAsB;GAC3D,MAAM,OAAO,qBAAqB,mBAAmB,IAAI;GACzD,OAAO,QAAQ,KAAA,KAAa,QAAQ,KAAK,GAAG,KAAK,OAAO,mBAAmB,GAAG,MAAM;EACtF;;;;;;;;EA0BA,eAAsB,UACpB,YACA,UACA,UAAmC,CAAC,GACxB;GACZ,MAAM,SAAS,MAAM,WAAW,IAAI,KAAK,cAAc,UAAU,WAAW,CAAC,CAAC;GAC9E,IAAI,CAAC,OAAO,IAAI,MAAM,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,IAAI,OAAO,MAAM,SAAS;GAChF,OAAO,OAAO;EAChB;;EAkCA,SAAgB,aAAa,aAAqB,UAAiC;GACjF,OAAO,cAAc,IAAI,OAAO,KAAK,MAAM,cAAc,QAAQ,IAAI;EACvE;;;;;;;;;;EC9CA,SAAS,qBACP,GACA,MACA,OACA,SACQ;GACR,IAAI,YAAY,KAAA,KAAa,QAAQ,KAAK,MAAM,IAC9C,OAAO,EAAE,wBAAwB;IAAE,SAAS,QAAQ,KAAK;IAAG;GAAK,CAAC;GAEpE,OAAO,EAAE,sBAAsB;IAAE,GAAG,QAAQ;IAAG;GAAK,CAAC;EACvD;EAEA,SAAgB,iBAAiB,EAAE,OAAO,cAAc,KAAK,GAAG,UAAiB;GAC/E,MAAM,CAAC,cAAc,oBAAA,GAAmBA,MAAAA,SAAAA,CAAS,KAAK;GACtD,MAAM,CAAC,SAAS,eAAA,GAAcA,MAAAA,SAAAA,CAAS,EAAE;GACzC,MAAM,CAAC,UAAU,gBAAA,GAAeA,MAAAA,SAAAA,CAAS,EAAE;GAE3C,MAAM,CAAC,cAAc,oBAAA,GAAmBA,MAAAA,SAAAA,CAAS,EAAE;GAEnD,MAAM,CAAC,eAAe,qBAAA,GAAoBA,MAAAA,SAAAA,iBAA8B,IAAI,IAAI,CAAC;GACjF,MAAM,CAAC,aAAa,mBAAA,GAAkBA,MAAAA,SAAAA,CAAS,EAAE;GAEjD,MAAM,YAAY,OAAO,SAAiB;IACxC,IAAI,WAAW,KAAA,GAAW;IAC1B,eAAe,EAAE;IACjB,IAAI;KACF,MAAM,OAAO,IAAI,MAAM,GAAG;KAC1B,kBAAkB,SAAS,IAAI,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC;IACpD,SAAS,KAAK;KACZ,eAAe,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;IACjE;GACF;GAEA,IAAI,EAAE,UAAU,QACd,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,OAAO;KAAE,SAAS;KAAS,UAAU;KAAI,OAAO;IAAkC;IACpF,UAAA,EAAE,iBAAiB;GACjB,CAAA;GAIT,MAAM,SAAS,MAAM,QAAQ,QAAQ,SAAS,KAAK,SAAS,OAAO;GACnE,MAAM,UAAU,MAAM,QACnB,QAAQ,SAAS,KAAK,SAAS,MAAM,CAAC,CACtC,KAAK,SAAS,KAAK,IAAI,CAAC,CACxB,KAAK,EAAE;GAEV,IAAI,OAAO,WAAW,GACpB,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IACE,OAAO;KACL,SAAS;KACT,YAAY;KACZ,UAAU;KACV,YAAY;KACZ,OAAO;IACT;IAEC,UAAA;GACE,CAAA;GAIT,MAAM,QAAQ,SAAiB;IAC7B,aAAa,SAAS,IAAI;IAC1B,aAAa,OAAO;GACtB;GAEA,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,OAAO;KAAE,SAAS;KAAQ,eAAe;KAAU,KAAK;KAAG,SAAS;IAAQ;IAAjF,UAAA;KACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,OAAO;OAAE,SAAS;OAAQ,UAAU;OAAQ,KAAK;MAAE;MACrD,UAAA,OAAO,KAAK,OAAO,UAAU;OAE5B,MAAM,OADM,MAAM,WACD,QAAQ,UAAU,QAAQ,EAAE;OAC7C,MAAM,WAAW,cAAc,IAAI,IAAI;OACvC,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;QAAiC,OAAO,EAAE,QAAQ,EAAE;QAApD,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SACE,KAAK,SAAS,MAAM,GAAG;SACvB,KAAK;SACL,SAAQ;SACR,OAAO;UACL,UAAU;UACV,WAAW;UACX,cAAc;UACd,QAAQ,aAAa,WAAW,mCAAmC;UACnE,WAAW;UACX,YAAY;SACd;QACD,CAAA,GACD,iBAAA,GAAA,kBAAA,KAAA,CAAC,cAAD;SACE,OAAO;UACL,UAAU;UACV,YAAY;UACZ,OAAO;UACP,WAAW;SACb;SANF,UAAA,CAQG,MACA,WAAW,MAAM,EAAE,eAAe,MAAM,EAC/B;QACN,CAAA,CAAA;OAzBK,GAAA,GAAG,KAAK,GAAG,OAyBhB;MAEZ,CAAC;KACE,CAAA;KACJ,gBAAgB,MACf,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,OAAO;OAAE,UAAU;OAAI,OAAO;MAA+B;MAAI,UAAA;KAAiB,CAAA;KAGzF,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,OAAO;OAAE,SAAS;OAAQ,UAAU;OAAQ,KAAK;OAAG,YAAY;MAAS;MAA9E,UAAA;OACE,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,QAAD;QACE,SAAQ;QACR,MAAK;QACL,eACE,KAAK,EAAE,uBAAuB,EAAE,MAAM,OAAO,EAAE,CAAE,WAAW,QAAQ,eAAe,CAAC,CAAC;QAGtF,UAAA,EAAE,cAAc;OACX,CAAA;OACP,OAAO,SAAS,KACf,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;QACE,OAAO;QACP,WAAW,UAAU;SACnB,MAAM,MAAM,MAAM,OAAO;SAEzB,IAAI,QAAQ,IAAI;SAChB,MAAM,QAAQ,OAAO,GAAG;SACxB,YAAY,EAAE;SACd,MAAM,OAAQ,OAAO,MAAM,CAAE,WAAwB,QAAQ,UAAU,QAAQ,EAAE;SACjF,KAAK,qBAAqB,GAAG,MAAM,KAAK,CAAC;QAC3C;QACA,OAAO;SACL,QAAQ;SACR,SAAS;SACT,QAAQ;SACR,cAAc;SACd,YAAY;SACZ,MAAM;SACN,UAAU;SACV,OAAO;QACT;QApBF,UAAA,CAsBE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,OAAM;SAAG,UAAA;SACd,UAAA,EAAE,wBAAwB;QACrB,CAAA,GACP,OAAO,KAAK,OAAO,UAClB,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAoB,OAAO;SACxB,UAAA,EAAE,eAAe,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC5B,GAFK,KAEL,CACT,CACK;;OAGT,WAAW,KAAA,MACT,OAAO,WAAW,IACjB,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;QACE,SAAQ;QACR,MAAK;QACL,OAAO,EAAE,gBAAgB;QACzB,eAAe,KAAK,UAAU,OAAO,EAAE,CAAE,WAAW,QAAQ,cAAc;QAEzE,UAAA,EAAE,sBAAsB;OACnB,CAAA,IAER,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;QACE,OAAO;QACP,WAAW,UAAU;SACnB,MAAM,MAAM,MAAM,OAAO;SAEzB,IAAI,QAAQ,IAAI;SAChB,MAAM,QAAQ,OAAO,GAAG;SACxB,gBAAgB,EAAE;SAClB,MAAM,OACH,OAAO,MAAM,CAAE,WAAwB,QAAQ,UAAU,QAAQ,EAAE;SACtE,UAAe,IAAI;QACrB;QACA,OAAO,EAAE,gBAAgB;QACzB,OAAO;SACL,QAAQ;SACR,SAAS;SACT,QAAQ;SACR,cAAc;SACd,YAAY;SACZ,MAAM;SACN,UAAU;SACV,OAAO;QACT;QAtBF,UAAA,CAwBE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,OAAM;SAAG,UAAA;SACd,UAAA,EAAE,sBAAsB;QACnB,CAAA,GACP,OAAO,KAAK,OAAO,UAClB,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAoB,OAAO;SACxB,UAAA,EAAE,wBAAwB,EAAE,GAAG,QAAQ,EAAE,CAAC;QACrC,GAFK,KAEL,CACT,CACK;;cAGJ;QACN,MAAM,YAAY,OAAO,EAAE,CAAE,WAAW,QAAQ;QAChD,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;SAAG,MAAM,SAAS,WAAW,GAAG;SAAG,QAAO;SAAS,KAAI;SACrD,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;UAAQ,SAAQ;UAAQ,MAAK;UAC1B,UAAA,EAAE,mBAAmB;SAChB,CAAA;QACP,CAAA;OAEP,EAAA,CAAG;OACH,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;QAAQ,SAAQ;QAAQ,MAAK;QAAK,eAAe,iBAAiB,UAAU,CAAC,KAAK;QAC/E,UAAA,EAAE,eAAe;OACZ,CAAA;MACL;;KAEJ,gBACC,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,OAAO;OAAE,SAAS;OAAQ,eAAe;OAAU,KAAK;MAAE;MAA/D,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,YAAD;OACE,OAAO;OACP,WAAW,UAAU,WAAW,MAAM,OAAO,KAAK;OAClD,aAAa,EAAE,0BAA0B;OACzC,MAAM;OACN,OAAO;QACL,QAAQ;QACR,SAAS;QACT,QAAQ;QACR,cAAc;QACd,YAAY;QACZ,MAAM;QACN,UAAU;QACV,YAAY;QACZ,OAAO;OACT;MACD,CAAA,GACD,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,OAAO;QAAE,SAAS;QAAQ,KAAK;OAAE;OAAtC,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;QACE,SAAQ;QACR,MAAK;QACL,eAAe;SACb,MAAM,OAAO,OAAO,EAAE,CAAE,WAAW,QAAQ;SAC3C,KAAK,qBAAqB,GAAG,MAAM,GAAG,OAAO,CAAC;SAC9C,WAAW,EAAE;SACb,gBAAgB,KAAK;QACvB;QAEC,UAAA,EAAE,qBAAqB;OAClB,CAAA,GACR,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;QAAQ,SAAQ;QAAQ,MAAK;QAAK,eAAe,gBAAgB,KAAK;QACnE,UAAA,EAAE,qBAAqB;OAClB,CAAA,CACL;MACF,CAAA,CAAA;;IAEJ;;EAET;;;EC5RA,IAAA,yBAAA;;;;;;;;;;ECiDA,MAAM,iBAA6B;GACjC,iBAAiB;GACjB,iBAAiB;GACjB,cAAc;GACd,WAAW;GACX,oBAAoB;GACpB,gBAAgB;GAChB,mBAAmB;GACnB,aAAa;EACf;EAgBA,MAAM,WAAW;GAAC;GAAY;GAAY;GAAe;EAAS;;EAIlE,MAAM,WAAoD;GACxD,UAAU;GACV,UAAU;GACV,aAAa;GACb,SAAS;EACX;EAEA,SAAgB,gBAAgB,EAAE,GAAG,OAAO,cAA0B;GACpE,MAAM,CAAC,MAAM,YAAA,GAAWC,MAAAA,SAAAA,CAAkB,UAAU;GACpD,MAAM,UAAA,GAASC,MAAAA,MAAAA,CAAM;GACrB,MAAM,WAAA,GAAUC,MAAAA,OAAAA,CAAwC,CAAC,CAAC;GAE1D,MAAM,yBAAyB,OAAyC,UAAkB;IACxF,MAAM,YACJ,MAAM,QAAQ,SACV,IACA,MAAM,QAAQ,QACZ,SAAS,SAAS,IAClB,MAAM,QAAQ,gBACX,QAAQ,KAAK,SAAS,SACvB,MAAM,QAAQ,eACX,QAAQ,IAAI,SAAS,UAAU,SAAS,SACzC;IACZ,IAAI,cAAc,MAAM;IACxB,MAAM,WAAW,SAAS;IAC1B,IAAI,aAAa,KAAA,GAAW;IAC5B,MAAM,eAAe;IACrB,QAAQ,QAAQ;IAChB,QAAQ,QAAQ,UAAU,EAAE,MAAM;GACpC;GAEA,MAAM,cAAc,GAAG,OAAO,OAAO;GACrC,MAAM,gBAAgB,GAAG,OAAO,SAAS;GACzC,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAU;IAAoB,OAAO;IAA1C,UAAA;KACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;MAAO,yBAAA;MAAuBC,UAAAA;KAAgB,CAAA;KAE9C,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,MAAK;MAAU,cAAY,EAAE,WAAW;MAAG,WAAU;MAAiB,OAAO;MAC/E,UAAA,SAAS,KAAK,KAAK,UAClB,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAEE,IAAI,GAAG,OAAO,OAAO;OACrB,MAAM,YAAY;QAChB,QAAQ,QAAQ,SAAS;OAC3B;OACA,MAAK;OACL,MAAK;OACL,WAAU;OACV,iBAAe,SAAS;OACxB,iBAAe,GAAG,OAAO,SAAS;OAClC,UAAU,SAAS,MAAM,IAAI;OAC7B,eAAa,SAAS;OACtB,eAAe,QAAQ,GAAG;OAC1B,YAAY,UAAU,sBAAsB,OAAO,KAAK;OACxD,OAAO,SAAS,MAAM;QAAE,GAAG;QAAU,GAAG;OAAe,IAAI;OAE1D,UAAA,EAAE,SAAS,IAAI;MACV,GAjBD,GAiBC,CACT;KACE,CAAA;KACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MACE,IAAI;MACJ,MAAK;MACL,mBAAiB;MACjB,WAAU;MACV,UAAU;MALZ,UAAA;OAOG,SAAS,cAAc,iBAAA,GAAA,kBAAA,IAAA,CAAC,cAAD;QAAiB;QAAe;OAAa,CAAA;OACpE,SAAS,cAAc,iBAAA,GAAA,kBAAA,IAAA,CAAC,cAAD;QAAiB;QAAU;QAAmB;OAAa,CAAA;OAClF,SAAS,iBAAiB,iBAAA,GAAA,kBAAA,IAAA,CAAC,iBAAD;QAAoB;QAAU;OAAQ,CAAA;OAChE,SAAS,aAAa,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD;QAAgB;QAAe;OAAa,CAAA;MAChE;;IACF;;EAET;;;;;;EASA,MAAM,SAAS;GACb,cAAc;GACd,gBAAgB;GAChB,eAAe;GACf,YAAY;GACZ,QAAQ;GACR,SAAS;GACT,OAAO;EACT;;EAGA,MAAM,eAAe;GACnB,SAAS;GACT,eAAe;GACf,KAAK;GACL,UAAU;GACV,OAAO;GACP,OAAO,OAAO;EAChB;EAEA,MAAM,YAAY;GAChB,SAAS;GACT,YAAY;GACZ,cAAc,aAAa,OAAO;GAClC,WAAW;EACb;EAEA,MAAM,WAAW;GACf,UAAU;GACV,QAAQ;GACR,SAAS;GACT,YAAY;GACZ,OAAO,OAAO;GACd,MAAM;GACN,UAAU;GACV,YAAY;GACZ,QAAQ;EACV;EAEA,MAAM,iBAAiB,EACrB,OAAO,OAAO,aAChB;;EAGA,MAAM,cAAc;GAClB,QAAQ;GACR,SAAS;GACT,QAAQ,aAAa,OAAO;GAC5B,cAAc;GACd,YAAY,OAAO;GACnB,MAAM;GACN,UAAU;GACV,YAAY;GACZ,OAAO,OAAO;EAChB;;EAGA,SAAS,UAAU,EAAE,IAAI,QAAyC;GAChE,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,UAAD;IAAU,OAAO,OAAO,YAAY,KAAK,SAAS;IAAW,WAAU;GAAiB,CAAA;EACjG;;;;;EAMA,SAAS,KAAK,EAAE,OAAO,YAAqD;GAC1E,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IACE,WAAU;IACV,OAAO;KACL,SAAS;KACT,eAAe;KACf,KAAK;KACL,QAAQ,aAAa,OAAO;KAC5B,cAAc;KACd,SAAS;IACX;IATF,UAAA,CAWG,UAAU,KAAA,KACT,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,OAAO;MAAE,UAAU;MAAI,YAAY;MAAK,YAAY;KAAO;KAAI,UAAA;IAAY,CAAA,GAElF,QACE;;EAET;;;;;;;;;EAUA,SAAS,SAAS,EAChB,OACA,UACA,QAAQ,SAKP;GACD,MAAM,WAAA,GAAUH,MAAAA,MAAAA,CAAM;GACtB,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IACE,MAAK;IACL,mBAAiB;IACjB,WAAU;IACV,OAAO;KACL,SAAS;KACT,YAAY;KACZ,KAAK;KACL,UAAU;KACV,WAAW;KACX,YAAY;KACZ,GAAI,QAAQ,CAAC,IAAI,EAAE,WAAW,aAAa,OAAO,SAAS;IAC7D;IAZF,UAAA,CAcE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KACE,IAAI;KACJ,WAAU;KACV,OAAO;MAAE,UAAU;MAAI,YAAY;MAAQ,OAAO,OAAO;KAAe;KAEvE,UAAA;IACG,CAAA,GACL,QACE;;EAET;;EAGA,SAAS,OAAO,EAAE,UAAU,UAAqD;GAC/E,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;IACE,OAAO;KACL,QAAQ;KACR,UAAU;KACV,YAAY;KACZ,OAAO,SAAS,OAAO,aAAa,OAAO;IAC7C;IAEC;GACA,CAAA;EAEP;;EAKA,MAAM,cAAc;GAClB;IACE,MAAMI,sCAAAA;IACN,OAAO;IACP,MAAM;GACR;GACA;IAAE,MAAMC,sCAAAA;IAAmB,OAAO;IAA6B,MAAM;GAA2B;GAChG;IACE,MAAMC,sCAAAA;IACN,OAAO;IACP,MAAM;GACR;EACF;EAeA,SAAS,aAAa,EAAE,GAAG,cAAyC;GAClE,MAAM,CAAC,MAAM,YAAA,GAAWP,MAAAA,SAAAA,CAAuB;GAC/C,MAAM,CAAC,OAAO,aAAA,GAAYA,MAAAA,SAAAA,CAAS,EAAE;GACrC,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,IAAI,QAAQ;IACZ,UAAwB,YAAY,UAAU,CAAC,CAC5C,MAAM,UAAU;KACf,IAAI,OAAO,QAAQ,KAAK;IAC1B,CAAC,CAAC,CACD,OAAO,QAAiB;KACvB,IAAI,OAAO,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;IACtE,CAAC;IACH,aAAa;KACX,QAAQ;IACV;GACF,GAAG,CAAC,UAAU,CAAC;GAEf,IAAI,UAAU,IAAI,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;IAAQ,QAAA;IAAQ,UAAA,EAAE,oBAAoB,EAAE,MAAM,CAAC;GAAU,CAAA;GAClF,IAAI,SAAS,KAAA,GACX,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,OAAO,EAAE,OAAO,OAAO,cAAc;IAAI,UAAA,EAAE,eAAe;GAAO,CAAA;GAE/E,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IACE,WAAU;IACV,OAAO;KAAE,SAAS;KAAQ,eAAe;KAAU,KAAK;IAAG;IAF7D,UAAA;KAIE,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,OAAO;OAAE,QAAQ;OAAG,UAAU;OAAI,YAAY;OAAQ,OAAO,OAAO;MAAc;MAClF,UAAA,EAAE,sBAAsB;KACxB,CAAA;KACH,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;MAAM,OAAO,EAAE,2BAA2B;MACvC,UAAA,YAAY,KAAK,EAAE,MAAM,OAAO,WAC/B,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAiB,WAAU;OAAuB,OAAO;QAAE,SAAS;QAAQ,KAAK;OAAE;OAAnF,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,eAAA;QAAY,OAAO;SAAE,MAAM;SAAQ,OAAO,OAAO;SAAgB,WAAW;QAAE;QAClF,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAM,MAAM,GAAK,CAAA;OACb,CAAA,GACN,iBAAA,GAAA,kBAAA,KAAA,CAAC,KAAD;QAAG,OAAO;SAAE,QAAQ;SAAG,YAAY;QAAO;QAA1C,UAAA;SACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,OAAO,EAAE,UAAU,GAAG;UAAI,UAAA,EAAE,KAAK;SAAU,CAAA;SACnD,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,CAAK,CAAA;SACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,OAAO;WAAE,UAAU;WAAI,OAAO,OAAO;UAAe;UAAI,UAAA,EAAE,IAAI;SAAQ,CAAA;QAC3E;OACA,CAAA,CAAA;MATK,GAAA,KASL,CACN;KACG,CAAA;KACN,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MACE,WAAU;MACV,OAAO;OACL,SAAS;OACT,YAAY;OACZ,KAAK;OACL,UAAU;OACV,YAAY;OACZ,OAAO,OAAO;MAChB;MATF,UAAA,CAWE,iBAAA,GAAA,kBAAA,IAAA,CAAC,WAAD,EAAW,IAAI,KAAK,WAAW,WAAa,CAAA,GAC3C,EAAE,6BAA6B;OAE9B,UACE,KAAK,aAAa,gBAAgB,KAAK,aAAa,cAChD,EAAE,mBAAmB,KAAK,SAAS,IACnC,EAAE,wBAAwB;OAChC,YAAY,KAAK,WAAW,aACxB,EAAE,wBAAwB,IAC1B,EAAE,4BAA4B,EAC5B,YACE,KAAK,aAAa,eACd,qBAAqB,aACrB,qBAAqB,UAC7B,CAAC;MACP,CAAC,CACE;;IACF;;EAET;;EAKA,MAAM,gBAA6C;GACjD,KAAK;GACL,MAAM;GACN,eAAe;GACf,YAAY;GACZ,SAAS;EACX;EAEA,SAAS,gBAAgB,GAAoB,QAAgD;GAC3F,IAAI,WAAW,KAAA,GAAW,OAAO,KAAA;GACjC,MAAM,MAAM,cAAc;GAC1B,OAAO,QAAQ,KAAA,IAAY,SAAS,EAAE,GAAG;EAC3C;EAEA,MAAM,wBAAsD;GAC1D,WAAW;IAAC;IAAI;IAAkB;IAAkB;GAAc;GAClE,YAAY;IAAC;IAAI;IAA8B;GAA4B;GAC3E,SAAS,CAAC,IAAI,gBAAgB;EAChC;EACA,MAAM,4BAA0D;GAC9D,WAAW;IAAC;IAAI;IAAsB;IAAsB;GAAkB;GAC9E,YAAY;IAAC;IAAI;IAAkC;GAA4B;GAC/E,SAAS,CAAC,IAAI,oBAAoB;EACpC;;EAMA,MAAM,uBAAmD;GACvD,WAAW;GACX,YAAY;GACZ,SAAS;EACX;;EAGA,MAAM,qBAA0E;GAC9E,WAAW;GACX,YAAY;EACd;EAEA,SAAS,aAAa,EAAE,GAAG,OAAO,cAA0B;GAC1D,MAAM,OAAO,MAAM,YAAY;GAC/B,YAAY,KAAK;GACjB,MAAM,CAAC,YAAY,kBAAA,GAAiBA,MAAAA,SAAAA,CAAwB,IAAI;GAChE,MAAM,CAAC,SAAS,eAAA,GAAcA,MAAAA,SAAAA,CAAS,KAAK;GAC5C,MAAM,CAAC,YAAY,kBAAA,GAAiBA,MAAAA,SAAAA,CAAS,EAAE;GAE/C,MAAM,CAAC,YAAY,kBAAA,GAAiBA,MAAAA,SAAAA,CAAqB,SAAS;GAGlE,MAAM,CAAC,eAAe,qBAAA,GAAoBA,MAAAA,SAAAA,CAAS,IAAI;GAEvD,MAAM,CAAC,WAAW,iBAAA,GAAgBA,MAAAA,SAAAA,CAAS,KAAK;GAEhD,MAAM,CAAC,gBAAgB,sBAAA,GAAqBA,MAAAA,SAAAA,CAAwB,IAAI;GAExE,MAAM,CAAC,YAAY,kBAAA,GAAiBA,MAAAA,SAAAA,CAAsC;GAC1E,MAAM,CAAC,UAAU,gBAAA,GAAeA,MAAAA,SAAAA,CAAS,EAAE;GAC3C,MAAM,CAAC,SAAS,eAAA,GAAcA,MAAAA,SAAAA,CAAS,KAAK;GAC5C,MAAM,CAAC,WAAW,iBAAA,GAAgBA,MAAAA,SAAAA,CAAwD,IAAI;GAE9F,MAAM,yBAAA,GAAwBQ,MAAAA,YAAAA,CAAY,YAAiC;IACzE,IAAI;KACF,MAAM,QAAQ,MAAM,UAAkC,YAAY,iBAAiB;KACnF,cAAc,MAAM,MAAM;KAC1B,iBAAiB,KAAK;KACtB,OAAO,MAAM;IACf,QAAQ;KACN,cAAc,SAAS;KACvB,iBAAiB,IAAI;KACrB,OAAO;IACT;GACF,GAAG,CAAC,UAAU,CAAC;GAEf,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,sBAA2B;GAC7B,GAAG,CAAC,qBAAqB,CAAC;GAE1B,MAAM,iBAAiB,qBAAqB;;GAG5C,MAAM,iBAAiB,OAAO,WAA2C;IACvE,IAAI,WAAW;IACf,aAAa,IAAI;IACjB,kBAAkB,IAAI;IACtB,IAAI;KACF,MAAM,SAAS,MAAM,UACnB,YACA,mBACA,EAAE,UAAU,OAAO,CACrB;KAIA,IAAI,OAAO,WAAW,UAAU,OAAO,YAAY,MAAM;MACvD,MAAM,UAAU,MAAM,YAAY,CAAC,CAAC;MACpC,IACE,YAAY,KAAA,MACX,QAAQ,mBAAmB,MAAM,QAAQ,sBAAsB,KAEhE,IAAI;OACF,MAAM,MAAM,IAAI,kBAAkB,EAAE;OACpC,MAAM,MAAM,IAAI,qBAAqB,EAAE;OACvC,kBAAkB,EAAE,4BAA4B,CAAC;MACnD,QAAQ,CAER;KAEJ;IACF,SAAS,KAAK;KACZ,cAAc,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;IAChE,UAAU;KAER,MAAM,sBAAsB;KAC5B,MAAM,kBAAkB;KACxB,aAAa,KAAK;IACpB;GACF;GAEA,MAAM,qBAAA,GAAoBA,MAAAA,YAAAA,CAAY,YAAkD;IACtF,IAAI;KACF,MAAM,QAAQ,MAAM,UAA2C,YAAY,UAAU;KACrF,cAAc,MAAM,UAAU;KAC9B,OAAO,MAAM;IACf,QAAQ;KACN,cAAc,KAAA,CAAS;KACvB;IACF;GACF,GAAG,CAAC,UAAU,CAAC;GAEf,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,kBAAuB;GACzB,GAAG,CAAC,iBAAiB,CAAC;;GAGtB,MAAM,WAAW,OAAO,aAAoD;IAC1E,WAAW,IAAI;IACf,aAAa,IAAI;IACjB,IAAI;KAEF,MAAM,SAAS,MAAM,UAA2C,YAAY,UAD5D,aAAa,mBAAmB,EAAE,OAAO,SAAS,IAAI,CAAC,CACsB;KAC7F,cAAc,OAAO,UAAU;KAC/B,YAAY,EAAE;KACd,aAAa;MACX,MAAM;MACN,MACE,aAAa,mBACT,EAAE,8BAA8B,IAChC,EAAE,kCAAkC,EAAE,YAAY,eAAe,CAAC;KAC1E,CAAC;IACH,SAAS,KAAK;KACZ,aAAa;MAAE,MAAM;MAAS,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;KAAE,CAAC;IACxF,UAAU;KACR,WAAW,KAAK;IAClB;GACF;GAEA,MAAM,UAAU,YAAY;IAC1B,WAAW,IAAI;IACf,cAAc,IAAI;IAClB,IAAI;KAEF,MAAM,SAAS,MAAM,UAIlB,YAAY,iBAAiB;KAChC,cACE,OAAO,KACH,EAAE,eAAe,IACjB,OAAO,WAAW,gBAChB,EAAE,yBAAyB,EAAE,YAAY,eAAe,CAAC,IACzD,OAAO,WAAW,gBAChB,EAAE,yBAAyB,EAAE,YAAY,eAAe,CAAC,IACzD,OAAO,WAAW,YAChB,EAAE,sBAAsB,EAAE,QAAQ,OAAO,UAAU,GAAG,CAAC,IACvD,EAAE,0BAA0B,EAAE,QAAQ,OAAO,UAAU,GAAG,CAAC,CACvE;IACF,SAAS,KAAK;KACZ,cAAc,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;IAChE,UAAU;KACR,WAAW,KAAK;IAClB;GACF;GAEA,MAAM,cAAc,gBAAgB,GAAG,YAAY,MAAM;;GAGzD,MAAM,mBACJ,eAAe,KAAA,IACX,EAAE,2BAA2B,IAC7B,WAAW,aACT,EAAE,wBAAwB,IAC1B,EAAE,4BAA4B,EAAE,YAAY,eAAe,CAAC;GAEpE,MAAM,iBACJ,eAAe,KAAA,IACX,EAAE,2BAA2B,IAC7B,WAAW,aACT,gBAAgB,KAAA,IACd,EAAE,wBAAwB,IAC1B,EAAE,oCAAoC,EAAE,QAAQ,YAAY,CAAC,IAC/D,EAAE,4BAA4B,EAAE,YAAY,eAAe,CAAC;GAMpE,MAAM,iBAAiB,CAAC;GACxB,MAAM,kBAAkB,eAAe,eAAgB,eAAe,aAAa;GACnF,MAAM,mBAAmB,eAAe;;GAExC,MAAM,qBAAqB,YAAqB;IAC9C,MAAM;IACN,WAAW;IACX,QAAQ,SACJ,mDACA,aAAa,OAAO;IACxB,cAAc;IACd,YAAY,SAAS,wCAAwC;IAC7D,SAAS;IACT,QAAQ;GACV;GACA,MAAM,oBAAoB;IACxB,WAAW;IACX,SAAS;IACT,eAAe;IACf,KAAK;GACP;GACA,MAAM,sBAAsB;IAC1B,SAAS;IACT,YAAY;IACZ,KAAK;IACL,UAAU;IACV,YAAY;IACZ,OAAO,OAAO;GAChB;GAEA,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,OAAO;KAAE,SAAS;KAAQ,eAAe;KAAU,KAAK;IAAG;IAAhE,UAAA;KACG,KAAK,SAAS,YAAY,CAAC,KAAK,WAC/B,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAS,EAAE,sBAAsB,EAAU,CAAA,IACzC;KACH,eAAe,MAAM,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAQ,QAAA;MAAQ,UAAA;KAAmB,CAAA;KAEzD,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;MAAM,OAAO,EAAE,sBAAsB;MAArC,UAAA;OAGG,iBAAiB,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAS,EAAE,4BAA4B,EAAU,CAAA;OAClE,mBAAmB,QAAQ,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAS,eAAuB,CAAA;OAC5D,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,OAAO;SAAE,SAAS;SAAQ,KAAK;SAAG,UAAU;QAAO;QAAxD,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;SACE,WAAU;SACV,OAAO;UACL,GAAG,kBAAkB,eAAe;UACpC,QAAQ,mBAAmB,YAAY,YAAY;SACrD;SACA,eAAe;UACb,IAAI,CAAC,iBAAiB,eAAoB,WAAW;SACvD;SARF,UAAA;UAUE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;WACE,MAAK;WACL,MAAK;WACL,SAAS;WACT,UAAU;WACV,UAAA;WACA,cAAY,EAAE,8BAA8B;UAC7C,CAAA;UAAE;UACH,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WAAQ,OAAO,EAAE,UAAU,GAAG;WAAI,UAAA,EAAE,8BAA8B;UAAU,CAAA;UAC5E,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;WAAK,OAAO;WACT,UAAA,kBACC,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;YAAK,OAAO;YAAZ,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,WAAD;aAAW,IAAI,YAAY,eAAe;aAAM,MAAM;YAAY,CAAA,GACjE,iBAAiB,eAAe,YAC7B,EAAE,+BAA+B,IACjC,gBACD;WACJ,CAAA,GAAA,YAAY,cAAc,gBAAgB,KAAA,KACzC,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;YACE,OAAO;aACL,UAAU;aACV,YAAY;aACZ,OAAO,OAAO;aACd,aAAa;YACf;YAEC,UAAA;WACE,CAAA,CAEP,EAAA,CAAA,IAEF,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;YAAK,OAAO;YAAZ,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,WAAD;aAAW,IAAI;aAAO,MAAM;YAAY,CAAA,GACvC,EAAE,yBAAyB,CACzB;;UAEJ,CAAA;SACA;QACP,CAAA,GAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;SACE,WAAU;SACV,OAAO;UACL,GAAG,kBAAkB,gBAAgB;UACrC,QAAQ,oBAAoB,YAAY,YAAY;SACtD;SACA,eAAe;UACb,IAAI,CAAC,kBAAkB,eAAoB,YAAY;SACzD;SARF,UAAA;UAUE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;WACE,MAAK;WACL,MAAK;WACL,SAAS;WACT,UAAU;WACV,UAAA;WACA,cAAY,EAAE,+BAA+B;UAC9C,CAAA;UAAE;UACH,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WAAQ,OAAO,EAAE,UAAU,GAAG;WAAI,UAAA,EAAE,+BAA+B;UAAU,CAAA;UAC7E,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;WAAK,OAAO;WACT,UAAA,mBACC,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;YAAK,OAAO;YAAZ,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,WAAD;aAAW,IAAI,YAAY,eAAe;aAAM,MAAM;YAAY,CAAA,GACjE,gBACE;WAEL,CAAA,IAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;YACE,OAAO;aACL,UAAU;aACV,YAAY;aACZ,OAAO,OAAO;YAChB;YAEC,UAAA,iBACG,EAAE,mCAAmC,IACrC,EAAE,yBAAyB;WAC5B,CAAA;UAEJ,CAAA;SACA;QACJ,CAAA,CAAA;;MACD;;KAEN,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;MAAM,OAAO,EAAE,0BAA0B,EAAE,YAAY,eAAe,CAAC;MAAvE,UAAA;OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,OAAO;SAAE,SAAS;SAAQ,YAAY;SAAU,KAAK;SAAI,UAAU;QAAO;QAA/E,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;SACE,OAAO;UACL,SAAS;UACT,YAAY;UACZ,KAAK;UACL,MAAM;UACN,UAAU;UACV,YAAY;UACZ,OAAO,OAAO;SAChB;SATF,UAAA,CAWE,iBAAA,GAAA,kBAAA,IAAA,CAAC,WAAD;UAAW,IAAI,YAAY,eAAe;UAAM,MAAM;SAAU,CAAA,GAC/D,cACG;QACN,CAAA,GAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,QAAD;SAAQ,SAAQ;SAAU,MAAK;SAAK,eAAe,KAAK,QAAQ;SAAG,UAAU;SAC1E,UAAA,UAAU,EAAE,eAAe,IAAI,EAAE,sBAAsB;QAClD,CAAA,CACL;;OACJ,eAAe,QAAQ,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAS,WAAmB,CAAA;OAEnD,YAAY,aAAa,OACxB,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,OAAO;SAAE,SAAS;SAAQ,KAAK;SAAG,UAAU;SAAQ,YAAY;QAAS;QAA9E,UAAA;SACE,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,OAAD;UACE,MAAK;UACL,cAAY,EAAE,kCAAkC,EAAE,YAAY,eAAe,CAAC;UAC9E,OAAO,EAAE,MAAM,YAAY;UAC3B,OAAO;UACP,cAAa;UACb,aAAa,EAAE,qCAAqC,EAAE,YAAY,eAAe,CAAC;UAClF,WAAW,UAAU,YAAY,MAAM,OAAO,KAAK;UACnD,YAAY,UAAU;WACpB,IAAI,MAAM,QAAQ,WAAW,SAAS,KAAK,MAAM,IAAI,SAAc,gBAAgB;UACrF;SACD,CAAA;SACD,iBAAA,GAAA,kBAAA,IAAA,CAACD,sCAAAA,QAAD;UACE,SAAQ;UACR,MAAK;UACL,UAAU,WAAW,SAAS,KAAK,MAAM;UACzC,eAAe,KAAK,SAAS,gBAAgB;UAE5C,UAAA,EAAE,uBAAuB;SACpB,CAAA;SACP,WAAW,cACV,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;UACE,SAAQ;UACR,MAAK;UACL,UAAU;UACV,eAAe,KAAK,SAAS,kBAAkB;UAE9C,UAAA,EAAE,wBAAwB;SACrB,CAAA;QAEP;OACH,CAAA,IAAA,eAAe,KAAA,KAAa,WAAW,aACzC,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAS,EAAE,gCAAgC,EAAE,QAAQ,eAAe,GAAG,CAAC,EAAU,CAAA,IAChF;OACH,cAAc,QACb,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAQ,QAAQ,UAAU,SAAS;QAAU,UAAA,UAAU;OAAa,CAAA;OAEtE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QACE,OAAO;SACL,UAAU;SACV,YAAY;SACZ,OAAO,OAAO;SACd,SAAS;SACT,eAAe;SACf,KAAK;SACL,WAAW;QACb;QATF,UAAA,CAWE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,OAAO;UAAE,YAAY;UAAK,OAAO,OAAO;SAAe;SAC1D,UAAA,EAAE,2BAA2B;QAC1B,CAAA,GACN,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;SAAI,OAAO;UAAE,QAAQ;UAAG,aAAa;SAAG;SAAxC,UAAA;UACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,EAAE,yBAAyB,EAAE,YAAY,eAAe,CAAC,EAAM,CAAA;UACpE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,EAAE,uBAAuB,EAAM,CAAA;UACpC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,EAAE,yBAAyB,EAAE,YAAY,eAAe,CAAC,EAAM,CAAA;UACpE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,EAAE,yBAAyB,EAAE,YAAY,eAAe,CAAC,EAAM,CAAA;SAClE;QACD,CAAA,CAAA;;MACD;;KAEN,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;MAAM,OAAO,EAAE,oBAAoB;MAAnC,UAAA;OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAU,OAAA;QAAM,OAAO,EAAE,wBAAwB;QAC/C,UAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;SACE,cAAY,EAAE,wBAAwB;SACtC,WAAU;SACV,OAAO,KAAK,OAAO,kBAAkB;SACrC,WAAW,UACT,KAAK,UAAU,OAAO,kBAAkB,MAAM,OAAO,MAAM,KAAK,GAAG,aAAa;SAElF,OAAO;UAAE,GAAG;UAAa,OAAO;SAAmB;SAPrD,UAAA,CASE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,OAAM;UAAI,UAAA,EAAE,4BAA4B;SAAU,CAAA,GACzD,sBAAsB,WAAW,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,MACtD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAgB,OAAO;UACpB,UAAA;SACK,GAFK,CAEL,CACT,CACK;;OACA,CAAA;OACV,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAU,OAAO,EAAE,2BAA2B;QAC5C,UAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;SACE,cAAY,EAAE,2BAA2B;SACzC,WAAU;SACV,OAAO,KAAK,OAAO,qBAAqB;SACxC,WAAW,UACT,KAAK,UAAU,OAAO,qBAAqB,MAAM,OAAO,MAAM,KAAK,GAAG,aAAa;SAErF,OAAO;UAAE,GAAG;UAAa,OAAO;SAAmB;SAPrD,UAAA,CASE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,OAAM;UAAI,UAAA,EAAE,4BAA4B;SAAU,CAAA,GACzD,0BAA0B,WAAW,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,MAC1D,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAgB,OAAO;UACpB,UAAA;SACK,GAFK,CAEL,CACT,CACK;;OACA,CAAA;OACV,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UACG,GAAG,EAAE,wBAAwB,EAAE,IAAI,sBAAsB,WAAW,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,KAAK,EAAE,2BAA2B,EAAE,IAAI,0BAA0B,WAAW,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,IAAI,IAClM,CAAA;MACJ;;IACH;;EAET;EAIA,MAAM,uBAAuB;GAC3B;GACA;GACA;GACA;GACA;EACF;;EAGA,SAAS,mBAAmB,MAAkB,OAA4B;GACxE,OACE,KAAK,oBAAoB,MAAM,mBAC/B,KAAK,oBAAoB,MAAM,mBAC/B,KAAK,iBAAiB,MAAM,gBAC5B,KAAK,uBAAuB,MAAM,sBAClC,KAAK,gBAAgB,MAAM;EAE/B;;EAGA,SAAS,6BAA6B,MAAwB;GAC5D,IAAI,SAAS,KAAA,GAAW,OAAO;GAC/B,IAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,MAAM,QAAQ,IAAI,GAAG,OAAO;GAC7E,OAAO,qBAAqB,OAAO,UAAU,CAAC,OAAO,UAAU,eAAe,KAAK,MAAM,KAAK,CAAC;EACjG;EAEA,SAAS,gBAAgB,EAAE,GAAG,SAAyC;GACrE,MAAM,OAAO,MAAM,YAAY;GAC/B,YAAY,KAAK;GACjB,MAAM,WAAA,GAAUE,MAAAA,QAAAA,OAAc,KAAK,SAAS,gBAAgB,CAAC,KAAK,KAAK,CAAC;GACxE,MAAM,CAAC,OAAO,aAAA,GAAYX,MAAAA,SAAAA,CAAqB,OAAO;GACtD,MAAM,CAAC,UAAU,gBAAA,GAAeA,MAAAA,SAAAA,CAAqB,OAAO;GAC5D,MAAM,CAAC,SAAS,eAAA,GAAcA,MAAAA,SAAAA,CAAS,CAAC;GACxC,MAAM,CAAC,OAAO,aAAA,GAAYA,MAAAA,SAAAA,CAAS,EAAE;GACrC,MAAM,CAAC,UAAU,gBAAA,GAAeA,MAAAA,SAAAA,CAAS,KAAK;GAC9C,MAAM,gBAAA,GAAeE,MAAAA,OAAAA,CAAO,KAAK;GACjC,MAAM,QAAQ,CAAC,mBAAmB,OAAO,QAAQ;GAEjD,CAAA,GAAA,MAAA,UAAA,OAAgB;IAEd,IAAI,CAAC,SAAS,CAAC,YAAY,KAAK,UAAU,KAAA,GAAW;KACnD,SAAS,KAAK,KAAK;KACnB,YAAY,KAAK,KAAK;IACxB;GACF,GAAG;IAAC;IAAO;IAAU,KAAK;GAAK,CAAC;GAEhC,MAAM,SAAS,SAA8B;IAC3C,IAAI,aAAa,SAAS;IAC1B,UAAU,UAAU;KAAE,GAAG;KAAM,GAAG;IAAK,EAAE;GAC3C;GAEA,MAAM,sBAA+B;IACnC,IAAI,aAAa,SAAS,OAAO;IACjC,aAAa,UAAU;IACvB,YAAY,IAAI;IAChB,WAAW,CAAC;IACZ,SAAS,EAAE;IACX,OAAO;GACT;GAEA,MAAM,oBAAoB;IACxB,aAAa,UAAU;IACvB,YAAY,KAAK;GACnB;GAEA,MAAM,kBAAkB,aAAqC;IAC3D,MAAM,SAAS,MAAM,YAAY,CAAC,CAAC;IACnC,IAAI,WAAW,KAAA,KAAa,CAAC,mBAAmB,QAAQ,QAAQ,GAC9D,MAAM,IAAI,MAAM,EAAE,6BAA6B,CAAC;IAElD,OAAO;GACT;;;GAIA,MAAM,WAAW,OAAO,OAA8C,UAAmB;IACvF,MAAM,MAAM,IAAI,OAAO,KAAK;IAC5B,MAAM,SAAS,MAAM,YAAY,CAAC,CAAC;IACnC,IAAI,WAAW,KAAA,KAAa,OAAO,WAAW,OAC5C,MAAM,IAAI,MAAM,EAAE,oCAAoC,EAAE,MAAM,CAAC,CAAC;GAEpE;GAEA,MAAM,4BAAwC;IAC5C,MAAM,UAAU,MAAM,YAAY;IAClC,IAAI,QAAQ,UAAU,KAAA,KAAa,CAAC,6BAA6B,QAAQ,IAAI,GAC3E,MAAM,IAAI,MAAM,EAAE,6BAA6B,CAAC;IAElD,OAAO,QAAQ;GACjB;GAEA,MAAM,OAAO,YAAY;IACvB,IAAI,CAAC,cAAc,GAAG;IACtB,IAAI;KACF,MAAM,QAAQ;MACZ,GAAG;MACH,cAAc,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,MAAM,MAAM,YAAY,CAAC,CAAC;MACrE,oBAAoB,KAAK,IAAI,GAAG,KAAK,MAAM,MAAM,kBAAkB,CAAC;KACtE;KACA,MAAM,SAAS,mBAAmB,MAAM,eAAe;KACvD,MAAM,SAAS,mBAAmB,MAAM,eAAe;KACvD,MAAM,SAAS,gBAAgB,MAAM,YAAY;KACjD,MAAM,SAAS,sBAAsB,MAAM,kBAAkB;KAC7D,MAAM,SAAS,eAAe,MAAM,WAAW;KAC/C,MAAM,UAAU,eAAe,KAAK;KACpC,SAAS,OAAO;KAChB,YAAY,OAAO;KACnB,WAAW,KAAK,IAAI,CAAC;IACvB,SAAS,KAAK;KACZ,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;IAC3D,UAAU;KACR,YAAY;IACd;GACF;GAEA,MAAM,gBAAgB,YAAY;IAChC,IAAI,CAAC,cAAc,GAAG;IACtB,IAAI;KACF,KAAK,MAAM,SAAS,sBAClB,MAAM,MAAM,MAAM,KAAK;KAEzB,MAAM,UAAU,oBAAoB;KACpC,SAAS,OAAO;KAChB,YAAY,OAAO;KACnB,WAAW,KAAK,IAAI,CAAC;IACvB,SAAS,KAAK;KACZ,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;IAC3D,UAAU;KACR,YAAY;IACd;GACF;GAEA,MAAM,eAAe,KAAK,SAAS,YAAY,CAAC,KAAK;GAErD,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,OAAO;KAAE,SAAS;KAAQ,eAAe;KAAU,KAAK;IAAG;IAAhE,UAAA;KACG,gBAAgB,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAS,EAAE,sBAAsB,EAAU,CAAA;KAC3D,UAAU,MAAM,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAQ,QAAA;MAAQ,UAAA;KAAc,CAAA;KAC/C,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA;MACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;OAAU,OAAA;OAAM,OAAO,EAAE,sBAAsB;OAA/C,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QACE,OAAO,EAAE,+BAA+B;QACxC,SAAS,MAAM,oBAAoB;QACnC,gBAAgB,MAAM,EAAE,iBAAiB,YAAY,CAAC;QACtD,MAAK;QACL,UAAU,gBAAgB;OAC3B,CAAA,GACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QACE,OAAO,EAAE,0BAA0B;QACnC,SAAS,MAAM,oBAAoB;QACnC,gBAAgB,MAAM,EAAE,iBAAiB,gBAAgB,CAAC;QAC1D,MAAK;QACL,UAAU,gBAAgB;OAC3B,CAAA,CACO;;MACV,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;OAAU,OAAO,EAAE,sBAAsB;OAAzC,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QACE,OAAM;QACN,SAAS,MAAM,oBAAoB;QACnC,gBAAgB,MAAM,EAAE,iBAAiB,MAAM,CAAC;QAChD,MAAK;QACL,UAAU,gBAAgB;OAC3B,CAAA,GACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QACE,OAAM;QACN,SAAS,MAAM,oBAAoB;QACnC,gBAAgB,MAAM,EAAE,iBAAiB,SAAS,CAAC;QACnD,MAAK;QACL,UAAU,gBAAgB;OAC3B,CAAA,CACO;;MACV,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAU,OAAO,EAAE,mBAAmB;OACnC,UAAA;QAAC;QAAG;QAAG;QAAG;OAAC,CAAC,CAAC,KAAK,MACjB,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QAEE,OAAO,OAAO,CAAC;QACf,SAAS,MAAM,iBAAiB;QAChC,gBAAgB,MAAM,EAAE,cAAc,EAAE,CAAC;QACzC,MAAK;QACL,UAAU,gBAAgB;OAC3B,GANM,CAMN,CACF;MACO,CAAA;MAEV,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;OAAU,OAAO,EAAE,yBAAyB;OAA5C,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAACQ,sCAAAA,OAAD;QACE,MAAK;QACL,cAAY,EAAE,yBAAyB;QACvC,KAAK;QACL,KAAK;QACL,OAAO,EAAE,OAAO,IAAI;QACpB,OAAO,MAAM;QACb,WAAW,UAAU,MAAM,EAAE,oBAAoB,OAAO,MAAM,OAAO,KAAK,EAAE,CAAC;QAC7E,UAAU,gBAAgB;OAC3B,CAAA,GACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,OAAO;SAAE,UAAU;SAAI,OAAO,OAAO;QAAc;QACtD,UAAA,EAAE,qBAAqB;OACpB,CAAA,CACE;;MACV,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAU,OAAO,EAAE,qBAAqB;OACtC,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,OAAO;SAAE,UAAU;SAAI,YAAY;SAAQ,OAAO,OAAO;QAAc;QAC1E,UAAA,EAAE,0BAA0B;OACzB,CAAA;MACE,CAAA;MACV,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAU,OAAO,EAAE,kBAAkB;OACnC,UAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;QACE,cAAY,EAAE,kBAAkB;QAChC,OAAO,MAAM;QACb,WAAW,UAAU,MAAM,EAAE,aAAa,MAAM,OAAO,MAAM,CAAC;QAC9D,UAAU,gBAAgB;QAC1B,OAAO;QALT,UAAA;SAOE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,OAAM;UAAI,UAAA,EAAE,4BAA4B;SAAU,CAAA;SAC1D,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,OAAM;UAAY,UAAA;SAAiB,CAAA;SAC3C,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,OAAM;UAAW,UAAA;SAAgB,CAAA;SACzC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,OAAM;UAAW,UAAA;SAAgB,CAAA;QACnC;;MACA,CAAA;KACN,EAAA,CAAA;KACN,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MACE,WAAU;MACV,OAAO;OAAE,SAAS;OAAQ,gBAAgB;OAAiB,YAAY;MAAS;MAFlF,UAAA,CAIE,iBAAA,GAAA,kBAAA,IAAA,CAACD,sCAAAA,QAAD;OACE,SAAQ;OACR,MAAK;OACL,eAAe,KAAK,cAAc;OAClC,UAAU,gBAAgB;OAEzB,UAAA,EAAE,mBAAmB;MAChB,CAAA,GACR,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OACE,WAAU;OACV,OAAO;QAAE,SAAS;QAAQ,KAAK;QAAI,YAAY;OAAS;OAF1D,UAAA,CAIG,UAAU,KAAK,CAAC,SACf,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QACE,MAAK;QACL,aAAU;QACV,OAAO;SAAE,UAAU;SAAI,OAAO,OAAO;QAAc;QAElD,UAAA,EAAE,mBAAmB;OAClB,CAAA,GAER,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;QACE,SAAQ;QACR,MAAK;QACL,eAAe,KAAK,KAAK;QACzB,UAAU,gBAAgB,YAAY,CAAC;QAEtC,UAAA,EAAE,kBAAkB;OACf,CAAA,CACL;MACF,CAAA,CAAA;;IACF;;EAET;EAeA,SAAS,YAAY,EAAE,GAAG,cAAyC;GAIjE,MAAM,MAA0B,KAAA;GAChC,MAAM,CAAC,MAAM,YAAA,GAAWT,MAAAA,SAAAA,CAAuB;GAC/C,MAAM,CAAC,YAAY,kBAAA,GAAiBA,MAAAA,SAAAA,CAAwB,IAAI;GAChE,MAAM,CAAC,aAAa,mBAAA,GAAkBA,MAAAA,SAAAA,CAAS,EAAE;GACjD,MAAM,CAAC,OAAO,aAAA,GAAYA,MAAAA,SAAAA,CAAS,CAAC;GACpC,MAAM,CAAC,MAAM,YAAA,GAAWA,MAAAA,SAAAA,CAAS,CAAC;GAClC,MAAM,CAAC,YAAY,kBAAA,GAAiBA,MAAAA,SAAAA,CAAS,EAAE;GAC/C,MAAM,CAAC,cAAc,oBAAA,GAAmBA,MAAAA,SAAAA,CAAS,EAAE;GACnD,MAAM,CAAC,OAAO,aAAA,GAAYA,MAAAA,SAAAA,CAAS,EAAE;GACrC,MAAM,CAAC,iBAAiB,uBAAA,GAAsBA,MAAAA,SAAAA,CAAS,KAAK;GAG5D,MAAM,cAAA,GAAaE,MAAAA,OAAAA,CAAO,CAAC;GAI3B,MAAM,UAAA,GAASM,MAAAA,YAAAA,CACb,OAAO,QAAgB,eAAuB;IAC5C,MAAM,MAAM,EAAE,WAAW;IACzB,SAAS,EAAE;IACX,IAAI;KACF,MAAM,OAAO,MAAM,UAOhB,YAAY,gBAAgB;MAC7B;MACA,OAAO;MACP,MAAM;MACN,UAAA;KACF,CAAC;KACD,IAAI,QAAQ,WAAW,SAAS;KAChC,QAAQ,KAAK,OAAO;KACpB,cAAc,KAAK,UAAU;KAC7B,eAAe,KAAK,WAAW;KAC/B,SAAS,KAAK,KAAK;KACnB,QAAQ,KAAK,IAAI;IACnB,SAAS,KAAK;KACZ,IAAI,QAAQ,WAAW,SAAS;KAChC,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;IAC3D;GACF,GACA,CAAC,YAAY,GAAG,CAClB;GAEA,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,OAAY,IAAI,CAAC;GAEnB,GAAG,CAAC,MAAM,CAAC;GAEX,MAAM,qBAAqB;IACzB,gBAAgB,UAAU;IAC1B,OAAY,YAAY,CAAC;GAC3B;GAEA,MAAM,aAAa,KAAK,IAAI,GAAG,KAAK,KAAK,QAAA,CAAyB,CAAC;GACnE,MAAM,aAAa,aAAa,aAAA,CAA8B;GAE9D,MAAM,MAAM,OAAO,UAAkB,SAAkC,WAAW,SAAS;IACzF,IAAI;KACF,MAAM,UAAU,YAAY,UAAU,OAAO;KAC7C,MAAM,OAAO,cAAc,QAAQ;IACrC,SAAS,KAAK;KACZ,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;IAC3D;GACF;GAEA,IAAI,UAAU,IAAI,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;IAAQ,QAAA;IAAQ,UAAA,EAAE,oBAAoB,EAAE,MAAM,CAAC;GAAU,CAAA;GAClF,IAAI,SAAS,KAAA,GACX,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,OAAO,EAAE,OAAO,OAAO,cAAc;IAAI,UAAA,EAAE,eAAe;GAAO,CAAA;GAE/E,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,OAAO;KAAE,SAAS;KAAQ,eAAe;KAAU,KAAK;IAAG;IAAhE,UAAA;KACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MACE,MAAK;MACL,cAAY,EAAE,2BAA2B;MACzC,WAAU;MACV,OAAO;OAAE,SAAS;OAAQ,KAAK;MAAE;MAJnC,UAAA;OAME,iBAAA,GAAA,kBAAA,IAAA,CAACE,sCAAAA,OAAD;QACE,MAAK;QACL,cAAY,EAAE,2BAA2B;QACzC,WAAU;QACV,aAAa,EAAE,iCAAiC;QAChD,OAAO;QACP,WAAW,UAAU,cAAc,MAAM,OAAO,KAAK;QACrD,YAAY,UAAU;SACpB,IAAI,MAAM,QAAQ,SAAS;SAC3B,MAAM,eAAe;SACrB,aAAa;QACf;OACD,CAAA;OACD,iBAAA,GAAA,kBAAA,IAAA,CAACD,sCAAAA,QAAD;QAAQ,SAAQ;QAAU,MAAK;QAAK,SAAS;QAC1C,UAAA,EAAE,sBAAsB;OACnB,CAAA;OAGP,kBACC,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;QACE,SAAQ;QACR,MAAK;QACL,eACE,KAAK,IAAI,iBAAiB,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,cAAc,mBAAmB,KAAK,CAAC;QAE/E,OAAO;SAAE,OAAO,OAAO;SAAY,aAAa,OAAO;QAAW;QAEjE,UAAA,EAAE,4BAA4B;OACzB,CAAA,GACR,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;QAAQ,SAAQ;QAAQ,MAAK;QAAK,eAAe,mBAAmB,KAAK;QACtE,UAAA,EAAE,2BAA2B;OACxB,CAAA,CACR,EAAA,CAAA,IAEF,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;QAAQ,SAAQ;QAAQ,MAAK;QAAK,eAAe,mBAAmB,IAAI;QACrE,UAAA,EAAE,qBAAqB;OAClB,CAAA;MAEP;;KACJ,eAAe,gBACd,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MACE,MAAK;MACL,aAAU;MACV,OAAO;OAAE,UAAU;OAAI,YAAY;OAAQ,OAAO,OAAO;MAAc;MAEtE,UAAA,EAAE,6BAA6B;KAC5B,CAAA;KAGP,KAAK,WAAW,KACf,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MACE,OAAO;OACL,OAAO,OAAO;OACd,UAAU;OACV,YAAY;OACZ,SAAS;OACT,WAAW;MACb;MAEC,UAAA,EAAE,qBAAqB;KACrB,CAAA;KAGN,KAAK,KAAK,KAAK,UAAU;MACxB,MAAM,QAAQ,IAAI,MAAM;MACxB,MAAM,OAAO,UAAU,KAAA,IAAY,KAAM,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,KAAK;MACnE,OAGE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAEE,WAAU;OACV,OAAO;QACL,SAAS;QACT,KAAK;QACL,YAAY;QACZ,QAAQ,GAAG,IAAI,WAAW,IAAI,EAAE,WAAW,OAAO;QAClD,cAAc;QACd,SAAS;QACT,UAAU;OACZ;OAXF,UAAA;QAaG,IAAI,YACH,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;SACE,OAAO;UACL,UAAU;UACV,KAAK;UACL,OAAO;UACP,YAAY;UACZ,cAAc;UACd,UAAU;UACV,YAAY;UACZ,SAAS;UACT,YAAY;UACZ,OAAO,OAAO;SAChB;SAZF,UAAA,CAaC,OACK,EAAE,yBAAyB,CAC3B;;QAEP,SAAS,MACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SACE,KAAK,SAAS,MAAM,GAAG;SACvB,KAAK;SACL,SAAQ;SACR,OAAO;SACP,QAAQ;SACR,OAAO;UACL,cAAc;UACd,QAAQ,aAAa,OAAO;UAC5B,WAAW;UACX,YAAY,OAAO;UACnB,YAAY;SACd;QACD,CAAA;QAEH,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SACE,WAAU;SACV,OAAO;UAAE,UAAU;UAAG,SAAS;UAAQ,eAAe;UAAU,KAAK;SAAE;SAFzE,UAAA,CAIE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;UACE,OAAO;WACL,YAAY;WACZ,UAAU;WACV,cAAc;WACd,UAAU;WACV,YAAY;WACZ,YAAY,IAAI,WAAW,MAAM;UACnC;UAEC,UAAA,IAAI;SACF,CAAA,GACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;UAAK,OAAO;WAAE,UAAU;WAAI,YAAY;WAAQ,OAAO,OAAO;UAAc;UAA5E,UAAA;WACG,WAAW,IAAI,IAAI;WAAE;WAAI,IAAI,SAAS;WAAI;WAAI,IAAI,QAAQ;WAAI;WAAG;WACjE,EAAE,2BAA2B,EAAE,GAAG,IAAI,MAAM,OAAO,CAAC;UAClD;SACF,CAAA,CAAA;;QACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SACE,WAAU;SACV,OAAO;UAAE,SAAS;UAAQ,KAAK;UAAG,UAAU;SAAO;SAFrD,UAAA,CAKG,IAAI,YACH,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;UAAQ,SAAQ;UAAQ,MAAK;UAAK,eAAe,KAAK,IAAI,gBAAgB,EAAE,IAAI,CAAC;UAC9E,UAAA,EAAE,2BAA2B;SACxB,CAAA,GAET,SAAS,MACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;UAAG,MAAM,SAAS,MAAM,GAAG;UAAG,QAAO;UAAS,KAAI;UAChD,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;WAAQ,SAAQ;WAAU,MAAK;WAC5B,UAAA,EAAE,mBAAmB;UAChB,CAAA;SACP,CAAA,CAEF;;OACF;MArFE,GAAA,GAAG,IAAI,KAAK,GAAG,IAAI,MAAM,MAAM,OAqFjC;KAET,CAAC;KACA,eAAe,QAAQ,eAAe,QACrC,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MACE,WAAU;MACV,OAAO;OACL,SAAS;OACT,YAAY;OACZ,KAAK;OACL,UAAU;OACV,YAAY;OACZ,OAAO,OAAO;MAChB;MATF,UAAA,CAWE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD,EAAA,UAAA,CAAM,OAAI,EAAE,8BAA8B,EAAE,GAAG,WAAW,CAAC,CAAQ,EAAA,CAAA,GACnE,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;OAAQ,SAAQ;OAAQ,MAAK;OAAK,eAAe,KAAK,OAAO,cAAc,UAAU;OAClF,UAAA,EAAE,0BAA0B;MACvB,CAAA,CACL;;KAGN,aAAa,KACZ,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MACE,WAAU;MACV,OAAO;OACL,SAAS;OACT,YAAY;OACZ,gBAAgB;OAChB,KAAK;OACL,UAAU;MACZ;MARF,UAAA,CAUE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,OAAO;QAAE,UAAU;QAAI,OAAO,OAAO;OAAc;OACtD,UAAA,EAAE,4BAA4B,EAAE,GAAG,MAAM,CAAC;MACvC,CAAA,GACN,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OACE,WAAU;OACV,OAAO;QAAE,SAAS;QAAQ,YAAY;QAAU,KAAK;OAAE;OAFzD,UAAA;QAIE,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;SACE,SAAQ;SACR,MAAK;SACL,UAAU,QAAQ;SAClB,eAAe,KAAK,OAAO,cAAc,OAAO,CAAC;SAEhD,UAAA,EAAE,oBAAoB;QACjB,CAAA;QACP,MAAM,KAAK,EAAE,QAAQ,WAAW,IAAI,GAAG,MAAM,IAAI,CAAC,CAAC,CAAC,KAAK,MACxD,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;SAEE,SAAS,MAAM,OAAO,YAAY;SAClC,MAAK;SACL,WAAU;SACV,eAAe,KAAK,OAAO,cAAc,CAAC;SAEzC,UAAA;QACK,GAPD,CAOC,CACT;QACD,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;SACE,SAAQ;SACR,MAAK;SACL,UAAU,QAAQ;SAClB,eAAe,KAAK,OAAO,cAAc,OAAO,CAAC;SAEhD,UAAA,EAAE,oBAAoB;QACjB,CAAA;OACL;MACF,CAAA,CAAA;;KAGN,eAAe,QAAQ,KAAK,MAAM,MAAM,EAAE,QAAQ,KACjD,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAS,EAAE,0BAA0B,EAAU,CAAA;IAE9C;;EAET;EAEA,SAAS,WAAW,KAAqB;GACvC,MAAM,OAAO,IAAI,KAAK,GAAG;GACzB,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,GAAG,OAAO;GACzC,MAAM,OAAO,MAAc,OAAO,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG;GACpD,OAAO,GAAG,KAAK,YAAY,EAAE,GAAG,IAAI,KAAK,SAAS,IAAI,CAAC,EAAE,GAAG,IAAI,KAAK,QAAQ,CAAC,EAAE,GAAG,IAAI,KAAK,SAAS,CAAC,EAAE,GAAG,IAAI,KAAK,WAAW,CAAC;EAClI;EAIA,SAAS,MAAM,OAMZ;GAED,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;IAAO,OAAO;KAAE,SAAS;KAAe,YAAY;KAAU,KAAK;IAAE;IAArE,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;KACE,MAAK;KACL,MAAM,MAAM;KACZ,SAAS,MAAM;KACf,UAAU,MAAM;KAChB,UAAU,MAAM;IACjB,CAAA,GACA,MAAM,KACF;;EAEX;;EAGA,SAAS,YAAY,OAAoC;GACvD,MAAM,GAAG,SAAA,GAAQT,MAAAA,SAAAA,CAAS,CAAC;GAC3B,CAAA,GAAA,MAAA,UAAA,OAAgB,MAAM,gBAAgB,MAAM,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;EACpE;;EAGA,eAAe,UACb,OACA,OACA,OACA,SACe;GACf,IAAI;IACF,MAAM,MAAM,IAAI,OAAO,KAAK;IAC5B,QAAQ,EAAE;GACZ,SAAS,KAAK;IACZ,QAAQ,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;GAC1D;EACF;;;;EC1/CA,MAAa,KAAK;;EAGlB,MAAa,KAAK;GAEhB,mBAAmB;GACnB,gBAAgB;GAChB,eAAe;GACf,0BAA0B;GAC1B,qBAAqB;GACrB,iBAAiB;GACjB,4BAA4B;GAC5B,uBAAuB;GACvB,uBAAuB;GACvB,uBAAuB;GACvB,sBAAsB;GACtB,wBAAwB;GACxB,kBAAkB;GAClB,wBAAwB;GACxB,wBAAwB;GACxB,wBAAwB;GACxB,iBAAiB;GAGjB,aAAa;GACb,sBAAsB;GACtB,sBAAsB;GACtB,yBAAyB;GACzB,qBAAqB;GACrB,iBAAiB;GACjB,oBAAoB;GACpB,wBAAwB;GACxB,wBAAwB;GACxB,iBAAiB;GAGjB,wBACE;GACF,6BAA6B;GAC7B,6BAA6B;GAC7B,4BAA4B;GAC5B,6BAA6B;GAC7B,4BACE;GACF,6BAA6B;GAC7B,4BAA4B;GAC5B,6BAA6B;GAG7B,wBAAwB;GACxB,gCAAgC;GAChC,iCAAiC;GACjC,0BAA0B;GAC1B,iCAAiC;GACjC,8BACE;GACF,qCACE;GACF,2BAA2B;GAC3B,8BACE;GACF,0BAA0B;GAC1B,0BAA0B;GAC1B,4BAA4B;GAC5B,6BAA6B;GAC7B,6BAA6B;GAC7B,yBACE;GACF,yBACE;GACF,yBACE;GACF,yBAAyB;GACzB,oCAAoC;GACpC,kCAAkC;GAClC,+BAA+B;GAC/B,gCAAgC;GAChC,uCAAuC;GACvC,oCAAoC;GACpC,mCAAmC;GACnC,qCAAqC;GACrC,yBAAyB;GACzB,0BAA0B;GAC1B,gCAAgC;GAChC,kCAAkC;GAClC,gCACE;GACF,iBAAiB;GACjB,yBAAyB;GACzB,yBACE;GACF,0BAA0B;GAC1B,sBAAsB;GACtB,sBAAsB;GACtB,0BAA0B;GAC1B,6BAA6B;GAC7B,8BAA8B;GAG9B,wBAAwB;GACxB,iCAAiC;GACjC,4BAA4B;GAC5B,wBAAwB;GACxB,qBAAqB;GACrB,2BAA2B;GAC3B,uBAAuB;GACvB,uBAAuB;GACvB,4BAA4B;GAC5B,oBAAoB;GACpB,qBAAqB;GACrB,oBAAoB;GACpB,qBAAqB;GACrB,+BAA+B;GAC/B,oCACE;GAGF,wBAAwB;GACxB,6BAA6B;GAC7B,mCAAmC;GACnC,+BAA+B;GAC/B,uBAAuB;GACvB,8BAA8B;GAC9B,6BAA6B;GAC7B,uBAAuB;GACvB,2BAA2B;GAC3B,6BAA6B;GAC7B,2BAA2B;GAC3B,4BACE;GACF,sBAAsB;GACtB,sBAAsB;GACtB,4BAA4B;GAC5B,8BAA8B;GAC9B,4BAA4B;GAC5B,2BAA2B;EAC7B;;EAaA,MAAa,KAAK;GAChB,mBAAmB;GACnB,gBAAgB;GAChB,eAAe;GACf,0BAA0B;GAC1B,qBAAqB;GACrB,iBAAiB;GACjB,4BAA4B;GAC5B,uBAAuB;GACvB,uBAAuB;GACvB,uBAAuB;GACvB,sBAAsB;GACtB,wBAAwB;GACxB,kBACE;GACF,wBAAwB;GACxB,wBAAwB;GACxB,wBAAwB;GACxB,iBAAiB;GAEjB,aAAa;GACb,sBAAsB;GACtB,sBAAsB;GACtB,yBAAyB;GACzB,qBAAqB;GACrB,iBAAiB;GACjB,oBAAoB;GACpB,wBACE;GACF,wBAAwB;GACxB,iBAAiB;GAEjB,wBACE;GACF,6BAA6B;GAC7B,6BAA6B;GAC7B,4BACE;GACF,6BAA6B;GAC7B,4BACE;GACF,6BAA6B;GAC7B,4BACE;GACF,6BAA6B;GAE7B,wBAAwB;GACxB,gCAAgC;GAChC,iCAAiC;GACjC,0BAA0B;GAC1B,iCAAiC;GACjC,8BACE;GACF,qCACE;GACF,2BAA2B;GAC3B,8BACE;GACF,0BAA0B;GAC1B,0BAA0B;GAC1B,4BAA4B;GAC5B,6BAA6B;GAC7B,6BAA6B;GAC7B,yBACE;GACF,yBACE;GACF,yBACE;GACF,yBAAyB;GACzB,oCAAoC;GACpC,kCAAkC;GAClC,+BAA+B;GAC/B,gCAAgC;GAChC,uCAAuC;GACvC,oCAAoC;GACpC,mCAAmC;GACnC,qCAAqC;GACrC,yBAAyB;GACzB,0BAA0B;GAC1B,gCAAgC;GAChC,kCAAkC;GAClC,gCACE;GACF,iBAAiB;GACjB,yBACE;GACF,yBACE;GACF,0BAA0B;GAC1B,sBACE;GACF,sBAAsB;GACtB,0BAA0B;GAC1B,6BAA6B;GAC7B,8BAA8B;GAE9B,wBAAwB;GACxB,iCAAiC;GACjC,4BAA4B;GAC5B,wBAAwB;GACxB,qBAAqB;GACrB,2BAA2B;GAC3B,uBAAuB;GACvB,uBAAuB;GACvB,4BAA4B;GAC5B,oBAAoB;GACpB,qBAAqB;GACrB,oBAAoB;GACpB,qBAAqB;GACrB,+BAA+B;GAC/B,oCACE;GAEF,wBAAwB;GACxB,6BAA6B;GAC7B,mCAAmC;GACnC,+BAA+B;GAC/B,uBAAuB;GACvB,8BAA8B;GAC9B,6BAA6B;GAC7B,uBAAuB;GACvB,2BAA2B;GAC3B,6BAA6B;GAC7B,2BAA2B;GAC3B,4BACE;GACF,sBAAsB;GACtB,sBAAsB;GACtB,4BAA4B;GAC5B,8BAA8B;GAC9B,4BAA4B;GAC5B,2BAA2B;EAC7B;;;;;;ECzQA,MAAa,SAAS;GAAC;GAAS;GAAU;GAAc;EAAe;EAEvE,SAAgB,MAAM,KAA0B;GAC9C,IAAI,aAAa,IAAI,OAAO,SAAS,IAAI;IAAE;IAAI;GAAG,CAAC,GAAG,yBAAyB;GAG/E,MAAM,QAAS,IAAI,IAAI,eAAe,CAAC,CAA6B,KAAiB,EACnF,WAAW,YACb,CAAC;GACD,MAAM,aAAa,IAAI,IAAI,YAAY;;;;;GAMvC,MAAM,aAAiC,EACrC,MAAM,MAAc,QAAiB,UAAU,YAAY,cAAc;IAAE;IAAM;GAAI,CAAC,EACxF;GAEA,IAAI,MAAM,OAAO,4BACf,IAAI,MAAM,SACR;IACE,MAAM;IACN,KAAK;IACL,QAAQ;IACR,eAAe,EAAE,QAAQ,WAAW;GACtC,GACA,gBACF,CACF;GAEA,MAAM,uBAA8C;IAAE;IAAO;GAAW;GAExE,IAAI,MAAM,OAAO,0BACf,IAAI,MAAM,SACR;IACE,MAAM;IACN,IAAI;IACJ,OAAO;IACP,aAAa,IAAI,OAAO,KAAK,EAAE,CAAC,CAAC,WAAW;IAC5C,QAAQ;IACR,QAAQ;GACV,GACA,eACF,CACF;EACF"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,73 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ import { type MockupPrefs } from './prefs.js';
3
+ import { buildPrompt } from './prompt.js';
4
+ export declare const name = "ui-mockup";
5
+ /** 硬依赖:工具注册与使用规则注入是本插件的全部职责,等待这些服务出现。 */
6
+ export declare const inject: string[];
7
+ /** 与 dsh-host-apiproxy 的 RpcResult 同构的最小形状(避免宿主半区引入该依赖)。 */
8
+ export type RpcResultLike<T> = {
9
+ ok: true;
10
+ value: T;
11
+ } | {
12
+ ok: false;
13
+ error: {
14
+ code: string;
15
+ message: string;
16
+ details?: Record<string, unknown>;
17
+ };
18
+ };
19
+ /** 插件 Config:设置命名空间的组合 base 层;未配置的字段取内置默认。 */
20
+ export interface MockupPluginConfig {
21
+ defaultFidelity?: 'wireframe' | 'high-fidelity';
22
+ defaultPlatform?: 'web' | 'mobile';
23
+ defaultCount?: number;
24
+ /** 已由设计资产库接管,配置不再生效;保留仅为兼容旧用户层数据。 */
25
+ outputDir?: string;
26
+ pollTimeoutMinutes?: number;
27
+ wireframeModel?: string;
28
+ highFidelityModel?: string;
29
+ defaultSize?: string;
30
+ }
31
+ export declare const Config: import("@deepseek-ai/schemastery").default<Schemastery.ObjectS<{
32
+ defaultFidelity: import("@deepseek-ai/schemastery").default<"wireframe" | "high-fidelity", "wireframe" | "high-fidelity">;
33
+ defaultPlatform: import("@deepseek-ai/schemastery").default<"web" | "mobile", "web" | "mobile">;
34
+ defaultCount: import("@deepseek-ai/schemastery").default<number, number>;
35
+ outputDir: import("@deepseek-ai/schemastery").default<string, string>;
36
+ pollTimeoutMinutes: import("@deepseek-ai/schemastery").default<number, number>;
37
+ wireframeModel: import("@deepseek-ai/schemastery").default<string, string>;
38
+ highFidelityModel: import("@deepseek-ai/schemastery").default<string, string>;
39
+ defaultSize: import("@deepseek-ai/schemastery").default<string, string>;
40
+ }>, Schemastery.ObjectT<{
41
+ defaultFidelity: import("@deepseek-ai/schemastery").default<"wireframe" | "high-fidelity", "wireframe" | "high-fidelity">;
42
+ defaultPlatform: import("@deepseek-ai/schemastery").default<"web" | "mobile", "web" | "mobile">;
43
+ defaultCount: import("@deepseek-ai/schemastery").default<number, number>;
44
+ outputDir: import("@deepseek-ai/schemastery").default<string, string>;
45
+ pollTimeoutMinutes: import("@deepseek-ai/schemastery").default<number, number>;
46
+ wireframeModel: import("@deepseek-ai/schemastery").default<string, string>;
47
+ highFidelityModel: import("@deepseek-ai/schemastery").default<string, string>;
48
+ defaultSize: import("@deepseek-ai/schemastery").default<string, string>;
49
+ }>>;
50
+ /**
51
+ * $DSH_HOME:与宿主 resolveDshHome 同口径——环境变量优先、默认 ~/.dsh;
52
+ * 纯空白值视为未设置(避免把 home 解析成 cwd 下的怪目录),前导 ~ 展开为 home。
53
+ */
54
+ declare function dshHome(): string;
55
+ /** 偏好生效值:settings 服务可用时以命名空间 resolved 值为准;
56
+ * 缺席(纯内存部署)时退化为 cordis.yml 配置层覆盖内置默认。 */
57
+ export declare function effectivePrefs(scope: {
58
+ get(): MockupPrefs;
59
+ } | undefined, config: MockupPluginConfig): MockupPrefs;
60
+ export declare function apply(ctx: Context, config?: MockupPluginConfig): void;
61
+ /** DSH home 用户层 patch 文件(launcher 实时 watch,编辑后组合热重载)。 */
62
+ export declare const HOME_PATCH_FILENAME = "cordis.patch.yml";
63
+ /**
64
+ * 生成切换提供方后的用户层 patch 行:对两行 Provider 做 id 定向 disabled 翻转。
65
+ * 用户层 applied after bundle layers——bundle 插入的行由此覆盖 enabled 状态,
66
+ * 且只携带 id/disabled 两个字段,不触碰用户可能写在同 id 行上的其他定制;
67
+ * 已有行原位更新(保留其余字段),缺失行追加在列表尾部。
68
+ * 纯函数:宿主端点与单测共用同一合并语义。
69
+ */
70
+ export declare function mergeProviderSwitchRows(patches: readonly unknown[], target: 'dashscope' | 'volcengine'): Record<string, unknown>[];
71
+ /** 供单元测试引用的内部实现。 */
72
+ export { buildPrompt, dshHome };
73
+ export { sanitizeOutputDir, clampCount, parseHistoryLine, filterHistory, DEFAULT_PREFS, } from './prefs.js';