@senior-gestao-relacionamento/angular-components 2.2.0 → 2.3.0-master-efd82255

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.
@@ -0,0 +1,140 @@
1
+ import { Component, NgZone, ViewChild, inject } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { FormsModule } from '@angular/forms';
4
+ import { ButtonModule } from 'primeng/button';
5
+ import { Textarea } from 'primeng/textarea';
6
+ import { BadgeModule } from 'primeng/badge';
7
+ import { TranslatePipe, TranslationService, WebSocketService } from '@seniorsistemas/components-ai';
8
+ import { ChatbotService } from './services/chatbot.service';
9
+ import { ChatbotMarkdownPipe } from './pipes/markdown.pipe';
10
+ import * as i0 from "@angular/core";
11
+ import * as i1 from "@angular/common";
12
+ import * as i2 from "@angular/forms";
13
+ import * as i3 from "primeng/button";
14
+ /**
15
+ * Delay (ms) used before scrolling the chat container to the bottom.
16
+ * Gives Angular time to render the newly pushed message into the DOM.
17
+ */
18
+ const SCROLL_TO_BOTTOM_DELAY_MS = 50;
19
+ /**
20
+ * Chatbot global do CRM.
21
+ *
22
+ * Standalone, plug-and-play: basta declarar `<s-chatbot></s-chatbot>` no
23
+ * `app.component.html` da aplicação consumidora. Toda a integração
24
+ * (WebSocket de respostas, REST de envio, traduções e renderização de
25
+ * Markdown) está encapsulada na biblioteca.
26
+ */
27
+ export class ChatbotComponent {
28
+ chatMessagesContainer;
29
+ isOpen = false;
30
+ userInput = '';
31
+ sendingMessage = false;
32
+ chatMessages = [];
33
+ chatId = null;
34
+ unreadCount = 0;
35
+ wsSubscription = null;
36
+ wsConfig = {
37
+ domain: 'crmx',
38
+ service: 'chatbot',
39
+ primitive: 'wsChatResponse',
40
+ userScoped: true
41
+ };
42
+ webSocketService = inject(WebSocketService);
43
+ ngZone = inject(NgZone);
44
+ chatbotService = inject(ChatbotService);
45
+ translationService = inject(TranslationService);
46
+ ngOnInit() {
47
+ this.subscribeToWebSocket();
48
+ }
49
+ ngOnDestroy() {
50
+ this.wsSubscription?.unsubscribe();
51
+ this.webSocketService.unsubscribe(this.wsConfig);
52
+ this.webSocketService.disconnect();
53
+ }
54
+ toggleChat() {
55
+ this.isOpen = !this.isOpen;
56
+ if (this.isOpen) {
57
+ this.unreadCount = 0;
58
+ setTimeout(() => this.scrollChatToBottom(), 100);
59
+ }
60
+ }
61
+ sendMessage() {
62
+ const text = this.userInput.trim();
63
+ if (!text || this.sendingMessage) {
64
+ return;
65
+ }
66
+ this.chatMessages.push({ role: 'user', content: text, timestamp: new Date() });
67
+ this.userInput = '';
68
+ this.sendingMessage = true;
69
+ this.scrollChatToBottom();
70
+ this.chatbotService.chat(text, this.chatId ?? undefined).subscribe({
71
+ error: () => {
72
+ this.chatMessages.push({
73
+ role: 'assistant',
74
+ content: this.translationService.translate('crmx.components.chatbot_error'),
75
+ timestamp: new Date()
76
+ });
77
+ this.sendingMessage = false;
78
+ this.scrollChatToBottom();
79
+ }
80
+ });
81
+ }
82
+ onChatKeydown(event) {
83
+ if (event.key === 'Enter' && !event.shiftKey) {
84
+ event.preventDefault();
85
+ this.sendMessage();
86
+ }
87
+ }
88
+ subscribeToWebSocket() {
89
+ this.wsSubscription = this.webSocketService
90
+ .subscribe(this.wsConfig)
91
+ .subscribe(msg => {
92
+ const data = msg.body.data;
93
+ this.ngZone.run(() => {
94
+ if (!data) {
95
+ return;
96
+ }
97
+ if (data.chatId) {
98
+ this.chatId = data.chatId;
99
+ }
100
+ this.chatMessages.push({
101
+ role: 'assistant',
102
+ content: data.response,
103
+ timestamp: new Date(),
104
+ responseTime: data.responseTime
105
+ });
106
+ this.sendingMessage = false;
107
+ if (!this.isOpen) {
108
+ this.unreadCount++;
109
+ }
110
+ this.scrollChatToBottom();
111
+ });
112
+ });
113
+ }
114
+ scrollChatToBottom() {
115
+ setTimeout(() => {
116
+ const el = this.chatMessagesContainer?.nativeElement;
117
+ if (el) {
118
+ el.scrollTop = el.scrollHeight;
119
+ }
120
+ }, SCROLL_TO_BOTTOM_DELAY_MS);
121
+ }
122
+ 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" }] });
124
+ }
125
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChatbotComponent, decorators: [{
126
+ type: Component,
127
+ args: [{ selector: 's-chatbot', standalone: true, imports: [
128
+ CommonModule,
129
+ FormsModule,
130
+ ButtonModule,
131
+ Textarea,
132
+ BadgeModule,
133
+ TranslatePipe,
134
+ 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"] }]
136
+ }], propDecorators: { chatMessagesContainer: [{
137
+ type: ViewChild,
138
+ args: ['chatMessagesContainer']
139
+ }] } });
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==
@@ -0,0 +1,48 @@
1
+ import { Pipe } from '@angular/core';
2
+ import DOMPurify from 'dompurify';
3
+ import { marked } from 'marked';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "@angular/platform-browser";
6
+ /**
7
+ * Pipe interno do chatbot para renderizar Markdown como HTML seguro.
8
+ *
9
+ * Fluxo de segurança:
10
+ * 1. `marked.parse` converte Markdown em HTML (sem JS executável por padrão).
11
+ * 2. `DOMPurify.sanitize` remove qualquer tag/atributo potencialmente
12
+ * malicioso (script, on*, javascript:..., etc.).
13
+ * 3. `bypassSecurityTrustHtml` libera o HTML já sanitizado para o
14
+ * `[innerHTML]` sem que o Angular faça uma segunda sanitização que
15
+ * removeria estilos e classes legítimas do markdown.
16
+ *
17
+ * Não exportado no public-api: uso restrito ao componente de chatbot.
18
+ */
19
+ export class ChatbotMarkdownPipe {
20
+ sanitizer;
21
+ constructor(sanitizer) {
22
+ this.sanitizer = sanitizer;
23
+ marked.setOptions({
24
+ breaks: true,
25
+ gfm: true
26
+ });
27
+ }
28
+ transform(value) {
29
+ if (!value) {
30
+ return '';
31
+ }
32
+ const rawHtml = marked.parse(value);
33
+ const cleanHtml = DOMPurify.sanitize(rawHtml);
34
+ // HTML sanitized via DOMPurify above; the bypass is required so the
35
+ // already-safe markdown styles aren't stripped by Angular's sanitizer.
36
+ return this.sanitizer.bypassSecurityTrustHtml(cleanHtml);
37
+ }
38
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChatbotMarkdownPipe, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe });
39
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: ChatbotMarkdownPipe, isStandalone: true, name: "sChatbotMarkdown" });
40
+ }
41
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChatbotMarkdownPipe, decorators: [{
42
+ type: Pipe,
43
+ args: [{
44
+ name: 'sChatbotMarkdown',
45
+ standalone: true
46
+ }]
47
+ }], ctorParameters: () => [{ type: i1.DomSanitizer }] });
48
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFya2Rvd24ucGlwZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItY29tcG9uZW50cy9zcmMvbGliL2NvbXBvbmVudHMvY2hhdGJvdC9waXBlcy9tYXJrZG93bi5waXBlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxJQUFJLEVBQWlCLE1BQU0sZUFBZSxDQUFDO0FBRXBELE9BQU8sU0FBUyxNQUFNLFdBQVcsQ0FBQztBQUNsQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sUUFBUSxDQUFDOzs7QUFFaEM7Ozs7Ozs7Ozs7OztHQVlHO0FBS0gsTUFBTSxPQUFPLG1CQUFtQjtJQUNEO0lBQTdCLFlBQTZCLFNBQXVCO1FBQXZCLGNBQVMsR0FBVCxTQUFTLENBQWM7UUFDbEQsTUFBTSxDQUFDLFVBQVUsQ0FBQztZQUNoQixNQUFNLEVBQUUsSUFBSTtZQUNaLEdBQUcsRUFBRSxJQUFJO1NBQ1YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELFNBQVMsQ0FBQyxLQUFhO1FBQ3JCLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNYLE9BQU8sRUFBRSxDQUFDO1FBQ1osQ0FBQztRQUNELE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFXLENBQUM7UUFDOUMsTUFBTSxTQUFTLEdBQUcsU0FBUyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM5QyxvRUFBb0U7UUFDcEUsdUVBQXVFO1FBQ3ZFLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyx1QkFBdUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUMzRCxDQUFDO3dHQWpCVSxtQkFBbUI7c0dBQW5CLG1CQUFtQjs7NEZBQW5CLG1CQUFtQjtrQkFKL0IsSUFBSTttQkFBQztvQkFDSixJQUFJLEVBQUUsa0JBQWtCO29CQUN4QixVQUFVLEVBQUUsSUFBSTtpQkFDakIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBQaXBlLCBQaXBlVHJhbnNmb3JtIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBEb21TYW5pdGl6ZXIsIFNhZmVIdG1sIH0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlcic7XG5pbXBvcnQgRE9NUHVyaWZ5IGZyb20gJ2RvbXB1cmlmeSc7XG5pbXBvcnQgeyBtYXJrZWQgfSBmcm9tICdtYXJrZWQnO1xuXG4vKipcbiAqIFBpcGUgaW50ZXJubyBkbyBjaGF0Ym90IHBhcmEgcmVuZGVyaXphciBNYXJrZG93biBjb21vIEhUTUwgc2VndXJvLlxuICpcbiAqIEZsdXhvIGRlIHNlZ3VyYW7Dp2E6XG4gKiAgIDEuIGBtYXJrZWQucGFyc2VgIGNvbnZlcnRlIE1hcmtkb3duIGVtIEhUTUwgKHNlbSBKUyBleGVjdXTDoXZlbCBwb3IgcGFkcsOjbykuXG4gKiAgIDIuIGBET01QdXJpZnkuc2FuaXRpemVgIHJlbW92ZSBxdWFscXVlciB0YWcvYXRyaWJ1dG8gcG90ZW5jaWFsbWVudGVcbiAqICAgICAgbWFsaWNpb3NvIChzY3JpcHQsIG9uKiwgamF2YXNjcmlwdDouLi4sIGV0Yy4pLlxuICogICAzLiBgYnlwYXNzU2VjdXJpdHlUcnVzdEh0bWxgIGxpYmVyYSBvIEhUTUwgasOhIHNhbml0aXphZG8gcGFyYSBvXG4gKiAgICAgIGBbaW5uZXJIVE1MXWAgc2VtIHF1ZSBvIEFuZ3VsYXIgZmHDp2EgdW1hIHNlZ3VuZGEgc2FuaXRpemHDp8OjbyBxdWVcbiAqICAgICAgcmVtb3ZlcmlhIGVzdGlsb3MgZSBjbGFzc2VzIGxlZ8OtdGltYXMgZG8gbWFya2Rvd24uXG4gKlxuICogTsOjbyBleHBvcnRhZG8gbm8gcHVibGljLWFwaTogdXNvIHJlc3RyaXRvIGFvIGNvbXBvbmVudGUgZGUgY2hhdGJvdC5cbiAqL1xuQFBpcGUoe1xuICBuYW1lOiAnc0NoYXRib3RNYXJrZG93bicsXG4gIHN0YW5kYWxvbmU6IHRydWVcbn0pXG5leHBvcnQgY2xhc3MgQ2hhdGJvdE1hcmtkb3duUGlwZSBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IHNhbml0aXplcjogRG9tU2FuaXRpemVyKSB7XG4gICAgbWFya2VkLnNldE9wdGlvbnMoe1xuICAgICAgYnJlYWtzOiB0cnVlLFxuICAgICAgZ2ZtOiB0cnVlXG4gICAgfSk7XG4gIH1cblxuICB0cmFuc2Zvcm0odmFsdWU6IHN0cmluZyk6IFNhZmVIdG1sIHtcbiAgICBpZiAoIXZhbHVlKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuICAgIGNvbnN0IHJhd0h0bWwgPSBtYXJrZWQucGFyc2UodmFsdWUpIGFzIHN0cmluZztcbiAgICBjb25zdCBjbGVhbkh0bWwgPSBET01QdXJpZnkuc2FuaXRpemUocmF3SHRtbCk7XG4gICAgLy8gSFRNTCBzYW5pdGl6ZWQgdmlhIERPTVB1cmlmeSBhYm92ZTsgdGhlIGJ5cGFzcyBpcyByZXF1aXJlZCBzbyB0aGVcbiAgICAvLyBhbHJlYWR5LXNhZmUgbWFya2Rvd24gc3R5bGVzIGFyZW4ndCBzdHJpcHBlZCBieSBBbmd1bGFyJ3Mgc2FuaXRpemVyLlxuICAgIHJldHVybiB0aGlzLnNhbml0aXplci5ieXBhc3NTZWN1cml0eVRydXN0SHRtbChjbGVhbkh0bWwpO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,30 @@
1
+ import { Injectable } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ import * as i1 from "@angular/common/http";
4
+ /**
5
+ * Serviço de integração com o backend do chatbot.
6
+ *
7
+ * Endpoint fixo: `crmx/chatbot/signals/chat` (compartilhado por todos os
8
+ * frontends do CRM).
9
+ */
10
+ export class ChatbotService {
11
+ http;
12
+ signalsUrl = 'crmx/chatbot/signals';
13
+ constructor(http) {
14
+ this.http = http;
15
+ }
16
+ chat(message, chatId) {
17
+ const payload = { message };
18
+ if (chatId) {
19
+ payload.chatId = chatId;
20
+ }
21
+ return this.http.post(`${this.signalsUrl}/chat`, payload);
22
+ }
23
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChatbotService, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
24
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChatbotService, providedIn: 'root' });
25
+ }
26
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChatbotService, decorators: [{
27
+ type: Injectable,
28
+ args: [{ providedIn: 'root' }]
29
+ }], ctorParameters: () => [{ type: i1.HttpClient }] });
30
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhdGJvdC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci1jb21wb25lbnRzL3NyYy9saWIvY29tcG9uZW50cy9jaGF0Ym90L3NlcnZpY2VzL2NoYXRib3Quc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDOzs7QUFJM0M7Ozs7O0dBS0c7QUFFSCxNQUFNLE9BQU8sY0FBYztJQUdJO0lBRlosVUFBVSxHQUFHLHNCQUFzQixDQUFDO0lBRXJELFlBQTZCLElBQWdCO1FBQWhCLFNBQUksR0FBSixJQUFJLENBQVk7SUFBRyxDQUFDO0lBRWpELElBQUksQ0FBQyxPQUFlLEVBQUUsTUFBZTtRQUNuQyxNQUFNLE9BQU8sR0FBeUMsRUFBRSxPQUFPLEVBQUUsQ0FBQztRQUNsRSxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDMUIsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQU8sR0FBRyxJQUFJLENBQUMsVUFBVSxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDbEUsQ0FBQzt3R0FYVSxjQUFjOzRHQUFkLGNBQWMsY0FERCxNQUFNOzs0RkFDbkIsY0FBYztrQkFEMUIsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuXG4vKipcbiAqIFNlcnZpw6dvIGRlIGludGVncmHDp8OjbyBjb20gbyBiYWNrZW5kIGRvIGNoYXRib3QuXG4gKlxuICogRW5kcG9pbnQgZml4bzogYGNybXgvY2hhdGJvdC9zaWduYWxzL2NoYXRgIChjb21wYXJ0aWxoYWRvIHBvciB0b2RvcyBvc1xuICogZnJvbnRlbmRzIGRvIENSTSkuXG4gKi9cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgQ2hhdGJvdFNlcnZpY2Uge1xuICBwcml2YXRlIHJlYWRvbmx5IHNpZ25hbHNVcmwgPSAnY3JteC9jaGF0Ym90L3NpZ25hbHMnO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgaHR0cDogSHR0cENsaWVudCkge31cblxuICBjaGF0KG1lc3NhZ2U6IHN0cmluZywgY2hhdElkPzogc3RyaW5nKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgY29uc3QgcGF5bG9hZDogeyBtZXNzYWdlOiBzdHJpbmc7IGNoYXRJZD86IHN0cmluZyB9ID0geyBtZXNzYWdlIH07XG4gICAgaWYgKGNoYXRJZCkge1xuICAgICAgcGF5bG9hZC5jaGF0SWQgPSBjaGF0SWQ7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmh0dHAucG9zdDx2b2lkPihgJHt0aGlzLnNpZ25hbHNVcmx9L2NoYXRgLCBwYXlsb2FkKTtcbiAgfVxufVxuIl19
@@ -97,5 +97,9 @@
97
97
  "crmx.components.schedule_status": "Status",
