@artenx/dshb 0.1.12 → 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["SECTION_ID","useState","useCallback","apply","inputStyle","buttonStyle","primaryButtonStyle","secondaryButtonStyle","useState","useCallback","useState","useCallback","apply"],"sources":["../src/client/auth.tsx","../src/client/directory-flow.tsx","../src/client/mobile.tsx","../src/client/workspace-instruction-menu.tsx","../src/client/ui.tsx","../src/client/index.tsx"],"sourcesContent":["import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { CSSProperties, ReactElement } from 'react'\nimport { useCallback, useEffect, useState } from 'react'\n\nexport const inject = ['connection']\n\nconst SECTION_ID = 'auth'\nconst MESSAGE_MS = 5000\n\nfunction useUsername(): [string | undefined, (username: string) => void] {\n const [username, setUsername] = useState<string | undefined>(undefined)\n useEffect(() => {\n let cancelled = false\n void (async () => {\n try {\n const res = await fetch('/api/auth/status')\n if (!res.ok) return\n const data = (await res.json()) as { username?: string }\n if (!cancelled && typeof data.username === 'string') setUsername(data.username)\n } catch {\n // best-effort\n }\n })()\n return () => {\n cancelled = true\n }\n }, [])\n return [username, setUsername]\n}\n\ntype Notice = { kind: 'ok' | 'error'; text: string; owner: 'username' | 'password' | 'account' }\n\nexport function AuthSection(_props: PropsRuntime<'settings.section'>): ReactElement {\n const [username, setUsername] = useUsername()\n const [newUsername, setNewUsername] = useState('')\n const [usernamePassword, setUsernamePassword] = useState('')\n const [oldPassword, setOldPassword] = useState('')\n const [newPassword, setNewPassword] = useState('')\n const [confirm, setConfirm] = useState('')\n const [busy, setBusy] = useState(false)\n const [notice, setNotice] = useState<Notice | undefined>(undefined)\n const [confirmingSignOut, setConfirmingSignOut] = useState(false)\n\n const flash = useCallback((n: Notice | undefined) => {\n setNotice(n)\n if (n !== undefined) setTimeout(() => setNotice(undefined), MESSAGE_MS)\n }, [])\n\n const signOut = useCallback(async () => {\n setBusy(true)\n try {\n await fetch('/api/auth/logout', { method: 'POST' })\n window.location.href = '/login'\n } catch {\n setBusy(false)\n setConfirmingSignOut(false)\n flash({ kind: 'error', text: '退出失败,请重试', owner: 'account' })\n }\n }, [flash])\n\n const changePassword = useCallback(async () => {\n if (newPassword !== confirm) {\n flash({ kind: 'error', text: '两次输入的新密码不一致', owner: 'password' })\n return\n }\n setBusy(true)\n try {\n const res = await fetch('/api/auth/change-password', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ currentPassword: oldPassword, password: newPassword }),\n })\n const data = (await res.json()) as { error?: string }\n if (res.ok) {\n setOldPassword('')\n setNewPassword('')\n setConfirm('')\n flash({ kind: 'ok', text: '密码已修改', owner: 'password' })\n } else {\n flash({ kind: 'error', text: data.error ?? '修改失败,请重试', owner: 'password' })\n }\n } catch {\n flash({ kind: 'error', text: '修改失败,请重试', owner: 'password' })\n } finally {\n setBusy(false)\n }\n }, [oldPassword, newPassword, confirm, flash])\n\n const changeUsername = useCallback(async () => {\n setBusy(true)\n try {\n const res = await fetch('/api/auth/change-username', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ username: newUsername, currentPassword: usernamePassword }),\n })\n const data = (await res.json()) as { error?: string }\n if (res.ok) {\n setNewUsername('')\n setUsernamePassword('')\n if (newUsername) setUsername(newUsername)\n flash({ kind: 'ok', text: '用户名已更新', owner: 'username' })\n } else {\n flash({ kind: 'error', text: data.error ?? '修改失败,请重试', owner: 'username' })\n }\n } catch {\n flash({ kind: 'error', text: '修改失败,请重试', owner: 'username' })\n } finally {\n setBusy(false)\n }\n }, [newUsername, usernamePassword, flash, setUsername])\n\n const inputStyle: CSSProperties = {\n width: '100%',\n boxSizing: 'border-box',\n padding: '0 10px',\n height: 32,\n border: '1px solid var(--dsw-alias-border-l2)',\n borderRadius: 8,\n fontSize: 14,\n fontFamily: 'inherit',\n background: 'var(--dsw-alias-bg-layer-1)',\n color: 'var(--dsw-alias-label-primary)',\n outline: 'none',\n }\n const buttonStyle: CSSProperties = {\n boxSizing: 'border-box',\n height: 36,\n padding: '0 14px',\n borderRadius: 18,\n fontSize: 14,\n lineHeight: '22px',\n fontFamily: 'inherit',\n cursor: 'pointer',\n border: 'none',\n display: 'inline-flex',\n justifyContent: 'center',\n alignItems: 'center',\n gap: 4,\n }\n const primaryButtonStyle: CSSProperties = {\n ...buttonStyle,\n background: 'var(--dsw-alias-button-primary-fill)',\n color: 'var(--dsw-alias-label-primary-foreground)',\n }\n const secondaryButtonStyle: CSSProperties = {\n ...buttonStyle,\n border: '1px solid var(--dsw-alias-border-l2)',\n color: 'var(--dsw-alias-label-primary)',\n background: 'transparent',\n }\n const dangerButtonStyle: CSSProperties = {\n ...buttonStyle,\n color: 'var(--dsw-alias-state-error-primary)',\n background: 'transparent',\n }\n const dangerOutlineButtonStyle: CSSProperties = {\n ...buttonStyle,\n border: '1px solid var(--dsw-alias-state-error-primary)',\n color: 'var(--dsw-alias-state-error-primary)',\n background: 'transparent',\n }\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 24, maxWidth: 420 }}>\n <section>\n <h2 style={{ fontSize: 16, fontWeight: 600, margin: '0 0 4px' }}>账号</h2>\n <p style={{ fontSize: 13, opacity: 0.7, margin: '0 0 12px' }}>\n {username !== undefined ? `当前登录:${username}` : '当前登录:管理员'}\n </p>\n <button\n type=\"button\"\n onClick={() => setConfirmingSignOut(true)}\n disabled={busy}\n style={dangerOutlineButtonStyle}\n >\n 退出登录\n </button>\n {confirmingSignOut && (\n <div role=\"alertdialog\" aria-label=\"确认退出登录\" style={{ marginTop: 10, padding: '12px 14px', border: '1px solid var(--dsw-alias-border-l2)', borderRadius: 8, maxWidth: 320 }}>\n <div style={{ fontSize: 13, marginBottom: 10, color: 'var(--dsw-alias-label-primary)' }}>退出登录将回到登录页</div>\n <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8 }}>\n <button type=\"button\" onClick={() => setConfirmingSignOut(false)} disabled={busy} style={{ ...secondaryButtonStyle, height: 32, padding: '0 12px', borderRadius: 16 }}>\n 取消\n </button>\n <button type=\"button\" onClick={() => void signOut()} disabled={busy} style={{ ...dangerOutlineButtonStyle, height: 32, padding: '0 12px', borderRadius: 16, background: 'var(--dsw-alias-interactive-bg-hover-danger)' }}>\n 确认退出\n </button>\n </div>\n </div>\n )}\n {notice?.owner === 'account' && (\n <p style={{ fontSize: 13, color: notice.kind === 'ok' ? 'var(--dsw-alias-state-success-primary)' : 'var(--dsw-alias-state-error-primary)', margin: '8px 0 0' }}>{notice.text}</p>\n )}\n </section>\n\n <section>\n <h2 style={{ fontSize: 16, fontWeight: 600, margin: '0 0 12px' }}>修改用户名</h2>\n <form onSubmit={(e) => { e.preventDefault(); void changeUsername() }} style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 新用户名\n <input type=\"text\" value={newUsername} onChange={(e) => setNewUsername(e.target.value)} autoComplete=\"username\" style={inputStyle} />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 当前密码\n <input type=\"password\" value={usernamePassword} onChange={(e) => setUsernamePassword(e.target.value)} autoComplete=\"current-password\" style={inputStyle} />\n </label>\n <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>\n <button type=\"submit\" disabled={busy} style={primaryButtonStyle}>修改用户名</button>\n {notice?.owner === 'username' && <span style={{ fontSize: 13, color: notice.kind === 'ok' ? 'var(--dsw-alias-state-success-primary)' : 'var(--dsw-alias-state-error-primary)' }}>{notice.text}</span>}\n </div>\n </form>\n </section>\n\n <section>\n <h2 style={{ fontSize: 16, fontWeight: 600, margin: '0 0 12px' }}>修改密码</h2>\n <form onSubmit={(e) => { e.preventDefault(); void changePassword() }} style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 当前密码\n <input type=\"password\" value={oldPassword} onChange={(e) => setOldPassword(e.target.value)} autoComplete=\"current-password\" style={inputStyle} />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 新密码\n <input type=\"password\" value={newPassword} onChange={(e) => setNewPassword(e.target.value)} autoComplete=\"new-password\" style={inputStyle} />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 确认新密码\n <input type=\"password\" value={confirm} onChange={(e) => setConfirm(e.target.value)} autoComplete=\"new-password\" style={inputStyle} />\n </label>\n <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>\n <button type=\"submit\" disabled={busy} style={primaryButtonStyle}>修改密码</button>\n {notice?.owner === 'password' && <span style={{ fontSize: 13, color: notice.kind === 'ok' ? 'var(--dsw-alias-state-success-primary)' : 'var(--dsw-alias-state-error-primary)' }}>{notice.text}</span>}\n </div>\n </form>\n </section>\n </div>\n )\n}\n\nexport function apply(ctx: ClientContext): void {\n const connection = ctx.get('connection') as { isLoopback?: boolean } | undefined\n if (connection !== undefined) {\n Object.defineProperty(connection, 'isLoopback', { configurable: true, get: () => true })\n }\n ctx.plugin({\n inject: ['slots'],\n apply: (sub: ClientContext): void => {\n sub.slots.inject('settings.section', () =>\n sub.slots.register({ name: 'settings.section', id: SECTION_ID, order: 100, label: () => '认证' }, AuthSection),\n )\n },\n })\n}\n","import type { DirectoryFlowOwnerProps } from '@deepseek-ai/dsh-client-ui-workspace/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type { CSSProperties, ReactElement } from 'react'\nimport { useCallback, useEffect, useState } from 'react'\n\ninterface NodeProfileView {\n id: string\n name: string\n type: 'local-host' | 'local-docker' | 'remote-ssh' | 'remote-docker'\n status?: { reachable?: boolean }\n}\n\ninterface DirEntry {\n name: string\n path: string\n isDirectory: boolean\n}\n\nconst inputStyle: CSSProperties = {\n width: '100%',\n boxSizing: 'border-box',\n padding: '0 10px',\n height: 32,\n border: '1px solid var(--dsw-alias-border-l2)',\n borderRadius: 8,\n fontSize: 14,\n fontFamily: 'inherit',\n background: 'var(--dsw-alias-bg-layer-1)',\n color: 'var(--dsw-alias-label-primary)',\n outline: 'none',\n}\nconst buttonStyle: CSSProperties = {\n boxSizing: 'border-box',\n height: 36,\n padding: '0 14px',\n borderRadius: 18,\n fontSize: 14,\n lineHeight: '22px',\n fontFamily: 'inherit',\n cursor: 'pointer',\n border: 'none',\n display: 'inline-flex',\n justifyContent: 'center',\n alignItems: 'center',\n gap: 4,\n}\nconst primaryButtonStyle: CSSProperties = {\n ...buttonStyle,\n background: 'var(--dsw-alias-button-primary-fill)',\n color: 'var(--dsw-alias-label-primary-foreground)',\n}\nconst secondaryButtonStyle: CSSProperties = {\n ...buttonStyle,\n border: '1px solid var(--dsw-alias-border-l2)',\n color: 'var(--dsw-alias-label-primary)',\n background: 'transparent',\n}\nconst overlayStyle: CSSProperties = {\n position: 'fixed',\n inset: 0,\n background: 'var(--dsw-alias-overlay-mask, rgba(0,0,0,0.45))',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 1000,\n}\nconst dialogStyle: CSSProperties = {\n width: 'min(92vw, 560px)',\n maxWidth: '100%',\n maxHeight: '80vh',\n overflow: 'auto',\n overflowX: 'hidden',\n background: 'var(--dsw-alias-bg-layer-1)',\n border: '1px solid var(--dsw-alias-border-l2)',\n borderRadius: 12,\n padding: 20,\n boxSizing: 'border-box',\n color: 'var(--dsw-alias-label-primary)',\n}\n\nfunction joinPath(base: string, name: string): string {\n return `${base.replace(/\\/+$/, '')}/${name}`\n}\n\nexport function DirectoryFlowOccupant(props: DirectoryFlowOwnerProps): ReactElement | null {\n const [nodes, setNodes] = useState<NodeProfileView[]>([])\n const [nodeId, setNodeId] = useState<string>('')\n const [path, setPath] = useState('')\n const [entries, setEntries] = useState<DirEntry[]>([])\n const [error, setError] = useState<string | undefined>(undefined)\n const [busy, setBusy] = useState(false)\n const [newDirName, setNewDirName] = useState('')\n const [pendingInstruction, setPendingInstruction] = useState<string | undefined>(undefined)\n const [instructionDialogOpen, setInstructionDialogOpen] = useState(false)\n\n useEffect(() => {\n if (!props.open) return\n void (async () => {\n try {\n const res = await fetch('/api/dshb/nodes')\n if (!res.ok) return\n const data = (await res.json()) as { nodes?: NodeProfileView[] }\n setNodes(data.nodes ?? [])\n } catch {}\n })()\n }, [props.open])\n\n const browse = useCallback(async (id: string, dir: string) => {\n setError(undefined)\n try {\n const res = await fetch(`/api/dshb/nodes/${id}/browse?path=${encodeURIComponent(dir)}`)\n const data = (await res.json()) as { ok?: boolean; path?: string; entries?: DirEntry[]; error?: string }\n if (!res.ok || !data.ok) {\n setError(data.error ?? '目录读取失败')\n return\n }\n setPath(data.path ?? dir)\n setEntries((data.entries ?? []).filter((e) => e.isDirectory))\n } catch {\n setError('网络错误')\n }\n }, [])\n\n const selectNode = useCallback(\n (id: string) => {\n setNodeId(id)\n setPath('')\n setEntries([])\n setError(undefined)\n void browse(id, '/')\n },\n [browse],\n )\n\n const mkdir = useCallback(async () => {\n if (!newDirName.trim()) return\n setBusy(true)\n setError(undefined)\n try {\n const target = joinPath(path, newDirName.trim())\n const res = await fetch(`/api/dshb/nodes/${nodeId}/mkdir`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ path: target }),\n })\n const data = (await res.json()) as { ok?: boolean; error?: string }\n if (!res.ok || !data.ok) {\n setError(data.error ?? '创建目录失败')\n return\n }\n setNewDirName('')\n void browse(nodeId, target)\n } catch {\n setError('网络错误')\n } finally {\n setBusy(false)\n }\n }, [newDirName, nodeId, path, browse])\n\n const confirm = useCallback(async () => {\n if (!nodeId || !path) {\n setError('请选择节点与目录')\n return\n }\n setBusy(true)\n setError(undefined)\n try {\n const node = nodes.find((n) => n.id === nodeId)\n if (!node) return\n let pickedPath = path\n if (node.type !== 'local-host') {\n const res = await fetch('/api/dshb/workspaces/bind', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ nodeId, remotePath: path }),\n })\n const data = (await res.json()) as { ok?: boolean; mirrorPath?: string; error?: string }\n if (!res.ok || !data.ok || !data.mirrorPath) {\n setError(data.error ?? '工作区注册失败')\n return\n }\n pickedPath = data.mirrorPath\n }\n props.onPicked(pickedPath)\n if (pendingInstruction !== undefined && pendingInstruction.trim()) {\n savePendingInstruction(pickedPath, pendingInstruction)\n }\n } catch {\n setError('网络错误')\n } finally {\n setBusy(false)\n }\n }, [nodeId, path, nodes, props, pendingInstruction])\n\n if (!props.open) return null\n\n const node = nodes.find((n) => n.id === nodeId)\n\n return (\n <div style={overlayStyle} role=\"dialog\" aria-label=\"添加工作区\">\n <div style={dialogStyle}>\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 14 }}>\n <h2 style={{ margin: 0, fontSize: 16, color: 'var(--dsw-alias-label-primary)' }}>添加工作区</h2>\n <button type=\"button\" onClick={props.onCancel} style={secondaryButtonStyle}>\n 关闭\n </button>\n </div>\n\n <label style={{ display: 'block', fontSize: 12, color: 'var(--dsw-alias-label-secondary)', marginBottom: 4 }}>工作节点</label>\n <select style={{ ...inputStyle, marginBottom: 14 }} value={nodeId} onChange={(e) => selectNode(e.target.value)} disabled={props.busy || busy}>\n <option value=\"\">选择节点…</option>\n {nodes.map((n) => {\n const typeLabel =\n n.type === 'local-host' ? '本地' : n.type === 'remote-ssh' ? '远程 SSH' : n.type === 'local-docker' ? '本地 Docker' : n.type === 'remote-docker' ? '远程 Docker' : n.type\n return (\n <option key={n.id} value={n.id}>\n {n.name}({typeLabel})\n </option>\n )\n })}\n </select>\n\n {nodeId !== '' && (\n <>\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 6 }}>\n <label style={{ fontSize: 12, color: 'var(--dsw-alias-label-secondary)' }}>当前目录({node?.type === 'local-host' ? '本机' : '远端'})</label>\n <button type=\"button\" onClick={() => void browse(nodeId, dirnameOf(path))} disabled={busy} style={secondaryButtonStyle}>\n 上一级\n </button>\n </div>\n <div style={{ ...inputStyle, marginBottom: 8, height: 'auto', minHeight: 32, display: 'flex', alignItems: 'center', flexWrap: 'wrap', gap: 2, cursor: 'pointer', lineHeight: '32px', overflow: 'hidden' }} onClick={() => void browse(nodeId, path)}>\n {path.split('/').filter(Boolean).length === 0 ? (\n <span style={{ opacity: 0.5 }}>根目录</span>\n ) : (\n <>\n <span onClick={(ev) => { ev.stopPropagation(); void browse(nodeId, '/') }} style={{ cursor: 'pointer', color: 'var(--dsw-alias-label-secondary)' }}>/</span>\n {path.split('/').filter(Boolean).map((seg, i, arr) => {\n const dir = '/' + arr.slice(0, i + 1).join('/')\n return (\n <span key={i} style={{ display: 'inline-flex', alignItems: 'center', gap: 2 }}>\n <span onClick={(ev) => { ev.stopPropagation(); void browse(nodeId, dir) }} style={{ cursor: 'pointer' }}>{seg}</span>\n {i < arr.length - 1 && <span style={{ opacity: 0.4 }}>/</span>}\n </span>\n )\n })}\n </>\n )}\n </div>\n <div style={{ maxHeight: 200, overflow: 'auto', border: '1px solid var(--dsw-alias-border-l2)', borderRadius: 6, marginBottom: 10 }}>\n {entries.map((e) => (\n <div key={e.path} onClick={() => void browse(nodeId, e.path)} style={{ padding: '7px 10px', cursor: 'pointer', fontSize: 13, borderRadius: 6, color: 'var(--dsw-alias-label-primary)', display: 'flex', alignItems: 'center', gap: 6, overflow: 'hidden' }} onMouseEnter={(ev) => (ev.currentTarget.style.background = 'var(--dsw-alias-interactive-bg-hover)')} onMouseLeave={(ev) => (ev.currentTarget.style.background = 'transparent')}>\n <span style={{ flexShrink: 0 }}>📁</span>\n <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{e.name}</span>\n </div>\n ))}\n {entries.length === 0 && <div style={{ padding: 12, fontSize: 12, color: 'var(--dsw-alias-label-tertiary)' }}>无子目录</div>}\n </div>\n <div style={{ display: 'flex', gap: 8, marginBottom: 12 }}>\n <input style={{ ...inputStyle, flex: 1, minWidth: 0 }} value={newDirName} onChange={(e) => setNewDirName(e.target.value)} placeholder=\"在当前目录下新建子目录…\" onKeyDown={(e) => { if (e.key === 'Enter') void mkdir() }} />\n <button type=\"button\" onClick={() => void mkdir()} disabled={busy || !newDirName.trim()} style={{ ...secondaryButtonStyle, flexShrink: 0, whiteSpace: 'nowrap' }}>\n 新建\n </button>\n </div>\n </>\n )}\n\n {error && <div style={{ fontSize: 13, color: 'var(--dsw-alias-state-error-primary)', marginBottom: 10 }}>{error}</div>}\n\n <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 10 }}>\n <button type=\"button\" onClick={props.onCancel} style={secondaryButtonStyle}>\n 取消\n </button>\n <button\n type=\"button\"\n onClick={() => setInstructionDialogOpen(true)}\n disabled={busy || props.busy || !nodeId || !path}\n style={{\n ...secondaryButtonStyle,\n borderColor: pendingInstruction !== undefined && pendingInstruction.trim() ? 'var(--dsw-alias-state-business-primary)' : 'var(--dsw-alias-border-l2)',\n color: pendingInstruction !== undefined && pendingInstruction.trim() ? 'var(--dsw-alias-state-business-primary)' : 'var(--dsw-alias-label-primary)',\n }}\n >\n 指令{pendingInstruction !== undefined && pendingInstruction.trim() ? ' ●' : ''}\n </button>\n <button type=\"button\" onClick={() => void confirm()} disabled={busy || props.busy || !nodeId || !path} style={primaryButtonStyle}>\n 设为工作区\n </button>\n </div>\n </div>\n\n {instructionDialogOpen && (\n <InstructionPreviewDialog\n text={pendingInstruction ?? ''}\n onClose={() => setInstructionDialogOpen(false)}\n onSave={(t) => {\n setPendingInstruction(t)\n setInstructionDialogOpen(false)\n }}\n />\n )}\n </div>\n )\n}\n\nfunction dirnameOf(path: string): string {\n const parts = path.split('/').filter(Boolean)\n parts.pop()\n return parts.length === 0 ? '/' : `/${parts.join('/')}`\n}\n\nconst pendingInstructions = new Map<string, string>()\n\nfunction savePendingInstruction(path: string, text: string): void {\n pendingInstructions.set(path, text)\n void (async () => {\n try {\n let attempts = 0\n const tryResolve = async (): Promise<void> => {\n if (attempts++ > 10) return\n const wks = (window as unknown as { workspaces?: { list?: { getSnapshot?: () => { items?: { workspaceId: string; path: string }[] } } } }).workspaces\n const snap = wks?.list?.getSnapshot?.()\n const items = snap?.items ?? []\n const ws = items.find((w) => w.path === path)\n if (!ws) {\n await new Promise((r) => setTimeout(r, 300))\n return tryResolve()\n }\n await fetch(`/api/dshb/instructions/${ws.workspaceId}`, {\n method: 'PUT',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ text, expectedRevision: 0 }),\n })\n pendingInstructions.delete(path)\n }\n void tryResolve()\n } catch {}\n })()\n}\n\nfunction InstructionPreviewDialog(props: {\n text: string\n onClose: () => void\n onSave: (text: string) => void\n}): ReactElement {\n const [text, setText] = useState(props.text)\n const overlayStyle: CSSProperties = {\n position: 'fixed',\n inset: 0,\n background: 'var(--dsw-alias-overlay-mask, rgba(0,0,0,0.45))',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 1100,\n }\n const dialogStyle: CSSProperties = {\n width: 'min(92vw, 600px)',\n maxWidth: '100%',\n maxHeight: '85vh',\n overflow: 'auto',\n overflowX: 'hidden',\n background: 'var(--dsw-alias-bg-layer-1)',\n border: '1px solid var(--dsw-alias-border-l2)',\n borderRadius: 12,\n padding: 20,\n boxSizing: 'border-box',\n color: 'var(--dsw-alias-label-primary)',\n }\n return (\n <div style={overlayStyle} onClick={props.onClose}>\n <div style={dialogStyle} onClick={(e) => e.stopPropagation()}>\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 14 }}>\n <h2 style={{ margin: 0, fontSize: 16, color: 'var(--dsw-alias-label-primary)' }}>项目指令</h2>\n <button type=\"button\" onClick={props.onClose} style={secondaryButtonStyle}>关闭</button>\n </div>\n <div style={{ fontSize: 12, color: 'var(--dsw-alias-label-secondary)', marginBottom: 10 }}>\n 工作区创建后,此指令将自动保存为新工作区的项目指令。新对话首次交互时注入。\n </div>\n <textarea\n style={{\n width: '100%',\n minHeight: '280px',\n fontFamily: 'monospace',\n fontSize: 13,\n padding: '12px',\n border: '1px solid var(--dsw-alias-border-l2)',\n borderRadius: 8,\n background: 'var(--dsw-alias-bg-layer-2)',\n color: 'var(--dsw-alias-label-primary)',\n resize: 'vertical',\n boxSizing: 'border-box',\n outline: 'none',\n }}\n value={text}\n onChange={(e) => setText(e.target.value)}\n placeholder=\"留空则不注入指令...\"\n spellCheck={false}\n />\n <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 10, marginTop: 14 }}>\n <button type=\"button\" onClick={props.onClose} style={secondaryButtonStyle}>取消</button>\n <button type=\"button\" onClick={() => props.onSave(text)} style={primaryButtonStyle}>确定</button>\n </div>\n </div>\n </div>\n )\n}\n","import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\n\n/**\n * dshb 移动端屏幕适配(参考 dsh-web-mobile 实现,仅保留页面适配与目录抽屉\n * 切换,不含文件浏览 / 导出会话日志等功能按钮)。\n *\n * 机制与上游一致:dsh 客户端在窄屏会自动给 AppFrame 加 data-sidebar-collapsed\n * 折叠侧边栏;这里把侧边栏列(frame 的第一个 grid 子元素)用 CSS 抽屉化\n * (绝对定位 + transform 移出/滑入),并在会话头部注入一个切换按钮调用\n * ctx.layout.toggleSidebar()。窄屏判定与上游一致(<1024 且粗指针,避免桌面\n * 小窗误触发)。\n */\nexport const MOBILE_QUERY = '(max-width: 1023px) and (pointer: coarse)'\n\n/** 纯视口宽度判定:与放宽后的 MOBILE_CSS 媒体查询一致(不依赖 pointer 类型)。 */\nconst NARROW_QUERY = '(max-width: 1023px)'\n\nconst FRAME_ATTR = 'data-dshb-mobile'\nconst COLLAPSED_ATTR = 'data-sidebar-collapsed'\n\nconst MOBILE_CSS = `\n/* 仅按视口宽度判定,不绑定 pointer:coarse —— 触屏笔记本 / DevTools 响应式模式\n 常报 pointer:fine,绑定 coarse 会让全部窄屏修复失效。抽屉相关选择器都挂在\n [data-dshb-mobile] 标记上,标记由 JS 的 coarse 判定添加,故放宽 CSS 不会误开抽屉。 */\n@media (max-width: 1023px) {\n html, body { touch-action: pan-y pinch-zoom !important; overscroll-behavior-x: none !important; -webkit-text-size-adjust: 100% !important; text-size-adjust: 100% !important; }\n\n [${FRAME_ATTR}=\"frame\"] {\n box-sizing: border-box !important;\n position: relative !important;\n grid-template-columns: minmax(0, 1fr) 0 0 !important;\n padding-top: env(safe-area-inset-top, 0px) !important;\n }\n\n /* 侧边栏列 -> 抽屉:默认移出屏幕,展开(无 collapsed)时滑入 */\n [${FRAME_ATTR}=\"frame\"] > :first-child {\n position: absolute !important;\n inset: 0 auto 0 0 !important;\n width: max-content;\n max-width: 92vw;\n z-index: 40 !important;\n transform: translateX(-110%);\n transition: transform .28s ease-in-out;\n background: var(--dsw-alias-bg-base, #ffffff);\n padding-top: env(safe-area-inset-top, 0px) !important;\n border-right: none !important;\n touch-action: pan-y pinch-zoom !important;\n }\n [${FRAME_ATTR}=\"frame\"]:not([${COLLAPSED_ATTR}]) > :first-child { transform: none !important; }\n @media (prefers-reduced-motion: reduce) {\n [${FRAME_ATTR}=\"frame\"] > :first-child { transition: none !important; }\n }\n\n /* 拖拽手柄在触屏上无用 */\n [data-side=\"sidebar\"], [data-side=\"details\"] { display: none !important; }\n\n /* 对话区:去桌面滚动条占位,收窄 gutter,字号降一档 */\n [data-phase] [class*=\"_scrollBody\"] { scrollbar-gutter: auto !important; scrollbar-width: none; }\n [data-phase] [class*=\"_scrollBody\"]::-webkit-scrollbar { display: none !important; width: 0; height: 0; }\n [data-phase] [class*=\"_scroll\"]:not([class*=\"_scrollBody\"]):has(p) { padding-left: 20px; padding-right: 20px; font-size: 15px !important; }\n [data-phase] [class*=\"_scroll\"]:not([class*=\"_scrollBody\"]):has(p) p,\n [data-phase] [class*=\"_scroll\"]:not([class*=\"_scrollBody\"]):has(p) li,\n [data-phase] [class*=\"_scroll\"]:not([class*=\"_scrollBody\"]):has(p) [class*=\"_text_\"] { font-size: 15px !important; }\n [data-phase] table { width: 100%; max-width: 100%; }\n [data-phase] th, [data-phase] td { max-width: none; min-width: 0; }\n [data-phase] [class*=\"_scroll\"]:not([class*=\"_scrollBody\"]) img { width: auto !important; max-width: 100% !important; height: auto !important; max-height: 220px !important; }\n [data-phase] [class*=\"_userStack\"], [data-phase] [class*=\"_userStack\"] [class*=\"_bubble\"] { box-sizing: border-box; width: fit-content; max-width: 100%; }\n [data-phase] [class*=\"_actions\"] { overflow: hidden; }\n\n /* 统计行(turns/steps/LLM/TPS):窄屏横向滚动,指标可滑动看全 */\n [${FRAME_ATTR}=\"stats\"] {\n display: flex !important;\n flex-wrap: nowrap !important;\n align-items: center;\n gap: 6px;\n overflow-x: auto !important;\n max-width: 100% !important;\n scrollbar-width: none;\n -webkit-overflow-scrolling: touch;\n }\n [${FRAME_ATTR}=\"stats\"]::-webkit-scrollbar { display: none; }\n [${FRAME_ATTR}=\"stats\"] > * { flex-shrink: 0 !important; white-space: nowrap !important; }\n [${FRAME_ATTR}=\"stats\"] { gap: 6px !important; }\n [class*=\"composerStack\"] { gap: 4px !important; }\n /* stats line 竖线分隔符(|)两边 margin 10px 太松,适度收紧 */\n [data-phase] [class*=\"_sep\"] { margin: 0 3px !important; }\n\n /* 每轮回复下方的统计文字(footer):收紧 actions 内部 gap 与气泡到 footer 间距,减少松散感 */\n [data-phase] [class*=\"_actions\"] { gap: 4px !important; }\n [data-phase] [class*=\"_actions\"] [class*=\"_timeEnd\"] { gap: 4px !important; padding-left: 6px !important; }\n [data-phase] [class*=\"userRow\"], [data-phase] [class*=\"assistantRow\"] { gap: 4px !important; }\n /* 点号(·)左右 margin 10px 太松,收紧并抵消前后空格 */\n [data-phase] [class*=\"_runTimeDot\"] { margin: 0 -2px !important; }\n /* footer 容器各项间距 16px 偏松 */\n [data-phase] [class*=\"_root\"][class*=\"osXY9a\"] { gap: 8px !important; }\n /* footer 统计行窄屏可横向滑动看全,不溢出页面 */\n [data-phase] [class*=\"_actions\"] { max-width: 100% !important; overflow-x: auto !important; scrollbar-width: none; touch-action: pan-x pan-y !important; }\n [data-phase] [class*=\"_actions\"]::-webkit-scrollbar { display: none; }\n\n /* 模型切换菜单:名称完整展示,长名称在菜单项内换行。 */\n [class*=\"_submenu_\"] [class*=\"_itemLabel_\"] {\n overflow: visible !important;\n text-overflow: clip !important;\n white-space: normal !important;\n overflow-wrap: anywhere;\n }\n\n /* 模型选择器(dsh-client-ui-model-selection,CSS 模块前缀 7KE1Ra_):\n 列表内模型名/描述默认 ellipsis 截断,改换行完整显示。除当前 hash 外,\n 再加 modelName 语义匹配,防止上游升级换 hash 后规则失效。\n 注意:必须用 break-word 而非 anywhere —— anywhere 让文字 min-content\n 宽度≈1 字符,配合全局 * {min-width:0} 会把 flex 行内名字列压到 1 字符宽,\n 出现\"一字符就换行\"。break-word 的 min-content 取最长词宽,只在真正\n 放不下时才断词。 */\n [class*=\"7KE1Ra_modelName\"],\n [class*=\"7KE1Ra_description\"],\n [class*=\"modelName\"] {\n white-space: normal !important;\n overflow-wrap: break-word;\n text-overflow: clip !important;\n overflow: visible !important;\n }\n\n /* 模型选择器弹窗:JS(installModelMenuPosition)在窄屏下改为 position:fixed\n 视口级浮层(fixed 不受祖先 overflow 裁剪),这里仅做静态兜底(JS 未生效时\n 仍从触发按钮左缘向右展开、宽度收进视口)。 */\n [class*=\"7KE1Ra_menu\"],\n [class*=\"_menu\"]:has([class*=\"modelName\"]) {\n left: 0 !important;\n right: auto !important;\n width: calc(100vw - 32px) !important;\n min-width: 0 !important;\n max-width: calc(100vw - 32px) !important;\n overflow-y: auto !important;\n max-height: calc(100vh - 120px) !important;\n }\n\n /* 工具调用执行结果/代码/JSON:窄屏可横向滑动。details 抽屉宽 min(92%,420px)\n 较窄,命令行输出/JSON 长行溢出被外层 overflow:hidden 裁剪看不到。命令行输出\n 改 white-space:pre(保持原格式不折行,像终端)+ overflow-x:auto 横向滑动;\n min-width:0+max-width:100% 约束宽度触发滚动。 */\n [data-phase] [class*=\"resultBlockText\"],\n [data-phase] [class*=\"payload\"]:not([class*=\"errorPayload\"]),\n [data-phase] [class*=\"sourceBlockContent\"] {\n white-space: pre !important;\n min-width: 0 !important;\n max-width: 100% !important;\n overflow-x: auto !important;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n touch-action: pan-x pan-y !important;\n }\n [data-phase] [class*=\"resultBlockText\"]::-webkit-scrollbar,\n [data-phase] [class*=\"payload\"]::-webkit-scrollbar,\n [data-phase] [class*=\"sourceBlockContent\"]::-webkit-scrollbar { display: none !important; }\n\n /* JSON 预览/代码块/promptDiff:横向滑动(不折行,保持格式) */\n [data-phase] [class*=\"jsonPayload\"],\n [data-phase] [class*=\"jsonPreview\"],\n [data-phase] [class*=\"promptDiff\"],\n [data-phase] [class*=\"overviewPreview\"],\n [data-phase] [class*=\"resultBlocks\"],\n [data-phase] pre {\n min-width: 0 !important;\n max-width: 100% !important;\n overflow-x: auto !important;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n touch-action: pan-x pan-y !important;\n }\n [data-phase] [class*=\"jsonPayload\"]::-webkit-scrollbar,\n [data-phase] [class*=\"jsonPreview\"]::-webkit-scrollbar,\n [data-phase] [class*=\"promptDiff\"]::-webkit-scrollbar,\n [data-phase] [class*=\"overviewPreview\"]::-webkit-scrollbar,\n [data-phase] [class*=\"resultBlocks\"]::-webkit-scrollbar,\n [data-phase] pre::-webkit-scrollbar { display: none !important; }\n\n /* dsh-client-ui-tool 工具卡片(Bash 等命令输出,class 前缀 o3BgMG_):\n bodyScroll/ioSection 只有 overflow-y:auto,横向溢出传到 row{overflow:hidden}\n 被裁剪且无法滑动。给输出容器链设 overflow-x:auto(不覆盖上游 overflow-y),\n 让终端格式长行在卡片内横向滑动。 */\n [data-phase] [class*=\"bodyScroll\"],\n [data-phase] [class*=\"ioCard\"],\n [data-phase] [class*=\"ioSection\"],\n [data-phase] [class*=\"terminalBody\"],\n [data-phase] [class*=\"codeBody\"] {\n min-width: 0 !important;\n max-width: 100% !important;\n overflow-x: auto !important;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n touch-action: pan-x pan-y !important;\n }\n /* xterm uses a transparent helper textarea for all terminal input. Keep it\n focusable and non-zero-sized so mobile browsers can present their keyboard. */\n [data-phase] .xterm .xterm-helper-textarea {\n width: 1px !important;\n height: 1px !important;\n opacity: .01 !important;\n z-index: 1 !important;\n }\n [data-phase] [class*=\"bodyScroll\"]::-webkit-scrollbar,\n [data-phase] [class*=\"ioCard\"]::-webkit-scrollbar,\n [data-phase] [class*=\"ioSection\"]::-webkit-scrollbar,\n [data-phase] [class*=\"terminalBody\"]::-webkit-scrollbar,\n [data-phase] [class*=\"codeBody\"]::-webkit-scrollbar { display: none !important; }\n\n /* 终端组件(dsh-web-frontend,CSS 模块前缀 1gdtu_):多行命令上游按行渲染成\n 多个 _promptLine_>_command_ 元素,行级不能各自设 overflow(会变成每行独立\n 滚动)。唯一横向滚动容器是公共祖先 _header_1gdtu_32(本就 overflow-y:auto):\n 行链 _prompt_/_promptLine_/_command_ 全部撑到 max-content 且 overflow 可见,\n 长行内容溢出传入 _header_ 的 scrollWidth,所有行随 _header_ 同步滚动。\n _output_1gdtu_156(输出区)同理以其为唯一容器,_line_ 撑宽不裁剪。 */\n [data-phase] [class*=\"_header_1gdtu_\"] {\n min-width: 0 !important;\n max-width: 100% !important;\n overflow-x: auto !important;\n overscroll-behavior-x: contain;\n touch-action: pan-x pan-y !important;\n }\n [data-phase] [class*=\"_prompt_1gdtu_\"],\n [data-phase] [class*=\"_promptLine_1gdtu_\"],\n [data-phase] [class*=\"_command_1gdtu_\"] {\n min-width: max-content !important;\n max-width: none !important;\n overflow: visible !important;\n /* Android Chrome TextAutosizer 按块宽计算 font boosting,max-content 行宽不一\n 导致各行字号参差;max-height 是其豁免条件,禁用放大并锁定继承字号。 */\n max-height: 999999px !important;\n }\n [data-phase] [class*=\"_command_1gdtu_\"] {\n display: inline-block;\n text-overflow: clip !important;\n white-space: pre !important;\n }\n [data-phase] [class*=\"_copyButton_1gdtu_\"] { position: sticky !important; right: 0; }\n [data-phase] [class*=\"_output_1gdtu_\"] {\n overflow-x: auto !important;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n touch-action: pan-x pan-y !important;\n }\n [data-phase] [class*=\"_output_1gdtu_\"]::-webkit-scrollbar { display: none !important; }\n [data-phase] [class*=\"_line_1gdtu_\"] {\n min-width: max-content !important;\n overflow-x: visible !important;\n max-height: 999999px !important;\n }\n\n /* 复制按钮周边也允许纵向页面手势,避免代码/总结区域形成触控死区。 */\n [data-phase] [class*=\"_copyButton_\"] { touch-action: manipulation !important; }\n [data-phase] [class*=\"_copyAnchor_\"],\n [data-phase] [class*=\"_body_1ye18_\"],\n [data-phase] [class*=\"_root_4qrvp_\"] { touch-action: pan-x pan-y !important; }\n\n /* 上下文用量弹窗(ContextMeter .JObwrW_panel):上游 dsh-client-ui-trajectory 的\n [class*=\"panel\"] 全局规则给它加了 max-width:100%!important,命中本弹窗,使宽度\n 从 264px 塌缩到包含块(.root 28px)宽,内容竖排成竖条。窄屏解除该误伤。 */\n .JObwrW_panel { max-width: none !important; overflow-x: visible !important; }\n\n /* 头部:标题省略,tab 条横向滚动 */\n [${FRAME_ATTR}=\"frame\"] [data-phase] header { padding-left: 44px; padding-right: 8px; }\n [${FRAME_ATTR}=\"frame\"] [data-phase] header [class*=\"_crumbs\"] { flex: 1 1 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap !important; }\n [${FRAME_ATTR}=\"frame\"] [data-phase] header [role=\"tablist\"] { flex-wrap: nowrap; gap: 0 16px; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; }\n [${FRAME_ATTR}=\"frame\"] [data-phase] header [role=\"tablist\"]::-webkit-scrollbar { display: none; }\n [${FRAME_ATTR}=\"frame\"] [data-phase] header [role=\"tablist\"] > button { flex-shrink: 0; white-space: nowrap; }\n\n /* 设置对话框:窄屏近全宽 sheet(排除导出等普通对话框与目录选择器) */\n [aria-modal=\"true\"]:has(> :first-child > :last-child > button):not(:has([role=\"navigation\"])):not(:has([class*=\"ZuhsRW\"])) {\n position: absolute !important;\n left: 8px !important;\n top: calc(env(safe-area-inset-top, 0px) + 12px) !important;\n width: calc(100vw - 16px) !important;\n max-width: calc(100vw - 16px) !important;\n height: auto !important;\n max-height: calc(100dvh - 24px - env(safe-area-inset-top, 0px)) !important;\n flex-direction: column !important;\n border-radius: 14px !important;\n }\n [aria-modal=\"true\"]:not(:has(> :first-child > :last-child > button)) { max-width: calc(100vw - 32px) !important; }\n /* nav:横排换行(避免 CJK 标签竖排楼梯状),隐藏冗余 caption */\n [aria-modal=\"true\"]:has(> :first-child > :last-child > button):not(:has([role=\"navigation\"])):not(:has([class*=\"ZuhsRW\"])) > :first-child {\n width: 100%;\n flex-direction: row !important;\n align-items: center;\n gap: 6px;\n padding: 10px 12px 8px;\n }\n [aria-modal=\"true\"]:has(> :first-child > :last-child > button):not(:has([role=\"navigation\"])):not(:has([class*=\"ZuhsRW\"])) > :first-child > :first-child { display: none !important; }\n [aria-modal=\"true\"] [class*=\"_navList\"] { flex: 1 1 auto; min-width: 0; flex-direction: row !important; flex-wrap: wrap; gap: 6px; overflow: visible; }\n [aria-modal=\"true\"] [class*=\"_navList\"] > button { flex-shrink: 0; white-space: nowrap; }\n /* 外观模式卡片横排 */\n [aria-modal=\"true\"] [class*=\"_cubeRow\"] { gap: 6px; }\n [aria-modal=\"true\"] [class*=\"_cubeRow\"] > * { flex: 1 1 0; flex-direction: row !important; align-items: center; justify-content: center; gap: 6px; padding: 10px 8px; min-height: 0; }\n /* section 填充 sheet 宽度 */\n [aria-modal=\"true\"] [class*=\"_section\"] { width: 100% !important; max-width: none !important; }\n [aria-modal=\"true\"]:has(> :first-child > :last-child > button):not(:has([role=\"navigation\"])):not(:has([class*=\"ZuhsRW\"])) > :last-child { flex: 1 1 auto; min-height: 0; }\n [aria-modal=\"true\"]:has(> :first-child > :last-child > button):not(:has([role=\"navigation\"])):not(:has([class*=\"ZuhsRW\"])) > :last-child > :last-child { padding: 0 12px 24px; }\n\n /* 切换按钮:固定头部左侧 */\n [${FRAME_ATTR}=\"toggle\"] {\n position: absolute !important;\n left: 8px !important;\n top: 12px !important;\n z-index: 2 !important;\n display: inline-flex !important;\n align-items: center; justify-content: center;\n width: 28px; height: 28px;\n padding: 0; border: none; background: none; cursor: pointer; color: inherit;\n -webkit-tap-highlight-color: transparent;\n }\n\n /* 首页/hero(无活跃会话,session header 不存在)的抽屉切换 FAB:\n 浮在顶部相机带下方,避免与 hero 头部内容重叠 */\n [${FRAME_ATTR}=\"fab\"] {\n position: absolute !important;\n top: calc(env(safe-area-inset-top, 0px) + 72px) !important;\n left: 10px !important;\n z-index: 21 !important;\n display: inline-flex !important;\n align-items: center; justify-content: center;\n width: 38px; height: 38px;\n padding: 0;\n border: 1px solid var(--dsw-alias-border-l1, rgba(0, 0, 0, .12)) !important;\n border-radius: 50% !important;\n background: var(--dsw-alias-button-floating-fill, #ffffff) !important;\n color: var(--dsw-alias-label-primary, inherit) !important;\n cursor: pointer !important;\n box-shadow: 0 2px 12px rgba(0, 0, 0, .18) !important;\n -webkit-tap-highlight-color: transparent;\n }\n}\n\n/* 宽屏 / 鼠标指针:隐藏切换按钮 */\n@media (min-width: 1024px), (pointer: fine) {\n [${FRAME_ATTR}=\"toggle\"], [${FRAME_ATTR}=\"fab\"] { display: none !important; }\n}\n`\n\nfunction findFrame(): HTMLElement | null {\n return document.querySelector('[data-shell-overlay]')?.parentElement ?? null\n}\n\nfunction getFrame(): HTMLElement | null {\n return document.querySelector(`[${FRAME_ATTR}=\"frame\"]`) ?? findFrame()\n}\n\n/** viewport-fit=cover:让 safe-area-inset 生效,内容避开刘海/状态栏。 */\nfunction installViewport(ctx: ClientContext): void {\n ctx.effect(() => {\n const narrow = window.matchMedia(MOBILE_QUERY)\n const viewport = document.querySelector<HTMLMetaElement>('meta[name=\"viewport\"]')\n if (viewport === null) return () => {}\n const original = viewport.content\n const sync = (): void => {\n viewport.content = narrow.matches\n ? 'width=device-width, initial-scale=1, viewport-fit=cover'\n : original\n }\n sync()\n narrow.addEventListener('change', sync)\n return () => {\n narrow.removeEventListener('change', sync)\n viewport.content = original\n }\n }, 'dshb-mobile: viewport')\n}\n\nfunction installStyles(ctx: ClientContext): void {\n ctx.effect(() => {\n const tag = document.createElement('style')\n tag.dataset.plugin = 'dshb-mobile'\n tag.textContent = MOBILE_CSS\n document.head.appendChild(tag)\n // 保持在 head 最后,确保覆盖宿主样式\n setTimeout(() => { if (tag.isConnected) document.head.appendChild(tag) }, 0)\n return () => { tag.remove() }\n }, 'dshb-mobile: styles')\n}\n\n/** 给 AppFrame 打标记(drawer CSS 选择器挂载点),窄屏才打。 */\nfunction installFrameMarker(ctx: ClientContext): void {\n ctx.effect(() => {\n const narrow = window.matchMedia(MOBILE_QUERY)\n let frame: HTMLElement | null = null\n const clear = (): void => {\n if (frame !== null) frame.removeAttribute(FRAME_ATTR)\n frame = null\n }\n const ensure = (): void => {\n if (!narrow.matches) return\n frame = findFrame()\n if (frame !== null && !frame.hasAttribute(FRAME_ATTR)) frame.setAttribute(FRAME_ATTR, 'frame')\n }\n ensure()\n const mo = new MutationObserver(ensure)\n mo.observe(document.documentElement, { childList: true, subtree: true })\n const onChange = (): void => { if (narrow.matches) ensure(); else clear() }\n narrow.addEventListener('change', onChange)\n return () => {\n mo.disconnect()\n narrow.removeEventListener('change', onChange)\n clear()\n }\n }, 'dshb-mobile: frame marker')\n}\n\n/**\n * 抽屉打开时覆盖内容区的半透明遮罩,点击关闭;Escape 同样关闭;\n * 点击抽屉内的会话/导航项后关闭抽屉。\n */\nfunction installDrawerInteractions(ctx: ClientContext, toggleSidebar: () => void): void {\n ctx.effect(() => {\n const narrow = window.matchMedia(MOBILE_QUERY)\n let backdrop: HTMLElement | null = null\n const drawerOpen = (): boolean => {\n const frame = getFrame()\n return narrow.matches && frame !== null && !frame.hasAttribute(COLLAPSED_ATTR)\n }\n const sync = (): void => {\n if (drawerOpen() && backdrop === null) {\n backdrop = document.createElement('div')\n backdrop.setAttribute(`${FRAME_ATTR}-backdrop`, '')\n backdrop.style.cssText = 'position:fixed;inset:0;z-index:39;background:rgba(0,0,0,.4);-webkit-tap-highlight-color:transparent;'\n backdrop.addEventListener('click', () => toggleSidebar())\n document.body.appendChild(backdrop)\n } else if (!drawerOpen() && backdrop !== null) {\n backdrop.remove()\n backdrop = null\n }\n }\n const onKeyDown = (event: KeyboardEvent): void => {\n if (event.key !== 'Escape') return\n if (document.querySelector('[aria-modal=\"true\"]') !== null) return\n if (drawerOpen()) toggleSidebar()\n }\n const onClick = (event: MouseEvent): void => {\n if (!drawerOpen()) return\n const target = event.target\n if (!(target instanceof Element)) return\n const drawer = document.querySelector(`[${FRAME_ATTR}=\"frame\"] > :first-child`)\n if (drawer === null || !drawer.contains(target)) return\n if (target.closest('button, a, [role=\"button\"]') !== null) return\n if (target.closest('[class*=\"newSession\"], [class*=\"sessionRow\"], [role=\"treeitem\"], [class*=\"searchResult\"]') !== null) toggleSidebar()\n }\n sync()\n const mo = new MutationObserver(sync)\n mo.observe(document.documentElement, { childList: true, subtree: true, attributes: true, attributeFilter: [COLLAPSED_ATTR] })\n document.addEventListener('keydown', onKeyDown, true)\n document.addEventListener('click', onClick, true)\n narrow.addEventListener('change', sync)\n return () => {\n mo.disconnect()\n document.removeEventListener('keydown', onKeyDown, true)\n document.removeEventListener('click', onClick, true)\n narrow.removeEventListener('change', sync)\n backdrop?.remove()\n }\n }, 'dshb-mobile: drawer interactions')\n}\n\n/** 对话/输入框下方的统计行(turns/steps/LLM/TPS):hashed class 无法直接选,按文本特征标记后由 CSS 横向滚动,避免溢出。 */\nfunction installStatsLine(ctx: ClientContext): void {\n ctx.effect(() => {\n const narrow = window.matchMedia(MOBILE_QUERY)\n // 统计行文本特征(\"3 轮 · 5 步 · LLM 2.1s · 缓存命中 80%\" 等),hashed class 无法直接选,按文本识别。\n // 含\"轮/步/turns/steps\"即可(footer 不含这些),无需额外排除 footer。\n const STATS_LINE_RE = /(\\d+\\s*轮|\\d+\\s*步|\\bturns\\b|\\bsteps\\b)/\n const isStatsText = (el: Element): boolean => {\n const text = (el.textContent ?? '').trim()\n if (text.length === 0 || text.length > 160) return false\n if (!STATS_LINE_RE.test(text)) return false\n if (el.querySelector('textarea, input, button, select, a') !== null) return false\n return true\n }\n const mark = (): void => {\n if (!narrow.matches) return\n // 清除失效标记:行容器仍含统计特征(轮/步)才保留\n document.querySelectorAll(`[${FRAME_ATTR}=\"stats\"]`).forEach((el) => {\n if (!el.isConnected || !STATS_LINE_RE.test((el.textContent ?? '').trim())) el.removeAttribute(FRAME_ATTR)\n })\n // 候选:含统计特征的短文本元素(全文档搜索,含 composer 内的 stats line),取最浅容器标记\n // 排除 display:contents(无 box,overflow 无效,会误占最浅候选)\n const cands = Array.from(document.querySelectorAll('span, div')).filter((el) => {\n if (!isStatsText(el)) return false\n if (getComputedStyle(el).display === 'contents') return false\n return true\n })\n for (const el of cands) {\n if (el.hasAttribute(FRAME_ATTR)) continue\n let anc = el.parentElement\n let hasOuterCand = false\n while (anc) {\n if (cands.includes(anc)) { hasOuterCand = true; break }\n anc = anc.parentElement\n }\n if (!hasOuterCand) {\n // 标最浅含统计的容器本身(整行),使其可横向滚动\n if (!el.hasAttribute(FRAME_ATTR)) el.setAttribute(FRAME_ATTR, 'stats')\n }\n }\n }\n mark()\n const mo = new MutationObserver(() => { if (narrow.matches) mark() })\n mo.observe(document.documentElement, { childList: true, subtree: true })\n narrow.addEventListener('change', mark)\n return () => {\n mo.disconnect()\n narrow.removeEventListener('change', mark)\n }\n }, 'dshb-mobile: stats line')\n}\n\n/** 浮层 fixed 定位需管理的内联样式键,清理时逐一移除以交还上游 CSS。 */\nconst SHEET_PROPS = [\n 'position', 'width', 'left', 'right', 'top', 'bottom',\n 'min-width', 'max-width', 'max-height', 'overflow-y', 'box-sizing',\n] as const\n\n/** Keep the model menu anchored to its trigger while fitting it in the viewport. */\nfunction positionAnchoredMenu(el: HTMLElement, triggerRect: DOMRect, maxWidth: number, maxHeight: number): void {\n const margin = 8\n const vw = window.innerWidth\n const vh = window.innerHeight\n el.style.setProperty('position', 'fixed', 'important')\n el.style.setProperty('box-sizing', 'border-box', 'important')\n el.style.setProperty('left', '0', 'important')\n el.style.setProperty('right', 'auto', 'important')\n el.style.setProperty('top', '0', 'important')\n el.style.setProperty('bottom', 'auto', 'important')\n el.style.setProperty('min-width', '0', 'important')\n el.style.setProperty('max-width', `${Math.max(0, Math.min(maxWidth, vw - margin * 2))}px`, 'important')\n el.style.setProperty('max-height', `${Math.max(0, Math.min(maxHeight, vh - margin * 2))}px`, 'important')\n el.style.setProperty('overflow-y', 'auto', 'important')\n let width = el.offsetWidth\n let height = el.offsetHeight\n const spaceAbove = Math.max(0, triggerRect.top - margin * 2)\n const spaceBelow = Math.max(0, vh - triggerRect.bottom - margin * 2)\n const expandUp = height <= spaceAbove || spaceAbove >= spaceBelow\n const available = expandUp ? spaceAbove : spaceBelow\n if (height > available) {\n el.style.setProperty('max-height', `${Math.max(0, available - margin)}px`, 'important')\n height = el.offsetHeight\n width = el.offsetWidth\n }\n const top = expandUp ? triggerRect.top - margin - height : triggerRect.bottom + margin\n const left = Math.max(margin, Math.min(triggerRect.right - width, vw - width - margin))\n el.style.setProperty('left', `${left}px`, 'important')\n el.style.setProperty('top', `${Math.max(margin, Math.min(top, vh - height - margin))}px`, 'important')\n}\n\n/**\n * 模型名多为纯连字符词(DeepSeek-V4-Flash-Vision-Exp);white-space:normal 下\n * 每个 \"-\" 都是软断点,名字一旦超列宽就在第一个连字符处断行(\"换行太早\")。\n * 把 \"-\" 就地换成不换行连字符 U+2011:放得下就整行显示,真超宽时仍由\n * overflow-wrap:break-word 兜底任意断。只改文本节点 data、不换节点,\n * 避免与 React 文本协调冲突;React 重渲染重置文本后由 MutationObserver\n * 重新应用(幂等:换过之后不再有 \"-\")。\n */\nfunction applyNonBreakingHyphens(menu: HTMLElement): void {\n for (const el of Array.from(menu.querySelectorAll<HTMLElement>('[class*=\"modelName\"]'))) {\n const tn = el.firstChild\n if (tn && tn.nodeType === Node.TEXT_NODE && tn.nodeValue !== null && tn.nodeValue.includes('-')) {\n tn.nodeValue = tn.nodeValue.replace(/-/g, '\\u2011')\n }\n }\n}\n\n/**\n * 模型名\"整行显示、不换行、不截断\":窄屏下把名字列里的所有 .modelName 设为\n * nowrap,并按\"最宽名字 vs 可用列宽\"统一缩小字号(下限 11px,上限 14px),\n * 让最长的名字也恰好放得下——从根上消除\"换行太早\"。只测一次最宽名字\n * (scrollWidth 一次布局读取),缩放结果应用到全部名字,保持同一字号。\n * 调用方按 vw + 名字集合签名缓存,避免每次 DOM 变更都强制作废布局。\n */\nfunction fitModelNameFont(menu: HTMLElement): void {\n const names = Array.from(menu.querySelectorAll<HTMLElement>('[class*=\"modelName\"]'))\n if (names.length === 0) return\n const col = names[0].parentElement\n if (col === null) return\n const colW = col.clientWidth - 4\n if (colW <= 0) return\n const base = 14\n let longest = names[0]\n for (const n of names) {\n if ((n.textContent?.length ?? 0) > (longest.textContent?.length ?? 0)) longest = n\n }\n const prevWs = longest.style.whiteSpace\n longest.style.whiteSpace = 'nowrap'\n longest.style.fontSize = `${base}px`\n const natural = longest.scrollWidth\n longest.style.whiteSpace = prevWs\n longest.style.fontSize = ''\n const fs = natural > colW ? Math.max(11, Math.min(base, Math.round(base * (colW / natural)))) : base\n for (const n of names) {\n n.style.setProperty('white-space', 'nowrap', 'important')\n n.style.setProperty('font-size', `${fs}px`, 'important')\n }\n}\n\n/** 宽屏(窄屏判定不成立)时复位名字列内联样式,交还上游 CSS(nowrap+ellipsis)。 */\nfunction clearModelNameFit(menu: HTMLElement | null | undefined): void {\n if (menu === null || menu === undefined) return\n for (const n of Array.from(menu.querySelectorAll<HTMLElement>('[class*=\"modelName\"]'))) {\n n.style.removeProperty('white-space')\n n.style.removeProperty('font-size')\n }\n}\n\n/** 清除 anchored menu 写入的内联样式,交还上游 CSS。 */\nfunction clearFixedSheet(el: HTMLElement | null | undefined): void {\n if (el === null || el === undefined) return\n for (const key of SHEET_PROPS) el.style.removeProperty(key)\n}\n\n/**\n * 模型选择弹窗(dsh-client-ui-model-selection)是两级 pane 的同一个 `_7KE1Ra_menu`\n * 元素:一级 Model/Effort 单元格列表(cellLabel),点击后切到模型列表(modelName)\n * 或档位列表。上游默认 `position:absolute;right:0` 贴触发按钮右缘,触发按钮在\n * 可横向滚动的 stats 行内时菜单会整体出屏。两级 pane 都必须接管(不能只按\n * modelName 匹配,否则一级 pane 漏掉)。所有视口都把菜单锚定到触发按钮,\n * 在上方/下方可用空间中选择更合适的一侧,避免上游空间不足时把菜单钳到屏幕顶端。\n */\nfunction installModelMenuPosition(ctx: ClientContext): void {\n ctx.effect(() => {\n const narrow = window.matchMedia(NARROW_QUERY)\n // 多 tab 场景可能并存多个模型选择器(各自一个 _menu);只处理可见的,\n // 避免 document.querySelector 命中隐藏 tab 的菜单而漏掉用户正在看的那个。\n const findMenus = (): HTMLElement[] => {\n const byHash = Array.from(document.querySelectorAll<HTMLElement>('[class*=\"7KE1Ra_menu\"]'))\n if (byHash.length > 0) return byHash\n // 上游升级换 hash 后回退:语义类匹配(cellLabel 命中一级 pane,modelName 命中二级)\n return Array.from(document.querySelectorAll<HTMLElement>('[class*=\"_menu\"]')).filter((el) =>\n el.querySelector('[class*=\"cellLabel\"], [class*=\"modelName\"]') !== null,\n )\n }\n const findTrigger = (menu: HTMLElement): HTMLElement | null => {\n if (menu.id) {\n const controlled = Array.from(document.querySelectorAll<HTMLElement>('[aria-controls]')).find(\n (el) => el.getAttribute('aria-controls') === menu.id,\n )\n if (controlled) return controlled\n }\n return document.querySelector<HTMLElement>('[class*=\"7KE1Ra_trigger\"][aria-expanded=\"true\"]')\n }\n let fittedVw = 0\n let fittedSig = -1\n let fittedMenus: HTMLElement[] = []\n let positionedMenus: HTMLElement[] = []\n const sync = (): void => {\n const menus = findMenus()\n let vw = 0\n let sig = 0\n const modelMenus: HTMLElement[] = []\n const visibleMenus: HTMLElement[] = []\n for (const menu of menus) {\n // 0.1.5 renders the menu through createPortal(..., document.body), so\n // parentElement is body rather than the trigger root. Match aria-controls\n // to the portal menu id to find the exact trigger across multiple tabs.\n const trigger = findTrigger(menu)\n if (trigger === null || trigger.getAttribute('aria-expanded') !== 'true') continue\n const rect = menu.getBoundingClientRect()\n // 跳过隐藏 tab / 未打开的菜单(0 尺寸或祖先 display:none)\n if (rect.width === 0 && rect.height === 0) continue\n const triggerRect = trigger.getBoundingClientRect()\n positionAnchoredMenu(menu, triggerRect, Math.min(420, window.innerWidth - 16), 360)\n visibleMenus.push(menu)\n if (menu.querySelector('[class*=\"modelName\"]')) {\n modelMenus.push(menu)\n if (narrow.matches) {\n applyNonBreakingHyphens(menu)\n vw = window.innerWidth\n for (const n of menu.querySelectorAll<HTMLElement>('[class*=\"modelName\"]')) {\n sig += n.textContent?.length ?? 0\n }\n }\n }\n }\n for (const previous of positionedMenus) {\n if (visibleMenus.includes(previous)) continue\n clearFixedSheet(previous)\n clearModelNameFit(previous)\n }\n positionedMenus = visibleMenus\n if (!narrow.matches) {\n for (const menu of modelMenus) clearModelNameFit(menu)\n fittedVw = 0\n fittedSig = -1\n fittedMenus = []\n return\n }\n // 菜单关闭再打开时 React 会重建菜单元素(新元素没有任何内联样式),\n // 所以缓存必须含元素身份:vw / 名字集合 / 菜单实例任一变化都要重测,\n // 否则重开的菜单会漏掉 nowrap+缩字而再次换行。\n const needFit = modelMenus.some((m) => !fittedMenus.includes(m))\n if (vw > 0 && (needFit || vw !== fittedVw || sig !== fittedSig)) {\n for (const menu of modelMenus) fitModelNameFont(menu)\n fittedVw = vw\n fittedSig = sig\n fittedMenus = modelMenus\n }\n }\n sync()\n const mo = new MutationObserver(() => requestAnimationFrame(sync))\n mo.observe(document.documentElement, { childList: true, subtree: true })\n narrow.addEventListener('change', sync)\n window.addEventListener('resize', sync)\n window.addEventListener('scroll', sync, true)\n return () => {\n mo.disconnect()\n narrow.removeEventListener('change', sync)\n window.removeEventListener('resize', sync)\n window.removeEventListener('scroll', sync, true)\n }\n }, 'dshb-mobile: model menu position')\n}\n\n/**\n * 上下文用量弹窗(ContextMeter .JObwrW_panel,dsh-client-ui-conversation)上游是\n * `position:absolute; bottom:calc(100%+8px); right:0` 挂 .JObwrW_root 内。窄屏下\n * 改为 fixed 视口浮层,右缘锚定触发按钮右缘、向上展开(用户已验证该形态正常,勿改)。\n */\nfunction installContextPanelPosition(ctx: ClientContext): void {\n ctx.effect(() => {\n const narrow = window.matchMedia(NARROW_QUERY)\n const sync = (): void => {\n if (!narrow.matches) return\n const panels = document.querySelectorAll<HTMLElement>('[class*=\"JObwrW_panel\"]')\n for (const panel of Array.from(panels)) {\n const root = panel.parentElement\n if (root === null || !root.className.includes('JObwrW_root')) continue\n const rootRect = root.getBoundingClientRect()\n if (rootRect.width === 0 && rootRect.height === 0) continue\n const gap = 8\n panel.style.setProperty('position', 'fixed', 'important')\n panel.style.setProperty('top', 'auto', 'important')\n panel.style.setProperty('bottom', `${window.innerHeight - rootRect.top + gap}px`, 'important')\n panel.style.setProperty('left', 'auto', 'important')\n panel.style.setProperty('right', `${Math.max(gap, window.innerWidth - rootRect.right)}px`, 'important')\n panel.style.setProperty('max-height', `${Math.max(160, rootRect.top - gap * 2)}px`, 'important')\n panel.style.setProperty('overflow-y', 'auto', 'important')\n }\n }\n sync()\n const mo = new MutationObserver(() => requestAnimationFrame(sync))\n mo.observe(document.documentElement, { childList: true, subtree: true })\n narrow.addEventListener('change', sync)\n window.addEventListener('resize', sync)\n window.addEventListener('scroll', sync, true)\n return () => {\n mo.disconnect()\n narrow.removeEventListener('change', sync)\n window.removeEventListener('resize', sync)\n window.removeEventListener('scroll', sync, true)\n }\n }, 'dshb-mobile: context panel position')\n}\n\nfunction installMobileTerminalInputFocus(ctx: ClientContext): void {\n ctx.effect(() => {\n const mobile = window.matchMedia(MOBILE_QUERY)\n const focusInput = (event: PointerEvent): void => {\n if (!mobile.matches || !(event.target instanceof Element)) return\n const terminal = event.target.closest('.xterm')\n const textarea = terminal?.querySelector<HTMLTextAreaElement>('.xterm-helper-textarea')\n if (!textarea || textarea.readOnly) return\n textarea.inputMode = 'text'\n textarea.focus({ preventScroll: true })\n try {\n const virtualKeyboard = (navigator as Navigator & { virtualKeyboard?: { show?: () => void } }).virtualKeyboard\n virtualKeyboard?.show?.()\n } catch {\n // The focus event still opens the keyboard on browsers without VirtualKeyboard API.\n }\n }\n document.addEventListener('pointerdown', focusInput, true)\n return () => document.removeEventListener('pointerdown', focusInput, true)\n }, 'dshb-mobile: terminal input focus')\n}\n\ninterface LayoutLike { toggleSidebar(): void }\ninterface SlotsLike {\n inject(name: string, fn: () => unknown): unknown\n register(spec: Record<string, unknown>, component: unknown): unknown\n}\n\n/** 目录抽屉切换按钮(仅切换,不含文件浏览/日志导出等功能按钮)。 */\nfunction DrawerToggle({ toggleSidebar }: { toggleSidebar: () => void }) {\n return (\n <button type=\"button\" data-dshb-mobile=\"toggle\" aria-label=\"打开目录\" title=\"打开目录\" onClick={() => toggleSidebar()}>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"1.5\" y=\"2.5\" width=\"13\" height=\"11\" rx=\"2\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M6 2.5v11\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n </svg>\n </button>\n )\n}\n\nconst PANEL_ICON_SVG =\n '<svg width=\"18\" height=\"18\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">' +\n '<rect x=\"1.5\" y=\"2.5\" width=\"13\" height=\"11\" rx=\"2\" stroke=\"currentColor\" strokeWidth=\"1.5\"/>' +\n '<path d=\"M6 2.5v11\" stroke=\"currentColor\" strokeWidth=\"1.5\"/>' +\n '</svg>'\n\n/**\n * 首页 / hero(无活跃会话)没有 session header,header 上的切换按钮不渲染;\n * 这里在 frame 上注入一个浮动切换按钮(FAB),仅 hero 且抽屉收起时显示。\n */\nfunction installFab(ctx: ClientContext, toggleSidebar: () => void): void {\n ctx.effect(() => {\n const narrow = window.matchMedia(MOBILE_QUERY)\n const FAB_ATTR = 'fab'\n const heroPhase = (): boolean => document.querySelector('[data-phase=\"active\"]') === null\n const drawerOpen = (): boolean => {\n const frame = getFrame()\n return frame !== null && !frame.hasAttribute(COLLAPSED_ATTR)\n }\n let fab: HTMLButtonElement | null = null\n const sync = (): void => {\n if (!narrow.matches || !heroPhase() || drawerOpen()) {\n if (fab !== null) {\n fab.remove()\n fab = null\n }\n return\n }\n const frame = getFrame()\n if (frame === null) return\n if (fab !== null && fab.parentElement === frame) return\n fab?.remove()\n fab = document.createElement('button')\n fab.type = 'button'\n fab.setAttribute(FRAME_ATTR, FAB_ATTR)\n fab.setAttribute('aria-label', '打开目录')\n fab.setAttribute('title', '打开目录')\n fab.innerHTML = PANEL_ICON_SVG\n fab.addEventListener('click', toggleSidebar)\n frame.appendChild(fab)\n }\n sync()\n const mo = new MutationObserver(sync)\n mo.observe(document.documentElement, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['data-phase', 'data-sidebar-collapsed', 'class'],\n })\n narrow.addEventListener('change', sync)\n return () => {\n mo.disconnect()\n narrow.removeEventListener('change', sync)\n fab?.remove()\n }\n }, 'dshb-mobile: hero fab')\n}\n\n/** 安装移动端适配:样式 + viewport + 抽屉标记 + 抽屉交互 + 切换按钮。 */\nexport function installMobile(ctx: ClientContext): void {\n installStyles(ctx)\n installMobileTerminalInputFocus(ctx)\n installViewport(ctx)\n installFrameMarker(ctx)\n installStatsLine(ctx)\n installModelMenuPosition(ctx)\n installContextPanelPosition(ctx)\n const layout = (ctx as unknown as { layout?: LayoutLike }).layout\n const slots = (ctx as unknown as { slots?: SlotsLike }).slots\n if (layout && typeof layout.toggleSidebar === 'function') {\n const toggleSidebar = (): void => layout.toggleSidebar()\n installDrawerInteractions(ctx, toggleSidebar)\n installFab(ctx, toggleSidebar)\n }\n if (slots && layout) {\n slots.inject('conversation.session.header.actions', () =>\n slots.register(\n {\n name: 'conversation.session.header.actions',\n id: 'dshb-mobile-toggle',\n order: 10,\n inject: () => ({ toggleSidebar: () => layout.toggleSidebar() }),\n },\n DrawerToggle,\n ),\n )\n }\n}\n","import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\n\ninterface WorkspaceItem {\n workspaceId: string\n title: string\n path: string\n}\n\ninterface WorkspaceSnapshotLike {\n items: readonly WorkspaceItem[]\n}\n\ninterface WorkspacesLike {\n list: {\n getSnapshot(): WorkspaceSnapshotLike\n subscribe(listener: () => void): () => void\n }\n}\n\nlet injectedRegistry: WorkspacesLike | undefined\n\nexport function setWorkspaceRegistry(reg: WorkspacesLike): void {\n injectedRegistry = reg\n}\n\nfunction resolveWorkspaceByTitle(title: string): WorkspaceItem | undefined {\n const wks = injectedRegistry\n if (!wks) return undefined\n const items = wks.list.getSnapshot().items\n return items.find((w) => w.title === title)\n}\n\nconst ROW_INJECT_FLAG = 'data-dshb-instr-row-bound'\nconst MENU_INJECT_FLAG = 'data-dshb-instr-menu-bound'\nconst MENU_ITEM_FLAG = 'data-dshb-instr-menu-item'\n\nfunction mountInstructionDialog(workspaceId: string, workspaceTitle: string): void {\n if (!workspaceId) return\n\n const overlay = document.createElement('div')\n overlay.style.cssText = 'position:fixed;inset:0;z-index:1100;display:flex;align-items:center;justify-content:center;background:var(--dsw-alias-overlay-mask,rgba(0,0,0,.45))'\n\n const dialog = document.createElement('div')\n dialog.setAttribute('role', 'dialog')\n dialog.setAttribute('aria-label', `修改 ${workspaceTitle} 的项目指令`)\n dialog.style.cssText = 'box-sizing:border-box;width:min(92vw,600px);max-height:85vh;overflow:auto;padding:20px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary)'\n\n const title = document.createElement('h2')\n title.textContent = `项目指令 - ${workspaceTitle}`\n title.style.cssText = 'margin:0 0 10px;font-size:16px'\n\n const description = document.createElement('div')\n description.textContent = '此内容会注入该工作区的新对话。已有对话继续使用创建时的指令快照。'\n description.style.cssText = 'margin-bottom:10px;font-size:12px;color:var(--dsw-alias-label-secondary)'\n\n const textarea = document.createElement('textarea')\n textarea.placeholder = '留空则不注入指令...'\n textarea.spellcheck = false\n textarea.style.cssText = 'box-sizing:border-box;width:100%;min-height:280px;resize:vertical;padding:12px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;outline:none;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font:13px monospace'\n\n const status = document.createElement('div')\n status.style.cssText = 'min-height:18px;margin-top:6px;font-size:12px;color:var(--dsw-alias-label-secondary)'\n\n const actions = document.createElement('div')\n actions.style.cssText = 'display:flex;justify-content:flex-end;gap:10px;margin-top:14px'\n const cancel = document.createElement('button')\n cancel.type = 'button'\n cancel.textContent = '取消'\n cancel.style.cssText = 'height:36px;padding:0 16px;border:1px solid var(--dsw-alias-border-l2);border-radius:18px;background:transparent;color:var(--dsw-alias-label-primary);cursor:pointer'\n const save = document.createElement('button')\n save.type = 'button'\n save.textContent = '保存'\n save.style.cssText = 'height:36px;padding:0 16px;border:0;border-radius:18px;background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground);cursor:pointer'\n\n const close = (): void => overlay.remove()\n cancel.addEventListener('click', close)\n overlay.addEventListener('click', (event) => {\n if (event.target === overlay) close()\n })\n dialog.addEventListener('click', (event) => event.stopPropagation())\n textarea.addEventListener('input', () => {\n const bytes = new TextEncoder().encode(textarea.value).length\n status.textContent = `${bytes} / 32768 字节`\n status.style.color = bytes > 32768 ? 'var(--dsw-alias-state-error-primary)' : 'var(--dsw-alias-label-secondary)'\n })\n save.addEventListener('click', () => {\n void (async () => {\n const bytes = new TextEncoder().encode(textarea.value).length\n if (bytes > 32768) {\n status.textContent = `指令超过 32768 字节限制(当前 ${bytes} 字节)`\n status.style.color = 'var(--dsw-alias-state-error-primary)'\n return\n }\n save.disabled = true\n save.textContent = '保存中...'\n try {\n const revision = Number(overlay.dataset.revision ?? '0')\n const response = await fetch(`/api/dshb/instructions/${workspaceId}`, {\n method: 'PUT',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ text: textarea.value, expectedRevision: revision }),\n })\n if (!response.ok) {\n const body = await response.json().catch(() => ({})) as { error?: string }\n status.textContent = body.error ?? `保存失败 (${response.status})`\n status.style.color = 'var(--dsw-alias-state-error-primary)'\n return\n }\n close()\n } catch {\n status.textContent = '保存失败'\n status.style.color = 'var(--dsw-alias-state-error-primary)'\n } finally {\n save.disabled = false\n save.textContent = '保存'\n }\n })()\n })\n\n actions.append(cancel, save)\n dialog.append(title, description, textarea, status, actions)\n overlay.append(dialog)\n document.body.append(overlay)\n\n status.textContent = '加载中...'\n void fetch(`/api/dshb/instructions/${workspaceId}`)\n .then(async (response) => {\n if (!response.ok) throw new Error(`读取失败 (${response.status})`)\n return response.json() as Promise<{ text?: string; revision?: number }>\n })\n .then((body) => {\n textarea.value = body.text ?? ''\n overlay.dataset.revision = String(body.revision ?? 0)\n textarea.dispatchEvent(new Event('input'))\n textarea.focus()\n })\n .catch((error: unknown) => {\n status.textContent = error instanceof Error ? error.message : '读取失败'\n status.style.color = 'var(--dsw-alias-state-error-primary)'\n })\n}\n\nexport function registerWorkspaceInstructionMenu(ctx: ClientContext): void {\n const wks = (ctx as unknown as { workspaces?: WorkspacesLike }).workspaces\n if (wks) setWorkspaceRegistry(wks)\n\n let activeWorkspaceTitle = ''\n\n const findWorkspaceRow = (el: Node | null): HTMLElement | null => {\n let node = el instanceof HTMLElement ? el : null\n while (node) {\n if (node.className && typeof node.className === 'string' && node.className.includes('projectRow')) {\n return node\n }\n node = node.parentElement\n }\n return null\n }\n\n const getRowTitle = (row: HTMLElement): string | null => {\n const titleEl = row.querySelector('[class*=\"title\"]')\n if (!titleEl) return null\n return titleEl.textContent ?? null\n }\n\n const injectMenuItem = (menuContainer: HTMLElement): void => {\n if (menuContainer.getAttribute(MENU_INJECT_FLAG) || menuContainer.querySelector(`[${MENU_ITEM_FLAG}]`)) return\n menuContainer.setAttribute(MENU_INJECT_FLAG, '1')\n\n const existingItems = menuContainer.querySelectorAll('button, [role=\"menuitem\"]')\n let refItem: Element | null = null\n for (const item of Array.from(existingItems)) {\n const text = item.textContent ?? ''\n if (text.includes('重命名') || text.includes('Rename')) {\n refItem = item\n break\n }\n }\n if (!refItem) refItem = existingItems[existingItems.length - 1]\n if (!refItem) return\n\n const btn = document.createElement('button')\n btn.type = 'button'\n btn.setAttribute('role', 'menuitem')\n btn.setAttribute(MENU_ITEM_FLAG, '1')\n if (refItem instanceof HTMLElement) {\n btn.className = refItem.className || ''\n btn.style.cssText = refItem.style.cssText\n }\n for (const className of Array.from(btn.classList)) {\n if (/danger|delete/i.test(className)) btn.classList.remove(className)\n }\n btn.style.color = 'var(--dsw-alias-label-primary)'\n btn.style.display = 'flex'\n btn.style.alignItems = 'center'\n btn.style.gap = '8px'\n\n const icon = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n icon.setAttribute('width', '16')\n icon.setAttribute('height', '16')\n icon.setAttribute('viewBox', '0 0 16 16')\n icon.setAttribute('fill', 'none')\n icon.setAttribute('aria-hidden', 'true')\n icon.style.flex = 'none'\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n path.setAttribute('d', 'M3 11.75V13h1.25l7.37-7.37-1.25-1.25L3 11.75Zm9.59-7.34a.66.66 0 0 0 0-.94l-1.06-1.06a.66.66 0 0 0-.94 0l-.83.83 1.25 1.25.83-.83.75.75Z')\n path.setAttribute('fill', 'currentColor')\n icon.append(path)\n const label = document.createElement('span')\n label.textContent = '修改指令'\n btn.append(icon, label)\n btn.addEventListener('click', (e) => {\n e.stopPropagation()\n e.preventDefault()\n const ws = activeWorkspaceTitle ? resolveWorkspaceByTitle(activeWorkspaceTitle) : undefined\n mountInstructionDialog(ws?.workspaceId ?? '', activeWorkspaceTitle || 'Unknown')\n })\n\n refItem.parentElement?.insertBefore(btn, refItem.nextSibling)\n }\n\n const observer = new MutationObserver(() => {\n const projectRows = document.querySelectorAll('[class*=\"projectRow\"]')\n for (const row of Array.from(projectRows)) {\n const rowEl = row as HTMLElement\n if (rowEl.getAttribute(ROW_INJECT_FLAG)) continue\n rowEl.setAttribute(ROW_INJECT_FLAG, '1')\n const iconBtns = rowEl.querySelectorAll('button[class*=\"iconButton\"]')\n for (const btn of Array.from(iconBtns)) {\n const label = btn.getAttribute('aria-label') ?? ''\n if (label.includes('workspace') || label.includes('操作') || label.includes('actions')) {\n btn.addEventListener('click', () => {\n const title = getRowTitle(rowEl)\n if (title) activeWorkspaceTitle = title\n })\n }\n }\n }\n\n const menuItems = document.querySelectorAll('[role=\"menuitem\"]')\n for (const item of Array.from(menuItems)) {\n const text = item.textContent ?? ''\n if (text.includes('删除') || text.includes('Delete') || text.includes('重命名') || text.includes('Rename')) {\n const container = item.closest('[role=\"menu\"]') ?? item.parentElement\n if (container instanceof HTMLElement && !container.getAttribute(MENU_INJECT_FLAG)) {\n const row = findWorkspaceRow(container)\n if (row) {\n const title = getRowTitle(row)\n if (title) activeWorkspaceTitle = title\n }\n injectMenuItem(container)\n }\n }\n }\n })\n observer.observe(document.body, { childList: true, subtree: true })\n}\n","import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-workspace/client'\nimport type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { CSSProperties, ReactElement } from 'react'\nimport { useCallback, useEffect, useState } from 'react'\nimport { DirectoryFlowOccupant } from './directory-flow.js'\nimport { installMobile } from './mobile.js'\nimport { registerWorkspaceInstructionMenu } from './workspace-instruction-menu.js'\n\nexport const inject = ['connection', 'workspaces', 'slots', 'layout', 'conversation']\n\nconst SECTION_ID = 'dshb-nodes'\n\ninterface NodeProfileView {\n id: string\n name: string\n type: 'local-host' | 'local-docker' | 'remote-ssh' | 'remote-docker'\n ssh?: {\n host: string\n port: number\n username: string\n auth: { kind: 'password' | 'key' | 'agent'; keyPath?: string }\n }\n docker?: {\n image?: string\n containerId?: string\n mode?: string\n resources?: { cpus?: number; memoryMB?: number }\n }\n hasSecret: { hasPassword: boolean; hasKey: boolean; hasPassphrase: boolean }\n status?: { reachable?: boolean; lastCheckedAt?: string; error?: string }\n provision?: { state: 'provisioning' | 'ready' | 'failed'; error?: string; containerId?: string; updatedAt: string }\n}\n\ninterface SshConfigEntryView {\n host: string\n port: number\n username: string\n identityFile?: string\n hasIdentityFile: boolean\n hasProxyJump: boolean\n}\n\ninterface FormState {\n name: string\n type: 'local-host' | 'local-docker' | 'remote-ssh' | 'remote-docker'\n host: string\n port: string\n username: string\n authKind: 'password' | 'key' | 'agent'\n password: string\n privateKey: string\n passphrase: string\n keyPath: string\n dockerImage: string\n dockerCpus: string\n dockerMemory: string\n}\n\nconst EMPTY_FORM: FormState = {\n name: '',\n type: 'remote-ssh',\n host: '',\n port: '22',\n username: '',\n authKind: 'password',\n password: '',\n privateKey: '',\n passphrase: '',\n keyPath: '',\n dockerImage: '',\n dockerCpus: '',\n dockerMemory: '',\n}\n\ntype Notice = { kind: 'ok' | 'error'; text: string } | undefined\n\nconst inputStyle: CSSProperties = {\n width: '100%',\n boxSizing: 'border-box',\n padding: '0 10px',\n height: 32,\n border: '1px solid var(--dsw-alias-border-l2)',\n borderRadius: 8,\n fontSize: 14,\n fontFamily: 'inherit',\n background: 'var(--dsw-alias-bg-layer-1)',\n color: 'var(--dsw-alias-label-primary)',\n outline: 'none',\n}\nconst buttonStyle: CSSProperties = {\n boxSizing: 'border-box',\n height: 36,\n padding: '0 14px',\n borderRadius: 18,\n fontSize: 14,\n lineHeight: '22px',\n fontFamily: 'inherit',\n cursor: 'pointer',\n border: 'none',\n display: 'inline-flex',\n justifyContent: 'center',\n alignItems: 'center',\n gap: 4,\n}\nconst primaryButtonStyle: CSSProperties = {\n ...buttonStyle,\n background: 'var(--dsw-alias-button-primary-fill)',\n color: 'var(--dsw-alias-label-primary-foreground)',\n}\nconst secondaryButtonStyle: CSSProperties = {\n ...buttonStyle,\n border: '1px solid var(--dsw-alias-border-l2)',\n color: 'var(--dsw-alias-label-primary)',\n background: 'transparent',\n}\nconst dangerOutlineButtonStyle: CSSProperties = {\n ...buttonStyle,\n border: '1px solid var(--dsw-alias-state-error-primary)',\n color: 'var(--dsw-alias-state-error-primary)',\n background: 'transparent',\n}\n\nfunction useNodes(reloadKey: number): NodeProfileView[] {\n const [nodes, setNodes] = useState<NodeProfileView[]>([])\n useEffect(() => {\n let cancelled = false\n void (async () => {\n try {\n const res = await fetch('/api/dshb/nodes')\n if (!res.ok) return\n const data = (await res.json()) as { nodes?: NodeProfileView[] }\n if (!cancelled) setNodes(data.nodes ?? [])\n } catch {}\n })()\n return () => {\n cancelled = true\n }\n }, [reloadKey])\n return nodes\n}\n\nexport function NodeSection(_props: PropsRuntime<'settings.section'>): ReactElement {\n const [reloadKey, setReloadKey] = useState(0)\n const nodes = useNodes(reloadKey)\n const [selectedId, setSelectedId] = useState<string | 'new'>('new')\n const [form, setForm] = useState<FormState>(EMPTY_FORM)\n const [notice, setNotice] = useState<Notice>(undefined)\n const [busy, setBusy] = useState(false)\n const [testing, setTesting] = useState(false)\n const [testResult, setTestResult] = useState<string | undefined>(undefined)\n const [sshConfigEntries, setSshConfigEntries] = useState<SshConfigEntryView[]>([])\n const [dockerBusy, setDockerBusy] = useState(false)\n\n const flash = useCallback((n: Notice) => {\n setNotice(n)\n if (n) setTimeout(() => setNotice(undefined), 6000)\n }, [])\n\n const reload = useCallback(() => setReloadKey((k) => k + 1), [])\n\n useEffect(() => {\n void (async () => {\n try {\n const res = await fetch('/api/dshb/ssh-config')\n if (!res.ok) return\n const data = (await res.json()) as { entries?: SshConfigEntryView[] }\n setSshConfigEntries(data.entries ?? [])\n } catch {}\n })()\n }, [])\n\n const selectNode = useCallback(\n (id: string | 'new') => {\n setSelectedId(id)\n setTestResult(undefined)\n setTesting(false)\n setDockerBusy(false)\n if (id === 'new') {\n setForm(EMPTY_FORM)\n return\n }\n const node = nodes.find((n) => n.id === id)\n if (!node) return\n setForm({\n name: node.name,\n type: node.type,\n host: node.ssh?.host ?? '',\n port: String(node.ssh?.port ?? 22),\n username: node.ssh?.username ?? '',\n authKind: node.ssh?.auth.kind ?? 'password',\n password: '',\n privateKey: '',\n passphrase: '',\n keyPath: node.ssh?.auth.keyPath ?? '',\n dockerImage: node.docker?.image ?? '',\n dockerCpus: node.docker?.resources?.cpus != null ? String(node.docker?.resources?.cpus) : '',\n dockerMemory: node.docker?.resources?.memoryMB != null ? String(node.docker?.resources?.memoryMB) : '',\n })\n },\n [nodes],\n )\n\n const importSshConfig = useCallback((entry: SshConfigEntryView) => {\n setForm((f) => ({\n ...f,\n type: 'remote-ssh',\n host: entry.host,\n port: String(entry.port),\n username: entry.username,\n authKind: entry.hasIdentityFile ? 'key' : f.authKind,\n keyPath: entry.identityFile ?? f.keyPath,\n name: f.name || entry.host,\n }))\n setTestResult(undefined)\n flash({ kind: 'ok', text: `已从 ~/.ssh/config 导入 ${entry.host}` })\n }, [flash])\n\n const save = useCallback(async () => {\n if (!form.name.trim()) {\n flash({ kind: 'error', text: '请填写节点名称' })\n return\n }\n setBusy(true)\n try {\n const isRemote = form.type === 'remote-ssh' || form.type === 'remote-docker'\n const isDocker = form.type === 'local-docker' || form.type === 'remote-docker'\n const payload: Record<string, unknown> = {\n name: form.name.trim(),\n type: form.type,\n ssh: isRemote\n ? {\n host: form.host.trim(),\n port: Number(form.port) || 22,\n username: form.username.trim(),\n auth: { kind: form.authKind, ...(form.keyPath.trim() ? { keyPath: form.keyPath.trim() } : {}) },\n }\n : undefined,\n secrets: isRemote\n ? {\n ...(form.password ? { password: form.password } : {}),\n ...(form.privateKey ? { privateKey: form.privateKey } : {}),\n ...(form.passphrase ? { passphrase: form.passphrase } : {}),\n }\n : undefined,\n docker: isDocker\n ? {\n mode: 'managed' as const,\n ...(form.dockerImage.trim() ? { image: form.dockerImage.trim() } : {}),\n ...(form.dockerCpus ? { resources: { cpus: Number(form.dockerCpus) || undefined } } : {}),\n ...(form.dockerMemory ? { resources: { memoryMB: Number(form.dockerMemory) || undefined } } : {}),\n ...(form.dockerCpus && form.dockerMemory ? { resources: { cpus: Number(form.dockerCpus) || undefined, memoryMB: Number(form.dockerMemory) || undefined } } : {}),\n }\n : undefined,\n }\n const url = selectedId === 'new' ? '/api/dshb/nodes' : `/api/dshb/nodes/${selectedId}`\n const res = await fetch(url, {\n method: selectedId === 'new' ? 'POST' : 'PATCH',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n const data = (await res.json()) as { ok?: boolean; error?: string; node?: NodeProfileView }\n if (res.ok && data.ok) {\n flash({ kind: 'ok', text: selectedId === 'new' ? '节点已创建' : '节点已保存' })\n reload()\n if (data.node) setSelectedId(data.node.id)\n } else {\n flash({ kind: 'error', text: data.error ?? '保存失败' })\n }\n } catch {\n flash({ kind: 'error', text: '网络错误' })\n } finally {\n setBusy(false)\n }\n }, [form, selectedId, flash, reload])\n\n const remove = useCallback(async () => {\n if (selectedId === 'new') return\n setBusy(true)\n try {\n const res = await fetch(`/api/dshb/nodes/${selectedId}`, { method: 'DELETE' })\n const data = (await res.json()) as { ok?: boolean; error?: string }\n if (res.ok && data.ok) {\n flash({ kind: 'ok', text: '节点已删除' })\n setSelectedId('new')\n setForm(EMPTY_FORM)\n reload()\n } else {\n flash({ kind: 'error', text: data.error ?? '删除失败' })\n }\n } catch {\n flash({ kind: 'error', text: '删除失败' })\n } finally {\n setBusy(false)\n }\n }, [selectedId, flash, reload])\n\n const test = useCallback(async () => {\n if (form.type === 'local-host') {\n flash({ kind: 'error', text: '本地节点无需测试连接' })\n return\n }\n const isRemote = form.type === 'remote-ssh' || form.type === 'remote-docker'\n if (isRemote && !form.host.trim()) {\n flash({ kind: 'error', text: '请填写主机地址' })\n return\n }\n setTesting(true)\n setTestResult(undefined)\n try {\n const payload = isRemote ? {\n ssh: {\n host: form.host.trim(),\n port: Number(form.port) || 22,\n username: form.username.trim(),\n auth: { kind: form.authKind, ...(form.keyPath.trim() ? { keyPath: form.keyPath.trim() } : {}) },\n },\n secrets: {\n ...(form.password ? { password: form.password } : {}),\n ...(form.privateKey ? { privateKey: form.privateKey } : {}),\n ...(form.passphrase ? { passphrase: form.passphrase } : {}),\n },\n } : {}\n const url = selectedId === 'new' ? '/api/dshb/nodes/test-unsaved' : `/api/dshb/nodes/${selectedId}/test`\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n const data = (await res.json()) as { ok?: boolean; report?: { ok?: boolean; reachable?: boolean; error?: string; category?: string } }\n const r = data.report\n if (r?.ok && r.reachable) {\n setTestResult('连接成功')\n } else {\n const cat = r?.category ? `(${r.category})` : ''\n setTestResult(`${r?.error ?? '连接失败'}${cat}`)\n }\n reload()\n } catch {\n setTestResult('网络错误')\n } finally {\n setTesting(false)\n }\n }, [form, selectedId, reload])\n\n const dockerAction = useCallback(async (action: 'restart' | 'stop' | 'start' | 'provision') => {\n if (selectedId === 'new') return\n if (action === 'provision') {\n setDockerBusy(true)\n try {\n const res = await fetch(`/api/dshb/docker/${selectedId}/provision`, { method: 'POST' })\n const data = (await res.json()) as { ok?: boolean; error?: string; containerId?: string }\n if (res.ok && data.ok) {\n flash({ kind: 'ok', text: `容器已就绪:${data.containerId?.slice(0, 12) ?? ''}` })\n } else {\n flash({ kind: 'error', text: data.error ?? '拉起失败' })\n }\n reload()\n } catch {\n flash({ kind: 'error', text: '网络错误' })\n } finally {\n setDockerBusy(false)\n }\n return\n }\n setDockerBusy(true)\n try {\n const res = await fetch(`/api/dshb/docker/${selectedId}/${action}`, { method: 'POST' })\n const data = (await res.json()) as { ok?: boolean; error?: string }\n if (res.ok && data.ok) {\n flash({ kind: 'ok', text: action === 'restart' ? '容器已重启' : action === 'stop' ? '容器已停止' : '容器已启动' })\n } else {\n flash({ kind: 'error', text: data.error ?? '操作失败' })\n }\n reload()\n } catch {\n flash({ kind: 'error', text: '网络错误' })\n } finally {\n setDockerBusy(false)\n }\n }, [selectedId, flash, reload])\n\n const selectedNode = selectedId === 'new' ? undefined : nodes.find((n) => n.id === selectedId)\n\n return (\n <>\n <style>{`\n @media (max-width:767px){\n .dshb-node-section{flex-direction:column!important}\n .dshb-node-section>div:first-child{width:100%!important;border-right:none!important;border-bottom:1px solid var(--dsw-alias-border-l2);padding-right:0!important;padding-bottom:12px;margin-bottom:12px}\n .dshb-node-section>div:last-child{max-width:100%!important}\n .dshb-form-row{flex-direction:column!important;gap:8px!important}\n .dshb-form-row>label{width:100%!important;flex:none!important}\n }\n `}</style>\n <div className=\"dshb-node-section\" style={{ display: 'flex', gap: 20, minHeight: 320, overflow: 'hidden', maxWidth: '100%', width: '100%', boxSizing: 'border-box' }}>\n <div style={{ width: 200, flexShrink: 0, borderRight: '1px solid var(--dsw-alias-border-l2)', paddingRight: 16 }}>\n <button type=\"button\" onClick={() => selectNode('new')} style={{ ...primaryButtonStyle, width: '100%', marginBottom: 10 }}>\n 新建节点\n </button>\n {nodes.map((n) => (\n <div\n key={n.id}\n onClick={() => selectNode(n.id)}\n style={{\n padding: '8px 10px',\n borderRadius: 6,\n cursor: 'pointer',\n marginBottom: 4,\n background: selectedId === n.id ? 'var(--dsw-alias-interactive-bg-active, var(--dsw-alias-interactive-bg-hover))' : 'transparent',\n fontSize: 13,\n }}\n >\n <div style={{ fontWeight: 500 }}>{n.name}</div>\n <div style={{ fontSize: 11, opacity: 0.7, display: 'flex', alignItems: 'center', gap: 4 }}>\n <span\n style={{\n width: 6,\n height: 6,\n borderRadius: '50%',\n background: n.status?.reachable === true ? 'var(--dsw-alias-state-success-primary)' : n.status?.reachable === false ? 'var(--dsw-alias-state-error-primary)' : 'var(--dsw-alias-label-dimmed)',\n }}\n />\n {n.type === 'local-host' ? '默认环境(本地)' : n.type === 'remote-ssh' ? '远程 SSH' : n.type === 'local-docker' ? '本地 Docker' : n.type === 'remote-docker' ? '远程 Docker' : n.type}\n <span style={{ marginLeft: 4, color: n.status?.reachable === true ? 'var(--dsw-alias-state-success-primary)' : n.status?.reachable === false ? 'var(--dsw-alias-state-error-primary)' : 'var(--dsw-alias-label-dimmed)' }}>\n {n.status?.reachable === true ? '在线' : n.status?.reachable === false ? '离线' : '未知'}\n </span>\n </div>\n {n.provision && (\n <div style={{ fontSize: 11, marginTop: 2, color: n.provision.state === 'ready' ? 'var(--dsw-alias-state-success-primary)' : n.provision.state === 'failed' ? 'var(--dsw-alias-state-error-primary)' : 'var(--dsw-alias-state-warn-label)' }}>\n {n.provision.state === 'provisioning' ? '容器拉起中…' : n.provision.state === 'ready' ? '容器已就绪' : `容器拉起失败:${n.provision.error ?? '未知错误'}`}\n </div>\n )}\n </div>\n ))}\n {nodes.length === 0 && <div style={{ fontSize: 12, opacity: 0.6 }}>暂无节点</div>}\n </div>\n\n <div style={{ flex: 1, maxWidth: 480, minWidth: 0, overflow: 'hidden' }}>\n {sshConfigEntries.length > 0 && (\n <div style={{ marginBottom: 14 }}>\n <label style={{ fontSize: 12, opacity: 0.75, display: 'block', marginBottom: 4 }}>从 ~/.ssh/config 导入</label>\n <select\n style={inputStyle}\n value=\"\"\n onChange={(e) => {\n const entry = sshConfigEntries[Number(e.target.value)]\n if (entry) importSshConfig(entry)\n e.target.value = ''\n }}\n >\n <option value=\"\">选择主机…</option>\n {sshConfigEntries.map((entry, i) => (\n <option key={entry.host} value={i}>\n {entry.host}:{entry.port}{entry.username ? ` (${entry.username})` : ''}{entry.hasProxyJump ? ' 跳板' : ''}\n </option>\n ))}\n </select>\n </div>\n )}\n\n <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 节点名称\n <input style={inputStyle} value={form.name} onChange={(e) => setForm((f) => ({ ...f, name: e.target.value }))} placeholder=\"例如:构建机\" />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 节点类型\n <select style={inputStyle} value={form.type} onChange={(e) => setForm((f) => ({ ...f, type: e.target.value as FormState['type'] }))}>\n <option value=\"remote-ssh\">远程 SSH 宿主机</option>\n <option value=\"remote-docker\">远程 Docker(SSH 通道)</option>\n <option value=\"local-host\">默认环境(本地)</option>\n <option value=\"local-docker\">本地 Docker 容器</option>\n </select>\n </label>\n\n {(form.type === 'remote-ssh' || form.type === 'remote-docker') && (\n <>\n <div className=\"dshb-form-row\" style={{ display: 'flex', gap: 10 }}>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13, flex: 1, minWidth: 0 }}>\n 主机地址\n <input style={inputStyle} value={form.host} onChange={(e) => setForm((f) => ({ ...f, host: e.target.value }))} placeholder=\"192.168.1.10\" />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13, width: 90 }}>\n 端口\n <input style={inputStyle} value={form.port} onChange={(e) => setForm((f) => ({ ...f, port: e.target.value }))} />\n </label>\n </div>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 用户名\n <input style={inputStyle} value={form.username} onChange={(e) => setForm((f) => ({ ...f, username: e.target.value }))} placeholder=\"root\" />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 认证方式\n <select style={inputStyle} value={form.authKind} onChange={(e) => setForm((f) => ({ ...f, authKind: e.target.value as FormState['authKind'] }))}>\n <option value=\"password\">密码</option>\n <option value=\"key\">私钥</option>\n <option value=\"agent\">ssh-agent</option>\n </select>\n </label>\n {form.authKind === 'password' && (\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 密码{selectedNode?.hasSecret.hasPassword ? '(已保存,留空保持不变)' : ''}\n <input style={inputStyle} type=\"password\" value={form.password} onChange={(e) => setForm((f) => ({ ...f, password: e.target.value }))} autoComplete=\"new-password\" />\n </label>\n )}\n {form.authKind === 'key' && (\n <>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 私钥内容{selectedNode?.hasSecret.hasKey ? '(已保存,留空保持不变)' : ''}\n <textarea style={{ ...inputStyle, minHeight: 90, resize: 'vertical' }} value={form.privateKey} onChange={(e) => setForm((f) => ({ ...f, privateKey: e.target.value }))} placeholder=\"-----BEGIN OPENSSH PRIVATE KEY-----\" />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 私钥 passphrase(可选)\n <input style={inputStyle} type=\"password\" value={form.passphrase} onChange={(e) => setForm((f) => ({ ...f, passphrase: e.target.value }))} autoComplete=\"new-password\" />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 或私钥文件路径(可选,优先使用内容)\n <input style={inputStyle} value={form.keyPath} onChange={(e) => setForm((f) => ({ ...f, keyPath: e.target.value }))} placeholder=\"~/.ssh/id_ed25519\" />\n </label>\n </>\n )}\n </>\n )}\n\n {(form.type === 'local-docker' || form.type === 'remote-docker') && (\n <>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 镜像地址\n <input style={inputStyle} value={form.dockerImage} onChange={(e) => setForm((f) => ({ ...f, dockerImage: e.target.value }))} placeholder=\"alpine:latest\" />\n </label>\n <div className=\"dshb-form-row\" style={{ display: 'flex', gap: 10 }}>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13, flex: 1, minWidth: 0 }}>\n CPU 核数(可选)\n <input style={inputStyle} value={form.dockerCpus} onChange={(e) => setForm((f) => ({ ...f, dockerCpus: e.target.value }))} placeholder=\"2\" />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13, flex: 1, minWidth: 0 }}>\n 内存 MB(可选)\n <input style={inputStyle} value={form.dockerMemory} onChange={(e) => setForm((f) => ({ ...f, dockerMemory: e.target.value }))} placeholder=\"512\" />\n </label>\n </div>\n </>\n )}\n\n {testResult !== undefined && (\n <div style={{ fontSize: 13, color: testResult === '连接成功' ? 'var(--dsw-alias-state-success-primary)' : 'var(--dsw-alias-state-error-primary)' }}>{testResult}</div>\n )}\n\n <div style={{ display: 'flex', gap: 10, marginTop: 6, flexWrap: 'wrap' }}>\n <button type=\"button\" onClick={() => void save()} disabled={busy} style={primaryButtonStyle}>\n {selectedId === 'new' ? '创建节点' : '保存'}\n </button>\n {(form.type === 'remote-ssh' || form.type === 'remote-docker' || (selectedId !== 'new' && form.type === 'local-docker')) && (\n <button type=\"button\" onClick={() => void test()} disabled={busy || testing} style={secondaryButtonStyle}>\n {testing ? '测试中…' : '测试连接'}\n </button>\n )}\n {selectedId !== 'new' && (form.type === 'local-docker' || form.type === 'remote-docker') && (\n <>\n <button type=\"button\" onClick={() => void dockerAction('provision')} disabled={busy || dockerBusy} style={primaryButtonStyle}>\n {dockerBusy ? '操作中…' : '拉起容器'}\n </button>\n <button type=\"button\" onClick={() => void dockerAction('restart')} disabled={busy || dockerBusy} style={secondaryButtonStyle}>\n {dockerBusy ? '操作中…' : '重启容器'}\n </button>\n <button type=\"button\" onClick={() => void dockerAction('stop')} disabled={busy || dockerBusy} style={secondaryButtonStyle}>\n {dockerBusy ? '操作中…' : '停止容器'}\n </button>\n </>\n )}\n {selectedId !== 'new' && (\n <button type=\"button\" onClick={() => void remove()} disabled={busy} style={dangerOutlineButtonStyle}>\n 删除\n </button>\n )}\n {notice && <span style={{ fontSize: 13, alignSelf: 'center', color: notice.kind === 'ok' ? 'var(--dsw-alias-state-success-primary)' : 'var(--dsw-alias-state-error-primary)' }}>{notice.text}</span>}\n </div>\n </div>\n </div>\n </div>\n </>\n )\n}\n\nexport function apply(ctx: ClientContext): void {\n const globalStyle = document.createElement('style')\n globalStyle.textContent = `\n /* 仅在页面根阻止整页横向滚动。绝对定位浮层(模型菜单、上下文统计面板等)\n 依赖祖先 overflow:visible 才能展开到输入框之外,禁止给任何中间祖先加裁剪。 */\n html, body { overflow-x: hidden !important; max-width: 100vw !important }\n * { min-width: 0 !important; }\n table { display: block !important; overflow-x: auto !important; }\n img, video, canvas, svg { max-width: 100% !important; height: auto !important }\n pre, code { white-space: pre-wrap !important; word-break: break-all !important }\n input, select, textarea { max-width: 100% !important; }\n /* 上下文用量弹窗 .JObwrW_panel(ContextMeter):解除宽度塌缩并允许溢出显示。\n JObwrW_ 为上游 CSS 模块 hash,上游升级需同步。 */\n .JObwrW_panel { max-width: none !important; overflow: visible !important; }\n /* 子代理切换弹窗(dsh-client-ui-subagent):menu 是 flex column + max-height + overflow:auto,\n position:fixed 经 portal 渲染。子代理很多时 flex 压缩 node(flex-shrink:1 默认),\n 文字挤压且不触发滚动。给 node flex-shrink:0 让 menu 整体 overflow:auto 滚动。 */\n [class*=\"_menu\"] [class*=\"_node\"] { flex-shrink: 0 !important; }\n /* 模型选择弹窗(dsh-client-ui-model-selection):Ra_menu 上游 max-width 420px,\n 长模型名单行放不下被 ellipsis 截断。放宽到 720px 让模型名单行完整显示。\n [class*=\"Ra_menu\"] 精确匹配模型弹窗,避免误伤其他菜单。Ra_ 为 hash,上游升级需同步。 */\n [class*=\"Ra_menu\"] { max-width: 720px !important; width: auto !important; }\n /* 终端组件(dsh-web-frontend,CSS 模块前缀 1gdtu_)桌面端修复:上游 _command_ 默认\n overflow:hidden+text-overflow:ellipsis,LLM 调 bash 的长命令在桌面端被省略号\n 截断、看不到完整内容(输出区 _output_ 本就可横向滚动,唯命令区不行)。宽屏与\n mobile.tsx 的窄屏规则等效:行链 _prompt_/_promptLine_/_command_ 撑到 max-content、\n overflow 可见,长行溢出传入 _header_(本就 overflow-y:auto)的 scrollWidth,整个\n 命令区随 _header_ 横向滚动;copyButton 贴右缘保持可见。与窄屏规则共用 1gdtu_\n hash,上游升级需同步。桌面保留可见滚动条(不隐藏、不加 touch-action)。 */\n @media (min-width: 1024px) {\n [data-phase] [class*=\"_header_1gdtu_\"] {\n min-width: 0 !important;\n max-width: 100% !important;\n overflow-x: auto !important;\n }\n [data-phase] [class*=\"_prompt_1gdtu_\"],\n [data-phase] [class*=\"_promptLine_1gdtu_\"],\n [data-phase] [class*=\"_command_1gdtu_\"] {\n min-width: max-content !important;\n max-width: none !important;\n overflow: visible !important;\n }\n [data-phase] [class*=\"_command_1gdtu_\"] {\n display: inline-block;\n text-overflow: clip !important;\n white-space: pre !important;\n }\n [data-phase] [class*=\"_copyButton_1gdtu_\"] { position: sticky !important; right: 0; top: 0; }\n }\n `\n document.head.appendChild(globalStyle)\n\n installMobile(ctx)\n\n registerWorkspaceInstructionMenu(ctx)\n\n ctx.plugin({\n inject: ['slots'],\n apply: (sub: ClientContext): void => {\n sub.slots.inject('settings.section', () =>\n sub.slots.register({ name: 'settings.section', id: SECTION_ID, order: 110, label: () => '工作节点' }, NodeSection),\n )\n /* 上游 dsh-client-ui-directory-picker-browse 以默认 priority 0 注册同一 slot;\n priority 升序遮蔽(lowest renders),用 -10 抢占渲染,避免同优先级抛错。 */\n sub.slots.inject('conversation.hero.workspace.directoryFlow', () =>\n sub.slots.register({ name: 'conversation.hero.workspace.directoryFlow', priority: -10 }, DirectoryFlowOccupant),\n )\n sub.slots.inject('sidebar.workspaces.directoryFlow', () =>\n sub.slots.register({ name: 'sidebar.workspaces.directoryFlow', priority: -10 }, DirectoryFlowOccupant),\n )\n },\n })\n\n const workspaces = (ctx as unknown as { workspaces?: { openPath(p: string): Promise<void> } }).workspaces\n if (workspaces && typeof workspaces.openPath === 'function') {\n const originalOpenPath = workspaces.openPath.bind(workspaces)\n workspaces.openPath = async (path: string): Promise<void> => {\n try {\n const res = await fetch(`/api/dshb/remote/bound?path=${encodeURIComponent(path)}`)\n if (res.ok) {\n const data = (await res.json()) as { bound?: boolean; kind?: 'file' | 'dir'; error?: string }\n if (data.bound) {\n if (data.kind !== 'file') return originalOpenPath(path)\n const a = document.createElement('a')\n a.href = `/api/dshb/remote/file?path=${encodeURIComponent(path)}`\n a.download = ''\n document.body.appendChild(a)\n a.click()\n a.remove()\n return\n }\n }\n } catch {\n // 探测失败则回退宿主原生打开\n }\n return originalOpenPath(path)\n }\n }\n\n const ICON_SVG: Record<string, string> = {\n auth: `<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M8 7C9.3807 7 10.5 5.8807 10.5 4.5C10.5 3.1193 9.3807 2 8 2C6.6193 2 5.5 3.1193 5.5 4.5C5.5 5.8807 6.6193 7 8 7Z\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M3 14C3 11.2386 5.2386 9 8 9C10.7614 9 13 11.2386 13 14\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>`,\n 'dshb-nodes': `<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"3.5\" cy=\"4\" r=\"2\" stroke=\"currentColor\" stroke-width=\"1.5\"/><circle cx=\"12.5\" cy=\"4\" r=\"2\" stroke=\"currentColor\" stroke-width=\"1.5\"/><circle cx=\"8\" cy=\"12\" r=\"2\" stroke=\"currentColor\" stroke-width=\"1.5\"/><path d=\"M3.5 6V8C3.5 9.1 4.4 10 5.5 10H8\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/><path d=\"M12.5 6V8C12.5 9.1 11.6 10 10.5 10H8\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/></svg>`,\n }\n const ICON_LABELS: Record<string, string> = { '认证': 'auth', '工作节点': 'dshb-nodes' }\n\n const observer = new MutationObserver(() => {\n const cells = document.querySelectorAll('button[class*=\"navCell\"]')\n for (const cell of Array.from(cells)) {\n const label = cell.querySelector('span[class*=\"navLabel\"]')\n if (!label) continue\n const text = label.textContent ?? ''\n const iconKey = ICON_LABELS[text]\n if (!iconKey) continue\n const iconSlot = cell.querySelector('[class*=\"navIcon\"]')\n if (!iconSlot) continue\n if (iconSlot.getAttribute('data-dshb-icon') === iconKey) continue\n iconSlot.innerHTML = ICON_SVG[iconKey] ?? ''\n iconSlot.setAttribute('data-dshb-icon', iconKey)\n }\n })\n observer.observe(document.body, { childList: true, subtree: true })\n}\n","import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport { apply as applyAuth } from './auth.js'\nimport { apply as applyUi } from './ui.js'\n\nexport const inject = ['connection', 'workspaces', 'slots', 'layout', 'conversation']\n\nexport function apply(ctx: ClientContext): void {\n applyAuth(ctx)\n applyUi(ctx)\n}\n"],"mappings":";;;;;;;;;EAQA,MAAMA,eAAa;EACnB,MAAM,aAAa;EAEnB,SAAS,cAAgE;GACvE,MAAM,CAAC,UAAU,gBAAA,GAAeC,MAAAA,SAAAA,CAA6B,KAAA,CAAS;GACtE,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,IAAI,YAAY;IAChB,CAAM,YAAY;KAChB,IAAI;MACF,MAAM,MAAM,MAAM,MAAM,kBAAkB;MAC1C,IAAI,CAAC,IAAI,IAAI;MACb,MAAM,OAAQ,MAAM,IAAI,KAAK;MAC7B,IAAI,CAAC,aAAa,OAAO,KAAK,aAAa,UAAU,YAAY,KAAK,QAAQ;KAChF,QAAQ,CAER;IACF,EAAA,CAAG;IACH,aAAa;KACX,YAAY;IACd;GACF,GAAG,CAAC,CAAC;GACL,OAAO,CAAC,UAAU,WAAW;EAC/B;EAIA,SAAgB,YAAY,QAAwD;GAClF,MAAM,CAAC,UAAU,eAAe,YAAY;GAC5C,MAAM,CAAC,aAAa,mBAAA,GAAkBA,MAAAA,SAAAA,CAAS,EAAE;GACjD,MAAM,CAAC,kBAAkB,wBAAA,GAAuBA,MAAAA,SAAAA,CAAS,EAAE;GAC3D,MAAM,CAAC,aAAa,mBAAA,GAAkBA,MAAAA,SAAAA,CAAS,EAAE;GACjD,MAAM,CAAC,aAAa,mBAAA,GAAkBA,MAAAA,SAAAA,CAAS,EAAE;GACjD,MAAM,CAAC,SAAS,eAAA,GAAcA,MAAAA,SAAAA,CAAS,EAAE;GACzC,MAAM,CAAC,MAAM,YAAA,GAAWA,MAAAA,SAAAA,CAAS,KAAK;GACtC,MAAM,CAAC,QAAQ,cAAA,GAAaA,MAAAA,SAAAA,CAA6B,KAAA,CAAS;GAClE,MAAM,CAAC,mBAAmB,yBAAA,GAAwBA,MAAAA,SAAAA,CAAS,KAAK;GAEhE,MAAM,SAAA,GAAQC,MAAAA,YAAAA,EAAa,MAA0B;IACnD,UAAU,CAAC;IACX,IAAI,MAAM,KAAA,GAAW,iBAAiB,UAAU,KAAA,CAAS,GAAG,UAAU;GACxE,GAAG,CAAC,CAAC;GAEL,MAAM,WAAA,GAAUA,MAAAA,YAAAA,CAAY,YAAY;IACtC,QAAQ,IAAI;IACZ,IAAI;KACF,MAAM,MAAM,oBAAoB,EAAE,QAAQ,OAAO,CAAC;KAClD,OAAO,SAAS,OAAO;IACzB,QAAQ;KACN,QAAQ,KAAK;KACb,qBAAqB,KAAK;KAC1B,MAAM;MAAE,MAAM;MAAS,MAAM;MAAY,OAAO;KAAU,CAAC;IAC7D;GACF,GAAG,CAAC,KAAK,CAAC;GAEV,MAAM,kBAAA,GAAiBA,MAAAA,YAAAA,CAAY,YAAY;IAC7C,IAAI,gBAAgB,SAAS;KAC3B,MAAM;MAAE,MAAM;MAAS,MAAM;MAAe,OAAO;KAAW,CAAC;KAC/D;IACF;IACA,QAAQ,IAAI;IACZ,IAAI;KACF,MAAM,MAAM,MAAM,MAAM,6BAA6B;MACnD,QAAQ;MACR,SAAS,EAAE,gBAAgB,mBAAmB;MAC9C,MAAM,KAAK,UAAU;OAAE,iBAAiB;OAAa,UAAU;MAAY,CAAC;KAC9E,CAAC;KACD,MAAM,OAAQ,MAAM,IAAI,KAAK;KAC7B,IAAI,IAAI,IAAI;MACV,eAAe,EAAE;MACjB,eAAe,EAAE;MACjB,WAAW,EAAE;MACb,MAAM;OAAE,MAAM;OAAM,MAAM;OAAS,OAAO;MAAW,CAAC;KACxD,OACE,MAAM;MAAE,MAAM;MAAS,MAAM,KAAK,SAAS;MAAY,OAAO;KAAW,CAAC;IAE9E,QAAQ;KACN,MAAM;MAAE,MAAM;MAAS,MAAM;MAAY,OAAO;KAAW,CAAC;IAC9D,UAAU;KACR,QAAQ,KAAK;IACf;GACF,GAAG;IAAC;IAAa;IAAa;IAAS;GAAK,CAAC;GAE7C,MAAM,kBAAA,GAAiBA,MAAAA,YAAAA,CAAY,YAAY;IAC7C,QAAQ,IAAI;IACZ,IAAI;KACF,MAAM,MAAM,MAAM,MAAM,6BAA6B;MACnD,QAAQ;MACR,SAAS,EAAE,gBAAgB,mBAAmB;MAC9C,MAAM,KAAK,UAAU;OAAE,UAAU;OAAa,iBAAiB;MAAiB,CAAC;KACnF,CAAC;KACD,MAAM,OAAQ,MAAM,IAAI,KAAK;KAC7B,IAAI,IAAI,IAAI;MACV,eAAe,EAAE;MACjB,oBAAoB,EAAE;MACtB,IAAI,aAAa,YAAY,WAAW;MACxC,MAAM;OAAE,MAAM;OAAM,MAAM;OAAU,OAAO;MAAW,CAAC;KACzD,OACE,MAAM;MAAE,MAAM;MAAS,MAAM,KAAK,SAAS;MAAY,OAAO;KAAW,CAAC;IAE9E,QAAQ;KACN,MAAM;MAAE,MAAM;MAAS,MAAM;MAAY,OAAO;KAAW,CAAC;IAC9D,UAAU;KACR,QAAQ,KAAK;IACf;GACF,GAAG;IAAC;IAAa;IAAkB;IAAO;GAAW,CAAC;GAEtD,MAAM,aAA4B;IAChC,OAAO;IACP,WAAW;IACX,SAAS;IACT,QAAQ;IACR,QAAQ;IACR,cAAc;IACd,UAAU;IACV,YAAY;IACZ,YAAY;IACZ,OAAO;IACP,SAAS;GACX;GACA,MAAM,cAA6B;IACjC,WAAW;IACX,QAAQ;IACR,SAAS;IACT,cAAc;IACd,UAAU;IACV,YAAY;IACZ,YAAY;IACZ,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,gBAAgB;IAChB,YAAY;IACZ,KAAK;GACP;GACA,MAAM,qBAAoC;IACxC,GAAG;IACH,YAAY;IACZ,OAAO;GACT;GACA,MAAM,uBAAsC;IAC1C,GAAG;IACH,QAAQ;IACR,OAAO;IACP,YAAY;GACd;GAGE,CAAA,EADA,GAAG,YACyC;GAG9C,MAAM,2BAA0C;IAC9C,GAAG;IACH,QAAQ;IACR,OAAO;IACP,YAAY;GACd;GAEA,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,OAAO;KAAE,SAAS;KAAQ,eAAe;KAAU,KAAK;KAAI,UAAU;IAAI;IAA/E,UAAA;KACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD,EAAA,UAAA;MACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;OAAI,OAAO;QAAE,UAAU;QAAI,YAAY;QAAK,QAAQ;OAAU;OAAG,UAAA;MAAM,CAAA;MACvE,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;OAAG,OAAO;QAAE,UAAU;QAAI,SAAS;QAAK,QAAQ;OAAW;OACxD,UAAA,aAAa,KAAA,IAAY,QAAQ,aAAa;MAC9C,CAAA;MACH,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OACE,MAAK;OACL,eAAe,qBAAqB,IAAI;OACxC,UAAU;OACV,OAAO;OACR,UAAA;MAEO,CAAA;MACP,qBACC,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,MAAK;OAAc,cAAW;OAAS,OAAO;QAAE,WAAW;QAAI,SAAS;QAAa,QAAQ;QAAwC,cAAc;QAAG,UAAU;OAAI;OAAzK,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QAAK,OAAO;SAAE,UAAU;SAAI,cAAc;SAAI,OAAO;QAAiC;QAAG,UAAA;OAAe,CAAA,GACxG,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,OAAO;SAAE,SAAS;SAAQ,gBAAgB;SAAY,KAAK;QAAE;QAAlE,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,eAAe,qBAAqB,KAAK;SAAG,UAAU;SAAM,OAAO;UAAE,GAAG;UAAsB,QAAQ;UAAI,SAAS;UAAU,cAAc;SAAG;SAAG,UAAA;QAE/J,CAAA,GACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,eAAe,KAAK,QAAQ;SAAG,UAAU;SAAM,OAAO;UAAE,GAAG;UAA0B,QAAQ;UAAI,SAAS;UAAU,cAAc;UAAI,YAAY;SAA+C;SAAG,UAAA;QAElN,CAAA,CACL;OACF,CAAA,CAAA;;MAEN,QAAQ,UAAU,aACjB,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;OAAG,OAAO;QAAE,UAAU;QAAI,OAAO,OAAO,SAAS,OAAO,2CAA2C;QAAwC,QAAQ;OAAU;OAAI,UAAA,OAAO;MAAQ,CAAA;KAE3K,EAAA,CAAA;KAET,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;MAAI,OAAO;OAAE,UAAU;OAAI,YAAY;OAAK,QAAQ;MAAW;MAAG,UAAA;KAAS,CAAA,GAC3E,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;MAAM,WAAW,MAAM;OAAE,EAAE,eAAe;OAAG,eAAoB;MAAE;MAAG,OAAO;OAAE,SAAS;OAAQ,eAAe;OAAU,KAAK;MAAG;MAAjI,UAAA;OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;QAAO,OAAO;SAAE,SAAS;SAAQ,eAAe;SAAU,KAAK;SAAG,UAAU;QAAG;QAA/E,UAAA,CAAkF,QAEhF,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SAAO,MAAK;SAAO,OAAO;SAAa,WAAW,MAAM,eAAe,EAAE,OAAO,KAAK;SAAG,cAAa;SAAW,OAAO;QAAa,CAAA,CAC/H;;OACP,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;QAAO,OAAO;SAAE,SAAS;SAAQ,eAAe;SAAU,KAAK;SAAG,UAAU;QAAG;QAA/E,UAAA,CAAkF,QAEhF,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SAAO,MAAK;SAAW,OAAO;SAAkB,WAAW,MAAM,oBAAoB,EAAE,OAAO,KAAK;SAAG,cAAa;SAAmB,OAAO;QAAa,CAAA,CACrJ;;OACP,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,OAAO;SAAE,SAAS;SAAQ,YAAY;SAAU,KAAK;QAAG;QAA7D,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,UAAU;SAAM,OAAO;SAAoB,UAAA;QAAa,CAAA,GAC7E,QAAQ,UAAU,cAAc,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,OAAO;UAAE,UAAU;UAAI,OAAO,OAAO,SAAS,OAAO,2CAA2C;SAAuC;SAAI,UAAA,OAAO;QAAW,CAAA,CACjM;;MACD;KACC,CAAA,CAAA,EAAA,CAAA;KAET,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;MAAI,OAAO;OAAE,UAAU;OAAI,YAAY;OAAK,QAAQ;MAAW;MAAG,UAAA;KAAQ,CAAA,GAC1E,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;MAAM,WAAW,MAAM;OAAE,EAAE,eAAe;OAAG,eAAoB;MAAE;MAAG,OAAO;OAAE,SAAS;OAAQ,eAAe;OAAU,KAAK;MAAG;MAAjI,UAAA;OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;QAAO,OAAO;SAAE,SAAS;SAAQ,eAAe;SAAU,KAAK;SAAG,UAAU;QAAG;QAA/E,UAAA,CAAkF,QAEhF,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SAAO,MAAK;SAAW,OAAO;SAAa,WAAW,MAAM,eAAe,EAAE,OAAO,KAAK;SAAG,cAAa;SAAmB,OAAO;QAAa,CAAA,CAC3I;;OACP,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;QAAO,OAAO;SAAE,SAAS;SAAQ,eAAe;SAAU,KAAK;SAAG,UAAU;QAAG;QAA/E,UAAA,CAAkF,OAEhF,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SAAO,MAAK;SAAW,OAAO;SAAa,WAAW,MAAM,eAAe,EAAE,OAAO,KAAK;SAAG,cAAa;SAAe,OAAO;QAAa,CAAA,CACvI;;OACP,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;QAAO,OAAO;SAAE,SAAS;SAAQ,eAAe;SAAU,KAAK;SAAG,UAAU;QAAG;QAA/E,UAAA,CAAkF,SAEhF,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SAAO,MAAK;SAAW,OAAO;SAAS,WAAW,MAAM,WAAW,EAAE,OAAO,KAAK;SAAG,cAAa;SAAe,OAAO;QAAa,CAAA,CAC/H;;OACP,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,OAAO;SAAE,SAAS;SAAQ,YAAY;SAAU,KAAK;QAAG;QAA7D,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,UAAU;SAAM,OAAO;SAAoB,UAAA;QAAY,CAAA,GAC5E,QAAQ,UAAU,cAAc,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,OAAO;UAAE,UAAU;UAAI,OAAO,OAAO,SAAS,OAAO,2CAA2C;SAAuC;SAAI,UAAA,OAAO;QAAW,CAAA,CACjM;;MACD;KACC,CAAA,CAAA,EAAA,CAAA;IACN;;EAET;EAEA,SAAgBC,QAAM,KAA0B;GAC9C,MAAM,aAAa,IAAI,IAAI,YAAY;GACvC,IAAI,eAAe,KAAA,GACjB,OAAO,eAAe,YAAY,cAAc;IAAE,cAAc;IAAM,WAAW;GAAK,CAAC;GAEzF,IAAI,OAAO;IACT,QAAQ,CAAC,OAAO;IAChB,QAAQ,QAA6B;KACnC,IAAI,MAAM,OAAO,0BACf,IAAI,MAAM,SAAS;MAAE,MAAM;MAAoB,IAAIH;MAAY,OAAO;MAAK,aAAa;KAAK,GAAG,WAAW,CAC7G;IACF;GACF,CAAC;EACH;;;EC5OA,MAAMI,eAA4B;GAChC,OAAO;GACP,WAAW;GACX,SAAS;GACT,QAAQ;GACR,QAAQ;GACR,cAAc;GACd,UAAU;GACV,YAAY;GACZ,YAAY;GACZ,OAAO;GACP,SAAS;EACX;EACA,MAAMC,gBAA6B;GACjC,WAAW;GACX,QAAQ;GACR,SAAS;GACT,cAAc;GACd,UAAU;GACV,YAAY;GACZ,YAAY;GACZ,QAAQ;GACR,QAAQ;GACR,SAAS;GACT,gBAAgB;GAChB,YAAY;GACZ,KAAK;EACP;EACA,MAAMC,uBAAoC;GACxC,GAAGD;GACH,YAAY;GACZ,OAAO;EACT;EACA,MAAME,yBAAsC;GAC1C,GAAGF;GACH,QAAQ;GACR,OAAO;GACP,YAAY;EACd;EACA,MAAM,eAA8B;GAClC,UAAU;GACV,OAAO;GACP,YAAY;GACZ,SAAS;GACT,YAAY;GACZ,gBAAgB;GAChB,QAAQ;EACV;EACA,MAAM,cAA6B;GACjC,OAAO;GACP,UAAU;GACV,WAAW;GACX,UAAU;GACV,WAAW;GACX,YAAY;GACZ,QAAQ;GACR,cAAc;GACd,SAAS;GACT,WAAW;GACX,OAAO;EACT;EAEA,SAAS,SAAS,MAAc,MAAsB;GACpD,OAAO,GAAG,KAAK,QAAQ,QAAQ,EAAE,EAAE,GAAG;EACxC;EAEA,SAAgB,sBAAsB,OAAqD;GACzF,MAAM,CAAC,OAAO,aAAA,GAAYG,MAAAA,SAAAA,CAA4B,CAAC,CAAC;GACxD,MAAM,CAAC,QAAQ,cAAA,GAAaA,MAAAA,SAAAA,CAAiB,EAAE;GAC/C,MAAM,CAAC,MAAM,YAAA,GAAWA,MAAAA,SAAAA,CAAS,EAAE;GACnC,MAAM,CAAC,SAAS,eAAA,GAAcA,MAAAA,SAAAA,CAAqB,CAAC,CAAC;GACrD,MAAM,CAAC,OAAO,aAAA,GAAYA,MAAAA,SAAAA,CAA6B,KAAA,CAAS;GAChE,MAAM,CAAC,MAAM,YAAA,GAAWA,MAAAA,SAAAA,CAAS,KAAK;GACtC,MAAM,CAAC,YAAY,kBAAA,GAAiBA,MAAAA,SAAAA,CAAS,EAAE;GAC/C,MAAM,CAAC,oBAAoB,0BAAA,GAAyBA,MAAAA,SAAAA,CAA6B,KAAA,CAAS;GAC1F,MAAM,CAAC,uBAAuB,6BAAA,GAA4BA,MAAAA,SAAAA,CAAS,KAAK;GAExE,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,IAAI,CAAC,MAAM,MAAM;IACjB,CAAM,YAAY;KAChB,IAAI;MACF,MAAM,MAAM,MAAM,MAAM,iBAAiB;MACzC,IAAI,CAAC,IAAI,IAAI;MACb,MAAM,OAAQ,MAAM,IAAI,KAAK;MAC7B,SAAS,KAAK,SAAS,CAAC,CAAC;KAC3B,QAAQ,CAAC;IACX,EAAA,CAAG;GACL,GAAG,CAAC,MAAM,IAAI,CAAC;GAEf,MAAM,UAAA,GAASC,MAAAA,YAAAA,CAAY,OAAO,IAAY,QAAgB;IAC5D,SAAS,KAAA,CAAS;IAClB,IAAI;KACF,MAAM,MAAM,MAAM,MAAM,mBAAmB,GAAG,eAAe,mBAAmB,GAAG,GAAG;KACtF,MAAM,OAAQ,MAAM,IAAI,KAAK;KAC7B,IAAI,CAAC,IAAI,MAAM,CAAC,KAAK,IAAI;MACvB,SAAS,KAAK,SAAS,QAAQ;MAC/B;KACF;KACA,QAAQ,KAAK,QAAQ,GAAG;KACxB,YAAY,KAAK,WAAW,CAAC,EAAA,CAAG,QAAQ,MAAM,EAAE,WAAW,CAAC;IAC9D,QAAQ;KACN,SAAS,MAAM;IACjB;GACF,GAAG,CAAC,CAAC;GAEL,MAAM,cAAA,GAAaA,MAAAA,YAAAA,EAChB,OAAe;IACd,UAAU,EAAE;IACZ,QAAQ,EAAE;IACV,WAAW,CAAC,CAAC;IACb,SAAS,KAAA,CAAS;IAClB,OAAY,IAAI,GAAG;GACrB,GACA,CAAC,MAAM,CACT;GAEA,MAAM,SAAA,GAAQA,MAAAA,YAAAA,CAAY,YAAY;IACpC,IAAI,CAAC,WAAW,KAAK,GAAG;IACxB,QAAQ,IAAI;IACZ,SAAS,KAAA,CAAS;IAClB,IAAI;KACF,MAAM,SAAS,SAAS,MAAM,WAAW,KAAK,CAAC;KAC/C,MAAM,MAAM,MAAM,MAAM,mBAAmB,OAAO,SAAS;MACzD,QAAQ;MACR,SAAS,EAAE,gBAAgB,mBAAmB;MAC9C,MAAM,KAAK,UAAU,EAAE,MAAM,OAAO,CAAC;KACvC,CAAC;KACD,MAAM,OAAQ,MAAM,IAAI,KAAK;KAC7B,IAAI,CAAC,IAAI,MAAM,CAAC,KAAK,IAAI;MACvB,SAAS,KAAK,SAAS,QAAQ;MAC/B;KACF;KACA,cAAc,EAAE;KAChB,OAAY,QAAQ,MAAM;IAC5B,QAAQ;KACN,SAAS,MAAM;IACjB,UAAU;KACR,QAAQ,KAAK;IACf;GACF,GAAG;IAAC;IAAY;IAAQ;IAAM;GAAM,CAAC;GAErC,MAAM,WAAA,GAAUA,MAAAA,YAAAA,CAAY,YAAY;IACtC,IAAI,CAAC,UAAU,CAAC,MAAM;KACpB,SAAS,UAAU;KACnB;IACF;IACA,QAAQ,IAAI;IACZ,SAAS,KAAA,CAAS;IAClB,IAAI;KACF,MAAM,OAAO,MAAM,MAAM,MAAM,EAAE,OAAO,MAAM;KAC9C,IAAI,CAAC,MAAM;KACX,IAAI,aAAa;KACjB,IAAI,KAAK,SAAS,cAAc;MAC9B,MAAM,MAAM,MAAM,MAAM,6BAA6B;OACnD,QAAQ;OACR,SAAS,EAAE,gBAAgB,mBAAmB;OAC9C,MAAM,KAAK,UAAU;QAAE;QAAQ,YAAY;OAAK,CAAC;MACnD,CAAC;MACD,MAAM,OAAQ,MAAM,IAAI,KAAK;MAC7B,IAAI,CAAC,IAAI,MAAM,CAAC,KAAK,MAAM,CAAC,KAAK,YAAY;OAC3C,SAAS,KAAK,SAAS,SAAS;OAChC;MACF;MACA,aAAa,KAAK;KACpB;KACA,MAAM,SAAS,UAAU;KACzB,IAAI,uBAAuB,KAAA,KAAa,mBAAmB,KAAK,GAC9D,uBAAuB,YAAY,kBAAkB;IAEzD,QAAQ;KACN,SAAS,MAAM;IACjB,UAAU;KACR,QAAQ,KAAK;IACf;GACF,GAAG;IAAC;IAAQ;IAAM;IAAO;IAAO;GAAkB,CAAC;GAEnD,IAAI,CAAC,MAAM,MAAM,OAAO;GAExB,MAAM,OAAO,MAAM,MAAM,MAAM,EAAE,OAAO,MAAM;GAE9C,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,OAAO;IAAc,MAAK;IAAS,cAAW;IAAnD,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,OAAO;KAAZ,UAAA;MACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,OAAO;QAAE,SAAS;QAAQ,gBAAgB;QAAiB,YAAY;QAAU,cAAc;OAAG;OAAvG,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;QAAI,OAAO;SAAE,QAAQ;SAAG,UAAU;SAAI,OAAO;QAAiC;QAAG,UAAA;OAAS,CAAA,GAC1F,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,SAAS,MAAM;QAAU,OAAOF;QAAsB,UAAA;OAEpE,CAAA,CACL;;MAEL,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;OAAO,OAAO;QAAE,SAAS;QAAS,UAAU;QAAI,OAAO;QAAoC,cAAc;OAAE;OAAG,UAAA;MAAW,CAAA;MACzH,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;OAAQ,OAAO;QAAE,GAAGH;QAAY,cAAc;OAAG;OAAG,OAAO;OAAQ,WAAW,MAAM,WAAW,EAAE,OAAO,KAAK;OAAG,UAAU,MAAM,QAAQ;OAAxI,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,OAAM;QAAG,UAAA;OAAa,CAAA,GAC7B,MAAM,KAAK,MAAM;QAChB,MAAM,YACJ,EAAE,SAAS,eAAe,OAAO,EAAE,SAAS,eAAe,WAAW,EAAE,SAAS,iBAAiB,cAAc,EAAE,SAAS,kBAAkB,cAAc,EAAE;QAC/J,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;SAAmB,OAAO,EAAE;SAA5B,UAAA;UACG,EAAE;UAAK;UAAE;UAAU;SACd;QAFK,GAAA,EAAE,EAEP;OAEZ,CAAC,CACK;;MAEP,WAAW,MACV,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,OAAO;SAAE,SAAS;SAAQ,gBAAgB;SAAiB,YAAY;SAAU,cAAc;QAAE;QAAtG,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;SAAO,OAAO;UAAE,UAAU;UAAI,OAAO;SAAmC;SAAxE,UAAA;UAA2E;UAAM,MAAM,SAAS,eAAe,OAAO;UAAK;SAAQ;QACnI,CAAA,GAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,eAAe,KAAK,OAAO,QAAQ,UAAU,IAAI,CAAC;SAAG,UAAU;SAAM,OAAOG;SAAsB,UAAA;QAEhH,CAAA,CACL;;OACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QAAK,OAAO;SAAE,GAAGH;SAAY,cAAc;SAAG,QAAQ;SAAQ,WAAW;SAAI,SAAS;SAAQ,YAAY;SAAU,UAAU;SAAQ,KAAK;SAAG,QAAQ;SAAW,YAAY;SAAQ,UAAU;QAAS;QAAG,eAAe,KAAK,OAAO,QAAQ,IAAI;QAC/O,UAAA,KAAK,MAAM,GAAG,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,WAAW,IAC1C,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,OAAO,EAAE,SAAS,GAAI;SAAG,UAAA;QAAS,CAAA,IAExC,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,UAAU,OAAO;UAAE,GAAG,gBAAgB;UAAG,OAAY,QAAQ,GAAG;SAAE;SAAG,OAAO;UAAE,QAAQ;UAAW,OAAO;SAAmC;SAAG,UAAA;QAAO,CAAA,GAC1J,KAAK,MAAM,GAAG,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,KAAK,GAAG,QAAQ;SACpD,MAAM,MAAM,MAAM,IAAI,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG;SAC9C,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;UAAc,OAAO;WAAE,SAAS;WAAe,YAAY;WAAU,KAAK;UAAE;UAA5E,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;WAAM,UAAU,OAAO;YAAE,GAAG,gBAAgB;YAAG,OAAY,QAAQ,GAAG;WAAE;WAAG,OAAO,EAAE,QAAQ,UAAU;WAAI,UAAA;UAAU,CAAA,GACnH,IAAI,IAAI,SAAS,KAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;WAAM,OAAO,EAAE,SAAS,GAAI;WAAG,UAAA;UAAO,CAAA,CACzD;SAHK,GAAA,CAGL;QAEV,CAAC,CACD,EAAA,CAAA;OAED,CAAA;OACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,OAAO;SAAE,WAAW;SAAK,UAAU;SAAQ,QAAQ;SAAwC,cAAc;SAAG,cAAc;QAAG;QAAlI,UAAA,CACG,QAAQ,KAAK,MACZ,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAkB,eAAe,KAAK,OAAO,QAAQ,EAAE,IAAI;SAAG,OAAO;UAAE,SAAS;UAAY,QAAQ;UAAW,UAAU;UAAI,cAAc;UAAG,OAAO;UAAkC,SAAS;UAAQ,YAAY;UAAU,KAAK;UAAG,UAAU;SAAS;SAAG,eAAe,OAAQ,GAAG,cAAc,MAAM,aAAa;SAA0C,eAAe,OAAQ,GAAG,cAAc,MAAM,aAAa;SAA5Z,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,OAAO,EAAE,YAAY,EAAE;UAAG,UAAA;SAAQ,CAAA,GACxC,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,OAAO;WAAE,UAAU;WAAU,cAAc;WAAY,YAAY;UAAS;UAAI,UAAA,EAAE;SAAW,CAAA,CAChG;QAHK,GAAA,EAAE,IAGP,CACN,GACA,QAAQ,WAAW,KAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,OAAO;UAAE,SAAS;UAAI,UAAU;UAAI,OAAO;SAAkC;SAAG,UAAA;QAAS,CAAA,CACpH;;OACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,OAAO;SAAE,SAAS;SAAQ,KAAK;SAAG,cAAc;QAAG;QAAxD,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SAAO,OAAO;UAAE,GAAGA;UAAY,MAAM;UAAG,UAAU;SAAE;SAAG,OAAO;SAAY,WAAW,MAAM,cAAc,EAAE,OAAO,KAAK;SAAG,aAAY;SAAe,YAAY,MAAM;UAAE,IAAI,EAAE,QAAQ,SAAS,MAAW;SAAE;QAAI,CAAA,GACjN,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,eAAe,KAAK,MAAM;SAAG,UAAU,QAAQ,CAAC,WAAW,KAAK;SAAG,OAAO;UAAE,GAAGG;UAAsB,YAAY;UAAG,YAAY;SAAS;SAAG,UAAA;QAE1J,CAAA,CACL;;MACL,EAAA,CAAA;MAGH,SAAS,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,OAAO;QAAE,UAAU;QAAI,OAAO;QAAwC,cAAc;OAAG;OAAI,UAAA;MAAW,CAAA;MAErH,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,OAAO;QAAE,SAAS;QAAQ,gBAAgB;QAAY,KAAK;OAAG;OAAnE,UAAA;QACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,SAAS,MAAM;SAAU,OAAOA;SAAsB,UAAA;QAEpE,CAAA;QACR,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;SACE,MAAK;SACL,eAAe,yBAAyB,IAAI;SAC5C,UAAU,QAAQ,MAAM,QAAQ,CAAC,UAAU,CAAC;SAC5C,OAAO;UACL,GAAGA;UACH,aAAa,uBAAuB,KAAA,KAAa,mBAAmB,KAAK,IAAI,4CAA4C;UACzH,OAAO,uBAAuB,KAAA,KAAa,mBAAmB,KAAK,IAAI,4CAA4C;SACrH;SARF,UAAA,CASC,MACI,uBAAuB,KAAA,KAAa,mBAAmB,KAAK,IAAI,OAAO,EACpE;;QACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,eAAe,KAAK,QAAQ;SAAG,UAAU,QAAQ,MAAM,QAAQ,CAAC,UAAU,CAAC;SAAM,OAAOD;SAAoB,UAAA;QAE1H,CAAA;OACL;;KACF;IAEJ,CAAA,GAAA,yBACC,iBAAA,GAAA,kBAAA,IAAA,CAAC,0BAAD;KACE,MAAM,sBAAsB;KAC5B,eAAe,yBAAyB,KAAK;KAC7C,SAAS,MAAM;MACb,sBAAsB,CAAC;MACvB,yBAAyB,KAAK;KAChC;IACD,CAAA,CAEA;;EAET;EAEA,SAAS,UAAU,MAAsB;GACvC,MAAM,QAAQ,KAAK,MAAM,GAAG,CAAC,CAAC,OAAO,OAAO;GAC5C,MAAM,IAAI;GACV,OAAO,MAAM,WAAW,IAAI,MAAM,IAAI,MAAM,KAAK,GAAG;EACtD;EAEA,MAAM,sCAAsB,IAAI,IAAoB;EAEpD,SAAS,uBAAuB,MAAc,MAAoB;GAChE,oBAAoB,IAAI,MAAM,IAAI;GAClC,CAAM,YAAY;IAChB,IAAI;KACF,IAAI,WAAW;KACf,MAAM,aAAa,YAA2B;MAC5C,IAAI,aAAa,IAAI;MAIrB,MAAM,OAHO,OAA8H,YACzH,MAAM,cAAc,EAAA,EAClB,SAAS,CAAC,EAAA,CACb,MAAM,MAAM,EAAE,SAAS,IAAI;MAC5C,IAAI,CAAC,IAAI;OACP,MAAM,IAAI,SAAS,MAAM,WAAW,GAAG,GAAG,CAAC;OAC3C,OAAO,WAAW;MACpB;MACA,MAAM,MAAM,0BAA0B,GAAG,eAAe;OACtD,QAAQ;OACR,SAAS,EAAE,gBAAgB,mBAAmB;OAC9C,MAAM,KAAK,UAAU;QAAE;QAAM,kBAAkB;OAAE,CAAC;MACpD,CAAC;MACD,oBAAoB,OAAO,IAAI;KACjC;KACA,WAAgB;IAClB,QAAQ,CAAC;GACX,EAAA,CAAG;EACL;EAEA,SAAS,yBAAyB,OAIjB;GACf,MAAM,CAAC,MAAM,YAAA,GAAWE,MAAAA,SAAAA,CAAS,MAAM,IAAI;GAuB3C,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,OAAO;KAtBZ,UAAU;KACV,OAAO;KACP,YAAY;KACZ,SAAS;KACT,YAAY;KACZ,gBAAgB;KAChB,QAAQ;IAgBe;IAAG,SAAS,MAAM;IACvC,UAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,OAAO;MAdd,OAAO;MACP,UAAU;MACV,WAAW;MACX,UAAU;MACV,WAAW;MACX,YAAY;MACZ,QAAQ;MACR,cAAc;MACd,SAAS;MACT,WAAW;MACX,OAAO;KAIiB;KAAG,UAAU,MAAM,EAAE,gBAAgB;KAA3D,UAAA;MACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,OAAO;QAAE,SAAS;QAAQ,gBAAgB;QAAiB,YAAY;QAAU,cAAc;OAAG;OAAvG,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;QAAI,OAAO;SAAE,QAAQ;SAAG,UAAU;SAAI,OAAO;QAAiC;QAAG,UAAA;OAAQ,CAAA,GACzF,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,SAAS,MAAM;QAAS,OAAOD;QAAsB,UAAA;OAAU,CAAA,CAClF;;MACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,OAAO;QAAE,UAAU;QAAI,OAAO;QAAoC,cAAc;OAAG;OAAG,UAAA;MAEtF,CAAA;MACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,YAAD;OACE,OAAO;QACL,OAAO;QACP,WAAW;QACX,YAAY;QACZ,UAAU;QACV,SAAS;QACT,QAAQ;QACR,cAAc;QACd,YAAY;QACZ,OAAO;QACP,QAAQ;QACR,WAAW;QACX,SAAS;OACX;OACA,OAAO;OACP,WAAW,MAAM,QAAQ,EAAE,OAAO,KAAK;OACvC,aAAY;OACZ,YAAY;MACb,CAAA;MACD,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,OAAO;QAAE,SAAS;QAAQ,gBAAgB;QAAY,KAAK;QAAI,WAAW;OAAG;OAAlF,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,SAAS,MAAM;QAAS,OAAOA;QAAsB,UAAA;OAAU,CAAA,GACrF,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,eAAe,MAAM,OAAO,IAAI;QAAG,OAAOD;QAAoB,UAAA;OAAU,CAAA,CAC3F;;KACF;;GACF,CAAA;EAET;;;;;;;;;;;;;ECxYA,MAAa,eAAe;;EAG5B,MAAM,eAAe;EAErB,MAAM,aAAa;EACnB,MAAM,iBAAiB;EAEvB,MAAM,aAAa;;;;;;;KAOd,WAAW;;;;;;;;KAQX,WAAW;;;;;;;;;;;;;KAaX,WAAW,iBAAiB,eAAe;;OAEzC,WAAW;;;;;;;;;;;;;;;;;;;;KAoBb,WAAW;;;;;;;;;;KAUX,WAAW;KACX,WAAW;KACX,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAmLX,WAAW;KACX,WAAW;KACX,WAAW;KACX,WAAW;KACX,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAmCX,WAAW;;;;;;;;;;;;;;KAcX,WAAW;;;;;;;;;;;;;;;;;;;;;KAqBX,WAAW,eAAe,WAAW;;;EAI1C,SAAS,YAAgC;GACvC,OAAO,SAAS,cAAc,sBAAsB,CAAC,EAAE,iBAAiB;EAC1E;EAEA,SAAS,WAA+B;GACtC,OAAO,SAAS,cAAc,IAAI,WAAW,UAAU,KAAK,UAAU;EACxE;;EAGA,SAAS,gBAAgB,KAA0B;GACjD,IAAI,aAAa;IACf,MAAM,SAAS,OAAO,WAAW,YAAY;IAC7C,MAAM,WAAW,SAAS,cAA+B,yBAAuB;IAChF,IAAI,aAAa,MAAM,aAAa,CAAC;IACrC,MAAM,WAAW,SAAS;IAC1B,MAAM,aAAmB;KACvB,SAAS,UAAU,OAAO,UACtB,4DACA;IACN;IACA,KAAK;IACL,OAAO,iBAAiB,UAAU,IAAI;IACtC,aAAa;KACX,OAAO,oBAAoB,UAAU,IAAI;KACzC,SAAS,UAAU;IACrB;GACF,GAAG,uBAAuB;EAC5B;EAEA,SAAS,cAAc,KAA0B;GAC/C,IAAI,aAAa;IACf,MAAM,MAAM,SAAS,cAAc,OAAO;IAC1C,IAAI,QAAQ,SAAS;IACrB,IAAI,cAAc;IAClB,SAAS,KAAK,YAAY,GAAG;IAE7B,iBAAiB;KAAE,IAAI,IAAI,aAAa,SAAS,KAAK,YAAY,GAAG;IAAE,GAAG,CAAC;IAC3E,aAAa;KAAE,IAAI,OAAO;IAAE;GAC9B,GAAG,qBAAqB;EAC1B;;EAGA,SAAS,mBAAmB,KAA0B;GACpD,IAAI,aAAa;IACf,MAAM,SAAS,OAAO,WAAW,YAAY;IAC7C,IAAI,QAA4B;IAChC,MAAM,cAAoB;KACxB,IAAI,UAAU,MAAM,MAAM,gBAAgB,UAAU;KACpD,QAAQ;IACV;IACA,MAAM,eAAqB;KACzB,IAAI,CAAC,OAAO,SAAS;KACrB,QAAQ,UAAU;KAClB,IAAI,UAAU,QAAQ,CAAC,MAAM,aAAa,UAAU,GAAG,MAAM,aAAa,YAAY,OAAO;IAC/F;IACA,OAAO;IACP,MAAM,KAAK,IAAI,iBAAiB,MAAM;IACtC,GAAG,QAAQ,SAAS,iBAAiB;KAAE,WAAW;KAAM,SAAS;IAAK,CAAC;IACvE,MAAM,iBAAuB;KAAE,IAAI,OAAO,SAAS,OAAO;UAAQ,MAAM;IAAE;IAC1E,OAAO,iBAAiB,UAAU,QAAQ;IAC1C,aAAa;KACX,GAAG,WAAW;KACd,OAAO,oBAAoB,UAAU,QAAQ;KAC7C,MAAM;IACR;GACF,GAAG,2BAA2B;EAChC;;;;;EAMA,SAAS,0BAA0B,KAAoB,eAAiC;GACtF,IAAI,aAAa;IACf,MAAM,SAAS,OAAO,WAAW,YAAY;IAC7C,IAAI,WAA+B;IACnC,MAAM,mBAA4B;KAChC,MAAM,QAAQ,SAAS;KACvB,OAAO,OAAO,WAAW,UAAU,QAAQ,CAAC,MAAM,aAAa,cAAc;IAC/E;IACA,MAAM,aAAmB;KACvB,IAAI,WAAW,KAAK,aAAa,MAAM;MACrC,WAAW,SAAS,cAAc,KAAK;MACvC,SAAS,aAAa,GAAG,WAAW,YAAY,EAAE;MAClD,SAAS,MAAM,UAAU;MACzB,SAAS,iBAAiB,eAAe,cAAc,CAAC;MACxD,SAAS,KAAK,YAAY,QAAQ;KACpC,OAAO,IAAI,CAAC,WAAW,KAAK,aAAa,MAAM;MAC7C,SAAS,OAAO;MAChB,WAAW;KACb;IACF;IACA,MAAM,aAAa,UAA+B;KAChD,IAAI,MAAM,QAAQ,UAAU;KAC5B,IAAI,SAAS,cAAc,uBAAqB,MAAM,MAAM;KAC5D,IAAI,WAAW,GAAG,cAAc;IAClC;IACA,MAAM,WAAW,UAA4B;KAC3C,IAAI,CAAC,WAAW,GAAG;KACnB,MAAM,SAAS,MAAM;KACrB,IAAI,EAAE,kBAAkB,UAAU;KAClC,MAAM,SAAS,SAAS,cAAc,IAAI,WAAW,yBAAyB;KAC9E,IAAI,WAAW,QAAQ,CAAC,OAAO,SAAS,MAAM,GAAG;KACjD,IAAI,OAAO,QAAQ,8BAA4B,MAAM,MAAM;KAC3D,IAAI,OAAO,QAAQ,kGAA0F,MAAM,MAAM,cAAc;IACzI;IACA,KAAK;IACL,MAAM,KAAK,IAAI,iBAAiB,IAAI;IACpC,GAAG,QAAQ,SAAS,iBAAiB;KAAE,WAAW;KAAM,SAAS;KAAM,YAAY;KAAM,iBAAiB,CAAC,cAAc;IAAE,CAAC;IAC5H,SAAS,iBAAiB,WAAW,WAAW,IAAI;IACpD,SAAS,iBAAiB,SAAS,SAAS,IAAI;IAChD,OAAO,iBAAiB,UAAU,IAAI;IACtC,aAAa;KACX,GAAG,WAAW;KACd,SAAS,oBAAoB,WAAW,WAAW,IAAI;KACvD,SAAS,oBAAoB,SAAS,SAAS,IAAI;KACnD,OAAO,oBAAoB,UAAU,IAAI;KACzC,UAAU,OAAO;IACnB;GACF,GAAG,kCAAkC;EACvC;;EAGA,SAAS,iBAAiB,KAA0B;GAClD,IAAI,aAAa;IACf,MAAM,SAAS,OAAO,WAAW,YAAY;IAG7C,MAAM,gBAAgB;IACtB,MAAM,eAAe,OAAyB;KAC5C,MAAM,QAAQ,GAAG,eAAe,GAAA,CAAI,KAAK;KACzC,IAAI,KAAK,WAAW,KAAK,KAAK,SAAS,KAAK,OAAO;KACnD,IAAI,CAAC,cAAc,KAAK,IAAI,GAAG,OAAO;KACtC,IAAI,GAAG,cAAc,oCAAoC,MAAM,MAAM,OAAO;KAC5E,OAAO;IACT;IACA,MAAM,aAAmB;KACvB,IAAI,CAAC,OAAO,SAAS;KAErB,SAAS,iBAAiB,IAAI,WAAW,UAAU,CAAC,CAAC,SAAS,OAAO;MACnE,IAAI,CAAC,GAAG,eAAe,CAAC,cAAc,MAAM,GAAG,eAAe,GAAA,CAAI,KAAK,CAAC,GAAG,GAAG,gBAAgB,UAAU;KAC1G,CAAC;KAGD,MAAM,QAAQ,MAAM,KAAK,SAAS,iBAAiB,WAAW,CAAC,CAAC,CAAC,QAAQ,OAAO;MAC9E,IAAI,CAAC,YAAY,EAAE,GAAG,OAAO;MAC7B,IAAI,iBAAiB,EAAE,CAAC,CAAC,YAAY,YAAY,OAAO;MACxD,OAAO;KACT,CAAC;KACD,KAAK,MAAM,MAAM,OAAO;MACtB,IAAI,GAAG,aAAa,UAAU,GAAG;MACjC,IAAI,MAAM,GAAG;MACb,IAAI,eAAe;MACnB,OAAO,KAAK;OACV,IAAI,MAAM,SAAS,GAAG,GAAG;QAAE,eAAe;QAAM;OAAM;OACtD,MAAM,IAAI;MACZ;MACA,IAAI,CAAC,cAEC;WAAA,CAAC,GAAG,aAAa,UAAU,GAAG,GAAG,aAAa,YAAY,OAAO;MAAA;KAEzE;IACF;IACA,KAAK;IACL,MAAM,KAAK,IAAI,uBAAuB;KAAE,IAAI,OAAO,SAAS,KAAK;IAAE,CAAC;IACpE,GAAG,QAAQ,SAAS,iBAAiB;KAAE,WAAW;KAAM,SAAS;IAAK,CAAC;IACvE,OAAO,iBAAiB,UAAU,IAAI;IACtC,aAAa;KACX,GAAG,WAAW;KACd,OAAO,oBAAoB,UAAU,IAAI;IAC3C;GACF,GAAG,yBAAyB;EAC9B;;EAGA,MAAM,cAAc;GAClB;GAAY;GAAS;GAAQ;GAAS;GAAO;GAC7C;GAAa;GAAa;GAAc;GAAc;EACxD;;EAGA,SAAS,qBAAqB,IAAiB,aAAsB,UAAkB,WAAyB;GAC9G,MAAM,SAAS;GACf,MAAM,KAAK,OAAO;GAClB,MAAM,KAAK,OAAO;GAClB,GAAG,MAAM,YAAY,YAAY,SAAS,WAAW;GACrD,GAAG,MAAM,YAAY,cAAc,cAAc,WAAW;GAC5D,GAAG,MAAM,YAAY,QAAQ,KAAK,WAAW;GAC7C,GAAG,MAAM,YAAY,SAAS,QAAQ,WAAW;GACjD,GAAG,MAAM,YAAY,OAAO,KAAK,WAAW;GAC5C,GAAG,MAAM,YAAY,UAAU,QAAQ,WAAW;GAClD,GAAG,MAAM,YAAY,aAAa,KAAK,WAAW;GAClD,GAAG,MAAM,YAAY,aAAa,GAAG,KAAK,IAAI,GAAG,KAAK,IAAI,UAAU,KAAK,EAAU,CAAC,EAAE,KAAK,WAAW;GACtG,GAAG,MAAM,YAAY,cAAc,GAAG,KAAK,IAAI,GAAG,KAAK,IAAI,WAAW,KAAK,EAAU,CAAC,EAAE,KAAK,WAAW;GACxG,GAAG,MAAM,YAAY,cAAc,QAAQ,WAAW;GACtD,IAAI,QAAQ,GAAG;GACf,IAAI,SAAS,GAAG;GAChB,MAAM,aAAa,KAAK,IAAI,GAAG,YAAY,MAAM,EAAU;GAC3D,MAAM,aAAa,KAAK,IAAI,GAAG,KAAK,YAAY,SAAS,EAAU;GACnE,MAAM,WAAW,UAAU,cAAc,cAAc;GACvD,MAAM,YAAY,WAAW,aAAa;GAC1C,IAAI,SAAS,WAAW;IACtB,GAAG,MAAM,YAAY,cAAc,GAAG,KAAK,IAAI,GAAG,YAAY,MAAM,EAAE,KAAK,WAAW;IACtF,SAAS,GAAG;IACZ,QAAQ,GAAG;GACb;GACA,MAAM,MAAM,WAAW,YAAY,MAAM,SAAS,SAAS,YAAY,SAAS;GAChF,MAAM,OAAO,KAAK,IAAI,QAAQ,KAAK,IAAI,YAAY,QAAQ,OAAO,KAAK,QAAQ,MAAM,CAAC;GACtF,GAAG,MAAM,YAAY,QAAQ,GAAG,KAAK,KAAK,WAAW;GACrD,GAAG,MAAM,YAAY,OAAO,GAAG,KAAK,IAAI,QAAQ,KAAK,IAAI,KAAK,KAAK,SAAS,MAAM,CAAC,EAAE,KAAK,WAAW;EACvG;;;;;;;;;EAUA,SAAS,wBAAwB,MAAyB;GACxD,KAAK,MAAM,MAAM,MAAM,KAAK,KAAK,iBAA8B,wBAAsB,CAAC,GAAG;IACvF,MAAM,KAAK,GAAG;IACd,IAAI,MAAM,GAAG,aAAa,KAAK,aAAa,GAAG,cAAc,QAAQ,GAAG,UAAU,SAAS,GAAG,GAC5F,GAAG,YAAY,GAAG,UAAU,QAAQ,MAAM,GAAQ;GAEtD;EACF;;;;;;;;EASA,SAAS,iBAAiB,MAAyB;GACjD,MAAM,QAAQ,MAAM,KAAK,KAAK,iBAA8B,wBAAsB,CAAC;GACnF,IAAI,MAAM,WAAW,GAAG;GACxB,MAAM,MAAM,MAAM,EAAE,CAAC;GACrB,IAAI,QAAQ,MAAM;GAClB,MAAM,OAAO,IAAI,cAAc;GAC/B,IAAI,QAAQ,GAAG;GACf,MAAM,OAAO;GACb,IAAI,UAAU,MAAM;GACpB,KAAK,MAAM,KAAK,OACd,KAAK,EAAE,aAAa,UAAU,MAAM,QAAQ,aAAa,UAAU,IAAI,UAAU;GAEnF,MAAM,SAAS,QAAQ,MAAM;GAC7B,QAAQ,MAAM,aAAa;GAC3B,QAAQ,MAAM,WAAW,GAAG,KAAK;GACjC,MAAM,UAAU,QAAQ;GACxB,QAAQ,MAAM,aAAa;GAC3B,QAAQ,MAAM,WAAW;GACzB,MAAM,KAAK,UAAU,OAAO,KAAK,IAAI,IAAI,KAAK,IAAI,MAAM,KAAK,MAAM,QAAQ,OAAO,QAAQ,CAAC,CAAC,IAAI;GAChG,KAAK,MAAM,KAAK,OAAO;IACrB,EAAE,MAAM,YAAY,eAAe,UAAU,WAAW;IACxD,EAAE,MAAM,YAAY,aAAa,GAAG,GAAG,KAAK,WAAW;GACzD;EACF;;EAGA,SAAS,kBAAkB,MAA4C;GACrE,IAAI,SAAS,QAAQ,SAAS,KAAA,GAAW;GACzC,KAAK,MAAM,KAAK,MAAM,KAAK,KAAK,iBAA8B,wBAAsB,CAAC,GAAG;IACtF,EAAE,MAAM,eAAe,aAAa;IACpC,EAAE,MAAM,eAAe,WAAW;GACpC;EACF;;EAGA,SAAS,gBAAgB,IAA0C;GACjE,IAAI,OAAO,QAAQ,OAAO,KAAA,GAAW;GACrC,KAAK,MAAM,OAAO,aAAa,GAAG,MAAM,eAAe,GAAG;EAC5D;;;;;;;;;EAUA,SAAS,yBAAyB,KAA0B;GAC1D,IAAI,aAAa;IACf,MAAM,SAAS,OAAO,WAAW,YAAY;IAG7C,MAAM,kBAAiC;KACrC,MAAM,SAAS,MAAM,KAAK,SAAS,iBAA8B,0BAAwB,CAAC;KAC1F,IAAI,OAAO,SAAS,GAAG,OAAO;KAE9B,OAAO,MAAM,KAAK,SAAS,iBAA8B,oBAAkB,CAAC,CAAC,CAAC,QAAQ,OACpF,GAAG,cAAc,gDAA4C,MAAM,IACrE;IACF;IACA,MAAM,eAAe,SAA0C;KAC7D,IAAI,KAAK,IAAI;MACX,MAAM,aAAa,MAAM,KAAK,SAAS,iBAA8B,iBAAiB,CAAC,CAAC,CAAC,MACtF,OAAO,GAAG,aAAa,eAAe,MAAM,KAAK,EACpD;MACA,IAAI,YAAY,OAAO;KACzB;KACA,OAAO,SAAS,cAA2B,qDAAiD;IAC9F;IACA,IAAI,WAAW;IACf,IAAI,YAAY;IAChB,IAAI,cAA6B,CAAC;IAClC,IAAI,kBAAiC,CAAC;IACtC,MAAM,aAAmB;KACvB,MAAM,QAAQ,UAAU;KACxB,IAAI,KAAK;KACT,IAAI,MAAM;KACV,MAAM,aAA4B,CAAC;KACnC,MAAM,eAA8B,CAAC;KACrC,KAAK,MAAM,QAAQ,OAAO;MAIxB,MAAM,UAAU,YAAY,IAAI;MAChC,IAAI,YAAY,QAAQ,QAAQ,aAAa,eAAe,MAAM,QAAQ;MAC1E,MAAM,OAAO,KAAK,sBAAsB;MAExC,IAAI,KAAK,UAAU,KAAK,KAAK,WAAW,GAAG;MAE3C,qBAAqB,MADD,QAAQ,sBACS,GAAG,KAAK,IAAI,KAAK,OAAO,aAAa,EAAE,GAAG,GAAG;MAClF,aAAa,KAAK,IAAI;MACtB,IAAI,KAAK,cAAc,wBAAsB,GAAG;OAC9C,WAAW,KAAK,IAAI;OACpB,IAAI,OAAO,SAAS;QAClB,wBAAwB,IAAI;QAC5B,KAAK,OAAO;QACZ,KAAK,MAAM,KAAK,KAAK,iBAA8B,wBAAsB,GACvE,OAAO,EAAE,aAAa,UAAU;OAEpC;MACF;KACF;KACA,KAAK,MAAM,YAAY,iBAAiB;MACtC,IAAI,aAAa,SAAS,QAAQ,GAAG;MACrC,gBAAgB,QAAQ;MACxB,kBAAkB,QAAQ;KAC5B;KACA,kBAAkB;KAClB,IAAI,CAAC,OAAO,SAAS;MACnB,KAAK,MAAM,QAAQ,YAAY,kBAAkB,IAAI;MACrD,WAAW;MACX,YAAY;MACZ,cAAc,CAAC;MACf;KACF;KAIA,MAAM,UAAU,WAAW,MAAM,MAAM,CAAC,YAAY,SAAS,CAAC,CAAC;KAC/D,IAAI,KAAK,MAAM,WAAW,OAAO,YAAY,QAAQ,YAAY;MAC/D,KAAK,MAAM,QAAQ,YAAY,iBAAiB,IAAI;MACpD,WAAW;MACX,YAAY;MACZ,cAAc;KAChB;IACF;IACA,KAAK;IACL,MAAM,KAAK,IAAI,uBAAuB,sBAAsB,IAAI,CAAC;IACjE,GAAG,QAAQ,SAAS,iBAAiB;KAAE,WAAW;KAAM,SAAS;IAAK,CAAC;IACvE,OAAO,iBAAiB,UAAU,IAAI;IACtC,OAAO,iBAAiB,UAAU,IAAI;IACtC,OAAO,iBAAiB,UAAU,MAAM,IAAI;IAC5C,aAAa;KACX,GAAG,WAAW;KACd,OAAO,oBAAoB,UAAU,IAAI;KACzC,OAAO,oBAAoB,UAAU,IAAI;KACzC,OAAO,oBAAoB,UAAU,MAAM,IAAI;IACjD;GACF,GAAG,kCAAkC;EACvC;;;;;;EAOA,SAAS,4BAA4B,KAA0B;GAC7D,IAAI,aAAa;IACf,MAAM,SAAS,OAAO,WAAW,YAAY;IAC7C,MAAM,aAAmB;KACvB,IAAI,CAAC,OAAO,SAAS;KACrB,MAAM,SAAS,SAAS,iBAA8B,2BAAyB;KAC/E,KAAK,MAAM,SAAS,MAAM,KAAK,MAAM,GAAG;MACtC,MAAM,OAAO,MAAM;MACnB,IAAI,SAAS,QAAQ,CAAC,KAAK,UAAU,SAAS,aAAa,GAAG;MAC9D,MAAM,WAAW,KAAK,sBAAsB;MAC5C,IAAI,SAAS,UAAU,KAAK,SAAS,WAAW,GAAG;MACnD,MAAM,MAAM;MACZ,MAAM,MAAM,YAAY,YAAY,SAAS,WAAW;MACxD,MAAM,MAAM,YAAY,OAAO,QAAQ,WAAW;MAClD,MAAM,MAAM,YAAY,UAAU,GAAG,OAAO,cAAc,SAAS,MAAM,IAAI,KAAK,WAAW;MAC7F,MAAM,MAAM,YAAY,QAAQ,QAAQ,WAAW;MACnD,MAAM,MAAM,YAAY,SAAS,GAAG,KAAK,IAAI,KAAK,OAAO,aAAa,SAAS,KAAK,EAAE,KAAK,WAAW;MACtG,MAAM,MAAM,YAAY,cAAc,GAAG,KAAK,IAAI,KAAK,SAAS,MAAM,EAAO,EAAE,KAAK,WAAW;MAC/F,MAAM,MAAM,YAAY,cAAc,QAAQ,WAAW;KAC3D;IACF;IACA,KAAK;IACL,MAAM,KAAK,IAAI,uBAAuB,sBAAsB,IAAI,CAAC;IACjE,GAAG,QAAQ,SAAS,iBAAiB;KAAE,WAAW;KAAM,SAAS;IAAK,CAAC;IACvE,OAAO,iBAAiB,UAAU,IAAI;IACtC,OAAO,iBAAiB,UAAU,IAAI;IACtC,OAAO,iBAAiB,UAAU,MAAM,IAAI;IAC5C,aAAa;KACX,GAAG,WAAW;KACd,OAAO,oBAAoB,UAAU,IAAI;KACzC,OAAO,oBAAoB,UAAU,IAAI;KACzC,OAAO,oBAAoB,UAAU,MAAM,IAAI;IACjD;GACF,GAAG,qCAAqC;EAC1C;EAEA,SAAS,gCAAgC,KAA0B;GACjE,IAAI,aAAa;IACf,MAAM,SAAS,OAAO,WAAW,YAAY;IAC7C,MAAM,cAAc,UAA8B;KAChD,IAAI,CAAC,OAAO,WAAW,EAAE,MAAM,kBAAkB,UAAU;KAE3D,MAAM,WADW,MAAM,OAAO,QAAQ,QACd,CAAC,EAAE,cAAmC,wBAAwB;KACtF,IAAI,CAAC,YAAY,SAAS,UAAU;KACpC,SAAS,YAAY;KACrB,SAAS,MAAM,EAAE,eAAe,KAAK,CAAC;KACtC,IAAI;MAEF,UAD+F,iBAC9E,OAAO;KAC1B,QAAQ,CAER;IACF;IACA,SAAS,iBAAiB,eAAe,YAAY,IAAI;IACzD,aAAa,SAAS,oBAAoB,eAAe,YAAY,IAAI;GAC3E,GAAG,mCAAmC;EACxC;;EASA,SAAS,aAAa,EAAE,iBAAgD;GACtE,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;IAAQ,MAAK;IAAS,oBAAiB;IAAS,cAAW;IAAO,OAAM;IAAO,eAAe,cAAc;IAC1G,UAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,OAAM;KAAK,QAAO;KAAK,SAAQ;KAAY,MAAK;KAAO,OAAM;KAAlE,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,GAAE;MAAM,GAAE;MAAM,OAAM;MAAK,QAAO;MAAK,IAAG;MAAI,QAAO;MAAe,aAAY;KAAO,CAAA,GAC7F,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,GAAE;MAAY,QAAO;MAAe,aAAY;KAAO,CAAA,CAC1D;;GACC,CAAA;EAEZ;EAEA,MAAM,iBACJ;;;;;EASF,SAAS,WAAW,KAAoB,eAAiC;GACvE,IAAI,aAAa;IACf,MAAM,SAAS,OAAO,WAAW,YAAY;IAC7C,MAAM,WAAW;IACjB,MAAM,kBAA2B,SAAS,cAAc,yBAAuB,MAAM;IACrF,MAAM,mBAA4B;KAChC,MAAM,QAAQ,SAAS;KACvB,OAAO,UAAU,QAAQ,CAAC,MAAM,aAAa,cAAc;IAC7D;IACA,IAAI,MAAgC;IACpC,MAAM,aAAmB;KACvB,IAAI,CAAC,OAAO,WAAW,CAAC,UAAU,KAAK,WAAW,GAAG;MACnD,IAAI,QAAQ,MAAM;OAChB,IAAI,OAAO;OACX,MAAM;MACR;MACA;KACF;KACA,MAAM,QAAQ,SAAS;KACvB,IAAI,UAAU,MAAM;KACpB,IAAI,QAAQ,QAAQ,IAAI,kBAAkB,OAAO;KACjD,KAAK,OAAO;KACZ,MAAM,SAAS,cAAc,QAAQ;KACrC,IAAI,OAAO;KACX,IAAI,aAAa,YAAY,QAAQ;KACrC,IAAI,aAAa,cAAc,MAAM;KACrC,IAAI,aAAa,SAAS,MAAM;KAChC,IAAI,YAAY;KAChB,IAAI,iBAAiB,SAAS,aAAa;KAC3C,MAAM,YAAY,GAAG;IACvB;IACA,KAAK;IACL,MAAM,KAAK,IAAI,iBAAiB,IAAI;IACpC,GAAG,QAAQ,SAAS,iBAAiB;KACnC,WAAW;KACX,SAAS;KACT,YAAY;KACZ,iBAAiB;MAAC;MAAc;MAA0B;KAAO;IACnE,CAAC;IACD,OAAO,iBAAiB,UAAU,IAAI;IACtC,aAAa;KACX,GAAG,WAAW;KACd,OAAO,oBAAoB,UAAU,IAAI;KACzC,KAAK,OAAO;IACd;GACF,GAAG,uBAAuB;EAC5B;;EAGA,SAAgB,cAAc,KAA0B;GACtD,cAAc,GAAG;GACjB,gCAAgC,GAAG;GACnC,gBAAgB,GAAG;GACnB,mBAAmB,GAAG;GACtB,iBAAiB,GAAG;GACpB,yBAAyB,GAAG;GAC5B,4BAA4B,GAAG;GAC/B,MAAM,SAAU,IAA2C;GAC3D,MAAM,QAAS,IAAyC;GACxD,IAAI,UAAU,OAAO,OAAO,kBAAkB,YAAY;IACxD,MAAM,sBAA4B,OAAO,cAAc;IACvD,0BAA0B,KAAK,aAAa;IAC5C,WAAW,KAAK,aAAa;GAC/B;GACA,IAAI,SAAS,QACX,MAAM,OAAO,6CACX,MAAM,SACJ;IACE,MAAM;IACN,IAAI;IACJ,OAAO;IACP,eAAe,EAAE,qBAAqB,OAAO,cAAc,EAAE;GAC/D,GACA,YACF,CACF;EAEJ;;;ECl2BA,IAAI;EAEJ,SAAgB,qBAAqB,KAA2B;GAC9D,mBAAmB;EACrB;EAEA,SAAS,wBAAwB,OAA0C;GACzE,MAAM,MAAM;GACZ,IAAI,CAAC,KAAK,OAAO,KAAA;GAEjB,OADc,IAAI,KAAK,YAAY,CAAC,CAAC,MACxB,MAAM,MAAM,EAAE,UAAU,KAAK;EAC5C;EAEA,MAAM,kBAAkB;EACxB,MAAM,mBAAmB;EACzB,MAAM,iBAAiB;EAEvB,SAAS,uBAAuB,aAAqB,gBAA8B;GACjF,IAAI,CAAC,aAAa;GAElB,MAAM,UAAU,SAAS,cAAc,KAAK;GAC5C,QAAQ,MAAM,UAAU;GAExB,MAAM,SAAS,SAAS,cAAc,KAAK;GAC3C,OAAO,aAAa,QAAQ,QAAQ;GACpC,OAAO,aAAa,cAAc,MAAM,eAAe,OAAO;GAC9D,OAAO,MAAM,UAAU;GAEvB,MAAM,QAAQ,SAAS,cAAc,IAAI;GACzC,MAAM,cAAc,UAAU;GAC9B,MAAM,MAAM,UAAU;GAEtB,MAAM,cAAc,SAAS,cAAc,KAAK;GAChD,YAAY,cAAc;GAC1B,YAAY,MAAM,UAAU;GAE5B,MAAM,WAAW,SAAS,cAAc,UAAU;GAClD,SAAS,cAAc;GACvB,SAAS,aAAa;GACtB,SAAS,MAAM,UAAU;GAEzB,MAAM,SAAS,SAAS,cAAc,KAAK;GAC3C,OAAO,MAAM,UAAU;GAEvB,MAAM,UAAU,SAAS,cAAc,KAAK;GAC5C,QAAQ,MAAM,UAAU;GACxB,MAAM,SAAS,SAAS,cAAc,QAAQ;GAC9C,OAAO,OAAO;GACd,OAAO,cAAc;GACrB,OAAO,MAAM,UAAU;GACvB,MAAM,OAAO,SAAS,cAAc,QAAQ;GAC5C,KAAK,OAAO;GACZ,KAAK,cAAc;GACnB,KAAK,MAAM,UAAU;GAErB,MAAM,cAAoB,QAAQ,OAAO;GACzC,OAAO,iBAAiB,SAAS,KAAK;GACtC,QAAQ,iBAAiB,UAAU,UAAU;IAC3C,IAAI,MAAM,WAAW,SAAS,MAAM;GACtC,CAAC;GACD,OAAO,iBAAiB,UAAU,UAAU,MAAM,gBAAgB,CAAC;GACnE,SAAS,iBAAiB,eAAe;IACvC,MAAM,QAAQ,IAAI,YAAY,CAAC,CAAC,OAAO,SAAS,KAAK,CAAC,CAAC;IACvD,OAAO,cAAc,GAAG,MAAM;IAC9B,OAAO,MAAM,QAAQ,QAAQ,QAAQ,yCAAyC;GAChF,CAAC;GACD,KAAK,iBAAiB,eAAe;IACnC,CAAM,YAAY;KAChB,MAAM,QAAQ,IAAI,YAAY,CAAC,CAAC,OAAO,SAAS,KAAK,CAAC,CAAC;KACvD,IAAI,QAAQ,OAAO;MACjB,OAAO,cAAc,sBAAsB,MAAM;MACjD,OAAO,MAAM,QAAQ;MACrB;KACF;KACA,KAAK,WAAW;KAChB,KAAK,cAAc;KACnB,IAAI;MACF,MAAM,WAAW,OAAO,QAAQ,QAAQ,YAAY,GAAG;MACvD,MAAM,WAAW,MAAM,MAAM,0BAA0B,eAAe;OACpE,QAAQ;OACR,SAAS,EAAE,gBAAgB,mBAAmB;OAC9C,MAAM,KAAK,UAAU;QAAE,MAAM,SAAS;QAAO,kBAAkB;OAAS,CAAC;MAC3E,CAAC;MACD,IAAI,CAAC,SAAS,IAAI;OAChB,MAAM,OAAO,MAAM,SAAS,KAAK,CAAC,CAAC,aAAa,CAAC,EAAE;OACnD,OAAO,cAAc,KAAK,SAAS,SAAS,SAAS,OAAO;OAC5D,OAAO,MAAM,QAAQ;OACrB;MACF;MACA,MAAM;KACR,QAAQ;MACN,OAAO,cAAc;MACrB,OAAO,MAAM,QAAQ;KACvB,UAAU;MACR,KAAK,WAAW;MAChB,KAAK,cAAc;KACrB;IACF,EAAA,CAAG;GACL,CAAC;GAED,QAAQ,OAAO,QAAQ,IAAI;GAC3B,OAAO,OAAO,OAAO,aAAa,UAAU,QAAQ,OAAO;GAC3D,QAAQ,OAAO,MAAM;GACrB,SAAS,KAAK,OAAO,OAAO;GAE5B,OAAO,cAAc;GACrB,MAAW,0BAA0B,aAAa,CAAC,CAChD,KAAK,OAAO,aAAa;IACxB,IAAI,CAAC,SAAS,IAAI,MAAM,IAAI,MAAM,SAAS,SAAS,OAAO,EAAE;IAC7D,OAAO,SAAS,KAAK;GACvB,CAAC,CAAC,CACD,MAAM,SAAS;IACd,SAAS,QAAQ,KAAK,QAAQ;IAC9B,QAAQ,QAAQ,WAAW,OAAO,KAAK,YAAY,CAAC;IACpD,SAAS,cAAc,IAAI,MAAM,OAAO,CAAC;IACzC,SAAS,MAAM;GACjB,CAAC,CAAC,CACD,OAAO,UAAmB;IACzB,OAAO,cAAc,iBAAiB,QAAQ,MAAM,UAAU;IAC9D,OAAO,MAAM,QAAQ;GACvB,CAAC;EACL;EAEA,SAAgB,iCAAiC,KAA0B;GACzE,MAAM,MAAO,IAAmD;GAChE,IAAI,KAAK,qBAAqB,GAAG;GAEjC,IAAI,uBAAuB;GAE3B,MAAM,oBAAoB,OAAwC;IAChE,IAAI,OAAO,cAAc,cAAc,KAAK;IAC5C,OAAO,MAAM;KACX,IAAI,KAAK,aAAa,OAAO,KAAK,cAAc,YAAY,KAAK,UAAU,SAAS,YAAY,GAC9F,OAAO;KAET,OAAO,KAAK;IACd;IACA,OAAO;GACT;GAEA,MAAM,eAAe,QAAoC;IACvD,MAAM,UAAU,IAAI,cAAc,oBAAkB;IACpD,IAAI,CAAC,SAAS,OAAO;IACrB,OAAO,QAAQ,eAAe;GAChC;GAEA,MAAM,kBAAkB,kBAAqC;IAC3D,IAAI,cAAc,aAAa,gBAAgB,KAAK,cAAc,cAAc,IAAI,eAAe,EAAE,GAAG;IACxG,cAAc,aAAa,kBAAkB,GAAG;IAEhD,MAAM,gBAAgB,cAAc,iBAAiB,6BAA2B;IAChF,IAAI,UAA0B;IAC9B,KAAK,MAAM,QAAQ,MAAM,KAAK,aAAa,GAAG;KAC5C,MAAM,OAAO,KAAK,eAAe;KACjC,IAAI,KAAK,SAAS,KAAK,KAAK,KAAK,SAAS,QAAQ,GAAG;MACnD,UAAU;MACV;KACF;IACF;IACA,IAAI,CAAC,SAAS,UAAU,cAAc,cAAc,SAAS;IAC7D,IAAI,CAAC,SAAS;IAEd,MAAM,MAAM,SAAS,cAAc,QAAQ;IAC3C,IAAI,OAAO;IACX,IAAI,aAAa,QAAQ,UAAU;IACnC,IAAI,aAAa,gBAAgB,GAAG;IACpC,IAAI,mBAAmB,aAAa;KAClC,IAAI,YAAY,QAAQ,aAAa;KACrC,IAAI,MAAM,UAAU,QAAQ,MAAM;IACpC;IACA,KAAK,MAAM,aAAa,MAAM,KAAK,IAAI,SAAS,GAC9C,IAAI,iBAAiB,KAAK,SAAS,GAAG,IAAI,UAAU,OAAO,SAAS;IAEtE,IAAI,MAAM,QAAQ;IAClB,IAAI,MAAM,UAAU;IACpB,IAAI,MAAM,aAAa;IACvB,IAAI,MAAM,MAAM;IAEhB,MAAM,OAAO,SAAS,gBAAgB,8BAA8B,KAAK;IACzE,KAAK,aAAa,SAAS,IAAI;IAC/B,KAAK,aAAa,UAAU,IAAI;IAChC,KAAK,aAAa,WAAW,WAAW;IACxC,KAAK,aAAa,QAAQ,MAAM;IAChC,KAAK,aAAa,eAAe,MAAM;IACvC,KAAK,MAAM,OAAO;IAClB,MAAM,OAAO,SAAS,gBAAgB,8BAA8B,MAAM;IAC1E,KAAK,aAAa,KAAK,0IAA0I;IACjK,KAAK,aAAa,QAAQ,cAAc;IACxC,KAAK,OAAO,IAAI;IAChB,MAAM,QAAQ,SAAS,cAAc,MAAM;IAC3C,MAAM,cAAc;IACpB,IAAI,OAAO,MAAM,KAAK;IACtB,IAAI,iBAAiB,UAAU,MAAM;KACnC,EAAE,gBAAgB;KAClB,EAAE,eAAe;KAEjB,wBADW,uBAAuB,wBAAwB,oBAAoB,IAAI,KAAA,EAAA,EACvD,eAAe,IAAI,wBAAwB,SAAS;IACjF,CAAC;IAED,QAAQ,eAAe,aAAa,KAAK,QAAQ,WAAW;GAC9D;GAoCA,IAlCqB,uBAAuB;IAC1C,MAAM,cAAc,SAAS,iBAAiB,yBAAuB;IACrE,KAAK,MAAM,OAAO,MAAM,KAAK,WAAW,GAAG;KACzC,MAAM,QAAQ;KACd,IAAI,MAAM,aAAa,eAAe,GAAG;KACzC,MAAM,aAAa,iBAAiB,GAAG;KACvC,MAAM,WAAW,MAAM,iBAAiB,+BAA6B;KACrE,KAAK,MAAM,OAAO,MAAM,KAAK,QAAQ,GAAG;MACtC,MAAM,QAAQ,IAAI,aAAa,YAAY,KAAK;MAChD,IAAI,MAAM,SAAS,WAAW,KAAK,MAAM,SAAS,IAAI,KAAK,MAAM,SAAS,SAAS,GACjF,IAAI,iBAAiB,eAAe;OAClC,MAAM,QAAQ,YAAY,KAAK;OAC/B,IAAI,OAAO,uBAAuB;MACpC,CAAC;KAEL;IACF;IAEA,MAAM,YAAY,SAAS,iBAAiB,qBAAmB;IAC/D,KAAK,MAAM,QAAQ,MAAM,KAAK,SAAS,GAAG;KACxC,MAAM,OAAO,KAAK,eAAe;KACjC,IAAI,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,QAAQ,KAAK,KAAK,SAAS,KAAK,KAAK,KAAK,SAAS,QAAQ,GAAG;MACrG,MAAM,YAAY,KAAK,QAAQ,iBAAe,KAAK,KAAK;MACxD,IAAI,qBAAqB,eAAe,CAAC,UAAU,aAAa,gBAAgB,GAAG;OACjF,MAAM,MAAM,iBAAiB,SAAS;OACtC,IAAI,KAAK;QACP,MAAM,QAAQ,YAAY,GAAG;QAC7B,IAAI,OAAO,uBAAuB;OACpC;OACA,eAAe,SAAS;MAC1B;KACF;IACF;GACF,CACO,CAAC,CAAC,QAAQ,SAAS,MAAM;IAAE,WAAW;IAAM,SAAS;GAAK,CAAC;EACpE;;;ECpPA,MAAM,aAAa;EAgDnB,MAAM,aAAwB;GAC5B,MAAM;GACN,MAAM;GACN,MAAM;GACN,MAAM;GACN,UAAU;GACV,UAAU;GACV,UAAU;GACV,YAAY;GACZ,YAAY;GACZ,SAAS;GACT,aAAa;GACb,YAAY;GACZ,cAAc;EAChB;EAIA,MAAM,aAA4B;GAChC,OAAO;GACP,WAAW;GACX,SAAS;GACT,QAAQ;GACR,QAAQ;GACR,cAAc;GACd,UAAU;GACV,YAAY;GACZ,YAAY;GACZ,OAAO;GACP,SAAS;EACX;EACA,MAAM,cAA6B;GACjC,WAAW;GACX,QAAQ;GACR,SAAS;GACT,cAAc;GACd,UAAU;GACV,YAAY;GACZ,YAAY;GACZ,QAAQ;GACR,QAAQ;GACR,SAAS;GACT,gBAAgB;GAChB,YAAY;GACZ,KAAK;EACP;EACA,MAAM,qBAAoC;GACxC,GAAG;GACH,YAAY;GACZ,OAAO;EACT;EACA,MAAM,uBAAsC;GAC1C,GAAG;GACH,QAAQ;GACR,OAAO;GACP,YAAY;EACd;EACA,MAAM,2BAA0C;GAC9C,GAAG;GACH,QAAQ;GACR,OAAO;GACP,YAAY;EACd;EAEA,SAAS,SAAS,WAAsC;GACtD,MAAM,CAAC,OAAO,aAAA,GAAYI,MAAAA,SAAAA,CAA4B,CAAC,CAAC;GACxD,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,IAAI,YAAY;IAChB,CAAM,YAAY;KAChB,IAAI;MACF,MAAM,MAAM,MAAM,MAAM,iBAAiB;MACzC,IAAI,CAAC,IAAI,IAAI;MACb,MAAM,OAAQ,MAAM,IAAI,KAAK;MAC7B,IAAI,CAAC,WAAW,SAAS,KAAK,SAAS,CAAC,CAAC;KAC3C,QAAQ,CAAC;IACX,EAAA,CAAG;IACH,aAAa;KACX,YAAY;IACd;GACF,GAAG,CAAC,SAAS,CAAC;GACd,OAAO;EACT;EAEA,SAAgB,YAAY,QAAwD;GAClF,MAAM,CAAC,WAAW,iBAAA,GAAgBA,MAAAA,SAAAA,CAAS,CAAC;GAC5C,MAAM,QAAQ,SAAS,SAAS;GAChC,MAAM,CAAC,YAAY,kBAAA,GAAiBA,MAAAA,SAAAA,CAAyB,KAAK;GAClE,MAAM,CAAC,MAAM,YAAA,GAAWA,MAAAA,SAAAA,CAAoB,UAAU;GACtD,MAAM,CAAC,QAAQ,cAAA,GAAaA,MAAAA,SAAAA,CAAiB,KAAA,CAAS;GACtD,MAAM,CAAC,MAAM,YAAA,GAAWA,MAAAA,SAAAA,CAAS,KAAK;GACtC,MAAM,CAAC,SAAS,eAAA,GAAcA,MAAAA,SAAAA,CAAS,KAAK;GAC5C,MAAM,CAAC,YAAY,kBAAA,GAAiBA,MAAAA,SAAAA,CAA6B,KAAA,CAAS;GAC1E,MAAM,CAAC,kBAAkB,wBAAA,GAAuBA,MAAAA,SAAAA,CAA+B,CAAC,CAAC;GACjF,MAAM,CAAC,YAAY,kBAAA,GAAiBA,MAAAA,SAAAA,CAAS,KAAK;GAElD,MAAM,SAAA,GAAQC,MAAAA,YAAAA,EAAa,MAAc;IACvC,UAAU,CAAC;IACX,IAAI,GAAG,iBAAiB,UAAU,KAAA,CAAS,GAAG,GAAI;GACpD,GAAG,CAAC,CAAC;GAEL,MAAM,UAAA,GAASA,MAAAA,YAAAA,OAAkB,cAAc,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;GAE/D,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,CAAM,YAAY;KAChB,IAAI;MACF,MAAM,MAAM,MAAM,MAAM,sBAAsB;MAC9C,IAAI,CAAC,IAAI,IAAI;MACb,MAAM,OAAQ,MAAM,IAAI,KAAK;MAC7B,oBAAoB,KAAK,WAAW,CAAC,CAAC;KACxC,QAAQ,CAAC;IACX,EAAA,CAAG;GACL,GAAG,CAAC,CAAC;GAEL,MAAM,cAAA,GAAaA,MAAAA,YAAAA,EAChB,OAAuB;IACtB,cAAc,EAAE;IAChB,cAAc,KAAA,CAAS;IACvB,WAAW,KAAK;IAChB,cAAc,KAAK;IACnB,IAAI,OAAO,OAAO;KAChB,QAAQ,UAAU;KAClB;IACF;IACA,MAAM,OAAO,MAAM,MAAM,MAAM,EAAE,OAAO,EAAE;IAC1C,IAAI,CAAC,MAAM;IACX,QAAQ;KACN,MAAM,KAAK;KACX,MAAM,KAAK;KACX,MAAM,KAAK,KAAK,QAAQ;KACxB,MAAM,OAAO,KAAK,KAAK,QAAQ,EAAE;KACjC,UAAU,KAAK,KAAK,YAAY;KAChC,UAAU,KAAK,KAAK,KAAK,QAAQ;KACjC,UAAU;KACV,YAAY;KACZ,YAAY;KACZ,SAAS,KAAK,KAAK,KAAK,WAAW;KACnC,aAAa,KAAK,QAAQ,SAAS;KACnC,YAAY,KAAK,QAAQ,WAAW,QAAQ,OAAO,OAAO,KAAK,QAAQ,WAAW,IAAI,IAAI;KAC1F,cAAc,KAAK,QAAQ,WAAW,YAAY,OAAO,OAAO,KAAK,QAAQ,WAAW,QAAQ,IAAI;IACtG,CAAC;GACH,GACA,CAAC,KAAK,CACR;GAEA,MAAM,mBAAA,GAAkBA,MAAAA,YAAAA,EAAa,UAA8B;IACjE,SAAS,OAAO;KACd,GAAG;KACH,MAAM;KACN,MAAM,MAAM;KACZ,MAAM,OAAO,MAAM,IAAI;KACvB,UAAU,MAAM;KAChB,UAAU,MAAM,kBAAkB,QAAQ,EAAE;KAC5C,SAAS,MAAM,gBAAgB,EAAE;KACjC,MAAM,EAAE,QAAQ,MAAM;IACxB,EAAE;IACF,cAAc,KAAA,CAAS;IACvB,MAAM;KAAE,MAAM;KAAM,MAAM,uBAAuB,MAAM;IAAO,CAAC;GACjE,GAAG,CAAC,KAAK,CAAC;GAEV,MAAM,QAAA,GAAOA,MAAAA,YAAAA,CAAY,YAAY;IACnC,IAAI,CAAC,KAAK,KAAK,KAAK,GAAG;KACrB,MAAM;MAAE,MAAM;MAAS,MAAM;KAAU,CAAC;KACxC;IACF;IACA,QAAQ,IAAI;IACZ,IAAI;KACF,MAAM,WAAW,KAAK,SAAS,gBAAgB,KAAK,SAAS;KAC7D,MAAM,WAAW,KAAK,SAAS,kBAAkB,KAAK,SAAS;KAC/D,MAAM,UAAmC;MACvC,MAAM,KAAK,KAAK,KAAK;MACrB,MAAM,KAAK;MACX,KAAK,WACD;OACE,MAAM,KAAK,KAAK,KAAK;OACrB,MAAM,OAAO,KAAK,IAAI,KAAK;OAC3B,UAAU,KAAK,SAAS,KAAK;OAC7B,MAAM;QAAE,MAAM,KAAK;QAAU,GAAI,KAAK,QAAQ,KAAK,IAAI,EAAE,SAAS,KAAK,QAAQ,KAAK,EAAE,IAAI,CAAC;OAAG;MAChG,IACA,KAAA;MACJ,SAAS,WACL;OACE,GAAI,KAAK,WAAW,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;OACnD,GAAI,KAAK,aAAa,EAAE,YAAY,KAAK,WAAW,IAAI,CAAC;OACzD,GAAI,KAAK,aAAa,EAAE,YAAY,KAAK,WAAW,IAAI,CAAC;MAC3D,IACA,KAAA;MACJ,QAAQ,WACJ;OACE,MAAM;OACN,GAAI,KAAK,YAAY,KAAK,IAAI,EAAE,OAAO,KAAK,YAAY,KAAK,EAAE,IAAI,CAAC;OACpE,GAAI,KAAK,aAAa,EAAE,WAAW,EAAE,MAAM,OAAO,KAAK,UAAU,KAAK,KAAA,EAAU,EAAE,IAAI,CAAC;OACvF,GAAI,KAAK,eAAe,EAAE,WAAW,EAAE,UAAU,OAAO,KAAK,YAAY,KAAK,KAAA,EAAU,EAAE,IAAI,CAAC;OAC/F,GAAI,KAAK,cAAc,KAAK,eAAe,EAAE,WAAW;QAAE,MAAM,OAAO,KAAK,UAAU,KAAK,KAAA;QAAW,UAAU,OAAO,KAAK,YAAY,KAAK,KAAA;OAAU,EAAE,IAAI,CAAC;MAChK,IACA,KAAA;KACN;KACA,MAAM,MAAM,eAAe,QAAQ,oBAAoB,mBAAmB;KAC1E,MAAM,MAAM,MAAM,MAAM,KAAK;MAC3B,QAAQ,eAAe,QAAQ,SAAS;MACxC,SAAS,EAAE,gBAAgB,mBAAmB;MAC9C,MAAM,KAAK,UAAU,OAAO;KAC9B,CAAC;KACD,MAAM,OAAQ,MAAM,IAAI,KAAK;KAC7B,IAAI,IAAI,MAAM,KAAK,IAAI;MACrB,MAAM;OAAE,MAAM;OAAM,MAAM,eAAe,QAAQ,UAAU;MAAQ,CAAC;MACpE,OAAO;MACP,IAAI,KAAK,MAAM,cAAc,KAAK,KAAK,EAAE;KAC3C,OACE,MAAM;MAAE,MAAM;MAAS,MAAM,KAAK,SAAS;KAAO,CAAC;IAEvD,QAAQ;KACN,MAAM;MAAE,MAAM;MAAS,MAAM;KAAO,CAAC;IACvC,UAAU;KACR,QAAQ,KAAK;IACf;GACF,GAAG;IAAC;IAAM;IAAY;IAAO;GAAM,CAAC;GAEpC,MAAM,UAAA,GAASA,MAAAA,YAAAA,CAAY,YAAY;IACrC,IAAI,eAAe,OAAO;IAC1B,QAAQ,IAAI;IACZ,IAAI;KACF,MAAM,MAAM,MAAM,MAAM,mBAAmB,cAAc,EAAE,QAAQ,SAAS,CAAC;KAC7E,MAAM,OAAQ,MAAM,IAAI,KAAK;KAC7B,IAAI,IAAI,MAAM,KAAK,IAAI;MACrB,MAAM;OAAE,MAAM;OAAM,MAAM;MAAQ,CAAC;MACnC,cAAc,KAAK;MACnB,QAAQ,UAAU;MAClB,OAAO;KACT,OACE,MAAM;MAAE,MAAM;MAAS,MAAM,KAAK,SAAS;KAAO,CAAC;IAEvD,QAAQ;KACN,MAAM;MAAE,MAAM;MAAS,MAAM;KAAO,CAAC;IACvC,UAAU;KACR,QAAQ,KAAK;IACf;GACF,GAAG;IAAC;IAAY;IAAO;GAAM,CAAC;GAE9B,MAAM,QAAA,GAAOA,MAAAA,YAAAA,CAAY,YAAY;IACnC,IAAI,KAAK,SAAS,cAAc;KAC9B,MAAM;MAAE,MAAM;MAAS,MAAM;KAAa,CAAC;KAC3C;IACF;IACA,MAAM,WAAW,KAAK,SAAS,gBAAgB,KAAK,SAAS;IAC7D,IAAI,YAAY,CAAC,KAAK,KAAK,KAAK,GAAG;KACjC,MAAM;MAAE,MAAM;MAAS,MAAM;KAAU,CAAC;KACxC;IACF;IACA,WAAW,IAAI;IACf,cAAc,KAAA,CAAS;IACvB,IAAI;KACF,MAAM,UAAU,WAAW;MACzB,KAAK;OACH,MAAM,KAAK,KAAK,KAAK;OACrB,MAAM,OAAO,KAAK,IAAI,KAAK;OAC3B,UAAU,KAAK,SAAS,KAAK;OAC7B,MAAM;QAAE,MAAM,KAAK;QAAU,GAAI,KAAK,QAAQ,KAAK,IAAI,EAAE,SAAS,KAAK,QAAQ,KAAK,EAAE,IAAI,CAAC;OAAG;MAChG;MACA,SAAS;OACP,GAAI,KAAK,WAAW,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;OACnD,GAAI,KAAK,aAAa,EAAE,YAAY,KAAK,WAAW,IAAI,CAAC;OACzD,GAAI,KAAK,aAAa,EAAE,YAAY,KAAK,WAAW,IAAI,CAAC;MAC3D;KACF,IAAI,CAAC;KACL,MAAM,MAAM,eAAe,QAAQ,iCAAiC,mBAAmB,WAAW;KAOlG,MAAM,KAAI,OADU,MALF,MAAM,KAAK;MAC3B,QAAQ;MACR,SAAS,EAAE,gBAAgB,mBAAmB;MAC9C,MAAM,KAAK,UAAU,OAAO;KAC9B,CAAC,EAAA,CACuB,KAAK,EAAA,CACd;KACf,IAAI,GAAG,MAAM,EAAE,WACb,cAAc,MAAM;UACf;MACL,MAAM,MAAM,GAAG,WAAW,IAAI,EAAE,SAAS,KAAK;MAC9C,cAAc,GAAG,GAAG,SAAS,SAAS,KAAK;KAC7C;KACA,OAAO;IACT,QAAQ;KACN,cAAc,MAAM;IACtB,UAAU;KACR,WAAW,KAAK;IAClB;GACF,GAAG;IAAC;IAAM;IAAY;GAAM,CAAC;GAE7B,MAAM,gBAAA,GAAeA,MAAAA,YAAAA,CAAY,OAAO,WAAuD;IAC7F,IAAI,eAAe,OAAO;IAC1B,IAAI,WAAW,aAAa;KAC1B,cAAc,IAAI;KAClB,IAAI;MACF,MAAM,MAAM,MAAM,MAAM,oBAAoB,WAAW,aAAa,EAAE,QAAQ,OAAO,CAAC;MACtF,MAAM,OAAQ,MAAM,IAAI,KAAK;MAC7B,IAAI,IAAI,MAAM,KAAK,IACjB,MAAM;OAAE,MAAM;OAAM,MAAM,SAAS,KAAK,aAAa,MAAM,GAAG,EAAE,KAAK;MAAK,CAAC;WAE3E,MAAM;OAAE,MAAM;OAAS,MAAM,KAAK,SAAS;MAAO,CAAC;MAErD,OAAO;KACT,QAAQ;MACN,MAAM;OAAE,MAAM;OAAS,MAAM;MAAO,CAAC;KACvC,UAAU;MACR,cAAc,KAAK;KACrB;KACA;IACF;IACA,cAAc,IAAI;IAClB,IAAI;KACF,MAAM,MAAM,MAAM,MAAM,oBAAoB,WAAW,GAAG,UAAU,EAAE,QAAQ,OAAO,CAAC;KACtF,MAAM,OAAQ,MAAM,IAAI,KAAK;KAC7B,IAAI,IAAI,MAAM,KAAK,IACjB,MAAM;MAAE,MAAM;MAAM,MAAM,WAAW,YAAY,UAAU,WAAW,SAAS,UAAU;KAAQ,CAAC;UAElG,MAAM;MAAE,MAAM;MAAS,MAAM,KAAK,SAAS;KAAO,CAAC;KAErD,OAAO;IACT,QAAQ;KACN,MAAM;MAAE,MAAM;MAAS,MAAM;KAAO,CAAC;IACvC,UAAU;KACR,cAAc,KAAK;IACrB;GACF,GAAG;IAAC;IAAY;IAAO;GAAM,CAAC;GAE9B,MAAM,eAAe,eAAe,QAAQ,KAAA,IAAY,MAAM,MAAM,MAAM,EAAE,OAAO,UAAU;GAE7F,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACA,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD,EAAA,UAAQ;;;;;;;;MAQC,CAAA,GACT,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAU;IAAoB,OAAO;KAAE,SAAS;KAAQ,KAAK;KAAI,WAAW;KAAK,UAAU;KAAU,UAAU;KAAQ,OAAO;KAAQ,WAAW;IAAa;IAAnK,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,OAAO;MAAE,OAAO;MAAK,YAAY;MAAG,aAAa;MAAwC,cAAc;KAAG;KAA/G,UAAA;MACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,eAAe,WAAW,KAAK;OAAG,OAAO;QAAE,GAAG;QAAoB,OAAO;QAAQ,cAAc;OAAG;OAAG,UAAA;MAEnH,CAAA;MACP,MAAM,KAAK,MACV,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAEE,eAAe,WAAW,EAAE,EAAE;OAC9B,OAAO;QACL,SAAS;QACT,cAAc;QACd,QAAQ;QACR,cAAc;QACd,YAAY,eAAe,EAAE,KAAK,kFAAkF;QACpH,UAAU;OACZ;OAVF,UAAA;QAYE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,OAAO,EAAE,YAAY,IAAI;SAAI,UAAA,EAAE;QAAU,CAAA;QAC9C,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAK,OAAO;UAAE,UAAU;UAAI,SAAS;UAAK,SAAS;UAAQ,YAAY;UAAU,KAAK;SAAE;SAAxF,UAAA;UACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EACE,OAAO;WACL,OAAO;WACP,QAAQ;WACR,cAAc;WACd,YAAY,EAAE,QAAQ,cAAc,OAAO,2CAA2C,EAAE,QAAQ,cAAc,QAAQ,yCAAyC;UACjK,EACD,CAAA;UACA,EAAE,SAAS,eAAe,aAAa,EAAE,SAAS,eAAe,WAAW,EAAE,SAAS,iBAAiB,cAAc,EAAE,SAAS,kBAAkB,cAAc,EAAE;UACpK,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;WAAM,OAAO;YAAE,YAAY;YAAG,OAAO,EAAE,QAAQ,cAAc,OAAO,2CAA2C,EAAE,QAAQ,cAAc,QAAQ,yCAAyC;WAAgC;WACrN,UAAA,EAAE,QAAQ,cAAc,OAAO,OAAO,EAAE,QAAQ,cAAc,QAAQ,OAAO;UAC1E,CAAA;SACH;;QACJ,EAAE,aACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,OAAO;UAAE,UAAU;UAAI,WAAW;UAAG,OAAO,EAAE,UAAU,UAAU,UAAU,2CAA2C,EAAE,UAAU,UAAU,WAAW,yCAAyC;SAAoC;SACvO,UAAA,EAAE,UAAU,UAAU,iBAAiB,WAAW,EAAE,UAAU,UAAU,UAAU,UAAU,UAAU,EAAE,UAAU,SAAS;QACzH,CAAA;OAEJ;MA/BE,GAAA,EAAE,EA+BJ,CACN;MACA,MAAM,WAAW,KAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,OAAO;QAAE,UAAU;QAAI,SAAS;OAAI;OAAG,UAAA;MAAS,CAAA;KACzE;IAEL,CAAA,GAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,OAAO;MAAE,MAAM;MAAG,UAAU;MAAK,UAAU;MAAG,UAAU;KAAS;KAAtE,UAAA,CACG,iBAAiB,SAAS,KACzB,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,OAAO,EAAE,cAAc,GAAG;MAA/B,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;OAAO,OAAO;QAAE,UAAU;QAAI,SAAS;QAAM,SAAS;QAAS,cAAc;OAAE;OAAG,UAAA;MAAyB,CAAA,GAC3G,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;OACE,OAAO;OACP,OAAM;OACN,WAAW,MAAM;QACf,MAAM,QAAQ,iBAAiB,OAAO,EAAE,OAAO,KAAK;QACpD,IAAI,OAAO,gBAAgB,KAAK;QAChC,EAAE,OAAO,QAAQ;OACnB;OAPF,UAAA,CASE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,OAAM;QAAG,UAAA;OAAa,CAAA,GAC7B,iBAAiB,KAAK,OAAO,MAC5B,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;QAAyB,OAAO;QAAhC,UAAA;SACG,MAAM;SAAK;SAAE,MAAM;SAAM,MAAM,WAAW,KAAK,MAAM,SAAS,KAAK;SAAI,MAAM,eAAe,QAAQ;QAC/F;OAFK,GAAA,MAAM,IAEX,CACT,CACK;MACL,CAAA,CAAA;KAGP,CAAA,GAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,OAAO;OAAE,SAAS;OAAQ,eAAe;OAAU,KAAK;MAAG;MAAhE,UAAA;OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;QAAO,OAAO;SAAE,SAAS;SAAQ,eAAe;SAAU,KAAK;SAAG,UAAU;QAAG;QAA/E,UAAA,CAAkF,QAEhF,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SAAO,OAAO;SAAY,OAAO,KAAK;SAAM,WAAW,MAAM,SAAS,OAAO;UAAE,GAAG;UAAG,MAAM,EAAE,OAAO;SAAM,EAAE;SAAG,aAAY;QAAU,CAAA,CAChI;;OACP,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;QAAO,OAAO;SAAE,SAAS;SAAQ,eAAe;SAAU,KAAK;SAAG,UAAU;QAAG;QAA/E,UAAA,CAAkF,QAEhF,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;SAAQ,OAAO;SAAY,OAAO,KAAK;SAAM,WAAW,MAAM,SAAS,OAAO;UAAE,GAAG;UAAG,MAAM,EAAE,OAAO;SAA2B,EAAE;SAAlI,UAAA;UACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WAAQ,OAAM;WAAa,UAAA;UAAkB,CAAA;UAC7C,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WAAQ,OAAM;WAAgB,UAAA;UAAyB,CAAA;UACvD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WAAQ,OAAM;WAAa,UAAA;UAAgB,CAAA;UAC3C,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WAAQ,OAAM;WAAe,UAAA;UAAoB,CAAA;SAC3C;QACH,CAAA,CAAA;;QAEL,KAAK,SAAS,gBAAgB,KAAK,SAAS,oBAC5C,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;QACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAK,WAAU;SAAgB,OAAO;UAAE,SAAS;UAAQ,KAAK;SAAG;SAAjE,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;UAAO,OAAO;WAAE,SAAS;WAAQ,eAAe;WAAU,KAAK;WAAG,UAAU;WAAI,MAAM;WAAG,UAAU;UAAE;UAArG,UAAA,CAAwG,QAEtG,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;WAAO,OAAO;WAAY,OAAO,KAAK;WAAM,WAAW,MAAM,SAAS,OAAO;YAAE,GAAG;YAAG,MAAM,EAAE,OAAO;WAAM,EAAE;WAAG,aAAY;UAAgB,CAAA,CACtI;SACP,CAAA,GAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;UAAO,OAAO;WAAE,SAAS;WAAQ,eAAe;WAAU,KAAK;WAAG,UAAU;WAAI,OAAO;UAAG;UAA1F,UAAA,CAA6F,MAE3F,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;WAAO,OAAO;WAAY,OAAO,KAAK;WAAM,WAAW,MAAM,SAAS,OAAO;YAAE,GAAG;YAAG,MAAM,EAAE,OAAO;WAAM,EAAE;UAAI,CAAA,CAC3G;SACJ,CAAA,CAAA;;QACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;SAAO,OAAO;UAAE,SAAS;UAAQ,eAAe;UAAU,KAAK;UAAG,UAAU;SAAG;SAA/E,UAAA,CAAkF,OAEhF,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;UAAO,OAAO;UAAY,OAAO,KAAK;UAAU,WAAW,MAAM,SAAS,OAAO;WAAE,GAAG;WAAG,UAAU,EAAE,OAAO;UAAM,EAAE;UAAG,aAAY;SAAQ,CAAA,CACtI;;QACP,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;SAAO,OAAO;UAAE,SAAS;UAAQ,eAAe;UAAU,KAAK;UAAG,UAAU;SAAG;SAA/E,UAAA,CAAkF,QAEhF,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;UAAQ,OAAO;UAAY,OAAO,KAAK;UAAU,WAAW,MAAM,SAAS,OAAO;WAAE,GAAG;WAAG,UAAU,EAAE,OAAO;UAA+B,EAAE;UAA9I,UAAA;WACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;YAAQ,OAAM;YAAW,UAAA;WAAU,CAAA;WACnC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;YAAQ,OAAM;YAAM,UAAA;WAAU,CAAA;WAC9B,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;YAAQ,OAAM;YAAQ,UAAA;WAAiB,CAAA;UACjC;SACH,CAAA,CAAA;;QACN,KAAK,aAAa,cACjB,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;SAAO,OAAO;UAAE,SAAS;UAAQ,eAAe;UAAU,KAAK;UAAG,UAAU;SAAG;SAA/E,UAAA;UAAkF;UAC7E,cAAc,UAAU,cAAc,iBAAiB;UAC1D,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;WAAO,OAAO;WAAY,MAAK;WAAW,OAAO,KAAK;WAAU,WAAW,MAAM,SAAS,OAAO;YAAE,GAAG;YAAG,UAAU,EAAE,OAAO;WAAM,EAAE;WAAG,cAAa;UAAgB,CAAA;SAC/J;;QAER,KAAK,aAAa,SACjB,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;SACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;UAAO,OAAO;WAAE,SAAS;WAAQ,eAAe;WAAU,KAAK;WAAG,UAAU;UAAG;UAA/E,UAAA;WAAkF;WAC3E,cAAc,UAAU,SAAS,iBAAiB;WACvD,iBAAA,GAAA,kBAAA,IAAA,CAAC,YAAD;YAAU,OAAO;aAAE,GAAG;aAAY,WAAW;aAAI,QAAQ;YAAW;YAAG,OAAO,KAAK;YAAY,WAAW,MAAM,SAAS,OAAO;aAAE,GAAG;aAAG,YAAY,EAAE,OAAO;YAAM,EAAE;YAAG,aAAY;WAAuC,CAAA;UACtN;;SACP,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;UAAO,OAAO;WAAE,SAAS;WAAQ,eAAe;WAAU,KAAK;WAAG,UAAU;UAAG;UAA/E,UAAA,CAAkF,qBAEhF,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;WAAO,OAAO;WAAY,MAAK;WAAW,OAAO,KAAK;WAAY,WAAW,MAAM,SAAS,OAAO;YAAE,GAAG;YAAG,YAAY,EAAE,OAAO;WAAM,EAAE;WAAG,cAAa;UAAgB,CAAA,CACnK;;SACP,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;UAAO,OAAO;WAAE,SAAS;WAAQ,eAAe;WAAU,KAAK;WAAG,UAAU;UAAG;UAA/E,UAAA,CAAkF,sBAEhF,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;WAAO,OAAO;WAAY,OAAO,KAAK;WAAS,WAAW,MAAM,SAAS,OAAO;YAAE,GAAG;YAAG,SAAS,EAAE,OAAO;WAAM,EAAE;WAAG,aAAY;UAAqB,CAAA,CACjJ;;QACP,EAAA,CAAA;OAEJ,EAAA,CAAA;QAGF,KAAK,SAAS,kBAAkB,KAAK,SAAS,oBAC9C,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;QAAO,OAAO;SAAE,SAAS;SAAQ,eAAe;SAAU,KAAK;SAAG,UAAU;QAAG;QAA/E,UAAA,CAAkF,QAEhF,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SAAO,OAAO;SAAY,OAAO,KAAK;SAAa,WAAW,MAAM,SAAS,OAAO;UAAE,GAAG;UAAG,aAAa,EAAE,OAAO;SAAM,EAAE;SAAG,aAAY;QAAiB,CAAA,CACrJ;OACP,CAAA,GAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAU;QAAgB,OAAO;SAAE,SAAS;SAAQ,KAAK;QAAG;QAAjE,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;SAAO,OAAO;UAAE,SAAS;UAAQ,eAAe;UAAU,KAAK;UAAG,UAAU;UAAI,MAAM;UAAG,UAAU;SAAE;SAArG,UAAA,CAAwG,cAEtG,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;UAAO,OAAO;UAAY,OAAO,KAAK;UAAY,WAAW,MAAM,SAAS,OAAO;WAAE,GAAG;WAAG,YAAY,EAAE,OAAO;UAAM,EAAE;UAAG,aAAY;SAAK,CAAA,CACvI;QACP,CAAA,GAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;SAAO,OAAO;UAAE,SAAS;UAAQ,eAAe;UAAU,KAAK;UAAG,UAAU;UAAI,MAAM;UAAG,UAAU;SAAE;SAArG,UAAA,CAAwG,aAEtG,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;UAAO,OAAO;UAAY,OAAO,KAAK;UAAc,WAAW,MAAM,SAAS,OAAO;WAAE,GAAG;WAAG,cAAc,EAAE,OAAO;UAAM,EAAE;UAAG,aAAY;SAAO,CAAA,CAC7I;QACJ,CAAA,CAAA;OACL,CAAA,CAAA,EAAA,CAAA;OAGH,eAAe,KAAA,KACd,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QAAK,OAAO;SAAE,UAAU;SAAI,OAAO,eAAe,SAAS,2CAA2C;QAAuC;QAAI,UAAA;OAAgB,CAAA;OAGnK,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,OAAO;SAAE,SAAS;SAAQ,KAAK;SAAI,WAAW;SAAG,UAAU;QAAO;QAAvE,UAAA;SACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,eAAe,KAAK,KAAK;UAAG,UAAU;UAAM,OAAO;UACtE,UAAA,eAAe,QAAQ,SAAS;SAC3B,CAAA;UACN,KAAK,SAAS,gBAAgB,KAAK,SAAS,mBAAoB,eAAe,SAAS,KAAK,SAAS,mBACtG,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,eAAe,KAAK,KAAK;UAAG,UAAU,QAAQ;UAAS,OAAO;UACjF,UAAA,UAAU,SAAS;SACd,CAAA;SAET,eAAe,UAAU,KAAK,SAAS,kBAAkB,KAAK,SAAS,oBACtE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;UACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WAAQ,MAAK;WAAS,eAAe,KAAK,aAAa,WAAW;WAAG,UAAU,QAAQ;WAAY,OAAO;WACvG,UAAA,aAAa,SAAS;UACjB,CAAA;UACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WAAQ,MAAK;WAAS,eAAe,KAAK,aAAa,SAAS;WAAG,UAAU,QAAQ;WAAY,OAAO;WACrG,UAAA,aAAa,SAAS;UACjB,CAAA;UACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WAAQ,MAAK;WAAS,eAAe,KAAK,aAAa,MAAM;WAAG,UAAU,QAAQ;WAAY,OAAO;WAClG,UAAA,aAAa,SAAS;UACjB,CAAA;SACR,EAAA,CAAA;SAEH,eAAe,SACd,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,eAAe,KAAK,OAAO;UAAG,UAAU;UAAM,OAAO;UAA0B,UAAA;SAE7F,CAAA;SAET,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,OAAO;WAAE,UAAU;WAAI,WAAW;WAAU,OAAO,OAAO,SAAS,OAAO,2CAA2C;UAAuC;UAAI,UAAA,OAAO;SAAW,CAAA;QAChM;;MACF;KACF,CAAA,CAAA;IACF,CAAA,CAAA;GACH,CAAA,CAAA,EAAA,CAAA;EAEN;EAEA,SAAgBC,QAAM,KAA0B;GAC9C,MAAM,cAAc,SAAS,cAAc,OAAO;GAClD,YAAY,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDzB,SAAS,KAAK,YAAY,WAAW;GAEtC,cAAc,GAAG;GAEjB,iCAAiC,GAAG;GAEpC,IAAI,OAAO;IACT,QAAQ,CAAC,OAAO;IAChB,QAAQ,QAA6B;KACnC,IAAI,MAAM,OAAO,0BACf,IAAI,MAAM,SAAS;MAAE,MAAM;MAAoB,IAAI;MAAY,OAAO;MAAK,aAAa;KAAO,GAAG,WAAW,CAC/G;KAGA,IAAI,MAAM,OAAO,mDACf,IAAI,MAAM,SAAS;MAAE,MAAM;MAA6C,UAAU;KAAI,GAAG,qBAAqB,CAChH;KACA,IAAI,MAAM,OAAO,0CACf,IAAI,MAAM,SAAS;MAAE,MAAM;MAAoC,UAAU;KAAI,GAAG,qBAAqB,CACvG;IACF;GACF,CAAC;GAED,MAAM,aAAc,IAA2E;GAC/F,IAAI,cAAc,OAAO,WAAW,aAAa,YAAY;IAC3D,MAAM,mBAAmB,WAAW,SAAS,KAAK,UAAU;IAC5D,WAAW,WAAW,OAAO,SAAgC;KAC3D,IAAI;MACF,MAAM,MAAM,MAAM,MAAM,+BAA+B,mBAAmB,IAAI,GAAG;MACjF,IAAI,IAAI,IAAI;OACV,MAAM,OAAQ,MAAM,IAAI,KAAK;OAC7B,IAAI,KAAK,OAAO;QACd,IAAI,KAAK,SAAS,QAAQ,OAAO,iBAAiB,IAAI;QACtD,MAAM,IAAI,SAAS,cAAc,GAAG;QACpC,EAAE,OAAO,8BAA8B,mBAAmB,IAAI;QAC9D,EAAE,WAAW;QACb,SAAS,KAAK,YAAY,CAAC;QAC3B,EAAE,MAAM;QACR,EAAE,OAAO;QACT;OACF;MACF;KACF,QAAQ,CAER;KACA,OAAO,iBAAiB,IAAI;IAC9B;GACF;GAEA,MAAM,WAAmC;IACvC,MAAM;IACN,cAAc;GAChB;GACA,MAAM,cAAsC;IAAE,MAAM;IAAQ,QAAQ;GAAa;GAiBjF,IAfqB,uBAAuB;IAC1C,MAAM,QAAQ,SAAS,iBAAiB,4BAA0B;IAClE,KAAK,MAAM,QAAQ,MAAM,KAAK,KAAK,GAAG;KACpC,MAAM,QAAQ,KAAK,cAAc,2BAAyB;KAC1D,IAAI,CAAC,OAAO;KACZ,MAAM,OAAO,MAAM,eAAe;KAClC,MAAM,UAAU,YAAY;KAC5B,IAAI,CAAC,SAAS;KACd,MAAM,WAAW,KAAK,cAAc,sBAAoB;KACxD,IAAI,CAAC,UAAU;KACf,IAAI,SAAS,aAAa,gBAAgB,MAAM,SAAS;KACzD,SAAS,YAAY,SAAS,YAAY;KAC1C,SAAS,aAAa,kBAAkB,OAAO;IACjD;GACF,CACO,CAAC,CAAC,QAAQ,SAAS,MAAM;IAAE,WAAW;IAAM,SAAS;GAAK,CAAC;EACpE;;;EC9rBA,MAAa,SAAS;GAAC;GAAc;GAAc;GAAS;GAAU;EAAc;EAEpF,SAAgB,MAAM,KAA0B;GAC9C,QAAU,GAAG;GACb,QAAQ,GAAG;EACb"}
1
+ {"version":3,"file":"client.js","names":["SECTION_ID","useState","useCallback","apply","inputStyle","buttonStyle","primaryButtonStyle","secondaryButtonStyle","useState","useCallback","useState","useCallback","apply"],"sources":["../src/client/auth.tsx","../src/client/directory-flow.tsx","../src/client/mobile.tsx","../src/client/workspace-instruction-menu.tsx","../src/client/ui.tsx","../src/client/index.tsx"],"sourcesContent":["import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { CSSProperties, ReactElement } from 'react'\nimport { useCallback, useEffect, useState } from 'react'\n\nexport const inject = ['connection']\n\nconst SECTION_ID = 'auth'\nconst MESSAGE_MS = 5000\n\nfunction useUsername(): [string | undefined, (username: string) => void] {\n const [username, setUsername] = useState<string | undefined>(undefined)\n useEffect(() => {\n let cancelled = false\n void (async () => {\n try {\n const res = await fetch('/api/auth/status')\n if (!res.ok) return\n const data = (await res.json()) as { username?: string }\n if (!cancelled && typeof data.username === 'string') setUsername(data.username)\n } catch {\n // best-effort\n }\n })()\n return () => {\n cancelled = true\n }\n }, [])\n return [username, setUsername]\n}\n\ntype Notice = { kind: 'ok' | 'error'; text: string; owner: 'username' | 'password' | 'account' }\n\nexport function AuthSection(_props: PropsRuntime<'settings.section'>): ReactElement {\n const [username, setUsername] = useUsername()\n const [newUsername, setNewUsername] = useState('')\n const [usernamePassword, setUsernamePassword] = useState('')\n const [oldPassword, setOldPassword] = useState('')\n const [newPassword, setNewPassword] = useState('')\n const [confirm, setConfirm] = useState('')\n const [busy, setBusy] = useState(false)\n const [notice, setNotice] = useState<Notice | undefined>(undefined)\n const [confirmingSignOut, setConfirmingSignOut] = useState(false)\n\n const flash = useCallback((n: Notice | undefined) => {\n setNotice(n)\n if (n !== undefined) setTimeout(() => setNotice(undefined), MESSAGE_MS)\n }, [])\n\n const signOut = useCallback(async () => {\n setBusy(true)\n try {\n await fetch('/api/auth/logout', { method: 'POST' })\n window.location.href = '/login'\n } catch {\n setBusy(false)\n setConfirmingSignOut(false)\n flash({ kind: 'error', text: '退出失败,请重试', owner: 'account' })\n }\n }, [flash])\n\n const changePassword = useCallback(async () => {\n if (newPassword !== confirm) {\n flash({ kind: 'error', text: '两次输入的新密码不一致', owner: 'password' })\n return\n }\n setBusy(true)\n try {\n const res = await fetch('/api/auth/change-password', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ currentPassword: oldPassword, password: newPassword }),\n })\n const data = (await res.json()) as { error?: string }\n if (res.ok) {\n setOldPassword('')\n setNewPassword('')\n setConfirm('')\n flash({ kind: 'ok', text: '密码已修改', owner: 'password' })\n } else {\n flash({ kind: 'error', text: data.error ?? '修改失败,请重试', owner: 'password' })\n }\n } catch {\n flash({ kind: 'error', text: '修改失败,请重试', owner: 'password' })\n } finally {\n setBusy(false)\n }\n }, [oldPassword, newPassword, confirm, flash])\n\n const changeUsername = useCallback(async () => {\n setBusy(true)\n try {\n const res = await fetch('/api/auth/change-username', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ username: newUsername, currentPassword: usernamePassword }),\n })\n const data = (await res.json()) as { error?: string }\n if (res.ok) {\n setNewUsername('')\n setUsernamePassword('')\n if (newUsername) setUsername(newUsername)\n flash({ kind: 'ok', text: '用户名已更新', owner: 'username' })\n } else {\n flash({ kind: 'error', text: data.error ?? '修改失败,请重试', owner: 'username' })\n }\n } catch {\n flash({ kind: 'error', text: '修改失败,请重试', owner: 'username' })\n } finally {\n setBusy(false)\n }\n }, [newUsername, usernamePassword, flash, setUsername])\n\n const inputStyle: CSSProperties = {\n width: '100%',\n boxSizing: 'border-box',\n padding: '0 10px',\n height: 32,\n border: '1px solid var(--dsw-alias-border-l2)',\n borderRadius: 8,\n fontSize: 14,\n fontFamily: 'inherit',\n background: 'var(--dsw-alias-bg-layer-1)',\n color: 'var(--dsw-alias-label-primary)',\n outline: 'none',\n }\n const buttonStyle: CSSProperties = {\n boxSizing: 'border-box',\n height: 36,\n padding: '0 14px',\n borderRadius: 18,\n fontSize: 14,\n lineHeight: '22px',\n fontFamily: 'inherit',\n cursor: 'pointer',\n border: 'none',\n display: 'inline-flex',\n justifyContent: 'center',\n alignItems: 'center',\n gap: 4,\n }\n const primaryButtonStyle: CSSProperties = {\n ...buttonStyle,\n background: 'var(--dsw-alias-button-primary-fill)',\n color: 'var(--dsw-alias-label-primary-foreground)',\n }\n const secondaryButtonStyle: CSSProperties = {\n ...buttonStyle,\n border: '1px solid var(--dsw-alias-border-l2)',\n color: 'var(--dsw-alias-label-primary)',\n background: 'transparent',\n }\n const dangerButtonStyle: CSSProperties = {\n ...buttonStyle,\n color: 'var(--dsw-alias-state-error-primary)',\n background: 'transparent',\n }\n const dangerOutlineButtonStyle: CSSProperties = {\n ...buttonStyle,\n border: '1px solid var(--dsw-alias-state-error-primary)',\n color: 'var(--dsw-alias-state-error-primary)',\n background: 'transparent',\n }\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 24, maxWidth: 420 }}>\n <section>\n <h2 style={{ fontSize: 16, fontWeight: 600, margin: '0 0 4px' }}>账号</h2>\n <p style={{ fontSize: 13, opacity: 0.7, margin: '0 0 12px' }}>\n {username !== undefined ? `当前登录:${username}` : '当前登录:管理员'}\n </p>\n <button\n type=\"button\"\n onClick={() => setConfirmingSignOut(true)}\n disabled={busy}\n style={dangerOutlineButtonStyle}\n >\n 退出登录\n </button>\n {confirmingSignOut && (\n <div role=\"alertdialog\" aria-label=\"确认退出登录\" style={{ marginTop: 10, padding: '12px 14px', border: '1px solid var(--dsw-alias-border-l2)', borderRadius: 8, maxWidth: 320 }}>\n <div style={{ fontSize: 13, marginBottom: 10, color: 'var(--dsw-alias-label-primary)' }}>退出登录将回到登录页</div>\n <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8 }}>\n <button type=\"button\" onClick={() => setConfirmingSignOut(false)} disabled={busy} style={{ ...secondaryButtonStyle, height: 32, padding: '0 12px', borderRadius: 16 }}>\n 取消\n </button>\n <button type=\"button\" onClick={() => void signOut()} disabled={busy} style={{ ...dangerOutlineButtonStyle, height: 32, padding: '0 12px', borderRadius: 16, background: 'var(--dsw-alias-interactive-bg-hover-danger)' }}>\n 确认退出\n </button>\n </div>\n </div>\n )}\n {notice?.owner === 'account' && (\n <p style={{ fontSize: 13, color: notice.kind === 'ok' ? 'var(--dsw-alias-state-success-primary)' : 'var(--dsw-alias-state-error-primary)', margin: '8px 0 0' }}>{notice.text}</p>\n )}\n </section>\n\n <section>\n <h2 style={{ fontSize: 16, fontWeight: 600, margin: '0 0 12px' }}>修改用户名</h2>\n <form onSubmit={(e) => { e.preventDefault(); void changeUsername() }} style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 新用户名\n <input type=\"text\" value={newUsername} onChange={(e) => setNewUsername(e.target.value)} autoComplete=\"username\" style={inputStyle} />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 当前密码\n <input type=\"password\" value={usernamePassword} onChange={(e) => setUsernamePassword(e.target.value)} autoComplete=\"current-password\" style={inputStyle} />\n </label>\n <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>\n <button type=\"submit\" disabled={busy} style={primaryButtonStyle}>修改用户名</button>\n {notice?.owner === 'username' && <span style={{ fontSize: 13, color: notice.kind === 'ok' ? 'var(--dsw-alias-state-success-primary)' : 'var(--dsw-alias-state-error-primary)' }}>{notice.text}</span>}\n </div>\n </form>\n </section>\n\n <section>\n <h2 style={{ fontSize: 16, fontWeight: 600, margin: '0 0 12px' }}>修改密码</h2>\n <form onSubmit={(e) => { e.preventDefault(); void changePassword() }} style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 当前密码\n <input type=\"password\" value={oldPassword} onChange={(e) => setOldPassword(e.target.value)} autoComplete=\"current-password\" style={inputStyle} />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 新密码\n <input type=\"password\" value={newPassword} onChange={(e) => setNewPassword(e.target.value)} autoComplete=\"new-password\" style={inputStyle} />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 确认新密码\n <input type=\"password\" value={confirm} onChange={(e) => setConfirm(e.target.value)} autoComplete=\"new-password\" style={inputStyle} />\n </label>\n <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>\n <button type=\"submit\" disabled={busy} style={primaryButtonStyle}>修改密码</button>\n {notice?.owner === 'password' && <span style={{ fontSize: 13, color: notice.kind === 'ok' ? 'var(--dsw-alias-state-success-primary)' : 'var(--dsw-alias-state-error-primary)' }}>{notice.text}</span>}\n </div>\n </form>\n </section>\n </div>\n )\n}\n\nexport function apply(ctx: ClientContext): void {\n const connection = ctx.get('connection') as { isLoopback?: boolean } | undefined\n if (connection !== undefined) {\n Object.defineProperty(connection, 'isLoopback', { configurable: true, get: () => true })\n }\n ctx.plugin({\n inject: ['slots'],\n apply: (sub: ClientContext): void => {\n sub.slots.inject('settings.section', () =>\n sub.slots.register({ name: 'settings.section', id: SECTION_ID, order: 100, label: () => '认证' }, AuthSection),\n )\n },\n })\n}\n","import type { DirectoryFlowOwnerProps } from '@deepseek-ai/dsh-client-ui-workspace/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type { CSSProperties, ReactElement } from 'react'\nimport { useCallback, useEffect, useState } from 'react'\n\ninterface NodeProfileView {\n id: string\n name: string\n type: 'local-host' | 'local-docker' | 'remote-ssh' | 'remote-docker'\n status?: { reachable?: boolean }\n}\n\ninterface DirEntry {\n name: string\n path: string\n isDirectory: boolean\n}\n\nconst inputStyle: CSSProperties = {\n width: '100%',\n boxSizing: 'border-box',\n padding: '0 10px',\n height: 32,\n border: '1px solid var(--dsw-alias-border-l2)',\n borderRadius: 8,\n fontSize: 14,\n fontFamily: 'inherit',\n background: 'var(--dsw-alias-bg-layer-1)',\n color: 'var(--dsw-alias-label-primary)',\n outline: 'none',\n}\nconst buttonStyle: CSSProperties = {\n boxSizing: 'border-box',\n height: 36,\n padding: '0 14px',\n borderRadius: 18,\n fontSize: 14,\n lineHeight: '22px',\n fontFamily: 'inherit',\n cursor: 'pointer',\n border: 'none',\n display: 'inline-flex',\n justifyContent: 'center',\n alignItems: 'center',\n gap: 4,\n}\nconst primaryButtonStyle: CSSProperties = {\n ...buttonStyle,\n background: 'var(--dsw-alias-button-primary-fill)',\n color: 'var(--dsw-alias-label-primary-foreground)',\n}\nconst secondaryButtonStyle: CSSProperties = {\n ...buttonStyle,\n border: '1px solid var(--dsw-alias-border-l2)',\n color: 'var(--dsw-alias-label-primary)',\n background: 'transparent',\n}\nconst overlayStyle: CSSProperties = {\n position: 'fixed',\n inset: 0,\n background: 'var(--dsw-alias-overlay-mask, rgba(0,0,0,0.45))',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 1000,\n}\nconst dialogStyle: CSSProperties = {\n width: 'min(92vw, 560px)',\n maxWidth: '100%',\n maxHeight: '80vh',\n overflow: 'auto',\n overflowX: 'hidden',\n background: 'var(--dsw-alias-bg-layer-1)',\n border: '1px solid var(--dsw-alias-border-l2)',\n borderRadius: 12,\n padding: 20,\n boxSizing: 'border-box',\n color: 'var(--dsw-alias-label-primary)',\n}\n\nfunction joinPath(base: string, name: string): string {\n return `${base.replace(/\\/+$/, '')}/${name}`\n}\n\nexport function DirectoryFlowOccupant(props: DirectoryFlowOwnerProps): ReactElement | null {\n const [nodes, setNodes] = useState<NodeProfileView[]>([])\n const [nodeId, setNodeId] = useState<string>('')\n const [path, setPath] = useState('')\n const [entries, setEntries] = useState<DirEntry[]>([])\n const [error, setError] = useState<string | undefined>(undefined)\n const [busy, setBusy] = useState(false)\n const [newDirName, setNewDirName] = useState('')\n const [pendingInstruction, setPendingInstruction] = useState<string | undefined>(undefined)\n const [instructionDialogOpen, setInstructionDialogOpen] = useState(false)\n\n useEffect(() => {\n if (!props.open) return\n void (async () => {\n try {\n const res = await fetch('/api/dshb/nodes')\n if (!res.ok) return\n const data = (await res.json()) as { nodes?: NodeProfileView[] }\n setNodes(data.nodes ?? [])\n } catch {}\n })()\n }, [props.open])\n\n const browse = useCallback(async (id: string, dir: string) => {\n setError(undefined)\n try {\n const res = await fetch(`/api/dshb/nodes/${id}/browse?path=${encodeURIComponent(dir)}`)\n const data = (await res.json()) as { ok?: boolean; path?: string; entries?: DirEntry[]; error?: string }\n if (!res.ok || !data.ok) {\n setError(data.error ?? '目录读取失败')\n return\n }\n setPath(data.path ?? dir)\n setEntries((data.entries ?? []).filter((e) => e.isDirectory))\n } catch {\n setError('网络错误')\n }\n }, [])\n\n const selectNode = useCallback(\n (id: string) => {\n setNodeId(id)\n setPath('')\n setEntries([])\n setError(undefined)\n void browse(id, '/')\n },\n [browse],\n )\n\n const mkdir = useCallback(async () => {\n if (!newDirName.trim()) return\n setBusy(true)\n setError(undefined)\n try {\n const target = joinPath(path, newDirName.trim())\n const res = await fetch(`/api/dshb/nodes/${nodeId}/mkdir`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ path: target }),\n })\n const data = (await res.json()) as { ok?: boolean; error?: string }\n if (!res.ok || !data.ok) {\n setError(data.error ?? '创建目录失败')\n return\n }\n setNewDirName('')\n void browse(nodeId, target)\n } catch {\n setError('网络错误')\n } finally {\n setBusy(false)\n }\n }, [newDirName, nodeId, path, browse])\n\n const confirm = useCallback(async () => {\n if (!nodeId || !path) {\n setError('请选择节点与目录')\n return\n }\n setBusy(true)\n setError(undefined)\n try {\n const node = nodes.find((n) => n.id === nodeId)\n if (!node) return\n let pickedPath = path\n if (node.type !== 'local-host') {\n const res = await fetch('/api/dshb/workspaces/bind', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ nodeId, remotePath: path }),\n })\n const data = (await res.json()) as { ok?: boolean; mirrorPath?: string; error?: string }\n if (!res.ok || !data.ok || !data.mirrorPath) {\n setError(data.error ?? '工作区注册失败')\n return\n }\n pickedPath = data.mirrorPath\n }\n props.onPicked(pickedPath)\n if (pendingInstruction !== undefined && pendingInstruction.trim()) {\n savePendingInstruction(pickedPath, pendingInstruction)\n }\n } catch {\n setError('网络错误')\n } finally {\n setBusy(false)\n }\n }, [nodeId, path, nodes, props, pendingInstruction])\n\n if (!props.open) return null\n\n const node = nodes.find((n) => n.id === nodeId)\n\n return (\n <div style={overlayStyle} role=\"dialog\" aria-label=\"添加工作区\">\n <div style={dialogStyle}>\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 14 }}>\n <h2 style={{ margin: 0, fontSize: 16, color: 'var(--dsw-alias-label-primary)' }}>添加工作区</h2>\n <button type=\"button\" onClick={props.onCancel} style={secondaryButtonStyle}>\n 关闭\n </button>\n </div>\n\n <label style={{ display: 'block', fontSize: 12, color: 'var(--dsw-alias-label-secondary)', marginBottom: 4 }}>工作节点</label>\n <select style={{ ...inputStyle, marginBottom: 14 }} value={nodeId} onChange={(e) => selectNode(e.target.value)} disabled={props.busy || busy}>\n <option value=\"\">选择节点…</option>\n {nodes.map((n) => {\n const typeLabel =\n n.type === 'local-host' ? '本地' : n.type === 'remote-ssh' ? '远程 SSH' : n.type === 'local-docker' ? '本地 Docker' : n.type === 'remote-docker' ? '远程 Docker' : n.type\n return (\n <option key={n.id} value={n.id}>\n {n.name}({typeLabel})\n </option>\n )\n })}\n </select>\n\n {nodeId !== '' && (\n <>\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 6 }}>\n <label style={{ fontSize: 12, color: 'var(--dsw-alias-label-secondary)' }}>当前目录({node?.type === 'local-host' ? '本机' : '远端'})</label>\n <button type=\"button\" onClick={() => void browse(nodeId, dirnameOf(path))} disabled={busy} style={secondaryButtonStyle}>\n 上一级\n </button>\n </div>\n <div style={{ ...inputStyle, marginBottom: 8, height: 'auto', minHeight: 32, display: 'flex', alignItems: 'center', flexWrap: 'wrap', gap: 2, cursor: 'pointer', lineHeight: '32px', overflow: 'hidden' }} onClick={() => void browse(nodeId, path)}>\n {path.split('/').filter(Boolean).length === 0 ? (\n <span style={{ opacity: 0.5 }}>根目录</span>\n ) : (\n <>\n <span onClick={(ev) => { ev.stopPropagation(); void browse(nodeId, '/') }} style={{ cursor: 'pointer', color: 'var(--dsw-alias-label-secondary)' }}>/</span>\n {path.split('/').filter(Boolean).map((seg, i, arr) => {\n const dir = '/' + arr.slice(0, i + 1).join('/')\n return (\n <span key={i} style={{ display: 'inline-flex', alignItems: 'center', gap: 2 }}>\n <span onClick={(ev) => { ev.stopPropagation(); void browse(nodeId, dir) }} style={{ cursor: 'pointer' }}>{seg}</span>\n {i < arr.length - 1 && <span style={{ opacity: 0.4 }}>/</span>}\n </span>\n )\n })}\n </>\n )}\n </div>\n <div style={{ maxHeight: 200, overflow: 'auto', border: '1px solid var(--dsw-alias-border-l2)', borderRadius: 6, marginBottom: 10 }}>\n {entries.map((e) => (\n <div key={e.path} onClick={() => void browse(nodeId, e.path)} style={{ padding: '7px 10px', cursor: 'pointer', fontSize: 13, borderRadius: 6, color: 'var(--dsw-alias-label-primary)', display: 'flex', alignItems: 'center', gap: 6, overflow: 'hidden' }} onMouseEnter={(ev) => (ev.currentTarget.style.background = 'var(--dsw-alias-interactive-bg-hover)')} onMouseLeave={(ev) => (ev.currentTarget.style.background = 'transparent')}>\n <span style={{ flexShrink: 0 }}>📁</span>\n <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{e.name}</span>\n </div>\n ))}\n {entries.length === 0 && <div style={{ padding: 12, fontSize: 12, color: 'var(--dsw-alias-label-tertiary)' }}>无子目录</div>}\n </div>\n <div style={{ display: 'flex', gap: 8, marginBottom: 12 }}>\n <input style={{ ...inputStyle, flex: 1, minWidth: 0 }} value={newDirName} onChange={(e) => setNewDirName(e.target.value)} placeholder=\"在当前目录下新建子目录…\" onKeyDown={(e) => { if (e.key === 'Enter') void mkdir() }} />\n <button type=\"button\" onClick={() => void mkdir()} disabled={busy || !newDirName.trim()} style={{ ...secondaryButtonStyle, flexShrink: 0, whiteSpace: 'nowrap' }}>\n 新建\n </button>\n </div>\n </>\n )}\n\n {error && <div style={{ fontSize: 13, color: 'var(--dsw-alias-state-error-primary)', marginBottom: 10 }}>{error}</div>}\n\n <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 10 }}>\n <button type=\"button\" onClick={props.onCancel} style={secondaryButtonStyle}>\n 取消\n </button>\n <button\n type=\"button\"\n onClick={() => setInstructionDialogOpen(true)}\n disabled={busy || props.busy || !nodeId || !path}\n style={{\n ...secondaryButtonStyle,\n borderColor: pendingInstruction !== undefined && pendingInstruction.trim() ? 'var(--dsw-alias-state-business-primary)' : 'var(--dsw-alias-border-l2)',\n color: pendingInstruction !== undefined && pendingInstruction.trim() ? 'var(--dsw-alias-state-business-primary)' : 'var(--dsw-alias-label-primary)',\n }}\n >\n 指令{pendingInstruction !== undefined && pendingInstruction.trim() ? ' ●' : ''}\n </button>\n <button type=\"button\" onClick={() => void confirm()} disabled={busy || props.busy || !nodeId || !path} style={primaryButtonStyle}>\n 设为工作区\n </button>\n </div>\n </div>\n\n {instructionDialogOpen && (\n <InstructionPreviewDialog\n text={pendingInstruction ?? ''}\n onClose={() => setInstructionDialogOpen(false)}\n onSave={(t) => {\n setPendingInstruction(t)\n setInstructionDialogOpen(false)\n }}\n />\n )}\n </div>\n )\n}\n\nfunction dirnameOf(path: string): string {\n const parts = path.split('/').filter(Boolean)\n parts.pop()\n return parts.length === 0 ? '/' : `/${parts.join('/')}`\n}\n\nconst pendingInstructions = new Map<string, string>()\n\nfunction savePendingInstruction(path: string, text: string): void {\n pendingInstructions.set(path, text)\n void (async () => {\n try {\n let attempts = 0\n const tryResolve = async (): Promise<void> => {\n if (attempts++ > 10) return\n const wks = (window as unknown as { workspaces?: { list?: { getSnapshot?: () => { items?: { workspaceId: string; path: string }[] } } } }).workspaces\n const snap = wks?.list?.getSnapshot?.()\n const items = snap?.items ?? []\n const ws = items.find((w) => w.path === path)\n if (!ws) {\n await new Promise((r) => setTimeout(r, 300))\n return tryResolve()\n }\n await fetch(`/api/dshb/instructions/${ws.workspaceId}`, {\n method: 'PUT',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ text, expectedRevision: 0 }),\n })\n pendingInstructions.delete(path)\n }\n void tryResolve()\n } catch {}\n })()\n}\n\nfunction InstructionPreviewDialog(props: {\n text: string\n onClose: () => void\n onSave: (text: string) => void\n}): ReactElement {\n const [text, setText] = useState(props.text)\n const overlayStyle: CSSProperties = {\n position: 'fixed',\n inset: 0,\n background: 'var(--dsw-alias-overlay-mask, rgba(0,0,0,0.45))',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 1100,\n }\n const dialogStyle: CSSProperties = {\n width: 'min(92vw, 600px)',\n maxWidth: '100%',\n maxHeight: '85vh',\n overflow: 'auto',\n overflowX: 'hidden',\n background: 'var(--dsw-alias-bg-layer-1)',\n border: '1px solid var(--dsw-alias-border-l2)',\n borderRadius: 12,\n padding: 20,\n boxSizing: 'border-box',\n color: 'var(--dsw-alias-label-primary)',\n }\n return (\n <div style={overlayStyle} onClick={props.onClose}>\n <div style={dialogStyle} onClick={(e) => e.stopPropagation()}>\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 14 }}>\n <h2 style={{ margin: 0, fontSize: 16, color: 'var(--dsw-alias-label-primary)' }}>项目指令</h2>\n <button type=\"button\" onClick={props.onClose} style={secondaryButtonStyle}>关闭</button>\n </div>\n <div style={{ fontSize: 12, color: 'var(--dsw-alias-label-secondary)', marginBottom: 10 }}>\n 工作区创建后,此指令将自动保存为新工作区的项目指令。新对话首次交互时注入。\n </div>\n <textarea\n style={{\n width: '100%',\n minHeight: '280px',\n fontFamily: 'monospace',\n fontSize: 13,\n padding: '12px',\n border: '1px solid var(--dsw-alias-border-l2)',\n borderRadius: 8,\n background: 'var(--dsw-alias-bg-layer-2)',\n color: 'var(--dsw-alias-label-primary)',\n resize: 'vertical',\n boxSizing: 'border-box',\n outline: 'none',\n }}\n value={text}\n onChange={(e) => setText(e.target.value)}\n placeholder=\"留空则不注入指令...\"\n spellCheck={false}\n />\n <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 10, marginTop: 14 }}>\n <button type=\"button\" onClick={props.onClose} style={secondaryButtonStyle}>取消</button>\n <button type=\"button\" onClick={() => props.onSave(text)} style={primaryButtonStyle}>确定</button>\n </div>\n </div>\n </div>\n )\n}\n","import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\n\n/**\n * dshb 移动端屏幕适配(参考 dsh-web-mobile 实现,仅保留页面适配与目录抽屉\n * 切换,不含文件浏览 / 导出会话日志等功能按钮)。\n *\n * 机制与上游一致:dsh 客户端在窄屏会自动给 AppFrame 加 data-sidebar-collapsed\n * 折叠侧边栏;这里把侧边栏列(frame 的第一个 grid 子元素)用 CSS 抽屉化\n * (绝对定位 + transform 移出/滑入),并在会话头部注入一个切换按钮调用\n * ctx.layout.toggleSidebar()。窄屏判定与上游一致(<1024 且粗指针,避免桌面\n * 小窗误触发)。\n */\nexport const MOBILE_QUERY = '(max-width: 1023px) and (pointer: coarse)'\n\n/** 纯视口宽度判定:与放宽后的 MOBILE_CSS 媒体查询一致(不依赖 pointer 类型)。 */\nconst NARROW_QUERY = '(max-width: 1023px)'\n\nconst FRAME_ATTR = 'data-dshb-mobile'\nconst COLLAPSED_ATTR = 'data-sidebar-collapsed'\n\nconst MOBILE_CSS = `\n/* 仅按视口宽度判定,不绑定 pointer:coarse —— 触屏笔记本 / DevTools 响应式模式\n 常报 pointer:fine,绑定 coarse 会让全部窄屏修复失效。抽屉相关选择器都挂在\n [data-dshb-mobile] 标记上,标记由 JS 的 coarse 判定添加,故放宽 CSS 不会误开抽屉。 */\n@media (max-width: 1023px) {\n html, body { touch-action: pan-y pinch-zoom !important; overscroll-behavior-x: none !important; -webkit-text-size-adjust: 100% !important; text-size-adjust: 100% !important; }\n\n [${FRAME_ATTR}=\"frame\"] {\n box-sizing: border-box !important;\n position: relative !important;\n grid-template-columns: minmax(0, 1fr) 0 0 !important;\n padding-top: env(safe-area-inset-top, 0px) !important;\n }\n\n /* 侧边栏列 -> 抽屉:默认移出屏幕,展开(无 collapsed)时滑入 */\n [${FRAME_ATTR}=\"frame\"] > :first-child {\n position: absolute !important;\n inset: 0 auto 0 0 !important;\n width: max-content;\n max-width: 92vw;\n z-index: 40 !important;\n transform: translateX(-110%);\n transition: transform .28s ease-in-out;\n background: var(--dsw-alias-bg-base, #ffffff);\n padding-top: env(safe-area-inset-top, 0px) !important;\n border-right: none !important;\n touch-action: pan-y pinch-zoom !important;\n }\n [${FRAME_ATTR}=\"frame\"]:not([${COLLAPSED_ATTR}]) > :first-child { transform: none !important; }\n @media (prefers-reduced-motion: reduce) {\n [${FRAME_ATTR}=\"frame\"] > :first-child { transition: none !important; }\n }\n\n /* 拖拽手柄在触屏上无用 */\n [data-side=\"sidebar\"], [data-side=\"details\"] { display: none !important; }\n\n /* 对话区:去桌面滚动条占位,收窄 gutter,字号降一档 */\n [data-phase] [class*=\"_scrollBody\"] { scrollbar-gutter: auto !important; scrollbar-width: none; }\n [data-phase] [class*=\"_scrollBody\"]::-webkit-scrollbar { display: none !important; width: 0; height: 0; }\n [data-phase] [class*=\"_scroll\"]:not([class*=\"_scrollBody\"]):has(p) { padding-left: 20px; padding-right: 20px; font-size: 15px !important; }\n [data-phase] [class*=\"_scroll\"]:not([class*=\"_scrollBody\"]):has(p) p,\n [data-phase] [class*=\"_scroll\"]:not([class*=\"_scrollBody\"]):has(p) li,\n [data-phase] [class*=\"_scroll\"]:not([class*=\"_scrollBody\"]):has(p) [class*=\"_text_\"] { font-size: 15px !important; }\n [data-phase] table { width: 100%; max-width: 100%; }\n [data-phase] th, [data-phase] td { max-width: none; min-width: 0; }\n [data-phase] [class*=\"_scroll\"]:not([class*=\"_scrollBody\"]) img { width: auto !important; max-width: 100% !important; height: auto !important; max-height: 220px !important; }\n [data-phase] [class*=\"_userStack\"], [data-phase] [class*=\"_userStack\"] [class*=\"_bubble\"] { box-sizing: border-box; width: fit-content; max-width: 100%; }\n [data-phase] [class*=\"_actions\"] { overflow: hidden; }\n\n /* 统计行(turns/steps/LLM/TPS):窄屏横向滚动,指标可滑动看全 */\n [${FRAME_ATTR}=\"stats\"] {\n display: flex !important;\n flex-wrap: nowrap !important;\n align-items: center;\n gap: 6px;\n overflow-x: auto !important;\n max-width: 100% !important;\n scrollbar-width: none;\n -webkit-overflow-scrolling: touch;\n }\n [${FRAME_ATTR}=\"stats\"]::-webkit-scrollbar { display: none; }\n [${FRAME_ATTR}=\"stats\"] > * { flex-shrink: 0 !important; white-space: nowrap !important; }\n [${FRAME_ATTR}=\"stats\"] { gap: 6px !important; }\n [class*=\"composerStack\"] { gap: 4px !important; }\n /* stats line 竖线分隔符(|)两边 margin 10px 太松,适度收紧 */\n [data-phase] [class*=\"_sep\"] { margin: 0 3px !important; }\n\n /* 每轮回复下方的统计文字(footer):收紧 actions 内部 gap 与气泡到 footer 间距,减少松散感 */\n [data-phase] [class*=\"_actions\"] { gap: 4px !important; }\n [data-phase] [class*=\"_actions\"] [class*=\"_timeEnd\"] { gap: 4px !important; padding-left: 6px !important; }\n [data-phase] [class*=\"userRow\"], [data-phase] [class*=\"assistantRow\"] { gap: 4px !important; }\n /* 点号(·)左右 margin 10px 太松,收紧并抵消前后空格 */\n [data-phase] [class*=\"_runTimeDot\"] { margin: 0 -2px !important; }\n /* footer 容器各项间距 16px 偏松 */\n [data-phase] [class*=\"_root\"][class*=\"osXY9a\"] { gap: 8px !important; }\n /* footer 统计行窄屏可横向滑动看全,不溢出页面 */\n [data-phase] [class*=\"_actions\"] { max-width: 100% !important; overflow-x: auto !important; scrollbar-width: none; touch-action: pan-x pan-y !important; }\n [data-phase] [class*=\"_actions\"]::-webkit-scrollbar { display: none; }\n\n /* 模型切换菜单:名称完整展示,长名称在菜单项内换行。 */\n [class*=\"_submenu_\"] [class*=\"_itemLabel_\"] {\n overflow: visible !important;\n text-overflow: clip !important;\n white-space: normal !important;\n overflow-wrap: anywhere;\n }\n\n /* 模型选择器(dsh-client-ui-model-selection,CSS 模块前缀 7KE1Ra_):\n 列表内模型名/描述默认 ellipsis 截断,改换行完整显示。除当前 hash 外,\n 再加 modelName 语义匹配,防止上游升级换 hash 后规则失效。\n 注意:必须用 break-word 而非 anywhere —— anywhere 让文字 min-content\n 宽度≈1 字符,配合全局 * {min-width:0} 会把 flex 行内名字列压到 1 字符宽,\n 出现\"一字符就换行\"。break-word 的 min-content 取最长词宽,只在真正\n 放不下时才断词。 */\n [class*=\"7KE1Ra_modelName\"],\n [class*=\"7KE1Ra_description\"],\n [class*=\"modelName\"] {\n white-space: normal !important;\n overflow-wrap: break-word;\n text-overflow: clip !important;\n overflow: visible !important;\n }\n\n /* 模型选择器弹窗:JS(installModelMenuPosition)在窄屏下改为 position:fixed\n 视口级浮层(fixed 不受祖先 overflow 裁剪),这里仅做静态兜底(JS 未生效时\n 仍从触发按钮左缘向右展开、宽度收进视口)。 */\n [class*=\"7KE1Ra_menu\"],\n [class*=\"_menu\"]:has([class*=\"modelName\"]) {\n left: 0 !important;\n right: auto !important;\n width: calc(100vw - 32px) !important;\n min-width: 0 !important;\n max-width: calc(100vw - 32px) !important;\n overflow-y: auto !important;\n max-height: calc(100vh - 120px) !important;\n }\n\n /* 工具调用执行结果/代码/JSON:窄屏可横向滑动。details 抽屉宽 min(92%,420px)\n 较窄,命令行输出/JSON 长行溢出被外层 overflow:hidden 裁剪看不到。命令行输出\n 改 white-space:pre(保持原格式不折行,像终端)+ overflow-x:auto 横向滑动;\n min-width:0+max-width:100% 约束宽度触发滚动。 */\n [data-phase] [class*=\"resultBlockText\"],\n [data-phase] [class*=\"payload\"]:not([class*=\"errorPayload\"]),\n [data-phase] [class*=\"sourceBlockContent\"] {\n white-space: pre !important;\n min-width: 0 !important;\n max-width: 100% !important;\n overflow-x: auto !important;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n touch-action: pan-x pan-y !important;\n }\n [data-phase] [class*=\"resultBlockText\"]::-webkit-scrollbar,\n [data-phase] [class*=\"payload\"]::-webkit-scrollbar,\n [data-phase] [class*=\"sourceBlockContent\"]::-webkit-scrollbar { display: none !important; }\n\n /* JSON 预览/代码块/promptDiff:横向滑动(不折行,保持格式) */\n [data-phase] [class*=\"jsonPayload\"],\n [data-phase] [class*=\"jsonPreview\"],\n [data-phase] [class*=\"promptDiff\"],\n [data-phase] [class*=\"overviewPreview\"],\n [data-phase] [class*=\"resultBlocks\"],\n [data-phase] pre {\n min-width: 0 !important;\n max-width: 100% !important;\n overflow-x: auto !important;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n touch-action: pan-x pan-y !important;\n }\n [data-phase] [class*=\"jsonPayload\"]::-webkit-scrollbar,\n [data-phase] [class*=\"jsonPreview\"]::-webkit-scrollbar,\n [data-phase] [class*=\"promptDiff\"]::-webkit-scrollbar,\n [data-phase] [class*=\"overviewPreview\"]::-webkit-scrollbar,\n [data-phase] [class*=\"resultBlocks\"]::-webkit-scrollbar,\n [data-phase] pre::-webkit-scrollbar { display: none !important; }\n\n /* dsh-client-ui-tool 工具卡片(Bash 等命令输出,class 前缀 o3BgMG_):\n bodyScroll/ioSection 只有 overflow-y:auto,横向溢出传到 row{overflow:hidden}\n 被裁剪且无法滑动。给输出容器链设 overflow-x:auto(不覆盖上游 overflow-y),\n 让终端格式长行在卡片内横向滑动。 */\n [data-phase] [class*=\"bodyScroll\"],\n [data-phase] [class*=\"ioCard\"],\n [data-phase] [class*=\"ioSection\"],\n [data-phase] [class*=\"terminalBody\"],\n [data-phase] [class*=\"codeBody\"] {\n min-width: 0 !important;\n max-width: 100% !important;\n overflow-x: auto !important;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n touch-action: pan-x pan-y !important;\n }\n /* xterm uses a transparent helper textarea for all terminal input. Keep it\n focusable and non-zero-sized so mobile browsers can present their keyboard. */\n [data-phase] .xterm .xterm-helper-textarea {\n width: 1px !important;\n height: 1px !important;\n opacity: .01 !important;\n z-index: 1 !important;\n }\n [data-phase] [class*=\"bodyScroll\"]::-webkit-scrollbar,\n [data-phase] [class*=\"ioCard\"]::-webkit-scrollbar,\n [data-phase] [class*=\"ioSection\"]::-webkit-scrollbar,\n [data-phase] [class*=\"terminalBody\"]::-webkit-scrollbar,\n [data-phase] [class*=\"codeBody\"]::-webkit-scrollbar { display: none !important; }\n\n /* 终端组件(dsh-web-frontend,CSS 模块前缀 1gdtu_):多行命令上游按行渲染成\n 多个 _promptLine_>_command_ 元素,行级不能各自设 overflow(会变成每行独立\n 滚动)。唯一横向滚动容器是公共祖先 _header_1gdtu_32(本就 overflow-y:auto):\n 行链 _prompt_/_promptLine_/_command_ 全部撑到 max-content 且 overflow 可见,\n 长行内容溢出传入 _header_ 的 scrollWidth,所有行随 _header_ 同步滚动。\n _output_1gdtu_156(输出区)同理以其为唯一容器,_line_ 撑宽不裁剪。 */\n [data-phase] [class*=\"_header_1gdtu_\"] {\n min-width: 0 !important;\n max-width: 100% !important;\n overflow-x: auto !important;\n overscroll-behavior-x: contain;\n touch-action: pan-x pan-y !important;\n }\n [data-phase] [class*=\"_prompt_1gdtu_\"],\n [data-phase] [class*=\"_promptLine_1gdtu_\"],\n [data-phase] [class*=\"_command_1gdtu_\"] {\n min-width: max-content !important;\n max-width: none !important;\n overflow: visible !important;\n /* Android Chrome TextAutosizer 按块宽计算 font boosting,max-content 行宽不一\n 导致各行字号参差;max-height 是其豁免条件,禁用放大并锁定继承字号。 */\n max-height: 999999px !important;\n }\n [data-phase] [class*=\"_command_1gdtu_\"] {\n display: inline-block;\n text-overflow: clip !important;\n white-space: pre !important;\n }\n [data-phase] [class*=\"_copyButton_1gdtu_\"] { position: sticky !important; right: 0; }\n [data-phase] [class*=\"_output_1gdtu_\"] {\n overflow-x: auto !important;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n touch-action: pan-x pan-y !important;\n }\n [data-phase] [class*=\"_output_1gdtu_\"]::-webkit-scrollbar { display: none !important; }\n [data-phase] [class*=\"_line_1gdtu_\"] {\n min-width: max-content !important;\n overflow-x: visible !important;\n max-height: 999999px !important;\n }\n\n /* 复制按钮周边也允许纵向页面手势,避免代码/总结区域形成触控死区。 */\n [data-phase] [class*=\"_copyButton_\"] { touch-action: manipulation !important; }\n [data-phase] [class*=\"_copyAnchor_\"],\n [data-phase] [class*=\"_body_1ye18_\"],\n [data-phase] [class*=\"_root_4qrvp_\"] { touch-action: pan-x pan-y !important; }\n\n /* 上下文用量弹窗(ContextMeter .JObwrW_panel):上游 dsh-client-ui-trajectory 的\n [class*=\"panel\"] 全局规则给它加了 max-width:100%!important,命中本弹窗,使宽度\n 从 264px 塌缩到包含块(.root 28px)宽,内容竖排成竖条。窄屏解除该误伤。 */\n .JObwrW_panel { max-width: none !important; overflow-x: visible !important; }\n\n /* 头部:标题省略,tab 条横向滚动 */\n [${FRAME_ATTR}=\"frame\"] [data-phase] header { padding-left: 44px; padding-right: 8px; }\n [${FRAME_ATTR}=\"frame\"] [data-phase] header [class*=\"_crumbs\"] { flex: 1 1 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap !important; }\n [${FRAME_ATTR}=\"frame\"] [data-phase] header [role=\"tablist\"] { flex-wrap: nowrap; gap: 0 16px; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; }\n [${FRAME_ATTR}=\"frame\"] [data-phase] header [role=\"tablist\"]::-webkit-scrollbar { display: none; }\n [${FRAME_ATTR}=\"frame\"] [data-phase] header [role=\"tablist\"] > button { flex-shrink: 0; white-space: nowrap; }\n\n /* 设置对话框:窄屏近全宽 sheet(排除导出等普通对话框与目录选择器) */\n [aria-modal=\"true\"]:has(> :first-child > :last-child > button):not(:has([role=\"navigation\"])):not(:has([class*=\"ZuhsRW\"])) {\n position: absolute !important;\n left: 8px !important;\n top: calc(env(safe-area-inset-top, 0px) + 12px) !important;\n width: calc(100vw - 16px) !important;\n max-width: calc(100vw - 16px) !important;\n height: auto !important;\n max-height: calc(100dvh - 24px - env(safe-area-inset-top, 0px)) !important;\n flex-direction: column !important;\n border-radius: 14px !important;\n }\n [aria-modal=\"true\"]:not(:has(> :first-child > :last-child > button)) { max-width: calc(100vw - 32px) !important; }\n /* nav:横排换行(避免 CJK 标签竖排楼梯状),隐藏冗余 caption */\n [aria-modal=\"true\"]:has(> :first-child > :last-child > button):not(:has([role=\"navigation\"])):not(:has([class*=\"ZuhsRW\"])) > :first-child {\n width: 100%;\n flex-direction: row !important;\n align-items: center;\n gap: 6px;\n padding: 10px 12px 8px;\n }\n [aria-modal=\"true\"]:has(> :first-child > :last-child > button):not(:has([role=\"navigation\"])):not(:has([class*=\"ZuhsRW\"])) > :first-child > :first-child { display: none !important; }\n [aria-modal=\"true\"] [class*=\"_navList\"] { flex: 1 1 auto; min-width: 0; flex-direction: row !important; flex-wrap: wrap; gap: 6px; overflow: visible; }\n [aria-modal=\"true\"] [class*=\"_navList\"] > button { flex-shrink: 0; white-space: nowrap; }\n /* 外观模式卡片横排 */\n [aria-modal=\"true\"] [class*=\"_cubeRow\"] { gap: 6px; }\n [aria-modal=\"true\"] [class*=\"_cubeRow\"] > * { flex: 1 1 0; flex-direction: row !important; align-items: center; justify-content: center; gap: 6px; padding: 10px 8px; min-height: 0; }\n /* section 填充 sheet 宽度 */\n [aria-modal=\"true\"] [class*=\"_section\"] { width: 100% !important; max-width: none !important; }\n [aria-modal=\"true\"]:has(> :first-child > :last-child > button):not(:has([role=\"navigation\"])):not(:has([class*=\"ZuhsRW\"])) > :last-child { flex: 1 1 auto; min-height: 0; }\n [aria-modal=\"true\"]:has(> :first-child > :last-child > button):not(:has([role=\"navigation\"])):not(:has([class*=\"ZuhsRW\"])) > :last-child > :last-child { padding: 0 12px 24px; }\n\n /* 切换按钮:固定头部左侧 */\n [${FRAME_ATTR}=\"toggle\"] {\n position: absolute !important;\n left: 8px !important;\n top: 12px !important;\n z-index: 2 !important;\n display: inline-flex !important;\n align-items: center; justify-content: center;\n width: 28px; height: 28px;\n padding: 0; border: none; background: none; cursor: pointer; color: inherit;\n -webkit-tap-highlight-color: transparent;\n }\n\n /* 首页/hero(无活跃会话,session header 不存在)的抽屉切换 FAB:\n 浮在顶部相机带下方,避免与 hero 头部内容重叠 */\n [${FRAME_ATTR}=\"fab\"] {\n position: absolute !important;\n top: calc(env(safe-area-inset-top, 0px) + 72px) !important;\n left: 10px !important;\n z-index: 21 !important;\n display: inline-flex !important;\n align-items: center; justify-content: center;\n width: 38px; height: 38px;\n padding: 0;\n border: 1px solid var(--dsw-alias-border-l1, rgba(0, 0, 0, .12)) !important;\n border-radius: 50% !important;\n background: var(--dsw-alias-button-floating-fill, #ffffff) !important;\n color: var(--dsw-alias-label-primary, inherit) !important;\n cursor: pointer !important;\n box-shadow: 0 2px 12px rgba(0, 0, 0, .18) !important;\n -webkit-tap-highlight-color: transparent;\n }\n}\n\n/* 宽屏 / 鼠标指针:隐藏切换按钮 */\n@media (min-width: 1024px), (pointer: fine) {\n [${FRAME_ATTR}=\"toggle\"], [${FRAME_ATTR}=\"fab\"] { display: none !important; }\n}\n`\n\nfunction findFrame(): HTMLElement | null {\n return document.querySelector('[data-shell-overlay]')?.parentElement ?? null\n}\n\nfunction getFrame(): HTMLElement | null {\n return document.querySelector(`[${FRAME_ATTR}=\"frame\"]`) ?? findFrame()\n}\n\n/** viewport-fit=cover:让 safe-area-inset 生效,内容避开刘海/状态栏。 */\nfunction installViewport(ctx: ClientContext): void {\n ctx.effect(() => {\n const narrow = window.matchMedia(MOBILE_QUERY)\n const viewport = document.querySelector<HTMLMetaElement>('meta[name=\"viewport\"]')\n if (viewport === null) return () => {}\n const original = viewport.content\n const sync = (): void => {\n viewport.content = narrow.matches\n ? 'width=device-width, initial-scale=1, viewport-fit=cover'\n : original\n }\n sync()\n narrow.addEventListener('change', sync)\n return () => {\n narrow.removeEventListener('change', sync)\n viewport.content = original\n }\n }, 'dshb-mobile: viewport')\n}\n\nfunction installStyles(ctx: ClientContext): void {\n ctx.effect(() => {\n const tag = document.createElement('style')\n tag.dataset.plugin = 'dshb-mobile'\n tag.textContent = MOBILE_CSS\n document.head.appendChild(tag)\n // 保持在 head 最后,确保覆盖宿主样式\n setTimeout(() => { if (tag.isConnected) document.head.appendChild(tag) }, 0)\n return () => { tag.remove() }\n }, 'dshb-mobile: styles')\n}\n\n/** 给 AppFrame 打标记(drawer CSS 选择器挂载点),窄屏才打。 */\nfunction installFrameMarker(ctx: ClientContext): void {\n ctx.effect(() => {\n const narrow = window.matchMedia(MOBILE_QUERY)\n let frame: HTMLElement | null = null\n const clear = (): void => {\n if (frame !== null) frame.removeAttribute(FRAME_ATTR)\n frame = null\n }\n const ensure = (): void => {\n if (!narrow.matches) return\n frame = findFrame()\n if (frame !== null && !frame.hasAttribute(FRAME_ATTR)) frame.setAttribute(FRAME_ATTR, 'frame')\n }\n ensure()\n const mo = new MutationObserver(ensure)\n mo.observe(document.documentElement, { childList: true, subtree: true })\n const onChange = (): void => { if (narrow.matches) ensure(); else clear() }\n narrow.addEventListener('change', onChange)\n return () => {\n mo.disconnect()\n narrow.removeEventListener('change', onChange)\n clear()\n }\n }, 'dshb-mobile: frame marker')\n}\n\n/**\n * 抽屉打开时覆盖内容区的半透明遮罩,点击关闭;Escape 同样关闭;\n * 点击抽屉内的会话/导航项后关闭抽屉。\n */\nfunction installDrawerInteractions(ctx: ClientContext, toggleSidebar: () => void): void {\n ctx.effect(() => {\n const narrow = window.matchMedia(MOBILE_QUERY)\n let backdrop: HTMLElement | null = null\n const drawerOpen = (): boolean => {\n const frame = getFrame()\n return narrow.matches && frame !== null && !frame.hasAttribute(COLLAPSED_ATTR)\n }\n const sync = (): void => {\n if (drawerOpen() && backdrop === null) {\n backdrop = document.createElement('div')\n backdrop.setAttribute(`${FRAME_ATTR}-backdrop`, '')\n backdrop.style.cssText = 'position:fixed;inset:0;z-index:39;background:rgba(0,0,0,.4);-webkit-tap-highlight-color:transparent;'\n backdrop.addEventListener('click', () => toggleSidebar())\n document.body.appendChild(backdrop)\n } else if (!drawerOpen() && backdrop !== null) {\n backdrop.remove()\n backdrop = null\n }\n }\n const onKeyDown = (event: KeyboardEvent): void => {\n if (event.key !== 'Escape') return\n if (document.querySelector('[aria-modal=\"true\"]') !== null) return\n if (drawerOpen()) toggleSidebar()\n }\n const onClick = (event: MouseEvent): void => {\n if (!drawerOpen()) return\n const target = event.target\n if (!(target instanceof Element)) return\n const drawer = document.querySelector(`[${FRAME_ATTR}=\"frame\"] > :first-child`)\n if (drawer === null || !drawer.contains(target)) return\n if (target.closest('button, a, [role=\"button\"]') !== null) return\n if (target.closest('[class*=\"newSession\"], [class*=\"sessionRow\"], [role=\"treeitem\"], [class*=\"searchResult\"]') !== null) toggleSidebar()\n }\n sync()\n const mo = new MutationObserver(sync)\n mo.observe(document.documentElement, { childList: true, subtree: true, attributes: true, attributeFilter: [COLLAPSED_ATTR] })\n document.addEventListener('keydown', onKeyDown, true)\n document.addEventListener('click', onClick, true)\n narrow.addEventListener('change', sync)\n return () => {\n mo.disconnect()\n document.removeEventListener('keydown', onKeyDown, true)\n document.removeEventListener('click', onClick, true)\n narrow.removeEventListener('change', sync)\n backdrop?.remove()\n }\n }, 'dshb-mobile: drawer interactions')\n}\n\n/** 对话/输入框下方的统计行(turns/steps/LLM/TPS):hashed class 无法直接选,按文本特征标记后由 CSS 横向滚动,避免溢出。 */\nfunction installStatsLine(ctx: ClientContext): void {\n ctx.effect(() => {\n const narrow = window.matchMedia(MOBILE_QUERY)\n // 统计行文本特征(\"3 轮 · 5 步 · LLM 2.1s · 缓存命中 80%\" 等),hashed class 无法直接选,按文本识别。\n // 含\"轮/步/turns/steps\"即可(footer 不含这些),无需额外排除 footer。\n const STATS_LINE_RE = /(\\d+\\s*轮|\\d+\\s*步|\\bturns\\b|\\bsteps\\b)/\n const isStatsText = (el: Element): boolean => {\n const text = (el.textContent ?? '').trim()\n if (text.length === 0 || text.length > 160) return false\n if (!STATS_LINE_RE.test(text)) return false\n if (el.querySelector('textarea, input, button, select, a') !== null) return false\n return true\n }\n const mark = (): void => {\n if (!narrow.matches) return\n // 清除失效标记:行容器仍含统计特征(轮/步)才保留\n document.querySelectorAll(`[${FRAME_ATTR}=\"stats\"]`).forEach((el) => {\n if (!el.isConnected || !STATS_LINE_RE.test((el.textContent ?? '').trim())) el.removeAttribute(FRAME_ATTR)\n })\n // 候选:含统计特征的短文本元素(全文档搜索,含 composer 内的 stats line),取最浅容器标记\n // 排除 display:contents(无 box,overflow 无效,会误占最浅候选)\n const cands = Array.from(document.querySelectorAll('span, div')).filter((el) => {\n if (!isStatsText(el)) return false\n if (getComputedStyle(el).display === 'contents') return false\n return true\n })\n for (const el of cands) {\n if (el.hasAttribute(FRAME_ATTR)) continue\n let anc = el.parentElement\n let hasOuterCand = false\n while (anc) {\n if (cands.includes(anc)) { hasOuterCand = true; break }\n anc = anc.parentElement\n }\n if (!hasOuterCand) {\n // 标最浅含统计的容器本身(整行),使其可横向滚动\n if (!el.hasAttribute(FRAME_ATTR)) el.setAttribute(FRAME_ATTR, 'stats')\n }\n }\n }\n mark()\n const mo = new MutationObserver(() => { if (narrow.matches) mark() })\n mo.observe(document.documentElement, { childList: true, subtree: true })\n narrow.addEventListener('change', mark)\n return () => {\n mo.disconnect()\n narrow.removeEventListener('change', mark)\n }\n }, 'dshb-mobile: stats line')\n}\n\n/** 浮层 fixed 定位需管理的内联样式键,清理时逐一移除以交还上游 CSS。 */\nconst SHEET_PROPS = [\n 'position', 'width', 'left', 'right', 'top', 'bottom',\n 'min-width', 'max-width', 'max-height', 'overflow-y', 'box-sizing',\n] as const\n\n/** Keep the model menu anchored to its trigger while fitting it in the viewport. */\nfunction positionAnchoredMenu(el: HTMLElement, triggerRect: DOMRect, maxWidth: number, maxHeight: number): void {\n const margin = 8\n const vw = window.innerWidth\n const vh = window.innerHeight\n el.style.setProperty('position', 'fixed', 'important')\n el.style.setProperty('box-sizing', 'border-box', 'important')\n el.style.setProperty('left', '0', 'important')\n el.style.setProperty('right', 'auto', 'important')\n el.style.setProperty('top', '0', 'important')\n el.style.setProperty('bottom', 'auto', 'important')\n el.style.setProperty('min-width', '0', 'important')\n el.style.setProperty('max-width', `${Math.max(0, Math.min(maxWidth, vw - margin * 2))}px`, 'important')\n el.style.setProperty('max-height', `${Math.max(0, Math.min(maxHeight, vh - margin * 2))}px`, 'important')\n el.style.setProperty('overflow-y', 'auto', 'important')\n let width = el.offsetWidth\n let height = el.offsetHeight\n const spaceAbove = Math.max(0, triggerRect.top - margin * 2)\n const spaceBelow = Math.max(0, vh - triggerRect.bottom - margin * 2)\n const expandUp = height <= spaceAbove || spaceAbove >= spaceBelow\n const available = expandUp ? spaceAbove : spaceBelow\n if (height > available) {\n el.style.setProperty('max-height', `${Math.max(0, available - margin)}px`, 'important')\n height = el.offsetHeight\n width = el.offsetWidth\n }\n const top = expandUp ? triggerRect.top - margin - height : triggerRect.bottom + margin\n const left = Math.max(margin, Math.min(triggerRect.right - width, vw - width - margin))\n el.style.setProperty('left', `${left}px`, 'important')\n el.style.setProperty('top', `${Math.max(margin, Math.min(top, vh - height - margin))}px`, 'important')\n}\n\n/**\n * 模型名多为纯连字符词(DeepSeek-V4-Flash-Vision-Exp);white-space:normal 下\n * 每个 \"-\" 都是软断点,名字一旦超列宽就在第一个连字符处断行(\"换行太早\")。\n * 把 \"-\" 就地换成不换行连字符 U+2011:放得下就整行显示,真超宽时仍由\n * overflow-wrap:break-word 兜底任意断。只改文本节点 data、不换节点,\n * 避免与 React 文本协调冲突;React 重渲染重置文本后由 MutationObserver\n * 重新应用(幂等:换过之后不再有 \"-\")。\n */\nfunction applyNonBreakingHyphens(menu: HTMLElement): void {\n for (const el of Array.from(menu.querySelectorAll<HTMLElement>('[class*=\"modelName\"]'))) {\n const tn = el.firstChild\n if (tn && tn.nodeType === Node.TEXT_NODE && tn.nodeValue !== null && tn.nodeValue.includes('-')) {\n tn.nodeValue = tn.nodeValue.replace(/-/g, '\\u2011')\n }\n }\n}\n\n/**\n * 模型名\"整行显示、不换行、不截断\":窄屏下把名字列里的所有 .modelName 设为\n * nowrap,并按\"最宽名字 vs 可用列宽\"统一缩小字号(下限 11px,上限 14px),\n * 让最长的名字也恰好放得下——从根上消除\"换行太早\"。只测一次最宽名字\n * (scrollWidth 一次布局读取),缩放结果应用到全部名字,保持同一字号。\n * 调用方按 vw + 名字集合签名缓存,避免每次 DOM 变更都强制作废布局。\n */\nfunction fitModelNameFont(menu: HTMLElement): void {\n const names = Array.from(menu.querySelectorAll<HTMLElement>('[class*=\"modelName\"]'))\n if (names.length === 0) return\n const col = names[0].parentElement\n if (col === null) return\n const colW = col.clientWidth - 4\n if (colW <= 0) return\n const base = 14\n let longest = names[0]\n for (const n of names) {\n if ((n.textContent?.length ?? 0) > (longest.textContent?.length ?? 0)) longest = n\n }\n const prevWs = longest.style.whiteSpace\n longest.style.whiteSpace = 'nowrap'\n longest.style.fontSize = `${base}px`\n const natural = longest.scrollWidth\n longest.style.whiteSpace = prevWs\n longest.style.fontSize = ''\n const fs = natural > colW ? Math.max(11, Math.min(base, Math.round(base * (colW / natural)))) : base\n for (const n of names) {\n n.style.setProperty('white-space', 'nowrap', 'important')\n n.style.setProperty('font-size', `${fs}px`, 'important')\n }\n}\n\n/** 宽屏(窄屏判定不成立)时复位名字列内联样式,交还上游 CSS(nowrap+ellipsis)。 */\nfunction clearModelNameFit(menu: HTMLElement | null | undefined): void {\n if (menu === null || menu === undefined) return\n for (const n of Array.from(menu.querySelectorAll<HTMLElement>('[class*=\"modelName\"]'))) {\n n.style.removeProperty('white-space')\n n.style.removeProperty('font-size')\n }\n}\n\n/** 清除 anchored menu 写入的内联样式,交还上游 CSS。 */\nfunction clearFixedSheet(el: HTMLElement | null | undefined): void {\n if (el === null || el === undefined) return\n for (const key of SHEET_PROPS) el.style.removeProperty(key)\n}\n\n/**\n * 模型选择弹窗(dsh-client-ui-model-selection)是两级 pane 的同一个 `_7KE1Ra_menu`\n * 元素:一级 Model/Effort 单元格列表(cellLabel),点击后切到模型列表(modelName)\n * 或档位列表。上游默认 `position:absolute;right:0` 贴触发按钮右缘,触发按钮在\n * 可横向滚动的 stats 行内时菜单会整体出屏。两级 pane 都必须接管(不能只按\n * modelName 匹配,否则一级 pane 漏掉)。所有视口都把菜单锚定到触发按钮,\n * 在上方/下方可用空间中选择更合适的一侧,避免上游空间不足时把菜单钳到屏幕顶端。\n */\nfunction installModelMenuPosition(ctx: ClientContext): void {\n ctx.effect(() => {\n const narrow = window.matchMedia(NARROW_QUERY)\n // 多 tab 场景可能并存多个模型选择器(各自一个 _menu);只处理可见的,\n // 避免 document.querySelector 命中隐藏 tab 的菜单而漏掉用户正在看的那个。\n const findMenus = (): HTMLElement[] => {\n const byHash = Array.from(document.querySelectorAll<HTMLElement>('[class*=\"7KE1Ra_menu\"]'))\n if (byHash.length > 0) return byHash\n // 上游升级换 hash 后回退:语义类匹配(cellLabel 命中一级 pane,modelName 命中二级)\n return Array.from(document.querySelectorAll<HTMLElement>('[class*=\"_menu\"]')).filter((el) =>\n el.querySelector('[class*=\"cellLabel\"], [class*=\"modelName\"]') !== null,\n )\n }\n const findTrigger = (menu: HTMLElement): HTMLElement | null => {\n if (menu.id) {\n const controlled = Array.from(document.querySelectorAll<HTMLElement>('[aria-controls]')).find(\n (el) => el.getAttribute('aria-controls') === menu.id,\n )\n if (controlled) return controlled\n }\n return document.querySelector<HTMLElement>('[class*=\"7KE1Ra_trigger\"][aria-expanded=\"true\"]')\n }\n let fittedVw = 0\n let fittedSig = -1\n let fittedMenus: HTMLElement[] = []\n let positionedMenus: HTMLElement[] = []\n const sync = (): void => {\n const menus = findMenus()\n let vw = 0\n let sig = 0\n const modelMenus: HTMLElement[] = []\n const visibleMenus: HTMLElement[] = []\n for (const menu of menus) {\n // 0.1.5 renders the menu through createPortal(..., document.body), so\n // parentElement is body rather than the trigger root. Match aria-controls\n // to the portal menu id to find the exact trigger across multiple tabs.\n const trigger = findTrigger(menu)\n if (trigger === null || trigger.getAttribute('aria-expanded') !== 'true') continue\n const rect = menu.getBoundingClientRect()\n // 跳过隐藏 tab / 未打开的菜单(0 尺寸或祖先 display:none)\n if (rect.width === 0 && rect.height === 0) continue\n const triggerRect = trigger.getBoundingClientRect()\n positionAnchoredMenu(menu, triggerRect, Math.min(420, window.innerWidth - 16), 360)\n visibleMenus.push(menu)\n if (menu.querySelector('[class*=\"modelName\"]')) {\n modelMenus.push(menu)\n if (narrow.matches) {\n applyNonBreakingHyphens(menu)\n vw = window.innerWidth\n for (const n of menu.querySelectorAll<HTMLElement>('[class*=\"modelName\"]')) {\n sig += n.textContent?.length ?? 0\n }\n }\n }\n }\n for (const previous of positionedMenus) {\n if (visibleMenus.includes(previous)) continue\n clearFixedSheet(previous)\n clearModelNameFit(previous)\n }\n positionedMenus = visibleMenus\n if (!narrow.matches) {\n for (const menu of modelMenus) clearModelNameFit(menu)\n fittedVw = 0\n fittedSig = -1\n fittedMenus = []\n return\n }\n // 菜单关闭再打开时 React 会重建菜单元素(新元素没有任何内联样式),\n // 所以缓存必须含元素身份:vw / 名字集合 / 菜单实例任一变化都要重测,\n // 否则重开的菜单会漏掉 nowrap+缩字而再次换行。\n const needFit = modelMenus.some((m) => !fittedMenus.includes(m))\n if (vw > 0 && (needFit || vw !== fittedVw || sig !== fittedSig)) {\n for (const menu of modelMenus) fitModelNameFont(menu)\n fittedVw = vw\n fittedSig = sig\n fittedMenus = modelMenus\n }\n }\n sync()\n const mo = new MutationObserver(() => requestAnimationFrame(sync))\n mo.observe(document.documentElement, { childList: true, subtree: true })\n narrow.addEventListener('change', sync)\n window.addEventListener('resize', sync)\n window.addEventListener('scroll', sync, true)\n return () => {\n mo.disconnect()\n narrow.removeEventListener('change', sync)\n window.removeEventListener('resize', sync)\n window.removeEventListener('scroll', sync, true)\n }\n }, 'dshb-mobile: model menu position')\n}\n\n/**\n * 上下文用量弹窗(ContextMeter .JObwrW_panel,dsh-client-ui-conversation)上游是\n * `position:absolute; bottom:calc(100%+8px); right:0` 挂 .JObwrW_root 内。窄屏下\n * 改为 fixed 视口浮层,右缘锚定触发按钮右缘、向上展开(用户已验证该形态正常,勿改)。\n */\nfunction installContextPanelPosition(ctx: ClientContext): void {\n ctx.effect(() => {\n const narrow = window.matchMedia(NARROW_QUERY)\n const sync = (): void => {\n if (!narrow.matches) return\n const panels = document.querySelectorAll<HTMLElement>('[class*=\"JObwrW_panel\"]')\n for (const panel of Array.from(panels)) {\n const root = panel.parentElement\n if (root === null || !root.className.includes('JObwrW_root')) continue\n const rootRect = root.getBoundingClientRect()\n if (rootRect.width === 0 && rootRect.height === 0) continue\n const gap = 8\n panel.style.setProperty('position', 'fixed', 'important')\n panel.style.setProperty('top', 'auto', 'important')\n panel.style.setProperty('bottom', `${window.innerHeight - rootRect.top + gap}px`, 'important')\n panel.style.setProperty('left', 'auto', 'important')\n panel.style.setProperty('right', `${Math.max(gap, window.innerWidth - rootRect.right)}px`, 'important')\n panel.style.setProperty('max-height', `${Math.max(160, rootRect.top - gap * 2)}px`, 'important')\n panel.style.setProperty('overflow-y', 'auto', 'important')\n }\n }\n sync()\n const mo = new MutationObserver(() => requestAnimationFrame(sync))\n mo.observe(document.documentElement, { childList: true, subtree: true })\n narrow.addEventListener('change', sync)\n window.addEventListener('resize', sync)\n window.addEventListener('scroll', sync, true)\n return () => {\n mo.disconnect()\n narrow.removeEventListener('change', sync)\n window.removeEventListener('resize', sync)\n window.removeEventListener('scroll', sync, true)\n }\n }, 'dshb-mobile: context panel position')\n}\n\nfunction installMobileTerminalInputFocus(ctx: ClientContext): void {\n ctx.effect(() => {\n const mobile = window.matchMedia(MOBILE_QUERY)\n const focusInput = (event: PointerEvent): void => {\n if (!mobile.matches || !(event.target instanceof Element)) return\n const terminal = event.target.closest('.xterm')\n const textarea = terminal?.querySelector<HTMLTextAreaElement>('.xterm-helper-textarea')\n if (!textarea || textarea.readOnly) return\n textarea.inputMode = 'text'\n textarea.focus({ preventScroll: true })\n try {\n const virtualKeyboard = (navigator as Navigator & { virtualKeyboard?: { show?: () => void } }).virtualKeyboard\n virtualKeyboard?.show?.()\n } catch {\n // The focus event still opens the keyboard on browsers without VirtualKeyboard API.\n }\n }\n document.addEventListener('pointerdown', focusInput, true)\n return () => document.removeEventListener('pointerdown', focusInput, true)\n }, 'dshb-mobile: terminal input focus')\n}\n\ninterface LayoutLike { toggleSidebar(): void }\ninterface SlotsLike {\n inject(name: string, fn: () => unknown): unknown\n register(spec: Record<string, unknown>, component: unknown): unknown\n}\n\n/** 目录抽屉切换按钮(仅切换,不含文件浏览/日志导出等功能按钮)。 */\nfunction DrawerToggle({ toggleSidebar }: { toggleSidebar: () => void }) {\n return (\n <button type=\"button\" data-dshb-mobile=\"toggle\" aria-label=\"打开目录\" title=\"打开目录\" onClick={() => toggleSidebar()}>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"1.5\" y=\"2.5\" width=\"13\" height=\"11\" rx=\"2\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M6 2.5v11\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n </svg>\n </button>\n )\n}\n\nconst PANEL_ICON_SVG =\n '<svg width=\"18\" height=\"18\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">' +\n '<rect x=\"1.5\" y=\"2.5\" width=\"13\" height=\"11\" rx=\"2\" stroke=\"currentColor\" strokeWidth=\"1.5\"/>' +\n '<path d=\"M6 2.5v11\" stroke=\"currentColor\" strokeWidth=\"1.5\"/>' +\n '</svg>'\n\n/**\n * 首页 / hero(无活跃会话)没有 session header,header 上的切换按钮不渲染;\n * 这里在 frame 上注入一个浮动切换按钮(FAB),仅 hero 且抽屉收起时显示。\n */\nfunction installFab(ctx: ClientContext, toggleSidebar: () => void): void {\n ctx.effect(() => {\n const narrow = window.matchMedia(MOBILE_QUERY)\n const FAB_ATTR = 'fab'\n const heroPhase = (): boolean => document.querySelector('[data-phase=\"active\"]') === null\n const drawerOpen = (): boolean => {\n const frame = getFrame()\n return frame !== null && !frame.hasAttribute(COLLAPSED_ATTR)\n }\n let fab: HTMLButtonElement | null = null\n const sync = (): void => {\n if (!narrow.matches || !heroPhase() || drawerOpen()) {\n if (fab !== null) {\n fab.remove()\n fab = null\n }\n return\n }\n const frame = getFrame()\n if (frame === null) return\n if (fab !== null && fab.parentElement === frame) return\n fab?.remove()\n fab = document.createElement('button')\n fab.type = 'button'\n fab.setAttribute(FRAME_ATTR, FAB_ATTR)\n fab.setAttribute('aria-label', '打开目录')\n fab.setAttribute('title', '打开目录')\n fab.innerHTML = PANEL_ICON_SVG\n fab.addEventListener('click', toggleSidebar)\n frame.appendChild(fab)\n }\n sync()\n const mo = new MutationObserver(sync)\n mo.observe(document.documentElement, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['data-phase', 'data-sidebar-collapsed', 'class'],\n })\n narrow.addEventListener('change', sync)\n return () => {\n mo.disconnect()\n narrow.removeEventListener('change', sync)\n fab?.remove()\n }\n }, 'dshb-mobile: hero fab')\n}\n\n/** 安装移动端适配:样式 + viewport + 抽屉标记 + 抽屉交互 + 切换按钮。 */\nexport function installMobile(ctx: ClientContext): void {\n installStyles(ctx)\n installMobileTerminalInputFocus(ctx)\n installViewport(ctx)\n installFrameMarker(ctx)\n installStatsLine(ctx)\n installModelMenuPosition(ctx)\n installContextPanelPosition(ctx)\n const layout = (ctx as unknown as { layout?: LayoutLike }).layout\n const slots = (ctx as unknown as { slots?: SlotsLike }).slots\n if (layout && typeof layout.toggleSidebar === 'function') {\n const toggleSidebar = (): void => layout.toggleSidebar()\n installDrawerInteractions(ctx, toggleSidebar)\n installFab(ctx, toggleSidebar)\n }\n if (slots && layout) {\n slots.inject('conversation.session.header.actions', () =>\n slots.register(\n {\n name: 'conversation.session.header.actions',\n id: 'dshb-mobile-toggle',\n order: 10,\n inject: () => ({ toggleSidebar: () => layout.toggleSidebar() }),\n },\n DrawerToggle,\n ),\n )\n }\n}\n","import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\n\ninterface WorkspaceItem {\n workspaceId: string\n title: string\n path: string\n}\n\ninterface WorkspaceSnapshotLike {\n items: readonly WorkspaceItem[]\n}\n\ninterface WorkspacesLike {\n list: {\n getSnapshot(): WorkspaceSnapshotLike\n subscribe(listener: () => void): () => void\n }\n}\n\nlet injectedRegistry: WorkspacesLike | undefined\n\nexport function setWorkspaceRegistry(reg: WorkspacesLike): void {\n injectedRegistry = reg\n}\n\nfunction resolveWorkspaceByTitle(title: string): WorkspaceItem | undefined {\n const wks = injectedRegistry\n if (!wks) return undefined\n const items = wks.list.getSnapshot().items\n return items.find((w) => w.title === title)\n}\n\nconst ROW_INJECT_FLAG = 'data-dshb-instr-row-bound'\nconst MENU_INJECT_FLAG = 'data-dshb-instr-menu-bound'\nconst MENU_ITEM_FLAG = 'data-dshb-instr-menu-item'\n\nfunction mountInstructionDialog(workspaceId: string, workspaceTitle: string): void {\n if (!workspaceId) return\n\n const overlay = document.createElement('div')\n overlay.style.cssText = 'position:fixed;inset:0;z-index:1100;display:flex;align-items:center;justify-content:center;background:var(--dsw-alias-overlay-mask,rgba(0,0,0,.45))'\n\n const dialog = document.createElement('div')\n dialog.setAttribute('role', 'dialog')\n dialog.setAttribute('aria-label', `修改 ${workspaceTitle} 的项目指令`)\n dialog.style.cssText = 'box-sizing:border-box;width:min(92vw,600px);max-height:85vh;overflow:auto;padding:20px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary)'\n\n const title = document.createElement('h2')\n title.textContent = `项目指令 - ${workspaceTitle}`\n title.style.cssText = 'margin:0 0 10px;font-size:16px'\n\n const description = document.createElement('div')\n description.textContent = '此内容会注入该工作区的新对话。已有对话继续使用创建时的指令快照。'\n description.style.cssText = 'margin-bottom:10px;font-size:12px;color:var(--dsw-alias-label-secondary)'\n\n const textarea = document.createElement('textarea')\n textarea.placeholder = '留空则不注入指令...'\n textarea.spellcheck = false\n textarea.style.cssText = 'box-sizing:border-box;width:100%;min-height:280px;resize:vertical;padding:12px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;outline:none;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font:13px monospace'\n\n const status = document.createElement('div')\n status.style.cssText = 'min-height:18px;margin-top:6px;font-size:12px;color:var(--dsw-alias-label-secondary)'\n\n const actions = document.createElement('div')\n actions.style.cssText = 'display:flex;justify-content:flex-end;gap:10px;margin-top:14px'\n const cancel = document.createElement('button')\n cancel.type = 'button'\n cancel.textContent = '取消'\n cancel.style.cssText = 'height:36px;padding:0 16px;border:1px solid var(--dsw-alias-border-l2);border-radius:18px;background:transparent;color:var(--dsw-alias-label-primary);cursor:pointer'\n const save = document.createElement('button')\n save.type = 'button'\n save.textContent = '保存'\n save.style.cssText = 'height:36px;padding:0 16px;border:0;border-radius:18px;background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground);cursor:pointer'\n\n const close = (): void => overlay.remove()\n cancel.addEventListener('click', close)\n overlay.addEventListener('click', (event) => {\n if (event.target === overlay) close()\n })\n dialog.addEventListener('click', (event) => event.stopPropagation())\n textarea.addEventListener('input', () => {\n const bytes = new TextEncoder().encode(textarea.value).length\n status.textContent = `${bytes} / 32768 字节`\n status.style.color = bytes > 32768 ? 'var(--dsw-alias-state-error-primary)' : 'var(--dsw-alias-label-secondary)'\n })\n save.addEventListener('click', () => {\n void (async () => {\n const bytes = new TextEncoder().encode(textarea.value).length\n if (bytes > 32768) {\n status.textContent = `指令超过 32768 字节限制(当前 ${bytes} 字节)`\n status.style.color = 'var(--dsw-alias-state-error-primary)'\n return\n }\n save.disabled = true\n save.textContent = '保存中...'\n try {\n const revision = Number(overlay.dataset.revision ?? '0')\n const response = await fetch(`/api/dshb/instructions/${workspaceId}`, {\n method: 'PUT',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ text: textarea.value, expectedRevision: revision }),\n })\n if (!response.ok) {\n const body = await response.json().catch(() => ({})) as { error?: string }\n status.textContent = body.error ?? `保存失败 (${response.status})`\n status.style.color = 'var(--dsw-alias-state-error-primary)'\n return\n }\n close()\n } catch {\n status.textContent = '保存失败'\n status.style.color = 'var(--dsw-alias-state-error-primary)'\n } finally {\n save.disabled = false\n save.textContent = '保存'\n }\n })()\n })\n\n actions.append(cancel, save)\n dialog.append(title, description, textarea, status, actions)\n overlay.append(dialog)\n document.body.append(overlay)\n\n status.textContent = '加载中...'\n void fetch(`/api/dshb/instructions/${workspaceId}`)\n .then(async (response) => {\n if (!response.ok) throw new Error(`读取失败 (${response.status})`)\n return response.json() as Promise<{ text?: string; revision?: number }>\n })\n .then((body) => {\n textarea.value = body.text ?? ''\n overlay.dataset.revision = String(body.revision ?? 0)\n textarea.dispatchEvent(new Event('input'))\n textarea.focus()\n })\n .catch((error: unknown) => {\n status.textContent = error instanceof Error ? error.message : '读取失败'\n status.style.color = 'var(--dsw-alias-state-error-primary)'\n })\n}\n\nexport function registerWorkspaceInstructionMenu(ctx: ClientContext): void {\n const wks = (ctx as unknown as { workspaces?: WorkspacesLike }).workspaces\n if (wks) setWorkspaceRegistry(wks)\n\n let activeWorkspaceTitle = ''\n\n const findWorkspaceRow = (el: Node | null): HTMLElement | null => {\n let node = el instanceof HTMLElement ? el : null\n while (node) {\n if (node.className && typeof node.className === 'string' && node.className.includes('projectRow')) {\n return node\n }\n node = node.parentElement\n }\n return null\n }\n\n const getRowTitle = (row: HTMLElement): string | null => {\n const titleEl = row.querySelector('[class*=\"title\"]')\n if (!titleEl) return null\n return titleEl.textContent ?? null\n }\n\n const injectMenuItem = (menuContainer: HTMLElement): void => {\n if (menuContainer.getAttribute(MENU_INJECT_FLAG) || menuContainer.querySelector(`[${MENU_ITEM_FLAG}]`)) return\n menuContainer.setAttribute(MENU_INJECT_FLAG, '1')\n\n const existingItems = menuContainer.querySelectorAll('button, [role=\"menuitem\"]')\n let refItem: Element | null = null\n for (const item of Array.from(existingItems)) {\n const text = item.textContent ?? ''\n if (text.includes('重命名') || text.includes('Rename')) {\n refItem = item\n break\n }\n }\n if (!refItem) refItem = existingItems[existingItems.length - 1]\n if (!refItem) return\n\n const btn = document.createElement('button')\n btn.type = 'button'\n btn.setAttribute('role', 'menuitem')\n btn.setAttribute(MENU_ITEM_FLAG, '1')\n if (refItem instanceof HTMLElement) {\n btn.className = refItem.className || ''\n btn.style.cssText = refItem.style.cssText\n }\n for (const className of Array.from(btn.classList)) {\n if (/danger|delete/i.test(className)) btn.classList.remove(className)\n }\n btn.style.color = 'var(--dsw-alias-label-primary)'\n btn.style.display = 'flex'\n btn.style.alignItems = 'center'\n btn.style.gap = '8px'\n\n const icon = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n icon.setAttribute('width', '16')\n icon.setAttribute('height', '16')\n icon.setAttribute('viewBox', '0 0 16 16')\n icon.setAttribute('fill', 'none')\n icon.setAttribute('aria-hidden', 'true')\n icon.style.flex = 'none'\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n path.setAttribute('d', 'M3 11.75V13h1.25l7.37-7.37-1.25-1.25L3 11.75Zm9.59-7.34a.66.66 0 0 0 0-.94l-1.06-1.06a.66.66 0 0 0-.94 0l-.83.83 1.25 1.25.83-.83.75.75Z')\n path.setAttribute('fill', 'currentColor')\n icon.append(path)\n const label = document.createElement('span')\n label.textContent = '修改指令'\n btn.append(icon, label)\n btn.addEventListener('click', (e) => {\n e.stopPropagation()\n e.preventDefault()\n const ws = activeWorkspaceTitle ? resolveWorkspaceByTitle(activeWorkspaceTitle) : undefined\n mountInstructionDialog(ws?.workspaceId ?? '', activeWorkspaceTitle || 'Unknown')\n })\n\n refItem.parentElement?.insertBefore(btn, refItem.nextSibling)\n }\n\n const observer = new MutationObserver(() => {\n const projectRows = document.querySelectorAll('[class*=\"projectRow\"]')\n for (const row of Array.from(projectRows)) {\n const rowEl = row as HTMLElement\n if (rowEl.getAttribute(ROW_INJECT_FLAG)) continue\n rowEl.setAttribute(ROW_INJECT_FLAG, '1')\n const iconBtns = rowEl.querySelectorAll('button[class*=\"iconButton\"]')\n for (const btn of Array.from(iconBtns)) {\n const label = btn.getAttribute('aria-label') ?? ''\n if (label.includes('workspace') || label.includes('操作') || label.includes('actions')) {\n btn.addEventListener('click', () => {\n const title = getRowTitle(rowEl)\n if (title) activeWorkspaceTitle = title\n })\n }\n }\n }\n\n const menuItems = document.querySelectorAll('[role=\"menuitem\"]')\n for (const item of Array.from(menuItems)) {\n const text = item.textContent ?? ''\n if (text.includes('删除') || text.includes('Delete') || text.includes('重命名') || text.includes('Rename')) {\n const container = item.closest('[role=\"menu\"]') ?? item.parentElement\n if (container instanceof HTMLElement && !container.getAttribute(MENU_INJECT_FLAG)) {\n const row = findWorkspaceRow(container)\n if (row) {\n const title = getRowTitle(row)\n if (title) activeWorkspaceTitle = title\n }\n injectMenuItem(container)\n }\n }\n }\n })\n observer.observe(document.body, { childList: true, subtree: true })\n}\n","import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-workspace/client'\nimport type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { CSSProperties, ReactElement } from 'react'\nimport { useCallback, useEffect, useState } from 'react'\nimport { DirectoryFlowOccupant } from './directory-flow.js'\nimport { installMobile } from './mobile.js'\nimport { registerWorkspaceInstructionMenu } from './workspace-instruction-menu.js'\n\nexport const inject = ['connection', 'workspaces', 'slots', 'layout', 'conversation']\n\nconst SECTION_ID = 'dshb-nodes'\n\ninterface NodeProfileView {\n id: string\n name: string\n type: 'local-host' | 'local-docker' | 'remote-ssh' | 'remote-docker'\n ssh?: {\n host: string\n port: number\n username: string\n auth: { kind: 'password' | 'key' | 'agent'; keyPath?: string }\n }\n docker?: {\n image?: string\n containerId?: string\n mode?: string\n resources?: { cpus?: number; memoryMB?: number }\n }\n hasSecret: { hasPassword: boolean; hasKey: boolean; hasPassphrase: boolean }\n status?: { reachable?: boolean; lastCheckedAt?: string; error?: string }\n provision?: { state: 'provisioning' | 'ready' | 'failed'; error?: string; containerId?: string; updatedAt: string }\n}\n\ninterface SshConfigEntryView {\n host: string\n port: number\n username: string\n identityFile?: string\n hasIdentityFile: boolean\n hasProxyJump: boolean\n}\n\ninterface FormState {\n name: string\n type: 'local-host' | 'local-docker' | 'remote-ssh' | 'remote-docker'\n host: string\n port: string\n username: string\n authKind: 'password' | 'key' | 'agent'\n password: string\n privateKey: string\n passphrase: string\n keyPath: string\n dockerImage: string\n dockerCpus: string\n dockerMemory: string\n}\n\nconst EMPTY_FORM: FormState = {\n name: '',\n type: 'remote-ssh',\n host: '',\n port: '22',\n username: '',\n authKind: 'password',\n password: '',\n privateKey: '',\n passphrase: '',\n keyPath: '',\n dockerImage: '',\n dockerCpus: '',\n dockerMemory: '',\n}\n\ntype Notice = { kind: 'ok' | 'error'; text: string } | undefined\n\nconst inputStyle: CSSProperties = {\n width: '100%',\n boxSizing: 'border-box',\n padding: '0 10px',\n height: 32,\n border: '1px solid var(--dsw-alias-border-l2)',\n borderRadius: 8,\n fontSize: 14,\n fontFamily: 'inherit',\n background: 'var(--dsw-alias-bg-layer-1)',\n color: 'var(--dsw-alias-label-primary)',\n outline: 'none',\n}\nconst buttonStyle: CSSProperties = {\n boxSizing: 'border-box',\n height: 36,\n padding: '0 14px',\n borderRadius: 18,\n fontSize: 14,\n lineHeight: '22px',\n fontFamily: 'inherit',\n cursor: 'pointer',\n border: 'none',\n display: 'inline-flex',\n justifyContent: 'center',\n alignItems: 'center',\n gap: 4,\n}\nconst primaryButtonStyle: CSSProperties = {\n ...buttonStyle,\n background: 'var(--dsw-alias-button-primary-fill)',\n color: 'var(--dsw-alias-label-primary-foreground)',\n}\nconst secondaryButtonStyle: CSSProperties = {\n ...buttonStyle,\n border: '1px solid var(--dsw-alias-border-l2)',\n color: 'var(--dsw-alias-label-primary)',\n background: 'transparent',\n}\nconst dangerOutlineButtonStyle: CSSProperties = {\n ...buttonStyle,\n border: '1px solid var(--dsw-alias-state-error-primary)',\n color: 'var(--dsw-alias-state-error-primary)',\n background: 'transparent',\n}\n\nfunction useNodes(reloadKey: number): NodeProfileView[] {\n const [nodes, setNodes] = useState<NodeProfileView[]>([])\n useEffect(() => {\n let cancelled = false\n void (async () => {\n try {\n const res = await fetch('/api/dshb/nodes')\n if (!res.ok) return\n const data = (await res.json()) as { nodes?: NodeProfileView[] }\n if (!cancelled) setNodes(data.nodes ?? [])\n } catch {}\n })()\n return () => {\n cancelled = true\n }\n }, [reloadKey])\n return nodes\n}\n\nexport function NodeSection(_props: PropsRuntime<'settings.section'>): ReactElement {\n const [reloadKey, setReloadKey] = useState(0)\n const nodes = useNodes(reloadKey)\n const [selectedId, setSelectedId] = useState<string | 'new'>('new')\n const [form, setForm] = useState<FormState>(EMPTY_FORM)\n const [notice, setNotice] = useState<Notice>(undefined)\n const [busy, setBusy] = useState(false)\n const [testing, setTesting] = useState(false)\n const [testResult, setTestResult] = useState<string | undefined>(undefined)\n const [sshConfigEntries, setSshConfigEntries] = useState<SshConfigEntryView[]>([])\n const [dockerBusy, setDockerBusy] = useState(false)\n\n const flash = useCallback((n: Notice) => {\n setNotice(n)\n if (n) setTimeout(() => setNotice(undefined), 6000)\n }, [])\n\n const reload = useCallback(() => setReloadKey((k) => k + 1), [])\n\n useEffect(() => {\n void (async () => {\n try {\n const res = await fetch('/api/dshb/ssh-config')\n if (!res.ok) return\n const data = (await res.json()) as { entries?: SshConfigEntryView[] }\n setSshConfigEntries(data.entries ?? [])\n } catch {}\n })()\n }, [])\n\n const selectNode = useCallback(\n (id: string | 'new') => {\n setSelectedId(id)\n setTestResult(undefined)\n setTesting(false)\n setDockerBusy(false)\n if (id === 'new') {\n setForm(EMPTY_FORM)\n return\n }\n const node = nodes.find((n) => n.id === id)\n if (!node) return\n setForm({\n name: node.name,\n type: node.type,\n host: node.ssh?.host ?? '',\n port: String(node.ssh?.port ?? 22),\n username: node.ssh?.username ?? '',\n authKind: node.ssh?.auth.kind ?? 'password',\n password: '',\n privateKey: '',\n passphrase: '',\n keyPath: node.ssh?.auth.keyPath ?? '',\n dockerImage: node.docker?.image ?? '',\n dockerCpus: node.docker?.resources?.cpus != null ? String(node.docker?.resources?.cpus) : '',\n dockerMemory: node.docker?.resources?.memoryMB != null ? String(node.docker?.resources?.memoryMB) : '',\n })\n },\n [nodes],\n )\n\n const importSshConfig = useCallback((entry: SshConfigEntryView) => {\n setForm((f) => ({\n ...f,\n type: 'remote-ssh',\n host: entry.host,\n port: String(entry.port),\n username: entry.username,\n authKind: entry.hasIdentityFile ? 'key' : f.authKind,\n keyPath: entry.identityFile ?? f.keyPath,\n name: f.name || entry.host,\n }))\n setTestResult(undefined)\n flash({ kind: 'ok', text: `已从 ~/.ssh/config 导入 ${entry.host}` })\n }, [flash])\n\n const save = useCallback(async () => {\n if (!form.name.trim()) {\n flash({ kind: 'error', text: '请填写节点名称' })\n return\n }\n setBusy(true)\n try {\n const isRemote = form.type === 'remote-ssh' || form.type === 'remote-docker'\n const isDocker = form.type === 'local-docker' || form.type === 'remote-docker'\n const payload: Record<string, unknown> = {\n name: form.name.trim(),\n type: form.type,\n ssh: isRemote\n ? {\n host: form.host.trim(),\n port: Number(form.port) || 22,\n username: form.username.trim(),\n auth: { kind: form.authKind, ...(form.keyPath.trim() ? { keyPath: form.keyPath.trim() } : {}) },\n }\n : undefined,\n secrets: isRemote\n ? {\n ...(form.password ? { password: form.password } : {}),\n ...(form.privateKey ? { privateKey: form.privateKey } : {}),\n ...(form.passphrase ? { passphrase: form.passphrase } : {}),\n }\n : undefined,\n docker: isDocker\n ? {\n mode: 'managed' as const,\n ...(form.dockerImage.trim() ? { image: form.dockerImage.trim() } : {}),\n ...(form.dockerCpus ? { resources: { cpus: Number(form.dockerCpus) || undefined } } : {}),\n ...(form.dockerMemory ? { resources: { memoryMB: Number(form.dockerMemory) || undefined } } : {}),\n ...(form.dockerCpus && form.dockerMemory ? { resources: { cpus: Number(form.dockerCpus) || undefined, memoryMB: Number(form.dockerMemory) || undefined } } : {}),\n }\n : undefined,\n }\n const url = selectedId === 'new' ? '/api/dshb/nodes' : `/api/dshb/nodes/${selectedId}`\n const res = await fetch(url, {\n method: selectedId === 'new' ? 'POST' : 'PATCH',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n const data = (await res.json()) as { ok?: boolean; error?: string; node?: NodeProfileView }\n if (res.ok && data.ok) {\n flash({ kind: 'ok', text: selectedId === 'new' ? '节点已创建' : '节点已保存' })\n reload()\n if (data.node) setSelectedId(data.node.id)\n } else {\n flash({ kind: 'error', text: data.error ?? '保存失败' })\n }\n } catch {\n flash({ kind: 'error', text: '网络错误' })\n } finally {\n setBusy(false)\n }\n }, [form, selectedId, flash, reload])\n\n const remove = useCallback(async () => {\n if (selectedId === 'new') return\n setBusy(true)\n try {\n const res = await fetch(`/api/dshb/nodes/${selectedId}`, { method: 'DELETE' })\n const data = (await res.json()) as { ok?: boolean; error?: string }\n if (res.ok && data.ok) {\n flash({ kind: 'ok', text: '节点已删除' })\n setSelectedId('new')\n setForm(EMPTY_FORM)\n reload()\n } else {\n flash({ kind: 'error', text: data.error ?? '删除失败' })\n }\n } catch {\n flash({ kind: 'error', text: '删除失败' })\n } finally {\n setBusy(false)\n }\n }, [selectedId, flash, reload])\n\n const test = useCallback(async () => {\n if (form.type === 'local-host') {\n flash({ kind: 'error', text: '本地节点无需测试连接' })\n return\n }\n const isRemote = form.type === 'remote-ssh' || form.type === 'remote-docker'\n if (isRemote && !form.host.trim()) {\n flash({ kind: 'error', text: '请填写主机地址' })\n return\n }\n setTesting(true)\n setTestResult(undefined)\n try {\n const payload = isRemote ? {\n ssh: {\n host: form.host.trim(),\n port: Number(form.port) || 22,\n username: form.username.trim(),\n auth: { kind: form.authKind, ...(form.keyPath.trim() ? { keyPath: form.keyPath.trim() } : {}) },\n },\n secrets: {\n ...(form.password ? { password: form.password } : {}),\n ...(form.privateKey ? { privateKey: form.privateKey } : {}),\n ...(form.passphrase ? { passphrase: form.passphrase } : {}),\n },\n } : {}\n const url = selectedId === 'new' ? '/api/dshb/nodes/test-unsaved' : `/api/dshb/nodes/${selectedId}/test`\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n const data = (await res.json()) as { ok?: boolean; report?: { ok?: boolean; reachable?: boolean; error?: string; category?: string } }\n const r = data.report\n if (r?.ok && r.reachable) {\n setTestResult('连接成功')\n } else {\n const cat = r?.category ? `(${r.category})` : ''\n setTestResult(`${r?.error ?? '连接失败'}${cat}`)\n }\n reload()\n } catch {\n setTestResult('网络错误')\n } finally {\n setTesting(false)\n }\n }, [form, selectedId, reload])\n\n const dockerAction = useCallback(async (action: 'restart' | 'stop' | 'start' | 'provision') => {\n if (selectedId === 'new') return\n if (action === 'provision') {\n setDockerBusy(true)\n try {\n const res = await fetch(`/api/dshb/docker/${selectedId}/provision`, { method: 'POST' })\n const data = (await res.json()) as { ok?: boolean; error?: string; containerId?: string }\n if (res.ok && data.ok) {\n flash({ kind: 'ok', text: `容器已就绪:${data.containerId?.slice(0, 12) ?? ''}` })\n } else {\n flash({ kind: 'error', text: data.error ?? '拉起失败' })\n }\n reload()\n } catch {\n flash({ kind: 'error', text: '网络错误' })\n } finally {\n setDockerBusy(false)\n }\n return\n }\n setDockerBusy(true)\n try {\n const res = await fetch(`/api/dshb/docker/${selectedId}/${action}`, { method: 'POST' })\n const data = (await res.json()) as { ok?: boolean; error?: string }\n if (res.ok && data.ok) {\n flash({ kind: 'ok', text: action === 'restart' ? '容器已重启' : action === 'stop' ? '容器已停止' : '容器已启动' })\n } else {\n flash({ kind: 'error', text: data.error ?? '操作失败' })\n }\n reload()\n } catch {\n flash({ kind: 'error', text: '网络错误' })\n } finally {\n setDockerBusy(false)\n }\n }, [selectedId, flash, reload])\n\n const selectedNode = selectedId === 'new' ? undefined : nodes.find((n) => n.id === selectedId)\n\n return (\n <>\n <style>{`\n @media (max-width:767px){\n .dshb-node-section{flex-direction:column!important}\n .dshb-node-section>div:first-child{width:100%!important;border-right:none!important;border-bottom:1px solid var(--dsw-alias-border-l2);padding-right:0!important;padding-bottom:12px;margin-bottom:12px}\n .dshb-node-section>div:last-child{max-width:100%!important}\n .dshb-form-row{flex-direction:column!important;gap:8px!important}\n .dshb-form-row>label{width:100%!important;flex:none!important}\n }\n `}</style>\n <div className=\"dshb-node-section\" style={{ display: 'flex', gap: 20, minHeight: 320, overflow: 'hidden', maxWidth: '100%', width: '100%', boxSizing: 'border-box' }}>\n <div style={{ width: 200, flexShrink: 0, borderRight: '1px solid var(--dsw-alias-border-l2)', paddingRight: 16 }}>\n <button type=\"button\" onClick={() => selectNode('new')} style={{ ...primaryButtonStyle, width: '100%', marginBottom: 10 }}>\n 新建节点\n </button>\n {nodes.map((n) => (\n <div\n key={n.id}\n onClick={() => selectNode(n.id)}\n style={{\n padding: '8px 10px',\n borderRadius: 6,\n cursor: 'pointer',\n marginBottom: 4,\n background: selectedId === n.id ? 'var(--dsw-alias-interactive-bg-active, var(--dsw-alias-interactive-bg-hover))' : 'transparent',\n fontSize: 13,\n }}\n >\n <div style={{ fontWeight: 500 }}>{n.name}</div>\n <div style={{ fontSize: 11, opacity: 0.7, display: 'flex', alignItems: 'center', gap: 4 }}>\n <span\n style={{\n width: 6,\n height: 6,\n borderRadius: '50%',\n background: n.status?.reachable === true ? 'var(--dsw-alias-state-success-primary)' : n.status?.reachable === false ? 'var(--dsw-alias-state-error-primary)' : 'var(--dsw-alias-label-dimmed)',\n }}\n />\n {n.type === 'local-host' ? '默认环境(本地)' : n.type === 'remote-ssh' ? '远程 SSH' : n.type === 'local-docker' ? '本地 Docker' : n.type === 'remote-docker' ? '远程 Docker' : n.type}\n <span style={{ marginLeft: 4, color: n.status?.reachable === true ? 'var(--dsw-alias-state-success-primary)' : n.status?.reachable === false ? 'var(--dsw-alias-state-error-primary)' : 'var(--dsw-alias-label-dimmed)' }}>\n {n.status?.reachable === true ? '在线' : n.status?.reachable === false ? '离线' : '未知'}\n </span>\n </div>\n {n.provision && (\n <div style={{ fontSize: 11, marginTop: 2, color: n.provision.state === 'ready' ? 'var(--dsw-alias-state-success-primary)' : n.provision.state === 'failed' ? 'var(--dsw-alias-state-error-primary)' : 'var(--dsw-alias-state-warn-label)' }}>\n {n.provision.state === 'provisioning' ? '容器拉起中…' : n.provision.state === 'ready' ? '容器已就绪' : `容器拉起失败:${n.provision.error ?? '未知错误'}`}\n </div>\n )}\n </div>\n ))}\n {nodes.length === 0 && <div style={{ fontSize: 12, opacity: 0.6 }}>暂无节点</div>}\n </div>\n\n <div style={{ flex: 1, maxWidth: 480, minWidth: 0, overflow: 'hidden' }}>\n {sshConfigEntries.length > 0 && (\n <div style={{ marginBottom: 14 }}>\n <label style={{ fontSize: 12, opacity: 0.75, display: 'block', marginBottom: 4 }}>从 ~/.ssh/config 导入</label>\n <select\n style={inputStyle}\n value=\"\"\n onChange={(e) => {\n const entry = sshConfigEntries[Number(e.target.value)]\n if (entry) importSshConfig(entry)\n e.target.value = ''\n }}\n >\n <option value=\"\">选择主机…</option>\n {sshConfigEntries.map((entry, i) => (\n <option key={entry.host} value={i}>\n {entry.host}:{entry.port}{entry.username ? ` (${entry.username})` : ''}{entry.hasProxyJump ? ' 跳板' : ''}\n </option>\n ))}\n </select>\n </div>\n )}\n\n <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 节点名称\n <input style={inputStyle} value={form.name} onChange={(e) => setForm((f) => ({ ...f, name: e.target.value }))} placeholder=\"例如:构建机\" />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 节点类型\n <select style={inputStyle} value={form.type} onChange={(e) => setForm((f) => ({ ...f, type: e.target.value as FormState['type'] }))}>\n <option value=\"remote-ssh\">远程 SSH 宿主机</option>\n <option value=\"remote-docker\">远程 Docker(SSH 通道)</option>\n <option value=\"local-host\">默认环境(本地)</option>\n <option value=\"local-docker\">本地 Docker 容器</option>\n </select>\n </label>\n\n {(form.type === 'remote-ssh' || form.type === 'remote-docker') && (\n <>\n <div className=\"dshb-form-row\" style={{ display: 'flex', gap: 10 }}>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13, flex: 1, minWidth: 0 }}>\n 主机地址\n <input style={inputStyle} value={form.host} onChange={(e) => setForm((f) => ({ ...f, host: e.target.value }))} placeholder=\"192.168.1.10\" />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13, width: 90 }}>\n 端口\n <input style={inputStyle} value={form.port} onChange={(e) => setForm((f) => ({ ...f, port: e.target.value }))} />\n </label>\n </div>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 用户名\n <input style={inputStyle} value={form.username} onChange={(e) => setForm((f) => ({ ...f, username: e.target.value }))} placeholder=\"root\" />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 认证方式\n <select style={inputStyle} value={form.authKind} onChange={(e) => setForm((f) => ({ ...f, authKind: e.target.value as FormState['authKind'] }))}>\n <option value=\"password\">密码</option>\n <option value=\"key\">私钥</option>\n <option value=\"agent\">ssh-agent</option>\n </select>\n </label>\n {form.authKind === 'password' && (\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 密码{selectedNode?.hasSecret.hasPassword ? '(已保存,留空保持不变)' : ''}\n <input style={inputStyle} type=\"password\" value={form.password} onChange={(e) => setForm((f) => ({ ...f, password: e.target.value }))} autoComplete=\"new-password\" />\n </label>\n )}\n {form.authKind === 'key' && (\n <>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 私钥内容{selectedNode?.hasSecret.hasKey ? '(已保存,留空保持不变)' : ''}\n <textarea style={{ ...inputStyle, minHeight: 90, resize: 'vertical' }} value={form.privateKey} onChange={(e) => setForm((f) => ({ ...f, privateKey: e.target.value }))} placeholder=\"-----BEGIN OPENSSH PRIVATE KEY-----\" />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 私钥 passphrase(可选)\n <input style={inputStyle} type=\"password\" value={form.passphrase} onChange={(e) => setForm((f) => ({ ...f, passphrase: e.target.value }))} autoComplete=\"new-password\" />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 或私钥文件路径(可选,优先使用内容)\n <input style={inputStyle} value={form.keyPath} onChange={(e) => setForm((f) => ({ ...f, keyPath: e.target.value }))} placeholder=\"~/.ssh/id_ed25519\" />\n </label>\n </>\n )}\n </>\n )}\n\n {(form.type === 'local-docker' || form.type === 'remote-docker') && (\n <>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 镜像地址\n <input style={inputStyle} value={form.dockerImage} onChange={(e) => setForm((f) => ({ ...f, dockerImage: e.target.value }))} placeholder=\"alpine:latest\" />\n </label>\n <div className=\"dshb-form-row\" style={{ display: 'flex', gap: 10 }}>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13, flex: 1, minWidth: 0 }}>\n CPU 核数(可选)\n <input style={inputStyle} value={form.dockerCpus} onChange={(e) => setForm((f) => ({ ...f, dockerCpus: e.target.value }))} placeholder=\"2\" />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13, flex: 1, minWidth: 0 }}>\n 内存 MB(可选)\n <input style={inputStyle} value={form.dockerMemory} onChange={(e) => setForm((f) => ({ ...f, dockerMemory: e.target.value }))} placeholder=\"512\" />\n </label>\n </div>\n </>\n )}\n\n {testResult !== undefined && (\n <div style={{ fontSize: 13, color: testResult === '连接成功' ? 'var(--dsw-alias-state-success-primary)' : 'var(--dsw-alias-state-error-primary)' }}>{testResult}</div>\n )}\n\n <div style={{ display: 'flex', gap: 10, marginTop: 6, flexWrap: 'wrap' }}>\n <button type=\"button\" onClick={() => void save()} disabled={busy} style={primaryButtonStyle}>\n {selectedId === 'new' ? '创建节点' : '保存'}\n </button>\n {(form.type === 'remote-ssh' || form.type === 'remote-docker' || (selectedId !== 'new' && form.type === 'local-docker')) && (\n <button type=\"button\" onClick={() => void test()} disabled={busy || testing} style={secondaryButtonStyle}>\n {testing ? '测试中…' : '测试连接'}\n </button>\n )}\n {selectedId !== 'new' && (form.type === 'local-docker' || form.type === 'remote-docker') && (\n <>\n <button type=\"button\" onClick={() => void dockerAction('provision')} disabled={busy || dockerBusy} style={primaryButtonStyle}>\n {dockerBusy ? '操作中…' : '拉起容器'}\n </button>\n <button type=\"button\" onClick={() => void dockerAction('restart')} disabled={busy || dockerBusy} style={secondaryButtonStyle}>\n {dockerBusy ? '操作中…' : '重启容器'}\n </button>\n <button type=\"button\" onClick={() => void dockerAction('stop')} disabled={busy || dockerBusy} style={secondaryButtonStyle}>\n {dockerBusy ? '操作中…' : '停止容器'}\n </button>\n </>\n )}\n {selectedId !== 'new' && (\n <button type=\"button\" onClick={() => void remove()} disabled={busy} style={dangerOutlineButtonStyle}>\n 删除\n </button>\n )}\n {notice && <span style={{ fontSize: 13, alignSelf: 'center', color: notice.kind === 'ok' ? 'var(--dsw-alias-state-success-primary)' : 'var(--dsw-alias-state-error-primary)' }}>{notice.text}</span>}\n </div>\n </div>\n </div>\n </div>\n </>\n )\n}\n\nexport function apply(ctx: ClientContext): void {\n const globalStyle = document.createElement('style')\n globalStyle.textContent = `\n /* 仅在页面根阻止整页横向滚动。绝对定位浮层(模型菜单、上下文统计面板等)\n 依赖祖先 overflow:visible 才能展开到输入框之外,禁止给任何中间祖先加裁剪。 */\n html, body { overflow-x: hidden !important; max-width: 100vw !important }\n * { min-width: 0 !important; }\n table { display: block !important; overflow-x: auto !important; }\n img, video, canvas, svg { max-width: 100% !important; height: auto !important }\n pre, code { white-space: pre-wrap !important; word-break: break-all !important }\n input, select, textarea { max-width: 100% !important; }\n /* 上下文用量弹窗 .JObwrW_panel(ContextMeter):解除宽度塌缩并允许溢出显示。\n JObwrW_ 为上游 CSS 模块 hash,上游升级需同步。 */\n .JObwrW_panel { max-width: none !important; overflow: visible !important; }\n /* 子代理切换弹窗(dsh-client-ui-subagent):menu 是 flex column + max-height + overflow:auto,\n position:fixed 经 portal 渲染。子代理很多时 flex 压缩 node(flex-shrink:1 默认),\n 文字挤压且不触发滚动。给 node flex-shrink:0 让 menu 整体 overflow:auto 滚动。 */\n [class*=\"_menu\"] [class*=\"_node\"] { flex-shrink: 0 !important; }\n /* 模型选择弹窗(dsh-client-ui-model-selection):Ra_menu 上游 max-width 420px,\n 长模型名单行放不下被 ellipsis 截断。放宽到 720px 让模型名单行完整显示。\n [class*=\"Ra_menu\"] 精确匹配模型弹窗,避免误伤其他菜单。Ra_ 为 hash,上游升级需同步。 */\n [class*=\"Ra_menu\"] { max-width: 720px !important; width: auto !important; }\n /* 终端组件(dsh-web-frontend,CSS 模块前缀 1gdtu_)桌面端修复:上游 _command_ 默认\n overflow:hidden+text-overflow:ellipsis,LLM 调 bash 的长命令在桌面端被省略号\n 截断、看不到完整内容(输出区 _output_ 本就可横向滚动,唯命令区不行)。宽屏与\n mobile.tsx 的窄屏规则等效:行链 _prompt_/_promptLine_/_command_ 撑到 max-content、\n overflow 可见,长行溢出传入 _header_(本就 overflow-y:auto)的 scrollWidth,整个\n 命令区随 _header_ 横向滚动;copyButton 贴右缘保持可见。与窄屏规则共用 1gdtu_\n hash,上游升级需同步。桌面保留可见滚动条(不隐藏、不加 touch-action)。 */\n @media (min-width: 1024px) {\n [data-phase] [class*=\"_header_1gdtu_\"] {\n min-width: 0 !important;\n max-width: 100% !important;\n overflow-x: auto !important;\n }\n [data-phase] [class*=\"_prompt_1gdtu_\"],\n [data-phase] [class*=\"_promptLine_1gdtu_\"],\n [data-phase] [class*=\"_command_1gdtu_\"] {\n min-width: max-content !important;\n max-width: none !important;\n overflow: visible !important;\n }\n [data-phase] [class*=\"_command_1gdtu_\"] {\n display: inline-block;\n text-overflow: clip !important;\n white-space: pre !important;\n }\n [data-phase] [class*=\"_copyButton_1gdtu_\"] { position: sticky !important; right: 0; top: 0; }\n }\n `\n document.head.appendChild(globalStyle)\n\n installMobile(ctx)\n\n registerWorkspaceInstructionMenu(ctx)\n\n ctx.plugin({\n inject: ['slots'],\n apply: (sub: ClientContext): void => {\n sub.slots.inject('settings.section', () =>\n sub.slots.register({ name: 'settings.section', id: SECTION_ID, order: 110, label: () => '工作节点' }, NodeSection),\n )\n /* 上游 dsh-client-ui-directory-picker-browse 以默认 priority 0 注册同一 slot;\n priority 升序遮蔽(lowest renders),用 -10 抢占渲染,避免同优先级抛错。 */\n sub.slots.inject('conversation.hero.workspace.directoryFlow', () =>\n sub.slots.register({ name: 'conversation.hero.workspace.directoryFlow', priority: -10 }, DirectoryFlowOccupant),\n )\n sub.slots.inject('sidebar.workspaces.directoryFlow', () =>\n sub.slots.register({ name: 'sidebar.workspaces.directoryFlow', priority: -10 }, DirectoryFlowOccupant),\n )\n },\n })\n\n const ICON_SVG: Record<string, string> = {\n auth: `<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M8 7C9.3807 7 10.5 5.8807 10.5 4.5C10.5 3.1193 9.3807 2 8 2C6.6193 2 5.5 3.1193 5.5 4.5C5.5 5.8807 6.6193 7 8 7Z\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M3 14C3 11.2386 5.2386 9 8 9C10.7614 9 13 11.2386 13 14\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>`,\n 'dshb-nodes': `<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"3.5\" cy=\"4\" r=\"2\" stroke=\"currentColor\" stroke-width=\"1.5\"/><circle cx=\"12.5\" cy=\"4\" r=\"2\" stroke=\"currentColor\" stroke-width=\"1.5\"/><circle cx=\"8\" cy=\"12\" r=\"2\" stroke=\"currentColor\" stroke-width=\"1.5\"/><path d=\"M3.5 6V8C3.5 9.1 4.4 10 5.5 10H8\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/><path d=\"M12.5 6V8C12.5 9.1 11.6 10 10.5 10H8\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/></svg>`,\n }\n const ICON_LABELS: Record<string, string> = { '认证': 'auth', '工作节点': 'dshb-nodes' }\n\n const observer = new MutationObserver(() => {\n const cells = document.querySelectorAll('button[class*=\"navCell\"]')\n for (const cell of Array.from(cells)) {\n const label = cell.querySelector('span[class*=\"navLabel\"]')\n if (!label) continue\n const text = label.textContent ?? ''\n const iconKey = ICON_LABELS[text]\n if (!iconKey) continue\n const iconSlot = cell.querySelector('[class*=\"navIcon\"]')\n if (!iconSlot) continue\n if (iconSlot.getAttribute('data-dshb-icon') === iconKey) continue\n iconSlot.innerHTML = ICON_SVG[iconKey] ?? ''\n iconSlot.setAttribute('data-dshb-icon', iconKey)\n }\n })\n observer.observe(document.body, { childList: true, subtree: true })\n}\n","import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport { apply as applyAuth } from './auth.js'\nimport { apply as applyUi } from './ui.js'\n\nexport const inject = ['connection', 'workspaces', 'slots', 'layout', 'conversation']\n\nexport function apply(ctx: ClientContext): void {\n applyAuth(ctx)\n applyUi(ctx)\n}\n"],"mappings":"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"}