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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,22 +3,25 @@
3
3
  ** Any changes made directly to this file will be overwritten next time its asset group is processed by Gulp.
4
4
  */
5
5
 
6
- function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
7
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
8
- function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
9
- function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
10
- function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
6
+ var _excluded = ["placeholder"];
11
7
  function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
12
8
  function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
13
9
  function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
14
10
  function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
15
- function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
16
11
  function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
17
12
  function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
18
- function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
19
13
  function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
20
14
  function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
15
+ function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
16
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
17
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
18
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
19
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
20
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
21
21
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
22
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
23
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
24
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
22
25
  window.chatInteractionManager = function () {
23
26
  // Defaults (can be overridden by instanceConfig)
24
27
  var defaultConfig = {
@@ -30,7 +33,7 @@ window.chatInteractionManager = function () {
30
33
  downloadChartButtonText: 'Download',
31
34
  codeCopiedText: 'Copied!',
32
35
  assistantLabel: 'Assistant',
33
- 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)\"><i :class=\"getAssistantIcon(message)\"></i></span>\n {{ getAssistantLabel(message) }}\n </div>\n <div class=\"ai-chat-message-body lh-base\">\n <h4 v-if=\"message.title\">{{ message.title }}</h4>\n <div v-html=\"message.htmlContent\"></div>\n <span class=\"message-buttons-container\" v-if=\"!isIndicator(message)\">\n <button v-if=\"textToSpeechEnabled && !isConversationMode && message.role === 'assistant' && !message.isStreaming\" class=\"btn btn-sm btn-link text-secondary p-0 me-1 button-message-toolbox\" :class=\"{ 'tts-playing': ttsPlayingMessageIndex === index }\" @click=\"toggleMessageTts(message, index)\" :title=\"ttsPlayingMessageIndex === index ? 'Pause audio' : 'Read aloud'\">\n <i :class=\"ttsPlayingMessageIndex === index ? 'fa-solid fa-circle-pause' : 'fa-solid fa-circle-play'\"></i>\n </button>\n <button class=\"btn btn-sm btn-link text-secondary p-0 button-message-toolbox\" @click=\"copyResponse(message.content)\" title=\"Click here to copy response to clipboard.\">\n <i class=\"fa-solid fa-copy\"></i>\n </button>\n </span>\n </div>\n </div>\n </div>\n <div v-for=\"notification in notifications\" :key=\"'notif-' + notification.type\" class=\"ai-chat-notification\" :class=\"'ai-chat-notification-' + (notification.type || 'info') + ' ' + (notification.cssClass || '')\">\n <div class=\"ai-chat-notification-content\">\n <i v-if=\"notification.icon\" :class=\"notification.icon\" class=\"ai-chat-notification-icon\"></i>\n <span class=\"ai-chat-notification-text\">{{ notification.content }}</span>\n <button v-if=\"notification.dismissible\" class=\"btn btn-sm btn-link p-0 ms-2 ai-chat-notification-dismiss\" @click=\"dismissNotification(notification.type)\" title=\"Dismiss\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n <div v-if=\"notification.actions && notification.actions.length\" class=\"ai-chat-notification-actions\">\n <button v-for=\"action in notification.actions\" :key=\"action.name\" class=\"btn btn-sm\" :class=\"action.cssClass || 'btn-outline-secondary'\" @click=\"handleNotificationAction(notification.type, action.name)\">\n <i v-if=\"action.icon\" :class=\"action.icon\" class=\"me-1\"></i>\n {{ action.label }}\n </button>\n </div>\n </div>\n </div>\n ",
36
+ 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)\"><i :class=\"getAssistantIcon(message)\"></i></span>\n {{ getAssistantLabel(message) }}\n </div>\n <div class=\"ai-chat-message-body lh-base\">\n <h4 v-if=\"message.title\">{{ message.title }}</h4>\n <div v-html=\"message.htmlContent\"></div>\n <ol v-if=\"message.citationReferences && message.citationReferences.length\" class=\"ai-chat-citation-list\">\n <li v-for=\"citation in message.citationReferences\" :key=\"'citation-' + (citation.referenceKey || citation.displayIndex)\" class=\"ai-chat-citation-item\">\n <a v-if=\"citation.link\" :href=\"citation.link\" :target=\"citation.isDownload ? null : '_blank'\" :rel=\"citation.isDownload ? null : 'noopener noreferrer'\">{{ citation.label }}</a>\n <span v-else>{{ citation.label }}</span>\n </li>\n </ol>\n <span class=\"message-buttons-container\" v-if=\"!isIndicator(message)\">\n <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 <i :class=\"ttsPlayingMessageIndex === index ? 'fa-solid fa-circle-pause' : 'fa-solid fa-circle-play'\"></i>\n </button>\n <button class=\"btn btn-sm btn-link text-secondary p-0 button-message-toolbox\" @click=\"copyResponse(message)\" title=\"Click here to copy response to clipboard.\">\n <i class=\"fa-solid fa-copy\"></i>\n </button>\n </span>\n </div>\n </div>\n </div>\n <div v-for=\"notification in notifications\" :key=\"'notif-' + notification.type\" class=\"ai-chat-notification\" :class=\"'ai-chat-notification-' + (notification.type || 'info') + ' ' + (notification.cssClass || '')\">\n <div class=\"ai-chat-notification-content\">\n <i v-if=\"notification.icon\" :class=\"notification.icon\" class=\"ai-chat-notification-icon\"></i>\n <span class=\"ai-chat-notification-text\">{{ notification.content }}</span>\n <button v-if=\"notification.dismissible\" class=\"btn btn-sm btn-link p-0 ms-2 ai-chat-notification-dismiss\" @click=\"dismissNotification(notification.type)\" title=\"Dismiss\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n <div v-if=\"notification.actions && notification.actions.length\" class=\"ai-chat-notification-actions\">\n <button v-for=\"action in notification.actions\" :key=\"action.name\" class=\"btn btn-sm\" :class=\"action.cssClass || 'btn-outline-secondary'\" @click=\"handleNotificationAction(notification.type, action.name)\">\n <i v-if=\"action.icon\" :class=\"action.icon\" class=\"me-1\"></i>\n {{ action.label }}\n </button>\n </div>\n </div>\n </div>\n ",
34
37
  indicatorTemplate: "\n <div class=\"ai-chat-msg-role ai-chat-msg-role-assistant\">\n <span class=\"ai-streaming-icon\"><i class=\"fa fa-robot\" style=\"display: inline-block;\"></i></span>\n Assistant\n </div>\n ",
35
38
  // Localizable strings
36
39
  untitledText: 'Untitled',
@@ -56,6 +59,200 @@ window.chatInteractionManager = function () {
56
59
  span.textContent = text;
57
60
  return span.innerHTML;
58
61
  }
62
+ function containsFontAwesomePlaceholders(root) {
63
+ if (!root || root.nodeType !== 1) {
64
+ return false;
65
+ }
66
+ var selector = 'i[class*="fa-"],i.fa,i.fas,i.far,i.fab';
67
+ if (typeof root.matches === 'function' && root.matches(selector)) {
68
+ return true;
69
+ }
70
+ return typeof root.querySelector === 'function' && !!root.querySelector(selector);
71
+ }
72
+ function refreshFontAwesomeIcons(root) {
73
+ var fontAwesome = window.FontAwesome;
74
+ if (!containsFontAwesomePlaceholders(root) || !fontAwesome || !fontAwesome.dom || typeof fontAwesome.dom.i2svg !== 'function') {
75
+ return;
76
+ }
77
+ fontAwesome.dom.i2svg({
78
+ node: root
79
+ });
80
+ }
81
+ function observeFontAwesomeIcons(root) {
82
+ if (!root || typeof MutationObserver === 'undefined') {
83
+ return null;
84
+ }
85
+ var observer = new MutationObserver(function (mutations) {
86
+ mutations.forEach(function (mutation) {
87
+ mutation.addedNodes.forEach(function (node) {
88
+ refreshFontAwesomeIcons(node);
89
+ });
90
+ });
91
+ });
92
+ observer.observe(root, {
93
+ childList: true,
94
+ subtree: true
95
+ });
96
+ return observer;
97
+ }
98
+ function normalizeReference(reference) {
99
+ var _ref, _normalized$index, _ref2, _normalized$text, _ref3, _normalized$title, _ref4, _normalized$link, _ref5, _normalized$reference;
100
+ if (!reference || _typeof(reference) !== 'object') {
101
+ return null;
102
+ }
103
+ var normalized = Object.assign({}, reference);
104
+ normalized.index = (_ref = (_normalized$index = normalized.index) !== null && _normalized$index !== void 0 ? _normalized$index : normalized.Index) !== null && _ref !== void 0 ? _ref : 0;
105
+ normalized.text = (_ref2 = (_normalized$text = normalized.text) !== null && _normalized$text !== void 0 ? _normalized$text : normalized.Text) !== null && _ref2 !== void 0 ? _ref2 : null;
106
+ normalized.title = (_ref3 = (_normalized$title = normalized.title) !== null && _normalized$title !== void 0 ? _normalized$title : normalized.Title) !== null && _ref3 !== void 0 ? _ref3 : null;
107
+ normalized.link = sanitizeUrl((_ref4 = (_normalized$link = normalized.link) !== null && _normalized$link !== void 0 ? _normalized$link : normalized.Link) !== null && _ref4 !== void 0 ? _ref4 : null);
108
+ normalized.referenceType = (_ref5 = (_normalized$reference = normalized.referenceType) !== null && _normalized$reference !== void 0 ? _normalized$reference : normalized.ReferenceType) !== null && _ref5 !== void 0 ? _ref5 : null;
109
+ return normalized;
110
+ }
111
+ function isDownloadCitationReference(reference) {
112
+ if (!reference || _typeof(reference) !== 'object') {
113
+ return false;
114
+ }
115
+ if (typeof reference.referenceType === 'string' && reference.referenceType.toLowerCase() === 'document') {
116
+ return true;
117
+ }
118
+ if (typeof reference.link === 'string' && /\/ai\/documents\/.+\/download(?:$|\?)/i.test(reference.link)) {
119
+ return true;
120
+ }
121
+ return false;
122
+ }
123
+ function normalizeReferences(references) {
124
+ if (!references || _typeof(references) !== 'object') {
125
+ return {};
126
+ }
127
+ var normalized = {};
128
+ for (var _i = 0, _Object$entries = Object.entries(references); _i < _Object$entries.length; _i++) {
129
+ var _normalizeReference;
130
+ var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
131
+ key = _Object$entries$_i[0],
132
+ value = _Object$entries$_i[1];
133
+ normalized[key] = (_normalizeReference = normalizeReference(value)) !== null && _normalizeReference !== void 0 ? _normalizeReference : {};
134
+ }
135
+ return normalized;
136
+ }
137
+ function getCitationLabel(reference, key) {
138
+ return reference.title || reference.text || key;
139
+ }
140
+ function buildCitationDisplay(content, references) {
141
+ var processedContent = (content || '').trim();
142
+ var messageReferences = normalizeReferences(references);
143
+ if (!processedContent || !Object.keys(messageReferences).length) {
144
+ return {
145
+ content: processedContent,
146
+ citations: []
147
+ };
148
+ }
149
+ var citedRefs = Object.entries(messageReferences).filter(function (_ref6) {
150
+ var _ref7 = _slicedToArray(_ref6, 1),
151
+ key = _ref7[0];
152
+ return processedContent.includes(key);
153
+ });
154
+ if (!citedRefs.length) {
155
+ return {
156
+ content: processedContent,
157
+ citations: []
158
+ };
159
+ }
160
+ citedRefs.sort(function (_ref8, _ref9) {
161
+ var _ref0 = _slicedToArray(_ref8, 2),
162
+ a = _ref0[1];
163
+ var _ref1 = _slicedToArray(_ref9, 2),
164
+ b = _ref1[1];
165
+ return a.index - b.index;
166
+ });
167
+ var citations = [];
168
+ var displayIndex = 1;
169
+ var _iterator = _createForOfIteratorHelper(citedRefs),
170
+ _step;
171
+ try {
172
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
173
+ var _step$value = _slicedToArray(_step.value, 2),
174
+ key = _step$value[0],
175
+ value = _step$value[1];
176
+ var placeholder = "__CITE_".concat(displayIndex, "_").concat(value.index || displayIndex, "__");
177
+ processedContent = processedContent.replaceAll(key, placeholder);
178
+ citations.push({
179
+ referenceKey: key,
180
+ displayIndex: displayIndex,
181
+ label: getCitationLabel(value, key),
182
+ link: value.link || null,
183
+ isDownload: isDownloadCitationReference(value),
184
+ placeholder: placeholder
185
+ });
186
+ displayIndex++;
187
+ }
188
+ } catch (err) {
189
+ _iterator.e(err);
190
+ } finally {
191
+ _iterator.f();
192
+ }
193
+ for (var _i2 = 0, _citations = citations; _i2 < _citations.length; _i2++) {
194
+ var citation = _citations[_i2];
195
+ processedContent = processedContent.replaceAll(citation.placeholder, "<sup>".concat(citation.displayIndex, "</sup>"));
196
+ }
197
+ processedContent = processedContent.replaceAll('</sup><sup>', '</sup><sup>,</sup><sup>');
198
+ return {
199
+ content: processedContent,
200
+ citations: citations.map(function (_ref10) {
201
+ var placeholder = _ref10.placeholder,
202
+ citation = _objectWithoutProperties(_ref10, _excluded);
203
+ return citation;
204
+ })
205
+ };
206
+ }
207
+ function buildCopyContent(content, citations) {
208
+ var copyContent = (content || '').trim();
209
+ if (!copyContent || !Array.isArray(citations) || citations.length === 0) {
210
+ return copyContent;
211
+ }
212
+ var _iterator2 = _createForOfIteratorHelper(citations),
213
+ _step2;
214
+ try {
215
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
216
+ var citation = _step2.value;
217
+ copyContent = copyContent.replaceAll(citation.referenceKey, "[".concat(citation.displayIndex, "]"));
218
+ }
219
+ } catch (err) {
220
+ _iterator2.e(err);
221
+ } finally {
222
+ _iterator2.f();
223
+ }
224
+ copyContent += '\n\nReferences:\n';
225
+ var _iterator3 = _createForOfIteratorHelper(citations),
226
+ _step3;
227
+ try {
228
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
229
+ var _citation = _step3.value;
230
+ copyContent += "".concat(_citation.displayIndex, ". ").concat(_citation.label);
231
+ if (_citation.link) {
232
+ copyContent += " - ".concat(_citation.link);
233
+ }
234
+ copyContent += '\n';
235
+ }
236
+ } catch (err) {
237
+ _iterator3.e(err);
238
+ } finally {
239
+ _iterator3.f();
240
+ }
241
+ return copyContent.trimEnd();
242
+ }
243
+ function updateMessagePresentation(message, references) {
244
+ var messageReferences = normalizeReferences(references !== null && references !== void 0 ? references : message.references);
245
+ var rawContent = typeof message.rawContent === 'string' ? message.rawContent : typeof message.content === 'string' ? message.content : '';
246
+ var citationDisplay = buildCitationDisplay(rawContent, messageReferences);
247
+ message.rawContent = rawContent;
248
+ message.content = rawContent;
249
+ message.displayContent = citationDisplay.content;
250
+ message.references = messageReferences;
251
+ message.citationReferences = citationDisplay.citations;
252
+ message.copyContent = buildCopyContent(rawContent, citationDisplay.citations);
253
+ message.htmlContent = parseMarkdownContent(citationDisplay.content, message);
254
+ return message;
255
+ }
59
256
  var renderer = new marked.Renderer();