98
98
  "crmx.components.schedule_confirmation_yes": "Confirmed",
99
99
  "crmx.components.schedule_confirmation_no": "Declined",
100
- "crmx.components.schedule_confirmation_pending": "Pending"
100
+ "crmx.components.schedule_confirmation_pending": "Pending",
101
+ "crmx.components.chatbot_title": "AI Assistant",
102
+ "crmx.components.chatbot_welcome": "Hello! I'm the CRMX virtual assistant. How can I help you?",
103
+ "crmx.components.chatbot_placeholder": "Type your message...",
104
+ "crmx.components.chatbot_error": "An error occurred while processing your message. Please try again."
101
105
  }
@@ -97,5 +97,9 @@
97
97
  "crmx.components.schedule_status": "Estado",
98
98
  "crmx.components.schedule_confirmation_yes": "Confirmado",
99
99
  "crmx.components.schedule_confirmation_no": "Rechazado",
100
- "crmx.components.schedule_confirmation_pending": "Pendiente"
100
+ "crmx.components.schedule_confirmation_pending": "Pendiente",
101
+ "crmx.components.chatbot_title": "Asistente IA",
102
+ "crmx.components.chatbot_welcome": "¡Hola! Soy el asistente virtual de CRMX. ¿Cómo puedo ayudarte?",
103
+ "crmx.components.chatbot_placeholder": "Escribe tu mensaje...",
104
+ "crmx.components.chatbot_error": "Ocurrió un error al procesar tu mensaje. Inténtalo de nuevo."
101
105
  }
