dsh-input-traffic 0.2.7 → 0.2.8

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":["useMemo","useState","useRef","useSyncExternalStore","useId","css","IconQueueOutline14","IconChevronDownOutline14","IconChevronUpOutline14","Tooltip","IconTrashOutline16","IconCheckOutline16","IconCloseOutline16","IconEditOutline16","IconRightUpOutline16","useSyncExternalStore","css"],"sources":["src/client/locales.ts","src/client/freeze-store.ts","src/client/steer-queue-dock.tsx","src/client/freeze-button.tsx","src/client/hide-enter-row.tsx","src/client/index.ts"],"sourcesContent":["/** `steer` namespace dictionaries. */\r\n\r\n/** Dictionary namespace owned by this plugin. */\r\nexport const NS = 'steer'\r\n\r\n/** Simplified Chinese dictionary (the key-set source of truth). */\r\nexport const zh = {\r\n 'queue.count': '{n} 条排队消息',\r\n 'queue.edit': '编辑排队消息',\r\n 'queue.edit.unsupported': '包含非文本内容,暂不支持编辑',\r\n 'queue.save': '保存排队消息',\r\n 'queue.cancelEdit': '取消编辑',\r\n 'queue.remove': '删除排队消息',\r\n 'queue.removeFailed': '删除失败:这条消息可能已经开始发送。',\r\n 'queue.editFailed': '编辑失败:这条消息可能已经开始发送。',\r\n 'queue.editFailed.pulledBack': '编辑失败,内容已退回主输入框,请确认后重新发送。',\r\n 'steer.inflight': '{n} 条正在插入',\r\n 'steer.now': '打断并输入',\r\n 'steer.now.aria': '红色:打断当前动作并立即输入',\r\n 'steer.now.unsupported': '包含非文本内容,暂不支持打断',\r\n 'steer.nowFailed': '打断失败,请重试。',\r\n 'steer.next': '插话发送',\r\n 'steer.next.aria': '黄色:当前动作结束后插入输入',\r\n 'steer.nextFailed': '插话发送失败,请重试。',\r\n 'steer.later': '排队到下一轮',\r\n 'steer.later.aria': '绿色:排队,上一轮输入的动作都结束后再处理',\r\n 'steer.revoke': '收回排队',\r\n 'steer.revoke.aria': '绿色:撤销插入,收回排队(下一轮处理)',\r\n 'steer.revoke.unsupported': '包含非文本内容,暂不支持收回',\r\n 'steer.revokeFailed': '收回排队失败,请重试。',\r\n 'steer.moveUp': '上移',\r\n 'steer.moveDown': '下移',\r\n 'steer.reorder.unsupported': '包含非文本内容,暂不支持排序',\r\n 'steer.reorderFailed': '调整顺序失败,请重试。',\r\n 'steer.reorderStale': '队列已变化,本次排序已取消,请重试。',\r\n 'steer.dragReorder': '拖动调整顺序',\r\n 'steer.pullBack': '打回输入框编辑',\r\n 'steer.pullBack.unsupported': '包含非文本内容,暂不支持打回编辑',\r\n 'steer.pullBack.composerBusy': '主输入框已有内容,请先发送或清空后再打回',\r\n 'steer.pullBackFailed': '打回输入框失败,请重试。',\r\n 'steer.badge.now': '打断中',\r\n 'steer.badge.next': '插话中',\r\n 'steer.badge.later': '排队',\r\n 'steer.unavailable.running': '仅运行中可规划',\r\n 'steer.clear': '取消并清空',\r\n 'steer.clear.confirm': '确认清空?',\r\n 'steer.clear.cancel': '取消清空',\r\n 'steer.clear.aria': '取消当前执行并清空全部排队消息',\r\n 'steer.clearFailed': '取消并清空失败,请重试。',\r\n 'steer.freeze': '冻结会话',\r\n 'steer.resume': '恢复会话',\r\n 'steer.frozen': '已冻结:当前轮次完成后暂停,排队消息将在恢复后继续',\r\n 'steer.frozenBadge': '已冻结',\r\n 'steer.freezeFailed': '冻结失败,请重试。',\r\n 'steer.resumeFailed': '恢复失败,请重试。',\r\n} satisfies Record<string, string>\r\n\r\n/** English dictionary (keys mirror zh). */\r\nexport const en: Record<keyof typeof zh, string> = {\r\n 'queue.count': '{n} queued messages',\r\n 'queue.edit': 'Edit queued message',\r\n 'queue.edit.unsupported': 'Contains non-text content; editing is unsupported',\r\n 'queue.save': 'Save queued message',\r\n 'queue.cancelEdit': 'Cancel edit',\r\n 'queue.remove': 'Remove queued message',\r\n 'queue.removeFailed': 'Remove failed: the message may have started sending.',\r\n 'queue.editFailed': 'Edit failed: the message may have started sending.',\r\n 'queue.editFailed.pulledBack': 'Edit failed; the content was moved back to the composer, please review and resend.',\r\n 'steer.inflight': '{n} inserting',\r\n 'steer.now': 'Interrupt and send',\r\n 'steer.now.aria': 'Red: interrupt the running action and send now',\r\n 'steer.now.unsupported': 'Contains non-text content; interrupting is unsupported',\r\n 'steer.nowFailed': 'Interrupt failed, please retry.',\r\n 'steer.next': 'Send after action',\r\n 'steer.next.aria': 'Yellow: insert after the current action finishes',\r\n 'steer.nextFailed': 'Steering failed, please retry.',\r\n 'steer.later': 'Queue for next turn',\r\n 'steer.later.aria': 'Green: queue; processed after all previously steered actions finish',\r\n 'steer.revoke': 'Pull back to queue',\r\n 'steer.revoke.aria': 'Green: revoke the insertion and queue for the next turn',\r\n 'steer.revoke.unsupported': 'Contains non-text content; revoking is unsupported',\r\n 'steer.revokeFailed': 'Revoke failed, please retry.',\r\n 'steer.moveUp': 'Move up',\r\n 'steer.moveDown': 'Move down',\r\n 'steer.reorder.unsupported': 'Contains non-text content; reordering is unsupported',\r\n 'steer.reorderFailed': 'Reorder failed, please retry.',\r\n 'steer.reorderStale': 'The queue changed; this reorder was cancelled, please retry.',\r\n 'steer.dragReorder': 'Drag to reorder',\r\n 'steer.pullBack': 'Edit in composer',\r\n 'steer.pullBack.unsupported': 'Contains non-text content; pulling back is unsupported',\r\n 'steer.pullBack.composerBusy': 'The composer already has content; send or clear it first',\r\n 'steer.pullBackFailed': 'Pull back failed, please retry.',\r\n 'steer.badge.now': 'interrupting',\r\n 'steer.badge.next': 'steering',\r\n 'steer.badge.later': 'queued',\r\n 'steer.unavailable.running': 'Planning requires a running session',\r\n 'steer.clear': 'Cancel and clear',\r\n 'steer.clear.confirm': 'Confirm clear?',\r\n 'steer.clear.cancel': 'Cancel clearing',\r\n 'steer.clear.aria': 'Cancel the current run and clear all queued messages',\r\n 'steer.clearFailed': 'Cancel and clear failed, please retry.',\r\n 'steer.freeze': 'Freeze session',\r\n 'steer.resume': 'Resume session',\r\n 'steer.frozen': 'Frozen: the current turn finishes, then the queue pauses until resumed',\r\n 'steer.frozenBadge': 'frozen',\r\n 'steer.freezeFailed': 'Freeze failed, please retry.',\r\n 'steer.resumeFailed': 'Resume failed, please retry.',\r\n}\r\n\r\n/** Dictionary key union. */\r\nexport type SteerKey = keyof typeof zh\r\n","/**\r\n * Session-freeze store shared by the composer freeze button (the control)\r\n * and the steering dock (the banner/disabled states).\r\n *\r\n * The queue is fully decoupled from freezing: freezing only stops the agent\n * from consuming the queue (the detached entries are preserved here so the\r\n * driver finds no pending work and stops). While frozen the entries stay\r\n * fully editable — text, order and the planned insertion tier (now/next/\r\n * later) can all change; resume re-submits the queue honoring those tiers.\r\n */\r\n\r\n/** Insertion tier planned for one detached queued message. */\r\nexport type FrozenTier = 'queue' | 'safe_point' | 'force'\r\n\r\n/** One detached queued message with its planned insertion tier. */\r\nexport interface FrozenEntry {\r\n text: string\r\n tier: FrozenTier\r\n}\r\n\r\nexport interface FreezeState {\r\n frozen: boolean\r\n /** Detached queued messages in FIFO order, each with a planned tier. */\r\n pending: readonly FrozenEntry[]\r\n}\r\n\r\nconst listeners = new Set<() => void>()\r\nlet state: FreezeState = { frozen: false, pending: [] }\r\n\r\n/** Minimal snapshot store (no runtime dependency, stable identity per mount). */\r\nexport const freezeStore = {\r\n getSnapshot(): FreezeState {\r\n return state\r\n },\r\n subscribe(listener: () => void): () => void {\r\n listeners.add(listener)\r\n return () => { listeners.delete(listener) }\r\n },\r\n set(next: FreezeState): void {\r\n state = next\r\n for (const listener of listeners) listener()\r\n },\r\n}\r\n\r\n/** Reset for tests. */\r\nexport function resetFreezeStore(): void {\r\n state = { frozen: false, pending: [] }\r\n for (const listener of listeners) listener()\r\n}\r\n\r\n/** Append one queued message while frozen (new input lands in the detached queue). */\r\nexport function pushPending(text: string, tier: FrozenTier = 'queue'): void {\r\n state = { ...state, pending: [...state.pending, { text, tier }] }\r\n emit()\r\n}\r\n\r\n/** Edit one detached queued message's text in place. */\r\nexport function updatePendingAt(index: number, text: string): void {\r\n const pending = [...state.pending]\r\n if (index < 0 || index >= pending.length) return\r\n const entry = pending[index]\r\n if (entry === undefined) return\r\n pending[index] = { ...entry, text }\r\n state = { ...state, pending }\r\n emit()\r\n}\r\n\r\n/** Change one detached queued message's planned insertion tier. */\r\nexport function setTierAt(index: number, tier: FrozenTier): void {\r\n const pending = [...state.pending]\r\n if (index < 0 || index >= pending.length) return\r\n const entry = pending[index]\r\n if (entry === undefined) return\r\n pending[index] = { ...entry, tier }\r\n state = { ...state, pending }\r\n emit()\r\n}\r\n\r\n/** Remove one detached queued message. */\r\nexport function removePendingAt(index: number): void {\r\n if (index < 0 || index >= state.pending.length) return\r\n state = { ...state, pending: state.pending.filter((_, i) => i !== index) }\r\n emit()\r\n}\r\n\r\n/** Move one detached queued message to a new position (reorder while frozen). */\r\nexport function movePending(from: number, to: number): void {\r\n if (from === to) return\r\n const pending = [...state.pending]\r\n const [moved] = pending.splice(from, 1)\r\n if (moved === undefined) return\r\n pending.splice(to, 0, moved)\r\n state = { ...state, pending }\r\n emit()\r\n}\r\n\r\nfunction emit(): void {\r\n for (const listener of listeners) listener()\r\n}\r\n","/**\r\n * Three-tier steering queue dock: the shadowing replacement for the official\r\n * `conversation.input.dock` entry (same cell id `queue`, priority -1, so the\r\n * lower priority wins and the official QueueDock never renders while this\r\n * plugin is mounted).\r\n *\r\n * Every queued row carries three planning buttons:\r\n * - green (later, the default state): the row already queues for the next\r\n * turn —plain Enter keeps feeding rows here; pressing green on a row that\r\n * was already steered (yellow) revokes the insertion and pulls it back to\r\n * later (the yellow flow is reversible);\r\n * - yellow (next): strict-steer the row into the running turn, consumed at\r\n * the next step boundary (after the current action finishes);\r\n * - red (now): cancel the running turn, then remove the row and re-send its\r\n * text as a fresh message —the re-send arms the harness wake latch (the\r\n * converged driver restarts) and the interrupted input is processed as the\r\n * next turn's input. A plain steer after cancel would re-insert a message\r\n * that is already pending in next-turn and the inbox rejects it.\r\n *\r\n * The toolbar also exposes a queue-level \"cancel and clear\" that stops the\r\n * current run and removes every queued row, plus a session-level\r\n * freeze/resume toggle for the peak-hour scenario: freeze stops the current\r\n * run while preserving the queue (keepInbox), resume re-arms the driver by\r\n * re-sending the first queued row so the preserved work continues.\r\n */\r\nimport { useEffect, useId, useMemo, useRef, useState, useSyncExternalStore } from 'react'\r\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\r\n// Type-only: the conversation slot/contract declarations (module augmentation\r\n// for the SlotMap and the session standard kit). No value import crosses the\r\n// plugin boundary.\r\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\r\nimport {\r\n IconCheckOutline16, IconChevronDownOutline14, IconChevronUpOutline14, IconCloseOutline16,\r\n IconEditOutline16, IconQueueOutline14, IconRightUpOutline16, IconTrashOutline16, Tooltip,\r\n} from '@deepseek-ai/dsh-client-ui-primitives'\r\nimport { freezeStore, setTierAt, updatePendingAt, removePendingAt, movePending } from './freeze-store.ts'\r\nimport css from './steer-queue-dock.module.css'\r\n\r\n/** One mutation accepted by the conversation queue verb. */\r\nexport type SteerQueueAction =\r\n | { kind: 'edit'; content: readonly { type: 'text'; text: string }[] }\r\n | { kind: 'remove' }\r\n | { kind: 'steer' }\r\n\r\n/** Busy marker for a whole-queue rebuild (reorder); locks every row action. */\r\nconst REORDER_MARK = '__reorder__'\r\n\r\n/** localStorage key for the manual collapse state (dsh-queue-plus parity). */\r\nconst COLLAPSE_KEY = 'dsh-input-traffic:collapsed'\r\n\r\n/** Queue operations injected by the session-scoped registration. */\r\nexport interface SteerQueueDockInjected {\r\n updateQueue: (itemId: string, action: SteerQueueAction) => Promise<void>\r\n /** Cancel the current turn while preserving the pending queue. */\r\n cancel: () => Promise<void>\r\n /** Re-send one plain-text message as a queued follow-up (the revoke path). */\r\n send: (text: string) => Promise<void>\r\n /** Re-deliver one plain-text message into the next step (the resume steer path). */\r\n sendSteer: (text: string) => Promise<void>\r\n /** Back-fill the composer draft (the pull-back-to-composer edit path). */\r\n setDraft: (text: string) => void\r\n notify: (level: 'info' | 'error', text: string) => void\r\n}\r\n\r\n/** Full props of a dock entry: InputZone owner share + session standard kit + global seat + the locale seat. */\r\nexport type SteerQueueDockProps = PropsRuntime<'conversation.input.dock'> & SteerQueueDockInjected & PropsLocale<'steer'>\r\n\r\n/** The planning tier of one queued row. */\r\nexport type SteerTier = 'now' | 'next' | 'later'\r\n\r\n/**\r\n * Resolve the action sequence for one planning button press. Pure so the\r\n * button wiring and its tests share one truth.\r\n * @param tier - the pressed planning tier.\r\n * @returns the queue mutation (red re-uses a steer-shaped action for the\r\n * yellow branch; the red branch performs cancel + remove + resend instead).\r\n */\r\nexport function planActionFor(tier: SteerTier): { action: SteerQueueAction; interruptFirst: boolean } {\r\n if (tier === 'later') return { action: { kind: 'steer' }, interruptFirst: false }\r\n // Yellow steers only; red cancels the running turn first, then steers.\r\n return { action: { kind: 'steer' }, interruptFirst: tier === 'now' }\r\n}\r\n\r\n/**\r\n * Project the tier badge of one inbox row from its placement. Pure so the\r\n * row rendering and its tests share one truth.\r\n * @param placement - the inbox projection placement.\r\n * @returns the tier badge, or null for non-visible context rows.\r\n */\r\nexport function badgeFor(placement: 'queued' | 'steering' | 'context'): SteerTier | null {\r\n if (placement === 'steering') return 'next'\r\n if (placement === 'queued') return 'later'\r\n return null\r\n}\r\n\r\n/**\r\n * Auto-grow one edit textarea to its content. The CSS max-height caps the\r\n * growth; beyond it the textarea scrolls internally. Height is reset first so\r\n * shrink (deleting lines) also tracks the content.\r\n * @param el - the textarea to resize in place.\r\n */\r\nexport function resizeEditor(el: HTMLTextAreaElement): void {\r\n el.style.height = 'auto'\r\n el.style.height = `${el.scrollHeight}px`\r\n}\r\n\r\n/**\r\n * Queue strip with three-tier planning: one item renders directly; multiple\r\n * items default to a collapsible count header; an empty queue renders nothing.\r\n */\r\nexport function SteerQueueDock({ useSession, input, updateQueue, cancel, send, setDraft, notify, t }: SteerQueueDockProps) {\r\n const inbox = useSession(s => s.queue)\r\n const queue = useMemo(() => inbox.filter(row => row.placement === 'queued'), [inbox])\r\n const steering = useMemo(() => inbox.filter(row => row.placement === 'steering'), [inbox])\r\n const running = useSession(s => s.running)\r\n const queueMutable = useSession(s => s.subagent === null)\r\n const [editing, setEditing] = useState<{ id: string; text: string } | null>(null)\r\n const [busy, setBusy] = useState<string | null>(null)\r\n const [clearing, setClearing] = useState(false)\r\n // Two-step clear confirmation: the first click arms the prompt, the second\r\n // executes; arming auto-reverts after a few seconds (no native confirm).\r\n const [confirmClear, setConfirmClear] = useState(false)\r\n const confirmTimer = useRef<ReturnType<typeof setTimeout> | null>(null)\r\n // Drag-and-drop reorder source index and the current drop-target row.\r\n const dragIndex = useRef<number | null>(null)\r\n const [dragOver, setDragOver] = useState<number | null>(null)\r\n // Collapse state persists across mounts (dsh-queue-plus parity).\r\n const [collapsed, setCollapsed] = useState(() => {\r\n try {\r\n const v = localStorage.getItem(COLLAPSE_KEY)\r\n return v === null ? true : v === '1'\r\n } catch {\r\n return true\r\n }\r\n })\r\n // Session-level freeze lives in the composer-right control; the dock reads\r\n // the shared store for the banner and inert states. While frozen the\r\n // detached queue is rendered here (read-only) so the waiting area stays\r\n // visible — freezing only pauses the running behavior, it must not hide\r\n // the queued messages.\r\n const { frozen, pending: frozenPending } = useSyncExternalStore(freezeStore.subscribe, freezeStore.getSnapshot)\r\n const listId = useId()\r\n // The edit textarea; grown to its content on entry and on every input.\r\n const editorRef = useRef<HTMLTextAreaElement>(null)\r\n\r\n useEffect(() => {\r\n if (queue.length === 0 && !collapsed) setCollapsed(true)\r\n // Frozen-row edits use a `frozen:` id that never exists in the dsh queue;\r\n // skip the stale-check for them so the detached queue stays editable.\r\n if (editing !== null && !editing.id.startsWith('frozen:') && (!queueMutable || !queue.some(row => row.id === editing.id))) setEditing(null)\r\n }, [collapsed, editing, queue, queueMutable])\r\n\r\n // Persist the manual collapse state; clear the confirm timer on unmount.\r\n useEffect(() => {\r\n try {\r\n localStorage.setItem(COLLAPSE_KEY, collapsed ? '1' : '0')\r\n } catch {\r\n /* storage unavailable: in-memory only */\r\n }\r\n }, [collapsed])\r\n useEffect(() => () => {\r\n if (confirmTimer.current !== null) clearTimeout(confirmTimer.current)\r\n }, [])\r\n\r\n // Grow the editor to its full content when a row enters edit mode.\r\n const editingId = editing?.id\r\n useEffect(() => {\r\n if (editingId === undefined) return\r\n const el = editorRef.current\r\n if (el !== null) resizeEditor(el)\r\n }, [editingId])\r\n\r\n // The dock stays mounted while the agent runs (the freeze entry must be\r\n // reachable before any message queues), while any row is pending, and while\r\n // the session is frozen (the detached queue stays visible).\r\n if (queue.length === 0 && steering.length === 0 && !running && !frozen) return null\r\n\r\n const interactionActive = queueMutable && (editing !== null || busy !== null || clearing)\r\n const expanded = !collapsed || interactionActive\r\n const listVisible = queue.length === 1 || expanded\r\n const planDisabled = !queueMutable || !running || frozen\r\n const nothingPending = queue.length === 0 && steering.length === 0\r\n // Reordering rebuilds the queue by re-sending texts; non-text rows cannot\r\n // be re-sent, so sorting is disabled while any such row is queued.\r\n const reorderUnsupported = queue.some(row => row.text === null)\r\n // Pull-back-to-composer is only offered when the composer draft is empty:\r\n // the pulled message back-fills the draft, so an occupied composer would be\r\n // overwritten. Steered (yellow/red) rows never offer it — once inserted,\r\n // they are not deeply re-edited.\r\n const composerEmpty = input.draft.trim() === ''\r\n\r\n const applyAction = async (\r\n itemId: string,\r\n action: SteerQueueAction,\r\n failure: string,\r\n ): Promise<boolean> => {\r\n setBusy(itemId)\r\n try {\r\n await updateQueue(itemId, action)\r\n return true\r\n } catch {\r\n notify('error', failure)\r\n return false\r\n } finally {\r\n setBusy(current => current === itemId ? null : current)\r\n }\r\n }\r\n\r\n const saveEdit = async (): Promise<void> => {\r\n if (editing === null || editing.text.trim() === '') return\r\n const itemId = editing.id\r\n const text = editing.text\r\n setBusy(itemId)\r\n try {\r\n await updateQueue(itemId, { kind: 'edit', content: [{ type: 'text', text }] })\r\n setEditing(null)\r\n } catch {\r\n // The edit failed (the agent may have claimed the row mid-edit): fall\r\n // back to the composer so the edited content is never lost. Only when\r\n // the composer is free — an occupied draft must not be overwritten.\r\n if (input.draft.trim() === '') {\r\n setDraft(text)\r\n setEditing(null)\r\n notify('error', t('queue.editFailed.pulledBack'))\r\n } else {\r\n notify('error', t('queue.editFailed'))\r\n }\r\n } finally {\r\n setBusy(current => current === itemId ? null : current)\r\n }\r\n }\r\n\r\n const steerRow = async (row: { id: string; text: string | null }, tier: Exclude<SteerTier, 'later'>): Promise<void> => {\r\n setBusy(row.id)\r\n try {\r\n if (tier === 'now') {\r\n // Interrupt, then re-submit: cancel stops the current run (keepInbox),\r\n // the row is removed so its identity cannot collide, and re-sending\r\n // the text arms the harness wake latch (the converged driver restarts\r\n // and processes it as the next turn's input). A plain steer after\r\n // cancel would re-insert a message already pending in next-turn and\r\n // the inbox rejects the duplicate.\r\n await cancel()\r\n await updateQueue(row.id, { kind: 'remove' })\r\n if (row.text !== null) await send(row.text)\r\n } else {\r\n await updateQueue(row.id, { kind: 'steer' })\r\n }\r\n } catch {\r\n notify('error', tier === 'now' ? t('steer.nowFailed') : t('steer.nextFailed'))\r\n } finally {\r\n setBusy(current => current === row.id ? null : current)\r\n }\r\n }\r\n\r\n /**\r\n * Revoke a steered (yellow) or interrupting (red) row back to later: remove\r\n * the admitted row and re-send its text as a queued follow-up, so it lands\r\n * in next-turn again (the yellow flow is reversible).\r\n */\r\n const revokeToLater = async (row: { id: string; text: string | null }): Promise<void> => {\r\n if (row.text === null) return\r\n setBusy(row.id)\r\n try {\r\n await updateQueue(row.id, { kind: 'remove' })\r\n await send(row.text)\r\n } catch {\r\n notify('error', t('steer.revokeFailed'))\r\n } finally {\r\n setBusy(current => current === row.id ? null : current)\r\n }\r\n }\r\n\r\n /**\r\n * Rebuild the queue in a new order: remove every queued row, then re-send\r\n * the texts sequentially so the agent's next-turn list matches the new\r\n * order. Concurrency protection (dsh-queue-plus parity): if a remove fails\r\n * with queue-item-not-found, the agent already claimed that row — the\r\n * rebuild stops immediately and nothing is re-sent, so the changed queue\r\n * is never scrambled.\r\n */\r\n const rebuildQueue = async (rows: readonly { id: string; text: string | null }[], next: readonly { id: string; text: string | null }[]): Promise<void> => {\r\n setBusy(REORDER_MARK)\r\n try {\r\n for (const row of rows) {\r\n try {\r\n await updateQueue(row.id, { kind: 'remove' })\r\n } catch (error) {\r\n if (error instanceof Error && error.message.includes('queue-item-not-found')) {\r\n notify('error', t('steer.reorderStale'))\r\n return\r\n }\r\n throw error\r\n }\r\n }\r\n for (const row of next) {\r\n if (row.text !== null) await send(row.text)\r\n }\r\n } catch {\r\n notify('error', t('steer.reorderFailed'))\r\n } finally {\r\n setBusy(null)\r\n }\r\n }\r\n\r\n /**\r\n * Move one queued row up/down in the FIFO order (arrow buttons).\r\n */\r\n const reorder = async (rowId: string, delta: -1 | 1): Promise<void> => {\r\n const rows = queue\r\n const index = rows.findIndex(row => row.id === rowId)\r\n const target = index + delta\r\n if (index < 0 || target < 0 || target >= rows.length) return\r\n const next = [...rows]\r\n const swapped = next[index] as typeof next[number]\r\n next[index] = next[target] as typeof next[number]\r\n next[target] = swapped\r\n if (next.some(row => row.text === null)) {\r\n notify('error', t('steer.reorder.unsupported'))\r\n return\r\n }\r\n await rebuildQueue(rows, next)\r\n }\r\n\r\n /**\r\n * Move one row to an absolute position (drag-and-drop drop handler).\r\n */\r\n const reorderTo = async (fromIndex: number, toIndex: number): Promise<void> => {\r\n if (fromIndex === toIndex) return\r\n const rows = queue\r\n if (rows[fromIndex] === undefined || rows[toIndex] === undefined) return\r\n const next = [...rows]\r\n const [moved] = next.splice(fromIndex, 1)\r\n if (moved === undefined) return\r\n next.splice(toIndex, 0, moved)\r\n if (next.some(row => row.text === null)) {\r\n notify('error', t('steer.reorder.unsupported'))\r\n return\r\n }\r\n await rebuildQueue(rows, next)\r\n }\r\n\r\n /** Arm or execute the two-step clear confirmation. */\r\n const armClear = (): void => {\r\n if (confirmClear) {\r\n if (confirmTimer.current !== null) clearTimeout(confirmTimer.current)\r\n setConfirmClear(false)\r\n void clearAll()\r\n return\r\n }\r\n setConfirmClear(true)\r\n if (confirmTimer.current !== null) clearTimeout(confirmTimer.current)\r\n confirmTimer.current = setTimeout(() => setConfirmClear(false), 3000)\r\n }\r\n\r\n /** Abort the armed clear confirmation (the explicit cancel button). */\r\n const cancelClear = (): void => {\r\n if (confirmTimer.current !== null) clearTimeout(confirmTimer.current)\r\n setConfirmClear(false)\r\n }\r\n\r\n /** Save an in-place edit of one detached (frozen) queued message. */\r\n const saveFrozenEdit = async (index: number): Promise<void> => {\r\n if (editing === null) return\r\n const text = editing.text.trim()\r\n if (text === '') {\r\n setEditing(null)\r\n return\r\n }\r\n updatePendingAt(index, text)\r\n setEditing(null)\r\n }\r\n\r\n /**\r\n * Pull one queued row back into the composer draft for editing: the text\r\n * back-fills the input box and the row leaves the queue; the user edits and\r\n * resubmits it as a fresh message.\r\n */\r\n const pullBackToComposer = async (row: { id: string; text: string | null }): Promise<void> => {\r\n if (row.text === null) return\r\n setDraft(row.text)\r\n setBusy(row.id)\r\n try {\r\n await updateQueue(row.id, { kind: 'remove' })\r\n } catch {\r\n notify('error', t('steer.pullBackFailed'))\r\n } finally {\r\n setBusy(current => current === row.id ? null : current)\r\n }\r\n }\r\n\r\n const clearAll = async (): Promise<void> => {\r\n setClearing(true)\r\n // Cancel the current run and clear every pending row (queued and\r\n // steering alike). Removal races the agent claiming rows;\r\n // item-not-found is a normal convergence and must not surface.\r\n const pending = [...queue, ...steering]\r\n try {\r\n await cancel()\r\n await Promise.all(pending.map(row =>\r\n updateQueue(row.id, { kind: 'remove' }).catch(() => undefined),\r\n ))\r\n } catch {\r\n notify('error', t('steer.clearFailed'))\r\n } finally {\r\n setClearing(false)\r\n }\r\n }\r\n\r\n return (\r\n <div className={css.dock} data-steer-dock=\"\">\r\n <div className={css.panel}>\r\n <div className={css.toolbar}>\r\n <button\r\n type=\"button\"\r\n className={css.header}\r\n aria-controls={listId}\r\n aria-expanded={expanded}\r\n disabled={queue.length <= 1 || interactionActive}\r\n onClick={() => { setCollapsed(value => !value) }}\r\n >\r\n <span className={css.lead} aria-hidden><IconQueueOutline14 /></span>\r\n {queue.length > 0 && (\r\n <span className={css.count}>{t('queue.count', { n: queue.length })}</span>\r\n )}\r\n {queue.length > 1 && (\r\n <span className={css.chevron} aria-hidden>\r\n {expanded ? <IconChevronDownOutline14 /> : <IconChevronUpOutline14 />}\r\n </span>\r\n )}\r\n </button>\r\n <div className={css.toolbarActions}>\r\n {confirmClear && (\r\n <button\r\n type=\"button\"\r\n className={css.clearCancel}\r\n aria-label={t('steer.clear.cancel')}\r\n disabled={clearing || busy !== null || nothingPending}\r\n onClick={cancelClear}\r\n >\r\n <span className={css.clearLabel}>{t('steer.clear.cancel')}</span>\r\n </button>\r\n )}\r\n <Tooltip label={confirmClear ? t('steer.clear.confirm') : t('steer.clear')} side=\"top\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={`${css.clear} ${confirmClear ? css.clearConfirm : ''}`}\r\n aria-label={confirmClear ? t('steer.clear.confirm') : t('steer.clear')}\r\n disabled={clearing || busy !== null || nothingPending}\r\n onClick={armClear}\r\n >\r\n <IconTrashOutline16 size={14} />\r\n <span className={css.clearLabel}>{confirmClear ? t('steer.clear.confirm') : t('steer.clear')}</span>\r\n </button>\r\n </Tooltip>\r\n </div>\r\n </div>\r\n {frozen && (\r\n <div className={css.frozenBanner} role=\"status\">\r\n {t('steer.frozen')}\r\n </div>\r\n )}\r\n {/* While frozen the queue is detached into the shared store: render it\r\n here so the waiting area never disappears. The detached rows stay\r\n fully editable (edit / remove / reorder) — freezing only pauses\r\n the running behavior, it must not lock the queue. */}\r\n {frozen && frozenPending.length > 0 && (\r\n <ul className={css.frozenList} data-testid=\"frozen-list\">\r\n {frozenPending.map((entry, i) => {\r\n const editingFrozen = editing?.id === `frozen:${i}`\r\n const text = entry.text\r\n return (\r\n <li\r\n key={i}\r\n className={`${css.frozenRow} ${dragOver === i && frozen ? css.rowDragOver : ''}`}\r\n data-tier={entry.tier === 'force' ? 'now' : entry.tier === 'safe_point' ? 'next' : 'later'}\r\n data-editing={editingFrozen ? '' : undefined}\r\n draggable={!editingFrozen}\r\n title={!editingFrozen ? t('steer.dragReorder') : undefined}\r\n onDragStart={(event) => {\r\n if (editingFrozen) return\r\n dragIndex.current = i\r\n event.dataTransfer.effectAllowed = 'move'\r\n // Some engines only start HTML5 drag once data is set.\r\n event.dataTransfer.setData('text/plain', String(i))\r\n }}\r\n onDragOver={(event) => {\r\n if (dragIndex.current === null) return\r\n event.preventDefault()\r\n setDragOver(i)\r\n }}\r\n onDrop={(event) => {\r\n event.preventDefault()\r\n const from = dragIndex.current\r\n dragIndex.current = null\r\n setDragOver(null)\r\n if (from !== null) movePending(from, i)\r\n }}\r\n onDragEnd={() => {\r\n dragIndex.current = null\r\n setDragOver(null)\r\n }}\r\n >\r\n <span className={css.lead} aria-hidden><IconQueueOutline14 /></span>\r\n <SteerBadge tier={entry.tier === 'force' ? 'now' : entry.tier === 'safe_point' ? 'next' : 'later'} t={t} />\r\n {editingFrozen\r\n ? (\r\n <textarea\r\n ref={editorRef}\r\n autoFocus\r\n className={css.editor}\r\n aria-label={t('queue.edit')}\r\n rows={1}\r\n value={editing?.text ?? text}\r\n onChange={(event) => { setEditing({ id: `frozen:${i}`, text: event.currentTarget.value }) }}\r\n onInput={(event) => { resizeEditor(event.currentTarget) }}\r\n onKeyDown={(event) => {\r\n if (event.key === 'Escape') {\r\n setEditing(null)\r\n return\r\n }\r\n if (event.key === 'Enter' && !event.shiftKey && !event.nativeEvent.isComposing) {\r\n event.preventDefault()\r\n void saveFrozenEdit(i)\r\n }\r\n }}\r\n />\r\n )\r\n : <span className={css.preview}>{text}</span>}\r\n <div className={css.actions}>\r\n {editingFrozen ? (\r\n <>\r\n <Tooltip label={t('queue.save')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.save')}\r\n disabled={editing === null || editing.text.trim() === ''}\r\n onClick={() => { void saveFrozenEdit(i) }}\r\n >\r\n <IconCheckOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('queue.cancelEdit')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.cancelEdit')}\r\n onClick={() => { setEditing(null) }}\r\n >\r\n <IconCloseOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n </>\r\n ) : (\r\n <>\r\n <Tooltip label={t('steer.moveUp')} side=\"bottom\" delayMs={500} disabled={i === 0}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('steer.moveUp')}\r\n disabled={i === 0}\r\n onClick={() => movePending(i, i - 1)}\r\n >\r\n <IconChevronUpOutline14 />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('steer.moveDown')} side=\"bottom\" delayMs={500} disabled={i === frozenPending.length - 1}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('steer.moveDown')}\r\n disabled={i === frozenPending.length - 1}\r\n onClick={() => movePending(i, i + 1)}\r\n >\r\n <IconChevronDownOutline14 />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('queue.edit')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.edit')}\r\n onClick={() => { setEditing({ id: `frozen:${i}`, text }) }}\r\n >\r\n <IconEditOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('queue.remove')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.remove')}\r\n onClick={() => removePendingAt(i)}\r\n >\r\n <IconTrashOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n {/* Planned insertion tier: freezing pauses consumption,\r\n it must not lock the tier planning of each row. */}\r\n <span className={css.plan} role=\"group\" aria-label={t('steer.later.aria')}>\r\n <Tooltip label={t('steer.now')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={`${css.tier} ${css.tierNow}`}\r\n aria-label={t('steer.now')}\r\n aria-pressed={entry.tier === 'force' || undefined}\r\n onClick={() => setTierAt(i, 'force')}\r\n >\r\n <span className={css.dot} aria-hidden />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('steer.next')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={`${css.tier} ${css.tierNext}`}\r\n aria-label={t('steer.next')}\r\n aria-pressed={entry.tier === 'safe_point' || undefined}\r\n onClick={() => setTierAt(i, 'safe_point')}\r\n >\r\n <span className={css.dot} aria-hidden />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('steer.later')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={`${css.tier} ${css.tierLater}`}\r\n aria-label={t('steer.later')}\r\n aria-pressed={entry.tier === 'queue' || undefined}\r\n onClick={() => setTierAt(i, 'queue')}\r\n >\r\n <span className={css.dot} aria-hidden />\r\n </button>\r\n </Tooltip>\r\n </span>\r\n </>\r\n )}\r\n </div>\r\n <span className={css.frozenMark}>{t('steer.frozenBadge')}</span>\r\n </li>\r\n )\r\n })}\r\n </ul>\r\n )}\r\n <ul id={listId} className={css.list} hidden={!listVisible}>\r\n {listVisible && queue.map((row, index) => (\r\n <li\r\n key={row.id}\r\n className={`${css.row} ${dragOver === index ? css.rowDragOver : ''}`}\r\n data-tier={badgeFor('queued') ?? undefined}\r\n data-editing={editing?.id === row.id ? '' : undefined}\r\n draggable={queueMutable && !reorderUnsupported && busy === null && !frozen}\r\n title={queueMutable && !reorderUnsupported && busy === null && !frozen ? t('steer.dragReorder') : undefined}\r\n onDragStart={(event) => {\r\n dragIndex.current = index\r\n event.dataTransfer.effectAllowed = 'move'\r\n // Some engines only start HTML5 drag once data is set.\r\n event.dataTransfer.setData('text/plain', String(index))\r\n }}\r\n onDragOver={(event) => {\r\n if (dragIndex.current === null) return\r\n event.preventDefault()\r\n setDragOver(index)\r\n }}\r\n onDrop={(event) => {\r\n event.preventDefault()\r\n const from = dragIndex.current\r\n dragIndex.current = null\r\n setDragOver(null)\r\n if (from !== null) void reorderTo(from, index)\r\n }}\r\n onDragEnd={() => {\r\n dragIndex.current = null\r\n setDragOver(null)\r\n }}\r\n >\r\n {queue.length === 1 && <span className={css.lead} aria-hidden><IconQueueOutline14 /></span>}\r\n <SteerBadge tier={badgeFor('queued')} t={t} />\r\n {editing?.id === row.id\r\n ? (\r\n <textarea\r\n ref={editorRef}\r\n autoFocus\r\n className={css.editor}\r\n aria-label={t('queue.edit')}\r\n rows={1}\r\n value={editing.text}\r\n onChange={(event) => { setEditing({ id: row.id, text: event.currentTarget.value }) }}\r\n onInput={(event) => { resizeEditor(event.currentTarget) }}\r\n onKeyDown={(event) => {\r\n if (event.key === 'Escape') {\r\n setEditing(null)\r\n return\r\n }\r\n // Plain Enter saves; Shift+Enter keeps editing (newline).\r\n if (event.key === 'Enter' && !event.shiftKey && !event.nativeEvent.isComposing) {\r\n event.preventDefault()\r\n void saveEdit()\r\n }\r\n }}\r\n />\r\n )\r\n : <span className={css.preview}>{row.preview}</span>}\r\n {queueMutable && <div className={css.actions}>\r\n {editing?.id === row.id\r\n ? (\r\n <>\r\n <Tooltip label={t('queue.save')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.save')}\r\n disabled={busy !== null || editing.text.trim() === ''}\r\n onClick={() => { void saveEdit() }}\r\n >\r\n <IconCheckOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('queue.cancelEdit')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.cancelEdit')}\r\n disabled={busy !== null}\r\n onClick={() => { setEditing(null) }}\r\n >\r\n <IconCloseOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n </>\r\n )\r\n : (\r\n <>\r\n <Tooltip label={t('steer.moveUp')} side=\"bottom\" delayMs={500} disabled={frozen || reorderUnsupported}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('steer.moveUp')}\r\n title={reorderUnsupported ? t('steer.reorder.unsupported') : undefined}\r\n disabled={busy !== null || frozen || reorderUnsupported}\r\n onClick={() => { void reorder(row.id, -1) }}\r\n >\r\n <IconChevronUpOutline14 />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('steer.moveDown')} side=\"bottom\" delayMs={500} disabled={frozen || reorderUnsupported}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('steer.moveDown')}\r\n title={reorderUnsupported ? t('steer.reorder.unsupported') : undefined}\r\n disabled={busy !== null || frozen || reorderUnsupported}\r\n onClick={() => { void reorder(row.id, 1) }}\r\n >\r\n <IconChevronDownOutline14 />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('steer.pullBack')} side=\"bottom\" delayMs={500} disabled={row.text === null || !composerEmpty}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('steer.pullBack')}\r\n title={row.text === null ? t('steer.pullBack.unsupported') : !composerEmpty ? t('steer.pullBack.composerBusy') : undefined}\r\n disabled={busy !== null || frozen || row.text === null || !composerEmpty}\r\n onClick={() => { void pullBackToComposer(row) }}\r\n >\r\n <IconRightUpOutline16 />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('queue.edit')} side=\"bottom\" delayMs={500} disabled={row.text === null}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.edit')}\r\n title={row.text === null ? t('queue.edit.unsupported') : undefined}\r\n disabled={busy !== null || row.text === null}\r\n onClick={() => {\r\n if (row.text !== null) setEditing({ id: row.id, text: row.text })\r\n }}\r\n >\r\n <IconEditOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('queue.remove')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.remove')}\r\n disabled={busy !== null}\r\n onClick={() => {\r\n void applyAction(row.id, { kind: 'remove' }, t('queue.removeFailed'))\r\n }}\r\n >\r\n <IconTrashOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n <span className={css.plan} role=\"group\" aria-label={t('steer.later.aria')}>\r\n <Tooltip label={t('steer.now')} side=\"bottom\" delayMs={500} disabled={planDisabled || row.text === null}>\r\n <button\r\n type=\"button\"\r\n className={`${css.tier} ${css.tierNow}`}\r\n aria-label={t('steer.now')}\r\n title={planDisabled ? t('steer.unavailable.running') : row.text === null ? t('steer.now.unsupported') : undefined}\r\n disabled={busy !== null || planDisabled || row.text === null}\r\n onClick={() => { void steerRow(row, 'now') }}\r\n >\r\n <span className={css.dot} aria-hidden />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('steer.next')} side=\"bottom\" delayMs={500} disabled={planDisabled}>\r\n <button\r\n type=\"button\"\r\n className={`${css.tier} ${css.tierNext}`}\r\n aria-label={t('steer.next')}\r\n title={planDisabled ? t('steer.unavailable.running') : undefined}\r\n disabled={busy !== null || planDisabled}\r\n onClick={() => { void steerRow(row, 'next') }}\r\n >\r\n <span className={css.dot} aria-hidden />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('steer.later')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={`${css.tier} ${css.tierLater}`}\r\n aria-label={t('steer.later')}\r\n aria-pressed\r\n disabled={busy !== null || clearing}\r\n onClick={() => {\r\n // Later is the default queue state; pressing it\r\n // keeps the row queued (no-op by design).\r\n }}\r\n >\r\n <span className={css.dot} aria-hidden />\r\n </button>\r\n </Tooltip>\r\n </span>\r\n </>\r\n )}\r\n </div>}\r\n </li>\r\n ))}\r\n </ul>\r\n {steering.length > 0 && (\r\n <ul className={css.steeringList} data-steering-list=\"\">\r\n {steering.map(row => (\r\n <li key={row.id} className={css.row} data-tier={badgeFor('steering') ?? undefined}>\r\n <span className={css.lead} aria-hidden><IconQueueOutline14 /></span>\r\n <SteerBadge tier={badgeFor('steering')} t={t} />\r\n <span className={css.preview}>{row.preview}</span>\r\n <div className={css.actions}>\r\n <Tooltip label={t('steer.revoke')} side=\"bottom\" delayMs={500} disabled={row.text === null}>\r\n <button\r\n type=\"button\"\r\n className={`${css.tier} ${css.tierLater}`}\r\n aria-label={t('steer.revoke')}\r\n title={row.text === null ? t('steer.revoke.unsupported') : undefined}\r\n disabled={busy !== null || row.text === null || frozen}\r\n onClick={() => { void revokeToLater(row) }}\r\n >\r\n <span className={css.dot} aria-hidden />\r\n </button>\r\n </Tooltip>\r\n </div>\r\n </li>\r\n ))}\r\n </ul>\r\n )}\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\n/** Badge label keys per tier. */\r\nconst BADGE_KEYS: Record<SteerTier, string> = {\r\n now: 'steer.badge.now',\r\n next: 'steer.badge.next',\r\n later: 'steer.badge.later',\r\n}\r\n\r\n/** Badge tint classes per tier (present at bundle time; typed through the css-modules declaration). */\r\nconst BADGE_CLASSES: Record<SteerTier, string> = {\r\n now: css.badgeNow as string,\r\n next: css.badgeNext as string,\r\n later: css.badgeLater as string,\r\n}\r\n\r\n/** One row's tier badge: colored dot + label; context rows render nothing. */\r\nfunction SteerBadge({ tier, t }: { tier: SteerTier | null; t: SteerQueueDockProps['t'] }) {\r\n if (tier === null) return null\r\n return (\r\n <span className={`${css.badge} ${BADGE_CLASSES[tier]}`} data-badge={tier}>\r\n <span className={css.dot} aria-hidden />\r\n <span className={css.badgeLabel}>{t(BADGE_KEYS[tier])}</span>\r\n </span>\r\n )\r\n}\r\n","/**\r\n * Session freeze/resume control, mounted in the composer's right tool row\r\n * (`conversation.input.right`) so it is reachable before anything queues.\r\n *\r\n * Peak-hour pause semantics: freeze does NOT interrupt the running turn —it\r\n * finishes naturally. The queued messages are detached (removed, preserved in\r\n * the shared store), so the driver finds no pending work and stops after the\r\n * current turn. Resume re-submits the preserved texts, waking the driver and\r\n * continuing the queue.\r\n */\r\nimport { useSyncExternalStore } from 'react'\r\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\r\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\r\nimport { freezeStore } from './freeze-store.ts'\r\nimport type { FrozenTier } from './freeze-store.ts'\r\nimport type { SteerQueueDockInjected } from './steer-queue-dock.tsx'\r\nimport css from './freeze-button.module.css'\r\n\r\n/** Full props of the composer-right entry: InputZone owner share + injected verbs + locale seat. */\r\nexport type FreezeButtonProps = PropsRuntime<'conversation.input.right'> & SteerQueueDockInjected & PropsLocale<'steer'>\r\n\r\n/**\r\n * Freeze/resume toggle for the peak-hour scenario.\r\n * @param props - slot props; the session snapshot drives the detach list.\r\n */\r\nexport function FreezeButton({ session, updateQueue, cancel, send, sendSteer, notify, t }: FreezeButtonProps) {\r\n const { frozen } = useSyncExternalStore(freezeStore.subscribe, freezeStore.getSnapshot)\r\n\r\n const freeze = async (): Promise<void> => {\r\n // Detach every pending input row — queued (next-turn) and already-steered\r\n // (next-step) alike — so nothing stays in the live queue while frozen.\r\n // Steered rows keep their next intent as a safe_point plan for resume.\r\n const rows = session.queue.filter(row => row.placement === 'queued' || row.placement === 'steering')\r\n // Preserve plain-text copies; non-text rows cannot be re-sent and are\r\n // released by the freeze (documented limitation).\r\n const pending: { text: string; tier: FrozenTier }[] = rows.flatMap(row =>\r\n row.text === null ? [] : [{ text: row.text, tier: row.placement === 'steering' ? 'safe_point' : 'queue' }],\r\n )\r\n // Detach every pending row: the running turn finishes naturally, then the\r\n // driver finds no pending work and stops.\r\n await Promise.all(rows.map(row =>\r\n updateQueue(row.id, { kind: 'remove' }).catch(() => undefined),\r\n ))\r\n freezeStore.set({ frozen: true, pending })\r\n }\r\n\r\n const resume = async (): Promise<void> => {\r\n const pending = freezeStore.getSnapshot().pending\r\n freezeStore.set({ frozen: false, pending: [] })\r\n try {\r\n // Re-submit the preserved queue in FIFO order honoring each entry's\r\n // planned insertion tier: force (red) interrupts the current run first,\r\n // safe_point (yellow) steers into the next step, queue (green) flows\r\n // through the wake-and-continue chain.\r\n for (const entry of pending) {\r\n if (entry.tier === 'force') await cancel()\r\n if (entry.tier === 'safe_point') await sendSteer(entry.text)\r\n else await send(entry.text)\r\n }\r\n } catch {\r\n notify('error', t('steer.resumeFailed'))\r\n }\r\n }\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n className={css.freeze}\r\n aria-label={frozen ? t('steer.resume') : t('steer.freeze')}\r\n aria-pressed={frozen || undefined}\r\n title={frozen ? t('steer.frozen') : undefined}\r\n onClick={() => {\r\n if (frozen) void resume()\r\n else void freeze()\r\n }}\r\n >\r\n <span className={css.label}>{frozen ? t('steer.resume') : t('steer.freeze')}</span>\r\n </button>\r\n )\r\n}\r\n","/**\r\n * Busy-Enter row hiding: shadows the official `settings.general.item` entry\r\n * `composer-enter` (same cell id, priority -1) so the lower priority wins and\r\n * the official \"繁忙时 Enter 键行为\" row never renders while this plugin is\r\n * mounted.\r\n *\r\n * The behavior itself is taken over by the plugin: plain Enter stays\r\n * queue-later (green), the planning dock owns yellow/red, and the plugin apply\r\n * pins `ui-conversation.busyEnter` to `queue` so no stale preference can\r\n * leak through the hidden row.\r\n */\r\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\r\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\r\n\r\n/** Full props of a settings-row entry (unused: the row renders nothing). */\r\nexport type HideEnterRowProps = PropsRuntime<'settings.general.item'> & PropsLocale<'steer'>\r\n\r\n/** Render nothing: the official busy-Enter row is hidden while mounted. */\r\nexport function HideEnterRow(_props: HideEnterRowProps): null {\r\n return null\r\n}\r\n","/**\r\n * dsh-input-traffic —browser half.\r\n *\r\n * The whole takeover lives here:\r\n * 1. registers the `steer` dictionaries;\r\n * 2. pins `ui-conversation.busyEnter` to `queue` (plain Enter = green later)\r\n * so the hidden official row cannot leak a stale queue/steer preference;\r\n * 3. shadows the official queue dock (`conversation.input.dock` cell id\r\n * `queue`, priority -1) with the three-tier planning strip;\r\n * 4. shadows the official busy-Enter settings row (`settings.general.item`\r\n * cell id `composer-enter`, priority -1) with a null render.\r\n *\r\n * All @deepseek-ai/* imports are type-only: collaboration happens through\r\n * cordis services and slot registration only (client bundle purity).\r\n */\r\nimport type { ClientContext, SessionId } from '@deepseek-ai/dsh-client-runtime/client'\r\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\r\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\r\nimport type { IConversation } from '@deepseek-ai/dsh-client-ui-conversation/client'\r\nimport { NS, en, zh } from './locales.ts'\r\nimport { SteerQueueDock } from './steer-queue-dock.tsx'\r\nimport type { SteerQueueDockInjected } from './steer-queue-dock.tsx'\r\nimport { FreezeButton } from './freeze-button.tsx'\r\nimport { HideEnterRow } from './hide-enter-row.tsx'\r\n\r\n/** Durable conversation settings namespace owned by ui-conversation. */\r\nconst CONVERSATION_SETTINGS_NAMESPACE = 'ui-conversation'\r\n\r\n/** Busy-Enter field inside that namespace; the plugin pins it to queue. */\r\nconst BUSY_ENTER_FIELD = 'busyEnter'\r\n\r\n/**\r\n * Deliver one plain-text message into the session's next step. The exposed\r\n * conversation `send` verb only queues into the next turn, so resume steers\r\n * through the session face's steer-mode prompt instead (no harness change).\r\n * @param ctx - root context (resolves the session face behind the scope).\r\n * @param actx - agent-scoped context of the owning session.\r\n * @param text - message text to deliver.\r\n */\r\nfunction steerPrompt(ctx: ClientContext, actx: ClientContext, text: string): Promise<void> {\r\n const session = ctx.sessions.sessionOf(actx)\r\n if (session === undefined) return Promise.reject(new Error('steer resume: session scope unavailable'))\r\n return session.prompt([{ type: 'text', text }], 'steer').then((result) => {\r\n if (!result.ok) {\r\n const error = result.error ?? { code: 'unknown', message: 'steer prompt rejected' }\r\n throw new Error(`conversation.sendSteer failed: ${error.code}: ${error.message}`)\r\n }\r\n })\r\n}\r\n\r\n/** Services required by the browser half. */\r\nexport const inject = ['slots', 'locale', 'sessions', 'conversation', 'settingsScope']\r\n\r\n/**\r\n * Client plugin body: dictionaries, busy-Enter pinning, and the two slot\r\n * shadowings.\r\n * @param ctx - client root context.\r\n */\r\nexport function apply(ctx: ClientContext): void {\r\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-input-traffic: dictionaries')\r\n\r\n // Take over the busy-Enter behavior: plain Enter stays queue-later while\r\n // the official row is hidden. Pinning here also repairs a persisted `steer`\r\n // preference that would otherwise keep working invisibly behind the hidden\r\n // row. Best-effort: a memory-mode host simply accepts it locally.\r\n const conversationSettings = ctx.settingsScope.bind<{ busyEnter: 'queue' | 'steer' }>({\r\n namespace: CONVERSATION_SETTINGS_NAMESPACE,\r\n })\r\n void conversationSettings.set(BUSY_ENTER_FIELD, 'queue')\r\n\r\n // Shadow the official queue dock with the three-tier planning strip.\r\n ctx.slots.inject('conversation.input.dock', () => ctx.slots.register({\r\n name: 'conversation.input.dock',\r\n id: 'queue',\r\n order: 20,\r\n priority: -1,\r\n locale: NS,\r\n inject: (sessionId: SessionId): SteerQueueDockInjected => {\r\n const actx = ctx.sessions.scope(sessionId)\r\n if (actx === undefined) throw new Error(`steer dock: session \"${sessionId}\" resolved no scope`)\r\n const conversation = actx.get<IConversation>('conversation')\r\n if (conversation === undefined) throw new Error('steer dock: conversation service unavailable')\r\n return {\r\n updateQueue: (itemId, action) => conversation.updateQueue(itemId, action),\r\n cancel: () => conversation.cancel(),\r\n send: (text) => conversation.send(text),\r\n sendSteer: (text) => steerPrompt(ctx, actx, text),\r\n setDraft: (text) => { conversation.input.for(actx).actions.setDraft(text) },\r\n notify: (level, text) => { conversation.input.for(actx).notify(level, text) },\r\n }\r\n },\r\n }, SteerQueueDock))\r\n\r\n // Composer-right freeze/resume control (reachable before anything queues).\r\n ctx.slots.inject('conversation.input.right', () => ctx.slots.register({\r\n name: 'conversation.input.right',\r\n id: 'steer-freeze',\r\n order: 30,\r\n locale: NS,\r\n inject: (sessionId: SessionId): SteerQueueDockInjected => {\r\n const actx = ctx.sessions.scope(sessionId)\r\n if (actx === undefined) throw new Error(`steer freeze: session \"${sessionId}\" resolved no scope`)\r\n const conversation = actx.get<IConversation>('conversation')\r\n if (conversation === undefined) throw new Error('steer freeze: conversation service unavailable')\r\n return {\r\n updateQueue: (itemId, action) => conversation.updateQueue(itemId, action),\r\n cancel: () => conversation.cancel(),\r\n send: (text) => conversation.send(text),\r\n sendSteer: (text) => steerPrompt(ctx, actx, text),\r\n setDraft: (text) => { conversation.input.for(actx).actions.setDraft(text) },\r\n notify: (level, text) => { conversation.input.for(actx).notify(level, text) },\r\n }\r\n },\r\n }, FreezeButton))\r\n\r\n // Hide the official busy-Enter settings row (null render wins the cell).\r\n ctx.slots.inject('settings.general.item', () => ctx.slots.register({\r\n name: 'settings.general.item',\r\n id: 'composer-enter',\r\n order: 20,\r\n priority: -1,\r\n locale: NS,\r\n }, HideEnterRow))\r\n}\r\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":["useMemo","useState","useRef","useSyncExternalStore","useId","css","IconQueueOutline14","IconChevronDownOutline14","IconChevronUpOutline14","Tooltip","IconTrashOutline16","IconCheckOutline16","IconCloseOutline16","IconEditOutline16","IconRightUpOutline16","useSyncExternalStore","css"],"sources":["src/client/locales.ts","src/client/freeze-store.ts","src/client/steer-queue-dock.tsx","src/client/freeze-button.tsx","src/client/hide-enter-row.tsx","src/client/index.ts"],"sourcesContent":["/** `steer` namespace dictionaries. */\r\n\r\n/** Dictionary namespace owned by this plugin. */\r\nexport const NS = 'steer'\r\n\r\n/** Simplified Chinese dictionary (the key-set source of truth). */\r\nexport const zh = {\r\n 'queue.count': '{n} 条排队消息',\r\n 'queue.edit': '编辑排队消息',\r\n 'queue.edit.unsupported': '包含非文本内容,暂不支持编辑',\r\n 'queue.save': '保存排队消息',\r\n 'queue.cancelEdit': '取消编辑',\r\n 'queue.remove': '删除排队消息',\r\n 'queue.removeFailed': '删除失败:这条消息可能已经开始发送。',\r\n 'queue.editFailed': '编辑失败:这条消息可能已经开始发送。',\r\n 'queue.editFailed.pulledBack': '编辑失败,内容已退回主输入框,请确认后重新发送。',\r\n 'steer.inflight': '{n} 条正在插入',\r\n 'steer.now': '打断并输入',\r\n 'steer.now.aria': '红色:打断当前动作并立即输入',\r\n 'steer.now.unsupported': '包含非文本内容,暂不支持打断',\r\n 'steer.nowFailed': '打断失败,请重试。',\r\n 'steer.next': '插话发送',\r\n 'steer.next.aria': '黄色:当前动作结束后插入输入',\r\n 'steer.nextFailed': '插话发送失败,请重试。',\r\n 'steer.later': '排队到下一轮',\r\n 'steer.later.aria': '绿色:排队,上一轮输入的动作都结束后再处理',\r\n 'steer.revoke': '收回排队',\r\n 'steer.revoke.aria': '绿色:撤销插入,收回排队(下一轮处理)',\r\n 'steer.revoke.unsupported': '包含非文本内容,暂不支持收回',\r\n 'steer.revokeFailed': '收回排队失败,请重试。',\r\n 'steer.moveUp': '上移',\r\n 'steer.moveDown': '下移',\r\n 'steer.reorder.unsupported': '包含非文本内容,暂不支持排序',\r\n 'steer.reorderFailed': '调整顺序失败,请重试。',\r\n 'steer.reorderStale': '队列已变化,本次排序已取消,请重试。',\r\n 'steer.dragReorder': '拖动调整顺序',\r\n 'steer.pullBack': '打回输入框编辑',\r\n 'steer.pullBack.unsupported': '包含非文本内容,暂不支持打回编辑',\r\n 'steer.pullBack.composerBusy': '主输入框已有内容,请先发送或清空后再打回',\r\n 'steer.pullBackFailed': '打回输入框失败,请重试。',\r\n 'steer.badge.now': '打断中',\r\n 'steer.badge.next': '插话中',\r\n 'steer.badge.later': '排队',\r\n 'steer.unavailable.running': '仅运行中可规划',\r\n 'steer.clear': '取消并清空',\r\n 'steer.clear.confirm': '确认清空?',\r\n 'steer.clear.cancel': '取消清空',\r\n 'steer.clear.aria': '取消当前执行并清空全部排队消息',\r\n 'steer.clearFailed': '取消并清空失败,请重试。',\r\n 'steer.freeze': '冻结会话',\r\n 'steer.resume': '恢复会话',\r\n 'steer.frozen': '已冻结:当前轮次完成后暂停,排队消息将在恢复后继续',\r\n 'steer.frozenBadge': '已冻结',\r\n 'steer.freezeFailed': '冻结失败,请重试。',\r\n 'steer.resumeFailed': '恢复失败,请重试。',\r\n} satisfies Record<string, string>\r\n\r\n/** English dictionary (keys mirror zh). */\r\nexport const en: Record<keyof typeof zh, string> = {\r\n 'queue.count': '{n} queued messages',\r\n 'queue.edit': 'Edit queued message',\r\n 'queue.edit.unsupported': 'Contains non-text content; editing is unsupported',\r\n 'queue.save': 'Save queued message',\r\n 'queue.cancelEdit': 'Cancel edit',\r\n 'queue.remove': 'Remove queued message',\r\n 'queue.removeFailed': 'Remove failed: the message may have started sending.',\r\n 'queue.editFailed': 'Edit failed: the message may have started sending.',\r\n 'queue.editFailed.pulledBack': 'Edit failed; the content was moved back to the composer, please review and resend.',\r\n 'steer.inflight': '{n} inserting',\r\n 'steer.now': 'Interrupt and send',\r\n 'steer.now.aria': 'Red: interrupt the running action and send now',\r\n 'steer.now.unsupported': 'Contains non-text content; interrupting is unsupported',\r\n 'steer.nowFailed': 'Interrupt failed, please retry.',\r\n 'steer.next': 'Send after action',\r\n 'steer.next.aria': 'Yellow: insert after the current action finishes',\r\n 'steer.nextFailed': 'Steering failed, please retry.',\r\n 'steer.later': 'Queue for next turn',\r\n 'steer.later.aria': 'Green: queue; processed after all previously steered actions finish',\r\n 'steer.revoke': 'Pull back to queue',\r\n 'steer.revoke.aria': 'Green: revoke the insertion and queue for the next turn',\r\n 'steer.revoke.unsupported': 'Contains non-text content; revoking is unsupported',\r\n 'steer.revokeFailed': 'Revoke failed, please retry.',\r\n 'steer.moveUp': 'Move up',\r\n 'steer.moveDown': 'Move down',\r\n 'steer.reorder.unsupported': 'Contains non-text content; reordering is unsupported',\r\n 'steer.reorderFailed': 'Reorder failed, please retry.',\r\n 'steer.reorderStale': 'The queue changed; this reorder was cancelled, please retry.',\r\n 'steer.dragReorder': 'Drag to reorder',\r\n 'steer.pullBack': 'Edit in composer',\r\n 'steer.pullBack.unsupported': 'Contains non-text content; pulling back is unsupported',\r\n 'steer.pullBack.composerBusy': 'The composer already has content; send or clear it first',\r\n 'steer.pullBackFailed': 'Pull back failed, please retry.',\r\n 'steer.badge.now': 'interrupting',\r\n 'steer.badge.next': 'steering',\r\n 'steer.badge.later': 'queued',\r\n 'steer.unavailable.running': 'Planning requires a running session',\r\n 'steer.clear': 'Cancel and clear',\r\n 'steer.clear.confirm': 'Confirm clear?',\r\n 'steer.clear.cancel': 'Cancel clearing',\r\n 'steer.clear.aria': 'Cancel the current run and clear all queued messages',\r\n 'steer.clearFailed': 'Cancel and clear failed, please retry.',\r\n 'steer.freeze': 'Freeze session',\r\n 'steer.resume': 'Resume session',\r\n 'steer.frozen': 'Frozen: the current turn finishes, then the queue pauses until resumed',\r\n 'steer.frozenBadge': 'frozen',\r\n 'steer.freezeFailed': 'Freeze failed, please retry.',\r\n 'steer.resumeFailed': 'Resume failed, please retry.',\r\n}\r\n\r\n/** Dictionary key union. */\r\nexport type SteerKey = keyof typeof zh\r\n","/**\r\n * Session-freeze store shared by the composer freeze button (the control)\r\n * and the steering dock (the banner/disabled states).\r\n *\r\n * The queue is fully decoupled from freezing: freezing only stops the agent\n * from consuming the queue (the detached entries are preserved here so the\r\n * driver finds no pending work and stops). While frozen the entries stay\r\n * fully editable — text, order and the planned insertion tier (now/next/\r\n * later) can all change; resume re-submits the queue honoring those tiers.\r\n */\r\n\r\n/** Insertion tier planned for one detached queued message. */\r\nexport type FrozenTier = 'queue' | 'safe_point' | 'force'\r\n\r\n/** One detached queued message with its planned insertion tier. */\r\nexport interface FrozenEntry {\r\n text: string\r\n tier: FrozenTier\r\n}\r\n\r\nexport interface FreezeState {\r\n frozen: boolean\r\n /** Detached queued messages in FIFO order, each with a planned tier. */\r\n pending: readonly FrozenEntry[]\r\n}\r\n\r\nconst listeners = new Set<() => void>()\r\nlet state: FreezeState = { frozen: false, pending: [] }\r\n\r\n/** Minimal snapshot store (no runtime dependency, stable identity per mount). */\r\nexport const freezeStore = {\r\n getSnapshot(): FreezeState {\r\n return state\r\n },\r\n subscribe(listener: () => void): () => void {\r\n listeners.add(listener)\r\n return () => { listeners.delete(listener) }\r\n },\r\n set(next: FreezeState): void {\r\n state = next\r\n for (const listener of listeners) listener()\r\n },\r\n}\r\n\r\n/** Reset for tests. */\r\nexport function resetFreezeStore(): void {\r\n state = { frozen: false, pending: [] }\r\n for (const listener of listeners) listener()\r\n}\r\n\r\n/** Append one queued message while frozen (new input lands in the detached queue). */\r\nexport function pushPending(text: string, tier: FrozenTier = 'queue'): void {\r\n state = { ...state, pending: [...state.pending, { text, tier }] }\r\n emit()\r\n}\r\n\r\n/** Edit one detached queued message's text in place. */\r\nexport function updatePendingAt(index: number, text: string): void {\r\n const pending = [...state.pending]\r\n if (index < 0 || index >= pending.length) return\r\n const entry = pending[index]\r\n if (entry === undefined) return\r\n pending[index] = { ...entry, text }\r\n state = { ...state, pending }\r\n emit()\r\n}\r\n\r\n/** Change one detached queued message's planned insertion tier. */\r\nexport function setTierAt(index: number, tier: FrozenTier): void {\r\n const pending = [...state.pending]\r\n if (index < 0 || index >= pending.length) return\r\n const entry = pending[index]\r\n if (entry === undefined) return\r\n pending[index] = { ...entry, tier }\r\n state = { ...state, pending }\r\n emit()\r\n}\r\n\r\n/** Remove one detached queued message. */\r\nexport function removePendingAt(index: number): void {\r\n if (index < 0 || index >= state.pending.length) return\r\n state = { ...state, pending: state.pending.filter((_, i) => i !== index) }\r\n emit()\r\n}\r\n\r\n/** Move one detached queued message to a new position (reorder while frozen). */\r\nexport function movePending(from: number, to: number): void {\r\n if (from === to) return\r\n const pending = [...state.pending]\r\n const [moved] = pending.splice(from, 1)\r\n if (moved === undefined) return\r\n pending.splice(to, 0, moved)\r\n state = { ...state, pending }\r\n emit()\r\n}\r\n\r\nfunction emit(): void {\r\n for (const listener of listeners) listener()\r\n}\r\n","/**\r\n * Three-tier steering queue dock: the shadowing replacement for the official\r\n * `conversation.input.dock` entry (same cell id `queue`, priority -1, so the\r\n * lower priority wins and the official QueueDock never renders while this\r\n * plugin is mounted).\r\n *\r\n * Every queued row carries three planning buttons:\r\n * - green (later, the default state): the row already queues for the next\r\n * turn —plain Enter keeps feeding rows here; pressing green on a row that\r\n * was already steered (yellow) revokes the insertion and pulls it back to\r\n * later (the yellow flow is reversible);\r\n * - yellow (next): strict-steer the row into the running turn, consumed at\r\n * the next step boundary (after the current action finishes);\r\n * - red (now): cancel the running turn, then remove the row and re-send its\r\n * text as a fresh message —the re-send arms the harness wake latch (the\r\n * converged driver restarts) and the interrupted input is processed as the\r\n * next turn's input. A plain steer after cancel would re-insert a message\r\n * that is already pending in next-turn and the inbox rejects it.\r\n *\r\n * The toolbar also exposes a queue-level \"cancel and clear\" that stops the\r\n * current run and removes every queued row, plus a session-level\r\n * freeze/resume toggle for the peak-hour scenario: freeze stops the current\r\n * run while preserving the queue (keepInbox), resume re-arms the driver by\r\n * re-sending the first queued row so the preserved work continues.\r\n */\r\nimport { useEffect, useId, useMemo, useRef, useState, useSyncExternalStore } from 'react'\r\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\r\n// Type-only: the conversation slot/contract declarations (module augmentation\r\n// for the SlotMap and the session standard kit). No value import crosses the\r\n// plugin boundary.\r\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\r\nimport {\r\n IconCheckOutline16, IconChevronDownOutline14, IconChevronUpOutline14, IconCloseOutline16,\r\n IconEditOutline16, IconQueueOutline14, IconRightUpOutline16, IconTrashOutline16, Tooltip,\r\n} from '@deepseek-ai/dsh-client-ui-primitives'\r\nimport { freezeStore, setTierAt, updatePendingAt, removePendingAt, movePending } from './freeze-store.ts'\r\nimport css from './steer-queue-dock.module.css'\r\n\r\n/** One mutation accepted by the conversation queue verb. */\r\nexport type SteerQueueAction =\r\n | { kind: 'edit'; content: readonly { type: 'text'; text: string }[] }\r\n | { kind: 'remove' }\r\n | { kind: 'steer' }\r\n\r\n/** Busy marker for a whole-queue rebuild (reorder); locks every row action. */\r\nconst REORDER_MARK = '__reorder__'\r\n\r\n/** localStorage key for the manual collapse state (dsh-queue-plus parity). */\r\nconst COLLAPSE_KEY = 'dsh-input-traffic:collapsed'\r\n\r\n/** Queue operations injected by the session-scoped registration. */\r\nexport interface SteerQueueDockInjected {\r\n updateQueue: (itemId: string, action: SteerQueueAction) => Promise<void>\r\n /** Cancel the current turn while preserving the pending queue. */\r\n cancel: () => Promise<void>\r\n /** Re-send one plain-text message as a queued follow-up (the revoke path). */\r\n send: (text: string) => Promise<void>\r\n /** Back-fill the composer draft (the pull-back-to-composer edit path). */\r\n setDraft: (text: string) => void\r\n notify: (level: 'info' | 'error', text: string) => void\r\n}\r\n\r\n/** Full props of a dock entry: InputZone owner share + session standard kit + global seat + the locale seat. */\r\nexport type SteerQueueDockProps = PropsRuntime<'conversation.input.dock'> & SteerQueueDockInjected & PropsLocale<'steer'>\r\n\r\n/** The planning tier of one queued row. */\r\nexport type SteerTier = 'now' | 'next' | 'later'\r\n\r\n/**\r\n * Resolve the action sequence for one planning button press. Pure so the\r\n * button wiring and its tests share one truth.\r\n * @param tier - the pressed planning tier.\r\n * @returns the queue mutation (red re-uses a steer-shaped action for the\r\n * yellow branch; the red branch performs cancel + remove + resend instead).\r\n */\r\nexport function planActionFor(tier: SteerTier): { action: SteerQueueAction; interruptFirst: boolean } {\r\n if (tier === 'later') return { action: { kind: 'steer' }, interruptFirst: false }\r\n // Yellow steers only; red cancels the running turn first, then steers.\r\n return { action: { kind: 'steer' }, interruptFirst: tier === 'now' }\r\n}\r\n\r\n/**\r\n * Project the tier badge of one inbox row from its placement. Pure so the\r\n * row rendering and its tests share one truth.\r\n * @param placement - the inbox projection placement.\r\n * @returns the tier badge, or null for non-visible context rows.\r\n */\r\nexport function badgeFor(placement: 'queued' | 'steering' | 'context'): SteerTier | null {\r\n if (placement === 'steering') return 'next'\r\n if (placement === 'queued') return 'later'\r\n return null\r\n}\r\n\r\n/**\r\n * Auto-grow one edit textarea to its content. The CSS max-height caps the\r\n * growth; beyond it the textarea scrolls internally. Height is reset first so\r\n * shrink (deleting lines) also tracks the content.\r\n * @param el - the textarea to resize in place.\r\n */\r\nexport function resizeEditor(el: HTMLTextAreaElement): void {\r\n el.style.height = 'auto'\r\n el.style.height = `${el.scrollHeight}px`\r\n}\r\n\r\n/**\r\n * Queue strip with three-tier planning: one item renders directly; multiple\r\n * items default to a collapsible count header; an empty queue renders nothing.\r\n */\r\nexport function SteerQueueDock({ useSession, input, updateQueue, cancel, send, setDraft, notify, t }: SteerQueueDockProps) {\r\n const inbox = useSession(s => s.queue)\r\n const queue = useMemo(() => inbox.filter(row => row.placement === 'queued'), [inbox])\r\n const steering = useMemo(() => inbox.filter(row => row.placement === 'steering'), [inbox])\r\n const running = useSession(s => s.running)\r\n const queueMutable = useSession(s => s.subagent === null)\r\n const [editing, setEditing] = useState<{ id: string; text: string } | null>(null)\r\n const [busy, setBusy] = useState<string | null>(null)\r\n const [clearing, setClearing] = useState(false)\r\n // Two-step clear confirmation: the first click arms the prompt, the second\r\n // executes; arming auto-reverts after a few seconds (no native confirm).\r\n const [confirmClear, setConfirmClear] = useState(false)\r\n const confirmTimer = useRef<ReturnType<typeof setTimeout> | null>(null)\r\n // Drag-and-drop reorder source index and the current drop-target row.\r\n const dragIndex = useRef<number | null>(null)\r\n const [dragOver, setDragOver] = useState<number | null>(null)\r\n // Collapse state persists across mounts (dsh-queue-plus parity).\r\n const [collapsed, setCollapsed] = useState(() => {\r\n try {\r\n const v = localStorage.getItem(COLLAPSE_KEY)\r\n return v === null ? true : v === '1'\r\n } catch {\r\n return true\r\n }\r\n })\r\n // Session-level freeze lives in the composer-right control; the dock reads\r\n // the shared store for the banner and inert states. While frozen the\r\n // detached queue is rendered here (read-only) so the waiting area stays\r\n // visible — freezing only pauses the running behavior, it must not hide\r\n // the queued messages.\r\n const { frozen, pending: frozenPending } = useSyncExternalStore(freezeStore.subscribe, freezeStore.getSnapshot)\r\n const listId = useId()\r\n // The edit textarea; grown to its content on entry and on every input.\r\n const editorRef = useRef<HTMLTextAreaElement>(null)\r\n\r\n useEffect(() => {\r\n if (queue.length === 0 && !collapsed) setCollapsed(true)\r\n // Frozen-row edits use a `frozen:` id that never exists in the dsh queue;\r\n // skip the stale-check for them so the detached queue stays editable.\r\n if (editing !== null && !editing.id.startsWith('frozen:') && (!queueMutable || !queue.some(row => row.id === editing.id))) setEditing(null)\r\n }, [collapsed, editing, queue, queueMutable])\r\n\r\n // Persist the manual collapse state; clear the confirm timer on unmount.\r\n useEffect(() => {\r\n try {\r\n localStorage.setItem(COLLAPSE_KEY, collapsed ? '1' : '0')\r\n } catch {\r\n /* storage unavailable: in-memory only */\r\n }\r\n }, [collapsed])\r\n useEffect(() => () => {\r\n if (confirmTimer.current !== null) clearTimeout(confirmTimer.current)\r\n }, [])\r\n\r\n // Grow the editor to its full content when a row enters edit mode.\r\n const editingId = editing?.id\r\n useEffect(() => {\r\n if (editingId === undefined) return\r\n const el = editorRef.current\r\n if (el !== null) resizeEditor(el)\r\n }, [editingId])\r\n\r\n // The dock stays mounted while the agent runs (the freeze entry must be\r\n // reachable before any message queues), while any row is pending, and while\r\n // the session is frozen (the detached queue stays visible).\r\n if (queue.length === 0 && steering.length === 0 && !running && !frozen) return null\r\n\r\n const interactionActive = queueMutable && (editing !== null || busy !== null || clearing)\r\n const expanded = !collapsed || interactionActive\r\n const listVisible = queue.length === 1 || expanded\r\n const planDisabled = !queueMutable || !running || frozen\r\n const nothingPending = queue.length === 0 && steering.length === 0\r\n // Reordering rebuilds the queue by re-sending texts; non-text rows cannot\r\n // be re-sent, so sorting is disabled while any such row is queued.\r\n const reorderUnsupported = queue.some(row => row.text === null)\r\n // Pull-back-to-composer is only offered when the composer draft is empty:\r\n // the pulled message back-fills the draft, so an occupied composer would be\r\n // overwritten. Steered (yellow/red) rows never offer it — once inserted,\r\n // they are not deeply re-edited.\r\n const composerEmpty = input.draft.trim() === ''\r\n\r\n const applyAction = async (\r\n itemId: string,\r\n action: SteerQueueAction,\r\n failure: string,\r\n ): Promise<boolean> => {\r\n setBusy(itemId)\r\n try {\r\n await updateQueue(itemId, action)\r\n return true\r\n } catch {\r\n notify('error', failure)\r\n return false\r\n } finally {\r\n setBusy(current => current === itemId ? null : current)\r\n }\r\n }\r\n\r\n const saveEdit = async (): Promise<void> => {\r\n if (editing === null || editing.text.trim() === '') return\r\n const itemId = editing.id\r\n const text = editing.text\r\n setBusy(itemId)\r\n try {\r\n await updateQueue(itemId, { kind: 'edit', content: [{ type: 'text', text }] })\r\n setEditing(null)\r\n } catch {\r\n // The edit failed (the agent may have claimed the row mid-edit): fall\r\n // back to the composer so the edited content is never lost. Only when\r\n // the composer is free — an occupied draft must not be overwritten.\r\n if (input.draft.trim() === '') {\r\n setDraft(text)\r\n setEditing(null)\r\n notify('error', t('queue.editFailed.pulledBack'))\r\n } else {\r\n notify('error', t('queue.editFailed'))\r\n }\r\n } finally {\r\n setBusy(current => current === itemId ? null : current)\r\n }\r\n }\r\n\r\n const steerRow = async (row: { id: string; text: string | null }, tier: Exclude<SteerTier, 'later'>): Promise<void> => {\r\n setBusy(row.id)\r\n try {\r\n if (tier === 'now') {\r\n // Interrupt, then re-submit: cancel stops the current run (keepInbox),\r\n // the row is removed so its identity cannot collide, and re-sending\r\n // the text arms the harness wake latch (the converged driver restarts\r\n // and processes it as the next turn's input). A plain steer after\r\n // cancel would re-insert a message already pending in next-turn and\r\n // the inbox rejects the duplicate.\r\n await cancel()\r\n await updateQueue(row.id, { kind: 'remove' })\r\n if (row.text !== null) await send(row.text)\r\n } else {\r\n await updateQueue(row.id, { kind: 'steer' })\r\n }\r\n } catch {\r\n notify('error', tier === 'now' ? t('steer.nowFailed') : t('steer.nextFailed'))\r\n } finally {\r\n setBusy(current => current === row.id ? null : current)\r\n }\r\n }\r\n\r\n /**\r\n * Revoke a steered (yellow) or interrupting (red) row back to later: remove\r\n * the admitted row and re-send its text as a queued follow-up, so it lands\r\n * in next-turn again (the yellow flow is reversible).\r\n */\r\n const revokeToLater = async (row: { id: string; text: string | null }): Promise<void> => {\r\n if (row.text === null) return\r\n setBusy(row.id)\r\n try {\r\n await updateQueue(row.id, { kind: 'remove' })\r\n await send(row.text)\r\n } catch {\r\n notify('error', t('steer.revokeFailed'))\r\n } finally {\r\n setBusy(current => current === row.id ? null : current)\r\n }\r\n }\r\n\r\n /**\r\n * Rebuild the queue in a new order: remove every queued row, then re-send\r\n * the texts sequentially so the agent's next-turn list matches the new\r\n * order. Concurrency protection (dsh-queue-plus parity): if a remove fails\r\n * with queue-item-not-found, the agent already claimed that row — the\r\n * rebuild stops immediately and nothing is re-sent, so the changed queue\r\n * is never scrambled.\r\n */\r\n const rebuildQueue = async (rows: readonly { id: string; text: string | null }[], next: readonly { id: string; text: string | null }[]): Promise<void> => {\r\n setBusy(REORDER_MARK)\r\n try {\r\n for (const row of rows) {\r\n try {\r\n await updateQueue(row.id, { kind: 'remove' })\r\n } catch (error) {\r\n if (error instanceof Error && error.message.includes('queue-item-not-found')) {\r\n notify('error', t('steer.reorderStale'))\r\n return\r\n }\r\n throw error\r\n }\r\n }\r\n for (const row of next) {\r\n if (row.text !== null) await send(row.text)\r\n }\r\n } catch {\r\n notify('error', t('steer.reorderFailed'))\r\n } finally {\r\n setBusy(null)\r\n }\r\n }\r\n\r\n /**\r\n * Move one queued row up/down in the FIFO order (arrow buttons).\r\n */\r\n const reorder = async (rowId: string, delta: -1 | 1): Promise<void> => {\r\n const rows = queue\r\n const index = rows.findIndex(row => row.id === rowId)\r\n const target = index + delta\r\n if (index < 0 || target < 0 || target >= rows.length) return\r\n const next = [...rows]\r\n const swapped = next[index] as typeof next[number]\r\n next[index] = next[target] as typeof next[number]\r\n next[target] = swapped\r\n if (next.some(row => row.text === null)) {\r\n notify('error', t('steer.reorder.unsupported'))\r\n return\r\n }\r\n await rebuildQueue(rows, next)\r\n }\r\n\r\n /**\r\n * Move one row to an absolute position (drag-and-drop drop handler).\r\n */\r\n const reorderTo = async (fromIndex: number, toIndex: number): Promise<void> => {\r\n if (fromIndex === toIndex) return\r\n const rows = queue\r\n if (rows[fromIndex] === undefined || rows[toIndex] === undefined) return\r\n const next = [...rows]\r\n const [moved] = next.splice(fromIndex, 1)\r\n if (moved === undefined) return\r\n next.splice(toIndex, 0, moved)\r\n if (next.some(row => row.text === null)) {\r\n notify('error', t('steer.reorder.unsupported'))\r\n return\r\n }\r\n await rebuildQueue(rows, next)\r\n }\r\n\r\n /** Arm or execute the two-step clear confirmation. */\r\n const armClear = (): void => {\r\n if (confirmClear) {\r\n if (confirmTimer.current !== null) clearTimeout(confirmTimer.current)\r\n setConfirmClear(false)\r\n void clearAll()\r\n return\r\n }\r\n setConfirmClear(true)\r\n if (confirmTimer.current !== null) clearTimeout(confirmTimer.current)\r\n confirmTimer.current = setTimeout(() => setConfirmClear(false), 3000)\r\n }\r\n\r\n /** Abort the armed clear confirmation (the explicit cancel button). */\r\n const cancelClear = (): void => {\r\n if (confirmTimer.current !== null) clearTimeout(confirmTimer.current)\r\n setConfirmClear(false)\r\n }\r\n\r\n /** Save an in-place edit of one detached (frozen) queued message. */\r\n const saveFrozenEdit = async (index: number): Promise<void> => {\r\n if (editing === null) return\r\n const text = editing.text.trim()\r\n if (text === '') {\r\n setEditing(null)\r\n return\r\n }\r\n updatePendingAt(index, text)\r\n setEditing(null)\r\n }\r\n\r\n /**\r\n * Pull one queued row back into the composer draft for editing: the text\r\n * back-fills the input box and the row leaves the queue; the user edits and\r\n * resubmits it as a fresh message.\r\n */\r\n const pullBackToComposer = async (row: { id: string; text: string | null }): Promise<void> => {\r\n if (row.text === null) return\r\n setDraft(row.text)\r\n setBusy(row.id)\r\n try {\r\n await updateQueue(row.id, { kind: 'remove' })\r\n } catch {\r\n notify('error', t('steer.pullBackFailed'))\r\n } finally {\r\n setBusy(current => current === row.id ? null : current)\r\n }\r\n }\r\n\r\n const clearAll = async (): Promise<void> => {\r\n setClearing(true)\r\n // Cancel the current run and clear every pending row (queued and\r\n // steering alike). Removal races the agent claiming rows;\r\n // item-not-found is a normal convergence and must not surface.\r\n const pending = [...queue, ...steering]\r\n try {\r\n await cancel()\r\n await Promise.all(pending.map(row =>\r\n updateQueue(row.id, { kind: 'remove' }).catch(() => undefined),\r\n ))\r\n } catch {\r\n notify('error', t('steer.clearFailed'))\r\n } finally {\r\n setClearing(false)\r\n }\r\n }\r\n\r\n return (\r\n <div className={css.dock} data-steer-dock=\"\">\r\n <div className={css.panel}>\r\n <div className={css.toolbar}>\r\n <button\r\n type=\"button\"\r\n className={css.header}\r\n aria-controls={listId}\r\n aria-expanded={expanded}\r\n disabled={queue.length <= 1 || interactionActive}\r\n onClick={() => { setCollapsed(value => !value) }}\r\n >\r\n <span className={css.lead} aria-hidden><IconQueueOutline14 /></span>\r\n {queue.length > 0 && (\r\n <span className={css.count}>{t('queue.count', { n: queue.length })}</span>\r\n )}\r\n {queue.length > 1 && (\r\n <span className={css.chevron} aria-hidden>\r\n {expanded ? <IconChevronDownOutline14 /> : <IconChevronUpOutline14 />}\r\n </span>\r\n )}\r\n </button>\r\n <div className={css.toolbarActions}>\r\n {confirmClear && (\r\n <button\r\n type=\"button\"\r\n className={css.clearCancel}\r\n aria-label={t('steer.clear.cancel')}\r\n disabled={clearing || busy !== null || nothingPending}\r\n onClick={cancelClear}\r\n >\r\n <span className={css.clearLabel}>{t('steer.clear.cancel')}</span>\r\n </button>\r\n )}\r\n <Tooltip label={confirmClear ? t('steer.clear.confirm') : t('steer.clear')} side=\"top\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={`${css.clear} ${confirmClear ? css.clearConfirm : ''}`}\r\n aria-label={confirmClear ? t('steer.clear.confirm') : t('steer.clear')}\r\n disabled={clearing || busy !== null || nothingPending}\r\n onClick={armClear}\r\n >\r\n <IconTrashOutline16 size={14} />\r\n <span className={css.clearLabel}>{confirmClear ? t('steer.clear.confirm') : t('steer.clear')}</span>\r\n </button>\r\n </Tooltip>\r\n </div>\r\n </div>\r\n {frozen && (\r\n <div className={css.frozenBanner} role=\"status\">\r\n {t('steer.frozen')}\r\n </div>\r\n )}\r\n {/* While frozen the queue is detached into the shared store: render it\r\n here so the waiting area never disappears. The detached rows stay\r\n fully editable (edit / remove / reorder) — freezing only pauses\r\n the running behavior, it must not lock the queue. */}\r\n {frozen && frozenPending.length > 0 && (\r\n <ul className={css.frozenList} data-testid=\"frozen-list\">\r\n {frozenPending.map((entry, i) => {\r\n const editingFrozen = editing?.id === `frozen:${i}`\r\n const text = entry.text\r\n return (\r\n <li\r\n key={i}\r\n className={`${css.frozenRow} ${dragOver === i && frozen ? css.rowDragOver : ''}`}\r\n data-tier={entry.tier === 'force' ? 'now' : entry.tier === 'safe_point' ? 'next' : 'later'}\r\n data-editing={editingFrozen ? '' : undefined}\r\n draggable={!editingFrozen}\r\n title={!editingFrozen ? t('steer.dragReorder') : undefined}\r\n onDragStart={(event) => {\r\n if (editingFrozen) return\r\n dragIndex.current = i\r\n event.dataTransfer.effectAllowed = 'move'\r\n // Some engines only start HTML5 drag once data is set.\r\n event.dataTransfer.setData('text/plain', String(i))\r\n }}\r\n onDragOver={(event) => {\r\n if (dragIndex.current === null) return\r\n event.preventDefault()\r\n setDragOver(i)\r\n }}\r\n onDrop={(event) => {\r\n event.preventDefault()\r\n const from = dragIndex.current\r\n dragIndex.current = null\r\n setDragOver(null)\r\n if (from !== null) movePending(from, i)\r\n }}\r\n onDragEnd={() => {\r\n dragIndex.current = null\r\n setDragOver(null)\r\n }}\r\n >\r\n <span className={css.lead} aria-hidden><IconQueueOutline14 /></span>\r\n <SteerBadge tier={entry.tier === 'force' ? 'now' : entry.tier === 'safe_point' ? 'next' : 'later'} t={t} />\r\n {editingFrozen\r\n ? (\r\n <textarea\r\n ref={editorRef}\r\n autoFocus\r\n className={css.editor}\r\n aria-label={t('queue.edit')}\r\n rows={1}\r\n value={editing?.text ?? text}\r\n onChange={(event) => { setEditing({ id: `frozen:${i}`, text: event.currentTarget.value }) }}\r\n onInput={(event) => { resizeEditor(event.currentTarget) }}\r\n onKeyDown={(event) => {\r\n if (event.key === 'Escape') {\r\n setEditing(null)\r\n return\r\n }\r\n if (event.key === 'Enter' && !event.shiftKey && !event.nativeEvent.isComposing) {\r\n event.preventDefault()\r\n void saveFrozenEdit(i)\r\n }\r\n }}\r\n />\r\n )\r\n : <span className={css.preview}>{text}</span>}\r\n <div className={css.actions}>\r\n {editingFrozen ? (\r\n <>\r\n <Tooltip label={t('queue.save')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.save')}\r\n disabled={editing === null || editing.text.trim() === ''}\r\n onClick={() => { void saveFrozenEdit(i) }}\r\n >\r\n <IconCheckOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('queue.cancelEdit')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.cancelEdit')}\r\n onClick={() => { setEditing(null) }}\r\n >\r\n <IconCloseOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n </>\r\n ) : (\r\n <>\r\n <Tooltip label={t('steer.moveUp')} side=\"bottom\" delayMs={500} disabled={i === 0}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('steer.moveUp')}\r\n disabled={i === 0}\r\n onClick={() => movePending(i, i - 1)}\r\n >\r\n <IconChevronUpOutline14 />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('steer.moveDown')} side=\"bottom\" delayMs={500} disabled={i === frozenPending.length - 1}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('steer.moveDown')}\r\n disabled={i === frozenPending.length - 1}\r\n onClick={() => movePending(i, i + 1)}\r\n >\r\n <IconChevronDownOutline14 />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('queue.edit')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.edit')}\r\n onClick={() => { setEditing({ id: `frozen:${i}`, text }) }}\r\n >\r\n <IconEditOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('queue.remove')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.remove')}\r\n onClick={() => removePendingAt(i)}\r\n >\r\n <IconTrashOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n {/* Planned insertion tier: freezing pauses consumption,\r\n it must not lock the tier planning of each row. */}\r\n <span className={css.plan} role=\"group\" aria-label={t('steer.later.aria')}>\r\n <Tooltip label={t('steer.now')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={`${css.tier} ${css.tierNow}`}\r\n aria-label={t('steer.now')}\r\n aria-pressed={entry.tier === 'force' || undefined}\r\n onClick={() => setTierAt(i, 'force')}\r\n >\r\n <span className={css.dot} aria-hidden />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('steer.next')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={`${css.tier} ${css.tierNext}`}\r\n aria-label={t('steer.next')}\r\n aria-pressed={entry.tier === 'safe_point' || undefined}\r\n onClick={() => setTierAt(i, 'safe_point')}\r\n >\r\n <span className={css.dot} aria-hidden />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('steer.later')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={`${css.tier} ${css.tierLater}`}\r\n aria-label={t('steer.later')}\r\n aria-pressed={entry.tier === 'queue' || undefined}\r\n onClick={() => setTierAt(i, 'queue')}\r\n >\r\n <span className={css.dot} aria-hidden />\r\n </button>\r\n </Tooltip>\r\n </span>\r\n </>\r\n )}\r\n </div>\r\n <span className={css.frozenMark}>{t('steer.frozenBadge')}</span>\r\n </li>\r\n )\r\n })}\r\n </ul>\r\n )}\r\n <ul id={listId} className={css.list} hidden={!listVisible}>\r\n {listVisible && queue.map((row, index) => (\r\n <li\r\n key={row.id}\r\n className={`${css.row} ${dragOver === index ? css.rowDragOver : ''}`}\r\n data-tier={badgeFor('queued') ?? undefined}\r\n data-editing={editing?.id === row.id ? '' : undefined}\r\n draggable={queueMutable && !reorderUnsupported && busy === null && !frozen}\r\n title={queueMutable && !reorderUnsupported && busy === null && !frozen ? t('steer.dragReorder') : undefined}\r\n onDragStart={(event) => {\r\n dragIndex.current = index\r\n event.dataTransfer.effectAllowed = 'move'\r\n // Some engines only start HTML5 drag once data is set.\r\n event.dataTransfer.setData('text/plain', String(index))\r\n }}\r\n onDragOver={(event) => {\r\n if (dragIndex.current === null) return\r\n event.preventDefault()\r\n setDragOver(index)\r\n }}\r\n onDrop={(event) => {\r\n event.preventDefault()\r\n const from = dragIndex.current\r\n dragIndex.current = null\r\n setDragOver(null)\r\n if (from !== null) void reorderTo(from, index)\r\n }}\r\n onDragEnd={() => {\r\n dragIndex.current = null\r\n setDragOver(null)\r\n }}\r\n >\r\n {queue.length === 1 && <span className={css.lead} aria-hidden><IconQueueOutline14 /></span>}\r\n <SteerBadge tier={badgeFor('queued')} t={t} />\r\n {editing?.id === row.id\r\n ? (\r\n <textarea\r\n ref={editorRef}\r\n autoFocus\r\n className={css.editor}\r\n aria-label={t('queue.edit')}\r\n rows={1}\r\n value={editing.text}\r\n onChange={(event) => { setEditing({ id: row.id, text: event.currentTarget.value }) }}\r\n onInput={(event) => { resizeEditor(event.currentTarget) }}\r\n onKeyDown={(event) => {\r\n if (event.key === 'Escape') {\r\n setEditing(null)\r\n return\r\n }\r\n // Plain Enter saves; Shift+Enter keeps editing (newline).\r\n if (event.key === 'Enter' && !event.shiftKey && !event.nativeEvent.isComposing) {\r\n event.preventDefault()\r\n void saveEdit()\r\n }\r\n }}\r\n />\r\n )\r\n : <span className={css.preview}>{row.preview}</span>}\r\n {queueMutable && <div className={css.actions}>\r\n {editing?.id === row.id\r\n ? (\r\n <>\r\n <Tooltip label={t('queue.save')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.save')}\r\n disabled={busy !== null || editing.text.trim() === ''}\r\n onClick={() => { void saveEdit() }}\r\n >\r\n <IconCheckOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('queue.cancelEdit')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.cancelEdit')}\r\n disabled={busy !== null}\r\n onClick={() => { setEditing(null) }}\r\n >\r\n <IconCloseOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n </>\r\n )\r\n : (\r\n <>\r\n <Tooltip label={t('steer.moveUp')} side=\"bottom\" delayMs={500} disabled={frozen || reorderUnsupported}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('steer.moveUp')}\r\n title={reorderUnsupported ? t('steer.reorder.unsupported') : undefined}\r\n disabled={busy !== null || frozen || reorderUnsupported}\r\n onClick={() => { void reorder(row.id, -1) }}\r\n >\r\n <IconChevronUpOutline14 />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('steer.moveDown')} side=\"bottom\" delayMs={500} disabled={frozen || reorderUnsupported}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('steer.moveDown')}\r\n title={reorderUnsupported ? t('steer.reorder.unsupported') : undefined}\r\n disabled={busy !== null || frozen || reorderUnsupported}\r\n onClick={() => { void reorder(row.id, 1) }}\r\n >\r\n <IconChevronDownOutline14 />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('steer.pullBack')} side=\"bottom\" delayMs={500} disabled={row.text === null || !composerEmpty}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('steer.pullBack')}\r\n title={row.text === null ? t('steer.pullBack.unsupported') : !composerEmpty ? t('steer.pullBack.composerBusy') : undefined}\r\n disabled={busy !== null || frozen || row.text === null || !composerEmpty}\r\n onClick={() => { void pullBackToComposer(row) }}\r\n >\r\n <IconRightUpOutline16 />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('queue.edit')} side=\"bottom\" delayMs={500} disabled={row.text === null}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.edit')}\r\n title={row.text === null ? t('queue.edit.unsupported') : undefined}\r\n disabled={busy !== null || row.text === null}\r\n onClick={() => {\r\n if (row.text !== null) setEditing({ id: row.id, text: row.text })\r\n }}\r\n >\r\n <IconEditOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('queue.remove')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.remove')}\r\n disabled={busy !== null}\r\n onClick={() => {\r\n void applyAction(row.id, { kind: 'remove' }, t('queue.removeFailed'))\r\n }}\r\n >\r\n <IconTrashOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n <span className={css.plan} role=\"group\" aria-label={t('steer.later.aria')}>\r\n <Tooltip label={t('steer.now')} side=\"bottom\" delayMs={500} disabled={planDisabled || row.text === null}>\r\n <button\r\n type=\"button\"\r\n className={`${css.tier} ${css.tierNow}`}\r\n aria-label={t('steer.now')}\r\n title={planDisabled ? t('steer.unavailable.running') : row.text === null ? t('steer.now.unsupported') : undefined}\r\n disabled={busy !== null || planDisabled || row.text === null}\r\n onClick={() => { void steerRow(row, 'now') }}\r\n >\r\n <span className={css.dot} aria-hidden />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('steer.next')} side=\"bottom\" delayMs={500} disabled={planDisabled}>\r\n <button\r\n type=\"button\"\r\n className={`${css.tier} ${css.tierNext}`}\r\n aria-label={t('steer.next')}\r\n title={planDisabled ? t('steer.unavailable.running') : undefined}\r\n disabled={busy !== null || planDisabled}\r\n onClick={() => { void steerRow(row, 'next') }}\r\n >\r\n <span className={css.dot} aria-hidden />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('steer.later')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={`${css.tier} ${css.tierLater}`}\r\n aria-label={t('steer.later')}\r\n aria-pressed\r\n disabled={busy !== null || clearing}\r\n onClick={() => {\r\n // Later is the default queue state; pressing it\r\n // keeps the row queued (no-op by design).\r\n }}\r\n >\r\n <span className={css.dot} aria-hidden />\r\n </button>\r\n </Tooltip>\r\n </span>\r\n </>\r\n )}\r\n </div>}\r\n </li>\r\n ))}\r\n </ul>\r\n {steering.length > 0 && (\r\n <ul className={css.steeringList} data-steering-list=\"\">\r\n {steering.map(row => (\r\n <li key={row.id} className={css.row} data-tier={badgeFor('steering') ?? undefined}>\r\n <span className={css.lead} aria-hidden><IconQueueOutline14 /></span>\r\n <SteerBadge tier={badgeFor('steering')} t={t} />\r\n <span className={css.preview}>{row.preview}</span>\r\n <div className={css.actions}>\r\n <Tooltip label={t('steer.revoke')} side=\"bottom\" delayMs={500} disabled={row.text === null}>\r\n <button\r\n type=\"button\"\r\n className={`${css.tier} ${css.tierLater}`}\r\n aria-label={t('steer.revoke')}\r\n title={row.text === null ? t('steer.revoke.unsupported') : undefined}\r\n disabled={busy !== null || row.text === null || frozen}\r\n onClick={() => { void revokeToLater(row) }}\r\n >\r\n <span className={css.dot} aria-hidden />\r\n </button>\r\n </Tooltip>\r\n </div>\r\n </li>\r\n ))}\r\n </ul>\r\n )}\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\n/** Badge label keys per tier. */\r\nconst BADGE_KEYS: Record<SteerTier, string> = {\r\n now: 'steer.badge.now',\r\n next: 'steer.badge.next',\r\n later: 'steer.badge.later',\r\n}\r\n\r\n/** Badge tint classes per tier (present at bundle time; typed through the css-modules declaration). */\r\nconst BADGE_CLASSES: Record<SteerTier, string> = {\r\n now: css.badgeNow as string,\r\n next: css.badgeNext as string,\r\n later: css.badgeLater as string,\r\n}\r\n\r\n/** One row's tier badge: colored dot + label; context rows render nothing. */\r\nfunction SteerBadge({ tier, t }: { tier: SteerTier | null; t: SteerQueueDockProps['t'] }) {\r\n if (tier === null) return null\r\n return (\r\n <span className={`${css.badge} ${BADGE_CLASSES[tier]}`} data-badge={tier}>\r\n <span className={css.dot} aria-hidden />\r\n <span className={css.badgeLabel}>{t(BADGE_KEYS[tier])}</span>\r\n </span>\r\n )\r\n}\r\n","/**\r\n * Session freeze/resume control, mounted in the composer's right tool row\r\n * (`conversation.input.right`) so it is reachable before anything queues.\r\n *\r\n * Peak-hour pause semantics: freeze does NOT interrupt the running turn —it\r\n * finishes naturally. The queued messages are detached (removed, preserved in\r\n * the shared store), so the driver finds no pending work and stops after the\r\n * current turn. Resume re-submits the preserved texts, waking the driver and\r\n * continuing the queue.\r\n */\r\nimport { useSyncExternalStore } from 'react'\r\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\r\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\r\nimport { freezeStore } from './freeze-store.ts'\r\nimport type { SteerQueueDockInjected } from './steer-queue-dock.tsx'\r\nimport css from './freeze-button.module.css'\r\n\r\n/** Full props of the composer-right entry: InputZone owner share + injected verbs + locale seat. */\r\nexport type FreezeButtonProps = PropsRuntime<'conversation.input.right'> & SteerQueueDockInjected & PropsLocale<'steer'>\r\n\r\n/**\r\n * Freeze/resume toggle for the peak-hour scenario.\r\n * @param props - slot props; the session snapshot drives the detach list.\r\n */\r\nexport function FreezeButton({ session, updateQueue, cancel, send, notify, t }: FreezeButtonProps) {\r\n const { frozen } = useSyncExternalStore(freezeStore.subscribe, freezeStore.getSnapshot)\r\n\r\n const freeze = async (): Promise<void> => {\r\n const queued = session.queue.filter(row => row.placement === 'queued')\r\n // Preserve plain-text copies; non-text rows cannot be re-sent and are\r\n // released by the freeze (documented limitation).\r\n const pending = queued.flatMap(row => row.text === null ? [] : [{ text: row.text, tier: 'queue' as const }])\r\n // Detach every queued row: the running turn finishes naturally, then the\r\n // driver finds no pending work and stops.\r\n await Promise.all(queued.map(row =>\r\n updateQueue(row.id, { kind: 'remove' }).catch(() => undefined),\r\n ))\r\n freezeStore.set({ frozen: true, pending })\r\n }\r\n\r\n const resume = async (): Promise<void> => {\r\n const pending = freezeStore.getSnapshot().pending\r\n freezeStore.set({ frozen: false, pending: [] })\r\n try {\r\n // Re-submit the preserved queue in FIFO order honoring each entry's\r\n // planned insertion tier: a force (red) entry interrupts the current\r\n // run first so it is consumed immediately; safe_point/later entries\r\n // flow through the wake-and-continue chain.\r\n for (const entry of pending) {\r\n if (entry.tier === 'force') await cancel()\r\n await send(entry.text)\r\n }\r\n } catch {\r\n notify('error', t('steer.resumeFailed'))\r\n }\r\n }\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n className={css.freeze}\r\n aria-label={frozen ? t('steer.resume') : t('steer.freeze')}\r\n aria-pressed={frozen || undefined}\r\n title={frozen ? t('steer.frozen') : undefined}\r\n onClick={() => {\r\n if (frozen) void resume()\r\n else void freeze()\r\n }}\r\n >\r\n <span className={css.label}>{frozen ? t('steer.resume') : t('steer.freeze')}</span>\r\n </button>\r\n )\r\n}\r\n","/**\r\n * Busy-Enter row hiding: shadows the official `settings.general.item` entry\r\n * `composer-enter` (same cell id, priority -1) so the lower priority wins and\r\n * the official \"繁忙时 Enter 键行为\" row never renders while this plugin is\r\n * mounted.\r\n *\r\n * The behavior itself is taken over by the plugin: plain Enter stays\r\n * queue-later (green), the planning dock owns yellow/red, and the plugin apply\r\n * pins `ui-conversation.busyEnter` to `queue` so no stale preference can\r\n * leak through the hidden row.\r\n */\r\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\r\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\r\n\r\n/** Full props of a settings-row entry (unused: the row renders nothing). */\r\nexport type HideEnterRowProps = PropsRuntime<'settings.general.item'> & PropsLocale<'steer'>\r\n\r\n/** Render nothing: the official busy-Enter row is hidden while mounted. */\r\nexport function HideEnterRow(_props: HideEnterRowProps): null {\r\n return null\r\n}\r\n","/**\r\n * dsh-input-traffic —browser half.\r\n *\r\n * The whole takeover lives here:\r\n * 1. registers the `steer` dictionaries;\r\n * 2. pins `ui-conversation.busyEnter` to `queue` (plain Enter = green later)\r\n * so the hidden official row cannot leak a stale queue/steer preference;\r\n * 3. shadows the official queue dock (`conversation.input.dock` cell id\r\n * `queue`, priority -1) with the three-tier planning strip;\r\n * 4. shadows the official busy-Enter settings row (`settings.general.item`\r\n * cell id `composer-enter`, priority -1) with a null render.\r\n *\r\n * All @deepseek-ai/* imports are type-only: collaboration happens through\r\n * cordis services and slot registration only (client bundle purity).\r\n */\r\nimport type { ClientContext, SessionId } from '@deepseek-ai/dsh-client-runtime/client'\r\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\r\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\r\nimport type { IConversation } from '@deepseek-ai/dsh-client-ui-conversation/client'\r\nimport { NS, en, zh } from './locales.ts'\r\nimport { SteerQueueDock } from './steer-queue-dock.tsx'\r\nimport type { SteerQueueDockInjected } from './steer-queue-dock.tsx'\r\nimport { FreezeButton } from './freeze-button.tsx'\r\nimport { HideEnterRow } from './hide-enter-row.tsx'\r\n\r\n/** Durable conversation settings namespace owned by ui-conversation. */\r\nconst CONVERSATION_SETTINGS_NAMESPACE = 'ui-conversation'\r\n\r\n/** Busy-Enter field inside that namespace; the plugin pins it to queue. */\r\nconst BUSY_ENTER_FIELD = 'busyEnter'\r\n\r\n/** Services required by the browser half. */\r\nexport const inject = ['slots', 'locale', 'sessions', 'conversation', 'settingsScope']\r\n\r\n/**\r\n * Client plugin body: dictionaries, busy-Enter pinning, and the two slot\r\n * shadowings.\r\n * @param ctx - client root context.\r\n */\r\nexport function apply(ctx: ClientContext): void {\r\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-input-traffic: dictionaries')\r\n\r\n // Take over the busy-Enter behavior: plain Enter stays queue-later while\r\n // the official row is hidden. Pinning here also repairs a persisted `steer`\r\n // preference that would otherwise keep working invisibly behind the hidden\r\n // row. Best-effort: a memory-mode host simply accepts it locally.\r\n const conversationSettings = ctx.settingsScope.bind<{ busyEnter: 'queue' | 'steer' }>({\r\n namespace: CONVERSATION_SETTINGS_NAMESPACE,\r\n })\r\n void conversationSettings.set(BUSY_ENTER_FIELD, 'queue')\r\n\r\n // Shadow the official queue dock with the three-tier planning strip.\r\n ctx.slots.inject('conversation.input.dock', () => ctx.slots.register({\r\n name: 'conversation.input.dock',\r\n id: 'queue',\r\n order: 20,\r\n priority: -1,\r\n locale: NS,\r\n inject: (sessionId: SessionId): SteerQueueDockInjected => {\r\n const actx = ctx.sessions.scope(sessionId)\r\n if (actx === undefined) throw new Error(`steer dock: session \"${sessionId}\" resolved no scope`)\r\n const conversation = actx.get<IConversation>('conversation')\r\n if (conversation === undefined) throw new Error('steer dock: conversation service unavailable')\r\n return {\r\n updateQueue: (itemId, action) => conversation.updateQueue(itemId, action),\r\n cancel: () => conversation.cancel(),\r\n send: (text) => conversation.send(text),\r\n setDraft: (text) => { conversation.input.for(actx).actions.setDraft(text) },\r\n notify: (level, text) => { conversation.input.for(actx).notify(level, text) },\r\n }\r\n },\r\n }, SteerQueueDock))\r\n\r\n // Composer-right freeze/resume control (reachable before anything queues).\r\n ctx.slots.inject('conversation.input.right', () => ctx.slots.register({\r\n name: 'conversation.input.right',\r\n id: 'steer-freeze',\r\n order: 30,\r\n locale: NS,\r\n inject: (sessionId: SessionId): SteerQueueDockInjected => {\r\n const actx = ctx.sessions.scope(sessionId)\r\n if (actx === undefined) throw new Error(`steer freeze: session \"${sessionId}\" resolved no scope`)\r\n const conversation = actx.get<IConversation>('conversation')\r\n if (conversation === undefined) throw new Error('steer freeze: conversation service unavailable')\r\n return {\r\n updateQueue: (itemId, action) => conversation.updateQueue(itemId, action),\r\n cancel: () => conversation.cancel(),\r\n send: (text) => conversation.send(text),\r\n setDraft: (text) => { conversation.input.for(actx).actions.setDraft(text) },\r\n notify: (level, text) => { conversation.input.for(actx).notify(level, text) },\r\n }\r\n },\r\n }, FreezeButton))\r\n\r\n // Hide the official busy-Enter settings row (null render wins the cell).\r\n ctx.slots.inject('settings.general.item', () => ctx.slots.register({\r\n name: 'settings.general.item',\r\n id: 'composer-enter',\r\n order: 20,\r\n priority: -1,\r\n locale: NS,\r\n }, HideEnterRow))\r\n}\r\n"],"mappings":";;;;;;;;;;;;EAGA,MAAa,KAAK;;EAGlB,MAAa,KAAK;GAChB,eAAe;GACf,cAAc;GACd,0BAA0B;GAC1B,cAAc;GACd,oBAAoB;GACpB,gBAAgB;GAChB,sBAAsB;GACtB,oBAAoB;GACpB,+BAA+B;GAC/B,kBAAkB;GAClB,aAAa;GACb,kBAAkB;GAClB,yBAAyB;GACzB,mBAAmB;GACnB,cAAc;GACd,mBAAmB;GACnB,oBAAoB;GACpB,eAAe;GACf,oBAAoB;GACpB,gBAAgB;GAChB,qBAAqB;GACrB,4BAA4B;GAC5B,sBAAsB;GACtB,gBAAgB;GAChB,kBAAkB;GAClB,6BAA6B;GAC7B,uBAAuB;GACvB,sBAAsB;GACtB,qBAAqB;GACrB,kBAAkB;GAClB,8BAA8B;GAC9B,+BAA+B;GAC/B,wBAAwB;GACxB,mBAAmB;GACnB,oBAAoB;GACpB,qBAAqB;GACrB,6BAA6B;GAC7B,eAAe;GACf,uBAAuB;GACvB,sBAAsB;GACtB,oBAAoB;GACpB,qBAAqB;GACrB,gBAAgB;GAChB,gBAAgB;GAChB,gBAAgB;GAChB,qBAAqB;GACrB,sBAAsB;GACtB,sBAAsB;EACxB;;EAGA,MAAa,KAAsC;GACjD,eAAe;GACf,cAAc;GACd,0BAA0B;GAC1B,cAAc;GACd,oBAAoB;GACpB,gBAAgB;GAChB,sBAAsB;GACtB,oBAAoB;GACpB,+BAA+B;GAC/B,kBAAkB;GAClB,aAAa;GACb,kBAAkB;GAClB,yBAAyB;GACzB,mBAAmB;GACnB,cAAc;GACd,mBAAmB;GACnB,oBAAoB;GACpB,eAAe;GACf,oBAAoB;GACpB,gBAAgB;GAChB,qBAAqB;GACrB,4BAA4B;GAC5B,sBAAsB;GACtB,gBAAgB;GAChB,kBAAkB;GAClB,6BAA6B;GAC7B,uBAAuB;GACvB,sBAAsB;GACtB,qBAAqB;GACrB,kBAAkB;GAClB,8BAA8B;GAC9B,+BAA+B;GAC/B,wBAAwB;GACxB,mBAAmB;GACnB,oBAAoB;GACpB,qBAAqB;GACrB,6BAA6B;GAC7B,eAAe;GACf,uBAAuB;GACvB,sBAAsB;GACtB,oBAAoB;GACpB,qBAAqB;GACrB,gBAAgB;GAChB,gBAAgB;GAChB,gBAAgB;GAChB,qBAAqB;GACrB,sBAAsB;GACtB,sBAAsB;EACxB;;;ECjFA,MAAM,4BAAY,IAAI,IAAgB;EACtC,IAAI,QAAqB;GAAE,QAAQ;GAAO,SAAS,CAAC;EAAE;;EAGtD,MAAa,cAAc;GACzB,cAA2B;IACzB,OAAO;GACT;GACA,UAAU,UAAkC;IAC1C,UAAU,IAAI,QAAQ;IACtB,aAAa;KAAE,UAAU,OAAO,QAAQ;IAAE;GAC5C;GACA,IAAI,MAAyB;IAC3B,QAAQ;IACR,KAAK,MAAM,YAAY,WAAW,SAAS;GAC7C;EACF;;EAeA,SAAgB,gBAAgB,OAAe,MAAoB;GACjE,MAAM,UAAU,CAAC,GAAG,MAAM,OAAO;GACjC,IAAI,QAAQ,KAAK,SAAS,QAAQ,QAAQ;GAC1C,MAAM,QAAQ,QAAQ;GACtB,IAAI,UAAU,KAAA,GAAW;GACzB,QAAQ,SAAS;IAAE,GAAG;IAAO;GAAK;GAClC,QAAQ;IAAE,GAAG;IAAO;GAAQ;GAC5B,KAAK;EACP;;EAGA,SAAgB,UAAU,OAAe,MAAwB;GAC/D,MAAM,UAAU,CAAC,GAAG,MAAM,OAAO;GACjC,IAAI,QAAQ,KAAK,SAAS,QAAQ,QAAQ;GAC1C,MAAM,QAAQ,QAAQ;GACtB,IAAI,UAAU,KAAA,GAAW;GACzB,QAAQ,SAAS;IAAE,GAAG;IAAO;GAAK;GAClC,QAAQ;IAAE,GAAG;IAAO;GAAQ;GAC5B,KAAK;EACP;;EAGA,SAAgB,gBAAgB,OAAqB;GACnD,IAAI,QAAQ,KAAK,SAAS,MAAM,QAAQ,QAAQ;GAChD,QAAQ;IAAE,GAAG;IAAO,SAAS,MAAM,QAAQ,QAAQ,GAAG,MAAM,MAAM,KAAK;GAAE;GACzE,KAAK;EACP;;EAGA,SAAgB,YAAY,MAAc,IAAkB;GAC1D,IAAI,SAAS,IAAI;GACjB,MAAM,UAAU,CAAC,GAAG,MAAM,OAAO;GACjC,MAAM,CAAC,SAAS,QAAQ,OAAO,MAAM,CAAC;GACtC,IAAI,UAAU,KAAA,GAAW;GACzB,QAAQ,OAAO,IAAI,GAAG,KAAK;GAC3B,QAAQ;IAAE,GAAG;IAAO;GAAQ;GAC5B,KAAK;EACP;EAEA,SAAS,OAAa;GACpB,KAAK,MAAM,YAAY,WAAW,SAAS;EAC7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ECrDA,MAAM,eAAe;;EAGrB,MAAM,eAAe;;;;;;;EAuCrB,SAAgB,SAAS,WAAgE;GACvF,IAAI,cAAc,YAAY,OAAO;GACrC,IAAI,cAAc,UAAU,OAAO;GACnC,OAAO;EACT;;;;;;;EAQA,SAAgB,aAAa,IAA+B;GAC1D,GAAG,MAAM,SAAS;GAClB,GAAG,MAAM,SAAS,GAAG,GAAG,aAAa;EACvC;;;;;EAMA,SAAgB,eAAe,EAAE,YAAY,OAAO,aAAa,QAAQ,MAAM,UAAU,QAAQ,KAA0B;GACzH,MAAM,QAAQ,YAAW,MAAK,EAAE,KAAK;GACrC,MAAM,SAAA,GAAQA,MAAAA,QAAAA,OAAc,MAAM,QAAO,QAAO,IAAI,cAAc,QAAQ,GAAG,CAAC,KAAK,CAAC;GACpF,MAAM,YAAA,GAAWA,MAAAA,QAAAA,OAAc,MAAM,QAAO,QAAO,IAAI,cAAc,UAAU,GAAG,CAAC,KAAK,CAAC;GACzF,MAAM,UAAU,YAAW,MAAK,EAAE,OAAO;GACzC,MAAM,eAAe,YAAW,MAAK,EAAE,aAAa,IAAI;GACxD,MAAM,CAAC,SAAS,eAAA,GAAcC,MAAAA,SAAAA,CAA8C,IAAI;GAChF,MAAM,CAAC,MAAM,YAAA,GAAWA,MAAAA,SAAAA,CAAwB,IAAI;GACpD,MAAM,CAAC,UAAU,gBAAA,GAAeA,MAAAA,SAAAA,CAAS,KAAK;GAG9C,MAAM,CAAC,cAAc,oBAAA,GAAmBA,MAAAA,SAAAA,CAAS,KAAK;GACtD,MAAM,gBAAA,GAAeC,MAAAA,OAAAA,CAA6C,IAAI;GAEtE,MAAM,aAAA,GAAYA,MAAAA,OAAAA,CAAsB,IAAI;GAC5C,MAAM,CAAC,UAAU,gBAAA,GAAeD,MAAAA,SAAAA,CAAwB,IAAI;GAE5D,MAAM,CAAC,WAAW,iBAAA,GAAgBA,MAAAA,SAAAA,OAAe;IAC/C,IAAI;KACF,MAAM,IAAI,aAAa,QAAQ,YAAY;KAC3C,OAAO,MAAM,OAAO,OAAO,MAAM;IACnC,QAAQ;KACN,OAAO;IACT;GACF,CAAC;GAMD,MAAM,EAAE,QAAQ,SAAS,mBAAA,GAAkBE,MAAAA,qBAAAA,CAAqB,YAAY,WAAW,YAAY,WAAW;GAC9G,MAAM,UAAA,GAASC,MAAAA,MAAAA,CAAM;GAErB,MAAM,aAAA,GAAYF,MAAAA,OAAAA,CAA4B,IAAI;GAElD,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,IAAI,MAAM,WAAW,KAAK,CAAC,WAAW,aAAa,IAAI;IAGvD,IAAI,YAAY,QAAQ,CAAC,QAAQ,GAAG,WAAW,SAAS,MAAM,CAAC,gBAAgB,CAAC,MAAM,MAAK,QAAO,IAAI,OAAO,QAAQ,EAAE,IAAI,WAAW,IAAI;GAC5I,GAAG;IAAC;IAAW;IAAS;IAAO;GAAY,CAAC;GAG5C,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,IAAI;KACF,aAAa,QAAQ,cAAc,YAAY,MAAM,GAAG;IAC1D,QAAQ,CAER;GACF,GAAG,CAAC,SAAS,CAAC;GACd,CAAA,GAAA,MAAA,UAAA,aAAsB;IACpB,IAAI,aAAa,YAAY,MAAM,aAAa,aAAa,OAAO;GACtE,GAAG,CAAC,CAAC;GAGL,MAAM,YAAY,SAAS;GAC3B,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,IAAI,cAAc,KAAA,GAAW;IAC7B,MAAM,KAAK,UAAU;IACrB,IAAI,OAAO,MAAM,aAAa,EAAE;GAClC,GAAG,CAAC,SAAS,CAAC;GAKd,IAAI,MAAM,WAAW,KAAK,SAAS,WAAW,KAAK,CAAC,WAAW,CAAC,QAAQ,OAAO;GAE/E,MAAM,oBAAoB,iBAAiB,YAAY,QAAQ,SAAS,QAAQ;GAChF,MAAM,WAAW,CAAC,aAAa;GAC/B,MAAM,cAAc,MAAM,WAAW,KAAK;GAC1C,MAAM,eAAe,CAAC,gBAAgB,CAAC,WAAW;GAClD,MAAM,iBAAiB,MAAM,WAAW,KAAK,SAAS,WAAW;GAGjE,MAAM,qBAAqB,MAAM,MAAK,QAAO,IAAI,SAAS,IAAI;GAK9D,MAAM,gBAAgB,MAAM,MAAM,KAAK,MAAM;GAE7C,MAAM,cAAc,OAClB,QACA,QACA,YACqB;IACrB,QAAQ,MAAM;IACd,IAAI;KACF,MAAM,YAAY,QAAQ,MAAM;KAChC,OAAO;IACT,QAAQ;KACN,OAAO,SAAS,OAAO;KACvB,OAAO;IACT,UAAU;KACR,SAAQ,YAAW,YAAY,SAAS,OAAO,OAAO;IACxD;GACF;GAEA,MAAM,WAAW,YAA2B;IAC1C,IAAI,YAAY,QAAQ,QAAQ,KAAK,KAAK,MAAM,IAAI;IACpD,MAAM,SAAS,QAAQ;IACvB,MAAM,OAAO,QAAQ;IACrB,QAAQ,MAAM;IACd,IAAI;KACF,MAAM,YAAY,QAAQ;MAAE,MAAM;MAAQ,SAAS,CAAC;OAAE,MAAM;OAAQ;MAAK,CAAC;KAAE,CAAC;KAC7E,WAAW,IAAI;IACjB,QAAQ;KAIN,IAAI,MAAM,MAAM,KAAK,MAAM,IAAI;MAC7B,SAAS,IAAI;MACb,WAAW,IAAI;MACf,OAAO,SAAS,EAAE,6BAA6B,CAAC;KAClD,OACE,OAAO,SAAS,EAAE,kBAAkB,CAAC;IAEzC,UAAU;KACR,SAAQ,YAAW,YAAY,SAAS,OAAO,OAAO;IACxD;GACF;GAEA,MAAM,WAAW,OAAO,KAA0C,SAAqD;IACrH,QAAQ,IAAI,EAAE;IACd,IAAI;KACF,IAAI,SAAS,OAAO;MAOlB,MAAM,OAAO;MACb,MAAM,YAAY,IAAI,IAAI,EAAE,MAAM,SAAS,CAAC;MAC5C,IAAI,IAAI,SAAS,MAAM,MAAM,KAAK,IAAI,IAAI;KAC5C,OACE,MAAM,YAAY,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAC;IAE/C,QAAQ;KACN,OAAO,SAAS,SAAS,QAAQ,EAAE,iBAAiB,IAAI,EAAE,kBAAkB,CAAC;IAC/E,UAAU;KACR,SAAQ,YAAW,YAAY,IAAI,KAAK,OAAO,OAAO;IACxD;GACF;;;;;;GAOA,MAAM,gBAAgB,OAAO,QAA4D;IACvF,IAAI,IAAI,SAAS,MAAM;IACvB,QAAQ,IAAI,EAAE;IACd,IAAI;KACF,MAAM,YAAY,IAAI,IAAI,EAAE,MAAM,SAAS,CAAC;KAC5C,MAAM,KAAK,IAAI,IAAI;IACrB,QAAQ;KACN,OAAO,SAAS,EAAE,oBAAoB,CAAC;IACzC,UAAU;KACR,SAAQ,YAAW,YAAY,IAAI,KAAK,OAAO,OAAO;IACxD;GACF;;;;;;;;;GAUA,MAAM,eAAe,OAAO,MAAsD,SAAwE;IACxJ,QAAQ,YAAY;IACpB,IAAI;KACF,KAAK,MAAM,OAAO,MAChB,IAAI;MACF,MAAM,YAAY,IAAI,IAAI,EAAE,MAAM,SAAS,CAAC;KAC9C,SAAS,OAAO;MACd,IAAI,iBAAiB,SAAS,MAAM,QAAQ,SAAS,sBAAsB,GAAG;OAC5E,OAAO,SAAS,EAAE,oBAAoB,CAAC;OACvC;MACF;MACA,MAAM;KACR;KAEF,KAAK,MAAM,OAAO,MAChB,IAAI,IAAI,SAAS,MAAM,MAAM,KAAK,IAAI,IAAI;IAE9C,QAAQ;KACN,OAAO,SAAS,EAAE,qBAAqB,CAAC;IAC1C,UAAU;KACR,QAAQ,IAAI;IACd;GACF;;;;GAKA,MAAM,UAAU,OAAO,OAAe,UAAiC;IACrE,MAAM,OAAO;IACb,MAAM,QAAQ,KAAK,WAAU,QAAO,IAAI,OAAO,KAAK;IACpD,MAAM,SAAS,QAAQ;IACvB,IAAI,QAAQ,KAAK,SAAS,KAAK,UAAU,KAAK,QAAQ;IACtD,MAAM,OAAO,CAAC,GAAG,IAAI;IACrB,MAAM,UAAU,KAAK;IACrB,KAAK,SAAS,KAAK;IACnB,KAAK,UAAU;IACf,IAAI,KAAK,MAAK,QAAO,IAAI,SAAS,IAAI,GAAG;KACvC,OAAO,SAAS,EAAE,2BAA2B,CAAC;KAC9C;IACF;IACA,MAAM,aAAa,MAAM,IAAI;GAC/B;;;;GAKA,MAAM,YAAY,OAAO,WAAmB,YAAmC;IAC7E,IAAI,cAAc,SAAS;IAC3B,MAAM,OAAO;IACb,IAAI,KAAK,eAAe,KAAA,KAAa,KAAK,aAAa,KAAA,GAAW;IAClE,MAAM,OAAO,CAAC,GAAG,IAAI;IACrB,MAAM,CAAC,SAAS,KAAK,OAAO,WAAW,CAAC;IACxC,IAAI,UAAU,KAAA,GAAW;IACzB,KAAK,OAAO,SAAS,GAAG,KAAK;IAC7B,IAAI,KAAK,MAAK,QAAO,IAAI,SAAS,IAAI,GAAG;KACvC,OAAO,SAAS,EAAE,2BAA2B,CAAC;KAC9C;IACF;IACA,MAAM,aAAa,MAAM,IAAI;GAC/B;;GAGA,MAAM,iBAAuB;IAC3B,IAAI,cAAc;KAChB,IAAI,aAAa,YAAY,MAAM,aAAa,aAAa,OAAO;KACpE,gBAAgB,KAAK;KACrB,SAAc;KACd;IACF;IACA,gBAAgB,IAAI;IACpB,IAAI,aAAa,YAAY,MAAM,aAAa,aAAa,OAAO;IACpE,aAAa,UAAU,iBAAiB,gBAAgB,KAAK,GAAG,GAAI;GACtE;;GAGA,MAAM,oBAA0B;IAC9B,IAAI,aAAa,YAAY,MAAM,aAAa,aAAa,OAAO;IACpE,gBAAgB,KAAK;GACvB;;GAGA,MAAM,iBAAiB,OAAO,UAAiC;IAC7D,IAAI,YAAY,MAAM;IACtB,MAAM,OAAO,QAAQ,KAAK,KAAK;IAC/B,IAAI,SAAS,IAAI;KACf,WAAW,IAAI;KACf;IACF;IACA,gBAAgB,OAAO,IAAI;IAC3B,WAAW,IAAI;GACjB;;;;;;GAOA,MAAM,qBAAqB,OAAO,QAA4D;IAC5F,IAAI,IAAI,SAAS,MAAM;IACvB,SAAS,IAAI,IAAI;IACjB,QAAQ,IAAI,EAAE;IACd,IAAI;KACF,MAAM,YAAY,IAAI,IAAI,EAAE,MAAM,SAAS,CAAC;IAC9C,QAAQ;KACN,OAAO,SAAS,EAAE,sBAAsB,CAAC;IAC3C,UAAU;KACR,SAAQ,YAAW,YAAY,IAAI,KAAK,OAAO,OAAO;IACxD;GACF;GAEA,MAAM,WAAW,YAA2B;IAC1C,YAAY,IAAI;IAIhB,MAAM,UAAU,CAAC,GAAG,OAAO,GAAG,QAAQ;IACtC,IAAI;KACF,MAAM,OAAO;KACb,MAAM,QAAQ,IAAI,QAAQ,KAAI,QAC5B,YAAY,IAAI,IAAI,EAAE,MAAM,SAAS,CAAC,CAAC,CAAC,YAAY,KAAA,CAAS,CAC/D,CAAC;IACH,QAAQ;KACN,OAAO,SAAS,EAAE,mBAAmB,CAAC;IACxC,UAAU;KACR,YAAY,KAAK;IACnB;GACF;GAEA,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,WAAWG,oCAAI;IAAM,mBAAgB;IACxC,UAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,WAAWA,oCAAI;KAApB,UAAA;MACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,oCAAI;OAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;QACE,MAAK;QACL,WAAWA,oCAAI;QACf,iBAAe;QACf,iBAAe;QACf,UAAU,MAAM,UAAU,KAAK;QAC/B,eAAe;SAAE,cAAa,UAAS,CAAC,KAAK;QAAE;QANjD,UAAA;SAQE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,oCAAI;UAAM,eAAA;UAAY,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,oBAAD,CAAqB,CAAA;SAAO,CAAA;SAClE,MAAM,SAAS,KACd,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWD,oCAAI;UAAQ,UAAA,EAAE,eAAe,EAAE,GAAG,MAAM,OAAO,CAAC;SAAQ,CAAA;SAE1E,MAAM,SAAS,KACd,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,oCAAI;UAAS,eAAA;UAC3B,UAAA,WAAW,iBAAA,GAAA,kBAAA,IAAA,CAACE,sCAAAA,0BAAD,CAA2B,CAAA,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,wBAAD,CAAyB,CAAA;SAChE,CAAA;QAEF;OACR,CAAA,GAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWH,oCAAI;QAApB,UAAA,CACG,gBACC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SACE,MAAK;SACL,WAAWA,oCAAI;SACf,cAAY,EAAE,oBAAoB;SAClC,UAAU,YAAY,SAAS,QAAQ;SACvC,SAAS;SAET,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,oCAAI;UAAa,UAAA,EAAE,oBAAoB;SAAQ,CAAA;QAC1D,CAAA,GAEV,iBAAA,GAAA,kBAAA,IAAA,CAACI,sCAAAA,SAAD;SAAS,OAAO,eAAe,EAAE,qBAAqB,IAAI,EAAE,aAAa;SAAG,MAAK;SAAM,SAAS;SAC9F,UAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;UACE,MAAK;UACL,WAAW,GAAGJ,oCAAI,MAAM,GAAG,eAAeA,oCAAI,eAAe;UAC7D,cAAY,eAAe,EAAE,qBAAqB,IAAI,EAAE,aAAa;UACrE,UAAU,YAAY,SAAS,QAAQ;UACvC,SAAS;UALX,UAAA,CAOE,iBAAA,GAAA,kBAAA,IAAA,CAACK,sCAAAA,oBAAD,EAAoB,MAAM,GAAK,CAAA,GAC/B,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;WAAM,WAAWL,oCAAI;WAAa,UAAA,eAAe,EAAE,qBAAqB,IAAI,EAAE,aAAa;UAAQ,CAAA,CAC7F;;QACD,CAAA,CACN;OACF,CAAA,CAAA;;MACJ,UACC,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAWA,oCAAI;OAAc,MAAK;OACpC,UAAA,EAAE,cAAc;MACd,CAAA;MAMN,UAAU,cAAc,SAAS,KAChC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;OAAI,WAAWA,oCAAI;OAAY,eAAY;OACxC,UAAA,cAAc,KAAK,OAAO,MAAM;QAC/B,MAAM,gBAAgB,SAAS,OAAO,UAAU;QAChD,MAAM,OAAO,MAAM;QACnB,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;SAEE,WAAW,GAAGA,oCAAI,UAAU,GAAG,aAAa,KAAK,SAASA,oCAAI,cAAc;SAC5E,aAAW,MAAM,SAAS,UAAU,QAAQ,MAAM,SAAS,eAAe,SAAS;SACnF,gBAAc,gBAAgB,KAAK,KAAA;SACnC,WAAW,CAAC;SACZ,OAAO,CAAC,gBAAgB,EAAE,mBAAmB,IAAI,KAAA;SACjD,cAAc,UAAU;UACtB,IAAI,eAAe;UACnB,UAAU,UAAU;UACpB,MAAM,aAAa,gBAAgB;UAEnC,MAAM,aAAa,QAAQ,cAAc,OAAO,CAAC,CAAC;SACpD;SACA,aAAa,UAAU;UACrB,IAAI,UAAU,YAAY,MAAM;UAChC,MAAM,eAAe;UACrB,YAAY,CAAC;SACf;SACA,SAAS,UAAU;UACjB,MAAM,eAAe;UACrB,MAAM,OAAO,UAAU;UACvB,UAAU,UAAU;UACpB,YAAY,IAAI;UAChB,IAAI,SAAS,MAAM,YAAY,MAAM,CAAC;SACxC;SACA,iBAAiB;UACf,UAAU,UAAU;UACpB,YAAY,IAAI;SAClB;SA7BF,UAAA;UA+BE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;WAAM,WAAWA,oCAAI;WAAM,eAAA;WAAY,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,oBAAD,CAAqB,CAAA;UAAO,CAAA;UACnE,iBAAA,GAAA,kBAAA,IAAA,CAAC,YAAD;WAAY,MAAM,MAAM,SAAS,UAAU,QAAQ,MAAM,SAAS,eAAe,SAAS;WAAY;UAAI,CAAA;UACzG,gBAEG,iBAAA,GAAA,kBAAA,IAAA,CAAC,YAAD;WACE,KAAK;WACL,WAAA;WACA,WAAWD,oCAAI;WACf,cAAY,EAAE,YAAY;WAC1B,MAAM;WACN,OAAO,SAAS,QAAQ;WACxB,WAAW,UAAU;YAAE,WAAW;aAAE,IAAI,UAAU;aAAK,MAAM,MAAM,cAAc;YAAM,CAAC;WAAE;WAC1F,UAAU,UAAU;YAAE,aAAa,MAAM,aAAa;WAAE;WACxD,YAAY,UAAU;YACpB,IAAI,MAAM,QAAQ,UAAU;aAC1B,WAAW,IAAI;aACf;YACF;YACA,IAAI,MAAM,QAAQ,WAAW,CAAC,MAAM,YAAY,CAAC,MAAM,YAAY,aAAa;aAC9E,MAAM,eAAe;aACrB,eAAoB,CAAC;YACvB;WACF;UACD,CAAA,IAED,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;WAAM,WAAWA,oCAAI;WAAU,UAAA;UAAW,CAAA;UAC9C,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;WAAK,WAAWA,oCAAI;WACjB,UAAA,gBACC,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAACI,sCAAAA,SAAD;YAAS,OAAO,EAAE,YAAY;YAAG,MAAK;YAAS,SAAS;YACtD,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;aACE,MAAK;aACL,WAAWJ,oCAAI;aACf,cAAY,EAAE,YAAY;aAC1B,UAAU,YAAY,QAAQ,QAAQ,KAAK,KAAK,MAAM;aACtD,eAAe;cAAE,eAAoB,CAAC;aAAE;aAExC,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACM,sCAAAA,oBAAD,EAAoB,MAAM,GAAK,CAAA;YACzB,CAAA;WACD,CAAA,GACT,iBAAA,GAAA,kBAAA,IAAA,CAACF,sCAAAA,SAAD;YAAS,OAAO,EAAE,kBAAkB;YAAG,MAAK;YAAS,SAAS;YAC5D,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;aACE,MAAK;aACL,WAAWJ,oCAAI;aACf,cAAY,EAAE,kBAAkB;aAChC,eAAe;cAAE,WAAW,IAAI;aAAE;aAElC,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACO,sCAAAA,oBAAD,EAAoB,MAAM,GAAK,CAAA;YACzB,CAAA;WACD,CAAA,CACT,EAAA,CAAA,IAEF,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;YACE,iBAAA,GAAA,kBAAA,IAAA,CAACH,sCAAAA,SAAD;aAAS,OAAO,EAAE,cAAc;aAAG,MAAK;aAAS,SAAS;aAAK,UAAU,MAAM;aAC7E,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;cACE,MAAK;cACL,WAAWJ,oCAAI;cACf,cAAY,EAAE,cAAc;cAC5B,UAAU,MAAM;cAChB,eAAe,YAAY,GAAG,IAAI,CAAC;cAEnC,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACG,sCAAAA,wBAAD,CAAyB,CAAA;aACnB,CAAA;YACD,CAAA;YACT,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,SAAD;aAAS,OAAO,EAAE,gBAAgB;aAAG,MAAK;aAAS,SAAS;aAAK,UAAU,MAAM,cAAc,SAAS;aACtG,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;cACE,MAAK;cACL,WAAWJ,oCAAI;cACf,cAAY,EAAE,gBAAgB;cAC9B,UAAU,MAAM,cAAc,SAAS;cACvC,eAAe,YAAY,GAAG,IAAI,CAAC;cAEnC,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACE,sCAAAA,0BAAD,CAA2B,CAAA;aACrB,CAAA;YACD,CAAA;YACT,iBAAA,GAAA,kBAAA,IAAA,CAACE,sCAAAA,SAAD;aAAS,OAAO,EAAE,YAAY;aAAG,MAAK;aAAS,SAAS;aACtD,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;cACE,MAAK;cACL,WAAWJ,oCAAI;cACf,cAAY,EAAE,YAAY;cAC1B,eAAe;eAAE,WAAW;gBAAE,IAAI,UAAU;gBAAK;eAAK,CAAC;cAAE;cAEzD,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACQ,sCAAAA,mBAAD,EAAmB,MAAM,GAAK,CAAA;aACxB,CAAA;YACD,CAAA;YACT,iBAAA,GAAA,kBAAA,IAAA,CAACJ,sCAAAA,SAAD;aAAS,OAAO,EAAE,cAAc;aAAG,MAAK;aAAS,SAAS;aACxD,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;cACE,MAAK;cACL,WAAWJ,oCAAI;cACf,cAAY,EAAE,cAAc;cAC5B,eAAe,gBAAgB,CAAC;cAEhC,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACK,sCAAAA,oBAAD,EAAoB,MAAM,GAAK,CAAA;aACzB,CAAA;YACD,CAAA;YAGT,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;aAAM,WAAWL,oCAAI;aAAM,MAAK;aAAQ,cAAY,EAAE,kBAAkB;aAAxE,UAAA;cACE,iBAAA,GAAA,kBAAA,IAAA,CAACI,sCAAAA,SAAD;eAAS,OAAO,EAAE,WAAW;eAAG,MAAK;eAAS,SAAS;eACrD,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;gBACE,MAAK;gBACL,WAAW,GAAGJ,oCAAI,KAAK,GAAGA,oCAAI;gBAC9B,cAAY,EAAE,WAAW;gBACzB,gBAAc,MAAM,SAAS,WAAW,KAAA;gBACxC,eAAe,UAAU,GAAG,OAAO;gBAEnC,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;iBAAM,WAAWA,oCAAI;iBAAK,eAAA;gBAAa,CAAA;eACjC,CAAA;cACD,CAAA;cACT,iBAAA,GAAA,kBAAA,IAAA,CAACI,sCAAAA,SAAD;eAAS,OAAO,EAAE,YAAY;eAAG,MAAK;eAAS,SAAS;eACtD,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;gBACE,MAAK;gBACL,WAAW,GAAGJ,oCAAI,KAAK,GAAGA,oCAAI;gBAC9B,cAAY,EAAE,YAAY;gBAC1B,gBAAc,MAAM,SAAS,gBAAgB,KAAA;gBAC7C,eAAe,UAAU,GAAG,YAAY;gBAExC,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;iBAAM,WAAWA,oCAAI;iBAAK,eAAA;gBAAa,CAAA;eACjC,CAAA;cACD,CAAA;cACT,iBAAA,GAAA,kBAAA,IAAA,CAACI,sCAAAA,SAAD;eAAS,OAAO,EAAE,aAAa;eAAG,MAAK;eAAS,SAAS;eACvD,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;gBACE,MAAK;gBACL,WAAW,GAAGJ,oCAAI,KAAK,GAAGA,oCAAI;gBAC9B,cAAY,EAAE,aAAa;gBAC3B,gBAAc,MAAM,SAAS,WAAW,KAAA;gBACxC,eAAe,UAAU,GAAG,OAAO;gBAEnC,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;iBAAM,WAAWA,oCAAI;iBAAK,eAAA;gBAAa,CAAA;eACjC,CAAA;cACD,CAAA;aACL;;WACN,EAAA,CAAA;UAED,CAAA;UACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;WAAM,WAAWA,oCAAI;WAAa,UAAA,EAAE,mBAAmB;UAAQ,CAAA;SAC7D;QAtKG,GAAA,CAsKH;OAER,CAAC;MACC,CAAA;MAEN,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;OAAI,IAAI;OAAQ,WAAWA,oCAAI;OAAM,QAAQ,CAAC;OAC3C,UAAA,eAAe,MAAM,KAAK,KAAK,UAC9B,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;QAEE,WAAW,GAAGA,oCAAI,IAAI,GAAG,aAAa,QAAQA,oCAAI,cAAc;QAChE,aAAW,SAAS,QAAQ,KAAK,KAAA;QACjC,gBAAc,SAAS,OAAO,IAAI,KAAK,KAAK,KAAA;QAC5C,WAAW,gBAAgB,CAAC,sBAAsB,SAAS,QAAQ,CAAC;QACpE,OAAO,gBAAgB,CAAC,sBAAsB,SAAS,QAAQ,CAAC,SAAS,EAAE,mBAAmB,IAAI,KAAA;QAClG,cAAc,UAAU;SACtB,UAAU,UAAU;SACpB,MAAM,aAAa,gBAAgB;SAEnC,MAAM,aAAa,QAAQ,cAAc,OAAO,KAAK,CAAC;QACxD;QACA,aAAa,UAAU;SACrB,IAAI,UAAU,YAAY,MAAM;SAChC,MAAM,eAAe;SACrB,YAAY,KAAK;QACnB;QACA,SAAS,UAAU;SACjB,MAAM,eAAe;SACrB,MAAM,OAAO,UAAU;SACvB,UAAU,UAAU;SACpB,YAAY,IAAI;SAChB,IAAI,SAAS,MAAM,UAAe,MAAM,KAAK;QAC/C;QACA,iBAAiB;SACf,UAAU,UAAU;SACpB,YAAY,IAAI;QAClB;QA5BF,UAAA;SA8BG,MAAM,WAAW,KAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,oCAAI;UAAM,eAAA;UAAY,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,oBAAD,CAAqB,CAAA;SAAO,CAAA;SAC1F,iBAAA,GAAA,kBAAA,IAAA,CAAC,YAAD;UAAY,MAAM,SAAS,QAAQ;UAAM;SAAI,CAAA;SAC5C,SAAS,OAAO,IAAI,KAEjB,iBAAA,GAAA,kBAAA,IAAA,CAAC,YAAD;UACE,KAAK;UACL,WAAA;UACA,WAAWD,oCAAI;UACf,cAAY,EAAE,YAAY;UAC1B,MAAM;UACN,OAAO,QAAQ;UACf,WAAW,UAAU;WAAE,WAAW;YAAE,IAAI,IAAI;YAAI,MAAM,MAAM,cAAc;WAAM,CAAC;UAAE;UACnF,UAAU,UAAU;WAAE,aAAa,MAAM,aAAa;UAAE;UACxD,YAAY,UAAU;WACpB,IAAI,MAAM,QAAQ,UAAU;YAC1B,WAAW,IAAI;YACf;WACF;WAEA,IAAI,MAAM,QAAQ,WAAW,CAAC,MAAM,YAAY,CAAC,MAAM,YAAY,aAAa;YAC9E,MAAM,eAAe;YACrB,SAAc;WAChB;UACF;SACD,CAAA,IAED,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,oCAAI;UAAU,UAAA,IAAI;SAAc,CAAA;SACpD,gBAAgB,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;UAAK,WAAWA,oCAAI;UAClC,UAAA,SAAS,OAAO,IAAI,KAEjB,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAACI,sCAAAA,SAAD;WAAS,OAAO,EAAE,YAAY;WAAG,MAAK;WAAS,SAAS;WACtD,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;YACE,MAAK;YACL,WAAWJ,oCAAI;YACf,cAAY,EAAE,YAAY;YAC1B,UAAU,SAAS,QAAQ,QAAQ,KAAK,KAAK,MAAM;YACnD,eAAe;aAAE,SAAc;YAAE;YAEjC,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACM,sCAAAA,oBAAD,EAAoB,MAAM,GAAK,CAAA;WACzB,CAAA;UACD,CAAA,GACT,iBAAA,GAAA,kBAAA,IAAA,CAACF,sCAAAA,SAAD;WAAS,OAAO,EAAE,kBAAkB;WAAG,MAAK;WAAS,SAAS;WAC5D,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;YACE,MAAK;YACL,WAAWJ,oCAAI;YACf,cAAY,EAAE,kBAAkB;YAChC,UAAU,SAAS;YACnB,eAAe;aAAE,WAAW,IAAI;YAAE;YAElC,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACO,sCAAAA,oBAAD,EAAoB,MAAM,GAAK,CAAA;WACzB,CAAA;UACD,CAAA,CACT,EAAA,CAAA,IAGF,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;WACE,iBAAA,GAAA,kBAAA,IAAA,CAACH,sCAAAA,SAAD;YAAS,OAAO,EAAE,cAAc;YAAG,MAAK;YAAS,SAAS;YAAK,UAAU,UAAU;YACjF,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;aACE,MAAK;aACL,WAAWJ,oCAAI;aACf,cAAY,EAAE,cAAc;aAC5B,OAAO,qBAAqB,EAAE,2BAA2B,IAAI,KAAA;aAC7D,UAAU,SAAS,QAAQ,UAAU;aACrC,eAAe;cAAE,QAAa,IAAI,IAAI,EAAE;aAAE;aAE1C,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACG,sCAAAA,wBAAD,CAAyB,CAAA;YACnB,CAAA;WACD,CAAA;WACT,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,SAAD;YAAS,OAAO,EAAE,gBAAgB;YAAG,MAAK;YAAS,SAAS;YAAK,UAAU,UAAU;YACnF,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;aACE,MAAK;aACL,WAAWJ,oCAAI;aACf,cAAY,EAAE,gBAAgB;aAC9B,OAAO,qBAAqB,EAAE,2BAA2B,IAAI,KAAA;aAC7D,UAAU,SAAS,QAAQ,UAAU;aACrC,eAAe;cAAE,QAAa,IAAI,IAAI,CAAC;aAAE;aAEzC,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACE,sCAAAA,0BAAD,CAA2B,CAAA;YACrB,CAAA;WACD,CAAA;WACT,iBAAA,GAAA,kBAAA,IAAA,CAACE,sCAAAA,SAAD;YAAS,OAAO,EAAE,gBAAgB;YAAG,MAAK;YAAS,SAAS;YAAK,UAAU,IAAI,SAAS,QAAQ,CAAC;YAC/F,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;aACE,MAAK;aACL,WAAWJ,oCAAI;aACf,cAAY,EAAE,gBAAgB;aAC9B,OAAO,IAAI,SAAS,OAAO,EAAE,4BAA4B,IAAI,CAAC,gBAAgB,EAAE,6BAA6B,IAAI,KAAA;aACjH,UAAU,SAAS,QAAQ,UAAU,IAAI,SAAS,QAAQ,CAAC;aAC3D,eAAe;cAAE,mBAAwB,GAAG;aAAE;aAE9C,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACS,sCAAAA,sBAAD,CAAuB,CAAA;YACjB,CAAA;WACD,CAAA;WACT,iBAAA,GAAA,kBAAA,IAAA,CAACL,sCAAAA,SAAD;YAAS,OAAO,EAAE,YAAY;YAAG,MAAK;YAAS,SAAS;YAAK,UAAU,IAAI,SAAS;YAClF,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;aACE,MAAK;aACL,WAAWJ,oCAAI;aACf,cAAY,EAAE,YAAY;aAC1B,OAAO,IAAI,SAAS,OAAO,EAAE,wBAAwB,IAAI,KAAA;aACzD,UAAU,SAAS,QAAQ,IAAI,SAAS;aACxC,eAAe;cACb,IAAI,IAAI,SAAS,MAAM,WAAW;eAAE,IAAI,IAAI;eAAI,MAAM,IAAI;cAAK,CAAC;aAClE;aAEA,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACQ,sCAAAA,mBAAD,EAAmB,MAAM,GAAK,CAAA;YACxB,CAAA;WACD,CAAA;WACT,iBAAA,GAAA,kBAAA,IAAA,CAACJ,sCAAAA,SAAD;YAAS,OAAO,EAAE,cAAc;YAAG,MAAK;YAAS,SAAS;YACxD,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;aACE,MAAK;aACL,WAAWJ,oCAAI;aACf,cAAY,EAAE,cAAc;aAC5B,UAAU,SAAS;aACnB,eAAe;cACb,YAAiB,IAAI,IAAI,EAAE,MAAM,SAAS,GAAG,EAAE,oBAAoB,CAAC;aACtE;aAEA,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACK,sCAAAA,oBAAD,EAAoB,MAAM,GAAK,CAAA;YACzB,CAAA;WACD,CAAA;WACT,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;YAAM,WAAWL,oCAAI;YAAM,MAAK;YAAQ,cAAY,EAAE,kBAAkB;YAAxE,UAAA;aACE,iBAAA,GAAA,kBAAA,IAAA,CAACI,sCAAAA,SAAD;cAAS,OAAO,EAAE,WAAW;cAAG,MAAK;cAAS,SAAS;cAAK,UAAU,gBAAgB,IAAI,SAAS;cACjG,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;eACE,MAAK;eACL,WAAW,GAAGJ,oCAAI,KAAK,GAAGA,oCAAI;eAC9B,cAAY,EAAE,WAAW;eACzB,OAAO,eAAe,EAAE,2BAA2B,IAAI,IAAI,SAAS,OAAO,EAAE,uBAAuB,IAAI,KAAA;eACxG,UAAU,SAAS,QAAQ,gBAAgB,IAAI,SAAS;eACxD,eAAe;gBAAE,SAAc,KAAK,KAAK;eAAE;eAE3C,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;gBAAM,WAAWA,oCAAI;gBAAK,eAAA;eAAa,CAAA;cACjC,CAAA;aACD,CAAA;aACT,iBAAA,GAAA,kBAAA,IAAA,CAACI,sCAAAA,SAAD;cAAS,OAAO,EAAE,YAAY;cAAG,MAAK;cAAS,SAAS;cAAK,UAAU;cACrE,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;eACE,MAAK;eACL,WAAW,GAAGJ,oCAAI,KAAK,GAAGA,oCAAI;eAC9B,cAAY,EAAE,YAAY;eAC1B,OAAO,eAAe,EAAE,2BAA2B,IAAI,KAAA;eACvD,UAAU,SAAS,QAAQ;eAC3B,eAAe;gBAAE,SAAc,KAAK,MAAM;eAAE;eAE5C,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;gBAAM,WAAWA,oCAAI;gBAAK,eAAA;eAAa,CAAA;cACjC,CAAA;aACD,CAAA;aACT,iBAAA,GAAA,kBAAA,IAAA,CAACI,sCAAAA,SAAD;cAAS,OAAO,EAAE,aAAa;cAAG,MAAK;cAAS,SAAS;cACvD,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;eACE,MAAK;eACL,WAAW,GAAGJ,oCAAI,KAAK,GAAGA,oCAAI;eAC9B,cAAY,EAAE,aAAa;eAC3B,gBAAA;eACA,UAAU,SAAS,QAAQ;eAC3B,eAAe,CAGf;eAEA,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;gBAAM,WAAWA,oCAAI;gBAAK,eAAA;eAAa,CAAA;cACjC,CAAA;aACD,CAAA;YACL;;UACN,EAAA,CAAA;SAEH,CAAA;QACH;OAjMG,GAAA,IAAI,EAiMP,CACL;MACC,CAAA;MACH,SAAS,SAAS,KACjB,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;OAAI,WAAWA,oCAAI;OAAc,sBAAmB;OACjD,UAAA,SAAS,KAAI,QACZ,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;QAAiB,WAAWA,oCAAI;QAAK,aAAW,SAAS,UAAU,KAAK,KAAA;QAAxE,UAAA;SACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,oCAAI;UAAM,eAAA;UAAY,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,oBAAD,CAAqB,CAAA;SAAO,CAAA;SACnE,iBAAA,GAAA,kBAAA,IAAA,CAAC,YAAD;UAAY,MAAM,SAAS,UAAU;UAAM;SAAI,CAAA;SAC/C,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWD,oCAAI;UAAU,UAAA,IAAI;SAAc,CAAA;SACjD,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;UAAK,WAAWA,oCAAI;UAClB,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACI,sCAAAA,SAAD;WAAS,OAAO,EAAE,cAAc;WAAG,MAAK;WAAS,SAAS;WAAK,UAAU,IAAI,SAAS;WACpF,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;YACE,MAAK;YACL,WAAW,GAAGJ,oCAAI,KAAK,GAAGA,oCAAI;YAC9B,cAAY,EAAE,cAAc;YAC5B,OAAO,IAAI,SAAS,OAAO,EAAE,0BAA0B,IAAI,KAAA;YAC3D,UAAU,SAAS,QAAQ,IAAI,SAAS,QAAQ;YAChD,eAAe;aAAE,cAAmB,GAAG;YAAE;YAEzC,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;aAAM,WAAWA,oCAAI;aAAK,eAAA;YAAa,CAAA;WACjC,CAAA;UACD,CAAA;SACN,CAAA;QACH;OAlBK,GAAA,IAAI,EAkBT,CACL;MACC,CAAA;KAEH;;GACF,CAAA;EAET;;EAGA,MAAM,aAAwC;GAC5C,KAAK;GACL,MAAM;GACN,OAAO;EACT;;EAGA,MAAM,gBAA2C;GAC/C,KAAKA,oCAAI;GACT,MAAMA,oCAAI;GACV,OAAOA,oCAAI;EACb;;EAGA,SAAS,WAAW,EAAE,MAAM,KAA8D;GACxF,IAAI,SAAS,MAAM,OAAO;GAC1B,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;IAAM,WAAW,GAAGA,oCAAI,MAAM,GAAG,cAAc;IAAS,cAAY;IAApE,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAWA,oCAAI;KAAK,eAAA;IAAa,CAAA,GACvC,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAWA,oCAAI;KAAa,UAAA,EAAE,WAAW,KAAK;IAAQ,CAAA,CACxD;;EAEV;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ECt2BA,SAAgB,aAAa,EAAE,SAAS,aAAa,QAAQ,MAAM,QAAQ,KAAwB;GACjG,MAAM,EAAE,YAAA,GAAWU,MAAAA,qBAAAA,CAAqB,YAAY,WAAW,YAAY,WAAW;GAEtF,MAAM,SAAS,YAA2B;IACxC,MAAM,SAAS,QAAQ,MAAM,QAAO,QAAO,IAAI,cAAc,QAAQ;IAGrE,MAAM,UAAU,OAAO,SAAQ,QAAO,IAAI,SAAS,OAAO,CAAC,IAAI,CAAC;KAAE,MAAM,IAAI;KAAM,MAAM;IAAiB,CAAC,CAAC;IAG3G,MAAM,QAAQ,IAAI,OAAO,KAAI,QAC3B,YAAY,IAAI,IAAI,EAAE,MAAM,SAAS,CAAC,CAAC,CAAC,YAAY,KAAA,CAAS,CAC/D,CAAC;IACD,YAAY,IAAI;KAAE,QAAQ;KAAM;IAAQ,CAAC;GAC3C;GAEA,MAAM,SAAS,YAA2B;IACxC,MAAM,UAAU,YAAY,YAAY,CAAC,CAAC;IAC1C,YAAY,IAAI;KAAE,QAAQ;KAAO,SAAS,CAAC;IAAE,CAAC;IAC9C,IAAI;KAKF,KAAK,MAAM,SAAS,SAAS;MAC3B,IAAI,MAAM,SAAS,SAAS,MAAM,OAAO;MACzC,MAAM,KAAK,MAAM,IAAI;KACvB;IACF,QAAQ;KACN,OAAO,SAAS,EAAE,oBAAoB,CAAC;IACzC;GACF;GAEA,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;IACE,MAAK;IACL,WAAWC,iCAAI;IACf,cAAY,SAAS,EAAE,cAAc,IAAI,EAAE,cAAc;IACzD,gBAAc,UAAU,KAAA;IACxB,OAAO,SAAS,EAAE,cAAc,IAAI,KAAA;IACpC,eAAe;KACb,IAAI,QAAQ,OAAY;UACnB,OAAY;IACnB;IAEA,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAWA,iCAAI;KAAQ,UAAA,SAAS,EAAE,cAAc,IAAI,EAAE,cAAc;IAAQ,CAAA;GAC5E,CAAA;EAEZ;;;;ECtDA,SAAgB,aAAa,QAAiC;GAC5D,OAAO;EACT;;;;ECMA,MAAM,kCAAkC;;EAGxC,MAAM,mBAAmB;;EAGzB,MAAa,SAAS;GAAC;GAAS;GAAU;GAAY;GAAgB;EAAe;;;;;;EAOrF,SAAgB,MAAM,KAA0B;GAC9C,IAAI,aAAa,IAAI,OAAO,SAAS,IAAI;IAAE;IAAI;GAAG,CAAC,GAAG,iCAAiC;GASvF,IAHiC,cAAc,KAAuC,EACpF,WAAW,gCACb,CACwB,CAAC,CAAC,IAAI,kBAAkB,OAAO;GAGvD,IAAI,MAAM,OAAO,iCAAiC,IAAI,MAAM,SAAS;IACnE,MAAM;IACN,IAAI;IACJ,OAAO;IACP,UAAU;IACV,QAAQ;IACR,SAAS,cAAiD;KACxD,MAAM,OAAO,IAAI,SAAS,MAAM,SAAS;KACzC,IAAI,SAAS,KAAA,GAAW,MAAM,IAAI,MAAM,wBAAwB,UAAU,oBAAoB;KAC9F,MAAM,eAAe,KAAK,IAAmB,cAAc;KAC3D,IAAI,iBAAiB,KAAA,GAAW,MAAM,IAAI,MAAM,8CAA8C;KAC9F,OAAO;MACL,cAAc,QAAQ,WAAW,aAAa,YAAY,QAAQ,MAAM;MACxE,cAAc,aAAa,OAAO;MAClC,OAAO,SAAS,aAAa,KAAK,IAAI;MACtC,WAAW,SAAS;OAAE,aAAa,MAAM,IAAI,IAAI,CAAC,CAAC,QAAQ,SAAS,IAAI;MAAE;MAC1E,SAAS,OAAO,SAAS;OAAE,aAAa,MAAM,IAAI,IAAI,CAAC,CAAC,OAAO,OAAO,IAAI;MAAE;KAC9E;IACF;GACF,GAAG,cAAc,CAAC;GAGlB,IAAI,MAAM,OAAO,kCAAkC,IAAI,MAAM,SAAS;IACpE,MAAM;IACN,IAAI;IACJ,OAAO;IACP,QAAQ;IACR,SAAS,cAAiD;KACxD,MAAM,OAAO,IAAI,SAAS,MAAM,SAAS;KACzC,IAAI,SAAS,KAAA,GAAW,MAAM,IAAI,MAAM,0BAA0B,UAAU,oBAAoB;KAChG,MAAM,eAAe,KAAK,IAAmB,cAAc;KAC3D,IAAI,iBAAiB,KAAA,GAAW,MAAM,IAAI,MAAM,gDAAgD;KAChG,OAAO;MACL,cAAc,QAAQ,WAAW,aAAa,YAAY,QAAQ,MAAM;MACxE,cAAc,aAAa,OAAO;MAClC,OAAO,SAAS,aAAa,KAAK,IAAI;MACtC,WAAW,SAAS;OAAE,aAAa,MAAM,IAAI,IAAI,CAAC,CAAC,QAAQ,SAAS,IAAI;MAAE;MAC1E,SAAS,OAAO,SAAS;OAAE,aAAa,MAAM,IAAI,IAAI,CAAC,CAAC,OAAO,OAAO,IAAI;MAAE;KAC9E;IACF;GACF,GAAG,YAAY,CAAC;GAGhB,IAAI,MAAM,OAAO,+BAA+B,IAAI,MAAM,SAAS;IACjE,MAAM;IACN,IAAI;IACJ,OAAO;IACP,UAAU;IACV,QAAQ;GACV,GAAG,YAAY,CAAC;EAClB"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Auto-continue core — 平台无关的纯逻辑, 吸收自 dsh-auto-continue
3
+ * (https://github.com/HsiangNianian/dsh-auto-continue, MIT, v0.8.1 的
4
+ * src/shared/core.ts), 按 input-traffic 的纯 client 定位裁剪:
5
+ *
6
+ * - 只吸收「错误分类 / 自适应退避 / 幂等护栏 / 模板填充」这些无宿主依赖的纯函数;
7
+ * - 不吸收宿主引擎(host firehose / agent.followup / SSE 桥)——那会破坏本插件
8
+ * 「纯浏览器侧、不改官方源码」的定位, 且与「冻结会话省钱」方向相反(见 README 兼容性);
9
+ * - 全部函数无任何 @deepseek-ai/* 值导入, 通过 client bundle purity gate。
10
+ *
11
+ * 应用场景: dock 的「续跑」——检测到会话停下但排队消息未处理完(疑似中断)时,
12
+ * 分类失败、按退避节奏重发, 永久性错误则停止并提示人工介入。
13
+ */
14
+ /** 一次发送失败的可分类事实(从 send 的 reject error 里提取)。 */
15
+ export interface FailureFacts {
16
+ /** 稳定机器路由码(如 UPSTREAM、RATE_LIMIT_EXCEEDED)。 */
17
+ code?: string;
18
+ /** 人类可读的失败描述。 */
19
+ message: string;
20
+ /** 供应商 HTTP 状态码(可用时)。 */
21
+ status?: number;
22
+ }
23
+ /**
24
+ * 错误分类: 该失败是否值得重试续跑。
25
+ * 永久性失败(认证/余额/模型不存在/上下文超限等)重试也不会成功, 应停止并提示用户;
26
+ * 其余(网络、超时、5xx、429 等)视为临时性失败, 允许自动重发。
27
+ */
28
+ export declare function isTransientFailure(failure: FailureFacts): boolean;
29
+ /**
30
+ * 消息文本分类: 仅明确属于网络/传输类的临时错误才值得重试。
31
+ * 其余(序列化失败、配置/宿主内部错误等)视为永久性——重试无益。
32
+ */
33
+ export declare function isTransientAgentError(message: string): boolean;
34
+ /** 自适应退避: 同一会话连续失败时的有效重试间隔。 */
35
+ export declare function effectiveCooldown(consecutive: number, base: number, factor: number, max: number): number;
36
+ /** 模板填充所需上下文(全部可选, 缺失的占位符填为空串)。 */
37
+ export interface TemplateContext {
38
+ /** 失败事实(错误码/消息/HTTP 状态), 对应 {code}/{message}/{status}。 */
39
+ facts?: FailureFacts;
40
+ /** 失败前最后一次工具调用的名称, 对应 {tool}。 */
41
+ tool?: string;
42
+ /** 连续失败次数(含本次), 对应 {errorCount}。 */
43
+ errorCount?: number;
44
+ /** 自失败发生以来的毫秒数, 对应 {elapsed}。 */
45
+ elapsedMs?: number;
46
+ /** 上一步工具结果摘要(截断), 对应 {result}(护栏模板用)。 */
47
+ result?: string;
48
+ }
49
+ /** 把毫秒格式化为人类可读的经过时长(如 65s → 1m5s)。 */
50
+ export declare function formatElapsed(ms: number | undefined): string;
51
+ /** 用失败事实填充续跑模板占位符({code}/{message}/{status}/{tool}/{errorCount}/{elapsed}/{result})。 */
52
+ export declare function fillTemplate(template: string, ctx: TemplateContext): string;
53
+ /** 上一步工具调用的判定结果: 是否已确认完成, 以及文本摘要。 */
54
+ export interface ToolResultFacts {
55
+ /** 工具是否成功完成(内部失败或 isError 视为未成功)。 */
56
+ ok: boolean;
57
+ /** 工具输出的文本摘要(截断)。 */
58
+ excerpt: string;
59
+ }
60
+ /** 从 tool/result 事件载荷提取成功与否与文本摘要(幂等护栏: 续跑时提示别重复执行)。 */
61
+ export declare function toolResultFacts(data: {
62
+ error?: {
63
+ name?: string;
64
+ code?: string;
65
+ };
66
+ message?: {
67
+ content?: Array<{
68
+ type?: string;
69
+ content?: unknown;
70
+ isError?: boolean;
71
+ }>;
72
+ };
73
+ }): ToolResultFacts;
74
+ /** 续跑配置(全部可选, 解析时回落默认值)。 */
75
+ export interface AutoContinueSettings {
76
+ /** 续跑时自动发送的消息文本(可含模板占位符)。 */
77
+ continueText?: string;
78
+ /** 宽限期: 停下多久后视为中断再自动重发(ms)。 */
79
+ graceMs?: number;
80
+ /** 同一会话两次自动续跑的最小间隔(ms)。 */
81
+ cooldownMs?: number;
82
+ /** 连续自动续跑上限; 超过后停止, 直到用户介入或成功回合。 */
83
+ maxConsecutive?: number;
84
+ /** 连续失败时的退避系数。 */
85
+ backoffFactor?: number;
86
+ /** 自适应退避的上限(ms)。 */
87
+ backoffMaxMs?: number;
88
+ /**
89
+ * 自动续跑: 检测到疑似中断时自动重发排队消息。
90
+ * 默认关闭——纯 client 拿不到 turn/end reason, 无法区分「用户主动停止」与
91
+ * 「非人为中断」, 故默认只提示不擅自续跑(与 auto-continue 的 paused 不同)。
92
+ */
93
+ autoResume?: boolean;
94
+ /** 全局暂停续跑(如冻结期间)。 */
95
+ paused?: boolean;
96
+ }
97
+ /** 完全解析后的续跑配置(内置默认值 + 用户覆盖)。 */
98
+ export type AutoContinueConfig = Required<AutoContinueSettings>;
99
+ /** 内置默认值(与 dock 的 localStorage 持久化键一致)。 */
100
+ export declare const DEFAULT_CONFIG: AutoContinueConfig;
101
+ /** 把(可能不完整的)配置解析为完整配置(合法数字/布尔校验 + 兜底默认)。 */
102
+ export declare function resolveConfig(section: AutoContinueSettings | undefined): AutoContinueConfig;
103
+ //# sourceMappingURL=auto-continue-core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-continue-core.d.ts","sourceRoot":"","sources":["../../../src/client/auto-continue-core.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,+CAA+C;AAC/C,MAAM,WAAW,YAAY;IAC3B,+CAA+C;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,iBAAiB;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,yBAAyB;IACzB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAWjE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED,+BAA+B;AAC/B,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,GACV,MAAM,CAIR;AAED,mCAAmC;AACnC,MAAM,WAAW,eAAe;IAC9B,0DAA0D;IAC1D,KAAK,CAAC,EAAE,YAAY,CAAA;IACpB,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,oCAAoC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,iCAAiC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,sCAAsC;AACtC,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAM5D;AAED,wFAAwF;AACxF,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,GAAG,MAAM,CAS3E;AA0BD,qCAAqC;AACrC,MAAM,WAAW,eAAe;IAC9B,qCAAqC;IACrC,EAAE,EAAE,OAAO,CAAA;IACX,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,uDAAuD;AACvD,wBAAgB,eAAe,CAAC,IAAI,EAAE;IACpC,KAAK,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACxC,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,KAAK,CAAC;YAAE,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,OAAO,CAAC;YAAC,OAAO,CAAC,EAAE,OAAO,CAAA;SAAE,CAAC,CAAA;KAAE,CAAA;CACvF,GAAG,eAAe,CAGlB;AAED,4BAA4B;AAC5B,MAAM,WAAW,oBAAoB;IACnC,6BAA6B;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,+BAA+B;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,2BAA2B;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,oCAAoC;IACpC,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,kBAAkB;IAClB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,oBAAoB;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,qBAAqB;IACrB,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,gCAAgC;AAChC,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC,oBAAoB,CAAC,CAAA;AAE/D,2CAA2C;AAC3C,eAAO,MAAM,cAAc,EAAE,kBAS5B,CAAA;AAUD,4CAA4C;AAC5C,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,SAAS,GAAG,kBAAkB,CAgB3F"}