@senior-gestao-relacionamento/angular-components 2.3.0-master-b74ccbc8 → 2.3.0-master-d385dd44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,7 @@
1
1
  import { Component, NgZone, ViewChild, inject } from '@angular/core';
2
2
  import { CommonModule } from '@angular/common';
3
3
  import { FormsModule } from '@angular/forms';
4
+ import { animate, style, transition, trigger } from '@angular/animations';
4
5
  import { ButtonModule } from 'primeng/button';
5
6
  import { Textarea } from 'primeng/textarea';
6
7
  import { BadgeModule } from 'primeng/badge';
@@ -16,6 +17,21 @@ import * as i3 from "primeng/button";
16
17
  * Gives Angular time to render the newly pushed message into the DOM.
17
18
  */
18
19
  const SCROLL_TO_BOTTOM_DELAY_MS = 50;
20
+ /**
21
+ * Interval (ms) between rotations of the "typing" status phrase.
22
+ */
23
+ const TYPING_PHRASE_ROTATION_MS = 2500;
24
+ /**
25
+ * Translation keys cycled while the assistant is preparing a response.
26
+ * Order matters: phrases are shown in this sequence.
27
+ */
28
+ const TYPING_PHRASE_KEYS = [
29
+ 'crmx.components.chatbot_typing_1',
30
+ 'crmx.components.chatbot_typing_2',
31
+ 'crmx.components.chatbot_typing_3',
32
+ 'crmx.components.chatbot_typing_4',
33
+ 'crmx.components.chatbot_typing_5'
34
+ ];
19
35
  /**
20
36
  * Chatbot global do CRM.
21
37
  *
@@ -32,7 +48,10 @@ export class ChatbotComponent {
32
48
  chatMessages = [];
33
49
  chatId = null;
34
50
  unreadCount = 0;
51
+ typingPhraseKey = TYPING_PHRASE_KEYS[0];
35
52
  wsSubscription = null;
53
+ typingPhraseTimer = null;
54
+ typingPhraseIndex = 0;
36
55
  wsConfig = {
37
56
  domain: 'crmx',
38
57
  service: 'chatbot',
@@ -50,6 +69,7 @@ export class ChatbotComponent {
50
69
  this.wsSubscription?.unsubscribe();
51
70
  this.webSocketService.unsubscribe(this.wsConfig);
52
71
  this.webSocketService.disconnect();
72
+ this.stopTypingPhraseRotation();
53
73
  }
54
74
  toggleChat() {
55
75
  this.isOpen = !this.isOpen;
@@ -66,6 +86,7 @@ export class ChatbotComponent {
66
86
  this.chatMessages.push({ role: 'user', content: text, timestamp: new Date() });
67
87
  this.userInput = '';
68
88
  this.sendingMessage = true;
89
+ this.startTypingPhraseRotation();
69
90
  this.scrollChatToBottom();
70
91
  this.chatbotService.chat(text, this.chatId ?? undefined).subscribe({
71
92
  error: () => {
@@ -75,6 +96,7 @@ export class ChatbotComponent {
75
96
  timestamp: new Date()
76
97
  });
77
98
  this.sendingMessage = false;
99
+ this.stopTypingPhraseRotation();
78
100
  this.scrollChatToBottom();
79
101
  }
80
102
  });
@@ -104,6 +126,7 @@ export class ChatbotComponent {
104
126
  responseTime: data.responseTime
105
127
  });
106
128
  this.sendingMessage = false;
129
+ this.stopTypingPhraseRotation();
107
130
  if (!this.isOpen) {
108
131
  this.unreadCount++;
109
132
  }
@@ -119,8 +142,36 @@ export class ChatbotComponent {
119
142
  }
120
143
  }, SCROLL_TO_BOTTOM_DELAY_MS);
121
144
  }
145
+ /**
146
+ * Starts cycling through the typing phrases. Always begins from the first
147
+ * key so the user sees the same friendly opening every time.
148
+ */
149
+ startTypingPhraseRotation() {
150
+ this.stopTypingPhraseRotation();
151
+ this.typingPhraseIndex = 0;
152
+ this.typingPhraseKey = TYPING_PHRASE_KEYS[0];
153
+ this.typingPhraseTimer = setInterval(() => {
154
+ this.ngZone.run(() => {
155
+ this.typingPhraseIndex = (this.typingPhraseIndex + 1) % TYPING_PHRASE_KEYS.length;
156
+ this.typingPhraseKey = TYPING_PHRASE_KEYS[this.typingPhraseIndex];
157
+ });
158
+ }, TYPING_PHRASE_ROTATION_MS);
159
+ }
160
+ stopTypingPhraseRotation() {
161
+ if (this.typingPhraseTimer !== null) {
162
+ clearInterval(this.typingPhraseTimer);
163
+ this.typingPhraseTimer = null;
164
+ }
165
+ }
122
166
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChatbotComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
123
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ChatbotComponent, isStandalone: true, selector: "s-chatbot", viewQueries: [{ propertyName: "chatMessagesContainer", first: true, predicate: ["chatMessagesContainer"], descendants: true }], ngImport: i0, template: "<!-- Floating Action Button -->\n<button type=\"button\" class=\"chatbot-fab\" [class.open]=\"isOpen\"\n [attr.aria-label]=\"'crmx.components.chatbot_title' | translate\"\n [attr.aria-expanded]=\"isOpen\"\n (click)=\"toggleChat()\">\n <i *ngIf=\"!isOpen\" class=\"pi pi-lightbulb fab-icon\"></i>\n <i *ngIf=\"isOpen\" class=\"pi pi-times\"></i>\n <span class=\"unread-badge\" *ngIf=\"unreadCount > 0 && !isOpen\">{{ unreadCount }}</span>\n</button>\n\n<!-- Chat Window -->\n<div class=\"chatbot-window\" *ngIf=\"isOpen\">\n <div class=\"chatbot-header\">\n <i class=\"pi pi-lightbulb header-icon\"></i>\n <span>{{ 'crmx.components.chatbot_title' | translate }}</span>\n </div>\n\n <div class=\"chatbot-messages\" #chatMessagesContainer>\n <!-- Welcome -->\n <div class=\"chatbot-welcome\" *ngIf=\"chatMessages.length === 0\">\n <i class=\"pi pi-lightbulb welcome-icon\"></i>\n <p>{{ 'crmx.components.chatbot_welcome' | translate }}</p>\n </div>\n\n <!-- Messages -->\n <div *ngFor=\"let msg of chatMessages\" class=\"chatbot-message\"\n [ngClass]=\"{ 'user-message': msg.role === 'user', 'assistant-message': msg.role === 'assistant' }\">\n <div class=\"message-avatar\">\n <i *ngIf=\"msg.role === 'user'\" class=\"pi pi-user\"></i>\n <i *ngIf=\"msg.role === 'assistant'\" class=\"pi pi-lightbulb assistant-avatar-icon\"></i>\n </div>\n <div class=\"message-bubble\" [class.markdown-content]=\"msg.role === 'assistant'\">\n <p *ngIf=\"msg.role === 'user'\">{{ msg.content }}</p>\n <div *ngIf=\"msg.role === 'assistant'\" [innerHTML]=\"msg.content | sChatbotMarkdown\"></div>\n <div class=\"message-meta\">\n <span class=\"message-time\">{{ msg.timestamp | date:'HH:mm' }}</span>\n <span class=\"response-time\" *ngIf=\"msg.responseTime\">\u23F1 {{ msg.responseTime }}s</span>\n </div>\n </div>\n </div>\n\n <!-- Typing indicator -->\n <div class=\"chatbot-typing\" *ngIf=\"sendingMessage\">\n <div class=\"message-avatar\"><i class=\"pi pi-lightbulb assistant-avatar-icon\"></i></div>\n <div class=\"typing-indicator\"><span></span><span></span><span></span></div>\n </div>\n </div>\n\n <div class=\"chatbot-input-area\">\n <div class=\"input-row\">\n <label for=\"s-chatbot-input\" class=\"sr-only\">{{ 'crmx.components.chatbot_placeholder' | translate }}</label>\n <textarea pTextarea id=\"s-chatbot-input\" [(ngModel)]=\"userInput\"\n [placeholder]=\"'crmx.components.chatbot_placeholder' | translate\"\n [autoResize]=\"true\" [rows]=\"1\" [maxlength]=\"2000\"\n (keydown)=\"onChatKeydown($event)\" [disabled]=\"sendingMessage\"></textarea>\n <button pButton type=\"button\" class=\"p-button-rounded send-btn\"\n [attr.aria-label]=\"'crmx.components.chatbot_placeholder' | translate\"\n [loading]=\"sendingMessage\" [disabled]=\"!userInput.trim() || sendingMessage\"\n (click)=\"sendMessage()\">\n <i class=\"pi pi-send\"></i>\n </button>\n </div>\n </div>\n</div>\n", styles: [".sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.chatbot-fab{position:fixed;bottom:1.5rem;right:1.5rem;width:56px;height:56px;border:0;padding:0;border-radius:50%;background:var(--p-primary-color, #667eea);color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 4px 12px #00000040;z-index:1100;transition:transform .2s ease,background .2s ease;font:inherit}.chatbot-fab:hover{transform:scale(1.08)}.chatbot-fab:focus-visible{outline:2px solid var(--p-primary-color, #667eea);outline-offset:2px}.chatbot-fab.open{background:var(--p-surface-500, #6c757d)}.chatbot-fab .pi-times{font-size:1.25rem}.chatbot-fab .fab-icon{font-size:1.5rem}.chatbot-fab .unread-badge{position:absolute;top:-4px;right:-4px;min-width:20px;height:20px;border-radius:10px;background:#ef4444;color:#fff;font-size:.7rem;font-weight:700;display:flex;align-items:center;justify-content:center;padding:0 5px;box-shadow:0 2px 4px #0003}.chatbot-window{position:fixed;bottom:6.5rem;right:1.5rem;width:380px;height:520px;background:#fff;border-radius:12px;box-shadow:0 8px 32px #0000002e;z-index:1100;display:flex;flex-direction:column;overflow:hidden;animation:chatbot-slide-up .25s ease-out}.chatbot-header{display:flex;align-items:center;gap:.5rem;padding:.75rem 1rem;background:var(--p-primary-color, #667eea);color:#fff;font-weight:600;font-size:.9rem;flex-shrink:0}.chatbot-header .header-icon{font-size:1.1rem}.chatbot-messages{flex:1;overflow-y:auto;padding:1rem;display:flex;flex-direction:column;gap:.75rem}.chatbot-welcome{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;color:#adb5bd;text-align:center;padding:2rem}.chatbot-welcome .welcome-icon{font-size:2.5rem;color:var(--p-primary-color, #667eea);opacity:.7}.chatbot-welcome p{font-size:.9rem;color:#6c757d;margin:.75rem 0 0;line-height:1.5}.chatbot-message{display:flex;gap:.5rem;max-width:90%;align-items:flex-end}.message-avatar{width:26px;height:26px;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0}.message-avatar .assistant-avatar-icon{font-size:1rem;color:var(--p-primary-color, #667eea)}.message-bubble{padding:.6rem .85rem;font-size:.85rem;line-height:1.4}.message-bubble p{margin:0;white-space:pre-wrap;word-break:break-word}.message-bubble .response-time{opacity:.7}.message-bubble .message-meta{display:flex;justify-content:flex-start;align-items:center;gap:.5rem;margin-top:.25rem;font-size:.7rem}.chatbot-message.assistant-message{align-self:flex-start}.chatbot-message.assistant-message .message-bubble{background:#f1f3f5;color:#2c3e50;border-radius:12px 12px 12px 0}.chatbot-message.assistant-message .message-bubble .message-time{color:#adb5bd}.chatbot-message.user-message{align-self:flex-end;flex-direction:row-reverse}.chatbot-message.user-message .message-avatar{background:var(--p-primary-color, #667eea);color:#fff}.chatbot-message.user-message .message-bubble{background:var(--p-primary-color, #667eea);color:#fff;border-radius:12px 12px 0}.chatbot-message.user-message .message-bubble .message-meta{justify-content:flex-end}.chatbot-message.user-message .message-bubble .message-time{color:#ffffffb3}.chatbot-typing{display:flex;gap:.5rem;align-self:flex-start;align-items:flex-end}.chatbot-typing .typing-indicator{display:flex;gap:4px;padding:.75rem 1rem;background:#f1f3f5;border-radius:12px 12px 12px 0}.chatbot-typing .typing-indicator span{width:6px;height:6px;border-radius:50%;background:#adb5bd;animation:chatbot-typing 1.4s infinite}.chatbot-typing .typing-indicator span:nth-child(2){animation-delay:.2s}.chatbot-typing .typing-indicator span:nth-child(3){animation-delay:.4s}.chatbot-input-area{display:flex;flex-direction:column;gap:.5rem;padding:.75rem;border-top:1px solid #e9ecef;background:#fff;flex-shrink:0}.chatbot-input-area .input-row{display:flex;align-items:center;gap:.5rem}.chatbot-input-area textarea{flex:1;resize:none;border-radius:8px;font-size:.85rem;max-height:100px}.chatbot-input-area .send-btn{flex-shrink:0;width:36px;height:36px}:host ::ng-deep .message-bubble.markdown-content{overflow-x:auto}:host ::ng-deep .message-bubble.markdown-content>*{margin-top:0;margin-bottom:0}:host ::ng-deep .message-bubble.markdown-content>*+*{margin-top:.4rem}:host ::ng-deep .message-bubble.markdown-content a{color:var(--p-primary-color, #667eea);text-decoration:underline}:host ::ng-deep .message-bubble.markdown-content strong{font-weight:600}:host ::ng-deep .message-bubble.markdown-content hr{border:0;border-top:1px solid rgba(0,0,0,.12);margin:.5rem 0}:host ::ng-deep .message-bubble.markdown-content code{background:#00000014;padding:.1rem .3rem;border-radius:3px;font-size:.8rem;font-family:Courier New,monospace}:host ::ng-deep .message-bubble.markdown-content pre{background:#0000000f;padding:.5rem;border-radius:6px;overflow-x:auto;font-size:.8rem}:host ::ng-deep .message-bubble.markdown-content pre code{background:none;padding:0}:host ::ng-deep .message-bubble.markdown-content blockquote{border-left:3px solid rgba(0,0,0,.15);padding-left:.6rem;opacity:.85}:host ::ng-deep .message-bubble.markdown-content ul,:host ::ng-deep .message-bubble.markdown-content ol{padding-left:1.2rem}:host ::ng-deep .message-bubble.markdown-content li{margin-bottom:.15rem}:host ::ng-deep .message-bubble.markdown-content h1,:host ::ng-deep .message-bubble.markdown-content h2,:host ::ng-deep .message-bubble.markdown-content h3,:host ::ng-deep .message-bubble.markdown-content h4,:host ::ng-deep .message-bubble.markdown-content h5,:host ::ng-deep .message-bubble.markdown-content h6{font-weight:600;line-height:1.3}:host ::ng-deep .message-bubble.markdown-content h1{font-size:1.1rem}:host ::ng-deep .message-bubble.markdown-content h2{font-size:1rem}:host ::ng-deep .message-bubble.markdown-content h3{font-size:.95rem}:host ::ng-deep .message-bubble.markdown-content table{border-collapse:collapse;width:100%;font-size:.8rem;margin:.4rem 0}:host ::ng-deep .message-bubble.markdown-content table th,:host ::ng-deep .message-bubble.markdown-content table td{border:1px solid rgba(0,0,0,.2);padding:.3rem .5rem;text-align:left;vertical-align:top}:host ::ng-deep .message-bubble.markdown-content table th{font-weight:600;background:#0000000d}:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content table th,:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content table td{border-color:#fff3}:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content table th{background:#ffffff14}:host ::ng-deep .message-bubble.markdown-content table tbody tr:nth-child(2n) td{background:#00000005}:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content table tbody tr:nth-child(2n) td{background:#ffffff08}@keyframes chatbot-slide-up{0%{opacity:0;transform:translateY(16px)}to{opacity:1;transform:translateY(0)}}@keyframes chatbot-typing{0%,60%,to{transform:translateY(0);opacity:.4}30%{transform:translateY(-4px);opacity:1}}:host-context(.app-dark) .chatbot-window{background:var(--p-surface-100, #1e1e1e)}:host-context(.app-dark) .chatbot-messages{background:var(--p-surface-100, #1e1e1e)}:host-context(.app-dark) .chatbot-welcome p{color:var(--p-surface-500, #adb5bd)}:host-context(.app-dark) .chatbot-message.assistant-message .message-bubble{background:var(--p-surface-200, #2d2d2d);color:var(--p-surface-900, #e0e0e0)}:host-context(.app-dark) .chatbot-input-area{background:var(--p-surface-100, #1e1e1e);border-top-color:var(--p-surface-300, #3d3d3d)}:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content code{background:#ffffff1a}:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content pre{background:#ffffff14}:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content blockquote{border-left-color:#fff3}:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content hr{border-top-color:#ffffff26}@media (max-width: 480px){.chatbot-window{width:calc(100vw - 2rem);height:calc(100vh - 8rem);right:1rem;bottom:5rem}.chatbot-fab{bottom:1rem;right:1rem}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.DatePipe, name: "date" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i3.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "directive", type: Textarea, selector: "[pTextarea]", inputs: ["autoResize", "variant", "fluid", "pSize"], outputs: ["onResize"] }, { kind: "ngmodule", type: BadgeModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: ChatbotMarkdownPipe, name: "sChatbotMarkdown" }] });
167
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ChatbotComponent, isStandalone: true, selector: "s-chatbot", viewQueries: [{ propertyName: "chatMessagesContainer", first: true, predicate: ["chatMessagesContainer"], descendants: true }], ngImport: i0, template: "<!-- Floating Action Button -->\n<button type=\"button\" class=\"chatbot-fab\" [class.open]=\"isOpen\"\n [attr.aria-label]=\"'crmx.components.chatbot_title' | translate\"\n [attr.aria-expanded]=\"isOpen\"\n (click)=\"toggleChat()\">\n <i *ngIf=\"!isOpen\" class=\"pi pi-lightbulb fab-icon\"></i>\n <i *ngIf=\"isOpen\" class=\"pi pi-times\"></i>\n <span class=\"unread-badge\" *ngIf=\"unreadCount > 0 && !isOpen\">{{ unreadCount }}</span>\n</button>\n\n<!-- Chat Window -->\n<div class=\"chatbot-window\" *ngIf=\"isOpen\">\n <div class=\"chatbot-header\">\n <i class=\"pi pi-lightbulb header-icon\"></i>\n <span>{{ 'crmx.components.chatbot_title' | translate }}</span>\n </div>\n\n <div class=\"chatbot-messages\" #chatMessagesContainer>\n <!-- Welcome -->\n <div class=\"chatbot-welcome\" *ngIf=\"chatMessages.length === 0\">\n <i class=\"pi pi-lightbulb welcome-icon\"></i>\n <p>{{ 'crmx.components.chatbot_welcome' | translate }}</p>\n </div>\n\n <!-- Messages -->\n <div *ngFor=\"let msg of chatMessages\" class=\"chatbot-message\"\n [ngClass]=\"{ 'user-message': msg.role === 'user', 'assistant-message': msg.role === 'assistant' }\">\n <div class=\"message-avatar\">\n <i *ngIf=\"msg.role === 'user'\" class=\"pi pi-user\"></i>\n <i *ngIf=\"msg.role === 'assistant'\" class=\"pi pi-lightbulb assistant-avatar-icon\"></i>\n </div>\n <div class=\"message-bubble\" [class.markdown-content]=\"msg.role === 'assistant'\">\n <p *ngIf=\"msg.role === 'user'\">{{ msg.content }}</p>\n <div *ngIf=\"msg.role === 'assistant'\" [innerHTML]=\"msg.content | sChatbotMarkdown\"></div>\n <div class=\"message-meta\">\n <span class=\"message-time\">{{ msg.timestamp | date:'HH:mm' }}</span>\n <span class=\"response-time\" *ngIf=\"msg.responseTime\">\u23F1 {{ msg.responseTime }}s</span>\n </div>\n </div>\n </div>\n\n <!-- Typing indicator -->\n <div class=\"chatbot-typing\" *ngIf=\"sendingMessage\">\n <div class=\"message-avatar\"><i class=\"pi pi-lightbulb assistant-avatar-icon\"></i></div>\n <div class=\"typing-bubble\" aria-live=\"polite\">\n <span class=\"typing-phrase\" [@chatbotPhraseFade]=\"typingPhraseKey\">{{ typingPhraseKey | translate }}</span>\n <span class=\"typing-pulse\" aria-hidden=\"true\">\n <span></span><span></span><span></span>\n </span>\n </div>\n </div>\n </div>\n\n <div class=\"chatbot-input-area\">\n <div class=\"input-row\">\n <label for=\"s-chatbot-input\" class=\"sr-only\">{{ 'crmx.components.chatbot_placeholder' | translate }}</label>\n <textarea pTextarea id=\"s-chatbot-input\" [(ngModel)]=\"userInput\"\n [placeholder]=\"'crmx.components.chatbot_placeholder' | translate\"\n [autoResize]=\"true\" [rows]=\"1\" [maxlength]=\"2000\"\n (keydown)=\"onChatKeydown($event)\" [disabled]=\"sendingMessage\"></textarea>\n <button pButton type=\"button\" class=\"p-button-rounded send-btn\"\n [attr.aria-label]=\"'crmx.components.chatbot_placeholder' | translate\"\n [disabled]=\"!userInput.trim() || sendingMessage\"\n (click)=\"sendMessage()\">\n <i class=\"pi pi-send\"></i>\n </button>\n </div>\n </div>\n</div>\n", styles: [".sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.chatbot-fab{position:fixed;bottom:1.5rem;right:1.5rem;width:56px;height:56px;border:0;padding:0;border-radius:50%;background:var(--p-primary-color, #667eea);color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 4px 12px #00000040;z-index:1100;transition:transform .2s ease,background .2s ease;font:inherit}.chatbot-fab:hover{transform:scale(1.08)}.chatbot-fab:focus-visible{outline:2px solid var(--p-primary-color, #667eea);outline-offset:2px}.chatbot-fab.open{background:var(--p-surface-500, #6c757d)}.chatbot-fab .pi-times{font-size:1.25rem}.chatbot-fab .fab-icon{font-size:1.5rem}.chatbot-fab .unread-badge{position:absolute;top:-4px;right:-4px;min-width:20px;height:20px;border-radius:10px;background:#ef4444;color:#fff;font-size:.7rem;font-weight:700;display:flex;align-items:center;justify-content:center;padding:0 5px;box-shadow:0 2px 4px #0003}.chatbot-window{position:fixed;bottom:6.5rem;right:1.5rem;width:380px;height:520px;background:#fff;border-radius:12px;box-shadow:0 8px 32px #0000002e;z-index:1100;display:flex;flex-direction:column;overflow:hidden;animation:chatbot-slide-up .25s ease-out}.chatbot-header{display:flex;align-items:center;gap:.5rem;padding:.75rem 1rem;background:var(--p-primary-color, #667eea);color:#fff;font-weight:600;font-size:.9rem;flex-shrink:0}.chatbot-header .header-icon{font-size:1.1rem}.chatbot-messages{flex:1;overflow-y:auto;padding:1rem;display:flex;flex-direction:column;gap:.75rem}.chatbot-welcome{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;color:#adb5bd;text-align:center;padding:2rem}.chatbot-welcome .welcome-icon{font-size:2.5rem;color:var(--p-primary-color, #667eea);opacity:.7}.chatbot-welcome p{font-size:.9rem;color:#6c757d;margin:.75rem 0 0;line-height:1.5}.chatbot-message{display:flex;gap:.5rem;max-width:90%;align-items:flex-end}.message-avatar{width:26px;height:26px;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0}.message-avatar .assistant-avatar-icon{font-size:1rem;color:var(--p-primary-color, #667eea)}.message-bubble{padding:.6rem .85rem;font-size:.85rem;line-height:1.4}.message-bubble p{margin:0;white-space:pre-wrap;word-break:break-word}.message-bubble .response-time{opacity:.7}.message-bubble .message-meta{display:flex;justify-content:flex-start;align-items:center;gap:.5rem;margin-top:.25rem;font-size:.7rem}.chatbot-message.assistant-message{align-self:flex-start}.chatbot-message.assistant-message .message-bubble{background:#f1f3f5;color:#2c3e50;border-radius:12px 12px 12px 0}.chatbot-message.assistant-message .message-bubble .message-time{color:#adb5bd}.chatbot-message.user-message{align-self:flex-end;flex-direction:row-reverse}.chatbot-message.user-message .message-avatar{background:var(--p-primary-color, #667eea);color:#fff}.chatbot-message.user-message .message-bubble{background:var(--p-primary-color, #667eea);color:#fff;border-radius:12px 12px 0}.chatbot-message.user-message .message-bubble .message-meta{justify-content:flex-end}.chatbot-message.user-message .message-bubble .message-time{color:#ffffffb3}.chatbot-typing{display:flex;gap:.5rem;align-self:flex-start;align-items:flex-end}.chatbot-typing .typing-bubble{display:flex;align-items:center;gap:.5rem;padding:.55rem .85rem;background:#f1f3f5;color:#495057;border-radius:12px 12px 12px 0;font-size:.85rem;line-height:1.3;max-width:240px}.chatbot-typing .typing-phrase{display:inline-block}.chatbot-typing .typing-pulse{display:inline-flex;gap:3px;flex-shrink:0}.chatbot-typing .typing-pulse span{width:4px;height:4px;border-radius:50%;background:#adb5bd;animation:chatbot-typing 1.4s infinite}.chatbot-typing .typing-pulse span:nth-child(2){animation-delay:.2s}.chatbot-typing .typing-pulse span:nth-child(3){animation-delay:.4s}.chatbot-input-area{display:flex;flex-direction:column;gap:.5rem;padding:.75rem;border-top:1px solid #e9ecef;background:#fff;flex-shrink:0}.chatbot-input-area .input-row{display:flex;align-items:flex-end;gap:.5rem}.chatbot-input-area textarea{flex:1;resize:none;border-radius:8px;font-size:.85rem;max-height:100px}.chatbot-input-area .send-btn{flex-shrink:0;width:36px;height:36px;align-self:center}:host ::ng-deep .message-bubble.markdown-content{overflow-x:auto}:host ::ng-deep .message-bubble.markdown-content>*{margin-top:0;margin-bottom:0}:host ::ng-deep .message-bubble.markdown-content>*+*{margin-top:.4rem}:host ::ng-deep .message-bubble.markdown-content a{color:var(--p-primary-color, #667eea);text-decoration:underline}:host ::ng-deep .message-bubble.markdown-content strong{font-weight:600}:host ::ng-deep .message-bubble.markdown-content hr{border:0;border-top:1px solid rgba(0,0,0,.12);margin:.5rem 0}:host ::ng-deep .message-bubble.markdown-content code{background:#00000014;padding:.1rem .3rem;border-radius:3px;font-size:.8rem;font-family:Courier New,monospace}:host ::ng-deep .message-bubble.markdown-content pre{background:#0000000f;padding:.5rem;border-radius:6px;overflow-x:auto;font-size:.8rem}:host ::ng-deep .message-bubble.markdown-content pre code{background:none;padding:0}:host ::ng-deep .message-bubble.markdown-content blockquote{border-left:3px solid rgba(0,0,0,.15);padding-left:.6rem;opacity:.85}:host ::ng-deep .message-bubble.markdown-content ul,:host ::ng-deep .message-bubble.markdown-content ol{padding-left:1.2rem}:host ::ng-deep .message-bubble.markdown-content li{margin-bottom:.15rem}:host ::ng-deep .message-bubble.markdown-content h1,:host ::ng-deep .message-bubble.markdown-content h2,:host ::ng-deep .message-bubble.markdown-content h3,:host ::ng-deep .message-bubble.markdown-content h4,:host ::ng-deep .message-bubble.markdown-content h5,:host ::ng-deep .message-bubble.markdown-content h6{font-weight:600;line-height:1.3}:host ::ng-deep .message-bubble.markdown-content h1{font-size:1.1rem}:host ::ng-deep .message-bubble.markdown-content h2{font-size:1rem}:host ::ng-deep .message-bubble.markdown-content h3{font-size:.95rem}:host ::ng-deep .message-bubble.markdown-content table{border-collapse:collapse;width:100%;font-size:.8rem;margin:.4rem 0}:host ::ng-deep .message-bubble.markdown-content table th,:host ::ng-deep .message-bubble.markdown-content table td{border:1px solid rgba(0,0,0,.2);padding:.3rem .5rem;text-align:left;vertical-align:top}:host ::ng-deep .message-bubble.markdown-content table th{font-weight:600;background:#0000000d}:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content table th,:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content table td{border-color:#fff3}:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content table th{background:#ffffff14}:host ::ng-deep .message-bubble.markdown-content table tbody tr:nth-child(2n) td{background:#00000005}:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content table tbody tr:nth-child(2n) td{background:#ffffff08}@keyframes chatbot-slide-up{0%{opacity:0;transform:translateY(16px)}to{opacity:1;transform:translateY(0)}}@keyframes chatbot-typing{0%,60%,to{transform:translateY(0);opacity:.4}30%{transform:translateY(-4px);opacity:1}}:host-context(.app-dark) .chatbot-window{background:var(--p-surface-100, #1e1e1e)}:host-context(.app-dark) .chatbot-messages{background:var(--p-surface-100, #1e1e1e)}:host-context(.app-dark) .chatbot-welcome p{color:var(--p-surface-500, #adb5bd)}:host-context(.app-dark) .chatbot-message.assistant-message .message-bubble{background:var(--p-surface-200, #2d2d2d);color:var(--p-surface-900, #e0e0e0)}:host-context(.app-dark) .chatbot-input-area{background:var(--p-surface-100, #1e1e1e);border-top-color:var(--p-surface-300, #3d3d3d)}:host-context(.app-dark) .chatbot-typing .typing-bubble{background:var(--p-surface-200, #2d2d2d);color:var(--p-surface-900, #e0e0e0)}:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content code{background:#ffffff1a}:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content pre{background:#ffffff14}:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content blockquote{border-left-color:#fff3}:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content hr{border-top-color:#ffffff26}@media (max-width: 480px){.chatbot-window{width:calc(100vw - 2rem);height:calc(100vh - 8rem);right:1rem;bottom:5rem}.chatbot-fab{bottom:1rem;right:1rem}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.DatePipe, name: "date" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i3.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "directive", type: Textarea, selector: "[pTextarea]", inputs: ["autoResize", "variant", "fluid", "pSize"], outputs: ["onResize"] }, { kind: "ngmodule", type: BadgeModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: ChatbotMarkdownPipe, name: "sChatbotMarkdown" }], animations: [
168
+ trigger('chatbotPhraseFade', [
169
+ transition('* => *', [
170
+ style({ opacity: 0, transform: 'translateY(2px)' }),
171
+ animate('220ms ease-out', style({ opacity: 1, transform: 'translateY(0)' }))
172
+ ])
173
+ ])
174
+ ] });
124
175
  }