@@ -97,5 +97,9 @@
97
97
  "crmx.components.schedule_status": "Status",
98
98
  "crmx.components.schedule_confirmation_yes": "Confirmado",
99
99
  "crmx.components.schedule_confirmation_no": "Recusado",
100
- "crmx.components.schedule_confirmation_pending": "Pendente"
100
+ "crmx.components.schedule_confirmation_pending": "Pendente",
101
+ "crmx.components.chatbot_title": "Assistente IA",
102
+ "crmx.components.chatbot_welcome": "Olá! Sou o assistente virtual do CRMX. Como posso ajudar você?",
103
+ "crmx.components.chatbot_placeholder": "Digite sua mensagem...",
104
+ "crmx.components.chatbot_error": "Ocorreu um erro ao processar sua mensagem. Tente novamente."
101
105
  }
@@ -7,10 +7,12 @@ export { StorageService } from './lib/services/storage/storage.service';
7
7
  export { CurrentCollaboratorService } from './lib/services/current-collaborator/current-collaborator.service';
8
8
  // Config
9
9
  export { provideAngularComponentsTranslations } from './lib/config/provide-angular-components-translations';
10
+ // Chatbot
11
+ export { ChatbotComponent } from './lib/components/chatbot/chatbot.component';
10
12
  // Schedule
