@triagly/sdk 0.1.1-beta.1 → 0.1.1-beta.2

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,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAKtD,qBAAa,OAAO;IAClB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,aAAa,CAA8B;gBAEvC,MAAM,EAAE,aAAa;IAmDjC;;OAEG;IACH,OAAO,CAAC,IAAI;IAWZ;;OAEG;YACW,YAAY;IAgE1B;;OAEG;IACH,IAAI,IAAI,IAAI;IAIZ;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;;OAGG;IACG,MAAM,CAAC,IAAI,EAAE,YAAY,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBxE;;OAEG;IACH,OAAO,IAAI,IAAI;CAKhB;AAGD,cAAc,SAAS,CAAC;AAWxB,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAKtD,qBAAa,OAAO;IAClB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,aAAa,CAA8B;gBAEvC,MAAM,EAAE,aAAa;IAqDjC;;OAEG;IACH,OAAO,CAAC,IAAI;IAWZ;;OAEG;YACW,YAAY;IAgE1B;;OAEG;IACH,IAAI,IAAI,IAAI;IAIZ;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;;OAGG;IACG,MAAM,CAAC,IAAI,EAAE,YAAY,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBxE;;OAEG;IACH,OAAO,IAAI,IAAI;CAKhB;AAGD,cAAc,SAAS,CAAC;AAexB,eAAe,OAAO,CAAC"}
package/dist/index.esm.js CHANGED
@@ -1190,15 +1190,15 @@ class ConsoleLogger {
1190
1190
  class Triagly {
1191
1191
  constructor(config) {
1192
1192
  this.consoleLogger = null;
1193
- // Handle backward compatibility
1194
- let publishableKey = config.publishableKey;
1195
- if (!publishableKey && config.projectId) {
1196
- console.warn('Triagly: projectId is deprecated. Please use publishableKey instead. ' +
1193
+ // Handle backward compatibility - support multiple key names
1194
+ let apiKey = config.apiKey || config.publishableKey;
1195
+ if (!apiKey && config.projectId) {
1196
+ console.warn('Triagly: projectId is deprecated. Please use apiKey instead. ' +
1197
1197
  'See migration guide: https://docs.triagly.com/sdk/migration');
1198
- publishableKey = config.projectId;
1198
+ apiKey = config.projectId;
1199
1199
  }
1200
- if (!publishableKey) {
1201
- throw new Error('Triagly: publishableKey is required. Get yours at https://triagly.com/dashboard');
1200
+ if (!apiKey) {
1201
+ throw new Error('Triagly: apiKey is required. Get yours at https://triagly.com/dashboard');
1202
1202
  }
1203
1203
  this.config = {
1204
1204
  theme: 'auto',
@@ -1212,11 +1212,12 @@ class Triagly {
1212
1212
  consoleLogLimit: 50,
1213
1213
  consoleLogLevels: ['error', 'warn'],
1214
1214
  ...config,
1215
- publishableKey,
1215
+ apiKey,
1216
+ publishableKey: apiKey, // Keep for backward compatibility
1216
1217
  };
1217
- this.api = new TriaglyAPI(this.config.publishableKey, this.config.apiUrl, this.config.getToken, this.config.turnstileSiteKey);
1218
+ this.api = new TriaglyAPI(apiKey, this.config.apiUrl, this.config.getToken, this.config.turnstileSiteKey);
1218
1219
  this.widget = new FeedbackWidget(this.config);
1219
- this.rateLimiter = new RateLimiter(this.config.publishableKey, 3, 5 * 60 * 1000);
1220
+ this.rateLimiter = new RateLimiter(apiKey, 3, 5 * 60 * 1000);
1220
1221
  // Initialize console logger if enabled
1221
1222
  if (this.config.captureConsole !== false) {
1222
1223
  this.consoleLogger = new ConsoleLogger(this.config.consoleLogLimit, this.config.consoleLogLevels);
@@ -1334,6 +1335,9 @@ if (typeof window !== 'undefined') {
1334
1335
  if (globalConfig) {
1335
1336
  window.triagly = new Triagly(globalConfig);
1336
1337
  }
1338
+ // Make Triagly class directly accessible as window.Triagly for UMD builds
1339
+ // This allows users to use: new Triagly({...}) instead of new Triagly.default({...})
1340
+ window.Triagly = Triagly;
1337
1341
  }
1338
1342
 
1339
1343
  export { Triagly, Triagly as default };
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/ui.ts","../src/api.ts","../src/utils.ts","../src/index.ts"],"sourcesContent":["// Feedback Widget UI\n\nimport { TriaglyConfig } from './types';\n\nexport class FeedbackWidget {\n private config: TriaglyConfig;\n private container: HTMLElement | null = null;\n private isOpen: boolean = false;\n private previouslyFocusedElement: HTMLElement | null = null;\n private focusableElements: HTMLElement[] = [];\n\n constructor(config: TriaglyConfig) {\n this.config = config;\n }\n\n /**\n * Initialize the widget\n */\n init(): void {\n this.createButton();\n this.injectStyles();\n }\n\n /**\n * Create the feedback button\n */\n private createButton(): void {\n const button = document.createElement('button');\n button.id = 'triagly-button';\n button.className = 'triagly-button';\n \n // Button shape\n const shape = this.config.buttonShape || 'rounded';\n button.classList.add(`triagly-shape-${shape}`);\n \n // Button orientation\n const orientation = this.config.orientation || 'horizontal';\n button.classList.add(`triagly-orientation-${orientation}`);\n \n // Handle button text based on shape\n const fullText = this.config.buttonText || '🐛 Feedback';\n if (shape === 'circular') {\n button.innerHTML = '🐛';\n button.setAttribute('aria-label', fullText);\n } else if (shape === 'expandable') {\n // Expandable starts with emoji, expands to full text on hover\n button.innerHTML = '<span class=\"triagly-btn-icon\">🐛</span><span class=\"triagly-btn-text\"> Feedback</span>';\n button.setAttribute('aria-label', fullText);\n // Store custom text if provided\n if (this.config.buttonText) {\n const textSpan = button.querySelector('.triagly-btn-text');\n if (textSpan) {\n textSpan.textContent = ' ' + this.config.buttonText.replace('🐛', '').trim();\n }\n }\n } else {\n button.innerHTML = fullText;\n }\n \n button.onclick = () => this.toggle();\n\n // Position button\n const position = this.config.position || 'bottom-right';\n button.classList.add(`triagly-${position}`);\n\n // For expandable buttons, set expansion direction based on position\n if (shape === 'expandable') {\n if (position.includes('right')) {\n button.classList.add('triagly-expand-left');\n } else if (position.includes('left')) {\n button.classList.add('triagly-expand-right');\n }\n }\n\n // Apply custom offsets if provided\n if (this.config.offsetX) {\n if (position.includes('right')) {\n button.style.right = this.config.offsetX;\n } else if (position.includes('left')) {\n button.style.left = this.config.offsetX;\n }\n }\n if (this.config.offsetY) {\n if (position.includes('top')) {\n button.style.top = this.config.offsetY;\n } else if (position.includes('bottom')) {\n button.style.bottom = this.config.offsetY;\n }\n }\n\n document.body.appendChild(button);\n }\n\n /**\n * Toggle widget visibility\n */\n toggle(): void {\n if (this.isOpen) {\n this.close();\n } else {\n this.open();\n }\n }\n\n /**\n * Open the widget\n */\n open(): void {\n if (this.isOpen) return;\n\n // Store currently focused element to restore later\n this.previouslyFocusedElement = document.activeElement as HTMLElement;\n\n this.container = this.createContainer();\n document.body.appendChild(this.container);\n this.isOpen = true;\n\n // Call onOpen callback\n if (this.config.onOpen) {\n this.config.onOpen();\n }\n\n // Set up keyboard and focus after DOM is ready\n setTimeout(() => {\n // Set up keyboard event listener\n this.setupKeyboardEvents();\n\n // Set up focus trap\n this.setupFocusTrap();\n\n // Focus on title field\n const titleInput = this.container?.querySelector('input[type=\"text\"]') as HTMLInputElement;\n titleInput?.focus();\n }, 0);\n }\n\n /**\n * Close the widget\n */\n close(reason?: 'cancel' | 'dismiss' | 'overlay' | 'programmatic'): void {\n if (!this.isOpen || !this.container) return;\n\n // Clean up tab handler (must match capture phase used when adding)\n const tabHandler = (this.container as any)._tabHandler;\n if (tabHandler) {\n document.removeEventListener('keydown', tabHandler, true);\n }\n\n this.container.remove();\n this.container = null;\n this.isOpen = false;\n\n // Restore focus to previously focused element\n if (this.previouslyFocusedElement) {\n this.previouslyFocusedElement.focus();\n this.previouslyFocusedElement = null;\n }\n\n // Call specific callbacks based on reason\n if (reason === 'cancel' && this.config.onCancel) {\n this.config.onCancel();\n } else if (reason === 'dismiss' && this.config.onDismiss) {\n this.config.onDismiss();\n } else if (reason === 'overlay' && this.config.onOverlayClick) {\n this.config.onOverlayClick();\n }\n\n // Always call general onClose callback (backward compatible)\n if (this.config.onClose) {\n this.config.onClose();\n }\n }\n\n /**\n * Create the widget container\n */\n private createContainer(): HTMLElement {\n const overlay = document.createElement('div');\n overlay.className = 'triagly-overlay';\n overlay.setAttribute('role', 'dialog');\n overlay.setAttribute('aria-modal', 'true');\n overlay.setAttribute('aria-labelledby', 'triagly-modal-title');\n overlay.onclick = (e) => {\n if (e.target === overlay) this.close('overlay');\n };\n\n const modal = document.createElement('div');\n modal.className = 'triagly-modal';\n modal.setAttribute('role', 'document');\n\n const header = document.createElement('div');\n header.className = 'triagly-header';\n header.innerHTML = `\n <h3 id=\"triagly-modal-title\">Send Feedback</h3>\n <button type=\"button\" class=\"triagly-close\" aria-label=\"Close feedback form\">×</button>\n `;\n\n const closeBtn = header.querySelector('.triagly-close');\n closeBtn?.addEventListener('click', () => this.close('dismiss'));\n\n const form = document.createElement('form');\n form.className = 'triagly-form';\n form.innerHTML = `\n <div class=\"triagly-field\">\n <label for=\"triagly-title\">Title (optional)</label>\n <input\n type=\"text\"\n id=\"triagly-title\"\n placeholder=\"Brief summary of your feedback\"\n />\n </div>\n\n <div class=\"triagly-field\">\n <label for=\"triagly-description\">Description *</label>\n <textarea\n id=\"triagly-description\"\n required\n rows=\"5\"\n placeholder=\"${this.config.placeholderText || 'Describe what happened...'}\"\n ></textarea>\n </div>\n\n <div class=\"triagly-field\">\n <label for=\"triagly-email\">Email (optional)</label>\n <input\n type=\"email\"\n id=\"triagly-email\"\n placeholder=\"your@email.com\"\n />\n </div>\n\n <div class=\"triagly-field triagly-checkbox\">\n <label>\n <input type=\"checkbox\" id=\"triagly-screenshot\" checked />\n <span>Include screenshot</span>\n </label>\n </div>\n\n ${this.config.turnstileSiteKey ? `\n <div class=\"triagly-field triagly-turnstile\">\n <div class=\"cf-turnstile\" data-sitekey=\"${this.config.turnstileSiteKey}\" data-theme=\"light\"></div>\n </div>\n ` : ''}\n\n <div class=\"triagly-actions\">\n <button type=\"button\" class=\"triagly-btn-secondary\" id=\"triagly-cancel\" aria-label=\"Cancel and close feedback form\">\n Cancel\n </button>\n <button type=\"submit\" class=\"triagly-btn-primary\" aria-label=\"Submit feedback\">\n Send Feedback\n </button>\n </div>\n\n <div class=\"triagly-status\" id=\"triagly-status\" role=\"status\" aria-live=\"polite\"></div>\n `;\n\n const cancelBtn = form.querySelector('#triagly-cancel');\n cancelBtn?.addEventListener('click', () => this.close('cancel'));\n\n form.onsubmit = (e) => {\n e.preventDefault();\n this.handleSubmit(form);\n };\n\n modal.appendChild(header);\n modal.appendChild(form);\n overlay.appendChild(modal);\n\n // Render Turnstile widget if available\n if (this.config.turnstileSiteKey) {\n setTimeout(() => {\n this.renderTurnstileWidget(form);\n }, 100);\n }\n\n return overlay;\n }\n\n /**\n * Render Cloudflare Turnstile widget\n */\n private renderTurnstileWidget(form: HTMLFormElement): void {\n const turnstileContainer = form.querySelector('.cf-turnstile');\n if (!turnstileContainer) return;\n\n // Check if Turnstile script is loaded\n if (!(window as any).turnstile) {\n console.warn('Triagly: Turnstile script not loaded. Please include: <script src=\"https://challenges.cloudflare.com/turnstile/v0/api.js\" async defer></script>');\n return;\n }\n\n try {\n const widgetId = (window as any).turnstile.render(turnstileContainer, {\n sitekey: this.config.turnstileSiteKey,\n theme: this.config.theme === 'dark' ? 'dark' : 'light',\n callback: (token: string) => {\n // Store token in a data attribute for easy retrieval\n turnstileContainer.setAttribute('data-turnstile-response', token);\n turnstileContainer.setAttribute('data-widget-id', widgetId);\n },\n 'error-callback': () => {\n console.error('Triagly: Turnstile widget error');\n },\n 'expired-callback': () => {\n // Clear stored token when it expires\n turnstileContainer.removeAttribute('data-turnstile-response');\n },\n });\n\n turnstileContainer.setAttribute('data-widget-id', widgetId);\n } catch (error) {\n console.error('Triagly: Failed to render Turnstile widget:', error);\n }\n }\n\n /**\n * Handle form submission\n */\n private async handleSubmit(form: HTMLFormElement): Promise<void> {\n const titleInput = form.querySelector('#triagly-title') as HTMLInputElement;\n const descInput = form.querySelector('#triagly-description') as HTMLTextAreaElement;\n const emailInput = form.querySelector('#triagly-email') as HTMLInputElement;\n const screenshotCheckbox = form.querySelector('#triagly-screenshot') as HTMLInputElement;\n const statusDiv = form.querySelector('#triagly-status') as HTMLDivElement;\n const submitBtn = form.querySelector('button[type=\"submit\"]') as HTMLButtonElement;\n const turnstileContainer = form.querySelector('.cf-turnstile');\n\n // Disable form\n submitBtn.disabled = true;\n submitBtn.textContent = 'Sending...';\n\n try {\n // Get Turnstile token if widget is present\n let turnstileToken: string | undefined;\n if (turnstileContainer) {\n turnstileToken = turnstileContainer.getAttribute('data-turnstile-response') || undefined;\n }\n\n const data = {\n title: titleInput.value.trim() || undefined,\n description: descInput.value.trim(),\n reporterEmail: emailInput.value.trim() || undefined,\n includeScreenshot: screenshotCheckbox.checked,\n turnstileToken,\n };\n\n // Create a promise that waits for actual submission result\n const submissionPromise = new Promise<void>((resolve, reject) => {\n const handleSuccess = () => {\n document.removeEventListener('triagly:success', handleSuccess);\n document.removeEventListener('triagly:error', handleError);\n resolve();\n };\n\n const handleError = (e: Event) => {\n document.removeEventListener('triagly:success', handleSuccess);\n document.removeEventListener('triagly:error', handleError);\n reject((e as CustomEvent).detail);\n };\n\n document.addEventListener('triagly:success', handleSuccess, { once: true });\n document.addEventListener('triagly:error', handleError, { once: true });\n\n // Set a timeout in case events don't fire\n setTimeout(() => {\n document.removeEventListener('triagly:success', handleSuccess);\n document.removeEventListener('triagly:error', handleError);\n reject(new Error('Submission timeout'));\n }, 30000); // 30 second timeout\n });\n\n // Dispatch custom event for parent to handle\n const event = new CustomEvent('triagly:submit', {\n detail: data,\n bubbles: true,\n });\n document.dispatchEvent(event);\n\n // Wait for actual submission result\n await submissionPromise;\n\n // Show success\n statusDiv.className = 'triagly-status triagly-success';\n statusDiv.textContent = this.config.successMessage || 'Feedback sent successfully!';\n\n // Close after delay\n setTimeout(() => {\n this.close();\n }, 2000);\n } catch (error) {\n // Show error with actual error message\n statusDiv.className = 'triagly-status triagly-error';\n const errorMessage = error instanceof Error ? error.message :\n (this.config.errorMessage || 'Failed to send feedback. Please try again.');\n statusDiv.textContent = errorMessage;\n\n // Re-enable form\n submitBtn.disabled = false;\n submitBtn.textContent = 'Send Feedback';\n }\n }\n\n /**\n * Inject widget styles\n */\n private injectStyles(): void {\n if (document.getElementById('triagly-styles')) return;\n\n const style = document.createElement('style');\n style.id = 'triagly-styles';\n style.textContent = `\n .triagly-button {\n position: fixed;\n z-index: 999999;\n padding: 12px 20px;\n background: var(--triagly-button-bg, #6366f1);\n color: var(--triagly-button-text, #ffffff);\n border: none;\n border-radius: var(--triagly-button-radius, 8px);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n box-shadow: var(--triagly-button-shadow, 0 4px 12px rgba(99, 102, 241, 0.3));\n transition: all 0.2s;\n }\n\n .triagly-button:hover {\n background: var(--triagly-button-bg-hover, #4f46e5);\n transform: translateY(-2px);\n box-shadow: var(--triagly-button-shadow-hover, 0 6px 16px rgba(99, 102, 241, 0.4));\n }\n\n /* Prevent expandable buttons from shifting on hover */\n .triagly-button.triagly-shape-expandable:hover {\n transform: translateY(0) !important;\n }\n\n .triagly-bottom-right { bottom: 20px; right: 20px; }\n .triagly-bottom-left { bottom: 20px; left: 20px; }\n .triagly-top-right { top: 20px; right: 20px; }\n .triagly-top-left { top: 20px; left: 20px; }\n\n /* Edge-aligned positions (0 offset from edges) */\n .triagly-edge-bottom-right { bottom: 0; right: 0; }\n .triagly-edge-bottom-left { bottom: 0; left: 0; }\n .triagly-edge-top-right { top: 0; right: 0; }\n .triagly-edge-top-left { top: 0; left: 0; }\n .triagly-edge-right { top: 50%; right: 0; transform: translateY(-50%); }\n .triagly-edge-left { top: 50%; left: 0; transform: translateY(-50%); }\n .triagly-edge-top { top: 0; left: 50%; transform: translateX(-50%); }\n .triagly-edge-bottom { bottom: 0; left: 50%; transform: translateX(-50%); }\n\n /* Button shapes */\n .triagly-shape-rounded {\n border-radius: var(--triagly-button-radius, 8px);\n }\n .triagly-shape-circular {\n border-radius: 50%;\n width: 60px;\n height: 60px;\n padding: 0;\n font-size: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .triagly-shape-square {\n border-radius: 0;\n }\n .triagly-shape-pill {\n border-radius: 30px;\n }\n .triagly-shape-expandable {\n border-radius: 50%;\n width: 60px;\n height: 60px;\n min-width: 60px;\n padding: 0;\n font-size: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1),\n border-radius 0.3s cubic-bezier(0.4, 0, 0.2, 1),\n padding 0.3s cubic-bezier(0.4, 0, 0.2, 1),\n background 0.2s,\n box-shadow 0.2s;\n white-space: nowrap;\n }\n \n /* Expansion direction - expands left for right-positioned buttons */\n .triagly-shape-expandable.triagly-expand-left {\n flex-direction: row-reverse;\n }\n \n /* Expansion direction - expands right for left-positioned buttons */\n .triagly-shape-expandable.triagly-expand-right {\n flex-direction: row;\n }\n \n .triagly-shape-expandable .triagly-btn-icon {\n display: inline-block;\n flex-shrink: 0;\n transition: margin 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n }\n .triagly-shape-expandable .triagly-btn-text {\n display: inline-block;\n width: 0;\n opacity: 0;\n overflow: hidden;\n font-size: 14px;\n font-weight: 500;\n transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1),\n opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n }\n \n /* Hover state */\n .triagly-shape-expandable:hover {\n width: auto;\n min-width: auto;\n padding: 12px 20px;\n border-radius: 30px;\n background: var(--triagly-button-bg-hover, #4f46e5);\n box-shadow: var(--triagly-button-shadow-hover, 0 6px 16px rgba(99, 102, 241, 0.4));\n }\n .triagly-shape-expandable:hover .triagly-btn-text {\n width: auto;\n opacity: 1;\n }\n\n /* Button orientations */\n .triagly-orientation-horizontal {\n writing-mode: horizontal-tb;\n }\n .triagly-orientation-vertical {\n writing-mode: vertical-rl;\n text-orientation: mixed;\n }\n\n .triagly-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--triagly-overlay-bg, rgba(0, 0, 0, 0.5));\n z-index: 1000000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: triagly-fadeIn 0.2s;\n }\n\n @keyframes triagly-fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n\n .triagly-modal {\n background: var(--triagly-modal-bg, #ffffff);\n border-radius: var(--triagly-modal-radius, 12px);\n width: 90%;\n max-width: var(--triagly-modal-max-width, 500px);\n max-height: 90vh;\n overflow-y: auto;\n box-shadow: var(--triagly-modal-shadow, 0 20px 60px rgba(0, 0, 0, 0.3));\n animation: triagly-slideUp 0.3s;\n }\n\n @keyframes triagly-slideUp {\n from {\n opacity: 0;\n transform: translateY(20px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n\n .triagly-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 20px 24px;\n background: var(--triagly-header-bg, #ffffff);\n border-bottom: 1px solid var(--triagly-header-border, #e5e7eb);\n }\n\n .triagly-header h3 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--triagly-header-text, #111827);\n }\n\n .triagly-close {\n background: none;\n border: none;\n font-size: 28px;\n color: #6b7280;\n cursor: pointer;\n padding: 0;\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 6px;\n transition: all 0.2s;\n }\n\n .triagly-close:hover {\n background: #f3f4f6;\n color: #111827;\n }\n\n .triagly-form {\n padding: 24px;\n background: var(--triagly-form-bg, #ffffff);\n }\n\n .triagly-field {\n margin-bottom: 16px;\n }\n\n .triagly-field label {\n display: block;\n margin-bottom: 6px;\n font-size: 14px;\n font-weight: 500;\n color: var(--triagly-label-text, #374151);\n }\n\n .triagly-field input,\n .triagly-field textarea {\n width: 100%;\n padding: 10px 12px;\n background: var(--triagly-input-bg, #ffffff);\n border: 1px solid var(--triagly-input-border, #d1d5db);\n border-radius: var(--triagly-input-radius, 6px);\n color: var(--triagly-input-text, #111827);\n font-size: 14px;\n font-family: inherit;\n transition: border-color 0.2s;\n box-sizing: border-box;\n }\n\n .triagly-field input:focus,\n .triagly-field textarea:focus {\n outline: none;\n border-color: var(--triagly-input-border-focus, #6366f1);\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);\n }\n\n .triagly-checkbox label {\n display: flex;\n align-items: center;\n gap: 8px;\n cursor: pointer;\n font-weight: 400;\n }\n\n .triagly-checkbox label span {\n user-select: none;\n }\n\n .triagly-checkbox input {\n width: 16px;\n height: 16px;\n margin: 0;\n cursor: pointer;\n }\n\n /* Focus visible styles for accessibility */\n .triagly-button:focus-visible,\n .triagly-field input:focus-visible,\n .triagly-field textarea:focus-visible,\n .triagly-checkbox input:focus-visible,\n .triagly-btn-primary:focus-visible,\n .triagly-btn-secondary:focus-visible,\n .triagly-close:focus-visible {\n outline: 2px solid #6366f1;\n outline-offset: 2px;\n }\n\n /* Checkbox label gets visual indicator when checkbox is focused */\n .triagly-checkbox input:focus-visible + span {\n text-decoration: underline;\n }\n\n .triagly-turnstile {\n display: flex;\n justify-content: center;\n margin: 8px 0;\n }\n\n .triagly-actions {\n display: flex;\n gap: 12px;\n margin-top: 24px;\n }\n\n .triagly-btn-primary,\n .triagly-btn-secondary {\n flex: 1;\n padding: 10px 16px;\n border-radius: var(--triagly-btn-radius, 6px);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s;\n border: none;\n }\n\n .triagly-btn-primary {\n background: var(--triagly-btn-primary-bg, #6366f1);\n color: var(--triagly-btn-primary-text, #ffffff);\n }\n\n .triagly-btn-primary:hover:not(:disabled) {\n background: var(--triagly-btn-primary-bg-hover, #4f46e5);\n }\n\n .triagly-btn-primary:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .triagly-btn-secondary {\n background: var(--triagly-btn-secondary-bg, #f3f4f6);\n color: var(--triagly-btn-secondary-text, #374151);\n }\n\n .triagly-btn-secondary:hover {\n background: var(--triagly-btn-secondary-bg-hover, #e5e7eb);\n }\n\n .triagly-status {\n margin-top: 16px;\n padding: 12px;\n border-radius: 6px;\n font-size: 14px;\n display: none;\n }\n\n .triagly-status.triagly-success {\n display: block;\n background: var(--triagly-success-bg, #d1fae5);\n color: var(--triagly-success-text, #065f46);\n }\n\n .triagly-status.triagly-error {\n display: block;\n background: var(--triagly-error-bg, #fee2e2);\n color: var(--triagly-error-text, #991b1b);\n }\n `;\n\n document.head.appendChild(style);\n }\n\n /**\n * Set up keyboard event handlers\n */\n private setupKeyboardEvents(): void {\n const handleKeyDown = (e: KeyboardEvent) => {\n // Close on Escape key\n if (e.key === 'Escape' && this.isOpen) {\n e.preventDefault();\n this.close('dismiss');\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n \n // Store handler for cleanup\n if (this.container) {\n (this.container as any)._keydownHandler = handleKeyDown;\n }\n }\n\n /**\n * Set up focus trap to keep focus within modal\n */\n private setupFocusTrap(): void {\n if (!this.container) return;\n\n // Get all focusable elements\n const modal = this.container.querySelector('.triagly-modal');\n if (!modal) return;\n\n const focusableSelector =\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])';\n this.focusableElements = Array.from(\n modal.querySelectorAll(focusableSelector)\n ) as HTMLElement[];\n\n if (this.focusableElements.length === 0) {\n console.warn('Triagly: No focusable elements found in modal');\n return;\n }\n\n // Handle Tab key to trap focus - must prevent default BEFORE focus moves\n const handleTab = (e: Event) => {\n const keyEvent = e as KeyboardEvent;\n if (keyEvent.key !== 'Tab') return;\n\n // Only handle if focus is within our modal\n if (!this.container?.contains(document.activeElement)) return;\n\n const firstFocusable = this.focusableElements[0];\n const lastFocusable = this.focusableElements[this.focusableElements.length - 1];\n\n if (keyEvent.shiftKey) {\n // Shift + Tab - moving backwards\n if (document.activeElement === firstFocusable) {\n keyEvent.preventDefault();\n lastFocusable?.focus();\n }\n } else {\n // Tab - moving forwards\n if (document.activeElement === lastFocusable) {\n keyEvent.preventDefault();\n firstFocusable?.focus();\n }\n }\n };\n\n // Use capture phase to intercept Tab before browser handles it\n document.addEventListener('keydown', handleTab as EventListener, true);\n (this.container as any)._tabHandler = handleTab;\n }\n\n /**\n * Destroy the widget\n */\n destroy(): void {\n // Clean up event listeners\n if (this.container) {\n const keydownHandler = (this.container as any)._keydownHandler;\n if (keydownHandler) {\n document.removeEventListener('keydown', keydownHandler);\n }\n\n const tabHandler = (this.container as any)._tabHandler;\n if (tabHandler) {\n document.removeEventListener('keydown', tabHandler, true);\n }\n }\n\n this.close();\n document.getElementById('triagly-button')?.remove();\n document.getElementById('triagly-styles')?.remove();\n }\n}\n","// API Client\n\nimport {\n FeedbackData,\n FeedbackMetadata,\n FeedbackResponse,\n} from './types';\n\nconst DEFAULT_API_URL = 'https://sypkjlwfyvyuqnvzkaxb.supabase.co/functions/v1';\n\nexport class TriaglyAPI {\n private apiUrl: string;\n private publishableKey: string;\n private getToken?: () => Promise<string>;\n private turnstileSiteKey?: string;\n\n constructor(\n publishableKey: string,\n apiUrl?: string,\n getToken?: () => Promise<string>,\n turnstileSiteKey?: string\n ) {\n this.apiUrl = (apiUrl || DEFAULT_API_URL).replace(/\\/$/, ''); // Remove trailing slash\n this.publishableKey = publishableKey;\n this.getToken = getToken;\n this.turnstileSiteKey = turnstileSiteKey;\n }\n\n /**\n * Get Turnstile token from widget if available\n */\n private async getTurnstileToken(): Promise<string | null> {\n // Check if Turnstile widget is available\n const turnstileWidget = document.querySelector('[data-turnstile-response]');\n if (turnstileWidget) {\n const token = turnstileWidget.getAttribute('data-turnstile-response');\n if (token) return token;\n }\n\n // Check if window.turnstile is available\n if ((window as any).turnstile) {\n try {\n // Get the first widget's response\n const widgets = document.querySelectorAll('.cf-turnstile');\n if (widgets.length > 0) {\n const widgetId = widgets[0].getAttribute('data-widget-id');\n if (widgetId) {\n const token = (window as any).turnstile.getResponse(widgetId);\n if (token) return token;\n }\n }\n } catch (error) {\n console.warn('Failed to get Turnstile token:', error);\n }\n }\n\n return null;\n }\n\n /**\n * Submit feedback with new authentication\n */\n async submitFeedback(\n data: FeedbackData,\n metadata: FeedbackMetadata,\n turnstileToken?: string\n ): Promise<FeedbackResponse> {\n // Get Turnstile token if not provided\n if (!turnstileToken) {\n turnstileToken = await this.getTurnstileToken() || undefined;\n }\n\n // Only require Turnstile if configured\n if (this.turnstileSiteKey && !turnstileToken) {\n throw new Error('Turnstile verification required. Please complete the captcha.');\n }\n\n // Get hardened token if callback is provided\n let hardenedToken: string | undefined;\n if (this.getToken) {\n try {\n hardenedToken = await this.getToken();\n } catch (error) {\n console.error('Failed to get hardened token:', error);\n throw new Error('Failed to authenticate. Please try again.');\n }\n }\n\n const payload = {\n publishableKey: this.publishableKey,\n title: data.title,\n description: data.description,\n metadata: {\n ...metadata,\n consoleLogs: data.consoleLogs,\n },\n tags: data.tags,\n screenshot: data.screenshot,\n reporterEmail: data.reporterEmail,\n reporterName: data.reporterName,\n turnstileToken,\n hardenedToken,\n };\n\n const response = await fetch(`${this.apiUrl}/feedback`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({ error: 'Unknown error', message: 'Unknown error' }));\n\n // Handle specific error types with user-friendly messages\n if (response.status === 401) {\n if (error.error === 'invalid_publishable_key') {\n throw new Error('Invalid API key. Please contact support.');\n } else if (error.error === 'token_required') {\n throw new Error('Authentication required. Please refresh and try again.');\n }\n throw new Error(error.message || 'Authentication failed');\n } else if (response.status === 403) {\n if (error.error === 'origin_not_allowed') {\n throw new Error('This website is not authorized to submit feedback.');\n }\n throw new Error(error.message || 'Access denied');\n } else if (response.status === 429) {\n const retryAfter = response.headers.get('Retry-After');\n const resetTime = retryAfter ? `in ${retryAfter} seconds` : 'later';\n throw new Error(`Too many requests. Please try again ${resetTime}.`);\n } else if (response.status === 400 && error.error === 'captcha_failed') {\n throw new Error('Captcha verification failed. Please try again.');\n }\n\n throw new Error(error.message || error.error || `Failed to submit feedback (HTTP ${response.status})`);\n }\n\n return await response.json();\n }\n}\n","// Utility functions\n\nimport { FeedbackMetadata } from './types';\n\n/**\n * Collect browser and page metadata\n */\nexport function collectMetadata(customMetadata?: Record<string, any>): FeedbackMetadata {\n const viewport = `${window.innerWidth}x${window.innerHeight}`;\n const browser = detectBrowser();\n\n return {\n url: window.location.href,\n browser,\n viewport,\n userAgent: navigator.userAgent,\n timestamp: new Date().toISOString(),\n ...customMetadata,\n };\n}\n\n/**\n * Detect browser name and version\n */\nfunction detectBrowser(): string {\n const ua = navigator.userAgent;\n let browser = 'Unknown';\n\n if (ua.includes('Firefox/')) {\n const version = ua.match(/Firefox\\/(\\d+)/)?.[1];\n browser = `Firefox ${version}`;\n } else if (ua.includes('Chrome/') && !ua.includes('Edg')) {\n const version = ua.match(/Chrome\\/(\\d+)/)?.[1];\n browser = `Chrome ${version}`;\n } else if (ua.includes('Safari/') && !ua.includes('Chrome')) {\n const version = ua.match(/Version\\/(\\d+)/)?.[1];\n browser = `Safari ${version}`;\n } else if (ua.includes('Edg/')) {\n const version = ua.match(/Edg\\/(\\d+)/)?.[1];\n browser = `Edge ${version}`;\n }\n\n return browser;\n}\n\n/**\n * Capture screenshot of current page\n */\nexport async function captureScreenshot(): Promise<string | null> {\n try {\n // Use html2canvas library if available\n if (typeof (window as any).html2canvas !== 'undefined') {\n const canvas = await (window as any).html2canvas(document.body, {\n logging: false,\n useCORS: true,\n allowTaint: true,\n });\n return canvas.toDataURL('image/png');\n }\n\n // Fallback to native screenshot API if supported (limited browser support)\n if ('mediaDevices' in navigator && 'getDisplayMedia' in navigator.mediaDevices) {\n // This requires user interaction and shows a permission dialog\n // Not ideal for automatic screenshots\n console.warn('Screenshot capture requires html2canvas library');\n return null;\n }\n\n return null;\n } catch (error) {\n console.error('Screenshot capture failed:', error);\n return null;\n }\n}\n\n/**\n * Simple rate limiter using localStorage\n */\nexport class RateLimiter {\n private key: string;\n private maxAttempts: number;\n private windowMs: number;\n\n constructor(key: string, maxAttempts: number = 3, windowMs: number = 5 * 60 * 1000) {\n this.key = `triagly_ratelimit_${key}`;\n this.maxAttempts = maxAttempts;\n this.windowMs = windowMs;\n }\n\n canProceed(): boolean {\n const now = Date.now();\n const data = this.getData();\n\n // Filter out old attempts\n const recentAttempts = data.attempts.filter(\n (timestamp) => now - timestamp < this.windowMs\n );\n\n if (recentAttempts.length >= this.maxAttempts) {\n return false;\n }\n\n return true;\n }\n\n recordAttempt(): void {\n const now = Date.now();\n const data = this.getData();\n\n // Add new attempt\n data.attempts.push(now);\n\n // Keep only recent attempts\n data.attempts = data.attempts.filter(\n (timestamp) => now - timestamp < this.windowMs\n );\n\n this.setData(data);\n }\n\n getTimeUntilReset(): number {\n const now = Date.now();\n const data = this.getData();\n\n if (data.attempts.length === 0) {\n return 0;\n }\n\n const oldestAttempt = Math.min(...data.attempts);\n const resetTime = oldestAttempt + this.windowMs;\n\n return Math.max(0, resetTime - now);\n }\n\n private getData(): { attempts: number[] } {\n try {\n const stored = localStorage.getItem(this.key);\n return stored ? JSON.parse(stored) : { attempts: [] };\n } catch {\n return { attempts: [] };\n }\n }\n\n private setData(data: { attempts: number[] }): void {\n try {\n localStorage.setItem(this.key, JSON.stringify(data));\n } catch (error) {\n console.error('Failed to store rate limit data:', error);\n }\n }\n}\n\n/**\n * Generate unique ID\n */\nexport function generateId(): string {\n return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n}\n\n/**\n * Console log capture for debugging\n */\nexport interface ConsoleLog {\n level: 'error' | 'warn' | 'log';\n message: string;\n timestamp: string;\n stack?: string;\n}\n\nexport class ConsoleLogger {\n private buffer: ConsoleLog[] = [];\n private maxLogs: number;\n private levels: Set<'error' | 'warn' | 'log'>;\n private originalConsole: {\n error: typeof console.error;\n warn: typeof console.warn;\n log: typeof console.log;\n };\n private isActive: boolean = false;\n\n constructor(maxLogs: number = 50, levels: ('error' | 'warn' | 'log')[] = ['error', 'warn']) {\n this.maxLogs = maxLogs;\n this.levels = new Set(levels);\n \n // Store original console methods\n this.originalConsole = {\n error: console.error,\n warn: console.warn,\n log: console.log,\n };\n }\n\n /**\n * Start capturing console logs\n */\n start(): void {\n if (this.isActive) return;\n this.isActive = true;\n\n // Intercept console.error\n if (this.levels.has('error')) {\n console.error = (...args: any[]) => {\n this.captureLog('error', args);\n this.originalConsole.error.apply(console, args);\n };\n }\n\n // Intercept console.warn\n if (this.levels.has('warn')) {\n console.warn = (...args: any[]) => {\n this.captureLog('warn', args);\n this.originalConsole.warn.apply(console, args);\n };\n }\n\n // Intercept console.log\n if (this.levels.has('log')) {\n console.log = (...args: any[]) => {\n this.captureLog('log', args);\n this.originalConsole.log.apply(console, args);\n };\n }\n }\n\n /**\n * Stop capturing and restore original console methods\n */\n stop(): void {\n if (!this.isActive) return;\n this.isActive = false;\n\n console.error = this.originalConsole.error;\n console.warn = this.originalConsole.warn;\n console.log = this.originalConsole.log;\n }\n\n /**\n * Capture a log entry\n */\n private captureLog(level: 'error' | 'warn' | 'log', args: any[]): void {\n try {\n // Convert arguments to string\n const message = args.map(arg => {\n if (typeof arg === 'string') return arg;\n if (arg instanceof Error) return arg.message;\n try {\n return JSON.stringify(arg);\n } catch {\n return String(arg);\n }\n }).join(' ');\n\n // Get stack trace for errors\n let stack: string | undefined;\n if (level === 'error') {\n const error = args.find(arg => arg instanceof Error);\n if (error) {\n stack = error.stack;\n } else {\n // Create stack trace\n stack = new Error().stack?.split('\\n').slice(2).join('\\n');\n }\n }\n\n // Sanitize sensitive data\n const sanitized = this.sanitize(message);\n const sanitizedStack = stack ? this.sanitize(stack) : undefined;\n\n // Add to buffer\n const logEntry: ConsoleLog = {\n level,\n message: sanitized,\n timestamp: new Date().toISOString(),\n stack: sanitizedStack,\n };\n\n this.buffer.push(logEntry);\n\n // Keep buffer size limited (circular buffer)\n if (this.buffer.length > this.maxLogs) {\n this.buffer.shift();\n }\n } catch (error) {\n // Don't let logging break the app\n this.originalConsole.error('Failed to capture log:', error);\n }\n }\n\n /**\n * Sanitize sensitive data from logs\n */\n private sanitize(text: string): string {\n return text\n // API keys, tokens, secrets\n .replace(/[a-zA-Z0-9_-]*token[a-zA-Z0-9_-]*\\s*[:=]\\s*[\"']?[\\w-]{20,}[\"']?/gi, 'token=***')\n .replace(/[a-zA-Z0-9_-]*key[a-zA-Z0-9_-]*\\s*[:=]\\s*[\"']?[\\w-]{20,}[\"']?/gi, 'key=***')\n .replace(/[a-zA-Z0-9_-]*secret[a-zA-Z0-9_-]*\\s*[:=]\\s*[\"']?[\\w-]{20,}[\"']?/gi, 'secret=***')\n // GitHub tokens (ghp_, gho_, etc.)\n .replace(/gh[ps]_[a-zA-Z0-9]{36,}/g, 'gh*_***')\n // JWT tokens\n .replace(/eyJ[a-zA-Z0-9_-]+\\.[a-zA-Z0-9_-]+\\.[a-zA-Z0-9_-]+/g, 'jwt.***')\n // Passwords\n .replace(/password\\s*[:=]\\s*[\"']?[^\"'\\s]+[\"']?/gi, 'password=***')\n // Email addresses\n .replace(/\\b[\\w._%+-]+@[\\w.-]+\\.[a-zA-Z]{2,}\\b/g, '***@***.com')\n // Credit cards (basic pattern)\n .replace(/\\b\\d{4}[-\\s]?\\d{4}[-\\s]?\\d{4}[-\\s]?\\d{4}\\b/g, '****-****-****-****')\n // URLs with tokens in query params\n .replace(/([?&])(token|key|secret|auth)=[^&\\s]+/gi, '$1$2=***');\n }\n\n /**\n * Get all captured logs\n */\n getLogs(): ConsoleLog[] {\n return [...this.buffer];\n }\n\n /**\n * Clear all captured logs\n */\n clear(): void {\n this.buffer = [];\n }\n\n /**\n * Get logs count\n */\n getCount(): number {\n return this.buffer.length;\n }\n}\n","// Triagly SDK Main Entry Point\n\nimport { TriaglyConfig, FeedbackData } from './types';\nimport { FeedbackWidget } from './ui';\nimport { TriaglyAPI } from './api';\nimport { collectMetadata, captureScreenshot, RateLimiter, ConsoleLogger } from './utils';\n\nexport class Triagly {\n private config: TriaglyConfig;\n private widget: FeedbackWidget;\n private api: TriaglyAPI;\n private rateLimiter: RateLimiter;\n private consoleLogger: ConsoleLogger | null = null;\n\n constructor(config: TriaglyConfig) {\n // Handle backward compatibility\n let publishableKey = config.publishableKey;\n if (!publishableKey && config.projectId) {\n console.warn(\n 'Triagly: projectId is deprecated. Please use publishableKey instead. ' +\n 'See migration guide: https://docs.triagly.com/sdk/migration'\n );\n publishableKey = config.projectId;\n }\n\n if (!publishableKey) {\n throw new Error('Triagly: publishableKey is required. Get yours at https://triagly.com/dashboard');\n }\n\n this.config = {\n theme: 'auto',\n position: 'bottom-right',\n buttonShape: 'rounded',\n buttonText: '🐛 Feedback',\n placeholderText: 'Describe what happened...',\n successMessage: 'Feedback sent successfully!',\n errorMessage: 'Failed to send feedback. Please try again.',\n captureConsole: true,\n consoleLogLimit: 50,\n consoleLogLevels: ['error', 'warn'],\n ...config,\n publishableKey,\n };\n\n this.api = new TriaglyAPI(\n this.config.publishableKey,\n this.config.apiUrl,\n this.config.getToken,\n this.config.turnstileSiteKey\n );\n this.widget = new FeedbackWidget(this.config);\n this.rateLimiter = new RateLimiter(this.config.publishableKey, 3, 5 * 60 * 1000);\n\n // Initialize console logger if enabled\n if (this.config.captureConsole !== false) {\n this.consoleLogger = new ConsoleLogger(\n this.config.consoleLogLimit,\n this.config.consoleLogLevels\n );\n this.consoleLogger.start();\n }\n\n this.init();\n }\n\n /**\n * Initialize the SDK\n */\n private init(): void {\n // Initialize widget\n this.widget.init();\n\n // Listen for form submissions\n document.addEventListener('triagly:submit', (e: Event) => {\n const customEvent = e as CustomEvent;\n this.handleSubmit(customEvent.detail);\n });\n }\n\n /**\n * Handle feedback submission\n */\n private async handleSubmit(data: any): Promise<void> {\n try {\n // Check rate limit\n if (!this.rateLimiter.canProceed()) {\n const resetTime = Math.ceil(this.rateLimiter.getTimeUntilReset() / 1000 / 60);\n throw new Error(`Rate limit exceeded. Please try again in ${resetTime} minute(s).`);\n }\n\n // Collect metadata\n const metadata = collectMetadata(this.config.metadata);\n\n // Capture screenshot if requested\n let screenshot: string | null = null;\n if (data.includeScreenshot) {\n screenshot = await captureScreenshot();\n }\n\n // Prepare feedback data\n const feedbackData: FeedbackData = {\n title: data.title,\n description: data.description,\n reporterEmail: data.reporterEmail,\n screenshot: screenshot || undefined,\n consoleLogs: this.consoleLogger?.getLogs(),\n };\n\n // Submit to API with Turnstile token if provided\n const response = await this.api.submitFeedback(\n feedbackData,\n metadata,\n data.turnstileToken\n );\n\n // Record rate limit attempt\n this.rateLimiter.recordAttempt();\n\n // Dispatch success event for UI layer\n document.dispatchEvent(new CustomEvent('triagly:success', {\n detail: { feedbackId: response.id }\n }));\n\n // Call success callback\n if (this.config.onSuccess) {\n this.config.onSuccess(response.id);\n }\n\n console.log('Feedback submitted successfully:', response.id);\n } catch (error) {\n console.error('Failed to submit feedback:', error);\n\n // Dispatch error event for UI layer\n document.dispatchEvent(new CustomEvent('triagly:error', {\n detail: error\n }));\n\n // Call error callback\n if (this.config.onError && error instanceof Error) {\n this.config.onError(error);\n }\n\n throw error;\n }\n }\n\n /**\n * Programmatically open the feedback widget\n */\n open(): void {\n this.widget.open();\n }\n\n /**\n * Programmatically close the feedback widget\n */\n close(): void {\n this.widget.close();\n }\n\n /**\n * Submit feedback programmatically without UI\n * Note: When Turnstile is enabled, you must use the widget UI or provide a token\n */\n async submit(data: FeedbackData, turnstileToken?: string): Promise<void> {\n // Require Turnstile token if configured\n if (this.config.turnstileSiteKey && !turnstileToken) {\n throw new Error(\n 'Turnstile verification required. When Turnstile is enabled, you must:\\n' +\n '1. Use the widget UI (triagly.open()), or\\n' +\n '2. Implement Turnstile in your form and pass the token: triagly.submit(data, token)'\n );\n }\n\n const metadata = collectMetadata(this.config.metadata);\n\n // Include console logs if available and not already provided\n if (!data.consoleLogs && this.consoleLogger) {\n data.consoleLogs = this.consoleLogger.getLogs();\n }\n\n await this.api.submitFeedback(data, metadata, turnstileToken);\n this.rateLimiter.recordAttempt();\n }\n\n /**\n * Destroy the SDK instance\n */\n destroy(): void {\n this.widget.destroy();\n this.consoleLogger?.stop();\n document.removeEventListener('triagly:submit', () => {});\n }\n}\n\n// Export types\nexport * from './types';\n\n// Auto-initialize if config is in window\nif (typeof window !== 'undefined') {\n const globalConfig = (window as any).TriaglyConfig;\n if (globalConfig) {\n (window as any).triagly = new Triagly(globalConfig);\n }\n}\n\n// Default export\nexport default Triagly;\n"],"names":[],"mappings":"AAAA;MAIa,cAAc,CAAA;AAOzB,IAAA,WAAA,CAAY,MAAqB,EAAA;QALzB,IAAA,CAAA,SAAS,GAAuB,IAAI;QACpC,IAAA,CAAA,MAAM,GAAY,KAAK;QACvB,IAAA,CAAA,wBAAwB,GAAuB,IAAI;QACnD,IAAA,CAAA,iBAAiB,GAAkB,EAAE;AAG3C,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM;IACtB;AAEA;;AAEG;IACH,IAAI,GAAA;QACF,IAAI,CAAC,YAAY,EAAE;QACnB,IAAI,CAAC,YAAY,EAAE;IACrB;AAEA;;AAEG;IACK,YAAY,GAAA;QAClB,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC;AAC/C,QAAA,MAAM,CAAC,EAAE,GAAG,gBAAgB;AAC5B,QAAA,MAAM,CAAC,SAAS,GAAG,gBAAgB;;QAGnC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,SAAS;QAClD,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA,cAAA,EAAiB,KAAK,CAAA,CAAE,CAAC;;QAG9C,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,YAAY;QAC3D,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA,oBAAA,EAAuB,WAAW,CAAA,CAAE,CAAC;;QAG1D,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,aAAa;AACxD,QAAA,IAAI,KAAK,KAAK,UAAU,EAAE;AACxB,YAAA,MAAM,CAAC,SAAS,GAAG,IAAI;AACvB,YAAA,MAAM,CAAC,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC;QAC7C;AAAO,aAAA,IAAI,KAAK,KAAK,YAAY,EAAE;;AAEjC,YAAA,MAAM,CAAC,SAAS,GAAG,yFAAyF;AAC5G,YAAA,MAAM,CAAC,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC;;AAE3C,YAAA,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE;gBAC1B,MAAM,QAAQ,GAAG,MAAM,CAAC,aAAa,CAAC,mBAAmB,CAAC;gBAC1D,IAAI,QAAQ,EAAE;oBACZ,QAAQ,CAAC,WAAW,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE;gBAC9E;YACF;QACF;aAAO;AACL,YAAA,MAAM,CAAC,SAAS,GAAG,QAAQ;QAC7B;QAEA,MAAM,CAAC,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE;;QAGpC,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,cAAc;QACvD,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA,QAAA,EAAW,QAAQ,CAAA,CAAE,CAAC;;AAG3C,QAAA,IAAI,KAAK,KAAK,YAAY,EAAE;AAC1B,YAAA,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE;AAC9B,gBAAA,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,qBAAqB,CAAC;YAC7C;AAAO,iBAAA,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;AACpC,gBAAA,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,sBAAsB,CAAC;YAC9C;QACF;;AAGA,QAAA,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;AACvB,YAAA,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE;gBAC9B,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO;YAC1C;AAAO,iBAAA,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;gBACpC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO;YACzC;QACF;AACA,QAAA,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;AACvB,YAAA,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;gBAC5B,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO;YACxC;AAAO,iBAAA,IAAI,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE;gBACtC,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO;YAC3C;QACF;AAEA,QAAA,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;IACnC;AAEA;;AAEG;IACH,MAAM,GAAA;AACJ,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE;YACf,IAAI,CAAC,KAAK,EAAE;QACd;aAAO;YACL,IAAI,CAAC,IAAI,EAAE;QACb;IACF;AAEA;;AAEG;IACH,IAAI,GAAA;QACF,IAAI,IAAI,CAAC,MAAM;YAAE;;AAGjB,QAAA,IAAI,CAAC,wBAAwB,GAAG,QAAQ,CAAC,aAA4B;AAErE,QAAA,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,eAAe,EAAE;QACvC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC;AACzC,QAAA,IAAI,CAAC,MAAM,GAAG,IAAI;;AAGlB,QAAA,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;AACtB,YAAA,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;QACtB;;QAGA,UAAU,CAAC,MAAK;;YAEd,IAAI,CAAC,mBAAmB,EAAE;;YAG1B,IAAI,CAAC,cAAc,EAAE;;YAGrB,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,oBAAoB,CAAqB;YAC1F,UAAU,EAAE,KAAK,EAAE;QACrB,CAAC,EAAE,CAAC,CAAC;IACP;AAEA;;AAEG;AACH,IAAA,KAAK,CAAC,MAA0D,EAAA;QAC9D,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE;;AAGrC,QAAA,MAAM,UAAU,GAAI,IAAI,CAAC,SAAiB,CAAC,WAAW;QACtD,IAAI,UAAU,EAAE;YACd,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC;QAC3D;AAEA,QAAA,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE;AACvB,QAAA,IAAI,CAAC,SAAS,GAAG,IAAI;AACrB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;;AAGnB,QAAA,IAAI,IAAI,CAAC,wBAAwB,EAAE;AACjC,YAAA,IAAI,CAAC,wBAAwB,CAAC,KAAK,EAAE;AACrC,YAAA,IAAI,CAAC,wBAAwB,GAAG,IAAI;QACtC;;QAGA,IAAI,MAAM,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE;AAC/C,YAAA,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE;QACxB;aAAO,IAAI,MAAM,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE;AACxD,YAAA,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE;QACzB;aAAO,IAAI,MAAM,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE;AAC7D,YAAA,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE;QAC9B;;AAGA,QAAA,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;AACvB,YAAA,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;QACvB;IACF;AAEA;;AAEG;IACK,eAAe,GAAA;QACrB,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC;AAC7C,QAAA,OAAO,CAAC,SAAS,GAAG,iBAAiB;AACrC,QAAA,OAAO,CAAC,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC;AACtC,QAAA,OAAO,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC;AAC1C,QAAA,OAAO,CAAC,YAAY,CAAC,iBAAiB,EAAE,qBAAqB,CAAC;AAC9D,QAAA,OAAO,CAAC,OAAO,GAAG,CAAC,CAAC,KAAI;AACtB,YAAA,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO;AAAE,gBAAA,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;AACjD,QAAA,CAAC;QAED,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC;AAC3C,QAAA,KAAK,CAAC,SAAS,GAAG,eAAe;AACjC,QAAA,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,UAAU,CAAC;QAEtC,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC;AAC5C,QAAA,MAAM,CAAC,SAAS,GAAG,gBAAgB;QACnC,MAAM,CAAC,SAAS,GAAG;;;KAGlB;QAED,MAAM,QAAQ,GAAG,MAAM,CAAC,aAAa,CAAC,gBAAgB,CAAC;AACvD,QAAA,QAAQ,EAAE,gBAAgB,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAEhE,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC;AAC3C,QAAA,IAAI,CAAC,SAAS,GAAG,cAAc;QAC/B,IAAI,CAAC,SAAS,GAAG;;;;;;;;;;;;;;;;AAgBI,uBAAA,EAAA,IAAI,CAAC,MAAM,CAAC,eAAe,IAAI,2BAA2B,CAAA;;;;;;;;;;;;;;;;;;;;AAoB3E,MAAA,EAAA,IAAI,CAAC,MAAM,CAAC,gBAAgB,GAAG;;kDAEW,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAA;;OAEvE,GAAG,EAAE;;;;;;;;;;;;KAYP;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC;AACvD,QAAA,SAAS,EAAE,gBAAgB,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;AAEhE,QAAA,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,KAAI;YACpB,CAAC,CAAC,cAAc,EAAE;AAClB,YAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;AACzB,QAAA,CAAC;AAED,QAAA,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC;AACzB,QAAA,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC;AACvB,QAAA,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC;;AAG1B,QAAA,IAAI,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAAE;YAChC,UAAU,CAAC,MAAK;AACd,gBAAA,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC;YAClC,CAAC,EAAE,GAAG,CAAC;QACT;AAEA,QAAA,OAAO,OAAO;IAChB;AAEA;;AAEG;AACK,IAAA,qBAAqB,CAAC,IAAqB,EAAA;QACjD,MAAM,kBAAkB,GAAG,IAAI,CAAC,aAAa,CAAC,eAAe,CAAC;AAC9D,QAAA,IAAI,CAAC,kBAAkB;YAAE;;AAGzB,QAAA,IAAI,CAAE,MAAc,CAAC,SAAS,EAAE;AAC9B,YAAA,OAAO,CAAC,IAAI,CAAC,iJAAiJ,CAAC;YAC/J;QACF;AAEA,QAAA,IAAI;YACF,MAAM,QAAQ,GAAI,MAAc,CAAC,SAAS,CAAC,MAAM,CAAC,kBAAkB,EAAE;AACpE,gBAAA,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB;AACrC,gBAAA,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,MAAM,GAAG,MAAM,GAAG,OAAO;AACtD,gBAAA,QAAQ,EAAE,CAAC,KAAa,KAAI;;AAE1B,oBAAA,kBAAkB,CAAC,YAAY,CAAC,yBAAyB,EAAE,KAAK,CAAC;AACjE,oBAAA,kBAAkB,CAAC,YAAY,CAAC,gBAAgB,EAAE,QAAQ,CAAC;gBAC7D,CAAC;gBACD,gBAAgB,EAAE,MAAK;AACrB,oBAAA,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC;gBAClD,CAAC;gBACD,kBAAkB,EAAE,MAAK;;AAEvB,oBAAA,kBAAkB,CAAC,eAAe,CAAC,yBAAyB,CAAC;gBAC/D,CAAC;AACF,aAAA,CAAC;AAEF,YAAA,kBAAkB,CAAC,YAAY,CAAC,gBAAgB,EAAE,QAAQ,CAAC;QAC7D;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,OAAO,CAAC,KAAK,CAAC,6CAA6C,EAAE,KAAK,CAAC;QACrE;IACF;AAEA;;AAEG;IACK,MAAM,YAAY,CAAC,IAAqB,EAAA;QAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAqB;QAC3E,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,sBAAsB,CAAwB;QACnF,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAqB;QAC3E,MAAM,kBAAkB,GAAG,IAAI,CAAC,aAAa,CAAC,qBAAqB,CAAqB;QACxF,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAmB;QACzE,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,uBAAuB,CAAsB;QAClF,MAAM,kBAAkB,GAAG,IAAI,CAAC,aAAa,CAAC,eAAe,CAAC;;AAG9D,QAAA,SAAS,CAAC,QAAQ,GAAG,IAAI;AACzB,QAAA,SAAS,CAAC,WAAW,GAAG,YAAY;AAEpC,QAAA,IAAI;;AAEF,YAAA,IAAI,cAAkC;YACtC,IAAI,kBAAkB,EAAE;gBACtB,cAAc,GAAG,kBAAkB,CAAC,YAAY,CAAC,yBAAyB,CAAC,IAAI,SAAS;YAC1F;AAEA,YAAA,MAAM,IAAI,GAAG;gBACX,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,SAAS;AAC3C,gBAAA,WAAW,EAAE,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE;gBACnC,aAAa,EAAE,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,SAAS;gBACnD,iBAAiB,EAAE,kBAAkB,CAAC,OAAO;gBAC7C,cAAc;aACf;;YAGD,MAAM,iBAAiB,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,KAAI;gBAC9D,MAAM,aAAa,GAAG,MAAK;AACzB,oBAAA,QAAQ,CAAC,mBAAmB,CAAC,iBAAiB,EAAE,aAAa,CAAC;AAC9D,oBAAA,QAAQ,CAAC,mBAAmB,CAAC,eAAe,EAAE,WAAW,CAAC;AAC1D,oBAAA,OAAO,EAAE;AACX,gBAAA,CAAC;AAED,gBAAA,MAAM,WAAW,GAAG,CAAC,CAAQ,KAAI;AAC/B,oBAAA,QAAQ,CAAC,mBAAmB,CAAC,iBAAiB,EAAE,aAAa,CAAC;AAC9D,oBAAA,QAAQ,CAAC,mBAAmB,CAAC,eAAe,EAAE,WAAW,CAAC;AAC1D,oBAAA,MAAM,CAAE,CAAiB,CAAC,MAAM,CAAC;AACnC,gBAAA,CAAC;AAED,gBAAA,QAAQ,CAAC,gBAAgB,CAAC,iBAAiB,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAC3E,gBAAA,QAAQ,CAAC,gBAAgB,CAAC,eAAe,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;;gBAGvE,UAAU,CAAC,MAAK;AACd,oBAAA,QAAQ,CAAC,mBAAmB,CAAC,iBAAiB,EAAE,aAAa,CAAC;AAC9D,oBAAA,QAAQ,CAAC,mBAAmB,CAAC,eAAe,EAAE,WAAW,CAAC;AAC1D,oBAAA,MAAM,CAAC,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;AACzC,gBAAA,CAAC,EAAE,KAAK,CAAC,CAAC;AACZ,YAAA,CAAC,CAAC;;AAGF,YAAA,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,gBAAgB,EAAE;AAC9C,gBAAA,MAAM,EAAE,IAAI;AACZ,gBAAA,OAAO,EAAE,IAAI;AACd,aAAA,CAAC;AACF,YAAA,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC;;AAG7B,YAAA,MAAM,iBAAiB;;AAGvB,YAAA,SAAS,CAAC,SAAS,GAAG,gCAAgC;YACtD,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc,IAAI,6BAA6B;;YAGnF,UAAU,CAAC,MAAK;gBACd,IAAI,CAAC,KAAK,EAAE;YACd,CAAC,EAAE,IAAI,CAAC;QACV;QAAE,OAAO,KAAK,EAAE;;AAEd,YAAA,SAAS,CAAC,SAAS,GAAG,8BAA8B;AACpD,YAAA,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,GAAG,KAAK,CAAC,OAAO;iBACxD,IAAI,CAAC,MAAM,CAAC,YAAY,IAAI,4CAA4C,CAAC;AAC5E,YAAA,SAAS,CAAC,WAAW,GAAG,YAAY;;AAGpC,YAAA,SAAS,CAAC,QAAQ,GAAG,KAAK;AAC1B,YAAA,SAAS,CAAC,WAAW,GAAG,eAAe;QACzC;IACF;AAEA;;AAEG;IACK,YAAY,GAAA;AAClB,QAAA,IAAI,QAAQ,CAAC,cAAc,CAAC,gBAAgB,CAAC;YAAE;QAE/C,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC;AAC7C,QAAA,KAAK,CAAC,EAAE,GAAG,gBAAgB;QAC3B,KAAK,CAAC,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA4VnB;AAED,QAAA,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;IAClC;AAEA;;AAEG;IACK,mBAAmB,GAAA;AACzB,QAAA,MAAM,aAAa,GAAG,CAAC,CAAgB,KAAI;;YAEzC,IAAI,CAAC,CAAC,GAAG,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,EAAE;gBACrC,CAAC,CAAC,cAAc,EAAE;AAClB,gBAAA,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;YACvB;AACF,QAAA,CAAC;AAED,QAAA,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,aAAa,CAAC;;AAGnD,QAAA,IAAI,IAAI,CAAC,SAAS,EAAE;AACjB,YAAA,IAAI,CAAC,SAAiB,CAAC,eAAe,GAAG,aAAa;QACzD;IACF;AAEA;;AAEG;IACK,cAAc,GAAA;QACpB,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE;;QAGrB,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,gBAAgB,CAAC;AAC5D,QAAA,IAAI,CAAC,KAAK;YAAE;QAEZ,MAAM,iBAAiB,GACrB,0EAA0E;AAC5E,QAAA,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC,IAAI,CACjC,KAAK,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,CACzB;QAElB,IAAI,IAAI,CAAC,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE;AACvC,YAAA,OAAO,CAAC,IAAI,CAAC,+CAA+C,CAAC;YAC7D;QACF;;AAGA,QAAA,MAAM,SAAS,GAAG,CAAC,CAAQ,KAAI;YAC7B,MAAM,QAAQ,GAAG,CAAkB;AACnC,YAAA,IAAI,QAAQ,CAAC,GAAG,KAAK,KAAK;gBAAE;;YAG5B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC;gBAAE;YAEvD,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;AAChD,YAAA,MAAM,aAAa,GAAG,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,CAAC;AAE/E,YAAA,IAAI,QAAQ,CAAC,QAAQ,EAAE;;AAErB,gBAAA,IAAI,QAAQ,CAAC,aAAa,KAAK,cAAc,EAAE;oBAC7C,QAAQ,CAAC,cAAc,EAAE;oBACzB,aAAa,EAAE,KAAK,EAAE;gBACxB;YACF;iBAAO;;AAEL,gBAAA,IAAI,QAAQ,CAAC,aAAa,KAAK,aAAa,EAAE;oBAC5C,QAAQ,CAAC,cAAc,EAAE;oBACzB,cAAc,EAAE,KAAK,EAAE;gBACzB;YACF;AACF,QAAA,CAAC;;QAGD,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,SAA0B,EAAE,IAAI,CAAC;AACrE,QAAA,IAAI,CAAC,SAAiB,CAAC,WAAW,GAAG,SAAS;IACjD;AAEA;;AAEG;IACH,OAAO,GAAA;;AAEL,QAAA,IAAI,IAAI,CAAC,SAAS,EAAE;AAClB,YAAA,MAAM,cAAc,GAAI,IAAI,CAAC,SAAiB,CAAC,eAAe;YAC9D,IAAI,cAAc,EAAE;AAClB,gBAAA,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,cAAc,CAAC;YACzD;AAEA,YAAA,MAAM,UAAU,GAAI,IAAI,CAAC,SAAiB,CAAC,WAAW;YACtD,IAAI,UAAU,EAAE;gBACd,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC;YAC3D;QACF;QAEA,IAAI,CAAC,KAAK,EAAE;QACZ,QAAQ,CAAC,cAAc,CAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE;QACnD,QAAQ,CAAC,cAAc,CAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE;IACrD;AACD;;ACx1BD;AAQA,MAAM,eAAe,GAAG,uDAAuD;MAElE,UAAU,CAAA;AAMrB,IAAA,WAAA,CACE,cAAsB,EACtB,MAAe,EACf,QAAgC,EAChC,gBAAyB,EAAA;AAEzB,QAAA,IAAI,CAAC,MAAM,GAAG,CAAC,MAAM,IAAI,eAAe,EAAE,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAC7D,QAAA,IAAI,CAAC,cAAc,GAAG,cAAc;AACpC,QAAA,IAAI,CAAC,QAAQ,GAAG,QAAQ;AACxB,QAAA,IAAI,CAAC,gBAAgB,GAAG,gBAAgB;IAC1C;AAEA;;AAEG;AACK,IAAA,MAAM,iBAAiB,GAAA;;QAE7B,MAAM,eAAe,GAAG,QAAQ,CAAC,aAAa,CAAC,2BAA2B,CAAC;QAC3E,IAAI,eAAe,EAAE;YACnB,MAAM,KAAK,GAAG,eAAe,CAAC,YAAY,CAAC,yBAAyB,CAAC;AACrE,YAAA,IAAI,KAAK;AAAE,gBAAA,OAAO,KAAK;QACzB;;AAGA,QAAA,IAAK,MAAc,CAAC,SAAS,EAAE;AAC7B,YAAA,IAAI;;gBAEF,MAAM,OAAO,GAAG,QAAQ,CAAC,gBAAgB,CAAC,eAAe,CAAC;AAC1D,gBAAA,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;oBACtB,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,gBAAgB,CAAC;oBAC1D,IAAI,QAAQ,EAAE;wBACZ,MAAM,KAAK,GAAI,MAAc,CAAC,SAAS,CAAC,WAAW,CAAC,QAAQ,CAAC;AAC7D,wBAAA,IAAI,KAAK;AAAE,4BAAA,OAAO,KAAK;oBACzB;gBACF;YACF;YAAE,OAAO,KAAK,EAAE;AACd,gBAAA,OAAO,CAAC,IAAI,CAAC,gCAAgC,EAAE,KAAK,CAAC;YACvD;QACF;AAEA,QAAA,OAAO,IAAI;IACb;AAEA;;AAEG;AACH,IAAA,MAAM,cAAc,CAClB,IAAkB,EAClB,QAA0B,EAC1B,cAAuB,EAAA;;QAGvB,IAAI,CAAC,cAAc,EAAE;YACnB,cAAc,GAAG,MAAM,IAAI,CAAC,iBAAiB,EAAE,IAAI,SAAS;QAC9D;;AAGA,QAAA,IAAI,IAAI,CAAC,gBAAgB,IAAI,CAAC,cAAc,EAAE;AAC5C,YAAA,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC;QAClF;;AAGA,QAAA,IAAI,aAAiC;AACrC,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE;AACjB,YAAA,IAAI;AACF,gBAAA,aAAa,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE;YACvC;YAAE,OAAO,KAAK,EAAE;AACd,gBAAA,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC;AACrD,gBAAA,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC;YAC9D;QACF;AAEA,QAAA,MAAM,OAAO,GAAG;YACd,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,WAAW,EAAE,IAAI,CAAC,WAAW;AAC7B,YAAA,QAAQ,EAAE;AACR,gBAAA,GAAG,QAAQ;gBACX,WAAW,EAAE,IAAI,CAAC,WAAW;AAC9B,aAAA;YACD,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,cAAc;YACd,aAAa;SACd;QAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,MAAM,CAAA,SAAA,CAAW,EAAE;AACtD,YAAA,MAAM,EAAE,MAAM;AACd,YAAA,OAAO,EAAE;AACP,gBAAA,cAAc,EAAE,kBAAkB;AACnC,aAAA;AACD,YAAA,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;AAC9B,SAAA,CAAC;AAEF,QAAA,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;YAChB,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAAC;;AAGvG,YAAA,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE;AAC3B,gBAAA,IAAI,KAAK,CAAC,KAAK,KAAK,yBAAyB,EAAE;AAC7C,oBAAA,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC;gBAC7D;AAAO,qBAAA,IAAI,KAAK,CAAC,KAAK,KAAK,gBAAgB,EAAE;AAC3C,oBAAA,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC;gBAC3E;gBACA,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,IAAI,uBAAuB,CAAC;YAC3D;AAAO,iBAAA,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE;AAClC,gBAAA,IAAI,KAAK,CAAC,KAAK,KAAK,oBAAoB,EAAE;AACxC,oBAAA,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC;gBACvE;gBACA,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,IAAI,eAAe,CAAC;YACnD;AAAO,iBAAA,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE;gBAClC,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;AACtD,gBAAA,MAAM,SAAS,GAAG,UAAU,GAAG,CAAA,GAAA,EAAM,UAAU,CAAA,QAAA,CAAU,GAAG,OAAO;AACnE,gBAAA,MAAM,IAAI,KAAK,CAAC,uCAAuC,SAAS,CAAA,CAAA,CAAG,CAAC;YACtE;AAAO,iBAAA,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,KAAK,KAAK,gBAAgB,EAAE;AACtE,gBAAA,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC;YACnE;AAEA,YAAA,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,KAAK,IAAI,CAAA,gCAAA,EAAmC,QAAQ,CAAC,MAAM,CAAA,CAAA,CAAG,CAAC;QACxG;AAEA,QAAA,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE;IAC9B;AACD;;AC7ID;AAIA;;AAEG;AACG,SAAU,eAAe,CAAC,cAAoC,EAAA;IAClE,MAAM,QAAQ,GAAG,CAAA,EAAG,MAAM,CAAC,UAAU,CAAA,CAAA,EAAI,MAAM,CAAC,WAAW,CAAA,CAAE;AAC7D,IAAA,MAAM,OAAO,GAAG,aAAa,EAAE;IAE/B,OAAO;AACL,QAAA,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI;QACzB,OAAO;QACP,QAAQ;QACR,SAAS,EAAE,SAAS,CAAC,SAAS;AAC9B,QAAA,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;AACnC,QAAA,GAAG,cAAc;KAClB;AACH;AAEA;;AAEG;AACH,SAAS,aAAa,GAAA;AACpB,IAAA,MAAM,EAAE,GAAG,SAAS,CAAC,SAAS;IAC9B,IAAI,OAAO,GAAG,SAAS;AAEvB,IAAA,IAAI,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE;AAC3B,QAAA,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;AAC/C,QAAA,OAAO,GAAG,CAAA,QAAA,EAAW,OAAO,CAAA,CAAE;IAChC;AAAO,SAAA,IAAI,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;AACxD,QAAA,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;AAC9C,QAAA,OAAO,GAAG,CAAA,OAAA,EAAU,OAAO,CAAA,CAAE;IAC/B;AAAO,SAAA,IAAI,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE;AAC3D,QAAA,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;AAC/C,QAAA,OAAO,GAAG,CAAA,OAAA,EAAU,OAAO,CAAA,CAAE;IAC/B;AAAO,SAAA,IAAI,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;AAC9B,QAAA,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;AAC3C,QAAA,OAAO,GAAG,CAAA,KAAA,EAAQ,OAAO,CAAA,CAAE;IAC7B;AAEA,IAAA,OAAO,OAAO;AAChB;AAEA;;AAEG;AACI,eAAe,iBAAiB,GAAA;AACrC,IAAA,IAAI;;AAEF,QAAA,IAAI,OAAQ,MAAc,CAAC,WAAW,KAAK,WAAW,EAAE;YACtD,MAAM,MAAM,GAAG,MAAO,MAAc,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE;AAC9D,gBAAA,OAAO,EAAE,KAAK;AACd,gBAAA,OAAO,EAAE,IAAI;AACb,gBAAA,UAAU,EAAE,IAAI;AACjB,aAAA,CAAC;AACF,YAAA,OAAO,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC;QACtC;;QAGA,IAAI,cAAc,IAAI,SAAS,IAAI,iBAAiB,IAAI,SAAS,CAAC,YAAY,EAAE;;;AAG9E,YAAA,OAAO,CAAC,IAAI,CAAC,iDAAiD,CAAC;AAC/D,YAAA,OAAO,IAAI;QACb;AAEA,QAAA,OAAO,IAAI;IACb;IAAE,OAAO,KAAK,EAAE;AACd,QAAA,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC;AAClD,QAAA,OAAO,IAAI;IACb;AACF;AAEA;;AAEG;MACU,WAAW,CAAA;IAKtB,WAAA,CAAY,GAAW,EAAE,WAAA,GAAsB,CAAC,EAAE,WAAmB,CAAC,GAAG,EAAE,GAAG,IAAI,EAAA;AAChF,QAAA,IAAI,CAAC,GAAG,GAAG,CAAA,kBAAA,EAAqB,GAAG,EAAE;AACrC,QAAA,IAAI,CAAC,WAAW,GAAG,WAAW;AAC9B,QAAA,IAAI,CAAC,QAAQ,GAAG,QAAQ;IAC1B;IAEA,UAAU,GAAA;AACR,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;AACtB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE;;QAG3B,MAAM,cAAc,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CACzC,CAAC,SAAS,KAAK,GAAG,GAAG,SAAS,GAAG,IAAI,CAAC,QAAQ,CAC/C;QAED,IAAI,cAAc,CAAC,MAAM,IAAI,IAAI,CAAC,WAAW,EAAE;AAC7C,YAAA,OAAO,KAAK;QACd;AAEA,QAAA,OAAO,IAAI;IACb;IAEA,aAAa,GAAA;AACX,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;AACtB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE;;AAG3B,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC;;QAGvB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAClC,CAAC,SAAS,KAAK,GAAG,GAAG,SAAS,GAAG,IAAI,CAAC,QAAQ,CAC/C;AAED,QAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IACpB;IAEA,iBAAiB,GAAA;AACf,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;AACtB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE;QAE3B,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE;AAC9B,YAAA,OAAO,CAAC;QACV;QAEA,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;AAChD,QAAA,MAAM,SAAS,GAAG,aAAa,GAAG,IAAI,CAAC,QAAQ;QAE/C,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,GAAG,CAAC;IACrC;IAEQ,OAAO,GAAA;AACb,QAAA,IAAI;YACF,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;AAC7C,YAAA,OAAO,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE;QACvD;AAAE,QAAA,MAAM;AACN,YAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE;QACzB;IACF;AAEQ,IAAA,OAAO,CAAC,IAA4B,EAAA;AAC1C,QAAA,IAAI;AACF,YAAA,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACtD;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,KAAK,CAAC;QAC1D;IACF;AACD;MAmBY,aAAa,CAAA;IAWxB,WAAA,CAAY,OAAA,GAAkB,EAAE,EAAE,MAAA,GAAuC,CAAC,OAAO,EAAE,MAAM,CAAC,EAAA;QAVlF,IAAA,CAAA,MAAM,GAAiB,EAAE;QAQzB,IAAA,CAAA,QAAQ,GAAY,KAAK;AAG/B,QAAA,IAAI,CAAC,OAAO,GAAG,OAAO;QACtB,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC;;QAG7B,IAAI,CAAC,eAAe,GAAG;YACrB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,GAAG,EAAE,OAAO,CAAC,GAAG;SACjB;IACH;AAEA;;AAEG;IACH,KAAK,GAAA;QACH,IAAI,IAAI,CAAC,QAAQ;YAAE;AACnB,QAAA,IAAI,CAAC,QAAQ,GAAG,IAAI;;QAGpB,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;AAC5B,YAAA,OAAO,CAAC,KAAK,GAAG,CAAC,GAAG,IAAW,KAAI;AACjC,gBAAA,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC;gBAC9B,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC;AACjD,YAAA,CAAC;QACH;;QAGA,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;AAC3B,YAAA,OAAO,CAAC,IAAI,GAAG,CAAC,GAAG,IAAW,KAAI;AAChC,gBAAA,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC;gBAC7B,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC;AAChD,YAAA,CAAC;QACH;;QAGA,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;AAC1B,YAAA,OAAO,CAAC,GAAG,GAAG,CAAC,GAAG,IAAW,KAAI;AAC/B,gBAAA,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC;gBAC5B,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC;AAC/C,YAAA,CAAC;QACH;IACF;AAEA;;AAEG;IACH,IAAI,GAAA;QACF,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE;AACpB,QAAA,IAAI,CAAC,QAAQ,GAAG,KAAK;QAErB,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK;QAC1C,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI;QACxC,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG;IACxC;AAEA;;AAEG;IACK,UAAU,CAAC,KAA+B,EAAE,IAAW,EAAA;AAC7D,QAAA,IAAI;;YAEF,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAG;gBAC7B,IAAI,OAAO,GAAG,KAAK,QAAQ;AAAE,oBAAA,OAAO,GAAG;gBACvC,IAAI,GAAG,YAAY,KAAK;oBAAE,OAAO,GAAG,CAAC,OAAO;AAC5C,gBAAA,IAAI;AACF,oBAAA,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;gBAC5B;AAAE,gBAAA,MAAM;AACN,oBAAA,OAAO,MAAM,CAAC,GAAG,CAAC;gBACpB;AACF,YAAA,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;;AAGZ,YAAA,IAAI,KAAyB;AAC7B,YAAA,IAAI,KAAK,KAAK,OAAO,EAAE;AACrB,gBAAA,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,YAAY,KAAK,CAAC;gBACpD,IAAI,KAAK,EAAE;AACT,oBAAA,KAAK,GAAG,KAAK,CAAC,KAAK;gBACrB;qBAAO;;oBAEL,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;gBAC5D;YACF;;YAGA,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;AACxC,YAAA,MAAM,cAAc,GAAG,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,SAAS;;AAG/D,YAAA,MAAM,QAAQ,GAAe;gBAC3B,KAAK;AACL,gBAAA,OAAO,EAAE,SAAS;AAClB,gBAAA,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;AACnC,gBAAA,KAAK,EAAE,cAAc;aACtB;AAED,YAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;;YAG1B,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE;AACrC,gBAAA,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE;YACrB;QACF;QAAE,OAAO,KAAK,EAAE;;YAEd,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC;QAC7D;IACF;AAEA;;AAEG;AACK,IAAA,QAAQ,CAAC,IAAY,EAAA;AAC3B,QAAA,OAAO;;AAEJ,aAAA,OAAO,CAAC,mEAAmE,EAAE,WAAW;AACxF,aAAA,OAAO,CAAC,iEAAiE,EAAE,SAAS;AACpF,aAAA,OAAO,CAAC,oEAAoE,EAAE,YAAY;;AAE1F,aAAA,OAAO,CAAC,0BAA0B,EAAE,SAAS;;AAE7C,aAAA,OAAO,CAAC,oDAAoD,EAAE,SAAS;;AAEvE,aAAA,OAAO,CAAC,wCAAwC,EAAE,cAAc;;AAEhE,aAAA,OAAO,CAAC,uCAAuC,EAAE,aAAa;;AAE9D,aAAA,OAAO,CAAC,6CAA6C,EAAE,qBAAqB;;AAE5E,aAAA,OAAO,CAAC,yCAAyC,EAAE,UAAU,CAAC;IACnE;AAEA;;AAEG;IACH,OAAO,GAAA;AACL,QAAA,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;IACzB;AAEA;;AAEG;IACH,KAAK,GAAA;AACH,QAAA,IAAI,CAAC,MAAM,GAAG,EAAE;IAClB;AAEA;;AAEG;IACH,QAAQ,GAAA;AACN,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM;IAC3B;AACD;;AC3UD;MAOa,OAAO,CAAA;AAOlB,IAAA,WAAA,CAAY,MAAqB,EAAA;QAFzB,IAAA,CAAA,aAAa,GAAyB,IAAI;;AAIhD,QAAA,IAAI,cAAc,GAAG,MAAM,CAAC,cAAc;AAC1C,QAAA,IAAI,CAAC,cAAc,IAAI,MAAM,CAAC,SAAS,EAAE;YACvC,OAAO,CAAC,IAAI,CACV,uEAAuE;AACvE,gBAAA,6DAA6D,CAC9D;AACD,YAAA,cAAc,GAAG,MAAM,CAAC,SAAS;QACnC;QAEA,IAAI,CAAC,cAAc,EAAE;AACnB,YAAA,MAAM,IAAI,KAAK,CAAC,iFAAiF,CAAC;QACpG;QAEA,IAAI,CAAC,MAAM,GAAG;AACZ,YAAA,KAAK,EAAE,MAAM;AACb,YAAA,QAAQ,EAAE,cAAc;AACxB,YAAA,WAAW,EAAE,SAAS;AACtB,YAAA,UAAU,EAAE,aAAa;AACzB,YAAA,eAAe,EAAE,2BAA2B;AAC5C,YAAA,cAAc,EAAE,6BAA6B;AAC7C,YAAA,YAAY,EAAE,4CAA4C;AAC1D,YAAA,cAAc,EAAE,IAAI;AACpB,YAAA,eAAe,EAAE,EAAE;AACnB,YAAA,gBAAgB,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;AACnC,YAAA,GAAG,MAAM;YACT,cAAc;SACf;AAED,QAAA,IAAI,CAAC,GAAG,GAAG,IAAI,UAAU,CACvB,IAAI,CAAC,MAAM,CAAC,cAAc,EAC1B,IAAI,CAAC,MAAM,CAAC,MAAM,EAClB,IAAI,CAAC,MAAM,CAAC,QAAQ,EACpB,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAC7B;QACD,IAAI,CAAC,MAAM,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC;QAC7C,IAAI,CAAC,WAAW,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;;QAGhF,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,KAAK,KAAK,EAAE;AACxC,YAAA,IAAI,CAAC,aAAa,GAAG,IAAI,aAAa,CACpC,IAAI,CAAC,MAAM,CAAC,eAAe,EAC3B,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAC7B;AACD,YAAA,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE;QAC5B;QAEA,IAAI,CAAC,IAAI,EAAE;IACb;AAEA;;AAEG;IACK,IAAI,GAAA;;AAEV,QAAA,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;;QAGlB,QAAQ,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,CAAC,CAAQ,KAAI;YACvD,MAAM,WAAW,GAAG,CAAgB;AACpC,YAAA,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,MAAM,CAAC;AACvC,QAAA,CAAC,CAAC;IACJ;AAEA;;AAEG;IACK,MAAM,YAAY,CAAC,IAAS,EAAA;AAClC,QAAA,IAAI;;YAEF,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,EAAE;AAClC,gBAAA,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,iBAAiB,EAAE,GAAG,IAAI,GAAG,EAAE,CAAC;AAC7E,gBAAA,MAAM,IAAI,KAAK,CAAC,4CAA4C,SAAS,CAAA,WAAA,CAAa,CAAC;YACrF;;YAGA,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;;YAGtD,IAAI,UAAU,GAAkB,IAAI;AACpC,YAAA,IAAI,IAAI,CAAC,iBAAiB,EAAE;AAC1B,gBAAA,UAAU,GAAG,MAAM,iBAAiB,EAAE;YACxC;;AAGA,YAAA,MAAM,YAAY,GAAiB;gBACjC,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,aAAa,EAAE,IAAI,CAAC,aAAa;gBACjC,UAAU,EAAE,UAAU,IAAI,SAAS;AACnC,gBAAA,WAAW,EAAE,IAAI,CAAC,aAAa,EAAE,OAAO,EAAE;aAC3C;;AAGD,YAAA,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,cAAc,CAC5C,YAAY,EACZ,QAAQ,EACR,IAAI,CAAC,cAAc,CACpB;;AAGD,YAAA,IAAI,CAAC,WAAW,CAAC,aAAa,EAAE;;AAGhC,YAAA,QAAQ,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,iBAAiB,EAAE;AACxD,gBAAA,MAAM,EAAE,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE;AAClC,aAAA,CAAC,CAAC;;AAGH,YAAA,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE;gBACzB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpC;YAEA,OAAO,CAAC,GAAG,CAAC,kCAAkC,EAAE,QAAQ,CAAC,EAAE,CAAC;QAC9D;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC;;AAGlD,YAAA,QAAQ,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,eAAe,EAAE;AACtD,gBAAA,MAAM,EAAE;AACT,aAAA,CAAC,CAAC;;YAGH,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,KAAK,YAAY,KAAK,EAAE;AACjD,gBAAA,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;YAC5B;AAEA,YAAA,MAAM,KAAK;QACb;IACF;AAEA;;AAEG;IACH,IAAI,GAAA;AACF,QAAA,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;IACpB;AAEA;;AAEG;IACH,KAAK,GAAA;AACH,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE;IACrB;AAEA;;;AAGG;AACH,IAAA,MAAM,MAAM,CAAC,IAAkB,EAAE,cAAuB,EAAA;;QAEtD,IAAI,IAAI,CAAC,MAAM,CAAC,gBAAgB,IAAI,CAAC,cAAc,EAAE;YACnD,MAAM,IAAI,KAAK,CACb,yEAAyE;gBACzE,6CAA6C;AAC7C,gBAAA,qFAAqF,CACtF;QACH;QAEA,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;;QAGtD,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,aAAa,EAAE;YAC3C,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE;QACjD;AAEA,QAAA,MAAM,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,QAAQ,EAAE,cAAc,CAAC;AAC7D,QAAA,IAAI,CAAC,WAAW,CAAC,aAAa,EAAE;IAClC;AAEA;;AAEG;IACH,OAAO,GAAA;AACL,QAAA,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;AACrB,QAAA,IAAI,CAAC,aAAa,EAAE,IAAI,EAAE;QAC1B,QAAQ,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,MAAK,EAAE,CAAC,CAAC;IAC1D;AACD;AAKD;AACA,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;AACjC,IAAA,MAAM,YAAY,GAAI,MAAc,CAAC,aAAa;IAClD,IAAI,YAAY,EAAE;QACf,MAAc,CAAC,OAAO,GAAG,IAAI,OAAO,CAAC,YAAY,CAAC;IACrD;AACF;;;;"}
1
+ {"version":3,"file":"index.esm.js","sources":["../src/ui.ts","../src/api.ts","../src/utils.ts","../src/index.ts"],"sourcesContent":["// Feedback Widget UI\n\nimport { TriaglyConfig } from './types';\n\nexport class FeedbackWidget {\n private config: TriaglyConfig;\n private container: HTMLElement | null = null;\n private isOpen: boolean = false;\n private previouslyFocusedElement: HTMLElement | null = null;\n private focusableElements: HTMLElement[] = [];\n\n constructor(config: TriaglyConfig) {\n this.config = config;\n }\n\n /**\n * Initialize the widget\n */\n init(): void {\n this.createButton();\n this.injectStyles();\n }\n\n /**\n * Create the feedback button\n */\n private createButton(): void {\n const button = document.createElement('button');\n button.id = 'triagly-button';\n button.className = 'triagly-button';\n \n // Button shape\n const shape = this.config.buttonShape || 'rounded';\n button.classList.add(`triagly-shape-${shape}`);\n \n // Button orientation\n const orientation = this.config.orientation || 'horizontal';\n button.classList.add(`triagly-orientation-${orientation}`);\n \n // Handle button text based on shape\n const fullText = this.config.buttonText || '🐛 Feedback';\n if (shape === 'circular') {\n button.innerHTML = '🐛';\n button.setAttribute('aria-label', fullText);\n } else if (shape === 'expandable') {\n // Expandable starts with emoji, expands to full text on hover\n button.innerHTML = '<span class=\"triagly-btn-icon\">🐛</span><span class=\"triagly-btn-text\"> Feedback</span>';\n button.setAttribute('aria-label', fullText);\n // Store custom text if provided\n if (this.config.buttonText) {\n const textSpan = button.querySelector('.triagly-btn-text');\n if (textSpan) {\n textSpan.textContent = ' ' + this.config.buttonText.replace('🐛', '').trim();\n }\n }\n } else {\n button.innerHTML = fullText;\n }\n \n button.onclick = () => this.toggle();\n\n // Position button\n const position = this.config.position || 'bottom-right';\n button.classList.add(`triagly-${position}`);\n\n // For expandable buttons, set expansion direction based on position\n if (shape === 'expandable') {\n if (position.includes('right')) {\n button.classList.add('triagly-expand-left');\n } else if (position.includes('left')) {\n button.classList.add('triagly-expand-right');\n }\n }\n\n // Apply custom offsets if provided\n if (this.config.offsetX) {\n if (position.includes('right')) {\n button.style.right = this.config.offsetX;\n } else if (position.includes('left')) {\n button.style.left = this.config.offsetX;\n }\n }\n if (this.config.offsetY) {\n if (position.includes('top')) {\n button.style.top = this.config.offsetY;\n } else if (position.includes('bottom')) {\n button.style.bottom = this.config.offsetY;\n }\n }\n\n document.body.appendChild(button);\n }\n\n /**\n * Toggle widget visibility\n */\n toggle(): void {\n if (this.isOpen) {\n this.close();\n } else {\n this.open();\n }\n }\n\n /**\n * Open the widget\n */\n open(): void {\n if (this.isOpen) return;\n\n // Store currently focused element to restore later\n this.previouslyFocusedElement = document.activeElement as HTMLElement;\n\n this.container = this.createContainer();\n document.body.appendChild(this.container);\n this.isOpen = true;\n\n // Call onOpen callback\n if (this.config.onOpen) {\n this.config.onOpen();\n }\n\n // Set up keyboard and focus after DOM is ready\n setTimeout(() => {\n // Set up keyboard event listener\n this.setupKeyboardEvents();\n\n // Set up focus trap\n this.setupFocusTrap();\n\n // Focus on title field\n const titleInput = this.container?.querySelector('input[type=\"text\"]') as HTMLInputElement;\n titleInput?.focus();\n }, 0);\n }\n\n /**\n * Close the widget\n */\n close(reason?: 'cancel' | 'dismiss' | 'overlay' | 'programmatic'): void {\n if (!this.isOpen || !this.container) return;\n\n // Clean up tab handler (must match capture phase used when adding)\n const tabHandler = (this.container as any)._tabHandler;\n if (tabHandler) {\n document.removeEventListener('keydown', tabHandler, true);\n }\n\n this.container.remove();\n this.container = null;\n this.isOpen = false;\n\n // Restore focus to previously focused element\n if (this.previouslyFocusedElement) {\n this.previouslyFocusedElement.focus();\n this.previouslyFocusedElement = null;\n }\n\n // Call specific callbacks based on reason\n if (reason === 'cancel' && this.config.onCancel) {\n this.config.onCancel();\n } else if (reason === 'dismiss' && this.config.onDismiss) {\n this.config.onDismiss();\n } else if (reason === 'overlay' && this.config.onOverlayClick) {\n this.config.onOverlayClick();\n }\n\n // Always call general onClose callback (backward compatible)\n if (this.config.onClose) {\n this.config.onClose();\n }\n }\n\n /**\n * Create the widget container\n */\n private createContainer(): HTMLElement {\n const overlay = document.createElement('div');\n overlay.className = 'triagly-overlay';\n overlay.setAttribute('role', 'dialog');\n overlay.setAttribute('aria-modal', 'true');\n overlay.setAttribute('aria-labelledby', 'triagly-modal-title');\n overlay.onclick = (e) => {\n if (e.target === overlay) this.close('overlay');\n };\n\n const modal = document.createElement('div');\n modal.className = 'triagly-modal';\n modal.setAttribute('role', 'document');\n\n const header = document.createElement('div');\n header.className = 'triagly-header';\n header.innerHTML = `\n <h3 id=\"triagly-modal-title\">Send Feedback</h3>\n <button type=\"button\" class=\"triagly-close\" aria-label=\"Close feedback form\">×</button>\n `;\n\n const closeBtn = header.querySelector('.triagly-close');\n closeBtn?.addEventListener('click', () => this.close('dismiss'));\n\n const form = document.createElement('form');\n form.className = 'triagly-form';\n form.innerHTML = `\n <div class=\"triagly-field\">\n <label for=\"triagly-title\">Title (optional)</label>\n <input\n type=\"text\"\n id=\"triagly-title\"\n placeholder=\"Brief summary of your feedback\"\n />\n </div>\n\n <div class=\"triagly-field\">\n <label for=\"triagly-description\">Description *</label>\n <textarea\n id=\"triagly-description\"\n required\n rows=\"5\"\n placeholder=\"${this.config.placeholderText || 'Describe what happened...'}\"\n ></textarea>\n </div>\n\n <div class=\"triagly-field\">\n <label for=\"triagly-email\">Email (optional)</label>\n <input\n type=\"email\"\n id=\"triagly-email\"\n placeholder=\"your@email.com\"\n />\n </div>\n\n <div class=\"triagly-field triagly-checkbox\">\n <label>\n <input type=\"checkbox\" id=\"triagly-screenshot\" checked />\n <span>Include screenshot</span>\n </label>\n </div>\n\n ${this.config.turnstileSiteKey ? `\n <div class=\"triagly-field triagly-turnstile\">\n <div class=\"cf-turnstile\" data-sitekey=\"${this.config.turnstileSiteKey}\" data-theme=\"light\"></div>\n </div>\n ` : ''}\n\n <div class=\"triagly-actions\">\n <button type=\"button\" class=\"triagly-btn-secondary\" id=\"triagly-cancel\" aria-label=\"Cancel and close feedback form\">\n Cancel\n </button>\n <button type=\"submit\" class=\"triagly-btn-primary\" aria-label=\"Submit feedback\">\n Send Feedback\n </button>\n </div>\n\n <div class=\"triagly-status\" id=\"triagly-status\" role=\"status\" aria-live=\"polite\"></div>\n `;\n\n const cancelBtn = form.querySelector('#triagly-cancel');\n cancelBtn?.addEventListener('click', () => this.close('cancel'));\n\n form.onsubmit = (e) => {\n e.preventDefault();\n this.handleSubmit(form);\n };\n\n modal.appendChild(header);\n modal.appendChild(form);\n overlay.appendChild(modal);\n\n // Render Turnstile widget if available\n if (this.config.turnstileSiteKey) {\n setTimeout(() => {\n this.renderTurnstileWidget(form);\n }, 100);\n }\n\n return overlay;\n }\n\n /**\n * Render Cloudflare Turnstile widget\n */\n private renderTurnstileWidget(form: HTMLFormElement): void {\n const turnstileContainer = form.querySelector('.cf-turnstile');\n if (!turnstileContainer) return;\n\n // Check if Turnstile script is loaded\n if (!(window as any).turnstile) {\n console.warn('Triagly: Turnstile script not loaded. Please include: <script src=\"https://challenges.cloudflare.com/turnstile/v0/api.js\" async defer></script>');\n return;\n }\n\n try {\n const widgetId = (window as any).turnstile.render(turnstileContainer, {\n sitekey: this.config.turnstileSiteKey,\n theme: this.config.theme === 'dark' ? 'dark' : 'light',\n callback: (token: string) => {\n // Store token in a data attribute for easy retrieval\n turnstileContainer.setAttribute('data-turnstile-response', token);\n turnstileContainer.setAttribute('data-widget-id', widgetId);\n },\n 'error-callback': () => {\n console.error('Triagly: Turnstile widget error');\n },\n 'expired-callback': () => {\n // Clear stored token when it expires\n turnstileContainer.removeAttribute('data-turnstile-response');\n },\n });\n\n turnstileContainer.setAttribute('data-widget-id', widgetId);\n } catch (error) {\n console.error('Triagly: Failed to render Turnstile widget:', error);\n }\n }\n\n /**\n * Handle form submission\n */\n private async handleSubmit(form: HTMLFormElement): Promise<void> {\n const titleInput = form.querySelector('#triagly-title') as HTMLInputElement;\n const descInput = form.querySelector('#triagly-description') as HTMLTextAreaElement;\n const emailInput = form.querySelector('#triagly-email') as HTMLInputElement;\n const screenshotCheckbox = form.querySelector('#triagly-screenshot') as HTMLInputElement;\n const statusDiv = form.querySelector('#triagly-status') as HTMLDivElement;\n const submitBtn = form.querySelector('button[type=\"submit\"]') as HTMLButtonElement;\n const turnstileContainer = form.querySelector('.cf-turnstile');\n\n // Disable form\n submitBtn.disabled = true;\n submitBtn.textContent = 'Sending...';\n\n try {\n // Get Turnstile token if widget is present\n let turnstileToken: string | undefined;\n if (turnstileContainer) {\n turnstileToken = turnstileContainer.getAttribute('data-turnstile-response') || undefined;\n }\n\n const data = {\n title: titleInput.value.trim() || undefined,\n description: descInput.value.trim(),\n reporterEmail: emailInput.value.trim() || undefined,\n includeScreenshot: screenshotCheckbox.checked,\n turnstileToken,\n };\n\n // Create a promise that waits for actual submission result\n const submissionPromise = new Promise<void>((resolve, reject) => {\n const handleSuccess = () => {\n document.removeEventListener('triagly:success', handleSuccess);\n document.removeEventListener('triagly:error', handleError);\n resolve();\n };\n\n const handleError = (e: Event) => {\n document.removeEventListener('triagly:success', handleSuccess);\n document.removeEventListener('triagly:error', handleError);\n reject((e as CustomEvent).detail);\n };\n\n document.addEventListener('triagly:success', handleSuccess, { once: true });\n document.addEventListener('triagly:error', handleError, { once: true });\n\n // Set a timeout in case events don't fire\n setTimeout(() => {\n document.removeEventListener('triagly:success', handleSuccess);\n document.removeEventListener('triagly:error', handleError);\n reject(new Error('Submission timeout'));\n }, 30000); // 30 second timeout\n });\n\n // Dispatch custom event for parent to handle\n const event = new CustomEvent('triagly:submit', {\n detail: data,\n bubbles: true,\n });\n document.dispatchEvent(event);\n\n // Wait for actual submission result\n await submissionPromise;\n\n // Show success\n statusDiv.className = 'triagly-status triagly-success';\n statusDiv.textContent = this.config.successMessage || 'Feedback sent successfully!';\n\n // Close after delay\n setTimeout(() => {\n this.close();\n }, 2000);\n } catch (error) {\n // Show error with actual error message\n statusDiv.className = 'triagly-status triagly-error';\n const errorMessage = error instanceof Error ? error.message :\n (this.config.errorMessage || 'Failed to send feedback. Please try again.');\n statusDiv.textContent = errorMessage;\n\n // Re-enable form\n submitBtn.disabled = false;\n submitBtn.textContent = 'Send Feedback';\n }\n }\n\n /**\n * Inject widget styles\n */\n private injectStyles(): void {\n if (document.getElementById('triagly-styles')) return;\n\n const style = document.createElement('style');\n style.id = 'triagly-styles';\n style.textContent = `\n .triagly-button {\n position: fixed;\n z-index: 999999;\n padding: 12px 20px;\n background: var(--triagly-button-bg, #6366f1);\n color: var(--triagly-button-text, #ffffff);\n border: none;\n border-radius: var(--triagly-button-radius, 8px);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n box-shadow: var(--triagly-button-shadow, 0 4px 12px rgba(99, 102, 241, 0.3));\n transition: all 0.2s;\n }\n\n .triagly-button:hover {\n background: var(--triagly-button-bg-hover, #4f46e5);\n transform: translateY(-2px);\n box-shadow: var(--triagly-button-shadow-hover, 0 6px 16px rgba(99, 102, 241, 0.4));\n }\n\n /* Prevent expandable buttons from shifting on hover */\n .triagly-button.triagly-shape-expandable:hover {\n transform: translateY(0) !important;\n }\n\n .triagly-bottom-right { bottom: 20px; right: 20px; }\n .triagly-bottom-left { bottom: 20px; left: 20px; }\n .triagly-top-right { top: 20px; right: 20px; }\n .triagly-top-left { top: 20px; left: 20px; }\n\n /* Edge-aligned positions (0 offset from edges) */\n .triagly-edge-bottom-right { bottom: 0; right: 0; }\n .triagly-edge-bottom-left { bottom: 0; left: 0; }\n .triagly-edge-top-right { top: 0; right: 0; }\n .triagly-edge-top-left { top: 0; left: 0; }\n .triagly-edge-right { top: 50%; right: 0; transform: translateY(-50%); }\n .triagly-edge-left { top: 50%; left: 0; transform: translateY(-50%); }\n .triagly-edge-top { top: 0; left: 50%; transform: translateX(-50%); }\n .triagly-edge-bottom { bottom: 0; left: 50%; transform: translateX(-50%); }\n\n /* Button shapes */\n .triagly-shape-rounded {\n border-radius: var(--triagly-button-radius, 8px);\n }\n .triagly-shape-circular {\n border-radius: 50%;\n width: 60px;\n height: 60px;\n padding: 0;\n font-size: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .triagly-shape-square {\n border-radius: 0;\n }\n .triagly-shape-pill {\n border-radius: 30px;\n }\n .triagly-shape-expandable {\n border-radius: 50%;\n width: 60px;\n height: 60px;\n min-width: 60px;\n padding: 0;\n font-size: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1),\n border-radius 0.3s cubic-bezier(0.4, 0, 0.2, 1),\n padding 0.3s cubic-bezier(0.4, 0, 0.2, 1),\n background 0.2s,\n box-shadow 0.2s;\n white-space: nowrap;\n }\n \n /* Expansion direction - expands left for right-positioned buttons */\n .triagly-shape-expandable.triagly-expand-left {\n flex-direction: row-reverse;\n }\n \n /* Expansion direction - expands right for left-positioned buttons */\n .triagly-shape-expandable.triagly-expand-right {\n flex-direction: row;\n }\n \n .triagly-shape-expandable .triagly-btn-icon {\n display: inline-block;\n flex-shrink: 0;\n transition: margin 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n }\n .triagly-shape-expandable .triagly-btn-text {\n display: inline-block;\n width: 0;\n opacity: 0;\n overflow: hidden;\n font-size: 14px;\n font-weight: 500;\n transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1),\n opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n }\n \n /* Hover state */\n .triagly-shape-expandable:hover {\n width: auto;\n min-width: auto;\n padding: 12px 20px;\n border-radius: 30px;\n background: var(--triagly-button-bg-hover, #4f46e5);\n box-shadow: var(--triagly-button-shadow-hover, 0 6px 16px rgba(99, 102, 241, 0.4));\n }\n .triagly-shape-expandable:hover .triagly-btn-text {\n width: auto;\n opacity: 1;\n }\n\n /* Button orientations */\n .triagly-orientation-horizontal {\n writing-mode: horizontal-tb;\n }\n .triagly-orientation-vertical {\n writing-mode: vertical-rl;\n text-orientation: mixed;\n }\n\n .triagly-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--triagly-overlay-bg, rgba(0, 0, 0, 0.5));\n z-index: 1000000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: triagly-fadeIn 0.2s;\n }\n\n @keyframes triagly-fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n\n .triagly-modal {\n background: var(--triagly-modal-bg, #ffffff);\n border-radius: var(--triagly-modal-radius, 12px);\n width: 90%;\n max-width: var(--triagly-modal-max-width, 500px);\n max-height: 90vh;\n overflow-y: auto;\n box-shadow: var(--triagly-modal-shadow, 0 20px 60px rgba(0, 0, 0, 0.3));\n animation: triagly-slideUp 0.3s;\n }\n\n @keyframes triagly-slideUp {\n from {\n opacity: 0;\n transform: translateY(20px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n\n .triagly-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 20px 24px;\n background: var(--triagly-header-bg, #ffffff);\n border-bottom: 1px solid var(--triagly-header-border, #e5e7eb);\n }\n\n .triagly-header h3 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--triagly-header-text, #111827);\n }\n\n .triagly-close {\n background: none;\n border: none;\n font-size: 28px;\n color: #6b7280;\n cursor: pointer;\n padding: 0;\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 6px;\n transition: all 0.2s;\n }\n\n .triagly-close:hover {\n background: #f3f4f6;\n color: #111827;\n }\n\n .triagly-form {\n padding: 24px;\n background: var(--triagly-form-bg, #ffffff);\n }\n\n .triagly-field {\n margin-bottom: 16px;\n }\n\n .triagly-field label {\n display: block;\n margin-bottom: 6px;\n font-size: 14px;\n font-weight: 500;\n color: var(--triagly-label-text, #374151);\n }\n\n .triagly-field input,\n .triagly-field textarea {\n width: 100%;\n padding: 10px 12px;\n background: var(--triagly-input-bg, #ffffff);\n border: 1px solid var(--triagly-input-border, #d1d5db);\n border-radius: var(--triagly-input-radius, 6px);\n color: var(--triagly-input-text, #111827);\n font-size: 14px;\n font-family: inherit;\n transition: border-color 0.2s;\n box-sizing: border-box;\n }\n\n .triagly-field input:focus,\n .triagly-field textarea:focus {\n outline: none;\n border-color: var(--triagly-input-border-focus, #6366f1);\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);\n }\n\n .triagly-checkbox label {\n display: flex;\n align-items: center;\n gap: 8px;\n cursor: pointer;\n font-weight: 400;\n }\n\n .triagly-checkbox label span {\n user-select: none;\n }\n\n .triagly-checkbox input {\n width: 16px;\n height: 16px;\n margin: 0;\n cursor: pointer;\n }\n\n /* Focus visible styles for accessibility */\n .triagly-button:focus-visible,\n .triagly-field input:focus-visible,\n .triagly-field textarea:focus-visible,\n .triagly-checkbox input:focus-visible,\n .triagly-btn-primary:focus-visible,\n .triagly-btn-secondary:focus-visible,\n .triagly-close:focus-visible {\n outline: 2px solid #6366f1;\n outline-offset: 2px;\n }\n\n /* Checkbox label gets visual indicator when checkbox is focused */\n .triagly-checkbox input:focus-visible + span {\n text-decoration: underline;\n }\n\n .triagly-turnstile {\n display: flex;\n justify-content: center;\n margin: 8px 0;\n }\n\n .triagly-actions {\n display: flex;\n gap: 12px;\n margin-top: 24px;\n }\n\n .triagly-btn-primary,\n .triagly-btn-secondary {\n flex: 1;\n padding: 10px 16px;\n border-radius: var(--triagly-btn-radius, 6px);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s;\n border: none;\n }\n\n .triagly-btn-primary {\n background: var(--triagly-btn-primary-bg, #6366f1);\n color: var(--triagly-btn-primary-text, #ffffff);\n }\n\n .triagly-btn-primary:hover:not(:disabled) {\n background: var(--triagly-btn-primary-bg-hover, #4f46e5);\n }\n\n .triagly-btn-primary:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .triagly-btn-secondary {\n background: var(--triagly-btn-secondary-bg, #f3f4f6);\n color: var(--triagly-btn-secondary-text, #374151);\n }\n\n .triagly-btn-secondary:hover {\n background: var(--triagly-btn-secondary-bg-hover, #e5e7eb);\n }\n\n .triagly-status {\n margin-top: 16px;\n padding: 12px;\n border-radius: 6px;\n font-size: 14px;\n display: none;\n }\n\n .triagly-status.triagly-success {\n display: block;\n background: var(--triagly-success-bg, #d1fae5);\n color: var(--triagly-success-text, #065f46);\n }\n\n .triagly-status.triagly-error {\n display: block;\n background: var(--triagly-error-bg, #fee2e2);\n color: var(--triagly-error-text, #991b1b);\n }\n `;\n\n document.head.appendChild(style);\n }\n\n /**\n * Set up keyboard event handlers\n */\n private setupKeyboardEvents(): void {\n const handleKeyDown = (e: KeyboardEvent) => {\n // Close on Escape key\n if (e.key === 'Escape' && this.isOpen) {\n e.preventDefault();\n this.close('dismiss');\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n \n // Store handler for cleanup\n if (this.container) {\n (this.container as any)._keydownHandler = handleKeyDown;\n }\n }\n\n /**\n * Set up focus trap to keep focus within modal\n */\n private setupFocusTrap(): void {\n if (!this.container) return;\n\n // Get all focusable elements\n const modal = this.container.querySelector('.triagly-modal');\n if (!modal) return;\n\n const focusableSelector =\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])';\n this.focusableElements = Array.from(\n modal.querySelectorAll(focusableSelector)\n ) as HTMLElement[];\n\n if (this.focusableElements.length === 0) {\n console.warn('Triagly: No focusable elements found in modal');\n return;\n }\n\n // Handle Tab key to trap focus - must prevent default BEFORE focus moves\n const handleTab = (e: Event) => {\n const keyEvent = e as KeyboardEvent;\n if (keyEvent.key !== 'Tab') return;\n\n // Only handle if focus is within our modal\n if (!this.container?.contains(document.activeElement)) return;\n\n const firstFocusable = this.focusableElements[0];\n const lastFocusable = this.focusableElements[this.focusableElements.length - 1];\n\n if (keyEvent.shiftKey) {\n // Shift + Tab - moving backwards\n if (document.activeElement === firstFocusable) {\n keyEvent.preventDefault();\n lastFocusable?.focus();\n }\n } else {\n // Tab - moving forwards\n if (document.activeElement === lastFocusable) {\n keyEvent.preventDefault();\n firstFocusable?.focus();\n }\n }\n };\n\n // Use capture phase to intercept Tab before browser handles it\n document.addEventListener('keydown', handleTab as EventListener, true);\n (this.container as any)._tabHandler = handleTab;\n }\n\n /**\n * Destroy the widget\n */\n destroy(): void {\n // Clean up event listeners\n if (this.container) {\n const keydownHandler = (this.container as any)._keydownHandler;\n if (keydownHandler) {\n document.removeEventListener('keydown', keydownHandler);\n }\n\n const tabHandler = (this.container as any)._tabHandler;\n if (tabHandler) {\n document.removeEventListener('keydown', tabHandler, true);\n }\n }\n\n this.close();\n document.getElementById('triagly-button')?.remove();\n document.getElementById('triagly-styles')?.remove();\n }\n}\n","// API Client\n\nimport {\n FeedbackData,\n FeedbackMetadata,\n FeedbackResponse,\n} from './types';\n\nconst DEFAULT_API_URL = 'https://sypkjlwfyvyuqnvzkaxb.supabase.co/functions/v1';\n\nexport class TriaglyAPI {\n private apiUrl: string;\n private publishableKey: string;\n private getToken?: () => Promise<string>;\n private turnstileSiteKey?: string;\n\n constructor(\n publishableKey: string,\n apiUrl?: string,\n getToken?: () => Promise<string>,\n turnstileSiteKey?: string\n ) {\n this.apiUrl = (apiUrl || DEFAULT_API_URL).replace(/\\/$/, ''); // Remove trailing slash\n this.publishableKey = publishableKey;\n this.getToken = getToken;\n this.turnstileSiteKey = turnstileSiteKey;\n }\n\n /**\n * Get Turnstile token from widget if available\n */\n private async getTurnstileToken(): Promise<string | null> {\n // Check if Turnstile widget is available\n const turnstileWidget = document.querySelector('[data-turnstile-response]');\n if (turnstileWidget) {\n const token = turnstileWidget.getAttribute('data-turnstile-response');\n if (token) return token;\n }\n\n // Check if window.turnstile is available\n if ((window as any).turnstile) {\n try {\n // Get the first widget's response\n const widgets = document.querySelectorAll('.cf-turnstile');\n if (widgets.length > 0) {\n const widgetId = widgets[0].getAttribute('data-widget-id');\n if (widgetId) {\n const token = (window as any).turnstile.getResponse(widgetId);\n if (token) return token;\n }\n }\n } catch (error) {\n console.warn('Failed to get Turnstile token:', error);\n }\n }\n\n return null;\n }\n\n /**\n * Submit feedback with new authentication\n */\n async submitFeedback(\n data: FeedbackData,\n metadata: FeedbackMetadata,\n turnstileToken?: string\n ): Promise<FeedbackResponse> {\n // Get Turnstile token if not provided\n if (!turnstileToken) {\n turnstileToken = await this.getTurnstileToken() || undefined;\n }\n\n // Only require Turnstile if configured\n if (this.turnstileSiteKey && !turnstileToken) {\n throw new Error('Turnstile verification required. Please complete the captcha.');\n }\n\n // Get hardened token if callback is provided\n let hardenedToken: string | undefined;\n if (this.getToken) {\n try {\n hardenedToken = await this.getToken();\n } catch (error) {\n console.error('Failed to get hardened token:', error);\n throw new Error('Failed to authenticate. Please try again.');\n }\n }\n\n const payload = {\n publishableKey: this.publishableKey,\n title: data.title,\n description: data.description,\n metadata: {\n ...metadata,\n consoleLogs: data.consoleLogs,\n },\n tags: data.tags,\n screenshot: data.screenshot,\n reporterEmail: data.reporterEmail,\n reporterName: data.reporterName,\n turnstileToken,\n hardenedToken,\n };\n\n const response = await fetch(`${this.apiUrl}/feedback`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({ error: 'Unknown error', message: 'Unknown error' }));\n\n // Handle specific error types with user-friendly messages\n if (response.status === 401) {\n if (error.error === 'invalid_publishable_key') {\n throw new Error('Invalid API key. Please contact support.');\n } else if (error.error === 'token_required') {\n throw new Error('Authentication required. Please refresh and try again.');\n }\n throw new Error(error.message || 'Authentication failed');\n } else if (response.status === 403) {\n if (error.error === 'origin_not_allowed') {\n throw new Error('This website is not authorized to submit feedback.');\n }\n throw new Error(error.message || 'Access denied');\n } else if (response.status === 429) {\n const retryAfter = response.headers.get('Retry-After');\n const resetTime = retryAfter ? `in ${retryAfter} seconds` : 'later';\n throw new Error(`Too many requests. Please try again ${resetTime}.`);\n } else if (response.status === 400 && error.error === 'captcha_failed') {\n throw new Error('Captcha verification failed. Please try again.');\n }\n\n throw new Error(error.message || error.error || `Failed to submit feedback (HTTP ${response.status})`);\n }\n\n return await response.json();\n }\n}\n","// Utility functions\n\nimport { FeedbackMetadata } from './types';\n\n/**\n * Collect browser and page metadata\n */\nexport function collectMetadata(customMetadata?: Record<string, any>): FeedbackMetadata {\n const viewport = `${window.innerWidth}x${window.innerHeight}`;\n const browser = detectBrowser();\n\n return {\n url: window.location.href,\n browser,\n viewport,\n userAgent: navigator.userAgent,\n timestamp: new Date().toISOString(),\n ...customMetadata,\n };\n}\n\n/**\n * Detect browser name and version\n */\nfunction detectBrowser(): string {\n const ua = navigator.userAgent;\n let browser = 'Unknown';\n\n if (ua.includes('Firefox/')) {\n const version = ua.match(/Firefox\\/(\\d+)/)?.[1];\n browser = `Firefox ${version}`;\n } else if (ua.includes('Chrome/') && !ua.includes('Edg')) {\n const version = ua.match(/Chrome\\/(\\d+)/)?.[1];\n browser = `Chrome ${version}`;\n } else if (ua.includes('Safari/') && !ua.includes('Chrome')) {\n const version = ua.match(/Version\\/(\\d+)/)?.[1];\n browser = `Safari ${version}`;\n } else if (ua.includes('Edg/')) {\n const version = ua.match(/Edg\\/(\\d+)/)?.[1];\n browser = `Edge ${version}`;\n }\n\n return browser;\n}\n\n/**\n * Capture screenshot of current page\n */\nexport async function captureScreenshot(): Promise<string | null> {\n try {\n // Use html2canvas library if available\n if (typeof (window as any).html2canvas !== 'undefined') {\n const canvas = await (window as any).html2canvas(document.body, {\n logging: false,\n useCORS: true,\n allowTaint: true,\n });\n return canvas.toDataURL('image/png');\n }\n\n // Fallback to native screenshot API if supported (limited browser support)\n if ('mediaDevices' in navigator && 'getDisplayMedia' in navigator.mediaDevices) {\n // This requires user interaction and shows a permission dialog\n // Not ideal for automatic screenshots\n console.warn('Screenshot capture requires html2canvas library');\n return null;\n }\n\n return null;\n } catch (error) {\n console.error('Screenshot capture failed:', error);\n return null;\n }\n}\n\n/**\n * Simple rate limiter using localStorage\n */\nexport class RateLimiter {\n private key: string;\n private maxAttempts: number;\n private windowMs: number;\n\n constructor(key: string, maxAttempts: number = 3, windowMs: number = 5 * 60 * 1000) {\n this.key = `triagly_ratelimit_${key}`;\n this.maxAttempts = maxAttempts;\n this.windowMs = windowMs;\n }\n\n canProceed(): boolean {\n const now = Date.now();\n const data = this.getData();\n\n // Filter out old attempts\n const recentAttempts = data.attempts.filter(\n (timestamp) => now - timestamp < this.windowMs\n );\n\n if (recentAttempts.length >= this.maxAttempts) {\n return false;\n }\n\n return true;\n }\n\n recordAttempt(): void {\n const now = Date.now();\n const data = this.getData();\n\n // Add new attempt\n data.attempts.push(now);\n\n // Keep only recent attempts\n data.attempts = data.attempts.filter(\n (timestamp) => now - timestamp < this.windowMs\n );\n\n this.setData(data);\n }\n\n getTimeUntilReset(): number {\n const now = Date.now();\n const data = this.getData();\n\n if (data.attempts.length === 0) {\n return 0;\n }\n\n const oldestAttempt = Math.min(...data.attempts);\n const resetTime = oldestAttempt + this.windowMs;\n\n return Math.max(0, resetTime - now);\n }\n\n private getData(): { attempts: number[] } {\n try {\n const stored = localStorage.getItem(this.key);\n return stored ? JSON.parse(stored) : { attempts: [] };\n } catch {\n return { attempts: [] };\n }\n }\n\n private setData(data: { attempts: number[] }): void {\n try {\n localStorage.setItem(this.key, JSON.stringify(data));\n } catch (error) {\n console.error('Failed to store rate limit data:', error);\n }\n }\n}\n\n/**\n * Generate unique ID\n */\nexport function generateId(): string {\n return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n}\n\n/**\n * Console log capture for debugging\n */\nexport interface ConsoleLog {\n level: 'error' | 'warn' | 'log';\n message: string;\n timestamp: string;\n stack?: string;\n}\n\nexport class ConsoleLogger {\n private buffer: ConsoleLog[] = [];\n private maxLogs: number;\n private levels: Set<'error' | 'warn' | 'log'>;\n private originalConsole: {\n error: typeof console.error;\n warn: typeof console.warn;\n log: typeof console.log;\n };\n private isActive: boolean = false;\n\n constructor(maxLogs: number = 50, levels: ('error' | 'warn' | 'log')[] = ['error', 'warn']) {\n this.maxLogs = maxLogs;\n this.levels = new Set(levels);\n \n // Store original console methods\n this.originalConsole = {\n error: console.error,\n warn: console.warn,\n log: console.log,\n };\n }\n\n /**\n * Start capturing console logs\n */\n start(): void {\n if (this.isActive) return;\n this.isActive = true;\n\n // Intercept console.error\n if (this.levels.has('error')) {\n console.error = (...args: any[]) => {\n this.captureLog('error', args);\n this.originalConsole.error.apply(console, args);\n };\n }\n\n // Intercept console.warn\n if (this.levels.has('warn')) {\n console.warn = (...args: any[]) => {\n this.captureLog('warn', args);\n this.originalConsole.warn.apply(console, args);\n };\n }\n\n // Intercept console.log\n if (this.levels.has('log')) {\n console.log = (...args: any[]) => {\n this.captureLog('log', args);\n this.originalConsole.log.apply(console, args);\n };\n }\n }\n\n /**\n * Stop capturing and restore original console methods\n */\n stop(): void {\n if (!this.isActive) return;\n this.isActive = false;\n\n console.error = this.originalConsole.error;\n console.warn = this.originalConsole.warn;\n console.log = this.originalConsole.log;\n }\n\n /**\n * Capture a log entry\n */\n private captureLog(level: 'error' | 'warn' | 'log', args: any[]): void {\n try {\n // Convert arguments to string\n const message = args.map(arg => {\n if (typeof arg === 'string') return arg;\n if (arg instanceof Error) return arg.message;\n try {\n return JSON.stringify(arg);\n } catch {\n return String(arg);\n }\n }).join(' ');\n\n // Get stack trace for errors\n let stack: string | undefined;\n if (level === 'error') {\n const error = args.find(arg => arg instanceof Error);\n if (error) {\n stack = error.stack;\n } else {\n // Create stack trace\n stack = new Error().stack?.split('\\n').slice(2).join('\\n');\n }\n }\n\n // Sanitize sensitive data\n const sanitized = this.sanitize(message);\n const sanitizedStack = stack ? this.sanitize(stack) : undefined;\n\n // Add to buffer\n const logEntry: ConsoleLog = {\n level,\n message: sanitized,\n timestamp: new Date().toISOString(),\n stack: sanitizedStack,\n };\n\n this.buffer.push(logEntry);\n\n // Keep buffer size limited (circular buffer)\n if (this.buffer.length > this.maxLogs) {\n this.buffer.shift();\n }\n } catch (error) {\n // Don't let logging break the app\n this.originalConsole.error('Failed to capture log:', error);\n }\n }\n\n /**\n * Sanitize sensitive data from logs\n */\n private sanitize(text: string): string {\n return text\n // API keys, tokens, secrets\n .replace(/[a-zA-Z0-9_-]*token[a-zA-Z0-9_-]*\\s*[:=]\\s*[\"']?[\\w-]{20,}[\"']?/gi, 'token=***')\n .replace(/[a-zA-Z0-9_-]*key[a-zA-Z0-9_-]*\\s*[:=]\\s*[\"']?[\\w-]{20,}[\"']?/gi, 'key=***')\n .replace(/[a-zA-Z0-9_-]*secret[a-zA-Z0-9_-]*\\s*[:=]\\s*[\"']?[\\w-]{20,}[\"']?/gi, 'secret=***')\n // GitHub tokens (ghp_, gho_, etc.)\n .replace(/gh[ps]_[a-zA-Z0-9]{36,}/g, 'gh*_***')\n // JWT tokens\n .replace(/eyJ[a-zA-Z0-9_-]+\\.[a-zA-Z0-9_-]+\\.[a-zA-Z0-9_-]+/g, 'jwt.***')\n // Passwords\n .replace(/password\\s*[:=]\\s*[\"']?[^\"'\\s]+[\"']?/gi, 'password=***')\n // Email addresses\n .replace(/\\b[\\w._%+-]+@[\\w.-]+\\.[a-zA-Z]{2,}\\b/g, '***@***.com')\n // Credit cards (basic pattern)\n .replace(/\\b\\d{4}[-\\s]?\\d{4}[-\\s]?\\d{4}[-\\s]?\\d{4}\\b/g, '****-****-****-****')\n // URLs with tokens in query params\n .replace(/([?&])(token|key|secret|auth)=[^&\\s]+/gi, '$1$2=***');\n }\n\n /**\n * Get all captured logs\n */\n getLogs(): ConsoleLog[] {\n return [...this.buffer];\n }\n\n /**\n * Clear all captured logs\n */\n clear(): void {\n this.buffer = [];\n }\n\n /**\n * Get logs count\n */\n getCount(): number {\n return this.buffer.length;\n }\n}\n","// Triagly SDK Main Entry Point\n\nimport { TriaglyConfig, FeedbackData } from './types';\nimport { FeedbackWidget } from './ui';\nimport { TriaglyAPI } from './api';\nimport { collectMetadata, captureScreenshot, RateLimiter, ConsoleLogger } from './utils';\n\nexport class Triagly {\n private config: TriaglyConfig;\n private widget: FeedbackWidget;\n private api: TriaglyAPI;\n private rateLimiter: RateLimiter;\n private consoleLogger: ConsoleLogger | null = null;\n\n constructor(config: TriaglyConfig) {\n // Handle backward compatibility - support multiple key names\n let apiKey = config.apiKey || config.publishableKey;\n\n if (!apiKey && config.projectId) {\n console.warn(\n 'Triagly: projectId is deprecated. Please use apiKey instead. ' +\n 'See migration guide: https://docs.triagly.com/sdk/migration'\n );\n apiKey = config.projectId;\n }\n\n if (!apiKey) {\n throw new Error('Triagly: apiKey is required. Get yours at https://triagly.com/dashboard');\n }\n\n this.config = {\n theme: 'auto',\n position: 'bottom-right',\n buttonShape: 'rounded',\n buttonText: '🐛 Feedback',\n placeholderText: 'Describe what happened...',\n successMessage: 'Feedback sent successfully!',\n errorMessage: 'Failed to send feedback. Please try again.',\n captureConsole: true,\n consoleLogLimit: 50,\n consoleLogLevels: ['error', 'warn'],\n ...config,\n apiKey,\n publishableKey: apiKey, // Keep for backward compatibility\n };\n\n this.api = new TriaglyAPI(\n apiKey,\n this.config.apiUrl,\n this.config.getToken,\n this.config.turnstileSiteKey\n );\n this.widget = new FeedbackWidget(this.config);\n this.rateLimiter = new RateLimiter(apiKey, 3, 5 * 60 * 1000);\n\n // Initialize console logger if enabled\n if (this.config.captureConsole !== false) {\n this.consoleLogger = new ConsoleLogger(\n this.config.consoleLogLimit,\n this.config.consoleLogLevels\n );\n this.consoleLogger.start();\n }\n\n this.init();\n }\n\n /**\n * Initialize the SDK\n */\n private init(): void {\n // Initialize widget\n this.widget.init();\n\n // Listen for form submissions\n document.addEventListener('triagly:submit', (e: Event) => {\n const customEvent = e as CustomEvent;\n this.handleSubmit(customEvent.detail);\n });\n }\n\n /**\n * Handle feedback submission\n */\n private async handleSubmit(data: any): Promise<void> {\n try {\n // Check rate limit\n if (!this.rateLimiter.canProceed()) {\n const resetTime = Math.ceil(this.rateLimiter.getTimeUntilReset() / 1000 / 60);\n throw new Error(`Rate limit exceeded. Please try again in ${resetTime} minute(s).`);\n }\n\n // Collect metadata\n const metadata = collectMetadata(this.config.metadata);\n\n // Capture screenshot if requested\n let screenshot: string | null = null;\n if (data.includeScreenshot) {\n screenshot = await captureScreenshot();\n }\n\n // Prepare feedback data\n const feedbackData: FeedbackData = {\n title: data.title,\n description: data.description,\n reporterEmail: data.reporterEmail,\n screenshot: screenshot || undefined,\n consoleLogs: this.consoleLogger?.getLogs(),\n };\n\n // Submit to API with Turnstile token if provided\n const response = await this.api.submitFeedback(\n feedbackData,\n metadata,\n data.turnstileToken\n );\n\n // Record rate limit attempt\n this.rateLimiter.recordAttempt();\n\n // Dispatch success event for UI layer\n document.dispatchEvent(new CustomEvent('triagly:success', {\n detail: { feedbackId: response.id }\n }));\n\n // Call success callback\n if (this.config.onSuccess) {\n this.config.onSuccess(response.id);\n }\n\n console.log('Feedback submitted successfully:', response.id);\n } catch (error) {\n console.error('Failed to submit feedback:', error);\n\n // Dispatch error event for UI layer\n document.dispatchEvent(new CustomEvent('triagly:error', {\n detail: error\n }));\n\n // Call error callback\n if (this.config.onError && error instanceof Error) {\n this.config.onError(error);\n }\n\n throw error;\n }\n }\n\n /**\n * Programmatically open the feedback widget\n */\n open(): void {\n this.widget.open();\n }\n\n /**\n * Programmatically close the feedback widget\n */\n close(): void {\n this.widget.close();\n }\n\n /**\n * Submit feedback programmatically without UI\n * Note: When Turnstile is enabled, you must use the widget UI or provide a token\n */\n async submit(data: FeedbackData, turnstileToken?: string): Promise<void> {\n // Require Turnstile token if configured\n if (this.config.turnstileSiteKey && !turnstileToken) {\n throw new Error(\n 'Turnstile verification required. When Turnstile is enabled, you must:\\n' +\n '1. Use the widget UI (triagly.open()), or\\n' +\n '2. Implement Turnstile in your form and pass the token: triagly.submit(data, token)'\n );\n }\n\n const metadata = collectMetadata(this.config.metadata);\n\n // Include console logs if available and not already provided\n if (!data.consoleLogs && this.consoleLogger) {\n data.consoleLogs = this.consoleLogger.getLogs();\n }\n\n await this.api.submitFeedback(data, metadata, turnstileToken);\n this.rateLimiter.recordAttempt();\n }\n\n /**\n * Destroy the SDK instance\n */\n destroy(): void {\n this.widget.destroy();\n this.consoleLogger?.stop();\n document.removeEventListener('triagly:submit', () => {});\n }\n}\n\n// Export types\nexport * from './types';\n\n// Auto-initialize if config is in window\nif (typeof window !== 'undefined') {\n const globalConfig = (window as any).TriaglyConfig;\n if (globalConfig) {\n (window as any).triagly = new Triagly(globalConfig);\n }\n\n // Make Triagly class directly accessible as window.Triagly for UMD builds\n // This allows users to use: new Triagly({...}) instead of new Triagly.default({...})\n (window as any).Triagly = Triagly;\n}\n\n// Default export\nexport default Triagly;\n"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1196,15 +1196,15 @@
1196
1196
  class Triagly {
1197
1197
  constructor(config) {
1198
1198
  this.consoleLogger = null;
1199
- // Handle backward compatibility
1200
- let publishableKey = config.publishableKey;
1201
- if (!publishableKey && config.projectId) {
1202
- console.warn('Triagly: projectId is deprecated. Please use publishableKey instead. ' +
1199
+ // Handle backward compatibility - support multiple key names
1200
+ let apiKey = config.apiKey || config.publishableKey;
1201
+ if (!apiKey && config.projectId) {
1202
+ console.warn('Triagly: projectId is deprecated. Please use apiKey instead. ' +
1203
1203
  'See migration guide: https://docs.triagly.com/sdk/migration');
1204
- publishableKey = config.projectId;
1204
+ apiKey = config.projectId;
1205
1205
  }
1206
- if (!publishableKey) {
1207
- throw new Error('Triagly: publishableKey is required. Get yours at https://triagly.com/dashboard');
1206
+ if (!apiKey) {
1207
+ throw new Error('Triagly: apiKey is required. Get yours at https://triagly.com/dashboard');
1208
1208
  }
1209
1209
  this.config = {
1210
1210
  theme: 'auto',
@@ -1218,11 +1218,12 @@
1218
1218
  consoleLogLimit: 50,
1219
1219
  consoleLogLevels: ['error', 'warn'],
1220
1220
  ...config,
1221
- publishableKey,
1221
+ apiKey,
1222
+ publishableKey: apiKey, // Keep for backward compatibility
1222
1223
  };
1223
- this.api = new TriaglyAPI(this.config.publishableKey, this.config.apiUrl, this.config.getToken, this.config.turnstileSiteKey);
1224
+ this.api = new TriaglyAPI(apiKey, this.config.apiUrl, this.config.getToken, this.config.turnstileSiteKey);
1224
1225
  this.widget = new FeedbackWidget(this.config);
1225
- this.rateLimiter = new RateLimiter(this.config.publishableKey, 3, 5 * 60 * 1000);
1226
+ this.rateLimiter = new RateLimiter(apiKey, 3, 5 * 60 * 1000);
1226
1227
  // Initialize console logger if enabled
1227
1228
  if (this.config.captureConsole !== false) {
1228
1229
  this.consoleLogger = new ConsoleLogger(this.config.consoleLogLimit, this.config.consoleLogLevels);
@@ -1340,6 +1341,9 @@
1340
1341
  if (globalConfig) {
1341
1342
  window.triagly = new Triagly(globalConfig);
1342
1343
  }
1344
+ // Make Triagly class directly accessible as window.Triagly for UMD builds
1345
+ // This allows users to use: new Triagly({...}) instead of new Triagly.default({...})
1346
+ window.Triagly = Triagly;
1343
1347
  }
1344
1348
 
1345
1349
  exports.Triagly = Triagly;