@crestapps/ai-chat-ui 1.0.0-preview.7 → 1.0.0-preview.73

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["ai-chat.js"],"names":["_regenerator","e","t","r","Symbol","n","iterator","o","toStringTag","i","c","prototype","Generator","u","Object","create","_regeneratorDefine2","f","p","y","G","v","a","d","bind","length","l","TypeError","call","done","value","GeneratorFunction","GeneratorFunctionPrototype","getPrototypeOf","this","setPrototypeOf","__proto__","displayName","w","m","defineProperty","_invoke","enumerable","configurable","writable","asyncGeneratorStep","Promise","resolve","then","_asyncToGenerator","arguments","apply","_next","_throw","_createForOfIteratorHelper","Array","isArray","_unsupportedIterableToArray","_n","F","s","next","_toConsumableArray","_arrayWithoutHoles","_iterableToArray","_nonIterableSpread","from","_arrayLikeToArray","_slicedToArray","_arrayWithHoles","_iterableToArrayLimit","_nonIterableRest","toString","slice","constructor","name","test","push","_typeof","window","openAIChatManager","defaultConfig","generatedImageAltText","generatedImageMaxWidth","downloadImageTitle","downloadChartTitle","downloadChartButtonText","userLabel","assistantLabel","thumbsUpTitle","thumbsDownTitle","copyTitle","codeCopiedText","widget","chatWidgetContainer","chatWidgetStateName","chatHistorySection","showHistoryButton","closeHistoryButton","newChatButton","toggleButtonSelector","resetSizeButtonSelector","dragHandleSelector","enableDragging","enableResizing","persistLayout","defaultWidth","defaultHeight","minWidth","minHeight","messageTemplate","indicatorTemplate","sanitizeUrl","url","trimmed","trim","escapeHtmlEntities","text","span","document","createElement","textContent","innerHTML","parsePixelValue","Number","isFinite","parsed","parseFloat","clamp","min","max","Math","normalizeReference","reference","_ref","_normalized$index","_ref2","_normalized$text","_ref3","_normalized$link","normalized","assign","index","Index","Text","link","Link","normalizeReferences","references","_i","_Object$entries","entries","_normalizeReference","_Object$entries$_i","key","renderer","marked","Renderer","data","href","concat","code","lang","highlighted","hljs","getLanguage","highlight","language","_","highlightAuto","langDisplay","image","src","alt","maxWidth","chartCounter","_pendingCharts","renderChartsInMessage","message","charts","requestAnimationFrame","_step","_iterator","renderChartOnCanvas","chartId","config","err","canvas","getElementById","Chart","console","warn","offsetParent","__chartConfigs","_cfg$options","_cfg$options2","_cfg$options2$aspectR","_chartInstance","destroy","cfg","JSON","parse","options","responsive","maintainAspectRatio","aspectRatio","error","parseMarkdownContent","content","html","DOMPurify","sanitize","ADD_TAGS","ADD_ATTR","use","extensions","level","start","idx","indexOf","undefined","tokenizer","extracted","token","jsonStart","depth","inString","escape","ch","jsonEnd","closeBracketIndex","startIndex","endIndex","json","substring","tryExtractChartMarker","type","raw","renderPendingCharts","configs","_i2","_Object$keys","keys","initialize","instanceConfig","hasWidgetConfig","signalRHubUrl","appElementSelector","chatContainerElementSelector","inputElementSelector","sendButtonElementSelector","Vue","createApp","inputElement","buttonElement","chatContainer","placeholder","isSessionStarted","isPlaceholderVisible","chatWidgetStateSession","chatWidgetLayoutKey","widgetContainerElement","widgetToggleButtonElement","widgetResetSizeButtonElement","widgetResizeObserver","widgetViewportResizeHandler","widgetDefaultWidth","widgetDefaultHeight","widgetIsInitialized","isStreaming","isNavigatingAway","autoScroll","stream","messages","notifications","prompt","documents","existingDocuments","isUploading","uploadErrors","isDragOver","documentBar","metricsEnabled","isRecording","mediaRecorder","preRecordingPrompt","micButton","speechToTextEnabled","chatMode","textToSpeechEnabled","ttsVoiceName","audioChunks","audioPlayQueue","isPlayingAudio","currentAudioElement","currentAudioUrl","ttsButton","ttsPlayingMessageIndex","ttsAudioCache","ttsInstanceId","random","singleResponseMode","conversationModeEnabled","conversationButton","isConversationMode","notificationDismissTimers","computed","lastAssistantIndex","role","methods","handleBeforeUnload","getStoredWidgetLayout","storedLayout","localStorage","getItem","saveStoredWidgetLayout","partialLayout","currentLayout","nextLayout","panel","toggle","setItem","stringify","getElementSize","element","fallbackWidth","fallbackHeight","width","height","rect","getBoundingClientRect","getComputedStyle","round","clampWidgetPosition","left","top","maxLeft","innerWidth","maxTop","innerHeight","applyAbsolutePosition","style","right","bottom","getWidgetDefaultSize","persistWidgetPanelPosition","panelRect","persistWidgetTogglePosition","toggleRect","persistWidgetPanelSize","defaultSize","currentSize","abs","updateWidgetResetSizeButtonVisibility","isResized","classList","add","resetWidgetSize","removeProperty","constrainWidgetElementsToViewport","restoreWidgetLayout","attachDraggableWidgetElement","handle","layoutKey","suppressClickOnDrag","_this","activePointerId","startX","startY","startLeft","startTop","dragged","stopDragging","event","pointerId","removeEventListener","onPointerMove","remove","dataset","dragSuppressClick","setTimeout","deltaX","clientX","deltaY","clientY","hypot","nextPosition","addEventListener","button","target","closest","setPointerCapture","preventDefault","panelDefaultSize","panelSize","clampedPanel","toggleSize","clampedToggle","handleDragOver","sessionDocumentsEnabled","stopPropagation","inputArea","handleDragLeave","handleDrop","dataTransfer","files","uploadFiles","triggerFileInput","fileInput","click","handleFileInputChange","_this2","_callee","sessionId","profileId","formData","response","errorText","uploadError","result","j","_t","_context","uploadDocumentUrl","getSessionId","getProfileId","renderDocumentBar","FormData","append","fetch","method","body","ok","extractReadableErrorMessage","fileName","initializeSession","uploaded","failed","removeDocument","doc","_this3","_callee2","removeError","_t2","_context2","removeDocumentUrl","headers","itemId","documentId","splice","status","formatFileSize","bytes","toFixed","escapeHtml","failedItem","failedName","errorMsg","supportedExtensionsText","replaceChildren","RETURN_DOM_FRAGMENT","self","closeButtons","querySelectorAll","docToRemove","parseInt","getAttribute","errorCloseButtons","addBtn","querySelector","div","fallbackMessage","startsWith","title","detail","normalizeAssistantAppearance","appearance","label","icon","cssClass","disableStreamingAnimation","getAssistantLabel","getAssistantRoleClasses","classes","getAssistantIconClasses","shouldAnimateAssistantIcon","getAssistantIcon","startConnection","_this4","_callee3","_t3","_context3","connection","signalR","HubConnectionBuilder","withUrl","withAutomaticReconnect","build","serverTimeoutInMilliseconds","keepAliveIntervalInMilliseconds","on","_data$messages","forEach","msg","addMessage","$nextTick","refreshAllFeedbackIcons","initialPrompt","sendMessage","stopRecording","_attemptedSessionRecovery","removeItem","startNewSession","messageId","userRating","find","id","isFinal","_conversationPartialTranscript","replace","_conversationPartialMessage","htmlContent","hidePlaceholder","isPartial","scrollToBottom","_audioInputSent","dispatchEvent","Event","stopAudio","_conversationAssistantMessage","oldMsg","escaped","responseId","hideTypingIndicator","msgIndex","newMessage","base64Audio","contentType","binaryString","atob","Uint8Array","charCodeAt","playCollectedAudio","notification","receiveNotification","updateNotification","notificationType","removeNotification","onreconnecting","onreconnected","info","reloadCurrentSession","autoCreateSession","onclose","addMessageInternal","_this5","fireEvent","CustomEvent","_this6","processedContent","citedRefs","filter","_ref4","includes","sort","_ref6","_ref7","b","_step2","displayIndex","_iterator2","_step2$value","replaceAll","_displayIndex","_placeholder","_step3","_iterator3","_step4","_iterator4","_step4$value","addMessages","_this7","showPlaceholder","isOrchestratorAvailable","applyOrchestratorAvailability","unavailableMessage","orchestratorUnavailableMessage","disabled","micButtonElement","display","conversationButtonElement","isIndicator","trimmedPrompt","streamMessage","startRecording","_this8","navigator","mediaDevices","getUserMedia","audio","echoCancellation","noiseSuppression","autoGainControl","mimeType","MediaRecorder","isTypeSupported","audioBitsPerSecond","subject","Subject","pendingChunk","size","_callee4","uint8Array","base64","_context4","arrayBuffer","reduce","str","byte","String","fromCharCode","btoa","getTracks","track","stop","complete","documentElement","send","updateMicButton","toggleRecording","sessionProfileId","_this9","dispose","streamingStarted","showTypingIndicator","lastResponseId","messageIndex","currentSessionId","subscribe","chunk","_i3","_Object$entries2","_normalizeReference2","_Object$entries2$_i","_i4","_Object$entries3","_Object$entries3$_i","_this9$stream","processReferences","streamingFinished","synthesizeSpeech","_this9$stream2","getServiceDownMessage","_this0","_ref1","_ref10","_ref11","_ref12","_step5","processed","_iterator5","_step5$value","_step6","_iterator6","_step7","_iterator7","_step7$value","stopIcon","setAttribute","startIcon","removeAttribute","focus","icons","handleExternalTtsStop","_e$detail","sourceId","cacheIndex","_this1","_ttsCacheIndex","invoke","toggleMessageTts","playAudioBlob","_step8","totalLength","sum","combined","offset","_iterator8","set","blob","Blob","_this10","URL","createObjectURL","Audio","revokeObjectURL","playNextInQueue","play","nextBlob","shift","conversationModeOnAudioEnded","pause","currentTime","toggleConversationMode","stopConversationMode","startConversationMode","_this11","updateConversationButton","_conversationSubject","_conversationStream","AudioCtx","AudioContext","webkitAudioContext","_conversationAudioCtx","_conversationAnalyser","createAnalyser","fftSize","createMediaStreamSource","connect","analyser","freqData","frequencyBinCount","getByteFrequencyData","k","_callee5","_context5","close","dismissible","autoDismissMs","endHtml","blur","startHtml","conversationModeSendPrompt","generatePrompt","templateProfileId","createSessionUrl","baseUrl","param","fullUrl","toLowerCase","location","origin","searchParams","originalLength","_this12","clearNotificationDismiss","existingIndex","findIndex","scheduleNotificationDismiss","_this13","timerId","clearTimeout","dismissNotification","handleNotificationAction","actionName","_this14","scrollTop","scrollHeight","clientHeight","handleUserInput","setSessionId","resetSession","sessionRating","initializeApp","_this15","placeholderElementSelector","loadSession","documentBarSelector","className","multiple","allowedExtensions","accept","parentElement","appendChild","atBottom","shiftKey","lastMsg","pop","promptGenerators","getElementsByClassName","chatSessions","showChatScreen","btn","block","codeEl","clipboard","writeText","copiedText","micButtonElementSelector","conversationButtonElementSelector","force","initializeWidget","_this16","ResizeObserver","observe","dragHandle","copyResponse","updateFeedbackIcons","container","upBtn","downBtn","upClass","upIcon","fontSize","downClass","downIcon","FontAwesome","dom","i2svg","node","containers","$el","msgId","rateMessage","isPositive","newRating","feedbackContainer","btnClass","offsetWidth","onEnd","watch","handler","deep","active","mounted","_this17","_callee6","_context6","beforeUnmount","template","mount","download","toDataURL","img","res","removeChild"],"mappings":"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","file":"ai-chat.min.js","sourcesContent":["window.openAIChatManager = function () {\n\n // Defaults (can be overridden by instanceConfig)\n var defaultConfig = {\n // UI defaults for generated media\n generatedImageAltText: 'Generated Image',\n generatedImageMaxWidth: 400,\n downloadImageTitle: 'Download image',\n downloadChartTitle: 'Download chart as image',\n downloadChartButtonText: 'Download',\n userLabel: 'You',\n assistantLabel: 'Assistant',\n thumbsUpTitle: 'Thumbs up',\n thumbsDownTitle: 'Thumbs down',\n copyTitle: 'Click here to copy response to clipboard.',\n codeCopiedText: 'Copied!',\n widget: {\n chatWidgetContainer: null,\n chatWidgetStateName: null,\n chatHistorySection: null,\n showHistoryButton: null,\n closeHistoryButton: null,\n newChatButton: null,\n toggleButtonSelector: null,\n resetSizeButtonSelector: null,\n dragHandleSelector: '.ai-chat-widget-header',\n enableDragging: true,\n enableResizing: true,\n persistLayout: true,\n defaultWidth: null,\n defaultHeight: null,\n minWidth: 320,\n minHeight: 420\n },\n messageTemplate: `\n <div class=\"ai-chat-messages\">\n <div v-for=\"(message, index) in messages\" :key=\"'msg-' + index\" class=\"ai-chat-message-item\">\n <div>\n <div v-if=\"message.role === 'user'\" class=\"ai-chat-msg-role ai-chat-msg-role-user\">{{ userLabel }}</div>\n <div v-else-if=\"message.role !== 'indicator'\" :class=\"getAssistantRoleClasses(message)\">\n <span :class=\"getAssistantIconClasses(message, index)\"><i :class=\"getAssistantIcon(message)\"></i></span>\n {{ getAssistantLabel(message) }}\n </div>\n <div class=\"ai-chat-message-body lh-base\">\n <h4 v-if=\"message.title\">{{ message.title }}</h4>\n <div v-html=\"message.htmlContent\"></div>\n <span class=\"message-buttons-container\" v-if=\"!isIndicator(message)\">\n <template v-if=\"metricsEnabled && message.role === 'assistant'\">\n <span class=\"ai-chat-message-assistant-feedback\" :data-message-id=\"message.id\">\n <button class=\"btn btn-sm btn-link text-success p-0 me-2 button-message-toolbox rate-up-btn\" @click=\"rateMessage(message, true, $event)\" :title=\"thumbsUpTitle\">\n <i class=\"fa-regular fa-thumbs-up\"></i>\n </button>\n <button class=\"btn btn-sm btn-link text-danger p-0 me-2 button-message-toolbox rate-down-btn\" @click=\"rateMessage(message, false, $event)\" :title=\"thumbsDownTitle\">\n <i class=\"fa-regular fa-thumbs-down\"></i>\n </button>\n </span>\n </template>\n <button v-if=\"textToSpeechEnabled && !isConversationMode && message.role === 'assistant' && !message.isStreaming\" class=\"btn btn-sm btn-link text-secondary p-0 me-1 button-message-toolbox\" :class=\"{ 'tts-playing': ttsPlayingMessageIndex === index }\" @click=\"toggleMessageTts(message, index)\" :title=\"ttsPlayingMessageIndex === index ? 'Pause audio' : 'Read aloud'\">\n <i :class=\"ttsPlayingMessageIndex === index ? 'fa-solid fa-circle-pause' : 'fa-solid fa-circle-play'\"></i>\n </button>\n <button class=\"btn btn-sm btn-link text-secondary p-0 button-message-toolbox\" @click=\"copyResponse(message.content)\" :title=\"copyTitle\">\n <i class=\"fa-solid fa-copy\"></i>\n </button>\n </span>\n </div>\n </div>\n </div>\n <div v-for=\"notification in notifications\" :key=\"'notif-' + notification.type\" class=\"ai-chat-notification\" :class=\"'ai-chat-notification-' + (notification.type || 'info') + ' ' + (notification.cssClass || '')\">\n <div class=\"ai-chat-notification-content\">\n <i v-if=\"notification.icon\" :class=\"notification.icon\" class=\"ai-chat-notification-icon\"></i>\n <span class=\"ai-chat-notification-text\">{{ notification.content }}</span>\n <button v-if=\"notification.dismissible\" class=\"btn btn-sm btn-link p-0 ms-2 ai-chat-notification-dismiss\" @click=\"dismissNotification(notification.type)\" title=\"Dismiss\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n <div v-if=\"notification.actions && notification.actions.length\" class=\"ai-chat-notification-actions\">\n <button v-for=\"action in notification.actions\" :key=\"action.name\" class=\"btn btn-sm\" :class=\"action.cssClass || 'btn-outline-secondary'\" @click=\"handleNotificationAction(notification.type, action.name)\">\n <i v-if=\"action.icon\" :class=\"action.icon\" class=\"me-1\"></i>\n {{ action.label }}\n </button>\n </div>\n </div>\n </div>\n `,\n indicatorTemplate: `\n <div class=\"ai-chat-msg-role ai-chat-msg-role-assistant\">\n <span class=\"ai-streaming-icon\"><i class=\"fa fa-robot\" style=\"display: inline-block;\"></i></span>\n Assistant\n </div>\n `\n };\n\n // Sanitize URLs to prevent javascript: protocol injection.\n function sanitizeUrl(url) {\n if (!url) return '';\n var trimmed = url.trim();\n if (/^javascript:/i.test(trimmed) || /^vbscript:/i.test(trimmed) || /^data:text\\/html/i.test(trimmed)) {\n return '';\n }\n return url;\n }\n\n // Safely HTML-encode a string using the DOM (avoids regex-based HTML filtering).\n function escapeHtmlEntities(text) {\n var span = document.createElement('span');\n span.textContent = text;\n return span.innerHTML;\n }\n\n function parsePixelValue(value) {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n\n if (typeof value !== 'string') {\n return null;\n }\n\n var parsed = parseFloat(value);\n return Number.isFinite(parsed) ? parsed : null;\n }\n\n function clamp(value, min, max) {\n return Math.min(Math.max(value, min), max);\n }\n\n function normalizeReference(reference) {\n if (!reference || typeof reference !== 'object') {\n return null;\n }\n\n const normalized = Object.assign({}, reference);\n normalized.index = normalized.index ?? normalized.Index ?? 0;\n normalized.text = normalized.text ?? normalized.Text ?? null;\n normalized.link = normalized.link ?? normalized.Link ?? null;\n\n return normalized;\n }\n\n function normalizeReferences(references) {\n if (!references || typeof references !== 'object') {\n return {};\n }\n\n const normalized = {};\n\n for (const [key, value] of Object.entries(references)) {\n normalized[key] = normalizeReference(value) ?? {};\n }\n\n return normalized;\n }\n\n const renderer = new marked.Renderer();\n\n // Modify the link rendering to open in a new tab\n renderer.link = function (data) {\n var href = sanitizeUrl(data.href);\n if (!href) return data.text || '';\n return `<a href=\"${href}\" target=\"_blank\" rel=\"noopener noreferrer\">${data.text}</a>`;\n };\n\n // Custom code block renderer with highlight.js integration and copy button.\n renderer.code = function (data) {\n var code = data.text || '';\n var lang = (data.lang || '').trim();\n var highlighted = code;\n\n if (typeof hljs !== 'undefined') {\n if (lang && hljs.getLanguage(lang)) {\n try {\n highlighted = hljs.highlight(code, { language: lang }).value;\n } catch (_) { }\n } else {\n try {\n highlighted = hljs.highlightAuto(code).value;\n } catch (_) { }\n }\n } else {\n highlighted = escapeHtmlEntities(code);\n }\n\n var langDisplay = lang ? escapeHtmlEntities(lang) : 'code';\n return `<div class=\"ai-code-block\"><div class=\"ai-code-header\"><span class=\"ai-code-lang\"><i class=\"fa-solid fa-code\"></i> ${langDisplay}</span><button type=\"button\" class=\"ai-code-copy-btn\" title=\"Copy code\"><i class=\"fa-regular fa-copy\"></i></button></div><pre><code class=\"hljs${lang ? ' language-' + lang : ''}\">${highlighted}</code></pre></div>`;\n };\n\n // Custom image renderer for generated images with thumbnail styling and download button.\n // Handles both URL and data-URI sources (data URIs are converted to blobs for download).\n renderer.image = function (data) {\n const src = sanitizeUrl(data.href);\n if (!src) return '';\n const alt = data.text || defaultConfig.generatedImageAltText;\n const maxWidth = defaultConfig.generatedImageMaxWidth;\n return `<div class=\"generated-image-container\">\n <img src=\"${src}\" alt=\"${alt}\" class=\"img-thumbnail\" style=\"max-width: ${maxWidth}px; height: auto;\" />\n <div class=\"mt-2\">\n <a href=\"${src}\" target=\"_blank\" download=\"${alt}\" title=\"${defaultConfig.downloadImageTitle}\" class=\"btn btn-sm btn-outline-secondary ai-download-image\">\n <i class=\"fa-solid fa-download\"></i>\n </a>\n </div>\n </div>`;\n };\n\n // Chart counter for unique IDs\n let chartCounter = 0;\n\n // Collector for charts discovered during marked parsing.\n let _pendingCharts = [];\n\n // Global chart config map: any page (e.g., Chat Interactions) that uses\n // the shared marked instance can call window.renderPendingCharts() after\n // its DOM update to render charts it didn't create itself.\n window.__chartConfigs = window.__chartConfigs || {};\n\n function createChartHtml(chartId) {\n return `<div class=\"chart-container\" style=\"position: relative; width: 100%; max-width: 560px; min-height: 420px;\">`\n + `<canvas id=\"${chartId}\"></canvas>`\n + `</div>`\n + `<div class=\"mt-2\">`\n + `<button type=\"button\" class=\"btn btn-sm btn-outline-secondary download-chart-btn\" data-chart-id=\"${chartId}\" title=\"${defaultConfig.downloadChartTitle}\">`\n + `<i class=\"fa-solid fa-download\"></i> ${defaultConfig.downloadChartButtonText}`\n + `</button>`\n + `</div>`;\n }\n\n // Register [chart:{...json...}] as a native marked block extension so the\n // markdown parser handles chart markers inline with surrounding text.\n marked.use({\n extensions: [{\n name: 'chart',\n level: 'block',\n start(src) {\n const idx = src.indexOf('[chart:');\n return idx >= 0 ? idx : undefined;\n },\n tokenizer(src) {\n const extracted = tryExtractChartMarker(src);\n if (!extracted || extracted.startIndex !== 0) {\n return undefined;\n }\n\n const chartId = `chat_chart_${++chartCounter}`;\n\n return {\n type: 'chart',\n raw: src.substring(0, extracted.endIndex),\n chartId: chartId,\n json: extracted.json,\n };\n },\n renderer(token) {\n _pendingCharts.push({ chartId: token.chartId, config: token.json });\n window.__chartConfigs[token.chartId] = token.json;\n return createChartHtml(token.chartId);\n }\n }]\n });\n\n // Extract a [chart:{...json...}] marker. This avoids regex issues with nested brackets.\n function tryExtractChartMarker(text) {\n const token = '[chart:';\n const start = text.indexOf(token);\n if (start < 0) {\n return null;\n }\n\n // Find JSON object boundary by balancing braces\n const jsonStart = start + token.length;\n let i = jsonStart;\n while (i < text.length && (text[i] === ' ' || text[i] === '\\n' || text[i] === '\\r' || text[i] === '\\t')) {\n i++;\n }\n\n if (i >= text.length || text[i] !== '{') {\n return null;\n }\n\n let depth = 0;\n let inString = false;\n let escape = false;\n\n for (; i < text.length; i++) {\n const ch = text[i];\n\n if (inString) {\n if (escape) {\n escape = false;\n continue;\n }\n if (ch === '\\\\') {\n escape = true;\n continue;\n }\n if (ch === '\"') {\n inString = false;\n }\n continue;\n }\n\n if (ch === '\"') {\n inString = true;\n continue;\n }\n\n if (ch === '{') {\n depth++;\n } else if (ch === '}') {\n depth--;\n if (depth === 0) {\n const jsonEnd = i;\n // Expect closing bracket after JSON\n const closeBracketIndex = text.indexOf(']', jsonEnd + 1);\n if (closeBracketIndex < 0) {\n return null;\n }\n\n const json = text.substring(jsonStart, jsonEnd + 1).trim();\n return {\n startIndex: start,\n endIndex: closeBracketIndex + 1,\n json: json\n };\n }\n }\n }\n\n return null;\n }\n\n function renderChartsInMessage(message) {\n if (!message || !message._pendingCharts || !message._pendingCharts.length) {\n return;\n }\n\n // Copy and clear pending charts immediately to prevent duplicate renders.\n const charts = [...message._pendingCharts];\n message._pendingCharts = [];\n\n // Defer to requestAnimationFrame so the browser has fully laid out the\n // canvas elements before Chart.js reads their dimensions.\n requestAnimationFrame(() => {\n for (const c of charts) {\n renderChartOnCanvas(c.chartId, c.config);\n }\n });\n }\n\n function renderChartOnCanvas(chartId, config) {\n const canvas = document.getElementById(chartId);\n if (!canvas) {\n return false;\n }\n\n if (typeof Chart === 'undefined') {\n console.warn('Chart.js is not loaded. To render interactive charts, include the Chart.js library on the page (e.g., <script src=\"https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.min.js\"></script>).');\n return false;\n }\n\n // When the canvas is inside a hidden container (e.g., a widget panel with\n // display:none), it has zero dimensions and Chart.js cannot render correctly.\n // Keep the config in __chartConfigs so renderPendingCharts() can retry later\n // once the container becomes visible.\n if (canvas.offsetParent === null) {\n window.__chartConfigs[chartId] = config;\n return false;\n }\n\n try {\n if (canvas._chartInstance) {\n canvas._chartInstance.destroy();\n }\n\n const cfg = typeof config === 'string' ? JSON.parse(config) : config;\n cfg.options ??= {};\n cfg.options.responsive = true;\n cfg.options.maintainAspectRatio = true;\n cfg.options.aspectRatio ??= 4 / 3;\n\n canvas._chartInstance = new Chart(canvas, cfg);\n delete window.__chartConfigs[chartId];\n return true;\n } catch (e) {\n console.error('Error creating chart:', e);\n return false;\n }\n }\n\n // Global function: renders any chart canvases whose configs are in the\n // global __chartConfigs map. Called by pages (e.g., Chat Interactions)\n // that share the marked instance but have their own rendering pipeline.\n window.renderPendingCharts = function () {\n if (typeof Chart === 'undefined') {\n return;\n }\n\n const configs = window.__chartConfigs;\n if (!configs) {\n return;\n }\n\n requestAnimationFrame(() => {\n for (const chartId of Object.keys(configs)) {\n renderChartOnCanvas(chartId, configs[chartId]);\n }\n });\n };\n\n // Parse markdown content via marked (which natively handles [chart:...] markers\n // through the registered extension) and collect pending chart configs for later\n // Chart.js rendering.\n function parseMarkdownContent(content, message) {\n _pendingCharts = [];\n const html = marked.parse(content, { renderer });\n message._pendingCharts = _pendingCharts.length > 0 ? [..._pendingCharts] : [];\n return DOMPurify.sanitize(html, { ADD_TAGS: ['canvas'], ADD_ATTR: ['target'] });\n }\n\n const initialize = (instanceConfig) => {\n\n const config = Object.assign({}, defaultConfig, instanceConfig);\n config.widget = Object.assign({}, defaultConfig.widget || {}, instanceConfig && instanceConfig.widget ? instanceConfig.widget : {});\n const hasWidgetConfig = !!(instanceConfig && instanceConfig.widget && instanceConfig.widget.chatWidgetContainer && instanceConfig.widget.chatWidgetStateName);\n // Keep defaultConfig in sync so renderers use overridden values\n defaultConfig = config;\n\n if (!config.signalRHubUrl) {\n console.error('The signalRHubUrl is required.');\n return;\n }\n\n if (!config.appElementSelector) {\n console.error('The appElementSelector is required.');\n return;\n }\n\n if (!config.chatContainerElementSelector) {\n console.error('The chatContainerElementSelector is required.');\n return;\n }\n\n if (!config.inputElementSelector) {\n console.error('The inputElementSelector is required.');\n return;\n }\n\n if (!config.sendButtonElementSelector) {\n console.error('The sendButtonElementSelector is required.');\n return;\n }\n\n const app = Vue.createApp({\n data() {\n return {\n inputElement: null,\n buttonElement: null,\n chatContainer: null,\n placeholder: null,\n isSessionStarted: false,\n isPlaceholderVisible: true,\n chatWidgetStateName: null,\n chatWidgetStateSession: null,\n chatWidgetLayoutKey: null,\n chatHistorySection: null,\n widgetContainerElement: null,\n widgetToggleButtonElement: null,\n widgetResetSizeButtonElement: null,\n widgetResizeObserver: null,\n widgetViewportResizeHandler: null,\n widgetDefaultWidth: null,\n widgetDefaultHeight: null,\n widgetIsInitialized: false,\n isStreaming: false,\n isNavigatingAway: false,\n autoScroll: true,\n stream: null,\n messages: [],\n notifications: [],\n prompt: '',\n documents: config.existingDocuments || [],\n isUploading: false,\n uploadErrors: [],\n isDragOver: false,\n documentBar: null,\n metricsEnabled: !!config.metricsEnabled,\n userLabel: config.userLabel,\n assistantLabel: config.assistantLabel,\n thumbsUpTitle: config.thumbsUpTitle,\n thumbsDownTitle: config.thumbsDownTitle,\n copyTitle: config.copyTitle,\n isRecording: false,\n mediaRecorder: null,\n preRecordingPrompt: '',\n micButton: null,\n speechToTextEnabled: config.chatMode === 'AudioInput' || config.chatMode === 'Conversation',\n textToSpeechEnabled: config.chatMode === 'Conversation' || !!config.textToSpeechEnabled,\n ttsVoiceName: config.ttsVoiceName || null,\n audioChunks: [],\n audioPlayQueue: [],\n isPlayingAudio: false,\n currentAudioElement: null,\n currentAudioUrl: null,\n ttsButton: null,\n ttsPlayingMessageIndex: -1,\n ttsAudioCache: {},\n ttsInstanceId: 'ai-chat-' + Math.random().toString(36).slice(2),\n singleResponseMode: !!config.singleResponseMode,\n conversationModeEnabled: config.chatMode === 'Conversation',\n conversationButton: null,\n isConversationMode: false,\n notificationDismissTimers: {},\n };\n },\n computed: {\n lastAssistantIndex() {\n for (var i = this.messages.length - 1; i >= 0; i--) {\n if (this.messages[i].role === 'assistant') {\n return i;\n }\n }\n return -1;\n }\n },\n methods: {\n handleBeforeUnload() {\n this.isNavigatingAway = true;\n },\n getStoredWidgetLayout() {\n if (!this.chatWidgetLayoutKey || !config.widget.persistLayout) {\n return {};\n }\n\n try {\n var storedLayout = localStorage.getItem(this.chatWidgetLayoutKey);\n return storedLayout ? JSON.parse(storedLayout) || {} : {};\n } catch (error) {\n console.warn('Failed to read widget layout state.', error);\n return {};\n }\n },\n saveStoredWidgetLayout(partialLayout) {\n if (!this.chatWidgetLayoutKey || !config.widget.persistLayout) {\n return;\n }\n\n var currentLayout = this.getStoredWidgetLayout();\n var nextLayout = Object.assign({}, currentLayout);\n\n if (partialLayout.panel !== undefined) {\n nextLayout.panel = Object.assign({}, currentLayout.panel || {}, partialLayout.panel || {});\n }\n\n if (partialLayout.toggle !== undefined) {\n nextLayout.toggle = Object.assign({}, currentLayout.toggle || {}, partialLayout.toggle || {});\n }\n\n localStorage.setItem(this.chatWidgetLayoutKey, JSON.stringify(nextLayout));\n },\n getElementSize(element, fallbackWidth, fallbackHeight) {\n if (!element) {\n return {\n width: fallbackWidth || 0,\n height: fallbackHeight || 0\n };\n }\n\n var rect = element.getBoundingClientRect();\n var computed = window.getComputedStyle(element);\n\n return {\n width: Math.round(rect.width || parsePixelValue(computed.width) || fallbackWidth || 0),\n height: Math.round(rect.height || parsePixelValue(computed.height) || fallbackHeight || 0)\n };\n },\n clampWidgetPosition(left, top, width, height) {\n var viewportPadding = 8;\n var maxLeft = Math.max(viewportPadding, window.innerWidth - width - viewportPadding);\n var maxTop = Math.max(viewportPadding, window.innerHeight - height - viewportPadding);\n\n return {\n left: Math.round(clamp(left, viewportPadding, maxLeft)),\n top: Math.round(clamp(top, viewportPadding, maxTop))\n };\n },\n applyAbsolutePosition(element, left, top) {\n if (!element) {\n return;\n }\n\n element.style.left = left + 'px';\n element.style.top = top + 'px';\n element.style.right = 'auto';\n element.style.bottom = 'auto';\n },\n getWidgetDefaultSize() {\n return {\n width: this.widgetDefaultWidth || parsePixelValue(config.widget.defaultWidth) || 380,\n height: this.widgetDefaultHeight || parsePixelValue(config.widget.defaultHeight) || 520\n };\n },\n persistWidgetPanelPosition() {\n if (!this.widgetContainerElement || !config.widget.persistLayout) {\n return;\n }\n\n var panelRect = this.widgetContainerElement.getBoundingClientRect();\n this.saveStoredWidgetLayout({\n panel: {\n left: Math.round(panelRect.left),\n top: Math.round(panelRect.top)\n }\n });\n },\n persistWidgetTogglePosition() {\n if (!this.widgetToggleButtonElement || !config.widget.persistLayout) {\n return;\n }\n\n var toggleRect = this.widgetToggleButtonElement.getBoundingClientRect();\n this.saveStoredWidgetLayout({\n toggle: {\n left: Math.round(toggleRect.left),\n top: Math.round(toggleRect.top)\n }\n });\n },\n persistWidgetPanelSize() {\n if (!this.widgetContainerElement || !config.widget.enableResizing || !config.widget.persistLayout) {\n return;\n }\n\n var defaultSize = this.getWidgetDefaultSize();\n var currentSize = this.getElementSize(this.widgetContainerElement, defaultSize.width, defaultSize.height);\n\n this.saveStoredWidgetLayout({\n panel: {\n width: Math.abs(currentSize.width - defaultSize.width) <= 1 ? null : currentSize.width,\n height: Math.abs(currentSize.height - defaultSize.height) <= 1 ? null : currentSize.height\n }\n });\n },\n updateWidgetResetSizeButtonVisibility() {\n if (!this.widgetResetSizeButtonElement) {\n return;\n }\n\n if (!config.widget.enableResizing || !this.widgetContainerElement) {\n this.widgetResetSizeButtonElement.classList.add('d-none');\n return;\n }\n\n var defaultSize = this.getWidgetDefaultSize();\n var currentSize = this.getElementSize(this.widgetContainerElement, defaultSize.width, defaultSize.height);\n var isResized =\n Math.abs(currentSize.width - defaultSize.width) > 1 ||\n Math.abs(currentSize.height - defaultSize.height) > 1 ||\n !!this.widgetContainerElement.style.width ||\n !!this.widgetContainerElement.style.height;\n\n this.widgetResetSizeButtonElement.classList.toggle('d-none', !isResized);\n },\n resetWidgetSize() {\n if (!this.widgetContainerElement || !config.widget.enableResizing) {\n return;\n }\n\n this.widgetContainerElement.style.removeProperty('width');\n this.widgetContainerElement.style.removeProperty('height');\n this.persistWidgetPanelSize();\n this.constrainWidgetElementsToViewport();\n this.updateWidgetResetSizeButtonVisibility();\n },\n restoreWidgetLayout() {\n var storedLayout = this.getStoredWidgetLayout();\n\n if (this.widgetContainerElement && config.widget.enableResizing) {\n if (Number.isFinite(storedLayout.panel && storedLayout.panel.width)) {\n this.widgetContainerElement.style.width = storedLayout.panel.width + 'px';\n } else {\n this.widgetContainerElement.style.removeProperty('width');\n }\n\n if (Number.isFinite(storedLayout.panel && storedLayout.panel.height)) {\n this.widgetContainerElement.style.height = storedLayout.panel.height + 'px';\n } else {\n this.widgetContainerElement.style.removeProperty('height');\n }\n }\n\n if (this.widgetContainerElement && config.widget.enableDragging &&\n Number.isFinite(storedLayout.panel && storedLayout.panel.left) &&\n Number.isFinite(storedLayout.panel && storedLayout.panel.top)) {\n this.applyAbsolutePosition(this.widgetContainerElement, storedLayout.panel.left, storedLayout.panel.top);\n }\n\n if (this.widgetToggleButtonElement && config.widget.enableDragging &&\n Number.isFinite(storedLayout.toggle && storedLayout.toggle.left) &&\n Number.isFinite(storedLayout.toggle && storedLayout.toggle.top)) {\n this.applyAbsolutePosition(this.widgetToggleButtonElement, storedLayout.toggle.left, storedLayout.toggle.top);\n }\n\n this.constrainWidgetElementsToViewport();\n this.updateWidgetResetSizeButtonVisibility();\n },\n attachDraggableWidgetElement(element, handle, layoutKey, suppressClickOnDrag) {\n if (!element || !handle || !config.widget.enableDragging) {\n return;\n }\n\n var activePointerId = null;\n var startX = 0;\n var startY = 0;\n var startLeft = 0;\n var startTop = 0;\n var dragged = false;\n var dragThreshold = 4;\n var interactiveSelector = 'button, a, input, textarea, select, option, label';\n\n var stopDragging = (event) => {\n if (activePointerId === null) {\n return;\n }\n\n if (event && event.pointerId !== undefined && event.pointerId !== activePointerId) {\n return;\n }\n\n document.removeEventListener('pointermove', onPointerMove);\n document.removeEventListener('pointerup', stopDragging);\n document.removeEventListener('pointercancel', stopDragging);\n element.classList.remove('ai-chat-widget-dragging');\n activePointerId = null;\n\n if (!dragged) {\n return;\n }\n\n if (layoutKey === 'panel') {\n this.persistWidgetPanelPosition();\n } else if (layoutKey === 'toggle') {\n this.persistWidgetTogglePosition();\n }\n\n if (suppressClickOnDrag) {\n element.dataset.dragSuppressClick = 'true';\n window.setTimeout(() => {\n if (element.dataset.dragSuppressClick === 'true') {\n element.dataset.dragSuppressClick = 'false';\n }\n }, 0);\n }\n };\n\n var onPointerMove = (event) => {\n if (activePointerId === null || event.pointerId !== activePointerId) {\n return;\n }\n\n var deltaX = event.clientX - startX;\n var deltaY = event.clientY - startY;\n\n if (!dragged && Math.hypot(deltaX, deltaY) < dragThreshold) {\n return;\n }\n\n dragged = true;\n\n var defaultSize = this.getWidgetDefaultSize();\n var currentSize = this.getElementSize(\n element,\n layoutKey === 'panel' ? defaultSize.width : 52,\n layoutKey === 'panel' ? defaultSize.height : 52);\n var nextPosition = this.clampWidgetPosition(\n startLeft + deltaX,\n startTop + deltaY,\n currentSize.width,\n currentSize.height);\n\n this.applyAbsolutePosition(element, nextPosition.left, nextPosition.top);\n };\n\n handle.addEventListener('pointerdown', (event) => {\n if (event.button !== 0) {\n return;\n }\n\n if (layoutKey === 'panel' && event.target.closest(interactiveSelector)) {\n return;\n }\n\n var rect = element.getBoundingClientRect();\n startX = event.clientX;\n startY = event.clientY;\n startLeft = rect.left;\n startTop = rect.top;\n dragged = false;\n activePointerId = event.pointerId;\n element.classList.add('ai-chat-widget-dragging');\n\n if (handle.setPointerCapture) {\n handle.setPointerCapture(event.pointerId);\n }\n\n document.addEventListener('pointermove', onPointerMove);\n document.addEventListener('pointerup', stopDragging);\n document.addEventListener('pointercancel', stopDragging);\n event.preventDefault();\n });\n },\n constrainWidgetElementsToViewport() {\n if (this.widgetContainerElement && this.widgetContainerElement.style.left) {\n var panelDefaultSize = this.getWidgetDefaultSize();\n var panelSize = this.getElementSize(this.widgetContainerElement, panelDefaultSize.width, panelDefaultSize.height);\n var panelRect = this.widgetContainerElement.getBoundingClientRect();\n var clampedPanel = this.clampWidgetPosition(panelRect.left, panelRect.top, panelSize.width, panelSize.height);\n\n this.applyAbsolutePosition(this.widgetContainerElement, clampedPanel.left, clampedPanel.top);\n\n if (config.widget.persistLayout) {\n this.persistWidgetPanelPosition();\n }\n }\n\n if (this.widgetToggleButtonElement && this.widgetToggleButtonElement.style.left) {\n var toggleSize = this.getElementSize(this.widgetToggleButtonElement, 52, 52);\n var toggleRect = this.widgetToggleButtonElement.getBoundingClientRect();\n var clampedToggle = this.clampWidgetPosition(toggleRect.left, toggleRect.top, toggleSize.width, toggleSize.height);\n\n this.applyAbsolutePosition(this.widgetToggleButtonElement, clampedToggle.left, clampedToggle.top);\n\n if (config.widget.persistLayout) {\n this.persistWidgetTogglePosition();\n }\n }\n },\n handleDragOver(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = true;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.add('ai-chat-drag-over');\n },\n handleDragLeave(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = false;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.remove('ai-chat-drag-over');\n },\n handleDrop(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = false;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.remove('ai-chat-drag-over');\n if (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n this.uploadFiles(e.dataTransfer.files);\n }\n },\n triggerFileInput() {\n if (!config.sessionDocumentsEnabled) return;\n var fileInput = document.getElementById('ai-chat-doc-input');\n if (fileInput) fileInput.click();\n },\n handleFileInputChange(e) {\n var files = e.target.files;\n if (files && files.length > 0) {\n this.uploadFiles(files);\n }\n e.target.value = '';\n },\n async uploadFiles(files) {\n if (!config.uploadDocumentUrl) return;\n\n var sessionId = this.getSessionId();\n var profileId = this.getProfileId();\n\n if (!sessionId && !profileId) {\n console.warn('Cannot upload documents without a session or profile.');\n return;\n }\n\n this.isUploading = true;\n this.uploadErrors = [];\n this.renderDocumentBar();\n try {\n var formData = new FormData();\n if (sessionId) {\n formData.append('sessionId', sessionId);\n } else {\n formData.append('profileId', profileId);\n }\n for (var i = 0; i < files.length; i++) {\n formData.append('files', files[i]);\n }\n\n var response = await fetch(config.uploadDocumentUrl, {\n method: 'POST',\n body: formData\n });\n\n if (!response.ok) {\n var errorText = await response.text();\n var uploadError = this.extractReadableErrorMessage(errorText, 'Upload failed. Please try again.');\n console.error('Upload failed:', errorText);\n this.uploadErrors = [{ fileName: '', error: uploadError }];\n return;\n }\n\n var result = await response.json();\n\n // If the server created a new session, initialize it.\n if (result.sessionId && !sessionId) {\n this.initializeSession(result.sessionId);\n }\n\n if (result.uploaded && result.uploaded.length > 0) {\n for (var j = 0; j < result.uploaded.length; j++) {\n this.documents.push(result.uploaded[j]);\n }\n }\n if (result.failed && result.failed.length > 0) {\n this.uploadErrors = result.failed;\n }\n } catch (err) {\n console.error('Upload error:', err);\n this.uploadErrors = [{ fileName: '', error: 'Upload failed. Please try again.' }];\n } finally {\n this.isUploading = false;\n this.renderDocumentBar();\n }\n },\n async removeDocument(doc) {\n if (!config.removeDocumentUrl) return;\n\n try {\n var sessionId = this.getSessionId();\n var response = await fetch(config.removeDocumentUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ itemId: sessionId, documentId: doc.documentId })\n });\n\n if (response.ok) {\n var idx = this.documents.indexOf(doc);\n if (idx > -1) this.documents.splice(idx, 1);\n } else {\n var errorText = await response.text();\n var removeError = this.extractReadableErrorMessage(errorText, 'Failed to remove document. Please try again.');\n console.error('Failed to remove document:', response.status, errorText);\n this.uploadErrors = [{ fileName: doc.fileName || '', error: removeError }];\n this.renderDocumentBar();\n }\n } catch (err) {\n console.error('Remove document error:', err);\n this.uploadErrors = [{ fileName: doc.fileName || '', error: 'Failed to remove document. Please try again.' }];\n this.renderDocumentBar();\n }\n },\n formatFileSize(bytes) {\n if (bytes < 1024) return bytes + ' B';\n if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';\n return (bytes / (1024 * 1024)).toFixed(1) + ' MB';\n },\n renderDocumentBar() {\n if (!this.documentBar) return;\n\n if (!config.sessionDocumentsEnabled) {\n this.documentBar.classList.add('d-none');\n return;\n }\n\n this.documentBar.classList.remove('d-none');\n\n var html = '<div class=\"ai-chat-doc-bar p-2\">';\n html += '<div class=\"d-flex flex-wrap align-items-center gap-1\">';\n\n for (var i = 0; i < this.documents.length; i++) {\n var doc = this.documents[i];\n var name = doc.fileName || 'Document';\n if (name.length > 20) name = name.substring(0, 17) + '...';\n html += '<span class=\"badge bg-secondary bg-opacity-25 text-dark d-inline-flex align-items-center gap-1 px-2 py-1\" style=\"font-size: 0.8rem;\" title=\"' + this.escapeHtml(doc.fileName || '') + '\">';\n html += '<i class=\"fa-solid fa-file-lines\" style=\"font-size: 0.7rem;\"></i> ';\n html += this.escapeHtml(name);\n html += ' <button type=\"button\" class=\"btn-close btn-close-sm ms-1\" style=\"font-size: 0.5rem;\" data-doc-index=\"' + i + '\" aria-label=\"Remove\"></button>';\n html += '</span>';\n }\n\n for (var m = 0; m < this.uploadErrors.length; m++) {\n var failedItem = this.uploadErrors[m];\n var failedName = failedItem.fileName || 'File';\n var errorMsg = failedItem.error || 'Upload failed';\n if (failedName.length > 15) failedName = failedName.substring(0, 12) + '...';\n html += '<span class=\"badge bg-danger bg-opacity-25 text-danger d-inline-flex align-items-center gap-1 px-2 py-1\" style=\"font-size: 0.8rem;\" title=\"' + this.escapeHtml((failedItem.fileName || '') + ': ' + errorMsg) + '\">';\n html += '<i class=\"fa-solid fa-circle-exclamation\" style=\"font-size: 0.7rem;\"></i> ';\n html += this.escapeHtml(failedName);\n html += ' <button type=\"button\" class=\"btn-close btn-close-sm ms-1\" style=\"font-size: 0.5rem;\" data-error-index=\"' + m + '\" aria-label=\"Dismiss\"></button>';\n html += '</span>';\n }\n\n if (this.isUploading) {\n html += '<span class=\"badge bg-info bg-opacity-25 text-dark d-inline-flex align-items-center gap-1 px-2 py-1\" style=\"font-size: 0.8rem;\">';\n html += '<span class=\"spinner-border spinner-border-sm\" style=\"width: 0.7rem; height: 0.7rem;\"></span> Uploading...';\n html += '</span>';\n }\n\n html += '<button type=\"button\" class=\"btn btn-sm btn-outline-secondary rounded-pill ai-chat-doc-add-btn d-inline-flex align-items-center gap-1\" style=\"font-size: 0.75rem; padding: 0.15rem 0.5rem;\" title=\"Attach documents\">';\n html += '<i class=\"fa-solid fa-paperclip\"></i>';\n if (this.documents.length === 0 && !this.isUploading) {\n html += ' <span>Attach files</span>';\n }\n html += '</button>';\n html += '</div>';\n if (config.supportedExtensionsText) {\n html += '<div class=\"small text-muted mt-2\">Supported formats: ' + this.escapeHtml(config.supportedExtensionsText) + '</div>';\n }\n\n html += '</div>';\n\n this.documentBar.replaceChildren(DOMPurify.sanitize(html, { RETURN_DOM_FRAGMENT: true }));\n\n // Bind remove handlers\n var self = this;\n var closeButtons = this.documentBar.querySelectorAll('[data-doc-index]');\n for (var j = 0; j < closeButtons.length; j++) {\n closeButtons[j].addEventListener('click', (function (idx) {\n return function (e) {\n e.preventDefault();\n e.stopPropagation();\n var docToRemove = self.documents[idx];\n if (docToRemove) self.removeDocument(docToRemove);\n };\n })(parseInt(closeButtons[j].getAttribute('data-doc-index'))));\n }\n\n // Bind error dismiss handlers\n var errorCloseButtons = this.documentBar.querySelectorAll('[data-error-index]');\n for (var n = 0; n < errorCloseButtons.length; n++) {\n errorCloseButtons[n].addEventListener('click', (function (idx) {\n return function (e) {\n e.preventDefault();\n e.stopPropagation();\n self.uploadErrors.splice(idx, 1);\n self.renderDocumentBar();\n };\n })(parseInt(errorCloseButtons[n].getAttribute('data-error-index'))));\n }\n\n // Bind add button\n var addBtn = this.documentBar.querySelector('.ai-chat-doc-add-btn');\n if (addBtn) {\n addBtn.addEventListener('click', function (e) {\n e.preventDefault();\n self.triggerFileInput();\n });\n }\n },\n escapeHtml(text) {\n var div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n },\n extractReadableErrorMessage(errorText, fallbackMessage) {\n if (!errorText || typeof errorText !== 'string') {\n return fallbackMessage;\n }\n\n var trimmed = errorText.trim();\n if (!trimmed) {\n return fallbackMessage;\n }\n\n if (trimmed.startsWith('{') || trimmed.startsWith('[')) {\n try {\n var parsed = JSON.parse(trimmed);\n var message = parsed?.error || parsed?.message || parsed?.title || parsed?.detail;\n return typeof message === 'string' && message.trim()\n ? message.trim()\n : fallbackMessage;\n } catch (err) {\n return fallbackMessage;\n }\n }\n\n if (/<[^>]+>/.test(trimmed)) {\n return fallbackMessage;\n }\n\n return trimmed;\n },\n normalizeAssistantAppearance(appearance) {\n if (!appearance) {\n return null;\n }\n\n var label = typeof appearance.label === 'string' ? appearance.label.trim() : '';\n var icon = typeof appearance.icon === 'string' ? appearance.icon.trim() : '';\n var cssClass = typeof appearance.cssClass === 'string' ? appearance.cssClass.trim() : '';\n var disableStreamingAnimation = !!appearance.disableStreamingAnimation;\n\n if (!label && !icon && !cssClass && !disableStreamingAnimation) {\n return null;\n }\n\n return {\n label: label,\n icon: icon,\n cssClass: cssClass,\n disableStreamingAnimation: disableStreamingAnimation,\n };\n },\n getAssistantLabel(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return appearance && appearance.label ? appearance.label : this.assistantLabel;\n },\n getAssistantRoleClasses(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n var classes = ['ai-chat-msg-role'];\n\n if (appearance && appearance.cssClass) {\n classes.push(appearance.cssClass);\n } else {\n classes.push('ai-chat-msg-role-assistant');\n }\n\n return classes;\n },\n getAssistantIconClasses(message, index) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return [this.shouldAnimateAssistantIcon(message, index) ? 'ai-streaming-icon' : 'ai-bot-icon', appearance && appearance.cssClass ? appearance.cssClass : ''];\n },\n getAssistantIcon(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return appearance && appearance.icon ? appearance.icon : 'fa fa-robot';\n },\n shouldAnimateAssistantIcon(message, index) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return !!message &&\n message.isStreaming &&\n index === this.lastAssistantIndex &&\n !(appearance && appearance.disableStreamingAnimation);\n },\n async startConnection() {\n this.connection = new signalR.HubConnectionBuilder()\n .withUrl(config.signalRHubUrl)\n .withAutomaticReconnect()\n .build();\n\n // Allow long-running operations (e.g., multi-step MCP tool calls)\n // without the client disconnecting prematurely.\n this.connection.serverTimeoutInMilliseconds = 600000;\n this.connection.keepAliveIntervalInMilliseconds = 15000;\n\n this.connection.on(\"LoadSession\", (data) => {\n this.initializeSession(data.sessionId, true);\n this.messages = [];\n this.documents = data.documents || [];\n\n (data.messages ?? []).forEach(msg => {\n this.addMessage(msg);\n\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n });\n });\n\n // Update feedback icons in the DOM after all messages have rendered.\n this.$nextTick(() => {\n this.refreshAllFeedbackIcons();\n });\n\n // When the session is new (no messages) and an initial prompt is configured,\n // automatically send it as the first user message to trigger an AI response.\n if (this.messages.length === 0 && config.initialPrompt) {\n this.prompt = config.initialPrompt;\n this.sendMessage();\n }\n });\n\n this.connection.on(\"ReceiveError\", (error) => {\n console.error(\"SignalR Error: \", error);\n\n if (this.isRecording) {\n this.stopRecording();\n }\n\n // If this is a widget with a stale cached session (e.g., profile was deleted),\n // clear the cached session and start fresh with the current profile.\n if (this.widgetIsInitialized && !this.isSessionStarted && !this._attemptedSessionRecovery) {\n this._attemptedSessionRecovery = true;\n localStorage.removeItem(this.chatWidgetStateSession);\n this.startNewSession();\n }\n });\n\n this.connection.on(\"MessageRated\", (messageId, userRating) => {\n var msg = this.messages.find(m => m.id === messageId);\n if (msg) {\n msg.userRating = userRating;\n }\n });\n\n this.connection.on(\"ReceiveTranscript\", (sessionId, text, isFinal) => {\n if (this.isConversationMode) {\n if (!isFinal && text) {\n this._conversationPartialTranscript = text;\n var escaped = text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n var html = '<p class=\"ai-partial-transcript\">' + escaped + '</p>';\n\n // Show partial transcript as a live user message.\n if (!this._conversationPartialMessage) {\n this.hidePlaceholder();\n this._conversationPartialMessage = {\n role: 'user',\n content: text,\n htmlContent: html,\n isPartial: true\n };\n this.messages.push(this._conversationPartialMessage);\n } else {\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = html;\n }\n this.scrollToBottom();\n }\n return;\n }\n\n if (text && !this._audioInputSent) {\n this.prompt = this.preRecordingPrompt + text;\n if (this.inputElement) {\n this.inputElement.value = this.prompt;\n this.inputElement.dispatchEvent(new Event('input'));\n }\n }\n });\n\n this.connection.on(\"ReceiveConversationUserMessage\", (sessionId, text) => {\n if (text) {\n this.stopAudio();\n\n // If there's an interrupted assistant message still streaming,\n // mark it as done to stop the spinner animation.\n if (this._conversationAssistantMessage) {\n var oldMsg = this.messages[this._conversationAssistantMessage.index];\n if (oldMsg) {\n oldMsg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Replace the partial transcript message with the final one.\n if (this._conversationPartialMessage) {\n var escaped = text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = '<p>' + escaped + '</p>';\n this._conversationPartialMessage.isPartial = false;\n this._conversationPartialMessage = null;\n } else {\n this.addMessage({\n role: 'user',\n content: text\n });\n }\n this.scrollToBottom();\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantToken\", (sessionId, messageId, token, responseId, appearance) => {\n if (!this._conversationAssistantMessage) {\n this.stopAudio();\n this.hideTypingIndicator();\n\n // Ensure no stale streaming indicators remain from prior messages.\n for (var j = 0; j < this.messages.length; j++) {\n if (this.messages[j].isStreaming) {\n this.messages[j].isStreaming = false;\n }\n }\n\n var msgIndex = this.messages.length;\n var newMessage = {\n id: messageId,\n role: \"assistant\",\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n userRating: null,\n appearance: this.normalizeAssistantAppearance(appearance),\n };\n this.messages.push(newMessage);\n this._conversationAssistantMessage = { index: msgIndex, content: '' };\n }\n\n this._conversationAssistantMessage.content += token;\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n if (!msg.appearance) {\n msg.appearance = this.normalizeAssistantAppearance(appearance);\n }\n msg.content = this._conversationAssistantMessage.content;\n msg.htmlContent = parseMarkdownContent(msg.content, msg);\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n this.scrollToBottom();\n });\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantComplete\", (sessionId, messageId) => {\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n });\n\n this.connection.on(\"ReceiveAudioChunk\", (sessionId, base64Audio, contentType) => {\n if (base64Audio) {\n const binaryString = atob(base64Audio);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n this.audioChunks.push(bytes);\n }\n });\n\n this.connection.on(\"ReceiveAudioComplete\", (sessionId) => {\n this.playCollectedAudio();\n });\n\n this.connection.on(\"ReceiveNotification\", (notification) => {\n this.receiveNotification(notification);\n });\n\n this.connection.on(\"UpdateNotification\", (notification) => {\n this.updateNotification(notification);\n });\n\n this.connection.on(\"RemoveNotification\", (notificationType) => {\n this.removeNotification(notificationType);\n });\n\n this.connection.onreconnecting(() => {\n console.warn(\"SignalR: reconnecting...\");\n });\n\n this.connection.onreconnected(() => {\n console.info(\"SignalR: reconnected.\");\n\n if (this.isSessionStarted) {\n this.reloadCurrentSession();\n } else if (config.autoCreateSession) {\n this.startNewSession();\n }\n });\n\n this.connection.onclose((error) => {\n if (this.isNavigatingAway) {\n return;\n }\n\n if (error) {\n console.warn(\"SignalR connection closed with error:\", error.message || error);\n }\n });\n\n try {\n await this.connection.start();\n } catch (err) {\n console.error(\"SignalR Connection Error: \", err);\n }\n },\n addMessageInternal(message) {\n if (message.role === 'assistant') {\n message.appearance = this.normalizeAssistantAppearance(message.appearance);\n }\n\n if (message.content && !message.htmlContent) {\n message.htmlContent = parseMarkdownContent(message.content, message);\n }\n this.fireEvent(new CustomEvent(\"addingOpenAIPromotMessage\", { detail: { message: message } }));\n this.messages.push(message);\n\n this.$nextTick(() => {\n this.fireEvent(new CustomEvent(\"addedOpenAIPromotMessage\", { detail: { message: message } }));\n });\n },\n addMessage(message) {\n\n // Ensure userRating is always defined for Vue reactivity.\n if (message.userRating === undefined) {\n message.userRating = null;\n }\n\n if (message.content) {\n let processedContent = message.content.trim();\n message.references = normalizeReferences(message.references);\n\n if (message.references && typeof message.references === \"object\" && Object.keys(message.references).length) {\n\n // Only include references that were actually cited in the response.\n const citedRefs = Object.entries(message.references).filter(([key]) => processedContent.includes(key));\n\n if (citedRefs.length) {\n // Sort by original index so display indices follow a natural order.\n citedRefs.sort(([, a], [, b]) => a.index - b.index);\n\n // Phase 1: Replace all markers with unique placeholders.\n let displayIndex = 1;\n for (const [key, value] of citedRefs) {\n const placeholder = `__CITE_${value.index}__`;\n processedContent = processedContent.replaceAll(key, placeholder);\n value._displayIndex = displayIndex++;\n value._placeholder = placeholder;\n }\n\n // Phase 2: Replace placeholders with sequential display indices.\n for (const [, value] of citedRefs) {\n processedContent = processedContent.replaceAll(value._placeholder, `<sup><strong>${value._displayIndex}</strong></sup>`);\n }\n\n // if we have multiple references, add a comma to ensure we don't concatenate numbers.\n processedContent = processedContent.replaceAll('</strong></sup><sup>', '</strong></sup><sup>,</sup><sup>');\n\n processedContent += '<br><br>';\n\n for (const [key, value] of citedRefs) {\n const label = value.text || key;\n processedContent += value.link\n ? `**${value._displayIndex}**. [${label}](${value.link})<br>`\n : `**${value._displayIndex}**. ${label}<br>`;\n }\n }\n }\n\n message.content = processedContent;\n message.htmlContent = parseMarkdownContent(processedContent, message);\n }\n\n this.addMessageInternal(message);\n this.hidePlaceholder();\n\n this.$nextTick(() => {\n // Render any pending charts once the DOM is updated\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n addMessages(messages) {\n\n for (let i = 0; i < messages.length; i++) {\n this.addMessageInternal(messages[i]);\n }\n\n this.hidePlaceholder();\n this.$nextTick(() => {\n this.scrollToBottom();\n });\n },\n hidePlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.add('d-none');\n }\n this.isPlaceholderVisible = false;\n },\n showPlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.remove('d-none');\n }\n this.isPlaceholderVisible = true;\n },\n isOrchestratorAvailable() {\n return config.isOrchestratorAvailable !== false;\n },\n applyOrchestratorAvailability() {\n if (this.isOrchestratorAvailable()) {\n return true;\n }\n\n const unavailableMessage = config.orchestratorUnavailableMessage || \"This orchestrator is not currently available.\";\n\n if (this.inputElement) {\n this.inputElement.disabled = true;\n this.inputElement.value = '';\n this.inputElement.placeholder = unavailableMessage;\n }\n\n if (this.buttonElement) {\n this.buttonElement.disabled = true;\n }\n\n if (this.micButtonElement) {\n this.micButtonElement.disabled = true;\n this.micButtonElement.style.display = 'none';\n }\n\n if (this.conversationButtonElement) {\n this.conversationButtonElement.disabled = true;\n this.conversationButtonElement.style.display = 'none';\n }\n\n return false;\n },\n fireEvent(event) {\n document.dispatchEvent(event);\n },\n isIndicator(message) {\n return message.role === 'indicator';\n },\n sendMessage() {\n if (!this.applyOrchestratorAvailability()) {\n return;\n }\n\n let trimmedPrompt = this.prompt.trim();\n\n if (!trimmedPrompt) {\n return;\n }\n\n // Stop any active recording before sending.\n if (this.isRecording) {\n this.stopRecording();\n }\n\n // Prevent stale ReceiveTranscript events from repopulating the prompt.\n this._audioInputSent = true;\n\n // In single-response mode, clear all previous messages.\n if (this.singleResponseMode) {\n this.messages.splice(0, this.messages.length);\n }\n\n this.addMessage({\n role: 'user',\n content: trimmedPrompt\n });\n\n this.streamMessage(this.getProfileId(), trimmedPrompt, null);\n this.inputElement.value = '';\n this.prompt = '';\n },\n startRecording() {\n if (this.isRecording || !this.connection) {\n return;\n }\n\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this.preRecordingPrompt = this.prompt;\n this._audioInputSent = false;\n\n var subject = new signalR.Subject();\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var pendingChunk = Promise.resolve();\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n subject.next(base64);\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => subject.complete());\n });\n\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"SendAudioStream\", profileId, sessionId, subject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n this.updateMicButton();\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n });\n },\n stopRecording() {\n if (!this.isRecording || !this.mediaRecorder) {\n return;\n }\n\n this.mediaRecorder.stop();\n this.isRecording = false;\n this.updateMicButton();\n },\n toggleRecording() {\n if (this.isRecording) {\n this.stopRecording();\n } else {\n this.startRecording();\n }\n },\n updateMicButton() {\n if (!this.micButton) {\n return;\n }\n\n if (this.isRecording) {\n this.micButton.classList.add('stt-recording');\n this.micButton.innerHTML = '<i class=\"fa-solid fa-stop\"></i>';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '<i class=\"fa-solid fa-microphone\"></i>';\n }\n },\n streamMessage(profileId, trimmedPrompt, sessionProfileId) {\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n\n this.streamingStarted();\n this.showTypingIndicator();\n this.autoScroll = true;\n\n var content = '';\n var references = {};\n var lastResponseId = null;\n\n // Get the index after showing typing indicator.\n var messageIndex = this.messages.length;\n var currentSessionId = this.getSessionId();\n\n this.stream = this.connection.stream(\"SendMessage\", profileId, trimmedPrompt, currentSessionId, sessionProfileId)\n .subscribe({\n next: (chunk) => {\n let message = this.messages[messageIndex];\n\n if (!message) {\n\n if (chunk.sessionId && !currentSessionId) {\n this.initializeSession(chunk.sessionId);\n }\n\n this.hideTypingIndicator();\n // Re-assign the index after hiding the typing indicator.\n messageIndex = this.messages.length;\n let newMessage = {\n id: chunk.messageId,\n role: \"assistant\",\n title: chunk.title,\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n userRating: null,\n };\n\n this.messages.push(newMessage);\n\n message = newMessage;\n }\n\n if (chunk.title && (!message.title || message.title !== chunk.title)) {\n message.title = chunk.title;\n }\n\n if (chunk.references && typeof chunk.references === \"object\" && Object.keys(chunk.references).length) {\n\n for (const [key, value] of Object.entries(chunk.references)) {\n references[key] = normalizeReference(value) ?? {};\n }\n }\n\n if (chunk.content) {\n\n // When the responseId changes (e.g., after an internal tool call),\n // insert a line break to visually separate response segments.\n if (chunk.responseId && lastResponseId && chunk.responseId !== lastResponseId) {\n content += '\\n\\n';\n }\n\n if (chunk.responseId) {\n lastResponseId = chunk.responseId;\n }\n\n let processedContent = chunk.content;\n\n for (const [key, value] of Object.entries(references)) {\n processedContent = processedContent.replaceAll(key, `<sup><strong>${value.index}</strong></sup>`);\n }\n\n // Append processed content to the message.\n // if we have multiple references, add a comma to ensure we don't concatenate numbers.\n content += processedContent.replaceAll('</strong></sup><sup>', '</strong></sup><sup>,</sup><sup>');\n }\n\n // Update the existing message\n message.content = content;\n\n message.htmlContent = parseMarkdownContent(content, message);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n complete: () => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n if (!msg || !msg.content) {\n // No content received at all.\n this.hideTypingIndicator();\n }\n\n // Trigger text-to-speech only in conversation mode.\n if (this.isConversationMode && this.textToSpeechEnabled && msg && msg.content) {\n this.synthesizeSpeech(msg.content);\n }\n\n this.stream?.dispose();\n this.stream = null;\n },\n error: (err) => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n this.hideTypingIndicator();\n\n if (!this.isNavigatingAway) {\n this.addMessage(this.getServiceDownMessage());\n }\n\n this.stream?.dispose();\n this.stream = null;\n\n console.error(\"Stream error:\", err);\n }\n });\n },\n getServiceDownMessage() {\n let newMessage = {\n role: \"assistant\",\n content: \"Our service is currently unavailable. Please try again later. We apologize for the inconvenience.\",\n htmlContent: \"\",\n };\n\n return newMessage;\n },\n processReferences(references, messageIndex) {\n references = normalizeReferences(references);\n\n if (Object.keys(references).length) {\n\n let message = this.messages[messageIndex];\n const content = message.content || '';\n\n // Only include references that were actually cited in the response.\n // Check both raw [doc:N] markers and already-rendered <sup> tags from streaming.\n const citedRefs = Object.entries(references).filter(([key, value]) =>\n content.includes(key) || content.includes(`<sup><strong>${value.index}</strong></sup>`)\n );\n\n if (!citedRefs.length) {\n return;\n }\n\n // Sort by original index so display indices follow a natural order.\n citedRefs.sort(([, a], [, b]) => a.index - b.index);\n\n // Phase 1: Replace all markers with unique placeholders to avoid collisions during remapping.\n let processed = content.trim();\n let displayIndex = 1;\n for (const [key, value] of citedRefs) {\n const placeholder = `__CITE_${value.index}__`;\n processed = processed.replaceAll(key, placeholder);\n processed = processed.replaceAll(`<sup><strong>${value.index}</strong></sup>`, placeholder);\n value._displayIndex = displayIndex++;\n value._placeholder = placeholder;\n }\n\n // Phase 2: Replace placeholders with sequential display indices.\n for (const [, value] of citedRefs) {\n processed = processed.replaceAll(value._placeholder, `<sup><strong>${value._displayIndex}</strong></sup>`);\n }\n\n processed = processed.replaceAll('</strong></sup><sup>', '</strong></sup><sup>,</sup><sup>');\n\n processed += '<br><br>';\n\n for (const [key, value] of citedRefs) {\n const label = value.text || key;\n processed += value.link\n ? `**${value._displayIndex}**. [${label}](${value.link})<br>`\n : `**${value._displayIndex}**. ${label}<br>`;\n }\n\n message.content = processed;\n message.htmlContent = parseMarkdownContent(processed, message);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n }\n },\n streamingStarted() {\n var stopIcon = this.buttonElement.getAttribute('data-stop-icon');\n\n if (stopIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(stopIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n if (this.inputElement) {\n this.inputElement.setAttribute('disabled', 'disabled');\n }\n },\n streamingFinished() {\n var startIcon = this.buttonElement.getAttribute('data-start-icon');\n\n if (startIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(startIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n if (this.inputElement) {\n this.inputElement.removeAttribute('disabled');\n this.inputElement.focus();\n }\n\n // Directly manipulate the DOM to stop all streaming animations.\n if (this.chatContainer) {\n var icons = this.chatContainer.querySelectorAll('.ai-streaming-icon');\n for (var i = 0; i < icons.length; i++) {\n icons[i].classList.remove('ai-streaming-icon');\n icons[i].classList.add('ai-bot-icon');\n }\n }\n\n // Also update Vue data for consistency.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n },\n handleExternalTtsStop(e) {\n if (e?.detail?.sourceId === this.ttsInstanceId) {\n return;\n }\n\n this.stopAudio(false);\n },\n synthesizeSpeech(text, cacheIndex) {\n if (!this.textToSpeechEnabled || !text || !this.connection) {\n return;\n }\n\n this.audioChunks = [];\n this.isPlayingAudio = true;\n this._ttsCacheIndex = cacheIndex !== undefined ? cacheIndex : -1;\n\n this.connection.invoke(\"SynthesizeSpeech\", this.getProfileId(), this.getSessionId(), text, this.ttsVoiceName)\n .catch(err => {\n console.error(\"TTS synthesis error:\", err);\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this._ttsCacheIndex = -1;\n });\n },\n toggleMessageTts(message, index) {\n if (this.ttsPlayingMessageIndex === index) {\n this.stopAudio();\n return;\n }\n\n this.stopAudio(false);\n window.dispatchEvent(new CustomEvent('crestapps-ai-chat-stop-tts', {\n detail: { sourceId: this.ttsInstanceId }\n }));\n this.ttsPlayingMessageIndex = index;\n\n if (this.ttsAudioCache[index]) {\n this.playAudioBlob(this.ttsAudioCache[index]);\n return;\n }\n\n this.synthesizeSpeech(message.content, index);\n },\n playCollectedAudio() {\n if (this.audioChunks.length === 0) {\n if (!this.currentAudioElement && this.audioPlayQueue.length === 0) {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n }\n return;\n }\n\n const totalLength = this.audioChunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const combined = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of this.audioChunks) {\n combined.set(chunk, offset);\n offset += chunk.length;\n }\n this.audioChunks = [];\n\n const blob = new Blob([combined], { type: 'audio/mp3' });\n\n if (this._ttsCacheIndex >= 0) {\n this.ttsAudioCache[this._ttsCacheIndex] = blob;\n this._ttsCacheIndex = -1;\n }\n\n // If audio is already playing, queue this blob for sequential playback.\n if (this.currentAudioElement) {\n this.audioPlayQueue.push(blob);\n return;\n }\n\n this.playAudioBlob(blob);\n },\n playAudioBlob(blob) {\n const url = URL.createObjectURL(blob);\n const audio = new Audio(url);\n\n this.currentAudioUrl = url;\n this.currentAudioElement = audio;\n this.isPlayingAudio = true;\n\n audio.addEventListener('ended', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.addEventListener('error', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.play().catch(err => {\n console.error(\"Audio playback error:\", err);\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n });\n },\n playNextInQueue() {\n if (this.audioPlayQueue.length > 0) {\n var nextBlob = this.audioPlayQueue.shift();\n this.playAudioBlob(nextBlob);\n } else {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.conversationModeOnAudioEnded();\n }\n },\n stopAudio() {\n if (this.currentAudioElement) {\n this.currentAudioElement.pause();\n this.currentAudioElement.currentTime = 0;\n this.currentAudioElement = null;\n }\n if (this.currentAudioUrl) {\n URL.revokeObjectURL(this.currentAudioUrl);\n this.currentAudioUrl = null;\n }\n this.audioChunks = [];\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n },\n toggleConversationMode() {\n if (this.isConversationMode) {\n this.stopConversationMode();\n } else {\n this.startConversationMode();\n }\n },\n startConversationMode() {\n if (!this.conversationModeEnabled || this.isConversationMode || !this.connection) {\n return;\n }\n\n this.isConversationMode = true;\n this.updateConversationButton();\n this._conversationPartialTranscript = '';\n this._conversationAssistantMessage = null;\n this._conversationPartialMessage = null;\n\n // Remove any previous conversation ended notification.\n this.removeNotification('conversation-ended');\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this._conversationSubject = new signalR.Subject();\n this._conversationStream = stream;\n\n // Create an AnalyserNode for volume-based interrupt detection.\n // During TTS playback, detect when the user speaks above\n // the threshold to stop TTS (interrupt). Audio chunks are\n // always forwarded — browser echo cancellation handles\n // speaker echo so the STT stream has no gaps.\n var AudioCtx = window.AudioContext || window.webkitAudioContext;\n if (AudioCtx) {\n this._conversationAudioCtx = new AudioCtx();\n this._conversationAnalyser = this._conversationAudioCtx.createAnalyser();\n this._conversationAnalyser.fftSize = 256;\n var micSource = this._conversationAudioCtx.createMediaStreamSource(stream);\n micSource.connect(this._conversationAnalyser);\n }\n\n var pendingChunk = Promise.resolve();\n var analyser = this._conversationAnalyser;\n var interruptVolumeThreshold = 30;\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n // During TTS playback, check mic volume to detect\n // user interruption (speaking above threshold).\n if (this.isPlayingAudio && analyser) {\n var freqData = new Uint8Array(analyser.frequencyBinCount);\n analyser.getByteFrequencyData(freqData);\n var sum = 0;\n for (var k = 0; k < freqData.length; k++) { sum += freqData[k]; }\n var avg = sum / freqData.length;\n\n if (avg >= interruptVolumeThreshold) {\n // User is speaking — interrupt TTS playback.\n this.stopAudio();\n }\n }\n\n // Always send audio to STT — browser echo cancellation\n // handles speaker echo; continuous audio avoids gaps\n // that increase recognition latency.\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n try {\n this._conversationSubject.next(base64);\n } catch (err) {\n // Subject may have been completed already.\n }\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => {\n try {\n this._conversationSubject.complete();\n } catch (err) {\n // Already completed.\n }\n });\n });\n\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var language = navigator.language || document.documentElement.lang || 'en-US';\n\n this.connection.send(\"StartConversation\", profileId, sessionId, this._conversationSubject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n this.isConversationMode = false;\n this.updateConversationButton();\n });\n },\n stopConversationMode() {\n if (!this.isConversationMode) {\n return;\n }\n\n this.isConversationMode = false;\n this.updateConversationButton();\n\n // Signal the server to cancel all in-progress STT/TTS streams immediately.\n if (this.connection) {\n this.connection.invoke(\"StopConversation\").catch(function () { });\n }\n\n if (this.isRecording && this.mediaRecorder) {\n this.mediaRecorder.stop();\n this.isRecording = false;\n }\n\n this.stopAudio();\n this._conversationPartialTranscript = '';\n this._conversationPartialMessage = null;\n\n // Clean up the AudioContext used for volume monitoring.\n if (this._conversationAudioCtx) {\n this._conversationAudioCtx.close().catch(function () { });\n this._conversationAudioCtx = null;\n this._conversationAnalyser = null;\n }\n\n // Mark any in-flight assistant message as done to stop the spinner.\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Safety net: clear all lingering streaming indicators.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n\n // Show a \"conversation ended\" notification system message.\n this.receiveNotification({\n type: 'conversation-ended',\n content: 'Conversation ended.',\n icon: 'fa-solid fa-circle-check',\n dismissible: true,\n autoDismissMs: 5000\n });\n },\n updateConversationButton() {\n if (!this.conversationButton) {\n return;\n }\n\n if (this.isConversationMode) {\n this.conversationButton.classList.add('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-dark', 'btn-outline-secondary');\n this.conversationButton.title = this.conversationButton.getAttribute('data-end-title') || 'End Conversation';\n var endHtml = this.conversationButton.getAttribute('data-end-html');\n if (endHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(endHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n } else {\n this.conversationButton.classList.remove('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-secondary');\n this.conversationButton.classList.add('btn-outline-dark');\n this.conversationButton.blur();\n this.conversationButton.title = this.conversationButton.getAttribute('data-start-title') || 'Start Conversation';\n var startHtml = this.conversationButton.getAttribute('data-start-html');\n if (startHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(startHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n }\n },\n conversationModeSendPrompt() {\n // Legacy: only used by AudioInput mode's ReceiveTranscript.\n },\n conversationModeOnAudioEnded() {\n // Legacy: in conversation mode, audio playback continuation\n // is handled by the persistent stream. This method is only\n // called from playCollectedAudio for non-conversation TTS.\n },\n generatePrompt(element) {\n if (!element) {\n console.error('The element paramter is required.');\n\n return;\n }\n\n let templateProfileId = element.getAttribute('data-profile-id');\n let sessionId = this.getSessionId();\n let sessionProfileId = this.getProfileId();\n\n if (!templateProfileId || !sessionId) {\n\n console.error('The given element is missing data-profile-id or the session has not yet started.');\n return;\n }\n\n // streamMessage() already shows the typing indicator.\n this.streamMessage(templateProfileId, null, sessionProfileId);\n },\n createSessionUrl(baseUrl, param, value) {\n\n const fullUrl = baseUrl.toLowerCase().startsWith('http') ? baseUrl : window.location.origin + baseUrl;\n const url = new URL(fullUrl);\n\n url.searchParams.set(param, value);\n\n return url.toString();\n },\n showTypingIndicator() {\n this.addMessage({\n role: 'indicator',\n htmlContent: config.indicatorTemplate\n });\n },\n hideTypingIndicator() {\n const originalLength = this.messages.length;\n this.messages = this.messages.filter(msg => msg.role !== 'indicator');\n const removedCount = originalLength - this.messages.length;\n return removedCount;\n },\n receiveNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var existingIndex = this.notifications.findIndex(n => n.type === notification.type);\n if (existingIndex >= 0) {\n this.notifications.splice(existingIndex, 1, notification);\n } else {\n this.notifications.push(notification);\n }\n this.scheduleNotificationDismiss(notification);\n this.$nextTick(() => {\n this.scrollToBottom();\n });\n },\n updateNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var existingIndex = this.notifications.findIndex(n => n.type === notification.type);\n if (existingIndex >= 0) {\n this.notifications.splice(existingIndex, 1, notification);\n this.scheduleNotificationDismiss(notification);\n }\n },\n scheduleNotificationDismiss(notification) {\n if (!notification || !notification.type || !notification.autoDismissMs || notification.autoDismissMs <= 0) {\n return;\n }\n this.notificationDismissTimers[notification.type] = setTimeout(() => {\n this.removeNotification(notification.type);\n }, notification.autoDismissMs);\n },\n clearNotificationDismiss(notificationType) {\n var timerId = this.notificationDismissTimers[notificationType];\n if (!timerId) {\n return;\n }\n clearTimeout(timerId);\n delete this.notificationDismissTimers[notificationType];\n },\n removeNotification(notificationType) {\n this.clearNotificationDismiss(notificationType);\n this.notifications = this.notifications.filter(n => n.type !== notificationType);\n },\n dismissNotification(notificationType) {\n this.removeNotification(notificationType);\n },\n handleNotificationAction(notificationType, actionName) {\n if (!this.connection) {\n return;\n }\n var sessionId = this.getSessionId();\n this.connection.invoke(\"HandleNotificationAction\", sessionId, notificationType, actionName).catch(function (err) {\n console.error(\"Error handling notification action:\", err);\n });\n },\n scrollToBottom() {\n if (!this.autoScroll) {\n return;\n }\n setTimeout(() => {\n this.chatContainer.scrollTop = this.chatContainer.scrollHeight - this.chatContainer.clientHeight;\n }, 50);\n },\n handleUserInput(event) {\n this.prompt = event.target.value;\n },\n getProfileId() {\n return this.inputElement.getAttribute('data-profile-id');\n },\n setSessionId(sessionId) {\n this.inputElement.setAttribute('data-session-id', sessionId || '');\n },\n resetSession() {\n this.stopRecording();\n this.setSessionId('');\n this.isSessionStarted = false;\n this.sessionRating = null;\n if (this.widgetIsInitialized) {\n localStorage.removeItem(this.chatWidgetStateSession);\n }\n this.messages = [];\n this.documents = [];\n if (!config.autoCreateSession) {\n this.showPlaceholder();\n }\n\n if (config.autoCreateSession) {\n this.startNewSession();\n }\n },\n startNewSession() {\n if (!this.applyOrchestratorAvailability()) {\n return;\n }\n\n const profileId = this.getProfileId();\n if (!profileId || !this.connection) {\n return;\n }\n\n this.connection.invoke(\"StartSession\", profileId, null).catch(err => console.error(err));\n },\n initializeApp() {\n this.inputElement = document.querySelector(config.inputElementSelector);\n this.buttonElement = document.querySelector(config.sendButtonElementSelector);\n this.chatContainer = document.querySelector(config.chatContainerElementSelector);\n this.placeholder = document.querySelector(config.placeholderElementSelector);\n this.applyOrchestratorAvailability();\n\n const sessionId = this.getSessionId();\n if (!hasWidgetConfig && sessionId) {\n this.loadSession(sessionId);\n } else if (this.isOrchestratorAvailable() && config.autoCreateSession && !hasWidgetConfig && !sessionId) {\n this.startNewSession();\n }\n\n // Initialize document bar if enabled.\n if (config.sessionDocumentsEnabled && config.documentBarSelector) {\n this.documentBar = document.querySelector(config.documentBarSelector);\n if (this.documentBar) {\n this.renderDocumentBar();\n\n // Create hidden file input for document uploads.\n var fileInput = document.createElement('input');\n fileInput.type = 'file';\n fileInput.id = 'ai-chat-doc-input';\n fileInput.className = 'd-none';\n fileInput.multiple = true;\n if (config.allowedExtensions) {\n fileInput.accept = config.allowedExtensions;\n }\n fileInput.addEventListener('change', (e) => this.handleFileInputChange(e));\n this.documentBar.parentElement.appendChild(fileInput);\n\n // Set up drag-and-drop on the input area.\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) {\n inputArea.addEventListener('dragover', (e) => this.handleDragOver(e));\n inputArea.addEventListener('dragleave', (e) => this.handleDragLeave(e));\n inputArea.addEventListener('drop', (e) => this.handleDrop(e));\n }\n }\n }\n\n // Pause auto-scroll when the user manually scrolls up during streaming.\n this.chatContainer.addEventListener('scroll', () => {\n if (!this.stream) {\n return;\n }\n const threshold = 30;\n const atBottom = this.chatContainer.scrollHeight - this.chatContainer.clientHeight - this.chatContainer.scrollTop <= threshold;\n this.autoScroll = atBottom;\n });\n\n this.inputElement.addEventListener('keydown', event => {\n\n if (this.stream != null) {\n return;\n }\n\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n this.buttonElement.click();\n }\n });\n\n this.inputElement.addEventListener('input', (e) => {\n this.handleUserInput(e);\n\n if (e.target.value.trim()) {\n this.buttonElement.removeAttribute('disabled');\n } else {\n this.buttonElement.setAttribute('disabled', true);\n }\n });\n\n this.buttonElement.addEventListener('click', () => {\n\n if (this.stream != null) {\n this.stream.dispose();\n this.stream = null;\n\n this.streamingFinished();\n this.hideTypingIndicator();\n\n // Clean up: remove empty assistant message or stop streaming animation.\n if (this.messages.length > 0) {\n const lastMsg = this.messages[this.messages.length - 1];\n if (lastMsg.role === 'assistant' && !lastMsg.content) {\n this.messages.pop();\n } else if (lastMsg.isStreaming) {\n lastMsg.isStreaming = false;\n }\n }\n\n return;\n }\n\n this.sendMessage();\n });\n\n const promptGenerators = document.getElementsByClassName('profile-generated-prompt');\n\n for (var i = 0; i < promptGenerators.length; i++) {\n promptGenerators[i].addEventListener('click', (e) => {\n e.preventDefault();\n this.generatePrompt(e.target);\n });\n }\n\n const chatSessions = document.getElementsByClassName('chat-session-history-item');\n\n for (var i = 0; i < chatSessions.length; i++) {\n chatSessions[i].addEventListener('click', (e) => {\n e.preventDefault();\n\n var sessionId = e.target.getAttribute('data-session-id');\n\n if (!sessionId) {\n console.error('an element with the class chat-session-history-item with no data-session-id set.');\n\n return;\n }\n\n this.loadSession(sessionId);\n this.showChatScreen();\n });\n }\n\n for (let i = 0; i < config.messages.length; i++) {\n this.addMessage(config.messages[i]);\n }\n\n // Update feedback icons in the DOM after initial messages have rendered.\n this.$nextTick(() => {\n this.refreshAllFeedbackIcons();\n });\n\n // Delegate click for code block copy buttons.\n if (this.chatContainer) {\n this.chatContainer.addEventListener('click', (e) => {\n var btn = e.target.closest('.ai-code-copy-btn');\n if (!btn) {\n return;\n }\n\n var block = btn.closest('.ai-code-block') || btn.closest('pre');\n if (!block) {\n return;\n }\n\n var codeEl = block.querySelector('code');\n if (codeEl) {\n navigator.clipboard.writeText(codeEl.textContent);\n var copiedText = config.codeCopiedText || 'Copied!';\n btn.innerHTML = '<i class=\"fa-solid fa-check\"></i> ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '<i class=\"fa-regular fa-copy\"></i>';\n }, 2000);\n }\n });\n }\n\n // Initialize speech-to-text microphone button.\n if (this.speechToTextEnabled && config.micButtonElementSelector) {\n this.micButton = document.querySelector(config.micButtonElementSelector);\n if (this.micButton) {\n this.micButton.style.display = '';\n this.micButton.addEventListener('click', () => {\n this.toggleRecording();\n });\n }\n }\n\n // Initialize conversation mode button.\n if (this.conversationModeEnabled && config.conversationButtonElementSelector) {\n this.conversationButton = document.querySelector(config.conversationButtonElementSelector);\n if (this.conversationButton) {\n this.conversationButton.addEventListener('click', () => {\n this.toggleConversationMode();\n });\n }\n }\n },\n loadSession(sessionId) {\n this.connection.invoke(\"LoadSession\", sessionId).catch(err => console.error(err));\n },\n reloadCurrentSession() {\n\n var sessionId = this.getSessionId();\n if (sessionId) {\n this.loadSession(sessionId);\n }\n },\n initializeSession(sessionId, force) {\n if (this.isSessionStarted && !force) {\n return\n }\n this.fireEvent(new CustomEvent(\"initializingSessionOpenAIChat\", { detail: { sessionId: sessionId } }))\n this.setSessionId(sessionId);\n this.isSessionStarted = true;\n\n if (this.widgetIsInitialized) {\n localStorage.setItem(this.chatWidgetStateSession, sessionId);\n }\n },\n initializeWidget() {\n\n if (!config.widget.chatWidgetContainer) {\n console.error('The widget chatWidgetContainer is required.');\n return;\n }\n\n if (!config.widget.chatWidgetStateName) {\n console.error('The widget chatWidgetStateName is required.');\n return;\n }\n\n const chatWidgetContainer = document.querySelector(config.widget.chatWidgetContainer);\n\n if (!chatWidgetContainer) {\n return;\n }\n\n if (config.widget.chatHistorySection) {\n this.chatHistorySection = document.querySelector(config.widget.chatHistorySection);\n }\n\n this.chatWidgetStateName = config.widget.chatWidgetStateName;\n this.chatWidgetStateSession = config.widget.chatWidgetStateName + 'Session';\n this.chatWidgetLayoutKey = config.widget.chatWidgetStateName + 'Layout';\n this.widgetContainerElement = chatWidgetContainer;\n this.widgetToggleButtonElement = config.widget.toggleButtonSelector\n ? document.querySelector(config.widget.toggleButtonSelector)\n : null;\n this.widgetResetSizeButtonElement = config.widget.resetSizeButtonSelector\n ? document.querySelector(config.widget.resetSizeButtonSelector)\n : null;\n this.widgetDefaultWidth = parsePixelValue(config.widget.defaultWidth) ||\n parsePixelValue(window.getComputedStyle(chatWidgetContainer).width) ||\n 380;\n this.widgetDefaultHeight = parsePixelValue(config.widget.defaultHeight) ||\n parsePixelValue(window.getComputedStyle(chatWidgetContainer).height) ||\n 520;\n this.widgetIsInitialized = true;\n\n if (config.widget.enableResizing) {\n chatWidgetContainer.classList.add('ai-chat-widget-resizable');\n chatWidgetContainer.style.minWidth = (parsePixelValue(config.widget.minWidth) || 320) + 'px';\n chatWidgetContainer.style.minHeight = (parsePixelValue(config.widget.minHeight) || 420) + 'px';\n\n if (typeof ResizeObserver !== 'undefined') {\n this.widgetResizeObserver = new ResizeObserver(() => {\n this.persistWidgetPanelSize();\n this.constrainWidgetElementsToViewport();\n this.updateWidgetResetSizeButtonVisibility();\n });\n\n this.widgetResizeObserver.observe(chatWidgetContainer);\n }\n }\n\n var dragHandleSelector = config.widget.dragHandleSelector || '.ai-chat-widget-header';\n var dragHandle = chatWidgetContainer.querySelector(dragHandleSelector);\n\n if (config.widget.enableDragging && dragHandle) {\n dragHandle.classList.add('ai-chat-widget-drag-handle');\n chatWidgetContainer.classList.add('ai-chat-widget-draggable');\n this.attachDraggableWidgetElement(chatWidgetContainer, dragHandle, 'panel', false);\n }\n\n if (config.widget.enableDragging && this.widgetToggleButtonElement) {\n this.widgetToggleButtonElement.classList.add('ai-chat-widget-draggable');\n this.attachDraggableWidgetElement(this.widgetToggleButtonElement, this.widgetToggleButtonElement, 'toggle', true);\n }\n\n if (this.widgetResetSizeButtonElement) {\n this.widgetResetSizeButtonElement.addEventListener('click', (event) => {\n event.preventDefault();\n this.resetWidgetSize();\n });\n }\n\n this.restoreWidgetLayout();\n\n if (!this.widgetViewportResizeHandler) {\n this.widgetViewportResizeHandler = () => {\n this.constrainWidgetElementsToViewport();\n this.updateWidgetResetSizeButtonVisibility();\n };\n\n window.addEventListener('resize', this.widgetViewportResizeHandler);\n }\n\n // Auto-load the last session so the user always sees previous chat history.\n this.reloadCurrentSession();\n\n if (config.autoCreateSession && !this.getSessionId()) {\n this.startNewSession();\n }\n\n if (config.widget.showHistoryButton && this.chatHistorySection) {\n\n const showHistoryButton = document.querySelector(config.widget.showHistoryButton);\n\n if (showHistoryButton) {\n showHistoryButton.addEventListener('click', () => {\n this.chatHistorySection.classList.toggle('show');\n });\n }\n\n if (config.widget.closeHistoryButton) {\n var closeHistoryButton = document.querySelector(config.widget.closeHistoryButton);\n\n if (closeHistoryButton) {\n closeHistoryButton.addEventListener('click', () => {\n this.showChatScreen();\n });\n }\n }\n }\n\n if (config.widget.newChatButton) {\n const newChatButton = document.querySelector(config.widget.newChatButton);\n\n if (newChatButton) {\n newChatButton.addEventListener('click', () => {\n this.resetSession();\n this.showChatScreen();\n });\n }\n }\n },\n showChatScreen() {\n\n if (!this.chatHistorySection) {\n return;\n }\n\n this.chatHistorySection.classList.remove('show');\n },\n getSessionId() {\n let sessionId = this.inputElement.getAttribute('data-session-id');\n\n if (!sessionId && this.widgetIsInitialized) {\n sessionId = localStorage.getItem(this.chatWidgetStateSession);\n }\n\n return sessionId;\n },\n copyResponse(message) {\n navigator.clipboard.writeText(message);\n },\n updateFeedbackIcons(container, userRating) {\n if (!container) {\n return;\n }\n\n var upBtn = container.querySelector('.rate-up-btn');\n var downBtn = container.querySelector('.rate-down-btn');\n\n // Font Awesome SVG+JS replaces <i> with <svg>, so we must replace\n // the entire button content and let Font Awesome re-process.\n if (upBtn) {\n var upClass = userRating === true ? 'fa-solid fa-thumbs-up' : 'fa-regular fa-thumbs-up';\n var upIcon = document.createElement('i');\n upIcon.className = upClass;\n upIcon.style.fontSize = '0.9rem';\n upBtn.textContent = '';\n upBtn.appendChild(upIcon);\n }\n\n if (downBtn) {\n var downClass = userRating === false ? 'fa-solid fa-thumbs-down' : 'fa-regular fa-thumbs-down';\n var downIcon = document.createElement('i');\n downIcon.className = downClass;\n downIcon.style.fontSize = '0.9rem';\n downBtn.textContent = '';\n downBtn.appendChild(downIcon);\n }\n\n // Trigger Font Awesome SVG+JS to convert the new <i> elements.\n if (window.FontAwesome && FontAwesome.dom && FontAwesome.dom.i2svg) {\n FontAwesome.dom.i2svg({ node: container });\n }\n },\n refreshAllFeedbackIcons() {\n var containers = this.$el.querySelectorAll('.ai-chat-message-assistant-feedback');\n\n for (var i = 0; i < containers.length; i++) {\n var msgId = containers[i].getAttribute('data-message-id');\n var msg = this.messages.find(m => m.id === msgId);\n\n if (msg) {\n this.updateFeedbackIcons(containers[i], msg.userRating);\n }\n }\n },\n rateMessage(message, isPositive, event) {\n var sessionId = this.getSessionId();\n\n if (!sessionId || !message.id || !this.connection) {\n return;\n }\n\n // Toggle: clicking the same rating again clears it.\n var newRating = message.userRating === isPositive ? null : isPositive;\n message.userRating = newRating;\n\n // Find the feedback container by message ID for reliable DOM targeting.\n var feedbackContainer = this.$el.querySelector(\n '.ai-chat-message-assistant-feedback[data-message-id=\"' + message.id + '\"]'\n );\n\n this.updateFeedbackIcons(feedbackContainer, newRating);\n\n // Trigger spark animation after Font Awesome has re-processed icons.\n if (newRating !== null && feedbackContainer) {\n setTimeout(() => {\n var btnClass = isPositive ? '.rate-up-btn' : '.rate-down-btn';\n var btn = feedbackContainer.querySelector(btnClass);\n\n if (btn) {\n btn.classList.remove('spark-effect');\n void btn.offsetWidth;\n btn.classList.add('spark-effect');\n btn.addEventListener('animationend', function onEnd() {\n btn.removeEventListener('animationend', onEnd);\n btn.classList.remove('spark-effect');\n });\n }\n }, 50);\n }\n\n this.connection.invoke(\"RateMessage\", sessionId, message.id, isPositive).catch(function (err) {\n console.error('Failed to rate message:', err);\n });\n }\n },\n watch: {\n documents: {\n handler() { this.renderDocumentBar(); },\n deep: true\n },\n isUploading() { this.renderDocumentBar(); },\n isPlayingAudio() {\n // Reserved for future use — volume-based interrupt detection\n // no longer mutes tracks; browser echo cancellation handles echo.\n },\n isConversationMode(active) {\n // Hide/show mic button.\n if (this.micButton) {\n this.micButton.style.display = active ? 'none' : (this.speechToTextEnabled ? '' : 'none');\n }\n\n // Hide/show send button.\n if (this.buttonElement) {\n this.buttonElement.style.display = active ? 'none' : '';\n }\n\n // Disable/enable textarea.\n if (this.inputElement) {\n this.inputElement.disabled = active;\n if (active) {\n this.inputElement.placeholder = '';\n }\n }\n }\n },\n mounted() {\n (async () => {\n await this.startConnection();\n this.initializeApp();\n if (hasWidgetConfig) {\n this.initializeWidget();\n }\n })();\n\n window.addEventListener('beforeunload', this.handleBeforeUnload);\n window.addEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n },\n beforeUnmount() {\n window.removeEventListener('beforeunload', this.handleBeforeUnload);\n window.removeEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n\n this.stopAudio(false);\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n if (this.connection) {\n this.connection.stop();\n }\n },\n template: config.messageTemplate\n }).mount(config.appElementSelector);\n\n return app;\n };\n\n return {\n initialize: initialize\n };\n}();\n\n// Download chart as image via event delegation (DOMPurify strips inline onclick).\ndocument.addEventListener('click', function (e) {\n const btn = e.target.closest('.download-chart-btn');\n if (!btn) {\n return;\n }\n const chartId = btn.getAttribute('data-chart-id');\n const canvas = chartId ? document.getElementById(chartId) : null;\n if (!canvas) {\n console.error('Chart canvas not found:', chartId);\n return;\n }\n const link = document.createElement('a');\n link.download = 'chart-' + chartId + '.png';\n link.href = canvas.toDataURL('image/png');\n link.click();\n});\n\n// Intercept download clicks for data-URI images and convert to blob downloads.\ndocument.addEventListener('click', function (e) {\n const link = e.target.closest('.ai-download-image');\n if (!link) {\n return;\n }\n\n const container = link.closest('.generated-image-container');\n const img = container?.querySelector('img');\n if (!img) {\n return;\n }\n\n const src = img.src;\n if (!src || !src.startsWith('data:')) {\n return; // Normal URL – let the default <a> behaviour handle it.\n }\n\n e.preventDefault();\n\n fetch(src)\n .then(function (res) { return res.blob(); })\n .then(function (blob) {\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = link.getAttribute('download') || 'generated-image.png';\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n setTimeout(function () { URL.revokeObjectURL(url); }, 100);\n })\n .catch(function (err) { console.error('Failed to download image:', err); });\n});\n"]}
1
+ {"version":3,"sources":["ai-chat.js"],"names":["_excluded","_regenerator","e","t","r","Symbol","n","iterator","o","toStringTag","i","c","prototype","Generator","u","Object","create","_regeneratorDefine2","f","p","y","G","v","a","d","bind","length","l","TypeError","call","done","value","GeneratorFunction","GeneratorFunctionPrototype","getPrototypeOf","this","setPrototypeOf","__proto__","displayName","w","m","defineProperty","_invoke","enumerable","configurable","writable","asyncGeneratorStep","Promise","resolve","then","_asyncToGenerator","arguments","apply","_next","_throw","_toConsumableArray","_arrayWithoutHoles","_iterableToArray","_unsupportedIterableToArray","_nonIterableSpread","Array","from","isArray","_arrayLikeToArray","_objectWithoutProperties","_objectWithoutPropertiesLoose","getOwnPropertySymbols","indexOf","propertyIsEnumerable","hasOwnProperty","_createForOfIteratorHelper","_n","F","s","next","_slicedToArray","_arrayWithHoles","_iterableToArrayLimit","_nonIterableRest","toString","slice","constructor","name","test","push","_typeof","window","openAIChatManager","defaultConfig","generatedImageAltText","generatedImageMaxWidth","downloadImageTitle","downloadChartTitle","downloadChartButtonText","userLabel","assistantLabel","thumbsUpTitle","thumbsDownTitle","copyTitle","codeCopiedText","widget","chatWidgetContainer","chatWidgetStateName","chatHistorySection","showHistoryButton","closeHistoryButton","newChatButton","toggleButtonSelector","resetSizeButtonSelector","dragHandleSelector","enableDragging","enableResizing","persistLayout","defaultWidth","defaultHeight","minWidth","minHeight","messageTemplate","indicatorTemplate","sanitizeUrl","url","trimmed","trim","escapeHtmlEntities","text","span","document","createElement","textContent","innerHTML","refreshFontAwesomeIcons","root","fontAwesome","FontAwesome","nodeType","selector","matches","querySelector","containsFontAwesomePlaceholders","dom","i2svg","node","observeFontAwesomeIcons","MutationObserver","observer","mutations","forEach","mutation","addedNodes","observe","childList","subtree","normalizeReference","reference","_ref","_normalized$index","_ref2","_normalized$text","_ref3","_normalized$title","_ref4","_normalized$link","_ref5","_normalized$reference","normalized","assign","index","Index","Text","title","Title","link","Link","referenceType","ReferenceType","isDownloadCitationReference","toLowerCase","normalizeReferences","references","_i","_Object$entries","entries","_normalizeReference","_Object$entries$_i","key","getCitationLabel","updateMessagePresentation","message","messageReferences","rawContent","content","citationDisplay","processedContent","keys","citations","citedRefs","filter","_ref6","includes","sort","_ref8","_ref9","b","_step","displayIndex","_iterator","_step$value","placeholder","concat","replaceAll","referenceKey","label","isDownload","err","_i2","_citations","citation","map","_ref10","buildCitationDisplay","displayContent","citationReferences","copyContent","_step2","_iterator2","_step3","_iterator3","trimEnd","buildCopyContent","htmlContent","parseMarkdownContent","renderer","marked","Renderer","data","href","code","lang","highlighted","hljs","getLanguage","highlight","language","_","highlightAuto","langDisplay","image","src","alt","maxWidth","chartCounter","_pendingCharts","renderChartsInMessage","charts","requestAnimationFrame","_step4","_iterator4","renderChartOnCanvas","chartId","config","canvas","getElementById","Chart","console","warn","offsetParent","__chartConfigs","_cfg$options","_cfg$options2","_cfg$options2$aspectR","_chartInstance","destroy","cfg","JSON","parse","options","responsive","maintainAspectRatio","aspectRatio","error","html","DOMPurify","sanitize","ADD_TAGS","ADD_ATTR","use","extensions","level","start","idx","undefined","tokenizer","extracted","token","jsonStart","depth","inString","escape","ch","jsonEnd","closeBracketIndex","startIndex","endIndex","json","substring","tryExtractChartMarker","type","raw","renderPendingCharts","configs","_i3","_Object$keys","initialize","instanceConfig","hasWidgetConfig","widgetBehavior","openAIChatWidgetBehavior","signalRHubUrl","appElementSelector","chatContainerElementSelector","inputElementSelector","sendButtonElementSelector","appDefinition","inputElement","buttonElement","chatContainer","isSessionStarted","isPlaceholderVisible","isStreaming","isNavigatingAway","autoScroll","stream","messages","notifications","prompt","documents","existingDocuments","isUploading","isDocumentOperationPending","documentOperationQueue","uploadErrors","isDragOver","documentBar","metricsEnabled","isRecording","mediaRecorder","preRecordingPrompt","micButton","speechToTextEnabled","chatMode","textToSpeechEnabled","ttsVoiceName","audioChunks","audioPlayQueue","isPlayingAudio","currentAudioElement","currentAudioUrl","ttsButton","ttsPlayingMessageIndex","ttsAudioCache","ttsInstanceId","Math","random","singleResponseMode","conversationModeEnabled","conversationButton","isConversationMode","notificationDismissTimers","pendingSessionPromise","pendingSessionResolver","pendingSessionRejector","pendingSessionTimeoutId","computed","lastAssistantIndex","role","methods","handleBeforeUnload","handleDragOver","sessionDocumentsEnabled","preventDefault","stopPropagation","inputArea","closest","classList","add","handleDragLeave","remove","handleDrop","dataTransfer","files","uploadFiles","triggerFileInput","fileInput","click","handleFileInputChange","target","queueDocumentOperation","operation","self","nextOperation","_callee","_context","_this","_callee3","filesToUpload","_context3","uploadDocumentUrl","_callee2","sessionId","profileId","formData","response","errorText","uploadError","result","_t","_t2","_context2","getSessionId","getProfileId","ensureSessionForDocuments","fileName","renderDocumentBar","FormData","append","fetch","method","body","ok","extractReadableErrorMessage","initializeSession","uploaded","failed","reloadCurrentSession","removeDocument","doc","_this2","_callee5","_context5","removeDocumentUrl","_callee4","removeError","_t3","_context4","headers","stringify","itemId","documentId","splice","status","formatFileSize","bytes","toFixed","escapeHtml","failedItem","failedName","errorMsg","supportedExtensionsText","replaceChildren","RETURN_DOM_FRAGMENT","closeButtons","querySelectorAll","j","addEventListener","docToRemove","parseInt","getAttribute","errorCloseButtons","addBtn","div","fallbackMessage","startsWith","parsed","detail","normalizeAssistantAppearance","appearance","icon","cssClass","disableStreamingAnimation","getAssistantLabel","getAssistantRoleClasses","classes","getAssistantIconClasses","shouldAnimateAssistantIcon","getAssistantIcon","startConnection","_this3","_callee6","_t4","_context6","connection","signalR","HubConnectionBuilder","withUrl","withAutomaticReconnect","build","serverTimeoutInMilliseconds","keepAliveIntervalInMilliseconds","on","_data$messages","msg","addMessage","$nextTick","refreshAllFeedbackIcons","initialPrompt","sendMessage","stopRecording","handleReceiveError","messageId","userRating","find","id","isFinal","_conversationPartialTranscript","replace","_conversationPartialMessage","hidePlaceholder","isPartial","scrollToBottom","_audioInputSent","dispatchEvent","Event","stopAudio","_conversationAssistantMessage","oldMsg","escaped","responseId","hideTypingIndicator","msgIndex","newMessage","base64Audio","contentType","binaryString","atob","Uint8Array","charCodeAt","playCollectedAudio","notification","receiveNotification","updateNotification","notificationType","removeNotification","onreconnecting","onreconnected","info","autoCreateSession","startNewSession","onclose","addMessageInternal","_this4","fireEvent","CustomEvent","_message$rawContent","_this5","addMessages","_this6","showPlaceholder","isOrchestratorAvailable","applyOrchestratorAvailability","unavailableMessage","orchestratorUnavailableMessage","disabled","micButtonElement","style","display","conversationButtonElement","event","isIndicator","trimmedPrompt","streamMessage","startRecording","_this7","navigator","mediaDevices","getUserMedia","audio","echoCancellation","noiseSuppression","autoGainControl","mimeType","MediaRecorder","isTypeSupported","audioBitsPerSecond","subject","Subject","pendingChunk","size","_callee7","uint8Array","base64","_context7","arrayBuffer","reduce","str","byte","String","fromCharCode","btoa","getTracks","track","stop","complete","documentElement","send","updateMicButton","toggleRecording","sessionProfileId","_this8","dispose","streamingStarted","showTypingIndicator","lastResponseId","messageIndex","currentSessionId","subscribe","chunk","_i4","_Object$entries2","_normalizeReference2","_Object$entries2$_i","_this8$stream","processReferences","streamingFinished","synthesizeSpeech","_this8$stream2","getServiceDownMessage","_this9","_ref15","_message$rawContent2","stopIcon","setAttribute","startIcon","removeAttribute","focus","icons","handleExternalTtsStop","_e$detail","sourceId","updateTtsPlaybackButtons","_this0","button","isPlaying","Number","toggle","cacheIndex","_this1","_ttsCacheIndex","invoke","toggleMessageTts","_this10","playAudioBlob","_this11","_step5","totalLength","sum","combined","offset","_iterator5","set","blob","Blob","_this12","URL","createObjectURL","Audio","revokeObjectURL","playNextInQueue","play","_this13","nextBlob","shift","conversationModeOnAudioEnded","_this14","pause","currentTime","toggleConversationMode","stopConversationMode","startConversationMode","_this15","updateConversationButton","_conversationSubject","_conversationStream","AudioCtx","AudioContext","webkitAudioContext","_conversationAudioCtx","_conversationAnalyser","createAnalyser","fftSize","createMediaStreamSource","connect","analyser","freqData","frequencyBinCount","getByteFrequencyData","k","_callee8","_context8","close","dismissible","autoDismissMs","endHtml","blur","startHtml","conversationModeSendPrompt","generatePrompt","element","templateProfileId","createSessionUrl","baseUrl","param","fullUrl","location","origin","searchParams","originalLength","_this16","clearNotificationDismiss","existingIndex","findIndex","scheduleNotificationDismiss","_this17","setTimeout","timerId","clearTimeout","dismissNotification","handleNotificationAction","actionName","_this18","scrollTop","scrollHeight","clientHeight","handleUserInput","setSessionId","resetSession","rejectPendingSessionRequest","sessionRating","onSessionReset","requestNewSession","_this19","_callee9","_context9","_this20","reject","resolvePendingSessionRequest","clearPendingSessionRequest","initializeApp","_this21","placeholderElementSelector","loadSession","documentBarSelector","className","multiple","allowedExtensions","accept","parentElement","appendChild","atBottom","shiftKey","lastMsg","pop","promptGenerators","getElementsByClassName","chatSessions","showChatScreen","btn","block","codeEl","clipboard","writeText","copiedText","micButtonElementSelector","conversationButtonElementSelector","force","onSessionInitialized","resolveSessionId","copyResponse","_ref17","_message$copyContent","updateFeedbackIcons","container","upBtn","downBtn","upClass","upIcon","fontSize","downClass","downIcon","containers","$el","msgId","rateMessage","isPositive","newRating","feedbackContainer","btnClass","offsetWidth","onEnd","removeEventListener","watch","handler","onDocumentsChanged","deep","active","mounted","_this22","_callee0","_context0","onMounted","fontAwesomeObserver","beforeUnmount","disconnect","onBeforeUnmount","template","app","Vue","createApp","mount","attach","download","toDataURL","img","res","removeChild"],"mappings":"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","file":"ai-chat.min.js","sourcesContent":["window.openAIChatManager = function () {\n\n // Defaults (can be overridden by instanceConfig)\n var defaultConfig = {\n // UI defaults for generated media\n generatedImageAltText: 'Generated Image',\n generatedImageMaxWidth: 400,\n downloadImageTitle: 'Download image',\n downloadChartTitle: 'Download chart as image',\n downloadChartButtonText: 'Download',\n userLabel: 'You',\n assistantLabel: 'Assistant',\n thumbsUpTitle: 'Thumbs up',\n thumbsDownTitle: 'Thumbs down',\n copyTitle: 'Click here to copy response to clipboard.',\n codeCopiedText: 'Copied!',\n widget: {\n chatWidgetContainer: null,\n chatWidgetStateName: null,\n chatHistorySection: null,\n showHistoryButton: null,\n closeHistoryButton: null,\n newChatButton: null,\n toggleButtonSelector: null,\n resetSizeButtonSelector: null,\n dragHandleSelector: '.ai-chat-widget-header',\n enableDragging: true,\n enableResizing: true,\n persistLayout: true,\n defaultWidth: null,\n defaultHeight: null,\n minWidth: 320,\n minHeight: 420\n },\n messageTemplate: `\n <div class=\"ai-chat-messages\">\n <div v-for=\"(message, index) in messages\" :key=\"'msg-' + index\" class=\"ai-chat-message-item\">\n <div>\n <div v-if=\"message.role === 'user'\" class=\"ai-chat-msg-role ai-chat-msg-role-user\">{{ userLabel }}</div>\n <div v-else-if=\"message.role !== 'indicator'\" :class=\"getAssistantRoleClasses(message)\">\n <span :class=\"getAssistantIconClasses(message, index)\"><i :class=\"getAssistantIcon(message)\"></i></span>\n {{ getAssistantLabel(message) }}\n </div>\n <div class=\"ai-chat-message-body lh-base\">\n <h4 v-if=\"message.title\">{{ message.title }}</h4>\n <div v-html=\"message.htmlContent\"></div>\n <ol v-if=\"message.citationReferences && message.citationReferences.length\" class=\"ai-chat-citation-list\">\n <li v-for=\"citation in message.citationReferences\" :key=\"'citation-' + (citation.referenceKey || citation.displayIndex)\" class=\"ai-chat-citation-item\">\n <a v-if=\"citation.link\" :href=\"citation.link\" :target=\"citation.isDownload ? null : '_blank'\" :rel=\"citation.isDownload ? null : 'noopener noreferrer'\">{{ citation.label }}</a>\n <span v-else>{{ citation.label }}</span>\n </li>\n </ol>\n <span class=\"message-buttons-container\" v-if=\"!isIndicator(message)\">\n <template v-if=\"metricsEnabled && message.role === 'assistant'\">\n <span class=\"ai-chat-message-assistant-feedback\" :data-message-id=\"message.id\">\n <button type=\"button\" class=\"btn btn-sm btn-link text-success p-0 me-2 button-message-toolbox rate-up-btn\" @click=\"rateMessage(message, true, $event)\" :title=\"thumbsUpTitle\">\n <i class=\"fa-regular fa-thumbs-up\"></i>\n </button>\n <button type=\"button\" class=\"btn btn-sm btn-link text-danger p-0 me-2 button-message-toolbox rate-down-btn\" @click=\"rateMessage(message, false, $event)\" :title=\"thumbsDownTitle\">\n <i class=\"fa-regular fa-thumbs-down\"></i>\n </button>\n </span>\n </template>\n <button type=\"button\" v-if=\"textToSpeechEnabled && !isConversationMode && message.role === 'assistant' && !message.isStreaming\" class=\"btn btn-sm btn-link text-secondary p-0 me-1 button-message-toolbox\" :class=\"{ 'tts-playing': ttsPlayingMessageIndex === index }\" :data-tts-message-index=\"index\" @click=\"toggleMessageTts(message, index)\" :title=\"ttsPlayingMessageIndex === index ? 'Pause audio' : 'Read aloud'\">\n <span :class=\"ttsPlayingMessageIndex === index ? 'fa-solid fa-circle-pause' : 'fa-solid fa-circle-play'\"></span>\n </button>\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary p-0 button-message-toolbox\" @click=\"copyResponse(message)\" :title=\"copyTitle\">\n <i class=\"fa-solid fa-copy\"></i>\n </button>\n </span>\n </div>\n </div>\n </div>\n <div v-for=\"notification in notifications\" :key=\"'notif-' + notification.type\" class=\"ai-chat-notification\" :class=\"'ai-chat-notification-' + (notification.type || 'info') + ' ' + (notification.cssClass || '')\">\n <div class=\"ai-chat-notification-content\">\n <i v-if=\"notification.icon\" :class=\"notification.icon\" class=\"ai-chat-notification-icon\"></i>\n <span class=\"ai-chat-notification-text\">{{ notification.content }}</span>\n <button type=\"button\" v-if=\"notification.dismissible\" class=\"btn btn-sm btn-link p-0 ms-2 ai-chat-notification-dismiss\" @click=\"dismissNotification(notification.type)\" title=\"Dismiss\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n <div v-if=\"notification.actions && notification.actions.length\" class=\"ai-chat-notification-actions\">\n <button type=\"button\" v-for=\"action in notification.actions\" :key=\"action.name\" class=\"btn btn-sm\" :class=\"action.cssClass || 'btn-outline-secondary'\" @click=\"handleNotificationAction(notification.type, action.name)\">\n <i v-if=\"action.icon\" :class=\"action.icon\" class=\"me-1\"></i>\n {{ action.label }}\n </button>\n </div>\n </div>\n </div>\n `,\n indicatorTemplate: `\n <div class=\"ai-chat-msg-role ai-chat-msg-role-assistant\">\n <span class=\"ai-streaming-icon\"><i class=\"fa fa-robot\" style=\"display: inline-block;\"></i></span>\n Assistant\n </div>\n `\n };\n\n // Sanitize URLs to prevent javascript: protocol injection.\n function sanitizeUrl(url) {\n if (!url) return '';\n var trimmed = url.trim();\n if (/^javascript:/i.test(trimmed) || /^vbscript:/i.test(trimmed) || /^data:text\\/html/i.test(trimmed)) {\n return '';\n }\n return url;\n }\n\n // Safely HTML-encode a string using the DOM (avoids regex-based HTML filtering).\n function escapeHtmlEntities(text) {\n var span = document.createElement('span');\n span.textContent = text;\n return span.innerHTML;\n }\n\n function containsFontAwesomePlaceholders(root) {\n if (!root || root.nodeType !== 1) {\n return false;\n }\n\n var selector = 'i[class*=\"fa-\"],i.fa,i.fas,i.far,i.fab';\n if (typeof root.matches === 'function' && root.matches(selector)) {\n return true;\n }\n\n return typeof root.querySelector === 'function' && !!root.querySelector(selector);\n }\n\n function refreshFontAwesomeIcons(root) {\n var fontAwesome = window.FontAwesome;\n if (!containsFontAwesomePlaceholders(root) || !fontAwesome || !fontAwesome.dom || typeof fontAwesome.dom.i2svg !== 'function') {\n return;\n }\n\n fontAwesome.dom.i2svg({ node: root });\n }\n\n function observeFontAwesomeIcons(root) {\n if (!root || typeof MutationObserver === 'undefined') {\n return null;\n }\n\n var observer = new MutationObserver(function (mutations) {\n mutations.forEach(function (mutation) {\n mutation.addedNodes.forEach(function (node) {\n refreshFontAwesomeIcons(node);\n });\n });\n });\n\n observer.observe(root, {\n childList: true,\n subtree: true\n });\n\n return observer;\n }\n\n function parsePixelValue(value) {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n\n if (typeof value !== 'string') {\n return null;\n }\n\n var parsed = parseFloat(value);\n return Number.isFinite(parsed) ? parsed : null;\n }\n\n function clamp(value, min, max) {\n return Math.min(Math.max(value, min), max);\n }\n\n function normalizeReference(reference) {\n if (!reference || typeof reference !== 'object') {\n return null;\n }\n\n const normalized = Object.assign({}, reference);\n normalized.index = normalized.index ?? normalized.Index ?? 0;\n normalized.text = normalized.text ?? normalized.Text ?? null;\n normalized.title = normalized.title ?? normalized.Title ?? null;\n normalized.link = sanitizeUrl(normalized.link ?? normalized.Link ?? null);\n normalized.referenceType = normalized.referenceType ?? normalized.ReferenceType ?? null;\n\n return normalized;\n }\n\n function isDownloadCitationReference(reference) {\n if (!reference || typeof reference !== 'object') {\n return false;\n }\n\n if (typeof reference.referenceType === 'string' && reference.referenceType.toLowerCase() === 'document') {\n return true;\n }\n\n if (typeof reference.link === 'string' && /\\/ai\\/documents\\/.+\\/download(?:$|\\?)/i.test(reference.link)) {\n return true;\n }\n\n return false;\n }\n\n function normalizeReferences(references) {\n if (!references || typeof references !== 'object') {\n return {};\n }\n\n const normalized = {};\n\n for (const [key, value] of Object.entries(references)) {\n normalized[key] = normalizeReference(value) ?? {};\n }\n\n return normalized;\n }\n\n function getCitationLabel(reference, key) {\n return reference.title || reference.text || key;\n }\n\n function buildCitationDisplay(content, references) {\n let processedContent = (content || '').trim();\n const messageReferences = normalizeReferences(references);\n\n if (!processedContent || !Object.keys(messageReferences).length) {\n return { content: processedContent, citations: [] };\n }\n\n const citedRefs = Object.entries(messageReferences).filter(([key]) => processedContent.includes(key));\n\n if (!citedRefs.length) {\n return { content: processedContent, citations: [] };\n }\n\n citedRefs.sort(([, a], [, b]) => a.index - b.index);\n\n const citations = [];\n let displayIndex = 1;\n\n for (const [key, value] of citedRefs) {\n const placeholder = `__CITE_${displayIndex}_${value.index || displayIndex}__`;\n processedContent = processedContent.replaceAll(key, placeholder);\n citations.push({\n referenceKey: key,\n displayIndex: displayIndex,\n label: getCitationLabel(value, key),\n link: value.link || null,\n isDownload: isDownloadCitationReference(value),\n placeholder: placeholder,\n });\n\n displayIndex++;\n }\n\n for (const citation of citations) {\n processedContent = processedContent.replaceAll(citation.placeholder, `<sup>${citation.displayIndex}</sup>`);\n }\n\n processedContent = processedContent.replaceAll('</sup><sup>', '</sup><sup>,</sup><sup>');\n\n return {\n content: processedContent,\n citations: citations.map(({ placeholder, ...citation }) => citation),\n };\n }\n\n function buildCopyContent(content, citations) {\n let copyContent = (content || '').trim();\n\n if (!copyContent || !Array.isArray(citations) || citations.length === 0) {\n return copyContent;\n }\n\n for (const citation of citations) {\n copyContent = copyContent.replaceAll(citation.referenceKey, `[${citation.displayIndex}]`);\n }\n\n copyContent += '\\n\\nReferences:\\n';\n\n for (const citation of citations) {\n copyContent += `${citation.displayIndex}. ${citation.label}`;\n\n if (citation.link) {\n copyContent += ` - ${citation.link}`;\n }\n\n copyContent += '\\n';\n }\n\n return copyContent.trimEnd();\n }\n\n function updateMessagePresentation(message, references) {\n const messageReferences = normalizeReferences(references ?? message.references);\n const rawContent = typeof message.rawContent === 'string'\n ? message.rawContent\n : typeof message.content === 'string'\n ? message.content\n : '';\n const citationDisplay = buildCitationDisplay(rawContent, messageReferences);\n\n message.rawContent = rawContent;\n message.content = rawContent;\n message.displayContent = citationDisplay.content;\n message.references = messageReferences;\n message.citationReferences = citationDisplay.citations;\n message.copyContent = buildCopyContent(rawContent, citationDisplay.citations);\n message.htmlContent = parseMarkdownContent(citationDisplay.content, message);\n\n return message;\n }\n\n const renderer = new marked.Renderer();\n\n // Modify the link rendering to open in a new tab\n renderer.link = function (data) {\n var href = sanitizeUrl(data.href);\n if (!href) return data.text || '';\n return `<a href=\"${href}\" target=\"_blank\" rel=\"noopener noreferrer\">${data.text}</a>`;\n };\n\n // Custom code block renderer with highlight.js integration and copy button.\n renderer.code = function (data) {\n var code = data.text || '';\n var lang = (data.lang || '').trim();\n var highlighted = code;\n\n if (typeof hljs !== 'undefined') {\n if (lang && hljs.getLanguage(lang)) {\n try {\n highlighted = hljs.highlight(code, { language: lang }).value;\n } catch (_) { }\n } else {\n try {\n highlighted = hljs.highlightAuto(code).value;\n } catch (_) { }\n }\n } else {\n highlighted = escapeHtmlEntities(code);\n }\n\n var langDisplay = lang ? escapeHtmlEntities(lang) : 'code';\n return `<div class=\"ai-code-block\"><div class=\"ai-code-header\"><span class=\"ai-code-lang\"><i class=\"fa-solid fa-code\"></i> ${langDisplay}</span><button type=\"button\" class=\"ai-code-copy-btn\" title=\"Copy code\"><i class=\"fa-regular fa-copy\"></i></button></div><pre><code class=\"hljs${lang ? ' language-' + lang : ''}\">${highlighted}</code></pre></div>`;\n };\n\n // Custom image renderer for generated images with thumbnail styling and download button.\n // Handles both URL and data-URI sources (data URIs are converted to blobs for download).\n renderer.image = function (data) {\n const src = sanitizeUrl(data.href);\n if (!src) return '';\n const alt = data.text || defaultConfig.generatedImageAltText;\n const maxWidth = defaultConfig.generatedImageMaxWidth;\n return `<div class=\"generated-image-container\">\n <img src=\"${src}\" alt=\"${alt}\" class=\"img-thumbnail\" style=\"max-width: ${maxWidth}px; height: auto;\" />\n <div class=\"mt-2\">\n <a href=\"${src}\" target=\"_blank\" download=\"${alt}\" title=\"${defaultConfig.downloadImageTitle}\" class=\"btn btn-sm btn-outline-secondary ai-download-image\">\n <i class=\"fa-solid fa-download\"></i>\n </a>\n </div>\n </div>`;\n };\n\n // Chart counter for unique IDs\n let chartCounter = 0;\n\n // Collector for charts discovered during marked parsing.\n let _pendingCharts = [];\n\n // Global chart config map: any page (e.g., Chat Interactions) that uses\n // the shared marked instance can call window.renderPendingCharts() after\n // its DOM update to render charts it didn't create itself.\n window.__chartConfigs = window.__chartConfigs || {};\n\n function createChartHtml(chartId) {\n return `<div class=\"chart-container\" style=\"position: relative; width: 100%; max-width: 560px; min-height: 420px;\">`\n + `<canvas id=\"${chartId}\"></canvas>`\n + `</div>`\n + `<div class=\"mt-2\">`\n + `<button type=\"button\" class=\"btn btn-sm btn-outline-secondary download-chart-btn\" data-chart-id=\"${chartId}\" title=\"${defaultConfig.downloadChartTitle}\">`\n + `<i class=\"fa-solid fa-download\"></i> ${defaultConfig.downloadChartButtonText}`\n + `</button>`\n + `</div>`;\n }\n\n // Register [chart:{...json...}] as a native marked block extension so the\n // markdown parser handles chart markers inline with surrounding text.\n marked.use({\n extensions: [{\n name: 'chart',\n level: 'block',\n start(src) {\n const idx = src.indexOf('[chart:');\n return idx >= 0 ? idx : undefined;\n },\n tokenizer(src) {\n const extracted = tryExtractChartMarker(src);\n if (!extracted || extracted.startIndex !== 0) {\n return undefined;\n }\n\n const chartId = `chat_chart_${++chartCounter}`;\n\n return {\n type: 'chart',\n raw: src.substring(0, extracted.endIndex),\n chartId: chartId,\n json: extracted.json,\n };\n },\n renderer(token) {\n _pendingCharts.push({ chartId: token.chartId, config: token.json });\n window.__chartConfigs[token.chartId] = token.json;\n return createChartHtml(token.chartId);\n }\n }]\n });\n\n // Extract a [chart:{...json...}] marker. This avoids regex issues with nested brackets.\n function tryExtractChartMarker(text) {\n const token = '[chart:';\n const start = text.indexOf(token);\n if (start < 0) {\n return null;\n }\n\n // Find JSON object boundary by balancing braces\n const jsonStart = start + token.length;\n let i = jsonStart;\n while (i < text.length && (text[i] === ' ' || text[i] === '\\n' || text[i] === '\\r' || text[i] === '\\t')) {\n i++;\n }\n\n if (i >= text.length || text[i] !== '{') {\n return null;\n }\n\n let depth = 0;\n let inString = false;\n let escape = false;\n\n for (; i < text.length; i++) {\n const ch = text[i];\n\n if (inString) {\n if (escape) {\n escape = false;\n continue;\n }\n if (ch === '\\\\') {\n escape = true;\n continue;\n }\n if (ch === '\"') {\n inString = false;\n }\n continue;\n }\n\n if (ch === '\"') {\n inString = true;\n continue;\n }\n\n if (ch === '{') {\n depth++;\n } else if (ch === '}') {\n depth--;\n if (depth === 0) {\n const jsonEnd = i;\n // Expect closing bracket after JSON\n const closeBracketIndex = text.indexOf(']', jsonEnd + 1);\n if (closeBracketIndex < 0) {\n return null;\n }\n\n const json = text.substring(jsonStart, jsonEnd + 1).trim();\n return {\n startIndex: start,\n endIndex: closeBracketIndex + 1,\n json: json\n };\n }\n }\n }\n\n return null;\n }\n\n function renderChartsInMessage(message) {\n if (!message || !message._pendingCharts || !message._pendingCharts.length) {\n return;\n }\n\n // Copy and clear pending charts immediately to prevent duplicate renders.\n const charts = [...message._pendingCharts];\n message._pendingCharts = [];\n\n // Defer to requestAnimationFrame so the browser has fully laid out the\n // canvas elements before Chart.js reads their dimensions.\n requestAnimationFrame(() => {\n for (const c of charts) {\n renderChartOnCanvas(c.chartId, c.config);\n }\n });\n }\n\n function renderChartOnCanvas(chartId, config) {\n const canvas = document.getElementById(chartId);\n if (!canvas) {\n return false;\n }\n\n if (typeof Chart === 'undefined') {\n console.warn('Chart.js is not loaded. To render interactive charts, include the Chart.js library on the page (e.g., <script src=\"https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.min.js\"></script>).');\n return false;\n }\n\n // When the canvas is inside a hidden container (e.g., a widget panel with\n // display:none), it has zero dimensions and Chart.js cannot render correctly.\n // Keep the config in __chartConfigs so renderPendingCharts() can retry later\n // once the container becomes visible.\n if (canvas.offsetParent === null) {\n window.__chartConfigs[chartId] = config;\n return false;\n }\n\n try {\n if (canvas._chartInstance) {\n canvas._chartInstance.destroy();\n }\n\n const cfg = typeof config === 'string' ? JSON.parse(config) : config;\n cfg.options ??= {};\n cfg.options.responsive = true;\n cfg.options.maintainAspectRatio = true;\n cfg.options.aspectRatio ??= 4 / 3;\n\n canvas._chartInstance = new Chart(canvas, cfg);\n delete window.__chartConfigs[chartId];\n return true;\n } catch (e) {\n console.error('Error creating chart:', e);\n return false;\n }\n }\n\n // Global function: renders any chart canvases whose configs are in the\n // global __chartConfigs map. Called by pages (e.g., Chat Interactions)\n // that share the marked instance but have their own rendering pipeline.\n window.renderPendingCharts = function () {\n if (typeof Chart === 'undefined') {\n return;\n }\n\n const configs = window.__chartConfigs;\n if (!configs) {\n return;\n }\n\n requestAnimationFrame(() => {\n for (const chartId of Object.keys(configs)) {\n renderChartOnCanvas(chartId, configs[chartId]);\n }\n });\n };\n\n // Parse markdown content via marked (which natively handles [chart:...] markers\n // through the registered extension) and collect pending chart configs for later\n // Chart.js rendering.\n function parseMarkdownContent(content, message) {\n _pendingCharts = [];\n const html = marked.parse(content, { renderer });\n message._pendingCharts = _pendingCharts.length > 0 ? [..._pendingCharts] : [];\n return DOMPurify.sanitize(html, { ADD_TAGS: ['canvas'], ADD_ATTR: ['target'] });\n }\n\n const initialize = (instanceConfig) => {\n\n const config = Object.assign({}, defaultConfig, instanceConfig);\n config.widget = Object.assign({}, defaultConfig.widget || {}, instanceConfig && instanceConfig.widget ? instanceConfig.widget : {});\n const hasWidgetConfig = !!(instanceConfig && instanceConfig.widget && instanceConfig.widget.chatWidgetContainer && instanceConfig.widget.chatWidgetStateName);\n const widgetBehavior = window.openAIChatWidgetBehavior || null;\n // Keep defaultConfig in sync so renderers use overridden values\n defaultConfig = config;\n\n if (!config.signalRHubUrl) {\n console.error('The signalRHubUrl is required.');\n return;\n }\n\n if (!config.appElementSelector) {\n console.error('The appElementSelector is required.');\n return;\n }\n\n if (!config.chatContainerElementSelector) {\n console.error('The chatContainerElementSelector is required.');\n return;\n }\n\n if (!config.inputElementSelector) {\n console.error('The inputElementSelector is required.');\n return;\n }\n\n if (!config.sendButtonElementSelector) {\n console.error('The sendButtonElementSelector is required.');\n return;\n }\n\n const appDefinition = {\n data() {\n return {\n inputElement: null,\n buttonElement: null,\n chatContainer: null,\n placeholder: null,\n isSessionStarted: false,\n isPlaceholderVisible: true,\n isStreaming: false,\n isNavigatingAway: false,\n autoScroll: true,\n stream: null,\n messages: [],\n notifications: [],\n prompt: '',\n documents: config.existingDocuments || [],\n isUploading: false,\n isDocumentOperationPending: false,\n documentOperationQueue: null,\n uploadErrors: [],\n isDragOver: false,\n documentBar: null,\n metricsEnabled: !!config.metricsEnabled,\n userLabel: config.userLabel,\n assistantLabel: config.assistantLabel,\n thumbsUpTitle: config.thumbsUpTitle,\n thumbsDownTitle: config.thumbsDownTitle,\n copyTitle: config.copyTitle,\n isRecording: false,\n mediaRecorder: null,\n preRecordingPrompt: '',\n micButton: null,\n speechToTextEnabled: config.chatMode === 'AudioInput' || config.chatMode === 'Conversation',\n textToSpeechEnabled: config.chatMode === 'Conversation' || !!config.textToSpeechEnabled,\n ttsVoiceName: config.ttsVoiceName || null,\n audioChunks: [],\n audioPlayQueue: [],\n isPlayingAudio: false,\n currentAudioElement: null,\n currentAudioUrl: null,\n ttsButton: null,\n ttsPlayingMessageIndex: -1,\n ttsAudioCache: {},\n ttsInstanceId: 'ai-chat-' + Math.random().toString(36).slice(2),\n singleResponseMode: !!config.singleResponseMode,\n conversationModeEnabled: config.chatMode === 'Conversation',\n conversationButton: null,\n isConversationMode: false,\n notificationDismissTimers: {},\n pendingSessionPromise: null,\n pendingSessionResolver: null,\n pendingSessionRejector: null,\n pendingSessionTimeoutId: null,\n };\n },\n computed: {\n lastAssistantIndex() {\n for (var i = this.messages.length - 1; i >= 0; i--) {\n if (this.messages[i].role === 'assistant') {\n return i;\n }\n }\n return -1;\n }\n },\n methods: {\n handleBeforeUnload() {\n this.isNavigatingAway = true;\n },\n handleDragOver(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = true;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.add('ai-chat-drag-over');\n },\n handleDragLeave(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = false;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.remove('ai-chat-drag-over');\n },\n handleDrop(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = false;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.remove('ai-chat-drag-over');\n if (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n this.uploadFiles(Array.from(e.dataTransfer.files));\n }\n },\n triggerFileInput() {\n if (!config.sessionDocumentsEnabled || this.isDocumentOperationPending) return;\n var fileInput = document.getElementById('ai-chat-doc-input');\n if (fileInput) fileInput.click();\n },\n handleFileInputChange(e) {\n var files = e.target.files ? Array.from(e.target.files) : [];\n if (files && files.length > 0) {\n this.uploadFiles(files);\n }\n e.target.value = '';\n },\n queueDocumentOperation(operation) {\n var self = this;\n var previousOperation = this.documentOperationQueue || Promise.resolve();\n var nextOperation = previousOperation\n .catch(function () { })\n .then(async function () {\n self.isDocumentOperationPending = true;\n try {\n return await operation();\n } finally {\n self.isDocumentOperationPending = false;\n }\n });\n\n this.documentOperationQueue = nextOperation.finally(function () {\n if (self.documentOperationQueue === nextOperation) {\n self.documentOperationQueue = null;\n }\n });\n\n return this.documentOperationQueue;\n },\n async uploadFiles(files) {\n if (!config.uploadDocumentUrl) return;\n\n var filesToUpload = Array.isArray(files) ? files.slice() : Array.from(files || []);\n if (filesToUpload.length === 0) return;\n\n return this.queueDocumentOperation(async () => {\n var sessionId = this.getSessionId();\n var profileId = this.getProfileId();\n\n if (!sessionId) {\n try {\n sessionId = await this.ensureSessionForDocuments(profileId);\n } catch (err) {\n console.error('Failed to create a chat session for document upload:', err);\n this.uploadErrors = [{ fileName: '', error: 'Could not create a chat session for the upload.' }];\n this.renderDocumentBar();\n return;\n }\n }\n\n if (!sessionId) {\n console.warn('Cannot upload documents without a session or profile.');\n this.uploadErrors = [{ fileName: '', error: 'Could not create a chat session for the upload.' }];\n this.renderDocumentBar();\n return;\n }\n\n this.isUploading = true;\n this.uploadErrors = [];\n this.renderDocumentBar();\n try {\n var formData = new FormData();\n formData.append('sessionId', sessionId);\n for (var i = 0; i < filesToUpload.length; i++) {\n formData.append('files', filesToUpload[i]);\n }\n\n var response = await fetch(config.uploadDocumentUrl, {\n method: 'POST',\n body: formData\n });\n\n if (!response.ok) {\n var errorText = await response.text();\n var uploadError = this.extractReadableErrorMessage(errorText, 'Upload failed. Please try again.');\n console.error('Upload failed:', errorText);\n this.uploadErrors = [{ fileName: '', error: uploadError }];\n return;\n }\n\n var result = await response.json();\n\n if (result.sessionId && result.sessionId !== this.getSessionId()) {\n this.initializeSession(result.sessionId);\n }\n\n if (Array.isArray(result.documents)) {\n this.documents = result.documents;\n } else if (result.uploaded && result.uploaded.length > 0) {\n this.documents = this.documents.concat(result.uploaded);\n }\n\n if (result.failed && result.failed.length > 0) {\n this.uploadErrors = result.failed;\n }\n } catch (err) {\n console.error('Upload error:', err);\n this.uploadErrors = [{ fileName: '', error: 'Upload failed. Please try again.' }];\n\n if (this.getSessionId()) {\n this.reloadCurrentSession();\n }\n } finally {\n this.isUploading = false;\n this.renderDocumentBar();\n }\n });\n },\n async removeDocument(doc) {\n if (!config.removeDocumentUrl) return;\n\n return this.queueDocumentOperation(async () => {\n try {\n var sessionId = this.getSessionId();\n var response = await fetch(config.removeDocumentUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ itemId: sessionId, documentId: doc.documentId })\n });\n\n if (response.ok) {\n var result = await response.json();\n\n if (Array.isArray(result.documents)) {\n this.documents = result.documents;\n } else {\n var idx = this.documents.indexOf(doc);\n if (idx > -1) {\n this.documents.splice(idx, 1);\n }\n }\n } else {\n var errorText = await response.text();\n var removeError = this.extractReadableErrorMessage(errorText, 'Failed to remove document. Please try again.');\n console.error('Failed to remove document:', response.status, errorText);\n this.uploadErrors = [{ fileName: doc.fileName || '', error: removeError }];\n if (sessionId) {\n this.reloadCurrentSession();\n }\n this.renderDocumentBar();\n }\n } catch (err) {\n console.error('Remove document error:', err);\n this.uploadErrors = [{ fileName: doc.fileName || '', error: 'Failed to remove document. Please try again.' }];\n if (this.getSessionId()) {\n this.reloadCurrentSession();\n }\n this.renderDocumentBar();\n }\n });\n },\n formatFileSize(bytes) {\n if (bytes < 1024) return bytes + ' B';\n if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';\n return (bytes / (1024 * 1024)).toFixed(1) + ' MB';\n },\n renderDocumentBar() {\n if (!this.documentBar) return;\n\n if (!config.sessionDocumentsEnabled) {\n this.documentBar.classList.add('d-none');\n return;\n }\n\n this.documentBar.classList.remove('d-none');\n\n var html = '<div class=\"ai-chat-doc-bar p-2\">';\n html += '<div class=\"d-flex flex-wrap align-items-center gap-1\">';\n\n for (var i = 0; i < this.documents.length; i++) {\n var doc = this.documents[i];\n var name = doc.fileName || 'Document';\n if (name.length > 20) name = name.substring(0, 17) + '...';\n html += '<span class=\"badge bg-secondary bg-opacity-25 text-dark d-inline-flex align-items-center gap-1 px-2 py-1\" style=\"font-size: 0.8rem;\" title=\"' + this.escapeHtml(doc.fileName || '') + '\">';\n html += '<i class=\"fa-solid fa-file-lines\" style=\"font-size: 0.7rem;\"></i> ';\n html += this.escapeHtml(name);\n html += ' <button type=\"button\" class=\"btn-close btn-close-sm ms-1\" style=\"font-size: 0.5rem;\" data-doc-index=\"' + i + '\" aria-label=\"Remove\"' + (this.isDocumentOperationPending ? ' disabled' : '') + '></button>';\n html += '</span>';\n }\n\n for (var m = 0; m < this.uploadErrors.length; m++) {\n var failedItem = this.uploadErrors[m];\n var failedName = failedItem.fileName || 'File';\n var errorMsg = failedItem.error || 'Upload failed';\n if (failedName.length > 15) failedName = failedName.substring(0, 12) + '...';\n html += '<span class=\"badge bg-danger bg-opacity-25 text-danger d-inline-flex align-items-center gap-1 px-2 py-1\" style=\"font-size: 0.8rem;\" title=\"' + this.escapeHtml((failedItem.fileName || '') + ': ' + errorMsg) + '\">';\n html += '<i class=\"fa-solid fa-circle-exclamation\" style=\"font-size: 0.7rem;\"></i> ';\n html += this.escapeHtml(failedName);\n html += ' <button type=\"button\" class=\"btn-close btn-close-sm ms-1\" style=\"font-size: 0.5rem;\" data-error-index=\"' + m + '\" aria-label=\"Dismiss\"></button>';\n html += '</span>';\n }\n\n if (this.isUploading) {\n html += '<span class=\"badge bg-info bg-opacity-25 text-dark d-inline-flex align-items-center gap-1 px-2 py-1\" style=\"font-size: 0.8rem;\">';\n html += '<span class=\"spinner-border spinner-border-sm\" style=\"width: 0.7rem; height: 0.7rem;\"></span> Uploading...';\n html += '</span>';\n }\n\n html += '<button type=\"button\" class=\"btn btn-sm btn-outline-secondary rounded-pill ai-chat-doc-add-btn d-inline-flex align-items-center gap-1\" style=\"font-size: 0.75rem; padding: 0.15rem 0.5rem;\" title=\"Attach documents\"' + (this.isDocumentOperationPending ? ' disabled' : '') + '>';\n html += '<i class=\"fa-solid fa-paperclip\"></i>';\n if (this.documents.length === 0 && !this.isUploading) {\n html += ' <span>Attach files</span>';\n }\n html += '</button>';\n html += '</div>';\n if (config.supportedExtensionsText) {\n html += '<div class=\"small text-muted mt-2\">Supported formats: ' + this.escapeHtml(config.supportedExtensionsText) + '</div>';\n }\n\n html += '</div>';\n\n this.documentBar.replaceChildren(DOMPurify.sanitize(html, { RETURN_DOM_FRAGMENT: true }));\n\n // Bind remove handlers\n var self = this;\n var closeButtons = this.documentBar.querySelectorAll('[data-doc-index]');\n for (var j = 0; j < closeButtons.length; j++) {\n closeButtons[j].addEventListener('click', (function (idx) {\n return function (e) {\n e.preventDefault();\n e.stopPropagation();\n if (self.isDocumentOperationPending) {\n return;\n }\n\n var docToRemove = self.documents[idx];\n if (docToRemove) self.removeDocument(docToRemove);\n };\n })(parseInt(closeButtons[j].getAttribute('data-doc-index'))));\n }\n\n // Bind error dismiss handlers\n var errorCloseButtons = this.documentBar.querySelectorAll('[data-error-index]');\n for (var n = 0; n < errorCloseButtons.length; n++) {\n errorCloseButtons[n].addEventListener('click', (function (idx) {\n return function (e) {\n e.preventDefault();\n e.stopPropagation();\n self.uploadErrors.splice(idx, 1);\n self.renderDocumentBar();\n };\n })(parseInt(errorCloseButtons[n].getAttribute('data-error-index'))));\n }\n\n // Bind add button\n var addBtn = this.documentBar.querySelector('.ai-chat-doc-add-btn');\n if (addBtn) {\n addBtn.addEventListener('click', function (e) {\n e.preventDefault();\n if (self.isDocumentOperationPending) {\n return;\n }\n self.triggerFileInput();\n });\n }\n },\n escapeHtml(text) {\n var div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n },\n extractReadableErrorMessage(errorText, fallbackMessage) {\n if (!errorText || typeof errorText !== 'string') {\n return fallbackMessage;\n }\n\n var trimmed = errorText.trim();\n if (!trimmed) {\n return fallbackMessage;\n }\n\n if (trimmed.startsWith('{') || trimmed.startsWith('[')) {\n try {\n var parsed = JSON.parse(trimmed);\n var message = parsed?.error || parsed?.message || parsed?.title || parsed?.detail;\n return typeof message === 'string' && message.trim()\n ? message.trim()\n : fallbackMessage;\n } catch (err) {\n return fallbackMessage;\n }\n }\n\n if (/<[^>]+>/.test(trimmed)) {\n return fallbackMessage;\n }\n\n return trimmed;\n },\n normalizeAssistantAppearance(appearance) {\n if (!appearance) {\n return null;\n }\n\n var label = typeof appearance.label === 'string' ? appearance.label.trim() : '';\n var icon = typeof appearance.icon === 'string' ? appearance.icon.trim() : '';\n var cssClass = typeof appearance.cssClass === 'string' ? appearance.cssClass.trim() : '';\n var disableStreamingAnimation = !!appearance.disableStreamingAnimation;\n\n if (!label && !icon && !cssClass && !disableStreamingAnimation) {\n return null;\n }\n\n return {\n label: label,\n icon: icon,\n cssClass: cssClass,\n disableStreamingAnimation: disableStreamingAnimation,\n };\n },\n getAssistantLabel(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return appearance && appearance.label ? appearance.label : this.assistantLabel;\n },\n getAssistantRoleClasses(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n var classes = ['ai-chat-msg-role'];\n\n if (appearance && appearance.cssClass) {\n classes.push(appearance.cssClass);\n } else {\n classes.push('ai-chat-msg-role-assistant');\n }\n\n return classes;\n },\n getAssistantIconClasses(message, index) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return [this.shouldAnimateAssistantIcon(message, index) ? 'ai-streaming-icon' : 'ai-bot-icon', appearance && appearance.cssClass ? appearance.cssClass : ''];\n },\n getAssistantIcon(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return appearance && appearance.icon ? appearance.icon : 'fa fa-robot';\n },\n shouldAnimateAssistantIcon(message, index) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return !!message &&\n message.isStreaming &&\n index === this.lastAssistantIndex &&\n !(appearance && appearance.disableStreamingAnimation);\n },\n async startConnection() {\n this.connection = new signalR.HubConnectionBuilder()\n .withUrl(config.signalRHubUrl)\n .withAutomaticReconnect()\n .build();\n\n // Allow long-running operations (e.g., multi-step MCP tool calls)\n // without the client disconnecting prematurely.\n this.connection.serverTimeoutInMilliseconds = 600000;\n this.connection.keepAliveIntervalInMilliseconds = 15000;\n\n this.connection.on(\"LoadSession\", (data) => {\n this.initializeSession(data.sessionId, true);\n this.messages = [];\n this.documents = data.documents || [];\n this.uploadErrors = [];\n\n (data.messages ?? []).forEach(msg => {\n this.addMessage(msg);\n\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n });\n });\n\n // Update feedback icons in the DOM after all messages have rendered.\n this.$nextTick(() => {\n this.refreshAllFeedbackIcons();\n });\n\n // When the session is new (no messages) and an initial prompt is configured,\n // automatically send it as the first user message to trigger an AI response.\n if (this.messages.length === 0 && config.initialPrompt) {\n this.prompt = config.initialPrompt;\n this.sendMessage();\n }\n });\n\n this.connection.on(\"ReceiveError\", (error) => {\n console.error(\"SignalR Error: \", error);\n\n if (this.isRecording) {\n this.stopRecording();\n }\n\n if (widgetBehavior && typeof widgetBehavior.handleReceiveError === 'function') {\n widgetBehavior.handleReceiveError(this, error, config);\n }\n });\n\n this.connection.on(\"MessageRated\", (messageId, userRating) => {\n var msg = this.messages.find(m => m.id === messageId);\n if (msg) {\n msg.userRating = userRating;\n }\n });\n\n this.connection.on(\"ReceiveTranscript\", (sessionId, text, isFinal) => {\n if (this.isConversationMode) {\n if (!isFinal && text) {\n this._conversationPartialTranscript = text;\n var escaped = text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n var html = '<p class=\"ai-partial-transcript\">' + escaped + '</p>';\n\n // Show partial transcript as a live user message.\n if (!this._conversationPartialMessage) {\n this.hidePlaceholder();\n this._conversationPartialMessage = {\n role: 'user',\n content: text,\n htmlContent: html,\n isPartial: true\n };\n this.messages.push(this._conversationPartialMessage);\n } else {\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = html;\n }\n this.scrollToBottom();\n }\n return;\n }\n\n if (text && !this._audioInputSent) {\n this.prompt = this.preRecordingPrompt + text;\n if (this.inputElement) {\n this.inputElement.value = this.prompt;\n this.inputElement.dispatchEvent(new Event('input'));\n }\n }\n });\n\n this.connection.on(\"ReceiveConversationUserMessage\", (sessionId, text) => {\n if (text) {\n this.stopAudio();\n\n // If there's an interrupted assistant message still streaming,\n // mark it as done to stop the spinner animation.\n if (this._conversationAssistantMessage) {\n var oldMsg = this.messages[this._conversationAssistantMessage.index];\n if (oldMsg) {\n oldMsg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Replace the partial transcript message with the final one.\n if (this._conversationPartialMessage) {\n var escaped = text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = '<p>' + escaped + '</p>';\n this._conversationPartialMessage.isPartial = false;\n this._conversationPartialMessage = null;\n } else {\n this.addMessage({\n role: 'user',\n content: text\n });\n }\n this.scrollToBottom();\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantToken\", (sessionId, messageId, token, responseId, references, appearance) => {\n if (!this._conversationAssistantMessage) {\n this.stopAudio();\n this.hideTypingIndicator();\n\n // Ensure no stale streaming indicators remain from prior messages.\n for (var j = 0; j < this.messages.length; j++) {\n if (this.messages[j].isStreaming) {\n this.messages[j].isStreaming = false;\n }\n }\n\n var msgIndex = this.messages.length;\n var newMessage = {\n id: messageId,\n role: \"assistant\",\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n userRating: null,\n appearance: this.normalizeAssistantAppearance(appearance),\n references: {},\n };\n this.messages.push(newMessage);\n this._conversationAssistantMessage = { index: msgIndex, content: '' };\n }\n\n this._conversationAssistantMessage.content += token;\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n if (!msg.appearance) {\n msg.appearance = this.normalizeAssistantAppearance(appearance);\n }\n msg.rawContent = this._conversationAssistantMessage.content;\n msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));\n updateMessagePresentation(msg, msg.references);\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n this.scrollToBottom();\n });\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantComplete\", (sessionId, messageId, references) => {\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));\n updateMessagePresentation(msg, msg.references);\n }\n this._conversationAssistantMessage = null;\n }\n });\n\n this.connection.on(\"ReceiveAudioChunk\", (sessionId, base64Audio, contentType) => {\n if (base64Audio) {\n const binaryString = atob(base64Audio);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n this.audioChunks.push(bytes);\n }\n });\n\n this.connection.on(\"ReceiveAudioComplete\", (sessionId) => {\n this.playCollectedAudio();\n });\n\n this.connection.on(\"ReceiveNotification\", (notification) => {\n this.receiveNotification(notification);\n });\n\n this.connection.on(\"UpdateNotification\", (notification) => {\n this.updateNotification(notification);\n });\n\n this.connection.on(\"RemoveNotification\", (notificationType) => {\n this.removeNotification(notificationType);\n });\n\n this.connection.onreconnecting(() => {\n console.warn(\"SignalR: reconnecting...\");\n });\n\n this.connection.onreconnected(() => {\n console.info(\"SignalR: reconnected.\");\n\n if (this.isSessionStarted) {\n this.reloadCurrentSession();\n } else if (config.autoCreateSession) {\n this.startNewSession();\n }\n });\n\n this.connection.onclose((error) => {\n if (this.isNavigatingAway) {\n return;\n }\n\n if (error) {\n console.warn(\"SignalR connection closed with error:\", error.message || error);\n }\n });\n\n try {\n await this.connection.start();\n } catch (err) {\n console.error(\"SignalR Connection Error: \", err);\n }\n },\n addMessageInternal(message) {\n if (message.role === 'assistant') {\n message.appearance = this.normalizeAssistantAppearance(message.appearance);\n }\n\n if (message.content && !message.htmlContent) {\n message.htmlContent = parseMarkdownContent(message.content, message);\n }\n this.fireEvent(new CustomEvent(\"addingOpenAIPromotMessage\", { detail: { message: message } }));\n this.messages.push(message);\n\n this.$nextTick(() => {\n this.fireEvent(new CustomEvent(\"addedOpenAIPromotMessage\", { detail: { message: message } }));\n });\n },\n addMessage(message) {\n\n // Ensure userRating is always defined for Vue reactivity.\n if (message.userRating === undefined) {\n message.userRating = null;\n }\n\n if (message.content) {\n message.rawContent = message.rawContent ?? message.content;\n updateMessagePresentation(message, message.references);\n }\n\n this.addMessageInternal(message);\n this.hidePlaceholder();\n\n this.$nextTick(() => {\n // Render any pending charts once the DOM is updated\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n addMessages(messages) {\n\n for (let i = 0; i < messages.length; i++) {\n this.addMessageInternal(messages[i]);\n }\n\n this.hidePlaceholder();\n this.$nextTick(() => {\n this.scrollToBottom();\n });\n },\n hidePlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.add('d-none');\n }\n this.isPlaceholderVisible = false;\n },\n showPlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.remove('d-none');\n }\n this.isPlaceholderVisible = true;\n },\n isOrchestratorAvailable() {\n return config.isOrchestratorAvailable !== false;\n },\n applyOrchestratorAvailability() {\n if (this.isOrchestratorAvailable()) {\n return true;\n }\n\n const unavailableMessage = config.orchestratorUnavailableMessage || \"This orchestrator is not currently available.\";\n\n if (this.inputElement) {\n this.inputElement.disabled = true;\n this.inputElement.value = '';\n this.inputElement.placeholder = unavailableMessage;\n }\n\n if (this.buttonElement) {\n this.buttonElement.disabled = true;\n }\n\n if (this.micButtonElement) {\n this.micButtonElement.disabled = true;\n this.micButtonElement.style.display = 'none';\n }\n\n if (this.conversationButtonElement) {\n this.conversationButtonElement.disabled = true;\n this.conversationButtonElement.style.display = 'none';\n }\n\n return false;\n },\n fireEvent(event) {\n document.dispatchEvent(event);\n },\n isIndicator(message) {\n return message.role === 'indicator';\n },\n sendMessage() {\n if (!this.applyOrchestratorAvailability()) {\n return;\n }\n\n let trimmedPrompt = this.prompt.trim();\n\n if (!trimmedPrompt) {\n return;\n }\n\n // Stop any active recording before sending.\n if (this.isRecording) {\n this.stopRecording();\n }\n\n // Prevent stale ReceiveTranscript events from repopulating the prompt.\n this._audioInputSent = true;\n\n // In single-response mode, clear all previous messages.\n if (this.singleResponseMode) {\n this.messages.splice(0, this.messages.length);\n }\n\n this.addMessage({\n role: 'user',\n content: trimmedPrompt\n });\n\n this.streamMessage(this.getProfileId(), trimmedPrompt, null);\n this.inputElement.value = '';\n this.prompt = '';\n },\n startRecording() {\n if (this.isRecording || !this.connection) {\n return;\n }\n\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this.preRecordingPrompt = this.prompt;\n this._audioInputSent = false;\n\n var subject = new signalR.Subject();\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var pendingChunk = Promise.resolve();\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n subject.next(base64);\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => subject.complete());\n });\n\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"SendAudioStream\", profileId, sessionId, subject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n this.updateMicButton();\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n });\n },\n stopRecording() {\n if (!this.isRecording || !this.mediaRecorder) {\n return;\n }\n\n this.mediaRecorder.stop();\n this.isRecording = false;\n this.updateMicButton();\n },\n toggleRecording() {\n if (this.isRecording) {\n this.stopRecording();\n } else {\n this.startRecording();\n }\n },\n updateMicButton() {\n if (!this.micButton) {\n return;\n }\n\n if (this.isRecording) {\n this.micButton.classList.add('stt-recording');\n this.micButton.innerHTML = '<i class=\"fa-solid fa-stop\"></i>';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '<i class=\"fa-solid fa-microphone\"></i>';\n }\n },\n streamMessage(profileId, trimmedPrompt, sessionProfileId) {\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n\n this.streamingStarted();\n this.showTypingIndicator();\n this.autoScroll = true;\n\n var content = '';\n var references = {};\n var lastResponseId = null;\n\n // Get the index after showing typing indicator.\n var messageIndex = this.messages.length;\n var currentSessionId = this.getSessionId();\n\n this.stream = this.connection.stream(\"SendMessage\", profileId, trimmedPrompt, currentSessionId, sessionProfileId)\n .subscribe({\n next: (chunk) => {\n let message = this.messages[messageIndex];\n\n if (!message) {\n\n if (chunk.sessionId && !currentSessionId) {\n this.initializeSession(chunk.sessionId);\n }\n\n this.hideTypingIndicator();\n // Re-assign the index after hiding the typing indicator.\n messageIndex = this.messages.length;\n let newMessage = {\n id: chunk.messageId,\n role: \"assistant\",\n title: chunk.title,\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n userRating: null,\n };\n\n this.messages.push(newMessage);\n\n message = newMessage;\n }\n\n if (chunk.title && (!message.title || message.title !== chunk.title)) {\n message.title = chunk.title;\n }\n\n if (chunk.references && typeof chunk.references === \"object\" && Object.keys(chunk.references).length) {\n\n for (const [key, value] of Object.entries(chunk.references)) {\n references[key] = normalizeReference(value) ?? {};\n }\n }\n\n if (chunk.content) {\n\n // When the responseId changes (e.g., after an internal tool call),\n // insert a line break to visually separate response segments.\n if (chunk.responseId && lastResponseId && chunk.responseId !== lastResponseId) {\n content += '\\n\\n';\n }\n\n if (chunk.responseId) {\n lastResponseId = chunk.responseId;\n }\n\n content += chunk.content;\n }\n\n // Update the existing message\n message.rawContent = content;\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n complete: () => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n if (!msg || !msg.content) {\n // No content received at all.\n this.hideTypingIndicator();\n }\n\n // Trigger text-to-speech only in conversation mode.\n if (this.isConversationMode && this.textToSpeechEnabled && msg && msg.content) {\n this.synthesizeSpeech(msg.content);\n }\n\n this.stream?.dispose();\n this.stream = null;\n },\n error: (err) => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n this.hideTypingIndicator();\n\n if (!this.isNavigatingAway) {\n this.addMessage(this.getServiceDownMessage());\n }\n\n this.stream?.dispose();\n this.stream = null;\n\n console.error(\"Stream error:\", err);\n }\n });\n },\n getServiceDownMessage() {\n let newMessage = {\n role: \"assistant\",\n content: \"Our service is currently unavailable. Please try again later. We apologize for the inconvenience.\",\n htmlContent: \"\",\n };\n\n return newMessage;\n },\n processReferences(references, messageIndex) {\n references = normalizeReferences(references);\n\n if (Object.keys(references).length) {\n\n let message = this.messages[messageIndex];\n message.rawContent = message.rawContent ?? message.content ?? '';\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n }\n },\n streamingStarted() {\n var stopIcon = this.buttonElement.getAttribute('data-stop-icon');\n\n if (stopIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(stopIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n if (this.inputElement) {\n this.inputElement.setAttribute('disabled', 'disabled');\n }\n },\n streamingFinished() {\n var startIcon = this.buttonElement.getAttribute('data-start-icon');\n\n if (startIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(startIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n if (this.inputElement) {\n this.inputElement.removeAttribute('disabled');\n this.inputElement.focus();\n }\n\n // Directly manipulate the DOM to stop all streaming animations.\n if (this.chatContainer) {\n var icons = this.chatContainer.querySelectorAll('.ai-streaming-icon');\n for (var i = 0; i < icons.length; i++) {\n icons[i].classList.remove('ai-streaming-icon');\n icons[i].classList.add('ai-bot-icon');\n }\n }\n\n // Also update Vue data for consistency.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n },\n handleExternalTtsStop(e) {\n if (e?.detail?.sourceId === this.ttsInstanceId) {\n return;\n }\n\n this.stopAudio(false);\n },\n updateTtsPlaybackButtons() {\n if (!this.chatContainer) {\n return;\n }\n\n var buttons = this.chatContainer.querySelectorAll('[data-tts-message-index]');\n\n buttons.forEach(button => {\n var buttonIndex = Number(button.getAttribute('data-tts-message-index'));\n var isPlaying = buttonIndex === this.ttsPlayingMessageIndex;\n\n button.classList.toggle('tts-playing', isPlaying);\n button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');\n });\n },\n synthesizeSpeech(text, cacheIndex) {\n if (!this.textToSpeechEnabled || !text || !this.connection) {\n return;\n }\n\n this.audioChunks = [];\n this.isPlayingAudio = true;\n this._ttsCacheIndex = cacheIndex !== undefined ? cacheIndex : -1;\n\n this.connection.invoke(\"SynthesizeSpeech\", this.getProfileId(), this.getSessionId(), text, this.ttsVoiceName)\n .catch(err => {\n console.error(\"TTS synthesis error:\", err);\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this._ttsCacheIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n });\n },\n toggleMessageTts(message, index) {\n if (this.ttsPlayingMessageIndex === index) {\n this.stopAudio();\n return;\n }\n\n this.stopAudio(false);\n window.dispatchEvent(new CustomEvent('crestapps-ai-chat-stop-tts', {\n detail: { sourceId: this.ttsInstanceId }\n }));\n this.ttsPlayingMessageIndex = index;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n\n if (this.ttsAudioCache[index]) {\n this.playAudioBlob(this.ttsAudioCache[index]);\n return;\n }\n\n this.synthesizeSpeech(message.content, index);\n },\n playCollectedAudio() {\n if (this.audioChunks.length === 0) {\n if (!this.currentAudioElement && this.audioPlayQueue.length === 0) {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n }\n return;\n }\n\n const totalLength = this.audioChunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const combined = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of this.audioChunks) {\n combined.set(chunk, offset);\n offset += chunk.length;\n }\n this.audioChunks = [];\n\n const blob = new Blob([combined], { type: 'audio/mp3' });\n\n if (this._ttsCacheIndex >= 0) {\n this.ttsAudioCache[this._ttsCacheIndex] = blob;\n this._ttsCacheIndex = -1;\n }\n\n // If audio is already playing, queue this blob for sequential playback.\n if (this.currentAudioElement) {\n this.audioPlayQueue.push(blob);\n return;\n }\n\n this.playAudioBlob(blob);\n },\n playAudioBlob(blob) {\n const url = URL.createObjectURL(blob);\n const audio = new Audio(url);\n\n this.currentAudioUrl = url;\n this.currentAudioElement = audio;\n this.isPlayingAudio = true;\n\n audio.addEventListener('ended', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.addEventListener('error', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.play().catch(err => {\n console.error(\"Audio playback error:\", err);\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n });\n },\n playNextInQueue() {\n if (this.audioPlayQueue.length > 0) {\n var nextBlob = this.audioPlayQueue.shift();\n this.playAudioBlob(nextBlob);\n } else {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n this.conversationModeOnAudioEnded();\n }\n },\n stopAudio() {\n if (this.currentAudioElement) {\n this.currentAudioElement.pause();\n this.currentAudioElement.currentTime = 0;\n this.currentAudioElement = null;\n }\n if (this.currentAudioUrl) {\n URL.revokeObjectURL(this.currentAudioUrl);\n this.currentAudioUrl = null;\n }\n this.audioChunks = [];\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n },\n toggleConversationMode() {\n if (this.isConversationMode) {\n this.stopConversationMode();\n } else {\n this.startConversationMode();\n }\n },\n startConversationMode() {\n if (!this.conversationModeEnabled || this.isConversationMode || !this.connection) {\n return;\n }\n\n this.isConversationMode = true;\n this.updateConversationButton();\n this._conversationPartialTranscript = '';\n this._conversationAssistantMessage = null;\n this._conversationPartialMessage = null;\n\n // Remove any previous conversation ended notification.\n this.removeNotification('conversation-ended');\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this._conversationSubject = new signalR.Subject();\n this._conversationStream = stream;\n\n // Create an AnalyserNode for volume-based interrupt detection.\n // During TTS playback, detect when the user speaks above\n // the threshold to stop TTS (interrupt). Audio chunks are\n // always forwarded — browser echo cancellation handles\n // speaker echo so the STT stream has no gaps.\n var AudioCtx = window.AudioContext || window.webkitAudioContext;\n if (AudioCtx) {\n this._conversationAudioCtx = new AudioCtx();\n this._conversationAnalyser = this._conversationAudioCtx.createAnalyser();\n this._conversationAnalyser.fftSize = 256;\n var micSource = this._conversationAudioCtx.createMediaStreamSource(stream);\n micSource.connect(this._conversationAnalyser);\n }\n\n var pendingChunk = Promise.resolve();\n var analyser = this._conversationAnalyser;\n var interruptVolumeThreshold = 30;\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n // During TTS playback, check mic volume to detect\n // user interruption (speaking above threshold).\n if (this.isPlayingAudio && analyser) {\n var freqData = new Uint8Array(analyser.frequencyBinCount);\n analyser.getByteFrequencyData(freqData);\n var sum = 0;\n for (var k = 0; k < freqData.length; k++) { sum += freqData[k]; }\n var avg = sum / freqData.length;\n\n if (avg >= interruptVolumeThreshold) {\n // User is speaking — interrupt TTS playback.\n this.stopAudio();\n }\n }\n\n // Always send audio to STT — browser echo cancellation\n // handles speaker echo; continuous audio avoids gaps\n // that increase recognition latency.\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n try {\n this._conversationSubject.next(base64);\n } catch (err) {\n // Subject may have been completed already.\n }\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => {\n try {\n this._conversationSubject.complete();\n } catch (err) {\n // Already completed.\n }\n });\n });\n\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var language = navigator.language || document.documentElement.lang || 'en-US';\n\n this.connection.send(\"StartConversation\", profileId, sessionId, this._conversationSubject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n this.isConversationMode = false;\n this.updateConversationButton();\n });\n },\n stopConversationMode() {\n if (!this.isConversationMode) {\n return;\n }\n\n this.isConversationMode = false;\n this.updateConversationButton();\n\n // Signal the server to cancel all in-progress STT/TTS streams immediately.\n if (this.connection) {\n this.connection.invoke(\"StopConversation\").catch(function () { });\n }\n\n if (this.isRecording && this.mediaRecorder) {\n this.mediaRecorder.stop();\n this.isRecording = false;\n }\n\n this.stopAudio();\n this._conversationPartialTranscript = '';\n this._conversationPartialMessage = null;\n\n // Clean up the AudioContext used for volume monitoring.\n if (this._conversationAudioCtx) {\n this._conversationAudioCtx.close().catch(function () { });\n this._conversationAudioCtx = null;\n this._conversationAnalyser = null;\n }\n\n // Mark any in-flight assistant message as done to stop the spinner.\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Safety net: clear all lingering streaming indicators.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n\n // Show a \"conversation ended\" notification system message.\n this.receiveNotification({\n type: 'conversation-ended',\n content: 'Conversation ended.',\n icon: 'fa-solid fa-circle-check',\n dismissible: true,\n autoDismissMs: 5000\n });\n },\n updateConversationButton() {\n if (!this.conversationButton) {\n return;\n }\n\n if (this.isConversationMode) {\n this.conversationButton.classList.add('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-dark', 'btn-outline-secondary');\n this.conversationButton.title = this.conversationButton.getAttribute('data-end-title') || 'End Conversation';\n var endHtml = this.conversationButton.getAttribute('data-end-html');\n if (endHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(endHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n } else {\n this.conversationButton.classList.remove('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-secondary');\n this.conversationButton.classList.add('btn-outline-dark');\n this.conversationButton.blur();\n this.conversationButton.title = this.conversationButton.getAttribute('data-start-title') || 'Start Conversation';\n var startHtml = this.conversationButton.getAttribute('data-start-html');\n if (startHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(startHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n }\n },\n conversationModeSendPrompt() {\n // Legacy: only used by AudioInput mode's ReceiveTranscript.\n },\n conversationModeOnAudioEnded() {\n // Legacy: in conversation mode, audio playback continuation\n // is handled by the persistent stream. This method is only\n // called from playCollectedAudio for non-conversation TTS.\n },\n generatePrompt(element) {\n if (!element) {\n console.error('The element paramter is required.');\n\n return;\n }\n\n let templateProfileId = element.getAttribute('data-profile-id');\n let sessionId = this.getSessionId();\n let sessionProfileId = this.getProfileId();\n\n if (!templateProfileId || !sessionId) {\n\n console.error('The given element is missing data-profile-id or the session has not yet started.');\n return;\n }\n\n // streamMessage() already shows the typing indicator.\n this.streamMessage(templateProfileId, null, sessionProfileId);\n },\n createSessionUrl(baseUrl, param, value) {\n\n const fullUrl = baseUrl.toLowerCase().startsWith('http') ? baseUrl : window.location.origin + baseUrl;\n const url = new URL(fullUrl);\n\n url.searchParams.set(param, value);\n\n return url.toString();\n },\n showTypingIndicator() {\n this.addMessage({\n role: 'indicator',\n htmlContent: config.indicatorTemplate\n });\n },\n hideTypingIndicator() {\n const originalLength = this.messages.length;\n this.messages = this.messages.filter(msg => msg.role !== 'indicator');\n const removedCount = originalLength - this.messages.length;\n return removedCount;\n },\n receiveNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var existingIndex = this.notifications.findIndex(n => n.type === notification.type);\n if (existingIndex >= 0) {\n this.notifications.splice(existingIndex, 1, notification);\n } else {\n this.notifications.push(notification);\n }\n this.scheduleNotificationDismiss(notification);\n this.$nextTick(() => {\n this.scrollToBottom();\n });\n },\n updateNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var existingIndex = this.notifications.findIndex(n => n.type === notification.type);\n if (existingIndex >= 0) {\n this.notifications.splice(existingIndex, 1, notification);\n this.scheduleNotificationDismiss(notification);\n }\n },\n scheduleNotificationDismiss(notification) {\n if (!notification || !notification.type || !notification.autoDismissMs || notification.autoDismissMs <= 0) {\n return;\n }\n this.notificationDismissTimers[notification.type] = setTimeout(() => {\n this.removeNotification(notification.type);\n }, notification.autoDismissMs);\n },\n clearNotificationDismiss(notificationType) {\n var timerId = this.notificationDismissTimers[notificationType];\n if (!timerId) {\n return;\n }\n clearTimeout(timerId);\n delete this.notificationDismissTimers[notificationType];\n },\n removeNotification(notificationType) {\n this.clearNotificationDismiss(notificationType);\n this.notifications = this.notifications.filter(n => n.type !== notificationType);\n },\n dismissNotification(notificationType) {\n this.removeNotification(notificationType);\n },\n handleNotificationAction(notificationType, actionName) {\n if (!this.connection) {\n return;\n }\n var sessionId = this.getSessionId();\n this.connection.invoke(\"HandleNotificationAction\", sessionId, notificationType, actionName).catch(function (err) {\n console.error(\"Error handling notification action:\", err);\n });\n },\n scrollToBottom() {\n if (!this.autoScroll) {\n return;\n }\n setTimeout(() => {\n this.chatContainer.scrollTop = this.chatContainer.scrollHeight - this.chatContainer.clientHeight;\n }, 50);\n },\n handleUserInput(event) {\n this.prompt = event.target.value;\n },\n getProfileId() {\n return this.inputElement\n ? this.inputElement.getAttribute('data-profile-id')\n : null;\n },\n setSessionId(sessionId) {\n if (!this.inputElement) {\n return;\n }\n\n this.inputElement.setAttribute('data-session-id', sessionId || '');\n },\n resetSession() {\n this.stopRecording();\n this.rejectPendingSessionRequest('Session was reset.');\n this.setSessionId('');\n this.isSessionStarted = false;\n this.sessionRating = null;\n this.messages = [];\n this.documents = [];\n if (!config.autoCreateSession) {\n this.showPlaceholder();\n }\n\n if (config.autoCreateSession) {\n this.startNewSession();\n }\n\n if (widgetBehavior && typeof widgetBehavior.onSessionReset === 'function') {\n widgetBehavior.onSessionReset(this, config);\n }\n },\n startNewSession() {\n if (!this.applyOrchestratorAvailability()) {\n return;\n }\n\n const profileId = this.getProfileId();\n if (!profileId || !this.connection) {\n return;\n }\n\n this.requestNewSession(profileId).catch(err => console.error(err));\n },\n async ensureSessionForDocuments(profileId) {\n var sessionId = this.getSessionId();\n if (sessionId) {\n return sessionId;\n }\n\n if (!profileId || !this.connection) {\n return null;\n }\n\n return await this.requestNewSession(profileId);\n },\n requestNewSession(profileId) {\n if (this.pendingSessionPromise) {\n return this.pendingSessionPromise;\n }\n\n if (!profileId || !this.connection) {\n return Promise.resolve(null);\n }\n\n this.pendingSessionPromise = new Promise((resolve, reject) => {\n this.pendingSessionResolver = resolve;\n this.pendingSessionRejector = reject;\n this.pendingSessionTimeoutId = window.setTimeout(() => {\n this.rejectPendingSessionRequest('Timed out while creating a chat session.');\n }, 15000);\n });\n\n this.connection.invoke(\"StartSession\", profileId, null).catch(err => {\n this.rejectPendingSessionRequest(err);\n });\n\n return this.pendingSessionPromise;\n },\n resolvePendingSessionRequest(sessionId) {\n if (this.pendingSessionResolver) {\n this.pendingSessionResolver(sessionId);\n }\n\n this.clearPendingSessionRequest();\n },\n rejectPendingSessionRequest(error) {\n if (this.pendingSessionRejector) {\n this.pendingSessionRejector(error);\n }\n\n this.clearPendingSessionRequest();\n },\n clearPendingSessionRequest() {\n if (this.pendingSessionTimeoutId) {\n window.clearTimeout(this.pendingSessionTimeoutId);\n }\n\n this.pendingSessionPromise = null;\n this.pendingSessionResolver = null;\n this.pendingSessionRejector = null;\n this.pendingSessionTimeoutId = null;\n },\n initializeApp() {\n this.inputElement = document.querySelector(config.inputElementSelector);\n this.buttonElement = document.querySelector(config.sendButtonElementSelector);\n this.chatContainer = document.querySelector(config.chatContainerElementSelector);\n this.placeholder = document.querySelector(config.placeholderElementSelector);\n\n if (!this.inputElement || !this.buttonElement || !this.chatContainer || !this.placeholder) {\n console.error('AI chat app could not initialize because one or more required elements were not found.', {\n inputElementSelector: config.inputElementSelector,\n sendButtonElementSelector: config.sendButtonElementSelector,\n chatContainerElementSelector: config.chatContainerElementSelector,\n placeholderElementSelector: config.placeholderElementSelector\n });\n\n return false;\n }\n\n this.applyOrchestratorAvailability();\n\n const sessionId = this.getSessionId();\n if (!hasWidgetConfig && sessionId) {\n this.loadSession(sessionId);\n } else if (this.isOrchestratorAvailable() && config.autoCreateSession && !hasWidgetConfig && !sessionId) {\n this.startNewSession();\n }\n\n // Initialize document bar if enabled.\n if (config.sessionDocumentsEnabled && config.documentBarSelector) {\n this.documentBar = document.querySelector(config.documentBarSelector);\n if (this.documentBar) {\n this.renderDocumentBar();\n\n // Create hidden file input for document uploads.\n var fileInput = document.createElement('input');\n fileInput.type = 'file';\n fileInput.id = 'ai-chat-doc-input';\n fileInput.className = 'd-none';\n fileInput.multiple = true;\n if (config.allowedExtensions) {\n fileInput.accept = config.allowedExtensions;\n }\n fileInput.addEventListener('change', (e) => this.handleFileInputChange(e));\n this.documentBar.parentElement.appendChild(fileInput);\n\n // Set up drag-and-drop on the input area.\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) {\n inputArea.addEventListener('dragover', (e) => this.handleDragOver(e));\n inputArea.addEventListener('dragleave', (e) => this.handleDragLeave(e));\n inputArea.addEventListener('drop', (e) => this.handleDrop(e));\n }\n }\n }\n\n // Pause auto-scroll when the user manually scrolls up during streaming.\n this.chatContainer.addEventListener('scroll', () => {\n if (!this.stream) {\n return;\n }\n const threshold = 30;\n const atBottom = this.chatContainer.scrollHeight - this.chatContainer.clientHeight - this.chatContainer.scrollTop <= threshold;\n this.autoScroll = atBottom;\n });\n\n this.inputElement.addEventListener('keydown', event => {\n\n if (this.stream != null) {\n return;\n }\n\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n this.buttonElement.click();\n }\n });\n\n this.inputElement.addEventListener('input', (e) => {\n this.handleUserInput(e);\n\n if (e.target.value.trim()) {\n this.buttonElement.removeAttribute('disabled');\n } else {\n this.buttonElement.setAttribute('disabled', true);\n }\n });\n\n this.buttonElement.addEventListener('click', () => {\n\n if (this.stream != null) {\n this.stream.dispose();\n this.stream = null;\n\n this.streamingFinished();\n this.hideTypingIndicator();\n\n // Clean up: remove empty assistant message or stop streaming animation.\n if (this.messages.length > 0) {\n const lastMsg = this.messages[this.messages.length - 1];\n if (lastMsg.role === 'assistant' && !lastMsg.content) {\n this.messages.pop();\n } else if (lastMsg.isStreaming) {\n lastMsg.isStreaming = false;\n }\n }\n\n return;\n }\n\n this.sendMessage();\n });\n\n const promptGenerators = document.getElementsByClassName('profile-generated-prompt');\n\n for (var i = 0; i < promptGenerators.length; i++) {\n promptGenerators[i].addEventListener('click', (e) => {\n e.preventDefault();\n this.generatePrompt(e.target);\n });\n }\n\n const chatSessions = document.getElementsByClassName('chat-session-history-item');\n\n for (var i = 0; i < chatSessions.length; i++) {\n chatSessions[i].addEventListener('click', (e) => {\n e.preventDefault();\n\n var sessionId = e.target.getAttribute('data-session-id');\n\n if (!sessionId) {\n console.error('an element with the class chat-session-history-item with no data-session-id set.');\n\n return;\n }\n\n this.loadSession(sessionId);\n this.showChatScreen();\n });\n }\n\n for (let i = 0; i < config.messages.length; i++) {\n this.addMessage(config.messages[i]);\n }\n\n // Update feedback icons in the DOM after initial messages have rendered.\n this.$nextTick(() => {\n this.refreshAllFeedbackIcons();\n });\n\n // Delegate click for code block copy buttons.\n if (this.chatContainer) {\n this.chatContainer.addEventListener('click', (e) => {\n var btn = e.target.closest('.ai-code-copy-btn');\n if (!btn) {\n return;\n }\n\n var block = btn.closest('.ai-code-block') || btn.closest('pre');\n if (!block) {\n return;\n }\n\n var codeEl = block.querySelector('code');\n if (codeEl) {\n navigator.clipboard.writeText(codeEl.textContent);\n var copiedText = config.codeCopiedText || 'Copied!';\n btn.innerHTML = '<i class=\"fa-solid fa-check\"></i> ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '<i class=\"fa-regular fa-copy\"></i>';\n }, 2000);\n }\n });\n }\n\n // Initialize speech-to-text microphone button.\n if (this.speechToTextEnabled && config.micButtonElementSelector) {\n this.micButton = document.querySelector(config.micButtonElementSelector);\n if (this.micButton) {\n this.micButton.style.display = '';\n this.micButton.addEventListener('click', () => {\n this.toggleRecording();\n });\n }\n }\n\n // Initialize conversation mode button.\n if (this.conversationModeEnabled && config.conversationButtonElementSelector) {\n this.conversationButton = document.querySelector(config.conversationButtonElementSelector);\n if (this.conversationButton) {\n this.conversationButton.addEventListener('click', () => {\n this.toggleConversationMode();\n });\n }\n }\n\n return true;\n },\n loadSession(sessionId) {\n this.connection.invoke(\"LoadSession\", sessionId).catch(err => console.error(err));\n },\n reloadCurrentSession() {\n\n var sessionId = this.getSessionId();\n if (sessionId) {\n this.loadSession(sessionId);\n }\n },\n initializeSession(sessionId, force) {\n if (this.isSessionStarted && !force) {\n if (sessionId && this.getSessionId() === sessionId) {\n this.resolvePendingSessionRequest(sessionId);\n }\n\n return\n }\n this.fireEvent(new CustomEvent(\"initializingSessionOpenAIChat\", { detail: { sessionId: sessionId } }))\n this.setSessionId(sessionId);\n this.isSessionStarted = true;\n this.resolvePendingSessionRequest(sessionId);\n\n if (widgetBehavior && typeof widgetBehavior.onSessionInitialized === 'function') {\n widgetBehavior.onSessionInitialized(this, sessionId, config);\n }\n },\n getSessionId() {\n let sessionId = this.inputElement\n ? this.inputElement.getAttribute('data-session-id')\n : null;\n\n if (!sessionId && widgetBehavior && typeof widgetBehavior.resolveSessionId === 'function') {\n sessionId = widgetBehavior.resolveSessionId(this, config);\n }\n\n return sessionId;\n },\n copyResponse(message) {\n const text = message && typeof message === 'object'\n ? message.copyContent ?? message.content ?? ''\n : message ?? '';\n\n navigator.clipboard.writeText(text);\n },\n updateFeedbackIcons(container, userRating) {\n if (!container) {\n return;\n }\n\n var upBtn = container.querySelector('.rate-up-btn');\n var downBtn = container.querySelector('.rate-down-btn');\n\n // Keep feedback icons as simple span-based Font Awesome markup so\n // later state updates do not depend on i2svg replacement.\n if (upBtn) {\n var upClass = userRating === true ? 'fa-solid fa-thumbs-up' : 'fa-regular fa-thumbs-up';\n var upIcon = document.createElement('span');\n upIcon.className = upClass;\n upIcon.style.fontSize = '0.9rem';\n upBtn.textContent = '';\n upBtn.appendChild(upIcon);\n }\n\n if (downBtn) {\n var downClass = userRating === false ? 'fa-solid fa-thumbs-down' : 'fa-regular fa-thumbs-down';\n var downIcon = document.createElement('span');\n downIcon.className = downClass;\n downIcon.style.fontSize = '0.9rem';\n downBtn.textContent = '';\n downBtn.appendChild(downIcon);\n }\n },\n refreshAllFeedbackIcons() {\n var containers = this.$el.querySelectorAll('.ai-chat-message-assistant-feedback');\n\n for (var i = 0; i < containers.length; i++) {\n var msgId = containers[i].getAttribute('data-message-id');\n var msg = this.messages.find(m => m.id === msgId);\n\n if (msg) {\n this.updateFeedbackIcons(containers[i], msg.userRating);\n }\n }\n },\n rateMessage(message, isPositive, event) {\n var sessionId = this.getSessionId();\n\n if (!sessionId || !message.id || !this.connection) {\n return;\n }\n\n // Toggle: clicking the same rating again clears it.\n var newRating = message.userRating === isPositive ? null : isPositive;\n message.userRating = newRating;\n\n // Find the feedback container by message ID for reliable DOM targeting.\n var feedbackContainer = this.$el.querySelector(\n '.ai-chat-message-assistant-feedback[data-message-id=\"' + message.id + '\"]'\n );\n\n this.updateFeedbackIcons(feedbackContainer, newRating);\n\n // Trigger spark animation after Font Awesome has re-processed icons.\n if (newRating !== null && feedbackContainer) {\n setTimeout(() => {\n var btnClass = isPositive ? '.rate-up-btn' : '.rate-down-btn';\n var btn = feedbackContainer.querySelector(btnClass);\n\n if (btn) {\n btn.classList.remove('spark-effect');\n void btn.offsetWidth;\n btn.classList.add('spark-effect');\n btn.addEventListener('animationend', function onEnd() {\n btn.removeEventListener('animationend', onEnd);\n btn.classList.remove('spark-effect');\n });\n }\n }, 50);\n }\n\n this.connection.invoke(\"RateMessage\", sessionId, message.id, isPositive).catch(function (err) {\n console.error('Failed to rate message:', err);\n });\n }\n },\n watch: {\n documents: {\n handler() {\n this.renderDocumentBar();\n if (widgetBehavior && typeof widgetBehavior.onDocumentsChanged === 'function') {\n widgetBehavior.onDocumentsChanged(this, this.documents, config);\n }\n },\n deep: true\n },\n isUploading() { this.renderDocumentBar(); },\n isDocumentOperationPending() { this.renderDocumentBar(); },\n isPlayingAudio() {\n // Reserved for future use — volume-based interrupt detection\n // no longer mutes tracks; browser echo cancellation handles echo.\n },\n isConversationMode(active) {\n // Hide/show mic button.\n if (this.micButton) {\n this.micButton.style.display = active ? 'none' : (this.speechToTextEnabled ? '' : 'none');\n }\n\n // Hide/show send button.\n if (this.buttonElement) {\n this.buttonElement.style.display = active ? 'none' : '';\n }\n\n // Disable/enable textarea.\n if (this.inputElement) {\n this.inputElement.disabled = active;\n if (active) {\n this.inputElement.placeholder = '';\n }\n }\n }\n },\n mounted() {\n (async () => {\n await this.startConnection();\n const isInitialized = this.initializeApp();\n if (isInitialized && hasWidgetConfig && widgetBehavior && typeof widgetBehavior.onMounted === 'function') {\n widgetBehavior.onMounted(this, config);\n }\n\n this.$nextTick(() => {\n refreshFontAwesomeIcons(this.$el);\n this.fontAwesomeObserver = observeFontAwesomeIcons(this.$el);\n });\n })();\n\n window.addEventListener('beforeunload', this.handleBeforeUnload);\n window.addEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n },\n beforeUnmount() {\n window.removeEventListener('beforeunload', this.handleBeforeUnload);\n window.removeEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n\n if (this.fontAwesomeObserver) {\n this.fontAwesomeObserver.disconnect();\n this.fontAwesomeObserver = null;\n }\n\n this.stopAudio(false);\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n if (this.connection) {\n this.connection.stop();\n }\n\n if (widgetBehavior && typeof widgetBehavior.onBeforeUnmount === 'function') {\n widgetBehavior.onBeforeUnmount(this, config);\n }\n },\n template: config.messageTemplate\n };\n\n const app = Vue.createApp(appDefinition).mount(config.appElementSelector);\n\n if (widgetBehavior && typeof widgetBehavior.attach === 'function') {\n widgetBehavior.attach(app, config);\n }\n\n return app;\n };\n\n return {\n initialize: initialize\n };\n}();\n\n// Download chart as image via event delegation (DOMPurify strips inline onclick).\ndocument.addEventListener('click', function (e) {\n const btn = e.target.closest('.download-chart-btn');\n if (!btn) {\n return;\n }\n const chartId = btn.getAttribute('data-chart-id');\n const canvas = chartId ? document.getElementById(chartId) : null;\n if (!canvas) {\n console.error('Chart canvas not found:', chartId);\n return;\n }\n const link = document.createElement('a');\n link.download = 'chart-' + chartId + '.png';\n link.href = canvas.toDataURL('image/png');\n link.click();\n});\n\n// Intercept download clicks for data-URI images and convert to blob downloads.\ndocument.addEventListener('click', function (e) {\n const link = e.target.closest('.ai-download-image');\n if (!link) {\n return;\n }\n\n const container = link.closest('.generated-image-container');\n const img = container?.querySelector('img');\n if (!img) {\n return;\n }\n\n const src = img.src;\n if (!src || !src.startsWith('data:')) {\n return; // Normal URL – let the default <a> behaviour handle it.\n }\n\n e.preventDefault();\n\n fetch(src)\n .then(function (res) { return res.blob(); })\n .then(function (blob) {\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = link.getAttribute('download') || 'generated-image.png';\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n setTimeout(function () { URL.revokeObjectURL(url); }, 100);\n })\n .catch(function (err) { console.error('Failed to download image:', err); });\n});\n"]}