@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.
@@ -160,7 +160,7 @@
160
160
  }
161
161
 
162
162
  .ai-chat-widget-messages .ai-chat-msg-role-assistant {
163
- color: #6f42c1;
163
+ color: var(--ai-widget-primary, #6f42c1);
164
164
  }
165
165
 
166
166
  .ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-streaming-icon {
@@ -168,7 +168,7 @@
168
168
  }
169
169
 
170
170
  .ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-bot-icon {
171
- color: #6f42c1;
171
+ color: currentColor;
172
172
  }
173
173
 
174
174
  .ai-chat-widget-messages .ai-chat-message-body {
@@ -211,6 +211,11 @@
211
211
  pointer-events: auto;
212
212
  }
213
213
 
214
+ .ai-chat-widget-messages .message-buttons-container:has(.tts-playing) {
215
+ opacity: 1;
216
+ pointer-events: auto;
217
+ }
218
+
214
219
  .ai-chat-widget-messages .message-buttons-container > .button-message-toolbox {
215
220
  display: inline-flex;
216
221
  align-items: center;
@@ -237,11 +242,76 @@
237
242
  }
238
243
 
239
244
  .ai-chat-widget-messages .message-buttons-container > .button-message-toolbox.tts-playing {
240
- color: var(--bs-primary, #0d6efd) !important;
245
+ color: var(--ai-widget-primary, #6f42c1) !important;
241
246
  opacity: 1;
242
247
  pointer-events: auto;
243
248
  }
244
249
 
250
+ .ai-chat-widget-history-panel {
251
+ position: absolute;
252
+ top: 3.5rem;
253
+ left: 0;
254
+ right: 0;
255
+ bottom: 0;
256
+ background: #fff;
257
+ padding: 1rem;
258
+ z-index: 10;
259
+ display: none;
260
+ overflow-y: auto;
261
+ flex-direction: column;
262
+ }
263
+
264
+ .ai-chat-widget-history-panel.show {
265
+ display: flex;
266
+ }
267
+
268
+ .ai-chat-widget-history-panel .history-header {
269
+ display: flex;
270
+ justify-content: space-between;
271
+ align-items: center;
272
+ margin-bottom: 0.75rem;
273
+ flex-shrink: 0;
274
+ }
275
+
276
+ .ai-chat-widget-history-panel .history-header h5 {
277
+ margin: 0;
278
+ font-size: 1rem;
279
+ }
280
+
281
+ .ai-chat-widget-history-list {
282
+ list-style: none;
283
+ padding: 0;
284
+ margin: 0;
285
+ overflow-y: auto;
286
+ flex: 1 1 auto;
287
+ }
288
+
289
+ .ai-chat-widget-history-list li {
290
+ margin-bottom: 0;
291
+ }
292
+
293
+ .ai-chat-widget-history-list .chat-session-history-item {
294
+ display: block;
295
+ padding: 0.5rem 0.75rem;
296
+ text-decoration: none;
297
+ color: var(--bs-body-color, #212529);
298
+ font-size: 0.85rem;
299
+ white-space: nowrap;
300
+ overflow: hidden;
301
+ text-overflow: ellipsis;
302
+ transition: background 0.15s;
303
+ cursor: pointer;
304
+ border-bottom: 1px solid var(--bs-border-color, #dee2e6);
305
+ }
306
+
307
+ .ai-chat-widget-history-list li:last-child .chat-session-history-item {
308
+ border-bottom: none;
309
+ }
310
+
311
+ .ai-chat-widget-history-list .chat-session-history-item:hover {
312
+ background: var(--bs-tertiary-bg, #f8f9fa);
313
+ }
314
+
245
315
  /* ── Notifications ── */
246
316
  .ai-chat-widget-messages .ai-chat-notification {
247
317
  margin: 0.75rem 0.5rem 0;
@@ -308,12 +378,22 @@
308
378
  border-top: 1px solid #e9ecef;
309
379
  padding: 0.5rem 0.75rem;
310
380
  display: flex;
381
+ flex-wrap: wrap;
311
382
  gap: 0.5rem;
312
383
  align-items: flex-end;
313
384
  }
314
385
 
386
+ .ai-chat-widget-input .ai-chat-doc-bar {
387
+ flex: 0 0 100%;
388
+ margin: -0.5rem -0.75rem 0.5rem;
389
+ padding: 0.5rem 0.75rem;
390
+ max-height: 4.5rem;
391
+ overflow-y: auto;
392
+ }
393
+
315
394
  .ai-chat-widget-input textarea {
316
395
  flex: 1;
396
+ min-width: 0;
317
397
  border: 1px solid #ced4da;
318
398
  border-radius: 8px;
319
399
  padding: 0.4rem 0.6rem;
@@ -341,6 +421,29 @@
341
421
  white-space: nowrap;
342
422
  }
343
423
 
424
+ .ai-chat-widget-input .btn {
425
+ background: var(--bs-body-bg, #fff);
426
+ color: var(--bs-body-color, #212529);
427
+ border: 1px solid var(--bs-border-color, #ced4da);
428
+ }
429
+
430
+ .ai-chat-widget-input .btn.btn-link {
431
+ background: transparent;
432
+ color: var(--bs-secondary-color, #6c757d);
433
+ border: none;
434
+ padding: 0.4rem;
435
+ }
436
+
437
+ .ai-chat-widget-input .btn.btn-outline-dark {
438
+ background: var(--bs-dark, #212529);
439
+ color: #fff;
440
+ border-color: var(--bs-dark, #212529);
441
+ }
442
+
443
+ .ai-chat-widget-input .btn.btn-outline-secondary {
444
+ color: var(--bs-secondary-color, #6c757d);
445
+ }
446
+
344
447
  .ai-chat-widget-input button:disabled {
345
448
  opacity: 0.5;
346
449
  cursor: not-allowed;
@@ -1 +1 @@
1
- {"version":3,"sources":["chat-widget.css"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"chat-widget.css","sourcesContent":["/* CrestApps AI Chat Widget */\n:root {\n --ai-widget-primary: var(--bs-secondary, #6c757d);\n --ai-widget-width: 380px;\n --ai-widget-height: 520px;\n}\n\n.ai-chat-widget-toggle {\n position: fixed;\n bottom: 1.25rem;\n right: 1.25rem;\n z-index: 10000;\n width: 52px;\n height: 52px;\n border-radius: 50%;\n background: var(--ai-widget-primary);\n color: white;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.5rem;\n box-shadow: 0 4px 12px rgba(0,0,0,0.2);\n transition: transform 0.2s, box-shadow 0.2s;\n}\n\n.ai-chat-widget-toggle:hover {\n transform: scale(1.1);\n box-shadow: 0 6px 16px rgba(0,0,0,0.3);\n}\n\n.ai-chat-widget-container {\n position: fixed;\n bottom: 5rem;\n right: 1.25rem;\n z-index: 10001;\n width: var(--ai-widget-width);\n height: var(--ai-widget-height);\n background: #fff;\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0,0,0,0.18);\n display: none;\n flex-direction: column;\n overflow: hidden;\n}\n\n.ai-chat-widget-container.ai-chat-widget-resizable {\n resize: both;\n min-width: 320px;\n min-height: 420px;\n max-width: min(90vw, 960px);\n max-height: min(90vh, 960px);\n}\n\n.ai-chat-widget-container.open {\n display: flex;\n}\n\n.ai-chat-widget-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.75rem 1rem;\n background: var(--ai-widget-primary);\n color: white;\n}\n\n.ai-chat-widget-header.ai-chat-widget-drag-handle {\n cursor: move;\n user-select: none;\n touch-action: none;\n}\n\n.ai-chat-widget-header-actions {\n display: flex;\n align-items: center;\n gap: 0.15rem;\n}\n\n.ai-chat-widget-toggle.ai-chat-widget-draggable {\n touch-action: none;\n}\n\n.ai-chat-widget-container.ai-chat-widget-dragging,\n.ai-chat-widget-toggle.ai-chat-widget-dragging {\n transition: none;\n}\n\n.ai-chat-widget-toggle.ai-chat-widget-dragging:hover {\n transform: none;\n}\n\n.ai-chat-widget-header .title {\n font-weight: 600;\n font-size: 0.95rem;\n}\n\n.ai-chat-widget-header button {\n background: none;\n border: none;\n color: white;\n cursor: pointer;\n font-size: 1rem;\n padding: 0 0.25rem;\n opacity: 0.8;\n}\n\n.ai-chat-widget-header button:hover {\n opacity: 1;\n}\n\n.ai-chat-widget-profile-select {\n padding: 0.5rem 0.75rem;\n border-bottom: 1px solid #e9ecef;\n background: #f8f9fa;\n}\n\n.ai-chat-widget-profile-select select {\n width: 100%;\n padding: 0.35rem 0.5rem;\n border: 1px solid #ced4da;\n border-radius: 6px;\n font-size: 0.85rem;\n}\n\n.ai-chat-widget-messages {\n flex: 1;\n overflow-y: auto;\n padding: 0.75rem;\n font-size: 0.9rem;\n}\n\n/* ── Widget message items (ai-chat.js Vue template) ── */\n.ai-chat-widget-messages .ai-chat-messages {\n padding: 0.5rem;\n}\n\n.ai-chat-widget-messages .ai-chat-message-item {\n position: relative;\n padding: 0.5rem 0;\n}\n\n.ai-chat-widget-messages .ai-chat-message-item + .ai-chat-message-item::before {\n content: '';\n display: block;\n width: 100%;\n margin-bottom: 0.5rem;\n border-top: 1px solid rgba(33, 37, 41, 0.08);\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role {\n font-size: 0.7rem;\n font-weight: 600;\n margin-bottom: 2px;\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role-user {\n color: #0d6efd;\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role-assistant {\n color: #6f42c1;\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-streaming-icon {\n animation: ai-widget-pulse 1.5s infinite;\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-bot-icon {\n color: #6f42c1;\n}\n\n.ai-chat-widget-messages .ai-chat-message-body {\n position: relative;\n padding: 0;\n overflow-wrap: break-word;\n word-break: break-word;\n min-width: 0;\n}\n\n.ai-chat-widget-messages .ai-chat-message-body p:last-child {\n margin-bottom: 0;\n}\n\n/* ── Message action buttons (copy, thumbs up/down) ── */\n.ai-chat-widget-messages .message-buttons-container {\n position: absolute;\n right: 0.1rem;\n bottom: 0;\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n width: auto;\n max-width: max-content;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s ease-in-out;\n background: rgba(255, 255, 255, 0.96);\n padding: 0.2rem 0.35rem;\n border-radius: 999px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n margin-bottom: 1rem;\n transform: translateY(50%);\n z-index: 1;\n}\n\n.ai-chat-widget-messages .ai-chat-message-item:hover .message-buttons-container,\n.ai-chat-widget-messages .ai-chat-message-item:focus-within .message-buttons-container {\n opacity: 1;\n pointer-events: auto;\n}\n\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 auto;\n width: 1.75rem;\n height: 1.75rem;\n margin: 0 !important;\n padding: 0 !important;\n border-radius: 50%;\n color: var(--bs-secondary-color, #6c757d) !important;\n text-decoration: none;\n}\n\n.ai-chat-widget-messages .message-buttons-container .ai-chat-message-assistant-feedback {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n}\n\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox:hover,\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox:focus {\n color: var(--bs-body-color, #212529) !important;\n}\n\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox.tts-playing {\n color: var(--bs-primary, #0d6efd) !important;\n opacity: 1;\n pointer-events: auto;\n}\n\n/* ── Notifications ── */\n.ai-chat-widget-messages .ai-chat-notification {\n margin: 0.75rem 0.5rem 0;\n padding: 0.625rem 0.75rem;\n border: 1px solid rgba(33, 37, 41, 0.12);\n border-radius: 0.5rem;\n background: rgba(248, 249, 250, 0.98);\n}\n\n.ai-chat-widget-messages .ai-chat-notification-content {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n}\n\n.ai-chat-widget-messages .ai-chat-notification-icon {\n margin-top: 0.1rem;\n color: var(--bs-secondary-color, #6c757d);\n}\n\n.ai-chat-widget-messages .ai-chat-notification-text {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.ai-chat-widget-messages .ai-chat-notification-dismiss {\n margin-left: auto !important;\n color: var(--bs-secondary-color, #6c757d) !important;\n}\n\n.ai-chat-widget-messages .ai-chat-notification-actions {\n display: flex;\n gap: 0.5rem;\n margin-top: 0.5rem;\n}\n\n/* ── Chart containers inside widget ── */\n.ai-chat-widget-messages .chart-container {\n width: 100%;\n max-width: 100% !important;\n min-height: 280px;\n}\n\n/* ── Code blocks & inline code ── */\n.ai-chat-widget-messages .ai-chat-message-body pre {\n background: #2d2d2d;\n color: #f8f8f2;\n padding: 0.5rem;\n border-radius: 4px;\n overflow-x: auto;\n font-size: 0.8rem;\n}\n\n.ai-chat-widget-messages .ai-chat-message-body code {\n font-size: 0.85em;\n}\n\n@keyframes ai-widget-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.4; }\n}\n\n.ai-chat-widget-input {\n border-top: 1px solid #e9ecef;\n padding: 0.5rem 0.75rem;\n display: flex;\n gap: 0.5rem;\n align-items: flex-end;\n}\n\n.ai-chat-widget-input textarea {\n flex: 1;\n border: 1px solid #ced4da;\n border-radius: 8px;\n padding: 0.4rem 0.6rem;\n font-size: 0.9rem;\n resize: none;\n max-height: 80px;\n min-height: 36px;\n line-height: 1.4;\n outline: none;\n}\n\n.ai-chat-widget-input textarea:focus {\n border-color: var(--ai-widget-primary);\n box-shadow: 0 0 0 2px rgba(65,182,112,0.15);\n}\n\n.ai-chat-widget-input button {\n background: var(--ai-widget-primary);\n color: white;\n border: none;\n border-radius: 8px;\n padding: 0.4rem 0.75rem;\n cursor: pointer;\n font-size: 0.9rem;\n white-space: nowrap;\n}\n\n.ai-chat-widget-input button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.ai-chat-widget-status {\n padding: 0.25rem 0.75rem;\n font-size: 0.8rem;\n color: #6c757d;\n display: none;\n}\n\n.ai-chat-widget-status.visible {\n display: block;\n}\n\n.ai-chat-widget-welcome {\n text-align: center;\n color: #6c757d;\n padding: 2rem 1rem;\n font-size: 0.9rem;\n}\n\n@media (max-width: 576px) {\n .ai-chat-widget-container {\n width: calc(100vw - 1rem);\n height: calc(100vh - 6rem);\n right: 0.5rem;\n bottom: 4.5rem;\n }\n}\n"]}
1
+ {"version":3,"sources":["chat-widget.css"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"chat-widget.css","sourcesContent":["/* CrestApps AI Chat Widget */\n:root {\n --ai-widget-primary: var(--bs-secondary, #6c757d);\n --ai-widget-width: 380px;\n --ai-widget-height: 520px;\n}\n\n.ai-chat-widget-toggle {\n position: fixed;\n bottom: 1.25rem;\n right: 1.25rem;\n z-index: 10000;\n width: 52px;\n height: 52px;\n border-radius: 50%;\n background: var(--ai-widget-primary);\n color: white;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.5rem;\n box-shadow: 0 4px 12px rgba(0,0,0,0.2);\n transition: transform 0.2s, box-shadow 0.2s;\n}\n\n.ai-chat-widget-toggle:hover {\n transform: scale(1.1);\n box-shadow: 0 6px 16px rgba(0,0,0,0.3);\n}\n\n.ai-chat-widget-container {\n position: fixed;\n bottom: 5rem;\n right: 1.25rem;\n z-index: 10001;\n width: var(--ai-widget-width);\n height: var(--ai-widget-height);\n background: #fff;\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0,0,0,0.18);\n display: none;\n flex-direction: column;\n overflow: hidden;\n}\n\n.ai-chat-widget-container.ai-chat-widget-resizable {\n resize: both;\n min-width: 320px;\n min-height: 420px;\n max-width: min(90vw, 960px);\n max-height: min(90vh, 960px);\n}\n\n.ai-chat-widget-container.open {\n display: flex;\n}\n\n.ai-chat-widget-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.75rem 1rem;\n background: var(--ai-widget-primary);\n color: white;\n}\n\n.ai-chat-widget-header.ai-chat-widget-drag-handle {\n cursor: move;\n user-select: none;\n touch-action: none;\n}\n\n.ai-chat-widget-header-actions {\n display: flex;\n align-items: center;\n gap: 0.15rem;\n}\n\n.ai-chat-widget-toggle.ai-chat-widget-draggable {\n touch-action: none;\n}\n\n.ai-chat-widget-container.ai-chat-widget-dragging,\n.ai-chat-widget-toggle.ai-chat-widget-dragging {\n transition: none;\n}\n\n.ai-chat-widget-toggle.ai-chat-widget-dragging:hover {\n transform: none;\n}\n\n.ai-chat-widget-header .title {\n font-weight: 600;\n font-size: 0.95rem;\n}\n\n.ai-chat-widget-header button {\n background: none;\n border: none;\n color: white;\n cursor: pointer;\n font-size: 1rem;\n padding: 0 0.25rem;\n opacity: 0.8;\n}\n\n.ai-chat-widget-header button:hover {\n opacity: 1;\n}\n\n.ai-chat-widget-profile-select {\n padding: 0.5rem 0.75rem;\n border-bottom: 1px solid #e9ecef;\n background: #f8f9fa;\n}\n\n.ai-chat-widget-profile-select select {\n width: 100%;\n padding: 0.35rem 0.5rem;\n border: 1px solid #ced4da;\n border-radius: 6px;\n font-size: 0.85rem;\n}\n\n.ai-chat-widget-messages {\n flex: 1;\n overflow-y: auto;\n padding: 0.75rem;\n font-size: 0.9rem;\n}\n\n/* ── Widget message items (ai-chat.js Vue template) ── */\n.ai-chat-widget-messages .ai-chat-messages {\n padding: 0.5rem;\n}\n\n.ai-chat-widget-messages .ai-chat-message-item {\n position: relative;\n padding: 0.5rem 0;\n}\n\n.ai-chat-widget-messages .ai-chat-message-item + .ai-chat-message-item::before {\n content: '';\n display: block;\n width: 100%;\n margin-bottom: 0.5rem;\n border-top: 1px solid rgba(33, 37, 41, 0.08);\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role {\n font-size: 0.7rem;\n font-weight: 600;\n margin-bottom: 2px;\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role-user {\n color: #0d6efd;\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role-assistant {\n color: var(--ai-widget-primary, #6f42c1);\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-streaming-icon {\n animation: ai-widget-pulse 1.5s infinite;\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-bot-icon {\n color: currentColor;\n}\n\n.ai-chat-widget-messages .ai-chat-message-body {\n position: relative;\n padding: 0;\n overflow-wrap: break-word;\n word-break: break-word;\n min-width: 0;\n}\n\n.ai-chat-widget-messages .ai-chat-message-body p:last-child {\n margin-bottom: 0;\n}\n\n/* ── Message action buttons (copy, thumbs up/down) ── */\n.ai-chat-widget-messages .message-buttons-container {\n position: absolute;\n right: 0.1rem;\n bottom: 0;\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n width: auto;\n max-width: max-content;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s ease-in-out;\n background: rgba(255, 255, 255, 0.96);\n padding: 0.2rem 0.35rem;\n border-radius: 999px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n margin-bottom: 1rem;\n transform: translateY(50%);\n z-index: 1;\n}\n\n.ai-chat-widget-messages .ai-chat-message-item:hover .message-buttons-container,\n.ai-chat-widget-messages .ai-chat-message-item:focus-within .message-buttons-container {\n opacity: 1;\n pointer-events: auto;\n}\n\n.ai-chat-widget-messages .message-buttons-container:has(.tts-playing) {\n opacity: 1;\n pointer-events: auto;\n}\n\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 auto;\n width: 1.75rem;\n height: 1.75rem;\n margin: 0 !important;\n padding: 0 !important;\n border-radius: 50%;\n color: var(--bs-secondary-color, #6c757d) !important;\n text-decoration: none;\n}\n\n.ai-chat-widget-messages .message-buttons-container .ai-chat-message-assistant-feedback {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n}\n\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox:hover,\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox:focus {\n color: var(--bs-body-color, #212529) !important;\n}\n\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox.tts-playing {\n color: var(--ai-widget-primary, #6f42c1) !important;\n opacity: 1;\n pointer-events: auto;\n}\n\n.ai-chat-widget-history-panel {\n position: absolute;\n top: 3.5rem;\n left: 0;\n right: 0;\n bottom: 0;\n background: #fff;\n padding: 1rem;\n z-index: 10;\n display: none;\n overflow-y: auto;\n flex-direction: column;\n}\n\n.ai-chat-widget-history-panel.show {\n display: flex;\n}\n\n.ai-chat-widget-history-panel .history-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 0.75rem;\n flex-shrink: 0;\n}\n\n.ai-chat-widget-history-panel .history-header h5 {\n margin: 0;\n font-size: 1rem;\n}\n\n.ai-chat-widget-history-list {\n list-style: none;\n padding: 0;\n margin: 0;\n overflow-y: auto;\n flex: 1 1 auto;\n}\n\n.ai-chat-widget-history-list li {\n margin-bottom: 0;\n}\n\n.ai-chat-widget-history-list .chat-session-history-item {\n display: block;\n padding: 0.5rem 0.75rem;\n text-decoration: none;\n color: var(--bs-body-color, #212529);\n font-size: 0.85rem;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n transition: background 0.15s;\n cursor: pointer;\n border-bottom: 1px solid var(--bs-border-color, #dee2e6);\n}\n\n.ai-chat-widget-history-list li:last-child .chat-session-history-item {\n border-bottom: none;\n}\n\n.ai-chat-widget-history-list .chat-session-history-item:hover {\n background: var(--bs-tertiary-bg, #f8f9fa);\n}\n\n/* ── Notifications ── */\n.ai-chat-widget-messages .ai-chat-notification {\n margin: 0.75rem 0.5rem 0;\n padding: 0.625rem 0.75rem;\n border: 1px solid rgba(33, 37, 41, 0.12);\n border-radius: 0.5rem;\n background: rgba(248, 249, 250, 0.98);\n}\n\n.ai-chat-widget-messages .ai-chat-notification-content {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n}\n\n.ai-chat-widget-messages .ai-chat-notification-icon {\n margin-top: 0.1rem;\n color: var(--bs-secondary-color, #6c757d);\n}\n\n.ai-chat-widget-messages .ai-chat-notification-text {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.ai-chat-widget-messages .ai-chat-notification-dismiss {\n margin-left: auto !important;\n color: var(--bs-secondary-color, #6c757d) !important;\n}\n\n.ai-chat-widget-messages .ai-chat-notification-actions {\n display: flex;\n gap: 0.5rem;\n margin-top: 0.5rem;\n}\n\n/* ── Chart containers inside widget ── */\n.ai-chat-widget-messages .chart-container {\n width: 100%;\n max-width: 100% !important;\n min-height: 280px;\n}\n\n/* ── Code blocks & inline code ── */\n.ai-chat-widget-messages .ai-chat-message-body pre {\n background: #2d2d2d;\n color: #f8f8f2;\n padding: 0.5rem;\n border-radius: 4px;\n overflow-x: auto;\n font-size: 0.8rem;\n}\n\n.ai-chat-widget-messages .ai-chat-message-body code {\n font-size: 0.85em;\n}\n\n@keyframes ai-widget-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.4; }\n}\n\n.ai-chat-widget-input {\n border-top: 1px solid #e9ecef;\n padding: 0.5rem 0.75rem;\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n align-items: flex-end;\n}\n\n.ai-chat-widget-input .ai-chat-doc-bar {\n flex: 0 0 100%;\n margin: -0.5rem -0.75rem 0.5rem;\n padding: 0.5rem 0.75rem;\n max-height: 4.5rem;\n overflow-y: auto;\n}\n\n.ai-chat-widget-input textarea {\n flex: 1;\n min-width: 0;\n border: 1px solid #ced4da;\n border-radius: 8px;\n padding: 0.4rem 0.6rem;\n font-size: 0.9rem;\n resize: none;\n max-height: 80px;\n min-height: 36px;\n line-height: 1.4;\n outline: none;\n}\n\n.ai-chat-widget-input textarea:focus {\n border-color: var(--ai-widget-primary);\n box-shadow: 0 0 0 2px rgba(65,182,112,0.15);\n}\n\n.ai-chat-widget-input button {\n background: var(--ai-widget-primary);\n color: white;\n border: none;\n border-radius: 8px;\n padding: 0.4rem 0.75rem;\n cursor: pointer;\n font-size: 0.9rem;\n white-space: nowrap;\n}\n\n.ai-chat-widget-input .btn {\n background: var(--bs-body-bg, #fff);\n color: var(--bs-body-color, #212529);\n border: 1px solid var(--bs-border-color, #ced4da);\n}\n\n.ai-chat-widget-input .btn.btn-link {\n background: transparent;\n color: var(--bs-secondary-color, #6c757d);\n border: none;\n padding: 0.4rem;\n}\n\n.ai-chat-widget-input .btn.btn-outline-dark {\n background: var(--bs-dark, #212529);\n color: #fff;\n border-color: var(--bs-dark, #212529);\n}\n\n.ai-chat-widget-input .btn.btn-outline-secondary {\n color: var(--bs-secondary-color, #6c757d);\n}\n\n.ai-chat-widget-input button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.ai-chat-widget-status {\n padding: 0.25rem 0.75rem;\n font-size: 0.8rem;\n color: #6c757d;\n display: none;\n}\n\n.ai-chat-widget-status.visible {\n display: block;\n}\n\n.ai-chat-widget-welcome {\n text-align: center;\n color: #6c757d;\n padding: 2rem 1rem;\n font-size: 0.9rem;\n}\n\n@media (max-width: 576px) {\n .ai-chat-widget-container {\n width: calc(100vw - 1rem);\n height: calc(100vh - 6rem);\n right: 0.5rem;\n bottom: 4.5rem;\n }\n}\n"]}
@@ -1 +1 @@
1
- :root{--ai-widget-primary:var(--bs-secondary, #6c757d);--ai-widget-width:380px;--ai-widget-height:520px}.ai-chat-widget-toggle{position:fixed;bottom:1.25rem;right:1.25rem;z-index:10000;width:52px;height:52px;border-radius:50%;background:var(--ai-widget-primary);color:#fff;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:1.5rem;box-shadow:0 4px 12px rgba(0,0,0,.2);transition:transform .2s,box-shadow .2s}.ai-chat-widget-toggle:hover{transform:scale(1.1);box-shadow:0 6px 16px rgba(0,0,0,.3)}.ai-chat-widget-container{position:fixed;bottom:5rem;right:1.25rem;z-index:10001;width:var(--ai-widget-width);height:var(--ai-widget-height);background:#fff;border-radius:12px;box-shadow:0 8px 32px rgba(0,0,0,.18);display:none;flex-direction:column;overflow:hidden}.ai-chat-widget-container.ai-chat-widget-resizable{resize:both;min-width:320px;min-height:420px;max-width:min(90vw,960px);max-height:min(90vh,960px)}.ai-chat-widget-container.open{display:flex}.ai-chat-widget-header{display:flex;align-items:center;justify-content:space-between;padding:.75rem 1rem;background:var(--ai-widget-primary);color:#fff}.ai-chat-widget-header.ai-chat-widget-drag-handle{cursor:move;user-select:none;touch-action:none}.ai-chat-widget-header-actions{display:flex;align-items:center;gap:.15rem}.ai-chat-widget-toggle.ai-chat-widget-draggable{touch-action:none}.ai-chat-widget-container.ai-chat-widget-dragging,.ai-chat-widget-toggle.ai-chat-widget-dragging{transition:none}.ai-chat-widget-toggle.ai-chat-widget-dragging:hover{transform:none}.ai-chat-widget-header .title{font-weight:600;font-size:.95rem}.ai-chat-widget-header button{background:0 0;border:none;color:#fff;cursor:pointer;font-size:1rem;padding:0 .25rem;opacity:.8}.ai-chat-widget-header button:hover{opacity:1}.ai-chat-widget-profile-select{padding:.5rem .75rem;border-bottom:1px solid #e9ecef;background:#f8f9fa}.ai-chat-widget-profile-select select{width:100%;padding:.35rem .5rem;border:1px solid #ced4da;border-radius:6px;font-size:.85rem}.ai-chat-widget-messages{flex:1;overflow-y:auto;padding:.75rem;font-size:.9rem}.ai-chat-widget-messages .ai-chat-messages{padding:.5rem}.ai-chat-widget-messages .ai-chat-message-item{position:relative;padding:.5rem 0}.ai-chat-widget-messages .ai-chat-message-item+.ai-chat-message-item::before{content:'';display:block;width:100%;margin-bottom:.5rem;border-top:1px solid rgba(33,37,41,.08)}.ai-chat-widget-messages .ai-chat-msg-role{font-size:.7rem;font-weight:600;margin-bottom:2px}.ai-chat-widget-messages .ai-chat-msg-role-user{color:#0d6efd}.ai-chat-widget-messages .ai-chat-msg-role-assistant{color:#6f42c1}.ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-streaming-icon{animation:ai-widget-pulse 1.5s infinite}.ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-bot-icon{color:#6f42c1}.ai-chat-widget-messages .ai-chat-message-body{position:relative;padding:0;overflow-wrap:break-word;word-break:break-word;min-width:0}.ai-chat-widget-messages .ai-chat-message-body p:last-child{margin-bottom:0}.ai-chat-widget-messages .message-buttons-container{position:absolute;right:.1rem;bottom:0;display:inline-flex;align-items:center;gap:.35rem;width:auto;max-width:max-content;opacity:0;pointer-events:none;transition:opacity .15s ease-in-out;background:rgba(255,255,255,.96);padding:.2rem .35rem;border-radius:999px;box-shadow:0 1px 3px rgba(0,0,0,.08);margin-bottom:1rem;transform:translateY(50%);z-index:1}.ai-chat-widget-messages .ai-chat-message-item:focus-within .message-buttons-container,.ai-chat-widget-messages .ai-chat-message-item:hover .message-buttons-container{opacity:1;pointer-events:auto}.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:1.75rem;height:1.75rem;margin:0!important;padding:0!important;border-radius:50%;color:var(--bs-secondary-color,#6c757d)!important;text-decoration:none}.ai-chat-widget-messages .message-buttons-container .ai-chat-message-assistant-feedback{display:inline-flex;align-items:center;gap:.35rem}.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox:focus,.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox:hover{color:var(--bs-body-color,#212529)!important}.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox.tts-playing{color:var(--bs-primary,#0d6efd)!important;opacity:1;pointer-events:auto}.ai-chat-widget-messages .ai-chat-notification{margin:.75rem .5rem 0;padding:.625rem .75rem;border:1px solid rgba(33,37,41,.12);border-radius:.5rem;background:rgba(248,249,250,.98)}.ai-chat-widget-messages .ai-chat-notification-content{display:flex;align-items:flex-start;gap:.5rem}.ai-chat-widget-messages .ai-chat-notification-icon{margin-top:.1rem;color:var(--bs-secondary-color,#6c757d)}.ai-chat-widget-messages .ai-chat-notification-text{flex:1 1 auto;min-width:0}.ai-chat-widget-messages .ai-chat-notification-dismiss{margin-left:auto!important;color:var(--bs-secondary-color,#6c757d)!important}.ai-chat-widget-messages .ai-chat-notification-actions{display:flex;gap:.5rem;margin-top:.5rem}.ai-chat-widget-messages .chart-container{width:100%;max-width:100%!important;min-height:280px}.ai-chat-widget-messages .ai-chat-message-body pre{background:#2d2d2d;color:#f8f8f2;padding:.5rem;border-radius:4px;overflow-x:auto;font-size:.8rem}.ai-chat-widget-messages .ai-chat-message-body code{font-size:.85em}@keyframes ai-widget-pulse{0%,100%{opacity:1}50%{opacity:.4}}.ai-chat-widget-input{border-top:1px solid #e9ecef;padding:.5rem .75rem;display:flex;gap:.5rem;align-items:flex-end}.ai-chat-widget-input textarea{flex:1;border:1px solid #ced4da;border-radius:8px;padding:.4rem .6rem;font-size:.9rem;resize:none;max-height:80px;min-height:36px;line-height:1.4;outline:0}.ai-chat-widget-input textarea:focus{border-color:var(--ai-widget-primary);box-shadow:0 0 0 2px rgba(65,182,112,.15)}.ai-chat-widget-input button{background:var(--ai-widget-primary);color:#fff;border:none;border-radius:8px;padding:.4rem .75rem;cursor:pointer;font-size:.9rem;white-space:nowrap}.ai-chat-widget-input button:disabled{opacity:.5;cursor:not-allowed}.ai-chat-widget-status{padding:.25rem .75rem;font-size:.8rem;color:#6c757d;display:none}.ai-chat-widget-status.visible{display:block}.ai-chat-widget-welcome{text-align:center;color:#6c757d;padding:2rem 1rem;font-size:.9rem}@media (max-width:576px){.ai-chat-widget-container{width:calc(100vw - 1rem);height:calc(100vh - 6rem);right:.5rem;bottom:4.5rem}}
1
+ :root{--ai-widget-primary:var(--bs-secondary, #6c757d);--ai-widget-width:380px;--ai-widget-height:520px}.ai-chat-widget-toggle{position:fixed;bottom:1.25rem;right:1.25rem;z-index:10000;width:52px;height:52px;border-radius:50%;background:var(--ai-widget-primary);color:#fff;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:1.5rem;box-shadow:0 4px 12px rgba(0,0,0,.2);transition:transform .2s,box-shadow .2s}.ai-chat-widget-toggle:hover{transform:scale(1.1);box-shadow:0 6px 16px rgba(0,0,0,.3)}.ai-chat-widget-container{position:fixed;bottom:5rem;right:1.25rem;z-index:10001;width:var(--ai-widget-width);height:var(--ai-widget-height);background:#fff;border-radius:12px;box-shadow:0 8px 32px rgba(0,0,0,.18);display:none;flex-direction:column;overflow:hidden}.ai-chat-widget-container.ai-chat-widget-resizable{resize:both;min-width:320px;min-height:420px;max-width:min(90vw,960px);max-height:min(90vh,960px)}.ai-chat-widget-container.open{display:flex}.ai-chat-widget-header{display:flex;align-items:center;justify-content:space-between;padding:.75rem 1rem;background:var(--ai-widget-primary);color:#fff}.ai-chat-widget-header.ai-chat-widget-drag-handle{cursor:move;user-select:none;touch-action:none}.ai-chat-widget-header-actions{display:flex;align-items:center;gap:.15rem}.ai-chat-widget-toggle.ai-chat-widget-draggable{touch-action:none}.ai-chat-widget-container.ai-chat-widget-dragging,.ai-chat-widget-toggle.ai-chat-widget-dragging{transition:none}.ai-chat-widget-toggle.ai-chat-widget-dragging:hover{transform:none}.ai-chat-widget-header .title{font-weight:600;font-size:.95rem}.ai-chat-widget-header button{background:0 0;border:none;color:#fff;cursor:pointer;font-size:1rem;padding:0 .25rem;opacity:.8}.ai-chat-widget-header button:hover{opacity:1}.ai-chat-widget-profile-select{padding:.5rem .75rem;border-bottom:1px solid #e9ecef;background:#f8f9fa}.ai-chat-widget-profile-select select{width:100%;padding:.35rem .5rem;border:1px solid #ced4da;border-radius:6px;font-size:.85rem}.ai-chat-widget-messages{flex:1;overflow-y:auto;padding:.75rem;font-size:.9rem}.ai-chat-widget-messages .ai-chat-messages{padding:.5rem}.ai-chat-widget-messages .ai-chat-message-item{position:relative;padding:.5rem 0}.ai-chat-widget-messages .ai-chat-message-item+.ai-chat-message-item::before{content:'';display:block;width:100%;margin-bottom:.5rem;border-top:1px solid rgba(33,37,41,.08)}.ai-chat-widget-messages .ai-chat-msg-role{font-size:.7rem;font-weight:600;margin-bottom:2px}.ai-chat-widget-messages .ai-chat-msg-role-user{color:#0d6efd}.ai-chat-widget-messages .ai-chat-msg-role-assistant{color:var(--ai-widget-primary,#6f42c1)}.ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-streaming-icon{animation:ai-widget-pulse 1.5s infinite}.ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-bot-icon{color:currentColor}.ai-chat-widget-messages .ai-chat-message-body{position:relative;padding:0;overflow-wrap:break-word;word-break:break-word;min-width:0}.ai-chat-widget-messages .ai-chat-message-body p:last-child{margin-bottom:0}.ai-chat-widget-messages .message-buttons-container{position:absolute;right:.1rem;bottom:0;display:inline-flex;align-items:center;gap:.35rem;width:auto;max-width:max-content;opacity:0;pointer-events:none;transition:opacity .15s ease-in-out;background:rgba(255,255,255,.96);padding:.2rem .35rem;border-radius:999px;box-shadow:0 1px 3px rgba(0,0,0,.08);margin-bottom:1rem;transform:translateY(50%);z-index:1}.ai-chat-widget-messages .ai-chat-message-item:focus-within .message-buttons-container,.ai-chat-widget-messages .ai-chat-message-item:hover .message-buttons-container{opacity:1;pointer-events:auto}.ai-chat-widget-messages .message-buttons-container:has(.tts-playing){opacity:1;pointer-events:auto}.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:1.75rem;height:1.75rem;margin:0!important;padding:0!important;border-radius:50%;color:var(--bs-secondary-color,#6c757d)!important;text-decoration:none}.ai-chat-widget-messages .message-buttons-container .ai-chat-message-assistant-feedback{display:inline-flex;align-items:center;gap:.35rem}.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox:focus,.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox:hover{color:var(--bs-body-color,#212529)!important}.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox.tts-playing{color:var(--ai-widget-primary,#6f42c1)!important;opacity:1;pointer-events:auto}.ai-chat-widget-history-panel{position:absolute;top:3.5rem;left:0;right:0;bottom:0;background:#fff;padding:1rem;z-index:10;display:none;overflow-y:auto;flex-direction:column}.ai-chat-widget-history-panel.show{display:flex}.ai-chat-widget-history-panel .history-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:.75rem;flex-shrink:0}.ai-chat-widget-history-panel .history-header h5{margin:0;font-size:1rem}.ai-chat-widget-history-list{list-style:none;padding:0;margin:0;overflow-y:auto;flex:1 1 auto}.ai-chat-widget-history-list li{margin-bottom:0}.ai-chat-widget-history-list .chat-session-history-item{display:block;padding:.5rem .75rem;text-decoration:none;color:var(--bs-body-color,#212529);font-size:.85rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:background .15s;cursor:pointer;border-bottom:1px solid var(--bs-border-color,#dee2e6)}.ai-chat-widget-history-list li:last-child .chat-session-history-item{border-bottom:none}.ai-chat-widget-history-list .chat-session-history-item:hover{background:var(--bs-tertiary-bg,#f8f9fa)}.ai-chat-widget-messages .ai-chat-notification{margin:.75rem .5rem 0;padding:.625rem .75rem;border:1px solid rgba(33,37,41,.12);border-radius:.5rem;background:rgba(248,249,250,.98)}.ai-chat-widget-messages .ai-chat-notification-content{display:flex;align-items:flex-start;gap:.5rem}.ai-chat-widget-messages .ai-chat-notification-icon{margin-top:.1rem;color:var(--bs-secondary-color,#6c757d)}.ai-chat-widget-messages .ai-chat-notification-text{flex:1 1 auto;min-width:0}.ai-chat-widget-messages .ai-chat-notification-dismiss{margin-left:auto!important;color:var(--bs-secondary-color,#6c757d)!important}.ai-chat-widget-messages .ai-chat-notification-actions{display:flex;gap:.5rem;margin-top:.5rem}.ai-chat-widget-messages .chart-container{width:100%;max-width:100%!important;min-height:280px}.ai-chat-widget-messages .ai-chat-message-body pre{background:#2d2d2d;color:#f8f8f2;padding:.5rem;border-radius:4px;overflow-x:auto;font-size:.8rem}.ai-chat-widget-messages .ai-chat-message-body code{font-size:.85em}@keyframes ai-widget-pulse{0%,100%{opacity:1}50%{opacity:.4}}.ai-chat-widget-input{border-top:1px solid #e9ecef;padding:.5rem .75rem;display:flex;flex-wrap:wrap;gap:.5rem;align-items:flex-end}.ai-chat-widget-input .ai-chat-doc-bar{flex:0 0 100%;margin:-.5rem -.75rem .5rem;padding:.5rem .75rem;max-height:4.5rem;overflow-y:auto}.ai-chat-widget-input textarea{flex:1;min-width:0;border:1px solid #ced4da;border-radius:8px;padding:.4rem .6rem;font-size:.9rem;resize:none;max-height:80px;min-height:36px;line-height:1.4;outline:0}.ai-chat-widget-input textarea:focus{border-color:var(--ai-widget-primary);box-shadow:0 0 0 2px rgba(65,182,112,.15)}.ai-chat-widget-input button{background:var(--ai-widget-primary);color:#fff;border:none;border-radius:8px;padding:.4rem .75rem;cursor:pointer;font-size:.9rem;white-space:nowrap}.ai-chat-widget-input .btn{background:var(--bs-body-bg,#fff);color:var(--bs-body-color,#212529);border:1px solid var(--bs-border-color,#ced4da)}.ai-chat-widget-input .btn.btn-link{background:0 0;color:var(--bs-secondary-color,#6c757d);border:none;padding:.4rem}.ai-chat-widget-input .btn.btn-outline-dark{background:var(--bs-dark,#212529);color:#fff;border-color:var(--bs-dark,#212529)}.ai-chat-widget-input .btn.btn-outline-secondary{color:var(--bs-secondary-color,#6c757d)}.ai-chat-widget-input button:disabled{opacity:.5;cursor:not-allowed}.ai-chat-widget-status{padding:.25rem .75rem;font-size:.8rem;color:#6c757d;display:none}.ai-chat-widget-status.visible{display:block}.ai-chat-widget-welcome{text-align:center;color:#6c757d;padding:2rem 1rem;font-size:.9rem}@media (max-width:576px){.ai-chat-widget-container{width:calc(100vw - 1rem);height:calc(100vh - 6rem);right:.5rem;bottom:4.5rem}}
@@ -16,26 +16,54 @@
16
16
  }
17
17
  function initAutoGenerateTechnicalName(displayId, nameId) {
18
18
  if (!displayId || !nameId) return;
19
- document.addEventListener('DOMContentLoaded', function () {
19
+ function attach() {
20
20
  var displayEl = document.getElementById(displayId);
21
21
  var nameEl = document.getElementById(nameId);
22
22
  if (!displayEl || !nameEl) return;
23
+ if (nameEl.dataset.techNameInitialized === 'true') return;
24
+ nameEl.dataset.techNameInitialized = 'true';
23
25
 
24
26
  // Track whether the user has entered a non-empty value in the Name field.
25
27
  var userEdited = nameEl.value.trim() !== '';
28
+ // Set while we synthesize input/change events on the name field so we can
29
+ // distinguish programmatic updates from real user typing.
30
+ var suppressUserEditedTracking = false;
26
31
 
27
32
  // Resume auto-generation only when the Name field is empty again.
28
- nameEl.addEventListener('input', function () {
33
+ nameEl.addEventListener('input', function (e) {
34
+ if (suppressUserEditedTracking || e && e.isTrusted === false) {
35
+ return;
36
+ }
29
37
  userEdited = nameEl.value.trim() !== '';
30
38
  });
31
-
32
- // Generate on keyup as requested
33
- displayEl.addEventListener('keyup', function () {
39
+ function updateGeneratedValue() {
34
40
  if (userEdited) return;
35
41
  var generated = toTitleCaseNoSpaces(displayEl.value || '');
36
- nameEl.value = generated;
37
- });
38
- });
42
+ if (nameEl.value === generated) {
43
+ return;
44
+ }
45
+ suppressUserEditedTracking = true;
46
+ try {
47
+ nameEl.value = generated;
48
+ nameEl.dispatchEvent(new Event('input', {
49
+ bubbles: true
50
+ }));
51
+ nameEl.dispatchEvent(new Event('change', {
52
+ bubbles: true
53
+ }));
54
+ } finally {
55
+ suppressUserEditedTracking = false;
56
+ }
57
+ }
58
+ displayEl.addEventListener('input', updateGeneratedValue);
59
+ displayEl.addEventListener('keyup', updateGeneratedValue);
60
+ displayEl.addEventListener('change', updateGeneratedValue);
61
+ }
62
+ if (document.readyState === 'loading') {
63
+ document.addEventListener('DOMContentLoaded', attach);
64
+ } else {
65
+ attach();
66
+ }
39
67
  }
40
68
 
41
69
  // Automatically initialize for any elements using the data attributes.
@@ -1 +1 @@
1
- {"version":3,"sources":["technical-name-generator.js"],"names":["toTitleCaseNoSpaces","value","trim","split","filter","w","length","map","charAt","toUpperCase","slice","toLowerCase","join","initAutoGenerateTechnicalName","displayId","nameId","document","addEventListener","displayEl","getElementById","nameEl","userEdited","generated","autoEls","querySelectorAll","i","el","getAttribute","window"],"mappings":";;;;;AAAA,CAAC,YAAY;EACX;EACA,SAASA,mBAAmBA,CAACC,KAAK,EAAE;IAClC,OAAO,CAACA,KAAK,IAAI,EAAE,EAChBC,IAAI,CAAC;IACN;IAAA,CACCC,KAAK,CAAC,eAAe,CAAC,CACtBC,MAAM,CAAC,UAAUC,CAAC,EAAE;MAAE,OAAOA,CAAC,CAACC,MAAM,GAAG,CAAC;IAAE,CAAC,CAAC,CAC7CC,GAAG,CAAC,UAAUF,CAAC,EAAE;MAAE,OAAOA,CAAC,CAACG,MAAM,CAAC,CAAC,CAAC,CAACC,WAAW,CAAC,CAAC,GAAGJ,CAAC,CAACK,KAAK,CAAC,CAAC,CAAC,CAACC,WAAW,CAAC,CAAC;IAAE,CAAC,CAAC,CAClFC,IAAI,CAAC,EAAE,CAAC;EACb;EAEA,SAASC,6BAA6BA,CAACC,SAAS,EAAEC,MAAM,EAAE;IACxD,IAAI,CAACD,SAAS,IAAI,CAACC,MAAM,EAAE;IAC3BC,QAAQ,CAACC,gBAAgB,CAAC,kBAAkB,EAAE,YAAY;MACxD,IAAIC,SAAS,GAAGF,QAAQ,CAACG,cAAc,CAACL,SAAS,CAAC;MAClD,IAAIM,MAAM,GAAGJ,QAAQ,CAACG,cAAc,CAACJ,MAAM,CAAC;MAC5C,IAAI,CAACG,SAAS,IAAI,CAACE,MAAM,EAAE;;MAE3B;MACA,IAAIC,UAAU,GAAGD,MAAM,CAACnB,KAAK,CAACC,IAAI,CAAC,CAAC,KAAK,EAAE;;MAE3C;MACAkB,MAAM,CAACH,gBAAgB,CAAC,OAAO,EAAE,YAAY;QAC3CI,UAAU,GAAGD,MAAM,CAACnB,KAAK,CAACC,IAAI,CAAC,CAAC,KAAK,EAAE;MACzC,CAAC,CAAC;;MAEF;MACAgB,SAAS,CAACD,gBAAgB,CAAC,OAAO,EAAE,YAAY;QAC9C,IAAII,UAAU,EAAE;QAChB,IAAIC,SAAS,GAAGtB,mBAAmB,CAACkB,SAAS,CAACjB,KAAK,IAAI,EAAE,CAAC;QAC1DmB,MAAM,CAACnB,KAAK,GAAGqB,SAAS;MAC1B,CAAC,CAAC;IACJ,CAAC,CAAC;EACJ;;EAEA;EACAN,QAAQ,CAACC,gBAAgB,CAAC,kBAAkB,EAAE,YAAY;IACxD,IAAIM,OAAO,GAAGP,QAAQ,CAACQ,gBAAgB,CAAC,uBAAuB,CAAC;IAChE,KAAK,IAAIC,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGF,OAAO,CAACjB,MAAM,EAAEmB,CAAC,EAAE,EAAE;MACvC,IAAIC,EAAE,GAAGH,OAAO,CAACE,CAAC,CAAC;MACnB,IAAIX,SAAS,GAAGY,EAAE,CAACC,YAAY,CAAC,iBAAiB,CAAC;MAClD,IAAIZ,MAAM,GAAGW,EAAE,CAACC,YAAY,CAAC,cAAc,CAAC;MAC5C,IAAIb,SAAS,IAAIC,MAAM,EAAE;QACvB;QACAF,6BAA6B,CAACC,SAAS,EAAEC,MAAM,CAAC;MAClD;IACF;EACF,CAAC,CAAC;EAEFa,MAAM,CAACf,6BAA6B,GAAGA,6BAA6B;AACtE,CAAC,EAAE,CAAC","file":"technical-name-generator.js","sourcesContent":["(function () {\n // Expose initializer globally so views can call it with specific field IDs.\n function toTitleCaseNoSpaces(value) {\n return (value || '')\n .trim()\n // split on whitespace or common separators or any non-alphanumeric\n .split(/[^A-Za-z0-9]+/)\n .filter(function (w) { return w.length > 0; })\n .map(function (w) { return w.charAt(0).toUpperCase() + w.slice(1).toLowerCase(); })\n .join('');\n }\n\n function initAutoGenerateTechnicalName(displayId, nameId) {\n if (!displayId || !nameId) return;\n document.addEventListener('DOMContentLoaded', function () {\n var displayEl = document.getElementById(displayId);\n var nameEl = document.getElementById(nameId);\n if (!displayEl || !nameEl) return;\n\n // Track whether the user has entered a non-empty value in the Name field.\n var userEdited = nameEl.value.trim() !== '';\n\n // Resume auto-generation only when the Name field is empty again.\n nameEl.addEventListener('input', function () {\n userEdited = nameEl.value.trim() !== '';\n });\n\n // Generate on keyup as requested\n displayEl.addEventListener('keyup', function () {\n if (userEdited) return;\n var generated = toTitleCaseNoSpaces(displayEl.value || '');\n nameEl.value = generated;\n });\n });\n }\n\n // Automatically initialize for any elements using the data attributes.\n document.addEventListener('DOMContentLoaded', function () {\n var autoEls = document.querySelectorAll('[data-auto-tech-name]');\n for (var i = 0; i < autoEls.length; i++) {\n var el = autoEls[i];\n var displayId = el.getAttribute('data-display-id');\n var nameId = el.getAttribute('data-name-id');\n if (displayId && nameId) {\n // call initializer immediately (it will attach listeners)\n initAutoGenerateTechnicalName(displayId, nameId);\n }\n }\n });\n\n window.initAutoGenerateTechnicalName = initAutoGenerateTechnicalName;\n})();\n"]}
1
+ {"version":3,"sources":["technical-name-generator.js"],"names":["toTitleCaseNoSpaces","value","trim","split","filter","w","length","map","charAt","toUpperCase","slice","toLowerCase","join","initAutoGenerateTechnicalName","displayId","nameId","attach","displayEl","document","getElementById","nameEl","dataset","techNameInitialized","userEdited","suppressUserEditedTracking","addEventListener","e","isTrusted","updateGeneratedValue","generated","dispatchEvent","Event","bubbles","readyState","autoEls","querySelectorAll","i","el","getAttribute","window"],"mappings":";;;;;AAAA,CAAC,YAAY;EACX;EACA,SAASA,mBAAmBA,CAACC,KAAK,EAAE;IAClC,OAAO,CAACA,KAAK,IAAI,EAAE,EAChBC,IAAI,CAAC;IACN;IAAA,CACCC,KAAK,CAAC,eAAe,CAAC,CACtBC,MAAM,CAAC,UAAUC,CAAC,EAAE;MAAE,OAAOA,CAAC,CAACC,MAAM,GAAG,CAAC;IAAE,CAAC,CAAC,CAC7CC,GAAG,CAAC,UAAUF,CAAC,EAAE;MAAE,OAAOA,CAAC,CAACG,MAAM,CAAC,CAAC,CAAC,CAACC,WAAW,CAAC,CAAC,GAAGJ,CAAC,CAACK,KAAK,CAAC,CAAC,CAAC,CAACC,WAAW,CAAC,CAAC;IAAE,CAAC,CAAC,CAClFC,IAAI,CAAC,EAAE,CAAC;EACb;EAEA,SAASC,6BAA6BA,CAACC,SAAS,EAAEC,MAAM,EAAE;IACxD,IAAI,CAACD,SAAS,IAAI,CAACC,MAAM,EAAE;IAE3B,SAASC,MAAMA,CAAA,EAAG;MAChB,IAAIC,SAAS,GAAGC,QAAQ,CAACC,cAAc,CAACL,SAAS,CAAC;MAClD,IAAIM,MAAM,GAAGF,QAAQ,CAACC,cAAc,CAACJ,MAAM,CAAC;MAC5C,IAAI,CAACE,SAAS,IAAI,CAACG,MAAM,EAAE;MAC3B,IAAIA,MAAM,CAACC,OAAO,CAACC,mBAAmB,KAAK,MAAM,EAAE;MAEnDF,MAAM,CAACC,OAAO,CAACC,mBAAmB,GAAG,MAAM;;MAE3C;MACA,IAAIC,UAAU,GAAGH,MAAM,CAACnB,KAAK,CAACC,IAAI,CAAC,CAAC,KAAK,EAAE;MAC3C;MACA;MACA,IAAIsB,0BAA0B,GAAG,KAAK;;MAEtC;MACAJ,MAAM,CAACK,gBAAgB,CAAC,OAAO,EAAE,UAAUC,CAAC,EAAE;QAC5C,IAAIF,0BAA0B,IAAKE,CAAC,IAAIA,CAAC,CAACC,SAAS,KAAK,KAAM,EAAE;UAC9D;QACF;QAEAJ,UAAU,GAAGH,MAAM,CAACnB,KAAK,CAACC,IAAI,CAAC,CAAC,KAAK,EAAE;MACzC,CAAC,CAAC;MAEF,SAAS0B,oBAAoBA,CAAA,EAAG;QAC9B,IAAIL,UAAU,EAAE;QAEhB,IAAIM,SAAS,GAAG7B,mBAAmB,CAACiB,SAAS,CAAChB,KAAK,IAAI,EAAE,CAAC;QAE1D,IAAImB,MAAM,CAACnB,KAAK,KAAK4B,SAAS,EAAE;UAC9B;QACF;QAEAL,0BAA0B,GAAG,IAAI;QACjC,IAAI;UACFJ,MAAM,CAACnB,KAAK,GAAG4B,SAAS;UACxBT,MAAM,CAACU,aAAa,CAAC,IAAIC,KAAK,CAAC,OAAO,EAAE;YAAEC,OAAO,EAAE;UAAK,CAAC,CAAC,CAAC;UAC3DZ,MAAM,CAACU,aAAa,CAAC,IAAIC,KAAK,CAAC,QAAQ,EAAE;YAAEC,OAAO,EAAE;UAAK,CAAC,CAAC,CAAC;QAC9D,CAAC,SAAS;UACRR,0BAA0B,GAAG,KAAK;QACpC;MACF;MAEAP,SAAS,CAACQ,gBAAgB,CAAC,OAAO,EAAEG,oBAAoB,CAAC;MACzDX,SAAS,CAACQ,gBAAgB,CAAC,OAAO,EAAEG,oBAAoB,CAAC;MACzDX,SAAS,CAACQ,gBAAgB,CAAC,QAAQ,EAAEG,oBAAoB,CAAC;IAC5D;IAEA,IAAIV,QAAQ,CAACe,UAAU,KAAK,SAAS,EAAE;MACrCf,QAAQ,CAACO,gBAAgB,CAAC,kBAAkB,EAAET,MAAM,CAAC;IACvD,CAAC,MAAM;MACLA,MAAM,CAAC,CAAC;IACV;EACF;;EAEA;EACAE,QAAQ,CAACO,gBAAgB,CAAC,kBAAkB,EAAE,YAAY;IACxD,IAAIS,OAAO,GAAGhB,QAAQ,CAACiB,gBAAgB,CAAC,uBAAuB,CAAC;IAChE,KAAK,IAAIC,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGF,OAAO,CAAC5B,MAAM,EAAE8B,CAAC,EAAE,EAAE;MACvC,IAAIC,EAAE,GAAGH,OAAO,CAACE,CAAC,CAAC;MACnB,IAAItB,SAAS,GAAGuB,EAAE,CAACC,YAAY,CAAC,iBAAiB,CAAC;MAClD,IAAIvB,MAAM,GAAGsB,EAAE,CAACC,YAAY,CAAC,cAAc,CAAC;MAC5C,IAAIxB,SAAS,IAAIC,MAAM,EAAE;QACvB;QACAF,6BAA6B,CAACC,SAAS,EAAEC,MAAM,CAAC;MAClD;IACF;EACF,CAAC,CAAC;EAEFwB,MAAM,CAAC1B,6BAA6B,GAAGA,6BAA6B;AACtE,CAAC,EAAE,CAAC","file":"technical-name-generator.js","sourcesContent":["(function () {\n // Expose initializer globally so views can call it with specific field IDs.\n function toTitleCaseNoSpaces(value) {\n return (value || '')\n .trim()\n // split on whitespace or common separators or any non-alphanumeric\n .split(/[^A-Za-z0-9]+/)\n .filter(function (w) { return w.length > 0; })\n .map(function (w) { return w.charAt(0).toUpperCase() + w.slice(1).toLowerCase(); })\n .join('');\n }\n\n function initAutoGenerateTechnicalName(displayId, nameId) {\n if (!displayId || !nameId) return;\n\n function attach() {\n var displayEl = document.getElementById(displayId);\n var nameEl = document.getElementById(nameId);\n if (!displayEl || !nameEl) return;\n if (nameEl.dataset.techNameInitialized === 'true') return;\n\n nameEl.dataset.techNameInitialized = 'true';\n\n // Track whether the user has entered a non-empty value in the Name field.\n var userEdited = nameEl.value.trim() !== '';\n // Set while we synthesize input/change events on the name field so we can\n // distinguish programmatic updates from real user typing.\n var suppressUserEditedTracking = false;\n\n // Resume auto-generation only when the Name field is empty again.\n nameEl.addEventListener('input', function (e) {\n if (suppressUserEditedTracking || (e && e.isTrusted === false)) {\n return;\n }\n\n userEdited = nameEl.value.trim() !== '';\n });\n\n function updateGeneratedValue() {\n if (userEdited) return;\n\n var generated = toTitleCaseNoSpaces(displayEl.value || '');\n\n if (nameEl.value === generated) {\n return;\n }\n\n suppressUserEditedTracking = true;\n try {\n nameEl.value = generated;\n nameEl.dispatchEvent(new Event('input', { bubbles: true }));\n nameEl.dispatchEvent(new Event('change', { bubbles: true }));\n } finally {\n suppressUserEditedTracking = false;\n }\n }\n\n displayEl.addEventListener('input', updateGeneratedValue);\n displayEl.addEventListener('keyup', updateGeneratedValue);\n displayEl.addEventListener('change', updateGeneratedValue);\n }\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', attach);\n } else {\n attach();\n }\n }\n\n // Automatically initialize for any elements using the data attributes.\n document.addEventListener('DOMContentLoaded', function () {\n var autoEls = document.querySelectorAll('[data-auto-tech-name]');\n for (var i = 0; i < autoEls.length; i++) {\n var el = autoEls[i];\n var displayId = el.getAttribute('data-display-id');\n var nameId = el.getAttribute('data-name-id');\n if (displayId && nameId) {\n // call initializer immediately (it will attach listeners)\n initAutoGenerateTechnicalName(displayId, nameId);\n }\n }\n });\n\n window.initAutoGenerateTechnicalName = initAutoGenerateTechnicalName;\n})();\n"]}
@@ -1,2 +1,2 @@
1
- !function(){function t(t,e){t&&e&&document.addEventListener("DOMContentLoaded",function(){var n=document.getElementById(t),a=document.getElementById(e);if(n&&a){var i=""!==a.value.trim();a.addEventListener("input",function(){i=""!==a.value.trim()}),n.addEventListener("keyup",function(){if(!i){var t=(n.value||""||"").trim().split(/[^A-Za-z0-9]+/).filter(function(t){return t.length>0}).map(function(t){return t.charAt(0).toUpperCase()+t.slice(1).toLowerCase()}).join("");a.value=t}})}})}document.addEventListener("DOMContentLoaded",function(){for(var e=document.querySelectorAll("[data-auto-tech-name]"),n=0;n<e.length;n++){var a=e[n],i=a.getAttribute("data-display-id"),d=a.getAttribute("data-name-id");i&&d&&t(i,d)}}),window.initAutoGenerateTechnicalName=t}();
1
+ !function(){function e(e,t){function n(){var n=document.getElementById(e),a=document.getElementById(t);if(n&&a&&"true"!==a.dataset.techNameInitialized){a.dataset.techNameInitialized="true";var i=""!==a.value.trim(),d=!1;a.addEventListener("input",function(e){d||e&&!1===e.isTrusted||(i=""!==a.value.trim())}),n.addEventListener("input",u),n.addEventListener("keyup",u),n.addEventListener("change",u)}function u(){if(!i){var e=(n.value||""||"").trim().split(/[^A-Za-z0-9]+/).filter(function(e){return e.length>0}).map(function(e){return e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()}).join("");if(a.value!==e){d=!0;try{a.value=e,a.dispatchEvent(new Event("input",{bubbles:!0})),a.dispatchEvent(new Event("change",{bubbles:!0}))}finally{d=!1}}}}}e&&t&&("loading"===document.readyState?document.addEventListener("DOMContentLoaded",n):n())}document.addEventListener("DOMContentLoaded",function(){for(var t=document.querySelectorAll("[data-auto-tech-name]"),n=0;n<t.length;n++){var a=t[n],i=a.getAttribute("data-display-id"),d=a.getAttribute("data-name-id");i&&d&&e(i,d)}}),window.initAutoGenerateTechnicalName=e}();
2
2
  //# sourceMappingURL=technical-name-generator.min.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["technical-name-generator.js"],"names":["initAutoGenerateTechnicalName","displayId","nameId","document","addEventListener","displayEl","getElementById","nameEl","userEdited","value","trim","generated","split","filter","w","length","map","charAt","toUpperCase","slice","toLowerCase","join","autoEls","querySelectorAll","i","el","getAttribute","window"],"mappings":"CAAA,WAYE,SAASA,EAA8BC,EAAWC,GAC3CD,GAAcC,GACnBC,SAASC,iBAAiB,mBAAoB,WAC5C,IAAIC,EAAYF,SAASG,eAAeL,GACpCM,EAASJ,SAASG,eAAeJ,GACrC,GAAKG,GAAcE,EAAnB,CAGA,IAAIC,EAAqC,KAAxBD,EAAOE,MAAMC,OAG9BH,EAAOH,iBAAiB,QAAS,WAC/BI,EAAqC,KAAxBD,EAAOE,MAAMC,MAC5B,GAGAL,EAAUD,iBAAiB,QAAS,WAClC,IAAII,EAAJ,CACA,IAAIG,GAAgCN,EAAUI,OAAS,IA3B1C,IACdC,OAEAE,MAAM,iBACNC,OAAO,SAAUC,GAAK,OAAOA,EAAEC,OAAS,CAAG,GAC3CC,IAAI,SAAUF,GAAK,OAAOA,EAAEG,OAAO,GAAGC,cAAgBJ,EAAEK,MAAM,GAAGC,aAAe,GAChFC,KAAK,IAsBJd,EAAOE,MAAQE,CAFC,CAGlB,EAf2B,CAgB7B,EACF,CAGAR,SAASC,iBAAiB,mBAAoB,WAE5C,IADA,IAAIkB,EAAUnB,SAASoB,iBAAiB,yBAC/BC,EAAI,EAAGA,EAAIF,EAAQP,OAAQS,IAAK,CACvC,IAAIC,EAAKH,EAAQE,GACbvB,EAAYwB,EAAGC,aAAa,mBAC5BxB,EAASuB,EAAGC,aAAa,gBACzBzB,GAAaC,GAEfF,EAA8BC,EAAWC,EAE7C,CACF,GAEAyB,OAAO3B,8BAAgCA,CACxC,CAnDD","file":"technical-name-generator.min.js","sourcesContent":["(function () {\n // Expose initializer globally so views can call it with specific field IDs.\n function toTitleCaseNoSpaces(value) {\n return (value || '')\n .trim()\n // split on whitespace or common separators or any non-alphanumeric\n .split(/[^A-Za-z0-9]+/)\n .filter(function (w) { return w.length > 0; })\n .map(function (w) { return w.charAt(0).toUpperCase() + w.slice(1).toLowerCase(); })\n .join('');\n }\n\n function initAutoGenerateTechnicalName(displayId, nameId) {\n if (!displayId || !nameId) return;\n document.addEventListener('DOMContentLoaded', function () {\n var displayEl = document.getElementById(displayId);\n var nameEl = document.getElementById(nameId);\n if (!displayEl || !nameEl) return;\n\n // Track whether the user has entered a non-empty value in the Name field.\n var userEdited = nameEl.value.trim() !== '';\n\n // Resume auto-generation only when the Name field is empty again.\n nameEl.addEventListener('input', function () {\n userEdited = nameEl.value.trim() !== '';\n });\n\n // Generate on keyup as requested\n displayEl.addEventListener('keyup', function () {\n if (userEdited) return;\n var generated = toTitleCaseNoSpaces(displayEl.value || '');\n nameEl.value = generated;\n });\n });\n }\n\n // Automatically initialize for any elements using the data attributes.\n document.addEventListener('DOMContentLoaded', function () {\n var autoEls = document.querySelectorAll('[data-auto-tech-name]');\n for (var i = 0; i < autoEls.length; i++) {\n var el = autoEls[i];\n var displayId = el.getAttribute('data-display-id');\n var nameId = el.getAttribute('data-name-id');\n if (displayId && nameId) {\n // call initializer immediately (it will attach listeners)\n initAutoGenerateTechnicalName(displayId, nameId);\n }\n }\n });\n\n window.initAutoGenerateTechnicalName = initAutoGenerateTechnicalName;\n})();\n"]}
1
+ {"version":3,"sources":["technical-name-generator.js"],"names":["initAutoGenerateTechnicalName","displayId","nameId","attach","displayEl","document","getElementById","nameEl","dataset","techNameInitialized","userEdited","value","trim","suppressUserEditedTracking","addEventListener","e","isTrusted","updateGeneratedValue","generated","split","filter","w","length","map","charAt","toUpperCase","slice","toLowerCase","join","dispatchEvent","Event","bubbles","readyState","autoEls","querySelectorAll","i","el","getAttribute","window"],"mappings":"CAAA,WAYE,SAASA,EAA8BC,EAAWC,GAGhD,SAASC,IACP,IAAIC,EAAYC,SAASC,eAAeL,GACpCM,EAASF,SAASC,eAAeJ,GACrC,GAAKE,GAAcG,GACwB,SAAvCA,EAAOC,QAAQC,oBAAnB,CAEAF,EAAOC,QAAQC,oBAAsB,OAGrC,IAAIC,EAAqC,KAAxBH,EAAOI,MAAMC,OAG1BC,GAA6B,EAGjCN,EAAOO,iBAAiB,QAAS,SAAUC,GACrCF,GAA+BE,IAAqB,IAAhBA,EAAEC,YAI1CN,EAAqC,KAAxBH,EAAOI,MAAMC,OAC5B,GAqBAR,EAAUU,iBAAiB,QAASG,GACpCb,EAAUU,iBAAiB,QAASG,GACpCb,EAAUU,iBAAiB,SAAUG,EAxCc,CAmBnD,SAASA,IACP,IAAIP,EAAJ,CAEA,IAAIQ,GAAgCd,EAAUO,OAAS,IAtC1C,IACdC,OAEAO,MAAM,iBACNC,OAAO,SAAUC,GAAK,OAAOA,EAAEC,OAAS,CAAG,GAC3CC,IAAI,SAAUF,GAAK,OAAOA,EAAEG,OAAO,GAAGC,cAAgBJ,EAAEK,MAAM,GAAGC,aAAe,GAChFC,KAAK,IAkCJ,GAAIrB,EAAOI,QAAUO,EAArB,CAIAL,GAA6B,EAC7B,IACEN,EAAOI,MAAQO,EACfX,EAAOsB,cAAc,IAAIC,MAAM,QAAS,CAAEC,SAAS,KACnDxB,EAAOsB,cAAc,IAAIC,MAAM,SAAU,CAAEC,SAAS,IACtD,CAAC,QACClB,GAA6B,CAC/B,CATA,CANgB,CAgBlB,CAKF,CA/CKZ,GAAcC,IAiDS,YAAxBG,SAAS2B,WACX3B,SAASS,iBAAiB,mBAAoBX,GAE9CA,IAEJ,CAGAE,SAASS,iBAAiB,mBAAoB,WAE5C,IADA,IAAImB,EAAU5B,SAAS6B,iBAAiB,yBAC/BC,EAAI,EAAGA,EAAIF,EAAQX,OAAQa,IAAK,CACvC,IAAIC,EAAKH,EAAQE,GACblC,EAAYmC,EAAGC,aAAa,mBAC5BnC,EAASkC,EAAGC,aAAa,gBACzBpC,GAAaC,GAEfF,EAA8BC,EAAWC,EAE7C,CACF,GAEAoC,OAAOtC,8BAAgCA,CACxC,CApFD","file":"technical-name-generator.min.js","sourcesContent":["(function () {\n // Expose initializer globally so views can call it with specific field IDs.\n function toTitleCaseNoSpaces(value) {\n return (value || '')\n .trim()\n // split on whitespace or common separators or any non-alphanumeric\n .split(/[^A-Za-z0-9]+/)\n .filter(function (w) { return w.length > 0; })\n .map(function (w) { return w.charAt(0).toUpperCase() + w.slice(1).toLowerCase(); })\n .join('');\n }\n\n function initAutoGenerateTechnicalName(displayId, nameId) {\n if (!displayId || !nameId) return;\n\n function attach() {\n var displayEl = document.getElementById(displayId);\n var nameEl = document.getElementById(nameId);\n if (!displayEl || !nameEl) return;\n if (nameEl.dataset.techNameInitialized === 'true') return;\n\n nameEl.dataset.techNameInitialized = 'true';\n\n // Track whether the user has entered a non-empty value in the Name field.\n var userEdited = nameEl.value.trim() !== '';\n // Set while we synthesize input/change events on the name field so we can\n // distinguish programmatic updates from real user typing.\n var suppressUserEditedTracking = false;\n\n // Resume auto-generation only when the Name field is empty again.\n nameEl.addEventListener('input', function (e) {\n if (suppressUserEditedTracking || (e && e.isTrusted === false)) {\n return;\n }\n\n userEdited = nameEl.value.trim() !== '';\n });\n\n function updateGeneratedValue() {\n if (userEdited) return;\n\n var generated = toTitleCaseNoSpaces(displayEl.value || '');\n\n if (nameEl.value === generated) {\n return;\n }\n\n suppressUserEditedTracking = true;\n try {\n nameEl.value = generated;\n nameEl.dispatchEvent(new Event('input', { bubbles: true }));\n nameEl.dispatchEvent(new Event('change', { bubbles: true }));\n } finally {\n suppressUserEditedTracking = false;\n }\n }\n\n displayEl.addEventListener('input', updateGeneratedValue);\n displayEl.addEventListener('keyup', updateGeneratedValue);\n displayEl.addEventListener('change', updateGeneratedValue);\n }\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', attach);\n } else {\n attach();\n }\n }\n\n // Automatically initialize for any elements using the data attributes.\n document.addEventListener('DOMContentLoaded', function () {\n var autoEls = document.querySelectorAll('[data-auto-tech-name]');\n for (var i = 0; i < autoEls.length; i++) {\n var el = autoEls[i];\n var displayId = el.getAttribute('data-display-id');\n var nameId = el.getAttribute('data-name-id');\n if (displayId && nameId) {\n // call initializer immediately (it will attach listeners)\n initAutoGenerateTechnicalName(displayId, nameId);\n }\n }\n });\n\n window.initAutoGenerateTechnicalName = initAutoGenerateTechnicalName;\n})();\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crestapps/ai-chat-ui",
3
- "version": "1.0.0-preview.7",
3
+ "version": "1.0.0-preview.73",
4
4
  "description": "Browser-ready JavaScript widgets and CSS for CrestApps AI chat sessions and chat interactions. Supports streaming responses, image generation, Chart.js interactive charts, document uploads, copy-to-clipboard, and feedback buttons.",
5
5
  "license": "MIT",
6
6
  "author": "CrestApps",
@@ -13,6 +13,10 @@
13
13
  "bugs": {
14
14
  "url": "https://github.com/CrestApps/CrestApps.Core/issues"
15
15
  },
16
+ "publishConfig": {
17
+ "access": "public",
18
+ "registry": "https://registry.npmjs.org/"
19
+ },
16
20
  "keywords": [
17
21
  "ai",
18
22
  "chat",
@@ -35,10 +39,17 @@
35
39
  "./ai-chat.min": "./dist/ai-chat.min.js",
36
40
  "./ai-chat.js.map": "./dist/ai-chat.js.map",
37
41
  "./ai-chat.min.js.map": "./dist/ai-chat.min.js.map",
42
+ "./ai-chat-widget": "./dist/ai-chat-widget.js",
43
+ "./ai-chat-widget.min": "./dist/ai-chat-widget.min.js",
44
+ "./ai-chat-widget.js.map": "./dist/ai-chat-widget.js.map",
45
+ "./ai-chat-widget.min.js.map": "./dist/ai-chat-widget.min.js.map",
38
46
  "./chat-interaction": "./dist/chat-interaction.js",
39
47
  "./chat-interaction.min": "./dist/chat-interaction.min.js",
40
48
  "./chat-interaction.js.map": "./dist/chat-interaction.js.map",
41
49
  "./chat-interaction.min.js.map": "./dist/chat-interaction.min.js.map",
50
+ "./ai-chat.css": "./dist/ai-chat.css",
51
+ "./ai-chat.min.css": "./dist/ai-chat.min.css",
52
+ "./ai-chat.css.map": "./dist/ai-chat.css.map",
42
53
  "./document-drop-zone": "./dist/document-drop-zone.js",
43
54
  "./document-drop-zone.min": "./dist/document-drop-zone.min.js",
44
55
  "./document-drop-zone.js.map": "./dist/document-drop-zone.js.map",
package/README.md DELETED
@@ -1,145 +0,0 @@
1
- # @crestapps/ai-chat-ui
2
-
3
- Browser-ready JavaScript widgets and CSS for **CrestApps AI** chat sessions and chat interactions. Drop them into any page that uses the [CrestApps.Core](https://github.com/CrestApps/CrestApps.Core) backend to get a fully functional AI chat experience with streaming responses, document uploads, image generation, interactive charts, copy-to-clipboard, and user feedback buttons.
4
-
5
- ## Features
6
-
7
- | Feature | Details |
8
- |---------|---------|
9
- | **Streaming responses** | Real-time token-by-token output via SignalR or REST |
10
- | **Image generation** | Inline rendering of images produced by `GenerateImageTool` |
11
- | **Interactive charts** | [Chart.js](https://www.chartjs.org/) rendering of charts produced by `GenerateChartTool` (optional peer dependency) |
12
- | **Document uploads** | Drag-and-drop or file-picker uploads attached to chat sessions |
13
- | **Copy to clipboard** | One-click copy of any assistant message |
14
- | **Feedback buttons** | Thumbs-up / thumbs-down per message |
15
- | **Markdown rendering** | Powered by [marked](https://github.com/markedjs/marked) and [DOMPurify](https://github.com/cure53/DOMPurify) |
16
-
17
- ## Installation
18
-
19
- ```bash
20
- npm install @crestapps/ai-chat-ui
21
- ```
22
-
23
- ### Optional: Chart.js Support
24
-
25
- To render interactive charts, also install Chart.js:
26
-
27
- ```bash
28
- npm install chart.js
29
- ```
30
-
31
- ## Included Files
32
-
33
- After installation the `dist/` directory contains:
34
-
35
- | File | Description |
36
- |------|-------------|
37
- | `ai-chat.js` / `.min.js` | AI Chat widget — manages sessions, uploads, streaming, and the full chat UI |
38
- | `chat-interaction.js` / `.min.js` | Chat Interaction widget — lighter standalone chat experience |
39
- | `document-drop-zone.js` / `.min.js` | Drag-and-drop file upload component |
40
- | `technical-name-generator.js` / `.min.js` | Auto-generates URL-safe technical names from display names |
41
- | `chat-widget.css` / `.min.css` | Styles for the floating AI Chat widget |
42
- | `document-drop-zone.css` / `.min.css` | Styles for the document drop-zone component |
43
-
44
- ## Usage
45
-
46
- ### Via CDN (simplest)
47
-
48
- Use [jsDelivr](https://www.jsdelivr.com/) to load files directly — no install required:
49
-
50
- ```html
51
- <!-- CSS -->
52
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@crestapps/ai-chat-ui@1.0.0-preview-22/dist/chat-widget.min.css" />
53
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@crestapps/ai-chat-ui@1.0.0-preview-22/dist/document-drop-zone.min.css" />
54
-
55
- <!-- Required dependencies -->
56
- <script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js"></script>
57
- <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
58
- <script src="https://cdn.jsdelivr.net/npm/dompurify/dist/purify.min.js"></script>
59
- <script src="https://cdn.jsdelivr.net/npm/@microsoft/signalr/dist/browser/signalr.min.js"></script>
60
-
61
- <!-- Optional: Chart.js for interactive charts -->
62
- <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
63
-
64
- <!-- CrestApps AI Chat UI -->
65
- <script src="https://cdn.jsdelivr.net/npm/@crestapps/ai-chat-ui@1.0.0-preview-22/dist/ai-chat.min.js"></script>
66
- <script src="https://cdn.jsdelivr.net/npm/@crestapps/ai-chat-ui@1.0.0-preview-22/dist/document-drop-zone.min.js"></script>
67
- ```
68
-
69
- > **Tip:** Replace `@1.0.0-preview-22` with the version you want, or omit it to always get the latest release.
70
-
71
- ### Via npm
72
-
73
- ```bash
74
- npm install @crestapps/ai-chat-ui
75
- ```
76
-
77
- Then copy the files from `node_modules/@crestapps/ai-chat-ui/dist/` into your web application's static assets folder and reference them with `<script>` and `<link>` tags.
78
-
79
- ### CDN URL Pattern
80
-
81
- All files in the package are available via jsDelivr using this pattern:
82
-
83
- ```
84
- https://cdn.jsdelivr.net/npm/@crestapps/ai-chat-ui@<version>/dist/<file>
85
- ```
86
-
87
- | Asset | CDN URL |
88
- |-------|---------|
89
- | `ai-chat.min.js` | `https://cdn.jsdelivr.net/npm/@crestapps/ai-chat-ui@1.0.0-preview-22/dist/ai-chat.min.js` |
90
- | `chat-interaction.min.js` | `https://cdn.jsdelivr.net/npm/@crestapps/ai-chat-ui@1.0.0-preview-22/dist/chat-interaction.min.js` |
91
- | `document-drop-zone.min.js` | `https://cdn.jsdelivr.net/npm/@crestapps/ai-chat-ui@1.0.0-preview-22/dist/document-drop-zone.min.js` |
92
- | `technical-name-generator.min.js` | `https://cdn.jsdelivr.net/npm/@crestapps/ai-chat-ui@1.0.0-preview-22/dist/technical-name-generator.min.js` |
93
- | `chat-widget.min.css` | `https://cdn.jsdelivr.net/npm/@crestapps/ai-chat-ui@1.0.0-preview-22/dist/chat-widget.min.css` |
94
- | `document-drop-zone.min.css` | `https://cdn.jsdelivr.net/npm/@crestapps/ai-chat-ui@1.0.0-preview-22/dist/document-drop-zone.min.css` |
95
-
96
- ### Initializing the AI Chat Widget
97
-
98
- ```javascript
99
- var chatManager = window.openAIChatManager();
100
- chatManager.createInstance({
101
- containerEl: '#ai-chat-container',
102
- profileId: 'your-profile-id',
103
- baseUrl: '/ai/chat-sessions',
104
- hubUrl: '/ai-chat-hub'
105
- });
106
- ```
107
-
108
- ### Initializing the Chat Interaction Widget
109
-
110
- ```javascript
111
- var interactionManager = window.chatInteractionManager();
112
- interactionManager.createInstance({
113
- containerEl: '#chat-interaction-container',
114
- deploymentName: 'your-deployment-name',
115
- baseUrl: '/chat-interactions',
116
- hubUrl: '/chat-interaction-hub'
117
- });
118
- ```
119
-
120
- ## Client-Side Dependencies
121
-
122
- Both widgets expect these libraries to be loaded on the page **before** the CrestApps script:
123
-
124
- | Library | Required | Purpose |
125
- |---------|----------|---------|
126
- | [Vue 3](https://vuejs.org/) | ✅ Yes | Reactive UI rendering |
127
- | [marked](https://github.com/markedjs/marked) | ✅ Yes | Markdown → HTML conversion |
128
- | [DOMPurify](https://github.com/cure53/DOMPurify) | ✅ Yes | HTML sanitization |
129
- | [SignalR](https://learn.microsoft.com/aspnet/core/signalr/) | ✅ Yes | Real-time streaming |
130
- | [Chart.js](https://www.chartjs.org/) | ❌ Optional | Interactive chart rendering |
131
- | [highlight.js](https://highlightjs.org/) | ❌ Optional | Code syntax highlighting |
132
-
133
- ## Backend Requirements
134
-
135
- These widgets are designed to work with the [CrestApps.Core](https://github.com/CrestApps/CrestApps.Core) .NET backend. You need:
136
-
137
- 1. **AI Chat sessions** — register with `.AddAISuite(ai => ai.AddChatInteractions(...))` or AI Profiles
138
- 2. **At least one AI provider** — e.g., `.AddOpenAI()`, `.AddAzureOpenAI()`, `.AddOllama()`
139
- 3. **SignalR hubs** — register with `.AddSignalR()`
140
-
141
- See the [CrestApps.Core documentation](https://crestapps.com/docs/core/chat) for full backend setup instructions.
142
-
143
- ## License
144
-
145
- [MIT](https://github.com/CrestApps/CrestApps.Core/blob/main/LICENSE)