@scoperat/tracker 0.1.1 → 0.2.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.
- package/dist/index.d.ts +163 -4
- package/dist/index.js +630 -2
- package/dist/index.js.map +1 -1
- package/dist/widget/index.d.ts +41 -0
- package/dist/widget/index.js +2633 -0
- package/dist/widget/index.js.map +1 -0
- package/dist/widget.global.js +970 -0
- package/dist/widget.global.js.map +1 -0
- package/package.json +15 -3
- package/dist/client.d.ts +0 -30
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js +0 -217
- package/dist/client.js.map +0 -1
- package/dist/context.d.ts +0 -5
- package/dist/context.d.ts.map +0 -1
- package/dist/context.js +0 -24
- package/dist/context.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/types.d.ts +0 -33
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/widget/index.ts","../../src/widget/styles.ts","../../src/widget/Widget.tsx","../../src/widget/ConversationList.tsx","../../src/breadcrumbs.ts","../../src/context.ts","../../src/errors.ts","../../src/flag-client.ts","../../src/client.ts","../../src/widget/api.ts","../../src/widget/state.ts","../../src/widget/ConversationThread.tsx","../../src/widget/Launcher.tsx","../../src/widget/TicketForm.tsx"],"sourcesContent":["/** @jsxImportSource preact */\nimport { h, render } from \"preact\";\n\nimport { getStyles } from \"./styles.js\";\nimport type { WidgetOptions } from \"./types.js\";\nimport { Widget } from \"./Widget.js\";\n\nexport type {\n TicketCategoryValue,\n WidgetOptions,\n WidgetTheme,\n} from \"./types.js\";\n\nlet initialized = false;\nlet hostEl: HTMLElement | null = null;\n\n/**\n * Initialize and render the support widget.\n * Mounts inside a Shadow DOM for style isolation.\n *\n * @example\n * ```ts\n * import scoperat from '@scoperat/tracker';\n * import { initWidget } from '@scoperat/tracker/widget';\n *\n * scoperat.init('tk_live_...', { endpoint: 'https://app.scoperat.ai' });\n * scoperat.identify('user-123', { email: 'user@co.com', name: 'Jane' });\n *\n * initWidget({ position: 'bottom-right' });\n * ```\n */\nexport function initWidget(options: WidgetOptions = {}): void {\n if (initialized) return;\n if (typeof document === \"undefined\") return;\n\n initialized = true;\n\n hostEl = document.createElement(\"div\");\n hostEl.id = \"scoperat-widget\";\n const shadow = hostEl.attachShadow({ mode: \"open\" });\n\n const styleEl = document.createElement(\"style\");\n styleEl.textContent = getStyles(options.theme, options.darkMode);\n shadow.appendChild(styleEl);\n\n const mountPoint = document.createElement(\"div\");\n shadow.appendChild(mountPoint);\n\n document.body.appendChild(hostEl);\n\n render(h(Widget, { options }), mountPoint);\n}\n\n/**\n * Unmount and remove the support widget from the DOM.\n * After calling this, `initWidget` can be called again to re-mount.\n */\nexport function destroyWidget(): void {\n if (!initialized || !hostEl) return;\n render(null, hostEl.shadowRoot!.lastElementChild as Element);\n hostEl.remove();\n hostEl = null;\n initialized = false;\n}\n","import type { WidgetTheme } from \"./types.js\";\n\nexport function getStyles(theme: WidgetTheme = {}, darkMode = false): string {\n const primary = theme.primaryColor ?? \"#6366f1\";\n // Dark palette derived from apps/web/src/styles/index.css .dark vars\n const text = theme.textColor ?? (darkMode ? \"#d4d4d4\" : \"#1f2937\");\n const bg = theme.backgroundColor ?? (darkMode ? \"#121212\" : \"#ffffff\");\n const font =\n theme.fontFamily ??\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif';\n\n const surfaceBg = darkMode ? \"#272727\" : \"#ffffff\"; // --card oklch(0.195)\n const subtleBorder = darkMode ? \"rgba(255,255,255,0.05)\" : \"#f0f0f0\"; // --border oklch(1 0 0 / 5%)\n const border = darkMode ? \"rgba(255,255,255,0.15)\" : \"#d1d5db\"; // --input oklch(1 0 0 / 15%)\n const borderLight = darkMode ? \"rgba(255,255,255,0.05)\" : \"#e5e7eb\"; // --border\n const hoverBg = darkMode ? \"#3a3a3a\" : \"#f9fafb\"; // --secondary oklch(0.269)\n const secondaryBg = darkMode ? \"#3a3a3a\" : \"#f3f4f6\"; // --secondary oklch(0.269)\n const secondaryHoverBg = darkMode ? \"#525252\" : \"#e5e7eb\"; // --accent oklch(0.371)\n const mutedText = darkMode ? \"#a3a3a3\" : \"#6b7280\"; // --muted-foreground oklch(0.708)\n const subtleText = darkMode ? \"#a3a3a3\" : \"#4b5563\"; // --muted-foreground\n const labelText = darkMode ? \"#d4d4d4\" : \"#374151\"; // --foreground\n const inputBg = darkMode ? \"#272727\" : \"white\"; // --card\n const panelShadow = darkMode\n ? \"0 8px 30px rgba(0,0,0,0.5)\"\n : \"0 8px 30px rgba(0,0,0,0.12)\";\n const panelBorder = darkMode\n ? \"1px solid rgba(255,255,255,0.05)\" // --border\n : \"1px solid rgba(0,0,0,0.08)\";\n const inlineCodeBg = darkMode ? \"#3a3a3a\" : \"#f3f4f6\"; // --secondary\n const preCodeBg = darkMode ? \"#1a1a1a\" : \"#1f2937\";\n const preCodeText = darkMode ? \"#d4d4d4\" : \"#e5e7eb\"; // --foreground\n const errorBg = darkMode ? \"#3b1111\" : \"#fef2f2\";\n const errorText = darkMode ? \"#fca5a5\" : \"#dc2626\";\n const successBg = darkMode ? \"#052e16\" : \"#f0fdf4\";\n const successText = darkMode ? \"#4ade80\" : \"#16a34a\";\n const blockquoteColor = darkMode ? \"#a3a3a3\" : \"#6b7280\"; // --muted-foreground\n const tableBg = darkMode ? \"#272727\" : \"#f9fafb\"; // --card\n\n return `\n :host {\n all: initial;\n font-family: ${font};\n color: ${text};\n font-size: 14px;\n line-height: 1.5;\n }\n\n * {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n }\n\n .sr-launcher {\n position: fixed;\n bottom: 20px;\n z-index: 2147483647;\n width: 44px;\n height: 44px;\n border-radius: 50%;\n background: ${primary};\n color: white;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow: 0 8px 30px rgba(0,0,0,0.35), 0 4px 12px rgba(0,0,0,0.25), 0 0 0 1px rgba(0,0,0,0.05);\n transition: transform 0.2s, box-shadow 0.2s;\n }\n .sr-launcher:hover {\n transform: scale(1.05);\n box-shadow: 0 12px 40px rgba(0,0,0,0.45), 0 6px 16px rgba(0,0,0,0.3), 0 0 0 1px rgba(0,0,0,0.05);\n }\n .sr-launcher.right { right: 20px; }\n .sr-launcher.left { left: 20px; }\n\n .sr-launcher svg {\n width: 20px;\n height: 20px;\n fill: currentColor;\n }\n\n .sr-panel {\n position: fixed;\n bottom: 88px;\n z-index: 2147483647;\n width: 380px;\n height: 520px;\n max-height: calc(100vh - 120px);\n background: ${bg};\n border-radius: 16px;\n box-shadow: ${panelShadow};\n border: ${panelBorder};\n display: flex;\n flex-direction: column;\n overflow: hidden;\n animation: sr-slide-up 0.2s ease-out;\n }\n .sr-panel.right { right: 20px; }\n .sr-panel.left { left: 20px; }\n\n @keyframes sr-slide-up {\n from { opacity: 0; transform: translateY(12px); }\n to { opacity: 1; transform: translateY(0); }\n }\n\n .sr-header {\n padding: 16px 20px;\n background: ${primary};\n color: white;\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-shrink: 0;\n border-radius: 16px 16px 0 0;\n margin: -1px -1px 0 -1px;\n }\n .sr-header h3 {\n font-size: 16px;\n font-weight: 600;\n margin: 0;\n flex: 1;\n min-width: 0;\n }\n .sr-header-title-truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .sr-header-actions {\n display: flex;\n gap: 8px;\n align-items: center;\n }\n .sr-header button {\n background: none;\n border: none;\n color: white;\n cursor: pointer;\n padding: 4px;\n border-radius: 4px;\n display: flex;\n align-items: center;\n opacity: 0.8;\n }\n .sr-header button:hover { opacity: 1; }\n .sr-header button svg { width: 18px; height: 18px; fill: currentColor; }\n\n .sr-body {\n flex: 1;\n overflow-y: auto;\n padding: 0;\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n\n .sr-ticket-list {\n list-style: none;\n padding: 0;\n }\n .sr-ticket-item {\n padding: 14px 20px;\n border-bottom: 1px solid ${subtleBorder};\n cursor: pointer;\n transition: background 0.15s;\n }\n .sr-ticket-item:hover { background: ${hoverBg}; }\n .sr-ticket-item h4 {\n font-size: 14px;\n font-weight: 500;\n margin-bottom: 4px;\n color: ${text};\n }\n .sr-ticket-item .sr-meta {\n font-size: 12px;\n color: ${mutedText};\n display: flex;\n gap: 8px;\n align-items: center;\n }\n\n .sr-badge {\n font-size: 11px;\n padding: 2px 8px;\n border-radius: 9999px;\n font-weight: 500;\n }\n .sr-badge-bug { background: ${darkMode ? \"#3b1111\" : \"#fef2f2\"}; color: ${darkMode ? \"#fca5a5\" : \"#dc2626\"}; }\n .sr-badge-feature_request { background: ${darkMode ? \"#052e16\" : \"#f0fdf4\"}; color: ${darkMode ? \"#4ade80\" : \"#16a34a\"}; }\n .sr-badge-question { background: ${darkMode ? \"#1e2a4a\" : \"#eff6ff\"}; color: ${darkMode ? \"#93c5fd\" : \"#2563eb\"}; }\n .sr-badge-access_issue { background: ${darkMode ? \"#3b2506\" : \"#fefce8\"}; color: ${darkMode ? \"#fcd34d\" : \"#ca8a04\"}; }\n .sr-badge-performance { background: ${darkMode ? \"#2e0a4a\" : \"#fdf4ff\"}; color: ${darkMode ? \"#c084fc\" : \"#9333ea\"}; }\n .sr-badge-billing { background: ${darkMode ? \"#042f2e\" : \"#f0fdfa\"}; color: ${darkMode ? \"#5eead4\" : \"#0d9488\"}; }\n .sr-badge-documentation { background: ${secondaryBg}; color: ${mutedText}; }\n .sr-badge-other { background: ${secondaryBg}; color: ${mutedText}; }\n\n .sr-empty {\n padding: 40px 20px;\n text-align: center;\n color: ${mutedText};\n }\n .sr-empty p { margin-bottom: 16px; font-size: 14px; }\n\n .sr-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 8px 16px;\n font-size: 14px;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: background 0.15s;\n }\n .sr-btn-primary {\n background: ${primary};\n color: white;\n }\n .sr-btn-primary:hover { filter: brightness(1.1); }\n .sr-btn-primary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n .sr-btn-secondary {\n background: ${secondaryBg};\n color: ${text};\n }\n .sr-btn-secondary:hover { background: ${secondaryHoverBg}; }\n\n .sr-form {\n padding: 16px 20px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n flex: 1;\n min-height: 0;\n }\n\n .sr-field-grow {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n }\n\n .sr-field label {\n display: block;\n font-size: 13px;\n font-weight: 500;\n margin-bottom: 4px;\n color: ${labelText};\n }\n .sr-field input,\n .sr-field textarea,\n .sr-field select {\n width: 100%;\n padding: 8px 12px;\n border: none;\n border-radius: 8px;\n font-size: 14px;\n font-family: inherit;\n color: ${text};\n background: ${inputBg};\n outline: none;\n }\n .sr-field input:focus,\n .sr-field textarea:focus,\n .sr-field select:focus {\n box-shadow: none;\n }\n .sr-field textarea {\n resize: none;\n min-height: 160px;\n padding-bottom: 44px;\n }\n\n .sr-textarea-wrap {\n position: relative;\n flex: 1;\n display: flex;\n flex-direction: column;\n }\n .sr-textarea-wrap textarea {\n flex: 1;\n }\n .sr-send-btn {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: ${darkMode ? \"white\" : primary};\n color: ${darkMode ? \"#121212\" : \"white\"};\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n transition: opacity 0.15s;\n }\n .sr-send-btn:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n }\n .sr-send-btn svg {\n width: 16px;\n height: 16px;\n fill: currentColor;\n }\n\n .sr-categories {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n }\n .sr-category-btn {\n padding: 6px 12px;\n border: 1px solid ${border};\n border-radius: 9999px;\n font-size: 12px;\n font-weight: 500;\n background: ${inputBg};\n cursor: pointer;\n transition: all 0.15s;\n color: ${subtleText};\n }\n .sr-category-btn.active {\n border-color: ${primary};\n background: ${primary}11;\n color: ${primary};\n }\n .sr-category-btn:hover { border-color: ${primary}; }\n\n .sr-thread {\n display: flex;\n flex-direction: column;\n min-height: 0;\n height: 100%;\n }\n .sr-thread-messages {\n flex: 1 1 0;\n min-height: 0;\n overflow-y: auto;\n padding: 16px 20px;\n display: flex;\n flex-direction: column;\n gap: 0;\n }\n .sr-message-row {\n display: flex;\n flex-direction: column;\n gap: 6px;\n max-width: 75%;\n }\n .sr-message-row + .sr-message-row {\n margin-top: 20px;\n }\n .sr-message-row-user {\n align-self: flex-end;\n align-items: flex-end;\n }\n .sr-message-row-agent {\n align-self: flex-start;\n align-items: flex-start;\n }\n .sr-message {\n padding: 12px 16px;\n background: none;\n border: 1px solid ${borderLight};\n border-radius: 8px;\n font-size: 14px;\n line-height: 1.5;\n word-break: break-word;\n color: ${text};\n }\n .sr-message-meta {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 11px;\n color: ${mutedText};\n }\n .sr-message-sender {\n font-weight: 600;\n color: ${mutedText};\n }\n .sr-avatar {\n width: 18px;\n height: 18px;\n border-radius: 4px;\n background: ${primary};\n color: white;\n font-size: 10px;\n font-weight: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n overflow: hidden;\n }\n .sr-avatar img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n }\n\n .sr-original-desc {\n padding: 12px 16px;\n background: none;\n border-radius: 8px;\n border: 1px solid ${borderLight};\n font-size: 14px;\n color: ${text};\n white-space: pre-wrap;\n word-break: break-word;\n max-width: 75%;\n margin-bottom: 0;\n }\n .sr-original-desc .sr-desc-label {\n font-size: 11px;\n font-weight: 600;\n color: ${mutedText};\n text-transform: uppercase;\n margin-bottom: 6px;\n }\n\n .sr-composer {\n padding: 12px 20px;\n border-top: 1px solid ${subtleBorder};\n flex-shrink: 0;\n }\n .sr-composer-wrap {\n position: relative;\n }\n .sr-composer textarea {\n width: 100%;\n padding: 10px 8px;\n padding-right: 8px;\n padding-bottom: 40px;\n border: 1px solid ${borderLight};\n border-radius: 10px;\n font-size: 14px;\n font-family: inherit;\n resize: none;\n min-height: 80px;\n max-height: 120px;\n outline: none;\n color: ${text};\n background: ${darkMode ? \"#1a1a1a\" : inputBg};\n }\n .sr-composer textarea:focus {\n border-color: ${borderLight};\n box-shadow: none;\n }\n .sr-composer .sr-send-btn {\n width: 26px;\n height: 26px;\n }\n .sr-composer .sr-send-btn svg {\n width: 13px;\n height: 13px;\n }\n\n .sr-loading {\n padding: 40px 20px;\n text-align: center;\n color: ${mutedText};\n }\n\n .sr-error {\n padding: 12px 20px;\n background: ${errorBg};\n color: ${errorText};\n font-size: 13px;\n text-align: center;\n }\n\n .sr-success {\n padding: 40px 20px;\n text-align: center;\n }\n .sr-success-icon {\n width: 48px;\n height: 48px;\n margin: 0 auto 12px;\n background: ${successBg};\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .sr-success-icon svg { width: 24px; height: 24px; fill: ${successText}; }\n .sr-success h4 {\n font-size: 16px;\n font-weight: 600;\n margin-bottom: 4px;\n color: ${text};\n }\n .sr-success p {\n font-size: 14px;\n color: ${mutedText};\n }\n\n .sr-form-actions {\n display: flex;\n gap: 8px;\n padding-top: 4px;\n }\n .sr-form-actions .sr-btn { flex: 1; }\n\n .sr-new-btn-wrap {\n padding: 12px 20px;\n border-bottom: 1px solid ${subtleBorder};\n }\n .sr-new-btn-wrap .sr-btn { width: 100%; }\n\n .sr-suggested-articles {\n margin-top: 12px;\n display: flex;\n flex-direction: column;\n gap: 6px;\n }\n .sr-suggested-label {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 11px;\n font-weight: 600;\n color: ${mutedText};\n text-transform: uppercase;\n letter-spacing: 0.03em;\n margin-bottom: 2px;\n }\n .sr-suggested-label svg {\n width: 14px;\n height: 14px;\n stroke: ${primary};\n fill: none;\n }\n .sr-article-card {\n border: 1px solid ${borderLight};\n border-radius: 8px;\n overflow: hidden;\n background: ${surfaceBg};\n }\n .sr-article-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 10px 12px;\n background: none;\n border: none;\n cursor: pointer;\n text-align: left;\n font-size: 13px;\n font-family: inherit;\n color: ${text};\n transition: background 0.15s;\n }\n .sr-article-btn:hover { background: ${hoverBg}; }\n .sr-article-icon {\n width: 16px;\n height: 16px;\n stroke: ${primary};\n fill: none;\n flex-shrink: 0;\n }\n .sr-article-title {\n flex: 1;\n min-width: 0;\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .sr-article-chevron {\n width: 14px;\n height: 14px;\n flex-shrink: 0;\n stroke: ${mutedText};\n fill: none;\n transition: transform 0.2s;\n }\n .sr-article-chevron.sr-expanded { transform: rotate(180deg); }\n .sr-article-loading {\n padding: 8px 12px;\n font-size: 12px;\n color: ${mutedText};\n }\n .sr-article-content {\n padding: 12px;\n font-size: 13px;\n line-height: 1.6;\n color: ${labelText};\n word-break: break-word;\n border-top: 1px solid ${subtleBorder};\n max-height: 300px;\n overflow-y: auto;\n }\n\n .sr-link-preview {\n display: flex;\n margin-top: 8px;\n max-width: 420px;\n border: 1px solid ${borderLight};\n border-radius: 8px;\n overflow: hidden;\n background: ${surfaceBg};\n text-decoration: none;\n color: inherit;\n transition: border-color 0.15s;\n }\n .sr-link-preview:hover { border-color: ${mutedText}; }\n .sr-link-preview-img {\n flex-shrink: 0;\n width: 96px;\n border-right: 1px solid ${subtleBorder};\n }\n .sr-link-preview-img img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\n }\n .sr-link-preview-body {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 3px;\n padding: 8px 10px;\n }\n .sr-link-preview-site {\n display: flex;\n align-items: center;\n gap: 5px;\n font-size: 10.5px;\n color: ${mutedText};\n }\n .sr-link-preview-site span {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .sr-link-preview-favicon {\n width: 12px;\n height: 12px;\n border-radius: 2px;\n flex-shrink: 0;\n }\n .sr-link-preview-title {\n margin: 0;\n font-size: 12.5px;\n font-weight: 600;\n color: ${text};\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n line-height: 1.3;\n }\n .sr-link-preview-desc {\n margin: 0;\n font-size: 11.5px;\n color: ${mutedText};\n line-height: 1.4;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n }\n\n .sr-prose h1, .sr-prose h2, .sr-prose h3,\n .sr-prose h4, .sr-prose h5, .sr-prose h6 {\n margin-top: 1em;\n margin-bottom: 0.5em;\n font-weight: 600;\n line-height: 1.3;\n color: ${text};\n }\n .sr-prose h1 { font-size: 1.35em; }\n .sr-prose h2 { font-size: 1.2em; }\n .sr-prose h3 { font-size: 1.1em; }\n .sr-prose h4, .sr-prose h5, .sr-prose h6 { font-size: 1em; }\n .sr-prose h1:first-child, .sr-prose h2:first-child,\n .sr-prose h3:first-child { margin-top: 0; }\n\n .sr-prose p { margin: 0.5em 0; }\n .sr-prose p:first-child { margin-top: 0; }\n .sr-prose p:last-child { margin-bottom: 0; }\n\n .sr-prose ul, .sr-prose ol {\n margin: 0.5em 0;\n padding-left: 1.5em;\n }\n .sr-prose li { margin: 0.2em 0; }\n .sr-prose li > p { margin: 0; }\n\n .sr-prose a {\n color: ${primary};\n text-decoration: underline;\n text-underline-offset: 2px;\n }\n .sr-prose a:hover { text-decoration-thickness: 2px; }\n\n .sr-prose strong { font-weight: 600; }\n .sr-prose em { font-style: italic; }\n\n .sr-prose code {\n background: ${inlineCodeBg};\n padding: 0.15em 0.35em;\n border-radius: 4px;\n font-size: 0.9em;\n font-family: ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, monospace;\n }\n .sr-prose pre {\n background: ${preCodeBg};\n color: ${preCodeText};\n padding: 12px;\n border-radius: 6px;\n overflow-x: auto;\n margin: 0.75em 0;\n font-size: 0.85em;\n line-height: 1.5;\n }\n .sr-prose pre code {\n background: none;\n padding: 0;\n border-radius: 0;\n font-size: inherit;\n color: inherit;\n }\n\n .sr-prose blockquote {\n border-left: 3px solid ${border};\n padding-left: 12px;\n margin: 0.75em 0;\n color: ${blockquoteColor};\n }\n\n .sr-prose hr {\n border: none;\n border-top: 1px solid ${borderLight};\n margin: 1em 0;\n }\n\n .sr-prose img {\n max-width: 100%;\n height: auto;\n border-radius: 6px;\n margin: 0.5em 0;\n }\n\n .sr-prose table {\n width: 100%;\n border-collapse: collapse;\n margin: 0.75em 0;\n font-size: 0.9em;\n }\n .sr-prose th, .sr-prose td {\n border: 1px solid ${borderLight};\n padding: 6px 10px;\n text-align: left;\n }\n .sr-prose th {\n background: ${tableBg};\n font-weight: 600;\n }\n\n .sr-attach-btn {\n width: 28px;\n height: 28px;\n border-radius: 50%;\n background: none;\n color: ${mutedText};\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n transition: color 0.15s;\n }\n .sr-attach-btn:hover { color: ${text}; }\n .sr-attach-btn:disabled { opacity: 0.3; cursor: not-allowed; }\n .sr-attach-btn svg { width: 15px; height: 15px; }\n .sr-attach-btn-left {\n position: absolute;\n bottom: 8px;\n left: 8px;\n }\n .sr-send-btn-abs {\n position: absolute;\n bottom: 8px;\n right: 8px;\n }\n\n .sr-attachment-pills {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 4px 0 8px;\n }\n .sr-attachment-pill {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border-radius: 9999px;\n background: ${secondaryBg};\n font-size: 11px;\n color: ${mutedText};\n max-width: 200px;\n }\n .sr-attachment-pill-icon {\n width: 11px;\n height: 11px;\n flex-shrink: 0;\n }\n .sr-attachment-pill-name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .sr-attachment-pill-remove {\n width: 14px;\n height: 14px;\n border-radius: 50%;\n background: none;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n color: ${mutedText};\n flex-shrink: 0;\n }\n .sr-attachment-pill-remove:hover { color: ${text}; }\n .sr-attachment-pill-remove svg { width: 10px; height: 10px; }\n\n .sr-message-attachments {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-top: 6px;\n }\n\n .sr-file-preview {\n border: 1px solid ${borderLight};\n border-radius: 8px;\n overflow: hidden;\n max-width: 280px;\n }\n .sr-file-preview-image {\n display: block;\n border-bottom: 1px solid ${borderLight};\n }\n .sr-file-preview-image img {\n display: block;\n max-height: 180px;\n width: 100%;\n object-fit: contain;\n background: ${darkMode ? \"#1a1a1a\" : \"#f9fafb\"};\n }\n .sr-file-preview-image:hover img { opacity: 0.9; }\n\n .sr-file-preview-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px;\n }\n .sr-file-preview-icon {\n width: 16px;\n height: 16px;\n flex-shrink: 0;\n color: ${mutedText};\n }\n .sr-file-preview-info {\n min-width: 0;\n flex: 1;\n }\n .sr-file-preview-name {\n display: block;\n font-size: 12px;\n font-weight: 500;\n color: ${primary};\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n text-decoration: none;\n }\n .sr-file-preview-name:hover { text-decoration: underline; }\n span.sr-file-preview-name { color: ${text}; }\n span.sr-file-preview-name:hover { text-decoration: none; }\n .sr-file-preview-size {\n font-size: 11px;\n color: ${mutedText};\n }\n .sr-file-preview-download {\n flex-shrink: 0;\n padding: 4px;\n border-radius: 4px;\n color: ${mutedText};\n transition: color 0.15s, background 0.15s;\n }\n .sr-file-preview-download:hover {\n color: ${text};\n background: ${hoverBg};\n }\n .sr-file-preview-download svg {\n width: 14px;\n height: 14px;\n }\n\n ::-webkit-scrollbar {\n width: 13px;\n height: 13px;\n }\n ::-webkit-scrollbar-track {\n background: transparent;\n }\n ::-webkit-scrollbar-thumb {\n background: ${darkMode ? \"#525252\" : \"oklch(0.8 0 0)\"};\n border: 3px solid transparent;\n border-radius: 7px;\n background-clip: padding-box;\n }\n ::-webkit-scrollbar-thumb:hover {\n background: ${darkMode ? \"#666666\" : \"oklch(0.65 0 0)\"};\n border: 3px solid transparent;\n background-clip: padding-box;\n }\n `;\n}\n","/** @jsxImportSource preact */\nimport { useEffect, useState } from \"preact/hooks\";\n\nimport { ConversationList } from \"./ConversationList.js\";\nimport { ConversationThread } from \"./ConversationThread.js\";\nimport { Launcher } from \"./Launcher.js\";\nimport { getState, goBack, setView, subscribe } from \"./state.js\";\nimport { TicketForm } from \"./TicketForm.js\";\nimport type { WidgetOptions } from \"./types.js\";\n\nfunction BackButton() {\n return (\n <button onClick={goBack} aria-label=\"Back\">\n <svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z\" />\n </svg>\n </button>\n );\n}\n\nfunction NewTicketButton() {\n return (\n <button onClick={() => setView(\"new-ticket\")} aria-label=\"New conversation\">\n <svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z\" />\n </svg>\n </button>\n );\n}\n\nexport function Widget({ options }: { options: WidgetOptions }) {\n const [, setTick] = useState(0);\n const position = options.position ?? \"bottom-right\";\n const title = options.labels?.title ?? \"How can we help?\";\n const posClass = position === \"bottom-left\" ? \"left\" : \"right\";\n\n useEffect(() => {\n return subscribe(() => setTick((t) => t + 1));\n }, []);\n\n const state = getState();\n\n const threadTitle =\n state.activeConversation?.ticket.subject ??\n state.tickets.find((t) => t.id === state.activeTicketId)?.subject ??\n \"Conversation\";\n\n const viewTitles: Record<string, string> = {\n conversations: title,\n \"new-ticket\": options.labels?.newTicket ?? \"New conversation\",\n thread: threadTitle,\n };\n\n return (\n <>\n <Launcher position={position} isOpen={state.isOpen} />\n {state.isOpen && (\n <div class={`sr-panel ${posClass}`}>\n <div class=\"sr-header\">\n <div class=\"sr-header-actions\">\n {(state.view === \"new-ticket\" || state.view === \"thread\") && (\n <BackButton />\n )}\n </div>\n <h3\n class={state.view === \"thread\" ? \"sr-header-title-truncate\" : \"\"}\n >\n {viewTitles[state.view]}\n </h3>\n <div class=\"sr-header-actions\">\n {state.view === \"conversations\" && <NewTicketButton />}\n </div>\n </div>\n <div class=\"sr-body\">\n {state.view === \"conversations\" && <ConversationList />}\n {state.view === \"new-ticket\" && <TicketForm />}\n {state.view === \"thread\" && <ConversationThread />}\n </div>\n </div>\n )}\n </>\n );\n}\n","/** @jsxImportSource preact */\nimport { useEffect } from \"preact/hooks\";\n\nimport { fetchTickets } from \"./api.js\";\nimport { getState, openThread, setState, setView } from \"./state.js\";\nimport type { TicketSummary } from \"./types.js\";\n\nfunction timeAgo(dateStr: string): string {\n const seconds = Math.floor((Date.now() - new Date(dateStr).getTime()) / 1000);\n if (seconds < 60) return \"just now\";\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n\nfunction TicketItem({ ticket }: { ticket: TicketSummary }) {\n return (\n <li class=\"sr-ticket-item\" onClick={() => openThread(ticket.id)}>\n <h4>{ticket.subject}</h4>\n <div class=\"sr-meta\">\n <span>{timeAgo(ticket.lastMessageAt ?? ticket.createdAt)}</span>\n </div>\n </li>\n );\n}\n\nexport function ConversationList() {\n const state = getState();\n\n useEffect(() => {\n setState({ loading: true });\n fetchTickets()\n .then((tickets) => setState({ tickets, loading: false }))\n .catch(() => setState({ loading: false }));\n }, []);\n\n if (state.loading) {\n return <div class=\"sr-loading\">Loading conversations...</div>;\n }\n\n return (\n <div>\n {state.tickets.length === 0 ? (\n <div class=\"sr-empty\">\n <p>No conversations yet</p>\n <button\n class=\"sr-btn sr-btn-secondary\"\n onClick={() => setView(\"new-ticket\")}\n >\n Start one\n </button>\n </div>\n ) : (\n <ul class=\"sr-ticket-list\">\n {state.tickets.map((t) => (\n <TicketItem key={t.id} ticket={t} />\n ))}\n </ul>\n )}\n </div>\n );\n}\n","export interface Breadcrumb {\n type: string;\n category: string;\n message: string;\n timestamp: number;\n data?: Record<string, unknown>;\n}\n\nconst MAX_BREADCRUMBS = 20;\nconst MAX_TEXT_LENGTH = 120;\n\nlet buffer: Breadcrumb[] = [];\nlet installed = false;\n\nfunction push(crumb: Breadcrumb): void {\n buffer.push(crumb);\n if (buffer.length > MAX_BREADCRUMBS) {\n buffer = buffer.slice(-MAX_BREADCRUMBS);\n }\n}\n\nfunction truncate(str: string, max = MAX_TEXT_LENGTH): string {\n return str.length > max ? str.slice(0, max) + \"…\" : str;\n}\n\nexport function getBreadcrumbs(): Breadcrumb[] {\n return [...buffer];\n}\n\nexport function addBreadcrumb(crumb: Breadcrumb): void {\n push(crumb);\n}\n\nexport function startBreadcrumbCollection(): void {\n if (installed || typeof window === \"undefined\") return;\n installed = true;\n\n document.addEventListener(\n \"click\",\n (e) => {\n const target = e.target as HTMLElement | null;\n if (!target) return;\n const text =\n target.textContent?.trim() || target.getAttribute(\"aria-label\") || \"\";\n push({\n type: \"user\",\n category: \"click\",\n message: truncate(\n `${target.tagName.toLowerCase()}${text ? ` \"${text}\"` : \"\"}`,\n ),\n timestamp: Date.now(),\n data: {\n tagName: target.tagName.toLowerCase(),\n className: target.className\n ? truncate(target.className, 80)\n : undefined,\n },\n });\n },\n { capture: true },\n );\n\n const origPushState = history.pushState;\n history.pushState = function (...args) {\n const from = location.pathname;\n origPushState.apply(this, args);\n push({\n type: \"navigation\",\n category: \"navigation\",\n message: `${from} → ${location.pathname}`,\n timestamp: Date.now(),\n });\n };\n\n window.addEventListener(\"popstate\", () => {\n push({\n type: \"navigation\",\n category: \"navigation\",\n message: `popstate → ${location.pathname}`,\n timestamp: Date.now(),\n });\n });\n\n const wrapConsole = (level: \"error\" | \"warn\") => {\n const orig = console[level];\n console[level] = (...args: unknown[]) => {\n push({\n type: \"console\",\n category: `console.${level}`,\n message: truncate(\n args.map((a) => (typeof a === \"string\" ? a : String(a))).join(\" \"),\n ),\n timestamp: Date.now(),\n });\n orig.apply(console, args);\n };\n };\n\n wrapConsole(\"error\");\n wrapConsole(\"warn\");\n}\n","/**\n * Auto-capture browser context: page, referrer, screen, locale, user agent.\n */\nexport function getBrowserContext(): Record<string, unknown> {\n if (typeof window === \"undefined\") {\n return {};\n }\n\n return {\n page: {\n url: window.location.href,\n path: window.location.pathname,\n title: document.title,\n referrer: document.referrer || undefined,\n },\n screen: {\n width: window.screen.width,\n height: window.screen.height,\n },\n locale: navigator.language,\n userAgent: navigator.userAgent,\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n };\n}\n","interface TrackerLike {\n track(event: string, properties?: Record<string, unknown>): void;\n}\n\ninterface ErrorProperties {\n type: string;\n message: string;\n stack: string | undefined;\n handled: boolean;\n mechanism: string;\n source: \"browser\";\n filename?: string;\n lineno?: number;\n colno?: number;\n}\n\ntype BreadcrumbGetter = () => Array<{\n type: string;\n category: string;\n message: string;\n timestamp: number;\n data?: Record<string, unknown>;\n}>;\n\nconst DEDUP_COOLDOWN_MS = 60_000;\nconst dedupMap = new Map<string, number>();\n\nfunction simpleFingerprint(type: string, stack?: string): string {\n const firstFrame = stack?.split(\"\\n\")[1]?.trim() ?? \"\";\n return `${type}:${firstFrame}`;\n}\n\nfunction isDuplicate(fingerprint: string): boolean {\n const lastSent = dedupMap.get(fingerprint);\n if (lastSent && Date.now() - lastSent < DEDUP_COOLDOWN_MS) return true;\n dedupMap.set(fingerprint, Date.now());\n return false;\n}\n\nfunction sendException(\n tracker: TrackerLike,\n props: ErrorProperties,\n getBreadcrumbs: BreadcrumbGetter,\n): void {\n const fp = simpleFingerprint(props.type, props.stack);\n if (isDuplicate(fp)) return;\n\n tracker.track(\"$exception\", {\n ...props,\n context: { breadcrumbs: getBreadcrumbs() as unknown[] },\n });\n}\n\nexport function installGlobalHandlers(\n tracker: TrackerLike,\n getBreadcrumbs: BreadcrumbGetter,\n): void {\n if (typeof window === \"undefined\") return;\n\n window.onerror = (\n _message: string | Event,\n filename?: string,\n lineno?: number,\n colno?: number,\n error?: Error,\n ) => {\n const err = error ?? new Error(String(_message));\n sendException(\n tracker,\n {\n type: err.name || \"Error\",\n message: err.message || String(_message),\n stack: err.stack,\n handled: false,\n mechanism: \"onerror\",\n source: \"browser\",\n filename,\n lineno,\n colno,\n },\n getBreadcrumbs,\n );\n };\n\n window.onunhandledrejection = (event: PromiseRejectionEvent) => {\n const reason = event.reason;\n const err = reason instanceof Error ? reason : new Error(String(reason));\n sendException(\n tracker,\n {\n type: err.name || \"UnhandledRejection\",\n message: err.message,\n stack: err.stack,\n handled: false,\n mechanism: \"onunhandledrejection\",\n source: \"browser\",\n },\n getBreadcrumbs,\n );\n };\n}\n","import type { EvaluatedFlag } from \"./types.js\";\n\nconst DEFAULT_FLAG_POLL_INTERVAL = 60_000;\n\nexport interface FlagClientConfig {\n endpoint: string;\n writeKey: string;\n timeout?: number;\n environment?: string;\n pollInterval?: number;\n getIdentity: () => {\n userId?: string;\n anonymousId?: string;\n orgId?: string;\n };\n /** Called when a flag is first evaluated (for impression tracking). */\n onEvaluation?: (key: string, flag: EvaluatedFlag) => void;\n}\n\nexport class FlagClient {\n private endpoint: string;\n private writeKey: string;\n private timeout: number;\n private environment: string | undefined;\n private getIdentity: FlagClientConfig[\"getIdentity\"];\n private onEvaluation: FlagClientConfig[\"onEvaluation\"];\n\n private cache = new Map<string, EvaluatedFlag>();\n private ready = false;\n private readyCallbacks: Array<() => void> = [];\n private changeListeners = new Set<() => void>();\n private evalTracked = new Set<string>();\n private timer: ReturnType<typeof setInterval> | null = null;\n\n constructor(config: FlagClientConfig) {\n this.endpoint = config.endpoint;\n this.writeKey = config.writeKey;\n this.timeout = config.timeout ?? 10_000;\n this.environment = config.environment;\n this.getIdentity = config.getIdentity;\n this.onEvaluation = config.onEvaluation;\n\n const interval = config.pollInterval ?? DEFAULT_FLAG_POLL_INTERVAL;\n this.fetch();\n this.timer = setInterval(() => this.fetch(), interval);\n }\n\n getFlag<T = unknown>(key: string, defaultValue: T): T {\n const flag = this.cache.get(key);\n if (!flag) return defaultValue;\n\n if (!this.evalTracked.has(key)) {\n this.evalTracked.add(key);\n this.onEvaluation?.(key, flag);\n }\n\n return flag.value as T;\n }\n\n onFlagsReady(callback: () => void): void {\n if (this.ready) {\n callback();\n } else {\n this.readyCallbacks.push(callback);\n }\n }\n\n onFlagChange(listener: () => void): () => void {\n this.changeListeners.add(listener);\n return () => this.changeListeners.delete(listener);\n }\n\n async refresh(): Promise<void> {\n await this.fetch();\n }\n\n destroy(): void {\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = null;\n }\n }\n\n private async fetch(): Promise<void> {\n if (!this.writeKey || !this.endpoint) return;\n\n const params = new URLSearchParams();\n if (this.environment) params.set(\"environment\", this.environment);\n const identity = this.getIdentity();\n const identifier = identity.userId ?? identity.anonymousId;\n if (identifier) params.set(\"identifier\", identifier);\n if (identity.orgId) params.set(\"orgId\", identity.orgId);\n\n const qs = params.toString();\n const url = `${this.endpoint}/api/flags${qs ? `?${qs}` : \"\"}`;\n\n try {\n const res = await globalThis.fetch(url, {\n headers: { Authorization: `Bearer ${this.writeKey}` },\n signal: AbortSignal.timeout(this.timeout),\n });\n if (!res.ok) return;\n\n const json = (await res.json()) as {\n flags: Record<string, EvaluatedFlag>;\n };\n\n this.cache.clear();\n for (const [key, flag] of Object.entries(json.flags)) {\n this.cache.set(key, flag);\n }\n\n if (!this.ready) {\n this.ready = true;\n for (const cb of this.readyCallbacks) {\n try {\n cb();\n } catch {\n // ignore callback errors\n }\n }\n this.readyCallbacks = [];\n }\n\n for (const listener of this.changeListeners) {\n try {\n listener();\n } catch {\n // ignore listener errors\n }\n }\n } catch {\n // Silently fail — flags use cached values or defaults\n }\n }\n}\n","import {\n addBreadcrumb,\n getBreadcrumbs,\n startBreadcrumbCollection,\n} from \"./breadcrumbs.js\";\nimport { getBrowserContext } from \"./context.js\";\nimport { installGlobalHandlers } from \"./errors.js\";\nimport { FlagClient } from \"./flag-client.js\";\nimport type {\n FlushResult,\n IdentifyOptions,\n IdentifyTraits,\n InitOptions,\n TrackEvent,\n} from \"./types.js\";\n\nconst DEFAULT_FLUSH_AT = 10;\nconst DEFAULT_FLUSH_INTERVAL = 3_000;\nconst DEFAULT_TIMEOUT = 10_000;\nconst DEFAULT_SESSION_TIMEOUT = 30 * 60 * 1_000; // 30 minutes\nconst MAX_BATCH_SIZE = 100;\nconst ANON_ID_KEY = \"__scoperat_anon_id\";\nconst SESSION_ID_KEY = \"__scoperat_session_id\";\nconst LAST_ACTIVITY_KEY = \"__scoperat_last_activity\";\n/**\n * Storage key for the anonymous support-ticket session token minted\n * by the server via `POST /ticket/session`. Stored as\n * `{ anonymousId, token, expiresAt }` JSON. The widget replays this\n * token on every ticket call so the server never has to trust a\n * client-supplied anonymous id (see `lib/ticket-session.ts` in the\n * API).\n */\nconst TICKET_SESSION_KEY = \"__scoperat_ticket_session\";\n\ninterface StoredTicketSession {\n anonymousId: string;\n token: string;\n expiresAt: number;\n}\n\nfunction generateAnonId(): string {\n if (typeof crypto !== \"undefined\" && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === \"x\" ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\nfunction getOrCreateAnonId(): string | undefined {\n if (typeof window === \"undefined\" || typeof localStorage === \"undefined\") {\n return undefined;\n }\n\n try {\n let id = localStorage.getItem(ANON_ID_KEY);\n if (!id) {\n id = generateAnonId();\n localStorage.setItem(ANON_ID_KEY, id);\n }\n return id;\n } catch {\n return generateAnonId();\n }\n}\n\nclass TrackerImpl {\n private writeKey: string | null = null;\n private endpoint: string = \"\";\n private flushAt: number = DEFAULT_FLUSH_AT;\n private flushInterval: number = DEFAULT_FLUSH_INTERVAL;\n private timeout: number = DEFAULT_TIMEOUT;\n private onError?: (error: Error, events: TrackEvent[]) => void;\n\n private buffer: TrackEvent[] = [];\n private timer: ReturnType<typeof setInterval> | null = null;\n private visibilityHandler: (() => void) | null = null;\n private userId: string | undefined;\n private orgId: string | undefined;\n private traits: IdentifyTraits = {};\n private userHash: string | undefined;\n private anonymousId: string | undefined;\n private sessionTimeout: number = DEFAULT_SESSION_TIMEOUT;\n private ticketSessionFetch: Promise<StoredTicketSession | null> | null = null;\n\n private _flagClient: FlagClient | null = null;\n\n init(writeKey: string, options: InitOptions = {}): void {\n this.writeKey = writeKey;\n this.endpoint = (\n options.endpoint ??\n globalThis.location?.origin ??\n \"\"\n ).replace(/\\/+$/, \"\");\n this.flushAt = options.flushAt ?? DEFAULT_FLUSH_AT;\n this.flushInterval = options.flushInterval ?? DEFAULT_FLUSH_INTERVAL;\n this.timeout = options.timeout ?? DEFAULT_TIMEOUT;\n this.onError = options.onError;\n this.sessionTimeout = options.sessionTimeout ?? DEFAULT_SESSION_TIMEOUT;\n\n this.anonymousId = getOrCreateAnonId();\n\n if (this.timer) clearInterval(this.timer);\n this.timer = setInterval(() => {\n if (this.buffer.length > 0) {\n this.flush().catch(() => {});\n }\n }, this.flushInterval);\n\n if (typeof window !== \"undefined\") {\n if (this.visibilityHandler) {\n window.removeEventListener(\"visibilitychange\", this.visibilityHandler);\n }\n this.visibilityHandler = () => {\n if (document.visibilityState === \"hidden\" && this.buffer.length > 0) {\n this.flushSync();\n }\n };\n window.addEventListener(\"visibilitychange\", this.visibilityHandler);\n }\n\n if (options.captureErrors) {\n installGlobalHandlers(this, getBreadcrumbs);\n startBreadcrumbCollection();\n }\n\n this._flagClient?.destroy();\n this._flagClient = new FlagClient({\n endpoint: this.endpoint,\n writeKey,\n timeout: this.timeout,\n environment: options.environment,\n pollInterval: options.flagPollInterval,\n getIdentity: () => ({\n userId: this.userId,\n anonymousId: this.anonymousId,\n orgId: this.orgId,\n }),\n onEvaluation: (key, flag) =>\n this.track(\"$flag_evaluation\", {\n flag_key: key,\n flag_value: flag.value,\n flag_type: flag.type,\n flag_source: flag.source,\n }),\n });\n }\n\n /** The underlying flag evaluation client. Use for direct SDK integration. */\n get flags(): FlagClient {\n if (!this._flagClient) {\n throw new Error(\"Tracker not initialized. Call init() first.\");\n }\n return this._flagClient;\n }\n\n identify(\n userId: string,\n traits?: IdentifyTraits,\n options?: IdentifyOptions,\n ): void {\n this.userId = userId;\n if (traits) {\n this.traits = { ...traits };\n if (traits.orgId) this.orgId = traits.orgId;\n }\n // Switching from one identified user to another invalidates the\n // prior userHash — callers must either pass a new one or accept\n // that ticket calls degrade to the anonymous session channel.\n this.userHash = options?.userHash;\n\n for (const evt of this.buffer) {\n if (!evt.user_id) evt.user_id = userId;\n if (!evt.org_id && this.orgId) evt.org_id = this.orgId;\n }\n\n this._flagClient?.refresh();\n }\n\n reset(): void {\n this.userId = undefined;\n this.orgId = undefined;\n this.traits = {};\n this.userHash = undefined;\n this.anonymousId = getOrCreateAnonId();\n this.clearSession();\n this.clearTicketSession();\n }\n\n private clearTicketSession(): void {\n this.ticketSessionFetch = null;\n if (typeof localStorage === \"undefined\") return;\n try {\n localStorage.removeItem(TICKET_SESSION_KEY);\n } catch {\n // ignore storage errors\n }\n }\n\n private readStoredTicketSession(): StoredTicketSession | null {\n if (typeof localStorage === \"undefined\") return null;\n try {\n const raw = localStorage.getItem(TICKET_SESSION_KEY);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as Partial<StoredTicketSession>;\n if (\n typeof parsed.anonymousId === \"string\" &&\n typeof parsed.token === \"string\" &&\n typeof parsed.expiresAt === \"number\" &&\n parsed.expiresAt > Date.now() + 60_000\n ) {\n return parsed as StoredTicketSession;\n }\n localStorage.removeItem(TICKET_SESSION_KEY);\n } catch {\n // fall through to network fetch\n }\n return null;\n }\n\n /**\n * @internal Used by the widget API helpers. Returns a cached or\n * newly-minted anonymous session token, or `null` if the server\n * has anonymous sessions disabled. Coalesces concurrent callers\n * onto a single in-flight network request so mount-time parallel\n * API calls don't each trigger a `POST /ticket/session`.\n */\n _ensureTicketSession(): Promise<StoredTicketSession | null> {\n const cached = this.readStoredTicketSession();\n if (cached) return Promise.resolve(cached);\n\n if (this.ticketSessionFetch) return this.ticketSessionFetch;\n if (!this.writeKey) return Promise.resolve(null);\n\n this.ticketSessionFetch = (async () => {\n try {\n const res = await fetch(`${this.endpoint}/api/ingest/ticket/session`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.writeKey}`,\n },\n body: \"{}\",\n signal: AbortSignal.timeout(this.timeout),\n });\n if (!res.ok) return null;\n const json = (await res.json()) as StoredTicketSession;\n if (\n typeof json?.anonymousId === \"string\" &&\n typeof json?.token === \"string\" &&\n typeof json?.expiresAt === \"number\"\n ) {\n try {\n localStorage?.setItem(TICKET_SESSION_KEY, JSON.stringify(json));\n } catch {\n // ignore storage errors\n }\n // Keep our in-memory anonymousId in sync with the\n // server-issued one so any code that reads `_getIdentity`\n // outside the ticket flow (e.g. analytics) sees a\n // consistent value.\n this.anonymousId = json.anonymousId;\n return json;\n }\n return null;\n } catch {\n return null;\n } finally {\n this.ticketSessionFetch = null;\n }\n })();\n\n return this.ticketSessionFetch;\n }\n\n private getOrCreateSessionId(): string | undefined {\n if (typeof window === \"undefined\") return undefined;\n\n try {\n const now = Date.now();\n const lastActivity = localStorage.getItem(LAST_ACTIVITY_KEY);\n const existingId = sessionStorage.getItem(SESSION_ID_KEY);\n\n const expired =\n !lastActivity || now - Number(lastActivity) > this.sessionTimeout;\n\n if (existingId && !expired) {\n localStorage.setItem(LAST_ACTIVITY_KEY, String(now));\n return existingId;\n }\n\n const newId = generateAnonId();\n sessionStorage.setItem(SESSION_ID_KEY, newId);\n localStorage.setItem(LAST_ACTIVITY_KEY, String(now));\n return newId;\n } catch {\n return generateAnonId();\n }\n }\n\n private clearSession(): void {\n if (typeof window === \"undefined\") return;\n try {\n sessionStorage.removeItem(SESSION_ID_KEY);\n localStorage.removeItem(LAST_ACTIVITY_KEY);\n } catch {\n // Ignore storage errors\n }\n }\n\n getSessionId(): string | undefined {\n return this.getOrCreateSessionId();\n }\n\n /** @internal Used by the widget to read tracker config. */\n _getEndpoint(): string {\n return this.endpoint;\n }\n\n /** @internal Used by the widget to read the write key. */\n _getWriteKey(): string | null {\n return this.writeKey;\n }\n\n /** @internal Used by the widget to read the current user identity. */\n _getIdentity(): {\n userId?: string;\n anonymousId?: string;\n email?: string;\n name?: string;\n userHash?: string;\n } {\n return {\n userId: this.userId,\n anonymousId: this.anonymousId,\n email: this.traits.email as string | undefined,\n name: this.traits.name as string | undefined,\n userHash: this.userHash,\n };\n }\n\n captureException(error: Error, context?: Record<string, unknown>): void {\n if (!this.writeKey) return;\n\n const breadcrumbs = getBreadcrumbs();\n this.track(\"$exception\", {\n type: error.name || \"Error\",\n message: error.message,\n stack: error.stack,\n handled: true,\n mechanism: (context?.mechanism as string) ?? \"manual\",\n source: \"browser\",\n ...context,\n context: { breadcrumbs: breadcrumbs as unknown[] },\n });\n }\n\n addBreadcrumb(\n category: string,\n message: string,\n data?: Record<string, unknown>,\n ): void {\n addBreadcrumb({\n type: \"custom\",\n category,\n message,\n timestamp: Date.now(),\n data,\n });\n }\n\n track(event: string, properties?: Record<string, unknown>): void;\n track(event: TrackEvent): void;\n track(\n eventOrName: string | TrackEvent,\n properties?: Record<string, unknown>,\n ): void {\n if (!this.writeKey) return;\n\n const evt: TrackEvent =\n typeof eventOrName === \"string\"\n ? { event: eventOrName, properties }\n : eventOrName;\n\n const traitsContext =\n Object.keys(this.traits).length > 0 ? { traits: this.traits } : {};\n\n const enriched: TrackEvent = {\n ...evt,\n occurred_at: evt.occurred_at ?? new Date().toISOString(),\n source: evt.source ?? \"browser\",\n org_id: evt.org_id ?? this.orgId,\n user_id: evt.user_id ?? this.userId,\n anonymous_id: evt.anonymous_id ?? this.anonymousId,\n session_id: evt.session_id ?? this.getOrCreateSessionId(),\n context: {\n ...getBrowserContext(),\n ...traitsContext,\n ...evt.context,\n },\n };\n\n this.buffer.push(enriched);\n\n if (this.buffer.length >= this.flushAt) {\n this.flush().catch(() => {});\n }\n }\n\n async flush(): Promise<FlushResult> {\n if (!this.writeKey || this.buffer.length === 0) {\n return { success: true, ingested: 0 };\n }\n\n const batch = this.buffer.splice(0, MAX_BATCH_SIZE);\n\n try {\n const res = await fetch(`${this.endpoint}/api/ingest/track`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.writeKey}`,\n },\n body: JSON.stringify({ events: batch }),\n signal: AbortSignal.timeout(this.timeout),\n });\n\n if (!res.ok) {\n const body = await res.text().catch(() => \"\");\n throw new Error(`API returned ${res.status}: ${body}`);\n }\n\n const json = (await res.json()) as { ingested: number };\n return { success: true, ingested: json.ingested };\n } catch (error) {\n this.buffer.unshift(...batch);\n const err = error instanceof Error ? error : new Error(String(error));\n this.onError?.(err, batch);\n return { success: false, ingested: 0 };\n }\n }\n\n private flushSync(): void {\n if (!this.writeKey) return;\n if (typeof navigator === \"undefined\" || !navigator.sendBeacon) return;\n if (this.buffer.length === 0) return;\n\n const batch = this.buffer.splice(0, MAX_BATCH_SIZE);\n const payload = JSON.stringify({ events: batch });\n const url = `${this.endpoint}/api/ingest/track?key=${encodeURIComponent(this.writeKey)}`;\n\n try {\n const blob = new Blob([payload], { type: \"application/json\" });\n navigator.sendBeacon(url, blob);\n } catch {\n // Best effort on unload\n }\n }\n\n getFlag<T = unknown>(key: string, defaultValue: T): T {\n return this._flagClient?.getFlag(key, defaultValue) ?? defaultValue;\n }\n\n onFlagsReady(callback: () => void): void {\n this._flagClient?.onFlagsReady(callback);\n }\n\n onFlagChange(listener: () => void): () => void {\n return this._flagClient?.onFlagChange(listener) ?? (() => {});\n }\n\n async refreshFlags(): Promise<void> {\n await this._flagClient?.refresh();\n }\n\n async shutdown(): Promise<void> {\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = null;\n }\n\n this._flagClient?.destroy();\n this._flagClient = null;\n\n if (typeof window !== \"undefined\" && this.visibilityHandler) {\n window.removeEventListener(\"visibilitychange\", this.visibilityHandler);\n this.visibilityHandler = null;\n }\n\n while (this.buffer.length > 0) {\n await this.flush();\n }\n }\n}\n\nconst scoperat = new TrackerImpl();\nexport default scoperat;\n","import scoperat from \"../client.js\";\nimport { getBrowserContext } from \"../context.js\";\nimport type {\n PendingAttachment,\n TicketConversation,\n TicketSummary,\n} from \"./types.js\";\n\n/**\n * Resolve the identity headers this widget call should send. We\n * prefer an `X-Scoperat-User-Hash` header when the host site has\n * supplied a `userHash` via `identify(..., { userHash })` — that\n * proves to the server that the claimed `userId` is vouched for by\n * the host's backend. When no `userHash` is available (anonymous\n * visitors, or host hasn't wired up identity verification yet), we\n * fall back to the server-issued anonymous session token minted by\n * `POST /ticket/session`.\n *\n * Raw `userId` / `anonymousId` values are NEVER sent as bearer\n * identity — the server refuses unverified identity input on every\n * ticket endpoint (see `requireVerifiedIdentity` in the API).\n */\nasync function identityHeaders(): Promise<Record<string, string>> {\n const identity = scoperat._getIdentity();\n if (identity.userId && identity.userHash) {\n return {\n \"X-Scoperat-User-Hash\": identity.userHash,\n \"X-Scoperat-User-Id\": identity.userId,\n };\n }\n const session = await scoperat._ensureTicketSession();\n if (session) {\n return { \"X-Scoperat-Session\": session.token };\n }\n return {};\n}\n\n/**\n * Resolve identity as URL query params (for GET requests that can't\n * easily carry custom headers through some proxies/CDNs). Falls\n * back to empty when no verified channel is available — the server\n * will respond 401 and the widget UI surfaces a \"sign in to view\n * tickets\" message.\n */\nasync function identityQueryParams(): Promise<URLSearchParams> {\n const params = new URLSearchParams();\n const identity = scoperat._getIdentity();\n if (identity.userId && identity.userHash) {\n params.set(\"user_id\", identity.userId);\n params.set(\"user_hash\", identity.userHash);\n return params;\n }\n const session = await scoperat._ensureTicketSession();\n if (session) {\n params.set(\"session\", session.token);\n }\n return params;\n}\n\nasync function jsonHeaders(): Promise<Record<string, string>> {\n const key = scoperat._getWriteKey();\n return {\n \"Content-Type\": \"application/json\",\n ...(key ? { Authorization: `Bearer ${key}` } : {}),\n ...(await identityHeaders()),\n };\n}\n\nasync function authHeaders(): Promise<Record<string, string>> {\n const key = scoperat._getWriteKey();\n return {\n ...(key ? { Authorization: `Bearer ${key}` } : {}),\n ...(await identityHeaders()),\n };\n}\n\nfunction baseUrl(): string {\n return scoperat._getEndpoint();\n}\n\nexport async function uploadFile(file: File): Promise<PendingAttachment> {\n const form = new FormData();\n form.append(\"file\", file);\n\n const res = await fetch(`${baseUrl()}/api/ingest/ticket/upload`, {\n method: \"POST\",\n headers: await authHeaders(),\n body: form,\n });\n\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n throw new Error(`Upload failed: ${res.status} ${text}`);\n }\n\n return res.json() as Promise<PendingAttachment>;\n}\n\nexport async function createTicket(data: {\n subject: string;\n description: string;\n category?: string;\n email?: string;\n name?: string;\n metadata?: Record<string, unknown>;\n attachments?: PendingAttachment[];\n}): Promise<{ id: string; status: string }> {\n const identity = scoperat._getIdentity();\n const context = getBrowserContext();\n\n const res = await fetch(`${baseUrl()}/api/ingest/ticket`, {\n method: \"POST\",\n headers: await jsonHeaders(),\n body: JSON.stringify({\n ...data,\n attachments: data.attachments?.map((a) => ({\n storageKey: a.storageKey,\n fileName: a.fileName,\n mimeType: a.mimeType,\n fileSize: a.size,\n })),\n email: data.email ?? identity.email,\n name: data.name ?? identity.name,\n metadata: {\n ...context,\n ...data.metadata,\n },\n }),\n });\n\n if (!res.ok) {\n const body = await res.text().catch(() => \"\");\n throw new Error(`Failed to create ticket: ${res.status} ${body}`);\n }\n\n return res.json() as Promise<{ id: string; status: string }>;\n}\n\nexport async function sendMessage(\n ticketId: string,\n body: string,\n attachments?: PendingAttachment[],\n): Promise<{ id: string }> {\n const res = await fetch(`${baseUrl()}/api/ingest/ticket/message`, {\n method: \"POST\",\n headers: await jsonHeaders(),\n body: JSON.stringify({\n ticketId,\n body,\n attachments: attachments?.map((a) => ({\n storageKey: a.storageKey,\n fileName: a.fileName,\n mimeType: a.mimeType,\n fileSize: a.size,\n })),\n }),\n });\n\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n throw new Error(`Failed to send message: ${res.status} ${text}`);\n }\n\n return res.json() as Promise<{ id: string }>;\n}\n\nexport async function fetchTickets(): Promise<TicketSummary[]> {\n const params = await identityQueryParams();\n\n const key = scoperat._getWriteKey();\n if (key) params.set(\"key\", key);\n\n const res = await fetch(\n `${baseUrl()}/api/ingest/tickets?${params.toString()}`,\n { headers: await authHeaders() },\n );\n\n if (!res.ok) return [];\n\n const data = (await res.json()) as { tickets: TicketSummary[] };\n return data.tickets;\n}\n\nexport async function fetchConversation(\n ticketId: string,\n): Promise<TicketConversation> {\n const params = await identityQueryParams();\n\n const res = await fetch(\n `${baseUrl()}/api/ingest/ticket/${ticketId}?${params.toString()}`,\n { headers: await authHeaders() },\n );\n\n if (!res.ok) {\n throw new Error(`Failed to fetch conversation: ${res.status}`);\n }\n\n return res.json() as Promise<TicketConversation>;\n}\n\nexport async function fetchPublicKbPage(\n workspaceSlug: string,\n pageSlug: string,\n): Promise<{\n page: { title: string; contentUrl: string };\n workspace: { name: string };\n} | null> {\n try {\n const res = await fetch(`${baseUrl()}/api/kb/${workspaceSlug}/${pageSlug}`);\n if (!res.ok) return null;\n return res.json() as Promise<{\n page: { title: string; contentUrl: string };\n workspace: { name: string };\n }>;\n } catch {\n return null;\n }\n}\n","import type { TicketConversation, TicketSummary, WidgetView } from \"./types.js\";\n\ntype Listener = () => void;\n\ninterface WidgetState {\n isOpen: boolean;\n view: WidgetView;\n tickets: TicketSummary[];\n activeTicketId: string | null;\n activeConversation: TicketConversation | null;\n loading: boolean;\n error: string | null;\n}\n\nconst listeners = new Set<Listener>();\n\nlet state: WidgetState = {\n isOpen: false,\n view: \"conversations\",\n tickets: [],\n activeTicketId: null,\n activeConversation: null,\n loading: false,\n error: null,\n};\n\nfunction notify() {\n for (const fn of listeners) fn();\n}\n\nexport function getState(): WidgetState {\n return state;\n}\n\nexport function subscribe(fn: Listener): () => void {\n listeners.add(fn);\n return () => listeners.delete(fn);\n}\n\nexport function setState(partial: Partial<WidgetState>) {\n state = { ...state, ...partial };\n notify();\n}\n\nexport function toggleOpen() {\n setState({ isOpen: !state.isOpen });\n}\n\nexport function setView(view: WidgetView) {\n setState({ view });\n}\n\nexport function openThread(ticketId: string) {\n setState({ view: \"thread\", activeTicketId: ticketId });\n}\n\nexport function goBack() {\n setState({\n view: \"conversations\",\n activeTicketId: null,\n activeConversation: null,\n });\n}\n","/** @jsxImportSource preact */\nimport DOMPurify from \"dompurify\";\nimport { Marked } from \"marked\";\nimport {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"preact/hooks\";\n\nimport {\n fetchConversation,\n fetchPublicKbPage,\n sendMessage,\n uploadFile,\n} from \"./api.js\";\nimport { getState, setState } from \"./state.js\";\nimport type {\n PendingAttachment,\n SuggestedArticle,\n TicketMessage,\n WidgetAttachment,\n} from \"./types.js\";\n\nconst marked = new Marked({ async: false, gfm: true, breaks: true });\n\n// The widget is embedded on customer websites via an open shadow DOM (see\n// `initWidget` in `./index.ts`). Shadow DOM is a style-isolation mechanism,\n// NOT a security boundary: any script that executes inside the shadow tree\n// runs on the host page's origin with full access to cookies, storage and\n// fetch. Message bodies, ticket descriptions and KB article content all flow\n// into `dangerouslySetInnerHTML` below, and their sources include untrusted\n// input (end-user ticket bodies, AI-authored \"system\" messages from\n// `ticket-analysis.ts`). Every HTML string we inject MUST go through\n// `renderMarkdown` so DOMPurify strips scripts, event handlers and\n// `javascript:` URLs before it reaches the DOM.\nif (typeof window !== \"undefined\") {\n DOMPurify.addHook(\"afterSanitizeAttributes\", (node) => {\n if (node.tagName === \"A\") {\n node.setAttribute(\"target\", \"_blank\");\n node.setAttribute(\"rel\", \"noopener noreferrer\");\n }\n });\n}\n\nfunction renderMarkdown(text: string): string {\n const rawHtml = marked.parse(text) as string;\n return DOMPurify.sanitize(rawHtml, { USE_PROFILES: { html: true } });\n}\n\nfunction formatTime(dateStr: string): string {\n const d = new Date(dateStr);\n const now = new Date();\n const sameDay =\n d.getFullYear() === now.getFullYear() &&\n d.getMonth() === now.getMonth() &&\n d.getDate() === now.getDate();\n\n if (sameDay) {\n return d.toLocaleTimeString(undefined, {\n hour: \"numeric\",\n minute: \"2-digit\",\n });\n }\n return d.toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n });\n}\n\nfunction Avatar({\n name,\n imageUrl,\n}: {\n name: string;\n imageUrl?: string | null;\n}) {\n if (imageUrl) {\n return (\n <div class=\"sr-avatar\">\n <img src={imageUrl} alt={name} />\n </div>\n );\n }\n return <div class=\"sr-avatar\">{name.charAt(0).toUpperCase()}</div>;\n}\n\nfunction formatFileSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nfunction FilePreview({ attachment }: { attachment: WidgetAttachment }) {\n const isImage = attachment.mimeType.startsWith(\"image/\");\n\n return (\n <div class=\"sr-file-preview\">\n {isImage && attachment.url && (\n <a\n href={attachment.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"sr-file-preview-image\"\n >\n <img src={attachment.url} alt={attachment.fileName} />\n </a>\n )}\n <div class=\"sr-file-preview-row\">\n <svg\n class=\"sr-file-preview-icon\"\n viewBox=\"0 0 24 24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <polyline\n points=\"14 2 14 8 20 8\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n <div class=\"sr-file-preview-info\">\n {attachment.url ? (\n <a\n href={attachment.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"sr-file-preview-name\"\n >\n {attachment.fileName}\n </a>\n ) : (\n <span class=\"sr-file-preview-name\">{attachment.fileName}</span>\n )}\n <span class=\"sr-file-preview-size\">\n {formatFileSize(attachment.fileSize)}\n </span>\n </div>\n {attachment.url && (\n <a\n href={attachment.url}\n download={attachment.fileName}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"sr-file-preview-download\"\n aria-label=\"Download\"\n >\n <svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </a>\n )}\n </div>\n </div>\n );\n}\n\nfunction MessageAttachments({ messageId }: { messageId: string | null }) {\n const state = getState();\n const allAttachments = state.activeConversation?.attachments ?? [];\n const msgAttachments = allAttachments.filter(\n (a) => a.messageId === messageId,\n );\n if (msgAttachments.length === 0) return null;\n\n return (\n <div class=\"sr-message-attachments\">\n {msgAttachments.map((att) => (\n <FilePreview key={att.id} attachment={att} />\n ))}\n </div>\n );\n}\n\ninterface WidgetLinkPreview {\n url: string;\n title: string | null;\n description: string | null;\n image: string | null;\n siteName: string | null;\n favicon: string | null;\n}\n\nfunction LinkPreviewCard({ preview }: { preview: WidgetLinkPreview }) {\n let hostname = \"\";\n try {\n hostname = new URL(preview.url).hostname.replace(/^www\\./, \"\");\n } catch {\n /* leave blank */\n }\n\n return (\n <a\n class=\"sr-link-preview\"\n href={preview.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {preview.image && (\n <div class=\"sr-link-preview-img\">\n <img\n src={preview.image}\n alt=\"\"\n loading=\"lazy\"\n onError={(e) => {\n const parent = (e.currentTarget as HTMLElement)\n .parentElement as HTMLElement | null;\n if (parent) parent.style.display = \"none\";\n }}\n />\n </div>\n )}\n <div class=\"sr-link-preview-body\">\n <div class=\"sr-link-preview-site\">\n {preview.favicon ? (\n <img\n class=\"sr-link-preview-favicon\"\n src={preview.favicon}\n alt=\"\"\n onError={(e) => {\n (e.currentTarget as HTMLElement).style.display = \"none\";\n }}\n />\n ) : null}\n <span>{preview.siteName ?? hostname}</span>\n </div>\n {preview.title && <p class=\"sr-link-preview-title\">{preview.title}</p>}\n {preview.description && (\n <p class=\"sr-link-preview-desc\">{preview.description}</p>\n )}\n </div>\n </a>\n );\n}\n\nfunction Message({ msg }: { msg: TicketMessage }) {\n const isUser = msg.senderType === \"user\";\n const senderName =\n msg.senderType === \"agent\"\n ? (msg.agentName ?? msg.senderName ?? \"Support\")\n : null;\n\n const displayName = isUser ? \"You\" : (senderName ?? \"Support\");\n const html = useMemo(() => renderMarkdown(msg.body), [msg.body]);\n\n const isAttachmentOnly = msg.body === \"(attachment)\";\n\n const messageArticles = useMemo(() => {\n const raw = (msg.metadata as Record<string, unknown> | null)?.articles;\n if (!Array.isArray(raw) || raw.length === 0) return null;\n return raw as SuggestedArticle[];\n }, [msg.metadata]);\n\n const linkPreview = useMemo<WidgetLinkPreview | null>(() => {\n const raw = (msg.metadata as Record<string, unknown> | null)?.linkPreview;\n if (!raw || typeof raw !== \"object\") return null;\n const candidate = raw as { url?: unknown } & Record<string, unknown>;\n if (typeof candidate.url !== \"string\") return null;\n return candidate as unknown as WidgetLinkPreview;\n }, [msg.metadata]);\n\n return (\n <div\n class={`sr-message-row ${isUser ? \"sr-message-row-user\" : \"sr-message-row-agent\"}`}\n >\n {!isAttachmentOnly && (\n <div\n class=\"sr-message sr-prose\"\n dangerouslySetInnerHTML={{ __html: html }}\n />\n )}\n <MessageAttachments messageId={msg.id} />\n {messageArticles && <SuggestedArticles articles={messageArticles} />}\n {linkPreview && <LinkPreviewCard preview={linkPreview} />}\n <div class=\"sr-message-meta\">\n {!isUser && <Avatar name={displayName} imageUrl={msg.agentAvatarUrl} />}\n <span class=\"sr-message-sender\">{displayName}</span>\n <span>·</span>\n <span>{formatTime(msg.createdAt)}</span>\n </div>\n </div>\n );\n}\n\nfunction MessageComposer({ ticketId }: { ticketId: string }) {\n const [body, setBody] = useState(\"\");\n const [sending, setSending] = useState(false);\n const [attachments, setAttachments] = useState<PendingAttachment[]>([]);\n const [uploading, setUploading] = useState(false);\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const handleFileSelect = useCallback(\n async (e: Event) => {\n const input = e.target as HTMLInputElement;\n const files = input.files;\n if (!files) return;\n for (let i = 0; i < files.length && attachments.length + i < 5; i++) {\n setUploading(true);\n try {\n const result = await uploadFile(files[i]!);\n setAttachments((prev) => [...prev, result]);\n } catch {\n /* silently fail */\n } finally {\n setUploading(false);\n }\n }\n input.value = \"\";\n },\n [attachments.length],\n );\n\n const handleSend = useCallback(async () => {\n if ((!body.trim() && attachments.length === 0) || sending) return;\n setSending(true);\n try {\n await sendMessage(\n ticketId,\n body.trim() || \"(attachment)\",\n attachments.length ? attachments : undefined,\n );\n setBody(\"\");\n setAttachments([]);\n const conv = await fetchConversation(ticketId);\n setState({ activeConversation: conv });\n } catch {\n // silently fail for now\n } finally {\n setSending(false);\n }\n }, [body, sending, ticketId, attachments]);\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleSend();\n }\n },\n [handleSend],\n );\n\n const canSend = (!!body.trim() || attachments.length > 0) && !sending;\n\n return (\n <div class=\"sr-composer\">\n {(attachments.length > 0 || uploading) && (\n <div class=\"sr-attachment-pills\">\n {attachments.map((att) => (\n <div key={att.storageKey} class=\"sr-attachment-pill\">\n <svg\n class=\"sr-attachment-pill-icon\"\n viewBox=\"0 0 24 24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M21.44 11.05l-9.19 9.19a6 6 0 01-8.49-8.49l9.19-9.19a4 4 0 015.66 5.66l-9.2 9.19a2 2 0 01-2.83-2.83l8.49-8.48\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n <span class=\"sr-attachment-pill-name\">{att.fileName}</span>\n <button\n type=\"button\"\n class=\"sr-attachment-pill-remove\"\n onClick={() =>\n setAttachments((prev) =>\n prev.filter((a) => a.storageKey !== att.storageKey),\n )\n }\n aria-label=\"Remove\"\n >\n <svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M18 6L6 18M6 6l12 12\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n </div>\n ))}\n {uploading && (\n <div class=\"sr-attachment-pill\">\n <span class=\"sr-attachment-pill-name\">Uploading...</span>\n </div>\n )}\n </div>\n )}\n <div class=\"sr-composer-wrap\">\n <textarea\n value={body}\n onInput={(e) => setBody((e.target as HTMLTextAreaElement).value)}\n onKeyDown={handleKeyDown}\n placeholder=\"Ask about this issue...\"\n rows={3}\n />\n <button\n type=\"button\"\n class=\"sr-attach-btn sr-attach-btn-left\"\n onClick={() => fileInputRef.current?.click()}\n aria-label=\"Attach file\"\n disabled={attachments.length >= 5}\n >\n <svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M21.44 11.05l-9.19 9.19a6 6 0 01-8.49-8.49l9.19-9.19a4 4 0 015.66 5.66l-9.2 9.19a2 2 0 01-2.83-2.83l8.49-8.48\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n <button\n class=\"sr-send-btn sr-send-btn-abs\"\n onClick={handleSend}\n disabled={!canSend}\n aria-label=\"Send\"\n >\n <svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z\" />\n </svg>\n </button>\n </div>\n <input\n ref={fileInputRef}\n type=\"file\"\n multiple\n style={{ display: \"none\" }}\n onChange={handleFileSelect}\n />\n </div>\n );\n}\n\nfunction ArticleCard({ article }: { article: SuggestedArticle }) {\n const [rawContent, setRawContent] = useState<string | null>(null);\n const [expanded, setExpanded] = useState(false);\n const [loading, setLoading] = useState(false);\n\n const html = useMemo(() => {\n if (!rawContent) return \"\";\n return renderMarkdown(rawContent);\n }, [rawContent]);\n\n const handleClick = useCallback(async () => {\n if (expanded) {\n setExpanded(false);\n return;\n }\n if (rawContent) {\n setExpanded(true);\n return;\n }\n setLoading(true);\n const data = await fetchPublicKbPage(article.workspaceSlug, article.slug);\n if (data?.page.contentUrl) {\n try {\n const res = await fetch(data.page.contentUrl);\n if (res.ok) {\n const text = await res.text();\n setRawContent(text);\n }\n } catch {\n /* fall through */\n }\n }\n setExpanded(true);\n setLoading(false);\n }, [article, rawContent, expanded]);\n\n return (\n <div class=\"sr-article-card\">\n <button type=\"button\" class=\"sr-article-btn\" onClick={handleClick}>\n <svg\n class=\"sr-article-icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H20v20H6.5a2.5 2.5 0 0 1 0-5H20\" />\n </svg>\n <span class=\"sr-article-title\">{article.title}</span>\n <svg\n class={`sr-article-chevron ${expanded ? \"sr-expanded\" : \"\"}`}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </button>\n {loading && <div class=\"sr-article-loading\">Loading...</div>}\n {expanded && html && (\n <div\n class=\"sr-article-content sr-prose\"\n dangerouslySetInnerHTML={{ __html: html }}\n />\n )}\n </div>\n );\n}\n\nfunction SuggestedArticles({ articles }: { articles: SuggestedArticle[] }) {\n if (!articles || articles.length === 0) return null;\n\n return (\n <div class=\"sr-suggested-articles\">\n <div class=\"sr-suggested-label\">\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3\" />\n <line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\" />\n </svg>\n These articles may help\n </div>\n {articles.map((article) => (\n <ArticleCard key={article.pageId} article={article} />\n ))}\n </div>\n );\n}\n\nexport function ConversationThread() {\n const state = getState();\n const ticketId = state.activeTicketId;\n const conversation = state.activeConversation;\n const messagesEndRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!ticketId) return;\n setState({ loading: true });\n fetchConversation(ticketId)\n .then((conv) => setState({ activeConversation: conv, loading: false }))\n .catch(() => setState({ loading: false }));\n }, [ticketId]);\n\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, [conversation?.messages.length]);\n\n if (!ticketId) return null;\n\n if (state.loading || !conversation) {\n return <div class=\"sr-loading\">Loading...</div>;\n }\n\n return (\n <div class=\"sr-thread\">\n <div class=\"sr-thread-messages\">\n <div class=\"sr-message-row sr-message-row-user\">\n <div\n class=\"sr-message sr-prose\"\n dangerouslySetInnerHTML={{\n __html: renderMarkdown(conversation.ticket.description),\n }}\n />\n <MessageAttachments messageId={null} />\n <div class=\"sr-message-meta\">\n <span class=\"sr-message-sender\">You</span>\n <span>·</span>\n <span>{formatTime(conversation.ticket.createdAt)}</span>\n </div>\n </div>\n {conversation.ticket.suggestedArticles &&\n conversation.ticket.suggestedArticles.length > 0 && (\n <SuggestedArticles\n articles={conversation.ticket.suggestedArticles}\n />\n )}\n {conversation.messages.map((msg) => (\n <Message key={msg.id} msg={msg} />\n ))}\n <div ref={messagesEndRef} />\n </div>\n <MessageComposer ticketId={ticketId} />\n </div>\n );\n}\n","/** @jsxImportSource preact */\nimport { toggleOpen } from \"./state.js\";\n\nexport function Launcher({\n position,\n isOpen,\n}: {\n position: \"bottom-right\" | \"bottom-left\";\n isOpen: boolean;\n}) {\n const posClass = position === \"bottom-left\" ? \"left\" : \"right\";\n\n return (\n <button\n class={`sr-launcher ${posClass}`}\n onClick={toggleOpen}\n aria-label={isOpen ? \"Close support\" : \"Open support\"}\n >\n {isOpen ? (\n <svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\" />\n </svg>\n ) : (\n <svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H5.17L4 17.17V4h16v12z\" />\n <path d=\"M7 9h2v2H7zm4 0h2v2h-2zm4 0h2v2h-2z\" />\n </svg>\n )}\n </button>\n );\n}\n","/** @jsxImportSource preact */\nimport { useCallback, useRef, useState } from \"preact/hooks\";\n\nimport scoperat from \"../client.js\";\nimport { createTicket, uploadFile } from \"./api.js\";\nimport { openThread } from \"./state.js\";\nimport type { PendingAttachment } from \"./types.js\";\n\nexport function TicketForm() {\n const identity = scoperat._getIdentity();\n const hasIdentity = !!identity.email;\n\n const [subject, setSubject] = useState(\"\");\n const [description, setDescription] = useState(\"\");\n const [email, setEmail] = useState(identity.email ?? \"\");\n const [submitting, setSubmitting] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [success, setSuccess] = useState(false);\n const [ticketId, setTicketId] = useState<string | null>(null);\n const [attachments, setAttachments] = useState<PendingAttachment[]>([]);\n const [uploading, setUploading] = useState(false);\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const handleFileSelect = useCallback(\n async (e: Event) => {\n const input = e.target as HTMLInputElement;\n const files = input.files;\n if (!files) return;\n for (let i = 0; i < files.length && attachments.length + i < 5; i++) {\n setUploading(true);\n try {\n const result = await uploadFile(files[i]!);\n setAttachments((prev) => [...prev, result]);\n } catch {\n setError(\"File upload failed\");\n } finally {\n setUploading(false);\n }\n }\n input.value = \"\";\n },\n [attachments.length],\n );\n\n const removeAttachment = useCallback((storageKey: string) => {\n setAttachments((prev) => prev.filter((a) => a.storageKey !== storageKey));\n }, []);\n\n const handleSubmit = useCallback(\n async (e: Event) => {\n e.preventDefault();\n if (!subject.trim() || !description.trim()) return;\n\n setSubmitting(true);\n setError(null);\n\n try {\n const result = await createTicket({\n subject: subject.trim(),\n description: description.trim(),\n email: email.trim() || undefined,\n attachments: attachments.length ? attachments : undefined,\n });\n setSuccess(true);\n setTicketId(result.id);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Something went wrong\");\n } finally {\n setSubmitting(false);\n }\n },\n [subject, description, email, attachments],\n );\n\n if (success && ticketId) {\n return (\n <div class=\"sr-success\">\n <div class=\"sr-success-icon\">\n <svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\" />\n </svg>\n </div>\n <h4>Message sent</h4>\n <p>We'll get back to you soon.</p>\n <div style={{ marginTop: \"16px\" }}>\n <button\n class=\"sr-btn sr-btn-primary\"\n onClick={() => openThread(ticketId)}\n >\n View conversation\n </button>\n </div>\n </div>\n );\n }\n\n const canSubmit = !!subject.trim() && !!description.trim() && !submitting;\n\n return (\n <form class=\"sr-form\" onSubmit={handleSubmit}>\n <div class=\"sr-field\">\n <label>Subject</label>\n <input\n type=\"text\"\n value={subject}\n onInput={(e) => setSubject((e.target as HTMLInputElement).value)}\n placeholder=\"Brief summary\"\n maxLength={500}\n required\n />\n </div>\n\n <div class=\"sr-field sr-field-grow\">\n <label>Description</label>\n <div class=\"sr-textarea-wrap\">\n <textarea\n value={description}\n onInput={(e) =>\n setDescription((e.target as HTMLTextAreaElement).value)\n }\n placeholder=\"Describe the issue or request...\"\n maxLength={10000}\n required\n />\n <button\n type=\"button\"\n class=\"sr-attach-btn sr-attach-btn-left\"\n onClick={() => fileInputRef.current?.click()}\n aria-label=\"Attach file\"\n disabled={attachments.length >= 5}\n >\n <svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M21.44 11.05l-9.19 9.19a6 6 0 01-8.49-8.49l9.19-9.19a4 4 0 015.66 5.66l-9.2 9.19a2 2 0 01-2.83-2.83l8.49-8.48\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n <button\n type=\"submit\"\n class=\"sr-send-btn sr-send-btn-abs\"\n disabled={!canSubmit}\n aria-label=\"Send\"\n >\n <svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z\" />\n </svg>\n </button>\n </div>\n <input\n ref={fileInputRef}\n type=\"file\"\n multiple\n style={{ display: \"none\" }}\n onChange={handleFileSelect}\n />\n </div>\n\n {(attachments.length > 0 || uploading) && (\n <div class=\"sr-attachment-pills\">\n {attachments.map((att) => (\n <div key={att.storageKey} class=\"sr-attachment-pill\">\n <svg\n class=\"sr-attachment-pill-icon\"\n viewBox=\"0 0 24 24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M21.44 11.05l-9.19 9.19a6 6 0 01-8.49-8.49l9.19-9.19a4 4 0 015.66 5.66l-9.2 9.19a2 2 0 01-2.83-2.83l8.49-8.48\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n <span class=\"sr-attachment-pill-name\">{att.fileName}</span>\n <button\n type=\"button\"\n class=\"sr-attachment-pill-remove\"\n onClick={() => removeAttachment(att.storageKey)}\n aria-label=\"Remove\"\n >\n <svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M18 6L6 18M6 6l12 12\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n </div>\n ))}\n {uploading && (\n <div class=\"sr-attachment-pill\">\n <span class=\"sr-attachment-pill-name\">Uploading...</span>\n </div>\n )}\n </div>\n )}\n\n {!hasIdentity && (\n <div class=\"sr-field\">\n <label>Email</label>\n <input\n type=\"email\"\n value={email}\n onInput={(e) => setEmail((e.target as HTMLInputElement).value)}\n placeholder=\"your@email.com\"\n />\n </div>\n )}\n\n {error && <div class=\"sr-error\">{error}</div>}\n </form>\n );\n}\n"],"mappings":"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","names":["useEffect","useState","getBreadcrumbs","state","useEffect","jsx","jsxs","state","useEffect","jsx","jsxs","useCallback","useRef","useState","jsx","jsxs","useState","useRef","useCallback","jsx","jsxs","useState","useEffect","state"]}
|