@guidelytech/guide-runtime 0.6.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/messenger.ts","../src/help-view.ts","../src/pdf-viewer.ts","../src/host.ts","../src/sanitize.ts","../src/howto-view.ts","../src/messenger-styles.ts","../src/render-safe.ts"],"sourcesContent":["import type {\n ConversationMessagesResponse,\n MessengerConfig,\n MessengerConversation,\n MessengerMessage,\n MessengerPageContent,\n MessengerStatus,\n ResourceCenterArticle,\n ResourceCenterConfig,\n SdkArticlesResponse,\n SdkHowTo,\n SdkHowToSummary,\n SdkHowTosResponse,\n} from \"@guidelytech/shared\";\nimport { foldPathIds, pageLabel } from \"@guidelytech/shared/runtime\";\nimport { createHelpView, el, listItem, type HelpData, type HelpGuideRef, type HelpSuggestion } from \"./help-view\";\nimport { renderHowTo } from \"./howto-view\";\nimport { MESSENGER_STYLES } from \"./messenger-styles\";\nimport { renderSafeText } from \"./render-safe\";\n\n/** Callbacks the transport invokes while a message is sent and Scout replies. */\nexport interface MessengerStreamHandlers {\n /** A new conversation was created (first message only). */\n onConversation?(conversation: MessengerConversation): void;\n onMessage(message: MessengerMessage): void;\n onDelta(messageId: string, text: string): void;\n onDone(message: MessengerMessage | null, conversation: MessengerConversation): void;\n onError(message: string): void;\n}\n\n/** Server access for the messenger; implemented by sdk-core over the public SDK API. */\nexport interface MessengerApi {\n listConversations(): Promise<MessengerConversation[]>;\n loadMessages(conversationId: string, since?: string | null): Promise<ConversationMessagesResponse>;\n start(text: string, handlers: MessengerStreamHandlers): Promise<void>;\n send(conversationId: string, text: string, handlers: MessengerStreamHandlers): Promise<void>;\n handoff(conversationId: string): Promise<ConversationMessagesResponse>;\n rate(conversationId: string, rating: number): Promise<void>;\n listArticles(): Promise<SdkArticlesResponse>;\n getArticle(id: string): Promise<ResourceCenterArticle | null>;\n searchArticles(q: string): Promise<ResourceCenterArticle[]>;\n /** How-tos available in the app, and the ones for the page the user is on (optional: older transports). */\n listHowTos?(): Promise<SdkHowTosResponse>;\n getHowTo?(id: string): Promise<SdkHowTo | null>;\n /** Page-matched how-tos, articles and common questions (servers before the personalised home lack it). */\n pageContent?(path: string): Promise<MessengerPageContent>;\n}\n\nexport type MessengerTab = \"home\" | \"messages\" | \"help\" | \"news\";\n\n/** A guide the visitor started and didn't finish. */\nexport interface MessengerResumeGuide {\n id: string;\n name: string;\n stepId: string;\n /** Zero-based index of the step they reached. */\n stepIndex: number;\n stepCount: number;\n}\n\nexport interface MessengerChecklistProgress {\n id: string;\n name: string;\n done: number;\n total: number;\n /** Title of the first unfinished task. */\n nextTask: string | null;\n}\n\n/** A live announcement, shown on Home and in the News tab. */\nexport interface MessengerNewsItem {\n id: string;\n key: string;\n title: string;\n /** Plain text. */\n body: string;\n imageUrl: string | null;\n publishedAt: string;\n unread: boolean;\n}\n\n/** What the SDK knows about the visitor right now, read each time the messenger renders. */\nexport interface MessengerVisitor {\n firstName: string | null;\n /** Current page path (no query or fragment); null when unknown. */\n path: string | null;\n /** Live guides targeted at this page that the visitor can start. */\n pageGuides: HelpGuideRef[];\n resumeGuide: MessengerResumeGuide | null;\n checklist: MessengerChecklistProgress | null;\n news: MessengerNewsItem[];\n}\n\nexport interface MessengerOptions {\n scope: HTMLElement;\n config: MessengerConfig;\n api: MessengerApi;\n /** Resource center extras (recommended guides, checklists, FAQs, links) shown in the Help tab. */\n resourceCenter?: ResourceCenterConfig | null;\n /** The visitor's audiences (for audience-targeted articles and collections in the Help tab). */\n audienceIds?: () => ReadonlySet<string> | readonly string[];\n guides?: HelpGuideRef[];\n onStartGuide?: (guideKeyOrId: string) => void;\n onOpenChecklist?: (guideId: string) => void;\n onArticleView?: (article: ResourceCenterArticle) => void;\n onOpen?: () => void;\n onClose?: () => void;\n onMessage?: (message: MessengerMessage, conversation: MessengerConversation) => void;\n /** Personalisation: name, page, progress and announcements. Without it the home screen is generic. */\n visitor?: () => MessengerVisitor;\n /** Logo and name shown at the top of the home screen (project theme). */\n brand?: { logoUrl?: string | null; name?: string | null };\n onResumeGuide?: (guideId: string, stepId: string) => void;\n /** The visitor saw these announcements (News tab opened). */\n onNewsSeen?: (ids: string[]) => void;\n hideLauncher?: boolean;\n /** Poll intervals (ms): open thread, and unread badge while closed. */\n pollMs?: { thread: number; background: number };\n}\n\nexport interface MessengerWidget {\n el: HTMLElement;\n open(tab?: MessengerTab): void;\n close(): void;\n toggle(): void;\n isOpen(): boolean;\n /** Opens a new conversation, optionally pre-filling the composer. */\n showNewMessage(text?: string): void;\n openArticle(id: string): void;\n /** Re-reads the visitor (page changed, progress made) and re-renders what is showing. */\n refresh(): void;\n destroy(): void;\n}\n\ntype View = { kind: \"tab\"; tab: MessengerTab } | { kind: \"thread\"; conversationId: string | null } | { kind: \"howto\"; id: string; from: View };\n\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\nfunction chatIcon(doc: Document): SVGSVGElement {\n const svg = doc.createElementNS(SVG_NS, \"svg\");\n svg.setAttribute(\"viewBox\", \"0 0 24 24\");\n svg.setAttribute(\"aria-hidden\", \"true\");\n const path = doc.createElementNS(SVG_NS, \"path\");\n path.setAttribute(\"d\", \"M12 3C6.5 3 2 6.8 2 11.5c0 2.4 1.2 4.6 3.1 6.1L4.5 21l3.9-2c1.1.3 2.3.5 3.6.5 5.5 0 10-3.8 10-8.5S17.5 3 12 3z\");\n svg.appendChild(path);\n return svg;\n}\n\n/** Stroke icons (24×24 viewBox), drawn with currentColor. */\nconst ICONS: Record<string, string[]> = {\n home: [\"M3 10.5 12 3l9 7.5V20a1 1 0 0 1-1 1h-5v-6H9v6H4a1 1 0 0 1-1-1z\"],\n messages: [\"M4 5h16v11H8l-4 4z\"],\n help: [\"M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18z\", \"M9.5 9.5a2.5 2.5 0 1 1 3.5 2.3c-.6.3-1 .8-1 1.5V14\", \"M12 17h.01\"],\n news: [\"M3 11v2a1 1 0 0 0 1 1h2l5 4V6L6 10H4a1 1 0 0 0-1 1z\", \"M15 9a4 4 0 0 1 0 6\", \"M18 6a8 8 0 0 1 0 12\"],\n arrow: [\"M5 12h14\", \"M13 6l6 6-6 6\"],\n close: [\"M6 6l12 12\", \"M18 6 6 18\"],\n back: [\"M15 6l-6 6 6 6\"],\n chevron: [\"m9 6 6 6-6 6\"],\n check: [\"M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18z\", \"m8 12 3 3 5-6\"],\n alert: [\"M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18z\", \"M12 8v4\", \"M12 16h.01\"],\n wrench: [\"M14.7 6.3a4 4 0 0 0-5.4 5.4L4 17l3 3 5.3-5.3a4 4 0 0 0 5.4-5.4l-2.5 2.5-2.4-.6-.6-2.4z\"],\n play: [\"M8 5v14l11-7z\"],\n steps: [\"M9 6h11\", \"M9 12h11\", \"M9 18h11\", \"M4 6h.01\", \"M4 12h.01\", \"M4 18h.01\"],\n article: [\"M6 3h9l4 4v14H6z\", \"M9 12h6\", \"M9 16h6\"],\n ask: [\"M4 5h16v11H8l-4 4z\", \"M9 9.5h6\", \"M9 12.5h4\"],\n search: [\"M11 4a7 7 0 1 0 0 14 7 7 0 0 0 0-14z\", \"m20 20-3.5-3.5\"],\n circle: [\"M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18z\"],\n};\n\nfunction icon(doc: Document, name: keyof typeof ICONS, cls = \"g-m-ico\"): SVGSVGElement {\n const svg = doc.createElementNS(SVG_NS, \"svg\");\n svg.setAttribute(\"viewBox\", \"0 0 24 24\");\n svg.setAttribute(\"aria-hidden\", \"true\");\n svg.setAttribute(\"class\", cls);\n for (const d of ICONS[name] ?? []) {\n const path = doc.createElementNS(SVG_NS, \"path\");\n path.setAttribute(\"d\", d);\n svg.appendChild(path);\n }\n return svg;\n}\n\nconst REPLY_TIME_TEXT: Record<string, string> = {\n minutes: \"typically replies in a few minutes\",\n hour: \"typically replies within an hour\",\n hours: \"typically replies in a few hours\",\n day: \"typically replies within a day\",\n};\n\nconst STATUS_TEXT: Record<MessengerStatus[\"level\"], { title: string; icon: keyof typeof ICONS }> = {\n operational: { title: \"All systems operational\", icon: \"check\" },\n degraded: { title: \"Degraded performance\", icon: \"alert\" },\n outage: { title: \"Service outage\", icon: \"alert\" },\n maintenance: { title: \"Scheduled maintenance\", icon: \"wrench\" },\n};\n\n/** \"Oct 18, 08:12\" in the visitor's locale and time zone. */\nfunction shortDateTime(iso: string): string {\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return \"\";\n try {\n return d.toLocaleString(undefined, { month: \"short\", day: \"numeric\", hour: \"2-digit\", minute: \"2-digit\" });\n } catch {\n return d.toISOString().slice(0, 16).replace(\"T\", \" \");\n }\n}\n\nfunction shortDate(iso: string): string {\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return \"\";\n try {\n return d.toLocaleDateString(undefined, { month: \"short\", day: \"numeric\" });\n } catch {\n return d.toISOString().slice(0, 10);\n }\n}\n\n/** Initials for an avatar fallback (\"Jordan\" → \"J\"). */\nconst initialOf = (name: string) => (name.trim().match(/\\p{L}/u)?.[0] ?? \"?\").toUpperCase();\n\n/** The greeting with a leading \"Hi!\" swapped for the visitor's name (\"Hi! I'm Scout.\" → \"Hi Maya! I'm Scout.\"). */\nexport function personalGreeting(greeting: string, firstName: string | null): string {\n if (!firstName) return greeting;\n const rest = greeting.replace(/^\\s*(hi|hello|hey)( there)?\\s*[!,.]?\\s*/i, \"\");\n return rest ? `Hi ${firstName}! ${rest}` : `Hi ${firstName}!`;\n}\n\nexport function relativeTime(iso: string, now = Date.now()): string {\n const s = Math.max(0, Math.round((now - Date.parse(iso)) / 1000));\n if (!Number.isFinite(s) || s < 60) return \"now\";\n if (s < 3600) return `${Math.floor(s / 60)}m`;\n if (s < 86400) return `${Math.floor(s / 3600)}h`;\n return `${Math.floor(s / 86400)}d`;\n}\n\nfunction ensureStyles(scope: HTMLElement) {\n const root = scope.getRootNode() as ShadowRoot | Document;\n const container = \"host\" in root ? root : scope.ownerDocument.head;\n if (container.querySelector?.(\"style[data-g-messenger]\")) return;\n const style = scope.ownerDocument.createElement(\"style\");\n style.setAttribute(\"data-g-messenger\", \"\");\n style.textContent = MESSENGER_STYLES;\n container.appendChild(style);\n}\n\n/** Intercom-style messenger: launcher + panel with Home, Messages (chat with Scout / the team) and Help tabs. */\nexport function renderMessenger(options: MessengerOptions): MessengerWidget {\n const { scope, config, api } = options;\n const doc = scope.ownerDocument;\n const poll = options.pollMs ?? { thread: 5000, background: 60000 };\n ensureStyles(scope);\n\n let open = false;\n let destroyed = false;\n let view: View = { kind: \"tab\", tab: \"home\" };\n let conversations: MessengerConversation[] = [];\n let messages: MessengerMessage[] = [];\n let current: MessengerConversation | null = null;\n const streaming = new Map<string, string>();\n let sending = false;\n let draft = \"\";\n let articles: SdkArticlesResponse | null = null;\n let articlesLoading = false;\n let threadTimer: ReturnType<typeof setTimeout> | null = null;\n let backgroundTimer: ReturnType<typeof setInterval> | null = null;\n let threadSeq = 0;\n let howTos: SdkHowTosResponse | null = null;\n let howTosSeq = 0;\n /** Loaded how-tos by id; null when it couldn't be loaded (switched off, deleted). */\n const howToCache = new Map<string, SdkHowTo | null>();\n // Page-matched content for the page the visitor is on, refetched when the page changes.\n let page: MessengerPageContent | null = null;\n let pageKey: string | null = null;\n let pageAt = 0;\n let pageSeq = 0;\n let pageLoading = false;\n const PAGE_TTL_MS = 120_000;\n\n const cards = { suggestions: config.home?.suggestions !== false, progress: config.home?.progress !== false, news: config.home?.news !== false };\n const visitor = (): MessengerVisitor => {\n try {\n const v = options.visitor?.();\n if (v) return v;\n } catch {\n /* a broken host callback must not break the messenger */\n }\n return { firstName: null, path: null, pageGuides: [], resumeGuide: null, checklist: null, news: [] };\n };\n const news = () => (cards.news ? visitor().news : []);\n\n const pos = `g-pos-${config.launcher.position}`;\n // Other launchers (checklists, resource center) in the same corner move aside for the chat bubble.\n const rootNode = scope.getRootNode();\n const shadowHost = \"host\" in rootNode ? (rootNode.host as HTMLElement) : null;\n shadowHost?.setAttribute(\"data-g-messenger\", config.launcher.position);\n const root = el(doc, \"div\", \"g-messenger-root\");\n const launcher = el(doc, \"button\", `g-m-launcher ${pos}`);\n launcher.type = \"button\";\n launcher.setAttribute(\"aria-label\", `Open ${config.name}`);\n launcher.setAttribute(\"aria-expanded\", \"false\");\n launcher.appendChild(chatIcon(doc));\n const badge = el(doc, \"span\", \"g-m-badge\");\n badge.hidden = true;\n launcher.appendChild(badge);\n if (options.hideLauncher) launcher.hidden = true;\n\n const panel = el(doc, \"div\", `g-panel g-messenger ${pos}`);\n panel.setAttribute(\"role\", \"dialog\");\n panel.setAttribute(\"aria-label\", config.name);\n panel.hidden = true;\n const head = el(doc, \"div\", \"g-m-head\");\n const main = el(doc, \"div\", \"g-m-main\");\n const tabs = el(doc, \"div\", \"g-m-tabs\");\n tabs.setAttribute(\"role\", \"tablist\");\n panel.append(head, main, tabs);\n root.append(launcher, panel);\n scope.appendChild(root);\n\n const rcExtras = (ids: string[] = []) => ids.map((id) => options.guides?.find((g) => g.id === id || g.key === id)).filter((g): g is HelpGuideRef => !!g);\n const help = createHelpView({\n doc,\n data: (): HelpData => ({\n collections: articles?.collections ?? options.resourceCenter?.collections ?? [],\n articles: articles?.articles ?? options.resourceCenter?.articles ?? [],\n suggested: helpSuggestions(),\n recommended: rcExtras(options.resourceCenter?.recommendedGuideIds),\n checklists: rcExtras(options.resourceCenter?.checklistGuideIds),\n faqs: options.resourceCenter?.faqs,\n links: options.resourceCenter?.links,\n }),\n search: (q) => api.searchArticles(q),\n audienceIds: options.audienceIds,\n loadArticle: (id) => api.getArticle(id),\n onStartGuide: (id) => {\n setOpen(false);\n options.onStartGuide?.(id);\n },\n onOpenChecklist: (id) => {\n setOpen(false);\n options.onOpenChecklist?.(id);\n },\n onArticleView: options.onArticleView,\n extra: (q) => howToItems(q),\n });\n\n const unreadTotal = () => conversations.reduce((n, c) => n + (c.unread > 0 ? 1 : 0), 0);\n const updateBadge = () => {\n const n = unreadTotal();\n badge.hidden = n === 0 || open;\n badge.textContent = n > 9 ? \"9+\" : String(n);\n launcher.setAttribute(\"aria-label\", n ? `Open ${config.name}, ${n} unread` : `Open ${config.name}`);\n };\n\n const upsertConversation = (c: MessengerConversation) => {\n conversations = [c, ...conversations.filter((x) => x.id !== c.id)].sort((a, b) => b.lastMessageAt.localeCompare(a.lastMessageAt));\n if (current?.id === c.id) current = c;\n updateBadge();\n };\n const upsertMessage = (m: MessengerMessage) => {\n const i = messages.findIndex((x) => x.id === m.id);\n if (i >= 0) messages[i] = m;\n else messages.push(m);\n messages.sort((a, b) => a.createdAt.localeCompare(b.createdAt));\n if (m.status !== \"pending\") streaming.delete(m.id);\n };\n\n const loadArticles = () => {\n if (articles || articlesLoading) return;\n articlesLoading = true;\n api\n .listArticles()\n .then((res) => {\n articles = res;\n if (view.kind === \"tab\" && view.tab === \"help\") help.render();\n })\n .catch(() => {})\n .finally(() => (articlesLoading = false));\n };\n\n // How-tos: refreshed on every open, since the page (and so \"Help for this page\") may have changed.\n const loadHowTos = () => {\n if (!api.listHowTos) return;\n const seq = ++howTosSeq;\n api\n .listHowTos()\n .then((res) => {\n if (seq !== howTosSeq || destroyed) return;\n howTos = res;\n if (open && view.kind === \"tab\" && view.tab === \"home\") render();\n else if (open && view.kind === \"tab\" && view.tab === \"help\") help.render();\n })\n .catch(() => {});\n };\n const pageHowTos = (): SdkHowToSummary[] => (howTos?.forPage ?? []).map((id) => howTos?.howTos.find((h) => h.id === id)).filter((h): h is SdkHowToSummary => !!h);\n const stepsLabel = (h: SdkHowToSummary) => `${h.stepCount} ${h.stepCount === 1 ? \"step\" : \"steps\"}`;\n const openHowTo = (id: string) => go({ kind: \"howto\", id, from: view });\n\n /** Help tab search: how-tos matching the query (the page's own are in \"Suggested for this page\"). */\n function howToItems(q: string): Node[] {\n const list = q ? (howTos?.howTos ?? []).filter((h) => h.title.toLowerCase().includes(q) || h.description.toLowerCase().includes(q)).slice(0, 10) : [];\n if (!list.length) return [];\n return [\n el(doc, \"div\", \"g-rc-section\", `How-tos (${list.length})`),\n ...list.map((h) => {\n const b = listItem(doc, \"📋\", h.title, h.description || stepsLabel(h));\n b.addEventListener(\"click\", () => openHowTo(h.id));\n return b;\n }),\n ];\n }\n\n const refreshConversations = () =>\n api\n .listConversations()\n .then((list) => {\n conversations = [...list].sort((a, b) => b.lastMessageAt.localeCompare(a.lastMessageAt));\n updateBadge();\n if (open && view.kind === \"tab\" && view.tab !== \"help\") render();\n })\n .catch(() => {});\n\n // ---------------------------------------------------------------------------\n // Rendering\n // ---------------------------------------------------------------------------\n\n function renderHead(title: string, back?: () => void) {\n head.textContent = \"\";\n head.hidden = false;\n if (back) {\n const b = el(doc, \"button\", \"g-m-back\");\n b.type = \"button\";\n b.setAttribute(\"aria-label\", \"Back\");\n b.appendChild(icon(doc, \"back\"));\n b.addEventListener(\"click\", back);\n head.appendChild(b);\n }\n head.appendChild(el(doc, \"h2\", \"\", title));\n head.appendChild(closeButton(\"g-close\"));\n }\n\n function closeButton(cls: string): HTMLButtonElement {\n const close = el(doc, \"button\", cls);\n close.type = \"button\";\n close.setAttribute(\"aria-label\", \"Close\");\n close.appendChild(icon(doc, \"close\"));\n close.addEventListener(\"click\", () => setOpen(false));\n return close;\n }\n\n function renderTabs() {\n tabs.textContent = \"\";\n tabs.hidden = view.kind !== \"tab\";\n const items: Array<[MessengerTab, keyof typeof ICONS, string]> = [\n [\"home\", \"home\", \"Home\"],\n [\"messages\", \"messages\", \"Messages\"],\n [\"help\", \"help\", \"Help\"],\n ];\n const latest = news();\n if (latest.length) items.push([\"news\", \"news\", \"News\"]);\n for (const [tab, ico, label] of items) {\n const b = el(doc, \"button\", \"g-m-tab\");\n b.type = \"button\";\n b.setAttribute(\"role\", \"tab\");\n b.setAttribute(\"aria-selected\", String(view.kind === \"tab\" && view.tab === tab));\n const i = el(doc, \"span\", \"g-m-tab-icon\");\n i.appendChild(icon(doc, ico));\n b.append(i, el(doc, \"span\", \"\", label));\n if (tab === \"news\" && latest.some((n) => n.unread)) {\n const dot = el(doc, \"span\", \"g-m-tab-dot\");\n dot.setAttribute(\"aria-label\", \"New\");\n i.appendChild(dot);\n }\n b.addEventListener(\"click\", () => go({ kind: \"tab\", tab }));\n tabs.appendChild(b);\n }\n }\n\n function conversationCard(c: MessengerConversation, label?: string): HTMLButtonElement {\n const card = el(doc, \"button\", \"g-m-card\");\n card.type = \"button\";\n const row = el(doc, \"div\", \"g-m-row\");\n if (c.unread > 0) row.appendChild(el(doc, \"span\", \"g-m-dot\"));\n const text = el(doc, \"div\", \"g-m-grow\");\n if (label) text.appendChild(el(doc, \"div\", \"g-m-card-label\", label));\n text.append(el(doc, \"div\", \"g-m-card-title g-m-ellipsis\", c.subject || \"Conversation\"), el(doc, \"div\", \"g-m-card-sub g-m-ellipsis\", c.lastMessagePreview));\n row.append(text, el(doc, \"span\", \"g-m-time\", relativeTime(c.lastMessageAt)));\n card.appendChild(row);\n card.setAttribute(\"aria-label\", `${label ? `${label}: ` : \"\"}${c.subject || \"Conversation\"}${c.unread ? \", unread\" : \"\"}`);\n card.addEventListener(\"click\", () => go({ kind: \"thread\", conversationId: c.id }));\n return card;\n }\n\n /** A full-width card: optional leading icon, title, subtitle and a trailing arrow. */\n function actionCard(opts: { title: string; sub?: string; lead?: SVGSVGElement | HTMLElement; trail?: boolean; onClick: () => void; cls?: string }): HTMLButtonElement {\n const card = el(doc, \"button\", `g-m-card g-m-row g-m-center${opts.cls ? ` ${opts.cls}` : \"\"}`);\n card.type = \"button\";\n if (opts.lead) card.appendChild(opts.lead);\n const text = el(doc, \"span\", \"g-m-grow\");\n text.appendChild(el(doc, \"span\", \"g-m-card-title\", opts.title));\n if (opts.sub) text.appendChild(el(doc, \"span\", \"g-m-card-sub\", opts.sub));\n card.appendChild(text);\n if (opts.trail) card.appendChild(icon(doc, \"arrow\", \"g-m-ico g-m-trail\"));\n card.addEventListener(\"click\", opts.onClick);\n return card;\n }\n\n function progressBar(done: number, total: number): HTMLElement {\n const bar = el(doc, \"span\", \"g-m-bar\");\n bar.setAttribute(\"role\", \"progressbar\");\n bar.setAttribute(\"aria-valuemin\", \"0\");\n bar.setAttribute(\"aria-valuemax\", String(total));\n bar.setAttribute(\"aria-valuenow\", String(done));\n const fill = el(doc, \"span\", \"g-m-bar-fill\");\n fill.style.width = `${total ? Math.round((Math.min(done, total) / total) * 100) : 0}%`;\n bar.appendChild(fill);\n return bar;\n }\n\n function teamAvatars(): HTMLElement | null {\n const team = (config.team ?? []).slice(0, 3);\n if (!team.length) return null;\n const wrap = el(doc, \"div\", \"g-m-team\");\n wrap.setAttribute(\"role\", \"img\");\n wrap.setAttribute(\"aria-label\", `The team: ${team.map((t) => t.name).join(\", \")}`);\n team.forEach((t, i) => {\n const a = el(doc, \"span\", `g-m-avatar g-m-avatar-${i % 3}`);\n if (t.avatarUrl) {\n const img = el(doc, \"img\");\n img.src = t.avatarUrl;\n img.alt = \"\";\n img.referrerPolicy = \"no-referrer\";\n img.addEventListener(\"error\", () => {\n img.remove();\n a.textContent = initialOf(t.name);\n });\n a.appendChild(img);\n } else a.textContent = initialOf(t.name);\n wrap.appendChild(a);\n });\n return wrap;\n }\n\n function brandMark(): HTMLElement {\n const name = options.brand?.name || config.name;\n const mark = el(doc, \"span\", \"g-m-logo\");\n const url = options.brand?.logoUrl;\n if (url && /^(https?:)?\\/\\//.test(url)) {\n const img = el(doc, \"img\");\n img.src = url;\n img.alt = name;\n img.addEventListener(\"error\", () => {\n img.remove();\n mark.textContent = initialOf(name);\n });\n mark.appendChild(img);\n } else {\n mark.textContent = initialOf(name);\n mark.setAttribute(\"aria-label\", name);\n mark.setAttribute(\"role\", \"img\");\n }\n return mark;\n }\n\n function messageSub(): string {\n const reply = config.replyTime ? REPLY_TIME_TEXT[config.replyTime] : null;\n if (config.aiAvailable) return reply ? `${config.name} answers right away. The team ${reply}.` : `${config.name} answers right away, and the team can help too.`;\n return reply ? `The team ${reply}.` : \"The team will reply here.\";\n }\n\n function statusCard(status: MessengerStatus): HTMLElement {\n const meta = STATUS_TEXT[status.level] ?? STATUS_TEXT.operational;\n const card = el(doc, \"div\", `g-m-card g-m-static g-m-row g-m-center g-m-status g-m-status-${status.level}`);\n card.setAttribute(\"role\", \"status\");\n card.appendChild(icon(doc, meta.icon, \"g-m-ico g-m-status-ico\"));\n const text = el(doc, \"span\", \"g-m-grow\");\n text.appendChild(el(doc, \"span\", \"g-m-card-title\", status.message || meta.title));\n const when = shortDateTime(status.updatedAt);\n if (when) text.appendChild(el(doc, \"span\", \"g-m-card-sub\", `Updated ${when}`));\n card.appendChild(text);\n return card;\n }\n\n function progressCards(v: MessengerVisitor): HTMLElement[] {\n const out: HTMLElement[] = [];\n if (v.resumeGuide) {\n const g = v.resumeGuide;\n const card = el(doc, \"button\", \"g-m-card\");\n card.type = \"button\";\n const row = el(doc, \"span\", \"g-m-row g-m-center\");\n row.appendChild(iconTile(\"play\", true));\n const text = el(doc, \"span\", \"g-m-grow\");\n text.append(el(doc, \"span\", \"g-m-card-label\", \"Pick up where you left off\"), el(doc, \"span\", \"g-m-card-title g-m-ellipsis\", g.name), el(doc, \"span\", \"g-m-card-sub\", `Step ${g.stepIndex + 1} of ${g.stepCount}`));\n row.append(text, el(doc, \"span\", \"g-m-link\", \"Resume\"));\n card.append(row, progressBar(g.stepIndex, g.stepCount));\n card.addEventListener(\"click\", () => {\n setOpen(false);\n options.onResumeGuide?.(g.id, g.stepId);\n });\n out.push(card);\n }\n if (v.checklist && v.checklist.total > 0) {\n const c = v.checklist;\n const card = el(doc, \"button\", \"g-m-card\");\n card.type = \"button\";\n const top = el(doc, \"span\", \"g-m-row g-m-baseline\");\n top.append(el(doc, \"span\", \"g-m-card-title g-m-grow g-m-ellipsis\", c.name), el(doc, \"span\", \"g-m-time\", `${c.done} of ${c.total} done`));\n card.append(top, progressBar(c.done, c.total));\n if (c.nextTask) card.appendChild(el(doc, \"span\", \"g-m-card-sub\", `Next: ${c.nextTask}`));\n card.addEventListener(\"click\", () => {\n setOpen(false);\n options.onOpenChecklist?.(c.id);\n });\n out.push(card);\n }\n return out;\n }\n\n function iconTile(name: keyof typeof ICONS, accent = false): HTMLElement {\n const b = el(doc, \"span\", `g-m-badge-ico${accent ? \" g-m-accent\" : \"\"}`);\n b.appendChild(icon(doc, name));\n return b;\n }\n\n interface Suggestion {\n icon: keyof typeof ICONS;\n title: string;\n sub: string;\n accent?: boolean;\n run: () => void;\n }\n\n /**\n * Page-aware suggestions: guides targeted here, how-tos made available in the app that were recorded\n * on this page (they open right here), then how-tos and articles matched by the server.\n */\n function pageSuggestions(v: MessengerVisitor, max = 4): Suggestion[] {\n if (!cards.suggestions) return [];\n const out: Suggestion[] = [];\n for (const g of v.pageGuides.slice(0, 2)) {\n out.push({ icon: \"play\", title: g.name, sub: g.kind === \"checklist\" ? \"Checklist\" : \"Interactive guide\", accent: true, run: () => (g.kind === \"checklist\" ? openChecklist(g.id) : startGuide(g.key || g.id)) });\n }\n const inApp = new Set<string>();\n for (const h of pageHowTos()) {\n if (out.length >= max) break;\n inApp.add(h.title.toLowerCase());\n out.push({ icon: \"steps\", title: h.title, sub: `How-to · ${stepsLabel(h)}`, run: () => openHowTo(h.id) });\n }\n for (const s of page?.suggestions ?? []) {\n if (out.length >= max) break;\n // The same how-to's help article, when it's already listed to open in place.\n if (s.type === \"howto\" && inApp.has(s.title.toLowerCase())) continue;\n if (s.type === \"howto\") out.push({ icon: \"steps\", title: s.title, sub: `How-to · ${s.steps} ${s.steps === 1 ? \"step\" : \"steps\"}`, run: () => openArticle(s.articleId) });\n else out.push({ icon: \"article\", title: s.title, sub: s.summary || \"Article\", run: () => openArticle(s.articleId) });\n }\n return out.slice(0, max);\n }\n\n function startGuide(keyOrId: string) {\n setOpen(false);\n options.onStartGuide?.(keyOrId);\n }\n\n function openChecklist(id: string) {\n setOpen(false);\n options.onOpenChecklist?.(id);\n }\n\n /** Asks Scout one of the page's common questions in a new conversation. */\n function ask(question: string) {\n go({ kind: \"thread\", conversationId: null });\n if (!textarea) return;\n textarea.value = question;\n submit();\n }\n\n function suggestionButton(s: Suggestion): HTMLButtonElement {\n const b = el(doc, \"button\", \"g-m-item\");\n b.type = \"button\";\n b.appendChild(iconTile(s.icon, s.accent));\n const text = el(doc, \"span\", \"g-m-grow\");\n text.append(el(doc, \"span\", \"g-m-item-title\", s.title), el(doc, \"span\", \"g-m-card-sub g-m-ellipsis\", s.sub));\n b.appendChild(text);\n b.addEventListener(\"click\", s.run);\n return b;\n }\n\n function newsCard(n: MessengerNewsItem): HTMLButtonElement {\n const card = el(doc, \"button\", \"g-m-card g-m-news\");\n card.type = \"button\";\n if (n.imageUrl && /^https?:\\/\\//.test(n.imageUrl)) {\n const img = el(doc, \"img\", \"g-m-news-img\");\n img.src = n.imageUrl;\n img.alt = \"\";\n img.loading = \"lazy\";\n img.addEventListener(\"error\", () => img.remove());\n card.appendChild(img);\n }\n const body = el(doc, \"span\", \"g-m-news-body\");\n const meta = el(doc, \"span\", \"g-m-row g-m-center g-m-news-meta\");\n if (n.unread) meta.appendChild(el(doc, \"span\", \"g-m-tag\", \"New\"));\n meta.appendChild(el(doc, \"span\", \"g-m-time\", shortDate(n.publishedAt)));\n body.append(meta, el(doc, \"span\", \"g-m-card-title\", n.title));\n if (n.body) body.appendChild(el(doc, \"span\", \"g-m-card-sub g-m-clamp\", n.body));\n card.appendChild(body);\n card.addEventListener(\"click\", () => startGuide(n.key || n.id));\n return card;\n }\n\n function renderHome() {\n head.hidden = true;\n const v = visitor();\n loadPage();\n const scroll = el(doc, \"div\", \"g-m-scroll g-m-home\");\n const hero = el(doc, \"div\", \"g-m-hero-bg\");\n hero.setAttribute(\"aria-hidden\", \"true\");\n const inner = el(doc, \"div\", \"g-m-home-inner\");\n const top = el(doc, \"div\", \"g-m-hero-top\");\n const right = el(doc, \"div\", \"g-m-row g-m-center\");\n const team = teamAvatars();\n if (team) right.appendChild(team);\n right.appendChild(closeButton(\"g-m-hero-close\"));\n top.append(brandMark(), right);\n const hello = el(doc, \"h2\", \"g-m-hello\");\n hello.append(el(doc, \"span\", \"g-m-hello-1\", v.firstName ? `Hi ${v.firstName}.` : \"Hi there.\"), el(doc, \"span\", \"g-m-hello-2\", \"How can we help?\"));\n inner.append(top, hello);\n\n inner.appendChild(actionCard({ title: \"Send us a message\", sub: messageSub(), trail: true, onClick: () => go({ kind: \"thread\", conversationId: null }) }));\n const recent = conversations[0];\n if (recent) inner.appendChild(conversationCard(recent, recent.status === \"closed\" && !recent.unread ? \"Recent conversation\" : \"Continue the conversation\"));\n if (config.status) inner.appendChild(statusCard(config.status));\n if (cards.progress) progressCards(v).forEach((c) => inner.appendChild(c));\n\n const suggestions = pageSuggestions(v);\n const questions = cards.suggestions ? (page?.questions ?? []).slice(0, 2) : [];\n const label = v.path ? pageLabel(v.path) : null;\n const fallback = !suggestions.length && !questions.length ? rcExtras(options.resourceCenter?.recommendedGuideIds).slice(0, 3) : [];\n if (suggestions.length || questions.length || fallback.length) {\n const box = el(doc, \"div\", \"g-m-card g-m-static g-m-suggest\");\n box.appendChild(el(doc, \"div\", \"g-m-card-title\", fallback.length ? \"Recommended\" : \"Suggested for you\"));\n if (!fallback.length && label) box.appendChild(el(doc, \"div\", \"g-m-card-sub\", `For the ${label} page`));\n const list = el(doc, \"div\", \"g-m-items\");\n suggestions.forEach((s) => list.appendChild(suggestionButton(s)));\n questions.forEach((q) => list.appendChild(suggestionButton({ icon: \"ask\", title: q, sub: config.aiAvailable ? `Ask ${config.name}` : \"Ask the team\", run: () => ask(q) })));\n fallback.forEach((g) => list.appendChild(suggestionButton({ icon: \"play\", title: g.name, sub: \"Interactive guide\", accent: true, run: () => startGuide(g.key || g.id) })));\n box.appendChild(list);\n inner.appendChild(box);\n }\n\n const latest = news()[0];\n if (latest) inner.appendChild(newsCard(latest));\n inner.appendChild(actionCard({ title: \"Search for help\", sub: \"Articles, guides and how-tos\", lead: icon(doc, \"search\", \"g-m-ico g-m-lead\"), onClick: () => go({ kind: \"tab\", tab: \"help\" }) }));\n scroll.append(hero, inner);\n main.appendChild(scroll);\n }\n\n function renderHowToView(id: string, from: View) {\n const cached = howToCache.get(id);\n renderHead(cached?.title ?? \"How-to\", () => go(from));\n const scroll = el(doc, \"div\", \"g-m-scroll\");\n if (cached) {\n scroll.appendChild(\n renderHowTo(doc, cached, (key) => {\n setOpen(false);\n options.onStartGuide?.(key);\n }),\n );\n } else scroll.appendChild(el(doc, \"div\", \"g-m-empty\", cached === null ? \"This how-to isn't available any more.\" : \"Loading…\"));\n main.appendChild(scroll);\n if (cached !== undefined || !api.getHowTo) return;\n const seq = threadSeq;\n api\n .getHowTo(id)\n .catch(() => null)\n .then((h) => {\n howToCache.set(id, h);\n if (seq === threadSeq && view.kind === \"howto\" && view.id === id) render();\n });\n }\n\n function renderMessagesTab() {\n renderHead(\"Messages\");\n const scroll = el(doc, \"div\", \"g-m-scroll\");\n if (!conversations.length) scroll.appendChild(el(doc, \"div\", \"g-m-empty\", \"No conversations yet.\"));\n conversations.forEach((c) => scroll.appendChild(conversationCard(c)));\n const start = el(doc, \"button\", \"g-btn g-btn-primary g-m-wide\", \"Send us a message\");\n start.type = \"button\";\n start.addEventListener(\"click\", () => go({ kind: \"thread\", conversationId: null }));\n scroll.appendChild(start);\n main.appendChild(scroll);\n }\n\n /** The Help tab's \"Suggested for this page\" section. */\n function helpSuggestions(): HelpData[\"suggested\"] {\n const v = visitor();\n const items = pageSuggestions(v, 5).map<HelpSuggestion>((s) => ({ kind: s.icon === \"play\" ? \"guide\" : s.icon === \"steps\" ? \"howto\" : \"article\", title: s.title, summary: s.sub, run: s.run }));\n if (!items.length) return undefined;\n const label = v.path ? pageLabel(v.path) : null;\n return { title: label ? `For the ${label} page` : \"Suggested for you\", items };\n }\n\n function renderHelpTab() {\n renderHead(\"Help\");\n loadArticles();\n loadPage();\n help.render();\n main.appendChild(help.el);\n }\n\n function renderNewsTab() {\n renderHead(\"News\");\n const scroll = el(doc, \"div\", \"g-m-scroll\");\n const items = news();\n if (!items.length) scroll.appendChild(el(doc, \"div\", \"g-m-empty\", \"No news yet.\"));\n items.forEach((n) => scroll.appendChild(newsCard(n)));\n main.appendChild(scroll);\n const unread = items.filter((n) => n.unread).map((n) => n.id);\n if (unread.length) options.onNewsSeen?.(unread);\n }\n\n /** Fetches page-matched content when the page changed (or it went stale), then re-renders. */\n function loadPage(force = false) {\n const path = visitor().path;\n if (!path || !api.pageContent || !cards.suggestions) {\n page = null;\n pageKey = null;\n return;\n }\n const key = foldPathIds(path).toLowerCase();\n if (!force && key === pageKey && (pageLoading || Date.now() - pageAt < PAGE_TTL_MS)) return;\n if (key !== pageKey) page = null;\n pageKey = key;\n pageLoading = true;\n const seq = ++pageSeq;\n api\n .pageContent(path)\n .then((res) => {\n if (seq !== pageSeq) return;\n page = res;\n pageAt = Date.now();\n if (!open) return;\n if (view.kind === \"tab\" && view.tab === \"home\") render();\n else if (view.kind === \"tab\" && view.tab === \"help\") help.render();\n else if (view.kind === \"thread\" && !messages.length) renderLog();\n })\n .catch(() => {\n if (seq === pageSeq) pageAt = Date.now();\n })\n .finally(() => {\n if (seq === pageSeq) pageLoading = false;\n });\n }\n\n let log: HTMLElement | null = null;\n let foot: HTMLElement | null = null;\n let textarea: HTMLTextAreaElement | null = null;\n let sendButton: HTMLButtonElement | null = null;\n\n function messageNode(m: MessengerMessage): HTMLElement {\n const wrap = el(doc, \"div\", `g-m-msg g-from-${m.author}${m.status === \"failed\" ? \" g-m-failed\" : \"\"}`);\n if (m.author === \"system\") {\n wrap.textContent = m.body;\n return wrap;\n }\n if (m.author !== \"user\") {\n const author = el(doc, \"div\", \"g-m-author\", m.author === \"scout\" ? config.name : m.authorName || \"Support team\");\n if (m.author === \"scout\") author.appendChild(el(doc, \"span\", \"g-m-ai\", \"AI\"));\n wrap.appendChild(author);\n }\n const bubble = el(doc, \"div\", \"g-m-bubble\");\n const live = streaming.get(m.id);\n if (m.status === \"pending\" && !live) {\n const dots = el(doc, \"span\", \"g-m-typing\");\n dots.setAttribute(\"aria-label\", `${config.name} is typing`);\n dots.append(el(doc, \"span\"), el(doc, \"span\"), el(doc, \"span\"));\n bubble.appendChild(dots);\n } else if (m.status === \"failed\") {\n bubble.textContent = \"This reply couldn't be completed.\";\n } else {\n bubble.appendChild(renderSafeText(doc, live ?? m.body));\n }\n if (m.status === \"pending\") bubble.setAttribute(\"aria-busy\", \"true\");\n bubble.dataset.messageId = m.id;\n wrap.appendChild(bubble);\n if (m.citations.length || m.suggestedGuides.length || m.howTos?.length) {\n const chips = el(doc, \"div\", \"g-m-chips\");\n for (const g of m.suggestedGuides) {\n const b = el(doc, \"button\", \"g-m-chip g-m-guide\", `▶ Show me: ${g.name}`);\n b.type = \"button\";\n b.addEventListener(\"click\", () => {\n setOpen(false);\n options.onStartGuide?.(g.key);\n });\n chips.appendChild(b);\n }\n for (const c of m.citations) {\n const b = el(doc, \"button\", \"g-m-chip\", `📄 ${c.title}`);\n b.type = \"button\";\n b.addEventListener(\"click\", () => openArticle(c.articleId));\n chips.appendChild(b);\n }\n for (const h of m.howTos ?? []) {\n const b = el(doc, \"button\", \"g-m-chip\", `📋 ${h.title}`);\n b.type = \"button\";\n b.addEventListener(\"click\", () => openHowTo(h.howToId));\n chips.appendChild(b);\n }\n wrap.appendChild(chips);\n }\n return wrap;\n }\n\n function renderLog() {\n if (!log) return;\n const atBottom = log.scrollHeight - log.scrollTop - log.clientHeight < 40;\n log.textContent = \"\";\n if (!messages.length) {\n const v = visitor();\n const label = v.path ? pageLabel(v.path) : null;\n if (label && config.aiAvailable && !current) log.appendChild(el(doc, \"div\", \"g-m-context\", `Asking from the ${label} page`));\n const intro: MessengerMessage = { id: \"intro\", author: config.aiAvailable ? \"scout\" : \"agent\", authorName: \"Support team\", body: personalGreeting(config.greeting, v.firstName), citations: [], suggestedGuides: [], status: \"complete\", createdAt: new Date().toISOString() };\n log.appendChild(messageNode(intro));\n const questions = !current && cards.suggestions ? (page?.questions ?? []) : [];\n if (questions.length && !sending) {\n const chips = el(doc, \"div\", \"g-m-chips g-m-asks\");\n chips.setAttribute(\"aria-label\", \"Common questions on this page\");\n for (const q of questions) {\n const b = el(doc, \"button\", \"g-m-chip g-m-ask\", q);\n b.type = \"button\";\n b.addEventListener(\"click\", () => {\n if (!textarea || sending) return;\n textarea.value = q;\n submit();\n });\n chips.appendChild(b);\n }\n log.appendChild(chips);\n }\n }\n messages.forEach((m) => log!.appendChild(messageNode(m)));\n if (atBottom || sending) log.scrollTop = log.scrollHeight;\n renderFoot();\n }\n\n function renderFoot() {\n if (!foot || !textarea || !sendButton) return;\n sendButton.disabled = sending || !textarea.value.trim();\n textarea.disabled = sending;\n for (const extra of Array.from(foot.querySelectorAll(\".g-m-human,.g-m-rate,.g-m-note\"))) extra.remove();\n if (current?.status === \"closed\" && current.rating == null) {\n const rate = el(doc, \"div\", \"g-m-rate\", \"How was this conversation? \");\n for (const [score, face, label] of [\n [1, \"😞\", \"Bad\"],\n [3, \"😐\", \"OK\"],\n [5, \"😀\", \"Great\"],\n ] as const) {\n const b = el(doc, \"button\", \"\", face);\n b.type = \"button\";\n b.setAttribute(\"aria-label\", label);\n b.addEventListener(\"click\", () => {\n if (!current) return;\n const id = current.id;\n current = { ...current, rating: score };\n upsertConversation(current);\n renderFoot();\n api.rate(id, score).catch(() => {});\n });\n rate.appendChild(b);\n }\n foot.prepend(rate);\n } else if (current && current.rating != null && current.status === \"closed\") {\n foot.prepend(el(doc, \"div\", \"g-m-note\", \"Thanks for the feedback!\"));\n }\n if (config.handoffEnabled && config.aiAvailable && current?.status === \"bot\" && !sending) {\n const human = el(doc, \"button\", \"g-m-human\", \"Talk to a person\");\n human.type = \"button\";\n human.addEventListener(\"click\", () => {\n if (!current) return;\n const id = current.id;\n human.disabled = true;\n api\n .handoff(id)\n .then((res) => {\n if (current?.id !== id) return;\n upsertConversation(res.conversation);\n res.messages.forEach(upsertMessage);\n renderLog();\n })\n .catch(() => (human.disabled = false));\n });\n foot.appendChild(human);\n }\n }\n\n function renderThread(conversationId: string | null) {\n renderHead(current?.subject || (conversationId ? \"Conversation\" : \"New conversation\"), () => go({ kind: \"tab\", tab: \"messages\" }));\n log = el(doc, \"div\", \"g-m-log\");\n log.setAttribute(\"role\", \"log\");\n log.setAttribute(\"aria-live\", \"polite\");\n foot = el(doc, \"div\", \"g-m-foot\");\n const compose = el(doc, \"form\", \"g-m-compose\");\n textarea = el(doc, \"textarea\");\n textarea.rows = 1;\n textarea.maxLength = 4000;\n textarea.placeholder = current?.status === \"open\" ? \"Reply to the team…\" : \"Ask a question…\";\n textarea.setAttribute(\"aria-label\", \"Message\");\n textarea.value = draft;\n sendButton = el(doc, \"button\", \"g-m-send\");\n sendButton.appendChild(icon(doc, \"arrow\"));\n sendButton.type = \"submit\";\n sendButton.setAttribute(\"aria-label\", \"Send\");\n compose.append(textarea, sendButton);\n foot.appendChild(compose);\n textarea.addEventListener(\"input\", () => {\n draft = textarea!.value;\n if (sendButton) sendButton.disabled = sending || !draft.trim();\n });\n textarea.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\" && !e.shiftKey && !e.isComposing) {\n e.preventDefault();\n submit();\n }\n });\n compose.addEventListener(\"submit\", (e) => {\n e.preventDefault();\n submit();\n });\n main.append(log, foot);\n renderLog();\n textarea.focus?.({ preventScroll: true });\n }\n\n function render() {\n if (destroyed) return;\n main.textContent = \"\";\n log = foot = null;\n textarea = null;\n sendButton = null;\n if (view.kind === \"thread\") renderThread(view.conversationId);\n else if (view.kind === \"howto\") renderHowToView(view.id, view.from);\n else if (view.tab === \"home\") renderHome();\n else if (view.tab === \"messages\") renderMessagesTab();\n else if (view.tab === \"news\" && news().length) renderNewsTab();\n else if (view.tab === \"news\") {\n view = { kind: \"tab\", tab: \"home\" };\n renderHome();\n } else renderHelpTab();\n renderTabs();\n }\n\n // ---------------------------------------------------------------------------\n // Behaviour\n // ---------------------------------------------------------------------------\n\n const handlers = (seq: number): MessengerStreamHandlers => ({\n onConversation(c) {\n if (seq !== threadSeq) return;\n current = c;\n view = { kind: \"thread\", conversationId: c.id };\n upsertConversation(c);\n },\n onMessage(m) {\n if (seq !== threadSeq) return;\n upsertMessage(m);\n renderLog();\n },\n onDelta(id, text) {\n if (seq !== threadSeq) return;\n streaming.set(id, (streaming.get(id) ?? \"\") + text);\n const bubble = log?.querySelector<HTMLElement>(`[data-message-id=\"${id}\"]`);\n if (!bubble) return renderLog();\n bubble.textContent = \"\";\n bubble.appendChild(renderSafeText(doc, streaming.get(id)!));\n if (log) log.scrollTop = log.scrollHeight;\n },\n onDone(m, c) {\n if (seq !== threadSeq) return;\n if (m) {\n upsertMessage(m);\n options.onMessage?.(m, c);\n }\n upsertConversation({ ...c, unread: 0 });\n current = { ...c, unread: 0 };\n },\n onError() {\n /* the server also stores a system message explaining what happened */\n },\n });\n\n function submit() {\n if (!textarea || sending) return;\n const text = textarea.value.trim();\n if (!text) return;\n sending = true;\n draft = \"\";\n textarea.value = \"\";\n renderFoot();\n const seq = threadSeq;\n const h = handlers(seq);\n const done = current ? api.send(current.id, text, h) : api.start(text, h);\n done\n .catch(() => {\n if (seq !== threadSeq) return;\n draft = text;\n if (textarea) textarea.value = text;\n const note: MessengerMessage = { id: `local_${Date.now()}`, author: \"system\", body: \"Your message couldn't be sent. Please try again.\", citations: [], suggestedGuides: [], status: \"complete\", createdAt: new Date().toISOString() };\n upsertMessage(note);\n })\n .finally(() => {\n if (seq !== threadSeq) return;\n sending = false;\n streaming.clear();\n if (view.kind === \"thread\") {\n if (current) renderHead(current.subject || \"Conversation\", () => go({ kind: \"tab\", tab: \"messages\" }));\n renderLog();\n }\n scheduleThreadPoll();\n });\n }\n\n function scheduleThreadPoll() {\n if (threadTimer) clearTimeout(threadTimer);\n threadTimer = null;\n if (!open || view.kind !== \"thread\" || !current || destroyed) return;\n threadTimer = setTimeout(pollThread, poll.thread);\n }\n\n function pollThread() {\n if (!current || sending) return scheduleThreadPoll();\n const seq = threadSeq;\n const pending = messages.find((m) => m.status === \"pending\");\n const last = messages.filter((m) => !m.id.startsWith(\"local_\")).at(-1);\n // Re-fetch from a pending reply (its body changes in place); otherwise only newer messages.\n const since = pending ? new Date(Date.parse(pending.createdAt) - 1).toISOString() : (last?.createdAt ?? null);\n api\n .loadMessages(current.id, since)\n .then((res) => {\n if (seq !== threadSeq) return;\n const before = messages.length;\n const changed = res.messages.some((m) => {\n const prev = messages.find((x) => x.id === m.id);\n return !prev || prev.status !== m.status || prev.body !== m.body;\n });\n res.messages.forEach(upsertMessage);\n upsertConversation({ ...res.conversation, unread: 0 });\n current = { ...res.conversation, unread: 0 };\n if (changed || messages.length !== before) {\n renderLog();\n res.messages.filter((m) => m.author !== \"user\").forEach((m) => options.onMessage?.(m, res.conversation));\n } else renderFoot();\n })\n .catch(() => {})\n .finally(scheduleThreadPoll);\n }\n\n function go(next: View) {\n threadSeq++;\n if (threadTimer) clearTimeout(threadTimer);\n threadTimer = null;\n // Opening a how-to from Help keeps the search, so Back returns to the same results.\n if (view.kind === \"tab\" && view.tab === \"help\" && !(next.kind === \"tab\" && next.tab === \"help\") && next.kind !== \"howto\") help.reset();\n view = next;\n if (next.kind === \"thread\") {\n messages = [];\n streaming.clear();\n sending = false;\n current = next.conversationId ? (conversations.find((c) => c.id === next.conversationId) ?? null) : null;\n if (!next.conversationId) loadPage();\n render();\n if (next.conversationId) {\n const seq = threadSeq;\n api\n .loadMessages(next.conversationId)\n .then((res) => {\n if (seq !== threadSeq) return;\n res.messages.forEach(upsertMessage);\n current = { ...res.conversation, unread: 0 };\n upsertConversation(current);\n renderHead(current.subject || \"Conversation\", () => go({ kind: \"tab\", tab: \"messages\" }));\n renderLog();\n })\n .catch(() => {})\n .finally(scheduleThreadPoll);\n }\n } else {\n draft = \"\";\n render();\n }\n }\n\n function openArticle(id: string) {\n go({ kind: \"tab\", tab: \"help\" });\n help.openArticle(id);\n }\n\n function startBackgroundPoll() {\n if (backgroundTimer) clearInterval(backgroundTimer);\n backgroundTimer = setInterval(() => {\n if (!open && conversations.length && !destroyed) void refreshConversations();\n }, poll.background);\n }\n\n const setOpen = (v: boolean) => {\n if (open === v || destroyed) return;\n open = v;\n panel.hidden = !v;\n launcher.setAttribute(\"aria-expanded\", String(v));\n launcher.setAttribute(\"aria-label\", v ? `Close ${config.name}` : `Open ${config.name}`);\n updateBadge();\n if (v) {\n render();\n void refreshConversations();\n loadHowTos();\n if (view.kind === \"thread\") scheduleThreadPoll();\n options.onOpen?.();\n } else {\n if (threadTimer) clearTimeout(threadTimer);\n threadTimer = null;\n options.onClose?.();\n }\n };\n launcher.addEventListener(\"click\", () => setOpen(!open));\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n e.stopPropagation();\n setOpen(false);\n launcher.focus();\n }\n };\n panel.addEventListener(\"keydown\", onKey);\n\n void refreshConversations();\n startBackgroundPoll();\n\n return {\n el: root,\n open(tab?: MessengerTab) {\n if (tab) view = { kind: \"tab\", tab };\n if (open && tab) render();\n setOpen(true);\n },\n close: () => setOpen(false),\n toggle: () => setOpen(!open),\n isOpen: () => open,\n showNewMessage(text?: string) {\n setOpen(true);\n go({ kind: \"thread\", conversationId: null });\n if (text && textarea) {\n textarea.value = text.slice(0, 4000);\n draft = textarea.value;\n renderFoot();\n }\n },\n openArticle(id: string) {\n setOpen(true);\n openArticle(id);\n },\n refresh() {\n if (destroyed) return;\n if (!open) {\n // Refetched on the next open; the tab bar (News) may change meanwhile.\n pageKey = null;\n return;\n }\n loadPage();\n if (view.kind === \"tab\") render();\n else if (!messages.length) renderLog();\n },\n destroy() {\n destroyed = true;\n if (threadTimer) clearTimeout(threadTimer);\n if (backgroundTimer) clearInterval(backgroundTimer);\n panel.removeEventListener(\"keydown\", onKey);\n help.destroy();\n shadowHost?.removeAttribute(\"data-g-messenger\");\n root.remove();\n },\n };\n}\n","import type { ResourceCenterArticle, ResourceCenterConfig } from \"@guidelytech/shared\";\nimport { isArticleListed, resourceCenterSections } from \"@guidelytech/shared/runtime\";\nimport { enhancePdfViewers } from \"./pdf-viewer\";\nimport { setSanitizedHtml } from \"./sanitize\";\n\nexport interface HelpGuideRef {\n id: string;\n key: string;\n name: string;\n kind: string;\n}\n\n/** A page-aware suggestion at the top of the help view (the messenger works out what and how it opens). */\nexport interface HelpSuggestion {\n kind: \"guide\" | \"howto\" | \"article\";\n title: string;\n summary?: string;\n run: () => void;\n}\n\n/** What the help view lists. Article bodies may be missing (`bodyOmitted` or summaries only): they load on open. */\nexport interface HelpData {\n collections: ResourceCenterConfig[\"collections\"];\n articles: Array<Omit<ResourceCenterArticle, \"body\"> & { body?: string }>;\n /** Shown first, under its own title (\"For the Invoices page\"). */\n suggested?: { title: string; items: HelpSuggestion[] };\n recommended?: HelpGuideRef[];\n checklists?: HelpGuideRef[];\n faqs?: ResourceCenterConfig[\"faqs\"];\n links?: ResourceCenterConfig[\"links\"];\n}\n\nexport interface HelpViewOptions {\n doc: Document;\n data: () => HelpData;\n /** Server search. Results are merged with the client-side title/summary filter. */\n search?: (q: string) => Promise<ResourceCenterArticle[]>;\n /** The visitor's audiences; articles and collections targeted at others aren't listed. */\n audienceIds?: () => ReadonlySet<string> | readonly string[];\n /** Loads an article body that isn't in `data()`. */\n loadArticle?: (id: string) => Promise<ResourceCenterArticle | null>;\n onStartGuide?: (guideId: string) => void;\n onOpenChecklist?: (guideId: string) => void;\n onArticleView?: (article: ResourceCenterArticle) => void;\n /** Extra items above the list (`query` empty) or above the article results (the messenger's how-tos). */\n extra?: (query: string) => Node[];\n}\n\nexport interface HelpView {\n /** Search box + scrollable body. */\n el: HTMLElement;\n render(): void;\n /** Back to the article list and clear the search. */\n reset(): void;\n openArticle(id: string): void;\n focusSearch(): void;\n setQuery(q: string): void;\n destroy(): void;\n}\n\nexport function el<K extends keyof HTMLElementTagNameMap>(doc: Document, tag: K, cls?: string, text?: string): HTMLElementTagNameMap[K] {\n const e = doc.createElement(tag);\n if (cls) e.className = cls;\n if (text != null) e.textContent = text;\n return e;\n}\n\nexport function listItem(doc: Document, icon: string, title: string, summary?: string): HTMLButtonElement {\n const b = el(doc, \"button\", \"g-rc-item\");\n b.type = \"button\";\n const i = el(doc, \"span\", \"g-rc-icon\", icon);\n i.setAttribute(\"aria-hidden\", \"true\");\n const text = el(doc, \"span\");\n text.appendChild(el(doc, \"div\", \"g-rc-title\", title));\n if (summary) text.appendChild(el(doc, \"div\", \"g-rc-sum\", summary));\n b.append(i, text);\n return b;\n}\n\ntype ListedArticle = HelpData[\"articles\"][number];\n\n/** Article browser shared by the resource center and the messenger Help tab. */\nexport function createHelpView(options: HelpViewOptions): HelpView {\n const { doc } = options;\n let query = \"\";\n let serverResults: ResourceCenterArticle[] = [];\n let searchSeq = 0;\n let openSeq = 0;\n let active: { article: ListedArticle; loading: boolean } | null = null;\n\n const root = el(doc, \"div\", \"g-help\");\n const searchWrap = el(doc, \"div\", \"g-rc-search\");\n const input = el(doc, \"input\", \"g-input\");\n input.type = \"search\";\n input.placeholder = \"Search help articles…\";\n input.setAttribute(\"aria-label\", \"Search help articles\");\n searchWrap.appendChild(input);\n const body = el(doc, \"div\", \"g-panel-body\");\n root.append(searchWrap, body);\n\n const hasBody = (a: ListedArticle): a is ResourceCenterArticle => typeof a.body === \"string\" && !a.bodyOmitted;\n\n const openArticle = (article: ListedArticle) => {\n if (article.externalUrl) {\n window.open(article.externalUrl, \"_blank\", \"noopener,noreferrer\");\n if (hasBody(article)) options.onArticleView?.(article);\n return;\n }\n const seq = ++openSeq;\n if (hasBody(article) || !options.loadArticle) {\n active = { article, loading: false };\n if (hasBody(article)) options.onArticleView?.(article);\n return render();\n }\n active = { article, loading: true };\n render();\n options\n .loadArticle(article.id)\n .then((full) => {\n if (seq !== openSeq || !active) return;\n active = { article: full ?? { ...article, body: \"\" }, loading: false };\n if (full) options.onArticleView?.(full);\n render();\n })\n .catch(() => {\n if (seq !== openSeq || !active) return;\n active = { article: { ...article, body: \"\" }, loading: false };\n render();\n });\n };\n\n const renderArticle = ({ article, loading }: NonNullable<typeof active>) => {\n const wrap = el(doc, \"div\", \"g-rc-article\");\n const back = el(doc, \"button\", \"g-btn g-btn-link g-rc-back\", \"← Back\");\n back.type = \"button\";\n back.addEventListener(\"click\", () => {\n openSeq++;\n active = null;\n render();\n });\n const title = el(doc, \"h3\", \"g-title\", article.title);\n const content = el(doc, \"div\", \"g-body\");\n if (loading) content.appendChild(el(doc, \"div\", \"g-rc-empty\", \"Loading…\"));\n else if (article.body) {\n setSanitizedHtml(content, article.body);\n enhancePdfViewers(content, doc);\n }\n else content.appendChild(el(doc, \"div\", \"g-rc-empty\", \"This article couldn't be loaded.\"));\n wrap.append(back, title, content);\n body.appendChild(wrap);\n back.focus?.({ preventScroll: true });\n };\n\n const section = (label: string, depth = 0) => {\n const s = body.appendChild(el(doc, \"div\", \"g-rc-section\", label));\n if (depth) s.dataset.depth = String(depth);\n return s;\n };\n const articleButton = (a: ListedArticle) => {\n const b = listItem(doc, \"📄\", a.title, a.summary);\n b.addEventListener(\"click\", () => openArticle(a));\n body.appendChild(b);\n };\n\n function render() {\n body.textContent = \"\";\n if (active) return renderArticle(active);\n const data = options.data();\n const member = options.audienceIds?.() ?? [];\n const sections = resourceCenterSections(data.collections, data.articles, member);\n const q = query.trim().toLowerCase();\n body.append(...(options.extra?.(q) ?? []));\n if (q) {\n const visible = sections.flatMap((s) => s.articles);\n const local = visible.filter((a) => a.title.toLowerCase().includes(q) || a.summary.toLowerCase().includes(q));\n const seen = new Set(local.map((a) => a.id));\n // Server search covers every published article: keep only the ones listed for this visitor.\n const hidden = new Set(data.articles.map((a) => a.id).filter((id) => !visible.some((v) => v.id === id)));\n const merged: ListedArticle[] = [...local, ...serverResults.filter((a) => !seen.has(a.id) && !hidden.has(a.id) && isArticleListed(data.collections, a, member))];\n section(`Results (${merged.length})`);\n if (!merged.length) body.appendChild(el(doc, \"div\", \"g-rc-empty\", \"No articles match your search.\"));\n merged.forEach(articleButton);\n return;\n }\n if (data.suggested?.items.length) {\n section(data.suggested.title);\n const glyph = { guide: \"▶\", howto: \"☰\", article: \"📄\" } as const;\n data.suggested.items.forEach((item) => {\n const b = listItem(doc, glyph[item.kind], item.title, item.summary);\n b.addEventListener(\"click\", item.run);\n body.appendChild(b);\n });\n }\n if (data.recommended?.length) {\n section(\"Recommended\");\n data.recommended.forEach((g) => {\n const b = listItem(doc, \"▶\", g.name, \"Start guide\");\n b.addEventListener(\"click\", () => options.onStartGuide?.(g.id));\n body.appendChild(b);\n });\n }\n if (data.checklists?.length) {\n section(\"Checklists\");\n data.checklists.forEach((g) => {\n const b = listItem(doc, \"☑\", g.name, \"Open checklist\");\n b.addEventListener(\"click\", () => options.onOpenChecklist?.(g.id));\n body.appendChild(b);\n });\n }\n // Nested collections read as \"Billing › Invoices\", depth first.\n for (const s of sections) {\n section(s.collection ? s.path.join(\" › \") : \"Articles\", s.depth);\n s.articles.forEach(articleButton);\n }\n if (data.faqs?.length) {\n section(\"FAQ\");\n data.faqs.forEach((f) => {\n const b = listItem(doc, \"?\", f.question);\n b.setAttribute(\"aria-expanded\", \"false\");\n const a = el(doc, \"div\", \"g-faq-a\");\n setSanitizedHtml(a, f.answer);\n a.hidden = true;\n b.addEventListener(\"click\", () => {\n a.hidden = !a.hidden;\n b.setAttribute(\"aria-expanded\", String(!a.hidden));\n });\n body.append(b, a);\n });\n }\n if (data.links?.length) {\n section(\"Links\");\n data.links.forEach((l) => {\n const a = el(doc, \"a\", \"g-rc-item\");\n a.href = l.url;\n a.target = \"_blank\";\n a.rel = \"noopener noreferrer\";\n const i = el(doc, \"span\", \"g-rc-icon\", \"↗\");\n i.setAttribute(\"aria-hidden\", \"true\");\n a.append(i, el(doc, \"span\", \"g-rc-title\", l.label));\n body.appendChild(a);\n });\n }\n if (!body.childNodes.length) body.appendChild(el(doc, \"div\", \"g-rc-empty\", \"Nothing here yet.\"));\n }\n\n let debounce: ReturnType<typeof setTimeout> | null = null;\n const onInput = () => {\n query = input.value;\n openSeq++;\n active = null;\n render();\n if (debounce) clearTimeout(debounce);\n if (!options.search || !query.trim()) {\n serverResults = [];\n return;\n }\n const seq = ++searchSeq;\n debounce = setTimeout(() => {\n options\n .search?.(query.trim())\n .then((results) => {\n if (seq !== searchSeq) return;\n serverResults = Array.isArray(results) ? results : [];\n render();\n })\n .catch(() => {});\n }, 250);\n };\n input.addEventListener(\"input\", onInput);\n\n return {\n el: root,\n render,\n reset() {\n openSeq++;\n active = null;\n query = \"\";\n input.value = \"\";\n serverResults = [];\n },\n openArticle(id: string) {\n const listed = options.data().articles.find((a) => a.id === id) ?? { id, slug: id, title: \"Article\", summary: \"\", updatedAt: \"\", bodyOmitted: true };\n openArticle(listed);\n },\n focusSearch: () => input.focus?.({ preventScroll: true }),\n setQuery(q: string) {\n input.value = q;\n onInput();\n },\n destroy() {\n if (debounce) clearTimeout(debounce);\n input.removeEventListener(\"input\", onInput);\n root.remove();\n },\n };\n}\n","import { FILE_LINK_CLASS, PDF_BLOCK_CLASS, PDF_PAGES_CLASS } from \"@guidelytech/shared/runtime\";\nimport { prefersReducedMotion } from \"./host\";\n\n/**\n * Turns the PDFs in a sanitized article body (`div.gd-pdf`: the PDF link plus its pages as images)\n * into inline viewers: pages swipe sideways with a page counter and previous/next buttons, and the\n * header or a tap on a page opens a full-screen reader inside the widget, so visitors read the\n * document without downloading it. The original PDF stays one tap away in the reader. Without this\n * (or without script) the CSS alone still shows a scrollable strip of pages.\n */\nexport function enhancePdfViewers(root: Element, doc: Document = root.ownerDocument): void {\n for (const block of Array.from(root.querySelectorAll(`div.${PDF_BLOCK_CLASS}`))) {\n const link = block.querySelector<HTMLAnchorElement>(`a.${FILE_LINK_CLASS}`);\n const strip = block.querySelector<HTMLElement>(`.${PDF_PAGES_CLASS}`);\n if (!link || !strip || block.hasAttribute(\"data-g-ready\")) continue;\n // The sanitizer strips unsafe sources; those images aren't pages.\n for (const img of Array.from(strip.querySelectorAll(\"img:not([src])\"))) img.remove();\n const pages = Array.from(strip.querySelectorAll(\"img\"));\n if (!pages.length) {\n strip.remove();\n continue;\n }\n block.setAttribute(\"data-g-ready\", \"\");\n const name = (link.textContent || \"\").trim() || \"PDF\";\n block.setAttribute(\"role\", \"group\");\n block.setAttribute(\"aria-label\", `${name}, ${pages.length} ${pages.length === 1 ? \"page\" : \"pages\"}`);\n link.setAttribute(\"aria-label\", `Read ${name} full screen`);\n link.addEventListener(\"click\", (e) => {\n e.preventDefault();\n openReader(doc, block, link, pages, 0);\n });\n\n const viewport = doc.createElement(\"div\");\n viewport.className = \"g-pdf-viewport\";\n strip.replaceWith(viewport);\n viewport.appendChild(strip);\n strip.tabIndex = 0;\n strip.setAttribute(\"aria-label\", `${name} pages`);\n\n const counter = doc.createElement(\"span\");\n counter.className = \"g-pdf-count\";\n counter.setAttribute(\"aria-live\", \"polite\");\n const prev = navButton(doc, \"prev\", \"Previous page\", \"‹\");\n const next = navButton(doc, \"next\", \"Next page\", \"›\");\n viewport.append(prev, next, counter);\n\n // Distance between page starts: one page width plus the gap.\n const stride = () => Math.max(1, pages.length > 1 ? pages[1]!.offsetLeft - pages[0]!.offsetLeft : strip.clientWidth);\n const current = () => Math.round(strip.scrollLeft / stride());\n const go = (i: number) => strip.scrollTo({ left: Math.max(0, Math.min(pages.length - 1, i)) * stride(), behavior: prefersReducedMotion() ? \"auto\" : \"smooth\" });\n const update = () => {\n const i = Math.min(pages.length - 1, current());\n counter.textContent = `${i + 1} / ${pages.length}`;\n prev.disabled = i === 0;\n next.disabled = i >= pages.length - 1;\n };\n prev.addEventListener(\"click\", () => go(current() - 1));\n next.addEventListener(\"click\", () => go(current() + 1));\n strip.addEventListener(\"scroll\", update, { passive: true });\n strip.addEventListener(\"keydown\", (e) => {\n if (e.key === \"ArrowRight\" || e.key === \"ArrowLeft\") {\n e.preventDefault();\n go(current() + (e.key === \"ArrowRight\" ? 1 : -1));\n } else if (e.key === \"Enter\") openReader(doc, block, link, pages, current());\n });\n pages.forEach((img, i) => img.addEventListener(\"click\", () => openReader(doc, block, link, pages, i)));\n if (pages.length === 1) viewport.classList.add(\"g-pdf-single\");\n update();\n }\n}\n\nfunction navButton(doc: Document, cls: string, label: string, text: string) {\n const b = doc.createElement(\"button\");\n b.type = \"button\";\n b.className = `g-pdf-nav g-pdf-${cls}`;\n b.setAttribute(\"aria-label\", label);\n b.textContent = text;\n return b;\n}\n\n/** Full-screen reader: every page stacked vertically, the original PDF linked, Escape to close. */\nfunction openReader(doc: Document, block: Element, link: HTMLAnchorElement, pages: HTMLImageElement[], start: number) {\n const host = (block.closest(\".g-scope\") as HTMLElement | null) ?? doc.body;\n // Inside the shadow root, `document.activeElement` is only the host.\n const returnFocus = (block.getRootNode() as Document | ShadowRoot).activeElement as HTMLElement | null;\n const name = (link.textContent || \"\").trim() || \"PDF\";\n\n const reader = doc.createElement(\"div\");\n reader.className = \"g-pdf-reader\";\n reader.setAttribute(\"role\", \"dialog\");\n reader.setAttribute(\"aria-modal\", \"true\");\n reader.setAttribute(\"aria-label\", name);\n const bar = doc.createElement(\"div\");\n bar.className = \"g-pdf-bar\";\n const title = doc.createElement(\"span\");\n title.className = \"g-pdf-title\";\n title.textContent = name;\n const original = doc.createElement(\"a\");\n original.className = \"g-btn g-btn-secondary\";\n original.href = link.href;\n original.target = \"_blank\";\n original.rel = \"noopener noreferrer\";\n original.textContent = \"Open PDF ↗\";\n const close = doc.createElement(\"button\");\n close.type = \"button\";\n close.className = \"g-close g-pdf-close\";\n close.setAttribute(\"aria-label\", \"Close\");\n close.textContent = \"×\";\n bar.append(title, original, close);\n\n const scroller = doc.createElement(\"div\");\n scroller.className = \"g-pdf-scroll\";\n scroller.tabIndex = 0;\n for (const page of pages) {\n const img = doc.createElement(\"img\");\n img.src = page.src;\n img.alt = page.alt;\n img.decoding = \"async\";\n // Sizes up front so every page has its height before loading, and opening at page N lands on it.\n for (const dim of [\"width\", \"height\"]) if (page.hasAttribute(dim)) img.setAttribute(dim, page.getAttribute(dim)!);\n scroller.appendChild(img);\n }\n reader.append(bar, scroller);\n\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n e.stopPropagation();\n done();\n } else if (e.key === \"Tab\") {\n // Keep focus inside the reader.\n const items: HTMLElement[] = [original, close, scroller];\n const at = items.indexOf((reader.getRootNode() as Document | ShadowRoot).activeElement as HTMLElement);\n e.preventDefault();\n items[(at + (e.shiftKey ? items.length - 1 : 1)) % items.length]!.focus();\n }\n };\n const done = () => {\n reader.remove();\n returnFocus?.focus?.({ preventScroll: true });\n };\n close.addEventListener(\"click\", done);\n reader.addEventListener(\"keydown\", onKey);\n host.appendChild(reader);\n close.focus();\n const target = scroller.children[start] as HTMLImageElement | undefined;\n if (target && start > 0) {\n const land = () => (scroller.scrollTop = target.offsetTop - 12);\n requestAnimationFrame(land);\n // Pages without stored sizes only get their height once the pages above have loaded.\n if (!target.hasAttribute(\"height\")) for (const img of Array.from(scroller.children).slice(0, start)) img.addEventListener(\"load\", land, { once: true });\n }\n}\n","import type { Appearance, ProjectTheme } from \"@guidelytech/shared\";\nimport { STYLES } from \"./styles\";\n\nexport const HOST_ID = \"guidely-root\";\n\nexport interface HostHandle {\n host: HTMLElement;\n shadow: ShadowRoot;\n /** Polite live region for screen-reader announcements. */\n live: HTMLElement;\n announce(text: string): void;\n destroy(): void;\n}\n\nlet current: HostHandle | null = null;\n\n/** Default project theme used when the config has not loaded yet. */\nexport const DEFAULT_THEME: ProjectTheme = {\n primaryColor: \"#4f46e5\",\n backgroundColor: \"#ffffff\",\n textColor: \"#111827\",\n borderRadius: 12,\n fontFamily: \"Inter, system-ui, -apple-system, sans-serif\",\n};\n\n/** Returns (creating when needed) the single Shadow-DOM host appended to `document.body`. */\nexport function ensureHost(doc: Document = document): HostHandle {\n if (current && current.host.isConnected && current.host.ownerDocument === doc) return current;\n let host = doc.getElementById(HOST_ID) as HTMLElement | null;\n if (!host) {\n host = doc.createElement(\"div\");\n host.id = HOST_ID;\n host.setAttribute(\"data-guidely\", \"\");\n (doc.body || doc.documentElement).appendChild(host);\n }\n const shadow = host.shadowRoot ?? host.attachShadow({ mode: \"open\" });\n if (!shadow.querySelector(\"style[data-g-base]\")) {\n const style = doc.createElement(\"style\");\n style.setAttribute(\"data-g-base\", \"\");\n style.textContent = STYLES;\n shadow.appendChild(style);\n }\n let live = shadow.querySelector<HTMLElement>(\".g-live\");\n if (!live) {\n live = doc.createElement(\"div\");\n live.className = \"g-live\";\n live.setAttribute(\"aria-live\", \"polite\");\n live.setAttribute(\"aria-atomic\", \"true\");\n shadow.appendChild(live);\n }\n const liveEl = live;\n current = {\n host,\n shadow,\n live: liveEl,\n announce(text: string) {\n liveEl.textContent = \"\";\n setTimeout(() => {\n liveEl.textContent = text;\n }, 30);\n },\n destroy() {\n host?.remove();\n if (current?.host === host) current = null;\n },\n };\n return current;\n}\n\n/** Removes the host from the document (all overlays with it). */\nexport function destroyHost(): void {\n current?.destroy();\n const stray = typeof document !== \"undefined\" ? document.getElementById(HOST_ID) : null;\n stray?.remove();\n current = null;\n}\n\nexport type ResolvedThemeMode = \"light\" | \"dark\";\n\nfunction prefersDark(): boolean {\n try {\n return typeof window !== \"undefined\" && typeof window.matchMedia === \"function\" && window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n } catch {\n return false;\n }\n}\n\nexport function prefersReducedMotion(): boolean {\n try {\n return typeof window !== \"undefined\" && typeof window.matchMedia === \"function\" && window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n } catch {\n return false;\n }\n}\n\nexport interface ThemeVars {\n primary: string;\n bg: string;\n text: string;\n radius: number;\n font: string;\n z: number;\n overlay: number;\n mode: ResolvedThemeMode;\n animation: Appearance[\"animation\"];\n}\n\n/** Merges project theme + guide appearance into CSS custom property values. */\nexport function resolveTheme(theme: Partial<ProjectTheme> | null | undefined, appearance?: Partial<Appearance> | null): ThemeVars {\n const t = { ...DEFAULT_THEME, ...(theme || {}) };\n const a = appearance || {};\n const requested = a.theme ?? \"auto\";\n const mode: ResolvedThemeMode = requested === \"auto\" ? (prefersDark() ? \"dark\" : \"light\") : requested;\n const dark = mode === \"dark\";\n return {\n primary: a.primaryColor || t.primaryColor,\n bg: a.backgroundColor || (dark ? \"#1f2937\" : t.backgroundColor),\n text: a.textColor || (dark ? \"#f9fafb\" : t.textColor),\n radius: a.borderRadius ?? t.borderRadius,\n font: a.fontFamily || t.fontFamily,\n z: a.zIndex ?? 2147483000,\n overlay: a.overlayOpacity ?? 0.5,\n mode,\n animation: prefersReducedMotion() ? \"none\" : (a.animation ?? \"fade\"),\n };\n}\n\n/** Applies theme variables to a scope element. */\nexport function applyTheme(el: HTMLElement, vars: ThemeVars): void {\n el.style.setProperty(\"--g-primary\", vars.primary);\n el.style.setProperty(\"--g-bg\", vars.bg);\n el.style.setProperty(\"--g-text\", vars.text);\n el.style.setProperty(\"--g-radius\", `${vars.radius}px`);\n el.style.setProperty(\"--g-font\", vars.font);\n el.style.setProperty(\"--g-z\", String(vars.z));\n el.style.setProperty(\"--g-overlay\", String(vars.overlay));\n el.setAttribute(\"data-theme\", vars.mode);\n el.setAttribute(\"data-anim\", vars.animation);\n}\n\n/**\n * Creates a themed scope container inside the shadow root. Each guide/widget renders inside its\n * own scope so appearance settings never leak between guides.\n */\nexport function createScope(theme?: Partial<ProjectTheme> | null, appearance?: Partial<Appearance> | null, doc: Document = document): { el: HTMLElement; vars: ThemeVars; destroy(): void } {\n const handle = ensureHost(doc);\n const el = doc.createElement(\"div\");\n el.className = \"g-scope\";\n const vars = resolveTheme(theme, appearance);\n applyTheme(el, vars);\n handle.shadow.appendChild(el);\n let mq: MediaQueryList | null = null;\n const onChange = () => applyTheme(el, resolveTheme(theme, appearance));\n if ((appearance?.theme ?? \"auto\") === \"auto\" && typeof window !== \"undefined\" && typeof window.matchMedia === \"function\") {\n try {\n mq = window.matchMedia(\"(prefers-color-scheme: dark)\");\n mq.addEventListener?.(\"change\", onChange);\n } catch {\n mq = null;\n }\n }\n return {\n el,\n vars,\n destroy() {\n mq?.removeEventListener?.(\"change\", onChange);\n el.remove();\n },\n };\n}\n","import { EMBED_IFRAME_ATTRS, VIDEO_ATTRS, isAllowedEmbedSrc, isSafeMediaUrl } from \"@guidelytech/shared/runtime\";\n\nconst ALLOWED_TAGS = new Set([\"p\", \"br\", \"strong\", \"b\", \"em\", \"i\", \"u\", \"a\", \"ul\", \"ol\", \"li\", \"img\", \"h1\", \"h2\", \"h3\", \"h4\", \"code\", \"pre\", \"blockquote\", \"span\", \"div\", \"hr\", \"button\"]);\nconst DROP_TAGS = new Set([\"script\", \"style\", \"object\", \"embed\", \"form\", \"input\", \"textarea\", \"select\", \"link\", \"meta\", \"base\", \"template\", \"svg\", \"math\", \"frame\", \"frameset\", \"noscript\"]);\nconst ALLOWED_ATTRS = new Set([\"href\", \"src\", \"alt\", \"title\", \"target\", \"rel\", \"class\", \"width\", \"height\", \"data-g-action\", \"data-g-value\"]);\nfunction isSafeUrl(value: string, attr: string, tag: string): boolean {\n // eslint-disable-next-line no-control-regex\n const v = value.trim().replace(/[\\u0000-\\u001f\\s]/g, \"\").toLowerCase();\n if (!v) return false;\n const m = /^([a-z][a-z0-9+.-]*):/.exec(v);\n if (!m) return true; // relative URL\n const scheme = m[1];\n if (scheme === \"data\") return tag === \"img\" && attr === \"src\" && v.startsWith(\"data:image/\");\n return scheme === \"http\" || scheme === \"https\" || scheme === \"mailto\" || scheme === \"tel\";\n}\n\nfunction sanitizeElement(el: Element): void {\n const tag = el.tagName.toLowerCase();\n for (const attr of Array.from(el.attributes)) {\n const name = attr.name.toLowerCase();\n if (name.startsWith(\"on\") || !ALLOWED_ATTRS.has(name)) {\n el.removeAttribute(attr.name);\n continue;\n }\n if ((name === \"href\" || name === \"src\") && !isSafeUrl(attr.value, name, tag)) el.removeAttribute(attr.name);\n }\n if (tag === \"a\") {\n const target = el.getAttribute(\"target\");\n if (target && target !== \"_blank\" && target !== \"_self\") el.removeAttribute(\"target\");\n if (el.getAttribute(\"target\") === \"_blank\") el.setAttribute(\"rel\", \"noopener noreferrer\");\n }\n if (tag === \"button\") el.setAttribute(\"type\", \"button\");\n if (tag === \"img\") {\n for (const dim of [\"width\", \"height\"]) if (el.hasAttribute(dim) && !/^\\d{1,5}$/.test(el.getAttribute(dim)!)) el.removeAttribute(dim);\n el.setAttribute(\"loading\", \"lazy\");\n if (!el.getAttribute(\"alt\")) el.setAttribute(\"alt\", \"\");\n }\n}\n\n/**\n * Media elements are rebuilt from scratch rather than filtered: an `<iframe>` only for a canonical\n * YouTube/Vimeo/Loom/Wistia embed, a `<video>` only for an absolute http(s) file, each with fixed\n * attributes. Returns null when the element must go.\n */\nfunction rebuildMedia(el: Element): Element | null {\n const doc = el.ownerDocument;\n const tag = el.tagName.toLowerCase();\n const src = el.getAttribute(\"src\");\n let out: Element;\n if (tag === \"iframe\") {\n if (!isAllowedEmbedSrc(src)) return null;\n out = doc.createElement(\"iframe\");\n out.setAttribute(\"src\", src!);\n out.setAttribute(\"title\", el.getAttribute(\"title\") || \"Embedded video\");\n for (const [k, v] of Object.entries(EMBED_IFRAME_ATTRS)) out.setAttribute(k, v);\n } else {\n if (!isSafeMediaUrl(src)) return null;\n out = doc.createElement(\"video\");\n out.setAttribute(\"src\", src!);\n const poster = el.getAttribute(\"poster\");\n if (isSafeMediaUrl(poster)) out.setAttribute(\"poster\", poster!);\n for (const [k, v] of Object.entries(VIDEO_ATTRS)) out.setAttribute(k, v);\n }\n return out;\n}\n\nfunction walk(node: Node): void {\n const children = Array.from(node.childNodes);\n for (const child of children) {\n if (child.nodeType === 8 /* comment */) {\n node.removeChild(child);\n continue;\n }\n if (child.nodeType !== 1) continue;\n const el = child as Element;\n const tag = el.tagName.toLowerCase();\n if (DROP_TAGS.has(tag)) {\n node.removeChild(el);\n continue;\n }\n if (tag === \"iframe\" || tag === \"video\") {\n const media = rebuildMedia(el);\n if (media) node.replaceChild(media, el);\n else node.removeChild(el);\n continue;\n }\n if (!ALLOWED_TAGS.has(tag)) {\n // Unwrap: keep text/children, drop the element itself.\n while (el.firstChild) node.insertBefore(el.firstChild, el);\n node.removeChild(el);\n // Re-walk the parent since children moved up.\n walk(node);\n return;\n }\n sanitizeElement(el);\n walk(el);\n }\n}\n\n/**\n * Parses HTML into a sanitized DocumentFragment using a strict allowlist. No external\n * dependency: a `<template>` element parses inertly and the tree is walked element by element.\n */\nexport function sanitizeToFragment(html: string, doc: Document = document): DocumentFragment {\n const tpl = doc.createElement(\"template\");\n tpl.innerHTML = html || \"\";\n walk(tpl.content);\n return tpl.content;\n}\n\n/** Returns sanitized HTML as a string. */\nexport function sanitizeHtml(html: string, doc: Document = document): string {\n const frag = sanitizeToFragment(html, doc);\n const div = doc.createElement(\"div\");\n div.appendChild(frag);\n return div.innerHTML;\n}\n\n/** Replaces the content of `el` with the sanitized HTML. */\nexport function setSanitizedHtml(el: Element, html: string): void {\n el.textContent = \"\";\n el.appendChild(sanitizeToFragment(html, el.ownerDocument));\n}\n","import type { NormalizedRect, SdkHowTo, SdkHowToStep } from \"@guidelytech/shared\";\nimport { el } from \"./help-view\";\n\n// A how-to inside the messenger: numbered steps with their screenshots and the element highlighted.\n// Built from DOM nodes and textContent only (step text is plain text), so nothing in it is parsed as HTML.\n\nconst pct = (v: number) => `${(v * 100).toFixed(3)}%`;\nconst place = (node: HTMLElement, r: NormalizedRect) =>\n Object.assign(node.style, {\n left: pct(r.x),\n top: pct(r.y),\n width: pct(r.width),\n height: pct(r.height),\n });\n\n/** Plain text as paragraphs (blank lines) with line breaks kept by CSS. */\nfunction paragraphs(doc: Document, text: string, cls: string): HTMLElement | null {\n const parts = text\n .split(/\\n{2,}/)\n .map((p) => p.trim())\n .filter(Boolean);\n if (!parts.length) return null;\n const wrap = el(doc, \"div\", cls);\n for (const p of parts) wrap.appendChild(el(doc, \"p\", \"\", p));\n return wrap;\n}\n\n/** The screenshot, cropped to `crop` when zoomed, with the highlight drawn over it. Only http(s) images load. */\nfunction screenshot(\n doc: Document,\n image: NonNullable<SdkHowToStep[\"image\"]>,\n alt: string,\n): HTMLElement | null {\n if (!/^https?:\\/\\//i.test(image.url)) return null;\n const frame = el(doc, \"div\", \"g-howto-shot\");\n const img = (cls: string) => {\n const i = el(doc, \"img\", cls);\n i.src = image.url;\n i.alt = alt;\n i.loading = \"lazy\";\n i.decoding = \"async\";\n return i;\n };\n const crop = image.crop;\n if (crop && crop.width > 0 && crop.height > 0) {\n // An invisible full-width copy gives the frame the screenshot's aspect ratio (the crop has the same one).\n const ghost = img(\"g-howto-ghost\");\n ghost.alt = \"\";\n ghost.setAttribute(\"aria-hidden\", \"true\");\n const zoomed = img(\"g-howto-zoomed\");\n Object.assign(zoomed.style, {\n width: pct(1 / crop.width),\n left: pct(-crop.x / crop.width),\n top: pct(-crop.y / crop.height),\n });\n frame.append(ghost, zoomed);\n } else frame.appendChild(img(\"\"));\n if (image.highlight) {\n const mark = el(doc, \"div\", \"g-howto-mark\");\n mark.setAttribute(\"aria-hidden\", \"true\");\n place(mark, image.highlight);\n frame.appendChild(mark);\n }\n return frame;\n}\n\n/** Renders a how-to; `onShowMe` starts its tour when it has one live in this environment. */\nexport function renderHowTo(\n doc: Document,\n howTo: SdkHowTo,\n onShowMe?: (guideKey: string) => void,\n): HTMLElement {\n const wrap = el(doc, \"div\", \"g-howto\");\n wrap.appendChild(el(doc, \"h3\", \"g-title\", howTo.title));\n const description = paragraphs(doc, howTo.description, \"g-howto-desc\");\n if (description) wrap.appendChild(description);\n const guideKey = howTo.guideKey;\n if (guideKey && onShowMe) {\n const show = el(doc, \"button\", \"g-btn g-btn-primary g-howto-show\", \"▶ Show me in the app\");\n show.type = \"button\";\n show.addEventListener(\"click\", () => onShowMe(guideKey));\n wrap.appendChild(show);\n }\n const list = el(doc, \"ol\", \"g-howto-steps\");\n let n = 0;\n for (const s of howTo.steps) {\n const li = el(doc, \"li\", `g-howto-step g-howto-${s.kind}`);\n if (s.kind === \"heading\") li.appendChild(el(doc, \"h4\", \"\", s.title));\n else if (s.kind === \"tip\" || s.kind === \"alert\") {\n li.appendChild(el(doc, \"strong\", \"\", s.title || (s.kind === \"tip\" ? \"Tip\" : \"Important\")));\n const body = paragraphs(doc, s.body, \"\");\n if (body) li.appendChild(body);\n } else if (s.kind === \"text\") {\n if (s.title) li.appendChild(el(doc, \"strong\", \"\", s.title));\n const body = paragraphs(doc, s.body, \"g-howto-note\");\n if (body) li.appendChild(body);\n } else {\n const row = el(doc, \"div\", \"g-howto-row\");\n const num = el(doc, \"span\", \"g-howto-num\", String(++n));\n const text = el(doc, \"div\", \"g-howto-text\");\n text.appendChild(el(doc, \"p\", \"g-howto-title\", s.title));\n const body = paragraphs(doc, s.body, \"g-howto-note\");\n if (body) text.appendChild(body);\n row.append(num, text);\n li.appendChild(row);\n const shot = s.image ? screenshot(doc, s.image, s.title) : null;\n if (shot) li.appendChild(shot);\n }\n list.appendChild(li);\n }\n if (!list.childNodes.length)\n wrap.appendChild(el(doc, \"div\", \"g-rc-empty\", \"This how-to has no steps yet.\"));\n else wrap.appendChild(list);\n return wrap;\n}\n","/** Messenger styles, injected into the Guidely shadow root the first time the messenger renders. */\nexport const MESSENGER_STYLES = `\n:host([data-g-messenger=\"bottom-right\"]) .g-launcher.g-pos-bottom-right{right:72px}\n:host([data-g-messenger=\"bottom-left\"]) .g-launcher.g-pos-bottom-left{left:72px}\n.g-m-launcher{position:fixed;z-index:calc(var(--g-z) + 1);pointer-events:auto;width:56px;height:56px;margin:16px;border-radius:999px;border:0;background:var(--g-primary);color:var(--g-primary-text);cursor:pointer;box-shadow:var(--g-shadow);display:inline-flex;align-items:center;justify-content:center;padding:0;transition:transform .15s}\n.g-m-launcher:hover{transform:scale(1.05)}\n.g-m-launcher:focus-visible{outline:2px solid var(--g-primary);outline-offset:3px}\n.g-m-launcher svg{width:26px;height:26px;fill:currentColor}\n.g-m-badge{position:absolute;top:-2px;right:-2px;min-width:20px;height:20px;padding:0 5px;border-radius:999px;background:#e11d48;color:#fff;font-size:11px;font-weight:700;display:inline-flex;align-items:center;justify-content:center;border:2px solid var(--g-bg)}\n.g-messenger{bottom:76px;height:min(640px,calc(100vh - 110px))}\n.g-m-head{padding:16px 48px 14px 20px;background:var(--g-primary);color:var(--g-primary-text);position:relative;display:flex;align-items:center;gap:8px;min-height:56px}\n.g-m-head .g-close{color:inherit;top:50%;transform:translateY(-50%)}\n.g-m-head .g-close:hover,.g-m-head .g-close:focus-visible{background:rgba(255,255,255,.18);color:inherit}\n.g-m-head h2{margin:0;font-size:16px;font-weight:600;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.g-m-back{border:0;background:transparent;color:inherit;font:inherit;cursor:pointer;width:32px;height:32px;border-radius:999px;margin-left:-8px;display:inline-flex;align-items:center;justify-content:center;padding:0}\n.g-m-back:hover,.g-m-back:focus-visible{background:rgba(255,255,255,.18);outline:none}\n.g-m-main{flex:1;min-height:0;display:flex;flex-direction:column;overflow:hidden}\n.g-m-scroll{flex:1;overflow:auto;padding:16px}\n.g-m-card{display:block;width:100%;text-align:left;border:1px solid var(--g-border);background:var(--g-bg);color:var(--g-text);border-radius:calc(var(--g-radius) * .8);padding:14px 16px;margin:0 0 12px;font:inherit;cursor:pointer;box-shadow:0 1px 2px rgba(0,0,0,.04)}\n.g-m-card:hover{background:var(--g-subtle)}\n.g-m-card:focus-visible{outline:2px solid var(--g-primary);outline-offset:2px}\n.g-m-card-title{display:block;font-weight:600}\n.g-m-card-sub{display:block;color:var(--g-muted);font-size:13px;margin-top:2px}\n.g-m-card-label{display:block;font-size:12px;color:var(--g-muted);font-weight:500}\n.g-m-row{display:flex;align-items:flex-start;gap:10px}\n.g-m-row .g-m-grow{flex:1;min-width:0}\n.g-m-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.g-m-time{color:var(--g-muted);font-size:12px;flex:none}\n.g-m-dot{width:8px;height:8px;border-radius:999px;background:var(--g-primary);flex:none;margin-top:6px}\n.g-m-tabs{display:flex;border-top:1px solid var(--g-border);background:var(--g-bg)}\n.g-m-tab{flex:1;border:0;background:transparent;color:var(--g-muted);font:inherit;font-size:12px;font-weight:600;padding:10px 4px 12px;cursor:pointer;display:flex;flex-direction:column;align-items:center;gap:2px}\n.g-m-tab[aria-selected=\"true\"]{color:var(--g-primary)}\n.g-m-tab:focus-visible{outline:2px solid var(--g-primary);outline-offset:-2px}\n.g-m-tab-icon{position:relative;display:inline-flex;line-height:1}\n.g-m-tab-icon .g-m-ico{width:22px;height:22px}\n.g-m-tab-dot{position:absolute;top:-2px;right:-4px;width:8px;height:8px;border-radius:999px;background:#e11d48;border:2px solid var(--g-bg);box-sizing:content-box}\n.g-m-log{flex:1;overflow:auto;padding:16px;display:flex;flex-direction:column;gap:10px}\n.g-m-msg{max-width:85%;display:flex;flex-direction:column;gap:4px}\n.g-m-msg.g-from-user{align-self:flex-end;align-items:flex-end}\n.g-m-msg.g-from-system{align-self:center;max-width:95%;text-align:center;color:var(--g-muted);font-size:12px}\n.g-m-author{font-size:12px;color:var(--g-muted);display:flex;align-items:center;gap:6px}\n.g-m-ai{font-size:10px;font-weight:700;letter-spacing:.04em;padding:1px 5px;border-radius:4px;background:var(--g-subtle);color:var(--g-muted)}\n.g-m-bubble{padding:10px 12px;border-radius:14px;background:var(--g-subtle);color:var(--g-text);overflow-wrap:anywhere}\n.g-from-user .g-m-bubble{background:var(--g-primary);color:var(--g-primary-text)}\n.g-from-user .g-m-bubble a{color:inherit}\n.g-m-bubble p{margin:0 0 8px}.g-m-bubble p:last-child{margin:0}\n.g-m-bubble ul,.g-m-bubble ol{margin:4px 0 8px;padding-left:20px}\n.g-m-bubble code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;background:color-mix(in srgb,var(--g-text) 8%,transparent);padding:1px 4px;border-radius:4px}\n.g-m-bubble a{color:var(--g-primary)}\n.g-m-failed .g-m-bubble{opacity:.7;font-style:italic}\n.g-m-typing{display:inline-flex;gap:4px;padding:4px 0}\n.g-m-typing span{width:6px;height:6px;border-radius:999px;background:var(--g-muted);animation:g-m-bounce 1s infinite}\n.g-m-typing span:nth-child(2){animation-delay:.15s}.g-m-typing span:nth-child(3){animation-delay:.3s}\n@keyframes g-m-bounce{0%,60%,100%{opacity:.3;transform:translateY(0)}30%{opacity:1;transform:translateY(-3px)}}\n@media (prefers-reduced-motion: reduce){.g-m-typing span{animation:none}.g-m-launcher{transition:none}}\n.g-m-chips{display:flex;flex-direction:column;gap:6px;margin-top:2px}\n.g-m-chip{display:flex;align-items:center;gap:8px;text-align:left;border:1px solid var(--g-border);background:var(--g-bg);color:var(--g-text);border-radius:10px;padding:8px 10px;font:inherit;font-size:13px;cursor:pointer}\n.g-m-chip:hover{background:var(--g-subtle)}\n.g-m-chip:focus-visible{outline:2px solid var(--g-primary);outline-offset:2px}\n.g-m-chip.g-m-guide{border-color:var(--g-primary);color:var(--g-primary);font-weight:600}\n.g-m-foot{border-top:1px solid var(--g-border);padding:10px 12px 12px;background:var(--g-bg)}\n.g-m-compose{display:flex;align-items:flex-end;gap:8px}\n.g-m-compose textarea{flex:1;resize:none;min-height:40px;max-height:120px;border:1px solid var(--g-border);border-radius:10px;padding:9px 10px;font:inherit;font-size:14px;color:var(--g-text);background:var(--g-bg)}\n.g-m-compose textarea:focus-visible{outline:2px solid var(--g-primary);outline-offset:1px}\n.g-m-send{width:40px;height:40px;border-radius:999px;border:0;background:var(--g-primary);color:var(--g-primary-text);cursor:pointer;flex:none;display:inline-flex;align-items:center;justify-content:center;padding:0}\n.g-m-send .g-m-ico{width:18px;height:18px}\n.g-m-send:disabled{opacity:.45;cursor:not-allowed}\n.g-m-send:focus-visible{outline:2px solid var(--g-primary);outline-offset:2px}\n.g-m-human{border:0;background:transparent;color:var(--g-muted);font:inherit;font-size:12px;cursor:pointer;padding:6px 2px 0;text-decoration:underline}\n.g-m-human:hover{color:var(--g-text)}\n.g-m-rate{text-align:center;padding:4px 0 2px;font-size:13px;color:var(--g-muted)}\n.g-m-rate button{border:0;background:transparent;font-size:22px;cursor:pointer;padding:4px 8px;border-radius:8px}\n.g-m-rate button:hover,.g-m-rate button:focus-visible{background:var(--g-subtle);outline:none}\n.g-m-note{color:var(--g-muted);font-size:12px;margin-top:6px}\n.g-m-empty{color:var(--g-muted);text-align:center;padding:24px 8px}\n.g-howto .g-title{margin:0 0 6px}\n.g-howto-desc,.g-howto-note{color:var(--g-muted);font-size:13px}\n.g-howto p{margin:0 0 6px;white-space:pre-line}\n.g-howto-show{width:100%;margin:6px 0 4px}\n.g-howto-steps{list-style:none;margin:12px 0 0;padding:0;display:flex;flex-direction:column;gap:16px}\n.g-howto-step h4{margin:4px 0 0;font-size:15px}\n.g-howto-tip,.g-howto-alert{border-left:3px solid var(--g-primary);background:var(--g-subtle);border-radius:6px;padding:8px 10px;font-size:13px}\n.g-howto-alert{border-left-color:#d97706}\n.g-howto-row{display:flex;gap:10px;align-items:flex-start}\n.g-howto-num{flex:none;width:24px;height:24px;border-radius:999px;background:var(--g-primary);color:var(--g-primary-text);font-size:12px;font-weight:700;display:inline-flex;align-items:center;justify-content:center}\n.g-howto-text{flex:1;min-width:0;padding-top:2px}\n.g-howto-title{font-weight:600}\n.g-howto-shot{position:relative;overflow:hidden;margin-top:8px;border:1px solid var(--g-border);border-radius:8px;background:var(--g-subtle)}\n.g-howto-shot img{display:block;width:100%;height:auto}\n.g-howto-shot .g-howto-ghost{visibility:hidden}\n.g-howto-shot .g-howto-zoomed{position:absolute;max-width:none}\n.g-howto-mark{position:absolute;pointer-events:none;border:3px solid var(--g-primary);border-radius:6px;box-shadow:0 0 0 3px color-mix(in srgb,var(--g-primary) 25%,transparent)}\n.g-m-ico{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;flex:none}\n.g-close .g-m-ico,.g-m-back .g-m-ico{width:18px;height:18px}\n.g-m-row.g-m-center{align-items:center}\n.g-m-row.g-m-baseline{align-items:baseline}\n.g-m-static{cursor:default}\n.g-m-static:hover{background:var(--g-bg)}\n.g-m-wide{width:100%}\n.g-m-home{position:relative;padding:0}\n.g-m-hero-bg{position:absolute;top:0;left:0;right:0;height:300px;pointer-events:none;background:linear-gradient(180deg,var(--g-primary) 0%,var(--g-primary) 52%,color-mix(in srgb,var(--g-primary) 30%,var(--g-bg)) 84%,var(--g-bg) 100%)}\n.g-m-home-inner{position:relative;padding:16px;display:flex;flex-direction:column;gap:12px}\n.g-m-home .g-m-card{margin:0;box-shadow:0 1px 2px rgba(0,0,0,.04),0 4px 14px rgba(17,24,39,.06)}\n.g-m-hero-top{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:40px;padding:2px 4px 0}\n.g-m-logo{width:36px;height:36px;border-radius:9px;background:var(--g-bg);color:var(--g-primary);display:inline-flex;align-items:center;justify-content:center;font-weight:700;font-size:17px;overflow:hidden;flex:none}\n.g-m-logo img{width:100%;height:100%;object-fit:contain}\n.g-m-team{display:flex}\n.g-m-avatar{width:32px;height:32px;border-radius:999px;border:2px solid var(--g-primary);display:inline-flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;overflow:hidden;margin-left:-8px;background:#fde7c7;color:#7a4a0a}\n.g-m-avatar:first-child{margin-left:0}\n.g-m-avatar-1{background:#d9f0e3;color:#1f5e3b}\n.g-m-avatar-2{background:#e3e1fa;color:#3b3486}\n.g-m-avatar img{width:100%;height:100%;object-fit:cover}\n.g-m-hero-close{width:36px;height:36px;border:0;border-radius:999px;background:rgba(255,255,255,.16);color:var(--g-primary-text);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;padding:0;margin-left:10px}\n.g-m-hero-close .g-m-ico{width:18px;height:18px}\n.g-m-hero-close:hover{background:rgba(255,255,255,.28)}\n.g-m-hero-close:focus-visible{outline:2px solid var(--g-primary-text);outline-offset:2px}\n.g-m-hello{margin:36px 4px 6px;color:var(--g-primary-text);font-size:26px;font-weight:700;line-height:1.2;letter-spacing:-.01em;display:flex;flex-direction:column}\n.g-m-hello-1{opacity:.8}\n.g-m-trail{color:var(--g-primary)}\n.g-m-lead{color:var(--g-muted)}\n.g-m-status-ico{width:26px;height:26px}\n.g-m-status-operational .g-m-status-ico{color:#15803d}\n.g-m-status-degraded .g-m-status-ico{color:#b45309}\n.g-m-status-outage .g-m-status-ico{color:#b91c1c}\n.g-m-status-maintenance .g-m-status-ico{color:#1d4ed8}\n.g-m-bar{display:block;height:6px;border-radius:999px;background:var(--g-border);margin-top:10px;overflow:hidden}\n.g-m-bar-fill{display:block;height:100%;background:var(--g-primary);border-radius:999px}\n.g-m-link{color:var(--g-primary);font-weight:600;font-size:13px;flex:none}\n.g-m-badge-ico{width:32px;height:32px;border-radius:8px;background:var(--g-subtle);color:color-mix(in srgb,var(--g-text) 78%,transparent);display:inline-flex;align-items:center;justify-content:center;flex:none}\n.g-m-badge-ico .g-m-ico{width:16px;height:16px}\n.g-m-badge-ico.g-m-accent{background:color-mix(in srgb,var(--g-primary) 12%,var(--g-bg));color:var(--g-primary)}\n.g-m-suggest{padding-bottom:4px}\n.g-m-items{display:flex;flex-direction:column;margin-top:8px}\n.g-m-item{display:flex;align-items:center;gap:12px;width:100%;text-align:left;border:0;border-top:1px solid var(--g-border);background:transparent;color:var(--g-text);padding:10px 0;font:inherit;cursor:pointer;min-height:44px}\n.g-m-item:hover .g-m-item-title{color:var(--g-primary)}\n.g-m-item:focus-visible{outline:2px solid var(--g-primary);outline-offset:2px;border-radius:4px}\n.g-m-item-title{display:block;font-weight:600}\n.g-m-news{padding:0;overflow:hidden}\n.g-m-news-img{display:block;width:100%;height:150px;object-fit:cover;background:var(--g-subtle)}\n.g-m-news-body{display:block;padding:14px 16px}\n.g-m-news-meta{gap:8px;margin-bottom:4px}\n.g-m-tag{font-size:11px;font-weight:700;color:var(--g-primary-text);background:var(--g-primary);border-radius:4px;padding:1px 6px;text-transform:uppercase;letter-spacing:.03em}\n.g-m-clamp{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}\n.g-m-context{align-self:center;font-size:12px;color:var(--g-muted);background:var(--g-subtle);border-radius:999px;padding:3px 10px}\n.g-m-asks{align-items:flex-start}\n.g-m-chip.g-m-ask{border-color:var(--g-primary);color:var(--g-primary);font-weight:600;border-radius:999px;padding:8px 14px;min-height:36px}\n.g-m-chip.g-m-ask:disabled{opacity:.5;cursor:not-allowed}\n`;\n","/**\n * Renders untrusted chat text (Scout replies, user and teammate messages) with createElement and\n * textContent only. Supports paragraphs, line breaks, `- ` / `1. ` lists, **bold**, `code` and\n * http(s) links. Never creates images, raw HTML or non-http links, so a prompt-injected reply can't\n * load remote resources or run script.\n */\n\nconst CITATION = /\\s*\\[\\[article:[^\\]]*\\]\\]/g;\n// Inline tokens: **bold**, `code`, [label](url), bare https?:// URLs.\nconst INLINE = /\\*\\*([^*\\n]+)\\*\\*|`([^`\\n]+)`|(!?)\\[([^\\]\\n]{1,200})\\]\\((https?:\\/\\/[^\\s)]+)\\)|(https?:\\/\\/[^\\s<>()\"']+[^\\s<>().,;:!?'\"])/g;\n\n/** Removes `[[article:ID]]` markers (citations are rendered from structured data instead). */\nexport function stripCitationMarkers(text: string): string {\n return text.replace(CITATION, \"\");\n}\n\nexport function safeHttpUrl(raw: string): string | null {\n try {\n const u = new URL(raw);\n return u.protocol === \"http:\" || u.protocol === \"https:\" ? u.href : null;\n } catch {\n return null;\n }\n}\n\nfunction link(doc: Document, label: string, href: string): Node {\n const url = safeHttpUrl(href);\n if (!url) return doc.createTextNode(label);\n const a = doc.createElement(\"a\");\n a.href = url;\n a.target = \"_blank\";\n a.rel = \"noopener noreferrer nofollow\";\n a.textContent = label;\n return a;\n}\n\nfunction appendInline(doc: Document, parent: Node, text: string) {\n let last = 0;\n for (const m of text.matchAll(INLINE)) {\n const start = m.index ?? 0;\n if (start > last) parent.appendChild(doc.createTextNode(text.slice(last, start)));\n if (m[1] !== undefined) {\n const b = doc.createElement(\"strong\");\n b.textContent = m[1];\n parent.appendChild(b);\n } else if (m[2] !== undefined) {\n const c = doc.createElement(\"code\");\n c.textContent = m[2];\n parent.appendChild(c);\n } else if (m[4] !== undefined && m[5] !== undefined) {\n // Markdown images (![alt](url)) are never loaded or linked: keep the alt text only.\n parent.appendChild(m[3] ? doc.createTextNode(m[4]) : link(doc, m[4], m[5]));\n } else if (m[6] !== undefined) {\n parent.appendChild(link(doc, m[6], m[6]));\n }\n last = start + m[0].length;\n }\n if (last < text.length) parent.appendChild(doc.createTextNode(text.slice(last)));\n}\n\nconst BULLET = /^\\s*[-*•]\\s+/;\nconst NUMBERED = /^\\s*\\d{1,3}[.)]\\s+/;\n\n/** Builds a fragment for `text`. Safe for any input. */\nexport function renderSafeText(doc: Document, text: string): DocumentFragment {\n const frag = doc.createDocumentFragment();\n const blocks = stripCitationMarkers(text).replace(/\\r\\n?/g, \"\\n\").trim().split(/\\n{2,}/);\n for (const block of blocks) {\n if (!block.trim()) continue;\n const lines = block.split(\"\\n\");\n if (lines.every((l) => BULLET.test(l)) || lines.every((l) => NUMBERED.test(l))) {\n const ordered = NUMBERED.test(lines[0]!);\n const list = doc.createElement(ordered ? \"ol\" : \"ul\");\n for (const line of lines) {\n const li = doc.createElement(\"li\");\n appendInline(doc, li, line.replace(ordered ? NUMBERED : BULLET, \"\"));\n list.appendChild(li);\n }\n frag.appendChild(list);\n continue;\n }\n const p = doc.createElement(\"p\");\n lines.forEach((line, i) => {\n if (i) p.appendChild(doc.createElement(\"br\"));\n appendInline(doc, p, line);\n });\n frag.appendChild(p);\n }\n return frag;\n}\n"],"mappings":"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","names":["import_runtime","import_runtime","link","import_runtime","el","el","icon"]}
1
+ {"version":3,"sources":["../src/messenger.ts","../src/help-view.ts","../src/pdf-viewer.ts","../src/host.ts","../src/sanitize.ts","../src/howto-view.ts","../src/messenger-styles.ts","../src/render-safe.ts"],"sourcesContent":["import type {\n ConversationMessagesResponse,\n MessengerConfig,\n MessengerConversation,\n MessengerMessage,\n MessengerPageContent,\n MessengerStatus,\n ResourceCenterArticle,\n ResourceCenterConfig,\n SdkArticlesResponse,\n SdkHowTo,\n SdkHowToSummary,\n SdkHowTosResponse,\n} from \"@guidelytech/shared\";\nimport { foldPathIds, pageLabel } from \"@guidelytech/shared/runtime\";\nimport { createHelpView, el, listItem, type HelpData, type HelpGuideRef, type HelpSuggestion } from \"./help-view\";\nimport { renderHowTo } from \"./howto-view\";\nimport { MESSENGER_STYLES } from \"./messenger-styles\";\nimport { renderSafeText } from \"./render-safe\";\n\n/** Callbacks the transport invokes while a message is sent and Scout replies. */\nexport interface MessengerStreamHandlers {\n /** A new conversation was created (first message only). */\n onConversation?(conversation: MessengerConversation): void;\n onMessage(message: MessengerMessage): void;\n onDelta(messageId: string, text: string): void;\n onDone(message: MessengerMessage | null, conversation: MessengerConversation): void;\n onError(message: string): void;\n}\n\n/** Server access for the messenger; implemented by sdk-core over the public SDK API. */\nexport interface MessengerApi {\n listConversations(): Promise<MessengerConversation[]>;\n loadMessages(conversationId: string, since?: string | null): Promise<ConversationMessagesResponse>;\n start(text: string, handlers: MessengerStreamHandlers): Promise<void>;\n send(conversationId: string, text: string, handlers: MessengerStreamHandlers): Promise<void>;\n handoff(conversationId: string): Promise<ConversationMessagesResponse>;\n rate(conversationId: string, rating: number): Promise<void>;\n listArticles(): Promise<SdkArticlesResponse>;\n getArticle(id: string): Promise<ResourceCenterArticle | null>;\n searchArticles(q: string): Promise<ResourceCenterArticle[]>;\n /** How-tos available in the app, and the ones for the page the user is on (optional: older transports). */\n listHowTos?(): Promise<SdkHowTosResponse>;\n getHowTo?(id: string): Promise<SdkHowTo | null>;\n /** Page-matched how-tos, articles and common questions (servers before the personalised home lack it). */\n pageContent?(path: string): Promise<MessengerPageContent>;\n}\n\nexport type MessengerTab = \"home\" | \"messages\" | \"help\" | \"news\";\n\n/** A guide the visitor started and didn't finish. */\nexport interface MessengerResumeGuide {\n id: string;\n name: string;\n stepId: string;\n /** Zero-based index of the step they reached. */\n stepIndex: number;\n stepCount: number;\n}\n\nexport interface MessengerChecklistProgress {\n id: string;\n name: string;\n done: number;\n total: number;\n /** Title of the first unfinished task. */\n nextTask: string | null;\n}\n\n/** A live announcement, shown on Home and in the News tab. */\nexport interface MessengerNewsItem {\n id: string;\n key: string;\n title: string;\n /** Plain text. */\n body: string;\n imageUrl: string | null;\n publishedAt: string;\n unread: boolean;\n}\n\n/** What the SDK knows about the visitor right now, read each time the messenger renders. */\nexport interface MessengerVisitor {\n firstName: string | null;\n /** Current page path (no query or fragment); null when unknown. */\n path: string | null;\n /** Live guides targeted at this page that the visitor can start. */\n pageGuides: HelpGuideRef[];\n resumeGuide: MessengerResumeGuide | null;\n checklist: MessengerChecklistProgress | null;\n news: MessengerNewsItem[];\n}\n\nexport interface MessengerOptions {\n scope: HTMLElement;\n config: MessengerConfig;\n api: MessengerApi;\n /** Resource center extras (recommended guides, checklists, FAQs, links) shown in the Help tab. */\n resourceCenter?: ResourceCenterConfig | null;\n /** The visitor's audiences (for audience-targeted articles and collections in the Help tab). */\n audienceIds?: () => ReadonlySet<string> | readonly string[];\n guides?: HelpGuideRef[];\n onStartGuide?: (guideKeyOrId: string) => void;\n onOpenChecklist?: (guideId: string) => void;\n onArticleView?: (article: ResourceCenterArticle) => void;\n onOpen?: () => void;\n onClose?: () => void;\n onMessage?: (message: MessengerMessage, conversation: MessengerConversation) => void;\n /** Personalisation: name, page, progress and announcements. Without it the home screen is generic. */\n visitor?: () => MessengerVisitor;\n /** Logo and name shown at the top of the home screen (project theme). */\n brand?: { logoUrl?: string | null; name?: string | null };\n onResumeGuide?: (guideId: string, stepId: string) => void;\n /** The visitor saw these announcements (News tab opened). */\n onNewsSeen?: (ids: string[]) => void;\n hideLauncher?: boolean;\n /** Poll intervals (ms): open thread, and unread badge while closed. */\n pollMs?: { thread: number; background: number };\n}\n\nexport interface MessengerWidget {\n el: HTMLElement;\n open(tab?: MessengerTab): void;\n close(): void;\n toggle(): void;\n isOpen(): boolean;\n /** Opens a new conversation, optionally pre-filling the composer. */\n showNewMessage(text?: string): void;\n openArticle(id: string): void;\n /** Re-reads the visitor (page changed, progress made) and re-renders what is showing. */\n refresh(): void;\n destroy(): void;\n}\n\ntype View = { kind: \"tab\"; tab: MessengerTab } | { kind: \"thread\"; conversationId: string | null } | { kind: \"howto\"; id: string; from: View };\n\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\nfunction chatIcon(doc: Document): SVGSVGElement {\n const svg = doc.createElementNS(SVG_NS, \"svg\");\n svg.setAttribute(\"viewBox\", \"0 0 24 24\");\n svg.setAttribute(\"aria-hidden\", \"true\");\n const path = doc.createElementNS(SVG_NS, \"path\");\n path.setAttribute(\"d\", \"M12 3C6.5 3 2 6.8 2 11.5c0 2.4 1.2 4.6 3.1 6.1L4.5 21l3.9-2c1.1.3 2.3.5 3.6.5 5.5 0 10-3.8 10-8.5S17.5 3 12 3z\");\n svg.appendChild(path);\n return svg;\n}\n\n/** Stroke icons (24×24 viewBox), drawn with currentColor. */\nconst ICONS: Record<string, string[]> = {\n home: [\"M3 10.5 12 3l9 7.5V20a1 1 0 0 1-1 1h-5v-6H9v6H4a1 1 0 0 1-1-1z\"],\n messages: [\"M4 5h16v11H8l-4 4z\"],\n help: [\"M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18z\", \"M9.5 9.5a2.5 2.5 0 1 1 3.5 2.3c-.6.3-1 .8-1 1.5V14\", \"M12 17h.01\"],\n news: [\"M3 11v2a1 1 0 0 0 1 1h2l5 4V6L6 10H4a1 1 0 0 0-1 1z\", \"M15 9a4 4 0 0 1 0 6\", \"M18 6a8 8 0 0 1 0 12\"],\n arrow: [\"M5 12h14\", \"M13 6l6 6-6 6\"],\n close: [\"M6 6l12 12\", \"M18 6 6 18\"],\n back: [\"M15 6l-6 6 6 6\"],\n chevron: [\"m9 6 6 6-6 6\"],\n check: [\"M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18z\", \"m8 12 3 3 5-6\"],\n alert: [\"M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18z\", \"M12 8v4\", \"M12 16h.01\"],\n wrench: [\"M14.7 6.3a4 4 0 0 0-5.4 5.4L4 17l3 3 5.3-5.3a4 4 0 0 0 5.4-5.4l-2.5 2.5-2.4-.6-.6-2.4z\"],\n play: [\"M8 5v14l11-7z\"],\n steps: [\"M9 6h11\", \"M9 12h11\", \"M9 18h11\", \"M4 6h.01\", \"M4 12h.01\", \"M4 18h.01\"],\n article: [\"M6 3h9l4 4v14H6z\", \"M9 12h6\", \"M9 16h6\"],\n ask: [\"M4 5h16v11H8l-4 4z\", \"M9 9.5h6\", \"M9 12.5h4\"],\n search: [\"M11 4a7 7 0 1 0 0 14 7 7 0 0 0 0-14z\", \"m20 20-3.5-3.5\"],\n circle: [\"M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18z\"],\n};\n\nfunction icon(doc: Document, name: keyof typeof ICONS, cls = \"g-m-ico\"): SVGSVGElement {\n const svg = doc.createElementNS(SVG_NS, \"svg\");\n svg.setAttribute(\"viewBox\", \"0 0 24 24\");\n svg.setAttribute(\"aria-hidden\", \"true\");\n svg.setAttribute(\"class\", cls);\n for (const d of ICONS[name] ?? []) {\n const path = doc.createElementNS(SVG_NS, \"path\");\n path.setAttribute(\"d\", d);\n svg.appendChild(path);\n }\n return svg;\n}\n\nconst REPLY_TIME_TEXT: Record<string, string> = {\n minutes: \"typically replies in a few minutes\",\n hour: \"typically replies within an hour\",\n hours: \"typically replies in a few hours\",\n day: \"typically replies within a day\",\n};\n\nconst STATUS_TEXT: Record<MessengerStatus[\"level\"], { title: string; icon: keyof typeof ICONS }> = {\n operational: { title: \"All systems operational\", icon: \"check\" },\n degraded: { title: \"Degraded performance\", icon: \"alert\" },\n outage: { title: \"Service outage\", icon: \"alert\" },\n maintenance: { title: \"Scheduled maintenance\", icon: \"wrench\" },\n};\n\n/** \"Oct 18, 08:12\" in the visitor's locale and time zone. */\nfunction shortDateTime(iso: string): string {\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return \"\";\n try {\n return d.toLocaleString(undefined, { month: \"short\", day: \"numeric\", hour: \"2-digit\", minute: \"2-digit\" });\n } catch {\n return d.toISOString().slice(0, 16).replace(\"T\", \" \");\n }\n}\n\nfunction shortDate(iso: string): string {\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return \"\";\n try {\n return d.toLocaleDateString(undefined, { month: \"short\", day: \"numeric\" });\n } catch {\n return d.toISOString().slice(0, 10);\n }\n}\n\n/** Initials for an avatar fallback (\"Jordan\" → \"J\"). */\nconst initialOf = (name: string) => (name.trim().match(/\\p{L}/u)?.[0] ?? \"?\").toUpperCase();\n\n/** The greeting with a leading \"Hi!\" swapped for the visitor's name (\"Hi! I'm Scout.\" → \"Hi Maya! I'm Scout.\"). */\nexport function personalGreeting(greeting: string, firstName: string | null): string {\n if (!firstName) return greeting;\n const rest = greeting.replace(/^\\s*(hi|hello|hey)( there)?\\s*[!,.]?\\s*/i, \"\");\n return rest ? `Hi ${firstName}! ${rest}` : `Hi ${firstName}!`;\n}\n\nexport function relativeTime(iso: string, now = Date.now()): string {\n const s = Math.max(0, Math.round((now - Date.parse(iso)) / 1000));\n if (!Number.isFinite(s) || s < 60) return \"now\";\n if (s < 3600) return `${Math.floor(s / 60)}m`;\n if (s < 86400) return `${Math.floor(s / 3600)}h`;\n return `${Math.floor(s / 86400)}d`;\n}\n\nfunction ensureStyles(scope: HTMLElement) {\n const root = scope.getRootNode() as ShadowRoot | Document;\n const container = \"host\" in root ? root : scope.ownerDocument.head;\n if (container.querySelector?.(\"style[data-g-messenger]\")) return;\n const style = scope.ownerDocument.createElement(\"style\");\n style.setAttribute(\"data-g-messenger\", \"\");\n style.textContent = MESSENGER_STYLES;\n container.appendChild(style);\n}\n\n/** Intercom-style messenger: launcher + panel with Home, Messages (chat with Scout / the team) and Help tabs. */\nexport function renderMessenger(options: MessengerOptions): MessengerWidget {\n const { scope, config, api } = options;\n const doc = scope.ownerDocument;\n const poll = options.pollMs ?? { thread: 5000, background: 60000 };\n ensureStyles(scope);\n\n let open = false;\n let destroyed = false;\n let view: View = { kind: \"tab\", tab: \"home\" };\n let conversations: MessengerConversation[] = [];\n let messages: MessengerMessage[] = [];\n let current: MessengerConversation | null = null;\n const streaming = new Map<string, string>();\n let sending = false;\n let draft = \"\";\n let articles: SdkArticlesResponse | null = null;\n let articlesLoading = false;\n let threadTimer: ReturnType<typeof setTimeout> | null = null;\n let backgroundTimer: ReturnType<typeof setInterval> | null = null;\n let threadSeq = 0;\n let howTos: SdkHowTosResponse | null = null;\n let howTosSeq = 0;\n /** Loaded how-tos by id; null when it couldn't be loaded (switched off, deleted). */\n const howToCache = new Map<string, SdkHowTo | null>();\n // Page-matched content for the page the visitor is on, refetched when the page changes.\n let page: MessengerPageContent | null = null;\n let pageKey: string | null = null;\n let pageAt = 0;\n let pageSeq = 0;\n let pageLoading = false;\n const PAGE_TTL_MS = 120_000;\n\n const cards = { suggestions: config.home?.suggestions !== false, progress: config.home?.progress !== false, news: config.home?.news !== false };\n const visitor = (): MessengerVisitor => {\n try {\n const v = options.visitor?.();\n if (v) return v;\n } catch {\n /* a broken host callback must not break the messenger */\n }\n return { firstName: null, path: null, pageGuides: [], resumeGuide: null, checklist: null, news: [] };\n };\n const news = () => (cards.news ? visitor().news : []);\n\n const pos = `g-pos-${config.launcher.position}`;\n // Other launchers (checklists, resource center) in the same corner move aside for the chat bubble.\n const rootNode = scope.getRootNode();\n const shadowHost = \"host\" in rootNode ? (rootNode.host as HTMLElement) : null;\n shadowHost?.setAttribute(\"data-g-messenger\", config.launcher.position);\n const root = el(doc, \"div\", \"g-messenger-root\");\n const launcher = el(doc, \"button\", `g-m-launcher ${pos}`);\n launcher.type = \"button\";\n launcher.setAttribute(\"aria-label\", `Open ${config.name}`);\n launcher.setAttribute(\"aria-expanded\", \"false\");\n launcher.appendChild(chatIcon(doc));\n const badge = el(doc, \"span\", \"g-m-badge\");\n badge.hidden = true;\n launcher.appendChild(badge);\n if (options.hideLauncher) launcher.hidden = true;\n\n const panel = el(doc, \"div\", `g-panel g-messenger ${pos}`);\n panel.setAttribute(\"role\", \"dialog\");\n panel.setAttribute(\"aria-label\", config.name);\n panel.hidden = true;\n const head = el(doc, \"div\", \"g-m-head\");\n const main = el(doc, \"div\", \"g-m-main\");\n const tabs = el(doc, \"div\", \"g-m-tabs\");\n tabs.setAttribute(\"role\", \"tablist\");\n panel.append(head, main, tabs);\n root.append(launcher, panel);\n scope.appendChild(root);\n\n const rcExtras = (ids: string[] = []) => ids.map((id) => options.guides?.find((g) => g.id === id || g.key === id)).filter((g): g is HelpGuideRef => !!g);\n const help = createHelpView({\n doc,\n data: (): HelpData => ({\n collections: articles?.collections ?? options.resourceCenter?.collections ?? [],\n articles: articles?.articles ?? options.resourceCenter?.articles ?? [],\n suggested: helpSuggestions(),\n recommended: rcExtras(options.resourceCenter?.recommendedGuideIds),\n checklists: rcExtras(options.resourceCenter?.checklistGuideIds),\n faqs: options.resourceCenter?.faqs,\n links: options.resourceCenter?.links,\n }),\n search: (q) => api.searchArticles(q),\n audienceIds: options.audienceIds,\n loadArticle: (id) => api.getArticle(id),\n onStartGuide: (id) => {\n setOpen(false);\n options.onStartGuide?.(id);\n },\n onOpenChecklist: (id) => {\n setOpen(false);\n options.onOpenChecklist?.(id);\n },\n onArticleView: options.onArticleView,\n extra: (q) => howToItems(q),\n });\n\n const unreadTotal = () => conversations.reduce((n, c) => n + (c.unread > 0 ? 1 : 0), 0);\n const updateBadge = () => {\n const n = unreadTotal();\n badge.hidden = n === 0 || open;\n badge.textContent = n > 9 ? \"9+\" : String(n);\n launcher.setAttribute(\"aria-label\", n ? `Open ${config.name}, ${n} unread` : `Open ${config.name}`);\n };\n\n const upsertConversation = (c: MessengerConversation) => {\n conversations = [c, ...conversations.filter((x) => x.id !== c.id)].sort((a, b) => b.lastMessageAt.localeCompare(a.lastMessageAt));\n if (current?.id === c.id) current = c;\n updateBadge();\n };\n const upsertMessage = (m: MessengerMessage) => {\n const i = messages.findIndex((x) => x.id === m.id);\n if (i >= 0) messages[i] = m;\n else messages.push(m);\n messages.sort((a, b) => a.createdAt.localeCompare(b.createdAt));\n if (m.status !== \"pending\") streaming.delete(m.id);\n };\n\n const loadArticles = () => {\n if (articles || articlesLoading) return;\n articlesLoading = true;\n api\n .listArticles()\n .then((res) => {\n articles = res;\n if (view.kind === \"tab\" && view.tab === \"help\") help.render();\n })\n .catch(() => {})\n .finally(() => (articlesLoading = false));\n };\n\n // How-tos: refreshed on every open, since the page (and so \"Help for this page\") may have changed.\n const loadHowTos = () => {\n if (!api.listHowTos) return;\n const seq = ++howTosSeq;\n api\n .listHowTos()\n .then((res) => {\n if (seq !== howTosSeq || destroyed) return;\n howTos = res;\n if (open && view.kind === \"tab\" && view.tab === \"home\") render();\n else if (open && view.kind === \"tab\" && view.tab === \"help\") help.render();\n })\n .catch(() => {});\n };\n const pageHowTos = (): SdkHowToSummary[] => (howTos?.forPage ?? []).map((id) => howTos?.howTos.find((h) => h.id === id)).filter((h): h is SdkHowToSummary => !!h);\n const stepsLabel = (h: SdkHowToSummary) => `${h.stepCount} ${h.stepCount === 1 ? \"step\" : \"steps\"}`;\n const openHowTo = (id: string) => go({ kind: \"howto\", id, from: view });\n\n /** Help tab search: how-tos matching the query (the page's own are in \"Suggested for this page\"). */\n function howToItems(q: string): Node[] {\n const list = q ? (howTos?.howTos ?? []).filter((h) => h.title.toLowerCase().includes(q) || h.description.toLowerCase().includes(q)).slice(0, 10) : [];\n if (!list.length) return [];\n return [\n el(doc, \"div\", \"g-rc-section\", `How-tos (${list.length})`),\n ...list.map((h) => {\n const b = listItem(doc, \"📋\", h.title, h.description || stepsLabel(h));\n b.addEventListener(\"click\", () => openHowTo(h.id));\n return b;\n }),\n ];\n }\n\n const refreshConversations = () =>\n api\n .listConversations()\n .then((list) => {\n conversations = [...list].sort((a, b) => b.lastMessageAt.localeCompare(a.lastMessageAt));\n updateBadge();\n if (open && view.kind === \"tab\" && view.tab !== \"help\") render();\n })\n .catch(() => {});\n\n // ---------------------------------------------------------------------------\n // Rendering\n // ---------------------------------------------------------------------------\n\n function renderHead(title: string, back?: () => void) {\n head.textContent = \"\";\n head.hidden = false;\n if (back) {\n const b = el(doc, \"button\", \"g-m-back\");\n b.type = \"button\";\n b.setAttribute(\"aria-label\", \"Back\");\n b.appendChild(icon(doc, \"back\"));\n b.addEventListener(\"click\", back);\n head.appendChild(b);\n }\n head.appendChild(el(doc, \"h2\", \"\", title));\n head.appendChild(closeButton(\"g-close\"));\n }\n\n function closeButton(cls: string): HTMLButtonElement {\n const close = el(doc, \"button\", cls);\n close.type = \"button\";\n close.setAttribute(\"aria-label\", \"Close\");\n close.appendChild(icon(doc, \"close\"));\n close.addEventListener(\"click\", () => setOpen(false));\n return close;\n }\n\n function renderTabs() {\n tabs.textContent = \"\";\n tabs.hidden = view.kind !== \"tab\";\n const items: Array<[MessengerTab, keyof typeof ICONS, string]> = [\n [\"home\", \"home\", \"Home\"],\n [\"messages\", \"messages\", \"Messages\"],\n [\"help\", \"help\", \"Help\"],\n ];\n const latest = news();\n if (latest.length) items.push([\"news\", \"news\", \"News\"]);\n for (const [tab, ico, label] of items) {\n const b = el(doc, \"button\", \"g-m-tab\");\n b.type = \"button\";\n b.setAttribute(\"role\", \"tab\");\n b.setAttribute(\"aria-selected\", String(view.kind === \"tab\" && view.tab === tab));\n const i = el(doc, \"span\", \"g-m-tab-icon\");\n i.appendChild(icon(doc, ico));\n b.append(i, el(doc, \"span\", \"\", label));\n if (tab === \"news\" && latest.some((n) => n.unread)) {\n const dot = el(doc, \"span\", \"g-m-tab-dot\");\n dot.setAttribute(\"aria-label\", \"New\");\n i.appendChild(dot);\n }\n b.addEventListener(\"click\", () => go({ kind: \"tab\", tab }));\n tabs.appendChild(b);\n }\n }\n\n function conversationCard(c: MessengerConversation, label?: string): HTMLButtonElement {\n const card = el(doc, \"button\", \"g-m-card\");\n card.type = \"button\";\n const row = el(doc, \"div\", \"g-m-row\");\n if (c.unread > 0) row.appendChild(el(doc, \"span\", \"g-m-dot\"));\n const text = el(doc, \"div\", \"g-m-grow\");\n if (label) text.appendChild(el(doc, \"div\", \"g-m-card-label\", label));\n text.append(el(doc, \"div\", \"g-m-card-title g-m-ellipsis\", c.subject || \"Conversation\"), el(doc, \"div\", \"g-m-card-sub g-m-ellipsis\", c.lastMessagePreview));\n row.append(text, el(doc, \"span\", \"g-m-time\", relativeTime(c.lastMessageAt)));\n card.appendChild(row);\n card.setAttribute(\"aria-label\", `${label ? `${label}: ` : \"\"}${c.subject || \"Conversation\"}${c.unread ? \", unread\" : \"\"}`);\n card.addEventListener(\"click\", () => go({ kind: \"thread\", conversationId: c.id }));\n return card;\n }\n\n /** A full-width card: optional leading icon, title, subtitle and a trailing arrow. */\n function actionCard(opts: { title: string; sub?: string; lead?: SVGSVGElement | HTMLElement; trail?: boolean; onClick: () => void; cls?: string }): HTMLButtonElement {\n const card = el(doc, \"button\", `g-m-card g-m-row g-m-center${opts.cls ? ` ${opts.cls}` : \"\"}`);\n card.type = \"button\";\n if (opts.lead) card.appendChild(opts.lead);\n const text = el(doc, \"span\", \"g-m-grow\");\n text.appendChild(el(doc, \"span\", \"g-m-card-title\", opts.title));\n if (opts.sub) text.appendChild(el(doc, \"span\", \"g-m-card-sub\", opts.sub));\n card.appendChild(text);\n if (opts.trail) card.appendChild(icon(doc, \"arrow\", \"g-m-ico g-m-trail\"));\n card.addEventListener(\"click\", opts.onClick);\n return card;\n }\n\n function progressBar(done: number, total: number): HTMLElement {\n const bar = el(doc, \"span\", \"g-m-bar\");\n bar.setAttribute(\"role\", \"progressbar\");\n bar.setAttribute(\"aria-valuemin\", \"0\");\n bar.setAttribute(\"aria-valuemax\", String(total));\n bar.setAttribute(\"aria-valuenow\", String(done));\n const fill = el(doc, \"span\", \"g-m-bar-fill\");\n fill.style.width = `${total ? Math.round((Math.min(done, total) / total) * 100) : 0}%`;\n bar.appendChild(fill);\n return bar;\n }\n\n function teamAvatars(): HTMLElement | null {\n const team = (config.team ?? []).slice(0, 3);\n if (!team.length) return null;\n const wrap = el(doc, \"div\", \"g-m-team\");\n wrap.setAttribute(\"role\", \"img\");\n wrap.setAttribute(\"aria-label\", `The team: ${team.map((t) => t.name).join(\", \")}`);\n team.forEach((t, i) => {\n const a = el(doc, \"span\", `g-m-avatar g-m-avatar-${i % 3}`);\n if (t.avatarUrl) {\n const img = el(doc, \"img\");\n img.src = t.avatarUrl;\n img.alt = \"\";\n img.referrerPolicy = \"no-referrer\";\n img.addEventListener(\"error\", () => {\n img.remove();\n a.textContent = initialOf(t.name);\n });\n a.appendChild(img);\n } else a.textContent = initialOf(t.name);\n wrap.appendChild(a);\n });\n return wrap;\n }\n\n function brandMark(): HTMLElement {\n const name = options.brand?.name || config.name;\n const mark = el(doc, \"span\", \"g-m-logo\");\n const url = options.brand?.logoUrl;\n if (url && /^(https?:)?\\/\\//.test(url)) {\n const img = el(doc, \"img\");\n img.src = url;\n img.alt = name;\n img.addEventListener(\"error\", () => {\n img.remove();\n mark.textContent = initialOf(name);\n });\n mark.appendChild(img);\n } else {\n mark.textContent = initialOf(name);\n mark.setAttribute(\"aria-label\", name);\n mark.setAttribute(\"role\", \"img\");\n }\n return mark;\n }\n\n function messageSub(): string {\n const reply = config.replyTime ? REPLY_TIME_TEXT[config.replyTime] : null;\n if (config.aiAvailable) return reply ? `${config.name} answers right away. The team ${reply}.` : `${config.name} answers right away, and the team can help too.`;\n return reply ? `The team ${reply}.` : \"The team will reply here.\";\n }\n\n function statusCard(status: MessengerStatus): HTMLElement {\n const meta = STATUS_TEXT[status.level] ?? STATUS_TEXT.operational;\n const card = el(doc, \"div\", `g-m-card g-m-static g-m-row g-m-center g-m-status g-m-status-${status.level}`);\n card.setAttribute(\"role\", \"status\");\n card.appendChild(icon(doc, meta.icon, \"g-m-ico g-m-status-ico\"));\n const text = el(doc, \"span\", \"g-m-grow\");\n text.appendChild(el(doc, \"span\", \"g-m-card-title\", status.message || meta.title));\n const when = shortDateTime(status.updatedAt);\n if (when) text.appendChild(el(doc, \"span\", \"g-m-card-sub\", `Updated ${when}`));\n card.appendChild(text);\n return card;\n }\n\n function progressCards(v: MessengerVisitor): HTMLElement[] {\n const out: HTMLElement[] = [];\n if (v.resumeGuide) {\n const g = v.resumeGuide;\n const card = el(doc, \"button\", \"g-m-card\");\n card.type = \"button\";\n const row = el(doc, \"span\", \"g-m-row g-m-center\");\n row.appendChild(iconTile(\"play\", true));\n const text = el(doc, \"span\", \"g-m-grow\");\n text.append(el(doc, \"span\", \"g-m-card-label\", \"Pick up where you left off\"), el(doc, \"span\", \"g-m-card-title g-m-ellipsis\", g.name), el(doc, \"span\", \"g-m-card-sub\", `Step ${g.stepIndex + 1} of ${g.stepCount}`));\n row.append(text, el(doc, \"span\", \"g-m-link\", \"Resume\"));\n card.append(row, progressBar(g.stepIndex, g.stepCount));\n card.addEventListener(\"click\", () => {\n setOpen(false);\n options.onResumeGuide?.(g.id, g.stepId);\n });\n out.push(card);\n }\n if (v.checklist && v.checklist.total > 0) {\n const c = v.checklist;\n const card = el(doc, \"button\", \"g-m-card\");\n card.type = \"button\";\n const top = el(doc, \"span\", \"g-m-row g-m-baseline\");\n top.append(el(doc, \"span\", \"g-m-card-title g-m-grow g-m-ellipsis\", c.name), el(doc, \"span\", \"g-m-time\", `${c.done} of ${c.total} done`));\n card.append(top, progressBar(c.done, c.total));\n if (c.nextTask) card.appendChild(el(doc, \"span\", \"g-m-card-sub\", `Next: ${c.nextTask}`));\n card.addEventListener(\"click\", () => {\n setOpen(false);\n options.onOpenChecklist?.(c.id);\n });\n out.push(card);\n }\n return out;\n }\n\n function iconTile(name: keyof typeof ICONS, accent = false): HTMLElement {\n const b = el(doc, \"span\", `g-m-badge-ico${accent ? \" g-m-accent\" : \"\"}`);\n b.appendChild(icon(doc, name));\n return b;\n }\n\n interface Suggestion {\n icon: keyof typeof ICONS;\n title: string;\n sub: string;\n accent?: boolean;\n run: () => void;\n }\n\n /**\n * Page-aware suggestions: guides targeted here, how-tos made available in the app that were recorded\n * on this page (they open right here), then how-tos and articles matched by the server.\n */\n function pageSuggestions(v: MessengerVisitor, max = 4): Suggestion[] {\n if (!cards.suggestions) return [];\n const out: Suggestion[] = [];\n for (const g of v.pageGuides.slice(0, 2)) {\n out.push({ icon: \"play\", title: g.name, sub: g.kind === \"checklist\" ? \"Checklist\" : \"Interactive guide\", accent: true, run: () => (g.kind === \"checklist\" ? openChecklist(g.id) : startGuide(g.key || g.id)) });\n }\n const inApp = new Set<string>();\n for (const h of pageHowTos()) {\n if (out.length >= max) break;\n inApp.add(h.title.toLowerCase());\n out.push({ icon: \"steps\", title: h.title, sub: `How-to · ${stepsLabel(h)}`, run: () => openHowTo(h.id) });\n }\n for (const s of page?.suggestions ?? []) {\n if (out.length >= max) break;\n // The same how-to's help article, when it's already listed to open in place.\n if (s.type === \"howto\" && inApp.has(s.title.toLowerCase())) continue;\n if (s.type === \"howto\") out.push({ icon: \"steps\", title: s.title, sub: `How-to · ${s.steps} ${s.steps === 1 ? \"step\" : \"steps\"}`, run: () => openArticle(s.articleId) });\n else out.push({ icon: \"article\", title: s.title, sub: s.summary || \"Article\", run: () => openArticle(s.articleId) });\n }\n return out.slice(0, max);\n }\n\n function startGuide(keyOrId: string) {\n setOpen(false);\n options.onStartGuide?.(keyOrId);\n }\n\n function openChecklist(id: string) {\n setOpen(false);\n options.onOpenChecklist?.(id);\n }\n\n /** Asks Scout one of the page's common questions in a new conversation. */\n function ask(question: string) {\n go({ kind: \"thread\", conversationId: null });\n if (!textarea) return;\n textarea.value = question;\n submit();\n }\n\n function suggestionButton(s: Suggestion): HTMLButtonElement {\n const b = el(doc, \"button\", \"g-m-item\");\n b.type = \"button\";\n b.appendChild(iconTile(s.icon, s.accent));\n const text = el(doc, \"span\", \"g-m-grow\");\n text.append(el(doc, \"span\", \"g-m-item-title\", s.title), el(doc, \"span\", \"g-m-card-sub g-m-ellipsis\", s.sub));\n b.appendChild(text);\n b.addEventListener(\"click\", s.run);\n return b;\n }\n\n function newsCard(n: MessengerNewsItem): HTMLButtonElement {\n const card = el(doc, \"button\", \"g-m-card g-m-news\");\n card.type = \"button\";\n if (n.imageUrl && /^https?:\\/\\//.test(n.imageUrl)) {\n const img = el(doc, \"img\", \"g-m-news-img\");\n img.src = n.imageUrl;\n img.alt = \"\";\n img.loading = \"lazy\";\n img.addEventListener(\"error\", () => img.remove());\n card.appendChild(img);\n }\n const body = el(doc, \"span\", \"g-m-news-body\");\n const meta = el(doc, \"span\", \"g-m-row g-m-center g-m-news-meta\");\n if (n.unread) meta.appendChild(el(doc, \"span\", \"g-m-tag\", \"New\"));\n meta.appendChild(el(doc, \"span\", \"g-m-time\", shortDate(n.publishedAt)));\n body.append(meta, el(doc, \"span\", \"g-m-card-title\", n.title));\n if (n.body) body.appendChild(el(doc, \"span\", \"g-m-card-sub g-m-clamp\", n.body));\n card.appendChild(body);\n card.addEventListener(\"click\", () => startGuide(n.key || n.id));\n return card;\n }\n\n function renderHome() {\n head.hidden = true;\n const v = visitor();\n loadPage();\n const scroll = el(doc, \"div\", \"g-m-scroll g-m-home\");\n const hero = el(doc, \"div\", \"g-m-hero-bg\");\n hero.setAttribute(\"aria-hidden\", \"true\");\n const inner = el(doc, \"div\", \"g-m-home-inner\");\n const top = el(doc, \"div\", \"g-m-hero-top\");\n const right = el(doc, \"div\", \"g-m-row g-m-center\");\n const team = teamAvatars();\n if (team) right.appendChild(team);\n right.appendChild(closeButton(\"g-m-hero-close\"));\n top.append(brandMark(), right);\n const hello = el(doc, \"h2\", \"g-m-hello\");\n hello.append(el(doc, \"span\", \"g-m-hello-1\", v.firstName ? `Hi ${v.firstName}.` : \"Hi there.\"), el(doc, \"span\", \"g-m-hello-2\", \"How can we help?\"));\n inner.append(top, hello);\n\n inner.appendChild(actionCard({ title: \"Send us a message\", sub: messageSub(), trail: true, onClick: () => go({ kind: \"thread\", conversationId: null }) }));\n const recent = conversations[0];\n if (recent) inner.appendChild(conversationCard(recent, recent.status === \"closed\" && !recent.unread ? \"Recent conversation\" : \"Continue the conversation\"));\n if (config.status) inner.appendChild(statusCard(config.status));\n if (cards.progress) progressCards(v).forEach((c) => inner.appendChild(c));\n\n const suggestions = pageSuggestions(v);\n const questions = cards.suggestions ? (page?.questions ?? []).slice(0, 2) : [];\n const label = v.path ? pageLabel(v.path) : null;\n const fallback = !suggestions.length && !questions.length ? rcExtras(options.resourceCenter?.recommendedGuideIds).slice(0, 3) : [];\n if (suggestions.length || questions.length || fallback.length) {\n const box = el(doc, \"div\", \"g-m-card g-m-static g-m-suggest\");\n box.appendChild(el(doc, \"div\", \"g-m-card-title\", fallback.length ? \"Recommended\" : \"Suggested for you\"));\n if (!fallback.length && label) box.appendChild(el(doc, \"div\", \"g-m-card-sub\", `For the ${label} page`));\n const list = el(doc, \"div\", \"g-m-items\");\n suggestions.forEach((s) => list.appendChild(suggestionButton(s)));\n questions.forEach((q) => list.appendChild(suggestionButton({ icon: \"ask\", title: q, sub: config.aiAvailable ? `Ask ${config.name}` : \"Ask the team\", run: () => ask(q) })));\n fallback.forEach((g) => list.appendChild(suggestionButton({ icon: \"play\", title: g.name, sub: \"Interactive guide\", accent: true, run: () => startGuide(g.key || g.id) })));\n box.appendChild(list);\n inner.appendChild(box);\n }\n\n const latest = news()[0];\n if (latest) inner.appendChild(newsCard(latest));\n inner.appendChild(actionCard({ title: \"Search for help\", sub: \"Articles, guides and how-tos\", lead: icon(doc, \"search\", \"g-m-ico g-m-lead\"), onClick: () => go({ kind: \"tab\", tab: \"help\" }) }));\n scroll.append(hero, inner);\n main.appendChild(scroll);\n }\n\n function renderHowToView(id: string, from: View) {\n const cached = howToCache.get(id);\n renderHead(cached?.title ?? \"How-to\", () => go(from));\n const scroll = el(doc, \"div\", \"g-m-scroll\");\n if (cached) {\n scroll.appendChild(\n renderHowTo(doc, cached, (key) => {\n setOpen(false);\n options.onStartGuide?.(key);\n }),\n );\n } else scroll.appendChild(el(doc, \"div\", \"g-m-empty\", cached === null ? \"This how-to isn't available any more.\" : \"Loading…\"));\n main.appendChild(scroll);\n if (cached !== undefined || !api.getHowTo) return;\n const seq = threadSeq;\n api\n .getHowTo(id)\n .catch(() => null)\n .then((h) => {\n howToCache.set(id, h);\n if (seq === threadSeq && view.kind === \"howto\" && view.id === id) render();\n });\n }\n\n function renderMessagesTab() {\n renderHead(\"Messages\");\n const scroll = el(doc, \"div\", \"g-m-scroll\");\n if (!conversations.length) scroll.appendChild(el(doc, \"div\", \"g-m-empty\", \"No conversations yet.\"));\n conversations.forEach((c) => scroll.appendChild(conversationCard(c)));\n const start = el(doc, \"button\", \"g-btn g-btn-primary g-m-wide\", \"Send us a message\");\n start.type = \"button\";\n start.addEventListener(\"click\", () => go({ kind: \"thread\", conversationId: null }));\n scroll.appendChild(start);\n main.appendChild(scroll);\n }\n\n /** The Help tab's \"Suggested for this page\" section. */\n function helpSuggestions(): HelpData[\"suggested\"] {\n const v = visitor();\n const items = pageSuggestions(v, 5).map<HelpSuggestion>((s) => ({ kind: s.icon === \"play\" ? \"guide\" : s.icon === \"steps\" ? \"howto\" : \"article\", title: s.title, summary: s.sub, run: s.run }));\n if (!items.length) return undefined;\n const label = v.path ? pageLabel(v.path) : null;\n return { title: label ? `For the ${label} page` : \"Suggested for you\", items };\n }\n\n function renderHelpTab() {\n renderHead(\"Help\");\n loadArticles();\n loadPage();\n help.render();\n main.appendChild(help.el);\n }\n\n function renderNewsTab() {\n renderHead(\"News\");\n const scroll = el(doc, \"div\", \"g-m-scroll\");\n const items = news();\n if (!items.length) scroll.appendChild(el(doc, \"div\", \"g-m-empty\", \"No news yet.\"));\n items.forEach((n) => scroll.appendChild(newsCard(n)));\n main.appendChild(scroll);\n const unread = items.filter((n) => n.unread).map((n) => n.id);\n if (unread.length) options.onNewsSeen?.(unread);\n }\n\n /** Fetches page-matched content when the page changed (or it went stale), then re-renders. */\n function loadPage(force = false) {\n const path = visitor().path;\n if (!path || !api.pageContent || !cards.suggestions) {\n page = null;\n pageKey = null;\n return;\n }\n const key = foldPathIds(path).toLowerCase();\n if (!force && key === pageKey && (pageLoading || Date.now() - pageAt < PAGE_TTL_MS)) return;\n if (key !== pageKey) page = null;\n pageKey = key;\n pageLoading = true;\n const seq = ++pageSeq;\n api\n .pageContent(path)\n .then((res) => {\n if (seq !== pageSeq) return;\n page = res;\n pageAt = Date.now();\n if (!open) return;\n if (view.kind === \"tab\" && view.tab === \"home\") render();\n else if (view.kind === \"tab\" && view.tab === \"help\") help.render();\n else if (view.kind === \"thread\" && !messages.length) renderLog();\n })\n .catch(() => {\n if (seq === pageSeq) pageAt = Date.now();\n })\n .finally(() => {\n if (seq === pageSeq) pageLoading = false;\n });\n }\n\n let log: HTMLElement | null = null;\n let foot: HTMLElement | null = null;\n let textarea: HTMLTextAreaElement | null = null;\n let sendButton: HTMLButtonElement | null = null;\n\n function messageNode(m: MessengerMessage): HTMLElement {\n const wrap = el(doc, \"div\", `g-m-msg g-from-${m.author}${m.status === \"failed\" ? \" g-m-failed\" : \"\"}`);\n if (m.author === \"system\") {\n wrap.textContent = m.body;\n return wrap;\n }\n if (m.author !== \"user\") {\n const author = el(doc, \"div\", \"g-m-author\", m.author === \"scout\" ? config.name : m.authorName || \"Support team\");\n if (m.author === \"scout\") author.appendChild(el(doc, \"span\", \"g-m-ai\", \"AI\"));\n wrap.appendChild(author);\n }\n const bubble = el(doc, \"div\", \"g-m-bubble\");\n const live = streaming.get(m.id);\n if (m.status === \"pending\" && !live) {\n const dots = el(doc, \"span\", \"g-m-typing\");\n dots.setAttribute(\"aria-label\", `${config.name} is typing`);\n dots.append(el(doc, \"span\"), el(doc, \"span\"), el(doc, \"span\"));\n bubble.appendChild(dots);\n } else if (m.status === \"failed\") {\n bubble.textContent = \"This reply couldn't be completed.\";\n } else {\n bubble.appendChild(renderSafeText(doc, live ?? m.body));\n }\n if (m.status === \"pending\") bubble.setAttribute(\"aria-busy\", \"true\");\n bubble.dataset.messageId = m.id;\n wrap.appendChild(bubble);\n if (m.citations.length || m.suggestedGuides.length || m.howTos?.length) {\n const chips = el(doc, \"div\", \"g-m-chips\");\n for (const g of m.suggestedGuides) {\n const b = el(doc, \"button\", \"g-m-chip g-m-guide\", `▶ Show me: ${g.name}`);\n b.type = \"button\";\n b.addEventListener(\"click\", () => {\n setOpen(false);\n options.onStartGuide?.(g.key);\n });\n chips.appendChild(b);\n }\n for (const c of m.citations) {\n const b = el(doc, \"button\", \"g-m-chip\", `📄 ${c.title}`);\n b.type = \"button\";\n b.addEventListener(\"click\", () => openArticle(c.articleId));\n chips.appendChild(b);\n }\n for (const h of m.howTos ?? []) {\n const b = el(doc, \"button\", \"g-m-chip\", `📋 ${h.title}`);\n b.type = \"button\";\n b.addEventListener(\"click\", () => openHowTo(h.howToId));\n chips.appendChild(b);\n }\n wrap.appendChild(chips);\n }\n return wrap;\n }\n\n function renderLog() {\n if (!log) return;\n const atBottom = log.scrollHeight - log.scrollTop - log.clientHeight < 40;\n log.textContent = \"\";\n if (!messages.length) {\n const v = visitor();\n const label = v.path ? pageLabel(v.path) : null;\n if (label && config.aiAvailable && !current) log.appendChild(el(doc, \"div\", \"g-m-context\", `Asking from the ${label} page`));\n const intro: MessengerMessage = { id: \"intro\", author: config.aiAvailable ? \"scout\" : \"agent\", authorName: \"Support team\", body: personalGreeting(config.greeting, v.firstName), citations: [], suggestedGuides: [], status: \"complete\", createdAt: new Date().toISOString() };\n log.appendChild(messageNode(intro));\n const questions = !current && cards.suggestions ? (page?.questions ?? []) : [];\n if (questions.length && !sending) {\n const chips = el(doc, \"div\", \"g-m-chips g-m-asks\");\n chips.setAttribute(\"aria-label\", \"Common questions on this page\");\n for (const q of questions) {\n const b = el(doc, \"button\", \"g-m-chip g-m-ask\", q);\n b.type = \"button\";\n b.addEventListener(\"click\", () => {\n if (!textarea || sending) return;\n textarea.value = q;\n submit();\n });\n chips.appendChild(b);\n }\n log.appendChild(chips);\n }\n }\n messages.forEach((m) => log!.appendChild(messageNode(m)));\n if (atBottom || sending) log.scrollTop = log.scrollHeight;\n renderFoot();\n }\n\n function renderFoot() {\n if (!foot || !textarea || !sendButton) return;\n sendButton.disabled = sending || !textarea.value.trim();\n textarea.disabled = sending;\n for (const extra of Array.from(foot.querySelectorAll(\".g-m-human,.g-m-rate,.g-m-note\"))) extra.remove();\n if (current?.status === \"closed\" && current.rating == null) {\n const rate = el(doc, \"div\", \"g-m-rate\", \"How was this conversation? \");\n for (const [score, face, label] of [\n [1, \"😞\", \"Bad\"],\n [3, \"😐\", \"OK\"],\n [5, \"😀\", \"Great\"],\n ] as const) {\n const b = el(doc, \"button\", \"\", face);\n b.type = \"button\";\n b.setAttribute(\"aria-label\", label);\n b.addEventListener(\"click\", () => {\n if (!current) return;\n const id = current.id;\n current = { ...current, rating: score };\n upsertConversation(current);\n renderFoot();\n api.rate(id, score).catch(() => {});\n });\n rate.appendChild(b);\n }\n foot.prepend(rate);\n } else if (current && current.rating != null && current.status === \"closed\") {\n foot.prepend(el(doc, \"div\", \"g-m-note\", \"Thanks for the feedback!\"));\n }\n if (config.handoffEnabled && config.aiAvailable && current?.status === \"bot\" && !sending) {\n const human = el(doc, \"button\", \"g-m-human\", \"Talk to a person\");\n human.type = \"button\";\n human.addEventListener(\"click\", () => {\n if (!current) return;\n const id = current.id;\n human.disabled = true;\n api\n .handoff(id)\n .then((res) => {\n if (current?.id !== id) return;\n upsertConversation(res.conversation);\n res.messages.forEach(upsertMessage);\n renderLog();\n })\n .catch(() => (human.disabled = false));\n });\n foot.appendChild(human);\n }\n }\n\n function renderThread(conversationId: string | null) {\n renderHead(current?.subject || (conversationId ? \"Conversation\" : \"New conversation\"), () => go({ kind: \"tab\", tab: \"messages\" }));\n log = el(doc, \"div\", \"g-m-log\");\n log.setAttribute(\"role\", \"log\");\n log.setAttribute(\"aria-live\", \"polite\");\n foot = el(doc, \"div\", \"g-m-foot\");\n const compose = el(doc, \"form\", \"g-m-compose\");\n textarea = el(doc, \"textarea\");\n textarea.rows = 1;\n textarea.maxLength = 4000;\n textarea.placeholder = current?.status === \"open\" ? \"Reply to the team…\" : \"Ask a question…\";\n textarea.setAttribute(\"aria-label\", \"Message\");\n textarea.value = draft;\n sendButton = el(doc, \"button\", \"g-m-send\");\n sendButton.appendChild(icon(doc, \"arrow\"));\n sendButton.type = \"submit\";\n sendButton.setAttribute(\"aria-label\", \"Send\");\n compose.append(textarea, sendButton);\n foot.appendChild(compose);\n textarea.addEventListener(\"input\", () => {\n draft = textarea!.value;\n if (sendButton) sendButton.disabled = sending || !draft.trim();\n });\n textarea.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\" && !e.shiftKey && !e.isComposing) {\n e.preventDefault();\n submit();\n }\n });\n compose.addEventListener(\"submit\", (e) => {\n e.preventDefault();\n submit();\n });\n main.append(log, foot);\n renderLog();\n textarea.focus?.({ preventScroll: true });\n }\n\n function render() {\n if (destroyed) return;\n main.textContent = \"\";\n log = foot = null;\n textarea = null;\n sendButton = null;\n if (view.kind === \"thread\") renderThread(view.conversationId);\n else if (view.kind === \"howto\") renderHowToView(view.id, view.from);\n else if (view.tab === \"home\") renderHome();\n else if (view.tab === \"messages\") renderMessagesTab();\n else if (view.tab === \"news\" && news().length) renderNewsTab();\n else if (view.tab === \"news\") {\n view = { kind: \"tab\", tab: \"home\" };\n renderHome();\n } else renderHelpTab();\n renderTabs();\n }\n\n // ---------------------------------------------------------------------------\n // Behaviour\n // ---------------------------------------------------------------------------\n\n const handlers = (seq: number): MessengerStreamHandlers => ({\n onConversation(c) {\n if (seq !== threadSeq) return;\n current = c;\n view = { kind: \"thread\", conversationId: c.id };\n upsertConversation(c);\n },\n onMessage(m) {\n if (seq !== threadSeq) return;\n upsertMessage(m);\n renderLog();\n },\n onDelta(id, text) {\n if (seq !== threadSeq) return;\n streaming.set(id, (streaming.get(id) ?? \"\") + text);\n const bubble = log?.querySelector<HTMLElement>(`[data-message-id=\"${id}\"]`);\n if (!bubble) return renderLog();\n bubble.textContent = \"\";\n bubble.appendChild(renderSafeText(doc, streaming.get(id)!));\n if (log) log.scrollTop = log.scrollHeight;\n },\n onDone(m, c) {\n if (seq !== threadSeq) return;\n if (m) {\n upsertMessage(m);\n options.onMessage?.(m, c);\n }\n upsertConversation({ ...c, unread: 0 });\n current = { ...c, unread: 0 };\n },\n onError() {\n /* the server also stores a system message explaining what happened */\n },\n });\n\n function submit() {\n if (!textarea || sending) return;\n const text = textarea.value.trim();\n if (!text) return;\n sending = true;\n draft = \"\";\n textarea.value = \"\";\n renderFoot();\n const seq = threadSeq;\n const h = handlers(seq);\n const done = current ? api.send(current.id, text, h) : api.start(text, h);\n done\n .catch(() => {\n if (seq !== threadSeq) return;\n draft = text;\n if (textarea) textarea.value = text;\n const note: MessengerMessage = { id: `local_${Date.now()}`, author: \"system\", body: \"Your message couldn't be sent. Please try again.\", citations: [], suggestedGuides: [], status: \"complete\", createdAt: new Date().toISOString() };\n upsertMessage(note);\n })\n .finally(() => {\n if (seq !== threadSeq) return;\n sending = false;\n streaming.clear();\n if (view.kind === \"thread\") {\n if (current) renderHead(current.subject || \"Conversation\", () => go({ kind: \"tab\", tab: \"messages\" }));\n renderLog();\n }\n scheduleThreadPoll();\n });\n }\n\n function scheduleThreadPoll() {\n if (threadTimer) clearTimeout(threadTimer);\n threadTimer = null;\n if (!open || view.kind !== \"thread\" || !current || destroyed) return;\n threadTimer = setTimeout(pollThread, poll.thread);\n }\n\n function pollThread() {\n if (!current || sending) return scheduleThreadPoll();\n const seq = threadSeq;\n const pending = messages.find((m) => m.status === \"pending\");\n const last = messages.filter((m) => !m.id.startsWith(\"local_\")).at(-1);\n // Re-fetch from a pending reply (its body changes in place); otherwise only newer messages.\n const since = pending ? new Date(Date.parse(pending.createdAt) - 1).toISOString() : (last?.createdAt ?? null);\n api\n .loadMessages(current.id, since)\n .then((res) => {\n if (seq !== threadSeq) return;\n const before = messages.length;\n const changed = res.messages.some((m) => {\n const prev = messages.find((x) => x.id === m.id);\n return !prev || prev.status !== m.status || prev.body !== m.body;\n });\n res.messages.forEach(upsertMessage);\n upsertConversation({ ...res.conversation, unread: 0 });\n current = { ...res.conversation, unread: 0 };\n if (changed || messages.length !== before) {\n renderLog();\n res.messages.filter((m) => m.author !== \"user\").forEach((m) => options.onMessage?.(m, res.conversation));\n } else renderFoot();\n })\n .catch(() => {})\n .finally(scheduleThreadPoll);\n }\n\n function go(next: View) {\n threadSeq++;\n if (threadTimer) clearTimeout(threadTimer);\n threadTimer = null;\n // Opening a how-to from Help keeps the search, so Back returns to the same results.\n if (view.kind === \"tab\" && view.tab === \"help\" && !(next.kind === \"tab\" && next.tab === \"help\") && next.kind !== \"howto\") help.reset();\n view = next;\n if (next.kind === \"thread\") {\n messages = [];\n streaming.clear();\n sending = false;\n current = next.conversationId ? (conversations.find((c) => c.id === next.conversationId) ?? null) : null;\n if (!next.conversationId) loadPage();\n render();\n if (next.conversationId) {\n const seq = threadSeq;\n api\n .loadMessages(next.conversationId)\n .then((res) => {\n if (seq !== threadSeq) return;\n res.messages.forEach(upsertMessage);\n current = { ...res.conversation, unread: 0 };\n upsertConversation(current);\n renderHead(current.subject || \"Conversation\", () => go({ kind: \"tab\", tab: \"messages\" }));\n renderLog();\n })\n .catch(() => {})\n .finally(scheduleThreadPoll);\n }\n } else {\n draft = \"\";\n render();\n }\n }\n\n function openArticle(id: string) {\n go({ kind: \"tab\", tab: \"help\" });\n help.openArticle(id);\n }\n\n function startBackgroundPoll() {\n if (backgroundTimer) clearInterval(backgroundTimer);\n backgroundTimer = setInterval(() => {\n if (!open && conversations.length && !destroyed) void refreshConversations();\n }, poll.background);\n }\n\n const setOpen = (v: boolean) => {\n if (open === v || destroyed) return;\n open = v;\n panel.hidden = !v;\n launcher.setAttribute(\"aria-expanded\", String(v));\n launcher.setAttribute(\"aria-label\", v ? `Close ${config.name}` : `Open ${config.name}`);\n updateBadge();\n if (v) {\n render();\n void refreshConversations();\n loadHowTos();\n if (view.kind === \"thread\") scheduleThreadPoll();\n options.onOpen?.();\n } else {\n if (threadTimer) clearTimeout(threadTimer);\n threadTimer = null;\n options.onClose?.();\n }\n };\n launcher.addEventListener(\"click\", () => setOpen(!open));\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n e.stopPropagation();\n setOpen(false);\n launcher.focus();\n }\n };\n panel.addEventListener(\"keydown\", onKey);\n\n void refreshConversations();\n startBackgroundPoll();\n\n return {\n el: root,\n open(tab?: MessengerTab) {\n if (tab) view = { kind: \"tab\", tab };\n if (open && tab) render();\n setOpen(true);\n },\n close: () => setOpen(false),\n toggle: () => setOpen(!open),\n isOpen: () => open,\n showNewMessage(text?: string) {\n setOpen(true);\n go({ kind: \"thread\", conversationId: null });\n if (text && textarea) {\n textarea.value = text.slice(0, 4000);\n draft = textarea.value;\n renderFoot();\n }\n },\n openArticle(id: string) {\n setOpen(true);\n openArticle(id);\n },\n refresh() {\n if (destroyed) return;\n if (!open) {\n // Refetched on the next open; the tab bar (News) may change meanwhile.\n pageKey = null;\n return;\n }\n loadPage();\n if (view.kind === \"tab\") render();\n else if (!messages.length) renderLog();\n },\n destroy() {\n destroyed = true;\n if (threadTimer) clearTimeout(threadTimer);\n if (backgroundTimer) clearInterval(backgroundTimer);\n panel.removeEventListener(\"keydown\", onKey);\n help.destroy();\n shadowHost?.removeAttribute(\"data-g-messenger\");\n root.remove();\n },\n };\n}\n","import type { ResourceCenterArticle, ResourceCenterConfig } from \"@guidelytech/shared\";\nimport { isArticleListed, resourceCenterSections } from \"@guidelytech/shared/runtime\";\nimport { enhancePdfViewers } from \"./pdf-viewer\";\nimport { setSanitizedHtml } from \"./sanitize\";\n\nexport interface HelpGuideRef {\n id: string;\n key: string;\n name: string;\n kind: string;\n}\n\n/** A page-aware suggestion at the top of the help view (the messenger works out what and how it opens). */\nexport interface HelpSuggestion {\n kind: \"guide\" | \"howto\" | \"article\";\n title: string;\n summary?: string;\n run: () => void;\n}\n\n/** What the help view lists. Article bodies may be missing (`bodyOmitted` or summaries only): they load on open. */\nexport interface HelpData {\n collections: ResourceCenterConfig[\"collections\"];\n articles: Array<Omit<ResourceCenterArticle, \"body\"> & { body?: string }>;\n /** Shown first, under its own title (\"For the Invoices page\"). */\n suggested?: { title: string; items: HelpSuggestion[] };\n recommended?: HelpGuideRef[];\n checklists?: HelpGuideRef[];\n faqs?: ResourceCenterConfig[\"faqs\"];\n links?: ResourceCenterConfig[\"links\"];\n}\n\nexport interface HelpViewOptions {\n doc: Document;\n data: () => HelpData;\n /** Server search. Results are merged with the client-side title/summary filter. */\n search?: (q: string) => Promise<ResourceCenterArticle[]>;\n /** The visitor's audiences; articles and collections targeted at others aren't listed. */\n audienceIds?: () => ReadonlySet<string> | readonly string[];\n /** Loads an article body that isn't in `data()`. */\n loadArticle?: (id: string) => Promise<ResourceCenterArticle | null>;\n onStartGuide?: (guideId: string) => void;\n onOpenChecklist?: (guideId: string) => void;\n onArticleView?: (article: ResourceCenterArticle) => void;\n /** Extra items above the list (`query` empty) or above the article results (the messenger's how-tos). */\n extra?: (query: string) => Node[];\n}\n\nexport interface HelpView {\n /** Search box + scrollable body. */\n el: HTMLElement;\n render(): void;\n /** Back to the article list and clear the search. */\n reset(): void;\n openArticle(id: string): void;\n focusSearch(): void;\n setQuery(q: string): void;\n destroy(): void;\n}\n\nexport function el<K extends keyof HTMLElementTagNameMap>(doc: Document, tag: K, cls?: string, text?: string): HTMLElementTagNameMap[K] {\n const e = doc.createElement(tag);\n if (cls) e.className = cls;\n if (text != null) e.textContent = text;\n return e;\n}\n\nexport function listItem(doc: Document, icon: string, title: string, summary?: string): HTMLButtonElement {\n const b = el(doc, \"button\", \"g-rc-item\");\n b.type = \"button\";\n const i = el(doc, \"span\", \"g-rc-icon\", icon);\n i.setAttribute(\"aria-hidden\", \"true\");\n const text = el(doc, \"span\");\n text.appendChild(el(doc, \"div\", \"g-rc-title\", title));\n if (summary) text.appendChild(el(doc, \"div\", \"g-rc-sum\", summary));\n b.append(i, text);\n return b;\n}\n\ntype ListedArticle = HelpData[\"articles\"][number];\n\n/** Article browser shared by the resource center and the messenger Help tab. */\nexport function createHelpView(options: HelpViewOptions): HelpView {\n const { doc } = options;\n let query = \"\";\n let serverResults: ResourceCenterArticle[] = [];\n let searchSeq = 0;\n let openSeq = 0;\n let active: { article: ListedArticle; loading: boolean } | null = null;\n\n const root = el(doc, \"div\", \"g-help\");\n const searchWrap = el(doc, \"div\", \"g-rc-search\");\n const input = el(doc, \"input\", \"g-input\");\n input.type = \"search\";\n input.placeholder = \"Search help articles…\";\n input.setAttribute(\"aria-label\", \"Search help articles\");\n searchWrap.appendChild(input);\n const body = el(doc, \"div\", \"g-panel-body\");\n root.append(searchWrap, body);\n\n const hasBody = (a: ListedArticle): a is ResourceCenterArticle => typeof a.body === \"string\" && !a.bodyOmitted;\n\n const openArticle = (article: ListedArticle) => {\n if (article.externalUrl) {\n window.open(article.externalUrl, \"_blank\", \"noopener,noreferrer\");\n if (hasBody(article)) options.onArticleView?.(article);\n return;\n }\n const seq = ++openSeq;\n if (hasBody(article) || !options.loadArticle) {\n active = { article, loading: false };\n if (hasBody(article)) options.onArticleView?.(article);\n return render();\n }\n active = { article, loading: true };\n render();\n options\n .loadArticle(article.id)\n .then((full) => {\n if (seq !== openSeq || !active) return;\n active = { article: full ?? { ...article, body: \"\" }, loading: false };\n if (full) options.onArticleView?.(full);\n render();\n })\n .catch(() => {\n if (seq !== openSeq || !active) return;\n active = { article: { ...article, body: \"\" }, loading: false };\n render();\n });\n };\n\n const renderArticle = ({ article, loading }: NonNullable<typeof active>) => {\n const wrap = el(doc, \"div\", \"g-rc-article\");\n const back = el(doc, \"button\", \"g-btn g-btn-link g-rc-back\", \"← Back\");\n back.type = \"button\";\n back.addEventListener(\"click\", () => {\n openSeq++;\n active = null;\n render();\n });\n const title = el(doc, \"h3\", \"g-title\", article.title);\n const content = el(doc, \"div\", \"g-body\");\n if (loading) content.appendChild(el(doc, \"div\", \"g-rc-empty\", \"Loading…\"));\n else if (article.body) {\n setSanitizedHtml(content, article.body);\n enhancePdfViewers(content, doc);\n }\n else content.appendChild(el(doc, \"div\", \"g-rc-empty\", \"This article couldn't be loaded.\"));\n wrap.append(back, title, content);\n body.appendChild(wrap);\n back.focus?.({ preventScroll: true });\n };\n\n const section = (label: string, depth = 0) => {\n const s = body.appendChild(el(doc, \"div\", \"g-rc-section\", label));\n if (depth) s.dataset.depth = String(depth);\n return s;\n };\n const articleButton = (a: ListedArticle) => {\n const b = listItem(doc, \"📄\", a.title, a.summary);\n b.addEventListener(\"click\", () => openArticle(a));\n body.appendChild(b);\n };\n\n function render() {\n body.textContent = \"\";\n if (active) return renderArticle(active);\n const data = options.data();\n const member = options.audienceIds?.() ?? [];\n const sections = resourceCenterSections(data.collections, data.articles, member);\n const q = query.trim().toLowerCase();\n body.append(...(options.extra?.(q) ?? []));\n if (q) {\n const visible = sections.flatMap((s) => s.articles);\n const local = visible.filter((a) => a.title.toLowerCase().includes(q) || a.summary.toLowerCase().includes(q));\n const seen = new Set(local.map((a) => a.id));\n // Server search covers every published article: keep only the ones listed for this visitor.\n const hidden = new Set(data.articles.map((a) => a.id).filter((id) => !visible.some((v) => v.id === id)));\n const merged: ListedArticle[] = [...local, ...serverResults.filter((a) => !seen.has(a.id) && !hidden.has(a.id) && isArticleListed(data.collections, a, member))];\n section(`Results (${merged.length})`);\n if (!merged.length) body.appendChild(el(doc, \"div\", \"g-rc-empty\", \"No articles match your search.\"));\n merged.forEach(articleButton);\n return;\n }\n if (data.suggested?.items.length) {\n section(data.suggested.title);\n const glyph = { guide: \"▶\", howto: \"☰\", article: \"📄\" } as const;\n data.suggested.items.forEach((item) => {\n const b = listItem(doc, glyph[item.kind], item.title, item.summary);\n b.addEventListener(\"click\", item.run);\n body.appendChild(b);\n });\n }\n if (data.recommended?.length) {\n section(\"Recommended\");\n data.recommended.forEach((g) => {\n const b = listItem(doc, \"▶\", g.name, \"Start guide\");\n b.addEventListener(\"click\", () => options.onStartGuide?.(g.id));\n body.appendChild(b);\n });\n }\n if (data.checklists?.length) {\n section(\"Checklists\");\n data.checklists.forEach((g) => {\n const b = listItem(doc, \"☑\", g.name, \"Open checklist\");\n b.addEventListener(\"click\", () => options.onOpenChecklist?.(g.id));\n body.appendChild(b);\n });\n }\n // Nested collections read as \"Billing › Invoices\", depth first.\n for (const s of sections) {\n section(s.collection ? s.path.join(\" › \") : \"Articles\", s.depth);\n s.articles.forEach(articleButton);\n }\n if (data.faqs?.length) {\n section(\"FAQ\");\n data.faqs.forEach((f) => {\n const b = listItem(doc, \"?\", f.question);\n b.setAttribute(\"aria-expanded\", \"false\");\n const a = el(doc, \"div\", \"g-faq-a\");\n setSanitizedHtml(a, f.answer);\n a.hidden = true;\n b.addEventListener(\"click\", () => {\n a.hidden = !a.hidden;\n b.setAttribute(\"aria-expanded\", String(!a.hidden));\n });\n body.append(b, a);\n });\n }\n if (data.links?.length) {\n section(\"Links\");\n data.links.forEach((l) => {\n const a = el(doc, \"a\", \"g-rc-item\");\n a.href = l.url;\n a.target = \"_blank\";\n a.rel = \"noopener noreferrer\";\n const i = el(doc, \"span\", \"g-rc-icon\", \"↗\");\n i.setAttribute(\"aria-hidden\", \"true\");\n a.append(i, el(doc, \"span\", \"g-rc-title\", l.label));\n body.appendChild(a);\n });\n }\n if (!body.childNodes.length) body.appendChild(el(doc, \"div\", \"g-rc-empty\", \"Nothing here yet.\"));\n }\n\n let debounce: ReturnType<typeof setTimeout> | null = null;\n const onInput = () => {\n query = input.value;\n openSeq++;\n active = null;\n render();\n if (debounce) clearTimeout(debounce);\n if (!options.search || !query.trim()) {\n serverResults = [];\n return;\n }\n const seq = ++searchSeq;\n debounce = setTimeout(() => {\n options\n .search?.(query.trim())\n .then((results) => {\n if (seq !== searchSeq) return;\n serverResults = Array.isArray(results) ? results : [];\n render();\n })\n .catch(() => {});\n }, 250);\n };\n input.addEventListener(\"input\", onInput);\n\n return {\n el: root,\n render,\n reset() {\n openSeq++;\n active = null;\n query = \"\";\n input.value = \"\";\n serverResults = [];\n },\n openArticle(id: string) {\n const listed = options.data().articles.find((a) => a.id === id) ?? { id, slug: id, title: \"Article\", summary: \"\", updatedAt: \"\", bodyOmitted: true };\n openArticle(listed);\n },\n focusSearch: () => input.focus?.({ preventScroll: true }),\n setQuery(q: string) {\n input.value = q;\n onInput();\n },\n destroy() {\n if (debounce) clearTimeout(debounce);\n input.removeEventListener(\"input\", onInput);\n root.remove();\n },\n };\n}\n","import { FILE_LINK_CLASS, PDF_BLOCK_CLASS, PDF_PAGES_CLASS } from \"@guidelytech/shared/runtime\";\nimport { prefersReducedMotion } from \"./host\";\n\n/**\n * Turns the PDFs in a sanitized article body (`div.gd-pdf`: the PDF link plus its pages as images)\n * into inline viewers: pages swipe sideways with a page counter and previous/next buttons, and the\n * header or a tap on a page opens a full-screen reader inside the widget, so visitors read the\n * document without downloading it. The original PDF stays one tap away in the reader. Without this\n * (or without script) the CSS alone still shows a scrollable strip of pages.\n */\nexport function enhancePdfViewers(root: Element, doc: Document = root.ownerDocument): void {\n for (const block of Array.from(root.querySelectorAll(`div.${PDF_BLOCK_CLASS}`))) {\n const link = block.querySelector<HTMLAnchorElement>(`a.${FILE_LINK_CLASS}`);\n const strip = block.querySelector<HTMLElement>(`.${PDF_PAGES_CLASS}`);\n if (!link || !strip || block.hasAttribute(\"data-g-ready\")) continue;\n // The sanitizer strips unsafe sources; those images aren't pages.\n for (const img of Array.from(strip.querySelectorAll(\"img:not([src])\"))) img.remove();\n const pages = Array.from(strip.querySelectorAll(\"img\"));\n if (!pages.length) {\n strip.remove();\n continue;\n }\n block.setAttribute(\"data-g-ready\", \"\");\n const name = (link.textContent || \"\").trim() || \"PDF\";\n block.setAttribute(\"role\", \"group\");\n block.setAttribute(\"aria-label\", `${name}, ${pages.length} ${pages.length === 1 ? \"page\" : \"pages\"}`);\n link.setAttribute(\"aria-label\", `Read ${name} full screen`);\n link.addEventListener(\"click\", (e) => {\n e.preventDefault();\n openReader(doc, block, link, pages, 0);\n });\n\n const viewport = doc.createElement(\"div\");\n viewport.className = \"g-pdf-viewport\";\n strip.replaceWith(viewport);\n viewport.appendChild(strip);\n strip.tabIndex = 0;\n strip.setAttribute(\"aria-label\", `${name} pages`);\n\n const counter = doc.createElement(\"span\");\n counter.className = \"g-pdf-count\";\n counter.setAttribute(\"aria-live\", \"polite\");\n const prev = navButton(doc, \"prev\", \"Previous page\", \"‹\");\n const next = navButton(doc, \"next\", \"Next page\", \"›\");\n viewport.append(prev, next, counter);\n\n // Distance between page starts: one page width plus the gap.\n const stride = () => Math.max(1, pages.length > 1 ? pages[1]!.offsetLeft - pages[0]!.offsetLeft : strip.clientWidth);\n const current = () => Math.round(strip.scrollLeft / stride());\n const go = (i: number) => strip.scrollTo({ left: Math.max(0, Math.min(pages.length - 1, i)) * stride(), behavior: prefersReducedMotion() ? \"auto\" : \"smooth\" });\n const update = () => {\n const i = Math.min(pages.length - 1, current());\n counter.textContent = `${i + 1} / ${pages.length}`;\n prev.disabled = i === 0;\n next.disabled = i >= pages.length - 1;\n };\n prev.addEventListener(\"click\", () => go(current() - 1));\n next.addEventListener(\"click\", () => go(current() + 1));\n strip.addEventListener(\"scroll\", update, { passive: true });\n strip.addEventListener(\"keydown\", (e) => {\n if (e.key === \"ArrowRight\" || e.key === \"ArrowLeft\") {\n e.preventDefault();\n go(current() + (e.key === \"ArrowRight\" ? 1 : -1));\n } else if (e.key === \"Enter\") openReader(doc, block, link, pages, current());\n });\n pages.forEach((img, i) => img.addEventListener(\"click\", () => openReader(doc, block, link, pages, i)));\n if (pages.length === 1) viewport.classList.add(\"g-pdf-single\");\n update();\n }\n}\n\nfunction navButton(doc: Document, cls: string, label: string, text: string) {\n const b = doc.createElement(\"button\");\n b.type = \"button\";\n b.className = `g-pdf-nav g-pdf-${cls}`;\n b.setAttribute(\"aria-label\", label);\n b.textContent = text;\n return b;\n}\n\n/** Full-screen reader: every page stacked vertically, the original PDF linked, Escape to close. */\nfunction openReader(doc: Document, block: Element, link: HTMLAnchorElement, pages: HTMLImageElement[], start: number) {\n const host = (block.closest(\".g-scope\") as HTMLElement | null) ?? doc.body;\n // Inside the shadow root, `document.activeElement` is only the host.\n const returnFocus = (block.getRootNode() as Document | ShadowRoot).activeElement as HTMLElement | null;\n const name = (link.textContent || \"\").trim() || \"PDF\";\n\n const reader = doc.createElement(\"div\");\n reader.className = \"g-pdf-reader\";\n reader.setAttribute(\"role\", \"dialog\");\n reader.setAttribute(\"aria-modal\", \"true\");\n reader.setAttribute(\"aria-label\", name);\n const bar = doc.createElement(\"div\");\n bar.className = \"g-pdf-bar\";\n const title = doc.createElement(\"span\");\n title.className = \"g-pdf-title\";\n title.textContent = name;\n const original = doc.createElement(\"a\");\n original.className = \"g-btn g-btn-secondary\";\n original.href = link.href;\n original.target = \"_blank\";\n original.rel = \"noopener noreferrer\";\n original.textContent = \"Open PDF ↗\";\n const close = doc.createElement(\"button\");\n close.type = \"button\";\n close.className = \"g-close g-pdf-close\";\n close.setAttribute(\"aria-label\", \"Close\");\n close.textContent = \"×\";\n bar.append(title, original, close);\n\n const scroller = doc.createElement(\"div\");\n scroller.className = \"g-pdf-scroll\";\n scroller.tabIndex = 0;\n for (const page of pages) {\n const img = doc.createElement(\"img\");\n img.src = page.src;\n img.alt = page.alt;\n img.decoding = \"async\";\n // Sizes up front so every page has its height before loading, and opening at page N lands on it.\n for (const dim of [\"width\", \"height\"]) if (page.hasAttribute(dim)) img.setAttribute(dim, page.getAttribute(dim)!);\n scroller.appendChild(img);\n }\n reader.append(bar, scroller);\n\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n e.stopPropagation();\n done();\n } else if (e.key === \"Tab\") {\n // Keep focus inside the reader.\n const items: HTMLElement[] = [original, close, scroller];\n const at = items.indexOf((reader.getRootNode() as Document | ShadowRoot).activeElement as HTMLElement);\n e.preventDefault();\n items[(at + (e.shiftKey ? items.length - 1 : 1)) % items.length]!.focus();\n }\n };\n const done = () => {\n reader.remove();\n returnFocus?.focus?.({ preventScroll: true });\n };\n close.addEventListener(\"click\", done);\n reader.addEventListener(\"keydown\", onKey);\n host.appendChild(reader);\n close.focus();\n const target = scroller.children[start] as HTMLImageElement | undefined;\n if (target && start > 0) {\n const land = () => (scroller.scrollTop = target.offsetTop - 12);\n requestAnimationFrame(land);\n // Pages without stored sizes only get their height once the pages above have loaded.\n if (!target.hasAttribute(\"height\")) for (const img of Array.from(scroller.children).slice(0, start)) img.addEventListener(\"load\", land, { once: true });\n }\n}\n","import type { Appearance, ProjectTheme } from \"@guidelytech/shared\";\nimport { STYLES } from \"./styles\";\n\nexport const HOST_ID = \"guidely-root\";\n\nexport interface HostHandle {\n host: HTMLElement;\n shadow: ShadowRoot;\n /** Polite live region for screen-reader announcements. */\n live: HTMLElement;\n announce(text: string): void;\n destroy(): void;\n}\n\nlet current: HostHandle | null = null;\n\n/** Default project theme used when the config has not loaded yet. */\nexport const DEFAULT_THEME: ProjectTheme = {\n primaryColor: \"#4f46e5\",\n backgroundColor: \"#ffffff\",\n textColor: \"#111827\",\n borderRadius: 12,\n fontFamily: \"Inter, system-ui, -apple-system, sans-serif\",\n};\n\n/** Returns (creating when needed) the single Shadow-DOM host appended to `document.body`. */\nexport function ensureHost(doc: Document = document): HostHandle {\n if (current && current.host.isConnected && current.host.ownerDocument === doc) return current;\n let host = doc.getElementById(HOST_ID) as HTMLElement | null;\n if (!host) {\n host = doc.createElement(\"div\");\n host.id = HOST_ID;\n host.setAttribute(\"data-guidely\", \"\");\n (doc.body || doc.documentElement).appendChild(host);\n }\n const shadow = host.shadowRoot ?? host.attachShadow({ mode: \"open\" });\n if (!shadow.querySelector(\"style[data-g-base]\")) {\n const style = doc.createElement(\"style\");\n style.setAttribute(\"data-g-base\", \"\");\n style.textContent = STYLES;\n shadow.appendChild(style);\n }\n let live = shadow.querySelector<HTMLElement>(\".g-live\");\n if (!live) {\n live = doc.createElement(\"div\");\n live.className = \"g-live\";\n live.setAttribute(\"aria-live\", \"polite\");\n live.setAttribute(\"aria-atomic\", \"true\");\n shadow.appendChild(live);\n }\n const liveEl = live;\n current = {\n host,\n shadow,\n live: liveEl,\n announce(text: string) {\n liveEl.textContent = \"\";\n setTimeout(() => {\n liveEl.textContent = text;\n }, 30);\n },\n destroy() {\n host?.remove();\n if (current?.host === host) current = null;\n },\n };\n return current;\n}\n\n/** Removes the host from the document (all overlays with it). */\nexport function destroyHost(): void {\n current?.destroy();\n const stray = typeof document !== \"undefined\" ? document.getElementById(HOST_ID) : null;\n stray?.remove();\n current = null;\n}\n\nexport type ResolvedThemeMode = \"light\" | \"dark\";\n\nfunction prefersDark(): boolean {\n try {\n return typeof window !== \"undefined\" && typeof window.matchMedia === \"function\" && window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n } catch {\n return false;\n }\n}\n\nexport function prefersReducedMotion(): boolean {\n try {\n return typeof window !== \"undefined\" && typeof window.matchMedia === \"function\" && window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n } catch {\n return false;\n }\n}\n\nexport interface ThemeVars {\n primary: string;\n bg: string;\n text: string;\n radius: number;\n font: string;\n z: number;\n overlay: number;\n mode: ResolvedThemeMode;\n animation: Appearance[\"animation\"];\n}\n\n/** Merges project theme + guide appearance into CSS custom property values. */\nexport function resolveTheme(theme: Partial<ProjectTheme> | null | undefined, appearance?: Partial<Appearance> | null): ThemeVars {\n const t = { ...DEFAULT_THEME, ...(theme || {}) };\n const a = appearance || {};\n const requested = a.theme ?? \"auto\";\n const mode: ResolvedThemeMode = requested === \"auto\" ? (prefersDark() ? \"dark\" : \"light\") : requested;\n const dark = mode === \"dark\";\n return {\n primary: a.primaryColor || t.primaryColor,\n bg: a.backgroundColor || (dark ? \"#1f2937\" : t.backgroundColor),\n text: a.textColor || (dark ? \"#f9fafb\" : t.textColor),\n radius: a.borderRadius ?? t.borderRadius,\n font: a.fontFamily || t.fontFamily,\n z: a.zIndex ?? 2147483000,\n overlay: a.overlayOpacity ?? 0.5,\n mode,\n animation: prefersReducedMotion() ? \"none\" : (a.animation ?? \"fade\"),\n };\n}\n\n/** Applies theme variables to a scope element. */\nexport function applyTheme(el: HTMLElement, vars: ThemeVars): void {\n el.style.setProperty(\"--g-primary\", vars.primary);\n el.style.setProperty(\"--g-bg\", vars.bg);\n el.style.setProperty(\"--g-text\", vars.text);\n el.style.setProperty(\"--g-radius\", `${vars.radius}px`);\n el.style.setProperty(\"--g-font\", vars.font);\n el.style.setProperty(\"--g-z\", String(vars.z));\n el.style.setProperty(\"--g-overlay\", String(vars.overlay));\n el.setAttribute(\"data-theme\", vars.mode);\n el.setAttribute(\"data-anim\", vars.animation);\n}\n\n/**\n * Creates a themed scope container inside the shadow root. Each guide/widget renders inside its\n * own scope so appearance settings never leak between guides.\n */\nexport function createScope(theme?: Partial<ProjectTheme> | null, appearance?: Partial<Appearance> | null, doc: Document = document): { el: HTMLElement; vars: ThemeVars; destroy(): void } {\n const handle = ensureHost(doc);\n const el = doc.createElement(\"div\");\n el.className = \"g-scope\";\n const vars = resolveTheme(theme, appearance);\n applyTheme(el, vars);\n handle.shadow.appendChild(el);\n let mq: MediaQueryList | null = null;\n const onChange = () => applyTheme(el, resolveTheme(theme, appearance));\n if ((appearance?.theme ?? \"auto\") === \"auto\" && typeof window !== \"undefined\" && typeof window.matchMedia === \"function\") {\n try {\n mq = window.matchMedia(\"(prefers-color-scheme: dark)\");\n mq.addEventListener?.(\"change\", onChange);\n } catch {\n mq = null;\n }\n }\n return {\n el,\n vars,\n destroy() {\n mq?.removeEventListener?.(\"change\", onChange);\n el.remove();\n },\n };\n}\n","import { EMBED_IFRAME_ATTRS, VIDEO_ATTRS, isAllowedEmbedSrc, isSafeMediaUrl } from \"@guidelytech/shared/runtime\";\n\nconst ALLOWED_TAGS = new Set([\"p\", \"br\", \"strong\", \"b\", \"em\", \"i\", \"u\", \"a\", \"ul\", \"ol\", \"li\", \"img\", \"h1\", \"h2\", \"h3\", \"h4\", \"code\", \"pre\", \"blockquote\", \"span\", \"div\", \"hr\", \"button\"]);\nconst DROP_TAGS = new Set([\"script\", \"style\", \"object\", \"embed\", \"form\", \"input\", \"textarea\", \"select\", \"link\", \"meta\", \"base\", \"template\", \"svg\", \"math\", \"frame\", \"frameset\", \"noscript\"]);\nconst ALLOWED_ATTRS = new Set([\"href\", \"src\", \"alt\", \"title\", \"target\", \"rel\", \"class\", \"width\", \"height\", \"data-g-action\", \"data-g-value\"]);\nfunction isSafeUrl(value: string, attr: string, tag: string): boolean {\n // eslint-disable-next-line no-control-regex\n const v = value.trim().replace(/[\\u0000-\\u001f\\s]/g, \"\").toLowerCase();\n if (!v) return false;\n const m = /^([a-z][a-z0-9+.-]*):/.exec(v);\n if (!m) return true; // relative URL\n const scheme = m[1];\n if (scheme === \"data\") return tag === \"img\" && attr === \"src\" && v.startsWith(\"data:image/\");\n return scheme === \"http\" || scheme === \"https\" || scheme === \"mailto\" || scheme === \"tel\";\n}\n\nfunction sanitizeElement(el: Element): void {\n const tag = el.tagName.toLowerCase();\n for (const attr of Array.from(el.attributes)) {\n const name = attr.name.toLowerCase();\n if (name.startsWith(\"on\") || !ALLOWED_ATTRS.has(name)) {\n el.removeAttribute(attr.name);\n continue;\n }\n if ((name === \"href\" || name === \"src\") && !isSafeUrl(attr.value, name, tag)) el.removeAttribute(attr.name);\n }\n if (tag === \"a\") {\n const target = el.getAttribute(\"target\");\n if (target && target !== \"_blank\" && target !== \"_self\") el.removeAttribute(\"target\");\n if (el.getAttribute(\"target\") === \"_blank\") el.setAttribute(\"rel\", \"noopener noreferrer\");\n }\n if (tag === \"button\") el.setAttribute(\"type\", \"button\");\n if (tag === \"img\") {\n for (const dim of [\"width\", \"height\"]) if (el.hasAttribute(dim) && !/^\\d{1,5}$/.test(el.getAttribute(dim)!)) el.removeAttribute(dim);\n el.setAttribute(\"loading\", \"lazy\");\n if (!el.getAttribute(\"alt\")) el.setAttribute(\"alt\", \"\");\n }\n}\n\n/**\n * Media elements are rebuilt from scratch rather than filtered: an `<iframe>` only for a canonical\n * YouTube/Vimeo/Loom/Wistia embed, a `<video>` only for an absolute http(s) file, each with fixed\n * attributes. Returns null when the element must go.\n */\nfunction rebuildMedia(el: Element): Element | null {\n const doc = el.ownerDocument;\n const tag = el.tagName.toLowerCase();\n const src = el.getAttribute(\"src\");\n let out: Element;\n if (tag === \"iframe\") {\n if (!isAllowedEmbedSrc(src)) return null;\n out = doc.createElement(\"iframe\");\n out.setAttribute(\"src\", src!);\n out.setAttribute(\"title\", el.getAttribute(\"title\") || \"Embedded video\");\n for (const [k, v] of Object.entries(EMBED_IFRAME_ATTRS)) out.setAttribute(k, v);\n } else {\n if (!isSafeMediaUrl(src)) return null;\n out = doc.createElement(\"video\");\n out.setAttribute(\"src\", src!);\n const poster = el.getAttribute(\"poster\");\n if (isSafeMediaUrl(poster)) out.setAttribute(\"poster\", poster!);\n for (const [k, v] of Object.entries(VIDEO_ATTRS)) out.setAttribute(k, v);\n }\n return out;\n}\n\nfunction walk(node: Node): void {\n const children = Array.from(node.childNodes);\n for (const child of children) {\n if (child.nodeType === 8 /* comment */) {\n node.removeChild(child);\n continue;\n }\n if (child.nodeType !== 1) continue;\n const el = child as Element;\n const tag = el.tagName.toLowerCase();\n if (DROP_TAGS.has(tag)) {\n node.removeChild(el);\n continue;\n }\n if (tag === \"iframe\" || tag === \"video\") {\n const media = rebuildMedia(el);\n if (media) node.replaceChild(media, el);\n else node.removeChild(el);\n continue;\n }\n if (!ALLOWED_TAGS.has(tag)) {\n // Unwrap: keep text/children, drop the element itself.\n while (el.firstChild) node.insertBefore(el.firstChild, el);\n node.removeChild(el);\n // Re-walk the parent since children moved up.\n walk(node);\n return;\n }\n sanitizeElement(el);\n walk(el);\n }\n}\n\n/**\n * Parses HTML into a sanitized DocumentFragment using a strict allowlist. No external\n * dependency: a `<template>` element parses inertly and the tree is walked element by element.\n */\nexport function sanitizeToFragment(html: string, doc: Document = document): DocumentFragment {\n const tpl = doc.createElement(\"template\");\n tpl.innerHTML = html || \"\";\n walk(tpl.content);\n return tpl.content;\n}\n\n/** Returns sanitized HTML as a string. */\nexport function sanitizeHtml(html: string, doc: Document = document): string {\n const frag = sanitizeToFragment(html, doc);\n const div = doc.createElement(\"div\");\n div.appendChild(frag);\n return div.innerHTML;\n}\n\n/** Replaces the content of `el` with the sanitized HTML. */\nexport function setSanitizedHtml(el: Element, html: string): void {\n el.textContent = \"\";\n el.appendChild(sanitizeToFragment(html, el.ownerDocument));\n}\n","import type { NormalizedRect, SdkHowTo, SdkHowToStep } from \"@guidelytech/shared\";\nimport { el } from \"./help-view\";\n\n// A how-to inside the messenger: numbered steps with their screenshots and the element highlighted.\n// Built from DOM nodes and textContent only (step text is plain text), so nothing in it is parsed as HTML.\n\nconst pct = (v: number) => `${(v * 100).toFixed(3)}%`;\nconst place = (node: HTMLElement, r: NormalizedRect) =>\n Object.assign(node.style, {\n left: pct(r.x),\n top: pct(r.y),\n width: pct(r.width),\n height: pct(r.height),\n });\n\n/** Plain text as paragraphs (blank lines) with line breaks kept by CSS. */\nfunction paragraphs(doc: Document, text: string, cls: string): HTMLElement | null {\n const parts = text\n .split(/\\n{2,}/)\n .map((p) => p.trim())\n .filter(Boolean);\n if (!parts.length) return null;\n const wrap = el(doc, \"div\", cls);\n for (const p of parts) wrap.appendChild(el(doc, \"p\", \"\", p));\n return wrap;\n}\n\n/** The screenshot, cropped to `crop` when zoomed, with the highlight drawn over it. Only http(s) images load. */\nfunction screenshot(\n doc: Document,\n image: NonNullable<SdkHowToStep[\"image\"]>,\n alt: string,\n): HTMLElement | null {\n if (!/^https?:\\/\\//i.test(image.url)) return null;\n const frame = el(doc, \"div\", \"g-howto-shot\");\n const img = (cls: string) => {\n const i = el(doc, \"img\", cls);\n i.src = image.url;\n i.alt = alt;\n i.loading = \"lazy\";\n i.decoding = \"async\";\n return i;\n };\n const crop = image.crop;\n if (crop && crop.width > 0 && crop.height > 0) {\n // An invisible full-width copy gives the frame the screenshot's aspect ratio (the crop has the same one).\n const ghost = img(\"g-howto-ghost\");\n ghost.alt = \"\";\n ghost.setAttribute(\"aria-hidden\", \"true\");\n const zoomed = img(\"g-howto-zoomed\");\n Object.assign(zoomed.style, {\n width: pct(1 / crop.width),\n left: pct(-crop.x / crop.width),\n top: pct(-crop.y / crop.height),\n });\n frame.append(ghost, zoomed);\n } else frame.appendChild(img(\"\"));\n if (image.highlight) {\n const mark = el(doc, \"div\", \"g-howto-mark\");\n mark.setAttribute(\"aria-hidden\", \"true\");\n place(mark, image.highlight);\n frame.appendChild(mark);\n }\n return frame;\n}\n\n/** Renders a how-to; `onShowMe` starts its tour when it has one live in this environment. */\nexport function renderHowTo(\n doc: Document,\n howTo: SdkHowTo,\n onShowMe?: (guideKey: string) => void,\n): HTMLElement {\n const wrap = el(doc, \"div\", \"g-howto\");\n wrap.appendChild(el(doc, \"h3\", \"g-title\", howTo.title));\n const description = paragraphs(doc, howTo.description, \"g-howto-desc\");\n if (description) wrap.appendChild(description);\n const guideKey = howTo.guideKey;\n if (guideKey && onShowMe) {\n const show = el(doc, \"button\", \"g-btn g-btn-primary g-howto-show\", \"▶ Show me in the app\");\n show.type = \"button\";\n show.addEventListener(\"click\", () => onShowMe(guideKey));\n wrap.appendChild(show);\n }\n const list = el(doc, \"ol\", \"g-howto-steps\");\n let n = 0;\n for (const s of howTo.steps) {\n const li = el(doc, \"li\", `g-howto-step g-howto-${s.kind}`);\n if (s.kind === \"heading\") li.appendChild(el(doc, \"h4\", \"\", s.title));\n else if (s.kind === \"tip\" || s.kind === \"alert\") {\n li.appendChild(el(doc, \"strong\", \"\", s.title || (s.kind === \"tip\" ? \"Tip\" : \"Important\")));\n const body = paragraphs(doc, s.body, \"\");\n if (body) li.appendChild(body);\n } else if (s.kind === \"text\") {\n if (s.title) li.appendChild(el(doc, \"strong\", \"\", s.title));\n const body = paragraphs(doc, s.body, \"g-howto-note\");\n if (body) li.appendChild(body);\n } else {\n const row = el(doc, \"div\", \"g-howto-row\");\n const num = el(doc, \"span\", \"g-howto-num\", String(++n));\n const text = el(doc, \"div\", \"g-howto-text\");\n text.appendChild(el(doc, \"p\", \"g-howto-title\", s.title));\n const body = paragraphs(doc, s.body, \"g-howto-note\");\n if (body) text.appendChild(body);\n row.append(num, text);\n li.appendChild(row);\n const shot = s.image ? screenshot(doc, s.image, s.title) : null;\n if (shot) li.appendChild(shot);\n }\n list.appendChild(li);\n }\n if (!list.childNodes.length)\n wrap.appendChild(el(doc, \"div\", \"g-rc-empty\", \"This how-to has no steps yet.\"));\n else wrap.appendChild(list);\n return wrap;\n}\n","/** Messenger styles, injected into the Guidely shadow root the first time the messenger renders. */\nexport const MESSENGER_STYLES = `\n:host([data-g-messenger=\"bottom-right\"]) .g-launcher.g-pos-bottom-right{right:72px}\n:host([data-g-messenger=\"bottom-left\"]) .g-launcher.g-pos-bottom-left{left:72px}\n.g-m-launcher{position:fixed;z-index:calc(var(--g-z) + 1);pointer-events:auto;width:56px;height:56px;margin:16px;border-radius:999px;border:0;background:var(--g-primary);color:var(--g-primary-text);cursor:pointer;box-shadow:var(--g-shadow);display:inline-flex;align-items:center;justify-content:center;padding:0;transition:transform .15s}\n.g-m-launcher:hover{transform:scale(1.05)}\n.g-m-launcher:focus-visible{outline:2px solid var(--g-primary);outline-offset:3px}\n.g-m-launcher svg{width:26px;height:26px;fill:currentColor}\n.g-m-badge{position:absolute;top:-2px;right:-2px;min-width:20px;height:20px;padding:0 5px;border-radius:999px;background:#e11d48;color:#fff;font-size:11px;font-weight:700;display:inline-flex;align-items:center;justify-content:center;border:2px solid var(--g-bg)}\n.g-messenger{bottom:76px;height:min(640px,calc(100vh - 110px))}\n.g-m-head{padding:16px 48px 14px 20px;background:var(--g-primary);color:var(--g-primary-text);position:relative;display:flex;align-items:center;gap:8px;min-height:56px}\n.g-m-head .g-close{color:inherit;top:50%;transform:translateY(-50%)}\n.g-m-head .g-close:hover,.g-m-head .g-close:focus-visible{background:rgba(255,255,255,.18);color:inherit}\n.g-m-head h2{margin:0;font-size:16px;font-weight:600;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.g-m-back{border:0;background:transparent;color:inherit;font:inherit;cursor:pointer;width:32px;height:32px;border-radius:999px;margin-left:-8px;display:inline-flex;align-items:center;justify-content:center;padding:0}\n.g-m-back:hover,.g-m-back:focus-visible{background:rgba(255,255,255,.18);outline:none}\n.g-m-main{flex:1;min-height:0;display:flex;flex-direction:column;overflow:hidden}\n.g-m-scroll{flex:1;overflow:auto;padding:16px}\n.g-m-card{display:block;width:100%;text-align:left;border:1px solid var(--g-border);background:var(--g-bg);color:var(--g-text);border-radius:calc(var(--g-radius) * .8);padding:14px 16px;margin:0 0 12px;font:inherit;cursor:pointer;box-shadow:0 1px 2px rgba(0,0,0,.04)}\n.g-m-card:hover{background:var(--g-subtle)}\n.g-m-card:focus-visible{outline:2px solid var(--g-primary);outline-offset:2px}\n.g-m-card-title{display:block;font-weight:600}\n.g-m-card-sub{display:block;color:var(--g-muted);font-size:13px;margin-top:2px}\n.g-m-card-label{display:block;font-size:12px;color:var(--g-muted);font-weight:500}\n.g-m-row{display:flex;align-items:flex-start;gap:10px}\n.g-m-row .g-m-grow{flex:1;min-width:0}\n.g-m-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.g-m-time{color:var(--g-muted);font-size:12px;flex:none}\n.g-m-dot{width:8px;height:8px;border-radius:999px;background:var(--g-primary);flex:none;margin-top:6px}\n.g-m-tabs{display:flex;border-top:1px solid var(--g-border);background:var(--g-bg)}\n.g-m-tab{flex:1;border:0;background:transparent;color:var(--g-muted);font:inherit;font-size:12px;font-weight:600;padding:10px 4px 12px;cursor:pointer;display:flex;flex-direction:column;align-items:center;gap:2px}\n.g-m-tab[aria-selected=\"true\"]{color:var(--g-primary)}\n.g-m-tab:focus-visible{outline:2px solid var(--g-primary);outline-offset:-2px}\n.g-m-tab-icon{position:relative;display:inline-flex;line-height:1}\n.g-m-tab-icon .g-m-ico{width:22px;height:22px}\n.g-m-tab-dot{position:absolute;top:-2px;right:-4px;width:8px;height:8px;border-radius:999px;background:#e11d48;border:2px solid var(--g-bg);box-sizing:content-box}\n.g-m-log{flex:1;overflow:auto;padding:16px;display:flex;flex-direction:column;gap:10px}\n.g-m-msg{max-width:85%;display:flex;flex-direction:column;gap:4px}\n.g-m-msg.g-from-user{align-self:flex-end;align-items:flex-end}\n.g-m-msg.g-from-system{align-self:center;max-width:95%;text-align:center;color:var(--g-muted);font-size:12px}\n.g-m-author{font-size:12px;color:var(--g-muted);display:flex;align-items:center;gap:6px}\n.g-m-ai{font-size:10px;font-weight:700;letter-spacing:.04em;padding:1px 5px;border-radius:4px;background:var(--g-subtle);color:var(--g-muted)}\n.g-m-bubble{padding:10px 12px;border-radius:14px;background:var(--g-subtle);color:var(--g-text);overflow-wrap:anywhere}\n.g-from-user .g-m-bubble{background:var(--g-primary);color:var(--g-primary-text)}\n.g-from-user .g-m-bubble a{color:inherit}\n.g-m-bubble p{margin:0 0 8px}.g-m-bubble p:last-child{margin:0}\n.g-m-bubble ul,.g-m-bubble ol{margin:4px 0 8px;padding-left:20px}\n.g-m-bubble code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;background:color-mix(in srgb,var(--g-text) 8%,transparent);padding:1px 4px;border-radius:4px}\n.g-m-bubble a{color:var(--g-primary)}\n.g-m-failed .g-m-bubble{opacity:.7;font-style:italic}\n.g-m-typing{display:inline-flex;gap:4px;padding:4px 0}\n.g-m-typing span{width:6px;height:6px;border-radius:999px;background:var(--g-muted);animation:g-m-bounce 1s infinite}\n.g-m-typing span:nth-child(2){animation-delay:.15s}.g-m-typing span:nth-child(3){animation-delay:.3s}\n@keyframes g-m-bounce{0%,60%,100%{opacity:.3;transform:translateY(0)}30%{opacity:1;transform:translateY(-3px)}}\n@media (prefers-reduced-motion: reduce){.g-m-typing span{animation:none}.g-m-launcher{transition:none}}\n.g-m-chips{display:flex;flex-direction:column;gap:6px;margin-top:2px}\n.g-m-chip{display:flex;align-items:center;gap:8px;text-align:left;border:1px solid var(--g-border);background:var(--g-bg);color:var(--g-text);border-radius:10px;padding:8px 10px;font:inherit;font-size:13px;cursor:pointer}\n.g-m-chip:hover{background:var(--g-subtle)}\n.g-m-chip:focus-visible{outline:2px solid var(--g-primary);outline-offset:2px}\n.g-m-chip.g-m-guide{border-color:var(--g-primary);color:var(--g-primary);font-weight:600}\n.g-m-foot{border-top:1px solid var(--g-border);padding:10px 12px 12px;background:var(--g-bg)}\n.g-m-compose{display:flex;align-items:flex-end;gap:8px}\n.g-m-compose textarea{flex:1;resize:none;min-height:40px;max-height:120px;border:1px solid var(--g-border);border-radius:10px;padding:9px 10px;font:inherit;font-size:14px;color:var(--g-text);background:var(--g-bg)}\n.g-m-compose textarea:focus-visible{outline:2px solid var(--g-primary);outline-offset:1px}\n.g-m-send{width:40px;height:40px;border-radius:999px;border:0;background:var(--g-primary);color:var(--g-primary-text);cursor:pointer;flex:none;display:inline-flex;align-items:center;justify-content:center;padding:0}\n.g-m-send .g-m-ico{width:18px;height:18px}\n.g-m-send:disabled{opacity:.45;cursor:not-allowed}\n.g-m-send:focus-visible{outline:2px solid var(--g-primary);outline-offset:2px}\n.g-m-human{border:0;background:transparent;color:var(--g-muted);font:inherit;font-size:12px;cursor:pointer;padding:6px 2px 0;text-decoration:underline}\n.g-m-human:hover{color:var(--g-text)}\n.g-m-rate{text-align:center;padding:4px 0 2px;font-size:13px;color:var(--g-muted)}\n.g-m-rate button{border:0;background:transparent;font-size:22px;cursor:pointer;padding:4px 8px;border-radius:8px}\n.g-m-rate button:hover,.g-m-rate button:focus-visible{background:var(--g-subtle);outline:none}\n.g-m-note{color:var(--g-muted);font-size:12px;margin-top:6px}\n.g-m-empty{color:var(--g-muted);text-align:center;padding:24px 8px}\n.g-howto .g-title{margin:0 0 6px}\n.g-howto-desc,.g-howto-note{color:var(--g-muted);font-size:13px}\n.g-howto p{margin:0 0 6px;white-space:pre-line}\n.g-howto-show{width:100%;margin:6px 0 4px}\n.g-howto-steps{list-style:none;margin:12px 0 0;padding:0;display:flex;flex-direction:column;gap:16px}\n.g-howto-step h4{margin:4px 0 0;font-size:15px}\n.g-howto-tip,.g-howto-alert{border-left:3px solid var(--g-primary);background:var(--g-subtle);border-radius:6px;padding:8px 10px;font-size:13px}\n.g-howto-alert{border-left-color:#d97706}\n.g-howto-row{display:flex;gap:10px;align-items:flex-start}\n.g-howto-num{flex:none;width:24px;height:24px;border-radius:999px;background:var(--g-primary);color:var(--g-primary-text);font-size:12px;font-weight:700;display:inline-flex;align-items:center;justify-content:center}\n.g-howto-text{flex:1;min-width:0;padding-top:2px}\n.g-howto-title{font-weight:600}\n.g-howto-shot{position:relative;overflow:hidden;margin-top:8px;border:1px solid var(--g-border);border-radius:8px;background:var(--g-subtle)}\n.g-howto-shot img{display:block;width:100%;height:auto}\n.g-howto-shot .g-howto-ghost{visibility:hidden}\n.g-howto-shot .g-howto-zoomed{position:absolute;max-width:none}\n.g-howto-mark{position:absolute;pointer-events:none;border:3px solid var(--g-primary);border-radius:6px;box-shadow:0 0 0 3px color-mix(in srgb,var(--g-primary) 25%,transparent)}\n.g-m-ico{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;flex:none}\n.g-close .g-m-ico,.g-m-back .g-m-ico{width:18px;height:18px}\n.g-m-row.g-m-center{align-items:center}\n.g-m-row.g-m-baseline{align-items:baseline}\n.g-m-static{cursor:default}\n.g-m-static:hover{background:var(--g-bg)}\n.g-m-wide{width:100%}\n.g-m-home{position:relative;padding:0}\n.g-m-hero-bg{position:absolute;top:0;left:0;right:0;height:300px;pointer-events:none;background:linear-gradient(180deg,var(--g-primary) 0%,var(--g-primary) 52%,color-mix(in srgb,var(--g-primary) 30%,var(--g-bg)) 84%,var(--g-bg) 100%)}\n.g-m-home-inner{position:relative;padding:16px;display:flex;flex-direction:column;gap:12px}\n.g-m-home .g-m-card{margin:0;box-shadow:0 1px 2px rgba(0,0,0,.04),0 4px 14px rgba(17,24,39,.06)}\n.g-m-hero-top{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:40px;padding:2px 4px 0}\n.g-m-logo{width:36px;height:36px;border-radius:9px;background:var(--g-bg);color:var(--g-primary);display:inline-flex;align-items:center;justify-content:center;font-weight:700;font-size:17px;overflow:hidden;flex:none}\n.g-m-logo img{width:100%;height:100%;object-fit:contain}\n.g-m-team{display:flex}\n.g-m-avatar{width:32px;height:32px;border-radius:999px;border:2px solid var(--g-primary);display:inline-flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;overflow:hidden;margin-left:-8px;background:#fde7c7;color:#7a4a0a}\n.g-m-avatar:first-child{margin-left:0}\n.g-m-avatar-1{background:#d9f0e3;color:#1f5e3b}\n.g-m-avatar-2{background:#e3e1fa;color:#3b3486}\n.g-m-avatar img{width:100%;height:100%;object-fit:cover}\n.g-m-hero-close{width:36px;height:36px;border:0;border-radius:999px;background:rgba(255,255,255,.16);color:var(--g-primary-text);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;padding:0;margin-left:10px}\n.g-m-hero-close .g-m-ico{width:18px;height:18px}\n.g-m-hero-close:hover{background:rgba(255,255,255,.28)}\n.g-m-hero-close:focus-visible{outline:2px solid var(--g-primary-text);outline-offset:2px}\n.g-m-hello{margin:36px 4px 6px;color:var(--g-primary-text);font-size:26px;font-weight:700;line-height:1.2;letter-spacing:-.01em;display:flex;flex-direction:column}\n.g-m-hello-1{opacity:.8}\n.g-m-trail{color:var(--g-primary)}\n.g-m-lead{color:var(--g-muted)}\n.g-m-status-ico{width:26px;height:26px}\n.g-m-status-operational .g-m-status-ico{color:#15803d}\n.g-m-status-degraded .g-m-status-ico{color:#b45309}\n.g-m-status-outage .g-m-status-ico{color:#b91c1c}\n.g-m-status-maintenance .g-m-status-ico{color:#1d4ed8}\n.g-m-bar{display:block;height:6px;border-radius:999px;background:var(--g-border);margin-top:10px;overflow:hidden}\n.g-m-bar-fill{display:block;height:100%;background:var(--g-primary);border-radius:999px}\n.g-m-link{color:var(--g-primary);font-weight:600;font-size:13px;flex:none}\n.g-m-badge-ico{width:32px;height:32px;border-radius:8px;background:var(--g-subtle);color:color-mix(in srgb,var(--g-text) 78%,transparent);display:inline-flex;align-items:center;justify-content:center;flex:none}\n.g-m-badge-ico .g-m-ico{width:16px;height:16px}\n.g-m-badge-ico.g-m-accent{background:color-mix(in srgb,var(--g-primary) 12%,var(--g-bg));color:var(--g-primary)}\n.g-m-suggest{padding-bottom:4px}\n.g-m-items{display:flex;flex-direction:column;margin-top:8px}\n.g-m-item{display:flex;align-items:center;gap:12px;width:100%;text-align:left;border:0;border-top:1px solid var(--g-border);background:transparent;color:var(--g-text);padding:10px 0;font:inherit;cursor:pointer;min-height:44px}\n.g-m-item:hover .g-m-item-title{color:var(--g-primary)}\n.g-m-item:focus-visible{outline:2px solid var(--g-primary);outline-offset:2px;border-radius:4px}\n.g-m-item .g-m-grow{flex:1;min-width:0}\n.g-m-item-title{display:block;font-weight:600;overflow-wrap:anywhere}\n.g-m-news{padding:0;overflow:hidden}\n.g-m-news-img{display:block;width:100%;height:150px;object-fit:cover;background:var(--g-subtle)}\n.g-m-news-body{display:block;padding:14px 16px}\n.g-m-news-meta{gap:8px;margin-bottom:4px}\n.g-m-tag{font-size:11px;font-weight:700;color:var(--g-primary-text);background:var(--g-primary);border-radius:4px;padding:1px 6px;text-transform:uppercase;letter-spacing:.03em}\n.g-m-clamp{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}\n.g-m-context{align-self:center;font-size:12px;color:var(--g-muted);background:var(--g-subtle);border-radius:999px;padding:3px 10px}\n.g-m-asks{align-items:flex-start}\n.g-m-chip.g-m-ask{border-color:var(--g-primary);color:var(--g-primary);font-weight:600;border-radius:999px;padding:8px 14px;min-height:36px}\n.g-m-chip.g-m-ask:disabled{opacity:.5;cursor:not-allowed}\n`;\n","/**\n * Renders untrusted chat text (Scout replies, user and teammate messages) with createElement and\n * textContent only. Supports paragraphs, line breaks, `- ` / `1. ` lists, **bold**, `code` and\n * http(s) links. Never creates images, raw HTML or non-http links, so a prompt-injected reply can't\n * load remote resources or run script.\n */\n\nconst CITATION = /\\s*\\[\\[article:[^\\]]*\\]\\]/g;\n// Inline tokens: **bold**, `code`, [label](url), bare https?:// URLs.\nconst INLINE = /\\*\\*([^*\\n]+)\\*\\*|`([^`\\n]+)`|(!?)\\[([^\\]\\n]{1,200})\\]\\((https?:\\/\\/[^\\s)]+)\\)|(https?:\\/\\/[^\\s<>()\"']+[^\\s<>().,;:!?'\"])/g;\n\n/** Removes `[[article:ID]]` markers (citations are rendered from structured data instead). */\nexport function stripCitationMarkers(text: string): string {\n return text.replace(CITATION, \"\");\n}\n\nexport function safeHttpUrl(raw: string): string | null {\n try {\n const u = new URL(raw);\n return u.protocol === \"http:\" || u.protocol === \"https:\" ? u.href : null;\n } catch {\n return null;\n }\n}\n\nfunction link(doc: Document, label: string, href: string): Node {\n const url = safeHttpUrl(href);\n if (!url) return doc.createTextNode(label);\n const a = doc.createElement(\"a\");\n a.href = url;\n a.target = \"_blank\";\n a.rel = \"noopener noreferrer nofollow\";\n a.textContent = label;\n return a;\n}\n\nfunction appendInline(doc: Document, parent: Node, text: string) {\n let last = 0;\n for (const m of text.matchAll(INLINE)) {\n const start = m.index ?? 0;\n if (start > last) parent.appendChild(doc.createTextNode(text.slice(last, start)));\n if (m[1] !== undefined) {\n const b = doc.createElement(\"strong\");\n b.textContent = m[1];\n parent.appendChild(b);\n } else if (m[2] !== undefined) {\n const c = doc.createElement(\"code\");\n c.textContent = m[2];\n parent.appendChild(c);\n } else if (m[4] !== undefined && m[5] !== undefined) {\n // Markdown images (![alt](url)) are never loaded or linked: keep the alt text only.\n parent.appendChild(m[3] ? doc.createTextNode(m[4]) : link(doc, m[4], m[5]));\n } else if (m[6] !== undefined) {\n parent.appendChild(link(doc, m[6], m[6]));\n }\n last = start + m[0].length;\n }\n if (last < text.length) parent.appendChild(doc.createTextNode(text.slice(last)));\n}\n\nconst BULLET = /^\\s*[-*•]\\s+/;\nconst NUMBERED = /^\\s*\\d{1,3}[.)]\\s+/;\n\n/** Builds a fragment for `text`. Safe for any input. */\nexport function renderSafeText(doc: Document, text: string): DocumentFragment {\n const frag = doc.createDocumentFragment();\n const blocks = stripCitationMarkers(text).replace(/\\r\\n?/g, \"\\n\").trim().split(/\\n{2,}/);\n for (const block of blocks) {\n if (!block.trim()) continue;\n const lines = block.split(\"\\n\");\n if (lines.every((l) => BULLET.test(l)) || lines.every((l) => NUMBERED.test(l))) {\n const ordered = NUMBERED.test(lines[0]!);\n const list = doc.createElement(ordered ? \"ol\" : \"ul\");\n for (const line of lines) {\n const li = doc.createElement(\"li\");\n appendInline(doc, li, line.replace(ordered ? NUMBERED : BULLET, \"\"));\n list.appendChild(li);\n }\n frag.appendChild(list);\n continue;\n }\n const p = doc.createElement(\"p\");\n lines.forEach((line, i) => {\n if (i) p.appendChild(doc.createElement(\"br\"));\n appendInline(doc, p, line);\n });\n frag.appendChild(p);\n }\n return frag;\n}\n"],"mappings":"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","names":["import_runtime","import_runtime","link","import_runtime","el","el","icon"]}