125
176
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChatbotComponent, decorators: [{
126
177
  type: Component,
@@ -132,9 +183,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
132
183
  BadgeModule,
133
184
  TranslatePipe,
134
185
  ChatbotMarkdownPipe
135
- ], template: "<!-- Floating Action Button -->\n<button type=\"button\" class=\"chatbot-fab\" [class.open]=\"isOpen\"\n [attr.aria-label]=\"'crmx.components.chatbot_title' | translate\"\n [attr.aria-expanded]=\"isOpen\"\n (click)=\"toggleChat()\">\n <i *ngIf=\"!isOpen\" class=\"pi pi-lightbulb fab-icon\"></i>\n <i *ngIf=\"isOpen\" class=\"pi pi-times\"></i>\n <span class=\"unread-badge\" *ngIf=\"unreadCount > 0 && !isOpen\">{{ unreadCount }}</span>\n</button>\n\n<!-- Chat Window -->\n<div class=\"chatbot-window\" *ngIf=\"isOpen\">\n <div class=\"chatbot-header\">\n <i class=\"pi pi-lightbulb header-icon\"></i>\n <span>{{ 'crmx.components.chatbot_title' | translate }}</span>\n </div>\n\n <div class=\"chatbot-messages\" #chatMessagesContainer>\n <!-- Welcome -->\n <div class=\"chatbot-welcome\" *ngIf=\"chatMessages.length === 0\">\n <i class=\"pi pi-lightbulb welcome-icon\"></i>\n <p>{{ 'crmx.components.chatbot_welcome' | translate }}</p>\n </div>\n\n <!-- Messages -->\n <div *ngFor=\"let msg of chatMessages\" class=\"chatbot-message\"\n [ngClass]=\"{ 'user-message': msg.role === 'user', 'assistant-message': msg.role === 'assistant' }\">\n <div class=\"message-avatar\">\n <i *ngIf=\"msg.role === 'user'\" class=\"pi pi-user\"></i>\n <i *ngIf=\"msg.role === 'assistant'\" class=\"pi pi-lightbulb assistant-avatar-icon\"></i>\n </div>\n <div class=\"message-bubble\" [class.markdown-content]=\"msg.role === 'assistant'\">\n <p *ngIf=\"msg.role === 'user'\">{{ msg.content }}</p>\n <div *ngIf=\"msg.role === 'assistant'\" [innerHTML]=\"msg.content | sChatbotMarkdown\"></div>\n <div class=\"message-meta\">\n <span class=\"message-time\">{{ msg.timestamp | date:'HH:mm' }}</span>\n <span class=\"response-time\" *ngIf=\"msg.responseTime\">\u23F1 {{ msg.responseTime }}s</span>\n </div>\n </div>\n </div>\n\n <!-- Typing indicator -->\n <div class=\"chatbot-typing\" *ngIf=\"sendingMessage\">\n <div class=\"message-avatar\"><i class=\"pi pi-lightbulb assistant-avatar-icon\"></i></div>\n <div class=\"typing-indicator\"><span></span><span></span><span></span></div>\n </div>\n </div>\n\n <div class=\"chatbot-input-area\">\n <div class=\"input-row\">\n <label for=\"s-chatbot-input\" class=\"sr-only\">{{ 'crmx.components.chatbot_placeholder' | translate }}</label>\n <textarea pTextarea id=\"s-chatbot-input\" [(ngModel)]=\"userInput\"\n [placeholder]=\"'crmx.components.chatbot_placeholder' | translate\"\n [autoResize]=\"true\" [rows]=\"1\" [maxlength]=\"2000\"\n (keydown)=\"onChatKeydown($event)\" [disabled]=\"sendingMessage\"></textarea>\n <button pButton type=\"button\" class=\"p-button-rounded send-btn\"\n [attr.aria-label]=\"'crmx.components.chatbot_placeholder' | translate\"\n [loading]=\"sendingMessage\" [disabled]=\"!userInput.trim() || sendingMessage\"\n (click)=\"sendMessage()\">\n <i class=\"pi pi-send\"></i>\n </button>\n </div>\n </div>\n</div>\n", styles: [".sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.chatbot-fab{position:fixed;bottom:1.5rem;right:1.5rem;width:56px;height:56px;border:0;padding:0;border-radius:50%;background:var(--p-primary-color, #667eea);color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 4px 12px #00000040;z-index:1100;transition:transform .2s ease,background .2s ease;font:inherit}.chatbot-fab:hover{transform:scale(1.08)}.chatbot-fab:focus-visible{outline:2px solid var(--p-primary-color, #667eea);outline-offset:2px}.chatbot-fab.open{background:var(--p-surface-500, #6c757d)}.chatbot-fab .pi-times{font-size:1.25rem}.chatbot-fab .fab-icon{font-size:1.5rem}.chatbot-fab .unread-badge{position:absolute;top:-4px;right:-4px;min-width:20px;height:20px;border-radius:10px;background:#ef4444;color:#fff;font-size:.7rem;font-weight:700;display:flex;align-items:center;justify-content:center;padding:0 5px;box-shadow:0 2px 4px #0003}.chatbot-window{position:fixed;bottom:6.5rem;right:1.5rem;width:380px;height:520px;background:#fff;border-radius:12px;box-shadow:0 8px 32px #0000002e;z-index:1100;display:flex;flex-direction:column;overflow:hidden;animation:chatbot-slide-up .25s ease-out}.chatbot-header{display:flex;align-items:center;gap:.5rem;padding:.75rem 1rem;background:var(--p-primary-color, #667eea);color:#fff;font-weight:600;font-size:.9rem;flex-shrink:0}.chatbot-header .header-icon{font-size:1.1rem}.chatbot-messages{flex:1;overflow-y:auto;padding:1rem;display:flex;flex-direction:column;gap:.75rem}.chatbot-welcome{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;color:#adb5bd;text-align:center;padding:2rem}.chatbot-welcome .welcome-icon{font-size:2.5rem;color:var(--p-primary-color, #667eea);opacity:.7}.chatbot-welcome p{font-size:.9rem;color:#6c757d;margin:.75rem 0 0;line-height:1.5}.chatbot-message{display:flex;gap:.5rem;max-width:90%;align-items:flex-end}.message-avatar{width:26px;height:26px;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0}.message-avatar .assistant-avatar-icon{font-size:1rem;color:var(--p-primary-color, #667eea)}.message-bubble{padding:.6rem .85rem;font-size:.85rem;line-height:1.4}.message-bubble p{margin:0;white-space:pre-wrap;word-break:break-word}.message-bubble .response-time{opacity:.7}.message-bubble .message-meta{display:flex;justify-content:flex-start;align-items:center;gap:.5rem;margin-top:.25rem;font-size:.7rem}.chatbot-message.assistant-message{align-self:flex-start}.chatbot-message.assistant-message .message-bubble{background:#f1f3f5;color:#2c3e50;border-radius:12px 12px 12px 0}.chatbot-message.assistant-message .message-bubble .message-time{color:#adb5bd}.chatbot-message.user-message{align-self:flex-end;flex-direction:row-reverse}.chatbot-message.user-message .message-avatar{background:var(--p-primary-color, #667eea);color:#fff}.chatbot-message.user-message .message-bubble{background:var(--p-primary-color, #667eea);color:#fff;border-radius:12px 12px 0}.chatbot-message.user-message .message-bubble .message-meta{justify-content:flex-end}.chatbot-message.user-message .message-bubble .message-time{color:#ffffffb3}.chatbot-typing{display:flex;gap:.5rem;align-self:flex-start;align-items:flex-end}.chatbot-typing .typing-indicator{display:flex;gap:4px;padding:.75rem 1rem;background:#f1f3f5;border-radius:12px 12px 12px 0}.chatbot-typing .typing-indicator span{width:6px;height:6px;border-radius:50%;background:#adb5bd;animation:chatbot-typing 1.4s infinite}.chatbot-typing .typing-indicator span:nth-child(2){animation-delay:.2s}.chatbot-typing .typing-indicator span:nth-child(3){animation-delay:.4s}.chatbot-input-area{display:flex;flex-direction:column;gap:.5rem;padding:.75rem;border-top:1px solid #e9ecef;background:#fff;flex-shrink:0}.chatbot-input-area .input-row{display:flex;align-items:center;gap:.5rem}.chatbot-input-area textarea{flex:1;resize:none;border-radius:8px;font-size:.85rem;max-height:100px}.chatbot-input-area .send-btn{flex-shrink:0;width:36px;height:36px}:host ::ng-deep .message-bubble.markdown-content{overflow-x:auto}:host ::ng-deep .message-bubble.markdown-content>*{margin-top:0;margin-bottom:0}:host ::ng-deep .message-bubble.markdown-content>*+*{margin-top:.4rem}:host ::ng-deep .message-bubble.markdown-content a{color:var(--p-primary-color, #667eea);text-decoration:underline}:host ::ng-deep .message-bubble.markdown-content strong{font-weight:600}:host ::ng-deep .message-bubble.markdown-content hr{border:0;border-top:1px solid rgba(0,0,0,.12);margin:.5rem 0}:host ::ng-deep .message-bubble.markdown-content code{background:#00000014;padding:.1rem .3rem;border-radius:3px;font-size:.8rem;font-family:Courier New,monospace}:host ::ng-deep .message-bubble.markdown-content pre{background:#0000000f;padding:.5rem;border-radius:6px;overflow-x:auto;font-size:.8rem}:host ::ng-deep .message-bubble.markdown-content pre code{background:none;padding:0}:host ::ng-deep .message-bubble.markdown-content blockquote{border-left:3px solid rgba(0,0,0,.15);padding-left:.6rem;opacity:.85}:host ::ng-deep .message-bubble.markdown-content ul,:host ::ng-deep .message-bubble.markdown-content ol{padding-left:1.2rem}:host ::ng-deep .message-bubble.markdown-content li{margin-bottom:.15rem}:host ::ng-deep .message-bubble.markdown-content h1,:host ::ng-deep .message-bubble.markdown-content h2,:host ::ng-deep .message-bubble.markdown-content h3,:host ::ng-deep .message-bubble.markdown-content h4,:host ::ng-deep .message-bubble.markdown-content h5,:host ::ng-deep .message-bubble.markdown-content h6{font-weight:600;line-height:1.3}:host ::ng-deep .message-bubble.markdown-content h1{font-size:1.1rem}:host ::ng-deep .message-bubble.markdown-content h2{font-size:1rem}:host ::ng-deep .message-bubble.markdown-content h3{font-size:.95rem}:host ::ng-deep .message-bubble.markdown-content table{border-collapse:collapse;width:100%;font-size:.8rem;margin:.4rem 0}:host ::ng-deep .message-bubble.markdown-content table th,:host ::ng-deep .message-bubble.markdown-content table td{border:1px solid rgba(0,0,0,.2);padding:.3rem .5rem;text-align:left;vertical-align:top}:host ::ng-deep .message-bubble.markdown-content table th{font-weight:600;background:#0000000d}:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content table th,:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content table td{border-color:#fff3}:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content table th{background:#ffffff14}:host ::ng-deep .message-bubble.markdown-content table tbody tr:nth-child(2n) td{background:#00000005}:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content table tbody tr:nth-child(2n) td{background:#ffffff08}@keyframes chatbot-slide-up{0%{opacity:0;transform:translateY(16px)}to{opacity:1;transform:translateY(0)}}@keyframes chatbot-typing{0%,60%,to{transform:translateY(0);opacity:.4}30%{transform:translateY(-4px);opacity:1}}:host-context(.app-dark) .chatbot-window{background:var(--p-surface-100, #1e1e1e)}:host-context(.app-dark) .chatbot-messages{background:var(--p-surface-100, #1e1e1e)}:host-context(.app-dark) .chatbot-welcome p{color:var(--p-surface-500, #adb5bd)}:host-context(.app-dark) .chatbot-message.assistant-message .message-bubble{background:var(--p-surface-200, #2d2d2d);color:var(--p-surface-900, #e0e0e0)}:host-context(.app-dark) .chatbot-input-area{background:var(--p-surface-100, #1e1e1e);border-top-color:var(--p-surface-300, #3d3d3d)}:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content code{background:#ffffff1a}:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content pre{background:#ffffff14}:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content blockquote{border-left-color:#fff3}:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content hr{border-top-color:#ffffff26}@media (max-width: 480px){.chatbot-window{width:calc(100vw - 2rem);height:calc(100vh - 8rem);right:1rem;bottom:5rem}.chatbot-fab{bottom:1rem;right:1rem}}\n"] }]
186
+ ], animations: [
187
+ trigger('chatbotPhraseFade', [
188
+ transition('* => *', [
189
+ style({ opacity: 0, transform: 'translateY(2px)' }),
190
+ animate('220ms ease-out', style({ opacity: 1, transform: 'translateY(0)' }))
191
+ ])
192
+ ])
193
+ ], template: "<!-- Floating Action Button -->\n<button type=\"button\" class=\"chatbot-fab\" [class.open]=\"isOpen\"\n [attr.aria-label]=\"'crmx.components.chatbot_title' | translate\"\n [attr.aria-expanded]=\"isOpen\"\n (click)=\"toggleChat()\">\n <i *ngIf=\"!isOpen\" class=\"pi pi-lightbulb fab-icon\"></i>\n <i *ngIf=\"isOpen\" class=\"pi pi-times\"></i>\n <span class=\"unread-badge\" *ngIf=\"unreadCount > 0 && !isOpen\">{{ unreadCount }}</span>\n</button>\n\n<!-- Chat Window -->\n<div class=\"chatbot-window\" *ngIf=\"isOpen\">\n <div class=\"chatbot-header\">\n <i class=\"pi pi-lightbulb header-icon\"></i>\n <span>{{ 'crmx.components.chatbot_title' | translate }}</span>\n </div>\n\n <div class=\"chatbot-messages\" #chatMessagesContainer>\n <!-- Welcome -->\n <div class=\"chatbot-welcome\" *ngIf=\"chatMessages.length === 0\">\n <i class=\"pi pi-lightbulb welcome-icon\"></i>\n <p>{{ 'crmx.components.chatbot_welcome' | translate }}</p>\n </div>\n\n <!-- Messages -->\n <div *ngFor=\"let msg of chatMessages\" class=\"chatbot-message\"\n [ngClass]=\"{ 'user-message': msg.role === 'user', 'assistant-message': msg.role === 'assistant' }\">\n <div class=\"message-avatar\">\n <i *ngIf=\"msg.role === 'user'\" class=\"pi pi-user\"></i>\n <i *ngIf=\"msg.role === 'assistant'\" class=\"pi pi-lightbulb assistant-avatar-icon\"></i>\n </div>\n <div class=\"message-bubble\" [class.markdown-content]=\"msg.role === 'assistant'\">\n <p *ngIf=\"msg.role === 'user'\">{{ msg.content }}</p>\n <div *ngIf=\"msg.role === 'assistant'\" [innerHTML]=\"msg.content | sChatbotMarkdown\"></div>\n <div class=\"message-meta\">\n <span class=\"message-time\">{{ msg.timestamp | date:'HH:mm' }}</span>\n <span class=\"response-time\" *ngIf=\"msg.responseTime\">\u23F1 {{ msg.responseTime }}s</span>\n </div>\n </div>\n </div>\n\n <!-- Typing indicator -->\n <div class=\"chatbot-typing\" *ngIf=\"sendingMessage\">\n <div class=\"message-avatar\"><i class=\"pi pi-lightbulb assistant-avatar-icon\"></i></div>\n <div class=\"typing-bubble\" aria-live=\"polite\">\n <span class=\"typing-phrase\" [@chatbotPhraseFade]=\"typingPhraseKey\">{{ typingPhraseKey | translate }}</span>\n <span class=\"typing-pulse\" aria-hidden=\"true\">\n <span></span><span></span><span></span>\n </span>\n </div>\n </div>\n </div>\n\n <div class=\"chatbot-input-area\">\n <div class=\"input-row\">\n <label for=\"s-chatbot-input\" class=\"sr-only\">{{ 'crmx.components.chatbot_placeholder' | translate }}</label>\n <textarea pTextarea id=\"s-chatbot-input\" [(ngModel)]=\"userInput\"\n [placeholder]=\"'crmx.components.chatbot_placeholder' | translate\"\n [autoResize]=\"true\" [rows]=\"1\" [maxlength]=\"2000\"\n (keydown)=\"onChatKeydown($event)\" [disabled]=\"sendingMessage\"></textarea>\n <button pButton type=\"button\" class=\"p-button-rounded send-btn\"\n [attr.aria-label]=\"'crmx.components.chatbot_placeholder' | translate\"\n [disabled]=\"!userInput.trim() || sendingMessage\"\n (click)=\"sendMessage()\">\n <i class=\"pi pi-send\"></i>\n </button>\n </div>\n </div>\n</div>\n", styles: [".sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.chatbot-fab{position:fixed;bottom:1.5rem;right:1.5rem;width:56px;height:56px;border:0;padding:0;border-radius:50%;background:var(--p-primary-color, #667eea);color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 4px 12px #00000040;z-index:1100;transition:transform .2s ease,background .2s ease;font:inherit}.chatbot-fab:hover{transform:scale(1.08)}.chatbot-fab:focus-visible{outline:2px solid var(--p-primary-color, #667eea);outline-offset:2px}.chatbot-fab.open{background:var(--p-surface-500, #6c757d)}.chatbot-fab .pi-times{font-size:1.25rem}.chatbot-fab .fab-icon{font-size:1.5rem}.chatbot-fab .unread-badge{position:absolute;top:-4px;right:-4px;min-width:20px;height:20px;border-radius:10px;background:#ef4444;color:#fff;font-size:.7rem;font-weight:700;display:flex;align-items:center;justify-content:center;padding:0 5px;box-shadow:0 2px 4px #0003}.chatbot-window{position:fixed;bottom:6.5rem;right:1.5rem;width:380px;height:520px;background:#fff;border-radius:12px;box-shadow:0 8px 32px #0000002e;z-index:1100;display:flex;flex-direction:column;overflow:hidden;animation:chatbot-slide-up .25s ease-out}.chatbot-header{display:flex;align-items:center;gap:.5rem;padding:.75rem 1rem;background:var(--p-primary-color, #667eea);color:#fff;font-weight:600;font-size:.9rem;flex-shrink:0}.chatbot-header .header-icon{font-size:1.1rem}.chatbot-messages{flex:1;overflow-y:auto;padding:1rem;display:flex;flex-direction:column;gap:.75rem}.chatbot-welcome{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;color:#adb5bd;text-align:center;padding:2rem}.chatbot-welcome .welcome-icon{font-size:2.5rem;color:var(--p-primary-color, #667eea);opacity:.7}.chatbot-welcome p{font-size:.9rem;color:#6c757d;margin:.75rem 0 0;line-height:1.5}.chatbot-message{display:flex;gap:.5rem;max-width:90%;align-items:flex-end}.message-avatar{width:26px;height:26px;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0}.message-avatar .assistant-avatar-icon{font-size:1rem;color:var(--p-primary-color, #667eea)}.message-bubble{padding:.6rem .85rem;font-size:.85rem;line-height:1.4}.message-bubble p{margin:0;white-space:pre-wrap;word-break:break-word}.message-bubble .response-time{opacity:.7}.message-bubble .message-meta{display:flex;justify-content:flex-start;align-items:center;gap:.5rem;margin-top:.25rem;font-size:.7rem}.chatbot-message.assistant-message{align-self:flex-start}.chatbot-message.assistant-message .message-bubble{background:#f1f3f5;color:#2c3e50;border-radius:12px 12px 12px 0}.chatbot-message.assistant-message .message-bubble .message-time{color:#adb5bd}.chatbot-message.user-message{align-self:flex-end;flex-direction:row-reverse}.chatbot-message.user-message .message-avatar{background:var(--p-primary-color, #667eea);color:#fff}.chatbot-message.user-message .message-bubble{background:var(--p-primary-color, #667eea);color:#fff;border-radius:12px 12px 0}.chatbot-message.user-message .message-bubble .message-meta{justify-content:flex-end}.chatbot-message.user-message .message-bubble .message-time{color:#ffffffb3}.chatbot-typing{display:flex;gap:.5rem;align-self:flex-start;align-items:flex-end}.chatbot-typing .typing-bubble{display:flex;align-items:center;gap:.5rem;padding:.55rem .85rem;background:#f1f3f5;color:#495057;border-radius:12px 12px 12px 0;font-size:.85rem;line-height:1.3;max-width:240px}.chatbot-typing .typing-phrase{display:inline-block}.chatbot-typing .typing-pulse{display:inline-flex;gap:3px;flex-shrink:0}.chatbot-typing .typing-pulse span{width:4px;height:4px;border-radius:50%;background:#adb5bd;animation:chatbot-typing 1.4s infinite}.chatbot-typing .typing-pulse span:nth-child(2){animation-delay:.2s}.chatbot-typing .typing-pulse span:nth-child(3){animation-delay:.4s}.chatbot-input-area{display:flex;flex-direction:column;gap:.5rem;padding:.75rem;border-top:1px solid #e9ecef;background:#fff;flex-shrink:0}.chatbot-input-area .input-row{display:flex;align-items:flex-end;gap:.5rem}.chatbot-input-area textarea{flex:1;resize:none;border-radius:8px;font-size:.85rem;max-height:100px}.chatbot-input-area .send-btn{flex-shrink:0;width:36px;height:36px;align-self:center}:host ::ng-deep .message-bubble.markdown-content{overflow-x:auto}:host ::ng-deep .message-bubble.markdown-content>*{margin-top:0;margin-bottom:0}:host ::ng-deep .message-bubble.markdown-content>*+*{margin-top:.4rem}:host ::ng-deep .message-bubble.markdown-content a{color:var(--p-primary-color, #667eea);text-decoration:underline}:host ::ng-deep .message-bubble.markdown-content strong{font-weight:600}:host ::ng-deep .message-bubble.markdown-content hr{border:0;border-top:1px solid rgba(0,0,0,.12);margin:.5rem 0}:host ::ng-deep .message-bubble.markdown-content code{background:#00000014;padding:.1rem .3rem;border-radius:3px;font-size:.8rem;font-family:Courier New,monospace}:host ::ng-deep .message-bubble.markdown-content pre{background:#0000000f;padding:.5rem;border-radius:6px;overflow-x:auto;font-size:.8rem}:host ::ng-deep .message-bubble.markdown-content pre code{background:none;padding:0}:host ::ng-deep .message-bubble.markdown-content blockquote{border-left:3px solid rgba(0,0,0,.15);padding-left:.6rem;opacity:.85}:host ::ng-deep .message-bubble.markdown-content ul,:host ::ng-deep .message-bubble.markdown-content ol{padding-left:1.2rem}:host ::ng-deep .message-bubble.markdown-content li{margin-bottom:.15rem}:host ::ng-deep .message-bubble.markdown-content h1,:host ::ng-deep .message-bubble.markdown-content h2,:host ::ng-deep .message-bubble.markdown-content h3,:host ::ng-deep .message-bubble.markdown-content h4,:host ::ng-deep .message-bubble.markdown-content h5,:host ::ng-deep .message-bubble.markdown-content h6{font-weight:600;line-height:1.3}:host ::ng-deep .message-bubble.markdown-content h1{font-size:1.1rem}:host ::ng-deep .message-bubble.markdown-content h2{font-size:1rem}:host ::ng-deep .message-bubble.markdown-content h3{font-size:.95rem}:host ::ng-deep .message-bubble.markdown-content table{border-collapse:collapse;width:100%;font-size:.8rem;margin:.4rem 0}:host ::ng-deep .message-bubble.markdown-content table th,:host ::ng-deep .message-bubble.markdown-content table td{border:1px solid rgba(0,0,0,.2);padding:.3rem .5rem;text-align:left;vertical-align:top}:host ::ng-deep .message-bubble.markdown-content table th{font-weight:600;background:#0000000d}:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content table th,:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content table td{border-color:#fff3}:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content table th{background:#ffffff14}:host ::ng-deep .message-bubble.markdown-content table tbody tr:nth-child(2n) td{background:#00000005}:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content table tbody tr:nth-child(2n) td{background:#ffffff08}@keyframes chatbot-slide-up{0%{opacity:0;transform:translateY(16px)}to{opacity:1;transform:translateY(0)}}@keyframes chatbot-typing{0%,60%,to{transform:translateY(0);opacity:.4}30%{transform:translateY(-4px);opacity:1}}:host-context(.app-dark) .chatbot-window{background:var(--p-surface-100, #1e1e1e)}:host-context(.app-dark) .chatbot-messages{background:var(--p-surface-100, #1e1e1e)}:host-context(.app-dark) .chatbot-welcome p{color:var(--p-surface-500, #adb5bd)}:host-context(.app-dark) .chatbot-message.assistant-message .message-bubble{background:var(--p-surface-200, #2d2d2d);color:var(--p-surface-900, #e0e0e0)}:host-context(.app-dark) .chatbot-input-area{background:var(--p-surface-100, #1e1e1e);border-top-color:var(--p-surface-300, #3d3d3d)}:host-context(.app-dark) .chatbot-typing .typing-bubble{background:var(--p-surface-200, #2d2d2d);color:var(--p-surface-900, #e0e0e0)}:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content code{background:#ffffff1a}:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content pre{background:#ffffff14}:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content blockquote{border-left-color:#fff3}:host-context(.app-dark) ::ng-deep .message-bubble.markdown-content hr{border-top-color:#ffffff26}@media (max-width: 480px){.chatbot-window{width:calc(100vw - 2rem);height:calc(100vh - 8rem);right:1rem;bottom:5rem}.chatbot-fab{bottom:1rem;right:1rem}}\n"] }]
136
194
  }], propDecorators: { chatMessagesContainer: [{
137
195
  type: ViewChild,
138
196
  args: ['chatMessagesContainer']
139
197
  }] } });
