@sinequa/assistant 3.7.8 → 3.8.1

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.
Files changed (32) hide show
  1. package/chat/chat-settings-v3/chat-settings-v3.component.d.ts +6 -5
  2. package/chat/chat.component.d.ts +7 -15
  3. package/chat/chat.service.d.ts +5 -5
  4. package/chat/documents-upload/document-list/document-list.component.d.ts +77 -0
  5. package/chat/documents-upload/document-overview/document-overview.component.d.ts +41 -0
  6. package/chat/documents-upload/document-upload/document-upload.component.d.ts +98 -0
  7. package/chat/documents-upload/documents-upload.model.d.ts +66 -0
  8. package/chat/documents-upload/documents-upload.service.d.ts +174 -0
  9. package/chat/public-api.d.ts +5 -0
  10. package/chat/styles/assistant.scss +2 -0
  11. package/chat/types.d.ts +76 -20
  12. package/chat/websocket-chat.service.d.ts +1 -1
  13. package/esm2020/chat/chat-message/chat-message.component.mjs +3 -3
  14. package/esm2020/chat/chat-reference/chat-reference.component.mjs +3 -3
  15. package/esm2020/chat/chat-settings-v3/chat-settings-v3.component.mjs +13 -10
  16. package/esm2020/chat/chat.component.mjs +31 -34
  17. package/esm2020/chat/chat.service.mjs +9 -9
  18. package/esm2020/chat/documents-upload/document-list/document-list.component.mjs +191 -0
  19. package/esm2020/chat/documents-upload/document-overview/document-overview.component.mjs +80 -0
  20. package/esm2020/chat/documents-upload/document-upload/document-upload.component.mjs +258 -0
  21. package/esm2020/chat/documents-upload/documents-upload.model.mjs +2 -0
  22. package/esm2020/chat/documents-upload/documents-upload.service.mjs +289 -0
  23. package/esm2020/chat/public-api.mjs +6 -1
  24. package/esm2020/chat/saved-chats/saved-chats.component.mjs +4 -4
  25. package/esm2020/chat/token-progress-bar/token-progress-bar.component.mjs +3 -3
  26. package/esm2020/chat/types.mjs +17 -6
  27. package/esm2020/chat/websocket-chat.service.mjs +2 -2
  28. package/fesm2015/sinequa-assistant-chat.mjs +3648 -2864
  29. package/fesm2015/sinequa-assistant-chat.mjs.map +1 -1
  30. package/fesm2020/sinequa-assistant-chat.mjs +3626 -2843
  31. package/fesm2020/sinequa-assistant-chat.mjs.map +1 -1
  32. package/package.json +4 -2
