@product7/feedback-sdk 1.2.2 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"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/messenger/MessengerState.js","../src/widgets/messenger/components/MessengerLauncher.js","../src/widgets/messenger/components/NavigationTabs.js","../src/widgets/messenger/components/MessengerPanel.js","../src/widgets/messenger/views/ChangelogView.js","../src/widgets/messenger/views/ChatView.js","../src/widgets/messenger/views/ConversationsView.js","../src/widgets/messenger/views/HelpView.js","../src/widgets/messenger/views/HomeView.js","../src/widgets/MessengerWidget.js","../src/widgets/SurveyWidget.js","../src/widgets/TabWidget.js","../src/widgets/WidgetFactory.js","../src/core/FeedbackSDK.js","../src/index.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\n// Mock surveys for development\nconst MOCK_SURVEYS = [\n\t{\n\t\tid: 'mock_nps_survey',\n\t\ttype: 'nps',\n\t\ttitle: 'How likely are you to recommend us?',\n\t\tdescription: 'Your feedback helps us improve',\n\t\tlow_label: 'Not likely',\n\t\thigh_label: 'Very likely',\n\t\ttrigger: 'manual',\n\t\tstatus: 'active',\n\t},\n\t{\n\t\tid: 'mock_csat_survey',\n\t\ttype: 'csat',\n\t\ttitle: 'How satisfied are you?',\n\t\tdescription: 'Rate your experience with our product',\n\t\ttrigger: 'manual',\n\t\tstatus: 'active',\n\t},\n\t{\n\t\tid: 'mock_ces_survey',\n\t\ttype: 'ces',\n\t\ttitle: 'How easy was it?',\n\t\tdescription: 'Rate the ease of completing your task',\n\t\tlow_label: 'Very difficult',\n\t\thigh_label: 'Very easy',\n\t\ttrigger: 'manual',\n\t\tstatus: 'active',\n\t},\n];\n\n// Environment URLs\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\t/**\n\t * Get active surveys for the current user/context\n\t * @param {Object} context - Optional context overrides for targeting\n\t * @param {string} context.url - Override current URL\n\t * @param {Object} context.userProperties - Additional user properties\n\t * @returns {Promise<Array>} Array of active surveys matching targeting rules\n\t */\n\tasync getActiveSurveys(context = {}) {\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 - return mock surveys\n\t\tif (this.mock) {\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 200));\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: MOCK_SURVEYS,\n\t\t\t};\n\t\t}\n\n\t\ttry {\n\t\t\tconst queryParams = new URLSearchParams();\n\n\t\t\t// Auto-detect current URL or use provided override\n\t\t\tconst currentUrl =\n\t\t\t\tcontext.url ||\n\t\t\t\t(typeof window !== 'undefined' ? window.location.href : '');\n\t\t\tif (currentUrl) {\n\t\t\t\tqueryParams.append('url', currentUrl);\n\t\t\t}\n\n\t\t\t// Auto-detect device info\n\t\t\tconst deviceInfo = this._getDeviceInfo();\n\t\t\tif (deviceInfo.device) queryParams.append('device', deviceInfo.device);\n\t\t\tif (deviceInfo.browser) queryParams.append('browser', deviceInfo.browser);\n\t\t\tif (deviceInfo.os) queryParams.append('os', deviceInfo.os);\n\n\t\t\t// Add user properties if provided\n\t\t\tif (context.userProperties) {\n\t\t\t\tqueryParams.append(\n\t\t\t\t\t'user_properties',\n\t\t\t\t\tJSON.stringify(context.userProperties)\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst endpoint = `/widget/surveys/active${queryParams.toString() ? '?' + queryParams.toString() : ''}`;\n\n\t\t\tconst response = await this._makeRequest(endpoint, {\n\t\t\t\tmethod: 'GET',\n\t\t\t\theaders: {\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.getActiveSurveys(context);\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 get active surveys: ${error.message}`,\n\t\t\t\terror.response\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Auto-detect device, browser, and OS info\n\t * @returns {Object} Device info object\n\t */\n\t_getDeviceInfo() {\n\t\tif (typeof navigator === 'undefined') {\n\t\t\treturn { device: null, browser: null, os: null };\n\t\t}\n\n\t\tconst ua = navigator.userAgent;\n\n\t\t// Detect device type\n\t\tlet device = 'desktop';\n\t\tif (/Mobi|Android/i.test(ua)) {\n\t\t\tdevice = /Tablet|iPad/i.test(ua) ? 'tablet' : 'mobile';\n\t\t}\n\n\t\t// Detect browser\n\t\tlet browser = 'unknown';\n\t\tif (ua.includes('Firefox')) browser = 'firefox';\n\t\telse if (ua.includes('Edg')) browser = 'edge';\n\t\telse if (ua.includes('Chrome')) browser = 'chrome';\n\t\telse if (ua.includes('Safari')) browser = 'safari';\n\t\telse if (ua.includes('Opera') || ua.includes('OPR')) browser = 'opera';\n\n\t\t// Detect OS\n\t\tlet os = 'unknown';\n\t\tif (ua.includes('Windows')) os = 'windows';\n\t\telse if (ua.includes('Mac')) os = 'macos';\n\t\telse if (ua.includes('Linux')) os = 'linux';\n\t\telse if (ua.includes('Android')) os = 'android';\n\t\telse if (ua.includes('iPhone') || ua.includes('iPad')) os = 'ios';\n\n\t\treturn { device, browser, os };\n\t}\n\n\t/**\n\t * Submit a survey response\n\t * @param {string} surveyId - The survey ID\n\t * @param {Object} responseData - The survey response data\n\t * @param {number|string} responseData.rating - The rating/score value\n\t * @param {string} responseData.feedback - Optional text feedback\n\t * @param {Object} responseData.answers - For custom surveys, key-value pairs\n\t * @returns {Promise<Object>} Submission result\n\t */\n\tasync submitSurveyResponse(surveyId, responseData) {\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\tif (!surveyId) {\n\t\t\tthrow new APIError(400, 'Survey ID is required');\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, 300));\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: {\n\t\t\t\t\tid: 'mock_response_' + Date.now(),\n\t\t\t\t\tsurvey_id: surveyId,\n\t\t\t\t\t...responseData,\n\t\t\t\t},\n\t\t\t\tmessage: 'Survey response submitted successfully!',\n\t\t\t};\n\t\t}\n\n\t\tconst payload = {\n\t\t\trating: responseData.rating,\n\t\t\tfeedback: responseData.feedback || '',\n\t\t\tanswers: responseData.answers || {},\n\t\t};\n\n\t\ttry {\n\t\t\tconst response = await this._makeRequest(\n\t\t\t\t`/widget/surveys/${surveyId}/responses`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\tbody: JSON.stringify(payload),\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t\tAuthorization: `Bearer ${this.sessionToken}`,\n\t\t\t\t\t},\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.submitSurveyResponse(surveyId, responseData);\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 survey response: ${error.message}`,\n\t\t\t\terror.response\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Dismiss a survey (mark as seen but not completed)\n\t * @param {string} surveyId - The survey ID to dismiss\n\t * @returns {Promise<Object>} Dismissal result\n\t */\n\tasync dismissSurvey(surveyId) {\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\tif (!surveyId) {\n\t\t\tthrow new APIError(400, 'Survey ID is required');\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, 100));\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: 'Survey dismissed successfully',\n\t\t\t};\n\t\t}\n\n\t\ttry {\n\t\t\tconst response = await this._makeRequest(\n\t\t\t\t`/widget/surveys/${surveyId}/dismiss`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAuthorization: `Bearer ${this.sessionToken}`,\n\t\t\t\t\t},\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.dismissSurvey(surveyId);\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 dismiss survey: ${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\">&times;</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\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\">&times;</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';\nexport class ButtonWidget extends BaseWidget {\n constructor(options) {\n super({ ...options, type: 'button' });\n this.isMinimized = false;\n }\n\n _render() {\n const button = document.createElement('div');\n button.className = `feedback-widget feedback-widget-button theme-${this.options.theme} position-${this.options.position}`;\n button.innerHTML = `\n <button class=\"feedback-trigger-btn\" type=\"button\">\n <svg class=\"feedback-icon\" width=\"20\" height=\"20\" viewBox=\"0 0 256 256\" fill=\"currentColor\">\n <path d=\"M216,80H184V48a16,16,0,0,0-16-16H40A16,16,0,0,0,24,48V176a8,8,0,0,0,13,6.22L72,154V184a16,16,0,0,0,16,16h93.59L219,230.22a8,8,0,0,0,5,1.78,8,8,0,0,0,8-8V96A16,16,0,0,0,216,80ZM66.55,137.78,40,159.25V48H168v88H71.58A8,8,0,0,0,66.55,137.78ZM216,207.25l-26.55-21.47a8,8,0,0,0-5-1.78H88V152h80a16,16,0,0,0,16-16V96h32Z\"/>\n </svg>\n <span class=\"feedback-text\">Feedback</span>\n \n <div class=\"feedback-minimize-icon\">\n <svg viewBox=\"0 0 256 256\">\n <path d=\"M213.66,53.66,163.31,104H192a8,8,0,0,1,0,16H144a8,8,0,0,1-8-8V64a8,8,0,0,1,16,0V92.69l50.34-50.35a8,8,0,0,1,11.32,11.32ZM112,136H64a8,8,0,0,0,0,16H92.69L42.34,202.34a8,8,0,0,0,11.32,11.32L104,163.31V192a8,8,0,0,0,16,0V144A8,8,0,0,0,112,136Z\"/>\n </svg>\n </div>\n \n <div class=\"feedback-expand-icon\">\n <svg viewBox=\"0 0 256 256\">\n <path d=\"M112,40V64.69L61.66,14.34A8,8,0,0,0,50.34,25.66L100.69,76H72a8,8,0,0,0,0,16h48a8,8,0,0,0,8-8V36A8,8,0,0,0,112,40Zm131.06,70.61a8,8,0,0,0-8.72,1.73L184,162.69V136a8,8,0,0,0-16,0v48a8,8,0,0,0,8,8h48a8,8,0,0,0,0-16H195.31l50.35-50.34A8,8,0,0,0,243.06,110.61Z\"/>\n </svg>\n </div>\n </button>\n `;\n\n if (this.options.customStyles) {\n Object.assign(button.style, this.options.customStyles);\n }\n\n return button;\n }\n\n _attachEvents() {\n const button = this.element.querySelector('.feedback-trigger-btn');\n const minimizeIcon = this.element.querySelector('.feedback-minimize-icon');\n const expandIcon = this.element.querySelector('.feedback-expand-icon');\n\n button.addEventListener('click', (e) => {\n const clickedMinimize = e.target.closest('.feedback-minimize-icon');\n const clickedExpand = e.target.closest('.feedback-expand-icon');\n \n if (clickedMinimize) {\n e.stopPropagation();\n this.minimize();\n } else if (clickedExpand) {\n e.stopPropagation();\n this.restore();\n } else {\n if (!this.isMinimized) {\n this.openPanel();\n }\n }\n });\n\n button.addEventListener('mouseenter', () => {\n if (!this.state.isSubmitting && !this.isMinimized) {\n button.style.transform = 'translateY(-2px)';\n }\n });\n\n button.addEventListener('mouseleave', () => {\n if (!this.isMinimized) {\n button.style.transform = 'translateY(0)';\n }\n });\n }\n\n minimize() {\n this.isMinimized = true;\n this.element.classList.add('minimized');\n }\n\n restore() {\n this.isMinimized = false;\n this.element.classList.remove('minimized');\n }\n\n mount(container) {\n super.mount(container);\n }\n\n updateText(text) {\n const textEl = this.element?.querySelector('.feedback-text');\n if (textEl) {\n textEl.textContent = text;\n }\n }\n\n updatePosition(position) {\n this.options.position = position;\n if (this.element) {\n this.element.className = this.element.className.replace(\n /position-\\w+-\\w+/,\n `position-${position}`\n );\n }\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","/**\n * MessengerState - State management for the Messenger widget\n */\nexport class MessengerState {\n\tconstructor(options = {}) {\n\t\tthis.currentView = 'home'; // 'home', 'messages', 'chat', 'help', 'changelog'\n\t\tthis.isOpen = false;\n\t\tthis.unreadCount = 0;\n\t\tthis.activeConversationId = null;\n\n\t\t// Conversations\n\t\tthis.conversations = [];\n\t\tthis.messages = {}; // { conversationId: [messages] }\n\n\t\t// Help articles\n\t\tthis.helpArticles = [];\n\t\tthis.helpSearchQuery = '';\n\n\t\t// Changelog\n\t\tthis.homeChangelogItems = [];\n\t\tthis.changelogItems = [];\n\n\t\t// Team info\n\t\tthis.teamName = options.teamName || 'Support';\n\t\tthis.teamAvatars = options.teamAvatars || [];\n\t\tthis.welcomeMessage = options.welcomeMessage || 'How can we help?';\n\n\t\t// User info\n\t\tthis.userContext = options.userContext || null;\n\n\t\t// Feature flags\n\t\tthis.enableHelp = options.enableHelp !== false;\n\t\tthis.enableChangelog = options.enableChangelog !== false;\n\n\t\t// Listeners\n\t\tthis._listeners = new Set();\n\t}\n\n\t/**\n\t * Subscribe to state changes\n\t */\n\tsubscribe(callback) {\n\t\tthis._listeners.add(callback);\n\t\treturn () => this._listeners.delete(callback);\n\t}\n\n\t/**\n\t * Notify all listeners of state change\n\t */\n\t_notify(changeType, data) {\n\t\tthis._listeners.forEach((cb) => cb(changeType, data, this));\n\t}\n\n\t/**\n\t * Set current view\n\t */\n\tsetView(view) {\n\t\tconst previousView = this.currentView;\n\t\tthis.currentView = view;\n\t\tthis._notify('viewChange', { previousView, currentView: view });\n\t}\n\n\t/**\n\t * Toggle panel open/closed\n\t */\n\tsetOpen(isOpen) {\n\t\tthis.isOpen = isOpen;\n\t\tthis._notify('openChange', { isOpen });\n\t}\n\n\t/**\n\t * Set active conversation for chat view\n\t */\n\tsetActiveConversation(conversationId) {\n\t\tthis.activeConversationId = conversationId;\n\t\tthis._notify('conversationChange', { conversationId });\n\t}\n\n\t/**\n\t * Update conversations list\n\t */\n\tsetConversations(conversations) {\n\t\tthis.conversations = conversations;\n\t\tthis._updateUnreadCount();\n\t\tthis._notify('conversationsUpdate', { conversations });\n\t}\n\n\t/**\n\t * Add a new conversation\n\t */\n\taddConversation(conversation) {\n\t\tthis.conversations.unshift(conversation);\n\t\tthis._updateUnreadCount();\n\t\tthis._notify('conversationAdded', { conversation });\n\t}\n\n\t/**\n\t * Update messages for a conversation\n\t */\n\tsetMessages(conversationId, messages) {\n\t\tthis.messages[conversationId] = messages;\n\t\tthis._notify('messagesUpdate', { conversationId, messages });\n\t}\n\n\t/**\n\t * Add a message to a conversation\n\t */\n\taddMessage(conversationId, message) {\n\t\tif (!this.messages[conversationId]) {\n\t\t\tthis.messages[conversationId] = [];\n\t\t}\n\t\tthis.messages[conversationId].push(message);\n\n\t\t// Update conversation preview\n\t\tconst conv = this.conversations.find((c) => c.id === conversationId);\n\t\tif (conv) {\n\t\t\tconv.lastMessage = message.content;\n\t\t\tconv.lastMessageTime = message.timestamp;\n\t\t\tif (!message.isOwn) {\n\t\t\t\tconv.unread = (conv.unread || 0) + 1;\n\t\t\t\tthis._updateUnreadCount();\n\t\t\t}\n\t\t}\n\n\t\tthis._notify('messageAdded', { conversationId, message });\n\t}\n\n\t/**\n\t * Mark conversation as read\n\t */\n\tmarkAsRead(conversationId) {\n\t\tconst conv = this.conversations.find((c) => c.id === conversationId);\n\t\tif (conv && conv.unread > 0) {\n\t\t\tconv.unread = 0;\n\t\t\tthis._updateUnreadCount();\n\t\t\tthis._notify('conversationRead', { conversationId });\n\t\t}\n\t}\n\n\t/**\n\t * Update unread count\n\t */\n\t_updateUnreadCount() {\n\t\tthis.unreadCount = this.conversations.reduce(\n\t\t\t(sum, c) => sum + (c.unread || 0),\n\t\t\t0\n\t\t);\n\t\tthis._notify('unreadCountChange', { count: this.unreadCount });\n\t}\n\n\t/**\n\t * Set help articles\n\t */\n\tsetHelpArticles(articles) {\n\t\tthis.helpArticles = articles;\n\t\tthis._notify('helpArticlesUpdate', { articles });\n\t}\n\n\t/**\n\t * Set help search query\n\t */\n\tsetHelpSearchQuery(query) {\n\t\tthis.helpSearchQuery = query;\n\t\tthis._notify('helpSearchChange', { query });\n\t}\n\n\t/**\n\t * Set home changelog items\n\t */\n\tsetHomeChangelogItems(items) {\n\t\tthis.homeChangelogItems = items;\n\t\tthis._notify('homeChangelogUpdate', { items });\n\t}\n\n\t/**\n\t * Set changelog items\n\t */\n\tsetChangelogItems(items) {\n\t\tthis.changelogItems = items;\n\t\tthis._notify('changelogUpdate', { items });\n\t}\n\n\t/**\n\t * Get current conversation\n\t */\n\tgetActiveConversation() {\n\t\treturn this.conversations.find((c) => c.id === this.activeConversationId);\n\t}\n\n\t/**\n\t * Get messages for active conversation\n\t */\n\tgetActiveMessages() {\n\t\treturn this.messages[this.activeConversationId] || [];\n\t}\n\n\t/**\n\t * Get filtered help articles\n\t */\n\tgetFilteredHelpArticles() {\n\t\tif (!this.helpSearchQuery) {\n\t\t\treturn this.helpArticles;\n\t\t}\n\t\tconst query = this.helpSearchQuery.toLowerCase();\n\t\treturn this.helpArticles.filter(\n\t\t\t(article) =>\n\t\t\t\tarticle.title.toLowerCase().includes(query) ||\n\t\t\t\t(article.description &&\n\t\t\t\t\tarticle.description.toLowerCase().includes(query))\n\t\t);\n\t}\n\n\t/**\n\t * Reset state\n\t */\n\treset() {\n\t\tthis.currentView = 'home';\n\t\tthis.activeConversationId = null;\n\t\tthis.helpSearchQuery = '';\n\t\tthis._notify('reset', {});\n\t}\n}\n","/**\n * MessengerLauncher - Floating trigger button for messenger\n */\nexport class MessengerLauncher {\n\tconstructor(state, options = {}) {\n\t\tthis.state = state;\n\t\tthis.options = {\n\t\t\tposition: options.position || 'bottom-right',\n\t\t\tprimaryColor: options.primaryColor || '#1c1c1e',\n\t\t\t...options,\n\t\t};\n\t\tthis.element = null;\n\t\tthis._unsubscribe = null;\n\t}\n\n\trender() {\n\t\tthis.element = document.createElement('div');\n\t\tthis.element.className = `messenger-launcher messenger-launcher-${this.options.position}`;\n\n\t\tthis._updateContent();\n\t\tthis._attachEvents();\n\n\t\t// Subscribe to state changes\n\t\tthis._unsubscribe = this.state.subscribe((type, data) => {\n\t\t\tif (type === 'openChange') {\n\t\t\t\tthis._updateIcon();\n\t\t\t}\n\t\t\tif (type === 'unreadCountChange') {\n\t\t\t\tthis._updateBadge();\n\t\t\t}\n\t\t});\n\n\t\treturn this.element;\n\t}\n\n\t_updateContent() {\n\t\tconst badgeHtml =\n\t\t\tthis.state.unreadCount > 0\n\t\t\t\t? `<span class=\"messenger-launcher-badge\">${this.state.unreadCount > 9 ? '9+' : this.state.unreadCount}</span>`\n\t\t\t\t: '';\n\n\t\tthis.element.innerHTML = `\n\t\t\t<button class=\"messenger-launcher-btn\" aria-label=\"Open messenger\" style=\"background: ${this.options.primaryColor};\">\n\t\t\t\t<span class=\"messenger-launcher-icon messenger-launcher-icon-chat\">\n\t\t\t\t\t<i class=\"ph ph-chat-circle-dots\" style=\"font-size: 24px;\"></i>\n\t\t\t\t</span>\n\t\t\t\t<span class=\"messenger-launcher-icon messenger-launcher-icon-close\" style=\"display: none;\">\n\t\t\t\t\t<i class=\"ph ph-x\" style=\"font-size: 24px;\"></i>\n\t\t\t\t</span>\n\t\t\t\t${badgeHtml}\n\t\t\t</button>\n\t\t`;\n\t}\n\n\t_attachEvents() {\n\t\tthis.element\n\t\t\t.querySelector('.messenger-launcher-btn')\n\t\t\t.addEventListener('click', () => {\n\t\t\t\tthis.state.setOpen(!this.state.isOpen);\n\t\t\t});\n\t}\n\n\t_updateIcon() {\n\t\tconst chatIcon = this.element.querySelector(\n\t\t\t'.messenger-launcher-icon-chat'\n\t\t);\n\t\tconst closeIcon = this.element.querySelector(\n\t\t\t'.messenger-launcher-icon-close'\n\t\t);\n\n\t\tif (this.state.isOpen) {\n\t\t\tchatIcon.style.display = 'none';\n\t\t\tcloseIcon.style.display = 'flex';\n\t\t\tthis.element.classList.add('messenger-launcher-open');\n\t\t} else {\n\t\t\tchatIcon.style.display = 'flex';\n\t\t\tcloseIcon.style.display = 'none';\n\t\t\tthis.element.classList.remove('messenger-launcher-open');\n\t\t}\n\t}\n\n\t_updateBadge() {\n\t\tconst existingBadge = this.element.querySelector(\n\t\t\t'.messenger-launcher-badge'\n\t\t);\n\t\tif (existingBadge) {\n\t\t\texistingBadge.remove();\n\t\t}\n\n\t\tif (this.state.unreadCount > 0 && !this.state.isOpen) {\n\t\t\tconst badge = document.createElement('span');\n\t\t\tbadge.className = 'messenger-launcher-badge';\n\t\t\tbadge.textContent =\n\t\t\t\tthis.state.unreadCount > 9 ? '9+' : this.state.unreadCount;\n\t\t\tthis.element.querySelector('.messenger-launcher-btn').appendChild(badge);\n\t\t}\n\t}\n\n\tshow() {\n\t\tif (this.element) {\n\t\t\tthis.element.style.display = 'block';\n\t\t}\n\t}\n\n\thide() {\n\t\tif (this.element) {\n\t\t\tthis.element.style.display = 'none';\n\t\t}\n\t}\n\n\tdestroy() {\n\t\tif (this._unsubscribe) {\n\t\t\tthis._unsubscribe();\n\t\t}\n\t\tif (this.element && this.element.parentNode) {\n\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t}\n\t}\n}\n","/**\n * NavigationTabs - Bottom navigation for messenger\n */\nexport class NavigationTabs {\n\tconstructor(state, options = {}) {\n\t\tthis.state = state;\n\t\tthis.options = options;\n\t\tthis.element = null;\n\t\tthis._unsubscribe = null;\n\t}\n\n\trender() {\n\t\tthis.element = document.createElement('div');\n\t\tthis.element.className = 'messenger-nav';\n\n\t\tthis._updateContent();\n\t\tthis._attachEvents();\n\n\t\t// Subscribe to state changes\n\t\tthis._unsubscribe = this.state.subscribe((type) => {\n\t\t\tif (type === 'viewChange' || type === 'unreadCountChange') {\n\t\t\t\tthis._updateActiveTab();\n\t\t\t}\n\t\t});\n\n\t\treturn this.element;\n\t}\n\n\t_getTabs() {\n\t\tconst tabs = [\n\t\t\t{ id: 'home', label: 'Home', icon: this._getHomeIcon() },\n\t\t\t{\n\t\t\t\tid: 'messages',\n\t\t\t\tlabel: 'Messages',\n\t\t\t\ticon: this._getMessagesIcon(),\n\t\t\t\tbadge: this.state.unreadCount,\n\t\t\t},\n\t\t];\n\n\t\tif (this.state.enableHelp) {\n\t\t\ttabs.push({ id: 'help', label: 'Help', icon: this._getHelpIcon() });\n\t\t}\n\n\t\tif (this.state.enableChangelog) {\n\t\t\ttabs.push({\n\t\t\t\tid: 'changelog',\n\t\t\t\tlabel: 'Changelog',\n\t\t\t\ticon: this._getChangelogIcon(),\n\t\t\t});\n\t\t}\n\n\t\treturn tabs;\n\t}\n\n\t_updateContent() {\n\t\tconst tabs = this._getTabs();\n\t\tconst tabsHtml = tabs\n\t\t\t.map((tab) => {\n\t\t\t\tconst isActive = this.state.currentView === tab.id;\n\t\t\t\tconst badgeHtml =\n\t\t\t\t\ttab.badge && tab.badge > 0\n\t\t\t\t\t\t? `<span class=\"messenger-nav-badge\">${tab.badge > 9 ? '9+' : tab.badge}</span>`\n\t\t\t\t\t\t: '';\n\n\t\t\t\treturn `\n\t\t\t\t<button class=\"messenger-nav-tab ${isActive ? 'active' : ''}\" data-tab=\"${tab.id}\">\n\t\t\t\t\t<span class=\"messenger-nav-icon\">${tab.icon}</span>\n\t\t\t\t\t<span class=\"messenger-nav-label\">${tab.label}</span>\n\t\t\t\t\t${badgeHtml}\n\t\t\t\t</button>\n\t\t\t`;\n\t\t\t})\n\t\t\t.join('');\n\n\t\tthis.element.innerHTML = tabsHtml;\n\t}\n\n\t_attachEvents() {\n\t\tthis.element.addEventListener('click', (e) => {\n\t\t\tconst tab = e.target.closest('.messenger-nav-tab');\n\t\t\tif (tab) {\n\t\t\t\tconst tabId = tab.dataset.tab;\n\t\t\t\tthis.state.setView(tabId);\n\t\t\t}\n\t\t});\n\t}\n\n\t_updateActiveTab() {\n\t\tconst tabs = this.element.querySelectorAll('.messenger-nav-tab');\n\t\ttabs.forEach((tab) => {\n\t\t\tconst isActive = tab.dataset.tab === this.state.currentView;\n\t\t\ttab.classList.toggle('active', isActive);\n\n\t\t\t// Update badge if messages tab\n\t\t\tif (tab.dataset.tab === 'messages') {\n\t\t\t\tconst existingBadge = tab.querySelector('.messenger-nav-badge');\n\t\t\t\tif (existingBadge) existingBadge.remove();\n\n\t\t\t\tif (this.state.unreadCount > 0) {\n\t\t\t\t\tconst badge = document.createElement('span');\n\t\t\t\t\tbadge.className = 'messenger-nav-badge';\n\t\t\t\t\tbadge.textContent =\n\t\t\t\t\t\tthis.state.unreadCount > 9 ? '9+' : this.state.unreadCount;\n\t\t\t\t\ttab.appendChild(badge);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\t_getHomeIcon() {\n\t\treturn `<i class=\"ph-duotone ph-house-simple\" style=\"font-size: 24px;\"></i>`;\n\t}\n\n\t_getMessagesIcon() {\n\t\treturn `<i class=\"ph-duotone ph-chat\" style=\"font-size: 24px;\"></i>`;\n\t}\n\n\t_getHelpIcon() {\n\t\treturn `<i class=\"ph-duotone ph-question\" style=\"font-size: 24px;\"></i>`;\n\t}\n\n\t_getChangelogIcon() {\n\t\treturn `<i class=\"ph-duotone ph-megaphone\" style=\"font-size: 24px;\"></i>`;\n\t}\n\n\tdestroy() {\n\t\tif (this._unsubscribe) {\n\t\t\tthis._unsubscribe();\n\t\t}\n\t\tif (this.element && this.element.parentNode) {\n\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t}\n\t}\n}\n","/**\n * MessengerPanel - Main panel container for messenger\n */\nimport { NavigationTabs } from './NavigationTabs.js';\n\nexport class MessengerPanel {\n\tconstructor(state, options = {}) {\n\t\tthis.state = state;\n\t\tthis.options = {\n\t\t\tposition: options.position || 'bottom-right',\n\t\t\ttheme: options.theme || 'dark',\n\t\t\t...options,\n\t\t};\n\t\tthis.element = null;\n\t\tthis.navigationTabs = null;\n\t\tthis.currentViewComponent = null;\n\t\tthis.viewRegistry = {};\n\t\tthis._unsubscribe = null;\n\t}\n\n\t/**\n\t * Register view components\n\t */\n\tregisterView(name, ViewClass) {\n\t\tthis.viewRegistry[name] = ViewClass;\n\t}\n\n\trender() {\n\t\tthis.element = document.createElement('div');\n\t\tthis.element.className = `messenger-panel messenger-panel-${this.options.position} theme-${this.options.theme}`;\n\n\t\tthis.element.innerHTML = `\n\t\t\t<div class=\"messenger-panel-content\">\n\t\t\t\t<div class=\"messenger-panel-views\"></div>\n\t\t\t\t<div class=\"messenger-panel-nav\"></div>\n\t\t\t</div>\n\t\t`;\n\n\t\t// Render navigation tabs\n\t\tthis.navigationTabs = new NavigationTabs(this.state, this.options);\n\t\tconst navContainer = this.element.querySelector('.messenger-panel-nav');\n\t\tnavContainer.appendChild(this.navigationTabs.render());\n\n\t\t// Render initial view\n\t\tthis._renderCurrentView();\n\n\t\t// Subscribe to state changes\n\t\tthis._unsubscribe = this.state.subscribe((type) => {\n\t\t\tif (type === 'viewChange') {\n\t\t\t\tthis._renderCurrentView();\n\t\t\t}\n\t\t});\n\n\t\treturn this.element;\n\t}\n\n\t_renderCurrentView() {\n\t\tconst viewsContainer = this.element.querySelector('.messenger-panel-views');\n\n\t\t// Destroy current view if exists\n\t\tif (this.currentViewComponent && this.currentViewComponent.destroy) {\n\t\t\tthis.currentViewComponent.destroy();\n\t\t}\n\n\t\t// Clear container\n\t\tviewsContainer.innerHTML = '';\n\n\t\t// Get view class\n\t\tconst ViewClass = this.viewRegistry[this.state.currentView];\n\t\tif (ViewClass) {\n\t\t\tthis.currentViewComponent = new ViewClass(this.state, this.options);\n\t\t\tviewsContainer.appendChild(this.currentViewComponent.render());\n\t\t} else {\n\t\t\tviewsContainer.innerHTML = `<div class=\"messenger-view-placeholder\">View not found: ${this.state.currentView}</div>`;\n\t\t}\n\t}\n\n\t/**\n\t * Show the panel with animation\n\t */\n\tshow() {\n\t\tif (this.element) {\n\t\t\tthis.element.style.display = 'block';\n\t\t\t// Trigger animation\n\t\t\trequestAnimationFrame(() => {\n\t\t\t\tthis.element.classList.add('open');\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Hide the panel with animation\n\t */\n\thide() {\n\t\tif (this.element) {\n\t\t\tthis.element.classList.remove('open');\n\t\t\t// Wait for animation to complete\n\t\t\tsetTimeout(() => {\n\t\t\t\tif (this.element) {\n\t\t\t\t\tthis.element.style.display = 'none';\n\t\t\t\t}\n\t\t\t}, 300);\n\t\t}\n\t}\n\n\t/**\n\t * Set panel header content (used by views)\n\t */\n\tsetHeader(headerContent) {\n\t\tconst header = this.element.querySelector('.messenger-panel-header');\n\t\tif (header) {\n\t\t\theader.innerHTML = headerContent;\n\t\t}\n\t}\n\n\tdestroy() {\n\t\tif (this._unsubscribe) {\n\t\t\tthis._unsubscribe();\n\t\t}\n\t\tif (this.navigationTabs) {\n\t\t\tthis.navigationTabs.destroy();\n\t\t}\n\t\tif (this.currentViewComponent && this.currentViewComponent.destroy) {\n\t\t\tthis.currentViewComponent.destroy();\n\t\t}\n\t\tif (this.element && this.element.parentNode) {\n\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t}\n\t}\n}\n","/**\n * ChangelogView - Changelog and announcements\n */\nexport class ChangelogView {\n\tconstructor(state, options = {}) {\n\t\tthis.state = state;\n\t\tthis.options = options;\n\t\tthis.element = null;\n\t\tthis._unsubscribe = null;\n\t}\n\n\trender() {\n\t\tthis.element = document.createElement('div');\n\t\tthis.element.className = 'messenger-view messenger-changelog-view';\n\n\t\tthis._updateContent();\n\n\t\t// Subscribe to state changes\n\t\tthis._unsubscribe = this.state.subscribe((type) => {\n\t\t\tif (type === 'changelogUpdate') {\n\t\t\t\tthis._updateChangelogList();\n\t\t\t}\n\t\t});\n\n\t\treturn this.element;\n\t}\n\n\t_updateContent() {\n\t\tconst avatarsHtml = this._renderTeamAvatars();\n\n\t\tthis.element.innerHTML = `\n\t\t\t<div class=\"messenger-changelog-header\">\n\t\t\t\t<h2>Changelog</h2>\n\t\t\t\t<button class=\"messenger-close-btn\" aria-label=\"Close\">\n\t\t\t\t\t<i class=\"ph ph-x\" style=\"font-size: 20px;\"></i>\n\t\t\t\t</button>\n\t\t\t</div>\n\n\t\t\t<div class=\"messenger-changelog-subheader\">\n\t\t\t\t<span class=\"messenger-changelog-latest\">Latest</span>\n\t\t\t\t<div class=\"messenger-changelog-team\">\n\t\t\t\t\t<span>From ${this.state.teamName}</span>\n\t\t\t\t\t${avatarsHtml}\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div class=\"messenger-changelog-body\">\n\t\t\t\t<div class=\"messenger-changelog-list\"></div>\n\t\t\t</div>\n\t\t`;\n\n\t\tthis._updateChangelogList();\n\t\tthis._attachEvents();\n\t}\n\n\t_updateChangelogList() {\n\t\tconst changelogContainer = this.element.querySelector(\n\t\t\t'.messenger-changelog-list'\n\t\t);\n\t\tconst changelogItems = this.state.changelogItems;\n\n\t\tif (changelogItems.length === 0) {\n\t\t\tchangelogContainer.innerHTML = this._renderEmptyState();\n\t\t\treturn;\n\t\t}\n\n\t\tchangelogContainer.innerHTML = changelogItems\n\t\t\t.map((item) => this._renderChangelogCard(item))\n\t\t\t.join('');\n\n\t\t// Attach click events\n\t\tthis._attachChangelogEvents();\n\t}\n\n\t_renderChangelogCard(item) {\n\t\tconst tagsHtml =\n\t\t\titem.tags && item.tags.length > 0\n\t\t\t\t? `<div class=\"messenger-changelog-tags\">\n\t\t\t\t${item.tags.map((tag) => `<span class=\"messenger-changelog-tag\">${tag}</span>`).join('')}\n\t\t\t</div>`\n\t\t\t\t: '';\n\n\t\tconst dateStr = this._formatDate(item.publishedAt || item.date);\n\n\t\treturn `\n\t\t\t<div class=\"messenger-changelog-card\" data-changelog-id=\"${item.id}\">\n\t\t\t\t${\n\t\t\t\t\titem.coverImage\n\t\t\t\t\t\t? `\n\t\t\t\t\t<div class=\"messenger-changelog-cover\">\n\t\t\t\t\t\t<img src=\"${item.coverImage}\" alt=\"${item.title}\" onerror=\"this.style.display='none';\" />\n\t\t\t\t\t</div>\n\t\t\t\t`\n\t\t\t\t\t\t: ''\n\t\t\t\t}\n\t\t\t\t<div class=\"messenger-changelog-content\">\n\t\t\t\t\t${tagsHtml}\n\t\t\t\t\t<h3 class=\"messenger-changelog-title\">${item.title}</h3>\n\t\t\t\t\t${item.description ? `<p class=\"messenger-changelog-description\">${this._truncateText(item.description, 100)}</p>` : ''}\n\t\t\t\t\t<div class=\"messenger-changelog-meta\">\n\t\t\t\t\t\t<span class=\"messenger-changelog-date\">${dateStr}</span>\n\t\t\t\t\t\t<i class=\"ph ph-caret-right messenger-changelog-arrow\" style=\"font-size: 16px;\"></i>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t`;\n\t}\n\n\t_renderTeamAvatars() {\n\t\tconst avatars = this.state.teamAvatars;\n\t\tif (!avatars || avatars.length === 0) {\n\t\t\treturn `\n\t\t\t\t<div class=\"messenger-avatar-stack messenger-avatar-stack-tiny\">\n\t\t\t\t\t<div class=\"messenger-avatar messenger-avatar-tiny\" style=\"background: #5856d6;\">S</div>\n\t\t\t\t</div>\n\t\t\t`;\n\t\t}\n\n\t\tconst colors = ['#5856d6', '#007aff', '#34c759'];\n\t\tconst avatarItems = avatars\n\t\t\t.slice(0, 2)\n\t\t\t.map((avatar, i) => {\n\t\t\t\tif (typeof avatar === 'string' && avatar.startsWith('http')) {\n\t\t\t\t\treturn `<img class=\"messenger-avatar messenger-avatar-tiny\" src=\"${avatar}\" alt=\"Team member\" style=\"z-index: ${2 - i};\" />`;\n\t\t\t\t}\n\t\t\t\treturn `<div class=\"messenger-avatar messenger-avatar-tiny\" style=\"background: ${colors[i % colors.length]}; z-index: ${2 - i};\">${avatar.charAt(0).toUpperCase()}</div>`;\n\t\t\t})\n\t\t\t.join('');\n\n\t\treturn `<div class=\"messenger-avatar-stack messenger-avatar-stack-tiny\">${avatarItems}</div>`;\n\t}\n\n\t_renderEmptyState() {\n\t\treturn `\n\t\t\t<div class=\"messenger-changelog-empty\">\n\t\t\t\t<div class=\"messenger-changelog-empty-icon\">\n\t\t\t\t\t<i class=\"ph ph-megaphone\" style=\"font-size: 48px;\"></i>\n\t\t\t\t</div>\n\t\t\t\t<h3>No changelog yet</h3>\n\t\t\t\t<p>Check back later for updates</p>\n\t\t\t</div>\n\t\t`;\n\t}\n\n\t_formatDate(dateString) {\n\t\tif (!dateString) return '';\n\t\tconst date = new Date(dateString);\n\t\treturn date.toLocaleDateString('en-US', {\n\t\t\tmonth: 'short',\n\t\t\tday: 'numeric',\n\t\t\tyear: 'numeric',\n\t\t});\n\t}\n\n\t_truncateText(text, maxLength) {\n\t\tif (!text) return '';\n\t\tif (text.length <= maxLength) return text;\n\t\treturn text.substring(0, maxLength).trim() + '...';\n\t}\n\n\t_attachEvents() {\n\t\t// Close button\n\t\tthis.element\n\t\t\t.querySelector('.messenger-close-btn')\n\t\t\t.addEventListener('click', () => {\n\t\t\t\tthis.state.setOpen(false);\n\t\t\t});\n\n\t\tthis._attachChangelogEvents();\n\t}\n\n\t_attachChangelogEvents() {\n\t\tthis.element\n\t\t\t.querySelectorAll('.messenger-changelog-card')\n\t\t\t.forEach((card) => {\n\t\t\t\tcard.addEventListener('click', () => {\n\t\t\t\t\tconst changelogId = card.dataset.changelogId;\n\t\t\t\t\tconst changelogItem = this.state.changelogItems.find(\n\t\t\t\t\t\t(n) => n.id === changelogId\n\t\t\t\t\t);\n\t\t\t\t\tif (changelogItem && changelogItem.url) {\n\t\t\t\t\t\twindow.open(changelogItem.url, '_blank');\n\t\t\t\t\t} else if (this.options.onChangelogClick) {\n\t\t\t\t\t\tthis.options.onChangelogClick(changelogItem);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\t}\n\n\tdestroy() {\n\t\tif (this._unsubscribe) {\n\t\t\tthis._unsubscribe();\n\t\t}\n\t\tif (this.element && this.element.parentNode) {\n\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t}\n\t}\n}\n","/**\n * ChatView - Individual conversation chat\n */\nexport class ChatView {\n\tconstructor(state, options = {}) {\n\t\tthis.state = state;\n\t\tthis.options = options;\n\t\tthis.element = null;\n\t\tthis._unsubscribe = null;\n\t}\n\n\trender() {\n\t\tthis.element = document.createElement('div');\n\t\tthis.element.className = 'messenger-view messenger-chat-view';\n\n\t\tthis._updateContent();\n\n\t\t// Subscribe to state changes\n\t\tthis._unsubscribe = this.state.subscribe((type, data) => {\n\t\t\tif (\n\t\t\t\ttype === 'messageAdded' &&\n\t\t\t\tdata.conversationId === this.state.activeConversationId\n\t\t\t) {\n\t\t\t\tthis._appendMessage(data.message);\n\t\t\t\tthis._scrollToBottom();\n\t\t\t}\n\t\t});\n\n\t\treturn this.element;\n\t}\n\n\t_updateContent() {\n\t\tconst conversation = this.state.getActiveConversation();\n\t\tconst messages = this.state.getActiveMessages();\n\n\t\tconst messagesHtml =\n\t\t\tmessages.length === 0\n\t\t\t\t? this._renderEmptyState()\n\t\t\t\t: messages.map((msg) => this._renderMessage(msg)).join('');\n\n\t\tconst avatarHtml = this._renderConversationAvatar(conversation);\n\n\t\tthis.element.innerHTML = `\n\t\t\t<div class=\"messenger-chat-header\">\n\t\t\t\t<button class=\"messenger-back-btn\" aria-label=\"Back\">\n\t\t\t\t\t<i class=\"ph ph-caret-left\" style=\"font-size: 20px;\"></i>\n\t\t\t\t</button>\n\t\t\t\t<div class=\"messenger-chat-header-info\">\n\t\t\t\t\t${avatarHtml}\n\t\t\t\t\t<span class=\"messenger-chat-title\">${conversation?.title || 'Chat with team'}</span>\n\t\t\t\t</div>\n\t\t\t\t<button class=\"messenger-close-btn\" aria-label=\"Close\">\n\t\t\t\t\t<i class=\"ph ph-x\" style=\"font-size: 20px;\"></i>\n\t\t\t\t</button>\n\t\t\t</div>\n\n\t\t\t<div class=\"messenger-chat-messages\">\n\t\t\t\t${messagesHtml}\n\t\t\t</div>\n\n\t\t\t<div class=\"messenger-chat-compose\">\n\t\t\t\t<div class=\"messenger-compose-input-wrapper\">\n\t\t\t\t\t<textarea class=\"messenger-compose-input\" placeholder=\"Write a message...\" rows=\"1\"></textarea>\n\t\t\t\t</div>\n\t\t\t\t<button class=\"messenger-compose-send\" aria-label=\"Send\" disabled>\n\t\t\t\t\t<i class=\"ph ph-paper-plane-tilt\" style=\"font-size: 20px;\"></i>\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t`;\n\n\t\tthis._attachEvents();\n\t\tthis._scrollToBottom();\n\t}\n\n\t_renderEmptyState() {\n\t\tconst avatarHtml = this._renderTeamAvatars();\n\t\treturn `\n\t\t\t<div class=\"messenger-chat-empty\">\n\t\t\t\t<div class=\"messenger-chat-empty-avatars\">${avatarHtml}</div>\n\t\t\t\t<h3>Start the conversation</h3>\n\t\t\t\t<p>Send us a message and we'll get back to you as soon as possible.</p>\n\t\t\t</div>\n\t\t`;\n\t}\n\n\t_renderMessage(message) {\n\t\tconst isOwn = message.isOwn;\n\t\tconst messageClass = isOwn\n\t\t\t? 'messenger-message-own'\n\t\t\t: 'messenger-message-received';\n\t\tconst timeStr = this._formatMessageTime(message.timestamp);\n\n\t\tif (isOwn) {\n\t\t\treturn `\n\t\t\t\t<div class=\"messenger-message ${messageClass}\">\n\t\t\t\t\t<div class=\"messenger-message-bubble\">\n\t\t\t\t\t\t<div class=\"messenger-message-content\">${this._formatMessageContent(message.content)}</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"messenger-message-time\">${timeStr}</div>\n\t\t\t\t</div>\n\t\t\t`;\n\t\t}\n\n\t\tconst avatarHtml = this._renderSenderAvatar(message.sender);\n\t\treturn `\n\t\t\t<div class=\"messenger-message ${messageClass}\">\n\t\t\t\t<div class=\"messenger-message-avatar\">${avatarHtml}</div>\n\t\t\t\t<div class=\"messenger-message-wrapper\">\n\t\t\t\t\t<div class=\"messenger-message-sender\">${message.sender?.name || 'Support'}</div>\n\t\t\t\t\t<div class=\"messenger-message-bubble\">\n\t\t\t\t\t\t<div class=\"messenger-message-content\">${this._formatMessageContent(message.content)}</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"messenger-message-time\">${timeStr}</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t`;\n\t}\n\n\t_renderSenderAvatar(sender) {\n\t\tif (sender?.avatarUrl) {\n\t\t\treturn `<img class=\"messenger-avatar messenger-avatar-small\" src=\"${sender.avatarUrl}\" alt=\"${sender.name}\" />`;\n\t\t}\n\t\tconst initial = (sender?.name || 'S').charAt(0).toUpperCase();\n\t\treturn `<div class=\"messenger-avatar messenger-avatar-small\" style=\"background: #5856d6;\">${initial}</div>`;\n\t}\n\n\t_renderConversationAvatar(conversation) {\n\t\tif (!conversation?.participants?.length) {\n\t\t\treturn `<div class=\"messenger-avatar messenger-avatar-small\" style=\"background: #5856d6;\">S</div>`;\n\t\t}\n\t\tconst p = conversation.participants[0];\n\t\tif (p.avatarUrl) {\n\t\t\treturn `<img class=\"messenger-avatar messenger-avatar-small\" src=\"${p.avatarUrl}\" alt=\"${p.name}\" />`;\n\t\t}\n\t\treturn `<div class=\"messenger-avatar messenger-avatar-small\" style=\"background: #5856d6;\">${(p.name || 'S').charAt(0).toUpperCase()}</div>`;\n\t}\n\n\t_renderTeamAvatars() {\n\t\tconst avatars = this.state.teamAvatars;\n\t\tif (!avatars || avatars.length === 0) {\n\t\t\treturn `\n\t\t\t\t<div class=\"messenger-avatar-stack\">\n\t\t\t\t\t<div class=\"messenger-avatar\" style=\"background: #5856d6;\">S</div>\n\t\t\t\t\t<div class=\"messenger-avatar\" style=\"background: #007aff;\">T</div>\n\t\t\t\t</div>\n\t\t\t`;\n\t\t}\n\n\t\tconst colors = ['#5856d6', '#007aff', '#34c759', '#ff9500', '#ff3b30'];\n\t\tconst avatarItems = avatars\n\t\t\t.slice(0, 3)\n\t\t\t.map((avatar, i) => {\n\t\t\t\tif (typeof avatar === 'string' && avatar.startsWith('http')) {\n\t\t\t\t\treturn `<img class=\"messenger-avatar\" src=\"${avatar}\" alt=\"Team member\" style=\"z-index: ${3 - i};\" />`;\n\t\t\t\t}\n\t\t\t\treturn `<div class=\"messenger-avatar\" style=\"background: ${colors[i % colors.length]}; z-index: ${3 - i};\">${avatar.charAt(0).toUpperCase()}</div>`;\n\t\t\t})\n\t\t\t.join('');\n\n\t\treturn `<div class=\"messenger-avatar-stack\">${avatarItems}</div>`;\n\t}\n\n\t_formatMessageTime(timestamp) {\n\t\tif (!timestamp) return '';\n\t\tconst date = new Date(timestamp);\n\t\treturn date.toLocaleTimeString('en-US', {\n\t\t\thour: 'numeric',\n\t\t\tminute: '2-digit',\n\t\t\thour12: true,\n\t\t});\n\t}\n\n\t_formatMessageContent(content) {\n\t\tif (!content) return '';\n\t\t// Basic HTML escaping and line breaks\n\t\treturn content\n\t\t\t.replace(/&/g, '&amp;')\n\t\t\t.replace(/</g, '&lt;')\n\t\t\t.replace(/>/g, '&gt;')\n\t\t\t.replace(/\\n/g, '<br>');\n\t}\n\n\t_appendMessage(message) {\n\t\tconst messagesContainer = this.element.querySelector(\n\t\t\t'.messenger-chat-messages'\n\t\t);\n\t\tconst emptyState = messagesContainer.querySelector('.messenger-chat-empty');\n\t\tif (emptyState) {\n\t\t\temptyState.remove();\n\t\t}\n\n\t\tconst messageHtml = this._renderMessage(message);\n\t\tconst tempDiv = document.createElement('div');\n\t\ttempDiv.innerHTML = messageHtml;\n\t\tmessagesContainer.appendChild(tempDiv.firstElementChild);\n\t}\n\n\t_scrollToBottom() {\n\t\tconst messagesContainer = this.element.querySelector(\n\t\t\t'.messenger-chat-messages'\n\t\t);\n\t\tif (messagesContainer) {\n\t\t\tsetTimeout(() => {\n\t\t\t\tmessagesContainer.scrollTop = messagesContainer.scrollHeight;\n\t\t\t}, 50);\n\t\t}\n\t}\n\n\t_attachEvents() {\n\t\t// Back button\n\t\tthis.element\n\t\t\t.querySelector('.messenger-back-btn')\n\t\t\t.addEventListener('click', () => {\n\t\t\t\tthis.state.setView('messages');\n\t\t\t});\n\n\t\t// Close button\n\t\tthis.element\n\t\t\t.querySelector('.messenger-close-btn')\n\t\t\t.addEventListener('click', () => {\n\t\t\t\tthis.state.setOpen(false);\n\t\t\t});\n\n\t\t// Compose input\n\t\tconst input = this.element.querySelector('.messenger-compose-input');\n\t\tconst sendBtn = this.element.querySelector('.messenger-compose-send');\n\n\t\tinput.addEventListener('input', () => {\n\t\t\t// Auto-resize textarea\n\t\t\tinput.style.height = 'auto';\n\t\t\tinput.style.height = Math.min(input.scrollHeight, 120) + 'px';\n\n\t\t\t// Enable/disable send button\n\t\t\tsendBtn.disabled = !input.value.trim();\n\t\t});\n\n\t\tinput.addEventListener('keydown', (e) => {\n\t\t\tif (e.key === 'Enter' && !e.shiftKey) {\n\t\t\t\te.preventDefault();\n\t\t\t\tthis._sendMessage();\n\t\t\t}\n\t\t});\n\n\t\tsendBtn.addEventListener('click', () => {\n\t\t\tthis._sendMessage();\n\t\t});\n\t}\n\n\t_sendMessage() {\n\t\tconst input = this.element.querySelector('.messenger-compose-input');\n\t\tconst content = input.value.trim();\n\n\t\tif (!content) return;\n\n\t\t// Add message to state\n\t\tconst message = {\n\t\t\tid: 'msg_' + Date.now(),\n\t\t\tcontent: content,\n\t\t\tisOwn: true,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t};\n\n\t\tthis.state.addMessage(this.state.activeConversationId, message);\n\n\t\t// Clear input\n\t\tinput.value = '';\n\t\tinput.style.height = 'auto';\n\t\tthis.element.querySelector('.messenger-compose-send').disabled = true;\n\n\t\t// Emit event for API integration\n\t\tif (this.options.onSendMessage) {\n\t\t\tthis.options.onSendMessage(this.state.activeConversationId, message);\n\t\t}\n\t}\n\n\tdestroy() {\n\t\tif (this._unsubscribe) {\n\t\t\tthis._unsubscribe();\n\t\t}\n\t\tif (this.element && this.element.parentNode) {\n\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t}\n\t}\n}\n","/**\n * ConversationsView - Message thread list\n */\nexport class ConversationsView {\n\tconstructor(state, options = {}) {\n\t\tthis.state = state;\n\t\tthis.options = options;\n\t\tthis.element = null;\n\t\tthis._unsubscribe = null;\n\t}\n\n\trender() {\n\t\tthis.element = document.createElement('div');\n\t\tthis.element.className = 'messenger-view messenger-conversations-view';\n\n\t\tthis._updateContent();\n\t\tthis._attachEvents();\n\n\t\t// Subscribe to state changes\n\t\tthis._unsubscribe = this.state.subscribe((type) => {\n\t\t\tif (\n\t\t\t\ttype === 'conversationsUpdate' ||\n\t\t\t\ttype === 'conversationAdded' ||\n\t\t\t\ttype === 'conversationRead'\n\t\t\t) {\n\t\t\t\tthis._updateContent();\n\t\t\t}\n\t\t});\n\n\t\treturn this.element;\n\t}\n\n\t_updateContent() {\n\t\tconst conversations = this.state.conversations;\n\t\tconst avatarsHtml = this._renderAvatarStack();\n\n\t\tlet conversationsHtml;\n\t\tif (conversations.length === 0) {\n\t\t\tconversationsHtml = `\n\t\t\t\t<div class=\"messenger-conversations-empty\">\n\t\t\t\t\t<div class=\"messenger-conversations-empty-icon\">\n\t\t\t\t\t\t<i class=\"ph ph-chat\" style=\"font-size: 48px;\"></i>\n\t\t\t\t\t</div>\n\t\t\t\t\t<h3>No conversations yet</h3>\n\t\t\t\t\t<p>Start a new conversation with our team</p>\n\t\t\t\t</div>\n\t\t\t`;\n\t\t} else {\n\t\t\tconversationsHtml = `\n\t\t\t\t<div class=\"messenger-conversations-list\">\n\t\t\t\t\t${conversations.map((conv) => this._renderConversationItem(conv)).join('')}\n\t\t\t\t</div>\n\t\t\t`;\n\t\t}\n\n\t\tthis.element.innerHTML = `\n\t\t\t<div class=\"messenger-conversations-header\">\n\t\t\t\t<h2>Messages</h2>\n\t\t\t\t<button class=\"messenger-close-btn\" aria-label=\"Close\">\n\t\t\t\t\t<i class=\"ph ph-x\" style=\"font-size: 20px;\"></i>\n\t\t\t\t</button>\n\t\t\t</div>\n\n\t\t\t<div class=\"messenger-conversations-body\">\n\t\t\t\t${conversationsHtml}\n\t\t\t</div>\n\n\t\t\t<div class=\"messenger-conversations-footer\">\n\t\t\t\t<button class=\"messenger-new-message-btn\">\n\t\t\t\t\t<div class=\"messenger-new-message-avatars\">${avatarsHtml}</div>\n\t\t\t\t\t<span>Send us a message</span>\n\t\t\t\t\t<i class=\"ph ph-arrow-right\" style=\"font-size: 16px;\"></i>\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t`;\n\n\t\tthis._attachEvents();\n\t}\n\n\t_renderConversationItem(conversation) {\n\t\tconst unreadClass = conversation.unread > 0 ? 'unread' : '';\n\t\tconst timeAgo = this._formatTimeAgo(conversation.lastMessageTime);\n\t\tconst avatarsHtml = this._renderConversationAvatars(\n\t\t\tconversation.participants\n\t\t);\n\n\t\treturn `\n\t\t\t<div class=\"messenger-conversation-item ${unreadClass}\" data-conversation-id=\"${conversation.id}\">\n\t\t\t\t<div class=\"messenger-conversation-avatars\">\n\t\t\t\t\t${avatarsHtml}\n\t\t\t\t</div>\n\t\t\t\t<div class=\"messenger-conversation-content\">\n\t\t\t\t\t<div class=\"messenger-conversation-header\">\n\t\t\t\t\t\t<span class=\"messenger-conversation-title\">${conversation.title || 'Chat with team'}</span>\n\t\t\t\t\t\t<span class=\"messenger-conversation-time\">${timeAgo}</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"messenger-conversation-preview\">\n\t\t\t\t\t\t${conversation.unread > 0 ? '<span class=\"messenger-unread-dot\"></span>' : ''}\n\t\t\t\t\t\t<span class=\"messenger-conversation-message\">${this._truncateMessage(conversation.lastMessage)}</span>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t`;\n\t}\n\n\t_renderConversationAvatars(participants) {\n\t\tif (!participants || participants.length === 0) {\n\t\t\treturn `<div class=\"messenger-avatar messenger-avatar-medium\" style=\"background: #5856d6;\">S</div>`;\n\t\t}\n\n\t\tconst p = participants[0];\n\t\tif (p.avatarUrl) {\n\t\t\treturn `<img class=\"messenger-avatar messenger-avatar-medium\" src=\"${p.avatarUrl}\" alt=\"${p.name}\" />`;\n\t\t}\n\t\treturn `<div class=\"messenger-avatar messenger-avatar-medium\" style=\"background: ${this._getAvatarColor(0)};\">${(p.name || 'S').charAt(0).toUpperCase()}</div>`;\n\t}\n\n\t_renderAvatarStack() {\n\t\tconst avatars = this.state.teamAvatars;\n\t\tif (!avatars || avatars.length === 0) {\n\t\t\treturn `\n\t\t\t\t<div class=\"messenger-avatar-stack messenger-avatar-stack-small\">\n\t\t\t\t\t<div class=\"messenger-avatar messenger-avatar-small\" style=\"background: #5856d6;\">S</div>\n\t\t\t\t\t<div class=\"messenger-avatar messenger-avatar-small\" style=\"background: #007aff;\">T</div>\n\t\t\t\t</div>\n\t\t\t`;\n\t\t}\n\n\t\tconst avatarItems = avatars\n\t\t\t.slice(0, 2)\n\t\t\t.map((avatar, i) => {\n\t\t\t\tif (typeof avatar === 'string' && avatar.startsWith('http')) {\n\t\t\t\t\treturn `<img class=\"messenger-avatar messenger-avatar-small\" src=\"${avatar}\" alt=\"Team member\" style=\"z-index: ${2 - i};\" />`;\n\t\t\t\t}\n\t\t\t\treturn `<div class=\"messenger-avatar messenger-avatar-small\" style=\"background: ${this._getAvatarColor(i)}; z-index: ${2 - i};\">${avatar.charAt(0).toUpperCase()}</div>`;\n\t\t\t})\n\t\t\t.join('');\n\n\t\treturn `<div class=\"messenger-avatar-stack messenger-avatar-stack-small\">${avatarItems}</div>`;\n\t}\n\n\t_getAvatarColor(index) {\n\t\tconst colors = ['#5856d6', '#007aff', '#34c759', '#ff9500', '#ff3b30'];\n\t\treturn colors[index % colors.length];\n\t}\n\n\t_formatTimeAgo(timestamp) {\n\t\tif (!timestamp) return '';\n\t\tconst date = new Date(timestamp);\n\t\tconst now = new Date();\n\t\tconst diffMs = now - date;\n\t\tconst diffMins = Math.floor(diffMs / 60000);\n\t\tconst diffHours = Math.floor(diffMs / 3600000);\n\t\tconst diffDays = Math.floor(diffMs / 86400000);\n\n\t\tif (diffMins < 1) return 'now';\n\t\tif (diffMins < 60) return `${diffMins}m`;\n\t\tif (diffHours < 24) return `${diffHours}h`;\n\t\tif (diffDays < 7) return `${diffDays}d`;\n\t\treturn date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });\n\t}\n\n\t_truncateMessage(message) {\n\t\tif (!message) return 'No messages yet';\n\t\tconst maxLength = 50;\n\t\tif (message.length <= maxLength) return message;\n\t\treturn message.substring(0, maxLength) + '...';\n\t}\n\n\t_attachEvents() {\n\t\t// Close button\n\t\tconst closeBtn = this.element.querySelector('.messenger-close-btn');\n\t\tif (closeBtn) {\n\t\t\tcloseBtn.addEventListener('click', () => {\n\t\t\t\tthis.state.setOpen(false);\n\t\t\t});\n\t\t}\n\n\t\t// Conversation items\n\t\tthis.element\n\t\t\t.querySelectorAll('.messenger-conversation-item')\n\t\t\t.forEach((item) => {\n\t\t\t\titem.addEventListener('click', () => {\n\t\t\t\t\tconst convId = item.dataset.conversationId;\n\t\t\t\t\tthis.state.setActiveConversation(convId);\n\t\t\t\t\tthis.state.markAsRead(convId);\n\t\t\t\t\tthis.state.setView('chat');\n\t\t\t\t});\n\t\t\t});\n\n\t\t// New message button\n\t\tconst newMsgBtn = this.element.querySelector('.messenger-new-message-btn');\n\t\tif (newMsgBtn) {\n\t\t\tnewMsgBtn.addEventListener('click', () => {\n\t\t\t\tthis._startNewConversation();\n\t\t\t});\n\t\t}\n\t}\n\n\t_startNewConversation() {\n\t\t// Create a new conversation and navigate to chat\n\t\tconst newConv = {\n\t\t\tid: 'conv_' + Date.now(),\n\t\t\ttitle: 'New conversation',\n\t\t\tparticipants: [],\n\t\t\tlastMessage: null,\n\t\t\tlastMessageTime: new Date().toISOString(),\n\t\t\tunread: 0,\n\t\t};\n\t\tthis.state.addConversation(newConv);\n\t\tthis.state.setActiveConversation(newConv.id);\n\t\tthis.state.setView('chat');\n\t}\n\n\tdestroy() {\n\t\tif (this._unsubscribe) {\n\t\t\tthis._unsubscribe();\n\t\t}\n\t\tif (this.element && this.element.parentNode) {\n\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t}\n\t}\n}\n","/**\n * HelpView - Help collections browse with Intercom-style design\n */\nexport class HelpView {\n\tconstructor(state, options = {}) {\n\t\tthis.state = state;\n\t\tthis.options = options;\n\t\tthis.element = null;\n\t\tthis._unsubscribe = null;\n\t}\n\n\trender() {\n\t\tthis.element = document.createElement('div');\n\t\tthis.element.className = 'messenger-view messenger-help-view';\n\n\t\tthis._updateContent();\n\n\t\t// Subscribe to state changes\n\t\tthis._unsubscribe = this.state.subscribe((type) => {\n\t\t\tif (type === 'helpArticlesUpdate' || type === 'helpSearchChange') {\n\t\t\t\tthis._updateCollectionsList();\n\t\t\t}\n\t\t});\n\n\t\treturn this.element;\n\t}\n\n\t_updateContent() {\n\t\tconst searchQuery = this.state.helpSearchQuery || '';\n\t\tconst collections = this.state.helpArticles || [];\n\t\tconst collectionCount = collections.length;\n\n\t\tthis.element.innerHTML = `\n\t\t\t<div class=\"messenger-help-header\">\n\t\t\t\t<h2>Help</h2>\n\t\t\t\t<button class=\"messenger-close-btn\" aria-label=\"Close\">\n\t\t\t\t\t<i class=\"ph ph-x\" style=\"font-size: 20px;\"></i>\n\t\t\t\t</button>\n\t\t\t</div>\n\n\t\t\t<div class=\"messenger-help-search\">\n\t\t\t\t<div class=\"messenger-help-search-wrapper\">\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\tclass=\"messenger-help-search-input\"\n\t\t\t\t\t\tplaceholder=\"Search for help\"\n\t\t\t\t\t\tvalue=\"${searchQuery}\"\n\t\t\t\t\t/>\n\t\t\t\t\t<i class=\"ph ph-magnifying-glass messenger-help-search-icon\" style=\"font-size: 18px;\"></i>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div class=\"messenger-help-body\">\n\t\t\t\t<div class=\"messenger-help-collections-header\">\n\t\t\t\t\t${collectionCount} collections\n\t\t\t\t</div>\n\t\t\t\t<div class=\"messenger-help-collections\"></div>\n\t\t\t</div>\n\t\t`;\n\n\t\tthis._updateCollectionsList();\n\t\tthis._attachEvents();\n\t}\n\n\t_updateCollectionsList() {\n\t\tconst collectionsContainer = this.element.querySelector(\n\t\t\t'.messenger-help-collections'\n\t\t);\n\t\tconst collections = this.state.helpArticles || [];\n\t\tconst searchQuery = (this.state.helpSearchQuery || '').toLowerCase();\n\n\t\t// Filter collections by search\n\t\tconst filteredCollections = searchQuery\n\t\t\t? collections.filter(\n\t\t\t\t\t(c) =>\n\t\t\t\t\t\tc.title.toLowerCase().includes(searchQuery) ||\n\t\t\t\t\t\t(c.description && c.description.toLowerCase().includes(searchQuery))\n\t\t\t\t)\n\t\t\t: collections;\n\n\t\t// Update collection count\n\t\tconst headerEl = this.element.querySelector(\n\t\t\t'.messenger-help-collections-header'\n\t\t);\n\t\tif (headerEl) {\n\t\t\theaderEl.textContent = `${filteredCollections.length} collections`;\n\t\t}\n\n\t\tif (filteredCollections.length === 0) {\n\t\t\tcollectionsContainer.innerHTML = this._renderEmptyState();\n\t\t\treturn;\n\t\t}\n\n\t\tcollectionsContainer.innerHTML = filteredCollections\n\t\t\t.map((collection) => this._renderCollectionItem(collection))\n\t\t\t.join('');\n\n\t\t// Attach click events\n\t\tthis._attachCollectionEvents();\n\t}\n\n\t_renderCollectionItem(collection) {\n\t\tconst articleCount = collection.articleCount || 0;\n\t\treturn `\n\t\t\t<div class=\"messenger-help-collection\" data-collection-id=\"${collection.id}\">\n\t\t\t\t<div class=\"messenger-help-collection-content\">\n\t\t\t\t\t<h3 class=\"messenger-help-collection-title\">${collection.title}</h3>\n\t\t\t\t\t<p class=\"messenger-help-collection-desc\">${collection.description || ''}</p>\n\t\t\t\t\t<span class=\"messenger-help-collection-count\">${articleCount} articles</span>\n\t\t\t\t</div>\n\t\t\t\t<i class=\"ph ph-caret-right messenger-help-collection-arrow\" style=\"font-size: 20px;\"></i>\n\t\t\t</div>\n\t\t`;\n\t}\n\n\t_renderEmptyState() {\n\t\tconst isSearching = this.state.helpSearchQuery;\n\n\t\tif (isSearching) {\n\t\t\treturn `\n\t\t\t\t<div class=\"messenger-help-empty\">\n\t\t\t\t\t<div class=\"messenger-help-empty-icon\">\n\t\t\t\t\t\t<i class=\"ph ph-magnifying-glass\" style=\"font-size: 48px;\"></i>\n\t\t\t\t\t</div>\n\t\t\t\t\t<h3>No results found</h3>\n\t\t\t\t\t<p>Try a different search term</p>\n\t\t\t\t</div>\n\t\t\t`;\n\t\t}\n\n\t\treturn `\n\t\t\t<div class=\"messenger-help-empty\">\n\t\t\t\t<div class=\"messenger-help-empty-icon\">\n\t\t\t\t\t<i class=\"ph ph-question\" style=\"font-size: 48px;\"></i>\n\t\t\t\t</div>\n\t\t\t\t<h3>Help collections</h3>\n\t\t\t\t<p>No collections available yet</p>\n\t\t\t</div>\n\t\t`;\n\t}\n\n\t_attachEvents() {\n\t\t// Close button\n\t\tthis.element\n\t\t\t.querySelector('.messenger-close-btn')\n\t\t\t.addEventListener('click', () => {\n\t\t\t\tthis.state.setOpen(false);\n\t\t\t});\n\n\t\t// Search input\n\t\tconst searchInput = this.element.querySelector(\n\t\t\t'.messenger-help-search-input'\n\t\t);\n\t\tlet searchTimeout;\n\t\tsearchInput.addEventListener('input', (e) => {\n\t\t\tclearTimeout(searchTimeout);\n\t\t\tsearchTimeout = setTimeout(() => {\n\t\t\t\tthis.state.setHelpSearchQuery(e.target.value);\n\t\t\t}, 300);\n\t\t});\n\n\t\tthis._attachCollectionEvents();\n\t}\n\n\t_attachCollectionEvents() {\n\t\tthis.element\n\t\t\t.querySelectorAll('.messenger-help-collection')\n\t\t\t.forEach((item) => {\n\t\t\t\titem.addEventListener('click', () => {\n\t\t\t\t\tconst collectionId = item.dataset.collectionId;\n\t\t\t\t\tconst collection = this.state.helpArticles.find(\n\t\t\t\t\t\t(c) => c.id === collectionId\n\t\t\t\t\t);\n\t\t\t\t\tif (collection && collection.url) {\n\t\t\t\t\t\twindow.open(collection.url, '_blank');\n\t\t\t\t\t} else if (this.options.onArticleClick) {\n\t\t\t\t\t\tthis.options.onArticleClick(collection);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\t}\n\n\tdestroy() {\n\t\tif (this._unsubscribe) {\n\t\t\tthis._unsubscribe();\n\t\t}\n\t\tif (this.element && this.element.parentNode) {\n\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t}\n\t}\n}\n","/**\n * HomeView - Welcome screen with team info and quick actions\n */\nexport class HomeView {\n\tconstructor(state, options = {}) {\n\t\tthis.state = state;\n\t\tthis.options = options;\n\t\tthis.element = null;\n\t\tthis._unsubscribe = null;\n\t}\n\n\trender() {\n\t\tthis.element = document.createElement('div');\n\t\tthis.element.className = 'messenger-view messenger-home-view';\n\n\t\tthis._updateContent();\n\n\t\t// Subscribe to state changes to re-render when data loads\n\t\tthis._unsubscribe = this.state.subscribe((type) => {\n\t\t\tif (type === 'homeChangelogUpdate' || type === 'conversationsUpdate') {\n\t\t\t\tthis._updateContent();\n\t\t\t}\n\t\t});\n\n\t\treturn this.element;\n\t}\n\n\t_updateContent() {\n\t\tconst avatarsHtml = this._renderAvatarStack();\n\t\tconst recentChangelogHtml = this._renderRecentChangelog();\n\n\t\tthis.element.innerHTML = `\n\t\t\t<div class=\"messenger-home-header\">\n\t\t\t\t<div class=\"messenger-home-header-top\">\n\t\t\t\t\t<div class=\"messenger-home-logo\">\n\t\t\t\t\t\t${this.options.logoUrl ? `<img src=\"${this.options.logoUrl}\" alt=\"${this.state.teamName}\" />` : ''}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"messenger-home-avatars\">${avatarsHtml}</div>\n\t\t\t\t\t<button class=\"messenger-close-btn\" aria-label=\"Close\">\n\t\t\t\t\t\t<i class=\"ph ph-x\" style=\"font-size: 20px;\"></i>\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"messenger-home-welcome\">\n\t\t\t\t\t<span class=\"messenger-home-greeting\">Hello there.</span>\n\t\t\t\t\t<span class=\"messenger-home-question\">${this.state.welcomeMessage}</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div class=\"messenger-home-body\">\n\t\t\t\t<button class=\"messenger-home-message-btn\">\n\t\t\t\t\t<span>Send us a message</span>\n\t\t\t\t\t<i class=\"ph ph-arrow-right\" style=\"font-size: 16px;\"></i>\n\t\t\t\t</button>\n\n\t\t\t\t${this._renderFeaturedCard()}\n\n\t\t\t\t${recentChangelogHtml}\n\t\t\t</div>\n\t\t`;\n\n\t\tthis._attachEvents();\n\t}\n\n\t_renderAvatarStack() {\n\t\tconst avatars = this.state.teamAvatars;\n\t\tif (!avatars || avatars.length === 0) {\n\t\t\t// Default avatars with initials\n\t\t\treturn `\n\t\t\t\t<div class=\"messenger-avatar-stack\">\n\t\t\t\t\t<div class=\"messenger-avatar\" style=\"background: #5856d6;\">S</div>\n\t\t\t\t\t<div class=\"messenger-avatar\" style=\"background: #007aff;\">T</div>\n\t\t\t\t</div>\n\t\t\t`;\n\t\t}\n\n\t\tconst avatarItems = avatars\n\t\t\t.slice(0, 3)\n\t\t\t.map((avatar, i) => {\n\t\t\t\tif (typeof avatar === 'string' && avatar.startsWith('http')) {\n\t\t\t\t\treturn `<img class=\"messenger-avatar\" src=\"${avatar}\" alt=\"Team member\" style=\"z-index: ${3 - i};\" />`;\n\t\t\t\t}\n\t\t\t\treturn `<div class=\"messenger-avatar\" style=\"background: ${this._getAvatarColor(i)}; z-index: ${3 - i};\">${avatar.charAt(0).toUpperCase()}</div>`;\n\t\t\t})\n\t\t\t.join('');\n\n\t\treturn `<div class=\"messenger-avatar-stack\">${avatarItems}</div>`;\n\t}\n\n\t_getAvatarColor(index) {\n\t\tconst colors = ['#5856d6', '#007aff', '#34c759', '#ff9500', '#ff3b30'];\n\t\treturn colors[index % colors.length];\n\t}\n\n\t_renderFeaturedCard() {\n\t\t// Only show if there's featured content configured\n\t\tif (!this.options.featuredContent) {\n\t\t\treturn '';\n\t\t}\n\n\t\tconst { title, description, imageUrl, action } =\n\t\t\tthis.options.featuredContent;\n\n\t\treturn `\n\t\t\t<div class=\"messenger-home-featured\">\n\t\t\t\t${imageUrl ? `<img src=\"${imageUrl}\" alt=\"${title}\" class=\"messenger-home-featured-image\" onerror=\"this.style.display='none';\" />` : ''}\n\t\t\t\t<div class=\"messenger-home-featured-content\">\n\t\t\t\t\t<h3>${title}</h3>\n\t\t\t\t\t<p>${description}</p>\n\t\t\t\t</div>\n\t\t\t\t${action ? `<button class=\"messenger-home-featured-btn\" data-action=\"${action.type}\" data-value=\"${action.value}\">${action.label}</button>` : ''}\n\t\t\t</div>\n\t\t`;\n\t}\n\n\t_renderRecentChangelog() {\n\t\t// Show recent changelog preview as cards with images\n\t\tconst changelogItems = this.state.homeChangelogItems;\n\t\tif (changelogItems.length === 0) {\n\t\t\treturn '';\n\t\t}\n\n\t\tconst changelogHtml = changelogItems\n\t\t\t.map(\n\t\t\t\t(item) => `\n\t\t\t<div class=\"messenger-home-changelog-card\" data-changelog-id=\"${item.id}\">\n\t\t\t\t${\n\t\t\t\t\titem.coverImage\n\t\t\t\t\t\t? `\n\t\t\t\t\t<div class=\"messenger-home-changelog-cover\">\n\t\t\t\t\t\t<img src=\"${item.coverImage}\" alt=\"${item.title}\" onerror=\"this.style.display='none';\" />\n\t\t\t\t\t\t${item.coverText ? `<span class=\"messenger-home-changelog-cover-text\">${item.coverText}</span>` : ''}\n\t\t\t\t\t</div>\n\t\t\t\t`\n\t\t\t\t\t\t: ''\n\t\t\t\t}\n\t\t\t\t<div class=\"messenger-home-changelog-card-content\">\n\t\t\t\t\t<h4 class=\"messenger-home-changelog-card-title\">${item.title}</h4>\n\t\t\t\t\t<p class=\"messenger-home-changelog-card-desc\">${item.description || ''}</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t`\n\t\t\t)\n\t\t\t.join('');\n\n\t\treturn `\n\t\t\t<div class=\"messenger-home-changelog-section\">\n\t\t\t\t${changelogHtml}\n\t\t\t</div>\n\t\t`;\n\t}\n\n\t_formatDate(dateString) {\n\t\tif (!dateString) return '';\n\t\tconst date = new Date(dateString);\n\t\tconst now = new Date();\n\t\tconst diffDays = Math.floor((now - date) / (1000 * 60 * 60 * 24));\n\n\t\tif (diffDays === 0) return 'Today';\n\t\tif (diffDays === 1) return 'Yesterday';\n\t\tif (diffDays < 7) return `${diffDays}d ago`;\n\t\treturn date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });\n\t}\n\n\t_attachEvents() {\n\t\t// Close button\n\t\tthis.element\n\t\t\t.querySelector('.messenger-close-btn')\n\t\t\t.addEventListener('click', () => {\n\t\t\t\tthis.state.setOpen(false);\n\t\t\t});\n\n\t\t// Send message button\n\t\tthis.element\n\t\t\t.querySelector('.messenger-home-message-btn')\n\t\t\t.addEventListener('click', () => {\n\t\t\t\tthis.state.setView('messages');\n\t\t\t});\n\n\t\t// Changelog items\n\t\tthis.element\n\t\t\t.querySelectorAll('.messenger-home-changelog-item')\n\t\t\t.forEach((item) => {\n\t\t\t\titem.addEventListener('click', () => {\n\t\t\t\t\t// Navigate to changelog view with specific item selected\n\t\t\t\t\tthis.state.setView('changelog');\n\t\t\t\t});\n\t\t\t});\n\n\t\t// See all changelog\n\t\tconst seeAllBtn = this.element.querySelector(\n\t\t\t'.messenger-home-changelog-all'\n\t\t);\n\t\tif (seeAllBtn) {\n\t\t\tseeAllBtn.addEventListener('click', () => {\n\t\t\t\tthis.state.setView('changelog');\n\t\t\t});\n\t\t}\n\n\t\t// Featured card action\n\t\tconst featuredBtn = this.element.querySelector(\n\t\t\t'.messenger-home-featured-btn'\n\t\t);\n\t\tif (featuredBtn) {\n\t\t\tfeaturedBtn.addEventListener('click', () => {\n\t\t\t\tconst action = featuredBtn.dataset.action;\n\t\t\t\tconst value = featuredBtn.dataset.value;\n\t\t\t\tif (action === 'url') {\n\t\t\t\t\twindow.open(value, '_blank');\n\t\t\t\t} else if (action === 'view') {\n\t\t\t\t\tthis.state.setView(value);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tdestroy() {\n\t\tif (this._unsubscribe) {\n\t\t\tthis._unsubscribe();\n\t\t}\n\t\tif (this.element && this.element.parentNode) {\n\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t}\n\t}\n}\n","/**\n * MessengerWidget - Full-featured Messenger/Chat widget\n */\nimport { BaseWidget } from './BaseWidget.js';\nimport { MessengerState } from './messenger/MessengerState.js';\nimport { MessengerLauncher } from './messenger/components/MessengerLauncher.js';\nimport { MessengerPanel } from './messenger/components/MessengerPanel.js';\nimport { ChangelogView } from './messenger/views/ChangelogView.js';\nimport { ChatView } from './messenger/views/ChatView.js';\nimport { ConversationsView } from './messenger/views/ConversationsView.js';\nimport { HelpView } from './messenger/views/HelpView.js';\nimport { HomeView } from './messenger/views/HomeView.js';\n\nexport class MessengerWidget extends BaseWidget {\n\tconstructor(options) {\n\t\tsuper({ ...options, type: 'messenger' });\n\n\t\tthis.messengerOptions = {\n\t\t\tposition: options.position || 'bottom-right',\n\t\t\ttheme: options.theme || 'light',\n\t\t\tteamName: options.teamName || 'Support',\n\t\t\tteamAvatars: options.teamAvatars || [],\n\t\t\twelcomeMessage: options.welcomeMessage || 'How can we help?',\n\t\t\tenableHelp: options.enableHelp !== false,\n\t\t\tenableChangelog: options.enableChangelog !== false,\n\t\t\tlogoUrl: options.logoUrl || 'https://feedback-sdk.product7.io/p7.png',\n\t\t\tfeaturedContent: options.featuredContent || null,\n\t\t\tprimaryColor: options.primaryColor || '#1c1c1e',\n\t\t\t// Callbacks\n\t\t\tonSendMessage: options.onSendMessage || null,\n\t\t\tonArticleClick: options.onArticleClick || null,\n\t\t\tonChangelogClick: options.onChangelogClick || null,\n\t\t};\n\n\t\t// Create state\n\t\tthis.messengerState = new MessengerState({\n\t\t\tteamName: this.messengerOptions.teamName,\n\t\t\tteamAvatars: this.messengerOptions.teamAvatars,\n\t\t\twelcomeMessage: this.messengerOptions.welcomeMessage,\n\t\t\tenableHelp: this.messengerOptions.enableHelp,\n\t\t\tenableChangelog: this.messengerOptions.enableChangelog,\n\t\t\tuserContext: this.sdk?.apiService?.getUserContext() || null,\n\t\t});\n\n\t\tthis.launcher = null;\n\t\tthis.panel = null;\n\n\t\t// Bind methods\n\t\tthis._handleOpenChange = this._handleOpenChange.bind(this);\n\t}\n\n\t_render() {\n\t\t// Create container\n\t\tconst container = document.createElement('div');\n\t\tcontainer.className = `messenger-widget theme-${this.messengerOptions.theme}`;\n\t\tcontainer.style.zIndex = '999999';\n\n\t\t// Create launcher\n\t\tthis.launcher = new MessengerLauncher(this.messengerState, {\n\t\t\tposition: this.messengerOptions.position,\n\t\t\tprimaryColor: this.messengerOptions.primaryColor,\n\t\t});\n\t\tcontainer.appendChild(this.launcher.render());\n\n\t\t// Create panel\n\t\tthis.panel = new MessengerPanel(this.messengerState, {\n\t\t\tposition: this.messengerOptions.position,\n\t\t\ttheme: this.messengerOptions.theme,\n\t\t\tprimaryColor: this.messengerOptions.primaryColor,\n\t\t\tlogoUrl: this.messengerOptions.logoUrl,\n\t\t\tfeaturedContent: this.messengerOptions.featuredContent,\n\t\t\tonSendMessage:\n\t\t\t\tthis.messengerOptions.onSendMessage ||\n\t\t\t\tthis._handleSendMessage.bind(this),\n\t\t\tonArticleClick: this.messengerOptions.onArticleClick,\n\t\t\tonChangelogClick: this.messengerOptions.onChangelogClick,\n\t\t});\n\n\t\t// Register views\n\t\tthis.panel.registerView('home', HomeView);\n\t\tthis.panel.registerView('messages', ConversationsView);\n\t\tthis.panel.registerView('chat', ChatView);\n\t\tthis.panel.registerView('help', HelpView);\n\t\tthis.panel.registerView('changelog', ChangelogView);\n\n\t\tcontainer.appendChild(this.panel.render());\n\t\tthis.panel.hide();\n\n\t\treturn container;\n\t}\n\n\t_attachEvents() {\n\t\t// Subscribe to state changes\n\t\tthis._stateUnsubscribe = this.messengerState.subscribe((type, data) => {\n\t\t\tif (type === 'openChange') {\n\t\t\t\tthis._handleOpenChange(data.isOpen);\n\t\t\t}\n\t\t});\n\t}\n\n\t_handleOpenChange(isOpen) {\n\t\tif (isOpen) {\n\t\t\tthis.panel.show();\n\t\t\tthis.sdk.eventBus.emit('messenger:opened', { widget: this });\n\t\t} else {\n\t\t\tthis.panel.hide();\n\t\t\tthis.messengerState.reset();\n\t\t\tthis.sdk.eventBus.emit('messenger:closed', { widget: this });\n\t\t}\n\t}\n\n\tasync _handleSendMessage(conversationId, message) {\n\t\t// Default message handler - can be overridden\n\t\tthis.sdk.eventBus.emit('messenger:messageSent', {\n\t\t\twidget: this,\n\t\t\tconversationId,\n\t\t\tmessage,\n\t\t});\n\n\t\t// In mock mode, simulate a response\n\t\tif (this.apiService?.mock) {\n\t\t\tsetTimeout(() => {\n\t\t\t\tconst response = {\n\t\t\t\t\tid: 'msg_' + Date.now(),\n\t\t\t\t\tcontent: \"Thanks for your message! We'll get back to you soon.\",\n\t\t\t\t\tisOwn: false,\n\t\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\t\tsender: {\n\t\t\t\t\t\tname: 'Support Team',\n\t\t\t\t\t\tavatarUrl: null,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t\tthis.messengerState.addMessage(conversationId, response);\n\t\t\t}, 1500);\n\t\t}\n\t}\n\n\t/**\n\t * Open the messenger panel\n\t */\n\topen() {\n\t\tthis.messengerState.setOpen(true);\n\t}\n\n\t/**\n\t * Close the messenger panel\n\t */\n\tclose() {\n\t\tthis.messengerState.setOpen(false);\n\t}\n\n\t/**\n\t * Toggle the messenger panel\n\t */\n\ttoggle() {\n\t\tthis.messengerState.setOpen(!this.messengerState.isOpen);\n\t}\n\n\t/**\n\t * Navigate to a specific view\n\t */\n\tnavigateTo(view) {\n\t\tthis.messengerState.setView(view);\n\t\tif (!this.messengerState.isOpen) {\n\t\t\tthis.open();\n\t\t}\n\t}\n\n\t/**\n\t * Set conversations\n\t */\n\tsetConversations(conversations) {\n\t\tthis.messengerState.setConversations(conversations);\n\t}\n\n\t/**\n\t * Add a message to a conversation\n\t */\n\taddMessage(conversationId, message) {\n\t\tthis.messengerState.addMessage(conversationId, message);\n\t}\n\n\t/**\n\t * Set help articles\n\t */\n\tsetHelpArticles(articles) {\n\t\tthis.messengerState.setHelpArticles(articles);\n\t}\n\n\t/**\n\t * Set home changelog items\n\t */\n\tsetHomeChangelogItems(items) {\n\t\tthis.messengerState.setHomeChangelogItems(items);\n\t}\n\n\t/**\n\t * Set changelog items\n\t */\n\tsetChangelogItems(items) {\n\t\tthis.messengerState.setChangelogItems(items);\n\t}\n\n\t/**\n\t * Update unread count (for external updates)\n\t */\n\tsetUnreadCount(count) {\n\t\tthis.messengerState.unreadCount = count;\n\t\tthis.messengerState._notify('unreadCountChange', { count });\n\t}\n\n\t/**\n\t * Get current state\n\t */\n\tgetState() {\n\t\treturn {\n\t\t\tisOpen: this.messengerState.isOpen,\n\t\t\tcurrentView: this.messengerState.currentView,\n\t\t\tunreadCount: this.messengerState.unreadCount,\n\t\t\tconversations: this.messengerState.conversations,\n\t\t};\n\t}\n\n\t/**\n\t * Load initial data (mock or API)\n\t */\n\tasync loadInitialData() {\n\t\t// Load conversations\n\t\ttry {\n\t\t\tconst conversations = await this._fetchConversations();\n\t\t\tthis.messengerState.setConversations(conversations);\n\t\t} catch (error) {\n\t\t\tconsole.error('[MessengerWidget] Failed to load conversations:', error);\n\t\t}\n\n\t\t// Load help articles if enabled\n\t\tif (this.messengerOptions.enableHelp) {\n\t\t\ttry {\n\t\t\t\tconst articles = await this._fetchHelpArticles();\n\t\t\t\tthis.messengerState.setHelpArticles(articles);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('[MessengerWidget] Failed to load help articles:', error);\n\t\t\t}\n\t\t}\n\n\t\t// Load changelog if enabled\n\t\tif (this.messengerOptions.enableChangelog) {\n\t\t\ttry {\n\t\t\t\tconst { homeItems, changelogItems } = await this._fetchChangelog();\n\t\t\t\tthis.messengerState.setHomeChangelogItems(homeItems);\n\t\t\t\tthis.messengerState.setChangelogItems(changelogItems);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('[MessengerWidget] Failed to load changelog:', error);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync _fetchConversations() {\n\t\t// Mock data for now\n\t\tif (this.apiService?.mock) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tid: 'conv_1',\n\t\t\t\t\ttitle: 'Chat with Sarah',\n\t\t\t\t\tparticipants: [{ name: 'Sarah', avatarUrl: null }],\n\t\t\t\t\tlastMessage: \"Sarah: Hi 👋 I'm Sarah. How can I help today?\",\n\t\t\t\t\tlastMessageTime: new Date(Date.now() - 49 * 60 * 1000).toISOString(),\n\t\t\t\t\tunread: 1,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: 'conv_2',\n\t\t\t\t\ttitle: 'Chat with Tom',\n\t\t\t\t\tparticipants: [{ name: 'Tom', avatarUrl: null }],\n\t\t\t\t\tlastMessage: 'Tom: The feature will be available next week.',\n\t\t\t\t\tlastMessageTime: new Date(\n\t\t\t\t\t\tDate.now() - 6 * 24 * 60 * 60 * 1000\n\t\t\t\t\t).toISOString(),\n\t\t\t\t\tunread: 0,\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\n\t\t// TODO: Implement API call\n\t\treturn [];\n\t}\n\n\tasync _fetchHelpArticles() {\n\t\t// Mock data for collections\n\t\tif (this.apiService?.mock) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tid: 'collection_1',\n\t\t\t\t\ttitle: 'Product Overview',\n\t\t\t\t\tdescription: 'See how your AI-first customer service solution works.',\n\t\t\t\t\tarticleCount: 24,\n\t\t\t\t\turl: '#',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: 'collection_2',\n\t\t\t\t\ttitle: 'Getting Started',\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'Everything you need to know to get started with Product7.',\n\t\t\t\t\tarticleCount: 30,\n\t\t\t\t\turl: '#',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: 'collection_3',\n\t\t\t\t\ttitle: 'AI Agent',\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'Resolving customer questions instantly and accurately—from live chat to email.',\n\t\t\t\t\tarticleCount: 82,\n\t\t\t\t\turl: '#',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: 'collection_4',\n\t\t\t\t\ttitle: 'Channels',\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'Enabling the channels you use to communicate with customers, all from the Inbox.',\n\t\t\t\t\tarticleCount: 45,\n\t\t\t\t\turl: '#',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: 'collection_5',\n\t\t\t\t\ttitle: 'Billing & Payments',\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'Manage your subscription, invoices, and payment methods.',\n\t\t\t\t\tarticleCount: 12,\n\t\t\t\t\turl: '#',\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\n\t\t// TODO: Implement API call\n\t\treturn [];\n\t}\n\n\tasync _fetchChangelog() {\n\t\t// Mock data for now - simulating changelog API response\n\t\tif (this.apiService?.mock) {\n\t\t\treturn {\n\t\t\t\thomeItems: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: 'changelog_5',\n\t\t\t\t\t\ttitle: 'New integrations available',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Connect with more tools you love and streamline your workflow.',\n\t\t\t\t\t\ttags: ['Integration'],\n\t\t\t\t\t\tcoverImage: 'https://feedback-sdk.product7.io/700x400__5_.png',\n\t\t\t\t\t\tcoverText: null,\n\t\t\t\t\t\tpublishedAt: new Date(\n\t\t\t\t\t\t\tDate.now() - 14 * 24 * 60 * 60 * 1000\n\t\t\t\t\t\t).toISOString(),\n\t\t\t\t\t\turl: '#',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: 'changelog_2',\n\t\t\t\t\t\ttitle: 'A new era of Insights has arrived',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'We announced Fin Insights, a groundbreaking, AI-powered product that gives you complete visibility into every customer conversation.',\n\t\t\t\t\t\ttags: ['New feature', 'AI'],\n\t\t\t\t\t\tcoverImage:\n\t\t\t\t\t\t\t'https://feedback-sdk.product7.io/Intercom_Messenger__1_.jpg',\n\t\t\t\t\t\tcoverText: 'Watch our major product launch on-demand',\n\t\t\t\t\t\tpublishedAt: new Date(\n\t\t\t\t\t\t\tDate.now() - 5 * 24 * 60 * 60 * 1000\n\t\t\t\t\t\t).toISOString(),\n\t\t\t\t\t\turl: '#',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: 'changelog_1',\n\t\t\t\t\t\ttitle: 'The 2025 Customer Service Transformation Report',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Learn how AI has transformed customer service from the ground up—rewriting its economics and reshaping expectations.',\n\t\t\t\t\t\ttags: ['Report'],\n\t\t\t\t\t\tcoverImage:\n\t\t\t\t\t\t\t'https://feedback-sdk.product7.io/Main_Report_Email_Header.png',\n\t\t\t\t\t\tcoverText: 'Customer service trends as we know them are dead.',\n\t\t\t\t\t\tpublishedAt: new Date(\n\t\t\t\t\t\t\tDate.now() - 2 * 24 * 60 * 60 * 1000\n\t\t\t\t\t\t).toISOString(),\n\t\t\t\t\t\turl: '#',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tchangelogItems: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: 'changelog_4',\n\t\t\t\t\t\ttitle: 'Enhanced conversation analytics',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Get deeper insights into your customer conversations with our new analytics dashboard.',\n\t\t\t\t\t\ttags: ['Analytics'],\n\t\t\t\t\t\tcoverImage:\n\t\t\t\t\t\t\t'https://feedback-sdk.product7.io/cgangelog-Frame%202087334450.jpg',\n\t\t\t\t\t\tcoverText: null,\n\t\t\t\t\t\tpublishedAt: new Date(\n\t\t\t\t\t\t\tDate.now() - 10 * 24 * 60 * 60 * 1000\n\t\t\t\t\t\t).toISOString(),\n\t\t\t\t\t\turl: '#',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: 'changelog_3',\n\t\t\t\t\t\ttitle: 'Escalation guidance for complex issues',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'New AI-powered escalation guidance helps your team handle complex customer issues more effectively.',\n\t\t\t\t\t\ttags: ['New feature', 'AI'],\n\t\t\t\t\t\tcoverImage:\n\t\t\t\t\t\t\t'https://feedback-sdk.product7.io/cgangelog-image-escalation-guidance-event@2x.png',\n\t\t\t\t\t\tcoverText: null,\n\t\t\t\t\t\tpublishedAt: new Date(\n\t\t\t\t\t\t\tDate.now() - 7 * 24 * 60 * 60 * 1000\n\t\t\t\t\t\t).toISOString(),\n\t\t\t\t\t\turl: '#',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t};\n\t\t}\n\n\t\t// TODO: Implement API call for changelogs\n\t\treturn { homeItems: [], changelogItems: [] };\n\t}\n\n\tonMount() {\n\t\t// Load initial data after mounting\n\t\tthis.loadInitialData();\n\t}\n\n\tonDestroy() {\n\t\tif (this._stateUnsubscribe) {\n\t\t\tthis._stateUnsubscribe();\n\t\t}\n\t}\n\n\tdestroy() {\n\t\tif (this.launcher) {\n\t\t\tthis.launcher.destroy();\n\t\t}\n\t\tif (this.panel) {\n\t\t\tthis.panel.destroy();\n\t\t}\n\t\tsuper.destroy();\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\tsurveyId: options.surveyId || null, // Backend survey ID for API calls\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;\">&times;</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 responseData = {\n\t\t\trating: this.surveyState.score,\n\t\t\tfeedback: this.surveyState.feedback,\n\t\t\tanswers: this.surveyState.customAnswers,\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\n\t\ttry {\n\t\t\tconst surveyId =\n\t\t\t\tthis.surveyOptions.surveyId || `local_${type}_${Date.now()}`;\n\t\t\tawait this.apiService.submitSurveyResponse(surveyId, responseData);\n\t\t} catch (error) {\n\t\t\tconsole.error('[SurveyWidget] Failed to submit survey:', error);\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\tasync _handleDismiss() {\n\t\t// Call dismiss API if survey has a backend ID\n\t\tif (this.surveyOptions.surveyId) {\n\t\t\ttry {\n\t\t\t\tawait this.apiService.dismissSurvey(this.surveyOptions.surveyId);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('[SurveyWidget] Failed to dismiss survey:', error);\n\t\t\t}\n\t\t}\n\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 { MessengerWidget } from './MessengerWidget.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\t['messenger', MessengerWidget],\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 * Fetch active surveys from the backend\n\t * @param {Object} context - Optional context for targeting\n\t * @param {string} context.page - Current page/route\n\t * @param {string} context.event - Event trigger name\n\t * @returns {Promise<Array>} Array of active survey configurations\n\t */\n\tasync getActiveSurveys(context = {}) {\n\t\tif (!this.initialized) {\n\t\t\tthrow new SDKError(\n\t\t\t\t'SDK must be initialized before fetching surveys. Call init() first.'\n\t\t\t);\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await this.apiService.getActiveSurveys(context);\n\t\t\treturn result.data || [];\n\t\t} catch (error) {\n\t\t\tthis.eventBus.emit('sdk:error', { error });\n\t\t\tthrow new SDKError(\n\t\t\t\t`Failed to fetch active surveys: ${error.message}`,\n\t\t\t\terror\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Show a survey by its backend ID\n\t * Fetches survey configuration from the backend and displays it\n\t * @param {string} surveyId - The backend survey ID\n\t * @param {Object} options - Additional display options\n\t * @param {string} options.position - Position override\n\t * @param {string} options.theme - Theme override\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 {Promise<SurveyWidget>} The survey widget instance\n\t */\n\tasync showSurveyById(surveyId, 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\t// Fetch active surveys to find the one with matching ID\n\t\tconst surveys = await this.getActiveSurveys();\n\t\tconst surveyConfig = surveys.find((s) => s.id === surveyId);\n\n\t\tif (!surveyConfig) {\n\t\t\tthrow new SDKError(\n\t\t\t\t`Survey with ID '${surveyId}' not found or not active`\n\t\t\t);\n\t\t}\n\n\t\treturn this.showSurvey({\n\t\t\tsurveyId: surveyConfig.id,\n\t\t\tsurveyType: surveyConfig.type,\n\t\t\ttitle: surveyConfig.title,\n\t\t\tdescription: surveyConfig.description,\n\t\t\tlowLabel: surveyConfig.low_label,\n\t\t\thighLabel: surveyConfig.high_label,\n\t\t\tcustomQuestions: surveyConfig.questions,\n\t\t\t...options,\n\t\t});\n\t}\n\n\t/**\n\t * Show a survey widget (local/manual mode)\n\t * For backend-driven surveys, use showSurveyById() instead\n\t * @param {Object} options - Survey options\n\t * @param {string} options.surveyId - Backend survey ID (for API tracking)\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\tsurveyId: options.surveyId,\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 { MESSENGER_STYLES } from './styles/messengerStyles.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 { MessengerWidget } from './widgets/MessengerWidget.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 + MESSENGER_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\tMessengerWidget,\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\tMessengerWidget,\n\tSDKError,\n\tSurveyWidget,\n\tTabWidget,\n\tValidationError,\n\tWidgetError,\n\tWidgetFactory,\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","MOCK_SURVEYS","id","type","title","description","low_label","high_label","trigger","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","content","board","board_id","attachments","Authorization","getActiveSurveys","context","queryParams","URLSearchParams","currentUrl","url","window","location","href","append","deviceInfo","_getDeviceInfo","device","browser","os","userProperties","endpoint","toString","navigator","ua","userAgent","test","includes","submitSurveyResponse","surveyId","responseData","survey_id","rating","feedback","answers","dismissSurvey","setUserContext","localStorage","setItem","getUserContext","clearSession","removeItem","sessionData","token","expiry","toISOString","stored","getItem","parse","options","fetch","ok","errorMessage","json","e","text","contentType","get","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","substring","deepMerge","target","source","result","key","hasOwnProperty","Array","isArray","isBrowser","document","func","wait","timeout","args","clearTimeout","ms","string","replace","bytes","i","floor","log","parseFloat","pow","toFixed","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","email","trim","str","div","createElement","textContent","innerHTML","scrollIntoView","behavior","block","inline","lastKey","pop","limit","lastFunc","lastRan","required","missing","join","BaseWidget","sdk","apiService","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","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","isMinimized","button","Object","assign","clickedMinimize","closest","clickedExpand","stopPropagation","minimize","restore","transform","updateText","textEl","updatePosition","InlineWidget","form","textarea","originalContent","updateTitle","titleElement","setPlaceholder","placeholder","input","MessengerState","currentView","unreadCount","activeConversationId","conversations","messages","helpArticles","helpSearchQuery","homeChangelogItems","changelogItems","teamName","teamAvatars","welcomeMessage","enableHelp","enableChangelog","_listeners","Set","subscribe","delete","_notify","changeType","cb","setView","view","previousView","setOpen","setActiveConversation","conversationId","setConversations","_updateUnreadCount","addConversation","conversation","unshift","setMessages","addMessage","conv","find","c","lastMessage","lastMessageTime","timestamp","isOwn","unread","markAsRead","reduce","sum","count","setHelpArticles","articles","setHelpSearchQuery","query","setHomeChangelogItems","items","setChangelogItems","getActiveConversation","getActiveMessages","getFilteredHelpArticles","toLowerCase","filter","article","reset","MessengerLauncher","_unsubscribe","render","_updateContent","_updateIcon","_updateBadge","badgeHtml","chatIcon","closeIcon","existingBadge","badge","NavigationTabs","_updateActiveTab","_getTabs","tabs","label","icon","_getHomeIcon","_getMessagesIcon","_getHelpIcon","_getChangelogIcon","tabsHtml","map","tab","isActive","tabId","dataset","querySelectorAll","toggle","MessengerPanel","navigationTabs","currentViewComponent","viewRegistry","registerView","ViewClass","_renderCurrentView","viewsContainer","setHeader","headerContent","header","ChangelogView","_updateChangelogList","avatarsHtml","_renderTeamAvatars","changelogContainer","item","_renderChangelogCard","_attachChangelogEvents","_renderEmptyState","tagsHtml","tags","tag","dateStr","_formatDate","publishedAt","date","coverImage","_truncateText","avatars","colors","slice","avatar","startsWith","charAt","toUpperCase","dateString","toLocaleDateString","month","day","year","maxLength","card","changelogId","changelogItem","n","open","onChangelogClick","ChatView","_appendMessage","_scrollToBottom","messagesHtml","msg","_renderMessage","avatarHtml","_renderConversationAvatar","messageClass","timeStr","_formatMessageTime","_formatMessageContent","_renderSenderAvatar","sender","avatarUrl","participants","p","toLocaleTimeString","hour","minute","hour12","messagesContainer","emptyState","messageHtml","tempDiv","firstElementChild","scrollTop","scrollHeight","sendBtn","min","shiftKey","_sendMessage","onSendMessage","ConversationsView","_renderAvatarStack","conversationsHtml","_renderConversationItem","unreadClass","timeAgo","_formatTimeAgo","_renderConversationAvatars","_truncateMessage","_getAvatarColor","diffMs","diffMins","diffHours","diffDays","closeBtn","convId","newMsgBtn","_startNewConversation","newConv","HelpView","_updateCollectionsList","searchQuery","collectionCount","collectionsContainer","collections","filteredCollections","headerEl","collection","_renderCollectionItem","_attachCollectionEvents","articleCount","searchTimeout","collectionId","onArticleClick","HomeView","recentChangelogHtml","_renderRecentChangelog","logoUrl","_renderFeaturedCard","featuredContent","imageUrl","action","coverText","seeAllBtn","featuredBtn","MessengerWidget","messengerOptions","messengerState","launcher","_handleOpenChange","zIndex","_handleSendMessage","_stateUnsubscribe","close","navigateTo","setUnreadCount","getState","loadInitialData","_fetchConversations","_fetchHelpArticles","homeItems","_fetchChangelog","SurveyWidget","surveyOptions","surveyType","lowLabel","highLabel","customQuestions","onSubmit","onDismiss","surveyState","score","customAnswers","isVisible","_renderSurvey","_closeSurvey","_getSurveyConfig","positionStyles","_getPositionStyles","themeStyles","_handleDismiss","surveyElement","cssText","html","_attachSurveyEvents","configs","nps","csat","emoji","ces","custom","_renderCustomQuestions","q","_renderQuestionInput","freq","question","opt","positions","center","_handleSubmit","_attachTypeSpecificEvents","_escapeHandler","btn","_selectNPS","parseInt","borderColor","_selectCSAT","_selectCES","_selectFrequency","select","background","color","btnScore","frequency","_showSuccessNotification","existing","insertBefore","transition","surveyEl","backdropEl","TabWidget","_getHoverTransform","textElement","WidgetFactory","static","register","WidgetClass","widgets","create","availableTypes","from","getAvailableTypes","isTypeRegistered","unregister","getWidgetClass","FeedbackSDK","_validateAndMergeConfig","initialized","alreadyInitialized","initData","createWidget","widgetOptions","getWidget","showSurveyById","surveyConfig","s","showSurvey","questions","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","CSS_STYLES","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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"}
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/messenger/MessengerState.js","../src/widgets/messenger/components/MessengerLauncher.js","../src/widgets/messenger/components/NavigationTabs.js","../src/widgets/messenger/components/MessengerPanel.js","../src/widgets/messenger/views/ChangelogView.js","../src/widgets/messenger/views/ChatView.js","../src/widgets/messenger/views/ConversationsView.js","../src/widgets/messenger/views/HelpView.js","../src/widgets/messenger/views/HomeView.js","../src/widgets/MessengerWidget.js","../src/widgets/SurveyWidget.js","../src/widgets/TabWidget.js","../src/widgets/WidgetFactory.js","../src/core/FeedbackSDK.js","../src/index.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\n// Mock surveys for development\nconst MOCK_SURVEYS = [\n\t{\n\t\tid: 'mock_nps_survey',\n\t\ttype: 'nps',\n\t\ttitle: 'How likely are you to recommend us?',\n\t\tdescription: 'Your feedback helps us improve',\n\t\tlow_label: 'Not likely',\n\t\thigh_label: 'Very likely',\n\t\ttrigger: 'manual',\n\t\tstatus: 'active',\n\t},\n\t{\n\t\tid: 'mock_csat_survey',\n\t\ttype: 'csat',\n\t\ttitle: 'How satisfied are you?',\n\t\tdescription: 'Rate your experience with our product',\n\t\ttrigger: 'manual',\n\t\tstatus: 'active',\n\t},\n\t{\n\t\tid: 'mock_ces_survey',\n\t\ttype: 'ces',\n\t\ttitle: 'How easy was it?',\n\t\tdescription: 'Rate the ease of completing your task',\n\t\tlow_label: 'Very difficult',\n\t\thigh_label: 'Very easy',\n\t\ttrigger: 'manual',\n\t\tstatus: 'active',\n\t},\n];\n\n// Environment URLs\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\t/**\n\t * Get active surveys for the current user/context\n\t * @param {Object} context - Optional context overrides for targeting\n\t * @param {string} context.url - Override current URL\n\t * @param {Object} context.userProperties - Additional user properties\n\t * @returns {Promise<Array>} Array of active surveys matching targeting rules\n\t */\n\tasync getActiveSurveys(context = {}) {\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 - return mock surveys\n\t\tif (this.mock) {\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 200));\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: MOCK_SURVEYS,\n\t\t\t};\n\t\t}\n\n\t\ttry {\n\t\t\tconst queryParams = new URLSearchParams();\n\n\t\t\t// Auto-detect current URL or use provided override\n\t\t\tconst currentUrl =\n\t\t\t\tcontext.url ||\n\t\t\t\t(typeof window !== 'undefined' ? window.location.href : '');\n\t\t\tif (currentUrl) {\n\t\t\t\tqueryParams.append('url', currentUrl);\n\t\t\t}\n\n\t\t\t// Auto-detect device info\n\t\t\tconst deviceInfo = this._getDeviceInfo();\n\t\t\tif (deviceInfo.device) queryParams.append('device', deviceInfo.device);\n\t\t\tif (deviceInfo.browser) queryParams.append('browser', deviceInfo.browser);\n\t\t\tif (deviceInfo.os) queryParams.append('os', deviceInfo.os);\n\n\t\t\t// Add user properties if provided\n\t\t\tif (context.userProperties) {\n\t\t\t\tqueryParams.append(\n\t\t\t\t\t'user_properties',\n\t\t\t\t\tJSON.stringify(context.userProperties)\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst endpoint = `/widget/surveys/active${queryParams.toString() ? '?' + queryParams.toString() : ''}`;\n\n\t\t\tconst response = await this._makeRequest(endpoint, {\n\t\t\t\tmethod: 'GET',\n\t\t\t\theaders: {\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.getActiveSurveys(context);\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 get active surveys: ${error.message}`,\n\t\t\t\terror.response\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Auto-detect device, browser, and OS info\n\t * @returns {Object} Device info object\n\t */\n\t_getDeviceInfo() {\n\t\tif (typeof navigator === 'undefined') {\n\t\t\treturn { device: null, browser: null, os: null };\n\t\t}\n\n\t\tconst ua = navigator.userAgent;\n\n\t\t// Detect device type\n\t\tlet device = 'desktop';\n\t\tif (/Mobi|Android/i.test(ua)) {\n\t\t\tdevice = /Tablet|iPad/i.test(ua) ? 'tablet' : 'mobile';\n\t\t}\n\n\t\t// Detect browser\n\t\tlet browser = 'unknown';\n\t\tif (ua.includes('Firefox')) browser = 'firefox';\n\t\telse if (ua.includes('Edg')) browser = 'edge';\n\t\telse if (ua.includes('Chrome')) browser = 'chrome';\n\t\telse if (ua.includes('Safari')) browser = 'safari';\n\t\telse if (ua.includes('Opera') || ua.includes('OPR')) browser = 'opera';\n\n\t\t// Detect OS\n\t\tlet os = 'unknown';\n\t\tif (ua.includes('Windows')) os = 'windows';\n\t\telse if (ua.includes('Mac')) os = 'macos';\n\t\telse if (ua.includes('Linux')) os = 'linux';\n\t\telse if (ua.includes('Android')) os = 'android';\n\t\telse if (ua.includes('iPhone') || ua.includes('iPad')) os = 'ios';\n\n\t\treturn { device, browser, os };\n\t}\n\n\t/**\n\t * Submit a survey response\n\t * @param {string} surveyId - The survey ID\n\t * @param {Object} responseData - The survey response data\n\t * @param {number|string} responseData.rating - The rating/score value\n\t * @param {string} responseData.feedback - Optional text feedback\n\t * @param {Object} responseData.answers - For custom surveys, key-value pairs\n\t * @returns {Promise<Object>} Submission result\n\t */\n\tasync submitSurveyResponse(surveyId, responseData) {\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\tif (!surveyId) {\n\t\t\tthrow new APIError(400, 'Survey ID is required');\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, 300));\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: {\n\t\t\t\t\tid: 'mock_response_' + Date.now(),\n\t\t\t\t\tsurvey_id: surveyId,\n\t\t\t\t\t...responseData,\n\t\t\t\t},\n\t\t\t\tmessage: 'Survey response submitted successfully!',\n\t\t\t};\n\t\t}\n\n\t\tconst payload = {\n\t\t\trating: responseData.rating,\n\t\t\tfeedback: responseData.feedback || '',\n\t\t\tanswers: responseData.answers || {},\n\t\t};\n\n\t\ttry {\n\t\t\tconst response = await this._makeRequest(\n\t\t\t\t`/widget/surveys/${surveyId}/responses`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\tbody: JSON.stringify(payload),\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t\tAuthorization: `Bearer ${this.sessionToken}`,\n\t\t\t\t\t},\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.submitSurveyResponse(surveyId, responseData);\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 survey response: ${error.message}`,\n\t\t\t\terror.response\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Dismiss a survey (mark as seen but not completed)\n\t * @param {string} surveyId - The survey ID to dismiss\n\t * @returns {Promise<Object>} Dismissal result\n\t */\n\tasync dismissSurvey(surveyId) {\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\tif (!surveyId) {\n\t\t\tthrow new APIError(400, 'Survey ID is required');\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, 100));\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: 'Survey dismissed successfully',\n\t\t\t};\n\t\t}\n\n\t\ttry {\n\t\t\tconst response = await this._makeRequest(\n\t\t\t\t`/widget/surveys/${surveyId}/dismiss`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAuthorization: `Bearer ${this.sessionToken}`,\n\t\t\t\t\t},\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.dismissSurvey(surveyId);\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 dismiss survey: ${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\">&times;</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\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\">&times;</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 constructor(options) {\n super({ ...options, type: 'button' });\n this.isMinimized = false;\n }\n\n render() {\n const button = document.createElement('div');\n button.className = `feedback-widget feedback-widget-button theme-${this.options.theme} position-${this.options.position}`;\n button.innerHTML = `\n <button class=\"feedback-trigger-btn\" type=\"button\">\n <svg class=\"feedback-icon\" width=\"20\" height=\"20\" viewBox=\"0 0 256 256\" fill=\"currentColor\">\n <path d=\"M216,80H184V48a16,16,0,0,0-16-16H40A16,16,0,0,0,24,48V176a8,8,0,0,0,13,6.22L72,154V184a16,16,0,0,0,16,16h93.59L219,230.22a8,8,0,0,0,5,1.78,8,8,0,0,0,8-8V96A16,16,0,0,0,216,80ZM66.55,137.78,40,159.25V48H168v88H71.58A8,8,0,0,0,66.55,137.78ZM216,207.25l-26.55-21.47a8,8,0,0,0-5-1.78H88V152h80a16,16,0,0,0,16-16V96h32Z\"/>\n </svg>\n <span class=\"feedback-text\">Feedback</span>\n \n <div class=\"feedback-minimize-icon\">\n <svg viewBox=\"0 0 256 256\">\n <path d=\"M213.66,53.66,163.31,104H192a8,8,0,0,1,0,16H144a8,8,0,0,1-8-8V64a8,8,0,0,1,16,0V92.69l50.34-50.35a8,8,0,0,1,11.32,11.32ZM112,136H64a8,8,0,0,0,0,16H92.69L42.34,202.34a8,8,0,0,0,11.32,11.32L104,163.31V192a8,8,0,0,0,16,0V144A8,8,0,0,0,112,136Z\"/>\n </svg>\n </div>\n \n <div class=\"feedback-expand-icon\">\n <svg viewBox=\"0 0 256 256\">\n <path d=\"M112,40V64.69L61.66,14.34A8,8,0,0,0,50.34,25.66L100.69,76H72a8,8,0,0,0,0,16h48a8,8,0,0,0,8-8V36A8,8,0,0,0,112,40Zm131.06,70.61a8,8,0,0,0-8.72,1.73L184,162.69V136a8,8,0,0,0-16,0v48a8,8,0,0,0,8,8h48a8,8,0,0,0,0-16H195.31l50.35-50.34A8,8,0,0,0,243.06,110.61Z\"/>\n </svg>\n </div>\n </button>\n `;\n\n if (this.options.customStyles) {\n Object.assign(button.style, this.options.customStyles);\n }\n\n return button;\n }\n\n attachEvents() {\n const button = this.element.querySelector('.feedback-trigger-btn');\n const minimizeIcon = this.element.querySelector('.feedback-minimize-icon');\n const expandIcon = this.element.querySelector('.feedback-expand-icon');\n\n // Add click handlers directly to the icons\n minimizeIcon.addEventListener('click', (e) => {\n e.stopPropagation();\n e.preventDefault();\n this.minimize();\n });\n\n expandIcon.addEventListener('click', (e) => {\n e.stopPropagation();\n e.preventDefault();\n this.restore();\n });\n\n // Main button click handler\n button.addEventListener('click', (e) => {\n // Check if the click originated from an icon\n if (e.target.closest('.feedback-minimize-icon') || \n e.target.closest('.feedback-expand-icon')) {\n return; // Let the icon handlers deal with it\n }\n \n if (!this.isMinimized) {\n this.openPanel();\n }\n });\n\n button.addEventListener('mouseenter', () => {\n if (!this.state.isSubmitting && !this.isMinimized) {\n button.style.transform = 'translateY(-2px)';\n }\n });\n\n button.addEventListener('mouseleave', () => {\n if (!this.isMinimized) {\n button.style.transform = 'translateY(0)';\n }\n });\n }\n\n minimize() {\n this.isMinimized = true;\n this.element.classList.add('minimized');\n }\n\n restore() {\n this.isMinimized = false;\n this.element.classList.remove('minimized');\n }\n\n mount(container) {\n super.mount(container);\n }\n\n updateText(text) {\n const textEl = this.element?.querySelector('.feedback-text');\n if (textEl) {\n textEl.textContent = text;\n }\n }\n\n updatePosition(position) {\n this.options.position = position;\n if (this.element) {\n this.element.className = this.element.className.replace(\n /position-\\w+-\\w+/,\n `position-${position}`\n );\n }\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","/**\n * MessengerState - State management for the Messenger widget\n */\nexport class MessengerState {\n\tconstructor(options = {}) {\n\t\tthis.currentView = 'home'; // 'home', 'messages', 'chat', 'help', 'changelog'\n\t\tthis.isOpen = false;\n\t\tthis.unreadCount = 0;\n\t\tthis.activeConversationId = null;\n\n\t\t// Conversations\n\t\tthis.conversations = [];\n\t\tthis.messages = {}; // { conversationId: [messages] }\n\n\t\t// Help articles\n\t\tthis.helpArticles = [];\n\t\tthis.helpSearchQuery = '';\n\n\t\t// Changelog\n\t\tthis.homeChangelogItems = [];\n\t\tthis.changelogItems = [];\n\n\t\t// Team info\n\t\tthis.teamName = options.teamName || 'Support';\n\t\tthis.teamAvatars = options.teamAvatars || [];\n\t\tthis.welcomeMessage = options.welcomeMessage || 'How can we help?';\n\n\t\t// User info\n\t\tthis.userContext = options.userContext || null;\n\n\t\t// Feature flags\n\t\tthis.enableHelp = options.enableHelp !== false;\n\t\tthis.enableChangelog = options.enableChangelog !== false;\n\n\t\t// Listeners\n\t\tthis._listeners = new Set();\n\t}\n\n\t/**\n\t * Subscribe to state changes\n\t */\n\tsubscribe(callback) {\n\t\tthis._listeners.add(callback);\n\t\treturn () => this._listeners.delete(callback);\n\t}\n\n\t/**\n\t * Notify all listeners of state change\n\t */\n\t_notify(changeType, data) {\n\t\tthis._listeners.forEach((cb) => cb(changeType, data, this));\n\t}\n\n\t/**\n\t * Set current view\n\t */\n\tsetView(view) {\n\t\tconst previousView = this.currentView;\n\t\tthis.currentView = view;\n\t\tthis._notify('viewChange', { previousView, currentView: view });\n\t}\n\n\t/**\n\t * Toggle panel open/closed\n\t */\n\tsetOpen(isOpen) {\n\t\tthis.isOpen = isOpen;\n\t\tthis._notify('openChange', { isOpen });\n\t}\n\n\t/**\n\t * Set active conversation for chat view\n\t */\n\tsetActiveConversation(conversationId) {\n\t\tthis.activeConversationId = conversationId;\n\t\tthis._notify('conversationChange', { conversationId });\n\t}\n\n\t/**\n\t * Update conversations list\n\t */\n\tsetConversations(conversations) {\n\t\tthis.conversations = conversations;\n\t\tthis._updateUnreadCount();\n\t\tthis._notify('conversationsUpdate', { conversations });\n\t}\n\n\t/**\n\t * Add a new conversation\n\t */\n\taddConversation(conversation) {\n\t\tthis.conversations.unshift(conversation);\n\t\tthis._updateUnreadCount();\n\t\tthis._notify('conversationAdded', { conversation });\n\t}\n\n\t/**\n\t * Update messages for a conversation\n\t */\n\tsetMessages(conversationId, messages) {\n\t\tthis.messages[conversationId] = messages;\n\t\tthis._notify('messagesUpdate', { conversationId, messages });\n\t}\n\n\t/**\n\t * Add a message to a conversation\n\t */\n\taddMessage(conversationId, message) {\n\t\tif (!this.messages[conversationId]) {\n\t\t\tthis.messages[conversationId] = [];\n\t\t}\n\t\tthis.messages[conversationId].push(message);\n\n\t\t// Update conversation preview\n\t\tconst conv = this.conversations.find((c) => c.id === conversationId);\n\t\tif (conv) {\n\t\t\tconv.lastMessage = message.content;\n\t\t\tconv.lastMessageTime = message.timestamp;\n\t\t\tif (!message.isOwn) {\n\t\t\t\tconv.unread = (conv.unread || 0) + 1;\n\t\t\t\tthis._updateUnreadCount();\n\t\t\t}\n\t\t}\n\n\t\tthis._notify('messageAdded', { conversationId, message });\n\t}\n\n\t/**\n\t * Mark conversation as read\n\t */\n\tmarkAsRead(conversationId) {\n\t\tconst conv = this.conversations.find((c) => c.id === conversationId);\n\t\tif (conv && conv.unread > 0) {\n\t\t\tconv.unread = 0;\n\t\t\tthis._updateUnreadCount();\n\t\t\tthis._notify('conversationRead', { conversationId });\n\t\t}\n\t}\n\n\t/**\n\t * Update unread count\n\t */\n\t_updateUnreadCount() {\n\t\tthis.unreadCount = this.conversations.reduce(\n\t\t\t(sum, c) => sum + (c.unread || 0),\n\t\t\t0\n\t\t);\n\t\tthis._notify('unreadCountChange', { count: this.unreadCount });\n\t}\n\n\t/**\n\t * Set help articles\n\t */\n\tsetHelpArticles(articles) {\n\t\tthis.helpArticles = articles;\n\t\tthis._notify('helpArticlesUpdate', { articles });\n\t}\n\n\t/**\n\t * Set help search query\n\t */\n\tsetHelpSearchQuery(query) {\n\t\tthis.helpSearchQuery = query;\n\t\tthis._notify('helpSearchChange', { query });\n\t}\n\n\t/**\n\t * Set home changelog items\n\t */\n\tsetHomeChangelogItems(items) {\n\t\tthis.homeChangelogItems = items;\n\t\tthis._notify('homeChangelogUpdate', { items });\n\t}\n\n\t/**\n\t * Set changelog items\n\t */\n\tsetChangelogItems(items) {\n\t\tthis.changelogItems = items;\n\t\tthis._notify('changelogUpdate', { items });\n\t}\n\n\t/**\n\t * Get current conversation\n\t */\n\tgetActiveConversation() {\n\t\treturn this.conversations.find((c) => c.id === this.activeConversationId);\n\t}\n\n\t/**\n\t * Get messages for active conversation\n\t */\n\tgetActiveMessages() {\n\t\treturn this.messages[this.activeConversationId] || [];\n\t}\n\n\t/**\n\t * Get filtered help articles\n\t */\n\tgetFilteredHelpArticles() {\n\t\tif (!this.helpSearchQuery) {\n\t\t\treturn this.helpArticles;\n\t\t}\n\t\tconst query = this.helpSearchQuery.toLowerCase();\n\t\treturn this.helpArticles.filter(\n\t\t\t(article) =>\n\t\t\t\tarticle.title.toLowerCase().includes(query) ||\n\t\t\t\t(article.description &&\n\t\t\t\t\tarticle.description.toLowerCase().includes(query))\n\t\t);\n\t}\n\n\t/**\n\t * Reset state\n\t */\n\treset() {\n\t\tthis.currentView = 'home';\n\t\tthis.activeConversationId = null;\n\t\tthis.helpSearchQuery = '';\n\t\tthis._notify('reset', {});\n\t}\n}\n","/**\n * MessengerLauncher - Floating trigger button for messenger\n */\nexport class MessengerLauncher {\n\tconstructor(state, options = {}) {\n\t\tthis.state = state;\n\t\tthis.options = {\n\t\t\tposition: options.position || 'bottom-right',\n\t\t\tprimaryColor: options.primaryColor || '#1c1c1e',\n\t\t\t...options,\n\t\t};\n\t\tthis.element = null;\n\t\tthis._unsubscribe = null;\n\t}\n\n\trender() {\n\t\tthis.element = document.createElement('div');\n\t\tthis.element.className = `messenger-launcher messenger-launcher-${this.options.position}`;\n\n\t\tthis._updateContent();\n\t\tthis._attachEvents();\n\n\t\t// Subscribe to state changes\n\t\tthis._unsubscribe = this.state.subscribe((type, data) => {\n\t\t\tif (type === 'openChange') {\n\t\t\t\tthis._updateIcon();\n\t\t\t}\n\t\t\tif (type === 'unreadCountChange') {\n\t\t\t\tthis._updateBadge();\n\t\t\t}\n\t\t});\n\n\t\treturn this.element;\n\t}\n\n\t_updateContent() {\n\t\tconst badgeHtml =\n\t\t\tthis.state.unreadCount > 0\n\t\t\t\t? `<span class=\"messenger-launcher-badge\">${this.state.unreadCount > 9 ? '9+' : this.state.unreadCount}</span>`\n\t\t\t\t: '';\n\n\t\tthis.element.innerHTML = `\n\t\t\t<button class=\"messenger-launcher-btn\" aria-label=\"Open messenger\" style=\"background: ${this.options.primaryColor};\">\n\t\t\t\t<span class=\"messenger-launcher-icon messenger-launcher-icon-chat\">\n\t\t\t\t\t<i class=\"ph ph-chat-circle-dots\" style=\"font-size: 24px;\"></i>\n\t\t\t\t</span>\n\t\t\t\t<span class=\"messenger-launcher-icon messenger-launcher-icon-close\" style=\"display: none;\">\n\t\t\t\t\t<i class=\"ph ph-x\" style=\"font-size: 24px;\"></i>\n\t\t\t\t</span>\n\t\t\t\t${badgeHtml}\n\t\t\t</button>\n\t\t`;\n\t}\n\n\t_attachEvents() {\n\t\tthis.element\n\t\t\t.querySelector('.messenger-launcher-btn')\n\t\t\t.addEventListener('click', () => {\n\t\t\t\tthis.state.setOpen(!this.state.isOpen);\n\t\t\t});\n\t}\n\n\t_updateIcon() {\n\t\tconst chatIcon = this.element.querySelector(\n\t\t\t'.messenger-launcher-icon-chat'\n\t\t);\n\t\tconst closeIcon = this.element.querySelector(\n\t\t\t'.messenger-launcher-icon-close'\n\t\t);\n\n\t\tif (this.state.isOpen) {\n\t\t\tchatIcon.style.display = 'none';\n\t\t\tcloseIcon.style.display = 'flex';\n\t\t\tthis.element.classList.add('messenger-launcher-open');\n\t\t} else {\n\t\t\tchatIcon.style.display = 'flex';\n\t\t\tcloseIcon.style.display = 'none';\n\t\t\tthis.element.classList.remove('messenger-launcher-open');\n\t\t}\n\t}\n\n\t_updateBadge() {\n\t\tconst existingBadge = this.element.querySelector(\n\t\t\t'.messenger-launcher-badge'\n\t\t);\n\t\tif (existingBadge) {\n\t\t\texistingBadge.remove();\n\t\t}\n\n\t\tif (this.state.unreadCount > 0 && !this.state.isOpen) {\n\t\t\tconst badge = document.createElement('span');\n\t\t\tbadge.className = 'messenger-launcher-badge';\n\t\t\tbadge.textContent =\n\t\t\t\tthis.state.unreadCount > 9 ? '9+' : this.state.unreadCount;\n\t\t\tthis.element.querySelector('.messenger-launcher-btn').appendChild(badge);\n\t\t}\n\t}\n\n\tshow() {\n\t\tif (this.element) {\n\t\t\tthis.element.style.display = 'block';\n\t\t}\n\t}\n\n\thide() {\n\t\tif (this.element) {\n\t\t\tthis.element.style.display = 'none';\n\t\t}\n\t}\n\n\tdestroy() {\n\t\tif (this._unsubscribe) {\n\t\t\tthis._unsubscribe();\n\t\t}\n\t\tif (this.element && this.element.parentNode) {\n\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t}\n\t}\n}\n","/**\n * NavigationTabs - Bottom navigation for messenger\n */\nexport class NavigationTabs {\n\tconstructor(state, options = {}) {\n\t\tthis.state = state;\n\t\tthis.options = options;\n\t\tthis.element = null;\n\t\tthis._unsubscribe = null;\n\t}\n\n\trender() {\n\t\tthis.element = document.createElement('div');\n\t\tthis.element.className = 'messenger-nav';\n\n\t\tthis._updateContent();\n\t\tthis._attachEvents();\n\n\t\t// Subscribe to state changes\n\t\tthis._unsubscribe = this.state.subscribe((type) => {\n\t\t\tif (type === 'viewChange' || type === 'unreadCountChange') {\n\t\t\t\tthis._updateActiveTab();\n\t\t\t}\n\t\t});\n\n\t\treturn this.element;\n\t}\n\n\t_getTabs() {\n\t\tconst tabs = [\n\t\t\t{ id: 'home', label: 'Home', icon: this._getHomeIcon() },\n\t\t\t{\n\t\t\t\tid: 'messages',\n\t\t\t\tlabel: 'Messages',\n\t\t\t\ticon: this._getMessagesIcon(),\n\t\t\t\tbadge: this.state.unreadCount,\n\t\t\t},\n\t\t];\n\n\t\tif (this.state.enableHelp) {\n\t\t\ttabs.push({ id: 'help', label: 'Help', icon: this._getHelpIcon() });\n\t\t}\n\n\t\tif (this.state.enableChangelog) {\n\t\t\ttabs.push({\n\t\t\t\tid: 'changelog',\n\t\t\t\tlabel: 'Changelog',\n\t\t\t\ticon: this._getChangelogIcon(),\n\t\t\t});\n\t\t}\n\n\t\treturn tabs;\n\t}\n\n\t_updateContent() {\n\t\tconst tabs = this._getTabs();\n\t\tconst tabsHtml = tabs\n\t\t\t.map((tab) => {\n\t\t\t\tconst isActive = this.state.currentView === tab.id;\n\t\t\t\tconst badgeHtml =\n\t\t\t\t\ttab.badge && tab.badge > 0\n\t\t\t\t\t\t? `<span class=\"messenger-nav-badge\">${tab.badge > 9 ? '9+' : tab.badge}</span>`\n\t\t\t\t\t\t: '';\n\n\t\t\t\treturn `\n\t\t\t\t<button class=\"messenger-nav-tab ${isActive ? 'active' : ''}\" data-tab=\"${tab.id}\">\n\t\t\t\t\t<span class=\"messenger-nav-icon\">${tab.icon}</span>\n\t\t\t\t\t<span class=\"messenger-nav-label\">${tab.label}</span>\n\t\t\t\t\t${badgeHtml}\n\t\t\t\t</button>\n\t\t\t`;\n\t\t\t})\n\t\t\t.join('');\n\n\t\tthis.element.innerHTML = tabsHtml;\n\t}\n\n\t_attachEvents() {\n\t\tthis.element.addEventListener('click', (e) => {\n\t\t\tconst tab = e.target.closest('.messenger-nav-tab');\n\t\t\tif (tab) {\n\t\t\t\tconst tabId = tab.dataset.tab;\n\t\t\t\tthis.state.setView(tabId);\n\t\t\t}\n\t\t});\n\t}\n\n\t_updateActiveTab() {\n\t\tconst tabs = this.element.querySelectorAll('.messenger-nav-tab');\n\t\ttabs.forEach((tab) => {\n\t\t\tconst isActive = tab.dataset.tab === this.state.currentView;\n\t\t\ttab.classList.toggle('active', isActive);\n\n\t\t\t// Update badge if messages tab\n\t\t\tif (tab.dataset.tab === 'messages') {\n\t\t\t\tconst existingBadge = tab.querySelector('.messenger-nav-badge');\n\t\t\t\tif (existingBadge) existingBadge.remove();\n\n\t\t\t\tif (this.state.unreadCount > 0) {\n\t\t\t\t\tconst badge = document.createElement('span');\n\t\t\t\t\tbadge.className = 'messenger-nav-badge';\n\t\t\t\t\tbadge.textContent =\n\t\t\t\t\t\tthis.state.unreadCount > 9 ? '9+' : this.state.unreadCount;\n\t\t\t\t\ttab.appendChild(badge);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\t_getHomeIcon() {\n\t\treturn `<i class=\"ph-duotone ph-house-simple\" style=\"font-size: 24px;\"></i>`;\n\t}\n\n\t_getMessagesIcon() {\n\t\treturn `<i class=\"ph-duotone ph-chat\" style=\"font-size: 24px;\"></i>`;\n\t}\n\n\t_getHelpIcon() {\n\t\treturn `<i class=\"ph-duotone ph-question\" style=\"font-size: 24px;\"></i>`;\n\t}\n\n\t_getChangelogIcon() {\n\t\treturn `<i class=\"ph-duotone ph-megaphone\" style=\"font-size: 24px;\"></i>`;\n\t}\n\n\tdestroy() {\n\t\tif (this._unsubscribe) {\n\t\t\tthis._unsubscribe();\n\t\t}\n\t\tif (this.element && this.element.parentNode) {\n\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t}\n\t}\n}\n","/**\n * MessengerPanel - Main panel container for messenger\n */\nimport { NavigationTabs } from './NavigationTabs.js';\n\nexport class MessengerPanel {\n\tconstructor(state, options = {}) {\n\t\tthis.state = state;\n\t\tthis.options = {\n\t\t\tposition: options.position || 'bottom-right',\n\t\t\ttheme: options.theme || 'dark',\n\t\t\t...options,\n\t\t};\n\t\tthis.element = null;\n\t\tthis.navigationTabs = null;\n\t\tthis.currentViewComponent = null;\n\t\tthis.viewRegistry = {};\n\t\tthis._unsubscribe = null;\n\t}\n\n\t/**\n\t * Register view components\n\t */\n\tregisterView(name, ViewClass) {\n\t\tthis.viewRegistry[name] = ViewClass;\n\t}\n\n\trender() {\n\t\tthis.element = document.createElement('div');\n\t\tthis.element.className = `messenger-panel messenger-panel-${this.options.position} theme-${this.options.theme}`;\n\n\t\tthis.element.innerHTML = `\n\t\t\t<div class=\"messenger-panel-content\">\n\t\t\t\t<div class=\"messenger-panel-views\"></div>\n\t\t\t\t<div class=\"messenger-panel-nav\"></div>\n\t\t\t</div>\n\t\t`;\n\n\t\t// Render navigation tabs\n\t\tthis.navigationTabs = new NavigationTabs(this.state, this.options);\n\t\tconst navContainer = this.element.querySelector('.messenger-panel-nav');\n\t\tnavContainer.appendChild(this.navigationTabs.render());\n\n\t\t// Render initial view\n\t\tthis._renderCurrentView();\n\n\t\t// Subscribe to state changes\n\t\tthis._unsubscribe = this.state.subscribe((type) => {\n\t\t\tif (type === 'viewChange') {\n\t\t\t\tthis._renderCurrentView();\n\t\t\t}\n\t\t});\n\n\t\treturn this.element;\n\t}\n\n\t_renderCurrentView() {\n\t\tconst viewsContainer = this.element.querySelector('.messenger-panel-views');\n\n\t\t// Destroy current view if exists\n\t\tif (this.currentViewComponent && this.currentViewComponent.destroy) {\n\t\t\tthis.currentViewComponent.destroy();\n\t\t}\n\n\t\t// Clear container\n\t\tviewsContainer.innerHTML = '';\n\n\t\t// Get view class\n\t\tconst ViewClass = this.viewRegistry[this.state.currentView];\n\t\tif (ViewClass) {\n\t\t\tthis.currentViewComponent = new ViewClass(this.state, this.options);\n\t\t\tviewsContainer.appendChild(this.currentViewComponent.render());\n\t\t} else {\n\t\t\tviewsContainer.innerHTML = `<div class=\"messenger-view-placeholder\">View not found: ${this.state.currentView}</div>`;\n\t\t}\n\t}\n\n\t/**\n\t * Show the panel with animation\n\t */\n\tshow() {\n\t\tif (this.element) {\n\t\t\tthis.element.style.display = 'block';\n\t\t\t// Trigger animation\n\t\t\trequestAnimationFrame(() => {\n\t\t\t\tthis.element.classList.add('open');\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Hide the panel with animation\n\t */\n\thide() {\n\t\tif (this.element) {\n\t\t\tthis.element.classList.remove('open');\n\t\t\t// Wait for animation to complete\n\t\t\tsetTimeout(() => {\n\t\t\t\tif (this.element) {\n\t\t\t\t\tthis.element.style.display = 'none';\n\t\t\t\t}\n\t\t\t}, 300);\n\t\t}\n\t}\n\n\t/**\n\t * Set panel header content (used by views)\n\t */\n\tsetHeader(headerContent) {\n\t\tconst header = this.element.querySelector('.messenger-panel-header');\n\t\tif (header) {\n\t\t\theader.innerHTML = headerContent;\n\t\t}\n\t}\n\n\tdestroy() {\n\t\tif (this._unsubscribe) {\n\t\t\tthis._unsubscribe();\n\t\t}\n\t\tif (this.navigationTabs) {\n\t\t\tthis.navigationTabs.destroy();\n\t\t}\n\t\tif (this.currentViewComponent && this.currentViewComponent.destroy) {\n\t\t\tthis.currentViewComponent.destroy();\n\t\t}\n\t\tif (this.element && this.element.parentNode) {\n\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t}\n\t}\n}\n","/**\n * ChangelogView - Changelog and announcements\n */\nexport class ChangelogView {\n\tconstructor(state, options = {}) {\n\t\tthis.state = state;\n\t\tthis.options = options;\n\t\tthis.element = null;\n\t\tthis._unsubscribe = null;\n\t}\n\n\trender() {\n\t\tthis.element = document.createElement('div');\n\t\tthis.element.className = 'messenger-view messenger-changelog-view';\n\n\t\tthis._updateContent();\n\n\t\t// Subscribe to state changes\n\t\tthis._unsubscribe = this.state.subscribe((type) => {\n\t\t\tif (type === 'changelogUpdate') {\n\t\t\t\tthis._updateChangelogList();\n\t\t\t}\n\t\t});\n\n\t\treturn this.element;\n\t}\n\n\t_updateContent() {\n\t\tconst avatarsHtml = this._renderTeamAvatars();\n\n\t\tthis.element.innerHTML = `\n\t\t\t<div class=\"messenger-changelog-header\">\n\t\t\t\t<h2>Changelog</h2>\n\t\t\t\t<button class=\"messenger-close-btn\" aria-label=\"Close\">\n\t\t\t\t\t<i class=\"ph ph-x\" style=\"font-size: 20px;\"></i>\n\t\t\t\t</button>\n\t\t\t</div>\n\n\t\t\t<div class=\"messenger-changelog-subheader\">\n\t\t\t\t<span class=\"messenger-changelog-latest\">Latest</span>\n\t\t\t\t<div class=\"messenger-changelog-team\">\n\t\t\t\t\t<span>From ${this.state.teamName}</span>\n\t\t\t\t\t${avatarsHtml}\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div class=\"messenger-changelog-body\">\n\t\t\t\t<div class=\"messenger-changelog-list\"></div>\n\t\t\t</div>\n\t\t`;\n\n\t\tthis._updateChangelogList();\n\t\tthis._attachEvents();\n\t}\n\n\t_updateChangelogList() {\n\t\tconst changelogContainer = this.element.querySelector(\n\t\t\t'.messenger-changelog-list'\n\t\t);\n\t\tconst changelogItems = this.state.changelogItems;\n\n\t\tif (changelogItems.length === 0) {\n\t\t\tchangelogContainer.innerHTML = this._renderEmptyState();\n\t\t\treturn;\n\t\t}\n\n\t\tchangelogContainer.innerHTML = changelogItems\n\t\t\t.map((item) => this._renderChangelogCard(item))\n\t\t\t.join('');\n\n\t\t// Attach click events\n\t\tthis._attachChangelogEvents();\n\t}\n\n\t_renderChangelogCard(item) {\n\t\tconst tagsHtml =\n\t\t\titem.tags && item.tags.length > 0\n\t\t\t\t? `<div class=\"messenger-changelog-tags\">\n\t\t\t\t${item.tags.map((tag) => `<span class=\"messenger-changelog-tag\">${tag}</span>`).join('')}\n\t\t\t</div>`\n\t\t\t\t: '';\n\n\t\tconst dateStr = this._formatDate(item.publishedAt || item.date);\n\n\t\treturn `\n\t\t\t<div class=\"messenger-changelog-card\" data-changelog-id=\"${item.id}\">\n\t\t\t\t${\n\t\t\t\t\titem.coverImage\n\t\t\t\t\t\t? `\n\t\t\t\t\t<div class=\"messenger-changelog-cover\">\n\t\t\t\t\t\t<img src=\"${item.coverImage}\" alt=\"${item.title}\" onerror=\"this.style.display='none';\" />\n\t\t\t\t\t</div>\n\t\t\t\t`\n\t\t\t\t\t\t: ''\n\t\t\t\t}\n\t\t\t\t<div class=\"messenger-changelog-content\">\n\t\t\t\t\t${tagsHtml}\n\t\t\t\t\t<h3 class=\"messenger-changelog-title\">${item.title}</h3>\n\t\t\t\t\t${item.description ? `<p class=\"messenger-changelog-description\">${this._truncateText(item.description, 100)}</p>` : ''}\n\t\t\t\t\t<div class=\"messenger-changelog-meta\">\n\t\t\t\t\t\t<span class=\"messenger-changelog-date\">${dateStr}</span>\n\t\t\t\t\t\t<i class=\"ph ph-caret-right messenger-changelog-arrow\" style=\"font-size: 16px;\"></i>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t`;\n\t}\n\n\t_renderTeamAvatars() {\n\t\tconst avatars = this.state.teamAvatars;\n\t\tif (!avatars || avatars.length === 0) {\n\t\t\treturn `\n\t\t\t\t<div class=\"messenger-avatar-stack messenger-avatar-stack-tiny\">\n\t\t\t\t\t<div class=\"messenger-avatar messenger-avatar-tiny\" style=\"background: #5856d6;\">S</div>\n\t\t\t\t</div>\n\t\t\t`;\n\t\t}\n\n\t\tconst colors = ['#5856d6', '#007aff', '#34c759'];\n\t\tconst avatarItems = avatars\n\t\t\t.slice(0, 2)\n\t\t\t.map((avatar, i) => {\n\t\t\t\tif (typeof avatar === 'string' && avatar.startsWith('http')) {\n\t\t\t\t\treturn `<img class=\"messenger-avatar messenger-avatar-tiny\" src=\"${avatar}\" alt=\"Team member\" style=\"z-index: ${2 - i};\" />`;\n\t\t\t\t}\n\t\t\t\treturn `<div class=\"messenger-avatar messenger-avatar-tiny\" style=\"background: ${colors[i % colors.length]}; z-index: ${2 - i};\">${avatar.charAt(0).toUpperCase()}</div>`;\n\t\t\t})\n\t\t\t.join('');\n\n\t\treturn `<div class=\"messenger-avatar-stack messenger-avatar-stack-tiny\">${avatarItems}</div>`;\n\t}\n\n\t_renderEmptyState() {\n\t\treturn `\n\t\t\t<div class=\"messenger-changelog-empty\">\n\t\t\t\t<div class=\"messenger-changelog-empty-icon\">\n\t\t\t\t\t<i class=\"ph ph-megaphone\" style=\"font-size: 48px;\"></i>\n\t\t\t\t</div>\n\t\t\t\t<h3>No changelog yet</h3>\n\t\t\t\t<p>Check back later for updates</p>\n\t\t\t</div>\n\t\t`;\n\t}\n\n\t_formatDate(dateString) {\n\t\tif (!dateString) return '';\n\t\tconst date = new Date(dateString);\n\t\treturn date.toLocaleDateString('en-US', {\n\t\t\tmonth: 'short',\n\t\t\tday: 'numeric',\n\t\t\tyear: 'numeric',\n\t\t});\n\t}\n\n\t_truncateText(text, maxLength) {\n\t\tif (!text) return '';\n\t\tif (text.length <= maxLength) return text;\n\t\treturn text.substring(0, maxLength).trim() + '...';\n\t}\n\n\t_attachEvents() {\n\t\t// Close button\n\t\tthis.element\n\t\t\t.querySelector('.messenger-close-btn')\n\t\t\t.addEventListener('click', () => {\n\t\t\t\tthis.state.setOpen(false);\n\t\t\t});\n\n\t\tthis._attachChangelogEvents();\n\t}\n\n\t_attachChangelogEvents() {\n\t\tthis.element\n\t\t\t.querySelectorAll('.messenger-changelog-card')\n\t\t\t.forEach((card) => {\n\t\t\t\tcard.addEventListener('click', () => {\n\t\t\t\t\tconst changelogId = card.dataset.changelogId;\n\t\t\t\t\tconst changelogItem = this.state.changelogItems.find(\n\t\t\t\t\t\t(n) => n.id === changelogId\n\t\t\t\t\t);\n\t\t\t\t\tif (changelogItem && changelogItem.url) {\n\t\t\t\t\t\twindow.open(changelogItem.url, '_blank');\n\t\t\t\t\t} else if (this.options.onChangelogClick) {\n\t\t\t\t\t\tthis.options.onChangelogClick(changelogItem);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\t}\n\n\tdestroy() {\n\t\tif (this._unsubscribe) {\n\t\t\tthis._unsubscribe();\n\t\t}\n\t\tif (this.element && this.element.parentNode) {\n\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t}\n\t}\n}\n","/**\n * ChatView - Individual conversation chat\n */\nexport class ChatView {\n\tconstructor(state, options = {}) {\n\t\tthis.state = state;\n\t\tthis.options = options;\n\t\tthis.element = null;\n\t\tthis._unsubscribe = null;\n\t}\n\n\trender() {\n\t\tthis.element = document.createElement('div');\n\t\tthis.element.className = 'messenger-view messenger-chat-view';\n\n\t\tthis._updateContent();\n\n\t\t// Subscribe to state changes\n\t\tthis._unsubscribe = this.state.subscribe((type, data) => {\n\t\t\tif (\n\t\t\t\ttype === 'messageAdded' &&\n\t\t\t\tdata.conversationId === this.state.activeConversationId\n\t\t\t) {\n\t\t\t\tthis._appendMessage(data.message);\n\t\t\t\tthis._scrollToBottom();\n\t\t\t}\n\t\t});\n\n\t\treturn this.element;\n\t}\n\n\t_updateContent() {\n\t\tconst conversation = this.state.getActiveConversation();\n\t\tconst messages = this.state.getActiveMessages();\n\n\t\tconst messagesHtml =\n\t\t\tmessages.length === 0\n\t\t\t\t? this._renderEmptyState()\n\t\t\t\t: messages.map((msg) => this._renderMessage(msg)).join('');\n\n\t\tconst avatarHtml = this._renderConversationAvatar(conversation);\n\n\t\tthis.element.innerHTML = `\n\t\t\t<div class=\"messenger-chat-header\">\n\t\t\t\t<button class=\"messenger-back-btn\" aria-label=\"Back\">\n\t\t\t\t\t<i class=\"ph ph-caret-left\" style=\"font-size: 20px;\"></i>\n\t\t\t\t</button>\n\t\t\t\t<div class=\"messenger-chat-header-info\">\n\t\t\t\t\t${avatarHtml}\n\t\t\t\t\t<span class=\"messenger-chat-title\">${conversation?.title || 'Chat with team'}</span>\n\t\t\t\t</div>\n\t\t\t\t<button class=\"messenger-close-btn\" aria-label=\"Close\">\n\t\t\t\t\t<i class=\"ph ph-x\" style=\"font-size: 20px;\"></i>\n\t\t\t\t</button>\n\t\t\t</div>\n\n\t\t\t<div class=\"messenger-chat-messages\">\n\t\t\t\t${messagesHtml}\n\t\t\t</div>\n\n\t\t\t<div class=\"messenger-chat-compose\">\n\t\t\t\t<div class=\"messenger-compose-input-wrapper\">\n\t\t\t\t\t<textarea class=\"messenger-compose-input\" placeholder=\"Write a message...\" rows=\"1\"></textarea>\n\t\t\t\t</div>\n\t\t\t\t<button class=\"messenger-compose-send\" aria-label=\"Send\" disabled>\n\t\t\t\t\t<i class=\"ph ph-paper-plane-tilt\" style=\"font-size: 20px;\"></i>\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t`;\n\n\t\tthis._attachEvents();\n\t\tthis._scrollToBottom();\n\t}\n\n\t_renderEmptyState() {\n\t\tconst avatarHtml = this._renderTeamAvatars();\n\t\treturn `\n\t\t\t<div class=\"messenger-chat-empty\">\n\t\t\t\t<div class=\"messenger-chat-empty-avatars\">${avatarHtml}</div>\n\t\t\t\t<h3>Start the conversation</h3>\n\t\t\t\t<p>Send us a message and we'll get back to you as soon as possible.</p>\n\t\t\t</div>\n\t\t`;\n\t}\n\n\t_renderMessage(message) {\n\t\tconst isOwn = message.isOwn;\n\t\tconst messageClass = isOwn\n\t\t\t? 'messenger-message-own'\n\t\t\t: 'messenger-message-received';\n\t\tconst timeStr = this._formatMessageTime(message.timestamp);\n\n\t\tif (isOwn) {\n\t\t\treturn `\n\t\t\t\t<div class=\"messenger-message ${messageClass}\">\n\t\t\t\t\t<div class=\"messenger-message-bubble\">\n\t\t\t\t\t\t<div class=\"messenger-message-content\">${this._formatMessageContent(message.content)}</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"messenger-message-time\">${timeStr}</div>\n\t\t\t\t</div>\n\t\t\t`;\n\t\t}\n\n\t\tconst avatarHtml = this._renderSenderAvatar(message.sender);\n\t\treturn `\n\t\t\t<div class=\"messenger-message ${messageClass}\">\n\t\t\t\t<div class=\"messenger-message-avatar\">${avatarHtml}</div>\n\t\t\t\t<div class=\"messenger-message-wrapper\">\n\t\t\t\t\t<div class=\"messenger-message-sender\">${message.sender?.name || 'Support'}</div>\n\t\t\t\t\t<div class=\"messenger-message-bubble\">\n\t\t\t\t\t\t<div class=\"messenger-message-content\">${this._formatMessageContent(message.content)}</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"messenger-message-time\">${timeStr}</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t`;\n\t}\n\n\t_renderSenderAvatar(sender) {\n\t\tif (sender?.avatarUrl) {\n\t\t\treturn `<img class=\"messenger-avatar messenger-avatar-small\" src=\"${sender.avatarUrl}\" alt=\"${sender.name}\" />`;\n\t\t}\n\t\tconst initial = (sender?.name || 'S').charAt(0).toUpperCase();\n\t\treturn `<div class=\"messenger-avatar messenger-avatar-small\" style=\"background: #5856d6;\">${initial}</div>`;\n\t}\n\n\t_renderConversationAvatar(conversation) {\n\t\tif (!conversation?.participants?.length) {\n\t\t\treturn `<div class=\"messenger-avatar messenger-avatar-small\" style=\"background: #5856d6;\">S</div>`;\n\t\t}\n\t\tconst p = conversation.participants[0];\n\t\tif (p.avatarUrl) {\n\t\t\treturn `<img class=\"messenger-avatar messenger-avatar-small\" src=\"${p.avatarUrl}\" alt=\"${p.name}\" />`;\n\t\t}\n\t\treturn `<div class=\"messenger-avatar messenger-avatar-small\" style=\"background: #5856d6;\">${(p.name || 'S').charAt(0).toUpperCase()}</div>`;\n\t}\n\n\t_renderTeamAvatars() {\n\t\tconst avatars = this.state.teamAvatars;\n\t\tif (!avatars || avatars.length === 0) {\n\t\t\treturn `\n\t\t\t\t<div class=\"messenger-avatar-stack\">\n\t\t\t\t\t<div class=\"messenger-avatar\" style=\"background: #5856d6;\">S</div>\n\t\t\t\t\t<div class=\"messenger-avatar\" style=\"background: #007aff;\">T</div>\n\t\t\t\t</div>\n\t\t\t`;\n\t\t}\n\n\t\tconst colors = ['#5856d6', '#007aff', '#34c759', '#ff9500', '#ff3b30'];\n\t\tconst avatarItems = avatars\n\t\t\t.slice(0, 3)\n\t\t\t.map((avatar, i) => {\n\t\t\t\tif (typeof avatar === 'string' && avatar.startsWith('http')) {\n\t\t\t\t\treturn `<img class=\"messenger-avatar\" src=\"${avatar}\" alt=\"Team member\" style=\"z-index: ${3 - i};\" />`;\n\t\t\t\t}\n\t\t\t\treturn `<div class=\"messenger-avatar\" style=\"background: ${colors[i % colors.length]}; z-index: ${3 - i};\">${avatar.charAt(0).toUpperCase()}</div>`;\n\t\t\t})\n\t\t\t.join('');\n\n\t\treturn `<div class=\"messenger-avatar-stack\">${avatarItems}</div>`;\n\t}\n\n\t_formatMessageTime(timestamp) {\n\t\tif (!timestamp) return '';\n\t\tconst date = new Date(timestamp);\n\t\treturn date.toLocaleTimeString('en-US', {\n\t\t\thour: 'numeric',\n\t\t\tminute: '2-digit',\n\t\t\thour12: true,\n\t\t});\n\t}\n\n\t_formatMessageContent(content) {\n\t\tif (!content) return '';\n\t\t// Basic HTML escaping and line breaks\n\t\treturn content\n\t\t\t.replace(/&/g, '&amp;')\n\t\t\t.replace(/</g, '&lt;')\n\t\t\t.replace(/>/g, '&gt;')\n\t\t\t.replace(/\\n/g, '<br>');\n\t}\n\n\t_appendMessage(message) {\n\t\tconst messagesContainer = this.element.querySelector(\n\t\t\t'.messenger-chat-messages'\n\t\t);\n\t\tconst emptyState = messagesContainer.querySelector('.messenger-chat-empty');\n\t\tif (emptyState) {\n\t\t\temptyState.remove();\n\t\t}\n\n\t\tconst messageHtml = this._renderMessage(message);\n\t\tconst tempDiv = document.createElement('div');\n\t\ttempDiv.innerHTML = messageHtml;\n\t\tmessagesContainer.appendChild(tempDiv.firstElementChild);\n\t}\n\n\t_scrollToBottom() {\n\t\tconst messagesContainer = this.element.querySelector(\n\t\t\t'.messenger-chat-messages'\n\t\t);\n\t\tif (messagesContainer) {\n\t\t\tsetTimeout(() => {\n\t\t\t\tmessagesContainer.scrollTop = messagesContainer.scrollHeight;\n\t\t\t}, 50);\n\t\t}\n\t}\n\n\t_attachEvents() {\n\t\t// Back button\n\t\tthis.element\n\t\t\t.querySelector('.messenger-back-btn')\n\t\t\t.addEventListener('click', () => {\n\t\t\t\tthis.state.setView('messages');\n\t\t\t});\n\n\t\t// Close button\n\t\tthis.element\n\t\t\t.querySelector('.messenger-close-btn')\n\t\t\t.addEventListener('click', () => {\n\t\t\t\tthis.state.setOpen(false);\n\t\t\t});\n\n\t\t// Compose input\n\t\tconst input = this.element.querySelector('.messenger-compose-input');\n\t\tconst sendBtn = this.element.querySelector('.messenger-compose-send');\n\n\t\tinput.addEventListener('input', () => {\n\t\t\t// Auto-resize textarea\n\t\t\tinput.style.height = 'auto';\n\t\t\tinput.style.height = Math.min(input.scrollHeight, 120) + 'px';\n\n\t\t\t// Enable/disable send button\n\t\t\tsendBtn.disabled = !input.value.trim();\n\t\t});\n\n\t\tinput.addEventListener('keydown', (e) => {\n\t\t\tif (e.key === 'Enter' && !e.shiftKey) {\n\t\t\t\te.preventDefault();\n\t\t\t\tthis._sendMessage();\n\t\t\t}\n\t\t});\n\n\t\tsendBtn.addEventListener('click', () => {\n\t\t\tthis._sendMessage();\n\t\t});\n\t}\n\n\t_sendMessage() {\n\t\tconst input = this.element.querySelector('.messenger-compose-input');\n\t\tconst content = input.value.trim();\n\n\t\tif (!content) return;\n\n\t\t// Add message to state\n\t\tconst message = {\n\t\t\tid: 'msg_' + Date.now(),\n\t\t\tcontent: content,\n\t\t\tisOwn: true,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t};\n\n\t\tthis.state.addMessage(this.state.activeConversationId, message);\n\n\t\t// Clear input\n\t\tinput.value = '';\n\t\tinput.style.height = 'auto';\n\t\tthis.element.querySelector('.messenger-compose-send').disabled = true;\n\n\t\t// Emit event for API integration\n\t\tif (this.options.onSendMessage) {\n\t\t\tthis.options.onSendMessage(this.state.activeConversationId, message);\n\t\t}\n\t}\n\n\tdestroy() {\n\t\tif (this._unsubscribe) {\n\t\t\tthis._unsubscribe();\n\t\t}\n\t\tif (this.element && this.element.parentNode) {\n\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t}\n\t}\n}\n","/**\n * ConversationsView - Message thread list\n */\nexport class ConversationsView {\n\tconstructor(state, options = {}) {\n\t\tthis.state = state;\n\t\tthis.options = options;\n\t\tthis.element = null;\n\t\tthis._unsubscribe = null;\n\t}\n\n\trender() {\n\t\tthis.element = document.createElement('div');\n\t\tthis.element.className = 'messenger-view messenger-conversations-view';\n\n\t\tthis._updateContent();\n\t\tthis._attachEvents();\n\n\t\t// Subscribe to state changes\n\t\tthis._unsubscribe = this.state.subscribe((type) => {\n\t\t\tif (\n\t\t\t\ttype === 'conversationsUpdate' ||\n\t\t\t\ttype === 'conversationAdded' ||\n\t\t\t\ttype === 'conversationRead'\n\t\t\t) {\n\t\t\t\tthis._updateContent();\n\t\t\t}\n\t\t});\n\n\t\treturn this.element;\n\t}\n\n\t_updateContent() {\n\t\tconst conversations = this.state.conversations;\n\t\tconst avatarsHtml = this._renderAvatarStack();\n\n\t\tlet conversationsHtml;\n\t\tif (conversations.length === 0) {\n\t\t\tconversationsHtml = `\n\t\t\t\t<div class=\"messenger-conversations-empty\">\n\t\t\t\t\t<div class=\"messenger-conversations-empty-icon\">\n\t\t\t\t\t\t<i class=\"ph ph-chat\" style=\"font-size: 48px;\"></i>\n\t\t\t\t\t</div>\n\t\t\t\t\t<h3>No conversations yet</h3>\n\t\t\t\t\t<p>Start a new conversation with our team</p>\n\t\t\t\t</div>\n\t\t\t`;\n\t\t} else {\n\t\t\tconversationsHtml = `\n\t\t\t\t<div class=\"messenger-conversations-list\">\n\t\t\t\t\t${conversations.map((conv) => this._renderConversationItem(conv)).join('')}\n\t\t\t\t</div>\n\t\t\t`;\n\t\t}\n\n\t\tthis.element.innerHTML = `\n\t\t\t<div class=\"messenger-conversations-header\">\n\t\t\t\t<h2>Messages</h2>\n\t\t\t\t<button class=\"messenger-close-btn\" aria-label=\"Close\">\n\t\t\t\t\t<i class=\"ph ph-x\" style=\"font-size: 20px;\"></i>\n\t\t\t\t</button>\n\t\t\t</div>\n\n\t\t\t<div class=\"messenger-conversations-body\">\n\t\t\t\t${conversationsHtml}\n\t\t\t</div>\n\n\t\t\t<div class=\"messenger-conversations-footer\">\n\t\t\t\t<button class=\"messenger-new-message-btn\">\n\t\t\t\t\t<div class=\"messenger-new-message-avatars\">${avatarsHtml}</div>\n\t\t\t\t\t<span>Send us a message</span>\n\t\t\t\t\t<i class=\"ph ph-arrow-right\" style=\"font-size: 16px;\"></i>\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t`;\n\n\t\tthis._attachEvents();\n\t}\n\n\t_renderConversationItem(conversation) {\n\t\tconst unreadClass = conversation.unread > 0 ? 'unread' : '';\n\t\tconst timeAgo = this._formatTimeAgo(conversation.lastMessageTime);\n\t\tconst avatarsHtml = this._renderConversationAvatars(\n\t\t\tconversation.participants\n\t\t);\n\n\t\treturn `\n\t\t\t<div class=\"messenger-conversation-item ${unreadClass}\" data-conversation-id=\"${conversation.id}\">\n\t\t\t\t<div class=\"messenger-conversation-avatars\">\n\t\t\t\t\t${avatarsHtml}\n\t\t\t\t</div>\n\t\t\t\t<div class=\"messenger-conversation-content\">\n\t\t\t\t\t<div class=\"messenger-conversation-header\">\n\t\t\t\t\t\t<span class=\"messenger-conversation-title\">${conversation.title || 'Chat with team'}</span>\n\t\t\t\t\t\t<span class=\"messenger-conversation-time\">${timeAgo}</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"messenger-conversation-preview\">\n\t\t\t\t\t\t${conversation.unread > 0 ? '<span class=\"messenger-unread-dot\"></span>' : ''}\n\t\t\t\t\t\t<span class=\"messenger-conversation-message\">${this._truncateMessage(conversation.lastMessage)}</span>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t`;\n\t}\n\n\t_renderConversationAvatars(participants) {\n\t\tif (!participants || participants.length === 0) {\n\t\t\treturn `<div class=\"messenger-avatar messenger-avatar-medium\" style=\"background: #5856d6;\">S</div>`;\n\t\t}\n\n\t\tconst p = participants[0];\n\t\tif (p.avatarUrl) {\n\t\t\treturn `<img class=\"messenger-avatar messenger-avatar-medium\" src=\"${p.avatarUrl}\" alt=\"${p.name}\" />`;\n\t\t}\n\t\treturn `<div class=\"messenger-avatar messenger-avatar-medium\" style=\"background: ${this._getAvatarColor(0)};\">${(p.name || 'S').charAt(0).toUpperCase()}</div>`;\n\t}\n\n\t_renderAvatarStack() {\n\t\tconst avatars = this.state.teamAvatars;\n\t\tif (!avatars || avatars.length === 0) {\n\t\t\treturn `\n\t\t\t\t<div class=\"messenger-avatar-stack messenger-avatar-stack-small\">\n\t\t\t\t\t<div class=\"messenger-avatar messenger-avatar-small\" style=\"background: #5856d6;\">S</div>\n\t\t\t\t\t<div class=\"messenger-avatar messenger-avatar-small\" style=\"background: #007aff;\">T</div>\n\t\t\t\t</div>\n\t\t\t`;\n\t\t}\n\n\t\tconst avatarItems = avatars\n\t\t\t.slice(0, 2)\n\t\t\t.map((avatar, i) => {\n\t\t\t\tif (typeof avatar === 'string' && avatar.startsWith('http')) {\n\t\t\t\t\treturn `<img class=\"messenger-avatar messenger-avatar-small\" src=\"${avatar}\" alt=\"Team member\" style=\"z-index: ${2 - i};\" />`;\n\t\t\t\t}\n\t\t\t\treturn `<div class=\"messenger-avatar messenger-avatar-small\" style=\"background: ${this._getAvatarColor(i)}; z-index: ${2 - i};\">${avatar.charAt(0).toUpperCase()}</div>`;\n\t\t\t})\n\t\t\t.join('');\n\n\t\treturn `<div class=\"messenger-avatar-stack messenger-avatar-stack-small\">${avatarItems}</div>`;\n\t}\n\n\t_getAvatarColor(index) {\n\t\tconst colors = ['#5856d6', '#007aff', '#34c759', '#ff9500', '#ff3b30'];\n\t\treturn colors[index % colors.length];\n\t}\n\n\t_formatTimeAgo(timestamp) {\n\t\tif (!timestamp) return '';\n\t\tconst date = new Date(timestamp);\n\t\tconst now = new Date();\n\t\tconst diffMs = now - date;\n\t\tconst diffMins = Math.floor(diffMs / 60000);\n\t\tconst diffHours = Math.floor(diffMs / 3600000);\n\t\tconst diffDays = Math.floor(diffMs / 86400000);\n\n\t\tif (diffMins < 1) return 'now';\n\t\tif (diffMins < 60) return `${diffMins}m`;\n\t\tif (diffHours < 24) return `${diffHours}h`;\n\t\tif (diffDays < 7) return `${diffDays}d`;\n\t\treturn date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });\n\t}\n\n\t_truncateMessage(message) {\n\t\tif (!message) return 'No messages yet';\n\t\tconst maxLength = 50;\n\t\tif (message.length <= maxLength) return message;\n\t\treturn message.substring(0, maxLength) + '...';\n\t}\n\n\t_attachEvents() {\n\t\t// Close button\n\t\tconst closeBtn = this.element.querySelector('.messenger-close-btn');\n\t\tif (closeBtn) {\n\t\t\tcloseBtn.addEventListener('click', () => {\n\t\t\t\tthis.state.setOpen(false);\n\t\t\t});\n\t\t}\n\n\t\t// Conversation items\n\t\tthis.element\n\t\t\t.querySelectorAll('.messenger-conversation-item')\n\t\t\t.forEach((item) => {\n\t\t\t\titem.addEventListener('click', () => {\n\t\t\t\t\tconst convId = item.dataset.conversationId;\n\t\t\t\t\tthis.state.setActiveConversation(convId);\n\t\t\t\t\tthis.state.markAsRead(convId);\n\t\t\t\t\tthis.state.setView('chat');\n\t\t\t\t});\n\t\t\t});\n\n\t\t// New message button\n\t\tconst newMsgBtn = this.element.querySelector('.messenger-new-message-btn');\n\t\tif (newMsgBtn) {\n\t\t\tnewMsgBtn.addEventListener('click', () => {\n\t\t\t\tthis._startNewConversation();\n\t\t\t});\n\t\t}\n\t}\n\n\t_startNewConversation() {\n\t\t// Create a new conversation and navigate to chat\n\t\tconst newConv = {\n\t\t\tid: 'conv_' + Date.now(),\n\t\t\ttitle: 'New conversation',\n\t\t\tparticipants: [],\n\t\t\tlastMessage: null,\n\t\t\tlastMessageTime: new Date().toISOString(),\n\t\t\tunread: 0,\n\t\t};\n\t\tthis.state.addConversation(newConv);\n\t\tthis.state.setActiveConversation(newConv.id);\n\t\tthis.state.setView('chat');\n\t}\n\n\tdestroy() {\n\t\tif (this._unsubscribe) {\n\t\t\tthis._unsubscribe();\n\t\t}\n\t\tif (this.element && this.element.parentNode) {\n\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t}\n\t}\n}\n","/**\n * HelpView - Help collections browse with Intercom-style design\n */\nexport class HelpView {\n\tconstructor(state, options = {}) {\n\t\tthis.state = state;\n\t\tthis.options = options;\n\t\tthis.element = null;\n\t\tthis._unsubscribe = null;\n\t}\n\n\trender() {\n\t\tthis.element = document.createElement('div');\n\t\tthis.element.className = 'messenger-view messenger-help-view';\n\n\t\tthis._updateContent();\n\n\t\t// Subscribe to state changes\n\t\tthis._unsubscribe = this.state.subscribe((type) => {\n\t\t\tif (type === 'helpArticlesUpdate' || type === 'helpSearchChange') {\n\t\t\t\tthis._updateCollectionsList();\n\t\t\t}\n\t\t});\n\n\t\treturn this.element;\n\t}\n\n\t_updateContent() {\n\t\tconst searchQuery = this.state.helpSearchQuery || '';\n\t\tconst collections = this.state.helpArticles || [];\n\t\tconst collectionCount = collections.length;\n\n\t\tthis.element.innerHTML = `\n\t\t\t<div class=\"messenger-help-header\">\n\t\t\t\t<h2>Help</h2>\n\t\t\t\t<button class=\"messenger-close-btn\" aria-label=\"Close\">\n\t\t\t\t\t<i class=\"ph ph-x\" style=\"font-size: 20px;\"></i>\n\t\t\t\t</button>\n\t\t\t</div>\n\n\t\t\t<div class=\"messenger-help-search\">\n\t\t\t\t<div class=\"messenger-help-search-wrapper\">\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\tclass=\"messenger-help-search-input\"\n\t\t\t\t\t\tplaceholder=\"Search for help\"\n\t\t\t\t\t\tvalue=\"${searchQuery}\"\n\t\t\t\t\t/>\n\t\t\t\t\t<i class=\"ph ph-magnifying-glass messenger-help-search-icon\" style=\"font-size: 18px;\"></i>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div class=\"messenger-help-body\">\n\t\t\t\t<div class=\"messenger-help-collections-header\">\n\t\t\t\t\t${collectionCount} collections\n\t\t\t\t</div>\n\t\t\t\t<div class=\"messenger-help-collections\"></div>\n\t\t\t</div>\n\t\t`;\n\n\t\tthis._updateCollectionsList();\n\t\tthis._attachEvents();\n\t}\n\n\t_updateCollectionsList() {\n\t\tconst collectionsContainer = this.element.querySelector(\n\t\t\t'.messenger-help-collections'\n\t\t);\n\t\tconst collections = this.state.helpArticles || [];\n\t\tconst searchQuery = (this.state.helpSearchQuery || '').toLowerCase();\n\n\t\t// Filter collections by search\n\t\tconst filteredCollections = searchQuery\n\t\t\t? collections.filter(\n\t\t\t\t\t(c) =>\n\t\t\t\t\t\tc.title.toLowerCase().includes(searchQuery) ||\n\t\t\t\t\t\t(c.description && c.description.toLowerCase().includes(searchQuery))\n\t\t\t\t)\n\t\t\t: collections;\n\n\t\t// Update collection count\n\t\tconst headerEl = this.element.querySelector(\n\t\t\t'.messenger-help-collections-header'\n\t\t);\n\t\tif (headerEl) {\n\t\t\theaderEl.textContent = `${filteredCollections.length} collections`;\n\t\t}\n\n\t\tif (filteredCollections.length === 0) {\n\t\t\tcollectionsContainer.innerHTML = this._renderEmptyState();\n\t\t\treturn;\n\t\t}\n\n\t\tcollectionsContainer.innerHTML = filteredCollections\n\t\t\t.map((collection) => this._renderCollectionItem(collection))\n\t\t\t.join('');\n\n\t\t// Attach click events\n\t\tthis._attachCollectionEvents();\n\t}\n\n\t_renderCollectionItem(collection) {\n\t\tconst articleCount = collection.articleCount || 0;\n\t\treturn `\n\t\t\t<div class=\"messenger-help-collection\" data-collection-id=\"${collection.id}\">\n\t\t\t\t<div class=\"messenger-help-collection-content\">\n\t\t\t\t\t<h3 class=\"messenger-help-collection-title\">${collection.title}</h3>\n\t\t\t\t\t<p class=\"messenger-help-collection-desc\">${collection.description || ''}</p>\n\t\t\t\t\t<span class=\"messenger-help-collection-count\">${articleCount} articles</span>\n\t\t\t\t</div>\n\t\t\t\t<i class=\"ph ph-caret-right messenger-help-collection-arrow\" style=\"font-size: 20px;\"></i>\n\t\t\t</div>\n\t\t`;\n\t}\n\n\t_renderEmptyState() {\n\t\tconst isSearching = this.state.helpSearchQuery;\n\n\t\tif (isSearching) {\n\t\t\treturn `\n\t\t\t\t<div class=\"messenger-help-empty\">\n\t\t\t\t\t<div class=\"messenger-help-empty-icon\">\n\t\t\t\t\t\t<i class=\"ph ph-magnifying-glass\" style=\"font-size: 48px;\"></i>\n\t\t\t\t\t</div>\n\t\t\t\t\t<h3>No results found</h3>\n\t\t\t\t\t<p>Try a different search term</p>\n\t\t\t\t</div>\n\t\t\t`;\n\t\t}\n\n\t\treturn `\n\t\t\t<div class=\"messenger-help-empty\">\n\t\t\t\t<div class=\"messenger-help-empty-icon\">\n\t\t\t\t\t<i class=\"ph ph-question\" style=\"font-size: 48px;\"></i>\n\t\t\t\t</div>\n\t\t\t\t<h3>Help collections</h3>\n\t\t\t\t<p>No collections available yet</p>\n\t\t\t</div>\n\t\t`;\n\t}\n\n\t_attachEvents() {\n\t\t// Close button\n\t\tthis.element\n\t\t\t.querySelector('.messenger-close-btn')\n\t\t\t.addEventListener('click', () => {\n\t\t\t\tthis.state.setOpen(false);\n\t\t\t});\n\n\t\t// Search input\n\t\tconst searchInput = this.element.querySelector(\n\t\t\t'.messenger-help-search-input'\n\t\t);\n\t\tlet searchTimeout;\n\t\tsearchInput.addEventListener('input', (e) => {\n\t\t\tclearTimeout(searchTimeout);\n\t\t\tsearchTimeout = setTimeout(() => {\n\t\t\t\tthis.state.setHelpSearchQuery(e.target.value);\n\t\t\t}, 300);\n\t\t});\n\n\t\tthis._attachCollectionEvents();\n\t}\n\n\t_attachCollectionEvents() {\n\t\tthis.element\n\t\t\t.querySelectorAll('.messenger-help-collection')\n\t\t\t.forEach((item) => {\n\t\t\t\titem.addEventListener('click', () => {\n\t\t\t\t\tconst collectionId = item.dataset.collectionId;\n\t\t\t\t\tconst collection = this.state.helpArticles.find(\n\t\t\t\t\t\t(c) => c.id === collectionId\n\t\t\t\t\t);\n\t\t\t\t\tif (collection && collection.url) {\n\t\t\t\t\t\twindow.open(collection.url, '_blank');\n\t\t\t\t\t} else if (this.options.onArticleClick) {\n\t\t\t\t\t\tthis.options.onArticleClick(collection);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\t}\n\n\tdestroy() {\n\t\tif (this._unsubscribe) {\n\t\t\tthis._unsubscribe();\n\t\t}\n\t\tif (this.element && this.element.parentNode) {\n\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t}\n\t}\n}\n","/**\n * HomeView - Welcome screen with team info and quick actions\n */\nexport class HomeView {\n\tconstructor(state, options = {}) {\n\t\tthis.state = state;\n\t\tthis.options = options;\n\t\tthis.element = null;\n\t\tthis._unsubscribe = null;\n\t}\n\n\trender() {\n\t\tthis.element = document.createElement('div');\n\t\tthis.element.className = 'messenger-view messenger-home-view';\n\n\t\tthis._updateContent();\n\n\t\t// Subscribe to state changes to re-render when data loads\n\t\tthis._unsubscribe = this.state.subscribe((type) => {\n\t\t\tif (type === 'homeChangelogUpdate' || type === 'conversationsUpdate') {\n\t\t\t\tthis._updateContent();\n\t\t\t}\n\t\t});\n\n\t\treturn this.element;\n\t}\n\n\t_updateContent() {\n\t\tconst avatarsHtml = this._renderAvatarStack();\n\t\tconst recentChangelogHtml = this._renderRecentChangelog();\n\n\t\tthis.element.innerHTML = `\n\t\t\t<div class=\"messenger-home-header\">\n\t\t\t\t<div class=\"messenger-home-header-top\">\n\t\t\t\t\t<div class=\"messenger-home-logo\">\n\t\t\t\t\t\t${this.options.logoUrl ? `<img src=\"${this.options.logoUrl}\" alt=\"${this.state.teamName}\" />` : ''}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"messenger-home-avatars\">${avatarsHtml}</div>\n\t\t\t\t\t<button class=\"messenger-close-btn\" aria-label=\"Close\">\n\t\t\t\t\t\t<i class=\"ph ph-x\" style=\"font-size: 20px;\"></i>\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"messenger-home-welcome\">\n\t\t\t\t\t<span class=\"messenger-home-greeting\">Hello there.</span>\n\t\t\t\t\t<span class=\"messenger-home-question\">${this.state.welcomeMessage}</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div class=\"messenger-home-body\">\n\t\t\t\t<button class=\"messenger-home-message-btn\">\n\t\t\t\t\t<span>Send us a message</span>\n\t\t\t\t\t<i class=\"ph ph-arrow-right\" style=\"font-size: 16px;\"></i>\n\t\t\t\t</button>\n\n\t\t\t\t${this._renderFeaturedCard()}\n\n\t\t\t\t${recentChangelogHtml}\n\t\t\t</div>\n\t\t`;\n\n\t\tthis._attachEvents();\n\t}\n\n\t_renderAvatarStack() {\n\t\tconst avatars = this.state.teamAvatars;\n\t\tif (!avatars || avatars.length === 0) {\n\t\t\t// Default avatars with initials\n\t\t\treturn `\n\t\t\t\t<div class=\"messenger-avatar-stack\">\n\t\t\t\t\t<div class=\"messenger-avatar\" style=\"background: #5856d6;\">S</div>\n\t\t\t\t\t<div class=\"messenger-avatar\" style=\"background: #007aff;\">T</div>\n\t\t\t\t</div>\n\t\t\t`;\n\t\t}\n\n\t\tconst avatarItems = avatars\n\t\t\t.slice(0, 3)\n\t\t\t.map((avatar, i) => {\n\t\t\t\tif (typeof avatar === 'string' && avatar.startsWith('http')) {\n\t\t\t\t\treturn `<img class=\"messenger-avatar\" src=\"${avatar}\" alt=\"Team member\" style=\"z-index: ${3 - i};\" />`;\n\t\t\t\t}\n\t\t\t\treturn `<div class=\"messenger-avatar\" style=\"background: ${this._getAvatarColor(i)}; z-index: ${3 - i};\">${avatar.charAt(0).toUpperCase()}</div>`;\n\t\t\t})\n\t\t\t.join('');\n\n\t\treturn `<div class=\"messenger-avatar-stack\">${avatarItems}</div>`;\n\t}\n\n\t_getAvatarColor(index) {\n\t\tconst colors = ['#5856d6', '#007aff', '#34c759', '#ff9500', '#ff3b30'];\n\t\treturn colors[index % colors.length];\n\t}\n\n\t_renderFeaturedCard() {\n\t\t// Only show if there's featured content configured\n\t\tif (!this.options.featuredContent) {\n\t\t\treturn '';\n\t\t}\n\n\t\tconst { title, description, imageUrl, action } =\n\t\t\tthis.options.featuredContent;\n\n\t\treturn `\n\t\t\t<div class=\"messenger-home-featured\">\n\t\t\t\t${imageUrl ? `<img src=\"${imageUrl}\" alt=\"${title}\" class=\"messenger-home-featured-image\" onerror=\"this.style.display='none';\" />` : ''}\n\t\t\t\t<div class=\"messenger-home-featured-content\">\n\t\t\t\t\t<h3>${title}</h3>\n\t\t\t\t\t<p>${description}</p>\n\t\t\t\t</div>\n\t\t\t\t${action ? `<button class=\"messenger-home-featured-btn\" data-action=\"${action.type}\" data-value=\"${action.value}\">${action.label}</button>` : ''}\n\t\t\t</div>\n\t\t`;\n\t}\n\n\t_renderRecentChangelog() {\n\t\t// Show recent changelog preview as cards with images\n\t\tconst changelogItems = this.state.homeChangelogItems;\n\t\tif (changelogItems.length === 0) {\n\t\t\treturn '';\n\t\t}\n\n\t\tconst changelogHtml = changelogItems\n\t\t\t.map(\n\t\t\t\t(item) => `\n\t\t\t<div class=\"messenger-home-changelog-card\" data-changelog-id=\"${item.id}\">\n\t\t\t\t${\n\t\t\t\t\titem.coverImage\n\t\t\t\t\t\t? `\n\t\t\t\t\t<div class=\"messenger-home-changelog-cover\">\n\t\t\t\t\t\t<img src=\"${item.coverImage}\" alt=\"${item.title}\" onerror=\"this.style.display='none';\" />\n\t\t\t\t\t\t${item.coverText ? `<span class=\"messenger-home-changelog-cover-text\">${item.coverText}</span>` : ''}\n\t\t\t\t\t</div>\n\t\t\t\t`\n\t\t\t\t\t\t: ''\n\t\t\t\t}\n\t\t\t\t<div class=\"messenger-home-changelog-card-content\">\n\t\t\t\t\t<h4 class=\"messenger-home-changelog-card-title\">${item.title}</h4>\n\t\t\t\t\t<p class=\"messenger-home-changelog-card-desc\">${item.description || ''}</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t`\n\t\t\t)\n\t\t\t.join('');\n\n\t\treturn `\n\t\t\t<div class=\"messenger-home-changelog-section\">\n\t\t\t\t${changelogHtml}\n\t\t\t</div>\n\t\t`;\n\t}\n\n\t_formatDate(dateString) {\n\t\tif (!dateString) return '';\n\t\tconst date = new Date(dateString);\n\t\tconst now = new Date();\n\t\tconst diffDays = Math.floor((now - date) / (1000 * 60 * 60 * 24));\n\n\t\tif (diffDays === 0) return 'Today';\n\t\tif (diffDays === 1) return 'Yesterday';\n\t\tif (diffDays < 7) return `${diffDays}d ago`;\n\t\treturn date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });\n\t}\n\n\t_attachEvents() {\n\t\t// Close button\n\t\tthis.element\n\t\t\t.querySelector('.messenger-close-btn')\n\t\t\t.addEventListener('click', () => {\n\t\t\t\tthis.state.setOpen(false);\n\t\t\t});\n\n\t\t// Send message button\n\t\tthis.element\n\t\t\t.querySelector('.messenger-home-message-btn')\n\t\t\t.addEventListener('click', () => {\n\t\t\t\tthis.state.setView('messages');\n\t\t\t});\n\n\t\t// Changelog items\n\t\tthis.element\n\t\t\t.querySelectorAll('.messenger-home-changelog-item')\n\t\t\t.forEach((item) => {\n\t\t\t\titem.addEventListener('click', () => {\n\t\t\t\t\t// Navigate to changelog view with specific item selected\n\t\t\t\t\tthis.state.setView('changelog');\n\t\t\t\t});\n\t\t\t});\n\n\t\t// See all changelog\n\t\tconst seeAllBtn = this.element.querySelector(\n\t\t\t'.messenger-home-changelog-all'\n\t\t);\n\t\tif (seeAllBtn) {\n\t\t\tseeAllBtn.addEventListener('click', () => {\n\t\t\t\tthis.state.setView('changelog');\n\t\t\t});\n\t\t}\n\n\t\t// Featured card action\n\t\tconst featuredBtn = this.element.querySelector(\n\t\t\t'.messenger-home-featured-btn'\n\t\t);\n\t\tif (featuredBtn) {\n\t\t\tfeaturedBtn.addEventListener('click', () => {\n\t\t\t\tconst action = featuredBtn.dataset.action;\n\t\t\t\tconst value = featuredBtn.dataset.value;\n\t\t\t\tif (action === 'url') {\n\t\t\t\t\twindow.open(value, '_blank');\n\t\t\t\t} else if (action === 'view') {\n\t\t\t\t\tthis.state.setView(value);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tdestroy() {\n\t\tif (this._unsubscribe) {\n\t\t\tthis._unsubscribe();\n\t\t}\n\t\tif (this.element && this.element.parentNode) {\n\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t}\n\t}\n}\n","/**\n * MessengerWidget - Full-featured Messenger/Chat widget\n */\nimport { BaseWidget } from './BaseWidget.js';\nimport { MessengerState } from './messenger/MessengerState.js';\nimport { MessengerLauncher } from './messenger/components/MessengerLauncher.js';\nimport { MessengerPanel } from './messenger/components/MessengerPanel.js';\nimport { ChangelogView } from './messenger/views/ChangelogView.js';\nimport { ChatView } from './messenger/views/ChatView.js';\nimport { ConversationsView } from './messenger/views/ConversationsView.js';\nimport { HelpView } from './messenger/views/HelpView.js';\nimport { HomeView } from './messenger/views/HomeView.js';\n\nexport class MessengerWidget extends BaseWidget {\n\tconstructor(options) {\n\t\tsuper({ ...options, type: 'messenger' });\n\n\t\tthis.messengerOptions = {\n\t\t\tposition: options.position || 'bottom-right',\n\t\t\ttheme: options.theme || 'light',\n\t\t\tteamName: options.teamName || 'Support',\n\t\t\tteamAvatars: options.teamAvatars || [],\n\t\t\twelcomeMessage: options.welcomeMessage || 'How can we help?',\n\t\t\tenableHelp: options.enableHelp !== false,\n\t\t\tenableChangelog: options.enableChangelog !== false,\n\t\t\tlogoUrl: options.logoUrl || 'https://feedback-sdk.product7.io/p7.png',\n\t\t\tfeaturedContent: options.featuredContent || null,\n\t\t\tprimaryColor: options.primaryColor || '#1c1c1e',\n\t\t\t// Callbacks\n\t\t\tonSendMessage: options.onSendMessage || null,\n\t\t\tonArticleClick: options.onArticleClick || null,\n\t\t\tonChangelogClick: options.onChangelogClick || null,\n\t\t};\n\n\t\t// Create state\n\t\tthis.messengerState = new MessengerState({\n\t\t\tteamName: this.messengerOptions.teamName,\n\t\t\tteamAvatars: this.messengerOptions.teamAvatars,\n\t\t\twelcomeMessage: this.messengerOptions.welcomeMessage,\n\t\t\tenableHelp: this.messengerOptions.enableHelp,\n\t\t\tenableChangelog: this.messengerOptions.enableChangelog,\n\t\t\tuserContext: this.sdk?.apiService?.getUserContext() || null,\n\t\t});\n\n\t\tthis.launcher = null;\n\t\tthis.panel = null;\n\n\t\t// Bind methods\n\t\tthis._handleOpenChange = this._handleOpenChange.bind(this);\n\t}\n\n\t_render() {\n\t\t// Create container\n\t\tconst container = document.createElement('div');\n\t\tcontainer.className = `messenger-widget theme-${this.messengerOptions.theme}`;\n\t\tcontainer.style.zIndex = '999999';\n\n\t\t// Create launcher\n\t\tthis.launcher = new MessengerLauncher(this.messengerState, {\n\t\t\tposition: this.messengerOptions.position,\n\t\t\tprimaryColor: this.messengerOptions.primaryColor,\n\t\t});\n\t\tcontainer.appendChild(this.launcher.render());\n\n\t\t// Create panel\n\t\tthis.panel = new MessengerPanel(this.messengerState, {\n\t\t\tposition: this.messengerOptions.position,\n\t\t\ttheme: this.messengerOptions.theme,\n\t\t\tprimaryColor: this.messengerOptions.primaryColor,\n\t\t\tlogoUrl: this.messengerOptions.logoUrl,\n\t\t\tfeaturedContent: this.messengerOptions.featuredContent,\n\t\t\tonSendMessage:\n\t\t\t\tthis.messengerOptions.onSendMessage ||\n\t\t\t\tthis._handleSendMessage.bind(this),\n\t\t\tonArticleClick: this.messengerOptions.onArticleClick,\n\t\t\tonChangelogClick: this.messengerOptions.onChangelogClick,\n\t\t});\n\n\t\t// Register views\n\t\tthis.panel.registerView('home', HomeView);\n\t\tthis.panel.registerView('messages', ConversationsView);\n\t\tthis.panel.registerView('chat', ChatView);\n\t\tthis.panel.registerView('help', HelpView);\n\t\tthis.panel.registerView('changelog', ChangelogView);\n\n\t\tcontainer.appendChild(this.panel.render());\n\t\tthis.panel.hide();\n\n\t\treturn container;\n\t}\n\n\t_attachEvents() {\n\t\t// Subscribe to state changes\n\t\tthis._stateUnsubscribe = this.messengerState.subscribe((type, data) => {\n\t\t\tif (type === 'openChange') {\n\t\t\t\tthis._handleOpenChange(data.isOpen);\n\t\t\t}\n\t\t});\n\t}\n\n\t_handleOpenChange(isOpen) {\n\t\tif (isOpen) {\n\t\t\tthis.panel.show();\n\t\t\tthis.sdk.eventBus.emit('messenger:opened', { widget: this });\n\t\t} else {\n\t\t\tthis.panel.hide();\n\t\t\tthis.messengerState.reset();\n\t\t\tthis.sdk.eventBus.emit('messenger:closed', { widget: this });\n\t\t}\n\t}\n\n\tasync _handleSendMessage(conversationId, message) {\n\t\t// Default message handler - can be overridden\n\t\tthis.sdk.eventBus.emit('messenger:messageSent', {\n\t\t\twidget: this,\n\t\t\tconversationId,\n\t\t\tmessage,\n\t\t});\n\n\t\t// In mock mode, simulate a response\n\t\tif (this.apiService?.mock) {\n\t\t\tsetTimeout(() => {\n\t\t\t\tconst response = {\n\t\t\t\t\tid: 'msg_' + Date.now(),\n\t\t\t\t\tcontent: \"Thanks for your message! We'll get back to you soon.\",\n\t\t\t\t\tisOwn: false,\n\t\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\t\tsender: {\n\t\t\t\t\t\tname: 'Support Team',\n\t\t\t\t\t\tavatarUrl: null,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t\tthis.messengerState.addMessage(conversationId, response);\n\t\t\t}, 1500);\n\t\t}\n\t}\n\n\t/**\n\t * Open the messenger panel\n\t */\n\topen() {\n\t\tthis.messengerState.setOpen(true);\n\t}\n\n\t/**\n\t * Close the messenger panel\n\t */\n\tclose() {\n\t\tthis.messengerState.setOpen(false);\n\t}\n\n\t/**\n\t * Toggle the messenger panel\n\t */\n\ttoggle() {\n\t\tthis.messengerState.setOpen(!this.messengerState.isOpen);\n\t}\n\n\t/**\n\t * Navigate to a specific view\n\t */\n\tnavigateTo(view) {\n\t\tthis.messengerState.setView(view);\n\t\tif (!this.messengerState.isOpen) {\n\t\t\tthis.open();\n\t\t}\n\t}\n\n\t/**\n\t * Set conversations\n\t */\n\tsetConversations(conversations) {\n\t\tthis.messengerState.setConversations(conversations);\n\t}\n\n\t/**\n\t * Add a message to a conversation\n\t */\n\taddMessage(conversationId, message) {\n\t\tthis.messengerState.addMessage(conversationId, message);\n\t}\n\n\t/**\n\t * Set help articles\n\t */\n\tsetHelpArticles(articles) {\n\t\tthis.messengerState.setHelpArticles(articles);\n\t}\n\n\t/**\n\t * Set home changelog items\n\t */\n\tsetHomeChangelogItems(items) {\n\t\tthis.messengerState.setHomeChangelogItems(items);\n\t}\n\n\t/**\n\t * Set changelog items\n\t */\n\tsetChangelogItems(items) {\n\t\tthis.messengerState.setChangelogItems(items);\n\t}\n\n\t/**\n\t * Update unread count (for external updates)\n\t */\n\tsetUnreadCount(count) {\n\t\tthis.messengerState.unreadCount = count;\n\t\tthis.messengerState._notify('unreadCountChange', { count });\n\t}\n\n\t/**\n\t * Get current state\n\t */\n\tgetState() {\n\t\treturn {\n\t\t\tisOpen: this.messengerState.isOpen,\n\t\t\tcurrentView: this.messengerState.currentView,\n\t\t\tunreadCount: this.messengerState.unreadCount,\n\t\t\tconversations: this.messengerState.conversations,\n\t\t};\n\t}\n\n\t/**\n\t * Load initial data (mock or API)\n\t */\n\tasync loadInitialData() {\n\t\t// Load conversations\n\t\ttry {\n\t\t\tconst conversations = await this._fetchConversations();\n\t\t\tthis.messengerState.setConversations(conversations);\n\t\t} catch (error) {\n\t\t\tconsole.error('[MessengerWidget] Failed to load conversations:', error);\n\t\t}\n\n\t\t// Load help articles if enabled\n\t\tif (this.messengerOptions.enableHelp) {\n\t\t\ttry {\n\t\t\t\tconst articles = await this._fetchHelpArticles();\n\t\t\t\tthis.messengerState.setHelpArticles(articles);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('[MessengerWidget] Failed to load help articles:', error);\n\t\t\t}\n\t\t}\n\n\t\t// Load changelog if enabled\n\t\tif (this.messengerOptions.enableChangelog) {\n\t\t\ttry {\n\t\t\t\tconst { homeItems, changelogItems } = await this._fetchChangelog();\n\t\t\t\tthis.messengerState.setHomeChangelogItems(homeItems);\n\t\t\t\tthis.messengerState.setChangelogItems(changelogItems);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('[MessengerWidget] Failed to load changelog:', error);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync _fetchConversations() {\n\t\t// Mock data for now\n\t\tif (this.apiService?.mock) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tid: 'conv_1',\n\t\t\t\t\ttitle: 'Chat with Sarah',\n\t\t\t\t\tparticipants: [{ name: 'Sarah', avatarUrl: null }],\n\t\t\t\t\tlastMessage: \"Sarah: Hi 👋 I'm Sarah. How can I help today?\",\n\t\t\t\t\tlastMessageTime: new Date(Date.now() - 49 * 60 * 1000).toISOString(),\n\t\t\t\t\tunread: 1,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: 'conv_2',\n\t\t\t\t\ttitle: 'Chat with Tom',\n\t\t\t\t\tparticipants: [{ name: 'Tom', avatarUrl: null }],\n\t\t\t\t\tlastMessage: 'Tom: The feature will be available next week.',\n\t\t\t\t\tlastMessageTime: new Date(\n\t\t\t\t\t\tDate.now() - 6 * 24 * 60 * 60 * 1000\n\t\t\t\t\t).toISOString(),\n\t\t\t\t\tunread: 0,\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\n\t\t// TODO: Implement API call\n\t\treturn [];\n\t}\n\n\tasync _fetchHelpArticles() {\n\t\t// Mock data for collections\n\t\tif (this.apiService?.mock) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tid: 'collection_1',\n\t\t\t\t\ttitle: 'Product Overview',\n\t\t\t\t\tdescription: 'See how your AI-first customer service solution works.',\n\t\t\t\t\tarticleCount: 24,\n\t\t\t\t\turl: '#',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: 'collection_2',\n\t\t\t\t\ttitle: 'Getting Started',\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'Everything you need to know to get started with Product7.',\n\t\t\t\t\tarticleCount: 30,\n\t\t\t\t\turl: '#',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: 'collection_3',\n\t\t\t\t\ttitle: 'AI Agent',\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'Resolving customer questions instantly and accurately—from live chat to email.',\n\t\t\t\t\tarticleCount: 82,\n\t\t\t\t\turl: '#',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: 'collection_4',\n\t\t\t\t\ttitle: 'Channels',\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'Enabling the channels you use to communicate with customers, all from the Inbox.',\n\t\t\t\t\tarticleCount: 45,\n\t\t\t\t\turl: '#',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: 'collection_5',\n\t\t\t\t\ttitle: 'Billing & Payments',\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'Manage your subscription, invoices, and payment methods.',\n\t\t\t\t\tarticleCount: 12,\n\t\t\t\t\turl: '#',\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\n\t\t// TODO: Implement API call\n\t\treturn [];\n\t}\n\n\tasync _fetchChangelog() {\n\t\t// Mock data for now - simulating changelog API response\n\t\tif (this.apiService?.mock) {\n\t\t\treturn {\n\t\t\t\thomeItems: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: 'changelog_5',\n\t\t\t\t\t\ttitle: 'New integrations available',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Connect with more tools you love and streamline your workflow.',\n\t\t\t\t\t\ttags: ['Integration'],\n\t\t\t\t\t\tcoverImage: 'https://feedback-sdk.product7.io/700x400__5_.png',\n\t\t\t\t\t\tcoverText: null,\n\t\t\t\t\t\tpublishedAt: new Date(\n\t\t\t\t\t\t\tDate.now() - 14 * 24 * 60 * 60 * 1000\n\t\t\t\t\t\t).toISOString(),\n\t\t\t\t\t\turl: '#',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: 'changelog_2',\n\t\t\t\t\t\ttitle: 'A new era of Insights has arrived',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'We announced Fin Insights, a groundbreaking, AI-powered product that gives you complete visibility into every customer conversation.',\n\t\t\t\t\t\ttags: ['New feature', 'AI'],\n\t\t\t\t\t\tcoverImage:\n\t\t\t\t\t\t\t'https://feedback-sdk.product7.io/Intercom_Messenger__1_.jpg',\n\t\t\t\t\t\tcoverText: 'Watch our major product launch on-demand',\n\t\t\t\t\t\tpublishedAt: new Date(\n\t\t\t\t\t\t\tDate.now() - 5 * 24 * 60 * 60 * 1000\n\t\t\t\t\t\t).toISOString(),\n\t\t\t\t\t\turl: '#',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: 'changelog_1',\n\t\t\t\t\t\ttitle: 'The 2025 Customer Service Transformation Report',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Learn how AI has transformed customer service from the ground up—rewriting its economics and reshaping expectations.',\n\t\t\t\t\t\ttags: ['Report'],\n\t\t\t\t\t\tcoverImage:\n\t\t\t\t\t\t\t'https://feedback-sdk.product7.io/Main_Report_Email_Header.png',\n\t\t\t\t\t\tcoverText: 'Customer service trends as we know them are dead.',\n\t\t\t\t\t\tpublishedAt: new Date(\n\t\t\t\t\t\t\tDate.now() - 2 * 24 * 60 * 60 * 1000\n\t\t\t\t\t\t).toISOString(),\n\t\t\t\t\t\turl: '#',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tchangelogItems: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: 'changelog_4',\n\t\t\t\t\t\ttitle: 'Enhanced conversation analytics',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Get deeper insights into your customer conversations with our new analytics dashboard.',\n\t\t\t\t\t\ttags: ['Analytics'],\n\t\t\t\t\t\tcoverImage:\n\t\t\t\t\t\t\t'https://feedback-sdk.product7.io/cgangelog-Frame%202087334450.jpg',\n\t\t\t\t\t\tcoverText: null,\n\t\t\t\t\t\tpublishedAt: new Date(\n\t\t\t\t\t\t\tDate.now() - 10 * 24 * 60 * 60 * 1000\n\t\t\t\t\t\t).toISOString(),\n\t\t\t\t\t\turl: '#',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: 'changelog_3',\n\t\t\t\t\t\ttitle: 'Escalation guidance for complex issues',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'New AI-powered escalation guidance helps your team handle complex customer issues more effectively.',\n\t\t\t\t\t\ttags: ['New feature', 'AI'],\n\t\t\t\t\t\tcoverImage:\n\t\t\t\t\t\t\t'https://feedback-sdk.product7.io/cgangelog-image-escalation-guidance-event@2x.png',\n\t\t\t\t\t\tcoverText: null,\n\t\t\t\t\t\tpublishedAt: new Date(\n\t\t\t\t\t\t\tDate.now() - 7 * 24 * 60 * 60 * 1000\n\t\t\t\t\t\t).toISOString(),\n\t\t\t\t\t\turl: '#',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t};\n\t\t}\n\n\t\t// TODO: Implement API call for changelogs\n\t\treturn { homeItems: [], changelogItems: [] };\n\t}\n\n\tonMount() {\n\t\t// Load initial data after mounting\n\t\tthis.loadInitialData();\n\t}\n\n\tonDestroy() {\n\t\tif (this._stateUnsubscribe) {\n\t\t\tthis._stateUnsubscribe();\n\t\t}\n\t}\n\n\tdestroy() {\n\t\tif (this.launcher) {\n\t\t\tthis.launcher.destroy();\n\t\t}\n\t\tif (this.panel) {\n\t\t\tthis.panel.destroy();\n\t\t}\n\t\tsuper.destroy();\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\tsurveyId: options.surveyId || null, // Backend survey ID for API calls\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;\">&times;</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 responseData = {\n\t\t\trating: this.surveyState.score,\n\t\t\tfeedback: this.surveyState.feedback,\n\t\t\tanswers: this.surveyState.customAnswers,\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\n\t\ttry {\n\t\t\tconst surveyId =\n\t\t\t\tthis.surveyOptions.surveyId || `local_${type}_${Date.now()}`;\n\t\t\tawait this.apiService.submitSurveyResponse(surveyId, responseData);\n\t\t} catch (error) {\n\t\t\tconsole.error('[SurveyWidget] Failed to submit survey:', error);\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\tasync _handleDismiss() {\n\t\t// Call dismiss API if survey has a backend ID\n\t\tif (this.surveyOptions.surveyId) {\n\t\t\ttry {\n\t\t\t\tawait this.apiService.dismissSurvey(this.surveyOptions.surveyId);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('[SurveyWidget] Failed to dismiss survey:', error);\n\t\t\t}\n\t\t}\n\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 { MessengerWidget } from './MessengerWidget.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\t['messenger', MessengerWidget],\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 * Fetch active surveys from the backend\n\t * @param {Object} context - Optional context for targeting\n\t * @param {string} context.page - Current page/route\n\t * @param {string} context.event - Event trigger name\n\t * @returns {Promise<Array>} Array of active survey configurations\n\t */\n\tasync getActiveSurveys(context = {}) {\n\t\tif (!this.initialized) {\n\t\t\tthrow new SDKError(\n\t\t\t\t'SDK must be initialized before fetching surveys. Call init() first.'\n\t\t\t);\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await this.apiService.getActiveSurveys(context);\n\t\t\treturn result.data || [];\n\t\t} catch (error) {\n\t\t\tthis.eventBus.emit('sdk:error', { error });\n\t\t\tthrow new SDKError(\n\t\t\t\t`Failed to fetch active surveys: ${error.message}`,\n\t\t\t\terror\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Show a survey by its backend ID\n\t * Fetches survey configuration from the backend and displays it\n\t * @param {string} surveyId - The backend survey ID\n\t * @param {Object} options - Additional display options\n\t * @param {string} options.position - Position override\n\t * @param {string} options.theme - Theme override\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 {Promise<SurveyWidget>} The survey widget instance\n\t */\n\tasync showSurveyById(surveyId, 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\t// Fetch active surveys to find the one with matching ID\n\t\tconst surveys = await this.getActiveSurveys();\n\t\tconst surveyConfig = surveys.find((s) => s.id === surveyId);\n\n\t\tif (!surveyConfig) {\n\t\t\tthrow new SDKError(\n\t\t\t\t`Survey with ID '${surveyId}' not found or not active`\n\t\t\t);\n\t\t}\n\n\t\treturn this.showSurvey({\n\t\t\tsurveyId: surveyConfig.id,\n\t\t\tsurveyType: surveyConfig.type,\n\t\t\ttitle: surveyConfig.title,\n\t\t\tdescription: surveyConfig.description,\n\t\t\tlowLabel: surveyConfig.low_label,\n\t\t\thighLabel: surveyConfig.high_label,\n\t\t\tcustomQuestions: surveyConfig.questions,\n\t\t\t...options,\n\t\t});\n\t}\n\n\t/**\n\t * Show a survey widget (local/manual mode)\n\t * For backend-driven surveys, use showSurveyById() instead\n\t * @param {Object} options - Survey options\n\t * @param {string} options.surveyId - Backend survey ID (for API tracking)\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\tsurveyId: options.surveyId,\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 { MESSENGER_STYLES } from './styles/messengerStyles.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 { MessengerWidget } from './widgets/MessengerWidget.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 + MESSENGER_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\tMessengerWidget,\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\tMessengerWidget,\n\tSDKError,\n\tSurveyWidget,\n\tTabWidget,\n\tValidationError,\n\tWidgetError,\n\tWidgetFactory,\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","MOCK_SURVEYS","id","type","title","description","low_label","high_label","trigger","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","content","board","board_id","attachments","Authorization","getActiveSurveys","context","queryParams","URLSearchParams","currentUrl","url","window","location","href","append","deviceInfo","_getDeviceInfo","device","browser","os","userProperties","endpoint","toString","navigator","ua","userAgent","test","includes","submitSurveyResponse","surveyId","responseData","survey_id","rating","feedback","answers","dismissSurvey","setUserContext","localStorage","setItem","getUserContext","clearSession","removeItem","sessionData","token","expiry","toISOString","stored","getItem","parse","options","fetch","ok","errorMessage","json","e","text","contentType","get","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","substring","deepMerge","target","source","result","key","hasOwnProperty","Array","isArray","isBrowser","document","func","wait","timeout","args","clearTimeout","ms","string","replace","bytes","i","floor","log","parseFloat","pow","toFixed","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","email","trim","str","div","createElement","textContent","innerHTML","scrollIntoView","behavior","block","inline","lastKey","pop","limit","lastFunc","lastRan","required","missing","join","BaseWidget","sdk","apiService","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","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","isMinimized","render","button","Object","assign","attachEvents","minimizeIcon","expandIcon","stopPropagation","minimize","restore","closest","transform","updateText","textEl","updatePosition","InlineWidget","form","textarea","originalContent","updateTitle","titleElement","setPlaceholder","placeholder","input","MessengerState","currentView","unreadCount","activeConversationId","conversations","messages","helpArticles","helpSearchQuery","homeChangelogItems","changelogItems","teamName","teamAvatars","welcomeMessage","enableHelp","enableChangelog","_listeners","Set","subscribe","delete","_notify","changeType","cb","setView","view","previousView","setOpen","setActiveConversation","conversationId","setConversations","_updateUnreadCount","addConversation","conversation","unshift","setMessages","addMessage","conv","find","c","lastMessage","lastMessageTime","timestamp","isOwn","unread","markAsRead","reduce","sum","count","setHelpArticles","articles","setHelpSearchQuery","query","setHomeChangelogItems","items","setChangelogItems","getActiveConversation","getActiveMessages","getFilteredHelpArticles","toLowerCase","filter","article","reset","MessengerLauncher","_unsubscribe","_updateContent","_updateIcon","_updateBadge","badgeHtml","chatIcon","closeIcon","existingBadge","badge","NavigationTabs","_updateActiveTab","_getTabs","tabs","label","icon","_getHomeIcon","_getMessagesIcon","_getHelpIcon","_getChangelogIcon","tabsHtml","map","tab","isActive","tabId","dataset","querySelectorAll","toggle","MessengerPanel","navigationTabs","currentViewComponent","viewRegistry","registerView","ViewClass","_renderCurrentView","viewsContainer","setHeader","headerContent","header","ChangelogView","_updateChangelogList","avatarsHtml","_renderTeamAvatars","changelogContainer","item","_renderChangelogCard","_attachChangelogEvents","_renderEmptyState","tagsHtml","tags","tag","dateStr","_formatDate","publishedAt","date","coverImage","_truncateText","avatars","colors","slice","avatar","startsWith","charAt","toUpperCase","dateString","toLocaleDateString","month","day","year","maxLength","card","changelogId","changelogItem","n","open","onChangelogClick","ChatView","_appendMessage","_scrollToBottom","messagesHtml","msg","_renderMessage","avatarHtml","_renderConversationAvatar","messageClass","timeStr","_formatMessageTime","_formatMessageContent","_renderSenderAvatar","sender","avatarUrl","participants","p","toLocaleTimeString","hour","minute","hour12","messagesContainer","emptyState","messageHtml","tempDiv","firstElementChild","scrollTop","scrollHeight","sendBtn","min","shiftKey","_sendMessage","onSendMessage","ConversationsView","_renderAvatarStack","conversationsHtml","_renderConversationItem","unreadClass","timeAgo","_formatTimeAgo","_renderConversationAvatars","_truncateMessage","_getAvatarColor","diffMs","diffMins","diffHours","diffDays","closeBtn","convId","newMsgBtn","_startNewConversation","newConv","HelpView","_updateCollectionsList","searchQuery","collectionCount","collectionsContainer","collections","filteredCollections","headerEl","collection","_renderCollectionItem","_attachCollectionEvents","articleCount","searchTimeout","collectionId","onArticleClick","HomeView","recentChangelogHtml","_renderRecentChangelog","logoUrl","_renderFeaturedCard","featuredContent","imageUrl","action","coverText","seeAllBtn","featuredBtn","MessengerWidget","messengerOptions","messengerState","launcher","_handleOpenChange","zIndex","_handleSendMessage","_stateUnsubscribe","close","navigateTo","setUnreadCount","getState","loadInitialData","_fetchConversations","_fetchHelpArticles","homeItems","_fetchChangelog","SurveyWidget","surveyOptions","surveyType","lowLabel","highLabel","customQuestions","onSubmit","onDismiss","surveyState","score","customAnswers","isVisible","_renderSurvey","_closeSurvey","_getSurveyConfig","positionStyles","_getPositionStyles","themeStyles","_handleDismiss","surveyElement","cssText","html","_attachSurveyEvents","configs","nps","csat","emoji","ces","custom","_renderCustomQuestions","q","_renderQuestionInput","freq","question","opt","positions","center","_handleSubmit","_attachTypeSpecificEvents","_escapeHandler","btn","_selectNPS","parseInt","borderColor","_selectCSAT","_selectCES","_selectFrequency","select","background","color","btnScore","frequency","_showSuccessNotification","existing","insertBefore","transition","surveyEl","backdropEl","TabWidget","_getHoverTransform","textElement","WidgetFactory","static","register","WidgetClass","widgets","create","availableTypes","from","getAvailableTypes","isTypeRegistered","unregister","getWidgetClass","FeedbackSDK","_validateAndMergeConfig","initialized","alreadyInitialized","initData","createWidget","widgetOptions","getWidget","showSurveyById","surveyConfig","s","showSurvey","questions","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","CSS_STYLES","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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"}