140
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhdGJvdC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLWNvbXBvbmVudHMvc3JjL2xpYi9jb21wb25lbnRzL2NoYXRib3QvY2hhdGJvdC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLWNvbXBvbmVudHMvc3JjL2xpYi9jb21wb25lbnRzL2NoYXRib3QvY2hhdGJvdC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFjLE1BQU0sRUFBcUIsU0FBUyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNwRyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRzdDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM1QyxPQUFPLEVBQUUsYUFBYSxFQUFFLGtCQUFrQixFQUFtQixnQkFBZ0IsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRXJILE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQzs7Ozs7QUFpQjVEOzs7R0FHRztBQUNILE1BQU0seUJBQXlCLEdBQUcsRUFBRSxDQUFDO0FBRXJDOzs7Ozs7O0dBT0c7QUFnQkgsTUFBTSxPQUFPLGdCQUFnQjtJQUMwQixxQkFBcUIsQ0FBMkI7SUFFckcsTUFBTSxHQUFHLEtBQUssQ0FBQztJQUNmLFNBQVMsR0FBRyxFQUFFLENBQUM7SUFDZixjQUFjLEdBQUcsS0FB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RUFBRSx5QkFBeUIsQ0FBQyxDQUFDO0lBQ2hDLENBQUM7d0dBL0dVLGdCQUFnQjs0RkFBaEIsZ0JBQWdCLHFNQ3pEN0IsdWxHQWdFQSxxK1BEbEJJLFlBQVksZ1pBQ1osV0FBVyxpeEJBQ1gsWUFBWSxxUUFDWixRQUFRLG1JQUNSLFdBQVcsMEJBQ1gsYUFBYSw2Q0FDYixtQkFBbUI7OzRGQUtWLGdCQUFnQjtrQkFmNUIsU0FBUzsrQkFDRSxXQUFXLGNBQ1QsSUFBSSxXQUNQO3dCQUNQLFlBQVk7d0JBQ1osV0FBVzt3QkFDWCxZQUFZO3dCQUNaLFFBQVE7d0JBQ1IsV0FBVzt3QkFDWCxhQUFhO3dCQUNiLG1CQUFtQjtxQkFDcEI7OEJBS29ELHFCQUFxQjtzQkFBekUsU0FBUzt1QkFBQyx1QkFBdUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEVsZW1lbnRSZWYsIE5nWm9uZSwgT25EZXN0cm95LCBPbkluaXQsIFZpZXdDaGlsZCwgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgQnV0dG9uTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9idXR0b24nO1xuaW1wb3J0IHsgVGV4dGFyZWEgfSBmcm9tICdwcmltZW5nL3RleHRhcmVhJztcbmltcG9ydCB7IEJhZGdlTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9iYWRnZSc7XG5pbXBvcnQgeyBUcmFuc2xhdGVQaXBlLCBUcmFuc2xhdGlvblNlcnZpY2UsIFdlYlNvY2tldENvbmZpZywgV2ViU29ja2V0U2VydmljZSB9IGZyb20gJ0BzZW5pb3JzaXN0ZW1hcy9jb21wb25lbnRzLWFpJztcblxuaW1wb3J0IHsgQ2hhdGJvdFNlcnZpY2UgfSBmcm9tICcuL3NlcnZpY2VzL2NoYXRib3Quc2VydmljZSc7XG5pbXBvcnQgeyBDaGF0Ym90TWFya2Rvd25QaXBlIH0gZnJvbSAnLi9waXBlcy9tYXJrZG93bi5waXBlJztcblxuZXhwb3J0IGludGVyZmFjZSBDaGF0Ym90TWVzc2FnZSB7XG4gIHJvbGU6ICd1c2VyJyB8ICdhc3Npc3RhbnQnO1xuICBjb250ZW50OiBzdHJpbmc7XG4gIHRpbWVzdGFtcDogRGF0ZTtcbiAgcmVzcG9uc2VUaW1lPzogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgQ2hhdGJvdFdzUGF5bG9hZCB7XG4gIGRhdGE6IHtcbiAgICByZXNwb25zZTogc3RyaW5nO1xuICAgIHJlc3BvbnNlVGltZTogbnVtYmVyO1xuICAgIGNoYXRJZDogc3RyaW5nO1xuICB9O1xufVxuXG4vKipcbiAqIERlbGF5IChtcykgdXNlZCBiZWZvcmUgc2Nyb2xsaW5nIHRoZSBjaGF0IGNvbnRhaW5lciB0byB0aGUgYm90dG9tLlxuICogR2l2ZXMgQW5ndWxhciB0aW1lIHRvIHJlbmRlciB0aGUgbmV3bHkgcHVzaGVkIG1lc3NhZ2UgaW50byB0aGUgRE9NLlxuICovXG5jb25zdCBTQ1JPTExfVE9fQk9UVE9NX0RFTEFZX01TID0gNTA7XG5cbi8qKlxuICogQ2hhdGJvdCBnbG9iYWwgZG8gQ1JNLlxuICpcbiAqIFN0YW5kYWxvbmUsIHBsdWctYW5kLXBsYXk6IGJhc3RhIGRlY2xhcmFyIGA8cy1jaGF0Ym90Pjwvcy1jaGF0Ym90PmAgbm9cbiAqIGBhcHAuY29tcG9uZW50Lmh0bWxgIGRhIGFwbGljYcOnw6NvIGNvbnN1bWlkb3JhLiBUb2RhIGEgaW50ZWdyYcOnw6NvXG4gKiAoV2ViU29ja2V0IGRlIHJlc3Bvc3RhcywgUkVTVCBkZSBlbnZpbywgdHJhZHXDp8O1ZXMgZSByZW5kZXJpemHDp8OjbyBkZVxuICogTWFya2Rvd24pIGVzdMOhIGVuY2Fwc3VsYWRhIG5hIGJpYmxpb3RlY2EuXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3MtY2hhdGJvdCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBDb21tb25Nb2R1bGUsXG4gICAgRm9ybXNNb2R1bGUsXG4gICAgQnV0dG9uTW9kdWxlLFxuICAgIFRleHRhcmVhLFxuICAgIEJhZGdlTW9kdWxlLFxuICAgIFRyYW5zbGF0ZVBpcGUsXG4gICAgQ2hhdGJvdE1hcmtkb3duUGlwZVxuICBdLFxuICB0ZW1wbGF0ZVVybDogJy4vY2hhdGJvdC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsOiAnLi9jaGF0Ym90LmNvbXBvbmVudC5zY3NzJ1xufSlcbmV4cG9ydCBjbGFzcyBDaGF0Ym90Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICBAVmlld0NoaWxkKCdjaGF0TWVzc2FnZXNDb250YWluZXInKSBwcml2YXRlIHJlYWRvbmx5IGNoYXRNZXNzYWdlc0NvbnRhaW5lciE6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+O1xuXG4gIGlzT3BlbiA9IGZhbHNlO1xuICB1c2VySW5wdXQgPSAnJztcbiAgc2VuZGluZ01lc3NhZ2UgPSBmYWxzZTtcbiAgY2hhdE1lc3NhZ2VzOiBDaGF0Ym90TWVzc2FnZVtdID0gW107XG4gIGNoYXRJZDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIHVucmVhZENvdW50ID0gMDtcblxuICBwcml2YXRlIHdzU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb24gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSByZWFkb25seSB3c0NvbmZpZzogV2ViU29ja2V0Q29uZmlnID0ge1xuICAgIGRvbWFpbjogJ2NybXgnLFxuICAgIHNlcnZpY2U6ICdjaGF0Ym90JyxcbiAgICBwcmltaXRpdmU6ICd3c0NoYXRSZXNwb25zZScsXG4gICAgdXNlclNjb3BlZDogdHJ1ZVxuICB9O1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgd2ViU29ja2V0U2VydmljZSA9IGluamVjdChXZWJTb2NrZXRTZXJ2aWNlKTtcbiAgcHJpdmF0ZSByZWFkb25seSBuZ1pvbmUgPSBpbmplY3QoTmdab25lKTtcbiAgcHJpdmF0ZSByZWFkb25seSBjaGF0Ym90U2VydmljZSA9IGluamVjdChDaGF0Ym90U2VydmljZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgdHJhbnNsYXRpb25TZXJ2aWNlID0gaW5qZWN0KFRyYW5zbGF0aW9uU2VydmljZSk7XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5zdWJzY3JpYmVUb1dlYlNvY2tldCgpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy53c1N1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLndlYlNvY2tldFNlcnZpY2UudW5zdWJzY3JpYmUodGhpcy53c0NvbmZpZyk7XG4gICAgdGhpcy53ZWJTb2NrZXRTZXJ2aWNlLmRpc2Nvbm5lY3QoKTtcbiAgfVxuXG4gIHRvZ2dsZUNoYXQoKTogdm9pZCB7XG4gICAgdGhpcy5pc09wZW4gPSAhdGhpcy5pc09wZW47XG4gICAgaWYgKHRoaXMuaXNPcGVuKSB7XG4gICAgICB0aGlzLnVucmVhZENvdW50ID0gMDtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5zY3JvbGxDaGF0VG9Cb3R0b20oKSwgMTAwKTtcbiAgICB9XG4gIH1cblxuICBzZW5kTWVzc2FnZSgpOiB2b2lkIHtcbiAgICBjb25zdCB0ZXh0ID0gdGhpcy51c2VySW5wdXQudHJpbSgpO1xuICAgIGlmICghdGV4dCB8fCB0aGlzLnNlbmRpbmdNZXNzYWdlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5jaGF0TWVzc2FnZXMucHVzaCh7IHJvbGU6ICd1c2VyJywgY29udGVudDogdGV4dCwgdGltZXN0YW1wOiBuZXcgRGF0ZSgpIH0pO1xuICAgIHRoaXMudXNlcklucHV0ID0gJyc7XG4gICAgdGhpcy5zZW5kaW5nTWVzc2FnZSA9IHRydWU7XG4gICAgdGhpcy5zY3JvbGxDaGF0VG9Cb3R0b20oKTtcblxuICAgIHRoaXMuY2hhdGJvdFNlcnZpY2UuY2hhdCh0ZXh0LCB0aGlzLmNoYXRJZCA/PyB1bmRlZmluZWQpLnN1YnNjcmliZSh7XG4gICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICB0aGlzLmNoYXRNZXNzYWdlcy5wdXNoKHtcbiAgICAgICAgICByb2xlOiAnYXNzaXN0YW50JyxcbiAgICAgICAgICBjb250ZW50OiB0aGlzLnRyYW5zbGF0aW9uU2VydmljZS50cmFuc2xhdGUoJ2NybXguY29tcG9uZW50cy5jaGF0Ym90X2Vycm9yJyksXG4gICAgICAgICAgdGltZXN0YW1wOiBuZXcgRGF0ZSgpXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnNlbmRpbmdNZXNzYWdlID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc2Nyb2xsQ2hhdFRvQm90dG9tKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBvbkNoYXRLZXlkb3duKGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKGV2ZW50LmtleSA9PT0gJ0VudGVyJyAmJiAhZXZlbnQuc2hpZnRLZXkpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB0aGlzLnNlbmRNZXNzYWdlKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzdWJzY3JpYmVUb1dlYlNvY2tldCgpOiB2b2lkIHtcbiAgICB0aGlzLndzU3Vic2NyaXB0aW9uID0gdGhpcy53ZWJTb2NrZXRTZXJ2aWNlXG4gICAgICAuc3Vic2NyaWJlPENoYXRib3RXc1BheWxvYWQ+KHRoaXMud3NDb25maWcpXG4gICAgICAuc3Vic2NyaWJlKG1zZyA9PiB7XG4gICAgICAgIGNvbnN0IGRhdGEgPSBtc2cuYm9keS5kYXRhO1xuICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgIGlmICghZGF0YSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChkYXRhLmNoYXRJZCkge1xuICAgICAgICAgICAgdGhpcy5jaGF0SWQgPSBkYXRhLmNoYXRJZDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLmNoYXRNZXNzYWdlcy5wdXNoKHtcbiAgICAgICAgICAgIHJvbGU6ICdhc3Npc3RhbnQnLFxuICAgICAgICAgICAgY29udGVudDogZGF0YS5yZXNwb25zZSxcbiAgICAgICAgICAgIHRpbWVzdGFtcDogbmV3IERhdGUoKSxcbiAgICAgICAgICAgIHJlc3BvbnNlVGltZTogZGF0YS5yZXNwb25zZVRpbWVcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHRoaXMuc2VuZGluZ01lc3NhZ2UgPSBmYWxzZTtcblxuICAgICAgICAgIGlmICghdGhpcy5pc09wZW4pIHtcbiAgICAgICAgICAgIHRoaXMudW5yZWFkQ291bnQrKztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLnNjcm9sbENoYXRUb0JvdHRvbSgpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzY3JvbGxDaGF0VG9Cb3R0b20oKTogdm9pZCB7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBjb25zdCBlbCA9IHRoaXMuY2hhdE1lc3NhZ2VzQ29udGFpbmVyPy5uYXRpdmVFbGVtZW50O1xuICAgICAgaWYgKGVsKSB7XG4gICAgICAgIGVsLnNjcm9sbFRvcCA9IGVsLnNjcm9sbEhlaWdodDtcbiAgICAgIH1cbiAgICB9LCBTQ1JPTExfVE9fQk9UVE9NX0RFTEFZX01TKTtcbiAgfVxufVxuIiwiPCEtLSBGbG9hdGluZyBBY3Rpb24gQnV0dG9uIC0tPlxuPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJjaGF0Ym90LWZhYlwiIFtjbGFzcy5vcGVuXT1cImlzT3BlblwiXG4gICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiJ2NybXguY29tcG9uZW50cy5jaGF0Ym90X3RpdGxlJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgIFthdHRyLmFyaWEtZXhwYW5kZWRdPVwiaXNPcGVuXCJcbiAgICAgICAgKGNsaWNrKT1cInRvZ2dsZUNoYXQoKVwiPlxuICA8aSAqbmdJZj1cIiFpc09wZW5cIiBjbGFzcz1cInBpIHBpLWxpZ2h0YnVsYiBmYWItaWNvblwiPjwvaT5cbiAgPGkgKm5nSWY9XCJpc09wZW5cIiBjbGFzcz1cInBpIHBpLXRpbWVzXCI+PC9pPlxuICA8c3BhbiBjbGFzcz1cInVucmVhZC1iYWRnZVwiICpuZ0lmPVwidW5yZWFkQ291bnQgPiAwICYmICFpc09wZW5cIj57eyB1bnJlYWRDb3VudCB9fTwvc3Bhbj5cbjwvYnV0dG9uPlxuXG48IS0tIENoYXQgV2luZG93IC0tPlxuPGRpdiBjbGFzcz1cImNoYXRib3Qtd2luZG93XCIgKm5nSWY9XCJpc09wZW5cIj5cbiAgPGRpdiBjbGFzcz1cImNoYXRib3QtaGVhZGVyXCI+XG4gICAgPGkgY2xhc3M9XCJwaSBwaS1saWdodGJ1bGIgaGVhZGVyLWljb25cIj48L2k+XG4gICAgPHNwYW4+e3sgJ2NybXguY29tcG9uZW50cy5jaGF0Ym90X3RpdGxlJyB8IHRyYW5zbGF0ZSB9fTwvc3Bhbj5cbiAgPC9kaXY+XG5cbiAgPGRpdiBjbGFzcz1cImNoYXRib3QtbWVzc2FnZXNcIiAjY2hhdE1lc3NhZ2VzQ29udGFpbmVyPlxuICAgIDwhLS0gV2VsY29tZSAtLT5cbiAgICA8ZGl2IGNsYXNzPVwiY2hhdGJvdC13ZWxjb21lXCIgKm5nSWY9XCJjaGF0TWVzc2FnZXMubGVuZ3RoID09PSAwXCI+XG4gICAgICA8aSBjbGFzcz1cInBpIHBpLWxpZ2h0YnVsYiB3ZWxjb21lLWljb25cIj48L2k+XG4gICAgICA8cD57eyAnY3JteC5jb21wb25lbnRzLmNoYXRib3Rfd2VsY29tZScgfCB0cmFuc2xhdGUgfX08L3A+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIE1lc3NhZ2VzIC0tPlxuICAgIDxkaXYgKm5nRm9yPVwibGV0IG1zZyBvZiBjaGF0TWVzc2FnZXNcIiBjbGFzcz1cImNoYXRib3QtbWVzc2FnZVwiXG4gICAgICAgICBbbmdDbGFzc109XCJ7ICd1c2VyLW1lc3NhZ2UnOiBtc2cucm9sZSA9PT0gJ3VzZXInLCAnYXNzaXN0YW50LW1lc3NhZ2UnOiBtc2cucm9sZSA9PT0gJ2Fzc2lzdGFudCcgfVwiPlxuICAgICAgPGRpdiBjbGFzcz1cIm1lc3NhZ2UtYXZhdGFyXCI+XG4gICAgICAgIDxpICpuZ0lmPVwibXNnLnJvbGUgPT09ICd1c2VyJ1wiIGNsYXNzPVwicGkgcGktdXNlclwiPjwvaT5cbiAgICAgICAgPGkgKm5nSWY9XCJtc2cucm9sZSA9PT0gJ2Fzc2lzdGFudCdcIiBjbGFzcz1cInBpIHBpLWxpZ2h0YnVsYiBhc3Npc3RhbnQtYXZhdGFyLWljb25cIj48L2k+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJtZXNzYWdlLWJ1YmJsZVwiIFtjbGFzcy5tYXJrZG93bi1jb250ZW50XT1cIm1zZy5yb2xlID09PSAnYXNzaXN0YW50J1wiPlxuICAgICAgICA8cCAqbmdJZj1cIm1zZy5yb2xlID09PSAndXNlcidcIj57eyBtc2cuY29udGVudCB9fTwvcD5cbiAgICAgICAgPGRpdiAqbmdJZj1cIm1zZy5yb2xlID09PSAnYXNzaXN0YW50J1wiIFtpbm5lckhUTUxdPVwibXNnLmNvbnRlbnQgfCBzQ2hhdGJvdE1hcmtkb3duXCI+PC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJtZXNzYWdlLW1ldGFcIj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1lc3NhZ2UtdGltZVwiPnt7IG1zZy50aW1lc3RhbXAgfCBkYXRlOidISDptbScgfX08L3NwYW4+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJyZXNwb25zZS10aW1lXCIgKm5nSWY9XCJtc2cucmVzcG9uc2VUaW1lXCI+4o+xIHt7IG1zZy5yZXNwb25zZVRpbWUgfX1zPC9zcGFuPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBUeXBpbmcgaW5kaWNhdG9yIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJjaGF0Ym90LXR5cGluZ1wiICpuZ0lmPVwic2VuZGluZ01lc3NhZ2VcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJtZXNzYWdlLWF2YXRhclwiPjxpIGNsYXNzPVwicGkgcGktbGlnaHRidWxiIGFzc2lzdGFudC1hdmF0YXItaWNvblwiPjwvaT48L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJ0eXBpbmctaW5kaWNhdG9yXCI+PHNwYW4+PC9zcGFuPjxzcGFuPjwvc3Bhbj48c3Bhbj48L3NwYW4+PC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuXG4gIDxkaXYgY2xhc3M9XCJjaGF0Ym90LWlucHV0LWFyZWFcIj5cbiAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtcm93XCI+XG4gICAgICA8bGFiZWwgZm9yPVwicy1jaGF0Ym90LWlucHV0XCIgY2xhc3M9XCJzci1vbmx5XCI+e3sgJ2NybXguY29tcG9uZW50cy5jaGF0Ym90X3BsYWNlaG9sZGVyJyB8IHRyYW5zbGF0ZSB9fTwvbGFiZWw+XG4gICAgICA8dGV4dGFyZWEgcFRleHRhcmVhIGlkPVwicy1jaGF0Ym90LWlucHV0XCIgWyhuZ01vZGVsKV09XCJ1c2VySW5wdXRcIlxuICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCInY3JteC5jb21wb25lbnRzLmNoYXRib3RfcGxhY2Vob2xkZXInIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICBbYXV0b1Jlc2l6ZV09XCJ0cnVlXCIgW3Jvd3NdPVwiMVwiIFttYXhsZW5ndGhdPVwiMjAwMFwiXG4gICAgICAgICAgICAgICAgKGtleWRvd24pPVwib25DaGF0S2V5ZG93bigkZXZlbnQpXCIgW2Rpc2FibGVkXT1cInNlbmRpbmdNZXNzYWdlXCI+PC90ZXh0YXJlYT5cbiAgICAgIDxidXR0b24gcEJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJwLWJ1dHRvbi1yb3VuZGVkIHNlbmQtYnRuXCJcbiAgICAgICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCInY3JteC5jb21wb25lbnRzLmNoYXRib3RfcGxhY2Vob2xkZXInIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgW2xvYWRpbmddPVwic2VuZGluZ01lc3NhZ2VcIiBbZGlzYWJsZWRdPVwiIXVzZXJJbnB1dC50cmltKCkgfHwgc2VuZGluZ01lc3NhZ2VcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwic2VuZE1lc3NhZ2UoKVwiPlxuICAgICAgICA8aSBjbGFzcz1cInBpIHBpLXNlbmRcIj48L2k+XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==
198
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhdGJvdC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLWNvbXBvbmVudHMvc3JjL2xpYi9jb21wb25lbnRzL2NoYXRib3QvY2hhdGJvdC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLWNvbXBvbmVudHMvc3JjL2xpYi9jb21wb25lbnRzL2NoYXRib3QvY2hhdGJvdC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFjLE1BQU0sRUFBcUIsU0FBUyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNwRyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxPQUFPLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUcxRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDOUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQzVDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDNUMsT0FBTyxFQUFFLGFBQWEsRUFBRSxrQkFBa0IsRUFBbUIsZ0JBQWdCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUVySCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDNUQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7Ozs7O0FBaUI1RDs7O0dBR0c7QUFDSCxNQUFNLHlCQUF5QixHQUFHLEVBQUUsQ0FBQztBQUVyQzs7R0FFRztBQUNILE1BQU0seUJBQXlCLEdBQUcsSUFBSSxDQUFDO0FBRXZDOzs7R0FHRztBQUNILE1BQU0sa0JBQWtCLEdBQXNCO0lBQzVDLGtDQUFrQztJQUNsQyxrQ0FBa0M7SUFDbEMsa0NBQWtDO0lBQ2xDLGtDQUFrQztJQUNsQyxrQ0FBa0M7Q0FDbkMsQ0FBQztBQUVGOzs7Ozs7O0dBT0c7QUF3QkgsTUFBTSxPQUFPLGdCQUFnQjtJQUMwQixxQkFBcUIsQ0FBMkI7SUFFckcsTUFBTSxHQUFHLEtBQUssQ0FBQztJQUNmLFNBQVMsR0FBRyxFQUFFLENBQUM7SUFDZixjQUFjLEdBQUcsS0FBSyxDQUFDO0lBQ3ZCLFlBQVksR0FBcUIsRUFBRSxDQUFDO0lBQ3BDLE1BQU0sR0FBa0IsSUFBSSxDQUFDO0lBQzdCLFdBQVcsR0FBRyxDQUFDLENBQUM7SUFDaEIsZUFBZSxHQUFXLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRXhDLGNBQWMsR0FBd0IsSUFBSSxDQUFDO0lBQzNDLGlCQUFpQixHQUEwQyxJQUFJLENBQUM7SUFDaEUsaUJBQWlCLEdBQUcsQ0FBQyxDQUFDO0lBQ2IsUUFBUSxHQUFvQjtRQUMzQyxNQUFNLEVBQUUsTUFBTTtRQUNkLE9BQU8sRUFBRSxTQUFTO1FBQ2xCLFNBQVMsRUFBRSxnQkFBZ0I7UUFDM0IsVUFBVSxFQUFFLElBQUk7S0FDakIsQ0FBQztJQUVlLGdCQUFnQixHQUFHLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQzVDLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDeEIsY0FBYyxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUN4QyxrQkFBa0IsR0FBRyxNQUFNLENBQUMsa0JBQWtCLENBQUMsQ0FBQztJQUVqRSxRQUFRO1FBQ04sSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7SUFDOUIsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsY0FBYyxFQUFFLFdBQVcsRUFBRSxDQUFDO1FBQ25DLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ2pELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNuQyxJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztJQUNsQyxDQUFDO0lBRUQsVUFBVTtRQUNSLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQzNCLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2hCLElBQUksQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDO1lBQ3JCLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNuRCxDQUFDO0lBQ0gsQ0FBQztJQUVELFdBQVc7UUFDVCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ25DLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ2pDLE9BQU87UUFDVCxDQUFDO1FBRUQsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLElBQUksSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQy9FLElBQUksQ0FBQyxTQUFTLEdBQUcsRUFBRSxDQUFDO1FBQ3BCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDO1FBQzNCLElBQUksQ0FBQyx5QkFBeUIsRUFBRSxDQUFDO1FBQ2pDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBRTFCLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsTUFBTSxJQUFJLFNBQVMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztZQUNqRSxLQUFLLEVBQUUsR0FBRyxFQUFFO2dCQUNWLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDO29CQUNyQixJQUFJLEVBQUUsV0FBVztvQkFDakIsT0FBTyxFQUFFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsK0JBQStCLENBQUM7b0JBQzNFLFNBQVMsRUFBRSxJQUFJLElBQUksRUFBRTtpQkFDdEIsQ0FBQyxDQUFDO2dCQUNILElBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFDO2dCQUM1QixJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztnQkFDaEMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDNUIsQ0FBQztTQUNGLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxhQUFhLENBQUMsS0FBb0I7UUFDaEMsSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUM3QyxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDdkIsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3JCLENBQUM7SUFDSCxDQUFDO0lBRU8sb0JBQW9CO1FBQzFCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLGdCQUFnQjthQUN4QyxTQUFTLENBQW1CLElBQUksQ0FBQyxRQUFRLENBQUM7YUFDMUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxFQUFFO1lBQ2YsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDM0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFO2dCQUNuQixJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7b0JBQ1YsT0FBTztnQkFDVCxDQUFDO2dCQUVELElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO29CQUNoQixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7Z0JBQzVCLENBQUM7Z0JBRUQsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUM7b0JBQ3JCLElBQUksRUFBRSxXQUFXO29CQUNqQixPQUFPLEVBQUUsSUFBSSxDQUFDLFFBQVE7b0JBQ3RCLFNBQVMsRUFBRSxJQUFJLElBQUksRUFBRTtvQkFDckIsWUFBWSxFQUFFLElBQUksQ0FBQyxZQUFZO2lCQUNoQyxDQUFDLENBQUM7Z0JBRUgsSUFBSSxDQUFDLGNBQWMsR0FBRyxLQUFLLENBQUM7Z0JBQzVCLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO2dCQUVoQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO29CQUNqQixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBQ3JCLENBQUM7Z0JBRUQsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDNUIsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFTyxrQkFBa0I7UUFDeEIsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUNkLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxhQUFhLENBQUM7WUFDckQsSUFBSSxFQUFFLEVBQUUsQ0FBQztnQkFDUCxFQUFFLENBQUMsU0FBUyxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQUM7WUFDakMsQ0FBQztRQUNILENBQUMsRUFBRSx5QkFBeUIsQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFFRDs7O09BR0c7SUFDSyx5QkFBeUI7UUFDL0IsSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7UUFDaEMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLENBQUMsQ0FBQztRQUMzQixJQUFJLENBQUMsZUFBZSxHQUFHLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzdDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFFO1lBQ3hDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRTtnQkFDbkIsSUFBSSxDQUFDLGlCQUFpQixHQUFHLENBQUMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLENBQUMsQ0FBQyxHQUFHLGtCQUFrQixDQUFDLE1BQU0sQ0FBQztnQkFDbEYsSUFBSSxDQUFDLGVBQWUsR0FBRyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztZQUNwRSxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsRUFBRSx5QkFBeUIsQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFFTyx3QkFBd0I7UUFDOUIsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEtBQUssSUFBSSxFQUFFLENBQUM7WUFDcEMsYUFBYSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1lBQ3RDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUM7UUFDaEMsQ0FBQztJQUNILENBQUM7d0dBN0lVLGdCQUFnQjs0RkFBaEIsZ0JBQWdCLHFNQ25GN0Isc3lHQXFFQSxpMFFETEksWUFBWSxnWkFDWixXQUFXLGl4QkFDWCxZQUFZLHFRQUNaLFFBQVEsbUlBQ1IsV0FBVywwQkFDWCxhQUFhLDZDQUNiLG1CQUFtQiwyQ0FFVDtZQUNWLE9BQU8sQ0FBQyxtQkFBbUIsRUFBRTtnQkFDM0IsVUFBVSxDQUFDLFFBQVEsRUFBRTtvQkFDbkIsS0FBSyxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsRUFBRSxTQUFTLEVBQUUsaUJBQWlCLEVBQUUsQ0FBQztvQkFDbkQsT0FBTyxDQUFDLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsU0FBUyxFQUFFLGVBQWUsRUFBRSxDQUFDLENBQUM7aUJBQzdFLENBQUM7YUFDSCxDQUFDO1NBQ0g7OzRGQUlVLGdCQUFnQjtrQkF2QjVCLFNBQVM7K0JBQ0UsV0FBVyxjQUNULElBQUksV0FDUDt3QkFDUCxZQUFZO3dCQUNaLFdBQVc7d0JBQ1gsWUFBWTt3QkFDWixRQUFRO3dCQUNSLFdBQVc7d0JBQ1gsYUFBYTt3QkFDYixtQkFBbUI7cUJBQ3BCLGNBQ1c7d0JBQ1YsT0FBTyxDQUFDLG1CQUFtQixFQUFFOzRCQUMzQixVQUFVLENBQUMsUUFBUSxFQUFFO2dDQUNuQixLQUFLLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLFNBQVMsRUFBRSxpQkFBaUIsRUFBRSxDQUFDO2dDQUNuRCxPQUFPLENBQUMsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsRUFBRSxTQUFTLEVBQUUsZUFBZSxFQUFFLENBQUMsQ0FBQzs2QkFDN0UsQ0FBQzt5QkFDSCxDQUFDO3FCQUNIOzhCQUtvRCxxQkFBcUI7c0JBQXpFLFNBQVM7dUJBQUMsdUJBQXVCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBOZ1pvbmUsIE9uRGVzdHJveSwgT25Jbml0LCBWaWV3Q2hpbGQsIGluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgYW5pbWF0ZSwgc3R5bGUsIHRyYW5zaXRpb24sIHRyaWdnZXIgfSBmcm9tICdAYW5ndWxhci9hbmltYXRpb25zJztcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBCdXR0b25Nb2R1bGUgfSBmcm9tICdwcmltZW5nL2J1dHRvbic7XG5pbXBvcnQgeyBUZXh0YXJlYSB9IGZyb20gJ3ByaW1lbmcvdGV4dGFyZWEnO1xuaW1wb3J0IHsgQmFkZ2VNb2R1bGUgfSBmcm9tICdwcmltZW5nL2JhZGdlJztcbmltcG9ydCB7IFRyYW5zbGF0ZVBpcGUsIFRyYW5zbGF0aW9uU2VydmljZSwgV2ViU29ja2V0Q29uZmlnLCBXZWJTb2NrZXRTZXJ2aWNlIH0gZnJvbSAnQHNlbmlvcnNpc3RlbWFzL2NvbXBvbmVudHMtYWknO1xuXG5pbXBvcnQgeyBDaGF0Ym90U2VydmljZSB9IGZyb20gJy4vc2VydmljZXMvY2hhdGJvdC5zZXJ2aWNlJztcbmltcG9ydCB7IENoYXRib3RNYXJrZG93blBpcGUgfSBmcm9tICcuL3BpcGVzL21hcmtkb3duLnBpcGUnO1xuXG5leHBvcnQgaW50ZXJmYWNlIENoYXRib3RNZXNzYWdlIHtcbiAgcm9sZTogJ3VzZXInIHwgJ2Fzc2lzdGFudCc7XG4gIGNvbnRlbnQ6IHN0cmluZztcbiAgdGltZXN0YW1wOiBEYXRlO1xuICByZXNwb25zZVRpbWU/OiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBDaGF0Ym90V3NQYXlsb2FkIHtcbiAgZGF0YToge1xuICAgIHJlc3BvbnNlOiBzdHJpbmc7XG4gICAgcmVzcG9uc2VUaW1lOiBudW1iZXI7XG4gICAgY2hhdElkOiBzdHJpbmc7XG4gIH07XG59XG5cbi8qKlxuICogRGVsYXkgKG1zKSB1c2VkIGJlZm9yZSBzY3JvbGxpbmcgdGhlIGNoYXQgY29udGFpbmVyIHRvIHRoZSBib3R0b20uXG4gKiBHaXZlcyBBbmd1bGFyIHRpbWUgdG8gcmVuZGVyIHRoZSBuZXdseSBwdXNoZWQgbWVzc2FnZSBpbnRvIHRoZSBET00uXG4gKi9cbmNvbnN0IFNDUk9MTF9UT19CT1RUT01fREVMQVlfTVMgPSA1MDtcblxuLyoqXG4gKiBJbnRlcnZhbCAobXMpIGJldHdlZW4gcm90YXRpb25zIG9mIHRoZSBcInR5cGluZ1wiIHN0YXR1cyBwaHJhc2UuXG4gKi9cbmNvbnN0IFRZUElOR19QSFJBU0VfUk9UQVRJT05fTVMgPSAyNTAwO1xuXG4vKipcbiAqIFRyYW5zbGF0aW9uIGtleXMgY3ljbGVkIHdoaWxlIHRoZSBhc3Npc3RhbnQgaXMgcHJlcGFyaW5nIGEgcmVzcG9uc2UuXG4gKiBPcmRlciBtYXR0ZXJzOiBwaHJhc2VzIGFyZSBzaG93biBpbiB0aGlzIHNlcXVlbmNlLlxuICovXG5jb25zdCBUWVBJTkdfUEhSQVNFX0tFWVM6IHJlYWRvbmx5IHN0cmluZ1tdID0gW1xuICAnY3JteC5jb21wb25lbnRzLmNoYXRib3RfdHlwaW5nXzEnLFxuICAnY3JteC5jb21wb25lbnRzLmNoYXRib3RfdHlwaW5nXzInLFxuICAnY3JteC5jb21wb25lbnRzLmNoYXRib3RfdHlwaW5nXzMnLFxuICAnY3JteC5jb21wb25lbnRzLmNoYXRib3RfdHlwaW5nXzQnLFxuICAnY3JteC5jb21wb25lbnRzLmNoYXRib3RfdHlwaW5nXzUnXG5dO1xuXG4vKipcbiAqIENoYXRib3QgZ2xvYmFsIGRvIENSTS5cbiAqXG4gKiBTdGFuZGFsb25lLCBwbHVnLWFuZC1wbGF5OiBiYXN0YSBkZWNsYXJhciBgPHMtY2hhdGJvdD48L3MtY2hhdGJvdD5gIG5vXG4gKiBgYXBwLmNvbXBvbmVudC5odG1sYCBkYSBhcGxpY2HDp8OjbyBjb25zdW1pZG9yYS4gVG9kYSBhIGludGVncmHDp8Ojb1xuICogKFdlYlNvY2tldCBkZSByZXNwb3N0YXMsIFJFU1QgZGUgZW52aW8sIHRyYWR1w6fDtWVzIGUgcmVuZGVyaXphw6fDo28gZGVcbiAqIE1hcmtkb3duKSBlc3TDoSBlbmNhcHN1bGFkYSBuYSBiaWJsaW90ZWNhLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdzLWNoYXRib3QnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgQ29tbW9uTW9kdWxlLFxuICAgIEZvcm1zTW9kdWxlLFxuICAgIEJ1dHRvbk1vZHVsZSxcbiAgICBUZXh0YXJlYSxcbiAgICBCYWRnZU1vZHVsZSxcbiAgICBUcmFuc2xhdGVQaXBlLFxuICAgIENoYXRib3RNYXJrZG93blBpcGVcbiAgXSxcbiAgYW5pbWF0aW9uczogW1xuICAgIHRyaWdnZXIoJ2NoYXRib3RQaHJhc2VGYWRlJywgW1xuICAgICAgdHJhbnNpdGlvbignKiA9PiAqJywgW1xuICAgICAgICBzdHlsZSh7IG9wYWNpdHk6IDAsIHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVkoMnB4KScgfSksXG4gICAgICAgIGFuaW1hdGUoJzIyMG1zIGVhc2Utb3V0Jywgc3R5bGUoeyBvcGFjaXR5OiAxLCB0cmFuc2Zvcm06ICd0cmFuc2xhdGVZKDApJyB9KSlcbiAgICAgIF0pXG4gICAgXSlcbiAgXSxcbiAgdGVtcGxhdGVVcmw6ICcuL2NoYXRib3QuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybDogJy4vY2hhdGJvdC5jb21wb25lbnQuc2Nzcydcbn0pXG5leHBvcnQgY2xhc3MgQ2hhdGJvdENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgQFZpZXdDaGlsZCgnY2hhdE1lc3NhZ2VzQ29udGFpbmVyJykgcHJpdmF0ZSByZWFkb25seSBjaGF0TWVzc2FnZXNDb250YWluZXIhOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PjtcblxuICBpc09wZW4gPSBmYWxzZTtcbiAgdXNlcklucHV0ID0gJyc7XG4gIHNlbmRpbmdNZXNzYWdlID0gZmFsc2U7XG4gIGNoYXRNZXNzYWdlczogQ2hhdGJvdE1lc3NhZ2VbXSA9IFtdO1xuICBjaGF0SWQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICB1bnJlYWRDb3VudCA9IDA7XG4gIHR5cGluZ1BocmFzZUtleTogc3RyaW5nID0gVFlQSU5HX1BIUkFTRV9LRVlTWzBdO1xuXG4gIHByaXZhdGUgd3NTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbiB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHR5cGluZ1BocmFzZVRpbWVyOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRJbnRlcnZhbD4gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSB0eXBpbmdQaHJhc2VJbmRleCA9IDA7XG4gIHByaXZhdGUgcmVhZG9ubHkgd3NDb25maWc6IFdlYlNvY2tldENvbmZpZyA9IHtcbiAgICBkb21haW46ICdjcm14JyxcbiAgICBzZXJ2aWNlOiAnY2hhdGJvdCcsXG4gICAgcHJpbWl0aXZlOiAnd3NDaGF0UmVzcG9uc2UnLFxuICAgIHVzZXJTY29wZWQ6IHRydWVcbiAgfTtcblxuICBwcml2YXRlIHJlYWRvbmx5IHdlYlNvY2tldFNlcnZpY2UgPSBpbmplY3QoV2ViU29ja2V0U2VydmljZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgbmdab25lID0gaW5qZWN0KE5nWm9uZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2hhdGJvdFNlcnZpY2UgPSBpbmplY3QoQ2hhdGJvdFNlcnZpY2UpO1xuICBwcml2YXRlIHJlYWRvbmx5IHRyYW5zbGF0aW9uU2VydmljZSA9IGluamVjdChUcmFuc2xhdGlvblNlcnZpY2UpO1xuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuc3Vic2NyaWJlVG9XZWJTb2NrZXQoKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMud3NTdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy53ZWJTb2NrZXRTZXJ2aWNlLnVuc3Vic2NyaWJlKHRoaXMud3NDb25maWcpO1xuICAgIHRoaXMud2ViU29ja2V0U2VydmljZS5kaXNjb25uZWN0KCk7XG4gICAgdGhpcy5zdG9wVHlwaW5nUGhyYXNlUm90YXRpb24oKTtcbiAgfVxuXG4gIHRvZ2dsZUNoYXQoKTogdm9pZCB7XG4gICAgdGhpcy5pc09wZW4gPSAhdGhpcy5pc09wZW47XG4gICAgaWYgKHRoaXMuaXNPcGVuKSB7XG4gICAgICB0aGlzLnVucmVhZENvdW50ID0gMDtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5zY3JvbGxDaGF0VG9Cb3R0b20oKSwgMTAwKTtcbiAgICB9XG4gIH1cblxuICBzZW5kTWVzc2FnZSgpOiB2b2lkIHtcbiAgICBjb25zdCB0ZXh0ID0gdGhpcy51c2VySW5wdXQudHJpbSgpO1xuICAgIGlmICghdGV4dCB8fCB0aGlzLnNlbmRpbmdNZXNzYWdlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5jaGF0TWVzc2FnZXMucHVzaCh7IHJvbGU6ICd1c2VyJywgY29udGVudDogdGV4dCwgdGltZXN0YW1wOiBuZXcgRGF0ZSgpIH0pO1xuICAgIHRoaXMudXNlcklucHV0ID0gJyc7XG4gICAgdGhpcy5zZW5kaW5nTWVzc2FnZSA9IHRydWU7XG4gICAgdGhpcy5zdGFydFR5cGluZ1BocmFzZVJvdGF0aW9uKCk7XG4gICAgdGhpcy5zY3JvbGxDaGF0VG9Cb3R0b20oKTtcblxuICAgIHRoaXMuY2hhdGJvdFNlcnZpY2UuY2hhdCh0ZXh0LCB0aGlzLmNoYXRJZCA/PyB1bmRlZmluZWQpLnN1YnNjcmliZSh7XG4gICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICB0aGlzLmNoYXRNZXNzYWdlcy5wdXNoKHtcbiAgICAgICAgICByb2xlOiAnYXNzaXN0YW50JyxcbiAgICAgICAgICBjb250ZW50OiB0aGlzLnRyYW5zbGF0aW9uU2VydmljZS50cmFuc2xhdGUoJ2NybXguY29tcG9uZW50cy5jaGF0Ym90X2Vycm9yJyksXG4gICAgICAgICAgdGltZXN0YW1wOiBuZXcgRGF0ZSgpXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnNlbmRpbmdNZXNzYWdlID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc3RvcFR5cGluZ1BocmFzZVJvdGF0aW9uKCk7XG4gICAgICAgIHRoaXMuc2Nyb2xsQ2hhdFRvQm90dG9tKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBvbkNoYXRLZXlkb3duKGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKGV2ZW50LmtleSA9PT0gJ0VudGVyJyAmJiAhZXZlbnQuc2hpZnRLZXkpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB0aGlzLnNlbmRNZXNzYWdlKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzdWJzY3JpYmVUb1dlYlNvY2tldCgpOiB2b2lkIHtcbiAgICB0aGlzLndzU3Vic2NyaXB0aW9uID0gdGhpcy53ZWJTb2NrZXRTZXJ2aWNlXG4gICAgICAuc3Vic2NyaWJlPENoYXRib3RXc1BheWxvYWQ+KHRoaXMud3NDb25maWcpXG4gICAgICAuc3Vic2NyaWJlKG1zZyA9PiB7XG4gICAgICAgIGNvbnN0IGRhdGEgPSBtc2cuYm9keS5kYXRhO1xuICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgIGlmICghZGF0YSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChkYXRhLmNoYXRJZCkge1xuICAgICAgICAgICAgdGhpcy5jaGF0SWQgPSBkYXRhLmNoYXRJZDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLmNoYXRNZXNzYWdlcy5wdXNoKHtcbiAgICAgICAgICAgIHJvbGU6ICdhc3Npc3RhbnQnLFxuICAgICAgICAgICAgY29udGVudDogZGF0YS5yZXNwb25zZSxcbiAgICAgICAgICAgIHRpbWVzdGFtcDogbmV3IERhdGUoKSxcbiAgICAgICAgICAgIHJlc3BvbnNlVGltZTogZGF0YS5yZXNwb25zZVRpbWVcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHRoaXMuc2VuZGluZ01lc3NhZ2UgPSBmYWxzZTtcbiAgICAgICAgICB0aGlzLnN0b3BUeXBpbmdQaHJhc2VSb3RhdGlvbigpO1xuXG4gICAgICAgICAgaWYgKCF0aGlzLmlzT3Blbikge1xuICAgICAgICAgICAgdGhpcy51bnJlYWRDb3VudCsrO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMuc2Nyb2xsQ2hhdFRvQm90dG9tKCk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHNjcm9sbENoYXRUb0JvdHRvbSgpOiB2b2lkIHtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGNvbnN0IGVsID0gdGhpcy5jaGF0TWVzc2FnZXNDb250YWluZXI/Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgICBpZiAoZWwpIHtcbiAgICAgICAgZWwuc2Nyb2xsVG9wID0gZWwuc2Nyb2xsSGVpZ2h0O1xuICAgICAgfVxuICAgIH0sIFNDUk9MTF9UT19CT1RUT01fREVMQVlfTVMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0cyBjeWNsaW5nIHRocm91Z2ggdGhlIHR5cGluZyBwaHJhc2VzLiBBbHdheXMgYmVnaW5zIGZyb20gdGhlIGZpcnN0XG4gICAqIGtleSBzbyB0aGUgdXNlciBzZWVzIHRoZSBzYW1lIGZyaWVuZGx5IG9wZW5pbmcgZXZlcnkgdGltZS5cbiAgICovXG4gIHByaXZhdGUgc3RhcnRUeXBpbmdQaHJhc2VSb3RhdGlvbigpOiB2b2lkIHtcbiAgICB0aGlzLnN0b3BUeXBpbmdQaHJhc2VSb3RhdGlvbigpO1xuICAgIHRoaXMudHlwaW5nUGhyYXNlSW5kZXggPSAwO1xuICAgIHRoaXMudHlwaW5nUGhyYXNlS2V5ID0gVFlQSU5HX1BIUkFTRV9LRVlTWzBdO1xuICAgIHRoaXMudHlwaW5nUGhyYXNlVGltZXIgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICB0aGlzLnR5cGluZ1BocmFzZUluZGV4ID0gKHRoaXMudHlwaW5nUGhyYXNlSW5kZXggKyAxKSAlIFRZUElOR19QSFJBU0VfS0VZUy5sZW5ndGg7XG4gICAgICAgIHRoaXMudHlwaW5nUGhyYXNlS2V5ID0gVFlQSU5HX1BIUkFTRV9LRVlTW3RoaXMudHlwaW5nUGhyYXNlSW5kZXhdO1xuICAgICAgfSk7XG4gICAgfSwgVFlQSU5HX1BIUkFTRV9ST1RBVElPTl9NUyk7XG4gIH1cblxuICBwcml2YXRlIHN0b3BUeXBpbmdQaHJhc2VSb3RhdGlvbigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy50eXBpbmdQaHJhc2VUaW1lciAhPT0gbnVsbCkge1xuICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLnR5cGluZ1BocmFzZVRpbWVyKTtcbiAgICAgIHRoaXMudHlwaW5nUGhyYXNlVGltZXIgPSBudWxsO1xuICAgIH1cbiAgfVxufVxuIiwiPCEtLSBGbG9hdGluZyBBY3Rpb24gQnV0dG9uIC0tPlxuPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJjaGF0Ym90LWZhYlwiIFtjbGFzcy5vcGVuXT1cImlzT3BlblwiXG4gICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiJ2NybXguY29tcG9uZW50cy5jaGF0Ym90X3RpdGxlJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgIFthdHRyLmFyaWEtZXhwYW5kZWRdPVwiaXNPcGVuXCJcbiAgICAgICAgKGNsaWNrKT1cInRvZ2dsZUNoYXQoKVwiPlxuICA8aSAqbmdJZj1cIiFpc09wZW5cIiBjbGFzcz1cInBpIHBpLWxpZ2h0YnVsYiBmYWItaWNvblwiPjwvaT5cbiAgPGkgKm5nSWY9XCJpc09wZW5cIiBjbGFzcz1cInBpIHBpLXRpbWVzXCI+PC9pPlxuICA8c3BhbiBjbGFzcz1cInVucmVhZC1iYWRnZVwiICpuZ0lmPVwidW5yZWFkQ291bnQgPiAwICYmICFpc09wZW5cIj57eyB1bnJlYWRDb3VudCB9fTwvc3Bhbj5cbjwvYnV0dG9uPlxuXG48IS0tIENoYXQgV2luZG93IC0tPlxuPGRpdiBjbGFzcz1cImNoYXRib3Qtd2luZG93XCIgKm5nSWY9XCJpc09wZW5cIj5cbiAgPGRpdiBjbGFzcz1cImNoYXRib3QtaGVhZGVyXCI+XG4gICAgPGkgY2xhc3M9XCJwaSBwaS1saWdodGJ1bGIgaGVhZGVyLWljb25cIj48L2k+XG4gICAgPHNwYW4+e3sgJ2NybXguY29tcG9uZW50cy5jaGF0Ym90X3RpdGxlJyB8IHRyYW5zbGF0ZSB9fTwvc3Bhbj5cbiAgPC9kaXY+XG5cbiAgPGRpdiBjbGFzcz1cImNoYXRib3QtbWVzc2FnZXNcIiAjY2hhdE1lc3NhZ2VzQ29udGFpbmVyPlxuICAgIDwhLS0gV2VsY29tZSAtLT5cbiAgICA8ZGl2IGNsYXNzPVwiY2hhdGJvdC13ZWxjb21lXCIgKm5nSWY9XCJjaGF0TWVzc2FnZXMubGVuZ3RoID09PSAwXCI+XG4gICAgICA8aSBjbGFzcz1cInBpIHBpLWxpZ2h0YnVsYiB3ZWxjb21lLWljb25cIj48L2k+XG4gICAgICA8cD57eyAnY3JteC5jb21wb25lbnRzLmNoYXRib3Rfd2VsY29tZScgfCB0cmFuc2xhdGUgfX08L3A+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIE1lc3NhZ2VzIC0tPlxuICAgIDxkaXYgKm5nRm9yPVwibGV0IG1zZyBvZiBjaGF0TWVzc2FnZXNcIiBjbGFzcz1cImNoYXRib3QtbWVzc2FnZVwiXG4gICAgICAgICBbbmdDbGFzc109XCJ7ICd1c2VyLW1lc3NhZ2UnOiBtc2cucm9sZSA9PT0gJ3VzZXInLCAnYXNzaXN0YW50LW1lc3NhZ2UnOiBtc2cucm9sZSA9PT0gJ2Fzc2lzdGFudCcgfVwiPlxuICAgICAgPGRpdiBjbGFzcz1cIm1lc3NhZ2UtYXZhdGFyXCI+XG4gICAgICAgIDxpICpuZ0lmPVwibXNnLnJvbGUgPT09ICd1c2VyJ1wiIGNsYXNzPVwicGkgcGktdXNlclwiPjwvaT5cbiAgICAgICAgPGkgKm5nSWY9XCJtc2cucm9sZSA9PT0gJ2Fzc2lzdGFudCdcIiBjbGFzcz1cInBpIHBpLWxpZ2h0YnVsYiBhc3Npc3RhbnQtYXZhdGFyLWljb25cIj48L2k+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJtZXNzYWdlLWJ1YmJsZVwiIFtjbGFzcy5tYXJrZG93bi1jb250ZW50XT1cIm1zZy5yb2xlID09PSAnYXNzaXN0YW50J1wiPlxuICAgICAgICA8cCAqbmdJZj1cIm1zZy5yb2xlID09PSAndXNlcidcIj57eyBtc2cuY29udGVudCB9fTwvcD5cbiAgICAgICAgPGRpdiAqbmdJZj1cIm1zZy5yb2xlID09PSAnYXNzaXN0YW50J1wiIFtpbm5lckhUTUxdPVwibXNnLmNvbnRlbnQgfCBzQ2hhdGJvdE1hcmtkb3duXCI+PC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJtZXNzYWdlLW1ldGFcIj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1lc3NhZ2UtdGltZVwiPnt7IG1zZy50aW1lc3RhbXAgfCBkYXRlOidISDptbScgfX08L3NwYW4+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJyZXNwb25zZS10aW1lXCIgKm5nSWY9XCJtc2cucmVzcG9uc2VUaW1lXCI+4o+xIHt7IG1zZy5yZXNwb25zZVRpbWUgfX1zPC9zcGFuPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBUeXBpbmcgaW5kaWNhdG9yIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJjaGF0Ym90LXR5cGluZ1wiICpuZ0lmPVwic2VuZGluZ01lc3NhZ2VcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJtZXNzYWdlLWF2YXRhclwiPjxpIGNsYXNzPVwicGkgcGktbGlnaHRidWxiIGFzc2lzdGFudC1hdmF0YXItaWNvblwiPjwvaT48L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJ0eXBpbmctYnViYmxlXCIgYXJpYS1saXZlPVwicG9saXRlXCI+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwidHlwaW5nLXBocmFzZVwiIFtAY2hhdGJvdFBocmFzZUZhZGVdPVwidHlwaW5nUGhyYXNlS2V5XCI+e3sgdHlwaW5nUGhyYXNlS2V5IHwgdHJhbnNsYXRlIH19PC9zcGFuPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInR5cGluZy1wdWxzZVwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPlxuICAgICAgICAgIDxzcGFuPjwvc3Bhbj48c3Bhbj48L3NwYW4+PHNwYW4+PC9zcGFuPlxuICAgICAgICA8L3NwYW4+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG5cbiAgPGRpdiBjbGFzcz1cImNoYXRib3QtaW5wdXQtYXJlYVwiPlxuICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1yb3dcIj5cbiAgICAgIDxsYWJlbCBmb3I9XCJzLWNoYXRib3QtaW5wdXRcIiBjbGFzcz1cInNyLW9ubHlcIj57eyAnY3JteC5jb21wb25lbnRzLmNoYXRib3RfcGxhY2Vob2xkZXInIHwgdHJhbnNsYXRlIH19PC9sYWJlbD5cbiAgICAgIDx0ZXh0YXJlYSBwVGV4dGFyZWEgaWQ9XCJzLWNoYXRib3QtaW5wdXRcIiBbKG5nTW9kZWwpXT1cInVzZXJJbnB1dFwiXG4gICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cIidjcm14LmNvbXBvbmVudHMuY2hhdGJvdF9wbGFjZWhvbGRlcicgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgIFthdXRvUmVzaXplXT1cInRydWVcIiBbcm93c109XCIxXCIgW21heGxlbmd0aF09XCIyMDAwXCJcbiAgICAgICAgICAgICAgICAoa2V5ZG93bik9XCJvbkNoYXRLZXlkb3duKCRldmVudClcIiBbZGlzYWJsZWRdPVwic2VuZGluZ01lc3NhZ2VcIj48L3RleHRhcmVhPlxuICAgICAgPGJ1dHRvbiBwQnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInAtYnV0dG9uLXJvdW5kZWQgc2VuZC1idG5cIlxuICAgICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIidjcm14LmNvbXBvbmVudHMuY2hhdGJvdF9wbGFjZWhvbGRlcicgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiIXVzZXJJbnB1dC50cmltKCkgfHwgc2VuZGluZ01lc3NhZ2VcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwic2VuZE1lc3NhZ2UoKVwiPlxuICAgICAgICA8aSBjbGFzcz1cInBpIHBpLXNlbmRcIj48L2k+XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==
@@ -101,5 +101,10 @@
101
101
  "crmx.components.chatbot_title": "AI Assistant",
