@crestapps/ai-chat-ui 1.0.0-preview.90 → 1.0.0-preview.95
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-chat-widget.js +153 -5
- package/dist/ai-chat-widget.js.map +1 -1
- package/dist/ai-chat-widget.min.js +1 -1
- package/dist/ai-chat-widget.min.js.map +1 -1
- package/dist/ai-chat.css +13 -0
- package/dist/ai-chat.css.map +1 -1
- package/dist/ai-chat.js +432 -157
- package/dist/ai-chat.js.map +1 -1
- package/dist/ai-chat.min.css +1 -1
- package/dist/ai-chat.min.js +1 -1
- package/dist/ai-chat.min.js.map +1 -1
- package/dist/chat-interaction-settings.js +63 -0
- package/dist/chat-interaction-settings.js.map +1 -1
- package/dist/chat-interaction-settings.min.js +1 -1
- package/dist/chat-interaction-settings.min.js.map +1 -1
- package/dist/chat-interaction.js +424 -163
- package/dist/chat-interaction.js.map +1 -1
- package/dist/chat-interaction.min.js +1 -1
- package/dist/chat-interaction.min.js.map +1 -1
- package/dist/chat-widget.css +13 -0
- package/dist/chat-widget.css.map +1 -1
- package/dist/chat-widget.min.css +1 -1
- package/dist/document-drop-zone.js +92 -14
- package/dist/document-drop-zone.js.map +1 -1
- package/dist/document-drop-zone.min.js +1 -1
- package/dist/document-drop-zone.min.js.map +1 -1
- package/package.json +1 -1
package/dist/ai-chat.js
CHANGED
|
@@ -22,7 +22,7 @@ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length)
|
|
|
22
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
23
|
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
24
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); }
|
|
25
|
-
window.
|
|
25
|
+
window.coreAIChatManager = function () {
|
|
26
26
|
// Defaults (can be overridden by instanceConfig)
|
|
27
27
|
var defaultConfig = {
|
|
28
28
|
// UI defaults for generated media
|
|
@@ -36,7 +36,9 @@ window.openAIChatManager = function () {
|
|
|
36
36
|
thumbsUpTitle: 'Thumbs up',
|
|
37
37
|
thumbsDownTitle: 'Thumbs down',
|
|
38
38
|
copyTitle: 'Click here to copy response to clipboard.',
|
|
39
|
+
copiedTitle: 'Response copied to clipboard.',
|
|
39
40
|
codeCopiedText: 'Copied!',
|
|
41
|
+
copyResetDelayMs: 2000,
|
|
40
42
|
widget: {
|
|
41
43
|
chatWidgetContainer: null,
|
|
42
44
|
chatWidgetStateName: null,
|
|
@@ -55,7 +57,7 @@ window.openAIChatManager = function () {
|
|
|
55
57
|
minWidth: 320,
|
|
56
58
|
minHeight: 420
|
|
57
59
|
},
|
|
58
|
-
messageTemplate: "\n <div class=\"ai-chat-messages\">\n <div v-for=\"(message, index) in messages\" :key=\"'msg-' + index\" class=\"ai-chat-message-item\">\n <div>\n <div v-if=\"message.role === 'user'\" class=\"ai-chat-msg-role ai-chat-msg-role-user\">{{ userLabel }}</div>\n <div v-else-if=\"message.role !== 'indicator'\" :class=\"getAssistantRoleClasses(message)\">\n <span :class=\"getAssistantIconClasses(message, index)\"><i :class=\"getAssistantIcon(message)\"></i></span>\n {{ getAssistantLabel(message) }}\n </div>\n <div class=\"ai-chat-message-body lh-base\">\n <h4 v-if=\"message.title\">{{ message.title }}</h4>\n <div v-html=\"message.htmlContent\"></div>\n <ol v-if=\"message.citationReferences && message.citationReferences.length\" class=\"ai-chat-citation-list\">\n <li v-for=\"citation in message.citationReferences\" :key=\"'citation-' + (citation.referenceKey || citation.displayIndex)\" class=\"ai-chat-citation-item\">\n <a v-if=\"citation.link\" :href=\"citation.link\" :target=\"citation.isDownload ? null : '_blank'\" :rel=\"citation.isDownload ? null : 'noopener noreferrer'\">{{ citation.label }}</a>\n <span v-else>{{ citation.label }}</span>\n </li>\n </ol>\n <span class=\"message-buttons-container\" v-if=\"!isIndicator(message)\">\n <template v-if=\"metricsEnabled && message.role === 'assistant'\">\n <span class=\"ai-chat-message-assistant-feedback\" :data-message-id=\"message.id\">\n <button type=\"button\" class=\"btn btn-sm btn-link text-success p-0 me-2 button-message-toolbox rate-up-btn\" @click=\"rateMessage(message, true, $event)\" :title=\"thumbsUpTitle\">\n <i class=\"fa-regular fa-thumbs-up\"></i>\n </button>\n <button type=\"button\" class=\"btn btn-sm btn-link text-danger p-0 me-2 button-message-toolbox rate-down-btn\" @click=\"rateMessage(message, false, $event)\" :title=\"thumbsDownTitle\">\n <i class=\"fa-regular fa-thumbs-down\"></i>\n </button>\n </span>\n </template>\n <button type=\"button\" v-if=\"textToSpeechEnabled && !isConversationMode && message.role === 'assistant' && !message.isStreaming\" class=\"btn btn-sm btn-link text-secondary p-0 me-1 button-message-toolbox\" :class=\"{ 'tts-playing': ttsPlayingMessageIndex === index }\" :data-tts-message-index=\"index\" @click=\"toggleMessageTts(message, index)\" :title=\"ttsPlayingMessageIndex === index ? 'Pause audio' : 'Read aloud'\">\n <span :class=\"ttsPlayingMessageIndex === index ? 'fa-solid fa-circle-pause' : 'fa-solid fa-circle-play'\"></span>\n </button>\n <button type=\"button\" class=\"btn btn-sm btn-link
|
|
60
|
+
messageTemplate: "\n <div class=\"ai-chat-messages\">\n <div v-for=\"(message, index) in messages\" :key=\"'msg-' + index\" class=\"ai-chat-message-item\">\n <div>\n <div v-if=\"message.role === 'user'\" class=\"ai-chat-msg-role ai-chat-msg-role-user\">{{ userLabel }}</div>\n <div v-else-if=\"message.role !== 'indicator'\" :class=\"getAssistantRoleClasses(message)\">\n <span :class=\"getAssistantIconClasses(message, index)\"><i :class=\"getAssistantIcon(message)\"></i></span>\n {{ getAssistantLabel(message) }}\n </div>\n <div class=\"ai-chat-message-body lh-base\">\n <h4 v-if=\"message.title\">{{ message.title }}</h4>\n <div v-html=\"message.htmlContent\"></div>\n <ol v-if=\"message.citationReferences && message.citationReferences.length\" class=\"ai-chat-citation-list\">\n <li v-for=\"citation in message.citationReferences\" :key=\"'citation-' + (citation.referenceKey || citation.displayIndex)\" class=\"ai-chat-citation-item\">\n <a v-if=\"citation.link\" :href=\"citation.link\" :target=\"citation.isDownload ? null : '_blank'\" :rel=\"citation.isDownload ? null : 'noopener noreferrer'\">{{ citation.label }}</a>\n <span v-else>{{ citation.label }}</span>\n </li>\n </ol>\n <span class=\"message-buttons-container\" v-if=\"!isIndicator(message)\">\n <template v-if=\"metricsEnabled && message.role === 'assistant'\">\n <span class=\"ai-chat-message-assistant-feedback\" :data-message-id=\"message.id\">\n <button type=\"button\" class=\"btn btn-sm btn-link text-success p-0 me-2 button-message-toolbox rate-up-btn\" @click=\"rateMessage(message, true, $event)\" :title=\"thumbsUpTitle\">\n <i class=\"fa-regular fa-thumbs-up\"></i>\n </button>\n <button type=\"button\" class=\"btn btn-sm btn-link text-danger p-0 me-2 button-message-toolbox rate-down-btn\" @click=\"rateMessage(message, false, $event)\" :title=\"thumbsDownTitle\">\n <i class=\"fa-regular fa-thumbs-down\"></i>\n </button>\n </span>\n </template>\n <button type=\"button\" v-if=\"textToSpeechEnabled && !isConversationMode && message.role === 'assistant' && !message.isStreaming\" class=\"btn btn-sm btn-link text-secondary p-0 me-1 button-message-toolbox\" :class=\"{ 'tts-playing': ttsPlayingMessageIndex === index }\" :data-tts-message-index=\"index\" @click=\"toggleMessageTts(message, index)\" :title=\"ttsPlayingMessageIndex === index ? 'Pause audio' : 'Read aloud'\">\n <span :class=\"ttsPlayingMessageIndex === index ? 'fa-solid fa-circle-pause' : 'fa-solid fa-circle-play'\"></span>\n </button>\n <button type=\"button\" class=\"btn btn-sm btn-link p-0 button-message-toolbox ai-response-copy-btn\" :class=\"copiedMessageIndex === index ? 'text-success' : 'text-secondary'\" :data-copy-message-index=\"index\" @click=\"copyResponse(message, index, $event)\" :title=\"copiedMessageIndex === index ? copiedTitle : copyTitle\">\n <i :class=\"copiedMessageIndex === index ? 'fa-solid fa-check' : 'fa-solid fa-copy'\"></i>\n </button>\n </span>\n </div>\n </div>\n </div>\n <div v-for=\"notification in notifications\" :key=\"'notif-' + notification.type\" class=\"ai-chat-notification\" :class=\"'ai-chat-notification-' + (notification.type || 'info') + ' ' + (notification.cssClass || '')\">\n <div class=\"ai-chat-notification-content\">\n <i v-if=\"notification.icon\" :class=\"notification.icon\" class=\"ai-chat-notification-icon\"></i>\n <span class=\"ai-chat-notification-text\">{{ notification.content }}</span>\n <button type=\"button\" v-if=\"notification.dismissible\" class=\"btn btn-sm btn-link p-0 ms-2 ai-chat-notification-dismiss\" @click=\"dismissNotification(notification.type)\" title=\"Dismiss\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n <div v-if=\"notification.actions && notification.actions.length\" class=\"ai-chat-notification-actions\">\n <button type=\"button\" v-for=\"action in notification.actions\" :key=\"action.name\" class=\"btn btn-sm\" :class=\"action.cssClass || 'btn-outline-secondary'\" @click=\"handleNotificationAction(notification.type, action.name)\">\n <i v-if=\"action.icon\" :class=\"action.icon\" class=\"me-1\"></i>\n {{ action.label }}\n </button>\n </div>\n </div>\n </div>\n ",
|
|
59
61
|
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 "
|
|
60
62
|
};
|
|
61
63
|
|
|
@@ -125,7 +127,7 @@ window.openAIChatManager = function () {
|
|
|
125
127
|
return Math.min(Math.max(value, min), max);
|
|
126
128
|
}
|
|
127
129
|
function normalizeReference(reference) {
|
|
128
|
-
var _ref, _normalized$index, _ref2, _normalized$text, _ref3, _normalized$title, _ref4, _normalized$link, _ref5, _normalized$reference;
|
|
130
|
+
var _ref, _normalized$index, _ref2, _normalized$text, _ref3, _normalized$title, _ref4, _normalized$link, _ref5, _normalized$reference, _normalized$isGenerat;
|
|
129
131
|
if (!reference || _typeof(reference) !== 'object') {
|
|
130
132
|
return null;
|
|
131
133
|
}
|
|
@@ -135,6 +137,7 @@ window.openAIChatManager = function () {
|
|
|
135
137
|
normalized.title = (_ref3 = (_normalized$title = normalized.title) !== null && _normalized$title !== void 0 ? _normalized$title : normalized.Title) !== null && _ref3 !== void 0 ? _ref3 : null;
|
|
136
138
|
normalized.link = sanitizeUrl((_ref4 = (_normalized$link = normalized.link) !== null && _normalized$link !== void 0 ? _normalized$link : normalized.Link) !== null && _ref4 !== void 0 ? _ref4 : null);
|
|
137
139
|
normalized.referenceType = (_ref5 = (_normalized$reference = normalized.referenceType) !== null && _normalized$reference !== void 0 ? _normalized$reference : normalized.ReferenceType) !== null && _ref5 !== void 0 ? _ref5 : null;
|
|
140
|
+
normalized.isGenerated = ((_normalized$isGenerat = normalized.isGenerated) !== null && _normalized$isGenerat !== void 0 ? _normalized$isGenerat : normalized.IsGenerated) === true;
|
|
138
141
|
return normalized;
|
|
139
142
|
}
|
|
140
143
|
function isDownloadCitationReference(reference) {
|
|
@@ -169,28 +172,42 @@ window.openAIChatManager = function () {
|
|
|
169
172
|
function buildCitationDisplay(content, references) {
|
|
170
173
|
var processedContent = (content || '').trim();
|
|
171
174
|
var messageReferences = normalizeReferences(references);
|
|
172
|
-
|
|
175
|
+
var referenceEntries = Object.entries(messageReferences);
|
|
176
|
+
if (!referenceEntries.length) {
|
|
173
177
|
return {
|
|
174
178
|
content: processedContent,
|
|
175
179
|
citations: []
|
|
176
180
|
};
|
|
177
181
|
}
|
|
178
|
-
var citedRefs =
|
|
182
|
+
var citedRefs = referenceEntries.filter(function (_ref6) {
|
|
179
183
|
var _ref7 = _slicedToArray(_ref6, 1),
|
|
180
184
|
key = _ref7[0];
|
|
181
185
|
return processedContent.includes(key);
|
|
182
186
|
});
|
|
183
|
-
|
|
187
|
+
var generatedRefs = referenceEntries.filter(function (_ref8) {
|
|
188
|
+
var _ref9 = _slicedToArray(_ref8, 2),
|
|
189
|
+
key = _ref9[0],
|
|
190
|
+
value = _ref9[1];
|
|
191
|
+
return value.isGenerated && !processedContent.includes(key);
|
|
192
|
+
});
|
|
193
|
+
if (!citedRefs.length && !generatedRefs.length) {
|
|
184
194
|
return {
|
|
185
195
|
content: processedContent,
|
|
186
196
|
citations: []
|
|
187
197
|
};
|
|
188
198
|
}
|
|
189
|
-
citedRefs.sort(function (
|
|
190
|
-
var
|
|
191
|
-
a =
|
|
192
|
-
var
|
|
193
|
-
b =
|
|
199
|
+
citedRefs.sort(function (_ref0, _ref1) {
|
|
200
|
+
var _ref10 = _slicedToArray(_ref0, 2),
|
|
201
|
+
a = _ref10[1];
|
|
202
|
+
var _ref11 = _slicedToArray(_ref1, 2),
|
|
203
|
+
b = _ref11[1];
|
|
204
|
+
return a.index - b.index;
|
|
205
|
+
});
|
|
206
|
+
generatedRefs.sort(function (_ref12, _ref13) {
|
|
207
|
+
var _ref14 = _slicedToArray(_ref12, 2),
|
|
208
|
+
a = _ref14[1];
|
|
209
|
+
var _ref15 = _slicedToArray(_ref13, 2),
|
|
210
|
+
b = _ref15[1];
|
|
194
211
|
return a.index - b.index;
|
|
195
212
|
});
|
|
196
213
|
var citations = [];
|
|
@@ -224,11 +241,36 @@ window.openAIChatManager = function () {
|
|
|
224
241
|
processedContent = processedContent.replaceAll(citation.placeholder, "<sup>".concat(citation.displayIndex, "</sup>"));
|
|
225
242
|
}
|
|
226
243
|
processedContent = processedContent.replaceAll('</sup><sup>', '</sup><sup>,</sup><sup>');
|
|
244
|
+
|
|
245
|
+
// Generated files (such as exported tabular data) are always offered as a download even when
|
|
246
|
+
// the model does not cite them inline, so the user never loses access to the produced file.
|
|
247
|
+
var _iterator2 = _createForOfIteratorHelper(generatedRefs),
|
|
248
|
+
_step2;
|
|
249
|
+
try {
|
|
250
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
251
|
+
var _step2$value = _slicedToArray(_step2.value, 2),
|
|
252
|
+
_key = _step2$value[0],
|
|
253
|
+
_value = _step2$value[1];
|
|
254
|
+
citations.push({
|
|
255
|
+
referenceKey: _key,
|
|
256
|
+
displayIndex: displayIndex,
|
|
257
|
+
label: getCitationLabel(_value, _key),
|
|
258
|
+
link: _value.link || null,
|
|
259
|
+
isDownload: true,
|
|
260
|
+
placeholder: null
|
|
261
|
+
});
|
|
262
|
+
displayIndex++;
|
|
263
|
+
}
|
|
264
|
+
} catch (err) {
|
|
265
|
+
_iterator2.e(err);
|
|
266
|
+
} finally {
|
|
267
|
+
_iterator2.f();
|
|
268
|
+
}
|
|
227
269
|
return {
|
|
228
270
|
content: processedContent,
|
|
229
|
-
citations: citations.map(function (
|
|
230
|
-
var placeholder =
|
|
231
|
-
citation = _objectWithoutProperties(
|
|
271
|
+
citations: citations.map(function (_ref16) {
|
|
272
|
+
var placeholder = _ref16.placeholder,
|
|
273
|
+
citation = _objectWithoutProperties(_ref16, _excluded);
|
|
232
274
|
return citation;
|
|
233
275
|
})
|
|
234
276
|
};
|
|
@@ -238,24 +280,24 @@ window.openAIChatManager = function () {
|
|
|
238
280
|
if (!copyContent || !Array.isArray(citations) || citations.length === 0) {
|
|
239
281
|
return copyContent;
|
|
240
282
|
}
|
|
241
|
-
var
|
|
242
|
-
|
|
283
|
+
var _iterator3 = _createForOfIteratorHelper(citations),
|
|
284
|
+
_step3;
|
|
243
285
|
try {
|
|
244
|
-
for (
|
|
245
|
-
var citation =
|
|
286
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
287
|
+
var citation = _step3.value;
|
|
246
288
|
copyContent = copyContent.replaceAll(citation.referenceKey, "[".concat(citation.displayIndex, "]"));
|
|
247
289
|
}
|
|
248
290
|
} catch (err) {
|
|
249
|
-
|
|
291
|
+
_iterator3.e(err);
|
|
250
292
|
} finally {
|
|
251
|
-
|
|
293
|
+
_iterator3.f();
|
|
252
294
|
}
|
|
253
295
|
copyContent += '\n\nReferences:\n';
|
|
254
|
-
var
|
|
255
|
-
|
|
296
|
+
var _iterator4 = _createForOfIteratorHelper(citations),
|
|
297
|
+
_step4;
|
|
256
298
|
try {
|
|
257
|
-
for (
|
|
258
|
-
var _citation =
|
|
299
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
300
|
+
var _citation = _step4.value;
|
|
259
301
|
copyContent += "".concat(_citation.displayIndex, ". ").concat(_citation.label);
|
|
260
302
|
if (_citation.link) {
|
|
261
303
|
copyContent += " - ".concat(_citation.link);
|
|
@@ -263,9 +305,9 @@ window.openAIChatManager = function () {
|
|
|
263
305
|
copyContent += '\n';
|
|
264
306
|
}
|
|
265
307
|
} catch (err) {
|
|
266
|
-
|
|
308
|
+
_iterator4.e(err);
|
|
267
309
|
} finally {
|
|
268
|
-
|
|
310
|
+
_iterator4.f();
|
|
269
311
|
}
|
|
270
312
|
return copyContent.trimEnd();
|
|
271
313
|
}
|
|
@@ -447,17 +489,17 @@ window.openAIChatManager = function () {
|
|
|
447
489
|
// Defer to requestAnimationFrame so the browser has fully laid out the
|
|
448
490
|
// canvas elements before Chart.js reads their dimensions.
|
|
449
491
|
requestAnimationFrame(function () {
|
|
450
|
-
var
|
|
451
|
-
|
|
492
|
+
var _iterator5 = _createForOfIteratorHelper(charts),
|
|
493
|
+
_step5;
|
|
452
494
|
try {
|
|
453
|
-
for (
|
|
454
|
-
var c =
|
|
495
|
+
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|
496
|
+
var c = _step5.value;
|
|
455
497
|
renderChartOnCanvas(c.chartId, c.config);
|
|
456
498
|
}
|
|
457
499
|
} catch (err) {
|
|
458
|
-
|
|
500
|
+
_iterator5.e(err);
|
|
459
501
|
} finally {
|
|
460
|
-
|
|
502
|
+
_iterator5.f();
|
|
461
503
|
}
|
|
462
504
|
});
|
|
463
505
|
}
|
|
@@ -531,11 +573,23 @@ window.openAIChatManager = function () {
|
|
|
531
573
|
ADD_ATTR: ['target']
|
|
532
574
|
});
|
|
533
575
|
}
|
|
576
|
+
function compactObject(source) {
|
|
577
|
+
if (!source || _typeof(source) !== 'object') {
|
|
578
|
+
return {};
|
|
579
|
+
}
|
|
580
|
+
return Object.fromEntries(Object.entries(source).filter(function (_ref17) {
|
|
581
|
+
var _ref18 = _slicedToArray(_ref17, 2),
|
|
582
|
+
value = _ref18[1];
|
|
583
|
+
return value !== undefined;
|
|
584
|
+
}));
|
|
585
|
+
}
|
|
534
586
|
var initialize = function initialize(instanceConfig) {
|
|
535
|
-
var
|
|
536
|
-
|
|
537
|
-
var
|
|
538
|
-
|
|
587
|
+
var normalizedInstanceConfig = compactObject(instanceConfig);
|
|
588
|
+
var normalizedWidgetConfig = compactObject(normalizedInstanceConfig.widget);
|
|
589
|
+
var config = Object.assign({}, defaultConfig, normalizedInstanceConfig);
|
|
590
|
+
config.widget = Object.assign({}, defaultConfig.widget || {}, normalizedWidgetConfig);
|
|
591
|
+
var hasWidgetConfig = !!(normalizedWidgetConfig.chatWidgetContainer && normalizedWidgetConfig.chatWidgetStateName);
|
|
592
|
+
var widgetBehavior = window.coreAIChatWidgetBehavior || null;
|
|
539
593
|
// Keep defaultConfig in sync so renderers use overridden values
|
|
540
594
|
defaultConfig = config;
|
|
541
595
|
if (!config.signalRHubUrl) {
|
|
@@ -587,6 +641,7 @@ window.openAIChatManager = function () {
|
|
|
587
641
|
thumbsUpTitle: config.thumbsUpTitle,
|
|
588
642
|
thumbsDownTitle: config.thumbsDownTitle,
|
|
589
643
|
copyTitle: config.copyTitle,
|
|
644
|
+
copiedTitle: config.copiedTitle,
|
|
590
645
|
isRecording: false,
|
|
591
646
|
mediaRecorder: null,
|
|
592
647
|
preRecordingPrompt: '',
|
|
@@ -611,7 +666,10 @@ window.openAIChatManager = function () {
|
|
|
611
666
|
pendingSessionPromise: null,
|
|
612
667
|
pendingSessionResolver: null,
|
|
613
668
|
pendingSessionRejector: null,
|
|
614
|
-
pendingSessionTimeoutId: null
|
|
669
|
+
pendingSessionTimeoutId: null,
|
|
670
|
+
copiedMessageIndex: -1,
|
|
671
|
+
copyResetTimeoutId: null,
|
|
672
|
+
activeCopyButton: null
|
|
615
673
|
};
|
|
616
674
|
},
|
|
617
675
|
computed: {
|
|
@@ -1325,14 +1383,14 @@ window.openAIChatManager = function () {
|
|
|
1325
1383
|
if (message.content && !message.htmlContent) {
|
|
1326
1384
|
message.htmlContent = parseMarkdownContent(message.content, message);
|
|
1327
1385
|
}
|
|
1328
|
-
this.fireEvent(new CustomEvent("
|
|
1386
|
+
this.fireEvent(new CustomEvent("addingCoreAIPromotMessage", {
|
|
1329
1387
|
detail: {
|
|
1330
1388
|
message: message
|
|
1331
1389
|
}
|
|
1332
1390
|
}));
|
|
1333
1391
|
this.messages.push(message);
|
|
1334
1392
|
this.$nextTick(function () {
|
|
1335
|
-
_this4.fireEvent(new CustomEvent("
|
|
1393
|
+
_this4.fireEvent(new CustomEvent("addedCoreAIPromotMessage", {
|
|
1336
1394
|
detail: {
|
|
1337
1395
|
message: message
|
|
1338
1396
|
}
|
|
@@ -1653,9 +1711,9 @@ window.openAIChatManager = function () {
|
|
|
1653
1711
|
var _this9 = this;
|
|
1654
1712
|
references = normalizeReferences(references);
|
|
1655
1713
|
if (Object.keys(references).length) {
|
|
1656
|
-
var
|
|
1714
|
+
var _ref23, _message$rawContent2;
|
|
1657
1715
|
var message = this.messages[messageIndex];
|
|
1658
|
-
message.rawContent = (
|
|
1716
|
+
message.rawContent = (_ref23 = (_message$rawContent2 = message.rawContent) !== null && _message$rawContent2 !== void 0 ? _message$rawContent2 : message.content) !== null && _ref23 !== void 0 ? _ref23 : '';
|
|
1659
1717
|
updateMessagePresentation(message, references);
|
|
1660
1718
|
this.messages[messageIndex] = message;
|
|
1661
1719
|
this.$nextTick(function () {
|
|
@@ -1723,8 +1781,38 @@ window.openAIChatManager = function () {
|
|
|
1723
1781
|
button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');
|
|
1724
1782
|
});
|
|
1725
1783
|
},
|
|
1726
|
-
|
|
1784
|
+
updateCopyButtons: function updateCopyButtons() {
|
|
1727
1785
|
var _this1 = this;
|
|
1786
|
+
if (!this.chatContainer) {
|
|
1787
|
+
return;
|
|
1788
|
+
}
|
|
1789
|
+
var buttons = this.chatContainer.querySelectorAll('[data-copy-message-index]');
|
|
1790
|
+
buttons.forEach(function (button) {
|
|
1791
|
+
var buttonIndex = Number(button.getAttribute('data-copy-message-index'));
|
|
1792
|
+
var isCopied = buttonIndex === _this1.copiedMessageIndex;
|
|
1793
|
+
var iconHtml = isCopied ? '<i class="fa-solid fa-check"></i>' : '<i class="fa-solid fa-copy"></i>';
|
|
1794
|
+
button.classList.toggle('text-success', isCopied);
|
|
1795
|
+
button.classList.toggle('text-secondary', !isCopied);
|
|
1796
|
+
button.setAttribute('title', isCopied ? _this1.copiedTitle : _this1.copyTitle);
|
|
1797
|
+
button.replaceChildren(DOMPurify.sanitize(iconHtml, {
|
|
1798
|
+
RETURN_DOM_FRAGMENT: true
|
|
1799
|
+
}));
|
|
1800
|
+
});
|
|
1801
|
+
},
|
|
1802
|
+
setCopyButtonState: function setCopyButtonState(button, isCopied) {
|
|
1803
|
+
if (!button) {
|
|
1804
|
+
return;
|
|
1805
|
+
}
|
|
1806
|
+
var iconHtml = isCopied ? '<i class="fa-solid fa-check"></i>' : '<i class="fa-solid fa-copy"></i>';
|
|
1807
|
+
button.classList.toggle('text-success', isCopied);
|
|
1808
|
+
button.classList.toggle('text-secondary', !isCopied);
|
|
1809
|
+
button.setAttribute('title', isCopied ? this.copiedTitle : this.copyTitle);
|
|
1810
|
+
button.replaceChildren(DOMPurify.sanitize(iconHtml, {
|
|
1811
|
+
RETURN_DOM_FRAGMENT: true
|
|
1812
|
+
}));
|
|
1813
|
+
},
|
|
1814
|
+
synthesizeSpeech: function synthesizeSpeech(text, cacheIndex) {
|
|
1815
|
+
var _this10 = this;
|
|
1728
1816
|
if (!this.textToSpeechEnabled || !text || !this.connection) {
|
|
1729
1817
|
return;
|
|
1730
1818
|
}
|
|
@@ -1733,16 +1821,16 @@ window.openAIChatManager = function () {
|
|
|
1733
1821
|
this._ttsCacheIndex = cacheIndex !== undefined ? cacheIndex : -1;
|
|
1734
1822
|
this.connection.invoke("SynthesizeSpeech", this.getProfileId(), this.getSessionId(), text, this.ttsVoiceName)["catch"](function (err) {
|
|
1735
1823
|
console.error("TTS synthesis error:", err);
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
return
|
|
1824
|
+
_this10.isPlayingAudio = false;
|
|
1825
|
+
_this10.ttsPlayingMessageIndex = -1;
|
|
1826
|
+
_this10._ttsCacheIndex = -1;
|
|
1827
|
+
_this10.$nextTick(function () {
|
|
1828
|
+
return _this10.updateTtsPlaybackButtons();
|
|
1741
1829
|
});
|
|
1742
1830
|
});
|
|
1743
1831
|
},
|
|
1744
1832
|
toggleMessageTts: function toggleMessageTts(message, index) {
|
|
1745
|
-
var
|
|
1833
|
+
var _this11 = this;
|
|
1746
1834
|
if (this.ttsPlayingMessageIndex === index) {
|
|
1747
1835
|
this.stopAudio();
|
|
1748
1836
|
return;
|
|
@@ -1755,7 +1843,7 @@ window.openAIChatManager = function () {
|
|
|
1755
1843
|
}));
|
|
1756
1844
|
this.ttsPlayingMessageIndex = index;
|
|
1757
1845
|
this.$nextTick(function () {
|
|
1758
|
-
return
|
|
1846
|
+
return _this11.updateTtsPlaybackButtons();
|
|
1759
1847
|
});
|
|
1760
1848
|
if (this.ttsAudioCache[index]) {
|
|
1761
1849
|
this.playAudioBlob(this.ttsAudioCache[index]);
|
|
@@ -1764,13 +1852,13 @@ window.openAIChatManager = function () {
|
|
|
1764
1852
|
this.synthesizeSpeech(message.content, index);
|
|
1765
1853
|
},
|
|
1766
1854
|
playCollectedAudio: function playCollectedAudio() {
|
|
1767
|
-
var
|
|
1855
|
+
var _this12 = this;
|
|
1768
1856
|
if (this.audioChunks.length === 0) {
|
|
1769
1857
|
if (!this.currentAudioElement && this.audioPlayQueue.length === 0) {
|
|
1770
1858
|
this.isPlayingAudio = false;
|
|
1771
1859
|
this.ttsPlayingMessageIndex = -1;
|
|
1772
1860
|
this.$nextTick(function () {
|
|
1773
|
-
return
|
|
1861
|
+
return _this12.updateTtsPlaybackButtons();
|
|
1774
1862
|
});
|
|
1775
1863
|
}
|
|
1776
1864
|
return;
|
|
@@ -1780,18 +1868,18 @@ window.openAIChatManager = function () {
|
|
|
1780
1868
|
}, 0);
|
|
1781
1869
|
var combined = new Uint8Array(totalLength);
|
|
1782
1870
|
var offset = 0;
|
|
1783
|
-
var
|
|
1784
|
-
|
|
1871
|
+
var _iterator6 = _createForOfIteratorHelper(this.audioChunks),
|
|
1872
|
+
_step6;
|
|
1785
1873
|
try {
|
|
1786
|
-
for (
|
|
1787
|
-
var chunk =
|
|
1874
|
+
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
|
1875
|
+
var chunk = _step6.value;
|
|
1788
1876
|
combined.set(chunk, offset);
|
|
1789
1877
|
offset += chunk.length;
|
|
1790
1878
|
}
|
|
1791
1879
|
} catch (err) {
|
|
1792
|
-
|
|
1880
|
+
_iterator6.e(err);
|
|
1793
1881
|
} finally {
|
|
1794
|
-
|
|
1882
|
+
_iterator6.f();
|
|
1795
1883
|
}
|
|
1796
1884
|
this.audioChunks = [];
|
|
1797
1885
|
var blob = new Blob([combined], {
|
|
@@ -1810,39 +1898,39 @@ window.openAIChatManager = function () {
|
|
|
1810
1898
|
this.playAudioBlob(blob);
|
|
1811
1899
|
},
|
|
1812
1900
|
playAudioBlob: function playAudioBlob(blob) {
|
|
1813
|
-
var
|
|
1901
|
+
var _this13 = this;
|
|
1814
1902
|
var url = URL.createObjectURL(blob);
|
|
1815
1903
|
var audio = new Audio(url);
|
|
1816
1904
|
this.currentAudioUrl = url;
|
|
1817
1905
|
this.currentAudioElement = audio;
|
|
1818
1906
|
this.isPlayingAudio = true;
|
|
1819
1907
|
audio.addEventListener('ended', function () {
|
|
1820
|
-
|
|
1821
|
-
|
|
1908
|
+
_this13.currentAudioElement = null;
|
|
1909
|
+
_this13.currentAudioUrl = null;
|
|
1822
1910
|
URL.revokeObjectURL(url);
|
|
1823
|
-
|
|
1911
|
+
_this13.playNextInQueue();
|
|
1824
1912
|
});
|
|
1825
1913
|
audio.addEventListener('error', function () {
|
|
1826
|
-
|
|
1827
|
-
|
|
1914
|
+
_this13.currentAudioElement = null;
|
|
1915
|
+
_this13.currentAudioUrl = null;
|
|
1828
1916
|
URL.revokeObjectURL(url);
|
|
1829
|
-
|
|
1917
|
+
_this13.playNextInQueue();
|
|
1830
1918
|
});
|
|
1831
1919
|
audio.play()["catch"](function (err) {
|
|
1832
1920
|
console.error("Audio playback error:", err);
|
|
1833
|
-
|
|
1834
|
-
|
|
1921
|
+
_this13.currentAudioElement = null;
|
|
1922
|
+
_this13.currentAudioUrl = null;
|
|
1835
1923
|
URL.revokeObjectURL(url);
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
return
|
|
1924
|
+
_this13.audioPlayQueue = [];
|
|
1925
|
+
_this13.isPlayingAudio = false;
|
|
1926
|
+
_this13.ttsPlayingMessageIndex = -1;
|
|
1927
|
+
_this13.$nextTick(function () {
|
|
1928
|
+
return _this13.updateTtsPlaybackButtons();
|
|
1841
1929
|
});
|
|
1842
1930
|
});
|
|
1843
1931
|
},
|
|
1844
1932
|
playNextInQueue: function playNextInQueue() {
|
|
1845
|
-
var
|
|
1933
|
+
var _this14 = this;
|
|
1846
1934
|
if (this.audioPlayQueue.length > 0) {
|
|
1847
1935
|
var nextBlob = this.audioPlayQueue.shift();
|
|
1848
1936
|
this.playAudioBlob(nextBlob);
|
|
@@ -1850,13 +1938,13 @@ window.openAIChatManager = function () {
|
|
|
1850
1938
|
this.isPlayingAudio = false;
|
|
1851
1939
|
this.ttsPlayingMessageIndex = -1;
|
|
1852
1940
|
this.$nextTick(function () {
|
|
1853
|
-
return
|
|
1941
|
+
return _this14.updateTtsPlaybackButtons();
|
|
1854
1942
|
});
|
|
1855
1943
|
this.conversationModeOnAudioEnded();
|
|
1856
1944
|
}
|
|
1857
1945
|
},
|
|
1858
1946
|
stopAudio: function stopAudio() {
|
|
1859
|
-
var
|
|
1947
|
+
var _this15 = this;
|
|
1860
1948
|
if (this.currentAudioElement) {
|
|
1861
1949
|
this.currentAudioElement.pause();
|
|
1862
1950
|
this.currentAudioElement.currentTime = 0;
|
|
@@ -1871,7 +1959,7 @@ window.openAIChatManager = function () {
|
|
|
1871
1959
|
this.isPlayingAudio = false;
|
|
1872
1960
|
this.ttsPlayingMessageIndex = -1;
|
|
1873
1961
|
this.$nextTick(function () {
|
|
1874
|
-
return
|
|
1962
|
+
return _this15.updateTtsPlaybackButtons();
|
|
1875
1963
|
});
|
|
1876
1964
|
},
|
|
1877
1965
|
toggleConversationMode: function toggleConversationMode() {
|
|
@@ -1882,7 +1970,7 @@ window.openAIChatManager = function () {
|
|
|
1882
1970
|
}
|
|
1883
1971
|
},
|
|
1884
1972
|
startConversationMode: function startConversationMode() {
|
|
1885
|
-
var
|
|
1973
|
+
var _this16 = this;
|
|
1886
1974
|
if (!this.conversationModeEnabled || this.isConversationMode || !this.connection) {
|
|
1887
1975
|
return;
|
|
1888
1976
|
}
|
|
@@ -1902,12 +1990,12 @@ window.openAIChatManager = function () {
|
|
|
1902
1990
|
}
|
|
1903
1991
|
}).then(function (stream) {
|
|
1904
1992
|
var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus') ? 'audio/ogg;codecs=opus' : MediaRecorder.isTypeSupported('audio/webm;codecs=opus') ? 'audio/webm;codecs=opus' : 'audio/webm';
|
|
1905
|
-
|
|
1993
|
+
_this16.mediaRecorder = new MediaRecorder(stream, {
|
|
1906
1994
|
mimeType: mimeType,
|
|
1907
1995
|
audioBitsPerSecond: 128000
|
|
1908
1996
|
});
|
|
1909
|
-
|
|
1910
|
-
|
|
1997
|
+
_this16._conversationSubject = new signalR.Subject();
|
|
1998
|
+
_this16._conversationStream = stream;
|
|
1911
1999
|
|
|
1912
2000
|
// Create an AnalyserNode for volume-based interrupt detection.
|
|
1913
2001
|
// During TTS playback, detect when the user speaks above
|
|
@@ -1916,20 +2004,20 @@ window.openAIChatManager = function () {
|
|
|
1916
2004
|
// speaker echo so the STT stream has no gaps.
|
|
1917
2005
|
var AudioCtx = window.AudioContext || window.webkitAudioContext;
|
|
1918
2006
|
if (AudioCtx) {
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
var micSource =
|
|
1923
|
-
micSource.connect(
|
|
2007
|
+
_this16._conversationAudioCtx = new AudioCtx();
|
|
2008
|
+
_this16._conversationAnalyser = _this16._conversationAudioCtx.createAnalyser();
|
|
2009
|
+
_this16._conversationAnalyser.fftSize = 256;
|
|
2010
|
+
var micSource = _this16._conversationAudioCtx.createMediaStreamSource(stream);
|
|
2011
|
+
micSource.connect(_this16._conversationAnalyser);
|
|
1924
2012
|
}
|
|
1925
2013
|
var pendingChunk = Promise.resolve();
|
|
1926
|
-
var analyser =
|
|
2014
|
+
var analyser = _this16._conversationAnalyser;
|
|
1927
2015
|
var interruptVolumeThreshold = 30;
|
|
1928
|
-
|
|
2016
|
+
_this16.mediaRecorder.addEventListener('dataavailable', function (e) {
|
|
1929
2017
|
if (e.data && e.data.size > 0) {
|
|
1930
2018
|
// During TTS playback, check mic volume to detect
|
|
1931
2019
|
// user interruption (speaking above threshold).
|
|
1932
|
-
if (
|
|
2020
|
+
if (_this16.isPlayingAudio && analyser) {
|
|
1933
2021
|
var freqData = new Uint8Array(analyser.frequencyBinCount);
|
|
1934
2022
|
analyser.getByteFrequencyData(freqData);
|
|
1935
2023
|
var sum = 0;
|
|
@@ -1939,7 +2027,7 @@ window.openAIChatManager = function () {
|
|
|
1939
2027
|
var avg = sum / freqData.length;
|
|
1940
2028
|
if (avg >= interruptVolumeThreshold) {
|
|
1941
2029
|
// User is speaking — interrupt TTS playback.
|
|
1942
|
-
|
|
2030
|
+
_this16.stopAudio();
|
|
1943
2031
|
}
|
|
1944
2032
|
}
|
|
1945
2033
|
|
|
@@ -1961,7 +2049,7 @@ window.openAIChatManager = function () {
|
|
|
1961
2049
|
}, '');
|
|
1962
2050
|
base64 = btoa(binaryString);
|
|
1963
2051
|
try {
|
|
1964
|
-
|
|
2052
|
+
_this16._conversationSubject.next(base64);
|
|
1965
2053
|
} catch (err) {
|
|
1966
2054
|
// Subject may have been completed already.
|
|
1967
2055
|
}
|
|
@@ -1972,28 +2060,28 @@ window.openAIChatManager = function () {
|
|
|
1972
2060
|
})));
|
|
1973
2061
|
}
|
|
1974
2062
|
});
|
|
1975
|
-
|
|
2063
|
+
_this16.mediaRecorder.addEventListener('stop', function () {
|
|
1976
2064
|
stream.getTracks().forEach(function (track) {
|
|
1977
2065
|
return track.stop();
|
|
1978
2066
|
});
|
|
1979
2067
|
pendingChunk.then(function () {
|
|
1980
2068
|
try {
|
|
1981
|
-
|
|
2069
|
+
_this16._conversationSubject.complete();
|
|
1982
2070
|
} catch (err) {
|
|
1983
2071
|
// Already completed.
|
|
1984
2072
|
}
|
|
1985
2073
|
});
|
|
1986
2074
|
});
|
|
1987
|
-
var profileId =
|
|
1988
|
-
var sessionId =
|
|
2075
|
+
var profileId = _this16.getProfileId();
|
|
2076
|
+
var sessionId = _this16.getSessionId() || '';
|
|
1989
2077
|
var language = navigator.language || document.documentElement.lang || 'en-US';
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
2078
|
+
_this16.connection.send("StartConversation", profileId, sessionId, _this16._conversationSubject, mimeType, language);
|
|
2079
|
+
_this16.mediaRecorder.start(250);
|
|
2080
|
+
_this16.isRecording = true;
|
|
1993
2081
|
})["catch"](function (err) {
|
|
1994
2082
|
console.error('Microphone access denied:', err);
|
|
1995
|
-
|
|
1996
|
-
|
|
2083
|
+
_this16.isConversationMode = false;
|
|
2084
|
+
_this16.updateConversationButton();
|
|
1997
2085
|
});
|
|
1998
2086
|
},
|
|
1999
2087
|
stopConversationMode: function stopConversationMode() {
|
|
@@ -2120,7 +2208,7 @@ window.openAIChatManager = function () {
|
|
|
2120
2208
|
return removedCount;
|
|
2121
2209
|
},
|
|
2122
2210
|
receiveNotification: function receiveNotification(notification) {
|
|
2123
|
-
var
|
|
2211
|
+
var _this17 = this;
|
|
2124
2212
|
if (!notification || !notification.type) {
|
|
2125
2213
|
return;
|
|
2126
2214
|
}
|
|
@@ -2135,7 +2223,7 @@ window.openAIChatManager = function () {
|
|
|
2135
2223
|
}
|
|
2136
2224
|
this.scheduleNotificationDismiss(notification);
|
|
2137
2225
|
this.$nextTick(function () {
|
|
2138
|
-
|
|
2226
|
+
_this17.scrollToBottom();
|
|
2139
2227
|
});
|
|
2140
2228
|
},
|
|
2141
2229
|
updateNotification: function updateNotification(notification) {
|
|
@@ -2152,12 +2240,12 @@ window.openAIChatManager = function () {
|
|
|
2152
2240
|
}
|
|
2153
2241
|
},
|
|
2154
2242
|
scheduleNotificationDismiss: function scheduleNotificationDismiss(notification) {
|
|
2155
|
-
var
|
|
2243
|
+
var _this18 = this;
|
|
2156
2244
|
if (!notification || !notification.type || !notification.autoDismissMs || notification.autoDismissMs <= 0) {
|
|
2157
2245
|
return;
|
|
2158
2246
|
}
|
|
2159
2247
|
this.notificationDismissTimers[notification.type] = setTimeout(function () {
|
|
2160
|
-
|
|
2248
|
+
_this18.removeNotification(notification.type);
|
|
2161
2249
|
}, notification.autoDismissMs);
|
|
2162
2250
|
},
|
|
2163
2251
|
clearNotificationDismiss: function clearNotificationDismiss(notificationType) {
|
|
@@ -2187,12 +2275,12 @@ window.openAIChatManager = function () {
|
|
|
2187
2275
|
});
|
|
2188
2276
|
},
|
|
2189
2277
|
scrollToBottom: function scrollToBottom() {
|
|
2190
|
-
var
|
|
2278
|
+
var _this19 = this;
|
|
2191
2279
|
if (!this.autoScroll) {
|
|
2192
2280
|
return;
|
|
2193
2281
|
}
|
|
2194
2282
|
setTimeout(function () {
|
|
2195
|
-
|
|
2283
|
+
_this19.chatContainer.scrollTop = _this19.chatContainer.scrollHeight - _this19.chatContainer.clientHeight;
|
|
2196
2284
|
}, 50);
|
|
2197
2285
|
},
|
|
2198
2286
|
handleUserInput: function handleUserInput(event) {
|
|
@@ -2238,27 +2326,27 @@ window.openAIChatManager = function () {
|
|
|
2238
2326
|
});
|
|
2239
2327
|
},
|
|
2240
2328
|
ensureSessionForDocuments: function ensureSessionForDocuments(profileId) {
|
|
2241
|
-
var
|
|
2329
|
+
var _this20 = this;
|
|
2242
2330
|
return _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee9() {
|
|
2243
2331
|
var sessionId;
|
|
2244
2332
|
return _regenerator().w(function (_context9) {
|
|
2245
2333
|
while (1) switch (_context9.n) {
|
|
2246
2334
|
case 0:
|
|
2247
|
-
sessionId =
|
|
2335
|
+
sessionId = _this20.getSessionId();
|
|
2248
2336
|
if (!sessionId) {
|
|
2249
2337
|
_context9.n = 1;
|
|
2250
2338
|
break;
|
|
2251
2339
|
}
|
|
2252
2340
|
return _context9.a(2, sessionId);
|
|
2253
2341
|
case 1:
|
|
2254
|
-
if (!(!profileId || !
|
|
2342
|
+
if (!(!profileId || !_this20.connection)) {
|
|
2255
2343
|
_context9.n = 2;
|
|
2256
2344
|
break;
|
|
2257
2345
|
}
|
|
2258
2346
|
return _context9.a(2, null);
|
|
2259
2347
|
case 2:
|
|
2260
2348
|
_context9.n = 3;
|
|
2261
|
-
return
|
|
2349
|
+
return _this20.requestNewSession(profileId);
|
|
2262
2350
|
case 3:
|
|
2263
2351
|
return _context9.a(2, _context9.v);
|
|
2264
2352
|
}
|
|
@@ -2266,7 +2354,7 @@ window.openAIChatManager = function () {
|
|
|
2266
2354
|
}))();
|
|
2267
2355
|
},
|
|
2268
2356
|
requestNewSession: function requestNewSession(profileId) {
|
|
2269
|
-
var
|
|
2357
|
+
var _this21 = this;
|
|
2270
2358
|
if (this.pendingSessionPromise) {
|
|
2271
2359
|
return this.pendingSessionPromise;
|
|
2272
2360
|
}
|
|
@@ -2274,14 +2362,14 @@ window.openAIChatManager = function () {
|
|
|
2274
2362
|
return Promise.resolve(null);
|
|
2275
2363
|
}
|
|
2276
2364
|
this.pendingSessionPromise = new Promise(function (resolve, reject) {
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2365
|
+
_this21.pendingSessionResolver = resolve;
|
|
2366
|
+
_this21.pendingSessionRejector = reject;
|
|
2367
|
+
_this21.pendingSessionTimeoutId = window.setTimeout(function () {
|
|
2368
|
+
_this21.rejectPendingSessionRequest('Timed out while creating a chat session.');
|
|
2281
2369
|
}, 15000);
|
|
2282
2370
|
});
|
|
2283
2371
|
this.connection.invoke("StartSession", profileId, null)["catch"](function (err) {
|
|
2284
|
-
|
|
2372
|
+
_this21.rejectPendingSessionRequest(err);
|
|
2285
2373
|
});
|
|
2286
2374
|
return this.pendingSessionPromise;
|
|
2287
2375
|
},
|
|
@@ -2307,7 +2395,7 @@ window.openAIChatManager = function () {
|
|
|
2307
2395
|
this.pendingSessionTimeoutId = null;
|
|
2308
2396
|
},
|
|
2309
2397
|
initializeApp: function initializeApp() {
|
|
2310
|
-
var
|
|
2398
|
+
var _this22 = this;
|
|
2311
2399
|
this.inputElement = document.querySelector(config.inputElementSelector);
|
|
2312
2400
|
this.buttonElement = document.querySelector(config.sendButtonElementSelector);
|
|
2313
2401
|
this.chatContainer = document.querySelector(config.chatContainerElementSelector);
|
|
@@ -2345,7 +2433,7 @@ window.openAIChatManager = function () {
|
|
|
2345
2433
|
fileInput.accept = config.allowedExtensions;
|
|
2346
2434
|
}
|
|
2347
2435
|
fileInput.addEventListener('change', function (e) {
|
|
2348
|
-
return
|
|
2436
|
+
return _this22.handleFileInputChange(e);
|
|
2349
2437
|
});
|
|
2350
2438
|
this.documentBar.parentElement.appendChild(fileInput);
|
|
2351
2439
|
|
|
@@ -2353,13 +2441,13 @@ window.openAIChatManager = function () {
|
|
|
2353
2441
|
var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;
|
|
2354
2442
|
if (inputArea) {
|
|
2355
2443
|
inputArea.addEventListener('dragover', function (e) {
|
|
2356
|
-
return
|
|
2444
|
+
return _this22.handleDragOver(e);
|
|
2357
2445
|
});
|
|
2358
2446
|
inputArea.addEventListener('dragleave', function (e) {
|
|
2359
|
-
return
|
|
2447
|
+
return _this22.handleDragLeave(e);
|
|
2360
2448
|
});
|
|
2361
2449
|
inputArea.addEventListener('drop', function (e) {
|
|
2362
|
-
return
|
|
2450
|
+
return _this22.handleDrop(e);
|
|
2363
2451
|
});
|
|
2364
2452
|
}
|
|
2365
2453
|
}
|
|
@@ -2367,55 +2455,55 @@ window.openAIChatManager = function () {
|
|
|
2367
2455
|
|
|
2368
2456
|
// Pause auto-scroll when the user manually scrolls up during streaming.
|
|
2369
2457
|
this.chatContainer.addEventListener('scroll', function () {
|
|
2370
|
-
if (!
|
|
2458
|
+
if (!_this22.stream) {
|
|
2371
2459
|
return;
|
|
2372
2460
|
}
|
|
2373
2461
|
var threshold = 30;
|
|
2374
|
-
var atBottom =
|
|
2375
|
-
|
|
2462
|
+
var atBottom = _this22.chatContainer.scrollHeight - _this22.chatContainer.clientHeight - _this22.chatContainer.scrollTop <= threshold;
|
|
2463
|
+
_this22.autoScroll = atBottom;
|
|
2376
2464
|
});
|
|
2377
2465
|
this.inputElement.addEventListener('keydown', function (event) {
|
|
2378
|
-
if (
|
|
2466
|
+
if (_this22.stream != null) {
|
|
2379
2467
|
return;
|
|
2380
2468
|
}
|
|
2381
2469
|
if (event.key === "Enter" && !event.shiftKey) {
|
|
2382
2470
|
event.preventDefault();
|
|
2383
|
-
|
|
2471
|
+
_this22.buttonElement.click();
|
|
2384
2472
|
}
|
|
2385
2473
|
});
|
|
2386
2474
|
this.inputElement.addEventListener('input', function (e) {
|
|
2387
|
-
|
|
2475
|
+
_this22.handleUserInput(e);
|
|
2388
2476
|
if (e.target.value.trim()) {
|
|
2389
|
-
|
|
2477
|
+
_this22.buttonElement.removeAttribute('disabled');
|
|
2390
2478
|
} else {
|
|
2391
|
-
|
|
2479
|
+
_this22.buttonElement.setAttribute('disabled', true);
|
|
2392
2480
|
}
|
|
2393
2481
|
});
|
|
2394
2482
|
this.buttonElement.addEventListener('click', function () {
|
|
2395
|
-
if (
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2483
|
+
if (_this22.stream != null) {
|
|
2484
|
+
_this22.stream.dispose();
|
|
2485
|
+
_this22.stream = null;
|
|
2486
|
+
_this22.streamingFinished();
|
|
2487
|
+
_this22.hideTypingIndicator();
|
|
2400
2488
|
|
|
2401
2489
|
// Clean up: remove empty assistant message or stop streaming animation.
|
|
2402
|
-
if (
|
|
2403
|
-
var lastMsg =
|
|
2490
|
+
if (_this22.messages.length > 0) {
|
|
2491
|
+
var lastMsg = _this22.messages[_this22.messages.length - 1];
|
|
2404
2492
|
if (lastMsg.role === 'assistant' && !lastMsg.content) {
|
|
2405
|
-
|
|
2493
|
+
_this22.messages.pop();
|
|
2406
2494
|
} else if (lastMsg.isStreaming) {
|
|
2407
2495
|
lastMsg.isStreaming = false;
|
|
2408
2496
|
}
|
|
2409
2497
|
}
|
|
2410
2498
|
return;
|
|
2411
2499
|
}
|
|
2412
|
-
|
|
2500
|
+
_this22.sendMessage();
|
|
2413
2501
|
});
|
|
2414
2502
|
var promptGenerators = document.getElementsByClassName('profile-generated-prompt');
|
|
2415
2503
|
for (var i = 0; i < promptGenerators.length; i++) {
|
|
2416
2504
|
promptGenerators[i].addEventListener('click', function (e) {
|
|
2417
2505
|
e.preventDefault();
|
|
2418
|
-
|
|
2506
|
+
_this22.generatePrompt(e.target);
|
|
2419
2507
|
});
|
|
2420
2508
|
}
|
|
2421
2509
|
var chatSessions = document.getElementsByClassName('chat-session-history-item');
|
|
@@ -2427,17 +2515,18 @@ window.openAIChatManager = function () {
|
|
|
2427
2515
|
console.error('an element with the class chat-session-history-item with no data-session-id set.');
|
|
2428
2516
|
return;
|
|
2429
2517
|
}
|
|
2430
|
-
|
|
2431
|
-
|
|
2518
|
+
_this22.loadSession(sessionId);
|
|
2519
|
+
_this22.showChatScreen();
|
|
2432
2520
|
});
|
|
2433
2521
|
}
|
|
2434
|
-
|
|
2435
|
-
|
|
2522
|
+
var initialMessages = Array.isArray(config.messages) ? config.messages : [];
|
|
2523
|
+
for (var _i5 = 0; _i5 < initialMessages.length; _i5++) {
|
|
2524
|
+
this.addMessage(initialMessages[_i5]);
|
|
2436
2525
|
}
|
|
2437
2526
|
|
|
2438
2527
|
// Update feedback icons in the DOM after initial messages have rendered.
|
|
2439
2528
|
this.$nextTick(function () {
|
|
2440
|
-
|
|
2529
|
+
_this22.refreshAllFeedbackIcons();
|
|
2441
2530
|
});
|
|
2442
2531
|
|
|
2443
2532
|
// Delegate click for code block copy buttons.
|
|
@@ -2469,7 +2558,7 @@ window.openAIChatManager = function () {
|
|
|
2469
2558
|
if (this.micButton) {
|
|
2470
2559
|
this.micButton.style.display = '';
|
|
2471
2560
|
this.micButton.addEventListener('click', function () {
|
|
2472
|
-
|
|
2561
|
+
_this22.toggleRecording();
|
|
2473
2562
|
});
|
|
2474
2563
|
}
|
|
2475
2564
|
}
|
|
@@ -2479,7 +2568,7 @@ window.openAIChatManager = function () {
|
|
|
2479
2568
|
this.conversationButton = document.querySelector(config.conversationButtonElementSelector);
|
|
2480
2569
|
if (this.conversationButton) {
|
|
2481
2570
|
this.conversationButton.addEventListener('click', function () {
|
|
2482
|
-
|
|
2571
|
+
_this22.toggleConversationMode();
|
|
2483
2572
|
});
|
|
2484
2573
|
}
|
|
2485
2574
|
}
|
|
@@ -2503,7 +2592,7 @@ window.openAIChatManager = function () {
|
|
|
2503
2592
|
}
|
|
2504
2593
|
return;
|
|
2505
2594
|
}
|
|
2506
|
-
this.fireEvent(new CustomEvent("
|
|
2595
|
+
this.fireEvent(new CustomEvent("initializingSessionCoreAIChat", {
|
|
2507
2596
|
detail: {
|
|
2508
2597
|
sessionId: sessionId
|
|
2509
2598
|
}
|
|
@@ -2522,10 +2611,45 @@ window.openAIChatManager = function () {
|
|
|
2522
2611
|
}
|
|
2523
2612
|
return sessionId;
|
|
2524
2613
|
},
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2614
|
+
clearCopiedMessageState: function clearCopiedMessageState() {
|
|
2615
|
+
if (this.copyResetTimeoutId) {
|
|
2616
|
+
window.clearTimeout(this.copyResetTimeoutId);
|
|
2617
|
+
this.copyResetTimeoutId = null;
|
|
2618
|
+
}
|
|
2619
|
+
if (this.activeCopyButton) {
|
|
2620
|
+
this.setCopyButtonState(this.activeCopyButton, false);
|
|
2621
|
+
this.activeCopyButton = null;
|
|
2622
|
+
}
|
|
2623
|
+
this.copiedMessageIndex = -1;
|
|
2624
|
+
},
|
|
2625
|
+
copyResponse: function copyResponse(message, index, event) {
|
|
2626
|
+
var _ref25,
|
|
2627
|
+
_message$copyContent,
|
|
2628
|
+
_event$target,
|
|
2629
|
+
_event$target$closest,
|
|
2630
|
+
_this23 = this;
|
|
2631
|
+
var text = message && _typeof(message) === 'object' ? (_ref25 = (_message$copyContent = message.copyContent) !== null && _message$copyContent !== void 0 ? _message$copyContent : message.content) !== null && _ref25 !== void 0 ? _ref25 : '' : message !== null && message !== void 0 ? message : '';
|
|
2632
|
+
var button = (event === null || event === void 0 ? void 0 : event.currentTarget) || (event === null || event === void 0 || (_event$target = event.target) === null || _event$target === void 0 || (_event$target$closest = _event$target.closest) === null || _event$target$closest === void 0 ? void 0 : _event$target$closest.call(_event$target, '[data-copy-message-index]')) || null;
|
|
2633
|
+
navigator.clipboard.writeText(text).then(function () {
|
|
2634
|
+
_this23.clearCopiedMessageState();
|
|
2635
|
+
_this23.copiedMessageIndex = typeof index === 'number' ? index : -1;
|
|
2636
|
+
_this23.activeCopyButton = button;
|
|
2637
|
+
if (button) {
|
|
2638
|
+
_this23.setCopyButtonState(button, true);
|
|
2639
|
+
} else {
|
|
2640
|
+
_this23.$nextTick(function () {
|
|
2641
|
+
return _this23.updateCopyButtons();
|
|
2642
|
+
});
|
|
2643
|
+
}
|
|
2644
|
+
_this23.copyResetTimeoutId = window.setTimeout(function () {
|
|
2645
|
+
_this23.clearCopiedMessageState();
|
|
2646
|
+
_this23.$nextTick(function () {
|
|
2647
|
+
return _this23.updateCopyButtons();
|
|
2648
|
+
});
|
|
2649
|
+
}, Number(config.copyResetDelayMs) || 2000);
|
|
2650
|
+
})["catch"](function (err) {
|
|
2651
|
+
return console.error('Failed to copy response:', err);
|
|
2652
|
+
});
|
|
2529
2653
|
},
|
|
2530
2654
|
updateFeedbackIcons: function updateFeedbackIcons(container, userRating) {
|
|
2531
2655
|
if (!container) {
|
|
@@ -2620,6 +2744,12 @@ window.openAIChatManager = function () {
|
|
|
2620
2744
|
// Reserved for future use — volume-based interrupt detection
|
|
2621
2745
|
// no longer mutes tracks; browser echo cancellation handles echo.
|
|
2622
2746
|
},
|
|
2747
|
+
copiedMessageIndex: function copiedMessageIndex() {
|
|
2748
|
+
var _this24 = this;
|
|
2749
|
+
this.$nextTick(function () {
|
|
2750
|
+
return _this24.updateCopyButtons();
|
|
2751
|
+
});
|
|
2752
|
+
},
|
|
2623
2753
|
isConversationMode: function isConversationMode(active) {
|
|
2624
2754
|
// Hide/show mic button.
|
|
2625
2755
|
if (this.micButton) {
|
|
@@ -2641,22 +2771,23 @@ window.openAIChatManager = function () {
|
|
|
2641
2771
|
}
|
|
2642
2772
|
},
|
|
2643
2773
|
mounted: function mounted() {
|
|
2644
|
-
var
|
|
2774
|
+
var _this25 = this;
|
|
2645
2775
|
_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee0() {
|
|
2646
2776
|
var isInitialized;
|
|
2647
2777
|
return _regenerator().w(function (_context0) {
|
|
2648
2778
|
while (1) switch (_context0.n) {
|
|
2649
2779
|
case 0:
|
|
2650
2780
|
_context0.n = 1;
|
|
2651
|
-
return
|
|
2781
|
+
return _this25.startConnection();
|
|
2652
2782
|
case 1:
|
|
2653
|
-
isInitialized =
|
|
2783
|
+
isInitialized = _this25.initializeApp();
|
|
2654
2784
|
if (isInitialized && hasWidgetConfig && widgetBehavior && typeof widgetBehavior.onMounted === 'function') {
|
|
2655
|
-
widgetBehavior.onMounted(
|
|
2785
|
+
widgetBehavior.onMounted(_this25, config);
|
|
2656
2786
|
}
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2787
|
+
_this25.$nextTick(function () {
|
|
2788
|
+
_this25.updateCopyButtons();
|
|
2789
|
+
refreshFontAwesomeIcons(_this25.$el);
|
|
2790
|
+
_this25.fontAwesomeObserver = observeFontAwesomeIcons(_this25.$el);
|
|
2660
2791
|
});
|
|
2661
2792
|
case 2:
|
|
2662
2793
|
return _context0.a(2);
|
|
@@ -2673,6 +2804,7 @@ window.openAIChatManager = function () {
|
|
|
2673
2804
|
this.fontAwesomeObserver.disconnect();
|
|
2674
2805
|
this.fontAwesomeObserver = null;
|
|
2675
2806
|
}
|
|
2807
|
+
this.clearCopiedMessageState();
|
|
2676
2808
|
this.stopAudio(false);
|
|
2677
2809
|
if (this.stream) {
|
|
2678
2810
|
this.stream.dispose();
|
|
@@ -2693,8 +2825,151 @@ window.openAIChatManager = function () {
|
|
|
2693
2825
|
}
|
|
2694
2826
|
return app;
|
|
2695
2827
|
};
|
|
2828
|
+
var autoInitializeSelector = '[data-coreai-chat-config],[data-coreai-chat-app-element-selector]';
|
|
2829
|
+
function getAttributeValue(element, attributeName) {
|
|
2830
|
+
var value = element.getAttribute(attributeName);
|
|
2831
|
+
return value === null || value === '' ? null : value;
|
|
2832
|
+
}
|
|
2833
|
+
function parseBooleanAttributeValue(value) {
|
|
2834
|
+
if (value === null || value === undefined) {
|
|
2835
|
+
return null;
|
|
2836
|
+
}
|
|
2837
|
+
if (typeof value === 'boolean') {
|
|
2838
|
+
return value;
|
|
2839
|
+
}
|
|
2840
|
+
var normalized = String(value).trim().toLowerCase();
|
|
2841
|
+
if (normalized === 'true') {
|
|
2842
|
+
return true;
|
|
2843
|
+
}
|
|
2844
|
+
if (normalized === 'false') {
|
|
2845
|
+
return false;
|
|
2846
|
+
}
|
|
2847
|
+
return null;
|
|
2848
|
+
}
|
|
2849
|
+
function parseJsonAttribute(element, attributeName, description) {
|
|
2850
|
+
var rawValue = getAttributeValue(element, attributeName);
|
|
2851
|
+
if (!rawValue) {
|
|
2852
|
+
return null;
|
|
2853
|
+
}
|
|
2854
|
+
try {
|
|
2855
|
+
return JSON.parse(rawValue);
|
|
2856
|
+
} catch (error) {
|
|
2857
|
+
console.error('Failed to parse ' + description + ' JSON.', error);
|
|
2858
|
+
return null;
|
|
2859
|
+
}
|
|
2860
|
+
}
|
|
2861
|
+
function buildConfigFromDataAttributes(element, options) {
|
|
2862
|
+
var _parseJsonAttribute, _parseJsonAttribute2;
|
|
2863
|
+
var settings = options || {};
|
|
2864
|
+
if (element.hasAttribute('data-coreai-chat-widget-container-selector') && settings.allowWidgetHost !== true) {
|
|
2865
|
+
return null;
|
|
2866
|
+
}
|
|
2867
|
+
var appElementSelector = getAttributeValue(element, 'data-coreai-chat-app-element-selector');
|
|
2868
|
+
if (!appElementSelector) {
|
|
2869
|
+
return null;
|
|
2870
|
+
}
|
|
2871
|
+
var config = {
|
|
2872
|
+
signalRHubUrl: getAttributeValue(element, 'data-coreai-chat-signalr-hub-url'),
|
|
2873
|
+
appElementSelector: appElementSelector,
|
|
2874
|
+
chatContainerElementSelector: getAttributeValue(element, 'data-coreai-chat-container-element-selector'),
|
|
2875
|
+
inputElementSelector: getAttributeValue(element, 'data-coreai-chat-input-element-selector'),
|
|
2876
|
+
sendButtonElementSelector: getAttributeValue(element, 'data-coreai-chat-send-button-element-selector'),
|
|
2877
|
+
placeholderElementSelector: getAttributeValue(element, 'data-coreai-chat-placeholder-element-selector'),
|
|
2878
|
+
messages: (_parseJsonAttribute = parseJsonAttribute(element, 'data-coreai-chat-messages', 'CoreAI chat messages')) !== null && _parseJsonAttribute !== void 0 ? _parseJsonAttribute : undefined,
|
|
2879
|
+
chatMode: getAttributeValue(element, 'data-coreai-chat-mode'),
|
|
2880
|
+
micButtonElementSelector: getAttributeValue(element, 'data-coreai-chat-mic-button-element-selector'),
|
|
2881
|
+
conversationButtonElementSelector: getAttributeValue(element, 'data-coreai-chat-conversation-button-element-selector'),
|
|
2882
|
+
ttsVoiceName: getAttributeValue(element, 'data-coreai-chat-tts-voice-name'),
|
|
2883
|
+
documentBarSelector: getAttributeValue(element, 'data-coreai-chat-document-bar-selector'),
|
|
2884
|
+
uploadDocumentUrl: getAttributeValue(element, 'data-coreai-chat-upload-document-url'),
|
|
2885
|
+
removeDocumentUrl: getAttributeValue(element, 'data-coreai-chat-remove-document-url'),
|
|
2886
|
+
allowedExtensions: getAttributeValue(element, 'data-coreai-chat-allowed-extensions'),
|
|
2887
|
+
supportedExtensionsText: getAttributeValue(element, 'data-coreai-chat-supported-extensions-text'),
|
|
2888
|
+
existingDocuments: (_parseJsonAttribute2 = parseJsonAttribute(element, 'data-coreai-chat-existing-documents', 'CoreAI chat existing documents')) !== null && _parseJsonAttribute2 !== void 0 ? _parseJsonAttribute2 : undefined,
|
|
2889
|
+
initialPrompt: getAttributeValue(element, 'data-coreai-chat-initial-prompt'),
|
|
2890
|
+
userLabel: getAttributeValue(element, 'data-coreai-chat-user-label'),
|
|
2891
|
+
assistantLabel: getAttributeValue(element, 'data-coreai-chat-assistant-label'),
|
|
2892
|
+
copyTitle: getAttributeValue(element, 'data-coreai-chat-copy-title'),
|
|
2893
|
+
copiedTitle: getAttributeValue(element, 'data-coreai-chat-copied-title')
|
|
2894
|
+
};
|
|
2895
|
+
var booleanAttributes = {
|
|
2896
|
+
metricsEnabled: 'data-coreai-chat-metrics-enabled',
|
|
2897
|
+
textToSpeechEnabled: 'data-coreai-chat-text-to-speech-enabled',
|
|
2898
|
+
sessionDocumentsEnabled: 'data-coreai-chat-session-documents-enabled',
|
|
2899
|
+
autoCreateSession: 'data-coreai-chat-auto-create-session',
|
|
2900
|
+
singleResponseMode: 'data-coreai-chat-single-response-mode'
|
|
2901
|
+
};
|
|
2902
|
+
Object.keys(booleanAttributes).forEach(function (key) {
|
|
2903
|
+
var parsed = parseBooleanAttributeValue(getAttributeValue(element, booleanAttributes[key]));
|
|
2904
|
+
if (parsed !== null) {
|
|
2905
|
+
config[key] = parsed;
|
|
2906
|
+
}
|
|
2907
|
+
});
|
|
2908
|
+
return compactObject(config);
|
|
2909
|
+
}
|
|
2910
|
+
function buildConfigFromElement(element, options) {
|
|
2911
|
+
var jsonConfig = parseJsonAttribute(element, 'data-coreai-chat-config', 'CoreAI chat config');
|
|
2912
|
+
var attributeConfig = buildConfigFromDataAttributes(element, options);
|
|
2913
|
+
if (!jsonConfig && !attributeConfig) {
|
|
2914
|
+
return null;
|
|
2915
|
+
}
|
|
2916
|
+
return Object.assign({}, jsonConfig || {}, attributeConfig || {});
|
|
2917
|
+
}
|
|
2918
|
+
function initializeFromElement(element) {
|
|
2919
|
+
if (!element || element.dataset.coreAiChatInitialized === 'true') {
|
|
2920
|
+
return element ? element.__coreAIChatApp || null : null;
|
|
2921
|
+
}
|
|
2922
|
+
var config = buildConfigFromElement(element);
|
|
2923
|
+
if (!config) {
|
|
2924
|
+
return null;
|
|
2925
|
+
}
|
|
2926
|
+
var app = initialize(config);
|
|
2927
|
+
if (!app) {
|
|
2928
|
+
return null;
|
|
2929
|
+
}
|
|
2930
|
+
element.dataset.coreAiChatInitialized = 'true';
|
|
2931
|
+
element.__coreAIChatApp = app;
|
|
2932
|
+
return app;
|
|
2933
|
+
}
|
|
2934
|
+
function scanForAutoInitialization(root) {
|
|
2935
|
+
if (!root || typeof root.querySelectorAll !== 'function') {
|
|
2936
|
+
return;
|
|
2937
|
+
}
|
|
2938
|
+
if (typeof root.matches === 'function' && root.matches(autoInitializeSelector)) {
|
|
2939
|
+
initializeFromElement(root);
|
|
2940
|
+
}
|
|
2941
|
+
root.querySelectorAll(autoInitializeSelector).forEach(initializeFromElement);
|
|
2942
|
+
}
|
|
2943
|
+
function startAutoInitialization() {
|
|
2944
|
+
scanForAutoInitialization(document);
|
|
2945
|
+
if (typeof MutationObserver === 'undefined') {
|
|
2946
|
+
return;
|
|
2947
|
+
}
|
|
2948
|
+
var observer = new MutationObserver(function (mutations) {
|
|
2949
|
+
mutations.forEach(function (mutation) {
|
|
2950
|
+
mutation.addedNodes.forEach(function (node) {
|
|
2951
|
+
if (node && node.nodeType === 1) {
|
|
2952
|
+
scanForAutoInitialization(node);
|
|
2953
|
+
}
|
|
2954
|
+
});
|
|
2955
|
+
});
|
|
2956
|
+
});
|
|
2957
|
+
observer.observe(document.body, {
|
|
2958
|
+
childList: true,
|
|
2959
|
+
subtree: true
|
|
2960
|
+
});
|
|
2961
|
+
}
|
|
2962
|
+
if (document.readyState === 'loading') {
|
|
2963
|
+
document.addEventListener('DOMContentLoaded', startAutoInitialization, {
|
|
2964
|
+
once: true
|
|
2965
|
+
});
|
|
2966
|
+
} else {
|
|
2967
|
+
startAutoInitialization();
|
|
2968
|
+
}
|
|
2696
2969
|
return {
|
|
2697
|
-
initialize: initialize
|
|
2970
|
+
initialize: initialize,
|
|
2971
|
+
initializeFromElement: initializeFromElement,
|
|
2972
|
+
buildConfigFromElement: buildConfigFromElement
|
|
2698
2973
|
};
|
|
2699
2974
|
}();
|
|
2700
2975
|
|