@aakash58/chatbot 1.1.16 → 1.1.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/aakash58-chatbot.mjs +5 -0
- package/esm2022/lib/app/chat/chat-ui-state.service.mjs +170 -0
- package/esm2022/lib/app/chat/chat.service.mjs +445 -0
- package/esm2022/lib/app/chat/components/chat-button/chat-button.component.mjs +50 -0
- package/esm2022/lib/app/chat/components/chat-footer/chat-footer.component.mjs +12 -0
- package/esm2022/lib/app/chat/components/chat-header/chat-header.component.mjs +66 -0
- package/esm2022/lib/app/chat/components/chat-history-sidebar/chat-history-sidebar.component.mjs +186 -0
- package/esm2022/lib/app/chat/components/chat-window/chat-window.component.mjs +312 -0
- package/esm2022/lib/app/chat/components/message-input/message-input.component.mjs +36 -0
- package/esm2022/lib/app/chat/components/message-list/message-list.component.mjs +115 -0
- package/esm2022/lib/app/chat/model/chat-history.model.mjs +2 -0
- package/esm2022/lib/app/chat/model/chat-request.model.mjs +2 -0
- package/esm2022/lib/app/chat/model/chat-response.model.mjs +2 -0
- package/esm2022/lib/app/chat/model/chat-session.model.mjs +2 -0
- package/esm2022/lib/app/chat/model/chat-stream-message.model.mjs +2 -0
- package/esm2022/lib/app/chat/model/chat-stream-response.model.mjs +2 -0
- package/esm2022/lib/app/chat/services/chat-api.service.mjs +61 -0
- package/esm2022/lib/app/chat/services/chat-audio.service.mjs +50 -0
- package/esm2022/lib/app/chat/services/chat-history.service.mjs +252 -0
- package/esm2022/lib/app/login/login-form.component.mjs +46 -0
- package/esm2022/lib/app/personalization/personalization-dialog.component.mjs +194 -0
- package/esm2022/lib/app/personalization/personalization.service.mjs +149 -0
- package/esm2022/lib/app/personalization/sections/account/account-section.component.mjs +122 -0
- package/esm2022/lib/app/personalization/sections/preferences/color-picker-dialog.component.mjs +86 -0
- package/esm2022/lib/app/personalization/sections/preferences/preferences-section.component.mjs +115 -0
- package/esm2022/lib/app/personalization/sections/profile/profile-section.component.mjs +29 -0
- package/esm2022/lib/app/personalization/sections/settings/setting-section.component.mjs +30 -0
- package/esm2022/lib/app/personalization/sections/terms/terms-section.component.mjs +12 -0
- package/esm2022/lib/constant/doohbot-constant.mjs +28 -0
- package/esm2022/lib/constant/html-entities.mjs +9 -0
- package/esm2022/lib/constant/utf8.mjs +10 -0
- package/esm2022/lib/core/app-const.mjs +61 -0
- package/esm2022/lib/core/auth/account-api.service.mjs +40 -0
- package/esm2022/lib/core/auth/auth.service.mjs +391 -0
- package/esm2022/lib/core/auth/models/auth-result.model.mjs +3 -0
- package/esm2022/lib/core/auth/models/federated-login-request.model.mjs +6 -0
- package/esm2022/lib/core/auth/models/login-request.model.mjs +6 -0
- package/esm2022/lib/core/auth/storage.service.mjs +110 -0
- package/esm2022/lib/core/directives/draggable/draggable-dialog.directive.mjs +112 -0
- package/esm2022/lib/core/directives/fullscreen/fullscreen.directive.mjs +55 -0
- package/esm2022/lib/core/directives/resizable/resizable-dialog.directive.mjs +179 -0
- package/esm2022/lib/core/environments/environment.mjs +15 -0
- package/esm2022/lib/core/environments/environment.prod.mjs +15 -0
- package/esm2022/lib/core/helpers/crypto-helper.service.mjs +52 -0
- package/esm2022/lib/core/http/http-stream.service.mjs +97 -0
- package/esm2022/lib/core/http/http.service.mjs +103 -0
- package/esm2022/lib/core/interceptors/auth.interceptor.mjs +96 -0
- package/esm2022/lib/core/interceptors/license.interceptor.mjs +44 -0
- package/esm2022/lib/core/models/api-config.model.mjs +18 -0
- package/esm2022/lib/core/models/api-request.model.mjs +2 -0
- package/esm2022/lib/core/models/api-response.model.mjs +8 -0
- package/esm2022/lib/core/models/doohbot-config.model.mjs +18 -0
- package/esm2022/lib/core/models/license.model.mjs +2 -0
- package/esm2022/lib/core/models/message.mjs +2 -0
- package/esm2022/lib/core/models/theme-config.model.mjs +2 -0
- package/esm2022/lib/core/services/core-config.service.mjs +52 -0
- package/esm2022/lib/core/services/license.service.mjs +145 -0
- package/esm2022/lib/core/services/markdown.service.mjs +64 -0
- package/esm2022/lib/core/services/theme.service.mjs +248 -0
- package/esm2022/lib/core/types/auth-mode.type.mjs +2 -0
- package/esm2022/lib/core/types/auth-status.type.mjs +5 -0
- package/esm2022/lib/core/types/chat-stream.type.mjs +2 -0
- package/esm2022/lib/core/types/message-role.type.mjs +2 -0
- package/esm2022/lib/core/types/prompt-mode.type.mjs +5 -0
- package/esm2022/lib/core/types/snackbar-error.type.mjs +5 -0
- package/esm2022/lib/core/types/tenant-resolution-strategy.type.mjs +2 -0
- package/esm2022/lib/core/utils/logger.service.mjs +42 -0
- package/esm2022/lib/doohbot-input.mjs +20 -0
- package/esm2022/lib/doohbot.component.mjs +444 -0
- package/esm2022/lib/predefined_messages.mjs +15 -0
- package/esm2022/lib/shared/chips/chips.component.mjs +28 -0
- package/esm2022/lib/shared/dialog/dialog.component.mjs +36 -0
- package/esm2022/lib/shared/dialog/dialog.service.mjs +64 -0
- package/esm2022/lib/shared/dialog/dialog.utils.mjs +85 -0
- package/esm2022/lib/shared/dropdown-menu/dropdown-menu.component.mjs +29 -0
- package/esm2022/lib/shared/input-dialog/input-dialog.component.mjs +38 -0
- package/esm2022/lib/shared/menu-item/menu-item.component.mjs +24 -0
- package/esm2022/lib/shared/pipes/simple-markdown.pipe.mjs +27 -0
- package/esm2022/lib/shared/snackbar/snackbar.component.mjs +43 -0
- package/esm2022/lib/shared/snackbar/snackbar.service.mjs +46 -0
- package/esm2022/lib/shared/snackbar/snackbar.utils.mjs +43 -0
- package/esm2022/public-api.mjs +37 -0
- package/fesm2022/aakash58-chatbot.mjs +1037 -827
- package/fesm2022/aakash58-chatbot.mjs.map +1 -1
- package/index.d.ts +3 -373
- package/lib/app/chat/chat-ui-state.service.d.ts +96 -0
- package/lib/app/chat/chat.service.d.ts +88 -0
- package/lib/app/chat/components/chat-button/chat-button.component.d.ts +16 -0
- package/lib/app/chat/components/chat-footer/chat-footer.component.d.ts +5 -0
- package/lib/app/chat/components/chat-header/chat-header.component.d.ts +24 -0
- package/lib/app/chat/components/chat-history-sidebar/chat-history-sidebar.component.d.ts +49 -0
- package/lib/app/chat/components/chat-window/chat-window.component.d.ts +107 -0
- package/lib/app/chat/components/message-input/message-input.component.d.ts +12 -0
- package/lib/app/chat/components/message-list/message-list.component.d.ts +40 -0
- package/lib/app/chat/model/chat-history.model.d.ts +51 -0
- package/lib/app/chat/model/chat-request.model.d.ts +10 -0
- package/lib/app/chat/model/chat-response.model.d.ts +9 -0
- package/lib/app/chat/model/chat-session.model.d.ts +12 -0
- package/lib/app/chat/model/chat-stream-message.model.d.ts +5 -0
- package/lib/app/chat/model/chat-stream-response.model.d.ts +10 -0
- package/lib/app/chat/services/chat-api.service.d.ts +30 -0
- package/lib/app/chat/services/chat-audio.service.d.ts +19 -0
- package/lib/app/chat/services/chat-history.service.d.ts +53 -0
- package/lib/app/login/login-form.component.d.ts +20 -0
- package/lib/app/personalization/personalization-dialog.component.d.ts +53 -0
- package/lib/app/personalization/personalization.service.d.ts +66 -0
- package/lib/app/personalization/sections/account/account-section.component.d.ts +30 -0
- package/lib/app/personalization/sections/preferences/color-picker-dialog.component.d.ts +17 -0
- package/lib/app/personalization/sections/preferences/preferences-section.component.d.ts +27 -0
- package/lib/app/personalization/sections/profile/profile-section.component.d.ts +17 -0
- package/lib/app/personalization/sections/settings/setting-section.component.d.ts +10 -0
- package/lib/app/personalization/sections/terms/terms-section.component.d.ts +5 -0
- package/lib/constant/doohbot-constant.d.ts +12 -0
- package/lib/constant/html-entities.d.ts +8 -0
- package/lib/constant/utf8.d.ts +9 -0
- package/lib/core/app-const.d.ts +11 -0
- package/lib/core/auth/account-api.service.d.ts +20 -0
- package/lib/core/auth/auth.service.d.ts +90 -0
- package/lib/core/auth/models/auth-result.model.d.ts +4 -0
- package/lib/core/auth/models/federated-login-request.model.d.ts +5 -0
- package/lib/core/auth/models/login-request.model.d.ts +6 -0
- package/lib/core/auth/storage.service.d.ts +21 -0
- package/lib/core/directives/draggable/draggable-dialog.directive.d.ts +23 -0
- package/lib/core/directives/fullscreen/fullscreen.directive.d.ts +14 -0
- package/lib/core/directives/resizable/resizable-dialog.directive.d.ts +30 -0
- package/lib/core/environments/environment.d.ts +7 -0
- package/lib/core/environments/environment.prod.d.ts +7 -0
- package/lib/core/helpers/crypto-helper.service.d.ts +12 -0
- package/lib/core/http/http-stream.service.d.ts +18 -0
- package/lib/core/http/http.service.d.ts +20 -0
- package/lib/core/interceptors/auth.interceptor.d.ts +18 -0
- package/lib/core/interceptors/license.interceptor.d.ts +11 -0
- package/lib/core/models/api-config.model.d.ts +58 -0
- package/lib/core/models/api-request.model.d.ts +77 -0
- package/lib/core/models/api-response.model.d.ts +6 -0
- package/lib/core/models/doohbot-config.model.d.ts +81 -0
- package/lib/core/models/license.model.d.ts +23 -0
- package/lib/core/models/message.d.ts +16 -0
- package/lib/core/models/theme-config.model.d.ts +28 -0
- package/lib/core/services/core-config.service.d.ts +23 -0
- package/lib/core/services/license.service.d.ts +33 -0
- package/lib/core/services/markdown.service.d.ts +8 -0
- package/lib/core/services/theme.service.d.ts +40 -0
- package/lib/core/types/auth-mode.type.d.ts +4 -0
- package/lib/core/types/auth-status.type.d.ts +4 -0
- package/lib/core/types/chat-stream.type.d.ts +4 -0
- package/lib/core/types/message-role.type.d.ts +4 -0
- package/lib/core/types/prompt-mode.type.d.ts +4 -0
- package/lib/core/types/snackbar-error.type.d.ts +4 -0
- package/lib/core/types/tenant-resolution-strategy.type.d.ts +4 -0
- package/lib/core/utils/logger.service.d.ts +11 -0
- package/lib/doohbot-input.d.ts +19 -0
- package/lib/doohbot.component.d.ts +108 -0
- package/lib/predefined_messages.d.ts +2 -0
- package/lib/shared/chips/chips.component.d.ts +10 -0
- package/lib/shared/dialog/dialog.component.d.ts +19 -0
- package/lib/shared/dialog/dialog.service.d.ts +29 -0
- package/lib/shared/dialog/dialog.utils.d.ts +41 -0
- package/lib/shared/dropdown-menu/dropdown-menu.component.d.ts +11 -0
- package/lib/shared/input-dialog/input-dialog.component.d.ts +20 -0
- package/lib/shared/menu-item/menu-item.component.d.ts +9 -0
- package/lib/shared/pipes/simple-markdown.pipe.d.ts +10 -0
- package/lib/shared/snackbar/snackbar.component.d.ts +14 -0
- package/lib/shared/snackbar/snackbar.service.d.ts +19 -0
- package/lib/shared/snackbar/snackbar.utils.d.ts +33 -0
- package/package.json +4 -2
- package/public-api.d.ts +11 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
4
|
+
import { MatMenuModule } from '@angular/material/menu';
|
|
5
|
+
import { ThemeService } from '../../../../core/services/theme.service';
|
|
6
|
+
import { inject } from '@angular/core';
|
|
7
|
+
import { ChatService } from '../../chat.service';
|
|
8
|
+
import Logger from '../../../../core/utils/logger.service';
|
|
9
|
+
import { ChatUIStateService } from '../../chat-ui-state.service';
|
|
10
|
+
import * as i0 from "@angular/core";
|
|
11
|
+
import * as i1 from "@angular/material/icon";
|
|
12
|
+
import * as i2 from "@angular/material/menu";
|
|
13
|
+
export class ChatHeaderComponent {
|
|
14
|
+
constructor() {
|
|
15
|
+
this.appHeaderLogoUrl = '';
|
|
16
|
+
this.isAuthenticated = false;
|
|
17
|
+
this.isFullScreen = false;
|
|
18
|
+
this.isNewChatDisabled = false;
|
|
19
|
+
this.toggleChat = new EventEmitter();
|
|
20
|
+
this.toggleFullScreen = new EventEmitter();
|
|
21
|
+
this.toggleHistorySidebar = new EventEmitter();
|
|
22
|
+
this.clearChat = new EventEmitter();
|
|
23
|
+
this.themeService = inject(ThemeService);
|
|
24
|
+
this.chatService = inject(ChatService);
|
|
25
|
+
this.uiState = inject(ChatUIStateService);
|
|
26
|
+
}
|
|
27
|
+
onToggleChat() {
|
|
28
|
+
this.toggleChat.emit();
|
|
29
|
+
}
|
|
30
|
+
onToggleHistorySidebar() {
|
|
31
|
+
this.toggleHistorySidebar.emit();
|
|
32
|
+
}
|
|
33
|
+
onToggleFullScreen() {
|
|
34
|
+
this.toggleFullScreen.emit();
|
|
35
|
+
}
|
|
36
|
+
onStartNewConversation() {
|
|
37
|
+
Logger.warn('Starting new conversation...');
|
|
38
|
+
this.chatService.startNewSession();
|
|
39
|
+
this.uiState.closeHistorySidebar();
|
|
40
|
+
}
|
|
41
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ChatHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
42
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: ChatHeaderComponent, isStandalone: true, selector: "app-chat-header", inputs: { appHeaderLogoUrl: "appHeaderLogoUrl", isAuthenticated: "isAuthenticated", isFullScreen: "isFullScreen", settingsMenu: "settingsMenu", isNewChatDisabled: "isNewChatDisabled" }, outputs: { toggleChat: "toggleChat", toggleFullScreen: "toggleFullScreen", toggleHistorySidebar: "toggleHistorySidebar", clearChat: "clearChat" }, ngImport: i0, template: "<div class=\"chat-header\">\r\n <div class=\"chat-title\">\r\n <img class=\"chat-logo\" style=\"width: 150px; height: 50px; margin-left: 0px\" [src]=\"appHeaderLogoUrl\"\r\n alt=\"Text-Logo\" />\r\n </div>\r\n\r\n <div class=\"chat-header-buttons\">\r\n <!-- History Button -->\r\n\r\n <!-- add chat Button -->\r\n @if (isAuthenticated) {\r\n <button class=\"header-button\" (click)=\"onStartNewConversation()\" title=\"Start new conversation\">\r\n <mat-icon>add</mat-icon>\r\n </button>\r\n }\r\n\r\n <!-- history Button -->\r\n @if (isAuthenticated) {\r\n <button class=\"header-button\" (click)=\"onToggleHistorySidebar()\" title=\"Chat History\">\r\n <mat-icon>history</mat-icon>\r\n </button>\r\n }\r\n\r\n <!-- more Button -->\r\n <button class=\"header-button\" [matMenuTriggerFor]=\"settingsMenu\">\r\n <mat-icon>more_vert</mat-icon>\r\n </button>\r\n\r\n <!-- minimize Button -->\r\n <button class=\"header-button\" (click)=\"onToggleChat()\">\r\n <mat-icon>minimize</mat-icon>\r\n </button>\r\n </div>\r\n</div>", styles: [".chat-header{display:flex;justify-content:space-between;align-items:center;padding:10px 20px;background-color:var(--background-color);color:var(--text-alt-color);-webkit-user-select:none;user-select:none}s .chat-title{display:flex;align-items:center;gap:6px;font-family:var(--font-family)}.chat-logo{width:45px;height:45px;object-fit:contain}.chat-header h2{margin:0;font-size:1.2rem;color:var(--mat-sys-on-primary);font-family:var(--font-family);font-weight:700}.chat-header-buttons{display:flex;flex-wrap:nowrap;gap:1px}.header-button{background:var(--background-color);border:1px solid var(--background-color);border-radius:50%;width:32px;height:32px;padding:0;display:flex;align-items:center;justify-content:center;cursor:pointer;color:var(--text-color);transition:all .2s cubic-bezier(.25,.8,.25,1);outline:none}.header-button mat-icon{font-size:18px;width:18px;height:18px}.header-button:hover{transform:translateY(-1px);box-shadow:0 4px 12px rgba(var(--black-rgb),.15)}.header-button:active{transform:translateY(0)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "directive", type: i2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }] }); }
|
|
43
|
+
}
|
|
44
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ChatHeaderComponent, decorators: [{
|
|
45
|
+
type: Component,
|
|
46
|
+
args: [{ selector: 'app-chat-header', standalone: true, imports: [CommonModule, MatIconModule, MatMenuModule], template: "<div class=\"chat-header\">\r\n <div class=\"chat-title\">\r\n <img class=\"chat-logo\" style=\"width: 150px; height: 50px; margin-left: 0px\" [src]=\"appHeaderLogoUrl\"\r\n alt=\"Text-Logo\" />\r\n </div>\r\n\r\n <div class=\"chat-header-buttons\">\r\n <!-- History Button -->\r\n\r\n <!-- add chat Button -->\r\n @if (isAuthenticated) {\r\n <button class=\"header-button\" (click)=\"onStartNewConversation()\" title=\"Start new conversation\">\r\n <mat-icon>add</mat-icon>\r\n </button>\r\n }\r\n\r\n <!-- history Button -->\r\n @if (isAuthenticated) {\r\n <button class=\"header-button\" (click)=\"onToggleHistorySidebar()\" title=\"Chat History\">\r\n <mat-icon>history</mat-icon>\r\n </button>\r\n }\r\n\r\n <!-- more Button -->\r\n <button class=\"header-button\" [matMenuTriggerFor]=\"settingsMenu\">\r\n <mat-icon>more_vert</mat-icon>\r\n </button>\r\n\r\n <!-- minimize Button -->\r\n <button class=\"header-button\" (click)=\"onToggleChat()\">\r\n <mat-icon>minimize</mat-icon>\r\n </button>\r\n </div>\r\n</div>", styles: [".chat-header{display:flex;justify-content:space-between;align-items:center;padding:10px 20px;background-color:var(--background-color);color:var(--text-alt-color);-webkit-user-select:none;user-select:none}s .chat-title{display:flex;align-items:center;gap:6px;font-family:var(--font-family)}.chat-logo{width:45px;height:45px;object-fit:contain}.chat-header h2{margin:0;font-size:1.2rem;color:var(--mat-sys-on-primary);font-family:var(--font-family);font-weight:700}.chat-header-buttons{display:flex;flex-wrap:nowrap;gap:1px}.header-button{background:var(--background-color);border:1px solid var(--background-color);border-radius:50%;width:32px;height:32px;padding:0;display:flex;align-items:center;justify-content:center;cursor:pointer;color:var(--text-color);transition:all .2s cubic-bezier(.25,.8,.25,1);outline:none}.header-button mat-icon{font-size:18px;width:18px;height:18px}.header-button:hover{transform:translateY(-1px);box-shadow:0 4px 12px rgba(var(--black-rgb),.15)}.header-button:active{transform:translateY(0)}\n"] }]
|
|
47
|
+
}], propDecorators: { appHeaderLogoUrl: [{
|
|
48
|
+
type: Input
|
|
49
|
+
}], isAuthenticated: [{
|
|
50
|
+
type: Input
|
|
51
|
+
}], isFullScreen: [{
|
|
52
|
+
type: Input
|
|
53
|
+
}], settingsMenu: [{
|
|
54
|
+
type: Input
|
|
55
|
+
}], isNewChatDisabled: [{
|
|
56
|
+
type: Input
|
|
57
|
+
}], toggleChat: [{
|
|
58
|
+
type: Output
|
|
59
|
+
}], toggleFullScreen: [{
|
|
60
|
+
type: Output
|
|
61
|
+
}], toggleHistorySidebar: [{
|
|
62
|
+
type: Output
|
|
63
|
+
}], clearChat: [{
|
|
64
|
+
type: Output
|
|
65
|
+
}] } });
|
|
66
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhdC1oZWFkZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZG9vaGJvdC9zcmMvbGliL2FwcC9jaGF0L2NvbXBvbmVudHMvY2hhdC1oZWFkZXIvY2hhdC1oZWFkZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZG9vaGJvdC9zcmMvbGliL2FwcC9jaGF0L2NvbXBvbmVudHMvY2hhdC1oZWFkZXIvY2hhdC1oZWFkZXIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN2RSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN2RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDdkUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN2QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDakQsT0FBTyxNQUFNLE1BQU0sdUNBQXVDLENBQUM7QUFDM0QsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7Ozs7QUFVakUsTUFBTSxPQUFPLG1CQUFtQjtJQVBoQztRQVFXLHFCQUFnQixHQUFXLEVBQUUsQ0FBQztRQUM5QixvQkFBZSxHQUFZLEtBQUssQ0FBQztRQUNqQyxpQkFBWSxHQUFZLEtBQUssQ0FBQztRQUU5QixzQkFBaUIsR0FBWSxLQUFLLENBQUM7UUFFbEMsZUFBVSxHQUFHLElBQUksWUFBWSxFQUFRLENBQUM7UUFDdEMscUJBQWdCLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUM1Qyx5QkFBb0IsR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBQ2hELGNBQVMsR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBRXhDLGlCQUFZLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ3BDLGdCQUFXLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ2pDLFlBQU8sR0FBRyxNQUFNLENBQUMsa0JBQWtCLENBQUMsQ0FBQztLQW1COUM7SUFqQkMsWUFBWTtRQUNWLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDekIsQ0FBQztJQUVELHNCQUFzQjtRQUNwQixJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDbkMsQ0FBQztJQUVELGtCQUFrQjtRQUNoQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDL0IsQ0FBQztJQUVELHNCQUFzQjtRQUNwQixNQUFNLENBQUMsSUFBSSxDQUFDLDhCQUE4QixDQUFDLENBQUM7UUFDNUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUNuQyxJQUFJLENBQUMsT0FBTyxDQUFDLG1CQUFtQixFQUFFLENBQUM7SUFDckMsQ0FBQzsrR0FoQ1UsbUJBQW1CO21HQUFuQixtQkFBbUIsd1pDbEJoQyxtbENBaUNNLHlqQ0RuQk0sWUFBWSw4QkFBRSxhQUFhLG1MQUFFLGFBQWE7OzRGQUl6QyxtQkFBbUI7a0JBUC9CLFNBQVM7K0JBQ0UsaUJBQWlCLGNBQ2YsSUFBSSxXQUNQLENBQUMsWUFBWSxFQUFFLGFBQWEsRUFBRSxhQUFhLENBQUM7OEJBSzVDLGdCQUFnQjtzQkFBeEIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxpQkFBaUI7c0JBQXpCLEtBQUs7Z0JBRUksVUFBVTtzQkFBbkIsTUFBTTtnQkFDRyxnQkFBZ0I7c0JBQXpCLE1BQU07Z0JBQ0csb0JBQW9CO3NCQUE3QixNQUFNO2dCQUNHLFNBQVM7c0JBQWxCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQgeyBNYXRJY29uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaWNvbic7XHJcbmltcG9ydCB7IE1hdE1lbnVNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9tZW51JztcclxuaW1wb3J0IHsgVGhlbWVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vLi4vY29yZS9zZXJ2aWNlcy90aGVtZS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IENoYXRTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vY2hhdC5zZXJ2aWNlJztcclxuaW1wb3J0IExvZ2dlciBmcm9tICcuLi8uLi8uLi8uLi9jb3JlL3V0aWxzL2xvZ2dlci5zZXJ2aWNlJztcclxuaW1wb3J0IHsgQ2hhdFVJU3RhdGVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vY2hhdC11aS1zdGF0ZS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgU25hY2tiYXJVdGlscyB9IGZyb20gJy4uLy4uLy4uLy4uL3NoYXJlZC9zbmFja2Jhci9zbmFja2Jhci51dGlscyc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2FwcC1jaGF0LWhlYWRlcicsXHJcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcclxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBNYXRJY29uTW9kdWxlLCBNYXRNZW51TW9kdWxlXSxcclxuICB0ZW1wbGF0ZVVybDogJy4vY2hhdC1oZWFkZXIuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL2NoYXQtaGVhZGVyLmNvbXBvbmVudC5zY3NzJ10sXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBDaGF0SGVhZGVyQ29tcG9uZW50IHtcclxuICBASW5wdXQoKSBhcHBIZWFkZXJMb2dvVXJsOiBzdHJpbmcgPSAnJztcclxuICBASW5wdXQoKSBpc0F1dGhlbnRpY2F0ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSBpc0Z1bGxTY3JlZW46IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSBzZXR0aW5nc01lbnU6IGFueTtcclxuICBASW5wdXQoKSBpc05ld0NoYXREaXNhYmxlZDogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICBAT3V0cHV0KCkgdG9nZ2xlQ2hhdCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcclxuICBAT3V0cHV0KCkgdG9nZ2xlRnVsbFNjcmVlbiA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcclxuICBAT3V0cHV0KCkgdG9nZ2xlSGlzdG9yeVNpZGViYXIgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XHJcbiAgQE91dHB1dCgpIGNsZWFyQ2hhdCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcclxuXHJcbiAgcHVibGljIHRoZW1lU2VydmljZSA9IGluamVjdChUaGVtZVNlcnZpY2UpO1xyXG4gIHB1YmxpYyBjaGF0U2VydmljZSA9IGluamVjdChDaGF0U2VydmljZSk7XHJcbiAgcHJpdmF0ZSB1aVN0YXRlID0gaW5qZWN0KENoYXRVSVN0YXRlU2VydmljZSk7XHJcblxyXG4gIG9uVG9nZ2xlQ2hhdCgpIHtcclxuICAgIHRoaXMudG9nZ2xlQ2hhdC5lbWl0KCk7XHJcbiAgfVxyXG5cclxuICBvblRvZ2dsZUhpc3RvcnlTaWRlYmFyKCkge1xyXG4gICAgdGhpcy50b2dnbGVIaXN0b3J5U2lkZWJhci5lbWl0KCk7XHJcbiAgfVxyXG5cclxuICBvblRvZ2dsZUZ1bGxTY3JlZW4oKSB7XHJcbiAgICB0aGlzLnRvZ2dsZUZ1bGxTY3JlZW4uZW1pdCgpO1xyXG4gIH1cclxuXHJcbiAgb25TdGFydE5ld0NvbnZlcnNhdGlvbigpIHtcclxuICAgIExvZ2dlci53YXJuKCdTdGFydGluZyBuZXcgY29udmVyc2F0aW9uLi4uJyk7XHJcbiAgICB0aGlzLmNoYXRTZXJ2aWNlLnN0YXJ0TmV3U2Vzc2lvbigpO1xyXG4gICAgdGhpcy51aVN0YXRlLmNsb3NlSGlzdG9yeVNpZGViYXIoKTtcclxuICB9XHJcbn1cclxuIiwiPGRpdiBjbGFzcz1cImNoYXQtaGVhZGVyXCI+XHJcbiAgPGRpdiBjbGFzcz1cImNoYXQtdGl0bGVcIj5cclxuICAgIDxpbWcgY2xhc3M9XCJjaGF0LWxvZ29cIiBzdHlsZT1cIndpZHRoOiAxNTBweDsgaGVpZ2h0OiA1MHB4OyBtYXJnaW4tbGVmdDogMHB4XCIgW3NyY109XCJhcHBIZWFkZXJMb2dvVXJsXCJcclxuICAgICAgYWx0PVwiVGV4dC1Mb2dvXCIgLz5cclxuICA8L2Rpdj5cclxuXHJcbiAgPGRpdiBjbGFzcz1cImNoYXQtaGVhZGVyLWJ1dHRvbnNcIj5cclxuICAgIDwhLS0gSGlzdG9yeSBCdXR0b24gLS0+XHJcblxyXG4gICAgPCEtLSBhZGQgY2hhdCBCdXR0b24gLS0+XHJcbiAgICBAaWYgKGlzQXV0aGVudGljYXRlZCkge1xyXG4gICAgPGJ1dHRvbiBjbGFzcz1cImhlYWRlci1idXR0b25cIiAoY2xpY2spPVwib25TdGFydE5ld0NvbnZlcnNhdGlvbigpXCIgdGl0bGU9XCJTdGFydCBuZXcgY29udmVyc2F0aW9uXCI+XHJcbiAgICAgIDxtYXQtaWNvbj5hZGQ8L21hdC1pY29uPlxyXG4gICAgPC9idXR0b24+XHJcbiAgICB9XHJcblxyXG4gICAgPCEtLSBoaXN0b3J5IEJ1dHRvbiAtLT5cclxuICAgIEBpZiAoaXNBdXRoZW50aWNhdGVkKSB7XHJcbiAgICA8YnV0dG9uIGNsYXNzPVwiaGVhZGVyLWJ1dHRvblwiIChjbGljayk9XCJvblRvZ2dsZUhpc3RvcnlTaWRlYmFyKClcIiB0aXRsZT1cIkNoYXQgSGlzdG9yeVwiPlxyXG4gICAgICA8bWF0LWljb24+aGlzdG9yeTwvbWF0LWljb24+XHJcbiAgICA8L2J1dHRvbj5cclxuICAgIH1cclxuXHJcbiAgICA8IS0tIG1vcmUgQnV0dG9uIC0tPlxyXG4gICAgPGJ1dHRvbiBjbGFzcz1cImhlYWRlci1idXR0b25cIiBbbWF0TWVudVRyaWdnZXJGb3JdPVwic2V0dGluZ3NNZW51XCI+XHJcbiAgICAgIDxtYXQtaWNvbj5tb3JlX3ZlcnQ8L21hdC1pY29uPlxyXG4gICAgPC9idXR0b24+XHJcblxyXG4gICAgPCEtLSBtaW5pbWl6ZSBCdXR0b24gLS0+XHJcbiAgICA8YnV0dG9uIGNsYXNzPVwiaGVhZGVyLWJ1dHRvblwiIChjbGljayk9XCJvblRvZ2dsZUNoYXQoKVwiPlxyXG4gICAgICA8bWF0LWljb24+bWluaW1pemU8L21hdC1pY29uPlxyXG4gICAgPC9idXR0b24+XHJcbiAgPC9kaXY+XHJcbjwvZGl2PiJdfQ==
|
package/esm2022/lib/app/chat/components/chat-history-sidebar/chat-history-sidebar.component.mjs
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { Component, EventEmitter, Input, Output, } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
import * as i1 from "../../../../shared/dialog/dialog.service";
|
|
6
|
+
import * as i2 from "@angular/material/icon";
|
|
7
|
+
export class ChatHistorySidebarComponent {
|
|
8
|
+
constructor(dialogService) {
|
|
9
|
+
this.dialogService = dialogService;
|
|
10
|
+
this.sessions = [];
|
|
11
|
+
this.isOpen = false;
|
|
12
|
+
this.userName = 'User';
|
|
13
|
+
this.isLoading = false;
|
|
14
|
+
this.hasMoreSessions = false;
|
|
15
|
+
this.isLoadingMore = false;
|
|
16
|
+
this.processingSessionId = null;
|
|
17
|
+
this.sessionSelected = new EventEmitter();
|
|
18
|
+
this.sessionDeleted = new EventEmitter();
|
|
19
|
+
this.closed = new EventEmitter();
|
|
20
|
+
this.loadMore = new EventEmitter();
|
|
21
|
+
this.refresh = new EventEmitter();
|
|
22
|
+
this.sessionRenamed = new EventEmitter();
|
|
23
|
+
this.deleteAll = new EventEmitter();
|
|
24
|
+
this.chatHistory = [];
|
|
25
|
+
}
|
|
26
|
+
ngOnInit() {
|
|
27
|
+
this.chatHistory = this.groupedSessions();
|
|
28
|
+
}
|
|
29
|
+
ngOnChanges(changes) {
|
|
30
|
+
if (changes['sessions']) {
|
|
31
|
+
this.chatHistory = this.groupedSessions();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
groupedSessions() {
|
|
35
|
+
const now = new Date();
|
|
36
|
+
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
37
|
+
const yesterday = new Date(today);
|
|
38
|
+
yesterday.setDate(yesterday.getDate() - 1);
|
|
39
|
+
const weekAgo = new Date(today);
|
|
40
|
+
weekAgo.setDate(weekAgo.getDate() - 7);
|
|
41
|
+
const groups = [
|
|
42
|
+
{ label: 'Today', sessions: [] },
|
|
43
|
+
{ label: 'Yesterday', sessions: [] },
|
|
44
|
+
{ label: 'This Week', sessions: [] },
|
|
45
|
+
{ label: 'Older', sessions: [] },
|
|
46
|
+
];
|
|
47
|
+
// Sort sessions by timestamp (newest first)
|
|
48
|
+
const sortedSessions = [...this.sessions].sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
|
|
49
|
+
sortedSessions.forEach((session) => {
|
|
50
|
+
const sessionDate = new Date(session.timestamp);
|
|
51
|
+
const sessionDayStart = new Date(sessionDate.getFullYear(), sessionDate.getMonth(), sessionDate.getDate());
|
|
52
|
+
if (sessionDayStart.getTime() === today.getTime()) {
|
|
53
|
+
groups[0].sessions.push(session);
|
|
54
|
+
}
|
|
55
|
+
else if (sessionDayStart.getTime() === yesterday.getTime()) {
|
|
56
|
+
groups[1].sessions.push(session);
|
|
57
|
+
}
|
|
58
|
+
else if (sessionDayStart.getTime() >= weekAgo.getTime()) {
|
|
59
|
+
groups[2].sessions.push(session);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
groups[3].sessions.push(session);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
// Filter out empty groups
|
|
66
|
+
return groups.filter((g) => g.sessions.length > 0);
|
|
67
|
+
}
|
|
68
|
+
onSessionClick(session) {
|
|
69
|
+
this.sessionSelected.emit(session);
|
|
70
|
+
}
|
|
71
|
+
onEditClick(event, session) {
|
|
72
|
+
event.stopPropagation();
|
|
73
|
+
this.dialogService
|
|
74
|
+
.openInput({
|
|
75
|
+
title: 'Rename Conversation',
|
|
76
|
+
message: 'Enter a new title for this conversation:',
|
|
77
|
+
initialValue: session.title,
|
|
78
|
+
placeholder: 'New title...',
|
|
79
|
+
confirmText: 'Rename',
|
|
80
|
+
})
|
|
81
|
+
.subscribe((newTitle) => {
|
|
82
|
+
if (newTitle !== null && newTitle.trim() !== '' && newTitle !== session.title) {
|
|
83
|
+
this.sessionRenamed.emit({ sessionId: session.id, newTitle: newTitle.trim() });
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
onDeleteClick(event, sessionId) {
|
|
88
|
+
event.stopPropagation();
|
|
89
|
+
this.dialogService.confirmDelete('this conversation').subscribe((confirmed) => {
|
|
90
|
+
if (confirmed) {
|
|
91
|
+
this.sessionDeleted.emit(sessionId);
|
|
92
|
+
this.chatHistory = this.groupedSessions();
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
onClose() {
|
|
97
|
+
this.closed.emit();
|
|
98
|
+
}
|
|
99
|
+
formatTime(date) {
|
|
100
|
+
return new Date(date).toLocaleTimeString('en-US', {
|
|
101
|
+
hour: 'numeric',
|
|
102
|
+
minute: '2-digit',
|
|
103
|
+
hour12: true,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
formatDate(date) {
|
|
107
|
+
return new Date(date).toLocaleDateString('en-US', {
|
|
108
|
+
month: 'short',
|
|
109
|
+
day: 'numeric',
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Handle scroll event for infinite scroll
|
|
114
|
+
*/
|
|
115
|
+
onScroll(event) {
|
|
116
|
+
const element = event.target;
|
|
117
|
+
const scrollTop = element.scrollTop;
|
|
118
|
+
const scrollHeight = element.scrollHeight;
|
|
119
|
+
const clientHeight = element.clientHeight;
|
|
120
|
+
// Check if scrolled near bottom (within 100px)
|
|
121
|
+
const scrollBottom = scrollHeight - scrollTop - clientHeight;
|
|
122
|
+
if (scrollBottom < 100 && this.hasMoreSessions && !this.isLoadingMore && !this.isLoading) {
|
|
123
|
+
this.loadMore.emit();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Handle manual refresh
|
|
128
|
+
*/
|
|
129
|
+
onRefresh() {
|
|
130
|
+
this.refresh.emit();
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Handle clear all history
|
|
134
|
+
*/
|
|
135
|
+
onClearAllClick() {
|
|
136
|
+
this.dialogService
|
|
137
|
+
.open({
|
|
138
|
+
title: 'Clear All History',
|
|
139
|
+
message: 'Are you sure you want to delete all chat history? This action cannot be undone.',
|
|
140
|
+
confirmText: 'Clear All',
|
|
141
|
+
cancelText: 'Cancel',
|
|
142
|
+
confirmButtonColor: 'warn',
|
|
143
|
+
icon: 'delete_sweep',
|
|
144
|
+
})
|
|
145
|
+
.subscribe((confirmed) => {
|
|
146
|
+
if (confirmed) {
|
|
147
|
+
this.deleteAll.emit();
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ChatHistorySidebarComponent, deps: [{ token: i1.DialogService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
152
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: ChatHistorySidebarComponent, isStandalone: true, selector: "app-chat-history-sidebar", inputs: { sessions: "sessions", isOpen: "isOpen", userName: "userName", isLoading: "isLoading", hasMoreSessions: "hasMoreSessions", isLoadingMore: "isLoadingMore", processingSessionId: "processingSessionId" }, outputs: { sessionSelected: "sessionSelected", sessionDeleted: "sessionDeleted", closed: "closed", loadMore: "loadMore", refresh: "refresh", sessionRenamed: "sessionRenamed", deleteAll: "deleteAll" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"history-sidebar\" [class.open]=\"isOpen\">\r\n <div class=\"sidebar-header\">\r\n <div class=\"marquee-container\" style=\"flex: 1; margin-right: 10px\">\r\n <h3 class=\"marquee-text\">{{ userName }}'s Chat History</h3>\r\n </div>\r\n <button class=\"refresh-btn\" (click)=\"onRefresh()\" title=\"Refresh history\">\r\n <mat-icon>refresh</mat-icon>\r\n </button>\r\n\r\n <button class=\"close-btn\" (click)=\"onClose()\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n </div>\r\n\r\n <div class=\"sidebar-content\" (scroll)=\"onScroll($event)\">\r\n @if (isLoading) {\r\n <div class=\"loader-container\">\r\n <div class=\"loader\"></div>\r\n <p>Loading history...</p>\r\n </div>\r\n }\r\n\r\n @if (!isLoading && sessions.length === 0) {\r\n <div class=\"empty-state\">\r\n <mat-icon>history</mat-icon>\r\n <p>No chat history yet</p>\r\n <span>Start a conversation to see it here</span>\r\n </div>\r\n }\r\n\r\n @if (!isLoading) {\r\n @for (group of chatHistory; track group.label) {\r\n <div class=\"session-group\">\r\n <div class=\"group-label\">{{ group.label }}</div>\r\n <div class=\"session-list\">\r\n @for (session of group.sessions; track session.id) {\r\n <div class=\"session-item\" (click)=\"onSessionClick(session)\">\r\n <div class=\"session-content\">\r\n <div class=\"session-title\">{{ session.title }}</div>\r\n <div class=\"session-time\">\r\n {{ formatTime(session.timestamp) }} \u00B7 {{ formatDate(session.timestamp) }}\r\n </div>\r\n </div>\r\n <div class=\"session-actions\">\r\n <button class=\"edit-btn\" [disabled]=\"processingSessionId === session.id\"\r\n (click)=\"onEditClick($event, session)\" title=\"Edit title\">\r\n @if (processingSessionId !== session.id) {\r\n <mat-icon>edit</mat-icon>\r\n } @else {\r\n <div class=\"loader-tiny\"></div>\r\n }\r\n </button>\r\n <button class=\"delete-btn\" [disabled]=\"processingSessionId === session.id\"\r\n (click)=\"onDeleteClick($event, session.id)\" title=\"Delete conversation\">\r\n @if (processingSessionId !== session.id) {\r\n <mat-icon>delete</mat-icon>\r\n } @else {\r\n <div class=\"loader-tiny\"></div>\r\n }\r\n </button>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n }\r\n\r\n <!-- Loading more indicator -->\r\n @if (isLoadingMore) {\r\n <div class=\"loading-more\">\r\n <div class=\"loader-small\"></div>\r\n <p>Loading more...</p>\r\n </div>\r\n }\r\n </div>\r\n</div>", styles: [":host{display:block;height:100%;width:100%}.history-sidebar{top:0;right:0;display:none;height:100%;width:100%;background:var(--background-color);flex-direction:column}.history-sidebar.open{display:flex}.sidebar-header{display:flex;justify-content:space-between;align-items:center;padding:20px;border-bottom:1px solid var(--border-color)}.sidebar-header h3{margin:0;font-size:16px;font-weight:600;color:var(--text-color);font-family:var(--font-family);display:inline-block}.sidebar-content{flex:1 1 auto;overflow-y:auto;padding:10px 0;scroll-behavior:smooth}.close-btn{background:none;border:none;cursor:pointer;padding:4px;display:flex;align-items:center;justify-content:center;border-radius:50%;transition:background .2s}.close-btn:hover{background:var(--bot-message-color)}.close-btn mat-icon{color:var(--text-color);font-size:20px;width:20px;height:20px}.refresh-btn{background:none;border:none;cursor:pointer;padding:4px;display:flex;align-items:center;justify-content:center;border-radius:50%;transition:background .2s;margin-right:8px}.refresh-btn:hover{background:var(--bot-message-color)}.refresh-btn mat-icon{color:var(--text-color);font-size:20px;width:20px;height:20px}.clear-all-btn{background:none;border:none;cursor:pointer;padding:4px;display:flex;align-items:center;justify-content:center;border-radius:50%;transition:background .2s;margin-right:8px}.clear-all-btn:hover{background:var(--bot-message-color)}.clear-all-btn mat-icon{color:var(--text-color);font-size:20px;width:20px;height:20px}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;text-align:center}.empty-state mat-icon{font-size:64px;width:64px;height:64px;color:var(--secondary-text-color);margin-bottom:16px}.empty-state p{margin:0 0 8px;font-size:16px;font-weight:500;color:var(--text-color);font-family:var(--font-family)}.empty-state span{font-size:14px;color:var(--secondary-text-color);font-family:var(--font-family)}.session-group{margin-bottom:24px}.group-label{padding:8px 20px;font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;color:var(--secondary-text-color);font-family:var(--font-family)}.session-list{display:flex;flex-direction:column}.session-item{display:flex;align-items:center;justify-content:space-between;padding:12px 20px;cursor:pointer;transition:background .2s;gap:8px}.session-item:hover{background:var(--bot-message-color)}.session-content{flex:1;min-width:0}.session-title{font-size:14px;font-weight:500;color:var(--text-color);font-family:var(--font-family);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-bottom:4px}.session-time{font-size:12px;color:var(--secondary-text-color);font-family:var(--font-family)}.session-actions{display:flex;gap:4px;opacity:0;transition:opacity .2s}.session-item:hover .session-actions{opacity:1}.edit-btn,.delete-btn{background:none;border:none;cursor:pointer;padding:4px;display:flex;align-items:center;justify-content:center;border-radius:50%;transition:all .2s}.edit-btn:hover{background:var(--bot-message-color)}.delete-btn:hover{background:var(--light-red)}.edit-btn mat-icon,.delete-btn mat-icon{color:var(--secondary-text-color);font-size:18px;width:18px;height:18px}.edit-btn:hover mat-icon{color:var(--primary-color)}.delete-btn:hover mat-icon{color:var(--red)}.sidebar-content::-webkit-scrollbar{width:6px}.sidebar-content::-webkit-scrollbar-track{background:transparent}.sidebar-content::-webkit-scrollbar-thumb{background:rgba(var(--black-rgb),.1);border-radius:10px}.sidebar-content::-webkit-scrollbar-thumb:hover{background:rgba(var(--black-rgb),.1);border-radius:10px}.loader-container{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 20px;color:var(--secondary-text-color)}.loader-container p{margin-top:15px;font-size:14px;font-weight:500}.loader{width:32px;height:32px;border:3px solid rgba(var(--border-color-rgb),.1);border-radius:50%;border-top-color:var(--primary-color);animation:spin 1s ease-in-out infinite}@keyframes spin{to{transform:rotate(360deg)}}.loading-more{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:20px;color:var(--secondary-text-color)}.loading-more p{margin-top:10px;font-size:13px;font-weight:500}.loader-small{width:24px;height:24px;border:3px solid rgba(var(--border-color-rgb),.1);border-radius:50%;border-top-color:var(--primary-color);animation:spin 1s ease-in-out infinite}.loader-tiny{width:14px;height:14px;border:2px solid rgba(var(--border-color-rgb),.1);border-radius:50%;border-top-color:var(--primary-color);animation:spin 1s ease-in-out infinite}.edit-btn:disabled,.delete-btn:disabled{cursor:not-allowed;opacity:.6}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] }); }
|
|
153
|
+
}
|
|
154
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ChatHistorySidebarComponent, decorators: [{
|
|
155
|
+
type: Component,
|
|
156
|
+
args: [{ selector: 'app-chat-history-sidebar', standalone: true, imports: [CommonModule, MatIconModule], template: "<div class=\"history-sidebar\" [class.open]=\"isOpen\">\r\n <div class=\"sidebar-header\">\r\n <div class=\"marquee-container\" style=\"flex: 1; margin-right: 10px\">\r\n <h3 class=\"marquee-text\">{{ userName }}'s Chat History</h3>\r\n </div>\r\n <button class=\"refresh-btn\" (click)=\"onRefresh()\" title=\"Refresh history\">\r\n <mat-icon>refresh</mat-icon>\r\n </button>\r\n\r\n <button class=\"close-btn\" (click)=\"onClose()\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n </div>\r\n\r\n <div class=\"sidebar-content\" (scroll)=\"onScroll($event)\">\r\n @if (isLoading) {\r\n <div class=\"loader-container\">\r\n <div class=\"loader\"></div>\r\n <p>Loading history...</p>\r\n </div>\r\n }\r\n\r\n @if (!isLoading && sessions.length === 0) {\r\n <div class=\"empty-state\">\r\n <mat-icon>history</mat-icon>\r\n <p>No chat history yet</p>\r\n <span>Start a conversation to see it here</span>\r\n </div>\r\n }\r\n\r\n @if (!isLoading) {\r\n @for (group of chatHistory; track group.label) {\r\n <div class=\"session-group\">\r\n <div class=\"group-label\">{{ group.label }}</div>\r\n <div class=\"session-list\">\r\n @for (session of group.sessions; track session.id) {\r\n <div class=\"session-item\" (click)=\"onSessionClick(session)\">\r\n <div class=\"session-content\">\r\n <div class=\"session-title\">{{ session.title }}</div>\r\n <div class=\"session-time\">\r\n {{ formatTime(session.timestamp) }} \u00B7 {{ formatDate(session.timestamp) }}\r\n </div>\r\n </div>\r\n <div class=\"session-actions\">\r\n <button class=\"edit-btn\" [disabled]=\"processingSessionId === session.id\"\r\n (click)=\"onEditClick($event, session)\" title=\"Edit title\">\r\n @if (processingSessionId !== session.id) {\r\n <mat-icon>edit</mat-icon>\r\n } @else {\r\n <div class=\"loader-tiny\"></div>\r\n }\r\n </button>\r\n <button class=\"delete-btn\" [disabled]=\"processingSessionId === session.id\"\r\n (click)=\"onDeleteClick($event, session.id)\" title=\"Delete conversation\">\r\n @if (processingSessionId !== session.id) {\r\n <mat-icon>delete</mat-icon>\r\n } @else {\r\n <div class=\"loader-tiny\"></div>\r\n }\r\n </button>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n }\r\n\r\n <!-- Loading more indicator -->\r\n @if (isLoadingMore) {\r\n <div class=\"loading-more\">\r\n <div class=\"loader-small\"></div>\r\n <p>Loading more...</p>\r\n </div>\r\n }\r\n </div>\r\n</div>", styles: [":host{display:block;height:100%;width:100%}.history-sidebar{top:0;right:0;display:none;height:100%;width:100%;background:var(--background-color);flex-direction:column}.history-sidebar.open{display:flex}.sidebar-header{display:flex;justify-content:space-between;align-items:center;padding:20px;border-bottom:1px solid var(--border-color)}.sidebar-header h3{margin:0;font-size:16px;font-weight:600;color:var(--text-color);font-family:var(--font-family);display:inline-block}.sidebar-content{flex:1 1 auto;overflow-y:auto;padding:10px 0;scroll-behavior:smooth}.close-btn{background:none;border:none;cursor:pointer;padding:4px;display:flex;align-items:center;justify-content:center;border-radius:50%;transition:background .2s}.close-btn:hover{background:var(--bot-message-color)}.close-btn mat-icon{color:var(--text-color);font-size:20px;width:20px;height:20px}.refresh-btn{background:none;border:none;cursor:pointer;padding:4px;display:flex;align-items:center;justify-content:center;border-radius:50%;transition:background .2s;margin-right:8px}.refresh-btn:hover{background:var(--bot-message-color)}.refresh-btn mat-icon{color:var(--text-color);font-size:20px;width:20px;height:20px}.clear-all-btn{background:none;border:none;cursor:pointer;padding:4px;display:flex;align-items:center;justify-content:center;border-radius:50%;transition:background .2s;margin-right:8px}.clear-all-btn:hover{background:var(--bot-message-color)}.clear-all-btn mat-icon{color:var(--text-color);font-size:20px;width:20px;height:20px}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;text-align:center}.empty-state mat-icon{font-size:64px;width:64px;height:64px;color:var(--secondary-text-color);margin-bottom:16px}.empty-state p{margin:0 0 8px;font-size:16px;font-weight:500;color:var(--text-color);font-family:var(--font-family)}.empty-state span{font-size:14px;color:var(--secondary-text-color);font-family:var(--font-family)}.session-group{margin-bottom:24px}.group-label{padding:8px 20px;font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;color:var(--secondary-text-color);font-family:var(--font-family)}.session-list{display:flex;flex-direction:column}.session-item{display:flex;align-items:center;justify-content:space-between;padding:12px 20px;cursor:pointer;transition:background .2s;gap:8px}.session-item:hover{background:var(--bot-message-color)}.session-content{flex:1;min-width:0}.session-title{font-size:14px;font-weight:500;color:var(--text-color);font-family:var(--font-family);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-bottom:4px}.session-time{font-size:12px;color:var(--secondary-text-color);font-family:var(--font-family)}.session-actions{display:flex;gap:4px;opacity:0;transition:opacity .2s}.session-item:hover .session-actions{opacity:1}.edit-btn,.delete-btn{background:none;border:none;cursor:pointer;padding:4px;display:flex;align-items:center;justify-content:center;border-radius:50%;transition:all .2s}.edit-btn:hover{background:var(--bot-message-color)}.delete-btn:hover{background:var(--light-red)}.edit-btn mat-icon,.delete-btn mat-icon{color:var(--secondary-text-color);font-size:18px;width:18px;height:18px}.edit-btn:hover mat-icon{color:var(--primary-color)}.delete-btn:hover mat-icon{color:var(--red)}.sidebar-content::-webkit-scrollbar{width:6px}.sidebar-content::-webkit-scrollbar-track{background:transparent}.sidebar-content::-webkit-scrollbar-thumb{background:rgba(var(--black-rgb),.1);border-radius:10px}.sidebar-content::-webkit-scrollbar-thumb:hover{background:rgba(var(--black-rgb),.1);border-radius:10px}.loader-container{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 20px;color:var(--secondary-text-color)}.loader-container p{margin-top:15px;font-size:14px;font-weight:500}.loader{width:32px;height:32px;border:3px solid rgba(var(--border-color-rgb),.1);border-radius:50%;border-top-color:var(--primary-color);animation:spin 1s ease-in-out infinite}@keyframes spin{to{transform:rotate(360deg)}}.loading-more{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:20px;color:var(--secondary-text-color)}.loading-more p{margin-top:10px;font-size:13px;font-weight:500}.loader-small{width:24px;height:24px;border:3px solid rgba(var(--border-color-rgb),.1);border-radius:50%;border-top-color:var(--primary-color);animation:spin 1s ease-in-out infinite}.loader-tiny{width:14px;height:14px;border:2px solid rgba(var(--border-color-rgb),.1);border-radius:50%;border-top-color:var(--primary-color);animation:spin 1s ease-in-out infinite}.edit-btn:disabled,.delete-btn:disabled{cursor:not-allowed;opacity:.6}\n"] }]
|
|
157
|
+
}], ctorParameters: () => [{ type: i1.DialogService }], propDecorators: { sessions: [{
|
|
158
|
+
type: Input
|
|
159
|
+
}], isOpen: [{
|
|
160
|
+
type: Input
|
|
161
|
+
}], userName: [{
|
|
162
|
+
type: Input
|
|
163
|
+
}], isLoading: [{
|
|
164
|
+
type: Input
|
|
165
|
+
}], hasMoreSessions: [{
|
|
166
|
+
type: Input
|
|
167
|
+
}], isLoadingMore: [{
|
|
168
|
+
type: Input
|
|
169
|
+
}], processingSessionId: [{
|
|
170
|
+
type: Input
|
|
171
|
+
}], sessionSelected: [{
|
|
172
|
+
type: Output
|
|
173
|
+
}], sessionDeleted: [{
|
|
174
|
+
type: Output
|
|
175
|
+
}], closed: [{
|
|
176
|
+
type: Output
|
|
177
|
+
}], loadMore: [{
|
|
178
|
+
type: Output
|
|
179
|
+
}], refresh: [{
|
|
180
|
+
type: Output
|
|
181
|
+
}], sessionRenamed: [{
|
|
182
|
+
type: Output
|
|
183
|
+
}], deleteAll: [{
|
|
184
|
+
type: Output
|
|
185
|
+
}] } });
|
|
186
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhdC1oaXN0b3J5LXNpZGViYXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZG9vaGJvdC9zcmMvbGliL2FwcC9jaGF0L2NvbXBvbmVudHMvY2hhdC1oaXN0b3J5LXNpZGViYXIvY2hhdC1oaXN0b3J5LXNpZGViYXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZG9vaGJvdC9zcmMvbGliL2FwcC9jaGF0L2NvbXBvbmVudHMvY2hhdC1oaXN0b3J5LXNpZGViYXIvY2hhdC1oaXN0b3J5LXNpZGViYXIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFDVCxZQUFZLEVBQ1osS0FBSyxFQUlMLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHdCQUF3QixDQUFDOzs7O0FBV3ZELE1BQU0sT0FBTywyQkFBMkI7SUFtQnRDLFlBQW9CLGFBQTRCO1FBQTVCLGtCQUFhLEdBQWIsYUFBYSxDQUFlO1FBbEJ2QyxhQUFRLEdBQWtCLEVBQUUsQ0FBQztRQUM3QixXQUFNLEdBQVksS0FBSyxDQUFDO1FBQ3hCLGFBQVEsR0FBVyxNQUFNLENBQUM7UUFDMUIsY0FBUyxHQUFZLEtBQUssQ0FBQztRQUMzQixvQkFBZSxHQUFZLEtBQUssQ0FBQztRQUNqQyxrQkFBYSxHQUFZLEtBQUssQ0FBQztRQUMvQix3QkFBbUIsR0FBa0IsSUFBSSxDQUFDO1FBRXpDLG9CQUFlLEdBQUcsSUFBSSxZQUFZLEVBQWUsQ0FBQztRQUNsRCxtQkFBYyxHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7UUFDNUMsV0FBTSxHQUFHLElBQUksWUFBWSxFQUFRLENBQUM7UUFDbEMsYUFBUSxH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QUFNO2dCQUNHLE1BQU07c0JBQWYsTUFBTTtnQkFDRyxRQUFRO3NCQUFqQixNQUFNO2dCQUNHLE9BQU87c0JBQWhCLE1BQU07Z0JBQ0csY0FBYztzQkFBdkIsTUFBTTtnQkFDRyxTQUFTO3NCQUFsQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBDb21wb25lbnQsXHJcbiAgRXZlbnRFbWl0dGVyLFxyXG4gIElucHV0LFxyXG4gIE9uSW5pdCxcclxuICBPbkNoYW5nZXMsXHJcbiAgU2ltcGxlQ2hhbmdlcyxcclxuICBPdXRwdXQsXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcbmltcG9ydCB7IE1hdEljb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pY29uJztcclxuaW1wb3J0IHsgRGlhbG9nU2VydmljZSB9IGZyb20gJy4uLy4uLy4uLy4uL3NoYXJlZC9kaWFsb2cvZGlhbG9nLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBDaGF0U2Vzc2lvbiwgQ2hhdFNlc3Npb25Hcm91cCB9IGZyb20gJy4uLy4uL21vZGVsL2NoYXQtc2Vzc2lvbi5tb2RlbCc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2FwcC1jaGF0LWhpc3Rvcnktc2lkZWJhcicsXHJcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcclxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBNYXRJY29uTW9kdWxlXSxcclxuICB0ZW1wbGF0ZVVybDogJy4vY2hhdC1oaXN0b3J5LXNpZGViYXIuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL2NoYXQtaGlzdG9yeS1zaWRlYmFyLmNvbXBvbmVudC5zY3NzJ10sXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBDaGF0SGlzdG9yeVNpZGViYXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XHJcbiAgQElucHV0KCkgc2Vzc2lvbnM6IENoYXRTZXNzaW9uW10gPSBbXTtcclxuICBASW5wdXQoKSBpc09wZW46IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSB1c2VyTmFtZTogc3RyaW5nID0gJ1VzZXInO1xyXG4gIEBJbnB1dCgpIGlzTG9hZGluZzogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIGhhc01vcmVTZXNzaW9uczogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIGlzTG9hZGluZ01vcmU6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSBwcm9jZXNzaW5nU2Vzc2lvbklkOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcclxuXHJcbiAgQE91dHB1dCgpIHNlc3Npb25TZWxlY3RlZCA9IG5ldyBFdmVudEVtaXR0ZXI8Q2hhdFNlc3Npb24+KCk7XHJcbiAgQE91dHB1dCgpIHNlc3Npb25EZWxldGVkID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XHJcbiAgQE91dHB1dCgpIGNsb3NlZCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcclxuICBAT3V0cHV0KCkgbG9hZE1vcmUgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XHJcbiAgQE91dHB1dCgpIHJlZnJlc2ggPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XHJcbiAgQE91dHB1dCgpIHNlc3Npb25SZW5hbWVkID0gbmV3IEV2ZW50RW1pdHRlcjx7IHNlc3Npb25JZDogc3RyaW5nOyBuZXdUaXRsZTogc3RyaW5nIH0+KCk7XHJcbiAgQE91dHB1dCgpIGRlbGV0ZUFsbCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcclxuXHJcbiAgY2hhdEhpc3Rvcnk6IENoYXRTZXNzaW9uR3JvdXBbXSA9IFtdO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGRpYWxvZ1NlcnZpY2U6IERpYWxvZ1NlcnZpY2UpIHsgfVxyXG5cclxuICBuZ09uSW5pdCgpOiB2b2lkIHtcclxuICAgIHRoaXMuY2hhdEhpc3RvcnkgPSB0aGlzLmdyb3VwZWRTZXNzaW9ucygpO1xyXG4gIH1cclxuXHJcbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xyXG4gICAgaWYgKGNoYW5nZXNbJ3Nlc3Npb25zJ10pIHtcclxuICAgICAgdGhpcy5jaGF0SGlzdG9yeSA9IHRoaXMuZ3JvdXBlZFNlc3Npb25zKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBncm91cGVkU2Vzc2lvbnMoKTogQ2hhdFNlc3Npb25Hcm91cFtdIHtcclxuICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCk7XHJcbiAgICBjb25zdCB0b2RheSA9IG5ldyBEYXRlKG5vdy5nZXRGdWxsWWVhcigpLCBub3cuZ2V0TW9udGgoKSwgbm93LmdldERhdGUoKSk7XHJcbiAgICBjb25zdCB5ZXN0ZXJkYXkgPSBuZXcgRGF0ZSh0b2RheSk7XHJcbiAgICB5ZXN0ZXJkYXkuc2V0RGF0ZSh5ZXN0ZXJkYXkuZ2V0RGF0ZSgpIC0gMSk7XHJcbiAgICBjb25zdCB3ZWVrQWdvID0gbmV3IERhdGUodG9kYXkpO1xyXG4gICAgd2Vla0Fnby5zZXREYXRlKHdlZWtBZ28uZ2V0RGF0ZSgpIC0gNyk7XHJcblxyXG4gICAgY29uc3QgZ3JvdXBzOiBDaGF0U2Vzc2lvbkdyb3VwW10gPSBbXHJcbiAgICAgIHsgbGFiZWw6ICdUb2RheScsIHNlc3Npb25zOiBbXSB9LFxyXG4gICAgICB7IGxhYmVsOiAnWWVzdGVyZGF5Jywgc2Vzc2lvbnM6IFtdIH0sXHJcbiAgICAgIHsgbGFiZWw6ICdUaGlzIFdlZWsnLCBzZXNzaW9uczogW10gfSxcclxuICAgICAgeyBsYWJlbDogJ09sZGVyJywgc2Vzc2lvbnM6IFtdIH0sXHJcbiAgICBdO1xyXG5cclxuICAgIC8vIFNvcnQgc2Vzc2lvbnMgYnkgdGltZXN0YW1wIChuZXdlc3QgZmlyc3QpXHJcbiAgICBjb25zdCBzb3J0ZWRTZXNzaW9ucyA9IFsuLi50aGlzLnNlc3Npb25zXS5zb3J0KFxyXG4gICAgICAoYSwgYikgPT4gYi50aW1lc3RhbXAuZ2V0VGltZSgpIC0gYS50aW1lc3RhbXAuZ2V0VGltZSgpLFxyXG4gICAgKTtcclxuXHJcbiAgICBzb3J0ZWRTZXNzaW9ucy5mb3JFYWNoKChzZXNzaW9uKSA9PiB7XHJcbiAgICAgIGNvbnN0IHNlc3Npb25EYXRlID0gbmV3IERhdGUoc2Vzc2lvbi50aW1lc3RhbXApO1xyXG4gICAgICBjb25zdCBzZXNzaW9uRGF5U3RhcnQgPSBuZXcgRGF0ZShcclxuICAgICAgICBzZXNzaW9uRGF0ZS5nZXRGdWxsWWVhcigpLFxyXG4gICAgICAgIHNlc3Npb25EYXRlLmdldE1vbnRoKCksXHJcbiAgICAgICAgc2Vzc2lvbkRhdGUuZ2V0RGF0ZSgpLFxyXG4gICAgICApO1xyXG5cclxuICAgICAgaWYgKHNlc3Npb25EYXlTdGFydC5nZXRUaW1lKCkgPT09IHRvZGF5LmdldFRpbWUoKSkge1xyXG4gICAgICAgIGdyb3Vwc1swXS5zZXNzaW9ucy5wdXNoKHNlc3Npb24pO1xyXG4gICAgICB9IGVsc2UgaWYgKHNlc3Npb25EYXlTdGFydC5nZXRUaW1lKCkgPT09IHllc3RlcmRheS5nZXRUaW1lKCkpIHtcclxuICAgICAgICBncm91cHNbMV0uc2Vzc2lvbnMucHVzaChzZXNzaW9uKTtcclxuICAgICAgfSBlbHNlIGlmIChzZXNzaW9uRGF5U3RhcnQuZ2V0VGltZSgpID49IHdlZWtBZ28uZ2V0VGltZSgpKSB7XHJcbiAgICAgICAgZ3JvdXBzWzJdLnNlc3Npb25zLnB1c2goc2Vzc2lvbik7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgZ3JvdXBzWzNdLnNlc3Npb25zLnB1c2goc2Vzc2lvbik7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIC8vIEZpbHRlciBvdXQgZW1wdHkgZ3JvdXBzXHJcbiAgICByZXR1cm4gZ3JvdXBzLmZpbHRlcigoZykgPT4gZy5zZXNzaW9ucy5sZW5ndGggPiAwKTtcclxuICB9XHJcblxyXG4gIG9uU2Vzc2lvbkNsaWNrKHNlc3Npb246IENoYXRTZXNzaW9uKTogdm9pZCB7XHJcbiAgICB0aGlzLnNlc3Npb25TZWxlY3RlZC5lbWl0KHNlc3Npb24pO1xyXG4gIH1cclxuXHJcbiAgb25FZGl0Q2xpY2soZXZlbnQ6IEV2ZW50LCBzZXNzaW9uOiBDaGF0U2Vzc2lvbik6IHZvaWQge1xyXG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICB0aGlzLmRpYWxvZ1NlcnZpY2VcclxuICAgICAgLm9wZW5JbnB1dCh7XHJcbiAgICAgICAgdGl0bGU6ICdSZW5hbWUgQ29udmVyc2F0aW9uJyxcclxuICAgICAgICBtZXNzYWdlOiAnRW50ZXIgYSBuZXcgdGl0bGUgZm9yIHRoaXMgY29udmVyc2F0aW9uOicsXHJcbiAgICAgICAgaW5pdGlhbFZhbHVlOiBzZXNzaW9uLnRpdGxlLFxyXG4gICAgICAgIHBsYWNlaG9sZGVyOiAnTmV3IHRpdGxlLi4uJyxcclxuICAgICAgICBjb25maXJtVGV4dDogJ1JlbmFtZScsXHJcbiAgICAgIH0pXHJcbiAgICAgIC5zdWJzY3JpYmUoKG5ld1RpdGxlKSA9PiB7XHJcbiAgICAgICAgaWYgKG5ld1RpdGxlICE9PSBudWxsICYmIG5ld1RpdGxlLnRyaW0oKSAhPT0gJycgJiYgbmV3VGl0bGUgIT09IHNlc3Npb24udGl0bGUpIHtcclxuICAgICAgICAgIHRoaXMuc2Vzc2lvblJlbmFtZWQuZW1pdCh7IHNlc3Npb25JZDogc2Vzc2lvbi5pZCwgbmV3VGl0bGU6IG5ld1RpdGxlLnRyaW0oKSB9KTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgb25EZWxldGVDbGljayhldmVudDogRXZlbnQsIHNlc3Npb25JZDogc3RyaW5nKTogdm9pZCB7XHJcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgIHRoaXMuZGlhbG9nU2VydmljZS5jb25maXJtRGVsZXRlKCd0aGlzIGNvbnZlcnNhdGlvbicpLnN1YnNjcmliZSgoY29uZmlybWVkKSA9PiB7XHJcbiAgICAgIGlmIChjb25maXJtZWQpIHtcclxuICAgICAgICB0aGlzLnNlc3Npb25EZWxldGVkLmVtaXQoc2Vzc2lvbklkKTtcclxuICAgICAgICB0aGlzLmNoYXRIaXN0b3J5ID0gdGhpcy5ncm91cGVkU2Vzc2lvbnMoKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBvbkNsb3NlKCk6IHZvaWQge1xyXG4gICAgdGhpcy5jbG9zZWQuZW1pdCgpO1xyXG4gIH1cclxuXHJcbiAgZm9ybWF0VGltZShkYXRlOiBEYXRlKTogc3RyaW5nIHtcclxuICAgIHJldHVybiBuZXcgRGF0ZShkYXRlKS50b0xvY2FsZVRpbWVTdHJpbmcoJ2VuLVVTJywge1xyXG4gICAgICBob3VyOiAnbnVtZXJpYycsXHJcbiAgICAgIG1pbnV0ZTogJzItZGlnaXQnLFxyXG4gICAgICBob3VyMTI6IHRydWUsXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIGZvcm1hdERhdGUoZGF0ZTogRGF0ZSk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gbmV3IERhdGUoZGF0ZSkudG9Mb2NhbGVEYXRlU3RyaW5nKCdlbi1VUycsIHtcclxuICAgICAgbW9udGg6ICdzaG9ydCcsXHJcbiAgICAgIGRheTogJ251bWVyaWMnLFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIYW5kbGUgc2Nyb2xsIGV2ZW50IGZvciBpbmZpbml0ZSBzY3JvbGxcclxuICAgKi9cclxuICBvblNjcm9sbChldmVudDogRXZlbnQpOiB2b2lkIHtcclxuICAgIGNvbnN0IGVsZW1lbnQgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XHJcbiAgICBjb25zdCBzY3JvbGxUb3AgPSBlbGVtZW50LnNjcm9sbFRvcDtcclxuICAgIGNvbnN0IHNjcm9sbEhlaWdodCA9IGVsZW1lbnQuc2Nyb2xsSGVpZ2h0O1xyXG4gICAgY29uc3QgY2xpZW50SGVpZ2h0ID0gZWxlbWVudC5jbGllbnRIZWlnaHQ7XHJcblxyXG4gICAgLy8gQ2hlY2sgaWYgc2Nyb2xsZWQgbmVhciBib3R0b20gKHdpdGhpbiAxMDBweClcclxuICAgIGNvbnN0IHNjcm9sbEJvdHRvbSA9IHNjcm9sbEhlaWdodCAtIHNjcm9sbFRvcCAtIGNsaWVudEhlaWdodDtcclxuICAgIGlmIChzY3JvbGxCb3R0b20gPCAxMDAgJiYgdGhpcy5oYXNNb3JlU2Vzc2lvbnMgJiYgIXRoaXMuaXNMb2FkaW5nTW9yZSAmJiAhdGhpcy5pc0xvYWRpbmcpIHtcclxuICAgICAgdGhpcy5sb2FkTW9yZS5lbWl0KCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIYW5kbGUgbWFudWFsIHJlZnJlc2hcclxuICAgKi9cclxuICBvblJlZnJlc2goKTogdm9pZCB7XHJcbiAgICB0aGlzLnJlZnJlc2guZW1pdCgpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSGFuZGxlIGNsZWFyIGFsbCBoaXN0b3J5XHJcbiAgICovXHJcbiAgb25DbGVhckFsbENsaWNrKCk6IHZvaWQge1xyXG4gICAgdGhpcy5kaWFsb2dTZXJ2aWNlXHJcbiAgICAgIC5vcGVuKHtcclxuICAgICAgICB0aXRsZTogJ0NsZWFyIEFsbCBIaXN0b3J5JyxcclxuICAgICAgICBtZXNzYWdlOiAnQXJlIHlvdSBzdXJlIHlvdSB3YW50IHRvIGRlbGV0ZSBhbGwgY2hhdCBoaXN0b3J5PyBUaGlzIGFjdGlvbiBjYW5ub3QgYmUgdW5kb25lLicsXHJcbiAgICAgICAgY29uZmlybVRleHQ6ICdDbGVhciBBbGwnLFxyXG4gICAgICAgIGNhbmNlbFRleHQ6ICdDYW5jZWwnLFxyXG4gICAgICAgIGNvbmZpcm1CdXR0b25Db2xvcjogJ3dhcm4nLFxyXG4gICAgICAgIGljb246ICdkZWxldGVfc3dlZXAnLFxyXG4gICAgICB9KVxyXG4gICAgICAuc3Vic2NyaWJlKChjb25maXJtZWQ6IGJvb2xlYW4gfCB1bmRlZmluZWQpID0+IHtcclxuICAgICAgICBpZiAoY29uZmlybWVkKSB7XHJcbiAgICAgICAgICB0aGlzLmRlbGV0ZUFsbC5lbWl0KCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICB9XHJcbn1cclxuIiwiPGRpdiBjbGFzcz1cImhpc3Rvcnktc2lkZWJhclwiIFtjbGFzcy5vcGVuXT1cImlzT3BlblwiPlxyXG4gIDxkaXYgY2xhc3M9XCJzaWRlYmFyLWhlYWRlclwiPlxyXG4gICAgPGRpdiBjbGFzcz1cIm1hcnF1ZWUtY29udGFpbmVyXCIgc3R5bGU9XCJmbGV4OiAxOyBtYXJnaW4tcmlnaHQ6IDEwcHhcIj5cclxuICAgICAgPGgzIGNsYXNzPVwibWFycXVlZS10ZXh0XCI+e3sgdXNlck5hbWUgfX0ncyBDaGF0IEhpc3Rvcnk8L2gzPlxyXG4gICAgPC9kaXY+XHJcbiAgICA8YnV0dG9uIGNsYXNzPVwicmVmcmVzaC1idG5cIiAoY2xpY2spPVwib25SZWZyZXNoKClcIiB0aXRsZT1cIlJlZnJlc2ggaGlzdG9yeVwiPlxyXG4gICAgICA8bWF0LWljb24+cmVmcmVzaDwvbWF0LWljb24+XHJcbiAgICA8L2J1dHRvbj5cclxuXHJcbiAgICA8YnV0dG9uIGNsYXNzPVwiY2xvc2UtYnRuXCIgKGNsaWNrKT1cIm9uQ2xvc2UoKVwiPlxyXG4gICAgICA8bWF0LWljb24+Y2xvc2U8L21hdC1pY29uPlxyXG4gICAgPC9idXR0b24+XHJcbiAgPC9kaXY+XHJcblxyXG4gIDxkaXYgY2xhc3M9XCJzaWRlYmFyLWNvbnRlbnRcIiAoc2Nyb2xsKT1cIm9uU2Nyb2xsKCRldmVudClcIj5cclxuICAgIEBpZiAoaXNMb2FkaW5nKSB7XHJcbiAgICA8ZGl2IGNsYXNzPVwibG9hZGVyLWNvbnRhaW5lclwiPlxyXG4gICAgICA8ZGl2IGNsYXNzPVwibG9hZGVyXCI+PC9kaXY+XHJcbiAgICAgIDxwPkxvYWRpbmcgaGlzdG9yeS4uLjwvcD5cclxuICAgIDwvZGl2PlxyXG4gICAgfVxyXG5cclxuICAgIEBpZiAoIWlzTG9hZGluZyAmJiBzZXNzaW9ucy5sZW5ndGggPT09IDApIHtcclxuICAgIDxkaXYgY2xhc3M9XCJlbXB0eS1zdGF0ZVwiPlxyXG4gICAgICA8bWF0LWljb24+aGlzdG9yeTwvbWF0LWljb24+XHJcbiAgICAgIDxwPk5vIGNoYXQgaGlzdG9yeSB5ZXQ8L3A+XHJcbiAgICAgIDxzcGFuPlN0YXJ0IGEgY29udmVyc2F0aW9uIHRvIHNlZSBpdCBoZXJlPC9zcGFuPlxyXG4gICAgPC9kaXY+XHJcbiAgICB9XHJcblxyXG4gICAgQGlmICghaXNMb2FkaW5nKSB7XHJcbiAgICBAZm9yIChncm91cCBvZiBjaGF0SGlzdG9yeTsgdHJhY2sgZ3JvdXAubGFiZWwpIHtcclxuICAgIDxkaXYgY2xhc3M9XCJzZXNzaW9uLWdyb3VwXCI+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJncm91cC1sYWJlbFwiPnt7IGdyb3VwLmxhYmVsIH19PC9kaXY+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJzZXNzaW9uLWxpc3RcIj5cclxuICAgICAgICBAZm9yIChzZXNzaW9uIG9mIGdyb3VwLnNlc3Npb25zOyB0cmFjayBzZXNzaW9uLmlkKSB7XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInNlc3Npb24taXRlbVwiIChjbGljayk9XCJvblNlc3Npb25DbGljayhzZXNzaW9uKVwiPlxyXG4gICAgICAgICAgPGRpdiBjbGFzcz1cInNlc3Npb24tY29udGVudFwiPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2Vzc2lvbi10aXRsZVwiPnt7IHNlc3Npb24udGl0bGUgfX08L2Rpdj5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlc3Npb24tdGltZVwiPlxyXG4gICAgICAgICAgICAgIHt7IGZvcm1hdFRpbWUoc2Vzc2lvbi50aW1lc3RhbXApIH19IMK3IHt7IGZvcm1hdERhdGUoc2Vzc2lvbi50aW1lc3RhbXApIH19XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic2Vzc2lvbi1hY3Rpb25zXCI+XHJcbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJlZGl0LWJ0blwiIFtkaXNhYmxlZF09XCJwcm9jZXNzaW5nU2Vzc2lvbklkID09PSBzZXNzaW9uLmlkXCJcclxuICAgICAgICAgICAgICAoY2xpY2spPVwib25FZGl0Q2xpY2soJGV2ZW50LCBzZXNzaW9uKVwiIHRpdGxlPVwiRWRpdCB0aXRsZVwiPlxyXG4gICAgICAgICAgICAgIEBpZiAocHJvY2Vzc2luZ1Nlc3Npb25JZCAhPT0gc2Vzc2lvbi5pZCkge1xyXG4gICAgICAgICAgICAgIDxtYXQtaWNvbj5lZGl0PC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICB9IEBlbHNlIHtcclxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibG9hZGVyLXRpbnlcIj48L2Rpdj5cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiZGVsZXRlLWJ0blwiIFtkaXNhYmxlZF09XCJwcm9jZXNzaW5nU2Vzc2lvbklkID09PSBzZXNzaW9uLmlkXCJcclxuICAgICAgICAgICAgICAoY2xpY2spPVwib25EZWxldGVDbGljaygkZXZlbnQsIHNlc3Npb24uaWQpXCIgdGl0bGU9XCJEZWxldGUgY29udmVyc2F0aW9uXCI+XHJcbiAgICAgICAgICAgICAgQGlmIChwcm9jZXNzaW5nU2Vzc2lvbklkICE9PSBzZXNzaW9uLmlkKSB7XHJcbiAgICAgICAgICAgICAgPG1hdC1pY29uPmRlbGV0ZTwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgfSBAZWxzZSB7XHJcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxvYWRlci10aW55XCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICAgIH1cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuICAgIH1cclxuICAgIH1cclxuXHJcbiAgICA8IS0tIExvYWRpbmcgbW9yZSBpbmRpY2F0b3IgLS0+XHJcbiAgICBAaWYgKGlzTG9hZGluZ01vcmUpIHtcclxuICAgIDxkaXYgY2xhc3M9XCJsb2FkaW5nLW1vcmVcIj5cclxuICAgICAgPGRpdiBjbGFzcz1cImxvYWRlci1zbWFsbFwiPjwvZGl2PlxyXG4gICAgICA8cD5Mb2FkaW5nIG1vcmUuLi48L3A+XHJcbiAgICA8L2Rpdj5cclxuICAgIH1cclxuICA8L2Rpdj5cclxuPC9kaXY+Il19
|