@product7/feedback-sdk 1.1.7 → 1.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/feedback-sdk.js +226 -219
- package/dist/feedback-sdk.js.map +1 -1
- package/dist/feedback-sdk.min.js +1 -1
- package/dist/feedback-sdk.min.js.map +1 -1
- package/package.json +1 -1
- package/src/styles/styles.js +185 -187
- package/src/widgets/BaseWidget.js +24 -21
- package/src/widgets/ButtonWidget.js +19 -13
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feedback-sdk.min.js","sources":["../src/utils/errors.js","../src/core/APIService.js","../src/core/EventBus.js","../src/utils/helpers.js","../src/widgets/BaseWidget.js","../src/widgets/ButtonWidget.js","../src/widgets/InlineWidget.js","../src/widgets/SurveyWidget.js","../src/widgets/TabWidget.js","../src/widgets/WidgetFactory.js","../src/core/FeedbackSDK.js","../src/index.js","../src/styles/styles.js"],"sourcesContent":["export class SDKError extends Error {\n\tconstructor(message, cause) {\n\t\tsuper(message);\n\t\tthis.name = 'SDKError';\n\t\tthis.cause = cause;\n\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, SDKError);\n\t\t}\n\t}\n}\n\nexport class APIError extends Error {\n\tconstructor(status, message, response) {\n\t\tsuper(message);\n\t\tthis.name = 'APIError';\n\t\tthis.status = status;\n\t\tthis.response = response;\n\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, APIError);\n\t\t}\n\t}\n\n\tisNetworkError() {\n\t\treturn this.status === 0;\n\t}\n\n\tisClientError() {\n\t\treturn this.status >= 400 && this.status < 500;\n\t}\n\n\tisServerError() {\n\t\treturn this.status >= 500 && this.status < 600;\n\t}\n}\n\nexport class WidgetError extends Error {\n\tconstructor(message, widgetType, widgetId) {\n\t\tsuper(message);\n\t\tthis.name = 'WidgetError';\n\t\tthis.widgetType = widgetType;\n\t\tthis.widgetId = widgetId;\n\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, WidgetError);\n\t\t}\n\t}\n}\n\nexport class ConfigError extends Error {\n\tconstructor(message, configKey) {\n\t\tsuper(message);\n\t\tthis.name = 'ConfigError';\n\t\tthis.configKey = configKey;\n\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, ConfigError);\n\t\t}\n\t}\n}\n\nexport class ValidationError extends Error {\n\tconstructor(message, field, value) {\n\t\tsuper(message);\n\t\tthis.name = 'ValidationError';\n\t\tthis.field = field;\n\t\tthis.value = value;\n\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, ValidationError);\n\t\t}\n\t}\n}\n\nexport class ErrorHandler {\n\tconstructor(debug = false) {\n\t\tthis.debug = debug;\n\t}\n\n\thandle(error, context = '') {\n\t\tconst errorInfo = {\n\t\t\tname: error.name,\n\t\t\tmessage: error.message,\n\t\t\tcontext,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t};\n\n\t\tif (error instanceof APIError) {\n\t\t\terrorInfo.status = error.status;\n\t\t\terrorInfo.type = 'api';\n\t\t} else if (error instanceof WidgetError) {\n\t\t\terrorInfo.widgetType = error.widgetType;\n\t\t\terrorInfo.widgetId = error.widgetId;\n\t\t\terrorInfo.type = 'widget';\n\t\t} else if (error instanceof ConfigError) {\n\t\t\terrorInfo.configKey = error.configKey;\n\t\t\terrorInfo.type = 'config';\n\t\t} else if (error instanceof ValidationError) {\n\t\t\terrorInfo.field = error.field;\n\t\t\terrorInfo.value = error.value;\n\t\t\terrorInfo.type = 'validation';\n\t\t} else {\n\t\t\terrorInfo.type = 'unknown';\n\t\t}\n\n\t\tif (this.debug) {\n\t\t\tconsole.error('[FeedbackSDK Error]', errorInfo, error);\n\t\t} else {\n\t\t\tconsole.error('[FeedbackSDK Error]', error.message);\n\t\t}\n\n\t\treturn errorInfo;\n\t}\n\n\tgetUserMessage(error) {\n\t\tif (error instanceof APIError) {\n\t\t\tif (error.isNetworkError()) {\n\t\t\t\treturn 'Network error. Please check your connection and try again.';\n\t\t\t} else if (error.isClientError()) {\n\t\t\t\treturn 'Invalid request. Please check your input and try again.';\n\t\t\t} else if (error.isServerError()) {\n\t\t\t\treturn 'Server error. Please try again later.';\n\t\t\t}\n\t\t\treturn 'Failed to submit feedback. Please try again.';\n\t\t}\n\n\t\tif (error instanceof ValidationError) {\n\t\t\treturn `Please check your ${error.field}: ${error.message}`;\n\t\t}\n\n\t\tif (error instanceof ConfigError) {\n\t\t\treturn 'Configuration error. Please check your SDK setup.';\n\t\t}\n\n\t\tif (error instanceof WidgetError) {\n\t\t\treturn 'Widget error. Please try refreshing the page.';\n\t\t}\n\n\t\treturn 'An unexpected error occurred. Please try again.';\n\t}\n}\n","import { APIError } from '../utils/errors.js';\n\nconst MOCK_CONFIG = {\n\tprimaryColor: '#21244A',\n\tbackgroundColor: '#ffffff',\n\ttextColor: '#1F2937',\n\tboardId: 'feature-requests',\n\tsize: 'medium',\n\tdisplayMode: 'modal',\n};\n\nconst ENV_URLS = {\n\tproduction: {\n\t\tbase: 'https://api.product7.io/api/v1',\n\t\twithWorkspace: (workspace) => `https://${workspace}.api.product7.io/api/v1`,\n\t},\n\tstaging: {\n\t\tbase: 'https://staging.api.product7.io/api/v1',\n\t\twithWorkspace: (workspace) =>\n\t\t\t`https://${workspace}.staging.api.product7.io/api/v1`,\n\t},\n};\n\nexport class APIService {\n\tconstructor(config = {}) {\n\t\tthis.workspace = config.workspace;\n\t\tthis.sessionToken = null;\n\t\tthis.sessionExpiry = null;\n\t\tthis.userContext = config.userContext || null;\n\t\tthis.mock = config.mock || false;\n\t\tthis.env = config.env || 'production';\n\n\t\tif (config.apiUrl) {\n\t\t\tthis.baseURL = config.apiUrl;\n\t\t} else {\n\t\t\tconst envConfig = ENV_URLS[this.env] || ENV_URLS.production;\n\t\t\tthis.baseURL = this.workspace\n\t\t\t\t? envConfig.withWorkspace(this.workspace)\n\t\t\t\t: envConfig.base;\n\t\t}\n\n\t\tthis._loadStoredSession();\n\t}\n\n\tasync init(userContext = null) {\n\t\tif (userContext) {\n\t\t\tthis.userContext = userContext;\n\t\t}\n\n\t\tif (this.isSessionValid()) {\n\t\t\treturn { sessionToken: this.sessionToken };\n\t\t}\n\n\t\tif (!this.userContext || !this.workspace) {\n\t\t\tconst error = `Missing ${!this.workspace ? 'workspace' : 'user context'} for initialization`;\n\t\t\tthrow new APIError(400, error);\n\t\t}\n\n\t\t// Mock mode - return fake session\n\t\tif (this.mock) {\n\t\t\tthis.sessionToken = 'mock_session_' + Date.now();\n\t\t\tthis.sessionExpiry = new Date(Date.now() + 3600 * 1000);\n\t\t\tthis._storeSession();\n\t\t\treturn {\n\t\t\t\tsessionToken: this.sessionToken,\n\t\t\t\tconfig: MOCK_CONFIG,\n\t\t\t\texpiresIn: 3600,\n\t\t\t};\n\t\t}\n\n\t\tconst payload = {\n\t\t\tworkspace: this.workspace,\n\t\t\tuser: this.userContext,\n\t\t};\n\n\t\ttry {\n\t\t\tconst response = await this._makeRequest('/widget/init', {\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: JSON.stringify(payload),\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tthis.sessionToken = response.session_token;\n\t\t\tthis.sessionExpiry = new Date(Date.now() + response.expires_in * 1000);\n\t\t\tthis._storeSession();\n\n\t\t\treturn {\n\t\t\t\tsessionToken: this.sessionToken,\n\t\t\t\tconfig: response.config || {},\n\t\t\t\texpiresIn: response.expires_in,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tthrow new APIError(\n\t\t\t\terror.status || 500,\n\t\t\t\t`Failed to initialize widget: ${error.message}`,\n\t\t\t\terror.response\n\t\t\t);\n\t\t}\n\t}\n\n\tasync submitFeedback(feedbackData) {\n\t\tif (!this.isSessionValid()) {\n\t\t\tawait this.init();\n\t\t}\n\n\t\tif (!this.sessionToken) {\n\t\t\tthrow new APIError(401, 'No valid session token available');\n\t\t}\n\n\t\t// Mock mode - simulate success\n\t\tif (this.mock) {\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 500));\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: {\n\t\t\t\t\tid: 'mock_post_' + Date.now(),\n\t\t\t\t\ttitle: feedbackData.title,\n\t\t\t\t\tcontent: feedbackData.content,\n\t\t\t\t},\n\t\t\t\tmessage: 'Feedback submitted successfully!',\n\t\t\t};\n\t\t}\n\n\t\tconst payload = {\n\t\t\tboard:\n\t\t\t\tfeedbackData.board_id || feedbackData.board || feedbackData.boardId,\n\t\t\ttitle: feedbackData.title,\n\t\t\tcontent: feedbackData.content,\n\t\t\tattachments: feedbackData.attachments || [],\n\t\t};\n\n\t\ttry {\n\t\t\tconst response = await this._makeRequest('/widget/feedback', {\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: JSON.stringify(payload),\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\tAuthorization: `Bearer ${this.sessionToken}`,\n\t\t\t\t},\n\t\t\t});\n\n\t\t\treturn response;\n\t\t} catch (error) {\n\t\t\tif (error.status === 401) {\n\t\t\t\tthis.sessionToken = null;\n\t\t\t\tthis.sessionExpiry = null;\n\t\t\t\tawait this.init();\n\t\t\t\treturn this.submitFeedback(feedbackData);\n\t\t\t}\n\n\t\t\tthrow new APIError(\n\t\t\t\terror.status || 500,\n\t\t\t\t`Failed to submit feedback: ${error.message}`,\n\t\t\t\terror.response\n\t\t\t);\n\t\t}\n\t}\n\n\tisSessionValid() {\n\t\treturn (\n\t\t\tthis.sessionToken && this.sessionExpiry && new Date() < this.sessionExpiry\n\t\t);\n\t}\n\n\tsetUserContext(userContext) {\n\t\tthis.userContext = userContext;\n\t\tif (typeof localStorage !== 'undefined') {\n\t\t\tlocalStorage.setItem(\n\t\t\t\t'feedbackSDK_userContext',\n\t\t\t\tJSON.stringify(userContext)\n\t\t\t);\n\t\t}\n\t}\n\n\tgetUserContext() {\n\t\treturn this.userContext;\n\t}\n\n\tclearSession() {\n\t\tthis.sessionToken = null;\n\t\tthis.sessionExpiry = null;\n\t\tif (typeof localStorage !== 'undefined') {\n\t\t\tlocalStorage.removeItem('feedbackSDK_session');\n\t\t\tlocalStorage.removeItem('feedbackSDK_userContext');\n\t\t}\n\t}\n\n\t_storeSession() {\n\t\tif (typeof localStorage === 'undefined') return;\n\n\t\ttry {\n\t\t\tconst sessionData = {\n\t\t\t\ttoken: this.sessionToken,\n\t\t\t\texpiry: this.sessionExpiry.toISOString(),\n\t\t\t\tworkspace: this.workspace,\n\t\t\t};\n\t\t\tlocalStorage.setItem('feedbackSDK_session', JSON.stringify(sessionData));\n\t\t} catch (error) {\n\t\t\t// Silently fail if localStorage is not available\n\t\t}\n\t}\n\n\t_loadStoredSession() {\n\t\tif (typeof localStorage === 'undefined') return false;\n\n\t\ttry {\n\t\t\tconst stored = localStorage.getItem('feedbackSDK_session');\n\t\t\tif (!stored) return false;\n\n\t\t\tconst sessionData = JSON.parse(stored);\n\t\t\tthis.sessionToken = sessionData.token;\n\t\t\tthis.sessionExpiry = new Date(sessionData.expiry);\n\n\t\t\treturn this.isSessionValid();\n\t\t} catch (error) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tasync _makeRequest(endpoint, options = {}) {\n\t\tconst url = `${this.baseURL}${endpoint}`;\n\n\t\ttry {\n\t\t\tconst response = await fetch(url, options);\n\n\t\t\tif (!response.ok) {\n\t\t\t\tlet errorMessage = `HTTP ${response.status}`;\n\t\t\t\tlet responseData = null;\n\n\t\t\t\ttry {\n\t\t\t\t\tresponseData = await response.json();\n\t\t\t\t\terrorMessage =\n\t\t\t\t\t\tresponseData.message || responseData.error || errorMessage;\n\t\t\t\t} catch (e) {\n\t\t\t\t\terrorMessage = (await response.text()) || errorMessage;\n\t\t\t\t}\n\n\t\t\t\tthrow new APIError(response.status, errorMessage, responseData);\n\t\t\t}\n\n\t\t\tconst contentType = response.headers.get('content-type');\n\t\t\tif (contentType && contentType.includes('application/json')) {\n\t\t\t\treturn await response.json();\n\t\t\t}\n\n\t\t\treturn await response.text();\n\t\t} catch (error) {\n\t\t\tif (error instanceof APIError) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tthrow new APIError(0, error.message, null);\n\t\t}\n\t}\n}\n","export class EventBus {\n\tconstructor() {\n\t\tthis.events = new Map();\n\t}\n\n\ton(event, callback) {\n\t\tif (!this.events.has(event)) {\n\t\t\tthis.events.set(event, []);\n\t\t}\n\t\tthis.events.get(event).push(callback);\n\n\t\treturn () => this.off(event, callback);\n\t}\n\n\toff(event, callback) {\n\t\tconst callbacks = this.events.get(event);\n\t\tif (callbacks) {\n\t\t\tconst index = callbacks.indexOf(callback);\n\t\t\tif (index > -1) {\n\t\t\t\tcallbacks.splice(index, 1);\n\t\t\t}\n\t\t}\n\t}\n\n\temit(event, data) {\n\t\tconst callbacks = this.events.get(event);\n\t\tif (callbacks) {\n\t\t\tcallbacks.forEach((callback) => {\n\t\t\t\ttry {\n\t\t\t\t\tcallback(data);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error('[FeedbackSDK] Event callback error:', error);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tonce(event, callback) {\n\t\tconst unsubscribe = this.on(event, (data) => {\n\t\t\tcallback(data);\n\t\t\tunsubscribe();\n\t\t});\n\t\treturn unsubscribe;\n\t}\n\n\tclear() {\n\t\tthis.events.clear();\n\t}\n\n\tgetListenerCount(event) {\n\t\tconst callbacks = this.events.get(event);\n\t\treturn callbacks ? callbacks.length : 0;\n\t}\n}\n","export function generateId(prefix = 'feedback') {\n\tconst timestamp = Date.now();\n\tconst random = Math.random().toString(36).substring(2, 9);\n\treturn `${prefix}_${timestamp}_${random}`;\n}\n\nexport function deepMerge(target, source) {\n\tconst result = { ...target };\n\n\tfor (const key in source) {\n\t\tif (source.hasOwnProperty(key)) {\n\t\t\tif (\n\t\t\t\tsource[key] &&\n\t\t\t\ttypeof source[key] === 'object' &&\n\t\t\t\t!Array.isArray(source[key])\n\t\t\t) {\n\t\t\t\tresult[key] = deepMerge(target[key] || {}, source[key]);\n\t\t\t} else {\n\t\t\t\tresult[key] = source[key];\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result;\n}\n\nexport function debounce(func, wait) {\n\tlet timeout;\n\treturn function executedFunction(...args) {\n\t\tconst later = () => {\n\t\t\tclearTimeout(timeout);\n\t\t\tfunc(...args);\n\t\t};\n\t\tclearTimeout(timeout);\n\t\ttimeout = setTimeout(later, wait);\n\t};\n}\n\nexport function throttle(func, limit) {\n\tlet lastFunc;\n\tlet lastRan;\n\treturn function (...args) {\n\t\tif (!lastRan) {\n\t\t\tfunc(...args);\n\t\t\tlastRan = Date.now();\n\t\t} else {\n\t\t\tclearTimeout(lastFunc);\n\t\t\tlastFunc = setTimeout(\n\t\t\t\t() => {\n\t\t\t\t\tif (Date.now() - lastRan >= limit) {\n\t\t\t\t\t\tfunc(...args);\n\t\t\t\t\t\tlastRan = Date.now();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tlimit - (Date.now() - lastRan)\n\t\t\t);\n\t\t}\n\t};\n}\n\nexport function isValidEmail(email) {\n\tif (!email || typeof email !== 'string') return false;\n\n\tconst emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\treturn emailRegex.test(email.trim());\n}\n\nexport function sanitizeHTML(str) {\n\tif (!str || typeof str !== 'string') return '';\n\n\tconst div = document.createElement('div');\n\tdiv.textContent = str;\n\treturn div.innerHTML;\n}\n\nexport function getCSSProperty(element, property, fallback = '') {\n\tif (!element || !property) return fallback;\n\n\ttry {\n\t\tconst style = window.getComputedStyle(element);\n\t\treturn style.getPropertyValue(property) || fallback;\n\t} catch (error) {\n\t\treturn fallback;\n\t}\n}\n\nexport function isInViewport(element) {\n\tif (!element) return false;\n\n\tconst rect = element.getBoundingClientRect();\n\treturn (\n\t\trect.top >= 0 &&\n\t\trect.left >= 0 &&\n\t\trect.bottom <=\n\t\t\t(window.innerHeight || document.documentElement.clientHeight) &&\n\t\trect.right <= (window.innerWidth || document.documentElement.clientWidth)\n\t);\n}\n\nexport function scrollToElement(element, options = {}) {\n\tif (!element) return;\n\n\tconst defaultOptions = {\n\t\tbehavior: 'smooth',\n\t\tblock: 'center',\n\t\tinline: 'nearest',\n\t};\n\n\telement.scrollIntoView({ ...defaultOptions, ...options });\n}\n\nexport function getBrowserInfo() {\n\tconst userAgent = navigator.userAgent;\n\tconst platform = navigator.platform;\n\n\treturn {\n\t\tuserAgent,\n\t\tplatform,\n\t\tlanguage: navigator.language || navigator.userLanguage,\n\t\tcookieEnabled: navigator.cookieEnabled,\n\t\tscreenResolution: `${screen.width}x${screen.height}`,\n\t\twindowSize: `${window.innerWidth}x${window.innerHeight}`,\n\t\ttimezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n\t};\n}\n\nexport function formatFileSize(bytes) {\n\tif (bytes === 0) return '0 Bytes';\n\n\tconst k = 1024;\n\tconst sizes = ['Bytes', 'KB', 'MB', 'GB'];\n\tconst i = Math.floor(Math.log(bytes) / Math.log(k));\n\n\treturn parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n}\n\nexport function delay(ms) {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function safeJsonParse(str, fallback = null) {\n\ttry {\n\t\treturn JSON.parse(str);\n\t} catch (error) {\n\t\treturn fallback;\n\t}\n}\n\nexport function escapeRegex(string) {\n\treturn string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport function getNestedProperty(obj, path, defaultValue = undefined) {\n\tif (!obj || !path) return defaultValue;\n\n\tconst keys = path.split('.');\n\tlet current = obj;\n\n\tfor (const key of keys) {\n\t\tif (current === null || current === undefined || !(key in current)) {\n\t\t\treturn defaultValue;\n\t\t}\n\t\tcurrent = current[key];\n\t}\n\n\treturn current;\n}\n\nexport function setNestedProperty(obj, path, value) {\n\tif (!obj || !path) return obj;\n\n\tconst keys = path.split('.');\n\tconst lastKey = keys.pop();\n\tlet current = obj;\n\n\tfor (const key of keys) {\n\t\tif (!(key in current) || typeof current[key] !== 'object') {\n\t\t\tcurrent[key] = {};\n\t\t}\n\t\tcurrent = current[key];\n\t}\n\n\tcurrent[lastKey] = value;\n\treturn obj;\n}\n\nexport function isBrowser() {\n\treturn typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\nexport function isMobile() {\n\tif (!isBrowser()) return false;\n\n\treturn (\n\t\t/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(\n\t\t\tnavigator.userAgent\n\t\t) || window.innerWidth <= 768\n\t);\n}\n\nexport function getCurrentTimestamp() {\n\treturn new Date().toISOString();\n}\n\nexport function validateConfig(config, required = []) {\n\tconst missing = [];\n\n\tfor (const key of required) {\n\t\tif (!config[key]) {\n\t\t\tmissing.push(key);\n\t\t}\n\t}\n\n\tif (missing.length > 0) {\n\t\tthrow new Error(`Missing required configuration: ${missing.join(', ')}`);\n\t}\n\n\treturn true;\n}\n","export class BaseWidget {\n\tconstructor(options = {}) {\n\t\tthis.id = options.id;\n\t\tthis.sdk = options.sdk;\n\t\tthis.apiService = options.apiService;\n\t\tthis.type = options.type || 'base';\n\n\t\tthis.options = {\n\t\t\tcontainer: null,\n\t\t\tposition: this.sdk.config.position,\n\t\t\tboardId: this.sdk.config.boardId,\n\t\t\tdisplayMode: options.displayMode || 'panel',\n\t\t\tsize: options.size || 'medium',\n\t\t\tprimaryColor: options.primaryColor || '#21244A',\n\t\t\tbackgroundColor: options.backgroundColor || '#ffffff',\n\t\t\ttextColor: options.textColor || '#1F2937',\n\t\t\tautoShow: false,\n\t\t\tshowBackdrop: true,\n\t\t\tcustomStyles: {},\n\t\t\t...options,\n\t\t};\n\n\t\tthis.element = null;\n\t\tthis.panelElement = null;\n\t\tthis.backdropElement = null;\n\t\tthis.mounted = false;\n\t\tthis.destroyed = false;\n\n\t\tthis.state = {\n\t\t\tisOpen: false,\n\t\t\tisLoading: false,\n\t\t\tisSubmitting: false,\n\t\t\ttitle: '',\n\t\t\tcontent: '',\n\t\t\temail: '',\n\t\t\tattachments: [],\n\t\t\terrors: {},\n\t\t};\n\n\t\tthis._bindMethods();\n\t}\n\n\tmount(container) {\n\t\tif (this.mounted || this.destroyed) return this;\n\n\t\tif (typeof container === 'string') {\n\t\t\tcontainer = document.querySelector(container);\n\t\t}\n\n\t\tif (!container) {\n\t\t\tcontainer = document.body;\n\t\t}\n\n\t\tthis.container = container;\n\t\tthis.element = this._render();\n\t\tthis.container.appendChild(this.element);\n\n\t\tthis.mounted = true;\n\t\tthis._attachEvents();\n\t\tthis.onMount();\n\n\t\tif (this.options.autoShow) {\n\t\t\tthis.show();\n\t\t}\n\n\t\tthis.sdk.eventBus.emit('widget:mounted', { widget: this });\n\t\treturn this;\n\t}\n\n\tshow() {\n\t\tif (this.element) {\n\t\t\tthis.element.style.display = 'block';\n\t\t}\n\t\treturn this;\n\t}\n\n\thide() {\n\t\tif (this.element) {\n\t\t\tthis.element.style.display = 'none';\n\t\t}\n\t\treturn this;\n\t}\n\n\topenPanel() {\n\t\tthis.state.isOpen = true;\n\n\t\tif (this.options.displayMode === 'modal') {\n\t\t\tthis._showLoadingModal();\n\t\t\t// Simulate loading delay then show form\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis._hideLoadingModal();\n\t\t\t\tthis._renderPanel();\n\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\tif (this.panelElement) {\n\t\t\t\t\t\tthis.panelElement.classList.add('open');\n\t\t\t\t\t}\n\t\t\t\t\tif (this.backdropElement) {\n\t\t\t\t\t\tthis.backdropElement.classList.add('show');\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}, 600);\n\t\t} else {\n\t\t\tthis._renderPanel();\n\t\t\trequestAnimationFrame(() => {\n\t\t\t\tif (this.panelElement) {\n\t\t\t\t\tthis.panelElement.classList.add('open');\n\t\t\t\t}\n\t\t\t\tif (this.backdropElement) {\n\t\t\t\t\tthis.backdropElement.classList.add('show');\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\t_showLoadingModal() {\n\t\tthis.state.isLoading = true;\n\n\t\t// Create backdrop\n\t\tthis.backdropElement = document.createElement('div');\n\t\tthis.backdropElement.className = 'feedback-panel-backdrop';\n\t\tdocument.body.appendChild(this.backdropElement);\n\n\t\t// Create loading modal\n\t\tthis.loadingElement = document.createElement('div');\n\t\tthis.loadingElement.className = `feedback-loading-modal theme-${this.options.theme}`;\n\t\tthis.loadingElement.innerHTML = `\n\t\t\t<div class=\"feedback-loading-spinner\"></div>\n\t\t`;\n\t\tdocument.body.appendChild(this.loadingElement);\n\n\t\trequestAnimationFrame(() => {\n\t\t\tthis.backdropElement.classList.add('show');\n\t\t\tthis.loadingElement.classList.add('show');\n\t\t});\n\t}\n\n\t_hideLoadingModal() {\n\t\tthis.state.isLoading = false;\n\t\tif (this.loadingElement) {\n\t\t\tthis.loadingElement.remove();\n\t\t\tthis.loadingElement = null;\n\t\t}\n\t}\n\n\tclosePanel() {\n\t\tif (this.panelElement) {\n\t\t\tthis.panelElement.classList.remove('open');\n\t\t}\n\t\tif (this.backdropElement) {\n\t\t\tthis.backdropElement.classList.remove('show');\n\t\t}\n\n\t\tsetTimeout(() => {\n\t\t\tthis.state.isOpen = false;\n\t\t\tif (this.panelElement && this.panelElement.parentNode) {\n\t\t\t\tthis.panelElement.parentNode.removeChild(this.panelElement);\n\t\t\t\tthis.panelElement = null;\n\t\t\t}\n\t\t\tif (this.backdropElement && this.backdropElement.parentNode) {\n\t\t\t\tthis.backdropElement.parentNode.removeChild(this.backdropElement);\n\t\t\t\tthis.backdropElement = null;\n\t\t\t}\n\t\t\tthis._resetForm();\n\t\t}, 300);\n\t}\n\n\tasync submitFeedback() {\n\t\tif (this.state.isSubmitting) return;\n\n\t\tthis._hideError();\n\n\t\ttry {\n\t\t\tthis.state.isSubmitting = true;\n\t\t\tthis._updateSubmitButton();\n\n\t\t\tconst payload = {\n\t\t\t\ttitle: this.state.title || 'Feedback',\n\t\t\t\tcontent: this.state.content,\n\t\t\t\temail: this.state.email,\n\t\t\t\tboard_id: this.options.boardId,\n\t\t\t\tattachments: this.state.attachments,\n\t\t\t};\n\n\t\t\tif (!this.state.content.trim()) {\n\t\t\t\tthis._showError('Please enter your feedback message.');\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst response = await this.apiService.submitFeedback(payload);\n\n\t\t\tthis._showSuccessMessage();\n\t\t\tthis.closePanel();\n\n\t\t\tthis.sdk.eventBus.emit('feedback:submitted', {\n\t\t\t\twidget: this,\n\t\t\t\tfeedback: response,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthis._showError('Failed to submit feedback. Please try again.');\n\t\t\tthis.sdk.eventBus.emit('feedback:error', { widget: this, error });\n\t\t} finally {\n\t\t\tthis.state.isSubmitting = false;\n\t\t\tthis._updateSubmitButton();\n\t\t}\n\t}\n\n\thandleConfigUpdate(newConfig) {\n\t\tthis.options.theme = newConfig.theme;\n\t\tif (this.element) {\n\t\t\tthis._updateTheme();\n\t\t}\n\t}\n\n\tdestroy() {\n\t\tif (this.destroyed) return;\n\n\t\tthis.onDestroy();\n\t\tthis.closePanel();\n\n\t\tif (this.element && this.element.parentNode) {\n\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t}\n\n\t\tthis.destroyed = true;\n\t\tthis.mounted = false;\n\t\tthis.sdk.eventBus.emit('widget:destroyed', { widget: this });\n\t}\n\n\tonMount() {}\n\tonDestroy() {}\n\n\t_render() {\n\t\tthrow new Error('_render() must be implemented by concrete widget');\n\t}\n\n\t_attachEvents() {\n\t\t// Override in concrete widgets\n\t}\n\n\t_bindMethods() {\n\t\tthis.openPanel = this.openPanel.bind(this);\n\t\tthis.closePanel = this.closePanel.bind(this);\n\t\tthis.submitFeedback = this.submitFeedback.bind(this);\n\t}\n\n\t_renderPanel() {\n\t\tif (this.panelElement) return;\n\n\t\tif (this.options.showBackdrop && !this.backdropElement) {\n\t\t\tthis.backdropElement = document.createElement('div');\n\t\t\tthis.backdropElement.className = 'feedback-panel-backdrop';\n\t\t\tdocument.body.appendChild(this.backdropElement);\n\n\t\t\tthis.backdropElement.addEventListener('click', this.closePanel);\n\t\t}\n\n\t\tconst modeClass =\n\t\t\tthis.options.displayMode === 'modal'\n\t\t\t\t? 'feedback-modal'\n\t\t\t\t: 'feedback-panel';\n\t\tconst sizeClass = `size-${this.options.size}`;\n\t\tthis.panelElement = document.createElement('div');\n\t\tthis.panelElement.className = `${modeClass} ${sizeClass}`;\n\t\tthis.panelElement.style.setProperty(\n\t\t\t'--primary-color',\n\t\t\tthis.options.primaryColor\n\t\t);\n\t\tthis.panelElement.style.setProperty(\n\t\t\t'--bg-color',\n\t\t\tthis.options.backgroundColor\n\t\t);\n\t\tthis.panelElement.style.setProperty('--text-color', this.options.textColor);\n\t\tthis.panelElement.innerHTML = this._getPanelHTML();\n\n\t\tdocument.body.appendChild(this.panelElement);\n\t\tthis._attachPanelEvents();\n\n\t\tconst firstInput = this.panelElement.querySelector('input, textarea');\n\t\tif (firstInput) {\n\t\t\tsetTimeout(() => firstInput.focus(), 350);\n\t\t}\n\t}\n\n\t_getPanelHTML() {\n\t\treturn `\n <div class=\"feedback-panel-content\">\n <div class=\"feedback-panel-header\">\n <h3>Share Your Thoughts</h3>\n <button class=\"feedback-panel-close\" type=\"button\" aria-label=\"Close\">×</button>\n </div>\n <div class=\"feedback-panel-body\">\n <form class=\"feedback-form\">\n <div class=\"feedback-form-group\">\n <div class=\"feedback-input-container\">\n <input \n type=\"text\" \n id=\"feedback-title-${this.id}\" \n name=\"title\" \n placeholder=\"Title\"\n value=\"${this.state.title}\"\n />\n <textarea \n id=\"feedback-content-${this.id}\" \n name=\"content\" \n placeholder=\"Tell us what's on your mind...\"\n required\n >${this.state.content}</textarea>\n </div>\n </div>\n <div class=\"feedback-error\" role=\"alert\"></div>\n <div class=\"feedback-form-group\">\n <button type=\"submit\" class=\"feedback-btn feedback-btn-submit\">\n ${this.state.isSubmitting ? 'Sending...' : 'Submit Feedback'}\n </button>\n </div>\n </form>\n </div>\n </div>\n `;\n\t}\n\t_attachPanelEvents() {\n\t\tconst panel = this.panelElement;\n\n\t\tpanel\n\t\t\t.querySelector('.feedback-panel-close')\n\t\t\t.addEventListener('click', this.closePanel);\n\n\t\tconst form = panel.querySelector('.feedback-form');\n\t\tform.addEventListener('submit', (e) => {\n\t\t\te.preventDefault();\n\t\t\tthis.submitFeedback();\n\t\t});\n\n\t\tpanel\n\t\t\t.querySelector('input[name=\"title\"]')\n\t\t\t.addEventListener('input', (e) => {\n\t\t\t\tthis.state.title = e.target.value;\n\t\t\t});\n\n\t\tpanel\n\t\t\t.querySelector('textarea[name=\"content\"]')\n\t\t\t.addEventListener('input', (e) => {\n\t\t\t\tthis.state.content = e.target.value;\n\t\t\t});\n\n\t\tconst handleEscape = (e) => {\n\t\t\tif (e.key === 'Escape') {\n\t\t\t\tthis.closePanel();\n\t\t\t\tdocument.removeEventListener('keydown', handleEscape);\n\t\t\t}\n\t\t};\n\t\tdocument.addEventListener('keydown', handleEscape);\n\t}\n\n\t_updateSubmitButton() {\n\t\tif (this.panelElement) {\n\t\t\tconst submitBtn = this.panelElement.querySelector('.feedback-btn-submit');\n\t\t\tif (submitBtn) {\n\t\t\t\tsubmitBtn.textContent = this.state.isSubmitting\n\t\t\t\t\t? 'Sending...'\n\t\t\t\t\t: 'Send Feedback';\n\t\t\t\tsubmitBtn.disabled = this.state.isSubmitting;\n\t\t\t}\n\t\t}\n\t}\n\n\t_showError(message) {\n\t\tif (this.panelElement) {\n\t\t\tconst errorElement = this.panelElement.querySelector('.feedback-error');\n\t\t\tif (errorElement) {\n\t\t\t\terrorElement.textContent = message;\n\t\t\t\terrorElement.classList.add('show');\n\t\t\t}\n\t\t}\n\t}\n\n\t_hideError() {\n\t\tif (this.panelElement) {\n\t\t\tconst errorElement = this.panelElement.querySelector('.feedback-error');\n\t\t\tif (errorElement) {\n\t\t\t\terrorElement.classList.remove('show');\n\t\t\t}\n\t\t}\n\t}\n\n\t_showSuccessMessage() {\n\t\tconst notification = document.createElement('div');\n\t\tnotification.className = 'feedback-success-notification';\n\t\tnotification.innerHTML = `\n <div class=\"feedback-success-content\">\n <div class=\"feedback-success-icon\">✓</div>\n <span>Feedback submitted successfully!</span>\n <button class=\"feedback-success-close\" aria-label=\"Close\">×</button>\n </div>\n `;\n\n\t\tdocument.body.appendChild(notification);\n\n\t\tconst closeBtn = notification.querySelector('.feedback-success-close');\n\t\tconst closeNotification = () => {\n\t\t\tif (notification.parentNode) {\n\t\t\t\tnotification.style.opacity = '0';\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tif (notification.parentNode) {\n\t\t\t\t\t\tnotification.parentNode.removeChild(notification);\n\t\t\t\t\t}\n\t\t\t\t}, 300);\n\t\t\t}\n\t\t};\n\n\t\tcloseBtn.addEventListener('click', closeNotification);\n\n\t\tsetTimeout(closeNotification, 4000);\n\t}\n\n\t_resetForm() {\n\t\tthis.state.title = '';\n\t\tthis.state.content = '';\n\t\tthis.state.email = '';\n\t\tthis.state.errors = {};\n\t}\n\n\t_updateTheme() {\n\t\tif (this.element) {\n\t\t\tthis.element.className = this.element.className.replace(\n\t\t\t\t/theme-\\w+/,\n\t\t\t\t`theme-${this.options.theme}`\n\t\t\t);\n\t\t}\n\t\tif (this.panelElement) {\n\t\t\tthis.panelElement.className = this.panelElement.className.replace(\n\t\t\t\t/theme-\\w+/,\n\t\t\t\t`theme-${this.options.theme}`\n\t\t\t);\n\t\t}\n\t}\n\n\topenModal() {\n\t\tthis.openPanel();\n\t}\n\n\tcloseModal() {\n\t\tthis.closePanel();\n\t}\n}\n","import { BaseWidget } from './BaseWidget.js';\n\nexport class ButtonWidget extends BaseWidget {\n\tconstructor(options) {\n\t\tsuper({ ...options, type: 'button' });\n\t}\n\n\t_render() {\n\t\tconst button = document.createElement('div');\n\t\tbutton.className = `feedback-widget feedback-widget-button theme-${this.options.theme} position-${this.options.position}`;\n\t\tbutton.innerHTML = `\n <button class=\"feedback-trigger-btn\" type=\"button\" aria-label=\"Send feedback\">\n <svg width=\"28\" height=\"32\" viewBox=\"0 0 28 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M15.0615 5.28044C8.5161 4.42949 3.30825 11.1456 5.89967 17.6588C6.9321 20.2538 9.06268 22.2644 11.8777 23.1968C16.2682 24.6507 18.4038 22.3222 19.0483 23.9691C19.4055 24.8894 18.7282 25.3209 17.988 25.4938C10.9146 27.15 5.15304 22.7566 3.5869 17.5531C1.52205 10.6941 5.98684 4.6667 11.3483 3.41065C17.8801 1.88094 24.0325 6.19355 24.3926 12.7175C24.7448 19.0921 18.6217 24.5978 11.927 22.2036C10.8789 21.8285 8.8419 20.6682 8.46823 19.858C8.06026 18.9727 8.80261 18.1725 9.68285 18.3576C10.2223 18.4726 10.3116 18.8706 11.3161 19.5372C14.4549 21.6213 19.1276 20.6132 21.2046 17.0972C23.991 12.3817 21.0481 6.05351 15.06 5.27758L15.0615 5.28044Z\" fill=\"#21244A\"/>\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M15.2492 2.19833C11.944 1.71463 8.88819 3.07214 6.91479 4.49682C2.27067 7.85488 0.76169 14.5038 3.49672 19.8731C4.08535 21.0096 4.84379 22.0497 5.7459 22.9576L7.16343 24.2515C7.67214 24.9131 7.27203 25.7176 6.64115 25.9269C5.13502 26.4271 2.0499 21.8172 1.42044 20.5383C0.0872204 17.8297 -0.312889 14.9047 0.242977 11.503C1.66908 2.77063 11.221 -2.51652 19.7197 1.21021C27.7548 4.73331 30.2733 15.4555 23.9351 22.0773C23.3107 22.7296 21.6352 24.4823 20.6278 23.8907C20.0076 23.5263 19.8933 22.6446 20.5192 22.1238C21.0301 21.6986 21.4759 21.435 21.9896 20.9734C23.6665 19.4688 25.2562 16.8752 25.3477 13.5636C25.4427 10.2055 24.1266 7.5848 22.3904 5.74859C20.6392 3.89665 18.6751 2.69919 15.2456 2.19691L15.2492 2.19833Z\" fill=\"#F69F06\"/>\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M8.48332 27.2217C7.93817 26.265 8.89987 25.3776 10.1352 25.8641C15.5653 27.9926 18.3081 25.5269 19.0255 27.0823C19.2655 27.6039 19.0448 28.1619 18.7354 28.3863C17.9895 28.9257 14.82 28.9343 13.9262 28.8714C12.9071 28.8053 11.897 28.6377 10.9111 28.3713C10.0888 28.1348 8.88057 27.9247 8.48189 27.2281L8.48332 27.2217Z\" fill=\"#21244A\"/>\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M15.8722 31.0607C15.7765 32.1381 14.579 32.0331 13.5766 31.9545C12.5742 31.8759 11.5203 31.8502 11.601 30.7013C11.6789 29.5882 12.8035 29.7532 13.8274 29.8332C14.4425 29.8811 15.9951 29.681 15.8722 31.0607Z\" fill=\"#21244A\"/>\n </svg>\n </button>\n `;\n\n\t\tif (this.options.customStyles) {\n\t\t\tObject.assign(button.style, this.options.customStyles);\n\t\t}\n\n\t\treturn button;\n\t}\n\t_attachEvents() {\n\t\tconst button = this.element.querySelector('.feedback-trigger-btn');\n\t\tbutton.addEventListener('click', this.openPanel);\n\n\t\tbutton.addEventListener('mouseenter', () => {\n\t\t\tif (!this.state.isSubmitting) {\n\t\t\t\tbutton.style.transform = 'scale(1.1)';\n\t\t\t}\n\t\t});\n\n\t\tbutton.addEventListener('mouseleave', () => {\n\t\t\tbutton.style.transform = 'scale(1)';\n\t\t});\n\t}\n\n\tupdateText(text) {\n\t\tconsole.warn('ButtonWidget: Text display is disabled for circular design');\n\t}\n\n\tupdatePosition(position) {\n\t\tthis.options.position = position;\n\t\tif (this.element) {\n\t\t\tthis.element.className = this.element.className.replace(\n\t\t\t\t/position-\\w+-\\w+/,\n\t\t\t\t`position-${position}`\n\t\t\t);\n\t\t}\n\t}\n}\n","import { BaseWidget } from './BaseWidget.js';\n\nexport class InlineWidget extends BaseWidget {\n\tconstructor(options) {\n\t\tsuper({ ...options, type: 'inline' });\n\t}\n\n\t_render() {\n\t\tconst widget = document.createElement('div');\n\t\twidget.className = `feedback-widget feedback-widget-inline theme-${this.options.theme}`;\n\t\twidget.innerHTML = `\n <div class=\"feedback-inline-content\">\n <h3>Send us your feedback</h3>\n <form class=\"feedback-inline-form\">\n <div class=\"feedback-form-group\">\n <input \n type=\"text\" \n name=\"title\" \n placeholder=\"Title (optional)\"\n value=\"${this.state.title}\"\n />\n </div>\n <div class=\"feedback-form-group\">\n <textarea \n name=\"content\" \n placeholder=\"Your feedback...\"\n required\n >${this.state.content}</textarea>\n </div>\n <div class=\"feedback-form-group\">\n <input \n type=\"email\" \n name=\"email\" \n placeholder=\"Email (optional)\"\n value=\"${this.state.email}\"\n />\n </div>\n <button type=\"submit\" class=\"feedback-btn feedback-btn-submit\">\n Send Feedback\n </button>\n <div class=\"feedback-error\" style=\"display: none;\"></div>\n </form>\n </div>\n `;\n\n\t\tif (this.options.customStyles) {\n\t\t\tObject.assign(widget.style, this.options.customStyles);\n\t\t}\n\n\t\treturn widget;\n\t}\n\n\t_attachEvents() {\n\t\tconst form = this.element.querySelector('.feedback-inline-form');\n\n\t\tform.addEventListener('submit', (e) => {\n\t\t\te.preventDefault();\n\t\t\tthis.submitFeedback();\n\t\t});\n\n\t\tform.querySelector('input[name=\"title\"]').addEventListener('input', (e) => {\n\t\t\tthis.state.title = e.target.value;\n\t\t});\n\n\t\tform\n\t\t\t.querySelector('textarea[name=\"content\"]')\n\t\t\t.addEventListener('input', (e) => {\n\t\t\t\tthis.state.content = e.target.value;\n\t\t\t});\n\n\t\tform.querySelector('input[name=\"email\"]').addEventListener('input', (e) => {\n\t\t\tthis.state.email = e.target.value;\n\t\t});\n\t}\n\n\topenModal() {\n\t\tconst textarea = this.element.querySelector('textarea[name=\"content\"]');\n\t\tif (textarea) {\n\t\t\ttextarea.focus();\n\t\t}\n\t}\n\n\tcloseModal() {\n\t\t// Inline widget doesn't use modal\n\t}\n\n\t_showSuccessMessage() {\n\t\tconst widget = this.element.querySelector('.feedback-inline-content');\n\t\tconst originalContent = widget.innerHTML;\n\n\t\twidget.innerHTML = `\n <div class=\"feedback-success\">\n <div class=\"feedback-success-icon\">✓</div>\n <h3>Thank you!</h3>\n <p>Your feedback has been submitted successfully.</p>\n <button class=\"feedback-btn feedback-btn-reset\">Send Another</button>\n </div>\n `;\n\n\t\tconst resetBtn = widget.querySelector('.feedback-btn-reset');\n\t\tresetBtn.addEventListener('click', () => {\n\t\t\twidget.innerHTML = originalContent;\n\t\t\tthis._attachEvents();\n\t\t\tthis._resetForm();\n\t\t});\n\t}\n\n\t_showError(message) {\n\t\tconst errorElement = this.element.querySelector('.feedback-error');\n\t\tif (errorElement) {\n\t\t\terrorElement.textContent = message;\n\t\t\terrorElement.style.display = 'block';\n\n\t\t\tsetTimeout(() => {\n\t\t\t\tif (errorElement) {\n\t\t\t\t\terrorElement.style.display = 'none';\n\t\t\t\t}\n\t\t\t}, 5000);\n\t\t}\n\t}\n\n\t_updateSubmitButton() {\n\t\tconst submitBtn = this.element.querySelector('.feedback-btn-submit');\n\t\tif (submitBtn) {\n\t\t\tsubmitBtn.textContent = this.state.isSubmitting\n\t\t\t\t? 'Sending...'\n\t\t\t\t: 'Send Feedback';\n\t\t\tsubmitBtn.disabled = this.state.isSubmitting;\n\t\t}\n\t}\n\n\tupdateTitle(title) {\n\t\tconst titleElement = this.element?.querySelector('h3');\n\t\tif (titleElement) {\n\t\t\ttitleElement.textContent = title;\n\t\t}\n\t}\n\n\tsetPlaceholder(field, placeholder) {\n\t\tconst input = this.element?.querySelector(`[name=\"${field}\"]`);\n\t\tif (input) {\n\t\t\tinput.placeholder = placeholder;\n\t\t}\n\t}\n}\n","import { BaseWidget } from './BaseWidget.js';\n\nexport class SurveyWidget extends BaseWidget {\n\tconstructor(options) {\n\t\tsuper({ ...options, type: 'survey' });\n\n\t\tthis.surveyOptions = {\n\t\t\tsurveyType: options.surveyType || 'nps', // 'nps', 'csat', 'ces', 'custom'\n\t\t\tposition: options.position || 'bottom-right', // 'bottom-right', 'bottom-left', 'center', 'bottom'\n\t\t\ttitle: options.title || null,\n\t\t\tdescription: options.description || null,\n\t\t\tlowLabel: options.lowLabel || null,\n\t\t\thighLabel: options.highLabel || null,\n\t\t\tcustomQuestions: options.customQuestions || [],\n\t\t\ttheme: options.theme || 'light',\n\t\t\tonSubmit: options.onSubmit || null,\n\t\t\tonDismiss: options.onDismiss || null,\n\t\t};\n\n\t\tthis.surveyState = {\n\t\t\tscore: null,\n\t\t\tfeedback: '',\n\t\t\tcustomAnswers: {},\n\t\t\tisVisible: false,\n\t\t};\n\t}\n\n\t_render() {\n\t\t// Survey widget doesn't render a trigger button, it's shown programmatically\n\t\tconst container = document.createElement('div');\n\t\tcontainer.className = 'feedback-survey-container';\n\t\tcontainer.style.display = 'none';\n\t\treturn container;\n\t}\n\n\t_attachEvents() {\n\t\t// Events are attached when survey is shown\n\t}\n\n\tshow() {\n\t\tthis._renderSurvey();\n\t\tthis.surveyState.isVisible = true;\n\t\tthis.sdk.eventBus.emit('survey:shown', {\n\t\t\twidget: this,\n\t\t\ttype: this.surveyOptions.surveyType,\n\t\t});\n\t\treturn this;\n\t}\n\n\thide() {\n\t\tthis._closeSurvey();\n\t\treturn this;\n\t}\n\n\t_renderSurvey() {\n\t\t// Remove any existing survey\n\t\tthis._closeSurvey();\n\n\t\tconst config = this._getSurveyConfig();\n\t\tconst positionStyles = this._getPositionStyles();\n\t\tconst themeStyles =\n\t\t\tthis.surveyOptions.theme === 'dark'\n\t\t\t\t? 'background: #1a1a1a; color: #fff;'\n\t\t\t\t: 'background: #fff; color: #1d1d1f;';\n\n\t\t// Create backdrop for center position\n\t\tif (this.surveyOptions.position === 'center') {\n\t\t\tthis.backdropElement = document.createElement('div');\n\t\t\tthis.backdropElement.className = 'feedback-survey-backdrop';\n\t\t\tdocument.body.appendChild(this.backdropElement);\n\t\t\tthis.backdropElement.addEventListener('click', () =>\n\t\t\t\tthis._handleDismiss()\n\t\t\t);\n\t\t}\n\n\t\tthis.surveyElement = document.createElement('div');\n\t\tthis.surveyElement.className = `feedback-survey feedback-survey-${this.surveyOptions.position} theme-${this.surveyOptions.theme}`;\n\t\tthis.surveyElement.style.cssText = `position: fixed; ${positionStyles} z-index: 10000; ${themeStyles} border-radius: 16px; box-shadow: 0 20px 60px rgba(0,0,0,0.3); padding: 24px; min-width: 320px; max-width: 400px; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;`;\n\n\t\tthis.surveyElement.innerHTML = `\n\t\t\t<button class=\"feedback-survey-close\" style=\"position: absolute; top: 12px; right: 12px; background: none; border: none; font-size: 20px; cursor: pointer; color: ${this.surveyOptions.theme === 'dark' ? '#888' : '#86868b'}; line-height: 1;\">×</button>\n\t\t\t<h3 class=\"feedback-survey-title\" style=\"margin: 0 0 8px 0; font-size: 18px; font-weight: 600; padding-right: 24px;\">${config.title}</h3>\n\t\t\t<p class=\"feedback-survey-description\" style=\"color: ${this.surveyOptions.theme === 'dark' ? '#aaa' : '#86868b'}; margin: 0 0 20px 0; font-size: 14px;\">${config.description}</p>\n\t\t\t<div class=\"feedback-survey-content\">${config.html}</div>\n\t\t\t<div class=\"feedback-survey-feedback\" style=\"margin-top: 16px;\">\n\t\t\t\t<textarea class=\"feedback-survey-textarea\" placeholder=\"Any additional feedback? (optional)\" style=\"width: 100%; padding: 12px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#333' : '#d2d2d7'}; border-radius: 8px; font-size: 14px; resize: none; height: 80px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#fff'}; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'}; font-family: inherit; box-sizing: border-box;\"></textarea>\n\t\t\t</div>\n\t\t\t<button class=\"feedback-survey-submit\" style=\"width: 100%; margin-top: 12px; padding: 12px; background: #007aff; color: white; border: none; border-radius: 8px; font-size: 14px; font-weight: 500; cursor: pointer; font-family: inherit;\">Submit</button>\n\t\t`;\n\n\t\tdocument.body.appendChild(this.surveyElement);\n\t\tthis._attachSurveyEvents();\n\n\t\t// Animate in\n\t\trequestAnimationFrame(() => {\n\t\t\tthis.surveyElement.style.opacity = '1';\n\t\t\tthis.surveyElement.style.transform =\n\t\t\t\tthis.surveyOptions.position === 'center'\n\t\t\t\t\t? 'translate(-50%, -50%) scale(1)'\n\t\t\t\t\t: 'translateY(0)';\n\t\t});\n\t}\n\n\t_getSurveyConfig() {\n\t\tconst configs = {\n\t\t\tnps: {\n\t\t\t\ttitle:\n\t\t\t\t\tthis.surveyOptions.title || 'How likely are you to recommend us?',\n\t\t\t\tdescription:\n\t\t\t\t\tthis.surveyOptions.description ||\n\t\t\t\t\t'On a scale of 0-10, how likely are you to recommend our product to a friend or colleague?',\n\t\t\t\thtml: `\n\t\t\t\t\t<div class=\"feedback-survey-nps\" style=\"display: flex; justify-content: space-between; gap: 4px;\">\n\t\t\t\t\t\t${[...Array(11).keys()]\n\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t(n) => `\n\t\t\t\t\t\t\t<button class=\"feedback-survey-nps-btn\" data-score=\"${n}\" style=\"width: 28px; height: 36px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7'}; border-radius: 6px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa'}; cursor: pointer; font-size: 12px; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'}; transition: all 0.15s;\">${n}</button>\n\t\t\t\t\t\t`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div style=\"display: flex; justify-content: space-between; margin-top: 8px; font-size: 11px; color: ${this.surveyOptions.theme === 'dark' ? '#888' : '#86868b'};\">\n\t\t\t\t\t\t<span>${this.surveyOptions.lowLabel || 'Not likely'}</span>\n\t\t\t\t\t\t<span>${this.surveyOptions.highLabel || 'Very likely'}</span>\n\t\t\t\t\t</div>\n\t\t\t\t`,\n\t\t\t},\n\t\t\tcsat: {\n\t\t\t\ttitle: this.surveyOptions.title || 'How satisfied are you?',\n\t\t\t\tdescription:\n\t\t\t\t\tthis.surveyOptions.description ||\n\t\t\t\t\t'How would you rate your overall satisfaction with our product?',\n\t\t\t\thtml: `\n\t\t\t\t\t<div class=\"feedback-survey-csat\" style=\"display: flex; justify-content: center; gap: 16px;\">\n\t\t\t\t\t\t${['😞', '😕', '😐', '🙂', '😄']\n\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t(emoji, i) => `\n\t\t\t\t\t\t\t<button class=\"feedback-survey-csat-btn\" data-score=\"${i + 1}\" style=\"background: none; border: none; cursor: pointer; font-size: 36px; transition: transform 0.15s; padding: 8px;\">${emoji}</button>\n\t\t\t\t\t\t`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div style=\"display: flex; justify-content: space-between; margin-top: 8px; font-size: 11px; color: ${this.surveyOptions.theme === 'dark' ? '#888' : '#86868b'};\">\n\t\t\t\t\t\t<span>${this.surveyOptions.lowLabel || 'Very dissatisfied'}</span>\n\t\t\t\t\t\t<span>${this.surveyOptions.highLabel || 'Very satisfied'}</span>\n\t\t\t\t\t</div>\n\t\t\t\t`,\n\t\t\t},\n\t\t\tces: {\n\t\t\t\ttitle: this.surveyOptions.title || 'How easy was it?',\n\t\t\t\tdescription:\n\t\t\t\t\tthis.surveyOptions.description ||\n\t\t\t\t\t'How easy was it to accomplish your task today?',\n\t\t\t\thtml: `\n\t\t\t\t\t<div class=\"feedback-survey-ces\" style=\"display: flex; justify-content: space-between; gap: 8px;\">\n\t\t\t\t\t\t${['Very Difficult', 'Difficult', 'Neutral', 'Easy', 'Very Easy']\n\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t(label, i) => `\n\t\t\t\t\t\t\t<button class=\"feedback-survey-ces-btn\" data-score=\"${i + 1}\" style=\"flex: 1; padding: 12px 8px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7'}; border-radius: 8px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa'}; cursor: pointer; font-size: 11px; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'}; transition: all 0.15s;\">${label}</button>\n\t\t\t\t\t\t`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.join('')}\n\t\t\t\t\t</div>\n\t\t\t\t`,\n\t\t\t},\n\t\t\tcustom: {\n\t\t\t\ttitle: this.surveyOptions.title || 'Quick Feedback',\n\t\t\t\tdescription:\n\t\t\t\t\tthis.surveyOptions.description ||\n\t\t\t\t\t'Help us improve by answering a few questions.',\n\t\t\t\thtml: this._renderCustomQuestions(),\n\t\t\t},\n\t\t};\n\n\t\treturn configs[this.surveyOptions.surveyType] || configs.nps;\n\t}\n\n\t_renderCustomQuestions() {\n\t\tif (\n\t\t\t!this.surveyOptions.customQuestions ||\n\t\t\tthis.surveyOptions.customQuestions.length === 0\n\t\t) {\n\t\t\t// Default custom questions\n\t\t\treturn `\n\t\t\t\t<div style=\"margin-bottom: 16px;\">\n\t\t\t\t\t<label style=\"display: block; margin-bottom: 6px; font-size: 13px; font-weight: 500;\">What feature do you use most?</label>\n\t\t\t\t\t<select class=\"feedback-survey-select\" data-question=\"feature\" style=\"width: 100%; padding: 10px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7'}; border-radius: 8px; font-size: 14px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#fff'}; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'};\">\n\t\t\t\t\t\t<option value=\"\">Select a feature</option>\n\t\t\t\t\t\t<option value=\"feedback\">Feedback Collection</option>\n\t\t\t\t\t\t<option value=\"surveys\">Surveys</option>\n\t\t\t\t\t\t<option value=\"analytics\">Analytics</option>\n\t\t\t\t\t\t<option value=\"integrations\">Integrations</option>\n\t\t\t\t\t</select>\n\t\t\t\t</div>\n\t\t\t\t<div>\n\t\t\t\t\t<label style=\"display: block; margin-bottom: 6px; font-size: 13px; font-weight: 500;\">How often do you use it?</label>\n\t\t\t\t\t<div class=\"feedback-survey-frequency\" style=\"display: flex; gap: 8px;\">\n\t\t\t\t\t\t${['Daily', 'Weekly', 'Monthly', 'Rarely']\n\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t(freq) => `\n\t\t\t\t\t\t\t<button class=\"feedback-survey-freq-btn\" data-freq=\"${freq}\" style=\"flex: 1; padding: 10px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7'}; border-radius: 8px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa'}; cursor: pointer; font-size: 12px; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'}; transition: all 0.15s;\">${freq}</button>\n\t\t\t\t\t\t`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.join('')}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t`;\n\t\t}\n\n\t\treturn this.surveyOptions.customQuestions\n\t\t\t.map(\n\t\t\t\t(q, index) => `\n\t\t\t<div style=\"margin-bottom: 16px;\">\n\t\t\t\t<label style=\"display: block; margin-bottom: 6px; font-size: 13px; font-weight: 500;\">${q.label}</label>\n\t\t\t\t${this._renderQuestionInput(q, index)}\n\t\t\t</div>\n\t\t`\n\t\t\t)\n\t\t\t.join('');\n\t}\n\n\t_renderQuestionInput(question, index) {\n\t\tswitch (question.type) {\n\t\t\tcase 'select':\n\t\t\t\treturn `\n\t\t\t\t\t<select class=\"feedback-survey-select\" data-question=\"${question.id || index}\" style=\"width: 100%; padding: 10px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7'}; border-radius: 8px; font-size: 14px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#fff'}; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'};\">\n\t\t\t\t\t\t<option value=\"\">${question.placeholder || 'Select an option'}</option>\n\t\t\t\t\t\t${question.options.map((opt) => `<option value=\"${opt.value}\">${opt.label}</option>`).join('')}\n\t\t\t\t\t</select>\n\t\t\t\t`;\n\t\t\tcase 'text':\n\t\t\t\treturn `\n\t\t\t\t\t<input type=\"text\" class=\"feedback-survey-input\" data-question=\"${question.id || index}\" placeholder=\"${question.placeholder || ''}\" style=\"width: 100%; padding: 10px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7'}; border-radius: 8px; font-size: 14px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#fff'}; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'}; box-sizing: border-box;\">\n\t\t\t\t`;\n\t\t\tdefault:\n\t\t\t\treturn '';\n\t\t}\n\t}\n\n\t_getPositionStyles() {\n\t\tconst positions = {\n\t\t\t'bottom-right':\n\t\t\t\t'bottom: 24px; right: 24px; opacity: 0; transform: translateY(20px); transition: all 0.3s ease;',\n\t\t\t'bottom-left':\n\t\t\t\t'bottom: 24px; left: 24px; opacity: 0; transform: translateY(20px); transition: all 0.3s ease;',\n\t\t\tcenter:\n\t\t\t\t'top: 50%; left: 50%; transform: translate(-50%, -50%) scale(0.95); opacity: 0; transition: all 0.3s ease;',\n\t\t\tbottom:\n\t\t\t\t'bottom: 0; left: 0; right: 0; border-radius: 16px 16px 0 0; max-width: none; opacity: 0; transform: translateY(20px); transition: all 0.3s ease;',\n\t\t};\n\t\treturn positions[this.surveyOptions.position] || positions['bottom-right'];\n\t}\n\n\t_attachSurveyEvents() {\n\t\tif (!this.surveyElement) return;\n\n\t\t// Close button\n\t\tconst closeBtn = this.surveyElement.querySelector('.feedback-survey-close');\n\t\tcloseBtn.addEventListener('click', () => this._handleDismiss());\n\n\t\t// Submit button\n\t\tconst submitBtn = this.surveyElement.querySelector(\n\t\t\t'.feedback-survey-submit'\n\t\t);\n\t\tsubmitBtn.addEventListener('click', () => this._handleSubmit());\n\n\t\t// Feedback textarea\n\t\tconst textarea = this.surveyElement.querySelector(\n\t\t\t'.feedback-survey-textarea'\n\t\t);\n\t\ttextarea.addEventListener('input', (e) => {\n\t\t\tthis.surveyState.feedback = e.target.value;\n\t\t});\n\n\t\t// Survey type specific events\n\t\tthis._attachTypeSpecificEvents();\n\n\t\t// Escape key\n\t\tthis._escapeHandler = (e) => {\n\t\t\tif (e.key === 'Escape') {\n\t\t\t\tthis._handleDismiss();\n\t\t\t}\n\t\t};\n\t\tdocument.addEventListener('keydown', this._escapeHandler);\n\t}\n\n\t_attachTypeSpecificEvents() {\n\t\tconst type = this.surveyOptions.surveyType;\n\n\t\tif (type === 'nps') {\n\t\t\tthis.surveyElement\n\t\t\t\t.querySelectorAll('.feedback-survey-nps-btn')\n\t\t\t\t.forEach((btn) => {\n\t\t\t\t\tbtn.addEventListener('click', () =>\n\t\t\t\t\t\tthis._selectNPS(parseInt(btn.dataset.score))\n\t\t\t\t\t);\n\t\t\t\t\tbtn.addEventListener('mouseenter', () => {\n\t\t\t\t\t\tif (this.surveyState.score !== parseInt(btn.dataset.score)) {\n\t\t\t\t\t\t\tbtn.style.borderColor = '#007aff';\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tbtn.addEventListener('mouseleave', () => {\n\t\t\t\t\t\tif (this.surveyState.score !== parseInt(btn.dataset.score)) {\n\t\t\t\t\t\t\tbtn.style.borderColor =\n\t\t\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t}\n\n\t\tif (type === 'csat') {\n\t\t\tthis.surveyElement\n\t\t\t\t.querySelectorAll('.feedback-survey-csat-btn')\n\t\t\t\t.forEach((btn) => {\n\t\t\t\t\tbtn.addEventListener('click', () =>\n\t\t\t\t\t\tthis._selectCSAT(parseInt(btn.dataset.score))\n\t\t\t\t\t);\n\t\t\t\t\tbtn.addEventListener('mouseenter', () => {\n\t\t\t\t\t\tbtn.style.transform = 'scale(1.1)';\n\t\t\t\t\t});\n\t\t\t\t\tbtn.addEventListener('mouseleave', () => {\n\t\t\t\t\t\tif (this.surveyState.score !== parseInt(btn.dataset.score)) {\n\t\t\t\t\t\t\tbtn.style.transform = 'scale(1)';\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t}\n\n\t\tif (type === 'ces') {\n\t\t\tthis.surveyElement\n\t\t\t\t.querySelectorAll('.feedback-survey-ces-btn')\n\t\t\t\t.forEach((btn) => {\n\t\t\t\t\tbtn.addEventListener('click', () =>\n\t\t\t\t\t\tthis._selectCES(parseInt(btn.dataset.score))\n\t\t\t\t\t);\n\t\t\t\t\tbtn.addEventListener('mouseenter', () => {\n\t\t\t\t\t\tif (this.surveyState.score !== parseInt(btn.dataset.score)) {\n\t\t\t\t\t\t\tbtn.style.borderColor = '#007aff';\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tbtn.addEventListener('mouseleave', () => {\n\t\t\t\t\t\tif (this.surveyState.score !== parseInt(btn.dataset.score)) {\n\t\t\t\t\t\t\tbtn.style.borderColor =\n\t\t\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t}\n\n\t\tif (type === 'custom') {\n\t\t\t// Frequency buttons\n\t\t\tthis.surveyElement\n\t\t\t\t.querySelectorAll('.feedback-survey-freq-btn')\n\t\t\t\t.forEach((btn) => {\n\t\t\t\t\tbtn.addEventListener('click', () =>\n\t\t\t\t\t\tthis._selectFrequency(btn.dataset.freq)\n\t\t\t\t\t);\n\t\t\t\t});\n\n\t\t\t// Select inputs\n\t\t\tthis.surveyElement\n\t\t\t\t.querySelectorAll('.feedback-survey-select')\n\t\t\t\t.forEach((select) => {\n\t\t\t\t\tselect.addEventListener('change', (e) => {\n\t\t\t\t\t\tthis.surveyState.customAnswers[select.dataset.question] =\n\t\t\t\t\t\t\te.target.value;\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t// Text inputs\n\t\t\tthis.surveyElement\n\t\t\t\t.querySelectorAll('.feedback-survey-input')\n\t\t\t\t.forEach((input) => {\n\t\t\t\t\tinput.addEventListener('input', (e) => {\n\t\t\t\t\t\tthis.surveyState.customAnswers[input.dataset.question] =\n\t\t\t\t\t\t\te.target.value;\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t}\n\t}\n\n\t_selectNPS(score) {\n\t\tthis.surveyState.score = score;\n\t\tthis.surveyElement\n\t\t\t.querySelectorAll('.feedback-survey-nps-btn')\n\t\t\t.forEach((btn) => {\n\t\t\t\tconst btnScore = parseInt(btn.dataset.score);\n\t\t\t\tif (btnScore === score) {\n\t\t\t\t\tbtn.style.background = '#007aff';\n\t\t\t\t\tbtn.style.borderColor = '#007aff';\n\t\t\t\t\tbtn.style.color = '#fff';\n\t\t\t\t} else {\n\t\t\t\t\tbtn.style.background =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa';\n\t\t\t\t\tbtn.style.borderColor =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';\n\t\t\t\t\tbtn.style.color =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f';\n\t\t\t\t}\n\t\t\t});\n\t}\n\n\t_selectCSAT(score) {\n\t\tthis.surveyState.score = score;\n\t\tthis.surveyElement\n\t\t\t.querySelectorAll('.feedback-survey-csat-btn')\n\t\t\t.forEach((btn) => {\n\t\t\t\tconst btnScore = parseInt(btn.dataset.score);\n\t\t\t\tbtn.style.transform = btnScore === score ? 'scale(1.2)' : 'scale(1)';\n\t\t\t});\n\t}\n\n\t_selectCES(score) {\n\t\tthis.surveyState.score = score;\n\t\tthis.surveyElement\n\t\t\t.querySelectorAll('.feedback-survey-ces-btn')\n\t\t\t.forEach((btn) => {\n\t\t\t\tconst btnScore = parseInt(btn.dataset.score);\n\t\t\t\tif (btnScore === score) {\n\t\t\t\t\tbtn.style.background = '#007aff';\n\t\t\t\t\tbtn.style.borderColor = '#007aff';\n\t\t\t\t\tbtn.style.color = '#fff';\n\t\t\t\t} else {\n\t\t\t\t\tbtn.style.background =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa';\n\t\t\t\t\tbtn.style.borderColor =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';\n\t\t\t\t\tbtn.style.color =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f';\n\t\t\t\t}\n\t\t\t});\n\t}\n\n\t_selectFrequency(freq) {\n\t\tthis.surveyState.customAnswers.frequency = freq;\n\t\tthis.surveyElement\n\t\t\t.querySelectorAll('.feedback-survey-freq-btn')\n\t\t\t.forEach((btn) => {\n\t\t\t\tif (btn.dataset.freq === freq) {\n\t\t\t\t\tbtn.style.background = '#007aff';\n\t\t\t\t\tbtn.style.borderColor = '#007aff';\n\t\t\t\t\tbtn.style.color = '#fff';\n\t\t\t\t} else {\n\t\t\t\t\tbtn.style.background =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa';\n\t\t\t\t\tbtn.style.borderColor =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';\n\t\t\t\t\tbtn.style.color =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f';\n\t\t\t\t}\n\t\t\t});\n\t}\n\n\tasync _handleSubmit() {\n\t\tconst type = this.surveyOptions.surveyType;\n\n\t\t// Validate\n\t\tif (\n\t\t\t(type === 'nps' || type === 'csat' || type === 'ces') &&\n\t\t\tthis.surveyState.score === null\n\t\t) {\n\t\t\tthis._showError('Please select a rating');\n\t\t\treturn;\n\t\t}\n\n\t\tconst response = {\n\t\t\ttype: type,\n\t\t\tscore: this.surveyState.score,\n\t\t\tfeedback: this.surveyState.feedback,\n\t\t\tcustomAnswers: this.surveyState.customAnswers,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t};\n\n\t\t// Call onSubmit callback if provided\n\t\tif (this.surveyOptions.onSubmit) {\n\t\t\tthis.surveyOptions.onSubmit(response);\n\t\t}\n\n\t\t// Submit to API if not in mock mode\n\t\tif (!this.sdk.config.mock) {\n\t\t\ttry {\n\t\t\t\tawait this.apiService.submitSurveyResponse(response);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('[SurveyWidget] Failed to submit survey:', error);\n\t\t\t}\n\t\t}\n\n\t\tthis.sdk.eventBus.emit('survey:submitted', { widget: this, response });\n\n\t\tthis._closeSurvey();\n\t\tthis._showSuccessNotification();\n\t}\n\n\t_handleDismiss() {\n\t\tif (this.surveyOptions.onDismiss) {\n\t\t\tthis.surveyOptions.onDismiss();\n\t\t}\n\t\tthis.sdk.eventBus.emit('survey:dismissed', { widget: this });\n\t\tthis._closeSurvey();\n\t}\n\n\t_showError(message) {\n\t\t// Simple error display - could be enhanced\n\t\tconst existing = this.surveyElement.querySelector('.feedback-survey-error');\n\t\tif (existing) existing.remove();\n\n\t\tconst error = document.createElement('div');\n\t\terror.className = 'feedback-survey-error';\n\t\terror.style.cssText =\n\t\t\t'color: #ef4444; font-size: 13px; margin-top: 8px; text-align: center;';\n\t\terror.textContent = message;\n\n\t\tconst submitBtn = this.surveyElement.querySelector(\n\t\t\t'.feedback-survey-submit'\n\t\t);\n\t\tsubmitBtn.parentNode.insertBefore(error, submitBtn);\n\n\t\tsetTimeout(() => error.remove(), 3000);\n\t}\n\n\t_showSuccessNotification() {\n\t\tconst notification = document.createElement('div');\n\t\tnotification.className = 'feedback-survey-success';\n\t\tnotification.style.cssText = `\n\t\t\tposition: fixed;\n\t\t\ttop: 24px;\n\t\t\tright: 24px;\n\t\t\tbackground: #10b981;\n\t\t\tcolor: white;\n\t\t\tpadding: 16px 24px;\n\t\t\tborder-radius: 12px;\n\t\t\tfont-size: 14px;\n\t\t\tfont-weight: 500;\n\t\t\tz-index: 10001;\n\t\t\tbox-shadow: 0 10px 40px rgba(0,0,0,0.2);\n\t\t\tfont-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;\n\t\t`;\n\t\tnotification.innerHTML = `\n\t\t\t<div style=\"display: flex; align-items: center; gap: 8px;\">\n\t\t\t\t<span style=\"font-size: 18px;\">✓</span>\n\t\t\t\t<span>Thank you for your feedback!</span>\n\t\t\t</div>\n\t\t`;\n\t\tdocument.body.appendChild(notification);\n\n\t\tsetTimeout(() => {\n\t\t\tnotification.style.opacity = '0';\n\t\t\tnotification.style.transition = 'opacity 0.3s ease';\n\t\t\tsetTimeout(() => notification.remove(), 300);\n\t\t}, 3000);\n\t}\n\n\t_closeSurvey() {\n\t\tif (this._escapeHandler) {\n\t\t\tdocument.removeEventListener('keydown', this._escapeHandler);\n\t\t\tthis._escapeHandler = null;\n\t\t}\n\n\t\t// Capture references to avoid race conditions with setTimeout\n\t\tconst surveyEl = this.surveyElement;\n\t\tconst backdropEl = this.backdropElement;\n\n\t\tif (surveyEl) {\n\t\t\tsurveyEl.style.opacity = '0';\n\t\t\tsurveyEl.style.transform =\n\t\t\t\tthis.surveyOptions.position === 'center'\n\t\t\t\t\t? 'translate(-50%, -50%) scale(0.95)'\n\t\t\t\t\t: 'translateY(20px)';\n\t\t\tsetTimeout(() => {\n\t\t\t\tif (surveyEl && surveyEl.parentNode) {\n\t\t\t\t\tsurveyEl.parentNode.removeChild(surveyEl);\n\t\t\t\t}\n\t\t\t}, 300);\n\t\t\tthis.surveyElement = null;\n\t\t}\n\n\t\tif (backdropEl) {\n\t\t\tbackdropEl.style.opacity = '0';\n\t\t\tsetTimeout(() => {\n\t\t\t\tif (backdropEl && backdropEl.parentNode) {\n\t\t\t\t\tbackdropEl.parentNode.removeChild(backdropEl);\n\t\t\t\t}\n\t\t\t}, 300);\n\t\t\tthis.backdropElement = null;\n\t\t}\n\n\t\tthis.surveyState = {\n\t\t\tscore: null,\n\t\t\tfeedback: '',\n\t\t\tcustomAnswers: {},\n\t\t\tisVisible: false,\n\t\t};\n\t}\n\n\tdestroy() {\n\t\tthis._closeSurvey();\n\t\tsuper.destroy();\n\t}\n}\n","import { BaseWidget } from './BaseWidget.js';\n\nexport class TabWidget extends BaseWidget {\n\tconstructor(options) {\n\t\tsuper({ ...options, type: 'tab' });\n\t}\n\n\t_render() {\n\t\tconst tab = document.createElement('div');\n\t\ttab.className = `feedback-widget feedback-widget-tab theme-${this.options.theme} position-${this.options.position}`;\n\t\ttab.innerHTML = `\n <div class=\"feedback-tab-trigger\">\n <span class=\"feedback-tab-text\">Feedback</span>\n </div>\n `;\n\n\t\tif (this.options.customStyles) {\n\t\t\tObject.assign(tab.style, this.options.customStyles);\n\t\t}\n\n\t\treturn tab;\n\t}\n\n\t_attachEvents() {\n\t\tconst tab = this.element.querySelector('.feedback-tab-trigger');\n\t\ttab.addEventListener('click', this.openModal);\n\n\t\ttab.addEventListener('mouseenter', () => {\n\t\t\tif (!this.state.isSubmitting) {\n\t\t\t\ttab.style.transform = this._getHoverTransform();\n\t\t\t}\n\t\t});\n\n\t\ttab.addEventListener('mouseleave', () => {\n\t\t\ttab.style.transform = 'none';\n\t\t});\n\t}\n\n\t_getHoverTransform() {\n\t\tconst position = this.options.position;\n\t\tif (position.includes('right')) {\n\t\t\treturn 'translateX(-5px)';\n\t\t} else if (position.includes('left')) {\n\t\t\treturn 'translateX(5px)';\n\t\t}\n\t\treturn 'none';\n\t}\n\n\tupdateText(text) {\n\t\tconst textElement = this.element?.querySelector('.feedback-tab-text');\n\t\tif (textElement) {\n\t\t\ttextElement.textContent = text;\n\t\t}\n\t}\n\n\tupdatePosition(position) {\n\t\tthis.options.position = position;\n\t\tif (this.element) {\n\t\t\tthis.element.className = this.element.className.replace(\n\t\t\t\t/position-\\w+-\\w+/,\n\t\t\t\t`position-${position}`\n\t\t\t);\n\t\t}\n\t}\n}\n","import { SDKError } from '../utils/errors.js';\nimport { ButtonWidget } from './ButtonWidget.js';\nimport { InlineWidget } from './InlineWidget.js';\nimport { SurveyWidget } from './SurveyWidget.js';\nimport { TabWidget } from './TabWidget.js';\n\nexport class WidgetFactory {\n\tstatic widgets = new Map([\n\t\t['button', ButtonWidget],\n\t\t['tab', TabWidget],\n\t\t['inline', InlineWidget],\n\t\t['survey', SurveyWidget],\n\t]);\n\n\tstatic register(type, WidgetClass) {\n\t\tif (typeof type !== 'string' || !type.trim()) {\n\t\t\tthrow new SDKError('Widget type must be a non-empty string');\n\t\t}\n\n\t\tif (typeof WidgetClass !== 'function') {\n\t\t\tthrow new SDKError('Widget class must be a constructor function');\n\t\t}\n\n\t\tthis.widgets.set(type, WidgetClass);\n\t}\n\n\tstatic create(type, options = {}) {\n\t\tconst WidgetClass = this.widgets.get(type);\n\n\t\tif (!WidgetClass) {\n\t\t\tconst availableTypes = Array.from(this.widgets.keys()).join(', ');\n\t\t\tthrow new SDKError(\n\t\t\t\t`Unknown widget type: ${type}. Available types: ${availableTypes}`\n\t\t\t);\n\t\t}\n\n\t\ttry {\n\t\t\treturn new WidgetClass(options);\n\t\t} catch (error) {\n\t\t\tthrow new SDKError(\n\t\t\t\t`Failed to create widget of type '${type}': ${error.message}`,\n\t\t\t\terror\n\t\t\t);\n\t\t}\n\t}\n\n\tstatic getAvailableTypes() {\n\t\treturn Array.from(this.widgets.keys());\n\t}\n\n\tstatic isTypeRegistered(type) {\n\t\treturn this.widgets.has(type);\n\t}\n\n\tstatic unregister(type) {\n\t\treturn this.widgets.delete(type);\n\t}\n\n\tstatic clear() {\n\t\tthis.widgets.clear();\n\t}\n\n\tstatic getWidgetClass(type) {\n\t\treturn this.widgets.get(type);\n\t}\n}\n","import { ConfigError, SDKError } from '../utils/errors.js';\nimport { deepMerge, generateId } from '../utils/helpers.js';\nimport { WidgetFactory } from '../widgets/WidgetFactory.js';\nimport { APIService } from './APIService.js';\nimport { EventBus } from './EventBus.js';\n\nexport class FeedbackSDK {\n\tconstructor(config = {}) {\n\t\tthis.config = this._validateAndMergeConfig(config);\n\t\tthis.initialized = false;\n\t\tthis.widgets = new Map();\n\t\tthis.eventBus = new EventBus();\n\n\t\tthis.apiService = new APIService({\n\t\t\tapiUrl: this.config.apiUrl,\n\t\t\tworkspace: this.config.workspace,\n\t\t\tuserContext: this.config.userContext,\n\t\t\tmock: this.config.mock,\n\t\t\tenv: this.config.env,\n\t\t});\n\n\t\tthis._bindMethods();\n\t}\n\n\tasync init() {\n\t\tif (this.initialized) {\n\t\t\treturn { alreadyInitialized: true };\n\t\t}\n\n\t\ttry {\n\t\t\tconst initData = await this.apiService.init(this.config.userContext);\n\n\t\t\t// Merge backend config as base, local config overrides\n\t\t\tif (initData.config) {\n\t\t\t\tthis.config = deepMerge(initData.config, this.config);\n\t\t\t}\n\n\t\t\tthis.initialized = true;\n\t\t\tthis.eventBus.emit('sdk:initialized', {\n\t\t\t\tconfig: this.config,\n\t\t\t\tsessionToken: initData.sessionToken,\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\tinitialized: true,\n\t\t\t\tconfig: initData.config || {},\n\t\t\t\tsessionToken: initData.sessionToken,\n\t\t\t\texpiresIn: initData.expiresIn,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tthis.eventBus.emit('sdk:error', { error });\n\t\t\tthrow new SDKError(`Failed to initialize SDK: ${error.message}`, error);\n\t\t}\n\t}\n\n\tcreateWidget(type = 'button', options = {}) {\n\t\tif (!this.initialized) {\n\t\t\tthrow new SDKError(\n\t\t\t\t'SDK must be initialized before creating widgets. Call init() first.'\n\t\t\t);\n\t\t}\n\n\t\tconst widgetId = generateId('widget');\n\t\tconst widgetOptions = {\n\t\t\tid: widgetId,\n\t\t\tsdk: this,\n\t\t\tapiService: this.apiService,\n\t\t\t...this.config,\n\t\t\t...options,\n\t\t};\n\n\t\ttry {\n\t\t\tconst widget = WidgetFactory.create(type, widgetOptions);\n\t\t\tthis.widgets.set(widgetId, widget);\n\t\t\tthis.eventBus.emit('widget:created', { widget, type });\n\t\t\treturn widget;\n\t\t} catch (error) {\n\t\t\tthrow new SDKError(`Failed to create widget: ${error.message}`, error);\n\t\t}\n\t}\n\n\tgetWidget(id) {\n\t\treturn this.widgets.get(id);\n\t}\n\n\t/**\n\t * Show a survey widget\n\t * @param {Object} options - Survey options\n\t * @param {string} options.surveyType - Type of survey: 'nps', 'csat', 'ces', 'custom'\n\t * @param {string} options.position - Position: 'bottom-right', 'bottom-left', 'center', 'bottom'\n\t * @param {string} options.theme - Theme: 'light', 'dark'\n\t * @param {string} options.title - Custom title\n\t * @param {string} options.description - Custom description\n\t * @param {string} options.lowLabel - Low end label\n\t * @param {string} options.highLabel - High end label\n\t * @param {Function} options.onSubmit - Callback when survey is submitted\n\t * @param {Function} options.onDismiss - Callback when survey is dismissed\n\t * @returns {SurveyWidget} The survey widget instance\n\t */\n\tshowSurvey(options = {}) {\n\t\tif (!this.initialized) {\n\t\t\tthrow new SDKError(\n\t\t\t\t'SDK must be initialized before showing surveys. Call init() first.'\n\t\t\t);\n\t\t}\n\n\t\tconst surveyWidget = this.createWidget('survey', {\n\t\t\tsurveyType: options.surveyType || options.type || 'nps',\n\t\t\tposition: options.position || 'bottom-right',\n\t\t\ttheme: options.theme || this.config.theme || 'light',\n\t\t\ttitle: options.title,\n\t\t\tdescription: options.description,\n\t\t\tlowLabel: options.lowLabel,\n\t\t\thighLabel: options.highLabel,\n\t\t\tcustomQuestions: options.customQuestions,\n\t\t\tonSubmit: options.onSubmit,\n\t\t\tonDismiss: options.onDismiss,\n\t\t});\n\n\t\tsurveyWidget.mount();\n\t\tsurveyWidget.show();\n\n\t\treturn surveyWidget;\n\t}\n\n\tgetAllWidgets() {\n\t\treturn Array.from(this.widgets.values());\n\t}\n\n\tdestroyWidget(id) {\n\t\tconst widget = this.widgets.get(id);\n\t\tif (widget) {\n\t\t\twidget.destroy();\n\t\t\tthis.widgets.delete(id);\n\t\t\tthis.eventBus.emit('widget:removed', { widgetId: id });\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tdestroyAllWidgets() {\n\t\tfor (const widget of this.widgets.values()) {\n\t\t\twidget.destroy();\n\t\t}\n\t\tthis.widgets.clear();\n\t\tthis.eventBus.emit('widgets:cleared');\n\t}\n\n\tupdateConfig(newConfig) {\n\t\tconst oldConfig = { ...this.config };\n\t\tthis.config = this._validateAndMergeConfig(newConfig, this.config);\n\n\t\tfor (const widget of this.widgets.values()) {\n\t\t\twidget.handleConfigUpdate(this.config);\n\t\t}\n\n\t\tthis.eventBus.emit('config:updated', {\n\t\t\toldConfig,\n\t\t\tnewConfig: this.config,\n\t\t});\n\t}\n\n\tsetUserContext(userContext) {\n\t\tthis.config.userContext = userContext;\n\t\tif (this.apiService) {\n\t\t\tthis.apiService.setUserContext(userContext);\n\t\t}\n\t\tthis.eventBus.emit('user:updated', { userContext });\n\t}\n\n\tgetUserContext() {\n\t\treturn (\n\t\t\tthis.config.userContext ||\n\t\t\t(this.apiService ? this.apiService.getUserContext() : null)\n\t\t);\n\t}\n\n\tasync reinitialize(newUserContext = null) {\n\t\tthis.apiService.clearSession();\n\t\tthis.initialized = false;\n\n\t\tif (newUserContext) {\n\t\t\tthis.setUserContext(newUserContext);\n\t\t}\n\n\t\treturn this.init();\n\t}\n\n\ton(event, callback) {\n\t\tthis.eventBus.on(event, callback);\n\t\treturn this;\n\t}\n\n\toff(event, callback) {\n\t\tthis.eventBus.off(event, callback);\n\t\treturn this;\n\t}\n\n\tonce(event, callback) {\n\t\tthis.eventBus.once(event, callback);\n\t\treturn this;\n\t}\n\n\temit(event, data) {\n\t\tthis.eventBus.emit(event, data);\n\t\treturn this;\n\t}\n\n\tdestroy() {\n\t\tthis.destroyAllWidgets();\n\t\tthis.eventBus.removeAllListeners();\n\t\tthis.apiService.clearSession();\n\t\tthis.initialized = false;\n\t\tthis.eventBus.emit('sdk:destroyed');\n\t}\n\n\t_validateAndMergeConfig(newConfig, existingConfig = {}) {\n\t\tconst defaultConfig = {\n\t\t\tapiUrl: null,\n\t\t\tworkspace: null,\n\t\t\tuserContext: null,\n\t\t\tposition: 'bottom-right',\n\t\t\ttheme: 'light',\n\t\t\tboardId: 'general',\n\t\t\tautoShow: true,\n\t\t\tdebug: false,\n\t\t\tmock: false,\n\t\t\tenv: 'production', // 'production' or 'staging'\n\t\t};\n\n\t\tconst mergedConfig = deepMerge(\n\t\t\tdeepMerge(defaultConfig, existingConfig),\n\t\t\tnewConfig\n\t\t);\n\n\t\tif (!mergedConfig.workspace) {\n\t\t\tthrow new ConfigError('Missing required configuration: workspace');\n\t\t}\n\n\t\tif (mergedConfig.userContext) {\n\t\t\tthis._validateUserContext(mergedConfig.userContext);\n\t\t}\n\n\t\treturn mergedConfig;\n\t}\n\n\t_validateUserContext(userContext) {\n\t\tif (!userContext.user_id && !userContext.email) {\n\t\t\tthrow new ConfigError(\n\t\t\t\t'User context must include at least user_id or email'\n\t\t\t);\n\t\t}\n\n\t\tconst validStructure = {\n\t\t\tuser_id: 'string',\n\t\t\temail: 'string',\n\t\t\tname: 'string',\n\t\t\tcustom_fields: 'object',\n\t\t\tcompany: 'object',\n\t\t};\n\n\t\tfor (const [key, expectedType] of Object.entries(validStructure)) {\n\t\t\tif (userContext[key] && typeof userContext[key] !== expectedType) {\n\t\t\t\tthrow new ConfigError(\n\t\t\t\t\t`User context field '${key}' must be of type '${expectedType}'`\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t_bindMethods() {\n\t\tthis.createWidget = this.createWidget.bind(this);\n\t\tthis.destroyWidget = this.destroyWidget.bind(this);\n\t\tthis.updateConfig = this.updateConfig.bind(this);\n\t}\n\n\tstatic create(config) {\n\t\treturn new FeedbackSDK(config);\n\t}\n\n\tstatic async createAndInit(config) {\n\t\tconst sdk = new FeedbackSDK(config);\n\t\tawait sdk.init();\n\t\treturn sdk;\n\t}\n\n\tstatic extractUserContextFromAuth(authData) {\n\t\tif (!authData) return null;\n\n\t\treturn {\n\t\t\tuser_id: authData.sub || authData.id || authData.user_id,\n\t\t\temail: authData.email,\n\t\t\tname: authData.name || authData.display_name || authData.full_name,\n\t\t\tcustom_fields: {\n\t\t\t\trole: authData.role,\n\t\t\t\tplan: authData.plan || authData.subscription?.plan,\n\t\t\t\t...(authData.custom_fields || {}),\n\t\t\t},\n\t\t\tcompany:\n\t\t\t\tauthData.company || authData.organization\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tid: authData.company?.id || authData.organization?.id,\n\t\t\t\t\t\t\tname: authData.company?.name || authData.organization?.name,\n\t\t\t\t\t\t\tmonthly_spend: authData.company?.monthly_spend,\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined,\n\t\t};\n\t}\n}\n","import { APIService } from './core/APIService.js';\nimport { EventBus } from './core/EventBus.js';\nimport { FeedbackSDK } from './core/FeedbackSDK.js';\nimport { CSS_STYLES } from './styles/styles.js';\nimport {\n\tAPIError,\n\tConfigError,\n\tSDKError,\n\tValidationError,\n\tWidgetError,\n} from './utils/errors.js';\nimport * as helpers from './utils/helpers.js';\nimport { BaseWidget } from './widgets/BaseWidget.js';\nimport { ButtonWidget } from './widgets/ButtonWidget.js';\nimport { InlineWidget } from './widgets/InlineWidget.js';\nimport { SurveyWidget } from './widgets/SurveyWidget.js';\nimport { TabWidget } from './widgets/TabWidget.js';\nimport { WidgetFactory } from './widgets/WidgetFactory.js';\n\nfunction injectStyles() {\n\tif (\n\t\ttypeof document !== 'undefined' &&\n\t\t!document.querySelector('#feedback-sdk-styles')\n\t) {\n\t\tconst style = document.createElement('style');\n\t\tstyle.id = 'feedback-sdk-styles';\n\t\tstyle.textContent = CSS_STYLES;\n\t\tdocument.head.appendChild(style);\n\t}\n}\n\nfunction autoInit() {\n\tif (typeof window !== 'undefined' && window.FeedbackSDKConfig) {\n\t\tinjectStyles();\n\n\t\tconst config = { ...window.FeedbackSDKConfig };\n\t\tconst sdk = new FeedbackSDK(config);\n\n\t\tsdk\n\t\t\t.init()\n\t\t\t.then((initData) => {\n\t\t\t\twindow.FeedbackSDK.instance = sdk;\n\n\t\t\t\tif (window.FeedbackSDKConfig.autoCreate) {\n\t\t\t\t\tconst widgets = Array.isArray(window.FeedbackSDKConfig.autoCreate)\n\t\t\t\t\t\t? window.FeedbackSDKConfig.autoCreate\n\t\t\t\t\t\t: [window.FeedbackSDKConfig.autoCreate];\n\n\t\t\t\t\twidgets.forEach((widgetConfig) => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst widget = sdk.createWidget(\n\t\t\t\t\t\t\t\twidgetConfig.type || 'button',\n\t\t\t\t\t\t\t\twidgetConfig\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\twidget.mount(widgetConfig.container);\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tconsole.error('[FeedbackSDK] Failed to create widget:', error);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tif (typeof CustomEvent !== 'undefined') {\n\t\t\t\t\tconst event = new CustomEvent('FeedbackSDKReady', {\n\t\t\t\t\t\tdetail: { sdk, config, initData },\n\t\t\t\t\t});\n\t\t\t\t\twindow.dispatchEvent(event);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tconsole.error('[FeedbackSDK] Auto-initialization failed:', error);\n\n\t\t\t\tif (typeof CustomEvent !== 'undefined') {\n\t\t\t\t\tconst event = new CustomEvent('FeedbackSDKError', {\n\t\t\t\t\t\tdetail: { error, config, phase: 'initialization' },\n\t\t\t\t\t});\n\t\t\t\t\twindow.dispatchEvent(event);\n\t\t\t\t}\n\t\t\t});\n\t}\n}\n\nfunction handleDOMReady() {\n\tif (typeof document !== 'undefined') {\n\t\tif (document.readyState === 'loading') {\n\t\t\tdocument.addEventListener('DOMContentLoaded', autoInit);\n\t\t} else {\n\t\t\tsetTimeout(autoInit, 0);\n\t\t}\n\t}\n}\n\nconst FeedbackSDKExport = {\n\tFeedbackSDK,\n\tBaseWidget,\n\tButtonWidget,\n\tTabWidget,\n\tInlineWidget,\n\tSurveyWidget,\n\tWidgetFactory,\n\tEventBus,\n\tAPIService,\n\tSDKError,\n\tAPIError,\n\tWidgetError,\n\tConfigError,\n\tValidationError,\n\thelpers,\n\tcreate: (config) => {\n\t\tinjectStyles();\n\t\treturn new FeedbackSDK(config);\n\t},\n\tversion: '1.0.0',\n\tinstance: null,\n\n\tisReady: () => Boolean(FeedbackSDKExport.instance),\n\tgetInstance: () => FeedbackSDKExport.instance,\n\n\tsetUserContext: (userContext) => {\n\t\tif (FeedbackSDKExport.instance) {\n\t\t\tFeedbackSDKExport.instance.setUserContext(userContext);\n\t\t} else {\n\t\t\tif (typeof window !== 'undefined') {\n\t\t\t\twindow.FeedbackSDKUserContext = userContext;\n\t\t\t}\n\t\t}\n\t},\n\n\tinitWithUser: async (config, userContext) => {\n\t\tinjectStyles();\n\t\tconst fullConfig = { ...config, userContext };\n\t\tconst sdk = new FeedbackSDK(fullConfig);\n\t\tawait sdk.init();\n\n\t\tif (typeof window !== 'undefined') {\n\t\t\twindow.FeedbackSDK.instance = sdk;\n\t\t}\n\n\t\treturn sdk;\n\t},\n\n\tonReady: (callback) => {\n\t\tif (typeof window !== 'undefined') {\n\t\t\tif (FeedbackSDKExport.isReady()) {\n\t\t\t\tcallback(FeedbackSDKExport.instance);\n\t\t\t} else {\n\t\t\t\twindow.addEventListener(\n\t\t\t\t\t'FeedbackSDKReady',\n\t\t\t\t\t(event) => {\n\t\t\t\t\t\tcallback(event.detail.sdk, event.detail);\n\t\t\t\t\t},\n\t\t\t\t\t{ once: true }\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t},\n\n\tonError: (callback) => {\n\t\tif (typeof window !== 'undefined') {\n\t\t\twindow.addEventListener('FeedbackSDKError', (event) => {\n\t\t\t\tcallback(event.detail.error, event.detail);\n\t\t\t});\n\t\t}\n\t},\n\n\textractUserContext: FeedbackSDK.extractUserContextFromAuth,\n};\n\nif (typeof window !== 'undefined') {\n\twindow.FeedbackSDK = FeedbackSDKExport;\n\thandleDOMReady();\n}\n\nexport default FeedbackSDKExport;\n\nexport {\n\tAPIError,\n\tAPIService,\n\tBaseWidget,\n\tButtonWidget,\n\tConfigError,\n\tEventBus,\n\tFeedbackSDK,\n\thelpers,\n\tInlineWidget,\n\tSDKError,\n\tSurveyWidget,\n\tTabWidget,\n\tValidationError,\n\tWidgetError,\n\tWidgetFactory,\n};\n","export const CSS_STYLES = `\n.feedback-widget {\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n font-size: 14px;\n line-height: 1.4;\n z-index: 999999;\n box-sizing: border-box;\n}\n\n.feedback-widget *,\n.feedback-widget *::before,\n.feedback-widget *::after {\n box-sizing: border-box;\n}\n\n.feedback-widget-button {\n position: fixed;\n z-index: 999999;\n}\n\n.feedback-widget-button.position-bottom-right {\n bottom: 20px;\n right: 20px;\n}\n\n.feedback-widget-button.position-bottom-left {\n bottom: 20px;\n left: 20px;\n}\n\n.feedback-widget-button.position-top-right {\n top: 20px;\n right: 20px;\n}\n\n.feedback-widget-button.position-top-left {\n top: 20px;\n left: 20px;\n}\n\n.feedback-widget-button.position-bottom-center {\n bottom: 20px;\n left: 50%;\n transform: translateX(-50%);\n}\n\n.feedback-widget-button.position-top-center {\n top: 20px;\n left: 50%;\n transform: translateX(-50%);\n}\n\n.feedback-widget-button.position-center {\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n}\n\n/* New button design - white with elevation */\n.feedback-trigger-btn {\n width: 52px;\n height: 52px;\n border-radius: 50%;\n border: none;\n background: #ffffff;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow: \n 0 2px 4px rgba(0, 0, 0, 0.1),\n 0 8px 16px rgba(0, 0, 0, 0.15),\n 0 0 1px rgba(0, 0, 0, 0.1);\n transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);\n padding: 0;\n}\n\n.feedback-trigger-btn:hover {\n box-shadow: \n 0 4px 8px rgba(0, 0, 0, 0.12),\n 0 12px 24px rgba(0, 0, 0, 0.2),\n 0 0 1px rgba(0, 0, 0, 0.1);\n transform: translateY(-2px);\n}\n\n.feedback-trigger-btn:active {\n transform: translateY(0px);\n box-shadow: \n 0 1px 3px rgba(0, 0, 0, 0.1),\n 0 4px 12px rgba(0, 0, 0, 0.12),\n 0 0 1px rgba(0, 0, 0, 0.1);\n}\n\n.feedback-trigger-btn svg {\n flex-shrink: 0;\n width: 22px;\n height: 25px;\n}\n\n.feedback-trigger-btn svg path {\n fill: #21244A;\n}\n\n/* Loading Modal */\n.feedback-loading-modal {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(0.9);\n z-index: 1000001;\n opacity: 0;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.feedback-loading-modal.show {\n opacity: 1;\n transform: translate(-50%, -50%) scale(1);\n}\n\n.feedback-loading-spinner {\n width: 48px;\n height: 48px;\n border: 4px solid rgba(0, 0, 0, 0.1);\n border-top-color: #21244A;\n border-radius: 50%;\n animation: spin 0.8s linear infinite;\n}\n\n@keyframes spin {\n to { transform: rotate(360deg); }\n}\n\n/* Modal Styles (centered) */\n.feedback-modal {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(0.9);\n width: 480px;\n max-width: 90vw;\n max-height: 85vh;\n z-index: 1000000;\n opacity: 0;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n font-family: inherit;\n}\n\n.feedback-modal.open {\n opacity: 1;\n transform: translate(-50%, -50%) scale(1);\n}\n\n.feedback-modal .feedback-panel-content {\n max-height: 85vh;\n overflow-y: auto;\n}\n\n/* Size variants */\n.feedback-modal.size-small {\n width: 360px;\n}\n\n.feedback-modal.size-medium {\n width: 480px;\n}\n\n.feedback-modal.size-large {\n width: 600px;\n}\n\n.feedback-panel.size-small {\n width: 320px;\n}\n\n.feedback-panel.size-medium {\n width: 420px;\n}\n\n.feedback-panel.size-large {\n width: 520px;\n}\n\n/* Side Panel Styles */\n.feedback-panel {\n position: fixed;\n bottom: 80px;\n right: 24px;\n width: 420px;\n max-height: 500px;\n z-index: 1000000;\n transform: translateX(calc(100% + 24px));\n transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);\n font-family: inherit;\n}\n\n.feedback-panel.open {\n transform: translateX(0);\n}\n\n.feedback-panel-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(4px);\n opacity: 0;\n transition: opacity 0.3s ease;\n pointer-events: none;\n z-index: 999999;\n}\n\n.feedback-panel-backdrop.show {\n opacity: 1;\n pointer-events: auto;\n}\n\n.feedback-panel-content {\n background: var(--bg-color, #ffffff);\n color: var(--text-color, #171717);\n height: 100%;\n display: flex;\n flex-direction: column;\n border-radius: 12px;\n border: 1px solid #e5e5e5;\n}\n\n.feedback-panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 24px 24px 20px 24px;\n flex-shrink: 0;\n}\n\n.feedback-panel-header h3 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--text-color, #171717);\n}\n\n.feedback-panel-close {\n background: none;\n border: none;\n font-size: 20px;\n cursor: pointer;\n color: #737373;\n padding: 0;\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 8px;\n transition: all 0.15s ease;\n}\n\n.feedback-panel-close:hover {\n background: #f5f5f5;\n color: #171717;\n}\n\n.feedback-panel-close:focus-visible {\n outline: 2px solid var(--primary-color, #21244A);\n outline-offset: 2px;\n}\n\n.feedback-panel-body {\n flex: 1;\n overflow-y: auto;\n padding: 0 24px 24px 24px;\n}\n\n.feedback-form {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.feedback-form-group {\n margin-bottom: 16px;\n}\n\n.feedback-form-group:last-child {\n margin-bottom: 0;\n}\n\n/* Unified input container */\n.feedback-input-container {\n border: 1px solid #e5e5e5;\n border-radius: 8px;\n padding: 16px;\n background: #ffffff;\n transition: all 0.15s ease;\n}\n\n.feedback-input-container:focus-within {\n border-color: var(--primary-color, #21244A);\n box-shadow: 0 0 0 3px rgba(33, 36, 74, 0.08);\n}\n\n.feedback-form-group input,\n.feedback-form-group textarea {\n width: 100%;\n border: none;\n padding: 0;\n font-size: 14px;\n font-family: inherit;\n color: var(--text-color, #171717);\n background: transparent;\n outline: none;\n resize: none;\n}\n\n.feedback-form-group input {\n font-weight: 600;\n font-size: 15px;\n margin-bottom: 12px;\n}\n\n.feedback-form-group input::placeholder {\n color: #737373;\n font-weight: 600;\n}\n\n.feedback-form-group textarea {\n min-height: 120px;\n font-weight: 400;\n}\n\n.feedback-form-group textarea::placeholder {\n color: #a3a3a3;\n font-weight: 400;\n}\n\n.feedback-btn {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n border-radius: 8px;\n border: none;\n height: 44px;\n padding: 10px 18px;\n font-size: 15px;\n font-weight: 500;\n font-family: inherit;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.feedback-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.feedback-btn:focus-visible {\n outline: 2px solid #21244A;\n outline-offset: 2px;\n}\n\n.feedback-btn-submit {\n background: var(--primary-color, #21244A);\n color: white;\n width: 100%;\n}\n\n.feedback-btn-submit:hover:not(:disabled) {\n background: #2d3159;\n}\n\n.feedback-btn-submit:active:not(:disabled) {\n transform: scale(0.98);\n}\n\n.feedback-error {\n background: #FEF2F2;\n border: 1px solid #FEE2E2;\n color: #DC2626;\n padding: 12px 14px;\n border-radius: 8px;\n font-size: 13px;\n margin-top: 12px;\n display: none;\n}\n\n.feedback-error.show {\n display: block;\n}\n\n.feedback-success-notification {\n position: fixed;\n top: 24px;\n right: 24px;\n z-index: 1000002;\n background: white;\n border: 1px solid #D1FAE5;\n border-radius: 12px;\n box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);\n animation: slideInRight 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n min-width: 320px;\n}\n\n.feedback-success-content {\n display: flex;\n align-items: center;\n padding: 16px 20px;\n gap: 12px;\n}\n\n.feedback-success-icon {\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: #10B981;\n color: white;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n font-weight: 600;\n flex-shrink: 0;\n}\n\n.feedback-success-content span {\n color: #065F46;\n font-weight: 500;\n font-size: 14px;\n flex: 1;\n}\n\n.feedback-success-close {\n background: none;\n border: none;\n color: #6B7280;\n cursor: pointer;\n font-size: 20px;\n padding: 0;\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n border-radius: 4px;\n flex-shrink: 0;\n}\n\n.feedback-success-close:hover {\n background: #F3F4F6;\n color: #374151;\n}\n\n.feedback-success-close:focus-visible {\n outline: 2px solid #21244A;\n outline-offset: 2px;\n}\n\n@keyframes slideInRight {\n from {\n transform: translateX(400px);\n opacity: 0;\n }\n to {\n transform: translateX(0);\n opacity: 1;\n }\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.feedback-panel-backdrop {\n animation: fadeIn 0.3s ease;\n}\n\n@media (max-width: 768px) {\n .feedback-panel {\n width: 100%;\n top: auto;\n bottom: 0;\n right: 0;\n left: 0;\n height: 85vh;\n max-height: 85vh;\n transform: translateY(100%);\n border-radius: 20px 20px 0 0;\n }\n \n .feedback-panel.open {\n transform: translateY(0);\n }\n \n .feedback-panel-content {\n border-radius: 20px 20px 0 0;\n }\n \n .feedback-panel-header {\n padding: 20px;\n position: relative;\n }\n \n .feedback-panel-header::before {\n content: '';\n position: absolute;\n top: 8px;\n left: 50%;\n transform: translateX(-50%);\n width: 40px;\n height: 4px;\n background: #D1D5DB;\n border-radius: 2px;\n }\n \n .feedback-panel-body {\n padding: 20px;\n }\n \n .feedback-widget-button {\n bottom: 16px;\n right: 16px;\n }\n \n .feedback-widget-button.position-bottom-left {\n left: 16px;\n }\n \n .feedback-success-notification {\n top: 16px;\n right: 16px;\n left: 16px;\n min-width: auto;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .feedback-trigger-btn,\n .feedback-btn,\n .feedback-panel,\n .feedback-panel-backdrop,\n .feedback-success-notification {\n transition: none;\n animation: none;\n }\n}\n\n@media print {\n .feedback-widget,\n .feedback-panel,\n .feedback-panel-backdrop,\n .feedback-success-notification {\n display: none !important;\n }\n}\n`;\n"],"names":["SDKError","Error","constructor","message","cause","super","this","name","captureStackTrace","APIError","status","response","isNetworkError","isClientError","isServerError","WidgetError","widgetType","widgetId","ConfigError","configKey","ValidationError","field","value","MOCK_CONFIG","primaryColor","backgroundColor","textColor","boardId","size","displayMode","ENV_URLS","production","base","withWorkspace","workspace","staging","APIService","config","sessionToken","sessionExpiry","userContext","mock","env","apiUrl","baseURL","envConfig","_loadStoredSession","init","isSessionValid","error","Date","now","_storeSession","expiresIn","payload","user","_makeRequest","method","body","JSON","stringify","headers","session_token","expires_in","submitFeedback","feedbackData","Promise","resolve","setTimeout","success","data","id","title","content","board","board_id","attachments","Authorization","setUserContext","localStorage","setItem","getUserContext","clearSession","removeItem","sessionData","token","expiry","toISOString","stored","getItem","parse","endpoint","options","url","fetch","ok","errorMessage","responseData","json","e","text","contentType","get","includes","EventBus","events","Map","on","event","callback","has","set","push","off","callbacks","index","indexOf","splice","emit","forEach","console","once","unsubscribe","clear","getListenerCount","length","generateId","prefix","Math","random","toString","substring","deepMerge","target","source","result","key","hasOwnProperty","Array","isArray","isBrowser","window","document","func","wait","timeout","args","clearTimeout","ms","string","replace","bytes","i","floor","log","parseFloat","pow","toFixed","userAgent","navigator","platform","language","userLanguage","cookieEnabled","screenResolution","screen","width","height","windowSize","innerWidth","innerHeight","timezone","Intl","DateTimeFormat","resolvedOptions","timeZone","element","property","fallback","getComputedStyle","getPropertyValue","obj","path","defaultValue","undefined","keys","split","current","rect","getBoundingClientRect","top","left","bottom","documentElement","clientHeight","right","clientWidth","test","email","trim","str","div","createElement","textContent","innerHTML","scrollIntoView","behavior","block","inline","lastKey","pop","limit","lastFunc","lastRan","required","missing","join","BaseWidget","sdk","apiService","type","container","position","autoShow","showBackdrop","customStyles","panelElement","backdropElement","mounted","destroyed","state","isOpen","isLoading","isSubmitting","errors","_bindMethods","mount","querySelector","_render","appendChild","_attachEvents","onMount","show","eventBus","widget","style","display","hide","openPanel","_showLoadingModal","_hideLoadingModal","_renderPanel","requestAnimationFrame","classList","add","className","loadingElement","theme","remove","closePanel","parentNode","removeChild","_resetForm","_hideError","_updateSubmitButton","_showError","_showSuccessMessage","feedback","handleConfigUpdate","newConfig","_updateTheme","destroy","onDestroy","bind","addEventListener","modeClass","sizeClass","setProperty","_getPanelHTML","_attachPanelEvents","firstInput","focus","panel","preventDefault","handleEscape","removeEventListener","submitBtn","disabled","errorElement","notification","closeNotification","opacity","openModal","closeModal","ButtonWidget","button","Object","assign","transform","updateText","warn","updatePosition","InlineWidget","form","textarea","originalContent","updateTitle","titleElement","setPlaceholder","placeholder","input","SurveyWidget","surveyOptions","surveyType","description","lowLabel","highLabel","customQuestions","onSubmit","onDismiss","surveyState","score","customAnswers","isVisible","_renderSurvey","_closeSurvey","_getSurveyConfig","positionStyles","_getPositionStyles","themeStyles","_handleDismiss","surveyElement","cssText","html","_attachSurveyEvents","configs","nps","map","n","csat","emoji","ces","label","custom","_renderCustomQuestions","q","_renderQuestionInput","freq","question","opt","positions","center","_handleSubmit","_attachTypeSpecificEvents","_escapeHandler","querySelectorAll","btn","_selectNPS","parseInt","dataset","borderColor","_selectCSAT","_selectCES","_selectFrequency","select","background","color","btnScore","frequency","timestamp","submitSurveyResponse","_showSuccessNotification","existing","insertBefore","transition","surveyEl","backdropEl","TabWidget","tab","_getHoverTransform","textElement","WidgetFactory","static","register","WidgetClass","widgets","create","availableTypes","from","getAvailableTypes","isTypeRegistered","unregister","delete","getWidgetClass","FeedbackSDK","_validateAndMergeConfig","initialized","alreadyInitialized","initData","createWidget","widgetOptions","getWidget","showSurvey","surveyWidget","getAllWidgets","values","destroyWidget","destroyAllWidgets","updateConfig","oldConfig","reinitialize","newUserContext","removeAllListeners","existingConfig","mergedConfig","debug","_validateUserContext","user_id","validStructure","custom_fields","company","expectedType","entries","createAndInit","extractUserContextFromAuth","authData","sub","display_name","full_name","role","plan","subscription","organization","monthly_spend","injectStyles","head","autoInit","FeedbackSDKConfig","then","instance","autoCreate","widgetConfig","CustomEvent","detail","dispatchEvent","catch","phase","FeedbackSDKExport","helpers","version","isReady","Boolean","getInstance","FeedbackSDKUserContext","initWithUser","async","fullConfig","onReady","onError","extractUserContext","readyState"],"mappings":"kPAAO,MAAMA,UAAiBC,MAC7B,WAAAC,CAAYC,EAASC,GACpBC,MAAMF,GACNG,KAAKC,KAAO,WACZD,KAAKF,MAAQA,EAETH,MAAMO,mBACTP,MAAMO,kBAAkBF,KAAMN,EAEhC,EAGM,MAAMS,UAAiBR,MAC7B,WAAAC,CAAYQ,EAAQP,EAASQ,GAC5BN,MAAMF,GACNG,KAAKC,KAAO,WACZD,KAAKI,OAASA,EACdJ,KAAKK,SAAWA,EAEZV,MAAMO,mBACTP,MAAMO,kBAAkBF,KAAMG,EAEhC,CAEA,cAAAG,GACC,OAAuB,IAAhBN,KAAKI,MACb,CAEA,aAAAG,GACC,OAAOP,KAAKI,QAAU,KAAOJ,KAAKI,OAAS,GAC5C,CAEA,aAAAI,GACC,OAAOR,KAAKI,QAAU,KAAOJ,KAAKI,OAAS,GAC5C,EAGM,MAAMK,UAAoBd,MAChC,WAAAC,CAAYC,EAASa,EAAYC,GAChCZ,MAAMF,GACNG,KAAKC,KAAO,cACZD,KAAKU,WAAaA,EAClBV,KAAKW,SAAWA,EAEZhB,MAAMO,mBACTP,MAAMO,kBAAkBF,KAAMS,EAEhC,EAGM,MAAMG,UAAoBjB,MAChC,WAAAC,CAAYC,EAASgB,GACpBd,MAAMF,GACNG,KAAKC,KAAO,cACZD,KAAKa,UAAYA,EAEblB,MAAMO,mBACTP,MAAMO,kBAAkBF,KAAMY,EAEhC,EAGM,MAAME,UAAwBnB,MACpC,WAAAC,CAAYC,EAASkB,EAAOC,GAC3BjB,MAAMF,GACNG,KAAKC,KAAO,kBACZD,KAAKe,MAAQA,EACbf,KAAKgB,MAAQA,EAETrB,MAAMO,mBACTP,MAAMO,kBAAkBF,KAAMc,EAEhC,ECtED,MAAMG,EAAc,CACnBC,aAAc,UACdC,gBAAiB,UACjBC,UAAW,UACXC,QAAS,mBACTC,KAAM,SACNC,YAAa,SAGRC,EAAW,CAChBC,WAAY,CACXC,KAAM,iCACNC,cAAgBC,GAAc,WAAWA,4BAE1CC,QAAS,CACRH,KAAM,yCACNC,cAAgBC,GACf,WAAWA,qCAIP,MAAME,EACZ,WAAAlC,CAAYmC,EAAS,IAQpB,GAPA/B,KAAK4B,UAAYG,EAAOH,UACxB5B,KAAKgC,aAAe,KACpBhC,KAAKiC,cAAgB,KACrBjC,KAAKkC,YAAcH,EAAOG,aAAe,KACzClC,KAAKmC,KAAOJ,EAAOI,OAAQ,EAC3BnC,KAAKoC,IAAML,EAAOK,KAAO,aAErBL,EAAOM,OACVrC,KAAKsC,QAAUP,EAAOM,WAChB,CACN,MAAME,EAAYf,EAASxB,KAAKoC,MAAQZ,EAASC,WACjDzB,KAAKsC,QAAUtC,KAAK4B,UACjBW,EAAUZ,cAAc3B,KAAK4B,WAC7BW,EAAUb,IACd,CAEA1B,KAAKwC,oBACN,CAEA,UAAMC,CAAKP,EAAc,MAKxB,GAJIA,IACHlC,KAAKkC,YAAcA,GAGhBlC,KAAK0C,iBACR,MAAO,CAAEV,aAAchC,KAAKgC,cAG7B,IAAKhC,KAAKkC,cAAgBlC,KAAK4B,UAAW,CACzC,MAAMe,EAAQ,WAAY3C,KAAK4B,UAA0B,eAAd,iCAC3C,MAAM,IAAIzB,EAAS,IAAKwC,EACzB,CAGA,GAAI3C,KAAKmC,KAIR,OAHAnC,KAAKgC,aAAe,gBAAkBY,KAAKC,MAC3C7C,KAAKiC,cAAgB,IAAIW,KAAKA,KAAKC,MAAQ,MAC3C7C,KAAK8C,gBACE,CACNd,aAAchC,KAAKgC,aACnBD,OAAQd,EACR8B,UAAW,MAIb,MAAMC,EAAU,CACfpB,UAAW5B,KAAK4B,UAChBqB,KAAMjD,KAAKkC,aAGZ,IACC,MAAM7B,QAAiBL,KAAKkD,aAAa,eAAgB,CACxDC,OAAQ,OACRC,KAAMC,KAAKC,UAAUN,GACrBO,QAAS,CACR,eAAgB,sBAQlB,OAJAvD,KAAKgC,aAAe3B,EAASmD,cAC7BxD,KAAKiC,cAAgB,IAAIW,KAAKA,KAAKC,MAA8B,IAAtBxC,EAASoD,YACpDzD,KAAK8C,gBAEE,CACNd,aAAchC,KAAKgC,aACnBD,OAAQ1B,EAAS0B,QAAU,CAAA,EAC3BgB,UAAW1C,EAASoD,WAEtB,CAAE,MAAOd,GACR,MAAM,IAAIxC,EACTwC,EAAMvC,QAAU,IAChB,gCAAgCuC,EAAM9C,UACtC8C,EAAMtC,SAER,CACD,CAEA,oBAAMqD,CAAeC,GAKpB,GAJK3D,KAAK0C,wBACH1C,KAAKyC,QAGPzC,KAAKgC,aACT,MAAM,IAAI7B,EAAS,IAAK,oCAIzB,GAAIH,KAAKmC,KAER,aADM,IAAIyB,QAASC,GAAYC,WAAWD,EAAS,MAC5C,CACNE,SAAS,EACTC,KAAM,CACLC,GAAI,aAAerB,KAAKC,MACxBqB,MAAOP,EAAaO,MACpBC,QAASR,EAAaQ,SAEvBtE,QAAS,oCAIX,MAAMmD,EAAU,CACfoB,MACCT,EAAaU,UAAYV,EAAaS,OAAST,EAAatC,QAC7D6C,MAAOP,EAAaO,MACpBC,QAASR,EAAaQ,QACtBG,YAAaX,EAAaW,aAAe,IAG1C,IAUC,aATuBtE,KAAKkD,aAAa,mBAAoB,CAC5DC,OAAQ,OACRC,KAAMC,KAAKC,UAAUN,GACrBO,QAAS,CACR,eAAgB,mBAChBgB,cAAe,UAAUvE,KAAKgC,iBAKjC,CAAE,MAAOW,GACR,GAAqB,MAAjBA,EAAMvC,OAIT,OAHAJ,KAAKgC,aAAe,KACpBhC,KAAKiC,cAAgB,WACfjC,KAAKyC,OACJzC,KAAK0D,eAAeC,GAG5B,MAAM,IAAIxD,EACTwC,EAAMvC,QAAU,IAChB,8BAA8BuC,EAAM9C,UACpC8C,EAAMtC,SAER,CACD,CAEA,cAAAqC,GACC,OACC1C,KAAKgC,cAAgBhC,KAAKiC,eAAiB,IAAIW,KAAS5C,KAAKiC,aAE/D,CAEA,cAAAuC,CAAetC,GACdlC,KAAKkC,YAAcA,EACS,oBAAjBuC,cACVA,aAAaC,QACZ,0BACArB,KAAKC,UAAUpB,GAGlB,CAEA,cAAAyC,GACC,OAAO3E,KAAKkC,WACb,CAEA,YAAA0C,GACC5E,KAAKgC,aAAe,KACpBhC,KAAKiC,cAAgB,KACO,oBAAjBwC,eACVA,aAAaI,WAAW,uBACxBJ,aAAaI,WAAW,2BAE1B,CAEA,aAAA/B,GACC,GAA4B,oBAAjB2B,aAEX,IACC,MAAMK,EAAc,CACnBC,MAAO/E,KAAKgC,aACZgD,OAAQhF,KAAKiC,cAAcgD,cAC3BrD,UAAW5B,KAAK4B,WAEjB6C,aAAaC,QAAQ,sBAAuBrB,KAAKC,UAAUwB,GAC5D,CAAE,MAAOnC,GAET,CACD,CAEA,kBAAAH,GACC,GAA4B,oBAAjBiC,aAA8B,OAAO,EAEhD,IACC,MAAMS,EAAST,aAAaU,QAAQ,uBACpC,IAAKD,EAAQ,OAAO,EAEpB,MAAMJ,EAAczB,KAAK+B,MAAMF,GAI/B,OAHAlF,KAAKgC,aAAe8C,EAAYC,MAChC/E,KAAKiC,cAAgB,IAAIW,KAAKkC,EAAYE,QAEnChF,KAAK0C,gBACb,CAAE,MAAOC,GACR,OAAO,CACR,CACD,CAEA,kBAAMO,CAAamC,EAAUC,EAAU,IACtC,MAAMC,EAAM,GAAGvF,KAAKsC,UAAU+C,IAE9B,IACC,MAAMhF,QAAiBmF,MAAMD,EAAKD,GAElC,IAAKjF,EAASoF,GAAI,CACjB,IAAIC,EAAe,QAAQrF,EAASD,SAChCuF,EAAe,KAEnB,IACCA,QAAqBtF,EAASuF,OAC9BF,EACCC,EAAa9F,SAAW8F,EAAahD,OAAS+C,CAChD,CAAE,MAAOG,GACRH,QAAsBrF,EAASyF,QAAWJ,CAC3C,CAEA,MAAM,IAAIvF,EAASE,EAASD,OAAQsF,EAAcC,EACnD,CAEA,MAAMI,EAAc1F,EAASkD,QAAQyC,IAAI,gBACzC,OAAID,GAAeA,EAAYE,SAAS,0BAC1B5F,EAASuF,aAGVvF,EAASyF,MACvB,CAAE,MAAOnD,GACR,GAAIA,aAAiBxC,EACpB,MAAMwC,EAEP,MAAM,IAAIxC,EAAS,EAAGwC,EAAM9C,QAAS,KACtC,CACD,EC9PM,MAAMqG,EACZ,WAAAtG,GACCI,KAAKmG,OAAS,IAAIC,GACnB,CAEA,EAAAC,CAAGC,EAAOC,GAMT,OALKvG,KAAKmG,OAAOK,IAAIF,IACpBtG,KAAKmG,OAAOM,IAAIH,EAAO,IAExBtG,KAAKmG,OAAOH,IAAIM,GAAOI,KAAKH,GAErB,IAAMvG,KAAK2G,IAAIL,EAAOC,EAC9B,CAEA,GAAAI,CAAIL,EAAOC,GACV,MAAMK,EAAY5G,KAAKmG,OAAOH,IAAIM,GAClC,GAAIM,EAAW,CACd,MAAMC,EAAQD,EAAUE,QAAQP,GAC5BM,GAAQ,GACXD,EAAUG,OAAOF,EAAO,EAE1B,CACD,CAEA,IAAAG,CAAKV,EAAOtC,GACX,MAAM4C,EAAY5G,KAAKmG,OAAOH,IAAIM,GAC9BM,GACHA,EAAUK,QAASV,IAClB,IACCA,EAASvC,EACV,CAAE,MAAOrB,GACRuE,QAAQvE,MAAM,sCAAuCA,EACtD,GAGH,CAEA,IAAAwE,CAAKb,EAAOC,GACX,MAAMa,EAAcpH,KAAKqG,GAAGC,EAAQtC,IACnCuC,EAASvC,GACToD,MAED,OAAOA,CACR,CAEA,KAAAC,GACCrH,KAAKmG,OAAOkB,OACb,CAEA,gBAAAC,CAAiBhB,GAChB,MAAMM,EAAY5G,KAAKmG,OAAOH,IAAIM,GAClC,OAAOM,EAAYA,EAAUW,OAAS,CACvC,ECpDM,SAASC,EAAWC,EAAS,YAGnC,MAAO,GAAGA,KAFQ7E,KAAKC,SACR6E,KAAKC,SAASC,SAAS,IAAIC,UAAU,EAAG,IAExD,CAEO,SAASC,EAAUC,EAAQC,GACjC,MAAMC,EAAS,IAAKF,GAEpB,IAAK,MAAMG,KAAOF,EACbA,EAAOG,eAAeD,KAExBF,EAAOE,IACgB,iBAAhBF,EAAOE,KACbE,MAAMC,QAAQL,EAAOE,IAEtBD,EAAOC,GAAOJ,EAAUC,EAAOG,IAAQ,CAAA,EAAIF,EAAOE,IAElDD,EAAOC,GAAOF,EAAOE,IAKxB,OAAOD,CACR,CAkKO,SAASK,IACf,MAAyB,oBAAXC,QAA8C,oBAAbC,QAChD,8CAlKO,SAAkBC,EAAMC,GAC9B,IAAIC,EACJ,OAAO,YAA6BC,GAKnCC,aAAaF,GACbA,EAAU7E,WALI,KACb+E,aAAaF,GACbF,KAAQG,IAGmBF,EAC7B,CACD,oBAoGO,SAAeI,GACrB,OAAO,IAAIlF,QAASC,GAAYC,WAAWD,EAASiF,GACrD,cAUO,SAAqBC,GAC3B,OAAOA,EAAOC,QAAQ,sBAAuB,OAC9C,iBAxBO,SAAwBC,GAC9B,GAAc,IAAVA,EAAa,MAAO,UAExB,MAEMC,EAAIxB,KAAKyB,MAAMzB,KAAK0B,IAAIH,GAASvB,KAAK0B,IAFlC,OAIV,OAAOC,YAAYJ,EAAQvB,KAAK4B,IAJtB,KAI6BJ,IAAIK,QAAQ,IAAM,IAH3C,CAAC,QAAS,KAAM,KAAM,MAGiCL,EACtE,8BAvBO,WAIN,MAAO,CACNM,UAJiBC,UAAUD,UAK3BE,SAJgBD,UAAUC,SAK1BC,SAAUF,UAAUE,UAAYF,UAAUG,aAC1CC,cAAeJ,UAAUI,cACzBC,iBAAkB,GAAGC,OAAOC,SAASD,OAAOE,SAC5CC,WAAY,GAAG3B,OAAO4B,cAAc5B,OAAO6B,cAC3CC,SAAUC,KAAKC,iBAAiBC,kBAAkBC,SAEpD,iBAjDO,SAAwBC,EAASC,EAAUC,EAAW,IAC5D,IAAKF,IAAYC,EAAU,OAAOC,EAElC,IAEC,OADcrC,OAAOsC,iBAAiBH,GACzBI,iBAAiBH,IAAaC,CAC5C,CAAE,MAAOjI,GACR,OAAOiI,CACR,CACD,sBAoHO,WACN,OAAO,IAAIhI,MAAOqC,aACnB,oBAlDO,SAA2B8F,EAAKC,EAAMC,OAAeC,GAC3D,IAAKH,IAAQC,EAAM,OAAOC,EAE1B,MAAME,EAAOH,EAAKI,MAAM,KACxB,IAAIC,EAAUN,EAEd,IAAK,MAAM7C,KAAOiD,EAAM,CACvB,GAAIE,WAA+CnD,KAAOmD,GACzD,OAAOJ,EAERI,EAAUA,EAAQnD,EACnB,CAEA,OAAOmD,CACR,2BAhFO,SAAsBX,GAC5B,IAAKA,EAAS,OAAO,EAErB,MAAMY,EAAOZ,EAAQa,wBACrB,OACCD,EAAKE,KAAO,GACZF,EAAKG,MAAQ,GACbH,EAAKI,SACHnD,OAAO6B,aAAe5B,SAASmD,gBAAgBC,eACjDN,EAAKO,QAAUtD,OAAO4B,YAAc3B,SAASmD,gBAAgBG,YAE/D,WA6FO,WACN,QAAKxD,MAGJ,iEAAiEyD,KAChEtC,UAAUD,YACNjB,OAAO4B,YAAc,IAE5B,eA1IO,SAAsB6B,GAC5B,SAAKA,GAA0B,iBAAVA,IAEF,6BACDD,KAAKC,EAAMC,OAC9B,gBA2EO,SAAuBC,EAAKtB,EAAW,MAC7C,IACC,OAAOvH,KAAK+B,MAAM8G,EACnB,CAAE,MAAOvJ,GACR,OAAOiI,CACR,CACD,eA/EO,SAAsBsB,GAC5B,IAAKA,GAAsB,iBAARA,EAAkB,MAAO,GAE5C,MAAMC,EAAM3D,SAAS4D,cAAc,OAEnC,OADAD,EAAIE,YAAcH,EACXC,EAAIG,SACZ,kBA0BO,SAAyB5B,EAASpF,EAAU,IAClD,IAAKoF,EAAS,OAQdA,EAAQ6B,eAAe,CALtBC,SAAU,SACVC,MAAO,SACPC,OAAQ,aAGsCpH,GAChD,oBA2DO,SAA2ByF,EAAKC,EAAMhK,GAC5C,IAAK+J,IAAQC,EAAM,OAAOD,EAE1B,MAAMI,EAAOH,EAAKI,MAAM,KAClBuB,EAAUxB,EAAKyB,MACrB,IAAIvB,EAAUN,EAEd,IAAK,MAAM7C,KAAOiD,EACXjD,KAAOmD,GAAoC,iBAAjBA,EAAQnD,KACvCmD,EAAQnD,GAAO,CAAA,GAEhBmD,EAAUA,EAAQnD,GAInB,OADAmD,EAAQsB,GAAW3L,EACZ+J,CACR,WAlJO,SAAkBtC,EAAMoE,GAC9B,IAAIC,EACAC,EACJ,OAAO,YAAanE,GACdmE,GAIJlE,aAAaiE,GACbA,EAAWhJ,WACV,KACKlB,KAAKC,MAAQkK,GAAWF,IAC3BpE,KAAQG,GACRmE,EAAUnK,KAAKC,QAGjBgK,GAASjK,KAAKC,MAAQkK,MAXvBtE,KAAQG,GACRmE,EAAUnK,KAAKC,MAajB,CACD,iBAkJO,SAAwBd,EAAQiL,EAAW,IACjD,MAAMC,EAAU,GAEhB,IAAK,MAAM/E,KAAO8E,EACZjL,EAAOmG,IACX+E,EAAQvG,KAAKwB,GAIf,GAAI+E,EAAQ1F,OAAS,EACpB,MAAM,IAAI5H,MAAM,mCAAmCsN,EAAQC,KAAK,SAGjE,OAAO,CACR,IC1NO,MAAMC,EACZ,WAAAvN,CAAY0F,EAAU,IACrBtF,KAAKiE,GAAKqB,EAAQrB,GAClBjE,KAAKoN,IAAM9H,EAAQ8H,IACnBpN,KAAKqN,WAAa/H,EAAQ+H,WAC1BrN,KAAKsN,KAAOhI,EAAQgI,MAAQ,OAE5BtN,KAAKsF,QAAU,CACdiI,UAAW,KACXC,SAAUxN,KAAKoN,IAAIrL,OAAOyL,SAC1BnM,QAASrB,KAAKoN,IAAIrL,OAAOV,QACzBE,YAAa+D,EAAQ/D,aAAe,QACpCD,KAAMgE,EAAQhE,MAAQ,SACtBJ,aAAcoE,EAAQpE,cAAgB,UACtCC,gBAAiBmE,EAAQnE,iBAAmB,UAC5CC,UAAWkE,EAAQlE,WAAa,UAChCqM,UAAU,EACVC,cAAc,EACdC,aAAc,CAAA,KACXrI,GAGJtF,KAAK0K,QAAU,KACf1K,KAAK4N,aAAe,KACpB5N,KAAK6N,gBAAkB,KACvB7N,KAAK8N,SAAU,EACf9N,KAAK+N,WAAY,EAEjB/N,KAAKgO,MAAQ,CACZC,QAAQ,EACRC,WAAW,EACXC,cAAc,EACdjK,MAAO,GACPC,QAAS,GACT6H,MAAO,GACP1H,YAAa,GACb8J,OAAQ,CAAA,GAGTpO,KAAKqO,cACN,CAEA,KAAAC,CAAMf,GACL,OAAIvN,KAAK8N,SAAW9N,KAAK+N,YAEA,iBAAdR,IACVA,EAAY/E,SAAS+F,cAAchB,IAG/BA,IACJA,EAAY/E,SAASpF,MAGtBpD,KAAKuN,UAAYA,EACjBvN,KAAK0K,QAAU1K,KAAKwO,UACpBxO,KAAKuN,UAAUkB,YAAYzO,KAAK0K,SAEhC1K,KAAK8N,SAAU,EACf9N,KAAK0O,gBACL1O,KAAK2O,UAED3O,KAAKsF,QAAQmI,UAChBzN,KAAK4O,OAGN5O,KAAKoN,IAAIyB,SAAS7H,KAAK,iBAAkB,CAAE8H,OAAQ9O,QAtBRA,IAwB5C,CAEA,IAAA4O,GAIC,OAHI5O,KAAK0K,UACR1K,KAAK0K,QAAQqE,MAAMC,QAAU,SAEvBhP,IACR,CAEA,IAAAiP,GAIC,OAHIjP,KAAK0K,UACR1K,KAAK0K,QAAQqE,MAAMC,QAAU,QAEvBhP,IACR,CAEA,SAAAkP,GACClP,KAAKgO,MAAMC,QAAS,EAEa,UAA7BjO,KAAKsF,QAAQ/D,aAChBvB,KAAKmP,oBAELrL,WAAW,KACV9D,KAAKoP,oBACLpP,KAAKqP,eACLC,sBAAsB,KACjBtP,KAAK4N,cACR5N,KAAK4N,aAAa2B,UAAUC,IAAI,QAE7BxP,KAAK6N,iBACR7N,KAAK6N,gBAAgB0B,UAAUC,IAAI,WAGnC,OAEHxP,KAAKqP,eACLC,sBAAsB,KACjBtP,KAAK4N,cACR5N,KAAK4N,aAAa2B,UAAUC,IAAI,QAE7BxP,KAAK6N,iBACR7N,KAAK6N,gBAAgB0B,UAAUC,IAAI,UAIvC,CAEA,iBAAAL,GACCnP,KAAKgO,MAAME,WAAY,EAGvBlO,KAAK6N,gBAAkBrF,SAAS4D,cAAc,OAC9CpM,KAAK6N,gBAAgB4B,UAAY,0BACjCjH,SAASpF,KAAKqL,YAAYzO,KAAK6N,iBAG/B7N,KAAK0P,eAAiBlH,SAAS4D,cAAc,OAC7CpM,KAAK0P,eAAeD,UAAY,gCAAgCzP,KAAKsF,QAAQqK,QAC7E3P,KAAK0P,eAAepD,UAAY,6DAGhC9D,SAASpF,KAAKqL,YAAYzO,KAAK0P,gBAE/BJ,sBAAsB,KACrBtP,KAAK6N,gBAAgB0B,UAAUC,IAAI,QACnCxP,KAAK0P,eAAeH,UAAUC,IAAI,SAEpC,CAEA,iBAAAJ,GACCpP,KAAKgO,MAAME,WAAY,EACnBlO,KAAK0P,iBACR1P,KAAK0P,eAAeE,SACpB5P,KAAK0P,eAAiB,KAExB,CAEA,UAAAG,GACK7P,KAAK4N,cACR5N,KAAK4N,aAAa2B,UAAUK,OAAO,QAEhC5P,KAAK6N,iBACR7N,KAAK6N,gBAAgB0B,UAAUK,OAAO,QAGvC9L,WAAW,KACV9D,KAAKgO,MAAMC,QAAS,EAChBjO,KAAK4N,cAAgB5N,KAAK4N,aAAakC,aAC1C9P,KAAK4N,aAAakC,WAAWC,YAAY/P,KAAK4N,cAC9C5N,KAAK4N,aAAe,MAEjB5N,KAAK6N,iBAAmB7N,KAAK6N,gBAAgBiC,aAChD9P,KAAK6N,gBAAgBiC,WAAWC,YAAY/P,KAAK6N,iBACjD7N,KAAK6N,gBAAkB,MAExB7N,KAAKgQ,cACH,IACJ,CAEA,oBAAMtM,GACL,IAAI1D,KAAKgO,MAAMG,aAAf,CAEAnO,KAAKiQ,aAEL,IACCjQ,KAAKgO,MAAMG,cAAe,EAC1BnO,KAAKkQ,sBAEL,MAAMlN,EAAU,CACfkB,MAAOlE,KAAKgO,MAAM9J,OAAS,WAC3BC,QAASnE,KAAKgO,MAAM7J,QACpB6H,MAAOhM,KAAKgO,MAAMhC,MAClB3H,SAAUrE,KAAKsF,QAAQjE,QACvBiD,YAAatE,KAAKgO,MAAM1J,aAGzB,IAAKtE,KAAKgO,MAAM7J,QAAQ8H,OAEvB,YADAjM,KAAKmQ,WAAW,uCAIjB,MAAM9P,QAAiBL,KAAKqN,WAAW3J,eAAeV,GAEtDhD,KAAKoQ,sBACLpQ,KAAK6P,aAEL7P,KAAKoN,IAAIyB,SAAS7H,KAAK,qBAAsB,CAC5C8H,OAAQ9O,KACRqQ,SAAUhQ,GAEZ,CAAE,MAAOsC,GACR3C,KAAKmQ,WAAW,gDAChBnQ,KAAKoN,IAAIyB,SAAS7H,KAAK,iBAAkB,CAAE8H,OAAQ9O,KAAM2C,SAC1D,CAAC,QACA3C,KAAKgO,MAAMG,cAAe,EAC1BnO,KAAKkQ,qBACN,CApC6B,CAqC9B,CAEA,kBAAAI,CAAmBC,GAClBvQ,KAAKsF,QAAQqK,MAAQY,EAAUZ,MAC3B3P,KAAK0K,SACR1K,KAAKwQ,cAEP,CAEA,OAAAC,GACKzQ,KAAK+N,YAET/N,KAAK0Q,YACL1Q,KAAK6P,aAED7P,KAAK0K,SAAW1K,KAAK0K,QAAQoF,YAChC9P,KAAK0K,QAAQoF,WAAWC,YAAY/P,KAAK0K,SAG1C1K,KAAK+N,WAAY,EACjB/N,KAAK8N,SAAU,EACf9N,KAAKoN,IAAIyB,SAAS7H,KAAK,mBAAoB,CAAE8H,OAAQ9O,OACtD,CAEA,OAAA2O,GAAW,CACX,SAAA+B,GAAa,CAEb,OAAAlC,GACC,MAAM,IAAI7O,MAAM,mDACjB,CAEA,aAAA+O,GAEA,CAEA,YAAAL,GACCrO,KAAKkP,UAAYlP,KAAKkP,UAAUyB,KAAK3Q,MACrCA,KAAK6P,WAAa7P,KAAK6P,WAAWc,KAAK3Q,MACvCA,KAAK0D,eAAiB1D,KAAK0D,eAAeiN,KAAK3Q,KAChD,CAEA,YAAAqP,GACC,GAAIrP,KAAK4N,aAAc,OAEnB5N,KAAKsF,QAAQoI,eAAiB1N,KAAK6N,kBACtC7N,KAAK6N,gBAAkBrF,SAAS4D,cAAc,OAC9CpM,KAAK6N,gBAAgB4B,UAAY,0BACjCjH,SAASpF,KAAKqL,YAAYzO,KAAK6N,iBAE/B7N,KAAK6N,gBAAgB+C,iBAAiB,QAAS5Q,KAAK6P,aAGrD,MAAMgB,EACwB,UAA7B7Q,KAAKsF,QAAQ/D,YACV,iBACA,iBACEuP,EAAY,QAAQ9Q,KAAKsF,QAAQhE,OACvCtB,KAAK4N,aAAepF,SAAS4D,cAAc,OAC3CpM,KAAK4N,aAAa6B,UAAY,GAAGoB,KAAaC,IAC9C9Q,KAAK4N,aAAamB,MAAMgC,YACvB,kBACA/Q,KAAKsF,QAAQpE,cAEdlB,KAAK4N,aAAamB,MAAMgC,YACvB,aACA/Q,KAAKsF,QAAQnE,iBAEdnB,KAAK4N,aAAamB,MAAMgC,YAAY,eAAgB/Q,KAAKsF,QAAQlE,WACjEpB,KAAK4N,aAAatB,UAAYtM,KAAKgR,gBAEnCxI,SAASpF,KAAKqL,YAAYzO,KAAK4N,cAC/B5N,KAAKiR,qBAEL,MAAMC,EAAalR,KAAK4N,aAAaW,cAAc,mBAC/C2C,GACHpN,WAAW,IAAMoN,EAAWC,QAAS,IAEvC,CAEA,aAAAH,GACC,MAAO,sfAY4BhR,KAAKiE,oGAGjBjE,KAAKgO,MAAM9J,4FAGGlE,KAAKiE,iJAI3BjE,KAAKgO,MAAM7J,gQAMZnE,KAAKgO,MAAMG,aAAe,aAAe,2GAOxD,CACA,kBAAA8C,GACC,MAAMG,EAAQpR,KAAK4N,aAEnBwD,EACE7C,cAAc,yBACdqC,iBAAiB,QAAS5Q,KAAK6P,YAEpBuB,EAAM7C,cAAc,kBAC5BqC,iBAAiB,SAAW/K,IAChCA,EAAEwL,iBACFrR,KAAK0D,mBAGN0N,EACE7C,cAAc,uBACdqC,iBAAiB,QAAU/K,IAC3B7F,KAAKgO,MAAM9J,MAAQ2B,EAAEkC,OAAO/G,QAG9BoQ,EACE7C,cAAc,4BACdqC,iBAAiB,QAAU/K,IAC3B7F,KAAKgO,MAAM7J,QAAU0B,EAAEkC,OAAO/G,QAGhC,MAAMsQ,EAAgBzL,IACP,WAAVA,EAAEqC,MACLlI,KAAK6P,aACLrH,SAAS+I,oBAAoB,UAAWD,KAG1C9I,SAASoI,iBAAiB,UAAWU,EACtC,CAEA,mBAAApB,GACC,GAAIlQ,KAAK4N,aAAc,CACtB,MAAM4D,EAAYxR,KAAK4N,aAAaW,cAAc,wBAC9CiD,IACHA,EAAUnF,YAAcrM,KAAKgO,MAAMG,aAChC,aACA,gBACHqD,EAAUC,SAAWzR,KAAKgO,MAAMG,aAElC,CACD,CAEA,UAAAgC,CAAWtQ,GACV,GAAIG,KAAK4N,aAAc,CACtB,MAAM8D,EAAe1R,KAAK4N,aAAaW,cAAc,mBACjDmD,IACHA,EAAarF,YAAcxM,EAC3B6R,EAAanC,UAAUC,IAAI,QAE7B,CACD,CAEA,UAAAS,GACC,GAAIjQ,KAAK4N,aAAc,CACtB,MAAM8D,EAAe1R,KAAK4N,aAAaW,cAAc,mBACjDmD,GACHA,EAAanC,UAAUK,OAAO,OAEhC,CACD,CAEA,mBAAAQ,GACC,MAAMuB,EAAenJ,SAAS4D,cAAc,OAC5CuF,EAAalC,UAAY,gCACzBkC,EAAarF,UAAY,oQAQzB9D,SAASpF,KAAKqL,YAAYkD,GAE1B,MACMC,EAAoB,KACrBD,EAAa7B,aAChB6B,EAAa5C,MAAM8C,QAAU,IAC7B/N,WAAW,KACN6N,EAAa7B,YAChB6B,EAAa7B,WAAWC,YAAY4B,IAEnC,OARYA,EAAapD,cAAc,2BAYnCqC,iBAAiB,QAASgB,GAEnC9N,WAAW8N,EAAmB,IAC/B,CAEA,UAAA5B,GACChQ,KAAKgO,MAAM9J,MAAQ,GACnBlE,KAAKgO,MAAM7J,QAAU,GACrBnE,KAAKgO,MAAMhC,MAAQ,GACnBhM,KAAKgO,MAAMI,OAAS,CAAA,CACrB,CAEA,YAAAoC,GACKxQ,KAAK0K,UACR1K,KAAK0K,QAAQ+E,UAAYzP,KAAK0K,QAAQ+E,UAAUzG,QAC/C,YACA,SAAShJ,KAAKsF,QAAQqK,UAGpB3P,KAAK4N,eACR5N,KAAK4N,aAAa6B,UAAYzP,KAAK4N,aAAa6B,UAAUzG,QACzD,YACA,SAAShJ,KAAKsF,QAAQqK,SAGzB,CAEA,SAAAmC,GACC9R,KAAKkP,WACN,CAEA,UAAA6C,GACC/R,KAAK6P,YACN,ECzbM,MAAMmC,UAAqB7E,EACjC,WAAAvN,CAAY0F,GACXvF,MAAM,IAAKuF,EAASgI,KAAM,UAC3B,CAEA,OAAAkB,GACC,MAAMyD,EAASzJ,SAAS4D,cAAc,OAiBtC,OAhBA6F,EAAOxC,UAAY,gDAAgDzP,KAAKsF,QAAQqK,kBAAkB3P,KAAKsF,QAAQkI,WAC/GyE,EAAO3F,UAAY,k3EAWftM,KAAKsF,QAAQqI,cAChBuE,OAAOC,OAAOF,EAAOlD,MAAO/O,KAAKsF,QAAQqI,cAGnCsE,CACR,CACA,aAAAvD,GACC,MAAMuD,EAASjS,KAAK0K,QAAQ6D,cAAc,yBAC1C0D,EAAOrB,iBAAiB,QAAS5Q,KAAKkP,WAEtC+C,EAAOrB,iBAAiB,aAAc,KAChC5Q,KAAKgO,MAAMG,eACf8D,EAAOlD,MAAMqD,UAAY,gBAI3BH,EAAOrB,iBAAiB,aAAc,KACrCqB,EAAOlD,MAAMqD,UAAY,YAE3B,CAEA,UAAAC,CAAWvM,GACVoB,QAAQoL,KAAK,6DACd,CAEA,cAAAC,CAAe/E,GACdxN,KAAKsF,QAAQkI,SAAWA,EACpBxN,KAAK0K,UACR1K,KAAK0K,QAAQ+E,UAAYzP,KAAK0K,QAAQ+E,UAAUzG,QAC/C,mBACA,YAAYwE,KAGf,ECpDM,MAAMgF,UAAqBrF,EACjC,WAAAvN,CAAY0F,GACXvF,MAAM,IAAKuF,EAASgI,KAAM,UAC3B,CAEA,OAAAkB,GACC,MAAMM,EAAStG,SAAS4D,cAAc,OAyCtC,OAxCA0C,EAAOW,UAAY,gDAAgDzP,KAAKsF,QAAQqK,QAChFb,EAAOxC,UAAY,qUASEtM,KAAKgO,MAAM9J,oOAQnBlE,KAAKgO,MAAM7J,wOAOHnE,KAAKgO,MAAMhC,gRAW5BhM,KAAKsF,QAAQqI,cAChBuE,OAAOC,OAAOrD,EAAOC,MAAO/O,KAAKsF,QAAQqI,cAGnCmB,CACR,CAEA,aAAAJ,GACC,MAAM+D,EAAOzS,KAAK0K,QAAQ6D,cAAc,yBAExCkE,EAAK7B,iBAAiB,SAAW/K,IAChCA,EAAEwL,iBACFrR,KAAK0D,mBAGN+O,EAAKlE,cAAc,uBAAuBqC,iBAAiB,QAAU/K,IACpE7F,KAAKgO,MAAM9J,MAAQ2B,EAAEkC,OAAO/G,QAG7ByR,EACElE,cAAc,4BACdqC,iBAAiB,QAAU/K,IAC3B7F,KAAKgO,MAAM7J,QAAU0B,EAAEkC,OAAO/G,QAGhCyR,EAAKlE,cAAc,uBAAuBqC,iBAAiB,QAAU/K,IACpE7F,KAAKgO,MAAMhC,MAAQnG,EAAEkC,OAAO/G,OAE9B,CAEA,SAAA8Q,GACC,MAAMY,EAAW1S,KAAK0K,QAAQ6D,cAAc,4BACxCmE,GACHA,EAASvB,OAEX,CAEA,UAAAY,GAEA,CAEA,mBAAA3B,GACC,MAAMtB,EAAS9O,KAAK0K,QAAQ6D,cAAc,4BACpCoE,EAAkB7D,EAAOxC,UAE/BwC,EAAOxC,UAAY,4RASFwC,EAAOP,cAAc,uBAC7BqC,iBAAiB,QAAS,KAClC9B,EAAOxC,UAAYqG,EACnB3S,KAAK0O,gBACL1O,KAAKgQ,cAEP,CAEA,UAAAG,CAAWtQ,GACV,MAAM6R,EAAe1R,KAAK0K,QAAQ6D,cAAc,mBAC5CmD,IACHA,EAAarF,YAAcxM,EAC3B6R,EAAa3C,MAAMC,QAAU,QAE7BlL,WAAW,KACN4N,IACHA,EAAa3C,MAAMC,QAAU,SAE5B,KAEL,CAEA,mBAAAkB,GACC,MAAMsB,EAAYxR,KAAK0K,QAAQ6D,cAAc,wBACzCiD,IACHA,EAAUnF,YAAcrM,KAAKgO,MAAMG,aAChC,aACA,gBACHqD,EAAUC,SAAWzR,KAAKgO,MAAMG,aAElC,CAEA,WAAAyE,CAAY1O,GACX,MAAM2O,EAAe7S,KAAK0K,SAAS6D,cAAc,MAC7CsE,IACHA,EAAaxG,YAAcnI,EAE7B,CAEA,cAAA4O,CAAe/R,EAAOgS,GACrB,MAAMC,EAAQhT,KAAK0K,SAAS6D,cAAc,UAAUxN,OAChDiS,IACHA,EAAMD,YAAcA,EAEtB,EC7IM,MAAME,UAAqB9F,EACjC,WAAAvN,CAAY0F,GACXvF,MAAM,IAAKuF,EAASgI,KAAM,WAE1BtN,KAAKkT,cAAgB,CACpBC,WAAY7N,EAAQ6N,YAAc,MAClC3F,SAAUlI,EAAQkI,UAAY,eAC9BtJ,MAAOoB,EAAQpB,OAAS,KACxBkP,YAAa9N,EAAQ8N,aAAe,KACpCC,SAAU/N,EAAQ+N,UAAY,KAC9BC,UAAWhO,EAAQgO,WAAa,KAChCC,gBAAiBjO,EAAQiO,iBAAmB,GAC5C5D,MAAOrK,EAAQqK,OAAS,QACxB6D,SAAUlO,EAAQkO,UAAY,KAC9BC,UAAWnO,EAAQmO,WAAa,MAGjCzT,KAAK0T,YAAc,CAClBC,MAAO,KACPtD,SAAU,GACVuD,cAAe,CAAA,EACfC,WAAW,EAEb,CAEA,OAAArF,GAEC,MAAMjB,EAAY/E,SAAS4D,cAAc,OAGzC,OAFAmB,EAAUkC,UAAY,4BACtBlC,EAAUwB,MAAMC,QAAU,OACnBzB,CACR,CAEA,aAAAmB,GAEA,CAEA,IAAAE,GAOC,OANA5O,KAAK8T,gBACL9T,KAAK0T,YAAYG,WAAY,EAC7B7T,KAAKoN,IAAIyB,SAAS7H,KAAK,eAAgB,CACtC8H,OAAQ9O,KACRsN,KAAMtN,KAAKkT,cAAcC,aAEnBnT,IACR,CAEA,IAAAiP,GAEC,OADAjP,KAAK+T,eACE/T,IACR,CAEA,aAAA8T,GAEC9T,KAAK+T,eAEL,MAAMhS,EAAS/B,KAAKgU,mBACdC,EAAiBjU,KAAKkU,qBACtBC,EACwB,SAA7BnU,KAAKkT,cAAcvD,MAChB,oCACA,oCAGgC,WAAhC3P,KAAKkT,cAAc1F,WACtBxN,KAAK6N,gBAAkBrF,SAAS4D,cAAc,OAC9CpM,KAAK6N,gBAAgB4B,UAAY,2BACjCjH,SAASpF,KAAKqL,YAAYzO,KAAK6N,iBAC/B7N,KAAK6N,gBAAgB+C,iBAAiB,QAAS,IAC9C5Q,KAAKoU,mBAIPpU,KAAKqU,cAAgB7L,SAAS4D,cAAc,OAC5CpM,KAAKqU,cAAc5E,UAAY,mCAAmCzP,KAAKkT,cAAc1F,kBAAkBxN,KAAKkT,cAAcvD,QAC1H3P,KAAKqU,cAActF,MAAMuF,QAAU,oBAAoBL,qBAAkCE,0LAEzFnU,KAAKqU,cAAc/H,UAAY,6KACmK,SAA7BtM,KAAKkT,cAAcvD,MAAmB,OAAS,4KAC5F5N,EAAOmC,0EAC1C,SAA7BlE,KAAKkT,cAAcvD,MAAmB,OAAS,oDAAoD5N,EAAOqR,+DAC1HrR,EAAOwS,iPAEoI,SAA7BvU,KAAKkT,cAAcvD,MAAmB,OAAS,2FAAwH,SAA7B3P,KAAKkT,cAAcvD,MAAmB,UAAY,kBAA+C,SAA7B3P,KAAKkT,cAAcvD,MAAmB,OAAS,+VAKnZnH,SAASpF,KAAKqL,YAAYzO,KAAKqU,eAC/BrU,KAAKwU,sBAGLlF,sBAAsB,KACrBtP,KAAKqU,cAActF,MAAM8C,QAAU,IACnC7R,KAAKqU,cAActF,MAAMqD,UACQ,WAAhCpS,KAAKkT,cAAc1F,SAChB,iCACA,iBAEN,CAEA,gBAAAwG,GACC,MAAMS,EAAU,CACfC,IAAK,CACJxQ,MACClE,KAAKkT,cAAchP,OAAS,sCAC7BkP,YACCpT,KAAKkT,cAAcE,aACnB,4FACDmB,KAAM,+HAEF,IAAInM,MAAM,IAAI+C,QACdwJ,IACCC,GAAM,uEAC8CA,0DAAuF,SAA7B5U,KAAKkT,cAAcvD,MAAmB,OAAS,8CAA2E,SAA7B3P,KAAKkT,cAAcvD,MAAmB,UAAY,uDAAoF,SAA7B3P,KAAKkT,cAAcvD,MAAmB,OAAS,sCAAsCiF,4BAG1Y1H,KAAK,wIAE2H,SAA7BlN,KAAKkT,cAAcvD,MAAmB,OAAS,mCAC5I3P,KAAKkT,cAAcG,UAAY,0CAC/BrT,KAAKkT,cAAcI,WAAa,oDAI3CuB,KAAM,CACL3Q,MAAOlE,KAAKkT,cAAchP,OAAS,yBACnCkP,YACCpT,KAAKkT,cAAcE,aACnB,iEACDmB,KAAM,0HAEF,CAAC,KAAM,KAAM,KAAM,KAAM,MACzBI,IACA,CAACG,EAAO5L,IAAM,wEACwCA,EAAI,2HAA2H4L,4BAGrL5H,KAAK,wIAE2H,SAA7BlN,KAAKkT,cAAcvD,MAAmB,OAAS,mCAC5I3P,KAAKkT,cAAcG,UAAY,iDAC/BrT,KAAKkT,cAAcI,WAAa,uDAI3CyB,IAAK,CACJ7Q,MAAOlE,KAAKkT,cAAchP,OAAS,mBACnCkP,YACCpT,KAAKkT,cAAcE,aACnB,iDACDmB,KAAM,+HAEF,CAAC,iBAAkB,YAAa,UAAW,OAAQ,aACnDI,IACA,CAACK,EAAO9L,IAAM,uEACuCA,EAAI,2DAAwF,SAA7BlJ,KAAKkT,cAAcvD,MAAmB,OAAS,8CAA2E,SAA7B3P,KAAKkT,cAAcvD,MAAmB,UAAY,uDAAoF,SAA7B3P,KAAKkT,cAAcvD,MAAmB,OAAS,sCAAsCqF,4BAG/Y9H,KAAK,mCAIV+H,OAAQ,CACP/Q,MAAOlE,KAAKkT,cAAchP,OAAS,iBACnCkP,YACCpT,KAAKkT,cAAcE,aACnB,gDACDmB,KAAMvU,KAAKkV,2BAIb,OAAOT,EAAQzU,KAAKkT,cAAcC,aAAesB,EAAQC,GAC1D,CAEA,sBAAAQ,GACC,OACElV,KAAKkT,cAAcK,iBAC0B,IAA9CvT,KAAKkT,cAAcK,gBAAgBhM,OA6B7BvH,KAAKkT,cAAcK,gBACxBoB,IACA,CAACQ,EAAGtO,IAAU,6IAE0EsO,EAAEH,0BACxFhV,KAAKoV,qBAAqBD,EAAGtO,0BAI/BqG,KAAK,IAnCC,sTAG8I,SAA7BlN,KAAKkT,cAAcvD,MAAmB,OAAS,+DAA4F,SAA7B3P,KAAKkT,cAAcvD,MAAmB,UAAY,kBAA+C,SAA7B3P,KAAKkT,cAAcvD,MAAmB,OAAS,klBAWpV,CAAC,QAAS,SAAU,UAAW,UAC/BgF,IACCU,GAAS,uEAC2CA,uDAAuF,SAA7BrV,KAAKkT,cAAcvD,MAAmB,OAAS,8CAA2E,SAA7B3P,KAAKkT,cAAcvD,MAAmB,UAAY,uDAAoF,SAA7B3P,KAAKkT,cAAcvD,MAAmB,OAAS,sCAAsC0F,4BAG1YnI,KAAK,+CAgBZ,CAEA,oBAAAkI,CAAqBE,EAAUzO,GAC9B,OAAQyO,EAAShI,MAChB,IAAK,SACJ,MAAO,qEACkDgI,EAASrR,IAAM4C,2DAA4F,SAA7B7G,KAAKkT,cAAcvD,MAAmB,OAAS,+DAA4F,SAA7B3P,KAAKkT,cAAcvD,MAAmB,UAAY,kBAA+C,SAA7B3P,KAAKkT,cAAcvD,MAAmB,OAAS,8CACnV2F,EAASvC,aAAe,4CACzCuC,EAAShQ,QAAQqP,IAAKY,GAAQ,kBAAkBA,EAAIvU,UAAUuU,EAAIP,kBAAkB9H,KAAK,qCAG9F,IAAK,OACJ,MAAO,+EAC4DoI,EAASrR,IAAM4C,mBAAuByO,EAASvC,aAAe,4DAAyF,SAA7B/S,KAAKkT,cAAcvD,MAAmB,OAAS,+DAA4F,SAA7B3P,KAAKkT,cAAcvD,MAAmB,UAAY,kBAA+C,SAA7B3P,KAAKkT,cAAcvD,MAAmB,OAAS,iDAE/Z,QACC,MAAO,GAEV,CAEA,kBAAAuE,GACC,MAAMsB,EAAY,CACjB,eACC,iGACD,cACC,gGACDC,OACC,4GACD/J,OACC,oJAEF,OAAO8J,EAAUxV,KAAKkT,cAAc1F,WAAagI,EAAU,eAC5D,CAEA,mBAAAhB,GACC,IAAKxU,KAAKqU,cAAe,OAGRrU,KAAKqU,cAAc9F,cAAc,0BACzCqC,iBAAiB,QAAS,IAAM5Q,KAAKoU,kBAG5BpU,KAAKqU,cAAc9F,cACpC,2BAESqC,iBAAiB,QAAS,IAAM5Q,KAAK0V,iBAG9B1V,KAAKqU,cAAc9F,cACnC,6BAEQqC,iBAAiB,QAAU/K,IACnC7F,KAAK0T,YAAYrD,SAAWxK,EAAEkC,OAAO/G,QAItChB,KAAK2V,4BAGL3V,KAAK4V,eAAkB/P,IACR,WAAVA,EAAEqC,KACLlI,KAAKoU,kBAGP5L,SAASoI,iBAAiB,UAAW5Q,KAAK4V,eAC3C,CAEA,yBAAAD,GACC,MAAMrI,EAAOtN,KAAKkT,cAAcC,WAEnB,QAAT7F,GACHtN,KAAKqU,cACHwB,iBAAiB,4BACjB5O,QAAS6O,IACTA,EAAIlF,iBAAiB,QAAS,IAC7B5Q,KAAK+V,WAAWC,SAASF,EAAIG,QAAQtC,SAEtCmC,EAAIlF,iBAAiB,aAAc,KAC9B5Q,KAAK0T,YAAYC,QAAUqC,SAASF,EAAIG,QAAQtC,SACnDmC,EAAI/G,MAAMmH,YAAc,aAG1BJ,EAAIlF,iBAAiB,aAAc,KAC9B5Q,KAAK0T,YAAYC,QAAUqC,SAASF,EAAIG,QAAQtC,SACnDmC,EAAI/G,MAAMmH,YACoB,SAA7BlW,KAAKkT,cAAcvD,MAAmB,OAAS,eAMxC,SAATrC,GACHtN,KAAKqU,cACHwB,iBAAiB,6BACjB5O,QAAS6O,IACTA,EAAIlF,iBAAiB,QAAS,IAC7B5Q,KAAKmW,YAAYH,SAASF,EAAIG,QAAQtC,SAEvCmC,EAAIlF,iBAAiB,aAAc,KAClCkF,EAAI/G,MAAMqD,UAAY,eAEvB0D,EAAIlF,iBAAiB,aAAc,KAC9B5Q,KAAK0T,YAAYC,QAAUqC,SAASF,EAAIG,QAAQtC,SACnDmC,EAAI/G,MAAMqD,UAAY,gBAMd,QAAT9E,GACHtN,KAAKqU,cACHwB,iBAAiB,4BACjB5O,QAAS6O,IACTA,EAAIlF,iBAAiB,QAAS,IAC7B5Q,KAAKoW,WAAWJ,SAASF,EAAIG,QAAQtC,SAEtCmC,EAAIlF,iBAAiB,aAAc,KAC9B5Q,KAAK0T,YAAYC,QAAUqC,SAASF,EAAIG,QAAQtC,SACnDmC,EAAI/G,MAAMmH,YAAc,aAG1BJ,EAAIlF,iBAAiB,aAAc,KAC9B5Q,KAAK0T,YAAYC,QAAUqC,SAASF,EAAIG,QAAQtC,SACnDmC,EAAI/G,MAAMmH,YACoB,SAA7BlW,KAAKkT,cAAcvD,MAAmB,OAAS,eAMxC,WAATrC,IAEHtN,KAAKqU,cACHwB,iBAAiB,6BACjB5O,QAAS6O,IACTA,EAAIlF,iBAAiB,QAAS,IAC7B5Q,KAAKqW,iBAAiBP,EAAIG,QAAQZ,SAKrCrV,KAAKqU,cACHwB,iBAAiB,2BACjB5O,QAASqP,IACTA,EAAO1F,iBAAiB,SAAW/K,IAClC7F,KAAK0T,YAAYE,cAAc0C,EAAOL,QAAQX,UAC7CzP,EAAEkC,OAAO/G,UAKbhB,KAAKqU,cACHwB,iBAAiB,0BACjB5O,QAAS+L,IACTA,EAAMpC,iBAAiB,QAAU/K,IAChC7F,KAAK0T,YAAYE,cAAcZ,EAAMiD,QAAQX,UAC5CzP,EAAEkC,OAAO/G,UAIf,CAEA,UAAA+U,CAAWpC,GACV3T,KAAK0T,YAAYC,MAAQA,EACzB3T,KAAKqU,cACHwB,iBAAiB,4BACjB5O,QAAS6O,IACQE,SAASF,EAAIG,QAAQtC,SACrBA,GAChBmC,EAAI/G,MAAMwH,WAAa,UACvBT,EAAI/G,MAAMmH,YAAc,UACxBJ,EAAI/G,MAAMyH,MAAQ,SAElBV,EAAI/G,MAAMwH,WACoB,SAA7BvW,KAAKkT,cAAcvD,MAAmB,UAAY,UACnDmG,EAAI/G,MAAMmH,YACoB,SAA7BlW,KAAKkT,cAAcvD,MAAmB,OAAS,UAChDmG,EAAI/G,MAAMyH,MACoB,SAA7BxW,KAAKkT,cAAcvD,MAAmB,OAAS,YAGpD,CAEA,WAAAwG,CAAYxC,GACX3T,KAAK0T,YAAYC,MAAQA,EACzB3T,KAAKqU,cACHwB,iBAAiB,6BACjB5O,QAAS6O,IACT,MAAMW,EAAWT,SAASF,EAAIG,QAAQtC,OACtCmC,EAAI/G,MAAMqD,UAAYqE,IAAa9C,EAAQ,aAAe,YAE7D,CAEA,UAAAyC,CAAWzC,GACV3T,KAAK0T,YAAYC,MAAQA,EACzB3T,KAAKqU,cACHwB,iBAAiB,4BACjB5O,QAAS6O,IACQE,SAASF,EAAIG,QAAQtC,SACrBA,GAChBmC,EAAI/G,MAAMwH,WAAa,UACvBT,EAAI/G,MAAMmH,YAAc,UACxBJ,EAAI/G,MAAMyH,MAAQ,SAElBV,EAAI/G,MAAMwH,WACoB,SAA7BvW,KAAKkT,cAAcvD,MAAmB,UAAY,UACnDmG,EAAI/G,MAAMmH,YACoB,SAA7BlW,KAAKkT,cAAcvD,MAAmB,OAAS,UAChDmG,EAAI/G,MAAMyH,MACoB,SAA7BxW,KAAKkT,cAAcvD,MAAmB,OAAS,YAGpD,CAEA,gBAAA0G,CAAiBhB,GAChBrV,KAAK0T,YAAYE,cAAc8C,UAAYrB,EAC3CrV,KAAKqU,cACHwB,iBAAiB,6BACjB5O,QAAS6O,IACLA,EAAIG,QAAQZ,OAASA,GACxBS,EAAI/G,MAAMwH,WAAa,UACvBT,EAAI/G,MAAMmH,YAAc,UACxBJ,EAAI/G,MAAMyH,MAAQ,SAElBV,EAAI/G,MAAMwH,WACoB,SAA7BvW,KAAKkT,cAAcvD,MAAmB,UAAY,UACnDmG,EAAI/G,MAAMmH,YACoB,SAA7BlW,KAAKkT,cAAcvD,MAAmB,OAAS,UAChDmG,EAAI/G,MAAMyH,MACoB,SAA7BxW,KAAKkT,cAAcvD,MAAmB,OAAS,YAGpD,CAEA,mBAAM+F,GACL,MAAMpI,EAAOtN,KAAKkT,cAAcC,WAGhC,IACW,QAAT7F,GAA2B,SAATA,GAA4B,QAATA,IACX,OAA3BtN,KAAK0T,YAAYC,MAGjB,YADA3T,KAAKmQ,WAAW,0BAIjB,MAAM9P,EAAW,CAChBiN,KAAMA,EACNqG,MAAO3T,KAAK0T,YAAYC,MACxBtD,SAAUrQ,KAAK0T,YAAYrD,SAC3BuD,cAAe5T,KAAK0T,YAAYE,cAChC+C,WAAW,IAAI/T,MAAOqC,eASvB,GALIjF,KAAKkT,cAAcM,UACtBxT,KAAKkT,cAAcM,SAASnT,IAIxBL,KAAKoN,IAAIrL,OAAOI,KACpB,UACOnC,KAAKqN,WAAWuJ,qBAAqBvW,EAC5C,CAAE,MAAOsC,GACRuE,QAAQvE,MAAM,0CAA2CA,EAC1D,CAGD3C,KAAKoN,IAAIyB,SAAS7H,KAAK,mBAAoB,CAAE8H,OAAQ9O,KAAMK,aAE3DL,KAAK+T,eACL/T,KAAK6W,0BACN,CAEA,cAAAzC,GACKpU,KAAKkT,cAAcO,WACtBzT,KAAKkT,cAAcO,YAEpBzT,KAAKoN,IAAIyB,SAAS7H,KAAK,mBAAoB,CAAE8H,OAAQ9O,OACrDA,KAAK+T,cACN,CAEA,UAAA5D,CAAWtQ,GAEV,MAAMiX,EAAW9W,KAAKqU,cAAc9F,cAAc,0BAC9CuI,GAAUA,EAASlH,SAEvB,MAAMjN,EAAQ6F,SAAS4D,cAAc,OACrCzJ,EAAM8M,UAAY,wBAClB9M,EAAMoM,MAAMuF,QACX,wEACD3R,EAAM0J,YAAcxM,EAEpB,MAAM2R,EAAYxR,KAAKqU,cAAc9F,cACpC,2BAEDiD,EAAU1B,WAAWiH,aAAapU,EAAO6O,GAEzC1N,WAAW,IAAMnB,EAAMiN,SAAU,IAClC,CAEA,wBAAAiH,GACC,MAAMlF,EAAenJ,SAAS4D,cAAc,OAC5CuF,EAAalC,UAAY,0BACzBkC,EAAa5C,MAAMuF,QAAU,mXAc7B3C,EAAarF,UAAY,8LAMzB9D,SAASpF,KAAKqL,YAAYkD,GAE1B7N,WAAW,KACV6N,EAAa5C,MAAM8C,QAAU,IAC7BF,EAAa5C,MAAMiI,WAAa,oBAChClT,WAAW,IAAM6N,EAAa/B,SAAU,MACtC,IACJ,CAEA,YAAAmE,GACK/T,KAAK4V,iBACRpN,SAAS+I,oBAAoB,UAAWvR,KAAK4V,gBAC7C5V,KAAK4V,eAAiB,MAIvB,MAAMqB,EAAWjX,KAAKqU,cAChB6C,EAAalX,KAAK6N,gBAEpBoJ,IACHA,EAASlI,MAAM8C,QAAU,IACzBoF,EAASlI,MAAMqD,UACkB,WAAhCpS,KAAKkT,cAAc1F,SAChB,oCACA,mBACJ1J,WAAW,KACNmT,GAAYA,EAASnH,YACxBmH,EAASnH,WAAWC,YAAYkH,IAE/B,KACHjX,KAAKqU,cAAgB,MAGlB6C,IACHA,EAAWnI,MAAM8C,QAAU,IAC3B/N,WAAW,KACNoT,GAAcA,EAAWpH,YAC5BoH,EAAWpH,WAAWC,YAAYmH,IAEjC,KACHlX,KAAK6N,gBAAkB,MAGxB7N,KAAK0T,YAAc,CAClBC,MAAO,KACPtD,SAAU,GACVuD,cAAe,CAAA,EACfC,WAAW,EAEb,CAEA,OAAApD,GACCzQ,KAAK+T,eACLhU,MAAM0Q,SACP,ECnlBM,MAAM0G,UAAkBhK,EAC9B,WAAAvN,CAAY0F,GACXvF,MAAM,IAAKuF,EAASgI,KAAM,OAC3B,CAEA,OAAAkB,GACC,MAAM4I,EAAM5O,SAAS4D,cAAc,OAYnC,OAXAgL,EAAI3H,UAAY,6CAA6CzP,KAAKsF,QAAQqK,kBAAkB3P,KAAKsF,QAAQkI,WACzG4J,EAAI9K,UAAY,0HAMZtM,KAAKsF,QAAQqI,cAChBuE,OAAOC,OAAOiF,EAAIrI,MAAO/O,KAAKsF,QAAQqI,cAGhCyJ,CACR,CAEA,aAAA1I,GACC,MAAM0I,EAAMpX,KAAK0K,QAAQ6D,cAAc,yBACvC6I,EAAIxG,iBAAiB,QAAS5Q,KAAK8R,WAEnCsF,EAAIxG,iBAAiB,aAAc,KAC7B5Q,KAAKgO,MAAMG,eACfiJ,EAAIrI,MAAMqD,UAAYpS,KAAKqX,wBAI7BD,EAAIxG,iBAAiB,aAAc,KAClCwG,EAAIrI,MAAMqD,UAAY,QAExB,CAEA,kBAAAiF,GACC,MAAM7J,EAAWxN,KAAKsF,QAAQkI,SAC9B,OAAIA,EAASvH,SAAS,SACd,mBACGuH,EAASvH,SAAS,QACrB,kBAED,MACR,CAEA,UAAAoM,CAAWvM,GACV,MAAMwR,EAActX,KAAK0K,SAAS6D,cAAc,sBAC5C+I,IACHA,EAAYjL,YAAcvG,EAE5B,CAEA,cAAAyM,CAAe/E,GACdxN,KAAKsF,QAAQkI,SAAWA,EACpBxN,KAAK0K,UACR1K,KAAK0K,QAAQ+E,UAAYzP,KAAK0K,QAAQ+E,UAAUzG,QAC/C,mBACA,YAAYwE,KAGf,ECzDM,MAAM+J,EACZC,eAAiB,IAAIpR,IAAI,CACxB,CAAC,SAAU4L,GACX,CAAC,MAAOmF,GACR,CAAC,SAAU3E,GACX,CAAC,SAAUS,KAGZ,eAAOwE,CAASnK,EAAMoK,GACrB,GAAoB,iBAATpK,IAAsBA,EAAKrB,OACrC,MAAM,IAAIvM,EAAS,0CAGpB,GAA2B,mBAAhBgY,EACV,MAAM,IAAIhY,EAAS,+CAGpBM,KAAK2X,QAAQlR,IAAI6G,EAAMoK,EACxB,CAEA,aAAOE,CAAOtK,EAAMhI,EAAU,IAC7B,MAAMoS,EAAc1X,KAAK2X,QAAQ3R,IAAIsH,GAErC,IAAKoK,EAAa,CACjB,MAAMG,EAAiBzP,MAAM0P,KAAK9X,KAAK2X,QAAQxM,QAAQ+B,KAAK,MAC5D,MAAM,IAAIxN,EACT,wBAAwB4N,uBAA0BuK,IAEpD,CAEA,IACC,OAAO,IAAIH,EAAYpS,EACxB,CAAE,MAAO3C,GACR,MAAM,IAAIjD,EACT,oCAAoC4N,OAAU3K,EAAM9C,UACpD8C,EAEF,CACD,CAEA,wBAAOoV,GACN,OAAO3P,MAAM0P,KAAK9X,KAAK2X,QAAQxM,OAChC,CAEA,uBAAO6M,CAAiB1K,GACvB,OAAOtN,KAAK2X,QAAQnR,IAAI8G,EACzB,CAEA,iBAAO2K,CAAW3K,GACjB,OAAOtN,KAAK2X,QAAQO,OAAO5K,EAC5B,CAEA,YAAOjG,GACNrH,KAAK2X,QAAQtQ,OACd,CAEA,qBAAO8Q,CAAe7K,GACrB,OAAOtN,KAAK2X,QAAQ3R,IAAIsH,EACzB,EC1DM,MAAM8K,EACZ,WAAAxY,CAAYmC,EAAS,IACpB/B,KAAK+B,OAAS/B,KAAKqY,wBAAwBtW,GAC3C/B,KAAKsY,aAAc,EACnBtY,KAAK2X,QAAU,IAAIvR,IACnBpG,KAAK6O,SAAW,IAAI3I,EAEpBlG,KAAKqN,WAAa,IAAIvL,EAAW,CAChCO,OAAQrC,KAAK+B,OAAOM,OACpBT,UAAW5B,KAAK+B,OAAOH,UACvBM,YAAalC,KAAK+B,OAAOG,YACzBC,KAAMnC,KAAK+B,OAAOI,KAClBC,IAAKpC,KAAK+B,OAAOK,MAGlBpC,KAAKqO,cACN,CAEA,UAAM5L,GACL,GAAIzC,KAAKsY,YACR,MAAO,CAAEC,oBAAoB,GAG9B,IACC,MAAMC,QAAiBxY,KAAKqN,WAAW5K,KAAKzC,KAAK+B,OAAOG,aAaxD,OAVIsW,EAASzW,SACZ/B,KAAK+B,OAAS+F,EAAU0Q,EAASzW,OAAQ/B,KAAK+B,SAG/C/B,KAAKsY,aAAc,EACnBtY,KAAK6O,SAAS7H,KAAK,kBAAmB,CACrCjF,OAAQ/B,KAAK+B,OACbC,aAAcwW,EAASxW,eAGjB,CACNsW,aAAa,EACbvW,OAAQyW,EAASzW,QAAU,CAAA,EAC3BC,aAAcwW,EAASxW,aACvBe,UAAWyV,EAASzV,UAEtB,CAAE,MAAOJ,GAER,MADA3C,KAAK6O,SAAS7H,KAAK,YAAa,CAAErE,UAC5B,IAAIjD,EAAS,6BAA6BiD,EAAM9C,UAAW8C,EAClE,CACD,CAEA,YAAA8V,CAAanL,EAAO,SAAUhI,EAAU,CAAA,GACvC,IAAKtF,KAAKsY,YACT,MAAM,IAAI5Y,EACT,uEAIF,MAAMiB,EAAW6G,EAAW,UACtBkR,EAAgB,CACrBzU,GAAItD,EACJyM,IAAKpN,KACLqN,WAAYrN,KAAKqN,cACdrN,KAAK+B,UACLuD,GAGJ,IACC,MAAMwJ,EAASyI,EAAcK,OAAOtK,EAAMoL,GAG1C,OAFA1Y,KAAK2X,QAAQlR,IAAI9F,EAAUmO,GAC3B9O,KAAK6O,SAAS7H,KAAK,iBAAkB,CAAE8H,SAAQxB,SACxCwB,CACR,CAAE,MAAOnM,GACR,MAAM,IAAIjD,EAAS,4BAA4BiD,EAAM9C,UAAW8C,EACjE,CACD,CAEA,SAAAgW,CAAU1U,GACT,OAAOjE,KAAK2X,QAAQ3R,IAAI/B,EACzB,CAgBA,UAAA2U,CAAWtT,EAAU,IACpB,IAAKtF,KAAKsY,YACT,MAAM,IAAI5Y,EACT,sEAIF,MAAMmZ,EAAe7Y,KAAKyY,aAAa,SAAU,CAChDtF,WAAY7N,EAAQ6N,YAAc7N,EAAQgI,MAAQ,MAClDE,SAAUlI,EAAQkI,UAAY,eAC9BmC,MAAOrK,EAAQqK,OAAS3P,KAAK+B,OAAO4N,OAAS,QAC7CzL,MAAOoB,EAAQpB,MACfkP,YAAa9N,EAAQ8N,YACrBC,SAAU/N,EAAQ+N,SAClBC,UAAWhO,EAAQgO,UACnBC,gBAAiBjO,EAAQiO,gBACzBC,SAAUlO,EAAQkO,SAClBC,UAAWnO,EAAQmO,YAMpB,OAHAoF,EAAavK,QACbuK,EAAajK,OAENiK,CACR,CAEA,aAAAC,GACC,OAAO1Q,MAAM0P,KAAK9X,KAAK2X,QAAQoB,SAChC,CAEA,aAAAC,CAAc/U,GACb,MAAM6K,EAAS9O,KAAK2X,QAAQ3R,IAAI/B,GAChC,QAAI6K,IACHA,EAAO2B,UACPzQ,KAAK2X,QAAQO,OAAOjU,GACpBjE,KAAK6O,SAAS7H,KAAK,iBAAkB,CAAErG,SAAUsD,KAC1C,EAGT,CAEA,iBAAAgV,GACC,IAAK,MAAMnK,KAAU9O,KAAK2X,QAAQoB,SACjCjK,EAAO2B,UAERzQ,KAAK2X,QAAQtQ,QACbrH,KAAK6O,SAAS7H,KAAK,kBACpB,CAEA,YAAAkS,CAAa3I,GACZ,MAAM4I,EAAY,IAAKnZ,KAAK+B,QAC5B/B,KAAK+B,OAAS/B,KAAKqY,wBAAwB9H,EAAWvQ,KAAK+B,QAE3D,IAAK,MAAM+M,KAAU9O,KAAK2X,QAAQoB,SACjCjK,EAAOwB,mBAAmBtQ,KAAK+B,QAGhC/B,KAAK6O,SAAS7H,KAAK,iBAAkB,CACpCmS,YACA5I,UAAWvQ,KAAK+B,QAElB,CAEA,cAAAyC,CAAetC,GACdlC,KAAK+B,OAAOG,YAAcA,EACtBlC,KAAKqN,YACRrN,KAAKqN,WAAW7I,eAAetC,GAEhClC,KAAK6O,SAAS7H,KAAK,eAAgB,CAAE9E,eACtC,CAEA,cAAAyC,GACC,OACC3E,KAAK+B,OAAOG,cACXlC,KAAKqN,WAAarN,KAAKqN,WAAW1I,iBAAmB,KAExD,CAEA,kBAAMyU,CAAaC,EAAiB,MAQnC,OAPArZ,KAAKqN,WAAWzI,eAChB5E,KAAKsY,aAAc,EAEfe,GACHrZ,KAAKwE,eAAe6U,GAGdrZ,KAAKyC,MACb,CAEA,EAAA4D,CAAGC,EAAOC,GAET,OADAvG,KAAK6O,SAASxI,GAAGC,EAAOC,GACjBvG,IACR,CAEA,GAAA2G,CAAIL,EAAOC,GAEV,OADAvG,KAAK6O,SAASlI,IAAIL,EAAOC,GAClBvG,IACR,CAEA,IAAAmH,CAAKb,EAAOC,GAEX,OADAvG,KAAK6O,SAAS1H,KAAKb,EAAOC,GACnBvG,IACR,CAEA,IAAAgH,CAAKV,EAAOtC,GAEX,OADAhE,KAAK6O,SAAS7H,KAAKV,EAAOtC,GACnBhE,IACR,CAEA,OAAAyQ,GACCzQ,KAAKiZ,oBACLjZ,KAAK6O,SAASyK,qBACdtZ,KAAKqN,WAAWzI,eAChB5E,KAAKsY,aAAc,EACnBtY,KAAK6O,SAAS7H,KAAK,gBACpB,CAEA,uBAAAqR,CAAwB9H,EAAWgJ,EAAiB,IACnD,MAaMC,EAAe1R,EACpBA,EAdqB,CACrBzF,OAAQ,KACRT,UAAW,KACXM,YAAa,KACbsL,SAAU,eACVmC,MAAO,QACPtO,QAAS,UACToM,UAAU,EACVgM,OAAO,EACPtX,MAAM,EACNC,IAAK,cAIoBmX,GACzBhJ,GAGD,IAAKiJ,EAAa5X,UACjB,MAAM,IAAIhB,EAAY,6CAOvB,OAJI4Y,EAAatX,aAChBlC,KAAK0Z,qBAAqBF,EAAatX,aAGjCsX,CACR,CAEA,oBAAAE,CAAqBxX,GACpB,IAAKA,EAAYyX,UAAYzX,EAAY8J,MACxC,MAAM,IAAIpL,EACT,uDAIF,MAAMgZ,EAAiB,CACtBD,QAAS,SACT3N,MAAO,SACP/L,KAAM,SACN4Z,cAAe,SACfC,QAAS,UAGV,IAAK,MAAO5R,EAAK6R,KAAiB7H,OAAO8H,QAAQJ,GAChD,GAAI1X,EAAYgG,WAAehG,EAAYgG,KAAS6R,EACnD,MAAM,IAAInZ,EACT,uBAAuBsH,uBAAyB6R,KAIpD,CAEA,YAAA1L,GACCrO,KAAKyY,aAAezY,KAAKyY,aAAa9H,KAAK3Q,MAC3CA,KAAKgZ,cAAgBhZ,KAAKgZ,cAAcrI,KAAK3Q,MAC7CA,KAAKkZ,aAAelZ,KAAKkZ,aAAavI,KAAK3Q,KAC5C,CAEA,aAAO4X,CAAO7V,GACb,OAAO,IAAIqW,EAAYrW,EACxB,CAEA,0BAAakY,CAAclY,GAC1B,MAAMqL,EAAM,IAAIgL,EAAYrW,GAE5B,aADMqL,EAAI3K,OACH2K,CACR,CAEA,iCAAO8M,CAA2BC,GACjC,OAAKA,EAEE,CACNR,QAASQ,EAASC,KAAOD,EAASlW,IAAMkW,EAASR,QACjD3N,MAAOmO,EAASnO,MAChB/L,KAAMka,EAASla,MAAQka,EAASE,cAAgBF,EAASG,UACzDT,cAAe,CACdU,KAAMJ,EAASI,KACfC,KAAML,EAASK,MAAQL,EAASM,cAAcD,QAC1CL,EAASN,eAAiB,IAE/BC,QACCK,EAASL,SAAWK,EAASO,aAC1B,CACAzW,GAAIkW,EAASL,SAAS7V,IAAMkW,EAASO,cAAczW,GACnDhE,KAAMka,EAASL,SAAS7Z,MAAQka,EAASO,cAAcza,KACvD0a,cAAeR,EAASL,SAASa,oBAEjCzP,GAlBiB,IAoBvB,EChSD,SAAS0P,IACR,GACqB,oBAAbpS,WACNA,SAAS+F,cAAc,wBACvB,CACD,MAAMQ,EAAQvG,SAAS4D,cAAc,SACrC2C,EAAM9K,GAAK,sBACX8K,EAAM1C,YC1BkB,mwUD2BxB7D,SAASqS,KAAKpM,YAAYM,EAC3B,CACD,CAEA,SAAS+L,IACR,GAAsB,oBAAXvS,QAA0BA,OAAOwS,kBAAmB,CAC9DH,IAEA,MAAM7Y,EAAS,IAAKwG,OAAOwS,mBACrB3N,EAAM,IAAIgL,EAAYrW,GAE5BqL,EACE3K,OACAuY,KAAMxC,IAGN,GAFAjQ,OAAO6P,YAAY6C,SAAW7N,EAE1B7E,OAAOwS,kBAAkBG,WAAY,EACxB9S,MAAMC,QAAQE,OAAOwS,kBAAkBG,YACpD3S,OAAOwS,kBAAkBG,WACzB,CAAC3S,OAAOwS,kBAAkBG,aAErBjU,QAASkU,IAChB,IACgB/N,EAAIqL,aAClB0C,EAAa7N,MAAQ,SACrB6N,GAEM7M,MAAM6M,EAAa5N,UAC3B,CAAE,MAAO5K,GACRuE,QAAQvE,MAAM,yCAA0CA,EACzD,GAEF,CAEA,GAA2B,oBAAhByY,YAA6B,CACvC,MAAM9U,EAAQ,IAAI8U,YAAY,mBAAoB,CACjDC,OAAQ,CAAEjO,MAAKrL,SAAQyW,cAExBjQ,OAAO+S,cAAchV,EACtB,IAEAiV,MAAO5Y,IAGP,GAFAuE,QAAQvE,MAAM,4CAA6CA,GAEhC,oBAAhByY,YAA6B,CACvC,MAAM9U,EAAQ,IAAI8U,YAAY,mBAAoB,CACjDC,OAAQ,CAAE1Y,QAAOZ,SAAQyZ,MAAO,oBAEjCjT,OAAO+S,cAAchV,EACtB,GAEH,CACD,CAYK,MAACmV,EAAoB,CACzBrD,cACAjL,aACA6E,eACAmF,YACA3E,eACAS,eACAsE,gBACArR,WACApE,aACApC,WACAS,WACAM,cACAG,cACAE,kBACA4a,UACA9D,OAAS7V,IACR6Y,IACO,IAAIxC,EAAYrW,IAExB4Z,QAAS,QACTV,SAAU,KAEVW,QAAS,IAAMC,QAAQJ,EAAkBR,UACzCa,YAAa,IAAML,EAAkBR,SAErCzW,eAAiBtC,IACZuZ,EAAkBR,SACrBQ,EAAkBR,SAASzW,eAAetC,GAEpB,oBAAXqG,SACVA,OAAOwT,uBAAyB7Z,IAKnC8Z,aAAcC,MAAOla,EAAQG,KAC5B0Y,IACA,MAAMsB,EAAa,IAAKna,EAAQG,eAC1BkL,EAAM,IAAIgL,EAAY8D,GAO5B,aANM9O,EAAI3K,OAEY,oBAAX8F,SACVA,OAAO6P,YAAY6C,SAAW7N,GAGxBA,GAGR+O,QAAU5V,IACa,oBAAXgC,SACNkT,EAAkBG,UACrBrV,EAASkV,EAAkBR,UAE3B1S,OAAOqI,iBACN,mBACCtK,IACAC,EAASD,EAAM+U,OAAOjO,IAAK9G,EAAM+U,SAElC,CAAElU,MAAM,MAMZiV,QAAU7V,IACa,oBAAXgC,QACVA,OAAOqI,iBAAiB,mBAAqBtK,IAC5CC,EAASD,EAAM+U,OAAO1Y,MAAO2D,EAAM+U,WAKtCgB,mBAAoBjE,EAAY8B,4BAGX,oBAAX3R,SACVA,OAAO6P,YAAcqD,EAtFG,oBAAbjT,WACkB,YAAxBA,SAAS8T,WACZ9T,SAASoI,iBAAiB,mBAAoBkK,GAE9ChX,WAAWgX,EAAU"}
|
|
1
|
+
{"version":3,"file":"feedback-sdk.min.js","sources":["../src/utils/errors.js","../src/core/APIService.js","../src/core/EventBus.js","../src/utils/helpers.js","../src/widgets/BaseWidget.js","../src/widgets/ButtonWidget.js","../src/widgets/InlineWidget.js","../src/widgets/SurveyWidget.js","../src/widgets/TabWidget.js","../src/widgets/WidgetFactory.js","../src/core/FeedbackSDK.js","../src/index.js","../src/styles/styles.js"],"sourcesContent":["export class SDKError extends Error {\n\tconstructor(message, cause) {\n\t\tsuper(message);\n\t\tthis.name = 'SDKError';\n\t\tthis.cause = cause;\n\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, SDKError);\n\t\t}\n\t}\n}\n\nexport class APIError extends Error {\n\tconstructor(status, message, response) {\n\t\tsuper(message);\n\t\tthis.name = 'APIError';\n\t\tthis.status = status;\n\t\tthis.response = response;\n\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, APIError);\n\t\t}\n\t}\n\n\tisNetworkError() {\n\t\treturn this.status === 0;\n\t}\n\n\tisClientError() {\n\t\treturn this.status >= 400 && this.status < 500;\n\t}\n\n\tisServerError() {\n\t\treturn this.status >= 500 && this.status < 600;\n\t}\n}\n\nexport class WidgetError extends Error {\n\tconstructor(message, widgetType, widgetId) {\n\t\tsuper(message);\n\t\tthis.name = 'WidgetError';\n\t\tthis.widgetType = widgetType;\n\t\tthis.widgetId = widgetId;\n\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, WidgetError);\n\t\t}\n\t}\n}\n\nexport class ConfigError extends Error {\n\tconstructor(message, configKey) {\n\t\tsuper(message);\n\t\tthis.name = 'ConfigError';\n\t\tthis.configKey = configKey;\n\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, ConfigError);\n\t\t}\n\t}\n}\n\nexport class ValidationError extends Error {\n\tconstructor(message, field, value) {\n\t\tsuper(message);\n\t\tthis.name = 'ValidationError';\n\t\tthis.field = field;\n\t\tthis.value = value;\n\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, ValidationError);\n\t\t}\n\t}\n}\n\nexport class ErrorHandler {\n\tconstructor(debug = false) {\n\t\tthis.debug = debug;\n\t}\n\n\thandle(error, context = '') {\n\t\tconst errorInfo = {\n\t\t\tname: error.name,\n\t\t\tmessage: error.message,\n\t\t\tcontext,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t};\n\n\t\tif (error instanceof APIError) {\n\t\t\terrorInfo.status = error.status;\n\t\t\terrorInfo.type = 'api';\n\t\t} else if (error instanceof WidgetError) {\n\t\t\terrorInfo.widgetType = error.widgetType;\n\t\t\terrorInfo.widgetId = error.widgetId;\n\t\t\terrorInfo.type = 'widget';\n\t\t} else if (error instanceof ConfigError) {\n\t\t\terrorInfo.configKey = error.configKey;\n\t\t\terrorInfo.type = 'config';\n\t\t} else if (error instanceof ValidationError) {\n\t\t\terrorInfo.field = error.field;\n\t\t\terrorInfo.value = error.value;\n\t\t\terrorInfo.type = 'validation';\n\t\t} else {\n\t\t\terrorInfo.type = 'unknown';\n\t\t}\n\n\t\tif (this.debug) {\n\t\t\tconsole.error('[FeedbackSDK Error]', errorInfo, error);\n\t\t} else {\n\t\t\tconsole.error('[FeedbackSDK Error]', error.message);\n\t\t}\n\n\t\treturn errorInfo;\n\t}\n\n\tgetUserMessage(error) {\n\t\tif (error instanceof APIError) {\n\t\t\tif (error.isNetworkError()) {\n\t\t\t\treturn 'Network error. Please check your connection and try again.';\n\t\t\t} else if (error.isClientError()) {\n\t\t\t\treturn 'Invalid request. Please check your input and try again.';\n\t\t\t} else if (error.isServerError()) {\n\t\t\t\treturn 'Server error. Please try again later.';\n\t\t\t}\n\t\t\treturn 'Failed to submit feedback. Please try again.';\n\t\t}\n\n\t\tif (error instanceof ValidationError) {\n\t\t\treturn `Please check your ${error.field}: ${error.message}`;\n\t\t}\n\n\t\tif (error instanceof ConfigError) {\n\t\t\treturn 'Configuration error. Please check your SDK setup.';\n\t\t}\n\n\t\tif (error instanceof WidgetError) {\n\t\t\treturn 'Widget error. Please try refreshing the page.';\n\t\t}\n\n\t\treturn 'An unexpected error occurred. Please try again.';\n\t}\n}\n","import { APIError } from '../utils/errors.js';\n\nconst MOCK_CONFIG = {\n\tprimaryColor: '#21244A',\n\tbackgroundColor: '#ffffff',\n\ttextColor: '#1F2937',\n\tboardId: 'feature-requests',\n\tsize: 'medium',\n\tdisplayMode: 'modal',\n};\n\nconst ENV_URLS = {\n\tproduction: {\n\t\tbase: 'https://api.product7.io/api/v1',\n\t\twithWorkspace: (workspace) => `https://${workspace}.api.product7.io/api/v1`,\n\t},\n\tstaging: {\n\t\tbase: 'https://staging.api.product7.io/api/v1',\n\t\twithWorkspace: (workspace) =>\n\t\t\t`https://${workspace}.staging.api.product7.io/api/v1`,\n\t},\n};\n\nexport class APIService {\n\tconstructor(config = {}) {\n\t\tthis.workspace = config.workspace;\n\t\tthis.sessionToken = null;\n\t\tthis.sessionExpiry = null;\n\t\tthis.userContext = config.userContext || null;\n\t\tthis.mock = config.mock || false;\n\t\tthis.env = config.env || 'production';\n\n\t\tif (config.apiUrl) {\n\t\t\tthis.baseURL = config.apiUrl;\n\t\t} else {\n\t\t\tconst envConfig = ENV_URLS[this.env] || ENV_URLS.production;\n\t\t\tthis.baseURL = this.workspace\n\t\t\t\t? envConfig.withWorkspace(this.workspace)\n\t\t\t\t: envConfig.base;\n\t\t}\n\n\t\tthis._loadStoredSession();\n\t}\n\n\tasync init(userContext = null) {\n\t\tif (userContext) {\n\t\t\tthis.userContext = userContext;\n\t\t}\n\n\t\tif (this.isSessionValid()) {\n\t\t\treturn { sessionToken: this.sessionToken };\n\t\t}\n\n\t\tif (!this.userContext || !this.workspace) {\n\t\t\tconst error = `Missing ${!this.workspace ? 'workspace' : 'user context'} for initialization`;\n\t\t\tthrow new APIError(400, error);\n\t\t}\n\n\t\t// Mock mode - return fake session\n\t\tif (this.mock) {\n\t\t\tthis.sessionToken = 'mock_session_' + Date.now();\n\t\t\tthis.sessionExpiry = new Date(Date.now() + 3600 * 1000);\n\t\t\tthis._storeSession();\n\t\t\treturn {\n\t\t\t\tsessionToken: this.sessionToken,\n\t\t\t\tconfig: MOCK_CONFIG,\n\t\t\t\texpiresIn: 3600,\n\t\t\t};\n\t\t}\n\n\t\tconst payload = {\n\t\t\tworkspace: this.workspace,\n\t\t\tuser: this.userContext,\n\t\t};\n\n\t\ttry {\n\t\t\tconst response = await this._makeRequest('/widget/init', {\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: JSON.stringify(payload),\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tthis.sessionToken = response.session_token;\n\t\t\tthis.sessionExpiry = new Date(Date.now() + response.expires_in * 1000);\n\t\t\tthis._storeSession();\n\n\t\t\treturn {\n\t\t\t\tsessionToken: this.sessionToken,\n\t\t\t\tconfig: response.config || {},\n\t\t\t\texpiresIn: response.expires_in,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tthrow new APIError(\n\t\t\t\terror.status || 500,\n\t\t\t\t`Failed to initialize widget: ${error.message}`,\n\t\t\t\terror.response\n\t\t\t);\n\t\t}\n\t}\n\n\tasync submitFeedback(feedbackData) {\n\t\tif (!this.isSessionValid()) {\n\t\t\tawait this.init();\n\t\t}\n\n\t\tif (!this.sessionToken) {\n\t\t\tthrow new APIError(401, 'No valid session token available');\n\t\t}\n\n\t\t// Mock mode - simulate success\n\t\tif (this.mock) {\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 500));\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: {\n\t\t\t\t\tid: 'mock_post_' + Date.now(),\n\t\t\t\t\ttitle: feedbackData.title,\n\t\t\t\t\tcontent: feedbackData.content,\n\t\t\t\t},\n\t\t\t\tmessage: 'Feedback submitted successfully!',\n\t\t\t};\n\t\t}\n\n\t\tconst payload = {\n\t\t\tboard:\n\t\t\t\tfeedbackData.board_id || feedbackData.board || feedbackData.boardId,\n\t\t\ttitle: feedbackData.title,\n\t\t\tcontent: feedbackData.content,\n\t\t\tattachments: feedbackData.attachments || [],\n\t\t};\n\n\t\ttry {\n\t\t\tconst response = await this._makeRequest('/widget/feedback', {\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: JSON.stringify(payload),\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\tAuthorization: `Bearer ${this.sessionToken}`,\n\t\t\t\t},\n\t\t\t});\n\n\t\t\treturn response;\n\t\t} catch (error) {\n\t\t\tif (error.status === 401) {\n\t\t\t\tthis.sessionToken = null;\n\t\t\t\tthis.sessionExpiry = null;\n\t\t\t\tawait this.init();\n\t\t\t\treturn this.submitFeedback(feedbackData);\n\t\t\t}\n\n\t\t\tthrow new APIError(\n\t\t\t\terror.status || 500,\n\t\t\t\t`Failed to submit feedback: ${error.message}`,\n\t\t\t\terror.response\n\t\t\t);\n\t\t}\n\t}\n\n\tisSessionValid() {\n\t\treturn (\n\t\t\tthis.sessionToken && this.sessionExpiry && new Date() < this.sessionExpiry\n\t\t);\n\t}\n\n\tsetUserContext(userContext) {\n\t\tthis.userContext = userContext;\n\t\tif (typeof localStorage !== 'undefined') {\n\t\t\tlocalStorage.setItem(\n\t\t\t\t'feedbackSDK_userContext',\n\t\t\t\tJSON.stringify(userContext)\n\t\t\t);\n\t\t}\n\t}\n\n\tgetUserContext() {\n\t\treturn this.userContext;\n\t}\n\n\tclearSession() {\n\t\tthis.sessionToken = null;\n\t\tthis.sessionExpiry = null;\n\t\tif (typeof localStorage !== 'undefined') {\n\t\t\tlocalStorage.removeItem('feedbackSDK_session');\n\t\t\tlocalStorage.removeItem('feedbackSDK_userContext');\n\t\t}\n\t}\n\n\t_storeSession() {\n\t\tif (typeof localStorage === 'undefined') return;\n\n\t\ttry {\n\t\t\tconst sessionData = {\n\t\t\t\ttoken: this.sessionToken,\n\t\t\t\texpiry: this.sessionExpiry.toISOString(),\n\t\t\t\tworkspace: this.workspace,\n\t\t\t};\n\t\t\tlocalStorage.setItem('feedbackSDK_session', JSON.stringify(sessionData));\n\t\t} catch (error) {\n\t\t\t// Silently fail if localStorage is not available\n\t\t}\n\t}\n\n\t_loadStoredSession() {\n\t\tif (typeof localStorage === 'undefined') return false;\n\n\t\ttry {\n\t\t\tconst stored = localStorage.getItem('feedbackSDK_session');\n\t\t\tif (!stored) return false;\n\n\t\t\tconst sessionData = JSON.parse(stored);\n\t\t\tthis.sessionToken = sessionData.token;\n\t\t\tthis.sessionExpiry = new Date(sessionData.expiry);\n\n\t\t\treturn this.isSessionValid();\n\t\t} catch (error) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tasync _makeRequest(endpoint, options = {}) {\n\t\tconst url = `${this.baseURL}${endpoint}`;\n\n\t\ttry {\n\t\t\tconst response = await fetch(url, options);\n\n\t\t\tif (!response.ok) {\n\t\t\t\tlet errorMessage = `HTTP ${response.status}`;\n\t\t\t\tlet responseData = null;\n\n\t\t\t\ttry {\n\t\t\t\t\tresponseData = await response.json();\n\t\t\t\t\terrorMessage =\n\t\t\t\t\t\tresponseData.message || responseData.error || errorMessage;\n\t\t\t\t} catch (e) {\n\t\t\t\t\terrorMessage = (await response.text()) || errorMessage;\n\t\t\t\t}\n\n\t\t\t\tthrow new APIError(response.status, errorMessage, responseData);\n\t\t\t}\n\n\t\t\tconst contentType = response.headers.get('content-type');\n\t\t\tif (contentType && contentType.includes('application/json')) {\n\t\t\t\treturn await response.json();\n\t\t\t}\n\n\t\t\treturn await response.text();\n\t\t} catch (error) {\n\t\t\tif (error instanceof APIError) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tthrow new APIError(0, error.message, null);\n\t\t}\n\t}\n}\n","export class EventBus {\n\tconstructor() {\n\t\tthis.events = new Map();\n\t}\n\n\ton(event, callback) {\n\t\tif (!this.events.has(event)) {\n\t\t\tthis.events.set(event, []);\n\t\t}\n\t\tthis.events.get(event).push(callback);\n\n\t\treturn () => this.off(event, callback);\n\t}\n\n\toff(event, callback) {\n\t\tconst callbacks = this.events.get(event);\n\t\tif (callbacks) {\n\t\t\tconst index = callbacks.indexOf(callback);\n\t\t\tif (index > -1) {\n\t\t\t\tcallbacks.splice(index, 1);\n\t\t\t}\n\t\t}\n\t}\n\n\temit(event, data) {\n\t\tconst callbacks = this.events.get(event);\n\t\tif (callbacks) {\n\t\t\tcallbacks.forEach((callback) => {\n\t\t\t\ttry {\n\t\t\t\t\tcallback(data);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error('[FeedbackSDK] Event callback error:', error);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tonce(event, callback) {\n\t\tconst unsubscribe = this.on(event, (data) => {\n\t\t\tcallback(data);\n\t\t\tunsubscribe();\n\t\t});\n\t\treturn unsubscribe;\n\t}\n\n\tclear() {\n\t\tthis.events.clear();\n\t}\n\n\tgetListenerCount(event) {\n\t\tconst callbacks = this.events.get(event);\n\t\treturn callbacks ? callbacks.length : 0;\n\t}\n}\n","export function generateId(prefix = 'feedback') {\n\tconst timestamp = Date.now();\n\tconst random = Math.random().toString(36).substring(2, 9);\n\treturn `${prefix}_${timestamp}_${random}`;\n}\n\nexport function deepMerge(target, source) {\n\tconst result = { ...target };\n\n\tfor (const key in source) {\n\t\tif (source.hasOwnProperty(key)) {\n\t\t\tif (\n\t\t\t\tsource[key] &&\n\t\t\t\ttypeof source[key] === 'object' &&\n\t\t\t\t!Array.isArray(source[key])\n\t\t\t) {\n\t\t\t\tresult[key] = deepMerge(target[key] || {}, source[key]);\n\t\t\t} else {\n\t\t\t\tresult[key] = source[key];\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result;\n}\n\nexport function debounce(func, wait) {\n\tlet timeout;\n\treturn function executedFunction(...args) {\n\t\tconst later = () => {\n\t\t\tclearTimeout(timeout);\n\t\t\tfunc(...args);\n\t\t};\n\t\tclearTimeout(timeout);\n\t\ttimeout = setTimeout(later, wait);\n\t};\n}\n\nexport function throttle(func, limit) {\n\tlet lastFunc;\n\tlet lastRan;\n\treturn function (...args) {\n\t\tif (!lastRan) {\n\t\t\tfunc(...args);\n\t\t\tlastRan = Date.now();\n\t\t} else {\n\t\t\tclearTimeout(lastFunc);\n\t\t\tlastFunc = setTimeout(\n\t\t\t\t() => {\n\t\t\t\t\tif (Date.now() - lastRan >= limit) {\n\t\t\t\t\t\tfunc(...args);\n\t\t\t\t\t\tlastRan = Date.now();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tlimit - (Date.now() - lastRan)\n\t\t\t);\n\t\t}\n\t};\n}\n\nexport function isValidEmail(email) {\n\tif (!email || typeof email !== 'string') return false;\n\n\tconst emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\treturn emailRegex.test(email.trim());\n}\n\nexport function sanitizeHTML(str) {\n\tif (!str || typeof str !== 'string') return '';\n\n\tconst div = document.createElement('div');\n\tdiv.textContent = str;\n\treturn div.innerHTML;\n}\n\nexport function getCSSProperty(element, property, fallback = '') {\n\tif (!element || !property) return fallback;\n\n\ttry {\n\t\tconst style = window.getComputedStyle(element);\n\t\treturn style.getPropertyValue(property) || fallback;\n\t} catch (error) {\n\t\treturn fallback;\n\t}\n}\n\nexport function isInViewport(element) {\n\tif (!element) return false;\n\n\tconst rect = element.getBoundingClientRect();\n\treturn (\n\t\trect.top >= 0 &&\n\t\trect.left >= 0 &&\n\t\trect.bottom <=\n\t\t\t(window.innerHeight || document.documentElement.clientHeight) &&\n\t\trect.right <= (window.innerWidth || document.documentElement.clientWidth)\n\t);\n}\n\nexport function scrollToElement(element, options = {}) {\n\tif (!element) return;\n\n\tconst defaultOptions = {\n\t\tbehavior: 'smooth',\n\t\tblock: 'center',\n\t\tinline: 'nearest',\n\t};\n\n\telement.scrollIntoView({ ...defaultOptions, ...options });\n}\n\nexport function getBrowserInfo() {\n\tconst userAgent = navigator.userAgent;\n\tconst platform = navigator.platform;\n\n\treturn {\n\t\tuserAgent,\n\t\tplatform,\n\t\tlanguage: navigator.language || navigator.userLanguage,\n\t\tcookieEnabled: navigator.cookieEnabled,\n\t\tscreenResolution: `${screen.width}x${screen.height}`,\n\t\twindowSize: `${window.innerWidth}x${window.innerHeight}`,\n\t\ttimezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n\t};\n}\n\nexport function formatFileSize(bytes) {\n\tif (bytes === 0) return '0 Bytes';\n\n\tconst k = 1024;\n\tconst sizes = ['Bytes', 'KB', 'MB', 'GB'];\n\tconst i = Math.floor(Math.log(bytes) / Math.log(k));\n\n\treturn parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n}\n\nexport function delay(ms) {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function safeJsonParse(str, fallback = null) {\n\ttry {\n\t\treturn JSON.parse(str);\n\t} catch (error) {\n\t\treturn fallback;\n\t}\n}\n\nexport function escapeRegex(string) {\n\treturn string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport function getNestedProperty(obj, path, defaultValue = undefined) {\n\tif (!obj || !path) return defaultValue;\n\n\tconst keys = path.split('.');\n\tlet current = obj;\n\n\tfor (const key of keys) {\n\t\tif (current === null || current === undefined || !(key in current)) {\n\t\t\treturn defaultValue;\n\t\t}\n\t\tcurrent = current[key];\n\t}\n\n\treturn current;\n}\n\nexport function setNestedProperty(obj, path, value) {\n\tif (!obj || !path) return obj;\n\n\tconst keys = path.split('.');\n\tconst lastKey = keys.pop();\n\tlet current = obj;\n\n\tfor (const key of keys) {\n\t\tif (!(key in current) || typeof current[key] !== 'object') {\n\t\t\tcurrent[key] = {};\n\t\t}\n\t\tcurrent = current[key];\n\t}\n\n\tcurrent[lastKey] = value;\n\treturn obj;\n}\n\nexport function isBrowser() {\n\treturn typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\nexport function isMobile() {\n\tif (!isBrowser()) return false;\n\n\treturn (\n\t\t/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(\n\t\t\tnavigator.userAgent\n\t\t) || window.innerWidth <= 768\n\t);\n}\n\nexport function getCurrentTimestamp() {\n\treturn new Date().toISOString();\n}\n\nexport function validateConfig(config, required = []) {\n\tconst missing = [];\n\n\tfor (const key of required) {\n\t\tif (!config[key]) {\n\t\t\tmissing.push(key);\n\t\t}\n\t}\n\n\tif (missing.length > 0) {\n\t\tthrow new Error(`Missing required configuration: ${missing.join(', ')}`);\n\t}\n\n\treturn true;\n}\n","export class BaseWidget {\n\tconstructor(options = {}) {\n\t\tthis.id = options.id;\n\t\tthis.sdk = options.sdk;\n\t\tthis.apiService = options.apiService;\n\t\tthis.type = options.type || 'base';\n\n\t\tthis.options = {\n\t\t\tcontainer: null,\n\t\t\tposition: this.sdk.config.position,\n\t\t\tboardId: this.sdk.config.boardId,\n\t\t\tdisplayMode: options.displayMode || 'panel',\n\t\t\tsize: options.size || 'medium',\n\t\t\tprimaryColor: options.primaryColor || '#21244A',\n\t\t\tbackgroundColor: options.backgroundColor || '#ffffff',\n\t\t\ttextColor: options.textColor || '#1F2937',\n\t\t\tautoShow: false,\n\t\t\tshowBackdrop: true,\n\t\t\tcustomStyles: {},\n\t\t\t...options,\n\t\t};\n\n\t\tthis.element = null;\n\t\tthis.panelElement = null;\n\t\tthis.backdropElement = null;\n\t\tthis.mounted = false;\n\t\tthis.destroyed = false;\n\n\t\tthis.state = {\n\t\t\tisOpen: false,\n\t\t\tisLoading: false,\n\t\t\tisSubmitting: false,\n\t\t\ttitle: '',\n\t\t\tcontent: '',\n\t\t\temail: '',\n\t\t\tattachments: [],\n\t\t\terrors: {},\n\t\t};\n\n\t\tthis._bindMethods();\n\t}\n\n\tmount(container) {\n\t\tif (this.mounted || this.destroyed) return this;\n\n\t\tif (typeof container === 'string') {\n\t\t\tcontainer = document.querySelector(container);\n\t\t}\n\n\t\tif (!container) {\n\t\t\tcontainer = document.body;\n\t\t}\n\n\t\tthis.container = container;\n\t\tthis.element = this._render();\n\t\tthis.container.appendChild(this.element);\n\n\t\tthis.mounted = true;\n\t\tthis._attachEvents();\n\t\tthis.onMount();\n\n\t\tif (this.options.autoShow) {\n\t\t\tthis.show();\n\t\t}\n\n\t\tthis.sdk.eventBus.emit('widget:mounted', { widget: this });\n\t\treturn this;\n\t}\n\n\tshow() {\n\t\tif (this.element) {\n\t\t\tthis.element.style.display = 'block';\n\t\t}\n\t\treturn this;\n\t}\n\n\thide() {\n\t\tif (this.element) {\n\t\t\tthis.element.style.display = 'none';\n\t\t}\n\t\treturn this;\n\t}\n\n\topenPanel() {\n\t\tthis.state.isOpen = true;\n\n\t\tif (this.options.displayMode === 'modal') {\n\t\t\tthis._showLoadingModal();\n\t\t\t// Simulate loading delay then show form\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis._hideLoadingModal();\n\t\t\t\tthis._renderPanel();\n\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\tif (this.panelElement) {\n\t\t\t\t\t\tthis.panelElement.classList.add('open');\n\t\t\t\t\t}\n\t\t\t\t\tif (this.backdropElement) {\n\t\t\t\t\t\tthis.backdropElement.classList.add('show');\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}, 600);\n\t\t} else {\n\t\t\tthis._renderPanel();\n\t\t\trequestAnimationFrame(() => {\n\t\t\t\tif (this.panelElement) {\n\t\t\t\t\tthis.panelElement.classList.add('open');\n\t\t\t\t}\n\t\t\t\tif (this.backdropElement) {\n\t\t\t\t\tthis.backdropElement.classList.add('show');\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\t_showLoadingModal() {\n\t\tthis.state.isLoading = true;\n\n\t\t// Create backdrop\n\t\tthis.backdropElement = document.createElement('div');\n\t\tthis.backdropElement.className = 'feedback-panel-backdrop';\n\t\tdocument.body.appendChild(this.backdropElement);\n\n\t\t// Create loading modal\n\t\tthis.loadingElement = document.createElement('div');\n\t\tthis.loadingElement.className = `feedback-loading-modal theme-${this.options.theme}`;\n\t\tthis.loadingElement.innerHTML = `\n\t\t\t<div class=\"feedback-loading-spinner\"></div>\n\t\t`;\n\t\tdocument.body.appendChild(this.loadingElement);\n\n\t\trequestAnimationFrame(() => {\n\t\t\tthis.backdropElement.classList.add('show');\n\t\t\tthis.loadingElement.classList.add('show');\n\t\t});\n\t}\n\n\t_hideLoadingModal() {\n\t\tthis.state.isLoading = false;\n\t\tif (this.loadingElement) {\n\t\t\tthis.loadingElement.remove();\n\t\t\tthis.loadingElement = null;\n\t\t}\n\t}\n\n\tclosePanel() {\n\t\tif (this.panelElement) {\n\t\t\tthis.panelElement.classList.remove('open');\n\t\t}\n\t\tif (this.backdropElement) {\n\t\t\tthis.backdropElement.classList.remove('show');\n\t\t}\n\n\t\tsetTimeout(() => {\n\t\t\tthis.state.isOpen = false;\n\t\t\tif (this.panelElement && this.panelElement.parentNode) {\n\t\t\t\tthis.panelElement.parentNode.removeChild(this.panelElement);\n\t\t\t\tthis.panelElement = null;\n\t\t\t}\n\t\t\tif (this.backdropElement && this.backdropElement.parentNode) {\n\t\t\t\tthis.backdropElement.parentNode.removeChild(this.backdropElement);\n\t\t\t\tthis.backdropElement = null;\n\t\t\t}\n\t\t\tthis._resetForm();\n\t\t}, 300);\n\t}\n\n\tasync submitFeedback() {\n\t\tif (this.state.isSubmitting) return;\n\n\t\tthis._hideError();\n\n\t\ttry {\n\t\t\tthis.state.isSubmitting = true;\n\t\t\tthis._updateSubmitButton();\n\n\t\t\tconst payload = {\n\t\t\t\ttitle: this.state.title || 'Feedback',\n\t\t\t\tcontent: this.state.content,\n\t\t\t\temail: this.state.email,\n\t\t\t\tboard_id: this.options.boardId,\n\t\t\t\tattachments: this.state.attachments,\n\t\t\t};\n\n\t\t\tif (!this.state.content.trim()) {\n\t\t\t\tthis._showError('Please enter your feedback message.');\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst response = await this.apiService.submitFeedback(payload);\n\n\t\t\tthis._showSuccessMessage();\n\t\t\tthis.closePanel();\n\n\t\t\tthis.sdk.eventBus.emit('feedback:submitted', {\n\t\t\t\twidget: this,\n\t\t\t\tfeedback: response,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthis._showError('Failed to submit feedback. Please try again.');\n\t\t\tthis.sdk.eventBus.emit('feedback:error', { widget: this, error });\n\t\t} finally {\n\t\t\tthis.state.isSubmitting = false;\n\t\t\tthis._updateSubmitButton();\n\t\t}\n\t}\n\n\thandleConfigUpdate(newConfig) {\n\t\tthis.options.theme = newConfig.theme;\n\t\tif (this.element) {\n\t\t\tthis._updateTheme();\n\t\t}\n\t}\n\n\tdestroy() {\n\t\tif (this.destroyed) return;\n\n\t\tthis.onDestroy();\n\t\tthis.closePanel();\n\n\t\tif (this.element && this.element.parentNode) {\n\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t}\n\n\t\tthis.destroyed = true;\n\t\tthis.mounted = false;\n\t\tthis.sdk.eventBus.emit('widget:destroyed', { widget: this });\n\t}\n\n\tonMount() {}\n\tonDestroy() {}\n\n\t_render() {\n\t\tthrow new Error('_render() must be implemented by concrete widget');\n\t}\n\n\t_attachEvents() {\n\t\t// Override in concrete widgets\n\t}\n\n\t_bindMethods() {\n\t\tthis.openPanel = this.openPanel.bind(this);\n\t\tthis.closePanel = this.closePanel.bind(this);\n\t\tthis.submitFeedback = this.submitFeedback.bind(this);\n\t}\n\n\t_renderPanel() {\n\t\tif (this.panelElement) return;\n\n\t\tif (this.options.showBackdrop && !this.backdropElement) {\n\t\t\tthis.backdropElement = document.createElement('div');\n\t\t\tthis.backdropElement.className = 'feedback-panel-backdrop';\n\t\t\tdocument.body.appendChild(this.backdropElement);\n\n\t\t\tthis.backdropElement.addEventListener('click', this.closePanel);\n\t\t}\n\n\t\tconst modeClass =\n\t\t\tthis.options.displayMode === 'modal'\n\t\t\t\t? 'feedback-modal'\n\t\t\t\t: 'feedback-panel';\n\t\tconst sizeClass = `size-${this.options.size}`;\n\t\tthis.panelElement = document.createElement('div');\n\t\tthis.panelElement.className = `${modeClass} ${sizeClass}`;\n\t\tthis.panelElement.style.setProperty(\n\t\t\t'--primary-color',\n\t\t\tthis.options.primaryColor\n\t\t);\n\t\tthis.panelElement.style.setProperty(\n\t\t\t'--bg-color',\n\t\t\tthis.options.backgroundColor\n\t\t);\n\t\tthis.panelElement.style.setProperty('--text-color', this.options.textColor);\n\t\tthis.panelElement.innerHTML = this._getPanelHTML();\n\n\t\tdocument.body.appendChild(this.panelElement);\n\t\tthis._attachPanelEvents();\n\n\t\tconst firstInput = this.panelElement.querySelector('input, textarea');\n\t\tif (firstInput) {\n\t\t\tsetTimeout(() => firstInput.focus(), 350);\n\t\t}\n\t}\n\n\t_getPanelHTML() {\n\t\treturn `\n <div class=\"feedback-panel-content\">\n <div class=\"feedback-panel-header\">\n <h3>Send Feedback</h3>\n <button class=\"feedback-panel-close\" type=\"button\" aria-label=\"Close\">×</button>\n </div>\n <div class=\"feedback-panel-body\">\n <form class=\"feedback-form\">\n <div class=\"feedback-form-group\">\n <label for=\"feedback-title-${this.id}\">Title (optional)</label>\n <input \n type=\"text\" \n id=\"feedback-title-${this.id}\" \n name=\"title\" \n placeholder=\"Brief description of your feedback\"\n value=\"${this.state.title}\"\n />\n </div>\n <div class=\"feedback-form-group\">\n <label for=\"feedback-content-${this.id}\">Message *</label>\n <textarea \n id=\"feedback-content-${this.id}\" \n name=\"content\" \n placeholder=\"Tell us what you think...\"\n required\n >${this.state.content}</textarea>\n </div>\n <div class=\"feedback-error\" role=\"alert\"></div>\n <div class=\"feedback-form-actions\">\n <button type=\"submit\" class=\"feedback-btn feedback-btn-submit\">\n ${this.state.isSubmitting ? 'Sending...' : 'Send Feedback'}\n </button>\n </div>\n </form>\n </div>\n </div>\n `;\n\t}\n\t\n\t_attachPanelEvents() {\n\t\tconst panel = this.panelElement;\n\n\t\tpanel\n\t\t\t.querySelector('.feedback-panel-close')\n\t\t\t.addEventListener('click', this.closePanel);\n\n\t\tconst form = panel.querySelector('.feedback-form');\n\t\tform.addEventListener('submit', (e) => {\n\t\t\te.preventDefault();\n\t\t\tthis.submitFeedback();\n\t\t});\n\n\t\tpanel\n\t\t\t.querySelector('input[name=\"title\"]')\n\t\t\t.addEventListener('input', (e) => {\n\t\t\t\tthis.state.title = e.target.value;\n\t\t\t});\n\n\t\tpanel\n\t\t\t.querySelector('textarea[name=\"content\"]')\n\t\t\t.addEventListener('input', (e) => {\n\t\t\t\tthis.state.content = e.target.value;\n\t\t\t});\n\n\t\tconst handleEscape = (e) => {\n\t\t\tif (e.key === 'Escape') {\n\t\t\t\tthis.closePanel();\n\t\t\t\tdocument.removeEventListener('keydown', handleEscape);\n\t\t\t}\n\t\t};\n\t\tdocument.addEventListener('keydown', handleEscape);\n\t}\n\n\t_updateSubmitButton() {\n\t\tif (this.panelElement) {\n\t\t\tconst submitBtn = this.panelElement.querySelector('.feedback-btn-submit');\n\t\t\tif (submitBtn) {\n\t\t\t\tsubmitBtn.textContent = this.state.isSubmitting\n\t\t\t\t\t? 'Sending...'\n\t\t\t\t\t: 'Send Feedback';\n\t\t\t\tsubmitBtn.disabled = this.state.isSubmitting;\n\t\t\t}\n\t\t}\n\t}\n\n\t_showError(message) {\n\t\tif (this.panelElement) {\n\t\t\tconst errorElement = this.panelElement.querySelector('.feedback-error');\n\t\t\tif (errorElement) {\n\t\t\t\terrorElement.textContent = message;\n\t\t\t\terrorElement.classList.add('show');\n\t\t\t}\n\t\t}\n\t}\n\n\t_hideError() {\n\t\tif (this.panelElement) {\n\t\t\tconst errorElement = this.panelElement.querySelector('.feedback-error');\n\t\t\tif (errorElement) {\n\t\t\t\terrorElement.classList.remove('show');\n\t\t\t}\n\t\t}\n\t}\n\n\t_showSuccessMessage() {\n\t\tconst notification = document.createElement('div');\n\t\tnotification.className = 'feedback-success-notification';\n\t\tnotification.innerHTML = `\n <div class=\"feedback-success-content\">\n <div class=\"feedback-success-icon\">✓</div>\n <span>Feedback submitted successfully!</span>\n <button class=\"feedback-success-close\" aria-label=\"Close\">×</button>\n </div>\n `;\n\n\t\tdocument.body.appendChild(notification);\n\n\t\tconst closeBtn = notification.querySelector('.feedback-success-close');\n\t\tconst closeNotification = () => {\n\t\t\tif (notification.parentNode) {\n\t\t\t\tnotification.style.opacity = '0';\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tif (notification.parentNode) {\n\t\t\t\t\t\tnotification.parentNode.removeChild(notification);\n\t\t\t\t\t}\n\t\t\t\t}, 300);\n\t\t\t}\n\t\t};\n\n\t\tcloseBtn.addEventListener('click', closeNotification);\n\n\t\tsetTimeout(closeNotification, 4000);\n\t}\n\n\t_resetForm() {\n\t\tthis.state.title = '';\n\t\tthis.state.content = '';\n\t\tthis.state.email = '';\n\t\tthis.state.errors = {};\n\t}\n\n\t_updateTheme() {\n\t\tif (this.element) {\n\t\t\tthis.element.className = this.element.className.replace(\n\t\t\t\t/theme-\\w+/,\n\t\t\t\t`theme-${this.options.theme}`\n\t\t\t);\n\t\t}\n\t\tif (this.panelElement) {\n\t\t\tthis.panelElement.className = this.panelElement.className.replace(\n\t\t\t\t/theme-\\w+/,\n\t\t\t\t`theme-${this.options.theme}`\n\t\t\t);\n\t\t}\n\t}\n\n\topenModal() {\n\t\tthis.openPanel();\n\t}\n\n\tcloseModal() {\n\t\tthis.closePanel();\n\t}\n}\n","import { BaseWidget } from './BaseWidget.js';\n\nexport class ButtonWidget extends BaseWidget {\n\tconstructor(options) {\n\t\tsuper({ ...options, type: 'button' });\n\t}\n\n\t_render() {\n\t\tconst button = document.createElement('div');\n\t\tbutton.className = `feedback-widget feedback-widget-button theme-${this.options.theme} position-${this.options.position}`;\n\t\tbutton.innerHTML = `\n <button class=\"feedback-trigger-btn\" type=\"button\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path d=\"M2.003 5.884L10 9.882l7.997-3.998A2 2 0 0016 4H4a2 2 0 00-1.997 1.884z\"/>\n <path d=\"M18 8.118l-8 4-8-4V14a2 2 0 002 2h12a2 2 0 002-2V8.118z\"/>\n </svg>\n Feedback\n </button>\n `;\n\n\t\tif (this.options.customStyles) {\n\t\t\tObject.assign(button.style, this.options.customStyles);\n\t\t}\n\n\t\treturn button;\n\t}\n\n\t_attachEvents() {\n\t\tconst button = this.element.querySelector('.feedback-trigger-btn');\n\t\tbutton.addEventListener('click', this.openPanel);\n\n\t\tbutton.addEventListener('mouseenter', () => {\n\t\t\tif (!this.state.isSubmitting) {\n\t\t\t\tbutton.style.transform = 'translateY(-2px)';\n\t\t\t}\n\t\t});\n\n\t\tbutton.addEventListener('mouseleave', () => {\n\t\t\tbutton.style.transform = 'translateY(0)';\n\t\t});\n\t}\n\n\tupdateText(text) {\n\t\tconst button = this.element?.querySelector('.feedback-trigger-btn');\n\t\tif (button) {\n\t\t\tconst textNode = button.childNodes[button.childNodes.length - 1];\n\t\t\tif (textNode && textNode.nodeType === Node.TEXT_NODE) {\n\t\t\t\ttextNode.textContent = text;\n\t\t\t}\n\t\t}\n\t}\n\n\tupdatePosition(position) {\n\t\tthis.options.position = position;\n\t\tif (this.element) {\n\t\t\tthis.element.className = this.element.className.replace(\n\t\t\t\t/position-\\w+-\\w+/,\n\t\t\t\t`position-${position}`\n\t\t\t);\n\t\t}\n\t}\n}","import { BaseWidget } from './BaseWidget.js';\n\nexport class InlineWidget extends BaseWidget {\n\tconstructor(options) {\n\t\tsuper({ ...options, type: 'inline' });\n\t}\n\n\t_render() {\n\t\tconst widget = document.createElement('div');\n\t\twidget.className = `feedback-widget feedback-widget-inline theme-${this.options.theme}`;\n\t\twidget.innerHTML = `\n <div class=\"feedback-inline-content\">\n <h3>Send us your feedback</h3>\n <form class=\"feedback-inline-form\">\n <div class=\"feedback-form-group\">\n <input \n type=\"text\" \n name=\"title\" \n placeholder=\"Title (optional)\"\n value=\"${this.state.title}\"\n />\n </div>\n <div class=\"feedback-form-group\">\n <textarea \n name=\"content\" \n placeholder=\"Your feedback...\"\n required\n >${this.state.content}</textarea>\n </div>\n <div class=\"feedback-form-group\">\n <input \n type=\"email\" \n name=\"email\" \n placeholder=\"Email (optional)\"\n value=\"${this.state.email}\"\n />\n </div>\n <button type=\"submit\" class=\"feedback-btn feedback-btn-submit\">\n Send Feedback\n </button>\n <div class=\"feedback-error\" style=\"display: none;\"></div>\n </form>\n </div>\n `;\n\n\t\tif (this.options.customStyles) {\n\t\t\tObject.assign(widget.style, this.options.customStyles);\n\t\t}\n\n\t\treturn widget;\n\t}\n\n\t_attachEvents() {\n\t\tconst form = this.element.querySelector('.feedback-inline-form');\n\n\t\tform.addEventListener('submit', (e) => {\n\t\t\te.preventDefault();\n\t\t\tthis.submitFeedback();\n\t\t});\n\n\t\tform.querySelector('input[name=\"title\"]').addEventListener('input', (e) => {\n\t\t\tthis.state.title = e.target.value;\n\t\t});\n\n\t\tform\n\t\t\t.querySelector('textarea[name=\"content\"]')\n\t\t\t.addEventListener('input', (e) => {\n\t\t\t\tthis.state.content = e.target.value;\n\t\t\t});\n\n\t\tform.querySelector('input[name=\"email\"]').addEventListener('input', (e) => {\n\t\t\tthis.state.email = e.target.value;\n\t\t});\n\t}\n\n\topenModal() {\n\t\tconst textarea = this.element.querySelector('textarea[name=\"content\"]');\n\t\tif (textarea) {\n\t\t\ttextarea.focus();\n\t\t}\n\t}\n\n\tcloseModal() {\n\t\t// Inline widget doesn't use modal\n\t}\n\n\t_showSuccessMessage() {\n\t\tconst widget = this.element.querySelector('.feedback-inline-content');\n\t\tconst originalContent = widget.innerHTML;\n\n\t\twidget.innerHTML = `\n <div class=\"feedback-success\">\n <div class=\"feedback-success-icon\">✓</div>\n <h3>Thank you!</h3>\n <p>Your feedback has been submitted successfully.</p>\n <button class=\"feedback-btn feedback-btn-reset\">Send Another</button>\n </div>\n `;\n\n\t\tconst resetBtn = widget.querySelector('.feedback-btn-reset');\n\t\tresetBtn.addEventListener('click', () => {\n\t\t\twidget.innerHTML = originalContent;\n\t\t\tthis._attachEvents();\n\t\t\tthis._resetForm();\n\t\t});\n\t}\n\n\t_showError(message) {\n\t\tconst errorElement = this.element.querySelector('.feedback-error');\n\t\tif (errorElement) {\n\t\t\terrorElement.textContent = message;\n\t\t\terrorElement.style.display = 'block';\n\n\t\t\tsetTimeout(() => {\n\t\t\t\tif (errorElement) {\n\t\t\t\t\terrorElement.style.display = 'none';\n\t\t\t\t}\n\t\t\t}, 5000);\n\t\t}\n\t}\n\n\t_updateSubmitButton() {\n\t\tconst submitBtn = this.element.querySelector('.feedback-btn-submit');\n\t\tif (submitBtn) {\n\t\t\tsubmitBtn.textContent = this.state.isSubmitting\n\t\t\t\t? 'Sending...'\n\t\t\t\t: 'Send Feedback';\n\t\t\tsubmitBtn.disabled = this.state.isSubmitting;\n\t\t}\n\t}\n\n\tupdateTitle(title) {\n\t\tconst titleElement = this.element?.querySelector('h3');\n\t\tif (titleElement) {\n\t\t\ttitleElement.textContent = title;\n\t\t}\n\t}\n\n\tsetPlaceholder(field, placeholder) {\n\t\tconst input = this.element?.querySelector(`[name=\"${field}\"]`);\n\t\tif (input) {\n\t\t\tinput.placeholder = placeholder;\n\t\t}\n\t}\n}\n","import { BaseWidget } from './BaseWidget.js';\n\nexport class SurveyWidget extends BaseWidget {\n\tconstructor(options) {\n\t\tsuper({ ...options, type: 'survey' });\n\n\t\tthis.surveyOptions = {\n\t\t\tsurveyType: options.surveyType || 'nps', // 'nps', 'csat', 'ces', 'custom'\n\t\t\tposition: options.position || 'bottom-right', // 'bottom-right', 'bottom-left', 'center', 'bottom'\n\t\t\ttitle: options.title || null,\n\t\t\tdescription: options.description || null,\n\t\t\tlowLabel: options.lowLabel || null,\n\t\t\thighLabel: options.highLabel || null,\n\t\t\tcustomQuestions: options.customQuestions || [],\n\t\t\ttheme: options.theme || 'light',\n\t\t\tonSubmit: options.onSubmit || null,\n\t\t\tonDismiss: options.onDismiss || null,\n\t\t};\n\n\t\tthis.surveyState = {\n\t\t\tscore: null,\n\t\t\tfeedback: '',\n\t\t\tcustomAnswers: {},\n\t\t\tisVisible: false,\n\t\t};\n\t}\n\n\t_render() {\n\t\t// Survey widget doesn't render a trigger button, it's shown programmatically\n\t\tconst container = document.createElement('div');\n\t\tcontainer.className = 'feedback-survey-container';\n\t\tcontainer.style.display = 'none';\n\t\treturn container;\n\t}\n\n\t_attachEvents() {\n\t\t// Events are attached when survey is shown\n\t}\n\n\tshow() {\n\t\tthis._renderSurvey();\n\t\tthis.surveyState.isVisible = true;\n\t\tthis.sdk.eventBus.emit('survey:shown', {\n\t\t\twidget: this,\n\t\t\ttype: this.surveyOptions.surveyType,\n\t\t});\n\t\treturn this;\n\t}\n\n\thide() {\n\t\tthis._closeSurvey();\n\t\treturn this;\n\t}\n\n\t_renderSurvey() {\n\t\t// Remove any existing survey\n\t\tthis._closeSurvey();\n\n\t\tconst config = this._getSurveyConfig();\n\t\tconst positionStyles = this._getPositionStyles();\n\t\tconst themeStyles =\n\t\t\tthis.surveyOptions.theme === 'dark'\n\t\t\t\t? 'background: #1a1a1a; color: #fff;'\n\t\t\t\t: 'background: #fff; color: #1d1d1f;';\n\n\t\t// Create backdrop for center position\n\t\tif (this.surveyOptions.position === 'center') {\n\t\t\tthis.backdropElement = document.createElement('div');\n\t\t\tthis.backdropElement.className = 'feedback-survey-backdrop';\n\t\t\tdocument.body.appendChild(this.backdropElement);\n\t\t\tthis.backdropElement.addEventListener('click', () =>\n\t\t\t\tthis._handleDismiss()\n\t\t\t);\n\t\t}\n\n\t\tthis.surveyElement = document.createElement('div');\n\t\tthis.surveyElement.className = `feedback-survey feedback-survey-${this.surveyOptions.position} theme-${this.surveyOptions.theme}`;\n\t\tthis.surveyElement.style.cssText = `position: fixed; ${positionStyles} z-index: 10000; ${themeStyles} border-radius: 16px; box-shadow: 0 20px 60px rgba(0,0,0,0.3); padding: 24px; min-width: 320px; max-width: 400px; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;`;\n\n\t\tthis.surveyElement.innerHTML = `\n\t\t\t<button class=\"feedback-survey-close\" style=\"position: absolute; top: 12px; right: 12px; background: none; border: none; font-size: 20px; cursor: pointer; color: ${this.surveyOptions.theme === 'dark' ? '#888' : '#86868b'}; line-height: 1;\">×</button>\n\t\t\t<h3 class=\"feedback-survey-title\" style=\"margin: 0 0 8px 0; font-size: 18px; font-weight: 600; padding-right: 24px;\">${config.title}</h3>\n\t\t\t<p class=\"feedback-survey-description\" style=\"color: ${this.surveyOptions.theme === 'dark' ? '#aaa' : '#86868b'}; margin: 0 0 20px 0; font-size: 14px;\">${config.description}</p>\n\t\t\t<div class=\"feedback-survey-content\">${config.html}</div>\n\t\t\t<div class=\"feedback-survey-feedback\" style=\"margin-top: 16px;\">\n\t\t\t\t<textarea class=\"feedback-survey-textarea\" placeholder=\"Any additional feedback? (optional)\" style=\"width: 100%; padding: 12px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#333' : '#d2d2d7'}; border-radius: 8px; font-size: 14px; resize: none; height: 80px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#fff'}; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'}; font-family: inherit; box-sizing: border-box;\"></textarea>\n\t\t\t</div>\n\t\t\t<button class=\"feedback-survey-submit\" style=\"width: 100%; margin-top: 12px; padding: 12px; background: #007aff; color: white; border: none; border-radius: 8px; font-size: 14px; font-weight: 500; cursor: pointer; font-family: inherit;\">Submit</button>\n\t\t`;\n\n\t\tdocument.body.appendChild(this.surveyElement);\n\t\tthis._attachSurveyEvents();\n\n\t\t// Animate in\n\t\trequestAnimationFrame(() => {\n\t\t\tthis.surveyElement.style.opacity = '1';\n\t\t\tthis.surveyElement.style.transform =\n\t\t\t\tthis.surveyOptions.position === 'center'\n\t\t\t\t\t? 'translate(-50%, -50%) scale(1)'\n\t\t\t\t\t: 'translateY(0)';\n\t\t});\n\t}\n\n\t_getSurveyConfig() {\n\t\tconst configs = {\n\t\t\tnps: {\n\t\t\t\ttitle:\n\t\t\t\t\tthis.surveyOptions.title || 'How likely are you to recommend us?',\n\t\t\t\tdescription:\n\t\t\t\t\tthis.surveyOptions.description ||\n\t\t\t\t\t'On a scale of 0-10, how likely are you to recommend our product to a friend or colleague?',\n\t\t\t\thtml: `\n\t\t\t\t\t<div class=\"feedback-survey-nps\" style=\"display: flex; justify-content: space-between; gap: 4px;\">\n\t\t\t\t\t\t${[...Array(11).keys()]\n\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t(n) => `\n\t\t\t\t\t\t\t<button class=\"feedback-survey-nps-btn\" data-score=\"${n}\" style=\"width: 28px; height: 36px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7'}; border-radius: 6px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa'}; cursor: pointer; font-size: 12px; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'}; transition: all 0.15s;\">${n}</button>\n\t\t\t\t\t\t`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div style=\"display: flex; justify-content: space-between; margin-top: 8px; font-size: 11px; color: ${this.surveyOptions.theme === 'dark' ? '#888' : '#86868b'};\">\n\t\t\t\t\t\t<span>${this.surveyOptions.lowLabel || 'Not likely'}</span>\n\t\t\t\t\t\t<span>${this.surveyOptions.highLabel || 'Very likely'}</span>\n\t\t\t\t\t</div>\n\t\t\t\t`,\n\t\t\t},\n\t\t\tcsat: {\n\t\t\t\ttitle: this.surveyOptions.title || 'How satisfied are you?',\n\t\t\t\tdescription:\n\t\t\t\t\tthis.surveyOptions.description ||\n\t\t\t\t\t'How would you rate your overall satisfaction with our product?',\n\t\t\t\thtml: `\n\t\t\t\t\t<div class=\"feedback-survey-csat\" style=\"display: flex; justify-content: center; gap: 16px;\">\n\t\t\t\t\t\t${['😞', '😕', '😐', '🙂', '😄']\n\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t(emoji, i) => `\n\t\t\t\t\t\t\t<button class=\"feedback-survey-csat-btn\" data-score=\"${i + 1}\" style=\"background: none; border: none; cursor: pointer; font-size: 36px; transition: transform 0.15s; padding: 8px;\">${emoji}</button>\n\t\t\t\t\t\t`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div style=\"display: flex; justify-content: space-between; margin-top: 8px; font-size: 11px; color: ${this.surveyOptions.theme === 'dark' ? '#888' : '#86868b'};\">\n\t\t\t\t\t\t<span>${this.surveyOptions.lowLabel || 'Very dissatisfied'}</span>\n\t\t\t\t\t\t<span>${this.surveyOptions.highLabel || 'Very satisfied'}</span>\n\t\t\t\t\t</div>\n\t\t\t\t`,\n\t\t\t},\n\t\t\tces: {\n\t\t\t\ttitle: this.surveyOptions.title || 'How easy was it?',\n\t\t\t\tdescription:\n\t\t\t\t\tthis.surveyOptions.description ||\n\t\t\t\t\t'How easy was it to accomplish your task today?',\n\t\t\t\thtml: `\n\t\t\t\t\t<div class=\"feedback-survey-ces\" style=\"display: flex; justify-content: space-between; gap: 8px;\">\n\t\t\t\t\t\t${['Very Difficult', 'Difficult', 'Neutral', 'Easy', 'Very Easy']\n\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t(label, i) => `\n\t\t\t\t\t\t\t<button class=\"feedback-survey-ces-btn\" data-score=\"${i + 1}\" style=\"flex: 1; padding: 12px 8px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7'}; border-radius: 8px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa'}; cursor: pointer; font-size: 11px; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'}; transition: all 0.15s;\">${label}</button>\n\t\t\t\t\t\t`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.join('')}\n\t\t\t\t\t</div>\n\t\t\t\t`,\n\t\t\t},\n\t\t\tcustom: {\n\t\t\t\ttitle: this.surveyOptions.title || 'Quick Feedback',\n\t\t\t\tdescription:\n\t\t\t\t\tthis.surveyOptions.description ||\n\t\t\t\t\t'Help us improve by answering a few questions.',\n\t\t\t\thtml: this._renderCustomQuestions(),\n\t\t\t},\n\t\t};\n\n\t\treturn configs[this.surveyOptions.surveyType] || configs.nps;\n\t}\n\n\t_renderCustomQuestions() {\n\t\tif (\n\t\t\t!this.surveyOptions.customQuestions ||\n\t\t\tthis.surveyOptions.customQuestions.length === 0\n\t\t) {\n\t\t\t// Default custom questions\n\t\t\treturn `\n\t\t\t\t<div style=\"margin-bottom: 16px;\">\n\t\t\t\t\t<label style=\"display: block; margin-bottom: 6px; font-size: 13px; font-weight: 500;\">What feature do you use most?</label>\n\t\t\t\t\t<select class=\"feedback-survey-select\" data-question=\"feature\" style=\"width: 100%; padding: 10px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7'}; border-radius: 8px; font-size: 14px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#fff'}; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'};\">\n\t\t\t\t\t\t<option value=\"\">Select a feature</option>\n\t\t\t\t\t\t<option value=\"feedback\">Feedback Collection</option>\n\t\t\t\t\t\t<option value=\"surveys\">Surveys</option>\n\t\t\t\t\t\t<option value=\"analytics\">Analytics</option>\n\t\t\t\t\t\t<option value=\"integrations\">Integrations</option>\n\t\t\t\t\t</select>\n\t\t\t\t</div>\n\t\t\t\t<div>\n\t\t\t\t\t<label style=\"display: block; margin-bottom: 6px; font-size: 13px; font-weight: 500;\">How often do you use it?</label>\n\t\t\t\t\t<div class=\"feedback-survey-frequency\" style=\"display: flex; gap: 8px;\">\n\t\t\t\t\t\t${['Daily', 'Weekly', 'Monthly', 'Rarely']\n\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t(freq) => `\n\t\t\t\t\t\t\t<button class=\"feedback-survey-freq-btn\" data-freq=\"${freq}\" style=\"flex: 1; padding: 10px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7'}; border-radius: 8px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa'}; cursor: pointer; font-size: 12px; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'}; transition: all 0.15s;\">${freq}</button>\n\t\t\t\t\t\t`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.join('')}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t`;\n\t\t}\n\n\t\treturn this.surveyOptions.customQuestions\n\t\t\t.map(\n\t\t\t\t(q, index) => `\n\t\t\t<div style=\"margin-bottom: 16px;\">\n\t\t\t\t<label style=\"display: block; margin-bottom: 6px; font-size: 13px; font-weight: 500;\">${q.label}</label>\n\t\t\t\t${this._renderQuestionInput(q, index)}\n\t\t\t</div>\n\t\t`\n\t\t\t)\n\t\t\t.join('');\n\t}\n\n\t_renderQuestionInput(question, index) {\n\t\tswitch (question.type) {\n\t\t\tcase 'select':\n\t\t\t\treturn `\n\t\t\t\t\t<select class=\"feedback-survey-select\" data-question=\"${question.id || index}\" style=\"width: 100%; padding: 10px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7'}; border-radius: 8px; font-size: 14px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#fff'}; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'};\">\n\t\t\t\t\t\t<option value=\"\">${question.placeholder || 'Select an option'}</option>\n\t\t\t\t\t\t${question.options.map((opt) => `<option value=\"${opt.value}\">${opt.label}</option>`).join('')}\n\t\t\t\t\t</select>\n\t\t\t\t`;\n\t\t\tcase 'text':\n\t\t\t\treturn `\n\t\t\t\t\t<input type=\"text\" class=\"feedback-survey-input\" data-question=\"${question.id || index}\" placeholder=\"${question.placeholder || ''}\" style=\"width: 100%; padding: 10px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7'}; border-radius: 8px; font-size: 14px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#fff'}; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'}; box-sizing: border-box;\">\n\t\t\t\t`;\n\t\t\tdefault:\n\t\t\t\treturn '';\n\t\t}\n\t}\n\n\t_getPositionStyles() {\n\t\tconst positions = {\n\t\t\t'bottom-right':\n\t\t\t\t'bottom: 24px; right: 24px; opacity: 0; transform: translateY(20px); transition: all 0.3s ease;',\n\t\t\t'bottom-left':\n\t\t\t\t'bottom: 24px; left: 24px; opacity: 0; transform: translateY(20px); transition: all 0.3s ease;',\n\t\t\tcenter:\n\t\t\t\t'top: 50%; left: 50%; transform: translate(-50%, -50%) scale(0.95); opacity: 0; transition: all 0.3s ease;',\n\t\t\tbottom:\n\t\t\t\t'bottom: 0; left: 0; right: 0; border-radius: 16px 16px 0 0; max-width: none; opacity: 0; transform: translateY(20px); transition: all 0.3s ease;',\n\t\t};\n\t\treturn positions[this.surveyOptions.position] || positions['bottom-right'];\n\t}\n\n\t_attachSurveyEvents() {\n\t\tif (!this.surveyElement) return;\n\n\t\t// Close button\n\t\tconst closeBtn = this.surveyElement.querySelector('.feedback-survey-close');\n\t\tcloseBtn.addEventListener('click', () => this._handleDismiss());\n\n\t\t// Submit button\n\t\tconst submitBtn = this.surveyElement.querySelector(\n\t\t\t'.feedback-survey-submit'\n\t\t);\n\t\tsubmitBtn.addEventListener('click', () => this._handleSubmit());\n\n\t\t// Feedback textarea\n\t\tconst textarea = this.surveyElement.querySelector(\n\t\t\t'.feedback-survey-textarea'\n\t\t);\n\t\ttextarea.addEventListener('input', (e) => {\n\t\t\tthis.surveyState.feedback = e.target.value;\n\t\t});\n\n\t\t// Survey type specific events\n\t\tthis._attachTypeSpecificEvents();\n\n\t\t// Escape key\n\t\tthis._escapeHandler = (e) => {\n\t\t\tif (e.key === 'Escape') {\n\t\t\t\tthis._handleDismiss();\n\t\t\t}\n\t\t};\n\t\tdocument.addEventListener('keydown', this._escapeHandler);\n\t}\n\n\t_attachTypeSpecificEvents() {\n\t\tconst type = this.surveyOptions.surveyType;\n\n\t\tif (type === 'nps') {\n\t\t\tthis.surveyElement\n\t\t\t\t.querySelectorAll('.feedback-survey-nps-btn')\n\t\t\t\t.forEach((btn) => {\n\t\t\t\t\tbtn.addEventListener('click', () =>\n\t\t\t\t\t\tthis._selectNPS(parseInt(btn.dataset.score))\n\t\t\t\t\t);\n\t\t\t\t\tbtn.addEventListener('mouseenter', () => {\n\t\t\t\t\t\tif (this.surveyState.score !== parseInt(btn.dataset.score)) {\n\t\t\t\t\t\t\tbtn.style.borderColor = '#007aff';\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tbtn.addEventListener('mouseleave', () => {\n\t\t\t\t\t\tif (this.surveyState.score !== parseInt(btn.dataset.score)) {\n\t\t\t\t\t\t\tbtn.style.borderColor =\n\t\t\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t}\n\n\t\tif (type === 'csat') {\n\t\t\tthis.surveyElement\n\t\t\t\t.querySelectorAll('.feedback-survey-csat-btn')\n\t\t\t\t.forEach((btn) => {\n\t\t\t\t\tbtn.addEventListener('click', () =>\n\t\t\t\t\t\tthis._selectCSAT(parseInt(btn.dataset.score))\n\t\t\t\t\t);\n\t\t\t\t\tbtn.addEventListener('mouseenter', () => {\n\t\t\t\t\t\tbtn.style.transform = 'scale(1.1)';\n\t\t\t\t\t});\n\t\t\t\t\tbtn.addEventListener('mouseleave', () => {\n\t\t\t\t\t\tif (this.surveyState.score !== parseInt(btn.dataset.score)) {\n\t\t\t\t\t\t\tbtn.style.transform = 'scale(1)';\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t}\n\n\t\tif (type === 'ces') {\n\t\t\tthis.surveyElement\n\t\t\t\t.querySelectorAll('.feedback-survey-ces-btn')\n\t\t\t\t.forEach((btn) => {\n\t\t\t\t\tbtn.addEventListener('click', () =>\n\t\t\t\t\t\tthis._selectCES(parseInt(btn.dataset.score))\n\t\t\t\t\t);\n\t\t\t\t\tbtn.addEventListener('mouseenter', () => {\n\t\t\t\t\t\tif (this.surveyState.score !== parseInt(btn.dataset.score)) {\n\t\t\t\t\t\t\tbtn.style.borderColor = '#007aff';\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tbtn.addEventListener('mouseleave', () => {\n\t\t\t\t\t\tif (this.surveyState.score !== parseInt(btn.dataset.score)) {\n\t\t\t\t\t\t\tbtn.style.borderColor =\n\t\t\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t}\n\n\t\tif (type === 'custom') {\n\t\t\t// Frequency buttons\n\t\t\tthis.surveyElement\n\t\t\t\t.querySelectorAll('.feedback-survey-freq-btn')\n\t\t\t\t.forEach((btn) => {\n\t\t\t\t\tbtn.addEventListener('click', () =>\n\t\t\t\t\t\tthis._selectFrequency(btn.dataset.freq)\n\t\t\t\t\t);\n\t\t\t\t});\n\n\t\t\t// Select inputs\n\t\t\tthis.surveyElement\n\t\t\t\t.querySelectorAll('.feedback-survey-select')\n\t\t\t\t.forEach((select) => {\n\t\t\t\t\tselect.addEventListener('change', (e) => {\n\t\t\t\t\t\tthis.surveyState.customAnswers[select.dataset.question] =\n\t\t\t\t\t\t\te.target.value;\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t// Text inputs\n\t\t\tthis.surveyElement\n\t\t\t\t.querySelectorAll('.feedback-survey-input')\n\t\t\t\t.forEach((input) => {\n\t\t\t\t\tinput.addEventListener('input', (e) => {\n\t\t\t\t\t\tthis.surveyState.customAnswers[input.dataset.question] =\n\t\t\t\t\t\t\te.target.value;\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t}\n\t}\n\n\t_selectNPS(score) {\n\t\tthis.surveyState.score = score;\n\t\tthis.surveyElement\n\t\t\t.querySelectorAll('.feedback-survey-nps-btn')\n\t\t\t.forEach((btn) => {\n\t\t\t\tconst btnScore = parseInt(btn.dataset.score);\n\t\t\t\tif (btnScore === score) {\n\t\t\t\t\tbtn.style.background = '#007aff';\n\t\t\t\t\tbtn.style.borderColor = '#007aff';\n\t\t\t\t\tbtn.style.color = '#fff';\n\t\t\t\t} else {\n\t\t\t\t\tbtn.style.background =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa';\n\t\t\t\t\tbtn.style.borderColor =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';\n\t\t\t\t\tbtn.style.color =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f';\n\t\t\t\t}\n\t\t\t});\n\t}\n\n\t_selectCSAT(score) {\n\t\tthis.surveyState.score = score;\n\t\tthis.surveyElement\n\t\t\t.querySelectorAll('.feedback-survey-csat-btn')\n\t\t\t.forEach((btn) => {\n\t\t\t\tconst btnScore = parseInt(btn.dataset.score);\n\t\t\t\tbtn.style.transform = btnScore === score ? 'scale(1.2)' : 'scale(1)';\n\t\t\t});\n\t}\n\n\t_selectCES(score) {\n\t\tthis.surveyState.score = score;\n\t\tthis.surveyElement\n\t\t\t.querySelectorAll('.feedback-survey-ces-btn')\n\t\t\t.forEach((btn) => {\n\t\t\t\tconst btnScore = parseInt(btn.dataset.score);\n\t\t\t\tif (btnScore === score) {\n\t\t\t\t\tbtn.style.background = '#007aff';\n\t\t\t\t\tbtn.style.borderColor = '#007aff';\n\t\t\t\t\tbtn.style.color = '#fff';\n\t\t\t\t} else {\n\t\t\t\t\tbtn.style.background =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa';\n\t\t\t\t\tbtn.style.borderColor =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';\n\t\t\t\t\tbtn.style.color =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f';\n\t\t\t\t}\n\t\t\t});\n\t}\n\n\t_selectFrequency(freq) {\n\t\tthis.surveyState.customAnswers.frequency = freq;\n\t\tthis.surveyElement\n\t\t\t.querySelectorAll('.feedback-survey-freq-btn')\n\t\t\t.forEach((btn) => {\n\t\t\t\tif (btn.dataset.freq === freq) {\n\t\t\t\t\tbtn.style.background = '#007aff';\n\t\t\t\t\tbtn.style.borderColor = '#007aff';\n\t\t\t\t\tbtn.style.color = '#fff';\n\t\t\t\t} else {\n\t\t\t\t\tbtn.style.background =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa';\n\t\t\t\t\tbtn.style.borderColor =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';\n\t\t\t\t\tbtn.style.color =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f';\n\t\t\t\t}\n\t\t\t});\n\t}\n\n\tasync _handleSubmit() {\n\t\tconst type = this.surveyOptions.surveyType;\n\n\t\t// Validate\n\t\tif (\n\t\t\t(type === 'nps' || type === 'csat' || type === 'ces') &&\n\t\t\tthis.surveyState.score === null\n\t\t) {\n\t\t\tthis._showError('Please select a rating');\n\t\t\treturn;\n\t\t}\n\n\t\tconst response = {\n\t\t\ttype: type,\n\t\t\tscore: this.surveyState.score,\n\t\t\tfeedback: this.surveyState.feedback,\n\t\t\tcustomAnswers: this.surveyState.customAnswers,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t};\n\n\t\t// Call onSubmit callback if provided\n\t\tif (this.surveyOptions.onSubmit) {\n\t\t\tthis.surveyOptions.onSubmit(response);\n\t\t}\n\n\t\t// Submit to API if not in mock mode\n\t\tif (!this.sdk.config.mock) {\n\t\t\ttry {\n\t\t\t\tawait this.apiService.submitSurveyResponse(response);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('[SurveyWidget] Failed to submit survey:', error);\n\t\t\t}\n\t\t}\n\n\t\tthis.sdk.eventBus.emit('survey:submitted', { widget: this, response });\n\n\t\tthis._closeSurvey();\n\t\tthis._showSuccessNotification();\n\t}\n\n\t_handleDismiss() {\n\t\tif (this.surveyOptions.onDismiss) {\n\t\t\tthis.surveyOptions.onDismiss();\n\t\t}\n\t\tthis.sdk.eventBus.emit('survey:dismissed', { widget: this });\n\t\tthis._closeSurvey();\n\t}\n\n\t_showError(message) {\n\t\t// Simple error display - could be enhanced\n\t\tconst existing = this.surveyElement.querySelector('.feedback-survey-error');\n\t\tif (existing) existing.remove();\n\n\t\tconst error = document.createElement('div');\n\t\terror.className = 'feedback-survey-error';\n\t\terror.style.cssText =\n\t\t\t'color: #ef4444; font-size: 13px; margin-top: 8px; text-align: center;';\n\t\terror.textContent = message;\n\n\t\tconst submitBtn = this.surveyElement.querySelector(\n\t\t\t'.feedback-survey-submit'\n\t\t);\n\t\tsubmitBtn.parentNode.insertBefore(error, submitBtn);\n\n\t\tsetTimeout(() => error.remove(), 3000);\n\t}\n\n\t_showSuccessNotification() {\n\t\tconst notification = document.createElement('div');\n\t\tnotification.className = 'feedback-survey-success';\n\t\tnotification.style.cssText = `\n\t\t\tposition: fixed;\n\t\t\ttop: 24px;\n\t\t\tright: 24px;\n\t\t\tbackground: #10b981;\n\t\t\tcolor: white;\n\t\t\tpadding: 16px 24px;\n\t\t\tborder-radius: 12px;\n\t\t\tfont-size: 14px;\n\t\t\tfont-weight: 500;\n\t\t\tz-index: 10001;\n\t\t\tbox-shadow: 0 10px 40px rgba(0,0,0,0.2);\n\t\t\tfont-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;\n\t\t`;\n\t\tnotification.innerHTML = `\n\t\t\t<div style=\"display: flex; align-items: center; gap: 8px;\">\n\t\t\t\t<span style=\"font-size: 18px;\">✓</span>\n\t\t\t\t<span>Thank you for your feedback!</span>\n\t\t\t</div>\n\t\t`;\n\t\tdocument.body.appendChild(notification);\n\n\t\tsetTimeout(() => {\n\t\t\tnotification.style.opacity = '0';\n\t\t\tnotification.style.transition = 'opacity 0.3s ease';\n\t\t\tsetTimeout(() => notification.remove(), 300);\n\t\t}, 3000);\n\t}\n\n\t_closeSurvey() {\n\t\tif (this._escapeHandler) {\n\t\t\tdocument.removeEventListener('keydown', this._escapeHandler);\n\t\t\tthis._escapeHandler = null;\n\t\t}\n\n\t\t// Capture references to avoid race conditions with setTimeout\n\t\tconst surveyEl = this.surveyElement;\n\t\tconst backdropEl = this.backdropElement;\n\n\t\tif (surveyEl) {\n\t\t\tsurveyEl.style.opacity = '0';\n\t\t\tsurveyEl.style.transform =\n\t\t\t\tthis.surveyOptions.position === 'center'\n\t\t\t\t\t? 'translate(-50%, -50%) scale(0.95)'\n\t\t\t\t\t: 'translateY(20px)';\n\t\t\tsetTimeout(() => {\n\t\t\t\tif (surveyEl && surveyEl.parentNode) {\n\t\t\t\t\tsurveyEl.parentNode.removeChild(surveyEl);\n\t\t\t\t}\n\t\t\t}, 300);\n\t\t\tthis.surveyElement = null;\n\t\t}\n\n\t\tif (backdropEl) {\n\t\t\tbackdropEl.style.opacity = '0';\n\t\t\tsetTimeout(() => {\n\t\t\t\tif (backdropEl && backdropEl.parentNode) {\n\t\t\t\t\tbackdropEl.parentNode.removeChild(backdropEl);\n\t\t\t\t}\n\t\t\t}, 300);\n\t\t\tthis.backdropElement = null;\n\t\t}\n\n\t\tthis.surveyState = {\n\t\t\tscore: null,\n\t\t\tfeedback: '',\n\t\t\tcustomAnswers: {},\n\t\t\tisVisible: false,\n\t\t};\n\t}\n\n\tdestroy() {\n\t\tthis._closeSurvey();\n\t\tsuper.destroy();\n\t}\n}\n","import { BaseWidget } from './BaseWidget.js';\n\nexport class TabWidget extends BaseWidget {\n\tconstructor(options) {\n\t\tsuper({ ...options, type: 'tab' });\n\t}\n\n\t_render() {\n\t\tconst tab = document.createElement('div');\n\t\ttab.className = `feedback-widget feedback-widget-tab theme-${this.options.theme} position-${this.options.position}`;\n\t\ttab.innerHTML = `\n <div class=\"feedback-tab-trigger\">\n <span class=\"feedback-tab-text\">Feedback</span>\n </div>\n `;\n\n\t\tif (this.options.customStyles) {\n\t\t\tObject.assign(tab.style, this.options.customStyles);\n\t\t}\n\n\t\treturn tab;\n\t}\n\n\t_attachEvents() {\n\t\tconst tab = this.element.querySelector('.feedback-tab-trigger');\n\t\ttab.addEventListener('click', this.openModal);\n\n\t\ttab.addEventListener('mouseenter', () => {\n\t\t\tif (!this.state.isSubmitting) {\n\t\t\t\ttab.style.transform = this._getHoverTransform();\n\t\t\t}\n\t\t});\n\n\t\ttab.addEventListener('mouseleave', () => {\n\t\t\ttab.style.transform = 'none';\n\t\t});\n\t}\n\n\t_getHoverTransform() {\n\t\tconst position = this.options.position;\n\t\tif (position.includes('right')) {\n\t\t\treturn 'translateX(-5px)';\n\t\t} else if (position.includes('left')) {\n\t\t\treturn 'translateX(5px)';\n\t\t}\n\t\treturn 'none';\n\t}\n\n\tupdateText(text) {\n\t\tconst textElement = this.element?.querySelector('.feedback-tab-text');\n\t\tif (textElement) {\n\t\t\ttextElement.textContent = text;\n\t\t}\n\t}\n\n\tupdatePosition(position) {\n\t\tthis.options.position = position;\n\t\tif (this.element) {\n\t\t\tthis.element.className = this.element.className.replace(\n\t\t\t\t/position-\\w+-\\w+/,\n\t\t\t\t`position-${position}`\n\t\t\t);\n\t\t}\n\t}\n}\n","import { SDKError } from '../utils/errors.js';\nimport { ButtonWidget } from './ButtonWidget.js';\nimport { InlineWidget } from './InlineWidget.js';\nimport { SurveyWidget } from './SurveyWidget.js';\nimport { TabWidget } from './TabWidget.js';\n\nexport class WidgetFactory {\n\tstatic widgets = new Map([\n\t\t['button', ButtonWidget],\n\t\t['tab', TabWidget],\n\t\t['inline', InlineWidget],\n\t\t['survey', SurveyWidget],\n\t]);\n\n\tstatic register(type, WidgetClass) {\n\t\tif (typeof type !== 'string' || !type.trim()) {\n\t\t\tthrow new SDKError('Widget type must be a non-empty string');\n\t\t}\n\n\t\tif (typeof WidgetClass !== 'function') {\n\t\t\tthrow new SDKError('Widget class must be a constructor function');\n\t\t}\n\n\t\tthis.widgets.set(type, WidgetClass);\n\t}\n\n\tstatic create(type, options = {}) {\n\t\tconst WidgetClass = this.widgets.get(type);\n\n\t\tif (!WidgetClass) {\n\t\t\tconst availableTypes = Array.from(this.widgets.keys()).join(', ');\n\t\t\tthrow new SDKError(\n\t\t\t\t`Unknown widget type: ${type}. Available types: ${availableTypes}`\n\t\t\t);\n\t\t}\n\n\t\ttry {\n\t\t\treturn new WidgetClass(options);\n\t\t} catch (error) {\n\t\t\tthrow new SDKError(\n\t\t\t\t`Failed to create widget of type '${type}': ${error.message}`,\n\t\t\t\terror\n\t\t\t);\n\t\t}\n\t}\n\n\tstatic getAvailableTypes() {\n\t\treturn Array.from(this.widgets.keys());\n\t}\n\n\tstatic isTypeRegistered(type) {\n\t\treturn this.widgets.has(type);\n\t}\n\n\tstatic unregister(type) {\n\t\treturn this.widgets.delete(type);\n\t}\n\n\tstatic clear() {\n\t\tthis.widgets.clear();\n\t}\n\n\tstatic getWidgetClass(type) {\n\t\treturn this.widgets.get(type);\n\t}\n}\n","import { ConfigError, SDKError } from '../utils/errors.js';\nimport { deepMerge, generateId } from '../utils/helpers.js';\nimport { WidgetFactory } from '../widgets/WidgetFactory.js';\nimport { APIService } from './APIService.js';\nimport { EventBus } from './EventBus.js';\n\nexport class FeedbackSDK {\n\tconstructor(config = {}) {\n\t\tthis.config = this._validateAndMergeConfig(config);\n\t\tthis.initialized = false;\n\t\tthis.widgets = new Map();\n\t\tthis.eventBus = new EventBus();\n\n\t\tthis.apiService = new APIService({\n\t\t\tapiUrl: this.config.apiUrl,\n\t\t\tworkspace: this.config.workspace,\n\t\t\tuserContext: this.config.userContext,\n\t\t\tmock: this.config.mock,\n\t\t\tenv: this.config.env,\n\t\t});\n\n\t\tthis._bindMethods();\n\t}\n\n\tasync init() {\n\t\tif (this.initialized) {\n\t\t\treturn { alreadyInitialized: true };\n\t\t}\n\n\t\ttry {\n\t\t\tconst initData = await this.apiService.init(this.config.userContext);\n\n\t\t\t// Merge backend config as base, local config overrides\n\t\t\tif (initData.config) {\n\t\t\t\tthis.config = deepMerge(initData.config, this.config);\n\t\t\t}\n\n\t\t\tthis.initialized = true;\n\t\t\tthis.eventBus.emit('sdk:initialized', {\n\t\t\t\tconfig: this.config,\n\t\t\t\tsessionToken: initData.sessionToken,\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\tinitialized: true,\n\t\t\t\tconfig: initData.config || {},\n\t\t\t\tsessionToken: initData.sessionToken,\n\t\t\t\texpiresIn: initData.expiresIn,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tthis.eventBus.emit('sdk:error', { error });\n\t\t\tthrow new SDKError(`Failed to initialize SDK: ${error.message}`, error);\n\t\t}\n\t}\n\n\tcreateWidget(type = 'button', options = {}) {\n\t\tif (!this.initialized) {\n\t\t\tthrow new SDKError(\n\t\t\t\t'SDK must be initialized before creating widgets. Call init() first.'\n\t\t\t);\n\t\t}\n\n\t\tconst widgetId = generateId('widget');\n\t\tconst widgetOptions = {\n\t\t\tid: widgetId,\n\t\t\tsdk: this,\n\t\t\tapiService: this.apiService,\n\t\t\t...this.config,\n\t\t\t...options,\n\t\t};\n\n\t\ttry {\n\t\t\tconst widget = WidgetFactory.create(type, widgetOptions);\n\t\t\tthis.widgets.set(widgetId, widget);\n\t\t\tthis.eventBus.emit('widget:created', { widget, type });\n\t\t\treturn widget;\n\t\t} catch (error) {\n\t\t\tthrow new SDKError(`Failed to create widget: ${error.message}`, error);\n\t\t}\n\t}\n\n\tgetWidget(id) {\n\t\treturn this.widgets.get(id);\n\t}\n\n\t/**\n\t * Show a survey widget\n\t * @param {Object} options - Survey options\n\t * @param {string} options.surveyType - Type of survey: 'nps', 'csat', 'ces', 'custom'\n\t * @param {string} options.position - Position: 'bottom-right', 'bottom-left', 'center', 'bottom'\n\t * @param {string} options.theme - Theme: 'light', 'dark'\n\t * @param {string} options.title - Custom title\n\t * @param {string} options.description - Custom description\n\t * @param {string} options.lowLabel - Low end label\n\t * @param {string} options.highLabel - High end label\n\t * @param {Function} options.onSubmit - Callback when survey is submitted\n\t * @param {Function} options.onDismiss - Callback when survey is dismissed\n\t * @returns {SurveyWidget} The survey widget instance\n\t */\n\tshowSurvey(options = {}) {\n\t\tif (!this.initialized) {\n\t\t\tthrow new SDKError(\n\t\t\t\t'SDK must be initialized before showing surveys. Call init() first.'\n\t\t\t);\n\t\t}\n\n\t\tconst surveyWidget = this.createWidget('survey', {\n\t\t\tsurveyType: options.surveyType || options.type || 'nps',\n\t\t\tposition: options.position || 'bottom-right',\n\t\t\ttheme: options.theme || this.config.theme || 'light',\n\t\t\ttitle: options.title,\n\t\t\tdescription: options.description,\n\t\t\tlowLabel: options.lowLabel,\n\t\t\thighLabel: options.highLabel,\n\t\t\tcustomQuestions: options.customQuestions,\n\t\t\tonSubmit: options.onSubmit,\n\t\t\tonDismiss: options.onDismiss,\n\t\t});\n\n\t\tsurveyWidget.mount();\n\t\tsurveyWidget.show();\n\n\t\treturn surveyWidget;\n\t}\n\n\tgetAllWidgets() {\n\t\treturn Array.from(this.widgets.values());\n\t}\n\n\tdestroyWidget(id) {\n\t\tconst widget = this.widgets.get(id);\n\t\tif (widget) {\n\t\t\twidget.destroy();\n\t\t\tthis.widgets.delete(id);\n\t\t\tthis.eventBus.emit('widget:removed', { widgetId: id });\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tdestroyAllWidgets() {\n\t\tfor (const widget of this.widgets.values()) {\n\t\t\twidget.destroy();\n\t\t}\n\t\tthis.widgets.clear();\n\t\tthis.eventBus.emit('widgets:cleared');\n\t}\n\n\tupdateConfig(newConfig) {\n\t\tconst oldConfig = { ...this.config };\n\t\tthis.config = this._validateAndMergeConfig(newConfig, this.config);\n\n\t\tfor (const widget of this.widgets.values()) {\n\t\t\twidget.handleConfigUpdate(this.config);\n\t\t}\n\n\t\tthis.eventBus.emit('config:updated', {\n\t\t\toldConfig,\n\t\t\tnewConfig: this.config,\n\t\t});\n\t}\n\n\tsetUserContext(userContext) {\n\t\tthis.config.userContext = userContext;\n\t\tif (this.apiService) {\n\t\t\tthis.apiService.setUserContext(userContext);\n\t\t}\n\t\tthis.eventBus.emit('user:updated', { userContext });\n\t}\n\n\tgetUserContext() {\n\t\treturn (\n\t\t\tthis.config.userContext ||\n\t\t\t(this.apiService ? this.apiService.getUserContext() : null)\n\t\t);\n\t}\n\n\tasync reinitialize(newUserContext = null) {\n\t\tthis.apiService.clearSession();\n\t\tthis.initialized = false;\n\n\t\tif (newUserContext) {\n\t\t\tthis.setUserContext(newUserContext);\n\t\t}\n\n\t\treturn this.init();\n\t}\n\n\ton(event, callback) {\n\t\tthis.eventBus.on(event, callback);\n\t\treturn this;\n\t}\n\n\toff(event, callback) {\n\t\tthis.eventBus.off(event, callback);\n\t\treturn this;\n\t}\n\n\tonce(event, callback) {\n\t\tthis.eventBus.once(event, callback);\n\t\treturn this;\n\t}\n\n\temit(event, data) {\n\t\tthis.eventBus.emit(event, data);\n\t\treturn this;\n\t}\n\n\tdestroy() {\n\t\tthis.destroyAllWidgets();\n\t\tthis.eventBus.removeAllListeners();\n\t\tthis.apiService.clearSession();\n\t\tthis.initialized = false;\n\t\tthis.eventBus.emit('sdk:destroyed');\n\t}\n\n\t_validateAndMergeConfig(newConfig, existingConfig = {}) {\n\t\tconst defaultConfig = {\n\t\t\tapiUrl: null,\n\t\t\tworkspace: null,\n\t\t\tuserContext: null,\n\t\t\tposition: 'bottom-right',\n\t\t\ttheme: 'light',\n\t\t\tboardId: 'general',\n\t\t\tautoShow: true,\n\t\t\tdebug: false,\n\t\t\tmock: false,\n\t\t\tenv: 'production', // 'production' or 'staging'\n\t\t};\n\n\t\tconst mergedConfig = deepMerge(\n\t\t\tdeepMerge(defaultConfig, existingConfig),\n\t\t\tnewConfig\n\t\t);\n\n\t\tif (!mergedConfig.workspace) {\n\t\t\tthrow new ConfigError('Missing required configuration: workspace');\n\t\t}\n\n\t\tif (mergedConfig.userContext) {\n\t\t\tthis._validateUserContext(mergedConfig.userContext);\n\t\t}\n\n\t\treturn mergedConfig;\n\t}\n\n\t_validateUserContext(userContext) {\n\t\tif (!userContext.user_id && !userContext.email) {\n\t\t\tthrow new ConfigError(\n\t\t\t\t'User context must include at least user_id or email'\n\t\t\t);\n\t\t}\n\n\t\tconst validStructure = {\n\t\t\tuser_id: 'string',\n\t\t\temail: 'string',\n\t\t\tname: 'string',\n\t\t\tcustom_fields: 'object',\n\t\t\tcompany: 'object',\n\t\t};\n\n\t\tfor (const [key, expectedType] of Object.entries(validStructure)) {\n\t\t\tif (userContext[key] && typeof userContext[key] !== expectedType) {\n\t\t\t\tthrow new ConfigError(\n\t\t\t\t\t`User context field '${key}' must be of type '${expectedType}'`\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t_bindMethods() {\n\t\tthis.createWidget = this.createWidget.bind(this);\n\t\tthis.destroyWidget = this.destroyWidget.bind(this);\n\t\tthis.updateConfig = this.updateConfig.bind(this);\n\t}\n\n\tstatic create(config) {\n\t\treturn new FeedbackSDK(config);\n\t}\n\n\tstatic async createAndInit(config) {\n\t\tconst sdk = new FeedbackSDK(config);\n\t\tawait sdk.init();\n\t\treturn sdk;\n\t}\n\n\tstatic extractUserContextFromAuth(authData) {\n\t\tif (!authData) return null;\n\n\t\treturn {\n\t\t\tuser_id: authData.sub || authData.id || authData.user_id,\n\t\t\temail: authData.email,\n\t\t\tname: authData.name || authData.display_name || authData.full_name,\n\t\t\tcustom_fields: {\n\t\t\t\trole: authData.role,\n\t\t\t\tplan: authData.plan || authData.subscription?.plan,\n\t\t\t\t...(authData.custom_fields || {}),\n\t\t\t},\n\t\t\tcompany:\n\t\t\t\tauthData.company || authData.organization\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tid: authData.company?.id || authData.organization?.id,\n\t\t\t\t\t\t\tname: authData.company?.name || authData.organization?.name,\n\t\t\t\t\t\t\tmonthly_spend: authData.company?.monthly_spend,\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined,\n\t\t};\n\t}\n}\n","import { APIService } from './core/APIService.js';\nimport { EventBus } from './core/EventBus.js';\nimport { FeedbackSDK } from './core/FeedbackSDK.js';\nimport { CSS_STYLES } from './styles/styles.js';\nimport {\n\tAPIError,\n\tConfigError,\n\tSDKError,\n\tValidationError,\n\tWidgetError,\n} from './utils/errors.js';\nimport * as helpers from './utils/helpers.js';\nimport { BaseWidget } from './widgets/BaseWidget.js';\nimport { ButtonWidget } from './widgets/ButtonWidget.js';\nimport { InlineWidget } from './widgets/InlineWidget.js';\nimport { SurveyWidget } from './widgets/SurveyWidget.js';\nimport { TabWidget } from './widgets/TabWidget.js';\nimport { WidgetFactory } from './widgets/WidgetFactory.js';\n\nfunction injectStyles() {\n\tif (\n\t\ttypeof document !== 'undefined' &&\n\t\t!document.querySelector('#feedback-sdk-styles')\n\t) {\n\t\tconst style = document.createElement('style');\n\t\tstyle.id = 'feedback-sdk-styles';\n\t\tstyle.textContent = CSS_STYLES;\n\t\tdocument.head.appendChild(style);\n\t}\n}\n\nfunction autoInit() {\n\tif (typeof window !== 'undefined' && window.FeedbackSDKConfig) {\n\t\tinjectStyles();\n\n\t\tconst config = { ...window.FeedbackSDKConfig };\n\t\tconst sdk = new FeedbackSDK(config);\n\n\t\tsdk\n\t\t\t.init()\n\t\t\t.then((initData) => {\n\t\t\t\twindow.FeedbackSDK.instance = sdk;\n\n\t\t\t\tif (window.FeedbackSDKConfig.autoCreate) {\n\t\t\t\t\tconst widgets = Array.isArray(window.FeedbackSDKConfig.autoCreate)\n\t\t\t\t\t\t? window.FeedbackSDKConfig.autoCreate\n\t\t\t\t\t\t: [window.FeedbackSDKConfig.autoCreate];\n\n\t\t\t\t\twidgets.forEach((widgetConfig) => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst widget = sdk.createWidget(\n\t\t\t\t\t\t\t\twidgetConfig.type || 'button',\n\t\t\t\t\t\t\t\twidgetConfig\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\twidget.mount(widgetConfig.container);\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tconsole.error('[FeedbackSDK] Failed to create widget:', error);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tif (typeof CustomEvent !== 'undefined') {\n\t\t\t\t\tconst event = new CustomEvent('FeedbackSDKReady', {\n\t\t\t\t\t\tdetail: { sdk, config, initData },\n\t\t\t\t\t});\n\t\t\t\t\twindow.dispatchEvent(event);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tconsole.error('[FeedbackSDK] Auto-initialization failed:', error);\n\n\t\t\t\tif (typeof CustomEvent !== 'undefined') {\n\t\t\t\t\tconst event = new CustomEvent('FeedbackSDKError', {\n\t\t\t\t\t\tdetail: { error, config, phase: 'initialization' },\n\t\t\t\t\t});\n\t\t\t\t\twindow.dispatchEvent(event);\n\t\t\t\t}\n\t\t\t});\n\t}\n}\n\nfunction handleDOMReady() {\n\tif (typeof document !== 'undefined') {\n\t\tif (document.readyState === 'loading') {\n\t\t\tdocument.addEventListener('DOMContentLoaded', autoInit);\n\t\t} else {\n\t\t\tsetTimeout(autoInit, 0);\n\t\t}\n\t}\n}\n\nconst FeedbackSDKExport = {\n\tFeedbackSDK,\n\tBaseWidget,\n\tButtonWidget,\n\tTabWidget,\n\tInlineWidget,\n\tSurveyWidget,\n\tWidgetFactory,\n\tEventBus,\n\tAPIService,\n\tSDKError,\n\tAPIError,\n\tWidgetError,\n\tConfigError,\n\tValidationError,\n\thelpers,\n\tcreate: (config) => {\n\t\tinjectStyles();\n\t\treturn new FeedbackSDK(config);\n\t},\n\tversion: '1.0.0',\n\tinstance: null,\n\n\tisReady: () => Boolean(FeedbackSDKExport.instance),\n\tgetInstance: () => FeedbackSDKExport.instance,\n\n\tsetUserContext: (userContext) => {\n\t\tif (FeedbackSDKExport.instance) {\n\t\t\tFeedbackSDKExport.instance.setUserContext(userContext);\n\t\t} else {\n\t\t\tif (typeof window !== 'undefined') {\n\t\t\t\twindow.FeedbackSDKUserContext = userContext;\n\t\t\t}\n\t\t}\n\t},\n\n\tinitWithUser: async (config, userContext) => {\n\t\tinjectStyles();\n\t\tconst fullConfig = { ...config, userContext };\n\t\tconst sdk = new FeedbackSDK(fullConfig);\n\t\tawait sdk.init();\n\n\t\tif (typeof window !== 'undefined') {\n\t\t\twindow.FeedbackSDK.instance = sdk;\n\t\t}\n\n\t\treturn sdk;\n\t},\n\n\tonReady: (callback) => {\n\t\tif (typeof window !== 'undefined') {\n\t\t\tif (FeedbackSDKExport.isReady()) {\n\t\t\t\tcallback(FeedbackSDKExport.instance);\n\t\t\t} else {\n\t\t\t\twindow.addEventListener(\n\t\t\t\t\t'FeedbackSDKReady',\n\t\t\t\t\t(event) => {\n\t\t\t\t\t\tcallback(event.detail.sdk, event.detail);\n\t\t\t\t\t},\n\t\t\t\t\t{ once: true }\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t},\n\n\tonError: (callback) => {\n\t\tif (typeof window !== 'undefined') {\n\t\t\twindow.addEventListener('FeedbackSDKError', (event) => {\n\t\t\t\tcallback(event.detail.error, event.detail);\n\t\t\t});\n\t\t}\n\t},\n\n\textractUserContext: FeedbackSDK.extractUserContextFromAuth,\n};\n\nif (typeof window !== 'undefined') {\n\twindow.FeedbackSDK = FeedbackSDKExport;\n\thandleDOMReady();\n}\n\nexport default FeedbackSDKExport;\n\nexport {\n\tAPIError,\n\tAPIService,\n\tBaseWidget,\n\tButtonWidget,\n\tConfigError,\n\tEventBus,\n\tFeedbackSDK,\n\thelpers,\n\tInlineWidget,\n\tSDKError,\n\tSurveyWidget,\n\tTabWidget,\n\tValidationError,\n\tWidgetError,\n\tWidgetFactory,\n};\n","export const CSS_STYLES = `\n.feedback-widget {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', Oxygen, Ubuntu, Cantarell, sans-serif;\n font-size: 14px;\n line-height: 1.4;\n z-index: 999999;\n box-sizing: border-box;\n}\n\n.feedback-widget *,\n.feedback-widget *::before,\n.feedback-widget *::after {\n box-sizing: border-box;\n}\n\n.feedback-widget-button {\n position: fixed;\n z-index: 999999;\n}\n\n.feedback-widget-button.position-bottom-right {\n bottom: 20px;\n right: 20px;\n}\n\n.feedback-widget-button.position-bottom-left {\n bottom: 20px;\n left: 20px;\n}\n\n.feedback-widget-button.position-top-right {\n top: 20px;\n right: 20px;\n}\n\n.feedback-widget-button.position-top-left {\n top: 20px;\n left: 20px;\n}\n\n.feedback-trigger-btn {\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n height: 44px;\n overflow: hidden;\n border-radius: 0.5rem;\n border: none;\n padding: 10px 16px;\n font-size: 14px;\n font-weight: 500;\n font-family: inherit;\n cursor: pointer;\n transition: all 0.3s ease;\n color: white;\n background: #155EEF;\n box-shadow: 0 1px 2px 0 rgba(16, 24, 40, 0.05);\n}\n\n.feedback-trigger-btn:hover:not(:disabled) {\n background: #004EEB;\n box-shadow: 0 1px 2px 0 rgba(16, 24, 40, 0.1);\n}\n\n.feedback-trigger-btn:disabled {\n opacity: 0.7;\n cursor: not-allowed;\n}\n\n.feedback-trigger-btn:focus-visible {\n outline: 2px solid #155EEF;\n outline-offset: 2px;\n}\n\n/* Side Panel Styles */\n.feedback-panel {\n position: fixed;\n bottom: 80px;\n right: 24px;\n width: 420px;\n max-height: 500px;\n z-index: 1000000;\n transform: translateX(calc(100% + 24px));\n transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);\n font-family: inherit;\n}\n\n.feedback-panel.open {\n transform: translateX(0);\n}\n\n.feedback-panel-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.1);\n opacity: 0;\n transition: opacity 0.3s ease;\n pointer-events: none;\n z-index: 999999;\n}\n\n.feedback-panel-backdrop.show {\n opacity: 1;\n pointer-events: auto;\n}\n\n.feedback-panel-content {\n background: white;\n height: 100%;\n display: flex;\n flex-direction: column;\n border-radius: 16px;\n box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), \n 0 10px 10px -5px rgba(0, 0, 0, 0.04),\n 0 0 0 1px rgba(0, 0, 0, 0.05);\n}\n\n.feedback-panel.theme-dark .feedback-panel-content {\n background: #1F2937;\n color: white;\n}\n\n.feedback-panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 24px;\n border-bottom: 1px solid #E5E7EB;\n flex-shrink: 0;\n}\n\n.feedback-panel.theme-dark .feedback-panel-header {\n border-bottom-color: #374151;\n}\n\n.feedback-panel-header h3 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n color: #111827;\n}\n\n.feedback-panel.theme-dark .feedback-panel-header h3 {\n color: white;\n}\n\n.feedback-panel-close {\n background: none;\n border: none;\n font-size: 24px;\n cursor: pointer;\n color: #6B7280;\n padding: 4px;\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 ease;\n}\n\n.feedback-panel-close:hover {\n background: #F3F4F6;\n color: #111827;\n}\n\n.feedback-panel-close:focus-visible {\n outline: 2px solid #155EEF;\n outline-offset: 2px;\n}\n\n.feedback-panel.theme-dark .feedback-panel-close {\n color: #9CA3AF;\n}\n\n.feedback-panel.theme-dark .feedback-panel-close:hover {\n background: #374151;\n color: white;\n}\n\n.feedback-panel-body {\n flex: 1;\n overflow-y: auto;\n padding: 24px;\n}\n\n.feedback-form {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.feedback-form-group {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 20px;\n}\n\n.feedback-form-group:last-child {\n margin-bottom: 0;\n}\n\n.feedback-form-group label {\n font-size: 14px;\n font-weight: 500;\n line-height: 1.25;\n color: #374151;\n}\n\n.feedback-panel.theme-dark .feedback-form-group label {\n color: #D1D5DB;\n}\n\n.feedback-form-group input {\n height: 44px;\n width: 100%;\n border-radius: 8px;\n border: 1px solid #D1D5DB;\n padding: 10px 14px;\n font-size: 15px;\n font-weight: 400;\n line-height: 1.5;\n color: #1F2937;\n font-family: inherit;\n outline: none;\n transition: all 0.2s ease;\n}\n\n.feedback-form-group input::placeholder {\n font-size: 15px;\n color: #9CA3AF;\n}\n\n.feedback-form-group input:focus {\n border-color: #155EEF;\n box-shadow: 0 0 0 3px rgba(21, 94, 239, 0.1);\n}\n\n.feedback-form-group input:focus-visible {\n outline: none;\n}\n\n.feedback-form-group textarea {\n min-height: 200px;\n width: 100%;\n resize: vertical;\n border-radius: 8px;\n border: 1px solid #D1D5DB;\n padding: 10px 14px;\n font-size: 15px;\n font-weight: 400;\n line-height: 1.5;\n color: #1F2937;\n font-family: inherit;\n outline: none;\n transition: all 0.2s ease;\n}\n\n.feedback-form-group textarea::placeholder {\n font-size: 15px;\n color: #9CA3AF;\n}\n\n.feedback-form-group textarea:focus {\n border-color: #155EEF;\n box-shadow: 0 0 0 3px rgba(21, 94, 239, 0.1);\n}\n\n.feedback-form-group textarea:focus-visible {\n outline: none;\n}\n\n.feedback-panel.theme-dark .feedback-form-group input,\n.feedback-panel.theme-dark .feedback-form-group textarea {\n background: #374151;\n border-color: #4B5563;\n color: white;\n}\n\n.feedback-panel.theme-dark .feedback-form-group input::placeholder,\n.feedback-panel.theme-dark .feedback-form-group textarea::placeholder {\n color: #6B7280;\n}\n\n.feedback-btn {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n border-radius: 8px;\n border: none;\n height: 44px;\n padding: 10px 18px;\n font-size: 15px;\n font-weight: 500;\n font-family: inherit;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.feedback-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.feedback-btn:focus-visible {\n outline: 2px solid #155EEF;\n outline-offset: 2px;\n}\n\n.feedback-btn-submit {\n background: #155EEF;\n color: white;\n width: 100%;\n}\n\n.feedback-btn-submit:hover:not(:disabled) {\n background: #1A56DB;\n}\n\n.feedback-btn-submit:active:not(:disabled) {\n background: #1E429F;\n}\n\n.feedback-btn-cancel {\n background: transparent;\n color: #6B7280;\n border: 1px solid #D1D5DB;\n}\n\n.feedback-btn-cancel:hover:not(:disabled) {\n background: #F9FAFB;\n border-color: #9CA3AF;\n color: #374151;\n}\n\n.feedback-panel.theme-dark .feedback-btn-cancel {\n color: #D1D5DB;\n border-color: #4B5563;\n}\n\n.feedback-panel.theme-dark .feedback-btn-cancel:hover:not(:disabled) {\n background: #374151;\n}\n\n.feedback-form-actions {\n display: flex;\n flex-direction: column;\n gap: 12px;\n margin-top: auto;\n padding-top: 24px;\n}\n\n.feedback-error {\n color: #DC2626;\n font-size: 14px;\n font-weight: 400;\n margin-top: 8px;\n padding: 12px;\n background: #FEE2E2;\n border: 1px solid #FECACA;\n border-radius: 8px;\n display: none;\n}\n\n.feedback-error.show {\n display: block;\n}\n\n.feedback-panel.theme-dark .feedback-error {\n background: #7F1D1D;\n border-color: #991B1B;\n color: #FCA5A5;\n}\n\n.feedback-success-notification {\n position: fixed;\n top: 24px;\n right: 24px;\n z-index: 1000002;\n background: white;\n border: 1px solid #D1FAE5;\n border-radius: 12px;\n box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);\n animation: slideInRight 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n min-width: 320px;\n}\n\n.feedback-success-content {\n display: flex;\n align-items: center;\n padding: 16px 20px;\n gap: 12px;\n}\n\n.feedback-success-icon {\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: #10B981;\n color: white;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n font-weight: 600;\n flex-shrink: 0;\n}\n\n.feedback-success-content span {\n color: #065F46;\n font-weight: 500;\n font-size: 14px;\n flex: 1;\n}\n\n.feedback-success-close {\n background: none;\n border: none;\n color: #6B7280;\n cursor: pointer;\n font-size: 20px;\n padding: 0;\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n border-radius: 4px;\n flex-shrink: 0;\n}\n\n.feedback-success-close:hover {\n background: #F3F4F6;\n color: #374151;\n}\n\n.feedback-success-close:focus-visible {\n outline: 2px solid #155EEF;\n outline-offset: 2px;\n}\n\n@keyframes slideInRight {\n from {\n transform: translateX(400px);\n opacity: 0;\n }\n to {\n transform: translateX(0);\n opacity: 1;\n }\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.feedback-panel-backdrop {\n animation: fadeIn 0.3s ease;\n}\n\n@media (max-width: 768px) {\n .feedback-panel {\n width: 100%;\n top: auto;\n bottom: 0;\n right: 0;\n left: 0;\n height: 85vh;\n max-height: 85vh;\n transform: translateY(100%);\n border-radius: 20px 20px 0 0;\n }\n \n .feedback-panel.open {\n transform: translateY(0);\n }\n \n .feedback-panel-content {\n border-radius: 20px 20px 0 0;\n }\n \n .feedback-panel-header {\n padding: 20px;\n position: relative;\n }\n \n .feedback-panel-header::before {\n content: '';\n position: absolute;\n top: 8px;\n left: 50%;\n transform: translateX(-50%);\n width: 40px;\n height: 4px;\n background: #D1D5DB;\n border-radius: 2px;\n }\n \n .feedback-panel.theme-dark .feedback-panel-header::before {\n background: #4B5563;\n }\n \n .feedback-panel-body {\n padding: 20px;\n }\n \n .feedback-form-group textarea {\n min-height: 150px;\n }\n \n .feedback-widget-button {\n bottom: 16px;\n right: 16px;\n }\n \n .feedback-widget-button.position-bottom-left {\n left: 16px;\n }\n \n .feedback-success-notification {\n top: 16px;\n right: 16px;\n left: 16px;\n min-width: auto;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .feedback-trigger-btn,\n .feedback-btn,\n .feedback-panel,\n .feedback-panel-backdrop,\n .feedback-success-notification {\n transition: none;\n animation: none;\n }\n}\n\n@media print {\n .feedback-widget,\n .feedback-panel,\n .feedback-panel-backdrop,\n .feedback-success-notification {\n display: none !important;\n }\n}\n`;"],"names":["SDKError","Error","constructor","message","cause","super","this","name","captureStackTrace","APIError","status","response","isNetworkError","isClientError","isServerError","WidgetError","widgetType","widgetId","ConfigError","configKey","ValidationError","field","value","MOCK_CONFIG","primaryColor","backgroundColor","textColor","boardId","size","displayMode","ENV_URLS","production","base","withWorkspace","workspace","staging","APIService","config","sessionToken","sessionExpiry","userContext","mock","env","apiUrl","baseURL","envConfig","_loadStoredSession","init","isSessionValid","error","Date","now","_storeSession","expiresIn","payload","user","_makeRequest","method","body","JSON","stringify","headers","session_token","expires_in","submitFeedback","feedbackData","Promise","resolve","setTimeout","success","data","id","title","content","board","board_id","attachments","Authorization","setUserContext","localStorage","setItem","getUserContext","clearSession","removeItem","sessionData","token","expiry","toISOString","stored","getItem","parse","endpoint","options","url","fetch","ok","errorMessage","responseData","json","e","text","contentType","get","includes","EventBus","events","Map","on","event","callback","has","set","push","off","callbacks","index","indexOf","splice","emit","forEach","console","once","unsubscribe","clear","getListenerCount","length","generateId","prefix","Math","random","toString","substring","deepMerge","target","source","result","key","hasOwnProperty","Array","isArray","isBrowser","window","document","func","wait","timeout","args","clearTimeout","ms","string","replace","bytes","i","floor","log","parseFloat","pow","toFixed","userAgent","navigator","platform","language","userLanguage","cookieEnabled","screenResolution","screen","width","height","windowSize","innerWidth","innerHeight","timezone","Intl","DateTimeFormat","resolvedOptions","timeZone","element","property","fallback","getComputedStyle","getPropertyValue","obj","path","defaultValue","undefined","keys","split","current","rect","getBoundingClientRect","top","left","bottom","documentElement","clientHeight","right","clientWidth","test","email","trim","str","div","createElement","textContent","innerHTML","scrollIntoView","behavior","block","inline","lastKey","pop","limit","lastFunc","lastRan","required","missing","join","BaseWidget","sdk","apiService","type","container","position","autoShow","showBackdrop","customStyles","panelElement","backdropElement","mounted","destroyed","state","isOpen","isLoading","isSubmitting","errors","_bindMethods","mount","querySelector","_render","appendChild","_attachEvents","onMount","show","eventBus","widget","style","display","hide","openPanel","_showLoadingModal","_hideLoadingModal","_renderPanel","requestAnimationFrame","classList","add","className","loadingElement","theme","remove","closePanel","parentNode","removeChild","_resetForm","_hideError","_updateSubmitButton","_showError","_showSuccessMessage","feedback","handleConfigUpdate","newConfig","_updateTheme","destroy","onDestroy","bind","addEventListener","modeClass","sizeClass","setProperty","_getPanelHTML","_attachPanelEvents","firstInput","focus","panel","preventDefault","handleEscape","removeEventListener","submitBtn","disabled","errorElement","notification","closeNotification","opacity","openModal","closeModal","ButtonWidget","button","Object","assign","transform","updateText","textNode","childNodes","nodeType","Node","TEXT_NODE","updatePosition","InlineWidget","form","textarea","originalContent","updateTitle","titleElement","setPlaceholder","placeholder","input","SurveyWidget","surveyOptions","surveyType","description","lowLabel","highLabel","customQuestions","onSubmit","onDismiss","surveyState","score","customAnswers","isVisible","_renderSurvey","_closeSurvey","_getSurveyConfig","positionStyles","_getPositionStyles","themeStyles","_handleDismiss","surveyElement","cssText","html","_attachSurveyEvents","configs","nps","map","n","csat","emoji","ces","label","custom","_renderCustomQuestions","q","_renderQuestionInput","freq","question","opt","positions","center","_handleSubmit","_attachTypeSpecificEvents","_escapeHandler","querySelectorAll","btn","_selectNPS","parseInt","dataset","borderColor","_selectCSAT","_selectCES","_selectFrequency","select","background","color","btnScore","frequency","timestamp","submitSurveyResponse","_showSuccessNotification","existing","insertBefore","transition","surveyEl","backdropEl","TabWidget","tab","_getHoverTransform","textElement","WidgetFactory","static","register","WidgetClass","widgets","create","availableTypes","from","getAvailableTypes","isTypeRegistered","unregister","delete","getWidgetClass","FeedbackSDK","_validateAndMergeConfig","initialized","alreadyInitialized","initData","createWidget","widgetOptions","getWidget","showSurvey","surveyWidget","getAllWidgets","values","destroyWidget","destroyAllWidgets","updateConfig","oldConfig","reinitialize","newUserContext","removeAllListeners","existingConfig","mergedConfig","debug","_validateUserContext","user_id","validStructure","custom_fields","company","expectedType","entries","createAndInit","extractUserContextFromAuth","authData","sub","display_name","full_name","role","plan","subscription","organization","monthly_spend","injectStyles","head","autoInit","FeedbackSDKConfig","then","instance","autoCreate","widgetConfig","CustomEvent","detail","dispatchEvent","catch","phase","FeedbackSDKExport","helpers","version","isReady","Boolean","getInstance","FeedbackSDKUserContext","initWithUser","async","fullConfig","onReady","onError","extractUserContext","readyState"],"mappings":"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"}
|