ng-kinintel 0.0.397 → 20.0.2
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/fesm2022/ng-kinintel.mjs +11874 -0
- package/fesm2022/ng-kinintel.mjs.map +1 -0
- package/index.d.ts +2818 -5
- package/package.json +6 -14
- package/esm2020/lib/components/alert-groups/alert-groups.component.mjs +0 -76
- package/esm2020/lib/components/alert-groups/edit-alert-group/edit-alert-group.component.mjs +0 -83
- package/esm2020/lib/components/dashboard-editor/configure-item/configure-item.component.mjs +0 -853
- package/esm2020/lib/components/dashboard-editor/configure-item/edit-dashboard-alert/edit-dashboard-alert.component.mjs +0 -56
- package/esm2020/lib/components/dashboard-editor/configure-item/html-documentation/html-documentation.component.mjs +0 -114
- package/esm2020/lib/components/dashboard-editor/configure-item/table-cell-formatter/table-cell-formatter.component.mjs +0 -163
- package/esm2020/lib/components/dashboard-editor/configure-item/vis-network-options.json +0 -135
- package/esm2020/lib/components/dashboard-editor/dashboard-editor.component.mjs +0 -580
- package/esm2020/lib/components/dashboard-editor/dashboard-parameter/dashboard-parameter.component.mjs +0 -15
- package/esm2020/lib/components/dashboard-editor/dashboard-settings/dashboard-settings.component.mjs +0 -50
- package/esm2020/lib/components/dashboard-editor/item-component/item-component.component.mjs +0 -1226
- package/esm2020/lib/components/dashboard-editor/source-selector-dialog/source-selector-dialog.component.mjs +0 -111
- package/esm2020/lib/components/dashboards/dashboards.component.mjs +0 -163
- package/esm2020/lib/components/dashboards/view-dashboard/view-dashboard.component.mjs +0 -429
- package/esm2020/lib/components/data-explorer/change-source-warning/change-source-warning.component.mjs +0 -20
- package/esm2020/lib/components/data-explorer/data-explorer.component.mjs +0 -243
- package/esm2020/lib/components/data-explorer/export-data/export-data.component.mjs +0 -62
- package/esm2020/lib/components/data-explorer/snapshot-api-access/snapshot-api-access.component.mjs +0 -70
- package/esm2020/lib/components/data-explorer/snapshot-profile-dialog/snapshot-profile-dialog.component.mjs +0 -190
- package/esm2020/lib/components/data-picker/data-picker.component.mjs +0 -79
- package/esm2020/lib/components/data-search/data-search.component.mjs +0 -11
- package/esm2020/lib/components/data-sharing-invite/data-sharing-invite.component.mjs +0 -52
- package/esm2020/lib/components/dataset/create-dataset/create-dataset.component.mjs +0 -47
- package/esm2020/lib/components/dataset/dataset-editor/available-columns/available-columns.component.mjs +0 -28
- package/esm2020/lib/components/dataset/dataset-editor/dataset-add-join/dataset-add-join.component.mjs +0 -344
- package/esm2020/lib/components/dataset/dataset-editor/dataset-column-settings/dataset-column-editor/dataset-column-editor.component.mjs +0 -80
- package/esm2020/lib/components/dataset/dataset-editor/dataset-column-settings/dataset-column-settings.component.mjs +0 -54
- package/esm2020/lib/components/dataset/dataset-editor/dataset-create-formula/dataset-create-formula.component.mjs +0 -67
- package/esm2020/lib/components/dataset/dataset-editor/dataset-editor.component.mjs +0 -1134
- package/esm2020/lib/components/dataset/dataset-editor/dataset-filters/dataset-filter/dataset-filter.component.mjs +0 -201
- package/esm2020/lib/components/dataset/dataset-editor/dataset-filters/dataset-filter-inclusion/dataset-filter-inclusion.component.mjs +0 -25
- package/esm2020/lib/components/dataset/dataset-editor/dataset-filters/dataset-filter-junction/dataset-filter-junction.component.mjs +0 -72
- package/esm2020/lib/components/dataset/dataset-editor/dataset-filters/dataset-filters.component.mjs +0 -62
- package/esm2020/lib/components/dataset/dataset-editor/dataset-name-dialog/dataset-name-dialog.component.mjs +0 -41
- package/esm2020/lib/components/dataset/dataset-editor/dataset-parameter-values/dataset-add-parameter/dataset-add-parameter.component.mjs +0 -78
- package/esm2020/lib/components/dataset/dataset-editor/dataset-parameter-values/dataset-parameter-type/dataset-parameter-type.component.mjs +0 -39
- package/esm2020/lib/components/dataset/dataset-editor/dataset-parameter-values/dataset-parameter-values.component.mjs +0 -75
- package/esm2020/lib/components/dataset/dataset-editor/dataset-summarise/dataset-summarise.component.mjs +0 -107
- package/esm2020/lib/components/dataset/dataset-editor/move-transformation-confirmation/move-transformation-confirmation.component.mjs +0 -20
- package/esm2020/lib/components/dataset/dataset-editor/remove-transformation-warning/remove-transformation-warning.component.mjs +0 -20
- package/esm2020/lib/components/dataset/dataset-editor/save-as-query/save-as-query.component.mjs +0 -58
- package/esm2020/lib/components/dataset/dataset-editor/share-query/share-query.component.mjs +0 -110
- package/esm2020/lib/components/dataset/dataset-editor/upstream-changes-confirmation/upstream-changes-confirmation.component.mjs +0 -20
- package/esm2020/lib/components/dataset/dataset.component.mjs +0 -294
- package/esm2020/lib/components/datasource/create-datasource/advanced-settings/advanced-settings.component.mjs +0 -130
- package/esm2020/lib/components/datasource/create-datasource/api-access/api-access.component.mjs +0 -132
- package/esm2020/lib/components/datasource/create-datasource/create-datasource.component.mjs +0 -729
- package/esm2020/lib/components/datasource/create-datasource/import-data/import-data.component.mjs +0 -146
- package/esm2020/lib/components/datasource/create-datasource/import-data/import-wizard/import-wizard.component.mjs +0 -165
- package/esm2020/lib/components/datasource/create-datasource/tabular-datasource/tabular-datasource.component.mjs +0 -145
- package/esm2020/lib/components/datasource/datasource.component.mjs +0 -162
- package/esm2020/lib/components/datasource/document-datasource/document-datasource.component.mjs +0 -297
- package/esm2020/lib/components/export-project/export-project.component.mjs +0 -29
- package/esm2020/lib/components/feeds/feed/feed.component.mjs +0 -92
- package/esm2020/lib/components/feeds/feeds.component.mjs +0 -145
- package/esm2020/lib/components/job-tasks/job-tasks.component.mjs +0 -25
- package/esm2020/lib/components/marketplace/marketplace.component.mjs +0 -65
- package/esm2020/lib/components/metadata/metadata.component.mjs +0 -65
- package/esm2020/lib/components/notification-groups/edit-notification-group/edit-notification-group.component.mjs +0 -113
- package/esm2020/lib/components/notification-groups/notification-groups.component.mjs +0 -86
- package/esm2020/lib/components/project-picker/project-picker.component.mjs +0 -118
- package/esm2020/lib/components/project-settings/project-link-selection/project-link-selection.component.mjs +0 -104
- package/esm2020/lib/components/project-settings/project-settings.component.mjs +0 -155
- package/esm2020/lib/components/query-caching/edit-query-cache/edit-query-cache.component.mjs +0 -51
- package/esm2020/lib/components/query-caching/query-cache-view/query-cache-view.component.mjs +0 -121
- package/esm2020/lib/components/query-caching/query-caching.component.mjs +0 -162
- package/esm2020/lib/components/shared-with-me/feed-api-modal/feed-api-modal.component.mjs +0 -45
- package/esm2020/lib/components/shared-with-me/shared-with-me.component.mjs +0 -174
- package/esm2020/lib/components/snapshots/snapshots.component.mjs +0 -244
- package/esm2020/lib/components/tag-picker/tag-picker.component.mjs +0 -74
- package/esm2020/lib/components/task-time-periods/task-time-periods.component.mjs +0 -55
- package/esm2020/lib/components/whitelisted-sql-functions/whitelisted-sql-functions.component.mjs +0 -40
- package/esm2020/lib/guards/dashboard-changes.guard.mjs +0 -22
- package/esm2020/lib/kinintel-config.mjs +0 -3
- package/esm2020/lib/ng-kinintel.module.mjs +0 -437
- package/esm2020/lib/objects/action-event.mjs +0 -16
- package/esm2020/lib/services/alert.service.mjs +0 -52
- package/esm2020/lib/services/dashboard.service.mjs +0 -75
- package/esm2020/lib/services/data-processor.service.mjs +0 -56
- package/esm2020/lib/services/data-search.service.mjs +0 -36
- package/esm2020/lib/services/dataset.service.mjs +0 -187
- package/esm2020/lib/services/datasource.service.mjs +0 -93
- package/esm2020/lib/services/external.service.mjs +0 -33
- package/esm2020/lib/services/feed.service.mjs +0 -50
- package/esm2020/lib/services/notification.service.mjs +0 -41
- package/esm2020/lib/services/project.service.mjs +0 -130
- package/esm2020/lib/services/tag.service.mjs +0 -63
- package/esm2020/ng-kinintel.mjs +0 -5
- package/esm2020/public-api.mjs +0 -43
- package/fesm2015/ng-kinintel.mjs +0 -12182
- package/fesm2015/ng-kinintel.mjs.map +0 -1
- package/fesm2020/ng-kinintel.mjs +0 -11872
- package/fesm2020/ng-kinintel.mjs.map +0 -1
- package/lib/components/alert-groups/alert-groups.component.d.ts +0 -30
- package/lib/components/alert-groups/edit-alert-group/edit-alert-group.component.d.ts +0 -28
- package/lib/components/dashboard-editor/configure-item/configure-item.component.d.ts +0 -256
- package/lib/components/dashboard-editor/configure-item/edit-dashboard-alert/edit-dashboard-alert.component.d.ts +0 -16
- package/lib/components/dashboard-editor/configure-item/html-documentation/html-documentation.component.d.ts +0 -59
- package/lib/components/dashboard-editor/configure-item/table-cell-formatter/table-cell-formatter.component.d.ts +0 -26
- package/lib/components/dashboard-editor/dashboard-editor.component.d.ts +0 -85
- package/lib/components/dashboard-editor/dashboard-parameter/dashboard-parameter.component.d.ts +0 -8
- package/lib/components/dashboard-editor/dashboard-settings/dashboard-settings.component.d.ts +0 -22
- package/lib/components/dashboard-editor/item-component/item-component.component.d.ts +0 -264
- package/lib/components/dashboard-editor/source-selector-dialog/source-selector-dialog.component.d.ts +0 -30
- package/lib/components/dashboards/dashboards.component.d.ts +0 -56
- package/lib/components/dashboards/view-dashboard/view-dashboard.component.d.ts +0 -81
- package/lib/components/data-explorer/change-source-warning/change-source-warning.component.d.ts +0 -11
- package/lib/components/data-explorer/data-explorer.component.d.ts +0 -61
- package/lib/components/data-explorer/export-data/export-data.component.d.ts +0 -17
- package/lib/components/data-explorer/snapshot-api-access/snapshot-api-access.component.d.ts +0 -25
- package/lib/components/data-explorer/snapshot-profile-dialog/snapshot-profile-dialog.component.d.ts +0 -44
- package/lib/components/data-picker/data-picker.component.d.ts +0 -32
- package/lib/components/data-search/data-search.component.d.ts +0 -5
- package/lib/components/data-sharing-invite/data-sharing-invite.component.d.ts +0 -21
- package/lib/components/dataset/create-dataset/create-dataset.component.d.ts +0 -17
- package/lib/components/dataset/dataset-editor/available-columns/available-columns.component.d.ts +0 -12
- package/lib/components/dataset/dataset-editor/dataset-add-join/dataset-add-join.component.d.ts +0 -61
- package/lib/components/dataset/dataset-editor/dataset-column-settings/dataset-column-editor/dataset-column-editor.component.d.ts +0 -21
- package/lib/components/dataset/dataset-editor/dataset-column-settings/dataset-column-settings.component.d.ts +0 -20
- package/lib/components/dataset/dataset-editor/dataset-create-formula/dataset-create-formula.component.d.ts +0 -19
- package/lib/components/dataset/dataset-editor/dataset-editor.component.d.ts +0 -131
- package/lib/components/dataset/dataset-editor/dataset-filters/dataset-filter/dataset-filter.component.d.ts +0 -63
- package/lib/components/dataset/dataset-editor/dataset-filters/dataset-filter-inclusion/dataset-filter-inclusion.component.d.ts +0 -11
- package/lib/components/dataset/dataset-editor/dataset-filters/dataset-filter-junction/dataset-filter-junction.component.d.ts +0 -20
- package/lib/components/dataset/dataset-editor/dataset-filters/dataset-filters.component.d.ts +0 -16
- package/lib/components/dataset/dataset-editor/dataset-name-dialog/dataset-name-dialog.component.d.ts +0 -18
- package/lib/components/dataset/dataset-editor/dataset-parameter-values/dataset-add-parameter/dataset-add-parameter.component.d.ts +0 -23
- package/lib/components/dataset/dataset-editor/dataset-parameter-values/dataset-parameter-type/dataset-parameter-type.component.d.ts +0 -13
- package/lib/components/dataset/dataset-editor/dataset-parameter-values/dataset-parameter-values.component.d.ts +0 -22
- package/lib/components/dataset/dataset-editor/dataset-summarise/dataset-summarise.component.d.ts +0 -27
- package/lib/components/dataset/dataset-editor/move-transformation-confirmation/move-transformation-confirmation.component.d.ts +0 -11
- package/lib/components/dataset/dataset-editor/remove-transformation-warning/remove-transformation-warning.component.d.ts +0 -11
- package/lib/components/dataset/dataset-editor/save-as-query/save-as-query.component.d.ts +0 -25
- package/lib/components/dataset/dataset-editor/share-query/share-query.component.d.ts +0 -41
- package/lib/components/dataset/dataset-editor/upstream-changes-confirmation/upstream-changes-confirmation.component.d.ts +0 -11
- package/lib/components/dataset/dataset.component.d.ts +0 -74
- package/lib/components/datasource/create-datasource/advanced-settings/advanced-settings.component.d.ts +0 -26
- package/lib/components/datasource/create-datasource/api-access/api-access.component.d.ts +0 -31
- package/lib/components/datasource/create-datasource/create-datasource.component.d.ts +0 -112
- package/lib/components/datasource/create-datasource/import-data/import-data.component.d.ts +0 -28
- package/lib/components/datasource/create-datasource/import-data/import-wizard/import-wizard.component.d.ts +0 -40
- package/lib/components/datasource/create-datasource/tabular-datasource/tabular-datasource.component.d.ts +0 -34
- package/lib/components/datasource/datasource.component.d.ts +0 -46
- package/lib/components/datasource/document-datasource/document-datasource.component.d.ts +0 -64
- package/lib/components/export-project/export-project.component.d.ts +0 -9
- package/lib/components/feeds/feed/feed.component.d.ts +0 -30
- package/lib/components/feeds/feeds.component.d.ts +0 -47
- package/lib/components/job-tasks/job-tasks.component.d.ts +0 -11
- package/lib/components/marketplace/marketplace.component.d.ts +0 -42
- package/lib/components/metadata/metadata.component.d.ts +0 -24
- package/lib/components/notification-groups/edit-notification-group/edit-notification-group.component.d.ts +0 -37
- package/lib/components/notification-groups/notification-groups.component.d.ts +0 -28
- package/lib/components/project-picker/project-picker.component.d.ts +0 -37
- package/lib/components/project-settings/project-link-selection/project-link-selection.component.d.ts +0 -32
- package/lib/components/project-settings/project-settings.component.d.ts +0 -40
- package/lib/components/query-caching/edit-query-cache/edit-query-cache.component.d.ts +0 -17
- package/lib/components/query-caching/query-cache-view/query-cache-view.component.d.ts +0 -35
- package/lib/components/query-caching/query-caching.component.d.ts +0 -38
- package/lib/components/shared-with-me/feed-api-modal/feed-api-modal.component.d.ts +0 -21
- package/lib/components/shared-with-me/shared-with-me.component.d.ts +0 -43
- package/lib/components/snapshots/snapshots.component.d.ts +0 -52
- package/lib/components/tag-picker/tag-picker.component.d.ts +0 -27
- package/lib/components/task-time-periods/task-time-periods.component.d.ts +0 -20
- package/lib/components/whitelisted-sql-functions/whitelisted-sql-functions.component.d.ts +0 -17
- package/lib/guards/dashboard-changes.guard.d.ts +0 -11
- package/lib/kinintel-config.d.ts +0 -10
- package/lib/ng-kinintel.module.d.ts +0 -116
- package/lib/objects/action-event.d.ts +0 -12
- package/lib/services/alert.service.d.ts +0 -17
- package/lib/services/dashboard.service.d.ts +0 -25
- package/lib/services/data-processor.service.d.ts +0 -18
- package/lib/services/data-search.service.d.ts +0 -14
- package/lib/services/dataset.service.d.ts +0 -56
- package/lib/services/datasource.service.d.ts +0 -34
- package/lib/services/external.service.d.ts +0 -12
- package/lib/services/feed.service.d.ts +0 -19
- package/lib/services/notification.service.d.ts +0 -16
- package/lib/services/project.service.d.ts +0 -27
- package/lib/services/tag.service.d.ts +0 -19
- package/public-api.d.ts +0 -38
|
@@ -1,1226 +0,0 @@
|
|
|
1
|
-
import { Component, EventEmitter, HostBinding, Input, Output, ViewChild } from '@angular/core';
|
|
2
|
-
import { ConfigureItemComponent } from '../configure-item/configure-item.component';
|
|
3
|
-
import * as lodash from 'lodash';
|
|
4
|
-
import { Subject } from 'rxjs';
|
|
5
|
-
import moment from 'moment';
|
|
6
|
-
import regression from 'regression';
|
|
7
|
-
import { EditDashboardAlertComponent } from '../configure-item/edit-dashboard-alert/edit-dashboard-alert.component';
|
|
8
|
-
import { ExportDataComponent } from '../../data-explorer/export-data/export-data.component';
|
|
9
|
-
import chroma from 'chroma-js';
|
|
10
|
-
import { DataSet, Network } from 'vis-network/standalone';
|
|
11
|
-
import visNetworkOptions from '../configure-item/vis-network-options.json';
|
|
12
|
-
import * as i0 from "@angular/core";
|
|
13
|
-
import * as i1 from "@angular/material/legacy-dialog";
|
|
14
|
-
import * as i2 from "../../../services/datasource.service";
|
|
15
|
-
import * as i3 from "../../../services/dataset.service";
|
|
16
|
-
import * as i4 from "../../../services/alert.service";
|
|
17
|
-
import * as i5 from "../../../services/dashboard.service";
|
|
18
|
-
import * as i6 from "@angular/platform-browser";
|
|
19
|
-
import * as i7 from "@angular/router";
|
|
20
|
-
import * as i8 from "@angular/common";
|
|
21
|
-
import * as i9 from "../../../services/external.service";
|
|
22
|
-
import * as i10 from "../../../services/project.service";
|
|
23
|
-
import * as i11 from "@angular/material/legacy-button";
|
|
24
|
-
import * as i12 from "@angular/material/icon";
|
|
25
|
-
import * as i13 from "ng2-charts";
|
|
26
|
-
import * as i14 from "@angular/material/legacy-menu";
|
|
27
|
-
import * as i15 from "@angular/forms";
|
|
28
|
-
import * as i16 from "@angular/material/legacy-slide-toggle";
|
|
29
|
-
import * as i17 from "@angular/material/divider";
|
|
30
|
-
import * as i18 from "@angular/material/legacy-tooltip";
|
|
31
|
-
import * as i19 from "angular-d3-cloud";
|
|
32
|
-
const _ = lodash.default;
|
|
33
|
-
export class ItemComponentComponent {
|
|
34
|
-
constructor(dialog, kiDatasourceService, kiDatasetService, kiAlertService, dashboardService, sanitizer, router, location, externalService, projectService) {
|
|
35
|
-
this.dialog = dialog;
|
|
36
|
-
this.kiDatasourceService = kiDatasourceService;
|
|
37
|
-
this.kiDatasetService = kiDatasetService;
|
|
38
|
-
this.kiAlertService = kiAlertService;
|
|
39
|
-
this.dashboardService = dashboardService;
|
|
40
|
-
this.sanitizer = sanitizer;
|
|
41
|
-
this.router = router;
|
|
42
|
-
this.location = location;
|
|
43
|
-
this.externalService = externalService;
|
|
44
|
-
this.projectService = projectService;
|
|
45
|
-
this.actionEvents = [];
|
|
46
|
-
this.external = false;
|
|
47
|
-
this.editAlerts = false;
|
|
48
|
-
this.duplicateItem = new EventEmitter();
|
|
49
|
-
this.configureClass = false;
|
|
50
|
-
this._ = _;
|
|
51
|
-
this.imageError = false;
|
|
52
|
-
this.Object = Object;
|
|
53
|
-
this.String = String;
|
|
54
|
-
this.dashboardDatasetInstance = {};
|
|
55
|
-
this.loadingItem = false;
|
|
56
|
-
this.filterFields = [];
|
|
57
|
-
this.dependencies = {};
|
|
58
|
-
this.metric = {};
|
|
59
|
-
this.textData = {};
|
|
60
|
-
this.networkData = {};
|
|
61
|
-
this.wordCloud = {};
|
|
62
|
-
this.imageData = {};
|
|
63
|
-
this.tabular = {};
|
|
64
|
-
this.tableCells = {};
|
|
65
|
-
this.hiddenColumns = {};
|
|
66
|
-
this.general = {};
|
|
67
|
-
this.callToAction = {};
|
|
68
|
-
this.actionItem = {};
|
|
69
|
-
this.alert = false;
|
|
70
|
-
this.alertData = [];
|
|
71
|
-
this.showAlertData = false;
|
|
72
|
-
this.currencies = [
|
|
73
|
-
{
|
|
74
|
-
name: 'British Pound (£)',
|
|
75
|
-
value: 'GBP',
|
|
76
|
-
symbol: '£'
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
name: 'US Dollar ($)',
|
|
80
|
-
value: 'USD',
|
|
81
|
-
symbol: '$'
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
name: 'Euro (€)',
|
|
85
|
-
value: 'EUR',
|
|
86
|
-
symbol: '€'
|
|
87
|
-
}
|
|
88
|
-
];
|
|
89
|
-
this.limit = 25;
|
|
90
|
-
this.page = 1;
|
|
91
|
-
this.offset = 0;
|
|
92
|
-
this.endOfResults = false;
|
|
93
|
-
this.itemLocked = false;
|
|
94
|
-
this.optimise = true;
|
|
95
|
-
this.optimiseSubject = new Subject();
|
|
96
|
-
this.canExportData = false;
|
|
97
|
-
this.externalError = false;
|
|
98
|
-
this.quotaExceeded = null;
|
|
99
|
-
this.existingGridItem = false;
|
|
100
|
-
this.itemNoMove = false;
|
|
101
|
-
this.visNetworkOptions = visNetworkOptions;
|
|
102
|
-
}
|
|
103
|
-
ngAfterViewInit() {
|
|
104
|
-
setTimeout(() => {
|
|
105
|
-
this.canExportData = this.projectService.doesActiveProjectHavePrivilege('exportdata');
|
|
106
|
-
const instanceElement = document.getElementById(this.itemInstanceKey);
|
|
107
|
-
if (instanceElement) {
|
|
108
|
-
const widget = instanceElement.closest('.grid-stack-item');
|
|
109
|
-
this.itemNoMove = widget.getAttribute('gs-no-move') === 'true';
|
|
110
|
-
}
|
|
111
|
-
}, 50);
|
|
112
|
-
}
|
|
113
|
-
async init(evaluate = false) {
|
|
114
|
-
this.mapLayoutSettingsToComponentData();
|
|
115
|
-
if (this.tabular && this.tabular.limit) {
|
|
116
|
-
this.limit = this.tabular.limit;
|
|
117
|
-
}
|
|
118
|
-
if (this.general && this.general.limit) {
|
|
119
|
-
this.limit = this.general.limit;
|
|
120
|
-
this.offset = this.general.offset;
|
|
121
|
-
}
|
|
122
|
-
if (!this.datasourceService) {
|
|
123
|
-
this.datasourceService = this.kiDatasourceService;
|
|
124
|
-
}
|
|
125
|
-
if (!this.datasetService) {
|
|
126
|
-
this.datasetService = this.kiDatasetService;
|
|
127
|
-
}
|
|
128
|
-
if (!this.alertService) {
|
|
129
|
-
this.alertService = this.kiAlertService;
|
|
130
|
-
}
|
|
131
|
-
if (this.dashboard &&
|
|
132
|
-
this.dashboard.displaySettings.heading &&
|
|
133
|
-
this.dashboard.displaySettings.heading[this.itemInstanceKey]) {
|
|
134
|
-
this.dashboardItemType.headingValue = this.dashboard.displaySettings.heading[this.itemInstanceKey];
|
|
135
|
-
}
|
|
136
|
-
if (this.general.parameterBar && Object.keys(this.general.parameterBar).length) {
|
|
137
|
-
if (!this.general.widgetParameters || Array.isArray(this.general.widgetParameters)) {
|
|
138
|
-
this.general.widgetParameters = {};
|
|
139
|
-
}
|
|
140
|
-
Object.keys(this.general.parameterBar).forEach(paramKey => {
|
|
141
|
-
if (this.general.parameterBar[paramKey] && !this.general.widgetParameters[paramKey]) {
|
|
142
|
-
this.general.widgetParameters[paramKey] = _.cloneDeep(this.dashboard.layoutSettings.parameters[paramKey]);
|
|
143
|
-
}
|
|
144
|
-
if (!this.general.parameterBar[paramKey]) {
|
|
145
|
-
delete this.general.widgetParameters[paramKey];
|
|
146
|
-
}
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
this.configureClass = true;
|
|
150
|
-
if (this.dependencies.instanceKeys && this.dependencies.instanceKeys.length) {
|
|
151
|
-
this.loadingItem = true;
|
|
152
|
-
this.itemLoadedSub = this.dashboardService.dashboardItems.subscribe(async (loaded) => {
|
|
153
|
-
const loadedInstances = Object.keys(loaded);
|
|
154
|
-
const dependent = _.filter(loadedInstances, key => {
|
|
155
|
-
return this.dependencies.instanceKeys.indexOf(key) > -1;
|
|
156
|
-
});
|
|
157
|
-
if (dependent.length === this.dependencies.instanceKeys.length) {
|
|
158
|
-
if (this.itemLoadedSub) {
|
|
159
|
-
this.itemLoadedSub.unsubscribe();
|
|
160
|
-
}
|
|
161
|
-
const allLoaded = _.every(this.dependencies.instanceKeys, key => {
|
|
162
|
-
return this.dependencies[key].type === 'LOADED';
|
|
163
|
-
});
|
|
164
|
-
if (allLoaded) {
|
|
165
|
-
this.evaluate();
|
|
166
|
-
}
|
|
167
|
-
else {
|
|
168
|
-
const matches = _.filter(this.dependencies, { type: 'MATCH' });
|
|
169
|
-
const allMatched = [];
|
|
170
|
-
for (const dep of matches) {
|
|
171
|
-
const selectedDatasetInstance = _.find(this.dashboard.datasetInstances, { instanceKey: dep.key });
|
|
172
|
-
if (selectedDatasetInstance) {
|
|
173
|
-
const mappedParams = this.getMappedParams(selectedDatasetInstance);
|
|
174
|
-
const transformations = _.clone(selectedDatasetInstance.transformationInstances);
|
|
175
|
-
transformations.push({ type: 'filter', config: dep.filterJunction });
|
|
176
|
-
const datasetInstanceSummary = {
|
|
177
|
-
datasetInstanceId: selectedDatasetInstance.datasetInstanceId,
|
|
178
|
-
datasourceInstanceKey: selectedDatasetInstance.datasourceInstanceKey,
|
|
179
|
-
transformationInstances: transformations,
|
|
180
|
-
parameterValues: mappedParams,
|
|
181
|
-
parameters: selectedDatasetInstance.parameters
|
|
182
|
-
};
|
|
183
|
-
let data = null;
|
|
184
|
-
if (this.external) {
|
|
185
|
-
data = await this.externalService.evaluateDataset(this.dashboard.id, this.itemInstanceKey, selectedDatasetInstance.parameterValues, '0', '1', this.queryParams);
|
|
186
|
-
}
|
|
187
|
-
else {
|
|
188
|
-
data = await this.datasetService.evaluateDataset(datasetInstanceSummary, '0', '1');
|
|
189
|
-
}
|
|
190
|
-
allMatched.push(data.allData.length === 1);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
if (_.every(allMatched)) {
|
|
194
|
-
this.evaluate();
|
|
195
|
-
}
|
|
196
|
-
else {
|
|
197
|
-
this.loadingItem = false;
|
|
198
|
-
const itemElement = document.getElementById(this.itemInstanceKey).closest('.grid-stack-item');
|
|
199
|
-
itemElement.classList.add('item-disabled');
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
else if (evaluate) {
|
|
206
|
-
this.evaluate();
|
|
207
|
-
}
|
|
208
|
-
this.optimiseSub = this.optimiseSubject.subscribe(res => this.optimise = res);
|
|
209
|
-
this.existingGridItem = !!_.find(this.dashboard.layoutSettings.grid, item => {
|
|
210
|
-
return item.content.includes(this.itemInstanceKey);
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
ngOnDestroy() {
|
|
214
|
-
if (this.optimiseSub) {
|
|
215
|
-
this.optimiseSub.unsubscribe();
|
|
216
|
-
}
|
|
217
|
-
if (this.itemLoadedSub) {
|
|
218
|
-
this.itemLoadedSub.unsubscribe();
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
lockItem() {
|
|
222
|
-
const itemElement = document.getElementById(this.itemInstanceKey);
|
|
223
|
-
const widget = itemElement.closest('.grid-stack-item');
|
|
224
|
-
this.itemNoMove = widget.getAttribute('gs-no-move') !== 'true';
|
|
225
|
-
this.grid.update(widget, { noMove: this.itemNoMove });
|
|
226
|
-
}
|
|
227
|
-
duplicate() {
|
|
228
|
-
this.duplicateItem.emit(this.itemInstanceKey);
|
|
229
|
-
}
|
|
230
|
-
configure() {
|
|
231
|
-
if (this.dashboardItemType.type === 'heading') {
|
|
232
|
-
this.dashboardItemType._editing = true;
|
|
233
|
-
}
|
|
234
|
-
else {
|
|
235
|
-
const queryParams = {};
|
|
236
|
-
if (this.admin) {
|
|
237
|
-
queryParams.a = true;
|
|
238
|
-
}
|
|
239
|
-
this.router.navigate([window.location.pathname], {
|
|
240
|
-
queryParams,
|
|
241
|
-
fragment: _.kebabCase(this.dashboard.title)
|
|
242
|
-
});
|
|
243
|
-
const dialogRef = this.dialog.open(ConfigureItemComponent, {
|
|
244
|
-
width: '100vw',
|
|
245
|
-
height: '100vh',
|
|
246
|
-
maxWidth: '100vw',
|
|
247
|
-
maxHeight: '100vh',
|
|
248
|
-
hasBackdrop: false,
|
|
249
|
-
data: {
|
|
250
|
-
grid: this.grid,
|
|
251
|
-
dashboard: this.dashboard,
|
|
252
|
-
dashboardDatasetInstance: this.dashboardDatasetInstance,
|
|
253
|
-
itemInstanceKey: this.itemInstanceKey,
|
|
254
|
-
dashboardItemType: this.dashboardItemType,
|
|
255
|
-
admin: this.admin,
|
|
256
|
-
actionEvents: this.actionEvents
|
|
257
|
-
}
|
|
258
|
-
});
|
|
259
|
-
dialogRef.afterClosed().subscribe(dashboardDatasetInstance => {
|
|
260
|
-
if (dashboardDatasetInstance) {
|
|
261
|
-
this.dashboardDatasetInstance = dashboardDatasetInstance;
|
|
262
|
-
this.location.back();
|
|
263
|
-
this.init(true);
|
|
264
|
-
}
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
load() {
|
|
269
|
-
// Check to see if any of the grid items are locked
|
|
270
|
-
const grid = this.dashboard.layoutSettings.grid;
|
|
271
|
-
const lockedItems = _.filter(grid, 'locked');
|
|
272
|
-
this.itemLocked = !!_.find(lockedItems, lockedItem => {
|
|
273
|
-
return lockedItem.content.includes(this.itemInstanceKey);
|
|
274
|
-
});
|
|
275
|
-
if (this.external) {
|
|
276
|
-
this.itemLocked = true;
|
|
277
|
-
}
|
|
278
|
-
if (this.dashboardDatasetInstance) {
|
|
279
|
-
return this.evaluate();
|
|
280
|
-
}
|
|
281
|
-
return Promise.resolve(true);
|
|
282
|
-
}
|
|
283
|
-
removeWidget(event) {
|
|
284
|
-
const message = 'Are your sure you would like to remove this item from your dashboard?';
|
|
285
|
-
if (window.confirm(message)) {
|
|
286
|
-
const itemElement = document.getElementById(this.itemInstanceKey);
|
|
287
|
-
_.remove(this.dashboard.datasetInstances, { instanceKey: this.itemInstanceKey });
|
|
288
|
-
const widget = itemElement.closest('.grid-stack-item');
|
|
289
|
-
this.grid.removeWidget(widget);
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
triggerActionEvent(actionEvent, column, value) {
|
|
293
|
-
const action = _.find(this.actionEvents, { name: actionEvent });
|
|
294
|
-
if (action) {
|
|
295
|
-
action.event.next({ key: column.name, value });
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
getActionEventTitle(actionEvent, column, value) {
|
|
299
|
-
const action = _.find(this.actionEvents, { name: actionEvent });
|
|
300
|
-
let title = '';
|
|
301
|
-
if (action) {
|
|
302
|
-
title = this.isActionComplete(actionEvent, value) ? action.completeLabel : action.actionLabel;
|
|
303
|
-
}
|
|
304
|
-
return title;
|
|
305
|
-
}
|
|
306
|
-
isActionComplete(actionEvent, value) {
|
|
307
|
-
let complete = false;
|
|
308
|
-
const action = _.find(this.actionEvents, { name: actionEvent });
|
|
309
|
-
if (action) {
|
|
310
|
-
const findData = {};
|
|
311
|
-
findData[action.comparisonField] = value;
|
|
312
|
-
complete = _.find(action.data || [], findData);
|
|
313
|
-
}
|
|
314
|
-
return complete;
|
|
315
|
-
}
|
|
316
|
-
editItemAlerts(alert, index) {
|
|
317
|
-
const dialogRef = this.dialog.open(EditDashboardAlertComponent, {
|
|
318
|
-
width: '900px',
|
|
319
|
-
height: '750px',
|
|
320
|
-
data: {
|
|
321
|
-
alert,
|
|
322
|
-
filterFields: this.filterFields
|
|
323
|
-
}
|
|
324
|
-
});
|
|
325
|
-
dialogRef.afterClosed().subscribe(alertItem => {
|
|
326
|
-
if (alertItem) {
|
|
327
|
-
if (!this.dashboardDatasetInstance.alerts) {
|
|
328
|
-
this.dashboardDatasetInstance.alerts = [];
|
|
329
|
-
}
|
|
330
|
-
if (index >= 0) {
|
|
331
|
-
this.dashboardDatasetInstance.alerts[index] = alertItem;
|
|
332
|
-
}
|
|
333
|
-
else {
|
|
334
|
-
this.dashboardDatasetInstance.alerts.push(alertItem);
|
|
335
|
-
}
|
|
336
|
-
this.reloadAlert();
|
|
337
|
-
}
|
|
338
|
-
});
|
|
339
|
-
}
|
|
340
|
-
removeAlert(event, alert, i) {
|
|
341
|
-
const message = `Are you sure you would like to delete the "${alert.title}" Alert?`;
|
|
342
|
-
if (window.confirm(message)) {
|
|
343
|
-
this.dashboardDatasetInstance.alerts.splice(i, 1);
|
|
344
|
-
this.reloadAlert();
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
exportData() {
|
|
348
|
-
const datasetInstanceSummary = this.prepareDatasetInstanceSummaryForEvaluation();
|
|
349
|
-
const dialogRef = this.dialog.open(ExportDataComponent, {
|
|
350
|
-
width: '600px',
|
|
351
|
-
height: '530px',
|
|
352
|
-
data: {
|
|
353
|
-
datasetInstanceSummary
|
|
354
|
-
}
|
|
355
|
-
});
|
|
356
|
-
}
|
|
357
|
-
updateHeading(event) {
|
|
358
|
-
if (!this.dashboard.displaySettings.heading) {
|
|
359
|
-
this.dashboard.displaySettings.heading = {};
|
|
360
|
-
}
|
|
361
|
-
this.dashboard.displaySettings.heading[this.itemInstanceKey] = this.dashboardItemType.headingValue;
|
|
362
|
-
this.dashboardItemType._editing = false;
|
|
363
|
-
}
|
|
364
|
-
async setupNetworkChart() {
|
|
365
|
-
const nodeData = this.dataset.allData;
|
|
366
|
-
const datasetNodes = [];
|
|
367
|
-
const datasetEdges = [];
|
|
368
|
-
nodeData.forEach(item => {
|
|
369
|
-
const nodeLevelItem = {};
|
|
370
|
-
const nodeItem = {
|
|
371
|
-
id: item[this.networkData.nodeIds],
|
|
372
|
-
label: item[this.networkData.nodeLabels],
|
|
373
|
-
group: item[this.networkData.nodeGroups]
|
|
374
|
-
};
|
|
375
|
-
if (this.networkData.nodes) {
|
|
376
|
-
if (this.networkData.nodes[nodeItem.id]) {
|
|
377
|
-
nodeItem.x = this.networkData.nodes[nodeItem.id].x;
|
|
378
|
-
nodeItem.y = this.networkData.nodes[nodeItem.id].y;
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
if (this.networkData.nodeLevelOptions && Object.keys(this.networkData.nodeLevelOptions).length &&
|
|
382
|
-
this.networkData.nodeLevelOptions[nodeItem.id]) {
|
|
383
|
-
this.networkData.nodeLevelOptions[nodeItem.id].forEach(option => {
|
|
384
|
-
nodeLevelItem[option.key] = option.value;
|
|
385
|
-
});
|
|
386
|
-
}
|
|
387
|
-
datasetNodes.push(Object.assign(nodeLevelItem, nodeItem));
|
|
388
|
-
if (!this.networkData.edgeDatasetTitle) {
|
|
389
|
-
datasetEdges.push({
|
|
390
|
-
from: item[this.networkData.fromIds],
|
|
391
|
-
to: item[this.networkData.toIds]
|
|
392
|
-
});
|
|
393
|
-
}
|
|
394
|
-
});
|
|
395
|
-
if (this.networkData.edgeDatasetTitle) {
|
|
396
|
-
const datasetInstanceSummary = {
|
|
397
|
-
datasetInstanceId: this.networkData.edgeDatasetId,
|
|
398
|
-
datasourceInstanceKey: this.networkData.edgeDatasourceKey,
|
|
399
|
-
transformationInstances: [],
|
|
400
|
-
parameterValues: {},
|
|
401
|
-
parameters: {}
|
|
402
|
-
};
|
|
403
|
-
const edgeDataset = await this.datasetService.evaluateDataset(datasetInstanceSummary, '0', '10000000');
|
|
404
|
-
edgeDataset.allData.forEach(item => {
|
|
405
|
-
datasetEdges.push({
|
|
406
|
-
from: item[this.networkData.fromIds],
|
|
407
|
-
to: item[this.networkData.toIds]
|
|
408
|
-
});
|
|
409
|
-
});
|
|
410
|
-
}
|
|
411
|
-
datasetEdges.forEach(edge => {
|
|
412
|
-
const edgeOptions = _.find(this.networkData.edgeLevelOptions, { from: edge.from, to: edge.to });
|
|
413
|
-
if (edgeOptions && edgeOptions.options.length) {
|
|
414
|
-
edgeOptions.options.forEach(option => {
|
|
415
|
-
edge[option.key] = option.value;
|
|
416
|
-
});
|
|
417
|
-
}
|
|
418
|
-
});
|
|
419
|
-
// create an array with nodes
|
|
420
|
-
const nodes = new DataSet(datasetNodes);
|
|
421
|
-
// create an array with edges
|
|
422
|
-
const edges = new DataSet(datasetEdges);
|
|
423
|
-
// create a network
|
|
424
|
-
const container = document.getElementById(this.itemInstanceKey + 'VIS');
|
|
425
|
-
const data = {
|
|
426
|
-
nodes,
|
|
427
|
-
edges
|
|
428
|
-
};
|
|
429
|
-
const options = {
|
|
430
|
-
nodes: {
|
|
431
|
-
font: {
|
|
432
|
-
multi: 'html'
|
|
433
|
-
}
|
|
434
|
-
},
|
|
435
|
-
edges: {},
|
|
436
|
-
groups: {},
|
|
437
|
-
layout: {}
|
|
438
|
-
};
|
|
439
|
-
const mapOptionValue = (option, networkType) => {
|
|
440
|
-
if (option && Object.keys(option).length) {
|
|
441
|
-
const type = visNetworkOptions[networkType][option.key].type;
|
|
442
|
-
let value = option.value;
|
|
443
|
-
if (type === 'number') {
|
|
444
|
-
value = Number(value);
|
|
445
|
-
}
|
|
446
|
-
else if (type === 'boolean') {
|
|
447
|
-
value = value === 'true';
|
|
448
|
-
}
|
|
449
|
-
options[networkType][option.key] = value;
|
|
450
|
-
}
|
|
451
|
-
};
|
|
452
|
-
if (this.networkData.nodeOptions) {
|
|
453
|
-
this.networkData.nodeOptions.forEach(option => {
|
|
454
|
-
mapOptionValue(option, 'nodes');
|
|
455
|
-
});
|
|
456
|
-
}
|
|
457
|
-
if (this.networkData.edgeOptions) {
|
|
458
|
-
this.networkData.edgeOptions.forEach(option => {
|
|
459
|
-
mapOptionValue(option, 'edges');
|
|
460
|
-
});
|
|
461
|
-
}
|
|
462
|
-
if (this.networkData.nodeGroupOptions && Object.keys(this.networkData.nodeGroupOptions).length) {
|
|
463
|
-
Object.keys(this.networkData.nodeGroupOptions).forEach(groupKey => {
|
|
464
|
-
this.networkData.nodeGroupOptions[groupKey].options.forEach(option => {
|
|
465
|
-
if (!options.groups[groupKey]) {
|
|
466
|
-
options.groups[groupKey] = {};
|
|
467
|
-
}
|
|
468
|
-
if (option && Object.keys(option).length) {
|
|
469
|
-
options.groups[groupKey][option.key] = option.value;
|
|
470
|
-
}
|
|
471
|
-
});
|
|
472
|
-
});
|
|
473
|
-
}
|
|
474
|
-
const network = new Network(container, data, options);
|
|
475
|
-
this.networkData.network = network;
|
|
476
|
-
}
|
|
477
|
-
evaluateTextData(textData) {
|
|
478
|
-
let evaluatedTextData = '';
|
|
479
|
-
const element = document.createElement('div');
|
|
480
|
-
element.innerHTML = this.bindParametersInString(textData);
|
|
481
|
-
const data = {
|
|
482
|
-
dataSet: this.dataset.allData
|
|
483
|
-
};
|
|
484
|
-
_.forEach(this.dataset.allData[0] || [], (value, key) => {
|
|
485
|
-
data[key] = value;
|
|
486
|
-
});
|
|
487
|
-
const Kinibind = window.Kinibind;
|
|
488
|
-
Kinibind.config = {
|
|
489
|
-
prefix: 'd',
|
|
490
|
-
templateDelimiters: ['[[', ']]']
|
|
491
|
-
};
|
|
492
|
-
const bind = new Kinibind(element, data);
|
|
493
|
-
const boundHTML = bind.boundContext.els[0].innerHTML;
|
|
494
|
-
evaluatedTextData = this.sanitizer.sanitize(1, boundHTML);
|
|
495
|
-
element.remove();
|
|
496
|
-
return evaluatedTextData;
|
|
497
|
-
}
|
|
498
|
-
async setChartData() {
|
|
499
|
-
if (this.dashboardItemType.xAxis && this.dashboardItemType.yAxis) {
|
|
500
|
-
let datasetData = this.dataset.allData;
|
|
501
|
-
if (this.dashboardItemType.limit) {
|
|
502
|
-
datasetData = datasetData.slice(0, this.dashboardItemType.limit);
|
|
503
|
-
if (this.dashboardItemType.combineRemaining && !this.dashboardItemType.seriesColumn) {
|
|
504
|
-
const remainingData = await this.evaluateDataset(10000000, 0);
|
|
505
|
-
const combined = [];
|
|
506
|
-
for (let i = 0; i < remainingData.allData.length; i++) {
|
|
507
|
-
if (i > this.dashboardItemType.limit) {
|
|
508
|
-
combined.push(remainingData.allData[i]);
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
const pushObject = {};
|
|
512
|
-
pushObject[this.dashboardItemType.xAxis] = this.dashboardItemType.combineRemaingingLabel || 'Remaining';
|
|
513
|
-
pushObject[this.dashboardItemType.yAxis] = _.sumBy(combined, remainingItem => {
|
|
514
|
-
return Number(remainingItem[this.dashboardItemType.yAxis]);
|
|
515
|
-
});
|
|
516
|
-
datasetData.push(pushObject);
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
let data;
|
|
520
|
-
if (!this.dashboardItemType.seriesColumn) {
|
|
521
|
-
if (this.dashboardItemType.type !== 'pie' && this.dashboardItemType.type !== 'doughnut') {
|
|
522
|
-
data = _.map(datasetData, item => {
|
|
523
|
-
return { x: item[this.dashboardItemType.xAxis], y: item[this.dashboardItemType.yAxis] };
|
|
524
|
-
});
|
|
525
|
-
}
|
|
526
|
-
else {
|
|
527
|
-
data = _.map(datasetData, item => {
|
|
528
|
-
return item[this.dashboardItemType.yAxis];
|
|
529
|
-
});
|
|
530
|
-
}
|
|
531
|
-
this.chartData = [
|
|
532
|
-
{
|
|
533
|
-
data,
|
|
534
|
-
label: _.find(this.filterFields, { name: this.dashboardItemType.xAxis }).title,
|
|
535
|
-
fill: !!this.dashboardItemType.fill,
|
|
536
|
-
borderColor: (this.dashboardItemType.type === 'pie' || this.dashboardItemType.type === 'doughnut') ? chroma('white').alpha(0.2).hex() : this.dashboardItemType.borderColor,
|
|
537
|
-
backgroundColor: this.dashboardItemType.type === 'line' ?
|
|
538
|
-
(Array.isArray(this.dashboardItemType.borderColor) ? _.map(this.dashboardItemType.borderColor, colour => {
|
|
539
|
-
return chroma(colour || 'black').alpha(0.5).hex();
|
|
540
|
-
}) : chroma(this.dashboardItemType.borderColor || 'black').alpha(0.5).hex()) : this.dashboardItemType.backgroundColor,
|
|
541
|
-
tension: 0.2,
|
|
542
|
-
pointBackgroundColor: this.dashboardItemType.borderColor ? this.dashboardItemType.borderColor[0] : null,
|
|
543
|
-
pointBorderColor: this.dashboardItemType.borderColor ? this.dashboardItemType.borderColor[0] : null
|
|
544
|
-
}
|
|
545
|
-
];
|
|
546
|
-
this.dashboardItemType.labels = _.map(datasetData, item => {
|
|
547
|
-
return item[this.dashboardItemType.xAxis];
|
|
548
|
-
});
|
|
549
|
-
}
|
|
550
|
-
else {
|
|
551
|
-
const chartData = [];
|
|
552
|
-
const series = _.uniq(_.map(datasetData, this.dashboardItemType.seriesColumn));
|
|
553
|
-
series.forEach((value, index) => {
|
|
554
|
-
const seriesResults = _.filter(datasetData, allData => {
|
|
555
|
-
return allData[this.dashboardItemType.seriesColumn] === value;
|
|
556
|
-
});
|
|
557
|
-
chartData.push({
|
|
558
|
-
data: _.map(seriesResults, item => {
|
|
559
|
-
return { x: item[this.dashboardItemType.xAxis], y: item[this.dashboardItemType.yAxis] };
|
|
560
|
-
}),
|
|
561
|
-
label: value,
|
|
562
|
-
fill: !!this.dashboardItemType.fill,
|
|
563
|
-
borderColor: this.dashboardItemType.borderColor,
|
|
564
|
-
backgroundColor: this.dashboardItemType.type === 'line' ?
|
|
565
|
-
(Array.isArray(this.dashboardItemType.borderColor) ? _.map(this.dashboardItemType.borderColor, colour => {
|
|
566
|
-
return chroma(colour || 'black').alpha(0.5).hex();
|
|
567
|
-
}) : chroma(this.dashboardItemType.borderColor || 'black').alpha(0.5).hex()) : this.dashboardItemType.backgroundColor[index],
|
|
568
|
-
tension: 0.2,
|
|
569
|
-
pointBackgroundColor: this.dashboardItemType.borderColor[index],
|
|
570
|
-
pointBorderColor: this.dashboardItemType.borderColor[index]
|
|
571
|
-
});
|
|
572
|
-
});
|
|
573
|
-
this.chartData = chartData;
|
|
574
|
-
this.dashboardItemType.labels = _.uniq(_.map(datasetData, item => {
|
|
575
|
-
return item[this.dashboardItemType.xAxis];
|
|
576
|
-
}));
|
|
577
|
-
}
|
|
578
|
-
if (this.dashboardItemType.trendLine) {
|
|
579
|
-
let trendLine = [];
|
|
580
|
-
let trendLabel = 'Trend';
|
|
581
|
-
if (this.dashboardItemType.trendLine === 'average') {
|
|
582
|
-
trendLabel = 'Average';
|
|
583
|
-
const trendData = [];
|
|
584
|
-
this.chartData.forEach(dataItem => {
|
|
585
|
-
trendData.push(_.map(dataItem.data, 'y'));
|
|
586
|
-
});
|
|
587
|
-
const average = _.flatMap(trendData).reduce((p, c) => p + c, 0) / _.flatMap(trendData).length;
|
|
588
|
-
trendLine = _.fill(_.range(0, _.flatMap(trendData).length), average, 0, _.flatMap(trendData).length);
|
|
589
|
-
}
|
|
590
|
-
else if (this.dashboardItemType.trendLine === 'logarithmic' ||
|
|
591
|
-
this.dashboardItemType.trendLine === 'linear' ||
|
|
592
|
-
this.dashboardItemType.trendLine === 'power' ||
|
|
593
|
-
this.dashboardItemType.trendLine === 'exponential') {
|
|
594
|
-
const trendLineData = _.map(this.dataset.allData, (item, index) => {
|
|
595
|
-
return { x: index + 1, y: item[this.dashboardItemType.yAxis] };
|
|
596
|
-
}).filter(({ x, y }) => {
|
|
597
|
-
return (typeof x === typeof y && // filter out one string & one number
|
|
598
|
-
!isNaN(x) && // filter out `NaN`
|
|
599
|
-
!isNaN(y) &&
|
|
600
|
-
Math.abs(x) !== Infinity &&
|
|
601
|
-
Math.abs(y) !== Infinity);
|
|
602
|
-
}).map(({ x, y }) => {
|
|
603
|
-
return [x, y];
|
|
604
|
-
});
|
|
605
|
-
const trendLineResults = regression[this.dashboardItemType.trendLine](trendLineData);
|
|
606
|
-
trendLine = trendLineResults.points.map(([x, y]) => {
|
|
607
|
-
return y;
|
|
608
|
-
});
|
|
609
|
-
}
|
|
610
|
-
else {
|
|
611
|
-
trendLine = _.map(this.dataset.allData, item => {
|
|
612
|
-
return item[this.dashboardItemType.trendLine];
|
|
613
|
-
});
|
|
614
|
-
trendLabel = _.find(this.filterFields, { name: this.dashboardItemType.trendLine }).title;
|
|
615
|
-
}
|
|
616
|
-
this.chartData.push({
|
|
617
|
-
type: 'line',
|
|
618
|
-
data: trendLine,
|
|
619
|
-
label: trendLabel,
|
|
620
|
-
borderColor: this.dashboardItemType.trendLineColour,
|
|
621
|
-
fill: false,
|
|
622
|
-
order: -1,
|
|
623
|
-
tension: 0.15,
|
|
624
|
-
pointBackgroundColor: this.dashboardItemType.trendLineColour,
|
|
625
|
-
pointBorderColor: this.dashboardItemType.trendLineColour
|
|
626
|
-
});
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
}
|
|
630
|
-
updateImageData() {
|
|
631
|
-
this.imageData.source = this.imageData.column ? this.dataset.allData[0][this.imageData.column] : null;
|
|
632
|
-
}
|
|
633
|
-
updateMetricDataValues() {
|
|
634
|
-
if (this.metric.main) {
|
|
635
|
-
this.metric.mainValue = _.isNaN(Number(this.dataset.allData[0][this.metric.main])) ? this.dataset.allData[0][this.metric.main] : Number(this.dataset.allData[0][this.metric.main]);
|
|
636
|
-
this.metric.title = _.startCase(this.metric.main);
|
|
637
|
-
}
|
|
638
|
-
if (this.metric.subMetric) {
|
|
639
|
-
this.metric.subValue = Number(this.dataset.allData[0][this.metric.subMetric]);
|
|
640
|
-
this.metric.subTitle = _.startCase(this.metric.subMetric);
|
|
641
|
-
}
|
|
642
|
-
if (this.metric.showSubChange) {
|
|
643
|
-
this.metric.difference = Math.abs(this.metric.mainValue - this.metric.subValue);
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
callToActionLink(cta, dataItem) {
|
|
647
|
-
let url = null;
|
|
648
|
-
if (cta.type === 'dashboard') {
|
|
649
|
-
const params = _.pickBy(cta.parameters, (value, key) => {
|
|
650
|
-
return !_.startsWith(key, 'custom-');
|
|
651
|
-
});
|
|
652
|
-
const data = dataItem || this.dashboard.layoutSettings.parameters;
|
|
653
|
-
Object.keys(params).forEach(paramKey => {
|
|
654
|
-
let value = this.bindParametersInString(params[paramKey], data);
|
|
655
|
-
// Check if we have any column eg. [[ ]] values needing mapping
|
|
656
|
-
value = this.mapColumnToValue(value, data);
|
|
657
|
-
params[paramKey] = value;
|
|
658
|
-
});
|
|
659
|
-
const urlParams = new URLSearchParams(params).toString();
|
|
660
|
-
url = `/dashboards/view/${cta.value}${this.admin ? '?a=true&' : '?'}${urlParams}`;
|
|
661
|
-
}
|
|
662
|
-
else if (cta.type === 'custom') {
|
|
663
|
-
url = cta.link;
|
|
664
|
-
const data = dataItem || this.dashboard.layoutSettings.parameters;
|
|
665
|
-
url = this.bindParametersInString(url, data);
|
|
666
|
-
// Check if we have any column eg. [[ ]] values needing mapping
|
|
667
|
-
url = this.mapColumnToValue(url, data);
|
|
668
|
-
}
|
|
669
|
-
else if (cta.type === 'feed') {
|
|
670
|
-
url = `/dap-data-feeds/${cta.value}`;
|
|
671
|
-
}
|
|
672
|
-
if (url) {
|
|
673
|
-
if (!cta.windowLocation || cta.windowLocation === 'EXISTING') {
|
|
674
|
-
window.location.href = url;
|
|
675
|
-
}
|
|
676
|
-
else {
|
|
677
|
-
const a = document.createElement('a');
|
|
678
|
-
a.href = url;
|
|
679
|
-
a.setAttribute('target', '_blank');
|
|
680
|
-
a.setAttribute('rel', 'noopener noreferrer');
|
|
681
|
-
a.click();
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
}
|
|
685
|
-
bindParametersInString(searchString, data) {
|
|
686
|
-
if (!data) {
|
|
687
|
-
data = this.dashboard.layoutSettings.parameters;
|
|
688
|
-
}
|
|
689
|
-
if (searchString) {
|
|
690
|
-
const matches = searchString.match(/\{\{(.*?)\}\}/g) || [];
|
|
691
|
-
matches.forEach(exp => {
|
|
692
|
-
const expValue = exp.replace('{{', '').replace('}}', '');
|
|
693
|
-
const parameter = data ? data[expValue] : null;
|
|
694
|
-
if (parameter) {
|
|
695
|
-
const value = _.isPlainObject(parameter) ? parameter.value : parameter;
|
|
696
|
-
searchString = searchString.replace(exp, value);
|
|
697
|
-
}
|
|
698
|
-
});
|
|
699
|
-
}
|
|
700
|
-
return searchString;
|
|
701
|
-
}
|
|
702
|
-
increaseOffset() {
|
|
703
|
-
this.page = this.page + 1;
|
|
704
|
-
this.offset = (this.limit * this.page) - this.limit;
|
|
705
|
-
this.evaluate();
|
|
706
|
-
}
|
|
707
|
-
decreaseOffset() {
|
|
708
|
-
this.page = this.page <= 1 ? 1 : this.page - 1;
|
|
709
|
-
this.offset = (this.limit * this.page) - this.limit;
|
|
710
|
-
this.evaluate();
|
|
711
|
-
}
|
|
712
|
-
pageSizeChange(value) {
|
|
713
|
-
this.limit = value;
|
|
714
|
-
// If we change the table limit - we also want to save the dashboard automatically to keep the changes
|
|
715
|
-
this.tabular.limit = this.limit;
|
|
716
|
-
this.dashboardService.saveDashboard(this.dashboard);
|
|
717
|
-
this.evaluate(true);
|
|
718
|
-
}
|
|
719
|
-
sortHeader(columnObject) {
|
|
720
|
-
const column = columnObject.name;
|
|
721
|
-
let direction = '';
|
|
722
|
-
const existingMultiSort = _.find(this.dashboardDatasetInstance.transformationInstances, { type: 'multisort' });
|
|
723
|
-
let existingColumnIndex = -1;
|
|
724
|
-
if (existingMultiSort) {
|
|
725
|
-
existingColumnIndex = _.findIndex(existingMultiSort.config.sorts, { fieldName: column });
|
|
726
|
-
}
|
|
727
|
-
if (!existingMultiSort || existingColumnIndex === -1) {
|
|
728
|
-
direction = 'asc';
|
|
729
|
-
}
|
|
730
|
-
else if (existingColumnIndex >= 0 && existingMultiSort.config.sorts[existingColumnIndex].direction === 'asc') {
|
|
731
|
-
direction = 'desc';
|
|
732
|
-
}
|
|
733
|
-
else if (existingColumnIndex >= 0 && existingMultiSort.config.sorts[existingColumnIndex].direction === 'desc') {
|
|
734
|
-
direction = '';
|
|
735
|
-
}
|
|
736
|
-
else if (existingColumnIndex >= 0 && !existingMultiSort.config.sorts[existingColumnIndex].direction) {
|
|
737
|
-
direction = 'asc';
|
|
738
|
-
}
|
|
739
|
-
columnObject.direction = direction;
|
|
740
|
-
if (existingMultiSort) {
|
|
741
|
-
const existingIndex = _.findIndex(existingMultiSort.config.sorts, { fieldName: column });
|
|
742
|
-
if (direction) {
|
|
743
|
-
if (existingIndex > -1) {
|
|
744
|
-
existingMultiSort.config.sorts[existingIndex] = { fieldName: column, direction };
|
|
745
|
-
}
|
|
746
|
-
else {
|
|
747
|
-
existingMultiSort.config.sorts.push({ fieldName: column, direction });
|
|
748
|
-
}
|
|
749
|
-
}
|
|
750
|
-
else {
|
|
751
|
-
existingMultiSort.config.sorts.splice(existingIndex, 1);
|
|
752
|
-
if (!existingMultiSort.config.sorts.length) {
|
|
753
|
-
_.remove(this.dashboardDatasetInstance.transformationInstances, { type: 'multisort' });
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
else {
|
|
758
|
-
if (direction) {
|
|
759
|
-
this.dashboardDatasetInstance.transformationInstances.push({
|
|
760
|
-
type: 'multisort',
|
|
761
|
-
config: {
|
|
762
|
-
sorts: [{ fieldName: column, direction }]
|
|
763
|
-
}
|
|
764
|
-
});
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
this.evaluate(true);
|
|
768
|
-
}
|
|
769
|
-
changeDateType(event, parameter, value) {
|
|
770
|
-
event.stopPropagation();
|
|
771
|
-
event.preventDefault();
|
|
772
|
-
parameter._dateType = value;
|
|
773
|
-
this.reloadWidget();
|
|
774
|
-
}
|
|
775
|
-
updatePeriodValue(value, period, parameter) {
|
|
776
|
-
parameter.value = `${value}_${period}_AGO`;
|
|
777
|
-
this.reloadWidget();
|
|
778
|
-
}
|
|
779
|
-
booleanUpdate(event, parameter) {
|
|
780
|
-
parameter.value = event.checked;
|
|
781
|
-
this.reloadWidget();
|
|
782
|
-
}
|
|
783
|
-
reloadWidget() {
|
|
784
|
-
const parameterValues = {};
|
|
785
|
-
_.forEach(this.general.widgetParameters, param => {
|
|
786
|
-
parameterValues[param.name] = param.value;
|
|
787
|
-
});
|
|
788
|
-
this.evaluate();
|
|
789
|
-
}
|
|
790
|
-
mapColumnToValue(searchString, data) {
|
|
791
|
-
if (searchString) {
|
|
792
|
-
const matches = searchString.match(/\[\[(.*?)\]\]/g) || [];
|
|
793
|
-
matches.forEach(exp => {
|
|
794
|
-
const expValue = exp.replace('[[', '').replace(']]', '');
|
|
795
|
-
let value = data ? data[expValue] : null;
|
|
796
|
-
if (value) {
|
|
797
|
-
value = _.isPlainObject(value) ? value.initialValue : value;
|
|
798
|
-
searchString = searchString.replace(exp, value);
|
|
799
|
-
}
|
|
800
|
-
});
|
|
801
|
-
}
|
|
802
|
-
return searchString;
|
|
803
|
-
}
|
|
804
|
-
evaluate(resetPager) {
|
|
805
|
-
if (resetPager) {
|
|
806
|
-
this.resetPager();
|
|
807
|
-
}
|
|
808
|
-
const itemElement = document.getElementById(this.itemInstanceKey);
|
|
809
|
-
if (itemElement) {
|
|
810
|
-
const parentElement = itemElement.closest('.grid-stack-item');
|
|
811
|
-
parentElement.classList.remove('item-disabled');
|
|
812
|
-
}
|
|
813
|
-
if (this.grid && _.isFunction(this.grid.makeElement)) {
|
|
814
|
-
setTimeout(() => {
|
|
815
|
-
this.grid.makeElement(itemElement);
|
|
816
|
-
}, 0);
|
|
817
|
-
}
|
|
818
|
-
this.loadingItem = true;
|
|
819
|
-
this.hiddenColumns = {};
|
|
820
|
-
return this.evaluateDataset().then(data => {
|
|
821
|
-
if (Object.keys(this.tableCells).length) {
|
|
822
|
-
Object.keys(this.tableCells).forEach(tableCell => {
|
|
823
|
-
if (tableCell !== 'column') {
|
|
824
|
-
data.allData.map((item, index) => {
|
|
825
|
-
if (!_.isUndefined(item[tableCell])) {
|
|
826
|
-
const cellData = this.tableCells[tableCell].data;
|
|
827
|
-
switch (this.tableCells[tableCell].type) {
|
|
828
|
-
case 'number':
|
|
829
|
-
const cellNumber = parseFloat(String(item[tableCell]));
|
|
830
|
-
item[tableCell] = {
|
|
831
|
-
cellValue: cellNumber.toFixed(cellData.decimal),
|
|
832
|
-
initialValue: item[tableCell]
|
|
833
|
-
};
|
|
834
|
-
break;
|
|
835
|
-
case 'currency':
|
|
836
|
-
let cellCurrency = parseFloat(String(item[tableCell]));
|
|
837
|
-
if (cellData.thousandsSeparator && (cellData.currency && cellData.currency.value)) {
|
|
838
|
-
cellCurrency = cellCurrency.toLocaleString('en-GB', {
|
|
839
|
-
style: 'currency',
|
|
840
|
-
currency: cellData.currency.value,
|
|
841
|
-
minimumFractionDigits: cellData.decimal || 0
|
|
842
|
-
});
|
|
843
|
-
}
|
|
844
|
-
else {
|
|
845
|
-
cellCurrency = cellCurrency.toFixed(cellData.decimal);
|
|
846
|
-
if (cellData.thousandsSeparator) {
|
|
847
|
-
cellCurrency = Number(cellCurrency).toLocaleString('en-GB', {
|
|
848
|
-
minimumFractionDigits: cellData.decimal || 0
|
|
849
|
-
});
|
|
850
|
-
}
|
|
851
|
-
if (cellData.currency && cellData.currency.value) {
|
|
852
|
-
cellCurrency = `${cellData.currency.symbol}${cellCurrency}`;
|
|
853
|
-
}
|
|
854
|
-
}
|
|
855
|
-
item[tableCell] = { cellValue: cellCurrency, initialValue: item[tableCell] };
|
|
856
|
-
break;
|
|
857
|
-
case 'percentage':
|
|
858
|
-
let cellPercent = Number(item[tableCell]);
|
|
859
|
-
const formatter = new Intl.NumberFormat('en-GB', {
|
|
860
|
-
style: 'percent',
|
|
861
|
-
minimumFractionDigits: cellData.decimal || 0
|
|
862
|
-
});
|
|
863
|
-
cellPercent = formatter.format(cellPercent);
|
|
864
|
-
if (!cellData.thousandsSeparator) {
|
|
865
|
-
cellPercent = cellPercent.replace(',', '');
|
|
866
|
-
}
|
|
867
|
-
item[tableCell] = { cellValue: cellPercent, initialValue: item[tableCell] };
|
|
868
|
-
break;
|
|
869
|
-
case 'datetime':
|
|
870
|
-
const dateMoment = moment(item[tableCell]);
|
|
871
|
-
const dateFormat = cellData.dateFormat === 'null' ? '' : cellData.dateFormat;
|
|
872
|
-
const timeFormat = cellData.timeFormat === 'null' ? '' : cellData.timeFormat;
|
|
873
|
-
item[tableCell] = {
|
|
874
|
-
cellValue: dateMoment.format(dateFormat + ' ' + timeFormat),
|
|
875
|
-
initialValue: item[tableCell]
|
|
876
|
-
};
|
|
877
|
-
break;
|
|
878
|
-
case 'comparison':
|
|
879
|
-
const comparisonColumn = this.tableCells[tableCell].data.comparisonColumn;
|
|
880
|
-
const initialValue = _.isPlainObject(item[tableCell]) ? item[tableCell].initialValue : item[tableCell];
|
|
881
|
-
const comparisonValue = _.isPlainObject(data.allData[index][comparisonColumn]) ? data.allData[index][comparisonColumn].initialValue : data.allData[index][comparisonColumn];
|
|
882
|
-
let difference = Number(initialValue) - Number(comparisonValue);
|
|
883
|
-
let cellValue = `<div class="flex items-center space-between"><span class="font-medium">${initialValue}</span>`;
|
|
884
|
-
if (difference === 0) {
|
|
885
|
-
cellValue += `<span class="ml-1 text-blue-500 font-medium text-lg">=</span>`;
|
|
886
|
-
}
|
|
887
|
-
if (difference > 0) {
|
|
888
|
-
if (cellData.comparisonPercentage) {
|
|
889
|
-
const compareFormatter = new Intl.NumberFormat('en-GB', {
|
|
890
|
-
style: 'percent',
|
|
891
|
-
minimumFractionDigits: cellData.comparisonDecimals || 0
|
|
892
|
-
});
|
|
893
|
-
difference = compareFormatter.format(difference / comparisonValue);
|
|
894
|
-
}
|
|
895
|
-
cellValue += `<span class="ml-1 text-green-500 font-medium text-lg">↑</span><span class="text-sm text-green-500">${difference}</span>`;
|
|
896
|
-
}
|
|
897
|
-
if (difference < 0) {
|
|
898
|
-
if (cellData.comparisonPercentage) {
|
|
899
|
-
const compareFormatter = new Intl.NumberFormat('en-GB', {
|
|
900
|
-
style: 'percent',
|
|
901
|
-
minimumFractionDigits: cellData.comparisonDecimals || 0
|
|
902
|
-
});
|
|
903
|
-
difference = compareFormatter.format(difference / comparisonValue);
|
|
904
|
-
}
|
|
905
|
-
cellValue += `<span class="ml-1 text-red-500 font-medium text-lg">↓</span><span class="text-sm text-red-500">${difference}</span>`;
|
|
906
|
-
}
|
|
907
|
-
cellValue += `<span class="ml-2 text-xs text-gray-400">from ${comparisonValue}</span></div>`;
|
|
908
|
-
item[tableCell] = { cellValue, initialValue };
|
|
909
|
-
break;
|
|
910
|
-
case 'link':
|
|
911
|
-
let linkValue = cellData.customLink;
|
|
912
|
-
let anchor = '';
|
|
913
|
-
if (cellData.linkType === 'custom') {
|
|
914
|
-
const dataItem = data.allData[index] || this.dashboard.layoutSettings.parameters;
|
|
915
|
-
linkValue = this.bindParametersInString(linkValue, dataItem);
|
|
916
|
-
// Check if we have any column eg. [[ ]] values needing mapping
|
|
917
|
-
linkValue = this.mapColumnToValue(linkValue, dataItem);
|
|
918
|
-
anchor = `<a href="${linkValue}" target="_blank" class="text-cta hover:underline flex items-center">${item[tableCell]}</a>`;
|
|
919
|
-
}
|
|
920
|
-
else if (cellData.linkType === 'dashboard') {
|
|
921
|
-
const params = {};
|
|
922
|
-
const dashboardLink = cellData.dashboardLink;
|
|
923
|
-
const dataItem = data.allData[index] || this.dashboard.layoutSettings.parameters;
|
|
924
|
-
Object.keys(cellData.dashboardLinkParams).forEach(paramKey => {
|
|
925
|
-
let value = this.bindParametersInString(cellData.dashboardLinkParams[paramKey], dataItem);
|
|
926
|
-
// Check if we have any column eg. [[ ]] values needing mapping
|
|
927
|
-
value = this.mapColumnToValue(value, dataItem);
|
|
928
|
-
params[paramKey] = value;
|
|
929
|
-
});
|
|
930
|
-
const urlParams = new URLSearchParams(params).toString();
|
|
931
|
-
linkValue = `${this.router.url.split('/')[0]}/dashboards/view/${dashboardLink.value}${this.admin ? '?a=true&' : '?'}${urlParams}`;
|
|
932
|
-
anchor = `<a href="${linkValue}" class="text-cta hover:underline flex items-center">${item[tableCell]}</a>`;
|
|
933
|
-
}
|
|
934
|
-
else {
|
|
935
|
-
linkValue = linkValue.includes('http') ? linkValue : `http://${linkValue}`;
|
|
936
|
-
anchor = `<a href="${linkValue}" target="_blank" class="text-cta hover:underline flex items-center">${item[tableCell]}</a>`;
|
|
937
|
-
}
|
|
938
|
-
item[tableCell] = {
|
|
939
|
-
cellValue: anchor,
|
|
940
|
-
initialValue: linkValue
|
|
941
|
-
};
|
|
942
|
-
break;
|
|
943
|
-
case 'custom':
|
|
944
|
-
const element = document.createElement('div');
|
|
945
|
-
const originalValue = item[tableCell];
|
|
946
|
-
element.innerHTML = this.bindParametersInString(cellData.customText);
|
|
947
|
-
const kData = {
|
|
948
|
-
dataSet: data.allData
|
|
949
|
-
};
|
|
950
|
-
_.forEach(data.allData[index] || [], (value, key) => {
|
|
951
|
-
kData[key] = value;
|
|
952
|
-
});
|
|
953
|
-
const Kinibind = window.Kinibind;
|
|
954
|
-
Kinibind.config = {
|
|
955
|
-
prefix: 'd',
|
|
956
|
-
templateDelimiters: ['[[', ']]']
|
|
957
|
-
};
|
|
958
|
-
const bind = new Kinibind(element, kData);
|
|
959
|
-
const boundHTML = bind.boundContext.els[0].innerHTML;
|
|
960
|
-
item[tableCell] = {
|
|
961
|
-
cellValue: this.sanitizer.sanitize(1, boundHTML),
|
|
962
|
-
initialValue: originalValue
|
|
963
|
-
};
|
|
964
|
-
element.remove();
|
|
965
|
-
break;
|
|
966
|
-
case 'hide':
|
|
967
|
-
this.hiddenColumns[tableCell] = true;
|
|
968
|
-
break;
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
return item;
|
|
972
|
-
});
|
|
973
|
-
}
|
|
974
|
-
});
|
|
975
|
-
}
|
|
976
|
-
this.dataset = data;
|
|
977
|
-
const returnedDataLength = this.dataset.allData.length;
|
|
978
|
-
const existingMultiSort = _.find(this.dashboardDatasetInstance.transformationInstances, { type: 'multisort' });
|
|
979
|
-
if (existingMultiSort && existingMultiSort.config.sorts.length) {
|
|
980
|
-
existingMultiSort.config.sorts.forEach(sort => {
|
|
981
|
-
const column = _.find(this.dataset.columns, { name: sort.fieldName });
|
|
982
|
-
if (column) {
|
|
983
|
-
column.direction = sort.direction;
|
|
984
|
-
}
|
|
985
|
-
});
|
|
986
|
-
}
|
|
987
|
-
this.filterFields = _.map(this.dataset.columns, column => {
|
|
988
|
-
return {
|
|
989
|
-
title: column.title,
|
|
990
|
-
name: column.name
|
|
991
|
-
};
|
|
992
|
-
});
|
|
993
|
-
if (this.dashboard.layoutSettings.metric) {
|
|
994
|
-
this.updateMetricDataValues();
|
|
995
|
-
}
|
|
996
|
-
if (this.dashboard.layoutSettings.imageData) {
|
|
997
|
-
this.updateImageData();
|
|
998
|
-
}
|
|
999
|
-
if (Object.keys(this.textData).length) {
|
|
1000
|
-
this.textData.safeTextData = this.evaluateTextData(this.textData.value);
|
|
1001
|
-
}
|
|
1002
|
-
if (Object.keys(this.general).length) {
|
|
1003
|
-
this.general.evaluatedName = this.general.name ? this.evaluateTextData(this.general.name) : '';
|
|
1004
|
-
this.general.evaluatedDescription = this.general.description ? this.evaluateTextData(this.general.description) : '';
|
|
1005
|
-
this.general.evaluatedFooter = this.general.footer ? this.evaluateTextData(this.general.footer) : '';
|
|
1006
|
-
}
|
|
1007
|
-
setTimeout(() => {
|
|
1008
|
-
if (this.dashboardItemType.type === 'network') {
|
|
1009
|
-
this.setupNetworkChart();
|
|
1010
|
-
}
|
|
1011
|
-
const element = document.getElementById(this.itemInstanceKey);
|
|
1012
|
-
for (const child of Array.from(element ? element.children : [])) {
|
|
1013
|
-
if (child.classList.contains('item-container')) {
|
|
1014
|
-
this.wordCloud.width = child.clientWidth - 40;
|
|
1015
|
-
this.wordCloud.height = child.clientHeight - 40;
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
if (Object.keys(this.wordCloud).length) {
|
|
1019
|
-
if (this.wordCloud.populationMethod === 'SINGLE') {
|
|
1020
|
-
const rowData = this.dataset.allData[this.wordCloud.row];
|
|
1021
|
-
if (rowData) {
|
|
1022
|
-
const words = _.words(rowData[this.wordCloud.column]);
|
|
1023
|
-
const count = _.countBy(words, _.identity);
|
|
1024
|
-
const max = _.max(_.values(count));
|
|
1025
|
-
const fontSize = ((this.wordCloud.height) * (this.wordCloud.width)) / 1000;
|
|
1026
|
-
this.wordCloud.data = _.orderBy(_.uniq(words).map(word => {
|
|
1027
|
-
return { text: word, value: ((count[word] / max) * _.min([fontSize, 120])) };
|
|
1028
|
-
}), ['value'], ['desc']).slice(0, 100);
|
|
1029
|
-
}
|
|
1030
|
-
}
|
|
1031
|
-
else if (this.wordCloud.populationMethod === 'WHOLE') {
|
|
1032
|
-
const maxFreq = _.maxBy(this.dataset.allData, item => {
|
|
1033
|
-
return Number(item[this.wordCloud.frequency]);
|
|
1034
|
-
})[this.wordCloud.frequency];
|
|
1035
|
-
const maxWordWidth = _.max(_.map(this.dataset.allData, item => item[this.wordCloud.column].length * item[this.wordCloud.frequency] / maxFreq));
|
|
1036
|
-
const fontSize = ((this.wordCloud.height) * (this.wordCloud.width)) / 3000;
|
|
1037
|
-
this.wordCloud.data = _.orderBy(this.dataset.allData.map(item => {
|
|
1038
|
-
const text = item[this.wordCloud.column];
|
|
1039
|
-
const itemFrequency = item[this.wordCloud.frequency];
|
|
1040
|
-
return {
|
|
1041
|
-
text,
|
|
1042
|
-
value: ((8 / maxWordWidth) * (Number(itemFrequency) / Number(maxFreq)) * _.min([fontSize, 400]))
|
|
1043
|
-
};
|
|
1044
|
-
}), ['value'], ['desc']).slice(0, 100);
|
|
1045
|
-
}
|
|
1046
|
-
}
|
|
1047
|
-
}, 50);
|
|
1048
|
-
this.loadingItem = false;
|
|
1049
|
-
this.configureClass = false;
|
|
1050
|
-
this.setChartData();
|
|
1051
|
-
if (this.dashboard.alertsEnabled && !this.external) {
|
|
1052
|
-
if (this.dashboardDatasetInstance.alerts && this.dashboardDatasetInstance.alerts.length) {
|
|
1053
|
-
if (this.dashboard.layoutSettings.parameters && Object.keys(this.dashboard.layoutSettings.parameters).length) {
|
|
1054
|
-
if (Array.isArray(this.dashboardDatasetInstance.parameterValues)) {
|
|
1055
|
-
this.dashboardDatasetInstance.parameterValues = {};
|
|
1056
|
-
}
|
|
1057
|
-
_.forEach(this.dashboard.layoutSettings.parameters, parameter => {
|
|
1058
|
-
this.dashboardDatasetInstance.parameterValues[parameter.name] = parameter.value;
|
|
1059
|
-
});
|
|
1060
|
-
}
|
|
1061
|
-
const dashboardInstance = _.cloneDeep(this.dashboardDatasetInstance);
|
|
1062
|
-
dashboardInstance.parameterValues = this.getMappedParams(this.dashboardDatasetInstance);
|
|
1063
|
-
this.alertService.processAlertsForDashboardDatasetInstance(dashboardInstance)
|
|
1064
|
-
.then((res) => {
|
|
1065
|
-
if (res && res.length) {
|
|
1066
|
-
this.alert = true;
|
|
1067
|
-
this.alertData = res;
|
|
1068
|
-
if (itemElement) {
|
|
1069
|
-
itemElement.classList.add('alert');
|
|
1070
|
-
itemElement.parentElement.classList.add('alert');
|
|
1071
|
-
}
|
|
1072
|
-
}
|
|
1073
|
-
else {
|
|
1074
|
-
this.resetAlertData(itemElement);
|
|
1075
|
-
}
|
|
1076
|
-
});
|
|
1077
|
-
}
|
|
1078
|
-
else {
|
|
1079
|
-
this.resetAlertData(itemElement);
|
|
1080
|
-
}
|
|
1081
|
-
}
|
|
1082
|
-
else {
|
|
1083
|
-
this.resetAlertData(itemElement);
|
|
1084
|
-
}
|
|
1085
|
-
const existing = this.dashboardService.dashboardItems.getValue();
|
|
1086
|
-
existing[this.itemInstanceKey] = true;
|
|
1087
|
-
this.dashboardService.dashboardItems.next(existing);
|
|
1088
|
-
this.endOfResults = returnedDataLength < this.limit;
|
|
1089
|
-
return Promise.resolve(true);
|
|
1090
|
-
}).catch(err => {
|
|
1091
|
-
});
|
|
1092
|
-
}
|
|
1093
|
-
getMappedParams(dashboardDatasetInstance) {
|
|
1094
|
-
const mappedParams = {};
|
|
1095
|
-
_.forEach(dashboardDatasetInstance.parameterValues, (value, key) => {
|
|
1096
|
-
if (_.isString(value) && value.includes('{{')) {
|
|
1097
|
-
const globalKey = value.replace('{{', '').replace('}}', '');
|
|
1098
|
-
if (this.dashboard.layoutSettings.parameters && this.dashboard.layoutSettings.parameters[globalKey]) {
|
|
1099
|
-
mappedParams[key] = this.dashboard.layoutSettings.parameters[globalKey].value;
|
|
1100
|
-
}
|
|
1101
|
-
}
|
|
1102
|
-
else {
|
|
1103
|
-
mappedParams[key] = value;
|
|
1104
|
-
}
|
|
1105
|
-
});
|
|
1106
|
-
return mappedParams;
|
|
1107
|
-
}
|
|
1108
|
-
resetAlertData(itemElement) {
|
|
1109
|
-
this.alert = false;
|
|
1110
|
-
this.alertData = [];
|
|
1111
|
-
if (itemElement) {
|
|
1112
|
-
itemElement.classList.remove('alert');
|
|
1113
|
-
itemElement.parentElement.classList.remove('alert');
|
|
1114
|
-
}
|
|
1115
|
-
}
|
|
1116
|
-
resetPager() {
|
|
1117
|
-
this.offset = 0;
|
|
1118
|
-
this.page = 1;
|
|
1119
|
-
}
|
|
1120
|
-
mapLayoutSettingsToComponentData() {
|
|
1121
|
-
_.forEach(this.dashboard.layoutSettings, (data, key) => {
|
|
1122
|
-
if (key !== 'grid') {
|
|
1123
|
-
const defaultValue = _.isPlainObject(this[key]) ? {} : [];
|
|
1124
|
-
this[key] = Object.keys(data).length ? data[this.itemInstanceKey] || defaultValue : defaultValue;
|
|
1125
|
-
}
|
|
1126
|
-
});
|
|
1127
|
-
}
|
|
1128
|
-
reloadAlert(save = true) {
|
|
1129
|
-
const thisEl = document.getElementById(this.itemInstanceKey).closest('.grid-stack-item');
|
|
1130
|
-
const existingGrid = _.find(this.dashboard.layoutSettings.grid, grid => {
|
|
1131
|
-
return grid.content.includes(`id="${this.itemInstanceKey}"`);
|
|
1132
|
-
});
|
|
1133
|
-
if (thisEl && existingGrid) {
|
|
1134
|
-
this.grid.removeWidget(thisEl);
|
|
1135
|
-
this.grid.addWidget(existingGrid);
|
|
1136
|
-
}
|
|
1137
|
-
if (save) {
|
|
1138
|
-
this.dashboardService.saveDashboard(this.dashboard);
|
|
1139
|
-
}
|
|
1140
|
-
}
|
|
1141
|
-
evaluateDataset(limit, offset) {
|
|
1142
|
-
const datasetInstanceSummary = this.prepareDatasetInstanceSummaryForEvaluation();
|
|
1143
|
-
this.hiddenColumns = {};
|
|
1144
|
-
this.externalError = false;
|
|
1145
|
-
this.quotaExceeded = null;
|
|
1146
|
-
if (this.external) {
|
|
1147
|
-
return this.externalService.evaluateDataset(this.dashboard.id, this.itemInstanceKey, datasetInstanceSummary.parameterValues, String(offset || this.offset), String(limit || this.limit), this.queryParams).catch(e => {
|
|
1148
|
-
this.externalError = true;
|
|
1149
|
-
});
|
|
1150
|
-
}
|
|
1151
|
-
else {
|
|
1152
|
-
return this.datasetService.evaluateDataset(datasetInstanceSummary, String(offset || this.offset), String(limit || this.limit)).catch(e => {
|
|
1153
|
-
if (e && e.error && e.error.message && e.error.message.includes('quota')) {
|
|
1154
|
-
this.quotaExceeded = e.error.message;
|
|
1155
|
-
}
|
|
1156
|
-
else {
|
|
1157
|
-
this.externalError = true;
|
|
1158
|
-
}
|
|
1159
|
-
});
|
|
1160
|
-
}
|
|
1161
|
-
}
|
|
1162
|
-
prepareDatasetInstanceSummaryForEvaluation() {
|
|
1163
|
-
const mappedParams = this.getMappedParams(this.dashboardDatasetInstance);
|
|
1164
|
-
const datasetInstanceSummary = {
|
|
1165
|
-
datasetInstanceId: this.dashboardDatasetInstance.datasetInstanceId,
|
|
1166
|
-
datasourceInstanceKey: this.dashboardDatasetInstance.datasourceInstanceKey,
|
|
1167
|
-
transformationInstances: this.dashboardDatasetInstance.transformationInstances,
|
|
1168
|
-
parameterValues: mappedParams,
|
|
1169
|
-
parameters: this.dashboardDatasetInstance.parameters
|
|
1170
|
-
};
|
|
1171
|
-
if (this.dashboard.layoutSettings.parameters && Object.keys(this.dashboard.layoutSettings.parameters).length) {
|
|
1172
|
-
_.forEach(this.dashboard.layoutSettings.parameters, (param, name) => {
|
|
1173
|
-
let value = param.value;
|
|
1174
|
-
if (param.type === 'date' || param.type === 'datetime') {
|
|
1175
|
-
if (value && !value.includes('AGO')) {
|
|
1176
|
-
value = moment(value).format('YYYY-MM-DD HH:mm:ss');
|
|
1177
|
-
}
|
|
1178
|
-
}
|
|
1179
|
-
// Add in the widget specific parameter values if there are any
|
|
1180
|
-
if (this.general.widgetParameters && Object.keys(this.general.widgetParameters).length) {
|
|
1181
|
-
const widgetParam = _.find(this.general.widgetParameters, { name });
|
|
1182
|
-
if (widgetParam && widgetParam.value) {
|
|
1183
|
-
value = widgetParam.value;
|
|
1184
|
-
}
|
|
1185
|
-
}
|
|
1186
|
-
datasetInstanceSummary.parameterValues[name] = value;
|
|
1187
|
-
});
|
|
1188
|
-
}
|
|
1189
|
-
return datasetInstanceSummary;
|
|
1190
|
-
}
|
|
1191
|
-
}
|
|
1192
|
-
ItemComponentComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ItemComponentComponent, deps: [{ token: i1.MatLegacyDialog }, { token: i2.DatasourceService }, { token: i3.DatasetService }, { token: i4.AlertService }, { token: i5.DashboardService }, { token: i6.DomSanitizer }, { token: i7.Router }, { token: i8.Location }, { token: i9.ExternalService }, { token: i10.ProjectService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1193
|
-
ItemComponentComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: ItemComponentComponent, selector: "ki-item-component", inputs: { dashboardItemType: "dashboardItemType", itemInstanceKey: "itemInstanceKey", dashboard: "dashboard", dashboardItem: "dashboardItem", dragItem: "dragItem", grid: "grid", actionEvents: "actionEvents", external: "external", queryParams: "queryParams", editAlerts: "editAlerts" }, outputs: { duplicateItem: "duplicateItem" }, host: { properties: { "class.justify-center": "this.configureClass" } }, viewQueries: [{ propertyName: "textTemplate", first: true, predicate: ["textTemplate"], descendants: true }], ngImport: i0, template: "<div class=\"alert-panel\" *ngIf=\"showAlertData\" (click)=\"showAlertData = false\">\n <div class=\"align-center flex-col w-3/4 m-auto\">\n <mat-icon>notification_important</mat-icon>\n <h2 class=\"mb-0\">Alert Notification</h2>\n <p class=\"text-center\">The following alerts have been triggered based on the criteria set for this dashboard\n item...</p>\n <div class=\"alert-item mb-2\" *ngFor=\"let alertItem of alertData\"\n [innerHTML]=\"alertItem.notificationMessage\">\n </div>\n </div>\n</div>\n\n<div class=\"item-disabled\">\n <p>{{general.name || dashboardItemType.label}}</p>\n <mat-icon>block</mat-icon>\n <p class=\"disabled-notice\">{{dependencies.notice || 'No Data Available'}}</p>\n</div>\n\n<ng-template [ngIf]=\"dragItem\">\n <span class=\"material-symbols-outlined\">{{dashboardItemType.icon}}</span>\n <span [innerHTML]=\"dashboardItemType.label\"></span>\n</ng-template>\n<div class=\"alert-widget\" *ngIf=\"alert\" (click)=\"showAlertData = true;\">\n <button mat-icon-button>\n <mat-icon>notification_important</mat-icon>\n </button>\n <div class=\"alert-summaries\">\n <span class=\"mr-2\" *ngFor=\"let alertItem of alertData\">\n {{alertItem.summaryMessage}}\n </span>\n </div>\n</div>\n\n<ng-template\n [ngIf]=\"!dragItem && !dashboardDatasetInstance && !dashboardItemType.headingValue && !dashboardItemType._editing\">\n <button mat-stroked-button color=\"primary\" class=\"config-button\" (click)=\"configure()\">\n Configure {{dashboardItemType.label}}\n </button>\n</ng-template>\n\n<div class=\"absolute top-1 right-1 z-20\" *ngIf=\"!dragItem && loadingItem && (chartData || dataset)\">\n <svg class=\"animate-spin h-5 w-5 text-secondary\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle>\n <path class=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n</div>\n\n<ng-template [ngIf]=\"!viewOnly\">\n <div class=\"absolute top-1 left-1 z-20 cursor-pointer\" *ngIf=\"!dragItem && this.itemNoMove\"\n (click)=\"lockItem()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"\n class=\"h-5 w-5 text-gray-400\">\n <path fill-rule=\"evenodd\" d=\"M12 1.5a5.25 5.25 0 0 0-5.25 5.25v3a3 3 0 0 0-3 3v6.75a3 3 0 0 0 3 3h10.5a3 3 0 0 0 3-3v-6.75a3 3 0 0 0-3-3v-3c0-2.9-2.35-5.25-5.25-5.25Zm3.75 8.25v-3a3.75 3.75 0 1 0-7.5 0v3h7.5Z\" clip-rule=\"evenodd\" />\n </svg>\n </div>\n\n <div class=\"item-unlocked absolute top-1 left-1 z-20 cursor-pointer\" *ngIf=\"!dragItem && !this.itemNoMove\"\n (click)=\"lockItem()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"\n class=\"h-5 w-5 text-gray-400\">\n <path d=\"M18 1.5c2.9 0 5.25 2.35 5.25 5.25v3.75a.75.75 0 0 1-1.5 0V6.75a3.75 3.75 0 1 0-7.5 0v3a3 3 0 0 1 3 3v6.75a3 3 0 0 1-3 3H3.75a3 3 0 0 1-3-3v-6.75a3 3 0 0 1 3-3h9v-3c0-2.9 2.35-5.25 5.25-5.25Z\" />\n </svg>\n </div>\n</ng-template>\n\n\n<ng-template [ngIf]=\"!externalError && !quotaExceeded\">\n <div class=\"loading-item\" *ngIf=\"!dragItem && loadingItem && !(chartData || dataset)\">\n\n <div class=\"mx-auto flex h-14 w-14 flex-shrink-0 items-center justify-center rounded-full bg-gray-100 \">\n <svg class=\"animate-spin h-14 w-14 text-gray-400\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle>\n <path class=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n </div>\n <div class=\"px-4 text-center mt-4\">Loading {{dashboardItemType.label}} ...</div>\n </div>\n</ng-template>\n\n<ng-template [ngIf]=\"externalError\">\n <div class=\"loading-item\">\n <div class=\"mx-auto flex h-14 w-14 flex-shrink-0 items-center justify-center rounded-full bg-red-100 \">\n <svg class=\"h-10 w-10 text-red-600\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" aria-hidden=\"true\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z\" />\n </svg>\n </div>\n <div class=\"px-4 w-3/4 text-center mt-4\">There was a problem loading this item. Please try again later.</div>\n </div>\n</ng-template>\n\n<ng-template [ngIf]=\"quotaExceeded\">\n <div class=\"loading-item\">\n <div class=\"mx-auto flex h-14 w-14 flex-shrink-0 items-center justify-center rounded-full bg-blue-100 \">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\"\n class=\"h-10 w-10 text-blue-600\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z\" />\n </svg>\n </div>\n <div class=\"px-4 w-3/4 text-center mt-4\">{{quotaExceeded}}</div>\n </div>\n</ng-template>\n\n<ng-template [ngIf]=\"!itemLocked\">\n <button *ngIf=\"!dragItem\" mat-mini-fab class=\"edit-widget bg-white text-gray-500 bg-opacity-90\"\n [matMenuTriggerFor]=\"editMenu\">\n <mat-icon>more_horiz</mat-icon>\n </button>\n <mat-menu #editMenu=\"matMenu\">\n <ng-template [ngIf]=\"!viewOnly\">\n <button mat-menu-item (click)=\"configure()\">\n <mat-icon>edit</mat-icon>\n Edit Item\n </button>\n <button *ngIf=\"existingGridItem\" mat-menu-item (click)=\"duplicate()\">\n <mat-icon>copy_all</mat-icon>\n Duplicate Item\n </button>\n <button *ngIf=\"canExportData\" mat-menu-item (click)=\"exportData()\">\n <mat-icon>file_download</mat-icon>\n Export Data\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"removeWidget($event)\">\n <mat-icon class=\"text-red-600\">delete</mat-icon>\n Delete Item\n </button>\n </ng-template>\n <ng-template [ngIf]=\"viewOnly\">\n <button *ngIf=\"canExportData\" mat-menu-item (click)=\"exportData()\">\n <mat-icon>file_download</mat-icon>\n Export Data\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"editItemAlerts(null)\">\n <mat-icon color=\"primary\">add</mat-icon>\n <span>New Alert</span>\n </button>\n <ng-template [ngIf]=\"dashboardDatasetInstance\">\n <div mat-menu-item class=\"flex items-center justify-between p-0 \"\n [ngClass]=\"{'border border-t border-b-0 border-r-0 border-l-0 border-solid border-gray-200': i === 0}\"\n *ngFor=\"let alert of dashboardDatasetInstance.alerts; let i = index\">\n <div class=\"px-4 flex items-center\" (click)=\"editItemAlerts(alert, i)\">\n <mat-icon>edit</mat-icon>\n <span>{{alert.title}}</span>\n </div>\n <div class=\"flex items-center\">\n <div class=\"mx-2 divider\"></div>\n <button mat-icon-button (click)=\"removeAlert($event, alert, i)\">\n <mat-icon class=\"mx-2 text-red-600 m-0\">highlight_off</mat-icon>\n </button>\n </div>\n\n </div>\n </ng-template>\n </ng-template>\n </mat-menu>\n</ng-template>\n\n<ng-template [ngIf]=\"!dragItem && dashboardItemType.type === 'heading'\">\n\n <div class=\"item-heading\" *ngIf=\"!dashboardItemType._editing\">\n {{bindParametersInString(dashboardItemType.headingValue)}}\n </div>\n\n <input type=\"text\" *ngIf=\"dashboardItemType._editing\" [(ngModel)]=\"dashboardItemType.headingValue\"\n (blur)=\"updateHeading($event)\" class=\"w-11/12\">\n\n</ng-template>\n\n<ng-template [ngIf]=\"!dragItem && (chartData || dataset)\">\n\n <div class=\"item-title \" *ngIf=\"general.name\" [innerHTML]=\"general.evaluatedName\"\n [ngClass]=\"{'pb-4': !general.description, 'pb-2': general.description}\"></div>\n\n <div class=\"item-description text-sm\" *ngIf=\"general.description\"\n [innerHTML]=\"general.evaluatedDescription\"></div>\n\n <ng-template [ngIf]=\"general.widgetParameters && _.values(general.widgetParameters).length\">\n <div class=\"p-2 bg-gray-100 w-full flex flex-wrap\">\n <ng-template ngFor let-parameter [ngForOf]=\"_.values(general.widgetParameters)\" let-i=index>\n <label class=\"widget-parameter\">\n {{parameter.title}}\n <div class=\"parameter-input\">\n <ng-template [ngIf]=\"parameter.type === 'text'\">\n <input type=\"text\" placeholder=\"Enter {{parameter.title}}\" [(ngModel)]=\"parameter.value\"\n (keyup.enter)=\"reloadWidget()\" required autofocus>\n </ng-template>\n <ng-template [ngIf]=\"parameter.type === 'numeric'\">\n <input type=\"number\" placeholder=\"Enter {{parameter.title}}\" [(ngModel)]=\"parameter.value\"\n (keyup.enter)=\"reloadWidget()\" required autofocus>\n </ng-template>\n <ng-template [ngIf]=\"parameter.type === 'date' || parameter.type === 'datetime'\">\n <ng-template [ngIf]=\"!parameter._dateType\">\n <div class=\"flex items-center\">\n <button (click)=\"changeDateType($event, parameter, 'picker')\"\n class=\"hover:bg-gray-50 text-gray-800 border border-gray-300 py-0.5 pr-2 rounded mr-2 bg-white flex items-center\">\n <mat-icon class=\"text-base\">calendar_month</mat-icon>\n Date Picker\n </button>\n <button (click)=\"changeDateType($event, parameter, 'period')\"\n class=\"hover:bg-gray-50 text-gray-800 border border-gray-300 py-0.5 pr-2 rounded bg-white flex items-center\">\n <mat-icon class=\"text-base\">restore</mat-icon>\n Time Period\n </button>\n </div>\n </ng-template>\n <ng-template [ngIf]=\"parameter._dateType === 'picker'\">\n <input [type]=\"parameter.type === 'date' ? 'date' : 'datetime-local'\" placeholder=\"Enter {{parameter.title}}\" [(ngModel)]=\"parameter.value\"\n (keyup.enter)=\"reloadWidget()\" required autofocus>\n\n <a (click)=\"changeDateType($event, parameter, 'period')\"\n matTooltip=\"Time Period\"\n class=\"text-center ml-2 hover:bg-gray-50 text-gray-800 border border-gray-300 py-0.5 pr-0.5 rounded mr-2 bg-white flex items-center\">\n <mat-icon class=\"text-base\">restore</mat-icon>\n </a>\n </ng-template>\n <ng-template [ngIf]=\"parameter._dateType === 'period'\">\n <div class=\"flex items-center\">\n <input #periodValue type=\"number\" placeholder=\"No.\" required autofocus\n class=\"w-16 mr-2\" min=\"0\" [value]=\"parameter._periodValue || 1\"\n (change)=\"updatePeriodValue(periodValue.value, period.value, parameter)\">\n\n <select class=\"param-period-picker mr-2\" [value]=\"parameter._period || 'DAYS'\"\n #period (change)=\"updatePeriodValue(periodValue.value, period.value, parameter)\">\n <option value=\"DAYS\">Days</option>\n <option value=\"HOURS\">Hours</option>\n </select>\n\n <div>Ago</div>\n </div>\n\n <a (click)=\"changeDateType($event, parameter, 'picker')\"\n matTooltip=\"Date Picker\"\n class=\"text-center ml-2 hover:bg-gray-50 text-gray-800 border border-gray-300 py-0.5 pr-0.5 rounded mr-2 bg-white flex items-center\">\n <mat-icon class=\"text-base\">calendar_month</mat-icon>\n </a>\n </ng-template>\n\n </ng-template>\n <ng-template [ngIf]=\"parameter.type === 'boolean'\">\n <mat-slide-toggle class=\"pr-4\" color=\"primary\"\n [checked]=\"parameter.value\" (change)=\"booleanUpdate($event, parameter)\"\n required></mat-slide-toggle>\n </ng-template>\n </div>\n </label>\n </ng-template>\n </div>\n </ng-template>\n\n <div class=\"item-container\" [ngClass]=\"{'flex justify-center': dashboardItemType.type === 'image',\n 'p-px': (dashboardItemType.type === 'table' || general.transparent), 'overflow-hidden': !!chartData,\n 'flex items-center': dashboardItemType.type === 'metric', 'cursor-pointer': (actionItem && Object.keys(actionItem).length)}\"\n (click)=\"(actionItem && Object.keys(actionItem).length) ? callToActionLink(actionItem): null\">\n\n <ng-template [ngIf]=\"dashboardItemType.type === 'text' && textData.value\">\n <div class=\"h-full\" *ngIf=\"textData.safeTextData\" [innerHTML]=\"textData.safeTextData\"></div>\n </ng-template>\n\n <ng-template [ngIf]=\"dashboardItemType.type === 'metric'\">\n <div class=\"w-full\">\n <dt class=\"text-base font-normal text-gray-900\">{{metric.title}}</dt>\n <dd class=\"mt-1 flex items-baseline justify-between md:block lg:flex\">\n <div class=\"flex items-baseline text-2xl font-semibold text-indigo-600\">\n {{metric.mainValue}}\n <span *ngIf=\"metric.subMetric\"\n class=\"ml-2 text-sm font-medium text-gray-500\">from {{metric.subValue}}\n <span class=\"text-xs\">({{metric.subTitle}})</span></span>\n </div>\n\n <div *ngIf=\"metric.showSubChange\"\n class=\"inline-flex items-baseline px-2.5 py-0.5 rounded-full text-sm font-medium md:mt-2 lg:mt-0\"\n [ngClass]=\"{'bg-green-100 text-green-800': metric.mainValue >= metric.subValue, 'bg-red-100 text-red-800': metric.mainValue < metric.subValue}\">\n <!-- Heroicon name: mini/arrow-up -->\n <svg *ngIf=\"metric.mainValue >= metric.subValue\"\n class=\"-ml-1 mr-0.5 h-5 w-5 flex-shrink-0 self-center text-green-500\"\n xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\"\n aria-hidden=\"true\">\n <path fill-rule=\"evenodd\"\n d=\"M10 17a.75.75 0 01-.75-.75V5.612L5.29 9.77a.75.75 0 01-1.08-1.04l5.25-5.5a.75.75 0 011.08 0l5.25 5.5a.75.75 0 11-1.08 1.04l-3.96-4.158V16.25A.75.75 0 0110 17z\"\n clip-rule=\"evenodd\"/>\n </svg>\n <svg *ngIf=\"metric.mainValue < metric.subValue \" xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\" fill=\"currentColor\"\n class=\"-ml-1 mr-0.5 h-5 w-5 flex-shrink-0 self-center text-red-500\">\n <path fill-rule=\"evenodd\"\n d=\"M10 3a.75.75 0 01.75.75v10.638l3.96-4.158a.75.75 0 111.08 1.04l-5.25 5.5a.75.75 0 01-1.08 0l-5.25-5.5a.75.75 0 111.08-1.04l3.96 4.158V3.75A.75.75 0 0110 3z\"\n clip-rule=\"evenodd\"/>\n </svg>\n {{metric.difference}}\n </div>\n </dd>\n </div>\n </ng-template>\n\n <ng-template [ngIf]=\"dashboardItemType.type === 'network'\">\n <div class=\"w-full h-full\" [id]=\"itemInstanceKey + 'VIS'\"></div>\n </ng-template>\n\n <ng-template [ngIf]=\"dashboardItemType.type === 'image'\">\n <div *ngIf=\"imageData.source\" class=\"w-auto h-full\">\n <img [src]=\"imageData.source\" alt=\"\"\n (error)=\"imageError = true\">\n </div>\n\n <div *ngIf=\"!imageData.source || imageError\" class=\"h-full relative flex items-center justify-center\">\n <p class=\"z-10 text-lg\">No image</p>\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"filter blur-sm absolute w-auto h-full text-gray-300\"\n fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"/>\n </svg>\n </div>\n </ng-template>\n\n <ng-template [ngIf]=\"dashboardItemType.type === 'pie' || dashboardItemType.type === 'doughnut'\">\n <canvas baseChart *ngIf=\"chartData\" style=\"height: 200px\"\n [datasets]=\"chartData\"\n [labels]=\"dashboardItemType.labels\"\n [options]=\"{tooltips: { titleFontSize: 0 }, responsive:true, maintainAspectRatio: false}\"\n [legend]=\"!!dashboardItemType.legend\"\n [type]=\"dashboardItemType.type\"\n [plugins]=\"[]\">\n </canvas>\n </ng-template>\n\n <ng-template [ngIf]=\"dashboardItemType.type === 'line' || dashboardItemType.type === 'bar' || dashboardItemType.type === 'scatter'\">\n <canvas baseChart *ngIf=\"chartData\" style=\"height: 200px\"\n [datasets]=\"chartData\"\n [labels]=\"dashboardItemType.labels\"\n [options]=\"{tooltips: { titleFontSize: 0 }, scales: {y: {beginAtZero: dashboardItemType.beginAtZero, max: dashboardItemType.maxValue || null}}, responsive:true, maintainAspectRatio: false}\"\n [legend]=\"!!dashboardItemType.legend\"\n [type]=\"dashboardItemType.type\"\n [plugins]=\"[]\">\n </canvas>\n </ng-template>\n\n <ng-template [ngIf]=\"dashboardItemType.type === 'table'\">\n\n <table class=\"min-w-full border-separate\" style=\"border-spacing: 0\">\n <thead class=\"bg-gray-50 \">\n <tr>\n <ng-template ngFor let-column [ngForOf]=\"dataset.columns\">\n <th scope=\"col\" *ngIf=\"!hiddenColumns[column.name]\" (click)=\"sortHeader(column)\"\n class=\"cursor-pointer sticky -top-px z-10 border-b border-gray-300 bg-gray-50 bg-opacity-75 p-3 text-left text-xs font-semibold text-gray-900 backdrop-blur backdrop-filter\">\n <div *ngIf=\"!tableCells[column.name] || tableCells[column.name].type !== 'action'\"\n class=\"flex items-center \">\n {{column.title}}\n <svg *ngIf=\"column.direction === 'asc'\"\n xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\"\n stroke=\"currentColor\" class=\"stroke-3 text-secondary ml-1 w-4 h-4\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\n d=\"M4.5 10.5L12 3m0 0l7.5 7.5M12 3v18\"/>\n </svg>\n <svg *ngIf=\"column.direction === 'desc'\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\"\n viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\"\n class=\"stroke-3 text-secondary ml-1 w-4 h-4\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\n d=\"M19.5 13.5L12 21m0 0l-7.5-7.5M12 21V3\"/>\n </svg>\n </div>\n </th>\n </ng-template>\n </tr>\n </thead>\n <tbody class=\"bg-white \">\n <tr *ngFor=\"let dataItem of optimise ? dataset.allData.slice(0,10) : dataset.allData\"\n [ngClass]=\"{'hover:bg-gray-50 cursor-pointer ': (tabular.actionRows && tabular.cta)}\"\n (click)=\"(tabular.actionRows && tabular.cta) ? callToActionLink(tabular.cta, dataItem) : null\">\n <ng-template ngFor let-column [ngForOf]=\"dataset.columns\" let-i=index>\n <td *ngIf=\"!hiddenColumns[column.name]\"\n [title]=\"(tableCells[column.name] && tableCells[column.name].maxWidth) ? dataItem[column.name] : ''\"\n class=\"border-b border-gray-200 px-3 py-2 text-sm text-gray-500 relative\"\n [ngClass]=\"{'whitespace-nowrap': !tabular.expandRows, 'font-medium text-gray-900': i === 0}\"\n [ngStyle]=\"{'width': '', 'max-width': (tableCells[column.name] && tableCells[column.name].maxWidth) ? tableCells[column.name].maxWidth + 'px' : null, 'overflow': (tableCells[column.name] && tableCells[column.name].maxWidth) ? 'hidden' : null, 'text-overflow': (tableCells[column.name] && tableCells[column.name].maxWidth) ? 'ellipsis' : null}\">\n <ng-template [ngIf]=\"tableCells[column.name] && tableCells[column.name].type === 'action'\">\n <button type=\"button\" *ngIf=\"tableCells[column.name].data.actionEvent\"\n [ngClass]=\"{'bg-orange-50 border-orange-200 hover:bg-orange-100': isActionComplete(tableCells[column.name].data.actionEvent, dataItem[column.name])}\"\n (click)=\"triggerActionEvent(tableCells[column.name].data.actionEvent, column, dataItem[column.name])\"\n class=\"text-gray-600 inline-flex items-center rounded border border-primary bg-gray-50 px-2.5 py-1.5 text-xs font-medium hover:bg-gray-100\">\n {{getActionEventTitle(tableCells[column.name].data.actionEvent, column, dataItem[column.name])}}\n </button>\n </ng-template>\n\n <ng-template [ngIf]=\"!tableCells[column.name] || tableCells[column.name].type !== 'action'\">\n\n\n <ng-template [ngIf]=\"tabular.expandRows\">\n <div *ngIf=\"!_.isPlainObject(dataItem[column.name])\"\n [innerHTML]=\"dataItem[column.name]\"></div>\n <div *ngIf=\"_.isPlainObject(dataItem[column.name])\"\n [innerHTML]=\"dataItem[column.name].cellValue\"></div>\n </ng-template>\n <ng-template [ngIf]=\"!tabular.expandRows && _.isPlainObject(dataItem[column.name])\">\n <div [innerHTML]=\"dataItem[column.name].cellValue\"\n [ngStyle]=\"{'max-width': (tableCells[column.name] && tableCells[column.name].maxWidth) ? tableCells[column.name].maxWidth + 'px' : null, 'overflow': (tableCells[column.name] && tableCells[column.name].maxWidth) ? 'hidden' : null, 'text-overflow': (tableCells[column.name] && tableCells[column.name].maxWidth) ? 'ellipsis' : null}\"></div>\n </ng-template>\n <ng-template [ngIf]=\"!tabular.expandRows && !_.isPlainObject(dataItem[column.name])\">\n <ng-template\n [ngIf]=\"dataItem[column.name] && String(dataItem[column.name]).length <= 100\">\n {{dataItem[column.name]}}\n </ng-template>\n <ng-template\n [ngIf]=\"dataItem[column.name] && String(dataItem[column.name]).length > 100\">\n <div\n [ngStyle]=\"{'max-width': (tableCells[column.name] && tableCells[column.name].maxWidth) ? tableCells[column.name].maxWidth + 'px' : null, 'overflow': (tableCells[column.name] && tableCells[column.name].maxWidth) ? 'hidden' : null, 'text-overflow': (tableCells[column.name] && tableCells[column.name].maxWidth) ? 'ellipsis' : null}\"\n [title]=\"dataItem[column.name]\">{{dataItem[column.name].substring(0, 100) + '...'}}</div>\n </ng-template>\n <ng-template [ngIf]=\"!dataItem[column.name]\">\n {{dataItem[column.name]}}\n </ng-template>\n </ng-template>\n </ng-template>\n </td>\n </ng-template>\n\n </tr>\n <tr *ngIf=\"optimise && dataset.allData.length > 10\">\n <td class=\"pl-3 text-gray-900 font-medium bg-gray-200\" [colSpan]=\"dataset.columns.length\">\n Results limited during editing for enhanced performance.\n </td>\n </tr>\n </tbody>\n </table>\n\n <div *ngIf=\"!dataset.allData.length\"\n class=\"no-table-records text-sm text-gray-500 flex m-0 justify-center items-center\">\n No records to show\n </div>\n </ng-template>\n\n <ng-template [ngIf]=\"dashboardItemType.type === 'words'\">\n <angular-d3-cloud *ngIf=\"wordCloud.data\"\n [data]=\"wordCloud.data\"\n [width]=\"wordCloud.width\"\n [height]=\"wordCloud.height\"\n [padding]=\"5\"\n font=\"serif\"\n [rotate]=\"0\"\n [autoFill]=\"true\"\n ></angular-d3-cloud>\n </ng-template>\n\n </div>\n\n <div *ngIf=\"!optimise && dashboardItemType.type === 'table' && !tabular.hidePager\"\n class=\"table-pager flex items-center justify-between px-2 border-t border-gray-200 h-12 bg-gray-50 w-full\">\n <div class=\"text-xs text-gray-400\">\n Showing {{offset + 1}} - {{(page * limit) - (limit - dataset.allData.length)}}</div>\n <div class=\"flex items-center justify-center\">\n <button mat-icon-button (click)=\"decreaseOffset()\" [disabled]=\"page <= 1\">\n <mat-icon>chevron_left</mat-icon>\n </button>\n <select [value]=\"limit\" (change)=\"pageSizeChange($event.target.value)\"\n class=\"p-1 mx-2\">\n <option [value]=\"1\">1</option>\n <option [value]=\"5\">5</option>\n <option [value]=\"10\">10</option>\n <option [value]=\"25\">25</option>\n <option [value]=\"50\">50</option>\n <option [value]=\"100\">100</option>\n <option [value]=\"250\">250</option>\n <option [value]=\"1000\">1000</option>\n </select>\n <button mat-icon-button (click)=\"increaseOffset()\" [disabled]=\"endOfResults\">\n <mat-icon>chevron_right</mat-icon>\n </button>\n </div>\n </div>\n\n <div class=\"footer w-full bg-gray-50 px-2 py-1 text-gray-600 border-b border-gray-200 text-xs\"\n [ngClass]=\"{'border-b': callToAction && Object.keys(callToAction).length}\"\n *ngIf=\"general.footer\" [innerHTML]=\"general.evaluatedFooter\"></div>\n\n <div class=\"call-to-action w-full bg-gray-50 px-5 py-3\" *ngIf=\"callToAction && Object.keys(callToAction).length\">\n <div class=\"text-sm\">\n <a class=\"font-medium text-cta flex items-center\"\n (click)=\"callToActionLink(callToAction)\">\n {{callToAction.label}}\n <mat-icon>chevron_right</mat-icon>\n </a>\n </div>\n </div>\n\n</ng-template>\n", styles: [":host:hover .edit-widget,:host:hover .item-unlocked{display:block}.alert-panel{position:absolute;background-color:#fffffff2;inset:0;z-index:99999;display:flex;align-items:center;flex-direction:column}.alert-panel .alert-item{font-weight:500}.alert-panel mat-icon{color:#c41717;font-size:3rem;width:3rem;height:3rem}.no-table-records{height:calc(100% - 41px)}.divider{width:1px;height:17px;background-color:#cecece}.loading-item{display:flex;align-items:center;justify-content:center;flex-direction:column}.loading-item p{margin:1rem 0}.item-title{width:100%;color:gray;padding:1rem 1rem 0;font-size:1rem;font-weight:300}.item-description{width:100%;padding:0 1rem 1rem;font-size:1.1rem;font-weight:500}.item-heading{font-size:1.2rem;display:flex;align-items:center;justify-content:center;width:100%;height:100%}.item-container{padding:1rem;box-sizing:border-box;position:relative;width:100%;height:100%;overflow:auto}.item-container::-webkit-scrollbar{width:.75em;height:.75em;background:transparent}.item-container::-webkit-scrollbar-thumb{background:#d2d2d2}.edit-widget,.item-unlocked{display:none}table{width:100%;border-collapse:collapse}table thead tr th{text-transform:uppercase;text-align:left;border-bottom:1px solid #dbdbdb;padding:0 1rem 1rem 0;color:#5f6368;letter-spacing:1px;white-space:nowrap;font-weight:400;font-size:12px}table tbody tr td{padding:.5rem 1rem .5rem 0;border-bottom:1px solid #ececec;font-size:13px}label.widget-parameter{flex-direction:row;align-items:center;margin-left:1rem}label.widget-parameter .parameter-input{border-radius:4px;padding-left:.5rem;height:36px;display:flex;align-items:center}label.widget-parameter .parameter-input .param-period-picker{padding:5px}label.widget-parameter .parameter-input button{color:#8e8e8e}label.widget-parameter .parameter-input button.edit-parameter{visibility:hidden}label.widget-parameter .parameter-input button.mat-icon-button{width:30px;height:30px;line-height:30px;align-self:center}label.widget-parameter .parameter-input button.mat-icon-button mat-icon{font-size:20px;width:20px;height:20px;line-height:20px}label.widget-parameter .parameter-input input{font-size:.9rem;padding:.25rem .45rem;width:175px}label.widget-parameter .parameter-input:hover .edit-parameter{visibility:visible}\n"], dependencies: [{ kind: "directive", type: i8.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i8.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i8.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i11.MatLegacyButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i12.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i13.BaseChartDirective, selector: "canvas[baseChart]", inputs: ["type", "legend", "data", "options", "plugins", "labels", "datasets"], outputs: ["chartClick", "chartHover"], exportAs: ["base-chart"] }, { kind: "component", type: i14.MatLegacyMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i14.MatLegacyMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i14.MatLegacyMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "directive", type: i15.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i15.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i15.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i15.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i15.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i15.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i15.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i16.MatLegacySlideToggle, selector: "mat-slide-toggle", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matSlideToggle"] }, { kind: "component", type: i17.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i18.MatLegacyTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i19.AngularD3CloudComponent, selector: "angular-d3-cloud", inputs: ["data", "width", "height", "padding", "font", "fontSizeMapper", "rotate", "autoFill", "animations", "fillMapper"], outputs: ["wordClick", "wordMouseOver", "wordMouseOut"] }] });
|
|
1194
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ItemComponentComponent, decorators: [{
|
|
1195
|
-
type: Component,
|
|
1196
|
-
args: [{ selector: 'ki-item-component', template: "<div class=\"alert-panel\" *ngIf=\"showAlertData\" (click)=\"showAlertData = false\">\n <div class=\"align-center flex-col w-3/4 m-auto\">\n <mat-icon>notification_important</mat-icon>\n <h2 class=\"mb-0\">Alert Notification</h2>\n <p class=\"text-center\">The following alerts have been triggered based on the criteria set for this dashboard\n item...</p>\n <div class=\"alert-item mb-2\" *ngFor=\"let alertItem of alertData\"\n [innerHTML]=\"alertItem.notificationMessage\">\n </div>\n </div>\n</div>\n\n<div class=\"item-disabled\">\n <p>{{general.name || dashboardItemType.label}}</p>\n <mat-icon>block</mat-icon>\n <p class=\"disabled-notice\">{{dependencies.notice || 'No Data Available'}}</p>\n</div>\n\n<ng-template [ngIf]=\"dragItem\">\n <span class=\"material-symbols-outlined\">{{dashboardItemType.icon}}</span>\n <span [innerHTML]=\"dashboardItemType.label\"></span>\n</ng-template>\n<div class=\"alert-widget\" *ngIf=\"alert\" (click)=\"showAlertData = true;\">\n <button mat-icon-button>\n <mat-icon>notification_important</mat-icon>\n </button>\n <div class=\"alert-summaries\">\n <span class=\"mr-2\" *ngFor=\"let alertItem of alertData\">\n {{alertItem.summaryMessage}}\n </span>\n </div>\n</div>\n\n<ng-template\n [ngIf]=\"!dragItem && !dashboardDatasetInstance && !dashboardItemType.headingValue && !dashboardItemType._editing\">\n <button mat-stroked-button color=\"primary\" class=\"config-button\" (click)=\"configure()\">\n Configure {{dashboardItemType.label}}\n </button>\n</ng-template>\n\n<div class=\"absolute top-1 right-1 z-20\" *ngIf=\"!dragItem && loadingItem && (chartData || dataset)\">\n <svg class=\"animate-spin h-5 w-5 text-secondary\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle>\n <path class=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n</div>\n\n<ng-template [ngIf]=\"!viewOnly\">\n <div class=\"absolute top-1 left-1 z-20 cursor-pointer\" *ngIf=\"!dragItem && this.itemNoMove\"\n (click)=\"lockItem()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"\n class=\"h-5 w-5 text-gray-400\">\n <path fill-rule=\"evenodd\" d=\"M12 1.5a5.25 5.25 0 0 0-5.25 5.25v3a3 3 0 0 0-3 3v6.75a3 3 0 0 0 3 3h10.5a3 3 0 0 0 3-3v-6.75a3 3 0 0 0-3-3v-3c0-2.9-2.35-5.25-5.25-5.25Zm3.75 8.25v-3a3.75 3.75 0 1 0-7.5 0v3h7.5Z\" clip-rule=\"evenodd\" />\n </svg>\n </div>\n\n <div class=\"item-unlocked absolute top-1 left-1 z-20 cursor-pointer\" *ngIf=\"!dragItem && !this.itemNoMove\"\n (click)=\"lockItem()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"\n class=\"h-5 w-5 text-gray-400\">\n <path d=\"M18 1.5c2.9 0 5.25 2.35 5.25 5.25v3.75a.75.75 0 0 1-1.5 0V6.75a3.75 3.75 0 1 0-7.5 0v3a3 3 0 0 1 3 3v6.75a3 3 0 0 1-3 3H3.75a3 3 0 0 1-3-3v-6.75a3 3 0 0 1 3-3h9v-3c0-2.9 2.35-5.25 5.25-5.25Z\" />\n </svg>\n </div>\n</ng-template>\n\n\n<ng-template [ngIf]=\"!externalError && !quotaExceeded\">\n <div class=\"loading-item\" *ngIf=\"!dragItem && loadingItem && !(chartData || dataset)\">\n\n <div class=\"mx-auto flex h-14 w-14 flex-shrink-0 items-center justify-center rounded-full bg-gray-100 \">\n <svg class=\"animate-spin h-14 w-14 text-gray-400\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle>\n <path class=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n </div>\n <div class=\"px-4 text-center mt-4\">Loading {{dashboardItemType.label}} ...</div>\n </div>\n</ng-template>\n\n<ng-template [ngIf]=\"externalError\">\n <div class=\"loading-item\">\n <div class=\"mx-auto flex h-14 w-14 flex-shrink-0 items-center justify-center rounded-full bg-red-100 \">\n <svg class=\"h-10 w-10 text-red-600\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" aria-hidden=\"true\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z\" />\n </svg>\n </div>\n <div class=\"px-4 w-3/4 text-center mt-4\">There was a problem loading this item. Please try again later.</div>\n </div>\n</ng-template>\n\n<ng-template [ngIf]=\"quotaExceeded\">\n <div class=\"loading-item\">\n <div class=\"mx-auto flex h-14 w-14 flex-shrink-0 items-center justify-center rounded-full bg-blue-100 \">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\"\n class=\"h-10 w-10 text-blue-600\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z\" />\n </svg>\n </div>\n <div class=\"px-4 w-3/4 text-center mt-4\">{{quotaExceeded}}</div>\n </div>\n</ng-template>\n\n<ng-template [ngIf]=\"!itemLocked\">\n <button *ngIf=\"!dragItem\" mat-mini-fab class=\"edit-widget bg-white text-gray-500 bg-opacity-90\"\n [matMenuTriggerFor]=\"editMenu\">\n <mat-icon>more_horiz</mat-icon>\n </button>\n <mat-menu #editMenu=\"matMenu\">\n <ng-template [ngIf]=\"!viewOnly\">\n <button mat-menu-item (click)=\"configure()\">\n <mat-icon>edit</mat-icon>\n Edit Item\n </button>\n <button *ngIf=\"existingGridItem\" mat-menu-item (click)=\"duplicate()\">\n <mat-icon>copy_all</mat-icon>\n Duplicate Item\n </button>\n <button *ngIf=\"canExportData\" mat-menu-item (click)=\"exportData()\">\n <mat-icon>file_download</mat-icon>\n Export Data\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"removeWidget($event)\">\n <mat-icon class=\"text-red-600\">delete</mat-icon>\n Delete Item\n </button>\n </ng-template>\n <ng-template [ngIf]=\"viewOnly\">\n <button *ngIf=\"canExportData\" mat-menu-item (click)=\"exportData()\">\n <mat-icon>file_download</mat-icon>\n Export Data\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"editItemAlerts(null)\">\n <mat-icon color=\"primary\">add</mat-icon>\n <span>New Alert</span>\n </button>\n <ng-template [ngIf]=\"dashboardDatasetInstance\">\n <div mat-menu-item class=\"flex items-center justify-between p-0 \"\n [ngClass]=\"{'border border-t border-b-0 border-r-0 border-l-0 border-solid border-gray-200': i === 0}\"\n *ngFor=\"let alert of dashboardDatasetInstance.alerts; let i = index\">\n <div class=\"px-4 flex items-center\" (click)=\"editItemAlerts(alert, i)\">\n <mat-icon>edit</mat-icon>\n <span>{{alert.title}}</span>\n </div>\n <div class=\"flex items-center\">\n <div class=\"mx-2 divider\"></div>\n <button mat-icon-button (click)=\"removeAlert($event, alert, i)\">\n <mat-icon class=\"mx-2 text-red-600 m-0\">highlight_off</mat-icon>\n </button>\n </div>\n\n </div>\n </ng-template>\n </ng-template>\n </mat-menu>\n</ng-template>\n\n<ng-template [ngIf]=\"!dragItem && dashboardItemType.type === 'heading'\">\n\n <div class=\"item-heading\" *ngIf=\"!dashboardItemType._editing\">\n {{bindParametersInString(dashboardItemType.headingValue)}}\n </div>\n\n <input type=\"text\" *ngIf=\"dashboardItemType._editing\" [(ngModel)]=\"dashboardItemType.headingValue\"\n (blur)=\"updateHeading($event)\" class=\"w-11/12\">\n\n</ng-template>\n\n<ng-template [ngIf]=\"!dragItem && (chartData || dataset)\">\n\n <div class=\"item-title \" *ngIf=\"general.name\" [innerHTML]=\"general.evaluatedName\"\n [ngClass]=\"{'pb-4': !general.description, 'pb-2': general.description}\"></div>\n\n <div class=\"item-description text-sm\" *ngIf=\"general.description\"\n [innerHTML]=\"general.evaluatedDescription\"></div>\n\n <ng-template [ngIf]=\"general.widgetParameters && _.values(general.widgetParameters).length\">\n <div class=\"p-2 bg-gray-100 w-full flex flex-wrap\">\n <ng-template ngFor let-parameter [ngForOf]=\"_.values(general.widgetParameters)\" let-i=index>\n <label class=\"widget-parameter\">\n {{parameter.title}}\n <div class=\"parameter-input\">\n <ng-template [ngIf]=\"parameter.type === 'text'\">\n <input type=\"text\" placeholder=\"Enter {{parameter.title}}\" [(ngModel)]=\"parameter.value\"\n (keyup.enter)=\"reloadWidget()\" required autofocus>\n </ng-template>\n <ng-template [ngIf]=\"parameter.type === 'numeric'\">\n <input type=\"number\" placeholder=\"Enter {{parameter.title}}\" [(ngModel)]=\"parameter.value\"\n (keyup.enter)=\"reloadWidget()\" required autofocus>\n </ng-template>\n <ng-template [ngIf]=\"parameter.type === 'date' || parameter.type === 'datetime'\">\n <ng-template [ngIf]=\"!parameter._dateType\">\n <div class=\"flex items-center\">\n <button (click)=\"changeDateType($event, parameter, 'picker')\"\n class=\"hover:bg-gray-50 text-gray-800 border border-gray-300 py-0.5 pr-2 rounded mr-2 bg-white flex items-center\">\n <mat-icon class=\"text-base\">calendar_month</mat-icon>\n Date Picker\n </button>\n <button (click)=\"changeDateType($event, parameter, 'period')\"\n class=\"hover:bg-gray-50 text-gray-800 border border-gray-300 py-0.5 pr-2 rounded bg-white flex items-center\">\n <mat-icon class=\"text-base\">restore</mat-icon>\n Time Period\n </button>\n </div>\n </ng-template>\n <ng-template [ngIf]=\"parameter._dateType === 'picker'\">\n <input [type]=\"parameter.type === 'date' ? 'date' : 'datetime-local'\" placeholder=\"Enter {{parameter.title}}\" [(ngModel)]=\"parameter.value\"\n (keyup.enter)=\"reloadWidget()\" required autofocus>\n\n <a (click)=\"changeDateType($event, parameter, 'period')\"\n matTooltip=\"Time Period\"\n class=\"text-center ml-2 hover:bg-gray-50 text-gray-800 border border-gray-300 py-0.5 pr-0.5 rounded mr-2 bg-white flex items-center\">\n <mat-icon class=\"text-base\">restore</mat-icon>\n </a>\n </ng-template>\n <ng-template [ngIf]=\"parameter._dateType === 'period'\">\n <div class=\"flex items-center\">\n <input #periodValue type=\"number\" placeholder=\"No.\" required autofocus\n class=\"w-16 mr-2\" min=\"0\" [value]=\"parameter._periodValue || 1\"\n (change)=\"updatePeriodValue(periodValue.value, period.value, parameter)\">\n\n <select class=\"param-period-picker mr-2\" [value]=\"parameter._period || 'DAYS'\"\n #period (change)=\"updatePeriodValue(periodValue.value, period.value, parameter)\">\n <option value=\"DAYS\">Days</option>\n <option value=\"HOURS\">Hours</option>\n </select>\n\n <div>Ago</div>\n </div>\n\n <a (click)=\"changeDateType($event, parameter, 'picker')\"\n matTooltip=\"Date Picker\"\n class=\"text-center ml-2 hover:bg-gray-50 text-gray-800 border border-gray-300 py-0.5 pr-0.5 rounded mr-2 bg-white flex items-center\">\n <mat-icon class=\"text-base\">calendar_month</mat-icon>\n </a>\n </ng-template>\n\n </ng-template>\n <ng-template [ngIf]=\"parameter.type === 'boolean'\">\n <mat-slide-toggle class=\"pr-4\" color=\"primary\"\n [checked]=\"parameter.value\" (change)=\"booleanUpdate($event, parameter)\"\n required></mat-slide-toggle>\n </ng-template>\n </div>\n </label>\n </ng-template>\n </div>\n </ng-template>\n\n <div class=\"item-container\" [ngClass]=\"{'flex justify-center': dashboardItemType.type === 'image',\n 'p-px': (dashboardItemType.type === 'table' || general.transparent), 'overflow-hidden': !!chartData,\n 'flex items-center': dashboardItemType.type === 'metric', 'cursor-pointer': (actionItem && Object.keys(actionItem).length)}\"\n (click)=\"(actionItem && Object.keys(actionItem).length) ? callToActionLink(actionItem): null\">\n\n <ng-template [ngIf]=\"dashboardItemType.type === 'text' && textData.value\">\n <div class=\"h-full\" *ngIf=\"textData.safeTextData\" [innerHTML]=\"textData.safeTextData\"></div>\n </ng-template>\n\n <ng-template [ngIf]=\"dashboardItemType.type === 'metric'\">\n <div class=\"w-full\">\n <dt class=\"text-base font-normal text-gray-900\">{{metric.title}}</dt>\n <dd class=\"mt-1 flex items-baseline justify-between md:block lg:flex\">\n <div class=\"flex items-baseline text-2xl font-semibold text-indigo-600\">\n {{metric.mainValue}}\n <span *ngIf=\"metric.subMetric\"\n class=\"ml-2 text-sm font-medium text-gray-500\">from {{metric.subValue}}\n <span class=\"text-xs\">({{metric.subTitle}})</span></span>\n </div>\n\n <div *ngIf=\"metric.showSubChange\"\n class=\"inline-flex items-baseline px-2.5 py-0.5 rounded-full text-sm font-medium md:mt-2 lg:mt-0\"\n [ngClass]=\"{'bg-green-100 text-green-800': metric.mainValue >= metric.subValue, 'bg-red-100 text-red-800': metric.mainValue < metric.subValue}\">\n <!-- Heroicon name: mini/arrow-up -->\n <svg *ngIf=\"metric.mainValue >= metric.subValue\"\n class=\"-ml-1 mr-0.5 h-5 w-5 flex-shrink-0 self-center text-green-500\"\n xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\"\n aria-hidden=\"true\">\n <path fill-rule=\"evenodd\"\n d=\"M10 17a.75.75 0 01-.75-.75V5.612L5.29 9.77a.75.75 0 01-1.08-1.04l5.25-5.5a.75.75 0 011.08 0l5.25 5.5a.75.75 0 11-1.08 1.04l-3.96-4.158V16.25A.75.75 0 0110 17z\"\n clip-rule=\"evenodd\"/>\n </svg>\n <svg *ngIf=\"metric.mainValue < metric.subValue \" xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\" fill=\"currentColor\"\n class=\"-ml-1 mr-0.5 h-5 w-5 flex-shrink-0 self-center text-red-500\">\n <path fill-rule=\"evenodd\"\n d=\"M10 3a.75.75 0 01.75.75v10.638l3.96-4.158a.75.75 0 111.08 1.04l-5.25 5.5a.75.75 0 01-1.08 0l-5.25-5.5a.75.75 0 111.08-1.04l3.96 4.158V3.75A.75.75 0 0110 3z\"\n clip-rule=\"evenodd\"/>\n </svg>\n {{metric.difference}}\n </div>\n </dd>\n </div>\n </ng-template>\n\n <ng-template [ngIf]=\"dashboardItemType.type === 'network'\">\n <div class=\"w-full h-full\" [id]=\"itemInstanceKey + 'VIS'\"></div>\n </ng-template>\n\n <ng-template [ngIf]=\"dashboardItemType.type === 'image'\">\n <div *ngIf=\"imageData.source\" class=\"w-auto h-full\">\n <img [src]=\"imageData.source\" alt=\"\"\n (error)=\"imageError = true\">\n </div>\n\n <div *ngIf=\"!imageData.source || imageError\" class=\"h-full relative flex items-center justify-center\">\n <p class=\"z-10 text-lg\">No image</p>\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"filter blur-sm absolute w-auto h-full text-gray-300\"\n fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"/>\n </svg>\n </div>\n </ng-template>\n\n <ng-template [ngIf]=\"dashboardItemType.type === 'pie' || dashboardItemType.type === 'doughnut'\">\n <canvas baseChart *ngIf=\"chartData\" style=\"height: 200px\"\n [datasets]=\"chartData\"\n [labels]=\"dashboardItemType.labels\"\n [options]=\"{tooltips: { titleFontSize: 0 }, responsive:true, maintainAspectRatio: false}\"\n [legend]=\"!!dashboardItemType.legend\"\n [type]=\"dashboardItemType.type\"\n [plugins]=\"[]\">\n </canvas>\n </ng-template>\n\n <ng-template [ngIf]=\"dashboardItemType.type === 'line' || dashboardItemType.type === 'bar' || dashboardItemType.type === 'scatter'\">\n <canvas baseChart *ngIf=\"chartData\" style=\"height: 200px\"\n [datasets]=\"chartData\"\n [labels]=\"dashboardItemType.labels\"\n [options]=\"{tooltips: { titleFontSize: 0 }, scales: {y: {beginAtZero: dashboardItemType.beginAtZero, max: dashboardItemType.maxValue || null}}, responsive:true, maintainAspectRatio: false}\"\n [legend]=\"!!dashboardItemType.legend\"\n [type]=\"dashboardItemType.type\"\n [plugins]=\"[]\">\n </canvas>\n </ng-template>\n\n <ng-template [ngIf]=\"dashboardItemType.type === 'table'\">\n\n <table class=\"min-w-full border-separate\" style=\"border-spacing: 0\">\n <thead class=\"bg-gray-50 \">\n <tr>\n <ng-template ngFor let-column [ngForOf]=\"dataset.columns\">\n <th scope=\"col\" *ngIf=\"!hiddenColumns[column.name]\" (click)=\"sortHeader(column)\"\n class=\"cursor-pointer sticky -top-px z-10 border-b border-gray-300 bg-gray-50 bg-opacity-75 p-3 text-left text-xs font-semibold text-gray-900 backdrop-blur backdrop-filter\">\n <div *ngIf=\"!tableCells[column.name] || tableCells[column.name].type !== 'action'\"\n class=\"flex items-center \">\n {{column.title}}\n <svg *ngIf=\"column.direction === 'asc'\"\n xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\"\n stroke=\"currentColor\" class=\"stroke-3 text-secondary ml-1 w-4 h-4\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\n d=\"M4.5 10.5L12 3m0 0l7.5 7.5M12 3v18\"/>\n </svg>\n <svg *ngIf=\"column.direction === 'desc'\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\"\n viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\"\n class=\"stroke-3 text-secondary ml-1 w-4 h-4\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\n d=\"M19.5 13.5L12 21m0 0l-7.5-7.5M12 21V3\"/>\n </svg>\n </div>\n </th>\n </ng-template>\n </tr>\n </thead>\n <tbody class=\"bg-white \">\n <tr *ngFor=\"let dataItem of optimise ? dataset.allData.slice(0,10) : dataset.allData\"\n [ngClass]=\"{'hover:bg-gray-50 cursor-pointer ': (tabular.actionRows && tabular.cta)}\"\n (click)=\"(tabular.actionRows && tabular.cta) ? callToActionLink(tabular.cta, dataItem) : null\">\n <ng-template ngFor let-column [ngForOf]=\"dataset.columns\" let-i=index>\n <td *ngIf=\"!hiddenColumns[column.name]\"\n [title]=\"(tableCells[column.name] && tableCells[column.name].maxWidth) ? dataItem[column.name] : ''\"\n class=\"border-b border-gray-200 px-3 py-2 text-sm text-gray-500 relative\"\n [ngClass]=\"{'whitespace-nowrap': !tabular.expandRows, 'font-medium text-gray-900': i === 0}\"\n [ngStyle]=\"{'width': '', 'max-width': (tableCells[column.name] && tableCells[column.name].maxWidth) ? tableCells[column.name].maxWidth + 'px' : null, 'overflow': (tableCells[column.name] && tableCells[column.name].maxWidth) ? 'hidden' : null, 'text-overflow': (tableCells[column.name] && tableCells[column.name].maxWidth) ? 'ellipsis' : null}\">\n <ng-template [ngIf]=\"tableCells[column.name] && tableCells[column.name].type === 'action'\">\n <button type=\"button\" *ngIf=\"tableCells[column.name].data.actionEvent\"\n [ngClass]=\"{'bg-orange-50 border-orange-200 hover:bg-orange-100': isActionComplete(tableCells[column.name].data.actionEvent, dataItem[column.name])}\"\n (click)=\"triggerActionEvent(tableCells[column.name].data.actionEvent, column, dataItem[column.name])\"\n class=\"text-gray-600 inline-flex items-center rounded border border-primary bg-gray-50 px-2.5 py-1.5 text-xs font-medium hover:bg-gray-100\">\n {{getActionEventTitle(tableCells[column.name].data.actionEvent, column, dataItem[column.name])}}\n </button>\n </ng-template>\n\n <ng-template [ngIf]=\"!tableCells[column.name] || tableCells[column.name].type !== 'action'\">\n\n\n <ng-template [ngIf]=\"tabular.expandRows\">\n <div *ngIf=\"!_.isPlainObject(dataItem[column.name])\"\n [innerHTML]=\"dataItem[column.name]\"></div>\n <div *ngIf=\"_.isPlainObject(dataItem[column.name])\"\n [innerHTML]=\"dataItem[column.name].cellValue\"></div>\n </ng-template>\n <ng-template [ngIf]=\"!tabular.expandRows && _.isPlainObject(dataItem[column.name])\">\n <div [innerHTML]=\"dataItem[column.name].cellValue\"\n [ngStyle]=\"{'max-width': (tableCells[column.name] && tableCells[column.name].maxWidth) ? tableCells[column.name].maxWidth + 'px' : null, 'overflow': (tableCells[column.name] && tableCells[column.name].maxWidth) ? 'hidden' : null, 'text-overflow': (tableCells[column.name] && tableCells[column.name].maxWidth) ? 'ellipsis' : null}\"></div>\n </ng-template>\n <ng-template [ngIf]=\"!tabular.expandRows && !_.isPlainObject(dataItem[column.name])\">\n <ng-template\n [ngIf]=\"dataItem[column.name] && String(dataItem[column.name]).length <= 100\">\n {{dataItem[column.name]}}\n </ng-template>\n <ng-template\n [ngIf]=\"dataItem[column.name] && String(dataItem[column.name]).length > 100\">\n <div\n [ngStyle]=\"{'max-width': (tableCells[column.name] && tableCells[column.name].maxWidth) ? tableCells[column.name].maxWidth + 'px' : null, 'overflow': (tableCells[column.name] && tableCells[column.name].maxWidth) ? 'hidden' : null, 'text-overflow': (tableCells[column.name] && tableCells[column.name].maxWidth) ? 'ellipsis' : null}\"\n [title]=\"dataItem[column.name]\">{{dataItem[column.name].substring(0, 100) + '...'}}</div>\n </ng-template>\n <ng-template [ngIf]=\"!dataItem[column.name]\">\n {{dataItem[column.name]}}\n </ng-template>\n </ng-template>\n </ng-template>\n </td>\n </ng-template>\n\n </tr>\n <tr *ngIf=\"optimise && dataset.allData.length > 10\">\n <td class=\"pl-3 text-gray-900 font-medium bg-gray-200\" [colSpan]=\"dataset.columns.length\">\n Results limited during editing for enhanced performance.\n </td>\n </tr>\n </tbody>\n </table>\n\n <div *ngIf=\"!dataset.allData.length\"\n class=\"no-table-records text-sm text-gray-500 flex m-0 justify-center items-center\">\n No records to show\n </div>\n </ng-template>\n\n <ng-template [ngIf]=\"dashboardItemType.type === 'words'\">\n <angular-d3-cloud *ngIf=\"wordCloud.data\"\n [data]=\"wordCloud.data\"\n [width]=\"wordCloud.width\"\n [height]=\"wordCloud.height\"\n [padding]=\"5\"\n font=\"serif\"\n [rotate]=\"0\"\n [autoFill]=\"true\"\n ></angular-d3-cloud>\n </ng-template>\n\n </div>\n\n <div *ngIf=\"!optimise && dashboardItemType.type === 'table' && !tabular.hidePager\"\n class=\"table-pager flex items-center justify-between px-2 border-t border-gray-200 h-12 bg-gray-50 w-full\">\n <div class=\"text-xs text-gray-400\">\n Showing {{offset + 1}} - {{(page * limit) - (limit - dataset.allData.length)}}</div>\n <div class=\"flex items-center justify-center\">\n <button mat-icon-button (click)=\"decreaseOffset()\" [disabled]=\"page <= 1\">\n <mat-icon>chevron_left</mat-icon>\n </button>\n <select [value]=\"limit\" (change)=\"pageSizeChange($event.target.value)\"\n class=\"p-1 mx-2\">\n <option [value]=\"1\">1</option>\n <option [value]=\"5\">5</option>\n <option [value]=\"10\">10</option>\n <option [value]=\"25\">25</option>\n <option [value]=\"50\">50</option>\n <option [value]=\"100\">100</option>\n <option [value]=\"250\">250</option>\n <option [value]=\"1000\">1000</option>\n </select>\n <button mat-icon-button (click)=\"increaseOffset()\" [disabled]=\"endOfResults\">\n <mat-icon>chevron_right</mat-icon>\n </button>\n </div>\n </div>\n\n <div class=\"footer w-full bg-gray-50 px-2 py-1 text-gray-600 border-b border-gray-200 text-xs\"\n [ngClass]=\"{'border-b': callToAction && Object.keys(callToAction).length}\"\n *ngIf=\"general.footer\" [innerHTML]=\"general.evaluatedFooter\"></div>\n\n <div class=\"call-to-action w-full bg-gray-50 px-5 py-3\" *ngIf=\"callToAction && Object.keys(callToAction).length\">\n <div class=\"text-sm\">\n <a class=\"font-medium text-cta flex items-center\"\n (click)=\"callToActionLink(callToAction)\">\n {{callToAction.label}}\n <mat-icon>chevron_right</mat-icon>\n </a>\n </div>\n </div>\n\n</ng-template>\n", styles: [":host:hover .edit-widget,:host:hover .item-unlocked{display:block}.alert-panel{position:absolute;background-color:#fffffff2;inset:0;z-index:99999;display:flex;align-items:center;flex-direction:column}.alert-panel .alert-item{font-weight:500}.alert-panel mat-icon{color:#c41717;font-size:3rem;width:3rem;height:3rem}.no-table-records{height:calc(100% - 41px)}.divider{width:1px;height:17px;background-color:#cecece}.loading-item{display:flex;align-items:center;justify-content:center;flex-direction:column}.loading-item p{margin:1rem 0}.item-title{width:100%;color:gray;padding:1rem 1rem 0;font-size:1rem;font-weight:300}.item-description{width:100%;padding:0 1rem 1rem;font-size:1.1rem;font-weight:500}.item-heading{font-size:1.2rem;display:flex;align-items:center;justify-content:center;width:100%;height:100%}.item-container{padding:1rem;box-sizing:border-box;position:relative;width:100%;height:100%;overflow:auto}.item-container::-webkit-scrollbar{width:.75em;height:.75em;background:transparent}.item-container::-webkit-scrollbar-thumb{background:#d2d2d2}.edit-widget,.item-unlocked{display:none}table{width:100%;border-collapse:collapse}table thead tr th{text-transform:uppercase;text-align:left;border-bottom:1px solid #dbdbdb;padding:0 1rem 1rem 0;color:#5f6368;letter-spacing:1px;white-space:nowrap;font-weight:400;font-size:12px}table tbody tr td{padding:.5rem 1rem .5rem 0;border-bottom:1px solid #ececec;font-size:13px}label.widget-parameter{flex-direction:row;align-items:center;margin-left:1rem}label.widget-parameter .parameter-input{border-radius:4px;padding-left:.5rem;height:36px;display:flex;align-items:center}label.widget-parameter .parameter-input .param-period-picker{padding:5px}label.widget-parameter .parameter-input button{color:#8e8e8e}label.widget-parameter .parameter-input button.edit-parameter{visibility:hidden}label.widget-parameter .parameter-input button.mat-icon-button{width:30px;height:30px;line-height:30px;align-self:center}label.widget-parameter .parameter-input button.mat-icon-button mat-icon{font-size:20px;width:20px;height:20px;line-height:20px}label.widget-parameter .parameter-input input{font-size:.9rem;padding:.25rem .45rem;width:175px}label.widget-parameter .parameter-input:hover .edit-parameter{visibility:visible}\n"] }]
|
|
1197
|
-
}], ctorParameters: function () { return [{ type: i1.MatLegacyDialog }, { type: i2.DatasourceService }, { type: i3.DatasetService }, { type: i4.AlertService }, { type: i5.DashboardService }, { type: i6.DomSanitizer }, { type: i7.Router }, { type: i8.Location }, { type: i9.ExternalService }, { type: i10.ProjectService }]; }, propDecorators: { dashboardItemType: [{
|
|
1198
|
-
type: Input
|
|
1199
|
-
}], itemInstanceKey: [{
|
|
1200
|
-
type: Input
|
|
1201
|
-
}], dashboard: [{
|
|
1202
|
-
type: Input
|
|
1203
|
-
}], dashboardItem: [{
|
|
1204
|
-
type: Input
|
|
1205
|
-
}], dragItem: [{
|
|
1206
|
-
type: Input
|
|
1207
|
-
}], grid: [{
|
|
1208
|
-
type: Input
|
|
1209
|
-
}], actionEvents: [{
|
|
1210
|
-
type: Input
|
|
1211
|
-
}], external: [{
|
|
1212
|
-
type: Input
|
|
1213
|
-
}], queryParams: [{
|
|
1214
|
-
type: Input
|
|
1215
|
-
}], editAlerts: [{
|
|
1216
|
-
type: Input
|
|
1217
|
-
}], duplicateItem: [{
|
|
1218
|
-
type: Output
|
|
1219
|
-
}], configureClass: [{
|
|
1220
|
-
type: HostBinding,
|
|
1221
|
-
args: ['class.justify-center']
|
|
1222
|
-
}], textTemplate: [{
|
|
1223
|
-
type: ViewChild,
|
|
1224
|
-
args: ['textTemplate']
|
|
1225
|
-
}] } });
|
|
1226
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXRlbS1jb21wb25lbnQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmcta2luaW50ZWwvc3JjL2xpYi9jb21wb25lbnRzL2Rhc2hib2FyZC1lZGl0b3IvaXRlbS1jb21wb25lbnQvaXRlbS1jb21wb25lbnQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmcta2luaW50ZWwvc3JjL2xpYi9jb21wb25lbnRzL2Rhc2hib2FyZC1lZGl0b3IvaXRlbS1jb21wb25lbnQvaXRlbS1jb21wb25lbnQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVILFNBQVMsRUFFVCxZQUFZLEVBQ1osV0FBVyxFQUNYLEtBQUssRUFFTCxNQUFNLEVBQ04sU0FBUyxFQUNaLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBQyxzQkFBc0IsRUFBQyxNQUFNLDRDQUE0QyxDQUFDO0FBRWxGLE9BQU8sS0FBSyxNQUFNLE1BQU0sUUFBUSxDQUFDO0FBS2pDLE9BQU8sRUFBQyxPQUFPLEVBQWUsTUFBTSxNQUFNLENBQUM7QUFHM0MsT0FBTyxNQUFNLE1BQU0sUUFBUSxDQUFDO0FBQzVCLE9BQU8sVUFBVSxNQUFNLFlBQVksQ0FBQztBQUVwQyxPQUFPLEVBQ0gsMkJBQTJCLEVBQzlCLE1BQU0sdUVBQXVFLENBQUM7QUFDL0UsT0FBTyxFQUFDLG1CQUFtQixFQUFDLE1BQU0sdURBQXVELENBQUM7QUFLMUYsT0FBTyxNQUFNLE1BQU0sV0FBVyxDQUFDO0FBQy9CLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDMUQsT0FBTyxpQkFBaUIsTUFBTSw0Q0FBNEMsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBbkIzRSxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDO0FBNEJ6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QkFBQyxjQUFjIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgICBBZnRlclZpZXdJbml0LFxuICAgIENvbXBvbmVudCxcbiAgICBFbGVtZW50UmVmLFxuICAgIEV2ZW50RW1pdHRlcixcbiAgICBIb3N0QmluZGluZyxcbiAgICBJbnB1dCxcbiAgICBPbkRlc3Ryb3ksXG4gICAgT3V0cHV0LFxuICAgIFZpZXdDaGlsZFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7TWF0TGVnYWN5RGlhbG9nIGFzIE1hdERpYWxvZ30gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvbGVnYWN5LWRpYWxvZyc7XG5pbXBvcnQge0NvbmZpZ3VyZUl0ZW1Db21wb25lbnR9IGZyb20gJy4uL2NvbmZpZ3VyZS1pdGVtL2NvbmZpZ3VyZS1pdGVtLmNvbXBvbmVudCc7XG5pbXBvcnQge0RhdGFzb3VyY2VTZXJ2aWNlfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9kYXRhc291cmNlLnNlcnZpY2UnO1xuaW1wb3J0ICogYXMgbG9kYXNoIGZyb20gJ2xvZGFzaCc7XG5cbmNvbnN0IF8gPSBsb2Rhc2guZGVmYXVsdDtcbmltcG9ydCB7RGF0YXNldFNlcnZpY2V9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2RhdGFzZXQuc2VydmljZSc7XG5pbXBvcnQge0FsZXJ0U2VydmljZX0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvYWxlcnQuc2VydmljZSc7XG5pbXBvcnQge1N1YmplY3QsIFN1YnNjcmlwdGlvbn0gZnJvbSAncnhqcyc7XG5pbXBvcnQge0Rhc2hib2FyZFNlcnZpY2V9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2Rhc2hib2FyZC5zZXJ2aWNlJztcbmltcG9ydCB7RG9tU2FuaXRpemVyfSBmcm9tICdAYW5ndWxhci9wbGF0Zm9ybS1icm93c2VyJztcbmltcG9ydCBtb21lbnQgZnJvbSAnbW9tZW50JztcbmltcG9ydCByZWdyZXNzaW9uIGZyb20gJ3JlZ3Jlc3Npb24nO1xuaW1wb3J0IHtSb3V0ZXJ9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQge1xuICAgIEVkaXREYXNoYm9hcmRBbGVydENvbXBvbmVudFxufSBmcm9tICcuLi9jb25maWd1cmUtaXRlbS9lZGl0LWRhc2hib2FyZC1hbGVydC9lZGl0LWRhc2hib2FyZC1hbGVydC5jb21wb25lbnQnO1xuaW1wb3J0IHtFeHBvcnREYXRhQ29tcG9uZW50fSBmcm9tICcuLi8uLi9kYXRhLWV4cGxvcmVyL2V4cG9ydC1kYXRhL2V4cG9ydC1kYXRhLmNvbXBvbmVudCc7XG5pbXBvcnQge0xvY2F0aW9ufSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtBY3Rpb25FdmVudH0gZnJvbSAnLi4vLi4vLi4vb2JqZWN0cy9hY3Rpb24tZXZlbnQnO1xuaW1wb3J0IHtFeHRlcm5hbFNlcnZpY2V9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2V4dGVybmFsLnNlcnZpY2UnO1xuaW1wb3J0IHtQcm9qZWN0U2VydmljZX0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvcHJvamVjdC5zZXJ2aWNlJztcbmltcG9ydCBjaHJvbWEgZnJvbSAnY2hyb21hLWpzJztcbmltcG9ydCB7IERhdGFTZXQsIE5ldHdvcmsgfSBmcm9tICd2aXMtbmV0d29yay9zdGFuZGFsb25lJztcbmltcG9ydCB2aXNOZXR3b3JrT3B0aW9ucyBmcm9tICcuLi9jb25maWd1cmUtaXRlbS92aXMtbmV0d29yay1vcHRpb25zLmpzb24nO1xuXG5kZWNsYXJlIHZhciB3aW5kb3c6IGFueTtcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdraS1pdGVtLWNvbXBvbmVudCcsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2l0ZW0tY29tcG9uZW50LmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsnLi9pdGVtLWNvbXBvbmVudC5jb21wb25lbnQuc2FzcyddXG59KVxuZXhwb3J0IGNsYXNzIEl0ZW1Db21wb25lbnRDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuXG4gICAgQElucHV0KCkgZGFzaGJvYXJkSXRlbVR5cGU6IGFueTtcbiAgICBASW5wdXQoKSBpdGVtSW5zdGFuY2VLZXk6IGFueTtcbiAgICBASW5wdXQoKSBkYXNoYm9hcmQ6IGFueTtcbiAgICBASW5wdXQoKSBkYXNoYm9hcmRJdGVtOiBhbnk7XG4gICAgQElucHV0KCkgZHJhZ0l0ZW06IGJvb2xlYW47XG4gICAgQElucHV0KCkgZ3JpZDogYW55O1xuICAgIEBJbnB1dCgpIGFjdGlvbkV2ZW50czogQWN0aW9uRXZlbnRbXSA9IFtdO1xuICAgIEBJbnB1dCgpIGV4dGVybmFsID0gZmFsc2U7XG4gICAgQElucHV0KCkgcXVlcnlQYXJhbXM6IGFueTtcbiAgICBASW5wdXQoKSBlZGl0QWxlcnRzID0gZmFsc2U7XG5cbiAgICBAT3V0cHV0KCkgZHVwbGljYXRlSXRlbTogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuICAgIEBIb3N0QmluZGluZygnY2xhc3MuanVzdGlmeS1jZW50ZXInKSBjb25maWd1cmVDbGFzcyA9IGZhbHNlO1xuXG4gICAgQFZpZXdDaGlsZCgndGV4dFRlbXBsYXRlJykgdGV4dFRlbXBsYXRlOiBFbGVtZW50UmVmO1xuXG4gICAgcHVibGljIGRhdGFzb3VyY2VTZXJ2aWNlOiBhbnk7XG4gICAgcHVibGljIGRhdGFzZXRTZXJ2aWNlOiBhbnk7XG4gICAgcHVibGljIGFsZXJ0U2VydmljZTogYW55O1xuICAgIHB1YmxpYyBfID0gXztcbiAgICBwdWJsaWMgaW1hZ2VFcnJvciA9IGZhbHNlO1xuICAgIHB1YmxpYyBPYmplY3QgPSBPYmplY3Q7XG4gICAgcHVibGljIFN0cmluZyA9IFN0cmluZztcbiAgICBwdWJsaWMgZGF0YXNldDogYW55O1xuICAgIHB1YmxpYyBjaGFydERhdGE6IGFueTtcbiAgICBwdWJsaWMgZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlOiBhbnkgPSB7fTtcbiAgICBwdWJsaWMgbG9hZGluZ0l0ZW0gPSBmYWxzZTtcbiAgICBwdWJsaWMgZmlsdGVyRmllbGRzOiBhbnkgPSBbXTtcbiAgICBwdWJsaWMgZGVwZW5kZW5jaWVzOiBhbnkgPSB7fTtcbiAgICBwdWJsaWMgbWV0cmljOiBhbnkgPSB7fTtcbiAgICBwdWJsaWMgdGV4dERhdGE6IGFueSA9IHt9O1xuICAgIHB1YmxpYyBuZXR3b3JrRGF0YTogYW55ID0ge307XG4gICAgcHVibGljIHdvcmRDbG91ZDogYW55ID0ge307XG4gICAgcHVibGljIGltYWdlRGF0YTogYW55ID0ge307XG4gICAgcHVibGljIHRhYnVsYXI6IGFueSA9IHt9O1xuICAgIHB1YmxpYyB0YWJsZUNlbGxzOiBhbnkgPSB7fTtcbiAgICBwdWJsaWMgaGlkZGVuQ29sdW1uczogYW55ID0ge307XG4gICAgcHVibGljIGdlbmVyYWw6IGFueSA9IHt9O1xuICAgIHB1YmxpYyBjYWxsVG9BY3Rpb246IGFueSA9IHt9O1xuICAgIHB1YmxpYyBhY3Rpb25JdGVtOiBhbnkgPSB7fTtcbiAgICBwdWJsaWMgYWxlcnQgPSBmYWxzZTtcbiAgICBwdWJsaWMgYWxlcnREYXRhOiBhbnkgPSBbXTtcbiAgICBwdWJsaWMgc2hvd0FsZXJ0RGF0YSA9IGZhbHNlO1xuICAgIHB1YmxpYyBhZG1pbjogYm9vbGVhbjtcbiAgICBwdWJsaWMgdmlld09ubHk6IGJvb2xlYW47XG4gICAgcHVibGljIGN1cnJlbmNpZXMgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICAgIG5hbWU6ICdCcml0aXNoIFBvdW5kICjCoyknLFxuICAgICAgICAgICAgdmFsdWU6ICdHQlAnLFxuICAgICAgICAgICAgc3ltYm9sOiAnwqMnXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAgIG5hbWU6ICdVUyBEb2xsYXIgKCQpJyxcbiAgICAgICAgICAgIHZhbHVlOiAnVVNEJyxcbiAgICAgICAgICAgIHN5bWJvbDogJyQnXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAgIG5hbWU6ICdFdXJvICjigqwpJyxcbiAgICAgICAgICAgIHZhbHVlOiAnRVVSJyxcbiAgICAgICAgICAgIHN5bWJvbDogJ+KCrCdcbiAgICAgICAgfVxuICAgIF07XG4gICAgcHVibGljIGxpbWl0ID0gMjU7XG4gICAgcHVibGljIHBhZ2UgPSAxO1xuICAgIHB1YmxpYyBvZmZzZXQgPSAwO1xuICAgIHB1YmxpYyBlbmRPZlJlc3VsdHMgPSBmYWxzZTtcbiAgICBwdWJsaWMgaXRlbUxvY2tlZCA9IGZhbHNlO1xuICAgIHB1YmxpYyBvcHRpbWlzZSA9IHRydWU7XG4gICAgcHVibGljIG9wdGltaXNlU3ViamVjdCA9IG5ldyBTdWJqZWN0PGJvb2xlYW4+KCk7XG4gICAgcHVibGljIGNhbkV4cG9ydERhdGEgPSBmYWxzZTtcbiAgICBwdWJsaWMgZXh0ZXJuYWxFcnJvciA9IGZhbHNlO1xuICAgIHB1YmxpYyBxdW90YUV4Y2VlZGVkOiBzdHJpbmcgPSBudWxsO1xuICAgIHB1YmxpYyBleGlzdGluZ0dyaWRJdGVtID0gZmFsc2U7XG4gICAgcHVibGljIGl0ZW1Ob01vdmUgPSBmYWxzZTtcbiAgICBwdWJsaWMgdmlzTmV0d29ya09wdGlvbnMgPSB2aXNOZXR3b3JrT3B0aW9ucztcblxuICAgIHByaXZhdGUgaXRlbUxvYWRlZFN1YjogU3Vic2NyaXB0aW9uO1xuICAgIHByaXZhdGUgb3B0aW1pc2VTdWI6IFN1YnNjcmlwdGlvbjtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgZGlhbG9nOiBNYXREaWFsb2csXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBraURhdGFzb3VyY2VTZXJ2aWNlOiBEYXRhc291cmNlU2VydmljZSxcbiAgICAgICAgICAgICAgICBwcml2YXRlIGtpRGF0YXNldFNlcnZpY2U6IERhdGFzZXRTZXJ2aWNlLFxuICAgICAgICAgICAgICAgIHByaXZhdGUga2lBbGVydFNlcnZpY2U6IEFsZXJ0U2VydmljZSxcbiAgICAgICAgICAgICAgICBwcml2YXRlIGRhc2hib2FyZFNlcnZpY2U6IERhc2hib2FyZFNlcnZpY2UsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBzYW5pdGl6ZXI6IERvbVNhbml0aXplcixcbiAgICAgICAgICAgICAgICBwcml2YXRlIHJvdXRlcjogUm91dGVyLFxuICAgICAgICAgICAgICAgIHByaXZhdGUgbG9jYXRpb246IExvY2F0aW9uLFxuICAgICAgICAgICAgICAgIHByaXZhdGUgZXh0ZXJuYWxTZXJ2aWNlOiBFeHRlcm5hbFNlcnZpY2UsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBwcm9qZWN0U2VydmljZTogUHJvamVjdFNlcnZpY2UpIHtcbiAgICB9XG5cbiAgICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5jYW5FeHBvcnREYXRhID0gdGhpcy5wcm9qZWN0U2VydmljZS5kb2VzQWN0aXZlUHJvamVjdEhhdmVQcml2aWxlZ2UoJ2V4cG9ydGRhdGEnKTtcblxuICAgICAgICAgICAgY29uc3QgaW5zdGFuY2VFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5pdGVtSW5zdGFuY2VLZXkpO1xuICAgICAgICAgICAgaWYgKGluc3RhbmNlRWxlbWVudCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHdpZGdldCA9IGluc3RhbmNlRWxlbWVudC5jbG9zZXN0KCcuZ3JpZC1zdGFjay1pdGVtJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5pdGVtTm9Nb3ZlID0gd2lkZ2V0LmdldEF0dHJpYnV0ZSgnZ3Mtbm8tbW92ZScpID09PSAndHJ1ZSc7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIDUwKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgaW5pdChldmFsdWF0ZSA9IGZhbHNlKSB7XG4gICAgICAgIHRoaXMubWFwTGF5b3V0U2V0dGluZ3NUb0NvbXBvbmVudERhdGEoKTtcblxuICAgICAgICBpZiAodGhpcy50YWJ1bGFyICYmIHRoaXMudGFidWxhci5saW1pdCkge1xuICAgICAgICAgICAgdGhpcy5saW1pdCA9IHRoaXMudGFidWxhci5saW1pdDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmdlbmVyYWwgJiYgdGhpcy5nZW5lcmFsLmxpbWl0KSB7XG4gICAgICAgICAgICB0aGlzLmxpbWl0ID0gdGhpcy5nZW5lcmFsLmxpbWl0O1xuICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSB0aGlzLmdlbmVyYWwub2Zmc2V0O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLmRhdGFzb3VyY2VTZXJ2aWNlKSB7XG4gICAgICAgICAgICB0aGlzLmRhdGFzb3VyY2VTZXJ2aWNlID0gdGhpcy5raURhdGFzb3VyY2VTZXJ2aWNlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLmRhdGFzZXRTZXJ2aWNlKSB7XG4gICAgICAgICAgICB0aGlzLmRhdGFzZXRTZXJ2aWNlID0gdGhpcy5raURhdGFzZXRTZXJ2aWNlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLmFsZXJ0U2VydmljZSkge1xuICAgICAgICAgICAgdGhpcy5hbGVydFNlcnZpY2UgPSB0aGlzLmtpQWxlcnRTZXJ2aWNlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuZGFzaGJvYXJkICYmXG4gICAgICAgICAgICB0aGlzLmRhc2hib2FyZC5kaXNwbGF5U2V0dGluZ3MuaGVhZGluZyAmJlxuICAgICAgICAgICAgdGhpcy5kYXNoYm9hcmQuZGlzcGxheVNldHRpbmdzLmhlYWRpbmdbdGhpcy5pdGVtSW5zdGFuY2VLZXldKSB7XG4gICAgICAgICAgICB0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLmhlYWRpbmdWYWx1ZSA9IHRoaXMuZGFzaGJvYXJkLmRpc3BsYXlTZXR0aW5ncy5oZWFkaW5nW3RoaXMuaXRlbUluc3RhbmNlS2V5XTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmdlbmVyYWwucGFyYW1ldGVyQmFyICYmIE9iamVjdC5rZXlzKHRoaXMuZ2VuZXJhbC5wYXJhbWV0ZXJCYXIpLmxlbmd0aCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzLmdlbmVyYWwud2lkZ2V0UGFyYW1ldGVycyB8fCBBcnJheS5pc0FycmF5KHRoaXMuZ2VuZXJhbC53aWRnZXRQYXJhbWV0ZXJzKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZ2VuZXJhbC53aWRnZXRQYXJhbWV0ZXJzID0ge307XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIE9iamVjdC5rZXlzKHRoaXMuZ2VuZXJhbC5wYXJhbWV0ZXJCYXIpLmZvckVhY2gocGFyYW1LZXkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmdlbmVyYWwucGFyYW1ldGVyQmFyW3BhcmFtS2V5XSAmJiAhdGhpcy5nZW5lcmFsLndpZGdldFBhcmFtZXRlcnNbcGFyYW1LZXldKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZ2VuZXJhbC53aWRnZXRQYXJhbWV0ZXJzW3BhcmFtS2V5XSA9IF8uY2xvbmVEZWVwKHRoaXMuZGFzaGJvYXJkLmxheW91dFNldHRpbmdzLnBhcmFtZXRlcnNbcGFyYW1LZXldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmdlbmVyYWwucGFyYW1ldGVyQmFyW3BhcmFtS2V5XSkge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5nZW5lcmFsLndpZGdldFBhcmFtZXRlcnNbcGFyYW1LZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jb25maWd1cmVDbGFzcyA9IHRydWU7XG4gICAgICAgIGlmICh0aGlzLmRlcGVuZGVuY2llcy5pbnN0YW5jZUtleXMgJiYgdGhpcy5kZXBlbmRlbmNpZXMuaW5zdGFuY2VLZXlzLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy5sb2FkaW5nSXRlbSA9IHRydWU7XG5cbiAgICAgICAgICAgIHRoaXMuaXRlbUxvYWRlZFN1YiA9IHRoaXMuZGFzaGJvYXJkU2VydmljZS5kYXNoYm9hcmRJdGVtcy5zdWJzY3JpYmUoYXN5bmMgbG9hZGVkID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBsb2FkZWRJbnN0YW5jZXMgPSBPYmplY3Qua2V5cyhsb2FkZWQpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGRlcGVuZGVudCA9IF8uZmlsdGVyKGxvYWRlZEluc3RhbmNlcywga2V5ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGVwZW5kZW5jaWVzLmluc3RhbmNlS2V5cy5pbmRleE9mKGtleSkgPiAtMTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBpZiAoZGVwZW5kZW50Lmxlbmd0aCA9PT0gdGhpcy5kZXBlbmRlbmNpZXMuaW5zdGFuY2VLZXlzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pdGVtTG9hZGVkU3ViKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLml0ZW1Mb2FkZWRTdWIudW5zdWJzY3JpYmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFsbExvYWRlZCA9IF8uZXZlcnkodGhpcy5kZXBlbmRlbmNpZXMuaW5zdGFuY2VLZXlzLCBrZXkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGVwZW5kZW5jaWVzW2tleV0udHlwZSA9PT0gJ0xPQURFRCc7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYWxsTG9hZGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmV2YWx1YXRlKCk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXRjaGVzID0gXy5maWx0ZXIodGhpcy5kZXBlbmRlbmNpZXMsIHt0eXBlOiAnTUFUQ0gnfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhbGxNYXRjaGVkID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGRlcCBvZiBtYXRjaGVzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2VsZWN0ZWREYXRhc2V0SW5zdGFuY2UgPSBfLmZpbmQodGhpcy5kYXNoYm9hcmQuZGF0YXNldEluc3RhbmNlcywge2luc3RhbmNlS2V5OiBkZXAua2V5fSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGVjdGVkRGF0YXNldEluc3RhbmNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hcHBlZFBhcmFtcyA9IHRoaXMuZ2V0TWFwcGVkUGFyYW1zKHNlbGVjdGVkRGF0YXNldEluc3RhbmNlKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0cmFuc2Zvcm1hdGlvbnMgPSBfLmNsb25lKHNlbGVjdGVkRGF0YXNldEluc3RhbmNlLnRyYW5zZm9ybWF0aW9uSW5zdGFuY2VzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtYXRpb25zLnB1c2goe3R5cGU6ICdmaWx0ZXInLCBjb25maWc6IGRlcC5maWx0ZXJKdW5jdGlvbn0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRhdGFzZXRJbnN0YW5jZVN1bW1hcnkgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhc2V0SW5zdGFuY2VJZDogc2VsZWN0ZWREYXRhc2V0SW5zdGFuY2UuZGF0YXNldEluc3RhbmNlSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhc291cmNlSW5zdGFuY2VLZXk6IHNlbGVjdGVkRGF0YXNldEluc3RhbmNlLmRhdGFzb3VyY2VJbnN0YW5jZUtleSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybWF0aW9uSW5zdGFuY2VzOiB0cmFuc2Zvcm1hdGlvbnMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJWYWx1ZXM6IG1hcHBlZFBhcmFtcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlcnM6IHNlbGVjdGVkRGF0YXNldEluc3RhbmNlLnBhcmFtZXRlcnNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgZGF0YSA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmV4dGVybmFsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gYXdhaXQgdGhpcy5leHRlcm5hbFNlcnZpY2UuZXZhbHVhdGVEYXRhc2V0KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGFzaGJvYXJkLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXRlbUluc3RhbmNlS2V5LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkRGF0YXNldEluc3RhbmNlLnBhcmFtZXRlclZhbHVlcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnMCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzEnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucXVlcnlQYXJhbXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGF3YWl0IHRoaXMuZGF0YXNldFNlcnZpY2UuZXZhbHVhdGVEYXRhc2V0KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFzZXRJbnN0YW5jZVN1bW1hcnksICcwJywgJzEnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxsTWF0Y2hlZC5wdXNoKGRhdGEuYWxsRGF0YS5sZW5ndGggPT09IDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfLmV2ZXJ5KGFsbE1hdGNoZWQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5ldmFsdWF0ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvYWRpbmdJdGVtID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaXRlbUVsZW1lbnQ6IGFueSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMuaXRlbUluc3RhbmNlS2V5KS5jbG9zZXN0KCcuZ3JpZC1zdGFjay1pdGVtJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbUVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnaXRlbS1kaXNhYmxlZCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZhbHVhdGUpIHtcbiAgICAgICAgICAgIHRoaXMuZXZhbHVhdGUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMub3B0aW1pc2VTdWIgPSB0aGlzLm9wdGltaXNlU3ViamVjdC5zdWJzY3JpYmUocmVzID0+IHRoaXMub3B0aW1pc2UgPSByZXMpO1xuXG4gICAgICAgIHRoaXMuZXhpc3RpbmdHcmlkSXRlbSA9ICEhXy5maW5kKHRoaXMuZGFzaGJvYXJkLmxheW91dFNldHRpbmdzLmdyaWQsIGl0ZW0gPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGl0ZW0uY29udGVudC5pbmNsdWRlcyh0aGlzLml0ZW1JbnN0YW5jZUtleSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG5nT25EZXN0cm95KCkge1xuICAgICAgICBpZiAodGhpcy5vcHRpbWlzZVN1Yikge1xuICAgICAgICAgICAgdGhpcy5vcHRpbWlzZVN1Yi51bnN1YnNjcmliZSgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLml0ZW1Mb2FkZWRTdWIpIHtcbiAgICAgICAgICAgIHRoaXMuaXRlbUxvYWRlZFN1Yi51bnN1YnNjcmliZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGxvY2tJdGVtKCkge1xuICAgICAgICBjb25zdCBpdGVtRWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMuaXRlbUluc3RhbmNlS2V5KTtcbiAgICAgICAgY29uc3Qgd2lkZ2V0ID0gaXRlbUVsZW1lbnQuY2xvc2VzdCgnLmdyaWQtc3RhY2staXRlbScpO1xuICAgICAgICB0aGlzLml0ZW1Ob01vdmUgPSB3aWRnZXQuZ2V0QXR0cmlidXRlKCdncy1uby1tb3ZlJykgIT09ICd0cnVlJztcbiAgICAgICAgdGhpcy5ncmlkLnVwZGF0ZSh3aWRnZXQsIHtub01vdmU6IHRoaXMuaXRlbU5vTW92ZX0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBkdXBsaWNhdGUoKSB7XG4gICAgICAgIHRoaXMuZHVwbGljYXRlSXRlbS5lbWl0KHRoaXMuaXRlbUluc3RhbmNlS2V5KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgY29uZmlndXJlKCkge1xuICAgICAgICBpZiAodGhpcy5kYXNoYm9hcmRJdGVtVHlwZS50eXBlID09PSAnaGVhZGluZycpIHtcbiAgICAgICAgICAgIHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUuX2VkaXRpbmcgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgcXVlcnlQYXJhbXM6IGFueSA9IHt9O1xuICAgICAgICAgICAgaWYgKHRoaXMuYWRtaW4pIHtcbiAgICAgICAgICAgICAgICBxdWVyeVBhcmFtcy5hID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFt3aW5kb3cubG9jYXRpb24ucGF0aG5hbWVdLCB7XG4gICAgICAgICAgICAgICAgcXVlcnlQYXJhbXMsXG4gICAgICAgICAgICAgICAgZnJhZ21lbnQ6IF8ua2ViYWJDYXNlKHRoaXMuZGFzaGJvYXJkLnRpdGxlKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjb25zdCBkaWFsb2dSZWYgPSB0aGlzLmRpYWxvZy5vcGVuKENvbmZpZ3VyZUl0ZW1Db21wb25lbnQsIHtcbiAgICAgICAgICAgICAgICB3aWR0aDogJzEwMHZ3JyxcbiAgICAgICAgICAgICAgICBoZWlnaHQ6ICcxMDB2aCcsXG4gICAgICAgICAgICAgICAgbWF4V2lkdGg6ICcxMDB2dycsXG4gICAgICAgICAgICAgICAgbWF4SGVpZ2h0OiAnMTAwdmgnLFxuICAgICAgICAgICAgICAgIGhhc0JhY2tkcm9wOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgICAgIGdyaWQ6IHRoaXMuZ3JpZCxcbiAgICAgICAgICAgICAgICAgICAgZGFzaGJvYXJkOiB0aGlzLmRhc2hib2FyZCxcbiAgICAgICAgICAgICAgICAgICAgZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlOiB0aGlzLmRhc2hib2FyZERhdGFzZXRJbnN0YW5jZSxcbiAgICAgICAgICAgICAgICAgICAgaXRlbUluc3RhbmNlS2V5OiB0aGlzLml0ZW1JbnN0YW5jZUtleSxcbiAgICAgICAgICAgICAgICAgICAgZGFzaGJvYXJkSXRlbVR5cGU6IHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUsXG4gICAgICAgICAgICAgICAgICAgIGFkbWluOiB0aGlzLmFkbWluLFxuICAgICAgICAgICAgICAgICAgICBhY3Rpb25FdmVudHM6IHRoaXMuYWN0aW9uRXZlbnRzXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBkaWFsb2dSZWYuYWZ0ZXJDbG9zZWQoKS5zdWJzY3JpYmUoZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlID0gZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvY2F0aW9uLmJhY2soKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbml0KHRydWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGxvYWQoKSB7XG4gICAgICAgIC8vIENoZWNrIHRvIHNlZSBpZiBhbnkgb2YgdGhlIGdyaWQgaXRlbXMgYXJlIGxvY2tlZFxuICAgICAgICBjb25zdCBncmlkID0gdGhpcy5kYXNoYm9hcmQubGF5b3V0U2V0dGluZ3MuZ3JpZDtcbiAgICAgICAgY29uc3QgbG9ja2VkSXRlbXMgPSBfLmZpbHRlcihncmlkLCAnbG9ja2VkJyk7XG4gICAgICAgIHRoaXMuaXRlbUxvY2tlZCA9ICEhXy5maW5kKGxvY2tlZEl0ZW1zLCBsb2NrZWRJdGVtID0+IHtcbiAgICAgICAgICAgIHJldHVybiBsb2NrZWRJdGVtLmNvbnRlbnQuaW5jbHVkZXModGhpcy5pdGVtSW5zdGFuY2VLZXkpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAodGhpcy5leHRlcm5hbCkge1xuICAgICAgICAgICAgdGhpcy5pdGVtTG9ja2VkID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmRhc2hib2FyZERhdGFzZXRJbnN0YW5jZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXZhbHVhdGUoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRydWUpO1xuICAgIH1cblxuICAgIHB1YmxpYyByZW1vdmVXaWRnZXQoZXZlbnQpIHtcbiAgICAgICAgY29uc3QgbWVzc2FnZSA9ICdBcmUgeW91ciBzdXJlIHlvdSB3b3VsZCBsaWtlIHRvIHJlbW92ZSB0aGlzIGl0ZW0gZnJvbSB5b3VyIGRhc2hib2FyZD8nO1xuICAgICAgICBpZiAod2luZG93LmNvbmZpcm0obWVzc2FnZSkpIHtcbiAgICAgICAgICAgIGNvbnN0IGl0ZW1FbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5pdGVtSW5zdGFuY2VLZXkpO1xuICAgICAgICAgICAgXy5yZW1vdmUodGhpcy5kYXNoYm9hcmQuZGF0YXNldEluc3RhbmNlcywge2luc3RhbmNlS2V5OiB0aGlzLml0ZW1JbnN0YW5jZUtleX0pO1xuICAgICAgICAgICAgY29uc3Qgd2lkZ2V0ID0gaXRlbUVsZW1lbnQuY2xvc2VzdCgnLmdyaWQtc3RhY2staXRlbScpO1xuICAgICAgICAgICAgdGhpcy5ncmlkLnJlbW92ZVdpZGdldCh3aWRnZXQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIHRyaWdnZXJBY3Rpb25FdmVudChhY3Rpb25FdmVudCwgY29sdW1uLCB2YWx1ZSkge1xuICAgICAgICBjb25zdCBhY3Rpb246IEFjdGlvbkV2ZW50ID0gXy5maW5kKHRoaXMuYWN0aW9uRXZlbnRzLCB7bmFtZTogYWN0aW9uRXZlbnR9KTtcbiAgICAgICAgaWYgKGFjdGlvbikge1xuICAgICAgICAgICAgYWN0aW9uLmV2ZW50Lm5leHQoe2tleTogY29sdW1uLm5hbWUsIHZhbHVlfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0QWN0aW9uRXZlbnRUaXRsZShhY3Rpb25FdmVudCwgY29sdW1uLCB2YWx1ZSkge1xuICAgICAgICBjb25zdCBhY3Rpb246IEFjdGlvbkV2ZW50ID0gXy5maW5kKHRoaXMuYWN0aW9uRXZlbnRzLCB7bmFtZTogYWN0aW9uRXZlbnR9KTtcblxuICAgICAgICBsZXQgdGl0bGUgPSAnJztcbiAgICAgICAgaWYgKGFjdGlvbikge1xuICAgICAgICAgICAgdGl0bGUgPSB0aGlzLmlzQWN0aW9uQ29tcGxldGUoYWN0aW9uRXZlbnQsIHZhbHVlKSA/IGFjdGlvbi5jb21wbGV0ZUxhYmVsIDogYWN0aW9uLmFjdGlvbkxhYmVsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aXRsZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgaXNBY3Rpb25Db21wbGV0ZShhY3Rpb25FdmVudCwgdmFsdWUpIHtcbiAgICAgICAgbGV0IGNvbXBsZXRlID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IGFjdGlvbjogQWN0aW9uRXZlbnQgPSBfLmZpbmQodGhpcy5hY3Rpb25FdmVudHMsIHtuYW1lOiBhY3Rpb25FdmVudH0pO1xuXG4gICAgICAgIGlmIChhY3Rpb24pIHtcbiAgICAgICAgICAgIGNvbnN0IGZpbmREYXRhID0ge307XG4gICAgICAgICAgICBmaW5kRGF0YVthY3Rpb24uY29tcGFyaXNvbkZpZWxkXSA9IHZhbHVlO1xuICAgICAgICAgICAgY29tcGxldGUgPSBfLmZpbmQoYWN0aW9uLmRhdGEgfHwgW10sIGZpbmREYXRhKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBjb21wbGV0ZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZWRpdEl0ZW1BbGVydHMoYWxlcnQsIGluZGV4Pykge1xuICAgICAgICBjb25zdCBkaWFsb2dSZWYgPSB0aGlzLmRpYWxvZy5vcGVuKEVkaXREYXNoYm9hcmRBbGVydENvbXBvbmVudCwge1xuICAgICAgICAgICAgd2lkdGg6ICc5MDBweCcsXG4gICAgICAgICAgICBoZWlnaHQ6ICc3NTBweCcsXG4gICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgYWxlcnQsXG4gICAgICAgICAgICAgICAgZmlsdGVyRmllbGRzOiB0aGlzLmZpbHRlckZpZWxkc1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBkaWFsb2dSZWYuYWZ0ZXJDbG9zZWQoKS5zdWJzY3JpYmUoYWxlcnRJdGVtID0+IHtcbiAgICAgICAgICAgIGlmIChhbGVydEl0ZW0pIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlLmFsZXJ0cykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRhc2hib2FyZERhdGFzZXRJbnN0YW5jZS5hbGVydHMgPSBbXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGluZGV4ID49IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kYXNoYm9hcmREYXRhc2V0SW5zdGFuY2UuYWxlcnRzW2luZGV4XSA9IGFsZXJ0SXRlbTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRhc2hib2FyZERhdGFzZXRJbnN0YW5jZS5hbGVydHMucHVzaChhbGVydEl0ZW0pO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMucmVsb2FkQWxlcnQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIHJlbW92ZUFsZXJ0KGV2ZW50LCBhbGVydCwgaSkge1xuICAgICAgICBjb25zdCBtZXNzYWdlID0gYEFyZSB5b3Ugc3VyZSB5b3Ugd291bGQgbGlrZSB0byBkZWxldGUgdGhlIFwiJHthbGVydC50aXRsZX1cIiBBbGVydD9gO1xuICAgICAgICBpZiAod2luZG93LmNvbmZpcm0obWVzc2FnZSkpIHtcbiAgICAgICAgICAgIHRoaXMuZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlLmFsZXJ0cy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICB0aGlzLnJlbG9hZEFsZXJ0KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgZXhwb3J0RGF0YSgpIHtcbiAgICAgICAgY29uc3QgZGF0YXNldEluc3RhbmNlU3VtbWFyeSA9IHRoaXMucHJlcGFyZURhdGFzZXRJbnN0YW5jZVN1bW1hcnlGb3JFdmFsdWF0aW9uKCk7XG5cbiAgICAgICAgY29uc3QgZGlhbG9nUmVmID0gdGhpcy5kaWFsb2cub3BlbihFeHBvcnREYXRhQ29tcG9uZW50LCB7XG4gICAgICAgICAgICB3aWR0aDogJzYwMHB4JyxcbiAgICAgICAgICAgIGhlaWdodDogJzUzMHB4JyxcbiAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICBkYXRhc2V0SW5zdGFuY2VTdW1tYXJ5XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyB1cGRhdGVIZWFkaW5nKGV2ZW50KSB7XG4gICAgICAgIGlmICghdGhpcy5kYXNoYm9hcmQuZGlzcGxheVNldHRpbmdzLmhlYWRpbmcpIHtcbiAgICAgICAgICAgIHRoaXMuZGFzaGJvYXJkLmRpc3BsYXlTZXR0aW5ncy5oZWFkaW5nID0ge307XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmRhc2hib2FyZC5kaXNwbGF5U2V0dGluZ3MuaGVhZGluZ1t0aGlzLml0ZW1JbnN0YW5jZUtleV0gPSB0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLmhlYWRpbmdWYWx1ZTtcbiAgICAgICAgdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5fZWRpdGluZyA9IGZhbHNlO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBzZXR1cE5ldHdvcmtDaGFydCgpIHtcbiAgICAgICAgY29uc3Qgbm9kZURhdGEgPSB0aGlzLmRhdGFzZXQuYWxsRGF0YTtcblxuICAgICAgICBjb25zdCBkYXRhc2V0Tm9kZXM6IGFueSA9IFtdO1xuICAgICAgICBjb25zdCBkYXRhc2V0RWRnZXM6IGFueSA9IFtdO1xuXG4gICAgICAgIG5vZGVEYXRhLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgICAgICBjb25zdCBub2RlTGV2ZWxJdGVtOiBhbnkgPSB7fTtcbiAgICAgICAgICAgIGNvbnN0IG5vZGVJdGVtOiBhbnkgPSB7XG4gICAgICAgICAgICAgICAgaWQ6IGl0ZW1bdGhpcy5uZXR3b3JrRGF0YS5ub2RlSWRzXSxcbiAgICAgICAgICAgICAgICBsYWJlbDogaXRlbVt0aGlzLm5ldHdvcmtEYXRhLm5vZGVMYWJlbHNdLFxuICAgICAgICAgICAgICAgIGdyb3VwOiBpdGVtW3RoaXMubmV0d29ya0RhdGEubm9kZUdyb3Vwc11cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmICh0aGlzLm5ldHdvcmtEYXRhLm5vZGVzKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMubmV0d29ya0RhdGEubm9kZXNbbm9kZUl0ZW0uaWRdKSB7XG4gICAgICAgICAgICAgICAgICAgIG5vZGVJdGVtLnggPSB0aGlzLm5ldHdvcmtEYXRhLm5vZGVzW25vZGVJdGVtLmlkXS54O1xuICAgICAgICAgICAgICAgICAgICBub2RlSXRlbS55ID0gdGhpcy5uZXR3b3JrRGF0YS5ub2Rlc1tub2RlSXRlbS5pZF0ueTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0aGlzLm5ldHdvcmtEYXRhLm5vZGVMZXZlbE9wdGlvbnMgJiYgT2JqZWN0LmtleXModGhpcy5uZXR3b3JrRGF0YS5ub2RlTGV2ZWxPcHRpb25zKS5sZW5ndGggJiZcbiAgICAgICAgICAgICAgICB0aGlzLm5ldHdvcmtEYXRhLm5vZGVMZXZlbE9wdGlvbnNbbm9kZUl0ZW0uaWRdKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5uZXR3b3JrRGF0YS5ub2RlTGV2ZWxPcHRpb25zW25vZGVJdGVtLmlkXS5mb3JFYWNoKG9wdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgIG5vZGVMZXZlbEl0ZW1bb3B0aW9uLmtleV0gPSBvcHRpb24udmFsdWU7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkYXRhc2V0Tm9kZXMucHVzaChPYmplY3QuYXNzaWduKG5vZGVMZXZlbEl0ZW0sIG5vZGVJdGVtKSk7XG4gICAgICAgICAgICBpZiAoIXRoaXMubmV0d29ya0RhdGEuZWRnZURhdGFzZXRUaXRsZSkge1xuICAgICAgICAgICAgICAgIGRhdGFzZXRFZGdlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgZnJvbTogaXRlbVt0aGlzLm5ldHdvcmtEYXRhLmZyb21JZHNdLFxuICAgICAgICAgICAgICAgICAgICB0bzogaXRlbVt0aGlzLm5ldHdvcmtEYXRhLnRvSWRzXVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBpZiAodGhpcy5uZXR3b3JrRGF0YS5lZGdlRGF0YXNldFRpdGxlKSB7XG4gICAgICAgICAgICBjb25zdCBkYXRhc2V0SW5zdGFuY2VTdW1tYXJ5ID0ge1xuICAgICAgICAgICAgICAgIGRhdGFzZXRJbnN0YW5jZUlkOiB0aGlzLm5ldHdvcmtEYXRhLmVkZ2VEYXRhc2V0SWQsXG4gICAgICAgICAgICAgICAgZGF0YXNvdXJjZUluc3RhbmNlS2V5OiB0aGlzLm5ldHdvcmtEYXRhLmVkZ2VEYXRhc291cmNlS2V5LFxuICAgICAgICAgICAgICAgIHRyYW5zZm9ybWF0aW9uSW5zdGFuY2VzOiBbXSxcbiAgICAgICAgICAgICAgICBwYXJhbWV0ZXJWYWx1ZXM6IHt9LFxuICAgICAgICAgICAgICAgIHBhcmFtZXRlcnM6IHt9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBlZGdlRGF0YXNldDogYW55ID0gYXdhaXQgdGhpcy5kYXRhc2V0U2VydmljZS5ldmFsdWF0ZURhdGFzZXQoXG4gICAgICAgICAgICAgICAgZGF0YXNldEluc3RhbmNlU3VtbWFyeSxcbiAgICAgICAgICAgICAgICAnMCcsXG4gICAgICAgICAgICAgICAgJzEwMDAwMDAwJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGVkZ2VEYXRhc2V0LmFsbERhdGEuZm9yRWFjaChpdGVtID0+IHtcbiAgICAgICAgICAgICAgICBkYXRhc2V0RWRnZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIGZyb206IGl0ZW1bdGhpcy5uZXR3b3JrRGF0YS5mcm9tSWRzXSxcbiAgICAgICAgICAgICAgICAgICAgdG86IGl0ZW1bdGhpcy5uZXR3b3JrRGF0YS50b0lkc11cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgZGF0YXNldEVkZ2VzLmZvckVhY2goZWRnZSA9PiB7XG4gICAgICAgICAgICBjb25zdCBlZGdlT3B0aW9ucyA9IF8uZmluZCh0aGlzLm5ldHdvcmtEYXRhLmVkZ2VMZXZlbE9wdGlvbnMsIHtmcm9tOiBlZGdlLmZyb20sIHRvOiBlZGdlLnRvfSk7XG4gICAgICAgICAgICBpZiAoZWRnZU9wdGlvbnMgJiYgZWRnZU9wdGlvbnMub3B0aW9ucy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBlZGdlT3B0aW9ucy5vcHRpb25zLmZvckVhY2gob3B0aW9uID0+IHtcbiAgICAgICAgICAgICAgICAgICAgZWRnZVtvcHRpb24ua2V5XSA9IG9wdGlvbi52YWx1ZTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gY3JlYXRlIGFuIGFycmF5IHdpdGggbm9kZXNcbiAgICAgICAgY29uc3Qgbm9kZXMgPSBuZXcgRGF0YVNldChkYXRhc2V0Tm9kZXMpO1xuXG4gICAgICAgIC8vIGNyZWF0ZSBhbiBhcnJheSB3aXRoIGVkZ2VzXG4gICAgICAgIGNvbnN0IGVkZ2VzID0gbmV3IERhdGFTZXQoZGF0YXNldEVkZ2VzKTtcblxuICAgICAgICAvLyBjcmVhdGUgYSBuZXR3b3JrXG4gICAgICAgIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMuaXRlbUluc3RhbmNlS2V5ICsgJ1ZJUycpO1xuICAgICAgICBjb25zdCBkYXRhID0ge1xuICAgICAgICAgICAgbm9kZXMsXG4gICAgICAgICAgICBlZGdlc1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCBvcHRpb25zOiBhbnkgPSB7XG4gICAgICAgICAgICBub2Rlczoge1xuICAgICAgICAgICAgICAgIGZvbnQ6IHtcbiAgICAgICAgICAgICAgICAgICAgbXVsdGk6ICdodG1sJ1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlZGdlczoge30sXG4gICAgICAgICAgICBncm91cHM6IHt9LFxuICAgICAgICAgICAgbGF5b3V0OiB7fVxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IG1hcE9wdGlvblZhbHVlID0gKG9wdGlvbjogYW55LCBuZXR3b3JrVHlwZTogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgICBpZiAob3B0aW9uICYmIE9iamVjdC5rZXlzKG9wdGlvbikubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdHlwZSA9IHZpc05ldHdvcmtPcHRpb25zW25ldHdvcmtUeXBlXVtvcHRpb24ua2V5XS50eXBlO1xuICAgICAgICAgICAgICAgIGxldCB2YWx1ZSA9IG9wdGlvbi52YWx1ZTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBOdW1iZXIodmFsdWUpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gdmFsdWUgPT09ICd0cnVlJztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgb3B0aW9uc1tuZXR3b3JrVHlwZV1bb3B0aW9uLmtleV0gPSB2YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBpZiAodGhpcy5uZXR3b3JrRGF0YS5ub2RlT3B0aW9ucykge1xuICAgICAgICAgICAgdGhpcy5uZXR3b3JrRGF0YS5ub2RlT3B0aW9ucy5mb3JFYWNoKG9wdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgbWFwT3B0aW9uVmFsdWUob3B0aW9uLCAnbm9kZXMnKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMubmV0d29ya0RhdGEuZWRnZU9wdGlvbnMpIHtcbiAgICAgICAgICAgIHRoaXMubmV0d29ya0RhdGEuZWRnZU9wdGlvbnMuZm9yRWFjaChvcHRpb24gPT4ge1xuICAgICAgICAgICAgICAgIG1hcE9wdGlvblZhbHVlKG9wdGlvbiwgJ2VkZ2VzJyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLm5ldHdvcmtEYXRhLm5vZGVHcm91cE9wdGlvbnMgJiYgT2JqZWN0LmtleXModGhpcy5uZXR3b3JrRGF0YS5ub2RlR3JvdXBPcHRpb25zKS5sZW5ndGgpIHtcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKHRoaXMubmV0d29ya0RhdGEubm9kZUdyb3VwT3B0aW9ucykuZm9yRWFjaChncm91cEtleSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5uZXR3b3JrRGF0YS5ub2RlR3JvdXBPcHRpb25zW2dyb3VwS2V5XS5vcHRpb25zLmZvckVhY2gob3B0aW9uID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFvcHRpb25zLmdyb3Vwc1tncm91cEtleV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMuZ3JvdXBzW2dyb3VwS2V5XSA9IHt9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb24gJiYgT2JqZWN0LmtleXMob3B0aW9uKS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMuZ3JvdXBzW2dyb3VwS2V5XVtvcHRpb24ua2V5XSA9IG9wdGlvbi52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBuZXR3b3JrID0gbmV3IE5ldHdvcmsoY29udGFpbmVyLCBkYXRhLCBvcHRpb25zKTtcbiAgICAgICAgdGhpcy5uZXR3b3JrRGF0YS5uZXR3b3JrID0gbmV0d29yaztcbiAgICB9XG5cbiAgICBwdWJsaWMgZXZhbHVhdGVUZXh0RGF0YSh0ZXh0RGF0YSkge1xuICAgICAgICBsZXQgZXZhbHVhdGVkVGV4dERhdGEgPSAnJztcbiAgICAgICAgY29uc3QgZWxlbWVudDogYW55ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gdGhpcy5iaW5kUGFyYW1ldGVyc0luU3RyaW5nKHRleHREYXRhKTtcblxuICAgICAgICBjb25zdCBkYXRhOiBhbnkgPSB7XG4gICAgICAgICAgICBkYXRhU2V0OiB0aGlzLmRhdGFzZXQuYWxsRGF0YVxuICAgICAgICB9O1xuICAgICAgICBfLmZvckVhY2godGhpcy5kYXRhc2V0LmFsbERhdGFbMF0gfHwgW10sICh2YWx1ZSwga2V5KSA9PiB7XG4gICAgICAgICAgICBkYXRhW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgS2luaWJpbmQgPSB3aW5kb3cuS2luaWJpbmQ7XG4gICAgICAgIEtpbmliaW5kLmNvbmZpZyA9IHtcbiAgICAgICAgICAgIHByZWZpeDogJ2QnLFxuICAgICAgICAgICAgdGVtcGxhdGVEZWxpbWl0ZXJzOiBbJ1tbJywgJ11dJ11cbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgYmluZCA9IG5ldyBLaW5pYmluZChlbGVtZW50LCBkYXRhKTtcbiAgICAgICAgY29uc3QgYm91bmRIVE1MID0gYmluZC5ib3VuZENvbnRleHQuZWxzWzBdLmlubmVySFRNTDtcbiAgICAgICAgZXZhbHVhdGVkVGV4dERhdGEgPSB0aGlzLnNhbml0aXplci5zYW5pdGl6ZSgxLCBib3VuZEhUTUwpO1xuICAgICAgICBlbGVtZW50LnJlbW92ZSgpO1xuICAgICAgICByZXR1cm4gZXZhbHVhdGVkVGV4dERhdGE7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHNldENoYXJ0RGF0YSgpIHtcbiAgICAgICAgaWYgKHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUueEF4aXMgJiYgdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS55QXhpcykge1xuICAgICAgICAgICAgbGV0IGRhdGFzZXREYXRhID0gdGhpcy5kYXRhc2V0LmFsbERhdGE7XG4gICAgICAgICAgICBpZiAodGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5saW1pdCkge1xuICAgICAgICAgICAgICAgIGRhdGFzZXREYXRhID0gZGF0YXNldERhdGEuc2xpY2UoMCwgdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5saW1pdCk7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUuY29tYmluZVJlbWFpbmluZyAmJiAhdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5zZXJpZXNDb2x1bW4pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVtYWluaW5nRGF0YSA9IGF3YWl0IHRoaXMuZXZhbHVhdGVEYXRhc2V0KDEwMDAwMDAwLCAwKTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb21iaW5lZCA9IFtdO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJlbWFpbmluZ0RhdGEuYWxsRGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiB0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLmxpbWl0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tYmluZWQucHVzaChyZW1haW5pbmdEYXRhLmFsbERhdGFbaV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcHVzaE9iamVjdCA9IHt9O1xuICAgICAgICAgICAgICAgICAgICBwdXNoT2JqZWN0W3RoaXMuZGFzaGJvYXJkSXRlbVR5cGUueEF4aXNdID0gdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5jb21iaW5lUmVtYWluZ2luZ0xhYmVsIHx8ICdSZW1haW5pbmcnO1xuICAgICAgICAgICAgICAgICAgICBwdXNoT2JqZWN0W3RoaXMuZGFzaGJvYXJkSXRlbVR5cGUueUF4aXNdID0gXy5zdW1CeShjb21iaW5lZCwgcmVtYWluaW5nSXRlbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gTnVtYmVyKHJlbWFpbmluZ0l0ZW1bdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS55QXhpc10pO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgZGF0YXNldERhdGEucHVzaChwdXNoT2JqZWN0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBkYXRhOiBhbnk7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5zZXJpZXNDb2x1bW4pIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5kYXNoYm9hcmRJdGVtVHlwZS50eXBlICE9PSAncGllJyAmJiB0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLnR5cGUgIT09ICdkb3VnaG51dCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YSA9IF8ubWFwKGRhdGFzZXREYXRhLCBpdGVtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7eDogaXRlbVt0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLnhBeGlzXSwgeTogaXRlbVt0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLnlBeGlzXX07XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGRhdGEgPSBfLm1hcChkYXRhc2V0RGF0YSwgaXRlbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXRlbVt0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLnlBeGlzXTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5jaGFydERhdGEgPSBbXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogXy5maW5kKHRoaXMuZmlsdGVyRmllbGRzLCB7bmFtZTogdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS54QXhpc30pLnRpdGxlLFxuICAgICAgICAgICAgICAgICAgICAgICAgZmlsbDogISF0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLmZpbGwsXG4gICAgICAgICAgICAgICAgICAgICAgICBib3JkZXJDb2xvcjogKHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUudHlwZSA9PT0gJ3BpZScgfHwgdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS50eXBlID09PSAnZG91Z2hudXQnKSA/IGNocm9tYSgnd2hpdGUnKS5hbHBoYSgwLjIpLmhleCgpIDogdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5ib3JkZXJDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS50eXBlID09PSAnbGluZScgP1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChBcnJheS5pc0FycmF5KHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUuYm9yZGVyQ29sb3IpID8gXy5tYXAodGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5ib3JkZXJDb2xvciwgY29sb3VyID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNocm9tYShjb2xvdXIgfHwgJ2JsYWNrJykuYWxwaGEoMC41KS5oZXgoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSA6IGNocm9tYSh0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLmJvcmRlckNvbG9yIHx8ICdibGFjaycpLmFscGhhKDAuNSkuaGV4KCkpIDogdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5iYWNrZ3JvdW5kQ29sb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZW5zaW9uOiAwLjIsXG4gICAgICAgICAgICAgICAgICAgICAgICBwb2ludEJhY2tncm91bmRDb2xvcjogdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5ib3JkZXJDb2xvciA/IHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUuYm9yZGVyQ29sb3JbMF0gOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRCb3JkZXJDb2xvcjogdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5ib3JkZXJDb2xvciA/IHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUuYm9yZGVyQ29sb3JbMF0gOiBudWxsXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBdO1xuICAgICAgICAgICAgICAgIHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUubGFiZWxzID0gXy5tYXAoZGF0YXNldERhdGEsIGl0ZW0gPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXRlbVt0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLnhBeGlzXTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2hhcnREYXRhID0gW107XG4gICAgICAgICAgICAgICAgY29uc3Qgc2VyaWVzID0gXy51bmlxKF8ubWFwKGRhdGFzZXREYXRhLCB0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLnNlcmllc0NvbHVtbikpO1xuICAgICAgICAgICAgICAgIHNlcmllcy5mb3JFYWNoKCh2YWx1ZSwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2VyaWVzUmVzdWx0cyA9IF8uZmlsdGVyKGRhdGFzZXREYXRhLCBhbGxEYXRhID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhbGxEYXRhW3RoaXMuZGFzaGJvYXJkSXRlbVR5cGUuc2VyaWVzQ29sdW1uXSA9PT0gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgIGNoYXJ0RGF0YS5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGE6IF8ubWFwKHNlcmllc1Jlc3VsdHMsIGl0ZW0gPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7eDogaXRlbVt0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLnhBeGlzXSwgeTogaXRlbVt0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLnlBeGlzXX07XG4gICAgICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw6ICEhdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5maWxsLFxuICAgICAgICAgICAgICAgICAgICAgICAgYm9yZGVyQ29sb3I6IHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUuYm9yZGVyQ29sb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUudHlwZSA9PT0gJ2xpbmUnID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoQXJyYXkuaXNBcnJheSh0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLmJvcmRlckNvbG9yKSA/IF8ubWFwKHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUuYm9yZGVyQ29sb3IsIGNvbG91ciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjaHJvbWEoY29sb3VyIHx8ICdibGFjaycpLmFscGhhKDAuNSkuaGV4KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkgOiBjaHJvbWEodGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5ib3JkZXJDb2xvciB8fCAnYmxhY2snKS5hbHBoYSgwLjUpLmhleCgpKSA6IHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUuYmFja2dyb3VuZENvbG9yW2luZGV4XSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRlbnNpb246IDAuMixcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvaW50QmFja2dyb3VuZENvbG9yOiB0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLmJvcmRlckNvbG9yW2luZGV4XSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvaW50Qm9yZGVyQ29sb3I6IHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUuYm9yZGVyQ29sb3JbaW5kZXhdXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHRoaXMuY2hhcnREYXRhID0gY2hhcnREYXRhO1xuICAgICAgICAgICAgICAgIHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUubGFiZWxzID0gXy51bmlxKF8ubWFwKGRhdGFzZXREYXRhLCBpdGVtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW1bdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS54QXhpc107XG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5kYXNoYm9hcmRJdGVtVHlwZS50cmVuZExpbmUpIHtcbiAgICAgICAgICAgICAgICBsZXQgdHJlbmRMaW5lID0gW107XG4gICAgICAgICAgICAgICAgbGV0IHRyZW5kTGFiZWwgPSAnVHJlbmQnO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLnRyZW5kTGluZSA9PT0gJ2F2ZXJhZ2UnKSB7XG4gICAgICAgICAgICAgICAgICAgIHRyZW5kTGFiZWwgPSAnQXZlcmFnZSc7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRyZW5kRGF0YSA9IFtdO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNoYXJ0RGF0YS5mb3JFYWNoKGRhdGFJdGVtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyZW5kRGF0YS5wdXNoKF8ubWFwKGRhdGFJdGVtLmRhdGEsICd5JykpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYXZlcmFnZSA9IF8uZmxhdE1hcCh0cmVuZERhdGEpLnJlZHVjZSgocCwgYykgPT4gcCArIGMsIDApIC8gXy5mbGF0TWFwKHRyZW5kRGF0YSkubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICB0cmVuZExpbmUgPSBfLmZpbGwoXy5yYW5nZSgwLCBfLmZsYXRNYXAodHJlbmREYXRhKS5sZW5ndGgpLCBhdmVyYWdlLCAwLCBfLmZsYXRNYXAodHJlbmREYXRhKS5sZW5ndGgpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5kYXNoYm9hcmRJdGVtVHlwZS50cmVuZExpbmUgPT09ICdsb2dhcml0aG1pYycgfHxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS50cmVuZExpbmUgPT09ICdsaW5lYXInIHx8XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUudHJlbmRMaW5lID09PSAncG93ZXInIHx8XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUudHJlbmRMaW5lID09PSAnZXhwb25lbnRpYWwnKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdHJlbmRMaW5lRGF0YSA9IF8ubWFwKHRoaXMuZGF0YXNldC5hbGxEYXRhLCAoaXRlbSwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7eDogaW5kZXggKyAxLCB5OiBpdGVtW3RoaXMuZGFzaGJvYXJkSXRlbVR5cGUueUF4aXNdfTtcbiAgICAgICAgICAgICAgICAgICAgfSkuZmlsdGVyKCh7eCwgeX0pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZW9mIHggPT09IHR5cGVvZiB5ICYmICAvLyBmaWx0ZXIgb3V0IG9uZSBzdHJpbmcgJiBvbmUgbnVtYmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIWlzTmFOKHgpICYmICAgICAgICAgICAgICAvLyBmaWx0ZXIgb3V0IGBOYU5gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIWlzTmFOKHkpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgTWF0aC5hYnMoeCkgIT09IEluZmluaXR5ICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgTWF0aC5hYnMoeSkgIT09IEluZmluaXR5XG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9KS5tYXAoKHt4LCB5fSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFt4LCB5XTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdHJlbmRMaW5lUmVzdWx0cyA9IHJlZ3Jlc3Npb25bdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS50cmVuZExpbmVdKHRyZW5kTGluZURhdGEpO1xuICAgICAgICAgICAgICAgICAgICB0cmVuZExpbmUgPSB0cmVuZExpbmVSZXN1bHRzLnBvaW50cy5tYXAoKFt4LCB5XSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRyZW5kTGluZSA9IF8ubWFwKHRoaXMuZGF0YXNldC5hbGxEYXRhLCBpdGVtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpdGVtW3RoaXMuZGFzaGJvYXJkSXRlbVR5cGUudHJlbmRMaW5lXTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHRyZW5kTGFiZWwgPSBfLmZpbmQodGhpcy5maWx0ZXJGaWVsZHMsIHtuYW1lOiB0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLnRyZW5kTGluZX0pLnRpdGxlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMuY2hhcnREYXRhLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICB0eXBlOiAnbGluZScsXG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IHRyZW5kTGluZSxcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHRyZW5kTGFiZWwsXG4gICAgICAgICAgICAgICAgICAgIGJvcmRlckNvbG9yOiB0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLnRyZW5kTGluZUNvbG91cixcbiAgICAgICAgICAgICAgICAgICAgZmlsbDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIG9yZGVyOiAtMSxcbiAgICAgICAgICAgICAgICAgICAgdGVuc2lvbjogMC4xNSxcbiAgICAgICAgICAgICAgICAgICAgcG9pbnRCYWNrZ3JvdW5kQ29sb3I6IHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUudHJlbmRMaW5lQ29sb3VyLFxuICAgICAgICAgICAgICAgICAgICBwb2ludEJvcmRlckNvbG9yOiB0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLnRyZW5kTGluZUNvbG91clxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIHVwZGF0ZUltYWdlRGF0YSgpIHtcbiAgICAgICAgdGhpcy5pbWFnZURhdGEuc291cmNlID0gdGhpcy5pbWFnZURhdGEuY29sdW1uID8gdGhpcy5kYXRhc2V0LmFsbERhdGFbMF1bdGhpcy5pbWFnZURhdGEuY29sdW1uXSA6IG51bGw7XG4gICAgfVxuXG4gICAgcHVibGljIHVwZGF0ZU1ldHJpY0RhdGFWYWx1ZXMoKSB7XG4gICAgICAgIGlmICh0aGlzLm1ldHJpYy5tYWluKSB7XG4gICAgICAgICAgICB0aGlzLm1ldHJpYy5tYWluVmFsdWUgPSBfLmlzTmFOKE51bWJlcih0aGlzLmRhdGFzZXQuYWxsRGF0YVswXVt0aGlzLm1ldHJpYy5tYWluXSkpID8gdGhpcy5kYXRhc2V0LmFsbERhdGFbMF1bdGhpcy5tZXRyaWMubWFpbl0gOiBOdW1iZXIodGhpcy5kYXRhc2V0LmFsbERhdGFbMF1bdGhpcy5tZXRyaWMubWFpbl0pO1xuICAgICAgICAgICAgdGhpcy5tZXRyaWMudGl0bGUgPSBfLnN0YXJ0Q2FzZSh0aGlzLm1ldHJpYy5tYWluKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLm1ldHJpYy5zdWJNZXRyaWMpIHtcbiAgICAgICAgICAgIHRoaXMubWV0cmljLnN1YlZhbHVlID0gTnVtYmVyKHRoaXMuZGF0YXNldC5hbGxEYXRhWzBdW3RoaXMubWV0cmljLnN1Yk1ldHJpY10pO1xuICAgICAgICAgICAgdGhpcy5tZXRyaWMuc3ViVGl0bGUgPSBfLnN0YXJ0Q2FzZSh0aGlzLm1ldHJpYy5zdWJNZXRyaWMpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMubWV0cmljLnNob3dTdWJDaGFuZ2UpIHtcbiAgICAgICAgICAgIHRoaXMubWV0cmljLmRpZmZlcmVuY2UgPSBNYXRoLmFicyh0aGlzLm1ldHJpYy5tYWluVmFsdWUgLSB0aGlzLm1ldHJpYy5zdWJWYWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgY2FsbFRvQWN0aW9uTGluayhjdGEsIGRhdGFJdGVtPykge1xuICAgICAgICBsZXQgdXJsOiBzdHJpbmcgPSBudWxsO1xuXG4gICAgICAgIGlmIChjdGEudHlwZSA9PT0gJ2Rhc2hib2FyZCcpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IF8ucGlja0J5KGN0YS5wYXJhbWV0ZXJzLCAodmFsdWUsIGtleSkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiAhXy5zdGFydHNXaXRoKGtleSwgJ2N1c3RvbS0nKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBjb25zdCBkYXRhID0gZGF0YUl0ZW0gfHwgdGhpcy5kYXNoYm9hcmQubGF5b3V0U2V0dGluZ3MucGFyYW1ldGVycztcblxuICAgICAgICAgICAgT2JqZWN0LmtleXMocGFyYW1zKS5mb3JFYWNoKHBhcmFtS2V5ID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgdmFsdWUgPSB0aGlzLmJpbmRQYXJhbWV0ZXJzSW5TdHJpbmcocGFyYW1zW3BhcmFtS2V5XSwgZGF0YSk7XG4gICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgd2UgaGF2ZSBhbnkgY29sdW1uIGVnLiBbWyBdXSB2YWx1ZXMgbmVlZGluZyBtYXBwaW5nXG4gICAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzLm1hcENvbHVtblRvVmFsdWUodmFsdWUsIGRhdGEpO1xuXG4gICAgICAgICAgICAgICAgcGFyYW1zW3BhcmFtS2V5XSA9IHZhbHVlO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjb25zdCB1cmxQYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHBhcmFtcykudG9TdHJpbmcoKTtcbiAgICAgICAgICAgIHVybCA9IGAvZGFzaGJvYXJkcy92aWV3LyR7Y3RhLnZhbHVlfSR7dGhpcy5hZG1pbiA/ICc/YT10cnVlJicgOiAnPyd9JHt1cmxQYXJhbXN9YDtcbiAgICAgICAgfSBlbHNlIGlmIChjdGEudHlwZSA9PT0gJ2N1c3RvbScpIHtcbiAgICAgICAgICAgIHVybCA9IGN0YS5saW5rO1xuXG4gICAgICAgICAgICBjb25zdCBkYXRhID0gZGF0YUl0ZW0gfHwgdGhpcy5kYXNoYm9hcmQubGF5b3V0U2V0dGluZ3MucGFyYW1ldGVycztcblxuICAgICAgICAgICAgdXJsID0gdGhpcy5iaW5kUGFyYW1ldGVyc0luU3RyaW5nKHVybCwgZGF0YSk7XG4gICAgICAgICAgICAvLyBDaGVjayBpZiB3ZSBoYXZlIGFueSBjb2x1bW4gZWcuIFtbIF1dIHZhbHVlcyBuZWVkaW5nIG1hcHBpbmdcbiAgICAgICAgICAgIHVybCA9IHRoaXMubWFwQ29sdW1uVG9WYWx1ZSh1cmwsIGRhdGEpO1xuICAgICAgICB9IGVsc2UgaWYgKGN0YS50eXBlID09PSAnZmVlZCcpIHtcbiAgICAgICAgICAgIHVybCA9IGAvZGFwLWRhdGEtZmVlZHMvJHtjdGEudmFsdWV9YDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh1cmwpIHtcbiAgICAgICAgICAgIGlmICghY3RhLndpbmRvd0xvY2F0aW9uIHx8IGN0YS53aW5kb3dMb2NhdGlvbiA9PT0gJ0VYSVNUSU5HJykge1xuICAgICAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gdXJsO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpO1xuICAgICAgICAgICAgICAgIGEuaHJlZiA9IHVybDtcbiAgICAgICAgICAgICAgICBhLnNldEF0dHJpYnV0ZSgndGFyZ2V0JywgJ19ibGFuaycpO1xuICAgICAgICAgICAgICAgIGEuc2V0QXR0cmlidXRlKCdyZWwnLCAnbm9vcGVuZXIgbm9yZWZlcnJlcicpO1xuICAgICAgICAgICAgICAgIGEuY2xpY2soKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBiaW5kUGFyYW1ldGVyc0luU3RyaW5nKHNlYXJjaFN0cmluZywgZGF0YT8pIHtcbiAgICAgICAgaWYgKCFkYXRhKSB7XG4gICAgICAgICAgICBkYXRhID0gdGhpcy5kYXNoYm9hcmQubGF5b3V0U2V0dGluZ3MucGFyYW1ldGVycztcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2VhcmNoU3RyaW5nKSB7XG4gICAgICAgICAgICBjb25zdCBtYXRjaGVzID0gc2VhcmNoU3RyaW5nLm1hdGNoKC9cXHtcXHsoLio/KVxcfVxcfS9nKSB8fCBbXTtcbiAgICAgICAgICAgIG1hdGNoZXMuZm9yRWFjaChleHAgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGV4cFZhbHVlID0gZXhwLnJlcGxhY2UoJ3t7JywgJycpLnJlcGxhY2UoJ319JywgJycpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcmFtZXRlciA9IGRhdGEgPyBkYXRhW2V4cFZhbHVlXSA6IG51bGw7XG4gICAgICAgICAgICAgICAgaWYgKHBhcmFtZXRlcikge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IF8uaXNQbGFpbk9iamVjdChwYXJhbWV0ZXIpID8gcGFyYW1ldGVyLnZhbHVlIDogcGFyYW1ldGVyO1xuICAgICAgICAgICAgICAgICAgICBzZWFyY2hTdHJpbmcgPSBzZWFyY2hTdHJpbmcucmVwbGFjZShleHAsIHZhbHVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBzZWFyY2hTdHJpbmc7XG4gICAgfVxuXG4gICAgcHVibGljIGluY3JlYXNlT2Zmc2V0KCkge1xuICAgICAgICB0aGlzLnBhZ2UgPSB0aGlzLnBhZ2UgKyAxO1xuICAgICAgICB0aGlzLm9mZnNldCA9ICh0aGlzLmxpbWl0ICogdGhpcy5wYWdlKSAtIHRoaXMubGltaXQ7XG4gICAgICAgIHRoaXMuZXZhbHVhdGUoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZGVjcmVhc2VPZmZzZXQoKSB7XG4gICAgICAgIHRoaXMucGFnZSA9IHRoaXMucGFnZSA8PSAxID8gMSA6IHRoaXMucGFnZSAtIDE7XG4gICAgICAgIHRoaXMub2Zmc2V0ID0gKHRoaXMubGltaXQgKiB0aGlzLnBhZ2UpIC0gdGhpcy5saW1pdDtcbiAgICAgICAgdGhpcy5ldmFsdWF0ZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBwYWdlU2l6ZUNoYW5nZSh2YWx1ZSkge1xuICAgICAgICB0aGlzLmxpbWl0ID0gdmFsdWU7XG5cbiAgICAgICAgLy8gSWYgd2UgY2hhbmdlIHRoZSB0YWJsZSBsaW1pdCAtIHdlIGFsc28gd2FudCB0byBzYXZlIHRoZSBkYXNoYm9hcmQgYXV0b21hdGljYWxseSB0byBrZWVwIHRoZSBjaGFuZ2VzXG4gICAgICAgIHRoaXMudGFidWxhci5saW1pdCA9IHRoaXMubGltaXQ7XG4gICAgICAgIHRoaXMuZGFzaGJvYXJkU2VydmljZS5zYXZlRGFzaGJvYXJkKHRoaXMuZGFzaGJvYXJkKTtcblxuICAgICAgICB0aGlzLmV2YWx1YXRlKHRydWUpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzb3J0SGVhZGVyKGNvbHVtbk9iamVjdCkge1xuICAgICAgICBjb25zdCBjb2x1bW4gPSBjb2x1bW5PYmplY3QubmFtZTtcbiAgICAgICAgbGV0IGRpcmVjdGlvbiA9ICcnO1xuXG4gICAgICAgIGNvbnN0IGV4aXN0aW5nTXVsdGlTb3J0ID0gXy5maW5kKHRoaXMuZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlLnRyYW5zZm9ybWF0aW9uSW5zdGFuY2VzLCB7dHlwZTogJ211bHRpc29ydCd9KTtcblxuICAgICAgICBsZXQgZXhpc3RpbmdDb2x1bW5JbmRleCA9IC0xO1xuICAgICAgICBpZiAoZXhpc3RpbmdNdWx0aVNvcnQpIHtcbiAgICAgICAgICAgIGV4aXN0aW5nQ29sdW1uSW5kZXggPSBfLmZpbmRJbmRleChleGlzdGluZ011bHRpU29ydC5jb25maWcuc29ydHMsIHtmaWVsZE5hbWU6IGNvbHVtbn0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFleGlzdGluZ011bHRpU29ydCB8fCBleGlzdGluZ0NvbHVtbkluZGV4ID09PSAtMSkge1xuICAgICAgICAgICAgZGlyZWN0aW9uID0gJ2FzYyc7XG4gICAgICAgIH0gZWxzZSBpZiAoZXhpc3RpbmdDb2x1bW5JbmRleCA+PSAwICYmIGV4aXN0aW5nTXVsdGlTb3J0LmNvbmZpZy5zb3J0c1tleGlzdGluZ0NvbHVtbkluZGV4XS5kaXJlY3Rpb24gPT09ICdhc2MnKSB7XG4gICAgICAgICAgICBkaXJlY3Rpb24gPSAnZGVzYyc7XG4gICAgICAgIH0gZWxzZSBpZiAoZXhpc3RpbmdDb2x1bW5JbmRleCA+PSAwICYmIGV4aXN0aW5nTXVsdGlTb3J0LmNvbmZpZy5zb3J0c1tleGlzdGluZ0NvbHVtbkluZGV4XS5kaXJlY3Rpb24gPT09ICdkZXNjJykge1xuICAgICAgICAgICAgZGlyZWN0aW9uID0gJyc7XG4gICAgICAgIH0gZWxzZSBpZiAoZXhpc3RpbmdDb2x1bW5JbmRleCA+PSAwICYmICFleGlzdGluZ011bHRpU29ydC5jb25maWcuc29ydHNbZXhpc3RpbmdDb2x1bW5JbmRleF0uZGlyZWN0aW9uKSB7XG4gICAgICAgICAgICBkaXJlY3Rpb24gPSAnYXNjJztcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbHVtbk9iamVjdC5kaXJlY3Rpb24gPSBkaXJlY3Rpb247XG5cbiAgICAgICAgaWYgKGV4aXN0aW5nTXVsdGlTb3J0KSB7XG4gICAgICAgICAgICBjb25zdCBleGlzdGluZ0luZGV4ID0gXy5maW5kSW5kZXgoZXhpc3RpbmdNdWx0aVNvcnQuY29uZmlnLnNvcnRzLCB7ZmllbGROYW1lOiBjb2x1bW59KTtcbiAgICAgICAgICAgIGlmIChkaXJlY3Rpb24pIHtcbiAgICAgICAgICAgICAgICBpZiAoZXhpc3RpbmdJbmRleCA+IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nTXVsdGlTb3J0LmNvbmZpZy5zb3J0c1tleGlzdGluZ0luZGV4XSA9IHtmaWVsZE5hbWU6IGNvbHVtbiwgZGlyZWN0aW9ufTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBleGlzdGluZ011bHRpU29ydC5jb25maWcuc29ydHMucHVzaCh7ZmllbGROYW1lOiBjb2x1bW4sIGRpcmVjdGlvbn0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZXhpc3RpbmdNdWx0aVNvcnQuY29uZmlnLnNvcnRzLnNwbGljZShleGlzdGluZ0luZGV4LCAxKTtcbiAgICAgICAgICAgICAgICBpZiAoIWV4aXN0aW5nTXVsdGlTb3J0LmNvbmZpZy5zb3J0cy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgXy5yZW1vdmUodGhpcy5kYXNoYm9hcmREYXRhc2V0SW5zdGFuY2UudHJhbnNmb3JtYXRpb25JbnN0YW5jZXMsIHt0eXBlOiAnbXVsdGlzb3J0J30pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChkaXJlY3Rpb24pIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRhc2hib2FyZERhdGFzZXRJbnN0YW5jZS50cmFuc2Zvcm1hdGlvbkluc3RhbmNlcy5wdXNoKFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnbXVsdGlzb3J0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZzoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvcnRzOiBbe2ZpZWxkTmFtZTogY29sdW1uLCBkaXJlY3Rpb259XVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZXZhbHVhdGUodHJ1ZSk7XG4gICAgfVxuXG4gICAgcHVibGljIGNoYW5nZURhdGVUeXBlKGV2ZW50LCBwYXJhbWV0ZXIsIHZhbHVlKSB7XG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBwYXJhbWV0ZXIuX2RhdGVUeXBlID0gdmFsdWU7XG4gICAgICAgIHRoaXMucmVsb2FkV2lkZ2V0KCk7XG4gICAgfVxuXG4gICAgcHVibGljIHVwZGF0ZVBlcmlvZFZhbHVlKHZhbHVlLCBwZXJpb2QsIHBhcmFtZXRlcikge1xuICAgICAgICBwYXJhbWV0ZXIudmFsdWUgPSBgJHt2YWx1ZX1fJHtwZXJpb2R9X0FHT2A7XG4gICAgICAgIHRoaXMucmVsb2FkV2lkZ2V0KCk7XG4gICAgfVxuXG4gICAgcHVibGljIGJvb2xlYW5VcGRhdGUoZXZlbnQsIHBhcmFtZXRlcikge1xuICAgICAgICBwYXJhbWV0ZXIudmFsdWUgPSBldmVudC5jaGVja2VkO1xuICAgICAgICB0aGlzLnJlbG9hZFdpZGdldCgpO1xuICAgIH1cblxuICAgIHB1YmxpYyByZWxvYWRXaWRnZXQoKSB7XG4gICAgICAgIGNvbnN0IHBhcmFtZXRlclZhbHVlczogYW55ID0ge307XG4gICAgICAgIF8uZm9yRWFjaCh0aGlzLmdlbmVyYWwud2lkZ2V0UGFyYW1ldGVycywgcGFyYW0gPT4ge1xuICAgICAgICAgICAgcGFyYW1ldGVyVmFsdWVzW3BhcmFtLm5hbWVdID0gcGFyYW0udmFsdWU7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuZXZhbHVhdGUoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIG1hcENvbHVtblRvVmFsdWUoc2VhcmNoU3RyaW5nLCBkYXRhKSB7XG4gICAgICAgIGlmIChzZWFyY2hTdHJpbmcpIHtcbiAgICAgICAgICAgIGNvbnN0IG1hdGNoZXMgPSBzZWFyY2hTdHJpbmcubWF0Y2goL1xcW1xcWyguKj8pXFxdXFxdL2cpIHx8IFtdO1xuICAgICAgICAgICAgbWF0Y2hlcy5mb3JFYWNoKGV4cCA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXhwVmFsdWUgPSBleHAucmVwbGFjZSgnW1snLCAnJykucmVwbGFjZSgnXV0nLCAnJyk7XG4gICAgICAgICAgICAgICAgbGV0IHZhbHVlID0gZGF0YSA/IGRhdGFbZXhwVmFsdWVdIDogbnVsbDtcbiAgICAgICAgICAgICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBfLmlzUGxhaW5PYmplY3QodmFsdWUpID8gdmFsdWUuaW5pdGlhbFZhbHVlIDogdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIHNlYXJjaFN0cmluZyA9IHNlYXJjaFN0cmluZy5yZXBsYWNlKGV4cCwgdmFsdWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHNlYXJjaFN0cmluZztcbiAgICB9XG5cbiAgICBwcml2YXRlIGV2YWx1YXRlKHJlc2V0UGFnZXI/KSB7XG4gICAgICAgIGlmIChyZXNldFBhZ2VyKSB7XG4gICAgICAgICAgICB0aGlzLnJlc2V0UGFnZXIoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGl0ZW1FbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5pdGVtSW5zdGFuY2VLZXkpO1xuICAgICAgICBpZiAoaXRlbUVsZW1lbnQpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcmVudEVsZW1lbnQgPSBpdGVtRWxlbWVudC5jbG9zZXN0KCcuZ3JpZC1zdGFjay1pdGVtJyk7XG4gICAgICAgICAgICBwYXJlbnRFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ2l0ZW0tZGlzYWJsZWQnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmdyaWQgJiYgXy5pc0Z1bmN0aW9uKHRoaXMuZ3JpZC5tYWtlRWxlbWVudCkpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZ3JpZC5tYWtlRWxlbWVudChpdGVtRWxlbWVudCk7XG4gICAgICAgICAgICB9LCAwKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMubG9hZGluZ0l0ZW0gPSB0cnVlO1xuICAgICAgICB0aGlzLmhpZGRlbkNvbHVtbnMgPSB7fTtcblxuICAgICAgICByZXR1cm4gdGhpcy5ldmFsdWF0ZURhdGFzZXQoKS50aGVuKGRhdGEgPT4ge1xuICAgICAgICAgICAgaWYgKE9iamVjdC5rZXlzKHRoaXMudGFibGVDZWxscykubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgT2JqZWN0LmtleXModGhpcy50YWJsZUNlbGxzKS5mb3JFYWNoKHRhYmxlQ2VsbCA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0YWJsZUNlbGwgIT09ICdjb2x1bW4nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhLmFsbERhdGEubWFwKChpdGVtLCBpbmRleCkgPT4ge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKGl0ZW1bdGFibGVDZWxsXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2VsbERhdGEgPSB0aGlzLnRhYmxlQ2VsbHNbdGFibGVDZWxsXS5kYXRhO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHRoaXMudGFibGVDZWxsc1t0YWJsZUNlbGxdLnR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ251bWJlcic6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2VsbE51bWJlciA9IHBhcnNlRmxvYXQoU3RyaW5nKGl0ZW1bdGFibGVDZWxsXSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1bdGFibGVDZWxsXSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2VsbFZhbHVlOiBjZWxsTnVtYmVyLnRvRml4ZWQoY2VsbERhdGEuZGVjaW1hbCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluaXRpYWxWYWx1ZTogaXRlbVt0YWJsZUNlbGxdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2N1cnJlbmN5JzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgY2VsbEN1cnJlbmN5OiBhbnkgPSBwYXJzZUZsb2F0KFN0cmluZyhpdGVtW3RhYmxlQ2VsbF0pKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjZWxsRGF0YS50aG91c2FuZHNTZXBhcmF0b3IgJiYgKGNlbGxEYXRhLmN1cnJlbmN5ICYmIGNlbGxEYXRhLmN1cnJlbmN5LnZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjZWxsQ3VycmVuY3kgPSBjZWxsQ3VycmVuY3kudG9Mb2NhbGVTdHJpbmcoJ2VuLUdCJywge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6ICdjdXJyZW5jeScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW5jeTogY2VsbERhdGEuY3VycmVuY3kudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW5pbXVtRnJhY3Rpb25EaWdpdHM6IGNlbGxEYXRhLmRlY2ltYWwgfHwgMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjZWxsQ3VycmVuY3kgPSBjZWxsQ3VycmVuY3kudG9GaXhlZChjZWxsRGF0YS5kZWNpbWFsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNlbGxEYXRhLnRob3VzYW5kc1NlcGFyYXRvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2VsbEN1cnJlbmN5ID0gTnVtYmVyKGNlbGxDdXJyZW5jeSkudG9Mb2NhbGVTdHJpbmcoJ2VuLUdCJywge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbmltdW1GcmFjdGlvbkRpZ2l0czogY2VsbERhdGEuZGVjaW1hbCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2VsbERhdGEuY3VycmVuY3kgJiYgY2VsbERhdGEuY3VycmVuY3kudmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNlbGxDdXJyZW5jeSA9IGAke2NlbGxEYXRhLmN1cnJlbmN5LnN5bWJvbH0ke2NlbGxDdXJyZW5jeX1gO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbVt0YWJsZUNlbGxdID0ge2NlbGxWYWx1ZTogY2VsbEN1cnJlbmN5LCBpbml0aWFsVmFsdWU6IGl0ZW1bdGFibGVDZWxsXX07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdwZXJjZW50YWdlJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgY2VsbFBlcmNlbnQ6IGFueSA9IE51bWJlcihpdGVtW3RhYmxlQ2VsbF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZvcm1hdHRlciA9IG5ldyBJbnRsLk51bWJlckZvcm1hdCgnZW4tR0InLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiAncGVyY2VudCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbmltdW1GcmFjdGlvbkRpZ2l0czogY2VsbERhdGEuZGVjaW1hbCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2VsbFBlcmNlbnQgPSBmb3JtYXR0ZXIuZm9ybWF0KGNlbGxQZXJjZW50KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY2VsbERhdGEudGhvdXNhbmRzU2VwYXJhdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNlbGxQZXJjZW50ID0gY2VsbFBlcmNlbnQucmVwbGFjZSgnLCcsICcnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtW3RhYmxlQ2VsbF0gPSB7Y2VsbFZhbHVlOiBjZWxsUGVyY2VudCwgaW5pdGlhbFZhbHVlOiBpdGVtW3RhYmxlQ2VsbF19O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnZGF0ZXRpbWUnOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRhdGVNb21lbnQgPSBtb21lbnQoaXRlbVt0YWJsZUNlbGxdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkYXRlRm9ybWF0ID0gY2VsbERhdGEuZGF0ZUZvcm1hdCA9PT0gJ251bGwnID8gJycgOiBjZWxsRGF0YS5kYXRlRm9ybWF0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRpbWVGb3JtYXQgPSBjZWxsRGF0YS50aW1lRm9ybWF0ID09PSAnbnVsbCcgPyAnJyA6IGNlbGxEYXRhLnRpbWVGb3JtYXQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtW3RhYmxlQ2VsbF0gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNlbGxWYWx1ZTogZGF0ZU1vbWVudC5mb3JtYXQoZGF0ZUZvcm1hdCArICcgJyArIHRpbWVGb3JtYXQpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbml0aWFsVmFsdWU6IGl0ZW1bdGFibGVDZWxsXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdjb21wYXJpc29uJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb21wYXJpc29uQ29sdW1uID0gdGhpcy50YWJsZUNlbGxzW3RhYmxlQ2VsbF0uZGF0YS5jb21wYXJpc29uQ29sdW1uO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGluaXRpYWxWYWx1ZSA9IF8uaXNQbGFpbk9iamVjdChpdGVtW3RhYmxlQ2VsbF0pID8gaXRlbVt0YWJsZUNlbGxdLmluaXRpYWxWYWx1ZSA6IGl0ZW1bdGFibGVDZWxsXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb21wYXJpc29uVmFsdWUgPSBfLmlzUGxhaW5PYmplY3QoZGF0YS5hbGxEYXRhW2luZGV4XVtjb21wYXJpc29uQ29sdW1uXSkgPyBkYXRhLmFsbERhdGFbaW5kZXhdW2NvbXBhcmlzb25Db2x1bW5dLmluaXRpYWxWYWx1ZSA6IGRhdGEuYWxsRGF0YVtpbmRleF1bY29tcGFyaXNvbkNvbHVtbl07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGRpZmZlcmVuY2U6IGFueSA9IE51bWJlcihpbml0aWFsVmFsdWUpIC0gTnVtYmVyKGNvbXBhcmlzb25WYWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNlbGxWYWx1ZSA9IGA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgc3BhY2UtYmV0d2VlblwiPjxzcGFuIGNsYXNzPVwiZm9udC1tZWRpdW1cIj4ke2luaXRpYWxWYWx1ZX08L3NwYW4+YDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGlmZmVyZW5jZSA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjZWxsVmFsdWUgKz0gYDxzcGFuIGNsYXNzPVwibWwtMSB0ZXh0LWJsdWUtNTAwIGZvbnQtbWVkaXVtIHRleHQtbGdcIj4mIzYxOzwvc3Bhbj5gO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGlmZmVyZW5jZSA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNlbGxEYXRhLmNvbXBhcmlzb25QZXJjZW50YWdlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb21wYXJlRm9ybWF0dGVyID0gbmV3IEludGwuTnVtYmVyRm9ybWF0KCdlbi1HQicsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogJ3BlcmNlbnQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbmltdW1GcmFjdGlvbkRpZ2l0czogY2VsbERhdGEuY29tcGFyaXNvbkRlY2ltYWxzIHx8IDBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlmZmVyZW5jZSA9IGNvbXBhcmVGb3JtYXR0ZXIuZm9ybWF0KGRpZmZlcmVuY2UgLyBjb21wYXJpc29uVmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNlbGxWYWx1ZSArPSBgPHNwYW4gY2xhc3M9XCJtbC0xIHRleHQtZ3JlZW4tNTAwIGZvbnQtbWVkaXVtIHRleHQtbGdcIj4mIzg1OTM7PC9zcGFuPjxzcGFuIGNsYXNzPVwidGV4dC1zbSB0ZXh0LWdyZWVuLTUwMFwiPiR7ZGlmZmVyZW5jZX08L3NwYW4+YDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRpZmZlcmVuY2UgPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjZWxsRGF0YS5jb21wYXJpc29uUGVyY2VudGFnZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29tcGFyZUZvcm1hdHRlciA9IG5ldyBJbnRsLk51bWJlckZvcm1hdCgnZW4tR0InLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6ICdwZXJjZW50JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW5pbXVtRnJhY3Rpb25EaWdpdHM6IGNlbGxEYXRhLmNvbXBhcmlzb25EZWNpbWFscyB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpZmZlcmVuY2UgPSBjb21wYXJlRm9ybWF0dGVyLmZvcm1hdChkaWZmZXJlbmNlIC8gY29tcGFyaXNvblZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjZWxsVmFsdWUgKz0gYDxzcGFuIGNsYXNzPVwibWwtMSB0ZXh0LXJlZC01MDAgZm9udC1tZWRpdW0gdGV4dC1sZ1wiPiYjODU5NTs8L3NwYW4+PHNwYW4gY2xhc3M9XCJ0ZXh0LXNtIHRleHQtcmVkLTUwMFwiPiR7ZGlmZmVyZW5jZX08L3NwYW4+YDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2VsbFZhbHVlICs9IGA8c3BhbiBjbGFzcz1cIm1sLTIgdGV4dC14cyB0ZXh0LWdyYXktNDAwXCI+ZnJvbSAke2NvbXBhcmlzb25WYWx1ZX08L3NwYW4+PC9kaXY+YDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtW3RhYmxlQ2VsbF0gPSB7Y2VsbFZhbHVlLCBpbml0aWFsVmFsdWV9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnbGluayc6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGxpbmtWYWx1ZSA9IGNlbGxEYXRhLmN1c3RvbUxpbms7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGFuY2hvciA9ICcnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjZWxsRGF0YS5saW5rVHlwZSA9PT0gJ2N1c3RvbScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZGF0YUl0ZW0gPSBkYXRhLmFsbERhdGFbaW5kZXhdIHx8IHRoaXMuZGFzaGJvYXJkLmxheW91dFNldHRpbmdzLnBhcmFtZXRlcnM7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlua1ZhbHVlID0gdGhpcy5iaW5kUGFyYW1ldGVyc0luU3RyaW5nKGxpbmtWYWx1ZSwgZGF0YUl0ZW0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiB3ZSBoYXZlIGFueSBjb2x1bW4gZWcuIFtbIF1dIHZhbHVlcyBuZWVkaW5nIG1hcHBpbmdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlua1ZhbHVlID0gdGhpcy5tYXBDb2x1bW5Ub1ZhbHVlKGxpbmtWYWx1ZSwgZGF0YUl0ZW0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmNob3IgPSBgPGEgaHJlZj1cIiR7bGlua1ZhbHVlfVwiIHRhcmdldD1cIl9ibGFua1wiIGNsYXNzPVwidGV4dC1jdGEgaG92ZXI6dW5kZXJsaW5lIGZsZXggaXRlbXMtY2VudGVyXCI+JHtpdGVtW3RhYmxlQ2VsbF19PC9hPmA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjZWxsRGF0YS5saW5rVHlwZSA9PT0gJ2Rhc2hib2FyZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcGFyYW1zID0ge307XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRhc2hib2FyZExpbmsgPSBjZWxsRGF0YS5kYXNoYm9hcmRMaW5rO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkYXRhSXRlbSA9IGRhdGEuYWxsRGF0YVtpbmRleF0gfHwgdGhpcy5kYXNoYm9hcmQubGF5b3V0U2V0dGluZ3MucGFyYW1ldGVycztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3Qua2V5cyhjZWxsRGF0YS5kYXNoYm9hcmRMaW5rUGFyYW1zKS5mb3JFYWNoKHBhcmFtS2V5ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCB2YWx1ZSA9IHRoaXMuYmluZFBhcmFtZXRlcnNJblN0cmluZyhjZWxsRGF0YS5kYXNoYm9hcmRMaW5rUGFyYW1zW3BhcmFtS2V5XSwgZGF0YUl0ZW0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgd2UgaGF2ZSBhbnkgY29sdW1uIGVnLiBbWyBdXSB2YWx1ZXMgbmVlZGluZyBtYXBwaW5nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHRoaXMubWFwQ29sdW1uVG9WYWx1ZSh2YWx1ZSwgZGF0YUl0ZW0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbXNbcGFyYW1LZXldID0gdmFsdWU7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVybFBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMocGFyYW1zKS50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5rVmFsdWUgPSBgJHt0aGlzLnJvdXRlci51cmwuc3BsaXQoJy8nKVswXX0vZGFzaGJvYXJkcy92aWV3LyR7ZGFzaGJvYXJkTGluay52YWx1ZX0ke3RoaXMuYWRtaW4gPyAnP2E9dHJ1ZSYnIDogJz8nfSR7dXJsUGFyYW1zfWA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuY2hvciA9IGA8YSBocmVmPVwiJHtsaW5rVmFsdWV9XCIgY2xhc3M9XCJ0ZXh0LWN0YSBob3Zlcjp1bmRlcmxpbmUgZmxleCBpdGVtcy1jZW50ZXJcIj4ke2l0ZW1bdGFibGVDZWxsXX08L2E+YDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5rVmFsdWUgPSBsaW5rVmFsdWUuaW5jbHVkZXMoJ2h0dHAnKSA/IGxpbmtWYWx1ZSA6IGBodHRwOi8vJHtsaW5rVmFsdWV9YDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5jaG9yID0gYDxhIGhyZWY9XCIke2xpbmtWYWx1ZX1cIiB0YXJnZXQ9XCJfYmxhbmtcIiBjbGFzcz1cInRleHQtY3RhIGhvdmVyOnVuZGVybGluZSBmbGV4IGl0ZW1zLWNlbnRlclwiPiR7aXRlbVt0YWJsZUNlbGxdfTwvYT5gO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1bdGFibGVDZWxsXSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2VsbFZhbHVlOiBhbmNob3IsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluaXRpYWxWYWx1ZTogbGlua1ZhbHVlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2N1c3RvbSc6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZWxlbWVudDogYW55ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3JpZ2luYWxWYWx1ZSA9IGl0ZW1bdGFibGVDZWxsXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmlubmVySFRNTCA9IHRoaXMuYmluZFBhcmFtZXRlcnNJblN0cmluZyhjZWxsRGF0YS5jdXN0b21UZXh0KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGtEYXRhOiBhbnkgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFTZXQ6IGRhdGEuYWxsRGF0YVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXy5mb3JFYWNoKGRhdGEuYWxsRGF0YVtpbmRleF0gfHwgW10sICh2YWx1ZSwga2V5KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtEYXRhW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBLaW5pYmluZCA9IHdpbmRvdy5LaW5pYmluZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLaW5pYmluZC5jb25maWcgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeDogJ2QnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZURlbGltaXRlcnM6IFsnW1snLCAnXV0nXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYmluZCA9IG5ldyBLaW5pYmluZChlbGVtZW50LCBrRGF0YSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYm91bmRIVE1MID0gYmluZC5ib3VuZENvbnRleHQuZWxzWzBdLmlubmVySFRNTDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtW3RhYmxlQ2VsbF0gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNlbGxWYWx1ZTogdGhpcy5zYW5pdGl6ZXIuc2FuaXRpemUoMSwgYm91bmRIVE1MKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5pdGlhbFZhbHVlOiBvcmlnaW5hbFZhbHVlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnJlbW92ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnaGlkZSc6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5oaWRkZW5Db2x1bW5zW3RhYmxlQ2VsbF0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpdGVtO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZGF0YXNldCA9IGRhdGE7XG4gICAgICAgICAgICBjb25zdCByZXR1cm5lZERhdGFMZW5ndGggPSB0aGlzLmRhdGFzZXQuYWxsRGF0YS5sZW5ndGg7XG5cbiAgICAgICAgICAgIGNvbnN0IGV4aXN0aW5nTXVsdGlTb3J0ID0gXy5maW5kKHRoaXMuZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlLnRyYW5zZm9ybWF0aW9uSW5zdGFuY2VzLCB7dHlwZTogJ211bHRpc29ydCd9KTtcblxuICAgICAgICAgICAgaWYgKGV4aXN0aW5nTXVsdGlTb3J0ICYmIGV4aXN0aW5nTXVsdGlTb3J0LmNvbmZpZy5zb3J0cy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBleGlzdGluZ011bHRpU29ydC5jb25maWcuc29ydHMuZm9yRWFjaChzb3J0ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29sdW1uID0gXy5maW5kKHRoaXMuZGF0YXNldC5jb2x1bW5zLCB7bmFtZTogc29ydC5maWVsZE5hbWV9KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbHVtbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29sdW1uLmRpcmVjdGlvbiA9IHNvcnQuZGlyZWN0aW9uO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuZmlsdGVyRmllbGRzID0gXy5tYXAodGhpcy5kYXRhc2V0LmNvbHVtbnMsIGNvbHVtbiA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6IGNvbHVtbi50aXRsZSxcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogY29sdW1uLm5hbWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAodGhpcy5kYXNoYm9hcmQubGF5b3V0U2V0dGluZ3MubWV0cmljKSB7XG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVNZXRyaWNEYXRhVmFsdWVzKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmRhc2hib2FyZC5sYXlvdXRTZXR0aW5ncy5pbWFnZURhdGEpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUltYWdlRGF0YSgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoT2JqZWN0LmtleXModGhpcy50ZXh0RGF0YSkubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy50ZXh0RGF0YS5zYWZlVGV4dERhdGEgPSB0aGlzLmV2YWx1YXRlVGV4dERhdGEodGhpcy50ZXh0RGF0YS52YWx1ZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChPYmplY3Qua2V5cyh0aGlzLmdlbmVyYWwpLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZ2VuZXJhbC5ldmFsdWF0ZWROYW1lID0gdGhpcy5nZW5lcmFsLm5hbWUgPyB0aGlzLmV2YWx1YXRlVGV4dERhdGEodGhpcy5nZW5lcmFsLm5hbWUpIDogJyc7XG4gICAgICAgICAgICAgICAgdGhpcy5nZW5lcmFsLmV2YWx1YXRlZERlc2NyaXB0aW9uID0gdGhpcy5nZW5lcmFsLmRlc2NyaXB0aW9uID8gdGhpcy5ldmFsdWF0ZVRleHREYXRhKHRoaXMuZ2VuZXJhbC5kZXNjcmlwdGlvbikgOiAnJztcbiAgICAgICAgICAgICAgICB0aGlzLmdlbmVyYWwuZXZhbHVhdGVkRm9vdGVyID0gdGhpcy5nZW5lcmFsLmZvb3RlciA/IHRoaXMuZXZhbHVhdGVUZXh0RGF0YSh0aGlzLmdlbmVyYWwuZm9vdGVyKSA6ICcnO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5kYXNoYm9hcmRJdGVtVHlwZS50eXBlID09PSAnbmV0d29yaycpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXR1cE5ldHdvcmtDaGFydCgpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLml0ZW1JbnN0YW5jZUtleSk7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBjaGlsZCBvZiBBcnJheS5mcm9tKGVsZW1lbnQgPyBlbGVtZW50LmNoaWxkcmVuIDogW10pIGFzIGFueVtdKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjaGlsZC5jbGFzc0xpc3QuY29udGFpbnMoJ2l0ZW0tY29udGFpbmVyJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMud29yZENsb3VkLndpZHRoID0gY2hpbGQuY2xpZW50V2lkdGggLSA0MDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMud29yZENsb3VkLmhlaWdodCA9IGNoaWxkLmNsaWVudEhlaWdodCAtIDQwO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChPYmplY3Qua2V5cyh0aGlzLndvcmRDbG91ZCkubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLndvcmRDbG91ZC5wb3B1bGF0aW9uTWV0aG9kID09PSAnU0lOR0xFJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgcm93RGF0YSA9IHRoaXMuZGF0YXNldC5hbGxEYXRhW3RoaXMud29yZENsb3VkLnJvd107XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocm93RGF0YSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHdvcmRzID0gXy53b3Jkcyhyb3dEYXRhW3RoaXMud29yZENsb3VkLmNvbHVtbl0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvdW50ID0gXy5jb3VudEJ5KHdvcmRzLCBfLmlkZW50aXR5KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1heCA9IF8ubWF4KF8udmFsdWVzKGNvdW50KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZm9udFNpemUgPSAoKHRoaXMud29yZENsb3VkLmhlaWdodCkgKiAodGhpcy53b3JkQ2xvdWQud2lkdGgpKSAvIDEwMDA7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLndvcmRDbG91ZC5kYXRhID0gXy5vcmRlckJ5KF8udW5pcSh3b3JkcykubWFwKHdvcmQgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge3RleHQ6IHdvcmQsIHZhbHVlOiAoKGNvdW50W3dvcmRdIC8gbWF4KSAqIF8ubWluKFtmb250U2l6ZSwgMTIwXSkpfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSwgWyd2YWx1ZSddLCBbJ2Rlc2MnXSkuc2xpY2UoMCwgMTAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLndvcmRDbG91ZC5wb3B1bGF0aW9uTWV0aG9kID09PSAnV0hPTEUnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXhGcmVxID0gXy5tYXhCeSh0aGlzLmRhdGFzZXQuYWxsRGF0YSwgaXRlbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlcihpdGVtW3RoaXMud29yZENsb3VkLmZyZXF1ZW5jeV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlbdGhpcy53b3JkQ2xvdWQuZnJlcXVlbmN5XTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1heFdvcmRXaWR0aDogbnVtYmVyID0gXy5tYXgoXy5tYXAodGhpcy5kYXRhc2V0LmFsbERhdGEsIGl0ZW0gPT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtW3RoaXMud29yZENsb3VkLmNvbHVtbl0ubGVuZ3RoICogaXRlbVt0aGlzLndvcmRDbG91ZC5mcmVxdWVuY3ldIC8gbWF4RnJlcVxuICAgICAgICAgICAgICAgICAgICAgICAgKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmb250U2l6ZSA9ICgodGhpcy53b3JkQ2xvdWQuaGVpZ2h0KSAqICh0aGlzLndvcmRDbG91ZC53aWR0aCkpIC8gMzAwMDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMud29yZENsb3VkLmRhdGEgPSBfLm9yZGVyQnkodGhpcy5kYXRhc2V0LmFsbERhdGEubWFwKGl0ZW0gPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRleHQgPSBpdGVtW3RoaXMud29yZENsb3VkLmNvbHVtbl07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaXRlbUZyZXF1ZW5jeSA9IGl0ZW1bdGhpcy53b3JkQ2xvdWQuZnJlcXVlbmN5XTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiAoKDggLyBtYXhXb3JkV2lkdGgpICogKE51bWJlcihpdGVtRnJlcXVlbmN5KSAvIE51bWJlcihtYXhGcmVxKSkgKiBfLm1pbihbZm9udFNpemUsIDQwMF0pKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICB9KSwgWyd2YWx1ZSddLCBbJ2Rlc2MnXSkuc2xpY2UoMCwgMTAwKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgNTApO1xuXG5cbiAgICAgICAgICAgIHRoaXMubG9hZGluZ0l0ZW0gPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuY29uZmlndXJlQ2xhc3MgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuc2V0Q2hhcnREYXRhKCk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmRhc2hib2FyZC5hbGVydHNFbmFibGVkICYmICF0aGlzLmV4dGVybmFsKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlLmFsZXJ0cyAmJiB0aGlzLmRhc2hib2FyZERhdGFzZXRJbnN0YW5jZS5hbGVydHMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmRhc2hib2FyZC5sYXlvdXRTZXR0aW5ncy5wYXJhbWV0ZXJzICYmIE9iamVjdC5rZXlzKHRoaXMuZGFzaGJvYXJkLmxheW91dFNldHRpbmdzLnBhcmFtZXRlcnMpLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodGhpcy5kYXNoYm9hcmREYXRhc2V0SW5zdGFuY2UucGFyYW1ldGVyVmFsdWVzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlLnBhcmFtZXRlclZhbHVlcyA9IHt9O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgXy5mb3JFYWNoKHRoaXMuZGFzaGJvYXJkLmxheW91dFNldHRpbmdzLnBhcmFtZXRlcnMsIHBhcmFtZXRlciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kYXNoYm9hcmREYXRhc2V0SW5zdGFuY2UucGFyYW1ldGVyVmFsdWVzW3BhcmFtZXRlci5uYW1lXSA9IHBhcmFtZXRlci52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGRhc2hib2FyZEluc3RhbmNlID0gXy5jbG9uZURlZXAodGhpcy5kYXNoYm9hcmREYXRhc2V0SW5zdGFuY2UpO1xuICAgICAgICAgICAgICAgICAgICBkYXNoYm9hcmRJbnN0YW5jZS5wYXJhbWV0ZXJWYWx1ZXMgPSB0aGlzLmdldE1hcHBlZFBhcmFtcyh0aGlzLmRhc2hib2FyZERhdGFzZXRJbnN0YW5jZSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWxlcnRTZXJ2aWNlLnByb2Nlc3NBbGVydHNGb3JEYXNoYm9hcmREYXRhc2V0SW5zdGFuY2UoZGFzaGJvYXJkSW5zdGFuY2UpXG4gICAgICAgICAgICAgICAgICAgICAgICAudGhlbigocmVzOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzICYmIHJlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hbGVydCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYWxlcnREYXRhID0gcmVzO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXRlbUVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1FbGVtZW50LmNsYXNzTGlzdC5hZGQoJ2FsZXJ0Jyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtRWxlbWVudC5wYXJlbnRFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ2FsZXJ0Jyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc2V0QWxlcnREYXRhKGl0ZW1FbGVtZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc2V0QWxlcnREYXRhKGl0ZW1FbGVtZW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMucmVzZXRBbGVydERhdGEoaXRlbUVsZW1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgZXhpc3RpbmcgPSB0aGlzLmRhc2hib2FyZFNlcnZpY2UuZGFzaGJvYXJkSXRlbXMuZ2V0VmFsdWUoKTtcbiAgICAgICAgICAgIGV4aXN0aW5nW3RoaXMuaXRlbUluc3RhbmNlS2V5XSA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLmRhc2hib2FyZFNlcnZpY2UuZGFzaGJvYXJkSXRlbXMubmV4dChleGlzdGluZyk7XG5cbiAgICAgICAgICAgIHRoaXMuZW5kT2ZSZXN1bHRzID0gcmV0dXJuZWREYXRhTGVuZ3RoIDwgdGhpcy5saW1pdDtcblxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0cnVlKTtcbiAgICAgICAgfSkuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRNYXBwZWRQYXJhbXMoZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlKSB7XG4gICAgICAgIGNvbnN0IG1hcHBlZFBhcmFtcyA9IHt9O1xuICAgICAgICBfLmZvckVhY2goZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlLnBhcmFtZXRlclZhbHVlcywgKHZhbHVlLCBrZXkpID0+IHtcbiAgICAgICAgICAgIGlmIChfLmlzU3RyaW5nKHZhbHVlKSAmJiB2YWx1ZS5pbmNsdWRlcygne3snKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGdsb2JhbEtleSA9IHZhbHVlLnJlcGxhY2UoJ3t7JywgJycpLnJlcGxhY2UoJ319JywgJycpO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmRhc2hib2FyZC5sYXlvdXRTZXR0aW5ncy5wYXJhbWV0ZXJzICYmIHRoaXMuZGFzaGJvYXJkLmxheW91dFNldHRpbmdzLnBhcmFtZXRlcnNbZ2xvYmFsS2V5XSkge1xuICAgICAgICAgICAgICAgICAgICBtYXBwZWRQYXJhbXNba2V5XSA9IHRoaXMuZGFzaGJvYXJkLmxheW91dFNldHRpbmdzLnBhcmFtZXRlcnNbZ2xvYmFsS2V5XS52YWx1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG1hcHBlZFBhcmFtc1trZXldID0gdmFsdWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBtYXBwZWRQYXJhbXM7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZXNldEFsZXJ0RGF0YShpdGVtRWxlbWVudCkge1xuICAgICAgICB0aGlzLmFsZXJ0ID0gZmFsc2U7XG4gICAgICAgIHRoaXMuYWxlcnREYXRhID0gW107XG4gICAgICAgIGlmIChpdGVtRWxlbWVudCkge1xuICAgICAgICAgICAgaXRlbUVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgnYWxlcnQnKTtcbiAgICAgICAgICAgIGl0ZW1FbGVtZW50LnBhcmVudEVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgnYWxlcnQnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgcmVzZXRQYWdlcigpIHtcbiAgICAgICAgdGhpcy5vZmZzZXQgPSAwO1xuICAgICAgICB0aGlzLnBhZ2UgPSAxO1xuICAgIH1cblxuICAgIHByaXZhdGUgbWFwTGF5b3V0U2V0dGluZ3NUb0NvbXBvbmVudERhdGEoKSB7XG4gICAgICAgIF8uZm9yRWFjaCh0aGlzLmRhc2hib2FyZC5sYXlvdXRTZXR0aW5ncywgKGRhdGEsIGtleSkgPT4ge1xuICAgICAgICAgICAgaWYgKGtleSAhPT0gJ2dyaWQnKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGVmYXVsdFZhbHVlID0gXy5pc1BsYWluT2JqZWN0KHRoaXNba2V5XSkgPyB7fSA6IFtdO1xuICAgICAgICAgICAgICAgIHRoaXNba2V5XSA9IE9iamVjdC5rZXlzKGRhdGEpLmxlbmd0aCA/IGRhdGFbdGhpcy5pdGVtSW5zdGFuY2VLZXldIHx8IGRlZmF1bHRWYWx1ZSA6IGRlZmF1bHRWYWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZWxvYWRBbGVydChzYXZlID0gdHJ1ZSkge1xuICAgICAgICBjb25zdCB0aGlzRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLml0ZW1JbnN0YW5jZUtleSkuY2xvc2VzdCgnLmdyaWQtc3RhY2staXRlbScpO1xuICAgICAgICBjb25zdCBleGlzdGluZ0dyaWQgPSBfLmZpbmQodGhpcy5kYXNoYm9hcmQubGF5b3V0U2V0dGluZ3MuZ3JpZCwgZ3JpZCA9PiB7XG4gICAgICAgICAgICByZXR1cm4gZ3JpZC5jb250ZW50LmluY2x1ZGVzKGBpZD1cIiR7dGhpcy5pdGVtSW5zdGFuY2VLZXl9XCJgKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0aGlzRWwgJiYgZXhpc3RpbmdHcmlkKSB7XG4gICAgICAgICAgICB0aGlzLmdyaWQucmVtb3ZlV2lkZ2V0KHRoaXNFbCk7XG4gICAgICAgICAgICB0aGlzLmdyaWQuYWRkV2lkZ2V0KGV4aXN0aW5nR3JpZCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc2F2ZSkge1xuICAgICAgICAgICAgdGhpcy5kYXNoYm9hcmRTZXJ2aWNlLnNhdmVEYXNoYm9hcmQodGhpcy5kYXNoYm9hcmQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBldmFsdWF0ZURhdGFzZXQobGltaXQ/LCBvZmZzZXQ/KSB7XG4gICAgICAgIGNvbnN0IGRhdGFzZXRJbnN0YW5jZVN1bW1hcnkgPSB0aGlzLnByZXBhcmVEYXRhc2V0SW5zdGFuY2VTdW1tYXJ5Rm9yRXZhbHVhdGlvbigpO1xuXG4gICAgICAgIHRoaXMuaGlkZGVuQ29sdW1ucyA9IHt9O1xuXG4gICAgICAgIHRoaXMuZXh0ZXJuYWxFcnJvciA9IGZhbHNlO1xuICAgICAgICB0aGlzLnF1b3RhRXhjZWVkZWQgPSBudWxsO1xuXG4gICAgICAgIGlmICh0aGlzLmV4dGVybmFsKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5leHRlcm5hbFNlcnZpY2UuZXZhbHVhdGVEYXRhc2V0KFxuICAgICAgICAgICAgICAgIHRoaXMuZGFzaGJvYXJkLmlkLFxuICAgICAgICAgICAgICAgIHRoaXMuaXRlbUluc3RhbmNlS2V5LFxuICAgICAgICAgICAgICAgIGRhdGFzZXRJbnN0YW5jZVN1bW1hcnkucGFyYW1ldGVyVmFsdWVzLFxuICAgICAgICAgICAgICAgIFN0cmluZyhvZmZzZXQgfHwgdGhpcy5vZmZzZXQpLFxuICAgICAgICAgICAgICAgIFN0cmluZyhsaW1pdCB8fCB0aGlzLmxpbWl0KSxcbiAgICAgICAgICAgICAgICB0aGlzLnF1ZXJ5UGFyYW1zXG4gICAgICAgICAgICApLmNhdGNoKGUgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZXh0ZXJuYWxFcnJvciA9IHRydWU7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRhdGFzZXRTZXJ2aWNlLmV2YWx1YXRlRGF0YXNldChcbiAgICAgICAgICAgICAgICBkYXRhc2V0SW5zdGFuY2VTdW1tYXJ5LFxuICAgICAgICAgICAgICAgIFN0cmluZyhvZmZzZXQgfHwgdGhpcy5vZmZzZXQpLFxuICAgICAgICAgICAgICAgIFN0cmluZyhsaW1pdCB8fCB0aGlzLmxpbWl0KVxuICAgICAgICAgICAgKS5jYXRjaChlID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZSAmJiBlLmVycm9yICYmIGUuZXJyb3IubWVzc2FnZSAmJiBlLmVycm9yLm1lc3NhZ2UuaW5jbHVkZXMoJ3F1b3RhJykpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5xdW90YUV4Y2VlZGVkID0gZS5lcnJvci5tZXNzYWdlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXh0ZXJuYWxFcnJvciA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHByZXBhcmVEYXRhc2V0SW5zdGFuY2VTdW1tYXJ5Rm9yRXZhbHVhdGlvbigpIHtcbiAgICAgICAgY29uc3QgbWFwcGVkUGFyYW1zID0gdGhpcy5nZXRNYXBwZWRQYXJhbXModGhpcy5kYXNoYm9hcmREYXRhc2V0SW5zdGFuY2UpO1xuXG4gICAgICAgIGNvbnN0IGRhdGFzZXRJbnN0YW5jZVN1bW1hcnkgPSB7XG4gICAgICAgICAgICBkYXRhc2V0SW5zdGFuY2VJZDogdGhpcy5kYXNoYm9hcmREYXRhc2V0SW5zdGFuY2UuZGF0YXNldEluc3RhbmNlSWQsXG4gICAgICAgICAgICBkYXRhc291cmNlSW5zdGFuY2VLZXk6IHRoaXMuZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlLmRhdGFzb3VyY2VJbnN0YW5jZUtleSxcbiAgICAgICAgICAgIHRyYW5zZm9ybWF0aW9uSW5zdGFuY2VzOiB0aGlzLmRhc2hib2FyZERhdGFzZXRJbnN0YW5jZS50cmFuc2Zvcm1hdGlvbkluc3RhbmNlcyxcbiAgICAgICAgICAgIHBhcmFtZXRlclZhbHVlczogbWFwcGVkUGFyYW1zLFxuICAgICAgICAgICAgcGFyYW1ldGVyczogdGhpcy5kYXNoYm9hcmREYXRhc2V0SW5zdGFuY2UucGFyYW1ldGVyc1xuICAgICAgICB9O1xuXG4gICAgICAgIGlmICh0aGlzLmRhc2hib2FyZC5sYXlvdXRTZXR0aW5ncy5wYXJhbWV0ZXJzICYmIE9iamVjdC5rZXlzKHRoaXMuZGFzaGJvYXJkLmxheW91dFNldHRpbmdzLnBhcmFtZXRlcnMpLmxlbmd0aCkge1xuICAgICAgICAgICAgXy5mb3JFYWNoKHRoaXMuZGFzaGJvYXJkLmxheW91dFNldHRpbmdzLnBhcmFtZXRlcnMsIChwYXJhbSwgbmFtZSkgPT4ge1xuICAgICAgICAgICAgICAgIGxldCB2YWx1ZSA9IHBhcmFtLnZhbHVlO1xuICAgICAgICAgICAgICAgIGlmIChwYXJhbS50eXBlID09PSAnZGF0ZScgfHwgcGFyYW0udHlwZSA9PT0gJ2RhdGV0aW1lJykge1xuICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgJiYgIXZhbHVlLmluY2x1ZGVzKCdBR08nKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBtb21lbnQodmFsdWUpLmZvcm1hdCgnWVlZWS1NTS1ERCBISDptbTpzcycpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gQWRkIGluIHRoZSB3aWRnZXQgc3BlY2lmaWMgcGFyYW1ldGVyIHZhbHVlcyBpZiB0aGVyZSBhcmUgYW55XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZ2VuZXJhbC53aWRnZXRQYXJhbWV0ZXJzICYmIE9iamVjdC5rZXlzKHRoaXMuZ2VuZXJhbC53aWRnZXRQYXJhbWV0ZXJzKS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgd2lkZ2V0UGFyYW0gPSBfLmZpbmQodGhpcy5nZW5lcmFsLndpZGdldFBhcmFtZXRlcnMsIHtuYW1lfSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh3aWRnZXRQYXJhbSAmJiB3aWRnZXRQYXJhbS52YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSB3aWRnZXRQYXJhbS52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGRhdGFzZXRJbnN0YW5jZVN1bW1hcnkucGFyYW1ldGVyVmFsdWVzW25hbWVdID0gdmFsdWU7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBkYXRhc2V0SW5zdGFuY2VTdW1tYXJ5O1xuICAgIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJhbGVydC1wYW5lbFwiICpuZ0lmPVwic2hvd0FsZXJ0RGF0YVwiIChjbGljayk9XCJzaG93QWxlcnREYXRhID0gZmFsc2VcIj5cbiAgICA8ZGl2IGNsYXNzPVwiYWxpZ24tY2VudGVyIGZsZXgtY29sIHctMy80IG0tYXV0b1wiPlxuICAgICAgICA8bWF0LWljb24+bm90aWZpY2F0aW9uX2ltcG9ydGFudDwvbWF0LWljb24+XG4gICAgICAgIDxoMiBjbGFzcz1cIm1iLTBcIj5BbGVydCBOb3RpZmljYXRpb248L2gyPlxuICAgICAgICA8cCBjbGFzcz1cInRleHQtY2VudGVyXCI+VGhlIGZvbGxvd2luZyBhbGVydHMgaGF2ZSBiZWVuIHRyaWdnZXJlZCBiYXNlZCBvbiB0aGUgY3JpdGVyaWEgc2V0IGZvciB0aGlzIGRhc2hib2FyZFxuICAgICAgICAgICAgaXRlbS4uLjwvcD5cbiAgICAgICAgPGRpdiBjbGFzcz1cImFsZXJ0LWl0ZW0gbWItMlwiICpuZ0Zvcj1cImxldCBhbGVydEl0ZW0gb2YgYWxlcnREYXRhXCJcbiAgICAgICAgICAgICBbaW5uZXJIVE1MXT1cImFsZXJ0SXRlbS5ub3RpZmljYXRpb25NZXNzYWdlXCI+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC9kaXY+XG5cbjxkaXYgY2xhc3M9XCJpdGVtLWRpc2FibGVkXCI+XG4gICAgPHA+e3tnZW5lcmFsLm5hbWUgfHwgZGFzaGJvYXJkSXRlbVR5cGUubGFiZWx9fTwvcD5cbiAgICA8bWF0LWljb24+YmxvY2s8L21hdC1pY29uPlxuICAgIDxwIGNsYXNzPVwiZGlzYWJsZWQtbm90aWNlXCI+e3tkZXBlbmRlbmNpZXMubm90aWNlIHx8ICdObyBEYXRhIEF2YWlsYWJsZSd9fTwvcD5cbjwvZGl2PlxuXG48bmctdGVtcGxhdGUgW25nSWZdPVwiZHJhZ0l0ZW1cIj5cbiAgICA8c3BhbiBjbGFzcz1cIm1hdGVyaWFsLXN5bWJvbHMtb3V0bGluZWRcIj57e2Rhc2hib2FyZEl0ZW1UeXBlLmljb259fTwvc3Bhbj5cbiAgICA8c3BhbiBbaW5uZXJIVE1MXT1cImRhc2hib2FyZEl0ZW1UeXBlLmxhYmVsXCI+PC9zcGFuPlxuPC9uZy10ZW1wbGF0ZT5cbjxkaXYgY2xhc3M9XCJhbGVydC13aWRnZXRcIiAqbmdJZj1cImFsZXJ0XCIgKGNsaWNrKT1cInNob3dBbGVydERhdGEgPSB0cnVlO1wiPlxuICAgIDxidXR0b24gbWF0LWljb24tYnV0dG9uPlxuICAgICAgICA8bWF0LWljb24+bm90aWZpY2F0aW9uX2ltcG9ydGFudDwvbWF0LWljb24+XG4gICAgPC9idXR0b24+XG4gICAgPGRpdiBjbGFzcz1cImFsZXJ0LXN1bW1hcmllc1wiPlxuICAgICAgICA8c3BhbiBjbGFzcz1cIm1yLTJcIiAqbmdGb3I9XCJsZXQgYWxlcnRJdGVtIG9mIGFsZXJ0RGF0YVwiPlxuICAgICAgICAgICAge3thbGVydEl0ZW0uc3VtbWFyeU1lc3NhZ2V9fVxuICAgICAgICA8L3NwYW4+XG4gICAgPC9kaXY+XG48L2Rpdj5cblxuPG5nLXRlbXBsYXRlXG4gICAgW25nSWZdPVwiIWRyYWdJdGVtICYmICFkYXNoYm9hcmREYXRhc2V0SW5zdGFuY2UgJiYgIWRhc2hib2FyZEl0ZW1UeXBlLmhlYWRpbmdWYWx1ZSAmJiAhZGFzaGJvYXJkSXRlbVR5cGUuX2VkaXRpbmdcIj5cbiAgICA8YnV0dG9uIG1hdC1zdHJva2VkLWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIiBjbGFzcz1cImNvbmZpZy1idXR0b25cIiAoY2xpY2spPVwiY29uZmlndXJlKClcIj5cbiAgICAgICAgQ29uZmlndXJlIHt7ZGFzaGJvYXJkSXRlbVR5cGUubGFiZWx9fVxuICAgIDwvYnV0dG9uPlxuPC9uZy10ZW1wbGF0ZT5cblxuPGRpdiBjbGFzcz1cImFic29sdXRlIHRvcC0xIHJpZ2h0LTEgIHotMjBcIiAqbmdJZj1cIiFkcmFnSXRlbSAmJiBsb2FkaW5nSXRlbSAmJiAoY2hhcnREYXRhIHx8IGRhdGFzZXQpXCI+XG4gICAgPHN2ZyBjbGFzcz1cImFuaW1hdGUtc3BpbiBoLTUgdy01IHRleHQtc2Vjb25kYXJ5XCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIGZpbGw9XCJub25lXCIgdmlld0JveD1cIjAgMCAyNCAyNFwiPlxuICAgICAgICA8Y2lyY2xlIGNsYXNzPVwib3BhY2l0eS0yNVwiIGN4PVwiMTJcIiBjeT1cIjEyXCIgcj1cIjEwXCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiNFwiPjwvY2lyY2xlPlxuICAgICAgICA8cGF0aCBjbGFzcz1cIm9wYWNpdHktNzVcIiBmaWxsPVwiY3VycmVudENvbG9yXCIgZD1cIk00IDEyYTggOCAwIDAxOC04VjBDNS4zNzMgMCAwIDUuMzczIDAgMTJoNHptMiA1LjI5MUE3Ljk2MiA3Ljk2MiAwIDAxNCAxMkgwYzAgMy4wNDIgMS4xMzUgNS44MjQgMyA3LjkzOGwzLTIuNjQ3elwiPjwvcGF0aD5cbiAgICA8L3N2Zz5cbjwvZGl2PlxuXG48bmctdGVtcGxhdGUgW25nSWZdPVwiIXZpZXdPbmx5XCI+XG4gICAgPGRpdiBjbGFzcz1cImFic29sdXRlIHRvcC0xIGxlZnQtMSB6LTIwIGN1cnNvci1wb2ludGVyXCIgKm5nSWY9XCIhZHJhZ0l0ZW0gJiYgdGhpcy5pdGVtTm9Nb3ZlXCJcbiAgICAgICAgIChjbGljayk9XCJsb2NrSXRlbSgpXCI+XG4gICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwiY3VycmVudENvbG9yXCJcbiAgICAgICAgICAgICBjbGFzcz1cImgtNSB3LTUgdGV4dC1ncmF5LTQwMFwiPlxuICAgICAgICAgICAgPHBhdGggZmlsbC1ydWxlPVwiZXZlbm9kZFwiIGQ9XCJNMTIgMS41YTUuMjUgNS4yNSAwIDAgMC01LjI1IDUuMjV2M2EzIDMgMCAwIDAtMyAzdjYuNzVhMyAzIDAgMCAwIDMgM2gxMC41YTMgMyAwIDAgMCAzLTN2LTYuNzVhMyAzIDAgMCAwLTMtM3YtM2MwLTIuOS0yLjM1LTUuMjUtNS4yNS01LjI1Wm0zLjc1IDguMjV2LTNhMy43NSAzLjc1IDAgMSAwLTcuNSAwdjNoNy41WlwiIGNsaXAtcnVsZT1cImV2ZW5vZGRcIiAvPlxuICAgICAgICA8L3N2Zz5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJpdGVtLXVubG9ja2VkIGFic29sdXRlIHRvcC0xIGxlZnQtMSB6LTIwIGN1cnNvci1wb2ludGVyXCIgKm5nSWY9XCIhZHJhZ0l0ZW0gJiYgIXRoaXMuaXRlbU5vTW92ZVwiXG4gICAgICAgICAoY2xpY2spPVwibG9ja0l0ZW0oKVwiPlxuICAgICAgICA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCIgZmlsbD1cImN1cnJlbnRDb2xvclwiXG4gICAgICAgICAgICAgY2xhc3M9XCJoLTUgdy01IHRleHQtZ3JheS00MDBcIj5cbiAgICAgICAgICAgIDxwYXRoIGQ9XCJNMTggMS41YzIuOSAwIDUuMjUgMi4zNSA1LjI1IDUuMjV2My43NWEuNzUuNzUgMCAwIDEtMS41IDBWNi43NWEzLjc1IDMuNzUgMCAxIDAtNy41IDB2M2EzIDMgMCAwIDEgMyAzdjYuNzVhMyAzIDAgMCAxLTMgM0gzLjc1YTMgMyAwIDAgMS0zLTN2LTYuNzVhMyAzIDAgMCAxIDMtM2g5di0zYzAtMi45IDIuMzUtNS4yNSA1LjI1LTUuMjVaXCIgLz5cbiAgICAgICAgPC9zdmc+XG4gICAgPC9kaXY+XG48L25nLXRlbXBsYXRlPlxuXG5cbjxuZy10ZW1wbGF0ZSBbbmdJZl09XCIhZXh0ZXJuYWxFcnJvciAmJiAhcXVvdGFFeGNlZWRlZFwiPlxuICAgIDxkaXYgY2xhc3M9XCJsb2FkaW5nLWl0ZW1cIiAqbmdJZj1cIiFkcmFnSXRlbSAmJiBsb2FkaW5nSXRlbSAmJiAhKGNoYXJ0RGF0YSB8fCBkYXRhc2V0KVwiPlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJteC1hdXRvIGZsZXggaC0xNCB3LTE0IGZsZXgtc2hyaW5rLTAgaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyIHJvdW5kZWQtZnVsbCBiZy1ncmF5LTEwMCBcIj5cbiAgICAgICAgICAgIDxzdmcgY2xhc3M9XCJhbmltYXRlLXNwaW4gaC0xNCB3LTE0IHRleHQtZ3JheS00MDBcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgZmlsbD1cIm5vbmVcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCI+XG4gICAgICAgICAgICAgICAgPGNpcmNsZSBjbGFzcz1cIm9wYWNpdHktMjVcIiBjeD1cIjEyXCIgY3k9XCIxMlwiIHI9XCIxMFwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjRcIj48L2NpcmNsZT5cbiAgICAgICAgICAgICAgICA8cGF0aCBjbGFzcz1cIm9wYWNpdHktNzVcIiBmaWxsPVwiY3VycmVudENvbG9yXCIgZD1cIk00IDEyYTggOCAwIDAxOC04VjBDNS4zNzMgMCAwIDUuMzczIDAgMTJoNHptMiA1LjI5MUE3Ljk2MiA3Ljk2MiAwIDAxNCAxMkgwYzAgMy4wNDIgMS4xMzUgNS44MjQgMyA3LjkzOGwzLTIuNjQ3elwiPjwvcGF0aD5cbiAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInB4LTQgdGV4dC1jZW50ZXIgbXQtNFwiPkxvYWRpbmcge3tkYXNoYm9hcmRJdGVtVHlwZS5sYWJlbH19IC4uLjwvZGl2PlxuICAgIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImV4dGVybmFsRXJyb3JcIj5cbiAgICA8ZGl2IGNsYXNzPVwibG9hZGluZy1pdGVtXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJteC1hdXRvIGZsZXggaC0xNCB3LTE0IGZsZXgtc2hyaW5rLTAgaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyIHJvdW5kZWQtZnVsbCBiZy1yZWQtMTAwIFwiPlxuICAgICAgICAgICAgPHN2ZyBjbGFzcz1cImgtMTAgdy0xMCB0ZXh0LXJlZC02MDBcIiBmaWxsPVwibm9uZVwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBzdHJva2Utd2lkdGg9XCIxLjVcIiBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICAgICAgICA8cGF0aCBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiBkPVwiTTEyIDl2My43NW0tOS4zMDMgMy4zNzZjLS44NjYgMS41LjIxNyAzLjM3NCAxLjk0OCAzLjM3NGgxNC43MWMxLjczIDAgMi44MTMtMS44NzQgMS45NDgtMy4zNzRMMTMuOTQ5IDMuMzc4Yy0uODY2LTEuNS0zLjAzMi0xLjUtMy44OTggMEwyLjY5NyAxNi4xMjZ6TTEyIDE1Ljc1aC4wMDd2LjAwOEgxMnYtLjAwOHpcIiAvPlxuICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwicHgtNCB3LTMvNCB0ZXh0LWNlbnRlciBtdC00XCI+VGhlcmUgd2FzIGEgcHJvYmxlbSBsb2FkaW5nIHRoaXMgaXRlbS4gUGxlYXNlIHRyeSBhZ2FpbiBsYXRlci48L2Rpdj5cbiAgICA8L2Rpdj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSBbbmdJZl09XCJxdW90YUV4Y2VlZGVkXCI+XG4gICAgPGRpdiBjbGFzcz1cImxvYWRpbmctaXRlbVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwibXgtYXV0byBmbGV4IGgtMTQgdy0xNCBmbGV4LXNocmluay0wIGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciByb3VuZGVkLWZ1bGwgYmctYmx1ZS0xMDAgXCI+XG4gICAgICAgICAgICA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiBmaWxsPVwibm9uZVwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBzdHJva2Utd2lkdGg9XCIxLjVcIiBzdHJva2U9XCJjdXJyZW50Q29sb3JcIlxuICAgICAgICAgICAgICAgICBjbGFzcz1cImgtMTAgdy0xMCB0ZXh0LWJsdWUtNjAwXCI+XG4gICAgICAgICAgICAgICAgPHBhdGggc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgZD1cIk0xMS4yNSAxMS4yNWwuMDQxLS4wMmEuNzUuNzUgMCAwMTEuMDYzLjg1MmwtLjcwOCAyLjgzNmEuNzUuNzUgMCAwMDEuMDYzLjg1M2wuMDQxLS4wMjFNMjEgMTJhOSA5IDAgMTEtMTggMCA5IDkgMCAwMTE4IDB6bS05LTMuNzVoLjAwOHYuMDA4SDEyVjguMjV6XCIgLz5cbiAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInB4LTQgdy0zLzQgdGV4dC1jZW50ZXIgbXQtNFwiPnt7cXVvdGFFeGNlZWRlZH19PC9kaXY+XG4gICAgPC9kaXY+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgW25nSWZdPVwiIWl0ZW1Mb2NrZWRcIj5cbiAgICA8YnV0dG9uICpuZ0lmPVwiIWRyYWdJdGVtXCIgbWF0LW1pbmktZmFiIGNsYXNzPVwiZWRpdC13aWRnZXQgYmctd2hpdGUgdGV4dC1ncmF5LTUwMCBiZy1vcGFjaXR5LTkwXCJcbiAgICAgICAgICAgIFttYXRNZW51VHJpZ2dlckZvcl09XCJlZGl0TWVudVwiPlxuICAgICAgICA8bWF0LWljb24+bW9yZV9ob3JpejwvbWF0LWljb24+XG4gICAgPC9idXR0b24+XG4gICAgPG1hdC1tZW51ICNlZGl0TWVudT1cIm1hdE1lbnVcIj5cbiAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cIiF2aWV3T25seVwiPlxuICAgICAgICAgICAgPGJ1dHRvbiBtYXQtbWVudS1pdGVtIChjbGljayk9XCJjb25maWd1cmUoKVwiPlxuICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5lZGl0PC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICBFZGl0IEl0ZW1cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPGJ1dHRvbiAqbmdJZj1cImV4aXN0aW5nR3JpZEl0ZW1cIiBtYXQtbWVudS1pdGVtIChjbGljayk9XCJkdXBsaWNhdGUoKVwiPlxuICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5jb3B5X2FsbDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgRHVwbGljYXRlIEl0ZW1cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPGJ1dHRvbiAqbmdJZj1cImNhbkV4cG9ydERhdGFcIiBtYXQtbWVudS1pdGVtIChjbGljayk9XCJleHBvcnREYXRhKClcIj5cbiAgICAgICAgICAgICAgICA8bWF0LWljb24+ZmlsZV9kb3dubG9hZDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgRXhwb3J0IERhdGFcbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPG1hdC1kaXZpZGVyPjwvbWF0LWRpdmlkZXI+XG4gICAgICAgICAgICA8YnV0dG9uIG1hdC1tZW51LWl0ZW0gKGNsaWNrKT1cInJlbW92ZVdpZGdldCgkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwidGV4dC1yZWQtNjAwXCI+ZGVsZXRlPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICBEZWxldGUgSXRlbVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJ2aWV3T25seVwiPlxuICAgICAgICAgICAgPGJ1dHRvbiAqbmdJZj1cImNhbkV4cG9ydERhdGFcIiBtYXQtbWVudS1pdGVtIChjbGljayk9XCJleHBvcnREYXRhKClcIj5cbiAgICAgICAgICAgICAgICA8bWF0LWljb24+ZmlsZV9kb3dubG9hZDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgRXhwb3J0IERhdGFcbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPG1hdC1kaXZpZGVyPjwvbWF0LWRpdmlkZXI+XG4gICAgICAgICAgICA8YnV0dG9uIG1hdC1tZW51LWl0ZW0gKGNsaWNrKT1cImVkaXRJdGVtQWxlcnRzKG51bGwpXCI+XG4gICAgICAgICAgICAgICAgPG1hdC1pY29uIGNvbG9yPVwicHJpbWFyeVwiPmFkZDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgPHNwYW4+TmV3IEFsZXJ0PC9zcGFuPlxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBtYXQtbWVudS1pdGVtIGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1iZXR3ZWVuIHAtMCBcIlxuICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydib3JkZXIgYm9yZGVyLXQgYm9yZGVyLWItMCBib3JkZXItci0wIGJvcmRlci1sLTAgYm9yZGVyLXNvbGlkIGJvcmRlci1ncmF5LTIwMCc6IGkgPT09IDB9XCJcbiAgICAgICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBhbGVydCBvZiBkYXNoYm9hcmREYXRhc2V0SW5zdGFuY2UuYWxlcnRzOyBsZXQgaSA9IGluZGV4XCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC00IGZsZXggaXRlbXMtY2VudGVyXCIgKGNsaWNrKT1cImVkaXRJdGVtQWxlcnRzKGFsZXJ0LCBpKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPmVkaXQ8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+e3thbGVydC50aXRsZX19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXgtMiBkaXZpZGVyXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiAoY2xpY2spPVwicmVtb3ZlQWxlcnQoJGV2ZW50LCBhbGVydCwgaSlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJteC0yIHRleHQtcmVkLTYwMCBtLTBcIj5oaWdobGlnaHRfb2ZmPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICA8L21hdC1tZW51PlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlIFtuZ0lmXT1cIiFkcmFnSXRlbSAmJiBkYXNoYm9hcmRJdGVtVHlwZS50eXBlID09PSAnaGVhZGluZydcIj5cblxuICAgIDxkaXYgY2xhc3M9XCJpdGVtLWhlYWRpbmdcIiAqbmdJZj1cIiFkYXNoYm9hcmRJdGVtVHlwZS5fZWRpdGluZ1wiPlxuICAgICAgICB7e2JpbmRQYXJhbWV0ZXJzSW5TdHJpbmcoZGFzaGJvYXJkSXRlbVR5cGUuaGVhZGluZ1ZhbHVlKX19XG4gICAgPC9kaXY+XG5cbiAgICA8aW5wdXQgdHlwZT1cInRleHRcIiAqbmdJZj1cImRhc2hib2FyZEl0ZW1UeXBlLl9lZGl0aW5nXCIgWyhuZ01vZGVsKV09XCJkYXNoYm9hcmRJdGVtVHlwZS5oZWFkaW5nVmFsdWVcIlxuICAgICAgICAgICAoYmx1cik9XCJ1cGRhdGVIZWFkaW5nKCRldmVudClcIiBjbGFzcz1cInctMTEvMTJcIj5cblxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlIFtuZ0lmXT1cIiFkcmFnSXRlbSAmJiAoY2hhcnREYXRhIHx8IGRhdGFzZXQpXCI+XG5cbiAgICA8ZGl2IGNsYXNzPVwiaXRlbS10aXRsZSBcIiAqbmdJZj1cImdlbmVyYWwubmFtZVwiIFtpbm5lckhUTUxdPVwiZ2VuZXJhbC5ldmFsdWF0ZWROYW1lXCJcbiAgICAgICAgIFtuZ0NsYXNzXT1cInsncGItNCc6ICFnZW5lcmFsLmRlc2NyaXB0aW9uLCAncGItMic6IGdlbmVyYWwuZGVzY3JpcHRpb259XCI+PC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiaXRlbS1kZXNjcmlwdGlvbiB0ZXh0LXNtXCIgKm5nSWY9XCJnZW5lcmFsLmRlc2NyaXB0aW9uXCJcbiAgICAgICAgIFtpbm5lckhUTUxdPVwiZ2VuZXJhbC5ldmFsdWF0ZWREZXNjcmlwdGlvblwiPjwvZGl2PlxuXG4gICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImdlbmVyYWwud2lkZ2V0UGFyYW1ldGVycyAmJiBfLnZhbHVlcyhnZW5lcmFsLndpZGdldFBhcmFtZXRlcnMpLmxlbmd0aFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwicC0yIGJnLWdyYXktMTAwIHctZnVsbCBmbGV4IGZsZXgtd3JhcFwiPlxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlIG5nRm9yIGxldC1wYXJhbWV0ZXIgW25nRm9yT2ZdPVwiXy52YWx1ZXMoZ2VuZXJhbC53aWRnZXRQYXJhbWV0ZXJzKVwiIGxldC1pPWluZGV4PlxuICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cIndpZGdldC1wYXJhbWV0ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAge3twYXJhbWV0ZXIudGl0bGV9fVxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicGFyYW1ldGVyLWlucHV0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwicGFyYW1ldGVyLnR5cGUgPT09ICd0ZXh0J1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIHBsYWNlaG9sZGVyPVwiRW50ZXIge3twYXJhbWV0ZXIudGl0bGV9fVwiIFsobmdNb2RlbCldPVwicGFyYW1ldGVyLnZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGtleXVwLmVudGVyKT1cInJlbG9hZFdpZGdldCgpXCIgcmVxdWlyZWQgYXV0b2ZvY3VzPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJwYXJhbWV0ZXIudHlwZSA9PT0gJ251bWVyaWMnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBwbGFjZWhvbGRlcj1cIkVudGVyIHt7cGFyYW1ldGVyLnRpdGxlfX1cIiBbKG5nTW9kZWwpXT1cInBhcmFtZXRlci52YWx1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChrZXl1cC5lbnRlcik9XCJyZWxvYWRXaWRnZXQoKVwiIHJlcXVpcmVkIGF1dG9mb2N1cz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwicGFyYW1ldGVyLnR5cGUgPT09ICdkYXRlJyB8fCBwYXJhbWV0ZXIudHlwZSA9PT0gJ2RhdGV0aW1lJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCIhcGFyYW1ldGVyLl9kYXRlVHlwZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gKGNsaWNrKT1cImNoYW5nZURhdGVUeXBlKCRldmVudCwgcGFyYW1ldGVyLCAncGlja2VyJylcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImhvdmVyOmJnLWdyYXktNTAgdGV4dC1ncmF5LTgwMCBib3JkZXIgYm9yZGVyLWdyYXktMzAwIHB5LTAuNSBwci0yIHJvdW5kZWQgbXItMiBiZy13aGl0ZSBmbGV4IGl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cInRleHQtYmFzZVwiPmNhbGVuZGFyX21vbnRoPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEYXRlIFBpY2tlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIChjbGljayk9XCJjaGFuZ2VEYXRlVHlwZSgkZXZlbnQsIHBhcmFtZXRlciwgJ3BlcmlvZCcpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJob3ZlcjpiZy1ncmF5LTUwIHRleHQtZ3JheS04MDAgYm9yZGVyIGJvcmRlci1ncmF5LTMwMCBweS0wLjUgcHItMiByb3VuZGVkIGJnLXdoaXRlIGZsZXggaXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwidGV4dC1iYXNlXCI+cmVzdG9yZTwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGltZSBQZXJpb2RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJwYXJhbWV0ZXIuX2RhdGVUeXBlID09PSAncGlja2VyJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgW3R5cGVdPVwicGFyYW1ldGVyLnR5cGUgPT09ICdkYXRlJyA/ICdkYXRlJyA6ICdkYXRldGltZS1sb2NhbCdcIiBwbGFjZWhvbGRlcj1cIkVudGVyIHt7cGFyYW1ldGVyLnRpdGxlfX1cIiBbKG5nTW9kZWwpXT1cInBhcmFtZXRlci52YWx1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoa2V5dXAuZW50ZXIpPVwicmVsb2FkV2lkZ2V0KClcIiByZXF1aXJlZCBhdXRvZm9jdXM+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgKGNsaWNrKT1cImNoYW5nZURhdGVUeXBlKCRldmVudCwgcGFyYW1ldGVyLCAncGVyaW9kJylcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRUb29sdGlwPVwiVGltZSBQZXJpb2RcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInRleHQtY2VudGVyIG1sLTIgaG92ZXI6YmctZ3JheS01MCB0ZXh0LWdyYXktODAwIGJvcmRlciBib3JkZXItZ3JheS0zMDAgcHktMC41IHByLTAuNSByb3VuZGVkIG1yLTIgYmctd2hpdGUgZmxleCBpdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cInRleHQtYmFzZVwiPnJlc3RvcmU8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwicGFyYW1ldGVyLl9kYXRlVHlwZSA9PT0gJ3BlcmlvZCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgI3BlcmlvZFZhbHVlIHR5cGU9XCJudW1iZXJcIiBwbGFjZWhvbGRlcj1cIk5vLlwiIHJlcXVpcmVkIGF1dG9mb2N1c1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwidy0xNiBtci0yXCIgbWluPVwiMFwiIFt2YWx1ZV09XCJwYXJhbWV0ZXIuX3BlcmlvZFZhbHVlIHx8IDFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwidXBkYXRlUGVyaW9kVmFsdWUocGVyaW9kVmFsdWUudmFsdWUsIHBlcmlvZC52YWx1ZSwgcGFyYW1ldGVyKVwiPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IGNsYXNzPVwicGFyYW0tcGVyaW9kLXBpY2tlciBtci0yXCIgW3ZhbHVlXT1cInBhcmFtZXRlci5fcGVyaW9kIHx8ICdEQVlTJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNwZXJpb2QgKGNoYW5nZSk9XCJ1cGRhdGVQZXJpb2RWYWx1ZShwZXJpb2RWYWx1ZS52YWx1ZSwgcGVyaW9kLnZhbHVlLCBwYXJhbWV0ZXIpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIkRBWVNcIj5EYXlzPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIkhPVVJTXCI+SG91cnM8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2PkFnbzwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YSAoY2xpY2spPVwiY2hhbmdlRGF0ZVR5cGUoJGV2ZW50LCBwYXJhbWV0ZXIsICdwaWNrZXInKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXA9XCJEYXRlIFBpY2tlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwidGV4dC1jZW50ZXIgbWwtMiBob3ZlcjpiZy1ncmF5LTUwIHRleHQtZ3JheS04MDAgYm9yZGVyIGJvcmRlci1ncmF5LTMwMCBweS0wLjUgcHItMC41IHJvdW5kZWQgbXItMiBiZy13aGl0ZSBmbGV4IGl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwidGV4dC1iYXNlXCI+Y2FsZW5kYXJfbW9udGg8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJwYXJhbWV0ZXIudHlwZSA9PT0gJ2Jvb2xlYW4nXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zbGlkZS10b2dnbGUgY2xhc3M9XCJwci00XCIgY29sb3I9XCJwcmltYXJ5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2hlY2tlZF09XCJwYXJhbWV0ZXIudmFsdWVcIiAoY2hhbmdlKT1cImJvb2xlYW5VcGRhdGUoJGV2ZW50LCBwYXJhbWV0ZXIpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1aXJlZD48L21hdC1zbGlkZS10b2dnbGU+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgIDxkaXYgY2xhc3M9XCJpdGVtLWNvbnRhaW5lclwiIFtuZ0NsYXNzXT1cInsnZmxleCBqdXN0aWZ5LWNlbnRlcic6IGRhc2hib2FyZEl0ZW1UeXBlLnR5cGUgPT09ICdpbWFnZScsXG4gICAgICAgICdwLXB4JzogKGRhc2hib2FyZEl0ZW1UeXBlLnR5cGUgPT09ICd0YWJsZScgfHwgZ2VuZXJhbC50cmFuc3BhcmVudCksICdvdmVyZmxvdy1oaWRkZW4nOiAhIWNoYXJ0RGF0YSxcbiAgICAgICAgJ2ZsZXggaXRlbXMtY2VudGVyJzogZGFzaGJvYXJkSXRlbVR5cGUudHlwZSA9PT0gJ21ldHJpYycsICdjdXJzb3ItcG9pbnRlcic6IChhY3Rpb25JdGVtICYmIE9iamVjdC5rZXlzKGFjdGlvbkl0ZW0pLmxlbmd0aCl9XCJcbiAgICAgICAgIChjbGljayk9XCIoYWN0aW9uSXRlbSAmJiBPYmplY3Qua2V5cyhhY3Rpb25JdGVtKS5sZW5ndGgpID8gY2FsbFRvQWN0aW9uTGluayhhY3Rpb25JdGVtKTogbnVsbFwiPlxuXG4gICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJkYXNoYm9hcmRJdGVtVHlwZS50eXBlID09PSAndGV4dCcgJiYgdGV4dERhdGEudmFsdWVcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoLWZ1bGxcIiAqbmdJZj1cInRleHREYXRhLnNhZmVUZXh0RGF0YVwiIFtpbm5lckhUTUxdPVwidGV4dERhdGEuc2FmZVRleHREYXRhXCI+PC9kaXY+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImRhc2hib2FyZEl0ZW1UeXBlLnR5cGUgPT09ICdtZXRyaWMnXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidy1mdWxsXCI+XG4gICAgICAgICAgICAgICAgPGR0IGNsYXNzPVwidGV4dC1iYXNlIGZvbnQtbm9ybWFsIHRleHQtZ3JheS05MDBcIj57e21ldHJpYy50aXRsZX19PC9kdD5cbiAgICAgICAgICAgICAgICA8ZGQgY2xhc3M9XCJtdC0xIGZsZXggaXRlbXMtYmFzZWxpbmUganVzdGlmeS1iZXR3ZWVuIG1kOmJsb2NrIGxnOmZsZXhcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtYmFzZWxpbmUgdGV4dC0yeGwgZm9udC1zZW1pYm9sZCB0ZXh0LWluZGlnby02MDBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7bWV0cmljLm1haW5WYWx1ZX19XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cIm1ldHJpYy5zdWJNZXRyaWNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJtbC0yIHRleHQtc20gZm9udC1tZWRpdW0gdGV4dC1ncmF5LTUwMFwiPmZyb20ge3ttZXRyaWMuc3ViVmFsdWV9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC14c1wiPih7e21ldHJpYy5zdWJUaXRsZX19KTwvc3Bhbj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJtZXRyaWMuc2hvd1N1YkNoYW5nZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJpbmxpbmUtZmxleCBpdGVtcy1iYXNlbGluZSBweC0yLjUgcHktMC41IHJvdW5kZWQtZnVsbCB0ZXh0LXNtIGZvbnQtbWVkaXVtIG1kOm10LTIgbGc6bXQtMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydiZy1ncmVlbi0xMDAgdGV4dC1ncmVlbi04MDAnOiBtZXRyaWMubWFpblZhbHVlID49IG1ldHJpYy5zdWJWYWx1ZSwgJ2JnLXJlZC0xMDAgdGV4dC1yZWQtODAwJzogbWV0cmljLm1haW5WYWx1ZSA8IG1ldHJpYy5zdWJWYWx1ZX1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gSGVyb2ljb24gbmFtZTogbWluaS9hcnJvdy11cCAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgKm5nSWY9XCJtZXRyaWMubWFpblZhbHVlID49IG1ldHJpYy5zdWJWYWx1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiLW1sLTEgbXItMC41IGgtNSB3LTUgZmxleC1zaHJpbmstMCBzZWxmLWNlbnRlciB0ZXh0LWdyZWVuLTUwMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDIwIDIwXCIgZmlsbD1cImN1cnJlbnRDb2xvclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGZpbGwtcnVsZT1cImV2ZW5vZGRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQ9XCJNMTAgMTdhLjc1Ljc1IDAgMDEtLjc1LS43NVY1LjYxMkw1LjI5IDkuNzdhLjc1Ljc1IDAgMDEtMS4wOC0xLjA0bDUuMjUtNS41YS43NS43NSAwIDAxMS4wOCAwbDUuMjUgNS41YS43NS43NSAwIDExLTEuMDggMS4wNGwtMy45Ni00LjE1OFYxNi4yNUEuNzUuNzUgMCAwMTEwIDE3elwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpcC1ydWxlPVwiZXZlbm9kZFwiLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyAqbmdJZj1cIm1ldHJpYy5tYWluVmFsdWUgPCBtZXRyaWMuc3ViVmFsdWUgXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdCb3g9XCIwIDAgMjAgMjBcIiBmaWxsPVwiY3VycmVudENvbG9yXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCItbWwtMSBtci0wLjUgaC01IHctNSBmbGV4LXNocmluay0wIHNlbGYtY2VudGVyIHRleHQtcmVkLTUwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGZpbGwtcnVsZT1cImV2ZW5vZGRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQ9XCJNMTAgM2EuNzUuNzUgMCAwMS43NS43NXYxMC42MzhsMy45Ni00LjE1OGEuNzUuNzUgMCAxMTEuMDggMS4wNGwtNS4yNSA1LjVhLjc1Ljc1IDAgMDEtMS4wOCAwbC01LjI1LTUuNWEuNzUuNzUgMCAxMTEuMDgtMS4wNGwzLjk2IDQuMTU4VjMuNzVBLjc1Ljc1IDAgMDExMCAzelwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpcC1ydWxlPVwiZXZlbm9kZFwiLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICAgICAge3ttZXRyaWMuZGlmZmVyZW5jZX19XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGQ+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiZGFzaGJvYXJkSXRlbVR5cGUudHlwZSA9PT0gJ25ldHdvcmsnXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidy1mdWxsIGgtZnVsbFwiIFtpZF09XCJpdGVtSW5zdGFuY2VLZXkgKyAnVklTJ1wiPjwvZGl2PlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJkYXNoYm9hcmRJdGVtVHlwZS50eXBlID09PSAnaW1hZ2UnXCI+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiaW1hZ2VEYXRhLnNvdXJjZVwiIGNsYXNzPVwidy1hdXRvIGgtZnVsbFwiPlxuICAgICAgICAgICAgICAgIDxpbWcgW3NyY109XCJpbWFnZURhdGEuc291cmNlXCIgYWx0PVwiXCJcbiAgICAgICAgICAgICAgICAgICAgIChlcnJvcik9XCJpbWFnZUVycm9yID0gdHJ1ZVwiPlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCIhaW1hZ2VEYXRhLnNvdXJjZSB8fCBpbWFnZUVycm9yXCIgY2xhc3M9XCJoLWZ1bGwgcmVsYXRpdmUgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICA8cCBjbGFzcz1cInotMTAgdGV4dC1sZ1wiPk5vIGltYWdlPC9wPlxuICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIGNsYXNzPVwiZmlsdGVyIGJsdXItc20gYWJzb2x1dGUgdy1hdXRvIGgtZnVsbCB0ZXh0LWdyYXktMzAwXCJcbiAgICAgICAgICAgICAgICAgICAgIGZpbGw9XCJub25lXCIgdmlld0JveD1cIjAgMCAyNCAyNFwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiPlxuICAgICAgICAgICAgICAgICAgICA8cGF0aCBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiBzdHJva2Utd2lkdGg9XCIyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZD1cIk00IDE2bDQuNTg2LTQuNTg2YTIgMiAwIDAxMi44MjggMEwxNiAxNm0tMi0ybDEuNTg2LTEuNTg2YTIgMiAwIDAxMi44MjggMEwyMCAxNG0tNi02aC4wMU02IDIwaDEyYTIgMiAwIDAwMi0yVjZhMiAyIDAgMDAtMi0ySDZhMiAyIDAgMDAtMiAydjEyYTIgMiAwIDAwMiAyelwiLz5cbiAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJkYXNoYm9hcmRJdGVtVHlwZS50eXBlID09PSAncGllJyB8fCBkYXNoYm9hcmRJdGVtVHlwZS50eXBlID09PSAnZG91Z2hudXQnXCI+XG4gICAgICAgICAgICA8Y2FudmFzIGJhc2VDaGFydCAqbmdJZj1cImNoYXJ0RGF0YVwiIHN0eWxlPVwiaGVpZ2h0OiAyMDBweFwiXG4gICAgICAgICAgICAgICAgICAgIFtkYXRhc2V0c109XCJjaGFydERhdGFcIlxuICAgICAgICAgICAgICAgICAgICBbbGFiZWxzXT1cImRhc2hib2FyZEl0ZW1UeXBlLmxhYmVsc1wiXG4gICAgICAgICAgICAgICAgICAgIFtvcHRpb25zXT1cInt0b29sdGlwczogeyB0aXRsZUZvbnRTaXplOiAwIH0sIHJlc3BvbnNpdmU6dHJ1ZSwgbWFpbnRhaW5Bc3BlY3RSYXRpbzogZmFsc2V9XCJcbiAgICAgICAgICAgICAgICAgICAgW2xlZ2VuZF09XCIhIWRhc2hib2FyZEl0ZW1UeXBlLmxlZ2VuZFwiXG4gICAgICAgICAgICAgICAgICAgIFt0eXBlXT1cImRhc2hib2FyZEl0ZW1UeXBlLnR5cGVcIlxuICAgICAgICAgICAgICAgICAgICBbcGx1Z2luc109XCJbXVwiPlxuICAgICAgICAgICAgPC9jYW52YXM+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImRhc2hib2FyZEl0ZW1UeXBlLnR5cGUgPT09ICdsaW5lJyB8fCBkYXNoYm9hcmRJdGVtVHlwZS50eXBlID09PSAnYmFyJyB8fCBkYXNoYm9hcmRJdGVtVHlwZS50eXBlID09PSAnc2NhdHRlcidcIj5cbiAgICAgICAgICAgIDxjYW52YXMgYmFzZUNoYXJ0ICpuZ0lmPVwiY2hhcnREYXRhXCIgc3R5bGU9XCJoZWlnaHQ6IDIwMHB4XCJcbiAgICAgICAgICAgICAgICAgICAgW2RhdGFzZXRzXT1cImNoYXJ0RGF0YVwiXG4gICAgICAgICAgICAgICAgICAgIFtsYWJlbHNdPVwiZGFzaGJvYXJkSXRlbVR5cGUubGFiZWxzXCJcbiAgICAgICAgICAgICAgICAgICAgW29wdGlvbnNdPVwie3Rvb2x0aXBzOiB7IHRpdGxlRm9udFNpemU6IDAgfSwgc2NhbGVzOiB7eToge2JlZ2luQXRaZXJvOiBkYXNoYm9hcmRJdGVtVHlwZS5iZWdpbkF0WmVybywgbWF4OiBkYXNoYm9hcmRJdGVtVHlwZS5tYXhWYWx1ZSB8fCBudWxsfX0sIHJlc3BvbnNpdmU6dHJ1ZSwgbWFpbnRhaW5Bc3BlY3RSYXRpbzogZmFsc2V9XCJcbiAgICAgICAgICAgICAgICAgICAgW2xlZ2VuZF09XCIhIWRhc2hib2FyZEl0ZW1UeXBlLmxlZ2VuZFwiXG4gICAgICAgICAgICAgICAgICAgIFt0eXBlXT1cImRhc2hib2FyZEl0ZW1UeXBlLnR5cGVcIlxuICAgICAgICAgICAgICAgICAgICBbcGx1Z2luc109XCJbXVwiPlxuICAgICAgICAgICAgPC9jYW52YXM+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImRhc2hib2FyZEl0ZW1UeXBlLnR5cGUgPT09ICd0YWJsZSdcIj5cblxuICAgICAgICAgICAgPHRhYmxlIGNsYXNzPVwibWluLXctZnVsbCBib3JkZXItc2VwYXJhdGVcIiBzdHlsZT1cImJvcmRlci1zcGFjaW5nOiAwXCI+XG4gICAgICAgICAgICAgICAgPHRoZWFkIGNsYXNzPVwiYmctZ3JheS01MCBcIj5cbiAgICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBuZ0ZvciBsZXQtY29sdW1uIFtuZ0Zvck9mXT1cImRhdGFzZXQuY29sdW1uc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRoIHNjb3BlPVwiY29sXCIgKm5nSWY9XCIhaGlkZGVuQ29sdW1uc1tjb2x1bW4ubmFtZV1cIiAoY2xpY2spPVwic29ydEhlYWRlcihjb2x1bW4pXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImN1cnNvci1wb2ludGVyIHN0aWNreSAtdG9wLXB4IHotMTAgYm9yZGVyLWIgYm9yZGVyLWdyYXktMzAwIGJnLWdyYXktNTAgYmctb3BhY2l0eS03NSBwLTMgdGV4dC1sZWZ0IHRleHQteHMgZm9udC1zZW1pYm9sZCB0ZXh0LWdyYXktOTAwIGJhY2tkcm9wLWJsdXIgYmFja2Ryb3AtZmlsdGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cIiF0YWJsZUNlbGxzW2NvbHVtbi5uYW1lXSB8fCB0YWJsZUNlbGxzW2NvbHVtbi5uYW1lXS50eXBlICE9PSAnYWN0aW9uJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2NvbHVtbi50aXRsZX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgKm5nSWY9XCJjb2x1bW4uZGlyZWN0aW9uID09PSAnYXNjJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIGZpbGw9XCJub25lXCIgdmlld0JveD1cIjAgMCAyNCAyNFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlLXdpZHRoPVwiMS41XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBjbGFzcz1cInN0cm9rZS0zIHRleHQtc2Vjb25kYXJ5IG1sLTEgdy00IGgtNFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQ9XCJNNC41IDEwLjVMMTIgM20wIDBsNy41IDcuNU0xMiAzdjE4XCIvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyAqbmdJZj1cImNvbHVtbi5kaXJlY3Rpb24gPT09ICdkZXNjJ1wiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiBmaWxsPVwibm9uZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld0JveD1cIjAgMCAyNCAyNFwiIHN0cm9rZS13aWR0aD1cIjEuNVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJzdHJva2UtMyB0ZXh0LXNlY29uZGFyeSBtbC0xIHctNCBoLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTE5LjUgMTMuNUwxMiAyMW0wIDBsLTcuNS03LjVNMTIgMjFWM1wiLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgPC90aGVhZD5cbiAgICAgICAgICAgICAgICA8dGJvZHkgY2xhc3M9XCJiZy13aGl0ZSBcIj5cbiAgICAgICAgICAgICAgICA8dHIgKm5nRm9yPVwibGV0IGRhdGFJdGVtIG9mIG9wdGltaXNlID8gZGF0YXNldC5hbGxEYXRhLnNsaWNlKDAsMTApIDogZGF0YXNldC5hbGxEYXRhXCJcbiAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydob3ZlcjpiZy1ncmF5LTUwIGN1cnNvci1wb2ludGVyICc6ICh0YWJ1bGFyLmFjdGlvblJvd3MgJiYgdGFidWxhci5jdGEpfVwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCIodGFidWxhci5hY3Rpb25Sb3dzICYmIHRhYnVsYXIuY3RhKSA/IGNhbGxUb0FjdGlvbkxpbmsodGFidWxhci5jdGEsIGRhdGFJdGVtKSA6IG51bGxcIj5cbiAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIG5nRm9yIGxldC1jb2x1bW4gW25nRm9yT2ZdPVwiZGF0YXNldC5jb2x1bW5zXCIgbGV0LWk9aW5kZXg+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGQgKm5nSWY9XCIhaGlkZGVuQ29sdW1uc1tjb2x1bW4ubmFtZV1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0aXRsZV09XCIodGFibGVDZWxsc1tjb2x1bW4ubmFtZV0gJiYgdGFibGVDZWxsc1tjb2x1bW4ubmFtZV0ubWF4V2lkdGgpID8gZGF0YUl0ZW1bY29sdW1uLm5hbWVdIDogJydcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYm9yZGVyLWIgYm9yZGVyLWdyYXktMjAwICBweC0zIHB5LTIgdGV4dC1zbSB0ZXh0LWdyYXktNTAwIHJlbGF0aXZlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J3doaXRlc3BhY2Utbm93cmFwJzogIXRhYnVsYXIuZXhwYW5kUm93cywgJ2ZvbnQtbWVkaXVtIHRleHQtZ3JheS05MDAnOiBpID09PSAwfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nU3R5bGVdPVwieyd3aWR0aCc6ICcnLCAnbWF4LXdpZHRoJzogKHRhYmxlQ2VsbHNbY29sdW1uLm5hbWVdICYmIHRhYmxlQ2VsbHNbY29sdW1uLm5hbWVdLm1heFdpZHRoKSA/IHRhYmxlQ2VsbHNbY29sdW1uLm5hbWVdLm1heFdpZHRoICsgJ3B4JyA6IG51bGwsICdvdmVyZmxvdyc6ICh0YWJsZUNlbGxzW2NvbHVtbi5uYW1lXSAmJiB0YWJsZUNlbGxzW2NvbHVtbi5uYW1lXS5tYXhXaWR0aCkgPyAnaGlkZGVuJyA6IG51bGwsICd0ZXh0LW92ZXJmbG93JzogKHRhYmxlQ2VsbHNbY29sdW1uLm5hbWVdICYmIHRhYmxlQ2VsbHNbY29sdW1uLm5hbWVdLm1heFdpZHRoKSA/ICdlbGxpcHNpcycgOiBudWxsfVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJ0YWJsZUNlbGxzW2NvbHVtbi5uYW1lXSAmJiB0YWJsZUNlbGxzW2NvbHVtbi5uYW1lXS50eXBlID09PSAnYWN0aW9uJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAqbmdJZj1cInRhYmxlQ2VsbHNbY29sdW1uLm5hbWVdLmRhdGEuYWN0aW9uRXZlbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnYmctb3JhbmdlLTUwIGJvcmRlci1vcmFuZ2UtMjAwIGhvdmVyOmJnLW9yYW5nZS0xMDAnOiBpc0FjdGlvbkNvbXBsZXRlKHRhYmxlQ2VsbHNbY29sdW1uLm5hbWVdLmRhdGEuYWN0aW9uRXZlbnQsIGRhdGFJdGVtW2NvbHVtbi5uYW1lXSl9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwidHJpZ2dlckFjdGlvbkV2ZW50KHRhYmxlQ2VsbHNbY29sdW1uLm5hbWVdLmRhdGEuYWN0aW9uRXZlbnQsIGNvbHVtbiwgZGF0YUl0ZW1bY29sdW1uLm5hbWVdKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0ZXh0LWdyYXktNjAwIGlubGluZS1mbGV4IGl0ZW1zLWNlbnRlciByb3VuZGVkIGJvcmRlciBib3JkZXItcHJpbWFyeSBiZy1ncmF5LTUwIHB4LTIuNSBweS0xLjUgdGV4dC14cyBmb250LW1lZGl1bSBob3ZlcjpiZy1ncmF5LTEwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tnZXRBY3Rpb25FdmVudFRpdGxlKHRhYmxlQ2VsbHNbY29sdW1uLm5hbWVdLmRhdGEuYWN0aW9uRXZlbnQsIGNvbHVtbiwgZGF0YUl0ZW1bY29sdW1uLm5hbWVdKX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiIXRhYmxlQ2VsbHNbY29sdW1uLm5hbWVdIHx8IHRhYmxlQ2VsbHNbY29sdW1uLm5hbWVdLnR5cGUgIT09ICdhY3Rpb24nXCI+XG5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwidGFidWxhci5leHBhbmRSb3dzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiIV8uaXNQbGFpbk9iamVjdChkYXRhSXRlbVtjb2x1bW4ubmFtZV0pXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lubmVySFRNTF09XCJkYXRhSXRlbVtjb2x1bW4ubmFtZV1cIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJfLmlzUGxhaW5PYmplY3QoZGF0YUl0ZW1bY29sdW1uLm5hbWVdKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpbm5lckhUTUxdPVwiZGF0YUl0ZW1bY29sdW1uLm5hbWVdLmNlbGxWYWx1ZVwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiIXRhYnVsYXIuZXhwYW5kUm93cyAmJiBfLmlzUGxhaW5PYmplY3QoZGF0YUl0ZW1bY29sdW1uLm5hbWVdKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBbaW5uZXJIVE1MXT1cImRhdGFJdGVtW2NvbHVtbi5uYW1lXS5jZWxsVmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJ7J21heC13aWR0aCc6ICh0YWJsZUNlbGxzW2NvbHVtbi5uYW1lXSAmJiB0YWJsZUNlbGxzW2NvbHVtbi5uYW1lXS5tYXhXaWR0aCkgPyB0YWJsZUNlbGxzW2NvbHVtbi5uYW1lXS5tYXhXaWR0aCArICdweCcgOiBudWxsLCAnb3ZlcmZsb3cnOiAodGFibGVDZWxsc1tjb2x1bW4ubmFtZV0gJiYgdGFibGVDZWxsc1tjb2x1bW4ubmFtZV0ubWF4V2lkdGgpID8gJ2hpZGRlbicgOiBudWxsLCAndGV4dC1vdmVyZmxvdyc6ICh0YWJsZUNlbGxzW2NvbHVtbi5uYW1lXSAmJiB0YWJsZUNlbGxzW2NvbHVtbi5uYW1lXS5tYXhXaWR0aCkgPyAnZWxsaXBzaXMnIDogbnVsbH1cIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cIiF0YWJ1bGFyLmV4cGFuZFJvd3MgJiYgIV8uaXNQbGFpbk9iamVjdChkYXRhSXRlbVtjb2x1bW4ubmFtZV0pXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdJZl09XCJkYXRhSXRlbVtjb2x1bW4ubmFtZV0gJiYgU3RyaW5nKGRhdGFJdGVtW2NvbHVtbi5uYW1lXSkubGVuZ3RoIDw9IDEwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7ZGF0YUl0ZW1bY29sdW1uLm5hbWVdfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdJZl09XCJkYXRhSXRlbVtjb2x1bW4ubmFtZV0gJiYgU3RyaW5nKGRhdGFJdGVtW2NvbHVtbi5uYW1lXSkubGVuZ3RoID4gMTAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJ7J21heC13aWR0aCc6ICh0YWJsZUNlbGxzW2NvbHVtbi5uYW1lXSAmJiB0YWJsZUNlbGxzW2NvbHVtbi5uYW1lXS5tYXhXaWR0aCkgPyB0YWJsZUNlbGxzW2NvbHVtbi5uYW1lXS5tYXhXaWR0aCArICdweCcgOiBudWxsLCAnb3ZlcmZsb3cnOiAodGFibGVDZWxsc1tjb2x1bW4ubmFtZV0gJiYgdGFibGVDZWxsc1tjb2x1bW4ubmFtZV0ubWF4V2lkdGgpID8gJ2hpZGRlbicgOiBudWxsLCAndGV4dC1vdmVyZmxvdyc6ICh0YWJsZUNlbGxzW2NvbHVtbi5uYW1lXSAmJiB0YWJsZUNlbGxzW2NvbHVtbi5uYW1lXS5tYXhXaWR0aCkgPyAnZWxsaXBzaXMnIDogbnVsbH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdGl0bGVdPVwiZGF0YUl0ZW1bY29sdW1uLm5hbWVdXCI+e3tkYXRhSXRlbVtjb2x1bW4ubmFtZV0uc3Vic3RyaW5nKDAsIDEwMCkgKyAnLi4uJ319PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cIiFkYXRhSXRlbVtjb2x1bW4ubmFtZV1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2RhdGFJdGVtW2NvbHVtbi5uYW1lXX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgICAgICA8dHIgKm5nSWY9XCJvcHRpbWlzZSAmJiBkYXRhc2V0LmFsbERhdGEubGVuZ3RoID4gMTBcIj5cbiAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwicGwtMyB0ZXh0LWdyYXktOTAwIGZvbnQtbWVkaXVtIGJnLWdyYXktMjAwXCIgW2NvbFNwYW5dPVwiZGF0YXNldC5jb2x1bW5zLmxlbmd0aFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgUmVzdWx0cyBsaW1pdGVkIGR1cmluZyBlZGl0aW5nIGZvciBlbmhhbmNlZCBwZXJmb3JtYW5jZS5cbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgIDwvdGJvZHk+XG4gICAgICAgICAgICA8L3RhYmxlPlxuXG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiIWRhdGFzZXQuYWxsRGF0YS5sZW5ndGhcIlxuICAgICAgICAgICAgICAgICBjbGFzcz1cIm5vLXRhYmxlLXJlY29yZHMgdGV4dC1zbSB0ZXh0LWdyYXktNTAwIGZsZXggbS0wIGp1c3RpZnktY2VudGVyIGl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgIE5vIHJlY29yZHMgdG8gc2hvd1xuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImRhc2hib2FyZEl0ZW1UeXBlLnR5cGUgPT09ICd3b3JkcydcIj5cbiAgICAgICAgICAgIDxhbmd1bGFyLWQzLWNsb3VkICpuZ0lmPVwid29yZENsb3VkLmRhdGFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2RhdGFdPVwid29yZENsb3VkLmRhdGFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3dpZHRoXT1cIndvcmRDbG91ZC53aWR0aFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaGVpZ2h0XT1cIndvcmRDbG91ZC5oZWlnaHRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BhZGRpbmddPVwiNVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb250PVwic2VyaWZcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3JvdGF0ZV09XCIwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthdXRvRmlsbF09XCJ0cnVlXCJcbiAgICAgICAgICAgID48L2FuZ3VsYXItZDMtY2xvdWQ+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgKm5nSWY9XCIhb3B0aW1pc2UgJiYgZGFzaGJvYXJkSXRlbVR5cGUudHlwZSA9PT0gJ3RhYmxlJyAmJiAhdGFidWxhci5oaWRlUGFnZXJcIlxuICAgICAgICAgY2xhc3M9XCJ0YWJsZS1wYWdlciBmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWJldHdlZW4gcHgtMiBib3JkZXItdCBib3JkZXItZ3JheS0yMDAgaC0xMiBiZy1ncmF5LTUwIHctZnVsbFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC14cyB0ZXh0LWdyYXktNDAwXCI+XG4gICAgICAgICAgICBTaG93aW5nIHt7b2Zmc2V0ICsgMX19IC0ge3socGFnZSAqIGxpbWl0KSAtIChsaW1pdCAtIGRhdGFzZXQuYWxsRGF0YS5sZW5ndGgpfX08L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyXCI+XG4gICAgICAgICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiAoY2xpY2spPVwiZGVjcmVhc2VPZmZzZXQoKVwiIFtkaXNhYmxlZF09XCJwYWdlIDw9IDFcIj5cbiAgICAgICAgICAgICAgICA8bWF0LWljb24+Y2hldnJvbl9sZWZ0PC9tYXQtaWNvbj5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPHNlbGVjdCBbdmFsdWVdPVwibGltaXRcIiAoY2hhbmdlKT1cInBhZ2VTaXplQ2hhbmdlKCRldmVudC50YXJnZXQudmFsdWUpXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJwLTEgbXgtMlwiPlxuICAgICAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cIjFcIj4xPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwiNVwiPjU8L29wdGlvbj5cbiAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCIxMFwiPjEwPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwiMjVcIj4yNTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cIjUwXCI+NTA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCIxMDBcIj4xMDA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCIyNTBcIj4yNTA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCIxMDAwXCI+MTAwMDwvb3B0aW9uPlxuICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiAoY2xpY2spPVwiaW5jcmVhc2VPZmZzZXQoKVwiIFtkaXNhYmxlZF09XCJlbmRPZlJlc3VsdHNcIj5cbiAgICAgICAgICAgICAgICA8bWF0LWljb24+Y2hldnJvbl9yaWdodDwvbWF0LWljb24+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiZm9vdGVyIHctZnVsbCBiZy1ncmF5LTUwIHB4LTIgcHktMSB0ZXh0LWdyYXktNjAwIGJvcmRlci1iIGJvcmRlci1ncmF5LTIwMCB0ZXh0LXhzXCJcbiAgICAgICAgIFtuZ0NsYXNzXT1cInsnYm9yZGVyLWInOiBjYWxsVG9BY3Rpb24gJiYgT2JqZWN0LmtleXMoY2FsbFRvQWN0aW9uKS5sZW5ndGh9XCJcbiAgICAgICAgICpuZ0lmPVwiZ2VuZXJhbC5mb290ZXJcIiBbaW5uZXJIVE1MXT1cImdlbmVyYWwuZXZhbHVhdGVkRm9vdGVyXCI+PC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiY2FsbC10by1hY3Rpb24gdy1mdWxsIGJnLWdyYXktNTAgcHgtNSBweS0zXCIgKm5nSWY9XCJjYWxsVG9BY3Rpb24gJiYgT2JqZWN0LmtleXMoY2FsbFRvQWN0aW9uKS5sZW5ndGhcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtc21cIj5cbiAgICAgICAgICAgIDxhIGNsYXNzPVwiZm9udC1tZWRpdW0gdGV4dC1jdGEgZmxleCBpdGVtcy1jZW50ZXJcIlxuICAgICAgICAgICAgICAgKGNsaWNrKT1cImNhbGxUb0FjdGlvbkxpbmsoY2FsbFRvQWN0aW9uKVwiPlxuICAgICAgICAgICAgICAgIHt7Y2FsbFRvQWN0aW9uLmxhYmVsfX1cbiAgICAgICAgICAgICAgICA8bWF0LWljb24+Y2hldnJvbl9yaWdodDwvbWF0LWljb24+XG4gICAgICAgICAgICA8L2E+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG48L25nLXRlbXBsYXRlPlxuIl19
|