openmagic 0.7.0 → 0.8.1
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/dist/cli.js +13 -18
- package/dist/cli.js.map +1 -1
- package/dist/toolbar/index.global.js +226 -643
- package/dist/toolbar/index.global.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/toolbar/styles/toolbar.css.ts","../../src/toolbar/services/ws-client.ts","../../src/toolbar/services/dom-inspector.ts","../../src/toolbar/services/capture.ts","../../src/toolbar/services/context-builder.ts","../../src/toolbar/index.ts"],"sourcesContent":["// CSS as a JS string so it can be injected into Shadow DOM\nexport const TOOLBAR_CSS = `\n:host {\n all: initial;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n color: #e0e0e0;\n line-height: 1.5;\n}\n\n* {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n}\n\n/* Floating Pill */\n.om-pill {\n position: fixed;\n bottom: 24px;\n right: 24px;\n z-index: 2147483647;\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 6px 12px 6px 6px;\n background: linear-gradient(135deg, #13132b 0%, #1a1a3e 100%);\n border: 1px solid rgba(108, 92, 231, 0.25);\n border-radius: 12px;\n user-select: none;\n box-shadow: 0 4px 24px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(108, 92, 231, 0.08);\n transition: box-shadow 0.2s, transform 0.15s;\n}\n\n.om-pill:hover {\n box-shadow: 0 6px 32px rgba(108, 92, 231, 0.25), 0 0 0 1px rgba(108, 92, 231, 0.3);\n transform: translateY(-1px);\n}\n\n/* Six-dot grab handle */\n.om-grab {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 28px;\n color: #444;\n cursor: grab;\n border-radius: 6px;\n transition: color 0.15s, background 0.15s;\n flex-shrink: 0;\n}\n\n.om-grab:hover {\n color: #888;\n background: rgba(255, 255, 255, 0.05);\n}\n\n.om-grab:active {\n cursor: grabbing;\n color: #a29bfe;\n}\n\n/* Brand */\n.om-pill-brand {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 0 6px;\n}\n\n.om-pill-icon {\n color: #a29bfe;\n flex-shrink: 0;\n}\n\n.om-pill-text {\n font-size: 12px;\n font-weight: 700;\n color: #c4b5fd;\n letter-spacing: 0.3px;\n white-space: nowrap;\n}\n\n.om-pill-btn {\n background: none;\n border: none;\n color: #888;\n cursor: pointer;\n padding: 6px;\n border-radius: 8px;\n line-height: 1;\n transition: background 0.15s, color 0.15s;\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n}\n\n.om-pill-btn:hover {\n background: rgba(108, 92, 231, 0.2);\n}\n\n.om-pill-btn.active {\n background: rgba(108, 92, 231, 0.3);\n color: #a29bfe;\n}\n\n.om-pill-divider {\n width: 1px;\n height: 20px;\n background: rgba(255, 255, 255, 0.1);\n margin: 0 4px;\n}\n\n/* Panel */\n.om-panel {\n position: fixed;\n bottom: 80px;\n right: 24px;\n z-index: 2147483647;\n width: 420px;\n max-height: 600px;\n background: #1a1a2e;\n border: 1px solid rgba(108, 92, 231, 0.2);\n border-radius: 16px;\n box-shadow: 0 8px 48px rgba(0, 0, 0, 0.5);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n animation: om-slide-up 0.2s ease;\n}\n\n@keyframes om-slide-up {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n.om-panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n border-bottom: 1px solid rgba(255, 255, 255, 0.05);\n background: rgba(108, 92, 231, 0.05);\n}\n\n.om-panel-title {\n font-size: 13px;\n font-weight: 600;\n color: #a29bfe;\n}\n\n.om-panel-close {\n background: none;\n border: none;\n color: #666;\n cursor: pointer;\n font-size: 18px;\n padding: 2px 6px;\n border-radius: 4px;\n line-height: 1;\n}\n\n.om-panel-close:hover {\n color: #e0e0e0;\n background: rgba(255, 255, 255, 0.05);\n}\n\n.om-panel-body {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n}\n\n.om-panel-body::-webkit-scrollbar {\n width: 6px;\n}\n\n.om-panel-body::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.om-panel-body::-webkit-scrollbar-thumb {\n background: rgba(255, 255, 255, 0.1);\n border-radius: 3px;\n}\n\n/* Chat */\n.om-chat-messages {\n display: flex;\n flex-direction: column;\n gap: 12px;\n min-height: 200px;\n max-height: 380px;\n overflow-y: auto;\n padding-bottom: 8px;\n}\n\n.om-chat-messages::-webkit-scrollbar {\n width: 4px;\n}\n\n.om-chat-messages::-webkit-scrollbar-thumb {\n background: rgba(255, 255, 255, 0.1);\n border-radius: 2px;\n}\n\n.om-msg {\n padding: 10px 14px;\n border-radius: 12px;\n font-size: 13px;\n line-height: 1.5;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n.om-msg-user {\n background: rgba(108, 92, 231, 0.15);\n color: #e0e0e0;\n margin-left: 32px;\n border-bottom-right-radius: 4px;\n}\n\n.om-msg-assistant {\n background: rgba(255, 255, 255, 0.03);\n color: #ccc;\n margin-right: 32px;\n border-bottom-left-radius: 4px;\n border: 1px solid rgba(255, 255, 255, 0.05);\n}\n\n.om-msg-system {\n background: rgba(233, 69, 96, 0.1);\n color: #e94560;\n font-size: 12px;\n text-align: center;\n padding: 8px;\n}\n\n.om-chat-input-wrap {\n display: flex;\n gap: 8px;\n margin-top: 12px;\n}\n\n.om-chat-input {\n flex: 1;\n background: rgba(255, 255, 255, 0.05);\n border: 1px solid rgba(255, 255, 255, 0.1);\n border-radius: 10px;\n padding: 10px 14px;\n color: #e0e0e0;\n font-size: 13px;\n font-family: inherit;\n outline: none;\n resize: none;\n min-height: 40px;\n max-height: 120px;\n}\n\n.om-chat-input:focus {\n border-color: rgba(108, 92, 231, 0.5);\n}\n\n.om-chat-input::placeholder {\n color: #555;\n}\n\n.om-chat-send {\n background: #6c5ce7;\n border: none;\n color: white;\n cursor: pointer;\n padding: 10px 16px;\n border-radius: 10px;\n font-size: 13px;\n font-weight: 600;\n transition: background 0.15s;\n white-space: nowrap;\n}\n\n.om-chat-send:hover {\n background: #7c6cf7;\n}\n\n.om-chat-send:disabled {\n background: #333;\n color: #666;\n cursor: not-allowed;\n}\n\n/* Settings */\n.om-settings {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.om-field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.om-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: #888;\n}\n\n.om-select, .om-input {\n background: rgba(255, 255, 255, 0.05);\n border: 1px solid rgba(255, 255, 255, 0.1);\n border-radius: 8px;\n padding: 10px 12px;\n color: #e0e0e0;\n font-size: 13px;\n font-family: inherit;\n outline: none;\n width: 100%;\n}\n\n.om-select:focus, .om-input:focus {\n border-color: rgba(108, 92, 231, 0.5);\n}\n\n.om-select option {\n background: #1a1a2e;\n color: #e0e0e0;\n}\n\n.om-btn {\n background: #6c5ce7;\n border: none;\n color: white;\n cursor: pointer;\n padding: 10px 16px;\n border-radius: 8px;\n font-size: 13px;\n font-weight: 600;\n transition: background 0.15s;\n}\n\n.om-btn:hover {\n background: #7c6cf7;\n}\n\n.om-btn-secondary {\n background: rgba(255, 255, 255, 0.05);\n color: #e0e0e0;\n border: 1px solid rgba(255, 255, 255, 0.1);\n}\n\n.om-btn-secondary:hover {\n background: rgba(255, 255, 255, 0.1);\n}\n\n.om-status {\n font-size: 12px;\n padding: 6px 10px;\n border-radius: 6px;\n text-align: center;\n}\n\n.om-status-success {\n background: rgba(0, 184, 148, 0.1);\n color: #00b894;\n}\n\n.om-status-error {\n background: rgba(233, 69, 96, 0.1);\n color: #e94560;\n}\n\n/* Context bar */\n.om-context-bar {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n margin-bottom: 8px;\n}\n\n.om-context-chip {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n background: rgba(108, 92, 231, 0.1);\n border: 1px solid rgba(108, 92, 231, 0.2);\n border-radius: 20px;\n font-size: 11px;\n color: #a29bfe;\n}\n\n.om-context-chip-remove {\n background: none;\n border: none;\n color: #a29bfe;\n cursor: pointer;\n font-size: 14px;\n padding: 0 2px;\n line-height: 1;\n}\n\n/* Diff */\n.om-diff {\n font-family: 'SF Mono', 'Fira Code', Consolas, monospace;\n font-size: 12px;\n border-radius: 8px;\n overflow: hidden;\n border: 1px solid rgba(255, 255, 255, 0.05);\n margin: 8px 0;\n}\n\n.om-diff-header {\n padding: 8px 12px;\n background: rgba(255, 255, 255, 0.03);\n border-bottom: 1px solid rgba(255, 255, 255, 0.05);\n color: #888;\n font-size: 11px;\n}\n\n.om-diff-line {\n padding: 2px 12px;\n white-space: pre;\n overflow-x: auto;\n}\n\n.om-diff-add {\n background: rgba(0, 184, 148, 0.1);\n color: #55efc4;\n}\n\n.om-diff-remove {\n background: rgba(233, 69, 96, 0.1);\n color: #fab1a0;\n}\n\n.om-diff-actions {\n display: flex;\n gap: 8px;\n padding: 8px 12px;\n border-top: 1px solid rgba(255, 255, 255, 0.05);\n background: rgba(255, 255, 255, 0.02);\n}\n\n/* Element info */\n.om-element-info {\n background: rgba(255, 255, 255, 0.03);\n border: 1px solid rgba(255, 255, 255, 0.05);\n border-radius: 8px;\n padding: 10px 12px;\n font-family: 'SF Mono', 'Fira Code', Consolas, monospace;\n font-size: 11px;\n color: #888;\n margin: 8px 0;\n max-height: 100px;\n overflow-y: auto;\n}\n\n.om-hidden {\n display: none !important;\n}\n\n/* Loading */\n.om-loading {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n color: #888;\n font-size: 12px;\n}\n\n.om-spinner {\n width: 16px;\n height: 16px;\n border: 2px solid rgba(108, 92, 231, 0.2);\n border-top-color: #6c5ce7;\n border-radius: 50%;\n animation: om-spin 0.6s linear infinite;\n}\n\n@keyframes om-spin {\n to { transform: rotate(360deg); }\n}\n\n/* Tooltip */\n.om-tooltip {\n position: absolute;\n bottom: 100%;\n left: 50%;\n transform: translateX(-50%);\n background: #1a1a2e;\n color: #e0e0e0;\n padding: 4px 8px;\n border-radius: 4px;\n font-size: 11px;\n white-space: nowrap;\n pointer-events: none;\n opacity: 0;\n transition: opacity 0.15s;\n margin-bottom: 4px;\n}\n\n.om-pill-btn:hover .om-tooltip {\n opacity: 1;\n}\n\n/* Update indicator dot on pill */\n.om-update-dot {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n background: #00b894;\n margin-left: 6px;\n cursor: pointer;\n position: relative;\n animation: om-pulse-green 2s ease infinite;\n flex-shrink: 0;\n}\n\n@keyframes om-pulse-green {\n 0%, 100% { box-shadow: 0 0 0 0 rgba(0, 184, 148, 0.5); }\n 50% { box-shadow: 0 0 0 6px rgba(0, 184, 148, 0); }\n}\n\n/* Update banner in settings */\n.om-update-banner {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n padding: 10px 14px;\n margin-bottom: 16px;\n background: rgba(0, 184, 148, 0.08);\n border: 1px solid rgba(0, 184, 148, 0.2);\n border-radius: 10px;\n font-size: 13px;\n color: #00b894;\n}\n\n.om-update-current {\n font-size: 11px;\n color: #888;\n}\n\n.om-update-cmd {\n display: block;\n width: 100%;\n margin-top: 4px;\n padding: 6px 10px;\n background: rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n font-family: 'SF Mono', 'Fira Code', Consolas, monospace;\n font-size: 12px;\n color: #55efc4;\n user-select: all;\n}\n\n/* Version in panel header */\n.om-panel-version {\n font-size: 11px;\n color: #555;\n margin-left: auto;\n margin-right: 8px;\n}\n\n.om-header-icon {\n color: #a29bfe;\n margin-right: 6px;\n flex-shrink: 0;\n}\n\n/* API Key row with connect button */\n.om-key-row {\n display: flex;\n gap: 8px;\n align-items: stretch;\n}\n\n.om-key-input {\n flex: 1;\n min-width: 0;\n}\n\n.om-btn-connect {\n display: flex;\n align-items: center;\n gap: 5px;\n padding: 8px 12px;\n background: rgba(108, 92, 231, 0.12);\n border: 1px solid rgba(108, 92, 231, 0.25);\n border-radius: 8px;\n color: #a29bfe;\n font-size: 12px;\n font-weight: 600;\n font-family: inherit;\n cursor: pointer;\n white-space: nowrap;\n transition: all 0.15s;\n}\n\n.om-btn-connect:hover {\n background: rgba(108, 92, 231, 0.2);\n border-color: rgba(108, 92, 231, 0.4);\n color: #c4b5fd;\n}\n\n.om-key-hint {\n font-size: 11px;\n color: #666;\n margin-top: 6px;\n line-height: 1.5;\n}\n\n.om-key-hint a {\n color: #a29bfe;\n cursor: pointer;\n text-decoration: none;\n}\n\n.om-key-hint a:hover {\n text-decoration: underline;\n color: #c4b5fd;\n}\n\n.om-status svg {\n vertical-align: -2px;\n margin-right: 4px;\n}\n`;\n","type MessageHandler = (msg: any) => void;\n\nlet ws: WebSocket | null = null;\nlet handlers: Map<string, MessageHandler> = new Map();\nlet globalHandlers: ((msg: any) => void)[] = [];\nlet messageQueue: string[] = [];\nlet connected = false;\nlet reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n\nfunction generateId(): string {\n return Math.random().toString(36).slice(2) + Date.now().toString(36);\n}\n\nexport function connect(port: number, token: string): Promise<void> {\n return new Promise((resolve, reject) => {\n try {\n ws = new WebSocket(`ws://127.0.0.1:${port}/__openmagic__/ws`);\n\n ws.onopen = () => {\n // Send handshake\n const handshakeId = generateId();\n send({ id: handshakeId, type: \"handshake\", payload: { token } });\n\n // Wait for handshake.ok\n handlers.set(handshakeId, (msg) => {\n if (msg.type === \"handshake.ok\") {\n connected = true;\n // Flush queued messages\n for (const queued of messageQueue) {\n ws?.send(queued);\n }\n messageQueue = [];\n resolve();\n } else if (msg.type === \"error\") {\n reject(new Error(msg.payload?.message || \"Handshake failed\"));\n }\n });\n };\n\n ws.onmessage = (event) => {\n try {\n const msg = JSON.parse(event.data);\n\n // Route to specific handler if exists\n if (msg.id && handlers.has(msg.id)) {\n const handler = handlers.get(msg.id)!;\n handler(msg);\n // Don't delete handler for streaming responses\n if (msg.type === \"llm.done\" || msg.type === \"llm.error\" || !msg.type.startsWith(\"llm.\")) {\n handlers.delete(msg.id);\n }\n }\n\n // Notify global handlers\n for (const handler of globalHandlers) {\n handler(msg);\n }\n } catch {\n // Ignore parse errors\n }\n };\n\n ws.onclose = () => {\n connected = false;\n // Reconnect after 2 seconds\n if (!reconnectTimer) {\n reconnectTimer = setTimeout(() => {\n reconnectTimer = null;\n connect(port, token).catch(() => {});\n }, 2000);\n }\n };\n\n ws.onerror = () => {\n // Will trigger onclose\n };\n } catch (e) {\n reject(e);\n }\n });\n}\n\nexport function send(msg: { id: string; type: string; payload?: any }): void {\n const data = JSON.stringify(msg);\n if (ws && connected) {\n ws.send(data);\n } else {\n messageQueue.push(data);\n }\n}\n\nexport function request(type: string, payload?: any): Promise<any> {\n return new Promise((resolve, reject) => {\n const id = generateId();\n const timeout = setTimeout(() => {\n handlers.delete(id);\n reject(new Error(\"Request timeout\"));\n }, 30000);\n\n handlers.set(id, (msg) => {\n clearTimeout(timeout);\n if (msg.type === \"error\") {\n reject(new Error(msg.payload?.message || \"Unknown error\"));\n } else {\n resolve(msg);\n }\n });\n\n send({ id, type, payload });\n });\n}\n\nexport function stream(\n type: string,\n payload: any,\n onChunk: (chunk: string) => void\n): Promise<any> {\n return new Promise((resolve, reject) => {\n const id = generateId();\n const timeout = setTimeout(() => {\n handlers.delete(id);\n reject(new Error(\"Stream timeout\"));\n }, 120000); // 2 min timeout for LLM responses\n\n handlers.set(id, (msg) => {\n if (msg.type === \"llm.chunk\") {\n onChunk(msg.payload?.delta || \"\");\n } else if (msg.type === \"llm.done\") {\n clearTimeout(timeout);\n handlers.delete(id);\n resolve(msg.payload);\n } else if (msg.type === \"llm.error\" || msg.type === \"error\") {\n clearTimeout(timeout);\n handlers.delete(id);\n reject(new Error(msg.payload?.message || \"Stream error\"));\n }\n });\n\n send({ id, type, payload });\n });\n}\n\nexport function onMessage(handler: (msg: any) => void): () => void {\n globalHandlers.push(handler);\n return () => {\n globalHandlers = globalHandlers.filter((h) => h !== handler);\n };\n}\n\nexport function isConnected(): boolean {\n return connected;\n}\n\nexport function disconnect(): void {\n if (reconnectTimer) {\n clearTimeout(reconnectTimer);\n reconnectTimer = null;\n }\n if (ws) {\n ws.close();\n ws = null;\n }\n connected = false;\n}\n","export interface SelectedElement {\n tagName: string;\n id: string;\n className: string;\n textContent: string;\n outerHTML: string;\n cssSelector: string;\n xpath: string;\n computedStyles: Record<string, string>;\n rect: { x: number; y: number; width: number; height: number };\n}\n\nconst IMPORTANT_STYLES = [\n \"display\",\n \"position\",\n \"width\",\n \"height\",\n \"margin\",\n \"padding\",\n \"color\",\n \"background-color\",\n \"background\",\n \"font-size\",\n \"font-weight\",\n \"font-family\",\n \"border\",\n \"border-radius\",\n \"box-shadow\",\n \"flex-direction\",\n \"justify-content\",\n \"align-items\",\n \"gap\",\n \"grid-template-columns\",\n \"grid-template-rows\",\n \"overflow\",\n \"opacity\",\n \"z-index\",\n \"text-align\",\n \"line-height\",\n \"letter-spacing\",\n];\n\nexport function inspectElement(el: HTMLElement): SelectedElement {\n const computed = window.getComputedStyle(el);\n const styles: Record<string, string> = {};\n for (const prop of IMPORTANT_STYLES) {\n styles[prop] = computed.getPropertyValue(prop);\n }\n\n const rect = el.getBoundingClientRect();\n\n return {\n tagName: el.tagName.toLowerCase(),\n id: el.id || \"\",\n className: el.className || \"\",\n textContent: (el.textContent || \"\").trim().slice(0, 200),\n outerHTML: getCleanOuterHTML(el),\n cssSelector: getCssSelector(el),\n xpath: getXPath(el),\n computedStyles: styles,\n rect: {\n x: rect.x,\n y: rect.y,\n width: rect.width,\n height: rect.height,\n },\n };\n}\n\nfunction getCleanOuterHTML(el: HTMLElement): string {\n const clone = el.cloneNode(true) as HTMLElement;\n\n // Remove script tags and large content\n const scripts = clone.querySelectorAll(\"script, style, svg\");\n scripts.forEach((s) => s.remove());\n\n // Truncate children if too many\n let html = clone.outerHTML;\n if (html.length > 2000) {\n // Just get the opening tag + first level children hints\n const tag = el.tagName.toLowerCase();\n const attrs = Array.from(el.attributes)\n .map((a) => `${a.name}=\"${a.value}\"`)\n .join(\" \");\n const childSummary = Array.from(el.children)\n .slice(0, 5)\n .map((c) => `<${c.tagName.toLowerCase()} .../>`)\n .join(\"\\n \");\n html = `<${tag} ${attrs}>\\n ${childSummary}\\n ${el.children.length > 5 ? `<!-- +${el.children.length - 5} more children -->` : \"\"}\\n</${tag}>`;\n }\n\n return html;\n}\n\nfunction getCssSelector(el: HTMLElement): string {\n if (el.id) return `#${el.id}`;\n\n const parts: string[] = [];\n let current: HTMLElement | null = el;\n\n while (current && current !== document.body) {\n let selector = current.tagName.toLowerCase();\n\n if (current.id) {\n parts.unshift(`#${current.id}`);\n break;\n }\n\n if (current.className && typeof current.className === \"string\") {\n const classes = current.className\n .trim()\n .split(/\\s+/)\n .filter((c) => !c.startsWith(\"__\") && c.length < 30)\n .slice(0, 2);\n if (classes.length > 0) {\n selector += \".\" + classes.join(\".\");\n }\n }\n\n // Add nth-child if needed for uniqueness\n const parent = current.parentElement;\n if (parent) {\n const siblings = Array.from(parent.children).filter(\n (s) => s.tagName === current!.tagName\n );\n if (siblings.length > 1) {\n const index = siblings.indexOf(current) + 1;\n selector += `:nth-child(${index})`;\n }\n }\n\n parts.unshift(selector);\n current = current.parentElement;\n }\n\n return parts.join(\" > \");\n}\n\nfunction getXPath(el: HTMLElement): string {\n const parts: string[] = [];\n let current: Node | null = el;\n\n while (current && current !== document) {\n if (current.nodeType === Node.ELEMENT_NODE) {\n const element = current as HTMLElement;\n let index = 1;\n let sibling = element.previousElementSibling;\n while (sibling) {\n if (sibling.tagName === element.tagName) index++;\n sibling = sibling.previousElementSibling;\n }\n parts.unshift(`${element.tagName.toLowerCase()}[${index}]`);\n }\n current = current.parentNode;\n }\n\n return \"/\" + parts.join(\"/\");\n}\n\n// --- Highlight Overlay ---\n\nlet highlightEl: HTMLDivElement | null = null;\n\nexport function showHighlight(rect: {\n x: number;\n y: number;\n width: number;\n height: number;\n}): void {\n if (!highlightEl) {\n highlightEl = document.createElement(\"div\");\n highlightEl.style.cssText = `\n position: fixed;\n pointer-events: none;\n z-index: 2147483646;\n border: 2px solid #6c5ce7;\n background: rgba(108, 92, 231, 0.1);\n transition: all 0.1s ease;\n `;\n highlightEl.dataset.openmagic = \"highlight\";\n document.body.appendChild(highlightEl);\n }\n\n highlightEl.style.left = `${rect.x}px`;\n highlightEl.style.top = `${rect.y}px`;\n highlightEl.style.width = `${rect.width}px`;\n highlightEl.style.height = `${rect.height}px`;\n highlightEl.style.display = \"block\";\n}\n\nexport function hideHighlight(): void {\n if (highlightEl) {\n highlightEl.style.display = \"none\";\n }\n}\n\nexport function removeHighlight(): void {\n if (highlightEl) {\n highlightEl.remove();\n highlightEl = null;\n }\n}\n","// Simple screenshot capture using Canvas API\n// Falls back to a simpler approach if html-to-image isn't available\n\nexport async function captureScreenshot(\n target?: HTMLElement\n): Promise<string | null> {\n try {\n // Try using the Canvas approach for element capture\n if (target) {\n return await captureElementViaCanvas(target);\n }\n\n // Full page: use a simple canvas capture of the viewport\n return await captureViewport();\n } catch (e) {\n console.warn(\"[OpenMagic] Screenshot capture failed:\", e);\n return null;\n }\n}\n\nasync function captureViewport(): Promise<string | null> {\n // Create a canvas the size of the viewport\n const canvas = document.createElement(\"canvas\");\n const dpr = window.devicePixelRatio || 1;\n canvas.width = window.innerWidth * dpr;\n canvas.height = window.innerHeight * dpr;\n const ctx = canvas.getContext(\"2d\")!;\n ctx.scale(dpr, dpr);\n\n // We can't directly capture the viewport without html2canvas or similar\n // Instead, we use the SVG foreignObject approach (snapdom-like)\n try {\n const svgData = await elementToSvg(document.body);\n const img = await svgToImage(svgData, window.innerWidth, window.innerHeight);\n ctx.drawImage(img, 0, 0);\n return canvas.toDataURL(\"image/png\");\n } catch {\n return null;\n }\n}\n\nasync function captureElementViaCanvas(\n element: HTMLElement\n): Promise<string | null> {\n const rect = element.getBoundingClientRect();\n const canvas = document.createElement(\"canvas\");\n const dpr = window.devicePixelRatio || 1;\n canvas.width = rect.width * dpr;\n canvas.height = rect.height * dpr;\n const ctx = canvas.getContext(\"2d\")!;\n ctx.scale(dpr, dpr);\n\n try {\n const svgData = await elementToSvg(element);\n const img = await svgToImage(svgData, rect.width, rect.height);\n ctx.drawImage(img, 0, 0);\n return canvas.toDataURL(\"image/png\");\n } catch {\n return null;\n }\n}\n\nfunction elementToSvg(element: HTMLElement): Promise<string> {\n return new Promise((resolve) => {\n const clone = element.cloneNode(true) as HTMLElement;\n\n // Inline computed styles on the clone\n inlineStyles(element, clone);\n\n const rect = element.getBoundingClientRect();\n const width = rect.width;\n const height = rect.height;\n\n const foreignObject = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${width}\" height=\"${height}\">\n <foreignObject width=\"100%\" height=\"100%\">\n <div xmlns=\"http://www.w3.org/1999/xhtml\" style=\"width:${width}px;height:${height}px;overflow:hidden;\">\n ${clone.outerHTML}\n </div>\n </foreignObject>\n </svg>`;\n\n resolve(foreignObject);\n });\n}\n\nfunction inlineStyles(source: HTMLElement, target: HTMLElement): void {\n const computed = window.getComputedStyle(source);\n let cssText = \"\";\n for (let i = 0; i < computed.length; i++) {\n const prop = computed[i];\n cssText += `${prop}:${computed.getPropertyValue(prop)};`;\n }\n target.style.cssText = cssText;\n\n const sourceChildren = source.children;\n const targetChildren = target.children;\n for (let i = 0; i < sourceChildren.length && i < targetChildren.length; i++) {\n inlineStyles(\n sourceChildren[i] as HTMLElement,\n targetChildren[i] as HTMLElement\n );\n }\n}\n\nfunction svgToImage(\n svgData: string,\n width: number,\n height: number\n): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n const blob = new Blob([svgData], { type: \"image/svg+xml;charset=utf-8\" });\n const url = URL.createObjectURL(blob);\n\n img.onload = () => {\n URL.revokeObjectURL(url);\n resolve(img);\n };\n img.onerror = () => {\n URL.revokeObjectURL(url);\n reject(new Error(\"Failed to load SVG image\"));\n };\n\n img.width = width;\n img.height = height;\n img.src = url;\n });\n}\n","import type { SelectedElement } from \"./dom-inspector.js\";\n\n// --- Network Log Capture ---\n\ninterface NetworkEntry {\n method: string;\n url: string;\n status?: number;\n duration?: number;\n timestamp: number;\n}\n\nconst networkLogs: NetworkEntry[] = [];\nconst MAX_NETWORK_LOGS = 50;\n\nlet networkCaptureInstalled = false;\n\nexport function installNetworkCapture(): void {\n if (networkCaptureInstalled) return;\n networkCaptureInstalled = true;\n\n // Intercept fetch\n const originalFetch = window.fetch;\n window.fetch = async function (...args) {\n const request = new Request(...args);\n const entry: NetworkEntry = {\n method: request.method,\n url: request.url,\n timestamp: Date.now(),\n };\n\n try {\n const response = await originalFetch.apply(this, args);\n entry.status = response.status;\n entry.duration = Date.now() - entry.timestamp;\n addNetworkEntry(entry);\n return response;\n } catch (e) {\n entry.status = 0;\n entry.duration = Date.now() - entry.timestamp;\n addNetworkEntry(entry);\n throw e;\n }\n };\n\n // Intercept XMLHttpRequest\n const originalOpen = XMLHttpRequest.prototype.open;\n const originalSend = XMLHttpRequest.prototype.send;\n\n XMLHttpRequest.prototype.open = function (method: string, url: string, ...rest: any[]) {\n (this as any).__om_method = method;\n (this as any).__om_url = url;\n (this as any).__om_start = Date.now();\n return originalOpen.apply(this, [method, url, ...rest] as any);\n };\n\n XMLHttpRequest.prototype.send = function (...args) {\n this.addEventListener(\"loadend\", () => {\n addNetworkEntry({\n method: (this as any).__om_method || \"GET\",\n url: (this as any).__om_url || \"\",\n status: this.status,\n duration: Date.now() - ((this as any).__om_start || Date.now()),\n timestamp: (this as any).__om_start || Date.now(),\n });\n });\n return originalSend.apply(this, args);\n };\n}\n\nfunction addNetworkEntry(entry: NetworkEntry): void {\n // Filter out OpenMagic's own requests\n if (entry.url.includes(\"__openmagic__\")) return;\n networkLogs.push(entry);\n if (networkLogs.length > MAX_NETWORK_LOGS) {\n networkLogs.shift();\n }\n}\n\nexport function getNetworkLogs(): NetworkEntry[] {\n return [...networkLogs];\n}\n\nexport function clearNetworkLogs(): void {\n networkLogs.length = 0;\n}\n\n// --- Console Log Capture ---\n\ninterface ConsoleEntry {\n level: \"log\" | \"warn\" | \"error\" | \"info\" | \"debug\";\n args: string[];\n timestamp: number;\n}\n\nconst consoleLogs: ConsoleEntry[] = [];\nconst MAX_CONSOLE_LOGS = 100;\n\nlet consoleCaptureInstalled = false;\n\nexport function installConsoleCapture(): void {\n if (consoleCaptureInstalled) return;\n consoleCaptureInstalled = true;\n\n const levels: ConsoleEntry[\"level\"][] = [\"log\", \"warn\", \"error\", \"info\", \"debug\"];\n\n for (const level of levels) {\n const original = console[level];\n console[level] = function (...args: any[]) {\n consoleLogs.push({\n level,\n args: args.map((a) => {\n try {\n return typeof a === \"object\" ? JSON.stringify(a).slice(0, 500) : String(a);\n } catch {\n return String(a);\n }\n }),\n timestamp: Date.now(),\n });\n\n if (consoleLogs.length > MAX_CONSOLE_LOGS) {\n consoleLogs.shift();\n }\n\n original.apply(console, args);\n };\n }\n}\n\nexport function getConsoleLogs(): ConsoleEntry[] {\n return [...consoleLogs];\n}\n\nexport function clearConsoleLogs(): void {\n consoleLogs.length = 0;\n}\n\n// --- Context Builder ---\n\nexport function buildContext(\n selectedElement: SelectedElement | null,\n screenshot: string | null\n) {\n return {\n selectedElement: selectedElement\n ? {\n tagName: selectedElement.tagName,\n id: selectedElement.id,\n className: selectedElement.className,\n textContent: selectedElement.textContent,\n outerHTML: selectedElement.outerHTML,\n cssSelector: selectedElement.cssSelector,\n computedStyles: selectedElement.computedStyles,\n }\n : undefined,\n screenshot: screenshot || undefined,\n networkLogs: getNetworkLogs().map((l) => ({\n method: l.method,\n url: l.url,\n status: l.status,\n duration: l.duration,\n timestamp: l.timestamp,\n })),\n consoleLogs: getConsoleLogs().map((l) => ({\n level: l.level,\n args: l.args,\n timestamp: l.timestamp,\n })),\n };\n}\n","import { TOOLBAR_CSS } from \"./styles/toolbar.css.js\";\nimport * as ws from \"./services/ws-client.js\";\nimport {\n inspectElement,\n showHighlight,\n hideHighlight,\n removeHighlight,\n type SelectedElement,\n} from \"./services/dom-inspector.js\";\nimport { captureScreenshot } from \"./services/capture.js\";\nimport {\n installNetworkCapture,\n installConsoleCapture,\n buildContext,\n} from \"./services/context-builder.js\";\n\n// Inline model registry (bundled into toolbar IIFE)\nconst MODEL_REGISTRY: Record<string, { name: string; models: { id: string; name: string }[]; keyPlaceholder: string; local?: boolean }> = {\n openai: { name: \"OpenAI\", models: [\n { id: \"gpt-5.4\", name: \"GPT-5.4\" },\n { id: \"gpt-5.4-pro\", name: \"GPT-5.4 Pro\" },\n { id: \"gpt-5.4-mini\", name: \"GPT-5.4 Mini\" },\n { id: \"gpt-5.4-nano\", name: \"GPT-5.4 Nano\" },\n { id: \"gpt-5.2\", name: \"GPT-5.2 Thinking\" },\n { id: \"gpt-5.2-pro\", name: \"GPT-5.2 Pro\" },\n { id: \"o3\", name: \"o3 (Reasoning)\" },\n { id: \"o4-mini\", name: \"o4-mini (Reasoning)\" },\n { id: \"gpt-4.1\", name: \"GPT-4.1\" },\n { id: \"gpt-4.1-mini\", name: \"GPT-4.1 Mini\" },\n { id: \"codex-mini-latest\", name: \"Codex Mini\" },\n ], keyPlaceholder: \"sk-...\" },\n anthropic: { name: \"Anthropic\", models: [\n { id: \"claude-opus-4-6\", name: \"Claude Opus 4.6\" },\n { id: \"claude-sonnet-4-6\", name: \"Claude Sonnet 4.6\" },\n { id: \"claude-haiku-4-5-20251001\", name: \"Claude Haiku 4.5\" },\n { id: \"claude-sonnet-4-5-20250929\", name: \"Claude Sonnet 4.5\" },\n { id: \"claude-opus-4-5-20251101\", name: \"Claude Opus 4.5\" },\n { id: \"claude-sonnet-4-20250514\", name: \"Claude Sonnet 4\" },\n { id: \"claude-opus-4-20250514\", name: \"Claude Opus 4\" },\n ], keyPlaceholder: \"sk-ant-...\" },\n google: { name: \"Google Gemini\", models: [\n { id: \"gemini-3.1-pro-preview\", name: \"Gemini 3.1 Pro\" },\n { id: \"gemini-3-flash-preview\", name: \"Gemini 3 Flash\" },\n { id: \"gemini-3.1-flash-lite-preview\", name: \"Gemini 3.1 Flash Lite\" },\n { id: \"gemini-2.5-pro\", name: \"Gemini 2.5 Pro\" },\n { id: \"gemini-2.5-flash\", name: \"Gemini 2.5 Flash\" },\n { id: \"gemini-2.5-flash-lite\", name: \"Gemini 2.5 Flash Lite\" },\n ], keyPlaceholder: \"AIza...\" },\n xai: { name: \"xAI (Grok)\", models: [\n { id: \"grok-4.20-0309-reasoning\", name: \"Grok 4.20 Reasoning\" },\n { id: \"grok-4.20-0309-non-reasoning\", name: \"Grok 4.20\" },\n { id: \"grok-4-1-fast-reasoning\", name: \"Grok 4.1 Fast Reasoning\" },\n { id: \"grok-4-1-fast-non-reasoning\", name: \"Grok 4.1 Fast\" },\n ], keyPlaceholder: \"xai-...\" },\n deepseek: { name: \"DeepSeek\", models: [\n { id: \"deepseek-chat\", name: \"DeepSeek V3.2\" },\n { id: \"deepseek-reasoner\", name: \"DeepSeek R1\" },\n ], keyPlaceholder: \"sk-...\" },\n mistral: { name: \"Mistral\", models: [\n { id: \"mistral-large-3-25-12\", name: \"Mistral Large 3\" },\n { id: \"mistral-small-4-0-26-03\", name: \"Mistral Small 4\" },\n { id: \"codestral-2508\", name: \"Codestral\" },\n { id: \"devstral-2-25-12\", name: \"Devstral 2\" },\n { id: \"magistral-medium-1-2-25-09\", name: \"Magistral Medium\" },\n ], keyPlaceholder: \"...\" },\n groq: { name: \"Groq\", models: [\n { id: \"meta-llama/llama-4-scout-17b-16e-instruct\", name: \"Llama 4 Scout 17B\" },\n { id: \"llama-3.3-70b-versatile\", name: \"Llama 3.3 70B\" },\n { id: \"llama-3.1-8b-instant\", name: \"Llama 3.1 8B Instant\" },\n { id: \"qwen/qwen3-32b\", name: \"Qwen 3 32B\" },\n ], keyPlaceholder: \"gsk_...\" },\n minimax: { name: \"MiniMax\", models: [\n { id: \"MiniMax-M2.7\", name: \"MiniMax M2.7\" },\n { id: \"MiniMax-M2.7-highspeed\", name: \"M2.7 Highspeed\" },\n { id: \"MiniMax-M2.5\", name: \"MiniMax M2.5\" },\n ], keyPlaceholder: \"MiniMax key...\" },\n moonshot: { name: \"Kimi (Moonshot)\", models: [\n { id: \"kimi-k2.5\", name: \"Kimi K2.5\" },\n { id: \"kimi-k2-thinking\", name: \"Kimi K2 Thinking\" },\n ], keyPlaceholder: \"Moonshot key...\" },\n qwen: { name: \"Qwen (Alibaba)\", models: [\n { id: \"qwen3.5-plus\", name: \"Qwen 3.5 Plus\" },\n { id: \"qwen-max\", name: \"Qwen Max\" },\n { id: \"qwen-turbo\", name: \"Qwen Turbo\" },\n ], keyPlaceholder: \"DashScope key...\" },\n zhipu: { name: \"Zhipu AI (GLM)\", models: [\n { id: \"glm-5\", name: \"GLM-5\" },\n { id: \"glm-4.7\", name: \"GLM-4.7\" },\n { id: \"glm-4.6\", name: \"GLM-4.6\" },\n ], keyPlaceholder: \"Zhipu key...\" },\n doubao: { name: \"Doubao (ByteDance)\", models: [\n { id: \"doubao-seed-2-0-pro\", name: \"Doubao Seed 2.0 Pro\" },\n { id: \"doubao-seed-2-0-code\", name: \"Doubao Seed 2.0 Code\" },\n ], keyPlaceholder: \"Volcano key...\" },\n ollama: { name: \"Ollama (Local)\", models: [], keyPlaceholder: \"not required\", local: true },\n openrouter: { name: \"OpenRouter\", models: [], keyPlaceholder: \"sk-or-...\" },\n};\n\nconst CURRENT_VERSION = \"0.7.0\";\n\n// --- State ---\ninterface AppState {\n connected: boolean;\n panelOpen: boolean;\n activePanel: \"chat\" | \"settings\" | null;\n selecting: boolean;\n selectedElement: SelectedElement | null;\n screenshot: string | null;\n messages: Array<{ role: \"user\" | \"assistant\" | \"system\"; content: string }>;\n streaming: boolean;\n streamContent: string;\n provider: string;\n model: string;\n hasApiKey: boolean;\n roots: string[];\n updateAvailable: boolean;\n latestVersion: string;\n}\n\nconst state: AppState = {\n connected: false,\n panelOpen: false,\n activePanel: null,\n selecting: false,\n selectedElement: null,\n screenshot: null,\n messages: [],\n streaming: false,\n streamContent: \"\",\n provider: \"\",\n model: \"\",\n hasApiKey: false,\n roots: [],\n updateAvailable: false,\n latestVersion: \"\",\n};\n\n// --- DOM References ---\nlet shadow: ShadowRoot;\nlet container: HTMLDivElement;\n\n// --- Initialize ---\nfunction init() {\n // Don't initialize if already loaded\n if (document.querySelector(\"openmagic-toolbar\")) return;\n\n // Create custom element\n const host = document.createElement(\"openmagic-toolbar\");\n host.dataset.openmagic = \"true\";\n shadow = host.attachShadow({ mode: \"closed\" });\n\n // Inject styles\n const style = document.createElement(\"style\");\n style.textContent = TOOLBAR_CSS;\n shadow.appendChild(style);\n\n // Create container\n container = document.createElement(\"div\");\n shadow.appendChild(container);\n\n // Mount\n document.body.appendChild(host);\n\n // Install captures\n installNetworkCapture();\n installConsoleCapture();\n\n // Check for updates (non-blocking)\n checkForUpdates();\n\n // Connect to server\n const config = (window as any).__OPENMAGIC_CONFIG__;\n if (config) {\n ws.connect(config.wsPort, config.token)\n .then(() => {\n state.connected = true;\n // Fetch config\n ws.request(\"config.get\").then((msg: any) => {\n state.provider = msg.payload?.provider || \"\";\n state.model = msg.payload?.model || \"\";\n state.hasApiKey = msg.payload?.hasApiKey || false;\n state.roots = msg.payload?.roots || [];\n\n // If not configured, open settings\n if (!state.provider || !state.hasApiKey) {\n state.panelOpen = true;\n state.activePanel = \"settings\";\n }\n\n render();\n });\n })\n .catch((e: Error) => {\n console.error(\"[OpenMagic] Connection failed:\", e);\n state.connected = false;\n render();\n });\n }\n\n render();\n}\n\n// --- Render ---\nfunction render() {\n container.innerHTML = \"\";\n\n // Panel (if open)\n if (state.panelOpen && state.activePanel) {\n const panel = document.createElement(\"div\");\n panel.className = \"om-panel\";\n\n if (state.activePanel === \"settings\") {\n panel.innerHTML = renderSettings();\n } else if (state.activePanel === \"chat\") {\n panel.innerHTML = renderChat();\n }\n\n container.appendChild(panel);\n attachPanelEvents(panel);\n }\n\n // Floating pill\n const pill = document.createElement(\"div\");\n pill.className = \"om-pill\";\n pill.innerHTML = `\n <span class=\"om-grab\" title=\"Drag to move\">\n <svg width=\"8\" height=\"14\" viewBox=\"0 0 8 14\" fill=\"currentColor\"><circle cx=\"2\" cy=\"2\" r=\"1.2\"/><circle cx=\"6\" cy=\"2\" r=\"1.2\"/><circle cx=\"2\" cy=\"7\" r=\"1.2\"/><circle cx=\"6\" cy=\"7\" r=\"1.2\"/><circle cx=\"2\" cy=\"12\" r=\"1.2\"/><circle cx=\"6\" cy=\"12\" r=\"1.2\"/></svg>\n </span>\n <span class=\"om-pill-brand\">\n <svg class=\"om-pill-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.582a.5.5 0 0 1 0 .962L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z\"/></svg>\n <span class=\"om-pill-text\">OpenMagic</span>\n </span>\n <span class=\"om-pill-divider\"></span>\n <button class=\"om-pill-btn ${state.selecting ? \"active\" : \"\"}\" data-action=\"select\" title=\"Select Element\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M7 7h10v10\"/><path d=\"M7 17 17 7\"/></svg>\n </button>\n <button class=\"om-pill-btn\" data-action=\"screenshot\" title=\"Screenshot\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M14.5 4h-5L7 7H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3l-2.5-3z\"/><circle cx=\"12\" cy=\"13\" r=\"3\"/></svg>\n </button>\n <button class=\"om-pill-btn ${state.activePanel === \"chat\" ? \"active\" : \"\"}\" data-action=\"chat\" title=\"Chat with AI\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"/></svg>\n </button>\n <button class=\"om-pill-btn ${state.activePanel === \"settings\" ? \"active\" : \"\"}\" data-action=\"settings\" title=\"Settings\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"3\"/><path d=\"M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42\"/></svg>\n </button>\n `;\n\n // Connection indicator\n if (!state.connected) {\n const dot = document.createElement(\"span\");\n dot.style.cssText = \"width:8px;height:8px;border-radius:50%;background:#e94560;margin-left:4px;\";\n pill.appendChild(dot);\n }\n\n // Update indicator\n if (state.updateAvailable) {\n const updateDot = document.createElement(\"span\");\n updateDot.className = \"om-update-dot\";\n updateDot.title = `Update available: v${state.latestVersion}`;\n updateDot.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n state.panelOpen = true;\n state.activePanel = \"settings\";\n render();\n });\n pill.appendChild(updateDot);\n }\n\n container.appendChild(pill);\n\n // Draggable\n makeDraggable(pill);\n\n // Pill button events\n pill.querySelectorAll(\".om-pill-btn\").forEach((btn) => {\n btn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n const action = (btn as HTMLElement).dataset.action;\n\n if (action === \"select\") {\n toggleSelectMode();\n } else if (action === \"screenshot\") {\n takeScreenshot();\n } else if (action === \"chat\") {\n togglePanel(\"chat\");\n } else if (action === \"settings\") {\n togglePanel(\"settings\");\n }\n });\n });\n}\n\n// --- Renderers ---\n\nfunction renderSettings(): string {\n const providerOptions = Object.entries(MODEL_REGISTRY)\n .map(([key, p]) => `<option value=\"${key}\" ${state.provider === key ? \"selected\" : \"\"}>${p.name}</option>`)\n .join(\"\");\n\n const currentProvider = MODEL_REGISTRY[state.provider];\n const modelOptions = currentProvider\n ? currentProvider.models.map((m) =>\n `<option value=\"${m.id}\" ${state.model === m.id ? \"selected\" : \"\"}>${m.name}</option>`\n ).join(\"\")\n : '<option value=\"\">Select a provider first</option>';\n\n const keyPlaceholder = currentProvider?.keyPlaceholder || \"Enter API key...\";\n const isLocal = currentProvider?.local || false;\n\n const updateBanner = state.updateAvailable\n ? `<div class=\"om-update-banner\">\n <span>🚀 v${state.latestVersion} available</span>\n <span class=\"om-update-current\">current: v${CURRENT_VERSION}</span>\n <code class=\"om-update-cmd\">npx openmagic@latest</code>\n </div>`\n : \"\";\n\n // Provider → API key page URLs\n const KEY_URLS: Record<string, string> = {\n openai: \"https://platform.openai.com/api-keys\",\n anthropic: \"https://console.anthropic.com/settings/keys\",\n google: \"https://aistudio.google.com/apikey\",\n xai: \"https://console.x.ai/team/default/api-keys\",\n deepseek: \"https://platform.deepseek.com/api_keys\",\n mistral: \"https://console.mistral.ai/api-keys\",\n groq: \"https://console.groq.com/keys\",\n minimax: \"https://platform.minimax.chat/user-center/basic-information/interface-key\",\n moonshot: \"https://platform.moonshot.cn/console/api-keys\",\n qwen: \"https://dashscope.console.aliyun.com/apiKey\",\n zhipu: \"https://open.bigmodel.cn/usercenter/apikeys\",\n doubao: \"https://console.volcengine.com/ark/region:ark+cn-beijing/apiKey\",\n openrouter: \"https://openrouter.ai/settings/keys\",\n };\n\n const keyUrl = KEY_URLS[state.provider] || \"\";\n const providerName = currentProvider?.name || \"provider\";\n\n return `\n <div class=\"om-panel-header\">\n <svg class=\"om-header-icon\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"3\"/><path d=\"M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42\"/></svg>\n <span class=\"om-panel-title\">Settings</span>\n <span class=\"om-panel-version\">v${CURRENT_VERSION}</span>\n <button class=\"om-panel-close\" data-action=\"close\">×</button>\n </div>\n <div class=\"om-panel-body\">\n ${updateBanner}\n <div class=\"om-settings\">\n <div class=\"om-field\">\n <label class=\"om-label\">Provider</label>\n <select class=\"om-select\" data-field=\"provider\">\n <option value=\"\">Select Provider...</option>\n ${providerOptions}\n </select>\n </div>\n\n <div class=\"om-field\">\n <label class=\"om-label\">Model</label>\n <select class=\"om-select\" data-field=\"model\">\n <option value=\"\">Select Model...</option>\n ${modelOptions}\n </select>\n </div>\n\n <div class=\"om-field ${isLocal ? \"om-hidden\" : \"\"}\">\n <label class=\"om-label\">API Key</label>\n <div class=\"om-key-row\">\n <input type=\"password\" class=\"om-input om-key-input\" data-field=\"apiKey\"\n placeholder=\"${keyPlaceholder}\"\n value=\"\" />\n ${keyUrl ? `<button class=\"om-btn-connect\" data-action=\"get-key\" data-url=\"${keyUrl}\" title=\"Get API key from ${providerName}\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\"/><polyline points=\"15 3 21 3 21 9\"/><line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\"/></svg>\n Get key\n </button>` : \"\"}\n </div>\n ${state.provider && !isLocal ? `<div class=\"om-key-hint\">Paste your ${providerName} API key above.${keyUrl ? ` <a data-action=\"get-key\" data-url=\"${keyUrl}\">Get one here →</a>` : \"\"}</div>` : \"\"}\n </div>\n\n <button class=\"om-btn\" data-action=\"save-settings\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z\"/><polyline points=\"17 21 17 13 7 13 7 21\"/><polyline points=\"7 3 7 8 15 8\"/></svg>\n Save\n </button>\n\n ${state.hasApiKey ? `<div class=\"om-status om-status-success\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"/><polyline points=\"22 4 12 14.01 9 11.01\"/></svg>\n Connected\n </div>` : \"\"}\n </div>\n </div>\n `;\n}\n\nfunction renderChat(): string {\n if (!state.hasApiKey || !state.provider) {\n return `\n <div class=\"om-panel-header\">\n <span class=\"om-panel-title\">Chat</span>\n <button class=\"om-panel-close\" data-action=\"close\">×</button>\n </div>\n <div class=\"om-panel-body\">\n <div class=\"om-status om-status-error\">\n Configure your LLM provider in Settings first\n </div>\n </div>\n `;\n }\n\n const messagesHtml = state.messages\n .map((m) => `<div class=\"om-msg om-msg-${m.role}\">${escapeHtml(m.content)}</div>`)\n .join(\"\");\n\n const streamHtml = state.streaming\n ? `<div class=\"om-msg om-msg-assistant\"><div class=\"om-loading\"><div class=\"om-spinner\"></div> Thinking...</div>${escapeHtml(state.streamContent)}</div>`\n : \"\";\n\n const contextChips: string[] = [];\n if (state.selectedElement) {\n contextChips.push(`<span class=\"om-context-chip\">🎯 ${state.selectedElement.tagName}${state.selectedElement.id ? \"#\" + state.selectedElement.id : \"\"} <button class=\"om-context-chip-remove\" data-action=\"clear-element\">×</button></span>`);\n }\n if (state.screenshot) {\n contextChips.push(`<span class=\"om-context-chip\">📸 Screenshot <button class=\"om-context-chip-remove\" data-action=\"clear-screenshot\">×</button></span>`);\n }\n\n return `\n <div class=\"om-panel-header\">\n <span class=\"om-panel-title\">Chat — ${MODEL_REGISTRY[state.provider]?.name || state.provider} / ${state.model}</span>\n <button class=\"om-panel-close\" data-action=\"close\">×</button>\n </div>\n <div class=\"om-panel-body\">\n ${contextChips.length > 0 ? `<div class=\"om-context-bar\">${contextChips.join(\"\")}</div>` : \"\"}\n ${state.selectedElement ? `<div class=\"om-element-info\"><${state.selectedElement.tagName}${state.selectedElement.id ? ' id=\"' + state.selectedElement.id + '\"' : \"\"}${state.selectedElement.className ? ' class=\"' + state.selectedElement.className.toString().slice(0, 60) + '\"' : \"\"}></div>` : \"\"}\n <div class=\"om-chat-messages\">\n ${messagesHtml || '<div style=\"color:#555;text-align:center;padding:40px 0;font-size:13px;\">Select an element or describe what you want to change</div>'}\n ${streamHtml}\n </div>\n <div class=\"om-chat-input-wrap\">\n <textarea class=\"om-chat-input\" placeholder=\"Describe the change you want...\"\n rows=\"1\" ${state.streaming ? \"disabled\" : \"\"}></textarea>\n <button class=\"om-chat-send\" data-action=\"send\" ${state.streaming ? \"disabled\" : \"\"}>\n ${state.streaming ? \"...\" : \"Send\"}\n </button>\n </div>\n </div>\n `;\n}\n\n// --- Event Handlers ---\n\nfunction attachPanelEvents(panel: HTMLElement) {\n // Close button\n panel.querySelector('[data-action=\"close\"]')?.addEventListener(\"click\", () => {\n state.panelOpen = false;\n state.activePanel = null;\n render();\n });\n\n // Settings: provider change\n panel.querySelector('[data-field=\"provider\"]')?.addEventListener(\"change\", (e) => {\n state.provider = (e.target as HTMLSelectElement).value;\n state.model = \"\";\n render();\n });\n\n // Settings: model change\n panel.querySelector('[data-field=\"model\"]')?.addEventListener(\"change\", (e) => {\n state.model = (e.target as HTMLSelectElement).value;\n });\n\n // Settings: \"Get key\" button — opens provider's API key page\n panel.querySelectorAll('[data-action=\"get-key\"]').forEach((el) => {\n el.addEventListener(\"click\", (e) => {\n e.preventDefault();\n const url = (el as HTMLElement).dataset.url;\n if (url) window.open(url, \"_blank\", \"noopener\");\n });\n });\n\n // Settings: save\n panel.querySelector('[data-action=\"save-settings\"]')?.addEventListener(\"click\", () => {\n const apiKeyInput = panel.querySelector('[data-field=\"apiKey\"]') as HTMLInputElement;\n const apiKey = apiKeyInput?.value || \"\";\n\n const payload: any = {\n provider: state.provider,\n model: state.model,\n };\n if (apiKey) {\n payload.apiKey = apiKey;\n }\n\n ws.request(\"config.set\", payload).then(() => {\n state.hasApiKey = true;\n render();\n }).catch((e: Error) => {\n console.error(\"[OpenMagic] Failed to save config:\", e);\n });\n });\n\n // Chat: send\n panel.querySelector('[data-action=\"send\"]')?.addEventListener(\"click\", () => {\n sendMessage(panel);\n });\n\n // Chat: enter to send\n const input = panel.querySelector(\".om-chat-input\") as HTMLTextAreaElement;\n input?.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n sendMessage(panel);\n }\n });\n\n // Auto-resize textarea\n input?.addEventListener(\"input\", () => {\n input.style.height = \"auto\";\n input.style.height = Math.min(input.scrollHeight, 120) + \"px\";\n });\n\n // Clear context\n panel.querySelector('[data-action=\"clear-element\"]')?.addEventListener(\"click\", () => {\n state.selectedElement = null;\n render();\n });\n\n panel.querySelector('[data-action=\"clear-screenshot\"]')?.addEventListener(\"click\", () => {\n state.screenshot = null;\n render();\n });\n}\n\nasync function sendMessage(panel: HTMLElement) {\n const input = panel.querySelector(\".om-chat-input\") as HTMLTextAreaElement;\n if (!input) return;\n\n const text = input.value.trim();\n if (!text || state.streaming) return;\n\n // Add user message\n state.messages.push({ role: \"user\", content: text });\n state.streaming = true;\n state.streamContent = \"\";\n render();\n\n // Build context\n const context = buildContext(state.selectedElement, state.screenshot);\n\n try {\n const result = await ws.stream(\n \"llm.chat\",\n {\n provider: state.provider,\n model: state.model,\n messages: state.messages.map((m) => ({ role: m.role, content: m.content })),\n context,\n },\n (chunk: string) => {\n state.streamContent += chunk;\n // Update streaming message in place\n const msgContainer = shadow.querySelector(\".om-chat-messages\");\n const streamEl = msgContainer?.querySelector(\".om-msg-assistant:last-child\");\n if (streamEl) {\n streamEl.innerHTML = escapeHtml(state.streamContent);\n }\n }\n );\n\n // Add assistant message\n state.messages.push({ role: \"assistant\", content: state.streamContent || result?.content || \"\" });\n\n // Handle modifications\n if (result?.modifications && result.modifications.length > 0) {\n for (const mod of result.modifications) {\n if (mod.type === \"edit\" && mod.file && mod.search && mod.replace) {\n // Read the file first\n try {\n const fileResult = await ws.request(\"fs.read\", { path: resolveFilePath(mod.file) });\n const content = fileResult.payload?.content;\n if (content && content.includes(mod.search)) {\n const newContent = content.replace(mod.search, mod.replace);\n await ws.request(\"fs.write\", { path: resolveFilePath(mod.file), content: newContent });\n state.messages.push({\n role: \"system\",\n content: `Applied change to ${mod.file}`,\n });\n }\n } catch (e: any) {\n state.messages.push({\n role: \"system\",\n content: `Failed to apply change to ${mod.file}: ${e.message}`,\n });\n }\n }\n }\n }\n } catch (e: any) {\n state.messages.push({ role: \"system\", content: `Error: ${e.message}` });\n }\n\n state.streaming = false;\n state.streamContent = \"\";\n render();\n}\n\nfunction resolveFilePath(relativePath: string): string {\n // Resolve relative to first root\n if (state.roots.length > 0) {\n return state.roots[0] + \"/\" + relativePath;\n }\n return relativePath;\n}\n\n// --- Select Mode ---\n\nlet selectHandler: ((e: MouseEvent) => void) | null = null;\nlet hoverHandler: ((e: MouseEvent) => void) | null = null;\n\nfunction toggleSelectMode() {\n if (state.selecting) {\n exitSelectMode();\n } else {\n enterSelectMode();\n }\n}\n\nfunction enterSelectMode() {\n state.selecting = true;\n document.body.style.cursor = \"crosshair\";\n\n hoverHandler = (e: MouseEvent) => {\n const target = e.target as HTMLElement;\n if (isOpenMagicElement(target)) return;\n const rect = target.getBoundingClientRect();\n showHighlight({\n x: rect.x,\n y: rect.y,\n width: rect.width,\n height: rect.height,\n });\n };\n\n selectHandler = (e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n const target = e.target as HTMLElement;\n if (isOpenMagicElement(target)) return;\n\n state.selectedElement = inspectElement(target);\n exitSelectMode();\n\n // Open chat if not open\n if (state.activePanel !== \"chat\") {\n state.panelOpen = true;\n state.activePanel = \"chat\";\n }\n\n render();\n };\n\n document.addEventListener(\"mousemove\", hoverHandler, true);\n document.addEventListener(\"click\", selectHandler, true);\n\n render();\n}\n\nfunction exitSelectMode() {\n state.selecting = false;\n document.body.style.cursor = \"\";\n hideHighlight();\n\n if (hoverHandler) {\n document.removeEventListener(\"mousemove\", hoverHandler, true);\n hoverHandler = null;\n }\n if (selectHandler) {\n document.removeEventListener(\"click\", selectHandler, true);\n selectHandler = null;\n }\n\n render();\n}\n\n// --- Screenshot ---\n\nasync function takeScreenshot() {\n const screenshot = await captureScreenshot();\n if (screenshot) {\n state.screenshot = screenshot;\n // Open chat\n state.panelOpen = true;\n state.activePanel = \"chat\";\n render();\n }\n}\n\n// --- Panel Toggle ---\n\nfunction togglePanel(panel: \"chat\" | \"settings\") {\n if (state.panelOpen && state.activePanel === panel) {\n state.panelOpen = false;\n state.activePanel = null;\n } else {\n state.panelOpen = true;\n state.activePanel = panel;\n }\n render();\n}\n\n// --- Draggable ---\n\nfunction makeDraggable(el: HTMLElement) {\n let isDragging = false;\n let startX = 0;\n let startY = 0;\n let origX = 0;\n let origY = 0;\n\n el.addEventListener(\"mousedown\", (e) => {\n // Only drag from the grab handle or brand area, not buttons\n const target = e.target as HTMLElement;\n if (target.closest(\".om-pill-btn\")) return;\n if (!target.closest(\".om-grab\") && !target.closest(\".om-pill-brand\")) return;\n\n isDragging = true;\n startX = e.clientX;\n startY = e.clientY;\n const rect = el.getBoundingClientRect();\n origX = rect.left;\n origY = rect.top;\n e.preventDefault();\n });\n\n document.addEventListener(\"mousemove\", (e) => {\n if (!isDragging) return;\n const dx = e.clientX - startX;\n const dy = e.clientY - startY;\n el.style.position = \"fixed\";\n el.style.left = origX + dx + \"px\";\n el.style.top = origY + dy + \"px\";\n el.style.right = \"auto\";\n el.style.bottom = \"auto\";\n });\n\n document.addEventListener(\"mouseup\", () => {\n isDragging = false;\n });\n}\n\n// --- Helpers ---\n\nfunction isOpenMagicElement(el: HTMLElement): boolean {\n return !!el.closest(\"openmagic-toolbar\") || !!el.dataset?.openmagic;\n}\n\nfunction escapeHtml(text: string): string {\n const div = document.createElement(\"div\");\n div.textContent = text;\n return div.innerHTML;\n}\n\n// --- Update Check ---\n\nfunction checkForUpdates(): void {\n // Query npm registry for latest version (non-blocking, silent fail)\n fetch(\"https://registry.npmjs.org/openmagic/latest\", {\n headers: { Accept: \"application/json\" },\n signal: AbortSignal.timeout(5000),\n })\n .then((res) => {\n if (!res.ok) return;\n return res.json();\n })\n .then((data) => {\n if (!data?.version) return;\n const latest = data.version;\n if (isNewerVersion(latest, CURRENT_VERSION)) {\n state.updateAvailable = true;\n state.latestVersion = latest;\n render();\n }\n })\n .catch(() => {\n // Silently ignore — update check is best-effort\n });\n}\n\nfunction isNewerVersion(latest: string, current: string): boolean {\n const l = latest.split(\".\").map(Number);\n const c = current.split(\".\").map(Number);\n for (let i = 0; i < 3; i++) {\n if ((l[i] || 0) > (c[i] || 0)) return true;\n if ((l[i] || 0) < (c[i] || 0)) return false;\n }\n return false;\n}\n\n// --- Boot ---\nif (typeof window !== \"undefined\") {\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", init);\n } else {\n init();\n }\n}\n"],"mappings":";wCACO,IAAMA,EAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ECC3B,IAAIC,EAAuB,KACvBC,EAAwC,IAAI,IAC5CC,EAAyC,CAAC,EAC1CC,EAAyB,CAAC,EAC1BC,EAAY,GACZC,EAAuD,KAE3D,SAASC,GAAqB,CAC5B,OAAO,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,EAAI,KAAK,IAAI,EAAE,SAAS,EAAE,CACrE,CAEO,SAASC,EAAQC,EAAcC,EAA8B,CAClE,OAAO,IAAI,QAAQ,CAACC,EAASC,IAAW,CACtC,GAAI,CACFX,EAAK,IAAI,UAAU,kBAAkBQ,CAAI,mBAAmB,EAE5DR,EAAG,OAAS,IAAM,CAEhB,IAAMY,EAAcN,EAAW,EAC/BO,EAAK,CAAE,GAAID,EAAa,KAAM,YAAa,QAAS,CAAE,MAAAH,CAAM,CAAE,CAAC,EAG/DR,EAAS,IAAIW,EAAcE,GAAQ,CACjC,GAAIA,EAAI,OAAS,eAAgB,CAC/BV,EAAY,GAEZ,QAAWW,KAAUZ,EACnBH,GAAI,KAAKe,CAAM,EAEjBZ,EAAe,CAAC,EAChBO,EAAQ,CACV,MAAWI,EAAI,OAAS,SACtBH,EAAO,IAAI,MAAMG,EAAI,SAAS,SAAW,kBAAkB,CAAC,CAEhE,CAAC,CACH,EAEAd,EAAG,UAAagB,GAAU,CACxB,GAAI,CACF,IAAMF,EAAM,KAAK,MAAME,EAAM,IAAI,EAG7BF,EAAI,IAAMb,EAAS,IAAIa,EAAI,EAAE,IACfb,EAAS,IAAIa,EAAI,EAAE,EAC3BA,CAAG,GAEPA,EAAI,OAAS,YAAcA,EAAI,OAAS,aAAe,CAACA,EAAI,KAAK,WAAW,MAAM,IACpFb,EAAS,OAAOa,EAAI,EAAE,GAK1B,QAAWG,KAAWf,EACpBe,EAAQH,CAAG,CAEf,MAAQ,CAER,CACF,EAEAd,EAAG,QAAU,IAAM,CACjBI,EAAY,GAEPC,IACHA,EAAiB,WAAW,IAAM,CAChCA,EAAiB,KACjBE,EAAQC,EAAMC,CAAK,EAAE,MAAM,IAAM,CAAC,CAAC,CACrC,EAAG,GAAI,EAEX,EAEAT,EAAG,QAAU,IAAM,CAEnB,CACF,OAASkB,EAAG,CACVP,EAAOO,CAAC,CACV,CACF,CAAC,CACH,CAEO,SAASL,EAAKC,EAAwD,CAC3E,IAAMK,EAAO,KAAK,UAAUL,CAAG,EAC3Bd,GAAMI,EACRJ,EAAG,KAAKmB,CAAI,EAEZhB,EAAa,KAAKgB,CAAI,CAE1B,CAEO,SAASC,EAAQC,EAAcC,EAA6B,CACjE,OAAO,IAAI,QAAQ,CAACZ,EAASC,IAAW,CACtC,IAAMY,EAAKjB,EAAW,EAChBkB,EAAU,WAAW,IAAM,CAC/BvB,EAAS,OAAOsB,CAAE,EAClBZ,EAAO,IAAI,MAAM,iBAAiB,CAAC,CACrC,EAAG,GAAK,EAERV,EAAS,IAAIsB,EAAKT,GAAQ,CACxB,aAAaU,CAAO,EAChBV,EAAI,OAAS,QACfH,EAAO,IAAI,MAAMG,EAAI,SAAS,SAAW,eAAe,CAAC,EAEzDJ,EAAQI,CAAG,CAEf,CAAC,EAEDD,EAAK,CAAE,GAAAU,EAAI,KAAAF,EAAM,QAAAC,CAAQ,CAAC,CAC5B,CAAC,CACH,CAEO,SAASG,EACdJ,EACAC,EACAI,EACc,CACd,OAAO,IAAI,QAAQ,CAAChB,EAASC,IAAW,CACtC,IAAMY,EAAKjB,EAAW,EAChBkB,EAAU,WAAW,IAAM,CAC/BvB,EAAS,OAAOsB,CAAE,EAClBZ,EAAO,IAAI,MAAM,gBAAgB,CAAC,CACpC,EAAG,IAAM,EAETV,EAAS,IAAIsB,EAAKT,GAAQ,CACpBA,EAAI,OAAS,YACfY,EAAQZ,EAAI,SAAS,OAAS,EAAE,EACvBA,EAAI,OAAS,YACtB,aAAaU,CAAO,EACpBvB,EAAS,OAAOsB,CAAE,EAClBb,EAAQI,EAAI,OAAO,IACVA,EAAI,OAAS,aAAeA,EAAI,OAAS,WAClD,aAAaU,CAAO,EACpBvB,EAAS,OAAOsB,CAAE,EAClBZ,EAAO,IAAI,MAAMG,EAAI,SAAS,SAAW,cAAc,CAAC,EAE5D,CAAC,EAEDD,EAAK,CAAE,GAAAU,EAAI,KAAAF,EAAM,QAAAC,CAAQ,CAAC,CAC5B,CAAC,CACH,CChIA,IAAMK,GAAmB,CACvB,UACA,WACA,QACA,SACA,SACA,UACA,QACA,mBACA,aACA,YACA,cACA,cACA,SACA,gBACA,aACA,iBACA,kBACA,cACA,MACA,wBACA,qBACA,WACA,UACA,UACA,aACA,cACA,gBACF,EAEO,SAASC,EAAeC,EAAkC,CAC/D,IAAMC,EAAW,OAAO,iBAAiBD,CAAE,EACrCE,EAAiC,CAAC,EACxC,QAAWC,KAAQL,GACjBI,EAAOC,CAAI,EAAIF,EAAS,iBAAiBE,CAAI,EAG/C,IAAMC,EAAOJ,EAAG,sBAAsB,EAEtC,MAAO,CACL,QAASA,EAAG,QAAQ,YAAY,EAChC,GAAIA,EAAG,IAAM,GACb,UAAWA,EAAG,WAAa,GAC3B,aAAcA,EAAG,aAAe,IAAI,KAAK,EAAE,MAAM,EAAG,GAAG,EACvD,UAAWK,GAAkBL,CAAE,EAC/B,YAAaM,GAAeN,CAAE,EAC9B,MAAOO,GAASP,CAAE,EAClB,eAAgBE,EAChB,KAAM,CACJ,EAAGE,EAAK,EACR,EAAGA,EAAK,EACR,MAAOA,EAAK,MACZ,OAAQA,EAAK,MACf,CACF,CACF,CAEA,SAASC,GAAkBL,EAAyB,CAClD,IAAMQ,EAAQR,EAAG,UAAU,EAAI,EAGfQ,EAAM,iBAAiB,oBAAoB,EACnD,QAASC,GAAMA,EAAE,OAAO,CAAC,EAGjC,IAAIC,EAAOF,EAAM,UACjB,GAAIE,EAAK,OAAS,IAAM,CAEtB,IAAMC,EAAMX,EAAG,QAAQ,YAAY,EAC7BY,EAAQ,MAAM,KAAKZ,EAAG,UAAU,EACnC,IAAKa,GAAM,GAAGA,EAAE,IAAI,KAAKA,EAAE,KAAK,GAAG,EACnC,KAAK,GAAG,EACLC,EAAe,MAAM,KAAKd,EAAG,QAAQ,EACxC,MAAM,EAAG,CAAC,EACV,IAAKe,GAAM,IAAIA,EAAE,QAAQ,YAAY,CAAC,QAAQ,EAC9C,KAAK;AAAA,GAAM,EACdL,EAAO,IAAIC,CAAG,IAAIC,CAAK;AAAA,IAAQE,CAAY;AAAA,IAAOd,EAAG,SAAS,OAAS,EAAI,SAASA,EAAG,SAAS,OAAS,CAAC,qBAAuB,EAAE;AAAA,IAAOW,CAAG,GAC/I,CAEA,OAAOD,CACT,CAEA,SAASJ,GAAeN,EAAyB,CAC/C,GAAIA,EAAG,GAAI,MAAO,IAAIA,EAAG,EAAE,GAE3B,IAAMgB,EAAkB,CAAC,EACrBC,EAA8BjB,EAElC,KAAOiB,GAAWA,IAAY,SAAS,MAAM,CAC3C,IAAIC,EAAWD,EAAQ,QAAQ,YAAY,EAE3C,GAAIA,EAAQ,GAAI,CACdD,EAAM,QAAQ,IAAIC,EAAQ,EAAE,EAAE,EAC9B,KACF,CAEA,GAAIA,EAAQ,WAAa,OAAOA,EAAQ,WAAc,SAAU,CAC9D,IAAME,EAAUF,EAAQ,UACrB,KAAK,EACL,MAAM,KAAK,EACX,OAAQF,GAAM,CAACA,EAAE,WAAW,IAAI,GAAKA,EAAE,OAAS,EAAE,EAClD,MAAM,EAAG,CAAC,EACTI,EAAQ,OAAS,IACnBD,GAAY,IAAMC,EAAQ,KAAK,GAAG,EAEtC,CAGA,IAAMC,EAASH,EAAQ,cACvB,GAAIG,EAAQ,CACV,IAAMC,EAAW,MAAM,KAAKD,EAAO,QAAQ,EAAE,OAC1C,GAAM,EAAE,UAAYH,EAAS,OAChC,EACA,GAAII,EAAS,OAAS,EAAG,CACvB,IAAMC,EAAQD,EAAS,QAAQJ,CAAO,EAAI,EAC1CC,GAAY,cAAcI,CAAK,GACjC,CACF,CAEAN,EAAM,QAAQE,CAAQ,EACtBD,EAAUA,EAAQ,aACpB,CAEA,OAAOD,EAAM,KAAK,KAAK,CACzB,CAEA,SAAST,GAASP,EAAyB,CACzC,IAAMgB,EAAkB,CAAC,EACrBC,EAAuBjB,EAE3B,KAAOiB,GAAWA,IAAY,UAAU,CACtC,GAAIA,EAAQ,WAAa,KAAK,aAAc,CAC1C,IAAMM,EAAUN,EACZK,EAAQ,EACRE,EAAUD,EAAQ,uBACtB,KAAOC,GACDA,EAAQ,UAAYD,EAAQ,SAASD,IACzCE,EAAUA,EAAQ,uBAEpBR,EAAM,QAAQ,GAAGO,EAAQ,QAAQ,YAAY,CAAC,IAAID,CAAK,GAAG,CAC5D,CACAL,EAAUA,EAAQ,UACpB,CAEA,MAAO,IAAMD,EAAM,KAAK,GAAG,CAC7B,CAIA,IAAIS,EAAqC,KAElC,SAASC,EAActB,EAKrB,CACFqB,IACHA,EAAc,SAAS,cAAc,KAAK,EAC1CA,EAAY,MAAM,QAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQ5BA,EAAY,QAAQ,UAAY,YAChC,SAAS,KAAK,YAAYA,CAAW,GAGvCA,EAAY,MAAM,KAAO,GAAGrB,EAAK,CAAC,KAClCqB,EAAY,MAAM,IAAM,GAAGrB,EAAK,CAAC,KACjCqB,EAAY,MAAM,MAAQ,GAAGrB,EAAK,KAAK,KACvCqB,EAAY,MAAM,OAAS,GAAGrB,EAAK,MAAM,KACzCqB,EAAY,MAAM,QAAU,OAC9B,CAEO,SAASE,GAAsB,CAChCF,IACFA,EAAY,MAAM,QAAU,OAEhC,CC/LA,eAAsBG,EACpBC,EACwB,CACxB,GAAI,CAEF,OAAIA,EACK,MAAMC,GAAwBD,CAAM,EAItC,MAAME,GAAgB,CAC/B,OAASC,EAAG,CACV,eAAQ,KAAK,yCAA0CA,CAAC,EACjD,IACT,CACF,CAEA,eAAeD,IAA0C,CAEvD,IAAME,EAAS,SAAS,cAAc,QAAQ,EACxCC,EAAM,OAAO,kBAAoB,EACvCD,EAAO,MAAQ,OAAO,WAAaC,EACnCD,EAAO,OAAS,OAAO,YAAcC,EACrC,IAAMC,EAAMF,EAAO,WAAW,IAAI,EAClCE,EAAI,MAAMD,EAAKA,CAAG,EAIlB,GAAI,CACF,IAAME,EAAU,MAAMC,EAAa,SAAS,IAAI,EAC1CC,EAAM,MAAMC,EAAWH,EAAS,OAAO,WAAY,OAAO,WAAW,EAC3E,OAAAD,EAAI,UAAUG,EAAK,EAAG,CAAC,EAChBL,EAAO,UAAU,WAAW,CACrC,MAAQ,CACN,OAAO,IACT,CACF,CAEA,eAAeH,GACbU,EACwB,CACxB,IAAMC,EAAOD,EAAQ,sBAAsB,EACrCP,EAAS,SAAS,cAAc,QAAQ,EACxCC,EAAM,OAAO,kBAAoB,EACvCD,EAAO,MAAQQ,EAAK,MAAQP,EAC5BD,EAAO,OAASQ,EAAK,OAASP,EAC9B,IAAMC,EAAMF,EAAO,WAAW,IAAI,EAClCE,EAAI,MAAMD,EAAKA,CAAG,EAElB,GAAI,CACF,IAAME,EAAU,MAAMC,EAAaG,CAAO,EACpCF,EAAM,MAAMC,EAAWH,EAASK,EAAK,MAAOA,EAAK,MAAM,EAC7D,OAAAN,EAAI,UAAUG,EAAK,EAAG,CAAC,EAChBL,EAAO,UAAU,WAAW,CACrC,MAAQ,CACN,OAAO,IACT,CACF,CAEA,SAASI,EAAaG,EAAuC,CAC3D,OAAO,IAAI,QAASE,GAAY,CAC9B,IAAMC,EAAQH,EAAQ,UAAU,EAAI,EAGpCI,EAAaJ,EAASG,CAAK,EAE3B,IAAMF,EAAOD,EAAQ,sBAAsB,EACrCK,EAAQJ,EAAK,MACbK,EAASL,EAAK,OAEdM,EAAgB;AAAA,uDAC6BF,CAAK,aAAaC,CAAM;AAAA;AAAA,mEAEZD,CAAK,aAAaC,CAAM;AAAA,cAC7EH,EAAM,SAAS;AAAA;AAAA;AAAA,cAKzBD,EAAQK,CAAa,CACvB,CAAC,CACH,CAEA,SAASH,EAAaI,EAAqBnB,EAA2B,CACpE,IAAMoB,EAAW,OAAO,iBAAiBD,CAAM,EAC3CE,EAAU,GACd,QAASC,EAAI,EAAGA,EAAIF,EAAS,OAAQE,IAAK,CACxC,IAAMC,EAAOH,EAASE,CAAC,EACvBD,GAAW,GAAGE,CAAI,IAAIH,EAAS,iBAAiBG,CAAI,CAAC,GACvD,CACAvB,EAAO,MAAM,QAAUqB,EAEvB,IAAMG,EAAiBL,EAAO,SACxBM,EAAiBzB,EAAO,SAC9B,QAASsB,EAAI,EAAGA,EAAIE,EAAe,QAAUF,EAAIG,EAAe,OAAQH,IACtEP,EACES,EAAeF,CAAC,EAChBG,EAAeH,CAAC,CAClB,CAEJ,CAEA,SAASZ,EACPH,EACAS,EACAC,EAC2B,CAC3B,OAAO,IAAI,QAAQ,CAACJ,EAASa,IAAW,CACtC,IAAMjB,EAAM,IAAI,MACVkB,EAAO,IAAI,KAAK,CAACpB,CAAO,EAAG,CAAE,KAAM,6BAA8B,CAAC,EAClEqB,EAAM,IAAI,gBAAgBD,CAAI,EAEpClB,EAAI,OAAS,IAAM,CACjB,IAAI,gBAAgBmB,CAAG,EACvBf,EAAQJ,CAAG,CACb,EACAA,EAAI,QAAU,IAAM,CAClB,IAAI,gBAAgBmB,CAAG,EACvBF,EAAO,IAAI,MAAM,0BAA0B,CAAC,CAC9C,EAEAjB,EAAI,MAAQO,EACZP,EAAI,OAASQ,EACbR,EAAI,IAAMmB,CACZ,CAAC,CACH,CCpHA,IAAMC,EAA8B,CAAC,EAGrC,IAAIC,EAA0B,GAEvB,SAASC,GAA8B,CAC5C,GAAID,EAAyB,OAC7BA,EAA0B,GAG1B,IAAME,EAAgB,OAAO,MAC7B,OAAO,MAAQ,kBAAmBC,EAAM,CACtC,IAAMC,EAAU,IAAI,QAAQ,GAAGD,CAAI,EAC7BE,EAAsB,CAC1B,OAAQD,EAAQ,OAChB,IAAKA,EAAQ,IACb,UAAW,KAAK,IAAI,CACtB,EAEA,GAAI,CACF,IAAME,EAAW,MAAMJ,EAAc,MAAM,KAAMC,CAAI,EACrD,OAAAE,EAAM,OAASC,EAAS,OACxBD,EAAM,SAAW,KAAK,IAAI,EAAIA,EAAM,UACpCE,EAAgBF,CAAK,EACdC,CACT,OAASE,EAAG,CACV,MAAAH,EAAM,OAAS,EACfA,EAAM,SAAW,KAAK,IAAI,EAAIA,EAAM,UACpCE,EAAgBF,CAAK,EACfG,CACR,CACF,EAGA,IAAMC,EAAe,eAAe,UAAU,KACxCC,EAAe,eAAe,UAAU,KAE9C,eAAe,UAAU,KAAO,SAAUC,EAAgBC,KAAgBC,EAAa,CACrF,OAAC,KAAa,YAAcF,EAC3B,KAAa,SAAWC,EACxB,KAAa,WAAa,KAAK,IAAI,EAC7BH,EAAa,MAAM,KAAM,CAACE,EAAQC,EAAK,GAAGC,CAAI,CAAQ,CAC/D,EAEA,eAAe,UAAU,KAAO,YAAaV,EAAM,CACjD,YAAK,iBAAiB,UAAW,IAAM,CACrCI,EAAgB,CACd,OAAS,KAAa,aAAe,MACrC,IAAM,KAAa,UAAY,GAC/B,OAAQ,KAAK,OACb,SAAU,KAAK,IAAI,GAAM,KAAa,YAAc,KAAK,IAAI,GAC7D,UAAY,KAAa,YAAc,KAAK,IAAI,CAClD,CAAC,CACH,CAAC,EACMG,EAAa,MAAM,KAAMP,CAAI,CACtC,CACF,CAEA,SAASI,EAAgBF,EAA2B,CAE9CA,EAAM,IAAI,SAAS,eAAe,IACtCS,EAAY,KAAKT,CAAK,EAClBS,EAAY,OAAS,IACvBA,EAAY,MAAM,EAEtB,CAEO,SAASC,IAAiC,CAC/C,MAAO,CAAC,GAAGD,CAAW,CACxB,CAcA,IAAME,EAA8B,CAAC,EAC/BC,GAAmB,IAErBC,EAA0B,GAEvB,SAASC,GAA8B,CAC5C,GAAID,EAAyB,OAC7BA,EAA0B,GAE1B,IAAME,EAAkC,CAAC,MAAO,OAAQ,QAAS,OAAQ,OAAO,EAEhF,QAAWC,KAASD,EAAQ,CAC1B,IAAME,EAAW,QAAQD,CAAK,EAC9B,QAAQA,CAAK,EAAI,YAAaE,EAAa,CACzCP,EAAY,KAAK,CACf,MAAAK,EACA,KAAME,EAAK,IAAKC,GAAM,CACpB,GAAI,CACF,OAAO,OAAOA,GAAM,SAAW,KAAK,UAAUA,CAAC,EAAE,MAAM,EAAG,GAAG,EAAI,OAAOA,CAAC,CAC3E,MAAQ,CACN,OAAO,OAAOA,CAAC,CACjB,CACF,CAAC,EACD,UAAW,KAAK,IAAI,CACtB,CAAC,EAEGR,EAAY,OAASC,IACvBD,EAAY,MAAM,EAGpBM,EAAS,MAAM,QAASC,CAAI,CAC9B,CACF,CACF,CAEO,SAASE,IAAiC,CAC/C,MAAO,CAAC,GAAGT,CAAW,CACxB,CAQO,SAASU,EACdC,EACAC,EACA,CACA,MAAO,CACL,gBAAiBD,EACb,CACE,QAASA,EAAgB,QACzB,GAAIA,EAAgB,GACpB,UAAWA,EAAgB,UAC3B,YAAaA,EAAgB,YAC7B,UAAWA,EAAgB,UAC3B,YAAaA,EAAgB,YAC7B,eAAgBA,EAAgB,cAClC,EACA,OACJ,WAAYC,GAAc,OAC1B,YAAaC,GAAe,EAAE,IAAKC,IAAO,CACxC,OAAQA,EAAE,OACV,IAAKA,EAAE,IACP,OAAQA,EAAE,OACV,SAAUA,EAAE,SACZ,UAAWA,EAAE,SACf,EAAE,EACF,YAAaC,GAAe,EAAE,IAAKD,IAAO,CACxC,MAAOA,EAAE,MACT,KAAMA,EAAE,KACR,UAAWA,EAAE,SACf,EAAE,CACJ,CACF,CCzJA,IAAME,EAAoI,CACxI,OAAQ,CAAE,KAAM,SAAU,OAAQ,CAChC,CAAE,GAAI,UAAW,KAAM,SAAU,EACjC,CAAE,GAAI,cAAe,KAAM,aAAc,EACzC,CAAE,GAAI,eAAgB,KAAM,cAAe,EAC3C,CAAE,GAAI,eAAgB,KAAM,cAAe,EAC3C,CAAE,GAAI,UAAW,KAAM,kBAAmB,EAC1C,CAAE,GAAI,cAAe,KAAM,aAAc,EACzC,CAAE,GAAI,KAAM,KAAM,gBAAiB,EACnC,CAAE,GAAI,UAAW,KAAM,qBAAsB,EAC7C,CAAE,GAAI,UAAW,KAAM,SAAU,EACjC,CAAE,GAAI,eAAgB,KAAM,cAAe,EAC3C,CAAE,GAAI,oBAAqB,KAAM,YAAa,CAChD,EAAG,eAAgB,QAAS,EAC5B,UAAW,CAAE,KAAM,YAAa,OAAQ,CACtC,CAAE,GAAI,kBAAmB,KAAM,iBAAkB,EACjD,CAAE,GAAI,oBAAqB,KAAM,mBAAoB,EACrD,CAAE,GAAI,4BAA6B,KAAM,kBAAmB,EAC5D,CAAE,GAAI,6BAA8B,KAAM,mBAAoB,EAC9D,CAAE,GAAI,2BAA4B,KAAM,iBAAkB,EAC1D,CAAE,GAAI,2BAA4B,KAAM,iBAAkB,EAC1D,CAAE,GAAI,yBAA0B,KAAM,eAAgB,CACxD,EAAG,eAAgB,YAAa,EAChC,OAAQ,CAAE,KAAM,gBAAiB,OAAQ,CACvC,CAAE,GAAI,yBAA0B,KAAM,gBAAiB,EACvD,CAAE,GAAI,yBAA0B,KAAM,gBAAiB,EACvD,CAAE,GAAI,gCAAiC,KAAM,uBAAwB,EACrE,CAAE,GAAI,iBAAkB,KAAM,gBAAiB,EAC/C,CAAE,GAAI,mBAAoB,KAAM,kBAAmB,EACnD,CAAE,GAAI,wBAAyB,KAAM,uBAAwB,CAC/D,EAAG,eAAgB,SAAU,EAC7B,IAAK,CAAE,KAAM,aAAc,OAAQ,CACjC,CAAE,GAAI,2BAA4B,KAAM,qBAAsB,EAC9D,CAAE,GAAI,+BAAgC,KAAM,WAAY,EACxD,CAAE,GAAI,0BAA2B,KAAM,yBAA0B,EACjE,CAAE,GAAI,8BAA+B,KAAM,eAAgB,CAC7D,EAAG,eAAgB,SAAU,EAC7B,SAAU,CAAE,KAAM,WAAY,OAAQ,CACpC,CAAE,GAAI,gBAAiB,KAAM,eAAgB,EAC7C,CAAE,GAAI,oBAAqB,KAAM,aAAc,CACjD,EAAG,eAAgB,QAAS,EAC5B,QAAS,CAAE,KAAM,UAAW,OAAQ,CAClC,CAAE,GAAI,wBAAyB,KAAM,iBAAkB,EACvD,CAAE,GAAI,0BAA2B,KAAM,iBAAkB,EACzD,CAAE,GAAI,iBAAkB,KAAM,WAAY,EAC1C,CAAE,GAAI,mBAAoB,KAAM,YAAa,EAC7C,CAAE,GAAI,6BAA8B,KAAM,kBAAmB,CAC/D,EAAG,eAAgB,KAAM,EACzB,KAAM,CAAE,KAAM,OAAQ,OAAQ,CAC5B,CAAE,GAAI,4CAA6C,KAAM,mBAAoB,EAC7E,CAAE,GAAI,0BAA2B,KAAM,eAAgB,EACvD,CAAE,GAAI,uBAAwB,KAAM,sBAAuB,EAC3D,CAAE,GAAI,iBAAkB,KAAM,YAAa,CAC7C,EAAG,eAAgB,SAAU,EAC7B,QAAS,CAAE,KAAM,UAAW,OAAQ,CAClC,CAAE,GAAI,eAAgB,KAAM,cAAe,EAC3C,CAAE,GAAI,yBAA0B,KAAM,gBAAiB,EACvD,CAAE,GAAI,eAAgB,KAAM,cAAe,CAC7C,EAAG,eAAgB,gBAAiB,EACpC,SAAU,CAAE,KAAM,kBAAmB,OAAQ,CAC3C,CAAE,GAAI,YAAa,KAAM,WAAY,EACrC,CAAE,GAAI,mBAAoB,KAAM,kBAAmB,CACrD,EAAG,eAAgB,iBAAkB,EACrC,KAAM,CAAE,KAAM,iBAAkB,OAAQ,CACtC,CAAE,GAAI,eAAgB,KAAM,eAAgB,EAC5C,CAAE,GAAI,WAAY,KAAM,UAAW,EACnC,CAAE,GAAI,aAAc,KAAM,YAAa,CACzC,EAAG,eAAgB,kBAAmB,EACtC,MAAO,CAAE,KAAM,iBAAkB,OAAQ,CACvC,CAAE,GAAI,QAAS,KAAM,OAAQ,EAC7B,CAAE,GAAI,UAAW,KAAM,SAAU,EACjC,CAAE,GAAI,UAAW,KAAM,SAAU,CACnC,EAAG,eAAgB,cAAe,EAClC,OAAQ,CAAE,KAAM,qBAAsB,OAAQ,CAC5C,CAAE,GAAI,sBAAuB,KAAM,qBAAsB,EACzD,CAAE,GAAI,uBAAwB,KAAM,sBAAuB,CAC7D,EAAG,eAAgB,gBAAiB,EACpC,OAAQ,CAAE,KAAM,iBAAkB,OAAQ,CAAC,EAAG,eAAgB,eAAgB,MAAO,EAAK,EAC1F,WAAY,CAAE,KAAM,aAAc,OAAQ,CAAC,EAAG,eAAgB,WAAY,CAC5E,EAEMC,EAAkB,QAqBlBC,EAAkB,CACtB,UAAW,GACX,UAAW,GACX,YAAa,KACb,UAAW,GACX,gBAAiB,KACjB,WAAY,KACZ,SAAU,CAAC,EACX,UAAW,GACX,cAAe,GACf,SAAU,GACV,MAAO,GACP,UAAW,GACX,MAAO,CAAC,EACR,gBAAiB,GACjB,cAAe,EACjB,EAGIC,EACAC,EAGJ,SAASC,GAAO,CAEd,GAAI,SAAS,cAAc,mBAAmB,EAAG,OAGjD,IAAMC,EAAO,SAAS,cAAc,mBAAmB,EACvDA,EAAK,QAAQ,UAAY,OACzBH,EAASG,EAAK,aAAa,CAAE,KAAM,QAAS,CAAC,EAG7C,IAAMC,EAAQ,SAAS,cAAc,OAAO,EAC5CA,EAAM,YAAcC,EACpBL,EAAO,YAAYI,CAAK,EAGxBH,EAAY,SAAS,cAAc,KAAK,EACxCD,EAAO,YAAYC,CAAS,EAG5B,SAAS,KAAK,YAAYE,CAAI,EAG9BG,EAAsB,EACtBC,EAAsB,EAGtBC,GAAgB,EAGhB,IAAMC,EAAU,OAAe,qBAC3BA,GACCC,EAAQD,EAAO,OAAQA,EAAO,KAAK,EACnC,KAAK,IAAM,CACVV,EAAM,UAAY,GAEfY,EAAQ,YAAY,EAAE,KAAMC,GAAa,CAC1Cb,EAAM,SAAWa,EAAI,SAAS,UAAY,GAC1Cb,EAAM,MAAQa,EAAI,SAAS,OAAS,GACpCb,EAAM,UAAYa,EAAI,SAAS,WAAa,GAC5Cb,EAAM,MAAQa,EAAI,SAAS,OAAS,CAAC,GAGjC,CAACb,EAAM,UAAY,CAACA,EAAM,aAC5BA,EAAM,UAAY,GAClBA,EAAM,YAAc,YAGtBc,EAAO,CACT,CAAC,CACH,CAAC,EACA,MAAOC,GAAa,CACnB,QAAQ,MAAM,iCAAkCA,CAAC,EACjDf,EAAM,UAAY,GAClBc,EAAO,CACT,CAAC,EAGLA,EAAO,CACT,CAGA,SAASA,GAAS,CAIhB,GAHAZ,EAAU,UAAY,GAGlBF,EAAM,WAAaA,EAAM,YAAa,CACxC,IAAMgB,EAAQ,SAAS,cAAc,KAAK,EAC1CA,EAAM,UAAY,WAEdhB,EAAM,cAAgB,WACxBgB,EAAM,UAAYC,GAAe,EACxBjB,EAAM,cAAgB,SAC/BgB,EAAM,UAAYE,GAAW,GAG/BhB,EAAU,YAAYc,CAAK,EAC3BG,GAAkBH,CAAK,CACzB,CAGA,IAAMI,EAAO,SAAS,cAAc,KAAK,EA0BzC,GAzBAA,EAAK,UAAY,UACjBA,EAAK,UAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iCAScpB,EAAM,UAAY,SAAW,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iCAM/BA,EAAM,cAAgB,OAAS,SAAW,EAAE;AAAA;AAAA;AAAA,iCAG5CA,EAAM,cAAgB,WAAa,SAAW,EAAE;AAAA;AAAA;AAAA,IAM3E,CAACA,EAAM,UAAW,CACpB,IAAMqB,EAAM,SAAS,cAAc,MAAM,EACzCA,EAAI,MAAM,QAAU,6EACpBD,EAAK,YAAYC,CAAG,CACtB,CAGA,GAAIrB,EAAM,gBAAiB,CACzB,IAAMsB,EAAY,SAAS,cAAc,MAAM,EAC/CA,EAAU,UAAY,gBACtBA,EAAU,MAAQ,sBAAsBtB,EAAM,aAAa,GAC3DsB,EAAU,iBAAiB,QAAUP,GAAM,CACzCA,EAAE,gBAAgB,EAClBf,EAAM,UAAY,GAClBA,EAAM,YAAc,WACpBc,EAAO,CACT,CAAC,EACDM,EAAK,YAAYE,CAAS,CAC5B,CAEApB,EAAU,YAAYkB,CAAI,EAG1BG,GAAcH,CAAI,EAGlBA,EAAK,iBAAiB,cAAc,EAAE,QAASI,GAAQ,CACrDA,EAAI,iBAAiB,QAAUT,GAAM,CACnCA,EAAE,gBAAgB,EAClB,IAAMU,EAAUD,EAAoB,QAAQ,OAExCC,IAAW,SACbC,GAAiB,EACRD,IAAW,aACpBE,GAAe,EACNF,IAAW,OACpBG,EAAY,MAAM,EACTH,IAAW,YACpBG,EAAY,UAAU,CAE1B,CAAC,CACH,CAAC,CACH,CAIA,SAASX,IAAyB,CAChC,IAAMY,EAAkB,OAAO,QAAQ/B,CAAc,EAClD,IAAI,CAAC,CAACgC,EAAKC,CAAC,IAAM,kBAAkBD,CAAG,KAAK9B,EAAM,WAAa8B,EAAM,WAAa,EAAE,IAAIC,EAAE,IAAI,WAAW,EACzG,KAAK,EAAE,EAEJC,EAAkBlC,EAAeE,EAAM,QAAQ,EAC/CiC,EAAeD,EACjBA,EAAgB,OAAO,IAAKE,GAC1B,kBAAkBA,EAAE,EAAE,KAAKlC,EAAM,QAAUkC,EAAE,GAAK,WAAa,EAAE,IAAIA,EAAE,IAAI,WAC7E,EAAE,KAAK,EAAE,EACT,oDAEEC,EAAiBH,GAAiB,gBAAkB,mBACpDI,EAAUJ,GAAiB,OAAS,GAEpCK,EAAerC,EAAM,gBACvB;AAAA,2BACcA,EAAM,aAAa;AAAA,oDACaD,CAAe;AAAA;AAAA,eAG7D,GAmBEuC,EAhBmC,CACvC,OAAQ,uCACR,UAAW,8CACX,OAAQ,qCACR,IAAK,6CACL,SAAU,yCACV,QAAS,sCACT,KAAM,gCACN,QAAS,4EACT,SAAU,gDACV,KAAM,8CACN,MAAO,8CACP,OAAQ,kEACR,WAAY,qCACd,EAEwBtC,EAAM,QAAQ,GAAK,GACrCuC,EAAeP,GAAiB,MAAQ,WAE9C,MAAO;AAAA;AAAA;AAAA;AAAA,wCAI+BjC,CAAe;AAAA;AAAA;AAAA;AAAA,QAI/CsC,CAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAMNR,CAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAQfI,CAAY;AAAA;AAAA;AAAA;AAAA,+BAIKG,EAAU,YAAc,EAAE;AAAA;AAAA;AAAA;AAAA,kCAIvBD,CAAc;AAAA;AAAA,cAElCG,EAAS,kEAAkEA,CAAM,6BAA6BC,CAAY;AAAA;AAAA;AAAA,uBAG/G,EAAE;AAAA;AAAA,YAEfvC,EAAM,UAAY,CAACoC,EAAU,uCAAuCG,CAAY,kBAAkBD,EAAS,uCAAuCA,CAAM,4BAA8B,EAAE,SAAW,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAQvMtC,EAAM,UAAY;AAAA;AAAA;AAAA,gBAGV,EAAE;AAAA;AAAA;AAAA,GAIpB,CAEA,SAASkB,IAAqB,CAC5B,GAAI,CAAClB,EAAM,WAAa,CAACA,EAAM,SAC7B,MAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAaT,IAAMwC,EAAexC,EAAM,SACxB,IAAKkC,GAAM,6BAA6BA,EAAE,IAAI,KAAKO,EAAWP,EAAE,OAAO,CAAC,QAAQ,EAChF,KAAK,EAAE,EAEJQ,EAAa1C,EAAM,UACrB,gHAAgHyC,EAAWzC,EAAM,aAAa,CAAC,SAC/I,GAEE2C,EAAyB,CAAC,EAChC,OAAI3C,EAAM,iBACR2C,EAAa,KAAK,2CAAoC3C,EAAM,gBAAgB,OAAO,GAAGA,EAAM,gBAAgB,GAAK,IAAMA,EAAM,gBAAgB,GAAK,EAAE,6FAA6F,EAE/OA,EAAM,YACR2C,EAAa,KAAK,kJAA2I,EAGxJ;AAAA;AAAA,iDAEmC7C,EAAeE,EAAM,QAAQ,GAAG,MAAQA,EAAM,QAAQ,MAAMA,EAAM,KAAK;AAAA;AAAA;AAAA;AAAA,QAI3G2C,EAAa,OAAS,EAAI,+BAA+BA,EAAa,KAAK,EAAE,CAAC,SAAW,EAAE;AAAA,QAC3F3C,EAAM,gBAAkB,oCAAoCA,EAAM,gBAAgB,OAAO,GAAGA,EAAM,gBAAgB,GAAK,QAAUA,EAAM,gBAAgB,GAAK,IAAM,EAAE,GAAGA,EAAM,gBAAgB,UAAY,WAAaA,EAAM,gBAAgB,UAAU,SAAS,EAAE,MAAM,EAAG,EAAE,EAAI,IAAM,EAAE,aAAe,EAAE;AAAA;AAAA,UAEvSwC,GAAgB,sIAAsI;AAAA,UACtJE,CAAU;AAAA;AAAA;AAAA;AAAA,6BAIS1C,EAAM,UAAY,WAAa,EAAE;AAAA,0DACJA,EAAM,UAAY,WAAa,EAAE;AAAA,YAC/EA,EAAM,UAAY,MAAQ,MAAM;AAAA;AAAA;AAAA;AAAA,GAK5C,CAIA,SAASmB,GAAkBH,EAAoB,CAE7CA,EAAM,cAAc,uBAAuB,GAAG,iBAAiB,QAAS,IAAM,CAC5EhB,EAAM,UAAY,GAClBA,EAAM,YAAc,KACpBc,EAAO,CACT,CAAC,EAGDE,EAAM,cAAc,yBAAyB,GAAG,iBAAiB,SAAWD,GAAM,CAChFf,EAAM,SAAYe,EAAE,OAA6B,MACjDf,EAAM,MAAQ,GACdc,EAAO,CACT,CAAC,EAGDE,EAAM,cAAc,sBAAsB,GAAG,iBAAiB,SAAWD,GAAM,CAC7Ef,EAAM,MAASe,EAAE,OAA6B,KAChD,CAAC,EAGDC,EAAM,iBAAiB,yBAAyB,EAAE,QAAS4B,GAAO,CAChEA,EAAG,iBAAiB,QAAU7B,GAAM,CAClCA,EAAE,eAAe,EACjB,IAAM8B,EAAOD,EAAmB,QAAQ,IACpCC,GAAK,OAAO,KAAKA,EAAK,SAAU,UAAU,CAChD,CAAC,CACH,CAAC,EAGD7B,EAAM,cAAc,+BAA+B,GAAG,iBAAiB,QAAS,IAAM,CAEpF,IAAM8B,EADc9B,EAAM,cAAc,uBAAuB,GACnC,OAAS,GAE/B+B,EAAe,CACnB,SAAU/C,EAAM,SAChB,MAAOA,EAAM,KACf,EACI8C,IACFC,EAAQ,OAASD,GAGhBlC,EAAQ,aAAcmC,CAAO,EAAE,KAAK,IAAM,CAC3C/C,EAAM,UAAY,GAClBc,EAAO,CACT,CAAC,EAAE,MAAOC,GAAa,CACrB,QAAQ,MAAM,qCAAsCA,CAAC,CACvD,CAAC,CACH,CAAC,EAGDC,EAAM,cAAc,sBAAsB,GAAG,iBAAiB,QAAS,IAAM,CAC3EgC,EAAYhC,CAAK,CACnB,CAAC,EAGD,IAAMiC,EAAQjC,EAAM,cAAc,gBAAgB,EAClDiC,GAAO,iBAAiB,UAAYlC,GAAM,CACpCA,EAAE,MAAQ,SAAW,CAACA,EAAE,WAC1BA,EAAE,eAAe,EACjBiC,EAAYhC,CAAK,EAErB,CAAC,EAGDiC,GAAO,iBAAiB,QAAS,IAAM,CACrCA,EAAM,MAAM,OAAS,OACrBA,EAAM,MAAM,OAAS,KAAK,IAAIA,EAAM,aAAc,GAAG,EAAI,IAC3D,CAAC,EAGDjC,EAAM,cAAc,+BAA+B,GAAG,iBAAiB,QAAS,IAAM,CACpFhB,EAAM,gBAAkB,KACxBc,EAAO,CACT,CAAC,EAEDE,EAAM,cAAc,kCAAkC,GAAG,iBAAiB,QAAS,IAAM,CACvFhB,EAAM,WAAa,KACnBc,EAAO,CACT,CAAC,CACH,CAEA,eAAekC,EAAYhC,EAAoB,CAC7C,IAAMiC,EAAQjC,EAAM,cAAc,gBAAgB,EAClD,GAAI,CAACiC,EAAO,OAEZ,IAAMC,EAAOD,EAAM,MAAM,KAAK,EAC9B,GAAI,CAACC,GAAQlD,EAAM,UAAW,OAG9BA,EAAM,SAAS,KAAK,CAAE,KAAM,OAAQ,QAASkD,CAAK,CAAC,EACnDlD,EAAM,UAAY,GAClBA,EAAM,cAAgB,GACtBc,EAAO,EAGP,IAAMqC,EAAUC,EAAapD,EAAM,gBAAiBA,EAAM,UAAU,EAEpE,GAAI,CACF,IAAMqD,EAAS,MAASC,EACtB,WACA,CACE,SAAUtD,EAAM,SAChB,MAAOA,EAAM,MACb,SAAUA,EAAM,SAAS,IAAKkC,IAAO,CAAE,KAAMA,EAAE,KAAM,QAASA,EAAE,OAAQ,EAAE,EAC1E,QAAAiB,CACF,EACCI,GAAkB,CACjBvD,EAAM,eAAiBuD,EAGvB,IAAMC,EADevD,EAAO,cAAc,mBAAmB,GAC9B,cAAc,8BAA8B,EACvEuD,IACFA,EAAS,UAAYf,EAAWzC,EAAM,aAAa,EAEvD,CACF,EAMA,GAHAA,EAAM,SAAS,KAAK,CAAE,KAAM,YAAa,QAASA,EAAM,eAAiBqD,GAAQ,SAAW,EAAG,CAAC,EAG5FA,GAAQ,eAAiBA,EAAO,cAAc,OAAS,GACzD,QAAWI,KAAOJ,EAAO,cACvB,GAAII,EAAI,OAAS,QAAUA,EAAI,MAAQA,EAAI,QAAUA,EAAI,QAEvD,GAAI,CAEF,IAAMC,GADa,MAAS9C,EAAQ,UAAW,CAAE,KAAM+C,EAAgBF,EAAI,IAAI,CAAE,CAAC,GACvD,SAAS,QACpC,GAAIC,GAAWA,EAAQ,SAASD,EAAI,MAAM,EAAG,CAC3C,IAAMG,EAAaF,EAAQ,QAAQD,EAAI,OAAQA,EAAI,OAAO,EAC1D,MAAS7C,EAAQ,WAAY,CAAE,KAAM+C,EAAgBF,EAAI,IAAI,EAAG,QAASG,CAAW,CAAC,EACrF5D,EAAM,SAAS,KAAK,CAClB,KAAM,SACN,QAAS,qBAAqByD,EAAI,IAAI,EACxC,CAAC,CACH,CACF,OAAS1C,EAAQ,CACff,EAAM,SAAS,KAAK,CAClB,KAAM,SACN,QAAS,6BAA6ByD,EAAI,IAAI,KAAK1C,EAAE,OAAO,EAC9D,CAAC,CACH,EAIR,OAASA,EAAQ,CACff,EAAM,SAAS,KAAK,CAAE,KAAM,SAAU,QAAS,UAAUe,EAAE,OAAO,EAAG,CAAC,CACxE,CAEAf,EAAM,UAAY,GAClBA,EAAM,cAAgB,GACtBc,EAAO,CACT,CAEA,SAAS6C,EAAgBE,EAA8B,CAErD,OAAI7D,EAAM,MAAM,OAAS,EAChBA,EAAM,MAAM,CAAC,EAAI,IAAM6D,EAEzBA,CACT,CAIA,IAAIC,EAAkD,KAClDC,EAAiD,KAErD,SAASrC,IAAmB,CACtB1B,EAAM,UACRgE,EAAe,EAEfC,GAAgB,CAEpB,CAEA,SAASA,IAAkB,CACzBjE,EAAM,UAAY,GAClB,SAAS,KAAK,MAAM,OAAS,YAE7B+D,EAAgB,GAAkB,CAChC,IAAMG,EAAS,EAAE,OACjB,GAAIC,EAAmBD,CAAM,EAAG,OAChC,IAAME,EAAOF,EAAO,sBAAsB,EAC1CG,EAAc,CACZ,EAAGD,EAAK,EACR,EAAGA,EAAK,EACR,MAAOA,EAAK,MACZ,OAAQA,EAAK,MACf,CAAC,CACH,EAEAN,EAAiB,GAAkB,CACjC,EAAE,eAAe,EACjB,EAAE,gBAAgB,EAElB,IAAMI,EAAS,EAAE,OACbC,EAAmBD,CAAM,IAE7BlE,EAAM,gBAAkBsE,EAAeJ,CAAM,EAC7CF,EAAe,EAGXhE,EAAM,cAAgB,SACxBA,EAAM,UAAY,GAClBA,EAAM,YAAc,QAGtBc,EAAO,EACT,EAEA,SAAS,iBAAiB,YAAaiD,EAAc,EAAI,EACzD,SAAS,iBAAiB,QAASD,EAAe,EAAI,EAEtDhD,EAAO,CACT,CAEA,SAASkD,GAAiB,CACxBhE,EAAM,UAAY,GAClB,SAAS,KAAK,MAAM,OAAS,GAC7BuE,EAAc,EAEVR,IACF,SAAS,oBAAoB,YAAaA,EAAc,EAAI,EAC5DA,EAAe,MAEbD,IACF,SAAS,oBAAoB,QAASA,EAAe,EAAI,EACzDA,EAAgB,MAGlBhD,EAAO,CACT,CAIA,eAAea,IAAiB,CAC9B,IAAM6C,EAAa,MAAMC,EAAkB,EACvCD,IACFxE,EAAM,WAAawE,EAEnBxE,EAAM,UAAY,GAClBA,EAAM,YAAc,OACpBc,EAAO,EAEX,CAIA,SAASc,EAAYZ,EAA4B,CAC3ChB,EAAM,WAAaA,EAAM,cAAgBgB,GAC3ChB,EAAM,UAAY,GAClBA,EAAM,YAAc,OAEpBA,EAAM,UAAY,GAClBA,EAAM,YAAcgB,GAEtBF,EAAO,CACT,CAIA,SAASS,GAAcqB,EAAiB,CACtC,IAAI8B,EAAa,GACbC,EAAS,EACTC,EAAS,EACTC,EAAQ,EACRC,EAAQ,EAEZlC,EAAG,iBAAiB,YAAc7B,GAAM,CAEtC,IAAMmD,EAASnD,EAAE,OAEjB,GADImD,EAAO,QAAQ,cAAc,GAC7B,CAACA,EAAO,QAAQ,UAAU,GAAK,CAACA,EAAO,QAAQ,gBAAgB,EAAG,OAEtEQ,EAAa,GACbC,EAAS5D,EAAE,QACX6D,EAAS7D,EAAE,QACX,IAAMqD,EAAOxB,EAAG,sBAAsB,EACtCiC,EAAQT,EAAK,KACbU,EAAQV,EAAK,IACbrD,EAAE,eAAe,CACnB,CAAC,EAED,SAAS,iBAAiB,YAAcA,GAAM,CAC5C,GAAI,CAAC2D,EAAY,OACjB,IAAMK,EAAKhE,EAAE,QAAU4D,EACjBK,EAAKjE,EAAE,QAAU6D,EACvBhC,EAAG,MAAM,SAAW,QACpBA,EAAG,MAAM,KAAOiC,EAAQE,EAAK,KAC7BnC,EAAG,MAAM,IAAMkC,EAAQE,EAAK,KAC5BpC,EAAG,MAAM,MAAQ,OACjBA,EAAG,MAAM,OAAS,MACpB,CAAC,EAED,SAAS,iBAAiB,UAAW,IAAM,CACzC8B,EAAa,EACf,CAAC,CACH,CAIA,SAASP,EAAmBvB,EAA0B,CACpD,MAAO,CAAC,CAACA,EAAG,QAAQ,mBAAmB,GAAK,CAAC,CAACA,EAAG,SAAS,SAC5D,CAEA,SAASH,EAAWS,EAAsB,CACxC,IAAM+B,EAAM,SAAS,cAAc,KAAK,EACxC,OAAAA,EAAI,YAAc/B,EACX+B,EAAI,SACb,CAIA,SAASxE,IAAwB,CAE/B,MAAM,8CAA+C,CACnD,QAAS,CAAE,OAAQ,kBAAmB,EACtC,OAAQ,YAAY,QAAQ,GAAI,CAClC,CAAC,EACE,KAAMyE,GAAQ,CACb,GAAKA,EAAI,GACT,OAAOA,EAAI,KAAK,CAClB,CAAC,EACA,KAAMC,GAAS,CACd,GAAI,CAACA,GAAM,QAAS,OACpB,IAAMC,EAASD,EAAK,QAChBE,GAAeD,EAAQrF,CAAe,IACxCC,EAAM,gBAAkB,GACxBA,EAAM,cAAgBoF,EACtBtE,EAAO,EAEX,CAAC,EACA,MAAM,IAAM,CAEb,CAAC,CACL,CAEA,SAASuE,GAAeD,EAAgBE,EAA0B,CAChE,IAAMC,EAAIH,EAAO,MAAM,GAAG,EAAE,IAAI,MAAM,EAChCI,EAAIF,EAAQ,MAAM,GAAG,EAAE,IAAI,MAAM,EACvC,QAASG,EAAI,EAAGA,EAAI,EAAGA,IAAK,CAC1B,IAAKF,EAAEE,CAAC,GAAK,IAAMD,EAAEC,CAAC,GAAK,GAAI,MAAO,GACtC,IAAKF,EAAEE,CAAC,GAAK,IAAMD,EAAEC,CAAC,GAAK,GAAI,MAAO,EACxC,CACA,MAAO,EACT,CAGI,OAAO,OAAW,MAChB,SAAS,aAAe,UAC1B,SAAS,iBAAiB,mBAAoBtF,CAAI,EAElDA,EAAK","names":["TOOLBAR_CSS","ws","handlers","globalHandlers","messageQueue","connected","reconnectTimer","generateId","connect","port","token","resolve","reject","handshakeId","send","msg","queued","event","handler","e","data","request","type","payload","id","timeout","stream","onChunk","IMPORTANT_STYLES","inspectElement","el","computed","styles","prop","rect","getCleanOuterHTML","getCssSelector","getXPath","clone","s","html","tag","attrs","a","childSummary","c","parts","current","selector","classes","parent","siblings","index","element","sibling","highlightEl","showHighlight","hideHighlight","captureScreenshot","target","captureElementViaCanvas","captureViewport","e","canvas","dpr","ctx","svgData","elementToSvg","img","svgToImage","element","rect","resolve","clone","inlineStyles","width","height","foreignObject","source","computed","cssText","i","prop","sourceChildren","targetChildren","reject","blob","url","networkLogs","networkCaptureInstalled","installNetworkCapture","originalFetch","args","request","entry","response","addNetworkEntry","e","originalOpen","originalSend","method","url","rest","networkLogs","getNetworkLogs","consoleLogs","MAX_CONSOLE_LOGS","consoleCaptureInstalled","installConsoleCapture","levels","level","original","args","a","getConsoleLogs","buildContext","selectedElement","screenshot","getNetworkLogs","l","getConsoleLogs","MODEL_REGISTRY","CURRENT_VERSION","state","shadow","container","init","host","style","TOOLBAR_CSS","installNetworkCapture","installConsoleCapture","checkForUpdates","config","connect","request","msg","render","e","panel","renderSettings","renderChat","attachPanelEvents","pill","dot","updateDot","makeDraggable","btn","action","toggleSelectMode","takeScreenshot","togglePanel","providerOptions","key","p","currentProvider","modelOptions","m","keyPlaceholder","isLocal","updateBanner","keyUrl","providerName","messagesHtml","escapeHtml","streamHtml","contextChips","el","url","apiKey","payload","sendMessage","input","text","context","buildContext","result","stream","chunk","streamEl","mod","content","resolveFilePath","newContent","relativePath","selectHandler","hoverHandler","exitSelectMode","enterSelectMode","target","isOpenMagicElement","rect","showHighlight","inspectElement","hideHighlight","screenshot","captureScreenshot","isDragging","startX","startY","origX","origY","dx","dy","div","res","data","latest","isNewerVersion","current","l","c","i"]}
|
|
1
|
+
{"version":3,"sources":["../../src/toolbar/styles/toolbar.css.ts","../../src/toolbar/services/ws-client.ts","../../src/toolbar/services/dom-inspector.ts","../../src/toolbar/services/capture.ts","../../src/toolbar/services/context-builder.ts","../../src/toolbar/index.ts"],"sourcesContent":["export const TOOLBAR_CSS = `\n:host {\n all: initial;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n color: #e0e0e0;\n line-height: 1.5;\n}\n\n* { box-sizing: border-box; margin: 0; padding: 0; }\n\n.om-hidden { display: none !important; }\n\n/* ── Pill Bar ─────────────────────────────────────────── */\n.om-pill {\n position: fixed;\n bottom: 24px;\n right: 24px;\n z-index: 2147483647;\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 5px 10px 5px 4px;\n background: linear-gradient(135deg, #111125 0%, #191938 100%);\n border: 1px solid rgba(108, 92, 231, 0.2);\n border-radius: 12px;\n user-select: none;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255,255,255,0.03);\n transition: box-shadow 0.2s;\n}\n.om-pill:hover { box-shadow: 0 6px 28px rgba(108, 92, 231, 0.2), inset 0 1px 0 rgba(255,255,255,0.03); }\n\n.om-grab {\n display: flex; align-items: center; justify-content: center;\n width: 18px; height: 26px; color: #3a3a5a; cursor: grab;\n border-radius: 5px; transition: color 0.15s; flex-shrink: 0;\n}\n.om-grab:hover { color: #6c5ce7; }\n.om-grab:active { cursor: grabbing; color: #a29bfe; }\n\n.om-pill-brand {\n display: flex; align-items: center; gap: 5px;\n padding: 0 6px 0 4px; cursor: grab;\n}\n.om-pill-icon { color: #a29bfe; flex-shrink: 0; }\n.om-pill-text { font-size: 11px; font-weight: 700; color: #a29bfe; letter-spacing: 0.3px; white-space: nowrap; }\n\n.om-pill-divider { width: 1px; height: 18px; background: rgba(255,255,255,0.07); margin: 0 3px; }\n\n.om-pill-btn {\n background: none; border: none; color: #555; cursor: pointer;\n padding: 5px 6px; border-radius: 6px; line-height: 1;\n transition: background 0.15s, color 0.15s;\n display: flex; align-items: center; justify-content: center;\n}\n.om-pill-btn:hover { background: rgba(108, 92, 231, 0.15); color: #a29bfe; }\n.om-pill-btn.active { background: rgba(108, 92, 231, 0.25); color: #c4b5fd; }\n\n.om-status-dot {\n width: 7px; height: 7px; border-radius: 50%; margin-left: 4px; flex-shrink: 0;\n}\n.om-status-dot.connected { background: #00b894; }\n.om-status-dot.disconnected { background: #e94560; }\n\n.om-update-dot {\n width: 7px; height: 7px; border-radius: 50%; background: #fdcb6e;\n margin-left: 4px; cursor: pointer; flex-shrink: 0;\n animation: om-pulse 2s ease infinite;\n}\n@keyframes om-pulse {\n 0%, 100% { box-shadow: 0 0 0 0 rgba(253,203,110,0.4); }\n 50% { box-shadow: 0 0 0 5px rgba(253,203,110,0); }\n}\n\n/* ── Prompt Bar (always visible) ──────────────────────── */\n.om-prompt-bar {\n position: fixed;\n bottom: 62px;\n right: 24px;\n z-index: 2147483647;\n display: flex;\n align-items: center;\n width: 420px;\n background: #151528;\n border: 1px solid rgba(108, 92, 231, 0.15);\n border-radius: 12px;\n padding: 4px;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);\n transition: border-color 0.2s, box-shadow 0.2s;\n}\n.om-prompt-bar:focus-within {\n border-color: rgba(108, 92, 231, 0.4);\n box-shadow: 0 4px 24px rgba(108, 92, 231, 0.15);\n}\n\n.om-prompt-input {\n flex: 1;\n background: transparent;\n border: none;\n color: #e0e0e0;\n font-size: 13px;\n font-family: inherit;\n padding: 8px 12px;\n outline: none;\n min-width: 0;\n}\n.om-prompt-input::placeholder { color: #444; }\n\n.om-prompt-context {\n display: flex; gap: 3px; padding: 0 4px; flex-shrink: 0;\n}\n.om-prompt-chip {\n display: flex; align-items: center; gap: 3px;\n padding: 3px 7px; background: rgba(108, 92, 231, 0.1);\n border: 1px solid rgba(108, 92, 231, 0.15);\n border-radius: 6px; font-size: 10px; color: #a29bfe;\n cursor: default; white-space: nowrap;\n}\n.om-prompt-chip-x {\n background: none; border: none; color: #a29bfe; cursor: pointer;\n font-size: 12px; line-height: 1; padding: 0 1px; opacity: 0.6;\n}\n.om-prompt-chip-x:hover { opacity: 1; }\n\n.om-prompt-send {\n display: flex; align-items: center; justify-content: center;\n width: 32px; height: 32px; flex-shrink: 0;\n background: #6c5ce7; border: none; border-radius: 8px;\n color: white; cursor: pointer; transition: background 0.15s;\n}\n.om-prompt-send:hover { background: #7c6cf7; }\n.om-prompt-send:disabled { background: #2a2a4a; color: #555; cursor: not-allowed; }\n\n/* ── Panel ────────────────────────────────────────────── */\n.om-panel {\n position: fixed;\n bottom: 110px;\n right: 24px;\n z-index: 2147483647;\n width: 420px;\n max-height: 520px;\n background: #151528;\n border: 1px solid rgba(108, 92, 231, 0.15);\n border-radius: 14px;\n box-shadow: 0 8px 40px rgba(0, 0, 0, 0.5);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n animation: om-slide-up 0.15s ease;\n}\n@keyframes om-slide-up {\n from { opacity: 0; transform: translateY(6px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n.om-panel-header {\n display: flex; align-items: center; gap: 8px;\n padding: 10px 14px;\n border-bottom: 1px solid rgba(255,255,255,0.04);\n background: rgba(108, 92, 231, 0.03);\n}\n.om-panel-title { font-size: 12px; font-weight: 600; color: #a29bfe; }\n.om-panel-version { font-size: 10px; color: #444; margin-left: auto; }\n.om-panel-close {\n background: none; border: none; color: #555; cursor: pointer;\n padding: 2px 5px; border-radius: 4px; line-height: 1;\n display: flex; align-items: center; justify-content: center;\n}\n.om-panel-close:hover { color: #ccc; background: rgba(255,255,255,0.05); }\n\n.om-panel-body {\n flex: 1; overflow-y: auto; padding: 14px;\n}\n.om-panel-body::-webkit-scrollbar { width: 5px; }\n.om-panel-body::-webkit-scrollbar-track { background: transparent; }\n.om-panel-body::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.08); border-radius: 3px; }\n\n/* ── Settings ─────────────────────────────────────────── */\n.om-settings { display: flex; flex-direction: column; gap: 14px; }\n\n.om-field { display: flex; flex-direction: column; gap: 5px; }\n.om-label { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; color: #666; }\n\n.om-select, .om-input {\n background: rgba(255,255,255,0.04);\n border: 1px solid rgba(255,255,255,0.08);\n border-radius: 8px;\n padding: 9px 11px;\n color: #e0e0e0;\n font-size: 13px;\n font-family: inherit;\n outline: none;\n width: 100%;\n transition: border-color 0.15s;\n}\n.om-select:focus, .om-input:focus { border-color: rgba(108, 92, 231, 0.4); }\n.om-select option { background: #151528; color: #e0e0e0; }\n\n.om-key-row { display: flex; gap: 6px; align-items: stretch; }\n.om-key-input { flex: 1; min-width: 0; -webkit-text-security: disc; }\n\n.om-btn-get-key {\n display: flex; align-items: center; gap: 4px;\n padding: 7px 10px; background: rgba(108, 92, 231, 0.1);\n border: 1px solid rgba(108, 92, 231, 0.2); border-radius: 8px;\n color: #a29bfe; font-size: 11px; font-weight: 600;\n font-family: inherit; cursor: pointer; white-space: nowrap;\n transition: all 0.15s;\n}\n.om-btn-get-key:hover { background: rgba(108, 92, 231, 0.18); color: #c4b5fd; }\n\n.om-btn {\n display: flex; align-items: center; justify-content: center; gap: 6px;\n background: #6c5ce7; border: none; color: white; cursor: pointer;\n padding: 9px 16px; border-radius: 8px;\n font-size: 13px; font-weight: 600; font-family: inherit;\n transition: background 0.15s;\n}\n.om-btn:hover { background: #7c6cf7; }\n.om-btn:disabled { background: #2a2a4a; color: #555; cursor: not-allowed; }\n\n.om-btn-saving { background: #4a3db0; }\n.om-btn-saved { background: #00b894; }\n\n.om-status { font-size: 11px; padding: 6px 10px; border-radius: 6px; text-align: center; display: flex; align-items: center; justify-content: center; gap: 5px; }\n.om-status-success { background: rgba(0, 184, 148, 0.08); color: #00b894; }\n.om-status-error { background: rgba(233, 69, 96, 0.08); color: #e94560; }\n\n.om-key-hint { font-size: 10px; color: #555; margin-top: 4px; line-height: 1.4; }\n.om-key-hint a { color: #7c6cf7; cursor: pointer; text-decoration: none; }\n.om-key-hint a:hover { text-decoration: underline; }\n\n.om-update-banner {\n display: flex; align-items: center; gap: 6px; flex-wrap: wrap;\n padding: 8px 12px; margin-bottom: 12px;\n background: rgba(253, 203, 110, 0.06); border: 1px solid rgba(253, 203, 110, 0.15);\n border-radius: 8px; font-size: 12px; color: #fdcb6e;\n}\n.om-update-cmd {\n display: block; width: 100%; margin-top: 3px;\n padding: 5px 8px; background: rgba(0, 0, 0, 0.15); border-radius: 5px;\n font-family: 'SF Mono', 'Fira Code', Consolas, monospace;\n font-size: 11px; color: #fdcb6e; user-select: all;\n}\n\n/* ── Chat ─────────────────────────────────────────────── */\n.om-chat-messages {\n display: flex; flex-direction: column; gap: 10px;\n min-height: 120px; max-height: 400px;\n overflow-y: auto; padding-bottom: 6px;\n}\n.om-chat-messages::-webkit-scrollbar { width: 4px; }\n.om-chat-messages::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.08); border-radius: 2px; }\n\n.om-msg {\n padding: 9px 12px; border-radius: 10px;\n font-size: 13px; line-height: 1.55;\n white-space: pre-wrap; word-break: break-word;\n}\n.om-msg-user { background: rgba(108, 92, 231, 0.1); color: #d0d0d0; margin-left: 40px; border-bottom-right-radius: 3px; }\n.om-msg-assistant { background: rgba(255,255,255,0.02); color: #bbb; margin-right: 40px; border-bottom-left-radius: 3px; border: 1px solid rgba(255,255,255,0.04); }\n.om-msg-system { background: rgba(108, 92, 231, 0.06); color: #a29bfe; font-size: 11px; text-align: center; padding: 6px 8px; border-radius: 6px; }\n\n.om-chat-empty { color: #3a3a5a; text-align: center; padding: 40px 20px; font-size: 13px; line-height: 1.6; }\n\n.om-spinner { width: 14px; height: 14px; border: 2px solid rgba(108,92,231,0.15); border-top-color: #6c5ce7; border-radius: 50%; animation: om-spin 0.6s linear infinite; display: inline-block; vertical-align: -2px; margin-right: 6px; }\n@keyframes om-spin { to { transform: rotate(360deg); } }\n\n/* ── Element info ─────────────────────────────────────── */\n.om-element-info {\n background: rgba(255,255,255,0.02); border: 1px solid rgba(255,255,255,0.04);\n border-radius: 6px; padding: 8px 10px;\n font-family: 'SF Mono', 'Fira Code', Consolas, monospace;\n font-size: 10px; color: #666; max-height: 80px; overflow-y: auto; margin-bottom: 8px;\n}\n`;\n","type MessageHandler = (msg: any) => void;\n\nlet ws: WebSocket | null = null;\nlet handlers: Map<string, MessageHandler> = new Map();\nlet globalHandlers: ((msg: any) => void)[] = [];\nlet messageQueue: string[] = [];\nlet connected = false;\nlet reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n\nfunction generateId(): string {\n return Math.random().toString(36).slice(2) + Date.now().toString(36);\n}\n\nexport function connect(port: number, token: string): Promise<void> {\n return new Promise((resolve, reject) => {\n try {\n ws = new WebSocket(`ws://127.0.0.1:${port}/__openmagic__/ws`);\n\n ws.onopen = () => {\n // Send handshake\n const handshakeId = generateId();\n send({ id: handshakeId, type: \"handshake\", payload: { token } });\n\n // Wait for handshake.ok\n handlers.set(handshakeId, (msg) => {\n if (msg.type === \"handshake.ok\") {\n connected = true;\n // Flush queued messages\n for (const queued of messageQueue) {\n ws?.send(queued);\n }\n messageQueue = [];\n resolve();\n } else if (msg.type === \"error\") {\n reject(new Error(msg.payload?.message || \"Handshake failed\"));\n }\n });\n };\n\n ws.onmessage = (event) => {\n try {\n const msg = JSON.parse(event.data);\n\n // Route to specific handler if exists\n if (msg.id && handlers.has(msg.id)) {\n const handler = handlers.get(msg.id)!;\n handler(msg);\n // Don't delete handler for streaming responses\n if (msg.type === \"llm.done\" || msg.type === \"llm.error\" || !msg.type.startsWith(\"llm.\")) {\n handlers.delete(msg.id);\n }\n }\n\n // Notify global handlers\n for (const handler of globalHandlers) {\n handler(msg);\n }\n } catch {\n // Ignore parse errors\n }\n };\n\n ws.onclose = () => {\n connected = false;\n // Reconnect after 2 seconds\n if (!reconnectTimer) {\n reconnectTimer = setTimeout(() => {\n reconnectTimer = null;\n connect(port, token).catch(() => {});\n }, 2000);\n }\n };\n\n ws.onerror = () => {\n // Will trigger onclose\n };\n } catch (e) {\n reject(e);\n }\n });\n}\n\nexport function send(msg: { id: string; type: string; payload?: any }): void {\n const data = JSON.stringify(msg);\n if (ws && ws.readyState === WebSocket.OPEN && connected) {\n ws.send(data);\n } else {\n messageQueue.push(data);\n }\n}\n\nexport function request(type: string, payload?: any): Promise<any> {\n return new Promise((resolve, reject) => {\n const id = generateId();\n const timeout = setTimeout(() => {\n handlers.delete(id);\n reject(new Error(\"Request timeout\"));\n }, 30000);\n\n handlers.set(id, (msg) => {\n clearTimeout(timeout);\n if (msg.type === \"error\") {\n reject(new Error(msg.payload?.message || \"Unknown error\"));\n } else {\n resolve(msg);\n }\n });\n\n send({ id, type, payload });\n });\n}\n\nexport function stream(\n type: string,\n payload: any,\n onChunk: (chunk: string) => void\n): Promise<any> {\n return new Promise((resolve, reject) => {\n const id = generateId();\n const timeout = setTimeout(() => {\n handlers.delete(id);\n reject(new Error(\"Stream timeout\"));\n }, 120000); // 2 min timeout for LLM responses\n\n handlers.set(id, (msg) => {\n if (msg.type === \"llm.chunk\") {\n onChunk(msg.payload?.delta || \"\");\n } else if (msg.type === \"llm.done\") {\n clearTimeout(timeout);\n handlers.delete(id);\n resolve(msg.payload);\n } else if (msg.type === \"llm.error\" || msg.type === \"error\") {\n clearTimeout(timeout);\n handlers.delete(id);\n reject(new Error(msg.payload?.message || \"Stream error\"));\n }\n });\n\n send({ id, type, payload });\n });\n}\n\nexport function onMessage(handler: (msg: any) => void): () => void {\n globalHandlers.push(handler);\n return () => {\n globalHandlers = globalHandlers.filter((h) => h !== handler);\n };\n}\n\nexport function isConnected(): boolean {\n return connected;\n}\n\nexport function disconnect(): void {\n if (reconnectTimer) {\n clearTimeout(reconnectTimer);\n reconnectTimer = null;\n }\n if (ws) {\n ws.close();\n ws = null;\n }\n connected = false;\n}\n","export interface SelectedElement {\n tagName: string;\n id: string;\n className: string;\n textContent: string;\n outerHTML: string;\n cssSelector: string;\n xpath: string;\n computedStyles: Record<string, string>;\n rect: { x: number; y: number; width: number; height: number };\n}\n\nconst IMPORTANT_STYLES = [\n \"display\",\n \"position\",\n \"width\",\n \"height\",\n \"margin\",\n \"padding\",\n \"color\",\n \"background-color\",\n \"background\",\n \"font-size\",\n \"font-weight\",\n \"font-family\",\n \"border\",\n \"border-radius\",\n \"box-shadow\",\n \"flex-direction\",\n \"justify-content\",\n \"align-items\",\n \"gap\",\n \"grid-template-columns\",\n \"grid-template-rows\",\n \"overflow\",\n \"opacity\",\n \"z-index\",\n \"text-align\",\n \"line-height\",\n \"letter-spacing\",\n];\n\nexport function inspectElement(el: HTMLElement): SelectedElement {\n const computed = window.getComputedStyle(el);\n const styles: Record<string, string> = {};\n for (const prop of IMPORTANT_STYLES) {\n styles[prop] = computed.getPropertyValue(prop);\n }\n\n const rect = el.getBoundingClientRect();\n\n return {\n tagName: el.tagName.toLowerCase(),\n id: el.id || \"\",\n className: el.className || \"\",\n textContent: (el.textContent || \"\").trim().slice(0, 200),\n outerHTML: getCleanOuterHTML(el),\n cssSelector: getCssSelector(el),\n xpath: getXPath(el),\n computedStyles: styles,\n rect: {\n x: rect.x,\n y: rect.y,\n width: rect.width,\n height: rect.height,\n },\n };\n}\n\nfunction getCleanOuterHTML(el: HTMLElement): string {\n const clone = el.cloneNode(true) as HTMLElement;\n\n // Remove script tags and large content\n const scripts = clone.querySelectorAll(\"script, style, svg\");\n scripts.forEach((s) => s.remove());\n\n // Truncate children if too many\n let html = clone.outerHTML;\n if (html.length > 2000) {\n // Just get the opening tag + first level children hints\n const tag = el.tagName.toLowerCase();\n const attrs = Array.from(el.attributes)\n .map((a) => `${a.name}=\"${a.value}\"`)\n .join(\" \");\n const childSummary = Array.from(el.children)\n .slice(0, 5)\n .map((c) => `<${c.tagName.toLowerCase()} .../>`)\n .join(\"\\n \");\n html = `<${tag} ${attrs}>\\n ${childSummary}\\n ${el.children.length > 5 ? `<!-- +${el.children.length - 5} more children -->` : \"\"}\\n</${tag}>`;\n }\n\n return html;\n}\n\nfunction getCssSelector(el: HTMLElement): string {\n if (el.id) return `#${el.id}`;\n\n const parts: string[] = [];\n let current: HTMLElement | null = el;\n\n while (current && current !== document.body) {\n let selector = current.tagName.toLowerCase();\n\n if (current.id) {\n parts.unshift(`#${current.id}`);\n break;\n }\n\n if (current.className && typeof current.className === \"string\") {\n const classes = current.className\n .trim()\n .split(/\\s+/)\n .filter((c) => !c.startsWith(\"__\") && c.length < 30)\n .slice(0, 2);\n if (classes.length > 0) {\n selector += \".\" + classes.join(\".\");\n }\n }\n\n // Add nth-child if needed for uniqueness\n const parent = current.parentElement;\n if (parent) {\n const siblings = Array.from(parent.children).filter(\n (s) => s.tagName === current!.tagName\n );\n if (siblings.length > 1) {\n const index = siblings.indexOf(current) + 1;\n selector += `:nth-child(${index})`;\n }\n }\n\n parts.unshift(selector);\n current = current.parentElement;\n }\n\n return parts.join(\" > \");\n}\n\nfunction getXPath(el: HTMLElement): string {\n const parts: string[] = [];\n let current: Node | null = el;\n\n while (current && current !== document) {\n if (current.nodeType === Node.ELEMENT_NODE) {\n const element = current as HTMLElement;\n let index = 1;\n let sibling = element.previousElementSibling;\n while (sibling) {\n if (sibling.tagName === element.tagName) index++;\n sibling = sibling.previousElementSibling;\n }\n parts.unshift(`${element.tagName.toLowerCase()}[${index}]`);\n }\n current = current.parentNode;\n }\n\n return \"/\" + parts.join(\"/\");\n}\n\n// --- Highlight Overlay ---\n\nlet highlightEl: HTMLDivElement | null = null;\n\nexport function showHighlight(rect: {\n x: number;\n y: number;\n width: number;\n height: number;\n}): void {\n if (!highlightEl) {\n highlightEl = document.createElement(\"div\");\n highlightEl.style.cssText = `\n position: fixed;\n pointer-events: none;\n z-index: 2147483646;\n border: 2px solid #6c5ce7;\n background: rgba(108, 92, 231, 0.1);\n transition: all 0.1s ease;\n `;\n highlightEl.dataset.openmagic = \"highlight\";\n document.body.appendChild(highlightEl);\n }\n\n highlightEl.style.left = `${rect.x}px`;\n highlightEl.style.top = `${rect.y}px`;\n highlightEl.style.width = `${rect.width}px`;\n highlightEl.style.height = `${rect.height}px`;\n highlightEl.style.display = \"block\";\n}\n\nexport function hideHighlight(): void {\n if (highlightEl) {\n highlightEl.style.display = \"none\";\n }\n}\n\nexport function removeHighlight(): void {\n if (highlightEl) {\n highlightEl.remove();\n highlightEl = null;\n }\n}\n","// Simple screenshot capture using Canvas API\n// Falls back to a simpler approach if html-to-image isn't available\n\nexport async function captureScreenshot(\n target?: HTMLElement\n): Promise<string | null> {\n try {\n // Try using the Canvas approach for element capture\n if (target) {\n return await captureElementViaCanvas(target);\n }\n\n // Full page: use a simple canvas capture of the viewport\n return await captureViewport();\n } catch (e) {\n console.warn(\"[OpenMagic] Screenshot capture failed:\", e);\n return null;\n }\n}\n\nasync function captureViewport(): Promise<string | null> {\n // Create a canvas the size of the viewport\n const canvas = document.createElement(\"canvas\");\n const dpr = window.devicePixelRatio || 1;\n canvas.width = window.innerWidth * dpr;\n canvas.height = window.innerHeight * dpr;\n const ctx = canvas.getContext(\"2d\")!;\n ctx.scale(dpr, dpr);\n\n // We can't directly capture the viewport without html2canvas or similar\n // Instead, we use the SVG foreignObject approach (snapdom-like)\n try {\n const svgData = await elementToSvg(document.body);\n const img = await svgToImage(svgData, window.innerWidth, window.innerHeight);\n ctx.drawImage(img, 0, 0);\n return canvas.toDataURL(\"image/png\");\n } catch {\n return null;\n }\n}\n\nasync function captureElementViaCanvas(\n element: HTMLElement\n): Promise<string | null> {\n const rect = element.getBoundingClientRect();\n const canvas = document.createElement(\"canvas\");\n const dpr = window.devicePixelRatio || 1;\n canvas.width = rect.width * dpr;\n canvas.height = rect.height * dpr;\n const ctx = canvas.getContext(\"2d\")!;\n ctx.scale(dpr, dpr);\n\n try {\n const svgData = await elementToSvg(element);\n const img = await svgToImage(svgData, rect.width, rect.height);\n ctx.drawImage(img, 0, 0);\n return canvas.toDataURL(\"image/png\");\n } catch {\n return null;\n }\n}\n\nfunction elementToSvg(element: HTMLElement): Promise<string> {\n return new Promise((resolve) => {\n const clone = element.cloneNode(true) as HTMLElement;\n\n // Inline computed styles on the clone\n inlineStyles(element, clone);\n\n const rect = element.getBoundingClientRect();\n const width = rect.width;\n const height = rect.height;\n\n const foreignObject = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${width}\" height=\"${height}\">\n <foreignObject width=\"100%\" height=\"100%\">\n <div xmlns=\"http://www.w3.org/1999/xhtml\" style=\"width:${width}px;height:${height}px;overflow:hidden;\">\n ${clone.outerHTML}\n </div>\n </foreignObject>\n </svg>`;\n\n resolve(foreignObject);\n });\n}\n\nfunction inlineStyles(source: HTMLElement, target: HTMLElement): void {\n const computed = window.getComputedStyle(source);\n let cssText = \"\";\n for (let i = 0; i < computed.length; i++) {\n const prop = computed[i];\n cssText += `${prop}:${computed.getPropertyValue(prop)};`;\n }\n target.style.cssText = cssText;\n\n const sourceChildren = source.children;\n const targetChildren = target.children;\n for (let i = 0; i < sourceChildren.length && i < targetChildren.length; i++) {\n inlineStyles(\n sourceChildren[i] as HTMLElement,\n targetChildren[i] as HTMLElement\n );\n }\n}\n\nfunction svgToImage(\n svgData: string,\n width: number,\n height: number\n): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n const blob = new Blob([svgData], { type: \"image/svg+xml;charset=utf-8\" });\n const url = URL.createObjectURL(blob);\n\n img.onload = () => {\n URL.revokeObjectURL(url);\n resolve(img);\n };\n img.onerror = () => {\n URL.revokeObjectURL(url);\n reject(new Error(\"Failed to load SVG image\"));\n };\n\n img.width = width;\n img.height = height;\n img.src = url;\n });\n}\n","import type { SelectedElement } from \"./dom-inspector.js\";\n\n// --- Network Log Capture ---\n\ninterface NetworkEntry {\n method: string;\n url: string;\n status?: number;\n duration?: number;\n timestamp: number;\n}\n\nconst networkLogs: NetworkEntry[] = [];\nconst MAX_NETWORK_LOGS = 50;\n\nlet networkCaptureInstalled = false;\n\nexport function installNetworkCapture(): void {\n if (networkCaptureInstalled) return;\n networkCaptureInstalled = true;\n\n // Intercept fetch\n const originalFetch = window.fetch;\n window.fetch = async function (...args) {\n const request = new Request(...args);\n const entry: NetworkEntry = {\n method: request.method,\n url: request.url,\n timestamp: Date.now(),\n };\n\n try {\n const response = await originalFetch.apply(this, args);\n entry.status = response.status;\n entry.duration = Date.now() - entry.timestamp;\n addNetworkEntry(entry);\n return response;\n } catch (e) {\n entry.status = 0;\n entry.duration = Date.now() - entry.timestamp;\n addNetworkEntry(entry);\n throw e;\n }\n };\n\n // Intercept XMLHttpRequest\n const originalOpen = XMLHttpRequest.prototype.open;\n const originalSend = XMLHttpRequest.prototype.send;\n\n XMLHttpRequest.prototype.open = function (method: string, url: string, ...rest: any[]) {\n (this as any).__om_method = method;\n (this as any).__om_url = url;\n (this as any).__om_start = Date.now();\n return originalOpen.apply(this, [method, url, ...rest] as any);\n };\n\n XMLHttpRequest.prototype.send = function (...args) {\n this.addEventListener(\"loadend\", () => {\n addNetworkEntry({\n method: (this as any).__om_method || \"GET\",\n url: (this as any).__om_url || \"\",\n status: this.status,\n duration: Date.now() - ((this as any).__om_start || Date.now()),\n timestamp: (this as any).__om_start || Date.now(),\n });\n });\n return originalSend.apply(this, args);\n };\n}\n\nfunction addNetworkEntry(entry: NetworkEntry): void {\n // Filter out OpenMagic's own requests\n if (entry.url.includes(\"__openmagic__\")) return;\n networkLogs.push(entry);\n if (networkLogs.length > MAX_NETWORK_LOGS) {\n networkLogs.shift();\n }\n}\n\nexport function getNetworkLogs(): NetworkEntry[] {\n return [...networkLogs];\n}\n\nexport function clearNetworkLogs(): void {\n networkLogs.length = 0;\n}\n\n// --- Console Log Capture ---\n\ninterface ConsoleEntry {\n level: \"log\" | \"warn\" | \"error\" | \"info\" | \"debug\";\n args: string[];\n timestamp: number;\n}\n\nconst consoleLogs: ConsoleEntry[] = [];\nconst MAX_CONSOLE_LOGS = 100;\n\nlet consoleCaptureInstalled = false;\n\nexport function installConsoleCapture(): void {\n if (consoleCaptureInstalled) return;\n consoleCaptureInstalled = true;\n\n const levels: ConsoleEntry[\"level\"][] = [\"log\", \"warn\", \"error\", \"info\", \"debug\"];\n\n for (const level of levels) {\n const original = console[level];\n console[level] = function (...args: any[]) {\n consoleLogs.push({\n level,\n args: args.map((a) => {\n try {\n return typeof a === \"object\" ? JSON.stringify(a).slice(0, 500) : String(a);\n } catch {\n return String(a);\n }\n }),\n timestamp: Date.now(),\n });\n\n if (consoleLogs.length > MAX_CONSOLE_LOGS) {\n consoleLogs.shift();\n }\n\n original.apply(console, args);\n };\n }\n}\n\nexport function getConsoleLogs(): ConsoleEntry[] {\n return [...consoleLogs];\n}\n\nexport function clearConsoleLogs(): void {\n consoleLogs.length = 0;\n}\n\n// --- Context Builder ---\n\nexport function buildContext(\n selectedElement: SelectedElement | null,\n screenshot: string | null\n) {\n return {\n selectedElement: selectedElement\n ? {\n tagName: selectedElement.tagName,\n id: selectedElement.id,\n className: selectedElement.className,\n textContent: selectedElement.textContent,\n outerHTML: selectedElement.outerHTML,\n cssSelector: selectedElement.cssSelector,\n computedStyles: selectedElement.computedStyles,\n }\n : undefined,\n screenshot: screenshot || undefined,\n networkLogs: getNetworkLogs().map((l) => ({\n method: l.method,\n url: l.url,\n status: l.status,\n duration: l.duration,\n timestamp: l.timestamp,\n })),\n consoleLogs: getConsoleLogs().map((l) => ({\n level: l.level,\n args: l.args,\n timestamp: l.timestamp,\n })),\n };\n}\n","import { TOOLBAR_CSS } from \"./styles/toolbar.css.js\";\nimport * as ws from \"./services/ws-client.js\";\nimport { inspectElement, showHighlight, hideHighlight, type SelectedElement } from \"./services/dom-inspector.js\";\nimport { captureScreenshot } from \"./services/capture.js\";\nimport { installNetworkCapture, installConsoleCapture, buildContext } from \"./services/context-builder.js\";\n\n// ── SVG Icons (Lucide-style) ─────────────────────────────────────\nconst ICON = {\n sparkle: `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.582a.5.5 0 0 1 0 .962L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z\"/></svg>`,\n crosshair: `<svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"22\" y1=\"12\" x2=\"18\" y2=\"12\"/><line x1=\"6\" y1=\"12\" x2=\"2\" y2=\"12\"/><line x1=\"12\" y1=\"6\" x2=\"12\" y2=\"2\"/><line x1=\"12\" y1=\"22\" x2=\"12\" y2=\"18\"/></svg>`,\n camera: `<svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M14.5 4h-5L7 7H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3l-2.5-3z\"/><circle cx=\"12\" cy=\"13\" r=\"3\"/></svg>`,\n chat: `<svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"/></svg>`,\n settings: `<svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z\"/><circle cx=\"12\" cy=\"12\" r=\"3\"/></svg>`,\n send: `<svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"/><polygon points=\"22 2 15 22 11 13 2 9 22 2\"/></svg>`,\n x: `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/></svg>`,\n externalLink: `<svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\"/><polyline points=\"15 3 21 3 21 9\"/><line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\"/></svg>`,\n check: `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><polyline points=\"20 6 9 17 4 12\"/></svg>`,\n grip: `<svg width=\"7\" height=\"14\" viewBox=\"0 0 8 14\" fill=\"currentColor\"><circle cx=\"2\" cy=\"2\" r=\"1.2\"/><circle cx=\"6\" cy=\"2\" r=\"1.2\"/><circle cx=\"2\" cy=\"7\" r=\"1.2\"/><circle cx=\"6\" cy=\"7\" r=\"1.2\"/><circle cx=\"2\" cy=\"12\" r=\"1.2\"/><circle cx=\"6\" cy=\"12\" r=\"1.2\"/></svg>`,\n};\n\n// ── Model Registry (inline for browser bundle) ───────────────────\nconst MODEL_REGISTRY: Record<string, { name: string; models: { id: string; name: string }[]; keyPlaceholder: string; local?: boolean; keyUrl?: string }> = {\n openai: { name: \"OpenAI\", keyUrl: \"https://platform.openai.com/api-keys\", keyPlaceholder: \"sk-...\", models: [\n { id: \"gpt-5.4\", name: \"GPT-5.4\" }, { id: \"gpt-5.4-mini\", name: \"GPT-5.4 Mini\" },\n { id: \"gpt-5.2\", name: \"GPT-5.2 Thinking\" }, { id: \"o3\", name: \"o3\" }, { id: \"o4-mini\", name: \"o4-mini\" },\n { id: \"gpt-4.1\", name: \"GPT-4.1\" }, { id: \"gpt-4.1-mini\", name: \"GPT-4.1 Mini\" },\n ]},\n anthropic: { name: \"Anthropic\", keyUrl: \"https://console.anthropic.com/settings/keys\", keyPlaceholder: \"sk-ant-...\", models: [\n { id: \"claude-opus-4-6\", name: \"Claude Opus 4.6\" }, { id: \"claude-sonnet-4-6\", name: \"Claude Sonnet 4.6\" },\n { id: \"claude-haiku-4-5-20251001\", name: \"Claude Haiku 4.5\" },\n ]},\n google: { name: \"Google Gemini\", keyUrl: \"https://aistudio.google.com/apikey\", keyPlaceholder: \"AIza...\", models: [\n { id: \"gemini-3.1-pro-preview\", name: \"Gemini 3.1 Pro\" }, { id: \"gemini-3-flash-preview\", name: \"Gemini 3 Flash\" },\n { id: \"gemini-2.5-pro\", name: \"Gemini 2.5 Pro\" }, { id: \"gemini-2.5-flash\", name: \"Gemini 2.5 Flash\" },\n ]},\n xai: { name: \"xAI (Grok)\", keyUrl: \"https://console.x.ai/team/default/api-keys\", keyPlaceholder: \"xai-...\", models: [\n { id: \"grok-4.20-0309-reasoning\", name: \"Grok 4.20 Reasoning\" }, { id: \"grok-4-1-fast-non-reasoning\", name: \"Grok 4.1 Fast\" },\n ]},\n deepseek: { name: \"DeepSeek\", keyUrl: \"https://platform.deepseek.com/api_keys\", keyPlaceholder: \"sk-...\", models: [\n { id: \"deepseek-chat\", name: \"DeepSeek V3.2\" }, { id: \"deepseek-reasoner\", name: \"DeepSeek R1\" },\n ]},\n mistral: { name: \"Mistral\", keyUrl: \"https://console.mistral.ai/api-keys\", keyPlaceholder: \"...\", models: [\n { id: \"mistral-large-3-25-12\", name: \"Mistral Large 3\" }, { id: \"codestral-2508\", name: \"Codestral\" }, { id: \"devstral-2-25-12\", name: \"Devstral 2\" },\n ]},\n groq: { name: \"Groq\", keyUrl: \"https://console.groq.com/keys\", keyPlaceholder: \"gsk_...\", models: [\n { id: \"meta-llama/llama-4-scout-17b-16e-instruct\", name: \"Llama 4 Scout\" }, { id: \"llama-3.3-70b-versatile\", name: \"Llama 3.3 70B\" },\n ]},\n minimax: { name: \"MiniMax\", keyUrl: \"https://platform.minimax.chat/user-center/basic-information/interface-key\", keyPlaceholder: \"MiniMax key...\", models: [\n { id: \"MiniMax-M2.7\", name: \"MiniMax M2.7\" }, { id: \"MiniMax-M2.5\", name: \"MiniMax M2.5\" },\n ]},\n moonshot: { name: \"Kimi (Moonshot)\", keyUrl: \"https://platform.moonshot.cn/console/api-keys\", keyPlaceholder: \"Moonshot key...\", models: [\n { id: \"kimi-k2.5\", name: \"Kimi K2.5\" }, { id: \"kimi-k2-thinking\", name: \"Kimi K2 Thinking\" },\n ]},\n qwen: { name: \"Qwen (Alibaba)\", keyUrl: \"https://dashscope.console.aliyun.com/apiKey\", keyPlaceholder: \"DashScope key...\", models: [\n { id: \"qwen3.5-plus\", name: \"Qwen 3.5 Plus\" }, { id: \"qwen-max\", name: \"Qwen Max\" },\n ]},\n zhipu: { name: \"Zhipu AI (GLM)\", keyUrl: \"https://open.bigmodel.cn/usercenter/apikeys\", keyPlaceholder: \"Zhipu key...\", models: [\n { id: \"glm-5\", name: \"GLM-5\" }, { id: \"glm-4.7\", name: \"GLM-4.7\" },\n ]},\n doubao: { name: \"Doubao (ByteDance)\", keyUrl: \"https://console.volcengine.com/ark/region:ark+cn-beijing/apiKey\", keyPlaceholder: \"Volcano key...\", models: [\n { id: \"doubao-seed-2-0-pro\", name: \"Doubao Seed 2.0 Pro\" }, { id: \"doubao-seed-2-0-code\", name: \"Doubao Seed 2.0 Code\" },\n ]},\n ollama: { name: \"Ollama (Local)\", keyPlaceholder: \"not required\", local: true, models: [] },\n openrouter: { name: \"OpenRouter\", keyUrl: \"https://openrouter.ai/settings/keys\", keyPlaceholder: \"sk-or-...\", models: [] },\n};\n\nconst CURRENT_VERSION = \"0.8.1\";\n\n// ── State ────────────────────────────────────────────────────────\nconst state = {\n connected: false,\n panelOpen: false,\n activePanel: \"\" as \"\" | \"chat\" | \"settings\",\n selecting: false,\n selectedElement: null as SelectedElement | null,\n screenshot: null as string | null,\n messages: [] as { role: \"user\" | \"assistant\" | \"system\"; content: string }[],\n streaming: false,\n streamContent: \"\",\n provider: \"\",\n model: \"\",\n hasApiKey: false,\n roots: [] as string[],\n updateAvailable: false,\n latestVersion: \"\",\n saveStatus: \"\" as \"\" | \"saving\" | \"saved\" | \"error\",\n};\n\n// ── DOM refs (created once) ──────────────────────────────────────\nlet shadow: ShadowRoot;\nlet $pill: HTMLDivElement;\nlet $promptBar: HTMLDivElement;\nlet $promptInput: HTMLInputElement;\nlet $promptCtx: HTMLDivElement;\nlet $panel: HTMLDivElement;\nlet $panelBody: HTMLDivElement;\n\n// ── Initialize ───────────────────────────────────────────────────\nfunction init() {\n if (document.querySelector(\"openmagic-toolbar\")) return;\n\n const host = document.createElement(\"openmagic-toolbar\");\n host.dataset.openmagic = \"true\";\n shadow = host.attachShadow({ mode: \"closed\" });\n\n const style = document.createElement(\"style\");\n style.textContent = TOOLBAR_CSS;\n shadow.appendChild(style);\n\n const root = document.createElement(\"div\");\n shadow.appendChild(root);\n\n // Build DOM structure ONCE\n root.innerHTML = buildStaticDOM();\n\n // Cache refs\n $pill = root.querySelector(\".om-pill\")!;\n $promptBar = root.querySelector(\".om-prompt-bar\")!;\n $promptInput = root.querySelector(\".om-prompt-input\")!;\n $promptCtx = root.querySelector(\".om-prompt-context\")!;\n $panel = root.querySelector(\".om-panel\")!;\n $panelBody = root.querySelector(\".om-panel-body\")!;\n\n document.body.appendChild(host);\n\n // Attach event delegation ONCE\n attachGlobalEvents(root);\n setupDraggable();\n\n installNetworkCapture();\n installConsoleCapture();\n checkForUpdates();\n\n // Connect to server\n const config = (window as any).__OPENMAGIC_CONFIG__;\n if (config) {\n ws.connect(config.wsPort, config.token)\n .then(() => {\n state.connected = true;\n updateStatusDot();\n return ws.request(\"config.get\");\n })\n .then((msg: any) => {\n state.provider = msg.payload?.provider || \"\";\n state.model = msg.payload?.model || \"\";\n state.hasApiKey = msg.payload?.hasApiKey || false;\n state.roots = msg.payload?.roots || [];\n if (!state.provider || !state.hasApiKey) {\n openPanel(\"settings\");\n }\n updatePillButtons();\n })\n .catch(() => {\n state.connected = false;\n updateStatusDot();\n });\n }\n}\n\nfunction buildStaticDOM(): string {\n return `\n <div class=\"om-panel om-hidden\">\n <div class=\"om-panel-header\">\n <span class=\"om-panel-title\"></span>\n <span class=\"om-panel-version\">v${CURRENT_VERSION}</span>\n <button class=\"om-panel-close\" data-action=\"close-panel\">${ICON.x}</button>\n </div>\n <div class=\"om-panel-body\"></div>\n </div>\n <div class=\"om-prompt-bar\">\n <div class=\"om-prompt-context\"></div>\n <input class=\"om-prompt-input\" type=\"text\" placeholder=\"Describe what you want to change...\" />\n <button class=\"om-prompt-send\" data-action=\"prompt-send\">${ICON.send}</button>\n </div>\n <div class=\"om-pill\">\n <span class=\"om-grab\">${ICON.grip}</span>\n <span class=\"om-pill-brand\">\n <span class=\"om-pill-icon\">${ICON.sparkle}</span>\n <span class=\"om-pill-text\">OpenMagic</span>\n </span>\n <span class=\"om-pill-divider\"></span>\n <button class=\"om-pill-btn\" data-action=\"select\" title=\"Select element\">${ICON.crosshair}</button>\n <button class=\"om-pill-btn\" data-action=\"screenshot\" title=\"Screenshot\">${ICON.camera}</button>\n <button class=\"om-pill-btn\" data-action=\"chat\" title=\"Chat\">${ICON.chat}</button>\n <button class=\"om-pill-btn\" data-action=\"settings\" title=\"Settings\">${ICON.settings}</button>\n <span class=\"om-status-dot disconnected\"></span>\n </div>`;\n}\n\n// ── Event Delegation (attached ONCE) ─────────────────────────────\nfunction attachGlobalEvents(root: HTMLElement) {\n // Click delegation\n root.addEventListener(\"click\", (e) => {\n const target = (e.target as HTMLElement).closest(\"[data-action]\") as HTMLElement | null;\n if (!target) return;\n e.preventDefault();\n e.stopPropagation();\n const action = target.dataset.action!;\n handleAction(action, target);\n });\n\n // Change delegation (dropdowns)\n root.addEventListener(\"change\", (e) => {\n const target = e.target as HTMLSelectElement;\n const field = target.dataset.field;\n if (!field) return;\n\n if (field === \"provider\") {\n state.provider = target.value;\n state.model = \"\";\n state.saveStatus = \"\";\n refreshPanelContent();\n } else if (field === \"model\") {\n state.model = target.value;\n }\n });\n\n // Prompt input: Enter to send\n $promptInput.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n sendPrompt();\n }\n });\n}\n\nfunction handleAction(action: string, target: HTMLElement) {\n switch (action) {\n case \"select\": toggleSelectMode(); break;\n case \"screenshot\": takeScreenshot(); break;\n case \"chat\": togglePanel(\"chat\"); break;\n case \"settings\": togglePanel(\"settings\"); break;\n case \"close-panel\": closePanel(); break;\n case \"prompt-send\": sendPrompt(); break;\n case \"save-settings\": saveSettings(); break;\n case \"get-key\": {\n const url = target.dataset.url;\n if (url) window.open(url, \"_blank\", \"noopener\");\n break;\n }\n case \"clear-element\": state.selectedElement = null; updatePromptContext(); break;\n case \"clear-screenshot\": state.screenshot = null; updatePromptContext(); break;\n }\n}\n\n// ── Targeted UI Updates (no full DOM rebuild) ────────────────────\n\nfunction updateStatusDot() {\n const dot = shadow.querySelector(\".om-status-dot\");\n if (dot) {\n dot.className = `om-status-dot ${state.connected ? \"connected\" : \"disconnected\"}`;\n }\n}\n\nfunction updatePillButtons() {\n shadow.querySelectorAll(\".om-pill-btn\").forEach((btn) => {\n const action = (btn as HTMLElement).dataset.action;\n btn.classList.toggle(\"active\", action === state.activePanel || (action === \"select\" && state.selecting));\n });\n}\n\nfunction updatePromptContext() {\n const chips: string[] = [];\n if (state.selectedElement) {\n chips.push(`<span class=\"om-prompt-chip\">${state.selectedElement.tagName}${state.selectedElement.id ? \"#\" + state.selectedElement.id : \"\"} <button class=\"om-prompt-chip-x\" data-action=\"clear-element\">${ICON.x}</button></span>`);\n }\n if (state.screenshot) {\n chips.push(`<span class=\"om-prompt-chip\">Screenshot <button class=\"om-prompt-chip-x\" data-action=\"clear-screenshot\">${ICON.x}</button></span>`);\n }\n $promptCtx.innerHTML = chips.join(\"\");\n}\n\n// ── Panel Management ─────────────────────────────────────────────\n\nfunction openPanel(panel: \"chat\" | \"settings\") {\n state.panelOpen = true;\n state.activePanel = panel;\n $panel.classList.remove(\"om-hidden\");\n const title = shadow.querySelector(\".om-panel-title\")!;\n title.textContent = panel === \"settings\" ? \"Settings\" : \"Chat\";\n refreshPanelContent();\n updatePillButtons();\n}\n\nfunction closePanel() {\n state.panelOpen = false;\n state.activePanel = \"\";\n $panel.classList.add(\"om-hidden\");\n updatePillButtons();\n}\n\nfunction togglePanel(panel: \"chat\" | \"settings\") {\n if (state.panelOpen && state.activePanel === panel) {\n closePanel();\n } else {\n openPanel(panel);\n }\n}\n\nfunction refreshPanelContent() {\n if (state.activePanel === \"settings\") {\n $panelBody.innerHTML = renderSettingsHTML();\n } else if (state.activePanel === \"chat\") {\n $panelBody.innerHTML = renderChatHTML();\n scrollChatToBottom();\n }\n}\n\n// ── Settings Renderer ────────────────────────────────────────────\n\nfunction renderSettingsHTML(): string {\n const providerOpts = Object.entries(MODEL_REGISTRY)\n .map(([k, p]) => `<option value=\"${k}\" ${state.provider === k ? \"selected\" : \"\"}>${p.name}</option>`).join(\"\");\n\n const prov = MODEL_REGISTRY[state.provider];\n const modelOpts = prov\n ? prov.models.map(m => `<option value=\"${m.id}\" ${state.model === m.id ? \"selected\" : \"\"}>${m.name}</option>`).join(\"\")\n : '<option value=\"\">Select provider first</option>';\n\n const isLocal = prov?.local || false;\n const keyUrl = prov?.keyUrl || \"\";\n const keyPh = prov?.keyPlaceholder || \"Enter API key...\";\n\n const updateBanner = state.updateAvailable\n ? `<div class=\"om-update-banner\">v${state.latestVersion} available <code class=\"om-update-cmd\">npx openmagic@latest</code></div>` : \"\";\n\n const statusHtml = state.hasApiKey\n ? `<div class=\"om-status om-status-success\">${ICON.check} Connected</div>` : \"\";\n\n const saveBtnText = state.saveStatus === \"saving\" ? '<span class=\"om-spinner\"></span> Saving...'\n : state.saveStatus === \"saved\" ? `${ICON.check} Saved` : \"Save\";\n const saveBtnClass = state.saveStatus === \"saving\" ? \"om-btn om-btn-saving\"\n : state.saveStatus === \"saved\" ? \"om-btn om-btn-saved\" : \"om-btn\";\n const saveBtnDisabled = state.saveStatus === \"saving\" ? \"disabled\" : \"\";\n\n return `\n ${updateBanner}\n <div class=\"om-settings\">\n <div class=\"om-field\">\n <label class=\"om-label\">Provider</label>\n <select class=\"om-select\" data-field=\"provider\"><option value=\"\">Select Provider...</option>${providerOpts}</select>\n </div>\n <div class=\"om-field\">\n <label class=\"om-label\">Model</label>\n <select class=\"om-select\" data-field=\"model\"><option value=\"\">Select Model...</option>${modelOpts}</select>\n </div>\n <div class=\"om-field ${isLocal ? \"om-hidden\" : \"\"}\">\n <label class=\"om-label\">API Key</label>\n <div class=\"om-key-row\">\n <input type=\"text\" class=\"om-input om-key-input\" data-field=\"apiKey\" placeholder=\"${keyPh}\" autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" data-lpignore=\"true\" data-1p-ignore=\"true\" data-form-type=\"other\" />\n ${keyUrl ? `<button class=\"om-btn-get-key\" data-action=\"get-key\" data-url=\"${keyUrl}\">${ICON.externalLink} Get key</button>` : \"\"}\n </div>\n ${keyUrl ? `<div class=\"om-key-hint\"><a data-action=\"get-key\" data-url=\"${keyUrl}\">Get your ${prov?.name || \"\"} API key here</a></div>` : \"\"}\n </div>\n <button class=\"${saveBtnClass}\" data-action=\"save-settings\" ${saveBtnDisabled}>${saveBtnText}</button>\n ${statusHtml}\n </div>`;\n}\n\n// ── Chat Renderer ────────────────────────────────────────────────\n\nfunction renderChatHTML(): string {\n if (!state.hasApiKey || !state.provider) {\n return `<div class=\"om-status om-status-error\">Configure your provider in Settings first</div>`;\n }\n\n const msgs = state.messages.map(m =>\n `<div class=\"om-msg om-msg-${m.role}\">${escapeHtml(m.content)}</div>`\n ).join(\"\");\n\n const streamHtml = state.streaming\n ? `<div class=\"om-msg om-msg-assistant\"><span class=\"om-spinner\"></span>${escapeHtml(state.streamContent)}</div>` : \"\";\n\n const empty = !state.messages.length && !state.streaming\n ? `<div class=\"om-chat-empty\">Select an element or type below to start</div>` : \"\";\n\n return `<div class=\"om-chat-messages\">${empty}${msgs}${streamHtml}</div>`;\n}\n\nfunction scrollChatToBottom() {\n const el = $panelBody.querySelector(\".om-chat-messages\");\n if (el) el.scrollTop = el.scrollHeight;\n}\n\n// ── Save Settings ────────────────────────────────────────────────\n\nasync function saveSettings() {\n const apiKeyInput = $panelBody.querySelector('[data-field=\"apiKey\"]') as HTMLInputElement;\n const apiKey = apiKeyInput?.value || \"\";\n\n if (!state.provider) {\n state.saveStatus = \"error\";\n updateSaveButton();\n setTimeout(() => { state.saveStatus = \"\"; refreshPanelContent(); }, 2000);\n return;\n }\n\n // Check WebSocket connection\n if (!ws.isConnected()) {\n state.saveStatus = \"error\";\n updateSaveButton();\n const btn = $panelBody.querySelector('[data-action=\"save-settings\"]');\n if (btn) btn.innerHTML = \"Not connected - check terminal\";\n setTimeout(() => { state.saveStatus = \"\"; refreshPanelContent(); }, 3000);\n return;\n }\n\n const payload: any = { provider: state.provider, model: state.model };\n if (apiKey) payload.apiKey = apiKey;\n\n state.saveStatus = \"saving\";\n updateSaveButton();\n\n try {\n // Race against a 8s local timeout (don't wait 30s)\n const result = await Promise.race([\n ws.request(\"config.set\", payload),\n new Promise((_, reject) => setTimeout(() => reject(new Error(\"Save timed out\")), 8000)),\n ]);\n state.hasApiKey = !!(apiKey || state.hasApiKey);\n state.saveStatus = \"saved\";\n updateSaveButton();\n\n // Auto-transition to chat after 1.2s\n setTimeout(() => {\n state.saveStatus = \"\";\n if (state.activePanel === \"settings\") {\n openPanel(\"chat\");\n }\n }, 1200);\n } catch (e: any) {\n state.saveStatus = \"error\";\n const btn = $panelBody.querySelector('[data-action=\"save-settings\"]');\n const msg = (e?.message || \"\").includes(\"timeout\") ? \"Connection timeout - is the CLI running?\"\n : (e?.message || \"\").includes(\"connected\") ? \"Not connected to OpenMagic server\"\n : `Save failed: ${e?.message || \"Unknown error\"}`;\n if (btn) {\n btn.innerHTML = msg;\n btn.className = \"om-btn\";\n (btn as HTMLButtonElement).disabled = false;\n }\n setTimeout(() => { state.saveStatus = \"\"; refreshPanelContent(); }, 4000);\n }\n}\n\nfunction updateSaveButton() {\n const btn = $panelBody.querySelector('[data-action=\"save-settings\"]');\n if (!btn) return;\n if (state.saveStatus === \"saving\") {\n btn.innerHTML = '<span class=\"om-spinner\"></span> Saving...';\n btn.className = \"om-btn om-btn-saving\";\n (btn as HTMLButtonElement).disabled = true;\n } else if (state.saveStatus === \"saved\") {\n btn.innerHTML = `${ICON.check} Saved`;\n btn.className = \"om-btn om-btn-saved\";\n (btn as HTMLButtonElement).disabled = false;\n } else if (state.saveStatus === \"error\") {\n btn.innerHTML = \"Save failed - try again\";\n btn.className = \"om-btn\";\n (btn as HTMLButtonElement).disabled = false;\n } else {\n btn.innerHTML = \"Save\";\n btn.className = \"om-btn\";\n (btn as HTMLButtonElement).disabled = false;\n }\n}\n\n// ── Send Prompt ──────────────────────────────────────────────────\n\nasync function sendPrompt() {\n const text = $promptInput.value.trim();\n if (!text || state.streaming) return;\n\n if (!state.hasApiKey || !state.provider) {\n openPanel(\"settings\");\n return;\n }\n\n // Add user message\n state.messages.push({ role: \"user\", content: text });\n state.streaming = true;\n state.streamContent = \"\";\n $promptInput.value = \"\";\n\n // Open chat panel\n openPanel(\"chat\");\n\n // Build context — includes page info, selected element, screenshot, network/console logs\n const context: any = buildContext(state.selectedElement, state.screenshot);\n\n // Add current page context\n context.pageUrl = window.location.href;\n context.pageTitle = document.title;\n\n try {\n const result = await ws.stream(\n \"llm.chat\",\n {\n provider: state.provider,\n model: state.model,\n messages: state.messages.map(m => ({ role: m.role, content: m.content })),\n context,\n },\n (chunk: string) => {\n state.streamContent += chunk;\n // Update the streaming message in-place\n const msgEl = $panelBody.querySelector(\".om-msg-assistant:last-child\");\n if (msgEl) {\n msgEl.innerHTML = `<span class=\"om-spinner\"></span>${escapeHtml(state.streamContent)}`;\n scrollChatToBottom();\n }\n }\n );\n\n state.messages.push({ role: \"assistant\", content: state.streamContent || result?.content || \"\" });\n\n // Apply code modifications if any\n if (result?.modifications?.length) {\n for (const mod of result.modifications) {\n if (mod.type === \"edit\" && mod.file && mod.search && mod.replace) {\n try {\n const fileResult = await ws.request(\"fs.read\", { path: resolveFilePath(mod.file) });\n const content = fileResult.payload?.content;\n if (content?.includes(mod.search)) {\n await ws.request(\"fs.write\", { path: resolveFilePath(mod.file), content: content.replace(mod.search, mod.replace) });\n state.messages.push({ role: \"system\", content: `Applied change to ${mod.file}` });\n }\n } catch (e: any) {\n state.messages.push({ role: \"system\", content: `Failed: ${mod.file} - ${e.message}` });\n }\n }\n }\n }\n } catch (e: any) {\n state.messages.push({ role: \"system\", content: `Error: ${e.message}` });\n }\n\n state.streaming = false;\n state.streamContent = \"\";\n refreshPanelContent();\n}\n\nfunction resolveFilePath(rel: string): string {\n return state.roots.length > 0 ? state.roots[0] + \"/\" + rel : rel;\n}\n\n// ── Select Mode ──────────────────────────────────────────────────\n\nlet selectHandler: ((e: MouseEvent) => void) | null = null;\nlet hoverHandler: ((e: MouseEvent) => void) | null = null;\n\nfunction toggleSelectMode() {\n state.selecting ? exitSelectMode() : enterSelectMode();\n}\n\nfunction enterSelectMode() {\n state.selecting = true;\n document.body.style.cursor = \"crosshair\";\n updatePillButtons();\n\n hoverHandler = (e: MouseEvent) => {\n const t = e.target as HTMLElement;\n if (t.closest(\"openmagic-toolbar\") || t.dataset?.openmagic) return;\n const r = t.getBoundingClientRect();\n showHighlight({ x: r.x, y: r.y, width: r.width, height: r.height });\n };\n\n selectHandler = (e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n const t = e.target as HTMLElement;\n if (t.closest(\"openmagic-toolbar\") || t.dataset?.openmagic) return;\n state.selectedElement = inspectElement(t);\n exitSelectMode();\n updatePromptContext();\n $promptInput.focus();\n };\n\n document.addEventListener(\"mousemove\", hoverHandler, true);\n document.addEventListener(\"click\", selectHandler, true);\n}\n\nfunction exitSelectMode() {\n state.selecting = false;\n document.body.style.cursor = \"\";\n hideHighlight();\n if (hoverHandler) { document.removeEventListener(\"mousemove\", hoverHandler, true); hoverHandler = null; }\n if (selectHandler) { document.removeEventListener(\"click\", selectHandler, true); selectHandler = null; }\n updatePillButtons();\n}\n\nasync function takeScreenshot() {\n const ss = await captureScreenshot();\n if (ss) {\n state.screenshot = ss;\n updatePromptContext();\n $promptInput.focus();\n }\n}\n\n// ── Draggable (setup ONCE) ───────────────────────────────────────\n\nfunction setupDraggable() {\n let active = false, startX = 0, startY = 0, origX = 0, origY = 0;\n\n $pill.addEventListener(\"mousedown\", (e) => {\n const t = e.target as HTMLElement;\n if (t.closest(\"[data-action]\")) return;\n if (!t.closest(\".om-grab\") && !t.closest(\".om-pill-brand\")) return;\n active = true;\n startX = e.clientX; startY = e.clientY;\n const r = $pill.getBoundingClientRect();\n origX = r.left; origY = r.top;\n e.preventDefault();\n });\n\n document.addEventListener(\"mousemove\", (e) => {\n if (!active) return;\n $pill.style.left = (origX + e.clientX - startX) + \"px\";\n $pill.style.top = (origY + e.clientY - startY) + \"px\";\n $pill.style.right = \"auto\";\n $pill.style.bottom = \"auto\";\n // Move prompt bar and panel with pill\n const pillRect = $pill.getBoundingClientRect();\n $promptBar.style.right = \"auto\";\n $promptBar.style.bottom = \"auto\";\n $promptBar.style.left = pillRect.left + \"px\";\n $promptBar.style.top = (pillRect.top - 42) + \"px\";\n $panel.style.right = \"auto\";\n $panel.style.bottom = \"auto\";\n $panel.style.left = pillRect.left + \"px\";\n $panel.style.top = (pillRect.top - 42 - ($panel.classList.contains(\"om-hidden\") ? 0 : $panel.offsetHeight + 6)) + \"px\";\n });\n\n document.addEventListener(\"mouseup\", () => { active = false; });\n}\n\n// ── Helpers ──────────────────────────────────────────────────────\n\nfunction escapeHtml(text: string): string {\n const d = document.createElement(\"div\");\n d.textContent = text;\n return d.innerHTML;\n}\n\nfunction checkForUpdates() {\n fetch(\"https://registry.npmjs.org/openmagic/latest\", {\n headers: { Accept: \"application/json\" },\n signal: AbortSignal.timeout(5000),\n }).then(r => r.ok ? r.json() : null).then(d => {\n if (!d?.version) return;\n const l = d.version.split(\".\").map(Number), c = CURRENT_VERSION.split(\".\").map(Number);\n for (let i = 0; i < 3; i++) { if ((l[i]||0) > (c[i]||0)) { state.updateAvailable = true; state.latestVersion = d.version; showUpdateDot(); return; } if ((l[i]||0) < (c[i]||0)) return; }\n }).catch(() => {});\n}\n\nfunction showUpdateDot() {\n const existing = shadow.querySelector(\".om-update-dot\");\n if (existing) return;\n const dot = document.createElement(\"span\");\n dot.className = \"om-update-dot\";\n dot.title = `v${state.latestVersion} available`;\n dot.addEventListener(\"click\", () => openPanel(\"settings\"));\n $pill.appendChild(dot);\n}\n\n// ── Boot ─────────────────────────────────────────────────────────\nif (typeof window !== \"undefined\") {\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", init);\n } else {\n init();\n }\n}\n"],"mappings":";wCAAO,IAAMA,EAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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","names":["TOOLBAR_CSS","ws","handlers","globalHandlers","messageQueue","connected","reconnectTimer","generateId","connect","port","token","resolve","reject","handshakeId","send","msg","queued","event","handler","e","data","request","type","payload","id","timeout","stream","onChunk","isConnected","connected","IMPORTANT_STYLES","inspectElement","el","computed","styles","prop","rect","getCleanOuterHTML","getCssSelector","getXPath","clone","s","html","tag","attrs","a","childSummary","c","parts","current","selector","classes","parent","siblings","index","element","sibling","highlightEl","showHighlight","hideHighlight","captureScreenshot","target","captureElementViaCanvas","captureViewport","e","canvas","dpr","ctx","svgData","elementToSvg","img","svgToImage","element","rect","resolve","clone","inlineStyles","width","height","foreignObject","source","computed","cssText","i","prop","sourceChildren","targetChildren","reject","blob","url","networkLogs","networkCaptureInstalled","installNetworkCapture","originalFetch","args","request","entry","response","addNetworkEntry","e","originalOpen","originalSend","method","url","rest","networkLogs","getNetworkLogs","consoleLogs","MAX_CONSOLE_LOGS","consoleCaptureInstalled","installConsoleCapture","levels","level","original","args","a","getConsoleLogs","buildContext","selectedElement","screenshot","getNetworkLogs","l","getConsoleLogs","ICON","MODEL_REGISTRY","CURRENT_VERSION","state","shadow","$pill","$promptBar","$promptInput","$promptCtx","$panel","$panelBody","init","host","style","TOOLBAR_CSS","root","buildStaticDOM","attachGlobalEvents","setupDraggable","installNetworkCapture","installConsoleCapture","checkForUpdates","config","connect","updateStatusDot","request","msg","openPanel","updatePillButtons","e","target","action","handleAction","field","refreshPanelContent","sendPrompt","toggleSelectMode","takeScreenshot","togglePanel","closePanel","saveSettings","url","updatePromptContext","dot","btn","chips","panel","title","renderSettingsHTML","renderChatHTML","scrollChatToBottom","providerOpts","k","p","prov","modelOpts","m","isLocal","keyUrl","keyPh","updateBanner","statusHtml","saveBtnText","saveBtnClass","saveBtnDisabled","msgs","escapeHtml","streamHtml","el","apiKey","updateSaveButton","isConnected","payload","result","_","reject","text","context","buildContext","stream","chunk","msgEl","mod","content","resolveFilePath","rel","selectHandler","hoverHandler","exitSelectMode","enterSelectMode","r","showHighlight","inspectElement","hideHighlight","ss","captureScreenshot","active","startX","startY","origX","origY","t","pillRect","d","l","c","i","showUpdateDot"]}
|
package/package.json
CHANGED