@crestapps/ai-chat-ui 1.0.0-preview.95 → 1.0.0-preview.97
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-chat-widget.js +2 -0
- package/dist/ai-chat-widget.js.map +1 -1
- package/dist/ai-chat-widget.min.js +1 -1
- package/dist/ai-chat-widget.min.js.map +1 -1
- package/dist/ai-chat.css +22 -3
- package/dist/ai-chat.css.map +1 -1
- package/dist/ai-chat.js +10 -2
- package/dist/ai-chat.js.map +1 -1
- package/dist/ai-chat.min.css +1 -1
- package/dist/ai-chat.min.js +1 -1
- package/dist/ai-chat.min.js.map +1 -1
- package/dist/chat-widget.css +40 -9
- package/dist/chat-widget.css.map +1 -1
- package/dist/chat-widget.min.css +1 -1
- package/package.json +1 -1
package/dist/ai-chat.min.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["ai-chat.js"],"names":["_excluded","_regenerator","e","t","r","Symbol","n","iterator","o","toStringTag","i","c","prototype","Generator","u","Object","create","_regeneratorDefine2","f","p","y","G","v","a","d","bind","length","l","TypeError","call","done","value","GeneratorFunction","GeneratorFunctionPrototype","getPrototypeOf","this","setPrototypeOf","__proto__","displayName","w","m","defineProperty","_invoke","enumerable","configurable","writable","asyncGeneratorStep","Promise","resolve","then","_asyncToGenerator","arguments","apply","_next","_throw","_toConsumableArray","_arrayWithoutHoles","_iterableToArray","_unsupportedIterableToArray","_nonIterableSpread","Array","from","isArray","_arrayLikeToArray","_objectWithoutProperties","_objectWithoutPropertiesLoose","getOwnPropertySymbols","indexOf","propertyIsEnumerable","hasOwnProperty","_createForOfIteratorHelper","_n","F","s","next","_slicedToArray","_arrayWithHoles","_iterableToArrayLimit","_nonIterableRest","toString","slice","constructor","name","test","push","_typeof","window","coreAIChatManager","defaultConfig","generatedImageAltText","generatedImageMaxWidth","downloadImageTitle","downloadChartTitle","downloadChartButtonText","userLabel","assistantLabel","thumbsUpTitle","thumbsDownTitle","copyTitle","copiedTitle","codeCopiedText","copyResetDelayMs","widget","chatWidgetContainer","chatWidgetStateName","chatHistorySection","showHistoryButton","closeHistoryButton","newChatButton","toggleButtonSelector","resetSizeButtonSelector","dragHandleSelector","enableDragging","enableResizing","persistLayout","defaultWidth","defaultHeight","minWidth","minHeight","messageTemplate","indicatorTemplate","sanitizeUrl","url","trimmed","trim","escapeHtmlEntities","text","span","document","createElement","textContent","innerHTML","refreshFontAwesomeIcons","root","fontAwesome","FontAwesome","nodeType","selector","matches","querySelector","containsFontAwesomePlaceholders","dom","i2svg","node","observeFontAwesomeIcons","MutationObserver","observer","mutations","forEach","mutation","addedNodes","observe","childList","subtree","normalizeReference","reference","_ref","_normalized$index","_ref2","_normalized$text","_ref3","_normalized$title","_ref4","_normalized$link","_ref5","_normalized$reference","_normalized$isGenerat","normalized","assign","index","Index","Text","title","Title","link","Link","referenceType","ReferenceType","isGenerated","IsGenerated","isDownloadCitationReference","toLowerCase","normalizeReferences","references","_i","_Object$entries","entries","_normalizeReference","_Object$entries$_i","key","getCitationLabel","updateMessagePresentation","message","messageReferences","rawContent","content","citationDisplay","processedContent","referenceEntries","citations","citedRefs","filter","_ref6","includes","generatedRefs","_ref8","_ref9","sort","_ref0","_ref1","b","_ref12","_ref13","_step","displayIndex","_iterator","_step$value","placeholder","concat","replaceAll","referenceKey","label","isDownload","err","_i2","_citations","citation","_step2","_iterator2","_step2$value","map","_ref16","buildCitationDisplay","displayContent","citationReferences","copyContent","_step3","_iterator3","_step4","_iterator4","trimEnd","buildCopyContent","htmlContent","parseMarkdownContent","renderer","marked","Renderer","data","href","code","lang","highlighted","hljs","getLanguage","highlight","language","_","highlightAuto","langDisplay","image","src","alt","maxWidth","chartCounter","_pendingCharts","renderChartsInMessage","charts","requestAnimationFrame","_step5","_iterator5","renderChartOnCanvas","chartId","config","canvas","getElementById","Chart","console","warn","offsetParent","__chartConfigs","_cfg$options","_cfg$options2","_cfg$options2$aspectR","_chartInstance","destroy","cfg","JSON","parse","options","responsive","maintainAspectRatio","aspectRatio","error","html","DOMPurify","sanitize","ADD_TAGS","ADD_ATTR","compactObject","source","fromEntries","_ref17","undefined","use","extensions","level","start","idx","tokenizer","extracted","token","jsonStart","depth","inString","escape","ch","jsonEnd","closeBracketIndex","startIndex","endIndex","json","substring","tryExtractChartMarker","type","raw","renderPendingCharts","configs","_i3","_Object$keys","keys","initialize","instanceConfig","normalizedInstanceConfig","normalizedWidgetConfig","hasWidgetConfig","widgetBehavior","coreAIChatWidgetBehavior","signalRHubUrl","appElementSelector","chatContainerElementSelector","inputElementSelector","sendButtonElementSelector","appDefinition","inputElement","buttonElement","chatContainer","isSessionStarted","isPlaceholderVisible","isStreaming","isNavigatingAway","autoScroll","stream","messages","notifications","prompt","documents","existingDocuments","isUploading","isDocumentOperationPending","documentOperationQueue","uploadErrors","isDragOver","documentBar","metricsEnabled","isRecording","mediaRecorder","preRecordingPrompt","micButton","speechToTextEnabled","chatMode","textToSpeechEnabled","ttsVoiceName","audioChunks","audioPlayQueue","isPlayingAudio","currentAudioElement","currentAudioUrl","ttsButton","ttsPlayingMessageIndex","ttsAudioCache","ttsInstanceId","Math","random","singleResponseMode","conversationModeEnabled","conversationButton","isConversationMode","notificationDismissTimers","pendingSessionPromise","pendingSessionResolver","pendingSessionRejector","pendingSessionTimeoutId","copiedMessageIndex","copyResetTimeoutId","activeCopyButton","computed","lastAssistantIndex","role","methods","handleBeforeUnload","handleDragOver","sessionDocumentsEnabled","preventDefault","stopPropagation","inputArea","closest","classList","add","handleDragLeave","remove","handleDrop","dataTransfer","files","uploadFiles","triggerFileInput","fileInput","click","handleFileInputChange","target","queueDocumentOperation","operation","self","nextOperation","_callee","_context","_this","_callee3","filesToUpload","_context3","uploadDocumentUrl","_callee2","sessionId","profileId","formData","response","errorText","uploadError","result","_t","_t2","_context2","getSessionId","getProfileId","ensureSessionForDocuments","fileName","renderDocumentBar","FormData","append","fetch","method","body","ok","extractReadableErrorMessage","initializeSession","uploaded","failed","reloadCurrentSession","removeDocument","doc","_this2","_callee5","_context5","removeDocumentUrl","_callee4","removeError","_t3","_context4","headers","stringify","itemId","documentId","splice","status","formatFileSize","bytes","toFixed","escapeHtml","failedItem","failedName","errorMsg","supportedExtensionsText","replaceChildren","RETURN_DOM_FRAGMENT","closeButtons","querySelectorAll","j","addEventListener","docToRemove","parseInt","getAttribute","errorCloseButtons","addBtn","div","fallbackMessage","startsWith","parsed","detail","normalizeAssistantAppearance","appearance","icon","cssClass","disableStreamingAnimation","getAssistantLabel","getAssistantRoleClasses","classes","getAssistantIconClasses","shouldAnimateAssistantIcon","getAssistantIcon","startConnection","_this3","_callee6","_t4","_context6","connection","signalR","HubConnectionBuilder","withUrl","withAutomaticReconnect","build","serverTimeoutInMilliseconds","keepAliveIntervalInMilliseconds","on","_data$messages","msg","addMessage","$nextTick","refreshAllFeedbackIcons","initialPrompt","sendMessage","stopRecording","handleReceiveError","messageId","userRating","find","id","isFinal","_conversationPartialTranscript","replace","_conversationPartialMessage","hidePlaceholder","isPartial","scrollToBottom","_audioInputSent","dispatchEvent","Event","stopAudio","_conversationAssistantMessage","oldMsg","escaped","responseId","hideTypingIndicator","msgIndex","newMessage","base64Audio","contentType","binaryString","atob","Uint8Array","charCodeAt","playCollectedAudio","notification","receiveNotification","updateNotification","notificationType","removeNotification","onreconnecting","onreconnected","info","autoCreateSession","startNewSession","onclose","addMessageInternal","_this4","fireEvent","CustomEvent","_message$rawContent","_this5","addMessages","_this6","showPlaceholder","isOrchestratorAvailable","applyOrchestratorAvailability","unavailableMessage","orchestratorUnavailableMessage","disabled","micButtonElement","style","display","conversationButtonElement","event","isIndicator","trimmedPrompt","streamMessage","startRecording","_this7","navigator","mediaDevices","getUserMedia","audio","echoCancellation","noiseSuppression","autoGainControl","mimeType","MediaRecorder","isTypeSupported","audioBitsPerSecond","subject","Subject","pendingChunk","size","_callee7","uint8Array","base64","_context7","arrayBuffer","reduce","str","byte","String","fromCharCode","btoa","getTracks","track","stop","complete","documentElement","send","updateMicButton","toggleRecording","sessionProfileId","_this8","dispose","streamingStarted","showTypingIndicator","lastResponseId","messageIndex","currentSessionId","subscribe","chunk","_i4","_Object$entries2","_normalizeReference2","_Object$entries2$_i","_this8$stream","processReferences","streamingFinished","synthesizeSpeech","_this8$stream2","getServiceDownMessage","_this9","_ref23","_message$rawContent2","stopIcon","setAttribute","startIcon","removeAttribute","focus","icons","handleExternalTtsStop","_e$detail","sourceId","updateTtsPlaybackButtons","_this0","button","isPlaying","Number","toggle","updateCopyButtons","_this1","isCopied","iconHtml","setCopyButtonState","cacheIndex","_this10","_ttsCacheIndex","invoke","toggleMessageTts","_this11","playAudioBlob","_this12","_step6","totalLength","sum","combined","offset","_iterator6","set","blob","Blob","_this13","URL","createObjectURL","Audio","revokeObjectURL","playNextInQueue","play","_this14","nextBlob","shift","conversationModeOnAudioEnded","_this15","pause","currentTime","toggleConversationMode","stopConversationMode","startConversationMode","_this16","updateConversationButton","_conversationSubject","_conversationStream","AudioCtx","AudioContext","webkitAudioContext","_conversationAudioCtx","_conversationAnalyser","createAnalyser","fftSize","createMediaStreamSource","connect","analyser","freqData","frequencyBinCount","getByteFrequencyData","k","_callee8","_context8","close","dismissible","autoDismissMs","endHtml","blur","startHtml","conversationModeSendPrompt","generatePrompt","element","templateProfileId","createSessionUrl","baseUrl","param","fullUrl","location","origin","searchParams","originalLength","_this17","clearNotificationDismiss","existingIndex","findIndex","scheduleNotificationDismiss","_this18","setTimeout","timerId","clearTimeout","dismissNotification","handleNotificationAction","actionName","_this19","scrollTop","scrollHeight","clientHeight","handleUserInput","setSessionId","resetSession","rejectPendingSessionRequest","sessionRating","onSessionReset","requestNewSession","_this20","_callee9","_context9","_this21","reject","resolvePendingSessionRequest","clearPendingSessionRequest","initializeApp","_this22","placeholderElementSelector","loadSession","documentBarSelector","className","multiple","allowedExtensions","accept","parentElement","appendChild","atBottom","shiftKey","lastMsg","pop","promptGenerators","getElementsByClassName","chatSessions","showChatScreen","initialMessages","btn","block","codeEl","clipboard","writeText","copiedText","micButtonElementSelector","conversationButtonElementSelector","force","onSessionInitialized","resolveSessionId","clearCopiedMessageState","copyResponse","_ref25","_message$copyContent","_event$target","_event$target$closest","_this23","currentTarget","updateFeedbackIcons","container","upBtn","downBtn","upClass","upIcon","fontSize","downClass","downIcon","containers","$el","msgId","rateMessage","isPositive","newRating","feedbackContainer","btnClass","offsetWidth","onEnd","removeEventListener","watch","handler","onDocumentsChanged","deep","_this24","active","mounted","_this25","_callee0","_context0","onMounted","fontAwesomeObserver","beforeUnmount","disconnect","onBeforeUnmount","template","app","Vue","createApp","mount","attach","autoInitializeSelector","getAttributeValue","attributeName","parseJsonAttribute","description","rawValue","buildConfigFromDataAttributes","_parseJsonAttribute","_parseJsonAttribute2","settings","hasAttribute","allowWidgetHost","booleanAttributes","parseBooleanAttributeValue","buildConfigFromElement","jsonConfig","attributeConfig","initializeFromElement","dataset","coreAiChatInitialized","__coreAIChatApp","scanForAutoInitialization","startAutoInitialization","readyState","once","download","toDataURL","img","res","removeChild"],"mappings":"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","file":"ai-chat.min.js","sourcesContent":["window.coreAIChatManager = 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 copiedTitle: 'Response copied to clipboard.',\n codeCopiedText: 'Copied!',\n copyResetDelayMs: 2000,\n widget: {\n chatWidgetContainer: null,\n chatWidgetStateName: null,\n chatHistorySection: null,\n showHistoryButton: null,\n closeHistoryButton: null,\n newChatButton: null,\n toggleButtonSelector: null,\n resetSizeButtonSelector: null,\n dragHandleSelector: '.ai-chat-widget-header',\n enableDragging: true,\n enableResizing: true,\n persistLayout: true,\n defaultWidth: null,\n defaultHeight: null,\n minWidth: 320,\n minHeight: 420\n },\n messageTemplate: `\n <div class=\"ai-chat-messages\">\n <div v-for=\"(message, index) in messages\" :key=\"'msg-' + index\" class=\"ai-chat-message-item\">\n <div>\n <div v-if=\"message.role === 'user'\" class=\"ai-chat-msg-role ai-chat-msg-role-user\">{{ userLabel }}</div>\n <div v-else-if=\"message.role !== 'indicator'\" :class=\"getAssistantRoleClasses(message)\">\n <span :class=\"getAssistantIconClasses(message, index)\"><i :class=\"getAssistantIcon(message)\"></i></span>\n {{ getAssistantLabel(message) }}\n </div>\n <div class=\"ai-chat-message-body lh-base\">\n <h4 v-if=\"message.title\">{{ message.title }}</h4>\n <div v-html=\"message.htmlContent\"></div>\n <ol v-if=\"message.citationReferences && message.citationReferences.length\" class=\"ai-chat-citation-list\">\n <li v-for=\"citation in message.citationReferences\" :key=\"'citation-' + (citation.referenceKey || citation.displayIndex)\" class=\"ai-chat-citation-item\">\n <a v-if=\"citation.link\" :href=\"citation.link\" :target=\"citation.isDownload ? null : '_blank'\" :rel=\"citation.isDownload ? null : 'noopener noreferrer'\">{{ citation.label }}</a>\n <span v-else>{{ citation.label }}</span>\n </li>\n </ol>\n <span class=\"message-buttons-container\" v-if=\"!isIndicator(message)\">\n <template v-if=\"metricsEnabled && message.role === 'assistant'\">\n <span class=\"ai-chat-message-assistant-feedback\" :data-message-id=\"message.id\">\n <button type=\"button\" class=\"btn btn-sm btn-link text-success p-0 me-2 button-message-toolbox rate-up-btn\" @click=\"rateMessage(message, true, $event)\" :title=\"thumbsUpTitle\">\n <i class=\"fa-regular fa-thumbs-up\"></i>\n </button>\n <button type=\"button\" class=\"btn btn-sm btn-link text-danger p-0 me-2 button-message-toolbox rate-down-btn\" @click=\"rateMessage(message, false, $event)\" :title=\"thumbsDownTitle\">\n <i class=\"fa-regular fa-thumbs-down\"></i>\n </button>\n </span>\n </template>\n <button type=\"button\" v-if=\"textToSpeechEnabled && !isConversationMode && message.role === 'assistant' && !message.isStreaming\" class=\"btn btn-sm btn-link text-secondary p-0 me-1 button-message-toolbox\" :class=\"{ 'tts-playing': ttsPlayingMessageIndex === index }\" :data-tts-message-index=\"index\" @click=\"toggleMessageTts(message, index)\" :title=\"ttsPlayingMessageIndex === index ? 'Pause audio' : 'Read aloud'\">\n <span :class=\"ttsPlayingMessageIndex === index ? 'fa-solid fa-circle-pause' : 'fa-solid fa-circle-play'\"></span>\n </button>\n <button type=\"button\" class=\"btn btn-sm btn-link p-0 button-message-toolbox ai-response-copy-btn\" :class=\"copiedMessageIndex === index ? 'text-success' : 'text-secondary'\" :data-copy-message-index=\"index\" @click=\"copyResponse(message, index, $event)\" :title=\"copiedMessageIndex === index ? copiedTitle : copyTitle\">\n <i :class=\"copiedMessageIndex === index ? 'fa-solid fa-check' : 'fa-solid fa-copy'\"></i>\n </button>\n </span>\n </div>\n </div>\n </div>\n <div v-for=\"notification in notifications\" :key=\"'notif-' + notification.type\" class=\"ai-chat-notification\" :class=\"'ai-chat-notification-' + (notification.type || 'info') + ' ' + (notification.cssClass || '')\">\n <div class=\"ai-chat-notification-content\">\n <i v-if=\"notification.icon\" :class=\"notification.icon\" class=\"ai-chat-notification-icon\"></i>\n <span class=\"ai-chat-notification-text\">{{ notification.content }}</span>\n <button type=\"button\" v-if=\"notification.dismissible\" class=\"btn btn-sm btn-link p-0 ms-2 ai-chat-notification-dismiss\" @click=\"dismissNotification(notification.type)\" title=\"Dismiss\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n <div v-if=\"notification.actions && notification.actions.length\" class=\"ai-chat-notification-actions\">\n <button type=\"button\" v-for=\"action in notification.actions\" :key=\"action.name\" class=\"btn btn-sm\" :class=\"action.cssClass || 'btn-outline-secondary'\" @click=\"handleNotificationAction(notification.type, action.name)\">\n <i v-if=\"action.icon\" :class=\"action.icon\" class=\"me-1\"></i>\n {{ action.label }}\n </button>\n </div>\n </div>\n </div>\n `,\n indicatorTemplate: `\n <div class=\"ai-chat-msg-role ai-chat-msg-role-assistant\">\n <span class=\"ai-streaming-icon\"><i class=\"fa fa-robot\" style=\"display: inline-block;\"></i></span>\n Assistant\n </div>\n `\n };\n\n // Sanitize URLs to prevent javascript: protocol injection.\n function sanitizeUrl(url) {\n if (!url) return '';\n var trimmed = url.trim();\n if (/^javascript:/i.test(trimmed) || /^vbscript:/i.test(trimmed) || /^data:text\\/html/i.test(trimmed)) {\n return '';\n }\n return url;\n }\n\n // Safely HTML-encode a string using the DOM (avoids regex-based HTML filtering).\n function escapeHtmlEntities(text) {\n var span = document.createElement('span');\n span.textContent = text;\n return span.innerHTML;\n }\n\n function containsFontAwesomePlaceholders(root) {\n if (!root || root.nodeType !== 1) {\n return false;\n }\n\n var selector = 'i[class*=\"fa-\"],i.fa,i.fas,i.far,i.fab';\n if (typeof root.matches === 'function' && root.matches(selector)) {\n return true;\n }\n\n return typeof root.querySelector === 'function' && !!root.querySelector(selector);\n }\n\n function refreshFontAwesomeIcons(root) {\n var fontAwesome = window.FontAwesome;\n if (!containsFontAwesomePlaceholders(root) || !fontAwesome || !fontAwesome.dom || typeof fontAwesome.dom.i2svg !== 'function') {\n return;\n }\n\n fontAwesome.dom.i2svg({ node: root });\n }\n\n function observeFontAwesomeIcons(root) {\n if (!root || typeof MutationObserver === 'undefined') {\n return null;\n }\n\n var observer = new MutationObserver(function (mutations) {\n mutations.forEach(function (mutation) {\n mutation.addedNodes.forEach(function (node) {\n refreshFontAwesomeIcons(node);\n });\n });\n });\n\n observer.observe(root, {\n childList: true,\n subtree: true\n });\n\n return observer;\n }\n\n function parsePixelValue(value) {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n\n if (typeof value !== 'string') {\n return null;\n }\n\n var parsed = parseFloat(value);\n return Number.isFinite(parsed) ? parsed : null;\n }\n\n function clamp(value, min, max) {\n return Math.min(Math.max(value, min), max);\n }\n\n function normalizeReference(reference) {\n if (!reference || typeof reference !== 'object') {\n return null;\n }\n\n const normalized = Object.assign({}, reference);\n normalized.index = normalized.index ?? normalized.Index ?? 0;\n normalized.text = normalized.text ?? normalized.Text ?? null;\n normalized.title = normalized.title ?? normalized.Title ?? null;\n normalized.link = sanitizeUrl(normalized.link ?? normalized.Link ?? null);\n normalized.referenceType = normalized.referenceType ?? normalized.ReferenceType ?? null;\n normalized.isGenerated = (normalized.isGenerated ?? normalized.IsGenerated) === true;\n\n return normalized;\n }\n\n function isDownloadCitationReference(reference) {\n if (!reference || typeof reference !== 'object') {\n return false;\n }\n\n if (typeof reference.referenceType === 'string' && reference.referenceType.toLowerCase() === 'document') {\n return true;\n }\n\n if (typeof reference.link === 'string' && /\\/ai\\/documents\\/.+\\/download(?:$|\\?)/i.test(reference.link)) {\n return true;\n }\n\n return false;\n }\n\n function normalizeReferences(references) {\n if (!references || typeof references !== 'object') {\n return {};\n }\n\n const normalized = {};\n\n for (const [key, value] of Object.entries(references)) {\n normalized[key] = normalizeReference(value) ?? {};\n }\n\n return normalized;\n }\n\n function getCitationLabel(reference, key) {\n return reference.title || reference.text || key;\n }\n\n function buildCitationDisplay(content, references) {\n let processedContent = (content || '').trim();\n const messageReferences = normalizeReferences(references);\n const referenceEntries = Object.entries(messageReferences);\n\n if (!referenceEntries.length) {\n return { content: processedContent, citations: [] };\n }\n\n const citedRefs = referenceEntries.filter(([key]) => processedContent.includes(key));\n const generatedRefs = referenceEntries.filter(([key, value]) => value.isGenerated && !processedContent.includes(key));\n\n if (!citedRefs.length && !generatedRefs.length) {\n return { content: processedContent, citations: [] };\n }\n\n citedRefs.sort(([, a], [, b]) => a.index - b.index);\n generatedRefs.sort(([, a], [, b]) => a.index - b.index);\n\n const citations = [];\n let displayIndex = 1;\n\n for (const [key, value] of citedRefs) {\n const placeholder = `__CITE_${displayIndex}_${value.index || displayIndex}__`;\n processedContent = processedContent.replaceAll(key, placeholder);\n citations.push({\n referenceKey: key,\n displayIndex: displayIndex,\n label: getCitationLabel(value, key),\n link: value.link || null,\n isDownload: isDownloadCitationReference(value),\n placeholder: placeholder,\n });\n\n displayIndex++;\n }\n\n for (const citation of citations) {\n processedContent = processedContent.replaceAll(citation.placeholder, `<sup>${citation.displayIndex}</sup>`);\n }\n\n processedContent = processedContent.replaceAll('</sup><sup>', '</sup><sup>,</sup><sup>');\n\n // Generated files (such as exported tabular data) are always offered as a download even when\n // the model does not cite them inline, so the user never loses access to the produced file.\n for (const [key, value] of generatedRefs) {\n citations.push({\n referenceKey: key,\n displayIndex: displayIndex,\n label: getCitationLabel(value, key),\n link: value.link || null,\n isDownload: true,\n placeholder: null,\n });\n\n displayIndex++;\n }\n\n return {\n content: processedContent,\n citations: citations.map(({ placeholder, ...citation }) => citation),\n };\n }\n\n function buildCopyContent(content, citations) {\n let copyContent = (content || '').trim();\n\n if (!copyContent || !Array.isArray(citations) || citations.length === 0) {\n return copyContent;\n }\n\n for (const citation of citations) {\n copyContent = copyContent.replaceAll(citation.referenceKey, `[${citation.displayIndex}]`);\n }\n\n copyContent += '\\n\\nReferences:\\n';\n\n for (const citation of citations) {\n copyContent += `${citation.displayIndex}. ${citation.label}`;\n\n if (citation.link) {\n copyContent += ` - ${citation.link}`;\n }\n\n copyContent += '\\n';\n }\n\n return copyContent.trimEnd();\n }\n\n function updateMessagePresentation(message, references) {\n const messageReferences = normalizeReferences(references ?? message.references);\n const rawContent = typeof message.rawContent === 'string'\n ? message.rawContent\n : typeof message.content === 'string'\n ? message.content\n : '';\n const citationDisplay = buildCitationDisplay(rawContent, messageReferences);\n\n message.rawContent = rawContent;\n message.content = rawContent;\n message.displayContent = citationDisplay.content;\n message.references = messageReferences;\n message.citationReferences = citationDisplay.citations;\n message.copyContent = buildCopyContent(rawContent, citationDisplay.citations);\n message.htmlContent = parseMarkdownContent(citationDisplay.content, message);\n\n return message;\n }\n\n const renderer = new marked.Renderer();\n\n // Modify the link rendering to open in a new tab\n renderer.link = function (data) {\n var href = sanitizeUrl(data.href);\n if (!href) return data.text || '';\n return `<a href=\"${href}\" target=\"_blank\" rel=\"noopener noreferrer\">${data.text}</a>`;\n };\n\n // Custom code block renderer with highlight.js integration and copy button.\n renderer.code = function (data) {\n var code = data.text || '';\n var lang = (data.lang || '').trim();\n var highlighted = code;\n\n if (typeof hljs !== 'undefined') {\n if (lang && hljs.getLanguage(lang)) {\n try {\n highlighted = hljs.highlight(code, { language: lang }).value;\n } catch (_) { }\n } else {\n try {\n highlighted = hljs.highlightAuto(code).value;\n } catch (_) { }\n }\n } else {\n highlighted = escapeHtmlEntities(code);\n }\n\n var langDisplay = lang ? escapeHtmlEntities(lang) : 'code';\n return `<div class=\"ai-code-block\"><div class=\"ai-code-header\"><span class=\"ai-code-lang\"><i class=\"fa-solid fa-code\"></i> ${langDisplay}</span><button type=\"button\" class=\"ai-code-copy-btn\" title=\"Copy code\"><i class=\"fa-regular fa-copy\"></i></button></div><pre><code class=\"hljs${lang ? ' language-' + lang : ''}\">${highlighted}</code></pre></div>`;\n };\n\n // Custom image renderer for generated images with thumbnail styling and download button.\n // Handles both URL and data-URI sources (data URIs are converted to blobs for download).\n renderer.image = function (data) {\n const src = sanitizeUrl(data.href);\n if (!src) return '';\n const alt = data.text || defaultConfig.generatedImageAltText;\n const maxWidth = defaultConfig.generatedImageMaxWidth;\n return `<div class=\"generated-image-container\">\n <img src=\"${src}\" alt=\"${alt}\" class=\"img-thumbnail\" style=\"max-width: ${maxWidth}px; height: auto;\" />\n <div class=\"mt-2\">\n <a href=\"${src}\" target=\"_blank\" download=\"${alt}\" title=\"${defaultConfig.downloadImageTitle}\" class=\"btn btn-sm btn-outline-secondary ai-download-image\">\n <i class=\"fa-solid fa-download\"></i>\n </a>\n </div>\n </div>`;\n };\n\n // Chart counter for unique IDs\n let chartCounter = 0;\n\n // Collector for charts discovered during marked parsing.\n let _pendingCharts = [];\n\n // Global chart config map: any page (e.g., Chat Interactions) that uses\n // the shared marked instance can call window.renderPendingCharts() after\n // its DOM update to render charts it didn't create itself.\n window.__chartConfigs = window.__chartConfigs || {};\n\n function createChartHtml(chartId) {\n return `<div class=\"chart-container\" style=\"position: relative; width: 100%; max-width: 560px; min-height: 420px;\">`\n + `<canvas id=\"${chartId}\"></canvas>`\n + `</div>`\n + `<div class=\"mt-2\">`\n + `<button type=\"button\" class=\"btn btn-sm btn-outline-secondary download-chart-btn\" data-chart-id=\"${chartId}\" title=\"${defaultConfig.downloadChartTitle}\">`\n + `<i class=\"fa-solid fa-download\"></i> ${defaultConfig.downloadChartButtonText}`\n + `</button>`\n + `</div>`;\n }\n\n // Register [chart:{...json...}] as a native marked block extension so the\n // markdown parser handles chart markers inline with surrounding text.\n marked.use({\n extensions: [{\n name: 'chart',\n level: 'block',\n start(src) {\n const idx = src.indexOf('[chart:');\n return idx >= 0 ? idx : undefined;\n },\n tokenizer(src) {\n const extracted = tryExtractChartMarker(src);\n if (!extracted || extracted.startIndex !== 0) {\n return undefined;\n }\n\n const chartId = `chat_chart_${++chartCounter}`;\n\n return {\n type: 'chart',\n raw: src.substring(0, extracted.endIndex),\n chartId: chartId,\n json: extracted.json,\n };\n },\n renderer(token) {\n _pendingCharts.push({ chartId: token.chartId, config: token.json });\n window.__chartConfigs[token.chartId] = token.json;\n return createChartHtml(token.chartId);\n }\n }]\n });\n\n // Extract a [chart:{...json...}] marker. This avoids regex issues with nested brackets.\n function tryExtractChartMarker(text) {\n const token = '[chart:';\n const start = text.indexOf(token);\n if (start < 0) {\n return null;\n }\n\n // Find JSON object boundary by balancing braces\n const jsonStart = start + token.length;\n let i = jsonStart;\n while (i < text.length && (text[i] === ' ' || text[i] === '\\n' || text[i] === '\\r' || text[i] === '\\t')) {\n i++;\n }\n\n if (i >= text.length || text[i] !== '{') {\n return null;\n }\n\n let depth = 0;\n let inString = false;\n let escape = false;\n\n for (; i < text.length; i++) {\n const ch = text[i];\n\n if (inString) {\n if (escape) {\n escape = false;\n continue;\n }\n if (ch === '\\\\') {\n escape = true;\n continue;\n }\n if (ch === '\"') {\n inString = false;\n }\n continue;\n }\n\n if (ch === '\"') {\n inString = true;\n continue;\n }\n\n if (ch === '{') {\n depth++;\n } else if (ch === '}') {\n depth--;\n if (depth === 0) {\n const jsonEnd = i;\n // Expect closing bracket after JSON\n const closeBracketIndex = text.indexOf(']', jsonEnd + 1);\n if (closeBracketIndex < 0) {\n return null;\n }\n\n const json = text.substring(jsonStart, jsonEnd + 1).trim();\n return {\n startIndex: start,\n endIndex: closeBracketIndex + 1,\n json: json\n };\n }\n }\n }\n\n return null;\n }\n\n function renderChartsInMessage(message) {\n if (!message || !message._pendingCharts || !message._pendingCharts.length) {\n return;\n }\n\n // Copy and clear pending charts immediately to prevent duplicate renders.\n const charts = [...message._pendingCharts];\n message._pendingCharts = [];\n\n // Defer to requestAnimationFrame so the browser has fully laid out the\n // canvas elements before Chart.js reads their dimensions.\n requestAnimationFrame(() => {\n for (const c of charts) {\n renderChartOnCanvas(c.chartId, c.config);\n }\n });\n }\n\n function renderChartOnCanvas(chartId, config) {\n const canvas = document.getElementById(chartId);\n if (!canvas) {\n return false;\n }\n\n if (typeof Chart === 'undefined') {\n console.warn('Chart.js is not loaded. To render interactive charts, include the Chart.js library on the page (e.g., <script src=\"https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.min.js\"></script>).');\n return false;\n }\n\n // When the canvas is inside a hidden container (e.g., a widget panel with\n // display:none), it has zero dimensions and Chart.js cannot render correctly.\n // Keep the config in __chartConfigs so renderPendingCharts() can retry later\n // once the container becomes visible.\n if (canvas.offsetParent === null) {\n window.__chartConfigs[chartId] = config;\n return false;\n }\n\n try {\n if (canvas._chartInstance) {\n canvas._chartInstance.destroy();\n }\n\n const cfg = typeof config === 'string' ? JSON.parse(config) : config;\n cfg.options ??= {};\n cfg.options.responsive = true;\n cfg.options.maintainAspectRatio = true;\n cfg.options.aspectRatio ??= 4 / 3;\n\n canvas._chartInstance = new Chart(canvas, cfg);\n delete window.__chartConfigs[chartId];\n return true;\n } catch (e) {\n console.error('Error creating chart:', e);\n return false;\n }\n }\n\n // Global function: renders any chart canvases whose configs are in the\n // global __chartConfigs map. Called by pages (e.g., Chat Interactions)\n // that share the marked instance but have their own rendering pipeline.\n window.renderPendingCharts = function () {\n if (typeof Chart === 'undefined') {\n return;\n }\n\n const configs = window.__chartConfigs;\n if (!configs) {\n return;\n }\n\n requestAnimationFrame(() => {\n for (const chartId of Object.keys(configs)) {\n renderChartOnCanvas(chartId, configs[chartId]);\n }\n });\n };\n\n // Parse markdown content via marked (which natively handles [chart:...] markers\n // through the registered extension) and collect pending chart configs for later\n // Chart.js rendering.\n function parseMarkdownContent(content, message) {\n _pendingCharts = [];\n const html = marked.parse(content, { renderer });\n message._pendingCharts = _pendingCharts.length > 0 ? [..._pendingCharts] : [];\n return DOMPurify.sanitize(html, { ADD_TAGS: ['canvas'], ADD_ATTR: ['target'] });\n }\n\n function compactObject(source) {\n if (!source || typeof source !== 'object') {\n return {};\n }\n\n return Object.fromEntries(\n Object.entries(source).filter(([, value]) => value !== undefined)\n );\n }\n\n const initialize = (instanceConfig) => {\n const normalizedInstanceConfig = compactObject(instanceConfig);\n const normalizedWidgetConfig = compactObject(normalizedInstanceConfig.widget);\n const config = Object.assign({}, defaultConfig, normalizedInstanceConfig);\n config.widget = Object.assign({}, defaultConfig.widget || {}, normalizedWidgetConfig);\n const hasWidgetConfig = !!(normalizedWidgetConfig.chatWidgetContainer && normalizedWidgetConfig.chatWidgetStateName);\n const widgetBehavior = window.coreAIChatWidgetBehavior || 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 copiedTitle: config.copiedTitle,\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 copiedMessageIndex: -1,\n copyResetTimeoutId: null,\n activeCopyButton: null,\n };\n },\n computed: {\n lastAssistantIndex() {\n for (var i = this.messages.length - 1; i >= 0; i--) {\n if (this.messages[i].role === 'assistant') {\n return i;\n }\n }\n return -1;\n }\n },\n methods: {\n handleBeforeUnload() {\n this.isNavigatingAway = true;\n },\n handleDragOver(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = true;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.add('ai-chat-drag-over');\n },\n handleDragLeave(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = false;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.remove('ai-chat-drag-over');\n },\n handleDrop(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = false;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.remove('ai-chat-drag-over');\n if (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n this.uploadFiles(Array.from(e.dataTransfer.files));\n }\n },\n triggerFileInput() {\n if (!config.sessionDocumentsEnabled || this.isDocumentOperationPending) return;\n var fileInput = document.getElementById('ai-chat-doc-input');\n if (fileInput) fileInput.click();\n },\n handleFileInputChange(e) {\n var files = e.target.files ? Array.from(e.target.files) : [];\n if (files && files.length > 0) {\n this.uploadFiles(files);\n }\n e.target.value = '';\n },\n queueDocumentOperation(operation) {\n var self = this;\n var previousOperation = this.documentOperationQueue || Promise.resolve();\n var nextOperation = previousOperation\n .catch(function () { })\n .then(async function () {\n self.isDocumentOperationPending = true;\n try {\n return await operation();\n } finally {\n self.isDocumentOperationPending = false;\n }\n });\n\n this.documentOperationQueue = nextOperation.finally(function () {\n if (self.documentOperationQueue === nextOperation) {\n self.documentOperationQueue = null;\n }\n });\n\n return this.documentOperationQueue;\n },\n async uploadFiles(files) {\n if (!config.uploadDocumentUrl) return;\n\n var filesToUpload = Array.isArray(files) ? files.slice() : Array.from(files || []);\n if (filesToUpload.length === 0) return;\n\n return this.queueDocumentOperation(async () => {\n var sessionId = this.getSessionId();\n var profileId = this.getProfileId();\n\n if (!sessionId) {\n try {\n sessionId = await this.ensureSessionForDocuments(profileId);\n } catch (err) {\n console.error('Failed to create a chat session for document upload:', err);\n this.uploadErrors = [{ fileName: '', error: 'Could not create a chat session for the upload.' }];\n this.renderDocumentBar();\n return;\n }\n }\n\n if (!sessionId) {\n console.warn('Cannot upload documents without a session or profile.');\n this.uploadErrors = [{ fileName: '', error: 'Could not create a chat session for the upload.' }];\n this.renderDocumentBar();\n return;\n }\n\n this.isUploading = true;\n this.uploadErrors = [];\n this.renderDocumentBar();\n try {\n var formData = new FormData();\n formData.append('sessionId', sessionId);\n for (var i = 0; i < filesToUpload.length; i++) {\n formData.append('files', filesToUpload[i]);\n }\n\n var response = await fetch(config.uploadDocumentUrl, {\n method: 'POST',\n body: formData\n });\n\n if (!response.ok) {\n var errorText = await response.text();\n var uploadError = this.extractReadableErrorMessage(errorText, 'Upload failed. Please try again.');\n console.error('Upload failed:', errorText);\n this.uploadErrors = [{ fileName: '', error: uploadError }];\n return;\n }\n\n var result = await response.json();\n\n if (result.sessionId && result.sessionId !== this.getSessionId()) {\n this.initializeSession(result.sessionId);\n }\n\n if (Array.isArray(result.documents)) {\n this.documents = result.documents;\n } else if (result.uploaded && result.uploaded.length > 0) {\n this.documents = this.documents.concat(result.uploaded);\n }\n\n if (result.failed && result.failed.length > 0) {\n this.uploadErrors = result.failed;\n }\n } catch (err) {\n console.error('Upload error:', err);\n this.uploadErrors = [{ fileName: '', error: 'Upload failed. Please try again.' }];\n\n if (this.getSessionId()) {\n this.reloadCurrentSession();\n }\n } finally {\n this.isUploading = false;\n this.renderDocumentBar();\n }\n });\n },\n async removeDocument(doc) {\n if (!config.removeDocumentUrl) return;\n\n return this.queueDocumentOperation(async () => {\n try {\n var sessionId = this.getSessionId();\n var response = await fetch(config.removeDocumentUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ itemId: sessionId, documentId: doc.documentId })\n });\n\n if (response.ok) {\n var result = await response.json();\n\n if (Array.isArray(result.documents)) {\n this.documents = result.documents;\n } else {\n var idx = this.documents.indexOf(doc);\n if (idx > -1) {\n this.documents.splice(idx, 1);\n }\n }\n } else {\n var errorText = await response.text();\n var removeError = this.extractReadableErrorMessage(errorText, 'Failed to remove document. Please try again.');\n console.error('Failed to remove document:', response.status, errorText);\n this.uploadErrors = [{ fileName: doc.fileName || '', error: removeError }];\n if (sessionId) {\n this.reloadCurrentSession();\n }\n this.renderDocumentBar();\n }\n } catch (err) {\n console.error('Remove document error:', err);\n this.uploadErrors = [{ fileName: doc.fileName || '', error: 'Failed to remove document. Please try again.' }];\n if (this.getSessionId()) {\n this.reloadCurrentSession();\n }\n this.renderDocumentBar();\n }\n });\n },\n formatFileSize(bytes) {\n if (bytes < 1024) return bytes + ' B';\n if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';\n return (bytes / (1024 * 1024)).toFixed(1) + ' MB';\n },\n renderDocumentBar() {\n if (!this.documentBar) return;\n\n if (!config.sessionDocumentsEnabled) {\n this.documentBar.classList.add('d-none');\n return;\n }\n\n this.documentBar.classList.remove('d-none');\n\n var html = '<div class=\"ai-chat-doc-bar p-2\">';\n html += '<div class=\"d-flex flex-wrap align-items-center gap-1\">';\n\n for (var i = 0; i < this.documents.length; i++) {\n var doc = this.documents[i];\n var name = doc.fileName || 'Document';\n if (name.length > 20) name = name.substring(0, 17) + '...';\n html += '<span class=\"badge bg-secondary bg-opacity-25 text-dark d-inline-flex align-items-center gap-1 px-2 py-1\" style=\"font-size: 0.8rem;\" title=\"' + this.escapeHtml(doc.fileName || '') + '\">';\n html += '<i class=\"fa-solid fa-file-lines\" style=\"font-size: 0.7rem;\"></i> ';\n html += this.escapeHtml(name);\n html += ' <button type=\"button\" class=\"btn-close btn-close-sm ms-1\" style=\"font-size: 0.5rem;\" data-doc-index=\"' + i + '\" aria-label=\"Remove\"' + (this.isDocumentOperationPending ? ' disabled' : '') + '></button>';\n html += '</span>';\n }\n\n for (var m = 0; m < this.uploadErrors.length; m++) {\n var failedItem = this.uploadErrors[m];\n var failedName = failedItem.fileName || 'File';\n var errorMsg = failedItem.error || 'Upload failed';\n if (failedName.length > 15) failedName = failedName.substring(0, 12) + '...';\n html += '<span class=\"badge bg-danger bg-opacity-25 text-danger d-inline-flex align-items-center gap-1 px-2 py-1\" style=\"font-size: 0.8rem;\" title=\"' + this.escapeHtml((failedItem.fileName || '') + ': ' + errorMsg) + '\">';\n html += '<i class=\"fa-solid fa-circle-exclamation\" style=\"font-size: 0.7rem;\"></i> ';\n html += this.escapeHtml(failedName);\n html += ' <button type=\"button\" class=\"btn-close btn-close-sm ms-1\" style=\"font-size: 0.5rem;\" data-error-index=\"' + m + '\" aria-label=\"Dismiss\"></button>';\n html += '</span>';\n }\n\n if (this.isUploading) {\n html += '<span class=\"badge bg-info bg-opacity-25 text-dark d-inline-flex align-items-center gap-1 px-2 py-1\" style=\"font-size: 0.8rem;\">';\n html += '<span class=\"spinner-border spinner-border-sm\" style=\"width: 0.7rem; height: 0.7rem;\"></span> Uploading...';\n html += '</span>';\n }\n\n html += '<button type=\"button\" class=\"btn btn-sm btn-outline-secondary rounded-pill ai-chat-doc-add-btn d-inline-flex align-items-center gap-1\" style=\"font-size: 0.75rem; padding: 0.15rem 0.5rem;\" title=\"Attach documents\"' + (this.isDocumentOperationPending ? ' disabled' : '') + '>';\n html += '<i class=\"fa-solid fa-paperclip\"></i>';\n if (this.documents.length === 0 && !this.isUploading) {\n html += ' <span>Attach files</span>';\n }\n html += '</button>';\n html += '</div>';\n if (config.supportedExtensionsText) {\n html += '<div class=\"small text-muted mt-2\">Supported formats: ' + this.escapeHtml(config.supportedExtensionsText) + '</div>';\n }\n\n html += '</div>';\n\n this.documentBar.replaceChildren(DOMPurify.sanitize(html, { RETURN_DOM_FRAGMENT: true }));\n\n // Bind remove handlers\n var self = this;\n var closeButtons = this.documentBar.querySelectorAll('[data-doc-index]');\n for (var j = 0; j < closeButtons.length; j++) {\n closeButtons[j].addEventListener('click', (function (idx) {\n return function (e) {\n e.preventDefault();\n e.stopPropagation();\n if (self.isDocumentOperationPending) {\n return;\n }\n\n var docToRemove = self.documents[idx];\n if (docToRemove) self.removeDocument(docToRemove);\n };\n })(parseInt(closeButtons[j].getAttribute('data-doc-index'))));\n }\n\n // Bind error dismiss handlers\n var errorCloseButtons = this.documentBar.querySelectorAll('[data-error-index]');\n for (var n = 0; n < errorCloseButtons.length; n++) {\n errorCloseButtons[n].addEventListener('click', (function (idx) {\n return function (e) {\n e.preventDefault();\n e.stopPropagation();\n self.uploadErrors.splice(idx, 1);\n self.renderDocumentBar();\n };\n })(parseInt(errorCloseButtons[n].getAttribute('data-error-index'))));\n }\n\n // Bind add button\n var addBtn = this.documentBar.querySelector('.ai-chat-doc-add-btn');\n if (addBtn) {\n addBtn.addEventListener('click', function (e) {\n e.preventDefault();\n if (self.isDocumentOperationPending) {\n return;\n }\n self.triggerFileInput();\n });\n }\n },\n escapeHtml(text) {\n var div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n },\n extractReadableErrorMessage(errorText, fallbackMessage) {\n if (!errorText || typeof errorText !== 'string') {\n return fallbackMessage;\n }\n\n var trimmed = errorText.trim();\n if (!trimmed) {\n return fallbackMessage;\n }\n\n if (trimmed.startsWith('{') || trimmed.startsWith('[')) {\n try {\n var parsed = JSON.parse(trimmed);\n var message = parsed?.error || parsed?.message || parsed?.title || parsed?.detail;\n return typeof message === 'string' && message.trim()\n ? message.trim()\n : fallbackMessage;\n } catch (err) {\n return fallbackMessage;\n }\n }\n\n if (/<[^>]+>/.test(trimmed)) {\n return fallbackMessage;\n }\n\n return trimmed;\n },\n normalizeAssistantAppearance(appearance) {\n if (!appearance) {\n return null;\n }\n\n var label = typeof appearance.label === 'string' ? appearance.label.trim() : '';\n var icon = typeof appearance.icon === 'string' ? appearance.icon.trim() : '';\n var cssClass = typeof appearance.cssClass === 'string' ? appearance.cssClass.trim() : '';\n var disableStreamingAnimation = !!appearance.disableStreamingAnimation;\n\n if (!label && !icon && !cssClass && !disableStreamingAnimation) {\n return null;\n }\n\n return {\n label: label,\n icon: icon,\n cssClass: cssClass,\n disableStreamingAnimation: disableStreamingAnimation,\n };\n },\n getAssistantLabel(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return appearance && appearance.label ? appearance.label : this.assistantLabel;\n },\n getAssistantRoleClasses(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n var classes = ['ai-chat-msg-role'];\n\n if (appearance && appearance.cssClass) {\n classes.push(appearance.cssClass);\n } else {\n classes.push('ai-chat-msg-role-assistant');\n }\n\n return classes;\n },\n getAssistantIconClasses(message, index) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return [this.shouldAnimateAssistantIcon(message, index) ? 'ai-streaming-icon' : 'ai-bot-icon', appearance && appearance.cssClass ? appearance.cssClass : ''];\n },\n getAssistantIcon(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return appearance && appearance.icon ? appearance.icon : 'fa fa-robot';\n },\n shouldAnimateAssistantIcon(message, index) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return !!message &&\n message.isStreaming &&\n index === this.lastAssistantIndex &&\n !(appearance && appearance.disableStreamingAnimation);\n },\n async startConnection() {\n this.connection = new signalR.HubConnectionBuilder()\n .withUrl(config.signalRHubUrl)\n .withAutomaticReconnect()\n .build();\n\n // Allow long-running operations (e.g., multi-step MCP tool calls)\n // without the client disconnecting prematurely.\n this.connection.serverTimeoutInMilliseconds = 600000;\n this.connection.keepAliveIntervalInMilliseconds = 15000;\n\n this.connection.on(\"LoadSession\", (data) => {\n this.initializeSession(data.sessionId, true);\n this.messages = [];\n this.documents = data.documents || [];\n this.uploadErrors = [];\n\n (data.messages ?? []).forEach(msg => {\n this.addMessage(msg);\n\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n });\n });\n\n // Update feedback icons in the DOM after all messages have rendered.\n this.$nextTick(() => {\n this.refreshAllFeedbackIcons();\n });\n\n // When the session is new (no messages) and an initial prompt is configured,\n // automatically send it as the first user message to trigger an AI response.\n if (this.messages.length === 0 && config.initialPrompt) {\n this.prompt = config.initialPrompt;\n this.sendMessage();\n }\n });\n\n this.connection.on(\"ReceiveError\", (error) => {\n console.error(\"SignalR Error: \", error);\n\n if (this.isRecording) {\n this.stopRecording();\n }\n\n if (widgetBehavior && typeof widgetBehavior.handleReceiveError === 'function') {\n widgetBehavior.handleReceiveError(this, error, config);\n }\n });\n\n this.connection.on(\"MessageRated\", (messageId, userRating) => {\n var msg = this.messages.find(m => m.id === messageId);\n if (msg) {\n msg.userRating = userRating;\n }\n });\n\n this.connection.on(\"ReceiveTranscript\", (sessionId, text, isFinal) => {\n if (this.isConversationMode) {\n if (!isFinal && text) {\n this._conversationPartialTranscript = text;\n var escaped = text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\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, '&').replace(/</g, '<').replace(/>/g, '>');\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = '<p>' + escaped + '</p>';\n this._conversationPartialMessage.isPartial = false;\n this._conversationPartialMessage = null;\n } else {\n this.addMessage({\n role: 'user',\n content: text\n });\n }\n this.scrollToBottom();\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantToken\", (sessionId, messageId, token, responseId, references, appearance) => {\n if (!this._conversationAssistantMessage) {\n this.stopAudio();\n this.hideTypingIndicator();\n\n // Ensure no stale streaming indicators remain from prior messages.\n for (var j = 0; j < this.messages.length; j++) {\n if (this.messages[j].isStreaming) {\n this.messages[j].isStreaming = false;\n }\n }\n\n var msgIndex = this.messages.length;\n var newMessage = {\n id: messageId,\n role: \"assistant\",\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n userRating: null,\n appearance: this.normalizeAssistantAppearance(appearance),\n references: {},\n };\n this.messages.push(newMessage);\n this._conversationAssistantMessage = { index: msgIndex, content: '' };\n }\n\n this._conversationAssistantMessage.content += token;\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n if (!msg.appearance) {\n msg.appearance = this.normalizeAssistantAppearance(appearance);\n }\n msg.rawContent = this._conversationAssistantMessage.content;\n msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));\n updateMessagePresentation(msg, msg.references);\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n this.scrollToBottom();\n });\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantComplete\", (sessionId, messageId, references) => {\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));\n updateMessagePresentation(msg, msg.references);\n }\n this._conversationAssistantMessage = null;\n }\n });\n\n this.connection.on(\"ReceiveAudioChunk\", (sessionId, base64Audio, contentType) => {\n if (base64Audio) {\n const binaryString = atob(base64Audio);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n this.audioChunks.push(bytes);\n }\n });\n\n this.connection.on(\"ReceiveAudioComplete\", (sessionId) => {\n this.playCollectedAudio();\n });\n\n this.connection.on(\"ReceiveNotification\", (notification) => {\n this.receiveNotification(notification);\n });\n\n this.connection.on(\"UpdateNotification\", (notification) => {\n this.updateNotification(notification);\n });\n\n this.connection.on(\"RemoveNotification\", (notificationType) => {\n this.removeNotification(notificationType);\n });\n\n this.connection.onreconnecting(() => {\n console.warn(\"SignalR: reconnecting...\");\n });\n\n this.connection.onreconnected(() => {\n console.info(\"SignalR: reconnected.\");\n\n if (this.isSessionStarted) {\n this.reloadCurrentSession();\n } else if (config.autoCreateSession) {\n this.startNewSession();\n }\n });\n\n this.connection.onclose((error) => {\n if (this.isNavigatingAway) {\n return;\n }\n\n if (error) {\n console.warn(\"SignalR connection closed with error:\", error.message || error);\n }\n });\n\n try {\n await this.connection.start();\n } catch (err) {\n console.error(\"SignalR Connection Error: \", err);\n }\n },\n addMessageInternal(message) {\n if (message.role === 'assistant') {\n message.appearance = this.normalizeAssistantAppearance(message.appearance);\n }\n\n if (message.content && !message.htmlContent) {\n message.htmlContent = parseMarkdownContent(message.content, message);\n }\n this.fireEvent(new CustomEvent(\"addingCoreAIPromotMessage\", { detail: { message: message } }));\n this.messages.push(message);\n\n this.$nextTick(() => {\n this.fireEvent(new CustomEvent(\"addedCoreAIPromotMessage\", { detail: { message: message } }));\n });\n },\n addMessage(message) {\n\n // Ensure userRating is always defined for Vue reactivity.\n if (message.userRating === undefined) {\n message.userRating = null;\n }\n\n if (message.content) {\n message.rawContent = message.rawContent ?? message.content;\n updateMessagePresentation(message, message.references);\n }\n\n this.addMessageInternal(message);\n this.hidePlaceholder();\n\n this.$nextTick(() => {\n // Render any pending charts once the DOM is updated\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n addMessages(messages) {\n\n for (let i = 0; i < messages.length; i++) {\n this.addMessageInternal(messages[i]);\n }\n\n this.hidePlaceholder();\n this.$nextTick(() => {\n this.scrollToBottom();\n });\n },\n hidePlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.add('d-none');\n }\n this.isPlaceholderVisible = false;\n },\n showPlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.remove('d-none');\n }\n this.isPlaceholderVisible = true;\n },\n isOrchestratorAvailable() {\n return config.isOrchestratorAvailable !== false;\n },\n applyOrchestratorAvailability() {\n if (this.isOrchestratorAvailable()) {\n return true;\n }\n\n const unavailableMessage = config.orchestratorUnavailableMessage || \"This orchestrator is not currently available.\";\n\n if (this.inputElement) {\n this.inputElement.disabled = true;\n this.inputElement.value = '';\n this.inputElement.placeholder = unavailableMessage;\n }\n\n if (this.buttonElement) {\n this.buttonElement.disabled = true;\n }\n\n if (this.micButtonElement) {\n this.micButtonElement.disabled = true;\n this.micButtonElement.style.display = 'none';\n }\n\n if (this.conversationButtonElement) {\n this.conversationButtonElement.disabled = true;\n this.conversationButtonElement.style.display = 'none';\n }\n\n return false;\n },\n fireEvent(event) {\n document.dispatchEvent(event);\n },\n isIndicator(message) {\n return message.role === 'indicator';\n },\n sendMessage() {\n if (!this.applyOrchestratorAvailability()) {\n return;\n }\n\n let trimmedPrompt = this.prompt.trim();\n\n if (!trimmedPrompt) {\n return;\n }\n\n // Stop any active recording before sending.\n if (this.isRecording) {\n this.stopRecording();\n }\n\n // Prevent stale ReceiveTranscript events from repopulating the prompt.\n this._audioInputSent = true;\n\n // In single-response mode, clear all previous messages.\n if (this.singleResponseMode) {\n this.messages.splice(0, this.messages.length);\n }\n\n this.addMessage({\n role: 'user',\n content: trimmedPrompt\n });\n\n this.streamMessage(this.getProfileId(), trimmedPrompt, null);\n this.inputElement.value = '';\n this.prompt = '';\n },\n startRecording() {\n if (this.isRecording || !this.connection) {\n return;\n }\n\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this.preRecordingPrompt = this.prompt;\n this._audioInputSent = false;\n\n var subject = new signalR.Subject();\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var pendingChunk = Promise.resolve();\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n subject.next(base64);\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => subject.complete());\n });\n\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"SendAudioStream\", profileId, sessionId, subject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n this.updateMicButton();\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n });\n },\n stopRecording() {\n if (!this.isRecording || !this.mediaRecorder) {\n return;\n }\n\n this.mediaRecorder.stop();\n this.isRecording = false;\n this.updateMicButton();\n },\n toggleRecording() {\n if (this.isRecording) {\n this.stopRecording();\n } else {\n this.startRecording();\n }\n },\n updateMicButton() {\n if (!this.micButton) {\n return;\n }\n\n if (this.isRecording) {\n this.micButton.classList.add('stt-recording');\n this.micButton.innerHTML = '<i class=\"fa-solid fa-stop\"></i>';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '<i class=\"fa-solid fa-microphone\"></i>';\n }\n },\n streamMessage(profileId, trimmedPrompt, sessionProfileId) {\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n\n this.streamingStarted();\n this.showTypingIndicator();\n this.autoScroll = true;\n\n var content = '';\n var references = {};\n var lastResponseId = null;\n\n // Get the index after showing typing indicator.\n var messageIndex = this.messages.length;\n var currentSessionId = this.getSessionId();\n\n this.stream = this.connection.stream(\"SendMessage\", profileId, trimmedPrompt, currentSessionId, sessionProfileId)\n .subscribe({\n next: (chunk) => {\n let message = this.messages[messageIndex];\n\n if (!message) {\n\n if (chunk.sessionId && !currentSessionId) {\n this.initializeSession(chunk.sessionId);\n }\n\n this.hideTypingIndicator();\n // Re-assign the index after hiding the typing indicator.\n messageIndex = this.messages.length;\n let newMessage = {\n id: chunk.messageId,\n role: \"assistant\",\n title: chunk.title,\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n userRating: null,\n };\n\n this.messages.push(newMessage);\n\n message = newMessage;\n }\n\n if (chunk.title && (!message.title || message.title !== chunk.title)) {\n message.title = chunk.title;\n }\n\n if (chunk.references && typeof chunk.references === \"object\" && Object.keys(chunk.references).length) {\n\n for (const [key, value] of Object.entries(chunk.references)) {\n references[key] = normalizeReference(value) ?? {};\n }\n }\n\n if (chunk.content) {\n\n // When the responseId changes (e.g., after an internal tool call),\n // insert a line break to visually separate response segments.\n if (chunk.responseId && lastResponseId && chunk.responseId !== lastResponseId) {\n content += '\\n\\n';\n }\n\n if (chunk.responseId) {\n lastResponseId = chunk.responseId;\n }\n\n content += chunk.content;\n }\n\n // Update the existing message\n message.rawContent = content;\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n complete: () => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n if (!msg || !msg.content) {\n // No content received at all.\n this.hideTypingIndicator();\n }\n\n // Trigger text-to-speech only in conversation mode.\n if (this.isConversationMode && this.textToSpeechEnabled && msg && msg.content) {\n this.synthesizeSpeech(msg.content);\n }\n\n this.stream?.dispose();\n this.stream = null;\n },\n error: (err) => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n this.hideTypingIndicator();\n\n if (!this.isNavigatingAway) {\n this.addMessage(this.getServiceDownMessage());\n }\n\n this.stream?.dispose();\n this.stream = null;\n\n console.error(\"Stream error:\", err);\n }\n });\n },\n getServiceDownMessage() {\n let newMessage = {\n role: \"assistant\",\n content: \"Our service is currently unavailable. Please try again later. We apologize for the inconvenience.\",\n htmlContent: \"\",\n };\n\n return newMessage;\n },\n processReferences(references, messageIndex) {\n references = normalizeReferences(references);\n\n if (Object.keys(references).length) {\n\n let message = this.messages[messageIndex];\n message.rawContent = message.rawContent ?? message.content ?? '';\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n }\n },\n streamingStarted() {\n var stopIcon = this.buttonElement.getAttribute('data-stop-icon');\n\n if (stopIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(stopIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n if (this.inputElement) {\n this.inputElement.setAttribute('disabled', 'disabled');\n }\n },\n streamingFinished() {\n var startIcon = this.buttonElement.getAttribute('data-start-icon');\n\n if (startIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(startIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n if (this.inputElement) {\n this.inputElement.removeAttribute('disabled');\n this.inputElement.focus();\n }\n\n // Directly manipulate the DOM to stop all streaming animations.\n if (this.chatContainer) {\n var icons = this.chatContainer.querySelectorAll('.ai-streaming-icon');\n for (var i = 0; i < icons.length; i++) {\n icons[i].classList.remove('ai-streaming-icon');\n icons[i].classList.add('ai-bot-icon');\n }\n }\n\n // Also update Vue data for consistency.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n },\n handleExternalTtsStop(e) {\n if (e?.detail?.sourceId === this.ttsInstanceId) {\n return;\n }\n\n this.stopAudio(false);\n },\n updateTtsPlaybackButtons() {\n if (!this.chatContainer) {\n return;\n }\n\n var buttons = this.chatContainer.querySelectorAll('[data-tts-message-index]');\n\n buttons.forEach(button => {\n var buttonIndex = Number(button.getAttribute('data-tts-message-index'));\n var isPlaying = buttonIndex === this.ttsPlayingMessageIndex;\n\n button.classList.toggle('tts-playing', isPlaying);\n button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');\n });\n },\n updateCopyButtons() {\n if (!this.chatContainer) {\n return;\n }\n\n var buttons = this.chatContainer.querySelectorAll('[data-copy-message-index]');\n\n buttons.forEach(button => {\n var buttonIndex = Number(button.getAttribute('data-copy-message-index'));\n var isCopied = buttonIndex === this.copiedMessageIndex;\n var iconHtml = isCopied\n ? '<i class=\"fa-solid fa-check\"></i>'\n : '<i class=\"fa-solid fa-copy\"></i>';\n\n button.classList.toggle('text-success', isCopied);\n button.classList.toggle('text-secondary', !isCopied);\n button.setAttribute('title', isCopied ? this.copiedTitle : this.copyTitle);\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\n });\n },\n setCopyButtonState(button, isCopied) {\n if (!button) {\n return;\n }\n\n var iconHtml = isCopied\n ? '<i class=\"fa-solid fa-check\"></i>'\n : '<i class=\"fa-solid fa-copy\"></i>';\n\n button.classList.toggle('text-success', isCopied);\n button.classList.toggle('text-secondary', !isCopied);\n button.setAttribute('title', isCopied ? this.copiedTitle : this.copyTitle);\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\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 const initialMessages = Array.isArray(config.messages) ? config.messages : [];\n\n for (let i = 0; i < initialMessages.length; i++) {\n this.addMessage(initialMessages[i]);\n }\n\n // Update feedback icons in the DOM after initial messages have rendered.\n this.$nextTick(() => {\n this.refreshAllFeedbackIcons();\n });\n\n // Delegate click for code block copy buttons.\n if (this.chatContainer) {\n this.chatContainer.addEventListener('click', (e) => {\n var btn = e.target.closest('.ai-code-copy-btn');\n if (!btn) {\n return;\n }\n\n var block = btn.closest('.ai-code-block') || btn.closest('pre');\n if (!block) {\n return;\n }\n\n var codeEl = block.querySelector('code');\n if (codeEl) {\n navigator.clipboard.writeText(codeEl.textContent);\n var copiedText = config.codeCopiedText || 'Copied!';\n btn.innerHTML = '<i class=\"fa-solid fa-check\"></i> ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '<i class=\"fa-regular fa-copy\"></i>';\n }, 2000);\n }\n });\n }\n\n // Initialize speech-to-text microphone button.\n if (this.speechToTextEnabled && config.micButtonElementSelector) {\n this.micButton = document.querySelector(config.micButtonElementSelector);\n if (this.micButton) {\n this.micButton.style.display = '';\n this.micButton.addEventListener('click', () => {\n this.toggleRecording();\n });\n }\n }\n\n // Initialize conversation mode button.\n if (this.conversationModeEnabled && config.conversationButtonElementSelector) {\n this.conversationButton = document.querySelector(config.conversationButtonElementSelector);\n if (this.conversationButton) {\n this.conversationButton.addEventListener('click', () => {\n this.toggleConversationMode();\n });\n }\n }\n\n return true;\n },\n loadSession(sessionId) {\n this.connection.invoke(\"LoadSession\", sessionId).catch(err => console.error(err));\n },\n reloadCurrentSession() {\n\n var sessionId = this.getSessionId();\n if (sessionId) {\n this.loadSession(sessionId);\n }\n },\n initializeSession(sessionId, force) {\n if (this.isSessionStarted && !force) {\n if (sessionId && this.getSessionId() === sessionId) {\n this.resolvePendingSessionRequest(sessionId);\n }\n\n return\n }\n this.fireEvent(new CustomEvent(\"initializingSessionCoreAIChat\", { 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 clearCopiedMessageState() {\n if (this.copyResetTimeoutId) {\n window.clearTimeout(this.copyResetTimeoutId);\n this.copyResetTimeoutId = null;\n }\n\n if (this.activeCopyButton) {\n this.setCopyButtonState(this.activeCopyButton, false);\n this.activeCopyButton = null;\n }\n\n this.copiedMessageIndex = -1;\n },\n copyResponse(message, index, event) {\n const text = message && typeof message === 'object'\n ? message.copyContent ?? message.content ?? ''\n : message ?? '';\n const button = event?.currentTarget || event?.target?.closest?.('[data-copy-message-index]') || null;\n\n navigator.clipboard.writeText(text)\n .then(() => {\n this.clearCopiedMessageState();\n this.copiedMessageIndex = typeof index === 'number' ? index : -1;\n this.activeCopyButton = button;\n\n if (button) {\n this.setCopyButtonState(button, true);\n } else {\n this.$nextTick(() => this.updateCopyButtons());\n }\n\n this.copyResetTimeoutId = window.setTimeout(() => {\n this.clearCopiedMessageState();\n this.$nextTick(() => this.updateCopyButtons());\n }, Number(config.copyResetDelayMs) || 2000);\n })\n .catch(err => console.error('Failed to copy response:', err));\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 copiedMessageIndex() {\n this.$nextTick(() => this.updateCopyButtons());\n },\n isConversationMode(active) {\n // Hide/show mic button.\n if (this.micButton) {\n this.micButton.style.display = active ? 'none' : (this.speechToTextEnabled ? '' : 'none');\n }\n\n // Hide/show send button.\n if (this.buttonElement) {\n this.buttonElement.style.display = active ? 'none' : '';\n }\n\n // Disable/enable textarea.\n if (this.inputElement) {\n this.inputElement.disabled = active;\n if (active) {\n this.inputElement.placeholder = '';\n }\n }\n }\n },\n mounted() {\n (async () => {\n await this.startConnection();\n const isInitialized = this.initializeApp();\n if (isInitialized && hasWidgetConfig && widgetBehavior && typeof widgetBehavior.onMounted === 'function') {\n widgetBehavior.onMounted(this, config);\n }\n\n this.$nextTick(() => {\n this.updateCopyButtons();\n refreshFontAwesomeIcons(this.$el);\n this.fontAwesomeObserver = observeFontAwesomeIcons(this.$el);\n });\n })();\n\n window.addEventListener('beforeunload', this.handleBeforeUnload);\n window.addEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n },\n beforeUnmount() {\n window.removeEventListener('beforeunload', this.handleBeforeUnload);\n window.removeEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n\n if (this.fontAwesomeObserver) {\n this.fontAwesomeObserver.disconnect();\n this.fontAwesomeObserver = null;\n }\n\n this.clearCopiedMessageState();\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 const autoInitializeSelector = '[data-coreai-chat-config],[data-coreai-chat-app-element-selector]';\n\n function getAttributeValue(element, attributeName) {\n const value = element.getAttribute(attributeName);\n return value === null || value === '' ? null : value;\n }\n\n function parseBooleanAttributeValue(value) {\n if (value === null || value === undefined) {\n return null;\n }\n\n if (typeof value === 'boolean') {\n return value;\n }\n\n const normalized = String(value).trim().toLowerCase();\n if (normalized === 'true') {\n return true;\n }\n\n if (normalized === 'false') {\n return false;\n }\n\n return null;\n }\n\n function parseJsonAttribute(element, attributeName, description) {\n const rawValue = getAttributeValue(element, attributeName);\n if (!rawValue) {\n return null;\n }\n\n try {\n return JSON.parse(rawValue);\n } catch (error) {\n console.error('Failed to parse ' + description + ' JSON.', error);\n return null;\n }\n }\n\n function buildConfigFromDataAttributes(element, options) {\n const settings = options || {};\n\n if (element.hasAttribute('data-coreai-chat-widget-container-selector') && settings.allowWidgetHost !== true) {\n return null;\n }\n\n const appElementSelector = getAttributeValue(element, 'data-coreai-chat-app-element-selector');\n if (!appElementSelector) {\n return null;\n }\n\n const config = {\n signalRHubUrl: getAttributeValue(element, 'data-coreai-chat-signalr-hub-url'),\n appElementSelector: appElementSelector,\n chatContainerElementSelector: getAttributeValue(element, 'data-coreai-chat-container-element-selector'),\n inputElementSelector: getAttributeValue(element, 'data-coreai-chat-input-element-selector'),\n sendButtonElementSelector: getAttributeValue(element, 'data-coreai-chat-send-button-element-selector'),\n placeholderElementSelector: getAttributeValue(element, 'data-coreai-chat-placeholder-element-selector'),\n messages: parseJsonAttribute(element, 'data-coreai-chat-messages', 'CoreAI chat messages') ?? undefined,\n chatMode: getAttributeValue(element, 'data-coreai-chat-mode'),\n micButtonElementSelector: getAttributeValue(element, 'data-coreai-chat-mic-button-element-selector'),\n conversationButtonElementSelector: getAttributeValue(element, 'data-coreai-chat-conversation-button-element-selector'),\n ttsVoiceName: getAttributeValue(element, 'data-coreai-chat-tts-voice-name'),\n documentBarSelector: getAttributeValue(element, 'data-coreai-chat-document-bar-selector'),\n uploadDocumentUrl: getAttributeValue(element, 'data-coreai-chat-upload-document-url'),\n removeDocumentUrl: getAttributeValue(element, 'data-coreai-chat-remove-document-url'),\n allowedExtensions: getAttributeValue(element, 'data-coreai-chat-allowed-extensions'),\n supportedExtensionsText: getAttributeValue(element, 'data-coreai-chat-supported-extensions-text'),\n existingDocuments: parseJsonAttribute(element, 'data-coreai-chat-existing-documents', 'CoreAI chat existing documents') ?? undefined,\n initialPrompt: getAttributeValue(element, 'data-coreai-chat-initial-prompt'),\n userLabel: getAttributeValue(element, 'data-coreai-chat-user-label'),\n assistantLabel: getAttributeValue(element, 'data-coreai-chat-assistant-label'),\n copyTitle: getAttributeValue(element, 'data-coreai-chat-copy-title'),\n copiedTitle: getAttributeValue(element, 'data-coreai-chat-copied-title'),\n };\n\n const booleanAttributes = {\n metricsEnabled: 'data-coreai-chat-metrics-enabled',\n textToSpeechEnabled: 'data-coreai-chat-text-to-speech-enabled',\n sessionDocumentsEnabled: 'data-coreai-chat-session-documents-enabled',\n autoCreateSession: 'data-coreai-chat-auto-create-session',\n singleResponseMode: 'data-coreai-chat-single-response-mode',\n };\n\n Object.keys(booleanAttributes).forEach(key => {\n const parsed = parseBooleanAttributeValue(getAttributeValue(element, booleanAttributes[key]));\n if (parsed !== null) {\n config[key] = parsed;\n }\n });\n\n return compactObject(config);\n }\n\n function buildConfigFromElement(element, options) {\n const jsonConfig = parseJsonAttribute(element, 'data-coreai-chat-config', 'CoreAI chat config');\n const attributeConfig = buildConfigFromDataAttributes(element, options);\n\n if (!jsonConfig && !attributeConfig) {\n return null;\n }\n\n return Object.assign({}, jsonConfig || {}, attributeConfig || {});\n }\n\n function initializeFromElement(element) {\n if (!element || element.dataset.coreAiChatInitialized === 'true') {\n return element ? element.__coreAIChatApp || null : null;\n }\n\n const config = buildConfigFromElement(element);\n if (!config) {\n return null;\n }\n\n const app = initialize(config);\n if (!app) {\n return null;\n }\n\n element.dataset.coreAiChatInitialized = 'true';\n element.__coreAIChatApp = app;\n\n return app;\n }\n\n function scanForAutoInitialization(root) {\n if (!root || typeof root.querySelectorAll !== 'function') {\n return;\n }\n\n if (typeof root.matches === 'function' && root.matches(autoInitializeSelector)) {\n initializeFromElement(root);\n }\n\n root.querySelectorAll(autoInitializeSelector).forEach(initializeFromElement);\n }\n\n function startAutoInitialization() {\n scanForAutoInitialization(document);\n\n if (typeof MutationObserver === 'undefined') {\n return;\n }\n\n const observer = new MutationObserver(mutations => {\n mutations.forEach(mutation => {\n mutation.addedNodes.forEach(node => {\n if (node && node.nodeType === 1) {\n scanForAutoInitialization(node);\n }\n });\n });\n });\n\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n });\n }\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', startAutoInitialization, { once: true });\n } else {\n startAutoInitialization();\n }\n\n return {\n initialize: initialize,\n initializeFromElement: initializeFromElement,\n buildConfigFromElement: buildConfigFromElement,\n };\n}();\n\n// Download chart as image via event delegation (DOMPurify strips inline onclick).\ndocument.addEventListener('click', function (e) {\n const btn = e.target.closest('.download-chart-btn');\n if (!btn) {\n return;\n }\n const chartId = btn.getAttribute('data-chart-id');\n const canvas = chartId ? document.getElementById(chartId) : null;\n if (!canvas) {\n console.error('Chart canvas not found:', chartId);\n return;\n }\n const link = document.createElement('a');\n link.download = 'chart-' + chartId + '.png';\n link.href = canvas.toDataURL('image/png');\n link.click();\n});\n\n// Intercept download clicks for data-URI images and convert to blob downloads.\ndocument.addEventListener('click', function (e) {\n const link = e.target.closest('.ai-download-image');\n if (!link) {\n return;\n }\n\n const container = link.closest('.generated-image-container');\n const img = container?.querySelector('img');\n if (!img) {\n return;\n }\n\n const src = img.src;\n if (!src || !src.startsWith('data:')) {\n return; // Normal URL – let the default <a> behaviour handle it.\n }\n\n e.preventDefault();\n\n fetch(src)\n .then(function (res) { return res.blob(); })\n .then(function (blob) {\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = link.getAttribute('download') || 'generated-image.png';\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n setTimeout(function () { URL.revokeObjectURL(url); }, 100);\n })\n .catch(function (err) { console.error('Failed to download image:', err); });\n});\n"]}
|
|
1
|
+
{"version":3,"sources":["ai-chat.js"],"names":["_excluded","_regenerator","e","t","r","Symbol","n","iterator","o","toStringTag","i","c","prototype","Generator","u","Object","create","_regeneratorDefine2","f","p","y","G","v","a","d","bind","length","l","TypeError","call","done","value","GeneratorFunction","GeneratorFunctionPrototype","getPrototypeOf","this","setPrototypeOf","__proto__","displayName","w","m","defineProperty","_invoke","enumerable","configurable","writable","asyncGeneratorStep","Promise","resolve","then","_asyncToGenerator","arguments","apply","_next","_throw","_toConsumableArray","_arrayWithoutHoles","_iterableToArray","_unsupportedIterableToArray","_nonIterableSpread","Array","from","isArray","_arrayLikeToArray","_objectWithoutProperties","_objectWithoutPropertiesLoose","getOwnPropertySymbols","indexOf","propertyIsEnumerable","hasOwnProperty","_createForOfIteratorHelper","_n","F","s","next","_slicedToArray","_arrayWithHoles","_iterableToArrayLimit","_nonIterableRest","toString","slice","constructor","name","test","push","_typeof","window","coreAIChatManager","defaultConfig","generatedImageAltText","generatedImageMaxWidth","downloadImageTitle","downloadChartTitle","downloadChartButtonText","userLabel","assistantLabel","thumbsUpTitle","thumbsDownTitle","copyTitle","copiedTitle","codeCopiedText","copyResetDelayMs","widget","chatWidgetContainer","chatWidgetStateName","chatHistorySection","showHistoryButton","closeHistoryButton","newChatButton","toggleButtonSelector","resetSizeButtonSelector","dragHandleSelector","enableDragging","enableResizing","persistLayout","defaultWidth","defaultHeight","minWidth","minHeight","messageTemplate","indicatorTemplate","sanitizeUrl","url","trimmed","trim","escapeHtmlEntities","text","span","document","createElement","textContent","innerHTML","refreshFontAwesomeIcons","root","fontAwesome","FontAwesome","nodeType","selector","matches","querySelector","containsFontAwesomePlaceholders","dom","i2svg","node","observeFontAwesomeIcons","MutationObserver","observer","mutations","forEach","mutation","addedNodes","observe","childList","subtree","normalizeReference","reference","_ref","_normalized$index","_ref2","_normalized$text","_ref3","_normalized$title","_ref4","_normalized$link","_ref5","_normalized$reference","_normalized$isGenerat","normalized","assign","index","Index","Text","title","Title","link","Link","referenceType","ReferenceType","isGenerated","IsGenerated","isDownloadCitationReference","toLowerCase","normalizeReferences","references","_i","_Object$entries","entries","_normalizeReference","_Object$entries$_i","key","getCitationLabel","updateMessagePresentation","message","messageReferences","rawContent","content","citationDisplay","processedContent","referenceEntries","citations","citedRefs","filter","_ref6","includes","generatedRefs","_ref8","_ref9","sort","_ref0","_ref1","b","_ref12","_ref13","_step","displayIndex","_iterator","_step$value","placeholder","concat","replaceAll","referenceKey","label","isDownload","err","_i2","_citations","citation","_step2","_iterator2","_step2$value","map","_ref16","buildCitationDisplay","displayContent","citationReferences","copyContent","_step3","_iterator3","_step4","_iterator4","trimEnd","buildCopyContent","htmlContent","parseMarkdownContent","renderer","marked","Renderer","data","href","code","lang","highlighted","hljs","getLanguage","highlight","language","_","highlightAuto","langDisplay","image","src","alt","maxWidth","chartCounter","_pendingCharts","renderChartsInMessage","charts","requestAnimationFrame","_step5","_iterator5","renderChartOnCanvas","chartId","config","canvas","getElementById","Chart","console","warn","offsetParent","__chartConfigs","_cfg$options","_cfg$options2","_cfg$options2$aspectR","_chartInstance","destroy","cfg","JSON","parse","options","responsive","maintainAspectRatio","aspectRatio","error","html","DOMPurify","sanitize","ADD_TAGS","ADD_ATTR","compactObject","source","fromEntries","_ref17","undefined","use","extensions","level","start","idx","tokenizer","extracted","token","jsonStart","depth","inString","escape","ch","jsonEnd","closeBracketIndex","startIndex","endIndex","json","substring","tryExtractChartMarker","type","raw","renderPendingCharts","configs","_i3","_Object$keys","keys","initialize","instanceConfig","normalizedInstanceConfig","normalizedWidgetConfig","template","encodedAssistantLabel","replace","resolveIndicatorTemplate","hasWidgetConfig","widgetBehavior","coreAIChatWidgetBehavior","signalRHubUrl","appElementSelector","chatContainerElementSelector","inputElementSelector","sendButtonElementSelector","appDefinition","inputElement","buttonElement","chatContainer","isSessionStarted","isPlaceholderVisible","isStreaming","isNavigatingAway","autoScroll","stream","messages","notifications","prompt","documents","existingDocuments","isUploading","isDocumentOperationPending","documentOperationQueue","uploadErrors","isDragOver","documentBar","metricsEnabled","isRecording","mediaRecorder","preRecordingPrompt","micButton","speechToTextEnabled","chatMode","textToSpeechEnabled","ttsVoiceName","audioChunks","audioPlayQueue","isPlayingAudio","currentAudioElement","currentAudioUrl","ttsButton","ttsPlayingMessageIndex","ttsAudioCache","ttsInstanceId","Math","random","singleResponseMode","conversationModeEnabled","conversationButton","isConversationMode","notificationDismissTimers","pendingSessionPromise","pendingSessionResolver","pendingSessionRejector","pendingSessionTimeoutId","copiedMessageIndex","copyResetTimeoutId","activeCopyButton","computed","lastAssistantIndex","role","methods","handleBeforeUnload","handleDragOver","sessionDocumentsEnabled","preventDefault","stopPropagation","inputArea","closest","classList","add","handleDragLeave","remove","handleDrop","dataTransfer","files","uploadFiles","triggerFileInput","fileInput","click","handleFileInputChange","target","queueDocumentOperation","operation","self","nextOperation","_callee","_context","_this","_callee3","filesToUpload","_context3","uploadDocumentUrl","_callee2","sessionId","profileId","formData","response","errorText","uploadError","result","_t","_t2","_context2","getSessionId","getProfileId","ensureSessionForDocuments","fileName","renderDocumentBar","FormData","append","fetch","method","body","ok","extractReadableErrorMessage","initializeSession","uploaded","failed","reloadCurrentSession","removeDocument","doc","_this2","_callee5","_context5","removeDocumentUrl","_callee4","removeError","_t3","_context4","headers","stringify","itemId","documentId","splice","status","formatFileSize","bytes","toFixed","escapeHtml","failedItem","failedName","errorMsg","supportedExtensionsText","replaceChildren","RETURN_DOM_FRAGMENT","closeButtons","querySelectorAll","j","addEventListener","docToRemove","parseInt","getAttribute","errorCloseButtons","addBtn","div","fallbackMessage","startsWith","parsed","detail","normalizeAssistantAppearance","appearance","icon","cssClass","disableStreamingAnimation","getAssistantLabel","getAssistantRoleClasses","classes","getAssistantIconClasses","shouldAnimateAssistantIcon","getAssistantIcon","startConnection","_this3","_callee6","_t4","_context6","connection","signalR","HubConnectionBuilder","withUrl","withAutomaticReconnect","build","serverTimeoutInMilliseconds","keepAliveIntervalInMilliseconds","on","_data$messages","msg","addMessage","$nextTick","refreshAllFeedbackIcons","initialPrompt","sendMessage","stopRecording","handleReceiveError","messageId","userRating","find","id","isFinal","_conversationPartialTranscript","_conversationPartialMessage","hidePlaceholder","isPartial","scrollToBottom","_audioInputSent","dispatchEvent","Event","stopAudio","_conversationAssistantMessage","oldMsg","escaped","responseId","hideTypingIndicator","msgIndex","newMessage","base64Audio","contentType","binaryString","atob","Uint8Array","charCodeAt","playCollectedAudio","notification","receiveNotification","updateNotification","notificationType","removeNotification","onreconnecting","onreconnected","info","autoCreateSession","startNewSession","onclose","addMessageInternal","_this4","fireEvent","CustomEvent","_message$rawContent","_this5","addMessages","_this6","showPlaceholder","isOrchestratorAvailable","applyOrchestratorAvailability","unavailableMessage","orchestratorUnavailableMessage","disabled","micButtonElement","style","display","conversationButtonElement","event","isIndicator","trimmedPrompt","streamMessage","startRecording","_this7","navigator","mediaDevices","getUserMedia","audio","echoCancellation","noiseSuppression","autoGainControl","mimeType","MediaRecorder","isTypeSupported","audioBitsPerSecond","subject","Subject","pendingChunk","size","_callee7","uint8Array","base64","_context7","arrayBuffer","reduce","str","byte","String","fromCharCode","btoa","getTracks","track","stop","complete","documentElement","send","updateMicButton","toggleRecording","sessionProfileId","_this8","dispose","streamingStarted","showTypingIndicator","lastResponseId","messageIndex","currentSessionId","subscribe","chunk","_i4","_Object$entries2","_normalizeReference2","_Object$entries2$_i","_this8$stream","processReferences","streamingFinished","synthesizeSpeech","_this8$stream2","getServiceDownMessage","_this9","_ref23","_message$rawContent2","stopIcon","setAttribute","startIcon","removeAttribute","focus","icons","handleExternalTtsStop","_e$detail","sourceId","updateTtsPlaybackButtons","_this0","button","isPlaying","Number","toggle","updateCopyButtons","_this1","isCopied","iconHtml","setCopyButtonState","cacheIndex","_this10","_ttsCacheIndex","invoke","toggleMessageTts","_this11","playAudioBlob","_this12","_step6","totalLength","sum","combined","offset","_iterator6","set","blob","Blob","_this13","URL","createObjectURL","Audio","revokeObjectURL","playNextInQueue","play","_this14","nextBlob","shift","conversationModeOnAudioEnded","_this15","pause","currentTime","toggleConversationMode","stopConversationMode","startConversationMode","_this16","updateConversationButton","_conversationSubject","_conversationStream","AudioCtx","AudioContext","webkitAudioContext","_conversationAudioCtx","_conversationAnalyser","createAnalyser","fftSize","createMediaStreamSource","connect","analyser","freqData","frequencyBinCount","getByteFrequencyData","k","_callee8","_context8","close","dismissible","autoDismissMs","endHtml","blur","startHtml","conversationModeSendPrompt","generatePrompt","element","templateProfileId","createSessionUrl","baseUrl","param","fullUrl","location","origin","searchParams","originalLength","_this17","clearNotificationDismiss","existingIndex","findIndex","scheduleNotificationDismiss","_this18","setTimeout","timerId","clearTimeout","dismissNotification","handleNotificationAction","actionName","_this19","scrollTop","scrollHeight","clientHeight","handleUserInput","setSessionId","resetSession","rejectPendingSessionRequest","sessionRating","onSessionReset","requestNewSession","_this20","_callee9","_context9","_this21","reject","resolvePendingSessionRequest","clearPendingSessionRequest","initializeApp","_this22","placeholderElementSelector","loadSession","documentBarSelector","className","multiple","allowedExtensions","accept","parentElement","appendChild","atBottom","shiftKey","lastMsg","pop","promptGenerators","getElementsByClassName","chatSessions","showChatScreen","initialMessages","btn","block","codeEl","clipboard","writeText","copiedText","micButtonElementSelector","conversationButtonElementSelector","force","onSessionInitialized","resolveSessionId","clearCopiedMessageState","copyResponse","_ref25","_message$copyContent","_event$target","_event$target$closest","_this23","currentTarget","updateFeedbackIcons","container","upBtn","downBtn","upClass","upIcon","fontSize","downClass","downIcon","containers","$el","msgId","rateMessage","isPositive","newRating","feedbackContainer","btnClass","offsetWidth","onEnd","removeEventListener","watch","handler","onDocumentsChanged","deep","_this24","active","mounted","_this25","_callee0","_context0","onMounted","fontAwesomeObserver","beforeUnmount","disconnect","onBeforeUnmount","app","Vue","createApp","mount","attach","autoInitializeSelector","getAttributeValue","attributeName","parseJsonAttribute","description","rawValue","buildConfigFromDataAttributes","_parseJsonAttribute","_parseJsonAttribute2","settings","hasAttribute","allowWidgetHost","booleanAttributes","parseBooleanAttributeValue","buildConfigFromElement","jsonConfig","attributeConfig","initializeFromElement","dataset","coreAiChatInitialized","__coreAIChatApp","scanForAutoInitialization","startAutoInitialization","readyState","once","download","toDataURL","img","res","removeChild"],"mappings":"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","file":"ai-chat.min.js","sourcesContent":["window.coreAIChatManager = 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 copiedTitle: 'Response copied to clipboard.',\n codeCopiedText: 'Copied!',\n copyResetDelayMs: 2000,\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-message-heading ai-chat-message-heading-user\">\n <span class=\"ai-chat-msg-role ai-chat-msg-role-user\">{{ userLabel }}</span>\n </div>\n <div v-else-if=\"message.role !== 'indicator'\" class=\"ai-chat-message-heading ai-chat-message-heading-assistant\">\n <div :class=\"getAssistantRoleClasses(message)\">\n <span :class=\"getAssistantIconClasses(message, index)\"><i :class=\"getAssistantIcon(message)\"></i></span>\n <span class=\"ai-chat-message-role-label\">{{ getAssistantLabel(message) }}</span>\n </div>\n </div>\n <div class=\"ai-chat-message-body lh-base\">\n <h4 v-if=\"message.title\">{{ message.title }}</h4>\n <div v-html=\"message.htmlContent\"></div>\n <ol v-if=\"message.citationReferences && message.citationReferences.length\" class=\"ai-chat-citation-list\">\n <li v-for=\"citation in message.citationReferences\" :key=\"'citation-' + (citation.referenceKey || citation.displayIndex)\" class=\"ai-chat-citation-item\">\n <a v-if=\"citation.link\" :href=\"citation.link\" :target=\"citation.isDownload ? null : '_blank'\" :rel=\"citation.isDownload ? null : 'noopener noreferrer'\">{{ citation.label }}</a>\n <span v-else>{{ citation.label }}</span>\n </li>\n </ol>\n <span class=\"message-buttons-container\" v-if=\"!isIndicator(message)\">\n <template v-if=\"metricsEnabled && message.role === 'assistant'\">\n <span class=\"ai-chat-message-assistant-feedback\" :data-message-id=\"message.id\">\n <button type=\"button\" class=\"btn btn-sm btn-link text-success p-0 me-2 button-message-toolbox rate-up-btn\" @click=\"rateMessage(message, true, $event)\" :title=\"thumbsUpTitle\">\n <i class=\"fa-regular fa-thumbs-up\"></i>\n </button>\n <button type=\"button\" class=\"btn btn-sm btn-link text-danger p-0 me-2 button-message-toolbox rate-down-btn\" @click=\"rateMessage(message, false, $event)\" :title=\"thumbsDownTitle\">\n <i class=\"fa-regular fa-thumbs-down\"></i>\n </button>\n </span>\n </template>\n <button type=\"button\" v-if=\"textToSpeechEnabled && !isConversationMode && message.role === 'assistant' && !message.isStreaming\" class=\"btn btn-sm btn-link text-secondary p-0 me-1 button-message-toolbox\" :class=\"{ 'tts-playing': ttsPlayingMessageIndex === index }\" :data-tts-message-index=\"index\" @click=\"toggleMessageTts(message, index)\" :title=\"ttsPlayingMessageIndex === index ? 'Pause audio' : 'Read aloud'\">\n <span :class=\"ttsPlayingMessageIndex === index ? 'fa-solid fa-circle-pause' : 'fa-solid fa-circle-play'\"></span>\n </button>\n <button type=\"button\" class=\"btn btn-sm btn-link p-0 button-message-toolbox ai-response-copy-btn\" :class=\"copiedMessageIndex === index ? 'text-success' : 'text-secondary'\" :data-copy-message-index=\"index\" @click=\"copyResponse(message, index, $event)\" :title=\"copiedMessageIndex === index ? copiedTitle : copyTitle\">\n <i :class=\"copiedMessageIndex === index ? 'fa-solid fa-check' : 'fa-solid fa-copy'\"></i>\n </button>\n </span>\n </div>\n </div>\n </div>\n <div v-for=\"notification in notifications\" :key=\"'notif-' + notification.type\" class=\"ai-chat-notification\" :class=\"'ai-chat-notification-' + (notification.type || 'info') + ' ' + (notification.cssClass || '')\">\n <div class=\"ai-chat-notification-content\">\n <i v-if=\"notification.icon\" :class=\"notification.icon\" class=\"ai-chat-notification-icon\"></i>\n <span class=\"ai-chat-notification-text\">{{ notification.content }}</span>\n <button type=\"button\" v-if=\"notification.dismissible\" class=\"btn btn-sm btn-link p-0 ms-2 ai-chat-notification-dismiss\" @click=\"dismissNotification(notification.type)\" title=\"Dismiss\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n <div v-if=\"notification.actions && notification.actions.length\" class=\"ai-chat-notification-actions\">\n <button type=\"button\" v-for=\"action in notification.actions\" :key=\"action.name\" class=\"btn btn-sm\" :class=\"action.cssClass || 'btn-outline-secondary'\" @click=\"handleNotificationAction(notification.type, action.name)\">\n <i v-if=\"action.icon\" :class=\"action.icon\" class=\"me-1\"></i>\n {{ action.label }}\n </button>\n </div>\n </div>\n </div>\n `,\n indicatorTemplate: `\n <div class=\"ai-chat-message-heading ai-chat-message-heading-assistant\">\n <div class=\"ai-chat-msg-role ai-chat-msg-role-assistant\">\n <span class=\"ai-streaming-icon\"><i class=\"fa fa-robot\" style=\"display: inline-block;\"></i></span>\n <span class=\"ai-chat-message-role-label\">Assistant</span>\n </div>\n </div>\n `\n };\n\n // Sanitize URLs to prevent javascript: protocol injection.\n function sanitizeUrl(url) {\n if (!url) return '';\n var trimmed = url.trim();\n if (/^javascript:/i.test(trimmed) || /^vbscript:/i.test(trimmed) || /^data:text\\/html/i.test(trimmed)) {\n return '';\n }\n return url;\n }\n\n // Safely HTML-encode a string using the DOM (avoids regex-based HTML filtering).\n function escapeHtmlEntities(text) {\n var span = document.createElement('span');\n span.textContent = text;\n return span.innerHTML;\n }\n\n function containsFontAwesomePlaceholders(root) {\n if (!root || root.nodeType !== 1) {\n return false;\n }\n\n var selector = 'i[class*=\"fa-\"],i.fa,i.fas,i.far,i.fab';\n if (typeof root.matches === 'function' && root.matches(selector)) {\n return true;\n }\n\n return typeof root.querySelector === 'function' && !!root.querySelector(selector);\n }\n\n function refreshFontAwesomeIcons(root) {\n var fontAwesome = window.FontAwesome;\n if (!containsFontAwesomePlaceholders(root) || !fontAwesome || !fontAwesome.dom || typeof fontAwesome.dom.i2svg !== 'function') {\n return;\n }\n\n fontAwesome.dom.i2svg({ node: root });\n }\n\n function observeFontAwesomeIcons(root) {\n if (!root || typeof MutationObserver === 'undefined') {\n return null;\n }\n\n var observer = new MutationObserver(function (mutations) {\n mutations.forEach(function (mutation) {\n mutation.addedNodes.forEach(function (node) {\n refreshFontAwesomeIcons(node);\n });\n });\n });\n\n observer.observe(root, {\n childList: true,\n subtree: true\n });\n\n return observer;\n }\n\n function parsePixelValue(value) {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n\n if (typeof value !== 'string') {\n return null;\n }\n\n var parsed = parseFloat(value);\n return Number.isFinite(parsed) ? parsed : null;\n }\n\n function clamp(value, min, max) {\n return Math.min(Math.max(value, min), max);\n }\n\n function normalizeReference(reference) {\n if (!reference || typeof reference !== 'object') {\n return null;\n }\n\n const normalized = Object.assign({}, reference);\n normalized.index = normalized.index ?? normalized.Index ?? 0;\n normalized.text = normalized.text ?? normalized.Text ?? null;\n normalized.title = normalized.title ?? normalized.Title ?? null;\n normalized.link = sanitizeUrl(normalized.link ?? normalized.Link ?? null);\n normalized.referenceType = normalized.referenceType ?? normalized.ReferenceType ?? null;\n normalized.isGenerated = (normalized.isGenerated ?? normalized.IsGenerated) === true;\n\n return normalized;\n }\n\n function isDownloadCitationReference(reference) {\n if (!reference || typeof reference !== 'object') {\n return false;\n }\n\n if (typeof reference.referenceType === 'string' && reference.referenceType.toLowerCase() === 'document') {\n return true;\n }\n\n if (typeof reference.link === 'string' && /\\/ai\\/documents\\/.+\\/download(?:$|\\?)/i.test(reference.link)) {\n return true;\n }\n\n return false;\n }\n\n function normalizeReferences(references) {\n if (!references || typeof references !== 'object') {\n return {};\n }\n\n const normalized = {};\n\n for (const [key, value] of Object.entries(references)) {\n normalized[key] = normalizeReference(value) ?? {};\n }\n\n return normalized;\n }\n\n function getCitationLabel(reference, key) {\n return reference.title || reference.text || key;\n }\n\n function buildCitationDisplay(content, references) {\n let processedContent = (content || '').trim();\n const messageReferences = normalizeReferences(references);\n const referenceEntries = Object.entries(messageReferences);\n\n if (!referenceEntries.length) {\n return { content: processedContent, citations: [] };\n }\n\n const citedRefs = referenceEntries.filter(([key]) => processedContent.includes(key));\n const generatedRefs = referenceEntries.filter(([key, value]) => value.isGenerated && !processedContent.includes(key));\n\n if (!citedRefs.length && !generatedRefs.length) {\n return { content: processedContent, citations: [] };\n }\n\n citedRefs.sort(([, a], [, b]) => a.index - b.index);\n generatedRefs.sort(([, a], [, b]) => a.index - b.index);\n\n const citations = [];\n let displayIndex = 1;\n\n for (const [key, value] of citedRefs) {\n const placeholder = `__CITE_${displayIndex}_${value.index || displayIndex}__`;\n processedContent = processedContent.replaceAll(key, placeholder);\n citations.push({\n referenceKey: key,\n displayIndex: displayIndex,\n label: getCitationLabel(value, key),\n link: value.link || null,\n isDownload: isDownloadCitationReference(value),\n placeholder: placeholder,\n });\n\n displayIndex++;\n }\n\n for (const citation of citations) {\n processedContent = processedContent.replaceAll(citation.placeholder, `<sup>${citation.displayIndex}</sup>`);\n }\n\n processedContent = processedContent.replaceAll('</sup><sup>', '</sup><sup>,</sup><sup>');\n\n // Generated files (such as exported tabular data) are always offered as a download even when\n // the model does not cite them inline, so the user never loses access to the produced file.\n for (const [key, value] of generatedRefs) {\n citations.push({\n referenceKey: key,\n displayIndex: displayIndex,\n label: getCitationLabel(value, key),\n link: value.link || null,\n isDownload: true,\n placeholder: null,\n });\n\n displayIndex++;\n }\n\n return {\n content: processedContent,\n citations: citations.map(({ placeholder, ...citation }) => citation),\n };\n }\n\n function buildCopyContent(content, citations) {\n let copyContent = (content || '').trim();\n\n if (!copyContent || !Array.isArray(citations) || citations.length === 0) {\n return copyContent;\n }\n\n for (const citation of citations) {\n copyContent = copyContent.replaceAll(citation.referenceKey, `[${citation.displayIndex}]`);\n }\n\n copyContent += '\\n\\nReferences:\\n';\n\n for (const citation of citations) {\n copyContent += `${citation.displayIndex}. ${citation.label}`;\n\n if (citation.link) {\n copyContent += ` - ${citation.link}`;\n }\n\n copyContent += '\\n';\n }\n\n return copyContent.trimEnd();\n }\n\n function updateMessagePresentation(message, references) {\n const messageReferences = normalizeReferences(references ?? message.references);\n const rawContent = typeof message.rawContent === 'string'\n ? message.rawContent\n : typeof message.content === 'string'\n ? message.content\n : '';\n const citationDisplay = buildCitationDisplay(rawContent, messageReferences);\n\n message.rawContent = rawContent;\n message.content = rawContent;\n message.displayContent = citationDisplay.content;\n message.references = messageReferences;\n message.citationReferences = citationDisplay.citations;\n message.copyContent = buildCopyContent(rawContent, citationDisplay.citations);\n message.htmlContent = parseMarkdownContent(citationDisplay.content, message);\n\n return message;\n }\n\n const renderer = new marked.Renderer();\n\n // Modify the link rendering to open in a new tab\n renderer.link = function (data) {\n var href = sanitizeUrl(data.href);\n if (!href) return data.text || '';\n return `<a href=\"${href}\" target=\"_blank\" rel=\"noopener noreferrer\">${data.text}</a>`;\n };\n\n // Custom code block renderer with highlight.js integration and copy button.\n renderer.code = function (data) {\n var code = data.text || '';\n var lang = (data.lang || '').trim();\n var highlighted = code;\n\n if (typeof hljs !== 'undefined') {\n if (lang && hljs.getLanguage(lang)) {\n try {\n highlighted = hljs.highlight(code, { language: lang }).value;\n } catch (_) { }\n } else {\n try {\n highlighted = hljs.highlightAuto(code).value;\n } catch (_) { }\n }\n } else {\n highlighted = escapeHtmlEntities(code);\n }\n\n var langDisplay = lang ? escapeHtmlEntities(lang) : 'code';\n return `<div class=\"ai-code-block\"><div class=\"ai-code-header\"><span class=\"ai-code-lang\"><i class=\"fa-solid fa-code\"></i> ${langDisplay}</span><button type=\"button\" class=\"ai-code-copy-btn\" title=\"Copy code\"><i class=\"fa-regular fa-copy\"></i></button></div><pre><code class=\"hljs${lang ? ' language-' + lang : ''}\">${highlighted}</code></pre></div>`;\n };\n\n // Custom image renderer for generated images with thumbnail styling and download button.\n // Handles both URL and data-URI sources (data URIs are converted to blobs for download).\n renderer.image = function (data) {\n const src = sanitizeUrl(data.href);\n if (!src) return '';\n const alt = data.text || defaultConfig.generatedImageAltText;\n const maxWidth = defaultConfig.generatedImageMaxWidth;\n return `<div class=\"generated-image-container\">\n <img src=\"${src}\" alt=\"${alt}\" class=\"img-thumbnail\" style=\"max-width: ${maxWidth}px; height: auto;\" />\n <div class=\"mt-2\">\n <a href=\"${src}\" target=\"_blank\" download=\"${alt}\" title=\"${defaultConfig.downloadImageTitle}\" class=\"btn btn-sm btn-outline-secondary ai-download-image\">\n <i class=\"fa-solid fa-download\"></i>\n </a>\n </div>\n </div>`;\n };\n\n // Chart counter for unique IDs\n let chartCounter = 0;\n\n // Collector for charts discovered during marked parsing.\n let _pendingCharts = [];\n\n // Global chart config map: any page (e.g., Chat Interactions) that uses\n // the shared marked instance can call window.renderPendingCharts() after\n // its DOM update to render charts it didn't create itself.\n window.__chartConfigs = window.__chartConfigs || {};\n\n function createChartHtml(chartId) {\n return `<div class=\"chart-container\" style=\"position: relative; width: 100%; max-width: 560px; min-height: 420px;\">`\n + `<canvas id=\"${chartId}\"></canvas>`\n + `</div>`\n + `<div class=\"mt-2\">`\n + `<button type=\"button\" class=\"btn btn-sm btn-outline-secondary download-chart-btn\" data-chart-id=\"${chartId}\" title=\"${defaultConfig.downloadChartTitle}\">`\n + `<i class=\"fa-solid fa-download\"></i> ${defaultConfig.downloadChartButtonText}`\n + `</button>`\n + `</div>`;\n }\n\n // Register [chart:{...json...}] as a native marked block extension so the\n // markdown parser handles chart markers inline with surrounding text.\n marked.use({\n extensions: [{\n name: 'chart',\n level: 'block',\n start(src) {\n const idx = src.indexOf('[chart:');\n return idx >= 0 ? idx : undefined;\n },\n tokenizer(src) {\n const extracted = tryExtractChartMarker(src);\n if (!extracted || extracted.startIndex !== 0) {\n return undefined;\n }\n\n const chartId = `chat_chart_${++chartCounter}`;\n\n return {\n type: 'chart',\n raw: src.substring(0, extracted.endIndex),\n chartId: chartId,\n json: extracted.json,\n };\n },\n renderer(token) {\n _pendingCharts.push({ chartId: token.chartId, config: token.json });\n window.__chartConfigs[token.chartId] = token.json;\n return createChartHtml(token.chartId);\n }\n }]\n });\n\n // Extract a [chart:{...json...}] marker. This avoids regex issues with nested brackets.\n function tryExtractChartMarker(text) {\n const token = '[chart:';\n const start = text.indexOf(token);\n if (start < 0) {\n return null;\n }\n\n // Find JSON object boundary by balancing braces\n const jsonStart = start + token.length;\n let i = jsonStart;\n while (i < text.length && (text[i] === ' ' || text[i] === '\\n' || text[i] === '\\r' || text[i] === '\\t')) {\n i++;\n }\n\n if (i >= text.length || text[i] !== '{') {\n return null;\n }\n\n let depth = 0;\n let inString = false;\n let escape = false;\n\n for (; i < text.length; i++) {\n const ch = text[i];\n\n if (inString) {\n if (escape) {\n escape = false;\n continue;\n }\n if (ch === '\\\\') {\n escape = true;\n continue;\n }\n if (ch === '\"') {\n inString = false;\n }\n continue;\n }\n\n if (ch === '\"') {\n inString = true;\n continue;\n }\n\n if (ch === '{') {\n depth++;\n } else if (ch === '}') {\n depth--;\n if (depth === 0) {\n const jsonEnd = i;\n // Expect closing bracket after JSON\n const closeBracketIndex = text.indexOf(']', jsonEnd + 1);\n if (closeBracketIndex < 0) {\n return null;\n }\n\n const json = text.substring(jsonStart, jsonEnd + 1).trim();\n return {\n startIndex: start,\n endIndex: closeBracketIndex + 1,\n json: json\n };\n }\n }\n }\n\n return null;\n }\n\n function renderChartsInMessage(message) {\n if (!message || !message._pendingCharts || !message._pendingCharts.length) {\n return;\n }\n\n // Copy and clear pending charts immediately to prevent duplicate renders.\n const charts = [...message._pendingCharts];\n message._pendingCharts = [];\n\n // Defer to requestAnimationFrame so the browser has fully laid out the\n // canvas elements before Chart.js reads their dimensions.\n requestAnimationFrame(() => {\n for (const c of charts) {\n renderChartOnCanvas(c.chartId, c.config);\n }\n });\n }\n\n function renderChartOnCanvas(chartId, config) {\n const canvas = document.getElementById(chartId);\n if (!canvas) {\n return false;\n }\n\n if (typeof Chart === 'undefined') {\n console.warn('Chart.js is not loaded. To render interactive charts, include the Chart.js library on the page (e.g., <script src=\"https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.min.js\"></script>).');\n return false;\n }\n\n // When the canvas is inside a hidden container (e.g., a widget panel with\n // display:none), it has zero dimensions and Chart.js cannot render correctly.\n // Keep the config in __chartConfigs so renderPendingCharts() can retry later\n // once the container becomes visible.\n if (canvas.offsetParent === null) {\n window.__chartConfigs[chartId] = config;\n return false;\n }\n\n try {\n if (canvas._chartInstance) {\n canvas._chartInstance.destroy();\n }\n\n const cfg = typeof config === 'string' ? JSON.parse(config) : config;\n cfg.options ??= {};\n cfg.options.responsive = true;\n cfg.options.maintainAspectRatio = true;\n cfg.options.aspectRatio ??= 4 / 3;\n\n canvas._chartInstance = new Chart(canvas, cfg);\n delete window.__chartConfigs[chartId];\n return true;\n } catch (e) {\n console.error('Error creating chart:', e);\n return false;\n }\n }\n\n // Global function: renders any chart canvases whose configs are in the\n // global __chartConfigs map. Called by pages (e.g., Chat Interactions)\n // that share the marked instance but have their own rendering pipeline.\n window.renderPendingCharts = function () {\n if (typeof Chart === 'undefined') {\n return;\n }\n\n const configs = window.__chartConfigs;\n if (!configs) {\n return;\n }\n\n requestAnimationFrame(() => {\n for (const chartId of Object.keys(configs)) {\n renderChartOnCanvas(chartId, configs[chartId]);\n }\n });\n };\n\n // Parse markdown content via marked (which natively handles [chart:...] markers\n // through the registered extension) and collect pending chart configs for later\n // Chart.js rendering.\n function parseMarkdownContent(content, message) {\n _pendingCharts = [];\n const html = marked.parse(content, { renderer });\n message._pendingCharts = _pendingCharts.length > 0 ? [..._pendingCharts] : [];\n return DOMPurify.sanitize(html, { ADD_TAGS: ['canvas'], ADD_ATTR: ['target'] });\n }\n\n function compactObject(source) {\n if (!source || typeof source !== 'object') {\n return {};\n }\n\n return Object.fromEntries(\n Object.entries(source).filter(([, value]) => value !== undefined)\n );\n }\n\n function resolveIndicatorTemplate(template, assistantLabel) {\n if (!template) {\n return template;\n }\n\n const encodedAssistantLabel = escapeHtmlEntities(assistantLabel || 'Assistant');\n return template.replace(/\\{\\{\\s*assistantLabel\\s*\\}\\}/g, encodedAssistantLabel);\n }\n\n const initialize = (instanceConfig) => {\n const normalizedInstanceConfig = compactObject(instanceConfig);\n const normalizedWidgetConfig = compactObject(normalizedInstanceConfig.widget);\n const config = Object.assign({}, defaultConfig, normalizedInstanceConfig);\n config.widget = Object.assign({}, defaultConfig.widget || {}, normalizedWidgetConfig);\n config.indicatorTemplate = resolveIndicatorTemplate(config.indicatorTemplate, config.assistantLabel);\n const hasWidgetConfig = !!(normalizedWidgetConfig.chatWidgetContainer && normalizedWidgetConfig.chatWidgetStateName);\n const widgetBehavior = window.coreAIChatWidgetBehavior || 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 copiedTitle: config.copiedTitle,\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 copiedMessageIndex: -1,\n copyResetTimeoutId: null,\n activeCopyButton: null,\n };\n },\n computed: {\n lastAssistantIndex() {\n for (var i = this.messages.length - 1; i >= 0; i--) {\n if (this.messages[i].role === 'assistant') {\n return i;\n }\n }\n return -1;\n }\n },\n methods: {\n handleBeforeUnload() {\n this.isNavigatingAway = true;\n },\n handleDragOver(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = true;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.add('ai-chat-drag-over');\n },\n handleDragLeave(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = false;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.remove('ai-chat-drag-over');\n },\n handleDrop(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = false;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.remove('ai-chat-drag-over');\n if (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n this.uploadFiles(Array.from(e.dataTransfer.files));\n }\n },\n triggerFileInput() {\n if (!config.sessionDocumentsEnabled || this.isDocumentOperationPending) return;\n var fileInput = document.getElementById('ai-chat-doc-input');\n if (fileInput) fileInput.click();\n },\n handleFileInputChange(e) {\n var files = e.target.files ? Array.from(e.target.files) : [];\n if (files && files.length > 0) {\n this.uploadFiles(files);\n }\n e.target.value = '';\n },\n queueDocumentOperation(operation) {\n var self = this;\n var previousOperation = this.documentOperationQueue || Promise.resolve();\n var nextOperation = previousOperation\n .catch(function () { })\n .then(async function () {\n self.isDocumentOperationPending = true;\n try {\n return await operation();\n } finally {\n self.isDocumentOperationPending = false;\n }\n });\n\n this.documentOperationQueue = nextOperation.finally(function () {\n if (self.documentOperationQueue === nextOperation) {\n self.documentOperationQueue = null;\n }\n });\n\n return this.documentOperationQueue;\n },\n async uploadFiles(files) {\n if (!config.uploadDocumentUrl) return;\n\n var filesToUpload = Array.isArray(files) ? files.slice() : Array.from(files || []);\n if (filesToUpload.length === 0) return;\n\n return this.queueDocumentOperation(async () => {\n var sessionId = this.getSessionId();\n var profileId = this.getProfileId();\n\n if (!sessionId) {\n try {\n sessionId = await this.ensureSessionForDocuments(profileId);\n } catch (err) {\n console.error('Failed to create a chat session for document upload:', err);\n this.uploadErrors = [{ fileName: '', error: 'Could not create a chat session for the upload.' }];\n this.renderDocumentBar();\n return;\n }\n }\n\n if (!sessionId) {\n console.warn('Cannot upload documents without a session or profile.');\n this.uploadErrors = [{ fileName: '', error: 'Could not create a chat session for the upload.' }];\n this.renderDocumentBar();\n return;\n }\n\n this.isUploading = true;\n this.uploadErrors = [];\n this.renderDocumentBar();\n try {\n var formData = new FormData();\n formData.append('sessionId', sessionId);\n for (var i = 0; i < filesToUpload.length; i++) {\n formData.append('files', filesToUpload[i]);\n }\n\n var response = await fetch(config.uploadDocumentUrl, {\n method: 'POST',\n body: formData\n });\n\n if (!response.ok) {\n var errorText = await response.text();\n var uploadError = this.extractReadableErrorMessage(errorText, 'Upload failed. Please try again.');\n console.error('Upload failed:', errorText);\n this.uploadErrors = [{ fileName: '', error: uploadError }];\n return;\n }\n\n var result = await response.json();\n\n if (result.sessionId && result.sessionId !== this.getSessionId()) {\n this.initializeSession(result.sessionId);\n }\n\n if (Array.isArray(result.documents)) {\n this.documents = result.documents;\n } else if (result.uploaded && result.uploaded.length > 0) {\n this.documents = this.documents.concat(result.uploaded);\n }\n\n if (result.failed && result.failed.length > 0) {\n this.uploadErrors = result.failed;\n }\n } catch (err) {\n console.error('Upload error:', err);\n this.uploadErrors = [{ fileName: '', error: 'Upload failed. Please try again.' }];\n\n if (this.getSessionId()) {\n this.reloadCurrentSession();\n }\n } finally {\n this.isUploading = false;\n this.renderDocumentBar();\n }\n });\n },\n async removeDocument(doc) {\n if (!config.removeDocumentUrl) return;\n\n return this.queueDocumentOperation(async () => {\n try {\n var sessionId = this.getSessionId();\n var response = await fetch(config.removeDocumentUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ itemId: sessionId, documentId: doc.documentId })\n });\n\n if (response.ok) {\n var result = await response.json();\n\n if (Array.isArray(result.documents)) {\n this.documents = result.documents;\n } else {\n var idx = this.documents.indexOf(doc);\n if (idx > -1) {\n this.documents.splice(idx, 1);\n }\n }\n } else {\n var errorText = await response.text();\n var removeError = this.extractReadableErrorMessage(errorText, 'Failed to remove document. Please try again.');\n console.error('Failed to remove document:', response.status, errorText);\n this.uploadErrors = [{ fileName: doc.fileName || '', error: removeError }];\n if (sessionId) {\n this.reloadCurrentSession();\n }\n this.renderDocumentBar();\n }\n } catch (err) {\n console.error('Remove document error:', err);\n this.uploadErrors = [{ fileName: doc.fileName || '', error: 'Failed to remove document. Please try again.' }];\n if (this.getSessionId()) {\n this.reloadCurrentSession();\n }\n this.renderDocumentBar();\n }\n });\n },\n formatFileSize(bytes) {\n if (bytes < 1024) return bytes + ' B';\n if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';\n return (bytes / (1024 * 1024)).toFixed(1) + ' MB';\n },\n renderDocumentBar() {\n if (!this.documentBar) return;\n\n if (!config.sessionDocumentsEnabled) {\n this.documentBar.classList.add('d-none');\n return;\n }\n\n this.documentBar.classList.remove('d-none');\n\n var html = '<div class=\"ai-chat-doc-bar p-2\">';\n html += '<div class=\"d-flex flex-wrap align-items-center gap-1\">';\n\n for (var i = 0; i < this.documents.length; i++) {\n var doc = this.documents[i];\n var name = doc.fileName || 'Document';\n if (name.length > 20) name = name.substring(0, 17) + '...';\n html += '<span class=\"badge bg-secondary bg-opacity-25 text-dark d-inline-flex align-items-center gap-1 px-2 py-1\" style=\"font-size: 0.8rem;\" title=\"' + this.escapeHtml(doc.fileName || '') + '\">';\n html += '<i class=\"fa-solid fa-file-lines\" style=\"font-size: 0.7rem;\"></i> ';\n html += this.escapeHtml(name);\n html += ' <button type=\"button\" class=\"btn-close btn-close-sm ms-1\" style=\"font-size: 0.5rem;\" data-doc-index=\"' + i + '\" aria-label=\"Remove\"' + (this.isDocumentOperationPending ? ' disabled' : '') + '></button>';\n html += '</span>';\n }\n\n for (var m = 0; m < this.uploadErrors.length; m++) {\n var failedItem = this.uploadErrors[m];\n var failedName = failedItem.fileName || 'File';\n var errorMsg = failedItem.error || 'Upload failed';\n if (failedName.length > 15) failedName = failedName.substring(0, 12) + '...';\n html += '<span class=\"badge bg-danger bg-opacity-25 text-danger d-inline-flex align-items-center gap-1 px-2 py-1\" style=\"font-size: 0.8rem;\" title=\"' + this.escapeHtml((failedItem.fileName || '') + ': ' + errorMsg) + '\">';\n html += '<i class=\"fa-solid fa-circle-exclamation\" style=\"font-size: 0.7rem;\"></i> ';\n html += this.escapeHtml(failedName);\n html += ' <button type=\"button\" class=\"btn-close btn-close-sm ms-1\" style=\"font-size: 0.5rem;\" data-error-index=\"' + m + '\" aria-label=\"Dismiss\"></button>';\n html += '</span>';\n }\n\n if (this.isUploading) {\n html += '<span class=\"badge bg-info bg-opacity-25 text-dark d-inline-flex align-items-center gap-1 px-2 py-1\" style=\"font-size: 0.8rem;\">';\n html += '<span class=\"spinner-border spinner-border-sm\" style=\"width: 0.7rem; height: 0.7rem;\"></span> Uploading...';\n html += '</span>';\n }\n\n html += '<button type=\"button\" class=\"btn btn-sm btn-outline-secondary rounded-pill ai-chat-doc-add-btn d-inline-flex align-items-center gap-1\" style=\"font-size: 0.75rem; padding: 0.15rem 0.5rem;\" title=\"Attach documents\"' + (this.isDocumentOperationPending ? ' disabled' : '') + '>';\n html += '<i class=\"fa-solid fa-paperclip\"></i>';\n if (this.documents.length === 0 && !this.isUploading) {\n html += ' <span>Attach files</span>';\n }\n html += '</button>';\n html += '</div>';\n if (config.supportedExtensionsText) {\n html += '<div class=\"small text-muted mt-2\">Supported formats: ' + this.escapeHtml(config.supportedExtensionsText) + '</div>';\n }\n\n html += '</div>';\n\n this.documentBar.replaceChildren(DOMPurify.sanitize(html, { RETURN_DOM_FRAGMENT: true }));\n\n // Bind remove handlers\n var self = this;\n var closeButtons = this.documentBar.querySelectorAll('[data-doc-index]');\n for (var j = 0; j < closeButtons.length; j++) {\n closeButtons[j].addEventListener('click', (function (idx) {\n return function (e) {\n e.preventDefault();\n e.stopPropagation();\n if (self.isDocumentOperationPending) {\n return;\n }\n\n var docToRemove = self.documents[idx];\n if (docToRemove) self.removeDocument(docToRemove);\n };\n })(parseInt(closeButtons[j].getAttribute('data-doc-index'))));\n }\n\n // Bind error dismiss handlers\n var errorCloseButtons = this.documentBar.querySelectorAll('[data-error-index]');\n for (var n = 0; n < errorCloseButtons.length; n++) {\n errorCloseButtons[n].addEventListener('click', (function (idx) {\n return function (e) {\n e.preventDefault();\n e.stopPropagation();\n self.uploadErrors.splice(idx, 1);\n self.renderDocumentBar();\n };\n })(parseInt(errorCloseButtons[n].getAttribute('data-error-index'))));\n }\n\n // Bind add button\n var addBtn = this.documentBar.querySelector('.ai-chat-doc-add-btn');\n if (addBtn) {\n addBtn.addEventListener('click', function (e) {\n e.preventDefault();\n if (self.isDocumentOperationPending) {\n return;\n }\n self.triggerFileInput();\n });\n }\n },\n escapeHtml(text) {\n var div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n },\n extractReadableErrorMessage(errorText, fallbackMessage) {\n if (!errorText || typeof errorText !== 'string') {\n return fallbackMessage;\n }\n\n var trimmed = errorText.trim();\n if (!trimmed) {\n return fallbackMessage;\n }\n\n if (trimmed.startsWith('{') || trimmed.startsWith('[')) {\n try {\n var parsed = JSON.parse(trimmed);\n var message = parsed?.error || parsed?.message || parsed?.title || parsed?.detail;\n return typeof message === 'string' && message.trim()\n ? message.trim()\n : fallbackMessage;\n } catch (err) {\n return fallbackMessage;\n }\n }\n\n if (/<[^>]+>/.test(trimmed)) {\n return fallbackMessage;\n }\n\n return trimmed;\n },\n normalizeAssistantAppearance(appearance) {\n if (!appearance) {\n return null;\n }\n\n var label = typeof appearance.label === 'string' ? appearance.label.trim() : '';\n var icon = typeof appearance.icon === 'string' ? appearance.icon.trim() : '';\n var cssClass = typeof appearance.cssClass === 'string' ? appearance.cssClass.trim() : '';\n var disableStreamingAnimation = !!appearance.disableStreamingAnimation;\n\n if (!label && !icon && !cssClass && !disableStreamingAnimation) {\n return null;\n }\n\n return {\n label: label,\n icon: icon,\n cssClass: cssClass,\n disableStreamingAnimation: disableStreamingAnimation,\n };\n },\n getAssistantLabel(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return appearance && appearance.label ? appearance.label : this.assistantLabel;\n },\n getAssistantRoleClasses(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n var classes = ['ai-chat-msg-role'];\n\n if (appearance && appearance.cssClass) {\n classes.push(appearance.cssClass);\n } else {\n classes.push('ai-chat-msg-role-assistant');\n }\n\n return classes;\n },\n getAssistantIconClasses(message, index) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return [this.shouldAnimateAssistantIcon(message, index) ? 'ai-streaming-icon' : 'ai-bot-icon', appearance && appearance.cssClass ? appearance.cssClass : ''];\n },\n getAssistantIcon(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return appearance && appearance.icon ? appearance.icon : 'fa fa-robot';\n },\n shouldAnimateAssistantIcon(message, index) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return !!message &&\n message.isStreaming &&\n index === this.lastAssistantIndex &&\n !(appearance && appearance.disableStreamingAnimation);\n },\n async startConnection() {\n this.connection = new signalR.HubConnectionBuilder()\n .withUrl(config.signalRHubUrl)\n .withAutomaticReconnect()\n .build();\n\n // Allow long-running operations (e.g., multi-step MCP tool calls)\n // without the client disconnecting prematurely.\n this.connection.serverTimeoutInMilliseconds = 600000;\n this.connection.keepAliveIntervalInMilliseconds = 15000;\n\n this.connection.on(\"LoadSession\", (data) => {\n this.initializeSession(data.sessionId, true);\n this.messages = [];\n this.documents = data.documents || [];\n this.uploadErrors = [];\n\n (data.messages ?? []).forEach(msg => {\n this.addMessage(msg);\n\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n });\n });\n\n // Update feedback icons in the DOM after all messages have rendered.\n this.$nextTick(() => {\n this.refreshAllFeedbackIcons();\n });\n\n // When the session is new (no messages) and an initial prompt is configured,\n // automatically send it as the first user message to trigger an AI response.\n if (this.messages.length === 0 && config.initialPrompt) {\n this.prompt = config.initialPrompt;\n this.sendMessage();\n }\n });\n\n this.connection.on(\"ReceiveError\", (error) => {\n console.error(\"SignalR Error: \", error);\n\n if (this.isRecording) {\n this.stopRecording();\n }\n\n if (widgetBehavior && typeof widgetBehavior.handleReceiveError === 'function') {\n widgetBehavior.handleReceiveError(this, error, config);\n }\n });\n\n this.connection.on(\"MessageRated\", (messageId, userRating) => {\n var msg = this.messages.find(m => m.id === messageId);\n if (msg) {\n msg.userRating = userRating;\n }\n });\n\n this.connection.on(\"ReceiveTranscript\", (sessionId, text, isFinal) => {\n if (this.isConversationMode) {\n if (!isFinal && text) {\n this._conversationPartialTranscript = text;\n var escaped = text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\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, '&').replace(/</g, '<').replace(/>/g, '>');\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = '<p>' + escaped + '</p>';\n this._conversationPartialMessage.isPartial = false;\n this._conversationPartialMessage = null;\n } else {\n this.addMessage({\n role: 'user',\n content: text\n });\n }\n this.scrollToBottom();\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantToken\", (sessionId, messageId, token, responseId, references, appearance) => {\n if (!this._conversationAssistantMessage) {\n this.stopAudio();\n this.hideTypingIndicator();\n\n // Ensure no stale streaming indicators remain from prior messages.\n for (var j = 0; j < this.messages.length; j++) {\n if (this.messages[j].isStreaming) {\n this.messages[j].isStreaming = false;\n }\n }\n\n var msgIndex = this.messages.length;\n var newMessage = {\n id: messageId,\n role: \"assistant\",\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n userRating: null,\n appearance: this.normalizeAssistantAppearance(appearance),\n references: {},\n };\n this.messages.push(newMessage);\n this._conversationAssistantMessage = { index: msgIndex, content: '' };\n }\n\n this._conversationAssistantMessage.content += token;\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n if (!msg.appearance) {\n msg.appearance = this.normalizeAssistantAppearance(appearance);\n }\n msg.rawContent = this._conversationAssistantMessage.content;\n msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));\n updateMessagePresentation(msg, msg.references);\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n this.scrollToBottom();\n });\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantComplete\", (sessionId, messageId, references) => {\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));\n updateMessagePresentation(msg, msg.references);\n }\n this._conversationAssistantMessage = null;\n }\n });\n\n this.connection.on(\"ReceiveAudioChunk\", (sessionId, base64Audio, contentType) => {\n if (base64Audio) {\n const binaryString = atob(base64Audio);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n this.audioChunks.push(bytes);\n }\n });\n\n this.connection.on(\"ReceiveAudioComplete\", (sessionId) => {\n this.playCollectedAudio();\n });\n\n this.connection.on(\"ReceiveNotification\", (notification) => {\n this.receiveNotification(notification);\n });\n\n this.connection.on(\"UpdateNotification\", (notification) => {\n this.updateNotification(notification);\n });\n\n this.connection.on(\"RemoveNotification\", (notificationType) => {\n this.removeNotification(notificationType);\n });\n\n this.connection.onreconnecting(() => {\n console.warn(\"SignalR: reconnecting...\");\n });\n\n this.connection.onreconnected(() => {\n console.info(\"SignalR: reconnected.\");\n\n if (this.isSessionStarted) {\n this.reloadCurrentSession();\n } else if (config.autoCreateSession) {\n this.startNewSession();\n }\n });\n\n this.connection.onclose((error) => {\n if (this.isNavigatingAway) {\n return;\n }\n\n if (error) {\n console.warn(\"SignalR connection closed with error:\", error.message || error);\n }\n });\n\n try {\n await this.connection.start();\n } catch (err) {\n console.error(\"SignalR Connection Error: \", err);\n }\n },\n addMessageInternal(message) {\n if (message.role === 'assistant') {\n message.appearance = this.normalizeAssistantAppearance(message.appearance);\n }\n\n if (message.content && !message.htmlContent) {\n message.htmlContent = parseMarkdownContent(message.content, message);\n }\n this.fireEvent(new CustomEvent(\"addingCoreAIPromotMessage\", { detail: { message: message } }));\n this.messages.push(message);\n\n this.$nextTick(() => {\n this.fireEvent(new CustomEvent(\"addedCoreAIPromotMessage\", { detail: { message: message } }));\n });\n },\n addMessage(message) {\n\n // Ensure userRating is always defined for Vue reactivity.\n if (message.userRating === undefined) {\n message.userRating = null;\n }\n\n if (message.content) {\n message.rawContent = message.rawContent ?? message.content;\n updateMessagePresentation(message, message.references);\n }\n\n this.addMessageInternal(message);\n this.hidePlaceholder();\n\n this.$nextTick(() => {\n // Render any pending charts once the DOM is updated\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n addMessages(messages) {\n\n for (let i = 0; i < messages.length; i++) {\n this.addMessageInternal(messages[i]);\n }\n\n this.hidePlaceholder();\n this.$nextTick(() => {\n this.scrollToBottom();\n });\n },\n hidePlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.add('d-none');\n }\n this.isPlaceholderVisible = false;\n },\n showPlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.remove('d-none');\n }\n this.isPlaceholderVisible = true;\n },\n isOrchestratorAvailable() {\n return config.isOrchestratorAvailable !== false;\n },\n applyOrchestratorAvailability() {\n if (this.isOrchestratorAvailable()) {\n return true;\n }\n\n const unavailableMessage = config.orchestratorUnavailableMessage || \"This orchestrator is not currently available.\";\n\n if (this.inputElement) {\n this.inputElement.disabled = true;\n this.inputElement.value = '';\n this.inputElement.placeholder = unavailableMessage;\n }\n\n if (this.buttonElement) {\n this.buttonElement.disabled = true;\n }\n\n if (this.micButtonElement) {\n this.micButtonElement.disabled = true;\n this.micButtonElement.style.display = 'none';\n }\n\n if (this.conversationButtonElement) {\n this.conversationButtonElement.disabled = true;\n this.conversationButtonElement.style.display = 'none';\n }\n\n return false;\n },\n fireEvent(event) {\n document.dispatchEvent(event);\n },\n isIndicator(message) {\n return message.role === 'indicator';\n },\n sendMessage() {\n if (!this.applyOrchestratorAvailability()) {\n return;\n }\n\n let trimmedPrompt = this.prompt.trim();\n\n if (!trimmedPrompt) {\n return;\n }\n\n // Stop any active recording before sending.\n if (this.isRecording) {\n this.stopRecording();\n }\n\n // Prevent stale ReceiveTranscript events from repopulating the prompt.\n this._audioInputSent = true;\n\n // In single-response mode, clear all previous messages.\n if (this.singleResponseMode) {\n this.messages.splice(0, this.messages.length);\n }\n\n this.addMessage({\n role: 'user',\n content: trimmedPrompt\n });\n\n this.streamMessage(this.getProfileId(), trimmedPrompt, null);\n this.inputElement.value = '';\n this.prompt = '';\n },\n startRecording() {\n if (this.isRecording || !this.connection) {\n return;\n }\n\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this.preRecordingPrompt = this.prompt;\n this._audioInputSent = false;\n\n var subject = new signalR.Subject();\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var pendingChunk = Promise.resolve();\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n subject.next(base64);\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => subject.complete());\n });\n\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"SendAudioStream\", profileId, sessionId, subject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n this.updateMicButton();\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n });\n },\n stopRecording() {\n if (!this.isRecording || !this.mediaRecorder) {\n return;\n }\n\n this.mediaRecorder.stop();\n this.isRecording = false;\n this.updateMicButton();\n },\n toggleRecording() {\n if (this.isRecording) {\n this.stopRecording();\n } else {\n this.startRecording();\n }\n },\n updateMicButton() {\n if (!this.micButton) {\n return;\n }\n\n if (this.isRecording) {\n this.micButton.classList.add('stt-recording');\n this.micButton.innerHTML = '<i class=\"fa-solid fa-stop\"></i>';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '<i class=\"fa-solid fa-microphone\"></i>';\n }\n },\n streamMessage(profileId, trimmedPrompt, sessionProfileId) {\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n\n this.streamingStarted();\n this.showTypingIndicator();\n this.autoScroll = true;\n\n var content = '';\n var references = {};\n var lastResponseId = null;\n\n // Get the index after showing typing indicator.\n var messageIndex = this.messages.length;\n var currentSessionId = this.getSessionId();\n\n this.stream = this.connection.stream(\"SendMessage\", profileId, trimmedPrompt, currentSessionId, sessionProfileId)\n .subscribe({\n next: (chunk) => {\n let message = this.messages[messageIndex];\n\n if (!message) {\n\n if (chunk.sessionId && !currentSessionId) {\n this.initializeSession(chunk.sessionId);\n }\n\n this.hideTypingIndicator();\n // Re-assign the index after hiding the typing indicator.\n messageIndex = this.messages.length;\n let newMessage = {\n id: chunk.messageId,\n role: \"assistant\",\n title: chunk.title,\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n userRating: null,\n };\n\n this.messages.push(newMessage);\n\n message = newMessage;\n }\n\n if (chunk.title && (!message.title || message.title !== chunk.title)) {\n message.title = chunk.title;\n }\n\n if (chunk.references && typeof chunk.references === \"object\" && Object.keys(chunk.references).length) {\n\n for (const [key, value] of Object.entries(chunk.references)) {\n references[key] = normalizeReference(value) ?? {};\n }\n }\n\n if (chunk.content) {\n\n // When the responseId changes (e.g., after an internal tool call),\n // insert a line break to visually separate response segments.\n if (chunk.responseId && lastResponseId && chunk.responseId !== lastResponseId) {\n content += '\\n\\n';\n }\n\n if (chunk.responseId) {\n lastResponseId = chunk.responseId;\n }\n\n content += chunk.content;\n }\n\n // Update the existing message\n message.rawContent = content;\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n complete: () => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n if (!msg || !msg.content) {\n // No content received at all.\n this.hideTypingIndicator();\n }\n\n // Trigger text-to-speech only in conversation mode.\n if (this.isConversationMode && this.textToSpeechEnabled && msg && msg.content) {\n this.synthesizeSpeech(msg.content);\n }\n\n this.stream?.dispose();\n this.stream = null;\n },\n error: (err) => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n this.hideTypingIndicator();\n\n if (!this.isNavigatingAway) {\n this.addMessage(this.getServiceDownMessage());\n }\n\n this.stream?.dispose();\n this.stream = null;\n\n console.error(\"Stream error:\", err);\n }\n });\n },\n getServiceDownMessage() {\n let newMessage = {\n role: \"assistant\",\n content: \"Our service is currently unavailable. Please try again later. We apologize for the inconvenience.\",\n htmlContent: \"\",\n };\n\n return newMessage;\n },\n processReferences(references, messageIndex) {\n references = normalizeReferences(references);\n\n if (Object.keys(references).length) {\n\n let message = this.messages[messageIndex];\n message.rawContent = message.rawContent ?? message.content ?? '';\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n }\n },\n streamingStarted() {\n var stopIcon = this.buttonElement.getAttribute('data-stop-icon');\n\n if (stopIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(stopIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n if (this.inputElement) {\n this.inputElement.setAttribute('disabled', 'disabled');\n }\n },\n streamingFinished() {\n var startIcon = this.buttonElement.getAttribute('data-start-icon');\n\n if (startIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(startIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n if (this.inputElement) {\n this.inputElement.removeAttribute('disabled');\n this.inputElement.focus();\n }\n\n // Directly manipulate the DOM to stop all streaming animations.\n if (this.chatContainer) {\n var icons = this.chatContainer.querySelectorAll('.ai-streaming-icon');\n for (var i = 0; i < icons.length; i++) {\n icons[i].classList.remove('ai-streaming-icon');\n icons[i].classList.add('ai-bot-icon');\n }\n }\n\n // Also update Vue data for consistency.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n },\n handleExternalTtsStop(e) {\n if (e?.detail?.sourceId === this.ttsInstanceId) {\n return;\n }\n\n this.stopAudio(false);\n },\n updateTtsPlaybackButtons() {\n if (!this.chatContainer) {\n return;\n }\n\n var buttons = this.chatContainer.querySelectorAll('[data-tts-message-index]');\n\n buttons.forEach(button => {\n var buttonIndex = Number(button.getAttribute('data-tts-message-index'));\n var isPlaying = buttonIndex === this.ttsPlayingMessageIndex;\n\n button.classList.toggle('tts-playing', isPlaying);\n button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');\n });\n },\n updateCopyButtons() {\n if (!this.chatContainer) {\n return;\n }\n\n var buttons = this.chatContainer.querySelectorAll('[data-copy-message-index]');\n\n buttons.forEach(button => {\n var buttonIndex = Number(button.getAttribute('data-copy-message-index'));\n var isCopied = buttonIndex === this.copiedMessageIndex;\n var iconHtml = isCopied\n ? '<i class=\"fa-solid fa-check\"></i>'\n : '<i class=\"fa-solid fa-copy\"></i>';\n\n button.classList.toggle('text-success', isCopied);\n button.classList.toggle('text-secondary', !isCopied);\n button.setAttribute('title', isCopied ? this.copiedTitle : this.copyTitle);\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\n });\n },\n setCopyButtonState(button, isCopied) {\n if (!button) {\n return;\n }\n\n var iconHtml = isCopied\n ? '<i class=\"fa-solid fa-check\"></i>'\n : '<i class=\"fa-solid fa-copy\"></i>';\n\n button.classList.toggle('text-success', isCopied);\n button.classList.toggle('text-secondary', !isCopied);\n button.setAttribute('title', isCopied ? this.copiedTitle : this.copyTitle);\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\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 const initialMessages = Array.isArray(config.messages) ? config.messages : [];\n\n for (let i = 0; i < initialMessages.length; i++) {\n this.addMessage(initialMessages[i]);\n }\n\n // Update feedback icons in the DOM after initial messages have rendered.\n this.$nextTick(() => {\n this.refreshAllFeedbackIcons();\n });\n\n // Delegate click for code block copy buttons.\n if (this.chatContainer) {\n this.chatContainer.addEventListener('click', (e) => {\n var btn = e.target.closest('.ai-code-copy-btn');\n if (!btn) {\n return;\n }\n\n var block = btn.closest('.ai-code-block') || btn.closest('pre');\n if (!block) {\n return;\n }\n\n var codeEl = block.querySelector('code');\n if (codeEl) {\n navigator.clipboard.writeText(codeEl.textContent);\n var copiedText = config.codeCopiedText || 'Copied!';\n btn.innerHTML = '<i class=\"fa-solid fa-check\"></i> ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '<i class=\"fa-regular fa-copy\"></i>';\n }, 2000);\n }\n });\n }\n\n // Initialize speech-to-text microphone button.\n if (this.speechToTextEnabled && config.micButtonElementSelector) {\n this.micButton = document.querySelector(config.micButtonElementSelector);\n if (this.micButton) {\n this.micButton.style.display = '';\n this.micButton.addEventListener('click', () => {\n this.toggleRecording();\n });\n }\n }\n\n // Initialize conversation mode button.\n if (this.conversationModeEnabled && config.conversationButtonElementSelector) {\n this.conversationButton = document.querySelector(config.conversationButtonElementSelector);\n if (this.conversationButton) {\n this.conversationButton.addEventListener('click', () => {\n this.toggleConversationMode();\n });\n }\n }\n\n return true;\n },\n loadSession(sessionId) {\n this.connection.invoke(\"LoadSession\", sessionId).catch(err => console.error(err));\n },\n reloadCurrentSession() {\n\n var sessionId = this.getSessionId();\n if (sessionId) {\n this.loadSession(sessionId);\n }\n },\n initializeSession(sessionId, force) {\n if (this.isSessionStarted && !force) {\n if (sessionId && this.getSessionId() === sessionId) {\n this.resolvePendingSessionRequest(sessionId);\n }\n\n return\n }\n this.fireEvent(new CustomEvent(\"initializingSessionCoreAIChat\", { 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 clearCopiedMessageState() {\n if (this.copyResetTimeoutId) {\n window.clearTimeout(this.copyResetTimeoutId);\n this.copyResetTimeoutId = null;\n }\n\n if (this.activeCopyButton) {\n this.setCopyButtonState(this.activeCopyButton, false);\n this.activeCopyButton = null;\n }\n\n this.copiedMessageIndex = -1;\n },\n copyResponse(message, index, event) {\n const text = message && typeof message === 'object'\n ? message.copyContent ?? message.content ?? ''\n : message ?? '';\n const button = event?.currentTarget || event?.target?.closest?.('[data-copy-message-index]') || null;\n\n navigator.clipboard.writeText(text)\n .then(() => {\n this.clearCopiedMessageState();\n this.copiedMessageIndex = typeof index === 'number' ? index : -1;\n this.activeCopyButton = button;\n\n if (button) {\n this.setCopyButtonState(button, true);\n } else {\n this.$nextTick(() => this.updateCopyButtons());\n }\n\n this.copyResetTimeoutId = window.setTimeout(() => {\n this.clearCopiedMessageState();\n this.$nextTick(() => this.updateCopyButtons());\n }, Number(config.copyResetDelayMs) || 2000);\n })\n .catch(err => console.error('Failed to copy response:', err));\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 copiedMessageIndex() {\n this.$nextTick(() => this.updateCopyButtons());\n },\n isConversationMode(active) {\n // Hide/show mic button.\n if (this.micButton) {\n this.micButton.style.display = active ? 'none' : (this.speechToTextEnabled ? '' : 'none');\n }\n\n // Hide/show send button.\n if (this.buttonElement) {\n this.buttonElement.style.display = active ? 'none' : '';\n }\n\n // Disable/enable textarea.\n if (this.inputElement) {\n this.inputElement.disabled = active;\n if (active) {\n this.inputElement.placeholder = '';\n }\n }\n }\n },\n mounted() {\n (async () => {\n await this.startConnection();\n const isInitialized = this.initializeApp();\n if (isInitialized && hasWidgetConfig && widgetBehavior && typeof widgetBehavior.onMounted === 'function') {\n widgetBehavior.onMounted(this, config);\n }\n\n this.$nextTick(() => {\n this.updateCopyButtons();\n refreshFontAwesomeIcons(this.$el);\n this.fontAwesomeObserver = observeFontAwesomeIcons(this.$el);\n });\n })();\n\n window.addEventListener('beforeunload', this.handleBeforeUnload);\n window.addEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n },\n beforeUnmount() {\n window.removeEventListener('beforeunload', this.handleBeforeUnload);\n window.removeEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n\n if (this.fontAwesomeObserver) {\n this.fontAwesomeObserver.disconnect();\n this.fontAwesomeObserver = null;\n }\n\n this.clearCopiedMessageState();\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 const autoInitializeSelector = '[data-coreai-chat-config],[data-coreai-chat-app-element-selector]';\n\n function getAttributeValue(element, attributeName) {\n const value = element.getAttribute(attributeName);\n return value === null || value === '' ? null : value;\n }\n\n function parseBooleanAttributeValue(value) {\n if (value === null || value === undefined) {\n return null;\n }\n\n if (typeof value === 'boolean') {\n return value;\n }\n\n const normalized = String(value).trim().toLowerCase();\n if (normalized === 'true') {\n return true;\n }\n\n if (normalized === 'false') {\n return false;\n }\n\n return null;\n }\n\n function parseJsonAttribute(element, attributeName, description) {\n const rawValue = getAttributeValue(element, attributeName);\n if (!rawValue) {\n return null;\n }\n\n try {\n return JSON.parse(rawValue);\n } catch (error) {\n console.error('Failed to parse ' + description + ' JSON.', error);\n return null;\n }\n }\n\n function buildConfigFromDataAttributes(element, options) {\n const settings = options || {};\n\n if (element.hasAttribute('data-coreai-chat-widget-container-selector') && settings.allowWidgetHost !== true) {\n return null;\n }\n\n const appElementSelector = getAttributeValue(element, 'data-coreai-chat-app-element-selector');\n if (!appElementSelector) {\n return null;\n }\n\n const config = {\n signalRHubUrl: getAttributeValue(element, 'data-coreai-chat-signalr-hub-url'),\n appElementSelector: appElementSelector,\n chatContainerElementSelector: getAttributeValue(element, 'data-coreai-chat-container-element-selector'),\n inputElementSelector: getAttributeValue(element, 'data-coreai-chat-input-element-selector'),\n sendButtonElementSelector: getAttributeValue(element, 'data-coreai-chat-send-button-element-selector'),\n placeholderElementSelector: getAttributeValue(element, 'data-coreai-chat-placeholder-element-selector'),\n messages: parseJsonAttribute(element, 'data-coreai-chat-messages', 'CoreAI chat messages') ?? undefined,\n chatMode: getAttributeValue(element, 'data-coreai-chat-mode'),\n micButtonElementSelector: getAttributeValue(element, 'data-coreai-chat-mic-button-element-selector'),\n conversationButtonElementSelector: getAttributeValue(element, 'data-coreai-chat-conversation-button-element-selector'),\n ttsVoiceName: getAttributeValue(element, 'data-coreai-chat-tts-voice-name'),\n documentBarSelector: getAttributeValue(element, 'data-coreai-chat-document-bar-selector'),\n uploadDocumentUrl: getAttributeValue(element, 'data-coreai-chat-upload-document-url'),\n removeDocumentUrl: getAttributeValue(element, 'data-coreai-chat-remove-document-url'),\n allowedExtensions: getAttributeValue(element, 'data-coreai-chat-allowed-extensions'),\n supportedExtensionsText: getAttributeValue(element, 'data-coreai-chat-supported-extensions-text'),\n existingDocuments: parseJsonAttribute(element, 'data-coreai-chat-existing-documents', 'CoreAI chat existing documents') ?? undefined,\n initialPrompt: getAttributeValue(element, 'data-coreai-chat-initial-prompt'),\n userLabel: getAttributeValue(element, 'data-coreai-chat-user-label'),\n assistantLabel: getAttributeValue(element, 'data-coreai-chat-assistant-label'),\n copyTitle: getAttributeValue(element, 'data-coreai-chat-copy-title'),\n copiedTitle: getAttributeValue(element, 'data-coreai-chat-copied-title'),\n };\n\n const booleanAttributes = {\n metricsEnabled: 'data-coreai-chat-metrics-enabled',\n textToSpeechEnabled: 'data-coreai-chat-text-to-speech-enabled',\n sessionDocumentsEnabled: 'data-coreai-chat-session-documents-enabled',\n autoCreateSession: 'data-coreai-chat-auto-create-session',\n singleResponseMode: 'data-coreai-chat-single-response-mode',\n };\n\n Object.keys(booleanAttributes).forEach(key => {\n const parsed = parseBooleanAttributeValue(getAttributeValue(element, booleanAttributes[key]));\n if (parsed !== null) {\n config[key] = parsed;\n }\n });\n\n return compactObject(config);\n }\n\n function buildConfigFromElement(element, options) {\n const jsonConfig = parseJsonAttribute(element, 'data-coreai-chat-config', 'CoreAI chat config');\n const attributeConfig = buildConfigFromDataAttributes(element, options);\n\n if (!jsonConfig && !attributeConfig) {\n return null;\n }\n\n return Object.assign({}, jsonConfig || {}, attributeConfig || {});\n }\n\n function initializeFromElement(element) {\n if (!element || element.dataset.coreAiChatInitialized === 'true') {\n return element ? element.__coreAIChatApp || null : null;\n }\n\n const config = buildConfigFromElement(element);\n if (!config) {\n return null;\n }\n\n const app = initialize(config);\n if (!app) {\n return null;\n }\n\n element.dataset.coreAiChatInitialized = 'true';\n element.__coreAIChatApp = app;\n\n return app;\n }\n\n function scanForAutoInitialization(root) {\n if (!root || typeof root.querySelectorAll !== 'function') {\n return;\n }\n\n if (typeof root.matches === 'function' && root.matches(autoInitializeSelector)) {\n initializeFromElement(root);\n }\n\n root.querySelectorAll(autoInitializeSelector).forEach(initializeFromElement);\n }\n\n function startAutoInitialization() {\n scanForAutoInitialization(document);\n\n if (typeof MutationObserver === 'undefined') {\n return;\n }\n\n const observer = new MutationObserver(mutations => {\n mutations.forEach(mutation => {\n mutation.addedNodes.forEach(node => {\n if (node && node.nodeType === 1) {\n scanForAutoInitialization(node);\n }\n });\n });\n });\n\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n });\n }\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', startAutoInitialization, { once: true });\n } else {\n startAutoInitialization();\n }\n\n return {\n initialize: initialize,\n initializeFromElement: initializeFromElement,\n buildConfigFromElement: buildConfigFromElement,\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"]}
|