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,729 +0,0 @@
|
|
|
1
|
-
import { Component, Input } from '@angular/core';
|
|
2
|
-
import * as lodash from 'lodash';
|
|
3
|
-
import { ImportDataComponent } from '../create-datasource/import-data/import-data.component';
|
|
4
|
-
import { ApiAccessComponent } from '../create-datasource/api-access/api-access.component';
|
|
5
|
-
import { AdvancedSettingsComponent } from '../create-datasource/advanced-settings/advanced-settings.component';
|
|
6
|
-
import { ImportWizardComponent } from '../create-datasource/import-data/import-wizard/import-wizard.component';
|
|
7
|
-
import { BehaviorSubject } from 'rxjs';
|
|
8
|
-
import { CreateDatasetComponent } from '../../dataset/create-dataset/create-dataset.component';
|
|
9
|
-
import shortHash from 'short-hash';
|
|
10
|
-
import * as i0 from "@angular/core";
|
|
11
|
-
import * as i1 from "@angular/material/legacy-dialog";
|
|
12
|
-
import * as i2 from "@angular/router";
|
|
13
|
-
import * as i3 from "../../../services/datasource.service";
|
|
14
|
-
import * as i4 from "../../../services/dataset.service";
|
|
15
|
-
import * as i5 from "@angular/material/legacy-snack-bar";
|
|
16
|
-
import * as i6 from "@angular/common";
|
|
17
|
-
import * as i7 from "@angular/material/legacy-button";
|
|
18
|
-
import * as i8 from "@angular/material/icon";
|
|
19
|
-
import * as i9 from "@angular/material/legacy-menu";
|
|
20
|
-
import * as i10 from "@angular/forms";
|
|
21
|
-
import * as i11 from "@angular/material/legacy-checkbox";
|
|
22
|
-
import * as i12 from "@angular/material/legacy-tooltip";
|
|
23
|
-
import * as i13 from "../../dataset/dataset-editor/dataset-filters/dataset-filters.component";
|
|
24
|
-
const _ = lodash.default;
|
|
25
|
-
export class CreateDatasourceComponent {
|
|
26
|
-
constructor(dialog, route, datasourceService, datasetService, snackbar, location, router) {
|
|
27
|
-
this.dialog = dialog;
|
|
28
|
-
this.route = route;
|
|
29
|
-
this.datasourceService = datasourceService;
|
|
30
|
-
this.datasetService = datasetService;
|
|
31
|
-
this.snackbar = snackbar;
|
|
32
|
-
this.location = location;
|
|
33
|
-
this.router = router;
|
|
34
|
-
this.backURL = '/imported-data';
|
|
35
|
-
this.reloadURL = 'import-data';
|
|
36
|
-
this.namePrefix = '';
|
|
37
|
-
this.readonly = false;
|
|
38
|
-
this.automaticImportKey = false;
|
|
39
|
-
this.hideAPIAccess = false;
|
|
40
|
-
this.editColumns = true;
|
|
41
|
-
this.filterJunction = {
|
|
42
|
-
logic: 'AND',
|
|
43
|
-
filters: [{
|
|
44
|
-
lhsExpression: '',
|
|
45
|
-
rhsExpression: [],
|
|
46
|
-
filterType: ''
|
|
47
|
-
}],
|
|
48
|
-
filterJunctions: []
|
|
49
|
-
};
|
|
50
|
-
this.datasourceTypes = {
|
|
51
|
-
string: 'Text (up to 255 chars)',
|
|
52
|
-
mediumstring: 'Medium Text (up to 32767 chars)',
|
|
53
|
-
longstring: 'Long Text (more than 32767 chars)',
|
|
54
|
-
integer: 'Number (whole number)',
|
|
55
|
-
biginteger: 'Number (large number)',
|
|
56
|
-
boolean: 'Tick (Yes / No)',
|
|
57
|
-
float: 'Decimal number',
|
|
58
|
-
date: 'Date',
|
|
59
|
-
datetime: 'Date and Time',
|
|
60
|
-
pickfromsource: 'Pick From List (using another source)',
|
|
61
|
-
json: 'Nested JSON Object'
|
|
62
|
-
};
|
|
63
|
-
this.rows = [];
|
|
64
|
-
this.columns = [
|
|
65
|
-
{
|
|
66
|
-
title: 'Column 1',
|
|
67
|
-
name: 'column_1',
|
|
68
|
-
type: 'string'
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
title: 'Column 2',
|
|
72
|
-
name: 'column_2',
|
|
73
|
-
type: 'string'
|
|
74
|
-
}
|
|
75
|
-
];
|
|
76
|
-
this.selectedItem = {};
|
|
77
|
-
this._ = _;
|
|
78
|
-
this.showUpload = false;
|
|
79
|
-
this.headerRow = false;
|
|
80
|
-
this.adds = [];
|
|
81
|
-
this.updates = [];
|
|
82
|
-
this.deletes = [];
|
|
83
|
-
this.invalidItems = [];
|
|
84
|
-
this.editMode = false;
|
|
85
|
-
this.autoIncrementColumn = false;
|
|
86
|
-
this.datasourceUpdate = {
|
|
87
|
-
title: '',
|
|
88
|
-
instanceImportKey: '',
|
|
89
|
-
fields: [],
|
|
90
|
-
adds: [],
|
|
91
|
-
updates: [],
|
|
92
|
-
deletes: []
|
|
93
|
-
};
|
|
94
|
-
this.offset = 0;
|
|
95
|
-
this.limit = 25;
|
|
96
|
-
this.page = 1;
|
|
97
|
-
this.endOfResults = false;
|
|
98
|
-
this.showAutoIncrement = false;
|
|
99
|
-
this.selectAll = false;
|
|
100
|
-
this.showFilters = false;
|
|
101
|
-
this.filterFields = [];
|
|
102
|
-
this.sortConfig = null;
|
|
103
|
-
this.openSide = new BehaviorSubject(false);
|
|
104
|
-
this.Object = Object;
|
|
105
|
-
this.isMouseDown = false;
|
|
106
|
-
this.startRowIndex = null;
|
|
107
|
-
this.startCellIndex = null;
|
|
108
|
-
this.endRowIndex = null;
|
|
109
|
-
this.endCellIndex = null;
|
|
110
|
-
this.selectedCell = null;
|
|
111
|
-
// Associative list of pick from datasets used for list selection
|
|
112
|
-
this.columnPickFromDatasets = {};
|
|
113
|
-
}
|
|
114
|
-
ngOnInit() {
|
|
115
|
-
this.datasourceInstanceKey = this.route.snapshot.params.key;
|
|
116
|
-
if (this.datasourceInstanceKey) {
|
|
117
|
-
this.showAutoIncrement = localStorage.getItem(this.datasourceInstanceKey + '_show_id') === 'true';
|
|
118
|
-
this.loadDatasource();
|
|
119
|
-
}
|
|
120
|
-
else {
|
|
121
|
-
const dialogRef = this.dialog.open(ImportWizardComponent, {
|
|
122
|
-
width: '800px',
|
|
123
|
-
height: '900px',
|
|
124
|
-
disableClose: true,
|
|
125
|
-
data: {
|
|
126
|
-
columns: this.columns,
|
|
127
|
-
datasourceUpdate: this.datasourceUpdate,
|
|
128
|
-
rows: this.rows,
|
|
129
|
-
datasourceInstanceKey: this.datasourceInstanceKey,
|
|
130
|
-
reloadURL: this.reloadURL,
|
|
131
|
-
namePrefix: this.namePrefix,
|
|
132
|
-
automaticImportKey: this.automaticImportKey
|
|
133
|
-
}
|
|
134
|
-
});
|
|
135
|
-
dialogRef.afterClosed().subscribe(res => {
|
|
136
|
-
if (res === 'closed') {
|
|
137
|
-
this.location.back();
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
ngAfterViewInit() {
|
|
143
|
-
if (this.sidenavService) {
|
|
144
|
-
setTimeout(() => {
|
|
145
|
-
this.sidenavService.close();
|
|
146
|
-
}, 100);
|
|
147
|
-
}
|
|
148
|
-
document.addEventListener('mouseup', () => {
|
|
149
|
-
this.isMouseDown = false;
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
ngOnDestroy() {
|
|
153
|
-
if (this.sidenavService) {
|
|
154
|
-
this.sidenavService.open();
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
clearFilter() {
|
|
158
|
-
this.filterJunction = {
|
|
159
|
-
logic: 'AND',
|
|
160
|
-
filters: [{
|
|
161
|
-
lhsExpression: '',
|
|
162
|
-
rhsExpression: [],
|
|
163
|
-
filterType: ''
|
|
164
|
-
}],
|
|
165
|
-
filterJunctions: []
|
|
166
|
-
};
|
|
167
|
-
this.loadDatasource();
|
|
168
|
-
}
|
|
169
|
-
applyFilter() {
|
|
170
|
-
this.loadDatasource();
|
|
171
|
-
}
|
|
172
|
-
sortColumn(column, direction) {
|
|
173
|
-
this.sortConfig = { fieldName: column.name, direction };
|
|
174
|
-
this.loadDatasource();
|
|
175
|
-
}
|
|
176
|
-
updateSelectAll() {
|
|
177
|
-
this.rows.map(row => {
|
|
178
|
-
row._selected = this.selectAll;
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
updateSelected() {
|
|
182
|
-
this.selectAll = _.every(this.rows, '_selected');
|
|
183
|
-
}
|
|
184
|
-
updateAutoIncrementColumn(value) {
|
|
185
|
-
if (value) {
|
|
186
|
-
this.columns.map(column => {
|
|
187
|
-
column.keyField = false;
|
|
188
|
-
return column;
|
|
189
|
-
});
|
|
190
|
-
this.columns.unshift({
|
|
191
|
-
title: 'ID',
|
|
192
|
-
name: 'id',
|
|
193
|
-
type: 'id'
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
else {
|
|
197
|
-
_.remove(this.columns, { type: 'id' });
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
addColumn(index) {
|
|
201
|
-
this.selectedItem = {
|
|
202
|
-
_tableType: 'column',
|
|
203
|
-
type: 'string'
|
|
204
|
-
};
|
|
205
|
-
if (index > -1) {
|
|
206
|
-
this.columns.splice(index, 0, this.selectedItem);
|
|
207
|
-
this.selectedItem._index = index;
|
|
208
|
-
}
|
|
209
|
-
else {
|
|
210
|
-
this.columns.push(this.selectedItem);
|
|
211
|
-
this.selectedItem._index = this.columns.length - 1;
|
|
212
|
-
}
|
|
213
|
-
setTimeout(() => {
|
|
214
|
-
document.getElementById(this.selectedItem.type + this.selectedItem._index).scrollIntoView();
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
import() {
|
|
218
|
-
const dialogRef = this.dialog.open(ImportDataComponent, {
|
|
219
|
-
width: '800px',
|
|
220
|
-
height: '900px',
|
|
221
|
-
data: {
|
|
222
|
-
columns: this.columns,
|
|
223
|
-
datasourceUpdate: this.datasourceUpdate,
|
|
224
|
-
rows: this.rows,
|
|
225
|
-
datasourceInstanceKey: this.datasourceInstanceKey,
|
|
226
|
-
reloadURL: this.reloadURL
|
|
227
|
-
}
|
|
228
|
-
});
|
|
229
|
-
dialogRef.afterClosed().subscribe(res => {
|
|
230
|
-
if (res) {
|
|
231
|
-
if (!this.selectedCell) {
|
|
232
|
-
const rowColIndex = 0;
|
|
233
|
-
this.selectedCell = { rowIndex: 0, rowColIndex };
|
|
234
|
-
}
|
|
235
|
-
if (res.headerRow) {
|
|
236
|
-
const columns = [];
|
|
237
|
-
res.data[0].forEach(header => {
|
|
238
|
-
columns.push({
|
|
239
|
-
title: header,
|
|
240
|
-
name: _.snakeCase(header),
|
|
241
|
-
type: 'string'
|
|
242
|
-
});
|
|
243
|
-
});
|
|
244
|
-
this.columns = columns;
|
|
245
|
-
res.data.shift();
|
|
246
|
-
this.insertCellData(res.data);
|
|
247
|
-
}
|
|
248
|
-
else {
|
|
249
|
-
this.insertCellData(res.data);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
async deleteSelectedEntries() {
|
|
255
|
-
const message = 'Are you sure you would like to remove all of the selected entries? This action cannot be reversed.';
|
|
256
|
-
if (window.confirm(message)) {
|
|
257
|
-
const selected = _.filter(this.rows, '_selected');
|
|
258
|
-
await this.datasourceService.updateCustomDatasource(this.datasourceInstanceKey, {
|
|
259
|
-
title: this.datasourceUpdate.title,
|
|
260
|
-
importKey: this.datasourceUpdate.instanceImportKey || '',
|
|
261
|
-
fields: this.datasourceUpdate.fields,
|
|
262
|
-
adds: [],
|
|
263
|
-
updates: [],
|
|
264
|
-
deletes: selected
|
|
265
|
-
});
|
|
266
|
-
window.location.href = this.reloadURL + '/' + this.datasourceInstanceKey;
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
addFilter() {
|
|
270
|
-
}
|
|
271
|
-
advancedSettings() {
|
|
272
|
-
const dialogRef = this.dialog.open(AdvancedSettingsComponent, {
|
|
273
|
-
width: '800px',
|
|
274
|
-
height: '900px',
|
|
275
|
-
data: {
|
|
276
|
-
datasourceUpdate: this.datasourceUpdate,
|
|
277
|
-
datasourceInstanceKey: this.datasourceInstanceKey,
|
|
278
|
-
backendURL: this.backendURL,
|
|
279
|
-
columns: this.columns,
|
|
280
|
-
showAutoIncrement: this.showAutoIncrement
|
|
281
|
-
}
|
|
282
|
-
});
|
|
283
|
-
dialogRef.afterClosed().subscribe(advancedSettings => {
|
|
284
|
-
if (advancedSettings) {
|
|
285
|
-
this.columns = advancedSettings.columns;
|
|
286
|
-
this.datasourceUpdate.indexes = advancedSettings.datasourceUpdate.indexes;
|
|
287
|
-
this.showAutoIncrement = advancedSettings.showAutoIncrement;
|
|
288
|
-
localStorage.setItem(this.datasourceInstanceKey + '_show_id', String(this.showAutoIncrement));
|
|
289
|
-
}
|
|
290
|
-
});
|
|
291
|
-
}
|
|
292
|
-
apiAccess() {
|
|
293
|
-
const dialogRef = this.dialog.open(ApiAccessComponent, {
|
|
294
|
-
width: '800px',
|
|
295
|
-
height: '900px',
|
|
296
|
-
data: {
|
|
297
|
-
datasourceUpdate: this.datasourceUpdate,
|
|
298
|
-
datasourceInstanceKey: this.datasourceInstanceKey,
|
|
299
|
-
backendURL: this.backendURL,
|
|
300
|
-
columns: this.columns
|
|
301
|
-
}
|
|
302
|
-
});
|
|
303
|
-
dialogRef.afterClosed().subscribe(res => {
|
|
304
|
-
});
|
|
305
|
-
}
|
|
306
|
-
selectColumn(column, index) {
|
|
307
|
-
if (this.editColumns && !column.autoIncrement) {
|
|
308
|
-
this.selectedCell = null;
|
|
309
|
-
document.querySelectorAll('.datasource-table .bg-indigo-50').forEach(element => {
|
|
310
|
-
element.classList.remove('bg-indigo-50');
|
|
311
|
-
});
|
|
312
|
-
if (index === this.selectedItem._index) {
|
|
313
|
-
this.selectedItem = {};
|
|
314
|
-
}
|
|
315
|
-
else {
|
|
316
|
-
column._tableType = 'column';
|
|
317
|
-
column._index = index;
|
|
318
|
-
if (!column.previousName) {
|
|
319
|
-
column.previousName = column.name;
|
|
320
|
-
}
|
|
321
|
-
this.selectedItem = column;
|
|
322
|
-
this.removeCellFocusBorder();
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
deleteColumn(index) {
|
|
327
|
-
this.columns.splice(index, 1);
|
|
328
|
-
}
|
|
329
|
-
addRow(index) {
|
|
330
|
-
const row = {};
|
|
331
|
-
this.columns.forEach(column => {
|
|
332
|
-
row[column.name] = null;
|
|
333
|
-
});
|
|
334
|
-
if (index > -1) {
|
|
335
|
-
this.rows.splice(index, 0, row);
|
|
336
|
-
this.adds.push(index);
|
|
337
|
-
}
|
|
338
|
-
else {
|
|
339
|
-
this.rows.push(row);
|
|
340
|
-
this.adds.push(this.rows.length - 1);
|
|
341
|
-
}
|
|
342
|
-
setTimeout(() => {
|
|
343
|
-
const tableWrapper = document.getElementById('tableWrapper');
|
|
344
|
-
tableWrapper.scrollTop = tableWrapper.scrollHeight;
|
|
345
|
-
}, 0);
|
|
346
|
-
}
|
|
347
|
-
deleteRow(rowIndex) {
|
|
348
|
-
const inAdds = this.adds.indexOf(rowIndex);
|
|
349
|
-
if (inAdds > -1) {
|
|
350
|
-
this.rows.splice(rowIndex, 1);
|
|
351
|
-
this.adds.pop();
|
|
352
|
-
}
|
|
353
|
-
else {
|
|
354
|
-
this.deletes.push(rowIndex);
|
|
355
|
-
}
|
|
356
|
-
const inUpdates = this.updates.indexOf(rowIndex);
|
|
357
|
-
if (inUpdates > -1) {
|
|
358
|
-
this.updates.splice(inUpdates, 1);
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
focusCell(event, rowIndex, rowColIndex) {
|
|
362
|
-
this.selectedCell = { rowIndex, rowColIndex };
|
|
363
|
-
this.removeCellFocusBorder();
|
|
364
|
-
event.target.parentElement.classList.add('border', 'border-blue-500');
|
|
365
|
-
}
|
|
366
|
-
blurCell() {
|
|
367
|
-
this.selectedCell = null;
|
|
368
|
-
this.removeCellFocusBorder();
|
|
369
|
-
}
|
|
370
|
-
clearCell(rowIndex, rowColIndex) {
|
|
371
|
-
const columnName = this.columns[rowColIndex].name;
|
|
372
|
-
this.rows[rowIndex][columnName] = '';
|
|
373
|
-
if (this.adds.indexOf(rowIndex) === -1) {
|
|
374
|
-
this.updates.push(rowIndex);
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
updateField(field, rowIndex, event) {
|
|
378
|
-
if (this.adds.indexOf(rowIndex) === -1) {
|
|
379
|
-
if (this.updates.indexOf(rowIndex) === -1) {
|
|
380
|
-
this.updates.push(rowIndex);
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
// Handle implicit false values for booleans and implicit nulls for other fields
|
|
384
|
-
if (field.type == 'boolean') {
|
|
385
|
-
this.rows[rowIndex][field.name] = event.target.checked;
|
|
386
|
-
}
|
|
387
|
-
else {
|
|
388
|
-
if (this.rows[rowIndex][field.name] === '')
|
|
389
|
-
this.rows[rowIndex][field.name] = null;
|
|
390
|
-
}
|
|
391
|
-
this.editMode = true;
|
|
392
|
-
}
|
|
393
|
-
updateColumnName() {
|
|
394
|
-
this.selectedItem.name = _.snakeCase(this.selectedItem.title);
|
|
395
|
-
this.rows.map(row => {
|
|
396
|
-
row[this.selectedItem.name] = row[this.selectedItem.previousName] || '';
|
|
397
|
-
if (row[this.selectedItem.previousName]) {
|
|
398
|
-
delete row[this.selectedItem.previousName];
|
|
399
|
-
}
|
|
400
|
-
return row;
|
|
401
|
-
});
|
|
402
|
-
}
|
|
403
|
-
enterCell(rowIndex, rowColIndex, event) {
|
|
404
|
-
const row = {};
|
|
405
|
-
let rowElement = null;
|
|
406
|
-
let rowElementIndex;
|
|
407
|
-
this.columns.forEach(column => {
|
|
408
|
-
row[column.name] = '';
|
|
409
|
-
});
|
|
410
|
-
if (rowIndex === this.rows.length - 1) {
|
|
411
|
-
this.rows.push(row);
|
|
412
|
-
rowElementIndex = this.rows.length - 1;
|
|
413
|
-
this.adds.push(this.rows.length - 1);
|
|
414
|
-
}
|
|
415
|
-
else {
|
|
416
|
-
rowElementIndex = rowIndex + 1;
|
|
417
|
-
}
|
|
418
|
-
setTimeout(() => {
|
|
419
|
-
rowElement = document.querySelectorAll('.table-rows').item(rowElementIndex);
|
|
420
|
-
const rowCell = rowElement.querySelectorAll('.row-cell').item(this.showAutoIncrement ? rowColIndex + 1 : rowColIndex);
|
|
421
|
-
rowCell.querySelectorAll('.cell-input').item(0).focus();
|
|
422
|
-
}, 0);
|
|
423
|
-
}
|
|
424
|
-
async save(exit = false) {
|
|
425
|
-
if (!this.datasourceUpdate.title) {
|
|
426
|
-
window.alert('Please enter a title for this Datasource.');
|
|
427
|
-
return;
|
|
428
|
-
}
|
|
429
|
-
if (!_.find(this.columns, { keyField: true }) &&
|
|
430
|
-
!_.find(this.columns, { type: 'id' })) {
|
|
431
|
-
window.alert('Please select one of your fields as the "Unique Key"');
|
|
432
|
-
return;
|
|
433
|
-
}
|
|
434
|
-
this.datasourceUpdate.fields = this.columns.map(column => {
|
|
435
|
-
if (column.name === column.previousName) {
|
|
436
|
-
delete column.previousName;
|
|
437
|
-
}
|
|
438
|
-
return column;
|
|
439
|
-
});
|
|
440
|
-
const changes = ['adds', 'updates', 'deletes'];
|
|
441
|
-
changes.forEach(change => {
|
|
442
|
-
this.datasourceUpdate[change] = _.map(_.uniq(this[change]), rowIndex => {
|
|
443
|
-
return this.rows[rowIndex];
|
|
444
|
-
});
|
|
445
|
-
});
|
|
446
|
-
if (this.namePrefix && !this.datasourceUpdate.title.includes(this.namePrefix)) {
|
|
447
|
-
this.datasourceUpdate.title = this.namePrefix + this.datasourceUpdate.title;
|
|
448
|
-
}
|
|
449
|
-
// Reset invalid items
|
|
450
|
-
this.invalidItems = [];
|
|
451
|
-
if (!this.datasourceInstanceKey) {
|
|
452
|
-
if (this.automaticImportKey) {
|
|
453
|
-
this.datasourceUpdate.importKey = shortHash(Date.now().toString());
|
|
454
|
-
}
|
|
455
|
-
await this.datasourceService.createCustomDatasource(this.datasourceUpdate).then(key => {
|
|
456
|
-
if (!exit) {
|
|
457
|
-
window.location.href = this.reloadURL + '/' + key;
|
|
458
|
-
}
|
|
459
|
-
return true;
|
|
460
|
-
}).catch(err => {
|
|
461
|
-
const errorCode = (err.error && err.error.sqlStateCode) ? err.error.sqlStateCode : 0;
|
|
462
|
-
this.displayError(errorCode);
|
|
463
|
-
});
|
|
464
|
-
}
|
|
465
|
-
else {
|
|
466
|
-
this.datasourceUpdate.importKey = this.datasourceUpdate.instanceImportKey;
|
|
467
|
-
await this.datasourceService.updateCustomDatasource(this.datasourceInstanceKey, this.datasourceUpdate)
|
|
468
|
-
.then(async (result) => {
|
|
469
|
-
if (result && result.rejected && result.rejected > 0) {
|
|
470
|
-
this.snackbar.open('There were validation problems with one or more of your rows - see highlighted cells below', null, {
|
|
471
|
-
duration: 5000,
|
|
472
|
-
verticalPosition: 'top'
|
|
473
|
-
});
|
|
474
|
-
const invalidAddRows = _.map(result.validationErrors.add || [], 'itemNumber');
|
|
475
|
-
for (let i = this.adds.length - 1; i >= 0; i--) {
|
|
476
|
-
if (invalidAddRows.includes(i)) {
|
|
477
|
-
this.invalidItems[this.adds[i]] = _.find(result.validationErrors.add, { itemNumber: i }).validationErrors;
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
const invalidUpdateRows = _.map(result.validationErrors.update || [], 'itemNumber');
|
|
481
|
-
for (let i = this.updates.length - 1; i >= 0; i--) {
|
|
482
|
-
if (invalidUpdateRows.includes(i)) {
|
|
483
|
-
this.invalidItems[this.updates[i]] = _.find(result.validationErrors.update, { itemNumber: i }).validationErrors;
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
else {
|
|
488
|
-
this.adds = [];
|
|
489
|
-
this.updates = [];
|
|
490
|
-
this.deletes = [];
|
|
491
|
-
await this.loadDatasource();
|
|
492
|
-
}
|
|
493
|
-
return true;
|
|
494
|
-
})
|
|
495
|
-
.catch(err => {
|
|
496
|
-
console.log('ERROR', err);
|
|
497
|
-
const errorCode = (err.error && err.error.sqlStateCode) ? err.error.sqlStateCode : 0;
|
|
498
|
-
this.displayError(errorCode);
|
|
499
|
-
});
|
|
500
|
-
}
|
|
501
|
-
if (exit) {
|
|
502
|
-
return this.router.navigate([this.backURL]);
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
cancelChanges() {
|
|
506
|
-
this.adds = [];
|
|
507
|
-
this.updates = [];
|
|
508
|
-
this.deletes = [];
|
|
509
|
-
this.loadDatasource();
|
|
510
|
-
}
|
|
511
|
-
setTypeConfig() {
|
|
512
|
-
if (!this.selectedItem.typeConfig || Array.isArray(this.selectedItem.typeConfig)) {
|
|
513
|
-
this.selectedItem.typeConfig = {};
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
deleteSelectedColumn() {
|
|
517
|
-
this.columns.splice(this.selectedItem._index, 1);
|
|
518
|
-
}
|
|
519
|
-
pageSizeChange(value) {
|
|
520
|
-
this.limit = value;
|
|
521
|
-
this.loadDatasource();
|
|
522
|
-
}
|
|
523
|
-
increaseOffset() {
|
|
524
|
-
this.page = this.page + 1;
|
|
525
|
-
this.offset = (this.limit * this.page) - this.limit;
|
|
526
|
-
this.loadDatasource();
|
|
527
|
-
}
|
|
528
|
-
decreaseOffset() {
|
|
529
|
-
this.page = this.page <= 1 ? 1 : this.page - 1;
|
|
530
|
-
this.offset = (this.limit * this.page) - this.limit;
|
|
531
|
-
this.loadDatasource();
|
|
532
|
-
}
|
|
533
|
-
// Get input type for field
|
|
534
|
-
inputTypeForField(field) {
|
|
535
|
-
switch (field.type) {
|
|
536
|
-
case 'integer':
|
|
537
|
-
case 'float':
|
|
538
|
-
return 'number';
|
|
539
|
-
case 'boolean':
|
|
540
|
-
return 'checkbox';
|
|
541
|
-
case 'date':
|
|
542
|
-
return 'date';
|
|
543
|
-
case 'datetime':
|
|
544
|
-
return 'datetime-local';
|
|
545
|
-
default:
|
|
546
|
-
return 'text';
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
loadDatasource() {
|
|
550
|
-
if (this.datasourceInstanceKey) {
|
|
551
|
-
// If we have a filter in use, apply it to the next load...
|
|
552
|
-
const transformationInstances = [];
|
|
553
|
-
if (this.filterJunction.filterJunctions.length || this.filterJunction.filters[0].filterType) {
|
|
554
|
-
transformationInstances.push({ type: 'filter', config: this.filterJunction });
|
|
555
|
-
}
|
|
556
|
-
if (this.sortConfig) {
|
|
557
|
-
transformationInstances.push({ type: 'multisort', config: { sorts: [this.sortConfig] } });
|
|
558
|
-
}
|
|
559
|
-
const evaluatedDatasource = {
|
|
560
|
-
key: this.datasourceInstanceKey,
|
|
561
|
-
transformationInstances,
|
|
562
|
-
parameterValues: {},
|
|
563
|
-
offset: this.offset,
|
|
564
|
-
limit: this.limit
|
|
565
|
-
};
|
|
566
|
-
this.datasourceService.evaluateDatasource(evaluatedDatasource).then((res) => {
|
|
567
|
-
let jsonColumns = [];
|
|
568
|
-
this.columns = res.columns.map(column => {
|
|
569
|
-
column.previousName = column.name;
|
|
570
|
-
if (column.type === 'pickfromsource') {
|
|
571
|
-
if (!this.columnPickFromDatasets[column.name]) {
|
|
572
|
-
this.populateColumnPickFrom(column);
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
else if (column.type === 'json') {
|
|
576
|
-
jsonColumns.push(column.name);
|
|
577
|
-
}
|
|
578
|
-
return column;
|
|
579
|
-
});
|
|
580
|
-
this.filterFields = _.map(this.columns, column => {
|
|
581
|
-
return {
|
|
582
|
-
title: column.title,
|
|
583
|
-
name: column.name
|
|
584
|
-
};
|
|
585
|
-
});
|
|
586
|
-
this.rows = res.allData;
|
|
587
|
-
// If JSON Columns, ensure we deserialise JSON values
|
|
588
|
-
if (jsonColumns.length) {
|
|
589
|
-
this.rows.forEach(row => {
|
|
590
|
-
jsonColumns.forEach(jsonColumn => {
|
|
591
|
-
if (row[jsonColumn] || null)
|
|
592
|
-
row[jsonColumn] = JSON.stringify(row[jsonColumn]);
|
|
593
|
-
});
|
|
594
|
-
});
|
|
595
|
-
}
|
|
596
|
-
this.endOfResults = this.rows.length < this.limit;
|
|
597
|
-
this.datasourceUpdate.title = res.instanceTitle;
|
|
598
|
-
this.datasourceUpdate.instanceImportKey = res.instanceImportKey;
|
|
599
|
-
this.datasourceUpdate.indexes = res.indexes;
|
|
600
|
-
this.datasourceUpdate.adds = [];
|
|
601
|
-
this.datasourceUpdate.updates = [];
|
|
602
|
-
this.datasourceUpdate.deletes = [];
|
|
603
|
-
this.autoIncrementColumn = _.some(this.columns, { type: 'id' });
|
|
604
|
-
this.selectAll = false;
|
|
605
|
-
});
|
|
606
|
-
}
|
|
607
|
-
this.editMode = false;
|
|
608
|
-
}
|
|
609
|
-
selectCell(rowIndex, cellIndex) {
|
|
610
|
-
let rowStart, rowEnd, cellStart, cellEnd;
|
|
611
|
-
if (rowIndex < this.startRowIndex) {
|
|
612
|
-
rowStart = rowIndex;
|
|
613
|
-
rowEnd = this.startRowIndex;
|
|
614
|
-
}
|
|
615
|
-
else {
|
|
616
|
-
rowStart = this.startRowIndex;
|
|
617
|
-
rowEnd = rowIndex;
|
|
618
|
-
}
|
|
619
|
-
if (cellIndex < this.startCellIndex) {
|
|
620
|
-
cellStart = cellIndex;
|
|
621
|
-
cellEnd = this.startCellIndex;
|
|
622
|
-
}
|
|
623
|
-
else {
|
|
624
|
-
cellStart = this.startCellIndex;
|
|
625
|
-
cellEnd = cellIndex;
|
|
626
|
-
}
|
|
627
|
-
for (let i = rowStart; i <= rowEnd; i++) {
|
|
628
|
-
const rowElement = document.querySelectorAll('.table-rows').item(i);
|
|
629
|
-
const rowCells = rowElement.querySelectorAll('td');
|
|
630
|
-
for (let j = cellStart; j <= cellEnd; j++) {
|
|
631
|
-
rowCells.item(j).classList.add('bg-indigo-50');
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
removeCellFocusBorder() {
|
|
636
|
-
document.querySelectorAll('.input-wrapper.border-blue-500').forEach(element => {
|
|
637
|
-
element.classList.remove('border-blue-500');
|
|
638
|
-
});
|
|
639
|
-
}
|
|
640
|
-
insertCellData(data) {
|
|
641
|
-
const row = {};
|
|
642
|
-
this.columns.forEach(column => {
|
|
643
|
-
row[column.name] = '';
|
|
644
|
-
});
|
|
645
|
-
let startIndex = this.selectedCell.rowIndex;
|
|
646
|
-
while (this.rows.length < (data.length + this.selectedCell.rowIndex)) {
|
|
647
|
-
this.rows.push(_.clone(row));
|
|
648
|
-
this.deletes.splice(startIndex, 1);
|
|
649
|
-
this.updates.splice(startIndex, 1);
|
|
650
|
-
this.adds.splice(startIndex, 1);
|
|
651
|
-
this.adds.push(startIndex);
|
|
652
|
-
startIndex++;
|
|
653
|
-
}
|
|
654
|
-
let rowIndex = 0;
|
|
655
|
-
for (let i = this.selectedCell.rowIndex; i < (this.selectedCell.rowIndex + data.length); i++) {
|
|
656
|
-
let valIndex = 0;
|
|
657
|
-
const values = _.values(data[rowIndex]);
|
|
658
|
-
for (let j = this.selectedCell.rowColIndex; j < (values.length + this.selectedCell.rowColIndex); j++) {
|
|
659
|
-
if (this.columns[j]) {
|
|
660
|
-
this.rows[i][this.columns[j].name] = values[valIndex] || '';
|
|
661
|
-
}
|
|
662
|
-
valIndex++;
|
|
663
|
-
}
|
|
664
|
-
rowIndex++;
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
displayError(code) {
|
|
668
|
-
let message = 'There was an error creating/editing your data source. Please check and try again.';
|
|
669
|
-
switch (Number(code)) {
|
|
670
|
-
case 23000:
|
|
671
|
-
message = 'Duplicate Unique Key Found. Please check for duplicate values in unique identity column.';
|
|
672
|
-
break;
|
|
673
|
-
}
|
|
674
|
-
this.snackbar.open(message, null, {
|
|
675
|
-
duration: 5000,
|
|
676
|
-
verticalPosition: 'top'
|
|
677
|
-
});
|
|
678
|
-
}
|
|
679
|
-
selectColumnPickFromDatasource(column) {
|
|
680
|
-
const dialogRef = this.dialog.open(CreateDatasetComponent, {
|
|
681
|
-
width: '1200px',
|
|
682
|
-
height: '800px',
|
|
683
|
-
data: {}
|
|
684
|
-
});
|
|
685
|
-
dialogRef.afterClosed().subscribe(async (res) => {
|
|
686
|
-
if (res) {
|
|
687
|
-
column.typeConfig = {
|
|
688
|
-
datasetInstanceId: res.datasetInstanceId,
|
|
689
|
-
datasourceInstanceKey: res.datasourceInstanceKey
|
|
690
|
-
};
|
|
691
|
-
// Populate the column pick from
|
|
692
|
-
this.populateColumnPickFrom(column);
|
|
693
|
-
}
|
|
694
|
-
});
|
|
695
|
-
}
|
|
696
|
-
// Pick from datasets
|
|
697
|
-
populateColumnPickFrom(column) {
|
|
698
|
-
this.datasetService.evaluateDataset(column.typeConfig, '0', '10000000').then((dataset) => {
|
|
699
|
-
this.columnPickFromDatasets[column.name] = dataset;
|
|
700
|
-
});
|
|
701
|
-
}
|
|
702
|
-
}
|
|
703
|
-
CreateDatasourceComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CreateDatasourceComponent, deps: [{ token: i1.MatLegacyDialog }, { token: i2.ActivatedRoute }, { token: i3.DatasourceService }, { token: i4.DatasetService }, { token: i5.MatLegacySnackBar }, { token: i6.Location }, { token: i2.Router }], target: i0.ɵɵFactoryTarget.Component });
|
|
704
|
-
CreateDatasourceComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: CreateDatasourceComponent, selector: "ki-create-datasource", inputs: { sidenavService: "sidenavService", backURL: "backURL", reloadURL: "reloadURL", backendURL: "backendURL", namePrefix: "namePrefix", readonly: "readonly", automaticImportKey: "automaticImportKey", hideAPIAccess: "hideAPIAccess", editColumns: "editColumns", filterJunction: "filterJunction" }, ngImport: i0, template: "<div class=\"border-b w-full flex items-center justify-between \">\n <div *ngIf=\"!readonly\"\n class=\"leading-5 flex items-center px-4 text-xs w-96 uppercase tracking-wider font-medium text-gray-600\">\n Name\n <input type=\"text\" class=\"w-full py-1.5 ml-4\" placeholder=\"Enter datasource name\"\n [ngClass]=\"{'border border-red-500': !datasourceUpdate.title}\"\n [(ngModel)]=\"datasourceUpdate.title\">\n </div>\n <div *ngIf=\"readonly\"\n class=\"leading-5 font-medium text-lg px-4\">{{datasourceUpdate.title.replace((namePrefix || ''), '')}}</div>\n <div class=\"flex-1 flex items-center flex-wrap w-full justify-end bg-white\">\n <ng-template [ngIf]=\"_.some(rows, '_selected')\">\n <button (click)=\"deleteSelectedEntries()\"\n class=\"w-28 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">delete_forever</mat-icon>\n delete selected\n </button>\n <div class=\"divider\"></div>\n </ng-template>\n\n <button *ngIf=\"!editMode\" (click)=\"showFilters = !showFilters\"\n [ngStyle]=\"{'background-color': this.showFilters ? '#00000012' : ''}\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">filter_alt</mat-icon>\n filter\n </button>\n <div *ngIf=\"!editMode\" class=\"divider\"></div>\n <button *ngIf=\"!editMode\" (click)=\"advancedSettings()\" [disabled]=\"!datasourceInstanceKey\"\n class=\"disabled:opacity-50 w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">tune</mat-icon>\n advanced\n </button>\n <button *ngIf=\"!editMode && !hideAPIAccess\" (click)=\"apiAccess()\" [disabled]=\"!datasourceInstanceKey\"\n class=\"disabled:opacity-50 w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">api</mat-icon>\n api access\n </button>\n <button *ngIf=\"!editMode\" (click)=\"import()\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">upload_file</mat-icon>\n upload\n </button>\n <div *ngIf=\"!editMode\" class=\"divider\"></div>\n\n <button *ngIf=\"editMode\" (click)=\"cancelChanges()\"\n class=\"disabled:opacity-50 w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">cancel</mat-icon>\n cancel edit\n </button>\n\n <button (click)=\"save()\"\n class=\"disabled:opacity-50 w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">save</mat-icon>\n save\n </button>\n </div>\n</div>\n<div *ngIf=\"showFilters\" class=\"dataset-filters\">\n <div class=\"dataset-filter border-b border-gray-200\">\n\n <ki-dataset-filters *ngIf=\"columns.length\" [filterFields]=\"filterFields\"\n [openSide]=\"openSide\"\n [filterJunction]=\"filterJunction\"></ki-dataset-filters>\n\n <div class=\"flex items-center apply-filter\">\n <button mat-stroked-button class=\"mr-2 bg-white\" color=\"warn\"\n (click)=\"clearFilter()\">\n Clear Filter\n </button>\n <button mat-flat-button class=\"mr-2\" color=\"primary\"\n (click)=\"applyFilter()\" [disabled]=\"!filterJunction.filters.length\">\n Apply Filter\n </button>\n </div>\n\n\n </div>\n</div>\n<div class=\"flex create-datasource-container\">\n <div class=\"flex-1 relative overflow-y-scroll table-scroll\">\n\n <div class=\"create-datasource\">\n <div id=\"tableWrapper\" class=\"flex-1 overflow-y-scroll relative\">\n <table class=\"datasource-table table-fixed w-full overflow-scroll\">\n <thead>\n <tr>\n <th class=\"w-10 relative cursor-pointer bg-gray-100 p-0 sticky text-xs\">\n <div class=\"flex items-center justify-center\">\n <input type=\"checkbox\" [(ngModel)]=\"selectAll\" (ngModelChange)=\"updateSelectAll()\">\n </div>\n </th>\n <ng-template ngFor let-column [ngForOf]=\"columns\" let-colIndex=index>\n <th [id]=\"column.type + colIndex\" *ngIf=\"column.type === 'id' ? showAutoIncrement : true\"\n class=\"w-64 relative cursor-pointer bg-gray-100 p-2 sticky text-xs\"\n [ngClass]=\"{'bg-indigo-50': selectedItem._index === colIndex, 'border-r-0': (colIndex + 1) === columns.length}\">\n <div class=\"pr-8 w-full header-title\" (click)=\"selectColumn(column, colIndex)\">\n {{ column.title }} \n <svg *ngIf=\"column.keyField || column.type ==='id'\"\n xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\"\n class=\"w-5 h-5 text-yellow-500\">\n <path fill-rule=\"evenodd\"\n d=\"M8 7a5 5 0 113.61 4.804l-1.903 1.903A1 1 0 019 14H8v1a1 1 0 01-1 1H6v1a1 1 0 01-1 1H3a1 1 0 01-1-1v-2a1 1 0 01.293-.707L8.196 8.39A5.002 5.002 0 018 7zm5-3a.75.75 0 000 1.5A1.5 1.5 0 0114.5 7 .75.75 0 0016 7a3 3 0 00-3-3z\"\n clip-rule=\"evenodd\"/>\n </svg>\n </div>\n <button mat-icon-button [matMenuTriggerFor]=\"header\"\n class=\"absolute header-actions\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #header=\"matMenu\">\n <button mat-menu-item (click)=\"sortColumn(column, 'asc')\">\n <div class=\"flex items-center justify-between w-full\">\n Sort Ascending\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\" stroke=\"currentColor\"\n class=\"h-6 w-6\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\n d=\"M3 4.5h14.25M3 9h9.75M3 13.5h5.25m5.25-.75L17.25 9m0 0L21 12.75M17.25 9v12\"/>\n </svg>\n </div>\n </button>\n <button mat-menu-item (click)=\"sortColumn(column, 'desc')\">\n <div class=\"flex items-center justify-between w-full\">\n Sort Descending\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\" stroke=\"currentColor\"\n class=\"h-6 w-6\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\n d=\"M3 4.5h14.25M3 9h9.75M3 13.5h9.75m4.5-4.5v12m0 0-3.75-3.75M17.25 21 21 17.25\"/>\n </svg>\n </div>\n </button>\n <ng-template [ngIf]=\"column.type !== 'id' && editColumns\">\n <button mat-menu-item (click)=\"addColumn(colIndex === 0 ? 0 : colIndex - 1)\">\n Insert column before\n </button>\n </ng-template>\n <button *ngIf=\"editColumns\" mat-menu-item (click)=\"addColumn(colIndex + 1)\">Insert column after</button>\n <button *ngIf=\"editColumns\" mat-menu-item (click)=\"deleteColumn(colIndex)\">Delete column</button>\n </mat-menu>\n </th>\n </ng-template>\n </tr>\n </thead>\n <tbody>\n <tr class=\"table-rows\" [ngClass]=\"{'bg-gray-200 opacity-30': this.deletes.indexOf(rowIndex) > -1,\n 'bg-green-50': this.adds.indexOf(rowIndex) > -1, 'bg-indigo-100': this.updates.indexOf(rowIndex) > -1}\"\n *ngFor=\"let row of rows; let rowIndex = index\">\n <td class=\"p-0 row-cell text-center\">\n <div class=\"flex items-center justify-center\">\n <input type=\"checkbox\" [(ngModel)]=\"row._selected\" (ngModelChange)=\"updateSelected()\">\n </div>\n </td>\n <ng-template ngFor let-rowColumn [ngForOf]=\"columns\" let-rowColIndex=index>\n <td *ngIf=\"rowColumn.type === 'id' ? showAutoIncrement : true\"\n [ngClass]=\"{'bg-indigo-50': selectedItem._index === rowColIndex,\n 'w-24 bg-gray-100': columns[rowColIndex].type === 'id',\n 'bg-gray-100': columns[rowColIndex].keyField && this.adds.indexOf(rowIndex) === -1}\"\n class=\"p-0 row-cell\">\n <div\n class=\"py-1 px-2 h-full w-full border border-transparent input-wrapper flex items-center justify-between relative\">\n <input class=\"p-0 border-none w-full bg-transparent pr-10 cell-input\"\n [type]=\"inputTypeForField(rowColumn)\" #field=\"ngModel\"\n [(ngModel)]=\"row[rowColumn.name]\"\n [step]=\"1\"\n [max]=\"columns[rowColIndex].typeConfig ? columns[rowColIndex].typeConfig.maximumValue : null\"\n [min]=\"columns[rowColIndex].typeConfig ? columns[rowColIndex].typeConfig.minimumValue : null\"\n *ngIf=\"columns[rowColIndex].type !== 'id' && columns[rowColIndex].type !== 'pickfromsource' && columns[rowColIndex].type !== 'boolean' && !columns[rowColIndex].keyField\"\n (change)=\"updateField(rowColumn, rowIndex, $event)\"\n (focus)=\"focusCell($event, rowIndex, rowColIndex)\"\n (keyup.enter)=\"enterCell(rowIndex, rowColIndex, $event)\">\n\n\n <input class=\"p-0 border-none w-full bg-transparent pr-10 cell-input\"\n type=\"checkbox\" #field=\"ngModel\"\n [(ngModel)]=\"row[rowColumn.name]\"\n [step]=\"1\"\n *ngIf=\"columns[rowColIndex].type === 'boolean' && !columns[rowColIndex].keyField\"\n (change)=\"updateField(rowColumn, rowIndex, $event)\"\n (focus)=\"focusCell($event, rowIndex, rowColIndex)\"\n (keyup.enter)=\"enterCell(rowIndex, rowColIndex, $event)\">\n\n\n <div\n *ngIf=\"columns[rowColIndex].type == 'pickfromsource' && columnPickFromDatasets[rowColumn.name]\"\n class=\"w-full pr-10\">\n <select\n class=\"p-0 border-none w-full bg-transparent cell-input outline-none ring-0\"\n #field=\"ngModel\"\n [(ngModel)]=\"row[rowColumn.name]\"\n (change)=\"updateField(field, rowIndex)\"\n (focus)=\"focusCell($event, rowIndex, rowColIndex)\"\n (keyup.enter)=\"enterCell(rowIndex, rowColIndex, $event)\">\n <option\n *ngFor=\"let pickFrom of columnPickFromDatasets[rowColumn.name].allData\"\n [value]=\"pickFrom[rowColumn.typeConfig.valueFieldName]\">\n {{pickFrom[rowColumn.typeConfig.labelFieldName]}}\n </option>\n </select>\n </div>\n\n\n <ng-template [ngIf]=\"columns[rowColIndex].type === 'id'\">\n <div\n class=\"text-gray-500 text-xs\">{{ row[rowColumn.name] || '<\\generated\\>' }}\n </div>\n </ng-template>\n\n <ng-template [ngIf]=\"columns[rowColIndex].keyField\">\n <ng-template [ngIf]=\"this.adds.indexOf(rowIndex) > -1\">\n <input class=\"p-0 border-none w-full bg-transparent pr-5 cell-input\"\n type=\"text\" #field=\"ngModel\" [(ngModel)]=\"row[rowColumn.name]\"\n (change)=\"updateField(field, rowIndex)\"\n (focus)=\"focusCell($event, rowIndex, rowColIndex)\"\n (keyup.enter)=\"enterCell(rowIndex, rowColIndex, $event)\">\n </ng-template>\n <ng-template [ngIf]=\"this.adds.indexOf(rowIndex) === -1\">\n <div class=\"text-gray-500 text-xs\">{{ row[rowColumn.name] }}</div>\n </ng-template>\n\n </ng-template>\n\n <span\n class=\"absolute material-symbols-outlined right-0 w-10 text-orange-500 text-lg\"\n *ngIf=\"invalidItems[rowIndex] && invalidItems[rowIndex][rowColumn.name]\"\n [matTooltip]=\"invalidItems[rowIndex][rowColumn.name]\">warning</span>\n\n <button mat-icon-button [matMenuTriggerFor]=\"menu\"\n class=\"absolute cell-actions\" tabindex=\"-1\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #menu=\"matMenu\">\n <button mat-menu-item (click)=\"addRow(rowIndex + 1)\">Add row</button>\n <button mat-menu-item (click)=\"deleteRow(rowIndex)\">Delete row</button>\n <button *ngIf=\"columns[rowColIndex].type !== 'id'\"\n mat-menu-item (click)=\"clearCell(rowIndex, rowColIndex)\">Clear cell\n </button>\n </mat-menu>\n </div>\n\n </td>\n </ng-template>\n\n </tr>\n </tbody>\n </table>\n <div (click)=\"addRow()\" title=\"Add Row\"\n class=\"cursor-pointer flex items-center text-sm m-2 p-1 bg-gray-100 rounded-md\">\n <button class=\"ml-2\" mat-icon-button color=\"primary\">\n <mat-icon>add_circle</mat-icon>\n </button>\n Add new row\n </div>\n </div>\n\n\n <div class=\"border-t bg-gray-50 py-2 flex align-center justify-between\">\n <button class=\"ml-2\" mat-icon-button color=\"primary\" title=\"Add Row\" (click)=\"addRow()\">\n <mat-icon>add_circle</mat-icon>\n </button>\n <div *ngIf=\"!editMode\" class=\"flex items-center\">\n <div class=\"text-xs text-gray-400 mr-10\">\n Showing {{offset + 1}}\n - {{(page * limit) - (limit - rows.length)}}</div>\n <select [value]=\"limit\" (change)=\"pageSizeChange($event.target.value)\"\n class=\"mr-8 p-2\">\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 class=\"mr-4\" (click)=\"decreaseOffset()\" [disabled]=\"page <= 1\">\n <mat-icon>chevron_left</mat-icon>\n </button>\n <button mat-icon-button (click)=\"increaseOffset()\" [disabled]=\"endOfResults\">\n <mat-icon>chevron_right</mat-icon>\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"border-l border-r bg-gray-50 -ml-2.5\">\n <button mat-icon-button color=\"primary\" title=\"Add Column\" (click)=\"addColumn()\"\n class=\"-mt-0.5\">\n <mat-icon>add_circle</mat-icon>\n </button>\n </div>\n\n <div *ngIf=\"Object.keys(selectedItem).length\" class=\"bg-gray-100 w-72 h-full p-3 flex justify-between flex-col\">\n <div>\n <div class=\"uppercase font-medium tracking-wider mb-4 text-xs text-gray-600\">\n Settings\n </div>\n\n <hr class=\"my-4\">\n\n <ng-template [ngIf]=\"selectedItem._tableType\">\n <div class=\"uppercase font-medium tracking-wider mb-4 text-xs text-gray-600\">\n Column\n </div>\n <label *ngIf=\"datasourceUpdate.instanceImportKey\" class=\"mb-4\">\n Column Key\n <input type=\"text\" [(ngModel)]=\"selectedItem.name\" disabled>\n </label>\n <label class=\"mb-4\">\n Column Title\n <input type=\"text\" [(ngModel)]=\"selectedItem.title\" placeholder=\"Enter column title\"\n (change)=\"updateColumnName()\">\n </label>\n\n <ng-template [ngIf]=\"selectedItem.type === 'id'\">\n <label class=\"mb-4\">\n Column Type\n <select [(ngModel)]=\"selectedItem.type\" disabled>\n <option [value]=\"'id'\">ID</option>\n </select>\n </label>\n </ng-template>\n\n <ng-template [ngIf]=\"selectedItem.type !== 'id'\">\n <label class=\"mb-4\">\n Column Type\n <select [(ngModel)]=\"selectedItem.type\" (ngModelChange)=\"setTypeConfig()\">\n <option [value]=\"null\">-- Select column type --</option>\n <option *ngFor=\"let type of Object.keys(datasourceTypes)\" [value]=\"type\">\n {{ datasourceTypes[type] }}\n </option>\n </select>\n </label>\n </ng-template>\n\n <div class=\"flex items-center gap-2\"\n *ngIf=\"selectedItem.typeConfig && selectedItem.type == 'integer' || selectedItem.type == 'float'\">\n <label class=\"mb-4 w-32\">\n Minimum Value\n <input type=\"number\" class=\"py-1 px-2\"\n [(ngModel)]=\"selectedItem.typeConfig.minimumValue\" placeholder=\"Enter value\" />\n </label>\n\n <label class=\"mb-4 w-32\">\n Maximum Value\n <input type=\"number\" class=\"py-1 px-2\"\n [(ngModel)]=\"selectedItem.typeConfig.maximumValue\" placeholder=\"Enter value\" />\n </label>\n </div>\n\n <div *ngIf=\"selectedItem.type == 'pickfromsource'\" class=\"mb-4\">\n\n <div *ngIf=\"selectedItem.typeConfig && columnPickFromDatasets[selectedItem.name]\"\n class=\"mb-4\">\n Datasource: <span\n class=\"text-gray-500\">{{ columnPickFromDatasets[selectedItem.name].instanceTitle }}</span>\n </div>\n\n <button mat-flat-button color=\"primary\" (click)=\"selectColumnPickFromDatasource(selectedItem)\">\n Select Datasource\n </button>\n\n <div *ngIf=\"selectedItem.typeConfig && columnPickFromDatasets[selectedItem.name]\" class=\"mt-4\">\n\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Label column\n </label>\n <div class=\"mt-1 sm:col-span-2 sm:mt-0\">\n <select [(ngModel)]=\"selectedItem.typeConfig.labelFieldName\"\n class=\"block w-full max-w-lg rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:max-w-xs sm:text-sm py-1 px-2\">\n <option *ngFor=\"let column of columnPickFromDatasets[selectedItem.name].columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </select>\n </div>\n\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Value column\n </label>\n <div class=\"mt-1 sm:col-span-2 sm:mt-0\">\n <select [(ngModel)]=\"selectedItem.typeConfig.valueFieldName\"\n class=\"block w-full max-w-lg rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:max-w-xs sm:text-sm py-1 px-2\">\n <option *ngFor=\"let column of columnPickFromDatasets[selectedItem.name].columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </select>\n </div>\n\n\n </div>\n\n </div>\n\n\n <div>\n <mat-checkbox class=\"mb-4\"\n [(ngModel)]=\"selectedItem.required\">\n Required\n </mat-checkbox>\n </div>\n\n <div>\n <mat-checkbox class=\"mb-4\"\n [(ngModel)]=\"selectedItem.valueExpressionOnNullOnly\" (change)=\"!($event.checked) ? selectedItem.valueExpression = '' : null\">\n Has Default Value\n </mat-checkbox>\n </div>\n\n <label *ngIf=\"selectedItem.valueExpressionOnNullOnly\" class=\"mb-4\">\n Default Value\n <input type=\"text\" [(ngModel)]=\"selectedItem.valueExpression\" placeholder=\"Enter default value\">\n </label>\n\n\n <div>\n <button mat-button color=\"warn\" (click)=\"deleteSelectedColumn()\">Delete Column</button>\n </div>\n\n <hr class=\"my-4\">\n </ng-template>\n </div>\n\n <button mat-flat-button color=\"primary\" (click)=\"save(true)\">\n Save & Exit\n </button>\n </div>\n</div>\n\n\n", styles: [":host{display:block;background-color:#fff;height:calc(100vh - 104px)}.divider{width:1px;height:36px;background-color:#cecece}.action-toolbar{display:flex;align-items:center;flex-wrap:wrap;width:100%;justify-content:flex-end;background-color:#fff;border-bottom:1px solid #ddd}.action-toolbar button{min-width:50px;padding:0 13px;color:#505050}.cell-header{width:100%;display:flex;align-items:center;justify-content:space-between}.cell-header.end{justify-content:flex-end}.cell-header.sorting{min-height:43px}.transformation-listing{display:flex;align-items:center;width:100%;background-color:#00000012;border-bottom:1px solid #ddd;min-height:47px}.transformation-listing .list-title{text-transform:uppercase;font-size:.75rem;padding:0 1rem;border-right:2px solid #ddd;color:#4c4c4c;font-weight:500;letter-spacing:1px}.transformation-listing .badge-item{display:flex;align-items:center;margin-left:1rem;padding-left:1rem;border-radius:20px;background-color:#fff;border:1px solid #ddd;height:30px}.transformation-listing .badge-item.exclude{opacity:.8}.transformation-listing .badge-item:hover{background-color:#fcfcfc}.transformation-listing .badge-item span{margin-right:.5rem;color:#0000008a}.transformation-listing .badge-item button.mat-icon-button{width:33px;height:33px;line-height:33px}.transformation-listing .badge-item button.mat-icon-button mat-icon{font-size:20px;height:20px;width:20px;line-height:20px;color:#0000008a}.dataset-filters{position:relative;overflow-y:scroll;flex:none!important;max-height:400px}.dataset-filters .dataset-filter{position:relative}.dataset-filters .dataset-filter .apply-filter{position:absolute;bottom:.5rem;right:0;z-index:10}.dataset-filters .dataset-filter .remove-filter{position:absolute;top:.5rem;right:0;z-index:10}.create-datasource-container{min-width:1024px;height:calc(100% - 49px)}.create-datasource-container .table-scroll::-webkit-scrollbar{width:.75em;background:transparent}.create-datasource-container .table-scroll::-webkit-scrollbar-thumb{background:#d2d2d2}.create-datasource-container .add-column{position:absolute;top:0;right:0}.create-datasource-container .create-datasource{margin-left:-1px;margin-top:-1px;display:flex;flex-direction:column;justify-content:space-between;height:100%}.create-datasource-container .create-datasource table.datasource-table td,.create-datasource-container .create-datasource table.datasource-table th{border:1px solid #ddd;vertical-align:middle;padding:.5rem}.create-datasource-container .create-datasource table.datasource-table th{font-weight:500}.create-datasource-container .create-datasource table.datasource-table th .header-title{min-height:20px;display:flex;align-items:center}.create-datasource-container .create-datasource table.datasource-table th .header-title mat-icon{height:20px;width:20px;font-size:20px;line-height:20px;color:#ffc400b3}.create-datasource-container .create-datasource table.datasource-table th button.header-actions{width:30px;height:30px;line-height:30px;top:50%;transform:translateY(-50%);right:0;color:gray}.create-datasource-container .create-datasource table.datasource-table th button.header-actions mat-icon{line-height:20px;height:20px;width:20px;font-size:20px}.create-datasource-container .create-datasource table.datasource-table .input-wrapper button.cell-actions{width:30px;height:30px;line-height:30px;top:50%;transform:translateY(-50%);right:0;color:gray;display:none}.create-datasource-container .create-datasource table.datasource-table .input-wrapper button.cell-actions mat-icon{line-height:20px;height:20px;width:20px;font-size:20px}.create-datasource-container .create-datasource table.datasource-table .input-wrapper:hover button.cell-actions{display:block}\n"], dependencies: [{ kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i7.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: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatLegacyMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i9.MatLegacyMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i9.MatLegacyMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "directive", type: i10.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i10.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i10.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: i10.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i10.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i10.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i10.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i10.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i11.MatLegacyCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "directive", type: i12.MatLegacyTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i13.DatasetFiltersComponent, selector: "ki-dataset-filters", inputs: ["filterJunction", "filterFields", "joinFilterFields", "joinFieldsName", "openSide", "parameterValues"] }] });
|
|
705
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CreateDatasourceComponent, decorators: [{
|
|
706
|
-
type: Component,
|
|
707
|
-
args: [{ selector: 'ki-create-datasource', template: "<div class=\"border-b w-full flex items-center justify-between \">\n <div *ngIf=\"!readonly\"\n class=\"leading-5 flex items-center px-4 text-xs w-96 uppercase tracking-wider font-medium text-gray-600\">\n Name\n <input type=\"text\" class=\"w-full py-1.5 ml-4\" placeholder=\"Enter datasource name\"\n [ngClass]=\"{'border border-red-500': !datasourceUpdate.title}\"\n [(ngModel)]=\"datasourceUpdate.title\">\n </div>\n <div *ngIf=\"readonly\"\n class=\"leading-5 font-medium text-lg px-4\">{{datasourceUpdate.title.replace((namePrefix || ''), '')}}</div>\n <div class=\"flex-1 flex items-center flex-wrap w-full justify-end bg-white\">\n <ng-template [ngIf]=\"_.some(rows, '_selected')\">\n <button (click)=\"deleteSelectedEntries()\"\n class=\"w-28 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">delete_forever</mat-icon>\n delete selected\n </button>\n <div class=\"divider\"></div>\n </ng-template>\n\n <button *ngIf=\"!editMode\" (click)=\"showFilters = !showFilters\"\n [ngStyle]=\"{'background-color': this.showFilters ? '#00000012' : ''}\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">filter_alt</mat-icon>\n filter\n </button>\n <div *ngIf=\"!editMode\" class=\"divider\"></div>\n <button *ngIf=\"!editMode\" (click)=\"advancedSettings()\" [disabled]=\"!datasourceInstanceKey\"\n class=\"disabled:opacity-50 w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">tune</mat-icon>\n advanced\n </button>\n <button *ngIf=\"!editMode && !hideAPIAccess\" (click)=\"apiAccess()\" [disabled]=\"!datasourceInstanceKey\"\n class=\"disabled:opacity-50 w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">api</mat-icon>\n api access\n </button>\n <button *ngIf=\"!editMode\" (click)=\"import()\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">upload_file</mat-icon>\n upload\n </button>\n <div *ngIf=\"!editMode\" class=\"divider\"></div>\n\n <button *ngIf=\"editMode\" (click)=\"cancelChanges()\"\n class=\"disabled:opacity-50 w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">cancel</mat-icon>\n cancel edit\n </button>\n\n <button (click)=\"save()\"\n class=\"disabled:opacity-50 w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">save</mat-icon>\n save\n </button>\n </div>\n</div>\n<div *ngIf=\"showFilters\" class=\"dataset-filters\">\n <div class=\"dataset-filter border-b border-gray-200\">\n\n <ki-dataset-filters *ngIf=\"columns.length\" [filterFields]=\"filterFields\"\n [openSide]=\"openSide\"\n [filterJunction]=\"filterJunction\"></ki-dataset-filters>\n\n <div class=\"flex items-center apply-filter\">\n <button mat-stroked-button class=\"mr-2 bg-white\" color=\"warn\"\n (click)=\"clearFilter()\">\n Clear Filter\n </button>\n <button mat-flat-button class=\"mr-2\" color=\"primary\"\n (click)=\"applyFilter()\" [disabled]=\"!filterJunction.filters.length\">\n Apply Filter\n </button>\n </div>\n\n\n </div>\n</div>\n<div class=\"flex create-datasource-container\">\n <div class=\"flex-1 relative overflow-y-scroll table-scroll\">\n\n <div class=\"create-datasource\">\n <div id=\"tableWrapper\" class=\"flex-1 overflow-y-scroll relative\">\n <table class=\"datasource-table table-fixed w-full overflow-scroll\">\n <thead>\n <tr>\n <th class=\"w-10 relative cursor-pointer bg-gray-100 p-0 sticky text-xs\">\n <div class=\"flex items-center justify-center\">\n <input type=\"checkbox\" [(ngModel)]=\"selectAll\" (ngModelChange)=\"updateSelectAll()\">\n </div>\n </th>\n <ng-template ngFor let-column [ngForOf]=\"columns\" let-colIndex=index>\n <th [id]=\"column.type + colIndex\" *ngIf=\"column.type === 'id' ? showAutoIncrement : true\"\n class=\"w-64 relative cursor-pointer bg-gray-100 p-2 sticky text-xs\"\n [ngClass]=\"{'bg-indigo-50': selectedItem._index === colIndex, 'border-r-0': (colIndex + 1) === columns.length}\">\n <div class=\"pr-8 w-full header-title\" (click)=\"selectColumn(column, colIndex)\">\n {{ column.title }} \n <svg *ngIf=\"column.keyField || column.type ==='id'\"\n xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\"\n class=\"w-5 h-5 text-yellow-500\">\n <path fill-rule=\"evenodd\"\n d=\"M8 7a5 5 0 113.61 4.804l-1.903 1.903A1 1 0 019 14H8v1a1 1 0 01-1 1H6v1a1 1 0 01-1 1H3a1 1 0 01-1-1v-2a1 1 0 01.293-.707L8.196 8.39A5.002 5.002 0 018 7zm5-3a.75.75 0 000 1.5A1.5 1.5 0 0114.5 7 .75.75 0 0016 7a3 3 0 00-3-3z\"\n clip-rule=\"evenodd\"/>\n </svg>\n </div>\n <button mat-icon-button [matMenuTriggerFor]=\"header\"\n class=\"absolute header-actions\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #header=\"matMenu\">\n <button mat-menu-item (click)=\"sortColumn(column, 'asc')\">\n <div class=\"flex items-center justify-between w-full\">\n Sort Ascending\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\" stroke=\"currentColor\"\n class=\"h-6 w-6\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\n d=\"M3 4.5h14.25M3 9h9.75M3 13.5h5.25m5.25-.75L17.25 9m0 0L21 12.75M17.25 9v12\"/>\n </svg>\n </div>\n </button>\n <button mat-menu-item (click)=\"sortColumn(column, 'desc')\">\n <div class=\"flex items-center justify-between w-full\">\n Sort Descending\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\" stroke=\"currentColor\"\n class=\"h-6 w-6\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\n d=\"M3 4.5h14.25M3 9h9.75M3 13.5h9.75m4.5-4.5v12m0 0-3.75-3.75M17.25 21 21 17.25\"/>\n </svg>\n </div>\n </button>\n <ng-template [ngIf]=\"column.type !== 'id' && editColumns\">\n <button mat-menu-item (click)=\"addColumn(colIndex === 0 ? 0 : colIndex - 1)\">\n Insert column before\n </button>\n </ng-template>\n <button *ngIf=\"editColumns\" mat-menu-item (click)=\"addColumn(colIndex + 1)\">Insert column after</button>\n <button *ngIf=\"editColumns\" mat-menu-item (click)=\"deleteColumn(colIndex)\">Delete column</button>\n </mat-menu>\n </th>\n </ng-template>\n </tr>\n </thead>\n <tbody>\n <tr class=\"table-rows\" [ngClass]=\"{'bg-gray-200 opacity-30': this.deletes.indexOf(rowIndex) > -1,\n 'bg-green-50': this.adds.indexOf(rowIndex) > -1, 'bg-indigo-100': this.updates.indexOf(rowIndex) > -1}\"\n *ngFor=\"let row of rows; let rowIndex = index\">\n <td class=\"p-0 row-cell text-center\">\n <div class=\"flex items-center justify-center\">\n <input type=\"checkbox\" [(ngModel)]=\"row._selected\" (ngModelChange)=\"updateSelected()\">\n </div>\n </td>\n <ng-template ngFor let-rowColumn [ngForOf]=\"columns\" let-rowColIndex=index>\n <td *ngIf=\"rowColumn.type === 'id' ? showAutoIncrement : true\"\n [ngClass]=\"{'bg-indigo-50': selectedItem._index === rowColIndex,\n 'w-24 bg-gray-100': columns[rowColIndex].type === 'id',\n 'bg-gray-100': columns[rowColIndex].keyField && this.adds.indexOf(rowIndex) === -1}\"\n class=\"p-0 row-cell\">\n <div\n class=\"py-1 px-2 h-full w-full border border-transparent input-wrapper flex items-center justify-between relative\">\n <input class=\"p-0 border-none w-full bg-transparent pr-10 cell-input\"\n [type]=\"inputTypeForField(rowColumn)\" #field=\"ngModel\"\n [(ngModel)]=\"row[rowColumn.name]\"\n [step]=\"1\"\n [max]=\"columns[rowColIndex].typeConfig ? columns[rowColIndex].typeConfig.maximumValue : null\"\n [min]=\"columns[rowColIndex].typeConfig ? columns[rowColIndex].typeConfig.minimumValue : null\"\n *ngIf=\"columns[rowColIndex].type !== 'id' && columns[rowColIndex].type !== 'pickfromsource' && columns[rowColIndex].type !== 'boolean' && !columns[rowColIndex].keyField\"\n (change)=\"updateField(rowColumn, rowIndex, $event)\"\n (focus)=\"focusCell($event, rowIndex, rowColIndex)\"\n (keyup.enter)=\"enterCell(rowIndex, rowColIndex, $event)\">\n\n\n <input class=\"p-0 border-none w-full bg-transparent pr-10 cell-input\"\n type=\"checkbox\" #field=\"ngModel\"\n [(ngModel)]=\"row[rowColumn.name]\"\n [step]=\"1\"\n *ngIf=\"columns[rowColIndex].type === 'boolean' && !columns[rowColIndex].keyField\"\n (change)=\"updateField(rowColumn, rowIndex, $event)\"\n (focus)=\"focusCell($event, rowIndex, rowColIndex)\"\n (keyup.enter)=\"enterCell(rowIndex, rowColIndex, $event)\">\n\n\n <div\n *ngIf=\"columns[rowColIndex].type == 'pickfromsource' && columnPickFromDatasets[rowColumn.name]\"\n class=\"w-full pr-10\">\n <select\n class=\"p-0 border-none w-full bg-transparent cell-input outline-none ring-0\"\n #field=\"ngModel\"\n [(ngModel)]=\"row[rowColumn.name]\"\n (change)=\"updateField(field, rowIndex)\"\n (focus)=\"focusCell($event, rowIndex, rowColIndex)\"\n (keyup.enter)=\"enterCell(rowIndex, rowColIndex, $event)\">\n <option\n *ngFor=\"let pickFrom of columnPickFromDatasets[rowColumn.name].allData\"\n [value]=\"pickFrom[rowColumn.typeConfig.valueFieldName]\">\n {{pickFrom[rowColumn.typeConfig.labelFieldName]}}\n </option>\n </select>\n </div>\n\n\n <ng-template [ngIf]=\"columns[rowColIndex].type === 'id'\">\n <div\n class=\"text-gray-500 text-xs\">{{ row[rowColumn.name] || '<\\generated\\>' }}\n </div>\n </ng-template>\n\n <ng-template [ngIf]=\"columns[rowColIndex].keyField\">\n <ng-template [ngIf]=\"this.adds.indexOf(rowIndex) > -1\">\n <input class=\"p-0 border-none w-full bg-transparent pr-5 cell-input\"\n type=\"text\" #field=\"ngModel\" [(ngModel)]=\"row[rowColumn.name]\"\n (change)=\"updateField(field, rowIndex)\"\n (focus)=\"focusCell($event, rowIndex, rowColIndex)\"\n (keyup.enter)=\"enterCell(rowIndex, rowColIndex, $event)\">\n </ng-template>\n <ng-template [ngIf]=\"this.adds.indexOf(rowIndex) === -1\">\n <div class=\"text-gray-500 text-xs\">{{ row[rowColumn.name] }}</div>\n </ng-template>\n\n </ng-template>\n\n <span\n class=\"absolute material-symbols-outlined right-0 w-10 text-orange-500 text-lg\"\n *ngIf=\"invalidItems[rowIndex] && invalidItems[rowIndex][rowColumn.name]\"\n [matTooltip]=\"invalidItems[rowIndex][rowColumn.name]\">warning</span>\n\n <button mat-icon-button [matMenuTriggerFor]=\"menu\"\n class=\"absolute cell-actions\" tabindex=\"-1\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #menu=\"matMenu\">\n <button mat-menu-item (click)=\"addRow(rowIndex + 1)\">Add row</button>\n <button mat-menu-item (click)=\"deleteRow(rowIndex)\">Delete row</button>\n <button *ngIf=\"columns[rowColIndex].type !== 'id'\"\n mat-menu-item (click)=\"clearCell(rowIndex, rowColIndex)\">Clear cell\n </button>\n </mat-menu>\n </div>\n\n </td>\n </ng-template>\n\n </tr>\n </tbody>\n </table>\n <div (click)=\"addRow()\" title=\"Add Row\"\n class=\"cursor-pointer flex items-center text-sm m-2 p-1 bg-gray-100 rounded-md\">\n <button class=\"ml-2\" mat-icon-button color=\"primary\">\n <mat-icon>add_circle</mat-icon>\n </button>\n Add new row\n </div>\n </div>\n\n\n <div class=\"border-t bg-gray-50 py-2 flex align-center justify-between\">\n <button class=\"ml-2\" mat-icon-button color=\"primary\" title=\"Add Row\" (click)=\"addRow()\">\n <mat-icon>add_circle</mat-icon>\n </button>\n <div *ngIf=\"!editMode\" class=\"flex items-center\">\n <div class=\"text-xs text-gray-400 mr-10\">\n Showing {{offset + 1}}\n - {{(page * limit) - (limit - rows.length)}}</div>\n <select [value]=\"limit\" (change)=\"pageSizeChange($event.target.value)\"\n class=\"mr-8 p-2\">\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 class=\"mr-4\" (click)=\"decreaseOffset()\" [disabled]=\"page <= 1\">\n <mat-icon>chevron_left</mat-icon>\n </button>\n <button mat-icon-button (click)=\"increaseOffset()\" [disabled]=\"endOfResults\">\n <mat-icon>chevron_right</mat-icon>\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"border-l border-r bg-gray-50 -ml-2.5\">\n <button mat-icon-button color=\"primary\" title=\"Add Column\" (click)=\"addColumn()\"\n class=\"-mt-0.5\">\n <mat-icon>add_circle</mat-icon>\n </button>\n </div>\n\n <div *ngIf=\"Object.keys(selectedItem).length\" class=\"bg-gray-100 w-72 h-full p-3 flex justify-between flex-col\">\n <div>\n <div class=\"uppercase font-medium tracking-wider mb-4 text-xs text-gray-600\">\n Settings\n </div>\n\n <hr class=\"my-4\">\n\n <ng-template [ngIf]=\"selectedItem._tableType\">\n <div class=\"uppercase font-medium tracking-wider mb-4 text-xs text-gray-600\">\n Column\n </div>\n <label *ngIf=\"datasourceUpdate.instanceImportKey\" class=\"mb-4\">\n Column Key\n <input type=\"text\" [(ngModel)]=\"selectedItem.name\" disabled>\n </label>\n <label class=\"mb-4\">\n Column Title\n <input type=\"text\" [(ngModel)]=\"selectedItem.title\" placeholder=\"Enter column title\"\n (change)=\"updateColumnName()\">\n </label>\n\n <ng-template [ngIf]=\"selectedItem.type === 'id'\">\n <label class=\"mb-4\">\n Column Type\n <select [(ngModel)]=\"selectedItem.type\" disabled>\n <option [value]=\"'id'\">ID</option>\n </select>\n </label>\n </ng-template>\n\n <ng-template [ngIf]=\"selectedItem.type !== 'id'\">\n <label class=\"mb-4\">\n Column Type\n <select [(ngModel)]=\"selectedItem.type\" (ngModelChange)=\"setTypeConfig()\">\n <option [value]=\"null\">-- Select column type --</option>\n <option *ngFor=\"let type of Object.keys(datasourceTypes)\" [value]=\"type\">\n {{ datasourceTypes[type] }}\n </option>\n </select>\n </label>\n </ng-template>\n\n <div class=\"flex items-center gap-2\"\n *ngIf=\"selectedItem.typeConfig && selectedItem.type == 'integer' || selectedItem.type == 'float'\">\n <label class=\"mb-4 w-32\">\n Minimum Value\n <input type=\"number\" class=\"py-1 px-2\"\n [(ngModel)]=\"selectedItem.typeConfig.minimumValue\" placeholder=\"Enter value\" />\n </label>\n\n <label class=\"mb-4 w-32\">\n Maximum Value\n <input type=\"number\" class=\"py-1 px-2\"\n [(ngModel)]=\"selectedItem.typeConfig.maximumValue\" placeholder=\"Enter value\" />\n </label>\n </div>\n\n <div *ngIf=\"selectedItem.type == 'pickfromsource'\" class=\"mb-4\">\n\n <div *ngIf=\"selectedItem.typeConfig && columnPickFromDatasets[selectedItem.name]\"\n class=\"mb-4\">\n Datasource: <span\n class=\"text-gray-500\">{{ columnPickFromDatasets[selectedItem.name].instanceTitle }}</span>\n </div>\n\n <button mat-flat-button color=\"primary\" (click)=\"selectColumnPickFromDatasource(selectedItem)\">\n Select Datasource\n </button>\n\n <div *ngIf=\"selectedItem.typeConfig && columnPickFromDatasets[selectedItem.name]\" class=\"mt-4\">\n\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Label column\n </label>\n <div class=\"mt-1 sm:col-span-2 sm:mt-0\">\n <select [(ngModel)]=\"selectedItem.typeConfig.labelFieldName\"\n class=\"block w-full max-w-lg rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:max-w-xs sm:text-sm py-1 px-2\">\n <option *ngFor=\"let column of columnPickFromDatasets[selectedItem.name].columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </select>\n </div>\n\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Value column\n </label>\n <div class=\"mt-1 sm:col-span-2 sm:mt-0\">\n <select [(ngModel)]=\"selectedItem.typeConfig.valueFieldName\"\n class=\"block w-full max-w-lg rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:max-w-xs sm:text-sm py-1 px-2\">\n <option *ngFor=\"let column of columnPickFromDatasets[selectedItem.name].columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </select>\n </div>\n\n\n </div>\n\n </div>\n\n\n <div>\n <mat-checkbox class=\"mb-4\"\n [(ngModel)]=\"selectedItem.required\">\n Required\n </mat-checkbox>\n </div>\n\n <div>\n <mat-checkbox class=\"mb-4\"\n [(ngModel)]=\"selectedItem.valueExpressionOnNullOnly\" (change)=\"!($event.checked) ? selectedItem.valueExpression = '' : null\">\n Has Default Value\n </mat-checkbox>\n </div>\n\n <label *ngIf=\"selectedItem.valueExpressionOnNullOnly\" class=\"mb-4\">\n Default Value\n <input type=\"text\" [(ngModel)]=\"selectedItem.valueExpression\" placeholder=\"Enter default value\">\n </label>\n\n\n <div>\n <button mat-button color=\"warn\" (click)=\"deleteSelectedColumn()\">Delete Column</button>\n </div>\n\n <hr class=\"my-4\">\n </ng-template>\n </div>\n\n <button mat-flat-button color=\"primary\" (click)=\"save(true)\">\n Save & Exit\n </button>\n </div>\n</div>\n\n\n", styles: [":host{display:block;background-color:#fff;height:calc(100vh - 104px)}.divider{width:1px;height:36px;background-color:#cecece}.action-toolbar{display:flex;align-items:center;flex-wrap:wrap;width:100%;justify-content:flex-end;background-color:#fff;border-bottom:1px solid #ddd}.action-toolbar button{min-width:50px;padding:0 13px;color:#505050}.cell-header{width:100%;display:flex;align-items:center;justify-content:space-between}.cell-header.end{justify-content:flex-end}.cell-header.sorting{min-height:43px}.transformation-listing{display:flex;align-items:center;width:100%;background-color:#00000012;border-bottom:1px solid #ddd;min-height:47px}.transformation-listing .list-title{text-transform:uppercase;font-size:.75rem;padding:0 1rem;border-right:2px solid #ddd;color:#4c4c4c;font-weight:500;letter-spacing:1px}.transformation-listing .badge-item{display:flex;align-items:center;margin-left:1rem;padding-left:1rem;border-radius:20px;background-color:#fff;border:1px solid #ddd;height:30px}.transformation-listing .badge-item.exclude{opacity:.8}.transformation-listing .badge-item:hover{background-color:#fcfcfc}.transformation-listing .badge-item span{margin-right:.5rem;color:#0000008a}.transformation-listing .badge-item button.mat-icon-button{width:33px;height:33px;line-height:33px}.transformation-listing .badge-item button.mat-icon-button mat-icon{font-size:20px;height:20px;width:20px;line-height:20px;color:#0000008a}.dataset-filters{position:relative;overflow-y:scroll;flex:none!important;max-height:400px}.dataset-filters .dataset-filter{position:relative}.dataset-filters .dataset-filter .apply-filter{position:absolute;bottom:.5rem;right:0;z-index:10}.dataset-filters .dataset-filter .remove-filter{position:absolute;top:.5rem;right:0;z-index:10}.create-datasource-container{min-width:1024px;height:calc(100% - 49px)}.create-datasource-container .table-scroll::-webkit-scrollbar{width:.75em;background:transparent}.create-datasource-container .table-scroll::-webkit-scrollbar-thumb{background:#d2d2d2}.create-datasource-container .add-column{position:absolute;top:0;right:0}.create-datasource-container .create-datasource{margin-left:-1px;margin-top:-1px;display:flex;flex-direction:column;justify-content:space-between;height:100%}.create-datasource-container .create-datasource table.datasource-table td,.create-datasource-container .create-datasource table.datasource-table th{border:1px solid #ddd;vertical-align:middle;padding:.5rem}.create-datasource-container .create-datasource table.datasource-table th{font-weight:500}.create-datasource-container .create-datasource table.datasource-table th .header-title{min-height:20px;display:flex;align-items:center}.create-datasource-container .create-datasource table.datasource-table th .header-title mat-icon{height:20px;width:20px;font-size:20px;line-height:20px;color:#ffc400b3}.create-datasource-container .create-datasource table.datasource-table th button.header-actions{width:30px;height:30px;line-height:30px;top:50%;transform:translateY(-50%);right:0;color:gray}.create-datasource-container .create-datasource table.datasource-table th button.header-actions mat-icon{line-height:20px;height:20px;width:20px;font-size:20px}.create-datasource-container .create-datasource table.datasource-table .input-wrapper button.cell-actions{width:30px;height:30px;line-height:30px;top:50%;transform:translateY(-50%);right:0;color:gray;display:none}.create-datasource-container .create-datasource table.datasource-table .input-wrapper button.cell-actions mat-icon{line-height:20px;height:20px;width:20px;font-size:20px}.create-datasource-container .create-datasource table.datasource-table .input-wrapper:hover button.cell-actions{display:block}\n"] }]
|
|
708
|
-
}], ctorParameters: function () { return [{ type: i1.MatLegacyDialog }, { type: i2.ActivatedRoute }, { type: i3.DatasourceService }, { type: i4.DatasetService }, { type: i5.MatLegacySnackBar }, { type: i6.Location }, { type: i2.Router }]; }, propDecorators: { sidenavService: [{
|
|
709
|
-
type: Input
|
|
710
|
-
}], backURL: [{
|
|
711
|
-
type: Input
|
|
712
|
-
}], reloadURL: [{
|
|
713
|
-
type: Input
|
|
714
|
-
}], backendURL: [{
|
|
715
|
-
type: Input
|
|
716
|
-
}], namePrefix: [{
|
|
717
|
-
type: Input
|
|
718
|
-
}], readonly: [{
|
|
719
|
-
type: Input
|
|
720
|
-
}], automaticImportKey: [{
|
|
721
|
-
type: Input
|
|
722
|
-
}], hideAPIAccess: [{
|
|
723
|
-
type: Input
|
|
724
|
-
}], editColumns: [{
|
|
725
|
-
type: Input
|
|
726
|
-
}], filterJunction: [{
|
|
727
|
-
type: Input
|
|
728
|
-
}] } });
|
|
729
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlLWRhdGFzb3VyY2UuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmcta2luaW50ZWwvc3JjL2xpYi9jb21wb25lbnRzL2RhdGFzb3VyY2UvY3JlYXRlLWRhdGFzb3VyY2UvY3JlYXRlLWRhdGFzb3VyY2UuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmcta2luaW50ZWwvc3JjL2xpYi9jb21wb25lbnRzL2RhdGFzb3VyY2UvY3JlYXRlLWRhdGFzb3VyY2UvY3JlYXRlLWRhdGFzb3VyY2UuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFnQixTQUFTLEVBQUUsS0FBSyxFQUFvQixNQUFNLGVBQWUsQ0FBQztBQUNqRixPQUFPLEtBQUssTUFBTSxNQUFNLFFBQVEsQ0FBQztBQUlqQyxPQUFPLEVBQUMsbUJBQW1CLEVBQUMsTUFBTSx3REFBd0QsQ0FBQztBQU0zRixPQUFPLEVBQ0gsa0JBQWtCLEVBQ3JCLE1BQU0sc0RBQXNELENBQUM7QUFDOUQsT0FBTyxFQUNILHlCQUF5QixFQUM1QixNQUFNLG9FQUFvRSxDQUFDO0FBQzVFLE9BQU8sRUFDSCxxQkFBcUIsRUFDeEIsTUFBTSx3RUFBd0UsQ0FBQztBQUNoRixPQUFPLEVBQUMsZUFBZSxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQ3JDLE9BQU8sRUFBQyxzQkFBc0IsRUFBQyxNQUFNLHVEQUF1RCxDQUFDO0FBQzdGLE9BQU8sU0FBUyxNQUFNLFlBQVksQ0FBQzs7Ozs7Ozs7Ozs7Ozs7O0FBbkJuQyxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDO0FBNkJ6QixNQUFNLE9BQU8seUJBQXlCO0lBMkZsQyxZQUFvQixNQUFpQixFQUNqQixLQUFxQixFQUNyQixpQkFBb0MsRUFDcEMsY0FBOEIsRUFDOUIsUUFBcUIsRUFDckIsUUFBa0Is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QkFBeUI7a0JBTHJDLFNBQVM7K0JBQ0ksc0JBQXNCOzRRQU12QixjQUFjO3NCQUF0QixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLGtCQUFrQjtzQkFBMUIsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csY0FBYztzQkFBdEIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7QWZ0ZXJWaWV3SW5pdCwgQ29tcG9uZW50LCBJbnB1dCwgT25EZXN0cm95LCBPbkluaXR9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0ICogYXMgbG9kYXNoIGZyb20gJ2xvZGFzaCc7XG5cbmNvbnN0IF8gPSBsb2Rhc2guZGVmYXVsdDtcbmltcG9ydCB7TWF0TGVnYWN5RGlhbG9nIGFzIE1hdERpYWxvZ30gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvbGVnYWN5LWRpYWxvZyc7XG5pbXBvcnQge0ltcG9ydERhdGFDb21wb25lbnR9IGZyb20gJy4uL2NyZWF0ZS1kYXRhc291cmNlL2ltcG9ydC1kYXRhL2ltcG9ydC1kYXRhLmNvbXBvbmVudCc7XG5pbXBvcnQge0FjdGl2YXRlZFJvdXRlLCBSb3V0ZXJ9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQge0RhdGFzb3VyY2VTZXJ2aWNlLCBEYXRhc291cmNlVXBkYXRlfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9kYXRhc291cmNlLnNlcnZpY2UnO1xuaW1wb3J0IHtEYXRhc2V0U2VydmljZX0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvZGF0YXNldC5zZXJ2aWNlJztcbmltcG9ydCB7TWF0TGVnYWN5U25hY2tCYXIgYXMgTWF0U25hY2tCYXJ9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2xlZ2FjeS1zbmFjay1iYXInO1xuaW1wb3J0IHtMb2NhdGlvbn0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gICAgQXBpQWNjZXNzQ29tcG9uZW50XG59IGZyb20gJy4uL2NyZWF0ZS1kYXRhc291cmNlL2FwaS1hY2Nlc3MvYXBpLWFjY2Vzcy5jb21wb25lbnQnO1xuaW1wb3J0IHtcbiAgICBBZHZhbmNlZFNldHRpbmdzQ29tcG9uZW50XG59IGZyb20gJy4uL2NyZWF0ZS1kYXRhc291cmNlL2FkdmFuY2VkLXNldHRpbmdzL2FkdmFuY2VkLXNldHRpbmdzLmNvbXBvbmVudCc7XG5pbXBvcnQge1xuICAgIEltcG9ydFdpemFyZENvbXBvbmVudFxufSBmcm9tICcuLi9jcmVhdGUtZGF0YXNvdXJjZS9pbXBvcnQtZGF0YS9pbXBvcnQtd2l6YXJkL2ltcG9ydC13aXphcmQuY29tcG9uZW50JztcbmltcG9ydCB7QmVoYXZpb3JTdWJqZWN0fSBmcm9tICdyeGpzJztcbmltcG9ydCB7Q3JlYXRlRGF0YXNldENvbXBvbmVudH0gZnJvbSAnLi4vLi4vZGF0YXNldC9jcmVhdGUtZGF0YXNldC9jcmVhdGUtZGF0YXNldC5jb21wb25lbnQnO1xuaW1wb3J0IHNob3J0SGFzaCBmcm9tICdzaG9ydC1oYXNoJztcblxuXG5kZWNsYXJlIHZhciB3aW5kb3c6IGFueTtcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdraS1jcmVhdGUtZGF0YXNvdXJjZScsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2NyZWF0ZS1kYXRhc291cmNlLmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsnLi9jcmVhdGUtZGF0YXNvdXJjZS5jb21wb25lbnQuc2FzcyddXG59KVxuZXhwb3J0IGNsYXNzIENyZWF0ZURhdGFzb3VyY2VDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XG5cbiAgICBASW5wdXQoKSBzaWRlbmF2U2VydmljZTogYW55O1xuICAgIEBJbnB1dCgpIGJhY2tVUkwgPSAnL2ltcG9ydGVkLWRhdGEnO1xuICAgIEBJbnB1dCgpIHJlbG9hZFVSTCA9ICdpbXBvcnQtZGF0YSc7XG4gICAgQElucHV0KCkgYmFja2VuZFVSTDogc3RyaW5nO1xuICAgIEBJbnB1dCgpIG5hbWVQcmVmaXggPSAnJztcbiAgICBASW5wdXQoKSByZWFkb25seSA9IGZhbHNlO1xuICAgIEBJbnB1dCgpIGF1dG9tYXRpY0ltcG9ydEtleTogYm9vbGVhbiA9IGZhbHNlO1xuICAgIEBJbnB1dCgpIGhpZGVBUElBY2Nlc3M6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBASW5wdXQoKSBlZGl0Q29sdW1ucyA9IHRydWU7XG4gICAgQElucHV0KCkgZmlsdGVySnVuY3Rpb24gPSB7XG4gICAgICAgIGxvZ2ljOiAnQU5EJyxcbiAgICAgICAgZmlsdGVyczogW3tcbiAgICAgICAgICAgIGxoc0V4cHJlc3Npb246ICcnLFxuICAgICAgICAgICAgcmhzRXhwcmVzc2lvbjogW10sXG4gICAgICAgICAgICBmaWx0ZXJUeXBlOiAnJ1xuICAgICAgICB9XSxcbiAgICAgICAgZmlsdGVySnVuY3Rpb25zOiBbXVxuICAgIH07XG5cbiAgICBwdWJsaWMgcmVhZG9ubHkgZGF0YXNvdXJjZVR5cGVzOiBhbnkgPSB7XG4gICAgICAgIHN0cmluZzogJ1RleHQgKHVwIHRvIDI1NSBjaGFycyknLFxuICAgICAgICBtZWRpdW1zdHJpbmc6ICdNZWRpdW0gVGV4dCAodXAgdG8gMzI3NjcgY2hhcnMpJyxcbiAgICAgICAgbG9uZ3N0cmluZzogJ0xvbmcgVGV4dCAobW9yZSB0aGFuIDMyNzY3IGNoYXJzKScsXG4gICAgICAgIGludGVnZXI6ICdOdW1iZXIgKHdob2xlIG51bWJlciknLFxuICAgICAgICBiaWdpbnRlZ2VyOiAnTnVtYmVyIChsYXJnZSBudW1iZXIpJyxcbiAgICAgICAgYm9vbGVhbjogJ1RpY2sgKFllcyAvIE5vKScsXG4gICAgICAgIGZsb2F0OiAnRGVjaW1hbCBudW1iZXInLFxuICAgICAgICBkYXRlOiAnRGF0ZScsXG4gICAgICAgIGRhdGV0aW1lOiAnRGF0ZSBhbmQgVGltZScsXG4gICAgICAgIHBpY2tmcm9tc291cmNlOiAnUGljayBGcm9tIExpc3QgKHVzaW5nIGFub3RoZXIgc291cmNlKScsXG4gICAgICAgIGpzb246ICdOZXN0ZWQgSlNPTiBPYmplY3QnXG4gICAgfTtcblxuICAgIHB1YmxpYyByb3dzOiBhbnkgPSBbXTtcbiAgICBwdWJsaWMgY29sdW1uczogYW55ID0gW1xuICAgICAgICB7XG4gICAgICAgICAgICB0aXRsZTogJ0NvbHVtbiAxJyxcbiAgICAgICAgICAgIG5hbWU6ICdjb2x1bW5fMScsXG4gICAgICAgICAgICB0eXBlOiAnc3RyaW5nJ1xuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICB0aXRsZTogJ0NvbHVtbiAyJyxcbiAgICAgICAgICAgIG5hbWU6ICdjb2x1bW5fMicsXG4gICAgICAgICAgICB0eXBlOiAnc3RyaW5nJ1xuICAgICAgICB9XG4gICAgXTtcbiAgICBwdWJsaWMgc2VsZWN0ZWRJdGVtOiBhbnkgPSB7fTtcbiAgICBwdWJsaWMgXyA9IF87XG4gICAgcHVibGljIHNob3dVcGxvYWQgPSBmYWxzZTtcbiAgICBwdWJsaWMgaGVhZGVyUm93ID0gZmFsc2U7XG4gICAgcHVibGljIGFkZHM6IGFueSA9IFtdO1xuICAgIHB1YmxpYyB1cGRhdGVzOiBhbnkgPSBbXTtcbiAgICBwdWJsaWMgZGVsZXRlczogYW55ID0gW107XG4gICAgcHVibGljIGludmFsaWRJdGVtczogYW55ID0gW107XG4gICAgcHVibGljIGVkaXRNb2RlID0gZmFsc2U7XG4gICAgcHVibGljIGF1dG9JbmNyZW1lbnRDb2x1bW4gPSBmYWxzZTtcbiAgICBwdWJsaWMgZGF0YXNvdXJjZUluc3RhbmNlS2V5OiBzdHJpbmc7XG4gICAgcHVibGljIGRhdGFzb3VyY2VVcGRhdGU6IGFueSA9IHtcbiAgICAgICAgdGl0bGU6ICcnLFxuICAgICAgICBpbnN0YW5jZUltcG9ydEtleTogJycsXG4gICAgICAgIGZpZWxkczogW10sXG4gICAgICAgIGFkZHM6IFtdLFxuICAgICAgICB1cGRhdGVzOiBbXSxcbiAgICAgICAgZGVsZXRlczogW11cbiAgICB9O1xuICAgIHB1YmxpYyBvZmZzZXQgPSAwO1xuICAgIHB1YmxpYyBsaW1pdCA9IDI1O1xuICAgIHB1YmxpYyBwYWdlID0gMTtcbiAgICBwdWJsaWMgZW5kT2ZSZXN1bHRzID0gZmFsc2U7XG4gICAgcHVibGljIHNob3dBdXRvSW5jcmVtZW50ID0gZmFsc2U7XG4gICAgcHVibGljIHNlbGVjdEFsbCA9IGZhbHNlO1xuICAgIHB1YmxpYyBzaG93RmlsdGVycyA9IGZhbHNlO1xuICAgIHB1YmxpYyBmaWx0ZXJGaWVsZHMgPSBbXTtcbiAgICBwdWJsaWMgc29ydENvbmZpZyA9IG51bGw7XG4gICAgcHVibGljIG9wZW5TaWRlID0gbmV3IEJlaGF2aW9yU3ViamVjdChmYWxzZSk7XG4gICAgcHVibGljIE9iamVjdCA9IE9iamVjdDtcblxuXG4gICAgcHJpdmF0ZSBpc01vdXNlRG93biA9IGZhbHNlO1xuICAgIHByaXZhdGUgc3RhcnRSb3dJbmRleCA9IG51bGw7XG4gICAgcHJpdmF0ZSBzdGFydENlbGxJbmRleCA9IG51bGw7XG4gICAgcHJpdmF0ZSBlbmRSb3dJbmRleCA9IG51bGw7XG4gICAgcHJpdmF0ZSBlbmRDZWxsSW5kZXggPSBudWxsO1xuICAgIHByaXZhdGUgc2VsZWN0ZWRDZWxsID0gbnVsbDtcblxuICAgIC8vIEFzc29jaWF0aXZlIGxpc3Qgb2YgcGljayBmcm9tIGRhdGFzZXRzIHVzZWQgZm9yIGxpc3Qgc2VsZWN0aW9uXG4gICAgcHJpdmF0ZSBjb2x1bW5QaWNrRnJvbURhdGFzZXRzID0ge307XG5cblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgZGlhbG9nOiBNYXREaWFsb2csXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSByb3V0ZTogQWN0aXZhdGVkUm91dGUsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBkYXRhc291cmNlU2VydmljZTogRGF0YXNvdXJjZVNlcnZpY2UsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBkYXRhc2V0U2VydmljZTogRGF0YXNldFNlcnZpY2UsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBzbmFja2JhcjogTWF0U25hY2tCYXIsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBsb2NhdGlvbjogTG9jYXRpb24sXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSByb3V0ZXI6IFJvdXRlclxuICAgICkge1xuICAgIH1cblxuICAgIG5nT25Jbml0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLmRhdGFzb3VyY2VJbnN0YW5jZUtleSA9IHRoaXMucm91dGUuc25hcHNob3QucGFyYW1zLmtleTtcblxuICAgICAgICBpZiAodGhpcy5kYXRhc291cmNlSW5zdGFuY2VLZXkpIHtcbiAgICAgICAgICAgIHRoaXMuc2hvd0F1dG9JbmNyZW1lbnQgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSh0aGlzLmRhdGFzb3VyY2VJbnN0YW5jZUtleSArICdfc2hvd19pZCcpID09PSAndHJ1ZSc7XG4gICAgICAgICAgICB0aGlzLmxvYWREYXRhc291cmNlKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBkaWFsb2dSZWYgPSB0aGlzLmRpYWxvZy5vcGVuKEltcG9ydFdpemFyZENvbXBvbmVudCwge1xuICAgICAgICAgICAgICAgIHdpZHRoOiAnODAwcHgnLFxuICAgICAgICAgICAgICAgIGhlaWdodDogJzkwMHB4JyxcbiAgICAgICAgICAgICAgICBkaXNhYmxlQ2xvc2U6IHRydWUsXG4gICAgICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgICAgICBjb2x1bW5zOiB0aGlzLmNvbHVtbnMsXG4gICAgICAgICAgICAgICAgICAgIGRhdGFzb3VyY2VVcGRhdGU6IHRoaXMuZGF0YXNvdXJjZVVwZGF0ZSxcbiAgICAgICAgICAgICAgICAgICAgcm93czogdGhpcy5yb3dzLFxuICAgICAgICAgICAgICAgICAgICBkYXRhc291cmNlSW5zdGFuY2VLZXk6IHRoaXMuZGF0YXNvdXJjZUluc3RhbmNlS2V5LFxuICAgICAgICAgICAgICAgICAgICByZWxvYWRVUkw6IHRoaXMucmVsb2FkVVJMLFxuICAgICAgICAgICAgICAgICAgICBuYW1lUHJlZml4OiB0aGlzLm5hbWVQcmVmaXgsXG4gICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpY0ltcG9ydEtleTogdGhpcy5hdXRvbWF0aWNJbXBvcnRLZXlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGRpYWxvZ1JlZi5hZnRlckNsb3NlZCgpLnN1YnNjcmliZShyZXMgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChyZXMgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9jYXRpb24uYmFjaygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgICAgICBpZiAodGhpcy5zaWRlbmF2U2VydmljZSkge1xuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zaWRlbmF2U2VydmljZS5jbG9zZSgpO1xuICAgICAgICAgICAgfSwgMTAwKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmlzTW91c2VEb3duID0gZmFsc2U7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG5nT25EZXN0cm95KCkge1xuICAgICAgICBpZiAodGhpcy5zaWRlbmF2U2VydmljZSkge1xuICAgICAgICAgICAgdGhpcy5zaWRlbmF2U2VydmljZS5vcGVuKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgY2xlYXJGaWx0ZXIoKSB7XG4gICAgICAgIHRoaXMuZmlsdGVySnVuY3Rpb24gPSB7XG4gICAgICAgICAgICBsb2dpYzogJ0FORCcsXG4gICAgICAgICAgICBmaWx0ZXJzOiBbe1xuICAgICAgICAgICAgICAgIGxoc0V4cHJlc3Npb246ICcnLFxuICAgICAgICAgICAgICAgIHJoc0V4cHJlc3Npb246IFtdLFxuICAgICAgICAgICAgICAgIGZpbHRlclR5cGU6ICcnXG4gICAgICAgICAgICB9XSxcbiAgICAgICAgICAgIGZpbHRlckp1bmN0aW9uczogW11cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5sb2FkRGF0YXNvdXJjZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhcHBseUZpbHRlcigpIHtcbiAgICAgICAgdGhpcy5sb2FkRGF0YXNvdXJjZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzb3J0Q29sdW1uKGNvbHVtbjogYW55LCBkaXJlY3Rpb246IHN0cmluZykge1xuICAgICAgICB0aGlzLnNvcnRDb25maWcgPSB7ZmllbGROYW1lOiBjb2x1bW4ubmFtZSwgZGlyZWN0aW9ufTtcbiAgICAgICAgdGhpcy5sb2FkRGF0YXNvdXJjZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyB1cGRhdGVTZWxlY3RBbGwoKSB7XG4gICAgICAgIHRoaXMucm93cy5tYXAocm93ID0+IHtcbiAgICAgICAgICAgIHJvdy5fc2VsZWN0ZWQgPSB0aGlzLnNlbGVjdEFsbDtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIHVwZGF0ZVNlbGVjdGVkKCkge1xuICAgICAgICB0aGlzLnNlbGVjdEFsbCA9IF8uZXZlcnkodGhpcy5yb3dzLCAnX3NlbGVjdGVkJyk7XG4gICAgfVxuXG4gICAgcHVibGljIHVwZGF0ZUF1dG9JbmNyZW1lbnRDb2x1bW4odmFsdWUpIHtcbiAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLmNvbHVtbnMubWFwKGNvbHVtbiA9PiB7XG4gICAgICAgICAgICAgICAgY29sdW1uLmtleUZpZWxkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbHVtbjtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICB0aGlzLmNvbHVtbnMudW5zaGlmdCh7XG4gICAgICAgICAgICAgICAgdGl0bGU6ICdJRCcsXG4gICAgICAgICAgICAgICAgbmFtZTogJ2lkJyxcbiAgICAgICAgICAgICAgICB0eXBlOiAnaWQnXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIF8ucmVtb3ZlKHRoaXMuY29sdW1ucywge3R5cGU6ICdpZCd9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBhZGRDb2x1bW4oaW5kZXg/KSB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRJdGVtID0ge1xuICAgICAgICAgICAgX3RhYmxlVHlwZTogJ2NvbHVtbicsXG4gICAgICAgICAgICB0eXBlOiAnc3RyaW5nJ1xuICAgICAgICB9O1xuXG4gICAgICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICAgICAgICB0aGlzLmNvbHVtbnMuc3BsaWNlKGluZGV4LCAwLCB0aGlzLnNlbGVjdGVkSXRlbSk7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkSXRlbS5faW5kZXggPSBpbmRleDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY29sdW1ucy5wdXNoKHRoaXMuc2VsZWN0ZWRJdGVtKTtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRJdGVtLl9pbmRleCA9IHRoaXMuY29sdW1ucy5sZW5ndGggLSAxO1xuICAgICAgICB9XG5cbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLnNlbGVjdGVkSXRlbS50eXBlICsgdGhpcy5zZWxlY3RlZEl0ZW0uX2luZGV4KS5zY3JvbGxJbnRvVmlldygpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgaW1wb3J0KCkge1xuICAgICAgICBjb25zdCBkaWFsb2dSZWYgPSB0aGlzLmRpYWxvZy5vcGVuKEltcG9ydERhdGFDb21wb25lbnQsIHtcbiAgICAgICAgICAgIHdpZHRoOiAnODAwcHgnLFxuICAgICAgICAgICAgaGVpZ2h0OiAnOTAwcHgnLFxuICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgIGNvbHVtbnM6IHRoaXMuY29sdW1ucyxcbiAgICAgICAgICAgICAgICBkYXRhc291cmNlVXBkYXRlOiB0aGlzLmRhdGFzb3VyY2VVcGRhdGUsXG4gICAgICAgICAgICAgICAgcm93czogdGhpcy5yb3dzLFxuICAgICAgICAgICAgICAgIGRhdGFzb3VyY2VJbnN0YW5jZUtleTogdGhpcy5kYXRhc291cmNlSW5zdGFuY2VLZXksXG4gICAgICAgICAgICAgICAgcmVsb2FkVVJMOiB0aGlzLnJlbG9hZFVSTFxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgZGlhbG9nUmVmLmFmdGVyQ2xvc2VkKCkuc3Vic2NyaWJlKHJlcyA9PiB7XG4gICAgICAgICAgICBpZiAocmVzKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLnNlbGVjdGVkQ2VsbCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByb3dDb2xJbmRleCA9IDA7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRDZWxsID0ge3Jvd0luZGV4OiAwLCByb3dDb2xJbmRleH07XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHJlcy5oZWFkZXJSb3cpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29sdW1ucyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICByZXMuZGF0YVswXS5mb3JFYWNoKGhlYWRlciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2x1bW5zLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlOiBoZWFkZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogXy5zbmFrZUNhc2UoaGVhZGVyKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnc3RyaW5nJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbHVtbnMgPSBjb2x1bW5zO1xuICAgICAgICAgICAgICAgICAgICByZXMuZGF0YS5zaGlmdCgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmluc2VydENlbGxEYXRhKHJlcy5kYXRhKTtcblxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW5zZXJ0Q2VsbERhdGEocmVzLmRhdGEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGRlbGV0ZVNlbGVjdGVkRW50cmllcygpIHtcbiAgICAgICAgY29uc3QgbWVzc2FnZSA9ICdBcmUgeW91IHN1cmUgeW91IHdvdWxkIGxpa2UgdG8gcmVtb3ZlIGFsbCBvZiB0aGUgc2VsZWN0ZWQgZW50cmllcz8gVGhpcyBhY3Rpb24gY2Fubm90IGJlIHJldmVyc2VkLic7XG4gICAgICAgIGlmICh3aW5kb3cuY29uZmlybShtZXNzYWdlKSkge1xuICAgICAgICAgICAgY29uc3Qgc2VsZWN0ZWQgPSBfLmZpbHRlcih0aGlzLnJvd3MsICdfc2VsZWN0ZWQnKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZGF0YXNvdXJjZVNlcnZpY2UudXBkYXRlQ3VzdG9tRGF0YXNvdXJjZSh0aGlzLmRhdGFzb3VyY2VJbnN0YW5jZUtleSwge1xuICAgICAgICAgICAgICAgIHRpdGxlOiB0aGlzLmRhdGFzb3VyY2VVcGRhdGUudGl0bGUsXG4gICAgICAgICAgICAgICAgaW1wb3J0S2V5OiB0aGlzLmRhdGFzb3VyY2VVcGRhdGUuaW5zdGFuY2VJbXBvcnRLZXkgfHwgJycsXG4gICAgICAgICAgICAgICAgZmllbGRzOiB0aGlzLmRhdGFzb3VyY2VVcGRhdGUuZmllbGRzLFxuICAgICAgICAgICAgICAgIGFkZHM6IFtdLFxuICAgICAgICAgICAgICAgIHVwZGF0ZXM6IFtdLFxuICAgICAgICAgICAgICAgIGRlbGV0ZXM6IHNlbGVjdGVkXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gdGhpcy5yZWxvYWRVUkwgKyAnLycgKyB0aGlzLmRhdGFzb3VyY2VJbnN0YW5jZUtleTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBhZGRGaWx0ZXIoKSB7XG5cbiAgICB9XG5cbiAgICBwdWJsaWMgYWR2YW5jZWRTZXR0aW5ncygpIHtcbiAgICAgICAgY29uc3QgZGlhbG9nUmVmID0gdGhpcy5kaWFsb2cub3BlbihBZHZhbmNlZFNldHRpbmdzQ29tcG9uZW50LCB7XG4gICAgICAgICAgICB3aWR0aDogJzgwMHB4JyxcbiAgICAgICAgICAgIGhlaWdodDogJzkwMHB4JyxcbiAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICBkYXRhc291cmNlVXBkYXRlOiB0aGlzLmRhdGFzb3VyY2VVcGRhdGUsXG4gICAgICAgICAgICAgICAgZGF0YXNvdXJjZUluc3RhbmNlS2V5OiB0aGlzLmRhdGFzb3VyY2VJbnN0YW5jZUtleSxcbiAgICAgICAgICAgICAgICBiYWNrZW5kVVJMOiB0aGlzLmJhY2tlbmRVUkwsXG4gICAgICAgICAgICAgICAgY29sdW1uczogdGhpcy5jb2x1bW5zLFxuICAgICAgICAgICAgICAgIHNob3dBdXRvSW5jcmVtZW50OiB0aGlzLnNob3dBdXRvSW5jcmVtZW50XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBkaWFsb2dSZWYuYWZ0ZXJDbG9zZWQoKS5zdWJzY3JpYmUoYWR2YW5jZWRTZXR0aW5ncyA9PiB7XG4gICAgICAgICAgICBpZiAoYWR2YW5jZWRTZXR0aW5ncykge1xuICAgICAgICAgICAgICAgIHRoaXMuY29sdW1ucyA9IGFkdmFuY2VkU2V0dGluZ3MuY29sdW1ucztcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGFzb3VyY2VVcGRhdGUuaW5kZXhlcyA9IGFkdmFuY2VkU2V0dGluZ3MuZGF0YXNvdXJjZVVwZGF0ZS5pbmRleGVzO1xuICAgICAgICAgICAgICAgIHRoaXMuc2hvd0F1dG9JbmNyZW1lbnQgPSBhZHZhbmNlZFNldHRpbmdzLnNob3dBdXRvSW5jcmVtZW50O1xuICAgICAgICAgICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKHRoaXMuZGF0YXNvdXJjZUluc3RhbmNlS2V5ICsgJ19zaG93X2lkJywgU3RyaW5nKHRoaXMuc2hvd0F1dG9JbmNyZW1lbnQpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFwaUFjY2VzcygpIHtcbiAgICAgICAgY29uc3QgZGlhbG9nUmVmID0gdGhpcy5kaWFsb2cub3BlbihBcGlBY2Nlc3NDb21wb25lbnQsIHtcbiAgICAgICAgICAgIHdpZHRoOiAnODAwcHgnLFxuICAgICAgICAgICAgaGVpZ2h0OiAnOTAwcHgnLFxuICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgIGRhdGFzb3VyY2VVcGRhdGU6IHRoaXMuZGF0YXNvdXJjZVVwZGF0ZSxcbiAgICAgICAgICAgICAgICBkYXRhc291cmNlSW5zdGFuY2VLZXk6IHRoaXMuZGF0YXNvdXJjZUluc3RhbmNlS2V5LFxuICAgICAgICAgICAgICAgIGJhY2tlbmRVUkw6IHRoaXMuYmFja2VuZFVSTCxcbiAgICAgICAgICAgICAgICBjb2x1bW5zOiB0aGlzLmNvbHVtbnNcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGRpYWxvZ1JlZi5hZnRlckNsb3NlZCgpLnN1YnNjcmliZShyZXMgPT4ge1xuXG4gICAgICAgIH0pO1xuICAgIH1cblxuXG4gICAgcHVibGljIHNlbGVjdENvbHVtbihjb2x1bW4sIGluZGV4KSB7XG4gICAgICAgIGlmICh0aGlzLmVkaXRDb2x1bW5zICYmICFjb2x1bW4uYXV0b0luY3JlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZENlbGwgPSBudWxsO1xuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmRhdGFzb3VyY2UtdGFibGUgLmJnLWluZGlnby01MCcpLmZvckVhY2goZWxlbWVudCA9PiB7XG4gICAgICAgICAgICAgICAgZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdiZy1pbmRpZ28tNTAnKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpZiAoaW5kZXggPT09IHRoaXMuc2VsZWN0ZWRJdGVtLl9pbmRleCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRJdGVtID0ge307XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbHVtbi5fdGFibGVUeXBlID0gJ2NvbHVtbic7XG4gICAgICAgICAgICAgICAgY29sdW1uLl9pbmRleCA9IGluZGV4O1xuICAgICAgICAgICAgICAgIGlmICghY29sdW1uLnByZXZpb3VzTmFtZSkge1xuICAgICAgICAgICAgICAgICAgICBjb2x1bW4ucHJldmlvdXNOYW1lID0gY29sdW1uLm5hbWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RlZEl0ZW0gPSBjb2x1bW47XG5cbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUNlbGxGb2N1c0JvcmRlcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGRlbGV0ZUNvbHVtbihpbmRleCkge1xuICAgICAgICB0aGlzLmNvbHVtbnMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYWRkUm93KGluZGV4Pykge1xuICAgICAgICBjb25zdCByb3cgPSB7fTtcbiAgICAgICAgdGhpcy5jb2x1bW5zLmZvckVhY2goY29sdW1uID0+IHtcbiAgICAgICAgICAgIHJvd1tjb2x1bW4ubmFtZV0gPSBudWxsO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoaW5kZXggPiAtMSkge1xuICAgICAgICAgICAgdGhpcy5yb3dzLnNwbGljZShpbmRleCwgMCwgcm93KTtcbiAgICAgICAgICAgIHRoaXMuYWRkcy5wdXNoKGluZGV4KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMucm93cy5wdXNoKHJvdyk7XG4gICAgICAgICAgICB0aGlzLmFkZHMucHVzaCh0aGlzLnJvd3MubGVuZ3RoIC0gMSk7XG4gICAgICAgIH1cblxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRhYmxlV3JhcHBlciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0YWJsZVdyYXBwZXInKTtcbiAgICAgICAgICAgIHRhYmxlV3JhcHBlci5zY3JvbGxUb3AgPSB0YWJsZVdyYXBwZXIuc2Nyb2xsSGVpZ2h0O1xuICAgICAgICB9LCAwKTtcblxuICAgIH1cblxuICAgIHB1YmxpYyBkZWxldGVSb3cocm93SW5kZXgpIHtcbiAgICAgICAgY29uc3QgaW5BZGRzID0gdGhpcy5hZGRzLmluZGV4T2Yocm93SW5kZXgpO1xuICAgICAgICBpZiAoaW5BZGRzID4gLTEpIHtcbiAgICAgICAgICAgIHRoaXMucm93cy5zcGxpY2Uocm93SW5kZXgsIDEpO1xuICAgICAgICAgICAgdGhpcy5hZGRzLnBvcCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5kZWxldGVzLnB1c2gocm93SW5kZXgpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaW5VcGRhdGVzID0gdGhpcy51cGRhdGVzLmluZGV4T2Yocm93SW5kZXgpO1xuICAgICAgICBpZiAoaW5VcGRhdGVzID4gLTEpIHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlcy5zcGxpY2UoaW5VcGRhdGVzLCAxKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBmb2N1c0NlbGwoZXZlbnQsIHJvd0luZGV4LCByb3dDb2xJbmRleCkge1xuICAgICAgICB0aGlzLnNlbGVjdGVkQ2VsbCA9IHtyb3dJbmRleCwgcm93Q29sSW5kZXh9O1xuICAgICAgICB0aGlzLnJlbW92ZUNlbGxGb2N1c0JvcmRlcigpO1xuICAgICAgICBldmVudC50YXJnZXQucGFyZW50RWxlbWVudC5jbGFzc0xpc3QuYWRkKCdib3JkZXInLCAnYm9yZGVyLWJsdWUtNTAwJyk7XG4gICAgfVxuXG4gICAgcHVibGljIGJsdXJDZWxsKCkge1xuICAgICAgICB0aGlzLnNlbGVjdGVkQ2VsbCA9IG51bGw7XG4gICAgICAgIHRoaXMucmVtb3ZlQ2VsbEZvY3VzQm9yZGVyKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGNsZWFyQ2VsbChyb3dJbmRleCwgcm93Q29sSW5kZXgpIHtcbiAgICAgICAgY29uc3QgY29sdW1uTmFtZSA9IHRoaXMuY29sdW1uc1tyb3dDb2xJbmRleF0ubmFtZTtcbiAgICAgICAgdGhpcy5yb3dzW3Jvd0luZGV4XVtjb2x1bW5OYW1lXSA9ICcnO1xuICAgICAgICBpZiAodGhpcy5hZGRzLmluZGV4T2Yocm93SW5kZXgpID09PSAtMSkge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVzLnB1c2gocm93SW5kZXgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIHVwZGF0ZUZpZWxkKGZpZWxkLCByb3dJbmRleCwgZXZlbnQpIHtcbiAgICAgICAgaWYgKHRoaXMuYWRkcy5pbmRleE9mKHJvd0luZGV4KSA9PT0gLTEpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnVwZGF0ZXMuaW5kZXhPZihyb3dJbmRleCkgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVzLnB1c2gocm93SW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gSGFuZGxlIGltcGxpY2l0IGZhbHNlIHZhbHVlcyBmb3IgYm9vbGVhbnMgYW5kIGltcGxpY2l0IG51bGxzIGZvciBvdGhlciBmaWVsZHNcbiAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgICB0aGlzLnJvd3Nbcm93SW5kZXhdW2ZpZWxkLm5hbWVdID0gZXZlbnQudGFyZ2V0LmNoZWNrZWQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAodGhpcy5yb3dzW3Jvd0luZGV4XVtmaWVsZC5uYW1lXSA9PT0gJycpXG4gICAgICAgICAgICAgICAgdGhpcy5yb3dzW3Jvd0luZGV4XVtmaWVsZC5uYW1lXSA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmVkaXRNb2RlID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgdXBkYXRlQ29sdW1uTmFtZSgpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZEl0ZW0ubmFtZSA9IF8uc25ha2VDYXNlKHRoaXMuc2VsZWN0ZWRJdGVtLnRpdGxlKTtcbiAgICAgICAgdGhpcy5yb3dzLm1hcChyb3cgPT4ge1xuICAgICAgICAgICAgcm93W3RoaXMuc2VsZWN0ZWRJdGVtLm5hbWVdID0gcm93W3RoaXMuc2VsZWN0ZWRJdGVtLnByZXZpb3VzTmFtZV0gfHwgJyc7XG4gICAgICAgICAgICBpZiAocm93W3RoaXMuc2VsZWN0ZWRJdGVtLnByZXZpb3VzTmFtZV0pIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgcm93W3RoaXMuc2VsZWN0ZWRJdGVtLnByZXZpb3VzTmFtZV07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiByb3c7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBlbnRlckNlbGwocm93SW5kZXgsIHJvd0NvbEluZGV4LCBldmVudCkge1xuICAgICAgICBjb25zdCByb3cgPSB7fTtcbiAgICAgICAgbGV0IHJvd0VsZW1lbnQgPSBudWxsO1xuICAgICAgICBsZXQgcm93RWxlbWVudEluZGV4O1xuICAgICAgICB0aGlzLmNvbHVtbnMuZm9yRWFjaChjb2x1bW4gPT4ge1xuICAgICAgICAgICAgcm93W2NvbHVtbi5uYW1lXSA9ICcnO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHJvd0luZGV4ID09PSB0aGlzLnJvd3MubGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgdGhpcy5yb3dzLnB1c2gocm93KTtcbiAgICAgICAgICAgIHJvd0VsZW1lbnRJbmRleCA9IHRoaXMucm93cy5sZW5ndGggLSAxO1xuICAgICAgICAgICAgdGhpcy5hZGRzLnB1c2godGhpcy5yb3dzLmxlbmd0aCAtIDEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcm93RWxlbWVudEluZGV4ID0gcm93SW5kZXggKyAxO1xuICAgICAgICB9XG5cbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICByb3dFbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLnRhYmxlLXJvd3MnKS5pdGVtKHJvd0VsZW1lbnRJbmRleCk7XG4gICAgICAgICAgICBjb25zdCByb3dDZWxsOiBhbnkgPSByb3dFbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5yb3ctY2VsbCcpLml0ZW0odGhpcy5zaG93QXV0b0luY3JlbWVudCA/IHJvd0NvbEluZGV4ICsgMSA6IHJvd0NvbEluZGV4KTtcbiAgICAgICAgICAgIHJvd0NlbGwucXVlcnlTZWxlY3RvckFsbCgnLmNlbGwtaW5wdXQnKS5pdGVtKDApLmZvY3VzKCk7XG4gICAgICAgIH0sIDApO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBzYXZlKGV4aXQgPSBmYWxzZSkge1xuICAgICAgICBpZiAoIXRoaXMuZGF0YXNvdXJjZVVwZGF0ZS50aXRsZSkge1xuICAgICAgICAgICAgd2luZG93LmFsZXJ0KCdQbGVhc2UgZW50ZXIgYSB0aXRsZSBmb3IgdGhpcyBEYXRhc291cmNlLicpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFfLmZpbmQodGhpcy5jb2x1bW5zLCB7a2V5RmllbGQ6IHRydWV9KSAmJlxuICAgICAgICAgICAgIV8uZmluZCh0aGlzLmNvbHVtbnMsIHt0eXBlOiAnaWQnfSkpIHtcbiAgICAgICAgICAgIHdpbmRvdy5hbGVydCgnUGxlYXNlIHNlbGVjdCBvbmUgb2YgeW91ciBmaWVsZHMgYXMgdGhlIFwiVW5pcXVlIEtleVwiJyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmRhdGFzb3VyY2VVcGRhdGUuZmllbGRzID0gdGhpcy5jb2x1bW5zLm1hcChjb2x1bW4gPT4ge1xuICAgICAgICAgICAgaWYgKGNvbHVtbi5uYW1lID09PSBjb2x1bW4ucHJldmlvdXNOYW1lKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIGNvbHVtbi5wcmV2aW91c05hbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gY29sdW1uO1xuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBjaGFuZ2VzID0gWydhZGRzJywgJ3VwZGF0ZXMnLCAnZGVsZXRlcyddO1xuICAgICAgICBjaGFuZ2VzLmZvckVhY2goY2hhbmdlID0+IHtcbiAgICAgICAgICAgIHRoaXMuZGF0YXNvdXJjZVVwZGF0ZVtjaGFuZ2VdID0gXy5tYXAoXy51bmlxKHRoaXNbY2hhbmdlXSksIHJvd0luZGV4ID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5yb3dzW3Jvd0luZGV4XTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAodGhpcy5uYW1lUHJlZml4ICYmICF0aGlzLmRhdGFzb3VyY2VVcGRhdGUudGl0bGUuaW5jbHVkZXModGhpcy5uYW1lUHJlZml4KSkge1xuICAgICAgICAgICAgdGhpcy5kYXRhc291cmNlVXBkYXRlLnRpdGxlID0gdGhpcy5uYW1lUHJlZml4ICsgdGhpcy5kYXRhc291cmNlVXBkYXRlLnRpdGxlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVzZXQgaW52YWxpZCBpdGVtc1xuICAgICAgICB0aGlzLmludmFsaWRJdGVtcyA9IFtdO1xuXG5cbiAgICAgICAgaWYgKCF0aGlzLmRhdGFzb3VyY2VJbnN0YW5jZUtleSkge1xuXG4gICAgICAgICAgICBpZiAodGhpcy5hdXRvbWF0aWNJbXBvcnRLZXkpe1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YXNvdXJjZVVwZGF0ZS5pbXBvcnRLZXkgPSBzaG9ydEhhc2goRGF0ZS5ub3coKS50b1N0cmluZygpKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgYXdhaXQgdGhpcy5kYXRhc291cmNlU2VydmljZS5jcmVhdGVDdXN0b21EYXRhc291cmNlKHRoaXMuZGF0YXNvdXJjZVVwZGF0ZSkudGhlbihrZXkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghZXhpdCkge1xuICAgICAgICAgICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZiA9IHRoaXMucmVsb2FkVVJMICsgJy8nICsga2V5O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0pLmNhdGNoKGVyciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXJyb3JDb2RlID0gKGVyci5lcnJvciAmJiBlcnIuZXJyb3Iuc3FsU3RhdGVDb2RlKSA/IGVyci5lcnJvci5zcWxTdGF0ZUNvZGUgOiAwO1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzcGxheUVycm9yKGVycm9yQ29kZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZGF0YXNvdXJjZVVwZGF0ZS5pbXBvcnRLZXkgPSB0aGlzLmRhdGFzb3VyY2VVcGRhdGUuaW5zdGFuY2VJbXBvcnRLZXk7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmRhdGFzb3VyY2VTZXJ2aWNlLnVwZGF0ZUN1c3RvbURhdGFzb3VyY2UodGhpcy5kYXRhc291cmNlSW5zdGFuY2VLZXksIHRoaXMuZGF0YXNvdXJjZVVwZGF0ZSlcbiAgICAgICAgICAgICAgICAudGhlbihhc3luYyAocmVzdWx0OiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAmJiByZXN1bHQucmVqZWN0ZWQgJiYgcmVzdWx0LnJlamVjdGVkID4gMCkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNuYWNrYmFyLm9wZW4oJ1RoZXJlIHdlcmUgdmFsaWRhdGlvbiBwcm9ibGVtcyB3aXRoIG9uZSBvciBtb3JlIG9mIHlvdXIgcm93cyAtIHNlZSBoaWdobGlnaHRlZCBjZWxscyBiZWxvdycsIG51bGwsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbjogNTAwMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZXJ0aWNhbFBvc2l0aW9uOiAndG9wJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW52YWxpZEFkZFJvd3MgPSBfLm1hcChyZXN1bHQudmFsaWRhdGlvbkVycm9ycy5hZGQgfHwgW10sICdpdGVtTnVtYmVyJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gdGhpcy5hZGRzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGludmFsaWRBZGRSb3dzLmluY2x1ZGVzKGkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW52YWxpZEl0ZW1zW3RoaXMuYWRkc1tpXV0gPSBfLmZpbmQocmVzdWx0LnZhbGlkYXRpb25FcnJvcnMuYWRkLCB7aXRlbU51bWJlcjogaX0pLnZhbGlkYXRpb25FcnJvcnM7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGludmFsaWRVcGRhdGVSb3dzID0gXy5tYXAocmVzdWx0LnZhbGlkYXRpb25FcnJvcnMudXBkYXRlIHx8IFtdLCAnaXRlbU51bWJlcicpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IHRoaXMudXBkYXRlcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbnZhbGlkVXBkYXRlUm93cy5pbmNsdWRlcyhpKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmludmFsaWRJdGVtc1t0aGlzLnVwZGF0ZXNbaV1dID0gXy5maW5kKHJlc3VsdC52YWxpZGF0aW9uRXJyb3JzLnVwZGF0ZSwge2l0ZW1OdW1iZXI6IGl9KS52YWxpZGF0aW9uRXJyb3JzO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFkZHMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlcyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kZWxldGVzID0gW107XG5cblxuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5sb2FkRGF0YXNvdXJjZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVyciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdFUlJPUicsIGVycik7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yQ29kZSA9IChlcnIuZXJyb3IgJiYgZXJyLmVycm9yLnNxbFN0YXRlQ29kZSkgPyBlcnIuZXJyb3Iuc3FsU3RhdGVDb2RlIDogMDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kaXNwbGF5RXJyb3IoZXJyb3JDb2RlKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChleGl0KSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5yb3V0ZXIubmF2aWdhdGUoW3RoaXMuYmFja1VSTF0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGNhbmNlbENoYW5nZXMoKSB7XG4gICAgICAgIHRoaXMuYWRkcyA9IFtdO1xuICAgICAgICB0aGlzLnVwZGF0ZXMgPSBbXTtcbiAgICAgICAgdGhpcy5kZWxldGVzID0gW107XG5cbiAgICAgICAgdGhpcy5sb2FkRGF0YXNvdXJjZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXRUeXBlQ29uZmlnKCkge1xuICAgICAgICBpZiAoIXRoaXMuc2VsZWN0ZWRJdGVtLnR5cGVDb25maWcgfHwgQXJyYXkuaXNBcnJheSh0aGlzLnNlbGVjdGVkSXRlbS50eXBlQ29uZmlnKSkge1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZEl0ZW0udHlwZUNvbmZpZyA9IHt9O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGRlbGV0ZVNlbGVjdGVkQ29sdW1uKCkge1xuICAgICAgICB0aGlzLmNvbHVtbnMuc3BsaWNlKHRoaXMuc2VsZWN0ZWRJdGVtLl9pbmRleCwgMSk7XG4gICAgfVxuXG4gICAgcHVibGljIHBhZ2VTaXplQ2hhbmdlKHZhbHVlKSB7XG4gICAgICAgIHRoaXMubGltaXQgPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5sb2FkRGF0YXNvdXJjZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBpbmNyZWFzZU9mZnNldCgpIHtcbiAgICAgICAgdGhpcy5wYWdlID0gdGhpcy5wYWdlICsgMTtcbiAgICAgICAgdGhpcy5vZmZzZXQgPSAodGhpcy5saW1pdCAqIHRoaXMucGFnZSkgLSB0aGlzLmxpbWl0O1xuICAgICAgICB0aGlzLmxvYWREYXRhc291cmNlKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGRlY3JlYXNlT2Zmc2V0KCkge1xuICAgICAgICB0aGlzLnBhZ2UgPSB0aGlzLnBhZ2UgPD0gMSA/IDEgOiB0aGlzLnBhZ2UgLSAxO1xuICAgICAgICB0aGlzLm9mZnNldCA9ICh0aGlzLmxpbWl0ICogdGhpcy5wYWdlKSAtIHRoaXMubGltaXQ7XG4gICAgICAgIHRoaXMubG9hZERhdGFzb3VyY2UoKTtcbiAgICB9XG5cblxuICAgIC8vIEdldCBpbnB1dCB0eXBlIGZvciBmaWVsZFxuICAgIHB1YmxpYyBpbnB1dFR5cGVGb3JGaWVsZChmaWVsZDogYW55KSB7XG4gICAgICAgIHN3aXRjaCAoZmllbGQudHlwZSkge1xuICAgICAgICAgICAgY2FzZSAnaW50ZWdlcic6XG4gICAgICAgICAgICBjYXNlICdmbG9hdCc6XG4gICAgICAgICAgICAgICAgcmV0dXJuICdudW1iZXInO1xuICAgICAgICAgICAgY2FzZSAnYm9vbGVhbic6XG4gICAgICAgICAgICAgICAgcmV0dXJuICdjaGVja2JveCc7XG4gICAgICAgICAgICBjYXNlICdkYXRlJzpcbiAgICAgICAgICAgICAgICByZXR1cm4gJ2RhdGUnO1xuICAgICAgICAgICAgY2FzZSAnZGF0ZXRpbWUnOlxuICAgICAgICAgICAgICAgIHJldHVybiAnZGF0ZXRpbWUtbG9jYWwnO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gJ3RleHQnO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICBwcml2YXRlIGxvYWREYXRhc291cmNlKCkge1xuICAgICAgICBpZiAodGhpcy5kYXRhc291cmNlSW5zdGFuY2VLZXkpIHtcblxuICAgICAgICAgICAgLy8gSWYgd2UgaGF2ZSBhIGZpbHRlciBpbiB1c2UsIGFwcGx5IGl0IHRvIHRoZSBuZXh0IGxvYWQuLi5cbiAgICAgICAgICAgIGNvbnN0IHRyYW5zZm9ybWF0aW9uSW5zdGFuY2VzID0gW107XG4gICAgICAgICAgICBpZiAodGhpcy5maWx0ZXJKdW5jdGlvbi5maWx0ZXJKdW5jdGlvbnMubGVuZ3RoIHx8IHRoaXMuZmlsdGVySnVuY3Rpb24uZmlsdGVyc1swXS5maWx0ZXJUeXBlKSB7XG4gICAgICAgICAgICAgICAgdHJhbnNmb3JtYXRpb25JbnN0YW5jZXMucHVzaCh7dHlwZTogJ2ZpbHRlcicsIGNvbmZpZzogdGhpcy5maWx0ZXJKdW5jdGlvbn0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuc29ydENvbmZpZykge1xuICAgICAgICAgICAgICAgIHRyYW5zZm9ybWF0aW9uSW5zdGFuY2VzLnB1c2goe3R5cGU6ICdtdWx0aXNvcnQnLCBjb25maWc6IHtzb3J0czogW3RoaXMuc29ydENvbmZpZ119fSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGV2YWx1YXRlZERhdGFzb3VyY2UgPSB7XG4gICAgICAgICAgICAgICAga2V5OiB0aGlzLmRhdGFzb3VyY2VJbnN0YW5jZUtleSxcbiAgICAgICAgICAgICAgICB0cmFuc2Zvcm1hdGlvbkluc3RhbmNlcyxcbiAgICAgICAgICAgICAgICBwYXJhbWV0ZXJWYWx1ZXM6IHt9LFxuICAgICAgICAgICAgICAgIG9mZnNldDogdGhpcy5vZmZzZXQsXG4gICAgICAgICAgICAgICAgbGltaXQ6IHRoaXMubGltaXRcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMuZGF0YXNvdXJjZVNlcnZpY2UuZXZhbHVhdGVEYXRhc291cmNlKGV2YWx1YXRlZERhdGFzb3VyY2UpLnRoZW4oKHJlczogYW55KSA9PiB7XG5cbiAgICAgICAgICAgICAgICBsZXQganNvbkNvbHVtbnMgPSBbXTtcblxuICAgICAgICAgICAgICAgIHRoaXMuY29sdW1ucyA9IHJlcy5jb2x1bW5zLm1hcChjb2x1bW4gPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb2x1bW4ucHJldmlvdXNOYW1lID0gY29sdW1uLm5hbWU7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbHVtbi50eXBlID09PSAncGlja2Zyb21zb3VyY2UnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuY29sdW1uUGlja0Zyb21EYXRhc2V0c1tjb2x1bW4ubmFtZV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBvcHVsYXRlQ29sdW1uUGlja0Zyb20oY29sdW1uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjb2x1bW4udHlwZSA9PT0gJ2pzb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBqc29uQ29sdW1ucy5wdXNoKGNvbHVtbi5uYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjb2x1bW47XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgdGhpcy5maWx0ZXJGaWVsZHMgPSBfLm1hcCh0aGlzLmNvbHVtbnMsIGNvbHVtbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZTogY29sdW1uLnRpdGxlLFxuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogY29sdW1uLm5hbWVcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB0aGlzLnJvd3MgPSByZXMuYWxsRGF0YTtcblxuICAgICAgICAgICAgICAgIC8vIElmIEpTT04gQ29sdW1ucywgZW5zdXJlIHdlIGRlc2VyaWFsaXNlIEpTT04gdmFsdWVzXG4gICAgICAgICAgICAgICAgaWYgKGpzb25Db2x1bW5zLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnJvd3MuZm9yRWFjaChyb3cgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAganNvbkNvbHVtbnMuZm9yRWFjaChqc29uQ29sdW1uID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocm93W2pzb25Db2x1bW5dIHx8IG51bGwpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvd1tqc29uQ29sdW1uXSA9IEpTT04uc3RyaW5naWZ5KHJvd1tqc29uQ29sdW1uXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5lbmRPZlJlc3VsdHMgPSB0aGlzLnJvd3MubGVuZ3RoIDwgdGhpcy5saW1pdDtcblxuICAgICAgICAgICAgICAgIHRoaXMuZGF0YXNvdXJjZVVwZGF0ZS50aXRsZSA9IHJlcy5pbnN0YW5jZVRpdGxlO1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YXNvdXJjZVVwZGF0ZS5pbnN0YW5jZUltcG9ydEtleSA9IHJlcy5pbnN0YW5jZUltcG9ydEtleTtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGFzb3VyY2VVcGRhdGUuaW5kZXhlcyA9IHJlcy5pbmRleGVzO1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YXNvdXJjZVVwZGF0ZS5hZGRzID0gW107XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhc291cmNlVXBkYXRlLnVwZGF0ZXMgPSBbXTtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGFzb3VyY2VVcGRhdGUuZGVsZXRlcyA9IFtdO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5hdXRvSW5jcmVtZW50Q29sdW1uID0gXy5zb21lKHRoaXMuY29sdW1ucywge3R5cGU6ICdpZCd9KTtcblxuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0QWxsID0gZmFsc2U7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVkaXRNb2RlID0gZmFsc2U7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzZWxlY3RDZWxsKHJvd0luZGV4LCBjZWxsSW5kZXgpIHtcbiAgICAgICAgbGV0IHJvd1N0YXJ0LCByb3dFbmQsIGNlbGxTdGFydCwgY2VsbEVuZDtcblxuICAgICAgICBpZiAocm93SW5kZXggPCB0aGlzLnN0YXJ0Um93SW5kZXgpIHtcbiAgICAgICAgICAgIHJvd1N0YXJ0ID0gcm93SW5kZXg7XG4gICAgICAgICAgICByb3dFbmQgPSB0aGlzLnN0YXJ0Um93SW5kZXg7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByb3dTdGFydCA9IHRoaXMuc3RhcnRSb3dJbmRleDtcbiAgICAgICAgICAgIHJvd0VuZCA9IHJvd0luZGV4O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNlbGxJbmRleCA8IHRoaXMuc3RhcnRDZWxsSW5kZXgpIHtcbiAgICAgICAgICAgIGNlbGxTdGFydCA9IGNlbGxJbmRleDtcbiAgICAgICAgICAgIGNlbGxFbmQgPSB0aGlzLnN0YXJ0Q2VsbEluZGV4O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2VsbFN0YXJ0ID0gdGhpcy5zdGFydENlbGxJbmRleDtcbiAgICAgICAgICAgIGNlbGxFbmQgPSBjZWxsSW5kZXg7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGxldCBpID0gcm93U3RhcnQ7IGkgPD0gcm93RW5kOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHJvd0VsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcudGFibGUtcm93cycpLml0ZW0oaSk7XG4gICAgICAgICAgICBjb25zdCByb3dDZWxscyA9IHJvd0VsZW1lbnQucXVlcnlTZWxlY3RvckFsbCgndGQnKTtcbiAgICAgICAgICAgIGZvciAobGV0IGogPSBjZWxsU3RhcnQ7IGogPD0gY2VsbEVuZDsgaisrKSB7XG4gICAgICAgICAgICAgICAgcm93Q2VsbHMuaXRlbShqKS5jbGFzc0xpc3QuYWRkKCdiZy1pbmRpZ28tNTAnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgcmVtb3ZlQ2VsbEZvY3VzQm9yZGVyKCkge1xuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuaW5wdXQtd3JhcHBlci5ib3JkZXItYmx1ZS01MDAnKS5mb3JFYWNoKGVsZW1lbnQgPT4ge1xuICAgICAgICAgICAgZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdib3JkZXItYmx1ZS01MDAnKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpbnNlcnRDZWxsRGF0YShkYXRhKSB7XG4gICAgICAgIGNvbnN0IHJvdyA9IHt9O1xuICAgICAgICB0aGlzLmNvbHVtbnMuZm9yRWFjaChjb2x1bW4gPT4ge1xuICAgICAgICAgICAgcm93W2NvbHVtbi5uYW1lXSA9ICcnO1xuICAgICAgICB9KTtcblxuICAgICAgICBsZXQgc3RhcnRJbmRleCA9IHRoaXMuc2VsZWN0ZWRDZWxsLnJvd0luZGV4O1xuICAgICAgICB3aGlsZSAodGhpcy5yb3dzLmxlbmd0aCA8IChkYXRhLmxlbmd0aCArIHRoaXMuc2VsZWN0ZWRDZWxsLnJvd0luZGV4KSkge1xuICAgICAgICAgICAgdGhpcy5yb3dzLnB1c2goXy5jbG9uZShyb3cpKTtcbiAgICAgICAgICAgIHRoaXMuZGVsZXRlcy5zcGxpY2Uoc3RhcnRJbmRleCwgMSk7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZXMuc3BsaWNlKHN0YXJ0SW5kZXgsIDEpO1xuICAgICAgICAgICAgdGhpcy5hZGRzLnNwbGljZShzdGFydEluZGV4LCAxKTtcbiAgICAgICAgICAgIHRoaXMuYWRkcy5wdXNoKHN0YXJ0SW5kZXgpO1xuICAgICAgICAgICAgc3RhcnRJbmRleCsrO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHJvd0luZGV4ID0gMDtcbiAgICAgICAgZm9yIChsZXQgaSA9IHRoaXMuc2VsZWN0ZWRDZWxsLnJvd0luZGV4OyBpIDwgKHRoaXMuc2VsZWN0ZWRDZWxsLnJvd0luZGV4ICsgZGF0YS5sZW5ndGgpOyBpKyspIHtcbiAgICAgICAgICAgIGxldCB2YWxJbmRleCA9IDA7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZXMgPSBfLnZhbHVlcyhkYXRhW3Jvd0luZGV4XSk7XG4gICAgICAgICAgICBmb3IgKGxldCBqID0gdGhpcy5zZWxlY3RlZENlbGwucm93Q29sSW5kZXg7IGogPCAodmFsdWVzLmxlbmd0aCArIHRoaXMuc2VsZWN0ZWRDZWxsLnJvd0NvbEluZGV4KTsgaisrKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuY29sdW1uc1tqXSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnJvd3NbaV1bdGhpcy5jb2x1bW5zW2pdLm5hbWVdID0gdmFsdWVzW3ZhbEluZGV4XSB8fCAnJztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFsSW5kZXgrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJvd0luZGV4Kys7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGRpc3BsYXlFcnJvcihjb2RlOiBhbnkpIHtcbiAgICAgICAgbGV0IG1lc3NhZ2UgPSAnVGhlcmUgd2FzIGFuIGVycm9yIGNyZWF0aW5nL2VkaXRpbmcgeW91ciBkYXRhIHNvdXJjZS4gUGxlYXNlIGNoZWNrIGFuZCB0cnkgYWdhaW4uJztcblxuICAgICAgICBzd2l0Y2ggKE51bWJlcihjb2RlKSkge1xuICAgICAgICAgICAgY2FzZSAyMzAwMDpcbiAgICAgICAgICAgICAgICBtZXNzYWdlID0gJ0R1cGxpY2F0ZSBVbmlxdWUgS2V5IEZvdW5kLiBQbGVhc2UgY2hlY2sgZm9yIGR1cGxpY2F0ZSB2YWx1ZXMgaW4gdW5pcXVlIGlkZW50aXR5IGNvbHVtbi4nO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zbmFja2Jhci5vcGVuKG1lc3NhZ2UsIG51bGwsIHtcbiAgICAgICAgICAgIGR1cmF0aW9uOiA1MDAwLFxuICAgICAgICAgICAgdmVydGljYWxQb3NpdGlvbjogJ3RvcCdcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIHNlbGVjdENvbHVtblBpY2tGcm9tRGF0YXNvdXJjZShjb2x1bW46IGFueSkge1xuXG4gICAgICAgIGNvbnN0IGRpYWxvZ1JlZiA9IHRoaXMuZGlhbG9nLm9wZW4oQ3JlYXRlRGF0YXNldENvbXBvbmVudCwge1xuICAgICAgICAgICAgd2lkdGg6ICcxMjAwcHgnLFxuICAgICAgICAgICAgaGVpZ2h0OiAnODAwcHgnLFxuICAgICAgICAgICAgZGF0YToge31cbiAgICAgICAgfSk7XG4gICAgICAgIGRpYWxvZ1JlZi5hZnRlckNsb3NlZCgpLnN1YnNjcmliZShhc3luYyByZXMgPT4ge1xuICAgICAgICAgICAgaWYgKHJlcykge1xuICAgICAgICAgICAgICAgIGNvbHVtbi50eXBlQ29uZmlnID0ge1xuICAgICAgICAgICAgICAgICAgICBkYXRhc2V0SW5zdGFuY2VJZDogcmVzLmRhdGFzZXRJbnN0YW5jZUlkLFxuICAgICAgICAgICAgICAgICAgICBkYXRhc291cmNlSW5zdGFuY2VLZXk6IHJlcy5kYXRhc291cmNlSW5zdGFuY2VLZXlcbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgLy8gUG9wdWxhdGUgdGhlIGNvbHVtbiBwaWNrIGZyb21cbiAgICAgICAgICAgICAgICB0aGlzLnBvcHVsYXRlQ29sdW1uUGlja0Zyb20oY29sdW1uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvLyBQaWNrIGZyb20gZGF0YXNldHNcbiAgICBwcml2YXRlIHBvcHVsYXRlQ29sdW1uUGlja0Zyb20oY29sdW1uOiBhbnkpIHtcbiAgICAgICAgdGhpcy5kYXRhc2V0U2VydmljZS5ldmFsdWF0ZURhdGFzZXQoY29sdW1uLnR5cGVDb25maWcsICcwJywgJzEwMDAwMDAwJykudGhlbigoZGF0YXNldCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5jb2x1bW5QaWNrRnJvbURhdGFzZXRzW2NvbHVtbi5uYW1lXSA9IGRhdGFzZXQ7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJib3JkZXItYiB3LWZ1bGwgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1iZXR3ZWVuIFwiPlxuICAgIDxkaXYgKm5nSWY9XCIhcmVhZG9ubHlcIlxuICAgICAgICAgY2xhc3M9XCJsZWFkaW5nLTUgZmxleCBpdGVtcy1jZW50ZXIgcHgtNCB0ZXh0LXhzIHctOTYgdXBwZXJjYXNlIHRyYWNraW5nLXdpZGVyIGZvbnQtbWVkaXVtIHRleHQtZ3JheS02MDBcIj5cbiAgICAgICAgTmFtZVxuICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cInctZnVsbCBweS0xLjUgbWwtNFwiIHBsYWNlaG9sZGVyPVwiRW50ZXIgZGF0YXNvdXJjZSBuYW1lXCJcbiAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnYm9yZGVyIGJvcmRlci1yZWQtNTAwJzogIWRhdGFzb3VyY2VVcGRhdGUudGl0bGV9XCJcbiAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiZGF0YXNvdXJjZVVwZGF0ZS50aXRsZVwiPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgKm5nSWY9XCJyZWFkb25seVwiXG4gICAgICAgICBjbGFzcz1cImxlYWRpbmctNSBmb250LW1lZGl1bSB0ZXh0LWxnIHB4LTRcIj57e2RhdGFzb3VyY2VVcGRhdGUudGl0bGUucmVwbGFjZSgobmFtZVByZWZpeCB8fCAnJyksICcnKX19PC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImZsZXgtMSBmbGV4IGl0ZW1zLWNlbnRlciBmbGV4LXdyYXAgdy1mdWxsIGp1c3RpZnktZW5kIGJnLXdoaXRlXCI+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJfLnNvbWUocm93cywgJ19zZWxlY3RlZCcpXCI+XG4gICAgICAgICAgICA8YnV0dG9uIChjbGljayk9XCJkZWxldGVTZWxlY3RlZEVudHJpZXMoKVwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwidy0yOCBmbGV4IGZsZXgtY29sIGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciBweS0xIHB4LTIgdGV4dC14cyB0ZXh0LWdyYXktNjAwIGN1cnNvci1wb2ludGVyIGhvdmVyOmJnLWdyYXktMTAwXCI+XG4gICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwidGV4dC14bFwiPmRlbGV0ZV9mb3JldmVyPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICBkZWxldGUgc2VsZWN0ZWRcbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRpdmlkZXJcIj48L2Rpdj5cbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICA8YnV0dG9uICpuZ0lmPVwiIWVkaXRNb2RlXCIgKGNsaWNrKT1cInNob3dGaWx0ZXJzID0gIXNob3dGaWx0ZXJzXCJcbiAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJ7J2JhY2tncm91bmQtY29sb3InOiB0aGlzLnNob3dGaWx0ZXJzID8gJyMwMDAwMDAxMicgOiAnJ31cIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwidy0yMCBmbGV4IGZsZXgtY29sIGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciBweS0xIHB4LTIgdGV4dC14cyB0ZXh0LWdyYXktNjAwIGN1cnNvci1wb2ludGVyIGhvdmVyOmJnLWdyYXktMTAwXCI+XG4gICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJ0ZXh0LXhsXCI+ZmlsdGVyX2FsdDwvbWF0LWljb24+XG4gICAgICAgICAgICBmaWx0ZXJcbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxkaXYgKm5nSWY9XCIhZWRpdE1vZGVcIiBjbGFzcz1cImRpdmlkZXJcIj48L2Rpdj5cbiAgICAgICAgPGJ1dHRvbiAqbmdJZj1cIiFlZGl0TW9kZVwiIChjbGljayk9XCJhZHZhbmNlZFNldHRpbmdzKClcIiBbZGlzYWJsZWRdPVwiIWRhdGFzb3VyY2VJbnN0YW5jZUtleVwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJkaXNhYmxlZDpvcGFjaXR5LTUwIHctMjAgZmxleCBmbGV4LWNvbCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgcHktMSBweC0yIHRleHQteHMgdGV4dC1ncmF5LTYwMCBjdXJzb3ItcG9pbnRlciBob3ZlcjpiZy1ncmF5LTEwMFwiPlxuICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwidGV4dC14bFwiPnR1bmU8L21hdC1pY29uPlxuICAgICAgICAgICAgYWR2YW5jZWRcbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxidXR0b24gKm5nSWY9XCIhZWRpdE1vZGUgJiYgIWhpZGVBUElBY2Nlc3NcIiAoY2xpY2spPVwiYXBpQWNjZXNzKClcIiBbZGlzYWJsZWRdPVwiIWRhdGFzb3VyY2VJbnN0YW5jZUtleVwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJkaXNhYmxlZDpvcGFjaXR5LTUwIHctMjAgZmxleCBmbGV4LWNvbCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgcHktMSBweC0yIHRleHQteHMgdGV4dC1ncmF5LTYwMCBjdXJzb3ItcG9pbnRlciBob3ZlcjpiZy1ncmF5LTEwMFwiPlxuICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwidGV4dC14bFwiPmFwaTwvbWF0LWljb24+XG4gICAgICAgICAgICBhcGkgYWNjZXNzXG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uICpuZ0lmPVwiIWVkaXRNb2RlXCIgKGNsaWNrKT1cImltcG9ydCgpXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInctMjAgZmxleCBmbGV4LWNvbCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgcHktMSBweC0yIHRleHQteHMgdGV4dC1ncmF5LTYwMCBjdXJzb3ItcG9pbnRlciBob3ZlcjpiZy1ncmF5LTEwMFwiPlxuICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwidGV4dC14bFwiPnVwbG9hZF9maWxlPC9tYXQtaWNvbj5cbiAgICAgICAgICAgIHVwbG9hZFxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGRpdiAqbmdJZj1cIiFlZGl0TW9kZVwiIGNsYXNzPVwiZGl2aWRlclwiPjwvZGl2PlxuXG4gICAgICAgIDxidXR0b24gKm5nSWY9XCJlZGl0TW9kZVwiIChjbGljayk9XCJjYW5jZWxDaGFuZ2VzKClcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwiZGlzYWJsZWQ6b3BhY2l0eS01MCB3LTIwIGZsZXggZmxleC1jb2wgaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyIHB5LTEgcHgtMiB0ZXh0LXhzIHRleHQtZ3JheS02MDAgY3Vyc29yLXBvaW50ZXIgaG92ZXI6YmctZ3JheS0xMDBcIj5cbiAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cInRleHQteGxcIj5jYW5jZWw8L21hdC1pY29uPlxuICAgICAgICAgICAgY2FuY2VsIGVkaXRcbiAgICAgICAgPC9idXR0b24+XG5cbiAgICAgICAgPGJ1dHRvbiAoY2xpY2spPVwic2F2ZSgpXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cImRpc2FibGVkOm9wYWNpdHktNTAgdy0yMCBmbGV4IGZsZXgtY29sIGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciBweS0xIHB4LTIgdGV4dC14cyB0ZXh0LWdyYXktNjAwIGN1cnNvci1wb2ludGVyIGhvdmVyOmJnLWdyYXktMTAwXCI+XG4gICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJ0ZXh0LXhsXCI+c2F2ZTwvbWF0LWljb24+XG4gICAgICAgICAgICBzYXZlXG4gICAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuPC9kaXY+XG48ZGl2ICpuZ0lmPVwic2hvd0ZpbHRlcnNcIiBjbGFzcz1cImRhdGFzZXQtZmlsdGVyc1wiPlxuICAgIDxkaXYgY2xhc3M9XCJkYXRhc2V0LWZpbHRlciBib3JkZXItYiBib3JkZXItZ3JheS0yMDBcIj5cblxuICAgICAgICA8a2ktZGF0YXNldC1maWx0ZXJzICpuZ0lmPVwiY29sdW1ucy5sZW5ndGhcIiBbZmlsdGVyRmllbGRzXT1cImZpbHRlckZpZWxkc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW29wZW5TaWRlXT1cIm9wZW5TaWRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZmlsdGVySnVuY3Rpb25dPVwiZmlsdGVySnVuY3Rpb25cIj48L2tpLWRhdGFzZXQtZmlsdGVycz5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgYXBwbHktZmlsdGVyXCI+XG4gICAgICAgICAgICA8YnV0dG9uIG1hdC1zdHJva2VkLWJ1dHRvbiBjbGFzcz1cIm1yLTIgYmctd2hpdGVcIiBjb2xvcj1cIndhcm5cIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiY2xlYXJGaWx0ZXIoKVwiPlxuICAgICAgICAgICAgICAgIENsZWFyIEZpbHRlclxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8YnV0dG9uIG1hdC1mbGF0LWJ1dHRvbiBjbGFzcz1cIm1yLTJcIiBjb2xvcj1cInByaW1hcnlcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYXBwbHlGaWx0ZXIoKVwiIFtkaXNhYmxlZF09XCIhZmlsdGVySnVuY3Rpb24uZmlsdGVycy5sZW5ndGhcIj5cbiAgICAgICAgICAgICAgICBBcHBseSBGaWx0ZXJcbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cblxuXG4gICAgPC9kaXY+XG48L2Rpdj5cbjxkaXYgY2xhc3M9XCJmbGV4IGNyZWF0ZS1kYXRhc291cmNlLWNvbnRhaW5lclwiPlxuICAgIDxkaXYgY2xhc3M9XCJmbGV4LTEgcmVsYXRpdmUgb3ZlcmZsb3cteS1zY3JvbGwgdGFibGUtc2Nyb2xsXCI+XG5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNyZWF0ZS1kYXRhc291cmNlXCI+XG4gICAgICAgICAgICA8ZGl2IGlkPVwidGFibGVXcmFwcGVyXCIgY2xhc3M9XCJmbGV4LTEgb3ZlcmZsb3cteS1zY3JvbGwgcmVsYXRpdmVcIj5cbiAgICAgICAgICAgICAgICA8dGFibGUgY2xhc3M9XCJkYXRhc291cmNlLXRhYmxlIHRhYmxlLWZpeGVkIHctZnVsbCBvdmVyZmxvdy1zY3JvbGxcIj5cbiAgICAgICAgICAgICAgICAgICAgPHRoZWFkPlxuICAgICAgICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGggY2xhc3M9XCJ3LTEwIHJlbGF0aXZlIGN1cnNvci1wb2ludGVyIGJnLWdyYXktMTAwIHAtMCBzdGlja3kgdGV4dC14c1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgWyhuZ01vZGVsKV09XCJzZWxlY3RBbGxcIiAobmdNb2RlbENoYW5nZSk9XCJ1cGRhdGVTZWxlY3RBbGwoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBuZ0ZvciBsZXQtY29sdW1uIFtuZ0Zvck9mXT1cImNvbHVtbnNcIiBsZXQtY29sSW5kZXg9aW5kZXg+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoIFtpZF09XCJjb2x1bW4udHlwZSArIGNvbEluZGV4XCIgKm5nSWY9XCJjb2x1bW4udHlwZSA9PT0gJ2lkJyA/IHNob3dBdXRvSW5jcmVtZW50IDogdHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwidy02NCByZWxhdGl2ZSBjdXJzb3ItcG9pbnRlciBiZy1ncmF5LTEwMCBwLTIgc3RpY2t5IHRleHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J2JnLWluZGlnby01MCc6IHNlbGVjdGVkSXRlbS5faW5kZXggPT09IGNvbEluZGV4LCAnYm9yZGVyLXItMCc6IChjb2xJbmRleCArIDEpID09PSBjb2x1bW5zLmxlbmd0aH1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInByLTggdy1mdWxsIGhlYWRlci10aXRsZVwiIChjbGljayk9XCJzZWxlY3RDb2x1bW4oY29sdW1uLCBjb2xJbmRleClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGNvbHVtbi50aXRsZSB9fSZuYnNwO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyAqbmdJZj1cImNvbHVtbi5rZXlGaWVsZCB8fCBjb2x1bW4udHlwZSA9PT0naWQnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMjAgMjBcIiBmaWxsPVwiY3VycmVudENvbG9yXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ3LTUgaC01IHRleHQteWVsbG93LTUwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGZpbGwtcnVsZT1cImV2ZW5vZGRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQ9XCJNOCA3YTUgNSAwIDExMy42MSA0LjgwNGwtMS45MDMgMS45MDNBMSAxIDAgMDE5IDE0SDh2MWExIDEgMCAwMS0xIDFINnYxYTEgMSAwIDAxLTEgMUgzYTEgMSAwIDAxLTEtMXYtMmExIDEgMCAwMS4yOTMtLjcwN0w4LjE5NiA4LjM5QTUuMDAyIDUuMDAyIDAgMDE4IDd6bTUtM2EuNzUuNzUgMCAwMDAgMS41QTEuNSAxLjUgMCAwMTE0LjUgNyAuNzUuNzUgMCAwMDE2IDdhMyAzIDAgMDAtMy0zelwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpcC1ydWxlPVwiZXZlbm9kZFwiLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtaWNvbi1idXR0b24gW21hdE1lbnVUcmlnZ2VyRm9yXT1cImhlYWRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJhYnNvbHV0ZSBoZWFkZXItYWN0aW9uc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPm1vcmVfdmVydDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LW1lbnUgI2hlYWRlcj1cIm1hdE1lbnVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gbWF0LW1lbnUtaXRlbSAoY2xpY2spPVwic29ydENvbHVtbihjb2x1bW4sICdhc2MnKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWJldHdlZW4gdy1mdWxsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNvcnQgQXNjZW5kaW5nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIGZpbGw9XCJub25lXCIgdmlld0JveD1cIjAgMCAyNCAyNFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlLXdpZHRoPVwiMS41XCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImgtNiB3LTZcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTMgNC41aDE0LjI1TTMgOWg5Ljc1TTMgMTMuNWg1LjI1bTUuMjUtLjc1TDE3LjI1IDltMCAwTDIxIDEyLjc1TTE3LjI1IDl2MTJcIi8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIG1hdC1tZW51LWl0ZW0gKGNsaWNrKT1cInNvcnRDb2x1bW4oY29sdW1uLCAnZGVzYycpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktYmV0d2VlbiB3LWZ1bGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU29ydCBEZXNjZW5kaW5nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIGZpbGw9XCJub25lXCIgdmlld0JveD1cIjAgMCAyNCAyNFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlLXdpZHRoPVwiMS41XCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImgtNiB3LTZcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTMgNC41aDE0LjI1TTMgOWg5Ljc1TTMgMTMuNWg5Ljc1bTQuNS00LjV2MTJtMCAwLTMuNzUtMy43NU0xNy4yNSAyMSAyMSAxNy4yNVwiLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJjb2x1bW4udHlwZSAhPT0gJ2lkJyAmJiBlZGl0Q29sdW1uc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gbWF0LW1lbnUtaXRlbSAoY2xpY2spPVwiYWRkQ29sdW1uKGNvbEluZGV4ID09PSAwID8gMCA6IGNvbEluZGV4IC0gMSlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5zZXJ0IGNvbHVtbiBiZWZvcmVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uICpuZ0lmPVwiZWRpdENvbHVtbnNcIiBtYXQtbWVudS1pdGVtIChjbGljayk9XCJhZGRDb2x1bW4oY29sSW5kZXggKyAxKVwiPkluc2VydCBjb2x1bW4gYWZ0ZXI8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gKm5nSWY9XCJlZGl0Q29sdW1uc1wiIG1hdC1tZW51LWl0ZW0gKGNsaWNrKT1cImRlbGV0ZUNvbHVtbihjb2xJbmRleClcIj5EZWxldGUgY29sdW1uPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LW1lbnU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgICAgIDwvdGhlYWQ+XG4gICAgICAgICAgICAgICAgICAgIDx0Ym9keT5cbiAgICAgICAgICAgICAgICAgICAgPHRyIGNsYXNzPVwidGFibGUtcm93c1wiIFtuZ0NsYXNzXT1cInsnYmctZ3JheS0yMDAgb3BhY2l0eS0zMCc6IHRoaXMuZGVsZXRlcy5pbmRleE9mKHJvd0luZGV4KSA+IC0xLFxuICAgICAgICAgICAgICAgICAgICAnYmctZ3JlZW4tNTAnOiB0aGlzLmFkZHMuaW5kZXhPZihyb3dJbmRleCkgPiAtMSwgJ2JnLWluZGlnby0xMDAnOiB0aGlzLnVwZGF0ZXMuaW5kZXhPZihyb3dJbmRleCkgPiAtMX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IHJvdyBvZiByb3dzOyBsZXQgcm93SW5kZXggPSBpbmRleFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwicC0wIHJvdy1jZWxsIHRleHQtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBbKG5nTW9kZWwpXT1cInJvdy5fc2VsZWN0ZWRcIiAobmdNb2RlbENoYW5nZSk9XCJ1cGRhdGVTZWxlY3RlZCgpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIG5nRm9yIGxldC1yb3dDb2x1bW4gW25nRm9yT2ZdPVwiY29sdW1uc1wiIGxldC1yb3dDb2xJbmRleD1pbmRleD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgKm5nSWY9XCJyb3dDb2x1bW4udHlwZSA9PT0gJ2lkJyA/IHNob3dBdXRvSW5jcmVtZW50IDogdHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnYmctaW5kaWdvLTUwJzogc2VsZWN0ZWRJdGVtLl9pbmRleCA9PT0gcm93Q29sSW5kZXgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3ctMjQgYmctZ3JheS0xMDAnOiBjb2x1bW5zW3Jvd0NvbEluZGV4XS50eXBlID09PSAnaWQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdiZy1ncmF5LTEwMCc6IGNvbHVtbnNbcm93Q29sSW5kZXhdLmtleUZpZWxkICYmIHRoaXMuYWRkcy5pbmRleE9mKHJvd0luZGV4KSA9PT0gLTF9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJwLTAgcm93LWNlbGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJweS0xIHB4LTIgaC1mdWxsIHctZnVsbCBib3JkZXIgYm9yZGVyLXRyYW5zcGFyZW50IGlucHV0LXdyYXBwZXIgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1iZXR3ZWVuIHJlbGF0aXZlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJwLTAgYm9yZGVyLW5vbmUgdy1mdWxsIGJnLXRyYW5zcGFyZW50IHByLTEwIGNlbGwtaW5wdXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0eXBlXT1cImlucHV0VHlwZUZvckZpZWxkKHJvd0NvbHVtbilcIiAjZmllbGQ9XCJuZ01vZGVsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInJvd1tyb3dDb2x1bW4ubmFtZV1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdGVwXT1cIjFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttYXhdPVwiY29sdW1uc1tyb3dDb2xJbmRleF0udHlwZUNvbmZpZyA/IGNvbHVtbnNbcm93Q29sSW5kZXhdLnR5cGVDb25maWcubWF4aW11bVZhbHVlIDogbnVsbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21pbl09XCJjb2x1bW5zW3Jvd0NvbEluZGV4XS50eXBlQ29uZmlnID8gY29sdW1uc1tyb3dDb2xJbmRleF0udHlwZUNvbmZpZy5taW5pbXVtVmFsdWUgOiBudWxsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbHVtbnNbcm93Q29sSW5kZXhdLnR5cGUgIT09ICdpZCcgJiYgY29sdW1uc1tyb3dDb2xJbmRleF0udHlwZSAhPT0gJ3BpY2tmcm9tc291cmNlJyAgJiYgY29sdW1uc1tyb3dDb2xJbmRleF0udHlwZSAhPT0gJ2Jvb2xlYW4nICYmICFjb2x1bW5zW3Jvd0NvbEluZGV4XS5rZXlGaWVsZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJ1cGRhdGVGaWVsZChyb3dDb2x1bW4sIHJvd0luZGV4LCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZm9jdXMpPVwiZm9jdXNDZWxsKCRldmVudCwgcm93SW5kZXgsIHJvd0NvbEluZGV4KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGtleXVwLmVudGVyKT1cImVudGVyQ2VsbChyb3dJbmRleCwgcm93Q29sSW5kZXgsICRldmVudClcIj5cblxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJwLTAgYm9yZGVyLW5vbmUgdy1mdWxsIGJnLXRyYW5zcGFyZW50IHByLTEwIGNlbGwtaW5wdXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJjaGVja2JveFwiICNmaWVsZD1cIm5nTW9kZWxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwicm93W3Jvd0NvbHVtbi5uYW1lXVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0ZXBdPVwiMVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb2x1bW5zW3Jvd0NvbEluZGV4XS50eXBlID09PSAnYm9vbGVhbicgJiYgIWNvbHVtbnNbcm93Q29sSW5kZXhdLmtleUZpZWxkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cInVwZGF0ZUZpZWxkKHJvd0NvbHVtbiwgcm93SW5kZXgsICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmb2N1cyk9XCJmb2N1c0NlbGwoJGV2ZW50LCByb3dJbmRleCwgcm93Q29sSW5kZXgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoa2V5dXAuZW50ZXIpPVwiZW50ZXJDZWxsKHJvd0luZGV4LCByb3dDb2xJbmRleCwgJGV2ZW50KVwiPlxuXG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbHVtbnNbcm93Q29sSW5kZXhdLnR5cGUgPT0gJ3BpY2tmcm9tc291cmNlJyAmJiBjb2x1bW5QaWNrRnJvbURhdGFzZXRzW3Jvd0NvbHVtbi5uYW1lXVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ3LWZ1bGwgcHItMTBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwicC0wIGJvcmRlci1ub25lIHctZnVsbCBiZy10cmFuc3BhcmVudCBjZWxsLWlucHV0IG91dGxpbmUtbm9uZSByaW5nLTBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjZmllbGQ9XCJuZ01vZGVsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJyb3dbcm93Q29sdW1uLm5hbWVdXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJ1cGRhdGVGaWVsZChmaWVsZCwgcm93SW5kZXgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZvY3VzKT1cImZvY3VzQ2VsbCgkZXZlbnQsIHJvd0luZGV4LCByb3dDb2xJbmRleClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoa2V5dXAuZW50ZXIpPVwiZW50ZXJDZWxsKHJvd0luZGV4LCByb3dDb2xJbmRleCwgJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgcGlja0Zyb20gb2YgY29sdW1uUGlja0Zyb21EYXRhc2V0c1tyb3dDb2x1bW4ubmFtZV0uYWxsRGF0YVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdmFsdWVdPVwicGlja0Zyb21bcm93Q29sdW1uLnR5cGVDb25maWcudmFsdWVGaWVsZE5hbWVdXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e3BpY2tGcm9tW3Jvd0NvbHVtbi50eXBlQ29uZmlnLmxhYmVsRmllbGROYW1lXX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImNvbHVtbnNbcm93Q29sSW5kZXhdLnR5cGUgPT09ICdpZCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwidGV4dC1ncmF5LTUwMCB0ZXh0LXhzXCI+e3sgcm93W3Jvd0NvbHVtbi5uYW1lXSB8fCAnPFxcZ2VuZXJhdGVkXFw+JyB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImNvbHVtbnNbcm93Q29sSW5kZXhdLmtleUZpZWxkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cInRoaXMuYWRkcy5pbmRleE9mKHJvd0luZGV4KSA+IC0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cInAtMCBib3JkZXItbm9uZSB3LWZ1bGwgYmctdHJhbnNwYXJlbnQgcHItNSBjZWxsLWlucHV0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCIgI2ZpZWxkPVwibmdNb2RlbFwiIFsobmdNb2RlbCldPVwicm93W3Jvd0NvbHVtbi5uYW1lXVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cInVwZGF0ZUZpZWxkKGZpZWxkLCByb3dJbmRleClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZvY3VzKT1cImZvY3VzQ2VsbCgkZXZlbnQsIHJvd0luZGV4LCByb3dDb2xJbmRleClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGtleXVwLmVudGVyKT1cImVudGVyQ2VsbChyb3dJbmRleCwgcm93Q29sSW5kZXgsICRldmVudClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJ0aGlzLmFkZHMuaW5kZXhPZihyb3dJbmRleCkgPT09IC0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LWdyYXktNTAwIHRleHQteHNcIj57eyByb3dbcm93Q29sdW1uLm5hbWVdIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImFic29sdXRlIG1hdGVyaWFsLXN5bWJvbHMtb3V0bGluZWQgcmlnaHQtMCB3LTEwIHRleHQtb3JhbmdlLTUwMCB0ZXh0LWxnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImludmFsaWRJdGVtc1tyb3dJbmRleF0gJiYgaW52YWxpZEl0ZW1zW3Jvd0luZGV4XVtyb3dDb2x1bW4ubmFtZV1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttYXRUb29sdGlwXT1cImludmFsaWRJdGVtc1tyb3dJbmRleF1bcm93Q29sdW1uLm5hbWVdXCI+d2FybmluZzwvc3Bhbj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtaWNvbi1idXR0b24gW21hdE1lbnVUcmlnZ2VyRm9yXT1cIm1lbnVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImFic29sdXRlIGNlbGwtYWN0aW9uc1wiIHRhYmluZGV4PVwiLTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24+bW9yZV92ZXJ0PC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1tZW51ICNtZW51PVwibWF0TWVudVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gbWF0LW1lbnUtaXRlbSAoY2xpY2spPVwiYWRkUm93KHJvd0luZGV4ICsgMSlcIj5BZGQgcm93PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtbWVudS1pdGVtIChjbGljayk9XCJkZWxldGVSb3cocm93SW5kZXgpXCI+RGVsZXRlIHJvdzwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gKm5nSWY9XCJjb2x1bW5zW3Jvd0NvbEluZGV4XS50eXBlICE9PSAnaWQnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdC1tZW51LWl0ZW0gKGNsaWNrKT1cImNsZWFyQ2VsbChyb3dJbmRleCwgcm93Q29sSW5kZXgpXCI+Q2xlYXIgY2VsbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtbWVudT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgICAgICA8L3Rib2R5PlxuICAgICAgICAgICAgICAgIDwvdGFibGU+XG4gICAgICAgICAgICAgICAgPGRpdiAoY2xpY2spPVwiYWRkUm93KClcIiB0aXRsZT1cIkFkZCBSb3dcIlxuICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjdXJzb3ItcG9pbnRlciBmbGV4IGl0ZW1zLWNlbnRlciB0ZXh0LXNtIG0tMiBwLTEgYmctZ3JheS0xMDAgcm91bmRlZC1tZFwiPlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwibWwtMlwiIG1hdC1pY29uLWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5hZGRfY2lyY2xlPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIEFkZCBuZXcgcm93XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYm9yZGVyLXQgYmctZ3JheS01MCBweS0yIGZsZXggYWxpZ24tY2VudGVyIGp1c3RpZnktYmV0d2VlblwiPlxuICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJtbC0yXCIgbWF0LWljb24tYnV0dG9uIGNvbG9yPVwicHJpbWFyeVwiIHRpdGxlPVwiQWRkIFJvd1wiIChjbGljayk9XCJhZGRSb3coKVwiPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24+YWRkX2NpcmNsZTwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cIiFlZGl0TW9kZVwiIGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQteHMgdGV4dC1ncmF5LTQwMCBtci0xMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgU2hvd2luZyB7e29mZnNldCArIDF9fVxuICAgICAgICAgICAgICAgICAgICAgICAgLSB7eyhwYWdlICogbGltaXQpIC0gKGxpbWl0IC0gcm93cy5sZW5ndGgpfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBbdmFsdWVdPVwibGltaXRcIiAoY2hhbmdlKT1cInBhZ2VTaXplQ2hhbmdlKCRldmVudC50YXJnZXQudmFsdWUpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1yLTggcC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCIxMFwiPjEwPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCIyNVwiPjI1PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCI1MFwiPjUwPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCIxMDBcIj4xMDA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cIjI1MFwiPjI1MDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwiMTAwMFwiPjEwMDA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gbWF0LWljb24tYnV0dG9uIGNsYXNzPVwibXItNFwiIChjbGljayk9XCJkZWNyZWFzZU9mZnNldCgpXCIgW2Rpc2FibGVkXT1cInBhZ2UgPD0gMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPmNoZXZyb25fbGVmdDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiAoY2xpY2spPVwiaW5jcmVhc2VPZmZzZXQoKVwiIFtkaXNhYmxlZF09XCJlbmRPZlJlc3VsdHNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5jaGV2cm9uX3JpZ2h0PC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiYm9yZGVyLWwgYm9yZGVyLXIgYmctZ3JheS01MCAtbWwtMi41XCI+XG4gICAgICAgIDxidXR0b24gbWF0LWljb24tYnV0dG9uIGNvbG9yPVwicHJpbWFyeVwiIHRpdGxlPVwiQWRkIENvbHVtblwiIChjbGljayk9XCJhZGRDb2x1bW4oKVwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCItbXQtMC41XCI+XG4gICAgICAgICAgICA8bWF0LWljb24+YWRkX2NpcmNsZTwvbWF0LWljb24+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiAqbmdJZj1cIk9iamVjdC5rZXlzKHNlbGVjdGVkSXRlbSkubGVuZ3RoXCIgY2xhc3M9XCJiZy1ncmF5LTEwMCB3LTcyIGgtZnVsbCBwLTMgZmxleCBqdXN0aWZ5LWJldHdlZW4gZmxleC1jb2xcIj5cbiAgICAgICAgPGRpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ1cHBlcmNhc2UgZm9udC1tZWRpdW0gdHJhY2tpbmctd2lkZXIgbWItNCB0ZXh0LXhzIHRleHQtZ3JheS02MDBcIj5cbiAgICAgICAgICAgICAgICBTZXR0aW5nc1xuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDxociBjbGFzcz1cIm15LTRcIj5cblxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cInNlbGVjdGVkSXRlbS5fdGFibGVUeXBlXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInVwcGVyY2FzZSBmb250LW1lZGl1bSB0cmFja2luZy13aWRlciBtYi00IHRleHQteHMgdGV4dC1ncmF5LTYwMFwiPlxuICAgICAgICAgICAgICAgICAgICBDb2x1bW5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8bGFiZWwgKm5nSWY9XCJkYXRhc291cmNlVXBkYXRlLmluc3RhbmNlSW1wb3J0S2V5XCIgY2xhc3M9XCJtYi00XCI+XG4gICAgICAgICAgICAgICAgICAgIENvbHVtbiBLZXlcbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgWyhuZ01vZGVsKV09XCJzZWxlY3RlZEl0ZW0ubmFtZVwiIGRpc2FibGVkPlxuICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwibWItNFwiPlxuICAgICAgICAgICAgICAgICAgICBDb2x1bW4gVGl0bGVcbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgWyhuZ01vZGVsKV09XCJzZWxlY3RlZEl0ZW0udGl0bGVcIiBwbGFjZWhvbGRlcj1cIkVudGVyIGNvbHVtbiB0aXRsZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cInVwZGF0ZUNvbHVtbk5hbWUoKVwiPlxuICAgICAgICAgICAgICAgIDwvbGFiZWw+XG5cbiAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwic2VsZWN0ZWRJdGVtLnR5cGUgPT09ICdpZCdcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwibWItNFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgQ29sdW1uIFR5cGVcbiAgICAgICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgWyhuZ01vZGVsKV09XCJzZWxlY3RlZEl0ZW0udHlwZVwiIGRpc2FibGVkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cIidpZCdcIj5JRDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJzZWxlY3RlZEl0ZW0udHlwZSAhPT0gJ2lkJ1wiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJtYi00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBDb2x1bW4gVHlwZVxuICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBbKG5nTW9kZWwpXT1cInNlbGVjdGVkSXRlbS50eXBlXCIgKG5nTW9kZWxDaGFuZ2UpPVwic2V0VHlwZUNvbmZpZygpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwibnVsbFwiPi0tIFNlbGVjdCBjb2x1bW4gdHlwZSAtLTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IHR5cGUgb2YgT2JqZWN0LmtleXMoZGF0YXNvdXJjZVR5cGVzKVwiIFt2YWx1ZV09XCJ0eXBlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGRhdGFzb3VyY2VUeXBlc1t0eXBlXSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBnYXAtMlwiXG4gICAgICAgICAgICAgICAgICAgICAqbmdJZj1cInNlbGVjdGVkSXRlbS50eXBlQ29uZmlnICYmIHNlbGVjdGVkSXRlbS50eXBlID09ICdpbnRlZ2VyJyB8fCBzZWxlY3RlZEl0ZW0udHlwZSA9PSAnZmxvYXQnXCI+XG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cIm1iLTQgdy0zMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgTWluaW11bSBWYWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBjbGFzcz1cInB5LTEgcHgtMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJzZWxlY3RlZEl0ZW0udHlwZUNvbmZpZy5taW5pbXVtVmFsdWVcIiBwbGFjZWhvbGRlcj1cIkVudGVyIHZhbHVlXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cblxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJtYi00IHctMzJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIE1heGltdW0gVmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCIgY2xhc3M9XCJweS0xIHB4LTJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwic2VsZWN0ZWRJdGVtLnR5cGVDb25maWcubWF4aW11bVZhbHVlXCIgcGxhY2Vob2xkZXI9XCJFbnRlciB2YWx1ZVwiIC8+XG4gICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwic2VsZWN0ZWRJdGVtLnR5cGUgPT0gJ3BpY2tmcm9tc291cmNlJ1wiIGNsYXNzPVwibWItNFwiPlxuXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJzZWxlY3RlZEl0ZW0udHlwZUNvbmZpZyAmJiBjb2x1bW5QaWNrRnJvbURhdGFzZXRzW3NlbGVjdGVkSXRlbS5uYW1lXVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJtYi00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBEYXRhc291cmNlOiA8c3BhblxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0ZXh0LWdyYXktNTAwXCI+e3sgY29sdW1uUGlja0Zyb21EYXRhc2V0c1tzZWxlY3RlZEl0ZW0ubmFtZV0uaW5zdGFuY2VUaXRsZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtZmxhdC1idXR0b24gY29sb3I9XCJwcmltYXJ5XCIgKGNsaWNrKT1cInNlbGVjdENvbHVtblBpY2tGcm9tRGF0YXNvdXJjZShzZWxlY3RlZEl0ZW0pXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBTZWxlY3QgRGF0YXNvdXJjZVxuICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cblxuICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwic2VsZWN0ZWRJdGVtLnR5cGVDb25maWcgJiYgY29sdW1uUGlja0Zyb21EYXRhc2V0c1tzZWxlY3RlZEl0ZW0ubmFtZV1cIiBjbGFzcz1cIm10LTRcIj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiYmxvY2sgdGV4dC1zbSBmb250LW1lZGl1bSB0ZXh0LWdyYXktNzAwIHNtOm10LXB4IHNtOnB0LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMYWJlbCBjb2x1bW5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXQtMSBzbTpjb2wtc3Bhbi0yIHNtOm10LTBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IFsobmdNb2RlbCldPVwic2VsZWN0ZWRJdGVtLnR5cGVDb25maWcubGFiZWxGaWVsZE5hbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJibG9jayB3LWZ1bGwgbWF4LXctbGcgcm91bmRlZC1tZCBib3JkZXItZ3JheS0zMDAgc2hhZG93LXNtIGZvY3VzOmJvcmRlci1pbmRpZ28tNTAwIGZvY3VzOnJpbmctaW5kaWdvLTUwMCBzbTptYXgtdy14cyBzbTp0ZXh0LXNtIHB5LTEgcHgtMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgY29sdW1uUGlja0Zyb21EYXRhc2V0c1tzZWxlY3RlZEl0ZW0ubmFtZV0uY29sdW1uc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cImNvbHVtbi5uYW1lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2NvbHVtbi50aXRsZX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImJsb2NrIHRleHQtc20gZm9udC1tZWRpdW0gdGV4dC1ncmF5LTcwMCBzbTptdC1weCBzbTpwdC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUgY29sdW1uXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm10LTEgc206Y29sLXNwYW4tMiBzbTptdC0wXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBbKG5nTW9kZWwpXT1cInNlbGVjdGVkSXRlbS50eXBlQ29uZmlnLnZhbHVlRmllbGROYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYmxvY2sgdy1mdWxsIG1heC13LWxnIHJvdW5kZWQtbWQgYm9yZGVyLWdyYXktMzAwIHNoYWRvdy1zbSBmb2N1czpib3JkZXItaW5kaWdvLTUwMCBmb2N1czpyaW5nLWluZGlnby01MDAgc206bWF4LXcteHMgc206dGV4dC1zbSBweS0xIHB4LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIGNvbHVtblBpY2tGcm9tRGF0YXNldHNbc2VsZWN0ZWRJdGVtLm5hbWVdLmNvbHVtbnNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJjb2x1bW4ubmFtZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tjb2x1bW4udGl0bGV9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuXG4gICAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1jaGVja2JveCBjbGFzcz1cIm1iLTRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwic2VsZWN0ZWRJdGVtLnJlcXVpcmVkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBSZXF1aXJlZFxuICAgICAgICAgICAgICAgICAgICA8L21hdC1jaGVja2JveD5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggY2xhc3M9XCJtYi00XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInNlbGVjdGVkSXRlbS52YWx1ZUV4cHJlc3Npb25Pbk51bGxPbmx5XCIgKGNoYW5nZSk9XCIhKCRldmVudC5jaGVja2VkKSA/IHNlbGVjdGVkSXRlbS52YWx1ZUV4cHJlc3Npb24gPSAnJyA6IG51bGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIEhhcyBEZWZhdWx0IFZhbHVlXG4gICAgICAgICAgICAgICAgICAgIDwvbWF0LWNoZWNrYm94PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPGxhYmVsICpuZ0lmPVwic2VsZWN0ZWRJdGVtLnZhbHVlRXhwcmVzc2lvbk9uTnVsbE9ubHlcIiBjbGFzcz1cIm1iLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgRGVmYXVsdCBWYWx1ZVxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBbKG5nTW9kZWwpXT1cInNlbGVjdGVkSXRlbS52YWx1ZUV4cHJlc3Npb25cIiBwbGFjZWhvbGRlcj1cIkVudGVyIGRlZmF1bHQgdmFsdWVcIj5cbiAgICAgICAgICAgICAgICA8L2xhYmVsPlxuXG5cbiAgICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIG1hdC1idXR0b24gY29sb3I9XCJ3YXJuXCIgKGNsaWNrKT1cImRlbGV0ZVNlbGVjdGVkQ29sdW1uKClcIj5EZWxldGUgQ29sdW1uPC9idXR0b24+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8aHIgY2xhc3M9XCJteS00XCI+XG4gICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8YnV0dG9uIG1hdC1mbGF0LWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIiAoY2xpY2spPVwic2F2ZSh0cnVlKVwiPlxuICAgICAgICAgICAgU2F2ZSAmIEV4aXRcbiAgICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG48L2Rpdj5cblxuXG4iXX0=
|