102
102
  "crmx.components.chatbot_welcome": "Hello! I'm the CRMX virtual assistant. How can I help you?",
103
103
  "crmx.components.chatbot_placeholder": "Type your message...",
104
- "crmx.components.chatbot_error": "An error occurred while processing your message. Please try again."
104
+ "crmx.components.chatbot_error": "An error occurred while processing your message. Please try again.",
105
+ "crmx.components.chatbot_typing_1": "Searching...",
106
+ "crmx.components.chatbot_typing_2": "Analyzing your question...",
107
+ "crmx.components.chatbot_typing_3": "Gathering information...",
108
+ "crmx.components.chatbot_typing_4": "Almost there!",
109
+ "crmx.components.chatbot_typing_5": "Wrapping up the answer..."
105
110
  }
@@ -101,5 +101,10 @@
101
101
  "crmx.components.chatbot_title": "Asistente IA",
102
102
  "crmx.components.chatbot_welcome": "¡Hola! Soy el asistente virtual de CRMX. ¿Cómo puedo ayudarte?",
103
103
  "crmx.components.chatbot_placeholder": "Escribe tu mensaje...",
104
- "crmx.components.chatbot_error": "Ocurrió un error al procesar tu mensaje. Inténtalo de nuevo."
104
+ "crmx.components.chatbot_error": "Ocurrió un error al procesar tu mensaje. Inténtalo de nuevo.",
105
+ "crmx.components.chatbot_typing_1": "Buscando...",
106
+ "crmx.components.chatbot_typing_2": "Analizando tu pregunta...",
107
+ "crmx.components.chatbot_typing_3": "Reuniendo información...",
108
+ "crmx.components.chatbot_typing_4": "¡Casi listo!",
109
+ "crmx.components.chatbot_typing_5": "Finalizando la respuesta..."
105
110
  }
@@ -101,5 +101,10 @@
101
101
  "crmx.components.chatbot_title": "Assistente IA",
102
102
  "crmx.components.chatbot_welcome": "Olá! Sou o assistente virtual do CRMX. Como posso ajudar você?",
103
103
  "crmx.components.chatbot_placeholder": "Digite sua mensagem...",
104
- "crmx.components.chatbot_error": "Ocorreu um erro ao processar sua mensagem. Tente novamente."
104
+ "crmx.components.chatbot_error": "Ocorreu um erro ao processar sua mensagem. Tente novamente.",
105
+ "crmx.components.chatbot_typing_1": "Procurando...",
106
+ "crmx.components.chatbot_typing_2": "Analisando sua pergunta...",
107
+ "crmx.components.chatbot_typing_3": "Reunindo informações...",
108
+ "crmx.components.chatbot_typing_4": "Quase pronto!",
109
+ "crmx.components.chatbot_typing_5": "Finalizando a resposta..."
105
110
  }