11
13
  export { ScheduleFormComponent } from './lib/components/schedule/schedule-form/schedule-form.component';
12
14
  export { ScheduleDetailComponent } from './lib/components/schedule/schedule-detail/schedule-detail.component';
13
15
  export { ScheduleService } from './lib/components/schedule/services/schedule.service';
14
16
  export { ScheduleTypeService } from './lib/components/schedule/services/schedule-type.service';
15
17
  export { SchedulePriority, ScheduleRecurrence, WeekDay, Month, RepeatWhen, OrdinalWeekDay, ParticipantConfirmation, Status } from './lib/components/schedule/enums/schedule.enums';
16
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Byb2plY3RzL2FuZ3VsYXItY29tcG9uZW50cy9zcmMvcHVibGljLWFwaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRTFFLFdBQVc7QUFDWCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFDeEUsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sa0VBQWtFLENBQUM7QUFFOUcsU0FBUztBQUNULE9BQU8sRUFBRSxvQ0FBb0MsRUFBRSxNQUFNLHNEQUFzRCxDQUFDO0FBWTVHLFdBQVc7QUFDWCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxpRUFBaUUsQ0FBQztBQUN4RyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxxRUFBcUUsQ0FBQztBQUM5RyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0scURBQXFELENBQUM7QUFDdEYsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sMERBQTBELENBQUM7QUFJL0YsT0FBTyxFQUFFLGdCQUFnQixFQUFFLGtCQUFrQixFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBRSx1QkFBdUIsRUFBRSxNQUFNLEVBQUUsTUFBTSxnREFBZ0QsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBQdWJsaWMgQVBJIFN1cmZhY2Ugb2YgQHNlbmlvci1nZXN0YW8tcmVsYWNpb25hbWVudG8vYW5ndWxhci1jb21wb25lbnRzXG4gKi9cblxuZXhwb3J0IHsgQW5ndWxhckNvbXBvbmVudHNNb2R1bGUgfSBmcm9tICcuL2xpYi9hbmd1bGFyLWNvbXBvbmVudHMubW9kdWxlJztcblxuLy8gU2VydmljZXNcbmV4cG9ydCB7IFN0b3JhZ2VTZXJ2aWNlIH0gZnJvbSAnLi9saWIvc2VydmljZXMvc3RvcmFnZS9zdG9yYWdlLnNlcnZpY2UnO1xuZXhwb3J0IHsgQ3VycmVudENvbGxhYm9yYXRvclNlcnZpY2UgfSBmcm9tICcuL2xpYi9zZXJ2aWNlcy9jdXJyZW50LWNvbGxhYm9yYXRvci9jdXJyZW50LWNvbGxhYm9yYXRvci5zZXJ2aWNlJztcblxuLy8gQ29uZmlnXG5leHBvcnQgeyBwcm92aWRlQW5ndWxhckNvbXBvbmVudHNUcmFuc2xhdGlvbnMgfSBmcm9tICcuL2xpYi9jb25maWcvcHJvdmlkZS1hbmd1bGFyLWNvbXBvbmVudHMtdHJhbnNsYXRpb25zJztcblxuLy8gTW9kZWxzXG5leHBvcnQgdHlwZSB7XG4gIENvbGxhYm9yYXRvcixcbiAgQ29sbGFib3JhdG9yTGVhZGVyLFxuICBDb2xsYWJvcmF0b3JCcmFuY2gsXG4gIEJyYW5jaCxcbiAgQ29tcGFueSxcbiAgSm9iVGl0bGVcbn0gZnJvbSAnLi9saWIvc2VydmljZXMvY3VycmVudC1jb2xsYWJvcmF0b3IvbW9kZWxzL2NvbGxhYm9yYXRvci5tb2RlbCc7XG5cbi8vIFNjaGVkdWxlXG5leHBvcnQgeyBTY2hlZHVsZUZvcm1Db21wb25lbnQgfSBmcm9tICcuL2xpYi9jb21wb25lbnRzL3NjaGVkdWxlL3NjaGVkdWxlLWZvcm0vc2NoZWR1bGUtZm9ybS5jb21wb25lbnQnO1xuZXhwb3J0IHsgU2NoZWR1bGVEZXRhaWxDb21wb25lbnQgfSBmcm9tICcuL2xpYi9jb21wb25lbnRzL3NjaGVkdWxlL3NjaGVkdWxlLWRldGFpbC9zY2hlZHVsZS1kZXRhaWwuY29tcG9uZW50JztcbmV4cG9ydCB7IFNjaGVkdWxlU2VydmljZSB9IGZyb20gJy4vbGliL2NvbXBvbmVudHMvc2NoZWR1bGUvc2VydmljZXMvc2NoZWR1bGUuc2VydmljZSc7XG5leHBvcnQgeyBTY2hlZHVsZVR5cGVTZXJ2aWNlIH0gZnJvbSAnLi9saWIvY29tcG9uZW50cy9zY2hlZHVsZS9zZXJ2aWNlcy9zY2hlZHVsZS10eXBlLnNlcnZpY2UnO1xuZXhwb3J0IHR5cGUgeyBTY2hlZHVsZSwgU2NoZWR1bGVSZWN1cnJlbmNlSXRlbSwgUmVjdXJyZW5jZURhdGVzUmVjb3JkLCBTY2hlZHVsZVBhcnRpY2lwYW50IH0gZnJvbSAnLi9saWIvY29tcG9uZW50cy9zY2hlZHVsZS9lbnRpdGllcy9zY2hlZHVsZS5pbnRlcmZhY2UnO1xuZXhwb3J0IHR5cGUgeyBTY2hlZHVsZVR5cGUgfSBmcm9tICcuL2xpYi9jb21wb25lbnRzL3NjaGVkdWxlL2VudGl0aWVzL3NjaGVkdWxlLXR5cGUuaW50ZXJmYWNlJztcbmV4cG9ydCB0eXBlIHsgUGFydGljaXBhbnRMb29rdXAsIFBhcnRpY2lwYW50T3JpZ2luLCBTY2hlZHVsZVN1bW1hcnlCeURhdGUgfSBmcm9tICcuL2xpYi9jb21wb25lbnRzL3NjaGVkdWxlL2VudGl0aWVzL3BhcnRpY2lwYW50LWxvb2t1cC5pbnRlcmZhY2UnO1xuZXhwb3J0IHsgU2NoZWR1bGVQcmlvcml0eSwgU2NoZWR1bGVSZWN1cnJlbmNlLCBXZWVrRGF5LCBNb250aCwgUmVwZWF0V2hlbiwgT3JkaW5hbFdlZWtEYXksIFBhcnRpY2lwYW50Q29uZmlybWF0aW9uLCBTdGF0dXMgfSBmcm9tICcuL2xpYi9jb21wb25lbnRzL3NjaGVkdWxlL2VudW1zL3NjaGVkdWxlLmVudW1zJztcbiJdfQ==
18
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Byb2plY3RzL2FuZ3VsYXItY29tcG9uZW50cy9zcmMvcHVibGljLWFwaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRTFFLFdBQVc7QUFDWCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFDeEUsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sa0VBQWtFLENBQUM7QUFFOUcsU0FBUztBQUNULE9BQU8sRUFBRSxvQ0FBb0MsRUFBRSxNQUFNLHNEQUFzRCxDQUFDO0FBWTVHLFVBQVU7QUFDVixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUc5RSxXQUFXO0FBQ1gsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0saUVBQWlFLENBQUM7QUFDeEcsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0scUVBQXFFLENBQUM7QUFDOUcsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHFEQUFxRCxDQUFDO0FBQ3RGLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDBEQUEwRCxDQUFDO0FBSS9GLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxrQkFBa0IsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxjQUFjLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxFQUFFLE1BQU0sZ0RBQWdELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogUHVibGljIEFQSSBTdXJmYWNlIG9mIEBzZW5pb3ItZ2VzdGFvLXJlbGFjaW9uYW1lbnRvL2FuZ3VsYXItY29tcG9uZW50c1xuICovXG5cbmV4cG9ydCB7IEFuZ3VsYXJDb21wb25lbnRzTW9kdWxlIH0gZnJvbSAnLi9saWIvYW5ndWxhci1jb21wb25lbnRzLm1vZHVsZSc7XG5cbi8vIFNlcnZpY2VzXG5leHBvcnQgeyBTdG9yYWdlU2VydmljZSB9IGZyb20gJy4vbGliL3NlcnZpY2VzL3N0b3JhZ2Uvc3RvcmFnZS5zZXJ2aWNlJztcbmV4cG9ydCB7IEN1cnJlbnRDb2xsYWJvcmF0b3JTZXJ2aWNlIH0gZnJvbSAnLi9saWIvc2VydmljZXMvY3VycmVudC1jb2xsYWJvcmF0b3IvY3VycmVudC1jb2xsYWJvcmF0b3Iuc2VydmljZSc7XG5cbi8vIENvbmZpZ1xuZXhwb3J0IHsgcHJvdmlkZUFuZ3VsYXJDb21wb25lbnRzVHJhbnNsYXRpb25zIH0gZnJvbSAnLi9saWIvY29uZmlnL3Byb3ZpZGUtYW5ndWxhci1jb21wb25lbnRzLXRyYW5zbGF0aW9ucyc7XG5cbi8vIE1vZGVsc1xuZXhwb3J0IHR5cGUge1xuICBDb2xsYWJvcmF0b3IsXG4gIENvbGxhYm9yYXRvckxlYWRlcixcbiAgQ29sbGFib3JhdG9yQnJhbmNoLFxuICBCcmFuY2gsXG4gIENvbXBhbnksXG4gIEpvYlRpdGxlXG59IGZyb20gJy4vbGliL3NlcnZpY2VzL2N1cnJlbnQtY29sbGFib3JhdG9yL21vZGVscy9jb2xsYWJvcmF0b3IubW9kZWwnO1xuXG4vLyBDaGF0Ym90XG5leHBvcnQgeyBDaGF0Ym90Q29tcG9uZW50IH0gZnJvbSAnLi9saWIvY29tcG9uZW50cy9jaGF0Ym90L2NoYXRib3QuY29tcG9uZW50JztcbmV4cG9ydCB0eXBlIHsgQ2hhdGJvdE1lc3NhZ2UgfSBmcm9tICcuL2xpYi9jb21wb25lbnRzL2NoYXRib3QvY2hhdGJvdC5jb21wb25lbnQnO1xuXG4vLyBTY2hlZHVsZVxuZXhwb3J0IHsgU2NoZWR1bGVGb3JtQ29tcG9uZW50IH0gZnJvbSAnLi9saWIvY29tcG9uZW50cy9zY2hlZHVsZS9zY2hlZHVsZS1mb3JtL3NjaGVkdWxlLWZvcm0uY29tcG9uZW50JztcbmV4cG9ydCB7IFNjaGVkdWxlRGV0YWlsQ29tcG9uZW50IH0gZnJvbSAnLi9saWIvY29tcG9uZW50cy9zY2hlZHVsZS9zY2hlZHVsZS1kZXRhaWwvc2NoZWR1bGUtZGV0YWlsLmNvbXBvbmVudCc7XG5leHBvcnQgeyBTY2hlZHVsZVNlcnZpY2UgfSBmcm9tICcuL2xpYi9jb21wb25lbnRzL3NjaGVkdWxlL3NlcnZpY2VzL3NjaGVkdWxlLnNlcnZpY2UnO1xuZXhwb3J0IHsgU2NoZWR1bGVUeXBlU2VydmljZSB9IGZyb20gJy4vbGliL2NvbXBvbmVudHMvc2NoZWR1bGUvc2VydmljZXMvc2NoZWR1bGUtdHlwZS5zZXJ2aWNlJztcbmV4cG9ydCB0eXBlIHsgU2NoZWR1bGUsIFNjaGVkdWxlUmVjdXJyZW5jZUl0ZW0sIFJlY3VycmVuY2VEYXRlc1JlY29yZCwgU2NoZWR1bGVQYXJ0aWNpcGFudCB9IGZyb20gJy4vbGliL2NvbXBvbmVudHMvc2NoZWR1bGUvZW50aXRpZXMvc2NoZWR1bGUuaW50ZXJmYWNlJztcbmV4cG9ydCB0eXBlIHsgU2NoZWR1bGVUeXBlIH0gZnJvbSAnLi9saWIvY29tcG9uZW50cy9zY2hlZHVsZS9lbnRpdGllcy9zY2hlZHVsZS10eXBlLmludGVyZmFjZSc7XG5leHBvcnQgdHlwZSB7IFBhcnRpY2lwYW50TG9va3VwLCBQYXJ0aWNpcGFudE9yaWdpbiwgU2NoZWR1bGVTdW1tYXJ5QnlEYXRlIH0gZnJvbSAnLi9saWIvY29tcG9uZW50cy9zY2hlZHVsZS9lbnRpdGllcy9wYXJ0aWNpcGFudC1sb29rdXAuaW50ZXJmYWNlJztcbmV4cG9ydCB7IFNjaGVkdWxlUHJpb3JpdHksIFNjaGVkdWxlUmVjdXJyZW5jZSwgV2Vla0RheSwgTW9udGgsIFJlcGVhdFdoZW4sIE9yZGluYWxXZWVrRGF5LCBQYXJ0aWNpcGFudENvbmZpcm1hdGlvbiwgU3RhdHVzIH0gZnJvbSAnLi9saWIvY29tcG9uZW50cy9zY2hlZHVsZS9lbnVtcy9zY2hlZHVsZS5lbnVtcyc7XG4iXX0=