@crestapps/ai-chat-ui 1.0.0-preview.11 → 1.0.0-preview.13

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","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","widgetBehavior","openAIChatWidgetBehavior","signalRHubUrl","appElementSelector","chatContainerElementSelector","inputElementSelector","sendButtonElementSelector","appDefinition","inputElement","buttonElement","chatContainer","placeholder","isSessionStarted","isPlaceholderVisible","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","Math","random","singleResponseMode","conversationModeEnabled","conversationButton","isConversationMode","notificationDismissTimers","computed","lastAssistantIndex","role","methods","handleBeforeUnload","handleDragOver","sessionDocumentsEnabled","preventDefault","stopPropagation","inputArea","closest","classList","add","handleDragLeave","remove","handleDrop","dataTransfer","files","uploadFiles","triggerFileInput","fileInput","click","handleFileInputChange","target","_this","_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","_this2","_callee2","removeError","_t2","_context2","removeDocumentUrl","headers","stringify","itemId","documentId","splice","status","formatFileSize","bytes","toFixed","escapeHtml","failedItem","failedName","errorMsg","supportedExtensionsText","replaceChildren","RETURN_DOM_FRAGMENT","self","closeButtons","querySelectorAll","addEventListener","docToRemove","parseInt","getAttribute","errorCloseButtons","addBtn","querySelector","div","fallbackMessage","startsWith","parsed","title","detail","normalizeAssistantAppearance","appearance","label","icon","cssClass","disableStreamingAnimation","getAssistantLabel","getAssistantRoleClasses","classes","getAssistantIconClasses","shouldAnimateAssistantIcon","getAssistantIcon","startConnection","_this3","_callee3","_t3","_context3","connection","signalR","HubConnectionBuilder","withUrl","withAutomaticReconnect","build","serverTimeoutInMilliseconds","keepAliveIntervalInMilliseconds","on","_data$messages","forEach","msg","addMessage","$nextTick","refreshAllFeedbackIcons","initialPrompt","sendMessage","stopRecording","handleReceiveError","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","startNewSession","onclose","addMessageInternal","_this4","fireEvent","CustomEvent","_this5","processedContent","citedRefs","filter","_ref4","includes","sort","_ref6","_ref7","b","_step2","displayIndex","_iterator2","_step2$value","replaceAll","_displayIndex","_placeholder","_step3","_iterator3","_step4","_iterator4","_step4$value","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","_callee4","uint8Array","base64","_context4","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","_i3","_Object$entries2","_normalizeReference2","_Object$entries2$_i","_i4","_Object$entries3","_Object$entries3$_i","_this8$stream","processReferences","streamingFinished","synthesizeSpeech","_this8$stream2","getServiceDownMessage","_this9","_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","updateTtsPlaybackButtons","_this0","button","isPlaying","Number","iconHtml","toggle","cacheIndex","_this1","_ttsCacheIndex","invoke","toggleMessageTts","_this10","playAudioBlob","_this11","_step8","totalLength","sum","combined","offset","_iterator8","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","_callee5","_context5","close","dismissible","autoDismissMs","endHtml","blur","startHtml","conversationModeSendPrompt","generatePrompt","element","templateProfileId","createSessionUrl","baseUrl","param","fullUrl","toLowerCase","location","origin","searchParams","originalLength","_this16","clearNotificationDismiss","existingIndex","findIndex","scheduleNotificationDismiss","_this17","setTimeout","timerId","clearTimeout","dismissNotification","handleNotificationAction","actionName","_this18","scrollTop","scrollHeight","clientHeight","handleUserInput","setSessionId","resetSession","sessionRating","onSessionReset","initializeApp","_this19","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","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","_this20","_callee6","_context6","onMounted","beforeUnmount","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)\"><span :class=\"getAssistantIcon(message)\"></span></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 <span class=\"fa-regular fa-thumbs-up\"></span>\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 <span class=\"fa-regular fa-thumbs-down\"></span>\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 }\" :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 class=\"btn btn-sm btn-link text-secondary p-0 button-message-toolbox\" @click=\"copyResponse(message.content)\" :title=\"copyTitle\">\n <span class=\"fa-solid fa-copy\"></span>\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 <span v-if=\"notification.icon\" :class=\"notification.icon\" class=\"ai-chat-notification-icon\"></span>\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 <span class=\"fa-solid fa-xmark\"></span>\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 <span v-if=\"action.icon\" :class=\"action.icon\" class=\"me-1\"></span>\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\"><span class=\"fa fa-robot\" style=\"display: inline-block;\"></span></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\"><span class=\"fa-solid fa-code\"></span> ${langDisplay}</span><button type=\"button\" class=\"ai-code-copy-btn\" title=\"Copy code\"><span class=\"fa-regular fa-copy\"></span></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 <span class=\"fa-solid fa-download\"></span>\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 + `<span class=\"fa-solid fa-download\"></span> ${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 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 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 += '<span class=\"fa-solid fa-file-lines\" style=\"font-size: 0.7rem;\"></span> ';\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 += '<span class=\"fa-solid fa-circle-exclamation\" style=\"font-size: 0.7rem;\"></span> ';\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 += '<span class=\"fa-solid fa-paperclip\"></span>';\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 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, 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 = '<span class=\"fa-solid fa-stop\"></span>';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '<span class=\"fa-solid fa-microphone\"></span>';\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 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 var iconHtml = isPlaying\n ? '<span class=\"fa-solid fa-circle-pause\"></span>'\n : '<span class=\"fa-solid fa-circle-play\"></span>';\n\n button.classList.toggle('tts-playing', isPlaying);\n button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\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.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 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.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 = '<span class=\"fa-solid fa-check\"></span> ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '<span class=\"fa-regular fa-copy\"></span>';\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 (widgetBehavior && typeof widgetBehavior.onSessionInitialized === 'function') {\n widgetBehavior.onSessionInitialized(this, sessionId, config);\n }\n },\n getSessionId() {\n let sessionId = this.inputElement.getAttribute('data-session-id');\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 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 // 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 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 && widgetBehavior && typeof widgetBehavior.onMounted === 'function') {\n widgetBehavior.onMounted(this, config);\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 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"]}
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","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","widgetBehavior","openAIChatWidgetBehavior","signalRHubUrl","appElementSelector","chatContainerElementSelector","inputElementSelector","sendButtonElementSelector","appDefinition","inputElement","buttonElement","chatContainer","placeholder","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","querySelector","div","fallbackMessage","startsWith","parsed","title","detail","normalizeAssistantAppearance","appearance","label","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","forEach","msg","addMessage","$nextTick","refreshAllFeedbackIcons","initialPrompt","sendMessage","stopRecording","handleReceiveError","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","autoCreateSession","startNewSession","onclose","addMessageInternal","_this4","fireEvent","CustomEvent","_this5","processedContent","citedRefs","filter","_ref7","includes","sort","_ref9","_ref0","b","_step2","displayIndex","_iterator2","_step2$value","replaceAll","_displayIndex","_placeholder","_step3","_iterator3","_step4","_iterator4","_step4$value","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","_i3","_Object$entries2","_normalizeReference2","_Object$entries2$_i","_i4","_Object$entries3","_Object$entries3$_i","_this8$stream","processReferences","streamingFinished","synthesizeSpeech","_this8$stream2","getServiceDownMessage","_this9","_ref12","_ref13","_ref14","_ref15","_step5","processed","_iterator5","_step5$value","_step6","_iterator6","_step7","_iterator7","_step7$value","stopIcon","setAttribute","startIcon","removeAttribute","focus","icons","handleExternalTtsStop","_e$detail","sourceId","updateTtsPlaybackButtons","_this0","button","isPlaying","Number","iconHtml","toggle","cacheIndex","_this1","_ttsCacheIndex","invoke","toggleMessageTts","_this10","playAudioBlob","_this11","_step8","totalLength","sum","combined","offset","_iterator8","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","toLowerCase","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","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","beforeUnmount","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)\"><span :class=\"getAssistantIcon(message)\"></span></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 <span class=\"fa-regular fa-thumbs-up\"></span>\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 <span class=\"fa-regular fa-thumbs-down\"></span>\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 }\" :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 class=\"btn btn-sm btn-link text-secondary p-0 button-message-toolbox\" @click=\"copyResponse(message.content)\" :title=\"copyTitle\">\n <span class=\"fa-solid fa-copy\"></span>\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 <span v-if=\"notification.icon\" :class=\"notification.icon\" class=\"ai-chat-notification-icon\"></span>\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 <span class=\"fa-solid fa-xmark\"></span>\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 <span v-if=\"action.icon\" :class=\"action.icon\" class=\"me-1\"></span>\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\"><span class=\"fa fa-robot\" style=\"display: inline-block;\"></span></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\"><span class=\"fa-solid fa-code\"></span> ${langDisplay}</span><button type=\"button\" class=\"ai-code-copy-btn\" title=\"Copy code\"><span class=\"fa-regular fa-copy\"></span></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 <span class=\"fa-solid fa-download\"></span>\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 + `<span class=\"fa-solid fa-download\"></span> ${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 += '<span class=\"fa-solid fa-file-lines\" style=\"font-size: 0.7rem;\"></span> ';\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 += '<span class=\"fa-solid fa-circle-exclamation\" style=\"font-size: 0.7rem;\"></span> ';\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 += '<span class=\"fa-solid fa-paperclip\"></span>';\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, 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 = '<span class=\"fa-solid fa-stop\"></span>';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '<span class=\"fa-solid fa-microphone\"></span>';\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 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 var iconHtml = isPlaying\n ? '<span class=\"fa-solid fa-circle-pause\"></span>'\n : '<span class=\"fa-solid fa-circle-play\"></span>';\n\n button.classList.toggle('tts-playing', isPlaying);\n button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\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 = '<span class=\"fa-solid fa-check\"></span> ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '<span class=\"fa-regular fa-copy\"></span>';\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 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 // 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\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 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"]}