@mrrocket/sdk 0.22.0 → 0.23.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/CHANGELOG.md +20 -6
- package/dist/api-client.d.ts +14 -1
- package/dist/api-client.js +13 -4
- package/dist/api-client.js.map +1 -1
- package/dist/browser/mrrocket-flows.js +2 -2
- package/dist/browser/mrrocket-messenger.js +14 -5
- package/dist/browser/mrrocket.js +1 -1
- package/dist/client.js +36 -17
- package/dist/client.js.map +1 -1
- package/dist/core.d.ts +3 -1
- package/dist/core.js +3 -1
- package/dist/core.js.map +1 -1
- package/dist/messenger-ui.d.ts +2 -0
- package/dist/messenger-ui.js +138 -25
- package/dist/messenger-ui.js.map +1 -1
- package/dist/messenger.js +1 -0
- package/dist/messenger.js.map +1 -1
- package/dist/react-native/index.d.cts +5 -2
- package/dist/react-native/index.d.ts +5 -2
- package/dist/react-native/index.js +18 -8
- package/dist/react-native/index.js.map +1 -1
- package/dist/styles-css.d.ts +1 -1
- package/dist/styles-css.js +11 -2
- package/dist/styles-css.js.map +1 -1
- package/package.json +1 -1
package/dist/messenger-ui.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/messenger-ui.ts"],"sourcesContent":["/**\n * The web messenger, after Crisp's: a round launcher (a click opens it, no card on hover) and a panel\n * with a bar on top (Home, a \"Chat · Help\" switch while there are both, a ⋮ menu to minimize or widen it). Home shows the greeting,\n * the latest chat and the help search; Chat is the chat with the team, answered in MRRocket › Support by the owner or\n * the Customer experience agent; Help lists the product's published help articles by collection, searchable, read in\n * the panel. While the panel is closed it checks for answers now and then; a new answer plays a short sound, shows a\n * count on the launcher and a preview card above it. Opening, closing, switching and new messages move softly\n * (none of it with reduced motion).\n *\n * A visitor can have several conversations (0.19): Home's \"Ask a question\" starts a new one, the field inside a chat\n * answers in that chat, and Home and Messages list the others.\n *\n * Plain DOM, no React, so `<Messenger />` (Next.js) and the script tag share it; both load it only when it is used (a\n * dynamic import, and `sdk-messenger.js` for the script tag). Every text is set with textContent; articles arrive as\n * blocks, never HTML.\n */\nimport {\n type Api,\n type ArticleBlock,\n type ArticleSpan,\n type ArticleSummary,\n BRAND_URL,\n CHAT_FILES_PER_MESSAGE,\n CHAT_FILE_MAX_BYTES,\n CHAT_FILE_TYPES,\n type ChatFile,\n type ChatMessage,\n type ChatSummary,\n type ChatThread,\n type MessengerCorners,\n type MessengerLook,\n type MessengerPosition,\n createApi,\n inkOn,\n replyLine,\n type ChangelogEntry,\n} from \"./api-client\";\nimport { currentLocale, onWords, t, tf, wordsLang, wordsVersion } from \"./i18n\";\nimport { injectStyles } from \"./styles-css\";\n\nexport interface MessengerUiOptions {\n host: string;\n apiKey: string;\n /** The visitor id now (it changes on identify and reset). */\n distinctId: () => string;\n /** The signed-in person's id, name and email, when the site called identify. */\n user: () => { id?: string; name?: string; email?: string } | undefined;\n /** The identity hash of the visitor id now (0.16.0), when the site gave one to identify. */\n userHash?: () => string | undefined;\n /** Show the round launcher (default true). Without it the panel opens only through `open()`. */\n launcher?: boolean;\n /** Where the launcher sits (default bottom right); the panel and the cards open from there. */\n position?: MessengerPosition;\n /** The team's name beside its mark on Home. */\n title?: string;\n /** The big line on Home and the first line of an empty chat. */\n greeting?: string;\n /** Ask anonymous visitors for an email (optional for them). Default true. */\n askEmail?: boolean;\n /** Text on the launcher; empty shows the icon only. */\n label?: string;\n /** How soon the team usually answers, said under \"Send us a message\" and in the chat's head. */\n replyTime?: \"minutes\" | \"hours\" | \"day\";\n /** The Help tab with the product's published help articles (default true; hidden while there are none). */\n help?: boolean;\n /** The Updates tab with your published changelog (default true; hidden while there are none). */\n updates?: boolean;\n /** A short sound when an answer arrives (default true). */\n sound?: boolean;\n /** A preview of a new answer above the closed launcher (default true). */\n preview?: boolean;\n theme?: \"light\" | \"dark\" | \"auto\";\n accent?: string;\n /** Up to two more colors blended with the accent in Home's background glow. */\n glow?: string[];\n /** How round panel, bubbles, cards and fields are (default round). */\n corners?: MessengerCorners;\n /** The site's own font (default) or the system's. */\n font?: \"site\" | \"system\";\n /** Home's top: plain (default) or in the accent color. */\n header?: \"plain\" | \"color\";\n /** \"Powered by MRRocket\" at the bottom; MRRocket's server says whether the plan may hide it. */\n branding?: boolean;\n /** The logo at the top left of Home (MRRocket sends the uploaded logo, else the favicon); without it the title's first letter. */\n logo?: string;\n /** The round mark in the chat's head (MRRocket sends the favicon); without it the title's first letter. */\n icon?: string;\n /** The AI agent's name on its answers (default \"AI agent\"). */\n agentName?: string;\n /** The AI agent's picture beside its answers. */\n agentPhoto?: string;\n /** MRRocket's own preview: mount inside this element (positioned) instead of the page. */\n container?: HTMLElement;\n /** MRRocket's own preview: answers from here instead of the server. */\n client?: MessengerClient;\n /** MRRocket's own preview: start open on this view, without the opening motion. */\n opened?: MessengerView;\n}\n\n/** What the messenger asks the server (createApi's part it uses). */\nexport type MessengerClient = Pick<Api, \"chat\" | \"sendChat\" | \"uploadChatFile\" | \"attachmentUrl\" | \"articles\" | \"article\" | \"rateArticle\" | \"messengerLook\" | \"changelog\">;\n\nexport type MessengerView = \"home\" | \"messages\" | \"help\" | \"updates\";\n\nexport interface MessengerHandle {\n /** Opens the panel, on Home or the given tab; `{ article }` opens a help article. */\n open(view?: MessengerView | { article: string }): void;\n close(): void;\n toggle(): void;\n /** Removes the launcher and the panel from the page. */\n destroy(): void;\n}\n\n/** A long changelog stays light: the newest ones, the rest live on the product's changelog page. */\nconst UPDATES_SHOWN = 20;\nconst POLL_OPEN_MS = 4000;\n/** While the panel is closed: soon after the visitor wrote, answers are looked for often, later now and then. */\nconst POLL_WAITING_MS = 8000;\nconst POLL_IDLE_MS = 30000;\n/**\n * Nothing to wait for, page in view: a slow read, so a message the team starts (Inbox › Support › New message) reaches\n * someone who has the product open. Only for those the team can write to: signed in, or with a chat already.\n */\nconst POLL_QUIET_MS = 60000;\nconst WAITING_FOR_MS = 10 * 60_000;\n/** A message the server has not taken after this long reads \"Sending…\"; until then it reads \"just now\", like a sent one. */\nconst SLOW_SEND_MS = 1500;\nconst EMAIL = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]{2,}$/;\n/** The newest answer seen in the one chat a visitor had before 0.19; it still counts for that chat. */\nconst SEEN_KEY = \"ckw_msgr_seen\";\n/** When a conversation was last read, per conversation. */\nconst SEEN_CHATS_KEY = \"ckw_msgr_seen_chats\";\n\nconst readSeen = (): { old: string; chats: Record<string, string> } => {\n try {\n return { old: window.localStorage.getItem(SEEN_KEY) ?? \"\", chats: JSON.parse(window.localStorage.getItem(SEEN_CHATS_KEY) ?? \"{}\") as Record<string, string> };\n } catch {\n return { old: \"\", chats: {} };\n }\n};\nconst writeSeen = (chats: Record<string, string>) => {\n try {\n window.localStorage.setItem(SEEN_CHATS_KEY, JSON.stringify(chats));\n } catch {\n // Private mode: the count just shows again next time.\n }\n};\n\nconst timeAgo = (iso: string) => {\n const at = new Date(iso).getTime();\n if (Number.isNaN(at)) return \"\";\n const d = Math.max(0, Date.now() - at) / 1000;\n if (d < 60) return t(\"just now\");\n if (d < 3600) return tf(\"{n}m ago\", { n: Math.floor(d / 60) });\n if (d < 86400) return tf(\"{n}h ago\", { n: Math.floor(d / 3600) });\n if (d < 86400 * 30) return tf(\"{n}d ago\", { n: Math.floor(d / 86400) });\n return new Date(iso).toLocaleDateString(currentLocale(), { month: \"short\", day: \"numeric\", year: \"numeric\" });\n};\n\nconst el = <K extends keyof HTMLElementTagNameMap>(tag: K, attrs: Record<string, string> = {}, ...kids: (Node | string | null | false | undefined)[]) => {\n const e = document.createElement(tag);\n for (const [k, v] of Object.entries(attrs)) e.setAttribute(k, v);\n for (const k of kids) if (k !== null && k !== false && k !== undefined) e.append(k);\n return e;\n};\n\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\n/** A line icon on a 24-unit grid (Lucide's shapes, ISC). */\nconst icon = (d: string, size = 16) => {\n const svg = document.createElementNS(SVG_NS, \"svg\");\n for (const [k, v] of Object.entries({ class: \"ckw-icon\", width: String(size), height: String(size), viewBox: \"0 0 24 24\", fill: \"none\", stroke: \"currentColor\", \"stroke-width\": \"1.75\", \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\", \"aria-hidden\": \"true\" }))\n svg.setAttribute(k, v);\n const path = document.createElementNS(SVG_NS, \"path\");\n path.setAttribute(\"d\", d);\n svg.appendChild(path);\n return svg;\n};\nconst I = {\n cross: \"M18 6 6 18M6 6l12 12\",\n chat: \"M7.9 20A9 9 0 1 0 4 16.1L2 22z\",\n send: \"M5 12h14M12 5l7 7-7 7\",\n up: \"M12 19V5M5 12l7-7 7 7\",\n home: \"M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\",\n back: \"m15 18-6-6 6-6\",\n next: \"m9 18 6-6-6-6\",\n search: \"M19 11a8 8 0 1 1-16 0 8 8 0 0 1 16 0zM21 21l-4.3-4.3\",\n doc: \"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7zM14 2v4a2 2 0 0 0 2 2h4M10 9H8M16 13H8M16 17H8\",\n book: \"M12 7v14M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z\",\n dots: \"M13 12a1 1 0 1 1-2 0 1 1 0 0 1 2 0zM13 5a1 1 0 1 1-2 0 1 1 0 0 1 2 0zM13 19a1 1 0 1 1-2 0 1 1 0 0 1 2 0z\",\n expand: \"M15 3h6v6M21 3l-7 7M3 21l7-7M9 21H3v-6\",\n collapse: \"m14 10 7-7M20 10h-6V4M3 21l7-7M4 14h6v6\",\n minus: \"M5 12h14\",\n down: \"m6 9 6 6 6-6\",\n help: \"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20zM9.1 9a3 3 0 0 1 5.8 1c0 2-3 3-3 3M12 17h.01\",\n updates: \"m3 11 18-5v12L3 14zM11.6 16.8a3 3 0 1 1-5.8-1.6\",\n clip: \"m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l8.57-8.57A4 4 0 1 1 18 8.84l-8.59 8.57a2 2 0 0 1-2.83-2.83l8.49-8.48\",\n image: \"M19 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2zM9 11a2 2 0 1 0 0-4 2 2 0 0 0 0 4zM21 15l-3.09-3.09a2 2 0 0 0-2.82 0L6 21\",\n screen: \"M20 3H4a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2zM8 21h8M12 17v4\",\n};\n\n/** A message's words for a one-line preview: its text, or what it sent. */\nconst lineOf = (m: ChatMessage) => m.body || (m.attachments?.length === 1 ? tf(\"Sent {name}\", { name: m.attachments[0].name }) : m.attachments?.length ? tf(\"Sent {n} files\", { n: m.attachments.length }) : \"\");\n\n/** The browser can grab a picture of this tab (not on phones, where people screenshot with the phone and attach it). */\nconst canShoot = () => typeof navigator !== \"undefined\" && typeof navigator.mediaDevices?.getDisplayMedia === \"function\";\n/** The launcher's filled bubble (24-unit grid). */\nconst BUBBLE = \"M7.9 20A9 9 0 1 0 4 16.1L2 22z\";\nconst filled = (d: string, size: number) => {\n const svg = document.createElementNS(SVG_NS, \"svg\");\n for (const [k, v] of Object.entries({ class: \"ckw-icon\", width: String(size), height: String(size), viewBox: \"0 0 24 24\", fill: \"currentColor\", stroke: \"currentColor\", \"stroke-width\": \"1.5\", \"stroke-linejoin\": \"round\", \"aria-hidden\": \"true\" }))\n svg.setAttribute(k, v);\n const path = document.createElementNS(SVG_NS, \"path\");\n path.setAttribute(\"d\", d);\n svg.appendChild(path);\n return svg;\n};\n\n/** A filled shape with lines cut into it in the ground's color (`.ckw-cut`): the current tab's icon, the launcher's bubble. */\nconst duo = (shape: string, cut: string, size: number, width = 2) => {\n const svg = filled(shape, size);\n const path = document.createElementNS(SVG_NS, \"path\");\n for (const [k, v] of Object.entries({ d: cut, class: \"ckw-cut\", fill: \"none\", \"stroke-width\": String(width), \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\" })) path.setAttribute(k, v);\n svg.appendChild(path);\n return svg;\n};\nconst DOTS = \"M8 12h.01M12 12h.01M16 12h.01\";\nconst HOUSE = \"M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\";\nconst SMILE = \"M9.5 15.5c1.4 1 3.6 1 5 0\";\nconst DISC = \"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20z\";\nconst QMARK = \"M9.4 9.2a2.7 2.7 0 0 1 5.2 1c0 1.8-2.6 2.5-2.6 2.5M12 16.8h.01\";\nconst MEGAPHONE = \"m3 11 18-5v12L3 14zM5.8 15.2a3 3 0 0 0 5.8 1.6z\";\n\n/** A soft two-note chime made with Web Audio (no file to load). Browsers allow it once the visitor has clicked. */\nconst chime = (() => {\n let ctx: AudioContext | null = null;\n const get = () => {\n const AC = window.AudioContext ?? (window as unknown as { webkitAudioContext?: typeof AudioContext }).webkitAudioContext;\n if (!AC) return null;\n ctx ??= new AC();\n return ctx;\n };\n return {\n /** Call from a click so later sounds may play. */\n unlock: () => {\n try {\n const c = get();\n if (c?.state === \"suspended\") void c.resume();\n } catch {\n // No audio: no sound.\n }\n },\n play: () => {\n try {\n const c = get();\n if (!c || c.state !== \"running\") return;\n const t = c.currentTime;\n [880, 1318.5].forEach((f, i) => {\n const o = c.createOscillator();\n const g = c.createGain();\n const at = t + i * 0.11;\n o.type = \"sine\";\n o.frequency.value = f;\n g.gain.setValueAtTime(0.0001, at);\n g.gain.exponentialRampToValueAtTime(0.12, at + 0.012);\n g.gain.exponentialRampToValueAtTime(0.0001, at + 0.32);\n o.connect(g);\n g.connect(c.destination);\n o.start(at);\n o.stop(at + 0.34);\n });\n } catch {\n // No audio: no sound.\n }\n },\n };\n})();\n\nconst spansOf = (spans: ArticleSpan[]) =>\n spans.map((s) => {\n let node: HTMLElement = s.href ? el(\"a\", { href: s.href, target: \"_blank\", rel: \"noopener noreferrer\" }, s.text) : el(\"span\", {}, s.text);\n if (s.code) node = el(\"code\", {}, node);\n if (s.italic) node = el(\"em\", {}, node);\n if (s.bold) node = el(\"strong\", {}, node);\n return node;\n });\n\nconst blockOf = (b: ArticleBlock): HTMLElement => {\n switch (b.type) {\n case \"h2\":\n case \"h3\":\n return el(b.type, {}, ...spansOf(b.spans));\n case \"quote\":\n return el(\"blockquote\", {}, ...spansOf(b.spans));\n case \"ul\":\n case \"ol\":\n return el(b.type, {}, ...b.items.map((it) => el(\"li\", {}, ...spansOf(it))));\n case \"code\":\n return el(\"pre\", {}, el(\"code\", {}, b.text));\n case \"hr\":\n return el(\"hr\");\n default:\n return el(\"p\", {}, ...spansOf(b.spans));\n }\n};\n\n/** How long the launcher waits for the look from MRRocket before it shows with the code's options and the defaults. */\nconst LOOK_WAIT_MS = 2500;\nconst LOOK_KEY = \"ckw_msgr_look:\";\n\n/** The look this browser saw last, so a repeat visit shows the right launcher at once. */\nconst readCachedLook = (apiKey: string): Partial<MessengerLook> | null => {\n try {\n const raw = window.localStorage.getItem(LOOK_KEY + apiKey);\n return raw ? (JSON.parse(raw) as Partial<MessengerLook>) : null;\n } catch {\n return null;\n }\n};\nconst writeCachedLook = (apiKey: string, look: Partial<MessengerLook>) => {\n try {\n window.localStorage.setItem(LOOK_KEY + apiKey, JSON.stringify(look));\n } catch {\n // Private mode or full storage: the next visit waits for the look again.\n }\n};\n\n/**\n * Mounts the messenger with its look from MRRocket (Support › Messenger) underneath what the code passes: an option the\n * code sets wins, one it leaves out comes from MRRocket, then the default. Calls made before the look arrived wait.\n * A repeat visit starts with the look this browser saw last; a look that arrives later than that (changed, or slower\n * than LOOK_WAIT_MS) replaces the launcher while the panel is closed, or once it closes. New words or another language\n * do the same: the messenger is built anew, with the look read again in another language.\n */\nexport const mountMessenger = (o: MessengerUiOptions): MessengerHandle => {\n let real: BuiltMessenger | null = null;\n let shown = \"\";\n let gone = false;\n const queued: ((h: MessengerHandle) => void)[] = [];\n const later = (fn: (h: MessengerHandle) => void) => (real ? fn(real) : queued.push(fn));\n const ctrl = new AbortController();\n const caching = !o.client && !!o.apiKey;\n let lastLook: Partial<MessengerLook> | null = null;\n const start = (look: Partial<MessengerLook> | null) => {\n if (gone) return;\n lastLook = look;\n const key = `${wordsVersion()}:${JSON.stringify(look ?? {})}`;\n if (real && key === shown) return;\n if (real?.isOpen()) {\n // Never swap the panel under the visitor: the new look waits for the close.\n real.onClose(() => start(look));\n return;\n }\n real?.destroy();\n shown = key;\n const defined = Object.fromEntries(Object.entries(o).filter(([, v]) => v !== undefined)) as MessengerUiOptions;\n // The branding comes from the server alone: what the plan allows is not the site's code to decide.\n real = build({ ...(look ?? {}), ...defined, accent: o.accent ?? look?.accent, theme: o.theme ?? look?.theme, branding: look?.branding ?? true });\n for (const fn of queued.splice(0)) fn(real);\n };\n const cached = caching ? readCachedLook(o.apiKey) : null;\n if (cached) start(cached);\n const timer = cached ? undefined : setTimeout(() => start(null), LOOK_WAIT_MS);\n const readLook = () =>\n (o.client ?? createApi({ host: o.host, apiKey: o.apiKey, distinctId: o.distinctId(), user: o.user(), userHash: o.userHash?.() }))\n .messengerLook(ctrl.signal)\n .then((look) => {\n if (caching && look) writeCachedLook(o.apiKey, look);\n start(look);\n })\n .catch(() => {\n // Without the look: the words still change, under the look it has.\n start(lastLook);\n })\n .finally(() => clearTimeout(timer));\n let readIn = currentLocale();\n void readLook();\n const offWords = onWords(() => {\n // Another language: the look's words too. Only new words: the messenger is built anew with the look it has.\n if (currentLocale() !== readIn) {\n readIn = currentLocale();\n void readLook();\n } else if (real) start(lastLook);\n });\n return {\n open: (v) => later((h) => h.open(v)),\n close: () => real?.close(),\n toggle: () => later((h) => h.toggle()),\n destroy: () => {\n gone = true;\n offWords();\n ctrl.abort();\n clearTimeout(timer);\n real?.destroy();\n },\n };\n};\n\n/** What `build` hands `mountMessenger`: the handle plus what a later look needs to swap the messenger safely. */\ninterface BuiltMessenger extends MessengerHandle {\n isOpen(): boolean;\n /** Runs once, the next time the panel closes. */\n onClose(fn: () => void): void;\n}\n\nconst PLACES: MessengerPosition[] = [\"top-left\", \"top-center\", \"top-right\", \"middle-left\", \"middle-right\", \"bottom-left\", \"bottom-center\", \"bottom-right\"];\n\nconst build = (o: MessengerUiOptions): BuiltMessenger => {\n injectStyles();\n // A script tag's attribute can say anything: an unknown place, corner or top is the default.\n const position = PLACES.find((p) => p === o.position) ?? \"bottom-right\";\n const title = o.title || t(\"Support\");\n const greeting = o.greeting || t(\"Hi! How can we help?\");\n const askEmail = o.askEmail ?? true;\n const label = o.label ?? \"\";\n const reply = replyLine(o.replyTime);\n /** The team's mark: the first letter of the title, on the accent. */\n const initial = (title.trim()[0] ?? \"?\").toUpperCase();\n const whoLabel: Record<ChatMessage[\"from\"], string> = { visitor: t(\"You\"), team: t(\"Team\"), ai: o.agentName?.trim() || t(\"AI agent\"), auto: t(\"Team\") };\n const launcherOn = o.launcher ?? true;\n const helpOn = o.help ?? true;\n const updatesOn = o.updates ?? true;\n const soundOn = o.sound ?? true;\n const previewOn = o.preview ?? true;\n const api = (): MessengerClient => o.client ?? createApi({ host: o.host, apiKey: o.apiKey, distinctId: o.distinctId(), user: o.user(), userHash: o.userHash?.() });\n\n const root = el(\"div\", {\n class: \"ckw-root\",\n \"data-theme\": o.theme ?? \"auto\",\n \"data-corners\": o.corners === \"soft\" || o.corners === \"square\" ? o.corners : \"round\",\n \"data-font\": o.font === \"system\" ? \"system\" : \"site\",\n \"data-header\": o.header === \"color\" ? \"color\" : \"plain\",\n // Screen readers read the panel in the language of its words. Built anew when they change.\n ...(wordsLang() ? { lang: wordsLang() as string } : {}),\n });\n if (o.container) root.setAttribute(\"data-contained\", \"\");\n if (o.accent) {\n root.style.setProperty(\"--ckw-accent\", o.accent);\n root.style.setProperty(\"--ckw-accent-ink\", inkOn(o.accent));\n }\n o.glow?.slice(0, 2).forEach((c, i) => /^#[0-9a-f]{6}$/i.test(c) && root.style.setProperty(`--ckw-glow${i + 2}`, c));\n (o.container ?? document.body).appendChild(root);\n\n let open = false;\n let afterClose: (() => void) | null = null;\n let view: MessengerView | { article: string } = \"home\";\n let thread: ChatThread | null = null;\n /** All the visitor's conversations, the latest activity first. */\n let chats: ChatSummary[] = [];\n let hasEmail = false;\n /** The conversation on screen; null: the newest one, all a visitor with a single conversation ever sees. */\n let chatId: string | null = null;\n /** A new conversation being written, numbered so each stays its own; it becomes `chatId` once the server took it. */\n let draft: number | null = null;\n let drafts = 0;\n /** Messages shows the list of conversations instead of one of them. */\n let listing = false;\n let loaded = false;\n let error = \"\";\n /**\n * What the visitor reads when the server refuses. A refused identity (401: the product has not signed this user yet)\n * is the product team's setup, said in the console (warnUnsigned); the visitor never sees setup steps meant for them.\n */\n const sayable = (e: unknown) => ((e as { status?: number }).status === 401 ? t(\"The chat is not available right now. Please try again later.\") : (e as Error).message);\n /**\n * What the visitor sent that the server has not taken yet, oldest first: shown at once and sent one after another,\n * so the next message can be typed and sent right away (2026-10-30: one send blocked the field for seconds).\n */\n let outbox: { message: ChatMessage; files: Picked[]; email?: string; chat: string | null; draft: number | null }[] = [];\n let outboxSeq = 0;\n let flushing = false;\n /** The time of the newest message known per conversation in this page load: answers after it are new. */\n const known = new Map<string, string>();\n let seen = readSeen();\n let unseen: (ChatMessage & { chat: string })[] = [];\n let previewGone = false;\n let poll: ReturnType<typeof setTimeout> | undefined;\n /** The server refused the last read (a signed-in user without a valid hash): no slow reads until one works. */\n let refused = false;\n let ctrl: AbortController | null = null;\n let articles: ArticleSummary[] | null = null;\n let query = \"\";\n let rated = new Set<string>();\n /** Whether the product has any published article: the Help tab and Home's help card hide when it has none. */\n let hasArticles: boolean | null = null;\n /** The published changelog (null until read); kept as one node, so a redraw never moves the reader's place. */\n let updates: ChangelogEntry[] | null = null;\n let updatesNode: HTMLElement | null = null;\n /** The help collection opened from Help's list (null: the list of collections). */\n let collection: string | null = null;\n /** The panel widened from the ⋮ menu. */\n let wide = false;\n\n const isAnswer = (m: ChatMessage) => m.from === \"team\" || m.from === \"ai\";\n const watching = () => open && view === \"messages\" && document.visibilityState !== \"hidden\";\n /** The chat on screen, if one is: not while the list or a new conversation shows. */\n const shownChat = () => (listing || draft !== null ? null : (chatId ?? thread?.conversation?.id ?? null));\n const unseenIn = (chat: string) => unseen.filter((m) => m.chat === chat).length;\n\n /** New answers of one conversation count, chime and show in the preview; the list brings only its newest one. */\n const learn = (chat: string, answers: ChatMessage[], newest: string | undefined, settled: boolean) => {\n const was = known.get(chat);\n const after = (at: string) => answers.filter((m) => m.at > at);\n if (was === undefined) {\n // First sight: answers the visitor never saw in an earlier visit count, without a sound. An older chat that\n // is closed is history, not news.\n const read = seen.chats[chat];\n const fresh = settled ? [] : read ? after(read) : answers.slice(answers.findIndex((m) => m.id === seen.old) + 1);\n unseen = [...unseen, ...fresh.map((m) => ({ ...m, chat }))];\n // A conversation the team started while the page is open is news like any answer.\n if (loaded && fresh.length) {\n if (soundOn) chime.play();\n previewGone = false;\n }\n } else {\n const fresh = after(was);\n if (fresh.length) {\n if (soundOn) chime.play();\n if (!watching() || shownChat() !== chat) {\n unseen = [...unseen, ...fresh.map((m) => ({ ...m, chat }))];\n previewGone = false;\n }\n }\n }\n known.set(chat, newest ?? was ?? \"\");\n };\n /** Takes what the server read: the list of conversations and, if it is the one on screen, the chat. */\n const take = (t: ChatThread) => {\n const read = t.conversation;\n const last = t.messages.at(-1);\n // A server or a sample client without the list: the one chat it read.\n chats = t.conversations ?? (read && last ? [{ id: read.id, status: read.status, subject: lineOf(t.messages[0]), last }] : []);\n hasEmail = t.hasEmail;\n chats.forEach((c, i) => {\n if (c.id !== read?.id) learn(c.id, c.last && isAnswer(c.last) ? [c.last] : [], c.last?.at, c.status === \"solved\" && i > 0);\n });\n if (read) learn(read.id, t.messages.filter(isAnswer), last?.at, read.status === \"solved\" && chats[0]?.id !== read.id);\n if (chatId === null || read?.id === chatId) thread = t;\n if (watching()) markSeen();\n };\n const markSeen = () => {\n const chat = shownChat();\n if (!chat) return;\n unseen = unseen.filter((m) => m.chat !== chat);\n const at = known.get(chat);\n if (!at || seen.chats[chat] === at) return;\n // Only conversations the visitor still has, so this never grows.\n const kept = Object.fromEntries(Object.entries(seen.chats).filter(([c]) => chats.some((x) => x.id === c)));\n seen = { ...seen, chats: { ...kept, [chat]: at } };\n writeSeen(seen.chats);\n };\n\n /** Puts a conversation on screen; a read on its way for another one must not arrive here. */\n const enterChat = (id: string | null, d: number | null, list = false) => {\n if (id !== chatId || d !== draft) {\n ctrl?.abort();\n ctrl = null;\n thread = null;\n listSig = \"\";\n listCount = -1;\n }\n chatId = id;\n draft = d;\n listing = list;\n };\n /** Messages from a tab: the list once there are several conversations, else the one chat. */\n const enterMessages = () => enterChat(null, null, chats.length > 1);\n const startChat = () => enterChat(null, ++drafts);\n\n const letter = (size?: \"sm\") => el(\"span\", { class: `ckw-msgr-av${size ? \" ckw-msgr-av-sm\" : \"\"}`, \"aria-hidden\": \"true\" }, initial);\n /** The team's round mark: the product's icon, or the title's first letter when it has none (or it fails to load). */\n const avatar = (size?: \"sm\") => {\n if (!o.icon) return letter(size);\n const av = el(\"span\", { class: `ckw-msgr-av ckw-msgr-av-img${size ? \" ckw-msgr-av-sm\" : \"\"}`, \"aria-hidden\": \"true\" });\n const img = el(\"img\", { src: o.icon, alt: \"\" });\n img.addEventListener(\"error\", () => av.replaceWith(letter(size)));\n av.append(img);\n return av;\n };\n /** Home's top left: the uploaded logo (any shape) or the product's icon, else the round mark. */\n const logo = el(\"span\", { class: \"ckw-msgr-logo\", \"aria-hidden\": \"true\" });\n if (o.logo) {\n const img = el(\"img\", { src: o.logo, alt: \"\" });\n img.addEventListener(\"error\", () => logo.replaceChildren(avatar(\"sm\")));\n logo.append(img);\n } else logo.append(avatar(\"sm\"));\n /** The AI agent's face on its answers' line; nothing without a picture. */\n const agentFace = () => (o.agentPhoto ? el(\"img\", { class: \"ckw-msg-face\", src: o.agentPhoto, alt: \"\" }) : null);\n /** Home's background: a soft silk of the accent with a field of dots drifting through it, top right. */\n const sky = el(\"div\", { class: \"ckw-msgr-sky\", \"aria-hidden\": \"true\" });\n\n // ---------- Coming and going ----------\n /** Pending removals: a node that leaves plays its way out first (data-out), unless it is shown again meanwhile. */\n const leaving = new Map<HTMLElement, ReturnType<typeof setTimeout>>();\n const enter = (node: HTMLElement, parent: HTMLElement = root) => {\n clearTimeout(leaving.get(node));\n leaving.delete(node);\n node.removeAttribute(\"data-out\");\n if (!node.isConnected) parent.appendChild(node);\n };\n const leave = (node: HTMLElement, ms = 180) => {\n if (!node.isConnected || leaving.has(node)) return;\n node.setAttribute(\"data-out\", \"\");\n leaving.set(\n node,\n setTimeout(() => {\n leaving.delete(node);\n node.removeAttribute(\"data-out\");\n node.remove();\n }, ms),\n );\n };\n /** Plays an entrance again on a node that stays (a new view in the same body). */\n const replay = (node: HTMLElement, cls: string) => {\n node.classList.remove(cls);\n void node.offsetWidth;\n node.classList.add(cls);\n };\n\n // ---------- Launcher and preview ----------\n const fab = el(\"button\", { type: \"button\", class: `ckw-fab ckw-msgr-fab${label ? \"\" : \" ckw-msgr-round\"}`, \"data-pos\": position, \"aria-haspopup\": \"dialog\" });\n const fabIcons = el(\n \"span\",\n { class: \"ckw-msgr-fab-ic\", \"aria-hidden\": \"true\" },\n el(\"span\", { class: \"ckw-msgr-fab-i\", \"data-i\": \"chat\" }, duo(BUBBLE, DOTS, label ? 20 : 27, 2.6)),\n el(\"span\", { class: \"ckw-msgr-fab-i\", \"data-i\": \"x\" }, icon(I.down, label ? 18 : 24)),\n );\n const fabCount = el(\"span\", { class: \"ckw-msgr-count\", \"aria-hidden\": \"true\" });\n fab.append(fabIcons);\n if (label) fab.append(el(\"span\", {}, label));\n const prev = el(\"div\", { class: \"ckw-msgr-preview\", \"data-pos\": position, role: \"status\" });\n const drawFab = () => {\n fab.toggleAttribute(\"data-open\", open);\n if (unseen.length && !open) {\n const n = String(Math.min(unseen.length, 9));\n if (fabCount.textContent !== n) fabCount.textContent = n;\n if (!fabCount.isConnected) fab.append(fabCount);\n } else fabCount.remove();\n fab.setAttribute(\"aria-expanded\", String(open));\n fab.setAttribute(\"aria-label\", open ? t(\"Close chat\") : unseen.length === 1 ? t(\"Open chat, 1 new reply\") : unseen.length ? tf(\"Open chat, {n} new replies\", { n: unseen.length }) : t(\"Open chat\"));\n drawPreview();\n };\n const previewShown = () => previewOn && !open && !previewGone && !!unseen.length && launcherOn;\n const drawPreview = () => {\n const m = unseen.at(-1);\n if (!previewShown() || !m) return leave(prev);\n const x = el(\"button\", { type: \"button\", class: \"ckw-msgr-preview-x\", \"aria-label\": t(\"Dismiss\") }, icon(I.cross, 14));\n x.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n previewGone = true;\n drawPreview();\n });\n const card = el(\n \"button\",\n { type: \"button\", class: \"ckw-msgr-preview-card\" },\n el(\n \"span\",\n { class: \"ckw-msgr-preview-main\" },\n el(\"span\", { class: \"ckw-msgr-preview-who\" }, `${whoLabel[m.from]}${unseen.length > 1 ? ` · ${tf(\"{n} new\", { n: unseen.length })}` : \"\"}`),\n el(\"span\", { class: \"ckw-msgr-preview-text\" }, lineOf(m)),\n ),\n );\n card.addEventListener(\"click\", () => {\n enterChat(m.chat, null);\n show(\"messages\");\n });\n prev.replaceChildren(card, x);\n enter(prev);\n };\n\n fab.addEventListener(\"click\", () => {\n chime.unlock();\n if (open) return close();\n const news = unseen.at(-1);\n if (news) enterChat(news.chat, null);\n show(news ? \"messages\" : \"home\");\n });\n if (launcherOn) root.appendChild(fab);\n\n // ---------- Panel ----------\n const pop = el(\"div\", { class: \"ckw-pop ckw-msgr\", \"data-pos\": position, role: \"dialog\", \"aria-label\": title });\n const bar = el(\"div\", { class: \"ckw-msgr-bar\" });\n const body = el(\"div\", { class: \"ckw-pop-body ckw-msgr-body\" });\n pop.addEventListener(\"click\", () => chime.unlock());\n\n // The bar keeps its elements between draws; its middle says where the visitor is (the team in a chat, Help).\n const lead = el(\"span\", { class: \"ckw-msgr-lead\" });\n const mid = el(\"span\", { class: \"ckw-msgr-mid\" });\n // Home · Messages · Help along the foot like an app's tab bar (the open chat has its composer there instead):\n // a line icon, filled while its tab is the current one.\n const tabs = el(\"nav\", { class: \"ckw-msgr-tabs\", \"aria-label\": t(\"Messenger\") });\n const tab = (v: MessengerView, name: string, line: string, shape: string, cut: string) => {\n const b = el(\"button\", { type: \"button\", class: \"ckw-msgr-tab\" }, el(\"span\", { class: \"ckw-msgr-tab-ic\" }, icon(line, 22), duo(shape, cut, 22)), el(\"span\", {}, name));\n b.addEventListener(\"click\", () => {\n collection = null;\n if (v === \"messages\") enterMessages();\n go(v);\n });\n return b;\n };\n const homeTab = tab(\"home\", t(\"Home\"), I.home, HOUSE, SMILE);\n const chatTab = tab(\"messages\", t(\"Messages\"), I.chat, BUBBLE, DOTS);\n const helpTab = tab(\"help\", t(\"Help\"), I.help, DISC, QMARK);\n const updatesTab = tab(\"updates\", t(\"Updates\"), I.updates, MEGAPHONE, \"\");\n const tabCount = el(\"span\", { class: \"ckw-msgr-count ckw-msgr-count-tab\", \"aria-hidden\": \"true\" });\n const menuBtn = el(\"button\", { type: \"button\", class: \"ckw-msgr-ib\", \"aria-label\": t(\"More\"), \"aria-haspopup\": \"menu\", \"aria-expanded\": \"false\" }, icon(I.dots, 18));\n /** On a phone the panel covers the launcher, so it has its own close. */\n const xBtn = el(\"button\", { type: \"button\", class: \"ckw-msgr-ib ckw-msgr-x\", \"aria-label\": t(\"Close messenger\") }, icon(I.cross));\n xBtn.addEventListener(\"click\", () => close());\n bar.append(lead, mid, el(\"span\", { class: \"ckw-msgr-trail\" }, menuBtn, xBtn));\n\n const menu = el(\"div\", { class: \"ckw-msgr-menu\", role: \"menu\" });\n const menuOpen = () => menu.isConnected && !menu.hasAttribute(\"data-out\");\n const closeMenu = () => {\n menuBtn.setAttribute(\"aria-expanded\", \"false\");\n leave(menu, 120);\n };\n const menuItem = (d: string, name: string, act: () => void) => {\n const b = el(\"button\", { type: \"button\", class: \"ckw-msgr-menu-i\", role: \"menuitem\" }, icon(d, 15), el(\"span\", {}, name));\n b.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n closeMenu();\n act();\n });\n return b;\n };\n menuBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n if (menuOpen()) return closeMenu();\n menu.replaceChildren(\n el(\"span\", { class: \"ckw-msgr-menu-h\" }, t(\"Quick actions\")),\n menuItem(I.minus, t(\"Minimize chat\"), () => close()),\n menuItem(wide ? I.collapse : I.expand, wide ? t(\"Collapse view\") : t(\"Expand view\"), () => {\n wide = !wide;\n pop.toggleAttribute(\"data-wide\", wide);\n }),\n );\n menuBtn.setAttribute(\"aria-expanded\", \"true\");\n enter(menu, pop);\n (menu.querySelector(\"button\") as HTMLButtonElement | null)?.focus();\n });\n pop.addEventListener(\"click\", () => menuOpen() && closeMenu());\n\n const drawBar = () => {\n const back = (to: () => void, name: string) => {\n const b = el(\"button\", { type: \"button\", class: \"ckw-msgr-ib\", \"aria-label\": name }, icon(I.back, 18));\n b.addEventListener(\"click\", to);\n return b;\n };\n if (typeof view !== \"string\")\n lead.replaceChildren(\n back(() => go(\"help\"), t(\"Back to help\")),\n );\n else if (view === \"help\" && collection && !query.trim())\n lead.replaceChildren(\n back(() => {\n collection = null;\n go(\"help\");\n }, t(\"All collections\")),\n );\n else if (view === \"messages\" && !listing && chats.length > 1)\n lead.replaceChildren(\n back(() => {\n enterMessages();\n go(\"messages\");\n }, t(\"All conversations\")),\n );\n else if (view === \"messages\") lead.replaceChildren(back(() => go(\"home\"), t(\"Back to home\")));\n else if (view === \"home\") lead.replaceChildren(logo);\n else lead.replaceChildren();\n if (view === \"messages\" && listing) mid.replaceChildren(el(\"b\", {}, t(\"Messages\")));\n else if (view === \"messages\") mid.replaceChildren(avatar(\"sm\"), el(\"span\", { class: \"ckw-msgr-mid-t\" }, el(\"b\", {}, title), el(\"span\", { class: \"ckw-msgr-online\" }, reply)));\n else if (view === \"help\") mid.replaceChildren(el(\"b\", {}, t(\"Help\")));\n else if (view === \"updates\") mid.replaceChildren(el(\"b\", {}, t(\"Updates\")));\n else mid.replaceChildren();\n // Without published articles there is no Help tab, and without a published update no Updates tab.\n const items = [homeTab, chatTab, ...(helpOn && hasArticles !== false ? [helpTab] : []), ...(updatesOn && updates?.length ? [updatesTab] : [])];\n if (tabs.childNodes.length !== items.length || items.some((t, i) => tabs.childNodes[i] !== t)) tabs.replaceChildren(...items);\n // Four names do not fit beside their icons on a phone: each stands under its icon.\n tabs.toggleAttribute(\"data-four\", items.length > 3);\n homeTab.setAttribute(\"aria-current\", view === \"home\" ? \"page\" : \"false\");\n chatTab.setAttribute(\"aria-current\", view === \"messages\" ? \"page\" : \"false\");\n helpTab.setAttribute(\"aria-current\", view !== \"home\" && view !== \"messages\" && view !== \"updates\" ? \"page\" : \"false\");\n updatesTab.setAttribute(\"aria-current\", view === \"updates\" ? \"page\" : \"false\");\n if (unseen.length && view !== \"messages\") {\n tabCount.textContent = String(Math.min(unseen.length, 9));\n if (!tabCount.isConnected) chatTab.firstChild!.appendChild(tabCount);\n } else tabCount.remove();\n };\n\n // The chat's compose form keeps its elements between draws, so the field never loses the focus.\n const form = el(\"form\", { class: \"ckw-msgr-compose\" });\n const err = el(\"p\", { class: \"ckw-msgr-error\", role: \"alert\" });\n const email = el(\"input\", { class: \"ckw-input ckw-msgr-email\", type: \"email\", inputmode: \"email\", autocomplete: \"email\", placeholder: t(\"Email for our reply (optional)\"), \"aria-label\": t(\"Your email (optional)\"), maxlength: \"200\", \"data-1p-ignore\": \"\", \"data-lpignore\": \"true\", \"data-bwignore\": \"\", \"data-form-type\": \"other\" });\n const row = el(\"div\", { class: \"ckw-msgr-box\" });\n const text = el(\"textarea\", { class: \"ckw-textarea ckw-msgr-input\", rows: \"1\", placeholder: t(\"Write your message…\"), \"aria-label\": t(\"Message\"), maxlength: \"4000\" });\n const send = el(\"button\", { type: \"submit\", class: \"ckw-msgr-send\", \"aria-label\": t(\"Send\") }, icon(I.up));\n // Files for the next message (screenshots, photos, a PDF): picked with the paperclip, pasted or dropped onto the\n // panel. Each uploads the moment it is picked; Send waits for the uploads.\n const shots = canShoot();\n const clip = el(\n \"button\",\n { type: \"button\", class: \"ckw-msgr-clip\", \"aria-label\": shots ? t(\"Attach a file or a screenshot\") : t(\"Attach a file\"), ...(shots ? { \"aria-haspopup\": \"menu\", \"aria-expanded\": \"false\" } : {}) },\n icon(I.clip, 18),\n );\n row.append(text, el(\"div\", { class: \"ckw-msgr-tools\" }, clip, el(\"span\", { class: \"ckw-msgr-sp\" }), send));\n row.addEventListener(\"click\", (e) => e.target === row && text.focus());\n form.append(row);\n const picker = el(\"input\", { type: \"file\", accept: CHAT_FILE_TYPES.join(\",\"), multiple: \"\", hidden: \"\", tabindex: \"-1\", \"aria-hidden\": \"true\" });\n form.append(picker);\n const tray = el(\"div\", { class: \"ckw-msgr-files\", role: \"list\", \"aria-label\": t(\"Files to send\") });\n\n interface Picked {\n key: string;\n name: string;\n type: ChatFile[\"type\"];\n size: number;\n /** The picture on this device, shown until the server has it. */\n local: string;\n /** The upload id once the upload finished. */\n id?: string;\n up: Promise<void>;\n ctrl: AbortController;\n }\n let picked: Picked[] = [];\n /** Pictures of the message on its way, by their local key. */\n const localUrls = new Map<string, string>();\n const fileUrl = (id: string) => localUrls.get(id) ?? api().attachmentUrl(id);\n const forget = (p: Picked) => {\n p.ctrl.abort();\n if (![...localUrls.values()].includes(p.local)) URL.revokeObjectURL(p.local);\n };\n const dropFile = (p: Picked) => {\n picked = picked.filter((x) => x !== p);\n forget(p);\n };\n const addFiles = (list: (Blob & { name?: string })[]) => {\n error = \"\";\n for (const f of list) {\n const name = f.name || \"screenshot.png\";\n if (picked.length >= CHAT_FILES_PER_MESSAGE) {\n error = tf(\"Up to {n} files per message.\", { n: CHAT_FILES_PER_MESSAGE });\n break;\n }\n if (!(CHAT_FILE_TYPES as readonly string[]).includes(f.type)) {\n error = t(\"Only pictures (PNG, JPEG, WebP, GIF) and PDFs can be sent.\");\n continue;\n }\n if (f.size > CHAT_FILE_MAX_BYTES) {\n error = tf(\"{name} is larger than 10 MB.\", { name });\n continue;\n }\n const p: Picked = { key: `local-${Date.now().toString(36)}${Math.random().toString(36).slice(2, 7)}`, name, type: f.type as ChatFile[\"type\"], size: f.size, local: URL.createObjectURL(f), up: Promise.resolve(), ctrl: new AbortController() };\n p.up = api()\n .uploadChatFile(f, p.ctrl.signal)\n .then(\n (r) => {\n p.id = r.id;\n draw();\n },\n (e: Error) => {\n if (e.name === \"AbortError\") return;\n dropFile(p);\n error = `${p.name}: ${e.message}`;\n draw();\n },\n );\n picked.push(p);\n }\n if (open && (view !== \"messages\" || listing)) {\n startChat();\n go(\"messages\");\n } else draw();\n text.focus();\n };\n let traySig = \"\";\n const drawTray = () => {\n const sig = picked.map((p) => `${p.key}:${p.id ? 1 : 0}`).join(\",\");\n if (sig !== traySig) {\n traySig = sig;\n tray.replaceChildren(\n ...picked.map((p) => {\n const x = el(\"button\", { type: \"button\", class: \"ckw-msgr-file-x\", \"aria-label\": tf(\"Remove {name}\", { name: p.name }) }, icon(I.cross, 12));\n x.addEventListener(\"click\", () => {\n dropFile(p);\n draw();\n text.focus();\n });\n const face = p.type.startsWith(\"image/\") ? el(\"img\", { src: p.local, alt: \"\" }) : el(\"span\", { class: \"ckw-msgr-file-doc\" }, icon(I.doc, 18), el(\"span\", {}, p.name));\n return el(\"div\", { class: \"ckw-msgr-file\", role: \"listitem\", title: p.name, \"aria-label\": p.id ? p.name : tf(\"{name}, uploading\", { name: p.name }), ...(p.id ? {} : { \"aria-busy\": \"true\" }) }, face, x);\n }),\n );\n }\n if (!picked.length) tray.remove();\n else if (!tray.isConnected) form.insertBefore(tray, row);\n };\n\n /** A picture of this tab: the browser asks once, the messenger hides for the frame, then comes back. */\n const shoot = async () => {\n let stream: MediaStream;\n try {\n stream = await navigator.mediaDevices.getDisplayMedia({ video: { displaySurface: \"browser\" }, audio: false, preferCurrentTab: true, selfBrowserSurface: \"include\" } as DisplayMediaStreamOptions);\n } catch (e) {\n if ((e as Error).name !== \"NotAllowedError\" && (e as Error).name !== \"AbortError\") {\n error = t(\"The screenshot did not work here. Attach a picture instead.\");\n draw();\n }\n return;\n }\n root.style.visibility = \"hidden\";\n let blob: Blob | null = null;\n try {\n const video = document.createElement(\"video\");\n video.muted = true;\n video.playsInline = true;\n video.srcObject = stream;\n await video.play();\n // Frames from before the panel hid may still be on their way: wait for fresh ones.\n await new Promise((r) => setTimeout(r, 300));\n const v = video as HTMLVideoElement & { requestVideoFrameCallback?: (cb: () => void) => number };\n await new Promise<void>((r) => (v.requestVideoFrameCallback ? v.requestVideoFrameCallback(() => r()) : requestAnimationFrame(() => r())));\n const canvas = document.createElement(\"canvas\");\n canvas.width = video.videoWidth;\n canvas.height = video.videoHeight;\n canvas.getContext(\"2d\")?.drawImage(video, 0, 0);\n const encode = (type: string, q?: number) => new Promise<Blob | null>((r) => canvas.toBlob(r, type, q));\n blob = await encode(\"image/png\");\n // A large screen as PNG gets big; a JPEG reads just as well and stays small enough for the AI agent.\n if (blob && blob.size > 4.5 * 1024 * 1024) blob = await encode(\"image/jpeg\", 0.9);\n } catch {\n blob = null;\n } finally {\n for (const t of stream.getTracks()) t.stop();\n root.style.visibility = \"\";\n }\n if (!blob || !blob.size) {\n error = t(\"The screenshot did not work here. Attach a picture instead.\");\n return draw();\n }\n const stamp = new Date().toISOString().slice(0, 16).replace(/[:T]/g, \"-\");\n addFiles([Object.assign(blob, { name: `screenshot-${stamp}.${blob.type === \"image/png\" ? \"png\" : \"jpg\"}` })]);\n };\n\n // The paperclip: the file picker at once, or a small menu with Screenshot where the browser can take one.\n const amenu = el(\"div\", { class: \"ckw-msgr-menu ckw-msgr-amenu\", role: \"menu\" });\n const amenuOpen = () => amenu.isConnected && !amenu.hasAttribute(\"data-out\");\n const closeAmenu = () => {\n clip.setAttribute(\"aria-expanded\", \"false\");\n leave(amenu, 120);\n };\n const amenuItem = (d: string, name: string, act: () => void) => {\n const b = el(\"button\", { type: \"button\", class: \"ckw-msgr-menu-i\", role: \"menuitem\" }, icon(d, 15), el(\"span\", {}, name));\n b.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n closeAmenu();\n act();\n });\n return b;\n };\n clip.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n chime.unlock();\n if (!shots) return picker.click();\n if (amenuOpen()) return closeAmenu();\n amenu.replaceChildren(\n amenuItem(I.image, t(\"Photo or file\"), () => picker.click()),\n amenuItem(I.screen, t(\"Screenshot of this page\"), () => void shoot()),\n );\n clip.setAttribute(\"aria-expanded\", \"true\");\n enter(amenu, form);\n (amenu.querySelector(\"button\") as HTMLButtonElement | null)?.focus();\n });\n picker.addEventListener(\"change\", () => {\n addFiles([...(picker.files ?? [])]);\n picker.value = \"\";\n });\n\n const brand = el(\"a\", { class: \"ckw-msgr-powered\", href: BRAND_URL, target: \"_blank\", rel: \"noopener\" }, t(\"Powered by {brand}\").split(\"{brand}\")[0], el(\"b\", {}, \"MRRocket\"), t(\"Powered by {brand}\").split(\"{brand}\")[1]);\n\n const list = el(\"ol\", { class: \"ckw-msgs\", \"aria-live\": \"polite\", \"aria-label\": t(\"Messages\") });\n const needEmail = () => askEmail && !o.user()?.email && !hasEmail;\n const emailOk = () => !email.value.trim() || EMAIL.test(email.value.trim());\n const canSend = () => (!!text.value.trim() || picked.length > 0) && emailOk();\n\n const go = (v: MessengerView | { article: string }) => {\n const changed = JSON.stringify(v) !== JSON.stringify(view);\n view = v;\n drawn = -1;\n draw();\n if (changed) replay(body, \"ckw-msgr-enter\");\n if (v === \"messages\") {\n markSeen();\n drawFab();\n text.focus();\n } else if (v === \"help\") helpInput.focus();\n schedule(0);\n };\n\n /** A sent picture; once it has its height the chat stays at the bottom, if it was there. */\n const picture = (src: string, alt: string) => {\n const img = el(\"img\", { src, alt, loading: \"lazy\" });\n img.addEventListener(\"load\", () => {\n if (body.scrollHeight - body.scrollTop - body.clientHeight < img.clientHeight + 120) body.scrollTop = body.scrollHeight;\n });\n return img;\n };\n const bubble = (m: ChatMessage, isPending = false) => {\n const slow = isPending && Date.now() - Date.parse(m.at) >= SLOW_SEND_MS;\n const li = el(\"li\", { class: \"ckw-msg\", \"data-from\": m.from === \"visitor\" ? \"me\" : \"them\" }, m.body || !m.attachments?.length ? el(\"div\", { class: \"ckw-bubble\" }, m.body) : null);\n if (isPending) li.setAttribute(\"aria-busy\", \"true\");\n // Sent files: pictures as themselves, a PDF as a chip; each opens full size in a new tab.\n if (m.attachments?.length)\n li.append(\n el(\n \"div\",\n { class: \"ckw-msg-files\" },\n ...m.attachments.map((f) =>\n f.type.startsWith(\"image/\")\n ? el(\"a\", { class: \"ckw-msg-img\", href: fileUrl(f.id), target: \"_blank\", rel: \"noopener\", title: f.name }, picture(fileUrl(f.id), f.name))\n : el(\"a\", { class: \"ckw-msgr-cite\", href: fileUrl(f.id), target: \"_blank\", rel: \"noopener\" }, icon(I.doc, 14), el(\"span\", {}, f.name)),\n ),\n ),\n );\n for (const a of m.articles ?? []) {\n const chip = el(\"button\", { type: \"button\", class: \"ckw-msgr-cite\" }, icon(I.doc, 14), el(\"span\", {}, a.title));\n chip.addEventListener(\"click\", () => go({ article: a.id }));\n li.append(chip);\n }\n li.append(el(\"span\", { class: \"ckw-msg-meta\" }, m.from === \"ai\" ? agentFace() : null, `${m.from !== \"visitor\" ? `${whoLabel[m.from]} · ` : \"\"}${slow ? t(\"Sending…\") : timeAgo(m.at)}`));\n return li;\n };\n\n const articleRow = (a: ArticleSummary) => {\n const b = el(\"button\", { type: \"button\", class: \"ckw-msgr-art\" }, el(\"span\", { class: \"ckw-msgr-art-t\" }, a.title), icon(I.next, 14));\n b.addEventListener(\"click\", () => go({ article: a.id }));\n return b;\n };\n /** A row in Help's lists: a bold name, two lines under it, a count, the arrow. */\n const helpRow = (name: string, sub: string, meta: string, act: () => void) => {\n const b = el(\n \"button\",\n { type: \"button\", class: \"ckw-msgr-hrow\" },\n el(\"span\", { class: \"ckw-msgr-hrow-main\" }, el(\"b\", {}, name), sub ? el(\"span\", { class: \"ckw-msgr-hrow-sub\" }, sub) : null, meta ? el(\"span\", { class: \"ckw-msgr-hrow-meta\" }, meta) : null),\n icon(I.next, 16),\n );\n b.addEventListener(\"click\", act);\n return b;\n };\n\n const searchBox = (placeholder = t(\"Search for help\")) => {\n const wrap = el(\"label\", { class: \"ckw-msgr-search\" });\n const input = el(\"input\", { class: \"ckw-msgr-search-in\", type: \"search\", placeholder, \"aria-label\": t(\"Search for help\"), maxlength: \"200\" });\n input.value = query;\n let wait: ReturnType<typeof setTimeout> | undefined;\n input.addEventListener(\"input\", () => {\n query = input.value;\n clearTimeout(wait);\n wait = setTimeout(() => {\n if (view !== \"help\") return go(\"help\");\n void loadArticles(true);\n }, 250);\n });\n input.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n if (view !== \"help\") go(\"help\");\n }\n });\n wrap.append(icon(I.search, 16), input);\n return wrap;\n };\n // Help's own field stays the same element between draws, so typing never loses the cursor.\n const helpSearch = searchBox(t(\"Search our help center…\"));\n const helpInput = helpSearch.querySelector(\"input\")!;\n\n let loadingArticles = false;\n /** \"Send us a message\" after an article: a question of its own, not an answer in an older chat. */\n const askAnew = () => {\n startChat();\n go(\"messages\");\n };\n const loadArticles = async (force = false) => {\n if (!helpOn || (loadingArticles && !force)) return;\n loadingArticles = true;\n const q = query.trim();\n try {\n const r = await api().articles(q || undefined);\n if (q !== query.trim()) return;\n articles = r.articles;\n if (!q) hasArticles = r.articles.length > 0;\n } catch {\n articles = articles ?? [];\n } finally {\n loadingArticles = false;\n }\n draw();\n };\n const loadUpdates = async () => {\n try {\n updates = (await api().changelog()).entries.slice(0, UPDATES_SHOWN);\n } catch {\n // A server without the changelog, or a bad moment: no tab, and the rest of the messenger goes on.\n updates = [];\n }\n updatesNode = null;\n draw();\n };\n // Home's \"Ask a question\" field: what is typed there starts a new conversation and is sent (it went into the running\n // chat before; owner, 2026-11-04). The same element between draws, so a read that redraws Home never takes the\n // cursor or the words.\n const askForm = el(\"form\", { class: \"ckw-msgr-askq\" });\n const askIn = el(\"input\", { class: \"ckw-msgr-askq-in\", placeholder: t(\"Ask a question\"), \"aria-label\": t(\"Ask a question\"), maxlength: \"4000\", autocomplete: \"off\" });\n const askGo = el(\"button\", { type: \"submit\", class: \"ckw-msgr-send\", \"aria-label\": t(\"Send\"), disabled: \"\" }, icon(I.up));\n askForm.append(askIn, askGo);\n askIn.addEventListener(\"input\", () => (askGo.disabled = !askIn.value.trim()));\n askForm.addEventListener(\"submit\", (e) => {\n e.preventDefault();\n if (!askIn.value.trim()) {\n enterMessages();\n return go(\"messages\");\n }\n text.value = askIn.value;\n askIn.value = \"\";\n askGo.disabled = true;\n startChat();\n go(\"messages\");\n if (canSend()) submit();\n });\n /** One conversation as a card: what it was about, where it stands, a count of new answers. */\n const chatRow = (c: ChatSummary) => {\n const m = c.last;\n const n = unseenIn(c.id);\n const closed = c.status === \"solved\" ? ` · ${t(\"Closed\")}` : \"\";\n const row = el(\n \"button\",\n { type: \"button\", class: \"ckw-msgr-card ckw-msgr-recent\", \"aria-label\": `${tf(\"Conversation: {subject}\", { subject: c.subject })}${closed}${n ? `, ${tf(\"{n} new\", { n })}` : \"\"}` },\n el(\n \"span\",\n { class: \"ckw-msgr-recent-row\" },\n avatar(\"sm\"),\n el(\n \"span\",\n { class: \"ckw-msgr-card-main\" },\n el(\"span\", { class: \"ckw-msgr-card-sub ckw-msgr-recent-text\" }, c.subject),\n m && lineOf(m) !== c.subject ? el(\"span\", { class: \"ckw-msgr-card-sub\" }, lineOf(m)) : null,\n m ? el(\"span\", { class: \"ckw-msgr-card-meta\" }, `${whoLabel[m.from]} · ${timeAgo(m.at)}${closed}`) : null,\n ),\n n ? el(\"span\", { class: \"ckw-msgr-badge\" }, String(n)) : icon(I.next, 14),\n ),\n );\n row.addEventListener(\"click\", () => {\n enterChat(c.id, null);\n go(\"messages\");\n });\n return row;\n };\n const chatsBox = el(\"div\", { class: \"ckw-msgr-chats\" });\n const newChat = el(\"button\", { type: \"button\", class: \"ckw-btn ckw-btn-primary ckw-msgr-new\" }, icon(I.chat), t(\"New conversation\"));\n newChat.addEventListener(\"click\", askAnew);\n let chatsSig = \"\";\n const drawChats = () => {\n // Redrawn only when something shows differently, so a read never takes the keyboard's place in the list.\n const sig = `${chats.map((c) => `${c.id}:${c.status}:${c.last?.id}:${unseenIn(c.id)}`).join()}|${Math.floor(Date.now() / 60_000)}`;\n if (sig !== chatsSig) {\n chatsSig = sig;\n chatsBox.replaceChildren(...chats.map(chatRow));\n }\n if (body.childNodes[0] !== chatsBox) body.replaceChildren(chatsBox, newChat);\n };\n\n const drawHome = () => {\n // Two lines like Featurebase: \"Hi, Lukas 👋\" and the greeting in gray (without its own \"Hi!\", said above).\n const first = o.user()?.name?.trim().split(/\\s+/)[0];\n const rest = (o.greeting ? greeting.replace(/^(hi|hello|hey|hallo|moin|servus|bonjour|salut|hola|ciao|salve|hoi|ol[áa]|cze[śs][ćc]|hej|こんにちは)( there)?\\s*[!,.!、。]*\\s*/i, \"\").trim() : t(\"How can we help?\")) || t(\"How can we help you today?\");\n const hero = el(\n \"h2\",\n { class: \"ckw-msgr-hero ckw-msgr-hello\" },\n el(\"span\", {}, `${first ? tf(\"Hi, {name}\", { name: first }) : t(\"Hi there\")} `, el(\"span\", { class: \"ckw-msgr-wave\", \"aria-hidden\": \"true\" }, \"👋\")),\n el(\"span\", { class: \"ckw-msgr-hello-sub\" }, rest),\n );\n const parts: HTMLElement[] = [hero, askForm];\n // The conversations still open (a closed one only while there is nothing else); the rest behind \"All\".\n const running = chats.filter((c) => c.status !== \"solved\");\n const rows = (running.length ? running : chats).slice(0, 2);\n parts.push(...rows.map(chatRow));\n if (chats.length > rows.length) {\n const all = el(\"button\", { type: \"button\", class: \"ckw-msgr-all\" }, tf(\"All conversations ({n})\", { n: chats.length }), icon(I.next, 14));\n all.addEventListener(\"click\", () => {\n enterMessages();\n go(\"messages\");\n });\n parts.push(all);\n }\n // A few articles to tap; searching is the Help tab's, so Home fits without scrolling.\n if (helpOn && hasArticles !== false) {\n const helpCard = el(\"div\", { class: \"ckw-msgr-card ckw-msgr-card-col\" });\n const top = (articles ?? []).slice(0, 3);\n if (top.length) helpCard.append(...top.map(articleRow));\n else if (articles === null) helpCard.append(el(\"div\", { class: \"ckw-skel ckw-msgr-skel\" }));\n parts.push(helpCard);\n }\n body.replaceChildren(...parts);\n };\n\n const drawHelp = () => {\n if (helpInput.value !== query) helpInput.value = query;\n const q = query.trim();\n const all = articles ?? [];\n const groups = new Map<string, ArticleSummary[]>();\n for (const a of all) groups.set(a.collection, [...(groups.get(a.collection) ?? []), a]);\n const inside = !q && collection !== null ? (groups.get(collection) ?? []) : null;\n const heading = q ? t(\"Search results\") : inside ? (collection ?? \"\") : t(\"Most read articles\");\n const parts: HTMLElement[] = [el(\"h2\", { class: \"ckw-msgr-help-h\" }, heading), helpSearch];\n if (articles === null) parts.push(el(\"div\", { class: \"ckw-skel\" }));\n else if (!all.length) {\n const ask = el(\"button\", { type: \"button\", class: \"ckw-btn ckw-btn-primary\" }, t(\"Send us a message\"));\n ask.addEventListener(\"click\", askAnew);\n parts.push(el(\"div\", { class: \"ckw-msgr-empty\" }, el(\"p\", {}, q ? tf(\"Nothing found for “{q}”.\", { q }) : t(\"No help articles yet.\")), ask));\n } else if (q || inside)\n parts.push(\n el(\n \"div\",\n { class: \"ckw-msgr-hlist\" },\n // The excerpt often opens with the article's own heading; the row shows the title already.\n ...(inside ?? all).map((a) => helpRow(a.title, a.excerpt.startsWith(a.title) ? a.excerpt.slice(a.title.length).trim() : a.excerpt, q ? a.collection : \"\", () => go({ article: a.id }))),\n ),\n );\n else\n parts.push(\n el(\n \"div\",\n { class: \"ckw-msgr-hlist\" },\n ...[...groups].map(([name, items]) =>\n helpRow(name, items.map((a) => a.title).join(\", \"), items.length === 1 ? t(\"1 article\") : tf(\"{n} articles\", { n: items.length }), () => {\n collection = name;\n go(\"help\");\n replay(body, \"ckw-msgr-enter\");\n }),\n ),\n ),\n );\n // The field stays in place (moving it would take its focus); only what is around it changes.\n if (body.childNodes[1] !== helpSearch) body.replaceChildren(...parts);\n else {\n (body.firstChild as HTMLElement).replaceWith(parts[0]);\n while (body.childNodes.length > 2) body.lastChild!.remove();\n body.append(...parts.slice(2));\n }\n };\n\n // The owner's changelog, newest first, to read in place (owner, 2026-11-04: \"changelog auch im Messenger als Tab\").\n const drawUpdates = () => {\n updatesNode ??= !updates\n ? el(\"div\", { class: \"ckw-skel\" })\n : !updates.length\n ? el(\"div\", { class: \"ckw-msgr-empty\" }, el(\"p\", {}, t(\"No updates yet.\")))\n : el(\n \"div\",\n { class: \"ckw-msgr-updates\" },\n ...updates.map((e) => el(\"article\", { class: \"ckw-msgr-update\" }, el(\"p\", { class: \"ckw-msgr-doc-c\" }, timeAgo(e.publishedAt)), el(\"h2\", { class: \"ckw-msgr-update-t\" }, e.title), e.body ? el(\"p\", { class: \"ckw-msgr-update-b\" }, e.body) : null)),\n );\n if (body.firstChild !== updatesNode || body.childNodes.length !== 1) body.replaceChildren(updatesNode);\n };\n\n let articleShown: { id: string; node: HTMLElement } | null = null;\n const drawArticle = (id: string) => {\n if (articleShown?.id === id) return body.replaceChildren(articleShown.node);\n const node = el(\"article\", { class: \"ckw-msgr-doc\" }, el(\"div\", { class: \"ckw-skel\" }));\n articleShown = { id, node };\n body.replaceChildren(node);\n api()\n .article(id)\n .then((a) => {\n const foot = el(\"div\", { class: \"ckw-msgr-rate\" });\n const drawRate = () => {\n if (rated.has(id)) return foot.replaceChildren(el(\"span\", {}, t(\"Thanks for letting us know.\")));\n const yes = el(\"button\", { type: \"button\", class: \"ckw-btn\" }, t(\"Yes\"));\n const no = el(\"button\", { type: \"button\", class: \"ckw-btn\" }, t(\"No\"));\n const rate = (helpful: boolean) => {\n rated = new Set(rated).add(id);\n drawRate();\n api()\n .rateArticle(id, helpful)\n .catch(() => undefined);\n if (!helpful) askAnew();\n };\n yes.addEventListener(\"click\", () => rate(true));\n no.addEventListener(\"click\", () => rate(false));\n foot.replaceChildren(el(\"span\", {}, t(\"Did this answer your question?\")), el(\"span\", { class: \"ckw-msgr-rate-b\" }, yes, no));\n };\n drawRate();\n const ask = el(\"button\", { type: \"button\", class: \"ckw-btn ckw-msgr-ask\" }, icon(I.chat), t(\"Still need help? Send us a message\"));\n ask.addEventListener(\"click\", askAnew);\n node.replaceChildren(\n el(\"p\", { class: \"ckw-msgr-doc-c\" }, a.collection),\n el(\"h2\", { class: \"ckw-msgr-doc-t\" }, a.title),\n el(\"p\", { class: \"ckw-msgr-doc-c\" }, tf(\"Updated {when}\", { when: timeAgo(a.updatedAt) })),\n el(\"div\", { class: \"ckw-msgr-doc-b\" }, ...a.blocks.map(blockOf)),\n foot,\n ask,\n );\n })\n .catch((e: Error) => {\n articleShown = null;\n node.replaceChildren(el(\"p\", { class: \"ckw-msgr-error\" }, e.message));\n });\n };\n\n let drawn = -1;\n /** What the list shows, so a read that brings nothing new leaves it alone (no flicker, links stay where they are). */\n let listSig = \"\";\n /** How many bubbles the list had: the ones after it are new and glide in. */\n let listCount = -1;\n const suggestions = el(\"div\", { class: \"ckw-msgr-sugg\" });\n /** What is on its way into the conversation on screen. */\n const outboxHere = () => outbox.filter((x) => x.draft === draft && x.chat === chatId);\n const drawMessages = () => {\n const current = draft === null ? thread : null;\n const msgs = current?.messages ?? [];\n const here = outboxHere();\n const parts: HTMLElement[] = [];\n // No grey placeholder while the chat is read (owner, 2026-11-03: \"der lange Loader ist scheiße\"): the greeting\n // and the field are there at once, and the visitor's earlier messages take the greeting's place when they come.\n {\n const waiting = here.map((o) => o.message);\n const sig = `${msgs.map((m) => m.id).join(\",\")}|${waiting.map((m) => `${m.id}:${Date.now() - Date.parse(m.at) >= SLOW_SEND_MS}`).join(\",\")}|${Math.floor(Date.now() / 60_000)}`;\n if (sig !== listSig) {\n listSig = sig;\n // The greeting opens an empty chat only: once the visitor wrote (from Home's \"Ask a question\" too) the chat\n // starts with their words, never with a greeting above them (2026-10-30).\n const greet = msgs.length || waiting.length || chatId ? [] : [el(\"li\", { class: \"ckw-msg\", \"data-from\": \"them\" }, el(\"div\", { class: \"ckw-bubble\" }, greeting))];\n const items = [...greet, ...msgs.map((m) => bubble(m)), ...waiting.map((m) => bubble(m, true))];\n if (listCount >= 0) items.slice(listCount).forEach((li) => li.setAttribute(\"data-new\", \"\"));\n listCount = items.length;\n list.replaceChildren(...items);\n }\n parts.push(list);\n // Before the visitor wrote: the most read articles as answers to tap.\n const top = !msgs.some((m) => m.from === \"visitor\") && !here.length && !chatId ? (articles ?? []).slice(0, 3) : [];\n if (top.length) {\n if (suggestions.childNodes.length !== top.length)\n suggestions.replaceChildren(\n ...top.map((a) => {\n const b = el(\"button\", { type: \"button\", class: \"ckw-msgr-sugg-b\" }, a.title);\n b.addEventListener(\"click\", () => go({ article: a.id }));\n return b;\n }),\n );\n parts.push(suggestions);\n }\n }\n if (current?.conversation?.status === \"solved\" && !here.length) parts.push(el(\"p\", { class: \"ckw-fine ckw-msgr-note\" }, t(\"This conversation is closed. Write to start a new one.\")));\n if (body.childNodes.length !== parts.length || parts.some((x, i) => body.childNodes[i] !== x)) body.replaceChildren(...parts);\n const count = msgs.length + here.length;\n if (count !== drawn) {\n drawn = count;\n body.scrollTop = body.scrollHeight;\n }\n err.textContent = error;\n if (error && !err.isConnected) form.prepend(err);\n else if (!error) err.remove();\n if (needEmail()) {\n if (emailOk()) email.removeAttribute(\"aria-invalid\");\n else email.setAttribute(\"aria-invalid\", \"true\");\n if (!email.isConnected) row.insertBefore(email, text);\n } else email.remove();\n drawTray();\n send.disabled = !canSend();\n };\n\n const draw = () => {\n if (!open) return;\n pop.dataset.view = typeof view === \"string\" ? view : \"article\";\n drawBar();\n if (view === \"home\") drawHome();\n else if (view === \"messages\") (listing ? drawChats : drawMessages)();\n else if (view === \"help\") drawHelp();\n else if (view === \"updates\") drawUpdates();\n else drawArticle(view.article);\n const kids: HTMLElement[] = view === \"home\" ? [sky, bar, body] : [bar, body];\n kids.push(view === \"messages\" && !listing ? form : tabs);\n if (o.branding !== false) kids.push(brand);\n if (menu.isConnected) kids.push(menu);\n if (pop.childNodes.length !== kids.length || kids.some((k, i) => pop.childNodes[i] !== k)) pop.replaceChildren(...kids);\n };\n\n // ---------- Reading the chat ----------\n const tick = async () => {\n // A read on its way is the newest one: opening the panel again waits for it instead of starting over (a slow\n // first read was cut off by every open and the chat never came).\n if (ctrl) return;\n const mine = (ctrl = new AbortController());\n try {\n take(await api().chat(mine.signal, chatId ?? undefined));\n error = \"\";\n refused = false;\n } catch (e) {\n if ((e as Error).name === \"AbortError\") return;\n const status = (e as { status?: number }).status;\n refused = status === 401 || status === 403;\n // A chat that is gone (the team archived it): back to what is left.\n if (status === 404 && chatId) enterMessages();\n else if (open && view === \"messages\") error = sayable(e);\n } finally {\n if (ctrl === mine) ctrl = null;\n }\n // The first read's messages are already there, not new: they do not glide in.\n if (!loaded) {\n listCount = -1;\n // Messages opened before the first read knew of several conversations, and nothing was typed yet.\n if (view === \"messages\" && chatId === null && draft === null && !text.value.trim() && !outbox.length && !picked.length) enterMessages();\n }\n loaded = true;\n draw();\n drawFab();\n schedule();\n };\n /** The next read: often while the chat is on screen, now and then while the visitor waits for an answer, slowly else; never for a hidden page. */\n function schedule(now?: number) {\n clearTimeout(poll);\n const running = chats.filter((c) => c.status !== \"solved\");\n const waiting = running.length > 0;\n const recent = running.some((c) => c.last && Date.now() - new Date(c.last.at).getTime() < WAITING_FOR_MS);\n const quiet = now === undefined && !open && !waiting;\n const ms = now ?? (document.visibilityState === \"hidden\" ? 0 : watching() ? POLL_OPEN_MS : waiting && recent ? POLL_WAITING_MS : quiet ? POLL_QUIET_MS : POLL_IDLE_MS);\n // A slow turn without anyone to reach reads nothing; whoever signs in later is read from the next one on.\n if (ms || now === 0) poll = setTimeout(() => (quiet && (refused || !(o.user()?.id || chats.length)) ? schedule() : void tick()), ms);\n }\n const onVisible = () => {\n if (document.visibilityState === \"visible\") schedule(0);\n else clearTimeout(poll);\n };\n document.addEventListener(\"visibilitychange\", onVisible);\n\n /** Sends the outbox in order; what fails comes back into the field with what was queued after it. */\n const flush = async () => {\n if (flushing) return;\n flushing = true;\n while (outbox.length) {\n const item = outbox[0];\n const { message, files, email: given } = item;\n // Send waits for the uploads; one that failed is left out and said in the error line.\n await Promise.all(files.map((p) => p.up));\n const ids = files.filter((p) => p.id).map((p) => p.id!);\n try {\n if (!message.body && !ids.length) throw new Error(error || t(\"The file could not be sent.\"));\n const sent = await api().sendChat({\n body: message.body,\n ...(item.draft !== null ? { conversation: \"new\" } : item.chat ? { conversation: item.chat } : {}),\n email: given,\n url: window.location.href.slice(0, 500),\n ...(ids.length ? { attachments: ids } : {}),\n // A little context for a bug report; the server reads browser and system from the user agent.\n context: { viewport: `${window.innerWidth}×${window.innerHeight}` },\n });\n // A read that left before this send would bring the chat without it.\n ctrl?.abort();\n ctrl = null;\n // Where it went (a new conversation, or a new one after a closed chat) is where what follows it goes.\n const went = sent.conversation?.id ?? null;\n if (went) {\n const after = outbox.slice(1).filter((x) => x.draft === item.draft && x.chat === item.chat);\n if (item.draft === draft && item.chat === chatId) {\n draft = null;\n chatId = went;\n }\n for (const x of after) {\n x.draft = null;\n x.chat = went;\n }\n }\n take(sent);\n outbox.shift();\n for (const p of files) {\n localUrls.delete(p.key);\n URL.revokeObjectURL(p.local);\n }\n } catch (e) {\n // Nothing typed is lost: the unsent words go back into the field (before anything typed since), their\n // uploaded files back into the tray.\n const back = outbox.splice(0);\n // Back into the chat they were written for; a chat that is gone leaves them for a new one.\n const gone = (e as { status?: number }).status === 404;\n enterChat(gone ? null : back[0].chat, gone ? ++drafts : back[0].draft);\n text.value = [...back.map((b) => b.message.body), text.value.trim()].filter(Boolean).join(\"\\n\");\n picked = [...back.flatMap((b) => b.files.filter((p) => p.id)), ...picked];\n for (const b of back) for (const p of b.files) localUrls.delete(p.key);\n error = gone ? t(\"This conversation is no longer available. Your message is still here to send as a new one.\") : sayable(e);\n }\n draw();\n }\n flushing = false;\n schedule();\n };\n\n const submit = () => {\n const msg = text.value.trim();\n const files = picked;\n if ((!msg && !files.length) || !emailOk()) return;\n chime.unlock();\n for (const p of files) localUrls.set(p.key, p.local);\n outbox.push({\n message: {\n id: `pending-${++outboxSeq}`,\n from: \"visitor\",\n body: msg,\n at: new Date().toISOString(),\n ...(files.length ? { attachments: files.map((p) => ({ id: p.key, name: p.name, type: p.type, size: p.size })) } : {}),\n },\n files,\n email: needEmail() && email.value.trim() ? email.value.trim() : undefined,\n chat: chatId,\n draft,\n });\n text.value = \"\";\n picked = [];\n error = \"\";\n draw();\n // A slow answer turns \"just now\" into \"Sending…\".\n setTimeout(draw, SLOW_SEND_MS + 50);\n void flush();\n };\n form.addEventListener(\"submit\", (e) => {\n e.preventDefault();\n submit();\n });\n text.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\" && !e.shiftKey && !e.isComposing) {\n e.preventDefault();\n submit();\n }\n });\n text.addEventListener(\"input\", () => (send.disabled = !canSend()));\n // A picture on the clipboard (a screenshot) attaches when pasted into the field.\n text.addEventListener(\"paste\", (e) => {\n const fs = [...(e.clipboardData?.files ?? [])];\n if (!fs.length) return;\n e.preventDefault();\n addFiles(fs);\n });\n // Files dropped anywhere on the panel attach (and open the chat).\n const hasFiles = (e: DragEvent) => !!e.dataTransfer && [...e.dataTransfer.types].includes(\"Files\");\n pop.addEventListener(\"dragover\", (e) => {\n if (!hasFiles(e)) return;\n e.preventDefault();\n pop.setAttribute(\"data-drop\", \"\");\n });\n pop.addEventListener(\"dragleave\", (e) => {\n if (!e.relatedTarget || !pop.contains(e.relatedTarget as Node)) pop.removeAttribute(\"data-drop\");\n });\n pop.addEventListener(\"drop\", (e) => {\n if (!hasFiles(e)) return;\n e.preventDefault();\n pop.removeAttribute(\"data-drop\");\n addFiles([...(e.dataTransfer?.files ?? [])]);\n });\n email.addEventListener(\"input\", () => draw());\n\n function show(v: MessengerView | { article: string } = \"home\", still = false) {\n const was = open;\n open = true;\n view = (v === \"help\" && !helpOn) || (v === \"updates\" && !updatesOn) ? \"home\" : v;\n drawn = -1;\n previewGone = true;\n pop.toggleAttribute(\"data-still\", still);\n enter(pop);\n if (was) replay(body, \"ckw-msgr-enter\");\n if (articles === null || (view === \"help\" && query)) void loadArticles();\n draw();\n drawFab();\n if (view === \"messages\") {\n markSeen();\n text.focus();\n }\n schedule(0);\n }\n function close() {\n if (!open) return;\n open = false;\n if (menu.isConnected) closeMenu();\n leave(pop, 200);\n drawFab();\n schedule();\n if (launcherOn) fab.focus();\n // After the panel's leave, so a look waiting for the close does not cut it off.\n const fn = afterClose;\n afterClose = null;\n if (fn) setTimeout(fn, 220);\n }\n pop.addEventListener(\"click\", () => amenuOpen() && closeAmenu());\n const onKey = (e: KeyboardEvent) => {\n if (e.key !== \"Escape\" || !open) return;\n if (amenuOpen()) {\n closeAmenu();\n clip.focus();\n } else if (menuOpen()) {\n closeMenu();\n menuBtn.focus();\n } else close();\n };\n document.addEventListener(\"keydown\", onKey);\n\n // One read on load (the count and preview of answers not seen yet), and the article count for the Help tab.\n void tick();\n if (helpOn) void loadArticles();\n if (updatesOn) void loadUpdates();\n drawFab();\n if (o.opened) show(o.opened, true);\n\n return {\n open: (v) => {\n if (v === \"messages\") enterMessages();\n show(v ?? \"home\");\n },\n close,\n toggle: () => (open ? close() : show()),\n isOpen: () => open,\n onClose: (fn) => {\n afterClose = fn;\n },\n destroy: () => {\n clearTimeout(poll);\n for (const t of leaving.values()) clearTimeout(t);\n ctrl?.abort();\n for (const p of picked) forget(p);\n for (const u of localUrls.values()) URL.revokeObjectURL(u);\n document.removeEventListener(\"keydown\", onKey);\n document.removeEventListener(\"visibilitychange\", onVisible);\n root.remove();\n },\n };\n};\n"],"mappings":"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","names":["t","list","row","o"]}
|
|
1
|
+
{"version":3,"sources":["../src/messenger-ui.ts"],"sourcesContent":["/**\n * The web messenger, after Crisp's: a round launcher (a click opens it, no card on hover) and a panel\n * with a bar on top (Home, a \"Chat · Help\" switch while there are both, a ⋮ menu to minimize or widen it). Home shows the greeting,\n * the latest chat and the help search; Chat is the chat with the team, answered in MRRocket › Support by the owner or\n * the Customer experience agent; Help lists the product's published help articles by collection, searchable, read in\n * the panel. While the panel is closed it checks for answers now and then; a new answer plays a short sound, shows a\n * count on the launcher and a preview card above it. Opening, closing, switching and new messages move softly\n * (none of it with reduced motion).\n *\n * A visitor can have several conversations (0.19): Home's \"Ask a question\" starts a new one, the field inside a chat\n * answers in that chat, and Home and Messages list the others.\n *\n * Plain DOM, no React, so `<Messenger />` (Next.js) and the script tag share it; both load it only when it is used (a\n * dynamic import, and `sdk-messenger.js` for the script tag). Every text is set with textContent; articles arrive as\n * blocks, never HTML.\n */\nimport {\n type Api,\n type ArticleBlock,\n type ArticleSpan,\n type ArticleSummary,\n BRAND_URL,\n CHAT_FILES_PER_MESSAGE,\n CHAT_FILE_MAX_BYTES,\n CHAT_FILE_TYPES,\n type ChatFile,\n type ChatMessage,\n type ChatSummary,\n type ChatThread,\n type MessengerCorners,\n type MessengerLook,\n type MessengerPosition,\n createApi,\n inkOn,\n replyLine,\n stillThere,\n type ChangelogEntry,\n} from \"./api-client\";\nimport { currentLocale, onWords, t, tf, wordsLang, wordsVersion } from \"./i18n\";\nimport { injectStyles } from \"./styles-css\";\n\nexport interface MessengerUiOptions {\n host: string;\n apiKey: string;\n /** The visitor id now (it changes on identify and reset). */\n distinctId: () => string;\n /** The signed-in person's id, name and email, when the site called identify. */\n user: () => { id?: string; name?: string; email?: string } | undefined;\n /** The identity hash of the visitor id now (0.16.0), when the site gave one to identify. */\n userHash?: () => string | undefined;\n /** Show the round launcher (default true). Without it the panel opens only through `open()`. */\n launcher?: boolean;\n /** Where the launcher sits (default bottom right); the panel and the cards open from there. */\n position?: MessengerPosition;\n /** The team's name beside its mark on Home. */\n title?: string;\n /** The big line on Home and the first line of an empty chat. */\n greeting?: string;\n /** Ask anonymous visitors for an email (optional for them). Default true. */\n askEmail?: boolean;\n /** Text on the launcher; empty shows the icon only. */\n label?: string;\n /** How soon the team usually answers, said under \"Send us a message\" and in the chat's head. */\n replyTime?: \"minutes\" | \"hours\" | \"day\";\n /** The Help tab with the product's published help articles (default true; hidden while there are none). */\n help?: boolean;\n /** The Updates tab with your published changelog (default true; hidden while there are none). */\n updates?: boolean;\n /** A short sound when an answer arrives (default true). */\n sound?: boolean;\n /** A preview of a new answer above the closed launcher (default true). */\n preview?: boolean;\n theme?: \"light\" | \"dark\" | \"auto\";\n accent?: string;\n /** Up to two more colors blended with the accent in Home's background glow. */\n glow?: string[];\n /** How round panel, bubbles, cards and fields are (default round). */\n corners?: MessengerCorners;\n /** The site's own font (default) or the system's. */\n font?: \"site\" | \"system\";\n /** Home's top: plain (default) or in the accent color. */\n header?: \"plain\" | \"color\";\n /** \"Powered by MRRocket\" at the bottom; MRRocket's server says whether the plan may hide it. */\n branding?: boolean;\n /** The logo at the top left of Home (MRRocket sends the uploaded logo, else the favicon); without it the title's first letter. */\n logo?: string;\n /** The round mark in the chat's head (MRRocket sends the favicon); without it the title's first letter. */\n icon?: string;\n /** The AI agent's name on its answers (default \"AI agent\"). */\n agentName?: string;\n /** The AI agent's picture beside its answers. */\n agentPhoto?: string;\n /** MRRocket's own preview: mount inside this element (positioned) instead of the page. */\n container?: HTMLElement;\n /** MRRocket's own preview: answers from here instead of the server. */\n client?: MessengerClient;\n /** MRRocket's own preview: start open on this view, without the opening motion. */\n opened?: MessengerView;\n}\n\n/** What the messenger asks the server (createApi's part it uses). */\nexport type MessengerClient = Pick<Api, \"chat\" | \"sendChat\" | \"uploadChatFile\" | \"attachmentUrl\" | \"articles\" | \"article\" | \"rateArticle\" | \"messengerLook\" | \"changelog\">;\n\nexport type MessengerView = \"home\" | \"messages\" | \"help\" | \"updates\";\n\nexport interface MessengerHandle {\n /** Opens the panel, on Home or the given tab; `{ article }` opens a help article. */\n open(view?: MessengerView | { article: string }): void;\n close(): void;\n toggle(): void;\n /** The visitor changed (identify, reset, a signature that came later): reads for them at once. */\n refresh(): void;\n /** Removes the launcher and the panel from the page. */\n destroy(): void;\n}\n\n/** A long changelog stays light: the newest ones, the rest live on the product's changelog page. */\nconst UPDATES_SHOWN = 20;\nconst POLL_OPEN_MS = 4000;\n/**\n * A chat read not back by then is cut off and asked again: nearly every read takes 0.2 s, and the one that does not is\n * waiting for a Worker that starts cold (5 to 12 s, measured 2026-11-05), which the next read usually misses.\n */\nconst READ_PATIENCE_MS = 5000;\n/** While the panel is closed: soon after the visitor wrote, answers are looked for often, later now and then. */\nconst POLL_WAITING_MS = 8000;\nconst POLL_IDLE_MS = 30000;\n/**\n * Nothing to wait for, page in view: a slow read, so a message the team starts (Inbox › Support › New message) reaches\n * someone who has the product open. Only for those the team can write to: signed in, or with a chat already.\n */\nconst POLL_QUIET_MS = 60000;\nconst WAITING_FOR_MS = 10 * 60_000;\n/** A message the server has not taken after this long reads \"Sending…\"; until then it reads \"just now\", like a sent one. */\nconst SLOW_SEND_MS = 1500;\nconst EMAIL = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]{2,}$/;\n/** The newest answer seen in the one chat a visitor had before 0.19; it still counts for that chat. */\nconst SEEN_KEY = \"ckw_msgr_seen\";\n/** When a conversation was last read, per conversation. */\nconst SEEN_CHATS_KEY = \"ckw_msgr_seen_chats\";\n\nconst readSeen = (): { old: string; chats: Record<string, string> } => {\n try {\n return { old: window.localStorage.getItem(SEEN_KEY) ?? \"\", chats: JSON.parse(window.localStorage.getItem(SEEN_CHATS_KEY) ?? \"{}\") as Record<string, string> };\n } catch {\n return { old: \"\", chats: {} };\n }\n};\nconst writeSeen = (chats: Record<string, string>) => {\n try {\n window.localStorage.setItem(SEEN_CHATS_KEY, JSON.stringify(chats));\n } catch {\n // Private mode: the count just shows again next time.\n }\n};\n\nconst timeAgo = (iso: string) => {\n const at = new Date(iso).getTime();\n if (Number.isNaN(at)) return \"\";\n const d = Math.max(0, Date.now() - at) / 1000;\n if (d < 60) return t(\"just now\");\n if (d < 3600) return tf(\"{n}m ago\", { n: Math.floor(d / 60) });\n if (d < 86400) return tf(\"{n}h ago\", { n: Math.floor(d / 3600) });\n if (d < 86400 * 30) return tf(\"{n}d ago\", { n: Math.floor(d / 86400) });\n return new Date(iso).toLocaleDateString(currentLocale(), { month: \"short\", day: \"numeric\", year: \"numeric\" });\n};\n\nconst el = <K extends keyof HTMLElementTagNameMap>(tag: K, attrs: Record<string, string> = {}, ...kids: (Node | string | null | false | undefined)[]) => {\n const e = document.createElement(tag);\n for (const [k, v] of Object.entries(attrs)) e.setAttribute(k, v);\n for (const k of kids) if (k !== null && k !== false && k !== undefined) e.append(k);\n return e;\n};\n\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\n/** A line icon on a 24-unit grid (Lucide's shapes, ISC). */\nconst icon = (d: string, size = 16) => {\n const svg = document.createElementNS(SVG_NS, \"svg\");\n for (const [k, v] of Object.entries({ class: \"ckw-icon\", width: String(size), height: String(size), viewBox: \"0 0 24 24\", fill: \"none\", stroke: \"currentColor\", \"stroke-width\": \"1.75\", \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\", \"aria-hidden\": \"true\" }))\n svg.setAttribute(k, v);\n const path = document.createElementNS(SVG_NS, \"path\");\n path.setAttribute(\"d\", d);\n svg.appendChild(path);\n return svg;\n};\nconst I = {\n cross: \"M18 6 6 18M6 6l12 12\",\n chat: \"M7.9 20A9 9 0 1 0 4 16.1L2 22z\",\n send: \"M5 12h14M12 5l7 7-7 7\",\n up: \"M12 19V5M5 12l7-7 7 7\",\n home: \"M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\",\n back: \"m15 18-6-6 6-6\",\n next: \"m9 18 6-6-6-6\",\n search: \"M19 11a8 8 0 1 1-16 0 8 8 0 0 1 16 0zM21 21l-4.3-4.3\",\n doc: \"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7zM14 2v4a2 2 0 0 0 2 2h4M10 9H8M16 13H8M16 17H8\",\n book: \"M12 7v14M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z\",\n dots: \"M13 12a1 1 0 1 1-2 0 1 1 0 0 1 2 0zM13 5a1 1 0 1 1-2 0 1 1 0 0 1 2 0zM13 19a1 1 0 1 1-2 0 1 1 0 0 1 2 0z\",\n expand: \"M15 3h6v6M21 3l-7 7M3 21l7-7M9 21H3v-6\",\n collapse: \"m14 10 7-7M20 10h-6V4M3 21l7-7M4 14h6v6\",\n minus: \"M5 12h14\",\n down: \"m6 9 6 6 6-6\",\n help: \"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20zM9.1 9a3 3 0 0 1 5.8 1c0 2-3 3-3 3M12 17h.01\",\n updates: \"m3 11 18-5v12L3 14zM11.6 16.8a3 3 0 1 1-5.8-1.6\",\n clip: \"m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l8.57-8.57A4 4 0 1 1 18 8.84l-8.59 8.57a2 2 0 0 1-2.83-2.83l8.49-8.48\",\n image: \"M19 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2zM9 11a2 2 0 1 0 0-4 2 2 0 0 0 0 4zM21 15l-3.09-3.09a2 2 0 0 0-2.82 0L6 21\",\n screen: \"M20 3H4a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2zM8 21h8M12 17v4\",\n};\n\n/** A message's words for a one-line preview: its text, or what it sent. */\nconst lineOf = (m: ChatMessage) => m.body || (m.attachments?.length === 1 ? tf(\"Sent {name}\", { name: m.attachments[0].name }) : m.attachments?.length ? tf(\"Sent {n} files\", { n: m.attachments.length }) : \"\");\n\n/** The browser can grab a picture of this tab (not on phones, where people screenshot with the phone and attach it). */\nconst canShoot = () => typeof navigator !== \"undefined\" && typeof navigator.mediaDevices?.getDisplayMedia === \"function\";\n/** The launcher's filled bubble (24-unit grid). */\nconst BUBBLE = \"M7.9 20A9 9 0 1 0 4 16.1L2 22z\";\nconst filled = (d: string, size: number) => {\n const svg = document.createElementNS(SVG_NS, \"svg\");\n for (const [k, v] of Object.entries({ class: \"ckw-icon\", width: String(size), height: String(size), viewBox: \"0 0 24 24\", fill: \"currentColor\", stroke: \"currentColor\", \"stroke-width\": \"1.5\", \"stroke-linejoin\": \"round\", \"aria-hidden\": \"true\" }))\n svg.setAttribute(k, v);\n const path = document.createElementNS(SVG_NS, \"path\");\n path.setAttribute(\"d\", d);\n svg.appendChild(path);\n return svg;\n};\n\n/** A filled shape with lines cut into it in the ground's color (`.ckw-cut`): the current tab's icon, the launcher's bubble. */\nconst duo = (shape: string, cut: string, size: number, width = 2) => {\n const svg = filled(shape, size);\n const path = document.createElementNS(SVG_NS, \"path\");\n for (const [k, v] of Object.entries({ d: cut, class: \"ckw-cut\", fill: \"none\", \"stroke-width\": String(width), \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\" })) path.setAttribute(k, v);\n svg.appendChild(path);\n return svg;\n};\nconst DOTS = \"M8 12h.01M12 12h.01M16 12h.01\";\nconst HOUSE = \"M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\";\nconst SMILE = \"M9.5 15.5c1.4 1 3.6 1 5 0\";\nconst DISC = \"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20z\";\nconst QMARK = \"M9.4 9.2a2.7 2.7 0 0 1 5.2 1c0 1.8-2.6 2.5-2.6 2.5M12 16.8h.01\";\nconst MEGAPHONE = \"m3 11 18-5v12L3 14zM5.8 15.2a3 3 0 0 0 5.8 1.6z\";\n\n/** A soft two-note chime made with Web Audio (no file to load). Browsers allow it once the visitor has clicked. */\nconst chime = (() => {\n let ctx: AudioContext | null = null;\n const get = () => {\n const AC = window.AudioContext ?? (window as unknown as { webkitAudioContext?: typeof AudioContext }).webkitAudioContext;\n if (!AC) return null;\n ctx ??= new AC();\n return ctx;\n };\n return {\n /** Call from a click so later sounds may play. */\n unlock: () => {\n try {\n const c = get();\n if (c?.state === \"suspended\") void c.resume();\n } catch {\n // No audio: no sound.\n }\n },\n play: () => {\n try {\n const c = get();\n if (!c || c.state !== \"running\") return;\n const t = c.currentTime;\n [880, 1318.5].forEach((f, i) => {\n const o = c.createOscillator();\n const g = c.createGain();\n const at = t + i * 0.11;\n o.type = \"sine\";\n o.frequency.value = f;\n g.gain.setValueAtTime(0.0001, at);\n g.gain.exponentialRampToValueAtTime(0.12, at + 0.012);\n g.gain.exponentialRampToValueAtTime(0.0001, at + 0.32);\n o.connect(g);\n g.connect(c.destination);\n o.start(at);\n o.stop(at + 0.34);\n });\n } catch {\n // No audio: no sound.\n }\n },\n };\n})();\n\nconst spansOf = (spans: ArticleSpan[]) =>\n spans.map((s) => {\n let node: HTMLElement = s.href ? el(\"a\", { href: s.href, target: \"_blank\", rel: \"noopener noreferrer\" }, s.text) : el(\"span\", {}, s.text);\n if (s.code) node = el(\"code\", {}, node);\n if (s.italic) node = el(\"em\", {}, node);\n if (s.bold) node = el(\"strong\", {}, node);\n return node;\n });\n\nconst blockOf = (b: ArticleBlock): HTMLElement => {\n switch (b.type) {\n case \"h2\":\n case \"h3\":\n return el(b.type, {}, ...spansOf(b.spans));\n case \"quote\":\n return el(\"blockquote\", {}, ...spansOf(b.spans));\n case \"ul\":\n case \"ol\":\n return el(b.type, {}, ...b.items.map((it) => el(\"li\", {}, ...spansOf(it))));\n case \"code\":\n return el(\"pre\", {}, el(\"code\", {}, b.text));\n case \"hr\":\n return el(\"hr\");\n default:\n return el(\"p\", {}, ...spansOf(b.spans));\n }\n};\n\n/** How long the launcher waits for the look from MRRocket before it shows with the code's options and the defaults. */\nconst LOOK_WAIT_MS = 2500;\nconst LOOK_KEY = \"ckw_msgr_look:\";\n\n/** The look this browser saw last, so a repeat visit shows the right launcher at once. */\nconst readCachedLook = (apiKey: string): Partial<MessengerLook> | null => {\n try {\n const raw = window.localStorage.getItem(LOOK_KEY + apiKey);\n return raw ? (JSON.parse(raw) as Partial<MessengerLook>) : null;\n } catch {\n return null;\n }\n};\nconst writeCachedLook = (apiKey: string, look: Partial<MessengerLook>) => {\n try {\n window.localStorage.setItem(LOOK_KEY + apiKey, JSON.stringify(look));\n } catch {\n // Private mode or full storage: the next visit waits for the look again.\n }\n};\n\n/**\n * What the panel knew last, so a reload or the next page shows it at once and the read on load brings it up to date\n * (owner, 2026-11-05: \"dann kam lange nichts und jetzt sehe ich die chats wieder\"): a visitor's conversations, only under\n * the id that read them, and whether the product has help articles and updates. A sign-out takes the conversations along.\n */\nconst CHATS_KEY = \"ckw_msgr_chats:\";\nconst PRODUCT_KEY = \"ckw_msgr_product:\";\nconst KEPT = 20;\nconst kept = <T>(key: string): Partial<T> | null => {\n try {\n return JSON.parse(window.localStorage.getItem(key) ?? \"null\") as Partial<T> | null;\n } catch {\n return null;\n }\n};\nconst keep = (key: string, value: unknown) => {\n try {\n if (value) window.localStorage.setItem(key, JSON.stringify(value));\n else window.localStorage.removeItem(key);\n } catch {\n // Private mode or full storage: the next page waits for the read.\n }\n};\n\n/**\n * Mounts the messenger with its look from MRRocket (Support › Messenger) underneath what the code passes: an option the\n * code sets wins, one it leaves out comes from MRRocket, then the default. Calls made before the look arrived wait.\n * A repeat visit starts with the look this browser saw last; a look that arrives later than that (changed, or slower\n * than LOOK_WAIT_MS) replaces the launcher while the panel is closed, or once it closes. New words or another language\n * do the same: the messenger is built anew, with the look read again in another language.\n */\nexport const mountMessenger = (o: MessengerUiOptions): MessengerHandle => {\n let real: BuiltMessenger | null = null;\n let shown = \"\";\n let gone = false;\n const queued: ((h: MessengerHandle) => void)[] = [];\n const later = (fn: (h: MessengerHandle) => void) => (real ? fn(real) : queued.push(fn));\n const ctrl = new AbortController();\n const caching = !o.client && !!o.apiKey;\n let lastLook: Partial<MessengerLook> | null = null;\n const start = (look: Partial<MessengerLook> | null) => {\n if (gone) return;\n lastLook = look;\n const key = `${wordsVersion()}:${JSON.stringify(look ?? {})}`;\n if (real && key === shown) return;\n if (real?.isOpen()) {\n // Never swap the panel under the visitor: the new look waits for the close.\n real.onClose(() => start(look));\n return;\n }\n real?.destroy();\n shown = key;\n const defined = Object.fromEntries(Object.entries(o).filter(([, v]) => v !== undefined)) as MessengerUiOptions;\n // The branding comes from the server alone: what the plan allows is not the site's code to decide.\n real = build({ ...(look ?? {}), ...defined, accent: o.accent ?? look?.accent, theme: o.theme ?? look?.theme, branding: look?.branding ?? true });\n for (const fn of queued.splice(0)) fn(real);\n };\n const cached = caching ? readCachedLook(o.apiKey) : null;\n if (cached) start(cached);\n const timer = cached ? undefined : setTimeout(() => start(null), LOOK_WAIT_MS);\n const readLook = () =>\n (o.client ?? createApi({ host: o.host, apiKey: o.apiKey, distinctId: o.distinctId(), user: o.user(), userHash: o.userHash?.() }))\n .messengerLook(ctrl.signal)\n .then((look) => {\n if (caching && look) writeCachedLook(o.apiKey, look);\n start(look);\n })\n .catch(() => {\n // Without the look: the words still change, under the look it has.\n start(lastLook);\n })\n .finally(() => clearTimeout(timer));\n let readIn = currentLocale();\n void readLook();\n const offWords = onWords(() => {\n // Another language: the look's words too. Only new words: the messenger is built anew with the look it has.\n if (currentLocale() !== readIn) {\n readIn = currentLocale();\n void readLook();\n } else if (real) start(lastLook);\n });\n return {\n open: (v) => later((h) => h.open(v)),\n close: () => real?.close(),\n toggle: () => later((h) => h.toggle()),\n refresh: () => real?.refresh(),\n destroy: () => {\n gone = true;\n offWords();\n ctrl.abort();\n clearTimeout(timer);\n real?.destroy();\n },\n };\n};\n\n/** What `build` hands `mountMessenger`: the handle plus what a later look needs to swap the messenger safely. */\ninterface BuiltMessenger extends MessengerHandle {\n isOpen(): boolean;\n /** Runs once, the next time the panel closes. */\n onClose(fn: () => void): void;\n}\n\nconst PLACES: MessengerPosition[] = [\"top-left\", \"top-center\", \"top-right\", \"middle-left\", \"middle-right\", \"bottom-left\", \"bottom-center\", \"bottom-right\"];\n\nconst build = (o: MessengerUiOptions): BuiltMessenger => {\n injectStyles();\n // A script tag's attribute can say anything: an unknown place, corner or top is the default.\n const position = PLACES.find((p) => p === o.position) ?? \"bottom-right\";\n const title = o.title || t(\"Support\");\n const greeting = o.greeting || t(\"Hi! How can we help?\");\n const askEmail = o.askEmail ?? true;\n const label = o.label ?? \"\";\n const reply = replyLine(o.replyTime);\n /** The team's mark: the first letter of the title, on the accent. */\n const initial = (title.trim()[0] ?? \"?\").toUpperCase();\n // The agent's name never stands alone: this is what tells the visitor an answer is the AI's (EU AI Act Art. 50), in\n // place of the line under its text (src/server/legal/notices.ts in MRRocket).\n const whoLabel: Record<ChatMessage[\"from\"], string> = { visitor: t(\"You\"), team: t(\"Team\"), ai: o.agentName?.trim() ? `${o.agentName.trim()} · ${t(\"AI agent\")}` : t(\"AI agent\"), auto: t(\"Team\") };\n const launcherOn = o.launcher ?? true;\n const helpOn = o.help ?? true;\n const updatesOn = o.updates ?? true;\n const soundOn = o.sound ?? true;\n const previewOn = o.preview ?? true;\n const api = (): MessengerClient => o.client ?? createApi({ host: o.host, apiKey: o.apiKey, distinctId: o.distinctId(), user: o.user(), userHash: o.userHash?.() });\n\n const root = el(\"div\", {\n class: \"ckw-root\",\n \"data-theme\": o.theme ?? \"auto\",\n \"data-corners\": o.corners === \"soft\" || o.corners === \"square\" ? o.corners : \"round\",\n \"data-font\": o.font === \"system\" ? \"system\" : \"site\",\n \"data-header\": o.header === \"color\" ? \"color\" : \"plain\",\n // Screen readers read the panel in the language of its words. Built anew when they change.\n ...(wordsLang() ? { lang: wordsLang() as string } : {}),\n });\n if (o.container) root.setAttribute(\"data-contained\", \"\");\n if (o.accent) {\n root.style.setProperty(\"--ckw-accent\", o.accent);\n root.style.setProperty(\"--ckw-accent-ink\", inkOn(o.accent));\n }\n o.glow?.slice(0, 2).forEach((c, i) => /^#[0-9a-f]{6}$/i.test(c) && root.style.setProperty(`--ckw-glow${i + 2}`, c));\n (o.container ?? document.body).appendChild(root);\n\n let open = false;\n let afterClose: (() => void) | null = null;\n let view: MessengerView | { article: string } = \"home\";\n let thread: ChatThread | null = null;\n /** All the visitor's conversations, the latest activity first. */\n let chats: ChatSummary[] = [];\n let hasEmail = false;\n /** The conversation on screen; null: the newest one, all a visitor with a single conversation ever sees. */\n let chatId: string | null = null;\n /** A new conversation being written, numbered so each stays its own; it becomes `chatId` once the server took it. */\n let draft: number | null = null;\n let drafts = 0;\n /** Messages shows the list of conversations instead of one of them. */\n let listing = false;\n let loaded = false;\n let error = \"\";\n /**\n * What the visitor reads when the server refuses. A refused identity (401: the product has not signed this user yet)\n * is the product team's setup, said in the console (warnUnsigned); the visitor never sees setup steps meant for them.\n */\n const sayable = (e: unknown) => ((e as { status?: number }).status === 401 ? t(\"The chat is not available right now. Please try again later.\") : (e as Error).message);\n /**\n * What the visitor sent that the server has not taken yet, oldest first: shown at once and sent one after another,\n * so the next message can be typed and sent right away (2026-10-30: one send blocked the field for seconds).\n */\n let outbox: { message: ChatMessage; files: Picked[]; email?: string; chat: string | null; draft: number | null }[] = [];\n let outboxSeq = 0;\n let flushing = false;\n /** The time of the newest message known per conversation in this page load: answers after it are new. */\n const known = new Map<string, string>();\n let seen = readSeen();\n let unseen: (ChatMessage & { chat: string })[] = [];\n let previewGone = false;\n let poll: ReturnType<typeof setTimeout> | undefined;\n /** The server refused the last read (a signed-in user without a valid hash): no slow reads until one works. */\n let refused = false;\n let ctrl: AbortController | null = null;\n let articles: ArticleSummary[] | null = null;\n let query = \"\";\n let rated = new Set<string>();\n /** Whether the product has any published article (null: not known yet): the Help tab and Home's help card show only when it has. */\n let hasArticles: boolean | null = null;\n /** The newest articles without a search: Home's help card, and what the browser keeps. */\n let homeArticles: ArticleSummary[] = [];\n /** Reads in a row that failed or took too long; they are asked again soon, a little later each time. */\n let misses = 0;\n /** The published changelog (null until read); kept as one node, so a redraw never moves the reader's place. */\n let updates: ChangelogEntry[] | null = null;\n /** There are updates to read, known before `updates` from what the browser kept. */\n let hasUpdates = false;\n let updatesNode: HTMLElement | null = null;\n /** The help collection opened from Help's list (null: the list of collections). */\n let collection: string | null = null;\n /** The panel widened from the ⋮ menu. */\n let wide = false;\n\n const remembers = !o.client && !!o.apiKey;\n const chatsKey = CHATS_KEY + o.apiKey;\n const productKey = PRODUCT_KEY + o.apiKey;\n let visitor = o.distinctId();\n let person = o.user()?.id;\n /** This visitor's conversations as this browser kept them; another visitor's never show. */\n const recall = () => {\n const m = remembers ? kept<{ who: string; chats: ChatSummary[] }>(chatsKey) : null;\n chats = m?.who === visitor && Array.isArray(m.chats) ? m.chats : [];\n };\n recall();\n if (remembers) {\n const m = kept<{ articles: ArticleSummary[]; updates: boolean }>(productKey);\n if (m?.articles?.length) {\n homeArticles = m.articles;\n articles = m.articles;\n hasArticles = true;\n }\n hasUpdates = !!m?.updates;\n }\n /** An empty list forgets only the visitor's own: someone not signed in yet leaves what is kept for who they turn out to be. */\n const rememberChats = (who: string) => {\n if (!remembers || o.distinctId() !== who) return;\n if (chats.length) keep(chatsKey, { who, chats: chats.slice(0, KEPT) });\n else if (kept<{ who: string }>(chatsKey)?.who === who) keep(chatsKey, null);\n };\n const rememberProduct = () => {\n if (remembers) keep(productKey, homeArticles.length || hasUpdates ? { articles: homeArticles.slice(0, KEPT), updates: hasUpdates } : null);\n };\n\n const isAnswer = (m: ChatMessage) => m.from === \"team\" || m.from === \"ai\";\n const watching = () => open && view === \"messages\" && document.visibilityState !== \"hidden\";\n /** The chat on screen, if one is: not while the list or a new conversation shows. */\n const shownChat = () => (listing || draft !== null ? null : (chatId ?? thread?.conversation?.id ?? null));\n const unseenIn = (chat: string) => unseen.filter((m) => m.chat === chat).length;\n\n /** New answers of one conversation count, chime and show in the preview; the list brings only its newest one. */\n const learn = (chat: string, answers: ChatMessage[], newest: string | undefined, settled: boolean) => {\n const was = known.get(chat);\n const after = (at: string) => answers.filter((m) => m.at > at);\n if (was === undefined) {\n // First sight: answers the visitor never saw in an earlier visit count, without a sound. An older chat that\n // is closed is history, not news.\n const read = seen.chats[chat];\n const fresh = settled ? [] : read ? after(read) : answers.slice(answers.findIndex((m) => m.id === seen.old) + 1);\n unseen = [...unseen, ...fresh.map((m) => ({ ...m, chat }))];\n // A conversation the team started while the page is open is news like any answer.\n if (loaded && fresh.length) {\n if (soundOn) chime.play();\n previewGone = false;\n }\n } else {\n const fresh = after(was);\n if (fresh.length) {\n if (soundOn) chime.play();\n if (!watching() || shownChat() !== chat) {\n unseen = [...unseen, ...fresh.map((m) => ({ ...m, chat }))];\n previewGone = false;\n }\n }\n }\n known.set(chat, newest ?? was ?? \"\");\n };\n /** Takes what the server read: the list of conversations and, if it is the one on screen, the chat. */\n const take = (t: ChatThread) => {\n const read = t.conversation;\n const last = t.messages.at(-1);\n // A server or a sample client without the list: the one chat it read.\n chats = t.conversations ?? (read && last ? [{ id: read.id, status: read.status, subject: lineOf(t.messages[0]), last }] : []);\n hasEmail = t.hasEmail;\n chats.forEach((c, i) => {\n if (c.id !== read?.id) learn(c.id, c.last && isAnswer(c.last) ? [c.last] : [], c.last?.at, c.status === \"solved\" && i > 0);\n });\n if (read) learn(read.id, t.messages.filter(isAnswer), last?.at, read.status === \"solved\" && chats[0]?.id !== read.id);\n unseen = unseen.filter(stillThere(t, chats));\n if (chatId === null || read?.id === chatId) thread = t;\n if (watching()) markSeen();\n };\n const markSeen = () => {\n const chat = shownChat();\n if (!chat) return;\n unseen = unseen.filter((m) => m.chat !== chat);\n const at = known.get(chat);\n if (!at || seen.chats[chat] === at) return;\n // Only conversations the visitor still has, so this never grows.\n const kept = Object.fromEntries(Object.entries(seen.chats).filter(([c]) => chats.some((x) => x.id === c)));\n seen = { ...seen, chats: { ...kept, [chat]: at } };\n writeSeen(seen.chats);\n };\n\n /** Puts a conversation on screen; a read on its way for another one must not arrive here. */\n const enterChat = (id: string | null, d: number | null, list = false) => {\n if (id !== chatId || d !== draft) {\n ctrl?.abort();\n ctrl = null;\n thread = null;\n listSig = \"\";\n listCount = -1;\n }\n chatId = id;\n draft = d;\n listing = list;\n };\n /** Messages from a tab: the list once there are several conversations, else the one chat. */\n const enterMessages = () => enterChat(null, null, chats.length > 1);\n const startChat = () => enterChat(null, ++drafts);\n\n const letter = (size?: \"sm\") => el(\"span\", { class: `ckw-msgr-av${size ? \" ckw-msgr-av-sm\" : \"\"}`, \"aria-hidden\": \"true\" }, initial);\n /** The team's round mark: the product's icon, or the title's first letter when it has none (or it fails to load). */\n const avatar = (size?: \"sm\") => {\n if (!o.icon) return letter(size);\n const av = el(\"span\", { class: `ckw-msgr-av ckw-msgr-av-img${size ? \" ckw-msgr-av-sm\" : \"\"}`, \"aria-hidden\": \"true\" });\n const img = el(\"img\", { src: o.icon, alt: \"\" });\n img.addEventListener(\"error\", () => av.replaceWith(letter(size)));\n av.append(img);\n return av;\n };\n /** Home's top left: the uploaded logo (any shape) or the product's icon, else the round mark. */\n const logo = el(\"span\", { class: \"ckw-msgr-logo\", \"aria-hidden\": \"true\" });\n if (o.logo) {\n const img = el(\"img\", { src: o.logo, alt: \"\" });\n img.addEventListener(\"error\", () => logo.replaceChildren(avatar(\"sm\")));\n logo.append(img);\n } else logo.append(avatar(\"sm\"));\n /** The AI agent's face on its answers' line; nothing without a picture. */\n const agentFace = () => (o.agentPhoto ? el(\"img\", { class: \"ckw-msg-face\", src: o.agentPhoto, alt: \"\" }) : null);\n /** Home's background: a soft silk of the accent with a field of dots drifting through it, top right. */\n const sky = el(\"div\", { class: \"ckw-msgr-sky\", \"aria-hidden\": \"true\" });\n\n // ---------- Coming and going ----------\n /** Pending removals: a node that leaves plays its way out first (data-out), unless it is shown again meanwhile. */\n const leaving = new Map<HTMLElement, ReturnType<typeof setTimeout>>();\n const enter = (node: HTMLElement, parent: HTMLElement = root) => {\n clearTimeout(leaving.get(node));\n leaving.delete(node);\n node.removeAttribute(\"data-out\");\n if (!node.isConnected) parent.appendChild(node);\n };\n const leave = (node: HTMLElement, ms = 180) => {\n if (!node.isConnected || leaving.has(node)) return;\n node.setAttribute(\"data-out\", \"\");\n leaving.set(\n node,\n setTimeout(() => {\n leaving.delete(node);\n node.removeAttribute(\"data-out\");\n node.remove();\n }, ms),\n );\n };\n /** Plays an entrance again on a node that stays (a new view in the same body). */\n const replay = (node: HTMLElement, cls: string) => {\n node.classList.remove(cls);\n void node.offsetWidth;\n node.classList.add(cls);\n };\n\n // ---------- Launcher and preview ----------\n const fab = el(\"button\", { type: \"button\", class: `ckw-fab ckw-msgr-fab${label ? \"\" : \" ckw-msgr-round\"}`, \"data-pos\": position, \"aria-haspopup\": \"dialog\" });\n const fabIcons = el(\n \"span\",\n { class: \"ckw-msgr-fab-ic\", \"aria-hidden\": \"true\" },\n el(\"span\", { class: \"ckw-msgr-fab-i\", \"data-i\": \"chat\" }, duo(BUBBLE, DOTS, label ? 20 : 27, 2.6)),\n el(\"span\", { class: \"ckw-msgr-fab-i\", \"data-i\": \"x\" }, icon(I.down, label ? 18 : 24)),\n );\n const fabCount = el(\"span\", { class: \"ckw-msgr-count\", \"aria-hidden\": \"true\" });\n fab.append(fabIcons);\n if (label) fab.append(el(\"span\", {}, label));\n const prev = el(\"div\", { class: \"ckw-msgr-preview\", \"data-pos\": position, role: \"status\" });\n const drawFab = () => {\n fab.toggleAttribute(\"data-open\", open);\n if (unseen.length && !open) {\n const n = String(Math.min(unseen.length, 9));\n if (fabCount.textContent !== n) fabCount.textContent = n;\n if (!fabCount.isConnected) fab.append(fabCount);\n } else fabCount.remove();\n fab.setAttribute(\"aria-expanded\", String(open));\n fab.setAttribute(\"aria-label\", open ? t(\"Close chat\") : unseen.length === 1 ? t(\"Open chat, 1 new reply\") : unseen.length ? tf(\"Open chat, {n} new replies\", { n: unseen.length }) : t(\"Open chat\"));\n drawPreview();\n };\n const previewShown = () => previewOn && !open && !previewGone && !!unseen.length && launcherOn;\n const drawPreview = () => {\n const m = unseen.at(-1);\n if (!previewShown() || !m) return leave(prev);\n const x = el(\"button\", { type: \"button\", class: \"ckw-msgr-preview-x\", \"aria-label\": t(\"Dismiss\") }, icon(I.cross, 14));\n x.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n previewGone = true;\n drawPreview();\n });\n const card = el(\n \"button\",\n { type: \"button\", class: \"ckw-msgr-preview-card\" },\n el(\n \"span\",\n { class: \"ckw-msgr-preview-main\" },\n el(\"span\", { class: \"ckw-msgr-preview-who\" }, `${whoLabel[m.from]}${unseen.length > 1 ? ` · ${tf(\"{n} new\", { n: unseen.length })}` : \"\"}`),\n el(\"span\", { class: \"ckw-msgr-preview-text\" }, lineOf(m)),\n ),\n );\n card.addEventListener(\"click\", () => {\n enterChat(m.chat, null);\n show(\"messages\");\n });\n prev.replaceChildren(card, x);\n enter(prev);\n };\n\n fab.addEventListener(\"click\", () => {\n chime.unlock();\n if (open) return close();\n const news = unseen.at(-1);\n if (news) enterChat(news.chat, null);\n show(news ? \"messages\" : \"home\");\n });\n if (launcherOn) root.appendChild(fab);\n\n // ---------- Panel ----------\n const pop = el(\"div\", { class: \"ckw-pop ckw-msgr\", \"data-pos\": position, role: \"dialog\", \"aria-label\": title });\n const bar = el(\"div\", { class: \"ckw-msgr-bar\" });\n const body = el(\"div\", { class: \"ckw-pop-body ckw-msgr-body\" });\n pop.addEventListener(\"click\", () => chime.unlock());\n\n // The bar keeps its elements between draws; its middle says where the visitor is (the team in a chat, Help).\n const lead = el(\"span\", { class: \"ckw-msgr-lead\" });\n const mid = el(\"span\", { class: \"ckw-msgr-mid\" });\n // Home · Messages · Help along the foot like an app's tab bar (the open chat has its composer there instead):\n // a line icon, filled while its tab is the current one.\n const tabs = el(\"nav\", { class: \"ckw-msgr-tabs\", \"aria-label\": t(\"Messenger\") });\n const tab = (v: MessengerView, name: string, line: string, shape: string, cut: string) => {\n const b = el(\"button\", { type: \"button\", class: \"ckw-msgr-tab\" }, el(\"span\", { class: \"ckw-msgr-tab-ic\" }, icon(line, 22), duo(shape, cut, 22)), el(\"span\", {}, name));\n b.addEventListener(\"click\", () => {\n collection = null;\n if (v === \"messages\") enterMessages();\n go(v);\n });\n return b;\n };\n const homeTab = tab(\"home\", t(\"Home\"), I.home, HOUSE, SMILE);\n const chatTab = tab(\"messages\", t(\"Messages\"), I.chat, BUBBLE, DOTS);\n const helpTab = tab(\"help\", t(\"Help\"), I.help, DISC, QMARK);\n const updatesTab = tab(\"updates\", t(\"Updates\"), I.updates, MEGAPHONE, \"\");\n const tabCount = el(\"span\", { class: \"ckw-msgr-count ckw-msgr-count-tab\", \"aria-hidden\": \"true\" });\n const menuBtn = el(\"button\", { type: \"button\", class: \"ckw-msgr-ib\", \"aria-label\": t(\"More\"), \"aria-haspopup\": \"menu\", \"aria-expanded\": \"false\" }, icon(I.dots, 18));\n /** On a phone the panel covers the launcher, so it has its own close. */\n const xBtn = el(\"button\", { type: \"button\", class: \"ckw-msgr-ib ckw-msgr-x\", \"aria-label\": t(\"Close messenger\") }, icon(I.cross));\n xBtn.addEventListener(\"click\", () => close());\n bar.append(lead, mid, el(\"span\", { class: \"ckw-msgr-trail\" }, menuBtn, xBtn));\n\n const menu = el(\"div\", { class: \"ckw-msgr-menu\", role: \"menu\" });\n const menuOpen = () => menu.isConnected && !menu.hasAttribute(\"data-out\");\n const closeMenu = () => {\n menuBtn.setAttribute(\"aria-expanded\", \"false\");\n leave(menu, 120);\n };\n const menuItem = (d: string, name: string, act: () => void) => {\n const b = el(\"button\", { type: \"button\", class: \"ckw-msgr-menu-i\", role: \"menuitem\" }, icon(d, 15), el(\"span\", {}, name));\n b.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n closeMenu();\n act();\n });\n return b;\n };\n menuBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n if (menuOpen()) return closeMenu();\n menu.replaceChildren(\n el(\"span\", { class: \"ckw-msgr-menu-h\" }, t(\"Quick actions\")),\n menuItem(I.minus, t(\"Minimize chat\"), () => close()),\n menuItem(wide ? I.collapse : I.expand, wide ? t(\"Collapse view\") : t(\"Expand view\"), () => {\n wide = !wide;\n pop.toggleAttribute(\"data-wide\", wide);\n }),\n );\n menuBtn.setAttribute(\"aria-expanded\", \"true\");\n enter(menu, pop);\n (menu.querySelector(\"button\") as HTMLButtonElement | null)?.focus();\n });\n pop.addEventListener(\"click\", () => menuOpen() && closeMenu());\n\n const drawBar = () => {\n const back = (to: () => void, name: string) => {\n const b = el(\"button\", { type: \"button\", class: \"ckw-msgr-ib\", \"aria-label\": name }, icon(I.back, 18));\n b.addEventListener(\"click\", to);\n return b;\n };\n if (typeof view !== \"string\")\n lead.replaceChildren(\n back(() => go(\"help\"), t(\"Back to help\")),\n );\n else if (view === \"help\" && collection && !query.trim())\n lead.replaceChildren(\n back(() => {\n collection = null;\n go(\"help\");\n }, t(\"All collections\")),\n );\n else if (view === \"messages\" && !listing && chats.length > 1)\n lead.replaceChildren(\n back(() => {\n enterMessages();\n go(\"messages\");\n }, t(\"All conversations\")),\n );\n else if (view === \"messages\") lead.replaceChildren(back(() => go(\"home\"), t(\"Back to home\")));\n else if (view === \"home\") lead.replaceChildren(logo);\n else lead.replaceChildren();\n if (view === \"messages\" && listing) mid.replaceChildren(el(\"b\", {}, t(\"Messages\")));\n else if (view === \"messages\") mid.replaceChildren(avatar(\"sm\"), el(\"span\", { class: \"ckw-msgr-mid-t\" }, el(\"b\", {}, title), el(\"span\", { class: \"ckw-msgr-online\" }, reply)));\n else if (view === \"help\") mid.replaceChildren(el(\"b\", {}, t(\"Help\")));\n else if (view === \"updates\") mid.replaceChildren(el(\"b\", {}, t(\"Updates\")));\n else mid.replaceChildren();\n // Without published articles there is no Help tab, and without a published update no Updates tab.\n // A tab comes when its content is known to exist, so none shows first and then goes away again.\n const items = [homeTab, chatTab, ...(helpOn && hasArticles ? [helpTab] : []), ...(updatesOn && (updates ? updates.length : hasUpdates) ? [updatesTab] : [])];\n if (tabs.childNodes.length !== items.length || items.some((t, i) => tabs.childNodes[i] !== t)) tabs.replaceChildren(...items);\n // Four names do not fit beside their icons on a phone: each stands under its icon.\n tabs.toggleAttribute(\"data-four\", items.length > 3);\n homeTab.setAttribute(\"aria-current\", view === \"home\" ? \"page\" : \"false\");\n chatTab.setAttribute(\"aria-current\", view === \"messages\" ? \"page\" : \"false\");\n helpTab.setAttribute(\"aria-current\", view !== \"home\" && view !== \"messages\" && view !== \"updates\" ? \"page\" : \"false\");\n updatesTab.setAttribute(\"aria-current\", view === \"updates\" ? \"page\" : \"false\");\n if (unseen.length && view !== \"messages\") {\n tabCount.textContent = String(Math.min(unseen.length, 9));\n if (!tabCount.isConnected) chatTab.firstChild!.appendChild(tabCount);\n } else tabCount.remove();\n };\n\n // The chat's compose form keeps its elements between draws, so the field never loses the focus.\n const form = el(\"form\", { class: \"ckw-msgr-compose\" });\n const err = el(\"p\", { class: \"ckw-msgr-error\", role: \"alert\" });\n const email = el(\"input\", { class: \"ckw-input ckw-msgr-email\", type: \"email\", inputmode: \"email\", autocomplete: \"email\", placeholder: t(\"Email for our reply (optional)\"), \"aria-label\": t(\"Your email (optional)\"), maxlength: \"200\", \"data-1p-ignore\": \"\", \"data-lpignore\": \"true\", \"data-bwignore\": \"\", \"data-form-type\": \"other\" });\n const row = el(\"div\", { class: \"ckw-msgr-box\" });\n const text = el(\"textarea\", { class: \"ckw-textarea ckw-msgr-input\", rows: \"1\", placeholder: t(\"Write your message…\"), \"aria-label\": t(\"Message\"), maxlength: \"4000\" });\n const send = el(\"button\", { type: \"submit\", class: \"ckw-msgr-send\", \"aria-label\": t(\"Send\") }, icon(I.up));\n // Files for the next message (screenshots, photos, a PDF): picked with the paperclip, pasted or dropped onto the\n // panel. Each uploads the moment it is picked; Send waits for the uploads.\n const shots = canShoot();\n const clip = el(\n \"button\",\n { type: \"button\", class: \"ckw-msgr-clip\", \"aria-label\": shots ? t(\"Attach a file or a screenshot\") : t(\"Attach a file\"), ...(shots ? { \"aria-haspopup\": \"menu\", \"aria-expanded\": \"false\" } : {}) },\n icon(I.clip, 18),\n );\n row.append(text, el(\"div\", { class: \"ckw-msgr-tools\" }, clip, el(\"span\", { class: \"ckw-msgr-sp\" }), send));\n row.addEventListener(\"click\", (e) => e.target === row && text.focus());\n form.append(row);\n const picker = el(\"input\", { type: \"file\", accept: CHAT_FILE_TYPES.join(\",\"), multiple: \"\", hidden: \"\", tabindex: \"-1\", \"aria-hidden\": \"true\" });\n form.append(picker);\n const tray = el(\"div\", { class: \"ckw-msgr-files\", role: \"list\", \"aria-label\": t(\"Files to send\") });\n\n interface Picked {\n key: string;\n name: string;\n type: ChatFile[\"type\"];\n size: number;\n /** The picture on this device, shown until the server has it. */\n local: string;\n /** The upload id once the upload finished. */\n id?: string;\n up: Promise<void>;\n ctrl: AbortController;\n }\n let picked: Picked[] = [];\n /** Pictures of the message on its way, by their local key. */\n const localUrls = new Map<string, string>();\n const fileUrl = (id: string) => localUrls.get(id) ?? api().attachmentUrl(id);\n const forget = (p: Picked) => {\n p.ctrl.abort();\n if (![...localUrls.values()].includes(p.local)) URL.revokeObjectURL(p.local);\n };\n const dropFile = (p: Picked) => {\n picked = picked.filter((x) => x !== p);\n forget(p);\n };\n const addFiles = (list: (Blob & { name?: string })[]) => {\n error = \"\";\n for (const f of list) {\n const name = f.name || \"screenshot.png\";\n if (picked.length >= CHAT_FILES_PER_MESSAGE) {\n error = tf(\"Up to {n} files per message.\", { n: CHAT_FILES_PER_MESSAGE });\n break;\n }\n if (!(CHAT_FILE_TYPES as readonly string[]).includes(f.type)) {\n error = t(\"Only pictures (PNG, JPEG, WebP, GIF) and PDFs can be sent.\");\n continue;\n }\n if (f.size > CHAT_FILE_MAX_BYTES) {\n error = tf(\"{name} is larger than 10 MB.\", { name });\n continue;\n }\n const p: Picked = { key: `local-${Date.now().toString(36)}${Math.random().toString(36).slice(2, 7)}`, name, type: f.type as ChatFile[\"type\"], size: f.size, local: URL.createObjectURL(f), up: Promise.resolve(), ctrl: new AbortController() };\n p.up = api()\n .uploadChatFile(f, p.ctrl.signal)\n .then(\n (r) => {\n p.id = r.id;\n draw();\n },\n (e: Error) => {\n if (e.name === \"AbortError\") return;\n dropFile(p);\n error = `${p.name}: ${e.message}`;\n draw();\n },\n );\n picked.push(p);\n }\n if (open && (view !== \"messages\" || listing)) {\n startChat();\n go(\"messages\");\n } else draw();\n text.focus();\n };\n let traySig = \"\";\n const drawTray = () => {\n const sig = picked.map((p) => `${p.key}:${p.id ? 1 : 0}`).join(\",\");\n if (sig !== traySig) {\n traySig = sig;\n tray.replaceChildren(\n ...picked.map((p) => {\n const x = el(\"button\", { type: \"button\", class: \"ckw-msgr-file-x\", \"aria-label\": tf(\"Remove {name}\", { name: p.name }) }, icon(I.cross, 12));\n x.addEventListener(\"click\", () => {\n dropFile(p);\n draw();\n text.focus();\n });\n const face = p.type.startsWith(\"image/\") ? el(\"img\", { src: p.local, alt: \"\" }) : el(\"span\", { class: \"ckw-msgr-file-doc\" }, icon(I.doc, 18), el(\"span\", {}, p.name));\n return el(\"div\", { class: \"ckw-msgr-file\", role: \"listitem\", title: p.name, \"aria-label\": p.id ? p.name : tf(\"{name}, uploading\", { name: p.name }), ...(p.id ? {} : { \"aria-busy\": \"true\" }) }, face, x);\n }),\n );\n }\n if (!picked.length) tray.remove();\n else if (!tray.isConnected) form.insertBefore(tray, row);\n };\n\n /** A picture of this tab: the browser asks once, the messenger hides for the frame, then comes back. */\n const shoot = async () => {\n let stream: MediaStream;\n try {\n stream = await navigator.mediaDevices.getDisplayMedia({ video: { displaySurface: \"browser\" }, audio: false, preferCurrentTab: true, selfBrowserSurface: \"include\" } as DisplayMediaStreamOptions);\n } catch (e) {\n if ((e as Error).name !== \"NotAllowedError\" && (e as Error).name !== \"AbortError\") {\n error = t(\"The screenshot did not work here. Attach a picture instead.\");\n draw();\n }\n return;\n }\n root.style.visibility = \"hidden\";\n let blob: Blob | null = null;\n try {\n const video = document.createElement(\"video\");\n video.muted = true;\n video.playsInline = true;\n video.srcObject = stream;\n await video.play();\n // Frames from before the panel hid may still be on their way: wait for fresh ones.\n await new Promise((r) => setTimeout(r, 300));\n const v = video as HTMLVideoElement & { requestVideoFrameCallback?: (cb: () => void) => number };\n await new Promise<void>((r) => (v.requestVideoFrameCallback ? v.requestVideoFrameCallback(() => r()) : requestAnimationFrame(() => r())));\n const canvas = document.createElement(\"canvas\");\n canvas.width = video.videoWidth;\n canvas.height = video.videoHeight;\n canvas.getContext(\"2d\")?.drawImage(video, 0, 0);\n const encode = (type: string, q?: number) => new Promise<Blob | null>((r) => canvas.toBlob(r, type, q));\n blob = await encode(\"image/png\");\n // A large screen as PNG gets big; a JPEG reads just as well and stays small enough for the AI agent.\n if (blob && blob.size > 4.5 * 1024 * 1024) blob = await encode(\"image/jpeg\", 0.9);\n } catch {\n blob = null;\n } finally {\n for (const t of stream.getTracks()) t.stop();\n root.style.visibility = \"\";\n }\n if (!blob || !blob.size) {\n error = t(\"The screenshot did not work here. Attach a picture instead.\");\n return draw();\n }\n const stamp = new Date().toISOString().slice(0, 16).replace(/[:T]/g, \"-\");\n addFiles([Object.assign(blob, { name: `screenshot-${stamp}.${blob.type === \"image/png\" ? \"png\" : \"jpg\"}` })]);\n };\n\n // The paperclip: the file picker at once, or a small menu with Screenshot where the browser can take one.\n const amenu = el(\"div\", { class: \"ckw-msgr-menu ckw-msgr-amenu\", role: \"menu\" });\n const amenuOpen = () => amenu.isConnected && !amenu.hasAttribute(\"data-out\");\n const closeAmenu = () => {\n clip.setAttribute(\"aria-expanded\", \"false\");\n leave(amenu, 120);\n };\n const amenuItem = (d: string, name: string, act: () => void) => {\n const b = el(\"button\", { type: \"button\", class: \"ckw-msgr-menu-i\", role: \"menuitem\" }, icon(d, 15), el(\"span\", {}, name));\n b.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n closeAmenu();\n act();\n });\n return b;\n };\n clip.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n chime.unlock();\n if (!shots) return picker.click();\n if (amenuOpen()) return closeAmenu();\n amenu.replaceChildren(\n amenuItem(I.image, t(\"Photo or file\"), () => picker.click()),\n amenuItem(I.screen, t(\"Screenshot of this page\"), () => void shoot()),\n );\n clip.setAttribute(\"aria-expanded\", \"true\");\n enter(amenu, form);\n (amenu.querySelector(\"button\") as HTMLButtonElement | null)?.focus();\n });\n picker.addEventListener(\"change\", () => {\n addFiles([...(picker.files ?? [])]);\n picker.value = \"\";\n });\n\n const brand = el(\"a\", { class: \"ckw-msgr-powered\", href: BRAND_URL, target: \"_blank\", rel: \"noopener\" }, t(\"Powered by {brand}\").split(\"{brand}\")[0], el(\"b\", {}, \"MRRocket\"), t(\"Powered by {brand}\").split(\"{brand}\")[1]);\n\n const list = el(\"ol\", { class: \"ckw-msgs\", \"aria-live\": \"polite\", \"aria-label\": t(\"Messages\") });\n const needEmail = () => askEmail && !o.user()?.email && !hasEmail;\n const emailOk = () => !email.value.trim() || EMAIL.test(email.value.trim());\n const canSend = () => (!!text.value.trim() || picked.length > 0) && emailOk();\n\n const go = (v: MessengerView | { article: string }) => {\n const changed = JSON.stringify(v) !== JSON.stringify(view);\n view = v;\n drawn = -1;\n draw();\n if (changed) replay(body, \"ckw-msgr-enter\");\n if (v === \"messages\") {\n markSeen();\n drawFab();\n text.focus();\n } else if (v === \"help\") helpInput.focus();\n schedule(0);\n };\n\n /** A sent picture; once it has its height the chat stays at the bottom, if it was there. */\n const picture = (src: string, alt: string) => {\n const img = el(\"img\", { src, alt, loading: \"lazy\" });\n img.addEventListener(\"load\", () => {\n if (body.scrollHeight - body.scrollTop - body.clientHeight < img.clientHeight + 120) body.scrollTop = body.scrollHeight;\n });\n return img;\n };\n const bubble = (m: ChatMessage, isPending = false) => {\n const slow = isPending && Date.now() - Date.parse(m.at) >= SLOW_SEND_MS;\n const li = el(\"li\", { class: \"ckw-msg\", \"data-from\": m.from === \"visitor\" ? \"me\" : \"them\" }, m.body || !m.attachments?.length ? el(\"div\", { class: \"ckw-bubble\" }, m.body) : null);\n if (isPending) li.setAttribute(\"aria-busy\", \"true\");\n // Sent files: pictures as themselves, a PDF as a chip; each opens full size in a new tab.\n if (m.attachments?.length)\n li.append(\n el(\n \"div\",\n { class: \"ckw-msg-files\" },\n ...m.attachments.map((f) =>\n f.type.startsWith(\"image/\")\n ? el(\"a\", { class: \"ckw-msg-img\", href: fileUrl(f.id), target: \"_blank\", rel: \"noopener\", title: f.name }, picture(fileUrl(f.id), f.name))\n : el(\"a\", { class: \"ckw-msgr-cite\", href: fileUrl(f.id), target: \"_blank\", rel: \"noopener\" }, icon(I.doc, 14), el(\"span\", {}, f.name)),\n ),\n ),\n );\n for (const a of m.articles ?? []) {\n const chip = el(\"button\", { type: \"button\", class: \"ckw-msgr-cite\" }, icon(I.doc, 14), el(\"span\", {}, a.title));\n chip.addEventListener(\"click\", () => go({ article: a.id }));\n li.append(chip);\n }\n li.append(el(\"span\", { class: \"ckw-msg-meta\" }, m.from === \"ai\" ? agentFace() : null, `${m.from !== \"visitor\" ? `${whoLabel[m.from]} · ` : \"\"}${slow ? t(\"Sending…\") : timeAgo(m.at)}`));\n return li;\n };\n\n const articleRow = (a: ArticleSummary) => {\n const b = el(\"button\", { type: \"button\", class: \"ckw-msgr-art\" }, el(\"span\", { class: \"ckw-msgr-art-t\" }, a.title), icon(I.next, 14));\n b.addEventListener(\"click\", () => go({ article: a.id }));\n return b;\n };\n /** A row in Help's lists: a bold name, two lines under it, a count, the arrow. */\n const helpRow = (name: string, sub: string, meta: string, act: () => void) => {\n const b = el(\n \"button\",\n { type: \"button\", class: \"ckw-msgr-hrow\" },\n el(\"span\", { class: \"ckw-msgr-hrow-main\" }, el(\"b\", {}, name), sub ? el(\"span\", { class: \"ckw-msgr-hrow-sub\" }, sub) : null, meta ? el(\"span\", { class: \"ckw-msgr-hrow-meta\" }, meta) : null),\n icon(I.next, 16),\n );\n b.addEventListener(\"click\", act);\n return b;\n };\n\n const searchBox = (placeholder = t(\"Search for help\")) => {\n const wrap = el(\"label\", { class: \"ckw-msgr-search\" });\n const input = el(\"input\", { class: \"ckw-msgr-search-in\", type: \"search\", placeholder, \"aria-label\": t(\"Search for help\"), maxlength: \"200\" });\n input.value = query;\n let wait: ReturnType<typeof setTimeout> | undefined;\n input.addEventListener(\"input\", () => {\n query = input.value;\n clearTimeout(wait);\n wait = setTimeout(() => {\n if (view !== \"help\") return go(\"help\");\n void loadArticles(true);\n }, 250);\n });\n input.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n if (view !== \"help\") go(\"help\");\n }\n });\n wrap.append(icon(I.search, 16), input);\n return wrap;\n };\n // Help's own field stays the same element between draws, so typing never loses the cursor.\n const helpSearch = searchBox(t(\"Search our help center…\"));\n const helpInput = helpSearch.querySelector(\"input\")!;\n\n let loadingArticles = false;\n /** \"Send us a message\" after an article: a question of its own, not an answer in an older chat. */\n const askAnew = () => {\n startChat();\n go(\"messages\");\n };\n const loadArticles = async (force = false) => {\n if (!helpOn || (loadingArticles && !force)) return;\n loadingArticles = true;\n const q = query.trim();\n try {\n const r = await api().articles(q || undefined);\n if (q !== query.trim()) return;\n articles = r.articles;\n if (!q) {\n homeArticles = r.articles;\n hasArticles = r.articles.length > 0;\n rememberProduct();\n }\n } catch {\n articles = articles ?? [];\n } finally {\n loadingArticles = false;\n }\n draw();\n };\n const loadUpdates = async () => {\n try {\n updates = (await api().changelog()).entries.slice(0, UPDATES_SHOWN);\n hasUpdates = updates.length > 0;\n rememberProduct();\n } catch {\n // A server without the changelog, or a bad moment: no tab, and the rest of the messenger goes on.\n updates = [];\n }\n updatesNode = null;\n draw();\n };\n // Home's \"Ask a question\" field: what is typed there starts a new conversation and is sent (it went into the running\n // chat before; owner, 2026-11-04). The same element between draws, so a read that redraws Home never takes the\n // cursor or the words.\n const askForm = el(\"form\", { class: \"ckw-msgr-askq\" });\n const askIn = el(\"input\", { class: \"ckw-msgr-askq-in\", placeholder: t(\"Ask a question\"), \"aria-label\": t(\"Ask a question\"), maxlength: \"4000\", autocomplete: \"off\" });\n const askGo = el(\"button\", { type: \"submit\", class: \"ckw-msgr-send\", \"aria-label\": t(\"Send\"), disabled: \"\" }, icon(I.up));\n askForm.append(askIn, askGo);\n askIn.addEventListener(\"input\", () => (askGo.disabled = !askIn.value.trim()));\n askForm.addEventListener(\"submit\", (e) => {\n e.preventDefault();\n if (!askIn.value.trim()) {\n enterMessages();\n return go(\"messages\");\n }\n text.value = askIn.value;\n askIn.value = \"\";\n askGo.disabled = true;\n startChat();\n go(\"messages\");\n if (canSend()) submit();\n });\n /**\n * Where a read takes a moment: the shape of the rows that are coming, never a grey bar (owner, 2026-11-03: \"der lange\n * Loader ist scheiße\"; 2026-11-05 on Home's). It shows after a beat, so a quick read never flashes it.\n */\n const shapes = (rows: number, card = false) =>\n el(\n \"div\",\n { class: \"ckw-msgr-shapes\", \"aria-hidden\": \"true\" },\n ...Array.from({ length: rows }, () =>\n el(\n \"div\",\n { class: card ? \"ckw-msgr-card ckw-msgr-recent\" : \"ckw-msgr-shape\" },\n el(\"span\", { class: \"ckw-msgr-recent-row\" }, card ? el(\"span\", { class: \"ckw-msgr-av ckw-msgr-av-sm ckw-msgr-sk\" }) : null, el(\"span\", { class: \"ckw-msgr-card-main\" }, el(\"span\", { class: \"ckw-msgr-sk\" }), el(\"span\", { class: \"ckw-msgr-sk\" }))),\n ),\n ),\n );\n /** A redraw leaves shapes already on screen as they are, without the beat again. */\n const still = (node: HTMLElement) => {\n if (node.isConnected) node.setAttribute(\"data-still\", \"\");\n return node;\n };\n const chatShape = shapes(1, true);\n const listShape = shapes(3);\n /** What Home showed in its last draw; what is new since then fades in. Null: the panel just opened and comes in as a whole. */\n let homeSeen: Set<string> | null = null;\n /** One conversation as a card: what it was about, where it stands, a count of new answers. */\n const chatRow = (c: ChatSummary) => {\n const m = c.last;\n const n = unseenIn(c.id);\n const closed = c.status === \"solved\" ? ` · ${t(\"Closed\")}` : \"\";\n const row = el(\n \"button\",\n { type: \"button\", class: \"ckw-msgr-card ckw-msgr-recent\", \"aria-label\": `${tf(\"Conversation: {subject}\", { subject: c.subject })}${closed}${n ? `, ${tf(\"{n} new\", { n })}` : \"\"}` },\n el(\n \"span\",\n { class: \"ckw-msgr-recent-row\" },\n avatar(\"sm\"),\n el(\n \"span\",\n { class: \"ckw-msgr-card-main\" },\n el(\"span\", { class: \"ckw-msgr-card-sub ckw-msgr-recent-text\" }, c.subject),\n m && lineOf(m) !== c.subject ? el(\"span\", { class: \"ckw-msgr-card-sub\" }, lineOf(m)) : null,\n m ? el(\"span\", { class: \"ckw-msgr-card-meta\" }, `${whoLabel[m.from]} · ${timeAgo(m.at)}${closed}`) : null,\n ),\n n ? el(\"span\", { class: \"ckw-msgr-badge\" }, String(n)) : icon(I.next, 14),\n ),\n );\n row.addEventListener(\"click\", () => {\n enterChat(c.id, null);\n go(\"messages\");\n });\n return row;\n };\n const chatsBox = el(\"div\", { class: \"ckw-msgr-chats\" });\n const newChat = el(\"button\", { type: \"button\", class: \"ckw-btn ckw-btn-primary ckw-msgr-new\" }, icon(I.chat), t(\"New conversation\"));\n newChat.addEventListener(\"click\", askAnew);\n let chatsSig = \"\";\n const drawChats = () => {\n // Redrawn only when something shows differently, so a read never takes the keyboard's place in the list.\n const sig = `${chats.map((c) => `${c.id}:${c.status}:${c.last?.id}:${unseenIn(c.id)}`).join()}|${Math.floor(Date.now() / 60_000)}`;\n if (sig !== chatsSig) {\n chatsSig = sig;\n chatsBox.replaceChildren(...chats.map(chatRow));\n }\n if (body.childNodes[0] !== chatsBox) body.replaceChildren(chatsBox, newChat);\n };\n\n const drawHome = () => {\n // Two lines like Featurebase: \"Hi, Lukas 👋\" and the greeting in gray (without its own \"Hi!\", said above).\n const first = o.user()?.name?.trim().split(/\\s+/)[0];\n const rest = (o.greeting ? greeting.replace(/^(hi|hello|hey|hallo|moin|servus|bonjour|salut|hola|ciao|salve|hoi|ol[áa]|cze[śs][ćc]|hej|こんにちは)( there)?\\s*[!,.!、。]*\\s*/i, \"\").trim() : t(\"How can we help?\")) || t(\"How can we help you today?\");\n const hero = el(\n \"h2\",\n { class: \"ckw-msgr-hero ckw-msgr-hello\" },\n el(\"span\", {}, `${first ? tf(\"Hi, {name}\", { name: first }) : t(\"Hi there\")} `, el(\"span\", { class: \"ckw-msgr-wave\", \"aria-hidden\": \"true\" }, \"👋\")),\n el(\"span\", { class: \"ckw-msgr-hello-sub\" }, rest),\n );\n const parts: HTMLElement[] = [hero, askForm];\n const shown = new Set<string>();\n const arriving = (node: HTMLElement, key: string) => {\n shown.add(key);\n if (homeSeen && !homeSeen.has(key)) node.setAttribute(\"data-arrive\", \"\");\n return node;\n };\n // The conversations still open (a closed one only while there is nothing else); the rest behind \"All\".\n const running = chats.filter((c) => c.status !== \"solved\");\n const rows = (running.length ? running : chats).slice(0, 2);\n parts.push(...rows.map((c) => arriving(chatRow(c), c.id)));\n // Someone signed in may well have conversations, and this browser kept none: until the first read says.\n if (!rows.length && !loaded && misses < 3 && o.user()?.id) parts.push(still(chatShape));\n if (chats.length > rows.length) {\n const all = el(\"button\", { type: \"button\", class: \"ckw-msgr-all\" }, tf(\"All conversations ({n})\", { n: chats.length }), icon(I.next, 14));\n all.addEventListener(\"click\", () => {\n enterMessages();\n go(\"messages\");\n });\n parts.push(all);\n }\n // A few articles to tap; searching is the Help tab's, so Home fits without scrolling.\n const top = helpOn ? homeArticles.slice(0, 3) : [];\n if (top.length) parts.push(arriving(el(\"div\", { class: \"ckw-msgr-card ckw-msgr-card-col\" }, ...top.map(articleRow)), \"help\"));\n homeSeen = shown;\n body.replaceChildren(...parts);\n };\n\n const drawHelp = () => {\n if (helpInput.value !== query) helpInput.value = query;\n const q = query.trim();\n const all = articles ?? [];\n const groups = new Map<string, ArticleSummary[]>();\n for (const a of all) groups.set(a.collection, [...(groups.get(a.collection) ?? []), a]);\n const inside = !q && collection !== null ? (groups.get(collection) ?? []) : null;\n const heading = q ? t(\"Search results\") : inside ? (collection ?? \"\") : t(\"Most read articles\");\n const parts: HTMLElement[] = [el(\"h2\", { class: \"ckw-msgr-help-h\" }, heading), helpSearch];\n if (articles === null) parts.push(still(listShape));\n else if (!all.length) {\n const ask = el(\"button\", { type: \"button\", class: \"ckw-btn ckw-btn-primary\" }, t(\"Send us a message\"));\n ask.addEventListener(\"click\", askAnew);\n parts.push(el(\"div\", { class: \"ckw-msgr-empty\" }, el(\"p\", {}, q ? tf(\"Nothing found for “{q}”.\", { q }) : t(\"No help articles yet.\")), ask));\n } else if (q || inside)\n parts.push(\n el(\n \"div\",\n { class: \"ckw-msgr-hlist\" },\n // The excerpt often opens with the article's own heading; the row shows the title already.\n ...(inside ?? all).map((a) => helpRow(a.title, a.excerpt.startsWith(a.title) ? a.excerpt.slice(a.title.length).trim() : a.excerpt, q ? a.collection : \"\", () => go({ article: a.id }))),\n ),\n );\n else\n parts.push(\n el(\n \"div\",\n { class: \"ckw-msgr-hlist\" },\n ...[...groups].map(([name, items]) =>\n helpRow(name, items.map((a) => a.title).join(\", \"), items.length === 1 ? t(\"1 article\") : tf(\"{n} articles\", { n: items.length }), () => {\n collection = name;\n go(\"help\");\n replay(body, \"ckw-msgr-enter\");\n }),\n ),\n ),\n );\n // The field stays in place (moving it would take its focus); only what is around it changes.\n if (body.childNodes[1] !== helpSearch) body.replaceChildren(...parts);\n else {\n (body.firstChild as HTMLElement).replaceWith(parts[0]);\n while (body.childNodes.length > 2) body.lastChild!.remove();\n body.append(...parts.slice(2));\n }\n };\n\n // The owner's changelog, newest first, to read in place (owner, 2026-11-04: \"changelog auch im Messenger als Tab\").\n const drawUpdates = () => {\n updatesNode ??= !updates\n ? shapes(3)\n : !updates.length\n ? el(\"div\", { class: \"ckw-msgr-empty\" }, el(\"p\", {}, t(\"No updates yet.\")))\n : el(\n \"div\",\n { class: \"ckw-msgr-updates\" },\n ...updates.map((e) => el(\"article\", { class: \"ckw-msgr-update\" }, el(\"p\", { class: \"ckw-msgr-doc-c\" }, timeAgo(e.publishedAt)), el(\"h2\", { class: \"ckw-msgr-update-t\" }, e.title), e.body ? el(\"p\", { class: \"ckw-msgr-update-b\" }, e.body) : null)),\n );\n if (body.firstChild !== updatesNode || body.childNodes.length !== 1) body.replaceChildren(updatesNode);\n };\n\n let articleShown: { id: string; node: HTMLElement } | null = null;\n const drawArticle = (id: string) => {\n if (articleShown?.id === id) return body.replaceChildren(articleShown.node);\n const node = el(\"article\", { class: \"ckw-msgr-doc\" }, shapes(4));\n articleShown = { id, node };\n body.replaceChildren(node);\n api()\n .article(id)\n .then((a) => {\n const foot = el(\"div\", { class: \"ckw-msgr-rate\" });\n const drawRate = () => {\n if (rated.has(id)) return foot.replaceChildren(el(\"span\", {}, t(\"Thanks for letting us know.\")));\n const yes = el(\"button\", { type: \"button\", class: \"ckw-btn\" }, t(\"Yes\"));\n const no = el(\"button\", { type: \"button\", class: \"ckw-btn\" }, t(\"No\"));\n const rate = (helpful: boolean) => {\n rated = new Set(rated).add(id);\n drawRate();\n api()\n .rateArticle(id, helpful)\n .catch(() => undefined);\n if (!helpful) askAnew();\n };\n yes.addEventListener(\"click\", () => rate(true));\n no.addEventListener(\"click\", () => rate(false));\n foot.replaceChildren(el(\"span\", {}, t(\"Did this answer your question?\")), el(\"span\", { class: \"ckw-msgr-rate-b\" }, yes, no));\n };\n drawRate();\n const ask = el(\"button\", { type: \"button\", class: \"ckw-btn ckw-msgr-ask\" }, icon(I.chat), t(\"Still need help? Send us a message\"));\n ask.addEventListener(\"click\", askAnew);\n node.replaceChildren(\n el(\"p\", { class: \"ckw-msgr-doc-c\" }, a.collection),\n el(\"h2\", { class: \"ckw-msgr-doc-t\" }, a.title),\n el(\"p\", { class: \"ckw-msgr-doc-c\" }, tf(\"Updated {when}\", { when: timeAgo(a.updatedAt) })),\n el(\"div\", { class: \"ckw-msgr-doc-b\" }, ...a.blocks.map(blockOf)),\n foot,\n ask,\n );\n })\n .catch((e: Error) => {\n articleShown = null;\n node.replaceChildren(el(\"p\", { class: \"ckw-msgr-error\" }, e.message));\n });\n };\n\n let drawn = -1;\n /** What the list shows, so a read that brings nothing new leaves it alone (no flicker, links stay where they are). */\n let listSig = \"\";\n /** How many bubbles the list had: the ones after it are new and glide in. */\n let listCount = -1;\n const suggestions = el(\"div\", { class: \"ckw-msgr-sugg\" });\n /** What is on its way into the conversation on screen. */\n const outboxHere = () => outbox.filter((x) => x.draft === draft && x.chat === chatId);\n const drawMessages = () => {\n const current = draft === null ? thread : null;\n const msgs = current?.messages ?? [];\n const here = outboxHere();\n const parts: HTMLElement[] = [];\n // No grey placeholder while the chat is read (owner, 2026-11-03: \"der lange Loader ist scheiße\"): the greeting\n // and the field are there at once, and the visitor's earlier messages take the greeting's place when they come.\n {\n const waiting = here.map((o) => o.message);\n const sig = `${msgs.map((m) => m.id).join(\",\")}|${waiting.map((m) => `${m.id}:${Date.now() - Date.parse(m.at) >= SLOW_SEND_MS}`).join(\",\")}|${Math.floor(Date.now() / 60_000)}`;\n if (sig !== listSig) {\n listSig = sig;\n // The greeting opens an empty chat only: once the visitor wrote (from Home's \"Ask a question\" too) the chat\n // starts with their words, never with a greeting above them (2026-10-30).\n const greet = msgs.length || waiting.length || chatId ? [] : [el(\"li\", { class: \"ckw-msg\", \"data-from\": \"them\" }, el(\"div\", { class: \"ckw-bubble\" }, greeting))];\n const items = [...greet, ...msgs.map((m) => bubble(m)), ...waiting.map((m) => bubble(m, true))];\n if (listCount >= 0) items.slice(listCount).forEach((li) => li.setAttribute(\"data-new\", \"\"));\n listCount = items.length;\n list.replaceChildren(...items);\n }\n parts.push(list);\n // Before the visitor wrote: the most read articles as answers to tap.\n const top = !msgs.some((m) => m.from === \"visitor\") && !here.length && !chatId ? (articles ?? []).slice(0, 3) : [];\n if (top.length) {\n if (suggestions.childNodes.length !== top.length)\n suggestions.replaceChildren(\n ...top.map((a) => {\n const b = el(\"button\", { type: \"button\", class: \"ckw-msgr-sugg-b\" }, a.title);\n b.addEventListener(\"click\", () => go({ article: a.id }));\n return b;\n }),\n );\n parts.push(suggestions);\n }\n }\n if (current?.conversation?.status === \"solved\" && !here.length) parts.push(el(\"p\", { class: \"ckw-fine ckw-msgr-note\" }, t(\"This conversation is closed. Write to start a new one.\")));\n if (body.childNodes.length !== parts.length || parts.some((x, i) => body.childNodes[i] !== x)) body.replaceChildren(...parts);\n const count = msgs.length + here.length;\n if (count !== drawn) {\n drawn = count;\n body.scrollTop = body.scrollHeight;\n }\n err.textContent = error;\n if (error && !err.isConnected) form.prepend(err);\n else if (!error) err.remove();\n if (needEmail()) {\n if (emailOk()) email.removeAttribute(\"aria-invalid\");\n else email.setAttribute(\"aria-invalid\", \"true\");\n if (!email.isConnected) row.insertBefore(email, text);\n } else email.remove();\n drawTray();\n send.disabled = !canSend();\n };\n\n const draw = () => {\n if (!open) return;\n pop.dataset.view = typeof view === \"string\" ? view : \"article\";\n drawBar();\n if (view === \"home\") drawHome();\n else if (view === \"messages\") (listing ? drawChats : drawMessages)();\n else if (view === \"help\") drawHelp();\n else if (view === \"updates\") drawUpdates();\n else drawArticle(view.article);\n const kids: HTMLElement[] = view === \"home\" ? [sky, bar, body] : [bar, body];\n kids.push(view === \"messages\" && !listing ? form : tabs);\n if (o.branding !== false) kids.push(brand);\n if (menu.isConnected) kids.push(menu);\n if (pop.childNodes.length !== kids.length || kids.some((k, i) => pop.childNodes[i] !== k)) pop.replaceChildren(...kids);\n };\n\n // ---------- Reading the chat ----------\n const tick = async () => {\n // A read on its way is the newest one: opening the panel again waits for it instead of starting over (a slow\n // first read was cut off by every open and the chat never came).\n if (ctrl) return;\n const mine = (ctrl = new AbortController());\n const asked = o.distinctId();\n let late = false;\n const patience = setTimeout(() => {\n late = true;\n mine.abort();\n }, Math.min(READ_PATIENCE_MS * 2 ** misses, POLL_IDLE_MS));\n // A read that did not get through is asked again soon instead of at the next slow turn (on Home 30 s of empty\n // panel, 2026-11-05): at once after a read that took too long, a little later each time after an error.\n let again: number | undefined;\n try {\n take(await api().chat(mine.signal, chatId ?? undefined));\n error = \"\";\n refused = false;\n misses = 0;\n rememberChats(asked);\n } catch (e) {\n if ((e as Error).name === \"AbortError\" && !late) return;\n const status = (e as { status?: number }).status;\n refused = status === 401 || status === 403;\n // A chat that is gone (the team archived it): back to what is left.\n if (status === 404 && chatId) enterMessages();\n else if (open && view === \"messages\" && !late) error = sayable(e);\n if (late || status === undefined || status >= 500) {\n misses += 1;\n again = late ? 0 : Math.min(1000 * 2 ** (misses - 1), POLL_IDLE_MS);\n }\n } finally {\n clearTimeout(patience);\n if (ctrl === mine) ctrl = null;\n }\n // The first answer's messages are already there, not new: they do not glide in.\n if (!loaded && again === undefined) {\n listCount = -1;\n // Messages opened before the first read knew of several conversations, and nothing was typed yet.\n if (view === \"messages\" && chatId === null && draft === null && !text.value.trim() && !outbox.length && !picked.length) enterMessages();\n loaded = true;\n }\n draw();\n drawFab();\n schedule(open && document.visibilityState !== \"hidden\" ? again : undefined);\n };\n /** The visitor changed, or a refused one got their signature: what is on screen goes, and the read does not wait for the next turn. */\n const refresh = () => {\n const who = o.distinctId();\n if (who === visitor && !refused) return;\n if (who !== visitor) {\n // Signed out: nothing of theirs stays in this browser.\n if (person && !o.user()?.id && remembers) keep(chatsKey, null);\n visitor = who;\n ctrl?.abort();\n ctrl = null;\n unseen = [];\n loaded = false;\n misses = 0;\n recall();\n }\n person = o.user()?.id;\n draw();\n drawFab();\n schedule(0);\n };\n /** The next read: often while the chat is on screen, now and then while the visitor waits for an answer, slowly else; never for a hidden page. */\n function schedule(now?: number) {\n clearTimeout(poll);\n const running = chats.filter((c) => c.status !== \"solved\");\n const waiting = running.length > 0;\n const recent = running.some((c) => c.last && Date.now() - new Date(c.last.at).getTime() < WAITING_FOR_MS);\n const quiet = now === undefined && !open && !waiting;\n const ms = now ?? (document.visibilityState === \"hidden\" ? 0 : watching() ? POLL_OPEN_MS : waiting && recent ? POLL_WAITING_MS : quiet ? POLL_QUIET_MS : POLL_IDLE_MS);\n // A slow turn without anyone to reach reads nothing; whoever signs in later is read from the next one on.\n if (ms || now === 0) poll = setTimeout(() => (quiet && (refused || !(o.user()?.id || chats.length)) ? schedule() : void tick()), ms);\n }\n const onVisible = () => {\n if (document.visibilityState === \"visible\") schedule(0);\n else clearTimeout(poll);\n };\n document.addEventListener(\"visibilitychange\", onVisible);\n\n /** Sends the outbox in order; what fails comes back into the field with what was queued after it. */\n const flush = async () => {\n if (flushing) return;\n flushing = true;\n while (outbox.length) {\n const item = outbox[0];\n const { message, files, email: given } = item;\n // Send waits for the uploads; one that failed is left out and said in the error line.\n await Promise.all(files.map((p) => p.up));\n const ids = files.filter((p) => p.id).map((p) => p.id!);\n try {\n if (!message.body && !ids.length) throw new Error(error || t(\"The file could not be sent.\"));\n const sent = await api().sendChat({\n body: message.body,\n ...(item.draft !== null ? { conversation: \"new\" } : item.chat ? { conversation: item.chat } : {}),\n email: given,\n url: window.location.href.slice(0, 500),\n ...(ids.length ? { attachments: ids } : {}),\n // A little context for a bug report; the server reads browser and system from the user agent.\n context: { viewport: `${window.innerWidth}×${window.innerHeight}` },\n });\n // A read that left before this send would bring the chat without it.\n ctrl?.abort();\n ctrl = null;\n // Where it went (a new conversation, or a new one after a closed chat) is where what follows it goes.\n const went = sent.conversation?.id ?? null;\n if (went) {\n const after = outbox.slice(1).filter((x) => x.draft === item.draft && x.chat === item.chat);\n if (item.draft === draft && item.chat === chatId) {\n draft = null;\n chatId = went;\n }\n for (const x of after) {\n x.draft = null;\n x.chat = went;\n }\n }\n take(sent);\n outbox.shift();\n for (const p of files) {\n localUrls.delete(p.key);\n URL.revokeObjectURL(p.local);\n }\n } catch (e) {\n // Nothing typed is lost: the unsent words go back into the field (before anything typed since), their\n // uploaded files back into the tray.\n const back = outbox.splice(0);\n // Back into the chat they were written for; a chat that is gone leaves them for a new one.\n const gone = (e as { status?: number }).status === 404;\n enterChat(gone ? null : back[0].chat, gone ? ++drafts : back[0].draft);\n text.value = [...back.map((b) => b.message.body), text.value.trim()].filter(Boolean).join(\"\\n\");\n picked = [...back.flatMap((b) => b.files.filter((p) => p.id)), ...picked];\n for (const b of back) for (const p of b.files) localUrls.delete(p.key);\n error = gone ? t(\"This conversation is no longer available. Your message is still here to send as a new one.\") : sayable(e);\n }\n draw();\n }\n flushing = false;\n schedule();\n };\n\n const submit = () => {\n const msg = text.value.trim();\n const files = picked;\n if ((!msg && !files.length) || !emailOk()) return;\n chime.unlock();\n for (const p of files) localUrls.set(p.key, p.local);\n outbox.push({\n message: {\n id: `pending-${++outboxSeq}`,\n from: \"visitor\",\n body: msg,\n at: new Date().toISOString(),\n ...(files.length ? { attachments: files.map((p) => ({ id: p.key, name: p.name, type: p.type, size: p.size })) } : {}),\n },\n files,\n email: needEmail() && email.value.trim() ? email.value.trim() : undefined,\n chat: chatId,\n draft,\n });\n text.value = \"\";\n picked = [];\n error = \"\";\n draw();\n // A slow answer turns \"just now\" into \"Sending…\".\n setTimeout(draw, SLOW_SEND_MS + 50);\n void flush();\n };\n form.addEventListener(\"submit\", (e) => {\n e.preventDefault();\n submit();\n });\n text.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\" && !e.shiftKey && !e.isComposing) {\n e.preventDefault();\n submit();\n }\n });\n text.addEventListener(\"input\", () => (send.disabled = !canSend()));\n // A picture on the clipboard (a screenshot) attaches when pasted into the field.\n text.addEventListener(\"paste\", (e) => {\n const fs = [...(e.clipboardData?.files ?? [])];\n if (!fs.length) return;\n e.preventDefault();\n addFiles(fs);\n });\n // Files dropped anywhere on the panel attach (and open the chat).\n const hasFiles = (e: DragEvent) => !!e.dataTransfer && [...e.dataTransfer.types].includes(\"Files\");\n pop.addEventListener(\"dragover\", (e) => {\n if (!hasFiles(e)) return;\n e.preventDefault();\n pop.setAttribute(\"data-drop\", \"\");\n });\n pop.addEventListener(\"dragleave\", (e) => {\n if (!e.relatedTarget || !pop.contains(e.relatedTarget as Node)) pop.removeAttribute(\"data-drop\");\n });\n pop.addEventListener(\"drop\", (e) => {\n if (!hasFiles(e)) return;\n e.preventDefault();\n pop.removeAttribute(\"data-drop\");\n addFiles([...(e.dataTransfer?.files ?? [])]);\n });\n email.addEventListener(\"input\", () => draw());\n\n function show(v: MessengerView | { article: string } = \"home\", still = false) {\n const was = open;\n open = true;\n view = (v === \"help\" && !helpOn) || (v === \"updates\" && !updatesOn) ? \"home\" : v;\n drawn = -1;\n previewGone = true;\n homeSeen = null;\n pop.toggleAttribute(\"data-still\", still);\n enter(pop);\n if (was) replay(body, \"ckw-msgr-enter\");\n if (articles === null || hasArticles === null || (view === \"help\" && query)) void loadArticles();\n draw();\n drawFab();\n if (view === \"messages\") {\n markSeen();\n text.focus();\n }\n schedule(0);\n }\n function close() {\n if (!open) return;\n open = false;\n if (menu.isConnected) closeMenu();\n leave(pop, 200);\n drawFab();\n schedule();\n if (launcherOn) fab.focus();\n // After the panel's leave, so a look waiting for the close does not cut it off.\n const fn = afterClose;\n afterClose = null;\n if (fn) setTimeout(fn, 220);\n }\n pop.addEventListener(\"click\", () => amenuOpen() && closeAmenu());\n const onKey = (e: KeyboardEvent) => {\n if (e.key !== \"Escape\" || !open) return;\n if (amenuOpen()) {\n closeAmenu();\n clip.focus();\n } else if (menuOpen()) {\n closeMenu();\n menuBtn.focus();\n } else close();\n };\n document.addEventListener(\"keydown\", onKey);\n\n // One read on load (the count and preview of answers not seen yet), and the article count for the Help tab.\n void tick();\n if (helpOn) void loadArticles();\n if (updatesOn) void loadUpdates();\n drawFab();\n if (o.opened) show(o.opened, true);\n\n return {\n open: (v) => {\n if (v === \"messages\") enterMessages();\n show(v ?? \"home\");\n },\n close,\n toggle: () => (open ? close() : show()),\n refresh,\n isOpen: () => open,\n onClose: (fn) => {\n afterClose = fn;\n },\n destroy: () => {\n clearTimeout(poll);\n for (const t of leaving.values()) clearTimeout(t);\n ctrl?.abort();\n for (const p of picked) forget(p);\n for (const u of localUrls.values()) URL.revokeObjectURL(u);\n document.removeEventListener(\"keydown\", onKey);\n document.removeEventListener(\"visibilitychange\", onVisible);\n root.remove();\n },\n };\n};\n"],"mappings":";AAgBA;AAAA,EAKI;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAQA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEG;AACP,SAAS,eAAe,SAAS,GAAG,IAAI,WAAW,oBAAoB;AACvE,SAAS,oBAAoB;AA8E7B,IAAM,gBAAgB;AACtB,IAAM,eAAe;AAKrB,IAAM,mBAAmB;AAEzB,IAAM,kBAAkB;AACxB,IAAM,eAAe;AAKrB,IAAM,gBAAgB;AACtB,IAAM,iBAAiB,KAAK;AAE5B,IAAM,eAAe;AACrB,IAAM,QAAQ;AAEd,IAAM,WAAW;AAEjB,IAAM,iBAAiB;AAEvB,IAAM,WAAW,MAAsD;AACnE,MAAI;AACA,WAAO,EAAE,KAAK,OAAO,aAAa,QAAQ,QAAQ,KAAK,IAAI,OAAO,KAAK,MAAM,OAAO,aAAa,QAAQ,cAAc,KAAK,IAAI,EAA4B;AAAA,EAChK,QAAQ;AACJ,WAAO,EAAE,KAAK,IAAI,OAAO,CAAC,EAAE;AAAA,EAChC;AACJ;AACA,IAAM,YAAY,CAAC,UAAkC;AACjD,MAAI;AACA,WAAO,aAAa,QAAQ,gBAAgB,KAAK,UAAU,KAAK,CAAC;AAAA,EACrE,QAAQ;AAAA,EAER;AACJ;AAEA,IAAM,UAAU,CAAC,QAAgB;AAC7B,QAAM,KAAK,IAAI,KAAK,GAAG,EAAE,QAAQ;AACjC,MAAI,OAAO,MAAM,EAAE,EAAG,QAAO;AAC7B,QAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,EAAE,IAAI;AACzC,MAAI,IAAI,GAAI,QAAO,EAAE,UAAU;AAC/B,MAAI,IAAI,KAAM,QAAO,GAAG,YAAY,EAAE,GAAG,KAAK,MAAM,IAAI,EAAE,EAAE,CAAC;AAC7D,MAAI,IAAI,MAAO,QAAO,GAAG,YAAY,EAAE,GAAG,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC;AAChE,MAAI,IAAI,QAAQ,GAAI,QAAO,GAAG,YAAY,EAAE,GAAG,KAAK,MAAM,IAAI,KAAK,EAAE,CAAC;AACtE,SAAO,IAAI,KAAK,GAAG,EAAE,mBAAmB,cAAc,GAAG,EAAE,OAAO,SAAS,KAAK,WAAW,MAAM,UAAU,CAAC;AAChH;AAEA,IAAM,KAAK,CAAwC,KAAQ,QAAgC,CAAC,MAAM,SAAuD;AACrJ,QAAM,IAAI,SAAS,cAAc,GAAG;AACpC,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,KAAK,EAAG,GAAE,aAAa,GAAG,CAAC;AAC/D,aAAW,KAAK,KAAM,KAAI,MAAM,QAAQ,MAAM,SAAS,MAAM,OAAW,GAAE,OAAO,CAAC;AAClF,SAAO;AACX;AAEA,IAAM,SAAS;AAEf,IAAM,OAAO,CAAC,GAAW,OAAO,OAAO;AACnC,QAAM,MAAM,SAAS,gBAAgB,QAAQ,KAAK;AAClD,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,EAAE,OAAO,YAAY,OAAO,OAAO,IAAI,GAAG,QAAQ,OAAO,IAAI,GAAG,SAAS,aAAa,MAAM,QAAQ,QAAQ,gBAAgB,gBAAgB,QAAQ,kBAAkB,SAAS,mBAAmB,SAAS,eAAe,OAAO,CAAC;AAClQ,QAAI,aAAa,GAAG,CAAC;AACzB,QAAM,OAAO,SAAS,gBAAgB,QAAQ,MAAM;AACpD,OAAK,aAAa,KAAK,CAAC;AACxB,MAAI,YAAY,IAAI;AACpB,SAAO;AACX;AACA,IAAM,IAAI;AAAA,EACN,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,SAAS;AAAA,EACT,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AACZ;AAGA,IAAM,SAAS,CAAC,MAAmB,EAAE,SAAS,EAAE,aAAa,WAAW,IAAI,GAAG,eAAe,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,KAAK,CAAC,IAAI,EAAE,aAAa,SAAS,GAAG,kBAAkB,EAAE,GAAG,EAAE,YAAY,OAAO,CAAC,IAAI;AAG7M,IAAM,WAAW,MAAM,OAAO,cAAc,eAAe,OAAO,UAAU,cAAc,oBAAoB;AAE9G,IAAM,SAAS;AACf,IAAM,SAAS,CAAC,GAAW,SAAiB;AACxC,QAAM,MAAM,SAAS,gBAAgB,QAAQ,KAAK;AAClD,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,EAAE,OAAO,YAAY,OAAO,OAAO,IAAI,GAAG,QAAQ,OAAO,IAAI,GAAG,SAAS,aAAa,MAAM,gBAAgB,QAAQ,gBAAgB,gBAAgB,OAAO,mBAAmB,SAAS,eAAe,OAAO,CAAC;AAC9O,QAAI,aAAa,GAAG,CAAC;AACzB,QAAM,OAAO,SAAS,gBAAgB,QAAQ,MAAM;AACpD,OAAK,aAAa,KAAK,CAAC;AACxB,MAAI,YAAY,IAAI;AACpB,SAAO;AACX;AAGA,IAAM,MAAM,CAAC,OAAe,KAAa,MAAc,QAAQ,MAAM;AACjE,QAAM,MAAM,OAAO,OAAO,IAAI;AAC9B,QAAM,OAAO,SAAS,gBAAgB,QAAQ,MAAM;AACpD,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,EAAE,GAAG,KAAK,OAAO,WAAW,MAAM,QAAQ,gBAAgB,OAAO,KAAK,GAAG,kBAAkB,SAAS,mBAAmB,QAAQ,CAAC,EAAG,MAAK,aAAa,GAAG,CAAC;AAC7L,MAAI,YAAY,IAAI;AACpB,SAAO;AACX;AACA,IAAM,OAAO;AACb,IAAM,QAAQ;AACd,IAAM,QAAQ;AACd,IAAM,OAAO;AACb,IAAM,QAAQ;AACd,IAAM,YAAY;AAGlB,IAAM,QAAS,uBAAM;AACjB,MAAI,MAA2B;AAC/B,QAAM,MAAM,MAAM;AACd,UAAM,KAAK,OAAO,gBAAiB,OAAmE;AACtG,QAAI,CAAC,GAAI,QAAO;AAChB,YAAQ,IAAI,GAAG;AACf,WAAO;AAAA,EACX;AACA,SAAO;AAAA;AAAA,IAEH,QAAQ,MAAM;AACV,UAAI;AACA,cAAM,IAAI,IAAI;AACd,YAAI,GAAG,UAAU,YAAa,MAAK,EAAE,OAAO;AAAA,MAChD,QAAQ;AAAA,MAER;AAAA,IACJ;AAAA,IACA,MAAM,MAAM;AACR,UAAI;AACA,cAAM,IAAI,IAAI;AACd,YAAI,CAAC,KAAK,EAAE,UAAU,UAAW;AACjC,cAAMA,KAAI,EAAE;AACZ,SAAC,KAAK,MAAM,EAAE,QAAQ,CAAC,GAAG,MAAM;AAC5B,gBAAM,IAAI,EAAE,iBAAiB;AAC7B,gBAAM,IAAI,EAAE,WAAW;AACvB,gBAAM,KAAKA,KAAI,IAAI;AACnB,YAAE,OAAO;AACT,YAAE,UAAU,QAAQ;AACpB,YAAE,KAAK,eAAe,MAAQ,EAAE;AAChC,YAAE,KAAK,6BAA6B,MAAM,KAAK,KAAK;AACpD,YAAE,KAAK,6BAA6B,MAAQ,KAAK,IAAI;AACrD,YAAE,QAAQ,CAAC;AACX,YAAE,QAAQ,EAAE,WAAW;AACvB,YAAE,MAAM,EAAE;AACV,YAAE,KAAK,KAAK,IAAI;AAAA,QACpB,CAAC;AAAA,MACL,QAAQ;AAAA,MAER;AAAA,IACJ;AAAA,EACJ;AACJ,GAAG;AAEH,IAAM,UAAU,CAAC,UACb,MAAM,IAAI,CAAC,MAAM;AACb,MAAI,OAAoB,EAAE,OAAO,GAAG,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,UAAU,KAAK,sBAAsB,GAAG,EAAE,IAAI,IAAI,GAAG,QAAQ,CAAC,GAAG,EAAE,IAAI;AACxI,MAAI,EAAE,KAAM,QAAO,GAAG,QAAQ,CAAC,GAAG,IAAI;AACtC,MAAI,EAAE,OAAQ,QAAO,GAAG,MAAM,CAAC,GAAG,IAAI;AACtC,MAAI,EAAE,KAAM,QAAO,GAAG,UAAU,CAAC,GAAG,IAAI;AACxC,SAAO;AACX,CAAC;AAEL,IAAM,UAAU,CAAC,MAAiC;AAC9C,UAAQ,EAAE,MAAM;AAAA,IACZ,KAAK;AAAA,IACL,KAAK;AACD,aAAO,GAAG,EAAE,MAAM,CAAC,GAAG,GAAG,QAAQ,EAAE,KAAK,CAAC;AAAA,IAC7C,KAAK;AACD,aAAO,GAAG,cAAc,CAAC,GAAG,GAAG,QAAQ,EAAE,KAAK,CAAC;AAAA,IACnD,KAAK;AAAA,IACL,KAAK;AACD,aAAO,GAAG,EAAE,MAAM,CAAC,GAAG,GAAG,EAAE,MAAM,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,GAAG,GAAG,QAAQ,EAAE,CAAC,CAAC,CAAC;AAAA,IAC9E,KAAK;AACD,aAAO,GAAG,OAAO,CAAC,GAAG,GAAG,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC;AAAA,IAC/C,KAAK;AACD,aAAO,GAAG,IAAI;AAAA,IAClB;AACI,aAAO,GAAG,KAAK,CAAC,GAAG,GAAG,QAAQ,EAAE,KAAK,CAAC;AAAA,EAC9C;AACJ;AAGA,IAAM,eAAe;AACrB,IAAM,WAAW;AAGjB,IAAM,iBAAiB,CAAC,WAAkD;AACtE,MAAI;AACA,UAAM,MAAM,OAAO,aAAa,QAAQ,WAAW,MAAM;AACzD,WAAO,MAAO,KAAK,MAAM,GAAG,IAA+B;AAAA,EAC/D,QAAQ;AACJ,WAAO;AAAA,EACX;AACJ;AACA,IAAM,kBAAkB,CAAC,QAAgB,SAAiC;AACtE,MAAI;AACA,WAAO,aAAa,QAAQ,WAAW,QAAQ,KAAK,UAAU,IAAI,CAAC;AAAA,EACvE,QAAQ;AAAA,EAER;AACJ;AAOA,IAAM,YAAY;AAClB,IAAM,cAAc;AACpB,IAAM,OAAO;AACb,IAAM,OAAO,CAAI,QAAmC;AAChD,MAAI;AACA,WAAO,KAAK,MAAM,OAAO,aAAa,QAAQ,GAAG,KAAK,MAAM;AAAA,EAChE,QAAQ;AACJ,WAAO;AAAA,EACX;AACJ;AACA,IAAM,OAAO,CAAC,KAAa,UAAmB;AAC1C,MAAI;AACA,QAAI,MAAO,QAAO,aAAa,QAAQ,KAAK,KAAK,UAAU,KAAK,CAAC;AAAA,QAC5D,QAAO,aAAa,WAAW,GAAG;AAAA,EAC3C,QAAQ;AAAA,EAER;AACJ;AASO,IAAM,iBAAiB,CAAC,MAA2C;AACtE,MAAI,OAA8B;AAClC,MAAI,QAAQ;AACZ,MAAI,OAAO;AACX,QAAM,SAA2C,CAAC;AAClD,QAAM,QAAQ,CAAC,OAAsC,OAAO,GAAG,IAAI,IAAI,OAAO,KAAK,EAAE;AACrF,QAAM,OAAO,IAAI,gBAAgB;AACjC,QAAM,UAAU,CAAC,EAAE,UAAU,CAAC,CAAC,EAAE;AACjC,MAAI,WAA0C;AAC9C,QAAM,QAAQ,CAAC,SAAwC;AACnD,QAAI,KAAM;AACV,eAAW;AACX,UAAM,MAAM,GAAG,aAAa,CAAC,IAAI,KAAK,UAAU,QAAQ,CAAC,CAAC,CAAC;AAC3D,QAAI,QAAQ,QAAQ,MAAO;AAC3B,QAAI,MAAM,OAAO,GAAG;AAEhB,WAAK,QAAQ,MAAM,MAAM,IAAI,CAAC;AAC9B;AAAA,IACJ;AACA,UAAM,QAAQ;AACd,YAAQ;AACR,UAAM,UAAU,OAAO,YAAY,OAAO,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,MAAM,MAAS,CAAC;AAEvF,WAAO,MAAM,EAAE,GAAI,QAAQ,CAAC,GAAI,GAAG,SAAS,QAAQ,EAAE,UAAU,MAAM,QAAQ,OAAO,EAAE,SAAS,MAAM,OAAO,UAAU,MAAM,YAAY,KAAK,CAAC;AAC/I,eAAW,MAAM,OAAO,OAAO,CAAC,EAAG,IAAG,IAAI;AAAA,EAC9C;AACA,QAAM,SAAS,UAAU,eAAe,EAAE,MAAM,IAAI;AACpD,MAAI,OAAQ,OAAM,MAAM;AACxB,QAAM,QAAQ,SAAS,SAAY,WAAW,MAAM,MAAM,IAAI,GAAG,YAAY;AAC7E,QAAM,WAAW,OACZ,EAAE,UAAU,UAAU,EAAE,MAAM,EAAE,MAAM,QAAQ,EAAE,QAAQ,YAAY,EAAE,WAAW,GAAG,MAAM,EAAE,KAAK,GAAG,UAAU,EAAE,WAAW,EAAE,CAAC,GAC1H,cAAc,KAAK,MAAM,EACzB,KAAK,CAAC,SAAS;AACZ,QAAI,WAAW,KAAM,iBAAgB,EAAE,QAAQ,IAAI;AACnD,UAAM,IAAI;AAAA,EACd,CAAC,EACA,MAAM,MAAM;AAET,UAAM,QAAQ;AAAA,EAClB,CAAC,EACA,QAAQ,MAAM,aAAa,KAAK,CAAC;AAC1C,MAAI,SAAS,cAAc;AAC3B,OAAK,SAAS;AACd,QAAM,WAAW,QAAQ,MAAM;AAE3B,QAAI,cAAc,MAAM,QAAQ;AAC5B,eAAS,cAAc;AACvB,WAAK,SAAS;AAAA,IAClB,WAAW,KAAM,OAAM,QAAQ;AAAA,EACnC,CAAC;AACD,SAAO;AAAA,IACH,MAAM,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAAA,IACnC,OAAO,MAAM,MAAM,MAAM;AAAA,IACzB,QAAQ,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;AAAA,IACrC,SAAS,MAAM,MAAM,QAAQ;AAAA,IAC7B,SAAS,MAAM;AACX,aAAO;AACP,eAAS;AACT,WAAK,MAAM;AACX,mBAAa,KAAK;AAClB,YAAM,QAAQ;AAAA,IAClB;AAAA,EACJ;AACJ;AASA,IAAM,SAA8B,CAAC,YAAY,cAAc,aAAa,eAAe,gBAAgB,eAAe,iBAAiB,cAAc;AAEzJ,IAAM,QAAQ,CAAC,MAA0C;AACrD,eAAa;AAEb,QAAM,WAAW,OAAO,KAAK,CAAC,MAAM,MAAM,EAAE,QAAQ,KAAK;AACzD,QAAM,QAAQ,EAAE,SAAS,EAAE,SAAS;AACpC,QAAM,WAAW,EAAE,YAAY,EAAE,sBAAsB;AACvD,QAAM,WAAW,EAAE,YAAY;AAC/B,QAAM,QAAQ,EAAE,SAAS;AACzB,QAAM,QAAQ,UAAU,EAAE,SAAS;AAEnC,QAAM,WAAW,MAAM,KAAK,EAAE,CAAC,KAAK,KAAK,YAAY;AAGrD,QAAM,WAAgD,EAAE,SAAS,EAAE,KAAK,GAAG,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,WAAW,KAAK,IAAI,GAAG,EAAE,UAAU,KAAK,CAAC,SAAM,EAAE,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,EAAE,MAAM,EAAE;AAClM,QAAM,aAAa,EAAE,YAAY;AACjC,QAAM,SAAS,EAAE,QAAQ;AACzB,QAAM,YAAY,EAAE,WAAW;AAC/B,QAAM,UAAU,EAAE,SAAS;AAC3B,QAAM,YAAY,EAAE,WAAW;AAC/B,QAAM,MAAM,MAAuB,EAAE,UAAU,UAAU,EAAE,MAAM,EAAE,MAAM,QAAQ,EAAE,QAAQ,YAAY,EAAE,WAAW,GAAG,MAAM,EAAE,KAAK,GAAG,UAAU,EAAE,WAAW,EAAE,CAAC;AAEjK,QAAM,OAAO,GAAG,OAAO;AAAA,IACnB,OAAO;AAAA,IACP,cAAc,EAAE,SAAS;AAAA,IACzB,gBAAgB,EAAE,YAAY,UAAU,EAAE,YAAY,WAAW,EAAE,UAAU;AAAA,IAC7E,aAAa,EAAE,SAAS,WAAW,WAAW;AAAA,IAC9C,eAAe,EAAE,WAAW,UAAU,UAAU;AAAA;AAAA,IAEhD,GAAI,UAAU,IAAI,EAAE,MAAM,UAAU,EAAY,IAAI,CAAC;AAAA,EACzD,CAAC;AACD,MAAI,EAAE,UAAW,MAAK,aAAa,kBAAkB,EAAE;AACvD,MAAI,EAAE,QAAQ;AACV,SAAK,MAAM,YAAY,gBAAgB,EAAE,MAAM;AAC/C,SAAK,MAAM,YAAY,oBAAoB,MAAM,EAAE,MAAM,CAAC;AAAA,EAC9D;AACA,IAAE,MAAM,MAAM,GAAG,CAAC,EAAE,QAAQ,CAAC,GAAG,MAAM,kBAAkB,KAAK,CAAC,KAAK,KAAK,MAAM,YAAY,aAAa,IAAI,CAAC,IAAI,CAAC,CAAC;AAClH,GAAC,EAAE,aAAa,SAAS,MAAM,YAAY,IAAI;AAE/C,MAAI,OAAO;AACX,MAAI,aAAkC;AACtC,MAAI,OAA4C;AAChD,MAAI,SAA4B;AAEhC,MAAI,QAAuB,CAAC;AAC5B,MAAI,WAAW;AAEf,MAAI,SAAwB;AAE5B,MAAI,QAAuB;AAC3B,MAAI,SAAS;AAEb,MAAI,UAAU;AACd,MAAI,SAAS;AACb,MAAI,QAAQ;AAKZ,QAAM,UAAU,CAAC,MAAiB,EAA0B,WAAW,MAAM,EAAE,8DAA8D,IAAK,EAAY;AAK9J,MAAI,SAAiH,CAAC;AACtH,MAAI,YAAY;AAChB,MAAI,WAAW;AAEf,QAAM,QAAQ,oBAAI,IAAoB;AACtC,MAAI,OAAO,SAAS;AACpB,MAAI,SAA6C,CAAC;AAClD,MAAI,cAAc;AAClB,MAAI;AAEJ,MAAI,UAAU;AACd,MAAI,OAA+B;AACnC,MAAI,WAAoC;AACxC,MAAI,QAAQ;AACZ,MAAI,QAAQ,oBAAI,IAAY;AAE5B,MAAI,cAA8B;AAElC,MAAI,eAAiC,CAAC;AAEtC,MAAI,SAAS;AAEb,MAAI,UAAmC;AAEvC,MAAI,aAAa;AACjB,MAAI,cAAkC;AAEtC,MAAI,aAA4B;AAEhC,MAAI,OAAO;AAEX,QAAM,YAAY,CAAC,EAAE,UAAU,CAAC,CAAC,EAAE;AACnC,QAAM,WAAW,YAAY,EAAE;AAC/B,QAAM,aAAa,cAAc,EAAE;AACnC,MAAI,UAAU,EAAE,WAAW;AAC3B,MAAI,SAAS,EAAE,KAAK,GAAG;AAEvB,QAAM,SAAS,MAAM;AACjB,UAAM,IAAI,YAAY,KAA4C,QAAQ,IAAI;AAC9E,YAAQ,GAAG,QAAQ,WAAW,MAAM,QAAQ,EAAE,KAAK,IAAI,EAAE,QAAQ,CAAC;AAAA,EACtE;AACA,SAAO;AACP,MAAI,WAAW;AACX,UAAM,IAAI,KAAuD,UAAU;AAC3E,QAAI,GAAG,UAAU,QAAQ;AACrB,qBAAe,EAAE;AACjB,iBAAW,EAAE;AACb,oBAAc;AAAA,IAClB;AACA,iBAAa,CAAC,CAAC,GAAG;AAAA,EACtB;AAEA,QAAM,gBAAgB,CAAC,QAAgB;AACnC,QAAI,CAAC,aAAa,EAAE,WAAW,MAAM,IAAK;AAC1C,QAAI,MAAM,OAAQ,MAAK,UAAU,EAAE,KAAK,OAAO,MAAM,MAAM,GAAG,IAAI,EAAE,CAAC;AAAA,aAC5D,KAAsB,QAAQ,GAAG,QAAQ,IAAK,MAAK,UAAU,IAAI;AAAA,EAC9E;AACA,QAAM,kBAAkB,MAAM;AAC1B,QAAI,UAAW,MAAK,YAAY,aAAa,UAAU,aAAa,EAAE,UAAU,aAAa,MAAM,GAAG,IAAI,GAAG,SAAS,WAAW,IAAI,IAAI;AAAA,EAC7I;AAEA,QAAM,WAAW,CAAC,MAAmB,EAAE,SAAS,UAAU,EAAE,SAAS;AACrE,QAAM,WAAW,MAAM,QAAQ,SAAS,cAAc,SAAS,oBAAoB;AAEnF,QAAM,YAAY,MAAO,WAAW,UAAU,OAAO,OAAQ,UAAU,QAAQ,cAAc,MAAM;AACnG,QAAM,WAAW,CAAC,SAAiB,OAAO,OAAO,CAAC,MAAM,EAAE,SAAS,IAAI,EAAE;AAGzE,QAAM,QAAQ,CAAC,MAAc,SAAwB,QAA4B,YAAqB;AAClG,UAAM,MAAM,MAAM,IAAI,IAAI;AAC1B,UAAM,QAAQ,CAAC,OAAe,QAAQ,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE;AAC7D,QAAI,QAAQ,QAAW;AAGnB,YAAM,OAAO,KAAK,MAAM,IAAI;AAC5B,YAAM,QAAQ,UAAU,CAAC,IAAI,OAAO,MAAM,IAAI,IAAI,QAAQ,MAAM,QAAQ,UAAU,CAAC,MAAM,EAAE,OAAO,KAAK,GAAG,IAAI,CAAC;AAC/G,eAAS,CAAC,GAAG,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,KAAK,EAAE,CAAC;AAE1D,UAAI,UAAU,MAAM,QAAQ;AACxB,YAAI,QAAS,OAAM,KAAK;AACxB,sBAAc;AAAA,MAClB;AAAA,IACJ,OAAO;AACH,YAAM,QAAQ,MAAM,GAAG;AACvB,UAAI,MAAM,QAAQ;AACd,YAAI,QAAS,OAAM,KAAK;AACxB,YAAI,CAAC,SAAS,KAAK,UAAU,MAAM,MAAM;AACrC,mBAAS,CAAC,GAAG,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,KAAK,EAAE,CAAC;AAC1D,wBAAc;AAAA,QAClB;AAAA,MACJ;AAAA,IACJ;AACA,UAAM,IAAI,MAAM,UAAU,OAAO,EAAE;AAAA,EACvC;AAEA,QAAM,OAAO,CAACA,OAAkB;AAC5B,UAAM,OAAOA,GAAE;AACf,UAAM,OAAOA,GAAE,SAAS,GAAG,EAAE;AAE7B,YAAQA,GAAE,kBAAkB,QAAQ,OAAO,CAAC,EAAE,IAAI,KAAK,IAAI,QAAQ,KAAK,QAAQ,SAAS,OAAOA,GAAE,SAAS,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;AAC3H,eAAWA,GAAE;AACb,UAAM,QAAQ,CAAC,GAAG,MAAM;AACpB,UAAI,EAAE,OAAO,MAAM,GAAI,OAAM,EAAE,IAAI,EAAE,QAAQ,SAAS,EAAE,IAAI,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,MAAM,IAAI,EAAE,WAAW,YAAY,IAAI,CAAC;AAAA,IAC7H,CAAC;AACD,QAAI,KAAM,OAAM,KAAK,IAAIA,GAAE,SAAS,OAAO,QAAQ,GAAG,MAAM,IAAI,KAAK,WAAW,YAAY,MAAM,CAAC,GAAG,OAAO,KAAK,EAAE;AACpH,aAAS,OAAO,OAAO,WAAWA,IAAG,KAAK,CAAC;AAC3C,QAAI,WAAW,QAAQ,MAAM,OAAO,OAAQ,UAASA;AACrD,QAAI,SAAS,EAAG,UAAS;AAAA,EAC7B;AACA,QAAM,WAAW,MAAM;AACnB,UAAM,OAAO,UAAU;AACvB,QAAI,CAAC,KAAM;AACX,aAAS,OAAO,OAAO,CAAC,MAAM,EAAE,SAAS,IAAI;AAC7C,UAAM,KAAK,MAAM,IAAI,IAAI;AACzB,QAAI,CAAC,MAAM,KAAK,MAAM,IAAI,MAAM,GAAI;AAEpC,UAAMC,QAAO,OAAO,YAAY,OAAO,QAAQ,KAAK,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AACzG,WAAO,EAAE,GAAG,MAAM,OAAO,EAAE,GAAGA,OAAM,CAAC,IAAI,GAAG,GAAG,EAAE;AACjD,cAAU,KAAK,KAAK;AAAA,EACxB;AAGA,QAAM,YAAY,CAAC,IAAmB,GAAkBC,QAAO,UAAU;AACrE,QAAI,OAAO,UAAU,MAAM,OAAO;AAC9B,YAAM,MAAM;AACZ,aAAO;AACP,eAAS;AACT,gBAAU;AACV,kBAAY;AAAA,IAChB;AACA,aAAS;AACT,YAAQ;AACR,cAAUA;AAAA,EACd;AAEA,QAAM,gBAAgB,MAAM,UAAU,MAAM,MAAM,MAAM,SAAS,CAAC;AAClE,QAAM,YAAY,MAAM,UAAU,MAAM,EAAE,MAAM;AAEhD,QAAM,SAAS,CAAC,SAAgB,GAAG,QAAQ,EAAE,OAAO,cAAc,OAAO,oBAAoB,EAAE,IAAI,eAAe,OAAO,GAAG,OAAO;AAEnI,QAAM,SAAS,CAAC,SAAgB;AAC5B,QAAI,CAAC,EAAE,KAAM,QAAO,OAAO,IAAI;AAC/B,UAAM,KAAK,GAAG,QAAQ,EAAE,OAAO,8BAA8B,OAAO,oBAAoB,EAAE,IAAI,eAAe,OAAO,CAAC;AACrH,UAAM,MAAM,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,GAAG,CAAC;AAC9C,QAAI,iBAAiB,SAAS,MAAM,GAAG,YAAY,OAAO,IAAI,CAAC,CAAC;AAChE,OAAG,OAAO,GAAG;AACb,WAAO;AAAA,EACX;AAEA,QAAM,OAAO,GAAG,QAAQ,EAAE,OAAO,iBAAiB,eAAe,OAAO,CAAC;AACzE,MAAI,EAAE,MAAM;AACR,UAAM,MAAM,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,GAAG,CAAC;AAC9C,QAAI,iBAAiB,SAAS,MAAM,KAAK,gBAAgB,OAAO,IAAI,CAAC,CAAC;AACtE,SAAK,OAAO,GAAG;AAAA,EACnB,MAAO,MAAK,OAAO,OAAO,IAAI,CAAC;AAE/B,QAAM,YAAY,MAAO,EAAE,aAAa,GAAG,OAAO,EAAE,OAAO,gBAAgB,KAAK,EAAE,YAAY,KAAK,GAAG,CAAC,IAAI;AAE3G,QAAM,MAAM,GAAG,OAAO,EAAE,OAAO,gBAAgB,eAAe,OAAO,CAAC;AAItE,QAAM,UAAU,oBAAI,IAAgD;AACpE,QAAM,QAAQ,CAAC,MAAmB,SAAsB,SAAS;AAC7D,iBAAa,QAAQ,IAAI,IAAI,CAAC;AAC9B,YAAQ,OAAO,IAAI;AACnB,SAAK,gBAAgB,UAAU;AAC/B,QAAI,CAAC,KAAK,YAAa,QAAO,YAAY,IAAI;AAAA,EAClD;AACA,QAAM,QAAQ,CAAC,MAAmB,KAAK,QAAQ;AAC3C,QAAI,CAAC,KAAK,eAAe,QAAQ,IAAI,IAAI,EAAG;AAC5C,SAAK,aAAa,YAAY,EAAE;AAChC,YAAQ;AAAA,MACJ;AAAA,MACA,WAAW,MAAM;AACb,gBAAQ,OAAO,IAAI;AACnB,aAAK,gBAAgB,UAAU;AAC/B,aAAK,OAAO;AAAA,MAChB,GAAG,EAAE;AAAA,IACT;AAAA,EACJ;AAEA,QAAM,SAAS,CAAC,MAAmB,QAAgB;AAC/C,SAAK,UAAU,OAAO,GAAG;AACzB,SAAK,KAAK;AACV,SAAK,UAAU,IAAI,GAAG;AAAA,EAC1B;AAGA,QAAM,MAAM,GAAG,UAAU,EAAE,MAAM,UAAU,OAAO,uBAAuB,QAAQ,KAAK,iBAAiB,IAAI,YAAY,UAAU,iBAAiB,SAAS,CAAC;AAC5J,QAAM,WAAW;AAAA,IACb;AAAA,IACA,EAAE,OAAO,mBAAmB,eAAe,OAAO;AAAA,IAClD,GAAG,QAAQ,EAAE,OAAO,kBAAkB,UAAU,OAAO,GAAG,IAAI,QAAQ,MAAM,QAAQ,KAAK,IAAI,GAAG,CAAC;AAAA,IACjG,GAAG,QAAQ,EAAE,OAAO,kBAAkB,UAAU,IAAI,GAAG,KAAK,EAAE,MAAM,QAAQ,KAAK,EAAE,CAAC;AAAA,EACxF;AACA,QAAM,WAAW,GAAG,QAAQ,EAAE,OAAO,kBAAkB,eAAe,OAAO,CAAC;AAC9E,MAAI,OAAO,QAAQ;AACnB,MAAI,MAAO,KAAI,OAAO,GAAG,QAAQ,CAAC,GAAG,KAAK,CAAC;AAC3C,QAAM,OAAO,GAAG,OAAO,EAAE,OAAO,oBAAoB,YAAY,UAAU,MAAM,SAAS,CAAC;AAC1F,QAAM,UAAU,MAAM;AAClB,QAAI,gBAAgB,aAAa,IAAI;AACrC,QAAI,OAAO,UAAU,CAAC,MAAM;AACxB,YAAM,IAAI,OAAO,KAAK,IAAI,OAAO,QAAQ,CAAC,CAAC;AAC3C,UAAI,SAAS,gBAAgB,EAAG,UAAS,cAAc;AACvD,UAAI,CAAC,SAAS,YAAa,KAAI,OAAO,QAAQ;AAAA,IAClD,MAAO,UAAS,OAAO;AACvB,QAAI,aAAa,iBAAiB,OAAO,IAAI,CAAC;AAC9C,QAAI,aAAa,cAAc,OAAO,EAAE,YAAY,IAAI,OAAO,WAAW,IAAI,EAAE,wBAAwB,IAAI,OAAO,SAAS,GAAG,8BAA8B,EAAE,GAAG,OAAO,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC;AACnM,gBAAY;AAAA,EAChB;AACA,QAAM,eAAe,MAAM,aAAa,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,OAAO,UAAU;AACpF,QAAM,cAAc,MAAM;AACtB,UAAM,IAAI,OAAO,GAAG,EAAE;AACtB,QAAI,CAAC,aAAa,KAAK,CAAC,EAAG,QAAO,MAAM,IAAI;AAC5C,UAAM,IAAI,GAAG,UAAU,EAAE,MAAM,UAAU,OAAO,sBAAsB,cAAc,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,CAAC;AACrH,MAAE,iBAAiB,SAAS,CAAC,MAAM;AAC/B,QAAE,gBAAgB;AAClB,oBAAc;AACd,kBAAY;AAAA,IAChB,CAAC;AACD,UAAM,OAAO;AAAA,MACT;AAAA,MACA,EAAE,MAAM,UAAU,OAAO,wBAAwB;AAAA,MACjD;AAAA,QACI;AAAA,QACA,EAAE,OAAO,wBAAwB;AAAA,QACjC,GAAG,QAAQ,EAAE,OAAO,uBAAuB,GAAG,GAAG,SAAS,EAAE,IAAI,CAAC,GAAG,OAAO,SAAS,IAAI,SAAM,GAAG,WAAW,EAAE,GAAG,OAAO,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;AAAA,QAC1I,GAAG,QAAQ,EAAE,OAAO,wBAAwB,GAAG,OAAO,CAAC,CAAC;AAAA,MAC5D;AAAA,IACJ;AACA,SAAK,iBAAiB,SAAS,MAAM;AACjC,gBAAU,EAAE,MAAM,IAAI;AACtB,WAAK,UAAU;AAAA,IACnB,CAAC;AACD,SAAK,gBAAgB,MAAM,CAAC;AAC5B,UAAM,IAAI;AAAA,EACd;AAEA,MAAI,iBAAiB,SAAS,MAAM;AAChC,UAAM,OAAO;AACb,QAAI,KAAM,QAAO,MAAM;AACvB,UAAM,OAAO,OAAO,GAAG,EAAE;AACzB,QAAI,KAAM,WAAU,KAAK,MAAM,IAAI;AACnC,SAAK,OAAO,aAAa,MAAM;AAAA,EACnC,CAAC;AACD,MAAI,WAAY,MAAK,YAAY,GAAG;AAGpC,QAAM,MAAM,GAAG,OAAO,EAAE,OAAO,oBAAoB,YAAY,UAAU,MAAM,UAAU,cAAc,MAAM,CAAC;AAC9G,QAAM,MAAM,GAAG,OAAO,EAAE,OAAO,eAAe,CAAC;AAC/C,QAAM,OAAO,GAAG,OAAO,EAAE,OAAO,6BAA6B,CAAC;AAC9D,MAAI,iBAAiB,SAAS,MAAM,MAAM,OAAO,CAAC;AAGlD,QAAM,OAAO,GAAG,QAAQ,EAAE,OAAO,gBAAgB,CAAC;AAClD,QAAM,MAAM,GAAG,QAAQ,EAAE,OAAO,eAAe,CAAC;AAGhD,QAAM,OAAO,GAAG,OAAO,EAAE,OAAO,iBAAiB,cAAc,EAAE,WAAW,EAAE,CAAC;AAC/E,QAAM,MAAM,CAAC,GAAkB,MAAc,MAAc,OAAe,QAAgB;AACtF,UAAM,IAAI,GAAG,UAAU,EAAE,MAAM,UAAU,OAAO,eAAe,GAAG,GAAG,QAAQ,EAAE,OAAO,kBAAkB,GAAG,KAAK,MAAM,EAAE,GAAG,IAAI,OAAO,KAAK,EAAE,CAAC,GAAG,GAAG,QAAQ,CAAC,GAAG,IAAI,CAAC;AACrK,MAAE,iBAAiB,SAAS,MAAM;AAC9B,mBAAa;AACb,UAAI,MAAM,WAAY,eAAc;AACpC,SAAG,CAAC;AAAA,IACR,CAAC;AACD,WAAO;AAAA,EACX;AACA,QAAM,UAAU,IAAI,QAAQ,EAAE,MAAM,GAAG,EAAE,MAAM,OAAO,KAAK;AAC3D,QAAM,UAAU,IAAI,YAAY,EAAE,UAAU,GAAG,EAAE,MAAM,QAAQ,IAAI;AACnE,QAAM,UAAU,IAAI,QAAQ,EAAE,MAAM,GAAG,EAAE,MAAM,MAAM,KAAK;AAC1D,QAAM,aAAa,IAAI,WAAW,EAAE,SAAS,GAAG,EAAE,SAAS,WAAW,EAAE;AACxE,QAAM,WAAW,GAAG,QAAQ,EAAE,OAAO,qCAAqC,eAAe,OAAO,CAAC;AACjG,QAAM,UAAU,GAAG,UAAU,EAAE,MAAM,UAAU,OAAO,eAAe,cAAc,EAAE,MAAM,GAAG,iBAAiB,QAAQ,iBAAiB,QAAQ,GAAG,KAAK,EAAE,MAAM,EAAE,CAAC;AAEnK,QAAM,OAAO,GAAG,UAAU,EAAE,MAAM,UAAU,OAAO,0BAA0B,cAAc,EAAE,iBAAiB,EAAE,GAAG,KAAK,EAAE,KAAK,CAAC;AAChI,OAAK,iBAAiB,SAAS,MAAM,MAAM,CAAC;AAC5C,MAAI,OAAO,MAAM,KAAK,GAAG,QAAQ,EAAE,OAAO,iBAAiB,GAAG,SAAS,IAAI,CAAC;AAE5E,QAAM,OAAO,GAAG,OAAO,EAAE,OAAO,iBAAiB,MAAM,OAAO,CAAC;AAC/D,QAAM,WAAW,MAAM,KAAK,eAAe,CAAC,KAAK,aAAa,UAAU;AACxE,QAAM,YAAY,MAAM;AACpB,YAAQ,aAAa,iBAAiB,OAAO;AAC7C,UAAM,MAAM,GAAG;AAAA,EACnB;AACA,QAAM,WAAW,CAAC,GAAW,MAAc,QAAoB;AAC3D,UAAM,IAAI,GAAG,UAAU,EAAE,MAAM,UAAU,OAAO,mBAAmB,MAAM,WAAW,GAAG,KAAK,GAAG,EAAE,GAAG,GAAG,QAAQ,CAAC,GAAG,IAAI,CAAC;AACxH,MAAE,iBAAiB,SAAS,CAAC,MAAM;AAC/B,QAAE,gBAAgB;AAClB,gBAAU;AACV,UAAI;AAAA,IACR,CAAC;AACD,WAAO;AAAA,EACX;AACA,UAAQ,iBAAiB,SAAS,CAAC,MAAM;AACrC,MAAE,gBAAgB;AAClB,QAAI,SAAS,EAAG,QAAO,UAAU;AACjC,SAAK;AAAA,MACD,GAAG,QAAQ,EAAE,OAAO,kBAAkB,GAAG,EAAE,eAAe,CAAC;AAAA,MAC3D,SAAS,EAAE,OAAO,EAAE,eAAe,GAAG,MAAM,MAAM,CAAC;AAAA,MACnD,SAAS,OAAO,EAAE,WAAW,EAAE,QAAQ,OAAO,EAAE,eAAe,IAAI,EAAE,aAAa,GAAG,MAAM;AACvF,eAAO,CAAC;AACR,YAAI,gBAAgB,aAAa,IAAI;AAAA,MACzC,CAAC;AAAA,IACL;AACA,YAAQ,aAAa,iBAAiB,MAAM;AAC5C,UAAM,MAAM,GAAG;AACf,IAAC,KAAK,cAAc,QAAQ,GAAgC,MAAM;AAAA,EACtE,CAAC;AACD,MAAI,iBAAiB,SAAS,MAAM,SAAS,KAAK,UAAU,CAAC;AAE7D,QAAM,UAAU,MAAM;AAClB,UAAM,OAAO,CAAC,IAAgB,SAAiB;AAC3C,YAAM,IAAI,GAAG,UAAU,EAAE,MAAM,UAAU,OAAO,eAAe,cAAc,KAAK,GAAG,KAAK,EAAE,MAAM,EAAE,CAAC;AACrG,QAAE,iBAAiB,SAAS,EAAE;AAC9B,aAAO;AAAA,IACX;AACA,QAAI,OAAO,SAAS;AAChB,WAAK;AAAA,QACD,KAAK,MAAM,GAAG,MAAM,GAAG,EAAE,cAAc,CAAC;AAAA,MAC5C;AAAA,aACK,SAAS,UAAU,cAAc,CAAC,MAAM,KAAK;AAClD,WAAK;AAAA,QACD,KAAK,MAAM;AACP,uBAAa;AACb,aAAG,MAAM;AAAA,QACb,GAAG,EAAE,iBAAiB,CAAC;AAAA,MAC3B;AAAA,aACK,SAAS,cAAc,CAAC,WAAW,MAAM,SAAS;AACvD,WAAK;AAAA,QACD,KAAK,MAAM;AACP,wBAAc;AACd,aAAG,UAAU;AAAA,QACjB,GAAG,EAAE,mBAAmB,CAAC;AAAA,MAC7B;AAAA,aACK,SAAS,WAAY,MAAK,gBAAgB,KAAK,MAAM,GAAG,MAAM,GAAG,EAAE,cAAc,CAAC,CAAC;AAAA,aACnF,SAAS,OAAQ,MAAK,gBAAgB,IAAI;AAAA,QAC9C,MAAK,gBAAgB;AAC1B,QAAI,SAAS,cAAc,QAAS,KAAI,gBAAgB,GAAG,KAAK,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;AAAA,aACzE,SAAS,WAAY,KAAI,gBAAgB,OAAO,IAAI,GAAG,GAAG,QAAQ,EAAE,OAAO,iBAAiB,GAAG,GAAG,KAAK,CAAC,GAAG,KAAK,GAAG,GAAG,QAAQ,EAAE,OAAO,kBAAkB,GAAG,KAAK,CAAC,CAAC;AAAA,aACnK,SAAS,OAAQ,KAAI,gBAAgB,GAAG,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;AAAA,aAC3D,SAAS,UAAW,KAAI,gBAAgB,GAAG,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;AAAA,QACrE,KAAI,gBAAgB;AAGzB,UAAM,QAAQ,CAAC,SAAS,SAAS,GAAI,UAAU,cAAc,CAAC,OAAO,IAAI,CAAC,GAAI,GAAI,cAAc,UAAU,QAAQ,SAAS,cAAc,CAAC,UAAU,IAAI,CAAC,CAAE;AAC3J,QAAI,KAAK,WAAW,WAAW,MAAM,UAAU,MAAM,KAAK,CAACF,IAAG,MAAM,KAAK,WAAW,CAAC,MAAMA,EAAC,EAAG,MAAK,gBAAgB,GAAG,KAAK;AAE5H,SAAK,gBAAgB,aAAa,MAAM,SAAS,CAAC;AAClD,YAAQ,aAAa,gBAAgB,SAAS,SAAS,SAAS,OAAO;AACvE,YAAQ,aAAa,gBAAgB,SAAS,aAAa,SAAS,OAAO;AAC3E,YAAQ,aAAa,gBAAgB,SAAS,UAAU,SAAS,cAAc,SAAS,YAAY,SAAS,OAAO;AACpH,eAAW,aAAa,gBAAgB,SAAS,YAAY,SAAS,OAAO;AAC7E,QAAI,OAAO,UAAU,SAAS,YAAY;AACtC,eAAS,cAAc,OAAO,KAAK,IAAI,OAAO,QAAQ,CAAC,CAAC;AACxD,UAAI,CAAC,SAAS,YAAa,SAAQ,WAAY,YAAY,QAAQ;AAAA,IACvE,MAAO,UAAS,OAAO;AAAA,EAC3B;AAGA,QAAM,OAAO,GAAG,QAAQ,EAAE,OAAO,mBAAmB,CAAC;AACrD,QAAM,MAAM,GAAG,KAAK,EAAE,OAAO,kBAAkB,MAAM,QAAQ,CAAC;AAC9D,QAAM,QAAQ,GAAG,SAAS,EAAE,OAAO,4BAA4B,MAAM,SAAS,WAAW,SAAS,cAAc,SAAS,aAAa,EAAE,gCAAgC,GAAG,cAAc,EAAE,uBAAuB,GAAG,WAAW,OAAO,kBAAkB,IAAI,iBAAiB,QAAQ,iBAAiB,IAAI,kBAAkB,QAAQ,CAAC;AACtU,QAAM,MAAM,GAAG,OAAO,EAAE,OAAO,eAAe,CAAC;AAC/C,QAAM,OAAO,GAAG,YAAY,EAAE,OAAO,+BAA+B,MAAM,KAAK,aAAa,EAAE,0BAAqB,GAAG,cAAc,EAAE,SAAS,GAAG,WAAW,OAAO,CAAC;AACrK,QAAM,OAAO,GAAG,UAAU,EAAE,MAAM,UAAU,OAAO,iBAAiB,cAAc,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,EAAE,CAAC;AAGzG,QAAM,QAAQ,SAAS;AACvB,QAAM,OAAO;AAAA,IACT;AAAA,IACA,EAAE,MAAM,UAAU,OAAO,iBAAiB,cAAc,QAAQ,EAAE,+BAA+B,IAAI,EAAE,eAAe,GAAG,GAAI,QAAQ,EAAE,iBAAiB,QAAQ,iBAAiB,QAAQ,IAAI,CAAC,EAAG;AAAA,IACjM,KAAK,EAAE,MAAM,EAAE;AAAA,EACnB;AACA,MAAI,OAAO,MAAM,GAAG,OAAO,EAAE,OAAO,iBAAiB,GAAG,MAAM,GAAG,QAAQ,EAAE,OAAO,cAAc,CAAC,GAAG,IAAI,CAAC;AACzG,MAAI,iBAAiB,SAAS,CAAC,MAAM,EAAE,WAAW,OAAO,KAAK,MAAM,CAAC;AACrE,OAAK,OAAO,GAAG;AACf,QAAM,SAAS,GAAG,SAAS,EAAE,MAAM,QAAQ,QAAQ,gBAAgB,KAAK,GAAG,GAAG,UAAU,IAAI,QAAQ,IAAI,UAAU,MAAM,eAAe,OAAO,CAAC;AAC/I,OAAK,OAAO,MAAM;AAClB,QAAM,OAAO,GAAG,OAAO,EAAE,OAAO,kBAAkB,MAAM,QAAQ,cAAc,EAAE,eAAe,EAAE,CAAC;AAclG,MAAI,SAAmB,CAAC;AAExB,QAAM,YAAY,oBAAI,IAAoB;AAC1C,QAAM,UAAU,CAAC,OAAe,UAAU,IAAI,EAAE,KAAK,IAAI,EAAE,cAAc,EAAE;AAC3E,QAAM,SAAS,CAAC,MAAc;AAC1B,MAAE,KAAK,MAAM;AACb,QAAI,CAAC,CAAC,GAAG,UAAU,OAAO,CAAC,EAAE,SAAS,EAAE,KAAK,EAAG,KAAI,gBAAgB,EAAE,KAAK;AAAA,EAC/E;AACA,QAAM,WAAW,CAAC,MAAc;AAC5B,aAAS,OAAO,OAAO,CAAC,MAAM,MAAM,CAAC;AACrC,WAAO,CAAC;AAAA,EACZ;AACA,QAAM,WAAW,CAACE,UAAuC;AACrD,YAAQ;AACR,eAAW,KAAKA,OAAM;AAClB,YAAM,OAAO,EAAE,QAAQ;AACvB,UAAI,OAAO,UAAU,wBAAwB;AACzC,gBAAQ,GAAG,gCAAgC,EAAE,GAAG,uBAAuB,CAAC;AACxE;AAAA,MACJ;AACA,UAAI,CAAE,gBAAsC,SAAS,EAAE,IAAI,GAAG;AAC1D,gBAAQ,EAAE,4DAA4D;AACtE;AAAA,MACJ;AACA,UAAI,EAAE,OAAO,qBAAqB;AAC9B,gBAAQ,GAAG,gCAAgC,EAAE,KAAK,CAAC;AACnD;AAAA,MACJ;AACA,YAAM,IAAY,EAAE,KAAK,SAAS,KAAK,IAAI,EAAE,SAAS,EAAE,CAAC,GAAG,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,MAAM,MAAM,EAAE,MAA0B,MAAM,EAAE,MAAM,OAAO,IAAI,gBAAgB,CAAC,GAAG,IAAI,QAAQ,QAAQ,GAAG,MAAM,IAAI,gBAAgB,EAAE;AAC9O,QAAE,KAAK,IAAI,EACN,eAAe,GAAG,EAAE,KAAK,MAAM,EAC/B;AAAA,QACG,CAAC,MAAM;AACH,YAAE,KAAK,EAAE;AACT,eAAK;AAAA,QACT;AAAA,QACA,CAAC,MAAa;AACV,cAAI,EAAE,SAAS,aAAc;AAC7B,mBAAS,CAAC;AACV,kBAAQ,GAAG,EAAE,IAAI,KAAK,EAAE,OAAO;AAC/B,eAAK;AAAA,QACT;AAAA,MACJ;AACJ,aAAO,KAAK,CAAC;AAAA,IACjB;AACA,QAAI,SAAS,SAAS,cAAc,UAAU;AAC1C,gBAAU;AACV,SAAG,UAAU;AAAA,IACjB,MAAO,MAAK;AACZ,SAAK,MAAM;AAAA,EACf;AACA,MAAI,UAAU;AACd,QAAM,WAAW,MAAM;AACnB,UAAM,MAAM,OAAO,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,EAAE,KAAK,IAAI,CAAC,EAAE,EAAE,KAAK,GAAG;AAClE,QAAI,QAAQ,SAAS;AACjB,gBAAU;AACV,WAAK;AAAA,QACD,GAAG,OAAO,IAAI,CAAC,MAAM;AACjB,gBAAM,IAAI,GAAG,UAAU,EAAE,MAAM,UAAU,OAAO,mBAAmB,cAAc,GAAG,iBAAiB,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,CAAC;AAC3I,YAAE,iBAAiB,SAAS,MAAM;AAC9B,qBAAS,CAAC;AACV,iBAAK;AACL,iBAAK,MAAM;AAAA,UACf,CAAC;AACD,gBAAM,OAAO,EAAE,KAAK,WAAW,QAAQ,IAAI,GAAG,OAAO,EAAE,KAAK,EAAE,OAAO,KAAK,GAAG,CAAC,IAAI,GAAG,QAAQ,EAAE,OAAO,oBAAoB,GAAG,KAAK,EAAE,KAAK,EAAE,GAAG,GAAG,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC;AACpK,iBAAO,GAAG,OAAO,EAAE,OAAO,iBAAiB,MAAM,YAAY,OAAO,EAAE,MAAM,cAAc,EAAE,KAAK,EAAE,OAAO,GAAG,qBAAqB,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG,GAAI,EAAE,KAAK,CAAC,IAAI,EAAE,aAAa,OAAO,EAAG,GAAG,MAAM,CAAC;AAAA,QAC5M,CAAC;AAAA,MACL;AAAA,IACJ;AACA,QAAI,CAAC,OAAO,OAAQ,MAAK,OAAO;AAAA,aACvB,CAAC,KAAK,YAAa,MAAK,aAAa,MAAM,GAAG;AAAA,EAC3D;AAGA,QAAM,QAAQ,YAAY;AACtB,QAAI;AACJ,QAAI;AACA,eAAS,MAAM,UAAU,aAAa,gBAAgB,EAAE,OAAO,EAAE,gBAAgB,UAAU,GAAG,OAAO,OAAO,kBAAkB,MAAM,oBAAoB,UAAU,CAA8B;AAAA,IACpM,SAAS,GAAG;AACR,UAAK,EAAY,SAAS,qBAAsB,EAAY,SAAS,cAAc;AAC/E,gBAAQ,EAAE,6DAA6D;AACvE,aAAK;AAAA,MACT;AACA;AAAA,IACJ;AACA,SAAK,MAAM,aAAa;AACxB,QAAI,OAAoB;AACxB,QAAI;AACA,YAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,YAAM,QAAQ;AACd,YAAM,cAAc;AACpB,YAAM,YAAY;AAClB,YAAM,MAAM,KAAK;AAEjB,YAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,GAAG,CAAC;AAC3C,YAAM,IAAI;AACV,YAAM,IAAI,QAAc,CAAC,MAAO,EAAE,4BAA4B,EAAE,0BAA0B,MAAM,EAAE,CAAC,IAAI,sBAAsB,MAAM,EAAE,CAAC,CAAE;AACxI,YAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,aAAO,QAAQ,MAAM;AACrB,aAAO,SAAS,MAAM;AACtB,aAAO,WAAW,IAAI,GAAG,UAAU,OAAO,GAAG,CAAC;AAC9C,YAAM,SAAS,CAAC,MAAc,MAAe,IAAI,QAAqB,CAAC,MAAM,OAAO,OAAO,GAAG,MAAM,CAAC,CAAC;AACtG,aAAO,MAAM,OAAO,WAAW;AAE/B,UAAI,QAAQ,KAAK,OAAO,MAAM,OAAO,KAAM,QAAO,MAAM,OAAO,cAAc,GAAG;AAAA,IACpF,QAAQ;AACJ,aAAO;AAAA,IACX,UAAE;AACE,iBAAWF,MAAK,OAAO,UAAU,EAAG,CAAAA,GAAE,KAAK;AAC3C,WAAK,MAAM,aAAa;AAAA,IAC5B;AACA,QAAI,CAAC,QAAQ,CAAC,KAAK,MAAM;AACrB,cAAQ,EAAE,6DAA6D;AACvE,aAAO,KAAK;AAAA,IAChB;AACA,UAAM,SAAQ,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,EAAE,QAAQ,SAAS,GAAG;AACxE,aAAS,CAAC,OAAO,OAAO,MAAM,EAAE,MAAM,cAAc,KAAK,IAAI,KAAK,SAAS,cAAc,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC;AAAA,EAChH;AAGA,QAAM,QAAQ,GAAG,OAAO,EAAE,OAAO,gCAAgC,MAAM,OAAO,CAAC;AAC/E,QAAM,YAAY,MAAM,MAAM,eAAe,CAAC,MAAM,aAAa,UAAU;AAC3E,QAAM,aAAa,MAAM;AACrB,SAAK,aAAa,iBAAiB,OAAO;AAC1C,UAAM,OAAO,GAAG;AAAA,EACpB;AACA,QAAM,YAAY,CAAC,GAAW,MAAc,QAAoB;AAC5D,UAAM,IAAI,GAAG,UAAU,EAAE,MAAM,UAAU,OAAO,mBAAmB,MAAM,WAAW,GAAG,KAAK,GAAG,EAAE,GAAG,GAAG,QAAQ,CAAC,GAAG,IAAI,CAAC;AACxH,MAAE,iBAAiB,SAAS,CAAC,MAAM;AAC/B,QAAE,gBAAgB;AAClB,iBAAW;AACX,UAAI;AAAA,IACR,CAAC;AACD,WAAO;AAAA,EACX;AACA,OAAK,iBAAiB,SAAS,CAAC,MAAM;AAClC,MAAE,gBAAgB;AAClB,UAAM,OAAO;AACb,QAAI,CAAC,MAAO,QAAO,OAAO,MAAM;AAChC,QAAI,UAAU,EAAG,QAAO,WAAW;AACnC,UAAM;AAAA,MACF,UAAU,EAAE,OAAO,EAAE,eAAe,GAAG,MAAM,OAAO,MAAM,CAAC;AAAA,MAC3D,UAAU,EAAE,QAAQ,EAAE,yBAAyB,GAAG,MAAM,KAAK,MAAM,CAAC;AAAA,IACxE;AACA,SAAK,aAAa,iBAAiB,MAAM;AACzC,UAAM,OAAO,IAAI;AACjB,IAAC,MAAM,cAAc,QAAQ,GAAgC,MAAM;AAAA,EACvE,CAAC;AACD,SAAO,iBAAiB,UAAU,MAAM;AACpC,aAAS,CAAC,GAAI,OAAO,SAAS,CAAC,CAAE,CAAC;AAClC,WAAO,QAAQ;AAAA,EACnB,CAAC;AAED,QAAM,QAAQ,GAAG,KAAK,EAAE,OAAO,oBAAoB,MAAM,WAAW,QAAQ,UAAU,KAAK,WAAW,GAAG,EAAE,oBAAoB,EAAE,MAAM,SAAS,EAAE,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,UAAU,GAAG,EAAE,oBAAoB,EAAE,MAAM,SAAS,EAAE,CAAC,CAAC;AAE1N,QAAM,OAAO,GAAG,MAAM,EAAE,OAAO,YAAY,aAAa,UAAU,cAAc,EAAE,UAAU,EAAE,CAAC;AAC/F,QAAM,YAAY,MAAM,YAAY,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;AACzD,QAAM,UAAU,MAAM,CAAC,MAAM,MAAM,KAAK,KAAK,MAAM,KAAK,MAAM,MAAM,KAAK,CAAC;AAC1E,QAAM,UAAU,OAAO,CAAC,CAAC,KAAK,MAAM,KAAK,KAAK,OAAO,SAAS,MAAM,QAAQ;AAE5E,QAAM,KAAK,CAAC,MAA2C;AACnD,UAAM,UAAU,KAAK,UAAU,CAAC,MAAM,KAAK,UAAU,IAAI;AACzD,WAAO;AACP,YAAQ;AACR,SAAK;AACL,QAAI,QAAS,QAAO,MAAM,gBAAgB;AAC1C,QAAI,MAAM,YAAY;AAClB,eAAS;AACT,cAAQ;AACR,WAAK,MAAM;AAAA,IACf,WAAW,MAAM,OAAQ,WAAU,MAAM;AACzC,aAAS,CAAC;AAAA,EACd;AAGA,QAAM,UAAU,CAAC,KAAa,QAAgB;AAC1C,UAAM,MAAM,GAAG,OAAO,EAAE,KAAK,KAAK,SAAS,OAAO,CAAC;AACnD,QAAI,iBAAiB,QAAQ,MAAM;AAC/B,UAAI,KAAK,eAAe,KAAK,YAAY,KAAK,eAAe,IAAI,eAAe,IAAK,MAAK,YAAY,KAAK;AAAA,IAC/G,CAAC;AACD,WAAO;AAAA,EACX;AACA,QAAM,SAAS,CAAC,GAAgB,YAAY,UAAU;AAClD,UAAM,OAAO,aAAa,KAAK,IAAI,IAAI,KAAK,MAAM,EAAE,EAAE,KAAK;AAC3D,UAAM,KAAK,GAAG,MAAM,EAAE,OAAO,WAAW,aAAa,EAAE,SAAS,YAAY,OAAO,OAAO,GAAG,EAAE,QAAQ,CAAC,EAAE,aAAa,SAAS,GAAG,OAAO,EAAE,OAAO,aAAa,GAAG,EAAE,IAAI,IAAI,IAAI;AACjL,QAAI,UAAW,IAAG,aAAa,aAAa,MAAM;AAElD,QAAI,EAAE,aAAa;AACf,SAAG;AAAA,QACC;AAAA,UACI;AAAA,UACA,EAAE,OAAO,gBAAgB;AAAA,UACzB,GAAG,EAAE,YAAY;AAAA,YAAI,CAAC,MAClB,EAAE,KAAK,WAAW,QAAQ,IACpB,GAAG,KAAK,EAAE,OAAO,eAAe,MAAM,QAAQ,EAAE,EAAE,GAAG,QAAQ,UAAU,KAAK,YAAY,OAAO,EAAE,KAAK,GAAG,QAAQ,QAAQ,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,IACvI,GAAG,KAAK,EAAE,OAAO,iBAAiB,MAAM,QAAQ,EAAE,EAAE,GAAG,QAAQ,UAAU,KAAK,WAAW,GAAG,KAAK,EAAE,KAAK,EAAE,GAAG,GAAG,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC;AAAA,UAC7I;AAAA,QACJ;AAAA,MACJ;AACJ,eAAW,KAAK,EAAE,YAAY,CAAC,GAAG;AAC9B,YAAM,OAAO,GAAG,UAAU,EAAE,MAAM,UAAU,OAAO,gBAAgB,GAAG,KAAK,EAAE,KAAK,EAAE,GAAG,GAAG,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC;AAC9G,WAAK,iBAAiB,SAAS,MAAM,GAAG,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;AAC1D,SAAG,OAAO,IAAI;AAAA,IAClB;AACA,OAAG,OAAO,GAAG,QAAQ,EAAE,OAAO,eAAe,GAAG,EAAE,SAAS,OAAO,UAAU,IAAI,MAAM,GAAG,EAAE,SAAS,YAAY,GAAG,SAAS,EAAE,IAAI,CAAC,WAAQ,EAAE,GAAG,OAAO,EAAE,eAAU,IAAI,QAAQ,EAAE,EAAE,CAAC,EAAE,CAAC;AACvL,WAAO;AAAA,EACX;AAEA,QAAM,aAAa,CAAC,MAAsB;AACtC,UAAM,IAAI,GAAG,UAAU,EAAE,MAAM,UAAU,OAAO,eAAe,GAAG,GAAG,QAAQ,EAAE,OAAO,iBAAiB,GAAG,EAAE,KAAK,GAAG,KAAK,EAAE,MAAM,EAAE,CAAC;AACpI,MAAE,iBAAiB,SAAS,MAAM,GAAG,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;AACvD,WAAO;AAAA,EACX;AAEA,QAAM,UAAU,CAAC,MAAc,KAAa,MAAc,QAAoB;AAC1E,UAAM,IAAI;AAAA,MACN;AAAA,MACA,EAAE,MAAM,UAAU,OAAO,gBAAgB;AAAA,MACzC,GAAG,QAAQ,EAAE,OAAO,qBAAqB,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,GAAG,MAAM,GAAG,QAAQ,EAAE,OAAO,oBAAoB,GAAG,GAAG,IAAI,MAAM,OAAO,GAAG,QAAQ,EAAE,OAAO,qBAAqB,GAAG,IAAI,IAAI,IAAI;AAAA,MAC5L,KAAK,EAAE,MAAM,EAAE;AAAA,IACnB;AACA,MAAE,iBAAiB,SAAS,GAAG;AAC/B,WAAO;AAAA,EACX;AAEA,QAAM,YAAY,CAAC,cAAc,EAAE,iBAAiB,MAAM;AACtD,UAAM,OAAO,GAAG,SAAS,EAAE,OAAO,kBAAkB,CAAC;AACrD,UAAM,QAAQ,GAAG,SAAS,EAAE,OAAO,sBAAsB,MAAM,UAAU,aAAa,cAAc,EAAE,iBAAiB,GAAG,WAAW,MAAM,CAAC;AAC5I,UAAM,QAAQ;AACd,QAAI;AACJ,UAAM,iBAAiB,SAAS,MAAM;AAClC,cAAQ,MAAM;AACd,mBAAa,IAAI;AACjB,aAAO,WAAW,MAAM;AACpB,YAAI,SAAS,OAAQ,QAAO,GAAG,MAAM;AACrC,aAAK,aAAa,IAAI;AAAA,MAC1B,GAAG,GAAG;AAAA,IACV,CAAC;AACD,UAAM,iBAAiB,WAAW,CAAC,MAAM;AACrC,UAAI,EAAE,QAAQ,SAAS;AACnB,UAAE,eAAe;AACjB,YAAI,SAAS,OAAQ,IAAG,MAAM;AAAA,MAClC;AAAA,IACJ,CAAC;AACD,SAAK,OAAO,KAAK,EAAE,QAAQ,EAAE,GAAG,KAAK;AACrC,WAAO;AAAA,EACX;AAEA,QAAM,aAAa,UAAU,EAAE,8BAAyB,CAAC;AACzD,QAAM,YAAY,WAAW,cAAc,OAAO;AAElD,MAAI,kBAAkB;AAEtB,QAAM,UAAU,MAAM;AAClB,cAAU;AACV,OAAG,UAAU;AAAA,EACjB;AACA,QAAM,eAAe,OAAO,QAAQ,UAAU;AAC1C,QAAI,CAAC,UAAW,mBAAmB,CAAC,MAAQ;AAC5C,sBAAkB;AAClB,UAAM,IAAI,MAAM,KAAK;AACrB,QAAI;AACA,YAAM,IAAI,MAAM,IAAI,EAAE,SAAS,KAAK,MAAS;AAC7C,UAAI,MAAM,MAAM,KAAK,EAAG;AACxB,iBAAW,EAAE;AACb,UAAI,CAAC,GAAG;AACJ,uBAAe,EAAE;AACjB,sBAAc,EAAE,SAAS,SAAS;AAClC,wBAAgB;AAAA,MACpB;AAAA,IACJ,QAAQ;AACJ,iBAAW,YAAY,CAAC;AAAA,IAC5B,UAAE;AACE,wBAAkB;AAAA,IACtB;AACA,SAAK;AAAA,EACT;AACA,QAAM,cAAc,YAAY;AAC5B,QAAI;AACA,iBAAW,MAAM,IAAI,EAAE,UAAU,GAAG,QAAQ,MAAM,GAAG,aAAa;AAClE,mBAAa,QAAQ,SAAS;AAC9B,sBAAgB;AAAA,IACpB,QAAQ;AAEJ,gBAAU,CAAC;AAAA,IACf;AACA,kBAAc;AACd,SAAK;AAAA,EACT;AAIA,QAAM,UAAU,GAAG,QAAQ,EAAE,OAAO,gBAAgB,CAAC;AACrD,QAAM,QAAQ,GAAG,SAAS,EAAE,OAAO,oBAAoB,aAAa,EAAE,gBAAgB,GAAG,cAAc,EAAE,gBAAgB,GAAG,WAAW,QAAQ,cAAc,MAAM,CAAC;AACpK,QAAM,QAAQ,GAAG,UAAU,EAAE,MAAM,UAAU,OAAO,iBAAiB,cAAc,EAAE,MAAM,GAAG,UAAU,GAAG,GAAG,KAAK,EAAE,EAAE,CAAC;AACxH,UAAQ,OAAO,OAAO,KAAK;AAC3B,QAAM,iBAAiB,SAAS,MAAO,MAAM,WAAW,CAAC,MAAM,MAAM,KAAK,CAAE;AAC5E,UAAQ,iBAAiB,UAAU,CAAC,MAAM;AACtC,MAAE,eAAe;AACjB,QAAI,CAAC,MAAM,MAAM,KAAK,GAAG;AACrB,oBAAc;AACd,aAAO,GAAG,UAAU;AAAA,IACxB;AACA,SAAK,QAAQ,MAAM;AACnB,UAAM,QAAQ;AACd,UAAM,WAAW;AACjB,cAAU;AACV,OAAG,UAAU;AACb,QAAI,QAAQ,EAAG,QAAO;AAAA,EAC1B,CAAC;AAKD,QAAM,SAAS,CAAC,MAAc,OAAO,UACjC;AAAA,IACI;AAAA,IACA,EAAE,OAAO,mBAAmB,eAAe,OAAO;AAAA,IAClD,GAAG,MAAM;AAAA,MAAK,EAAE,QAAQ,KAAK;AAAA,MAAG,MAC5B;AAAA,QACI;AAAA,QACA,EAAE,OAAO,OAAO,kCAAkC,iBAAiB;AAAA,QACnE,GAAG,QAAQ,EAAE,OAAO,sBAAsB,GAAG,OAAO,GAAG,QAAQ,EAAE,OAAO,yCAAyC,CAAC,IAAI,MAAM,GAAG,QAAQ,EAAE,OAAO,qBAAqB,GAAG,GAAG,QAAQ,EAAE,OAAO,cAAc,CAAC,GAAG,GAAG,QAAQ,EAAE,OAAO,cAAc,CAAC,CAAC,CAAC;AAAA,MACvP;AAAA,IACJ;AAAA,EACJ;AAEJ,QAAM,QAAQ,CAAC,SAAsB;AACjC,QAAI,KAAK,YAAa,MAAK,aAAa,cAAc,EAAE;AACxD,WAAO;AAAA,EACX;AACA,QAAM,YAAY,OAAO,GAAG,IAAI;AAChC,QAAM,YAAY,OAAO,CAAC;AAE1B,MAAI,WAA+B;AAEnC,QAAM,UAAU,CAAC,MAAmB;AAChC,UAAM,IAAI,EAAE;AACZ,UAAM,IAAI,SAAS,EAAE,EAAE;AACvB,UAAM,SAAS,EAAE,WAAW,WAAW,SAAM,EAAE,QAAQ,CAAC,KAAK;AAC7D,UAAMG,OAAM;AAAA,MACR;AAAA,MACA,EAAE,MAAM,UAAU,OAAO,iCAAiC,cAAc,GAAG,GAAG,2BAA2B,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC,GAAG,MAAM,GAAG,IAAI,KAAK,GAAG,WAAW,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,GAAG;AAAA,MACnL;AAAA,QACI;AAAA,QACA,EAAE,OAAO,sBAAsB;AAAA,QAC/B,OAAO,IAAI;AAAA,QACX;AAAA,UACI;AAAA,UACA,EAAE,OAAO,qBAAqB;AAAA,UAC9B,GAAG,QAAQ,EAAE,OAAO,yCAAyC,GAAG,EAAE,OAAO;AAAA,UACzE,KAAK,OAAO,CAAC,MAAM,EAAE,UAAU,GAAG,QAAQ,EAAE,OAAO,oBAAoB,GAAG,OAAO,CAAC,CAAC,IAAI;AAAA,UACvF,IAAI,GAAG,QAAQ,EAAE,OAAO,qBAAqB,GAAG,GAAG,SAAS,EAAE,IAAI,CAAC,SAAM,QAAQ,EAAE,EAAE,CAAC,GAAG,MAAM,EAAE,IAAI;AAAA,QACzG;AAAA,QACA,IAAI,GAAG,QAAQ,EAAE,OAAO,iBAAiB,GAAG,OAAO,CAAC,CAAC,IAAI,KAAK,EAAE,MAAM,EAAE;AAAA,MAC5E;AAAA,IACJ;AACA,IAAAA,KAAI,iBAAiB,SAAS,MAAM;AAChC,gBAAU,EAAE,IAAI,IAAI;AACpB,SAAG,UAAU;AAAA,IACjB,CAAC;AACD,WAAOA;AAAA,EACX;AACA,QAAM,WAAW,GAAG,OAAO,EAAE,OAAO,iBAAiB,CAAC;AACtD,QAAM,UAAU,GAAG,UAAU,EAAE,MAAM,UAAU,OAAO,uCAAuC,GAAG,KAAK,EAAE,IAAI,GAAG,EAAE,kBAAkB,CAAC;AACnI,UAAQ,iBAAiB,SAAS,OAAO;AACzC,MAAI,WAAW;AACf,QAAM,YAAY,MAAM;AAEpB,UAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,GAAG,EAAE,EAAE,IAAI,EAAE,MAAM,IAAI,EAAE,MAAM,EAAE,IAAI,SAAS,EAAE,EAAE,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,KAAK,MAAM,KAAK,IAAI,IAAI,GAAM,CAAC;AAChI,QAAI,QAAQ,UAAU;AAClB,iBAAW;AACX,eAAS,gBAAgB,GAAG,MAAM,IAAI,OAAO,CAAC;AAAA,IAClD;AACA,QAAI,KAAK,WAAW,CAAC,MAAM,SAAU,MAAK,gBAAgB,UAAU,OAAO;AAAA,EAC/E;AAEA,QAAM,WAAW,MAAM;AAEnB,UAAM,QAAQ,EAAE,KAAK,GAAG,MAAM,KAAK,EAAE,MAAM,KAAK,EAAE,CAAC;AACnD,UAAM,QAAQ,EAAE,WAAW,SAAS,QAAQ,6HAA6H,EAAE,EAAE,KAAK,IAAI,EAAE,kBAAkB,MAAM,EAAE,4BAA4B;AAC9O,UAAM,OAAO;AAAA,MACT;AAAA,MACA,EAAE,OAAO,+BAA+B;AAAA,MACxC,GAAG,QAAQ,CAAC,GAAG,GAAG,QAAQ,GAAG,cAAc,EAAE,MAAM,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,KAAK,GAAG,QAAQ,EAAE,OAAO,iBAAiB,eAAe,OAAO,GAAG,WAAI,CAAC;AAAA,MACnJ,GAAG,QAAQ,EAAE,OAAO,qBAAqB,GAAG,IAAI;AAAA,IACpD;AACA,UAAM,QAAuB,CAAC,MAAM,OAAO;AAC3C,UAAM,QAAQ,oBAAI,IAAY;AAC9B,UAAM,WAAW,CAAC,MAAmB,QAAgB;AACjD,YAAM,IAAI,GAAG;AACb,UAAI,YAAY,CAAC,SAAS,IAAI,GAAG,EAAG,MAAK,aAAa,eAAe,EAAE;AACvE,aAAO;AAAA,IACX;AAEA,UAAM,UAAU,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,QAAQ;AACzD,UAAM,QAAQ,QAAQ,SAAS,UAAU,OAAO,MAAM,GAAG,CAAC;AAC1D,UAAM,KAAK,GAAG,KAAK,IAAI,CAAC,MAAM,SAAS,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;AAEzD,QAAI,CAAC,KAAK,UAAU,CAAC,UAAU,SAAS,KAAK,EAAE,KAAK,GAAG,GAAI,OAAM,KAAK,MAAM,SAAS,CAAC;AACtF,QAAI,MAAM,SAAS,KAAK,QAAQ;AAC5B,YAAM,MAAM,GAAG,UAAU,EAAE,MAAM,UAAU,OAAO,eAAe,GAAG,GAAG,2BAA2B,EAAE,GAAG,MAAM,OAAO,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,CAAC;AACxI,UAAI,iBAAiB,SAAS,MAAM;AAChC,sBAAc;AACd,WAAG,UAAU;AAAA,MACjB,CAAC;AACD,YAAM,KAAK,GAAG;AAAA,IAClB;AAEA,UAAM,MAAM,SAAS,aAAa,MAAM,GAAG,CAAC,IAAI,CAAC;AACjD,QAAI,IAAI,OAAQ,OAAM,KAAK,SAAS,GAAG,OAAO,EAAE,OAAO,kCAAkC,GAAG,GAAG,IAAI,IAAI,UAAU,CAAC,GAAG,MAAM,CAAC;AAC5H,eAAW;AACX,SAAK,gBAAgB,GAAG,KAAK;AAAA,EACjC;AAEA,QAAM,WAAW,MAAM;AACnB,QAAI,UAAU,UAAU,MAAO,WAAU,QAAQ;AACjD,UAAM,IAAI,MAAM,KAAK;AACrB,UAAM,MAAM,YAAY,CAAC;AACzB,UAAM,SAAS,oBAAI,IAA8B;AACjD,eAAW,KAAK,IAAK,QAAO,IAAI,EAAE,YAAY,CAAC,GAAI,OAAO,IAAI,EAAE,UAAU,KAAK,CAAC,GAAI,CAAC,CAAC;AACtF,UAAM,SAAS,CAAC,KAAK,eAAe,OAAQ,OAAO,IAAI,UAAU,KAAK,CAAC,IAAK;AAC5E,UAAM,UAAU,IAAI,EAAE,gBAAgB,IAAI,SAAU,cAAc,KAAM,EAAE,oBAAoB;AAC9F,UAAM,QAAuB,CAAC,GAAG,MAAM,EAAE,OAAO,kBAAkB,GAAG,OAAO,GAAG,UAAU;AACzF,QAAI,aAAa,KAAM,OAAM,KAAK,MAAM,SAAS,CAAC;AAAA,aACzC,CAAC,IAAI,QAAQ;AAClB,YAAM,MAAM,GAAG,UAAU,EAAE,MAAM,UAAU,OAAO,0BAA0B,GAAG,EAAE,mBAAmB,CAAC;AACrG,UAAI,iBAAiB,SAAS,OAAO;AACrC,YAAM,KAAK,GAAG,OAAO,EAAE,OAAO,iBAAiB,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,GAAG,sCAA4B,EAAE,EAAE,CAAC,IAAI,EAAE,uBAAuB,CAAC,GAAG,GAAG,CAAC;AAAA,IAC/I,WAAW,KAAK;AACZ,YAAM;AAAA,QACF;AAAA,UACI;AAAA,UACA,EAAE,OAAO,iBAAiB;AAAA,UAE1B,IAAI,UAAU,KAAK,IAAI,CAAC,MAAM,QAAQ,EAAE,OAAO,EAAE,QAAQ,WAAW,EAAE,KAAK,IAAI,EAAE,QAAQ,MAAM,EAAE,MAAM,MAAM,EAAE,KAAK,IAAI,EAAE,SAAS,IAAI,EAAE,aAAa,IAAI,MAAM,GAAG,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC;AAAA,QAC1L;AAAA,MACJ;AAAA;AAEA,YAAM;AAAA,QACF;AAAA,UACI;AAAA,UACA,EAAE,OAAO,iBAAiB;AAAA,UAC1B,GAAG,CAAC,GAAG,MAAM,EAAE;AAAA,YAAI,CAAC,CAAC,MAAM,KAAK,MAC5B,QAAQ,MAAM,MAAM,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,IAAI,GAAG,MAAM,WAAW,IAAI,EAAE,WAAW,IAAI,GAAG,gBAAgB,EAAE,GAAG,MAAM,OAAO,CAAC,GAAG,MAAM;AACrI,2BAAa;AACb,iBAAG,MAAM;AACT,qBAAO,MAAM,gBAAgB;AAAA,YACjC,CAAC;AAAA,UACL;AAAA,QACJ;AAAA,MACJ;AAEJ,QAAI,KAAK,WAAW,CAAC,MAAM,WAAY,MAAK,gBAAgB,GAAG,KAAK;AAAA,SAC/D;AACD,MAAC,KAAK,WAA2B,YAAY,MAAM,CAAC,CAAC;AACrD,aAAO,KAAK,WAAW,SAAS,EAAG,MAAK,UAAW,OAAO;AAC1D,WAAK,OAAO,GAAG,MAAM,MAAM,CAAC,CAAC;AAAA,IACjC;AAAA,EACJ;AAGA,QAAM,cAAc,MAAM;AACtB,oBAAgB,CAAC,UACX,OAAO,CAAC,IACR,CAAC,QAAQ,SACP,GAAG,OAAO,EAAE,OAAO,iBAAiB,GAAG,GAAG,KAAK,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC,IACxE;AAAA,MACI;AAAA,MACA,EAAE,OAAO,mBAAmB;AAAA,MAC5B,GAAG,QAAQ,IAAI,CAAC,MAAM,GAAG,WAAW,EAAE,OAAO,kBAAkB,GAAG,GAAG,KAAK,EAAE,OAAO,iBAAiB,GAAG,QAAQ,EAAE,WAAW,CAAC,GAAG,GAAG,MAAM,EAAE,OAAO,oBAAoB,GAAG,EAAE,KAAK,GAAG,EAAE,OAAO,GAAG,KAAK,EAAE,OAAO,oBAAoB,GAAG,EAAE,IAAI,IAAI,IAAI,CAAC;AAAA,IACvP;AACR,QAAI,KAAK,eAAe,eAAe,KAAK,WAAW,WAAW,EAAG,MAAK,gBAAgB,WAAW;AAAA,EACzG;AAEA,MAAI,eAAyD;AAC7D,QAAM,cAAc,CAAC,OAAe;AAChC,QAAI,cAAc,OAAO,GAAI,QAAO,KAAK,gBAAgB,aAAa,IAAI;AAC1E,UAAM,OAAO,GAAG,WAAW,EAAE,OAAO,eAAe,GAAG,OAAO,CAAC,CAAC;AAC/D,mBAAe,EAAE,IAAI,KAAK;AAC1B,SAAK,gBAAgB,IAAI;AACzB,QAAI,EACC,QAAQ,EAAE,EACV,KAAK,CAAC,MAAM;AACT,YAAM,OAAO,GAAG,OAAO,EAAE,OAAO,gBAAgB,CAAC;AACjD,YAAM,WAAW,MAAM;AACnB,YAAI,MAAM,IAAI,EAAE,EAAG,QAAO,KAAK,gBAAgB,GAAG,QAAQ,CAAC,GAAG,EAAE,6BAA6B,CAAC,CAAC;AAC/F,cAAM,MAAM,GAAG,UAAU,EAAE,MAAM,UAAU,OAAO,UAAU,GAAG,EAAE,KAAK,CAAC;AACvE,cAAM,KAAK,GAAG,UAAU,EAAE,MAAM,UAAU,OAAO,UAAU,GAAG,EAAE,IAAI,CAAC;AACrE,cAAM,OAAO,CAAC,YAAqB;AAC/B,kBAAQ,IAAI,IAAI,KAAK,EAAE,IAAI,EAAE;AAC7B,mBAAS;AACT,cAAI,EACC,YAAY,IAAI,OAAO,EACvB,MAAM,MAAM,MAAS;AAC1B,cAAI,CAAC,QAAS,SAAQ;AAAA,QAC1B;AACA,YAAI,iBAAiB,SAAS,MAAM,KAAK,IAAI,CAAC;AAC9C,WAAG,iBAAiB,SAAS,MAAM,KAAK,KAAK,CAAC;AAC9C,aAAK,gBAAgB,GAAG,QAAQ,CAAC,GAAG,EAAE,gCAAgC,CAAC,GAAG,GAAG,QAAQ,EAAE,OAAO,kBAAkB,GAAG,KAAK,EAAE,CAAC;AAAA,MAC/H;AACA,eAAS;AACT,YAAM,MAAM,GAAG,UAAU,EAAE,MAAM,UAAU,OAAO,uBAAuB,GAAG,KAAK,EAAE,IAAI,GAAG,EAAE,oCAAoC,CAAC;AACjI,UAAI,iBAAiB,SAAS,OAAO;AACrC,WAAK;AAAA,QACD,GAAG,KAAK,EAAE,OAAO,iBAAiB,GAAG,EAAE,UAAU;AAAA,QACjD,GAAG,MAAM,EAAE,OAAO,iBAAiB,GAAG,EAAE,KAAK;AAAA,QAC7C,GAAG,KAAK,EAAE,OAAO,iBAAiB,GAAG,GAAG,kBAAkB,EAAE,MAAM,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;AAAA,QACzF,GAAG,OAAO,EAAE,OAAO,iBAAiB,GAAG,GAAG,EAAE,OAAO,IAAI,OAAO,CAAC;AAAA,QAC/D;AAAA,QACA;AAAA,MACJ;AAAA,IACJ,CAAC,EACA,MAAM,CAAC,MAAa;AACjB,qBAAe;AACf,WAAK,gBAAgB,GAAG,KAAK,EAAE,OAAO,iBAAiB,GAAG,EAAE,OAAO,CAAC;AAAA,IACxE,CAAC;AAAA,EACT;AAEA,MAAI,QAAQ;AAEZ,MAAI,UAAU;AAEd,MAAI,YAAY;AAChB,QAAM,cAAc,GAAG,OAAO,EAAE,OAAO,gBAAgB,CAAC;AAExD,QAAM,aAAa,MAAM,OAAO,OAAO,CAAC,MAAM,EAAE,UAAU,SAAS,EAAE,SAAS,MAAM;AACpF,QAAM,eAAe,MAAM;AACvB,UAAM,UAAU,UAAU,OAAO,SAAS;AAC1C,UAAM,OAAO,SAAS,YAAY,CAAC;AACnC,UAAM,OAAO,WAAW;AACxB,UAAM,QAAuB,CAAC;AAG9B;AACI,YAAM,UAAU,KAAK,IAAI,CAACC,OAAMA,GAAE,OAAO;AACzC,YAAM,MAAM,GAAG,KAAK,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,KAAK,GAAG,CAAC,IAAI,QAAQ,IAAI,CAAC,MAAM,GAAG,EAAE,EAAE,IAAI,KAAK,IAAI,IAAI,KAAK,MAAM,EAAE,EAAE,KAAK,YAAY,EAAE,EAAE,KAAK,GAAG,CAAC,IAAI,KAAK,MAAM,KAAK,IAAI,IAAI,GAAM,CAAC;AAC7K,UAAI,QAAQ,SAAS;AACjB,kBAAU;AAGV,cAAM,QAAQ,KAAK,UAAU,QAAQ,UAAU,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,EAAE,OAAO,WAAW,aAAa,OAAO,GAAG,GAAG,OAAO,EAAE,OAAO,aAAa,GAAG,QAAQ,CAAC,CAAC;AAC/J,cAAM,QAAQ,CAAC,GAAG,OAAO,GAAG,KAAK,IAAI,CAAC,MAAM,OAAO,CAAC,CAAC,GAAG,GAAG,QAAQ,IAAI,CAAC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC;AAC9F,YAAI,aAAa,EAAG,OAAM,MAAM,SAAS,EAAE,QAAQ,CAAC,OAAO,GAAG,aAAa,YAAY,EAAE,CAAC;AAC1F,oBAAY,MAAM;AAClB,aAAK,gBAAgB,GAAG,KAAK;AAAA,MACjC;AACA,YAAM,KAAK,IAAI;AAEf,YAAM,MAAM,CAAC,KAAK,KAAK,CAAC,MAAM,EAAE,SAAS,SAAS,KAAK,CAAC,KAAK,UAAU,CAAC,UAAU,YAAY,CAAC,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC;AACjH,UAAI,IAAI,QAAQ;AACZ,YAAI,YAAY,WAAW,WAAW,IAAI;AACtC,sBAAY;AAAA,YACR,GAAG,IAAI,IAAI,CAAC,MAAM;AACd,oBAAM,IAAI,GAAG,UAAU,EAAE,MAAM,UAAU,OAAO,kBAAkB,GAAG,EAAE,KAAK;AAC5E,gBAAE,iBAAiB,SAAS,MAAM,GAAG,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;AACvD,qBAAO;AAAA,YACX,CAAC;AAAA,UACL;AACJ,cAAM,KAAK,WAAW;AAAA,MAC1B;AAAA,IACJ;AACA,QAAI,SAAS,cAAc,WAAW,YAAY,CAAC,KAAK,OAAQ,OAAM,KAAK,GAAG,KAAK,EAAE,OAAO,yBAAyB,GAAG,EAAE,wDAAwD,CAAC,CAAC;AACpL,QAAI,KAAK,WAAW,WAAW,MAAM,UAAU,MAAM,KAAK,CAAC,GAAG,MAAM,KAAK,WAAW,CAAC,MAAM,CAAC,EAAG,MAAK,gBAAgB,GAAG,KAAK;AAC5H,UAAM,QAAQ,KAAK,SAAS,KAAK;AACjC,QAAI,UAAU,OAAO;AACjB,cAAQ;AACR,WAAK,YAAY,KAAK;AAAA,IAC1B;AACA,QAAI,cAAc;AAClB,QAAI,SAAS,CAAC,IAAI,YAAa,MAAK,QAAQ,GAAG;AAAA,aACtC,CAAC,MAAO,KAAI,OAAO;AAC5B,QAAI,UAAU,GAAG;AACb,UAAI,QAAQ,EAAG,OAAM,gBAAgB,cAAc;AAAA,UAC9C,OAAM,aAAa,gBAAgB,MAAM;AAC9C,UAAI,CAAC,MAAM,YAAa,KAAI,aAAa,OAAO,IAAI;AAAA,IACxD,MAAO,OAAM,OAAO;AACpB,aAAS;AACT,SAAK,WAAW,CAAC,QAAQ;AAAA,EAC7B;AAEA,QAAM,OAAO,MAAM;AACf,QAAI,CAAC,KAAM;AACX,QAAI,QAAQ,OAAO,OAAO,SAAS,WAAW,OAAO;AACrD,YAAQ;AACR,QAAI,SAAS,OAAQ,UAAS;AAAA,aACrB,SAAS,WAAY,EAAC,UAAU,YAAY,cAAc;AAAA,aAC1D,SAAS,OAAQ,UAAS;AAAA,aAC1B,SAAS,UAAW,aAAY;AAAA,QACpC,aAAY,KAAK,OAAO;AAC7B,UAAM,OAAsB,SAAS,SAAS,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI;AAC3E,SAAK,KAAK,SAAS,cAAc,CAAC,UAAU,OAAO,IAAI;AACvD,QAAI,EAAE,aAAa,MAAO,MAAK,KAAK,KAAK;AACzC,QAAI,KAAK,YAAa,MAAK,KAAK,IAAI;AACpC,QAAI,IAAI,WAAW,WAAW,KAAK,UAAU,KAAK,KAAK,CAAC,GAAG,MAAM,IAAI,WAAW,CAAC,MAAM,CAAC,EAAG,KAAI,gBAAgB,GAAG,IAAI;AAAA,EAC1H;AAGA,QAAM,OAAO,YAAY;AAGrB,QAAI,KAAM;AACV,UAAM,OAAQ,OAAO,IAAI,gBAAgB;AACzC,UAAM,QAAQ,EAAE,WAAW;AAC3B,QAAI,OAAO;AACX,UAAM,WAAW,WAAW,MAAM;AAC9B,aAAO;AACP,WAAK,MAAM;AAAA,IACf,GAAG,KAAK,IAAI,mBAAmB,KAAK,QAAQ,YAAY,CAAC;AAGzD,QAAI;AACJ,QAAI;AACA,WAAK,MAAM,IAAI,EAAE,KAAK,KAAK,QAAQ,UAAU,MAAS,CAAC;AACvD,cAAQ;AACR,gBAAU;AACV,eAAS;AACT,oBAAc,KAAK;AAAA,IACvB,SAAS,GAAG;AACR,UAAK,EAAY,SAAS,gBAAgB,CAAC,KAAM;AACjD,YAAM,SAAU,EAA0B;AAC1C,gBAAU,WAAW,OAAO,WAAW;AAEvC,UAAI,WAAW,OAAO,OAAQ,eAAc;AAAA,eACnC,QAAQ,SAAS,cAAc,CAAC,KAAM,SAAQ,QAAQ,CAAC;AAChE,UAAI,QAAQ,WAAW,UAAa,UAAU,KAAK;AAC/C,kBAAU;AACV,gBAAQ,OAAO,IAAI,KAAK,IAAI,MAAO,MAAM,SAAS,IAAI,YAAY;AAAA,MACtE;AAAA,IACJ,UAAE;AACE,mBAAa,QAAQ;AACrB,UAAI,SAAS,KAAM,QAAO;AAAA,IAC9B;AAEA,QAAI,CAAC,UAAU,UAAU,QAAW;AAChC,kBAAY;AAEZ,UAAI,SAAS,cAAc,WAAW,QAAQ,UAAU,QAAQ,CAAC,KAAK,MAAM,KAAK,KAAK,CAAC,OAAO,UAAU,CAAC,OAAO,OAAQ,eAAc;AACtI,eAAS;AAAA,IACb;AACA,SAAK;AACL,YAAQ;AACR,aAAS,QAAQ,SAAS,oBAAoB,WAAW,QAAQ,MAAS;AAAA,EAC9E;AAEA,QAAM,UAAU,MAAM;AAClB,UAAM,MAAM,EAAE,WAAW;AACzB,QAAI,QAAQ,WAAW,CAAC,QAAS;AACjC,QAAI,QAAQ,SAAS;AAEjB,UAAI,UAAU,CAAC,EAAE,KAAK,GAAG,MAAM,UAAW,MAAK,UAAU,IAAI;AAC7D,gBAAU;AACV,YAAM,MAAM;AACZ,aAAO;AACP,eAAS,CAAC;AACV,eAAS;AACT,eAAS;AACT,aAAO;AAAA,IACX;AACA,aAAS,EAAE,KAAK,GAAG;AACnB,SAAK;AACL,YAAQ;AACR,aAAS,CAAC;AAAA,EACd;AAEA,WAAS,SAAS,KAAc;AAC5B,iBAAa,IAAI;AACjB,UAAM,UAAU,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,QAAQ;AACzD,UAAM,UAAU,QAAQ,SAAS;AACjC,UAAM,SAAS,QAAQ,KAAK,CAAC,MAAM,EAAE,QAAQ,KAAK,IAAI,IAAI,IAAI,KAAK,EAAE,KAAK,EAAE,EAAE,QAAQ,IAAI,cAAc;AACxG,UAAM,QAAQ,QAAQ,UAAa,CAAC,QAAQ,CAAC;AAC7C,UAAM,KAAK,QAAQ,SAAS,oBAAoB,WAAW,IAAI,SAAS,IAAI,eAAe,WAAW,SAAS,kBAAkB,QAAQ,gBAAgB;AAEzJ,QAAI,MAAM,QAAQ,EAAG,QAAO,WAAW,MAAO,UAAU,WAAW,EAAE,EAAE,KAAK,GAAG,MAAM,MAAM,WAAW,SAAS,IAAI,KAAK,KAAK,GAAI,EAAE;AAAA,EACvI;AACA,QAAM,YAAY,MAAM;AACpB,QAAI,SAAS,oBAAoB,UAAW,UAAS,CAAC;AAAA,QACjD,cAAa,IAAI;AAAA,EAC1B;AACA,WAAS,iBAAiB,oBAAoB,SAAS;AAGvD,QAAM,QAAQ,YAAY;AACtB,QAAI,SAAU;AACd,eAAW;AACX,WAAO,OAAO,QAAQ;AAClB,YAAM,OAAO,OAAO,CAAC;AACrB,YAAM,EAAE,SAAS,OAAO,OAAO,MAAM,IAAI;AAEzC,YAAM,QAAQ,IAAI,MAAM,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AACxC,YAAM,MAAM,MAAM,OAAO,CAAC,MAAM,EAAE,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE,EAAG;AACtD,UAAI;AACA,YAAI,CAAC,QAAQ,QAAQ,CAAC,IAAI,OAAQ,OAAM,IAAI,MAAM,SAAS,EAAE,6BAA6B,CAAC;AAC3F,cAAM,OAAO,MAAM,IAAI,EAAE,SAAS;AAAA,UAC9B,MAAM,QAAQ;AAAA,UACd,GAAI,KAAK,UAAU,OAAO,EAAE,cAAc,MAAM,IAAI,KAAK,OAAO,EAAE,cAAc,KAAK,KAAK,IAAI,CAAC;AAAA,UAC/F,OAAO;AAAA,UACP,KAAK,OAAO,SAAS,KAAK,MAAM,GAAG,GAAG;AAAA,UACtC,GAAI,IAAI,SAAS,EAAE,aAAa,IAAI,IAAI,CAAC;AAAA;AAAA,UAEzC,SAAS,EAAE,UAAU,GAAG,OAAO,UAAU,OAAI,OAAO,WAAW,GAAG;AAAA,QACtE,CAAC;AAED,cAAM,MAAM;AACZ,eAAO;AAEP,cAAM,OAAO,KAAK,cAAc,MAAM;AACtC,YAAI,MAAM;AACN,gBAAM,QAAQ,OAAO,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,EAAE,UAAU,KAAK,SAAS,EAAE,SAAS,KAAK,IAAI;AAC1F,cAAI,KAAK,UAAU,SAAS,KAAK,SAAS,QAAQ;AAC9C,oBAAQ;AACR,qBAAS;AAAA,UACb;AACA,qBAAW,KAAK,OAAO;AACnB,cAAE,QAAQ;AACV,cAAE,OAAO;AAAA,UACb;AAAA,QACJ;AACA,aAAK,IAAI;AACT,eAAO,MAAM;AACb,mBAAW,KAAK,OAAO;AACnB,oBAAU,OAAO,EAAE,GAAG;AACtB,cAAI,gBAAgB,EAAE,KAAK;AAAA,QAC/B;AAAA,MACJ,SAAS,GAAG;AAGR,cAAM,OAAO,OAAO,OAAO,CAAC;AAE5B,cAAM,OAAQ,EAA0B,WAAW;AACnD,kBAAU,OAAO,OAAO,KAAK,CAAC,EAAE,MAAM,OAAO,EAAE,SAAS,KAAK,CAAC,EAAE,KAAK;AACrE,aAAK,QAAQ,CAAC,GAAG,KAAK,IAAI,CAAC,MAAM,EAAE,QAAQ,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI;AAC9F,iBAAS,CAAC,GAAG,KAAK,QAAQ,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM;AACxE,mBAAW,KAAK,KAAM,YAAW,KAAK,EAAE,MAAO,WAAU,OAAO,EAAE,GAAG;AACrE,gBAAQ,OAAO,EAAE,4FAA4F,IAAI,QAAQ,CAAC;AAAA,MAC9H;AACA,WAAK;AAAA,IACT;AACA,eAAW;AACX,aAAS;AAAA,EACb;AAEA,QAAM,SAAS,MAAM;AACjB,UAAM,MAAM,KAAK,MAAM,KAAK;AAC5B,UAAM,QAAQ;AACd,QAAK,CAAC,OAAO,CAAC,MAAM,UAAW,CAAC,QAAQ,EAAG;AAC3C,UAAM,OAAO;AACb,eAAW,KAAK,MAAO,WAAU,IAAI,EAAE,KAAK,EAAE,KAAK;AACnD,WAAO,KAAK;AAAA,MACR,SAAS;AAAA,QACL,IAAI,WAAW,EAAE,SAAS;AAAA,QAC1B,MAAM;AAAA,QACN,MAAM;AAAA,QACN,KAAI,oBAAI,KAAK,GAAE,YAAY;AAAA,QAC3B,GAAI,MAAM,SAAS,EAAE,aAAa,MAAM,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,MAAM,EAAE,MAAM,MAAM,EAAE,MAAM,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC;AAAA,MACvH;AAAA,MACA;AAAA,MACA,OAAO,UAAU,KAAK,MAAM,MAAM,KAAK,IAAI,MAAM,MAAM,KAAK,IAAI;AAAA,MAChE,MAAM;AAAA,MACN;AAAA,IACJ,CAAC;AACD,SAAK,QAAQ;AACb,aAAS,CAAC;AACV,YAAQ;AACR,SAAK;AAEL,eAAW,MAAM,eAAe,EAAE;AAClC,SAAK,MAAM;AAAA,EACf;AACA,OAAK,iBAAiB,UAAU,CAAC,MAAM;AACnC,MAAE,eAAe;AACjB,WAAO;AAAA,EACX,CAAC;AACD,OAAK,iBAAiB,WAAW,CAAC,MAAM;AACpC,QAAI,EAAE,QAAQ,WAAW,CAAC,EAAE,YAAY,CAAC,EAAE,aAAa;AACpD,QAAE,eAAe;AACjB,aAAO;AAAA,IACX;AAAA,EACJ,CAAC;AACD,OAAK,iBAAiB,SAAS,MAAO,KAAK,WAAW,CAAC,QAAQ,CAAE;AAEjE,OAAK,iBAAiB,SAAS,CAAC,MAAM;AAClC,UAAM,KAAK,CAAC,GAAI,EAAE,eAAe,SAAS,CAAC,CAAE;AAC7C,QAAI,CAAC,GAAG,OAAQ;AAChB,MAAE,eAAe;AACjB,aAAS,EAAE;AAAA,EACf,CAAC;AAED,QAAM,WAAW,CAAC,MAAiB,CAAC,CAAC,EAAE,gBAAgB,CAAC,GAAG,EAAE,aAAa,KAAK,EAAE,SAAS,OAAO;AACjG,MAAI,iBAAiB,YAAY,CAAC,MAAM;AACpC,QAAI,CAAC,SAAS,CAAC,EAAG;AAClB,MAAE,eAAe;AACjB,QAAI,aAAa,aAAa,EAAE;AAAA,EACpC,CAAC;AACD,MAAI,iBAAiB,aAAa,CAAC,MAAM;AACrC,QAAI,CAAC,EAAE,iBAAiB,CAAC,IAAI,SAAS,EAAE,aAAqB,EAAG,KAAI,gBAAgB,WAAW;AAAA,EACnG,CAAC;AACD,MAAI,iBAAiB,QAAQ,CAAC,MAAM;AAChC,QAAI,CAAC,SAAS,CAAC,EAAG;AAClB,MAAE,eAAe;AACjB,QAAI,gBAAgB,WAAW;AAC/B,aAAS,CAAC,GAAI,EAAE,cAAc,SAAS,CAAC,CAAE,CAAC;AAAA,EAC/C,CAAC;AACD,QAAM,iBAAiB,SAAS,MAAM,KAAK,CAAC;AAE5C,WAAS,KAAK,IAAyC,QAAQC,SAAQ,OAAO;AAC1E,UAAM,MAAM;AACZ,WAAO;AACP,WAAQ,MAAM,UAAU,CAAC,UAAY,MAAM,aAAa,CAAC,YAAa,SAAS;AAC/E,YAAQ;AACR,kBAAc;AACd,eAAW;AACX,QAAI,gBAAgB,cAAcA,MAAK;AACvC,UAAM,GAAG;AACT,QAAI,IAAK,QAAO,MAAM,gBAAgB;AACtC,QAAI,aAAa,QAAQ,gBAAgB,QAAS,SAAS,UAAU,MAAQ,MAAK,aAAa;AAC/F,SAAK;AACL,YAAQ;AACR,QAAI,SAAS,YAAY;AACrB,eAAS;AACT,WAAK,MAAM;AAAA,IACf;AACA,aAAS,CAAC;AAAA,EACd;AACA,WAAS,QAAQ;AACb,QAAI,CAAC,KAAM;AACX,WAAO;AACP,QAAI,KAAK,YAAa,WAAU;AAChC,UAAM,KAAK,GAAG;AACd,YAAQ;AACR,aAAS;AACT,QAAI,WAAY,KAAI,MAAM;AAE1B,UAAM,KAAK;AACX,iBAAa;AACb,QAAI,GAAI,YAAW,IAAI,GAAG;AAAA,EAC9B;AACA,MAAI,iBAAiB,SAAS,MAAM,UAAU,KAAK,WAAW,CAAC;AAC/D,QAAM,QAAQ,CAAC,MAAqB;AAChC,QAAI,EAAE,QAAQ,YAAY,CAAC,KAAM;AACjC,QAAI,UAAU,GAAG;AACb,iBAAW;AACX,WAAK,MAAM;AAAA,IACf,WAAW,SAAS,GAAG;AACnB,gBAAU;AACV,cAAQ,MAAM;AAAA,IAClB,MAAO,OAAM;AAAA,EACjB;AACA,WAAS,iBAAiB,WAAW,KAAK;AAG1C,OAAK,KAAK;AACV,MAAI,OAAQ,MAAK,aAAa;AAC9B,MAAI,UAAW,MAAK,YAAY;AAChC,UAAQ;AACR,MAAI,EAAE,OAAQ,MAAK,EAAE,QAAQ,IAAI;AAEjC,SAAO;AAAA,IACH,MAAM,CAAC,MAAM;AACT,UAAI,MAAM,WAAY,eAAc;AACpC,WAAK,KAAK,MAAM;AAAA,IACpB;AAAA,IACA;AAAA,IACA,QAAQ,MAAO,OAAO,MAAM,IAAI,KAAK;AAAA,IACrC;AAAA,IACA,QAAQ,MAAM;AAAA,IACd,SAAS,CAAC,OAAO;AACb,mBAAa;AAAA,IACjB;AAAA,IACA,SAAS,MAAM;AACX,mBAAa,IAAI;AACjB,iBAAWL,MAAK,QAAQ,OAAO,EAAG,cAAaA,EAAC;AAChD,YAAM,MAAM;AACZ,iBAAW,KAAK,OAAQ,QAAO,CAAC;AAChC,iBAAW,KAAK,UAAU,OAAO,EAAG,KAAI,gBAAgB,CAAC;AACzD,eAAS,oBAAoB,WAAW,KAAK;AAC7C,eAAS,oBAAoB,oBAAoB,SAAS;AAC1D,WAAK,OAAO;AAAA,IAChB;AAAA,EACJ;AACJ;","names":["t","kept","list","row","o","still"]}
|