@crestapps/ai-chat-ui 1.0.0-preview.19 → 1.0.0-preview.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["chat-interaction.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","chatInteractionManager","defaultConfig","generatedImageAltText","generatedImageMaxWidth","downloadImageTitle","downloadChartTitle","downloadChartButtonText","codeCopiedText","assistantLabel","messageTemplate","indicatorTemplate","untitledText","clearHistoryTitle","clearHistoryMessage","clearHistoryOkText","clearHistoryCancelText","sanitizeUrl","url","trimmed","trim","escapeHtmlEntities","text","span","document","createElement","textContent","innerHTML","normalizeReference","reference","_ref","_normalized$index","_ref2","_normalized$text","_ref3","_normalized$title","_ref4","_normalized$link","_ref5","_normalized$reference","normalized","assign","index","Index","Text","title","Title","link","Link","referenceType","ReferenceType","isDownloadCitationReference","toLowerCase","normalizeReferences","references","_i","_Object$entries","entries","_normalizeReference","_Object$entries$_i","key","getCitationLabel","updateMessagePresentation","message","messageReferences","rawContent","content","citationDisplay","processedContent","keys","citations","citedRefs","filter","_ref6","includes","sort","_ref8","_ref9","b","_step","displayIndex","_iterator","_step$value","placeholder","concat","replaceAll","referenceKey","label","isDownload","err","_i2","_citations","citation","map","_ref10","buildCitationDisplay","displayContent","citationReferences","copyContent","_step2","_iterator2","_step3","_iterator3","trimEnd","buildCopyContent","htmlContent","parseMarkdownContent","renderer","marked","Renderer","data","href","code","lang","highlighted","hljs","getLanguage","highlight","language","_","highlightAuto","langDisplay","image","src","alt","maxWidth","chartCounter","_pendingCharts","renderChartsInMessage","charts","requestAnimationFrame","_step4","_iterator4","canvas","getElementById","chartId","Chart","offsetParent","_cfg$options","_cfg$options2","_cfg$options2$aspectR","_chartInstance","destroy","cfg","config","JSON","parse","options","responsive","maintainAspectRatio","aspectRatio","console","error","__chartConfigs","warn","html","DOMPurify","sanitize","ADD_TAGS","ADD_ATTR","use","extensions","level","start","idx","undefined","tokenizer","extracted","token","jsonStart","depth","inString","escape","ch","jsonEnd","closeBracketIndex","startIndex","endIndex","json","substring","tryExtractChartMarker","type","raw","initialize","instanceConfig","signalRHubUrl","appElementSelector","chatContainerElementSelector","inputElementSelector","sendButtonElementSelector","Vue","createApp","inputElement","buttonElement","chatContainer","isInteractionStarted","isPlaceholderVisible","isStreaming","isNavigatingAway","autoScroll","stream","messages","prompt","initialFieldValues","Map","settingsDirty","saveSettingsTimeout","saveIndicatorTimeout","isRecording","mediaRecorder","preRecordingPrompt","micButton","speechToTextEnabled","chatMode","textToSpeechEnabled","ttsVoiceName","audioChunks","audioPlayQueue","isPlayingAudio","currentAudioElement","currentAudioUrl","ttsPlayingMessageIndex","ttsAudioCache","ttsInstanceId","Math","random","conversationModeEnabled","conversationButton","isConversationMode","notifications","notificationDismissTimers","computed","lastAssistantIndex","role","methods","handleBeforeUnload","startConnection","_this","_callee","_t","_context","connection","signalR","HubConnectionBuilder","withUrl","withAutomaticReconnect","build","serverTimeoutInMilliseconds","keepAliveIntervalInMilliseconds","on","_data$messages","initializeInteraction","itemId","titleInput","querySelector","forEach","msg","addMessage","$nextTick","historyItem","showSaveIndicator","stopRecording","isFinal","_conversationPartialTranscript","replace","_conversationPartialMessage","hidePlaceholder","isPartial","scrollToBottom","_audioInputSent","dispatchEvent","Event","stopAudio","_conversationAssistantMessage","oldMsg","escaped","messageId","responseId","appearance","hideTypingIndicator","j","msgIndex","newMessage","id","normalizeAssistantAppearance","base64Audio","contentType","binaryString","atob","bytes","Uint8Array","charCodeAt","playCollectedAudio","showPlaceholder","clearHistoryBtn","classList","add","notification","receiveNotification","updateNotification","notificationType","removeNotification","onreconnecting","onreconnected","info","reloadCurrentInteraction","onclose","addMessageInternal","_this2","fireEvent","CustomEvent","detail","_message$rawContent","_this3","remove","event","icon","cssClass","disableStreamingAnimation","getAssistantLabel","getAssistantRoleClasses","classes","getAssistantIconClasses","shouldAnimateAssistantIcon","getAssistantIcon","isIndicator","sendMessage","_this4","_callee2","trimmedPrompt","_context2","flushPendingSave","streamMessage","_this5","dispose","streamingStarted","showTypingIndicator","lastResponseId","messageIndex","currentItemId","getItemId","subscribe","chunk","sessionId","setItemId","_i3","_Object$entries2","_normalizeReference2","_Object$entries2$_i","complete","_this5$stream","processReferences","streamingFinished","synthesizeSpeech","_this5$stream2","getServiceDownMessage","_this6","_ref11","_message$rawContent2","stopIcon","getAttribute","replaceChildren","RETURN_DOM_FRAGMENT","startIcon","icons","querySelectorAll","debouncedSaveSettings","handleExternalTtsStop","_e$detail","sourceId","updateTtsPlaybackButtons","_this7","button","isPlaying","Number","iconHtml","toggle","setAttribute","cacheIndex","_this8","_ttsCacheIndex","invoke","toggleMessageTts","_this9","playAudioBlob","_this0","_step5","totalLength","reduce","sum","combined","offset","_iterator5","set","blob","Blob","_this1","URL","createObjectURL","audio","Audio","addEventListener","revokeObjectURL","playNextInQueue","play","_this10","nextBlob","shift","conversationModeOnAudioEnded","_this11","pause","currentTime","toggleConversationMode","stopConversationMode","startConversationMode","_this12","updateConversationButton","navigator","mediaDevices","getUserMedia","echoCancellation","noiseSuppression","autoGainControl","mimeType","MediaRecorder","isTypeSupported","audioBitsPerSecond","_conversationSubject","Subject","_conversationStream","AudioCtx","AudioContext","webkitAudioContext","_conversationAudioCtx","_conversationAnalyser","createAnalyser","fftSize","createMediaStreamSource","connect","pendingChunk","analyser","size","freqData","frequencyBinCount","getByteFrequencyData","k","_callee3","uint8Array","base64","_context3","arrayBuffer","str","byte","String","fromCharCode","btoa","getTracks","track","stop","documentElement","send","close","dismissible","autoDismissMs","endHtml","blur","startHtml","conversationModeSendPrompt","originalLength","_this13","setTimeout","scrollTop","scrollHeight","clientHeight","handleUserInput","target","getSaveIndicatorElement","saveIndicatorElementSelector","className","_this14","indicator","clearTimeout","clearPendingSettingsSave","getFieldLabel","input","_input$closest","closest","dataset","setting","getValidationFeedbackElement","feedback","nextElementSibling","contains","insertAdjacentElement","clearSettingValidationError","removeAttribute","setSettingValidationError","getSettingValidationMessage","disabled","number","fieldLabel","isNaN","min","max","validateSettingInput","validateSettings","_this15","isValid","getSettingInputs","queueSettingsSave","explicitInputs","getSelectedGroupValues","groupName","fallbackSelector","explicitSelections","values","checkbox","baseName","hiddenInput","getPromptTemplateSelections","promptTemplates","card","templateIdInput","promptParametersInput","templateId","promptParameters","clearNotificationDismiss","findIndex","splice","scheduleNotificationDismiss","_this16","timerId","dismissNotification","handleNotificationAction","actionName","resetInteraction","initializeApp","_this17","placeholderElementSelector","loadInteraction","atBottom","shiftKey","click","lastMsg","pop","chatInteractionItems","getElementsByClassName","preventDefault","btn","block","codeEl","clipboard","writeText","copiedText","matches","clearHistory","micButtonElementSelector","style","display","toggleRecording","conversationButtonElementSelector","self","clearHistoryConfirmed","confirmDialog","confirm","okText","cancelText","callback","confirmed","_this18","saveSettings","getSelectedToolNames","getSelectedMcpConnectionIds","getSelectedA2AConnectionIds","getSelectedAgentNames","_this19","settings","match","checked","parseFloat","toolNames","mcpConnectionIds","a2aConnectionIds","agentNames","promptTemplateIds","template","force","copyResponse","_ref13","_message$copyContent","startRecording","_this20","subject","_callee4","_context4","updateMicButton","watch","active","mounted","_this21","_callee5","_context5","beforeUnmount","removeEventListener","mount","chatInteractionDocumentManager","managerStateKey","normalizeDocumentInfo","documentId","DocumentId","fileName","FileName","fileSize","FileSize","formatFileSize","toFixed","getDocumentKey","isDuplicateFile","file","knownKeys","has","fileInput","documentsList","status","progressContainer","progressBar","uploadQueue","previousState","container","interactionDocuments","existingDocuments","element","chatDocumentId","chatDocumentName","chatDocumentSize","uploadItems","isUploadingDocuments","onFileInputChange","_x","_uploadDocuments","uploadDocuments","files","renderDocuments","renderUploadQueue","showUploadStatus","showUploadProgress","createTextElement","tagName","documentInfo","row","details","prepend","appendChild","removeButton","removeIcon","_x2","_removeDocument","removeDocument","progress","width","roundedProgress","round","item","presentation","state","badgeClass","progressClass","getUploadStatePresentation","header","fileDetails","badge","progressState","formatUploadMessage","createUploadItem","lastModified","Date","now","updateUploadItem","updates","removeUploadItems","predicate","uploadSingleDocument","itemIdToUpdate","fileIndex","totalFiles","reject","formData","FormData","append","xhr","XMLHttpRequest","open","uploadDocumentUrl","upload","lengthComputable","fileProgress","loaded","total","responseText","Error","_callee6","filesToUpload","duplicateItems","knownDocumentKeys","pendingItems","uploadedCount","failedUploads","pendingItem","result","uploaded","failed","missingUploadMessage","failedMessage","errorMessage","_t2","_t3","_context6","Set","join","entry","_callee7","response","serverDocuments","_t4","_t5","_context7","removeDocumentUrl","fetch","method","headers","body","stringify","ok","documents","download","toDataURL","img","startsWith","res","removeChild"],"mappings":"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","file":"chat-interaction.min.js","sourcesContent":["window.chatInteractionManager = 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 codeCopiedText: 'Copied!',\n assistantLabel: 'Assistant',\n\n messageTemplate: `\n <div class=\"ai-chat-messages\">\n <div v-for=\"(message, index) in messages\" :key=\"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\">You</div>\n <div v-else-if=\"message.role !== 'indicator'\" :class=\"getAssistantRoleClasses(message)\">\n <span :class=\"getAssistantIconClasses(message, index)\"><span :class=\"getAssistantIcon(message)\"></span></span>\n {{ getAssistantLabel(message) }}\n </div>\n <div class=\"ai-chat-message-body lh-base\">\n <h4 v-if=\"message.title\">{{ message.title }}</h4>\n <div v-html=\"message.htmlContent\"></div>\n <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 <button v-if=\"textToSpeechEnabled && !isConversationMode && message.role === 'assistant' && !message.isStreaming\" class=\"btn btn-sm btn-link text-secondary p-0 me-1 button-message-toolbox\" :class=\"{ 'tts-playing': ttsPlayingMessageIndex === index }\" :data-tts-message-index=\"index\" @click=\"toggleMessageTts(message, index)\" :title=\"ttsPlayingMessageIndex === index ? 'Pause audio' : 'Read aloud'\">\n <span :class=\"ttsPlayingMessageIndex === index ? 'fa-solid fa-circle-pause' : 'fa-solid fa-circle-play'\"></span>\n </button>\n <button class=\"btn btn-sm btn-link text-secondary p-0 button-message-toolbox\" @click=\"copyResponse(message)\" title=\"Click here to copy response to clipboard.\">\n <span class=\"fa-solid fa-copy\"></span>\n </button>\n </span>\n </div>\n </div>\n </div>\n <div v-for=\"notification in notifications\" :key=\"'notif-' + notification.type\" class=\"ai-chat-notification\" :class=\"'ai-chat-notification-' + (notification.type || 'info') + ' ' + (notification.cssClass || '')\">\n <div class=\"ai-chat-notification-content\">\n <span v-if=\"notification.icon\" :class=\"notification.icon\" class=\"ai-chat-notification-icon\"></span>\n <span class=\"ai-chat-notification-text\">{{ notification.content }}</span>\n <button v-if=\"notification.dismissible\" class=\"btn btn-sm btn-link p-0 ms-2 ai-chat-notification-dismiss\" @click=\"dismissNotification(notification.type)\" title=\"Dismiss\">\n <span class=\"fa-solid fa-xmark\"></span>\n </button>\n </div>\n <div v-if=\"notification.actions && notification.actions.length\" class=\"ai-chat-notification-actions\">\n <button v-for=\"action in notification.actions\" :key=\"action.name\" class=\"btn btn-sm\" :class=\"action.cssClass || 'btn-outline-secondary'\" @click=\"handleNotificationAction(notification.type, action.name)\">\n <span v-if=\"action.icon\" :class=\"action.icon\" class=\"me-1\"></span>\n {{ action.label }}\n </button>\n </div>\n </div>\n </div>\n `,\n indicatorTemplate: `\n <div class=\"ai-chat-msg-role ai-chat-msg-role-assistant\">\n <span class=\"ai-streaming-icon\"><span class=\"fa fa-robot\" style=\"display: inline-block;\"></span></span>\n Assistant\n </div>\n `,\n // Localizable strings\n untitledText: 'Untitled',\n clearHistoryTitle: 'Clear History',\n clearHistoryMessage: 'Are you sure you want to clear the chat history? This action cannot be undone. Your documents, parameters, and tools will be preserved.',\n clearHistoryOkText: 'Yes',\n clearHistoryCancelText: 'Cancel'\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 normalizeReference(reference) {\n if (!reference || typeof reference !== 'object') {\n return null;\n }\n\n const normalized = Object.assign({}, reference);\n normalized.index = normalized.index ?? normalized.Index ?? 0;\n normalized.text = normalized.text ?? normalized.Text ?? null;\n normalized.title = normalized.title ?? normalized.Title ?? null;\n normalized.link = sanitizeUrl(normalized.link ?? normalized.Link ?? null);\n normalized.referenceType = normalized.referenceType ?? normalized.ReferenceType ?? null;\n\n return normalized;\n }\n\n function isDownloadCitationReference(reference) {\n if (!reference || typeof reference !== 'object') {\n return false;\n }\n\n if (typeof reference.referenceType === 'string' && reference.referenceType.toLowerCase() === 'document') {\n return true;\n }\n\n if (typeof reference.link === 'string' && /\\/ai\\/documents\\/.+\\/download(?:$|\\?)/i.test(reference.link)) {\n return true;\n }\n\n return false;\n }\n\n function normalizeReferences(references) {\n if (!references || typeof references !== 'object') {\n return {};\n }\n\n const normalized = {};\n\n for (const [key, value] of Object.entries(references)) {\n normalized[key] = normalizeReference(value) ?? {};\n }\n\n return normalized;\n }\n\n function getCitationLabel(reference, key) {\n return reference.title || reference.text || key;\n }\n\n function buildCitationDisplay(content, references) {\n let processedContent = (content || '').trim();\n const messageReferences = normalizeReferences(references);\n\n if (!processedContent || !Object.keys(messageReferences).length) {\n return { content: processedContent, citations: [] };\n }\n\n const citedRefs = Object.entries(messageReferences).filter(([key]) => processedContent.includes(key));\n\n if (!citedRefs.length) {\n return { content: processedContent, citations: [] };\n }\n\n citedRefs.sort(([, a], [, b]) => a.index - b.index);\n\n const citations = [];\n let displayIndex = 1;\n\n for (const [key, value] of citedRefs) {\n const placeholder = `__CITE_${displayIndex}_${value.index || displayIndex}__`;\n processedContent = processedContent.replaceAll(key, placeholder);\n citations.push({\n referenceKey: key,\n displayIndex: displayIndex,\n label: getCitationLabel(value, key),\n link: value.link || null,\n isDownload: isDownloadCitationReference(value),\n placeholder: placeholder,\n });\n\n displayIndex++;\n }\n\n for (const citation of citations) {\n processedContent = processedContent.replaceAll(citation.placeholder, `<sup>${citation.displayIndex}</sup>`);\n }\n\n processedContent = processedContent.replaceAll('</sup><sup>', '</sup><sup>,</sup><sup>');\n\n return {\n content: processedContent,\n citations: citations.map(({ placeholder, ...citation }) => citation),\n };\n }\n\n function buildCopyContent(content, citations) {\n let copyContent = (content || '').trim();\n\n if (!copyContent || !Array.isArray(citations) || citations.length === 0) {\n return copyContent;\n }\n\n for (const citation of citations) {\n copyContent = copyContent.replaceAll(citation.referenceKey, `[${citation.displayIndex}]`);\n }\n\n copyContent += '\\n\\nReferences:\\n';\n\n for (const citation of citations) {\n copyContent += `${citation.displayIndex}. ${citation.label}`;\n\n if (citation.link) {\n copyContent += ` - ${citation.link}`;\n }\n\n copyContent += '\\n';\n }\n\n return copyContent.trimEnd();\n }\n\n function updateMessagePresentation(message, references) {\n const messageReferences = normalizeReferences(references ?? message.references);\n const rawContent = typeof message.rawContent === 'string'\n ? message.rawContent\n : typeof message.content === 'string'\n ? message.content\n : '';\n const citationDisplay = buildCitationDisplay(rawContent, messageReferences);\n\n message.rawContent = rawContent;\n message.content = rawContent;\n message.displayContent = citationDisplay.content;\n message.references = messageReferences;\n message.citationReferences = citationDisplay.citations;\n message.copyContent = buildCopyContent(rawContent, citationDisplay.citations);\n message.htmlContent = parseMarkdownContent(citationDisplay.content, message);\n\n return message;\n }\n\n const renderer = new marked.Renderer();\n\n // Modify the link rendering to open in a new tab\n renderer.link = function (data) {\n var href = sanitizeUrl(data.href);\n if (!href) return data.text || '';\n return `<a href=\"${href}\" target=\"_blank\" rel=\"noopener noreferrer\">${data.text}</a>`;\n };\n\n // Custom code block renderer with highlight.js integration and copy button.\n renderer.code = function (data) {\n var code = data.text || '';\n var lang = (data.lang || '').trim();\n var highlighted = code;\n\n if (typeof hljs !== 'undefined') {\n if (lang && hljs.getLanguage(lang)) {\n try {\n highlighted = hljs.highlight(code, { language: lang }).value;\n } catch (_) { }\n } else {\n try {\n highlighted = hljs.highlightAuto(code).value;\n } catch (_) { }\n }\n } else {\n highlighted = escapeHtmlEntities(code);\n }\n\n var langDisplay = lang ? escapeHtmlEntities(lang) : 'code';\n return `<div class=\"ai-code-block\"><div class=\"ai-code-header\"><span class=\"ai-code-lang\"><span class=\"fa-solid fa-code\"></span> ${langDisplay}</span><button type=\"button\" class=\"ai-code-copy-btn\" title=\"Copy code\"><span class=\"fa-regular fa-copy\"></span></button></div><pre><code class=\"hljs${lang ? ' language-' + lang : ''}\">${highlighted}</code></pre></div>`;\n };\n\n // Custom image renderer for generated images with thumbnail styling and download button.\n // Handles both URL and data-URI sources (data URIs are converted to blobs for download).\n renderer.image = function (data) {\n const src = sanitizeUrl(data.href);\n if (!src) return '';\n const alt = data.text || defaultConfig.generatedImageAltText;\n const maxWidth = defaultConfig.generatedImageMaxWidth;\n return `<div class=\"generated-image-container\">\n <img src=\"${src}\" alt=\"${alt}\" class=\"img-thumbnail\" style=\"max-width: ${maxWidth}px; height: auto;\" />\n <div class=\"mt-2\">\n <a href=\"${src}\" target=\"_blank\" download=\"${alt}\" title=\"${defaultConfig.downloadImageTitle}\" class=\"btn btn-sm btn-outline-secondary ai-download-image\">\n <span class=\"fa-solid fa-download\"></span>\n </a>\n </div>\n </div>`;\n };\n\n // Chart counter for unique IDs\n let chartCounter = 0;\n\n // Collector for charts discovered during marked parsing.\n let _pendingCharts = [];\n\n // Global chart config map shared with ai-chat.js\n window.__chartConfigs = window.__chartConfigs || {};\n\n function createChartHtml(chartId) {\n return `<div class=\"chart-container\" style=\"position: relative; width: 100%; max-width: 560px; min-height: 420px;\">`\n + `<canvas id=\"${chartId}\"></canvas>`\n + `</div>`\n + `<div class=\"mt-2\">`\n + `<button type=\"button\" class=\"btn btn-sm btn-outline-secondary download-chart-btn\" data-chart-id=\"${chartId}\" title=\"${defaultConfig.downloadChartTitle}\">`\n + `<span class=\"fa-solid fa-download\"></span> ${defaultConfig.downloadChartButtonText}`\n + `</button>`\n + `</div>`;\n }\n\n // Register [chart:{...json...}] as a native marked block extension so the\n // markdown parser handles chart markers inline with surrounding text.\n marked.use({\n extensions: [{\n name: 'chart',\n level: 'block',\n start(src) {\n const idx = src.indexOf('[chart:');\n return idx >= 0 ? idx : undefined;\n },\n tokenizer(src) {\n const extracted = tryExtractChartMarker(src);\n if (!extracted || extracted.startIndex !== 0) {\n return undefined;\n }\n\n const chartId = `chat_chart_${++chartCounter}`;\n\n return {\n type: 'chart',\n raw: src.substring(0, extracted.endIndex),\n chartId: chartId,\n json: extracted.json,\n };\n },\n renderer(token) {\n _pendingCharts.push({ chartId: token.chartId, config: token.json });\n window.__chartConfigs[token.chartId] = token.json;\n return createChartHtml(token.chartId);\n }\n }]\n });\n\n // Extract a [chart:{...json...}] marker. This avoids regex issues with nested brackets.\n function tryExtractChartMarker(text) {\n const token = '[chart:';\n const start = text.indexOf(token);\n if (start < 0) {\n return null;\n }\n\n // Find JSON object boundary by balancing braces\n const jsonStart = start + token.length;\n let i = jsonStart;\n while (i < text.length && (text[i] === ' ' || text[i] === '\\n' || text[i] === '\\r' || text[i] === '\\t')) {\n i++;\n }\n\n if (i >= text.length || text[i] !== '{') {\n return null;\n }\n\n let depth = 0;\n let inString = false;\n let escape = false;\n\n for (; i < text.length; i++) {\n const ch = text[i];\n\n if (inString) {\n if (escape) {\n escape = false;\n continue;\n }\n if (ch === '\\\\') {\n escape = true;\n continue;\n }\n if (ch === '\"') {\n inString = false;\n }\n continue;\n }\n\n if (ch === '\"') {\n inString = true;\n continue;\n }\n\n if (ch === '{') {\n depth++;\n } else if (ch === '}') {\n depth--;\n if (depth === 0) {\n const jsonEnd = i;\n // Expect closing bracket after JSON\n const closeBracketIndex = text.indexOf(']', jsonEnd + 1);\n if (closeBracketIndex < 0) {\n return null;\n }\n\n const json = text.substring(jsonStart, jsonEnd + 1).trim();\n return {\n startIndex: start,\n endIndex: closeBracketIndex + 1,\n json: json\n };\n }\n }\n }\n\n return null;\n }\n\n function renderChartsInMessage(message) {\n if (!message || !message._pendingCharts || !message._pendingCharts.length) {\n return;\n }\n\n // Copy and clear pending charts immediately to prevent duplicate renders.\n const charts = [...message._pendingCharts];\n message._pendingCharts = [];\n\n // Defer to requestAnimationFrame so the browser has fully laid out the\n // canvas elements before Chart.js reads their dimensions.\n requestAnimationFrame(() => {\n for (const c of charts) {\n const canvas = document.getElementById(c.chartId);\n if (!canvas) {\n continue;\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 continue;\n }\n\n // When the canvas is inside a hidden container (e.g., display:none),\n // it has zero dimensions. Keep the config for later rendering.\n if (canvas.offsetParent === null) {\n window.__chartConfigs[c.chartId] = c.config;\n continue;\n }\n\n try {\n // Destroy existing chart instance if re-rendering\n if (canvas._chartInstance) {\n canvas._chartInstance.destroy();\n }\n\n const cfg = typeof c.config === 'string' ? JSON.parse(c.config) : c.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 } catch (e) {\n console.error('Error creating chart:', e);\n }\n }\n });\n }\n\n // Parse markdown content via marked (which natively handles [chart:...] markers\n // through the registered extension) and collect pending chart configs for later\n // Chart.js rendering.\n function parseMarkdownContent(content, message) {\n _pendingCharts = [];\n const html = marked.parse(content, { renderer });\n message._pendingCharts = _pendingCharts.length > 0 ? [..._pendingCharts] : [];\n return DOMPurify.sanitize(html, { ADD_TAGS: ['canvas'], ADD_ATTR: ['target'] });\n }\n\n const initialize = (instanceConfig) => {\n\n const config = Object.assign({}, defaultConfig, instanceConfig);\n // Keep defaultConfig in sync so renderers use overridden values\n defaultConfig = config;\n\n if (!config.signalRHubUrl) {\n console.error('The signalRHubUrl is required.');\n return;\n }\n\n if (!config.appElementSelector) {\n console.error('The appElementSelector is required.');\n return;\n }\n\n if (!config.chatContainerElementSelector) {\n console.error('The chatContainerElementSelector is required.');\n return;\n }\n\n if (!config.inputElementSelector) {\n console.error('The inputElementSelector is required.');\n return;\n }\n\n if (!config.sendButtonElementSelector) {\n console.error('The sendButtonElementSelector is required.');\n return;\n }\n\n const app = Vue.createApp({\n data() {\n return {\n inputElement: null,\n buttonElement: null,\n chatContainer: null,\n placeholder: null,\n isInteractionStarted: false,\n isPlaceholderVisible: true,\n isStreaming: false,\n isNavigatingAway: false,\n autoScroll: true,\n stream: null,\n messages: [],\n prompt: '',\n initialFieldValues: new Map(),\n settingsDirty: false,\n saveSettingsTimeout: null,\n saveIndicatorTimeout: null,\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 ttsPlayingMessageIndex: -1,\n ttsAudioCache: {},\n ttsInstanceId: 'chat-interaction-' + Math.random().toString(36).slice(2),\n conversationModeEnabled: config.chatMode === 'Conversation',\n conversationButton: null,\n isConversationMode: false,\n notifications: [],\n notificationDismissTimers: {},\n };\n },\n computed: {\n lastAssistantIndex() {\n for (var i = this.messages.length - 1; i >= 0; i--) {\n if (this.messages[i].role === 'assistant') {\n return i;\n }\n }\n return -1;\n }\n },\n methods: {\n handleBeforeUnload() {\n this.isNavigatingAway = true;\n },\n 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(\"LoadInteraction\", (data) => {\n this.initializeInteraction(data.itemId, true);\n this.messages = [];// Update the title field if it exists\n const titleInput = document.querySelector('[data-chat-interaction-title], .setting-input[data-setting=\"title\"], input[name=\"ChatInteraction.Title\"], input[name=\"Title\"]');\n if (titleInput && data.title) {\n titleInput.value = data.title;\n }\n\n (data.messages ?? []).forEach(msg => {\n this.addMessage(msg);\n\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n });\n });\n });\n\n this.connection.on(\"SettingsSaved\", (itemId, title) => {\n // Update the history list item if it exists\n // Use a more specific selector to only target history list items, not other elements like the Clear History button\n const historyItem = document.querySelector(`.chat-interaction-history-item[data-interaction-id=\"${itemId}\"]`);\n if (historyItem) {\n historyItem.textContent = title || config.untitledText;\n }\n\n const titleInput = document.querySelector('[data-chat-interaction-title], .setting-input[data-setting=\"title\"], input[name=\"ChatInteraction.Title\"], input[name=\"Title\"]');\n if (titleInput && title) {\n titleInput.value = title;\n }\n\n this.showSaveIndicator('Saved', 'text-success');\n });\n\n this.connection.on(\"ReceiveError\", (error) => {\n console.error(\"SignalR Error: \", error);\n this.showSaveIndicator('Save failed', 'text-danger');\n\n if (this.isRecording) {\n this.stopRecording();\n }\n });\n\n this.connection.on(\"ReceiveTranscript\", (itemId, text, isFinal) => {\n if (this.isConversationMode) {\n if (!isFinal && text) {\n this._conversationPartialTranscript = text;\n var escaped = text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n var html = '<p class=\"ai-partial-transcript\">' + escaped + '</p>';\n\n // Show partial transcript as a live user message.\n if (!this._conversationPartialMessage) {\n this.hidePlaceholder();\n this._conversationPartialMessage = {\n role: 'user',\n content: text,\n htmlContent: html,\n isPartial: true\n };\n this.messages.push(this._conversationPartialMessage);\n } else {\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = html;\n }\n this.scrollToBottom();\n }\n return;\n }\n\n if (text && !this._audioInputSent) {\n this.prompt = this.preRecordingPrompt + text;\n if (this.inputElement) {\n this.inputElement.value = this.prompt;\n this.inputElement.dispatchEvent(new Event('input'));\n }\n }\n });\n\n this.connection.on(\"ReceiveConversationUserMessage\", (itemId, text) => {\n if (text) {\n this.stopAudio();\n\n // If there's an interrupted assistant message still streaming,\n // mark it as done to stop the spinner animation.\n if (this._conversationAssistantMessage) {\n var oldMsg = this.messages[this._conversationAssistantMessage.index];\n if (oldMsg) {\n oldMsg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Replace the partial transcript message with the final one.\n if (this._conversationPartialMessage) {\n var escaped = text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = '<p>' + escaped + '</p>';\n this._conversationPartialMessage.isPartial = false;\n this._conversationPartialMessage = null;\n } else {\n this.addMessage({\n role: 'user',\n content: text\n });\n }\n this.scrollToBottom();\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantToken\", (itemId, 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 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\", (itemId, 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\", (itemId, 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\", (itemId) => {\n this.playCollectedAudio();\n });\n\n this.connection.on(\"HistoryCleared\", (itemId) => {\n // Clear messages and show placeholder\n this.messages = [];\n this.showPlaceholder();\n\n // Hide the clear history button since there's no history now\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.classList.add('d-none');\n }\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 this.reloadCurrentInteraction();\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(\"addingChatInteractionMessage\", { detail: { message: message } }));\n this.messages.push(message);\n\n this.$nextTick(() => {\n this.fireEvent(new CustomEvent(\"addedChatInteractionMessage\", { detail: { message: message } }));\n });\n },\n addMessage(message) {\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 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 fireEvent(event) {\n document.dispatchEvent(event);\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 : defaultConfig.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 isIndicator(message) {\n return message.role === 'indicator';\n },\n async sendMessage() {\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 // Flush any pending settings save before sending a message\n // to prevent concurrent hub calls that can cause database deadlocks.\n await this.flushPendingSave();\n\n this.addMessage({\n role: 'user',\n content: trimmedPrompt\n });\n\n // Show the clear history button since we now have prompts\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.classList.remove('d-none');\n }\n\n this.streamMessage(trimmedPrompt);\n this.inputElement.value = '';\n this.prompt = '';\n },\n streamMessage(trimmedPrompt) {\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 var messageIndex = this.messages.length;\n var currentItemId = this.getItemId();\n\n this.stream = this.connection.stream(\"SendMessage\", currentItemId, trimmedPrompt)\n .subscribe({\n next: (chunk) => {\n let message = this.messages[messageIndex];\n\n if (!message) {\n if (chunk.sessionId && !currentItemId) {\n this.setItemId(chunk.sessionId);\n }\n\n this.hideTypingIndicator();\n messageIndex = this.messages.length;\n let newMessage = {\n role: \"assistant\",\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n };\n\n this.messages.push(newMessage);\n message = newMessage;\n }\n\n if (chunk.references && typeof chunk.references === \"object\" && Object.keys(chunk.references).length) {\n for (const [key, value] of Object.entries(chunk.references)) {\n references[key] = normalizeReference(value) ?? {};\n }\n }\n\n if (chunk.content) {\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 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 return {\n role: \"assistant\",\n content: \"Our service is currently unavailable. Please try again later. We apologize for the inconvenience.\",\n htmlContent: \"\",\n };\n },\n processReferences(references, messageIndex) {\n references = normalizeReferences(references);\n\n if (Object.keys(references).length) {\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 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 // 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 // Save any settings that were deferred during streaming.\n if (this.settingsDirty) {\n this.debouncedSaveSettings();\n }\n },\n handleExternalTtsStop(e) {\n if (e?.detail?.sourceId === this.ttsInstanceId) {\n return;\n }\n\n this.stopAudio(false);\n },\n updateTtsPlaybackButtons() {\n if (!this.chatContainer) {\n return;\n }\n\n var buttons = this.chatContainer.querySelectorAll('[data-tts-message-index]');\n\n buttons.forEach(button => {\n var buttonIndex = Number(button.getAttribute('data-tts-message-index'));\n var isPlaying = buttonIndex === this.ttsPlayingMessageIndex;\n var iconHtml = isPlaying\n ? '<span class=\"fa-solid fa-circle-pause\"></span>'\n : '<span class=\"fa-solid fa-circle-play\"></span>';\n\n button.classList.toggle('tts-playing', isPlaying);\n button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\n });\n },\n synthesizeSpeech(text, cacheIndex) {\n if (!this.textToSpeechEnabled || !text || !this.connection) {\n return;\n }\n\n this.audioChunks = [];\n this.isPlayingAudio = true;\n this._ttsCacheIndex = cacheIndex !== undefined ? cacheIndex : -1;\n\n this.connection.invoke(\"SynthesizeSpeech\", this.getItemId(), 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.isPlayingAudio && 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 currently playing, queue this blob for later.\n if (this.isPlayingAudio && 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 const 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\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 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 itemId = this.getItemId();\n\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"StartConversation\", itemId, 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, continuation is handled\n // by the persistent stream.\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 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 getItemId() {\n return this.inputElement.getAttribute('data-interaction-id')\n || this.inputElement.getAttribute('data-item-id');\n },\n getSaveIndicatorElement() {\n if (config.saveIndicatorElementSelector) {\n return document.querySelector(config.saveIndicatorElementSelector);\n }\n\n return document.querySelector('[data-chat-interaction-save-indicator]');\n },\n showSaveIndicator(text, className) {\n const indicator = this.getSaveIndicatorElement();\n if (!indicator) {\n return;\n }\n\n indicator.textContent = text || '';\n indicator.className = 'settings-save-indicator ' + (className || 'text-muted');\n\n if (this.saveIndicatorTimeout) {\n clearTimeout(this.saveIndicatorTimeout);\n this.saveIndicatorTimeout = null;\n }\n\n if (!text) {\n return;\n }\n\n this.saveIndicatorTimeout = setTimeout(() => {\n indicator.textContent = '';\n this.saveIndicatorTimeout = null;\n }, 3000);\n },\n clearPendingSettingsSave() {\n if (this.saveSettingsTimeout) {\n clearTimeout(this.saveSettingsTimeout);\n this.saveSettingsTimeout = null;\n }\n },\n getFieldLabel(input) {\n const label = input\n .closest('.mb-3, .col-6, .col, .form-group, .form-floating')\n ?.querySelector('label');\n\n if (!label) {\n return input.dataset.setting || 'This field';\n }\n\n return (label.textContent || '')\n .replace(/\\s+/g, ' ')\n .trim()\n || input.dataset.setting\n || 'This field';\n },\n getValidationFeedbackElement(input) {\n let feedback = input.nextElementSibling;\n if (feedback && feedback.classList.contains('invalid-feedback')) {\n return feedback;\n }\n\n feedback = document.createElement('div');\n feedback.className = 'invalid-feedback';\n input.insertAdjacentElement('afterend', feedback);\n\n return feedback;\n },\n clearSettingValidationError(input) {\n input.classList.remove('is-invalid');\n input.removeAttribute('aria-invalid');\n\n const feedback = input.nextElementSibling;\n if (feedback && feedback.classList.contains('invalid-feedback')) {\n feedback.textContent = '';\n }\n },\n setSettingValidationError(input, message) {\n const feedback = this.getValidationFeedbackElement(input);\n input.classList.add('is-invalid');\n input.setAttribute('aria-invalid', 'true');\n feedback.textContent = message;\n },\n getSettingValidationMessage(input) {\n if (!input || input.disabled || input.type !== 'number') {\n return null;\n }\n\n const value = (input.value || '').trim();\n if (!value) {\n return null;\n }\n\n const number = Number(value);\n const fieldLabel = this.getFieldLabel(input);\n\n if (Number.isNaN(number)) {\n return `${fieldLabel} must be a valid number.`;\n }\n\n const min = input.getAttribute('min');\n if (min !== null && number < Number(min)) {\n return `${fieldLabel} must be ${min} or greater.`;\n }\n\n const max = input.getAttribute('max');\n if (max !== null && number > Number(max)) {\n return `${fieldLabel} must be ${max} or less.`;\n }\n\n return null;\n },\n validateSettingInput(input) {\n const message = this.getSettingValidationMessage(input);\n if (!message) {\n this.clearSettingValidationError(input);\n return true;\n }\n\n this.setSettingValidationError(input, message);\n return false;\n },\n validateSettings() {\n let isValid = true;\n\n this.getSettingInputs().forEach(input => {\n isValid = this.validateSettingInput(input) && isValid;\n });\n\n return isValid;\n },\n queueSettingsSave() {\n if (!this.validateSettings()) {\n this.clearPendingSettingsSave();\n this.settingsDirty = false;\n this.showSaveIndicator('Fix errors', 'text-danger');\n return;\n }\n\n this.settingsDirty = true;\n this.showSaveIndicator('Saving...', 'text-warning');\n this.debouncedSaveSettings();\n },\n getSettingInputs() {\n const explicitInputs = document.querySelectorAll('.setting-input[data-setting]');\n if (explicitInputs.length > 0) {\n return explicitInputs;\n }\n\n return document.querySelectorAll(\n 'input[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"]), ' +\n 'select[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"]), ' +\n 'textarea[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"])'\n );\n },\n getSelectedGroupValues(groupName, fallbackSelector) {\n const explicitSelections = document.querySelectorAll(`.capability-checkbox[data-save-group=\"${groupName}\"]:checked, .capability-checkbox[data-group=\"${groupName}\"]:checked`);\n if (explicitSelections.length > 0) {\n const values = [];\n\n explicitSelections.forEach(checkbox => {\n const value = checkbox.getAttribute('data-item-id') || checkbox.value;\n if (value) {\n values.push(value);\n }\n });\n\n return values;\n }\n\n if (!fallbackSelector) {\n return [];\n }\n\n const values = [];\n const checkboxes = document.querySelectorAll(fallbackSelector);\n\n checkboxes.forEach(checkbox => {\n const baseName = checkbox.name.replace('.IsSelected', '.ItemId');\n const hiddenInput = document.querySelector(`input[type=\"hidden\"][name=\"${baseName}\"]`);\n\n if (hiddenInput && hiddenInput.value) {\n values.push(hiddenInput.value);\n }\n });\n\n return values;\n },\n getPromptTemplateSelections() {\n const promptTemplates = [];\n\n document.querySelectorAll('.prompt-template-card').forEach(card => {\n const templateIdInput = card.querySelector('.prompt-template-id-input');\n const promptParametersInput = card.querySelector('.prompt-template-parameters-input');\n const templateId = templateIdInput ? templateIdInput.value : card.getAttribute('data-template-id');\n\n if (!templateId) {\n return;\n }\n\n promptTemplates.push({\n templateId: templateId,\n promptParameters: promptParametersInput ? (promptParametersInput.value || '').trim() : ''\n });\n });\n\n return promptTemplates;\n },\n receiveNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n // Replace existing notification with same type, or add new one.\n var idx = this.notifications.findIndex(n => n.type === notification.type);\n if (idx >= 0) {\n this.notifications.splice(idx, 1, notification);\n } else {\n this.notifications.push(notification);\n }\n this.scheduleNotificationDismiss(notification);\n this.scrollToBottom();\n },\n updateNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var idx = this.notifications.findIndex(n => n.type === notification.type);\n if (idx >= 0) {\n this.notifications.splice(idx, 1, notification);\n this.scheduleNotificationDismiss(notification);\n this.scrollToBottom();\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 itemId = this.getItemId();\n this.connection.invoke('HandleNotificationAction', itemId, notificationType, actionName)\n .catch(err => console.error('Failed to handle notification action:', err));\n },\n setItemId(itemId) {\n this.inputElement.setAttribute('data-interaction-id', itemId || '');\n this.inputElement.setAttribute('data-item-id', itemId || '');\n },\n resetInteraction() {\n this.setItemId('');\n this.isInteractionStarted = false;\n this.messages = [];\n this.showPlaceholder();\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 const itemId = this.getItemId();\n if (itemId) {\n this.loadInteraction(itemId);\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('keyup', event => {\n if (this.stream != null) {\n return;\n }\n\n if (event.key === \"Enter\" && !event.shiftKey) {\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.inputElement.addEventListener('paste', (e) => {\n // Use setTimeout to allow the paste to complete before checking the value\n setTimeout(() => {\n this.prompt = this.inputElement.value;\n if (this.inputElement.value.trim()) {\n this.buttonElement.removeAttribute('disabled');\n } else {\n this.buttonElement.setAttribute('disabled', true);\n }\n }, 0);\n });\n\n this.buttonElement.addEventListener('click', () => {\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 chatInteractionItems = document.getElementsByClassName('chat-interaction-history-item');\n\n for (var i = 0; i < chatInteractionItems.length; i++) {\n chatInteractionItems[i].addEventListener('click', (e) => {\n e.preventDefault();\n\n var itemId = e.target.getAttribute('data-interaction-id');\n\n if (!itemId) {\n console.error('An element with the class chat-interaction-history-item with no data-interaction-id set.');\n return;\n }\n\n this.loadInteraction(itemId);\n });\n }\n\n for (let i = 0; i < config.messages.length; i++) {\n this.addMessage(config.messages[i]);\n }\n\n // Delegate click for code block copy buttons.\n if (this.chatContainer) {\n this.chatContainer.addEventListener('click', (e) => {\n var btn = e.target.closest('.ai-code-copy-btn');\n if (!btn) {\n return;\n }\n\n var block = btn.closest('.ai-code-block') || btn.closest('pre');\n if (!block) {\n return;\n }\n\n var codeEl = block.querySelector('code');\n if (codeEl) {\n navigator.clipboard.writeText(codeEl.textContent);\n var copiedText = config.codeCopiedText || 'Copied!';\n btn.innerHTML = '<span class=\"fa-solid fa-check\"></span> ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '<span class=\"fa-regular fa-copy\"></span>';\n }, 2000);\n }\n });\n }\n\n document.addEventListener('input', event => {\n if (event.target.matches('.setting-input[data-setting]')) {\n this.validateSettingInput(event.target);\n this.queueSettingsSave();\n }\n });\n\n document.addEventListener('change', event => {\n if (event.target.matches('.setting-input[data-setting], .capability-checkbox[data-save-group], .capability-checkbox[data-group], .group-toggle, .ci-agent-global-toggle')) {\n if (event.target.matches('.setting-input[data-setting]')) {\n this.validateSettingInput(event.target);\n }\n\n this.queueSettingsSave();\n return;\n }\n\n if (event.target.closest('.prompt-template-parameters-input, .prompt-template-id-input')) {\n this.queueSettingsSave();\n }\n });\n\n document.addEventListener('click', event => {\n if (!event.target.closest('.prompt-template-add-btn, .remove-prompt-template-btn')) {\n return;\n }\n\n setTimeout(() => {\n this.queueSettingsSave();\n }, 0);\n });\n\n // Add event listener for clear history button\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.addEventListener('click', () => {\n const itemId = clearHistoryBtn.getAttribute('data-interaction-id');\n if (itemId) {\n this.clearHistory(itemId);\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 loadInteraction(itemId) {\n this.connection.invoke(\"LoadInteraction\", itemId).catch(err => console.error(err));\n },\n reloadCurrentInteraction() {\n const itemId = this.getItemId();\n if (itemId) {\n this.loadInteraction(itemId);\n }\n },\n clearHistory(itemId) {\n const self = this;\n const clearHistoryConfirmed = () => {\n // Cancel any active stream before clearing history.\n if (self.stream) {\n self.stream.dispose();\n self.stream = null;\n self.hideTypingIndicator();\n self.streamingFinished();\n }\n\n self.connection.invoke(\"ClearHistory\", itemId)\n .catch(err => console.error('Error clearing history:', err));\n };\n\n if (typeof confirmDialog === 'function') {\n confirmDialog({\n title: config.clearHistoryTitle,\n message: config.clearHistoryMessage,\n okText: config.clearHistoryOkText,\n cancelText: config.clearHistoryCancelText,\n callback: function (confirmed) {\n if (confirmed) {\n clearHistoryConfirmed();\n }\n }\n });\n\n return;\n }\n\n if (window.confirm(config.clearHistoryMessage || 'Clear all messages?')) {\n clearHistoryConfirmed();\n }\n },\n debouncedSaveSettings() {\n // Clear any existing timeout to reset the debounce timer\n this.clearPendingSettingsSave();\n\n // Don't save while streaming — it will be saved when streaming completes.\n if (this.stream) {\n return;\n }\n\n // Set a new timeout to save after 850ms of no changes\n this.saveSettingsTimeout = setTimeout(() => {\n if (this.settingsDirty) {\n this.saveSettings();\n this.settingsDirty = false;\n }\n this.saveSettingsTimeout = null;\n }, 850);\n },\n getSelectedToolNames() {\n return this.getSelectedGroupValues(\n 'toolNames',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Tools[\"]:checked'\n );\n },\n getSelectedMcpConnectionIds() {\n return this.getSelectedGroupValues(\n 'mcpConnectionIds',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Connections[\"]:checked'\n );\n },\n getSelectedA2AConnectionIds() {\n return this.getSelectedGroupValues('a2aConnectionIds');\n },\n getSelectedAgentNames() {\n return this.getSelectedGroupValues(\n 'agentNames',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Agents[\"]:checked'\n );\n },\n saveSettings() {\n const itemId = this.getItemId();\n if (!itemId) {\n return Promise.resolve();\n }\n\n if (!this.validateSettings()) {\n this.showSaveIndicator('Fix errors', 'text-danger');\n return Promise.resolve();\n }\n\n const settings = {};\n\n // Collect all form inputs with the \"ChatInteraction.\" prefix generically.\n // This avoids coupling the JS to specific field names — new fields added by\n // any module are automatically included.\n const inputs = this.getSettingInputs();\n\n inputs.forEach(input => {\n const key = input.dataset.setting\n || ((input.name || '').replace('ChatInteraction.', '').replace(/^[A-Z]/, match => match.toLowerCase()));\n\n if (!key) {\n return;\n }\n\n if (input.type === 'checkbox') {\n settings[key] = input.checked;\n } else if (input.type === 'number') {\n settings[key] = input.value ? parseFloat(input.value) : null;\n } else {\n settings[key] = input.value || null;\n }\n });\n\n // Add tool, MCP connection, and agent collections (special handling).\n settings.toolNames = this.getSelectedToolNames();\n settings.mcpConnectionIds = this.getSelectedMcpConnectionIds();\n settings.a2aConnectionIds = this.getSelectedA2AConnectionIds();\n settings.agentNames = this.getSelectedAgentNames();\n\n const promptTemplates = this.getPromptTemplateSelections();\n if (promptTemplates.length > 0) {\n settings.promptTemplates = promptTemplates;\n settings.promptTemplateIds = promptTemplates.map(template => template.templateId);\n }\n\n return this.connection.invoke(\"SaveSettings\", itemId, settings)\n .catch(err => {\n console.error('Error saving settings:', err);\n this.showSaveIndicator('Save failed', 'text-danger');\n });\n },\n flushPendingSave() {\n if (this.saveSettingsTimeout) {\n clearTimeout(this.saveSettingsTimeout);\n this.saveSettingsTimeout = null;\n }\n\n if (this.settingsDirty) {\n this.settingsDirty = false;\n return this.saveSettings();\n }\n\n return Promise.resolve();\n },\n initializeInteraction(itemId, force) {\n if (this.isInteractionStarted && !force) {\n return;\n }\n this.fireEvent(new CustomEvent(\"initializingChatInteraction\", { detail: { itemId: itemId } }));\n this.setItemId(itemId);\n this.isInteractionStarted = true;\n },\n copyResponse(message) {\n const text = message && typeof message === 'object'\n ? message.copyContent ?? message.content ?? ''\n : message ?? '';\n\n navigator.clipboard.writeText(text);\n },\n 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 itemId = this.getItemId();\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\", itemId, subject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n this.updateMicButton();\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n });\n },\n stopRecording() {\n if (!this.isRecording || !this.mediaRecorder) {\n return;\n }\n\n this.mediaRecorder.stop();\n this.isRecording = false;\n this.updateMicButton();\n },\n toggleRecording() {\n if (this.isRecording) {\n this.stopRecording();\n } else {\n this.startRecording();\n }\n },\n updateMicButton() {\n if (!this.micButton) {\n return;\n }\n\n if (this.isRecording) {\n this.micButton.classList.add('stt-recording');\n this.micButton.innerHTML = '<span class=\"fa-solid fa-stop\"></span>';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '<span class=\"fa-solid fa-microphone\"></span>';\n }\n }\n },\n watch: {\n isPlayingAudio() {\n // Reserved for future use — volume-based interrupt detection\n // no longer mutes tracks; browser echo cancellation handles echo.\n },\n isConversationMode(active) {\n if (this.micButton) {\n this.micButton.style.display = active ? 'none' : (this.speechToTextEnabled ? '' : 'none');\n }\n\n if (this.buttonElement) {\n this.buttonElement.style.display = active ? 'none' : '';\n }\n\n if (this.inputElement) {\n this.inputElement.disabled = active;\n if (active) {\n this.inputElement.placeholder = '';\n }\n }\n }\n },\n mounted() {\n (async () => {\n await this.startConnection();\n this.initializeApp();\n })();\n\n window.addEventListener('beforeunload', this.handleBeforeUnload);\n window.addEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n },\n beforeUnmount() {\n window.removeEventListener('beforeunload', this.handleBeforeUnload);\n window.removeEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n\n this.stopAudio(false);\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n if (this.connection) {\n this.connection.stop();\n }\n },\n template: config.messageTemplate\n }).mount(config.appElementSelector);\n\n return app;\n };\n\n return {\n initialize: initialize\n };\n}();\n\nwindow.chatInteractionDocumentManager = function () {\n const managerStateKey = '__chatInteractionDocumentManagerState';\n\n function normalizeDocumentInfo(document) {\n if (!document || typeof document !== 'object') {\n return null;\n }\n\n return {\n documentId: document.documentId || document.DocumentId || '',\n fileName: document.fileName || document.FileName || '',\n fileSize: document.fileSize || document.FileSize || 0\n };\n }\n\n function formatFileSize(bytes) {\n if (!bytes || bytes < 1024) {\n return (bytes || 0) + ' B';\n }\n\n if (bytes < 1024 * 1024) {\n return (bytes / 1024).toFixed(1) + ' KB';\n }\n\n return (bytes / (1024 * 1024)).toFixed(1) + ' MB';\n }\n\n function getDocumentKey(fileName, fileSize) {\n return ((fileName || '').trim().toLowerCase()) + '::' + (fileSize || 0);\n }\n\n function isDuplicateFile(file, knownKeys) {\n return knownKeys.has(getDocumentKey(file.name, file.size));\n }\n\n function getDocumentsFromDom(container) {\n if (!container) {\n return [];\n }\n\n return Array.from(container.querySelectorAll('[data-chat-document-id]'))\n .map(element => normalizeDocumentInfo({\n documentId: element.dataset.chatDocumentId,\n fileName: element.dataset.chatDocumentName,\n fileSize: Number(element.dataset.chatDocumentSize || 0)\n }))\n .filter(document => document && document.documentId);\n }\n\n function initialize(config) {\n if (!config || !config.itemId) {\n return;\n }\n\n const fileInput = document.getElementById('chat-doc-upload');\n const documentsList = document.getElementById('chat-documents-list');\n const status = document.getElementById('chat-doc-upload-status');\n const progressContainer = document.getElementById('chat-doc-upload-progress');\n const progressBar = document.getElementById('chat-doc-upload-progress-bar');\n const uploadQueue = document.getElementById('chat-doc-upload-queue');\n\n if (!fileInput || !documentsList || !status || !progressContainer || !progressBar || !uploadQueue) {\n return;\n }\n\n const previousState = fileInput[managerStateKey];\n if (previousState && typeof previousState.dispose === 'function') {\n previousState.dispose();\n }\n\n let interactionDocuments = (Array.isArray(config.existingDocuments) ? config.existingDocuments : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n\n if (interactionDocuments.length === 0) {\n interactionDocuments = getDocumentsFromDom(documentsList);\n }\n\n let uploadItems = [];\n let isUploadingDocuments = false;\n\n function createTextElement(tagName, className, text) {\n const element = document.createElement(tagName);\n if (className) {\n element.className = className;\n }\n\n element.textContent = text;\n return element;\n }\n\n function renderDocuments() {\n documentsList.innerHTML = '';\n\n if (interactionDocuments.length === 0) {\n documentsList.appendChild(createTextElement('div', 'text-muted small', 'No documents uploaded yet.'));\n return;\n }\n\n interactionDocuments.forEach(documentInfo => {\n const row = window.document.createElement('div');\n row.className = 'd-flex justify-content-between align-items-start gap-2 border rounded px-2 py-2 bg-white chat-document-row';\n row.dataset.chatDocumentId = documentInfo.documentId;\n row.dataset.chatDocumentName = documentInfo.fileName;\n row.dataset.chatDocumentSize = documentInfo.fileSize;\n\n const details = window.document.createElement('div');\n details.className = 'me-2 min-w-0';\n\n const name = createTextElement('div', 'fw-semibold small', documentInfo.fileName || 'Document');\n const icon = window.document.createElement('i');\n icon.className = 'bi bi-file-earmark-text me-1';\n name.prepend(icon);\n\n const size = createTextElement('div', 'text-muted small', formatFileSize(documentInfo.fileSize));\n\n details.appendChild(name);\n details.appendChild(size);\n\n const removeButton = createTextElement('button', 'btn btn-sm btn-outline-danger remove-chat-document-btn', ' Remove');\n removeButton.type = 'button';\n removeButton.dataset.documentId = documentInfo.documentId;\n const removeIcon = window.document.createElement('i');\n removeIcon.className = 'bi bi-trash';\n removeButton.prepend(removeIcon);\n removeButton.addEventListener('click', () => removeDocument(documentInfo.documentId));\n\n row.appendChild(details);\n row.appendChild(removeButton);\n documentsList.appendChild(row);\n });\n }\n\n function showUploadStatus(message, cssClass) {\n if (!message) {\n status.textContent = '';\n status.className = 'small mt-2 d-none';\n return;\n }\n\n status.textContent = message;\n status.className = 'small mt-2 ' + (cssClass || 'text-muted');\n }\n\n function showUploadProgress(progress, message, cssClass) {\n if (progress === null || progress === undefined) {\n progressContainer.className = 'progress mt-2 d-none';\n progressContainer.setAttribute('aria-valuenow', '0');\n progressBar.className = 'progress-bar progress-bar-striped progress-bar-animated';\n progressBar.style.width = '0%';\n progressBar.textContent = '0%';\n return;\n }\n\n const roundedProgress = Math.max(0, Math.min(100, Math.round(progress)));\n progressContainer.className = 'progress mt-2';\n progressContainer.setAttribute('aria-valuenow', roundedProgress.toString());\n progressBar.className = 'progress-bar ' + (cssClass || 'progress-bar-striped progress-bar-animated');\n progressBar.style.width = roundedProgress + '%';\n progressBar.textContent = message || (roundedProgress + '%');\n }\n\n function getUploadStatePresentation(state) {\n switch (state) {\n case 'uploaded':\n return { label: 'Uploaded', badgeClass: 'text-bg-success', progressClass: 'bg-success' };\n case 'failed':\n return { label: 'Failed', badgeClass: 'text-bg-danger', progressClass: 'bg-danger' };\n case 'uploading':\n return { label: 'Uploading', badgeClass: 'text-bg-warning', progressClass: 'bg-warning progress-bar-striped progress-bar-animated' };\n default:\n return { label: 'Queued', badgeClass: 'text-bg-secondary', progressClass: 'bg-secondary progress-bar-striped progress-bar-animated' };\n }\n }\n\n function formatUploadMessage(item) {\n if (item.status === 'failed' && item.error) {\n return item.error;\n }\n\n if (item.status === 'uploaded') {\n return 'Upload completed successfully.';\n }\n\n if (item.status === 'uploading') {\n return item.progress + '% uploaded';\n }\n\n return 'Waiting to upload...';\n }\n\n function renderUploadQueue() {\n uploadQueue.innerHTML = '';\n\n uploadItems.forEach(item => {\n const presentation = getUploadStatePresentation(item.status);\n const card = document.createElement('div');\n card.className = 'border rounded px-2 py-2 bg-white';\n\n const header = document.createElement('div');\n header.className = 'd-flex justify-content-between align-items-start gap-2';\n\n const fileDetails = document.createElement('div');\n fileDetails.className = 'flex-grow-1 min-w-0';\n fileDetails.appendChild(createTextElement('div', 'fw-semibold small', item.fileName));\n fileDetails.appendChild(createTextElement('div', 'text-muted small', formatFileSize(item.fileSize)));\n\n const badge = createTextElement('span', 'badge ' + presentation.badgeClass, presentation.label);\n\n header.appendChild(fileDetails);\n header.appendChild(badge);\n\n const progress = document.createElement('div');\n progress.className = 'progress mt-2';\n progress.setAttribute('role', 'progressbar');\n progress.setAttribute('aria-valuemin', '0');\n progress.setAttribute('aria-valuemax', '100');\n progress.setAttribute('aria-valuenow', item.progress.toString());\n\n const progressState = document.createElement('div');\n progressState.className = 'progress-bar ' + presentation.progressClass;\n progressState.style.width = item.progress + '%';\n progressState.textContent = item.progress + '%';\n progress.appendChild(progressState);\n\n const message = createTextElement('div', item.status === 'failed' ? 'small text-danger mt-2' : 'small text-muted mt-2', formatUploadMessage(item));\n\n card.appendChild(header);\n card.appendChild(progress);\n card.appendChild(message);\n uploadQueue.appendChild(card);\n });\n }\n\n function createUploadItem(file, index) {\n return {\n id: file.name + '::' + file.size + '::' + file.lastModified + '::' + index + '::' + Date.now(),\n fileName: file.name,\n fileSize: file.size,\n status: 'queued',\n progress: 0,\n error: null\n };\n }\n\n function updateUploadItem(itemId, updates) {\n uploadItems = uploadItems.map(item => item.id === itemId ? Object.assign({}, item, updates) : item);\n renderUploadQueue();\n }\n\n function removeUploadItems(predicate) {\n uploadItems = uploadItems.filter(item => !predicate(item));\n renderUploadQueue();\n }\n\n function uploadSingleDocument(file, itemIdToUpdate, fileIndex, totalFiles) {\n return new Promise((resolve, reject) => {\n const formData = new FormData();\n formData.append('chatInteractionId', config.itemId);\n formData.append('files', file);\n\n const xhr = new XMLHttpRequest();\n xhr.open('POST', config.uploadDocumentUrl, true);\n\n xhr.upload.addEventListener('progress', event => {\n if (!event.lengthComputable) {\n return;\n }\n\n const fileProgress = Math.round((event.loaded / event.total) * 100);\n updateUploadItem(itemIdToUpdate, {\n status: 'uploading',\n progress: fileProgress\n });\n\n const overallProgress = ((fileIndex + (event.loaded / event.total)) / totalFiles) * 100;\n showUploadProgress(overallProgress, 'Uploading ' + (fileIndex + 1) + ' of ' + totalFiles, 'progress-bar-striped progress-bar-animated');\n });\n\n xhr.addEventListener('load', () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n try {\n resolve(JSON.parse(xhr.responseText));\n } catch (error) {\n reject(new Error('Upload failed: invalid server response.'));\n }\n\n return;\n }\n\n reject(new Error((xhr.responseText || 'Upload failed.').trim()));\n });\n\n xhr.addEventListener('error', () => {\n reject(new Error('Upload failed. Please check your connection and try again.'));\n });\n\n xhr.send(formData);\n });\n }\n\n async function uploadDocuments(files) {\n if (!config.uploadDocumentUrl || !files || files.length === 0) {\n return;\n }\n\n if (isUploadingDocuments) {\n showUploadStatus('A document upload is already in progress.', 'text-warning');\n return;\n }\n\n isUploadingDocuments = true;\n\n const filesToUpload = [];\n const duplicateItems = [];\n const knownDocumentKeys = new Set(interactionDocuments.map(document => getDocumentKey(document.fileName, document.fileSize)));\n\n Array.from(files).forEach(file => {\n if (isDuplicateFile(file, knownDocumentKeys)) {\n duplicateItems.push(file);\n return;\n }\n\n knownDocumentKeys.add(getDocumentKey(file.name, file.size));\n filesToUpload.push(file);\n });\n\n if (duplicateItems.length > 0) {\n uploadItems = uploadItems.concat(duplicateItems.map((file, index) => Object.assign(createUploadItem(file, index), {\n status: 'failed',\n progress: 100,\n error: 'This document is already attached.'\n })));\n renderUploadQueue();\n }\n\n if (filesToUpload.length === 0) {\n isUploadingDocuments = false;\n showUploadStatus(duplicateItems.map(file => file.name + ': This document is already attached.').join(' | '), 'text-warning');\n showUploadProgress(null);\n return;\n }\n\n const pendingItems = filesToUpload.map(createUploadItem);\n uploadItems = uploadItems.concat(pendingItems);\n renderUploadQueue();\n showUploadProgress(0, 'Preparing upload...', 'progress-bar-striped progress-bar-animated');\n fileInput.disabled = true;\n\n try {\n let uploadedCount = 0;\n const failedUploads = duplicateItems.map(file => file.name + ': This document is already attached.');\n\n for (let i = 0; i < filesToUpload.length; i++) {\n const file = filesToUpload[i];\n const pendingItem = pendingItems[i];\n\n updateUploadItem(pendingItem.id, {\n status: 'uploading',\n progress: 0,\n error: null\n });\n\n showUploadStatus('Uploading ' + (i + 1) + ' of ' + filesToUpload.length + ' document(s)...', 'text-warning');\n\n try {\n const result = await uploadSingleDocument(file, pendingItem.id, i, filesToUpload.length);\n const uploaded = (Array.isArray(result.uploaded) ? result.uploaded : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n const failed = Array.isArray(result.failed) ? result.failed : [];\n\n if (uploaded.length > 0) {\n uploadedCount += uploaded.length;\n interactionDocuments = interactionDocuments.concat(uploaded);\n updateUploadItem(pendingItem.id, {\n status: 'uploaded',\n progress: 100,\n error: null\n });\n } else {\n const missingUploadMessage = failed.length > 0\n ? failed.map(entry => entry.fileName + ': ' + entry.error).join(' | ')\n : 'The server did not confirm that the file was uploaded.';\n if (failed.length === 0) {\n failedUploads.push(missingUploadMessage);\n }\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: 100,\n error: missingUploadMessage\n });\n }\n\n if (failed.length > 0) {\n const failedMessage = failed.map(entry => entry.fileName + ': ' + entry.error).join(' | ');\n failedUploads.push(failedMessage);\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: 100,\n error: failedMessage\n });\n }\n } catch (error) {\n const errorMessage = error && error.message\n ? error.message\n : 'Upload failed. Please try again.';\n console.error('Upload failed:', error);\n failedUploads.push(file.name + ': ' + errorMessage);\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: pendingItem.progress || 0,\n error: errorMessage\n });\n }\n }\n\n renderDocuments();\n\n if (failedUploads.length > 0) {\n removeUploadItems(item => item.status === 'uploaded');\n showUploadStatus(\n (uploadedCount > 0 ? ('Uploaded ' + uploadedCount + ' document(s). ') : '') + failedUploads.join(' | '),\n uploadedCount > 0 ? 'text-warning' : 'text-danger');\n showUploadProgress(null);\n return;\n }\n\n removeUploadItems(() => true);\n showUploadStatus('Uploaded ' + uploadedCount + ' document(s).', 'text-success');\n showUploadProgress(null);\n } catch (error) {\n console.error('Upload failed:', error);\n showUploadStatus('Upload failed. Please try again.', 'text-danger');\n showUploadProgress(null);\n } finally {\n isUploadingDocuments = false;\n fileInput.disabled = false;\n fileInput.value = '';\n }\n }\n\n async function removeDocument(documentId) {\n if (!config.removeDocumentUrl || !documentId || !window.confirm('Remove this document?')) {\n return;\n }\n\n try {\n const response = await fetch(config.removeDocumentUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n itemId: config.itemId,\n documentId: documentId\n })\n });\n\n if (!response.ok) {\n console.error('Failed to remove document:', await response.text());\n showUploadStatus('Failed to remove document.', 'text-danger');\n return;\n }\n\n const result = await response.json();\n const serverDocuments = (Array.isArray(result.documents) ? result.documents : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n\n interactionDocuments = serverDocuments.length > 0\n ? serverDocuments\n : interactionDocuments.filter(document => document.documentId !== documentId);\n renderDocuments();\n showUploadStatus('Document removed.', 'text-success');\n } catch (error) {\n console.error('Remove failed:', error);\n showUploadStatus('Failed to remove document.', 'text-danger');\n }\n }\n\n const onFileInputChange = event => {\n const selectedFiles = event.target.files ? Array.from(event.target.files) : [];\n uploadDocuments(selectedFiles);\n };\n\n fileInput.addEventListener('change', onFileInputChange);\n fileInput[managerStateKey] = {\n dispose: () => {\n fileInput.removeEventListener('change', onFileInputChange);\n }\n };\n\n renderDocuments();\n renderUploadQueue();\n showUploadStatus(null);\n showUploadProgress(null);\n }\n\n return {\n initialize: initialize\n };\n}();\n\n// Download chart as image via event delegation (DOMPurify strips inline onclick).\ndocument.addEventListener('click', function (e) {\n const btn = e.target.closest('.download-chart-btn');\n if (!btn) {\n return;\n }\n const chartId = btn.getAttribute('data-chart-id');\n const canvas = chartId ? document.getElementById(chartId) : null;\n if (!canvas) {\n console.error('Chart canvas not found:', chartId);\n return;\n }\n const link = document.createElement('a');\n link.download = 'chart-' + chartId + '.png';\n link.href = canvas.toDataURL('image/png');\n link.click();\n});\n\n// Intercept download clicks for data-URI images and convert to blob downloads.\ndocument.addEventListener('click', function (e) {\n const link = e.target.closest('.ai-download-image');\n if (!link) {\n return;\n }\n\n const container = link.closest('.generated-image-container');\n const img = container?.querySelector('img');\n if (!img) {\n return;\n }\n\n const src = img.src;\n if (!src || !src.startsWith('data:')) {\n return; // Normal URL – let the default <a> behaviour handle it.\n }\n\n e.preventDefault();\n\n fetch(src)\n .then(function (res) { return res.blob(); })\n .then(function (blob) {\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = link.getAttribute('download') || 'generated-image.png';\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n setTimeout(function () { URL.revokeObjectURL(url); }, 100);\n })\n .catch(function (err) { console.error('Failed to download image:', err); });\n});\n\n"]}
1
+ {"version":3,"sources":["chat-interaction.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","chatInteractionManager","defaultConfig","generatedImageAltText","generatedImageMaxWidth","downloadImageTitle","downloadChartTitle","downloadChartButtonText","codeCopiedText","assistantLabel","messageTemplate","indicatorTemplate","untitledText","clearHistoryTitle","clearHistoryMessage","clearHistoryOkText","clearHistoryCancelText","sanitizeUrl","url","trimmed","trim","escapeHtmlEntities","text","span","document","createElement","textContent","innerHTML","normalizeReference","reference","_ref","_normalized$index","_ref2","_normalized$text","_ref3","_normalized$title","_ref4","_normalized$link","_ref5","_normalized$reference","normalized","assign","index","Index","Text","title","Title","link","Link","referenceType","ReferenceType","isDownloadCitationReference","toLowerCase","normalizeReferences","references","_i","_Object$entries","entries","_normalizeReference","_Object$entries$_i","key","getCitationLabel","updateMessagePresentation","message","messageReferences","rawContent","content","citationDisplay","processedContent","keys","citations","citedRefs","filter","_ref6","includes","sort","_ref8","_ref9","b","_step","displayIndex","_iterator","_step$value","placeholder","concat","replaceAll","referenceKey","label","isDownload","err","_i2","_citations","citation","map","_ref10","buildCitationDisplay","displayContent","citationReferences","copyContent","_step2","_iterator2","_step3","_iterator3","trimEnd","buildCopyContent","htmlContent","parseMarkdownContent","renderer","marked","Renderer","data","href","code","lang","highlighted","hljs","getLanguage","highlight","language","_","highlightAuto","langDisplay","image","src","alt","maxWidth","chartCounter","_pendingCharts","renderChartsInMessage","charts","requestAnimationFrame","_step4","_iterator4","canvas","getElementById","chartId","Chart","offsetParent","_cfg$options","_cfg$options2","_cfg$options2$aspectR","_chartInstance","destroy","cfg","config","JSON","parse","options","responsive","maintainAspectRatio","aspectRatio","console","error","__chartConfigs","warn","html","DOMPurify","sanitize","ADD_TAGS","ADD_ATTR","use","extensions","level","start","idx","undefined","tokenizer","extracted","token","jsonStart","depth","inString","escape","ch","jsonEnd","closeBracketIndex","startIndex","endIndex","json","substring","tryExtractChartMarker","type","raw","initialize","instanceConfig","signalRHubUrl","appElementSelector","chatContainerElementSelector","inputElementSelector","sendButtonElementSelector","Vue","createApp","inputElement","buttonElement","chatContainer","isInteractionStarted","isPlaceholderVisible","isStreaming","isNavigatingAway","autoScroll","stream","messages","prompt","initialFieldValues","Map","settingsDirty","saveSettingsTimeout","saveIndicatorTimeout","isRecording","mediaRecorder","preRecordingPrompt","micButton","speechToTextEnabled","chatMode","textToSpeechEnabled","ttsVoiceName","audioChunks","audioPlayQueue","isPlayingAudio","currentAudioElement","currentAudioUrl","ttsPlayingMessageIndex","ttsAudioCache","ttsInstanceId","Math","random","conversationModeEnabled","conversationButton","isConversationMode","notifications","notificationDismissTimers","computed","lastAssistantIndex","role","methods","handleBeforeUnload","startConnection","_this","_callee","_t","_context","connection","signalR","HubConnectionBuilder","withUrl","withAutomaticReconnect","build","serverTimeoutInMilliseconds","keepAliveIntervalInMilliseconds","on","_data$messages","initializeInteraction","itemId","titleInput","querySelector","forEach","msg","addMessage","$nextTick","historyItem","showSaveIndicator","stopRecording","isFinal","_conversationPartialTranscript","replace","_conversationPartialMessage","hidePlaceholder","isPartial","scrollToBottom","_audioInputSent","dispatchEvent","Event","stopAudio","_conversationAssistantMessage","oldMsg","escaped","messageId","responseId","appearance","hideTypingIndicator","j","msgIndex","newMessage","id","normalizeAssistantAppearance","base64Audio","contentType","binaryString","atob","bytes","Uint8Array","charCodeAt","playCollectedAudio","showPlaceholder","clearHistoryBtn","classList","add","notification","receiveNotification","updateNotification","notificationType","removeNotification","onreconnecting","onreconnected","info","reloadCurrentInteraction","onclose","addMessageInternal","_this2","fireEvent","CustomEvent","detail","_message$rawContent","_this3","remove","event","icon","cssClass","disableStreamingAnimation","getAssistantLabel","getAssistantRoleClasses","classes","getAssistantIconClasses","shouldAnimateAssistantIcon","getAssistantIcon","isIndicator","sendMessage","_this4","_callee2","trimmedPrompt","_context2","flushPendingSave","streamMessage","_this5","dispose","streamingStarted","showTypingIndicator","lastResponseId","messageIndex","currentItemId","getItemId","subscribe","chunk","sessionId","setItemId","_i3","_Object$entries2","_normalizeReference2","_Object$entries2$_i","complete","_this5$stream","processReferences","streamingFinished","synthesizeSpeech","_this5$stream2","getServiceDownMessage","_this6","_ref11","_message$rawContent2","stopIcon","getAttribute","replaceChildren","RETURN_DOM_FRAGMENT","startIcon","icons","querySelectorAll","debouncedSaveSettings","handleExternalTtsStop","_e$detail","sourceId","updateTtsPlaybackButtons","_this7","button","isPlaying","Number","iconHtml","toggle","setAttribute","cacheIndex","_this8","_ttsCacheIndex","invoke","toggleMessageTts","_this9","playAudioBlob","_this0","_step5","totalLength","reduce","sum","combined","offset","_iterator5","set","blob","Blob","_this1","URL","createObjectURL","audio","Audio","addEventListener","revokeObjectURL","playNextInQueue","play","_this10","nextBlob","shift","conversationModeOnAudioEnded","_this11","pause","currentTime","toggleConversationMode","stopConversationMode","startConversationMode","_this12","updateConversationButton","navigator","mediaDevices","getUserMedia","echoCancellation","noiseSuppression","autoGainControl","mimeType","MediaRecorder","isTypeSupported","audioBitsPerSecond","_conversationSubject","Subject","_conversationStream","AudioCtx","AudioContext","webkitAudioContext","_conversationAudioCtx","_conversationAnalyser","createAnalyser","fftSize","createMediaStreamSource","connect","pendingChunk","analyser","size","freqData","frequencyBinCount","getByteFrequencyData","k","_callee3","uint8Array","base64","_context3","arrayBuffer","str","byte","String","fromCharCode","btoa","getTracks","track","stop","documentElement","send","close","dismissible","autoDismissMs","endHtml","blur","startHtml","conversationModeSendPrompt","originalLength","_this13","setTimeout","scrollTop","scrollHeight","clientHeight","handleUserInput","target","getSaveIndicatorElement","saveIndicatorElementSelector","className","_this14","indicator","clearTimeout","clearPendingSettingsSave","getFieldLabel","input","_input$closest","closest","dataset","setting","getValidationFeedbackElement","feedback","nextElementSibling","contains","insertAdjacentElement","clearSettingValidationError","removeAttribute","setSettingValidationError","getSettingValidationMessage","disabled","number","fieldLabel","isNaN","min","max","validateSettingInput","validateSettings","_this15","isValid","getSettingInputs","queueSettingsSave","explicitInputs","getSelectedGroupValues","groupName","fallbackSelector","explicitSelections","values","checkbox","baseName","hiddenInput","getPromptTemplateSelections","promptTemplates","card","templateIdInput","promptParametersInput","templateId","promptParameters","clearNotificationDismiss","findIndex","splice","scheduleNotificationDismiss","_this16","timerId","dismissNotification","handleNotificationAction","actionName","resetInteraction","initializeApp","_this17","placeholderElementSelector","loadInteraction","atBottom","shiftKey","click","lastMsg","pop","chatInteractionItems","getElementsByClassName","preventDefault","btn","block","codeEl","clipboard","writeText","copiedText","matches","clearHistory","micButtonElementSelector","style","display","toggleRecording","conversationButtonElementSelector","self","clearHistoryConfirmed","confirmDialog","confirm","okText","cancelText","callback","confirmed","_this18","saveSettings","getSelectedToolNames","getSelectedMcpConnectionIds","getSelectedA2AConnectionIds","getSelectedAgentNames","_this19","settings","match","checked","parseFloat","toolNames","mcpConnectionIds","a2aConnectionIds","agentNames","promptTemplateIds","template","force","copyResponse","_ref13","_message$copyContent","startRecording","_this20","subject","_callee4","_context4","updateMicButton","watch","active","mounted","_this21","_callee5","_context5","beforeUnmount","removeEventListener","mount","chatInteractionDocumentManager","managerStateKey","normalizeDocumentInfo","documentId","DocumentId","fileName","FileName","fileSize","FileSize","formatFileSize","toFixed","getDocumentKey","isDuplicateFile","file","knownKeys","has","fileInput","documentsList","status","progressContainer","progressBar","uploadQueue","previousState","container","interactionDocuments","existingDocuments","element","chatDocumentId","chatDocumentName","chatDocumentSize","uploadItems","isUploadingDocuments","onFileInputChange","_x","_uploadDocuments","uploadDocuments","files","renderDocuments","renderUploadQueue","showUploadStatus","showUploadProgress","createTextElement","tagName","documentInfo","row","details","prepend","appendChild","removeButton","removeIcon","_x2","_removeDocument","removeDocument","progress","width","roundedProgress","round","item","presentation","state","badgeClass","progressClass","getUploadStatePresentation","header","fileDetails","badge","progressState","formatUploadMessage","createUploadItem","lastModified","Date","now","updateUploadItem","updates","removeUploadItems","predicate","uploadSingleDocument","itemIdToUpdate","fileIndex","totalFiles","reject","formData","FormData","append","xhr","XMLHttpRequest","open","uploadDocumentUrl","upload","lengthComputable","fileProgress","loaded","total","responseText","Error","_callee6","filesToUpload","duplicateItems","knownDocumentKeys","pendingItems","uploadedCount","failedUploads","pendingItem","result","uploaded","failed","missingUploadMessage","failedMessage","errorMessage","_t2","_t3","_context6","Set","join","entry","_callee7","response","serverDocuments","_t4","_t5","_context7","removeDocumentUrl","fetch","method","headers","body","stringify","ok","documents","download","toDataURL","img","startsWith","res","removeChild"],"mappings":"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","file":"chat-interaction.min.js","sourcesContent":["window.chatInteractionManager = 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 codeCopiedText: 'Copied!',\n assistantLabel: 'Assistant',\n\n messageTemplate: `\n <div class=\"ai-chat-messages\">\n <div v-for=\"(message, index) in messages\" :key=\"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\">You</div>\n <div v-else-if=\"message.role !== 'indicator'\" :class=\"getAssistantRoleClasses(message)\">\n <span :class=\"getAssistantIconClasses(message, index)\"><span :class=\"getAssistantIcon(message)\"></span></span>\n {{ getAssistantLabel(message) }}\n </div>\n <div class=\"ai-chat-message-body lh-base\">\n <h4 v-if=\"message.title\">{{ message.title }}</h4>\n <div v-html=\"message.htmlContent\"></div>\n <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 <button v-if=\"textToSpeechEnabled && !isConversationMode && message.role === 'assistant' && !message.isStreaming\" class=\"btn btn-sm btn-link text-secondary p-0 me-1 button-message-toolbox\" :class=\"{ 'tts-playing': ttsPlayingMessageIndex === index }\" :data-tts-message-index=\"index\" @click=\"toggleMessageTts(message, index)\" :title=\"ttsPlayingMessageIndex === index ? 'Pause audio' : 'Read aloud'\">\n <span :class=\"ttsPlayingMessageIndex === index ? 'fa-solid fa-circle-pause' : 'fa-solid fa-circle-play'\"></span>\n </button>\n <button class=\"btn btn-sm btn-link text-secondary p-0 button-message-toolbox\" @click=\"copyResponse(message)\" title=\"Click here to copy response to clipboard.\">\n <span class=\"fa-solid fa-copy\"></span>\n </button>\n </span>\n </div>\n </div>\n </div>\n <div v-for=\"notification in notifications\" :key=\"'notif-' + notification.type\" class=\"ai-chat-notification\" :class=\"'ai-chat-notification-' + (notification.type || 'info') + ' ' + (notification.cssClass || '')\">\n <div class=\"ai-chat-notification-content\">\n <span v-if=\"notification.icon\" :class=\"notification.icon\" class=\"ai-chat-notification-icon\"></span>\n <span class=\"ai-chat-notification-text\">{{ notification.content }}</span>\n <button v-if=\"notification.dismissible\" class=\"btn btn-sm btn-link p-0 ms-2 ai-chat-notification-dismiss\" @click=\"dismissNotification(notification.type)\" title=\"Dismiss\">\n <span class=\"fa-solid fa-xmark\"></span>\n </button>\n </div>\n <div v-if=\"notification.actions && notification.actions.length\" class=\"ai-chat-notification-actions\">\n <button v-for=\"action in notification.actions\" :key=\"action.name\" class=\"btn btn-sm\" :class=\"action.cssClass || 'btn-outline-secondary'\" @click=\"handleNotificationAction(notification.type, action.name)\">\n <span v-if=\"action.icon\" :class=\"action.icon\" class=\"me-1\"></span>\n {{ action.label }}\n </button>\n </div>\n </div>\n </div>\n `,\n indicatorTemplate: `\n <div class=\"ai-chat-msg-role ai-chat-msg-role-assistant\">\n <span class=\"ai-streaming-icon\"><span class=\"fa fa-robot\" style=\"display: inline-block;\"></span></span>\n Assistant\n </div>\n `,\n // Localizable strings\n untitledText: 'Untitled',\n clearHistoryTitle: 'Clear History',\n clearHistoryMessage: 'Are you sure you want to clear the chat history? This action cannot be undone. Your documents, parameters, and tools will be preserved.',\n clearHistoryOkText: 'Yes',\n clearHistoryCancelText: 'Cancel'\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 normalizeReference(reference) {\n if (!reference || typeof reference !== 'object') {\n return null;\n }\n\n const normalized = Object.assign({}, reference);\n normalized.index = normalized.index ?? normalized.Index ?? 0;\n normalized.text = normalized.text ?? normalized.Text ?? null;\n normalized.title = normalized.title ?? normalized.Title ?? null;\n normalized.link = sanitizeUrl(normalized.link ?? normalized.Link ?? null);\n normalized.referenceType = normalized.referenceType ?? normalized.ReferenceType ?? null;\n\n return normalized;\n }\n\n function isDownloadCitationReference(reference) {\n if (!reference || typeof reference !== 'object') {\n return false;\n }\n\n if (typeof reference.referenceType === 'string' && reference.referenceType.toLowerCase() === 'document') {\n return true;\n }\n\n if (typeof reference.link === 'string' && /\\/ai\\/documents\\/.+\\/download(?:$|\\?)/i.test(reference.link)) {\n return true;\n }\n\n return false;\n }\n\n function normalizeReferences(references) {\n if (!references || typeof references !== 'object') {\n return {};\n }\n\n const normalized = {};\n\n for (const [key, value] of Object.entries(references)) {\n normalized[key] = normalizeReference(value) ?? {};\n }\n\n return normalized;\n }\n\n function getCitationLabel(reference, key) {\n return reference.title || reference.text || key;\n }\n\n function buildCitationDisplay(content, references) {\n let processedContent = (content || '').trim();\n const messageReferences = normalizeReferences(references);\n\n if (!processedContent || !Object.keys(messageReferences).length) {\n return { content: processedContent, citations: [] };\n }\n\n const citedRefs = Object.entries(messageReferences).filter(([key]) => processedContent.includes(key));\n\n if (!citedRefs.length) {\n return { content: processedContent, citations: [] };\n }\n\n citedRefs.sort(([, a], [, b]) => a.index - b.index);\n\n const citations = [];\n let displayIndex = 1;\n\n for (const [key, value] of citedRefs) {\n const placeholder = `__CITE_${displayIndex}_${value.index || displayIndex}__`;\n processedContent = processedContent.replaceAll(key, placeholder);\n citations.push({\n referenceKey: key,\n displayIndex: displayIndex,\n label: getCitationLabel(value, key),\n link: value.link || null,\n isDownload: isDownloadCitationReference(value),\n placeholder: placeholder,\n });\n\n displayIndex++;\n }\n\n for (const citation of citations) {\n processedContent = processedContent.replaceAll(citation.placeholder, `<sup>${citation.displayIndex}</sup>`);\n }\n\n processedContent = processedContent.replaceAll('</sup><sup>', '</sup><sup>,</sup><sup>');\n\n return {\n content: processedContent,\n citations: citations.map(({ placeholder, ...citation }) => citation),\n };\n }\n\n function buildCopyContent(content, citations) {\n let copyContent = (content || '').trim();\n\n if (!copyContent || !Array.isArray(citations) || citations.length === 0) {\n return copyContent;\n }\n\n for (const citation of citations) {\n copyContent = copyContent.replaceAll(citation.referenceKey, `[${citation.displayIndex}]`);\n }\n\n copyContent += '\\n\\nReferences:\\n';\n\n for (const citation of citations) {\n copyContent += `${citation.displayIndex}. ${citation.label}`;\n\n if (citation.link) {\n copyContent += ` - ${citation.link}`;\n }\n\n copyContent += '\\n';\n }\n\n return copyContent.trimEnd();\n }\n\n function updateMessagePresentation(message, references) {\n const messageReferences = normalizeReferences(references ?? message.references);\n const rawContent = typeof message.rawContent === 'string'\n ? message.rawContent\n : typeof message.content === 'string'\n ? message.content\n : '';\n const citationDisplay = buildCitationDisplay(rawContent, messageReferences);\n\n message.rawContent = rawContent;\n message.content = rawContent;\n message.displayContent = citationDisplay.content;\n message.references = messageReferences;\n message.citationReferences = citationDisplay.citations;\n message.copyContent = buildCopyContent(rawContent, citationDisplay.citations);\n message.htmlContent = parseMarkdownContent(citationDisplay.content, message);\n\n return message;\n }\n\n const renderer = new marked.Renderer();\n\n // Modify the link rendering to open in a new tab\n renderer.link = function (data) {\n var href = sanitizeUrl(data.href);\n if (!href) return data.text || '';\n return `<a href=\"${href}\" target=\"_blank\" rel=\"noopener noreferrer\">${data.text}</a>`;\n };\n\n // Custom code block renderer with highlight.js integration and copy button.\n renderer.code = function (data) {\n var code = data.text || '';\n var lang = (data.lang || '').trim();\n var highlighted = code;\n\n if (typeof hljs !== 'undefined') {\n if (lang && hljs.getLanguage(lang)) {\n try {\n highlighted = hljs.highlight(code, { language: lang }).value;\n } catch (_) { }\n } else {\n try {\n highlighted = hljs.highlightAuto(code).value;\n } catch (_) { }\n }\n } else {\n highlighted = escapeHtmlEntities(code);\n }\n\n var langDisplay = lang ? escapeHtmlEntities(lang) : 'code';\n return `<div class=\"ai-code-block\"><div class=\"ai-code-header\"><span class=\"ai-code-lang\"><span class=\"fa-solid fa-code\"></span> ${langDisplay}</span><button type=\"button\" class=\"ai-code-copy-btn\" title=\"Copy code\"><span class=\"fa-regular fa-copy\"></span></button></div><pre><code class=\"hljs${lang ? ' language-' + lang : ''}\">${highlighted}</code></pre></div>`;\n };\n\n // Custom image renderer for generated images with thumbnail styling and download button.\n // Handles both URL and data-URI sources (data URIs are converted to blobs for download).\n renderer.image = function (data) {\n const src = sanitizeUrl(data.href);\n if (!src) return '';\n const alt = data.text || defaultConfig.generatedImageAltText;\n const maxWidth = defaultConfig.generatedImageMaxWidth;\n return `<div class=\"generated-image-container\">\n <img src=\"${src}\" alt=\"${alt}\" class=\"img-thumbnail\" style=\"max-width: ${maxWidth}px; height: auto;\" />\n <div class=\"mt-2\">\n <a href=\"${src}\" target=\"_blank\" download=\"${alt}\" title=\"${defaultConfig.downloadImageTitle}\" class=\"btn btn-sm btn-outline-secondary ai-download-image\">\n <span class=\"fa-solid fa-download\"></span>\n </a>\n </div>\n </div>`;\n };\n\n // Chart counter for unique IDs\n let chartCounter = 0;\n\n // Collector for charts discovered during marked parsing.\n let _pendingCharts = [];\n\n // Global chart config map shared with ai-chat.js\n window.__chartConfigs = window.__chartConfigs || {};\n\n function createChartHtml(chartId) {\n return `<div class=\"chart-container\" style=\"position: relative; width: 100%; max-width: 560px; min-height: 420px;\">`\n + `<canvas id=\"${chartId}\"></canvas>`\n + `</div>`\n + `<div class=\"mt-2\">`\n + `<button type=\"button\" class=\"btn btn-sm btn-outline-secondary download-chart-btn\" data-chart-id=\"${chartId}\" title=\"${defaultConfig.downloadChartTitle}\">`\n + `<span class=\"fa-solid fa-download\"></span> ${defaultConfig.downloadChartButtonText}`\n + `</button>`\n + `</div>`;\n }\n\n // Register [chart:{...json...}] as a native marked block extension so the\n // markdown parser handles chart markers inline with surrounding text.\n marked.use({\n extensions: [{\n name: 'chart',\n level: 'block',\n start(src) {\n const idx = src.indexOf('[chart:');\n return idx >= 0 ? idx : undefined;\n },\n tokenizer(src) {\n const extracted = tryExtractChartMarker(src);\n if (!extracted || extracted.startIndex !== 0) {\n return undefined;\n }\n\n const chartId = `chat_chart_${++chartCounter}`;\n\n return {\n type: 'chart',\n raw: src.substring(0, extracted.endIndex),\n chartId: chartId,\n json: extracted.json,\n };\n },\n renderer(token) {\n _pendingCharts.push({ chartId: token.chartId, config: token.json });\n window.__chartConfigs[token.chartId] = token.json;\n return createChartHtml(token.chartId);\n }\n }]\n });\n\n // Extract a [chart:{...json...}] marker. This avoids regex issues with nested brackets.\n function tryExtractChartMarker(text) {\n const token = '[chart:';\n const start = text.indexOf(token);\n if (start < 0) {\n return null;\n }\n\n // Find JSON object boundary by balancing braces\n const jsonStart = start + token.length;\n let i = jsonStart;\n while (i < text.length && (text[i] === ' ' || text[i] === '\\n' || text[i] === '\\r' || text[i] === '\\t')) {\n i++;\n }\n\n if (i >= text.length || text[i] !== '{') {\n return null;\n }\n\n let depth = 0;\n let inString = false;\n let escape = false;\n\n for (; i < text.length; i++) {\n const ch = text[i];\n\n if (inString) {\n if (escape) {\n escape = false;\n continue;\n }\n if (ch === '\\\\') {\n escape = true;\n continue;\n }\n if (ch === '\"') {\n inString = false;\n }\n continue;\n }\n\n if (ch === '\"') {\n inString = true;\n continue;\n }\n\n if (ch === '{') {\n depth++;\n } else if (ch === '}') {\n depth--;\n if (depth === 0) {\n const jsonEnd = i;\n // Expect closing bracket after JSON\n const closeBracketIndex = text.indexOf(']', jsonEnd + 1);\n if (closeBracketIndex < 0) {\n return null;\n }\n\n const json = text.substring(jsonStart, jsonEnd + 1).trim();\n return {\n startIndex: start,\n endIndex: closeBracketIndex + 1,\n json: json\n };\n }\n }\n }\n\n return null;\n }\n\n function renderChartsInMessage(message) {\n if (!message || !message._pendingCharts || !message._pendingCharts.length) {\n return;\n }\n\n // Copy and clear pending charts immediately to prevent duplicate renders.\n const charts = [...message._pendingCharts];\n message._pendingCharts = [];\n\n // Defer to requestAnimationFrame so the browser has fully laid out the\n // canvas elements before Chart.js reads their dimensions.\n requestAnimationFrame(() => {\n for (const c of charts) {\n const canvas = document.getElementById(c.chartId);\n if (!canvas) {\n continue;\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 continue;\n }\n\n // When the canvas is inside a hidden container (e.g., display:none),\n // it has zero dimensions. Keep the config for later rendering.\n if (canvas.offsetParent === null) {\n window.__chartConfigs[c.chartId] = c.config;\n continue;\n }\n\n try {\n // Destroy existing chart instance if re-rendering\n if (canvas._chartInstance) {\n canvas._chartInstance.destroy();\n }\n\n const cfg = typeof c.config === 'string' ? JSON.parse(c.config) : c.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 } catch (e) {\n console.error('Error creating chart:', e);\n }\n }\n });\n }\n\n // Parse markdown content via marked (which natively handles [chart:...] markers\n // through the registered extension) and collect pending chart configs for later\n // Chart.js rendering.\n function parseMarkdownContent(content, message) {\n _pendingCharts = [];\n const html = marked.parse(content, { renderer });\n message._pendingCharts = _pendingCharts.length > 0 ? [..._pendingCharts] : [];\n return DOMPurify.sanitize(html, { ADD_TAGS: ['canvas'], ADD_ATTR: ['target'] });\n }\n\n const initialize = (instanceConfig) => {\n\n const config = Object.assign({}, defaultConfig, instanceConfig);\n // Keep defaultConfig in sync so renderers use overridden values\n defaultConfig = config;\n\n if (!config.signalRHubUrl) {\n console.error('The signalRHubUrl is required.');\n return;\n }\n\n if (!config.appElementSelector) {\n console.error('The appElementSelector is required.');\n return;\n }\n\n if (!config.chatContainerElementSelector) {\n console.error('The chatContainerElementSelector is required.');\n return;\n }\n\n if (!config.inputElementSelector) {\n console.error('The inputElementSelector is required.');\n return;\n }\n\n if (!config.sendButtonElementSelector) {\n console.error('The sendButtonElementSelector is required.');\n return;\n }\n\n const app = Vue.createApp({\n data() {\n return {\n inputElement: null,\n buttonElement: null,\n chatContainer: null,\n placeholder: null,\n isInteractionStarted: false,\n isPlaceholderVisible: true,\n isStreaming: false,\n isNavigatingAway: false,\n autoScroll: true,\n stream: null,\n messages: [],\n prompt: '',\n initialFieldValues: new Map(),\n settingsDirty: false,\n saveSettingsTimeout: null,\n saveIndicatorTimeout: null,\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 ttsPlayingMessageIndex: -1,\n ttsAudioCache: {},\n ttsInstanceId: 'chat-interaction-' + Math.random().toString(36).slice(2),\n conversationModeEnabled: config.chatMode === 'Conversation',\n conversationButton: null,\n isConversationMode: false,\n notifications: [],\n notificationDismissTimers: {},\n };\n },\n computed: {\n lastAssistantIndex() {\n for (var i = this.messages.length - 1; i >= 0; i--) {\n if (this.messages[i].role === 'assistant') {\n return i;\n }\n }\n return -1;\n }\n },\n methods: {\n handleBeforeUnload() {\n this.isNavigatingAway = true;\n },\n 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(\"LoadInteraction\", (data) => {\n this.initializeInteraction(data.itemId, true);\n this.messages = [];// Update the title field if it exists\n const titleInput = document.querySelector('[data-chat-interaction-title], .setting-input[data-setting=\"title\"], input[name=\"ChatInteraction.Title\"], input[name=\"Title\"]');\n if (titleInput && data.title) {\n titleInput.value = data.title;\n }\n\n (data.messages ?? []).forEach(msg => {\n this.addMessage(msg);\n\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n });\n });\n });\n\n this.connection.on(\"SettingsSaved\", (itemId, title) => {\n // Update the history list item if it exists\n // Use a more specific selector to only target history list items, not other elements like the Clear History button\n const historyItem = document.querySelector(`.chat-interaction-history-item[data-interaction-id=\"${itemId}\"]`);\n if (historyItem) {\n historyItem.textContent = title || config.untitledText;\n }\n\n const titleInput = document.querySelector('[data-chat-interaction-title], .setting-input[data-setting=\"title\"], input[name=\"ChatInteraction.Title\"], input[name=\"Title\"]');\n if (titleInput && title) {\n titleInput.value = title;\n }\n\n this.showSaveIndicator('Saved', 'text-success');\n });\n\n this.connection.on(\"ReceiveError\", (error) => {\n console.error(\"SignalR Error: \", error);\n this.showSaveIndicator('Save failed', 'text-danger');\n\n if (this.isRecording) {\n this.stopRecording();\n }\n });\n\n this.connection.on(\"ReceiveTranscript\", (itemId, text, isFinal) => {\n if (this.isConversationMode) {\n if (!isFinal && text) {\n this._conversationPartialTranscript = text;\n var escaped = text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n var html = '<p class=\"ai-partial-transcript\">' + escaped + '</p>';\n\n // Show partial transcript as a live user message.\n if (!this._conversationPartialMessage) {\n this.hidePlaceholder();\n this._conversationPartialMessage = {\n role: 'user',\n content: text,\n htmlContent: html,\n isPartial: true\n };\n this.messages.push(this._conversationPartialMessage);\n } else {\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = html;\n }\n this.scrollToBottom();\n }\n return;\n }\n\n if (text && !this._audioInputSent) {\n this.prompt = this.preRecordingPrompt + text;\n if (this.inputElement) {\n this.inputElement.value = this.prompt;\n this.inputElement.dispatchEvent(new Event('input'));\n }\n }\n });\n\n this.connection.on(\"ReceiveConversationUserMessage\", (itemId, text) => {\n if (text) {\n this.stopAudio();\n\n // If there's an interrupted assistant message still streaming,\n // mark it as done to stop the spinner animation.\n if (this._conversationAssistantMessage) {\n var oldMsg = this.messages[this._conversationAssistantMessage.index];\n if (oldMsg) {\n oldMsg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Replace the partial transcript message with the final one.\n if (this._conversationPartialMessage) {\n var escaped = text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = '<p>' + escaped + '</p>';\n this._conversationPartialMessage.isPartial = false;\n this._conversationPartialMessage = null;\n } else {\n this.addMessage({\n role: 'user',\n content: text\n });\n }\n this.scrollToBottom();\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantToken\", (itemId, 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 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\", (itemId, 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\", (itemId, 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\", (itemId) => {\n this.playCollectedAudio();\n });\n\n this.connection.on(\"HistoryCleared\", (itemId) => {\n // Clear messages and show placeholder\n this.messages = [];\n this.showPlaceholder();\n\n // Hide the clear history button since there's no history now\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.classList.add('d-none');\n }\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 this.reloadCurrentInteraction();\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(\"addingChatInteractionMessage\", { detail: { message: message } }));\n this.messages.push(message);\n\n this.$nextTick(() => {\n this.fireEvent(new CustomEvent(\"addedChatInteractionMessage\", { detail: { message: message } }));\n });\n },\n addMessage(message) {\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 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 fireEvent(event) {\n document.dispatchEvent(event);\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 : defaultConfig.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 isIndicator(message) {\n return message.role === 'indicator';\n },\n async sendMessage() {\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 // Flush any pending settings save before sending a message\n // to prevent concurrent hub calls that can cause database deadlocks.\n await this.flushPendingSave();\n\n this.addMessage({\n role: 'user',\n content: trimmedPrompt\n });\n\n // Show the clear history button since we now have prompts\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.classList.remove('d-none');\n }\n\n this.streamMessage(trimmedPrompt);\n this.inputElement.value = '';\n this.prompt = '';\n },\n streamMessage(trimmedPrompt) {\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 var messageIndex = this.messages.length;\n var currentItemId = this.getItemId();\n\n this.stream = this.connection.stream(\"SendMessage\", currentItemId, trimmedPrompt)\n .subscribe({\n next: (chunk) => {\n let message = this.messages[messageIndex];\n\n if (!message) {\n if (chunk.sessionId && !currentItemId) {\n this.setItemId(chunk.sessionId);\n }\n\n this.hideTypingIndicator();\n messageIndex = this.messages.length;\n let newMessage = {\n role: \"assistant\",\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n };\n\n this.messages.push(newMessage);\n message = newMessage;\n }\n\n if (chunk.references && typeof chunk.references === \"object\" && Object.keys(chunk.references).length) {\n for (const [key, value] of Object.entries(chunk.references)) {\n references[key] = normalizeReference(value) ?? {};\n }\n }\n\n if (chunk.content) {\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 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 return {\n role: \"assistant\",\n content: \"Our service is currently unavailable. Please try again later. We apologize for the inconvenience.\",\n htmlContent: \"\",\n };\n },\n processReferences(references, messageIndex) {\n references = normalizeReferences(references);\n\n if (Object.keys(references).length) {\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 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 // 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 // Save any settings that were deferred during streaming.\n if (this.settingsDirty) {\n this.debouncedSaveSettings();\n }\n },\n handleExternalTtsStop(e) {\n if (e?.detail?.sourceId === this.ttsInstanceId) {\n return;\n }\n\n this.stopAudio(false);\n },\n updateTtsPlaybackButtons() {\n if (!this.chatContainer) {\n return;\n }\n\n var buttons = this.chatContainer.querySelectorAll('[data-tts-message-index]');\n\n buttons.forEach(button => {\n var buttonIndex = Number(button.getAttribute('data-tts-message-index'));\n var isPlaying = buttonIndex === this.ttsPlayingMessageIndex;\n var iconHtml = isPlaying\n ? '<span class=\"fa-solid fa-circle-pause\"></span>'\n : '<span class=\"fa-solid fa-circle-play\"></span>';\n\n button.classList.toggle('tts-playing', isPlaying);\n button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\n });\n },\n synthesizeSpeech(text, cacheIndex) {\n if (!this.textToSpeechEnabled || !text || !this.connection) {\n return;\n }\n\n this.audioChunks = [];\n this.isPlayingAudio = true;\n this._ttsCacheIndex = cacheIndex !== undefined ? cacheIndex : -1;\n\n this.connection.invoke(\"SynthesizeSpeech\", this.getItemId(), 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.isPlayingAudio && 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 currently playing, queue this blob for later.\n if (this.isPlayingAudio && 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 const 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\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 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 itemId = this.getItemId();\n\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"StartConversation\", itemId, 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, continuation is handled\n // by the persistent stream.\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 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 getItemId() {\n return this.inputElement.getAttribute('data-interaction-id')\n || this.inputElement.getAttribute('data-item-id');\n },\n getSaveIndicatorElement() {\n if (config.saveIndicatorElementSelector) {\n return document.querySelector(config.saveIndicatorElementSelector);\n }\n\n return document.querySelector('[data-chat-interaction-save-indicator]');\n },\n showSaveIndicator(text, className) {\n const indicator = this.getSaveIndicatorElement();\n if (!indicator) {\n return;\n }\n\n indicator.textContent = text || '';\n indicator.className = 'settings-save-indicator ' + (className || 'text-muted');\n\n if (this.saveIndicatorTimeout) {\n clearTimeout(this.saveIndicatorTimeout);\n this.saveIndicatorTimeout = null;\n }\n\n if (!text) {\n return;\n }\n\n this.saveIndicatorTimeout = setTimeout(() => {\n indicator.textContent = '';\n this.saveIndicatorTimeout = null;\n }, 3000);\n },\n clearPendingSettingsSave() {\n if (this.saveSettingsTimeout) {\n clearTimeout(this.saveSettingsTimeout);\n this.saveSettingsTimeout = null;\n }\n },\n getFieldLabel(input) {\n const label = input\n .closest('.mb-3, .col-6, .col, .form-group, .form-floating')\n ?.querySelector('label');\n\n if (!label) {\n return input.dataset.setting || 'This field';\n }\n\n return (label.textContent || '')\n .replace(/\\s+/g, ' ')\n .trim()\n || input.dataset.setting\n || 'This field';\n },\n getValidationFeedbackElement(input) {\n let feedback = input.nextElementSibling;\n if (feedback && feedback.classList.contains('invalid-feedback')) {\n return feedback;\n }\n\n feedback = document.createElement('div');\n feedback.className = 'invalid-feedback';\n input.insertAdjacentElement('afterend', feedback);\n\n return feedback;\n },\n clearSettingValidationError(input) {\n input.classList.remove('is-invalid');\n input.removeAttribute('aria-invalid');\n\n const feedback = input.nextElementSibling;\n if (feedback && feedback.classList.contains('invalid-feedback')) {\n feedback.textContent = '';\n }\n },\n setSettingValidationError(input, message) {\n const feedback = this.getValidationFeedbackElement(input);\n input.classList.add('is-invalid');\n input.setAttribute('aria-invalid', 'true');\n feedback.textContent = message;\n },\n getSettingValidationMessage(input) {\n if (!input || input.disabled || input.type !== 'number') {\n return null;\n }\n\n const value = (input.value || '').trim();\n if (!value) {\n return null;\n }\n\n const number = Number(value);\n const fieldLabel = this.getFieldLabel(input);\n\n if (Number.isNaN(number)) {\n return `${fieldLabel} must be a valid number.`;\n }\n\n const min = input.getAttribute('min');\n if (min !== null && number < Number(min)) {\n return `${fieldLabel} must be ${min} or greater.`;\n }\n\n const max = input.getAttribute('max');\n if (max !== null && number > Number(max)) {\n return `${fieldLabel} must be ${max} or less.`;\n }\n\n return null;\n },\n validateSettingInput(input) {\n const message = this.getSettingValidationMessage(input);\n if (!message) {\n this.clearSettingValidationError(input);\n return true;\n }\n\n this.setSettingValidationError(input, message);\n return false;\n },\n validateSettings() {\n let isValid = true;\n\n this.getSettingInputs().forEach(input => {\n isValid = this.validateSettingInput(input) && isValid;\n });\n\n return isValid;\n },\n queueSettingsSave() {\n if (!this.validateSettings()) {\n this.clearPendingSettingsSave();\n this.settingsDirty = false;\n this.showSaveIndicator('Fix errors', 'text-danger');\n return;\n }\n\n this.settingsDirty = true;\n this.showSaveIndicator('Saving...', 'text-warning');\n this.debouncedSaveSettings();\n },\n getSettingInputs() {\n const explicitInputs = document.querySelectorAll('.setting-input[data-setting]');\n if (explicitInputs.length > 0) {\n return explicitInputs;\n }\n\n return document.querySelectorAll(\n 'input[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"]), ' +\n 'select[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"]), ' +\n 'textarea[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"])'\n );\n },\n getSelectedGroupValues(groupName, fallbackSelector) {\n const explicitSelections = document.querySelectorAll(`.capability-checkbox[data-save-group=\"${groupName}\"]:checked, .capability-checkbox[data-group=\"${groupName}\"]:checked`);\n if (explicitSelections.length > 0) {\n const values = [];\n\n explicitSelections.forEach(checkbox => {\n const value = checkbox.getAttribute('data-item-id') || checkbox.value;\n if (value) {\n values.push(value);\n }\n });\n\n return values;\n }\n\n if (!fallbackSelector) {\n return [];\n }\n\n const values = [];\n const checkboxes = document.querySelectorAll(fallbackSelector);\n\n checkboxes.forEach(checkbox => {\n const baseName = checkbox.name.replace('.IsSelected', '.ItemId');\n const hiddenInput = document.querySelector(`input[type=\"hidden\"][name=\"${baseName}\"]`);\n\n if (hiddenInput && hiddenInput.value) {\n values.push(hiddenInput.value);\n }\n });\n\n return values;\n },\n getPromptTemplateSelections() {\n const promptTemplates = [];\n\n document.querySelectorAll('.prompt-template-card').forEach(card => {\n const templateIdInput = card.querySelector('.prompt-template-id-input');\n const promptParametersInput = card.querySelector('.prompt-template-parameters-input');\n const templateId = templateIdInput ? templateIdInput.value : card.getAttribute('data-template-id');\n\n if (!templateId) {\n return;\n }\n\n promptTemplates.push({\n templateId: templateId,\n promptParameters: promptParametersInput ? (promptParametersInput.value || '').trim() : ''\n });\n });\n\n return promptTemplates;\n },\n receiveNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n // Replace existing notification with same type, or add new one.\n var idx = this.notifications.findIndex(n => n.type === notification.type);\n if (idx >= 0) {\n this.notifications.splice(idx, 1, notification);\n } else {\n this.notifications.push(notification);\n }\n this.scheduleNotificationDismiss(notification);\n this.scrollToBottom();\n },\n updateNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var idx = this.notifications.findIndex(n => n.type === notification.type);\n if (idx >= 0) {\n this.notifications.splice(idx, 1, notification);\n this.scheduleNotificationDismiss(notification);\n this.scrollToBottom();\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 itemId = this.getItemId();\n this.connection.invoke('HandleNotificationAction', itemId, notificationType, actionName)\n .catch(err => console.error('Failed to handle notification action:', err));\n },\n setItemId(itemId) {\n this.inputElement.setAttribute('data-interaction-id', itemId || '');\n this.inputElement.setAttribute('data-item-id', itemId || '');\n },\n resetInteraction() {\n this.setItemId('');\n this.isInteractionStarted = false;\n this.messages = [];\n this.showPlaceholder();\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 const itemId = this.getItemId();\n if (itemId) {\n this.loadInteraction(itemId);\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('keyup', event => {\n if (this.stream != null) {\n return;\n }\n\n if (event.key === \"Enter\" && !event.shiftKey) {\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.inputElement.addEventListener('paste', (e) => {\n // Use setTimeout to allow the paste to complete before checking the value\n setTimeout(() => {\n this.prompt = this.inputElement.value;\n if (this.inputElement.value.trim()) {\n this.buttonElement.removeAttribute('disabled');\n } else {\n this.buttonElement.setAttribute('disabled', true);\n }\n }, 0);\n });\n\n this.buttonElement.addEventListener('click', () => {\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 chatInteractionItems = document.getElementsByClassName('chat-interaction-history-item');\n\n for (var i = 0; i < chatInteractionItems.length; i++) {\n chatInteractionItems[i].addEventListener('click', (e) => {\n e.preventDefault();\n\n var itemId = e.target.getAttribute('data-interaction-id');\n\n if (!itemId) {\n console.error('An element with the class chat-interaction-history-item with no data-interaction-id set.');\n return;\n }\n\n this.loadInteraction(itemId);\n });\n }\n\n for (let i = 0; i < config.messages.length; i++) {\n this.addMessage(config.messages[i]);\n }\n\n // Delegate click for code block copy buttons.\n if (this.chatContainer) {\n this.chatContainer.addEventListener('click', (e) => {\n var btn = e.target.closest('.ai-code-copy-btn');\n if (!btn) {\n return;\n }\n\n var block = btn.closest('.ai-code-block') || btn.closest('pre');\n if (!block) {\n return;\n }\n\n var codeEl = block.querySelector('code');\n if (codeEl) {\n navigator.clipboard.writeText(codeEl.textContent);\n var copiedText = config.codeCopiedText || 'Copied!';\n btn.innerHTML = '<span class=\"fa-solid fa-check\"></span> ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '<span class=\"fa-regular fa-copy\"></span>';\n }, 2000);\n }\n });\n }\n\n document.addEventListener('input', event => {\n if (event.target.matches('.setting-input[data-setting]')) {\n this.validateSettingInput(event.target);\n this.queueSettingsSave();\n }\n });\n\n document.addEventListener('change', event => {\n if (event.target.matches('.setting-input[data-setting], .capability-checkbox[data-save-group], .capability-checkbox[data-group], .group-toggle, .ci-agent-global-toggle')) {\n if (event.target.matches('.setting-input[data-setting]')) {\n this.validateSettingInput(event.target);\n }\n\n this.queueSettingsSave();\n return;\n }\n\n if (event.target.closest('.prompt-template-parameters-input, .prompt-template-id-input')) {\n this.queueSettingsSave();\n }\n });\n\n document.addEventListener('click', event => {\n if (!event.target.closest('.prompt-template-add-btn, .remove-prompt-template-btn')) {\n return;\n }\n\n setTimeout(() => {\n this.queueSettingsSave();\n }, 0);\n });\n\n // Add event listener for clear history button\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.addEventListener('click', () => {\n const itemId = clearHistoryBtn.getAttribute('data-interaction-id');\n if (itemId) {\n this.clearHistory(itemId);\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 loadInteraction(itemId) {\n this.connection.invoke(\"LoadInteraction\", itemId).catch(err => console.error(err));\n },\n reloadCurrentInteraction() {\n const itemId = this.getItemId();\n if (itemId) {\n this.loadInteraction(itemId);\n }\n },\n clearHistory(itemId) {\n const self = this;\n const clearHistoryConfirmed = () => {\n // Cancel any active stream before clearing history.\n if (self.stream) {\n self.stream.dispose();\n self.stream = null;\n self.hideTypingIndicator();\n self.streamingFinished();\n }\n\n self.connection.invoke(\"ClearHistory\", itemId)\n .catch(err => console.error('Error clearing history:', err));\n };\n\n if (typeof confirmDialog === 'function') {\n confirmDialog({\n title: config.clearHistoryTitle,\n message: config.clearHistoryMessage,\n okText: config.clearHistoryOkText,\n cancelText: config.clearHistoryCancelText,\n callback: function (confirmed) {\n if (confirmed) {\n clearHistoryConfirmed();\n }\n }\n });\n\n return;\n }\n\n if (window.confirm(config.clearHistoryMessage || 'Clear all messages?')) {\n clearHistoryConfirmed();\n }\n },\n debouncedSaveSettings() {\n // Clear any existing timeout to reset the debounce timer\n this.clearPendingSettingsSave();\n\n // Don't save while streaming — it will be saved when streaming completes.\n if (this.stream) {\n return;\n }\n\n // Set a new timeout to save after 850ms of no changes\n this.saveSettingsTimeout = setTimeout(() => {\n if (this.settingsDirty) {\n this.saveSettings();\n this.settingsDirty = false;\n }\n this.saveSettingsTimeout = null;\n }, 850);\n },\n getSelectedToolNames() {\n return this.getSelectedGroupValues(\n 'toolNames',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Tools[\"]:checked'\n );\n },\n getSelectedMcpConnectionIds() {\n return this.getSelectedGroupValues(\n 'mcpConnectionIds',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Connections[\"]:checked'\n );\n },\n getSelectedA2AConnectionIds() {\n return this.getSelectedGroupValues('a2aConnectionIds');\n },\n getSelectedAgentNames() {\n return this.getSelectedGroupValues(\n 'agentNames',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Agents[\"]:checked'\n );\n },\n saveSettings() {\n const itemId = this.getItemId();\n if (!itemId) {\n return Promise.resolve();\n }\n\n if (!this.validateSettings()) {\n this.showSaveIndicator('Fix errors', 'text-danger');\n return Promise.resolve();\n }\n\n const settings = {};\n\n // Collect all form inputs with the \"ChatInteraction.\" prefix generically.\n // This avoids coupling the JS to specific field names — new fields added by\n // any module are automatically included.\n const inputs = this.getSettingInputs();\n\n inputs.forEach(input => {\n const key = input.dataset.setting\n || ((input.name || '').replace('ChatInteraction.', '').replace(/^[A-Z]/, match => match.toLowerCase()));\n\n if (!key) {\n return;\n }\n\n if (input.type === 'checkbox') {\n settings[key] = input.checked;\n } else if (input.type === 'number') {\n settings[key] = input.value ? parseFloat(input.value) : null;\n } else {\n settings[key] = input.value || null;\n }\n });\n\n // Add tool, MCP connection, and agent collections (special handling).\n settings.toolNames = this.getSelectedToolNames();\n settings.mcpConnectionIds = this.getSelectedMcpConnectionIds();\n settings.a2aConnectionIds = this.getSelectedA2AConnectionIds();\n settings.agentNames = this.getSelectedAgentNames();\n\n const promptTemplates = this.getPromptTemplateSelections();\n if (promptTemplates.length > 0) {\n settings.promptTemplates = promptTemplates;\n settings.promptTemplateIds = promptTemplates.map(template => template.templateId);\n }\n\n return this.connection.invoke(\"SaveSettings\", itemId, settings)\n .catch(err => {\n console.error('Error saving settings:', err);\n this.showSaveIndicator('Save failed', 'text-danger');\n });\n },\n flushPendingSave() {\n if (this.saveSettingsTimeout) {\n clearTimeout(this.saveSettingsTimeout);\n this.saveSettingsTimeout = null;\n }\n\n if (this.settingsDirty) {\n this.settingsDirty = false;\n return this.saveSettings();\n }\n\n return Promise.resolve();\n },\n initializeInteraction(itemId, force) {\n if (this.isInteractionStarted && !force) {\n return;\n }\n this.fireEvent(new CustomEvent(\"initializingChatInteraction\", { detail: { itemId: itemId } }));\n this.setItemId(itemId);\n this.isInteractionStarted = true;\n },\n copyResponse(message) {\n const text = message && typeof message === 'object'\n ? message.copyContent ?? message.content ?? ''\n : message ?? '';\n\n navigator.clipboard.writeText(text);\n },\n 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 itemId = this.getItemId();\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\", itemId, subject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n this.updateMicButton();\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n });\n },\n stopRecording() {\n if (!this.isRecording || !this.mediaRecorder) {\n return;\n }\n\n this.mediaRecorder.stop();\n this.isRecording = false;\n this.updateMicButton();\n },\n toggleRecording() {\n if (this.isRecording) {\n this.stopRecording();\n } else {\n this.startRecording();\n }\n },\n updateMicButton() {\n if (!this.micButton) {\n return;\n }\n\n if (this.isRecording) {\n this.micButton.classList.add('stt-recording');\n this.micButton.innerHTML = '<span class=\"fa-solid fa-stop\"></span>';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '<span class=\"fa-solid fa-microphone\"></span>';\n }\n }\n },\n watch: {\n isPlayingAudio() {\n // Reserved for future use — volume-based interrupt detection\n // no longer mutes tracks; browser echo cancellation handles echo.\n },\n isConversationMode(active) {\n if (this.micButton) {\n this.micButton.style.display = active ? 'none' : (this.speechToTextEnabled ? '' : 'none');\n }\n\n if (this.buttonElement) {\n this.buttonElement.style.display = active ? 'none' : '';\n }\n\n if (this.inputElement) {\n this.inputElement.disabled = active;\n if (active) {\n this.inputElement.placeholder = '';\n }\n }\n }\n },\n mounted() {\n (async () => {\n await this.startConnection();\n this.initializeApp();\n })();\n\n window.addEventListener('beforeunload', this.handleBeforeUnload);\n window.addEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n },\n beforeUnmount() {\n window.removeEventListener('beforeunload', this.handleBeforeUnload);\n window.removeEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n\n this.stopAudio(false);\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n if (this.connection) {\n this.connection.stop();\n }\n },\n template: config.messageTemplate\n }).mount(config.appElementSelector);\n\n return app;\n };\n\n return {\n initialize: initialize\n };\n}();\n\nwindow.chatInteractionDocumentManager = function () {\n const managerStateKey = '__chatInteractionDocumentManagerState';\n\n function normalizeDocumentInfo(document) {\n if (!document || typeof document !== 'object') {\n return null;\n }\n\n return {\n documentId: document.documentId || document.DocumentId || '',\n fileName: document.fileName || document.FileName || '',\n fileSize: document.fileSize || document.FileSize || 0\n };\n }\n\n function formatFileSize(bytes) {\n if (!bytes || bytes < 1024) {\n return (bytes || 0) + ' B';\n }\n\n if (bytes < 1024 * 1024) {\n return (bytes / 1024).toFixed(1) + ' KB';\n }\n\n return (bytes / (1024 * 1024)).toFixed(1) + ' MB';\n }\n\n function getDocumentKey(fileName, fileSize) {\n return ((fileName || '').trim().toLowerCase()) + '::' + (fileSize || 0);\n }\n\n function isDuplicateFile(file, knownKeys) {\n return knownKeys.has(getDocumentKey(file.name, file.size));\n }\n\n function getDocumentsFromDom(container) {\n if (!container) {\n return [];\n }\n\n return Array.from(container.querySelectorAll('[data-chat-document-id]'))\n .map(element => normalizeDocumentInfo({\n documentId: element.dataset.chatDocumentId,\n fileName: element.dataset.chatDocumentName,\n fileSize: Number(element.dataset.chatDocumentSize || 0)\n }))\n .filter(document => document && document.documentId);\n }\n\n function initialize(config) {\n if (!config || !config.itemId) {\n return;\n }\n\n const fileInput = document.getElementById('chat-doc-upload');\n const documentsList = document.getElementById('chat-documents-list');\n const status = document.getElementById('chat-doc-upload-status');\n const progressContainer = document.getElementById('chat-doc-upload-progress');\n const progressBar = document.getElementById('chat-doc-upload-progress-bar');\n const uploadQueue = document.getElementById('chat-doc-upload-queue');\n\n if (!fileInput || !documentsList || !status || !progressContainer || !progressBar || !uploadQueue) {\n return;\n }\n\n const previousState = fileInput[managerStateKey];\n if (previousState && typeof previousState.dispose === 'function') {\n previousState.dispose();\n }\n\n let interactionDocuments = (Array.isArray(config.existingDocuments) ? config.existingDocuments : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n\n if (interactionDocuments.length === 0) {\n interactionDocuments = getDocumentsFromDom(documentsList);\n }\n\n let uploadItems = [];\n let isUploadingDocuments = false;\n\n function createTextElement(tagName, className, text) {\n const element = document.createElement(tagName);\n if (className) {\n element.className = className;\n }\n\n element.textContent = text;\n return element;\n }\n\n function renderDocuments() {\n documentsList.innerHTML = '';\n\n if (interactionDocuments.length === 0) {\n documentsList.appendChild(createTextElement('div', 'text-muted small', 'No documents uploaded yet.'));\n return;\n }\n\n interactionDocuments.forEach(documentInfo => {\n const row = window.document.createElement('div');\n row.className = 'd-flex justify-content-between align-items-start gap-2 border rounded px-2 py-2 bg-white chat-document-row';\n row.dataset.chatDocumentId = documentInfo.documentId;\n row.dataset.chatDocumentName = documentInfo.fileName;\n row.dataset.chatDocumentSize = documentInfo.fileSize;\n\n const details = window.document.createElement('div');\n details.className = 'me-2 min-w-0';\n\n const name = createTextElement('div', 'fw-semibold small', documentInfo.fileName || 'Document');\n const icon = window.document.createElement('i');\n icon.className = 'bi bi-file-earmark-text me-1';\n name.prepend(icon);\n\n const size = createTextElement('div', 'text-muted small', formatFileSize(documentInfo.fileSize));\n\n details.appendChild(name);\n details.appendChild(size);\n\n const removeButton = createTextElement('button', 'btn btn-sm btn-outline-danger remove-chat-document-btn', ' Remove');\n removeButton.type = 'button';\n removeButton.dataset.documentId = documentInfo.documentId;\n const removeIcon = window.document.createElement('i');\n removeIcon.className = 'bi bi-trash';\n removeButton.prepend(removeIcon);\n removeButton.addEventListener('click', () => removeDocument(documentInfo.documentId));\n\n row.appendChild(details);\n row.appendChild(removeButton);\n documentsList.appendChild(row);\n });\n }\n\n function showUploadStatus(message, cssClass) {\n if (!message) {\n status.textContent = '';\n status.className = 'small mt-2 d-none';\n return;\n }\n\n status.textContent = message;\n status.className = 'small mt-2 ' + (cssClass || 'text-muted');\n }\n\n function showUploadProgress(progress, message, cssClass) {\n if (progress === null || progress === undefined) {\n progressContainer.className = 'progress mt-2 d-none';\n progressContainer.setAttribute('aria-valuenow', '0');\n progressBar.className = 'progress-bar progress-bar-striped progress-bar-animated';\n progressBar.style.width = '0%';\n progressBar.textContent = '0%';\n return;\n }\n\n const roundedProgress = Math.max(0, Math.min(100, Math.round(progress)));\n progressContainer.className = 'progress mt-2';\n progressContainer.setAttribute('aria-valuenow', roundedProgress.toString());\n progressBar.className = 'progress-bar ' + (cssClass || 'progress-bar-striped progress-bar-animated');\n progressBar.style.width = roundedProgress + '%';\n progressBar.textContent = message || (roundedProgress + '%');\n }\n\n function getUploadStatePresentation(state) {\n switch (state) {\n case 'uploaded':\n return { label: 'Uploaded', badgeClass: 'text-bg-success', progressClass: 'bg-success' };\n case 'failed':\n return { label: 'Failed', badgeClass: 'text-bg-danger', progressClass: 'bg-danger' };\n case 'uploading':\n return { label: 'Uploading', badgeClass: 'text-bg-warning', progressClass: 'bg-warning progress-bar-striped progress-bar-animated' };\n default:\n return { label: 'Queued', badgeClass: 'text-bg-secondary', progressClass: 'bg-secondary progress-bar-striped progress-bar-animated' };\n }\n }\n\n function formatUploadMessage(item) {\n if (item.status === 'failed' && item.error) {\n return item.error;\n }\n\n if (item.status === 'uploaded') {\n return 'Upload completed successfully.';\n }\n\n if (item.status === 'uploading') {\n return item.progress + '% uploaded';\n }\n\n return 'Waiting to upload...';\n }\n\n function renderUploadQueue() {\n uploadQueue.innerHTML = '';\n\n uploadItems.forEach(item => {\n const presentation = getUploadStatePresentation(item.status);\n const card = document.createElement('div');\n card.className = 'border rounded px-2 py-2 bg-white';\n\n const header = document.createElement('div');\n header.className = 'd-flex justify-content-between align-items-start gap-2';\n\n const fileDetails = document.createElement('div');\n fileDetails.className = 'flex-grow-1 min-w-0';\n fileDetails.appendChild(createTextElement('div', 'fw-semibold small', item.fileName));\n fileDetails.appendChild(createTextElement('div', 'text-muted small', formatFileSize(item.fileSize)));\n\n const badge = createTextElement('span', 'badge ' + presentation.badgeClass, presentation.label);\n\n header.appendChild(fileDetails);\n header.appendChild(badge);\n\n const progress = document.createElement('div');\n progress.className = 'progress mt-2';\n progress.setAttribute('role', 'progressbar');\n progress.setAttribute('aria-valuemin', '0');\n progress.setAttribute('aria-valuemax', '100');\n progress.setAttribute('aria-valuenow', item.progress.toString());\n\n const progressState = document.createElement('div');\n progressState.className = 'progress-bar ' + presentation.progressClass;\n progressState.style.width = item.progress + '%';\n progressState.textContent = item.progress + '%';\n progress.appendChild(progressState);\n\n const message = createTextElement('div', item.status === 'failed' ? 'small text-danger mt-2' : 'small text-muted mt-2', formatUploadMessage(item));\n\n card.appendChild(header);\n card.appendChild(progress);\n card.appendChild(message);\n uploadQueue.appendChild(card);\n });\n }\n\n function createUploadItem(file, index) {\n return {\n id: file.name + '::' + file.size + '::' + file.lastModified + '::' + index + '::' + Date.now(),\n fileName: file.name,\n fileSize: file.size,\n status: 'queued',\n progress: 0,\n error: null\n };\n }\n\n function updateUploadItem(itemId, updates) {\n uploadItems = uploadItems.map(item => item.id === itemId ? Object.assign({}, item, updates) : item);\n renderUploadQueue();\n }\n\n function removeUploadItems(predicate) {\n uploadItems = uploadItems.filter(item => !predicate(item));\n renderUploadQueue();\n }\n\n function uploadSingleDocument(file, itemIdToUpdate, fileIndex, totalFiles) {\n return new Promise((resolve, reject) => {\n const formData = new FormData();\n formData.append('chatInteractionId', config.itemId);\n formData.append('files', file);\n\n const xhr = new XMLHttpRequest();\n xhr.open('POST', config.uploadDocumentUrl, true);\n\n xhr.upload.addEventListener('progress', event => {\n if (!event.lengthComputable) {\n return;\n }\n\n const fileProgress = Math.round((event.loaded / event.total) * 100);\n updateUploadItem(itemIdToUpdate, {\n status: 'uploading',\n progress: fileProgress\n });\n\n const overallProgress = ((fileIndex + (event.loaded / event.total)) / totalFiles) * 100;\n showUploadProgress(overallProgress, 'Uploading ' + (fileIndex + 1) + ' of ' + totalFiles, 'progress-bar-striped progress-bar-animated');\n });\n\n xhr.addEventListener('load', () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n try {\n resolve(JSON.parse(xhr.responseText));\n } catch (error) {\n reject(new Error('Upload failed: invalid server response.'));\n }\n\n return;\n }\n\n reject(new Error((xhr.responseText || 'Upload failed.').trim()));\n });\n\n xhr.addEventListener('error', () => {\n reject(new Error('Upload failed. Please check your connection and try again.'));\n });\n\n xhr.send(formData);\n });\n }\n\n async function uploadDocuments(files) {\n if (!config.uploadDocumentUrl || !files || files.length === 0) {\n return;\n }\n\n if (isUploadingDocuments) {\n showUploadStatus('A document upload is already in progress.', 'text-warning');\n return;\n }\n\n isUploadingDocuments = true;\n\n const filesToUpload = [];\n const duplicateItems = [];\n const knownDocumentKeys = new Set(interactionDocuments.map(document => getDocumentKey(document.fileName, document.fileSize)));\n\n Array.from(files).forEach(file => {\n if (isDuplicateFile(file, knownDocumentKeys)) {\n duplicateItems.push(file);\n return;\n }\n\n knownDocumentKeys.add(getDocumentKey(file.name, file.size));\n filesToUpload.push(file);\n });\n\n if (duplicateItems.length > 0) {\n uploadItems = uploadItems.concat(duplicateItems.map((file, index) => Object.assign(createUploadItem(file, index), {\n status: 'failed',\n progress: 100,\n error: 'This document is already attached.'\n })));\n renderUploadQueue();\n }\n\n if (filesToUpload.length === 0) {\n isUploadingDocuments = false;\n showUploadStatus(duplicateItems.map(file => file.name + ': This document is already attached.').join(' | '), 'text-warning');\n showUploadProgress(null);\n return;\n }\n\n const pendingItems = filesToUpload.map(createUploadItem);\n uploadItems = uploadItems.concat(pendingItems);\n renderUploadQueue();\n showUploadProgress(0, 'Preparing upload...', 'progress-bar-striped progress-bar-animated');\n fileInput.disabled = true;\n\n try {\n let uploadedCount = 0;\n const failedUploads = duplicateItems.map(file => file.name + ': This document is already attached.');\n\n for (let i = 0; i < filesToUpload.length; i++) {\n const file = filesToUpload[i];\n const pendingItem = pendingItems[i];\n\n updateUploadItem(pendingItem.id, {\n status: 'uploading',\n progress: 0,\n error: null\n });\n\n showUploadStatus('Uploading ' + (i + 1) + ' of ' + filesToUpload.length + ' document(s)...', 'text-warning');\n\n try {\n const result = await uploadSingleDocument(file, pendingItem.id, i, filesToUpload.length);\n const uploaded = (Array.isArray(result.uploaded) ? result.uploaded : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n const failed = Array.isArray(result.failed) ? result.failed : [];\n\n if (uploaded.length > 0) {\n uploadedCount += uploaded.length;\n interactionDocuments = interactionDocuments.concat(uploaded);\n updateUploadItem(pendingItem.id, {\n status: 'uploaded',\n progress: 100,\n error: null\n });\n } else {\n const missingUploadMessage = failed.length > 0\n ? failed.map(entry => entry.fileName + ': ' + entry.error).join(' | ')\n : 'The server did not confirm that the file was uploaded.';\n if (failed.length === 0) {\n failedUploads.push(missingUploadMessage);\n }\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: 100,\n error: missingUploadMessage\n });\n }\n\n if (failed.length > 0) {\n const failedMessage = failed.map(entry => entry.fileName + ': ' + entry.error).join(' | ');\n failedUploads.push(failedMessage);\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: 100,\n error: failedMessage\n });\n }\n } catch (error) {\n const errorMessage = error && error.message\n ? error.message\n : 'Upload failed. Please try again.';\n console.error('Upload failed:', error);\n failedUploads.push(file.name + ': ' + errorMessage);\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: pendingItem.progress || 0,\n error: errorMessage\n });\n }\n }\n\n renderDocuments();\n\n if (failedUploads.length > 0) {\n removeUploadItems(item => item.status === 'uploaded');\n showUploadStatus(\n (uploadedCount > 0 ? ('Uploaded ' + uploadedCount + ' document(s). ') : '') + failedUploads.join(' | '),\n uploadedCount > 0 ? 'text-warning' : 'text-danger');\n showUploadProgress(null);\n return;\n }\n\n removeUploadItems(() => true);\n showUploadStatus('Uploaded ' + uploadedCount + ' document(s).', 'text-success');\n showUploadProgress(null);\n } catch (error) {\n console.error('Upload failed:', error);\n showUploadStatus('Upload failed. Please try again.', 'text-danger');\n showUploadProgress(null);\n } finally {\n isUploadingDocuments = false;\n fileInput.disabled = false;\n fileInput.value = '';\n }\n }\n\n async function removeDocument(documentId) {\n if (!config.removeDocumentUrl || !documentId || !window.confirm('Remove this document?')) {\n return;\n }\n\n try {\n const response = await fetch(config.removeDocumentUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n itemId: config.itemId,\n documentId: documentId\n })\n });\n\n if (!response.ok) {\n console.error('Failed to remove document:', await response.text());\n showUploadStatus('Failed to remove document.', 'text-danger');\n return;\n }\n\n const result = await response.json();\n const serverDocuments = (Array.isArray(result.documents) ? result.documents : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n\n interactionDocuments = serverDocuments.length > 0\n ? serverDocuments\n : interactionDocuments.filter(document => document.documentId !== documentId);\n renderDocuments();\n showUploadStatus('Document removed.', 'text-success');\n } catch (error) {\n console.error('Remove failed:', error);\n showUploadStatus('Failed to remove document.', 'text-danger');\n }\n }\n\n const onFileInputChange = event => {\n const selectedFiles = event.target.files ? Array.from(event.target.files) : [];\n uploadDocuments(selectedFiles);\n };\n\n fileInput.addEventListener('change', onFileInputChange);\n fileInput[managerStateKey] = {\n dispose: () => {\n fileInput.removeEventListener('change', onFileInputChange);\n }\n };\n\n renderDocuments();\n renderUploadQueue();\n showUploadStatus(null);\n showUploadProgress(null);\n }\n\n return {\n initialize: initialize\n };\n}();\n\n// Download chart as image via event delegation (DOMPurify strips inline onclick).\ndocument.addEventListener('click', function (e) {\n const btn = e.target.closest('.download-chart-btn');\n if (!btn) {\n return;\n }\n const chartId = btn.getAttribute('data-chart-id');\n const canvas = chartId ? document.getElementById(chartId) : null;\n if (!canvas) {\n console.error('Chart canvas not found:', chartId);\n return;\n }\n const link = document.createElement('a');\n link.download = 'chart-' + chartId + '.png';\n link.href = canvas.toDataURL('image/png');\n link.click();\n});\n\n// Intercept download clicks for data-URI images and convert to blob downloads.\ndocument.addEventListener('click', function (e) {\n const link = e.target.closest('.ai-download-image');\n if (!link) {\n return;\n }\n\n const container = link.closest('.generated-image-container');\n const img = container?.querySelector('img');\n if (!img) {\n return;\n }\n\n const src = img.src;\n if (!src || !src.startsWith('data:')) {\n return; // Normal URL – let the default <a> behaviour handle it.\n }\n\n e.preventDefault();\n\n fetch(src)\n .then(function (res) { return res.blob(); })\n .then(function (blob) {\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = link.getAttribute('download') || 'generated-image.png';\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n setTimeout(function () { URL.revokeObjectURL(url); }, 100);\n })\n .catch(function (err) { console.error('Failed to download image:', err); });\n});\n"]}