gamma-app-controller 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -0
- package/esm2020/gamma-app-controller.mjs +2 -0
- package/esm2020/lib/application-controller/app.http.service.mjs +24 -0
- package/esm2020/lib/application-controller/application-content.service.mjs +482 -0
- package/esm2020/lib/application-controller/application-controller.module.mjs +324 -0
- package/esm2020/lib/application-controller/application-dataset-call.service.mjs +321 -0
- package/esm2020/lib/application-controller/application-dataset-component/application-dataset/application-dataset.component.mjs +390 -0
- package/esm2020/lib/application-controller/application-dataset-component/create-dataset/create-dataset.component.mjs +349 -0
- package/esm2020/lib/application-controller/application-dataset-component/create-dataset-json/create-dataset-json.component.mjs +148 -0
- package/esm2020/lib/application-controller/application-dataset-component/create-dataset-sql/create-dataset-sql.component.mjs +167 -0
- package/esm2020/lib/application-controller/application-dataset-component/create-dataset-sql/sqlFormatter.mjs +17 -0
- package/esm2020/lib/application-controller/application-dataset-component/dataset-mongo/dataset-mongo.component.mjs +57 -0
- package/esm2020/lib/application-controller/application-dataset-component/dataset-query-bulder/dataset-query-bulder.component.mjs +409 -0
- package/esm2020/lib/application-controller/application-dataset-component/dataset-rest-api/dataset-rest-api.component.mjs +61 -0
- package/esm2020/lib/application-controller/application-filter/application-filter.component.mjs +186 -0
- package/esm2020/lib/application-controller/application-view-components/application-views/application-views.component.mjs +134 -0
- package/esm2020/lib/application-controller/application-view-components/create-comp-view/create-comp-view.component.mjs +559 -0
- package/esm2020/lib/application-controller/common-header/common-header.component.mjs +33 -0
- package/esm2020/lib/application-controller/common.mjs +1207 -0
- package/esm2020/lib/application-controller/environment.mjs +26 -0
- package/esm2020/lib/application-controller/kpi-comon-service.mjs +537 -0
- package/esm2020/lib/application-controller/kpi-service.mjs +108 -0
- package/esm2020/lib/application-controller/loading/loading.component.mjs +16 -0
- package/esm2020/lib/application-controller/loading/loadingModule.mjs +28 -0
- package/esm2020/lib/application-controller/moment-helper.mjs +4 -0
- package/esm2020/lib/application-controller/page-controller/page-config/page-config.component.mjs +977 -0
- package/esm2020/lib/application-controller/page-controller/page-controller/page-controller.component.mjs +172 -0
- package/esm2020/lib/application-controller/page-templates/cdr-config/cdr-config.component.mjs +227 -0
- package/esm2020/lib/application-controller/page-templates/dynamic-route-service.mjs +22 -0
- package/esm2020/lib/application-controller/shared/advanced-component/advance-widget-header-filter/advance-widget-header-filter.component.mjs +118 -0
- package/esm2020/lib/application-controller/shared/advanced-component/app-advance-header/app-header.component.mjs +181 -0
- package/esm2020/lib/application-controller/shared/advanced-component/gamm-single-number-card/gamm-single-number-card.component.mjs +71 -0
- package/esm2020/lib/application-controller/shared/advanced-component/gamma-advance-chart/gamma-advance-chart.component.mjs +266 -0
- package/esm2020/lib/application-controller/shared/advanced-component/gamma-advance-operator-table/gamma-advance-operator-table.component.mjs +159 -0
- package/esm2020/lib/application-controller/shared/advanced-component/gamma-table-clumn-bar-chart/gamma-table-clumn-bar-chart.component.mjs +144 -0
- package/esm2020/lib/application-controller/shared/advanced-component/gamma-table-with-percentage/contentSafeHtml.mjs +20 -0
- package/esm2020/lib/application-controller/shared/advanced-component/gamma-table-with-percentage/gamma-table-with-percentage.component.mjs +168 -0
- package/esm2020/lib/application-controller/shared/advanced-component/gamma-today-previous/gamma-today-previous.component.mjs +74 -0
- package/esm2020/lib/application-controller/shared/advanced-component/google-geo-map/google-geo-map.component.mjs +118 -0
- package/esm2020/lib/application-controller/shared/api.service.mjs +117 -0
- package/esm2020/lib/application-controller/shared/app-title/app-title.component.mjs +67 -0
- package/esm2020/lib/application-controller/shared/gamam-widget/gamam-widget.component.mjs +37 -0
- package/esm2020/lib/application-controller/shared/gamma-advance-filter/gamma-advance-filter.component.mjs +229 -0
- package/esm2020/lib/application-controller/shared/gamma-bread-crumbs/bread-crumbs.component.mjs +144 -0
- package/esm2020/lib/application-controller/shared/kpi-comon-service.mjs +537 -0
- package/esm2020/lib/application-controller/shared/loader/loader.component.mjs +14 -0
- package/esm2020/lib/application-controller/shared/loading/loading.component.mjs +16 -0
- package/esm2020/lib/application-controller/shared/loading/loadingModule.mjs +28 -0
- package/esm2020/lib/application-controller/shared/safeHtmlPipe.mjs +20 -0
- package/esm2020/lib/application-controller/support-components/dash-chart/dash-chart.component.mjs +294 -0
- package/esm2020/lib/application-controller/support-components/dash-table/dash-table.component.mjs +287 -0
- package/esm2020/lib/application-controller/support-components/geo-map/geo-map.component.mjs +255 -0
- package/esm2020/lib/application-controller/support-components/table-with-bar/table-with-bar.component.mjs +269 -0
- package/esm2020/lib/gamma-app-controller.component.mjs +16 -0
- package/esm2020/lib/gamma-app-controller.module.mjs +43 -0
- package/esm2020/lib/gamma-app-controller.service.mjs +20 -0
- package/esm2020/lib/icons.module.mjs +23 -0
- package/esm2020/public-api.mjs +49 -0
- package/fesm2015/gamma-app-controller.mjs +10250 -0
- package/fesm2015/gamma-app-controller.mjs.map +1 -0
- package/fesm2020/gamma-app-controller.mjs +10248 -0
- package/fesm2020/gamma-app-controller.mjs.map +1 -0
- package/index.d.ts +2 -0
- package/lib/application-controller/app.http.service.d.ts +15 -0
- package/lib/application-controller/application-content.service.d.ts +79 -0
- package/lib/application-controller/application-controller.module.d.ts +51 -0
- package/lib/application-controller/application-dataset-call.service.d.ts +20 -0
- package/lib/application-controller/application-dataset-component/application-dataset/application-dataset.component.d.ts +55 -0
- package/lib/application-controller/application-dataset-component/create-dataset/create-dataset.component.d.ts +121 -0
- package/lib/application-controller/application-dataset-component/create-dataset-json/create-dataset-json.component.d.ts +38 -0
- package/lib/application-controller/application-dataset-component/create-dataset-sql/create-dataset-sql.component.d.ts +42 -0
- package/lib/application-controller/application-dataset-component/create-dataset-sql/sqlFormatter.d.ts +7 -0
- package/lib/application-controller/application-dataset-component/dataset-mongo/dataset-mongo.component.d.ts +21 -0
- package/lib/application-controller/application-dataset-component/dataset-query-bulder/dataset-query-bulder.component.d.ts +62 -0
- package/lib/application-controller/application-dataset-component/dataset-rest-api/dataset-rest-api.component.d.ts +22 -0
- package/lib/application-controller/application-filter/application-filter.component.d.ts +36 -0
- package/lib/application-controller/application-view-components/application-views/application-views.component.d.ts +47 -0
- package/lib/application-controller/application-view-components/create-comp-view/create-comp-view.component.d.ts +73 -0
- package/lib/application-controller/common-header/common-header.component.d.ts +15 -0
- package/lib/application-controller/common.d.ts +148 -0
- package/lib/application-controller/environment.d.ts +25 -0
- package/lib/application-controller/kpi-comon-service.d.ts +14 -0
- package/lib/application-controller/kpi-service.d.ts +6 -0
- package/lib/application-controller/loading/loading.component.d.ts +9 -0
- package/lib/application-controller/loading/loadingModule.d.ts +10 -0
- package/lib/application-controller/moment-helper.d.ts +3 -0
- package/lib/application-controller/page-controller/page-config/page-config.component.d.ts +188 -0
- package/lib/application-controller/page-controller/page-controller/page-controller.component.d.ts +47 -0
- package/lib/application-controller/page-templates/cdr-config/cdr-config.component.d.ts +44 -0
- package/lib/application-controller/page-templates/dynamic-route-service.d.ts +8 -0
- package/lib/application-controller/shared/advanced-component/advance-widget-header-filter/advance-widget-header-filter.component.d.ts +33 -0
- package/lib/application-controller/shared/advanced-component/app-advance-header/app-header.component.d.ts +43 -0
- package/lib/application-controller/shared/advanced-component/gamm-single-number-card/gamm-single-number-card.component.d.ts +20 -0
- package/lib/application-controller/shared/advanced-component/gamma-advance-chart/gamma-advance-chart.component.d.ts +51 -0
- package/lib/application-controller/shared/advanced-component/gamma-advance-operator-table/gamma-advance-operator-table.component.d.ts +32 -0
- package/lib/application-controller/shared/advanced-component/gamma-table-clumn-bar-chart/gamma-table-clumn-bar-chart.component.d.ts +31 -0
- package/lib/application-controller/shared/advanced-component/gamma-table-with-percentage/contentSafeHtml.d.ts +10 -0
- package/lib/application-controller/shared/advanced-component/gamma-table-with-percentage/gamma-table-with-percentage.component.d.ts +26 -0
- package/lib/application-controller/shared/advanced-component/gamma-today-previous/gamma-today-previous.component.d.ts +21 -0
- package/lib/application-controller/shared/advanced-component/google-geo-map/google-geo-map.component.d.ts +29 -0
- package/lib/application-controller/shared/api.service.d.ts +26 -0
- package/lib/application-controller/shared/app-title/app-title.component.d.ts +28 -0
- package/lib/application-controller/shared/gamam-widget/gamam-widget.component.d.ts +20 -0
- package/lib/application-controller/shared/gamma-advance-filter/gamma-advance-filter.component.d.ts +45 -0
- package/lib/application-controller/shared/gamma-bread-crumbs/bread-crumbs.component.d.ts +32 -0
- package/lib/application-controller/shared/kpi-comon-service.d.ts +14 -0
- package/lib/application-controller/shared/loader/loader.component.d.ts +8 -0
- package/lib/application-controller/shared/loading/loading.component.d.ts +9 -0
- package/lib/application-controller/shared/loading/loadingModule.d.ts +10 -0
- package/lib/application-controller/shared/safeHtmlPipe.d.ts +10 -0
- package/lib/application-controller/support-components/dash-chart/dash-chart.component.d.ts +83 -0
- package/lib/application-controller/support-components/dash-table/dash-table.component.d.ts +67 -0
- package/lib/application-controller/support-components/geo-map/geo-map.component.d.ts +70 -0
- package/lib/application-controller/support-components/table-with-bar/table-with-bar.component.d.ts +70 -0
- package/lib/gamma-app-controller.component.d.ts +5 -0
- package/lib/gamma-app-controller.module.d.ts +10 -0
- package/lib/gamma-app-controller.service.d.ts +7 -0
- package/lib/icons.module.d.ts +11 -0
- package/package.json +33 -0
- package/public-api.d.ts +48 -0
package/esm2020/lib/application-controller/page-controller/page-config/page-config.component.mjs
ADDED
|
@@ -0,0 +1,977 @@
|
|
|
1
|
+
import { Component, ViewChild, ViewContainerRef } from '@angular/core';
|
|
2
|
+
import { confirm } from 'devextreme/ui/dialog';
|
|
3
|
+
import { DxScrollViewComponent } from 'devextreme-angular';
|
|
4
|
+
import moment from './../../moment-helper';
|
|
5
|
+
import { GammaTodayPreviousComponent } from '../../shared/advanced-component/gamma-today-previous/gamma-today-previous.component';
|
|
6
|
+
import { AppAdvanceHeaderComponent } from '../../shared/advanced-component/app-advance-header/app-header.component';
|
|
7
|
+
import { GammaTableWithPercentageComponent } from '../../shared/advanced-component/gamma-table-with-percentage/gamma-table-with-percentage.component';
|
|
8
|
+
import { GammSingleNumberCardComponent } from '../../shared/advanced-component/gamm-single-number-card/gamm-single-number-card.component';
|
|
9
|
+
import { GammaAdvanceOperatorTableComponent } from '../../shared/advanced-component/gamma-advance-operator-table/gamma-advance-operator-table.component';
|
|
10
|
+
import { AdvanceWidgetHeaderFilterComponent } from '../../shared/advanced-component/advance-widget-header-filter/advance-widget-header-filter.component';
|
|
11
|
+
import { GammaAdvanceChartComponent } from '../../shared/advanced-component/gamma-advance-chart/gamma-advance-chart.component';
|
|
12
|
+
import * as i0 from "@angular/core";
|
|
13
|
+
import * as i1 from "../../common";
|
|
14
|
+
import * as i2 from "@angular/router";
|
|
15
|
+
import * as i3 from "../../application-content.service";
|
|
16
|
+
import * as i4 from "ngx-toastr";
|
|
17
|
+
import * as i5 from "../../application-dataset-call.service";
|
|
18
|
+
import * as i6 from "@angular/common";
|
|
19
|
+
import * as i7 from "devextreme-angular/core";
|
|
20
|
+
import * as i8 from "devextreme-angular/ui/check-box";
|
|
21
|
+
import * as i9 from "devextreme-angular/ui/popup";
|
|
22
|
+
import * as i10 from "devextreme-angular/ui/scroll-view";
|
|
23
|
+
import * as i11 from "devextreme-angular/ui/select-box";
|
|
24
|
+
import * as i12 from "devextreme-angular/ui/tag-box";
|
|
25
|
+
import * as i13 from "devextreme-angular/ui/text-box";
|
|
26
|
+
import * as i14 from "@angular/forms";
|
|
27
|
+
import * as i15 from "@angular/material/icon";
|
|
28
|
+
import * as i16 from "../../shared/loading/loading.component";
|
|
29
|
+
import * as i17 from "../../application-view-components/create-comp-view/create-comp-view.component";
|
|
30
|
+
import * as i18 from "../../support-components/dash-chart/dash-chart.component";
|
|
31
|
+
import * as i19 from "../../support-components/dash-table/dash-table.component";
|
|
32
|
+
import * as i20 from "../../application-dataset-component/create-dataset/create-dataset.component";
|
|
33
|
+
import * as i21 from "../../common-header/common-header.component";
|
|
34
|
+
export class PageConfigComponent {
|
|
35
|
+
constructor(commonService, activatedRoute, viewContainerRef, componentFactoryResolver, service, toastr, router, datasetService) {
|
|
36
|
+
this.commonService = commonService;
|
|
37
|
+
this.activatedRoute = activatedRoute;
|
|
38
|
+
this.viewContainerRef = viewContainerRef;
|
|
39
|
+
this.componentFactoryResolver = componentFactoryResolver;
|
|
40
|
+
this.service = service;
|
|
41
|
+
this.toastr = toastr;
|
|
42
|
+
this.router = router;
|
|
43
|
+
this.datasetService = datasetService;
|
|
44
|
+
this.dashbord_container = [];
|
|
45
|
+
this.widget_width = ['w-full', 'w-1/2', 'w-1/3', 'w-2/3', 'w-1/4', 'w-3/4', 'w-1/5', 'w-4/5', 'w-1/6', 'w-5/6'];
|
|
46
|
+
this.loadingModal = true;
|
|
47
|
+
this.page_title = 'Dashboard';
|
|
48
|
+
this.isToggleSwich = true;
|
|
49
|
+
this.isDatePicker = false;
|
|
50
|
+
this.isToggleEventStatus = false;
|
|
51
|
+
this.isEditClick = false;
|
|
52
|
+
this.isUpdateWidget = false;
|
|
53
|
+
this.dynamicComponentRefs = [];
|
|
54
|
+
this.componentClassMap = {
|
|
55
|
+
GammaAdvanceChartComponent,
|
|
56
|
+
GammaTodayPreviousComponent,
|
|
57
|
+
AppAdvanceHeaderComponent,
|
|
58
|
+
GammaTableWithPercentageComponent,
|
|
59
|
+
GammSingleNumberCardComponent,
|
|
60
|
+
GammaAdvanceOperatorTableComponent,
|
|
61
|
+
AdvanceWidgetHeaderFilterComponent
|
|
62
|
+
};
|
|
63
|
+
this.dataSourceMataData = [];
|
|
64
|
+
this.queryType = "mongo";
|
|
65
|
+
this.dataSetModal = [];
|
|
66
|
+
this.componentConfigDataSource = [];
|
|
67
|
+
this.dataSourceModal = {};
|
|
68
|
+
this.isDashBoardContent = false;
|
|
69
|
+
this.selectedViewFormComponent = {};
|
|
70
|
+
this.addedwidGetConfig = {
|
|
71
|
+
"display": true,
|
|
72
|
+
"widgetTitle": "",
|
|
73
|
+
"width": "",
|
|
74
|
+
"height": "",
|
|
75
|
+
"isWidgetFilter": false
|
|
76
|
+
};
|
|
77
|
+
this.dashBoardWidgetConfig = [];
|
|
78
|
+
this.selectedIndexObjForChart = {};
|
|
79
|
+
this.selectedContainerObjectForChart = {};
|
|
80
|
+
this.uniqueDataSetObject = {};
|
|
81
|
+
this.islayoutCreate = false;
|
|
82
|
+
this.isDefaultView = true;
|
|
83
|
+
this.viewToSearch = '';
|
|
84
|
+
this.filteredComponentConfig = [];
|
|
85
|
+
this.editViewdataSourceModal = {};
|
|
86
|
+
this.editItemForUpdate = {};
|
|
87
|
+
this.allWidgetByDataset = [];
|
|
88
|
+
this.nodeProperticeFilters = [];
|
|
89
|
+
this.selectedFilterDatasource = {};
|
|
90
|
+
this.selectedViewsIds = [];
|
|
91
|
+
this.advanceLayoutContainer = [];
|
|
92
|
+
}
|
|
93
|
+
ngOnInit() {
|
|
94
|
+
this.isDashBoardContentTypeView = (this.activatedRoute.snapshot.queryParams['contentType'] == 'view') ? true : false;
|
|
95
|
+
this.pageId = this.activatedRoute.snapshot.queryParams['pageId'];
|
|
96
|
+
this.getDataSet();
|
|
97
|
+
this.defaultStartDate = moment().subtract('10', 'days').format('YYYY-MM-DD');
|
|
98
|
+
this.defaultEndDate = moment().subtract('1', 'days').format('YYYY-MM-DD');
|
|
99
|
+
this.getFilterItems();
|
|
100
|
+
this.getAllViewsItems();
|
|
101
|
+
this.getAppPageDetailConfigByPageId();
|
|
102
|
+
}
|
|
103
|
+
getAllViewsItems() {
|
|
104
|
+
this.service.getAppViewConfigs().subscribe({
|
|
105
|
+
next: (data) => {
|
|
106
|
+
this.componentConfigDataSource = data;
|
|
107
|
+
this.filteredComponentConfig = this.componentConfigDataSource;
|
|
108
|
+
}, error: (err) => {
|
|
109
|
+
this.toastr.error('Unexpected Server Exception. Please contact System Admin.', 'View Config');
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
getFilterItems() {
|
|
114
|
+
this.service.getAppFilterConfigs().subscribe({
|
|
115
|
+
next: (data) => {
|
|
116
|
+
this.filterDataSource = data;
|
|
117
|
+
}, error: (err) => {
|
|
118
|
+
this.toastr.error('Unexpected Server Exception. Please contact System Admin.', 'Error');
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
getAppPageDetailConfigByPageId() {
|
|
123
|
+
this.service.getAppPageDetailConfig(this.pageId).subscribe({
|
|
124
|
+
next: (data) => {
|
|
125
|
+
this.dashBoardWidgetConfig = data;
|
|
126
|
+
this.pageTitle = data.pageName;
|
|
127
|
+
this.pageUrl = data.pageUrl;
|
|
128
|
+
if (data.widgets && data.widgets.length !== 0) {
|
|
129
|
+
this.getComponentConfigSet();
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
this.loadingModal = false;
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
error: (err) => {
|
|
136
|
+
this.toastr.error('Unexpected Server Exception. Please contact System Admin.', 'Error');
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
getComponentConfigSet() {
|
|
141
|
+
let defaultFilters = { operationFilter: { startDate: "", endDate: "" } };
|
|
142
|
+
this.dashBoardWidgetConfig.widgets.forEach(widget => {
|
|
143
|
+
if (widget.filters) {
|
|
144
|
+
widget.filters.filterItems.forEach(element => {
|
|
145
|
+
if (element.filterType === 'date' || element.filterType === 'datetime') {
|
|
146
|
+
if (element.defaultFilterType === "dynamic" && element.momentFunction !== "" && element.defaultFilterValue !== "" && element.momentFormat !== "") {
|
|
147
|
+
let [count, unit] = element.defaultFilterValue.split(',');
|
|
148
|
+
if (element.apiName === "endDate") {
|
|
149
|
+
if (element.display) {
|
|
150
|
+
defaultFilters.operationFilter.endDate = moment()[element.momentFunction](parseInt(count), unit).format(element.momentFormat);
|
|
151
|
+
this.defaultEndDate = moment()[element.momentFunction](parseInt(count), unit).format(element.momentFormat);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (element.apiName === "startDate") {
|
|
155
|
+
defaultFilters.operationFilter.startDate = moment()[element.momentFunction](parseInt(count), unit).format(element.momentFormat);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
if ((typeof element.filterDataSourceValue === "string" && element.filterDataSourceValue !== "") ||
|
|
161
|
+
(Array.isArray(element.filterDataSourceValue) && element.filterDataSourceValue.length > 0)) {
|
|
162
|
+
if (element.operatorName !== "") {
|
|
163
|
+
defaultFilters.operationFilter[element.operatorName] = Array.isArray(element.filterDataSourceValue)
|
|
164
|
+
? element.filterDataSourceValue
|
|
165
|
+
: [element.filterDataSourceValue];
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
defaultFilters.operationFilter[element.apiName] = element.filterDataSourceValue.join(",");
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
let apiCalls = [];
|
|
176
|
+
this.defaultApplyedFilter = defaultFilters;
|
|
177
|
+
Promise.all(apiCalls).then(() => {
|
|
178
|
+
this.createDivElements(this.uniqueDataSetObject);
|
|
179
|
+
this.loadingModal = false;
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
ngOnDestroy() {
|
|
183
|
+
}
|
|
184
|
+
getDataSet() {
|
|
185
|
+
this.isLoader = true;
|
|
186
|
+
this.service.getAppDatasetConfigs().subscribe({
|
|
187
|
+
next: (data) => {
|
|
188
|
+
this.dataSettableDataSource = data;
|
|
189
|
+
this.isLoader = false;
|
|
190
|
+
}, error: (err) => {
|
|
191
|
+
this.toastr.error('Unexpected Server Exception. Please contact System Admin.', 'Dataset Creation');
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
getComponentConfig(event) {
|
|
196
|
+
const foundObject = this.componentConfigDataSource.find(view => view.viewId === event.viewId);
|
|
197
|
+
this.getEmitNewChartConfig(foundObject);
|
|
198
|
+
this.loadingModal = true;
|
|
199
|
+
}
|
|
200
|
+
addNewchart() {
|
|
201
|
+
this.isGenerate = false;
|
|
202
|
+
this.isChartButtonClick = true;
|
|
203
|
+
this.isWidgetCreationContent = false;
|
|
204
|
+
this.isDefaultView = false;
|
|
205
|
+
}
|
|
206
|
+
addWidget() {
|
|
207
|
+
this.newWidgetIndex = undefined;
|
|
208
|
+
this.isWidgetCreationContent = true;
|
|
209
|
+
this.isDefaultView = false;
|
|
210
|
+
this.isEditMainLayout = false;
|
|
211
|
+
this.isChartButtonClick = false;
|
|
212
|
+
this.isUpdateWidget = false;
|
|
213
|
+
this.widgetName = '';
|
|
214
|
+
this.widgetTitle = '';
|
|
215
|
+
this.addedwidGetConfig = {
|
|
216
|
+
"display": true,
|
|
217
|
+
"widgetTitle": "",
|
|
218
|
+
"width": "",
|
|
219
|
+
"height": "",
|
|
220
|
+
"isWidgetFilter": false
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
getWith(e) {
|
|
224
|
+
this.selectedWidth = e.value;
|
|
225
|
+
}
|
|
226
|
+
getHeight(e) {
|
|
227
|
+
this.selectedHeight = e.value;
|
|
228
|
+
}
|
|
229
|
+
addLayoutTOview() {
|
|
230
|
+
let inner_node = {
|
|
231
|
+
id: this.commonService.primeryRendomeId(5),
|
|
232
|
+
nodeTitle: "",
|
|
233
|
+
filterId: this.selectedFilterId,
|
|
234
|
+
nodeProperties: this.addedwidGetConfig,
|
|
235
|
+
compConfig: {
|
|
236
|
+
dynamicComponentRefs: [],
|
|
237
|
+
viewConfig: []
|
|
238
|
+
},
|
|
239
|
+
};
|
|
240
|
+
if (this.dashBoardWidgetConfig.widgets[this.newWidgetIndex].widgetNode) {
|
|
241
|
+
this.dashBoardWidgetConfig.widgets[this.newWidgetIndex].widgetNode.push(inner_node);
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
this.dashBoardWidgetConfig.widgets[this.newWidgetIndex].widgetNode = [];
|
|
245
|
+
this.dashBoardWidgetConfig.widgets[this.newWidgetIndex].widgetNode.push(inner_node);
|
|
246
|
+
}
|
|
247
|
+
this.loadingModal = true;
|
|
248
|
+
this.updateWidget();
|
|
249
|
+
}
|
|
250
|
+
reformatWidgetConfig(dashBoardWidgetConfig, index = null) {
|
|
251
|
+
const processWidget = (widget) => {
|
|
252
|
+
widget.compConfig.viewConfig = widget.compConfig.viewConfig.map(config => config.viewId);
|
|
253
|
+
widget.compConfig.dynamicComponentRefs = [];
|
|
254
|
+
if (widget.widgetNode && widget.widgetNode.length > 0) {
|
|
255
|
+
widget.widgetNode.forEach(node => {
|
|
256
|
+
node.compConfig.viewConfig = node.compConfig.viewConfig.map(config => config.viewId);
|
|
257
|
+
node.compConfig.dynamicComponentRefs = [];
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
if (index !== null && index >= 0 && index < dashBoardWidgetConfig.widgets.length) {
|
|
262
|
+
processWidget(dashBoardWidgetConfig.widgets[index]);
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
dashBoardWidgetConfig.widgets.forEach(widget => processWidget(widget));
|
|
266
|
+
}
|
|
267
|
+
return dashBoardWidgetConfig.widgets[index];
|
|
268
|
+
}
|
|
269
|
+
updateWidget() {
|
|
270
|
+
let modifiedConfig = this.reformatWidgetConfig(this.dashBoardWidgetConfig, this.newWidgetIndex);
|
|
271
|
+
modifiedConfig['filterId'] = (modifiedConfig.filters.filterId) ? modifiedConfig.filters.filterId : null;
|
|
272
|
+
delete modifiedConfig['filters'];
|
|
273
|
+
this.service.editAppWidgetConfig(modifiedConfig).subscribe({
|
|
274
|
+
next: (data) => {
|
|
275
|
+
this.getAppPageDetailConfigByPageId();
|
|
276
|
+
this.backToMainView();
|
|
277
|
+
}, error: (err) => {
|
|
278
|
+
this.loadingModal = false;
|
|
279
|
+
this.toastr.error('Unexpected Server Exception. Please contact System Admin.', 'Widget Creation');
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
this.newWidgetIndex = undefined;
|
|
283
|
+
this.isWidgetCreationContent = false;
|
|
284
|
+
this.isDefaultView = true;
|
|
285
|
+
}
|
|
286
|
+
updateLayoutWidgetTOview() {
|
|
287
|
+
this.loadingModal = true;
|
|
288
|
+
this.updateWidget();
|
|
289
|
+
}
|
|
290
|
+
addWidgetTOview() {
|
|
291
|
+
let obj = {
|
|
292
|
+
widgetId: this.commonService.primeryRendomeId(5),
|
|
293
|
+
widgetName: this.widgetName,
|
|
294
|
+
widgetTitle: this.widgetTitle,
|
|
295
|
+
widgetProperties: this.addedwidGetConfig,
|
|
296
|
+
pageId: this.pageId,
|
|
297
|
+
filterId: this.selectedFilterId,
|
|
298
|
+
widgetNode: [
|
|
299
|
+
{
|
|
300
|
+
id: this.commonService.primeryRendomeId(5),
|
|
301
|
+
nodeTitle: "",
|
|
302
|
+
filterId: "",
|
|
303
|
+
nodeProperties: {
|
|
304
|
+
"display": true,
|
|
305
|
+
"widgetTitle": "",
|
|
306
|
+
"width": "w-1/2",
|
|
307
|
+
"height": "",
|
|
308
|
+
},
|
|
309
|
+
compConfig: {
|
|
310
|
+
dynamicComponentRefs: [],
|
|
311
|
+
viewConfig: []
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
],
|
|
315
|
+
compConfig: {
|
|
316
|
+
dynamicComponentRefs: [],
|
|
317
|
+
viewConfig: []
|
|
318
|
+
},
|
|
319
|
+
};
|
|
320
|
+
this.loadingModal = true;
|
|
321
|
+
this.service.createAppWidgetConfig(obj).subscribe({
|
|
322
|
+
next: (data) => {
|
|
323
|
+
this.loadingModal = false;
|
|
324
|
+
this.getAppPageDetailConfigByPageId();
|
|
325
|
+
}, error: (err) => {
|
|
326
|
+
this.loadingModal = false;
|
|
327
|
+
this.toastr.error('Unexpected Server Exception. Please contact System Admin.', 'Widget Creation');
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
this.dashBoardWidgetConfig.widgets.push(obj);
|
|
331
|
+
this.dynamicContainer.nativeElement.innerHTML = '';
|
|
332
|
+
this.isWidgetCreationContent = false;
|
|
333
|
+
this.isDefaultView = true;
|
|
334
|
+
}
|
|
335
|
+
insertNewWiget(index) {
|
|
336
|
+
this.addedwidGetConfig = {
|
|
337
|
+
"display": true,
|
|
338
|
+
"widgetTitle": "",
|
|
339
|
+
"width": "",
|
|
340
|
+
"height": "",
|
|
341
|
+
"isWidgetFilter": false
|
|
342
|
+
};
|
|
343
|
+
this.isUpdateWidget = false;
|
|
344
|
+
this.isWidgetCreationContent = true;
|
|
345
|
+
this.isDefaultView = false;
|
|
346
|
+
this.isChartButtonClick = false;
|
|
347
|
+
this.islayoutCreate = true;
|
|
348
|
+
this.newWidgetIndex = index;
|
|
349
|
+
}
|
|
350
|
+
insertChartWiget(indexObj, containerElement) {
|
|
351
|
+
this.isGenerate = false;
|
|
352
|
+
this.isChartButtonClick = true;
|
|
353
|
+
this.isWidgetCreationContent = false;
|
|
354
|
+
this.isDefaultView = false;
|
|
355
|
+
this.selectedContainerObjectForChart = containerElement;
|
|
356
|
+
this.selectedIndexObjForChart = indexObj;
|
|
357
|
+
this.selectedViewFormComponent = {};
|
|
358
|
+
}
|
|
359
|
+
async getEmitNewChartConfig(data) {
|
|
360
|
+
this.selectedIndexObjForChart.compConfig.viewConfig.push(data);
|
|
361
|
+
this.loadDynamicComponent(data, this.selectedIndexObjForChart, this.selectedContainerObjectForChart);
|
|
362
|
+
console.log(this.dashBoardWidgetConfig);
|
|
363
|
+
this.updateWidget();
|
|
364
|
+
this.loadingModal = false;
|
|
365
|
+
this.isChartButtonClick = false;
|
|
366
|
+
}
|
|
367
|
+
updateToView() {
|
|
368
|
+
this.loadingModal = true;
|
|
369
|
+
this.updateWidget();
|
|
370
|
+
}
|
|
371
|
+
deleteWidget(item, index) {
|
|
372
|
+
this.dashBoardWidgetConfig.widgets.splice(index, 1);
|
|
373
|
+
this.newWidgetIndex = undefined;
|
|
374
|
+
}
|
|
375
|
+
deleteInsertWidget(item, childIndex, parentIndex) {
|
|
376
|
+
this.dashBoardWidgetConfig.widgets[parentIndex].widgetNode.splice(childIndex, 1);
|
|
377
|
+
this.newWidgetIndex = undefined;
|
|
378
|
+
}
|
|
379
|
+
getWidgetTitleDiv(item, div) {
|
|
380
|
+
const widgetDiv = document.createElement('div');
|
|
381
|
+
widgetDiv.classList.add('flex', 'items-center', 'justify-between', 'font-bold', 'text-md', 'text-gray-900', 'dark:text-white', 'border-b', 'p-3', 'bg-gray-800', 'mx-2', 'rounded-t-lg');
|
|
382
|
+
const titleDiv = document.createElement('div');
|
|
383
|
+
titleDiv.innerText = (item.nodeProperties) ? item.nodeProperties.widgetTitle : "";
|
|
384
|
+
widgetDiv.append(titleDiv);
|
|
385
|
+
const editIcon = document.createElement('i');
|
|
386
|
+
editIcon.classList.add('fa', 'fa-pencil', 'ml-2', 'cursor-pointer', 'text-blue-400', 'hover:text-blue-700');
|
|
387
|
+
widgetDiv.append(editIcon);
|
|
388
|
+
if (item.nodeProperties.isWidgetFilter) {
|
|
389
|
+
const searchContainerDiv = document.createElement('div');
|
|
390
|
+
searchContainerDiv.classList.add('flex', 'items-center', 'space-x-2');
|
|
391
|
+
const searchButton = document.createElement('button');
|
|
392
|
+
searchButton.innerText = 'Filter';
|
|
393
|
+
searchButton.classList.add('px-3', 'py-1.5', 'bg-blue-600', 'mr-2', 'text-white', 'rounded', 'hover:bg-blue-700');
|
|
394
|
+
this.nodeproperticeFilterDataSource = [];
|
|
395
|
+
searchButton.addEventListener('click', () => {
|
|
396
|
+
this.isWidgetFilters = true;
|
|
397
|
+
let filtePropertice = [];
|
|
398
|
+
item.compConfig.viewConfig.forEach(element => {
|
|
399
|
+
let key_name = this.uniqueDataSetObject[element.datasetId][0];
|
|
400
|
+
Object.keys(key_name).forEach(key => {
|
|
401
|
+
if (!filtePropertice.includes(key)) {
|
|
402
|
+
filtePropertice.push(key);
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
});
|
|
406
|
+
filtePropertice.forEach(element => {
|
|
407
|
+
let obj = {
|
|
408
|
+
columnName: element,
|
|
409
|
+
dataType: "float",
|
|
410
|
+
operator: "",
|
|
411
|
+
value: "",
|
|
412
|
+
};
|
|
413
|
+
this.nodeproperticeFilterDataSource.push(obj);
|
|
414
|
+
});
|
|
415
|
+
});
|
|
416
|
+
searchContainerDiv.appendChild(searchButton);
|
|
417
|
+
widgetDiv.appendChild(titleDiv);
|
|
418
|
+
widgetDiv.appendChild(searchContainerDiv);
|
|
419
|
+
}
|
|
420
|
+
if (item.filterId) {
|
|
421
|
+
this.nodeproperticeFilterDataSource = {};
|
|
422
|
+
this.nodeproperticeFilterDataSource['viewConfig'] = item;
|
|
423
|
+
this.nodeproperticeFilterDataSource['havingConfig'] = [];
|
|
424
|
+
this.service.getAppFilterConfig(item.filterId).subscribe({
|
|
425
|
+
next: (data) => {
|
|
426
|
+
const filterDiv = document.createElement('div');
|
|
427
|
+
this.loadWidgetFilterComponent(item, widgetDiv, data.filterItems);
|
|
428
|
+
}, error: (err) => {
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
if (item.nodeProperties.nodefilters && item.nodeProperties.nodefilters.length !== 0) {
|
|
433
|
+
const searchContainerDiv = document.createElement('div');
|
|
434
|
+
searchContainerDiv.classList.add('flex', 'items-center', 'space-x-2');
|
|
435
|
+
item.nodeProperties.nodefilters.forEach(filter => {
|
|
436
|
+
const filterDiv = document.createElement('div');
|
|
437
|
+
filterDiv.classList.add('flex', 'items-center');
|
|
438
|
+
if (filter.input_type === 'text') {
|
|
439
|
+
const textBox = document.createElement('input');
|
|
440
|
+
textBox.type = 'text';
|
|
441
|
+
textBox.placeholder = `Enter ${filter.local_column}`;
|
|
442
|
+
textBox.classList.add('px-2', 'py-1.5', 'rounded', 'border', 'mr-1', 'border-gray-500', 'text-gray-900', 'dark:bg-gray-700', 'dark:text-white');
|
|
443
|
+
const searchButton = document.createElement('button');
|
|
444
|
+
searchButton.innerText = 'Search';
|
|
445
|
+
searchButton.classList.add('px-3', 'py-1.5', 'bg-blue-600', 'mr-2', 'text-white', 'rounded', 'hover:bg-blue-700');
|
|
446
|
+
const separerotButton = document.createElement('div');
|
|
447
|
+
separerotButton.innerHTML = '|';
|
|
448
|
+
searchButton.addEventListener('click', () => {
|
|
449
|
+
const searchTerm = textBox.value;
|
|
450
|
+
console.log('Text search button clicked with:', searchTerm);
|
|
451
|
+
});
|
|
452
|
+
filterDiv.appendChild(textBox);
|
|
453
|
+
filterDiv.appendChild(searchButton);
|
|
454
|
+
filterDiv.appendChild(separerotButton);
|
|
455
|
+
}
|
|
456
|
+
searchContainerDiv.appendChild(filterDiv);
|
|
457
|
+
});
|
|
458
|
+
widgetDiv.appendChild(searchContainerDiv);
|
|
459
|
+
}
|
|
460
|
+
editIcon.addEventListener('click', () => {
|
|
461
|
+
this.newWidgetIndex = this.dashBoardWidgetConfig.widgets.findIndex(object => object.widgetId === div.widgetId);
|
|
462
|
+
this.isUpdateWidget = true;
|
|
463
|
+
this.islayoutCreate = true;
|
|
464
|
+
this.isWidgetCreationContent = true;
|
|
465
|
+
this.isDefaultView = false;
|
|
466
|
+
this.isChartButtonClick = false;
|
|
467
|
+
this.nodeProperticeFilters = (item.nodeProperties.nodefilters && item.nodeProperties.nodefilters.length !== 0) ? item.nodeProperties.nodefilters : [];
|
|
468
|
+
item.nodeProperties['nodefilters'] = this.nodeProperticeFilters;
|
|
469
|
+
this.addedwidGetConfig = item.nodeProperties;
|
|
470
|
+
this.allWidgetInnerContent = item.compConfig.viewConfig;
|
|
471
|
+
this.selectedFilterId = (item.filterId) ? item.filterId : "";
|
|
472
|
+
this.editViewdataSourceModal = {};
|
|
473
|
+
this.selectedFilterDatasource = item;
|
|
474
|
+
});
|
|
475
|
+
return widgetDiv;
|
|
476
|
+
}
|
|
477
|
+
getFilterValueById(event) {
|
|
478
|
+
if (event.event) {
|
|
479
|
+
this.service.getAppFilterConfig(event.value).subscribe({
|
|
480
|
+
next: (data) => {
|
|
481
|
+
if (Object.keys(this.selectedFilterDatasource).length !== 0) {
|
|
482
|
+
this.selectedFilterDatasource.filterId = this.selectedFilterId;
|
|
483
|
+
}
|
|
484
|
+
else {
|
|
485
|
+
this.dashBoardWidgetConfig.widgets[this.newWidgetIndex].filters = data;
|
|
486
|
+
}
|
|
487
|
+
this.toastr.success("Filter Changed");
|
|
488
|
+
}, erroe: (err) => {
|
|
489
|
+
this.toastr.error('Unexpected Server Exception. Please contact System Admin.', 'Filter Update');
|
|
490
|
+
}
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
createDivElements(datasetById) {
|
|
495
|
+
const container = this.dynamicContainer.nativeElement;
|
|
496
|
+
container.innerHTML = "";
|
|
497
|
+
this.dashBoardWidgetConfig.widgets.forEach(async (div) => {
|
|
498
|
+
const rowDiv = document.createElement('div');
|
|
499
|
+
let w_height = (div.widgetProperties.height == "") ? "h-auto" : 'h-[' + div.widgetProperties.height + ']';
|
|
500
|
+
rowDiv.classList.add(div.widgetProperties.width, w_height, 'border');
|
|
501
|
+
const filterDiv = document.createElement('div');
|
|
502
|
+
if (div.filters) {
|
|
503
|
+
this.loadFilterComponent(div, filterDiv, div.filters.filterItems);
|
|
504
|
+
}
|
|
505
|
+
rowDiv.appendChild(filterDiv);
|
|
506
|
+
if (div.widgetNode && div.widgetNode.length && div.widgetNode.length != 0) {
|
|
507
|
+
const mainItemDiv = document.createElement('div');
|
|
508
|
+
mainItemDiv.classList.add("flex", "flex-wrap");
|
|
509
|
+
this.loadWidgetNodes(div, mainItemDiv, datasetById);
|
|
510
|
+
rowDiv.appendChild(mainItemDiv);
|
|
511
|
+
}
|
|
512
|
+
const p_innerDiv = document.createElement('div');
|
|
513
|
+
p_innerDiv.classList.add('rounded', 'justify-center', 'items-center', 'border', 'p-1', 'm-1', 'flex', 'flex-row');
|
|
514
|
+
const p_button_widget = document.createElement('div');
|
|
515
|
+
p_button_widget.innerText = 'Add Single Layout';
|
|
516
|
+
p_button_widget.classList.add('bg-blue-700', "p-1", "w-fit", "cursor-pointer", 'text-xs');
|
|
517
|
+
p_button_widget.addEventListener('click', () => {
|
|
518
|
+
let index = this.dashBoardWidgetConfig.widgets.findIndex(object => object.widgetId === div.widgetId);
|
|
519
|
+
this.insertNewWiget(index);
|
|
520
|
+
});
|
|
521
|
+
const p_del_button = document.createElement('div');
|
|
522
|
+
p_del_button.innerText = 'Detete layout';
|
|
523
|
+
p_del_button.classList.add('bg-red-700', "p-1", "w-fit", "cursor-pointer", 'text-xs');
|
|
524
|
+
p_del_button.addEventListener('click', () => {
|
|
525
|
+
let result = confirm("<i>Are You Sure?</i>", "Delete Layout");
|
|
526
|
+
result.then((dialogResult) => {
|
|
527
|
+
if (dialogResult) {
|
|
528
|
+
this.loadingModal = true;
|
|
529
|
+
this.dashBoardWidgetConfig.widgets = this.dashBoardWidgetConfig.widgets.map(config => config.widgetId);
|
|
530
|
+
rowDiv.remove();
|
|
531
|
+
this.service.editAppPageConfig(this.dashBoardWidgetConfig).subscribe({
|
|
532
|
+
next: (data) => {
|
|
533
|
+
this.getAppPageDetailConfigByPageId();
|
|
534
|
+
}, error: (err) => {
|
|
535
|
+
this.loadingModal = false;
|
|
536
|
+
this.toastr.error('Unexpected Server Exception. Please contact System Admin.', 'Widget Creation');
|
|
537
|
+
}
|
|
538
|
+
});
|
|
539
|
+
this.newWidgetIndex = undefined;
|
|
540
|
+
this.isWidgetCreationContent = false;
|
|
541
|
+
this.isDefaultView = true;
|
|
542
|
+
}
|
|
543
|
+
});
|
|
544
|
+
});
|
|
545
|
+
const advance_button = document.createElement('div');
|
|
546
|
+
advance_button.innerText = 'Advance Layout';
|
|
547
|
+
advance_button.classList.add('bg-yellow-700', "p-1", "w-fit", "cursor-pointer", 'text-xs');
|
|
548
|
+
advance_button.addEventListener('click', () => {
|
|
549
|
+
const comp_object = this.findWidgetById(this.dashBoardWidgetConfig.widgets, div.widgetId);
|
|
550
|
+
this.newWidgetIndex = this.dashBoardWidgetConfig.widgets.findIndex(object => object.widgetId === div.widgetId);
|
|
551
|
+
this.isAdvanceLayout = true;
|
|
552
|
+
});
|
|
553
|
+
p_innerDiv.appendChild(advance_button);
|
|
554
|
+
p_innerDiv.appendChild(p_button_widget);
|
|
555
|
+
p_innerDiv.appendChild(p_del_button);
|
|
556
|
+
if (!this.isDashBoardContentTypeView) {
|
|
557
|
+
rowDiv.appendChild(p_innerDiv);
|
|
558
|
+
}
|
|
559
|
+
container.appendChild(rowDiv);
|
|
560
|
+
});
|
|
561
|
+
}
|
|
562
|
+
loadWidgetNodes(div, mainItemDiv, datasetById) {
|
|
563
|
+
div.widgetNode.forEach(item => {
|
|
564
|
+
this.loadSingleWidgetNode(item, mainItemDiv, datasetById, div);
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
loadSingleWidgetNode(item, containerElement, datasetById, div) {
|
|
568
|
+
let w_height = (item.nodeProperties.height == "") ? "h-auto" : 'h-[' + item.nodeProperties.height + ']';
|
|
569
|
+
let w_width = (item.nodeProperties.width == "") ? "w-full" : item.nodeProperties.width;
|
|
570
|
+
const itemDiv = document.createElement('div');
|
|
571
|
+
itemDiv.classList.add(w_width, w_height, 'border', 'p-1');
|
|
572
|
+
const flexContainer = document.createElement('div');
|
|
573
|
+
flexContainer.classList.add('flex', 'justify-between', 'items-center', 'text-gray-900', 'dark:text-white', 'bg-gray-800', 'mx-2', 'rounded-t-lg');
|
|
574
|
+
const widgetDiv = this.getWidgetTitleDiv(item, div);
|
|
575
|
+
item.compConfig.viewConfig.forEach(element => {
|
|
576
|
+
if (element.kpiConfig) {
|
|
577
|
+
let apiCalls = [];
|
|
578
|
+
this.service.getAppDatasetConfig(element.datasetId).subscribe({
|
|
579
|
+
next: (dataset) => {
|
|
580
|
+
const datasetWithLimit = this.setDataSetsLimit(dataset);
|
|
581
|
+
apiCalls.push(this.datasetService.getDataFromDataSet(datasetWithLimit, datasetWithLimit.datasetId, this.defaultApplyedFilter));
|
|
582
|
+
Promise.all(apiCalls).then(() => {
|
|
583
|
+
this.uniqueDataSetObject = this.datasetService.getUniqueDataSetObject();
|
|
584
|
+
element.kpiConfig['dataSource'] = this.uniqueDataSetObject[element.datasetId];
|
|
585
|
+
const comp_object = this.findWidgetById(this.dashBoardWidgetConfig.widgets, item.id);
|
|
586
|
+
this.loadDynamicComponent(element, comp_object, itemDiv);
|
|
587
|
+
});
|
|
588
|
+
}, error: (err) => {
|
|
589
|
+
}
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
});
|
|
593
|
+
flexContainer.appendChild(widgetDiv);
|
|
594
|
+
const buttonsContainer = document.createElement('div');
|
|
595
|
+
buttonsContainer.classList.add('flex', 'mx-2');
|
|
596
|
+
const innerDiv = document.createElement('div');
|
|
597
|
+
innerDiv.classList.add('rounded', 'justify-center', 'items-center', 'p-1', 'm-1', 'flex', 'flex-row');
|
|
598
|
+
const button_chart = document.createElement('div');
|
|
599
|
+
button_chart.innerText = 'Add View';
|
|
600
|
+
button_chart.classList.add('bg-green-700', "p-1", "w-fit", "cursor-pointer", 'text-xs');
|
|
601
|
+
button_chart.addEventListener('click', () => {
|
|
602
|
+
this.newWidgetIndex = this.dashBoardWidgetConfig.widgets.findIndex(object => object.widgetId === div.widgetId);
|
|
603
|
+
const comp_object = this.findWidgetById(this.dashBoardWidgetConfig.widgets, item.id);
|
|
604
|
+
this.insertChartWiget(comp_object, itemDiv);
|
|
605
|
+
});
|
|
606
|
+
const del_button_chart = document.createElement('div');
|
|
607
|
+
del_button_chart.innerText = 'Detete';
|
|
608
|
+
del_button_chart.classList.add('bg-red-700', "p-1", "w-fit", "cursor-pointer", 'text-xs');
|
|
609
|
+
del_button_chart.addEventListener('click', () => {
|
|
610
|
+
let result = confirm("<i>Are You Sure?</i>", "Delete View");
|
|
611
|
+
result.then((dialogResult) => {
|
|
612
|
+
if (dialogResult) {
|
|
613
|
+
let widgetIndex = this.dashBoardWidgetConfig.widgets.findIndex(object => object.widgetId === div.widgetId);
|
|
614
|
+
const mapedObject = this.dashBoardWidgetConfig.widgets[widgetIndex];
|
|
615
|
+
if (mapedObject.widgetNode && mapedObject.widgetNode.length > 0) {
|
|
616
|
+
let mapIndex = mapedObject.widgetNode.findIndex(ind => ind.id === item.id);
|
|
617
|
+
mapedObject.widgetNode.forEach(node => {
|
|
618
|
+
node.compConfig.viewConfig = node.compConfig.viewConfig.map(config => config.viewId);
|
|
619
|
+
node.compConfig.dynamicComponentRefs = [];
|
|
620
|
+
});
|
|
621
|
+
mapedObject.widgetNode.splice(mapIndex, 1);
|
|
622
|
+
}
|
|
623
|
+
mapedObject['filterId'] = (mapedObject.filters) ? mapedObject.filters.filterId : null;
|
|
624
|
+
delete mapedObject['filters'];
|
|
625
|
+
mapedObject.compConfig.dynamicComponentRefs = [];
|
|
626
|
+
this.service.editAppWidgetConfig(mapedObject).subscribe({
|
|
627
|
+
next: (data) => {
|
|
628
|
+
this.getAppPageDetailConfigByPageId();
|
|
629
|
+
}, error: (err) => {
|
|
630
|
+
this.loadingModal = false;
|
|
631
|
+
this.toastr.error('Unexpected Server Exception. Please contact System Admin.', 'Widget Creation');
|
|
632
|
+
}
|
|
633
|
+
});
|
|
634
|
+
this.newWidgetIndex = undefined;
|
|
635
|
+
itemDiv.remove();
|
|
636
|
+
}
|
|
637
|
+
});
|
|
638
|
+
});
|
|
639
|
+
buttonsContainer.appendChild(button_chart);
|
|
640
|
+
buttonsContainer.appendChild(del_button_chart);
|
|
641
|
+
flexContainer.appendChild(buttonsContainer);
|
|
642
|
+
if (!this.isDashBoardContentTypeView) {
|
|
643
|
+
}
|
|
644
|
+
itemDiv.appendChild(flexContainer);
|
|
645
|
+
containerElement.appendChild(itemDiv);
|
|
646
|
+
}
|
|
647
|
+
findWidgetById(configs, id) {
|
|
648
|
+
for (const config of configs) {
|
|
649
|
+
if (config.id === id) {
|
|
650
|
+
return config;
|
|
651
|
+
}
|
|
652
|
+
if (config.widgetNode && config.widgetNode.length > 0) {
|
|
653
|
+
const found = this.findWidgetById(config.widgetNode, id);
|
|
654
|
+
if (found) {
|
|
655
|
+
return found;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
return undefined;
|
|
660
|
+
}
|
|
661
|
+
deleteWidgetById(configs, id) {
|
|
662
|
+
for (let i = configs.length - 1; i >= 0; i--) {
|
|
663
|
+
if (configs[i].id === id) {
|
|
664
|
+
configs.splice(i, 1);
|
|
665
|
+
}
|
|
666
|
+
else if (configs[i].widgetNode && configs[i].widgetNode.length > 0) {
|
|
667
|
+
this.deleteWidgetById(configs[i].widgetNode, id);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
loadDynamicComponent(data, indexObj, containerElement) {
|
|
672
|
+
const componentClass = this.componentClassMap[data.kpiConfig['componentName']];
|
|
673
|
+
this.CompRefs = this.viewContainerRef.createComponent(componentClass);
|
|
674
|
+
const dynamicComponentInstance = this.CompRefs.instance;
|
|
675
|
+
dynamicComponentInstance.chartDataSource = data;
|
|
676
|
+
dynamicComponentInstance.kpi_name = "";
|
|
677
|
+
indexObj.compConfig.dynamicComponentRefs.push(this.CompRefs);
|
|
678
|
+
const cssClass = "w-full";
|
|
679
|
+
this.CompRefs.location.nativeElement.classList.add(cssClass);
|
|
680
|
+
containerElement.appendChild(this.CompRefs.location.nativeElement);
|
|
681
|
+
}
|
|
682
|
+
loadFilterComponent(indexObj, containerElement, filterItems) {
|
|
683
|
+
let selectedDates = { startDate: this.defaultStartDate, endDate: this.defaultEndDate };
|
|
684
|
+
const componentClass = this.componentClassMap['AppAdvanceHeaderComponent'];
|
|
685
|
+
this.CompRefs = this.viewContainerRef.createComponent(componentClass);
|
|
686
|
+
const dynamicComponentInstance = this.CompRefs.instance;
|
|
687
|
+
dynamicComponentInstance.selectedDates = selectedDates;
|
|
688
|
+
dynamicComponentInstance.filterItems = filterItems;
|
|
689
|
+
dynamicComponentInstance.pageTitle = this.pageTitle;
|
|
690
|
+
dynamicComponentInstance.isEditButton = false;
|
|
691
|
+
dynamicComponentInstance.isAdvanceButton = true;
|
|
692
|
+
indexObj.compConfig.dynamicComponentRefs.push(this.CompRefs);
|
|
693
|
+
const cssClass = "w-full";
|
|
694
|
+
this.CompRefs.location.nativeElement.classList.add(cssClass);
|
|
695
|
+
containerElement.appendChild(this.CompRefs.location.nativeElement);
|
|
696
|
+
}
|
|
697
|
+
loadWidgetFilterComponent(indexObj, containerElement, filterItems) {
|
|
698
|
+
let userName = localStorage.getItem('user_name');
|
|
699
|
+
let selectedDates = { startDate: this.defaultStartDate, endDate: this.defaultEndDate };
|
|
700
|
+
const componentClass = this.componentClassMap['AdvanceWidgetHeaderFilterComponent'];
|
|
701
|
+
this.CompRefs = this.viewContainerRef.createComponent(componentClass);
|
|
702
|
+
const dynamicComponentInstance = this.CompRefs.instance;
|
|
703
|
+
dynamicComponentInstance.selectedDates = selectedDates;
|
|
704
|
+
dynamicComponentInstance.filterItems = filterItems;
|
|
705
|
+
dynamicComponentInstance.getWidgetFilterConfig.subscribe((value) => {
|
|
706
|
+
this.getWidgetFilterForTemplate(value);
|
|
707
|
+
});
|
|
708
|
+
indexObj.compConfig.dynamicComponentRefs.push(this.CompRefs);
|
|
709
|
+
containerElement.appendChild(this.CompRefs.location.nativeElement);
|
|
710
|
+
}
|
|
711
|
+
getDeleteViewFromConfig(index) {
|
|
712
|
+
console.log(index);
|
|
713
|
+
this.allWidgetInnerContent.splice(index, 1);
|
|
714
|
+
}
|
|
715
|
+
moveItemForPageView(index, direction) {
|
|
716
|
+
if (index < 0 || index >= this.dashBoardWidgetConfig.widgets[this.newWidgetIndex].widgetNode.length)
|
|
717
|
+
return;
|
|
718
|
+
const newPosition = direction === 'up' ? index - 1 : index + 1;
|
|
719
|
+
if (newPosition < 0 || newPosition >= this.dashBoardWidgetConfig.widgets[this.newWidgetIndex].widgetNode.length)
|
|
720
|
+
return;
|
|
721
|
+
const itemToMove = this.dashBoardWidgetConfig.widgets[this.newWidgetIndex].widgetNode[index];
|
|
722
|
+
this.dashBoardWidgetConfig.widgets[this.newWidgetIndex].widgetNode.splice(index, 1);
|
|
723
|
+
this.dashBoardWidgetConfig.widgets[this.newWidgetIndex].widgetNode.splice(newPosition, 0, itemToMove);
|
|
724
|
+
}
|
|
725
|
+
moveItemForColumns(index, direction) {
|
|
726
|
+
if (index < 0 || index >= this.allWidgetInnerContent.length)
|
|
727
|
+
return;
|
|
728
|
+
const newPosition = direction === 'up' ? index - 1 : index + 1;
|
|
729
|
+
if (newPosition < 0 || newPosition >= this.allWidgetInnerContent.length)
|
|
730
|
+
return;
|
|
731
|
+
const itemToMove = this.allWidgetInnerContent[index];
|
|
732
|
+
this.allWidgetInnerContent.splice(index, 1);
|
|
733
|
+
this.allWidgetInnerContent.splice(newPosition, 0, itemToMove);
|
|
734
|
+
}
|
|
735
|
+
moveItemForWidget(index, direction) {
|
|
736
|
+
if (index < 0 || index >= this.dashBoardWidgetConfig.widgets.length)
|
|
737
|
+
return;
|
|
738
|
+
const newPosition = direction === 'up' ? index - 1 : index + 1;
|
|
739
|
+
if (newPosition < 0 || newPosition >= this.dashBoardWidgetConfig.widgets.length)
|
|
740
|
+
return;
|
|
741
|
+
const itemToMove = this.dashBoardWidgetConfig.widgets[index];
|
|
742
|
+
this.dashBoardWidgetConfig.widgets.splice(index, 1);
|
|
743
|
+
this.dashBoardWidgetConfig.widgets.splice(newPosition, 0, itemToMove);
|
|
744
|
+
}
|
|
745
|
+
getEditViewFromLayout(data, index) {
|
|
746
|
+
this.isEditMainLayout = true;
|
|
747
|
+
this.newWidgetIndex = index;
|
|
748
|
+
this.isWidgetCreationContent = true;
|
|
749
|
+
this.isDefaultView = false;
|
|
750
|
+
this.isChartButtonClick = false;
|
|
751
|
+
this.isUpdateWidget = false;
|
|
752
|
+
this.widgetName = data.widgetName;
|
|
753
|
+
this.widgetTitle = data.widgetTitle;
|
|
754
|
+
this.selectedFilterId = data.filters.filterId;
|
|
755
|
+
this.addedwidGetConfig = data.widgetProperties;
|
|
756
|
+
}
|
|
757
|
+
backToMainView() {
|
|
758
|
+
this.isDefaultView = true;
|
|
759
|
+
this.isUpdateWidget = false;
|
|
760
|
+
this.isWidgetCreationContent = false;
|
|
761
|
+
this.isChartButtonClick = false;
|
|
762
|
+
this.isEditMainLayout = false;
|
|
763
|
+
this.islayoutCreate = false;
|
|
764
|
+
this.newWidgetIndex = undefined;
|
|
765
|
+
this.selectedFilterId = undefined;
|
|
766
|
+
}
|
|
767
|
+
filterViews() {
|
|
768
|
+
if (this.viewToSearch.trim() !== '') {
|
|
769
|
+
this.filteredComponentConfig = this.componentConfigDataSource.filter((item) => item.viewName.toLowerCase().includes(this.viewToSearch.toLowerCase()));
|
|
770
|
+
}
|
|
771
|
+
else {
|
|
772
|
+
this.filteredComponentConfig = this.componentConfigDataSource;
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
editComponentViews(item) {
|
|
776
|
+
this.loadingModal = true;
|
|
777
|
+
this.editItemForUpdate = item;
|
|
778
|
+
if (this.isUpdateWidget && !this.isChartButtonClick) {
|
|
779
|
+
this.selectedViewId = item.viewId;
|
|
780
|
+
setTimeout(() => {
|
|
781
|
+
this.isCreateNewViewWithDefaultView = true;
|
|
782
|
+
this.loadingModal = false;
|
|
783
|
+
}, 400);
|
|
784
|
+
}
|
|
785
|
+
else {
|
|
786
|
+
let navigation = {
|
|
787
|
+
queryParams: {
|
|
788
|
+
'viewId': item.viewId,
|
|
789
|
+
'pageId': this.pageId
|
|
790
|
+
}
|
|
791
|
+
};
|
|
792
|
+
this.router.navigate(['apps/controlPanel/applicationContent/applicationViews'], navigation);
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
editComponentDatasets(item) {
|
|
796
|
+
this.loadingModal = true;
|
|
797
|
+
this.editItemForUpdate = item;
|
|
798
|
+
if (this.isUpdateWidget && !this.isChartButtonClick) {
|
|
799
|
+
this.selectedDatasetId = item.datasetId;
|
|
800
|
+
setTimeout(() => {
|
|
801
|
+
this.isCreateDatasetWithDatasetId = true;
|
|
802
|
+
this.loadingModal = false;
|
|
803
|
+
}, 400);
|
|
804
|
+
}
|
|
805
|
+
else {
|
|
806
|
+
let navigation = {
|
|
807
|
+
queryParams: {
|
|
808
|
+
'viewId': item.viewId,
|
|
809
|
+
'pageId': this.pageId
|
|
810
|
+
}
|
|
811
|
+
};
|
|
812
|
+
this.router.navigate(['apps/controlPanel/applicationContent/applicationViews'], navigation);
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
getAllPage() {
|
|
816
|
+
this.router.navigate(['apps/controlPanel/applicationContent/applicationDashboard']);
|
|
817
|
+
}
|
|
818
|
+
transformColumnsForColumns(inputColumns) {
|
|
819
|
+
const columns = [];
|
|
820
|
+
inputColumns.forEach(col => {
|
|
821
|
+
columns.push({
|
|
822
|
+
dataField: col.dataField,
|
|
823
|
+
visible: true,
|
|
824
|
+
caption: col.caption,
|
|
825
|
+
});
|
|
826
|
+
});
|
|
827
|
+
return columns;
|
|
828
|
+
}
|
|
829
|
+
getCreateDataSetPage() {
|
|
830
|
+
this.isCreateDataset = true;
|
|
831
|
+
}
|
|
832
|
+
getCreateViewPage() {
|
|
833
|
+
this.selectedViewId = undefined;
|
|
834
|
+
this.loadingModal = true;
|
|
835
|
+
setTimeout(() => {
|
|
836
|
+
this.isCreateNewView = true;
|
|
837
|
+
this.loadingModal = false;
|
|
838
|
+
}, 400);
|
|
839
|
+
}
|
|
840
|
+
getEmitNewChartCongig(event) {
|
|
841
|
+
delete event.kpiConfig.dataSource;
|
|
842
|
+
this.editItemForUpdate['kpiConfig'] = event.kpiConfig;
|
|
843
|
+
console.log(this.editItemForUpdate);
|
|
844
|
+
this.service.updateAppViewConfig(this.editItemForUpdate).subscribe({
|
|
845
|
+
next: (data) => {
|
|
846
|
+
this.isEditOptionClick = false;
|
|
847
|
+
this.toastr.success('View Update Successfully');
|
|
848
|
+
}, error: (err) => {
|
|
849
|
+
this.toastr.error('Unexpected Server Exception. Please contact System Admin.', 'View Creation');
|
|
850
|
+
}
|
|
851
|
+
});
|
|
852
|
+
}
|
|
853
|
+
getViewPage() {
|
|
854
|
+
let navigationExtras = {
|
|
855
|
+
queryParams: {
|
|
856
|
+
"pageId": this.pageId
|
|
857
|
+
}
|
|
858
|
+
};
|
|
859
|
+
this.router.navigate([this.pageUrl], navigationExtras);
|
|
860
|
+
}
|
|
861
|
+
getNodeProperticeFilterOption() {
|
|
862
|
+
let obj = {
|
|
863
|
+
input_type: "text",
|
|
864
|
+
server_column: "",
|
|
865
|
+
local_column: "",
|
|
866
|
+
select_box_option: "",
|
|
867
|
+
};
|
|
868
|
+
this.nodeProperticeFilters.push(obj);
|
|
869
|
+
}
|
|
870
|
+
deleteNodeFilter(index) {
|
|
871
|
+
this.nodeProperticeFilters.splice(index, 1);
|
|
872
|
+
}
|
|
873
|
+
setDataSetsLimit(dataset) {
|
|
874
|
+
let limit = { "limit": "10" };
|
|
875
|
+
dataset.config.queryConfig.reqFields.push(limit);
|
|
876
|
+
return dataset;
|
|
877
|
+
}
|
|
878
|
+
getViewPopupHide(e) {
|
|
879
|
+
this.getAllViewsItems();
|
|
880
|
+
}
|
|
881
|
+
getDatasetPopupHide(e) {
|
|
882
|
+
}
|
|
883
|
+
submitFilter() {
|
|
884
|
+
}
|
|
885
|
+
getWidgetFilterForTemplate(value) {
|
|
886
|
+
this.getDataSet();
|
|
887
|
+
}
|
|
888
|
+
getDeleteViewFromLayout(item, i) {
|
|
889
|
+
this.dashBoardWidgetConfig.widgets.splice(i, 1);
|
|
890
|
+
this.dashBoardWidgetConfig.widgets.forEach(widget => {
|
|
891
|
+
widget.compConfig.viewConfig = widget.compConfig.viewConfig.map(config => config.viewId);
|
|
892
|
+
widget.compConfig.dynamicComponentRefs = [];
|
|
893
|
+
if (widget.widgetNode && widget.widgetNode.length > 0) {
|
|
894
|
+
widget.widgetNode.forEach(node => {
|
|
895
|
+
node.compConfig.viewConfig = node.compConfig.viewConfig.map(config => config.viewId);
|
|
896
|
+
node.compConfig.dynamicComponentRefs = [];
|
|
897
|
+
});
|
|
898
|
+
}
|
|
899
|
+
});
|
|
900
|
+
const widgetData = this.dashBoardWidgetConfig;
|
|
901
|
+
widgetData['widgets'] = this.dashBoardWidgetConfig.widgets.map(item => item.widgetId);
|
|
902
|
+
widgetData['filterId'] = (widgetData.filters) ? widgetData.filters.filterId : null;
|
|
903
|
+
delete widgetData['filters'];
|
|
904
|
+
this.service.editAppPageConfig(widgetData).subscribe({
|
|
905
|
+
next: (data) => {
|
|
906
|
+
this.toastr.success("Layout Deleted Successfully");
|
|
907
|
+
this.getAppPageDetailConfigByPageId();
|
|
908
|
+
}, error: (err) => {
|
|
909
|
+
this.loadingModal = false;
|
|
910
|
+
this.toastr.error('Unexpected Server Exception. Please contact System Admin.', 'Widget Creation');
|
|
911
|
+
}
|
|
912
|
+
});
|
|
913
|
+
}
|
|
914
|
+
getProcessForConfig() {
|
|
915
|
+
this.advanceLayoutContainer = [];
|
|
916
|
+
const filteredColumns = this.componentConfigDataSource.filter(column => this.selectedViewsIds.includes(column.viewId));
|
|
917
|
+
const columnDefList = [];
|
|
918
|
+
filteredColumns.forEach(element => {
|
|
919
|
+
let obj = {
|
|
920
|
+
"id": this.commonService.primeryRendomeId(5),
|
|
921
|
+
"nodeTitle": "",
|
|
922
|
+
"compConfig": {
|
|
923
|
+
"dynamicComponentRefs": [],
|
|
924
|
+
"viewConfig": [element]
|
|
925
|
+
},
|
|
926
|
+
"filterId": null,
|
|
927
|
+
"nodeProperties": {
|
|
928
|
+
"display": true,
|
|
929
|
+
"widgetTitle": "",
|
|
930
|
+
"width": "",
|
|
931
|
+
"height": "",
|
|
932
|
+
"isWidgetFilter": false
|
|
933
|
+
}
|
|
934
|
+
};
|
|
935
|
+
this.advanceLayoutContainer.push(obj);
|
|
936
|
+
});
|
|
937
|
+
this.isProceed = true;
|
|
938
|
+
}
|
|
939
|
+
getSelectedColumnSource(event) {
|
|
940
|
+
if (event.event) {
|
|
941
|
+
this.selectedViewsIds = event.value;
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
submitAdvanceView() {
|
|
945
|
+
if (this.dashBoardWidgetConfig.widgets[this.newWidgetIndex].widgetNode && this.dashBoardWidgetConfig.widgets[this.newWidgetIndex].widgetNode.length !== 0) {
|
|
946
|
+
this.dashBoardWidgetConfig.widgets[this.newWidgetIndex].widgetNode = [...this.dashBoardWidgetConfig.widgets[this.newWidgetIndex].widgetNode, ...this.advanceLayoutContainer];
|
|
947
|
+
}
|
|
948
|
+
else {
|
|
949
|
+
this.dashBoardWidgetConfig.widgets[this.newWidgetIndex].widgetNode = this.advanceLayoutContainer;
|
|
950
|
+
}
|
|
951
|
+
this.isAdvanceLayout = false;
|
|
952
|
+
this.advanceLayoutContainer = [];
|
|
953
|
+
this.isProceed = false;
|
|
954
|
+
this.updateWidget();
|
|
955
|
+
}
|
|
956
|
+
deleteView(i) {
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
PageConfigComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: PageConfigComponent, deps: [{ token: i1.CommonService }, { token: i2.ActivatedRoute }, { token: i0.ViewContainerRef }, { token: i0.ComponentFactoryResolver }, { token: i3.ApplicationContentService }, { token: i4.ToastrService }, { token: i2.Router }, { token: i5.ApplicationDatssetsCall }], target: i0.ɵɵFactoryTarget.Component });
|
|
960
|
+
PageConfigComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.3", type: PageConfigComponent, selector: "app-dashbord-config", viewQueries: [{ propertyName: "dynamicComponentContainer", first: true, predicate: ["dynamicComponentContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "containerRef", first: true, predicate: ["container"], descendants: true, read: ViewContainerRef }, { propertyName: "dynamicContainer", first: true, predicate: ["dynamicContainer"], descendants: true, static: true }, { propertyName: "scrollView", first: true, predicate: DxScrollViewComponent, descendants: true }], ngImport: i0, template: "<app-loading *ngIf=\"loadingModal\"></app-loading>\n\n<!-- <div class=\"flex flex-col flex-auto w-full\"> -->\n<div class=\"flex flex-row h-screen\">\n <div class=\"flex-grow border-r h-full\">\n <div class=\"scrollable-content\">\n <!-- <div class=\"flex flex-wrap p-2 border\"> -->\n <!-- <app-advance-header [filterItems]=\"filterItems\" [pageTitle]=\"'Dashboard'\" [isEditButton]=\"false\"\n [isAdvanceButton]=\"true\"></app-advance-header> -->\n <div class=\"flex flex-wrap my-3\" #dynamicContainer></div>\n\n </div>\n <div class=\"flex flex-row justify-center items-center h-16 m-2 border\">\n <lib-common-header [pageTitle]=\"''\"></lib-common-header>\n <!-- <div class=\"{{commonService.btn_success_md}} m-2 \" (click)=\"getCreateDataSetPage()\">Create\n Dataset\n </div> -->\n <div class=\"{{commonService.btn_primary_md}} m-2\" (click)=\"addWidget()\">Add Layout\n </div>\n <!-- <div class=\"{{commonService.btn_success_md}} m-2\" (click)=\"getCreateViewPage()\">Create\n View\n </div> -->\n <div class=\"{{commonService.btnOthersPurple}} m-2 cursar-pointer\" (click)=\"getViewPage()\">View Page\n </div>\n <!-- <div class=\"{{commonService.btn_warning_md}} m-2 cursar-pointer\" (click)=\"getAllPage()\">All Pages\n </div> -->\n\n </div>\n </div>\n <div class=\"flex-shrink-0 w-1/4 p-2 h-full\">\n <ng-container *ngIf=\"isDashBoardContent\">\n <div class=\"{{commonService.btnDarkBlack}} m-2 w-fit text-center cursar-pointer\" (click)=\"backToMainView()\">\n Back\n </div>\n <ng-container *ngFor=\"let item of page_config.api_config; let i = index\">\n <div class=\"mb-2 flex flex-row justify-between items-center border-b\">\n <div class=\"text-md py-2 font-bold text-white px-2\">\n {{item.widGetConfig.widgetTitle}}\n </div>\n <div class=\"flex space-x-2\">\n <!-- <button (click)=\"editSelectedWidget(item, i)\"\n class=\"w-8 h-8 bg-sky-600 hover:bg-blue-800 text-white rounded-full flex items-center justify-center\">\n <i class=\"fa fa-edit\"></i>\n </button> -->\n <button\n class=\"w-8 h-8 bg-red-600 hover:bg-red-800 text-white rounded-full flex items-center justify-center\">\n <i class=\"fa fa-trash-o\"></i>\n </button>\n </div>\n </div>\n\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"isWidgetCreationContent\">\n <h6 class=\"mb-2 font-bold text-lg tracking-tight text-gray-900 dark:text-white border-b pb-3\">\n <span *ngIf=\"!islayoutCreate\">Widget Settings</span>\n <span *ngIf=\"islayoutCreate\">Layout Settings</span>\n </h6>\n <div class=\"flex flex-row my-4\">\n <dx-check-box class=\"ml-auto\" [(ngModel)]=\"addedwidGetConfig.display\" text=\"Display\"></dx-check-box>\n </div>\n <div class=\"flex flex-row mb-2 justify-between\">\n <span class=\"text-md my-auto px-2\">Width</span>\n <dx-select-box class=\"w-1/2\" [items]=\"widget_width\"\n [(ngModel)]=\"addedwidGetConfig.width\"></dx-select-box>\n </div>\n <div class=\"flex flex-row mb-2 justify-between\">\n <span class=\"text-md my-auto px-2\">Height</span>\n <dx-text-box class=\"w-1/2\" [(ngModel)]=\"addedwidGetConfig.height\"></dx-text-box>\n </div>\n\n <div class=\"flex flex-row mb-2 justify-between\" *ngIf=\"!islayoutCreate\">\n <span class=\"text-md my-auto px-2\">Widget Title</span>\n <dx-text-box class=\"w-1/2\" [(ngModel)]=\"widgetTitle\"></dx-text-box>\n </div>\n <div class=\"flex flex-row mb-2 justify-between\" *ngIf=\"!islayoutCreate\">\n <span class=\"text-md my-auto px-2\">Widget Name</span>\n <dx-text-box class=\"w-1/2\" [(ngModel)]=\"widgetName\"></dx-text-box>\n </div>\n\n\n <div class=\"flex flex-row mb-5 justify-between\" *ngIf=\"islayoutCreate\">\n <span class=\"text-sm my-auto px-2\">Layout Title</span>\n <dx-text-box class=\"w-1/2\" [(ngModel)]=\"addedwidGetConfig.widgetTitle\"></dx-text-box>\n </div>\n\n <div class=\"flex flex-row mb-2 justify-between\">\n <span class=\"text-md my-auto px-2\">Filter</span>\n <dx-select-box class=\"w-1/2\" [items]=\"filterDataSource\" displayExpr=\"filterName\" [searchEnabled]=\"true\"\n valueExpr=\"filterId\" [(ngModel)]=\"selectedFilterId\"\n (onValueChanged)=\"getFilterValueById($event)\"></dx-select-box>\n </div>\n <ng-container *ngIf=\"!isUpdateWidget\">\n <div class=\"mt-6\" *ngIf=\"!islayoutCreate && isEditMainLayout\">\n <ng-container\n *ngFor=\"let item of dashBoardWidgetConfig.widgets[newWidgetIndex].widgetNode;let i = index\">\n <div class=\"mb-2 flex flex-row justify-between items-center border-b \">\n <div class=\"text-md py-2 font-bold text-white px-2\">\n {{item.nodeProperties.widgetTitle}}\n </div>\n <div class=\"flex space-x-2\">\n <button *ngIf=\"i !== 0\" class=\"{{commonService.btn_light_sm}} cursor-pointer mx-1\"\n (click)=\"moveItemForPageView(i, 'up')\">\n <i class=\"fa fa-arrow-up\" aria-hidden=\"true\"></i>\n </button>\n\n <button\n *ngIf=\"i !== dashBoardWidgetConfig.widgets[newWidgetIndex].widgetNode.length - 1\"\n class=\"{{commonService.btn_light_sm}} cursor-pointer mx-1\"\n (click)=\"moveItemForPageView(i, 'down')\">\n <i class=\"fa fa-arrow-down\" aria-hidden=\"true\"></i>\n </button>\n <button\n class=\"w-8 h-8 bg-red-600 hover:bg-red-800 text-white rounded-full flex items-center justify-center\">\n <i class=\"fa fa-trash-o\"></i>\n </button>\n </div>\n </div>\n\n </ng-container>\n </div>\n </ng-container>\n\n\n\n <ng-container *ngIf=\"isUpdateWidget\">\n <div class=\"text-sm py-1 font-extrabold border-b bg-gray-700 text-white px-2\"> Application Views\n </div>\n <div class=\"border-x border-b p-2\">\n <ng-container *ngFor=\"let item of allWidgetInnerContent; let i = index\">\n <div class=\"group w-full flex justify-between border-b items-center\">\n <div class=\"text-md font-bold py-2 cursor-pointer\">\n {{item.viewName}}\n </div>\n\n <div class=\"flex space-x-2\">\n <button *ngIf=\"i !== 0\" class=\"{{commonService.btn_light_sm}} cursor-pointer mx-1\"\n (click)=\"moveItemForColumns(i, 'up')\">\n <i class=\"fa fa-arrow-up\" aria-hidden=\"true\"></i>\n </button>\n\n <button *ngIf=\"i !== allWidgetInnerContent.length - 1\"\n class=\"{{commonService.btn_light_sm}} cursor-pointer mx-1\"\n (click)=\"moveItemForColumns(i, 'down')\">\n <i class=\"fa fa-arrow-down\" aria-hidden=\"true\"></i>\n </button>\n <button class=\"rounded-full p-2 text-white bg-blue-500 hover:bg-blue-700 mb-2\"\n (click)=\"editComponentViews(item)\">\n <i class=\"fa fa-eye\" aria-hidden=\"true\"></i>\n </button>\n <button class=\"rounded-full p-2 text-white bg-blue-500 hover:bg-blue-700 mb-2\"\n (click)=\"editComponentDatasets(item)\">\n <i class=\"fa fa-database\" aria-hidden=\"true\"></i>\n </button>\n <button class=\"rounded-full p-2 text-white bg-red-500 hover:bg-red-700 mb-2\"\n (click)=\"getDeleteViewFromConfig(i)\">\n <i class=\"fa fa-trash-o\" aria-hidden=\"true\"></i>\n </button>\n </div>\n\n </div>\n </ng-container>\n </div>\n </ng-container>\n <ng-container *ngIf=\"isUpdateWidget\">\n <div class=\"text-sm py-1 font-extrabold border-b bg-gray-700 text-white px-2\"> Add Filter For View\n\n </div>\n <div class=\"border-x border-b p-2\">\n <div class=\"flex flex-row py-3 border-b\">\n <dx-check-box [(ngModel)]=\"addedwidGetConfig.isWidgetFilter\"\n text=\"Popup Columns Filter Enable\"></dx-check-box>\n </div>\n <div class=\"flex flex-row my-2 border-b\">\n <ng-container *ngFor=\"let item of nodeProperticeFilters; let i = index\">\n <div class=\"flex flex-wrap border-b\">\n <div class=\"px-1 w-1/3\">\n <div class=\"text-md\">Input Type</div>\n <dx-select-box [items]=\"['text']\" [(ngModel)]=\"item.input_type\"\n value=\"text\"></dx-select-box>\n </div>\n <div class=\"px-1-1 w-2/3\" *ngIf=\"item.input_type == 'text'\">\n <div class=\"text-md\">Server Column</div>\n <dx-text-box [(ngModel)]=\"item.server_column\"></dx-text-box>\n </div>\n <div class=\"px-1-1 w-1/2\" *ngIf=\"item.input_type == 'text'\">\n <div class=\"text-md\">Local Column</div>\n <dx-text-box [(ngModel)]=\"item.local_column\"></dx-text-box>\n </div>\n <div class=\"px-1-1 w-1/3\" *ngIf=\"item.input_type == 'select'\">\n <div class=\"text-md\">Columns Name</div>\n <dx-text-box [(ngModel)]=\"item.select_box_option\"></dx-text-box>\n </div>\n <div class=\"px-1-1 w-1/2\">\n <div class=\"flex justify-end\">\n <div class=\"{{commonService.btn_danger_sm}} w-24 mt-6 text-center\"\n (click)=\"deleteNodeFilter(i)\">Delete Filter</div>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n <div class=\"{{commonService.btn_primary_sm}} w-auto text-center\"\n (click)=\"getNodeProperticeFilterOption()\">Add\n Filter</div>\n </div>\n </ng-container>\n\n <div class=\"flex flex-row justify-end items-center h-16 m-2\">\n <div class=\"{{commonService.btnDarkBlack}} m-2 w-fit text-center cursar-pointer\"\n (click)=\"backToMainView()\">Back\n </div>\n <ng-container *ngIf=\"!isUpdateWidget\">\n <div *ngIf=\"islayoutCreate\"\n class=\"{{commonService.btn_success_md}} m-2 w-fit text-center cursar-pointer\"\n (click)=\"addLayoutTOview()\">Add View\n </div>\n <div *ngIf=\"!islayoutCreate && !isEditMainLayout\"\n class=\"{{commonService.btn_primary_md}} m-2 w-fit text-center cursar-pointer\"\n (click)=\"addWidgetTOview()\">Add Layout\n </div>\n <div *ngIf=\"!islayoutCreate && isEditMainLayout\"\n class=\"{{commonService.btn_primary_md}} m-2 w-fit text-center cursar-pointer\"\n (click)=\"updateLayoutWidgetTOview()\">Update Layout\n </div>\n\n </ng-container>\n\n <div class=\"{{commonService.btn_warning_md}} m-2 w-fit text-center cursar-pointer\"\n (click)=\"updateToView()\" *ngIf=\"isUpdateWidget\">Update View\n </div>\n\n </div>\n\n\n <!-- <pre><code>{{dashBoardWidgetConfig | json}}</code></pre> -->\n </ng-container>\n <ng-container *ngIf=\"isChartButtonClick\">\n <h6\n class=\"mb-2 font-bold text-md tracking-tight text-gray-900 dark:text-white border-b pb-3 flex items-center\">\n <i class=\"fa fa-bar-chart-o mr-2\"></i> Select View\n <div class=\"{{commonService.btnDarkBlack}} m-2 w-fit text-center cursor-pointer\"\n (click)=\"backToMainView()\">Back\n </div>\n </h6>\n <div class=\" h-[80vh] overflow-x-auto\">\n <div class=\"relative my-2 \">\n <input type=\"text\" [(ngModel)]=\"viewToSearch\" (keyup)=\"filterViews()\" (keydown)=\"filterViews()\"\n class=\"bg-gray-800 border border-gray-700 text-gray-200 text-sm focus:ring-gray-400 focus:border-gray-500 block w-full p-4 h-8 rounded\"\n placeholder=\"Search View\" />\n <button type=\"button\" class=\"absolute inset-y-0 right-0 flex items-center pr-6\">\n <mat-icon class=\"rotate-90 cursor-pointer\" [svgIcon]=\"'heroicons_outline:search'\"></mat-icon>\n </button>\n </div>\n <ng-container *ngFor=\"let item of filteredComponentConfig\">\n <div class=\"relative group my-3 w-full\">\n <!-- Item View Name -->\n <div class=\"text-md font-bold border-b py-2 cursar-pointer\">\n {{item.viewName}}</div>\n\n <!-- Hover Buttons -->\n <div\n class=\"absolute top-0 right-0 flex space-x-2 opacity-0 group-hover:opacity-100 transition-opacity duration-300 pb-2\">\n <button class=\"rounded-full p-2 text-white bg-blue-500 hover:bg-blue-700\">\n <i class=\"fa fa-pencil-square-o\" aria-hidden=\"true\"\n (click)=\"editComponentViews(item)\"></i>\n </button>\n <button class=\"rounded-full p-2 text-white bg-green-500 hover:bg-green-700\"\n (click)=\"getComponentConfig(item)\">\n <i class=\"fa fa-plus\"></i>\n </button>\n </div>\n </div>\n </ng-container>\n </div>\n\n </ng-container>\n <ng-container *ngIf=\"isDefaultView\">\n <ng-container *ngFor=\"let item of dashBoardWidgetConfig.widgets; let i = index\">\n <div class=\"group my-3 w-full flex justify-between border-b items-center\">\n <div class=\"text-md font-bold py-2 cursor-pointer\">\n {{item.widgetTitle}}\n </div>\n\n <div class=\"flex space-x-2\">\n <button *ngIf=\"i !== 0\" class=\"{{commonService.btn_light_sm}} cursor-pointer mx-1\"\n (click)=\"moveItemForWidget(i, 'up')\">\n <i class=\"fa fa-arrow-up\" aria-hidden=\"true\"></i>\n </button>\n\n <button *ngIf=\"i !== dashBoardWidgetConfig.widgets.length - 1\"\n class=\"{{commonService.btn_light_sm}} cursor-pointer mx-1\"\n (click)=\"moveItemForWidget(i, 'down')\">\n <i class=\"fa fa-arrow-down\" aria-hidden=\"true\"></i>\n </button>\n <button class=\"rounded-full p-2 text-white bg-blue-500 hover:bg-blue-700 mb-2\"\n (click)=\"getEditViewFromLayout(item,i)\">\n <i class=\"fa fa-pencil-square\" aria-hidden=\"true\"></i>\n\n </button>\n <button class=\"rounded-full p-2 text-white bg-red-500 hover:bg-red-700 mb-2\"\n (click)=\"getDeleteViewFromLayout(item,i)\">\n <i class=\"fa fa-trash-o\" aria-hidden=\"true\"></i>\n </button>\n\n </div>\n </div>\n </ng-container>\n </ng-container>\n\n\n </div>\n</div>\n<!-- </div> -->\n\n<dx-popup [(visible)]=\"isEditOptionClick\" [closeOnOutsideClick]=\"false\" [dragEnabled]=\"false\" [width]=\"1200\"\n [height]=\"'auto'\" [showTitle]=\"true\" class=\"popup\" title=\"{{editViewdataSourceModal.viewName}}\">\n <div *dxTemplate=\"let data of 'content'\">\n\n <app-dash-chart [datasetmodal]=\"editViewdataSourceModal\" (getChartConfigOutPut)=\"getEmitNewChartCongig($event)\"\n *ngIf=\"editViewdataSourceModal.viewType == 'chart'\"></app-dash-chart>\n <app-dash-table [datasetmodal]=\"editViewdataSourceModal\" (getTableConfigOutPut)=\"getEmitNewChartCongig($event)\"\n *ngIf=\"editViewdataSourceModal.viewType == 'table'\"></app-dash-table>\n <!-- <app-dash-other [datasetmodal]=\"editViewdataSourceModal\" *ngIf=\"editViewdataSourceModal.viewType == 'others'\"\n (createOtherComponentView)=\"getEmitNewChartCongig($event)\"></app-dash-other> -->\n </div>\n</dx-popup>\n\n\n<dx-popup [(visible)]=\"isCreateDataset\" [closeOnOutsideClick]=\"false\" [dragEnabled]=\"false\" [width]=\"1200\"\n [height]=\"600\" [showTitle]=\"true\" class=\"popup\" title=\"Dataset Editor\">\n <div *dxTemplate=\"let data of 'content'\">\n <dx-scroll-view class=\"h-full\" [width]=\"'100%'\" [height]=\"'100%'\">\n <app-create-dataset [isHeader]=\"false\"></app-create-dataset>\n </dx-scroll-view>\n </div>\n</dx-popup>\n<dx-popup [(visible)]=\"isCreateDatasetWithDatasetId\" [closeOnOutsideClick]=\"false\" [dragEnabled]=\"false\" [width]=\"1200\"\n [height]=\"600\" [showTitle]=\"true\" class=\"popup\" title=\"Dataset Editor\" (onHidden)=\"getDatasetPopupHide($event)\">\n <div *dxTemplate=\"let data of 'content'\">\n <dx-scroll-view class=\"h-full\" [width]=\"'100%'\" [height]=\"'100%'\">\n <app-create-dataset [selectedDatasetId]=\"selectedDatasetId\" [isHeader]=\"false\"></app-create-dataset>\n </dx-scroll-view>\n </div>\n</dx-popup>\n\n<dx-popup [(visible)]=\"isCreateNewViewWithDefaultView\" [closeOnOutsideClick]=\"false\" [dragEnabled]=\"false\"\n [width]=\"1200\" [height]=\"600\" [showTitle]=\"true\" class=\"popup\" title=\"Views Editor\"\n (onHidden)=\"getViewPopupHide($event)\">\n <div *dxTemplate=\"let data of 'content'\">\n <dx-scroll-view class=\"h-full\" [width]=\"'100%'\" [height]=\"'100%'\">\n <app-create-comp-view [selectedViewId]=\"selectedViewId\" [isHeader]=\"false\"></app-create-comp-view>\n </dx-scroll-view>\n </div>\n</dx-popup>\n<dx-popup [(visible)]=\"isCreateNewView\" [closeOnOutsideClick]=\"false\" [dragEnabled]=\"false\" [width]=\"1200\"\n [height]=\"600\" [showTitle]=\"true\" class=\"popup\" title=\"Views Editor\">\n <div *dxTemplate=\"let data of 'content'\">\n <dx-scroll-view class=\"h-full\" [width]=\"'100%'\" [height]=\"'100%'\">\n <app-create-comp-view [isHeader]=\"false\"></app-create-comp-view>\n </dx-scroll-view>\n </div>\n</dx-popup>\n\n\n<dx-popup [(visible)]=\"isWidgetFilters\" [closeOnOutsideClick]=\"false\" [dragEnabled]=\"false\" [width]=\"800\" [height]=\"400\"\n [showTitle]=\"true\" class=\"popup\" title=\"Dataset Filter\">\n <div *dxTemplate=\"let data of 'content'\">\n <div class=\"my-2\">\n <dx-scroll-view [width]=\"'100%'\" [height]=\"'85%'\">\n <ng-container *ngFor=\"let item of nodeproperticeFilterDataSource; let i = index\">\n <div class=\"flex flex-row my-2\">\n <div class=\"m-1\">\n <dx-text-box [(ngModel)]=\"item.columnName\"></dx-text-box>\n </div>\n <div class=\"m-1\">\n <dx-select-box [items]=\"['get','let']\" [(ngModel)]=\"item.operator\"\n placeholder=\"Operator\"></dx-select-box>\n </div>\n <div class=\"m-1\">\n <dx-text-box [(ngModel)]=\"item.value\"></dx-text-box>\n </div>\n </div>\n </ng-container>\n\n </dx-scroll-view>\n <div class=\"flex justify-end mx-1 flex-grow\">\n <button class=\"{{commonService.btn_success_md}} cursor-pointer mt-2\"\n (click)=\"submitFilter()\">Submit</button>\n </div>\n\n </div>\n\n </div>\n</dx-popup>\n<dx-popup [(visible)]=\"isAdvanceLayout\" [closeOnOutsideClick]=\"false\" [dragEnabled]=\"false\" [width]=\"1200\"\n [height]=\"700\" [showTitle]=\"true\" class=\"popup\" title=\"Dataset Filter\">\n <div *dxTemplate=\"let data of 'content'\">\n <div class=\"flex flex-row px-2 mb-3\">\n <div class=\"w-2/3 mb-2\">\n <div class=\"text-md mb-2\">Select Views</div>\n <dx-tag-box [dataSource]=\"componentConfigDataSource\" valueExpr=\"viewId\" displayExpr=\"viewName\"\n [multiline]=\"true\" [showSelectionControls]=\"true\" [(ngModel)]=\"selectedViewsIds\"\n [maxDisplayedTags]=\"3\" (onValueChanged)=\"getSelectedColumnSource($event)\" [searchEnabled]=\"true\">\n </dx-tag-box>\n </div>\n <div class=\"w-1/3 px-2\">\n <button class=\"{{commonService.btn_primary_md}} mt-6\" (click)=\"getProcessForConfig()\">\n Add To View\n </button>\n <!-- <button class=\"{{commonService.btn_danger_md}} cursor-pointer mt-6\" (click)=\"cancelCdrConfig()\">Cancel\n </button> -->\n </div>\n </div>\n <dx-scroll-view [width]=\"'100%'\" [height]=\"'80%'\">\n\n <div class=\"m-2 border-b\" *ngIf=\"isProceed\">\n <ng-container *ngFor=\"let item of advanceLayoutContainer; let i = index;\">\n <div class=\"flex flex-row m-2\">\n <div class=\"mx-2 w-1/2\">\n <div class=\"text-md mb-2\">View Name</div>\n <dx-text-box [(ngModel)]=\"item.compConfig.viewConfig[0].viewName\"></dx-text-box>\n </div>\n <div class=\"mx-2\">\n <div class=\"text-md mb-2\">Widget Title</div>\n <dx-text-box [(ngModel)]=\"item.nodeProperties.widgetTitle\"></dx-text-box>\n </div>\n\n <div class=\"mx-2\">\n <div class=\"text-md mb-2\">Widget Width</div>\n <dx-select-box [searchEnabled]=\"true\" [items]=\"widget_width\"\n [(ngModel)]=\"item.nodeProperties.width\"></dx-select-box>\n </div>\n\n <div class=\"mx-2\">\n <div class=\"text-md mb-2\">Widget Height</div>\n <dx-text-box [(ngModel)]=\"item.nodeProperties.height\"></dx-text-box>\n </div>\n <div class=\"mx-2\">\n <div class=\"text-md mb-2\">Widget Filter</div>\n <dx-select-box [items]=\"filterDataSource\" displayExpr=\"filterName\" [searchEnabled]=\"true\"\n valueExpr=\"filterId\" [(ngModel)]=\"item.filterId\"></dx-select-box>\n </div>\n <div class=\"mx-2\">\n <div class=\"text-md mt-8\">\n <dx-check-box [(ngModel)]=\"item.nodeProperties.display\" text=\"Display\"></dx-check-box>\n </div>\n </div>\n <div class=\"mx-2\">\n <button class=\"{{commonService.btn_danger_sm}} cursor-pointer mt-8\"\n (click)=\"deleteView(i)\"><i class=\"fa fa-trash-o\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n </ng-container>\n </div>\n </dx-scroll-view>\n <div class=\"flex justify-end mx-1 my-2 flex-grow\">\n <button class=\"{{commonService.btn_success_md}} cursor-pointer mt-2\" (click)=\"submitAdvanceView()\">Add\n Layout</button>\n </div>\n </div>\n</dx-popup>", styles: ["::ng-deep #scrollview-demo{min-height:550px}::ng-deep #scrollview{height:auto;position:absolute;top:0;bottom:300px;padding:20px}::ng-deep #scrollview-content{white-space:pre-wrap}.scrollable-content{height:85vh;overflow-y:auto}\n"], dependencies: [{ kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.DxTemplateDirective, selector: "[dxTemplate]", inputs: ["dxTemplateOf"] }, { kind: "component", type: i8.DxCheckBoxComponent, selector: "dx-check-box", inputs: ["accessKey", "activeStateEnabled", "disabled", "elementAttr", "focusStateEnabled", "height", "hint", "hoverStateEnabled", "iconSize", "isValid", "name", "readOnly", "rtlEnabled", "tabIndex", "text", "validationError", "validationErrors", "validationMessageMode", "validationStatus", "value", "visible", "width"], outputs: ["onContentReady", "onDisposing", "onInitialized", "onOptionChanged", "onValueChanged", "accessKeyChange", "activeStateEnabledChange", "disabledChange", "elementAttrChange", "focusStateEnabledChange", "heightChange", "hintChange", "hoverStateEnabledChange", "iconSizeChange", "isValidChange", "nameChange", "readOnlyChange", "rtlEnabledChange", "tabIndexChange", "textChange", "validationErrorChange", "validationErrorsChange", "validationMessageModeChange", "validationStatusChange", "valueChange", "visibleChange", "widthChange", "onBlur"] }, { kind: "component", type: i9.DxPopupComponent, selector: "dx-popup", inputs: ["accessKey", "animation", "closeOnOutsideClick", "container", "contentTemplate", "copyRootClassesToWrapper", "deferRendering", "disabled", "dragAndResizeArea", "dragEnabled", "dragOutsideBoundary", "elementAttr", "focusStateEnabled", "fullScreen", "height", "hideOnOutsideClick", "hideOnParentScroll", "hint", "hoverStateEnabled", "maxHeight", "maxWidth", "minHeight", "minWidth", "position", "resizeEnabled", "restorePosition", "rtlEnabled", "shading", "shadingColor", "showCloseButton", "showTitle", "tabIndex", "title", "titleTemplate", "toolbarItems", "visible", "width", "wrapperAttr"], outputs: ["onContentReady", "onDisposing", "onHidden", "onHiding", "onInitialized", "onOptionChanged", "onResize", "onResizeEnd", "onResizeStart", "onShowing", "onShown", "onTitleRendered", "accessKeyChange", "animationChange", "closeOnOutsideClickChange", "containerChange", "contentTemplateChange", "copyRootClassesToWrapperChange", "deferRenderingChange", "disabledChange", "dragAndResizeAreaChange", "dragEnabledChange", "dragOutsideBoundaryChange", "elementAttrChange", "focusStateEnabledChange", "fullScreenChange", "heightChange", "hideOnOutsideClickChange", "hideOnParentScrollChange", "hintChange", "hoverStateEnabledChange", "maxHeightChange", "maxWidthChange", "minHeightChange", "minWidthChange", "positionChange", "resizeEnabledChange", "restorePositionChange", "rtlEnabledChange", "shadingChange", "shadingColorChange", "showCloseButtonChange", "showTitleChange", "tabIndexChange", "titleChange", "titleTemplateChange", "toolbarItemsChange", "visibleChange", "widthChange", "wrapperAttrChange"] }, { kind: "component", type: i10.DxScrollViewComponent, selector: "dx-scroll-view", inputs: ["bounceEnabled", "direction", "disabled", "elementAttr", "height", "pulledDownText", "pullingDownText", "reachBottomText", "refreshingText", "rtlEnabled", "scrollByContent", "scrollByThumb", "showScrollbar", "useNative", "width"], outputs: ["onDisposing", "onInitialized", "onOptionChanged", "onPullDown", "onReachBottom", "onScroll", "onUpdated", "bounceEnabledChange", "directionChange", "disabledChange", "elementAttrChange", "heightChange", "pulledDownTextChange", "pullingDownTextChange", "reachBottomTextChange", "refreshingTextChange", "rtlEnabledChange", "scrollByContentChange", "scrollByThumbChange", "showScrollbarChange", "useNativeChange", "widthChange"] }, { kind: "component", type: i11.DxSelectBoxComponent, selector: "dx-select-box", inputs: ["acceptCustomValue", "accessKey", "activeStateEnabled", "buttons", "dataSource", "deferRendering", "disabled", "displayExpr", "displayValue", "dropDownButtonTemplate", "dropDownOptions", "elementAttr", "fieldTemplate", "focusStateEnabled", "grouped", "groupTemplate", "height", "hint", "hoverStateEnabled", "inputAttr", "isValid", "items", "itemTemplate", "label", "labelMode", "maxLength", "minSearchLength", "name", "noDataText", "opened", "openOnFieldClick", "placeholder", "readOnly", "rtlEnabled", "searchEnabled", "searchExpr", "searchMode", "searchTimeout", "selectedItem", "showClearButton", "showDataBeforeSearch", "showDropDownButton", "showSelectionControls", "spellcheck", "stylingMode", "tabIndex", "text", "useItemTextAsTitle", "validationError", "validationErrors", "validationMessageMode", "validationStatus", "value", "valueChangeEvent", "valueExpr", "visible", "width", "wrapItemText"], outputs: ["onChange", "onClosed", "onContentReady", "onCopy", "onCustomItemCreating", "onCut", "onDisposing", "onEnterKey", "onFocusIn", "onFocusOut", "onInitialized", "onInput", "onItemClick", "onKeyDown", "onKeyUp", "onOpened", "onOptionChanged", "onPaste", "onSelectionChanged", "onValueChanged", "acceptCustomValueChange", "accessKeyChange", "activeStateEnabledChange", "buttonsChange", "dataSourceChange", "deferRenderingChange", "disabledChange", "displayExprChange", "displayValueChange", "dropDownButtonTemplateChange", "dropDownOptionsChange", "elementAttrChange", "fieldTemplateChange", "focusStateEnabledChange", "groupedChange", "groupTemplateChange", "heightChange", "hintChange", "hoverStateEnabledChange", "inputAttrChange", "isValidChange", "itemsChange", "itemTemplateChange", "labelChange", "labelModeChange", "maxLengthChange", "minSearchLengthChange", "nameChange", "noDataTextChange", "openedChange", "openOnFieldClickChange", "placeholderChange", "readOnlyChange", "rtlEnabledChange", "searchEnabledChange", "searchExprChange", "searchModeChange", "searchTimeoutChange", "selectedItemChange", "showClearButtonChange", "showDataBeforeSearchChange", "showDropDownButtonChange", "showSelectionControlsChange", "spellcheckChange", "stylingModeChange", "tabIndexChange", "textChange", "useItemTextAsTitleChange", "validationErrorChange", "validationErrorsChange", "validationMessageModeChange", "validationStatusChange", "valueChange", "valueChangeEventChange", "valueExprChange", "visibleChange", "widthChange", "wrapItemTextChange", "onBlur"] }, { kind: "component", type: i12.DxTagBoxComponent, selector: "dx-tag-box", inputs: ["acceptCustomValue", "accessKey", "activeStateEnabled", "applyValueMode", "buttons", "dataSource", "deferRendering", "disabled", "displayExpr", "dropDownButtonTemplate", "dropDownOptions", "elementAttr", "fieldTemplate", "focusStateEnabled", "grouped", "groupTemplate", "height", "hideSelectedItems", "hint", "hoverStateEnabled", "inputAttr", "isValid", "items", "itemTemplate", "label", "labelMode", "maxDisplayedTags", "maxFilterQueryLength", "maxLength", "minSearchLength", "multiline", "name", "noDataText", "opened", "openOnFieldClick", "placeholder", "readOnly", "rtlEnabled", "searchEnabled", "searchExpr", "searchMode", "searchTimeout", "selectAllMode", "selectAllText", "selectedItems", "showClearButton", "showDataBeforeSearch", "showDropDownButton", "showMultiTagOnly", "showSelectionControls", "stylingMode", "tabIndex", "tagTemplate", "text", "useItemTextAsTitle", "validationError", "validationErrors", "validationMessageMode", "validationStatus", "value", "valueExpr", "visible", "width", "wrapItemText"], outputs: ["onChange", "onClosed", "onContentReady", "onCustomItemCreating", "onDisposing", "onEnterKey", "onFocusIn", "onFocusOut", "onInitialized", "onInput", "onItemClick", "onKeyDown", "onKeyUp", "onMultiTagPreparing", "onOpened", "onOptionChanged", "onSelectAllValueChanged", "onSelectionChanged", "onValueChanged", "acceptCustomValueChange", "accessKeyChange", "activeStateEnabledChange", "applyValueModeChange", "buttonsChange", "dataSourceChange", "deferRenderingChange", "disabledChange", "displayExprChange", "dropDownButtonTemplateChange", "dropDownOptionsChange", "elementAttrChange", "fieldTemplateChange", "focusStateEnabledChange", "groupedChange", "groupTemplateChange", "heightChange", "hideSelectedItemsChange", "hintChange", "hoverStateEnabledChange", "inputAttrChange", "isValidChange", "itemsChange", "itemTemplateChange", "labelChange", "labelModeChange", "maxDisplayedTagsChange", "maxFilterQueryLengthChange", "maxLengthChange", "minSearchLengthChange", "multilineChange", "nameChange", "noDataTextChange", "openedChange", "openOnFieldClickChange", "placeholderChange", "readOnlyChange", "rtlEnabledChange", "searchEnabledChange", "searchExprChange", "searchModeChange", "searchTimeoutChange", "selectAllModeChange", "selectAllTextChange", "selectedItemsChange", "showClearButtonChange", "showDataBeforeSearchChange", "showDropDownButtonChange", "showMultiTagOnlyChange", "showSelectionControlsChange", "stylingModeChange", "tabIndexChange", "tagTemplateChange", "textChange", "useItemTextAsTitleChange", "validationErrorChange", "validationErrorsChange", "validationMessageModeChange", "validationStatusChange", "valueChange", "valueExprChange", "visibleChange", "widthChange", "wrapItemTextChange", "onBlur"] }, { kind: "component", type: i13.DxTextBoxComponent, selector: "dx-text-box", inputs: ["accessKey", "activeStateEnabled", "buttons", "disabled", "elementAttr", "focusStateEnabled", "height", "hint", "hoverStateEnabled", "inputAttr", "isValid", "label", "labelMode", "mask", "maskChar", "maskInvalidMessage", "maskRules", "maxLength", "mode", "name", "placeholder", "readOnly", "rtlEnabled", "showClearButton", "showMaskMode", "spellcheck", "stylingMode", "tabIndex", "text", "useMaskedValue", "validationError", "validationErrors", "validationMessageMode", "validationStatus", "value", "valueChangeEvent", "visible", "width"], outputs: ["onChange", "onContentReady", "onCopy", "onCut", "onDisposing", "onEnterKey", "onFocusIn", "onFocusOut", "onInitialized", "onInput", "onKeyDown", "onKeyUp", "onOptionChanged", "onPaste", "onValueChanged", "accessKeyChange", "activeStateEnabledChange", "buttonsChange", "disabledChange", "elementAttrChange", "focusStateEnabledChange", "heightChange", "hintChange", "hoverStateEnabledChange", "inputAttrChange", "isValidChange", "labelChange", "labelModeChange", "maskChange", "maskCharChange", "maskInvalidMessageChange", "maskRulesChange", "maxLengthChange", "modeChange", "nameChange", "placeholderChange", "readOnlyChange", "rtlEnabledChange", "showClearButtonChange", "showMaskModeChange", "spellcheckChange", "stylingModeChange", "tabIndexChange", "textChange", "useMaskedValueChange", "validationErrorChange", "validationErrorsChange", "validationMessageModeChange", "validationStatusChange", "valueChange", "valueChangeEventChange", "visibleChange", "widthChange", "onBlur"] }, { kind: "directive", type: i14.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: i14.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i14.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i15.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i16.LoadingComponent, selector: "app-loading" }, { kind: "component", type: i17.CreateCompViewComponent, selector: "app-create-comp-view", inputs: ["kpiTreeData", "isHeader", "selectedViewId"] }, { kind: "component", type: i18.DashChartComponent, selector: "app-dash-chart", inputs: ["datasetmodal"], outputs: ["getChartConfigOutPut"] }, { kind: "component", type: i19.DashTableComponent, selector: "app-dash-table", inputs: ["datasetmodal"], outputs: ["getTableConfigOutPut"] }, { kind: "component", type: i20.CreateDatasetComponent, selector: "app-create-dataset", inputs: ["isHeader", "selectedDatasetId"] }, { kind: "component", type: i21.CommonHeaderComponent, selector: "lib-common-header", inputs: ["pageTitle"] }] });
|
|
961
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: PageConfigComponent, decorators: [{
|
|
962
|
+
type: Component,
|
|
963
|
+
args: [{ selector: 'app-dashbord-config', template: "<app-loading *ngIf=\"loadingModal\"></app-loading>\n\n<!-- <div class=\"flex flex-col flex-auto w-full\"> -->\n<div class=\"flex flex-row h-screen\">\n <div class=\"flex-grow border-r h-full\">\n <div class=\"scrollable-content\">\n <!-- <div class=\"flex flex-wrap p-2 border\"> -->\n <!-- <app-advance-header [filterItems]=\"filterItems\" [pageTitle]=\"'Dashboard'\" [isEditButton]=\"false\"\n [isAdvanceButton]=\"true\"></app-advance-header> -->\n <div class=\"flex flex-wrap my-3\" #dynamicContainer></div>\n\n </div>\n <div class=\"flex flex-row justify-center items-center h-16 m-2 border\">\n <lib-common-header [pageTitle]=\"''\"></lib-common-header>\n <!-- <div class=\"{{commonService.btn_success_md}} m-2 \" (click)=\"getCreateDataSetPage()\">Create\n Dataset\n </div> -->\n <div class=\"{{commonService.btn_primary_md}} m-2\" (click)=\"addWidget()\">Add Layout\n </div>\n <!-- <div class=\"{{commonService.btn_success_md}} m-2\" (click)=\"getCreateViewPage()\">Create\n View\n </div> -->\n <div class=\"{{commonService.btnOthersPurple}} m-2 cursar-pointer\" (click)=\"getViewPage()\">View Page\n </div>\n <!-- <div class=\"{{commonService.btn_warning_md}} m-2 cursar-pointer\" (click)=\"getAllPage()\">All Pages\n </div> -->\n\n </div>\n </div>\n <div class=\"flex-shrink-0 w-1/4 p-2 h-full\">\n <ng-container *ngIf=\"isDashBoardContent\">\n <div class=\"{{commonService.btnDarkBlack}} m-2 w-fit text-center cursar-pointer\" (click)=\"backToMainView()\">\n Back\n </div>\n <ng-container *ngFor=\"let item of page_config.api_config; let i = index\">\n <div class=\"mb-2 flex flex-row justify-between items-center border-b\">\n <div class=\"text-md py-2 font-bold text-white px-2\">\n {{item.widGetConfig.widgetTitle}}\n </div>\n <div class=\"flex space-x-2\">\n <!-- <button (click)=\"editSelectedWidget(item, i)\"\n class=\"w-8 h-8 bg-sky-600 hover:bg-blue-800 text-white rounded-full flex items-center justify-center\">\n <i class=\"fa fa-edit\"></i>\n </button> -->\n <button\n class=\"w-8 h-8 bg-red-600 hover:bg-red-800 text-white rounded-full flex items-center justify-center\">\n <i class=\"fa fa-trash-o\"></i>\n </button>\n </div>\n </div>\n\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"isWidgetCreationContent\">\n <h6 class=\"mb-2 font-bold text-lg tracking-tight text-gray-900 dark:text-white border-b pb-3\">\n <span *ngIf=\"!islayoutCreate\">Widget Settings</span>\n <span *ngIf=\"islayoutCreate\">Layout Settings</span>\n </h6>\n <div class=\"flex flex-row my-4\">\n <dx-check-box class=\"ml-auto\" [(ngModel)]=\"addedwidGetConfig.display\" text=\"Display\"></dx-check-box>\n </div>\n <div class=\"flex flex-row mb-2 justify-between\">\n <span class=\"text-md my-auto px-2\">Width</span>\n <dx-select-box class=\"w-1/2\" [items]=\"widget_width\"\n [(ngModel)]=\"addedwidGetConfig.width\"></dx-select-box>\n </div>\n <div class=\"flex flex-row mb-2 justify-between\">\n <span class=\"text-md my-auto px-2\">Height</span>\n <dx-text-box class=\"w-1/2\" [(ngModel)]=\"addedwidGetConfig.height\"></dx-text-box>\n </div>\n\n <div class=\"flex flex-row mb-2 justify-between\" *ngIf=\"!islayoutCreate\">\n <span class=\"text-md my-auto px-2\">Widget Title</span>\n <dx-text-box class=\"w-1/2\" [(ngModel)]=\"widgetTitle\"></dx-text-box>\n </div>\n <div class=\"flex flex-row mb-2 justify-between\" *ngIf=\"!islayoutCreate\">\n <span class=\"text-md my-auto px-2\">Widget Name</span>\n <dx-text-box class=\"w-1/2\" [(ngModel)]=\"widgetName\"></dx-text-box>\n </div>\n\n\n <div class=\"flex flex-row mb-5 justify-between\" *ngIf=\"islayoutCreate\">\n <span class=\"text-sm my-auto px-2\">Layout Title</span>\n <dx-text-box class=\"w-1/2\" [(ngModel)]=\"addedwidGetConfig.widgetTitle\"></dx-text-box>\n </div>\n\n <div class=\"flex flex-row mb-2 justify-between\">\n <span class=\"text-md my-auto px-2\">Filter</span>\n <dx-select-box class=\"w-1/2\" [items]=\"filterDataSource\" displayExpr=\"filterName\" [searchEnabled]=\"true\"\n valueExpr=\"filterId\" [(ngModel)]=\"selectedFilterId\"\n (onValueChanged)=\"getFilterValueById($event)\"></dx-select-box>\n </div>\n <ng-container *ngIf=\"!isUpdateWidget\">\n <div class=\"mt-6\" *ngIf=\"!islayoutCreate && isEditMainLayout\">\n <ng-container\n *ngFor=\"let item of dashBoardWidgetConfig.widgets[newWidgetIndex].widgetNode;let i = index\">\n <div class=\"mb-2 flex flex-row justify-between items-center border-b \">\n <div class=\"text-md py-2 font-bold text-white px-2\">\n {{item.nodeProperties.widgetTitle}}\n </div>\n <div class=\"flex space-x-2\">\n <button *ngIf=\"i !== 0\" class=\"{{commonService.btn_light_sm}} cursor-pointer mx-1\"\n (click)=\"moveItemForPageView(i, 'up')\">\n <i class=\"fa fa-arrow-up\" aria-hidden=\"true\"></i>\n </button>\n\n <button\n *ngIf=\"i !== dashBoardWidgetConfig.widgets[newWidgetIndex].widgetNode.length - 1\"\n class=\"{{commonService.btn_light_sm}} cursor-pointer mx-1\"\n (click)=\"moveItemForPageView(i, 'down')\">\n <i class=\"fa fa-arrow-down\" aria-hidden=\"true\"></i>\n </button>\n <button\n class=\"w-8 h-8 bg-red-600 hover:bg-red-800 text-white rounded-full flex items-center justify-center\">\n <i class=\"fa fa-trash-o\"></i>\n </button>\n </div>\n </div>\n\n </ng-container>\n </div>\n </ng-container>\n\n\n\n <ng-container *ngIf=\"isUpdateWidget\">\n <div class=\"text-sm py-1 font-extrabold border-b bg-gray-700 text-white px-2\"> Application Views\n </div>\n <div class=\"border-x border-b p-2\">\n <ng-container *ngFor=\"let item of allWidgetInnerContent; let i = index\">\n <div class=\"group w-full flex justify-between border-b items-center\">\n <div class=\"text-md font-bold py-2 cursor-pointer\">\n {{item.viewName}}\n </div>\n\n <div class=\"flex space-x-2\">\n <button *ngIf=\"i !== 0\" class=\"{{commonService.btn_light_sm}} cursor-pointer mx-1\"\n (click)=\"moveItemForColumns(i, 'up')\">\n <i class=\"fa fa-arrow-up\" aria-hidden=\"true\"></i>\n </button>\n\n <button *ngIf=\"i !== allWidgetInnerContent.length - 1\"\n class=\"{{commonService.btn_light_sm}} cursor-pointer mx-1\"\n (click)=\"moveItemForColumns(i, 'down')\">\n <i class=\"fa fa-arrow-down\" aria-hidden=\"true\"></i>\n </button>\n <button class=\"rounded-full p-2 text-white bg-blue-500 hover:bg-blue-700 mb-2\"\n (click)=\"editComponentViews(item)\">\n <i class=\"fa fa-eye\" aria-hidden=\"true\"></i>\n </button>\n <button class=\"rounded-full p-2 text-white bg-blue-500 hover:bg-blue-700 mb-2\"\n (click)=\"editComponentDatasets(item)\">\n <i class=\"fa fa-database\" aria-hidden=\"true\"></i>\n </button>\n <button class=\"rounded-full p-2 text-white bg-red-500 hover:bg-red-700 mb-2\"\n (click)=\"getDeleteViewFromConfig(i)\">\n <i class=\"fa fa-trash-o\" aria-hidden=\"true\"></i>\n </button>\n </div>\n\n </div>\n </ng-container>\n </div>\n </ng-container>\n <ng-container *ngIf=\"isUpdateWidget\">\n <div class=\"text-sm py-1 font-extrabold border-b bg-gray-700 text-white px-2\"> Add Filter For View\n\n </div>\n <div class=\"border-x border-b p-2\">\n <div class=\"flex flex-row py-3 border-b\">\n <dx-check-box [(ngModel)]=\"addedwidGetConfig.isWidgetFilter\"\n text=\"Popup Columns Filter Enable\"></dx-check-box>\n </div>\n <div class=\"flex flex-row my-2 border-b\">\n <ng-container *ngFor=\"let item of nodeProperticeFilters; let i = index\">\n <div class=\"flex flex-wrap border-b\">\n <div class=\"px-1 w-1/3\">\n <div class=\"text-md\">Input Type</div>\n <dx-select-box [items]=\"['text']\" [(ngModel)]=\"item.input_type\"\n value=\"text\"></dx-select-box>\n </div>\n <div class=\"px-1-1 w-2/3\" *ngIf=\"item.input_type == 'text'\">\n <div class=\"text-md\">Server Column</div>\n <dx-text-box [(ngModel)]=\"item.server_column\"></dx-text-box>\n </div>\n <div class=\"px-1-1 w-1/2\" *ngIf=\"item.input_type == 'text'\">\n <div class=\"text-md\">Local Column</div>\n <dx-text-box [(ngModel)]=\"item.local_column\"></dx-text-box>\n </div>\n <div class=\"px-1-1 w-1/3\" *ngIf=\"item.input_type == 'select'\">\n <div class=\"text-md\">Columns Name</div>\n <dx-text-box [(ngModel)]=\"item.select_box_option\"></dx-text-box>\n </div>\n <div class=\"px-1-1 w-1/2\">\n <div class=\"flex justify-end\">\n <div class=\"{{commonService.btn_danger_sm}} w-24 mt-6 text-center\"\n (click)=\"deleteNodeFilter(i)\">Delete Filter</div>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n <div class=\"{{commonService.btn_primary_sm}} w-auto text-center\"\n (click)=\"getNodeProperticeFilterOption()\">Add\n Filter</div>\n </div>\n </ng-container>\n\n <div class=\"flex flex-row justify-end items-center h-16 m-2\">\n <div class=\"{{commonService.btnDarkBlack}} m-2 w-fit text-center cursar-pointer\"\n (click)=\"backToMainView()\">Back\n </div>\n <ng-container *ngIf=\"!isUpdateWidget\">\n <div *ngIf=\"islayoutCreate\"\n class=\"{{commonService.btn_success_md}} m-2 w-fit text-center cursar-pointer\"\n (click)=\"addLayoutTOview()\">Add View\n </div>\n <div *ngIf=\"!islayoutCreate && !isEditMainLayout\"\n class=\"{{commonService.btn_primary_md}} m-2 w-fit text-center cursar-pointer\"\n (click)=\"addWidgetTOview()\">Add Layout\n </div>\n <div *ngIf=\"!islayoutCreate && isEditMainLayout\"\n class=\"{{commonService.btn_primary_md}} m-2 w-fit text-center cursar-pointer\"\n (click)=\"updateLayoutWidgetTOview()\">Update Layout\n </div>\n\n </ng-container>\n\n <div class=\"{{commonService.btn_warning_md}} m-2 w-fit text-center cursar-pointer\"\n (click)=\"updateToView()\" *ngIf=\"isUpdateWidget\">Update View\n </div>\n\n </div>\n\n\n <!-- <pre><code>{{dashBoardWidgetConfig | json}}</code></pre> -->\n </ng-container>\n <ng-container *ngIf=\"isChartButtonClick\">\n <h6\n class=\"mb-2 font-bold text-md tracking-tight text-gray-900 dark:text-white border-b pb-3 flex items-center\">\n <i class=\"fa fa-bar-chart-o mr-2\"></i> Select View\n <div class=\"{{commonService.btnDarkBlack}} m-2 w-fit text-center cursor-pointer\"\n (click)=\"backToMainView()\">Back\n </div>\n </h6>\n <div class=\" h-[80vh] overflow-x-auto\">\n <div class=\"relative my-2 \">\n <input type=\"text\" [(ngModel)]=\"viewToSearch\" (keyup)=\"filterViews()\" (keydown)=\"filterViews()\"\n class=\"bg-gray-800 border border-gray-700 text-gray-200 text-sm focus:ring-gray-400 focus:border-gray-500 block w-full p-4 h-8 rounded\"\n placeholder=\"Search View\" />\n <button type=\"button\" class=\"absolute inset-y-0 right-0 flex items-center pr-6\">\n <mat-icon class=\"rotate-90 cursor-pointer\" [svgIcon]=\"'heroicons_outline:search'\"></mat-icon>\n </button>\n </div>\n <ng-container *ngFor=\"let item of filteredComponentConfig\">\n <div class=\"relative group my-3 w-full\">\n <!-- Item View Name -->\n <div class=\"text-md font-bold border-b py-2 cursar-pointer\">\n {{item.viewName}}</div>\n\n <!-- Hover Buttons -->\n <div\n class=\"absolute top-0 right-0 flex space-x-2 opacity-0 group-hover:opacity-100 transition-opacity duration-300 pb-2\">\n <button class=\"rounded-full p-2 text-white bg-blue-500 hover:bg-blue-700\">\n <i class=\"fa fa-pencil-square-o\" aria-hidden=\"true\"\n (click)=\"editComponentViews(item)\"></i>\n </button>\n <button class=\"rounded-full p-2 text-white bg-green-500 hover:bg-green-700\"\n (click)=\"getComponentConfig(item)\">\n <i class=\"fa fa-plus\"></i>\n </button>\n </div>\n </div>\n </ng-container>\n </div>\n\n </ng-container>\n <ng-container *ngIf=\"isDefaultView\">\n <ng-container *ngFor=\"let item of dashBoardWidgetConfig.widgets; let i = index\">\n <div class=\"group my-3 w-full flex justify-between border-b items-center\">\n <div class=\"text-md font-bold py-2 cursor-pointer\">\n {{item.widgetTitle}}\n </div>\n\n <div class=\"flex space-x-2\">\n <button *ngIf=\"i !== 0\" class=\"{{commonService.btn_light_sm}} cursor-pointer mx-1\"\n (click)=\"moveItemForWidget(i, 'up')\">\n <i class=\"fa fa-arrow-up\" aria-hidden=\"true\"></i>\n </button>\n\n <button *ngIf=\"i !== dashBoardWidgetConfig.widgets.length - 1\"\n class=\"{{commonService.btn_light_sm}} cursor-pointer mx-1\"\n (click)=\"moveItemForWidget(i, 'down')\">\n <i class=\"fa fa-arrow-down\" aria-hidden=\"true\"></i>\n </button>\n <button class=\"rounded-full p-2 text-white bg-blue-500 hover:bg-blue-700 mb-2\"\n (click)=\"getEditViewFromLayout(item,i)\">\n <i class=\"fa fa-pencil-square\" aria-hidden=\"true\"></i>\n\n </button>\n <button class=\"rounded-full p-2 text-white bg-red-500 hover:bg-red-700 mb-2\"\n (click)=\"getDeleteViewFromLayout(item,i)\">\n <i class=\"fa fa-trash-o\" aria-hidden=\"true\"></i>\n </button>\n\n </div>\n </div>\n </ng-container>\n </ng-container>\n\n\n </div>\n</div>\n<!-- </div> -->\n\n<dx-popup [(visible)]=\"isEditOptionClick\" [closeOnOutsideClick]=\"false\" [dragEnabled]=\"false\" [width]=\"1200\"\n [height]=\"'auto'\" [showTitle]=\"true\" class=\"popup\" title=\"{{editViewdataSourceModal.viewName}}\">\n <div *dxTemplate=\"let data of 'content'\">\n\n <app-dash-chart [datasetmodal]=\"editViewdataSourceModal\" (getChartConfigOutPut)=\"getEmitNewChartCongig($event)\"\n *ngIf=\"editViewdataSourceModal.viewType == 'chart'\"></app-dash-chart>\n <app-dash-table [datasetmodal]=\"editViewdataSourceModal\" (getTableConfigOutPut)=\"getEmitNewChartCongig($event)\"\n *ngIf=\"editViewdataSourceModal.viewType == 'table'\"></app-dash-table>\n <!-- <app-dash-other [datasetmodal]=\"editViewdataSourceModal\" *ngIf=\"editViewdataSourceModal.viewType == 'others'\"\n (createOtherComponentView)=\"getEmitNewChartCongig($event)\"></app-dash-other> -->\n </div>\n</dx-popup>\n\n\n<dx-popup [(visible)]=\"isCreateDataset\" [closeOnOutsideClick]=\"false\" [dragEnabled]=\"false\" [width]=\"1200\"\n [height]=\"600\" [showTitle]=\"true\" class=\"popup\" title=\"Dataset Editor\">\n <div *dxTemplate=\"let data of 'content'\">\n <dx-scroll-view class=\"h-full\" [width]=\"'100%'\" [height]=\"'100%'\">\n <app-create-dataset [isHeader]=\"false\"></app-create-dataset>\n </dx-scroll-view>\n </div>\n</dx-popup>\n<dx-popup [(visible)]=\"isCreateDatasetWithDatasetId\" [closeOnOutsideClick]=\"false\" [dragEnabled]=\"false\" [width]=\"1200\"\n [height]=\"600\" [showTitle]=\"true\" class=\"popup\" title=\"Dataset Editor\" (onHidden)=\"getDatasetPopupHide($event)\">\n <div *dxTemplate=\"let data of 'content'\">\n <dx-scroll-view class=\"h-full\" [width]=\"'100%'\" [height]=\"'100%'\">\n <app-create-dataset [selectedDatasetId]=\"selectedDatasetId\" [isHeader]=\"false\"></app-create-dataset>\n </dx-scroll-view>\n </div>\n</dx-popup>\n\n<dx-popup [(visible)]=\"isCreateNewViewWithDefaultView\" [closeOnOutsideClick]=\"false\" [dragEnabled]=\"false\"\n [width]=\"1200\" [height]=\"600\" [showTitle]=\"true\" class=\"popup\" title=\"Views Editor\"\n (onHidden)=\"getViewPopupHide($event)\">\n <div *dxTemplate=\"let data of 'content'\">\n <dx-scroll-view class=\"h-full\" [width]=\"'100%'\" [height]=\"'100%'\">\n <app-create-comp-view [selectedViewId]=\"selectedViewId\" [isHeader]=\"false\"></app-create-comp-view>\n </dx-scroll-view>\n </div>\n</dx-popup>\n<dx-popup [(visible)]=\"isCreateNewView\" [closeOnOutsideClick]=\"false\" [dragEnabled]=\"false\" [width]=\"1200\"\n [height]=\"600\" [showTitle]=\"true\" class=\"popup\" title=\"Views Editor\">\n <div *dxTemplate=\"let data of 'content'\">\n <dx-scroll-view class=\"h-full\" [width]=\"'100%'\" [height]=\"'100%'\">\n <app-create-comp-view [isHeader]=\"false\"></app-create-comp-view>\n </dx-scroll-view>\n </div>\n</dx-popup>\n\n\n<dx-popup [(visible)]=\"isWidgetFilters\" [closeOnOutsideClick]=\"false\" [dragEnabled]=\"false\" [width]=\"800\" [height]=\"400\"\n [showTitle]=\"true\" class=\"popup\" title=\"Dataset Filter\">\n <div *dxTemplate=\"let data of 'content'\">\n <div class=\"my-2\">\n <dx-scroll-view [width]=\"'100%'\" [height]=\"'85%'\">\n <ng-container *ngFor=\"let item of nodeproperticeFilterDataSource; let i = index\">\n <div class=\"flex flex-row my-2\">\n <div class=\"m-1\">\n <dx-text-box [(ngModel)]=\"item.columnName\"></dx-text-box>\n </div>\n <div class=\"m-1\">\n <dx-select-box [items]=\"['get','let']\" [(ngModel)]=\"item.operator\"\n placeholder=\"Operator\"></dx-select-box>\n </div>\n <div class=\"m-1\">\n <dx-text-box [(ngModel)]=\"item.value\"></dx-text-box>\n </div>\n </div>\n </ng-container>\n\n </dx-scroll-view>\n <div class=\"flex justify-end mx-1 flex-grow\">\n <button class=\"{{commonService.btn_success_md}} cursor-pointer mt-2\"\n (click)=\"submitFilter()\">Submit</button>\n </div>\n\n </div>\n\n </div>\n</dx-popup>\n<dx-popup [(visible)]=\"isAdvanceLayout\" [closeOnOutsideClick]=\"false\" [dragEnabled]=\"false\" [width]=\"1200\"\n [height]=\"700\" [showTitle]=\"true\" class=\"popup\" title=\"Dataset Filter\">\n <div *dxTemplate=\"let data of 'content'\">\n <div class=\"flex flex-row px-2 mb-3\">\n <div class=\"w-2/3 mb-2\">\n <div class=\"text-md mb-2\">Select Views</div>\n <dx-tag-box [dataSource]=\"componentConfigDataSource\" valueExpr=\"viewId\" displayExpr=\"viewName\"\n [multiline]=\"true\" [showSelectionControls]=\"true\" [(ngModel)]=\"selectedViewsIds\"\n [maxDisplayedTags]=\"3\" (onValueChanged)=\"getSelectedColumnSource($event)\" [searchEnabled]=\"true\">\n </dx-tag-box>\n </div>\n <div class=\"w-1/3 px-2\">\n <button class=\"{{commonService.btn_primary_md}} mt-6\" (click)=\"getProcessForConfig()\">\n Add To View\n </button>\n <!-- <button class=\"{{commonService.btn_danger_md}} cursor-pointer mt-6\" (click)=\"cancelCdrConfig()\">Cancel\n </button> -->\n </div>\n </div>\n <dx-scroll-view [width]=\"'100%'\" [height]=\"'80%'\">\n\n <div class=\"m-2 border-b\" *ngIf=\"isProceed\">\n <ng-container *ngFor=\"let item of advanceLayoutContainer; let i = index;\">\n <div class=\"flex flex-row m-2\">\n <div class=\"mx-2 w-1/2\">\n <div class=\"text-md mb-2\">View Name</div>\n <dx-text-box [(ngModel)]=\"item.compConfig.viewConfig[0].viewName\"></dx-text-box>\n </div>\n <div class=\"mx-2\">\n <div class=\"text-md mb-2\">Widget Title</div>\n <dx-text-box [(ngModel)]=\"item.nodeProperties.widgetTitle\"></dx-text-box>\n </div>\n\n <div class=\"mx-2\">\n <div class=\"text-md mb-2\">Widget Width</div>\n <dx-select-box [searchEnabled]=\"true\" [items]=\"widget_width\"\n [(ngModel)]=\"item.nodeProperties.width\"></dx-select-box>\n </div>\n\n <div class=\"mx-2\">\n <div class=\"text-md mb-2\">Widget Height</div>\n <dx-text-box [(ngModel)]=\"item.nodeProperties.height\"></dx-text-box>\n </div>\n <div class=\"mx-2\">\n <div class=\"text-md mb-2\">Widget Filter</div>\n <dx-select-box [items]=\"filterDataSource\" displayExpr=\"filterName\" [searchEnabled]=\"true\"\n valueExpr=\"filterId\" [(ngModel)]=\"item.filterId\"></dx-select-box>\n </div>\n <div class=\"mx-2\">\n <div class=\"text-md mt-8\">\n <dx-check-box [(ngModel)]=\"item.nodeProperties.display\" text=\"Display\"></dx-check-box>\n </div>\n </div>\n <div class=\"mx-2\">\n <button class=\"{{commonService.btn_danger_sm}} cursor-pointer mt-8\"\n (click)=\"deleteView(i)\"><i class=\"fa fa-trash-o\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n </ng-container>\n </div>\n </dx-scroll-view>\n <div class=\"flex justify-end mx-1 my-2 flex-grow\">\n <button class=\"{{commonService.btn_success_md}} cursor-pointer mt-2\" (click)=\"submitAdvanceView()\">Add\n Layout</button>\n </div>\n </div>\n</dx-popup>", styles: ["::ng-deep #scrollview-demo{min-height:550px}::ng-deep #scrollview{height:auto;position:absolute;top:0;bottom:300px;padding:20px}::ng-deep #scrollview-content{white-space:pre-wrap}.scrollable-content{height:85vh;overflow-y:auto}\n"] }]
|
|
964
|
+
}], ctorParameters: function () { return [{ type: i1.CommonService }, { type: i2.ActivatedRoute }, { type: i0.ViewContainerRef }, { type: i0.ComponentFactoryResolver }, { type: i3.ApplicationContentService }, { type: i4.ToastrService }, { type: i2.Router }, { type: i5.ApplicationDatssetsCall }]; }, propDecorators: { dynamicComponentContainer: [{
|
|
965
|
+
type: ViewChild,
|
|
966
|
+
args: ['dynamicComponentContainer', { read: ViewContainerRef }]
|
|
967
|
+
}], containerRef: [{
|
|
968
|
+
type: ViewChild,
|
|
969
|
+
args: ['container', { read: ViewContainerRef }]
|
|
970
|
+
}], dynamicContainer: [{
|
|
971
|
+
type: ViewChild,
|
|
972
|
+
args: ['dynamicContainer', { static: true }]
|
|
973
|
+
}], scrollView: [{
|
|
974
|
+
type: ViewChild,
|
|
975
|
+
args: [DxScrollViewComponent, { static: false }]
|
|
976
|
+
}] } });
|
|
977
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFnZS1jb25maWcuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZ2FtbWEtYXBwLWNvbnRyb2xsZXIvc3JjL2xpYi9hcHBsaWNhdGlvbi1jb250cm9sbGVyL3BhZ2UtY29udHJvbGxlci9wYWdlLWNvbmZpZy9wYWdlLWNvbmZpZy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9nYW1tYS1hcHAtY29udHJvbGxlci9zcmMvbGliL2FwcGxpY2F0aW9uLWNvbnRyb2xsZXIvcGFnZS1jb250cm9sbGVyL3BhZ2UtY29uZmlnL3BhZ2UtY29uZmlnLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBaUIsU0FBUyxFQUFrRyxTQUFTLEVBQWdCLGdCQUFnQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBSXBNLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUUvQyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUUzRCxPQUFPLE1BQU0sTUFBTSx1QkFBdUIsQ0FBQztBQUMzQyxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxxRkFBcUYsQ0FBQztBQUNsSSxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSx5RUFBeUUsQ0FBQztBQUNwSCxPQUFPLEVBQUUsaUNBQWlDLEVBQUUsTUFBTSxtR0FBbUcsQ0FBQztBQUN0SixPQUFPLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSwyRkFBMkYsQ0FBQztBQUMxSSxPQUFPLEVBQUUsa0NBQWtDLEVBQUUsTUFBTSxxR0FBcUcsQ0FBQztBQUN6SixPQUFPLEVBQUUsa0NBQWtDLEVBQUUsTUFBTSxxR0FBcUcsQ0FBQztBQUV6SixPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxtRkFBbUYsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFP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dG9yeVJlc29sdmVyLCBDb21wb25lbnRSZWYsIEVsZW1lbnRSZWYsIEhvc3RMaXN0ZW5lciwgT25EZXN0cm95LCBPbkluaXQsIFF1ZXJ5TGlzdCwgVmlld0NoaWxkLCBWaWV3Q2hpbGRyZW4sIFZpZXdDb250YWluZXJSZWYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlLCBOYXZpZ2F0aW9uRXh0cmFzLCBSb3V0ZXIgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgVG9hc3RyU2VydmljZSB9IGZyb20gJ25neC10b2FzdHInO1xuaW1wb3J0IHsgZm9ya0pvaW4gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGNvbmZpcm0gfSBmcm9tICdkZXZleHRyZW1lL3VpL2RpYWxvZyc7XG5pbXBvcnQgeyBBcHBsaWNhdGlvbkNvbnRlbnRTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vYXBwbGljYXRpb24tY29udGVudC5zZXJ2aWNlJztcbmltcG9ydCB7IER4U2Nyb2xsVmlld0NvbXBvbmVudCB9IGZyb20gJ2RldmV4dHJlbWUtYW5ndWxhcic7XG5pbXBvcnQgeyBBcHBsaWNhdGlvbkRhdHNzZXRzQ2FsbCB9IGZyb20gJy4uLy4uL2FwcGxpY2F0aW9uLWRhdGFzZXQtY2FsbC5zZXJ2aWNlJztcbmltcG9ydCBtb21lbnQgZnJvbSAnLi8uLi8uLi9tb21lbnQtaGVscGVyJztcbmltcG9ydCB7IEdhbW1hVG9kYXlQcmV2aW91c0NvbXBvbmVudCB9IGZyb20gJy4uLy4uL3NoYXJlZC9hZHZhbmNlZC1jb21wb25lbnQvZ2FtbWEtdG9kYXktcHJldmlvdXMvZ2FtbWEtdG9kYXktcHJldmlvdXMuY29tcG9uZW50JztcbmltcG9ydCB7IEFwcEFkdmFuY2VIZWFkZXJDb21wb25lbnQgfSBmcm9tICcuLi8uLi9zaGFyZWQvYWR2YW5jZWQtY29tcG9uZW50L2FwcC1hZHZhbmNlLWhlYWRlci9hcHAtaGVhZGVyLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBHYW1tYVRhYmxlV2l0aFBlcmNlbnRhZ2VDb21wb25lbnQgfSBmcm9tICcuLi8uLi9zaGFyZWQvYWR2YW5jZWQtY29tcG9uZW50L2dhbW1hLXRhYmxlLXdpdGgtcGVyY2VudGFnZS9nYW1tYS10YWJsZS13aXRoLXBlcmNlbnRhZ2UuY29tcG9uZW50JztcbmltcG9ydCB7IEdhbW1TaW5nbGVOdW1iZXJDYXJkQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vc2hhcmVkL2FkdmFuY2VkLWNvbXBvbmVudC9nYW1tLXNpbmdsZS1udW1iZXItY2FyZC9nYW1tLXNpbmdsZS1udW1iZXItY2FyZC5jb21wb25lbnQnO1xuaW1wb3J0IHsgR2FtbWFBZHZhbmNlT3BlcmF0b3JUYWJsZUNvbXBvbmVudCB9IGZyb20gJy4uLy4uL3NoYXJlZC9hZHZhbmNlZC1jb21wb25lbnQvZ2FtbWEtYWR2YW5jZS1vcGVyYXRvci10YWJsZS9nYW1tYS1hZHZhbmNlLW9wZXJhdG9yLXRhYmxlLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBBZHZhbmNlV2lkZ2V0SGVhZGVyRmlsdGVyQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vc2hhcmVkL2FkdmFuY2VkLWNvbXBvbmVudC9hZHZhbmNlLXdpZGdldC1oZWFkZXItZmlsdGVyL2FkdmFuY2Utd2lkZ2V0LWhlYWRlci1maWx0ZXIuY29tcG9uZW50JztcbmltcG9ydCB7IENvbW1vblNlcnZpY2UgfSBmcm9tICcuLi8uLi9jb21tb24nO1xuaW1wb3J0IHsgR2FtbWFBZHZhbmNlQ2hhcnRDb21wb25lbnQgfSBmcm9tICcuLi8uLi9zaGFyZWQvYWR2YW5jZWQtY29tcG9uZW50L2dhbW1hLWFkdmFuY2UtY2hhcnQvZ2FtbWEtYWR2YW5jZS1jaGFydC5jb21wb25lbnQnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtZGFzaGJvcmQtY29uZmlnJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3BhZ2UtY29uZmlnLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vcGFnZS1jb25maWcuY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBQYWdlQ29uZmlnQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICBkYXNoYm9yZF9jb250YWluZXI6IGFueSA9IFtdO1xuICBzZWxlY3RlZF93aWR0aDogYW55O1xuICB3aWRnZXRfd2lkdGggPSBbJ3ctZnVsbCcsICd3LTEvMicsICd3LTEvMycsICd3LTIvMycsICd3LTEvNCcsICd3LTMvNCcsICd3LTEvNScsICd3LTQvNScsICd3LTEvNicsICd3LTUvNiddXG4gIGxvYWRpbmdNb2RhbDogYm9vbGVhbiA9IHRydWU7XG4gIGN1c3RvbWVyczogYW55O1xuICBwYWdlSGVhZGVyc0RhdGE6IGFueTtcbiAgcGFnZV90aXRsZSA9ICdEYXNoYm9hcmQnO1xuICBpc1NydlR5cGVPcGVyYXRvcjogYm9vbGVhbjtcbiAgZGVmYXVsdFN0YXJ0RGF0ZTtcbiAgZGVmYXVsdEVuZERhdGU7XG4gIHBhZ2VfY29uZmlnO1xuICBvcGVyYXRpb25MZXZlbHM6IGFueTtcbiAgZmlsdGVyX3ZhbHVlO1xuICBpc1RvZ2dsZVN3aWNoOiBib29sZWFuID0gdHJ1ZTtcbiAgaXNEYXRlUGlja2VyOiBib29sZWFuID0gZmFsc2U7XG4gIGlzVG9nZ2xlRXZlbnRTdGF0dXM6IGJvb2xlYW4gPSBmYWxzZTtcbiAgaXNFZGl0Q2xpY2s6IGJvb2xlYW4gPSBmYWxzZTtcbiAgaXNDb25maWdWaWV3OiBib29sZWFuO1xuICBpc0xvYWRlcjogYm9vbGVhbjtcbiAgY29tcG9uZW50TmFtZTogYW55O1xuICBpc1VwZGF0ZVdpZGdldDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIGlzQ2hhcnRCdXR0b25DbGljazogYm9vbGVhbjtcbiAgY2hhcnRBY2Nlc3M6IGFueTtcbiAgY2hhcnRUeXBlOiBhbnk7XG4gIGRhc2hDaGFydENvbVNvdXJjZTogYW55O1xuICBpc0dlbmVyYXRlOiBib29sZWFuXG4gIGlzRmlsdGVySW5wdXRzOiBib29sZWFuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3RvclxuICAgKi9cblxuICBAVmlld0NoaWxkKCdkeW5hbWljQ29tcG9uZW50Q29udGFpbmVyJywgeyByZWFkOiBWaWV3Q29udGFpbmVyUmVmIH0pXG4gIGR5bmFtaWNDb21wb25lbnRDb250YWluZXI6IFZpZXdDb250YWluZXJSZWY7XG4gIEBWaWV3Q2hpbGQoJ2NvbnRhaW5lcicsIHsgcmVhZDogVmlld0NvbnRhaW5lclJlZiB9KVxuICBjb250YWluZXJSZWY6IFZpZXdDb250YWluZXJSZWY7XG4gIEBWaWV3Q2hpbGQoJ2R5bmFtaWNDb250YWluZXInLCB7IHN0YXRpYzogdHJ1ZSB9KSBkeW5hbWljQ29udGFpbmVyOiBFbGVtZW50UmVmO1xuXG4gIGR5bmFtaWNDb21wb25lbnRSZWZzOiBDb21wb25lbnRSZWY8YW55PltdID0gW107XG4gIC8vIGR5bmFtaWNDb21wb25lbnRSZWZzOiBDb21wb25lbnRSZWY8YW55PltdID0gW107XG5cbiAgQ29tcFJlZnM6IENvbXBvbmVudFJlZjxhbnk+O1xuXG4gIGNvbXBvbmVudENsYXNzTWFwID0ge1xuICAgIEdhbW1hQWR2YW5jZUNoYXJ0Q29tcG9uZW50LFxuICAgIEdhbW1hVG9kYXlQcmV2aW91c0NvbXBvbmVudCxcbiAgICBBcHBBZHZhbmNlSGVhZGVyQ29tcG9uZW50LFxuICAgIEdhbW1hVGFibGVXaXRoUGVyY2VudGFnZUNvbXBvbmVudCxcbiAgICBHYW1tU2luZ2xlTnVtYmVyQ2FyZENvbXBvbmVudCxcbiAgICBHYW1tYUFkdmFuY2VPcGVyYXRvclRhYmxlQ29tcG9uZW50LFxuICAgIEFkdmFuY2VXaWRnZXRIZWFkZXJGaWx0ZXJDb21wb25lbnRcbiAgfTtcbiAgZGF0YVNvdXJjZU1hdGFEYXRhOiBhbnkgPSBbXTtcbiAgcXVlcnlUeXBlID0gXCJtb25nb1wiO1xuICBkYXRhU2V0TW9kYWw6IGFueSA9IFtdO1xuICBjb21wb25lbnRDb25maWdEYXRhU291cmNlOiBhbnkgPSBbXTtcbiAgc2VsZXNjZWREYXRhU291cmNlOiBhbnk7XG4gIGRhdGFTb3VyY2VNb2RhbDogYW55ID0ge307XG4gIGlzRGFzaEJvYXJkQ29udGVudDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIHNlbGVjdGVkVmlld0Zvcm1Db21wb25lbnQ6IGFueSA9IHt9O1xuICBhZGRlZHdpZEdldENvbmZpZyA9IHtcbiAgICBcImRpc3BsYXlcIjogdHJ1ZSxcbiAgICBcIndpZGdldFRpdGxlXCI6IFwiXCIsXG4gICAgXCJ3aWR0aFwiOiBcIlwiLFxuICAgIFwiaGVpZ2h0XCI6IFwiXCIsXG4gICAgXCJpc1dpZGdldEZpbHRlclwiOiBmYWxzZVxuICB9XG5cbiAgZGFzaEJvYXJkV2lkZ2V0Q29uZmlnOiBhbnkgPSBbXG4gIF07XG4gIGlzV2lkZ2V0Q3JlYXRpb25Db250ZW50OiBib29sZWFuO1xuICBzZWxlY3RlZFdpZHRoOiBhbnk7XG4gIHNlbGVjdGVkSGVpZ2h0OiBhbnk7XG4gIG5ld1dpZGdldEluZGV4OiBhbnk7XG4gIHNlbGVjdGVkSW5kZXhPYmpGb3JDaGFydDogYW55ID0ge307XG4gIHNlbGVjdGVkQ29udGFpbmVyT2JqZWN0Rm9yQ2hhcnQ6IGFueSA9IHt9O1xuICBkYXRhU2V0dGFibGVEYXRhU291cmNlOiBhbnk7XG4gIHVuaXF1ZURhdGFTZXRPYmplY3QgPSB7fTtcblxuICBpc0Rhc2hCb2FyZENvbnRlbnRUeXBlVmlldzogYm9vbGVhbjtcbiAgcGFnZUlkOiBhbnk7XG4gIGlzbGF5b3V0Q3JlYXRlOiBib29sZWFuID0gZmFsc2U7XG4gIHdpZGdldE5hbWU6IGFueTtcbiAgd2lkZ2V0VGl0bGU6IGFueTtcbiAgYWxsV2lkZ2V0SW5uZXJDb250ZW50OiBhbnk7XG4gIGlzRGVmYXVsdFZpZXc6IEJvb2xlYW4gPSB0cnVlO1xuICBpc0VkaXRNYWluTGF5b3V0OiBCb29sZWFuO1xuICBmaWx0ZXJEYXRhU291cmNlOiBhbnk7XG4gIHNlbGVjdGVkRmlsdGVySWQ6IGFueTtcblxuICB2aWV3VG9TZWFyY2g6IHN0cmluZyA9ICcnO1xuICBmaWx0ZXJlZENvbXBvbmVudENvbmZpZzogYW55W10gPSBbXTtcbiAgaXNFZGl0T3B0aW9uQ2xpY2s6IGJvb2xlYW47XG4gIGVkaXRWaWV3ZGF0YVNvdXJjZU1vZGFsOiBhbnkgPSB7fTtcblxuICBlZGl0SXRlbUZvclVwZGF0ZTogYW55ID0ge307XG4gIHBhZ2VUaXRsZTogYW55O1xuICBwYWdlVXJsOiBhbnk7XG4gIGFsbFdpZGdldEJ5RGF0YXNldDogYW55ID0gW107XG5cbiAgc2VsZWN0ZWRGaWx0ZXJzRGVmYXVsdDogYW55O1xuXG4gIG5vZGVQcm9wZXJ0aWNlRmlsdGVyczogYW55ID0gW107XG5cbiAgaXNDcmVhdGVEYXRhc2V0OiBib29sZWFuO1xuICBzZWxlY3RlZERhdGFzZXRJZDogYW55O1xuICBpc0NyZWF0ZURhdGFzZXRXaXRoRGF0YXNldElkOiBib29sZWFuO1xuXG4gIGlzQ3JlYXRlTmV3VmlldzogYm9vbGVhbjtcbiAgaXNDcmVhdGVOZXdWaWV3V2l0aERlZmF1bHRWaWV3OiBib29sZWFuO1xuXG4gIGRlZmF1bHRBcHBseWVkRmlsdGVyOiBhbnk7XG4gIGlzV2lkZ2V0RmlsdGVyczogYm9vbGVhbjtcbiAgbm9kZXByb3BlcnRpY2VGaWx0ZXJEYXRhU291cmNlOiBhbnk7XG4gIHNlbGVjdGVkRmlsdGVyRGF0YXNvdXJjZTogYW55ID0ge307XG4gIEBWaWV3Q2hpbGQoRHhTY3JvbGxWaWV3Q29tcG9uZW50LCB7IHN0YXRpYzogZmFsc2UgfSkgc2Nyb2xsVmlldzogRHhTY3JvbGxWaWV3Q29tcG9uZW50O1xuXG4gIHNlbGVjdGVkVmlld0lkOiBhbnk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIGNvbW1vblNlcnZpY2U6IENvbW1vblNlcnZpY2UsXG4gICAgcHJpdmF0ZSBhY3RpdmF0ZWRSb3V0ZTogQWN0aXZhdGVkUm91dGUsXG4gICAgcHJpdmF0ZSB2aWV3Q29udGFpbmVyUmVmOiBWaWV3Q29udGFpbmVyUmVmLFxuICAgIHByaXZhdGUgY29tcG9uZW50RmFjdG9yeVJlc29sdmVyOiBDb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIsXG4gICAgcHJpdmF0ZSBzZXJ2aWNlOiBBcHBsaWNhdGlvbkNvbnRlbnRTZXJ2aWNlLFxuICAgIHByaXZhdGUgdG9hc3RyOiBUb2FzdHJTZXJ2aWNlLFxuICAgIHByaXZhdGUgcm91dGVyOiBSb3V0ZXIsXG4gICAgcHJpdmF0ZSBkYXRhc2V0U2VydmljZTogQXBwbGljYXRpb25EYXRzc2V0c0NhbGwsXG4gICkgeyB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5pc0Rhc2hCb2FyZENvbnRlbnRUeXBlVmlldyA9ICh0aGlzLmFjdGl2YXRlZFJvdXRlLnNuYXBzaG90LnF1ZXJ5UGFyYW1zWydjb250ZW50VHlwZSddID09ICd2aWV3JykgPyB0cnVlIDogZmFsc2U7XG4gICAgdGhpcy5wYWdlSWQgPSB0aGlzLmFjdGl2YXRlZFJvdXRlLnNuYXBzaG90LnF1ZXJ5UGFyYW1zWydwYWdlSWQnXTtcblxuICAgIHRoaXMuZ2V0RGF0YVNldCgpO1xuICAgIHRoaXMuZGVmYXVsdFN0YXJ0RGF0ZSA9IG1vbWVudCgpLnN1YnRyYWN0KCcxMCcsICdkYXlzJykuZm9ybWF0KCdZWVlZLU1NLUREJyk7XG4gICAgdGhpcy5kZWZhdWx0RW5kRGF0ZSA9IG1vbWVudCgpLnN1YnRyYWN0KCcxJywgJ2RheXMnKS5mb3JtYXQoJ1lZWVktTU0tREQnKTtcbiAgICB0aGlzLmdldEZpbHRlckl0ZW1zKClcbiAgICB0aGlzLmdldEFsbFZpZXdzSXRlbXMoKVxuXG4gICAgdGhpcy5nZXRBcHBQYWdlRGV0YWlsQ29uZmlnQnlQYWdlSWQoKVxuICB9XG5cbiAgZ2V0QWxsVmlld3NJdGVtcygpIHtcbiAgICB0aGlzLnNlcnZpY2UuZ2V0QXBwVmlld0NvbmZpZ3MoKS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKGRhdGE6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLmNvbXBvbmVudENvbmZpZ0RhdGFTb3VyY2UgPSBkYXRhO1xuICAgICAgICB0aGlzLmZpbHRlcmVkQ29tcG9uZW50Q29uZmlnID0gdGhpcy5jb21wb25lbnRDb25maWdEYXRhU291cmNlO1xuICAgICAgfSwgZXJyb3I6IChlcnI6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLnRvYXN0ci5lcnJvcignVW5leHBlY3RlZCBTZXJ2ZXIgRXhjZXB0aW9uLiBQbGVhc2UgY29udGFjdCBTeXN0ZW0gQWRtaW4uJywgJ1ZpZXcgQ29uZmlnJyk7XG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIGdldEZpbHRlckl0ZW1zKCkge1xuICAgIHRoaXMuc2VydmljZS5nZXRBcHBGaWx0ZXJDb25maWdzKCkuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChkYXRhOiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy5maWx0ZXJEYXRhU291cmNlID0gZGF0YTtcbiAgICAgIH0sIGVycm9yOiAoZXJyOiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy50b2FzdHIuZXJyb3IoJ1VuZXhwZWN0ZWQgU2VydmVyIEV4Y2VwdGlvbi4gUGxlYXNlIGNvbnRhY3QgU3lzdGVtIEFkbWluLicsICdFcnJvcicpO1xuXG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgZ2V0QXBwUGFnZURldGFpbENvbmZpZ0J5UGFnZUlkKCkge1xuICAgIHRoaXMuc2VydmljZS5nZXRBcHBQYWdlRGV0YWlsQ29uZmlnKHRoaXMucGFnZUlkKS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKGRhdGE6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLmRhc2hCb2FyZFdpZGdldENvbmZpZyA9IGRhdGE7XG4gICAgICAgIHRoaXMucGFnZVRpdGxlID0gZGF0YS5wYWdlTmFtZTtcbiAgICAgICAgdGhpcy5wYWdlVXJsID0gZGF0YS5wYWdlVXJsO1xuICAgICAgICBpZiAoZGF0YS53aWRnZXRzICYmIGRhdGEud2lkZ2V0cy5sZW5ndGggIT09IDApIHtcbiAgICAgICAgICB0aGlzLmdldENvbXBvbmVudENvbmZpZ1NldCgpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5sb2FkaW5nTW9kYWwgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGVycm9yOiAoZXJyOiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy50b2FzdHIuZXJyb3IoJ1VuZXhwZWN0ZWQgU2VydmVyIEV4Y2VwdGlvbi4gUGxlYXNlIGNvbnRhY3QgU3lzdGVtIEFkbWluLicsICdFcnJvcicpO1xuXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG5cbiAgZ2V0Q29tcG9uZW50Q29uZmlnU2V0KCkge1xuICAgIGxldCBkZWZhdWx0RmlsdGVycyA9IHsgb3BlcmF0aW9uRmlsdGVyOiB7IHN0YXJ0RGF0ZTogXCJcIiwgZW5kRGF0ZTogXCJcIiB9IH07XG4gICAgdGhpcy5kYXNoQm9hcmRXaWRnZXRDb25maWcud2lkZ2V0cy5mb3JFYWNoKHdpZGdldCA9PiB7XG4gICAgICBpZiAod2lkZ2V0LmZpbHRlcnMpIHtcbiAgICAgICAgd2lkZ2V0LmZpbHRlcnMuZmlsdGVySXRlbXMuZm9yRWFjaChlbGVtZW50ID0+IHtcbiAgICAgICAgICBpZiAoZWxlbWVudC5maWx0ZXJUeXBlID09PSAnZGF0ZScgfHwgZWxlbWVudC5maWx0ZXJUeXBlID09PSAnZGF0ZXRpbWUnKSB7XG4gICAgICAgICAgICBpZiAoZWxlbWVudC5kZWZhdWx0RmlsdGVyVHlwZSA9PT0gXCJkeW5hbWljXCIgJiYgZWxlbWVudC5tb21lbnRGdW5jdGlvbiAhPT0gXCJcIiAmJiBlbGVtZW50LmRlZmF1bHRGaWx0ZXJWYWx1ZSAhPT0gXCJcIiAmJiBlbGVtZW50Lm1vbWVudEZvcm1hdCAhPT0gXCJcIikge1xuICAgICAgICAgICAgICBsZXQgW2NvdW50LCB1bml0XSA9IGVsZW1lbnQuZGVmYXVsdEZpbHRlclZhbHVlLnNwbGl0KCcsJyk7XG4gICAgICAgICAgICAgIGlmIChlbGVtZW50LmFwaU5hbWUgPT09IFwiZW5kRGF0ZVwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQuZGlzcGxheSkge1xuICAgICAgICAgICAgICAgICAgZGVmYXVsdEZpbHRlcnMub3BlcmF0aW9uRmlsdGVyLmVuZERhdGUgPSBtb21lbnQoKVtlbGVtZW50Lm1vbWVudEZ1bmN0aW9uXShwYXJzZUludChjb3VudCksIHVuaXQpLmZvcm1hdChlbGVtZW50Lm1vbWVudEZvcm1hdCk7XG4gICAgICAgICAgICAgICAgICB0aGlzLmRlZmF1bHRFbmREYXRlID0gbW9tZW50KClbZWxlbWVudC5tb21lbnRGdW5jdGlvbl0ocGFyc2VJbnQoY291bnQpLCB1bml0KS5mb3JtYXQoZWxlbWVudC5tb21lbnRGb3JtYXQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAoZWxlbWVudC5hcGlOYW1lID09PSBcInN0YXJ0RGF0ZVwiKSB7XG4gICAgICAgICAgICAgICAgZGVmYXVsdEZpbHRlcnMub3BlcmF0aW9uRmlsdGVyLnN0YXJ0RGF0ZSA9IG1vbWVudCgpW2VsZW1lbnQubW9tZW50RnVuY3Rpb25dKHBhcnNlSW50KGNvdW50KSwgdW5pdCkuZm9ybWF0KGVsZW1lbnQubW9tZW50Rm9ybWF0KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICh0eXBlb2YgZWxlbWVudC5maWx0ZXJEYXRhU291cmNlVmFsdWUgPT09IFwic3RyaW5nXCIgJiYgZWxlbWVudC5maWx0ZXJEYXRhU291cmNlVmFsdWUgIT09IFwiXCIpIHx8XG4gICAgICAgICAgICAgIChBcnJheS5pc0FycmF5KGVsZW1lbnQuZmlsdGVyRGF0YVNvdXJjZVZhbHVlKSAmJiBlbGVtZW50LmZpbHRlckRhdGFTb3VyY2VWYWx1ZS5sZW5ndGggPiAwKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIGlmIChlbGVtZW50Lm9wZXJhdG9yTmFtZSAhPT0gXCJcIikge1xuICAgICAgICAgICAgICAgIGRlZmF1bHRGaWx0ZXJzLm9wZXJhdGlvbkZpbHRlcltlbGVtZW50Lm9wZXJhdG9yTmFtZV0gPSBBcnJheS5pc0FycmF5KGVsZW1lbnQuZmlsdGVyRGF0YVNvdXJjZVZhbHVlKVxuICAgICAgICAgICAgICAgICAgPyBlbGVtZW50LmZpbHRlckRhdGFTb3VyY2VWYWx1ZVxuICAgICAgICAgICAgICAgICAgOiBbZWxlbWVudC5maWx0ZXJEYXRhU291cmNlVmFsdWVdO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGRlZmF1bHRGaWx0ZXJzLm9wZXJhdGlvbkZpbHRlcltlbGVtZW50LmFwaU5hbWVdID0gZWxlbWVudC5maWx0ZXJEYXRhU291cmNlVmFsdWUuam9pbihcIixcIik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICB9KTtcbiAgICBsZXQgYXBpQ2FsbHMgPSBbXTtcbiAgICB0aGlzLmRlZmF1bHRBcHBseWVkRmlsdGVyID0gZGVmYXVsdEZpbHRlcnM7XG5cbiAgICBQcm9taXNlLmFsbChhcGlDYWxscykudGhlbigoKSA9PiB7XG4gICAgICAvLyB0aGlzLnVuaXF1ZURhdGFTZXRPYmplY3QgPSB0aGlzLmRhdGFzZXRTZXJ2aWNlLmdldFVuaXF1ZURhdGFTZXRPYmplY3QoKTtcbiAgICAgIHRoaXMuY3JlYXRlRGl2RWxlbWVudHModGhpcy51bmlxdWVEYXRhU2V0T2JqZWN0KTtcbiAgICAgIHRoaXMubG9hZGluZ01vZGFsID0gZmFsc2U7XG4gICAgfSk7XG4gIH1cblxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuXG4gIH1cblxuICBnZXREYXRhU2V0KCkge1xuICAgIHRoaXMuaXNMb2FkZXIgPSB0cnVlO1xuICAgIHRoaXMuc2VydmljZS5nZXRBcHBEYXRhc2V0Q29uZmlncygpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAoZGF0YTogYW55KSA9PiB7XG4gICAgICAgIHRoaXMuZGF0YVNldHRhYmxlRGF0YVNvdXJjZSA9IGRhdGE7XG4gICAgICAgIHRoaXMuaXNMb2FkZXIgPSBmYWxzZTtcbiAgICAgIH0sIGVycm9yOiAoZXJyOiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy50b2FzdHIuZXJyb3IoJ1VuZXhwZWN0ZWQgU2VydmVyIEV4Y2VwdGlvbi4gUGxlYXNlIGNvbnRhY3QgU3lzdGVtIEFkbWluLicsICdEYXRhc2V0IENyZWF0aW9uJylcblxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuXG5cblxuICBnZXRDb21wb25lbnRDb25maWcoZXZlbnQpIHtcbiAgICBjb25zdCBmb3VuZE9iamVjdCA9IHRoaXMuY29tcG9uZW50Q29uZmlnRGF0YVNvdXJjZS5maW5kKHZpZXcgPT4gdmlldy52aWV3SWQgPT09IGV2ZW50LnZpZXdJZCk7XG4gICAgdGhpcy5nZXRFbWl0TmV3Q2hhcnRDb25maWcoZm91bmRPYmplY3QpO1xuICAgIHRoaXMubG9hZGluZ01vZGFsID0gdHJ1ZTtcbiAgfVxuXG4gIGFkZE5ld2NoYXJ0KCkge1xuICAgIHRoaXMuaXNHZW5lcmF0ZSA9IGZhbHNlO1xuICAgIHRoaXMuaXNDaGFydEJ1dHRvbkNsaWNrID0gdHJ1ZTtcbiAgICB0aGlzLmlzV2lkZ2V0Q3JlYXRpb25Db250ZW50ID0gZmFsc2U7XG4gICAgdGhpcy5pc0RlZmF1bHRWaWV3ID0gZmFsc2U7XG4gIH1cblxuXG4gIGFkZFdpZGdldCgpIHtcbiAgICB0aGlzLm5ld1dpZGdldEluZGV4ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuaXNXaWRnZXRDcmVhdGlvbkNvbnRlbnQgPSB0cnVlO1xuICAgIHRoaXMuaXNEZWZhdWx0VmlldyA9IGZhbHNlO1xuICAgIHRoaXMuaXNFZGl0TWFpbkxheW91dCA9IGZhbHNlO1xuICAgIHRoaXMuaXNDaGFydEJ1dHRvbkNsaWNrID0gZmFsc2U7XG4gICAgdGhpcy5pc1VwZGF0ZVdpZGdldCA9IGZhbHNlO1xuICAgIHRoaXMud2lkZ2V0TmFtZSA9ICcnO1xuICAgIHRoaXMud2lkZ2V0VGl0bGUgPSAnJztcbiAgICB0aGlzLmFkZGVkd2lkR2V0Q29uZmlnID0ge1xuICAgICAgXCJkaXNwbGF5XCI6IHRydWUsXG4gICAgICBcIndpZGdldFRpdGxlXCI6IFwiXCIsXG4gICAgICBcIndpZHRoXCI6IFwiXCIsXG4gICAgICBcImhlaWdodFwiOiBcIlwiLFxuICAgICAgXCJpc1dpZGdldEZpbHRlclwiOiBmYWxzZVxuICAgIH1cbiAgfVxuXG4gIGdldFdpdGgoZSkge1xuICAgIHRoaXMuc2VsZWN0ZWRXaWR0aCA9IGUudmFsdWU7XG4gIH1cblxuICBnZXRIZWlnaHQoZSkge1xuICAgIHRoaXMuc2VsZWN0ZWRIZWlnaHQgPSBlLnZhbHVlO1xuICB9XG5cbiAgYWRkTGF5b3V0VE92aWV3KCkge1xuICAgIGxldCBpbm5lcl9ub2RlID0ge1xuICAgICAgaWQ6IHRoaXMuY29tbW9uU2VydmljZS5wcmltZXJ5UmVuZG9tZUlkKDUpLFxuICAgICAgbm9kZVRpdGxlOiBcIlwiLFxuICAgICAgZmlsdGVySWQ6IHRoaXMuc2VsZWN0ZWRGaWx0ZXJJZCxcbiAgICAgIG5vZGVQcm9wZXJ0aWVzOiB0aGlzLmFkZGVkd2lkR2V0Q29uZmlnLFxuICAgICAgY29tcENvbmZpZzoge1xuICAgICAgICBkeW5hbWljQ29tcG9uZW50UmVmczogW10sXG4gICAgICAgIHZpZXdDb25maWc6IFtdXG4gICAgICB9LFxuICAgIH1cbiAgICBpZiAodGhpcy5kYXNoQm9hcmRXaWRnZXRDb25maWcud2lkZ2V0c1t0aGlzLm5ld1dpZGdldEluZGV4XS53aWRnZXROb2RlKSB7XG4gICAgICB0aGlzLmRhc2hCb2FyZFdpZGdldENvbmZpZy53aWRnZXRzW3RoaXMubmV3V2lkZ2V0SW5kZXhdLndpZGdldE5vZGUucHVzaChpbm5lcl9ub2RlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5kYXNoQm9hcmRXaWRnZXRDb25maWcud2lkZ2V0c1t0aGlzLm5ld1dpZGdldEluZGV4XS53aWRnZXROb2RlID0gW107XG4gICAgICB0aGlzLmRhc2hCb2FyZFdpZGdldENvbmZpZy53aWRnZXRzW3RoaXMubmV3V2lkZ2V0SW5kZXhdLndpZGdldE5vZGUucHVzaChpbm5lcl9ub2RlKTtcbiAgICB9XG5cbiAgICB0aGlzLmxvYWRpbmdNb2RhbCA9IHRydWU7XG4gICAgdGhpcy51cGRhdGVXaWRnZXQoKTtcbiAgfVxuXG5cblxuICByZWZvcm1hdFdpZGdldENvbmZpZyhkYXNoQm9hcmRXaWRnZXRDb25maWcsIGluZGV4ID0gbnVsbCkge1xuICAgIGNvbnN0IHByb2Nlc3NXaWRnZXQgPSAod2lkZ2V0KSA9PiB7XG4gICAgICB3aWRnZXQuY29tcENvbmZpZy52aWV3Q29uZmlnID0gd2lkZ2V0LmNvbXBDb25maWcudmlld0NvbmZpZy5tYXAoY29uZmlnID0+IGNvbmZpZy52aWV3SWQpO1xuICAgICAgd2lkZ2V0LmNvbXBDb25maWcuZHluYW1pY0NvbXBvbmVudFJlZnMgPSBbXTtcblxuICAgICAgaWYgKHdpZGdldC53aWRnZXROb2RlICYmIHdpZGdldC53aWRnZXROb2RlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgd2lkZ2V0LndpZGdldE5vZGUuZm9yRWFjaChub2RlID0+IHtcbiAgICAgICAgICBub2RlLmNvbXBDb25maWcudmlld0NvbmZpZyA9IG5vZGUuY29tcENvbmZpZy52aWV3Q29uZmlnLm1hcChjb25maWcgPT4gY29uZmlnLnZpZXdJZCk7XG4gICAgICAgICAgbm9kZS5jb21wQ29uZmlnLmR5bmFtaWNDb21wb25lbnRSZWZzID0gW107XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAoaW5kZXggIT09IG51bGwgJiYgaW5kZXggPj0gMCAmJiBpbmRleCA8IGRhc2hCb2FyZFdpZGdldENvbmZpZy53aWRnZXRzLmxlbmd0aCkge1xuICAgICAgcHJvY2Vzc1dpZGdldChkYXNoQm9hcmRXaWRnZXRDb25maWcud2lkZ2V0c1tpbmRleF0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBkYXNoQm9hcmRXaWRnZXRDb25maWcud2lkZ2V0cy5mb3JFYWNoKHdpZGdldCA9PiBwcm9jZXNzV2lkZ2V0KHdpZGdldCkpO1xuICAgIH1cblxuICAgIHJldHVybiBkYXNoQm9hcmRXaWRnZXRDb25maWcud2lkZ2V0c1tpbmRleF07XG4gIH1cblxuICB1cGRhdGVXaWRnZXQoKSB7XG4gICAgbGV0IG1vZGlmaWVkQ29uZmlnID0gdGhpcy5yZWZvcm1hdFdpZGdldENvbmZpZyh0aGlzLmRhc2hCb2FyZFdpZGdldENvbmZpZywgdGhpcy5uZXdXaWRnZXRJbmRleCk7XG4gICAgbW9kaWZpZWRDb25maWdbJ2ZpbHRlcklkJ10gPSAobW9kaWZpZWRDb25maWcuZmlsdGVycy5maWx0ZXJJZCkgPyBtb2RpZmllZENvbmZpZy5maWx0ZXJzLmZpbHRlcklkIDogbnVsbDtcbiAgICBkZWxldGUgbW9kaWZpZWRDb25maWdbJ2ZpbHRlcnMnXTtcbiAgICB0aGlzLnNlcnZpY2UuZWRpdEFwcFdpZGdldENvbmZpZyhtb2RpZmllZENvbmZpZykuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChkYXRhOiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy5nZXRBcHBQYWdlRGV0YWlsQ29uZmlnQnlQYWdlSWQoKVxuICAgICAgICB0aGlzLmJhY2tUb01haW5WaWV3KCk7XG4gICAgICB9LCBlcnJvcjogKGVycjogYW55KSA9PiB7XG4gICAgICAgIHRoaXMubG9hZGluZ01vZGFsID0gZmFsc2U7XG4gICAgICAgIHRoaXMudG9hc3RyLmVycm9yKCdVbmV4cGVjdGVkIFNlcnZlciBFeGNlcHRpb24uIFBsZWFzZSBjb250YWN0IFN5c3RlbSBBZG1pbi4nLCAnV2lkZ2V0IENyZWF0aW9uJylcbiAgICAgIH1cbiAgICB9KVxuICAgIHRoaXMubmV3V2lkZ2V0SW5kZXggPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5pc1dpZGdldENyZWF0aW9uQ29udGVudCA9IGZhbHNlO1xuICAgIHRoaXMuaXNEZWZhdWx0VmlldyA9IHRydWU7XG4gIH1cblxuICB1cGRhdGVMYXlvdXRXaWRnZXRUT3ZpZXcoKSB7XG4gICAgdGhpcy5sb2FkaW5nTW9kYWwgPSB0cnVlO1xuICAgIHRoaXMudXBkYXRlV2lkZ2V0KCk7XG4gIH1cblxuICBhZGRXaWRnZXRUT3ZpZXcoKSB7XG4gICAgbGV0IG9iaiA9IHtcbiAgICAgIHdpZGdldElkOiB0aGlzLmNvbW1vblNlcnZpY2UucHJpbWVyeVJlbmRvbWVJZCg1KSxcbiAgICAgIHdpZGdldE5hbWU6IHRoaXMud2lkZ2V0TmFtZSxcbiAgICAgIHdpZGdldFRpdGxlOiB0aGlzLndpZGdldFRpdGxlLFxuICAgICAgd2lkZ2V0UHJvcGVydGllczogdGhpcy5hZGRlZHdpZEdldENvbmZpZyxcbiAgICAgIHBhZ2VJZDogdGhpcy5wYWdlSWQsXG4gICAgICBmaWx0ZXJJZDogdGhpcy5zZWxlY3RlZEZpbHRlcklkLFxuICAgICAgd2lkZ2V0Tm9kZTogW1xuICAgICAgICB7XG4gICAgICAgICAgaWQ6IHRoaXMuY29tbW9uU2VydmljZS5wcmltZXJ5UmVuZG9tZUlkKDUpLFxuICAgICAgICAgIG5vZGVUaXRsZTogXCJcIixcbiAgICAgICAgICBmaWx0ZXJJZDogXCJcIixcbiAgICAgICAgICBub2RlUHJvcGVydGllczoge1xuICAgICAgICAgICAgXCJkaXNwbGF5XCI6IHRydWUsXG4gICAgICAgICAgICBcIndpZGdldFRpdGxlXCI6IFwiXCIsXG4gICAgICAgICAgICBcIndpZHRoXCI6IFwidy0xLzJcIixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IFwiXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBjb21wQ29uZmlnOiB7XG4gICAgICAgICAgICBkeW5hbWljQ29tcG9uZW50UmVmczogW10sXG4gICAgICAgICAgICB2aWV3Q29uZmlnOiBbXVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgXSxcbiAgICAgIGNvbXBDb25maWc6IHtcbiAgICAgICAgZHluYW1pY0NvbXBvbmVudFJlZnM6IFtdLFxuICAgICAgICB2aWV3Q29uZmlnOiBbXVxuICAgICAgfSxcbiAgICB9XG4gICAgdGhpcy5sb2FkaW5nTW9kYWwgPSB0cnVlO1xuICAgIHRoaXMuc2VydmljZS5jcmVhdGVBcHBXaWRnZXRDb25maWcob2JqKS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKGRhdGE6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLmxvYWRpbmdNb2RhbCA9IGZhbHNlO1xuICAgICAgICAvLyB0aGlzLmNyZWF0ZURpdkVsZW1lbnRzKHRoaXMudW5pcXVlRGF0YVNldE9iamVjdClcbiAgICAgICAgdGhpcy5nZXRBcHBQYWdlRGV0YWlsQ29uZmlnQnlQYWdlSWQoKVxuXG4gICAgICB9LCBlcnJvcjogKGVycjogYW55KSA9PiB7XG4gICAgICAgIHRoaXMubG9hZGluZ01vZGFsID0gZmFsc2U7XG5cbiAgICAgICAgdGhpcy50b2FzdHIuZXJyb3IoJ1VuZXhwZWN0ZWQgU2VydmVyIEV4Y2VwdGlvbi4gUGxlYXNlIGNvbnRhY3QgU3lzdGVtIEFkbWluLicsICdXaWRnZXQgQ3JlYXRpb24nKVxuICAgICAgfVxuICAgIH0pXG4gICAgdGhpcy5kYXNoQm9hcmRXaWRnZXRDb25maWcud2lkZ2V0cy5wdXNoKG9iailcbiAgICAvLyB0aGlzLmluc2VydER5bmFtaWNDb21wb25lbnRzKCk7XG5cblxuICAgIHRoaXMuZHluYW1pY0NvbnRhaW5lci5uYXRpdmVFbGVtZW50LmlubmVySFRNTCA9ICcnO1xuXG4gICAgdGhpcy5pc1dpZGdldENyZWF0aW9uQ29udGVudCA9IGZhbHNlO1xuICAgIHRoaXMuaXNEZWZhdWx0VmlldyA9IHRydWU7XG4gIH1cblxuICBpbnNlcnROZXdXaWdldChpbmRleCkge1xuICAgIHRoaXMuYWRkZWR3aWRHZXRDb25maWcgPSB7XG4gICAgICBcImRpc3BsYXlcIjogdHJ1ZSxcbiAgICAgIFwid2lkZ2V0VGl0bGVcIjogXCJcIixcbiAgICAgIFwid2lkdGhcIjogXCJcIixcbiAgICAgIFwiaGVpZ2h0XCI6IFwiXCIsXG4gICAgICBcImlzV2lkZ2V0RmlsdGVyXCI6IGZhbHNlXG4gICAgfVxuICAgIHRoaXMuaXNVcGRhdGVXaWRnZXQgPSBmYWxzZTtcbiAgICB0aGlzLmlzV2lkZ2V0Q3JlYXRpb25Db250ZW50ID0gdHJ1ZTtcbiAgICB0aGlzLmlzRGVmYXVsdFZpZXcgPSBmYWxzZTtcbiAgICB0aGlzLmlzQ2hhcnRCdXR0b25DbGljayA9IGZhbHNlO1xuICAgIHRoaXMuaXNsYXlvdXRDcmVhdGUgPSB0cnVlO1xuICAgIHRoaXMubmV3V2lkZ2V0SW5kZXggPSBpbmRleDtcbiAgfVxuICBpbnNlcnRDaGFydFdpZ2V0KGluZGV4T2JqLCBjb250YWluZXJFbGVtZW50KSB7XG5cbiAgICB0aGlzLmlzR2VuZXJhdGUgPSBmYWxzZTtcbiAgICB0aGlzLmlzQ2hhcnRCdXR0b25DbGljayA9IHRydWU7XG4gICAgdGhpcy5pc1dpZGdldENyZWF0aW9uQ29udGVudCA9IGZhbHNlO1xuICAgIHRoaXMuaXNEZWZhdWx0VmlldyA9IGZhbHNlO1xuICAgIHRoaXMuc2VsZWN0ZWRDb250YWluZXJPYmplY3RGb3JDaGFydCA9IGNvbnRhaW5lckVsZW1lbnQ7XG4gICAgdGhpcy5zZWxlY3RlZEluZGV4T2JqRm9yQ2hhcnQgPSBpbmRleE9iajtcbiAgICB0aGlzLnNlbGVjdGVkVmlld0Zvcm1Db21wb25lbnQgPSB7fTtcbiAgfVxuXG4gIGFzeW5jIGdldEVtaXROZXdDaGFydENvbmZpZyhkYXRhKSB7XG4gICAgLy8gbGV0IGRhdGFzZXRfY29uZmlnID0gdGhpcy5kYXRhU2V0TW9kYWwuZmluZChkYXRhc2V0ID0+IGRhdGFzZXQuZGF0YXNldElkID09IGRhdGEuZGF0YXNldElkKTtcbiAgICAvLyBhd2FpdCB0aGlzLmRhdGFzZXRTZXJ2aWNlLmdldERhdGFGcm9tRGF0YVNldChkYXRhc2V0X2NvbmZpZywgZGF0YXNldF9jb25maWcuZGF0YXNldElkLCB0aGlzLnNlbGVjdGVkRmlsdGVyc0RlZmF1bHQpXG4gICAgLy8gZGF0YS5rcGlDb25maWdbJ2RhdGFTb3VyY2UnXSA9IHRoaXMudW5pcXVlRGF0YVNldE9iamVjdFtkYXRhc2V0X2NvbmZpZy5kYXRhc2V0SWRdO1xuICAgIHRoaXMuc2VsZWN0ZWRJbmRleE9iakZvckNoYXJ0LmNvbXBDb25maWcudmlld0NvbmZpZy5wdXNoKGRhdGEpXG4gICAgdGhpcy5sb2FkRHluYW1pY0NvbXBvbmVudChkYXRhLCB0aGlzLnNlbGVjdGVkSW5kZXhPYmpGb3JDaGFydCwgdGhpcy5zZWxlY3RlZENvbnRhaW5lck9iamVjdEZvckNoYXJ0KTtcbiAgICBjb25zb2xlLmxvZyh0aGlzLmRhc2hCb2FyZFdpZGdldENvbmZpZylcbiAgICB0aGlzLnVwZGF0ZVdpZGdldCgpO1xuICAgIHRoaXMubG9hZGluZ01vZGFsID0gZmFsc2U7XG4gICAgdGhpcy5pc0NoYXJ0QnV0dG9uQ2xpY2sgPSBmYWxzZTtcblxuICAgIC8vIH1cblxuICB9XG5cbiAgdXBkYXRlVG9WaWV3KCkge1xuICAgIHRoaXMubG9hZGluZ01vZGFsID0gdHJ1ZTtcbiAgICB0aGlzLnVwZGF0ZVdpZGdldCgpO1xuICB9XG5cbiAgZGVsZXRlV2lkZ2V0KGl0ZW0sIGluZGV4KSB7XG4gICAgdGhpcy5kYXNoQm9hcmRXaWRnZXRDb25maWcud2lkZ2V0cy5zcGxpY2UoaW5kZXgsIDEpXG4gICAgdGhpcy5uZXdXaWRnZXRJbmRleCA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGRlbGV0ZUluc2VydFdpZGdldChpdGVtLCBjaGlsZEluZGV4LCBwYXJlbnRJbmRleCkge1xuICAgIHRoaXMuZGFzaEJvYXJkV2lkZ2V0Q29uZmlnLndpZGdldHNbcGFyZW50SW5kZXhdLndpZGdldE5vZGUuc3BsaWNlKGNoaWxkSW5kZXgsIDEpXG4gICAgdGhpcy5uZXdXaWRnZXRJbmRleCA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGdldFdpZGdldFRpdGxlRGl2KGl0ZW0sIGRpdikge1xuICAgIGNvbnN0IHdpZGdldERpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHdpZGdldERpdi5jbGFzc0xpc3QuYWRkKCdmbGV4JywgJ2l0ZW1zLWNlbnRlcicsICdqdXN0aWZ5LWJldHdlZW4nLCAnZm9udC1ib2xkJywgJ3RleHQtbWQnLCAndGV4dC1ncmF5LTkwMCcsICdkYXJrOnRleHQtd2hpdGUnLCAnYm9yZGVyLWInLCAncC0zJywgJ2JnLWdyYXktODAwJywgJ214LTInLCAncm91bmRlZC10LWxnJyk7XG4gICAgY29uc3QgdGl0bGVEaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICB0aXRsZURpdi5pbm5lclRleHQgPSAoaXRlbS5ub2RlUHJvcGVydGllcykgPyBpdGVtLm5vZGVQcm9wZXJ0aWVzLndpZGdldFRpdGxlIDogXCJcIjtcbiAgICB3aWRnZXREaXYuYXBwZW5kKHRpdGxlRGl2KVxuXG4gICAgLy8gQWRkIEZvbnRBd2Vzb21lIGVkaXQgaWNvblxuICAgIGNvbnN0IGVkaXRJY29uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaScpO1xuICAgIGVkaXRJY29uLmNsYXNzTGlzdC5hZGQoJ2ZhJywgJ2ZhLXBlbmNpbCcsICdtbC0yJywgJ2N1cnNvci1wb2ludGVyJywgJ3RleHQtYmx1ZS00MDAnLCAnaG92ZXI6dGV4dC1ibHVlLTcwMCcpO1xuICAgIHdpZGdldERpdi5hcHBlbmQoZWRpdEljb24pO1xuXG4gICAgaWYgKGl0ZW0ubm9kZVByb3BlcnRpZXMuaXNXaWRnZXRGaWx0ZXIpIHtcbiAgICAgIGNvbnN0IHNlYXJjaENvbnRhaW5lckRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgc2VhcmNoQ29udGFpbmVyRGl2LmNsYXNzTGlzdC5hZGQoJ2ZsZXgnLCAnaXRlbXMtY2VudGVyJywgJ3NwYWNlLXgtMicpO1xuICAgICAgY29uc3Qgc2VhcmNoQnV0dG9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYnV0dG9uJyk7XG4gICAgICBzZWFyY2hCdXR0b24uaW5uZXJUZXh0ID0gJ0ZpbHRlcic7XG4gICAgICBzZWFyY2hCdXR0b24uY2xhc3NMaXN0LmFkZCgncHgtMycsICdweS0xLjUnLCAnYmctYmx1ZS02MDAnLCAnbXItMicsICd0ZXh0LXdoaXRlJywgJ3JvdW5kZWQnLCAnaG92ZXI6YmctYmx1ZS03MDAnKTtcbiAgICAgIHRoaXMubm9kZXByb3BlcnRpY2VGaWx0ZXJEYXRhU291cmNlID0gW107XG5cbiAgICAgIHNlYXJjaEJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgdGhpcy5pc1dpZGdldEZpbHRlcnMgPSB0cnVlO1xuICAgICAgICBsZXQgZmlsdGVQcm9wZXJ0aWNlID0gW107XG4gICAgICAgIGl0ZW0uY29tcENvbmZpZy52aWV3Q29uZmlnLmZvckVhY2goZWxlbWVudCA9PiB7XG4gICAgICAgICAgbGV0IGtleV9uYW1lID0gdGhpcy51bmlxdWVEYXRhU2V0T2JqZWN0W2VsZW1lbnQuZGF0YXNldElkXVswXTtcbiAgICAgICAgICBPYmplY3Qua2V5cyhrZXlfbmFtZSkuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICAgICAgaWYgKCFmaWx0ZVByb3BlcnRpY2UuaW5jbHVkZXMoa2V5KSkge1xuICAgICAgICAgICAgICBmaWx0ZVByb3BlcnRpY2UucHVzaChrZXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBmaWx0ZVByb3BlcnRpY2UuZm9yRWFjaChlbGVtZW50ID0+IHtcbiAgICAgICAgICBsZXQgb2JqID0ge1xuICAgICAgICAgICAgY29sdW1uTmFtZTogZWxlbWVudCxcbiAgICAgICAgICAgIGRhdGFUeXBlOiBcImZsb2F0XCIsXG4gICAgICAgICAgICBvcGVyYXRvcjogXCJcIixcbiAgICAgICAgICAgIHZhbHVlOiBcIlwiLFxuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLm5vZGVwcm9wZXJ0aWNlRmlsdGVyRGF0YVNvdXJjZS5wdXNoKG9iailcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIHNlYXJjaENvbnRhaW5lckRpdi5hcHBlbmRDaGlsZChzZWFyY2hCdXR0b24pXG4gICAgICB3aWRnZXREaXYuYXBwZW5kQ2hpbGQodGl0bGVEaXYpO1xuICAgICAgd2lkZ2V0RGl2LmFwcGVuZENoaWxkKHNlYXJjaENvbnRhaW5lckRpdik7XG4gICAgfVxuXG4gICAgaWYgKGl0ZW0uZmlsdGVySWQpIHtcbiAgICAgIHRoaXMubm9kZXByb3BlcnRpY2VGaWx0ZXJEYXRhU291cmNlID0ge307XG4gICAgICB0aGlzLm5vZGVwcm9wZXJ0aWNlRmlsdGVyRGF0YVNvdXJjZVsndmlld0NvbmZpZyddID0gaXRlbTtcbiAgICAgIHRoaXMubm9kZXByb3BlcnRpY2VGaWx0ZXJEYXRhU291cmNlWydoYXZpbmdDb25maWcnXSA9IFtdO1xuXG4gICAgICB0aGlzLnNlcnZpY2UuZ2V0QXBwRmlsdGVyQ29uZmlnKGl0ZW0uZmlsdGVySWQpLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChkYXRhOiBhbnkpID0+IHtcbiAgICAgICAgICBjb25zdCBmaWx0ZXJEaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICB0aGlzLmxvYWRXaWRnZXRGaWx0ZXJDb21wb25lbnQoaXRlbSwgd2lkZ2V0RGl2LCBkYXRhLmZpbHRlckl0ZW1zKTtcbiAgICAgICAgfSwgZXJyb3I6IChlcnI6IGFueSkgPT4ge1xuXG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoaXRlbS5ub2RlUHJvcGVydGllcy5ub2RlZmlsdGVycyAmJiBpdGVtLm5vZGVQcm9wZXJ0aWVzLm5vZGVmaWx0ZXJzLmxlbmd0aCAhPT0gMCkge1xuICAgICAgY29uc3Qgc2VhcmNoQ29udGFpbmVyRGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICBzZWFyY2hDb250YWluZXJEaXYuY2xhc3NMaXN0LmFkZCgnZmxleCcsICdpdGVtcy1jZW50ZXInLCAnc3BhY2UteC0yJyk7XG4gICAgICBpdGVtLm5vZGVQcm9wZXJ0aWVzLm5vZGVmaWx0ZXJzLmZvckVhY2goZmlsdGVyID0+IHtcbiAgICAgICAgY29uc3QgZmlsdGVyRGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIGZpbHRlckRpdi5jbGFzc0xpc3QuYWRkKCdmbGV4JywgJ2l0ZW1zLWNlbnRlcicpO1xuICAgICAgICBpZiAoZmlsdGVyLmlucHV0X3R5cGUgPT09ICd0ZXh0Jykge1xuICAgICAgICAgIGNvbnN0IHRleHRCb3ggPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbnB1dCcpO1xuICAgICAgICAgIHRleHRCb3gudHlwZSA9ICd0ZXh0JztcbiAgICAgICAgICB0ZXh0Qm94LnBsYWNlaG9sZGVyID0gYEVudGVyICR7ZmlsdGVyLmxvY2FsX2NvbHVtbn1gO1xuICAgICAgICAgIHRleHRCb3guY2xhc3NMaXN0LmFkZCgncHgtMicsICdweS0xLjUnLCAncm91bmRlZCcsICdib3JkZXInLCAnbXItMScsICdib3JkZXItZ3JheS01MDAnLCAndGV4dC1ncmF5LTkwMCcsICdkYXJrOmJnLWdyYXktNzAwJywgJ2Rhcms6dGV4dC13aGl0ZScpO1xuICAgICAgICAgIGNvbnN0IHNlYXJjaEJ1dHRvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2J1dHRvbicpO1xuICAgICAgICAgIHNlYXJjaEJ1dHRvbi5pbm5lclRleHQgPSAnU2VhcmNoJztcbiAgICAgICAgICBzZWFyY2hCdXR0b24uY2xhc3NMaXN0LmFkZCgncHgtMycsICdweS0xLjUnLCAnYmctYmx1ZS02MDAnLCAnbXItMicsICd0ZXh0LXdoaXRlJywgJ3JvdW5kZWQnLCAnaG92ZXI6YmctYmx1ZS03MDAnKTtcbiAgICAgICAgICBjb25zdCBzZXBhcmVyb3RCdXR0b24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICBzZXBhcmVyb3RCdXR0b24uaW5uZXJIVE1MID0gJ3wnO1xuICAgICAgICAgIHNlYXJjaEJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHNlYXJjaFRlcm0gPSB0ZXh0Qm94LnZhbHVlO1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ1RleHQgc2VhcmNoIGJ1dHRvbiBjbGlja2VkIHdpdGg6Jywgc2VhcmNoVGVybSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgZmlsdGVyRGl2LmFwcGVuZENoaWxkKHRleHRCb3gpO1xuICAgICAgICAgIGZpbHRlckRpdi5hcHBlbmRDaGlsZChzZWFyY2hCdXR0b24pO1xuICAgICAgICAgIGZpbHRlckRpdi5hcHBlbmRDaGlsZChzZXBhcmVyb3RCdXR0b24pO1xuICAgICAgICB9XG5cbiAgICAgICAgc2VhcmNoQ29udGFpbmVyRGl2LmFwcGVuZENoaWxkKGZpbHRlckRpdik7XG4gICAgICB9KTtcbiAgICAgIHdpZGdldERpdi5hcHBlbmRDaGlsZChzZWFyY2hDb250YWluZXJEaXYpO1xuICAgIH1cblxuICAgIGVkaXRJY29uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuXG4gICAgICB0aGlzLm5ld1dpZGdldEluZGV4ID0gdGhpcy5kYXNoQm9hcmRXaWRnZXRDb25maWcud2lkZ2V0cy5maW5kSW5kZXgob2JqZWN0ID0+IG9iamVjdC53aWRnZXRJZCA9PT0gZGl2LndpZGdldElkKTtcbiAgICAgIHRoaXMuaXNVcGRhdGVXaWRnZXQgPSB0cnVlO1xuICAgICAgdGhpcy5pc2xheW91dENyZWF0ZSA9IHRydWU7XG4gICAgICB0aGlzLmlzV2lkZ2V0Q3JlYXRpb25Db250ZW50ID0gdHJ1ZTtcbiAgICAgIHRoaXMuaXNEZWZhdWx0VmlldyA9IGZhbHNlO1xuICAgICAgdGhpcy5pc0NoYXJ0QnV0dG9uQ2xpY2sgPSBmYWxzZTtcbiAgICAgIHRoaXMubm9kZVByb3BlcnRpY2VGaWx0ZXJzID0gKGl0ZW0ubm9kZVByb3BlcnRpZXMubm9kZWZpbHRlcnMgJiYgaXRlbS5ub2RlUHJvcGVydGllcy5ub2RlZmlsdGVycy5sZW5ndGggIT09IDApID8gaXRlbS5ub2RlUHJvcGVydGllcy5ub2RlZmlsdGVycyA6IFtdO1xuICAgICAgaXRlbS5ub2RlUHJvcGVydGllc1snbm9kZWZpbHRlcnMnXSA9IHRoaXMubm9kZVByb3BlcnRpY2VGaWx0ZXJzO1xuICAgICAgdGhpcy5hZGRlZHdpZEdldENvbmZpZyA9IGl0ZW0ubm9kZVByb3BlcnRpZXM7XG4gICAgICB0aGlzLmFsbFdpZGdldElubmVyQ29udGVudCA9IGl0ZW0uY29tcENvbmZpZy52aWV3Q29uZmlnO1xuICAgICAgdGhpcy5zZWxlY3RlZEZpbHRlcklkID0gKGl0ZW0uZmlsdGVySWQpID8gaXRlbS5maWx0ZXJJZCA6IFwiXCI7XG4gICAgICB0aGlzLmVkaXRWaWV3ZGF0YVNvdXJjZU1vZGFsID0ge307XG4gICAgICB0aGlzLnNlbGVjdGVkRmlsdGVyRGF0YXNvdXJjZSA9IGl0ZW07XG4gICAgfSk7XG4gICAgcmV0dXJuIHdpZGdldERpdjtcbiAgfVxuXG5cbiAgZ2V0RmlsdGVyVmFsdWVCeUlkKGV2ZW50KSB7XG4gICAgaWYgKGV2ZW50LmV2ZW50KSB7XG4gICAgICB0aGlzLnNlcnZpY2UuZ2V0QXBwRmlsdGVyQ29uZmlnKGV2ZW50LnZhbHVlKS5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAoZGF0YTogYW55KSA9PiB7XG4gICAgICAgICAgaWYgKE9iamVjdC5rZXlzKHRoaXMuc2VsZWN0ZWRGaWx0ZXJEYXRhc291cmNlKS5sZW5ndGggIT09IDApIHtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRGaWx0ZXJEYXRhc291cmNlLmZpbHRlcklkID0gdGhpcy5zZWxlY3RlZEZpbHRlcklkO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmRhc2hCb2FyZFdpZGdldENvbmZpZy53aWRnZXRzW3RoaXMubmV3V2lkZ2V0SW5kZXhdLmZpbHRlcnMgPSBkYXRhO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLnRvYXN0ci5zdWNjZXNzKFwiRmlsdGVyIENoYW5nZWRcIilcbiAgICAgICAgfSwgZXJyb2U6IChlcnI6IGFueSkgPT4ge1xuICAgICAgICAgIHRoaXMudG9hc3RyLmVycm9yKCdVbmV4cGVjdGVkIFNlcnZlciBFeGNlcHRpb24uIFBsZWFzZSBjb250YWN0IFN5c3RlbSBBZG1pbi4nLCAnRmlsdGVyIFVwZGF0ZScpXG5cbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9XG4gIH1cblxuXG4gIGNyZWF0ZURpdkVsZW1lbnRzKGRhdGFzZXRCeUlkKSB7XG4gICAgY29uc3QgY29udGFpbmVyID0gdGhpcy5keW5hbWljQ29udGFpbmVyLm5hdGl2ZUVsZW1lbnQ7XG5cbiAgICBjb250YWluZXIuaW5uZXJIVE1MID0gXCJcIjtcbiAgICB0aGlzLmRhc2hCb2FyZFdpZGdldENvbmZpZy53aWRnZXRzLmZvckVhY2goYXN5bmMgZGl2ID0+IHtcbiAgICAgIGNvbnN0IHJvd0RpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgbGV0IHdfaGVpZ2h0ID0gKGRpdi53aWRnZXRQcm9wZXJ0aWVzLmhlaWdodCA9PSBcIlwiKSA/IFwiaC1hdXRvXCIgOiAnaC1bJyArIGRpdi53aWRnZXRQcm9wZXJ0aWVzLmhlaWdodCArICddJztcbiAgICAgIHJvd0Rpdi5jbGFzc0xpc3QuYWRkKGRpdi53aWRnZXRQcm9wZXJ0aWVzLndpZHRoLCB3X2hlaWdodCwgJ2JvcmRlcicpO1xuICAgICAgY29uc3QgZmlsdGVyRGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICBpZiAoZGl2LmZpbHRlcnMpIHtcbiAgICAgICAgdGhpcy5sb2FkRmlsdGVyQ29tcG9uZW50KGRpdiwgZmlsdGVyRGl2LCBkaXYuZmlsdGVycy5maWx0ZXJJdGVtcyk7XG4gICAgICB9XG5cbiAgICAgIHJvd0Rpdi5hcHBlbmRDaGlsZChmaWx0ZXJEaXYpXG5cbiAgICAgIGlmIChkaXYud2lkZ2V0Tm9kZSAmJiBkaXYud2lkZ2V0Tm9kZS5sZW5ndGggJiYgZGl2LndpZGdldE5vZGUubGVuZ3RoICE9IDApIHtcbiAgICAgICAgY29uc3QgbWFpbkl0ZW1EaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgbWFpbkl0ZW1EaXYuY2xhc3NMaXN0LmFkZChcImZsZXhcIiwgXCJmbGV4LXdyYXBcIik7XG4gICAgICAgIHRoaXMubG9hZFdpZGdldE5vZGVzKGRpdiwgbWFpbkl0ZW1EaXYsIGRhdGFzZXRCeUlkKTtcbiAgICAgICAgLy8gZm9yIGxvb3Agb24gd2lkZ2V0XG4gICAgICAgIHJvd0Rpdi5hcHBlbmRDaGlsZChtYWluSXRlbURpdik7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBfaW5uZXJEaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgIHBfaW5uZXJEaXYuY2xhc3NMaXN0LmFkZCgncm91bmRlZCcsICdqdXN0aWZ5LWNlbnRlcicsICdpdGVtcy1jZW50ZXInLCAnYm9yZGVyJywgJ3AtMScsICdtLTEnLCAnZmxleCcsICdmbGV4LXJvdycpO1xuICAgICAgLy8gYWRkIHdpZGdldCBidXR0b25cbiAgICAgIGNvbnN0IHBfYnV0dG9uX3dpZGdldCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgcF9idXR0b25fd2lkZ2V0LmlubmVyVGV4dCA9ICdBZGQgU2luZ2xlIExheW91dCc7XG4gICAgICBwX2J1dHRvbl93aWRnZXQuY2xhc3NMaXN0LmFkZCgnYmctYmx1ZS03MDAnLCBcInAtMVwiLCBcInctZml0XCIsIFwiY3Vyc29yLXBvaW50ZXJcIiwgJ3RleHQteHMnKVxuICAgICAgcF9idXR0b25fd2lkZ2V0LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuXG4gICAgICAgIGxldCBpbmRleCA9IHRoaXMuZGFzaEJvYXJkV2lkZ2V0Q29uZmlnLndpZGdldHMuZmluZEluZGV4KG9iamVjdCA9PiBvYmplY3Qud2lkZ2V0SWQgPT09IGRpdi53aWRnZXRJZCk7XG4gICAgICAgIHRoaXMuaW5zZXJ0TmV3V2lnZXQoaW5kZXgpO1xuICAgICAgfSk7XG4gICAgICAvLyBhZGQgY2hhcnQgYnV0dG9uXG4gICAgICAvLyBjb25zdCBwX2J1dHRvbl9jaGFydCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgLy8gcF9idXR0b25fY2hhcnQuaW5uZXJUZXh0ID0gJ0FkZCBWaWV3JztcbiAgICAgIC8vIHBfYnV0dG9uX2NoYXJ0LmNsYXNzTGlzdC5hZGQoJ2JnLWdyZWVuLTcwMCcsIFwicC0xXCIsIFwidy1maXRcIiwgXCJjdXJzb3ItcG9pbnRlclwiLCAndGV4dC14cycpXG4gICAgICAvLyBwX2J1dHRvbl9jaGFydC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICAgIC8vICAgY29uc3QgY29tcF9vYmplY3QgPSB0aGlzLmZpbmRXaWRnZXRCeUlkKHRoaXMuZGFzaEJvYXJkV2lkZ2V0Q29uZmlnLndpZGdldHMsIGRpdi53aWRnZXRJZCk7XG4gICAgICAvLyAgIHRoaXMuaW5zZXJ0Q2hhcnRXaWdldChjb21wX29iamVjdCwgcm93RGl2KTtcbiAgICAgIC8vIH0pO1xuXG4gICAgICAvLyBkZWxldGUgd2lkZ2V0IGJ1dHRvblxuICAgICAgY29uc3QgcF9kZWxfYnV0dG9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICBwX2RlbF9idXR0b24uaW5uZXJUZXh0ID0gJ0RldGV0ZSBsYXlvdXQnO1xuICAgICAgcF9kZWxfYnV0dG9uLmNsYXNzTGlzdC5hZGQoJ2JnLXJlZC03MDAnLCBcInAtMVwiLCBcInctZml0XCIsIFwiY3Vyc29yLXBvaW50ZXJcIiwgJ3RleHQteHMnKVxuICAgICAgcF9kZWxfYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuXG5cbiAgICAgICAgbGV0IHJlc3VsdCA9IGNvbmZpcm0oXCI8aT5BcmUgWW91IFN1cmU/PC9pPlwiLCBcIkRlbGV0ZSBMYXlvdXRcIik7XG4gICAgICAgIHJlc3VsdC50aGVuKChkaWFsb2dSZXN1bHQpID0+IHtcbiAgICAgICAgICBpZiAoZGlhbG9nUmVzdWx0KSB7XG4gICAgICAgICAgICB0aGlzLmxvYWRpbmdNb2RhbCA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLmRhc2hCb2FyZFdpZGdldENvbmZpZy53aWRnZXRzID0gdGhpcy5kYXNoQm9hcmRXaWRnZXRDb25maWcud2lkZ2V0cy5tYXAoY29uZmlnID0+IGNvbmZpZy53aWRnZXRJZCk7XG4gICAgICAgICAgICByb3dEaXYucmVtb3ZlKClcblxuICAgICAgICAgICAgdGhpcy5zZXJ2aWNlLmVkaXRBcHBQYWdlQ29uZmlnKHRoaXMuZGFzaEJvYXJkV2lkZ2V0Q29uZmlnKS5zdWJzY3JpYmUoe1xuICAgICAgICAgICAgICBuZXh0OiAoZGF0YTogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5nZXRBcHBQYWdlRGV0YWlsQ29uZmlnQnlQYWdlSWQoKVxuICAgICAgICAgICAgICB9LCBlcnJvcjogKGVycjogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2FkaW5nTW9kYWwgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB0aGlzLnRvYXN0ci5lcnJvcignVW5leHBlY3RlZCBTZXJ2ZXIgRXhjZXB0aW9uLiBQbGVhc2UgY29udGFjdCBTeXN0ZW0gQWRtaW4uJywgJ1dpZGdldCBDcmVhdGlvbicpXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB0aGlzLm5ld1dpZGdldEluZGV4ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgdGhpcy5pc1dpZGdldENyZWF0aW9uQ29udGVudCA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5pc0RlZmF1bHRWaWV3ID0gdHJ1ZTtcbiAgICAgICAgICAgIC8vIHRoaXMuZGFzaEJvYXJkV2lkZ2V0Q29uZmlnLndpZGdldHMuc3BsaWNlKGluZGV4LCAxKTtcblxuXG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgLy8gYWR2YW5jZWQgYnV0dG9uXG4gICAgICBjb25zdCBhZHZhbmNlX2J1dHRvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgYWR2YW5jZV9idXR0b24uaW5uZXJUZXh0ID0gJ0FkdmFuY2UgTGF5b3V0JztcbiAgICAgIGFkdmFuY2VfYnV0dG9uLmNsYXNzTGlzdC5hZGQoJ2JnLXllbGxvdy03MDAnLCBcInAtMVwiLCBcInctZml0XCIsIFwiY3Vyc29yLXBvaW50ZXJcIiwgJ3RleHQteHMnKVxuICAgICAgYWR2YW5jZV9idXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGNvbXBfb2JqZWN0ID0gdGhpcy5maW5kV2lkZ2V0QnlJZCh0aGlzLmRhc2hCb2FyZFdpZGdldENvbmZpZy53aWRnZXRzLCBkaXYud2lkZ2V0SWQpO1xuICAgICAgICB0aGlzLm5ld1dpZGdldEluZGV4ID0gdGhpcy5kYXNoQm9hcmRXaWRnZXRDb25maWcud2lkZ2V0cy5maW5kSW5kZXgob2JqZWN0ID0+IG9iamVjdC53aWRnZXRJZCA9PT0gZGl2LndpZGdldElkKTtcblxuICAgICAgICAvLyB0aGlzLmluc2VydENoYXJ0V2lnZXQoY29tcF9vYmplY3QsIHJvd0Rpdik7XG4gICAgICAgIHRoaXMuaXNBZHZhbmNlTGF5b3V0ID0gdHJ1ZTtcblxuICAgICAgfSk7XG5cbiAgICAgIHBfaW5uZXJEaXYuYXBwZW5kQ2hpbGQoYWR2YW5jZV9idXR0b24pO1xuICAgICAgLy8gcF9pbm5lckRpdi5hcHBlbmRDaGlsZChwX2J1dHRvbl9jaGFydCk7XG4gICAgICBwX2lubmVyRGl2LmFwcGVuZENoaWxkKHBfYnV0dG9uX3dpZGdldCk7XG4gICAgICBwX2lubmVyRGl2LmFwcGVuZENoaWxkKHBfZGVsX2J1dHRvbik7XG5cbiAgICAgIGlmICghdGhpcy5pc0Rhc2hCb2FyZENvbnRlbnRUeXBlVmlldykge1xuICAgICAgICByb3dEaXYuYXBwZW5kQ2hpbGQocF9pbm5lckRpdik7XG4gICAgICB9XG4gICAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQocm93RGl2KTtcbiAgICB9KTtcbiAgfVxuXG4gIGxvYWRXaWRnZXROb2RlcyhkaXY6IGFueSwgbWFpbkl0ZW1EaXY6IGFueSwgZGF0YXNldEJ5SWQ6IGFueSkge1xuICAgIGRpdi53aWRnZXROb2RlLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICB0aGlzLmxvYWRTaW5nbGVXaWRnZXROb2RlKGl0ZW0sIG1haW5JdGVtRGl2LCBkYXRhc2V0QnlJZCwgZGl2KTtcbiAgICB9KTtcbiAgfVxuXG4gIGxvYWRTaW5nbGVXaWRnZXROb2RlKGl0ZW06IGFueSwgY29udGFpbmVyRWxlbWVudDogSFRNTEVsZW1lbnQsIGRhdGFzZXRCeUlkOiBhbnksIGRpdikge1xuICAgIGxldCB3X2hlaWdodCA9IChpdGVtLm5vZGVQcm9wZXJ0aWVzLmhlaWdodCA9PSBcIlwiKSA/IFwiaC1hdXRvXCIgOiAnaC1bJyArIGl0ZW0ubm9kZVByb3BlcnRpZXMuaGVpZ2h0ICsgJ10nO1xuICAgIGxldCB3X3dpZHRoID0gKGl0ZW0ubm9kZVByb3BlcnRpZXMud2lkdGggPT0gXCJcIikgPyBcInctZnVsbFwiIDogaXRlbS5ub2RlUHJvcGVydGllcy53aWR0aDtcbiAgICBjb25zdCBpdGVtRGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgaXRlbURpdi5jbGFzc0xpc3QuYWRkKHdfd2lkdGgsIHdfaGVpZ2h0LCAnYm9yZGVyJywgJ3AtMScpO1xuXG4gICAgY29uc3QgZmxleENvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGZsZXhDb250YWluZXIuY2xhc3NMaXN0LmFkZCgnZmxleCcsICdqdXN0aWZ5LWJldHdlZW4nLCAnaXRlbXMtY2VudGVyJywgJ3RleHQtZ3JheS05MDAnLCAnZGFyazp0ZXh0LXdoaXRlJywgJ2JnLWdyYXktODAwJywgJ214LTInLCAncm91bmRlZC10LWxnJyk7IC8vIEZsZXhib3ggY29udGFpbmVyXG5cbiAgICBjb25zdCB3aWRnZXREaXYgPSB0aGlzLmdldFdpZGdldFRpdGxlRGl2KGl0ZW0sIGRpdilcbiAgICBpdGVtLmNvbXBDb25maWcudmlld0NvbmZpZy5mb3JFYWNoKGVsZW1lbnQgPT4ge1xuICAgICAgaWYgKGVsZW1lbnQua3BpQ29uZmlnKSB7XG4gICAgICAgIGxldCBhcGlDYWxscyA9IFtdO1xuICAgICAgICB0aGlzLnNlcnZpY2UuZ2V0QXBwRGF0YXNldENvbmZpZyhlbGVtZW50LmRhdGFzZXRJZCkuc3Vic2NyaWJlKHtcbiAgICAgICAgICBuZXh0OiAoZGF0YXNldDogYW55KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBkYXRhc2V0V2l0aExpbWl0ID0gdGhpcy5zZXREYXRhU2V0c0xpbWl0KGRhdGFzZXQpO1xuICAgICAgICAgICAgYXBpQ2FsbHMucHVzaCh0aGlzLmRhdGFzZXRTZXJ2aWNlLmdldERhdGFGcm9tRGF0YVNldChkYXRhc2V0V2l0aExpbWl0LCBkYXRhc2V0V2l0aExpbWl0LmRhdGFzZXRJZCwgdGhpcy5kZWZhdWx0QXBwbHllZEZpbHRlcikpO1xuICAgICAgICAgICAgUHJvbWlzZS5hbGwoYXBpQ2FsbHMpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLnVuaXF1ZURhdGFTZXRPYmplY3QgPSB0aGlzLmRhdGFzZXRTZXJ2aWNlLmdldFVuaXF1ZURhdGFTZXRPYmplY3QoKTtcbiAgICAgICAgICAgICAgZWxlbWVudC5rcGlDb25maWdbJ2RhdGFTb3VyY2UnXSA9IHRoaXMudW5pcXVlRGF0YVNldE9iamVjdFtlbGVtZW50LmRhdGFzZXRJZF1cbiAgICAgICAgICAgICAgY29uc3QgY29tcF9vYmplY3QgPSB0aGlzLmZpbmRXaWRnZXRCeUlkKHRoaXMuZGFzaEJvYXJkV2lkZ2V0Q29uZmlnLndpZGdldHMsIGl0ZW0uaWQpO1xuICAgICAgICAgICAgICB0aGlzLmxvYWREeW5hbWljQ29tcG9uZW50KGVsZW1lbnQsIGNvbXBfb2JqZWN0LCBpdGVtRGl2KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0sIGVycm9yOiAoZXJyOiBhbnkpID0+IHtcblxuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICB9KTtcbiAgICBmbGV4Q29udGFpbmVyLmFwcGVuZENoaWxkKHdpZGdldERpdik7XG5cbiAgICAvLyBDcmVhdGUgYnV0dG9ucyBjb250YWluZXIgZm9yIGFsaWdubWVudFxuICAgIGNvbnN0IGJ1dHRvbnNDb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBidXR0b25zQ29udGFpbmVyLmNsYXNzTGlzdC5hZGQoJ2ZsZXgnLCAnbXgtMicpOyAvLyBUbyBhbGlnbiBidXR0b25zIHNpZGUgYnkgc2lkZSB3aXRoIHNvbWUgc3BhY2luZ1xuXG5cbiAgICBjb25zdCBpbm5lckRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGlubmVyRGl2LmNsYXNzTGlzdC5hZGQoJ3JvdW5kZWQnLCAnanVzdGlmeS1jZW50ZXInLCAnaXRlbXMtY2VudGVyJywgJ3AtMScsICdtLTEnLCAnZmxleCcsICdmbGV4LXJvdycpO1xuXG4gICAgY29uc3QgYnV0dG9uX2NoYXJ0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgYnV0dG9uX2NoYXJ0LmlubmVyVGV4dCA9ICdBZGQgVmlldyc7XG4gICAgYnV0dG9uX2NoYXJ0LmNsYXNzTGlzdC5hZGQoJ2JnLWdyZWVuLTcwMCcsIFwicC0xXCIsIFwidy1maXRcIiwgXCJjdXJzb3ItcG9pbnRlclwiLCAndGV4dC14cycpXG4gICAgYnV0dG9uX2NoYXJ0LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgdGhpcy5uZXdXaWRnZXRJbmRleCA9IHRoaXMuZGFzaEJvYXJkV2lkZ2V0Q29uZmlnLndpZGdldHMuZmluZEluZGV4KG9iamVjdCA9PiBvYmplY3Qud2lkZ2V0SWQgPT09IGRpdi53aWRnZXRJZCk7XG4gICAgICBjb25zdCBjb21wX29iamVjdCA9IHRoaXMuZmluZFdpZGdldEJ5SWQodGhpcy5kYXNoQm9hcmRXaWRnZXRDb25maWcud2lkZ2V0cywgaXRlbS5pZCk7XG4gICAgICB0aGlzLmluc2VydENoYXJ0V2lnZXQoY29tcF9vYmplY3QsIGl0ZW1EaXYpO1xuICAgIH0pO1xuXG5cbiAgICBjb25zdCBkZWxfYnV0dG9uX2NoYXJ0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgZGVsX2J1dHRvbl9jaGFydC5pbm5lclRleHQgPSAnRGV0ZXRlJztcbiAgICBkZWxfYnV0dG9uX2NoYXJ0LmNsYXNzTGlzdC5hZGQoJ2JnLXJlZC03MDAnLCBcInAtMVwiLCBcInctZml0XCIsIFwiY3Vyc29yLXBvaW50ZXJcIiwgJ3RleHQteHMnKVxuICAgIGRlbF9idXR0b25fY2hhcnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgICBsZXQgcmVzdWx0ID0gY29uZmlybShcIjxpPkFyZSBZb3UgU3VyZT88L2k+XCIsIFwiRGVsZXRlIFZpZXdcIik7XG4gICAgICByZXN1bHQudGhlbigoZGlhbG9nUmVzdWx0KSA9PiB7XG4gICAgICAgIGlmIChkaWFsb2dSZXN1bHQpIHtcbiAgICAgICAgICBsZXQgd2lkZ2V0SW5kZXggPSB0aGlzLmRhc2hCb2FyZFdpZGdldENvbmZpZy53aWRnZXRzLmZpbmRJbmRleChvYmplY3QgPT4gb2JqZWN0LndpZGdldElkID09PSBkaXYud2lkZ2V0SWQpO1xuICAgICAgICAgIGNvbnN0IG1hcGVkT2JqZWN0ID0gdGhpcy5kYXNoQm9hcmRXaWRnZXRDb25maWcud2lkZ2V0c1t3aWRnZXRJbmRleF1cbiAgICAgICAgICBpZiAobWFwZWRPYmplY3Qud2lkZ2V0Tm9kZSAmJiBtYXBlZE9iamVjdC53aWRnZXROb2RlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGxldCBtYXBJbmRleCA9IG1hcGVkT2JqZWN0LndpZGdldE5vZGUuZmluZEluZGV4KGluZCA9PiBpbmQuaWQgPT09IGl0ZW0uaWQpXG4gICAgICAgICAgICBtYXBlZE9iamVjdC53aWRnZXROb2RlLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgICAgICAgIG5vZGUuY29tcENvbmZpZy52aWV3Q29uZmlnID0gbm9kZS5jb21wQ29uZmlnLnZpZXdDb25maWcubWFwKGNvbmZpZyA9PiBjb25maWcudmlld0lkKTtcbiAgICAgICAgICAgICAgbm9kZS5jb21wQ29uZmlnLmR5bmFtaWNDb21wb25lbnRSZWZzID0gW107XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIG1hcGVkT2JqZWN0LndpZGdldE5vZGUuc3BsaWNlKG1hcEluZGV4LCAxKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgbWFwZWRPYmplY3RbJ2ZpbHRlcklkJ10gPSAobWFwZWRPYmplY3QuZmlsdGVycykgPyBtYXBlZE9iamVjdC5maWx0ZXJzLmZpbHRlcklkIDogbnVsbDtcbiAgICAgICAgICBkZWxldGUgbWFwZWRPYmplY3RbJ2ZpbHRlcnMnXTtcbiAgICAgICAgICBtYXBlZE9iamVjdC5jb21wQ29uZmlnLmR5bmFtaWNDb21wb25lbnRSZWZzID0gW107XG4gICAgICAgICAgdGhpcy5zZXJ2aWNlLmVkaXRBcHBXaWRnZXRDb25maWcobWFwZWRPYmplY3QpLnN1YnNjcmliZSh7XG4gICAgICAgICAgICBuZXh0OiAoZGF0YTogYW55KSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuZ2V0QXBwUGFnZURldGFpbENvbmZpZ0J5UGFnZUlkKClcbiAgICAgICAgICAgIH0sIGVycm9yOiAoZXJyOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5sb2FkaW5nTW9kYWwgPSBmYWxzZTtcbiAgICAgICAgICAgICAgdGhpcy50b2FzdHIuZXJyb3IoJ1VuZXhwZWN0ZWQgU2VydmVyIEV4Y2VwdGlvbi4gUGxlYXNlIGNvbnRhY3QgU3lzdGVtIEFkbWluLicsICdXaWRnZXQgQ3JlYXRpb24nKVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pXG4gICAgICAgICAgdGhpcy5uZXdXaWRnZXRJbmRleCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICBpdGVtRGl2LnJlbW92ZSgpXG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuXG5cbiAgICAvLyBpbm5lckRpdi5hcHBlbmRDaGlsZChidXR0b25fY2hhcnQpO1xuICAgIC8vIGlubmVyRGl2LmFwcGVuZENoaWxkKGRlbF9idXR0b25fY2hhcnQpO1xuICAgIC8vIEFwcGVuZCBidXR0b25zIHRvIGJ1dHRvbnMgY29udGFpbmVyXG4gICAgYnV0dG9uc0NvbnRhaW5lci5hcHBlbmRDaGlsZChidXR0b25fY2hhcnQpO1xuICAgIGJ1dHRvbnNDb250YWluZXIuYXBwZW5kQ2hpbGQoZGVsX2J1dHRvbl9jaGFydCk7XG5cbiAgICAvLyBBZGQgdGhlIGJ1dHRvbnMgY29udGFpbmVyIHRvIHRoZSBmbGV4IGNvbnRhaW5lclxuICAgIGZsZXhDb250YWluZXIuYXBwZW5kQ2hpbGQoYnV0dG9uc0NvbnRhaW5lcik7XG4gICAgaWYgKCF0aGlzLmlzRGFzaEJvYXJkQ29udGVudFR5cGVWaWV3KSB7XG4gICAgfVxuICAgIGl0ZW1EaXYuYXBwZW5kQ2hpbGQoZmxleENvbnRhaW5lcik7XG4gICAgLy8gaXRlbURpdi5hcHBlbmRDaGlsZCh3aWRnZXREaXYpO1xuXG4gICAgY29udGFpbmVyRWxlbWVudC5hcHBlbmRDaGlsZChpdGVtRGl2KVxuXG5cblxuICB9XG5cblxuXG4gIGZpbmRXaWRnZXRCeUlkKGNvbmZpZ3M6IGFueVtdLCBpZDogc3RyaW5nKTogYW55IHwgdW5kZWZpbmVkIHtcbiAgICBmb3IgKGNvbnN0IGNvbmZpZyBvZiBjb25maWdzKSB7XG4gICAgICBpZiAoY29uZmlnLmlkID09PSBpZCkge1xuICAgICAgICByZXR1cm4gY29uZmlnO1xuICAgICAgfVxuICAgICAgaWYgKGNvbmZpZy53aWRnZXROb2RlICYmIGNvbmZpZy53aWRnZXROb2RlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgZm91bmQgPSB0aGlzLmZpbmRXaWRnZXRCeUlkKGNvbmZpZy53aWRnZXROb2RlLCBpZCk7XG4gICAgICAgIGlmIChmb3VuZCkge1xuICAgICAgICAgIHJldHVybiBmb3VuZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgZGVsZXRlV2lkZ2V0QnlJZChjb25maWdzOiBhbnlbXSwgaWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGZvciAobGV0IGkgPSBjb25maWdzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBpZiAoY29uZmlnc1tpXS5pZCA9PT0gaWQpIHtcbiAgICAgICAgY29uZmlncy5zcGxpY2UoaSwgMSk7XG4gICAgICB9IGVsc2UgaWYgKGNvbmZpZ3NbaV0ud2lkZ2V0Tm9kZSAmJiBjb25maWdzW2ldLndpZGdldE5vZGUubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLmRlbGV0ZVdpZGdldEJ5SWQoY29uZmlnc1tpXS53aWRnZXROb2RlLCBpZCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgbG9hZER5bmFtaWNDb21wb25lbnQoZGF0YSwgaW5kZXhPYmosIGNvbnRhaW5lckVsZW1lbnQpOiBhbnkge1xuICAgIGNvbnN0IGNvbXBvbmVudENsYXNzID0gdGhpcy5jb21wb25lbnRDbGFzc01hcFtkYXRhLmtwaUNvbmZpZ1snY29tcG9uZW50TmFtZSddXTtcbiAgICB0aGlzLkNvbXBSZWZzID0gdGhpcy52aWV3Q29udGFpbmVyUmVmLmNyZWF0ZUNvbXBvbmVudChjb21wb25lbnRDbGFzcyk7XG4gICAgY29uc3QgZHluYW1pY0NvbXBvbmVudEluc3RhbmNlID0gdGhpcy5Db21wUmVmcy5pbnN0YW5jZTtcbiAgICBkeW5hbWljQ29tcG9uZW50SW5zdGFuY2UuY2hhcnREYXRhU291cmNlID0gZGF0YTtcbiAgICBkeW5hbWljQ29tcG9uZW50SW5zdGFuY2Uua3BpX25hbWUgPSBcIlwiO1xuXG4gICAgaW5kZXhPYmouY29tcENvbmZpZy5keW5hbWljQ29tcG9uZW50UmVmcy5wdXNoKHRoaXMuQ29tcFJlZnMpO1xuICAgIGNvbnN0IGNzc0NsYXNzID0gXCJ3LWZ1bGxcIjtcbiAgICB0aGlzLkNvbXBSZWZzLmxvY2F0aW9uLm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LmFkZChjc3NDbGFzcyk7XG4gICAgY29udGFpbmVyRWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLkNvbXBSZWZzLmxvY2F0aW9uLm5hdGl2ZUVsZW1lbnQpO1xuICB9XG5cbiAgbG9hZEZpbHRlckNvbXBvbmVudChpbmRleE9iaiwgY29udGFpbmVyRWxlbWVudCwgZmlsdGVySXRlbXMpIHtcblxuICAgIGxldCBzZWxlY3RlZERhdGVzID0geyBzdGFydERhdGU6IHRoaXMuZGVmYXVsdFN0YXJ0RGF0ZSwgZW5kRGF0ZTogdGhpcy5kZWZhdWx0RW5kRGF0ZSB9XG4gICAgY29uc3QgY29tcG9uZW50Q2xhc3MgPSB0aGlzLmNvbXBvbmVudENsYXNzTWFwWydBcHBBZHZhbmNlSGVhZGVyQ29tcG9uZW50J107XG4gICAgdGhpcy5Db21wUmVmcyA9IHRoaXMudmlld0NvbnRhaW5lclJlZi5jcmVhdGVDb21wb25lbnQoY29tcG9uZW50Q2xhc3MpO1xuICAgIGNvbnN0IGR5bmFtaWNDb21wb25lbnRJbnN0YW5jZSA9IHRoaXMuQ29tcFJlZnMuaW5zdGFuY2U7XG4gICAgZHluYW1pY0NvbXBvbmVudEluc3RhbmNlLnNlbGVjdGVkRGF0ZXMgPSBzZWxlY3RlZERhdGVzO1xuICAgIGR5bmFtaWNDb21wb25lbnRJbnN0YW5jZS5maWx0ZXJJdGVtcyA9IGZpbHRlckl0ZW1zO1xuXG5cbiAgICBkeW5hbWljQ29tcG9uZW50SW5zdGFuY2UucGFnZVRpdGxlID0gdGhpcy5wYWdlVGl0bGU7XG4gICAgZHluYW1pY0NvbXBvbmVudEluc3RhbmNlLmlzRWRpdEJ1dHRvbiA9IGZhbHNlO1xuICAgIGR5bmFtaWNDb21wb25lbnRJbnN0YW5jZS5pc0FkdmFuY2VCdXR0b24gPSB0cnVlO1xuXG4gICAgaW5kZXhPYmouY29tcENvbmZpZy5keW5hbWljQ29tcG9uZW50UmVmcy5wdXNoKHRoaXMuQ29tcFJlZnMpO1xuICAgIGNvbnN0IGNzc0NsYXNzID0gXCJ3LWZ1bGxcIjtcbiAgICB0aGlzLkNvbXBSZWZzLmxvY2F0aW9uLm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LmFkZChjc3NDbGFzcyk7XG4gICAgY29udGFpbmVyRWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLkNvbXBSZWZzLmxvY2F0aW9uLm5hdGl2ZUVsZW1lbnQpO1xuICB9XG5cbiAgbG9hZFdpZGdldEZpbHRlckNvbXBvbmVudChpbmRleE9iaiwgY29udGFpbmVyRWxlbWVudCwgZmlsdGVySXRlbXMpIHtcbiAgICBsZXQgdXNlck5hbWUgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgndXNlcl9uYW1lJylcbiAgICBsZXQgc2VsZWN0ZWREYXRlcyA9IHsgc3RhcnREYXRlOiB0aGlzLmRlZmF1bHRTdGFydERhdGUsIGVuZERhdGU6IHRoaXMuZGVmYXVsdEVuZERhdGUgfVxuICAgIGNvbnN0IGNvbXBvbmVudENsYXNzID0gdGhpcy5jb21wb25lbnRDbGFzc01hcFsnQWR2YW5jZVdpZGdldEhlYWRlckZpbHRlckNvbXBvbmVudCddO1xuICAgIHRoaXMuQ29tcFJlZnMgPSB0aGlzLnZpZXdDb250YWluZXJSZWYuY3JlYXRlQ29tcG9uZW50KGNvbXBvbmVudENsYXNzKTtcbiAgICBjb25zdCBkeW5hbWljQ29tcG9uZW50SW5zdGFuY2UgPSB0aGlzLkNvbXBSZWZzLmluc3RhbmNlO1xuICAgIGR5bmFtaWNDb21wb25lbnRJbnN0YW5jZS5zZWxlY3RlZERhdGVzID0gc2VsZWN0ZWREYXRlcztcbiAgICBkeW5hbWljQ29tcG9uZW50SW5zdGFuY2UuZmlsdGVySXRlbXMgPSBmaWx0ZXJJdGVtcztcbiAgICBkeW5hbWljQ29tcG9uZW50SW5zdGFuY2UuZ2V0V2lkZ2V0RmlsdGVyQ29uZmlnLnN1YnNjcmliZSgodmFsdWU6IHN0cmluZykgPT4ge1xuICAgICAgdGhpcy5nZXRXaWRnZXRGaWx0ZXJGb3JUZW1wbGF0ZSh2YWx1ZSk7XG4gICAgfSk7XG5cbiAgICBpbmRleE9iai5jb21wQ29uZmlnLmR5bmFtaWNDb21wb25lbnRSZWZzLnB1c2godGhpcy5Db21wUmVmcyk7XG4gICAgY29udGFpbmVyRWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLkNvbXBSZWZzLmxvY2F0aW9uLm5hdGl2ZUVsZW1lbnQpO1xuICB9XG5cbiAgZ2V0RGVsZXRlVmlld0Zyb21Db25maWcoaW5kZXgpIHtcbiAgICBjb25zb2xlLmxvZyhpbmRleCk7XG4gICAgdGhpcy5hbGxXaWRnZXRJbm5lckNvbnRlbnQuc3BsaWNlKGluZGV4LCAxKVxuICB9XG5cbiAgbW92ZUl0ZW1Gb3JQYWdlVmlldyhpbmRleDogbnVtYmVyLCBkaXJlY3Rpb246ICd1cCcgfCAnZG93bicpOiB2b2lkIHtcbiAgICAvLyBQcmV2ZW50IG1vdmluZyBiZXlvbmQgYXJyYXkgYm91bmRzXG4gICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSB0aGlzLmRhc2hCb2FyZFdpZGdldENvbmZpZy53aWRnZXRzW3RoaXMubmV3V2lkZ2V0SW5kZXhdLndpZGdldE5vZGUubGVuZ3RoKSByZXR1cm47XG4gICAgY29uc3QgbmV3UG9zaXRpb24gPSBkaXJlY3Rpb24gPT09ICd1cCcgPyBpbmRleCAtIDEgOiBpbmRleCArIDE7XG4gICAgLy8gUHJldmVudCBtb3ZpbmcgYmV5b25kIGFycmF5IGJvdW5kc1xuICAgIGlmIChuZXdQb3NpdGlvbiA8IDAgfHwgbmV3UG9zaXRpb24gPj0gdGhpcy5kYXNoQm9hcmRXaWRnZXRDb25maWcud2lkZ2V0c1t0aGlzLm5ld1dpZGdldEluZGV4XS53aWRnZXROb2RlLmxlbmd0aCkgcmV0dXJuO1xuXG4gICAgLy8gTW92ZSBpdGVtXG4gICAgY29uc3QgaXRlbVRvTW92ZSA9IHRoaXMuZGFzaEJvYXJkV2lkZ2V0Q29uZmlnLndpZGdldHNbdGhpcy5uZXdXaWRnZXRJbmRleF0ud2lkZ2V0Tm9kZVtpbmRleF07XG4gICAgdGhpcy5kYXNoQm9hcmRXaWRnZXRDb25maWcud2lkZ2V0c1t0aGlzLm5ld1dpZGdldEluZGV4XS53aWRnZXROb2RlLnNwbGljZShpbmRleCwgMSk7IC8vIFJlbW92ZSBpdGVtIGZyb20gY3VycmVudCBwb3NpdGlvblxuICAgIHRoaXMuZGFzaEJvYXJkV2lkZ2V0Q29uZmlnLndpZGdldHNbdGhpcy5uZXdXaWRnZXRJbmRleF0ud2lkZ2V0Tm9kZS5zcGxpY2UobmV3UG9zaXRpb24sIDAsIGl0ZW1Ub01vdmUpOyAvLyBJbnNlcnQgaXRlbSBpbiBuZXcgcG9zaXRpb25cbiAgfVxuICBtb3ZlSXRlbUZvckNvbHVtbnMoaW5kZXg6IG51bWJlciwgZGlyZWN0aW9uOiAndXAnIHwgJ2Rvd24nKTogdm9pZCB7XG4gICAgLy8gUHJldmVudCBtb3ZpbmcgYmV5b25kIGFycmF5IGJvdW5kc1xuICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gdGhpcy5hbGxXaWRnZXRJbm5lckNvbnRlbnQubGVuZ3RoKSByZXR1cm47XG4gICAgY29uc3QgbmV3UG9zaXRpb24gPSBkaXJlY3Rpb24gPT09ICd1cCcgPyBpbmRleCAtIDEgOiBpbmRleCArIDE7XG4gICAgLy8gUHJldmVudCBtb3ZpbmcgYmV5b25kIGFycmF5IGJvdW5kc1xuICAgIGlmIChuZXdQb3NpdGlvbiA8IDAgfHwgbmV3UG9zaXRpb24gPj0gdGhpcy5hbGxXaWRnZXRJbm5lckNvbnRlbnQubGVuZ3RoKSByZXR1cm47XG5cbiAgICAvLyBNb3ZlIGl0ZW1cbiAgICBjb25zdCBpdGVtVG9Nb3ZlID0gdGhpcy5hbGxXaWRnZXRJbm5lckNvbnRlbnRbaW5kZXhdO1xuICAgIHRoaXMuYWxsV2lkZ2V0SW5uZXJDb250ZW50LnNwbGljZShpbmRleCwgMSk7IC8vIFJlbW92ZSBpdGVtIGZyb20gY3VycmVudCBwb3NpdGlvblxuICAgIHRoaXMuYWxsV2lkZ2V0SW5uZXJDb250ZW50LnNwbGljZShuZXdQb3NpdGlvbiwgMCwgaXRlbVRvTW92ZSk7IC8vIEluc2VydCBpdGVtIGluIG5ldyBwb3NpdGlvblxuICB9XG5cbiAgbW92ZUl0ZW1Gb3JXaWRnZXQoaW5kZXg6IG51bWJlciwgZGlyZWN0aW9uOiAndXAnIHwgJ2Rvd24nKTogdm9pZCB7XG4gICAgLy8gUHJldmVudCBtb3ZpbmcgYmV5b25kIGFycmF5IGJvdW5kc1xuICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gdGhpcy5kYXNoQm9hcmRXaWRnZXRDb25maWcud2lkZ2V0cy5sZW5ndGgpIHJldHVybjtcbiAgICBjb25zdCBuZXdQb3NpdGlvbiA9IGRpcmVjdGlvbiA9PT0gJ3VwJyA/IGluZGV4IC0gMSA6IGluZGV4ICsgMTtcbiAgICAvLyBQcmV2ZW50IG1vdmluZyBiZXlvbmQgYXJyYXkgYm91bmRzXG4gICAgaWYgKG5ld1Bvc2l0aW9uIDwgMCB8fCBuZXdQb3NpdGlvbiA+PSB0aGlzLmRhc2hCb2FyZFdpZGdldENvbmZpZy53aWRnZXRzLmxlbmd0aCkgcmV0dXJuO1xuXG4gICAgLy8gTW92ZSBpdGVtXG4gICAgY29uc3QgaXRlbVRvTW92ZSA9IHRoaXMuZGFzaEJvYXJkV2lkZ2V0Q29uZmlnLndpZGdldHNbaW5kZXhdO1xuICAgIHRoaXMuZGFzaEJvYXJkV2lkZ2V0Q29uZmlnLndpZGdldHMuc3BsaWNlKGluZGV4LCAxKTsgLy8gUmVtb3ZlIGl0ZW0gZnJvbSBjdXJyZW50IHBvc2l0aW9uXG4gICAgdGhpcy5kYXNoQm9hcmRXaWRnZXRDb25maWcud2lkZ2V0cy5zcGxpY2UobmV3UG9zaXRpb24sIDAsIGl0ZW1Ub01vdmUpOyAvLyBJbnNlcnQgaXRlbSBpbiBuZXcgcG9zaXRpb25cbiAgfVxuXG4gIGdldEVkaXRWaWV3RnJvbUxheW91dChkYXRhLCBpbmRleCkge1xuXG4gICAgdGhpcy5pc0VkaXRNYWluTGF5b3V0ID0gdHJ1ZTtcbiAgICB0aGlzLm5ld1dpZGdldEluZGV4ID0gaW5kZXg7XG4gICAgdGhpcy5pc1dpZGdldENyZWF0aW9uQ29udGVudCA9IHRydWU7XG4gICAgdGhpcy5pc0RlZmF1bHRWaWV3ID0gZmFsc2U7XG4gICAgdGhpcy5pc0NoYXJ0QnV0dG9uQ2xpY2sgPSBmYWxzZTtcbiAgICB0aGlzLmlzVXBkYXRlV2lkZ2V0ID0gZmFsc2U7XG4gICAgdGhpcy53aWRnZXROYW1lID0gZGF0YS53aWRnZXROYW1lO1xuICAgIHRoaXMud2lkZ2V0VGl0bGUgPSBkYXRhLndpZGdldFRpdGxlO1xuICAgIHRoaXMuc2VsZWN0ZWRGaWx0ZXJJZCA9IGRhdGEuZmlsdGVycy5maWx0ZXJJZDtcbiAgICB0aGlzLmFkZGVkd2lkR2V0Q29uZmlnID0gZGF0YS53aWRnZXRQcm9wZXJ0aWVzO1xuICB9XG5cblxuICBiYWNrVG9NYWluVmlldygpIHtcbiAgICB0aGlzLmlzRGVmYXVsdFZpZXcgPSB0cnVlO1xuICAgIHRoaXMuaXNVcGRhdGVXaWRnZXQgPSBmYWxzZTtcbiAgICB0aGlzLmlzV2lkZ2V0Q3JlYXRpb25Db250ZW50ID0gZmFsc2U7XG4gICAgdGhpcy5pc0NoYXJ0QnV0dG9uQ2xpY2sgPSBmYWxzZTtcbiAgICB0aGlzLmlzRWRpdE1haW5MYXlvdXQgPSBmYWxzZTtcbiAgICB0aGlzLmlzbGF5b3V0Q3JlYXRlID0gZmFsc2U7XG4gICAgdGhpcy5uZXdXaWRnZXRJbmRleCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnNlbGVjdGVkRmlsdGVySWQgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBmaWx0ZXJWaWV3cygpIHtcbiAgICBpZiAodGhpcy52aWV3VG9TZWFyY2gudHJpbSgpICE9PSAnJykge1xuICAgICAgdGhpcy5maWx0ZXJlZENvbXBvbmVudENvbmZpZyA9IHRoaXMuY29tcG9uZW50Q29uZmlnRGF0YVNvdXJjZS5maWx0ZXIoKGl0ZW06IGFueSkgPT5cbiAgICAgICAgaXRlbS52aWV3TmFtZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHRoaXMudmlld1RvU2VhcmNoLnRvTG93ZXJDYXNlKCkpXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmZpbHRlcmVkQ29tcG9uZW50Q29uZmlnID0gdGhpcy5jb21wb25lbnRDb25maWdEYXRhU291cmNlO1xuICAgIH1cbiAgfVxuXG4gIGVkaXRDb21wb25lbnRWaWV3cyhpdGVtKSB7XG4gICAgdGhpcy5sb2FkaW5nTW9kYWwgPSB0cnVlO1xuICAgIHRoaXMuZWRpdEl0ZW1Gb3JVcGRhdGUgPSBpdGVtO1xuICAgIGlmICh0aGlzLmlzVXBkYXRlV2lkZ2V0ICYmICF0aGlzLmlzQ2hhcnRCdXR0b25DbGljaykge1xuICAgICAgdGhpcy5zZWxlY3RlZFZpZXdJZCA9IGl0ZW0udmlld0lkO1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuaXNDcmVhdGVOZXdWaWV3V2l0aERlZmF1bHRWaWV3ID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5sb2FkaW5nTW9kYWwgPSBmYWxzZTtcbiAgICAgIH0sIDQwMCk7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IG5hdmlnYXRpb246IE5hdmlnYXRpb25FeHRyYXMgPSB7XG4gICAgICAgIHF1ZXJ5UGFyYW1zOiB7XG4gICAgICAgICAgJ3ZpZXdJZCc6IGl0ZW0udmlld0lkLFxuICAgICAgICAgICdwYWdlSWQnOiB0aGlzLnBhZ2VJZFxuICAgICAgICB9XG4gICAgICB9O1xuICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoWydhcHBzL2NvbnRyb2xQYW5lbC9hcHBsaWNhdGlvbkNvbnRlbnQvYXBwbGljYXRpb25WaWV3cyddLCBuYXZpZ2F0aW9uKTtcbiAgICB9XG4gIH1cbiAgZWRpdENvbXBvbmVudERhdGFzZXRzKGl0ZW0pIHtcbiAgICB0aGlzLmxvYWRpbmdNb2RhbCA9IHRydWU7XG4gICAgdGhpcy5lZGl0SXRlbUZvclVwZGF0ZSA9IGl0ZW07XG4gICAgaWYgKHRoaXMuaXNVcGRhdGVXaWRnZXQgJiYgIXRoaXMuaXNDaGFydEJ1dHRvbkNsaWNrKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkRGF0YXNldElkID0gaXRlbS5kYXRhc2V0SWQ7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5pc0NyZWF0ZURhdGFzZXRXaXRoRGF0YXNldElkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5sb2FkaW5nTW9kYWwgPSBmYWxzZTtcbiAgICAgIH0sIDQwMCk7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IG5hdmlnYXRpb246IE5hdmlnYXRpb25FeHRyYXMgPSB7XG4gICAgICAgIHF1ZXJ5UGFyYW1zOiB7XG4gICAgICAgICAgJ3ZpZXdJZCc6IGl0ZW0udmlld0lkLFxuICAgICAgICAgICdwYWdlSWQnOiB0aGlzLnBhZ2VJZFxuICAgICAgICB9XG4gICAgICB9O1xuICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoWydhcHBzL2NvbnRyb2xQYW5lbC9hcHBsaWNhdGlvbkNvbnRlbnQvYXBwbGljYXRpb25WaWV3cyddLCBuYXZpZ2F0aW9uKTtcbiAgICB9XG4gIH1cblxuICBnZXRBbGxQYWdlKCkge1xuICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFsnYXBwcy9jb250cm9sUGFuZWwvYXBwbGljYXRpb25Db250ZW50L2FwcGxpY2F0aW9uRGFzaGJvYXJkJ10pO1xuICB9XG5cbiAgdHJhbnNmb3JtQ29sdW1uc0ZvckNvbHVtbnMoaW5wdXRDb2x1bW5zKSB7XG4gICAgY29uc3QgY29sdW1ucyA9IFtdO1xuXG4gICAgaW5wdXRDb2x1bW5zLmZvckVhY2goY29sID0+IHtcbiAgICAgIGNvbHVtbnMucHVzaCh7XG4gICAgICAgIGRhdGFGaWVsZDogY29sLmRhdGFGaWVsZCxcbiAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgY2FwdGlvbjogY29sLmNhcHRpb24sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHJldHVybiBjb2x1bW5zO1xuICB9XG5cblxuICBnZXRDcmVhdGVEYXRhU2V0UGFnZSgpIHtcbiAgICB0aGlzLmlzQ3JlYXRlRGF0YXNldCA9IHRydWU7XG4gIH1cblxuICBnZXRDcmVhdGVWaWV3UGFnZSgpIHtcblxuICAgIHRoaXMuc2VsZWN0ZWRWaWV3SWQgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5sb2FkaW5nTW9kYWwgPSB0cnVlO1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5pc0NyZWF0ZU5ld1ZpZXcgPSB0cnVlO1xuICAgICAgdGhpcy5sb2FkaW5nTW9kYWwgPSBmYWxzZTtcbiAgICB9LCA0MDApO1xuICB9XG5cblxuICBnZXRFbWl0TmV3Q2hhcnRDb25naWcoZXZlbnQpIHtcbiAgICBkZWxldGUgZXZlbnQua3BpQ29uZmlnLmRhdGFTb3VyY2U7XG4gICAgdGhpcy5lZGl0SXRlbUZvclVwZGF0ZVsna3BpQ29uZmlnJ10gPSBldmVudC5rcGlDb25maWc7XG5cbiAgICBjb25zb2xlLmxvZyh0aGlzLmVkaXRJdGVtRm9yVXBkYXRlKTtcbiAgICB0aGlzLnNlcnZpY2UudXBkYXRlQXBwVmlld0NvbmZpZyh0aGlzLmVkaXRJdGVtRm9yVXBkYXRlKS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKGRhdGE6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLmlzRWRpdE9wdGlvbkNsaWNrID0gZmFsc2U7XG4gICAgICAgIHRoaXMudG9hc3RyLnN1Y2Nlc3MoJ1ZpZXcgVXBkYXRlIFN1Y2Nlc3NmdWxseScpXG4gICAgICB9LCBlcnJvcjogKGVycjogYW55KSA9PiB7XG4gICAgICAgIHRoaXMudG9hc3RyLmVycm9yKCdVbmV4cGVjdGVkIFNlcnZlciBFeGNlcHRpb24uIFBsZWFzZSBjb250YWN0IFN5c3RlbSBBZG1pbi4nLCAnVmlldyBDcmVhdGlvbicpXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG5cbiAgZ2V0Vmlld1BhZ2UoKSB7XG4gICAgbGV0IG5hdmlnYXRpb25FeHRyYXM6IE5hdmlnYXRpb25FeHRyYXMgPSB7XG4gICAgICBxdWVyeVBhcmFtczoge1xuICAgICAgICBcInBhZ2VJZFwiOiB0aGlzLnBhZ2VJZFxuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbdGhpcy5wYWdlVXJsXSwgbmF2aWdhdGlvbkV4dHJhcylcblxuICB9XG4gIC8vIG5vZGVwcm9wZXJ0aWNlIGZpbHRlciBcblxuICBnZXROb2RlUHJvcGVydGljZUZpbHRlck9wdGlvbigpIHtcbiAgICBsZXQgb2JqID0ge1xuICAgICAgaW5wdXRfdHlwZTogXCJ0ZXh0XCIsXG4gICAgICBzZXJ2ZXJfY29sdW1uOiBcIlwiLFxuICAgICAgbG9jYWxfY29sdW1uOiBcIlwiLFxuICAgICAgc2VsZWN0X2JveF9vcHRpb246IFwiXCIsXG4gICAgfVxuICAgIHRoaXMubm9kZVByb3BlcnRpY2VGaWx0ZXJzLnB1c2gob2JqKVxuICB9XG5cbiAgZGVsZXRlTm9kZUZpbHRlcihpbmRleCkge1xuICAgIHRoaXMubm9kZVByb3BlcnRpY2VGaWx0ZXJzLnNwbGljZShpbmRleCwgMSlcbiAgfVxuXG4gIHNldERhdGFTZXRzTGltaXQoZGF0YXNldCkge1xuICAgIGxldCBsaW1pdCA9IHsgXCJsaW1pdFwiOiBcIjEwXCIgfVxuICAgIGRhdGFzZXQuY29uZmlnLnF1ZXJ5Q29uZmlnLnJlcUZpZWxkcy5wdXNoKGxpbWl0KTtcbiAgICByZXR1cm4gZGF0YXNldDtcbiAgfVxuXG4gIGdldFZpZXdQb3B1cEhpZGUoZSkge1xuICAgIHRoaXMuZ2V0QWxsVmlld3NJdGVtcygpO1xuICB9XG5cbiAgZ2V0RGF0YXNldFBvcHVwSGlkZShlKSB7XG5cbiAgfVxuXG4gIHN1Ym1pdEZpbHRlcigpIHtcblxuICB9XG5cbiAgZ2V0V2lkZ2V0RmlsdGVyRm9yVGVtcGxhdGUodmFsdWUpIHtcbiAgICB0aGlzLmdldERhdGFTZXQoKTtcbiAgfVxuXG4gIGdldERlbGV0ZVZpZXdGcm9tTGF5b3V0KGl0ZW0sIGkpIHtcbiAgICB0aGlzLmRhc2hCb2FyZFdpZGdldENvbmZpZy53aWRnZXRzLnNwbGljZShpLCAxKTtcbiAgICB0aGlzLmRhc2hCb2FyZFdpZGdldENvbmZpZy53aWRnZXRzLmZvckVhY2god2lkZ2V0ID0+IHtcbiAgICAgIHdpZGdldC5jb21wQ29uZmlnLnZpZXdDb25maWcgPSB3aWRnZXQuY29tcENvbmZpZy52aWV3Q29uZmlnLm1hcChjb25maWcgPT4gY29uZmlnLnZpZXdJZCk7XG4gICAgICB3aWRnZXQuY29tcENvbmZpZy5keW5hbWljQ29tcG9uZW50UmVmcyA9IFtdO1xuICAgICAgaWYgKHdpZGdldC53aWRnZXROb2RlICYmIHdpZGdldC53aWRnZXROb2RlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgd2lkZ2V0LndpZGdldE5vZGUuZm9yRWFjaChub2RlID0+IHtcbiAgICAgICAgICBub2RlLmNvbXBDb25maWcudmlld0NvbmZpZyA9IG5vZGUuY29tcENvbmZpZy52aWV3Q29uZmlnLm1hcChjb25maWcgPT4gY29uZmlnLnZpZXdJZCk7XG4gICAgICAgICAgbm9kZS5jb21wQ29uZmlnLmR5bmFtaWNDb21wb25lbnRSZWZzID0gW107XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pXG4gICAgY29uc3Qgd2lkZ2V0RGF0YSA9IHRoaXMuZGFzaEJvYXJkV2lkZ2V0Q29uZmlnO1xuICAgIHdpZGdldERhdGFbJ3dpZGdldHMnXSA9IHRoaXMuZGFzaEJvYXJkV2lkZ2V0Q29uZmlnLndpZGdldHMubWFwKGl0ZW0gPT4gaXRlbS53aWRnZXRJZCk7XG4gICAgd2lkZ2V0RGF0YVsnZmlsdGVySWQnXSA9ICh3aWRnZXREYXRhLmZpbHRlcnMpID8gd2lkZ2V0RGF0YS5maWx0ZXJzLmZpbHRlcklkIDogbnVsbDtcbiAgICBkZWxldGUgd2lkZ2V0RGF0YVsnZmlsdGVycyddO1xuXG4gICAgdGhpcy5zZXJ2aWNlLmVkaXRBcHBQYWdlQ29uZmlnKHdpZGdldERhdGEpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAoZGF0YTogYW55KSA9PiB7XG4gICAgICAgIHRoaXMudG9hc3RyLnN1Y2Nlc3MoXCJMYXlvdXQgRGVsZXRlZCBTdWNjZXNzZnVsbHlcIilcbiAgICAgICAgdGhpcy5nZXRBcHBQYWdlRGV0YWlsQ29uZmlnQnlQYWdlSWQoKVxuICAgICAgfSwgZXJyb3I6IChlcnI6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLmxvYWRpbmdNb2RhbCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnRvYXN0ci5lcnJvcignVW5leHBlY3RlZCBTZXJ2ZXIgRXhjZXB0aW9uLiBQbGVhc2UgY29udGFjdCBTeXN0ZW0gQWRtaW4uJywgJ1dpZGdldCBDcmVhdGlvbicpXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG5cbiAgLy8gYWR2YW5jZSBMYXlvdXQgXG4gIGlzQWR2YW5jZUxheW91dDogYm9vbGVhbjtcbiAgaXNQcm9jZWVkOiBib29sZWFuO1xuICBzZWxlY3RlZFZpZXdzSWRzOiBhbnkgPSBbXTtcbiAgYWR2YW5jZUxheW91dENvbnRhaW5lcjogYW55ID0gW107XG4gIGdldFByb2Nlc3NGb3JDb25maWcoKSB7XG4gICAgdGhpcy5hZHZhbmNlTGF5b3V0Q29udGFpbmVyID0gW107XG4gICAgY29uc3QgZmlsdGVyZWRDb2x1bW5zID0gdGhpcy5jb21wb25lbnRDb25maWdEYXRhU291cmNlLmZpbHRlcihjb2x1bW4gPT4gdGhpcy5zZWxlY3RlZFZpZXdzSWRzLmluY2x1ZGVzKGNvbHVtbi52aWV3SWQpKTtcbiAgICBjb25zdCBjb2x1bW5EZWZMaXN0ID0gW107XG5cbiAgICBmaWx0ZXJlZENvbHVtbnMuZm9yRWFjaChlbGVtZW50ID0+IHtcbiAgICAgIC8vIGNvbnN0IGV4aXN0aW5nQ29sdW1uID0gZmFsc2U7XG4gICAgICBsZXQgb2JqID0ge1xuICAgICAgICBcImlkXCI6IHRoaXMuY29tbW9uU2VydmljZS5wcmltZXJ5UmVuZG9tZUlkKDUpLFxuICAgICAgICBcIm5vZGVUaXRsZVwiOiBcIlwiLFxuICAgICAgICBcImNvbXBDb25maWdcIjoge1xuICAgICAgICAgIFwiZHluYW1pY0NvbXBvbmVudFJlZnNcIjogW10sXG4gICAgICAgICAgXCJ2aWV3Q29uZmlnXCI6IFtlbGVtZW50XVxuICAgICAgICB9LFxuICAgICAgICBcImZpbHRlcklkXCI6IG51bGwsXG4gICAgICAgIFwibm9kZVByb3BlcnRpZXNcIjoge1xuICAgICAgICAgIFwiZGlzcGxheVwiOiB0cnVlLFxuICAgICAgICAgIFwid2lkZ2V0VGl0bGVcIjogXCJcIixcbiAgICAgICAgICBcIndpZHRoXCI6IFwiXCIsXG4gICAgICAgICAgXCJoZWlnaHRcIjogXCJcIixcbiAgICAgICAgICBcImlzV2lkZ2V0RmlsdGVyXCI6IGZhbHNlXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMuYWR2YW5jZUxheW91dENvbnRhaW5lci5wdXNoKG9iaik7XG5cbiAgICB9KTtcblxuICAgIHRoaXMuaXNQcm9jZWVkID0gdHJ1ZTtcbiAgfVxuXG4gIGdldFNlbGVjdGVkQ29sdW1uU291cmNlKGV2ZW50KSB7XG4gICAgaWYgKGV2ZW50LmV2ZW50KSB7XG4gICAgICB0aGlzLnNlbGVjdGVkVmlld3NJZHMgPSBldmVudC52YWx1ZTtcbiAgICB9XG4gIH1cblxuICBzdWJtaXRBZHZhbmNlVmlldygpIHtcbiAgICBpZiAodGhpcy5kYXNoQm9hcmRXaWRnZXRDb25maWcud2lkZ2V0c1t0aGlzLm5ld1dpZGdldEluZGV4XS53aWRnZXROb2RlICYmIHRoaXMuZGFzaEJvYXJkV2lkZ2V0Q29uZmlnLndpZGdldHNbdGhpcy5uZXdXaWRnZXRJbmRleF0ud2lkZ2V0Tm9kZS5sZW5ndGggIT09IDApIHtcbiAgICAgIHRoaXMuZGFzaEJvYXJkV2lkZ2V0Q29uZmlnLndpZGdldHNbdGhpcy5uZXdXaWRnZXRJbmRleF0ud2lkZ2V0Tm9kZSA9IFsuLi50aGlzLmRhc2hCb2FyZFdpZGdldENvbmZpZy53aWRnZXRzW3RoaXMubmV3V2lkZ2V0SW5kZXhdLndpZGdldE5vZGUsIC4uLnRoaXMuYWR2YW5jZUxheW91dENvbnRhaW5lcl07XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZGFzaEJvYXJkV2lkZ2V0Q29uZmlnLndpZGdldHNbdGhpcy5uZXdXaWRnZXRJbmRleF0ud2lkZ2V0Tm9kZSA9IHRoaXMuYWR2YW5jZUxheW91dENvbnRhaW5lcjtcbiAgICB9XG4gICAgdGhpcy5pc0FkdmFuY2VMYXlvdXQgPSBmYWxzZTtcbiAgICB0aGlzLmFkdmFuY2VMYXlvdXRDb250YWluZXIgPSBbXTtcbiAgICB0aGlzLmlzUHJvY2VlZCA9IGZhbHNlO1xuICAgIHRoaXMudXBkYXRlV2lkZ2V0KCk7XG4gIH1cblxuXG5cbiAgZGVsZXRlVmlldyhpKSB7XG5cbiAgfVxufVxuIiwiPGFwcC1sb2FkaW5nICpuZ0lmPVwibG9hZGluZ01vZGFsXCI+PC9hcHAtbG9hZGluZz5cblxuPCEtLSA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbCBmbGV4LWF1dG8gdy1mdWxsXCI+IC0tPlxuPGRpdiBjbGFzcz1cImZsZXggZmxleC1yb3cgaC1zY3JlZW5cIj5cbiAgICA8ZGl2IGNsYXNzPVwiZmxleC1ncm93IGJvcmRlci1yIGgtZnVsbFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2Nyb2xsYWJsZS1jb250ZW50XCI+XG4gICAgICAgICAgICA8IS0tIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtd3JhcCBwLTIgYm9yZGVyXCI+IC0tPlxuICAgICAgICAgICAgPCEtLSA8YXBwLWFkdmFuY2UtaGVhZGVyIFtmaWx0ZXJJdGVtc109XCJmaWx0ZXJJdGVtc1wiIFtwYWdlVGl0bGVdPVwiJ0Rhc2hib2FyZCdcIiBbaXNFZGl0QnV0dG9uXT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgW2lzQWR2YW5jZUJ1dHRvbl09XCJ0cnVlXCI+PC9hcHAtYWR2YW5jZS1oZWFkZXI+IC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC13cmFwIG15LTNcIiAjZHluYW1pY0NvbnRhaW5lcj48L2Rpdj5cblxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1yb3cganVzdGlmeS1jZW50ZXIgaXRlbXMtY2VudGVyIGgtMTYgbS0yIGJvcmRlclwiPlxuICAgICAgICAgICAgPGxpYi1jb21tb24taGVhZGVyIFtwYWdlVGl0bGVdPVwiJydcIj48L2xpYi1jb21tb24taGVhZGVyPlxuICAgICAgICAgICAgPCEtLSA8ZGl2IGNsYXNzPVwie3tjb21tb25TZXJ2aWNlLmJ0bl9zdWNjZXNzX21kfX0gbS0yIFwiIChjbGljayk9XCJnZXRDcmVhdGVEYXRhU2V0UGFnZSgpXCI+Q3JlYXRlXG4gICAgICAgICAgICAgICAgRGF0YXNldFxuICAgICAgICAgICAgPC9kaXY+IC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInt7Y29tbW9uU2VydmljZS5idG5fcHJpbWFyeV9tZH19IG0tMlwiIChjbGljayk9XCJhZGRXaWRnZXQoKVwiPkFkZCBMYXlvdXRcbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPCEtLSA8ZGl2IGNsYXNzPVwie3tjb21tb25TZXJ2aWNlLmJ0bl9zdWNjZXNzX21kfX0gbS0yXCIgKGNsaWNrKT1cImdldENyZWF0ZVZpZXdQYWdlKClcIj5DcmVhdGVcbiAgICAgICAgICAgICAgICBWaWV3XG4gICAgICAgICAgICA8L2Rpdj4gLS0+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwie3tjb21tb25TZXJ2aWNlLmJ0bk90aGVyc1B1cnBsZX19IG0tMiBjdXJzYXItcG9pbnRlclwiIChjbGljayk9XCJnZXRWaWV3UGFnZSgpXCI+VmlldyBQYWdlXG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwhLS0gPGRpdiBjbGFzcz1cInt7Y29tbW9uU2VydmljZS5idG5fd2FybmluZ19tZH19IG0tMiBjdXJzYXItcG9pbnRlclwiIChjbGljayk9XCJnZXRBbGxQYWdlKClcIj5BbGwgUGFnZXNcbiAgICAgICAgICAgIDwvZGl2PiAtLT5cblxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwiZmxleC1zaHJpbmstMCB3LTEvNCBwLTIgaC1mdWxsXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc0Rhc2hCb2FyZENvbnRlbnRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ7e2NvbW1vblNlcnZpY2UuYnRuRGFya0JsYWNrfX0gbS0yIHctZml0IHRleHQtY2VudGVyIGN1cnNhci1wb2ludGVyXCIgKGNsaWNrKT1cImJhY2tUb01haW5WaWV3KClcIj5cbiAgICAgICAgICAgICAgICBCYWNrXG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGl0ZW0gb2YgcGFnZV9jb25maWcuYXBpX2NvbmZpZzsgbGV0IGkgPSBpbmRleFwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0yIGZsZXggZmxleC1yb3cganVzdGlmeS1iZXR3ZWVuIGl0ZW1zLWNlbnRlciBib3JkZXItYlwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tZCBweS0yIGZvbnQtYm9sZCAgdGV4dC13aGl0ZSBweC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICB7e2l0ZW0ud2lkR2V0Q29uZmlnLndpZGdldFRpdGxlfX1cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IHNwYWNlLXgtMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSA8YnV0dG9uIChjbGljayk9XCJlZGl0U2VsZWN0ZWRXaWRnZXQoaXRlbSwgaSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwidy04IGgtOCBiZy1za3ktNjAwIGhvdmVyOmJnLWJsdWUtODAwIHRleHQtd2hpdGUgcm91bmRlZC1mdWxsIGZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJmYSBmYS1lZGl0XCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+IC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwidy04IGgtOCBiZy1yZWQtNjAwIGhvdmVyOmJnLXJlZC04MDAgdGV4dC13aGl0ZSByb3VuZGVkLWZ1bGwgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImZhIGZhLXRyYXNoLW9cIj48L2k+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzV2lkZ2V0Q3JlYXRpb25Db250ZW50XCI+XG4gICAgICAgICAgICA8aDYgY2xhc3M9XCJtYi0yIGZvbnQtYm9sZCB0ZXh0LWxnIHRyYWNraW5nLXRpZ2h0IHRleHQtZ3JheS05MDAgZGFyazp0ZXh0LXdoaXRlIGJvcmRlci1iIHBiLTNcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cIiFpc2xheW91dENyZWF0ZVwiPldpZGdldCBTZXR0aW5nczwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cImlzbGF5b3V0Q3JlYXRlXCI+TGF5b3V0IFNldHRpbmdzPC9zcGFuPlxuICAgICAgICAgICAgPC9oNj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtcm93IG15LTRcIj5cbiAgICAgICAgICAgICAgICA8ZHgtY2hlY2stYm94IGNsYXNzPVwibWwtYXV0b1wiIFsobmdNb2RlbCldPVwiYWRkZWR3aWRHZXRDb25maWcuZGlzcGxheVwiIHRleHQ9XCJEaXNwbGF5XCI+PC9keC1jaGVjay1ib3g+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtcm93IG1iLTIganVzdGlmeS1iZXR3ZWVuXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LW1kIG15LWF1dG8gcHgtMlwiPldpZHRoPC9zcGFuPlxuICAgICAgICAgICAgICAgIDxkeC1zZWxlY3QtYm94IGNsYXNzPVwidy0xLzJcIiBbaXRlbXNdPVwid2lkZ2V0X3dpZHRoXCJcbiAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJhZGRlZHdpZEdldENvbmZpZy53aWR0aFwiPjwvZHgtc2VsZWN0LWJveD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1yb3cgbWItMiBqdXN0aWZ5LWJldHdlZW5cIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtbWQgbXktYXV0byBweC0yXCI+SGVpZ2h0PC9zcGFuPlxuICAgICAgICAgICAgICAgIDxkeC10ZXh0LWJveCBjbGFzcz1cInctMS8yXCIgWyhuZ01vZGVsKV09XCJhZGRlZHdpZEdldENvbmZpZy5oZWlnaHRcIj48L2R4LXRleHQtYm94PlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtcm93IG1iLTIganVzdGlmeS1iZXR3ZWVuXCIgKm5nSWY9XCIhaXNsYXlvdXRDcmVhdGVcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtbWQgbXktYXV0byBweC0yXCI+V2lkZ2V0IFRpdGxlPC9zcGFuPlxuICAgICAgICAgICAgICAgIDxkeC10ZXh0LWJveCBjbGFzcz1cInctMS8yXCIgWyhuZ01vZGVsKV09XCJ3aWRnZXRUaXRsZVwiPjwvZHgtdGV4dC1ib3g+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtcm93IG1iLTIganVzdGlmeS1iZXR3ZWVuXCIgKm5nSWY9XCIhaXNsYXlvdXRDcmVhdGVcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtbWQgbXktYXV0byBweC0yXCI+V2lkZ2V0IE5hbWU8L3NwYW4+XG4gICAgICAgICAgICAgICAgPGR4LXRleHQtYm94IGNsYXNzPVwidy0xLzJcIiBbKG5nTW9kZWwpXT1cIndpZGdldE5hbWVcIj48L2R4LXRleHQtYm94PlxuICAgICAgICAgICAgPC9kaXY+XG5cblxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1yb3cgbWItNSBqdXN0aWZ5LWJldHdlZW5cIiAqbmdJZj1cImlzbGF5b3V0Q3JlYXRlXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXNtIG15LWF1dG8gcHgtMlwiPkxheW91dCBUaXRsZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8ZHgtdGV4dC1ib3ggY2xhc3M9XCJ3LTEvMlwiIFsobmdNb2RlbCldPVwiYWRkZWR3aWRHZXRDb25maWcud2lkZ2V0VGl0bGVcIj48L2R4LXRleHQtYm94PlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtcm93IG1iLTIganVzdGlmeS1iZXR3ZWVuXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LW1kIG15LWF1dG8gcHgtMlwiPkZpbHRlcjwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8ZHgtc2VsZWN0LWJveCBjbGFzcz1cInctMS8yXCIgW2l0ZW1zXT1cImZpbHRlckRhdGFTb3VyY2VcIiBkaXNwbGF5RXhwcj1cImZpbHRlck5hbWVcIiBbc2VhcmNoRW5hYmxlZF09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVFeHByPVwiZmlsdGVySWRcIiBbKG5nTW9kZWwpXT1cInNlbGVjdGVkRmlsdGVySWRcIlxuICAgICAgICAgICAgICAgICAgICAob25WYWx1ZUNoYW5nZWQpPVwiZ2V0RmlsdGVyVmFsdWVCeUlkKCRldmVudClcIj48L2R4LXNlbGVjdC1ib3g+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhaXNVcGRhdGVXaWRnZXRcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXQtNlwiICpuZ0lmPVwiIWlzbGF5b3V0Q3JlYXRlICYmIGlzRWRpdE1haW5MYXlvdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IGl0ZW0gb2YgZGFzaEJvYXJkV2lkZ2V0Q29uZmlnLndpZGdldHNbbmV3V2lkZ2V0SW5kZXhdLndpZGdldE5vZGU7bGV0IGkgPSBpbmRleFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTIgZmxleCBmbGV4LXJvdyBqdXN0aWZ5LWJldHdlZW4gaXRlbXMtY2VudGVyIGJvcmRlci1iIFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW1kIHB5LTIgZm9udC1ib2xkICB0ZXh0LXdoaXRlIHB4LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tpdGVtLm5vZGVQcm9wZXJ0aWVzLndpZGdldFRpdGxlfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBzcGFjZS14LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiAqbmdJZj1cImkgIT09IDBcIiBjbGFzcz1cInt7Y29tbW9uU2VydmljZS5idG5fbGlnaHRfc219fSBjdXJzb3ItcG9pbnRlciBteC0xXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJtb3ZlSXRlbUZvclBhZ2VWaWV3KGksICd1cCcpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImZhIGZhLWFycm93LXVwXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImkgIT09ICBkYXNoQm9hcmRXaWRnZXRDb25maWcud2lkZ2V0c1tuZXdXaWRnZXRJbmRleF0ud2lkZ2V0Tm9kZS5sZW5ndGggLSAxXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwie3tjb21tb25TZXJ2aWNlLmJ0bl9saWdodF9zbX19IGN1cnNvci1wb2ludGVyIG14LTFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm1vdmVJdGVtRm9yUGFnZVZpZXcoaSwgJ2Rvd24nKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJmYSBmYS1hcnJvdy1kb3duXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ3LTggaC04IGJnLXJlZC02MDAgaG92ZXI6YmctcmVkLTgwMCB0ZXh0LXdoaXRlIHJvdW5kZWQtZnVsbCBmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJmYSBmYS10cmFzaC1vXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cblxuXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNVcGRhdGVXaWRnZXRcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1zbSBweS0xIGZvbnQtZXh0cmFib2xkIGJvcmRlci1iIGJnLWdyYXktNzAwIHRleHQtd2hpdGUgcHgtMlwiPiBBcHBsaWNhdGlvbiBWaWV3c1xuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJib3JkZXIteCBib3JkZXItYiBwLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgaXRlbSBvZiBhbGxXaWRnZXRJbm5lckNvbnRlbnQ7IGxldCBpID0gaW5kZXhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJncm91cCAgdy1mdWxsIGZsZXgganVzdGlmeS1iZXR3ZWVuIGJvcmRlci1iIGl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW1kIGZvbnQtYm9sZCAgcHktMiBjdXJzb3ItcG9pbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2l0ZW0udmlld05hbWV9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggc3BhY2UteC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gKm5nSWY9XCJpICE9PSAwXCIgY2xhc3M9XCJ7e2NvbW1vblNlcnZpY2UuYnRuX2xpZ2h0X3NtfX0gY3Vyc29yLXBvaW50ZXIgbXgtMVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwibW92ZUl0ZW1Gb3JDb2x1bW5zKGksICd1cCcpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImZhIGZhLWFycm93LXVwXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uICpuZ0lmPVwiaSAhPT0gYWxsV2lkZ2V0SW5uZXJDb250ZW50Lmxlbmd0aCAtIDFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ7e2NvbW1vblNlcnZpY2UuYnRuX2xpZ2h0X3NtfX0gY3Vyc29yLXBvaW50ZXIgbXgtMVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwibW92ZUl0ZW1Gb3JDb2x1bW5zKGksICdkb3duJylcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiZmEgZmEtYXJyb3ctZG93blwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJyb3VuZGVkLWZ1bGwgcC0yIHRleHQtd2hpdGUgYmctYmx1ZS01MDAgaG92ZXI6YmctYmx1ZS03MDAgbWItMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiZWRpdENvbXBvbmVudFZpZXdzKGl0ZW0pXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImZhIGZhLWV5ZVwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJyb3VuZGVkLWZ1bGwgcC0yIHRleHQtd2hpdGUgYmctYmx1ZS01MDAgaG92ZXI6YmctYmx1ZS03MDAgbWItMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiZWRpdENvbXBvbmVudERhdGFzZXRzKGl0ZW0pXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImZhIGZhLWRhdGFiYXNlXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInJvdW5kZWQtZnVsbCBwLTIgdGV4dC13aGl0ZSBiZy1yZWQtNTAwIGhvdmVyOmJnLXJlZC03MDAgbWItMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiZ2V0RGVsZXRlVmlld0Zyb21Db25maWcoaSlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiZmEgZmEtdHJhc2gtb1wiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzVXBkYXRlV2lkZ2V0XCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtc20gcHktMSBmb250LWV4dHJhYm9sZCBib3JkZXItYiBiZy1ncmF5LTcwMCB0ZXh0LXdoaXRlIHB4LTJcIj4gQWRkIEZpbHRlciBGb3IgVmlld1xuXG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJvcmRlci14IGJvcmRlci1iIHAtMlwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXJvdyBweS0zIGJvcmRlci1iXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZHgtY2hlY2stYm94IFsobmdNb2RlbCldPVwiYWRkZWR3aWRHZXRDb25maWcuaXNXaWRnZXRGaWx0ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQ9XCJQb3B1cCBDb2x1bW5zIEZpbHRlciBFbmFibGVcIj48L2R4LWNoZWNrLWJveD5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtcm93IG15LTIgYm9yZGVyLWJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGl0ZW0gb2Ygbm9kZVByb3BlcnRpY2VGaWx0ZXJzOyBsZXQgaSA9IGluZGV4XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC13cmFwIGJvcmRlci1iXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC0xIHctMS8zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tZFwiPklucHV0IFR5cGU8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkeC1zZWxlY3QtYm94IFtpdGVtc109XCJbJ3RleHQnXVwiIFsobmdNb2RlbCldPVwiaXRlbS5pbnB1dF90eXBlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT1cInRleHRcIj48L2R4LXNlbGVjdC1ib3g+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtMS0xIHctMi8zXCIgKm5nSWY9XCJpdGVtLmlucHV0X3R5cGUgPT0gJ3RleHQnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tZFwiPlNlcnZlciBDb2x1bW48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkeC10ZXh0LWJveCBbKG5nTW9kZWwpXT1cIml0ZW0uc2VydmVyX2NvbHVtblwiPjwvZHgtdGV4dC1ib3g+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtMS0xIHctMS8yXCIgKm5nSWY9XCJpdGVtLmlucHV0X3R5cGUgPT0gJ3RleHQnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tZFwiPkxvY2FsIENvbHVtbjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGR4LXRleHQtYm94IFsobmdNb2RlbCldPVwiaXRlbS5sb2NhbF9jb2x1bW5cIj48L2R4LXRleHQtYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB4LTEtMSB3LTEvM1wiICpuZ0lmPVwiaXRlbS5pbnB1dF90eXBlID09ICdzZWxlY3QnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tZFwiPkNvbHVtbnMgTmFtZTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGR4LXRleHQtYm94IFsobmdNb2RlbCldPVwiaXRlbS5zZWxlY3RfYm94X29wdGlvblwiPjwvZHgtdGV4dC1ib3g+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtMS0xIHctMS8yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBqdXN0aWZ5LWVuZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ7e2NvbW1vblNlcnZpY2UuYnRuX2Rhbmdlcl9zbX19IHctMjQgbXQtNiB0ZXh0LWNlbnRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJkZWxldGVOb2RlRmlsdGVyKGkpXCI+RGVsZXRlIEZpbHRlcjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwie3tjb21tb25TZXJ2aWNlLmJ0bl9wcmltYXJ5X3NtfX0gdy1hdXRvIHRleHQtY2VudGVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJnZXROb2RlUHJvcGVydGljZUZpbHRlck9wdGlvbigpXCI+QWRkXG4gICAgICAgICAgICAgICAgICAgICAgICBGaWx0ZXI8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXJvdyBqdXN0aWZ5LWVuZCBpdGVtcy1jZW50ZXIgaC0xNiBtLTJcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwie3tjb21tb25TZXJ2aWNlLmJ0bkRhcmtCbGFja319IG0tMiB3LWZpdCB0ZXh0LWNlbnRlciBjdXJzYXItcG9pbnRlclwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJiYWNrVG9NYWluVmlldygpXCI+QmFja1xuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhaXNVcGRhdGVXaWRnZXRcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImlzbGF5b3V0Q3JlYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwie3tjb21tb25TZXJ2aWNlLmJ0bl9zdWNjZXNzX21kfX0gbS0yIHctZml0IHRleHQtY2VudGVyIGN1cnNhci1wb2ludGVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJhZGRMYXlvdXRUT3ZpZXcoKVwiPkFkZCBWaWV3XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiIWlzbGF5b3V0Q3JlYXRlICYmICFpc0VkaXRNYWluTGF5b3V0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwie3tjb21tb25TZXJ2aWNlLmJ0bl9wcmltYXJ5X21kfX0gbS0yIHctZml0IHRleHQtY2VudGVyIGN1cnNhci1wb2ludGVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJhZGRXaWRnZXRUT3ZpZXcoKVwiPkFkZCBMYXlvdXRcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCIhaXNsYXlvdXRDcmVhdGUgJiYgaXNFZGl0TWFpbkxheW91dFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInt7Y29tbW9uU2VydmljZS5idG5fcHJpbWFyeV9tZH19IG0tMiB3LWZpdCB0ZXh0LWNlbnRlciBjdXJzYXItcG9pbnRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwidXBkYXRlTGF5b3V0V2lkZ2V0VE92aWV3KClcIj5VcGRhdGUgTGF5b3V0XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwie3tjb21tb25TZXJ2aWNlLmJ0bl93YXJuaW5nX21kfX0gbS0yIHctZml0IHRleHQtY2VudGVyIGN1cnNhci1wb2ludGVyXCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInVwZGF0ZVRvVmlldygpXCIgKm5nSWY9XCJpc1VwZGF0ZVdpZGdldFwiPlVwZGF0ZSBWaWV3XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDwvZGl2PlxuXG5cbiAgICAgICAgICAgIDwhLS0gPHByZT48Y29kZT57e2Rhc2hCb2FyZFdpZGdldENvbmZpZyB8IGpzb259fTwvY29kZT48L3ByZT4gLS0+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNDaGFydEJ1dHRvbkNsaWNrXCI+XG4gICAgICAgICAgICA8aDZcbiAgICAgICAgICAgICAgICBjbGFzcz1cIm1iLTIgZm9udC1ib2xkIHRleHQtbWQgdHJhY2tpbmctdGlnaHQgdGV4dC1ncmF5LTkwMCBkYXJrOnRleHQtd2hpdGUgYm9yZGVyLWIgcGItMyBmbGV4ICBpdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImZhIGZhLWJhci1jaGFydC1vIG1yLTJcIj48L2k+IFNlbGVjdCBWaWV3XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInt7Y29tbW9uU2VydmljZS5idG5EYXJrQmxhY2t9fSBtLTIgdy1maXQgdGV4dC1jZW50ZXIgY3Vyc29yLXBvaW50ZXJcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYmFja1RvTWFpblZpZXcoKVwiPkJhY2tcbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvaDY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiIGgtWzgwdmhdIG92ZXJmbG93LXgtYXV0b1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZWxhdGl2ZSBteS0yIFwiPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBbKG5nTW9kZWwpXT1cInZpZXdUb1NlYXJjaFwiIChrZXl1cCk9XCJmaWx0ZXJWaWV3cygpXCIgKGtleWRvd24pPVwiZmlsdGVyVmlld3MoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImJnLWdyYXktODAwIGJvcmRlciBib3JkZXItZ3JheS03MDAgdGV4dC1ncmF5LTIwMCB0ZXh0LXNtIGZvY3VzOnJpbmctZ3JheS00MDAgZm9jdXM6Ym9yZGVyLWdyYXktNTAwIGJsb2NrIHctZnVsbCBwLTQgaC04IHJvdW5kZWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJTZWFyY2ggVmlld1wiIC8+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYWJzb2x1dGUgaW5zZXQteS0wIHJpZ2h0LTAgZmxleCBpdGVtcy1jZW50ZXIgcHItNlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwicm90YXRlLTkwIGN1cnNvci1wb2ludGVyXCIgW3N2Z0ljb25dPVwiJ2hlcm9pY29uc19vdXRsaW5lOnNlYXJjaCdcIj48L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIGZpbHRlcmVkQ29tcG9uZW50Q29uZmlnXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZWxhdGl2ZSBncm91cCBteS0zIHctZnVsbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBJdGVtIFZpZXcgTmFtZSAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW1kIGZvbnQtYm9sZCBib3JkZXItYiBweS0yIGN1cnNhci1wb2ludGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3tpdGVtLnZpZXdOYW1lfX08L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBIb3ZlciBCdXR0b25zIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYWJzb2x1dGUgdG9wLTAgIHJpZ2h0LTAgZmxleCBzcGFjZS14LTIgb3BhY2l0eS0wIGdyb3VwLWhvdmVyOm9wYWNpdHktMTAwIHRyYW5zaXRpb24tb3BhY2l0eSBkdXJhdGlvbi0zMDAgcGItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJyb3VuZGVkLWZ1bGwgcC0yIHRleHQtd2hpdGUgYmctYmx1ZS01MDAgaG92ZXI6YmctYmx1ZS03MDBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJmYSBmYS1wZW5jaWwtc3F1YXJlLW9cIiBhcmlhLWhpZGRlbj1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImVkaXRDb21wb25lbnRWaWV3cyhpdGVtKVwiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwicm91bmRlZC1mdWxsIHAtMiB0ZXh0LXdoaXRlIGJnLWdyZWVuLTUwMCBob3ZlcjpiZy1ncmVlbi03MDBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiZ2V0Q29tcG9uZW50Q29uZmlnKGl0ZW0pXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiZmEgZmEtcGx1c1wiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNEZWZhdWx0Vmlld1wiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgaXRlbSBvZiBkYXNoQm9hcmRXaWRnZXRDb25maWcud2lkZ2V0czsgbGV0IGkgPSBpbmRleFwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJncm91cCBteS0zIHctZnVsbCBmbGV4IGp1c3RpZnktYmV0d2VlbiBib3JkZXItYiBpdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbWQgZm9udC1ib2xkICBweS0yIGN1cnNvci1wb2ludGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICB7e2l0ZW0ud2lkZ2V0VGl0bGV9fVxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBzcGFjZS14LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gKm5nSWY9XCJpICE9PSAwXCIgY2xhc3M9XCJ7e2NvbW1vblNlcnZpY2UuYnRuX2xpZ2h0X3NtfX0gY3Vyc29yLXBvaW50ZXIgbXgtMVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm1vdmVJdGVtRm9yV2lkZ2V0KGksICd1cCcpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJmYSBmYS1hcnJvdy11cFwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uICpuZ0lmPVwiaSAhPT0gZGFzaEJvYXJkV2lkZ2V0Q29uZmlnLndpZGdldHMubGVuZ3RoIC0gMVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ7e2NvbW1vblNlcnZpY2UuYnRuX2xpZ2h0X3NtfX0gY3Vyc29yLXBvaW50ZXIgbXgtMVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm1vdmVJdGVtRm9yV2lkZ2V0KGksICdkb3duJylcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImZhIGZhLWFycm93LWRvd25cIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L2k+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJyb3VuZGVkLWZ1bGwgcC0yIHRleHQtd2hpdGUgYmctYmx1ZS01MDAgaG92ZXI6YmctYmx1ZS03MDAgbWItMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImdldEVkaXRWaWV3RnJvbUxheW91dChpdGVtLGkpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJmYSBmYS1wZW5jaWwtc3F1YXJlXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJyb3VuZGVkLWZ1bGwgcC0yIHRleHQtd2hpdGUgYmctcmVkLTUwMCBob3ZlcjpiZy1yZWQtNzAwIG1iLTJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJnZXREZWxldGVWaWV3RnJvbUxheW91dChpdGVtLGkpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJmYSBmYS10cmFzaC1vXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cblxuICAgIDwvZGl2PlxuPC9kaXY+XG48IS0tIDwvZGl2PiAtLT5cblxuPGR4LXBvcHVwIFsodmlzaWJsZSldPVwiaXNFZGl0T3B0aW9uQ2xpY2tcIiBbY2xvc2VPbk91dHNpZGVDbGlja109XCJmYWxzZVwiIFtkcmFnRW5hYmxlZF09XCJmYWxzZVwiIFt3aWR0aF09XCIxMjAwXCJcbiAgICBbaGVpZ2h0XT1cIidhdXRvJ1wiIFtzaG93VGl0bGVdPVwidHJ1ZVwiIGNsYXNzPVwicG9wdXBcIiB0aXRsZT1cInt7ZWRpdFZpZXdkYXRhU291cmNlTW9kYWwudmlld05hbWV9fVwiPlxuICAgIDxkaXYgKmR4VGVtcGxhdGU9XCJsZXQgZGF0YSBvZiAnY29udGVudCdcIj5cblxuICAgICAgICA8YXBwLWRhc2gtY2hhcnQgW2RhdGFzZXRtb2RhbF09XCJlZGl0Vmlld2RhdGFTb3VyY2VNb2RhbFwiIChnZXRDaGFydENvbmZpZ091dFB1dCk9XCJnZXRFbWl0TmV3Q2hhcnRDb25naWcoJGV2ZW50KVwiXG4gICAgICAgICAgICAqbmdJZj1cImVkaXRWaWV3ZGF0YVNvdXJjZU1vZGFsLnZpZXdUeXBlID09ICdjaGFydCdcIj48L2FwcC1kYXNoLWNoYXJ0PlxuICAgICAgICA8YXBwLWRhc2gtdGFibGUgW2RhdGFzZXRtb2RhbF09XCJlZGl0Vmlld2RhdGFTb3VyY2VNb2RhbFwiIChnZXRUYWJsZUNvbmZpZ091dFB1dCk9XCJnZXRFbWl0TmV3Q2hhcnRDb25naWcoJGV2ZW50KVwiXG4gICAgICAgICAgICAqbmdJZj1cImVkaXRWaWV3ZGF0YVNvdXJjZU1vZGFsLnZpZXdUeXBlID09ICd0YWJsZSdcIj48L2FwcC1kYXNoLXRhYmxlPlxuICAgICAgICA8IS0tIDxhcHAtZGFzaC1vdGhlciBbZGF0YXNldG1vZGFsXT1cImVkaXRWaWV3ZGF0YVNvdXJjZU1vZGFsXCIgKm5nSWY9XCJlZGl0Vmlld2RhdGFTb3VyY2VNb2RhbC52aWV3VHlwZSA9PSAnb3RoZXJzJ1wiXG4gICAgICAgICAgICAoY3JlYXRlT3RoZXJDb21wb25lbnRWaWV3KT1cImdldEVtaXROZXdDaGFydENvbmdpZygkZXZlbnQpXCI+PC9hcHAtZGFzaC1vdGhlcj4gLS0+XG4gICAgPC9kaXY+XG48L2R4LXBvcHVwPlxuXG5cbjxkeC1wb3B1cCBbKHZpc2libGUpXT1cImlzQ3JlYXRlRGF0YXNldFwiIFtjbG9zZU9uT3V0c2lkZUNsaWNrXT1cImZhbHNlXCIgW2RyYWdFbmFibGVkXT1cImZhbHNlXCIgW3dpZHRoXT1cIjEyMDBcIlxuICAgIFtoZWlnaHRdPVwiNjAwXCIgW3Nob3dUaXRsZV09XCJ0cnVlXCIgY2xhc3M9XCJwb3B1cFwiIHRpdGxlPVwiRGF0YXNldCBFZGl0b3JcIj5cbiAgICA8ZGl2ICpkeFRlbXBsYXRlPVwibGV0IGRhdGEgb2YgJ2NvbnRlbnQnXCI+XG4gICAgICAgIDxkeC1zY3JvbGwtdmlldyBjbGFzcz1cImgtZnVsbFwiIFt3aWR0aF09XCInMTAwJSdcIiBbaGVpZ2h0XT1cIicxMDAlJ1wiPlxuICAgICAgICAgICAgPGFwcC1jcmVhdGUtZGF0YXNldCBbaXNIZWFkZXJdPVwiZmFsc2VcIj48L2FwcC1jcmVhdGUtZGF0YXNldD5cbiAgICAgICAgPC9keC1zY3JvbGwtdmlldz5cbiAgICA8L2Rpdj5cbjwvZHgtcG9wdXA+XG48ZHgtcG9wdXAgWyh2aXNpYmxlKV09XCJpc0NyZWF0ZURhdGFzZXRXaXRoRGF0YXNldElkXCIgW2Nsb3NlT25PdXRzaWRlQ2xpY2tdPVwiZmFsc2VcIiBbZHJhZ0VuYWJsZWRdPVwiZmFsc2VcIiBbd2lkdGhdPVwiMTIwMFwiXG4gICAgW2hlaWdodF09XCI2MDBcIiBbc2hvd1RpdGxlXT1cInRydWVcIiBjbGFzcz1cInBvcHVwXCIgdGl0bGU9XCJEYXRhc2V0IEVkaXRvclwiIChvbkhpZGRlbik9XCJnZXREYXRhc2V0UG9wdXBIaWRlKCRldmVudClcIj5cbiAgICA8ZGl2ICpkeFRlbXBsYXRlPVwibGV0IGRhdGEgb2YgJ2NvbnRlbnQnXCI+XG4gICAgICAgIDxkeC1zY3JvbGwtdmlldyBjbGFzcz1cImgtZnVsbFwiIFt3aWR0aF09XCInMTAwJSdcIiBbaGVpZ2h0XT1cIicxMDAlJ1wiPlxuICAgICAgICAgICAgPGFwcC1jcmVhdGUtZGF0YXNldCBbc2VsZWN0ZWREYXRhc2V0SWRdPVwic2VsZWN0ZWREYXRhc2V0SWRcIiBbaXNIZWFkZXJdPVwiZmFsc2VcIj48L2FwcC1jcmVhdGUtZGF0YXNldD5cbiAgICAgICAgPC9keC1zY3JvbGwtdmlldz5cbiAgICA8L2Rpdj5cbjwvZHgtcG9wdXA+XG5cbjxkeC1wb3B1cCBbKHZpc2libGUpXT1cImlzQ3JlYXRlTmV3Vmlld1dpdGhEZWZhdWx0Vmlld1wiIFtjbG9zZU9uT3V0c2lkZUNsaWNrXT1cImZhbHNlXCIgW2RyYWdFbmFibGVkXT1cImZhbHNlXCJcbiAgICBbd2lkdGhdPVwiMTIwMFwiIFtoZWlnaHRdPVwiNjAwXCIgW3Nob3dUaXRsZV09XCJ0cnVlXCIgY2xhc3M9XCJwb3B1cFwiIHRpdGxlPVwiVmlld3MgRWRpdG9yXCJcbiAgICAob25IaWRkZW4pPVwiZ2V0Vmlld1BvcHVwSGlkZSgkZXZlbnQpXCI+XG4gICAgPGRpdiAqZHhUZW1wbGF0ZT1cImxldCBkYXRhIG9mICdjb250ZW50J1wiPlxuICAgICAgICA8ZHgtc2Nyb2xsLXZpZXcgY2xhc3M9XCJoLWZ1bGxcIiBbd2lkdGhdPVwiJzEwMCUnXCIgW2hlaWdodF09XCInMTAwJSdcIj5cbiAgICAgICAgICAgIDxhcHAtY3JlYXRlLWNvbXAtdmlldyBbc2VsZWN0ZWRWaWV3SWRdPVwic2VsZWN0ZWRWaWV3SWRcIiBbaXNIZWFkZXJdPVwiZmFsc2VcIj48L2FwcC1jcmVhdGUtY29tcC12aWV3PlxuICAgICAgICA8L2R4LXNjcm9sbC12aWV3PlxuICAgIDwvZGl2PlxuPC9keC1wb3B1cD5cbjxkeC1wb3B1cCBbKHZpc2libGUpXT1cImlzQ3JlYXRlTmV3Vmlld1wiIFtjbG9zZU9uT3V0c2lkZUNsaWNrXT1cImZhbHNlXCIgW2RyYWdFbmFibGVkXT1cImZhbHNlXCIgW3dpZHRoXT1cIjEyMDBcIlxuICAgIFtoZWlnaHRdPVwiNjAwXCIgW3Nob3dUaXRsZV09XCJ0cnVlXCIgY2xhc3M9XCJwb3B1cFwiIHRpdGxlPVwiVmlld3MgRWRpdG9yXCI+XG4gICAgPGRpdiAqZHhUZW1wbGF0ZT1cImxldCBkYXRhIG9mICdjb250ZW50J1wiPlxuICAgICAgICA8ZHgtc2Nyb2xsLXZpZXcgY2xhc3M9XCJoLWZ1bGxcIiBbd2lkdGhdPVwiJzEwMCUnXCIgW2hlaWdodF09XCInMTAwJSdcIj5cbiAgICAgICAgICAgIDxhcHAtY3JlYXRlLWNvbXAtdmlldyBbaXNIZWFkZXJdPVwiZmFsc2VcIj48L2FwcC1jcmVhdGUtY29tcC12aWV3PlxuICAgICAgICA8L2R4LXNjcm9sbC12aWV3PlxuICAgIDwvZGl2PlxuPC9keC1wb3B1cD5cblxuXG48ZHgtcG9wdXAgWyh2aXNpYmxlKV09XCJpc1dpZGdldEZpbHRlcnNcIiBbY2xvc2VPbk91dHNpZGVDbGlja109XCJmYWxzZVwiIFtkcmFnRW5hYmxlZF09XCJmYWxzZVwiIFt3aWR0aF09XCI4MDBcIiBbaGVpZ2h0XT1cIjQwMFwiXG4gICAgW3Nob3dUaXRsZV09XCJ0cnVlXCIgY2xhc3M9XCJwb3B1cFwiIHRpdGxlPVwiRGF0YXNldCBGaWx0ZXJcIj5cbiAgICA8ZGl2ICpkeFRlbXBsYXRlPVwibGV0IGRhdGEgb2YgJ2NvbnRlbnQnXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJteS0yXCI+XG4gICAgICAgICAgICA8ZHgtc2Nyb2xsLXZpZXcgW3dpZHRoXT1cIicxMDAlJ1wiIFtoZWlnaHRdPVwiJzg1JSdcIj5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIG5vZGVwcm9wZXJ0aWNlRmlsdGVyRGF0YVNvdXJjZTsgbGV0IGkgPSBpbmRleFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXJvdyBteS0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibS0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGR4LXRleHQtYm94IFsobmdNb2RlbCldPVwiaXRlbS5jb2x1bW5OYW1lXCI+PC9keC10ZXh0LWJveD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm0tMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkeC1zZWxlY3QtYm94IFtpdGVtc109XCJbJ2dldCcsJ2xldCddXCIgWyhuZ01vZGVsKV09XCJpdGVtLm9wZXJhdG9yXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJPcGVyYXRvclwiPjwvZHgtc2VsZWN0LWJveD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm0tMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkeC10ZXh0LWJveCBbKG5nTW9kZWwpXT1cIml0ZW0udmFsdWVcIj48L2R4LXRleHQtYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICA8L2R4LXNjcm9sbC12aWV3PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXgganVzdGlmeS1lbmQgbXgtMSBmbGV4LWdyb3dcIj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwie3tjb21tb25TZXJ2aWNlLmJ0bl9zdWNjZXNzX21kfX0gY3Vyc29yLXBvaW50ZXIgbXQtMlwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJzdWJtaXRGaWx0ZXIoKVwiPlN1Ym1pdDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPC9kaXY+XG5cbiAgICA8L2Rpdj5cbjwvZHgtcG9wdXA+XG48ZHgtcG9wdXAgWyh2aXNpYmxlKV09XCJpc0FkdmFuY2VMYXlvdXRcIiBbY2xvc2VPbk91dHNpZGVDbGlja109XCJmYWxzZVwiIFtkcmFnRW5hYmxlZF09XCJmYWxzZVwiIFt3aWR0aF09XCIxMjAwXCJcbiAgICBbaGVpZ2h0XT1cIjcwMFwiIFtzaG93VGl0bGVdPVwidHJ1ZVwiIGNsYXNzPVwicG9wdXBcIiB0aXRsZT1cIkRhdGFzZXQgRmlsdGVyXCI+XG4gICAgPGRpdiAqZHhUZW1wbGF0ZT1cImxldCBkYXRhIG9mICdjb250ZW50J1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXJvdyBweC0yIG1iLTNcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ3LTIvMyBtYi0yXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbWQgbWItMlwiPlNlbGVjdCBWaWV3czwvZGl2PlxuICAgICAgICAgICAgICAgIDxkeC10YWctYm94IFtkYXRhU291cmNlXT1cImNvbXBvbmVudENvbmZpZ0RhdGFTb3VyY2VcIiB2YWx1ZUV4cHI9XCJ2aWV3SWRcIiBkaXNwbGF5RXhwcj1cInZpZXdOYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgW211bHRpbGluZV09XCJ0cnVlXCIgW3Nob3dTZWxlY3Rpb25Db250cm9sc109XCJ0cnVlXCIgWyhuZ01vZGVsKV09XCJzZWxlY3RlZFZpZXdzSWRzXCJcbiAgICAgICAgICAgICAgICAgICAgW21heERpc3BsYXllZFRhZ3NdPVwiM1wiIChvblZhbHVlQ2hhbmdlZCk9XCJnZXRTZWxlY3RlZENvbHVtblNvdXJjZSgkZXZlbnQpXCIgW3NlYXJjaEVuYWJsZWRdPVwidHJ1ZVwiPlxuICAgICAgICAgICAgICAgIDwvZHgtdGFnLWJveD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctMS8zIHB4LTJcIj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwie3tjb21tb25TZXJ2aWNlLmJ0bl9wcmltYXJ5X21kfX0gbXQtNlwiIChjbGljayk9XCJnZXRQcm9jZXNzRm9yQ29uZmlnKClcIj5cbiAgICAgICAgICAgICAgICAgICAgQWRkIFRvIFZpZXdcbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8IS0tIDxidXR0b24gY2xhc3M9XCJ7e2NvbW1vblNlcnZpY2UuYnRuX2Rhbmdlcl9tZH19IGN1cnNvci1wb2ludGVyIG10LTZcIiAoY2xpY2spPVwiY2FuY2VsQ2RyQ29uZmlnKClcIj5DYW5jZWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPiAtLT5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGR4LXNjcm9sbC12aWV3IFt3aWR0aF09XCInMTAwJSdcIiBbaGVpZ2h0XT1cIic4MCUnXCI+XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtLTIgYm9yZGVyLWJcIiAqbmdJZj1cImlzUHJvY2VlZFwiPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGl0ZW0gb2YgYWR2YW5jZUxheW91dENvbnRhaW5lcjsgbGV0IGkgPSBpbmRleDtcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1yb3cgbS0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXgtMiB3LTEvMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW1kIG1iLTJcIj5WaWV3IE5hbWU8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZHgtdGV4dC1ib3ggWyhuZ01vZGVsKV09XCJpdGVtLmNvbXBDb25maWcudmlld0NvbmZpZ1swXS52aWV3TmFtZVwiPjwvZHgtdGV4dC1ib3g+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJteC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbWQgbWItMlwiPldpZGdldCBUaXRsZTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkeC10ZXh0LWJveCBbKG5nTW9kZWwpXT1cIml0ZW0ubm9kZVByb3BlcnRpZXMud2lkZ2V0VGl0bGVcIj48L2R4LXRleHQtYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJteC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbWQgbWItMlwiPldpZGdldCBXaWR0aDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkeC1zZWxlY3QtYm94IFtzZWFyY2hFbmFibGVkXT1cInRydWVcIiBbaXRlbXNdPVwid2lkZ2V0X3dpZHRoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJpdGVtLm5vZGVQcm9wZXJ0aWVzLndpZHRoXCI+PC9keC1zZWxlY3QtYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJteC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbWQgbWItMlwiPldpZGdldCBIZWlnaHQ8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZHgtdGV4dC1ib3ggWyhuZ01vZGVsKV09XCJpdGVtLm5vZGVQcm9wZXJ0aWVzLmhlaWdodFwiPjwvZHgtdGV4dC1ib3g+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJteC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbWQgbWItMlwiPldpZGdldCBGaWx0ZXI8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZHgtc2VsZWN0LWJveCBbaXRlbXNdPVwiZmlsdGVyRGF0YVNvdXJjZVwiIGRpc3BsYXlFeHByPVwiZmlsdGVyTmFtZVwiIFtzZWFyY2hFbmFibGVkXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZUV4cHI9XCJmaWx0ZXJJZFwiIFsobmdNb2RlbCldPVwiaXRlbS5maWx0ZXJJZFwiPjwvZHgtc2VsZWN0LWJveD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm14LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tZCBtdC04XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkeC1jaGVjay1ib3ggWyhuZ01vZGVsKV09XCJpdGVtLm5vZGVQcm9wZXJ0aWVzLmRpc3BsYXlcIiB0ZXh0PVwiRGlzcGxheVwiPjwvZHgtY2hlY2stYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXgtMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJ7e2NvbW1vblNlcnZpY2UuYnRuX2Rhbmdlcl9zbX19IGN1cnNvci1wb2ludGVyIG10LThcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiZGVsZXRlVmlldyhpKVwiPjxpIGNsYXNzPVwiZmEgZmEtdHJhc2gtb1wiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2R4LXNjcm9sbC12aWV3PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBqdXN0aWZ5LWVuZCBteC0xIG15LTIgZmxleC1ncm93XCI+XG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwie3tjb21tb25TZXJ2aWNlLmJ0bl9zdWNjZXNzX21kfX0gY3Vyc29yLXBvaW50ZXIgbXQtMlwiIChjbGljayk9XCJzdWJtaXRBZHZhbmNlVmlldygpXCI+QWRkXG4gICAgICAgICAgICAgICAgTGF5b3V0PC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC9keC1wb3B1cD4iXX0=
|