60
257
 
61
258
  // Modify the link rendering to open in a new tab
@@ -219,11 +416,11 @@ window.chatInteractionManager = function () {
219
416
  // Defer to requestAnimationFrame so the browser has fully laid out the
220
417
  // canvas elements before Chart.js reads their dimensions.
221
418
  requestAnimationFrame(function () {
222
- var _iterator = _createForOfIteratorHelper(charts),
223
- _step;
419
+ var _iterator4 = _createForOfIteratorHelper(charts),
420
+ _step4;
224
421
  try {
225
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
226
- var c = _step.value;
422
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
423
+ var c = _step4.value;
227
424
  var canvas = document.getElementById(c.chartId);
228
425
  if (!canvas) {
229
426
  continue;
@@ -256,9 +453,9 @@ window.chatInteractionManager = function () {
256
453
  }
257
454
  }
258
455
  } catch (err) {
259
- _iterator.e(err);
456
+ _iterator4.e(err);
260
457
  } finally {
261
- _iterator.f();
458
+ _iterator4.f();
262
459
  }
263
460
  });
264
461
  }
@@ -467,7 +664,7 @@ window.chatInteractionManager = function () {
467
664
  _this.scrollToBottom();
468
665
  }
469
666
  });
470
- _this.connection.on("ReceiveConversationAssistantToken", function (itemId, messageId, token, responseId, appearance) {
667
+ _this.connection.on("ReceiveConversationAssistantToken", function (itemId, messageId, token, responseId, references, appearance) {
471
668
  if (!_this._conversationAssistantMessage) {
472
669
  _this.stopAudio();
473
670
  _this.hideTypingIndicator();
@@ -485,7 +682,8 @@ window.chatInteractionManager = function () {
485
682
  content: "",
486
683
  htmlContent: "",
487
684
  isStreaming: true,
488
- appearance: _this.normalizeAssistantAppearance(appearance)
685
+ appearance: _this.normalizeAssistantAppearance(appearance),
686
+ references: {}
489
687
  };
490
688
  _this.messages.push(newMessage);
491
689
  _this._conversationAssistantMessage = {
@@ -499,19 +697,22 @@ window.chatInteractionManager = function () {
499
697
  if (!msg.appearance) {
500
698
  msg.appearance = _this.normalizeAssistantAppearance(appearance);
501
699
  }
502
- msg.content = _this._conversationAssistantMessage.content;
503
- msg.htmlContent = parseMarkdownContent(msg.content, msg);
700
+ msg.rawContent = _this._conversationAssistantMessage.content;
701
+ msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));
702
+ updateMessagePresentation(msg, msg.references);
504
703
  _this.$nextTick(function () {
505
704
  renderChartsInMessage(msg);
506
705
  _this.scrollToBottom();
507
706
  });
508
707
  }
509
708
  });
510
- _this.connection.on("ReceiveConversationAssistantComplete", function (itemId, messageId) {
709
+ _this.connection.on("ReceiveConversationAssistantComplete", function (itemId, messageId, references) {
511
710
  if (_this._conversationAssistantMessage) {
512
711
  var msg = _this.messages[_this._conversationAssistantMessage.index];
513
712
  if (msg) {
514
713
  msg.isStreaming = false;
714
+ msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));
715
+ updateMessagePresentation(msg, msg.references);
515
716
  }
516
717
  _this._conversationAssistantMessage = null;
517
718
  }
@@ -605,79 +806,9 @@ window.chatInteractionManager = function () {
605
806
  addMessage: function addMessage(message) {
606
807
  var _this3 = this;
607
808
  if (message.content) {
608
- var processedContent = message.content.trim();
609
- if (message.references && _typeof(message.references) === "object" && Object.keys(message.references).length) {
610
- // Only include references that were actually cited in the response.
611
- var citedRefs = Object.entries(message.references).filter(function (_ref) {
612
- var _ref2 = _slicedToArray(_ref, 1),
613
- key = _ref2[0];
614
- return processedContent.includes(key);
615
- });
616
- if (citedRefs.length) {
617
- // Sort by original index so display indices follow a natural order.
618
- citedRefs.sort(function (_ref3, _ref4) {
619
- var _ref5 = _slicedToArray(_ref3, 2),
620
- a = _ref5[1];
621
- var _ref6 = _slicedToArray(_ref4, 2),
622
- b = _ref6[1];
623
- return a.index - b.index;
624
- });
625
-
626
- // Phase 1: Replace all markers with unique placeholders.
627
- var displayIndex = 1;
628
- var _iterator2 = _createForOfIteratorHelper(citedRefs),
629
- _step2;
630
- try {
631
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
632
- var _step2$value = _slicedToArray(_step2.value, 2),
633
- key = _step2$value[0],
634
- value = _step2$value[1];
635
- var placeholder = "__CITE_".concat(value.index, "__");
636
- processedContent = processedContent.replaceAll(key, placeholder);
637
- value._displayIndex = displayIndex++;
638
- value._placeholder = placeholder;
639
- }
640
-
641
- // Phase 2: Replace placeholders with sequential display indices.
642
- } catch (err) {
643
- _iterator2.e(err);
644
- } finally {
645
- _iterator2.f();
646
- }
647
- var _iterator3 = _createForOfIteratorHelper(citedRefs),
648
- _step3;
649
- try {
650
- for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
651
- var _step3$value = _slicedToArray(_step3.value, 2),
652
- _value = _step3$value[1];
653
- processedContent = processedContent.replaceAll(_value._placeholder, "<sup><strong>".concat(_value._displayIndex, "</strong></sup>"));
654
- }
655
- } catch (err) {
656
- _iterator3.e(err);
657
- } finally {
658
- _iterator3.f();
659
- }
660
- processedContent = processedContent.replaceAll('</strong></sup><sup>', '</strong></sup><sup>,</sup><sup>');
661
- processedContent += '<br><br>';
662
- var _iterator4 = _createForOfIteratorHelper(citedRefs),
663
- _step4;
664
- try {
665
- for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
666
- var _step4$value = _slicedToArray(_step4.value, 2),
667
- _key = _step4$value[0],
668
- _value2 = _step4$value[1];
669
- var label = _value2.text || "[doc:".concat(_value2.index, "]");
670
- processedContent += _value2.link ? "**".concat(_value2._displayIndex, "**. [").concat(label, "](").concat(_value2.link, ")<br>") : "**".concat(_value2._displayIndex, "**. ").concat(label, "<br>");
671
- }
672
- } catch (err) {
673
- _iterator4.e(err);
674
- } finally {
675
- _iterator4.f();
676
- }
677
- }
678
- }
679
- message.content = processedContent;
680
- message.htmlContent = parseMarkdownContent(processedContent, message);
809
+ var _message$rawContent;
810
+ message.rawContent = (_message$rawContent = message.rawContent) !== null && _message$rawContent !== void 0 ? _message$rawContent : message.content;
811
+ updateMessagePresentation(message, message.references);
681
812
  }
682
813
  this.addMessageInternal(message);
683
814
  this.hidePlaceholder();
@@ -828,11 +959,12 @@ window.chatInteractionManager = function () {
828
959
  message = newMessage;
829
960
  }
830
961
  if (chunk.references && _typeof(chunk.references) === "object" && Object.keys(chunk.references).length) {
831
- for (var _i = 0, _Object$entries = Object.entries(chunk.references); _i < _Object$entries.length; _i++) {
832
- var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
833
- key = _Object$entries$_i[0],
834
- value = _Object$entries$_i[1];
835
- references[key] = value;
962
+ for (var _i3 = 0, _Object$entries2 = Object.entries(chunk.references); _i3 < _Object$entries2.length; _i3++) {
963
+ var _normalizeReference2;
964
+ var _Object$entries2$_i = _slicedToArray(_Object$entries2[_i3], 2),
965
+ key = _Object$entries2$_i[0],
966
+ value = _Object$entries2$_i[1];
967
+ references[key] = (_normalizeReference2 = normalizeReference(value)) !== null && _normalizeReference2 !== void 0 ? _normalizeReference2 : {};
836
968
  }
837
969
  }
838
970
  if (chunk.content) {
@@ -844,17 +976,10 @@ window.chatInteractionManager = function () {
844
976
  if (chunk.responseId) {
845
977
  lastResponseId = chunk.responseId;
846
978
  }
847
- var processedContent = chunk.content;
848
- for (var _i2 = 0, _Object$entries2 = Object.entries(references); _i2 < _Object$entries2.length; _i2++) {
849
- var _Object$entries2$_i = _slicedToArray(_Object$entries2[_i2], 2),
850
- _key2 = _Object$entries2$_i[0],
851
- _value3 = _Object$entries2$_i[1];
852
- processedContent = processedContent.replaceAll(_key2, "<sup><strong>".concat(_value3.index, "</strong></sup>"));
853
- }
854
- content += processedContent.replaceAll('</strong></sup><sup>', '</strong></sup><sup>,</sup><sup>');
979
+ content += chunk.content;
855
980
  }
856
- message.content = content;
857
- message.htmlContent = parseMarkdownContent(content, message);
981
+ message.rawContent = content;
982
+ updateMessagePresentation(message, references);
858
983
  _this5.messages[messageIndex] = message;
859
984
  _this5.$nextTick(function () {
860
985
  renderChartsInMessage(message);
@@ -908,86 +1033,12 @@ window.chatInteractionManager = function () {
908
1033
  },
909
1034
  processReferences: function processReferences(references, messageIndex) {
910
1035
  var _this6 = this;
1036
+ references = normalizeReferences(references);
911
1037
  if (Object.keys(references).length) {
1038
+ var _ref11, _message$rawContent2;
912
1039
  var message = this.messages[messageIndex];
913
- var content = message.content || '';
914
-
915
- // Only include references that were actually cited in the response.
916
- // Check both raw [doc:N] markers and already-rendered <sup> tags from streaming.
917
- var citedRefs = Object.entries(references).filter(function (_ref7) {
918
- var _ref8 = _slicedToArray(_ref7, 2),
919
- key = _ref8[0],
920
- value = _ref8[1];
921
- return content.includes(key) || content.includes("<sup><strong>".concat(value.index, "</strong></sup>"));
922
- });
923
- if (!citedRefs.length) {
924
- return;
925
- }
926
-
927
- // Sort by original index so display indices follow a natural order.
928
- citedRefs.sort(function (_ref9, _ref0) {
929
- var _ref1 = _slicedToArray(_ref9, 2),
930
- a = _ref1[1];
931
- var _ref10 = _slicedToArray(_ref0, 2),
932
- b = _ref10[1];
933
- return a.index - b.index;
934
- });
935
-
936
- // Phase 1: Replace all markers with unique placeholders to avoid collisions during remapping.
937
- var processed = content.trim();
938
- var displayIndex = 1;
939
- var _iterator5 = _createForOfIteratorHelper(citedRefs),
940
- _step5;
941
- try {
942
- for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
943
- var _step5$value = _slicedToArray(_step5.value, 2),
944
- key = _step5$value[0],
945
- value = _step5$value[1];
946
- var placeholder = "__CITE_".concat(value.index, "__");
947
- processed = processed.replaceAll(key, placeholder);
948
- processed = processed.replaceAll("<sup><strong>".concat(value.index, "</strong></sup>"), placeholder);
949
- value._displayIndex = displayIndex++;
950
- value._placeholder = placeholder;
951
- }
952
-
953
- // Phase 2: Replace placeholders with sequential display indices.
954
- } catch (err) {
955
- _iterator5.e(err);
956
- } finally {
957
- _iterator5.f();
958
- }
959
- var _iterator6 = _createForOfIteratorHelper(citedRefs),
960
- _step6;
961
- try {
962
- for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
963
- var _step6$value = _slicedToArray(_step6.value, 2),
964
- _value4 = _step6$value[1];
965
- processed = processed.replaceAll(_value4._placeholder, "<sup><strong>".concat(_value4._displayIndex, "</strong></sup>"));
966
- }
967
- } catch (err) {
968
- _iterator6.e(err);
969
- } finally {
970
- _iterator6.f();
971
- }
972
- processed = processed.replaceAll('</strong></sup><sup>', '</strong></sup><sup>,</sup><sup>');
973
- processed += '<br><br>';
974
- var _iterator7 = _createForOfIteratorHelper(citedRefs),
975
- _step7;
976
- try {
977
- for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
978
- var _step7$value = _slicedToArray(_step7.value, 2),
979
- _key3 = _step7$value[0],
980
- _value5 = _step7$value[1];
981
- var label = _value5.text || "[doc:".concat(_value5.index, "]");
982
- processed += _value5.link ? "**".concat(_value5._displayIndex, "**. [").concat(label, "](").concat(_value5.link, ")<br>") : "**".concat(_value5._displayIndex, "**. ").concat(label, "<br>");
983
- }
984
- } catch (err) {
985
- _iterator7.e(err);
986
- } finally {
987
- _iterator7.f();
988
- }
989
- message.content = processed;
990
- message.htmlContent = parseMarkdownContent(processed, message);
1040
+ message.rawContent = (_ref11 = (_message$rawContent2 = message.rawContent) !== null && _message$rawContent2 !== void 0 ? _message$rawContent2 : message.content) !== null && _ref11 !== void 0 ? _ref11 : '';
1041
+ updateMessagePresentation(message, references);
991
1042
  this.messages[messageIndex] = message;
992
1043
  this.$nextTick(function () {
993
1044
  renderChartsInMessage(message);
@@ -1039,8 +1090,25 @@ window.chatInteractionManager = function () {
1039
1090
  }
1040
1091
  this.stopAudio(false);
1041
1092
  },
1042
- synthesizeSpeech: function synthesizeSpeech(text, cacheIndex) {
1093
+ updateTtsPlaybackButtons: function updateTtsPlaybackButtons() {
1043
1094
  var _this7 = this;
1095
+ if (!this.chatContainer) {
1096
+ return;
1097
+ }
1098
+ var buttons = this.chatContainer.querySelectorAll('[data-tts-message-index]');
1099
+ buttons.forEach(function (button) {
1100
+ var buttonIndex = Number(button.getAttribute('data-tts-message-index'));
1101
+ var isPlaying = buttonIndex === _this7.ttsPlayingMessageIndex;
1102
+ var iconHtml = isPlaying ? '<i class="fa-solid fa-circle-pause"></i>' : '<i class="fa-solid fa-circle-play"></i>';
1103
+ button.classList.toggle('tts-playing', isPlaying);
1104
+ button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');
1105
+ button.replaceChildren(DOMPurify.sanitize(iconHtml, {
1106
+ RETURN_DOM_FRAGMENT: true
1107
+ }));
1108
+ });
1109
+ },
1110
+ synthesizeSpeech: function synthesizeSpeech(text, cacheIndex) {
1111
+ var _this8 = this;
1044
1112
  if (!this.textToSpeechEnabled || !text || !this.connection) {
1045
1113
  return;
1046
1114
  }
@@ -1049,12 +1117,16 @@ window.chatInteractionManager = function () {
1049
1117
  this._ttsCacheIndex = cacheIndex !== undefined ? cacheIndex : -1;
1050
1118
  this.connection.invoke("SynthesizeSpeech", this.getItemId(), text, this.ttsVoiceName)["catch"](function (err) {
1051
1119
  console.error("TTS synthesis error:", err);
1052
- _this7.isPlayingAudio = false;
1053
- _this7.ttsPlayingMessageIndex = -1;
1054
- _this7._ttsCacheIndex = -1;
1120
+ _this8.isPlayingAudio = false;
1121
+ _this8.ttsPlayingMessageIndex = -1;
1122
+ _this8._ttsCacheIndex = -1;
1123
+ _this8.$nextTick(function () {
1124
+ return _this8.updateTtsPlaybackButtons();
1125
+ });
1055
1126
  });
1056
1127
  },
1057
1128
  toggleMessageTts: function toggleMessageTts(message, index) {
1129
+ var _this9 = this;
1058
1130
  if (this.ttsPlayingMessageIndex === index) {
1059
1131
  this.stopAudio();
1060
1132
  return;
@@ -1066,6 +1138,9 @@ window.chatInteractionManager = function () {
1066
1138
  }
1067
1139
  }));
1068
1140
  this.ttsPlayingMessageIndex = index;
1141
+ this.$nextTick(function () {
1142
+ return _this9.updateTtsPlaybackButtons();
1143
+ });
1069
1144
  if (this.ttsAudioCache[index]) {
1070
1145
  this.playAudioBlob(this.ttsAudioCache[index]);
1071
1146
  return;
@@ -1073,10 +1148,14 @@ window.chatInteractionManager = function () {
1073
1148
  this.synthesizeSpeech(message.content, index);
1074
1149
  },
1075
1150
  playCollectedAudio: function playCollectedAudio() {
1151
+ var _this0 = this;
1076
1152
  if (this.audioChunks.length === 0) {
1077
1153
  if (!this.isPlayingAudio && this.audioPlayQueue.length === 0) {
1078
1154
  this.isPlayingAudio = false;
1079
1155
  this.ttsPlayingMessageIndex = -1;
1156
+ this.$nextTick(function () {
1157
+ return _this0.updateTtsPlaybackButtons();
1158
+ });
1080
1159
  }
1081
1160
  return;
1082
1161
  }
@@ -1085,18 +1164,18 @@ window.chatInteractionManager = function () {
1085
1164
  }, 0);
1086
1165
  var combined = new Uint8Array(totalLength);
1087
1166
  var offset = 0;
1088
- var _iterator8 = _createForOfIteratorHelper(this.audioChunks),
1089
- _step8;
1167
+ var _iterator5 = _createForOfIteratorHelper(this.audioChunks),
1168
+ _step5;
1090
1169
  try {
1091
- for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
1092
- var chunk = _step8.value;
1170
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
1171
+ var chunk = _step5.value;
1093
1172
  combined.set(chunk, offset);
1094
1173
  offset += chunk.length;
1095
1174
  }
1096
1175
  } catch (err) {
1097
- _iterator8.e(err);
1176
+ _iterator5.e(err);
1098
1177
  } finally {
1099
- _iterator8.f();
1178
+ _iterator5.f();
1100
1179
  }
1101
1180
  this.audioChunks = [];
1102
1181
  var blob = new Blob([combined], {
@@ -1115,45 +1194,53 @@ window.chatInteractionManager = function () {
1115
1194
  this.playAudioBlob(blob);
1116
1195
  },
1117
1196
  playAudioBlob: function playAudioBlob(blob) {
1118
- var _this8 = this;
1197
+ var _this1 = this;
1119
1198
  var url = URL.createObjectURL(blob);
1120
1199
  var audio = new Audio(url);
1121
1200
  this.currentAudioUrl = url;
1122
1201
  this.currentAudioElement = audio;
1123
1202
  this.isPlayingAudio = true;
1124
1203
  audio.addEventListener('ended', function () {
1125
- _this8.currentAudioElement = null;
1126
- _this8.currentAudioUrl = null;
1204
+ _this1.currentAudioElement = null;
1205
+ _this1.currentAudioUrl = null;
1127
1206
  URL.revokeObjectURL(url);
1128
- _this8.playNextInQueue();
1207
+ _this1.playNextInQueue();
1129
1208
  });
1130
1209
  audio.addEventListener('error', function () {
1131
- _this8.currentAudioElement = null;
1132
- _this8.currentAudioUrl = null;
1210
+ _this1.currentAudioElement = null;
1211
+ _this1.currentAudioUrl = null;
1133
1212
  URL.revokeObjectURL(url);
1134
- _this8.playNextInQueue();
1213
+ _this1.playNextInQueue();
1135
1214
  });
1136
1215
  audio.play()["catch"](function (err) {
1137
1216
  console.error("Audio playback error:", err);
1138
- _this8.currentAudioElement = null;
1139
- _this8.currentAudioUrl = null;
1217
+ _this1.currentAudioElement = null;
1218
+ _this1.currentAudioUrl = null;
1140
1219
  URL.revokeObjectURL(url);
1141
- _this8.audioPlayQueue = [];
1142
- _this8.isPlayingAudio = false;
1143
- _this8.ttsPlayingMessageIndex = -1;
1220
+ _this1.audioPlayQueue = [];
1221
+ _this1.isPlayingAudio = false;
1222
+ _this1.ttsPlayingMessageIndex = -1;
1223
+ _this1.$nextTick(function () {
1224
+ return _this1.updateTtsPlaybackButtons();
1225
+ });
1144
1226
  });
1145
1227
  },
1146
1228
  playNextInQueue: function playNextInQueue() {
1229
+ var _this10 = this;
1147
1230
  if (this.audioPlayQueue.length > 0) {
1148
1231
  var nextBlob = this.audioPlayQueue.shift();
1149
1232
  this.playAudioBlob(nextBlob);
1150
1233
  } else {
1151
1234
  this.isPlayingAudio = false;
1152
1235
  this.ttsPlayingMessageIndex = -1;
1236
+ this.$nextTick(function () {
1237
+ return _this10.updateTtsPlaybackButtons();
1238
+ });
1153
1239
  this.conversationModeOnAudioEnded();
1154
1240
  }
1155
1241
  },
1156
1242
  stopAudio: function stopAudio() {
1243
+ var _this11 = this;
1157
1244
  if (this.currentAudioElement) {
1158
1245
  this.currentAudioElement.pause();
1159
1246
  this.currentAudioElement.currentTime = 0;
@@ -1167,6 +1254,9 @@ window.chatInteractionManager = function () {
1167
1254
  this.audioPlayQueue = [];
1168
1255
  this.isPlayingAudio = false;
1169
1256
  this.ttsPlayingMessageIndex = -1;
1257
+ this.$nextTick(function () {
1258
+ return _this11.updateTtsPlaybackButtons();
1259
+ });
1170
1260
  },
1171
1261
  toggleConversationMode: function toggleConversationMode() {
1172
1262
  if (this.isConversationMode) {
@@ -1176,7 +1266,7 @@ window.chatInteractionManager = function () {
1176
1266
  }
1177
1267
  },
1178
1268
  startConversationMode: function startConversationMode() {
1179
- var _this9 = this;
1269
+ var _this12 = this;
1180
1270
  if (!this.conversationModeEnabled || this.isConversationMode || !this.connection) {
1181
1271
  return;
1182
1272
  }
@@ -1196,30 +1286,30 @@ window.chatInteractionManager = function () {
1196
1286
  }
1197
1287
  }).then(function (stream) {
1198
1288
  var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus') ? 'audio/ogg;codecs=opus' : MediaRecorder.isTypeSupported('audio/webm;codecs=opus') ? 'audio/webm;codecs=opus' : 'audio/webm';
1199
- _this9.mediaRecorder = new MediaRecorder(stream, {
1289
+ _this12.mediaRecorder = new MediaRecorder(stream, {
1200
1290
  mimeType: mimeType,
1201
1291
  audioBitsPerSecond: 128000
1202
1292
  });
1203
- _this9._conversationSubject = new signalR.Subject();
1204
- _this9._conversationStream = stream;
1293
+ _this12._conversationSubject = new signalR.Subject();
1294
+ _this12._conversationStream = stream;
1205
1295
 
1206
1296
  // Create an AnalyserNode for volume-based interrupt detection.
1207
1297
  var AudioCtx = window.AudioContext || window.webkitAudioContext;
1208
1298
  if (AudioCtx) {
1209
- _this9._conversationAudioCtx = new AudioCtx();
1210
- _this9._conversationAnalyser = _this9._conversationAudioCtx.createAnalyser();
1211
- _this9._conversationAnalyser.fftSize = 256;
1212
- var micSource = _this9._conversationAudioCtx.createMediaStreamSource(stream);
1213
- micSource.connect(_this9._conversationAnalyser);
1299
+ _this12._conversationAudioCtx = new AudioCtx();
1300
+ _this12._conversationAnalyser = _this12._conversationAudioCtx.createAnalyser();
1301
+ _this12._conversationAnalyser.fftSize = 256;
1302
+ var micSource = _this12._conversationAudioCtx.createMediaStreamSource(stream);
1303
+ micSource.connect(_this12._conversationAnalyser);
1214
1304
  }
1215
1305
  var pendingChunk = Promise.resolve();
1216
- var analyser = _this9._conversationAnalyser;
1306
+ var analyser = _this12._conversationAnalyser;
1217
1307
  var interruptVolumeThreshold = 30;
1218
- _this9.mediaRecorder.addEventListener('dataavailable', function (e) {
1308
+ _this12.mediaRecorder.addEventListener('dataavailable', function (e) {
1219
1309
  if (e.data && e.data.size > 0) {
1220
1310
  // During TTS playback, check mic volume to detect
1221
1311
  // user interruption (speaking above threshold).
1222
- if (_this9.isPlayingAudio && analyser) {
1312
+ if (_this12.isPlayingAudio && analyser) {
1223
1313
  var freqData = new Uint8Array(analyser.frequencyBinCount);
1224
1314
  analyser.getByteFrequencyData(freqData);
1225
1315
  var sum = 0;
@@ -1229,7 +1319,7 @@ window.chatInteractionManager = function () {
1229
1319
  var avg = sum / freqData.length;
1230
1320
  if (avg >= interruptVolumeThreshold) {
1231
1321
  // User is speaking — interrupt TTS playback.
1232
- _this9.stopAudio();
1322
+ _this12.stopAudio();
1233
1323
  }
1234
1324
  }
1235
1325
 
@@ -1251,7 +1341,7 @@ window.chatInteractionManager = function () {
1251
1341
  }, '');
1252
1342
  base64 = btoa(binaryString);
1253
1343
  try {
1254
- _this9._conversationSubject.next(base64);
1344
+ _this12._conversationSubject.next(base64);
1255
1345
  } catch (err) {
1256
1346
  // Subject may have been completed already.
1257
1347
  }
@@ -1262,27 +1352,27 @@ window.chatInteractionManager = function () {
1262
1352
  })));
1263
1353
  }
1264
1354
  });
1265
- _this9.mediaRecorder.addEventListener('stop', function () {
1355
+ _this12.mediaRecorder.addEventListener('stop', function () {
1266
1356
  stream.getTracks().forEach(function (track) {
1267
1357
  return track.stop();
1268
1358
  });
1269
1359
  pendingChunk.then(function () {
1270
1360
  try {
1271
- _this9._conversationSubject.complete();
1361
+ _this12._conversationSubject.complete();
1272
1362
  } catch (err) {
1273
1363
  // Already completed.
1274
1364
  }
1275
1365
  });
1276
1366
  });
1277
- var itemId = _this9.getItemId();
1367
+ var itemId = _this12.getItemId();
1278
1368
  var language = navigator.language || document.documentElement.lang || 'en-US';
1279
- _this9.connection.send("StartConversation", itemId, _this9._conversationSubject, mimeType, language);
1280
- _this9.mediaRecorder.start(250);
1281
- _this9.isRecording = true;
1369
+ _this12.connection.send("StartConversation", itemId, _this12._conversationSubject, mimeType, language);
1370
+ _this12.mediaRecorder.start(250);
1371
+ _this12.isRecording = true;
1282
1372
  })["catch"](function (err) {
1283
1373
  console.error('Microphone access denied:', err);
1284
- _this9.isConversationMode = false;
1285
- _this9.updateConversationButton();
1374
+ _this12.isConversationMode = false;
1375
+ _this12.updateConversationButton();
1286
1376
  });
1287
1377
  },
1288
1378
  stopConversationMode: function stopConversationMode() {
@@ -1386,12 +1476,12 @@ window.chatInteractionManager = function () {
1386
1476
  return removedCount;
1387
1477
  },
1388
1478
  scrollToBottom: function scrollToBottom() {
1389
- var _this0 = this;
1479
+ var _this13 = this;
1390
1480
  if (!this.autoScroll) {
1391
1481
  return;
1392
1482
  }
1393
1483
  setTimeout(function () {
1394
- _this0.chatContainer.scrollTop = _this0.chatContainer.scrollHeight - _this0.chatContainer.clientHeight;
1484
+ _this13.chatContainer.scrollTop = _this13.chatContainer.scrollHeight - _this13.chatContainer.clientHeight;
1395
1485
  }, 50);
1396
1486
  },
1397
1487
  handleUserInput: function handleUserInput(event) {
@@ -1407,7 +1497,7 @@ window.chatInteractionManager = function () {
1407
1497
  return document.querySelector('[data-chat-interaction-save-indicator]');
1408
1498
  },
1409
1499
  showSaveIndicator: function showSaveIndicator(text, className) {
1410
- var _this1 = this;
1500
+ var _this14 = this;
1411
1501
  var indicator = this.getSaveIndicatorElement();
1412
1502
  if (!indicator) {
1413
1503
  return;
@@ -1423,7 +1513,7 @@ window.chatInteractionManager = function () {
1423
1513
  }
1424
1514
  this.saveIndicatorTimeout = setTimeout(function () {
1425
1515
  indicator.textContent = '';
1426
- _this1.saveIndicatorTimeout = null;
1516
+ _this14.saveIndicatorTimeout = null;
1427
1517
  }, 3000);
1428
1518
  },
1429
1519
  clearPendingSettingsSave: function clearPendingSettingsSave() {
@@ -1497,10 +1587,10 @@ window.chatInteractionManager = function () {
1497
1587
  return false;
1498
1588
  },
1499
1589
  validateSettings: function validateSettings() {
1500
- var _this10 = this;
1590
+ var _this15 = this;
1501
1591
  var isValid = true;
1502
1592
  this.getSettingInputs().forEach(function (input) {
1503
- isValid = _this10.validateSettingInput(input) && isValid;
1593
+ isValid = _this15.validateSettingInput(input) && isValid;
1504
1594
  });
1505
1595
  return isValid;
1506
1596
  },
@@ -1523,7 +1613,7 @@ window.chatInteractionManager = function () {
1523
1613
  return document.querySelectorAll('input[name^="ChatInteraction."]:not([name*=".Tools["]):not([name*=".Connections["]), ' + 'select[name^="ChatInteraction."]:not([name*=".Tools["]):not([name*=".Connections["]), ' + 'textarea[name^="ChatInteraction."]:not([name*=".Tools["]):not([name*=".Connections["])');
1524
1614
  },
1525
1615
  getSelectedGroupValues: function getSelectedGroupValues(groupName, fallbackSelector) {
1526
- var explicitSelections = document.querySelectorAll(".capability-checkbox[data-save-group=\"".concat(groupName, "\"]:checked"));
1616
+ var explicitSelections = document.querySelectorAll(".capability-checkbox[data-save-group=\"".concat(groupName, "\"]:checked, .capability-checkbox[data-group=\"").concat(groupName, "\"]:checked"));
1527
1617
  if (explicitSelections.length > 0) {
1528
1618
  var _values = [];
1529
1619
  explicitSelections.forEach(function (checkbox) {
@@ -1596,12 +1686,12 @@ window.chatInteractionManager = function () {
1596
1686
  }
1597
1687
  },
1598
1688
  scheduleNotificationDismiss: function scheduleNotificationDismiss(notification) {
1599
- var _this11 = this;
1689
+ var _this16 = this;
1600
1690
  if (!notification || !notification.type || !notification.autoDismissMs || notification.autoDismissMs <= 0) {
1601
1691
  return;
1602
1692
  }
1603
1693
  this.notificationDismissTimers[notification.type] = setTimeout(function () {
1604
- _this11.removeNotification(notification.type);
1694
+ _this16.removeNotification(notification.type);
1605
1695
  }, notification.autoDismissMs);
1606
1696
  },
1607
1697
  clearNotificationDismiss: function clearNotificationDismiss(notificationType) {
@@ -1641,7 +1731,7 @@ window.chatInteractionManager = function () {
1641
1731
  this.showPlaceholder();
1642
1732
  },
1643
1733
  initializeApp: function initializeApp() {
1644
- var _this12 = this;
1734
+ var _this17 = this;
1645
1735
  this.inputElement = document.querySelector(config.inputElementSelector);
1646
1736
  this.buttonElement = document.querySelector(config.sendButtonElementSelector);
1647
1737
  this.chatContainer = document.querySelector(config.chatContainerElementSelector);
@@ -1653,59 +1743,59 @@ window.chatInteractionManager = function () {
1653
1743
 
1654
1744
  // Pause auto-scroll when the user manually scrolls up during streaming.
1655
1745
  this.chatContainer.addEventListener('scroll', function () {
1656
- if (!_this12.stream) {
1746
+ if (!_this17.stream) {
1657
1747
  return;
1658
1748
  }
1659
1749
  var threshold = 30;
1660
- var atBottom = _this12.chatContainer.scrollHeight - _this12.chatContainer.clientHeight - _this12.chatContainer.scrollTop <= threshold;
1661
- _this12.autoScroll = atBottom;
1750
+ var atBottom = _this17.chatContainer.scrollHeight - _this17.chatContainer.clientHeight - _this17.chatContainer.scrollTop <= threshold;
1751
+ _this17.autoScroll = atBottom;
1662
1752
  });
1663
1753
  this.inputElement.addEventListener('keyup', function (event) {
1664
- if (_this12.stream != null) {
1754
+ if (_this17.stream != null) {
1665
1755
  return;
1666
1756
  }
1667
1757
  if (event.key === "Enter" && !event.shiftKey) {
1668
- _this12.buttonElement.click();
1758
+ _this17.buttonElement.click();
1669
1759
  }
1670
1760
  });
1671
1761
  this.inputElement.addEventListener('input', function (e) {
1672
- _this12.handleUserInput(e);
1762
+ _this17.handleUserInput(e);
1673
1763
  if (e.target.value.trim()) {
1674
- _this12.buttonElement.removeAttribute('disabled');
1764
+ _this17.buttonElement.removeAttribute('disabled');
1675
1765
  } else {
1676
- _this12.buttonElement.setAttribute('disabled', true);
1766
+ _this17.buttonElement.setAttribute('disabled', true);
1677
1767
  }
1678
1768
  });
1679
1769
  this.inputElement.addEventListener('paste', function (e) {
1680
1770
  // Use setTimeout to allow the paste to complete before checking the value
1681
1771
  setTimeout(function () {
1682
- _this12.prompt = _this12.inputElement.value;
1683
- if (_this12.inputElement.value.trim()) {
1684
- _this12.buttonElement.removeAttribute('disabled');
1772
+ _this17.prompt = _this17.inputElement.value;
1773
+ if (_this17.inputElement.value.trim()) {
1774
+ _this17.buttonElement.removeAttribute('disabled');
1685
1775
  } else {
1686
- _this12.buttonElement.setAttribute('disabled', true);
1776
+ _this17.buttonElement.setAttribute('disabled', true);
1687
1777
  }
1688
1778
  }, 0);
1689
1779
  });
1690
1780
  this.buttonElement.addEventListener('click', function () {
1691
- if (_this12.stream != null) {
1692
- _this12.stream.dispose();
1693
- _this12.stream = null;
1694
- _this12.streamingFinished();
1695
- _this12.hideTypingIndicator();
1781
+ if (_this17.stream != null) {
1782
+ _this17.stream.dispose();
1783
+ _this17.stream = null;
1784
+ _this17.streamingFinished();
1785
+ _this17.hideTypingIndicator();
1696
1786
 
1697
1787
  // Clean up: remove empty assistant message or stop streaming animation.
1698
- if (_this12.messages.length > 0) {
1699
- var lastMsg = _this12.messages[_this12.messages.length - 1];
1788
+ if (_this17.messages.length > 0) {
1789
+ var lastMsg = _this17.messages[_this17.messages.length - 1];
1700
1790
  if (lastMsg.role === 'assistant' && !lastMsg.content) {
1701
- _this12.messages.pop();
1791
+ _this17.messages.pop();
1702
1792
  } else if (lastMsg.isStreaming) {
1703
1793
  lastMsg.isStreaming = false;
1704
1794
  }
1705
1795
  }
1706
1796
  return;
1707
1797
  }
1708
- _this12.sendMessage();
1798
+ _this17.sendMessage();
1709
1799
  });
1710
1800
  var chatInteractionItems = document.getElementsByClassName('chat-interaction-history-item');
1711
1801
  for (var i = 0; i < chatInteractionItems.length; i++) {
@@ -1716,11 +1806,11 @@ window.chatInteractionManager = function () {
1716
1806
  console.error('An element with the class chat-interaction-history-item with no data-interaction-id set.');
1717
1807
  return;
1718
1808
  }
1719
- _this12.loadInteraction(itemId);
1809
+ _this17.loadInteraction(itemId);
1720
1810
  });
1721
1811
  }
1722
- for (var _i3 = 0; _i3 < config.messages.length; _i3++) {
1723
- this.addMessage(config.messages[_i3]);
1812
+ for (var _i4 = 0; _i4 < config.messages.length; _i4++) {
1813
+ this.addMessage(config.messages[_i4]);
1724
1814
  }
1725
1815
 
1726
1816
  // Delegate click for code block copy buttons.
@@ -1747,20 +1837,20 @@ window.chatInteractionManager = function () {
1747
1837
  }
1748
1838
  document.addEventListener('input', function (event) {
1749
1839
  if (event.target.matches('.setting-input[data-setting]')) {
1750
- _this12.validateSettingInput(event.target);
1751
- _this12.queueSettingsSave();
1840
+ _this17.validateSettingInput(event.target);
1841
+ _this17.queueSettingsSave();
1752
1842
  }
1753
1843
  });
1754
1844
  document.addEventListener('change', function (event) {
1755
- if (event.target.matches('.setting-input[data-setting], .capability-checkbox[data-save-group], .group-toggle, .ci-agent-global-toggle')) {
1845
+ if (event.target.matches('.setting-input[data-setting], .capability-checkbox[data-save-group], .capability-checkbox[data-group], .group-toggle, .ci-agent-global-toggle')) {
1756
1846
  if (event.target.matches('.setting-input[data-setting]')) {
1757
- _this12.validateSettingInput(event.target);
1847
+ _this17.validateSettingInput(event.target);
1758
1848
  }
1759
- _this12.queueSettingsSave();
1849
+ _this17.queueSettingsSave();
1760
1850
  return;
1761
1851
  }
1762
1852
  if (event.target.closest('.prompt-template-parameters-input, .prompt-template-id-input')) {
1763
- _this12.queueSettingsSave();
1853
+ _this17.queueSettingsSave();
1764
1854
  }
1765
1855
  });
1766
1856
  document.addEventListener('click', function (event) {
@@ -1768,7 +1858,7 @@ window.chatInteractionManager = function () {
1768
1858
  return;
1769
1859
  }
1770
1860
  setTimeout(function () {
1771
- _this12.queueSettingsSave();
1861
+ _this17.queueSettingsSave();
1772
1862
  }, 0);
1773
1863
  });
1774
1864
 
@@ -1778,7 +1868,7 @@ window.chatInteractionManager = function () {
1778
1868
  clearHistoryBtn.addEventListener('click', function () {
1779
1869
  var itemId = clearHistoryBtn.getAttribute('data-interaction-id');
1780
1870
  if (itemId) {
1781
- _this12.clearHistory(itemId);
1871
+ _this17.clearHistory(itemId);
1782
1872
  }
1783
1873
  });
1784
1874
  }
@@ -1789,7 +1879,7 @@ window.chatInteractionManager = function () {
1789
1879
  if (this.micButton) {
1790
1880
  this.micButton.style.display = '';
1791
1881
  this.micButton.addEventListener('click', function () {
1792
- _this12.toggleRecording();
1882
+ _this17.toggleRecording();
1793
1883
  });
1794
1884
  }
1795
1885
  }
@@ -1799,7 +1889,7 @@ window.chatInteractionManager = function () {
1799
1889
  this.conversationButton = document.querySelector(config.conversationButtonElementSelector);
1800
1890
  if (this.conversationButton) {
1801
1891
  this.conversationButton.addEventListener('click', function () {
1802
- _this12.toggleConversationMode();
1892
+ _this17.toggleConversationMode();
1803
1893
  });
1804
1894
  }
1805
1895
  }
@@ -1817,29 +1907,38 @@ window.chatInteractionManager = function () {
1817
1907
  },
1818
1908
  clearHistory: function clearHistory(itemId) {
1819
1909
  var self = this;
1820
- confirmDialog({
1821
- title: config.clearHistoryTitle,
1822
- message: config.clearHistoryMessage,
1823
- okText: config.clearHistoryOkText,
1824
- cancelText: config.clearHistoryCancelText,
1825
- callback: function callback(confirmed) {
1826
- if (confirmed) {
1827
- // Cancel any active stream before clearing history.
1828
- if (self.stream) {
1829
- self.stream.dispose();
1830
- self.stream = null;
1831
- self.hideTypingIndicator();
1832
- self.streamingFinished();
1910
+ var clearHistoryConfirmed = function clearHistoryConfirmed() {
1911
+ // Cancel any active stream before clearing history.
1912
+ if (self.stream) {
1913
+ self.stream.dispose();
1914
+ self.stream = null;
1915
+ self.hideTypingIndicator();
1916
+ self.streamingFinished();
1917
+ }
1918
+ self.connection.invoke("ClearHistory", itemId)["catch"](function (err) {
1919
+ return console.error('Error clearing history:', err);
1920
+ });
1921
+ };
1922
+ if (typeof confirmDialog === 'function') {
1923
+ confirmDialog({
1924
+ title: config.clearHistoryTitle,
1925
+ message: config.clearHistoryMessage,
1926
+ okText: config.clearHistoryOkText,
1927
+ cancelText: config.clearHistoryCancelText,
1928
+ callback: function callback(confirmed) {
1929
+ if (confirmed) {
1930
+ clearHistoryConfirmed();
1833
1931
  }
1834
- self.connection.invoke("ClearHistory", itemId)["catch"](function (err) {
1835
- return console.error('Error clearing history:', err);
1836
- });
1837
1932
  }
1838
- }
1839
- });
1933
+ });
1934
+ return;
1935
+ }
1936
+ if (window.confirm(config.clearHistoryMessage || 'Clear all messages?')) {
1937
+ clearHistoryConfirmed();
1938
+ }
1840
1939
  },
1841
1940
  debouncedSaveSettings: function debouncedSaveSettings() {
1842
- var _this13 = this;
1941
+ var _this18 = this;
1843
1942
  // Clear any existing timeout to reset the debounce timer
1844
1943
  this.clearPendingSettingsSave();
1845
1944
 
@@ -1850,11 +1949,11 @@ window.chatInteractionManager = function () {
1850
1949
 
1851
1950
  // Set a new timeout to save after 850ms of no changes
1852
1951
  this.saveSettingsTimeout = setTimeout(function () {
1853
- if (_this13.settingsDirty) {
1854
- _this13.saveSettings();
1855
- _this13.settingsDirty = false;
1952
+ if (_this18.settingsDirty) {
1953
+ _this18.saveSettings();
1954
+ _this18.settingsDirty = false;
1856
1955
  }
1857
- _this13.saveSettingsTimeout = null;
1956
+ _this18.saveSettingsTimeout = null;
1858
1957
  }, 850);
1859
1958
  },
1860
1959
  getSelectedToolNames: function getSelectedToolNames() {
@@ -1870,7 +1969,7 @@ window.chatInteractionManager = function () {
1870
1969
  return this.getSelectedGroupValues('agentNames', 'input[type="checkbox"][name$="].IsSelected"][name^="ChatInteraction.Agents["]:checked');
1871
1970
  },
1872
1971
  saveSettings: function saveSettings() {
1873
- var _this14 = this;
1972
+ var _this19 = this;
1874
1973
  var itemId = this.getItemId();
1875
1974
  if (!itemId) {
1876
1975
  return Promise.resolve();
@@ -1915,7 +2014,7 @@ window.chatInteractionManager = function () {
1915
2014
  }
1916
2015
  return this.connection.invoke("SaveSettings", itemId, settings)["catch"](function (err) {
1917
2016
  console.error('Error saving settings:', err);
1918
- _this14.showSaveIndicator('Save failed', 'text-danger');
2017
+ _this19.showSaveIndicator('Save failed', 'text-danger');
1919
2018
  });
1920
2019
  },
1921
2020
  flushPendingSave: function flushPendingSave() {
@@ -1942,10 +2041,12 @@ window.chatInteractionManager = function () {
1942
2041
  this.isInteractionStarted = true;
1943
2042
  },
1944
2043
  copyResponse: function copyResponse(message) {
1945
- navigator.clipboard.writeText(message);
2044
+ var _ref13, _message$copyContent;
2045
+ var text = message && _typeof(message) === 'object' ? (_ref13 = (_message$copyContent = message.copyContent) !== null && _message$copyContent !== void 0 ? _message$copyContent : message.content) !== null && _ref13 !== void 0 ? _ref13 : '' : message !== null && message !== void 0 ? message : '';
2046
+ navigator.clipboard.writeText(text);
1946
2047
  },
1947
2048
  startRecording: function startRecording() {
1948
- var _this15 = this;
2049
+ var _this20 = this;
1949
2050
  if (this.isRecording || !this.connection) {
1950
2051
  return;
1951
2052
  }
@@ -1957,16 +2058,16 @@ window.chatInteractionManager = function () {
1957
2058
  }
1958
2059
  }).then(function (stream) {
1959
2060
  var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus') ? 'audio/ogg;codecs=opus' : MediaRecorder.isTypeSupported('audio/webm;codecs=opus') ? 'audio/webm;codecs=opus' : 'audio/webm';
1960
- _this15.mediaRecorder = new MediaRecorder(stream, {
2061
+ _this20.mediaRecorder = new MediaRecorder(stream, {
1961
2062
  mimeType: mimeType,
1962
2063
  audioBitsPerSecond: 128000
1963
2064
  });
1964
- _this15.preRecordingPrompt = _this15.prompt;
1965
- _this15._audioInputSent = false;
2065
+ _this20.preRecordingPrompt = _this20.prompt;
2066
+ _this20._audioInputSent = false;
1966
2067
  var subject = new signalR.Subject();
1967
- var itemId = _this15.getItemId();
2068
+ var itemId = _this20.getItemId();
1968
2069
  var pendingChunk = Promise.resolve();
1969
- _this15.mediaRecorder.addEventListener('dataavailable', function (e) {
2070
+ _this20.mediaRecorder.addEventListener('dataavailable', function (e) {
1970
2071
  if (e.data && e.data.size > 0) {
1971
2072
  pendingChunk = pendingChunk.then(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4() {
1972
2073
  var data, uint8Array, binaryString, base64;
@@ -1990,7 +2091,7 @@ window.chatInteractionManager = function () {
1990
2091
  })));
1991
2092
  }
1992
2093
  });
1993
- _this15.mediaRecorder.addEventListener('stop', function () {
2094
+ _this20.mediaRecorder.addEventListener('stop', function () {
1994
2095
  stream.getTracks().forEach(function (track) {
1995
2096
  return track.stop();
1996
2097
  });
@@ -1999,10 +2100,10 @@ window.chatInteractionManager = function () {
1999
2100
  });
2000
2101
  });
2001
2102
  var language = navigator.language || document.documentElement.lang || 'en-US';
2002
- _this15.connection.send("SendAudioStream", itemId, subject, mimeType, language);
2003
- _this15.mediaRecorder.start(250);
2004
- _this15.isRecording = true;
2005
- _this15.updateMicButton();
2103
+ _this20.connection.send("SendAudioStream", itemId, subject, mimeType, language);
2104
+ _this20.mediaRecorder.start(250);
2105
+ _this20.isRecording = true;
2106
+ _this20.updateMicButton();
2006
2107
  })["catch"](function (err) {
2007
2108
  console.error('Microphone access denied:', err);
2008
2109
  });
@@ -2056,15 +2157,19 @@ window.chatInteractionManager = function () {
2056
2157
  }
2057
2158
  },
2058
2159
  mounted: function mounted() {
2059
- var _this16 = this;
2160
+ var _this21 = this;
2060
2161
  _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5() {
2061
2162
  return _regenerator().w(function (_context5) {
2062
2163
  while (1) switch (_context5.n) {
2063
2164
  case 0:
2064
2165
  _context5.n = 1;
2065
- return _this16.startConnection();
2166
+ return _this21.startConnection();
2066
2167
  case 1:
2067
- _this16.initializeApp();
2168
+ _this21.initializeApp();
2169
+ _this21.$nextTick(function () {
2170
+ refreshFontAwesomeIcons(_this21.$el);
2171
+ _this21.fontAwesomeObserver = observeFontAwesomeIcons(_this21.$el);
2172
+ });
2068
2173
  case 2:
2069
2174
  return _context5.a(2);
2070
2175
  }
@@ -2076,6 +2181,10 @@ window.chatInteractionManager = function () {
2076
2181
  beforeUnmount: function beforeUnmount() {
2077
2182
  window.removeEventListener('beforeunload', this.handleBeforeUnload);
2078
2183
  window.removeEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);
2184
+ if (this.fontAwesomeObserver) {
2185
+ this.fontAwesomeObserver.disconnect();
2186
+ this.fontAwesomeObserver = null;
2187
+ }
2079
2188
  this.stopAudio(false);
2080
2189
  if (this.stream) {
2081
2190
  this.stream.dispose();
@@ -2093,6 +2202,535 @@ window.chatInteractionManager = function () {
2093
2202
  initialize: initialize
2094
2203
  };
2095
2204
  }();
2205
+ window.chatInteractionDocumentManager = function () {
2206
+ var managerStateKey = '__chatInteractionDocumentManagerState';
2207
+ function normalizeDocumentInfo(document) {
2208
+ if (!document || _typeof(document) !== 'object') {
2209
+ return null;
2210
+ }
2211
+ return {
2212
+ documentId: document.documentId || document.DocumentId || '',
2213
+ fileName: document.fileName || document.FileName || '',
2214
+ fileSize: document.fileSize || document.FileSize || 0
2215
+ };
2216
+ }
2217
+ function formatFileSize(bytes) {
2218
+ if (!bytes || bytes < 1024) {
2219
+ return (bytes || 0) + ' B';
2220
+ }
2221
+ if (bytes < 1024 * 1024) {
2222
+ return (bytes / 1024).toFixed(1) + ' KB';
2223
+ }
2224
+ return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
2225
+ }
2226
+ function getDocumentKey(fileName, fileSize) {
2227
+ return (fileName || '').trim().toLowerCase() + '::' + (fileSize || 0);
2228
+ }
2229
+ function isDuplicateFile(file, knownKeys) {
2230
+ return knownKeys.has(getDocumentKey(file.name, file.size));
2231
+ }
2232
+ function getDocumentsFromDom(container) {
2233
+ if (!container) {
2234
+ return [];
2235
+ }
2236
+ return Array.from(container.querySelectorAll('[data-chat-document-id]')).map(function (element) {
2237
+ return normalizeDocumentInfo({
2238
+ documentId: element.dataset.chatDocumentId,
2239
+ fileName: element.dataset.chatDocumentName,
2240
+ fileSize: Number(element.dataset.chatDocumentSize || 0)
2241
+ });
2242
+ }).filter(function (document) {
2243
+ return document && document.documentId;
2244
+ });
2245
+ }
2246
+ function initialize(config) {
2247
+ if (!config || !config.itemId) {
2248
+ return;
2249
+ }
2250
+ var fileInput = document.getElementById('chat-doc-upload');
2251
+ var documentsList = document.getElementById('chat-documents-list');
2252
+ var status = document.getElementById('chat-doc-upload-status');
2253
+ var progressContainer = document.getElementById('chat-doc-upload-progress');
2254
+ var progressBar = document.getElementById('chat-doc-upload-progress-bar');
2255
+ var uploadQueue = document.getElementById('chat-doc-upload-queue');
2256
+ if (!fileInput || !documentsList || !status || !progressContainer || !progressBar || !uploadQueue) {
2257
+ return;
2258
+ }
2259
+ var previousState = fileInput[managerStateKey];
2260
+ if (previousState && typeof previousState.dispose === 'function') {
2261
+ previousState.dispose();
2262
+ }
2263
+ var interactionDocuments = (Array.isArray(config.existingDocuments) ? config.existingDocuments : []).map(normalizeDocumentInfo).filter(function (document) {
2264
+ return document && document.documentId;
2265
+ });
2266
+ if (interactionDocuments.length === 0) {
2267
+ interactionDocuments = getDocumentsFromDom(documentsList);
2268
+ }
2269
+ var uploadItems = [];
2270
+ var isUploadingDocuments = false;
2271
+ function createTextElement(tagName, className, text) {
2272
+ var element = document.createElement(tagName);
2273
+ if (className) {
2274
+ element.className = className;
2275
+ }
2276
+ element.textContent = text;
2277
+ return element;
2278
+ }
2279
+ function renderDocuments() {
2280
+ documentsList.innerHTML = '';
2281
+ if (interactionDocuments.length === 0) {
2282
+ documentsList.appendChild(createTextElement('div', 'text-muted small', 'No documents uploaded yet.'));
2283
+ return;
2284
+ }
2285
+ interactionDocuments.forEach(function (documentInfo) {
2286
+ var row = window.document.createElement('div');
2287
+ row.className = 'd-flex justify-content-between align-items-start gap-2 border rounded px-2 py-2 bg-white chat-document-row';
2288
+ row.dataset.chatDocumentId = documentInfo.documentId;
2289
+ row.dataset.chatDocumentName = documentInfo.fileName;
2290
+ row.dataset.chatDocumentSize = documentInfo.fileSize;
2291
+ var details = window.document.createElement('div');
2292
+ details.className = 'me-2 min-w-0';
2293
+ var name = createTextElement('div', 'fw-semibold small', documentInfo.fileName || 'Document');
2294
+ var icon = window.document.createElement('i');
2295
+ icon.className = 'bi bi-file-earmark-text me-1';
2296
+ name.prepend(icon);
2297
+ var size = createTextElement('div', 'text-muted small', formatFileSize(documentInfo.fileSize));
2298
+ details.appendChild(name);
2299
+ details.appendChild(size);
2300
+ var removeButton = createTextElement('button', 'btn btn-sm btn-outline-danger remove-chat-document-btn', ' Remove');
2301
+ removeButton.type = 'button';
2302
+ removeButton.dataset.documentId = documentInfo.documentId;
2303
+ var removeIcon = window.document.createElement('i');
2304
+ removeIcon.className = 'bi bi-trash';
2305
+ removeButton.prepend(removeIcon);
2306
+ removeButton.addEventListener('click', function () {
2307
+ return removeDocument(documentInfo.documentId);
2308
+ });
2309
+ row.appendChild(details);
2310
+ row.appendChild(removeButton);
2311
+ documentsList.appendChild(row);
2312
+ });
2313
+ }
2314
+ function showUploadStatus(message, cssClass) {
2315
+ if (!message) {
2316
+ status.textContent = '';
2317
+ status.className = 'small mt-2 d-none';
2318
+ return;
2319
+ }
2320
+ status.textContent = message;
2321
+ status.className = 'small mt-2 ' + (cssClass || 'text-muted');
2322
+ }
2323
+ function showUploadProgress(progress, message, cssClass) {
2324
+ if (progress === null || progress === undefined) {
2325
+ progressContainer.className = 'progress mt-2 d-none';
2326
+ progressContainer.setAttribute('aria-valuenow', '0');
2327
+ progressBar.className = 'progress-bar progress-bar-striped progress-bar-animated';
2328
+ progressBar.style.width = '0%';
2329
+ progressBar.textContent = '0%';
2330
+ return;
2331
+ }
2332
+ var roundedProgress = Math.max(0, Math.min(100, Math.round(progress)));
2333
+ progressContainer.className = 'progress mt-2';
2334
+ progressContainer.setAttribute('aria-valuenow', roundedProgress.toString());
2335
+ progressBar.className = 'progress-bar ' + (cssClass || 'progress-bar-striped progress-bar-animated');
2336
+ progressBar.style.width = roundedProgress + '%';
2337
+ progressBar.textContent = message || roundedProgress + '%';
2338
+ }
2339
+ function getUploadStatePresentation(state) {
2340
+ switch (state) {
2341
+ case 'uploaded':
2342
+ return {
2343
+ label: 'Uploaded',
2344
+ badgeClass: 'text-bg-success',
2345
+ progressClass: 'bg-success'
2346
+ };
2347
+ case 'failed':
2348
+ return {
2349
+ label: 'Failed',
2350
+ badgeClass: 'text-bg-danger',
2351
+ progressClass: 'bg-danger'
2352
+ };
2353
+ case 'uploading':
2354
+ return {
2355
+ label: 'Uploading',
2356
+ badgeClass: 'text-bg-warning',
2357
+ progressClass: 'bg-warning progress-bar-striped progress-bar-animated'
2358
+ };
2359
+ default:
2360
+ return {
2361
+ label: 'Queued',
2362
+ badgeClass: 'text-bg-secondary',
2363
+ progressClass: 'bg-secondary progress-bar-striped progress-bar-animated'
2364
+ };
2365
+ }
2366
+ }
2367
+ function formatUploadMessage(item) {
2368
+ if (item.status === 'failed' && item.error) {
2369
+ return item.error;
2370
+ }
2371
+ if (item.status === 'uploaded') {
2372
+ return 'Upload completed successfully.';
2373
+ }
2374
+ if (item.status === 'uploading') {
2375
+ return item.progress + '% uploaded';
2376
+ }
2377
+ return 'Waiting to upload...';
2378
+ }
2379
+ function renderUploadQueue() {
2380
+ uploadQueue.innerHTML = '';
2381
+ uploadItems.forEach(function (item) {
2382
+ var presentation = getUploadStatePresentation(item.status);
2383
+ var card = document.createElement('div');
2384
+ card.className = 'border rounded px-2 py-2 bg-white';
2385
+ var header = document.createElement('div');
2386
+ header.className = 'd-flex justify-content-between align-items-start gap-2';
2387
+ var fileDetails = document.createElement('div');
2388
+ fileDetails.className = 'flex-grow-1 min-w-0';
2389
+ fileDetails.appendChild(createTextElement('div', 'fw-semibold small', item.fileName));
2390
+ fileDetails.appendChild(createTextElement('div', 'text-muted small', formatFileSize(item.fileSize)));
2391
+ var badge = createTextElement('span', 'badge ' + presentation.badgeClass, presentation.label);
2392
+ header.appendChild(fileDetails);
2393
+ header.appendChild(badge);
2394
+ var progress = document.createElement('div');
2395
+ progress.className = 'progress mt-2';
2396
+ progress.setAttribute('role', 'progressbar');
2397
+ progress.setAttribute('aria-valuemin', '0');
2398
+ progress.setAttribute('aria-valuemax', '100');
2399
+ progress.setAttribute('aria-valuenow', item.progress.toString());
2400
+ var progressState = document.createElement('div');
2401
+ progressState.className = 'progress-bar ' + presentation.progressClass;
2402
+ progressState.style.width = item.progress + '%';
2403
+ progressState.textContent = item.progress + '%';
2404
+ progress.appendChild(progressState);
2405
+ var message = createTextElement('div', item.status === 'failed' ? 'small text-danger mt-2' : 'small text-muted mt-2', formatUploadMessage(item));
2406
+ card.appendChild(header);
2407
+ card.appendChild(progress);
2408
+ card.appendChild(message);
2409
+ uploadQueue.appendChild(card);
2410
+ });
2411
+ }
2412
+ function createUploadItem(file, index) {
2413
+ return {
2414
+ id: file.name + '::' + file.size + '::' + file.lastModified + '::' + index + '::' + Date.now(),
2415
+ fileName: file.name,
2416
+ fileSize: file.size,
2417
+ status: 'queued',
2418
+ progress: 0,
2419
+ error: null
2420
+ };
2421
+ }
2422
+ function updateUploadItem(itemId, updates) {
2423
+ uploadItems = uploadItems.map(function (item) {
2424
+ return item.id === itemId ? Object.assign({}, item, updates) : item;
2425
+ });
2426
+ renderUploadQueue();
2427
+ }
2428
+ function removeUploadItems(predicate) {
2429
+ uploadItems = uploadItems.filter(function (item) {
2430
+ return !predicate(item);
2431
+ });
2432
+ renderUploadQueue();
2433
+ }
2434
+ function uploadSingleDocument(file, itemIdToUpdate, fileIndex, totalFiles) {
2435
+ return new Promise(function (resolve, reject) {
2436
+ var formData = new FormData();
2437
+ formData.append('chatInteractionId', config.itemId);
2438
+ formData.append('files', file);
2439
+ var xhr = new XMLHttpRequest();
2440
+ xhr.open('POST', config.uploadDocumentUrl, true);
2441
+ xhr.upload.addEventListener('progress', function (event) {
2442
+ if (!event.lengthComputable) {
2443
+ return;
2444
+ }
2445
+ var fileProgress = Math.round(event.loaded / event.total * 100);
2446
+ updateUploadItem(itemIdToUpdate, {
2447
+ status: 'uploading',
2448
+ progress: fileProgress
2449
+ });
2450
+ var overallProgress = (fileIndex + event.loaded / event.total) / totalFiles * 100;
2451
+ showUploadProgress(overallProgress, 'Uploading ' + (fileIndex + 1) + ' of ' + totalFiles, 'progress-bar-striped progress-bar-animated');
2452
+ });
2453
+ xhr.addEventListener('load', function () {
2454
+ if (xhr.status >= 200 && xhr.status < 300) {
2455
+ try {
2456
+ resolve(JSON.parse(xhr.responseText));
2457
+ } catch (error) {
2458
+ reject(new Error('Upload failed: invalid server response.'));
2459
+ }
2460
+ return;
2461
+ }
2462
+ reject(new Error((xhr.responseText || 'Upload failed.').trim()));
2463
+ });
2464
+ xhr.addEventListener('error', function () {
2465
+ reject(new Error('Upload failed. Please check your connection and try again.'));
2466
+ });
2467
+ xhr.send(formData);
2468
+ });
2469
+ }
2470
+ function uploadDocuments(_x) {
2471
+ return _uploadDocuments.apply(this, arguments);
2472
+ }
2473
+ function _uploadDocuments() {
2474
+ _uploadDocuments = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee6(files) {
2475
+ var filesToUpload, duplicateItems, knownDocumentKeys, pendingItems, uploadedCount, failedUploads, i, file, pendingItem, result, uploaded, failed, missingUploadMessage, failedMessage, errorMessage, _t2, _t3;
2476
+ return _regenerator().w(function (_context6) {
2477
+ while (1) switch (_context6.p = _context6.n) {
2478
+ case 0:
2479
+ if (!(!config.uploadDocumentUrl || !files || files.length === 0)) {
2480
+ _context6.n = 1;
2481
+ break;
2482
+ }
2483
+ return _context6.a(2);
2484
+ case 1:
2485
+ if (!isUploadingDocuments) {
2486
+ _context6.n = 2;
2487
+ break;
2488
+ }
2489
+ showUploadStatus('A document upload is already in progress.', 'text-warning');
2490
+ return _context6.a(2);
2491
+ case 2:
2492
+ isUploadingDocuments = true;
2493
+ filesToUpload = [];
2494
+ duplicateItems = [];
2495
+ knownDocumentKeys = new Set(interactionDocuments.map(function (document) {
2496
+ return getDocumentKey(document.fileName, document.fileSize);
2497
+ }));
2498
+ Array.from(files).forEach(function (file) {
2499
+ if (isDuplicateFile(file, knownDocumentKeys)) {
2500
+ duplicateItems.push(file);
2501
+ return;
2502
+ }
2503
+ knownDocumentKeys.add(getDocumentKey(file.name, file.size));
2504
+ filesToUpload.push(file);
2505
+ });
2506
+ if (duplicateItems.length > 0) {
2507
+ uploadItems = uploadItems.concat(duplicateItems.map(function (file, index) {
2508
+ return Object.assign(createUploadItem(file, index), {
2509
+ status: 'failed',
2510
+ progress: 100,
2511
+ error: 'This document is already attached.'
2512
+ });
2513
+ }));
2514
+ renderUploadQueue();
2515
+ }
2516
+ if (!(filesToUpload.length === 0)) {
2517
+ _context6.n = 3;
2518
+ break;
2519
+ }
2520
+ isUploadingDocuments = false;
2521
+ showUploadStatus(duplicateItems.map(function (file) {
2522
+ return file.name + ': This document is already attached.';
2523
+ }).join(' | '), 'text-warning');
2524
+ showUploadProgress(null);
2525
+ return _context6.a(2);
2526
+ case 3:
2527
+ pendingItems = filesToUpload.map(createUploadItem);
2528
+ uploadItems = uploadItems.concat(pendingItems);
2529
+ renderUploadQueue();
2530
+ showUploadProgress(0, 'Preparing upload...', 'progress-bar-striped progress-bar-animated');
2531
+ fileInput.disabled = true;
2532
+ _context6.p = 4;
2533
+ uploadedCount = 0;
2534
+ failedUploads = duplicateItems.map(function (file) {
2535
+ return file.name + ': This document is already attached.';
2536
+ });
2537
+ i = 0;
2538
+ case 5:
2539
+ if (!(i < filesToUpload.length)) {
2540
+ _context6.n = 10;
2541
+ break;
2542
+ }
2543
+ file = filesToUpload[i];
2544
+ pendingItem = pendingItems[i];
2545
+ updateUploadItem(pendingItem.id, {
2546
+ status: 'uploading',
2547
+ progress: 0,
2548
+ error: null
2549
+ });
2550
+ showUploadStatus('Uploading ' + (i + 1) + ' of ' + filesToUpload.length + ' document(s)...', 'text-warning');
2551
+ _context6.p = 6;
2552
+ _context6.n = 7;
2553
+ return uploadSingleDocument(file, pendingItem.id, i, filesToUpload.length);
2554
+ case 7:
2555
+ result = _context6.v;
2556
+ uploaded = (Array.isArray(result.uploaded) ? result.uploaded : []).map(normalizeDocumentInfo).filter(function (document) {
2557
+ return document && document.documentId;
2558
+ });
2559
+ failed = Array.isArray(result.failed) ? result.failed : [];
2560
+ if (uploaded.length > 0) {
2561
+ uploadedCount += uploaded.length;
2562
+ interactionDocuments = interactionDocuments.concat(uploaded);
2563
+ updateUploadItem(pendingItem.id, {
2564
+ status: 'uploaded',
2565
+ progress: 100,
2566
+ error: null
2567
+ });
2568
+ } else {
2569
+ missingUploadMessage = failed.length > 0 ? failed.map(function (entry) {
2570
+ return entry.fileName + ': ' + entry.error;
2571
+ }).join(' | ') : 'The server did not confirm that the file was uploaded.';
2572
+ if (failed.length === 0) {
2573
+ failedUploads.push(missingUploadMessage);
2574
+ }
2575
+ updateUploadItem(pendingItem.id, {
2576
+ status: 'failed',
2577
+ progress: 100,
2578
+ error: missingUploadMessage
2579
+ });
2580
+ }
2581
+ if (failed.length > 0) {
2582
+ failedMessage = failed.map(function (entry) {
2583
+ return entry.fileName + ': ' + entry.error;
2584
+ }).join(' | ');
2585
+ failedUploads.push(failedMessage);
2586
+ updateUploadItem(pendingItem.id, {
2587
+ status: 'failed',
2588
+ progress: 100,
2589
+ error: failedMessage
2590
+ });
2591
+ }
2592
+ _context6.n = 9;
2593
+ break;
2594
+ case 8:
2595
+ _context6.p = 8;
2596
+ _t2 = _context6.v;
2597
+ errorMessage = _t2 && _t2.message ? _t2.message : 'Upload failed. Please try again.';
2598
+ console.error('Upload failed:', _t2);
2599
+ failedUploads.push(file.name + ': ' + errorMessage);
2600
+ updateUploadItem(pendingItem.id, {
2601
+ status: 'failed',
2602
+ progress: pendingItem.progress || 0,
2603
+ error: errorMessage
2604
+ });
2605
+ case 9:
2606
+ i++;
2607
+ _context6.n = 5;
2608
+ break;
2609
+ case 10:
2610
+ renderDocuments();
2611
+ if (!(failedUploads.length > 0)) {
2612
+ _context6.n = 11;
2613
+ break;
2614
+ }
2615
+ removeUploadItems(function (item) {
2616
+ return item.status === 'uploaded';
2617
+ });
2618
+ showUploadStatus((uploadedCount > 0 ? 'Uploaded ' + uploadedCount + ' document(s). ' : '') + failedUploads.join(' | '), uploadedCount > 0 ? 'text-warning' : 'text-danger');
2619
+ showUploadProgress(null);
2620
+ return _context6.a(2);
2621
+ case 11:
2622
+ removeUploadItems(function () {
2623
+ return true;
2624
+ });
2625
+ showUploadStatus('Uploaded ' + uploadedCount + ' document(s).', 'text-success');
2626
+ showUploadProgress(null);
2627
+ _context6.n = 13;
2628
+ break;
2629
+ case 12:
2630
+ _context6.p = 12;
2631
+ _t3 = _context6.v;
2632
+ console.error('Upload failed:', _t3);
2633
+ showUploadStatus('Upload failed. Please try again.', 'text-danger');
2634
+ showUploadProgress(null);
2635
+ case 13:
2636
+ _context6.p = 13;
2637
+ isUploadingDocuments = false;
2638
+ fileInput.disabled = false;
2639
+ fileInput.value = '';
2640
+ return _context6.f(13);
2641
+ case 14:
2642
+ return _context6.a(2);
2643
+ }
2644
+ }, _callee6, null, [[6, 8], [4, 12, 13, 14]]);
2645
+ }));
2646
+ return _uploadDocuments.apply(this, arguments);
2647
+ }
2648
+ function removeDocument(_x2) {
2649
+ return _removeDocument.apply(this, arguments);
2650
+ }
2651
+ function _removeDocument() {
2652
+ _removeDocument = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee7(documentId) {
2653
+ var response, result, serverDocuments, _t4, _t5;
2654
+ return _regenerator().w(function (_context7) {
2655
+ while (1) switch (_context7.p = _context7.n) {
2656
+ case 0:
2657
+ if (!(!config.removeDocumentUrl || !documentId || !window.confirm('Remove this document?'))) {
2658
+ _context7.n = 1;
2659
+ break;
2660
+ }
2661
+ return _context7.a(2);
2662
+ case 1:
2663
+ _context7.p = 1;
2664
+ _context7.n = 2;
2665
+ return fetch(config.removeDocumentUrl, {
2666
+ method: 'POST',
2667
+ headers: {
2668
+ 'Content-Type': 'application/json'
2669
+ },
2670
+ body: JSON.stringify({
2671
+ itemId: config.itemId,
2672
+ documentId: documentId
2673
+ })
2674
+ });
2675
+ case 2:
2676
+ response = _context7.v;
2677
+ if (response.ok) {
2678
+ _context7.n = 4;
2679
+ break;
2680
+ }
2681
+ _t4 = console;
2682
+ _context7.n = 3;
2683
+ return response.text();
2684
+ case 3:
2685
+ _t4.error.call(_t4, 'Failed to remove document:', _context7.v);
2686
+ showUploadStatus('Failed to remove document.', 'text-danger');
2687
+ return _context7.a(2);
2688
+ case 4:
2689
+ _context7.n = 5;
2690
+ return response.json();
2691
+ case 5:
2692
+ result = _context7.v;
2693
+ serverDocuments = (Array.isArray(result.documents) ? result.documents : []).map(normalizeDocumentInfo).filter(function (document) {
2694
+ return document && document.documentId;
2695
+ });
2696
+ interactionDocuments = serverDocuments.length > 0 ? serverDocuments : interactionDocuments.filter(function (document) {
2697
+ return document.documentId !== documentId;
2698
+ });
2699
+ renderDocuments();
2700
+ showUploadStatus('Document removed.', 'text-success');
2701
+ _context7.n = 7;
2702
+ break;
2703
+ case 6:
2704
+ _context7.p = 6;
2705
+ _t5 = _context7.v;
2706
+ console.error('Remove failed:', _t5);
2707
+ showUploadStatus('Failed to remove document.', 'text-danger');
2708
+ case 7:
2709
+ return _context7.a(2);
2710
+ }
2711
+ }, _callee7, null, [[1, 6]]);
2712
+ }));
2713
+ return _removeDocument.apply(this, arguments);
2714
+ }
2715
+ var onFileInputChange = function onFileInputChange(event) {
2716
+ var selectedFiles = event.target.files ? Array.from(event.target.files) : [];
2717
+ uploadDocuments(selectedFiles);
2718
+ };
2719
+ fileInput.addEventListener('change', onFileInputChange);
2720
+ fileInput[managerStateKey] = {
2721
+ dispose: function dispose() {
2722
+ fileInput.removeEventListener('change', onFileInputChange);
2723
+ }
2724
+ };
2725
+ renderDocuments();
2726
+ renderUploadQueue();
2727
+ showUploadStatus(null);
2728
+ showUploadProgress(null);
2729
+ }
2730
+ return {
2731
+ initialize: initialize
2732
+ };
2733
+ }();
2096
2734
 
2097
2735
  // Download chart as image via event delegation (DOMPurify strips inline onclick).
2098
2736
  document.addEventListener('click', function (e) {