@@ -0,0 +1,258 @@
1
+ import { CommonModule } from "@angular/common";
2
+ import { Component, inject, Input, ViewChild, } from "@angular/core";
3
+ import { NgxFlowModule } from "@flowjs/ngx-flow";
4
+ import { BehaviorSubject, catchError, EMPTY, filter, finalize, interval, Subscription, switchMap, takeWhile, tap, startWith, } from "rxjs";
5
+ import { LoginService } from "@sinequa/core/login";
6
+ import { NotificationsService } from "@sinequa/core/notification";
7
+ import { UtilsModule } from "@sinequa/components/utils";
8
+ import { InstanceManagerService } from "../../instance-manager.service";
9
+ import { DocumentsUploadService } from "../documents-upload.service";
10
+ import { FormatIconComponent } from '../../format-icon/format-icon.component';
11
+ import * as i0 from "@angular/core";
12
+ import * as i1 from "@angular/common";
13
+ import * as i2 from "@flowjs/ngx-flow";
14
+ import * as i3 from "@sinequa/components/utils";
15
+ export class DocumentUploadComponent {
16
+ constructor() {
17
+ /** Polling interval in milliseconds to update the indexing status of the uploaded documents */
18
+ this.pollingInterval = 1000;
19
+ this.flowConfig = {
20
+ // Disables chunk testing before uploading actual file data. Thus, avoids unnecessary requests and speeds up uploads
21
+ testChunks: false,
22
+ // Allows multiple file uploads simultaneously
23
+ singleFile: false,
24
+ // Allows the same file to be uploaded multiple times
25
+ allowDuplicateUploads: true,
26
+ query: () => {
27
+ return {}; // Empty object to prevent query parameters
28
+ },
29
+ preprocess: (chunk) => chunk.abort() // Prevents the default flow upload of chunks
30
+ };
31
+ this.errorAlerts = [];
32
+ this.dragging$ = new BehaviorSubject(false);
33
+ this.indexing$ = new BehaviorSubject(false);
34
+ this.indexingInfos$ = new BehaviorSubject(undefined);
35
+ this.uploading$ = new BehaviorSubject(false);
36
+ this.uploadingInfos$ = new BehaviorSubject(undefined);
37
+ this._subscription = new Subscription();
38
+ this.loginService = inject(LoginService);
39
+ this.instanceManagerService = inject(InstanceManagerService);
40
+ this.documentsUploadService = inject(DocumentsUploadService);
41
+ this.notificationsService = inject(NotificationsService);
42
+ }
43
+ ngOnInit() {
44
+ this._subscription.add(this.loginService.events
45
+ .pipe(filter((e) => e.type === "login-complete"), tap((_) => this.instantiateChatService()), switchMap((_) => this.chatService.assistantConfig$), filter((config) => !!config), tap((_) => this.documentsUploadService.init(this.chatService)), catchError((error) => {
46
+ console.error(error);
47
+ this.notificationsService.error(error);
48
+ return EMPTY;
49
+ }))
50
+ .subscribe());
51
+ this._subscription.add(this.flow.events$.subscribe((event) => {
52
+ const evt = event;
53
+ // Kept it just for reference to show how to access data of different events
54
+ if (event.type === "filesAdded") {
55
+ const addedFiles = evt.event[0];
56
+ this._onFilesAdded(addedFiles);
57
+ }
58
+ if (event.type === "filesSubmitted") {
59
+ this._onFilesSubmitted();
60
+ }
61
+ }));
62
+ // Override the upload method of the flow directive
63
+ this.flow.upload = this.startUpload.bind(this);
64
+ }
65
+ ngOnDestroy() {
66
+ this._subscription.unsubscribe();
67
+ }
68
+ instantiateChatService() {
69
+ this.chatService = this.instanceManagerService.getInstance(this.instanceId);
70
+ }
71
+ /**
72
+ * Handles the submission of files.
73
+ *
74
+ * @remarks
75
+ * This method performs the following checks on the submitted files:
76
+ *
77
+ * 1. Checks if the number of files submitted exceeds the remainingFileCount defined in the constraints.
78
+ * - If the number of files exceeds the allowed count, all files are removed from the flow.
79
+ * - An error message is added to the error alerts.
80
+ *
81
+ * 2. Checks if the total size of the files submitted exceeds the remainingFileSize defined in the constraints.
82
+ * - If the total size exceeds the allowed size, all files are removed from the flow.
83
+ * - An error message is added to the error alerts.
84
+ *
85
+ * 3. Checks if the file extension of the files submitted is not allowed.
86
+ * - If the file extension is not allowed, the file is removed from the flow.
87
+ * - An error message is added to the error alerts.
88
+ */
89
+ _onFilesSubmitted() {
90
+ // Get all files from the flow
91
+ const files = [...this.flow.flowJs.files];
92
+ // Clear the error alerts
93
+ this.errorAlerts = [];
94
+ const errors = [];
95
+ /**
96
+ * Checks if the number of files submitted exceeds the remainingFileCount defined in the constraints.
97
+ * If the number of files exceeds the allowed count, all files are removed from the flow
98
+ * An error message is added to the error alerts.
99
+ */
100
+ if (files.length > this.documentsUploadService.uploadConfig$.value.constraints.remainingFileCount) {
101
+ for (const file of files) {
102
+ this.flow.flowJs.removeFile(file);
103
+ }
104
+ errors.push(`The number of files exceeds the allowed limit. You can upload up to ${this.documentsUploadService.uploadConfig$.value.constraints.remainingFileCount} files.`);
105
+ }
106
+ /**
107
+ * Checks if the total size of the files submitted exceeds the remainingFileSize defined in the constraints.
108
+ * If the total size exceeds the allowed size, all files are removed from the flow
109
+ * An error message is added to the error alerts.
110
+ *
111
+ * @remarks
112
+ * The maximum size of the files that can be uploaded is temporary set to the maximum of 128 MB and the remainingFileSizeMB defined in the constraints.
113
+ * Waiting for the plugin to handle this kestrel issue
114
+ */
115
+ else if (this.documentsUploadService.convertBytesToMB(this.flow.flowJs.getSize()) > Math.min(128, this.documentsUploadService.uploadConfig$.value.constraints.remainingFileSizeMB)) {
116
+ for (const file of files) {
117
+ this.flow.flowJs.removeFile(file);
118
+ }
119
+ errors.push(`The total size of the files exceeds the allowed limit. You can upload files up to ${Math.min(128, this.documentsUploadService.uploadConfig$.value.constraints.remainingFileSizeMB)} MB.`);
120
+ }
121
+ /**
122
+ * Checks if the file extension of the files submitted is not allowed.
123
+ * If the file extension is not allowed, the file is removed from the flow
124
+ * An error message is added to the error alerts.
125
+ */
126
+ else {
127
+ for (const file of files) {
128
+ if (!this.documentsUploadService.uploadConfig$.value.constraints.supportedFileExtensions.includes(`${file.getExtension()}`)) {
129
+ this.flow.flowJs.removeFile(file);
130
+ errors.push(`The file extension "${file.getExtension()}" is not supported.`);
131
+ }
132
+ }
133
+ }
134
+ // Add unique error messages to the error alerts
135
+ this.errorAlerts = [...new Set(errors)];
136
+ }
137
+ _onFilesAdded(files) { }
138
+ onDragenter() {
139
+ this.dragging$.next(true);
140
+ }
141
+ onDragleave(event) {
142
+ if (!event.relatedTarget ||
143
+ !event.relatedTarget.closest(".dropzone")) {
144
+ this.dragging$.next(false);
145
+ }
146
+ }
147
+ onDrop() {
148
+ this.dragging$.next(false);
149
+ }
150
+ trackTransfer(transfer) {
151
+ return transfer.id;
152
+ }
153
+ /**
154
+ * Initiates the upload process by invoking the `upload` method
155
+ * of the `flow` instance.
156
+ * The `upload` method is overridden in the `ngOnInit` method to match the requirements of the assistant API.
157
+ */
158
+ upload() {
159
+ this.flow.upload();
160
+ }
161
+ /**
162
+ * Initiates the file upload process by preparing the form data,
163
+ * setting the uploading flag, and making an API call to upload the files.
164
+ *
165
+ * @remarks
166
+ * - Collects all files from the `flowJs` instance and appends them to a `FormData` object.
167
+ * - Subscribes to the upload process to handle progress updates, completion, and errors.
168
+ * - Triggers tracking the indexing process upon successful upload completion.
169
+ * - Cleans up the `flow` instance after the upload process is finalized.
170
+ */
171
+ startUpload() {
172
+ const formData = new FormData();
173
+ // Add all files with their original names
174
+ this.flow.flowJs.files.forEach((file) => {
175
+ formData.append(file.name, file.file);
176
+ });
177
+ // Clear the error alerts
178
+ this.errorAlerts = [];
179
+ // Set the uploading flag to true
180
+ this.uploading$.next(true);
181
+ // Make the API call to upload the files
182
+ this._subscription.add(this.documentsUploadService.uploadDocuments(formData).pipe(tap((event) => {
183
+ if (event.type === 'uploadProgress') {
184
+ this.uploadingInfos$.next(event);
185
+ }
186
+ if (event.type === 'response') {
187
+ this.trackIndexingProcess(event.body.statusToken);
188
+ }
189
+ }), catchError((err) => {
190
+ this.uploading$.next(false); // Set the uploading flag to false ONLY in case of an error. Otherwise, keep it true until the start of indexing process in order to prevent flickering of the UI
191
+ this.uploadingInfos$.next(undefined); // Clear the uploading infos
192
+ console.error(err);
193
+ this.notificationsService.error("Error uploading files");
194
+ return EMPTY;
195
+ }), finalize(() => {
196
+ // Clear the flow instance after the upload is complete or an error occurs
197
+ this.flow.cancel();
198
+ })).subscribe());
199
+ }
200
+ /**
201
+ * Tracks the indexing process for a single documents upload session by polling the API for its status.
202
+ *
203
+ * @param token - A unique token representing the single documents upload session.
204
+ *
205
+ * @remarks
206
+ * - Clears the uploading flags and sets the indexing flag to true before starting the process.
207
+ * - Polls the API every second to retrieve the current indexing status.
208
+ * - Updates the `indexingInfos` property with the latest status.
209
+ * - Stops polling when the indexing process is completed or an error occurs.
210
+ * - Cleans up by resetting the indexing flags and clearing the `indexingInfos` property when the process is finalized.
211
+ */
212
+ trackIndexingProcess(token) {
213
+ // Clear the uploading flags
214
+ this.uploading$.next(false);
215
+ this.uploadingInfos$.next(undefined);
216
+ // Set the indexing flag to true
217
+ this.indexing$.next(true);
218
+ // Combine immediate API call with interval-based polling
219
+ this._subscription.add(interval(this.pollingInterval).pipe(startWith(0), // Trigger the API call immediately
220
+ switchMap(() => this.documentsUploadService.getIndexingStatus(token)), tap((res) => this.indexingInfos$.next(res)), takeWhile((response) => !response.isCompleted, true), catchError((err) => {
221
+ console.error(err);
222
+ this.notificationsService.error("Error retrieving indexing status");
223
+ return EMPTY;
224
+ }), finalize(() => {
225
+ // Clear the indexing flags
226
+ this.indexing$.next(false);
227
+ this.indexingInfos$.next(undefined);
228
+ })).subscribe());
229
+ }
230
+ /**
231
+ * Calculates the indexing progress as a percentage of completed documents.
232
+ *
233
+ * @param infos - The indexing information containing the list of documents and their statuses.
234
+ * @returns The progress as a number between 0 and 1, where 0 indicates no progress and 1 indicates all documents are processed (processed means either indexed or errored).
235
+ * Returns 0 if the input is invalid or there are no documents.
236
+ */
237
+ getIndexingProgress(infos) {
238
+ if (!infos || !infos.docs)
239
+ return 0;
240
+ const completed = infos.docs.filter(doc => doc.status === "Indexed" || doc.status === "Error").length;
241
+ const total = infos.docs.length;
242
+ return completed / total;
243
+ }
244
+ }
245
+ DocumentUploadComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: DocumentUploadComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
246
+ DocumentUploadComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: DocumentUploadComponent, isStandalone: true, selector: "sq-document-upload", inputs: { instanceId: "instanceId", pollingInterval: "pollingInterval" }, providers: [DocumentsUploadService], viewQueries: [{ propertyName: "flow", first: true, predicate: ["flow"], descendants: true, static: true }], ngImport: i0, template: "<ng-container #flow=\"flow\" [flowConfig]=\"flowConfig\"></ng-container>\n<div class=\"file-upload-container\">\n <input\n type=\"file\"\n flowButton\n [flow]=\"flow.flowJs\"\n multiple\n hidden\n #fileInput>\n <div\n flowDrop\n [flow]=\"flow.flowJs\"\n (dragenter)=\"onDragenter()\"\n (dragleave)=\"onDragleave($event)\"\n (drop)=\"onDrop()\"\n (click)=\"fileInput.click()\"\n class=\"dropzone\"\n [ngClass]=\"{'dropzone--active': (dragging$ | async)}\"\n [hidden]=\"(uploading$ | async) || (indexing$ | async)\">\n <ng-container *ngIf=\"!(dragging$ | async); else draggingContent\">\n <i class=\"fas fa-cloud-upload-alt\"></i>\n <span>Drag and drop files here Or</span>\n <span class=\"text-orange\">Click to browse</span>\n </ng-container>\n <ng-template #draggingContent>\n <span>Drop files here</span>\n </ng-template>\n </div>\n\n <div *ngIf=\"(uploading$ | async) || (indexing$ | async)\" class=\"dropzone dropzone--active\">\n <ng-container *ngIf=\"(uploading$ | async); else indexingState\">\n <i class=\"fas fa-spinner fa-pulse\"></i>\n <span>\n Uploading {{ (flow.transfers$ | async)!.transfers.length }} files\n </span>\n <span *ngIf=\"(uploadingInfos$ | async) as uploadingInfos\">{{ uploadingInfos.progress | number:'1.0-0' }}%</span>\n </ng-container>\n <ng-template #indexingState>\n <i class=\"fas fa-spinner fa-pulse\"></i>\n <ng-container *ngIf=\"indexingInfos$ | async as indexingInfo\">\n <span>Indexing {{ indexingInfo.docs.length }} files</span>\n <span>{{ getIndexingProgress(indexingInfo) * 100 | number:'1.0-0' }}%</span>\n </ng-container>\n </ng-template>\n </div>\n\n <ul *ngIf=\"errorAlerts.length > 0\" class=\"error-list mt-3\">\n <li *ngFor=\"let error of errorAlerts\">\n {{ error }}\n </li>\n </ul>\n\n <div *ngIf=\"((flow.transfers$ | async)?.transfers?.length > 0) && !(uploading$ | async)\" class=\"file-list mt-3\">\n <ul>\n <li *ngFor=\"let transfer of (flow.transfers$ | async)!.transfers; trackBy: trackTransfer\">\n <sq-format-icon [extension]=\"transfer.flowFile.getExtension()\" class=\"me-1\"></sq-format-icon>\n <span [sqTooltip]=\"transfer.name\">{{ transfer.name }}</span>\n <i class=\"fas fa-trash ms-1\" (click)=\"flow.cancelFile(transfer)\" [sqTooltip]=\"'Cancel'\"></i>\n </li>\n </ul>\n </div>\n\n <div class=\"d-flex mt-2\">\n <button\n type=\"button\"\n class=\"btn btn-light cancel-btn me-2\"\n (click)=\"flow.cancel()\"\n [disabled]=\"!((flow.transfers$ | async)?.transfers?.length > 0) || (uploading$ | async) || (indexing$ | async)\">\n Cancel\n </button>\n <button\n type=\"button\"\n class=\"upload-btn\"\n (click)=\"upload()\"\n [disabled]=\"!((flow.transfers$ | async)?.transfers?.length > 0) || (uploading$ | async) || (indexing$ | async)\">\n Upload\n </button>\n </div>\n</div>\n", styles: [".ast-primary{color:var(--ast-primary-color, #005DA7);background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover{background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover:hover{color:var(--ast-primary-color, #005DA7)}.ast-secondary{color:var(--ast-secondary-color, #FF732E);background-color:var(--ast-secondary-bg, #FFF8F1)}.ast-error{background-color:var(--ast-error-bg, rgba(249, 58, 55, .2));color:var(--ast-action-buttons-color, inherit)}.ast-error:hover{color:var(--ast-error-color, rgba(249, 58, 55, .7))}.ast-btn{border:0;text-align:left;padding-top:.5rem;padding-bottom:.5rem;display:flex;align-items:center}.dark{--ast-primary-bg: #0d0701;--ast-primary-color: #008cd1;--ast-secondary-bg: #00070e;--ast-secondary-color: #ffa258;--ast-input-bg: #070707;--ast-input-color: rgba(222, 218, 218, .75);--ast-muted-color: rgba(222, 218, 218, .75);--ast-saved-chat-hover-background: #262421;--ast-uploaded-doc-hover-background: #262421;--ast-message-table-border-color: #333333;--ast-message-table-tr-bg: #070707;--ast-message-table-tr-border-color: #222222;--ast-reference-icon-color: white;--ast-reference-icon-active-color: black;--ast-reference-passages-color: white;--ast-reference-expanded-hover-bg: #262421;--ast-message-reference-color: black;--ast-action-buttons-color: white;--ast-action-buttons-hover-color: #6dbee6;--ast-report-bg: #070707}@keyframes dash-move{0%{background-position:0 0}to{background-position:100% 0}}.file-upload-container{width:100%;position:relative;padding:20px;background-color:#fff}.file-upload-container .dropzone{display:flex;flex-direction:column;justify-content:center;align-items:center;height:100px;border:2px dashed var(--ast-primary-color, #005DA7);border-color:var(--ast-secondary-color, #FF732E) var(--ast-primary-color, #005DA7) var(--ast-primary-color, #005DA7) var(--ast-secondary-color, #FF732E);border-radius:5px;padding:10px;cursor:pointer;background-color:#fff;transition:background-color .3s ease;color:var(--ast-primary-color, #005DA7)}.file-upload-container .dropzone--active{background-color:#fff8f1;color:var(--ast-secondary-color, #FF732E);border-color:var(--ast-secondary-color, #FF732E)}.file-upload-container .dropzone i{font-size:x-large}.file-upload-container .dropzone span{margin:0;font-size:small}.file-upload-container .dropzone span.text-orange{color:var(--ast-secondary-color, #FF732E)}.file-upload-container .file-list h6{color:#a9a9a9}.file-upload-container .file-list ul{list-style-type:none;padding:0}.file-upload-container .file-list ul li{display:flex;align-items:center;padding:10px;background-color:var(--ast-primary-bg, #f2f8fe);margin-bottom:5px;border-radius:5px;font-size:small}.file-upload-container .file-list ul li span{flex-grow:1;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.file-upload-container .file-list ul li i{cursor:pointer}.file-upload-container .file-list ul li i:hover{color:var(--ast-primary-color, #005DA7)}.file-upload-container .error-list{display:flex;flex-direction:column;list-style:disc;background:var(--ast-error-color, rgba(249, 58, 55, .7));color:#fff;border-radius:5px}.file-upload-container .error-list li{padding:3px}.file-upload-container .upload-btn{background:linear-gradient(to right,#1d4ed8,#ec4899,#f97316);color:#fff;border:none;padding:8px 16px;border-radius:5px;cursor:pointer;width:100%}.file-upload-container .upload-btn:hover{background:linear-gradient(to right,#1d4ed8cc,#ec4899cc,#f97316cc)}.file-upload-container .upload-btn[disabled]{opacity:.3;cursor:not-allowed}.file-upload-container .cancel-btn{cursor:pointer;pointer-events:unset;width:100%}.file-upload-container .cancel-btn[disabled]{opacity:.3;cursor:not-allowed}\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.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }, { kind: "ngmodule", type: NgxFlowModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[flowButton]", inputs: ["flowDirectoryOnly", "flowAttributes", "flow"] }, { kind: "directive", type: i2.DropDirective, selector: "[flowDrop]", inputs: ["flow"], exportAs: ["flowDrop"] }, { kind: "directive", type: i2.FlowDirective, selector: "[flowConfig]", inputs: ["flowConfig"], exportAs: ["flow"] }, { kind: "component", type: FormatIconComponent, selector: "sq-format-icon", inputs: ["extension"] }, { kind: "ngmodule", type: UtilsModule }, { kind: "directive", type: i3.TooltipDirective, selector: "[sqTooltip]", inputs: ["sqTooltip", "sqTooltipData", "sqTooltipTemplate", "placement", "fallbackPlacements", "delay", "hoverableTooltip", "tooltipClass"] }] });
247
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: DocumentUploadComponent, decorators: [{
248
+ type: Component,
249
+ args: [{ selector: "sq-document-upload", standalone: true, providers: [DocumentsUploadService], imports: [CommonModule, NgxFlowModule, FormatIconComponent, UtilsModule], template: "<ng-container #flow=\"flow\" [flowConfig]=\"flowConfig\"></ng-container>\n<div class=\"file-upload-container\">\n <input\n type=\"file\"\n flowButton\n [flow]=\"flow.flowJs\"\n multiple\n hidden\n #fileInput>\n <div\n flowDrop\n [flow]=\"flow.flowJs\"\n (dragenter)=\"onDragenter()\"\n (dragleave)=\"onDragleave($event)\"\n (drop)=\"onDrop()\"\n (click)=\"fileInput.click()\"\n class=\"dropzone\"\n [ngClass]=\"{'dropzone--active': (dragging$ | async)}\"\n [hidden]=\"(uploading$ | async) || (indexing$ | async)\">\n <ng-container *ngIf=\"!(dragging$ | async); else draggingContent\">\n <i class=\"fas fa-cloud-upload-alt\"></i>\n <span>Drag and drop files here Or</span>\n <span class=\"text-orange\">Click to browse</span>\n </ng-container>\n <ng-template #draggingContent>\n <span>Drop files here</span>\n </ng-template>\n </div>\n\n <div *ngIf=\"(uploading$ | async) || (indexing$ | async)\" class=\"dropzone dropzone--active\">\n <ng-container *ngIf=\"(uploading$ | async); else indexingState\">\n <i class=\"fas fa-spinner fa-pulse\"></i>\n <span>\n Uploading {{ (flow.transfers$ | async)!.transfers.length }} files\n </span>\n <span *ngIf=\"(uploadingInfos$ | async) as uploadingInfos\">{{ uploadingInfos.progress | number:'1.0-0' }}%</span>\n </ng-container>\n <ng-template #indexingState>\n <i class=\"fas fa-spinner fa-pulse\"></i>\n <ng-container *ngIf=\"indexingInfos$ | async as indexingInfo\">\n <span>Indexing {{ indexingInfo.docs.length }} files</span>\n <span>{{ getIndexingProgress(indexingInfo) * 100 | number:'1.0-0' }}%</span>\n </ng-container>\n </ng-template>\n </div>\n\n <ul *ngIf=\"errorAlerts.length > 0\" class=\"error-list mt-3\">\n <li *ngFor=\"let error of errorAlerts\">\n {{ error }}\n </li>\n </ul>\n\n <div *ngIf=\"((flow.transfers$ | async)?.transfers?.length > 0) && !(uploading$ | async)\" class=\"file-list mt-3\">\n <ul>\n <li *ngFor=\"let transfer of (flow.transfers$ | async)!.transfers; trackBy: trackTransfer\">\n <sq-format-icon [extension]=\"transfer.flowFile.getExtension()\" class=\"me-1\"></sq-format-icon>\n <span [sqTooltip]=\"transfer.name\">{{ transfer.name }}</span>\n <i class=\"fas fa-trash ms-1\" (click)=\"flow.cancelFile(transfer)\" [sqTooltip]=\"'Cancel'\"></i>\n </li>\n </ul>\n </div>\n\n <div class=\"d-flex mt-2\">\n <button\n type=\"button\"\n class=\"btn btn-light cancel-btn me-2\"\n (click)=\"flow.cancel()\"\n [disabled]=\"!((flow.transfers$ | async)?.transfers?.length > 0) || (uploading$ | async) || (indexing$ | async)\">\n Cancel\n </button>\n <button\n type=\"button\"\n class=\"upload-btn\"\n (click)=\"upload()\"\n [disabled]=\"!((flow.transfers$ | async)?.transfers?.length > 0) || (uploading$ | async) || (indexing$ | async)\">\n Upload\n </button>\n </div>\n</div>\n", styles: [".ast-primary{color:var(--ast-primary-color, #005DA7);background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover{background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover:hover{color:var(--ast-primary-color, #005DA7)}.ast-secondary{color:var(--ast-secondary-color, #FF732E);background-color:var(--ast-secondary-bg, #FFF8F1)}.ast-error{background-color:var(--ast-error-bg, rgba(249, 58, 55, .2));color:var(--ast-action-buttons-color, inherit)}.ast-error:hover{color:var(--ast-error-color, rgba(249, 58, 55, .7))}.ast-btn{border:0;text-align:left;padding-top:.5rem;padding-bottom:.5rem;display:flex;align-items:center}.dark{--ast-primary-bg: #0d0701;--ast-primary-color: #008cd1;--ast-secondary-bg: #00070e;--ast-secondary-color: #ffa258;--ast-input-bg: #070707;--ast-input-color: rgba(222, 218, 218, .75);--ast-muted-color: rgba(222, 218, 218, .75);--ast-saved-chat-hover-background: #262421;--ast-uploaded-doc-hover-background: #262421;--ast-message-table-border-color: #333333;--ast-message-table-tr-bg: #070707;--ast-message-table-tr-border-color: #222222;--ast-reference-icon-color: white;--ast-reference-icon-active-color: black;--ast-reference-passages-color: white;--ast-reference-expanded-hover-bg: #262421;--ast-message-reference-color: black;--ast-action-buttons-color: white;--ast-action-buttons-hover-color: #6dbee6;--ast-report-bg: #070707}@keyframes dash-move{0%{background-position:0 0}to{background-position:100% 0}}.file-upload-container{width:100%;position:relative;padding:20px;background-color:#fff}.file-upload-container .dropzone{display:flex;flex-direction:column;justify-content:center;align-items:center;height:100px;border:2px dashed var(--ast-primary-color, #005DA7);border-color:var(--ast-secondary-color, #FF732E) var(--ast-primary-color, #005DA7) var(--ast-primary-color, #005DA7) var(--ast-secondary-color, #FF732E);border-radius:5px;padding:10px;cursor:pointer;background-color:#fff;transition:background-color .3s ease;color:var(--ast-primary-color, #005DA7)}.file-upload-container .dropzone--active{background-color:#fff8f1;color:var(--ast-secondary-color, #FF732E);border-color:var(--ast-secondary-color, #FF732E)}.file-upload-container .dropzone i{font-size:x-large}.file-upload-container .dropzone span{margin:0;font-size:small}.file-upload-container .dropzone span.text-orange{color:var(--ast-secondary-color, #FF732E)}.file-upload-container .file-list h6{color:#a9a9a9}.file-upload-container .file-list ul{list-style-type:none;padding:0}.file-upload-container .file-list ul li{display:flex;align-items:center;padding:10px;background-color:var(--ast-primary-bg, #f2f8fe);margin-bottom:5px;border-radius:5px;font-size:small}.file-upload-container .file-list ul li span{flex-grow:1;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.file-upload-container .file-list ul li i{cursor:pointer}.file-upload-container .file-list ul li i:hover{color:var(--ast-primary-color, #005DA7)}.file-upload-container .error-list{display:flex;flex-direction:column;list-style:disc;background:var(--ast-error-color, rgba(249, 58, 55, .7));color:#fff;border-radius:5px}.file-upload-container .error-list li{padding:3px}.file-upload-container .upload-btn{background:linear-gradient(to right,#1d4ed8,#ec4899,#f97316);color:#fff;border:none;padding:8px 16px;border-radius:5px;cursor:pointer;width:100%}.file-upload-container .upload-btn:hover{background:linear-gradient(to right,#1d4ed8cc,#ec4899cc,#f97316cc)}.file-upload-container .upload-btn[disabled]{opacity:.3;cursor:not-allowed}.file-upload-container .cancel-btn{cursor:pointer;pointer-events:unset;width:100%}.file-upload-container .cancel-btn[disabled]{opacity:.3;cursor:not-allowed}\n"] }]
250
+ }], propDecorators: { instanceId: [{
251
+ type: Input
252
+ }], pollingInterval: [{
253
+ type: Input
254
+ }], flow: [{
255
+ type: ViewChild,
256
+ args: ["flow", { static: true }]
257
+ }] } });
258
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9jdW1lbnQtdXBsb2FkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Fzc2lzdGFudC9jaGF0L2RvY3VtZW50cy11cGxvYWQvZG9jdW1lbnQtdXBsb2FkL2RvY3VtZW50LXVwbG9hZC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hc3Npc3RhbnQvY2hhdC9kb2N1bWVudHMtdXBsb2FkL2RvY3VtZW50LXVwbG9hZC9kb2N1bWVudC11cGxvYWQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFDTCxTQUFTLEVBQ1QsTUFBTSxFQUNOLEtBQUssRUFHTCxTQUFTLEdBQ1YsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGFBQWEsRUFBMkIsTUFBTSxrQkFBa0IsQ0FBQztBQUUxRSxPQUFPLEVBQ0wsZUFBZSxFQUNmLFVBQVUsRUFDVixLQUFLLEVBQ0wsTUFBTSxFQUNOLFFBQVEsRUFDUixRQUFRLEVBQ1IsWUFBWSxFQUNaLFNBQVMsRUFDVCxTQUFTLEVBQ1QsR0FBRyxFQUNILFNBQVMsR0FDVixNQUFNLE1BQU0sQ0FBQztBQUNkLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNuRCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNsRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDeEQsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFFeEUsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDckUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0seUNBQXlDLENBQUM7Ozs7O0FBWTlFLE1BQU0sT0FBTyx1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LENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEtBQUssU0FBUyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDO1FBQ3RHLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQ2hDLE9BQU8sU0FBUyxHQUFDLEtBQUssQ0FBQztJQUN6QixDQUFDOztvSEE1UlUsdUJBQXVCO3dHQUF2Qix1QkFBdUIsMklBSHZCLENBQUMsc0JBQXNCLENBQUMsc0lDdkNyQyxxOUZBK0VBLHlwSER2Q1ksWUFBWSwwY0FBRSxhQUFhLHlZQUFFLG1CQUFtQixpRkFBRSxXQUFXOzJGQUU1RCx1QkFBdUI7a0JBUm5DLFNBQVM7K0JBQ0Usb0JBQW9CLGNBR2xCLElBQUksYUFDTCxDQUFDLHNCQUFzQixDQUFDLFdBQzFCLENBQUMsWUFBWSxFQUFFLGFBQWEsRUFBRSxtQkFBbUIsRUFBRSxXQUFXLENBQUM7OEJBSS9ELFVBQVU7c0JBQWxCLEtBQUs7Z0JBRUcsZUFBZTtzQkFBdkIsS0FBSztnQkFFK0IsSUFBSTtzQkFBeEMsU0FBUzt1QkFBQyxNQUFNLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSBcIkBhbmd1bGFyL2NvbW1vblwiO1xuaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBpbmplY3QsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgVmlld0NoaWxkLFxufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgTmd4Rmxvd01vZHVsZSwgRmxvd0RpcmVjdGl2ZSwgVHJhbnNmZXIgfSBmcm9tIFwiQGZsb3dqcy9uZ3gtZmxvd1wiO1xuaW1wb3J0IHsgRmxvd0ZpbGUgfSBmcm9tIFwiZmxvd2pzXCI7XG5pbXBvcnQge1xuICBCZWhhdmlvclN1YmplY3QsXG4gIGNhdGNoRXJyb3IsXG4gIEVNUFRZLFxuICBmaWx0ZXIsXG4gIGZpbmFsaXplLFxuICBpbnRlcnZhbCxcbiAgU3Vic2NyaXB0aW9uLFxuICBzd2l0Y2hNYXAsXG4gIHRha2VXaGlsZSxcbiAgdGFwLFxuICBzdGFydFdpdGgsXG59IGZyb20gXCJyeGpzXCI7XG5pbXBvcnQgeyBMb2dpblNlcnZpY2UgfSBmcm9tIFwiQHNpbmVxdWEvY29yZS9sb2dpblwiO1xuaW1wb3J0IHsgTm90aWZpY2F0aW9uc1NlcnZpY2UgfSBmcm9tIFwiQHNpbmVxdWEvY29yZS9ub3RpZmljYXRpb25cIjtcbmltcG9ydCB7IFV0aWxzTW9kdWxlIH0gZnJvbSBcIkBzaW5lcXVhL2NvbXBvbmVudHMvdXRpbHNcIjtcbmltcG9ydCB7IEluc3RhbmNlTWFuYWdlclNlcnZpY2UgfSBmcm9tIFwiLi4vLi4vaW5zdGFuY2UtbWFuYWdlci5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBDaGF0U2VydmljZSB9IGZyb20gXCIuLi8uLi9jaGF0LnNlcnZpY2VcIjtcbmltcG9ydCB7IERvY3VtZW50c1VwbG9hZFNlcnZpY2UgfSBmcm9tIFwiLi4vZG9jdW1lbnRzLXVwbG9hZC5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBGb3JtYXRJY29uQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vZm9ybWF0LWljb24vZm9ybWF0LWljb24uY29tcG9uZW50JztcbmltcG9ydCB7IENoYXRDb25maWcgfSBmcm9tIFwiLi4vLi4vdHlwZXNcIjtcbmltcG9ydCB7IEluZGV4aW5nSW5mb3MsIFVwbG9hZEV2ZW50LCBVcGxvYWRpbmdJbmZvcyB9IGZyb20gXCIuLi9kb2N1bWVudHMtdXBsb2FkLm1vZGVsXCI7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogXCJzcS1kb2N1bWVudC11cGxvYWRcIixcbiAgdGVtcGxhdGVVcmw6IFwiLi9kb2N1bWVudC11cGxvYWQuY29tcG9uZW50Lmh0bWxcIixcbiAgc3R5bGVVcmxzOiBbXCIuL2RvY3VtZW50LXVwbG9hZC5jb21wb25lbnQuc2Nzc1wiXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgcHJvdmlkZXJzOiBbRG9jdW1lbnRzVXBsb2FkU2VydmljZV0sXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIE5neEZsb3dNb2R1bGUsIEZvcm1hdEljb25Db21wb25lbnQsIFV0aWxzTW9kdWxlXSxcbn0pXG5leHBvcnQgY2xhc3MgRG9jdW1lbnRVcGxvYWRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG4gIC8qKiBEZWZpbmUgdGhlIGtleSBiYXNlZCBvbiBpdCwgdGhlIGFwcHJvcHJpYXRlIGNoYXRTZXJ2aWNlIGluc3RhbmNlIHdpbGwgYmUgcmV0dXJuZWQgZnJvbSBpbnN0YW5jZU1hbmFnZXJTZXJ2aWNlICovXG4gIEBJbnB1dCgpIGluc3RhbmNlSWQ6IHN0cmluZztcbiAgLyoqIFBvbGxpbmcgaW50ZXJ2YWwgaW4gbWlsbGlzZWNvbmRzIHRvIHVwZGF0ZSB0aGUgaW5kZXhpbmcgc3RhdHVzIG9mIHRoZSB1cGxvYWRlZCBkb2N1bWVudHMgKi9cbiAgQElucHV0KCkgcG9sbGluZ0ludGVydmFsIDogbnVtYmVyID0gMTAwMDtcbiAgLy8gUmVmZXJlbmNlIHRvIHRoZSBmbG93IGRpcmVjdGl2ZVxuICBAVmlld0NoaWxkKFwiZmxvd1wiLCB7IHN0YXRpYzogdHJ1ZSB9KSBmbG93ITogRmxvd0RpcmVjdGl2ZTtcblxuICBwdWJsaWMgY2hhdFNlcnZpY2U6IENoYXRTZXJ2aWNlO1xuICByZWFkb25seSBmbG93Q29uZmlnOiBmbG93anMuRmxvd09wdGlvbnMgPSB7XG4gICAgLy8gRGlzYWJsZXMgY2h1bmsgdGVzdGluZyBiZWZvcmUgdXBsb2FkaW5nIGFjdHVhbCBmaWxlIGRhdGEuIFRodXMsIGF2b2lkcyB1bm5lY2Vzc2FyeSByZXF1ZXN0cyBhbmQgc3BlZWRzIHVwIHVwbG9hZHNcbiAgICB0ZXN0Q2h1bmtzOiBmYWxzZSxcbiAgICAvLyBBbGxvd3MgbXVsdGlwbGUgZmlsZSB1cGxvYWRzIHNpbXVsdGFuZW91c2x5XG4gICAgc2luZ2xlRmlsZTogZmFsc2UsXG4gICAgLy8gQWxsb3dzIHRoZSBzYW1lIGZpbGUgdG8gYmUgdXBsb2FkZWQgbXVsdGlwbGUgdGltZXNcbiAgICBhbGxvd0R1cGxpY2F0ZVVwbG9hZHM6IHRydWUsXG4gICAgcXVlcnk6ICgpID0+IHtcbiAgICAgIHJldHVybiB7fTsgLy8gRW1wdHkgb2JqZWN0IHRvIHByZXZlbnQgcXVlcnkgcGFyYW1ldGVyc1xuICAgIH0sXG4gICAgcHJlcHJvY2VzczogKGNodW5rKSA9PiBjaHVuay5hYm9ydCgpIC8vIFByZXZlbnRzIHRoZSBkZWZhdWx0IGZsb3cgdXBsb2FkIG9mIGNodW5rc1xuICB9O1xuICBwdWJsaWMgZXJyb3JBbGVydHM6IHN0cmluZ1tdID0gW107XG4gIHB1YmxpYyBkcmFnZ2luZyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcbiAgcHVibGljIGluZGV4aW5nJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpO1xuICBwdWJsaWMgaW5kZXhpbmdJbmZvcyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PEluZGV4aW5nSW5mb3MgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG4gIHB1YmxpYyB1cGxvYWRpbmckID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XG4gIHB1YmxpYyB1cGxvYWRpbmdJbmZvcyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFVwbG9hZGluZ0luZm9zIHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuXG4gIHByaXZhdGUgX3N1YnNjcmlwdGlvbiA9IG5ldyBTdWJzY3JpcHRpb24oKTtcblxuICBwdWJsaWMgbG9naW5TZXJ2aWNlID0gaW5qZWN0KExvZ2luU2VydmljZSk7XG4gIHB1YmxpYyBpbnN0YW5jZU1hbmFnZXJTZXJ2aWNlID0gaW5qZWN0KEluc3RhbmNlTWFuYWdlclNlcnZpY2UpO1xuICBwdWJsaWMgZG9jdW1lbnRzVXBsb2FkU2VydmljZSA9IGluamVjdChEb2N1bWVudHNVcGxvYWRTZXJ2aWNlKTtcbiAgcHVibGljIG5vdGlmaWNhdGlvbnNTZXJ2aWNlID0gaW5qZWN0KE5vdGlmaWNhdGlvbnNTZXJ2aWNlKTtcblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLl9zdWJzY3JpcHRpb24uYWRkKFxuICAgICAgdGhpcy5sb2dpblNlcnZpY2UuZXZlbnRzXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgIGZpbHRlcigoZSkgPT4gZS50eXBlID09PSBcImxvZ2luLWNvbXBsZXRlXCIpLFxuICAgICAgICAgIHRhcCgoXykgPT4gdGhpcy5pbnN0YW50aWF0ZUNoYXRTZXJ2aWNlKCkpLFxuICAgICAgICAgIHN3aXRjaE1hcCgoXykgPT4gdGhpcy5jaGF0U2VydmljZS5hc3Npc3RhbnRDb25maWckKSxcbiAgICAgICAgICBmaWx0ZXIoKGNvbmZpZzogQ2hhdENvbmZpZyB8IHVuZGVmaW5lZCkgPT4gISFjb25maWcpLFxuICAgICAgICAgIHRhcCgoXykgPT4gdGhpcy5kb2N1bWVudHNVcGxvYWRTZXJ2aWNlLmluaXQodGhpcy5jaGF0U2VydmljZSkpLFxuICAgICAgICAgIGNhdGNoRXJyb3IoKGVycm9yKSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgIHRoaXMubm90aWZpY2F0aW9uc1NlcnZpY2UuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgcmV0dXJuIEVNUFRZO1xuICAgICAgICAgIH0pXG4gICAgICAgIClcbiAgICAgICAgLnN1YnNjcmliZSgpXG4gICAgKTtcblxuICAgIHRoaXMuX3N1YnNjcmlwdGlvbi5hZGQoXG4gICAgICB0aGlzLmZsb3cuZXZlbnRzJC5zdWJzY3JpYmUoKGV2ZW50KSA9PiB7XG4gICAgICAgIGNvbnN0IGV2dCA9IGV2ZW50IGFzIGFueTtcbiAgICAgICAgLy8gS2VwdCBpdCBqdXN0IGZvciByZWZlcmVuY2UgdG8gc2hvdyBob3cgdG8gYWNjZXNzIGRhdGEgb2YgZGlmZmVyZW50IGV2ZW50c1xuICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gXCJmaWxlc0FkZGVkXCIpIHtcbiAgICAgICAgICBjb25zdCBhZGRlZEZpbGVzID0gZXZ0LmV2ZW50WzBdIGFzIEZsb3dGaWxlW107XG4gICAgICAgICAgdGhpcy5fb25GaWxlc0FkZGVkKGFkZGVkRmlsZXMpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChldmVudC50eXBlID09PSBcImZpbGVzU3VibWl0dGVkXCIpIHtcbiAgICAgICAgICB0aGlzLl9vbkZpbGVzU3VibWl0dGVkKCk7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgKTtcblxuICAgIC8vIE92ZXJyaWRlIHRoZSB1cGxvYWQgbWV0aG9kIG9mIHRoZSBmbG93IGRpcmVjdGl2ZVxuICAgIHRoaXMuZmxvdy51cGxvYWQgPSB0aGlzLnN0YXJ0VXBsb2FkLmJpbmQodGhpcyk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLl9zdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIGluc3RhbnRpYXRlQ2hhdFNlcnZpY2UoKTogdm9pZCB7XG4gICAgdGhpcy5jaGF0U2VydmljZSA9IHRoaXMuaW5zdGFuY2VNYW5hZ2VyU2VydmljZS5nZXRJbnN0YW5jZSh0aGlzLmluc3RhbmNlSWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZXMgdGhlIHN1Ym1pc3Npb24gb2YgZmlsZXMuXG4gICAqXG4gICAqIEByZW1hcmtzXG4gICAqIFRoaXMgbWV0aG9kIHBlcmZvcm1zIHRoZSBmb2xsb3dpbmcgY2hlY2tzIG9uIHRoZSBzdWJtaXR0ZWQgZmlsZXM6XG4gICAqXG4gICAqIDEuIENoZWNrcyBpZiB0aGUgbnVtYmVyIG9mIGZpbGVzIHN1Ym1pdHRlZCBleGNlZWRzIHRoZSByZW1haW5pbmdGaWxlQ291bnQgZGVmaW5lZCBpbiB0aGUgY29uc3RyYWludHMuXG4gICAqICAgIC0gSWYgdGhlIG51bWJlciBvZiBmaWxlcyBleGNlZWRzIHRoZSBhbGxvd2VkIGNvdW50LCBhbGwgZmlsZXMgYXJlIHJlbW92ZWQgZnJvbSB0aGUgZmxvdy5cbiAgICogICAgLSBBbiBlcnJvciBtZXNzYWdlIGlzIGFkZGVkIHRvIHRoZSBlcnJvciBhbGVydHMuXG4gICAqXG4gICAqIDIuIENoZWNrcyBpZiB0aGUgdG90YWwgc2l6ZSBvZiB0aGUgZmlsZXMgc3VibWl0dGVkIGV4Y2VlZHMgdGhlIHJlbWFpbmluZ0ZpbGVTaXplIGRlZmluZWQgaW4gdGhlIGNvbnN0cmFpbnRzLlxuICAgKiAgICAtIElmIHRoZSB0b3RhbCBzaXplIGV4Y2VlZHMgdGhlIGFsbG93ZWQgc2l6ZSwgYWxsIGZpbGVzIGFyZSByZW1vdmVkIGZyb20gdGhlIGZsb3cuXG4gICAqICAgIC0gQW4gZXJyb3IgbWVzc2FnZSBpcyBhZGRlZCB0byB0aGUgZXJyb3IgYWxlcnRzLlxuICAgKlxuICAgKiAzLiBDaGVja3MgaWYgdGhlIGZpbGUgZXh0ZW5zaW9uIG9mIHRoZSBmaWxlcyBzdWJtaXR0ZWQgaXMgbm90IGFsbG93ZWQuXG4gICAqICAgIC0gSWYgdGhlIGZpbGUgZXh0ZW5zaW9uIGlzIG5vdCBhbGxvd2VkLCB0aGUgZmlsZSBpcyByZW1vdmVkIGZyb20gdGhlIGZsb3cuXG4gICAqICAgIC0gQW4gZXJyb3IgbWVzc2FnZSBpcyBhZGRlZCB0byB0aGUgZXJyb3IgYWxlcnRzLlxuICAgKi9cbiAgcHJpdmF0ZSBfb25GaWxlc1N1Ym1pdHRlZCgpIHtcbiAgICAvLyBHZXQgYWxsIGZpbGVzIGZyb20gdGhlIGZsb3dcbiAgICBjb25zdCBmaWxlcyA9IFsuLi50aGlzLmZsb3cuZmxvd0pzLmZpbGVzXTtcbiAgICAvLyBDbGVhciB0aGUgZXJyb3IgYWxlcnRzXG4gICAgdGhpcy5lcnJvckFsZXJ0cyA9IFtdO1xuICAgIGNvbnN0IGVycm9yczogc3RyaW5nW10gPSBbXTtcblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiB0aGUgbnVtYmVyIG9mIGZpbGVzIHN1Ym1pdHRlZCBleGNlZWRzIHRoZSByZW1haW5pbmdGaWxlQ291bnQgZGVmaW5lZCBpbiB0aGUgY29uc3RyYWludHMuXG4gICAgICogSWYgdGhlIG51bWJlciBvZiBmaWxlcyBleGNlZWRzIHRoZSBhbGxvd2VkIGNvdW50LCBhbGwgZmlsZXMgYXJlIHJlbW92ZWQgZnJvbSB0aGUgZmxvd1xuICAgICAqIEFuIGVycm9yIG1lc3NhZ2UgaXMgYWRkZWQgdG8gdGhlIGVycm9yIGFsZXJ0cy5cbiAgICAgKi9cbiAgICBpZiAoZmlsZXMubGVuZ3RoID4gdGhpcy5kb2N1bWVudHNVcGxvYWRTZXJ2aWNlLnVwbG9hZENvbmZpZyQudmFsdWUhLmNvbnN0cmFpbnRzLnJlbWFpbmluZ0ZpbGVDb3VudCkge1xuICAgICAgZm9yIChjb25zdCBmaWxlIG9mIGZpbGVzKSB7XG4gICAgICAgIHRoaXMuZmxvdy5mbG93SnMucmVtb3ZlRmlsZShmaWxlKTtcbiAgICAgIH1cbiAgICAgIGVycm9ycy5wdXNoKGBUaGUgbnVtYmVyIG9mIGZpbGVzIGV4Y2VlZHMgdGhlIGFsbG93ZWQgbGltaXQuIFlvdSBjYW4gdXBsb2FkIHVwIHRvICR7dGhpcy5kb2N1bWVudHNVcGxvYWRTZXJ2aWNlLnVwbG9hZENvbmZpZyQudmFsdWUhLmNvbnN0cmFpbnRzLnJlbWFpbmluZ0ZpbGVDb3VudH0gZmlsZXMuYClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgdGhlIHRvdGFsIHNpemUgb2YgdGhlIGZpbGVzIHN1Ym1pdHRlZCBleGNlZWRzIHRoZSByZW1haW5pbmdGaWxlU2l6ZSBkZWZpbmVkIGluIHRoZSBjb25zdHJhaW50cy5cbiAgICAgKiBJZiB0aGUgdG90YWwgc2l6ZSBleGNlZWRzIHRoZSBhbGxvd2VkIHNpemUsIGFsbCBmaWxlcyBhcmUgcmVtb3ZlZCBmcm9tIHRoZSBmbG93XG4gICAgICogQW4gZXJyb3IgbWVzc2FnZSBpcyBhZGRlZCB0byB0aGUgZXJyb3IgYWxlcnRzLlxuICAgICAqXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBUaGUgbWF4aW11bSBzaXplIG9mIHRoZSBmaWxlcyB0aGF0IGNhbiBiZSB1cGxvYWRlZCBpcyB0ZW1wb3Jhcnkgc2V0IHRvIHRoZSBtYXhpbXVtIG9mIDEyOCBNQiBhbmQgdGhlIHJlbWFpbmluZ0ZpbGVTaXplTUIgZGVmaW5lZCBpbiB0aGUgY29uc3RyYWludHMuXG4gICAgICogV2FpdGluZyBmb3IgdGhlIHBsdWdpbiB0byBoYW5kbGUgdGhpcyBrZXN0cmVsIGlzc3VlXG4gICAgICovXG4gICAgZWxzZSBpZiAodGhpcy5kb2N1bWVudHNVcGxvYWRTZXJ2aWNlLmNvbnZlcnRCeXRlc1RvTUIodGhpcy5mbG93LmZsb3dKcy5nZXRTaXplKCkpID4gTWF0aC5taW4oMTI4LCB0aGlzLmRvY3VtZW50c1VwbG9hZFNlcnZpY2UudXBsb2FkQ29uZmlnJC52YWx1ZSEuY29uc3RyYWludHMucmVtYWluaW5nRmlsZVNpemVNQikpIHtcbiAgICAgIGZvciAoY29uc3QgZmlsZSBvZiBmaWxlcykge1xuICAgICAgICB0aGlzLmZsb3cuZmxvd0pzLnJlbW92ZUZpbGUoZmlsZSk7XG4gICAgICB9XG4gICAgICBlcnJvcnMucHVzaChgVGhlIHRvdGFsIHNpemUgb2YgdGhlIGZpbGVzIGV4Y2VlZHMgdGhlIGFsbG93ZWQgbGltaXQuIFlvdSBjYW4gdXBsb2FkIGZpbGVzIHVwIHRvICR7TWF0aC5taW4oMTI4LCB0aGlzLmRvY3VtZW50c1VwbG9hZFNlcnZpY2UudXBsb2FkQ29uZmlnJC52YWx1ZSEuY29uc3RyYWludHMucmVtYWluaW5nRmlsZVNpemVNQil9IE1CLmApXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIHRoZSBmaWxlIGV4dGVuc2lvbiBvZiB0aGUgZmlsZXMgc3VibWl0dGVkIGlzIG5vdCBhbGxvd2VkLlxuICAgICAqIElmIHRoZSBmaWxlIGV4dGVuc2lvbiBpcyBub3QgYWxsb3dlZCwgdGhlIGZpbGUgaXMgcmVtb3ZlZCBmcm9tIHRoZSBmbG93XG4gICAgICogQW4gZXJyb3IgbWVzc2FnZSBpcyBhZGRlZCB0byB0aGUgZXJyb3IgYWxlcnRzLlxuICAgICAqL1xuICAgIGVsc2Uge1xuICAgICAgZm9yIChjb25zdCBmaWxlIG9mIGZpbGVzKSB7XG4gICAgICAgIGlmICghdGhpcy5kb2N1bWVudHNVcGxvYWRTZXJ2aWNlLnVwbG9hZENvbmZpZyQudmFsdWUhLmNvbnN0cmFpbnRzLnN1cHBvcnRlZEZpbGVFeHRlbnNpb25zLmluY2x1ZGVzKGAke2ZpbGUuZ2V0RXh0ZW5zaW9uKCl9YCkpIHtcbiAgICAgICAgICB0aGlzLmZsb3cuZmxvd0pzLnJlbW92ZUZpbGUoZmlsZSk7XG4gICAgICAgICAgZXJyb3JzLnB1c2goYFRoZSBmaWxlIGV4dGVuc2lvbiBcIiR7ZmlsZS5nZXRFeHRlbnNpb24oKX1cIiBpcyBub3Qgc3VwcG9ydGVkLmApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQWRkIHVuaXF1ZSBlcnJvciBtZXNzYWdlcyB0byB0aGUgZXJyb3IgYWxlcnRzXG4gICAgdGhpcy5lcnJvckFsZXJ0cyA9IFsuLi5uZXcgU2V0KGVycm9ycyldO1xuICB9XG5cbiAgcHJpdmF0ZSBfb25GaWxlc0FkZGVkKGZpbGVzOiBGbG93RmlsZVtdKSB7fVxuXG4gIG9uRHJhZ2VudGVyKCkge1xuICAgIHRoaXMuZHJhZ2dpbmckLm5leHQodHJ1ZSk7XG4gIH1cblxuICBvbkRyYWdsZWF2ZShldmVudDogRHJhZ0V2ZW50KSB7XG4gICAgaWYgKFxuICAgICAgIWV2ZW50LnJlbGF0ZWRUYXJnZXQgfHxcbiAgICAgICEoZXZlbnQucmVsYXRlZFRhcmdldCBhcyBIVE1MRWxlbWVudCkuY2xvc2VzdChcIi5kcm9wem9uZVwiKVxuICAgICkge1xuICAgICAgdGhpcy5kcmFnZ2luZyQubmV4dChmYWxzZSk7XG4gICAgfVxuICB9XG5cbiAgb25Ecm9wKCkge1xuICAgIHRoaXMuZHJhZ2dpbmckLm5leHQoZmFsc2UpO1xuICB9XG5cbiAgdHJhY2tUcmFuc2Zlcih0cmFuc2ZlcjogVHJhbnNmZXIpIHtcbiAgICByZXR1cm4gdHJhbnNmZXIuaWQ7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBJbml0aWF0ZXMgdGhlIHVwbG9hZCBwcm9jZXNzIGJ5IGludm9raW5nIHRoZSBgdXBsb2FkYCBtZXRob2RcbiAgICogb2YgdGhlIGBmbG93YCBpbnN0YW5jZS5cbiAgICogVGhlIGB1cGxvYWRgIG1ldGhvZCBpcyBvdmVycmlkZGVuIGluIHRoZSBgbmdPbkluaXRgIG1ldGhvZCB0byBtYXRjaCB0aGUgcmVxdWlyZW1lbnRzIG9mIHRoZSBhc3Npc3RhbnQgQVBJLlxuICAgKi9cbiAgdXBsb2FkKCkge1xuICAgIHRoaXMuZmxvdy51cGxvYWQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWF0ZXMgdGhlIGZpbGUgdXBsb2FkIHByb2Nlc3MgYnkgcHJlcGFyaW5nIHRoZSBmb3JtIGRhdGEsXG4gICAqIHNldHRpbmcgdGhlIHVwbG9hZGluZyBmbGFnLCBhbmQgbWFraW5nIGFuIEFQSSBjYWxsIHRvIHVwbG9hZCB0aGUgZmlsZXMuXG4gICAqXG4gICAqIEByZW1hcmtzXG4gICAqIC0gQ29sbGVjdHMgYWxsIGZpbGVzIGZyb20gdGhlIGBmbG93SnNgIGluc3RhbmNlIGFuZCBhcHBlbmRzIHRoZW0gdG8gYSBgRm9ybURhdGFgIG9iamVjdC5cbiAgICogLSBTdWJzY3JpYmVzIHRvIHRoZSB1cGxvYWQgcHJvY2VzcyB0byBoYW5kbGUgcHJvZ3Jlc3MgdXBkYXRlcywgY29tcGxldGlvbiwgYW5kIGVycm9ycy5cbiAgICogLSBUcmlnZ2VycyB0cmFja2luZyB0aGUgaW5kZXhpbmcgcHJvY2VzcyB1cG9uIHN1Y2Nlc3NmdWwgdXBsb2FkIGNvbXBsZXRpb24uXG4gICAqIC0gQ2xlYW5zIHVwIHRoZSBgZmxvd2AgaW5zdGFuY2UgYWZ0ZXIgdGhlIHVwbG9hZCBwcm9jZXNzIGlzIGZpbmFsaXplZC5cbiAgICovXG4gIHByaXZhdGUgc3RhcnRVcGxvYWQoKSB7XG4gICAgY29uc3QgZm9ybURhdGEgPSBuZXcgRm9ybURhdGEoKTtcblxuICAgIC8vIEFkZCBhbGwgZmlsZXMgd2l0aCB0aGVpciBvcmlnaW5hbCBuYW1lc1xuICAgIHRoaXMuZmxvdy5mbG93SnMuZmlsZXMuZm9yRWFjaCgoZmlsZSkgPT4ge1xuICAgICAgZm9ybURhdGEuYXBwZW5kKGZpbGUubmFtZSwgZmlsZS5maWxlKTtcbiAgICB9KTtcblxuICAgIC8vIENsZWFyIHRoZSBlcnJvciBhbGVydHNcbiAgICB0aGlzLmVycm9yQWxlcnRzID0gW107XG4gICAgLy8gU2V0IHRoZSB1cGxvYWRpbmcgZmxhZyB0byB0cnVlXG4gICAgdGhpcy51cGxvYWRpbmckLm5leHQodHJ1ZSk7XG5cbiAgICAvLyBNYWtlIHRoZSBBUEkgY2FsbCB0byB1cGxvYWQgdGhlIGZpbGVzXG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLmFkZChcbiAgICAgIHRoaXMuZG9jdW1lbnRzVXBsb2FkU2VydmljZS51cGxvYWREb2N1bWVudHMoZm9ybURhdGEpLnBpcGUoXG4gICAgICAgIHRhcCgoZXZlbnQ6IFVwbG9hZEV2ZW50KSA9PiB7XG4gICAgICAgICAgaWYgKGV2ZW50LnR5cGUgPT09ICd1cGxvYWRQcm9ncmVzcycpIHtcbiAgICAgICAgICAgIHRoaXMudXBsb2FkaW5nSW5mb3MkLm5leHQoZXZlbnQgYXMgVXBsb2FkaW5nSW5mb3MpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ3Jlc3BvbnNlJykge1xuICAgICAgICAgICAgdGhpcy50cmFja0luZGV4aW5nUHJvY2VzcyhldmVudC5ib2R5LnN0YXR1c1Rva2VuKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pLFxuICAgICAgICBjYXRjaEVycm9yKChlcnIpID0+IHtcbiAgICAgICAgICB0aGlzLnVwbG9hZGluZyQubmV4dChmYWxzZSk7IC8vIFNldCB0aGUgdXBsb2FkaW5nIGZsYWcgdG8gZmFsc2UgT05MWSBpbiBjYXNlIG9mIGFuIGVycm9yLiBPdGhlcndpc2UsIGtlZXAgaXQgdHJ1ZSB1bnRpbCB0aGUgc3RhcnQgb2YgaW5kZXhpbmcgcHJvY2VzcyBpbiBvcmRlciB0byBwcmV2ZW50IGZsaWNrZXJpbmcgb2YgdGhlIFVJXG4gICAgICAgICAgdGhpcy51cGxvYWRpbmdJbmZvcyQubmV4dCh1bmRlZmluZWQpOyAvLyBDbGVhciB0aGUgdXBsb2FkaW5nIGluZm9zXG4gICAgICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgICAgICAgIHRoaXMubm90aWZpY2F0aW9uc1NlcnZpY2UuZXJyb3IoXCJFcnJvciB1cGxvYWRpbmcgZmlsZXNcIik7XG4gICAgICAgICAgcmV0dXJuIEVNUFRZO1xuICAgICAgICB9KSxcbiAgICAgICAgZmluYWxpemUoKCkgPT4ge1xuICAgICAgICAgIC8vIENsZWFyIHRoZSBmbG93IGluc3RhbmNlIGFmdGVyIHRoZSB1cGxvYWQgaXMgY29tcGxldGUgb3IgYW4gZXJyb3Igb2NjdXJzXG4gICAgICAgICAgdGhpcy5mbG93LmNhbmNlbCgpO1xuICAgICAgICB9KVxuICAgICAgKS5zdWJzY3JpYmUoKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogVHJhY2tzIHRoZSBpbmRleGluZyBwcm9jZXNzIGZvciBhIHNpbmdsZSBkb2N1bWVudHMgdXBsb2FkIHNlc3Npb24gYnkgcG9sbGluZyB0aGUgQVBJIGZvciBpdHMgc3RhdHVzLlxuICAgKlxuICAgKiBAcGFyYW0gdG9rZW4gLSBBIHVuaXF1ZSB0b2tlbiByZXByZXNlbnRpbmcgdGhlIHNpbmdsZSBkb2N1bWVudHMgdXBsb2FkIHNlc3Npb24uXG4gICAqXG4gICAqIEByZW1hcmtzXG4gICAqIC0gQ2xlYXJzIHRoZSB1cGxvYWRpbmcgZmxhZ3MgYW5kIHNldHMgdGhlIGluZGV4aW5nIGZsYWcgdG8gdHJ1ZSBiZWZvcmUgc3RhcnRpbmcgdGhlIHByb2Nlc3MuXG4gICAqIC0gUG9sbHMgdGhlIEFQSSBldmVyeSBzZWNvbmQgdG8gcmV0cmlldmUgdGhlIGN1cnJlbnQgaW5kZXhpbmcgc3RhdHVzLlxuICAgKiAtIFVwZGF0ZXMgdGhlIGBpbmRleGluZ0luZm9zYCBwcm9wZXJ0eSB3aXRoIHRoZSBsYXRlc3Qgc3RhdHVzLlxuICAgKiAtIFN0b3BzIHBvbGxpbmcgd2hlbiB0aGUgaW5kZXhpbmcgcHJvY2VzcyBpcyBjb21wbGV0ZWQgb3IgYW4gZXJyb3Igb2NjdXJzLlxuICAgKiAtIENsZWFucyB1cCBieSByZXNldHRpbmcgdGhlIGluZGV4aW5nIGZsYWdzIGFuZCBjbGVhcmluZyB0aGUgYGluZGV4aW5nSW5mb3NgIHByb3BlcnR5IHdoZW4gdGhlIHByb2Nlc3MgaXMgZmluYWxpemVkLlxuICAgKi9cbiAgdHJhY2tJbmRleGluZ1Byb2Nlc3ModG9rZW46IHN0cmluZykge1xuICAgIC8vIENsZWFyIHRoZSB1cGxvYWRpbmcgZmxhZ3NcbiAgICB0aGlzLnVwbG9hZGluZyQubmV4dChmYWxzZSk7XG4gICAgdGhpcy51cGxvYWRpbmdJbmZvcyQubmV4dCh1bmRlZmluZWQpO1xuICAgIC8vIFNldCB0aGUgaW5kZXhpbmcgZmxhZyB0byB0cnVlXG4gICAgdGhpcy5pbmRleGluZyQubmV4dCh0cnVlKTtcblxuICAgIC8vIENvbWJpbmUgaW1tZWRpYXRlIEFQSSBjYWxsIHdpdGggaW50ZXJ2YWwtYmFzZWQgcG9sbGluZ1xuICAgIHRoaXMuX3N1YnNjcmlwdGlvbi5hZGQoXG4gICAgICBpbnRlcnZhbCh0aGlzLnBvbGxpbmdJbnRlcnZhbCkucGlwZShcbiAgICAgICAgc3RhcnRXaXRoKDApLCAvLyBUcmlnZ2VyIHRoZSBBUEkgY2FsbCBpbW1lZGlhdGVseVxuICAgICAgICBzd2l0Y2hNYXAoKCkgPT4gdGhpcy5kb2N1bWVudHNVcGxvYWRTZXJ2aWNlLmdldEluZGV4aW5nU3RhdHVzKHRva2VuKSksXG4gICAgICAgIHRhcCgocmVzOiBJbmRleGluZ0luZm9zKSA9PiB0aGlzLmluZGV4aW5nSW5mb3MkLm5leHQocmVzKSksXG4gICAgICAgIHRha2VXaGlsZSgocmVzcG9uc2U6IEluZGV4aW5nSW5mb3MpID0+ICFyZXNwb25zZS5pc0NvbXBsZXRlZCwgdHJ1ZSksXG4gICAgICAgIGNhdGNoRXJyb3IoKGVycikgPT4ge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcbiAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbnNTZXJ2aWNlLmVycm9yKFwiRXJyb3IgcmV0cmlldmluZyBpbmRleGluZyBzdGF0dXNcIik7XG4gICAgICAgICAgcmV0dXJuIEVNUFRZO1xuICAgICAgICB9KSxcbiAgICAgICAgZmluYWxpemUoKCkgPT4ge1xuICAgICAgICAgIC8vIENsZWFyIHRoZSBpbmRleGluZyBmbGFnc1xuICAgICAgICAgIHRoaXMuaW5kZXhpbmckLm5leHQoZmFsc2UpO1xuICAgICAgICAgIHRoaXMuaW5kZXhpbmdJbmZvcyQubmV4dCh1bmRlZmluZWQpO1xuICAgICAgICB9KVxuICAgICAgKS5zdWJzY3JpYmUoKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlcyB0aGUgaW5kZXhpbmcgcHJvZ3Jlc3MgYXMgYSBwZXJjZW50YWdlIG9mIGNvbXBsZXRlZCBkb2N1bWVudHMuXG4gICAqXG4gICAqIEBwYXJhbSBpbmZvcyAtIFRoZSBpbmRleGluZyBpbmZvcm1hdGlvbiBjb250YWluaW5nIHRoZSBsaXN0IG9mIGRvY3VtZW50cyBhbmQgdGhlaXIgc3RhdHVzZXMuXG4gICAqIEByZXR1cm5zIFRoZSBwcm9ncmVzcyBhcyBhIG51bWJlciBiZXR3ZWVuIDAgYW5kIDEsIHdoZXJlIDAgaW5kaWNhdGVzIG5vIHByb2dyZXNzIGFuZCAxIGluZGljYXRlcyBhbGwgZG9jdW1lbnRzIGFyZSBwcm9jZXNzZWQgKHByb2Nlc3NlZCBtZWFucyBlaXRoZXIgaW5kZXhlZCBvciBlcnJvcmVkKS5cbiAgICogICAgICAgICAgUmV0dXJucyAwIGlmIHRoZSBpbnB1dCBpcyBpbnZhbGlkIG9yIHRoZXJlIGFyZSBubyBkb2N1bWVudHMuXG4gICAqL1xuICBnZXRJbmRleGluZ1Byb2dyZXNzKGluZm9zOiBJbmRleGluZ0luZm9zIHwgdW5kZWZpbmVkKTogbnVtYmVyIHtcbiAgICBpZiAoIWluZm9zIHx8ICFpbmZvcy5kb2NzKSByZXR1cm4gMDtcbiAgICBjb25zdCBjb21wbGV0ZWQgPSBpbmZvcy5kb2NzLmZpbHRlcihkb2MgPT4gZG9jLnN0YXR1cyA9PT0gXCJJbmRleGVkXCIgfHwgZG9jLnN0YXR1cyA9PT0gXCJFcnJvclwiKS5sZW5ndGg7XG4gICAgY29uc3QgdG90YWwgPSBpbmZvcy5kb2NzLmxlbmd0aDtcbiAgICByZXR1cm4gY29tcGxldGVkL3RvdGFsO1xuICB9XG5cbn1cbiIsIjxuZy1jb250YWluZXIgI2Zsb3c9XCJmbG93XCIgW2Zsb3dDb25maWddPVwiZmxvd0NvbmZpZ1wiPjwvbmctY29udGFpbmVyPlxuPGRpdiBjbGFzcz1cImZpbGUtdXBsb2FkLWNvbnRhaW5lclwiPlxuICA8aW5wdXRcbiAgICB0eXBlPVwiZmlsZVwiXG4gICAgZmxvd0J1dHRvblxuICAgIFtmbG93XT1cImZsb3cuZmxvd0pzXCJcbiAgICBtdWx0aXBsZVxuICAgIGhpZGRlblxuICAgICNmaWxlSW5wdXQ+XG4gIDxkaXZcbiAgICBmbG93RHJvcFxuICAgIFtmbG93XT1cImZsb3cuZmxvd0pzXCJcbiAgICAoZHJhZ2VudGVyKT1cIm9uRHJhZ2VudGVyKClcIlxuICAgIChkcmFnbGVhdmUpPVwib25EcmFnbGVhdmUoJGV2ZW50KVwiXG4gICAgKGRyb3ApPVwib25Ecm9wKClcIlxuICAgIChjbGljayk9XCJmaWxlSW5wdXQuY2xpY2soKVwiXG4gICAgY2xhc3M9XCJkcm9wem9uZVwiXG4gICAgW25nQ2xhc3NdPVwieydkcm9wem9uZS0tYWN0aXZlJzogKGRyYWdnaW5nJCB8IGFzeW5jKX1cIlxuICAgIFtoaWRkZW5dPVwiKHVwbG9hZGluZyQgfCBhc3luYykgfHwgKGluZGV4aW5nJCB8IGFzeW5jKVwiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiEoZHJhZ2dpbmckIHwgYXN5bmMpOyBlbHNlIGRyYWdnaW5nQ29udGVudFwiPlxuICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1jbG91ZC11cGxvYWQtYWx0XCI+PC9pPlxuICAgICAgICA8c3Bhbj5EcmFnIGFuZCBkcm9wIGZpbGVzIGhlcmUgT3I8L3NwYW4+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1vcmFuZ2VcIj5DbGljayB0byBicm93c2U8L3NwYW4+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDxuZy10ZW1wbGF0ZSAjZHJhZ2dpbmdDb250ZW50PlxuICAgICAgICA8c3Bhbj5Ecm9wIGZpbGVzIGhlcmU8L3NwYW4+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuICA8L2Rpdj5cblxuICA8ZGl2ICpuZ0lmPVwiKHVwbG9hZGluZyQgfCBhc3luYykgfHwgKGluZGV4aW5nJCB8IGFzeW5jKVwiIGNsYXNzPVwiZHJvcHpvbmUgZHJvcHpvbmUtLWFjdGl2ZVwiPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIodXBsb2FkaW5nJCB8IGFzeW5jKTsgZWxzZSBpbmRleGluZ1N0YXRlXCI+XG4gICAgICA8aSBjbGFzcz1cImZhcyBmYS1zcGlubmVyIGZhLXB1bHNlXCI+PC9pPlxuICAgICAgPHNwYW4+XG4gICAgICAgIFVwbG9hZGluZyB7eyAoZmxvdy50cmFuc2ZlcnMkIHwgYXN5bmMpIS50cmFuc2ZlcnMubGVuZ3RoIH19IGZpbGVzXG4gICAgICA8L3NwYW4+XG4gICAgICA8c3BhbiAqbmdJZj1cIih1cGxvYWRpbmdJbmZvcyQgfCBhc3luYykgYXMgdXBsb2FkaW5nSW5mb3NcIj57eyB1cGxvYWRpbmdJbmZvcy5wcm9ncmVzcyB8IG51bWJlcjonMS4wLTAnIH19JTwvc3Bhbj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8bmctdGVtcGxhdGUgI2luZGV4aW5nU3RhdGU+XG4gICAgICA8aSBjbGFzcz1cImZhcyBmYS1zcGlubmVyIGZhLXB1bHNlXCI+PC9pPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImluZGV4aW5nSW5mb3MkIHwgYXN5bmMgYXMgaW5kZXhpbmdJbmZvXCI+XG4gICAgICAgIDxzcGFuPkluZGV4aW5nIHt7IGluZGV4aW5nSW5mby5kb2NzLmxlbmd0aCB9fSBmaWxlczwvc3Bhbj5cbiAgICAgICAgPHNwYW4+e3sgZ2V0SW5kZXhpbmdQcm9ncmVzcyhpbmRleGluZ0luZm8pICogMTAwIHwgbnVtYmVyOicxLjAtMCcgfX0lPC9zcGFuPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbiAgPC9kaXY+XG5cbiAgPHVsICpuZ0lmPVwiZXJyb3JBbGVydHMubGVuZ3RoID4gMFwiIGNsYXNzPVwiZXJyb3ItbGlzdCBtdC0zXCI+XG4gICAgPGxpICpuZ0Zvcj1cImxldCBlcnJvciBvZiBlcnJvckFsZXJ0c1wiPlxuICAgICAge3sgZXJyb3IgfX1cbiAgICA8L2xpPlxuICA8L3VsPlxuXG4gIDxkaXYgKm5nSWY9XCIoKGZsb3cudHJhbnNmZXJzJCB8IGFzeW5jKT8udHJhbnNmZXJzPy5sZW5ndGggPiAwKSAmJiAhKHVwbG9hZGluZyQgfCBhc3luYylcIiBjbGFzcz1cImZpbGUtbGlzdCBtdC0zXCI+XG4gICAgPHVsPlxuICAgICAgPGxpICpuZ0Zvcj1cImxldCB0cmFuc2ZlciBvZiAoZmxvdy50cmFuc2ZlcnMkIHwgYXN5bmMpIS50cmFuc2ZlcnM7IHRyYWNrQnk6IHRyYWNrVHJhbnNmZXJcIj5cbiAgICAgICAgPHNxLWZvcm1hdC1pY29uIFtleHRlbnNpb25dPVwidHJhbnNmZXIuZmxvd0ZpbGUuZ2V0RXh0ZW5zaW9uKClcIiBjbGFzcz1cIm1lLTFcIj48L3NxLWZvcm1hdC1pY29uPlxuICAgICAgICA8c3BhbiBbc3FUb29sdGlwXT1cInRyYW5zZmVyLm5hbWVcIj57eyB0cmFuc2Zlci5uYW1lIH19PC9zcGFuPlxuICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS10cmFzaCBtcy0xXCIgKGNsaWNrKT1cImZsb3cuY2FuY2VsRmlsZSh0cmFuc2ZlcilcIiBbc3FUb29sdGlwXT1cIidDYW5jZWwnXCI+PC9pPlxuICAgICAgPC9saT5cbiAgICA8L3VsPlxuICA8L2Rpdj5cblxuICA8ZGl2IGNsYXNzPVwiZC1mbGV4IG10LTJcIj5cbiAgICA8YnV0dG9uXG4gICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgIGNsYXNzPVwiYnRuIGJ0bi1saWdodCBjYW5jZWwtYnRuIG1lLTJcIlxuICAgICAgKGNsaWNrKT1cImZsb3cuY2FuY2VsKClcIlxuICAgICAgW2Rpc2FibGVkXT1cIiEoKGZsb3cudHJhbnNmZXJzJCB8IGFzeW5jKT8udHJhbnNmZXJzPy5sZW5ndGggPiAwKSB8fCAodXBsb2FkaW5nJCB8IGFzeW5jKSB8fCAoaW5kZXhpbmckIHwgYXN5bmMpXCI+XG4gICAgICBDYW5jZWxcbiAgICA8L2J1dHRvbj5cbiAgICA8YnV0dG9uXG4gICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgIGNsYXNzPVwidXBsb2FkLWJ0blwiXG4gICAgICAoY2xpY2spPVwidXBsb2FkKClcIlxuICAgICAgW2Rpc2FibGVkXT1cIiEoKGZsb3cudHJhbnNmZXJzJCB8IGFzeW5jKT8udHJhbnNmZXJzPy5sZW5ndGggPiAwKSB8fCAodXBsb2FkaW5nJCB8IGFzeW5jKSB8fCAoaW5kZXhpbmckIHwgYXN5bmMpXCI+XG4gICAgICBVcGxvYWRcbiAgICA8L2J1dHRvbj5cbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9jdW1lbnRzLXVwbG9hZC5tb2RlbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Fzc2lzdGFudC9jaGF0L2RvY3VtZW50cy11cGxvYWQvZG9jdW1lbnRzLXVwbG9hZC5tb2RlbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiXG5leHBvcnQgdHlwZSBVcGxvYWRDb25maWcgPSB7XG4gIGRvY3VtZW50c1VwbG9hZEVuYWJsZWQ6IGJvb2xlYW47XG4gIGNvbnN0cmFpbnRzOiB7XG4gICAgbWF4VG90YWxGaWxlU2l6ZU1COiBudW1iZXI7XG4gICAgcmVtYWluaW5nRmlsZVNpemVNQjogbnVtYmVyO1xuICAgIG1heFRvdGFsRmlsZUNvdW50OiBudW1iZXI7XG4gICAgcmVtYWluaW5nRmlsZUNvdW50OiBudW1iZXI7XG4gICAgc3VwcG9ydGVkRmlsZUV4dGVuc2lvbnM6IHN0cmluZ1tdXG4gIH1cbn1cblxuZXhwb3J0IHR5cGUgVXBsb2FkUmVzcG9uc2UgPSB7XG4gIHN0YXR1c1Rva2VuOiBzdHJpbmc7XG4gIGV4ZWN1dGlvblRpbWU6IHN0cmluZztcbiAgY29ubmVjdG9yUmVzcG9uc2U/OiB7XG4gICAgY29sbGVjdGlvbjogc3RyaW5nO1xuICAgIGFjdGlvbjogc3RyaW5nO1xuICAgIHN0YXRzOiB7XG4gICAgICBuYkRvY1VwZGF0ZWQ6IG51bWJlcjtcbiAgICB9O1xuICB9O1xufVxuXG5leHBvcnQgdHlwZSBVcGxvYWRpbmdJbmZvcyA9IHtcbiAgbG9hZGVkOiBudW1iZXI7XG4gIHRvdGFsOiBudW1iZXI7XG4gIHByb2dyZXNzOiBudW1iZXI7XG59XG5cbmV4cG9ydCB0eXBlIFVwbG9hZFByb2dyZXNzRXZlbnQgPSB7IHR5cGU6ICd1cGxvYWRQcm9ncmVzcyc7IH0gJiBVcGxvYWRpbmdJbmZvcztcblxuZXhwb3J0IGludGVyZmFjZSBVcGxvYWRSZXNwb25zZUV2ZW50IHtcbiAgdHlwZTogJ3Jlc3BvbnNlJztcbiAgYm9keTogVXBsb2FkUmVzcG9uc2U7XG59XG5cbmV4cG9ydCB0eXBlIFVwbG9hZEV2ZW50ID0gVXBsb2FkUHJvZ3Jlc3NFdmVudCB8IFVwbG9hZFJlc3BvbnNlRXZlbnQ7XG5cbmV4cG9ydCB0eXBlIEluZGV4aW5nSW5mb3MgPSB7XG4gIGRvY3M6IHtcbiAgICBpZDogc3RyaW5nO1xuICAgIGZpbGVOYW1lOiBzdHJpbmc7XG4gICAgb3BlcmF0aW9uOiBcIkFkZFwiIHwgXCJVcGRhdGVcIjtcbiAgICBzdGF0dXM6IFwiSW5kZXhpbmdcIiB8IFwiSW5kZXhlZFwiIHwgXCJFcnJvclwiO1xuICAgIHByZXZpb3VzSW5kZXhhdGlvblRpbWU6IHN0cmluZyB8IG51bGw7XG4gICAgY3VycmVudEluZGV4YXRpb25UaW1lOiBzdHJpbmcgfCBudWxsO1xuICB9W107XG4gIGlzQ29tcGxldGVkOiBib29sZWFuO1xuICBleGVjdXRpb25UaW1lOiBzdHJpbmc7XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIFVwbG9hZGVkRG9jdW1lbnRzIHtcbiAgZG9jczogVXBsb2FkZWREb2N1bWVudFtdO1xuICBjb3VudDogbnVtYmVyO1xuICB0b3RhbENvdW50OiBudW1iZXI7XG4gIGV4ZWN1dGlvblRpbWU6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBVcGxvYWRlZERvY3VtZW50IHtcbiAgaWQ6IHN0cmluZztcbiAgZmlsZU5hbWU6IHN0cmluZztcbiAgdGl0bGU6IHN0cmluZztcbiAgZmlsZUV4dDogc3RyaW5nO1xuICBpbmRleGF0aW9uVGltZTogc3RyaW5nO1xuICBzaXplOiBzdHJpbmc7XG4gIHNpemVEaXNwbGF5OiBzdHJpbmc7XG4gIFtrZXk6IHN0cmluZ106IGFueTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBkZWxldGVEb2N1bWVudHNSZXNwb25zZSB7XG4gIGRlbGV0ZWRDb3VudDogbnVtYmVyO1xuICBleGVjdXRpb25UaW1lOiBzdHJpbmc7XG59XG4iXX0=