@firestitch/report 18.0.3 → 18.0.4
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/app/reports/interfaces/report.interface.d.ts +1 -0
- package/app/reports/views/report/fs-ai-report.component.d.ts +43 -0
- package/app/reports/views/reports/fs-ai-reports.component.d.ts +23 -0
- package/esm2022/app/reports/interfaces/report.interface.mjs +1 -1
- package/esm2022/app/reports/views/report/fs-ai-report.component.mjs +312 -0
- package/esm2022/app/reports/views/reports/fs-ai-reports.component.mjs +112 -0
- package/esm2022/public_api.mjs +5 -1
- package/fesm2022/{firestitch-report-echarts-DibqM0Fw.mjs → firestitch-report-echarts-m2yVum4J.mjs} +2 -2
- package/fesm2022/{firestitch-report-echarts-DibqM0Fw.mjs.map → firestitch-report-echarts-m2yVum4J.mjs.map} +1 -1
- package/fesm2022/{firestitch-report-firestitch-report-UX1baw15.mjs → firestitch-report-firestitch-report-BclPOljK.mjs} +404 -14
- package/fesm2022/firestitch-report-firestitch-report-BclPOljK.mjs.map +1 -0
- package/fesm2022/firestitch-report.mjs +1 -1
- package/package.json +1 -1
- package/public_api.d.ts +2 -0
- package/fesm2022/firestitch-report-firestitch-report-UX1baw15.mjs.map +0 -1
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { FilterConfig } from '@firestitch/filter';
|
|
2
|
+
import { FsAiChatResponse } from '@firestitch/ai';
|
|
3
|
+
import { Report, ReportComponent as ReportComponentModel } from '../../interfaces/report.interface';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
export declare class FsAiReportComponent {
|
|
6
|
+
readonly reportId: import("@angular/core").InputSignal<number>;
|
|
7
|
+
readonly basePath: import("@angular/core").InputSignal<string>;
|
|
8
|
+
readonly deleted: import("@angular/core").OutputEmitterRef<number>;
|
|
9
|
+
readonly renamed: import("@angular/core").OutputEmitterRef<Report>;
|
|
10
|
+
report: Report | null;
|
|
11
|
+
editMode: boolean;
|
|
12
|
+
reportFilterConfig: FilterConfig;
|
|
13
|
+
private _split;
|
|
14
|
+
private _chatPanel;
|
|
15
|
+
private _reportData;
|
|
16
|
+
private _filterState;
|
|
17
|
+
private _exportCollector;
|
|
18
|
+
private _pptxService;
|
|
19
|
+
private _pdfService;
|
|
20
|
+
private _process;
|
|
21
|
+
private _dialog;
|
|
22
|
+
private _destroyRef;
|
|
23
|
+
private _cdRef;
|
|
24
|
+
private _zone;
|
|
25
|
+
constructor();
|
|
26
|
+
toggleEditMode(): void;
|
|
27
|
+
reportSettings(): void;
|
|
28
|
+
componentSettings(component: ReportComponentModel): void;
|
|
29
|
+
onCanvasReportChanged(): void;
|
|
30
|
+
exportPowerpoint(): void;
|
|
31
|
+
exportPdf(): void;
|
|
32
|
+
onChatResponse(response: FsAiChatResponse): void;
|
|
33
|
+
onResizeStart(event: PointerEvent): void;
|
|
34
|
+
private _resizeTo;
|
|
35
|
+
private _loadReport;
|
|
36
|
+
private _reportGroups;
|
|
37
|
+
get reportHasFilters(): boolean;
|
|
38
|
+
get reportFilterKey(): string;
|
|
39
|
+
private _buildReportConfig;
|
|
40
|
+
private _hasTimeSeriesChart;
|
|
41
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<FsAiReportComponent, never>;
|
|
42
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<FsAiReportComponent, "fs-ai-report", never, { "reportId": { "alias": "reportId"; "required": false; "isSignal": true; }; "basePath": { "alias": "basePath"; "required": false; "isSignal": true; }; }, { "deleted": "deleted"; "renamed": "renamed"; }, never, never, true, never>;
|
|
43
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { FsListComponent, FsListConfig } from '@firestitch/list';
|
|
2
|
+
import { ReportListItem } from '../../interfaces/report.interface';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
export declare class FsAiReportsComponent {
|
|
5
|
+
readonly basePath: import("@angular/core").InputSignal<string>;
|
|
6
|
+
readonly openPattern: import("@angular/core").InputSignal<string>;
|
|
7
|
+
readonly createPattern: import("@angular/core").InputSignal<string>;
|
|
8
|
+
readonly semantic: import("@angular/core").OutputEmitterRef<void>;
|
|
9
|
+
list: FsListComponent;
|
|
10
|
+
listConfig: FsListConfig<ReportListItem>;
|
|
11
|
+
private _reportData;
|
|
12
|
+
private _router;
|
|
13
|
+
private _route;
|
|
14
|
+
private _prompt;
|
|
15
|
+
private _destroyRef;
|
|
16
|
+
constructor();
|
|
17
|
+
openLink(report: ReportListItem): unknown[];
|
|
18
|
+
createReport(): void;
|
|
19
|
+
private _patternCommands;
|
|
20
|
+
private _initListConfig;
|
|
21
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<FsAiReportsComponent, never>;
|
|
22
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<FsAiReportsComponent, "fs-ai-reports", never, { "basePath": { "alias": "basePath"; "required": false; "isSignal": true; }; "openPattern": { "alias": "openPattern"; "required": false; "isSignal": true; }; "createPattern": { "alias": "createPattern"; "required": false; "isSignal": true; }; }, { "semantic": "semantic"; }, never, never, true, never>;
|
|
23
|
+
}
|
|
@@ -13,4 +13,4 @@ export const FREQUENCY_OPTIONS = [
|
|
|
13
13
|
{ value: 'quarter', name: 'Quarter' },
|
|
14
14
|
{ value: 'year', name: 'Annually' },
|
|
15
15
|
];
|
|
16
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LmludGVyZmFjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy9pbnRlcmZhY2VzL3JlcG9ydC5pbnRlcmZhY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsNkVBQTZFO0FBQzdFLG1FQUFtRTtBQUNuRSwrRUFBK0U7QUFDL0UsNEVBQTRFO0FBQzVFLG1DQUFtQztBQXdGbkMsK0VBQStFO0FBQy9FLDhFQUE4RTtBQUM5RSw2QkFBNkI7QUFDN0IsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQWdEO0lBQzVFLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFO0lBQzdCLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFO0lBQy9CLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFO0lBQ2pDLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFO0lBQ3JDLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFO0NBQ3BDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBUaGUgYXNzZW1ibGVkIHJlcG9ydCBzdHJ1Y3R1cmUgcmV0dXJuZWQgYnkgR0VUIC9hcGkvcmVwb3J0cy86aWQg4oCUIGNvbXBvc2VkXG4vLyBzZXJ2ZXItc2lkZSBmcm9tIHRoZSBub3JtYWxpemVkIHRhYmxlcyAocmVwb3J0cyDihpIgcmVwb3J0X3BhZ2VzIOKGklxuLy8gcmVwb3J0X2NvbXBvbmVudHMgKyByZXBvcnRfZmlsdGVycywgcGx1cyByZXBvcnRfZmlsdGVyX2dyb3VwcykuIEFsbCBrZXlzIGFyZVxuLy8gY2FtZWxDYXNlOyBjb21wb25lbnQgYGNvbmZpZ2AgaXMgdGhlIHN0YW5kYXJkIGZvcm1hdCB0aGUgcmVuZGVyZXIgbWFwcyB0b1xuLy8gRUNoYXJ0cyBvcHRpb25zIC8gRnNMaXN0IGNvbmZpZy5cblxuLy8gTGF5b3V0IG1vZGVzOiBGcmVlZm9ybSA9IGFic29sdXRlbHkgcG9zaXRpb25lZCBjb21wb25lbnRzIChkcmFnIGFueXdoZXJlKTtcbi8vIEZsb3cgPSBjb21wb25lbnRzIGZsb3cgbGlrZSByb3dzLCBlYWNoIHRha2luZyBmbG93V2lkdGggJSBvZiB0aGUgcGFnZSB3aWR0aC5cbmV4cG9ydCB0eXBlIFJlcG9ydExheW91dCA9ICdmcmVlZm9ybScgfCAnZmxvdyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwb3J0IHtcbiAgaWQ6IG51bWJlcjtcbiAgbmFtZTogc3RyaW5nO1xuICBwYWdlU2l6ZTogJ3dpZGVzY3JlZW4nIHwgJ2xldHRlcic7XG4gIHBhZ2VPcmllbnRhdGlvbjogJ2xhbmRzY2FwZScgfCAncG9ydHJhaXQnO1xuICBsYXlvdXQ6IFJlcG9ydExheW91dDtcbiAgLy8gSUFOQSB0aW1lem9uZSAoZS5nLiBBbWVyaWNhL05ld19Zb3JrKSBhbmNob3JpbmcgZGF0ZSBmaWx0ZXJpbmcgKyBjaGFydCBkYXRlXG4gIC8vIGJ1Y2tldGluZy4gbnVsbCBmYWxscyBiYWNrIHRvIHRoZSBhY2NvdW50IHpvbmUgdGhlbiBVVEMgKHJlc29sdmVkIHNlcnZlci1zaWRlKS5cbiAgdGltZXpvbmU6IHN0cmluZyB8IG51bGw7XG4gIC8vIFJlcG9ydC1sZXZlbCBjb25maWc6IHR5cG9ncmFwaGljIHN0eWxlcywgZXRjLiAoY2FtZWxDYXNlIEpTT04gY29sdW1uKS5cbiAgY29uZmlnOiBSZXBvcnRDb25maWc7XG4gIC8vIENhbnZhcyBkaW1lbnNpb25zIGluIElOQ0hFUyAodGhlIHJlcG9ydCdzIG5hdGl2ZSB1bml0IOKAlCBQREZzIGFuZFxuICAvLyBQb3dlclBvaW50IGFyZSBpbmNoLWJhc2VkLCBzbyBleHBvcnRzIGFyZSBkaW1lbnNpb25hbGx5IGV4YWN0KS5cbiAgcGFnZVdpZHRoOiBudW1iZXI7XG4gIHBhZ2VIZWlnaHQ6IG51bWJlcjtcbiAgcGFnZXM6IFJlcG9ydFBhZ2VbXTtcbiAgZmlsdGVyR3JvdXBzOiBSZXBvcnRGaWx0ZXJHcm91cFtdO1xufVxuXG4vLyBSZXBvcnQtbGV2ZWwgc3R5bGluZy4gU2l6ZXMgYXJlIGluIFBPSU5UUyAoMS83MlwiKSDigJQgdGhlIHJlcG9ydCdzIHR5cG9ncmFwaHlcbi8vIG1hcHMgMToxIHRvIFBERiAoNzJwdC9pbikgYW5kIFBvd2VyUG9pbnQgKHBvaW50IGZvbnQgc2l6ZXMpLCBzbyBhIHBvaW50XG4vLyB2YWx1ZSBpcyBkaW1lbnNpb25hbGx5IGV4YWN0IG9uIHNjcmVlbiBhbmQgaW4gZXZlcnkgZXhwb3J0LlxuZXhwb3J0IGludGVyZmFjZSBSZXBvcnRDb25maWcge1xuICBzdHlsZXM/OiBSZXBvcnRTdHlsZXM7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwb3J0U3R5bGVzIHtcbiAgaGVhZGluZz86IHsgc2l6ZT86IG51bWJlciB9O1xufVxuXG4vLyBDb250ZW50IHBhZGRpbmcgYXJvdW5kIGEgY29tcG9uZW50J3MgYm9keSwgaW4gSU5DSEVTICh0aGUgZ2VvbWV0cnkgdW5pdCkuXG5leHBvcnQgaW50ZXJmYWNlIENvbXBvbmVudFBhZGRpbmcge1xuICB0b3A/OiBudW1iZXI7XG4gIHJpZ2h0PzogbnVtYmVyO1xuICBib3R0b20/OiBudW1iZXI7XG4gIGxlZnQ/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwb3J0UGFnZSB7XG4gIGlkOiBudW1iZXI7XG4gIG5hbWU6IHN0cmluZyB8IG51bGw7XG4gIG9yZGVyOiBudW1iZXI7XG4gIGNvbXBvbmVudHM6IFJlcG9ydENvbXBvbmVudFtdO1xufVxuXG5leHBvcnQgdHlwZSBSZXBvcnRDb21wb25lbnRUeXBlID0gJ2NoYXJ0JyB8ICdsaXN0JyB8ICdrcGknO1xuXG5leHBvcnQgaW50ZXJmYWNlIFJlcG9ydENvbXBvbmVudCB7XG4gIGlkOiBudW1iZXI7XG4gIHR5cGU6IFJlcG9ydENvbXBvbmVudFR5cGU7XG4gIHRpdGxlOiBzdHJpbmcgfCBudWxsO1xuICAvLyBHZW9tZXRyeSBpbiBJTkNIRVMuIEZyZWVmb3JtOiBhYnNvbHV0ZSBwb3NpdGlvbiBvbiB0aGUgcGFnZSBjYW52YXMuXG4gIC8vIEZsb3c6IG9ubHkgZmxvd1dpZHRoL29yZGVyIGFwcGx5OyB4L3kgYXJlIHJlbWVtYmVyZWQgZm9yIGEgc3dpdGNoIGJhY2sgdG9cbiAgLy8gZnJlZWZvcm0uXG4gIHg6IG51bWJlcjtcbiAgeTogbnVtYmVyO1xuICB3OiBudW1iZXI7XG4gIGg6IG51bWJlcjtcbiAgLy8gSGVpZ2h0IG1vZGUsIERFUklWRUQgZnJvbSB0eXBlIHNlcnZlci1zaWRlIChub3Qgc3RvcmVkLCByZWFkLW9ubHkpOiBsaXN0c1xuICAvLyBhbmQgS1BJIHRpbGVzIGFyZSBhdXRvICh0aGUgYm94IHNpemVzIHRvIGl0cyBjb250ZW50LCBgaGAgaWdub3JlZCk7IGNoYXJ0c1xuICAvLyBhcmUgYWx3YXlzIGZpeGVkICh1c2UgYGhgKSBzbyB0aGV5IGZpdCB0aGUgYm94IGFuZCBuZXZlciBvdmVyZmxvdy5cbiAgYXV0b0hlaWdodDogYm9vbGVhbjtcbiAgLy8gRmxvdyBsYXlvdXQ6ICUgb2YgdGhlIHBhZ2UgY29udGVudCB3aWR0aCB0aGlzIGNvbXBvbmVudCB0YWtlcy5cbiAgZmxvd1dpZHRoOiBudW1iZXI7XG4gIC8vIEZsb3cgbGF5b3V0IG9yZGVyaW5nLlxuICBvcmRlcjogbnVtYmVyO1xuICBzcWw6IHN0cmluZyB8IG51bGw7XG4gIGNvbmZpZzogQ2hhcnRDb25maWcgJiBMaXN0Q29uZmlnICYgS3BpQ29uZmlnICYgQ29tcG9uZW50TGF5b3V0Q29uZmlnICYgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIGZpbHRlcnM6IFJlcG9ydEZpbHRlcltdO1xufVxuXG4vLyBDcm9zcy10eXBlIGxheW91dC9zdHlsZSBrZXlzIGNhcnJpZWQgaW4gYSBjb21wb25lbnQncyBjb25maWcgKGFsb25nc2lkZSB0aGVcbi8vIHR5cGUtc3BlY2lmaWMgY2hhcnQvbGlzdC9rcGkga2V5cykuXG5leHBvcnQgaW50ZXJmYWNlIENvbXBvbmVudExheW91dENvbmZpZyB7XG4gIHBhZGRpbmc/OiBDb21wb25lbnRQYWRkaW5nO1xufVxuXG4vLyBXaGVyZSBhIGNoYXJ0J3MgbGVnZW5kIHNpdHMgcmVsYXRpdmUgdG8gdGhlIHBsb3QsIG9yICdoaWRkZW4nIHRvIGRyb3AgaXQuXG5leHBvcnQgdHlwZSBMZWdlbmRQb3NpdGlvbiA9ICd0b3AnIHwgJ2JvdHRvbScgfCAnbGVmdCcgfCAncmlnaHQnIHwgJ2hpZGRlbic7XG5cbmV4cG9ydCB0eXBlIENoYXJ0R3JhbnVsYXJpdHkgPSAnZGF5JyB8ICd3ZWVrJyB8ICdtb250aCcgfCAncXVhcnRlcicgfCAneWVhcic7XG5cbi8vIFRoZSBydW50aW1lIEZyZXF1ZW5jeSBjb250cm9sJ3MgY2hvaWNlcyDigJQgcmUtYnVja2V0cyBldmVyeSB0aW1lLXNlcmllcyBjaGFydFxuLy8gYXQgdmlldyB0aW1lLCBvdmVycmlkaW5nIGVhY2ggY2hhcnQncyBhdXRob3JlZCBncmFudWxhcml0eS4gJ3llYXInIHJlYWRzIGFzXG4vLyBcIkFubnVhbGx5XCIgaW4gdGhlIGNvbnRyb2wuXG5leHBvcnQgY29uc3QgRlJFUVVFTkNZX09QVElPTlM6IHsgdmFsdWU6IENoYXJ0R3JhbnVsYXJpdHk7IG5hbWU6IHN0cmluZyB9W10gPSBbXG4gIHsgdmFsdWU6ICdkYXknLCBuYW1lOiAnRGF5JyB9LFxuICB7IHZhbHVlOiAnd2VlaycsIG5hbWU6ICdXZWVrJyB9LFxuICB7IHZhbHVlOiAnbW9udGgnLCBuYW1lOiAnTW9udGgnIH0sXG4gIHsgdmFsdWU6ICdxdWFydGVyJywgbmFtZTogJ1F1YXJ0ZXInIH0sXG4gIHsgdmFsdWU6ICd5ZWFyJywgbmFtZTogJ0FubnVhbGx5JyB9LFxuXTtcblxuZXhwb3J0IGludGVyZmFjZSBDaGFydENvbmZpZyB7XG4gIGNoYXJ0VHlwZT86ICdiYXInIHwgJ2xpbmUnIHwgJ2FyZWEnIHwgJ3BpZScgfCAnZG9udXQnO1xuICAvLyBGb3Iga2luZCAndGltZScsIHRoZSBzZXJ2ZXIgYnVja2V0cyB0aGUgcmF3IGRhdGV0aW1lIGNvbHVtbiB0byBgZ3JhbnVsYXJpdHlgXG4gIC8vIGluIHRoZSByZXBvcnQncyB0aW1lem9uZSAodGhlIFNRTCBleHBvc2VzIHRoZSByYXcgY29sdW1uLCB1bmJ1Y2tldGVkKS5cbiAgeEF4aXM/OiB7IGNvbHVtbjogc3RyaW5nOyBraW5kPzogJ2NhdGVnb3J5JyB8ICd0aW1lJzsgZ3JhbnVsYXJpdHk/OiBDaGFydEdyYW51bGFyaXR5OyBsYWJlbD86IHN0cmluZyB9O1xuICBtZWFzdXJlcz86IENoYXJ0TWVhc3VyZVtdO1xuICBzcGxpdEJ5PzogeyBjb2x1bW46IHN0cmluZzsgbGFiZWw/OiBzdHJpbmcgfTtcbiAgLy8gU2luZ2xlLWRpbWVuc2lvbiBiYXIgY2hhcnRzIG9ubHk6IGNvbG9yIGVhY2ggYmFyIGJ5IGl0cyBvd24gY2F0ZWdvcnkgYW5kXG4gIC8vIHNob3cgYSBsZWdlbmQsIFdJVEhPVVQgc3BsaXR0aW5nIGludG8gbXVsdGlwbGUgc2VyaWVzICh3aGljaCBzbGl2ZXJzIHRoZVxuICAvLyBiYXJzKS4gdjEgZXhwZWN0cyBjb2xvckJ5LmNvbHVtbiA9PT0geEF4aXMuY29sdW1uLiBJZ25vcmVkIHdoZW4gc3BsaXRCeSBpc1xuICAvLyBzZXQgb3IgdGhlIGNoYXJ0IGlzbid0IGEgYmFyIGNoYXJ0LlxuICBjb2xvckJ5PzogeyBjb2x1bW46IHN0cmluZzsgbGFiZWw/OiBzdHJpbmcgfTtcbiAgb3JpZW50YXRpb24/OiAndmVydGljYWwnIHwgJ2hvcml6b250YWwnO1xuICBzdGFja2VkPzogYm9vbGVhbjtcbiAgbGVnZW5kPzogTGVnZW5kUG9zaXRpb247XG4gIHNvcnQ/OiBSZXBvcnRTb3J0O1xuICBsaW1pdD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDaGFydE1lYXN1cmUge1xuICBjb2x1bW46IHN0cmluZztcbiAgYWdncmVnYXRpb24/OiAnc3VtJyB8ICdjb3VudCcgfCAnYXZnJyB8ICdtaW4nIHwgJ21heCc7XG4gIGxhYmVsPzogc3RyaW5nO1xuICBmb3JtYXQ/OiAnbnVtYmVyJyB8ICdwZXJjZW50JyB8ICdjdXJyZW5jeSc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTGlzdENvbmZpZyB7XG4gIGNvbHVtbnM/OiB7IGNvbHVtbjogc3RyaW5nOyBsYWJlbD86IHN0cmluZzsgZm9ybWF0PzogJ2RhdGUnIHwgJ251bWJlcicgfVtdO1xuICBzb3J0PzogUmVwb3J0U29ydDtcbiAgcGFnZVNpemU/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgS3BpQ29uZmlnIHtcbiAgbWVhc3VyZT86IENoYXJ0TWVhc3VyZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXBvcnRTb3J0IHtcbiAgY29sdW1uOiBzdHJpbmc7XG4gIGRpcmVjdGlvbj86ICdhc2MnIHwgJ2Rlc2MnO1xufVxuXG5leHBvcnQgdHlwZSBSZXBvcnRGaWx0ZXJUeXBlID0gJ2RhdGVSYW5nZScgfCAnc2VsZWN0JyB8ICdrZXl3b3JkJztcblxuLy8gV2hlcmUgYSBmaWx0ZXIgZ3JvdXAncyBjb250cm9sIGlzIGV4cG9zZWQuIEEgZ3JvdXAgY2FuIGJlIHNob3duIG9uIGl0c1xuLy8gY29tcG9uZW50cywgaW4gdGhlIHJlcG9ydCBiYXIsIG9yIEJPVEggYXQgb25jZSAodGhlIHR3byBhcmUgaW5kZXBlbmRlbnRcbi8vIHRvZ2dsZXMgaW4gdGhlIFVJKTsgYSBjb2x1bW4gd2l0aCBuZWl0aGVyIGV4cG9zZWQgc2ltcGx5IGhhcyBubyBmaWx0ZXIuXG5leHBvcnQgdHlwZSBSZXBvcnRGaWx0ZXJMZXZlbCA9ICdjb21wb25lbnQnIHwgJ3JlcG9ydCcgfCAnYm90aCc7XG5cbi8vIE9uZSBmaWx0ZXJhYmxlIG91dHB1dCBjb2x1bW4gb2YgYSBjb21wb25lbnQncyBTUUwsIHdpdGggdGhlIGZpbHRlciBpbnRlcmZhY2Vcbi8vIElORkVSUkVEIGZyb20gaXRzIGRhdGEgKHRoZSBodW1hbiBuZXZlciBwaWNrcyB0aGUgaW50ZXJmYWNlIOKAlCBpdCBmb2xsb3dzIHRoZVxuLy8gY29sdW1uJ3MgdHlwZSkuIERyaXZlcyB0aGUgRmlsdGVycyB0YWIgbGlzdGluZy5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwb3J0RmlsdGVyYWJsZUNvbHVtbiB7XG4gIGNvbHVtbjogc3RyaW5nO1xuICB0eXBlOiBSZXBvcnRGaWx0ZXJUeXBlO1xufVxuXG4vLyBHcm91bmQgdHJ1dGg6IG9uZSBmaWx0ZXJhYmxlIG91dHB1dCBjb2x1bW4gT04gb25lIGNvbXBvbmVudCdzIFNRTC4gQWx3YXlzIGFcbi8vIG1lbWJlciBvZiBhIGZpbHRlciBncm91cCDigJQgdGhlIHVuaXQgdGhhdCBsaW5rcyBlcXVpdmFsZW50IGZpbHRlcnMgYWNyb3NzXG4vLyBjb21wb25lbnRzIGFuZCBkZWNpZGVzIHdoZXJlIHRoZSBjb250cm9sIHJlbmRlcnMgKGNvbXBvbmVudCB2cyByZXBvcnQgYmFyKS5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwb3J0RmlsdGVyIHtcbiAgaWQ6IG51bWJlcjtcbiAgY29tcG9uZW50SWQ6IG51bWJlcjtcbiAgZmlsdGVyR3JvdXBJZDogbnVtYmVyO1xuICBmaWx0ZXJDb2x1bW46IHN0cmluZztcbiAgbGFiZWw6IHN0cmluZyB8IG51bGw7XG4gIGVuYWJsZWQ6IGJvb2xlYW47XG4gIGhhc09wdGlvbnM6IGJvb2xlYW47XG4gIGNvbmZpZzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwb3J0RmlsdGVyR3JvdXAge1xuICBpZDogbnVtYmVyO1xuICBsYWJlbDogc3RyaW5nIHwgbnVsbDtcbiAgdHlwZTogUmVwb3J0RmlsdGVyVHlwZTtcbiAgbGV2ZWw6IFJlcG9ydEZpbHRlckxldmVsO1xuICBvcmRlcjogbnVtYmVyO1xuICBjb25maWc6IHsgZGVmYXVsdD86IEZpbHRlckdyb3VwRGVmYXVsdCB9ICYgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIGZpbHRlcnM6IFJlcG9ydEZpbHRlcltdO1xufVxuXG4vLyBBIGZpbHRlciBncm91cCdzIGF1dGhvcmVkIGRlZmF1bHQg4oCUIHRoZSB2YWx1ZSB0aGF0IHNlZWRzIHRoZSByZXBvcnQgYmFyIG9uXG4vLyBldmVyeSBvcGVuLiBTaGFwZSBmb2xsb3dzIHRoZSBncm91cCdzIHR5cGU6IGRhdGVSYW5nZSB1c2VzIHN0YXJ0L2VuZCAoYSBmaXhlZFxuLy8gY2FsZW5kYXItZGF5IHJhbmdlKSBvciBhIHJlbGF0aXZlIHByZXNldDsgc2VsZWN0IHVzZXMgdmFsdWVzOyBrZXl3b3JkIHVzZXNcbi8vIHZhbHVlLlxuZXhwb3J0IGludGVyZmFjZSBGaWx0ZXJHcm91cERlZmF1bHQge1xuICByZWxhdGl2ZT86IHN0cmluZzsgLy8gZGF0ZVJhbmdlIHJlbGF0aXZlIHByZXNldCwgZS5nLiBsYXN0MTJNb250aHMsIHllYXJUb0RhdGVcbiAgc3RhcnQ/OiBzdHJpbmc7IC8vIGRhdGVSYW5nZSBmaXhlZCBzdGFydCAoeXl5eS1NTS1kZClcbiAgZW5kPzogc3RyaW5nOyAvLyBkYXRlUmFuZ2UgZml4ZWQgZW5kICh5eXl5LU1NLWRkKVxuICB2YWx1ZXM/OiB1bmtub3duW107IC8vIHNlbGVjdCBkZWZhdWx0IHBpY2tlZCB2YWx1ZXNcbiAgdmFsdWU/OiBzdHJpbmc7IC8vIGtleXdvcmQgZGVmYXVsdCB0ZXh0XG59XG5cbi8vIFRoZSBzZXNzaW9uIHZhbHVlIG9mIGEgZmlsdGVyIGdyb3VwIChuZXZlciBwZXJzaXN0ZWQpOiBzaGFwZSBkZXBlbmRzIG9uIHRoZVxuLy8gZ3JvdXAncyB0eXBlLlxuZXhwb3J0IGludGVyZmFjZSBGaWx0ZXJHcm91cFZhbHVlIHtcbiAgc3RhcnQ/OiBEYXRlIHwgc3RyaW5nIHwgbnVsbDsgLy8gZGF0ZVJhbmdlXG4gIGVuZD86IERhdGUgfCBzdHJpbmcgfCBudWxsOyAvLyBkYXRlUmFuZ2VcbiAgdmFsdWVzPzogdW5rbm93bltdOyAvLyBzZWxlY3RcbiAgdmFsdWU/OiBzdHJpbmc7IC8vIGtleXdvcmRcbn1cblxuLy8gT25lIHJlc29sdmVkIGZpbHRlciBzZW50IHdpdGggYSBjb21wb25lbnQncyBkYXRhIHJlcXVlc3QuXG5leHBvcnQgaW50ZXJmYWNlIFJlc29sdmVkRmlsdGVyVmFsdWUge1xuICBmaWx0ZXJJZDogbnVtYmVyO1xuICBzdGFydD86IHN0cmluZztcbiAgZW5kPzogc3RyaW5nO1xuICB2YWx1ZXM/OiB1bmtub3duW107XG4gIHZhbHVlPzogc3RyaW5nO1xufVxuXG4vLyBQZXItY29tcG9uZW50IGludGVyYWN0aW9uIHN0YXRlIHNlbnQgd2l0aCB0aGUgZGF0YSByZXF1ZXN0OiBsaXN0cyBzZW5kXG4vLyBzb3J0L3BhZ2luZzsgdGltZS1zZXJpZXMgY2hhcnRzIHNlbmQgdGhlIHZpZXdlcidzIGNob3NlbiBGcmVxdWVuY3ksIHdoaWNoXG4vLyBvdmVycmlkZXMgdGhlIGF1dGhvcmVkIGdyYW51bGFyaXR5IGZvciB0aGF0IHJlcXVlc3Qgb25seS5cbmV4cG9ydCBpbnRlcmZhY2UgQ29tcG9uZW50RGF0YVN0YXRlIHtcbiAgc29ydD86IFJlcG9ydFNvcnQ7XG4gIHBhZ2U/OiBudW1iZXI7XG4gIHBhZ2VTaXplPzogbnVtYmVyO1xuICBmcmVxdWVuY3k/OiBDaGFydEdyYW51bGFyaXR5O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbXBvbmVudERhdGEge1xuICBjb2x1bW5zOiBzdHJpbmdbXTtcbiAgcm93czogUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXTtcbiAgcGFnaW5nPzogeyB0b3RhbDogbnVtYmVyOyBwYWdlOiBudW1iZXI7IHBhZ2VTaXplOiBudW1iZXIgfTtcbiAgdHJ1bmNhdGVkOiBib29sZWFuO1xuICAvLyBUaGUgZWZmZWN0aXZlIHRpbWUgYnVja2V0IHRoZSByb3dzIHdlcmUgZ3JvdXBlZCBpbnRvIChhZnRlciBhbnkgRnJlcXVlbmN5XG4gIC8vIG92ZXJyaWRlKSwgb3IgbnVsbCBmb3IgYSBub24tdGltZSBheGlzLiBEcml2ZXMgdGhlIGNvbXBhY3QgeC1heGlzIGxhYmVscy5cbiAgZ3JhbnVsYXJpdHk/OiBDaGFydEdyYW51bGFyaXR5IHwgbnVsbDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXBvcnRMaXN0SXRlbSB7XG4gIGlkOiBudW1iZXI7XG4gIG5hbWU6IHN0cmluZztcbn1cblxuLy8gVGhlIGNoYXQgdHVybiBmbGFncyB0aGlzIGNvbnRleHQncyBiYWNrZW5kIGFkZHMgKFJlcG9ydHNcXEFpVmlldykuXG5leHBvcnQgaW50ZXJmYWNlIFJlcG9ydENoYXRSZXNwb25zZSB7XG4gIHJlcG9ydENoYW5nZWQ/OiBib29sZWFuO1xuICByZXBvcnRSZW5hbWVkPzogYm9vbGVhbjtcbn1cbiJdfQ==
|
|
16
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LmludGVyZmFjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy9pbnRlcmZhY2VzL3JlcG9ydC5pbnRlcmZhY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsNkVBQTZFO0FBQzdFLG1FQUFtRTtBQUNuRSwrRUFBK0U7QUFDL0UsNEVBQTRFO0FBQzVFLG1DQUFtQztBQXdGbkMsK0VBQStFO0FBQy9FLDhFQUE4RTtBQUM5RSw2QkFBNkI7QUFDN0IsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQWdEO0lBQzVFLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFO0lBQzdCLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFO0lBQy9CLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFO0lBQ2pDLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFO0lBQ3JDLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFO0NBQ3BDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBUaGUgYXNzZW1ibGVkIHJlcG9ydCBzdHJ1Y3R1cmUgcmV0dXJuZWQgYnkgR0VUIC9hcGkvcmVwb3J0cy86aWQg4oCUIGNvbXBvc2VkXG4vLyBzZXJ2ZXItc2lkZSBmcm9tIHRoZSBub3JtYWxpemVkIHRhYmxlcyAocmVwb3J0cyDihpIgcmVwb3J0X3BhZ2VzIOKGklxuLy8gcmVwb3J0X2NvbXBvbmVudHMgKyByZXBvcnRfZmlsdGVycywgcGx1cyByZXBvcnRfZmlsdGVyX2dyb3VwcykuIEFsbCBrZXlzIGFyZVxuLy8gY2FtZWxDYXNlOyBjb21wb25lbnQgYGNvbmZpZ2AgaXMgdGhlIHN0YW5kYXJkIGZvcm1hdCB0aGUgcmVuZGVyZXIgbWFwcyB0b1xuLy8gRUNoYXJ0cyBvcHRpb25zIC8gRnNMaXN0IGNvbmZpZy5cblxuLy8gTGF5b3V0IG1vZGVzOiBGcmVlZm9ybSA9IGFic29sdXRlbHkgcG9zaXRpb25lZCBjb21wb25lbnRzIChkcmFnIGFueXdoZXJlKTtcbi8vIEZsb3cgPSBjb21wb25lbnRzIGZsb3cgbGlrZSByb3dzLCBlYWNoIHRha2luZyBmbG93V2lkdGggJSBvZiB0aGUgcGFnZSB3aWR0aC5cbmV4cG9ydCB0eXBlIFJlcG9ydExheW91dCA9ICdmcmVlZm9ybScgfCAnZmxvdyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwb3J0IHtcbiAgaWQ6IG51bWJlcjtcbiAgbmFtZTogc3RyaW5nO1xuICBwYWdlU2l6ZTogJ3dpZGVzY3JlZW4nIHwgJ2xldHRlcic7XG4gIHBhZ2VPcmllbnRhdGlvbjogJ2xhbmRzY2FwZScgfCAncG9ydHJhaXQnO1xuICBsYXlvdXQ6IFJlcG9ydExheW91dDtcbiAgLy8gSUFOQSB0aW1lem9uZSAoZS5nLiBBbWVyaWNhL05ld19Zb3JrKSBhbmNob3JpbmcgZGF0ZSBmaWx0ZXJpbmcgKyBjaGFydCBkYXRlXG4gIC8vIGJ1Y2tldGluZy4gbnVsbCBmYWxscyBiYWNrIHRvIHRoZSBhY2NvdW50IHpvbmUgdGhlbiBVVEMgKHJlc29sdmVkIHNlcnZlci1zaWRlKS5cbiAgdGltZXpvbmU6IHN0cmluZyB8IG51bGw7XG4gIC8vIFJlcG9ydC1sZXZlbCBjb25maWc6IHR5cG9ncmFwaGljIHN0eWxlcywgZXRjLiAoY2FtZWxDYXNlIEpTT04gY29sdW1uKS5cbiAgY29uZmlnOiBSZXBvcnRDb25maWc7XG4gIC8vIENhbnZhcyBkaW1lbnNpb25zIGluIElOQ0hFUyAodGhlIHJlcG9ydCdzIG5hdGl2ZSB1bml0IOKAlCBQREZzIGFuZFxuICAvLyBQb3dlclBvaW50IGFyZSBpbmNoLWJhc2VkLCBzbyBleHBvcnRzIGFyZSBkaW1lbnNpb25hbGx5IGV4YWN0KS5cbiAgcGFnZVdpZHRoOiBudW1iZXI7XG4gIHBhZ2VIZWlnaHQ6IG51bWJlcjtcbiAgcGFnZXM6IFJlcG9ydFBhZ2VbXTtcbiAgZmlsdGVyR3JvdXBzOiBSZXBvcnRGaWx0ZXJHcm91cFtdO1xufVxuXG4vLyBSZXBvcnQtbGV2ZWwgc3R5bGluZy4gU2l6ZXMgYXJlIGluIFBPSU5UUyAoMS83MlwiKSDigJQgdGhlIHJlcG9ydCdzIHR5cG9ncmFwaHlcbi8vIG1hcHMgMToxIHRvIFBERiAoNzJwdC9pbikgYW5kIFBvd2VyUG9pbnQgKHBvaW50IGZvbnQgc2l6ZXMpLCBzbyBhIHBvaW50XG4vLyB2YWx1ZSBpcyBkaW1lbnNpb25hbGx5IGV4YWN0IG9uIHNjcmVlbiBhbmQgaW4gZXZlcnkgZXhwb3J0LlxuZXhwb3J0IGludGVyZmFjZSBSZXBvcnRDb25maWcge1xuICBzdHlsZXM/OiBSZXBvcnRTdHlsZXM7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwb3J0U3R5bGVzIHtcbiAgaGVhZGluZz86IHsgc2l6ZT86IG51bWJlciB9O1xufVxuXG4vLyBDb250ZW50IHBhZGRpbmcgYXJvdW5kIGEgY29tcG9uZW50J3MgYm9keSwgaW4gSU5DSEVTICh0aGUgZ2VvbWV0cnkgdW5pdCkuXG5leHBvcnQgaW50ZXJmYWNlIENvbXBvbmVudFBhZGRpbmcge1xuICB0b3A/OiBudW1iZXI7XG4gIHJpZ2h0PzogbnVtYmVyO1xuICBib3R0b20/OiBudW1iZXI7XG4gIGxlZnQ/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwb3J0UGFnZSB7XG4gIGlkOiBudW1iZXI7XG4gIG5hbWU6IHN0cmluZyB8IG51bGw7XG4gIG9yZGVyOiBudW1iZXI7XG4gIGNvbXBvbmVudHM6IFJlcG9ydENvbXBvbmVudFtdO1xufVxuXG5leHBvcnQgdHlwZSBSZXBvcnRDb21wb25lbnRUeXBlID0gJ2NoYXJ0JyB8ICdsaXN0JyB8ICdrcGknO1xuXG5leHBvcnQgaW50ZXJmYWNlIFJlcG9ydENvbXBvbmVudCB7XG4gIGlkOiBudW1iZXI7XG4gIHR5cGU6IFJlcG9ydENvbXBvbmVudFR5cGU7XG4gIHRpdGxlOiBzdHJpbmcgfCBudWxsO1xuICAvLyBHZW9tZXRyeSBpbiBJTkNIRVMuIEZyZWVmb3JtOiBhYnNvbHV0ZSBwb3NpdGlvbiBvbiB0aGUgcGFnZSBjYW52YXMuXG4gIC8vIEZsb3c6IG9ubHkgZmxvd1dpZHRoL29yZGVyIGFwcGx5OyB4L3kgYXJlIHJlbWVtYmVyZWQgZm9yIGEgc3dpdGNoIGJhY2sgdG9cbiAgLy8gZnJlZWZvcm0uXG4gIHg6IG51bWJlcjtcbiAgeTogbnVtYmVyO1xuICB3OiBudW1iZXI7XG4gIGg6IG51bWJlcjtcbiAgLy8gSGVpZ2h0IG1vZGUsIERFUklWRUQgZnJvbSB0eXBlIHNlcnZlci1zaWRlIChub3Qgc3RvcmVkLCByZWFkLW9ubHkpOiBsaXN0c1xuICAvLyBhbmQgS1BJIHRpbGVzIGFyZSBhdXRvICh0aGUgYm94IHNpemVzIHRvIGl0cyBjb250ZW50LCBgaGAgaWdub3JlZCk7IGNoYXJ0c1xuICAvLyBhcmUgYWx3YXlzIGZpeGVkICh1c2UgYGhgKSBzbyB0aGV5IGZpdCB0aGUgYm94IGFuZCBuZXZlciBvdmVyZmxvdy5cbiAgYXV0b0hlaWdodDogYm9vbGVhbjtcbiAgLy8gRmxvdyBsYXlvdXQ6ICUgb2YgdGhlIHBhZ2UgY29udGVudCB3aWR0aCB0aGlzIGNvbXBvbmVudCB0YWtlcy5cbiAgZmxvd1dpZHRoOiBudW1iZXI7XG4gIC8vIEZsb3cgbGF5b3V0IG9yZGVyaW5nLlxuICBvcmRlcjogbnVtYmVyO1xuICBzcWw6IHN0cmluZyB8IG51bGw7XG4gIGNvbmZpZzogQ2hhcnRDb25maWcgJiBMaXN0Q29uZmlnICYgS3BpQ29uZmlnICYgQ29tcG9uZW50TGF5b3V0Q29uZmlnICYgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIGZpbHRlcnM6IFJlcG9ydEZpbHRlcltdO1xufVxuXG4vLyBDcm9zcy10eXBlIGxheW91dC9zdHlsZSBrZXlzIGNhcnJpZWQgaW4gYSBjb21wb25lbnQncyBjb25maWcgKGFsb25nc2lkZSB0aGVcbi8vIHR5cGUtc3BlY2lmaWMgY2hhcnQvbGlzdC9rcGkga2V5cykuXG5leHBvcnQgaW50ZXJmYWNlIENvbXBvbmVudExheW91dENvbmZpZyB7XG4gIHBhZGRpbmc/OiBDb21wb25lbnRQYWRkaW5nO1xufVxuXG4vLyBXaGVyZSBhIGNoYXJ0J3MgbGVnZW5kIHNpdHMgcmVsYXRpdmUgdG8gdGhlIHBsb3QsIG9yICdoaWRkZW4nIHRvIGRyb3AgaXQuXG5leHBvcnQgdHlwZSBMZWdlbmRQb3NpdGlvbiA9ICd0b3AnIHwgJ2JvdHRvbScgfCAnbGVmdCcgfCAncmlnaHQnIHwgJ2hpZGRlbic7XG5cbmV4cG9ydCB0eXBlIENoYXJ0R3JhbnVsYXJpdHkgPSAnZGF5JyB8ICd3ZWVrJyB8ICdtb250aCcgfCAncXVhcnRlcicgfCAneWVhcic7XG5cbi8vIFRoZSBydW50aW1lIEZyZXF1ZW5jeSBjb250cm9sJ3MgY2hvaWNlcyDigJQgcmUtYnVja2V0cyBldmVyeSB0aW1lLXNlcmllcyBjaGFydFxuLy8gYXQgdmlldyB0aW1lLCBvdmVycmlkaW5nIGVhY2ggY2hhcnQncyBhdXRob3JlZCBncmFudWxhcml0eS4gJ3llYXInIHJlYWRzIGFzXG4vLyBcIkFubnVhbGx5XCIgaW4gdGhlIGNvbnRyb2wuXG5leHBvcnQgY29uc3QgRlJFUVVFTkNZX09QVElPTlM6IHsgdmFsdWU6IENoYXJ0R3JhbnVsYXJpdHk7IG5hbWU6IHN0cmluZyB9W10gPSBbXG4gIHsgdmFsdWU6ICdkYXknLCBuYW1lOiAnRGF5JyB9LFxuICB7IHZhbHVlOiAnd2VlaycsIG5hbWU6ICdXZWVrJyB9LFxuICB7IHZhbHVlOiAnbW9udGgnLCBuYW1lOiAnTW9udGgnIH0sXG4gIHsgdmFsdWU6ICdxdWFydGVyJywgbmFtZTogJ1F1YXJ0ZXInIH0sXG4gIHsgdmFsdWU6ICd5ZWFyJywgbmFtZTogJ0FubnVhbGx5JyB9LFxuXTtcblxuZXhwb3J0IGludGVyZmFjZSBDaGFydENvbmZpZyB7XG4gIGNoYXJ0VHlwZT86ICdiYXInIHwgJ2xpbmUnIHwgJ2FyZWEnIHwgJ3BpZScgfCAnZG9udXQnO1xuICAvLyBGb3Iga2luZCAndGltZScsIHRoZSBzZXJ2ZXIgYnVja2V0cyB0aGUgcmF3IGRhdGV0aW1lIGNvbHVtbiB0byBgZ3JhbnVsYXJpdHlgXG4gIC8vIGluIHRoZSByZXBvcnQncyB0aW1lem9uZSAodGhlIFNRTCBleHBvc2VzIHRoZSByYXcgY29sdW1uLCB1bmJ1Y2tldGVkKS5cbiAgeEF4aXM/OiB7IGNvbHVtbjogc3RyaW5nOyBraW5kPzogJ2NhdGVnb3J5JyB8ICd0aW1lJzsgZ3JhbnVsYXJpdHk/OiBDaGFydEdyYW51bGFyaXR5OyBsYWJlbD86IHN0cmluZyB9O1xuICBtZWFzdXJlcz86IENoYXJ0TWVhc3VyZVtdO1xuICBzcGxpdEJ5PzogeyBjb2x1bW46IHN0cmluZzsgbGFiZWw/OiBzdHJpbmcgfTtcbiAgLy8gU2luZ2xlLWRpbWVuc2lvbiBiYXIgY2hhcnRzIG9ubHk6IGNvbG9yIGVhY2ggYmFyIGJ5IGl0cyBvd24gY2F0ZWdvcnkgYW5kXG4gIC8vIHNob3cgYSBsZWdlbmQsIFdJVEhPVVQgc3BsaXR0aW5nIGludG8gbXVsdGlwbGUgc2VyaWVzICh3aGljaCBzbGl2ZXJzIHRoZVxuICAvLyBiYXJzKS4gdjEgZXhwZWN0cyBjb2xvckJ5LmNvbHVtbiA9PT0geEF4aXMuY29sdW1uLiBJZ25vcmVkIHdoZW4gc3BsaXRCeSBpc1xuICAvLyBzZXQgb3IgdGhlIGNoYXJ0IGlzbid0IGEgYmFyIGNoYXJ0LlxuICBjb2xvckJ5PzogeyBjb2x1bW46IHN0cmluZzsgbGFiZWw/OiBzdHJpbmcgfTtcbiAgb3JpZW50YXRpb24/OiAndmVydGljYWwnIHwgJ2hvcml6b250YWwnO1xuICBzdGFja2VkPzogYm9vbGVhbjtcbiAgbGVnZW5kPzogTGVnZW5kUG9zaXRpb247XG4gIHNvcnQ/OiBSZXBvcnRTb3J0O1xuICBsaW1pdD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDaGFydE1lYXN1cmUge1xuICBjb2x1bW46IHN0cmluZztcbiAgYWdncmVnYXRpb24/OiAnc3VtJyB8ICdjb3VudCcgfCAnYXZnJyB8ICdtaW4nIHwgJ21heCc7XG4gIGxhYmVsPzogc3RyaW5nO1xuICBmb3JtYXQ/OiAnbnVtYmVyJyB8ICdwZXJjZW50JyB8ICdjdXJyZW5jeSc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTGlzdENvbmZpZyB7XG4gIGNvbHVtbnM/OiB7IGNvbHVtbjogc3RyaW5nOyBsYWJlbD86IHN0cmluZzsgZm9ybWF0PzogJ2RhdGUnIHwgJ251bWJlcicgfVtdO1xuICBzb3J0PzogUmVwb3J0U29ydDtcbiAgcGFnZVNpemU/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgS3BpQ29uZmlnIHtcbiAgbWVhc3VyZT86IENoYXJ0TWVhc3VyZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXBvcnRTb3J0IHtcbiAgY29sdW1uOiBzdHJpbmc7XG4gIGRpcmVjdGlvbj86ICdhc2MnIHwgJ2Rlc2MnO1xufVxuXG5leHBvcnQgdHlwZSBSZXBvcnRGaWx0ZXJUeXBlID0gJ2RhdGVSYW5nZScgfCAnc2VsZWN0JyB8ICdrZXl3b3JkJztcblxuLy8gV2hlcmUgYSBmaWx0ZXIgZ3JvdXAncyBjb250cm9sIGlzIGV4cG9zZWQuIEEgZ3JvdXAgY2FuIGJlIHNob3duIG9uIGl0c1xuLy8gY29tcG9uZW50cywgaW4gdGhlIHJlcG9ydCBiYXIsIG9yIEJPVEggYXQgb25jZSAodGhlIHR3byBhcmUgaW5kZXBlbmRlbnRcbi8vIHRvZ2dsZXMgaW4gdGhlIFVJKTsgYSBjb2x1bW4gd2l0aCBuZWl0aGVyIGV4cG9zZWQgc2ltcGx5IGhhcyBubyBmaWx0ZXIuXG5leHBvcnQgdHlwZSBSZXBvcnRGaWx0ZXJMZXZlbCA9ICdjb21wb25lbnQnIHwgJ3JlcG9ydCcgfCAnYm90aCc7XG5cbi8vIE9uZSBmaWx0ZXJhYmxlIG91dHB1dCBjb2x1bW4gb2YgYSBjb21wb25lbnQncyBTUUwsIHdpdGggdGhlIGZpbHRlciBpbnRlcmZhY2Vcbi8vIElORkVSUkVEIGZyb20gaXRzIGRhdGEgKHRoZSBodW1hbiBuZXZlciBwaWNrcyB0aGUgaW50ZXJmYWNlIOKAlCBpdCBmb2xsb3dzIHRoZVxuLy8gY29sdW1uJ3MgdHlwZSkuIERyaXZlcyB0aGUgRmlsdGVycyB0YWIgbGlzdGluZy5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwb3J0RmlsdGVyYWJsZUNvbHVtbiB7XG4gIGNvbHVtbjogc3RyaW5nO1xuICB0eXBlOiBSZXBvcnRGaWx0ZXJUeXBlO1xufVxuXG4vLyBHcm91bmQgdHJ1dGg6IG9uZSBmaWx0ZXJhYmxlIG91dHB1dCBjb2x1bW4gT04gb25lIGNvbXBvbmVudCdzIFNRTC4gQWx3YXlzIGFcbi8vIG1lbWJlciBvZiBhIGZpbHRlciBncm91cCDigJQgdGhlIHVuaXQgdGhhdCBsaW5rcyBlcXVpdmFsZW50IGZpbHRlcnMgYWNyb3NzXG4vLyBjb21wb25lbnRzIGFuZCBkZWNpZGVzIHdoZXJlIHRoZSBjb250cm9sIHJlbmRlcnMgKGNvbXBvbmVudCB2cyByZXBvcnQgYmFyKS5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwb3J0RmlsdGVyIHtcbiAgaWQ6IG51bWJlcjtcbiAgY29tcG9uZW50SWQ6IG51bWJlcjtcbiAgZmlsdGVyR3JvdXBJZDogbnVtYmVyO1xuICBmaWx0ZXJDb2x1bW46IHN0cmluZztcbiAgbGFiZWw6IHN0cmluZyB8IG51bGw7XG4gIGVuYWJsZWQ6IGJvb2xlYW47XG4gIGhhc09wdGlvbnM6IGJvb2xlYW47XG4gIGNvbmZpZzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwb3J0RmlsdGVyR3JvdXAge1xuICBpZDogbnVtYmVyO1xuICBsYWJlbDogc3RyaW5nIHwgbnVsbDtcbiAgdHlwZTogUmVwb3J0RmlsdGVyVHlwZTtcbiAgbGV2ZWw6IFJlcG9ydEZpbHRlckxldmVsO1xuICBvcmRlcjogbnVtYmVyO1xuICBjb25maWc6IHsgZGVmYXVsdD86IEZpbHRlckdyb3VwRGVmYXVsdCB9ICYgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIGZpbHRlcnM6IFJlcG9ydEZpbHRlcltdO1xufVxuXG4vLyBBIGZpbHRlciBncm91cCdzIGF1dGhvcmVkIGRlZmF1bHQg4oCUIHRoZSB2YWx1ZSB0aGF0IHNlZWRzIHRoZSByZXBvcnQgYmFyIG9uXG4vLyBldmVyeSBvcGVuLiBTaGFwZSBmb2xsb3dzIHRoZSBncm91cCdzIHR5cGU6IGRhdGVSYW5nZSB1c2VzIHN0YXJ0L2VuZCAoYSBmaXhlZFxuLy8gY2FsZW5kYXItZGF5IHJhbmdlKSBvciBhIHJlbGF0aXZlIHByZXNldDsgc2VsZWN0IHVzZXMgdmFsdWVzOyBrZXl3b3JkIHVzZXNcbi8vIHZhbHVlLlxuZXhwb3J0IGludGVyZmFjZSBGaWx0ZXJHcm91cERlZmF1bHQge1xuICByZWxhdGl2ZT86IHN0cmluZzsgLy8gZGF0ZVJhbmdlIHJlbGF0aXZlIHByZXNldCwgZS5nLiBsYXN0MTJNb250aHMsIHllYXJUb0RhdGVcbiAgc3RhcnQ/OiBzdHJpbmc7IC8vIGRhdGVSYW5nZSBmaXhlZCBzdGFydCAoeXl5eS1NTS1kZClcbiAgZW5kPzogc3RyaW5nOyAvLyBkYXRlUmFuZ2UgZml4ZWQgZW5kICh5eXl5LU1NLWRkKVxuICB2YWx1ZXM/OiB1bmtub3duW107IC8vIHNlbGVjdCBkZWZhdWx0IHBpY2tlZCB2YWx1ZXNcbiAgdmFsdWU/OiBzdHJpbmc7IC8vIGtleXdvcmQgZGVmYXVsdCB0ZXh0XG59XG5cbi8vIFRoZSBzZXNzaW9uIHZhbHVlIG9mIGEgZmlsdGVyIGdyb3VwIChuZXZlciBwZXJzaXN0ZWQpOiBzaGFwZSBkZXBlbmRzIG9uIHRoZVxuLy8gZ3JvdXAncyB0eXBlLlxuZXhwb3J0IGludGVyZmFjZSBGaWx0ZXJHcm91cFZhbHVlIHtcbiAgc3RhcnQ/OiBEYXRlIHwgc3RyaW5nIHwgbnVsbDsgLy8gZGF0ZVJhbmdlXG4gIGVuZD86IERhdGUgfCBzdHJpbmcgfCBudWxsOyAvLyBkYXRlUmFuZ2VcbiAgdmFsdWVzPzogdW5rbm93bltdOyAvLyBzZWxlY3RcbiAgdmFsdWU/OiBzdHJpbmc7IC8vIGtleXdvcmRcbn1cblxuLy8gT25lIHJlc29sdmVkIGZpbHRlciBzZW50IHdpdGggYSBjb21wb25lbnQncyBkYXRhIHJlcXVlc3QuXG5leHBvcnQgaW50ZXJmYWNlIFJlc29sdmVkRmlsdGVyVmFsdWUge1xuICBmaWx0ZXJJZDogbnVtYmVyO1xuICBzdGFydD86IHN0cmluZztcbiAgZW5kPzogc3RyaW5nO1xuICB2YWx1ZXM/OiB1bmtub3duW107XG4gIHZhbHVlPzogc3RyaW5nO1xufVxuXG4vLyBQZXItY29tcG9uZW50IGludGVyYWN0aW9uIHN0YXRlIHNlbnQgd2l0aCB0aGUgZGF0YSByZXF1ZXN0OiBsaXN0cyBzZW5kXG4vLyBzb3J0L3BhZ2luZzsgdGltZS1zZXJpZXMgY2hhcnRzIHNlbmQgdGhlIHZpZXdlcidzIGNob3NlbiBGcmVxdWVuY3ksIHdoaWNoXG4vLyBvdmVycmlkZXMgdGhlIGF1dGhvcmVkIGdyYW51bGFyaXR5IGZvciB0aGF0IHJlcXVlc3Qgb25seS5cbmV4cG9ydCBpbnRlcmZhY2UgQ29tcG9uZW50RGF0YVN0YXRlIHtcbiAgc29ydD86IFJlcG9ydFNvcnQ7XG4gIHBhZ2U/OiBudW1iZXI7XG4gIHBhZ2VTaXplPzogbnVtYmVyO1xuICBmcmVxdWVuY3k/OiBDaGFydEdyYW51bGFyaXR5O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbXBvbmVudERhdGEge1xuICBjb2x1bW5zOiBzdHJpbmdbXTtcbiAgcm93czogUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXTtcbiAgcGFnaW5nPzogeyB0b3RhbDogbnVtYmVyOyBwYWdlOiBudW1iZXI7IHBhZ2VTaXplOiBudW1iZXIgfTtcbiAgdHJ1bmNhdGVkOiBib29sZWFuO1xuICAvLyBUaGUgZWZmZWN0aXZlIHRpbWUgYnVja2V0IHRoZSByb3dzIHdlcmUgZ3JvdXBlZCBpbnRvIChhZnRlciBhbnkgRnJlcXVlbmN5XG4gIC8vIG92ZXJyaWRlKSwgb3IgbnVsbCBmb3IgYSBub24tdGltZSBheGlzLiBEcml2ZXMgdGhlIGNvbXBhY3QgeC1heGlzIGxhYmVscy5cbiAgZ3JhbnVsYXJpdHk/OiBDaGFydEdyYW51bGFyaXR5IHwgbnVsbDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXBvcnRMaXN0SXRlbSB7XG4gIGlkOiBudW1iZXI7XG4gIG5hbWU6IHN0cmluZztcbiAgbW9kaWZ5RGF0ZTogc3RyaW5nO1xufVxuXG4vLyBUaGUgY2hhdCB0dXJuIGZsYWdzIHRoaXMgY29udGV4dCdzIGJhY2tlbmQgYWRkcyAoUmVwb3J0c1xcQWlWaWV3KS5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwb3J0Q2hhdFJlc3BvbnNlIHtcbiAgcmVwb3J0Q2hhbmdlZD86IGJvb2xlYW47XG4gIHJlcG9ydFJlbmFtZWQ/OiBib29sZWFuO1xufVxuIl19
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
import { CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, ElementRef, NgZone, ViewChild, effect, inject, input, output, } from '@angular/core';
|
|
2
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
3
|
+
import { MatButtonModule } from '@angular/material/button';
|
|
4
|
+
import { MatDialog } from '@angular/material/dialog';
|
|
5
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
6
|
+
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
7
|
+
import { FsFilterModule, ItemType } from '@firestitch/filter';
|
|
8
|
+
import { FsMenuModule } from '@firestitch/menu';
|
|
9
|
+
import { FsProcess } from '@firestitch/process';
|
|
10
|
+
import { from } from 'rxjs';
|
|
11
|
+
import { switchMap } from 'rxjs/operators';
|
|
12
|
+
import { provideEchartsCore } from 'ngx-echarts';
|
|
13
|
+
import { FsAiChatComponent } from '@firestitch/ai';
|
|
14
|
+
import { ReportCanvasComponent } from '../../components/report-canvas/report-canvas.component';
|
|
15
|
+
import { ReportData } from '../../data/report.data';
|
|
16
|
+
import { ComponentSettingsComponent } from '../../dialogs/component-settings/component-settings.component';
|
|
17
|
+
import { ReportSettingsComponent } from '../../dialogs/report-settings/report-settings.component';
|
|
18
|
+
import { ReportExportCollectorService } from '../../export/report-export-collector.service';
|
|
19
|
+
import { ReportPdfService } from '../../export/report-pdf.service';
|
|
20
|
+
import { ReportPptxService } from '../../export/report-pptx.service';
|
|
21
|
+
import { FREQUENCY_OPTIONS, } from '../../interfaces/report.interface';
|
|
22
|
+
import { filterItemForGroup, groupValuesFromQuery } from '../../report-filter-items';
|
|
23
|
+
import { ReportFilterStateService } from '../../services/report-filter-state.service';
|
|
24
|
+
import * as i0 from "@angular/core";
|
|
25
|
+
import * as i1 from "@firestitch/filter";
|
|
26
|
+
import * as i2 from "@firestitch/menu";
|
|
27
|
+
import * as i3 from "@angular/material/button";
|
|
28
|
+
import * as i4 from "@angular/material/icon";
|
|
29
|
+
import * as i5 from "@angular/material/tooltip";
|
|
30
|
+
// fs-filter query key for the runtime Frequency control (a render-layer bucket
|
|
31
|
+
// override, not a filter group — so it's read straight off the query).
|
|
32
|
+
const FREQUENCY_ITEM = 'frequency';
|
|
33
|
+
// A single report: the AI chat on the left, the report canvas on the right,
|
|
34
|
+
// under an H2 title + settings gear. The host supplies [reportId] (from its
|
|
35
|
+
// route) and switches reports by navigating — this component never picks one.
|
|
36
|
+
export class FsAiReportComponent {
|
|
37
|
+
// The report this view is focused on — supplied by the host from the route.
|
|
38
|
+
reportId = input(null);
|
|
39
|
+
// API base for the reports + chat endpoints; override to mount elsewhere.
|
|
40
|
+
basePath = input('reports');
|
|
41
|
+
// The report was deleted from its settings dialog — the host routes back to
|
|
42
|
+
// the listing.
|
|
43
|
+
deleted = output();
|
|
44
|
+
// The report was renamed (settings, or the agent) — the host can refresh a
|
|
45
|
+
// breadcrumb / document title.
|
|
46
|
+
renamed = output();
|
|
47
|
+
report = null;
|
|
48
|
+
editMode = false;
|
|
49
|
+
// The report-level filter toolbar (fs-filter). Rebuilt whenever the loaded
|
|
50
|
+
// report (and thus its groups) changes.
|
|
51
|
+
reportFilterConfig;
|
|
52
|
+
_split;
|
|
53
|
+
_chatPanel;
|
|
54
|
+
_reportData = inject(ReportData);
|
|
55
|
+
_filterState = inject(ReportFilterStateService);
|
|
56
|
+
_exportCollector = inject(ReportExportCollectorService);
|
|
57
|
+
_pptxService = inject(ReportPptxService);
|
|
58
|
+
_pdfService = inject(ReportPdfService);
|
|
59
|
+
_process = inject(FsProcess);
|
|
60
|
+
_dialog = inject(MatDialog);
|
|
61
|
+
_destroyRef = inject(DestroyRef);
|
|
62
|
+
_cdRef = inject(ChangeDetectorRef);
|
|
63
|
+
_zone = inject(NgZone);
|
|
64
|
+
constructor() {
|
|
65
|
+
// Point the shared data gateway at the configured base first (before any
|
|
66
|
+
// load below reads it).
|
|
67
|
+
effect(() => {
|
|
68
|
+
this._reportData.basePath = this.basePath();
|
|
69
|
+
});
|
|
70
|
+
// (Re)load whenever the host switches the report id.
|
|
71
|
+
effect(() => {
|
|
72
|
+
const reportId = this.reportId();
|
|
73
|
+
this.editMode = false;
|
|
74
|
+
if (reportId != null) {
|
|
75
|
+
this._loadReport(reportId);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
this.report = null;
|
|
79
|
+
this._buildReportConfig();
|
|
80
|
+
this._cdRef.markForCheck();
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
this._buildReportConfig();
|
|
84
|
+
}
|
|
85
|
+
toggleEditMode() {
|
|
86
|
+
this.editMode = !this.editMode;
|
|
87
|
+
}
|
|
88
|
+
// Report settings — name, page size, orientation, layout mode, delete. The
|
|
89
|
+
// dialog performs the delete itself; we react to what it reports back.
|
|
90
|
+
reportSettings() {
|
|
91
|
+
if (!this.report) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const reportId = this.report.id;
|
|
95
|
+
this._dialog.open(ReportSettingsComponent, {
|
|
96
|
+
data: { report: this.report },
|
|
97
|
+
width: '460px',
|
|
98
|
+
})
|
|
99
|
+
.afterClosed()
|
|
100
|
+
.pipe(takeUntilDestroyed(this._destroyRef))
|
|
101
|
+
.subscribe((result) => {
|
|
102
|
+
if (result?.action === 'deleted') {
|
|
103
|
+
this.deleted.emit(reportId);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (result?.action === 'saved') {
|
|
107
|
+
this._loadReport(reportId, true);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
// Component settings — title, exact geometry, and the diagnostic views
|
|
112
|
+
// (SQL, config, filter wiring).
|
|
113
|
+
componentSettings(component) {
|
|
114
|
+
if (!this.report) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const reportId = this.report.id;
|
|
118
|
+
this._dialog.open(ComponentSettingsComponent, {
|
|
119
|
+
data: { report: this.report, component },
|
|
120
|
+
width: '640px',
|
|
121
|
+
})
|
|
122
|
+
.afterClosed()
|
|
123
|
+
.pipe(takeUntilDestroyed(this._destroyRef))
|
|
124
|
+
.subscribe(() => {
|
|
125
|
+
// Always reload: filter add/remove/level changes persist immediately
|
|
126
|
+
// inside the dialog (no "save"), so the canvas + report bar must
|
|
127
|
+
// refresh however the dialog was closed.
|
|
128
|
+
this._loadReport(reportId);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
// The canvas changed the report's structure (added a page) — re-fetch so the
|
|
132
|
+
// new page renders; the canvas lands the view on it.
|
|
133
|
+
onCanvasReportChanged() {
|
|
134
|
+
if (this.report) {
|
|
135
|
+
this._loadReport(this.report.id);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// Export the report to PowerPoint, entirely client-side (native editable
|
|
139
|
+
// charts; page = slide). The dock shows progress until the file saves.
|
|
140
|
+
exportPowerpoint() {
|
|
141
|
+
if (!this.report) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const report = this.report;
|
|
145
|
+
this._process.run('Exporting PowerPoint', this._exportCollector.collect(report)
|
|
146
|
+
.pipe(switchMap((collected) => from(this._pptxService.export(collected)))));
|
|
147
|
+
}
|
|
148
|
+
// Export to PDF, entirely client-side (offscreen ECharts at 3×; page = PDF page).
|
|
149
|
+
exportPdf() {
|
|
150
|
+
if (!this.report) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
const report = this.report;
|
|
154
|
+
this._process.run('Exporting PDF', this._exportCollector.collect(report)
|
|
155
|
+
.pipe(switchMap((collected) => from(this._pdfService.export(collected)))));
|
|
156
|
+
}
|
|
157
|
+
// React to each chat turn (fs-chat handles the request + persistence); we
|
|
158
|
+
// only care about the report side effects this context's backend flags.
|
|
159
|
+
onChatResponse(response) {
|
|
160
|
+
const reportId = this.reportId();
|
|
161
|
+
if (reportId == null) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
const reportResponse = response;
|
|
165
|
+
// A structural change or a rename both re-fetch the report (session filter
|
|
166
|
+
// values survive); a rename additionally notifies the host so it can
|
|
167
|
+
// refresh a breadcrumb / title.
|
|
168
|
+
if (reportResponse.reportChanged || reportResponse.reportRenamed) {
|
|
169
|
+
this._loadReport(reportId, !!reportResponse.reportRenamed);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// Drag the divider between the chat and canvas panes (pointer-capture loop
|
|
173
|
+
// outside Angular).
|
|
174
|
+
onResizeStart(event) {
|
|
175
|
+
event.preventDefault();
|
|
176
|
+
const handle = event.target;
|
|
177
|
+
handle.setPointerCapture(event.pointerId);
|
|
178
|
+
this._split.nativeElement.classList.add('resizing');
|
|
179
|
+
this._zone.runOutsideAngular(() => {
|
|
180
|
+
const move = (e) => this._resizeTo(e.clientX);
|
|
181
|
+
const end = () => {
|
|
182
|
+
handle.releasePointerCapture(event.pointerId);
|
|
183
|
+
handle.removeEventListener('pointermove', move);
|
|
184
|
+
handle.removeEventListener('pointerup', end);
|
|
185
|
+
handle.removeEventListener('pointercancel', end);
|
|
186
|
+
this._split.nativeElement.classList.remove('resizing');
|
|
187
|
+
};
|
|
188
|
+
handle.addEventListener('pointermove', move);
|
|
189
|
+
handle.addEventListener('pointerup', end);
|
|
190
|
+
handle.addEventListener('pointercancel', end);
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
_resizeTo(clientX) {
|
|
194
|
+
const rect = this._split.nativeElement.getBoundingClientRect();
|
|
195
|
+
if (rect.width === 0) {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
const ratio = (clientX - rect.left) / rect.width;
|
|
199
|
+
const clamped = Math.min(0.8, Math.max(0.2, ratio));
|
|
200
|
+
this._chatPanel.nativeElement.style.flexBasis = `${clamped * 100}%`;
|
|
201
|
+
}
|
|
202
|
+
_loadReport(reportId, emitRenamed = false) {
|
|
203
|
+
this._reportData.get(reportId)
|
|
204
|
+
.pipe(takeUntilDestroyed(this._destroyRef))
|
|
205
|
+
.subscribe((report) => {
|
|
206
|
+
this.report = report;
|
|
207
|
+
this._filterState.init(report);
|
|
208
|
+
this._buildReportConfig();
|
|
209
|
+
if (emitRenamed) {
|
|
210
|
+
this.renamed.emit(report);
|
|
211
|
+
}
|
|
212
|
+
this._cdRef.markForCheck();
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
// Report-level filter groups in their saved order — the ones that render in
|
|
216
|
+
// the toolbar (component-level groups render on their components).
|
|
217
|
+
_reportGroups() {
|
|
218
|
+
return (this.report?.filterGroups ?? [])
|
|
219
|
+
.filter((group) => group.level === 'report' || group.level === 'both')
|
|
220
|
+
.sort((a, b) => a.order - b.order);
|
|
221
|
+
}
|
|
222
|
+
// Whether the loaded report has any report-level filters OR a time-series
|
|
223
|
+
// chart (which earns the runtime Frequency control) — gates the toolbar.
|
|
224
|
+
get reportHasFilters() {
|
|
225
|
+
return this._reportGroups().length > 0 || this._hasTimeSeriesChart();
|
|
226
|
+
}
|
|
227
|
+
// fs-filter reads its config only once (at init). The template keys the
|
|
228
|
+
// toolbar fs-filter on this signature so it's recreated (and re-reads the
|
|
229
|
+
// rebuilt config) whenever the report-level filter set changes.
|
|
230
|
+
get reportFilterKey() {
|
|
231
|
+
return [
|
|
232
|
+
...this._reportGroups().map((group) => `${group.id}:${group.level}:${group.label}`),
|
|
233
|
+
this._hasTimeSeriesChart() ? 'frequency' : '',
|
|
234
|
+
].join('|');
|
|
235
|
+
}
|
|
236
|
+
// (Re)build the toolbar fs-filter config — report-level filter items, plus
|
|
237
|
+
// the runtime Frequency control when the report has a time-series chart.
|
|
238
|
+
_buildReportConfig() {
|
|
239
|
+
const reportId = this.report?.id ?? null;
|
|
240
|
+
const items = reportId
|
|
241
|
+
? this._reportGroups().map((group) => filterItemForGroup(group, this._reportData, reportId, this._filterState.value(group.id)))
|
|
242
|
+
: [];
|
|
243
|
+
if (reportId && this._hasTimeSeriesChart()) {
|
|
244
|
+
items.push({
|
|
245
|
+
name: FREQUENCY_ITEM,
|
|
246
|
+
type: ItemType.Select,
|
|
247
|
+
label: 'Frequency',
|
|
248
|
+
multiple: false,
|
|
249
|
+
values: () => FREQUENCY_OPTIONS,
|
|
250
|
+
default: this._filterState.frequency() ?? undefined,
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
this.reportFilterConfig = {
|
|
254
|
+
// Never touch the URL or persist filter state — report filters are
|
|
255
|
+
// session-only, owned by ReportFilterStateService.
|
|
256
|
+
queryParam: false,
|
|
257
|
+
persist: false,
|
|
258
|
+
items,
|
|
259
|
+
change: (query) => {
|
|
260
|
+
for (const { groupId, value } of groupValuesFromQuery(query ?? {}, this._reportGroups())) {
|
|
261
|
+
this._filterState.setValue(groupId, value);
|
|
262
|
+
}
|
|
263
|
+
// Frequency isn't a filter group — it's a render-layer bucket override.
|
|
264
|
+
this._filterState.setFrequency(query?.[FREQUENCY_ITEM] || null);
|
|
265
|
+
},
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
// The report has at least one time-series chart (x-axis is a time axis) — the
|
|
269
|
+
// only kind the Frequency control affects.
|
|
270
|
+
_hasTimeSeriesChart() {
|
|
271
|
+
return (this.report?.pages ?? []).some((page) => page.components.some((component) => component.type === 'chart' && component.config?.xAxis?.kind === 'time'));
|
|
272
|
+
}
|
|
273
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FsAiReportComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
274
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: FsAiReportComponent, isStandalone: true, selector: "fs-ai-report", inputs: { reportId: { classPropertyName: "reportId", publicName: "reportId", isSignal: true, isRequired: false, transformFunction: null }, basePath: { classPropertyName: "basePath", publicName: "basePath", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { deleted: "deleted", renamed: "renamed" }, providers: [
|
|
275
|
+
// Session filter state is per-open-report, not app-global; the export
|
|
276
|
+
// services resolve filters through it, so they live at the same level.
|
|
277
|
+
ReportFilterStateService,
|
|
278
|
+
ReportExportCollectorService,
|
|
279
|
+
ReportPptxService,
|
|
280
|
+
ReportPdfService,
|
|
281
|
+
// Tree-shaken ECharts core + the 'report' house theme, loaded lazily.
|
|
282
|
+
provideEchartsCore({ echarts: () => import('../../theme/echarts').then((module) => module.default) }),
|
|
283
|
+
], viewQueries: [{ propertyName: "_split", first: true, predicate: ["split"], descendants: true, static: true }, { propertyName: "_chatPanel", first: true, predicate: ["chatPanel"], descendants: true, read: ElementRef, static: true }], ngImport: i0, template: "<div class=\"fs-ai-report fs-column\">\n\n <div class=\"fs-ai-report__header fs-row.align-center\">\n <h2 class=\"fs-ai-report__title fs-flex\">{{ report?.name }}</h2>\n\n @if (report) {\n <button\n mat-icon-button\n type=\"button\"\n [matTooltip]=\"editMode ? 'Done' : 'Edit layout'\"\n (click)=\"toggleEditMode()\">\n <mat-icon>{{ editMode ? 'lock' : 'open_with' }}</mat-icon>\n </button>\n\n <button\n mat-icon-button\n type=\"button\"\n matTooltip=\"Export\"\n [fsMenuTriggerFor]=\"exportMenu\">\n <mat-icon>download</mat-icon>\n </button>\n <fs-menu #exportMenu>\n <ng-template\n fs-menu-item\n (click)=\"exportPowerpoint()\">\n Export PowerPoint\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"exportPdf()\">\n Export PDF\n </ng-template>\n </fs-menu>\n\n <button\n mat-icon-button\n type=\"button\"\n matTooltip=\"Report settings\"\n (click)=\"reportSettings()\">\n <mat-icon>settings</mat-icon>\n </button>\n }\n </div>\n\n <div\n #split\n class=\"fs-ai-report__split fs-row.align-start\">\n <fs-ai-chat\n #chatPanel\n class=\"chat\"\n [basePath]=\"basePath()\"\n [requestData]=\"{ reportId: reportId() }\"\n (response)=\"onChatResponse($event)\">\n </fs-ai-chat>\n\n <div\n class=\"resizer\"\n (pointerdown)=\"onResizeStart($event)\">\n </div>\n\n <div class=\"viewer fs-flex fs-column\">\n @if (report) {\n <!-- Report-level filters only (the report's actions live in the header\n above). fs-filter reads its config once at init, so it's keyed on\n the filter signature: when the report-level filter set changes the\n block is recreated and re-reads the rebuilt config. -->\n @if (reportHasFilters) {\n @for (key of [reportFilterKey]; track key) {\n <fs-filter [config]=\"reportFilterConfig\"></fs-filter>\n }\n }\n <app-report-canvas\n [report]=\"report\"\n [editMode]=\"editMode\"\n (componentSettings)=\"componentSettings($event)\"\n (reportChanged)=\"onCanvasReportChanged()\"\n (editDone)=\"toggleEditMode()\">\n </app-report-canvas>\n }\n </div>\n </div>\n</div>\n", styles: [".fs-ai-report{height:100%;min-height:500px;display:flex;flex-direction:column}.fs-ai-report__header{flex:0 0 auto;margin-bottom:10px}.fs-ai-report__title{margin:0;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fs-ai-report__split{flex:1 1 auto;min-height:0}.fs-ai-report .chat{display:block;flex:0 0 25%;width:100%;height:100%;min-height:400px;min-width:0;border:none}.fs-ai-report .viewer{display:flex;flex-direction:column;min-width:0;height:100%;overflow:hidden}.fs-ai-report .viewer fs-filter{flex:0 0 auto;margin-top:10px;margin-bottom:0}.fs-ai-report .viewer ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}.fs-ai-report .resizer{flex:0 0 11px;align-self:stretch;display:flex;justify-content:center;cursor:col-resize;touch-action:none;-webkit-user-select:none;user-select:none}.fs-ai-report .resizer:before{content:\"\";width:1px;background:#0000001f;transition:width .12s ease,background-color .12s ease}.fs-ai-report .resizer:hover:before{width:3px;background:var(--brand-primary-color)}.fs-ai-report__split.resizing{cursor:col-resize;-webkit-user-select:none;user-select:none}.fs-ai-report__split.resizing .resizer:before{width:3px;background:var(--brand-primary-color)}.fs-ai-report__split.resizing .chat,.fs-ai-report__split.resizing .viewer{pointer-events:none}\n"], dependencies: [{ kind: "ngmodule", type: FsFilterModule }, { kind: "component", type: i1.FilterComponent, selector: "fs-filter", inputs: ["config"], outputs: ["closed", "opened", "ready"] }, { kind: "ngmodule", type: FsMenuModule }, { kind: "component", type: i2.FsMenuComponent, selector: "fs-menu", inputs: ["class", "buttonClass", "buttonType", "buttonColor"], outputs: ["opened", "closed"] }, { kind: "directive", type: i2.FsMenuItemDirective, selector: "fs-menu-group,[fs-menu-item]" }, { kind: "directive", type: i2.FsMenuTriggerDirective, selector: "[fsMenuTriggerFor]", inputs: ["fsMenuTriggerFor"] }, { kind: "component", type: FsAiChatComponent, selector: "fs-ai-chat", inputs: ["basePath", "requestData", "introMessage"], outputs: ["response"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: ReportCanvasComponent, selector: "app-report-canvas", inputs: ["report", "editMode"], outputs: ["componentSettings", "reportChanged", "editDone"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
284
|
+
}
|
|
285
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FsAiReportComponent, decorators: [{
|
|
286
|
+
type: Component,
|
|
287
|
+
args: [{ selector: 'fs-ai-report', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, schemas: [CUSTOM_ELEMENTS_SCHEMA], providers: [
|
|
288
|
+
// Session filter state is per-open-report, not app-global; the export
|
|
289
|
+
// services resolve filters through it, so they live at the same level.
|
|
290
|
+
ReportFilterStateService,
|
|
291
|
+
ReportExportCollectorService,
|
|
292
|
+
ReportPptxService,
|
|
293
|
+
ReportPdfService,
|
|
294
|
+
// Tree-shaken ECharts core + the 'report' house theme, loaded lazily.
|
|
295
|
+
provideEchartsCore({ echarts: () => import('../../theme/echarts').then((module) => module.default) }),
|
|
296
|
+
], imports: [
|
|
297
|
+
FsFilterModule,
|
|
298
|
+
FsMenuModule,
|
|
299
|
+
FsAiChatComponent,
|
|
300
|
+
MatButtonModule,
|
|
301
|
+
MatIconModule,
|
|
302
|
+
MatTooltipModule,
|
|
303
|
+
ReportCanvasComponent,
|
|
304
|
+
], template: "<div class=\"fs-ai-report fs-column\">\n\n <div class=\"fs-ai-report__header fs-row.align-center\">\n <h2 class=\"fs-ai-report__title fs-flex\">{{ report?.name }}</h2>\n\n @if (report) {\n <button\n mat-icon-button\n type=\"button\"\n [matTooltip]=\"editMode ? 'Done' : 'Edit layout'\"\n (click)=\"toggleEditMode()\">\n <mat-icon>{{ editMode ? 'lock' : 'open_with' }}</mat-icon>\n </button>\n\n <button\n mat-icon-button\n type=\"button\"\n matTooltip=\"Export\"\n [fsMenuTriggerFor]=\"exportMenu\">\n <mat-icon>download</mat-icon>\n </button>\n <fs-menu #exportMenu>\n <ng-template\n fs-menu-item\n (click)=\"exportPowerpoint()\">\n Export PowerPoint\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"exportPdf()\">\n Export PDF\n </ng-template>\n </fs-menu>\n\n <button\n mat-icon-button\n type=\"button\"\n matTooltip=\"Report settings\"\n (click)=\"reportSettings()\">\n <mat-icon>settings</mat-icon>\n </button>\n }\n </div>\n\n <div\n #split\n class=\"fs-ai-report__split fs-row.align-start\">\n <fs-ai-chat\n #chatPanel\n class=\"chat\"\n [basePath]=\"basePath()\"\n [requestData]=\"{ reportId: reportId() }\"\n (response)=\"onChatResponse($event)\">\n </fs-ai-chat>\n\n <div\n class=\"resizer\"\n (pointerdown)=\"onResizeStart($event)\">\n </div>\n\n <div class=\"viewer fs-flex fs-column\">\n @if (report) {\n <!-- Report-level filters only (the report's actions live in the header\n above). fs-filter reads its config once at init, so it's keyed on\n the filter signature: when the report-level filter set changes the\n block is recreated and re-reads the rebuilt config. -->\n @if (reportHasFilters) {\n @for (key of [reportFilterKey]; track key) {\n <fs-filter [config]=\"reportFilterConfig\"></fs-filter>\n }\n }\n <app-report-canvas\n [report]=\"report\"\n [editMode]=\"editMode\"\n (componentSettings)=\"componentSettings($event)\"\n (reportChanged)=\"onCanvasReportChanged()\"\n (editDone)=\"toggleEditMode()\">\n </app-report-canvas>\n }\n </div>\n </div>\n</div>\n", styles: [".fs-ai-report{height:100%;min-height:500px;display:flex;flex-direction:column}.fs-ai-report__header{flex:0 0 auto;margin-bottom:10px}.fs-ai-report__title{margin:0;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fs-ai-report__split{flex:1 1 auto;min-height:0}.fs-ai-report .chat{display:block;flex:0 0 25%;width:100%;height:100%;min-height:400px;min-width:0;border:none}.fs-ai-report .viewer{display:flex;flex-direction:column;min-width:0;height:100%;overflow:hidden}.fs-ai-report .viewer fs-filter{flex:0 0 auto;margin-top:10px;margin-bottom:0}.fs-ai-report .viewer ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}.fs-ai-report .resizer{flex:0 0 11px;align-self:stretch;display:flex;justify-content:center;cursor:col-resize;touch-action:none;-webkit-user-select:none;user-select:none}.fs-ai-report .resizer:before{content:\"\";width:1px;background:#0000001f;transition:width .12s ease,background-color .12s ease}.fs-ai-report .resizer:hover:before{width:3px;background:var(--brand-primary-color)}.fs-ai-report__split.resizing{cursor:col-resize;-webkit-user-select:none;user-select:none}.fs-ai-report__split.resizing .resizer:before{width:3px;background:var(--brand-primary-color)}.fs-ai-report__split.resizing .chat,.fs-ai-report__split.resizing .viewer{pointer-events:none}\n"] }]
|
|
305
|
+
}], ctorParameters: () => [], propDecorators: { _split: [{
|
|
306
|
+
type: ViewChild,
|
|
307
|
+
args: ['split', { static: true }]
|
|
308
|
+
}], _chatPanel: [{
|
|
309
|
+
type: ViewChild,
|
|
310
|
+
args: ['chatPanel', { static: true, read: ElementRef }]
|
|
311
|
+
}] } });
|
|
312
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnMtYWktcmVwb3J0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy92aWV3cy9yZXBvcnQvZnMtYWktcmVwb3J0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy92aWV3cy9yZXBvcnQvZnMtYWktcmVwb3J0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxzQkFBc0IsRUFBRSx1QkFBdUIsRUFBRSxpQkFBaUIsRUFBRSxTQUFTLEVBQzdFLFVBQVUsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEdBQ3pFLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRWhFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDckQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRTdELE9BQU8sRUFBZ0IsY0FBYyxFQUFFLFFBQVEsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzVFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFaEQsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUM1QixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFM0MsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRWpE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LENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO3FCQUN0RyxXQUNRO3dCQUNQLGNBQWM7d0JBQ2QsWUFBWTt3QkFDWixpQkFBaUI7d0JBQ2pCLGVBQWU7d0JBQ2YsYUFBYTt3QkFDYixnQkFBZ0I7d0JBQ2hCLHFCQUFxQjtxQkFDdEI7d0RBMEJPLE1BQU07c0JBRGIsU0FBUzt1QkFBQyxPQUFPLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQUk1QixVQUFVO3NCQURqQixTQUFTO3VCQUFDLFdBQVcsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENVU1RPTV9FTEVNRU5UU19TQ0hFTUEsIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDaGFuZ2VEZXRlY3RvclJlZiwgQ29tcG9uZW50LFxuICBEZXN0cm95UmVmLCBFbGVtZW50UmVmLCBOZ1pvbmUsIFZpZXdDaGlsZCwgZWZmZWN0LCBpbmplY3QsIGlucHV0LCBvdXRwdXQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuXG5pbXBvcnQgeyBNYXRCdXR0b25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9idXR0b24nO1xuaW1wb3J0IHsgTWF0RGlhbG9nIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nJztcbmltcG9ydCB7IE1hdEljb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pY29uJztcbmltcG9ydCB7IE1hdFRvb2x0aXBNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC90b29sdGlwJztcblxuaW1wb3J0IHsgRmlsdGVyQ29uZmlnLCBGc0ZpbHRlck1vZHVsZSwgSXRlbVR5cGUgfSBmcm9tICdAZmlyZXN0aXRjaC9maWx0ZXInO1xuaW1wb3J0IHsgRnNNZW51TW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvbWVudSc7XG5pbXBvcnQgeyBGc1Byb2Nlc3MgfSBmcm9tICdAZmlyZXN0aXRjaC9wcm9jZXNzJztcblxuaW1wb3J0IHsgZnJvbSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgc3dpdGNoTWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBwcm92aWRlRWNoYXJ0c0NvcmUgfSBmcm9tICduZ3gtZWNoYXJ0cyc7XG5cbmltcG9ydCB7IEZzQWlDaGF0Q29tcG9uZW50LCBGc0FpQ2hhdFJlc3BvbnNlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvYWknO1xuXG5pbXBvcnQgeyBSZXBvcnRDYW52YXNDb21wb25lbnQgfSBmcm9tICcuLi8uLi9jb21wb25lbnRzL3JlcG9ydC1jYW52YXMvcmVwb3J0LWNhbnZhcy5jb21wb25lbnQnO1xuaW1wb3J0IHsgUmVwb3J0RGF0YSB9IGZyb20gJy4uLy4uL2RhdGEvcmVwb3J0LmRhdGEnO1xuaW1wb3J0IHsgQ29tcG9uZW50U2V0dGluZ3NDb21wb25lbnQgfSBmcm9tICcuLi8uLi9kaWFsb2dzL2NvbXBvbmVudC1zZXR0aW5ncy9jb21wb25lbnQtc2V0dGluZ3MuY29tcG9uZW50JztcbmltcG9ydCB7IFJlcG9ydFNldHRpbmdzQ29tcG9uZW50LCBSZXBvcnRTZXR0aW5nc1Jlc3VsdCB9IGZyb20gJy4uLy4uL2RpYWxvZ3MvcmVwb3J0LXNldHRpbmdzL3JlcG9ydC1zZXR0aW5ncy5jb21wb25lbnQnO1xuaW1wb3J0IHsgUmVwb3J0RXhwb3J0Q29sbGVjdG9yU2VydmljZSB9IGZyb20gJy4uLy4uL2V4cG9ydC9yZXBvcnQtZXhwb3J0LWNvbGxlY3Rvci5zZXJ2aWNlJztcbmltcG9ydCB7IFJlcG9ydFBkZlNlcnZpY2UgfSBmcm9tICcuLi8uLi9leHBvcnQvcmVwb3J0LXBkZi5zZXJ2aWNlJztcbmltcG9ydCB7IFJlcG9ydFBwdHhTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vZXhwb3J0L3JlcG9ydC1wcHR4LnNlcnZpY2UnO1xuaW1wb3J0IHtcbiAgQ2hhcnRHcmFudWxhcml0eSwgRlJFUVVFTkNZX09QVElPTlMsIFJlcG9ydCwgUmVwb3J0Q2hhdFJlc3BvbnNlLFxuICBSZXBvcnRDb21wb25lbnQgYXMgUmVwb3J0Q29tcG9uZW50TW9kZWwsIFJlcG9ydEZpbHRlckdyb3VwLFxufSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL3JlcG9ydC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgZmlsdGVySXRlbUZvckdyb3VwLCBncm91cFZhbHVlc0Zyb21RdWVyeSB9IGZyb20gJy4uLy4uL3JlcG9ydC1maWx0ZXItaXRlbXMnO1xuaW1wb3J0IHsgUmVwb3J0RmlsdGVyU3RhdGVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvcmVwb3J0LWZpbHRlci1zdGF0ZS5zZXJ2aWNlJztcblxuXG4vLyBmcy1maWx0ZXIgcXVlcnkga2V5IGZvciB0aGUgcnVudGltZSBGcmVxdWVuY3kgY29udHJvbCAoYSByZW5kZXItbGF5ZXIgYnVja2V0XG4vLyBvdmVycmlkZSwgbm90IGEgZmlsdGVyIGdyb3VwIOKAlCBzbyBpdCdzIHJlYWQgc3RyYWlnaHQgb2ZmIHRoZSBxdWVyeSkuXG5jb25zdCBGUkVRVUVOQ1lfSVRFTSA9ICdmcmVxdWVuY3knO1xuXG4vLyBBIHNpbmdsZSByZXBvcnQ6IHRoZSBBSSBjaGF0IG9uIHRoZSBsZWZ0LCB0aGUgcmVwb3J0IGNhbnZhcyBvbiB0aGUgcmlnaHQsXG4vLyB1bmRlciBhbiBIMiB0aXRsZSArIHNldHRpbmdzIGdlYXIuIFRoZSBob3N0IHN1cHBsaWVzIFtyZXBvcnRJZF0gKGZyb20gaXRzXG4vLyByb3V0ZSkgYW5kIHN3aXRjaGVzIHJlcG9ydHMgYnkgbmF2aWdhdGluZyDigJQgdGhpcyBjb21wb25lbnQgbmV2ZXIgcGlja3Mgb25lLlxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnZnMtYWktcmVwb3J0JyxcbiAgdGVtcGxhdGVVcmw6ICcuL2ZzLWFpLXJlcG9ydC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2ZzLWFpLXJlcG9ydC5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgc2NoZW1hczogW0NVU1RPTV9FTEVNRU5UU19TQ0hFTUFdLFxuICBwcm92aWRlcnM6IFtcbiAgICAvLyBTZXNzaW9uIGZpbHRlciBzdGF0ZSBpcyBwZXItb3Blbi1yZXBvcnQsIG5vdCBhcHAtZ2xvYmFsOyB0aGUgZXhwb3J0XG4gICAgLy8gc2VydmljZXMgcmVzb2x2ZSBmaWx0ZXJzIHRocm91Z2ggaXQsIHNvIHRoZXkgbGl2ZSBhdCB0aGUgc2FtZSBsZXZlbC5cbiAgICBSZXBvcnRGaWx0ZXJTdGF0ZVNlcnZpY2UsXG4gICAgUmVwb3J0RXhwb3J0Q29sbGVjdG9yU2VydmljZSxcbiAgICBSZXBvcnRQcHR4U2VydmljZSxcbiAgICBSZXBvcnRQZGZTZXJ2aWNlLFxuICAgIC8vIFRyZWUtc2hha2VuIEVDaGFydHMgY29yZSArIHRoZSAncmVwb3J0JyBob3VzZSB0aGVtZSwgbG9hZGVkIGxhemlseS5cbiAgICBwcm92aWRlRWNoYXJ0c0NvcmUoeyBlY2hhcnRzOiAoKSA9PiBpbXBvcnQoJy4uLy4uL3RoZW1lL2VjaGFydHMnKS50aGVuKChtb2R1bGUpID0+IG1vZHVsZS5kZWZhdWx0KSB9KSxcbiAgXSxcbiAgaW1wb3J0czogW1xuICAgIEZzRmlsdGVyTW9kdWxlLFxuICAgIEZzTWVudU1vZHVsZSxcbiAgICBGc0FpQ2hhdENvbXBvbmVudCxcbiAgICBNYXRCdXR0b25Nb2R1bGUsXG4gICAgTWF0SWNvbk1vZHVsZSxcbiAgICBNYXRUb29sdGlwTW9kdWxlLFxuICAgIFJlcG9ydENhbnZhc0NvbXBvbmVudCxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgRnNBaVJlcG9ydENvbXBvbmVudCB7XG5cbiAgLy8gVGhlIHJlcG9ydCB0aGlzIHZpZXcgaXMgZm9jdXNlZCBvbiDigJQgc3VwcGxpZWQgYnkgdGhlIGhvc3QgZnJvbSB0aGUgcm91dGUuXG4gIHB1YmxpYyByZWFkb25seSByZXBvcnRJZCA9IGlucHV0PG51bWJlciB8IG51bGw+KG51bGwpO1xuXG4gIC8vIEFQSSBiYXNlIGZvciB0aGUgcmVwb3J0cyArIGNoYXQgZW5kcG9pbnRzOyBvdmVycmlkZSB0byBtb3VudCBlbHNld2hlcmUuXG4gIHB1YmxpYyByZWFkb25seSBiYXNlUGF0aCA9IGlucHV0PHN0cmluZz4oJ3JlcG9ydHMnKTtcblxuICAvLyBUaGUgcmVwb3J0IHdhcyBkZWxldGVkIGZyb20gaXRzIHNldHRpbmdzIGRpYWxvZyDigJQgdGhlIGhvc3Qgcm91dGVzIGJhY2sgdG9cbiAgLy8gdGhlIGxpc3RpbmcuXG4gIHB1YmxpYyByZWFkb25seSBkZWxldGVkID0gb3V0cHV0PG51bWJlcj4oKTtcblxuICAvLyBUaGUgcmVwb3J0IHdhcyByZW5hbWVkIChzZXR0aW5ncywgb3IgdGhlIGFnZW50KSDigJQgdGhlIGhvc3QgY2FuIHJlZnJlc2ggYVxuICAvLyBicmVhZGNydW1iIC8gZG9jdW1lbnQgdGl0bGUuXG4gIHB1YmxpYyByZWFkb25seSByZW5hbWVkID0gb3V0cHV0PFJlcG9ydD4oKTtcblxuICBwdWJsaWMgcmVwb3J0OiBSZXBvcnQgfCBudWxsID0gbnVsbDtcbiAgcHVibGljIGVkaXRNb2RlID0gZmFsc2U7XG5cbiAgLy8gVGhlIHJlcG9ydC1sZXZlbCBmaWx0ZXIgdG9vbGJhciAoZnMtZmlsdGVyKS4gUmVidWlsdCB3aGVuZXZlciB0aGUgbG9hZGVkXG4gIC8vIHJlcG9ydCAoYW5kIHRodXMgaXRzIGdyb3VwcykgY2hhbmdlcy5cbiAgcHVibGljIHJlcG9ydEZpbHRlckNvbmZpZyE6IEZpbHRlckNvbmZpZztcblxuICBAVmlld0NoaWxkKCdzcGxpdCcsIHsgc3RhdGljOiB0cnVlIH0pXG4gIHByaXZhdGUgX3NwbGl0ITogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD47XG5cbiAgQFZpZXdDaGlsZCgnY2hhdFBhbmVsJywgeyBzdGF0aWM6IHRydWUsIHJlYWQ6IEVsZW1lbnRSZWYgfSlcbiAgcHJpdmF0ZSBfY2hhdFBhbmVsITogRWxlbWVudFJlZjxIVE1MRWxlbWVudD47XG5cbiAgcHJpdmF0ZSBfcmVwb3J0RGF0YSA9IGluamVjdChSZXBvcnREYXRhKTtcbiAgcHJpdmF0ZSBfZmlsdGVyU3RhdGUgPSBpbmplY3QoUmVwb3J0RmlsdGVyU3RhdGVTZXJ2aWNlKTtcbiAgcHJpdmF0ZSBfZXhwb3J0Q29sbGVjdG9yID0gaW5qZWN0KFJlcG9ydEV4cG9ydENvbGxlY3RvclNlcnZpY2UpO1xuICBwcml2YXRlIF9wcHR4U2VydmljZSA9IGluamVjdChSZXBvcnRQcHR4U2VydmljZSk7XG4gIHByaXZhdGUgX3BkZlNlcnZpY2UgPSBpbmplY3QoUmVwb3J0UGRmU2VydmljZSk7XG4gIHByaXZhdGUgX3Byb2Nlc3MgPSBpbmplY3QoRnNQcm9jZXNzKTtcbiAgcHJpdmF0ZSBfZGlhbG9nID0gaW5qZWN0KE1hdERpYWxvZyk7XG4gIHByaXZhdGUgX2Rlc3Ryb3lSZWYgPSBpbmplY3QoRGVzdHJveVJlZik7XG4gIHByaXZhdGUgX2NkUmVmID0gaW5qZWN0KENoYW5nZURldGVjdG9yUmVmKTtcbiAgcHJpdmF0ZSBfem9uZSA9IGluamVjdChOZ1pvbmUpO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIC8vIFBvaW50IHRoZSBzaGFyZWQgZGF0YSBnYXRld2F5IGF0IHRoZSBjb25maWd1cmVkIGJhc2UgZmlyc3QgKGJlZm9yZSBhbnlcbiAgICAvLyBsb2FkIGJlbG93IHJlYWRzIGl0KS5cbiAgICBlZmZlY3QoKCkgPT4ge1xuICAgICAgdGhpcy5fcmVwb3J0RGF0YS5iYXNlUGF0aCA9IHRoaXMuYmFzZVBhdGgoKTtcbiAgICB9KTtcblxuICAgIC8vIChSZSlsb2FkIHdoZW5ldmVyIHRoZSBob3N0IHN3aXRjaGVzIHRoZSByZXBvcnQgaWQuXG4gICAgZWZmZWN0KCgpID0+IHtcbiAgICAgIGNvbnN0IHJlcG9ydElkID0gdGhpcy5yZXBvcnRJZCgpO1xuICAgICAgdGhpcy5lZGl0TW9kZSA9IGZhbHNlO1xuXG4gICAgICBpZiAocmVwb3J0SWQgIT0gbnVsbCkge1xuICAgICAgICB0aGlzLl9sb2FkUmVwb3J0KHJlcG9ydElkKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucmVwb3J0ID0gbnVsbDtcbiAgICAgICAgdGhpcy5fYnVpbGRSZXBvcnRDb25maWcoKTtcbiAgICAgICAgdGhpcy5fY2RSZWYubWFya0ZvckNoZWNrKCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLl9idWlsZFJlcG9ydENvbmZpZygpO1xuICB9XG5cbiAgcHVibGljIHRvZ2dsZUVkaXRNb2RlKCk6IHZvaWQge1xuICAgIHRoaXMuZWRpdE1vZGUgPSAhdGhpcy5lZGl0TW9kZTtcbiAgfVxuXG4gIC8vIFJlcG9ydCBzZXR0aW5ncyDigJQgbmFtZSwgcGFnZSBzaXplLCBvcmllbnRhdGlvbiwgbGF5b3V0IG1vZGUsIGRlbGV0ZS4gVGhlXG4gIC8vIGRpYWxvZyBwZXJmb3JtcyB0aGUgZGVsZXRlIGl0c2VsZjsgd2UgcmVhY3QgdG8gd2hhdCBpdCByZXBvcnRzIGJhY2suXG4gIHB1YmxpYyByZXBvcnRTZXR0aW5ncygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMucmVwb3J0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcmVwb3J0SWQgPSB0aGlzLnJlcG9ydC5pZDtcblxuICAgIHRoaXMuX2RpYWxvZy5vcGVuPFJlcG9ydFNldHRpbmdzQ29tcG9uZW50LCB1bmtub3duLCBSZXBvcnRTZXR0aW5nc1Jlc3VsdD4oUmVwb3J0U2V0dGluZ3NDb21wb25lbnQsIHtcbiAgICAgIGRhdGE6IHsgcmVwb3J0OiB0aGlzLnJlcG9ydCB9LFxuICAgICAgd2lkdGg6ICc0NjBweCcsXG4gICAgfSlcbiAgICAgIC5hZnRlckNsb3NlZCgpXG4gICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5fZGVzdHJveVJlZikpXG4gICAgICAuc3Vic2NyaWJlKChyZXN1bHQpID0+IHtcbiAgICAgICAgaWYgKHJlc3VsdD8uYWN0aW9uID09PSAnZGVsZXRlZCcpIHtcbiAgICAgICAgICB0aGlzLmRlbGV0ZWQuZW1pdChyZXBvcnRJZCk7XG5cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocmVzdWx0Py5hY3Rpb24gPT09ICdzYXZlZCcpIHtcbiAgICAgICAgICB0aGlzLl9sb2FkUmVwb3J0KHJlcG9ydElkLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICAvLyBDb21wb25lbnQgc2V0dGluZ3Mg4oCUIHRpdGxlLCBleGFjdCBnZW9tZXRyeSwgYW5kIHRoZSBkaWFnbm9zdGljIHZpZXdzXG4gIC8vIChTUUwsIGNvbmZpZywgZmlsdGVyIHdpcmluZykuXG4gIHB1YmxpYyBjb21wb25lbnRTZXR0aW5ncyhjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudE1vZGVsKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnJlcG9ydCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHJlcG9ydElkID0gdGhpcy5yZXBvcnQuaWQ7XG5cbiAgICB0aGlzLl9kaWFsb2cub3BlbihDb21wb25lbnRTZXR0aW5nc0NvbXBvbmVudCwge1xuICAgICAgZGF0YTogeyByZXBvcnQ6IHRoaXMucmVwb3J0LCBjb21wb25lbnQgfSxcbiAgICAgIHdpZHRoOiAnNjQwcHgnLFxuICAgIH0pXG4gICAgICAuYWZ0ZXJDbG9zZWQoKVxuICAgICAgLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIC8vIEFsd2F5cyByZWxvYWQ6IGZpbHRlciBhZGQvcmVtb3ZlL2xldmVsIGNoYW5nZXMgcGVyc2lzdCBpbW1lZGlhdGVseVxuICAgICAgICAvLyBpbnNpZGUgdGhlIGRpYWxvZyAobm8gXCJzYXZlXCIpLCBzbyB0aGUgY2FudmFzICsgcmVwb3J0IGJhciBtdXN0XG4gICAgICAgIC8vIHJlZnJlc2ggaG93ZXZlciB0aGUgZGlhbG9nIHdhcyBjbG9zZWQuXG4gICAgICAgIHRoaXMuX2xvYWRSZXBvcnQocmVwb3J0SWQpO1xuICAgICAgfSk7XG4gIH1cblxuICAvLyBUaGUgY2FudmFzIGNoYW5nZWQgdGhlIHJlcG9ydCdzIHN0cnVjdHVyZSAoYWRkZWQgYSBwYWdlKSDigJQgcmUtZmV0Y2ggc28gdGhlXG4gIC8vIG5ldyBwYWdlIHJlbmRlcnM7IHRoZSBjYW52YXMgbGFuZHMgdGhlIHZpZXcgb24gaXQuXG4gIHB1YmxpYyBvbkNhbnZhc1JlcG9ydENoYW5nZWQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMucmVwb3J0KSB7XG4gICAgICB0aGlzLl9sb2FkUmVwb3J0KHRoaXMucmVwb3J0LmlkKTtcbiAgICB9XG4gIH1cblxuICAvLyBFeHBvcnQgdGhlIHJlcG9ydCB0byBQb3dlclBvaW50LCBlbnRpcmVseSBjbGllbnQtc2lkZSAobmF0aXZlIGVkaXRhYmxlXG4gIC8vIGNoYXJ0czsgcGFnZSA9IHNsaWRlKS4gVGhlIGRvY2sgc2hvd3MgcHJvZ3Jlc3MgdW50aWwgdGhlIGZpbGUgc2F2ZXMuXG4gIHB1YmxpYyBleHBvcnRQb3dlcnBvaW50KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5yZXBvcnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCByZXBvcnQgPSB0aGlzLnJlcG9ydDtcbiAgICB0aGlzLl9wcm9jZXNzLnJ1bihcbiAgICAgICdFeHBvcnRpbmcgUG93ZXJQb2ludCcsXG4gICAgICB0aGlzLl9leHBvcnRDb2xsZWN0b3IuY29sbGVjdChyZXBvcnQpXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgIHN3aXRjaE1hcCgoY29sbGVjdGVkKSA9PiBmcm9tKHRoaXMuX3BwdHhTZXJ2aWNlLmV4cG9ydChjb2xsZWN0ZWQpKSksXG4gICAgICAgICksXG4gICAgKTtcbiAgfVxuXG4gIC8vIEV4cG9ydCB0byBQREYsIGVudGlyZWx5IGNsaWVudC1zaWRlIChvZmZzY3JlZW4gRUNoYXJ0cyBhdCAzw5c7IHBhZ2UgPSBQREYgcGFnZSkuXG4gIHB1YmxpYyBleHBvcnRQZGYoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnJlcG9ydCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHJlcG9ydCA9IHRoaXMucmVwb3J0O1xuICAgIHRoaXMuX3Byb2Nlc3MucnVuKFxuICAgICAgJ0V4cG9ydGluZyBQREYnLFxuICAgICAgdGhpcy5fZXhwb3J0Q29sbGVjdG9yLmNvbGxlY3QocmVwb3J0KVxuICAgICAgICAucGlwZShcbiAgICAgICAgICBzd2l0Y2hNYXAoKGNvbGxlY3RlZCkgPT4gZnJvbSh0aGlzLl9wZGZTZXJ2aWNlLmV4cG9ydChjb2xsZWN0ZWQpKSksXG4gICAgICAgICksXG4gICAgKTtcbiAgfVxuXG4gIC8vIFJlYWN0IHRvIGVhY2ggY2hhdCB0dXJuIChmcy1jaGF0IGhhbmRsZXMgdGhlIHJlcXVlc3QgKyBwZXJzaXN0ZW5jZSk7IHdlXG4gIC8vIG9ubHkgY2FyZSBhYm91dCB0aGUgcmVwb3J0IHNpZGUgZWZmZWN0cyB0aGlzIGNvbnRleHQncyBiYWNrZW5kIGZsYWdzLlxuICBwdWJsaWMgb25DaGF0UmVzcG9uc2UocmVzcG9uc2U6IEZzQWlDaGF0UmVzcG9uc2UpOiB2b2lkIHtcbiAgICBjb25zdCByZXBvcnRJZCA9IHRoaXMucmVwb3J0SWQoKTtcbiAgICBpZiAocmVwb3J0SWQgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHJlcG9ydFJlc3BvbnNlID0gcmVzcG9uc2UgYXMgRnNBaUNoYXRSZXNwb25zZSAmIFJlcG9ydENoYXRSZXNwb25zZTtcblxuICAgIC8vIEEgc3RydWN0dXJhbCBjaGFuZ2Ugb3IgYSByZW5hbWUgYm90aCByZS1mZXRjaCB0aGUgcmVwb3J0IChzZXNzaW9uIGZpbHRlclxuICAgIC8vIHZhbHVlcyBzdXJ2aXZlKTsgYSByZW5hbWUgYWRkaXRpb25hbGx5IG5vdGlmaWVzIHRoZSBob3N0IHNvIGl0IGNhblxuICAgIC8vIHJlZnJlc2ggYSBicmVhZGNydW1iIC8gdGl0bGUuXG4gICAgaWYgKHJlcG9ydFJlc3BvbnNlLnJlcG9ydENoYW5nZWQgfHwgcmVwb3J0UmVzcG9uc2UucmVwb3J0UmVuYW1lZCkge1xuICAgICAgdGhpcy5fbG9hZFJlcG9ydChyZXBvcnRJZCwgISFyZXBvcnRSZXNwb25zZS5yZXBvcnRSZW5hbWVkKTtcbiAgICB9XG4gIH1cblxuICAvLyBEcmFnIHRoZSBkaXZpZGVyIGJldHdlZW4gdGhlIGNoYXQgYW5kIGNhbnZhcyBwYW5lcyAocG9pbnRlci1jYXB0dXJlIGxvb3BcbiAgLy8gb3V0c2lkZSBBbmd1bGFyKS5cbiAgcHVibGljIG9uUmVzaXplU3RhcnQoZXZlbnQ6IFBvaW50ZXJFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICBjb25zdCBoYW5kbGUgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgaGFuZGxlLnNldFBvaW50ZXJDYXB0dXJlKGV2ZW50LnBvaW50ZXJJZCk7XG4gICAgdGhpcy5fc3BsaXQubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QuYWRkKCdyZXNpemluZycpO1xuXG4gICAgdGhpcy5fem9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICBjb25zdCBtb3ZlID0gKGU6IFBvaW50ZXJFdmVudCkgPT4gdGhpcy5fcmVzaXplVG8oZS5jbGllbnRYKTtcbiAgICAgIGNvbnN0IGVuZCA9ICgpID0+IHtcbiAgICAgICAgaGFuZGxlLnJlbGVhc2VQb2ludGVyQ2FwdHVyZShldmVudC5wb2ludGVySWQpO1xuICAgICAgICBoYW5kbGUucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcm1vdmUnLCBtb3ZlKTtcbiAgICAgICAgaGFuZGxlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJ1cCcsIGVuZCk7XG4gICAgICAgIGhhbmRsZS5yZW1vdmVFdmVudExpc3RlbmVyKCdwb2ludGVyY2FuY2VsJywgZW5kKTtcbiAgICAgICAgdGhpcy5fc3BsaXQubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdyZXNpemluZycpO1xuICAgICAgfTtcblxuICAgICAgaGFuZGxlLmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJtb3ZlJywgbW92ZSk7XG4gICAgICBoYW5kbGUuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcnVwJywgZW5kKTtcbiAgICAgIGhhbmRsZS5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVyY2FuY2VsJywgZW5kKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX3Jlc2l6ZVRvKGNsaWVudFg6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IHJlY3QgPSB0aGlzLl9zcGxpdC5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGlmIChyZWN0LndpZHRoID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcmF0aW8gPSAoY2xpZW50WCAtIHJlY3QubGVmdCkgLyByZWN0LndpZHRoO1xuICAgIGNvbnN0IGNsYW1wZWQgPSBNYXRoLm1pbigwLjgsIE1hdGgubWF4KDAuMiwgcmF0aW8pKTtcbiAgICB0aGlzLl9jaGF0UGFuZWwubmF0aXZlRWxlbWVudC5zdHlsZS5mbGV4QmFzaXMgPSBgJHtjbGFtcGVkICogMTAwfSVgO1xuICB9XG5cbiAgcHJpdmF0ZSBfbG9hZFJlcG9ydChyZXBvcnRJZDogbnVtYmVyLCBlbWl0UmVuYW1lZCA9IGZhbHNlKTogdm9pZCB7XG4gICAgdGhpcy5fcmVwb3J0RGF0YS5nZXQocmVwb3J0SWQpXG4gICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5fZGVzdHJveVJlZikpXG4gICAgICAuc3Vic2NyaWJlKChyZXBvcnQ6IFJlcG9ydCkgPT4ge1xuICAgICAgICB0aGlzLnJlcG9ydCA9IHJlcG9ydDtcbiAgICAgICAgdGhpcy5fZmlsdGVyU3RhdGUuaW5pdChyZXBvcnQpO1xuICAgICAgICB0aGlzLl9idWlsZFJlcG9ydENvbmZpZygpO1xuXG4gICAgICAgIGlmIChlbWl0UmVuYW1lZCkge1xuICAgICAgICAgIHRoaXMucmVuYW1lZC5lbWl0KHJlcG9ydCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9jZFJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLy8gUmVwb3J0LWxldmVsIGZpbHRlciBncm91cHMgaW4gdGhlaXIgc2F2ZWQgb3JkZXIg4oCUIHRoZSBvbmVzIHRoYXQgcmVuZGVyIGluXG4gIC8vIHRoZSB0b29sYmFyIChjb21wb25lbnQtbGV2ZWwgZ3JvdXBzIHJlbmRlciBvbiB0aGVpciBjb21wb25lbnRzKS5cbiAgcHJpdmF0ZSBfcmVwb3J0R3JvdXBzKCk6IFJlcG9ydEZpbHRlckdyb3VwW10ge1xuICAgIHJldHVybiAodGhpcy5yZXBvcnQ/LmZpbHRlckdyb3VwcyA/PyBbXSlcbiAgICAgIC5maWx0ZXIoKGdyb3VwKSA9PiBncm91cC5sZXZlbCA9PT0gJ3JlcG9ydCcgfHwgZ3JvdXAubGV2ZWwgPT09ICdib3RoJylcbiAgICAgIC5zb3J0KChhLCBiKSA9PiBhLm9yZGVyIC0gYi5vcmRlcik7XG4gIH1cblxuICAvLyBXaGV0aGVyIHRoZSBsb2FkZWQgcmVwb3J0IGhhcyBhbnkgcmVwb3J0LWxldmVsIGZpbHRlcnMgT1IgYSB0aW1lLXNlcmllc1xuICAvLyBjaGFydCAod2hpY2ggZWFybnMgdGhlIHJ1bnRpbWUgRnJlcXVlbmN5IGNvbnRyb2wpIOKAlCBnYXRlcyB0aGUgdG9vbGJhci5cbiAgcHVibGljIGdldCByZXBvcnRIYXNGaWx0ZXJzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9yZXBvcnRHcm91cHMoKS5sZW5ndGggPiAwIHx8IHRoaXMuX2hhc1RpbWVTZXJpZXNDaGFydCgpO1xuICB9XG5cbiAgLy8gZnMtZmlsdGVyIHJlYWRzIGl0cyBjb25maWcgb25seSBvbmNlIChhdCBpbml0KS4gVGhlIHRlbXBsYXRlIGtleXMgdGhlXG4gIC8vIHRvb2xiYXIgZnMtZmlsdGVyIG9uIHRoaXMgc2lnbmF0dXJlIHNvIGl0J3MgcmVjcmVhdGVkIChhbmQgcmUtcmVhZHMgdGhlXG4gIC8vIHJlYnVpbHQgY29uZmlnKSB3aGVuZXZlciB0aGUgcmVwb3J0LWxldmVsIGZpbHRlciBzZXQgY2hhbmdlcy5cbiAgcHVibGljIGdldCByZXBvcnRGaWx0ZXJLZXkoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gW1xuICAgICAgLi4udGhpcy5fcmVwb3J0R3JvdXBzKCkubWFwKChncm91cCkgPT4gYCR7Z3JvdXAuaWR9OiR7Z3JvdXAubGV2ZWx9OiR7Z3JvdXAubGFiZWx9YCksXG4gICAgICB0aGlzLl9oYXNUaW1lU2VyaWVzQ2hhcnQoKSA/ICdmcmVxdWVuY3knIDogJycsXG4gICAgXS5qb2luKCd8Jyk7XG4gIH1cblxuICAvLyAoUmUpYnVpbGQgdGhlIHRvb2xiYXIgZnMtZmlsdGVyIGNvbmZpZyDigJQgcmVwb3J0LWxldmVsIGZpbHRlciBpdGVtcywgcGx1c1xuICAvLyB0aGUgcnVudGltZSBGcmVxdWVuY3kgY29udHJvbCB3aGVuIHRoZSByZXBvcnQgaGFzIGEgdGltZS1zZXJpZXMgY2hhcnQuXG4gIHByaXZhdGUgX2J1aWxkUmVwb3J0Q29uZmlnKCk6IHZvaWQge1xuICAgIGNvbnN0IHJlcG9ydElkID0gdGhpcy5yZXBvcnQ/LmlkID8/IG51bGw7XG5cbiAgICBjb25zdCBpdGVtcyA9IHJlcG9ydElkXG4gICAgICA/IHRoaXMuX3JlcG9ydEdyb3VwcygpLm1hcCgoZ3JvdXApID0+XG4gICAgICAgIGZpbHRlckl0ZW1Gb3JHcm91cChncm91cCwgdGhpcy5fcmVwb3J0RGF0YSwgcmVwb3J0SWQsIHRoaXMuX2ZpbHRlclN0YXRlLnZhbHVlKGdyb3VwLmlkKSkpXG4gICAgICA6IFtdO1xuXG4gICAgaWYgKHJlcG9ydElkICYmIHRoaXMuX2hhc1RpbWVTZXJpZXNDaGFydCgpKSB7XG4gICAgICBpdGVtcy5wdXNoKHtcbiAgICAgICAgbmFtZTogRlJFUVVFTkNZX0lURU0sXG4gICAgICAgIHR5cGU6IEl0ZW1UeXBlLlNlbGVjdCxcbiAgICAgICAgbGFiZWw6ICdGcmVxdWVuY3knLFxuICAgICAgICBtdWx0aXBsZTogZmFsc2UsXG4gICAgICAgIHZhbHVlczogKCkgPT4gRlJFUVVFTkNZX09QVElPTlMsXG4gICAgICAgIGRlZmF1bHQ6IHRoaXMuX2ZpbHRlclN0YXRlLmZyZXF1ZW5jeSgpID8/IHVuZGVmaW5lZCxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMucmVwb3J0RmlsdGVyQ29uZmlnID0ge1xuICAgICAgLy8gTmV2ZXIgdG91Y2ggdGhlIFVSTCBvciBwZXJzaXN0IGZpbHRlciBzdGF0ZSDigJQgcmVwb3J0IGZpbHRlcnMgYXJlXG4gICAgICAvLyBzZXNzaW9uLW9ubHksIG93bmVkIGJ5IFJlcG9ydEZpbHRlclN0YXRlU2VydmljZS5cbiAgICAgIHF1ZXJ5UGFyYW06IGZhbHNlLFxuICAgICAgcGVyc2lzdDogZmFsc2UsXG4gICAgICBpdGVtcyxcbiAgICAgIGNoYW5nZTogKHF1ZXJ5KSA9PiB7XG4gICAgICAgIGZvciAoY29uc3QgeyBncm91cElkLCB2YWx1ZSB9IG9mIGdyb3VwVmFsdWVzRnJvbVF1ZXJ5KHF1ZXJ5ID8/IHt9LCB0aGlzLl9yZXBvcnRHcm91cHMoKSkpIHtcbiAgICAgICAgICB0aGlzLl9maWx0ZXJTdGF0ZS5zZXRWYWx1ZShncm91cElkLCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRnJlcXVlbmN5IGlzbid0IGEgZmlsdGVyIGdyb3VwIOKAlCBpdCdzIGEgcmVuZGVyLWxheWVyIGJ1Y2tldCBvdmVycmlkZS5cbiAgICAgICAgdGhpcy5fZmlsdGVyU3RhdGUuc2V0RnJlcXVlbmN5KChxdWVyeT8uW0ZSRVFVRU5DWV9JVEVNXSBhcyBDaGFydEdyYW51bGFyaXR5KSB8fCBudWxsKTtcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIC8vIFRoZSByZXBvcnQgaGFzIGF0IGxlYXN0IG9uZSB0aW1lLXNlcmllcyBjaGFydCAoeC1heGlzIGlzIGEgdGltZSBheGlzKSDigJQgdGhlXG4gIC8vIG9ubHkga2luZCB0aGUgRnJlcXVlbmN5IGNvbnRyb2wgYWZmZWN0cy5cbiAgcHJpdmF0ZSBfaGFzVGltZVNlcmllc0NoYXJ0KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAodGhpcy5yZXBvcnQ/LnBhZ2VzID8/IFtdKS5zb21lKChwYWdlKSA9PlxuICAgICAgcGFnZS5jb21wb25lbnRzLnNvbWUoKGNvbXBvbmVudCkgPT5cbiAgICAgICAgY29tcG9uZW50LnR5cGUgPT09ICdjaGFydCcgJiYgY29tcG9uZW50LmNvbmZpZz8ueEF4aXM/LmtpbmQgPT09ICd0aW1lJykpO1xuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwiZnMtYWktcmVwb3J0IGZzLWNvbHVtblwiPlxuXG4gIDxkaXYgY2xhc3M9XCJmcy1haS1yZXBvcnRfX2hlYWRlciBmcy1yb3cuYWxpZ24tY2VudGVyXCI+XG4gICAgPGgyIGNsYXNzPVwiZnMtYWktcmVwb3J0X190aXRsZSBmcy1mbGV4XCI+e3sgcmVwb3J0Py5uYW1lIH19PC9oMj5cblxuICAgIEBpZiAocmVwb3J0KSB7XG4gICAgICA8YnV0dG9uXG4gICAgICAgICAgbWF0LWljb24tYnV0dG9uXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgW21hdFRvb2x0aXBdPVwiZWRpdE1vZGUgPyAnRG9uZScgOiAnRWRpdCBsYXlvdXQnXCJcbiAgICAgICAgICAoY2xpY2spPVwidG9nZ2xlRWRpdE1vZGUoKVwiPlxuICAgICAgICA8bWF0LWljb24+e3sgZWRpdE1vZGUgPyAnbG9jaycgOiAnb3Blbl93aXRoJyB9fTwvbWF0LWljb24+XG4gICAgICA8L2J1dHRvbj5cblxuICAgICAgPGJ1dHRvblxuICAgICAgICAgIG1hdC1pY29uLWJ1dHRvblxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIG1hdFRvb2x0aXA9XCJFeHBvcnRcIlxuICAgICAgICAgIFtmc01lbnVUcmlnZ2VyRm9yXT1cImV4cG9ydE1lbnVcIj5cbiAgICAgICAgPG1hdC1pY29uPmRvd25sb2FkPC9tYXQtaWNvbj5cbiAgICAgIDwvYnV0dG9uPlxuICAgICAgPGZzLW1lbnUgI2V4cG9ydE1lbnU+XG4gICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgICAgZnMtbWVudS1pdGVtXG4gICAgICAgICAgICAoY2xpY2spPVwiZXhwb3J0UG93ZXJwb2ludCgpXCI+XG4gICAgICAgICAgRXhwb3J0IFBvd2VyUG9pbnRcbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICBmcy1tZW51LWl0ZW1cbiAgICAgICAgICAgIChjbGljayk9XCJleHBvcnRQZGYoKVwiPlxuICAgICAgICAgIEV4cG9ydCBQREZcbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgIDwvZnMtbWVudT5cblxuICAgICAgPGJ1dHRvblxuICAgICAgICAgIG1hdC1pY29uLWJ1dHRvblxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIG1hdFRvb2x0aXA9XCJSZXBvcnQgc2V0dGluZ3NcIlxuICAgICAgICAgIChjbGljayk9XCJyZXBvcnRTZXR0aW5ncygpXCI+XG4gICAgICAgIDxtYXQtaWNvbj5zZXR0aW5nczwvbWF0LWljb24+XG4gICAgICA8L2J1dHRvbj5cbiAgICB9XG4gIDwvZGl2PlxuXG4gIDxkaXZcbiAgICAgICNzcGxpdFxuICAgICAgY2xhc3M9XCJmcy1haS1yZXBvcnRfX3NwbGl0IGZzLXJvdy5hbGlnbi1zdGFydFwiPlxuICAgIDxmcy1haS1jaGF0XG4gICAgICAgICNjaGF0UGFuZWxcbiAgICAgICAgY2xhc3M9XCJjaGF0XCJcbiAgICAgICAgW2Jhc2VQYXRoXT1cImJhc2VQYXRoKClcIlxuICAgICAgICBbcmVxdWVzdERhdGFdPVwieyByZXBvcnRJZDogcmVwb3J0SWQoKSB9XCJcbiAgICAgICAgKHJlc3BvbnNlKT1cIm9uQ2hhdFJlc3BvbnNlKCRldmVudClcIj5cbiAgICA8L2ZzLWFpLWNoYXQ+XG5cbiAgICA8ZGl2XG4gICAgICAgIGNsYXNzPVwicmVzaXplclwiXG4gICAgICAgIChwb2ludGVyZG93bik9XCJvblJlc2l6ZVN0YXJ0KCRldmVudClcIj5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJ2aWV3ZXIgZnMtZmxleCBmcy1jb2x1bW5cIj5cbiAgICAgIEBpZiAocmVwb3J0KSB7XG4gICAgICAgIDwhLS0gUmVwb3J0LWxldmVsIGZpbHRlcnMgb25seSAodGhlIHJlcG9ydCdzIGFjdGlvbnMgbGl2ZSBpbiB0aGUgaGVhZGVyXG4gICAgICAgICAgICAgYWJvdmUpLiBmcy1maWx0ZXIgcmVhZHMgaXRzIGNvbmZpZyBvbmNlIGF0IGluaXQsIHNvIGl0J3Mga2V5ZWQgb25cbiAgICAgICAgICAgICB0aGUgZmlsdGVyIHNpZ25hdHVyZTogd2hlbiB0aGUgcmVwb3J0LWxldmVsIGZpbHRlciBzZXQgY2hhbmdlcyB0aGVcbiAgICAgICAgICAgICBibG9jayBpcyByZWNyZWF0ZWQgYW5kIHJlLXJlYWRzIHRoZSByZWJ1aWx0IGNvbmZpZy4gLS0+XG4gICAgICAgIEBpZiAocmVwb3J0SGFzRmlsdGVycykge1xuICAgICAgICAgIEBmb3IgKGtleSBvZiBbcmVwb3J0RmlsdGVyS2V5XTsgdHJhY2sga2V5KSB7XG4gICAgICAgICAgICA8ZnMtZmlsdGVyIFtjb25maWddPVwicmVwb3J0RmlsdGVyQ29uZmlnXCI+PC9mcy1maWx0ZXI+XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIDxhcHAtcmVwb3J0LWNhbnZhc1xuICAgICAgICAgICAgW3JlcG9ydF09XCJyZXBvcnRcIlxuICAgICAgICAgICAgW2VkaXRNb2RlXT1cImVkaXRNb2RlXCJcbiAgICAgICAgICAgIChjb21wb25lbnRTZXR0aW5ncyk9XCJjb21wb25lbnRTZXR0aW5ncygkZXZlbnQpXCJcbiAgICAgICAgICAgIChyZXBvcnRDaGFuZ2VkKT1cIm9uQ2FudmFzUmVwb3J0Q2hhbmdlZCgpXCJcbiAgICAgICAgICAgIChlZGl0RG9uZSk9XCJ0b2dnbGVFZGl0TW9kZSgpXCI+XG4gICAgICAgIDwvYXBwLXJlcG9ydC1jYW52YXM+XG4gICAgICB9XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9kaXY+XG4iXX0=
|