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
package/esm2020/lib/components/datasource/document-datasource/document-datasource.component.mjs
DELETED
|
@@ -1,297 +0,0 @@
|
|
|
1
|
-
import { Component, Input } from '@angular/core';
|
|
2
|
-
import { BehaviorSubject } from 'rxjs';
|
|
3
|
-
import { debounceTime, map, switchMap } from 'rxjs/operators';
|
|
4
|
-
import { DatasetEditorPopupComponent } from '../../dataset/dataset-editor/dataset-editor.component';
|
|
5
|
-
import * as lodash from 'lodash';
|
|
6
|
-
import * as i0 from "@angular/core";
|
|
7
|
-
import * as i1 from "@angular/router";
|
|
8
|
-
import * as i2 from "../../../services/datasource.service";
|
|
9
|
-
import * as i3 from "../../../services/dataset.service";
|
|
10
|
-
import * as i4 from "@angular/material/legacy-dialog";
|
|
11
|
-
import * as i5 from "@angular/common";
|
|
12
|
-
import * as i6 from "@angular/material/legacy-button";
|
|
13
|
-
import * as i7 from "@angular/material/icon";
|
|
14
|
-
import * as i8 from "@angular/material/legacy-input";
|
|
15
|
-
import * as i9 from "@angular/forms";
|
|
16
|
-
import * as i10 from "@angular/material/legacy-core";
|
|
17
|
-
import * as i11 from "@angular/material/legacy-checkbox";
|
|
18
|
-
import * as i12 from "@angular/material/legacy-autocomplete";
|
|
19
|
-
import * as i13 from "@angular/material/legacy-progress-bar";
|
|
20
|
-
const _ = lodash.default;
|
|
21
|
-
export class DocumentDatasourceComponent {
|
|
22
|
-
constructor(route, datasourceService, datasetService, dialog) {
|
|
23
|
-
this.route = route;
|
|
24
|
-
this.datasourceService = datasourceService;
|
|
25
|
-
this.datasetService = datasetService;
|
|
26
|
-
this.dialog = dialog;
|
|
27
|
-
this.searchText = new BehaviorSubject('');
|
|
28
|
-
this.searchParser = new BehaviorSubject('');
|
|
29
|
-
this.datasources = [];
|
|
30
|
-
this.documentParsers = [];
|
|
31
|
-
this.datasource = { config: { stopWords: [] } };
|
|
32
|
-
this.showSettings = true;
|
|
33
|
-
this.showUpload = false;
|
|
34
|
-
this.String = String;
|
|
35
|
-
this.files = null;
|
|
36
|
-
this._ = _;
|
|
37
|
-
this.builtInStopWords = {
|
|
38
|
-
builtIn: false
|
|
39
|
-
};
|
|
40
|
-
this.failedResults = [];
|
|
41
|
-
this.uploading = false;
|
|
42
|
-
this.page = 1;
|
|
43
|
-
this.endOfResults = false;
|
|
44
|
-
this.limit = 25;
|
|
45
|
-
this.offset = 0;
|
|
46
|
-
}
|
|
47
|
-
async ngOnInit() {
|
|
48
|
-
this.route.params.subscribe(async (param) => {
|
|
49
|
-
this.datasourceKey = param.key;
|
|
50
|
-
if (this.datasourceKey) {
|
|
51
|
-
this.showSettings = false;
|
|
52
|
-
this.datasource = await this.datasourceService.getDatasource(this.datasourceKey);
|
|
53
|
-
this.evaluateDatasource();
|
|
54
|
-
if (this.datasource.config.stopWords && this.datasource.config.stopWords.length) {
|
|
55
|
-
for (const stopWord of this.datasource.config.stopWords) {
|
|
56
|
-
if (stopWord.custom) {
|
|
57
|
-
stopWord.datasource = await this.datasourceService.getDatasource(stopWord.datasourceKey);
|
|
58
|
-
this.updateDatasource(stopWord, stopWord.datasource);
|
|
59
|
-
}
|
|
60
|
-
if (stopWord.builtIn) {
|
|
61
|
-
this.builtInStopWords = stopWord;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
this.searchText
|
|
68
|
-
.pipe(debounceTime(300),
|
|
69
|
-
// distinctUntilChanged(),
|
|
70
|
-
switchMap(() => this.getDatasources())).subscribe((datasources) => {
|
|
71
|
-
this.datasources = datasources;
|
|
72
|
-
});
|
|
73
|
-
this.searchParser
|
|
74
|
-
.pipe(debounceTime(300),
|
|
75
|
-
// distinctUntilChanged(),
|
|
76
|
-
switchMap(() => this.getDocumentParsers())).subscribe((parsers) => {
|
|
77
|
-
this.documentParsers = parsers;
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
increaseOffset() {
|
|
81
|
-
this.page = this.page + 1;
|
|
82
|
-
this.offset = (this.limit * this.page) - this.limit;
|
|
83
|
-
this.evaluateDatasource();
|
|
84
|
-
}
|
|
85
|
-
decreaseOffset() {
|
|
86
|
-
this.page = this.page <= 1 ? 1 : this.page - 1;
|
|
87
|
-
this.offset = (this.limit * this.page) - this.limit;
|
|
88
|
-
this.evaluateDatasource();
|
|
89
|
-
}
|
|
90
|
-
pageSizeChange(value) {
|
|
91
|
-
this.limit = value;
|
|
92
|
-
this.evaluateDatasource(true);
|
|
93
|
-
}
|
|
94
|
-
viewFullItemData(data, columnName) {
|
|
95
|
-
this.dialog.open(DatasetEditorPopupComponent, {
|
|
96
|
-
width: '800px',
|
|
97
|
-
height: '400px',
|
|
98
|
-
data: {
|
|
99
|
-
fullData: data,
|
|
100
|
-
columnName
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
indexDocumentChange(change) {
|
|
105
|
-
if (change) {
|
|
106
|
-
if (!this.datasource.config.minPhraseLength) {
|
|
107
|
-
this.datasource.config.minPhraseLength = 1;
|
|
108
|
-
}
|
|
109
|
-
if (!this.datasource.config.maxPhraseLength) {
|
|
110
|
-
this.datasource.config.maxPhraseLength = 1;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
chunkContentChange(change) {
|
|
115
|
-
if (change) {
|
|
116
|
-
if (!this.datasource.config.chunkContent) {
|
|
117
|
-
this.datasource.config.indexChunksByAI = false;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
updateBuiltInStopWordConfig(value) {
|
|
122
|
-
_.remove(this.datasource.config.stopWords, stopWord => {
|
|
123
|
-
return stopWord.builtIn !== undefined;
|
|
124
|
-
});
|
|
125
|
-
if (!this.datasource.config.stopWords) {
|
|
126
|
-
this.datasource.config.stopWords = [];
|
|
127
|
-
}
|
|
128
|
-
this.datasource.config.stopWords.push(this.builtInStopWords);
|
|
129
|
-
}
|
|
130
|
-
removeCustomStopWord(index) {
|
|
131
|
-
this.datasource.config.stopWords.splice(index, 1);
|
|
132
|
-
}
|
|
133
|
-
humanFileSize(size) {
|
|
134
|
-
const i = size === 0 ? 0 : Math.floor(Math.log(size) / Math.log(1024));
|
|
135
|
-
return Number((size / Math.pow(1024, i)).toFixed(2)) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i];
|
|
136
|
-
}
|
|
137
|
-
displayFn(dataset) {
|
|
138
|
-
return dataset && dataset.title ? dataset.title : '';
|
|
139
|
-
}
|
|
140
|
-
dragOverHandler(ev) {
|
|
141
|
-
// Prevent default behavior (Prevent file from being opened)
|
|
142
|
-
ev.preventDefault();
|
|
143
|
-
}
|
|
144
|
-
dropHandler(ev) {
|
|
145
|
-
// Prevent default behavior (Prevent file from being opened)
|
|
146
|
-
ev.preventDefault();
|
|
147
|
-
this.files = [];
|
|
148
|
-
if (ev.dataTransfer.items) {
|
|
149
|
-
// Use DataTransferItemList interface to access the file(s)
|
|
150
|
-
for (let i = 0; i < ev.dataTransfer.items.length; i++) {
|
|
151
|
-
// If dropped items aren't files, reject them
|
|
152
|
-
if (ev.dataTransfer.items[i].kind === 'file') {
|
|
153
|
-
const file = ev.dataTransfer.items[i].getAsFile();
|
|
154
|
-
this.files.push(file);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
else {
|
|
159
|
-
// Use DataTransfer interface to access the file(s)
|
|
160
|
-
for (let i = 0; i < ev.dataTransfer.files.length; i++) {
|
|
161
|
-
const file = ev.dataTransfer.files[i];
|
|
162
|
-
this.files.push(file);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
fileUpload(event) {
|
|
167
|
-
this.files = Array.from(event.target.files);
|
|
168
|
-
}
|
|
169
|
-
removeFile(index) {
|
|
170
|
-
this.files.splice(index, 1);
|
|
171
|
-
}
|
|
172
|
-
downloadDoc(url) {
|
|
173
|
-
window.open(url);
|
|
174
|
-
}
|
|
175
|
-
async uploadFiles() {
|
|
176
|
-
const formData = new FormData();
|
|
177
|
-
for (const file of this.files) {
|
|
178
|
-
formData.append(file.name, file);
|
|
179
|
-
}
|
|
180
|
-
await this.uploadDatasourceDocuments(formData);
|
|
181
|
-
this.evaluateDatasource();
|
|
182
|
-
}
|
|
183
|
-
async updateDatasource(stopWord, datasource) {
|
|
184
|
-
stopWord.datasourceKey = datasource.key;
|
|
185
|
-
stopWord.datasource = datasource;
|
|
186
|
-
const datasetInstanceSummary = {
|
|
187
|
-
datasetInstanceId: null,
|
|
188
|
-
datasourceInstanceKey: datasource.key,
|
|
189
|
-
transformationInstances: [],
|
|
190
|
-
parameterValues: {},
|
|
191
|
-
parameters: [],
|
|
192
|
-
originDataItemTitle: datasource.title
|
|
193
|
-
};
|
|
194
|
-
stopWord.selectedDatasource = await this.datasetService.evaluateDataset(datasetInstanceSummary, '0', '1');
|
|
195
|
-
}
|
|
196
|
-
updateCustomParser(value) {
|
|
197
|
-
this.datasource.config.customDocumentParser = value;
|
|
198
|
-
}
|
|
199
|
-
async save() {
|
|
200
|
-
if (!this.datasourceKey) {
|
|
201
|
-
this.datasourceKey = await this.datasourceService.createDocumentDatasource(this.datasource);
|
|
202
|
-
if (this.files && this.files.length) {
|
|
203
|
-
await this.uploadFiles();
|
|
204
|
-
this.evaluateDatasource();
|
|
205
|
-
}
|
|
206
|
-
window.location.href = window.location.href + '/' + this.datasourceKey;
|
|
207
|
-
}
|
|
208
|
-
else {
|
|
209
|
-
await this.datasourceService.updateDatasourceInstance(this.datasourceKey, this.datasource);
|
|
210
|
-
this.evaluateDatasource();
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
getDatasources() {
|
|
214
|
-
return this.datasourceService.getDatasources(this.searchText.getValue() || '', '10', '0').pipe(map((datasources) => {
|
|
215
|
-
return datasources;
|
|
216
|
-
}));
|
|
217
|
-
}
|
|
218
|
-
getDocumentParsers() {
|
|
219
|
-
return this.datasourceService.getDatasources(this.searchText.getValue() || '', '10', '0').pipe(map((datasources) => {
|
|
220
|
-
return [
|
|
221
|
-
{
|
|
222
|
-
title: 'Plenipot Bucharest 22',
|
|
223
|
-
value: 'plenipotBucharest22'
|
|
224
|
-
},
|
|
225
|
-
{
|
|
226
|
-
title: 'ITU Study Group',
|
|
227
|
-
value: 'itustudygroup'
|
|
228
|
-
},
|
|
229
|
-
{
|
|
230
|
-
title: 'IETF Internet Drafts',
|
|
231
|
-
value: 'ietfinternetdrafts'
|
|
232
|
-
},
|
|
233
|
-
{
|
|
234
|
-
title: 'WTSA',
|
|
235
|
-
value: 'wtsa'
|
|
236
|
-
},
|
|
237
|
-
{
|
|
238
|
-
title: 'WTDC',
|
|
239
|
-
value: 'wtdc'
|
|
240
|
-
}
|
|
241
|
-
];
|
|
242
|
-
}));
|
|
243
|
-
}
|
|
244
|
-
async uploadDatasourceDocuments(formData) {
|
|
245
|
-
this.uploading = true;
|
|
246
|
-
const trackingKey = Date.now() + (Math.random() + 1).toString(36).substr(2, 5);
|
|
247
|
-
this.datasourceService.uploadDatasourceDocuments(this.datasourceKey, formData, trackingKey).catch(err => {
|
|
248
|
-
// Ignore - we have set off a long-running task which we are tracking below
|
|
249
|
-
});
|
|
250
|
-
this.files = null;
|
|
251
|
-
return new Promise((resolve, reject) => {
|
|
252
|
-
setTimeout(() => {
|
|
253
|
-
const resultSub = this.datasourceService.getDataTrackingResults(trackingKey).subscribe((res) => {
|
|
254
|
-
this.uploadResults = res;
|
|
255
|
-
if (res && res.status === 'COMPLETED') {
|
|
256
|
-
this.uploading = false;
|
|
257
|
-
resultSub.unsubscribe();
|
|
258
|
-
this.failedResults = res.progressData.failed || [];
|
|
259
|
-
resolve(true);
|
|
260
|
-
setTimeout(() => {
|
|
261
|
-
this.uploadResults = null;
|
|
262
|
-
this.failedResults = [];
|
|
263
|
-
}, 5000);
|
|
264
|
-
}
|
|
265
|
-
});
|
|
266
|
-
}, 100);
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
async evaluateDatasource(resetPager = false) {
|
|
270
|
-
if (resetPager) {
|
|
271
|
-
this.offset = 0;
|
|
272
|
-
this.page = 1;
|
|
273
|
-
}
|
|
274
|
-
this.datasource.limit = this.limit;
|
|
275
|
-
this.datasource.offset = this.offset;
|
|
276
|
-
this.evaluatedDatasource = await this.datasourceService.evaluateDatasource(this.datasource);
|
|
277
|
-
this.evaluatedDatasource.allData.map(data => {
|
|
278
|
-
if (data.file_size) {
|
|
279
|
-
data.file_size = this.humanFileSize(data.file_size);
|
|
280
|
-
}
|
|
281
|
-
if (data.file_type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') {
|
|
282
|
-
data.file_type = 'application/docx';
|
|
283
|
-
}
|
|
284
|
-
return data;
|
|
285
|
-
});
|
|
286
|
-
this.endOfResults = this.evaluatedDatasource.allData.length < this.limit;
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
DocumentDatasourceComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DocumentDatasourceComponent, deps: [{ token: i1.ActivatedRoute }, { token: i2.DatasourceService }, { token: i3.DatasetService }, { token: i4.MatLegacyDialog }], target: i0.ɵɵFactoryTarget.Component });
|
|
290
|
-
DocumentDatasourceComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: DocumentDatasourceComponent, selector: "ki-document-datasource", inputs: { showCustomParser: "showCustomParser" }, ngImport: i0, template: "<div class=\"p-6 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-2xl font-bold text-gray-900\">\n {{!datasourceKey ? 'Document Datasource' : (datasource.title || 'Document Datasource')}}\n </h1>\n <p class=\"text-sm font-medium text-gray-500\">\n <ng-template [ngIf]=\"!datasourceKey\">\n Upload your documents using the form below.\n </ng-template>\n <ng-template [ngIf]=\"datasourceKey\">\n View your existing documents below and adjust any document settings here.\n </ng-template>\n </p>\n </div>\n </div>\n <div class=\"mt-6 flex flex-col-reverse justify-stretch\" *ngIf=\"datasourceKey\">\n <button type=\"button\" (click)=\"showUpload = !showUpload\"\n class=\"inline-flex items-center justify-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-primary focus:outline-none\">\n Upload Additional Documents\n </button>\n </div>\n </div>\n</div>\n\n<div class=\"bg-blue-50 p-4\" *ngIf=\"uploading\">\n <div class=\"flex\">\n <div class=\"flex-shrink-0\">\n <!-- Heroicon name: solid/information-circle -->\n <svg class=\"h-5 w-5 text-primary\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\"\n fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\"\n d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z\"\n clip-rule=\"evenodd\"/>\n </svg>\n </div>\n <div class=\"ml-3 w-full\">\n <p class=\"text-sm text-primary font-medium\">Progress</p>\n <ng-template [ngIf]=\"uploadResults && uploadResults.progressData\">\n <div class=\"text-primary my-2\">Uploaded {{uploadResults.progressData.completed}}\n /{{uploadResults.progressData.total}}</div>\n <mat-progress-bar class=\"w-full my-4\" mode=\"determinate\"\n [value]=\"(uploadResults.progressData.completed/uploadResults.progressData.total) * 100\"></mat-progress-bar>\n </ng-template>\n <ng-template [ngIf]=\"!uploadResults || !uploadResults.progressData\">\n <div class=\"text-primary my-2\">Preparing Upload...</div>\n <mat-progress-bar class=\"w-full my-4\" mode=\"buffer\"></mat-progress-bar>\n </ng-template>\n </div>\n </div>\n</div>\n\n<div class=\"bg-green-50 p-4\" *ngIf=\"!failedResults.length && uploadResults && !uploading\">\n <div class=\"flex\">\n <div class=\"flex-shrink-0\">\n <!-- Heroicon name: solid/check-circle -->\n <svg class=\"h-5 w-5 text-green-400\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\"\n fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\"\n d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z\"\n clip-rule=\"evenodd\"/>\n </svg>\n </div>\n <div class=\"ml-3\">\n <h3 class=\"text-sm font-medium text-green-800\">Upload completed</h3>\n <div class=\"mt-2 text-sm text-green-700\">\n <p><b>{{uploadResults.progressData.completed}}</b> files were processed successfully out of\n <b>{{uploadResults.progressData.total}}</b> uploaded items.</p>\n </div>\n </div>\n </div>\n</div>\n\n<div class=\"bg-red-50 p-4\" *ngIf=\"failedResults.length && uploadResults\">\n <div class=\"flex\">\n <div class=\"flex-shrink-0\">\n <!-- Heroicon name: solid/x-circle -->\n <svg class=\"h-5 w-5 text-red-400\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\"\n aria-hidden=\"true\">\n <path fill-rule=\"evenodd\"\n d=\"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z\"\n clip-rule=\"evenodd\"/>\n </svg>\n </div>\n <div class=\"ml-3\">\n <h3 class=\"text-sm font-medium text-red-800\">There were {{failedResults.length}} errors with your\n submission</h3>\n <div class=\"mt-2 text-sm text-red-700\">\n <ul role=\"list\" class=\"list-disc pl-5 space-y-1\">\n <li *ngFor=\"let failedResult of failedResults\">\n {{failedResult.message}}\n </li>\n </ul>\n </div>\n </div>\n </div>\n</div>\n\n<div *ngIf=\"showUpload\"\n class=\"space-y-8 p-6 bg-gray-50 border-b\">\n <div class=\"space-y-8 sm:space-y-5\">\n <div>\n <div class=\"space-y-6 sm:space-y-5\">\n <div class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start\">\n <label class=\"block text-sm font-medium text-gray-700\">\n Upload Documents\n <div class=\"text-xs font-normal text-gray-500\">\n Additional documents to be processed.\n </div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <div *ngIf=\"!files || !files.length\"\n (drop)=\"dropHandler($event)\" (dragover)=\"dragOverHandler($event)\"\n class=\"w-full flex justify-center px-6 pt-5 pb-6 border-2 border-gray-300 border-dashed rounded-md\">\n <div class=\"space-y-1 text-center\">\n <svg class=\"mx-auto h-12 w-12 text-gray-400\" stroke=\"currentColor\" fill=\"none\"\n viewBox=\"0 0 48 48\" aria-hidden=\"true\">\n <path\n d=\"M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02\"\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n <div class=\"flex text-sm text-gray-600\">\n <label\n class=\"relative cursor-pointer rounded-md font-medium text-secondary focus-within:outline-none\">\n <span>Select file(s) to upload</span>\n <input name=\"additionalUpload\" multiple type=\"file\" class=\"sr-only\"\n (change)=\"fileUpload($event)\">\n </label>\n <p class=\"pl-1 mb-0\">or drag and drop</p>\n </div>\n <p class=\"text-xs text-gray-500\">.docx, .txt, .pfd, .zip</p>\n </div>\n </div>\n <div *ngIf=\"files && files.length\"\n class=\"overflow-hidden shadow ring-1 ring-black ring-opacity-5 md:rounded-lg\">\n <table class=\"min-w-full divide-y divide-gray-300 block overflow-y-auto max-h-48\">\n <thead class=\"bg-gray-50\">\n <tr>\n <th scope=\"col\" colspan=\"2\"\n class=\"sticky top-0 z-10 bg-gray-100 py-2 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6\">\n Selected File Preview\n <span class=\"text-xs text-gray-500 lowercase ml-4 font-normal\">\n click <span class=\"font-medium\">'Upload Files'</span> to upload the selected files.</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"divide-y divide-gray-200 bg-white\">\n <tr *ngFor=\"let file of files; let i = index\">\n <td class=\"whitespace-nowrap py-2 pl-4 pr-3 text-xs font-medium text-gray-900 sm:pl-6\">\n {{file.name}}\n </td>\n <td class=\"relative whitespace-nowrap py-2 pl-3 pr-4 text-right text-sm font-medium sm:pr-6\">\n <a (click)=\"removeFile(i)\" class=\"text-danger\">Remove</a>\n </td>\n </tr>\n\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n </div>\n </div>\n\n </div>\n\n <div class=\"\">\n <div class=\"flex justify-end\">\n <button type=\"button\" (click)=\"showUpload = false;files = null\"\n class=\"bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none\">\n Cancel\n </button>\n\n <button type=\"submit\" [disabled]=\"!files\"\n class=\"disabled:opacity-50 ml-3 inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-secondary focus:outline-none\"\n (click)=\"uploadFiles()\">Upload Files\n </button>\n </div>\n </div>\n</div>\n\n<div class=\"transformation-listing py-2 bg-gray-50 cursor-pointer\"\n (click)=\"showSettings = !showSettings\" [ngClass]=\"{'border-b': !showSettings}\">\n <a class=\"list-title flex items-center\">\n Settings \n <mat-icon *ngIf=\"!showSettings\">expand_more</mat-icon>\n <mat-icon *ngIf=\"showSettings\">expand_less</mat-icon>\n </a>\n <div class=\"ml-6 text-xs text-gray-500\">\n Adjust the rules around how the uploaded documents will\n be processed.\n </div>\n</div>\n\n<div *ngIf=\"showSettings\" [ngClass]=\"{'border-b': showSettings}\"\n class=\"space-y-8 divide-y divide-gray-200 p-6 bg-gray-50\">\n <div class=\"space-y-8 divide-y divide-gray-200 sm:space-y-5\">\n <div>\n <div class=\"space-y-6 sm:space-y-5\">\n <div class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start\">\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Title\n <div class=\"text-xs font-normal text-gray-500\">Enter the name to identify this data source</div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <input type=\"text\" [(ngModel)]=\"datasource.title\"\n class=\"max-w-lg block w-full shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:max-w-xs sm:text-sm border-gray-300 rounded-md\">\n\n </div>\n </div>\n\n <div *ngIf=\"!datasourceKey\"\n class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5\">\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Upload Documents\n <div class=\"text-xs font-normal text-gray-500\">\n The documents to be processed.\n </div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <div *ngIf=\"!files || !files.length\"\n (drop)=\"dropHandler($event)\" (dragover)=\"dragOverHandler($event)\"\n class=\"w-full flex justify-center px-6 pt-5 pb-6 border-2 border-gray-300 border-dashed rounded-md\">\n <div class=\"space-y-1 text-center\">\n <svg class=\"mx-auto h-12 w-12 text-gray-400\" stroke=\"currentColor\" fill=\"none\"\n viewBox=\"0 0 48 48\" aria-hidden=\"true\">\n <path\n d=\"M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02\"\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n <div class=\"flex text-sm text-gray-600\">\n <label\n class=\"relative cursor-pointer rounded-md font-medium text-secondary focus-within:outline-none\">\n <span>Select file(s) to upload</span>\n <input name=\"additionalUpload\" multiple type=\"file\" class=\"sr-only\"\n (change)=\"fileUpload($event)\">\n </label>\n <p class=\"pl-1 mb-0\">or drag and drop</p>\n </div>\n <p class=\"text-xs text-gray-500\">.docx, .txt, .pfd, .zip</p>\n </div>\n </div>\n <div *ngIf=\"files\"\n class=\"overflow-hidden shadow ring-1 ring-black ring-opacity-5 md:rounded-lg\">\n <table class=\"min-w-full divide-y divide-gray-300 block overflow-y-auto max-h-48\">\n <thead class=\"bg-gray-50\">\n <tr>\n <th scope=\"col\" colspan=\"2\"\n class=\"sticky top-0 z-10 bg-gray-100 py-2 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6\">\n Selected File Preview\n <span class=\"text-xs text-gray-500 lowercase ml-4 font-normal\">\n click <span class=\"font-medium\">'Upload Files'</span> to upload the selected files.</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"divide-y divide-gray-200 bg-white\">\n <tr *ngFor=\"let file of files; let i = index\">\n <td class=\"whitespace-nowrap py-2 pl-4 pr-3 text-xs font-medium text-gray-900 sm:pl-6\">\n {{file.name}}\n </td>\n <td class=\"relative whitespace-nowrap py-2 pl-3 pr-4 text-right text-sm font-medium sm:pr-6\">\n <a (click)=\"removeFile(i)\" class=\"text-danger\">Remove</a>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n <ng-template [ngIf]=\"showCustomParser\">\n <div class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5\">\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Custom Document Parser\n <div class=\"text-xs font-normal text-gray-500\">\n Use a custom document parser to process the documents.\n </div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <label class=\"mb-4 text-sm\">\n Select Custom Document Parser\n <input type=\"text\" [matAutocomplete]=\"autoParsers\"\n [(ngModel)]=\"datasource.config.customDocumentParser\"\n (keyup)=\"searchParser.next($event.target.value)\"\n placeholder=\"Search for a custom parser\">\n <mat-autocomplete #autoParsers=\"matAutocomplete\">\n <mat-option *ngFor=\"let parser of documentParsers\" [value]=\"parser.value\">\n {{parser.title}}\n </mat-option>\n </mat-autocomplete>\n <small class=\"font-normal\">Start typing name to view available parsers</small>\n </label>\n </div>\n </div>\n </ng-template>\n\n <ng-template [ngIf]=\"!datasource.config.customDocumentParser\">\n\n\n <div class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5\">\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Indexing\n <div class=\"text-xs font-normal text-gray-500\">\n Set whether you want the content of the documents to be indexed\n </div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <mat-checkbox class=\"block mb-4\" [(ngModel)]=\"datasource.config.indexContent\"\n (ngModelChange)=\"indexDocumentChange($event)\">Index Document\n Content\n </mat-checkbox>\n <ng-template [ngIf]=\"datasource.config.indexContent\">\n <div class=\"max-w-lg flex rounded-md shadow-sm mb-2\">\n <span\n class=\"inline-flex items-center px-3 rounded-l-md border border-r-0 border-gray-300 bg-gray-50 text-gray-500 sm:text-sm\"> Min phrase length (words) </span>\n <input type=\"number\" name=\"minPhrase\" [min]=\"1\"\n [(ngModel)]=\"datasource.config.minPhraseLength\"\n class=\"flex-1 block w-full min-w-0 rounded-none rounded-r-md sm:text-sm border-gray-300\">\n </div>\n <div class=\"max-w-lg flex rounded-md shadow-sm\">\n <span\n class=\"inline-flex items-center px-3 rounded-l-md border border-r-0 border-gray-300 bg-gray-50 text-gray-500 sm:text-sm\"> Max phrase length (words) </span>\n <input type=\"number\" name=\"maxPhrase\" [min]=\"1\"\n [(ngModel)]=\"datasource.config.maxPhraseLength\"\n class=\"flex-1 block w-full min-w-0 rounded-none rounded-r-md sm:text-sm border-gray-300\">\n </div>\n </ng-template>\n </div>\n </div>\n\n <div class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5\">\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Chunking\n <div class=\"text-xs font-normal text-gray-500\">\n Set whether you want to split the documents into chunks for analysis\n </div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <mat-checkbox class=\"block mb-4\" [(ngModel)]=\"datasource.config.chunkContent\" (ngModelChange)=\"chunkContentChange($event)\"> Chunk Document Content\n </mat-checkbox>\n <ng-template [ngIf]=\"datasource.config.chunkContent\">\n <mat-checkbox class=\"block mb-4\" [(ngModel)]=\"datasource.config.indexChunksByAI\">Index Chunks by AI\n </mat-checkbox>\n </ng-template>\n </div>\n\n </div>\n\n <div *ngIf=\"datasource.config.indexContent\"\n class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5\">\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Stop Words\n <div class=\"text-xs font-normal text-gray-500\">\n A list of words to exclude from being indexed.\n </div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <mat-checkbox class=\"block mb-2\" [(ngModel)]=\"builtInStopWords.builtIn\"\n (ngModelChange)=\"updateBuiltInStopWordConfig($event)\">Use Built In\n </mat-checkbox>\n\n <ng-template [ngIf]=\"builtInStopWords.builtIn && datasource.config.maxPhraseLength > 1\">\n <label class=\"mb-4\">\n Min phrase length for including stop words\n <input type=\"number\" [min]=\"2\"\n [(ngModel)]=\"builtInStopWords.minPhraseLength\">\n <small class=\"font-normal\">The built it stop words will be included when the phrase\n length is greater than or equal to this value.</small>\n </label>\n </ng-template>\n\n <hr class=\"my-4\" *ngIf=\"_.filter(datasource.config.stopWords, 'custom').length\">\n\n <ng-template ngFor let-stopWord [ngForOf]=\"_.filter(datasource.config.stopWords, 'custom')\"\n let-i=index>\n <div class=\"flex items-center justify-between\">\n <div>\n <label class=\"mb-4 text-sm\">\n Datasource\n <input type=\"text\" [matAutocomplete]=\"autoDatasets\"\n [value]=\"stopWord.datasource ? stopWord.datasource.title : ''\"\n (keyup)=\"searchText.next($event.target.value)\"\n placeholder=\"Search for a datasource\">\n <mat-autocomplete #autoDatasets=\"matAutocomplete\" [displayWith]=\"displayFn\">\n <mat-option *ngFor=\"let datasource of datasources\" [value]=\"datasource\"\n (onSelectionChange)=\"updateDatasource(stopWord, $event.source.value)\">\n {{datasource.title}}\n </mat-option>\n </mat-autocomplete>\n <small class=\"font-normal\">Start typing name to view available\n datasources</small>\n </label>\n\n\n <div *ngIf=\"stopWord.selectedDatasource && stopWord.selectedDatasource.columns\">\n <label class=\"mb-4\">\n Stop Words Column\n <select matNativeControl [(ngModel)]=\"stopWord.datasourceColumn\">\n <option *ngFor=\"let column of stopWord.selectedDatasource.columns\"\n [ngValue]=\"column.name\">\n {{column.title}}\n </option>\n </select>\n <small class=\"font-normal\">Select the column to use for the stop\n words</small>\n </label>\n\n <label class=\"mb-4\" *ngIf=\"datasource.config.maxPhraseLength > 1\">\n Min phrase length for including stop words\n <input type=\"number\" [min]=\"2\"\n [(ngModel)]=\"stopWord.minPhraseLength\">\n <small\n class=\"font-normal\">The {{stopWord.datasource ? stopWord.datasource.title : ''}}\n stop words will be included when the\n phrase length is greater than or equal to this value.</small>\n </label>\n </div>\n </div>\n\n <button mat-icon-button color=\"warn\" (click)=\"removeCustomStopWord(i)\">\n <mat-icon>clear</mat-icon>\n </button>\n </div>\n\n <hr class=\"my-4\">\n </ng-template>\n\n <button mat-button color=\"primary\"\n (click)=\"datasource.config.stopWords.push({custom: true})\">\n <mat-icon>add</mat-icon>\n Add Custom Stop Words\n </button>\n\n </div>\n </div>\n\n </ng-template>\n\n <div class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5\">\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Storage Options\n <div class=\"text-xs font-normal text-gray-500\">\n Securely save an original copy of the document and/or its original text.\n </div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <mat-checkbox class=\"block mb-2\" [(ngModel)]=\"datasource.config.storeOriginal\">Store\n Original File\n </mat-checkbox>\n <mat-checkbox class=\"block mb-2\" [(ngModel)]=\"datasource.config.storeText\">Store Document\n Text\n </mat-checkbox>\n </div>\n </div>\n\n </div>\n </div>\n\n </div>\n\n <div class=\"pt-5\">\n <div class=\"flex justify-end\">\n <button type=\"button\"\n class=\"bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none\">\n Cancel\n </button>\n <button type=\"submit\" [disabled]=\"!datasource.title\"\n class=\"disabled:opacity-50 ml-3 inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-secondary focus:outline-none\"\n (click)=\"save()\">\n <ng-template [ngIf]=\"!datasourceKey\">\n Create Datasource\n </ng-template>\n <ng-template [ngIf]=\"datasourceKey\">\n Update Settings\n </ng-template>\n </button>\n </div>\n </div>\n</div>\n\n<ng-template [ngIf]=\"evaluatedDatasource\">\n\n\n <div class=\"overflow-scroll\">\n <table class=\"min-w-full border-separate bg-white\" style=\"border-spacing: 0\">\n <thead class=\"bg-gray-100\">\n <tr>\n <th *ngFor=\"let column of evaluatedDatasource.columns\" scope=\"col\"\n class=\"sticky top-0 z-10 border-b border-gray-300 bg-gray-50 bg-opacity-75 py-3.5 px-4 text-left text-xs font-semibold text-gray-900 backdrop-blur backdrop-filter\">\n {{column.title}}\n </th>\n </tr>\n </thead>\n <tbody class=\"bg-white\">\n <tr *ngFor=\"let data of evaluatedDatasource.allData\">\n <td *ngFor=\"let column of evaluatedDatasource.columns; let i = index\"\n [ngClass]=\"{'font-medium': i === 0}\"\n class=\"border-b border-gray-200 py-2 px-4 text-sm text-gray-900\">\n <ng-template [ngIf]=\"column.name === 'original_link'\">\n <a class=\"flex items-center text-cta hover:underline\" (click)=\"downloadDoc(data[column.name])\">\n {{data[column.name]}}\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"ml-1 h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke=\"currentColor\" stroke-width=\"2\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\n d=\"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4\"/>\n </svg>\n </a>\n </ng-template>\n <ng-template [ngIf]=\"column.name !== 'original_link'\">\n <ng-template [ngIf]=\"data[column.name] && String(data[column.name]).length <= 100\">\n {{data[column.name]}}\n </ng-template>\n <ng-template [ngIf]=\"data[column.name] && String(data[column.name]).length > 100\">\n <div>{{data[column.name].substring(0, 100) + '...'}}</div>\n <a (click)=\"viewFullItemData(data[column.name], column.name)\"\n class=\"flex items-center text-sm text-cta hover:underline\">\n view more\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"ml-1 h-4 w-4\" fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"\n d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"/>\n </svg>\n </a>\n </ng-template>\n <ng-template [ngIf]=\"!data[column.name]\">\n {{data[column.name]}}\n </ng-template>\n </ng-template>\n </td>\n </tr>\n </tbody>\n\n </table>\n\n </div>\n <div class=\"bg-white p-4 flex align-center justify-end\">\n <select [value]=\"limit\" (change)=\"pageSizeChange($event.target.value)\" class=\"mr-8\">\n <option [value]=\"1\">1</option>\n <option [value]=\"5\">5</option>\n <option [value]=\"10\">10</option>\n <option [value]=\"25\">25</option>\n <option [value]=\"50\">50</option>\n <option [value]=\"100\">100</option>\n <option [value]=\"250\">250</option>\n <option [value]=\"1000\">1000</option>\n </select>\n <button mat-icon-button 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\n</ng-template>\n", styles: [":host{display:block;background-color:#fff}.cell-header{width:100%;display:flex;align-items:center;justify-content:space-between}.cell-header.end{justify-content:flex-end}.transformation-listing{display:flex;align-items:center;flex-wrap:wrap;width:100%;border-bottom-color:#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}table{position:relative;border-collapse:collapse}table.sticky th{position:sticky;top:0;background-color:#f5f5f5;border-top:none!important;border-bottom:none!important;box-shadow:inset 0 -1px #ddd}table th.settings{padding:0}table td{max-width:400px;word-wrap:break-word;padding-top:.5rem;padding-bottom:.5rem;padding-right:1rem;min-width:100px;width:1%}table td.settings{max-width:25px;min-width:25px}table::-webkit-scrollbar{width:.75em;background:transparent}table::-webkit-scrollbar-thumb{background:#d2d2d2}\n"], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i6.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: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i8.MatLegacyInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", exportAs: ["matInput"] }, { kind: "directive", type: i9.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i9.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i9.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: i9.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i9.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i9.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i9.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i9.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i10.MatLegacyOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i11.MatLegacyCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i12.MatLegacyAutocomplete, selector: "mat-autocomplete", inputs: ["disableRipple"], exportAs: ["matAutocomplete"] }, { kind: "directive", type: i12.MatLegacyAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", exportAs: ["matAutocompleteTrigger"] }, { kind: "component", type: i13.MatLegacyProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }] });
|
|
291
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DocumentDatasourceComponent, decorators: [{
|
|
292
|
-
type: Component,
|
|
293
|
-
args: [{ selector: 'ki-document-datasource', template: "<div class=\"p-6 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-2xl font-bold text-gray-900\">\n {{!datasourceKey ? 'Document Datasource' : (datasource.title || 'Document Datasource')}}\n </h1>\n <p class=\"text-sm font-medium text-gray-500\">\n <ng-template [ngIf]=\"!datasourceKey\">\n Upload your documents using the form below.\n </ng-template>\n <ng-template [ngIf]=\"datasourceKey\">\n View your existing documents below and adjust any document settings here.\n </ng-template>\n </p>\n </div>\n </div>\n <div class=\"mt-6 flex flex-col-reverse justify-stretch\" *ngIf=\"datasourceKey\">\n <button type=\"button\" (click)=\"showUpload = !showUpload\"\n class=\"inline-flex items-center justify-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-primary focus:outline-none\">\n Upload Additional Documents\n </button>\n </div>\n </div>\n</div>\n\n<div class=\"bg-blue-50 p-4\" *ngIf=\"uploading\">\n <div class=\"flex\">\n <div class=\"flex-shrink-0\">\n <!-- Heroicon name: solid/information-circle -->\n <svg class=\"h-5 w-5 text-primary\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\"\n fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\"\n d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z\"\n clip-rule=\"evenodd\"/>\n </svg>\n </div>\n <div class=\"ml-3 w-full\">\n <p class=\"text-sm text-primary font-medium\">Progress</p>\n <ng-template [ngIf]=\"uploadResults && uploadResults.progressData\">\n <div class=\"text-primary my-2\">Uploaded {{uploadResults.progressData.completed}}\n /{{uploadResults.progressData.total}}</div>\n <mat-progress-bar class=\"w-full my-4\" mode=\"determinate\"\n [value]=\"(uploadResults.progressData.completed/uploadResults.progressData.total) * 100\"></mat-progress-bar>\n </ng-template>\n <ng-template [ngIf]=\"!uploadResults || !uploadResults.progressData\">\n <div class=\"text-primary my-2\">Preparing Upload...</div>\n <mat-progress-bar class=\"w-full my-4\" mode=\"buffer\"></mat-progress-bar>\n </ng-template>\n </div>\n </div>\n</div>\n\n<div class=\"bg-green-50 p-4\" *ngIf=\"!failedResults.length && uploadResults && !uploading\">\n <div class=\"flex\">\n <div class=\"flex-shrink-0\">\n <!-- Heroicon name: solid/check-circle -->\n <svg class=\"h-5 w-5 text-green-400\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\"\n fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\"\n d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z\"\n clip-rule=\"evenodd\"/>\n </svg>\n </div>\n <div class=\"ml-3\">\n <h3 class=\"text-sm font-medium text-green-800\">Upload completed</h3>\n <div class=\"mt-2 text-sm text-green-700\">\n <p><b>{{uploadResults.progressData.completed}}</b> files were processed successfully out of\n <b>{{uploadResults.progressData.total}}</b> uploaded items.</p>\n </div>\n </div>\n </div>\n</div>\n\n<div class=\"bg-red-50 p-4\" *ngIf=\"failedResults.length && uploadResults\">\n <div class=\"flex\">\n <div class=\"flex-shrink-0\">\n <!-- Heroicon name: solid/x-circle -->\n <svg class=\"h-5 w-5 text-red-400\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\"\n aria-hidden=\"true\">\n <path fill-rule=\"evenodd\"\n d=\"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z\"\n clip-rule=\"evenodd\"/>\n </svg>\n </div>\n <div class=\"ml-3\">\n <h3 class=\"text-sm font-medium text-red-800\">There were {{failedResults.length}} errors with your\n submission</h3>\n <div class=\"mt-2 text-sm text-red-700\">\n <ul role=\"list\" class=\"list-disc pl-5 space-y-1\">\n <li *ngFor=\"let failedResult of failedResults\">\n {{failedResult.message}}\n </li>\n </ul>\n </div>\n </div>\n </div>\n</div>\n\n<div *ngIf=\"showUpload\"\n class=\"space-y-8 p-6 bg-gray-50 border-b\">\n <div class=\"space-y-8 sm:space-y-5\">\n <div>\n <div class=\"space-y-6 sm:space-y-5\">\n <div class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start\">\n <label class=\"block text-sm font-medium text-gray-700\">\n Upload Documents\n <div class=\"text-xs font-normal text-gray-500\">\n Additional documents to be processed.\n </div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <div *ngIf=\"!files || !files.length\"\n (drop)=\"dropHandler($event)\" (dragover)=\"dragOverHandler($event)\"\n class=\"w-full flex justify-center px-6 pt-5 pb-6 border-2 border-gray-300 border-dashed rounded-md\">\n <div class=\"space-y-1 text-center\">\n <svg class=\"mx-auto h-12 w-12 text-gray-400\" stroke=\"currentColor\" fill=\"none\"\n viewBox=\"0 0 48 48\" aria-hidden=\"true\">\n <path\n d=\"M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02\"\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n <div class=\"flex text-sm text-gray-600\">\n <label\n class=\"relative cursor-pointer rounded-md font-medium text-secondary focus-within:outline-none\">\n <span>Select file(s) to upload</span>\n <input name=\"additionalUpload\" multiple type=\"file\" class=\"sr-only\"\n (change)=\"fileUpload($event)\">\n </label>\n <p class=\"pl-1 mb-0\">or drag and drop</p>\n </div>\n <p class=\"text-xs text-gray-500\">.docx, .txt, .pfd, .zip</p>\n </div>\n </div>\n <div *ngIf=\"files && files.length\"\n class=\"overflow-hidden shadow ring-1 ring-black ring-opacity-5 md:rounded-lg\">\n <table class=\"min-w-full divide-y divide-gray-300 block overflow-y-auto max-h-48\">\n <thead class=\"bg-gray-50\">\n <tr>\n <th scope=\"col\" colspan=\"2\"\n class=\"sticky top-0 z-10 bg-gray-100 py-2 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6\">\n Selected File Preview\n <span class=\"text-xs text-gray-500 lowercase ml-4 font-normal\">\n click <span class=\"font-medium\">'Upload Files'</span> to upload the selected files.</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"divide-y divide-gray-200 bg-white\">\n <tr *ngFor=\"let file of files; let i = index\">\n <td class=\"whitespace-nowrap py-2 pl-4 pr-3 text-xs font-medium text-gray-900 sm:pl-6\">\n {{file.name}}\n </td>\n <td class=\"relative whitespace-nowrap py-2 pl-3 pr-4 text-right text-sm font-medium sm:pr-6\">\n <a (click)=\"removeFile(i)\" class=\"text-danger\">Remove</a>\n </td>\n </tr>\n\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n </div>\n </div>\n\n </div>\n\n <div class=\"\">\n <div class=\"flex justify-end\">\n <button type=\"button\" (click)=\"showUpload = false;files = null\"\n class=\"bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none\">\n Cancel\n </button>\n\n <button type=\"submit\" [disabled]=\"!files\"\n class=\"disabled:opacity-50 ml-3 inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-secondary focus:outline-none\"\n (click)=\"uploadFiles()\">Upload Files\n </button>\n </div>\n </div>\n</div>\n\n<div class=\"transformation-listing py-2 bg-gray-50 cursor-pointer\"\n (click)=\"showSettings = !showSettings\" [ngClass]=\"{'border-b': !showSettings}\">\n <a class=\"list-title flex items-center\">\n Settings \n <mat-icon *ngIf=\"!showSettings\">expand_more</mat-icon>\n <mat-icon *ngIf=\"showSettings\">expand_less</mat-icon>\n </a>\n <div class=\"ml-6 text-xs text-gray-500\">\n Adjust the rules around how the uploaded documents will\n be processed.\n </div>\n</div>\n\n<div *ngIf=\"showSettings\" [ngClass]=\"{'border-b': showSettings}\"\n class=\"space-y-8 divide-y divide-gray-200 p-6 bg-gray-50\">\n <div class=\"space-y-8 divide-y divide-gray-200 sm:space-y-5\">\n <div>\n <div class=\"space-y-6 sm:space-y-5\">\n <div class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start\">\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Title\n <div class=\"text-xs font-normal text-gray-500\">Enter the name to identify this data source</div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <input type=\"text\" [(ngModel)]=\"datasource.title\"\n class=\"max-w-lg block w-full shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:max-w-xs sm:text-sm border-gray-300 rounded-md\">\n\n </div>\n </div>\n\n <div *ngIf=\"!datasourceKey\"\n class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5\">\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Upload Documents\n <div class=\"text-xs font-normal text-gray-500\">\n The documents to be processed.\n </div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <div *ngIf=\"!files || !files.length\"\n (drop)=\"dropHandler($event)\" (dragover)=\"dragOverHandler($event)\"\n class=\"w-full flex justify-center px-6 pt-5 pb-6 border-2 border-gray-300 border-dashed rounded-md\">\n <div class=\"space-y-1 text-center\">\n <svg class=\"mx-auto h-12 w-12 text-gray-400\" stroke=\"currentColor\" fill=\"none\"\n viewBox=\"0 0 48 48\" aria-hidden=\"true\">\n <path\n d=\"M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02\"\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n <div class=\"flex text-sm text-gray-600\">\n <label\n class=\"relative cursor-pointer rounded-md font-medium text-secondary focus-within:outline-none\">\n <span>Select file(s) to upload</span>\n <input name=\"additionalUpload\" multiple type=\"file\" class=\"sr-only\"\n (change)=\"fileUpload($event)\">\n </label>\n <p class=\"pl-1 mb-0\">or drag and drop</p>\n </div>\n <p class=\"text-xs text-gray-500\">.docx, .txt, .pfd, .zip</p>\n </div>\n </div>\n <div *ngIf=\"files\"\n class=\"overflow-hidden shadow ring-1 ring-black ring-opacity-5 md:rounded-lg\">\n <table class=\"min-w-full divide-y divide-gray-300 block overflow-y-auto max-h-48\">\n <thead class=\"bg-gray-50\">\n <tr>\n <th scope=\"col\" colspan=\"2\"\n class=\"sticky top-0 z-10 bg-gray-100 py-2 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6\">\n Selected File Preview\n <span class=\"text-xs text-gray-500 lowercase ml-4 font-normal\">\n click <span class=\"font-medium\">'Upload Files'</span> to upload the selected files.</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"divide-y divide-gray-200 bg-white\">\n <tr *ngFor=\"let file of files; let i = index\">\n <td class=\"whitespace-nowrap py-2 pl-4 pr-3 text-xs font-medium text-gray-900 sm:pl-6\">\n {{file.name}}\n </td>\n <td class=\"relative whitespace-nowrap py-2 pl-3 pr-4 text-right text-sm font-medium sm:pr-6\">\n <a (click)=\"removeFile(i)\" class=\"text-danger\">Remove</a>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n <ng-template [ngIf]=\"showCustomParser\">\n <div class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5\">\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Custom Document Parser\n <div class=\"text-xs font-normal text-gray-500\">\n Use a custom document parser to process the documents.\n </div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <label class=\"mb-4 text-sm\">\n Select Custom Document Parser\n <input type=\"text\" [matAutocomplete]=\"autoParsers\"\n [(ngModel)]=\"datasource.config.customDocumentParser\"\n (keyup)=\"searchParser.next($event.target.value)\"\n placeholder=\"Search for a custom parser\">\n <mat-autocomplete #autoParsers=\"matAutocomplete\">\n <mat-option *ngFor=\"let parser of documentParsers\" [value]=\"parser.value\">\n {{parser.title}}\n </mat-option>\n </mat-autocomplete>\n <small class=\"font-normal\">Start typing name to view available parsers</small>\n </label>\n </div>\n </div>\n </ng-template>\n\n <ng-template [ngIf]=\"!datasource.config.customDocumentParser\">\n\n\n <div class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5\">\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Indexing\n <div class=\"text-xs font-normal text-gray-500\">\n Set whether you want the content of the documents to be indexed\n </div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <mat-checkbox class=\"block mb-4\" [(ngModel)]=\"datasource.config.indexContent\"\n (ngModelChange)=\"indexDocumentChange($event)\">Index Document\n Content\n </mat-checkbox>\n <ng-template [ngIf]=\"datasource.config.indexContent\">\n <div class=\"max-w-lg flex rounded-md shadow-sm mb-2\">\n <span\n class=\"inline-flex items-center px-3 rounded-l-md border border-r-0 border-gray-300 bg-gray-50 text-gray-500 sm:text-sm\"> Min phrase length (words) </span>\n <input type=\"number\" name=\"minPhrase\" [min]=\"1\"\n [(ngModel)]=\"datasource.config.minPhraseLength\"\n class=\"flex-1 block w-full min-w-0 rounded-none rounded-r-md sm:text-sm border-gray-300\">\n </div>\n <div class=\"max-w-lg flex rounded-md shadow-sm\">\n <span\n class=\"inline-flex items-center px-3 rounded-l-md border border-r-0 border-gray-300 bg-gray-50 text-gray-500 sm:text-sm\"> Max phrase length (words) </span>\n <input type=\"number\" name=\"maxPhrase\" [min]=\"1\"\n [(ngModel)]=\"datasource.config.maxPhraseLength\"\n class=\"flex-1 block w-full min-w-0 rounded-none rounded-r-md sm:text-sm border-gray-300\">\n </div>\n </ng-template>\n </div>\n </div>\n\n <div class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5\">\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Chunking\n <div class=\"text-xs font-normal text-gray-500\">\n Set whether you want to split the documents into chunks for analysis\n </div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <mat-checkbox class=\"block mb-4\" [(ngModel)]=\"datasource.config.chunkContent\" (ngModelChange)=\"chunkContentChange($event)\"> Chunk Document Content\n </mat-checkbox>\n <ng-template [ngIf]=\"datasource.config.chunkContent\">\n <mat-checkbox class=\"block mb-4\" [(ngModel)]=\"datasource.config.indexChunksByAI\">Index Chunks by AI\n </mat-checkbox>\n </ng-template>\n </div>\n\n </div>\n\n <div *ngIf=\"datasource.config.indexContent\"\n class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5\">\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Stop Words\n <div class=\"text-xs font-normal text-gray-500\">\n A list of words to exclude from being indexed.\n </div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <mat-checkbox class=\"block mb-2\" [(ngModel)]=\"builtInStopWords.builtIn\"\n (ngModelChange)=\"updateBuiltInStopWordConfig($event)\">Use Built In\n </mat-checkbox>\n\n <ng-template [ngIf]=\"builtInStopWords.builtIn && datasource.config.maxPhraseLength > 1\">\n <label class=\"mb-4\">\n Min phrase length for including stop words\n <input type=\"number\" [min]=\"2\"\n [(ngModel)]=\"builtInStopWords.minPhraseLength\">\n <small class=\"font-normal\">The built it stop words will be included when the phrase\n length is greater than or equal to this value.</small>\n </label>\n </ng-template>\n\n <hr class=\"my-4\" *ngIf=\"_.filter(datasource.config.stopWords, 'custom').length\">\n\n <ng-template ngFor let-stopWord [ngForOf]=\"_.filter(datasource.config.stopWords, 'custom')\"\n let-i=index>\n <div class=\"flex items-center justify-between\">\n <div>\n <label class=\"mb-4 text-sm\">\n Datasource\n <input type=\"text\" [matAutocomplete]=\"autoDatasets\"\n [value]=\"stopWord.datasource ? stopWord.datasource.title : ''\"\n (keyup)=\"searchText.next($event.target.value)\"\n placeholder=\"Search for a datasource\">\n <mat-autocomplete #autoDatasets=\"matAutocomplete\" [displayWith]=\"displayFn\">\n <mat-option *ngFor=\"let datasource of datasources\" [value]=\"datasource\"\n (onSelectionChange)=\"updateDatasource(stopWord, $event.source.value)\">\n {{datasource.title}}\n </mat-option>\n </mat-autocomplete>\n <small class=\"font-normal\">Start typing name to view available\n datasources</small>\n </label>\n\n\n <div *ngIf=\"stopWord.selectedDatasource && stopWord.selectedDatasource.columns\">\n <label class=\"mb-4\">\n Stop Words Column\n <select matNativeControl [(ngModel)]=\"stopWord.datasourceColumn\">\n <option *ngFor=\"let column of stopWord.selectedDatasource.columns\"\n [ngValue]=\"column.name\">\n {{column.title}}\n </option>\n </select>\n <small class=\"font-normal\">Select the column to use for the stop\n words</small>\n </label>\n\n <label class=\"mb-4\" *ngIf=\"datasource.config.maxPhraseLength > 1\">\n Min phrase length for including stop words\n <input type=\"number\" [min]=\"2\"\n [(ngModel)]=\"stopWord.minPhraseLength\">\n <small\n class=\"font-normal\">The {{stopWord.datasource ? stopWord.datasource.title : ''}}\n stop words will be included when the\n phrase length is greater than or equal to this value.</small>\n </label>\n </div>\n </div>\n\n <button mat-icon-button color=\"warn\" (click)=\"removeCustomStopWord(i)\">\n <mat-icon>clear</mat-icon>\n </button>\n </div>\n\n <hr class=\"my-4\">\n </ng-template>\n\n <button mat-button color=\"primary\"\n (click)=\"datasource.config.stopWords.push({custom: true})\">\n <mat-icon>add</mat-icon>\n Add Custom Stop Words\n </button>\n\n </div>\n </div>\n\n </ng-template>\n\n <div class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5\">\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Storage Options\n <div class=\"text-xs font-normal text-gray-500\">\n Securely save an original copy of the document and/or its original text.\n </div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <mat-checkbox class=\"block mb-2\" [(ngModel)]=\"datasource.config.storeOriginal\">Store\n Original File\n </mat-checkbox>\n <mat-checkbox class=\"block mb-2\" [(ngModel)]=\"datasource.config.storeText\">Store Document\n Text\n </mat-checkbox>\n </div>\n </div>\n\n </div>\n </div>\n\n </div>\n\n <div class=\"pt-5\">\n <div class=\"flex justify-end\">\n <button type=\"button\"\n class=\"bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none\">\n Cancel\n </button>\n <button type=\"submit\" [disabled]=\"!datasource.title\"\n class=\"disabled:opacity-50 ml-3 inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-secondary focus:outline-none\"\n (click)=\"save()\">\n <ng-template [ngIf]=\"!datasourceKey\">\n Create Datasource\n </ng-template>\n <ng-template [ngIf]=\"datasourceKey\">\n Update Settings\n </ng-template>\n </button>\n </div>\n </div>\n</div>\n\n<ng-template [ngIf]=\"evaluatedDatasource\">\n\n\n <div class=\"overflow-scroll\">\n <table class=\"min-w-full border-separate bg-white\" style=\"border-spacing: 0\">\n <thead class=\"bg-gray-100\">\n <tr>\n <th *ngFor=\"let column of evaluatedDatasource.columns\" scope=\"col\"\n class=\"sticky top-0 z-10 border-b border-gray-300 bg-gray-50 bg-opacity-75 py-3.5 px-4 text-left text-xs font-semibold text-gray-900 backdrop-blur backdrop-filter\">\n {{column.title}}\n </th>\n </tr>\n </thead>\n <tbody class=\"bg-white\">\n <tr *ngFor=\"let data of evaluatedDatasource.allData\">\n <td *ngFor=\"let column of evaluatedDatasource.columns; let i = index\"\n [ngClass]=\"{'font-medium': i === 0}\"\n class=\"border-b border-gray-200 py-2 px-4 text-sm text-gray-900\">\n <ng-template [ngIf]=\"column.name === 'original_link'\">\n <a class=\"flex items-center text-cta hover:underline\" (click)=\"downloadDoc(data[column.name])\">\n {{data[column.name]}}\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"ml-1 h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke=\"currentColor\" stroke-width=\"2\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\n d=\"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4\"/>\n </svg>\n </a>\n </ng-template>\n <ng-template [ngIf]=\"column.name !== 'original_link'\">\n <ng-template [ngIf]=\"data[column.name] && String(data[column.name]).length <= 100\">\n {{data[column.name]}}\n </ng-template>\n <ng-template [ngIf]=\"data[column.name] && String(data[column.name]).length > 100\">\n <div>{{data[column.name].substring(0, 100) + '...'}}</div>\n <a (click)=\"viewFullItemData(data[column.name], column.name)\"\n class=\"flex items-center text-sm text-cta hover:underline\">\n view more\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"ml-1 h-4 w-4\" fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"\n d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"/>\n </svg>\n </a>\n </ng-template>\n <ng-template [ngIf]=\"!data[column.name]\">\n {{data[column.name]}}\n </ng-template>\n </ng-template>\n </td>\n </tr>\n </tbody>\n\n </table>\n\n </div>\n <div class=\"bg-white p-4 flex align-center justify-end\">\n <select [value]=\"limit\" (change)=\"pageSizeChange($event.target.value)\" class=\"mr-8\">\n <option [value]=\"1\">1</option>\n <option [value]=\"5\">5</option>\n <option [value]=\"10\">10</option>\n <option [value]=\"25\">25</option>\n <option [value]=\"50\">50</option>\n <option [value]=\"100\">100</option>\n <option [value]=\"250\">250</option>\n <option [value]=\"1000\">1000</option>\n </select>\n <button mat-icon-button 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\n</ng-template>\n", styles: [":host{display:block;background-color:#fff}.cell-header{width:100%;display:flex;align-items:center;justify-content:space-between}.cell-header.end{justify-content:flex-end}.transformation-listing{display:flex;align-items:center;flex-wrap:wrap;width:100%;border-bottom-color:#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}table{position:relative;border-collapse:collapse}table.sticky th{position:sticky;top:0;background-color:#f5f5f5;border-top:none!important;border-bottom:none!important;box-shadow:inset 0 -1px #ddd}table th.settings{padding:0}table td{max-width:400px;word-wrap:break-word;padding-top:.5rem;padding-bottom:.5rem;padding-right:1rem;min-width:100px;width:1%}table td.settings{max-width:25px;min-width:25px}table::-webkit-scrollbar{width:.75em;background:transparent}table::-webkit-scrollbar-thumb{background:#d2d2d2}\n"] }]
|
|
294
|
-
}], ctorParameters: function () { return [{ type: i1.ActivatedRoute }, { type: i2.DatasourceService }, { type: i3.DatasetService }, { type: i4.MatLegacyDialog }]; }, propDecorators: { showCustomParser: [{
|
|
295
|
-
type: Input
|
|
296
|
-
}] } });
|
|
297
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9jdW1lbnQtZGF0YXNvdXJjZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1raW5pbnRlbC9zcmMvbGliL2NvbXBvbmVudHMvZGF0YXNvdXJjZS9kb2N1bWVudC1kYXRhc291cmNlL2RvY3VtZW50LWRhdGFzb3VyY2UuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmcta2luaW50ZWwvc3JjL2xpYi9jb21wb25lbnRzL2RhdGFzb3VyY2UvZG9jdW1lbnQtZGF0YXNvdXJjZS9kb2N1bWVudC1kYXRhc291cmNlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxTQUFTLEVBQUUsS0FBSyxFQUFTLE1BQU0sZUFBZSxDQUFDO0FBRXZELE9BQU8sRUFBQyxlQUFlLEVBQVEsTUFBTSxNQUFNLENBQUM7QUFDNUMsT0FBTyxFQUFDLFlBQVksRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFHNUQsT0FBTyxFQUNILDJCQUEyQixFQUM5QixNQUFNLHVEQUF1RCxDQUFDO0FBRS9ELE9BQU8sS0FBSyxNQUFNLE1BQU0sUUFBUSxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7QUFFakMsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQztBQU96QixNQUFNLE9BQU8sMkJBQTJCO0lBNkJwQyxZQUFvQixLQUFxQixFQUNyQixpQkFBb0MsRUFDcEMsY0FBOEIsRUFDOUIsTUFBaUI7UUFIakIsVUFBSyxHQUFMLEtBQUssQ0FBZ0I7UUFDckIsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFtQjtRQUNwQyxtQkFBYyxHQUFkLGNBQWMsQ0FBZ0I7UUFDOUIsV0FBTSxHQUFOLE1BQU0sQ0FBVztRQTNCOUIsZUFBVSxHQUFHLElBQUksZUFBZSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3JDLGlC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MkIsZ0hDbkJ4Qyx3NWlDQThpQkE7NEZEM2hCYSwyQkFBMkI7a0JBTHZDLFNBQVM7K0JBQ0ksd0JBQXdCO2dNQU16QixnQkFBZ0I7c0JBQXhCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0NvbXBvbmVudCwgSW5wdXQsIE9uSW5pdH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0FjdGl2YXRlZFJvdXRlfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHtCZWhhdmlvclN1YmplY3QsIG1lcmdlfSBmcm9tICdyeGpzJztcbmltcG9ydCB7ZGVib3VuY2VUaW1lLCBtYXAsIHN3aXRjaE1hcH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHtEYXRhc291cmNlU2VydmljZX0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvZGF0YXNvdXJjZS5zZXJ2aWNlJztcbmltcG9ydCB7RGF0YXNldFNlcnZpY2V9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2RhdGFzZXQuc2VydmljZSc7XG5pbXBvcnQge1xuICAgIERhdGFzZXRFZGl0b3JQb3B1cENvbXBvbmVudFxufSBmcm9tICcuLi8uLi9kYXRhc2V0L2RhdGFzZXQtZWRpdG9yL2RhdGFzZXQtZWRpdG9yLmNvbXBvbmVudCc7XG5pbXBvcnQge01hdExlZ2FjeURpYWxvZyBhcyBNYXREaWFsb2d9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2xlZ2FjeS1kaWFsb2cnO1xuaW1wb3J0ICogYXMgbG9kYXNoIGZyb20gJ2xvZGFzaCc7XG5cbmNvbnN0IF8gPSBsb2Rhc2guZGVmYXVsdDtcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdraS1kb2N1bWVudC1kYXRhc291cmNlJyxcbiAgICB0ZW1wbGF0ZVVybDogJy4vZG9jdW1lbnQtZGF0YXNvdXJjZS5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vZG9jdW1lbnQtZGF0YXNvdXJjZS5jb21wb25lbnQuc2FzcyddXG59KVxuZXhwb3J0IGNsYXNzIERvY3VtZW50RGF0YXNvdXJjZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG5cbiAgICBASW5wdXQoKSBzaG93Q3VzdG9tUGFyc2VyOiBib29sZWFuO1xuXG4gICAgcHVibGljIGRhdGFzb3VyY2VLZXk6IGFueTtcbiAgICBwdWJsaWMgc2VhcmNoVGV4dCA9IG5ldyBCZWhhdmlvclN1YmplY3QoJycpO1xuICAgIHB1YmxpYyBzZWFyY2hQYXJzZXIgPSBuZXcgQmVoYXZpb3JTdWJqZWN0KCcnKTtcbiAgICBwdWJsaWMgZGF0YXNvdXJjZXM6IGFueSA9IFtdO1xuICAgIHB1YmxpYyBkb2N1bWVudFBhcnNlcnM6IGFueSA9IFtdO1xuICAgIHB1YmxpYyBzZWxlY3RlZERhdGFzb3VyY2U6IGFueTtcbiAgICBwdWJsaWMgZGF0YXNvdXJjZTogYW55ID0ge2NvbmZpZzoge3N0b3BXb3JkczogW119fTtcbiAgICBwdWJsaWMgZXZhbHVhdGVkRGF0YXNvdXJjZTogYW55O1xuICAgIHB1YmxpYyBzaG93U2V0dGluZ3MgPSB0cnVlO1xuICAgIHB1YmxpYyBzaG93VXBsb2FkID0gZmFsc2U7XG4gICAgcHVibGljIFN0cmluZyA9IFN0cmluZztcbiAgICBwdWJsaWMgZmlsZXM6IGFueSA9IG51bGw7XG4gICAgcHVibGljIF8gPSBfO1xuICAgIHB1YmxpYyBidWlsdEluU3RvcFdvcmRzID0ge1xuICAgICAgICBidWlsdEluOiBmYWxzZVxuICAgIH07XG4gICAgcHVibGljIHVwbG9hZFJlc3VsdHM6IGFueTtcbiAgICBwdWJsaWMgZmFpbGVkUmVzdWx0czogYW55ID0gW107XG4gICAgcHVibGljIHVwbG9hZGluZyA9IGZhbHNlO1xuICAgIHB1YmxpYyBwYWdlID0gMTtcbiAgICBwdWJsaWMgZW5kT2ZSZXN1bHRzID0gZmFsc2U7XG4gICAgcHVibGljIGxpbWl0ID0gMjU7XG5cbiAgICBwcml2YXRlIG9mZnNldCA9IDA7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJvdXRlOiBBY3RpdmF0ZWRSb3V0ZSxcbiAgICAgICAgICAgICAgICBwcml2YXRlIGRhdGFzb3VyY2VTZXJ2aWNlOiBEYXRhc291cmNlU2VydmljZSxcbiAgICAgICAgICAgICAgICBwcml2YXRlIGRhdGFzZXRTZXJ2aWNlOiBEYXRhc2V0U2VydmljZSxcbiAgICAgICAgICAgICAgICBwcml2YXRlIGRpYWxvZzogTWF0RGlhbG9nKSB7XG4gICAgfVxuXG4gICAgYXN5bmMgbmdPbkluaXQoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgdGhpcy5yb3V0ZS5wYXJhbXMuc3Vic2NyaWJlKGFzeW5jIHBhcmFtID0+IHtcbiAgICAgICAgICAgIHRoaXMuZGF0YXNvdXJjZUtleSA9IHBhcmFtLmtleTtcbiAgICAgICAgICAgIGlmICh0aGlzLmRhdGFzb3VyY2VLZXkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNob3dTZXR0aW5ncyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YXNvdXJjZSA9IGF3YWl0IHRoaXMuZGF0YXNvdXJjZVNlcnZpY2UuZ2V0RGF0YXNvdXJjZSh0aGlzLmRhdGFzb3VyY2VLZXkpO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5ldmFsdWF0ZURhdGFzb3VyY2UoKTtcblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmRhdGFzb3VyY2UuY29uZmlnLnN0b3BXb3JkcyAmJiB0aGlzLmRhdGFzb3VyY2UuY29uZmlnLnN0b3BXb3Jkcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBzdG9wV29yZCBvZiB0aGlzLmRhdGFzb3VyY2UuY29uZmlnLnN0b3BXb3Jkcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0b3BXb3JkLmN1c3RvbSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0b3BXb3JkLmRhdGFzb3VyY2UgPSBhd2FpdCB0aGlzLmRhdGFzb3VyY2VTZXJ2aWNlLmdldERhdGFzb3VyY2Uoc3RvcFdvcmQuZGF0YXNvdXJjZUtleSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVEYXRhc291cmNlKHN0b3BXb3JkLCBzdG9wV29yZC5kYXRhc291cmNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdG9wV29yZC5idWlsdEluKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5idWlsdEluU3RvcFdvcmRzID0gc3RvcFdvcmQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuc2VhcmNoVGV4dFxuICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgICAgZGVib3VuY2VUaW1lKDMwMCksXG4gICAgICAgICAgICAgICAgLy8gZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcbiAgICAgICAgICAgICAgICBzd2l0Y2hNYXAoKCkgPT5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXREYXRhc291cmNlcygpXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKS5zdWJzY3JpYmUoKGRhdGFzb3VyY2VzOiBhbnkpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZGF0YXNvdXJjZXMgPSBkYXRhc291cmNlcztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5zZWFyY2hQYXJzZXJcbiAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAgIGRlYm91bmNlVGltZSgzMDApLFxuICAgICAgICAgICAgICAgIC8vIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgICAgICAgICAgICAgc3dpdGNoTWFwKCgpID0+XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZ2V0RG9jdW1lbnRQYXJzZXJzKClcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApLnN1YnNjcmliZSgocGFyc2VyczogYW55KSA9PiB7XG4gICAgICAgICAgICB0aGlzLmRvY3VtZW50UGFyc2VycyA9IHBhcnNlcnM7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBpbmNyZWFzZU9mZnNldCgpIHtcbiAgICAgICAgdGhpcy5wYWdlID0gdGhpcy5wYWdlICsgMTtcbiAgICAgICAgdGhpcy5vZmZzZXQgPSAodGhpcy5saW1pdCAqIHRoaXMucGFnZSkgLSB0aGlzLmxpbWl0O1xuICAgICAgICB0aGlzLmV2YWx1YXRlRGF0YXNvdXJjZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBkZWNyZWFzZU9mZnNldCgpIHtcbiAgICAgICAgdGhpcy5wYWdlID0gdGhpcy5wYWdlIDw9IDEgPyAxIDogdGhpcy5wYWdlIC0gMTtcbiAgICAgICAgdGhpcy5vZmZzZXQgPSAodGhpcy5saW1pdCAqIHRoaXMucGFnZSkgLSB0aGlzLmxpbWl0O1xuICAgICAgICB0aGlzLmV2YWx1YXRlRGF0YXNvdXJjZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBwYWdlU2l6ZUNoYW5nZSh2YWx1ZSkge1xuICAgICAgICB0aGlzLmxpbWl0ID0gdmFsdWU7XG4gICAgICAgIHRoaXMuZXZhbHVhdGVEYXRhc291cmNlKHRydWUpO1xuICAgIH1cblxuICAgIHB1YmxpYyB2aWV3RnVsbEl0ZW1EYXRhKGRhdGEsIGNvbHVtbk5hbWUpIHtcbiAgICAgICAgdGhpcy5kaWFsb2cub3BlbihEYXRhc2V0RWRpdG9yUG9wdXBDb21wb25lbnQsIHtcbiAgICAgICAgICAgIHdpZHRoOiAnODAwcHgnLFxuICAgICAgICAgICAgaGVpZ2h0OiAnNDAwcHgnLFxuICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgIGZ1bGxEYXRhOiBkYXRhLFxuICAgICAgICAgICAgICAgIGNvbHVtbk5hbWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGluZGV4RG9jdW1lbnRDaGFuZ2UoY2hhbmdlKSB7XG4gICAgICAgIGlmIChjaGFuZ2UpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5kYXRhc291cmNlLmNvbmZpZy5taW5QaHJhc2VMZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGFzb3VyY2UuY29uZmlnLm1pblBocmFzZUxlbmd0aCA9IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRoaXMuZGF0YXNvdXJjZS5jb25maWcubWF4UGhyYXNlTGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhc291cmNlLmNvbmZpZy5tYXhQaHJhc2VMZW5ndGggPSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGNodW5rQ29udGVudENoYW5nZShjaGFuZ2UpIHtcbiAgICAgICAgaWYgKGNoYW5nZSl7XG4gICAgICAgICAgICBpZiAoIXRoaXMuZGF0YXNvdXJjZS5jb25maWcuY2h1bmtDb250ZW50KXtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGFzb3VyY2UuY29uZmlnLmluZGV4Q2h1bmtzQnlBSSA9IGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgdXBkYXRlQnVpbHRJblN0b3BXb3JkQ29uZmlnKHZhbHVlKSB7XG4gICAgICAgIF8ucmVtb3ZlKHRoaXMuZGF0YXNvdXJjZS5jb25maWcuc3RvcFdvcmRzLCBzdG9wV29yZCA9PiB7XG4gICAgICAgICAgICByZXR1cm4gc3RvcFdvcmQuYnVpbHRJbiAhPT0gdW5kZWZpbmVkO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKCF0aGlzLmRhdGFzb3VyY2UuY29uZmlnLnN0b3BXb3Jkcykge1xuICAgICAgICAgICAgdGhpcy5kYXRhc291cmNlLmNvbmZpZy5zdG9wV29yZHMgPSBbXTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRhdGFzb3VyY2UuY29uZmlnLnN0b3BXb3Jkcy5wdXNoKHRoaXMuYnVpbHRJblN0b3BXb3Jkcyk7XG4gICAgfVxuXG4gICAgcHVibGljIHJlbW92ZUN1c3RvbVN0b3BXb3JkKGluZGV4KSB7XG4gICAgICAgIHRoaXMuZGF0YXNvdXJjZS5jb25maWcuc3RvcFdvcmRzLnNwbGljZShpbmRleCwgMSk7XG4gICAgfVxuXG4gICAgcHVibGljIGh1bWFuRmlsZVNpemUoc2l6ZTogYW55KSB7XG4gICAgICAgIGNvbnN0IGkgPSBzaXplID09PSAwID8gMCA6IE1hdGguZmxvb3IoTWF0aC5sb2coc2l6ZSkgLyBNYXRoLmxvZygxMDI0KSk7XG4gICAgICAgIHJldHVybiBOdW1iZXIoKHNpemUgLyBNYXRoLnBvdygxMDI0LCBpKSkudG9GaXhlZCgyKSkgKiAxICsgJyAnICsgWydCJywgJ2tCJywgJ01CJywgJ0dCJywgJ1RCJ11baV07XG4gICAgfVxuXG4gICAgcHVibGljIGRpc3BsYXlGbihkYXRhc2V0KTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIGRhdGFzZXQgJiYgZGF0YXNldC50aXRsZSA/IGRhdGFzZXQudGl0bGUgOiAnJztcbiAgICB9XG5cbiAgICBwdWJsaWMgZHJhZ092ZXJIYW5kbGVyKGV2KSB7XG4gICAgICAgIC8vIFByZXZlbnQgZGVmYXVsdCBiZWhhdmlvciAoUHJldmVudCBmaWxlIGZyb20gYmVpbmcgb3BlbmVkKVxuICAgICAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBkcm9wSGFuZGxlcihldikge1xuICAgICAgICAvLyBQcmV2ZW50IGRlZmF1bHQgYmVoYXZpb3IgKFByZXZlbnQgZmlsZSBmcm9tIGJlaW5nIG9wZW5lZClcbiAgICAgICAgZXYucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICB0aGlzLmZpbGVzID0gW107XG5cbiAgICAgICAgaWYgKGV2LmRhdGFUcmFuc2Zlci5pdGVtcykge1xuICAgICAgICAgICAgLy8gVXNlIERhdGFUcmFuc2Zlckl0ZW1MaXN0IGludGVyZmFjZSB0byBhY2Nlc3MgdGhlIGZpbGUocylcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZXYuZGF0YVRyYW5zZmVyLml0ZW1zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgLy8gSWYgZHJvcHBlZCBpdGVtcyBhcmVuJ3QgZmlsZXMsIHJlamVjdCB0aGVtXG4gICAgICAgICAgICAgICAgaWYgKGV2LmRhdGFUcmFuc2Zlci5pdGVtc1tpXS5raW5kID09PSAnZmlsZScpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlsZSA9IGV2LmRhdGFUcmFuc2Zlci5pdGVtc1tpXS5nZXRBc0ZpbGUoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5maWxlcy5wdXNoKGZpbGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFVzZSBEYXRhVHJhbnNmZXIgaW50ZXJmYWNlIHRvIGFjY2VzcyB0aGUgZmlsZShzKVxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBldi5kYXRhVHJhbnNmZXIuZmlsZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCBmaWxlID0gZXYuZGF0YVRyYW5zZmVyLmZpbGVzW2ldO1xuICAgICAgICAgICAgICAgIHRoaXMuZmlsZXMucHVzaChmaWxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBmaWxlVXBsb2FkKGV2ZW50KSB7XG4gICAgICAgIHRoaXMuZmlsZXMgPSBBcnJheS5mcm9tKGV2ZW50LnRhcmdldC5maWxlcyk7XG4gICAgfVxuXG4gICAgcHVibGljIHJlbW92ZUZpbGUoaW5kZXgpIHtcbiAgICAgICAgdGhpcy5maWxlcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIH1cblxuICAgIHB1YmxpYyBkb3dubG9hZERvYyh1cmwpIHtcbiAgICAgICAgd2luZG93Lm9wZW4odXJsKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgdXBsb2FkRmlsZXMoKSB7XG4gICAgICAgIGNvbnN0IGZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKCk7XG5cbiAgICAgICAgZm9yIChjb25zdCBmaWxlIG9mIHRoaXMuZmlsZXMpIHtcblxuICAgICAgICAgICAgZm9ybURhdGEuYXBwZW5kKGZpbGUubmFtZSwgZmlsZSk7XG4gICAgICAgIH1cblxuICAgICAgICBhd2FpdCB0aGlzLnVwbG9hZERhdGFzb3VyY2VEb2N1bWVudHMoZm9ybURhdGEpO1xuICAgICAgICB0aGlzLmV2YWx1YXRlRGF0YXNvdXJjZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyB1cGRhdGVEYXRhc291cmNlKHN0b3BXb3JkLCBkYXRhc291cmNlKSB7XG4gICAgICAgIHN0b3BXb3JkLmRhdGFzb3VyY2VLZXkgPSBkYXRhc291cmNlLmtleTtcbiAgICAgICAgc3RvcFdvcmQuZGF0YXNvdXJjZSA9IGRhdGFzb3VyY2U7XG5cbiAgICAgICAgY29uc3QgZGF0YXNldEluc3RhbmNlU3VtbWFyeSA9IHtcbiAgICAgICAgICAgIGRhdGFzZXRJbnN0YW5jZUlkOiBudWxsLFxuICAgICAgICAgICAgZGF0YXNvdXJjZUluc3RhbmNlS2V5OiBkYXRhc291cmNlLmtleSxcbiAgICAgICAgICAgIHRyYW5zZm9ybWF0aW9uSW5zdGFuY2VzOiBbXSxcbiAgICAgICAgICAgIHBhcmFtZXRlclZhbHVlczoge30sXG4gICAgICAgICAgICBwYXJhbWV0ZXJzOiBbXSxcbiAgICAgICAgICAgIG9yaWdpbkRhdGFJdGVtVGl0bGU6IGRhdGFzb3VyY2UudGl0bGVcbiAgICAgICAgfTtcblxuICAgICAgICBzdG9wV29yZC5zZWxlY3RlZERhdGFzb3VyY2UgPSBhd2FpdCB0aGlzLmRhdGFzZXRTZXJ2aWNlLmV2YWx1YXRlRGF0YXNldChkYXRhc2V0SW5zdGFuY2VTdW1tYXJ5LCAnMCcsICcxJyk7XG4gICAgfVxuXG4gICAgcHVibGljIHVwZGF0ZUN1c3RvbVBhcnNlcih2YWx1ZSkge1xuICAgICAgICB0aGlzLmRhdGFzb3VyY2UuY29uZmlnLmN1c3RvbURvY3VtZW50UGFyc2VyID0gdmFsdWU7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHNhdmUoKSB7XG4gICAgICAgIGlmICghdGhpcy5kYXRhc291cmNlS2V5KSB7XG4gICAgICAgICAgICB0aGlzLmRhdGFzb3VyY2VLZXkgPSBhd2FpdCB0aGlzLmRhdGFzb3VyY2VTZXJ2aWNlLmNyZWF0ZURvY3VtZW50RGF0YXNvdXJjZSh0aGlzLmRhdGFzb3VyY2UpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5maWxlcyAmJiB0aGlzLmZpbGVzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMudXBsb2FkRmlsZXMoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmV2YWx1YXRlRGF0YXNvdXJjZSgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZiA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmICsgJy8nICsgdGhpcy5kYXRhc291cmNlS2V5O1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmRhdGFzb3VyY2VTZXJ2aWNlLnVwZGF0ZURhdGFzb3VyY2VJbnN0YW5jZSh0aGlzLmRhdGFzb3VyY2VLZXksIHRoaXMuZGF0YXNvdXJjZSk7XG5cbiAgICAgICAgICAgIHRoaXMuZXZhbHVhdGVEYXRhc291cmNlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldERhdGFzb3VyY2VzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5kYXRhc291cmNlU2VydmljZS5nZXREYXRhc291cmNlcyhcbiAgICAgICAgICAgIHRoaXMuc2VhcmNoVGV4dC5nZXRWYWx1ZSgpIHx8ICcnLFxuICAgICAgICAgICAgJzEwJyxcbiAgICAgICAgICAgICcwJ1xuICAgICAgICApLnBpcGUobWFwKChkYXRhc291cmNlczogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRhdGFzb3VyY2VzO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldERvY3VtZW50UGFyc2VycygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0YXNvdXJjZVNlcnZpY2UuZ2V0RGF0YXNvdXJjZXMoXG4gICAgICAgICAgICB0aGlzLnNlYXJjaFRleHQuZ2V0VmFsdWUoKSB8fCAnJyxcbiAgICAgICAgICAgICcxMCcsXG4gICAgICAgICAgICAnMCdcbiAgICAgICAgKS5waXBlKG1hcCgoZGF0YXNvdXJjZXM6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlOiAnUGxlbmlwb3QgQnVjaGFyZXN0IDIyJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiAncGxlbmlwb3RCdWNoYXJlc3QyMidcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICdJVFUgU3R1ZHkgR3JvdXAnLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6ICdpdHVzdHVkeWdyb3VwJ1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZTogJ0lFVEYgSW50ZXJuZXQgRHJhZnRzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiAnaWV0ZmludGVybmV0ZHJhZnRzJ1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZTogJ1dUU0EnLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6ICd3dHNhJ1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZTogJ1dUREMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6ICd3dGRjJ1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyB1cGxvYWREYXRhc291cmNlRG9jdW1lbnRzKGZvcm1EYXRhKSB7XG4gICAgICAgIHRoaXMudXBsb2FkaW5nID0gdHJ1ZTtcbiAgICAgICAgY29uc3QgdHJhY2tpbmdLZXkgPSBEYXRlLm5vdygpICsgKE1hdGgucmFuZG9tKCkgKyAxKS50b1N0cmluZygzNikuc3Vic3RyKDIsIDUpO1xuXG4gICAgICAgIHRoaXMuZGF0YXNvdXJjZVNlcnZpY2UudXBsb2FkRGF0YXNvdXJjZURvY3VtZW50cyh0aGlzLmRhdGFzb3VyY2VLZXksIGZvcm1EYXRhLCB0cmFja2luZ0tleSkuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgICAgIC8vIElnbm9yZSAtIHdlIGhhdmUgc2V0IG9mZiBhIGxvbmctcnVubmluZyB0YXNrIHdoaWNoIHdlIGFyZSB0cmFja2luZyBiZWxvd1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLmZpbGVzID0gbnVsbDtcblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0U3ViID0gdGhpcy5kYXRhc291cmNlU2VydmljZS5nZXREYXRhVHJhY2tpbmdSZXN1bHRzKHRyYWNraW5nS2V5KS5zdWJzY3JpYmUoKHJlczogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXBsb2FkUmVzdWx0cyA9IHJlcztcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlcyAmJiByZXMuc3RhdHVzID09PSAnQ09NUExFVEVEJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51cGxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdFN1Yi51bnN1YnNjcmliZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5mYWlsZWRSZXN1bHRzID0gcmVzLnByb2dyZXNzRGF0YS5mYWlsZWQgfHwgW107XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51cGxvYWRSZXN1bHRzID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZhaWxlZFJlc3VsdHMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sIDUwMDApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9LCAxMDApO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGV2YWx1YXRlRGF0YXNvdXJjZShyZXNldFBhZ2VyID0gZmFsc2UpIHtcbiAgICAgICAgaWYgKHJlc2V0UGFnZXIpIHtcbiAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gMDtcbiAgICAgICAgICAgIHRoaXMucGFnZSA9IDE7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmRhdGFzb3VyY2UubGltaXQgPSB0aGlzLmxpbWl0O1xuICAgICAgICB0aGlzLmRhdGFzb3VyY2Uub2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIHRoaXMuZXZhbHVhdGVkRGF0YXNvdXJjZSA9IGF3YWl0IHRoaXMuZGF0YXNvdXJjZVNlcnZpY2UuZXZhbHVhdGVEYXRhc291cmNlKHRoaXMuZGF0YXNvdXJjZSk7XG4gICAgICAgIHRoaXMuZXZhbHVhdGVkRGF0YXNvdXJjZS5hbGxEYXRhLm1hcChkYXRhID0+IHtcbiAgICAgICAgICAgIGlmIChkYXRhLmZpbGVfc2l6ZSkge1xuICAgICAgICAgICAgICAgIGRhdGEuZmlsZV9zaXplID0gdGhpcy5odW1hbkZpbGVTaXplKGRhdGEuZmlsZV9zaXplKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkYXRhLmZpbGVfdHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC53b3JkcHJvY2Vzc2luZ21sLmRvY3VtZW50Jykge1xuICAgICAgICAgICAgICAgIGRhdGEuZmlsZV90eXBlID0gJ2FwcGxpY2F0aW9uL2RvY3gnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuZW5kT2ZSZXN1bHRzID0gdGhpcy5ldmFsdWF0ZWREYXRhc291cmNlLmFsbERhdGEubGVuZ3RoIDwgdGhpcy5saW1pdDtcbiAgICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwicC02IGJnLXdoaXRlIGJvcmRlci1iIGJvcmRlci1ncmF5LTIwMFwiPlxuICAgIDxkaXYgY2xhc3M9XCJtZDpmbGV4IG1kOml0ZW1zLWNlbnRlciBtZDpqdXN0aWZ5LWJldHdlZW4gbWQ6c3BhY2UteC01XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLXN0YXJ0IGZsZXgtMVwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB0LTEuNVwiPlxuICAgICAgICAgICAgICAgIDxoMSBjbGFzcz1cInRleHQtMnhsIGZvbnQtYm9sZCB0ZXh0LWdyYXktOTAwXCI+XG4gICAgICAgICAgICAgICAgICAgIHt7IWRhdGFzb3VyY2VLZXkgPyAnRG9jdW1lbnQgRGF0YXNvdXJjZScgOiAoZGF0YXNvdXJjZS50aXRsZSB8fCAnRG9jdW1lbnQgRGF0YXNvdXJjZScpfX1cbiAgICAgICAgICAgICAgICA8L2gxPlxuICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwidGV4dC1zbSBmb250LW1lZGl1bSB0ZXh0LWdyYXktNTAwXCI+XG4gICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCIhZGF0YXNvdXJjZUtleVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgVXBsb2FkIHlvdXIgZG9jdW1lbnRzIHVzaW5nIHRoZSBmb3JtIGJlbG93LlxuICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiZGF0YXNvdXJjZUtleVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgVmlldyB5b3VyIGV4aXN0aW5nIGRvY3VtZW50cyBiZWxvdyBhbmQgYWRqdXN0IGFueSBkb2N1bWVudCBzZXR0aW5ncyBoZXJlLlxuICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm10LTYgZmxleCBmbGV4LWNvbC1yZXZlcnNlIGp1c3RpZnktc3RyZXRjaFwiICpuZ0lmPVwiZGF0YXNvdXJjZUtleVwiPlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cInNob3dVcGxvYWQgPSAhc2hvd1VwbG9hZFwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiaW5saW5lLWZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyIHB4LTQgcHktMiBib3JkZXIgYm9yZGVyLXRyYW5zcGFyZW50IHRleHQtc20gZm9udC1tZWRpdW0gcm91bmRlZC1tZCBzaGFkb3ctc20gdGV4dC13aGl0ZSBiZy1wcmltYXJ5IGZvY3VzOm91dGxpbmUtbm9uZVwiPlxuICAgICAgICAgICAgICAgIFVwbG9hZCBBZGRpdGlvbmFsIERvY3VtZW50c1xuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC9kaXY+XG5cbjxkaXYgY2xhc3M9XCJiZy1ibHVlLTUwIHAtNFwiICpuZ0lmPVwidXBsb2FkaW5nXCI+XG4gICAgPGRpdiBjbGFzcz1cImZsZXhcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZsZXgtc2hyaW5rLTBcIj5cbiAgICAgICAgICAgIDwhLS0gSGVyb2ljb24gbmFtZTogc29saWQvaW5mb3JtYXRpb24tY2lyY2xlIC0tPlxuICAgICAgICAgICAgPHN2ZyBjbGFzcz1cImgtNSB3LTUgdGV4dC1wcmltYXJ5XCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMjAgMjBcIlxuICAgICAgICAgICAgICAgICBmaWxsPVwiY3VycmVudENvbG9yXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+XG4gICAgICAgICAgICAgICAgPHBhdGggZmlsbC1ydWxlPVwiZXZlbm9kZFwiXG4gICAgICAgICAgICAgICAgICAgICAgZD1cIk0xOCAxMGE4IDggMCAxMS0xNiAwIDggOCAwIDAxMTYgMHptLTctNGExIDEgMCAxMS0yIDAgMSAxIDAgMDEyIDB6TTkgOWExIDEgMCAwMDAgMnYzYTEgMSAwIDAwMSAxaDFhMSAxIDAgMTAwLTJ2LTNhMSAxIDAgMDAtMS0xSDl6XCJcbiAgICAgICAgICAgICAgICAgICAgICBjbGlwLXJ1bGU9XCJldmVub2RkXCIvPlxuICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwibWwtMyB3LWZ1bGxcIj5cbiAgICAgICAgICAgIDxwIGNsYXNzPVwidGV4dC1zbSB0ZXh0LXByaW1hcnkgZm9udC1tZWRpdW1cIj5Qcm9ncmVzczwvcD5cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJ1cGxvYWRSZXN1bHRzICYmIHVwbG9hZFJlc3VsdHMucHJvZ3Jlc3NEYXRhXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtcHJpbWFyeSBteS0yXCI+VXBsb2FkZWQge3t1cGxvYWRSZXN1bHRzLnByb2dyZXNzRGF0YS5jb21wbGV0ZWR9fVxuICAgICAgICAgICAgICAgICAgICAve3t1cGxvYWRSZXN1bHRzLnByb2dyZXNzRGF0YS50b3RhbH19PC9kaXY+XG4gICAgICAgICAgICAgICAgPG1hdC1wcm9ncmVzcy1iYXIgY2xhc3M9XCJ3LWZ1bGwgbXktNFwiIG1vZGU9XCJkZXRlcm1pbmF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cIih1cGxvYWRSZXN1bHRzLnByb2dyZXNzRGF0YS5jb21wbGV0ZWQvdXBsb2FkUmVzdWx0cy5wcm9ncmVzc0RhdGEudG90YWwpICogMTAwXCI+PC9tYXQtcHJvZ3Jlc3MtYmFyPlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCIhdXBsb2FkUmVzdWx0cyB8fCAhdXBsb2FkUmVzdWx0cy5wcm9ncmVzc0RhdGFcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1wcmltYXJ5IG15LTJcIj5QcmVwYXJpbmcgVXBsb2FkLi4uPC9kaXY+XG4gICAgICAgICAgICAgICAgPG1hdC1wcm9ncmVzcy1iYXIgY2xhc3M9XCJ3LWZ1bGwgbXktNFwiIG1vZGU9XCJidWZmZXJcIj48L21hdC1wcm9ncmVzcy1iYXI+XG4gICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbjwvZGl2PlxuXG48ZGl2IGNsYXNzPVwiYmctZ3JlZW4tNTAgcC00XCIgKm5nSWY9XCIhZmFpbGVkUmVzdWx0cy5sZW5ndGggJiYgdXBsb2FkUmVzdWx0cyAmJiAhdXBsb2FkaW5nXCI+XG4gICAgPGRpdiBjbGFzcz1cImZsZXhcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZsZXgtc2hyaW5rLTBcIj5cbiAgICAgICAgICAgIDwhLS0gSGVyb2ljb24gbmFtZTogc29saWQvY2hlY2stY2lyY2xlIC0tPlxuICAgICAgICAgICAgPHN2ZyBjbGFzcz1cImgtNSB3LTUgdGV4dC1ncmVlbi00MDBcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAyMCAyMFwiXG4gICAgICAgICAgICAgICAgIGZpbGw9XCJjdXJyZW50Q29sb3JcIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICAgICAgICA8cGF0aCBmaWxsLXJ1bGU9XCJldmVub2RkXCJcbiAgICAgICAgICAgICAgICAgICAgICBkPVwiTTEwIDE4YTggOCAwIDEwMC0xNiA4IDggMCAwMDAgMTZ6bTMuNzA3LTkuMjkzYTEgMSAwIDAwLTEuNDE0LTEuNDE0TDkgMTAuNTg2IDcuNzA3IDkuMjkzYTEgMSAwIDAwLTEuNDE0IDEuNDE0bDIgMmExIDEgMCAwMDEuNDE0IDBsNC00elwiXG4gICAgICAgICAgICAgICAgICAgICAgY2xpcC1ydWxlPVwiZXZlbm9kZFwiLz5cbiAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm1sLTNcIj5cbiAgICAgICAgICAgIDxoMyBjbGFzcz1cInRleHQtc20gZm9udC1tZWRpdW0gdGV4dC1ncmVlbi04MDBcIj5VcGxvYWQgY29tcGxldGVkPC9oMz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtdC0yIHRleHQtc20gdGV4dC1ncmVlbi03MDBcIj5cbiAgICAgICAgICAgICAgICA8cD48Yj57e3VwbG9hZFJlc3VsdHMucHJvZ3Jlc3NEYXRhLmNvbXBsZXRlZH19PC9iPiBmaWxlcyB3ZXJlIHByb2Nlc3NlZCBzdWNjZXNzZnVsbHkgb3V0IG9mXG4gICAgICAgICAgICAgICAgICAgIDxiPnt7dXBsb2FkUmVzdWx0cy5wcm9ncmVzc0RhdGEudG90YWx9fTwvYj4gdXBsb2FkZWQgaXRlbXMuPC9wPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC9kaXY+XG5cbjxkaXYgY2xhc3M9XCJiZy1yZWQtNTAgcC00XCIgKm5nSWY9XCJmYWlsZWRSZXN1bHRzLmxlbmd0aCAmJiB1cGxvYWRSZXN1bHRzXCI+XG4gICAgPGRpdiBjbGFzcz1cImZsZXhcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZsZXgtc2hyaW5rLTBcIj5cbiAgICAgICAgICAgIDwhLS0gSGVyb2ljb24gbmFtZTogc29saWQveC1jaXJjbGUgLS0+XG4gICAgICAgICAgICA8c3ZnIGNsYXNzPVwiaC01IHctNSB0ZXh0LXJlZC00MDBcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAyMCAyMFwiIGZpbGw9XCJjdXJyZW50Q29sb3JcIlxuICAgICAgICAgICAgICAgICBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICAgICAgICA8cGF0aCBmaWxsLXJ1bGU9XCJldmVub2RkXCJcbiAgICAgICAgICAgICAgICAgICAgICBkPVwiTTEwIDE4YTggOCAwIDEwMC0xNiA4IDggMCAwMDAgMTZ6TTguNzA3IDcuMjkzYTEgMSAwIDAwLTEuNDE0IDEuNDE0TDguNTg2IDEwbC0xLjI5MyAxLjI5M2ExIDEgMCAxMDEuNDE0IDEuNDE0TDEwIDExLjQxNGwxLjI5MyAxLjI5M2ExIDEgMCAwMDEuNDE0LTEuNDE0TDExLjQxNCAxMGwxLjI5My0xLjI5M2ExIDEgMCAwMC0xLjQxNC0xLjQxNEwxMCA4LjU4NiA4LjcwNyA3LjI5M3pcIlxuICAgICAgICAgICAgICAgICAgICAgIGNsaXAtcnVsZT1cImV2ZW5vZGRcIi8+XG4gICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJtbC0zXCI+XG4gICAgICAgICAgICA8aDMgY2xhc3M9XCJ0ZXh0LXNtIGZvbnQtbWVkaXVtIHRleHQtcmVkLTgwMFwiPlRoZXJlIHdlcmUge3tmYWlsZWRSZXN1bHRzLmxlbmd0aH19IGVycm9ycyB3aXRoIHlvdXJcbiAgICAgICAgICAgICAgICBzdWJtaXNzaW9uPC9oMz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtdC0yIHRleHQtc20gdGV4dC1yZWQtNzAwXCI+XG4gICAgICAgICAgICAgICAgPHVsIHJvbGU9XCJsaXN0XCIgY2xhc3M9XCJsaXN0LWRpc2MgcGwtNSBzcGFjZS15LTFcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxpICpuZ0Zvcj1cImxldCBmYWlsZWRSZXN1bHQgb2YgZmFpbGVkUmVzdWx0c1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAge3tmYWlsZWRSZXN1bHQubWVzc2FnZX19XG4gICAgICAgICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICAgICAgPC91bD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbjwvZGl2PlxuXG48ZGl2ICpuZ0lmPVwic2hvd1VwbG9hZFwiXG4gICAgIGNsYXNzPVwic3BhY2UteS04IHAtNiBiZy1ncmF5LTUwIGJvcmRlci1iXCI+XG4gICAgPGRpdiBjbGFzcz1cInNwYWNlLXktOCBzbTpzcGFjZS15LTVcIj5cbiAgICAgICAgPGRpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzcGFjZS15LTYgc206c3BhY2UteS01XCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNtOmdyaWQgc206Z3JpZC1jb2xzLTMgc206Z2FwLTQgc206aXRlbXMtc3RhcnRcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiYmxvY2sgdGV4dC1zbSBmb250LW1lZGl1bSB0ZXh0LWdyYXktNzAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBVcGxvYWQgRG9jdW1lbnRzXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC14cyBmb250LW5vcm1hbCB0ZXh0LWdyYXktNTAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQWRkaXRpb25hbCBkb2N1bWVudHMgdG8gYmUgcHJvY2Vzc2VkLlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtdC0xIHNtOm10LTAgc206Y29sLXNwYW4tMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cIiFmaWxlcyB8fCAhZmlsZXMubGVuZ3RoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRyb3ApPVwiZHJvcEhhbmRsZXIoJGV2ZW50KVwiIChkcmFnb3Zlcik9XCJkcmFnT3ZlckhhbmRsZXIoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwidy1mdWxsIGZsZXgganVzdGlmeS1jZW50ZXIgcHgtNiBwdC01IHBiLTYgYm9yZGVyLTIgYm9yZGVyLWdyYXktMzAwIGJvcmRlci1kYXNoZWQgcm91bmRlZC1tZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzcGFjZS15LTEgdGV4dC1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyBjbGFzcz1cIm14LWF1dG8gaC0xMiB3LTEyIHRleHQtZ3JheS00MDBcIiBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBmaWxsPVwibm9uZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld0JveD1cIjAgMCA0OCA0OFwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTI4IDhIMTJhNCA0IDAgMDAtNCA0djIwbTMyLTEydjhtMCAwdjhhNCA0IDAgMDEtNCA0SDEyYTQgNCAwIDAxLTQtNHYtNG0zMi00bC0zLjE3Mi0zLjE3MmE0IDQgMCAwMC01LjY1NiAwTDI4IDI4TTggMzJsOS4xNzItOS4xNzJhNCA0IDAgMDE1LjY1NiAwTDI4IDI4bTAgMGw0IDRtNC0yNGg4bS00LTR2OG0tMTIgNGguMDJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS13aWR0aD1cIjJcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIi8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCB0ZXh0LXNtIHRleHQtZ3JheS02MDBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwicmVsYXRpdmUgY3Vyc29yLXBvaW50ZXIgcm91bmRlZC1tZCBmb250LW1lZGl1bSB0ZXh0LXNlY29uZGFyeSBmb2N1cy13aXRoaW46b3V0bGluZS1ub25lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+U2VsZWN0IGZpbGUocykgdG8gdXBsb2FkPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBuYW1lPVwiYWRkaXRpb25hbFVwbG9hZFwiIG11bHRpcGxlIHR5cGU9XCJmaWxlXCIgY2xhc3M9XCJzci1vbmx5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJmaWxlVXBsb2FkKCRldmVudClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cInBsLTEgbWItMFwiPm9yIGRyYWcgYW5kIGRyb3A8L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cInRleHQteHMgdGV4dC1ncmF5LTUwMFwiPi5kb2N4LCAudHh0LCAucGZkLCAuemlwPC9wPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiZmlsZXMgJiYgZmlsZXMubGVuZ3RoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJvdmVyZmxvdy1oaWRkZW4gc2hhZG93IHJpbmctMSByaW5nLWJsYWNrIHJpbmctb3BhY2l0eS01IG1kOnJvdW5kZWQtbGdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGFibGUgY2xhc3M9XCJtaW4tdy1mdWxsIGRpdmlkZS15IGRpdmlkZS1ncmF5LTMwMCBibG9jayBvdmVyZmxvdy15LWF1dG8gbWF4LWgtNDhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoZWFkIGNsYXNzPVwiYmctZ3JheS01MFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGggc2NvcGU9XCJjb2xcIiBjb2xzcGFuPVwiMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJzdGlja3kgdG9wLTAgei0xMCBiZy1ncmF5LTEwMCBweS0yIHBsLTQgcHItMyB0ZXh0LWxlZnQgdGV4dC1zbSBmb250LXNlbWlib2xkIHRleHQtZ3JheS05MDAgc206cGwtNlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlbGVjdGVkIEZpbGUgUHJldmlld1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC14cyB0ZXh0LWdyYXktNTAwIGxvd2VyY2FzZSBtbC00IGZvbnQtbm9ybWFsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaWNrIDxzcGFuIGNsYXNzPVwiZm9udC1tZWRpdW1cIj4nVXBsb2FkIEZpbGVzJzwvc3Bhbj4gdG8gdXBsb2FkIHRoZSBzZWxlY3RlZCBmaWxlcy48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RoZWFkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGJvZHkgY2xhc3M9XCJkaXZpZGUteSBkaXZpZGUtZ3JheS0yMDAgYmctd2hpdGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRyICpuZ0Zvcj1cImxldCBmaWxlIG9mIGZpbGVzOyBsZXQgaSA9IGluZGV4XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJ3aGl0ZXNwYWNlLW5vd3JhcCBweS0yIHBsLTQgcHItMyB0ZXh0LXhzIGZvbnQtbWVkaXVtIHRleHQtZ3JheS05MDAgc206cGwtNlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7ZmlsZS5uYW1lfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJyZWxhdGl2ZSB3aGl0ZXNwYWNlLW5vd3JhcCBweS0yIHBsLTMgcHItNCB0ZXh0LXJpZ2h0IHRleHQtc20gZm9udC1tZWRpdW0gc206cHItNlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIChjbGljayk9XCJyZW1vdmVGaWxlKGkpXCIgY2xhc3M9XCJ0ZXh0LWRhbmdlclwiPlJlbW92ZTwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90Ym9keT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RhYmxlPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZsZXgganVzdGlmeS1lbmRcIj5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJzaG93VXBsb2FkID0gZmFsc2U7ZmlsZXMgPSBudWxsXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJiZy13aGl0ZSBweS0yIHB4LTQgYm9yZGVyIGJvcmRlci1ncmF5LTMwMCByb3VuZGVkLW1kIHNoYWRvdy1zbSB0ZXh0LXNtIGZvbnQtbWVkaXVtIHRleHQtZ3JheS03MDAgaG92ZXI6YmctZ3JheS01MCBmb2N1czpvdXRsaW5lLW5vbmVcIj5cbiAgICAgICAgICAgICAgICBDYW5jZWxcbiAgICAgICAgICAgIDwvYnV0dG9uPlxuXG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJzdWJtaXRcIiBbZGlzYWJsZWRdPVwiIWZpbGVzXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJkaXNhYmxlZDpvcGFjaXR5LTUwIG1sLTMgaW5saW5lLWZsZXgganVzdGlmeS1jZW50ZXIgcHktMiBweC00IGJvcmRlciBib3JkZXItdHJhbnNwYXJlbnQgc2hhZG93LXNtIHRleHQtc20gZm9udC1tZWRpdW0gcm91bmRlZC1tZCB0ZXh0LXdoaXRlIGJnLXNlY29uZGFyeSBmb2N1czpvdXRsaW5lLW5vbmVcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwidXBsb2FkRmlsZXMoKVwiPlVwbG9hZCBGaWxlc1xuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC9kaXY+XG5cbjxkaXYgY2xhc3M9XCJ0cmFuc2Zvcm1hdGlvbi1saXN0aW5nIHB5LTIgYmctZ3JheS01MCBjdXJzb3ItcG9pbnRlclwiXG4gICAgIChjbGljayk9XCJzaG93U2V0dGluZ3MgPSAhc2hvd1NldHRpbmdzXCIgW25nQ2xhc3NdPVwieydib3JkZXItYic6ICFzaG93U2V0dGluZ3N9XCI+XG4gICAgPGEgY2xhc3M9XCJsaXN0LXRpdGxlIGZsZXggaXRlbXMtY2VudGVyXCI+XG4gICAgICAgIFNldHRpbmdzJm5ic3A7XG4gICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cIiFzaG93U2V0dGluZ3NcIj5leHBhbmRfbW9yZTwvbWF0LWljb24+XG4gICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cInNob3dTZXR0aW5nc1wiPmV4cGFuZF9sZXNzPC9tYXQtaWNvbj5cbiAgICA8L2E+XG4gICAgPGRpdiBjbGFzcz1cIm1sLTYgdGV4dC14cyB0ZXh0LWdyYXktNTAwXCI+XG4gICAgICAgIEFkanVzdCB0aGUgcnVsZXMgYXJvdW5kIGhvdyB0aGUgdXBsb2FkZWQgZG9jdW1lbnRzIHdpbGxcbiAgICAgICAgYmUgcHJvY2Vzc2VkLlxuICAgIDwvZGl2PlxuPC9kaXY+XG5cbjxkaXYgKm5nSWY9XCJzaG93U2V0dGluZ3NcIiBbbmdDbGFzc109XCJ7J2JvcmRlci1iJzogc2hvd1NldHRpbmdzfVwiXG4gICAgIGNsYXNzPVwic3BhY2UteS04IGRpdmlkZS15IGRpdmlkZS1ncmF5LTIwMCBwLTYgYmctZ3JheS01MFwiPlxuICAgIDxkaXYgY2xhc3M9XCJzcGFjZS15LTggZGl2aWRlLXkgZGl2aWRlLWdyYXktMjAwIHNtOnNwYWNlLXktNVwiPlxuICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNwYWNlLXktNiBzbTpzcGFjZS15LTVcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic206Z3JpZCBzbTpncmlkLWNvbHMtMyBzbTpnYXAtNCBzbTppdGVtcy1zdGFydFwiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJibG9jayB0ZXh0LXNtIGZvbnQtbWVkaXVtIHRleHQtZ3JheS03MDAgc206bXQtcHggc206cHQtMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgVGl0bGVcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXhzIGZvbnQtbm9ybWFsIHRleHQtZ3JheS01MDBcIj5FbnRlciB0aGUgbmFtZSB0byBpZGVudGlmeSB0aGlzIGRhdGEgc291cmNlPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtdC0xIHNtOm10LTAgc206Y29sLXNwYW4tMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgWyhuZ01vZGVsKV09XCJkYXRhc291cmNlLnRpdGxlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1heC13LWxnIGJsb2NrIHctZnVsbCBzaGFkb3ctc20gZm9jdXM6cmluZy1pbmRpZ28tNTAwIGZvY3VzOmJvcmRlci1pbmRpZ28tNTAwIHNtOm1heC13LXhzIHNtOnRleHQtc20gYm9yZGVyLWdyYXktMzAwIHJvdW5kZWQtbWRcIj5cblxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCIhZGF0YXNvdXJjZUtleVwiXG4gICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInNtOmdyaWQgc206Z3JpZC1jb2xzLTMgc206Z2FwLTQgc206aXRlbXMtc3RhcnQgc206Ym9yZGVyLXQgc206Ym9yZGVyLWdyYXktMjAwIHNtOnB0LTVcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiYmxvY2sgdGV4dC1zbSBmb250LW1lZGl1bSB0ZXh0LWdyYXktNzAwIHNtOm10LXB4IHNtOnB0LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIFVwbG9hZCBEb2N1bWVudHNcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXhzIGZvbnQtbm9ybWFsIHRleHQtZ3JheS01MDBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGUgZG9jdW1lbnRzIHRvIGJlIHByb2Nlc3NlZC5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXQtMSBzbTptdC0wIHNtOmNvbC1zcGFuLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCIhZmlsZXMgfHwgIWZpbGVzLmxlbmd0aFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIChkcm9wKT1cImRyb3BIYW5kbGVyKCRldmVudClcIiAoZHJhZ292ZXIpPVwiZHJhZ092ZXJIYW5kbGVyKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInctZnVsbCBmbGV4IGp1c3RpZnktY2VudGVyIHB4LTYgcHQtNSBwYi02IGJvcmRlci0yIGJvcmRlci1ncmF5LTMwMCBib3JkZXItZGFzaGVkIHJvdW5kZWQtbWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3BhY2UteS0xIHRleHQtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgY2xhc3M9XCJteC1hdXRvIGgtMTIgdy0xMiB0ZXh0LWdyYXktNDAwXCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgZmlsbD1cIm5vbmVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdCb3g9XCIwIDAgNDggNDhcIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZD1cIk0yOCA4SDEyYTQgNCAwIDAwLTQgNHYyMG0zMi0xMnY4bTAgMHY4YTQgNCAwIDAxLTQgNEgxMmE0IDQgMCAwMS00LTR2LTRtMzItNGwtMy4xNzItMy4xNzJhNCA0IDAgMDAtNS42NTYgMEwyOCAyOE04IDMybDkuMTcyLTkuMTcyYTQgNCAwIDAxNS42NTYgMEwyOCAyOG0wIDBsNCA0bTQtMjRoOG0tNC00djhtLTEyIDRoLjAyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2Utd2lkdGg9XCIyXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggdGV4dC1zbSB0ZXh0LWdyYXktNjAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInJlbGF0aXZlIGN1cnNvci1wb2ludGVyIHJvdW5kZWQtbWQgZm9udC1tZWRpdW0gdGV4dC1zZWNvbmRhcnkgZm9jdXMtd2l0aGluOm91dGxpbmUtbm9uZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPlNlbGVjdCBmaWxlKHMpIHRvIHVwbG9hZDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgbmFtZT1cImFkZGl0aW9uYWxVcGxvYWRcIiBtdWx0aXBsZSB0eXBlPVwiZmlsZVwiIGNsYXNzPVwic3Itb25seVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwiZmlsZVVwbG9hZCgkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJwbC0xIG1iLTBcIj5vciBkcmFnIGFuZCBkcm9wPC9wPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJ0ZXh0LXhzIHRleHQtZ3JheS01MDBcIj4uZG9jeCwgLnR4dCwgLnBmZCwgLnppcDwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImZpbGVzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJvdmVyZmxvdy1oaWRkZW4gc2hhZG93IHJpbmctMSByaW5nLWJsYWNrIHJpbmctb3BhY2l0eS01IG1kOnJvdW5kZWQtbGdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGFibGUgY2xhc3M9XCJtaW4tdy1mdWxsIGRpdmlkZS15IGRpdmlkZS1ncmF5LTMwMCBibG9jayBvdmVyZmxvdy15LWF1dG8gbWF4LWgtNDhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoZWFkIGNsYXNzPVwiYmctZ3JheS01MFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGggc2NvcGU9XCJjb2xcIiBjb2xzcGFuPVwiMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJzdGlja3kgdG9wLTAgei0xMCBiZy1ncmF5LTEwMCBweS0yIHBsLTQgcHItMyB0ZXh0LWxlZnQgdGV4dC1zbSBmb250LXNlbWlib2xkIHRleHQtZ3JheS05MDAgc206cGwtNlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlbGVjdGVkIEZpbGUgUHJldmlld1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC14cyB0ZXh0LWdyYXktNTAwIGxvd2VyY2FzZSBtbC00IGZvbnQtbm9ybWFsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaWNrIDxzcGFuIGNsYXNzPVwiZm9udC1tZWRpdW1cIj4nVXBsb2FkIEZpbGVzJzwvc3Bhbj4gdG8gdXBsb2FkIHRoZSBzZWxlY3RlZCBmaWxlcy48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RoZWFkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGJvZHkgY2xhc3M9XCJkaXZpZGUteSBkaXZpZGUtZ3JheS0yMDAgYmctd2hpdGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRyICpuZ0Zvcj1cImxldCBmaWxlIG9mIGZpbGVzOyBsZXQgaSA9IGluZGV4XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJ3aGl0ZXNwYWNlLW5vd3JhcCBweS0yIHBsLTQgcHItMyB0ZXh0LXhzIGZvbnQtbWVkaXVtIHRleHQtZ3JheS05MDAgc206cGwtNlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7ZmlsZS5uYW1lfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJyZWxhdGl2ZSB3aGl0ZXNwYWNlLW5vd3JhcCBweS0yIHBsLTMgcHItNCB0ZXh0LXJpZ2h0IHRleHQtc20gZm9udC1tZWRpdW0gc206cHItNlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIChjbGljayk9XCJyZW1vdmVGaWxlKGkpXCIgY2xhc3M9XCJ0ZXh0LWRhbmdlclwiPlJlbW92ZTwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGJvZHk+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90YWJsZT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJzaG93Q3VzdG9tUGFyc2VyXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzbTpncmlkIHNtOmdyaWQtY29scy0zIHNtOmdhcC00IHNtOml0ZW1zLXN0YXJ0IHNtOmJvcmRlci10IHNtOmJvcmRlci1ncmF5LTIwMCBzbTpwdC01XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJibG9jayB0ZXh0LXNtIGZvbnQtbWVkaXVtIHRleHQtZ3JheS03MDAgc206bXQtcHggc206cHQtMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEN1c3RvbSBEb2N1bWVudCBQYXJzZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC14cyBmb250LW5vcm1hbCB0ZXh0LWdyYXktNTAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVzZSBhIGN1c3RvbSBkb2N1bWVudCBwYXJzZXIgdG8gcHJvY2VzcyB0aGUgZG9jdW1lbnRzLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtdC0xIHNtOm10LTAgc206Y29sLXNwYW4tMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cIm1iLTQgdGV4dC1zbVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZWxlY3QgQ3VzdG9tIERvY3VtZW50IFBhcnNlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBbbWF0QXV0b2NvbXBsZXRlXT1cImF1dG9QYXJzZXJzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiZGF0YXNvdXJjZS5jb25maWcuY3VzdG9tRG9jdW1lbnRQYXJzZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGtleXVwKT1cInNlYXJjaFBhcnNlci5uZXh0KCRldmVudC50YXJnZXQudmFsdWUpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiU2VhcmNoIGZvciBhIGN1c3RvbSBwYXJzZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1hdXRvY29tcGxldGUgI2F1dG9QYXJzZXJzPVwibWF0QXV0b2NvbXBsZXRlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiAqbmdGb3I9XCJsZXQgcGFyc2VyIG9mIGRvY3VtZW50UGFyc2Vyc1wiIFt2YWx1ZV09XCJwYXJzZXIudmFsdWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e3BhcnNlci50aXRsZX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWF1dG9jb21wbGV0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNtYWxsIGNsYXNzPVwiZm9udC1ub3JtYWxcIj5TdGFydCB0eXBpbmcgbmFtZSB0byB2aWV3IGF2YWlsYWJsZSBwYXJzZXJzPC9zbWFsbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiIWRhdGFzb3VyY2UuY29uZmlnLmN1c3RvbURvY3VtZW50UGFyc2VyXCI+XG5cblxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic206Z3JpZCBzbTpncmlkLWNvbHMtMyBzbTpnYXAtNCBzbTppdGVtcy1zdGFydCBzbTpib3JkZXItdCBzbTpib3JkZXItZ3JheS0yMDAgc206cHQtNVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiYmxvY2sgdGV4dC1zbSBmb250LW1lZGl1bSB0ZXh0LWdyYXktNzAwIHNtOm10LXB4IHNtOnB0LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmRleGluZ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXhzIGZvbnQtbm9ybWFsIHRleHQtZ3JheS01MDBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2V0IHdoZXRoZXIgeW91IHdhbnQgdGhlIGNvbnRlbnQgb2YgdGhlIGRvY3VtZW50cyB0byBiZSBpbmRleGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm10LTEgc206bXQtMCBzbTpjb2wtc3Bhbi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1jaGVja2JveCBjbGFzcz1cImJsb2NrIG1iLTRcIiBbKG5nTW9kZWwpXT1cImRhdGFzb3VyY2UuY29uZmlnLmluZGV4Q29udGVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJpbmRleERvY3VtZW50Q2hhbmdlKCRldmVudClcIj5JbmRleCBEb2N1bWVudFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb250ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtY2hlY2tib3g+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImRhdGFzb3VyY2UuY29uZmlnLmluZGV4Q29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWF4LXctbGcgZmxleCByb3VuZGVkLW1kIHNoYWRvdy1zbSBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImlubGluZS1mbGV4IGl0ZW1zLWNlbnRlciBweC0zIHJvdW5kZWQtbC1tZCBib3JkZXIgYm9yZGVyLXItMCBib3JkZXItZ3JheS0zMDAgYmctZ3JheS01MCB0ZXh0LWdyYXktNTAwIHNtOnRleHQtc21cIj4gTWluIHBocmFzZSBsZW5ndGggKHdvcmRzKSA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiIG5hbWU9XCJtaW5QaHJhc2VcIiBbbWluXT1cIjFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiZGF0YXNvdXJjZS5jb25maWcubWluUGhyYXNlTGVuZ3RoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsZXgtMSBibG9jayB3LWZ1bGwgbWluLXctMCByb3VuZGVkLW5vbmUgcm91bmRlZC1yLW1kIHNtOnRleHQtc20gYm9yZGVyLWdyYXktMzAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWF4LXctbGcgZmxleCByb3VuZGVkLW1kIHNoYWRvdy1zbVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJpbmxpbmUtZmxleCBpdGVtcy1jZW50ZXIgcHgtMyByb3VuZGVkLWwtbWQgYm9yZGVyIGJvcmRlci1yLTAgYm9yZGVyLWdyYXktMzAwIGJnLWdyYXktNTAgdGV4dC1ncmF5LTUwMCBzbTp0ZXh0LXNtXCI+IE1heCBwaHJhc2UgbGVuZ3RoICh3b3JkcykgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBuYW1lPVwibWF4UGhyYXNlXCIgW21pbl09XCIxXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImRhdGFzb3VyY2UuY29uZmlnLm1heFBocmFzZUxlbmd0aFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbGV4LTEgYmxvY2sgdy1mdWxsIG1pbi13LTAgcm91bmRlZC1ub25lIHJvdW5kZWQtci1tZCBzbTp0ZXh0LXNtIGJvcmRlci1ncmF5LTMwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzbTpncmlkIHNtOmdyaWQtY29scy0zIHNtOmdhcC00IHNtOml0ZW1zLXN0YXJ0IHNtOmJvcmRlci10IHNtOmJvcmRlci1ncmF5LTIwMCBzbTpwdC01XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJibG9jayB0ZXh0LXNtIGZvbnQtbWVkaXVtIHRleHQtZ3JheS03MDAgc206bXQtcHggc206cHQtMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIENodW5raW5nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQteHMgZm9udC1ub3JtYWwgdGV4dC1ncmF5LTUwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXQgd2hldGhlciB5b3Ugd2FudCB0byBzcGxpdCB0aGUgZG9jdW1lbnRzIGludG8gY2h1bmtzIGZvciBhbmFseXNpc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtdC0xIHNtOm10LTAgc206Y29sLXNwYW4tMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggY2xhc3M9XCJibG9jayBtYi00XCIgWyhuZ01vZGVsKV09XCJkYXRhc291cmNlLmNvbmZpZy5jaHVua0NvbnRlbnRcIiAobmdNb2RlbENoYW5nZSk9XCJjaHVua0NvbnRlbnRDaGFuZ2UoJGV2ZW50KVwiPiBDaHVuayBEb2N1bWVudCBDb250ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtY2hlY2tib3g+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImRhdGFzb3VyY2UuY29uZmlnLmNodW5rQ29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWNoZWNrYm94IGNsYXNzPVwiYmxvY2sgbWItNFwiIFsobmdNb2RlbCldPVwiZGF0YXNvdXJjZS5jb25maWcuaW5kZXhDaHVua3NCeUFJXCI+SW5kZXggQ2h1bmtzIGJ5IEFJXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWNoZWNrYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiZGF0YXNvdXJjZS5jb25maWcuaW5kZXhDb250ZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInNtOmdyaWQgc206Z3JpZC1jb2xzLTMgc206Z2FwLTQgc206aXRlbXMtc3RhcnQgc206Ym9yZGVyLXQgc206Ym9yZGVyLWdyYXktMjAwIHNtOnB0LTVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImJsb2NrIHRleHQtc20gZm9udC1tZWRpdW0gdGV4dC1ncmF5LTcwMCBzbTptdC1weCBzbTpwdC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RvcCBXb3Jkc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXhzIGZvbnQtbm9ybWFsIHRleHQtZ3JheS01MDBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQSBsaXN0IG9mIHdvcmRzIHRvIGV4Y2x1ZGUgZnJvbSBiZWluZyBpbmRleGVkLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtdC0xIHNtOm10LTAgc206Y29sLXNwYW4tMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggY2xhc3M9XCJibG9jayBtYi0yXCIgWyhuZ01vZGVsKV09XCJidWlsdEluU3RvcFdvcmRzLmJ1aWx0SW5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwidXBkYXRlQnVpbHRJblN0b3BXb3JkQ29uZmlnKCRldmVudClcIj5Vc2UgQnVpbHQgSW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1jaGVja2JveD5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJidWlsdEluU3RvcFdvcmRzLmJ1aWx0SW4gJiYgZGF0YXNvdXJjZS5jb25maWcubWF4UGhyYXNlTGVuZ3RoID4gMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJtYi00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNaW4gcGhyYXNlIGxlbmd0aCBmb3IgaW5jbHVkaW5nIHN0b3Agd29yZHNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCIgW21pbl09XCIyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImJ1aWx0SW5TdG9wV29yZHMubWluUGhyYXNlTGVuZ3RoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c21hbGwgY2xhc3M9XCJmb250LW5vcm1hbFwiPlRoZSBidWlsdCBpdCBzdG9wIHdvcmRzIHdpbGwgYmUgaW5jbHVkZWQgd2hlbiB0aGUgcGhyYXNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGlzIHZhbHVlLjwvc21hbGw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxociBjbGFzcz1cIm15LTRcIiAqbmdJZj1cIl8uZmlsdGVyKGRhdGFzb3VyY2UuY29uZmlnLnN0b3BXb3JkcywgJ2N1c3RvbScpLmxlbmd0aFwiPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIG5nRm9yIGxldC1zdG9wV29yZCBbbmdGb3JPZl09XCJfLmZpbHRlcihkYXRhc291cmNlLmNvbmZpZy5zdG9wV29yZHMsICdjdXN0b20nKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldC1pPWluZGV4PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1iZXR3ZWVuXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cIm1iLTQgdGV4dC1zbVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEYXRhc291cmNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIFttYXRBdXRvY29tcGxldGVdPVwiYXV0b0RhdGFzZXRzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJzdG9wV29yZC5kYXRhc291cmNlID8gc3RvcFdvcmQuZGF0YXNvdXJjZS50aXRsZSA6ICcnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChrZXl1cCk9XCJzZWFyY2hUZXh0Lm5leHQoJGV2ZW50LnRhcmdldC52YWx1ZSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJTZWFyY2ggZm9yIGEgZGF0YXNvdXJjZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWF1dG9jb21wbGV0ZSAjYXV0b0RhdGFzZXRzPVwibWF0QXV0b2NvbXBsZXRlXCIgW2Rpc3BsYXlXaXRoXT1cImRpc3BsYXlGblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IGRhdGFzb3VyY2Ugb2YgZGF0YXNvdXJjZXNcIiBbdmFsdWVdPVwiZGF0YXNvdXJjZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob25TZWxlY3Rpb25DaGFuZ2UpPVwidXBkYXRlRGF0YXNvdXJjZShzdG9wV29yZCwgJGV2ZW50LnNvdXJjZS52YWx1ZSlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2RhdGFzb3VyY2UudGl0bGV9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1hdXRvY29tcGxldGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzbWFsbCBjbGFzcz1cImZvbnQtbm9ybWFsXCI+U3RhcnQgdHlwaW5nIG5hbWUgdG8gdmlldyBhdmFpbGFibGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFzb3VyY2VzPC9zbWFsbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuXG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwic3RvcFdvcmQuc2VsZWN0ZWREYXRhc291cmNlICYmIHN0b3BXb3JkLnNlbGVjdGVkRGF0YXNvdXJjZS5jb2x1bW5zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cIm1iLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0b3AgV29yZHMgQ29sdW1uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IG1hdE5hdGl2ZUNvbnRyb2wgWyhuZ01vZGVsKV09XCJzdG9wV29yZC5kYXRhc291cmNlQ29sdW1uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIHN0b3BXb3JkLnNlbGVjdGVkRGF0YXNvdXJjZS5jb2x1bW5zXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1ZhbHVlXT1cImNvbHVtbi5uYW1lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7Y29sdW1uLnRpdGxlfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNtYWxsIGNsYXNzPVwiZm9udC1ub3JtYWxcIj5TZWxlY3QgdGhlIGNvbHVtbiB0byB1c2UgZm9yIHRoZSBzdG9wXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd29yZHM8L3NtYWxsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cIm1iLTRcIiAqbmdJZj1cImRhdGFzb3VyY2UuY29uZmlnLm1heFBocmFzZUxlbmd0aCA+IDFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1pbiBwaHJhc2UgbGVuZ3RoIGZvciBpbmNsdWRpbmcgc3RvcCB3b3Jkc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBbbWluXT1cIjJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwic3RvcFdvcmQubWluUGhyYXNlTGVuZ3RoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c21hbGxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZvbnQtbm9ybWFsXCI+VGhlIHt7c3RvcFdvcmQuZGF0YXNvdXJjZSA/IHN0b3BXb3JkLmRhdGFzb3VyY2UudGl0bGUgOiAnJ319XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RvcCB3b3JkcyB3aWxsIGJlIGluY2x1ZGVkIHdoZW4gdGhlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGhyYXNlIGxlbmd0aCBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhpcyB2YWx1ZS48L3NtYWxsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gbWF0LWljb24tYnV0dG9uIGNvbG9yPVwid2FyblwiIChjbGljayk9XCJyZW1vdmVDdXN0b21TdG9wV29yZChpKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5jbGVhcjwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGhyIGNsYXNzPVwibXktNFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIG1hdC1idXR0b24gY29sb3I9XCJwcmltYXJ5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJkYXRhc291cmNlLmNvbmZpZy5zdG9wV29yZHMucHVzaCh7Y3VzdG9tOiB0cnVlfSlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPmFkZDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFkZCBDdXN0b20gU3RvcCBXb3Jkc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNtOmdyaWQgc206Z3JpZC1jb2xzLTMgc206Z2FwLTQgc206aXRlbXMtc3RhcnQgc206Ym9yZGVyLXQgc206Ym9yZGVyLWdyYXktMjAwIHNtOnB0LTVcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiYmxvY2sgdGV4dC1zbSBmb250LW1lZGl1bSB0ZXh0LWdyYXktNzAwIHNtOm10LXB4IHNtOnB0LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIFN0b3JhZ2UgT3B0aW9uc1xuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQteHMgZm9udC1ub3JtYWwgdGV4dC1ncmF5LTUwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlY3VyZWx5IHNhdmUgYW4gb3JpZ2luYWwgY29weSBvZiB0aGUgZG9jdW1lbnQgYW5kL29yIGl0cyBvcmlnaW5hbCB0ZXh0LlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtdC0xIHNtOm10LTAgc206Y29sLXNwYW4tMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1jaGVja2JveCBjbGFzcz1cImJsb2NrIG1iLTJcIiBbKG5nTW9kZWwpXT1cImRhdGFzb3VyY2UuY29uZmlnLnN0b3JlT3JpZ2luYWxcIj5TdG9yZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9yaWdpbmFsIEZpbGVcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWNoZWNrYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1jaGVja2JveCBjbGFzcz1cImJsb2NrIG1iLTJcIiBbKG5nTW9kZWwpXT1cImRhdGFzb3VyY2UuY29uZmlnLnN0b3JlVGV4dFwiPlN0b3JlIERvY3VtZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgVGV4dFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtY2hlY2tib3g+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJwdC01XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGp1c3RpZnktZW5kXCI+XG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImJnLXdoaXRlIHB5LTIgcHgtNCBib3JkZXIgYm9yZGVyLWdyYXktMzAwIHJvdW5kZWQtbWQgc2hhZG93LXNtIHRleHQtc20gZm9udC1tZWRpdW0gdGV4dC1ncmF5LTcwMCBob3ZlcjpiZy1ncmF5LTUwIGZvY3VzOm91dGxpbmUtbm9uZVwiPlxuICAgICAgICAgICAgICAgIENhbmNlbFxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJzdWJtaXRcIiBbZGlzYWJsZWRdPVwiIWRhdGFzb3VyY2UudGl0bGVcIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImRpc2FibGVkOm9wYWNpdHktNTAgbWwtMyBpbmxpbmUtZmxleCBqdXN0aWZ5LWNlbnRlciBweS0yIHB4LTQgYm9yZGVyIGJvcmRlci10cmFuc3BhcmVudCBzaGFkb3ctc20gdGV4dC1zbSBmb250LW1lZGl1bSByb3VuZGVkLW1kIHRleHQtd2hpdGUgYmctc2Vjb25kYXJ5IGZvY3VzOm91dGxpbmUtbm9uZVwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJzYXZlKClcIj5cbiAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiIWRhdGFzb3VyY2VLZXlcIj5cbiAgICAgICAgICAgICAgICAgICAgQ3JlYXRlIERhdGFzb3VyY2VcbiAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJkYXRhc291cmNlS2V5XCI+XG4gICAgICAgICAgICAgICAgICAgIFVwZGF0ZSBTZXR0aW5nc1xuICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG48L2Rpdj5cblxuPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImV2YWx1YXRlZERhdGFzb3VyY2VcIj5cblxuXG4gICAgPGRpdiBjbGFzcz1cIm92ZXJmbG93LXNjcm9sbFwiPlxuICAgICAgICA8dGFibGUgY2xhc3M9XCJtaW4tdy1mdWxsIGJvcmRlci1zZXBhcmF0ZSBiZy13aGl0ZVwiIHN0eWxlPVwiYm9yZGVyLXNwYWNpbmc6IDBcIj5cbiAgICAgICAgICAgIDx0aGVhZCBjbGFzcz1cImJnLWdyYXktMTAwXCI+XG4gICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgPHRoICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgZXZhbHVhdGVkRGF0YXNvdXJjZS5jb2x1bW5zXCIgc2NvcGU9XCJjb2xcIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInN0aWNreSB0b3AtMCB6LTEwIGJvcmRlci1iIGJvcmRlci1ncmF5LTMwMCBiZy1ncmF5LTUwIGJnLW9wYWNpdHktNzUgcHktMy41IHB4LTQgdGV4dC1sZWZ0IHRleHQteHMgZm9udC1zZW1pYm9sZCB0ZXh0LWdyYXktOTAwIGJhY2tkcm9wLWJsdXIgYmFja2Ryb3AtZmlsdGVyXCI+XG4gICAgICAgICAgICAgICAgICAgIHt7Y29sdW1uLnRpdGxlfX1cbiAgICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgIDwvdGhlYWQ+XG4gICAgICAgICAgICA8dGJvZHkgY2xhc3M9XCJiZy13aGl0ZVwiPlxuICAgICAgICAgICAgPHRyICpuZ0Zvcj1cImxldCBkYXRhIG9mIGV2YWx1YXRlZERhdGFzb3VyY2UuYWxsRGF0YVwiPlxuICAgICAgICAgICAgICAgIDx0ZCAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIGV2YWx1YXRlZERhdGFzb3VyY2UuY29sdW1uczsgbGV0IGkgPSBpbmRleFwiXG4gICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnZm9udC1tZWRpdW0nOiBpID09PSAwfVwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYm9yZGVyLWIgYm9yZGVyLWdyYXktMjAwIHB5LTIgcHgtNCB0ZXh0LXNtIHRleHQtZ3JheS05MDBcIj5cbiAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImNvbHVtbi5uYW1lID09PSAnb3JpZ2luYWxfbGluaydcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgdGV4dC1jdGEgaG92ZXI6dW5kZXJsaW5lXCIgKGNsaWNrKT1cImRvd25sb2FkRG9jKGRhdGFbY29sdW1uLm5hbWVdKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7ZGF0YVtjb2x1bW4ubmFtZV19fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIGNsYXNzPVwibWwtMSBoLTQgdy00XCIgZmlsbD1cIm5vbmVcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZD1cIk00IDE2djFhMyAzIDAgMDAzIDNoMTBhMyAzIDAgMDAzLTN2LTFtLTQtNGwtNCA0bTAgMGwtNC00bTQgNFY0XCIvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiY29sdW1uLm5hbWUgIT09ICdvcmlnaW5hbF9saW5rJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImRhdGFbY29sdW1uLm5hbWVdICYmIFN0cmluZyhkYXRhW2NvbHVtbi5uYW1lXSkubGVuZ3RoIDw9IDEwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7ZGF0YVtjb2x1bW4ubmFtZV19fVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJkYXRhW2NvbHVtbi5uYW1lXSAmJiBTdHJpbmcoZGF0YVtjb2x1bW4ubmFtZV0pLmxlbmd0aCA+IDEwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+e3tkYXRhW2NvbHVtbi5uYW1lXS5zdWJzdHJpbmcoMCwgMTAwKSArICcuLi4nfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YSAoY2xpY2spPVwidmlld0Z1bGxJdGVtRGF0YShkYXRhW2NvbHVtbi5uYW1lXSwgY29sdW1uLm5hbWUpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIHRleHQtc20gdGV4dC1jdGEgaG92ZXI6dW5kZXJsaW5lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXcgbW9yZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiBjbGFzcz1cIm1sLTEgaC00IHctNFwiIGZpbGw9XCJub25lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3Qm94PVwiMCAwIDI0IDI0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U9XCJjdXJyZW50Q29sb3JcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIHN0cm9rZS13aWR0aD1cIjJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZD1cIk0xMCA2SDZhMiAyIDAgMDAtMiAydjEwYTIgMiAwIDAwMiAyaDEwYTIgMiAwIDAwMi0ydi00TTE0IDRoNm0wIDB2Nm0wLTZMMTAgMTRcIi8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiIWRhdGFbY29sdW1uLm5hbWVdXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3tkYXRhW2NvbHVtbi5uYW1lXX19XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgPC90Ym9keT5cblxuICAgICAgICA8L3RhYmxlPlxuXG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImJnLXdoaXRlIHAtNCBmbGV4IGFsaWduLWNlbnRlciBqdXN0aWZ5LWVuZFwiPlxuICAgICAgICA8c2VsZWN0IFt2YWx1ZV09XCJsaW1pdFwiIChjaGFuZ2UpPVwicGFnZVNpemVDaGFuZ2UoJGV2ZW50LnRhcmdldC52YWx1ZSlcIiBjbGFzcz1cIm1yLThcIj5cbiAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cIjFcIj4xPC9vcHRpb24+XG4gICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCI1XCI+NTwvb3B0aW9uPlxuICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwiMTBcIj4xMDwvb3B0aW9uPlxuICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwiMjVcIj4yNTwvb3B0aW9uPlxuICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwiNTBcIj41MDwvb3B0aW9uPlxuICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwiMTAwXCI+MTAwPC9vcHRpb24+XG4gICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCIyNTBcIj4yNTA8L29wdGlvbj5cbiAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cIjEwMDBcIj4xMDAwPC9vcHRpb24+XG4gICAgICAgIDwvc2VsZWN0PlxuICAgICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiBjbGFzcz1cIm1yLTRcIiAoY2xpY2spPVwiZGVjcmVhc2VPZmZzZXQoKVwiIFtkaXNhYmxlZF09XCJwYWdlIDw9IDFcIj5cbiAgICAgICAgICAgIDxtYXQtaWNvbj5jaGV2cm9uX2xlZnQ8L21hdC1pY29uPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiBtYXQtaWNvbi1idXR0b24gKGNsaWNrKT1cImluY3JlYXNlT2Zmc2V0KClcIiBbZGlzYWJsZWRdPVwiZW5kT2ZSZXN1bHRzXCI+XG4gICAgICAgICAgICA8bWF0LWljb24+Y2hldnJvbl9yaWdodDwvbWF0LWljb24+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuXG48L25nLXRlbXBsYXRlPlxuIl19
|