gamma-app-controller 1.1.14 → 1.1.15

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.
Files changed (25) hide show
  1. package/esm2020/lib/application-controller/application-controller.module.mjs +15 -5
  2. package/esm2020/lib/application-controller/application-dataset-component/create-dataset-sql/create-dataset-sql.component.mjs +2 -2
  3. package/esm2020/lib/application-controller/application-filter/application-filter.component.mjs +1 -2
  4. package/esm2020/lib/application-controller/application-view-components/create-comp-view/create-comp-view.component.mjs +10 -9
  5. package/esm2020/lib/application-controller/page-controller/page-config/page-config.component.mjs +3 -1
  6. package/esm2020/lib/application-controller/shared/advanced-component/gamma-advance-operator-table/gamma-advance-operator-table.component.mjs +1 -2
  7. package/esm2020/lib/application-controller/shared/advanced-component/gamma-heatmap/gamma-heatmap.component.mjs +328 -0
  8. package/esm2020/lib/application-controller/support-components/dash-table/dash-table.component.mjs +2 -2
  9. package/esm2020/lib/application-controller/support-components/dash-today-previous/dash-today-previous.component.mjs +2 -2
  10. package/esm2020/lib/application-controller/support-components/geo-map/geo-map.component.mjs +2 -2
  11. package/esm2020/lib/application-controller/support-components/heat-map/heat-map.component.mjs +556 -0
  12. package/esm2020/lib/application-controller/support-components/single-card/single-card.component.mjs +2 -3
  13. package/esm2020/lib/application-controller/support-components/table-with-bar/table-with-bar.component.mjs +2 -2
  14. package/esm2020/public-api.mjs +3 -1
  15. package/fesm2015/gamma-app-controller.mjs +888 -22
  16. package/fesm2015/gamma-app-controller.mjs.map +1 -1
  17. package/fesm2020/gamma-app-controller.mjs +892 -22
  18. package/fesm2020/gamma-app-controller.mjs.map +1 -1
  19. package/lib/application-controller/application-controller.module.d.ts +13 -11
  20. package/lib/application-controller/application-view-components/create-comp-view/create-comp-view.component.d.ts +1 -0
  21. package/lib/application-controller/page-controller/page-config/page-config.component.d.ts +2 -0
  22. package/lib/application-controller/shared/advanced-component/gamma-heatmap/gamma-heatmap.component.d.ts +60 -0
  23. package/lib/application-controller/support-components/heat-map/heat-map.component.d.ts +99 -0
  24. package/package.json +1 -1
  25. package/public-api.d.ts +2 -0
@@ -0,0 +1,556 @@
1
+ import { Component, EventEmitter, Input, Output } from "@angular/core";
2
+ import moment from './../../moment-helper';
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "ngx-toastr";
5
+ import * as i2 from "../../common";
6
+ import * as i3 from "../../application-content.service";
7
+ import * as i4 from "@angular/common";
8
+ import * as i5 from "devextreme-angular/ui/check-box";
9
+ import * as i6 from "devextreme-angular/ui/color-box";
10
+ import * as i7 from "devextreme-angular/ui/select-box";
11
+ import * as i8 from "devextreme-angular/ui/tag-box";
12
+ import * as i9 from "devextreme-angular/ui/text-box";
13
+ import * as i10 from "@angular/forms";
14
+ import * as i11 from "../../shared/loader/loader.component";
15
+ export class HeatMapSupportComponent {
16
+ constructor(toastrService, commonService, cdr, service) {
17
+ this.toastrService = toastrService;
18
+ this.commonService = commonService;
19
+ this.cdr = cdr;
20
+ this.service = service;
21
+ this.isAdvanceFilter = false;
22
+ this.isHeatMapClick = false;
23
+ this.heatChartDataSource = {};
24
+ this.chartDataForTooltip = {};
25
+ this.enrichNameList = ["abbreviateNumber", "getColorCodeSpan", "ThousandSeparator", "ThousandSeparatorWithTwoDecimals", "formatBytesv2"];
26
+ this.heatmapChartConfig = {
27
+ "chartFormat": "",
28
+ "topArgument": "",
29
+ "leftArgument": "",
30
+ "color": [],
31
+ "type": "",
32
+ "formate": "",
33
+ "columns": [
34
+ {
35
+ "visible": true,
36
+ "dataField": "",
37
+ "caption": "",
38
+ "enrichName": "",
39
+ }
40
+ ],
41
+ "commonConfig": {
42
+ "title": "",
43
+ "dataField": "",
44
+ "checkedKey": "",
45
+ "isSearchBox": false
46
+ }
47
+ };
48
+ this.heatmap_content_config = {
49
+ "kpiConfig": {
50
+ "serviceId": "",
51
+ "api": "/kpi/trends/network/get-metric-data",
52
+ "displayType": "table",
53
+ "formate": "",
54
+ "keyToPass": [],
55
+ "componentName": "GammaHeatChartComponent",
56
+ "dataConfig": {}
57
+ },
58
+ };
59
+ this.dataSourseForHeatMap = [];
60
+ this.viewProperties = {
61
+ enableClickEvent: false,
62
+ enableRightClickEvent: true,
63
+ clickEventOptions: {
64
+ associatedViews: [],
65
+ eventType: ""
66
+ }
67
+ };
68
+ this.optionalDrilDownDataSource = [];
69
+ this.isLoader = true;
70
+ this.activeTab = 'basic';
71
+ this.allConfiguredViews = [];
72
+ this.colorArray = [];
73
+ this.firstColor = "rgba(45, 110, 18, 1)";
74
+ this.secondColor = "rgba(255, 204, 0, 1)";
75
+ this.singleColor = "rgba(255, 204, 0, 1)";
76
+ this.test_voice_data = [{
77
+ record_date: '20250527',
78
+ dataset: [
79
+ { other_party_iso: 'YEM', total_charge: 184357176 },
80
+ { other_party_iso: 'ERI', total_charge: 115262500 },
81
+ { other_party_iso: 'BGD', total_charge: 83289614 },
82
+ { other_party_iso: 'ETH', total_charge: 79004500 },
83
+ { other_party_iso: 'PAK', total_charge: 76992454 },
84
+ { other_party_iso: 'SDN', total_charge: 60480400 },
85
+ { other_party_iso: 'IND', total_charge: 38892858 },
86
+ { other_party_iso: 'EGY', total_charge: 37769744 },
87
+ { other_party_iso: 'NPL', total_charge: 17214000 },
88
+ { other_party_iso: 'AFG', total_charge: 7268000 },
89
+ { other_party_iso: 'TCD', total_charge: 5372500 },
90
+ { other_party_iso: 'IDN', total_charge: 4425700 },
91
+ { other_party_iso: 'UGA', total_charge: 3933300 },
92
+ { other_party_iso: 'GBR', total_charge: 3848225 }
93
+ ]
94
+ },
95
+ {
96
+ record_date: '20250531',
97
+ dataset: [
98
+ { other_party_iso: 'YEM', total_charge: 208699827 },
99
+ { other_party_iso: 'ERI', total_charge: 143501500 },
100
+ { other_party_iso: 'BGD', total_charge: 106296294 },
101
+ { other_party_iso: 'ETH', total_charge: 86093500 },
102
+ { other_party_iso: 'PAK', total_charge: 77428461 },
103
+ { other_party_iso: 'SDN', total_charge: 65818598 },
104
+ { other_party_iso: 'IND', total_charge: 38635175 },
105
+ { other_party_iso: 'EGY', total_charge: 37658700 },
106
+ { other_party_iso: 'NPL', total_charge: 18773200 },
107
+ { other_party_iso: 'AFG', total_charge: 8232500 },
108
+ { other_party_iso: 'TCD', total_charge: 7007500 },
109
+ { other_party_iso: 'ARE', total_charge: 4593800 },
110
+ { other_party_iso: 'IDN', total_charge: 4118800 },
111
+ { other_party_iso: 'PHL', total_charge: 4051500 }
112
+ ]
113
+ },
114
+ {
115
+ record_date: '20250528',
116
+ dataset: [
117
+ { other_party_iso: 'YEM', total_charge: 198943661 },
118
+ { other_party_iso: 'ERI', total_charge: 118065000 },
119
+ { other_party_iso: 'BGD', total_charge: 90980829 },
120
+ { other_party_iso: 'ETH', total_charge: 80367700 },
121
+ { other_party_iso: 'PAK', total_charge: 78018973 },
122
+ { other_party_iso: 'SDN', total_charge: 56826500 },
123
+ { other_party_iso: 'IND', total_charge: 37871625 },
124
+ { other_party_iso: 'EGY', total_charge: 33374815 },
125
+ { other_party_iso: 'NPL', total_charge: 16763400 },
126
+ { other_party_iso: 'AFG', total_charge: 7926000 },
127
+ { other_party_iso: 'TCD', total_charge: 5600000 },
128
+ { other_party_iso: 'IDN', total_charge: 4602400 },
129
+ { other_party_iso: 'GBR', total_charge: 4443625 },
130
+ { other_party_iso: 'UGA', total_charge: 4379200 }
131
+ ]
132
+ },
133
+ {
134
+ record_date: '20250530',
135
+ dataset: [
136
+ { other_party_iso: 'YEM', total_charge: 231378852 },
137
+ { other_party_iso: 'BGD', total_charge: 151786018 },
138
+ { other_party_iso: 'ERI', total_charge: 146782500 },
139
+ { other_party_iso: 'PAK', total_charge: 88054445 },
140
+ { other_party_iso: 'ETH', total_charge: 83635500 },
141
+ { other_party_iso: 'SDN', total_charge: 62257000 },
142
+ { other_party_iso: 'IND', total_charge: 44316500 },
143
+ { other_party_iso: 'EGY', total_charge: 29894392 },
144
+ { other_party_iso: 'NPL', total_charge: 23383500 },
145
+ { other_party_iso: 'AFG', total_charge: 8029500 },
146
+ { other_party_iso: 'TCD', total_charge: 7322500 },
147
+ { other_party_iso: 'GBR', total_charge: 4338450 },
148
+ { other_party_iso: 'IDN', total_charge: 3904400 },
149
+ { other_party_iso: 'ARE', total_charge: 3832100 }
150
+ ]
151
+ },
152
+ {
153
+ record_date: '20250529',
154
+ dataset: [
155
+ { other_party_iso: 'YEM', total_charge: 200906357 },
156
+ { other_party_iso: 'ERI', total_charge: 126725000 },
157
+ { other_party_iso: 'BGD', total_charge: 115287722 },
158
+ { other_party_iso: 'ETH', total_charge: 82062400 },
159
+ { other_party_iso: 'PAK', total_charge: 77260610 },
160
+ { other_party_iso: 'SDN', total_charge: 54394810 },
161
+ { other_party_iso: 'IND', total_charge: 38654000 },
162
+ { other_party_iso: 'EGY', total_charge: 34503350 },
163
+ { other_party_iso: 'NPL', total_charge: 17277100 },
164
+ { other_party_iso: 'AFG', total_charge: 7746500 },
165
+ { other_party_iso: 'TCD', total_charge: 6100000 },
166
+ { other_party_iso: 'GBR', total_charge: 4736150 },
167
+ { other_party_iso: 'IDN', total_charge: 4678900 },
168
+ { other_party_iso: 'KEN', total_charge: 4453000 }
169
+ ]
170
+ },
171
+ {
172
+ record_date: '20250601',
173
+ dataset: [
174
+ { other_party_iso: 'YEM', total_charge: 214287978 },
175
+ { other_party_iso: 'ERI', total_charge: 154402500 },
176
+ { other_party_iso: 'BGD', total_charge: 100204000 },
177
+ { other_party_iso: 'ETH', total_charge: 97479800 },
178
+ { other_party_iso: 'PAK', total_charge: 75391463 },
179
+ { other_party_iso: 'SDN', total_charge: 65622200 },
180
+ { other_party_iso: 'IND', total_charge: 38124497 },
181
+ { other_party_iso: 'EGY', total_charge: 35278025 },
182
+ { other_party_iso: 'NPL', total_charge: 22665000 },
183
+ { other_party_iso: 'AFG', total_charge: 6920000 },
184
+ { other_party_iso: 'UGA', total_charge: 5625100 },
185
+ { other_party_iso: 'IDN', total_charge: 5256900 },
186
+ { other_party_iso: 'TCD', total_charge: 4970000 },
187
+ { other_party_iso: 'GBR', total_charge: 4410250 }
188
+ ]
189
+ }
190
+ ];
191
+ this.getHeatMapConfigOutPut = new EventEmitter();
192
+ }
193
+ set chartconfigData(value) {
194
+ if (value === undefined || value.length === 0) {
195
+ return;
196
+ }
197
+ else {
198
+ this.jsaonDatasource = value.data[0];
199
+ this.configColume = Object.keys(value.data[0]);
200
+ this.dataSourseForHeatMap = value.data;
201
+ this.selectedViewConfigs = value;
202
+ this.selectedTableViewType = value.selectedViewType;
203
+ if (value.selectedWidgetConfig) {
204
+ this.heatmap_content_config['kpiConfig'] = value.selectedWidgetConfig;
205
+ this.heatmapChartConfig = value.selectedWidgetConfig.dataConfig;
206
+ this.heatmapChartConfig.columns = value.selectedWidgetConfig.dataConfig.columns;
207
+ if (value.selectedWidgetConfig.viewProperties) {
208
+ this.viewProperties = value.selectedWidgetConfig.viewProperties;
209
+ if (value.selectedWidgetConfig.viewProperties.enableClickEvent) {
210
+ if (value.selectedWidgetConfig.viewProperties.clickEventOptions.eventType == 'optionalDrillDown') {
211
+ this.optionalDrilDownDataSource = value.selectedWidgetConfig.viewProperties.clickEventOptions.associatedViews;
212
+ this.viewProperties['clickEventOptions'] = {
213
+ "eventType": value.selectedWidgetConfig.viewProperties.clickEventOptions.eventType,
214
+ "associatedViews": []
215
+ };
216
+ }
217
+ else if (value.selectedWidgetConfig.viewProperties.clickEventOptions.eventType == 'drilldown') {
218
+ this.viewProperties['clickEventOptions'] = {
219
+ "eventType": value.selectedWidgetConfig.viewProperties.clickEventOptions.eventType,
220
+ "associatedViews": value.selectedWidgetConfig.viewProperties.clickEventOptions.associatedViews
221
+ };
222
+ }
223
+ }
224
+ else {
225
+ this.viewProperties['clickEventOptions'] = {};
226
+ }
227
+ }
228
+ this.cdr.detectChanges();
229
+ }
230
+ else {
231
+ this.viewProperties = {
232
+ enableClickEvent: false,
233
+ enableRightClickEvent: true,
234
+ clickEventOptions: {
235
+ associatedViews: [],
236
+ eventType: ""
237
+ }
238
+ };
239
+ if (this.heatmapChartConfig.columns) {
240
+ }
241
+ else {
242
+ this.heatmapChartConfig.columns = [];
243
+ console.log(this.configColume);
244
+ }
245
+ this.cdr.detectChanges();
246
+ }
247
+ }
248
+ }
249
+ ngOnInit() {
250
+ this.service.getAppViewConfigs().subscribe({
251
+ next: (data) => {
252
+ this.allConfiguredViews = data;
253
+ this.isLoader = false;
254
+ }, error: (err) => {
255
+ this.toastrService.error('Unexpected Server Exception. Please contact System Admin.', 'All Views');
256
+ }
257
+ });
258
+ if (this.optionalDrilDownDataSource.length == 0) {
259
+ this.optionalDrilDownDataSource = [
260
+ {
261
+ 'viewId': "",
262
+ 'filterCondition': ""
263
+ }
264
+ ];
265
+ }
266
+ }
267
+ getHeatmapData() {
268
+ this.heatChartDataSource = {};
269
+ this.isAdvanceFilter = false;
270
+ if (this.dataSourseForHeatMap && this.dataSourseForHeatMap.length !== 0) {
271
+ if (this.heatmapChartConfig.chartFormat == "topx") {
272
+ const { result, uniqueDates } = this.generateDateWiseColorCodedData(this.dataSourseForHeatMap);
273
+ uniqueDates.sort();
274
+ this.heatChartDataSource.dataSet = this.getTransposedHeatmapData(result);
275
+ this.heatChartDataSource["argumentValue"] = uniqueDates;
276
+ }
277
+ else if ((this.heatmapChartConfig.chartFormat == "simple")) {
278
+ const { result, uniqueDates } = this.generateData(this.dataSourseForHeatMap);
279
+ uniqueDates.sort();
280
+ this.heatChartDataSource["dataSet"] = result;
281
+ this.heatChartDataSource["argumentValue"] = uniqueDates;
282
+ }
283
+ this.isHeatMapLoader = false;
284
+ this.isHeatMapClick = false;
285
+ }
286
+ else {
287
+ this.isHeatMapClick = false;
288
+ this.toastrService.info("No Data Found");
289
+ }
290
+ }
291
+ getTransposedHeatmapData(dataSet) {
292
+ const transposed = [];
293
+ const maxBoxes = Math.max(...dataSet.map(item => item.dataset.length));
294
+ for (let i = 0; i < maxBoxes; i++) {
295
+ const row = [];
296
+ for (let j = 0; j < dataSet.length; j++) {
297
+ const box = dataSet[j].dataset[i];
298
+ row.push({
299
+ box: box || null,
300
+ date: dataSet[j].record_date
301
+ });
302
+ }
303
+ transposed.push(row);
304
+ }
305
+ return transposed;
306
+ }
307
+ generateDateWiseColorCodedData(data) {
308
+ const result = [];
309
+ const uniqueDates = new Set();
310
+ const allEntries = [];
311
+ const topArg = this.heatmapChartConfig.topArgument;
312
+ const leftArg = this.heatmapChartConfig.leftArgument;
313
+ const valueField = this.heatmapChartConfig.columns[0].dataField;
314
+ data.forEach(entry => {
315
+ const formattedDate = moment(entry.record_date).format('YYYY-MM-DD');
316
+ uniqueDates.add(formattedDate);
317
+ entry.dataset.forEach(item => {
318
+ allEntries.push({
319
+ [topArg]: formattedDate,
320
+ [leftArg]: item[`${leftArg}`],
321
+ [valueField]: item[`${valueField}`]
322
+ });
323
+ });
324
+ });
325
+ let coloredData;
326
+ if (this.heatmapChartConfig.type === 'gradient') {
327
+ coloredData = this.getFormateDataByColorCodeForGradient(allEntries, valueField);
328
+ }
329
+ else if (this.heatmapChartConfig.type === 'twoColor') {
330
+ coloredData = this.getFormateDataByColorCodeForWithTwoColor(allEntries, valueField);
331
+ }
332
+ else {
333
+ coloredData = this.getFormateDataByColorCodeForWithSingleColor(allEntries, valueField);
334
+ }
335
+ const dateMap = {};
336
+ coloredData.forEach(item => {
337
+ const date = item[topArg];
338
+ if (!dateMap[date]) {
339
+ dateMap[date] = [];
340
+ }
341
+ dateMap[date].push({
342
+ [leftArg]: item[leftArg],
343
+ [valueField]: item[valueField],
344
+ color: item.color,
345
+ [topArg]: date,
346
+ });
347
+ });
348
+ for (const date of Array.from(uniqueDates).sort()) {
349
+ result.push({
350
+ record_date: date,
351
+ dataset: dateMap[date] || []
352
+ });
353
+ }
354
+ return {
355
+ result,
356
+ uniqueDates: Array.from(uniqueDates).sort()
357
+ };
358
+ }
359
+ generateData(data) {
360
+ const result = [];
361
+ const uniqueDates = new Set();
362
+ const dataSourceMap = {};
363
+ const topArg = this.heatmapChartConfig.topArgument;
364
+ const leftArg = this.heatmapChartConfig.leftArgument;
365
+ data.forEach(item => {
366
+ const rowKey = item[leftArg];
367
+ const columnKey = moment(item[topArg]).format('YYYY-MM-DD');
368
+ if (!dataSourceMap[rowKey]) {
369
+ dataSourceMap[rowKey] = {
370
+ datasource: rowKey,
371
+ dataset: []
372
+ };
373
+ }
374
+ dataSourceMap[rowKey].dataset.push({
375
+ ...item,
376
+ [topArg]: columnKey
377
+ });
378
+ uniqueDates.add(columnKey);
379
+ });
380
+ const uniqueDatesArray = Array.from(uniqueDates);
381
+ for (const key in dataSourceMap) {
382
+ const dataset = dataSourceMap[key].dataset;
383
+ let formattedDataset;
384
+ if (this.heatmapChartConfig.type == "gradient") {
385
+ formattedDataset = this.getFormateDataByColorCodeForGradient(dataset, this.heatmapChartConfig.columns[0].dataField);
386
+ }
387
+ else if (this.heatmapChartConfig.type == "twoColor") {
388
+ formattedDataset = this.getFormateDataByColorCodeForWithTwoColor(dataset, this.heatmapChartConfig.columns[0].dataField);
389
+ }
390
+ else {
391
+ formattedDataset = this.getFormateDataByColorCodeForWithSingleColor(dataset, this.heatmapChartConfig.columns[0].dataField);
392
+ }
393
+ const dateToItemMap = {};
394
+ formattedDataset.forEach(item => {
395
+ dateToItemMap[item[topArg]] = item;
396
+ });
397
+ const completeDataset = uniqueDatesArray.map((date) => {
398
+ if (dateToItemMap[date]) {
399
+ return dateToItemMap[date];
400
+ }
401
+ else {
402
+ return {
403
+ [topArg]: date,
404
+ avgSize: "No Data",
405
+ fileCount: 0,
406
+ fileSize: 0,
407
+ color: "rgb(242, 118, 109)"
408
+ };
409
+ }
410
+ });
411
+ result.push({
412
+ datasource: key,
413
+ dataset: completeDataset
414
+ });
415
+ }
416
+ return {
417
+ result: result,
418
+ uniqueDates: uniqueDatesArray
419
+ };
420
+ }
421
+ getFormateDataByColorCodeForGradient(filedata, column) {
422
+ filedata.forEach(item => {
423
+ item.avgSize = parseFloat(item[column]);
424
+ });
425
+ const maxAvgSize = Math.max(...filedata.map(item => item[column]));
426
+ const minAvgSize = Math.min(...filedata.map(item => item[column]));
427
+ const [minColorStr, maxColorStr] = this.colorArray || ["rgba(45, 110, 18,1)", "rgba(255, 204, 0,1)"];
428
+ const minColor = this.parseRGBA(minColorStr);
429
+ const maxColor = this.parseRGBA(maxColorStr);
430
+ filedata.forEach(item => {
431
+ item.color = this.calculateColor(item[column], minAvgSize, maxAvgSize, minColor, maxColor);
432
+ });
433
+ return filedata;
434
+ }
435
+ getFormateDataByColorCodeForWithTwoColor(filedata, column) {
436
+ filedata.forEach(item => {
437
+ item[column] = parseFloat(item[column]);
438
+ });
439
+ const [minColorStr, maxColorStr] = this.colorArray || ["rgba(45, 110, 18,1)", "rgba(255, 204, 0,1)"];
440
+ const minColor = this.parseRGBA(minColorStr);
441
+ const maxColor = this.parseRGBA(maxColorStr);
442
+ filedata.forEach(item => {
443
+ if (item[column] == 0) {
444
+ item.color = `rgb(${minColor.join(',')})`;
445
+ }
446
+ else {
447
+ item.color = `rgb(${maxColor.join(',')})`;
448
+ }
449
+ });
450
+ return filedata;
451
+ }
452
+ getFormateDataByColorCodeForWithSingleColor(filedata, column) {
453
+ filedata.forEach(item => {
454
+ item[column] = parseFloat(item[column]);
455
+ });
456
+ const [singleColor] = this.colorArray || ["rgba(255, 204, 0,1)"];
457
+ const minColor = this.parseRGBA(singleColor);
458
+ filedata.forEach(item => {
459
+ item.color = `rgb(${minColor.join(',')})`;
460
+ });
461
+ return filedata;
462
+ }
463
+ parseRGBA(colorStr) {
464
+ const values = colorStr.match(/[\d.]+/g)?.map(Number) || [];
465
+ if (values.length === 3)
466
+ values.push(1);
467
+ return [
468
+ values[0] ?? 0,
469
+ values[1] ?? 0,
470
+ values[2] ?? 0,
471
+ values[3] ?? 1
472
+ ];
473
+ }
474
+ calculateColor(avgSize, minAvgSize, maxAvgSize, minColor, maxColor) {
475
+ if (minAvgSize != maxAvgSize) {
476
+ let gradient = (avgSize - minAvgSize) / (maxAvgSize - minAvgSize);
477
+ let color = minColor.map((channel, index) => {
478
+ return Math.round(channel + gradient * (maxColor[index] - channel));
479
+ });
480
+ return `rgb(${color.join(',')})`;
481
+ }
482
+ else {
483
+ return `rgb(${minColor.join(',')})`;
484
+ }
485
+ }
486
+ setActiveTab(tab) {
487
+ this.activeTab = tab;
488
+ }
489
+ getSelectedEventType(e) {
490
+ if (e.event) {
491
+ this.optionalDrilDownDataSource = [];
492
+ if (this.viewProperties.clickEventOptions.eventType == 'drilldown') {
493
+ this.heatmapChartConfig['viewProperties']['associatedViews'] = [];
494
+ }
495
+ }
496
+ }
497
+ resetViewProprstise() {
498
+ this.viewProperties = {
499
+ enableClickEvent: false,
500
+ enableRightClickEvent: true,
501
+ clickEventOptions: {
502
+ associatedViews: [],
503
+ eventType: ""
504
+ }
505
+ };
506
+ }
507
+ deleteAssociatedParams(index) {
508
+ this.optionalDrilDownDataSource.splice(index, 1);
509
+ }
510
+ addAssociatedParams() {
511
+ this.optionalDrilDownDataSource.push({
512
+ 'viewId': "",
513
+ 'filterCondition': ""
514
+ });
515
+ }
516
+ getColorBoxVisible(e) {
517
+ this.colorArray = [];
518
+ }
519
+ saveColors() {
520
+ if (this.heatmapChartConfig.type == 'gradient' || this.heatmapChartConfig.type == 'twoColor') {
521
+ this.colorArray = [this.firstColor, this.secondColor];
522
+ }
523
+ else if (this.heatmapChartConfig.type == 'singleColor') {
524
+ this.colorArray = [this.singleColor];
525
+ }
526
+ this.getHeatmapData();
527
+ }
528
+ getSaveChartConfig() {
529
+ if (this.colorArray && this.colorArray.length !== 0) {
530
+ if (this.heatmapChartConfig.type == 'gradient' || this.heatmapChartConfig.type == 'twoColor') {
531
+ this.heatmapChartConfig.color = this.colorArray;
532
+ }
533
+ else if (this.heatmapChartConfig.type == 'singleColor') {
534
+ this.heatmapChartConfig.color = this.colorArray;
535
+ }
536
+ }
537
+ if (this.viewProperties.clickEventOptions.eventType == 'optionalDrillDown') {
538
+ this.viewProperties['clickEventOptions']['associatedViews'] = this.optionalDrilDownDataSource;
539
+ }
540
+ this.heatmap_content_config.kpiConfig['viewProperties'] = this.viewProperties;
541
+ this.heatmap_content_config.kpiConfig['dataConfig'] = this.heatmapChartConfig;
542
+ this.getHeatMapConfigOutPut.emit(this.heatmap_content_config);
543
+ }
544
+ }
545
+ HeatMapSupportComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: HeatMapSupportComponent, deps: [{ token: i1.ToastrService }, { token: i2.CommonService }, { token: i0.ChangeDetectorRef }, { token: i3.ApplicationContentService }], target: i0.ɵɵFactoryTarget.Component });
546
+ HeatMapSupportComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: HeatMapSupportComponent, selector: "app-heat-map", inputs: { chartconfigData: ["datasetmodal", "chartconfigData"] }, outputs: { getHeatMapConfigOutPut: "getHeatMapConfigOutPut" }, ngImport: i0, template: "<div class=\"m-2\">\n <div class=\"w-full m-2 border-r\">\n <ng-container *ngIf=\"!isJsonPreview\">\n <pre><code>{{jsaonDatasource | json}}</code></pre>\n </ng-container>\n <ng-container *ngIf=\"isJsonPreview\">\n <ng-container *ngIf=\"heatmapChartConfig.chartFormat == 'simple'\">\n <div class=\"mx-5 h-[60vh] overflow-x-auto\">\n <div class=\"inline-block\">\n <div class=\"flex flex-nowrap justify-center\">\n <div class=\"flex-shrink-0 w-64 max-w-[20%] h-10 flex items-center justify-center\"></div>\n <div *ngFor=\"let item of heatChartDataSource.argumentValue\"\n class=\"flex-shrink-0 min-w-22 max-w-[20%] h-8 text-sm flex items-center justify-center\">\n {{item}}\n </div>\n </div>\n </div>\n <ng-container *ngFor=\"let item of heatChartDataSource.dataSet\">\n <div class=\"flex flex-row\">\n <div class=\"h-8 flex text-sm items-center min-w-64 justify-end px-2 inline\">\n {{ item.datasource }}\n </div>\n <div class=\"inline-block\">\n <div class=\"flex flex-nowrap justify-start\">\n <ng-container *ngFor=\"let box of item.dataset\">\n <div class=\"flex-shrink-0 min-w-22 max-w-[20%] h-8 border-2 text-sm cursor-pointer flex items-center justify-center text-gray-800\"\n [ngStyle]=\"{ 'background-color': box.color }\"\n [attr.title]=\"'Record Date: ' + box[heatmapChartConfig.topArgument] + ', Value: ' + box[heatmapChartConfig.columns[0].dataField]\">\n {{ box[heatmapChartConfig.columns[0].dataField]}}\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </ng-container>\n <ng-container *ngIf=\"heatmapChartConfig.chartFormat == 'topx'\">\n <div class=\"mx-5 h-[60vh] overflow-x-auto\">\n <div class=\"flex flex-row\">\n <ng-container *ngFor=\"let header of heatChartDataSource.argumentValue\">\n <div class=\"min-w-32 text-sm font-medium text-center mb-2\">\n {{ header }}\n </div>\n </ng-container>\n </div>\n\n <!-- Heatmap Body (Top to Bottom Layout) -->\n <div *ngFor=\"let row of heatChartDataSource.dataSet\" class=\"flex flex-row\">\n <ng-container *ngFor=\"let cell of row\">\n <div *ngIf=\"cell.box\"\n class=\"h-8 border-2 text-sm cursor-pointer flex items-center justify-center text-gray-800 min-w-32\"\n [ngStyle]=\"{ 'background-color': cell.box.color }\"\n [attr.title]=\"'Record Date: ' + cell.heatmapChartConfig.topArgument + ', Value: ' + cell.box.heatmapChartConfig.columns[0].dataField\">\n {{ cell.box.heatmapChartConfig.leftArgument }} ({{ commonService.abbreviateNumber(cell.box.heatmapChartConfig.columns[0].dataField) }})\n </div>\n <div *ngIf=\"!cell.box\" class=\"h-8 min-w-32\"></div>\n </ng-container>\n </div>\n </div>\n </ng-container>\n \n \n </ng-container>\n </div>\n <div class=\"w-full mx-2 border-r\">\n <div class=\"mb-4 border-b border-gray-200 dark:border-gray-700\">\n <ul class=\"flex flex-wrap -mb-px text-sm font-medium text-center\" role=\"tablist\">\n <li class=\"me-2\" role=\"presentation\">\n <button class=\"inline-block p-4 border-b-2 rounded-t-lg\" [ngClass]=\"{\n 'text-purple-600 border-purple-600 dark:text-purple-500 dark:border-purple-500': activeTab === 'basic',\n 'text-gray-500 dark:text-gray-400 border-transparent': activeTab !== 'basic'\n }\" (click)=\"setActiveTab('basic')\" type=\"button\" role=\"tab\">\n Basic\n </button>\n </li>\n <li class=\"me-2\" role=\"presentation\">\n <button class=\"inline-block p-4 border-b-2 rounded-t-lg\" [ngClass]=\"{\n 'text-purple-600 border-purple-600 dark:text-purple-500 dark:border-purple-500': activeTab === 'columns',\n 'text-gray-500 dark:text-gray-400 border-transparent': activeTab !== 'columns'\n }\" (click)=\"setActiveTab('columns')\" type=\"button\" role=\"tab\">\n Columns\n </button>\n </li>\n <li class=\"me-2\" role=\"presentation\">\n <button class=\"inline-block p-4 border-b-2 rounded-t-lg\" [ngClass]=\"{\n 'text-purple-600 border-purple-600 dark:text-purple-500 dark:border-purple-500': activeTab === 'properties',\n 'text-gray-500 dark:text-gray-400 border-transparent': activeTab !== 'properties'\n }\" (click)=\"setActiveTab('properties')\" type=\"button\" role=\"tab\">\n Properties\n </button>\n </li>\n\n </ul>\n </div>\n\n <div id=\"default-styled-tab-content\">\n <div *ngIf=\"activeTab === 'basic'\">\n <div class=\"flex flex-col flex-auto min-w-0\">\n <div class=\"text-sm py-1 font-extrabold border-b bg-gray-700 text-white px-2\"> Filter Title Config\n </div>\n <div class=\"pt-2 border-x border-b \">\n <div class=\"my-2 flex justify-between\">\n <div class=\"px-1 mb-1 w-full\">\n <div class=\"text-md mb-1\"> Title</div>\n <dx-select-box [(ngModel)]=\"heatmapChartConfig.chartFormat\" [items]=\"['simple','topx']\"></dx-select-box>\n </div>\n <div class=\"px-1 mb-1 w-full\">\n <div class=\"text-md mb-1\"> Top Argument</div>\n <dx-select-box [searchEnabled]=\"true\" [items]=\"configColume\"\n [(ngModel)]=\"heatmapChartConfig.topArgument\"></dx-select-box>\n </div>\n <div class=\"px-1 mb-1 w-full\">\n <div class=\"text-md mb-1\"> Left Argument</div>\n <dx-select-box [searchEnabled]=\"true\" [items]=\"configColume\"\n [(ngModel)]=\"heatmapChartConfig.leftArgument\"></dx-select-box>\n </div>\n <div class=\"px-1 mb-1 w-full\">\n <div class=\"text-md mb-1\"> Color Usage</div>\n <dx-select-box [searchEnabled]=\"true\" [items]=\"['gradient','twoColor','singleColor',]\"\n [(ngModel)]=\"heatmapChartConfig.type\"\n (onValueChanged)=\"getColorBoxVisible($event)\"></dx-select-box>\n </div>\n\n <ng-container\n *ngIf=\"heatmapChartConfig.type == 'gradient' || heatmapChartConfig.type == 'twoColor'\">\n <div class=\"px-1 mb-1 w-full\">\n <div class=\"text-md mb-1\"> Color</div>\n <dx-color-box [(ngModel)]=\"firstColor\" [editAlphaChannel]=\"true\"></dx-color-box>\n </div>\n <div class=\"px-1 mb-1 w-full\">\n <div class=\"text-md mb-1\"> Color</div>\n <dx-color-box [(ngModel)]=\"secondColor\" [editAlphaChannel]=\"true\"></dx-color-box>\n </div>\n\n </ng-container>\n <ng-container *ngIf=\"heatmapChartConfig.type == 'singleColor'\">\n <div class=\"px-1 mb-1 w-full\">\n <div class=\"text-md mb-1\"> Color</div>\n <dx-color-box [(ngModel)]=\"singleColor\" [editAlphaChannel]=\"true\"></dx-color-box>\n </div>\n\n </ng-container>\n <div class=\"px-1 mb-1 w-full\" *ngIf=\"heatmapChartConfig.type !== ''\">\n <button class=\"{{commonService.btn_primary_md}} mt-6\" (click)=\"saveColors()\">Check\n View</button>\n </div>\n\n\n\n </div>\n </div>\n </div>\n </div>\n <div *ngIf=\"activeTab === 'columns'\">\n <div class=\"h-full overflow-x-auto\">\n <div class=\"flex flex-col flex-auto min-w-0\">\n\n <div class=\"pt-2 border-x border-b \">\n <div class=\"my-2 border-b flex flex-row\"\n *ngFor=\"let item of heatmapChartConfig.columns; let i = index;\">\n <div class=\"px-1 mb-2 mt-6 w-full\">\n <dx-check-box [value]=\"item.visible\" [(ngModel)]=\"item.visible\"\n text=\"Visiblity\"></dx-check-box>\n </div>\n\n <div class=\"px-1 mb-2 w-full\">\n <div class=\"text-md mb-2\"> Value Field</div>\n <dx-select-box [searchEnabled]=\"true\" [items]=\"configColume\"\n [(ngModel)]=\"item.dataField\"></dx-select-box>\n </div>\n <div class=\"px-1 mb-2 w-full\">\n <div class=\"text-md mb-2\"> Caption</div>\n <dx-text-box [(ngModel)]=\"item.caption\"></dx-text-box>\n </div>\n <div class=\"px-2 mb-2 w-full\">\n <div class=\"text-md mb-2\"> UI Function</div>\n <dx-select-box [items]=\"enrichNameList\" [(ngModel)]=\"item.enrichName\"\n [searchEnabled]=\"true\"></dx-select-box>\n </div>\n\n\n </div>\n </div>\n </div>\n </div>\n </div>\n <div *ngIf=\"activeTab === 'properties'\">\n <div class=\"h-full overflow-x-auto\">\n <app-loader *ngIf=\"isLoader\"></app-loader>\n <ng-container *ngIf=\"!isLoader\">\n <div class=\"flex flex-row justify-between border-b py-3\">\n <div class=\"mx-2\">\n <dx-check-box [value]=\"viewProperties.enableClickEvent\"\n [(ngModel)]=\"viewProperties.enableClickEvent\"\n text=\"Enable Click Event\"></dx-check-box>\n </div>\n <div class=\"mx-2\">\n <dx-check-box [value]=\"viewProperties.enableRightClickEvent\"\n [(ngModel)]=\"viewProperties.enableRightClickEvent\"\n text=\"Enable Right Click\"></dx-check-box>\n </div>\n </div>\n <div class=\"w-full p-2\" *ngIf=\"viewProperties.enableClickEvent\">\n\n <div class=\"flex flex-col flex-auto min-w-0 my-2\">\n <div class=\"text-sm py-1 font-extrabold border-b bg-gray-700 text-white px-2\"> Event\n Type\n Option\n </div>\n <div class=\"w-full p-3 border-x border-b \">\n <div class=\"flex flex-row\">\n <div class=\"w-full\">\n <div class=\"text-md mb-2\"> Event Type</div>\n </div>\n <div class=\"w-full\">\n <dx-select-box\n [items]=\"['drilldown','sameViewDrilldown','optionalDrillDown']\"\n (onValueChanged)=\"getSelectedEventType($event)\"\n [(ngModel)]=\"viewProperties.clickEventOptions.eventType\"></dx-select-box>\n </div>\n </div>\n <ng-container *ngIf=\"viewProperties.clickEventOptions.eventType == 'drilldown'\">\n <div class=\"flex flex-row justify-between mt-3\">\n <div class=\"w-full\">\n <div class=\"text-md mb-2\"> Associated Views</div>\n <dx-tag-box [items]=\"allConfiguredViews\"\n [(ngModel)]=\"viewProperties.clickEventOptions.associatedViews\"\n valueExpr=\"viewId\" displayExpr=\"viewName\"\n [showSelectionControls]=\"true\" [searchEnabled]=\"true\"></dx-tag-box>\n </div>\n </div>\n </ng-container>\n <ng-container\n *ngIf=\"viewProperties.clickEventOptions.eventType == 'sameViewDrilldown'\">\n <div class=\"flex flex-row justify-between mt-3\">\n <div class=\"w-full\">\n <div class=\"text-md mb-2\"> Associated Views</div>\n <dx-tag-box [items]=\"allConfiguredViews\"\n [(ngModel)]=\"viewProperties.clickEventOptions.associatedViews\"\n valueExpr=\"viewId\" displayExpr=\"viewName\"\n [showSelectionControls]=\"true\" [searchEnabled]=\"true\"></dx-tag-box>\n </div>\n </div>\n </ng-container>\n <ng-container\n *ngIf=\"viewProperties.clickEventOptions.eventType == 'optionalDrillDown'\">\n <div class=\"flex flex-row justify-between mt-3\">\n <div class=\"w-full\">\n <ng-container\n *ngFor=\"let item of optionalDrilDownDataSource;let i = index;\">\n\n <div class=\"flex flex-row justify-between\">\n <div class=\"mx-2 w-1/2\">\n <div class=\"text-md mb-2\"> Associated Views</div>\n <dx-tag-box [items]=\"allConfiguredViews\"\n [(ngModel)]=\"item.viewId\" valueExpr=\"viewId\"\n displayExpr=\"viewName\" [showSelectionControls]=\"true\"\n [maxDisplayedTags]=\"2\"\n [searchEnabled]=\"true\"></dx-tag-box>\n\n </div>\n <div class=\"mx-2 w-1/2\">\n <div class=\"text-md mb-2\"> Associated Params</div>\n <dx-text-box\n [(ngModel)]=\"item.filterCondition\"></dx-text-box>\n </div>\n <div class=\"mx-2\">\n <button\n class=\"{{commonService.btn_danger_sm}} cursor-pointer mt-8\"\n (click)=\"deleteAssociatedParams(i)\"><i\n class=\"fa fa-trash-o\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n </ng-container>\n <div class=\"flex flex-row justify-end mt-4\">\n <button class=\"{{commonService.btn_primary_sm}} cursor-pointer\"\n (click)=\"addAssociatedParams()\">Add\n Params</button>\n </div>\n </div>\n </div>\n </ng-container>\n <button class=\"{{commonService.btn_light_md}} cursor-pointer mt-4\"\n (click)=\"resetViewProprstise()\">Reset All Event</button>\n </div>\n </div>\n\n </div>\n </ng-container>\n </div>\n </div>\n\n </div>\n\n\n </div>\n</div>\n\n\n<div class=\"flex flex-row border-t pl-3\">\n <div class=\"flex justify-start mx-1\">\n <button class=\"{{commonService.btn_warning_md}} cursor-pointer mt-2\" (click)=\"isJsonPreview = true\">\n Preview</button>\n <button class=\"{{commonService.btn_primary_md}} cursor-pointer mt-2\" (click)=\"isJsonPreview = false\">Data\n Preview</button>\n </div>\n <div class=\"flex justify-end mx-1 flex-grow\">\n <button class=\"{{commonService.btn_success_md}} cursor-pointer mt-2\"\n (click)=\"getSaveChartConfig()\">Submit</button>\n </div>\n</div>", dependencies: [{ kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i5.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: i6.DxColorBoxComponent, selector: "dx-color-box", inputs: ["acceptCustomValue", "accessKey", "activeStateEnabled", "applyButtonText", "applyValueMode", "buttons", "cancelButtonText", "deferRendering", "disabled", "dropDownButtonTemplate", "dropDownOptions", "editAlphaChannel", "elementAttr", "fieldTemplate", "focusStateEnabled", "height", "hint", "hoverStateEnabled", "inputAttr", "isValid", "keyStep", "label", "labelMode", "name", "opened", "openOnFieldClick", "placeholder", "readOnly", "rtlEnabled", "showClearButton", "showDropDownButton", "stylingMode", "tabIndex", "text", "validationError", "validationErrors", "validationMessageMode", "validationStatus", "value", "visible", "width"], outputs: ["onChange", "onClosed", "onCopy", "onCut", "onDisposing", "onEnterKey", "onFocusIn", "onFocusOut", "onInitialized", "onInput", "onKeyDown", "onKeyUp", "onOpened", "onOptionChanged", "onPaste", "onValueChanged", "acceptCustomValueChange", "accessKeyChange", "activeStateEnabledChange", "applyButtonTextChange", "applyValueModeChange", "buttonsChange", "cancelButtonTextChange", "deferRenderingChange", "disabledChange", "dropDownButtonTemplateChange", "dropDownOptionsChange", "editAlphaChannelChange", "elementAttrChange", "fieldTemplateChange", "focusStateEnabledChange", "heightChange", "hintChange", "hoverStateEnabledChange", "inputAttrChange", "isValidChange", "keyStepChange", "labelChange", "labelModeChange", "nameChange", "openedChange", "openOnFieldClickChange", "placeholderChange", "readOnlyChange", "rtlEnabledChange", "showClearButtonChange", "showDropDownButtonChange", "stylingModeChange", "tabIndexChange", "textChange", "validationErrorChange", "validationErrorsChange", "validationMessageModeChange", "validationStatusChange", "valueChange", "visibleChange", "widthChange", "onBlur"] }, { kind: "component", type: i7.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: i8.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: i9.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: i10.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i10.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i11.LoaderComponent, selector: "app-loader" }, { kind: "pipe", type: i4.JsonPipe, name: "json" }] });
547
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: HeatMapSupportComponent, decorators: [{
548
+ type: Component,
549
+ args: [{ selector: 'app-heat-map', template: "<div class=\"m-2\">\n <div class=\"w-full m-2 border-r\">\n <ng-container *ngIf=\"!isJsonPreview\">\n <pre><code>{{jsaonDatasource | json}}</code></pre>\n </ng-container>\n <ng-container *ngIf=\"isJsonPreview\">\n <ng-container *ngIf=\"heatmapChartConfig.chartFormat == 'simple'\">\n <div class=\"mx-5 h-[60vh] overflow-x-auto\">\n <div class=\"inline-block\">\n <div class=\"flex flex-nowrap justify-center\">\n <div class=\"flex-shrink-0 w-64 max-w-[20%] h-10 flex items-center justify-center\"></div>\n <div *ngFor=\"let item of heatChartDataSource.argumentValue\"\n class=\"flex-shrink-0 min-w-22 max-w-[20%] h-8 text-sm flex items-center justify-center\">\n {{item}}\n </div>\n </div>\n </div>\n <ng-container *ngFor=\"let item of heatChartDataSource.dataSet\">\n <div class=\"flex flex-row\">\n <div class=\"h-8 flex text-sm items-center min-w-64 justify-end px-2 inline\">\n {{ item.datasource }}\n </div>\n <div class=\"inline-block\">\n <div class=\"flex flex-nowrap justify-start\">\n <ng-container *ngFor=\"let box of item.dataset\">\n <div class=\"flex-shrink-0 min-w-22 max-w-[20%] h-8 border-2 text-sm cursor-pointer flex items-center justify-center text-gray-800\"\n [ngStyle]=\"{ 'background-color': box.color }\"\n [attr.title]=\"'Record Date: ' + box[heatmapChartConfig.topArgument] + ', Value: ' + box[heatmapChartConfig.columns[0].dataField]\">\n {{ box[heatmapChartConfig.columns[0].dataField]}}\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </ng-container>\n <ng-container *ngIf=\"heatmapChartConfig.chartFormat == 'topx'\">\n <div class=\"mx-5 h-[60vh] overflow-x-auto\">\n <div class=\"flex flex-row\">\n <ng-container *ngFor=\"let header of heatChartDataSource.argumentValue\">\n <div class=\"min-w-32 text-sm font-medium text-center mb-2\">\n {{ header }}\n </div>\n </ng-container>\n </div>\n\n <!-- Heatmap Body (Top to Bottom Layout) -->\n <div *ngFor=\"let row of heatChartDataSource.dataSet\" class=\"flex flex-row\">\n <ng-container *ngFor=\"let cell of row\">\n <div *ngIf=\"cell.box\"\n class=\"h-8 border-2 text-sm cursor-pointer flex items-center justify-center text-gray-800 min-w-32\"\n [ngStyle]=\"{ 'background-color': cell.box.color }\"\n [attr.title]=\"'Record Date: ' + cell.heatmapChartConfig.topArgument + ', Value: ' + cell.box.heatmapChartConfig.columns[0].dataField\">\n {{ cell.box.heatmapChartConfig.leftArgument }} ({{ commonService.abbreviateNumber(cell.box.heatmapChartConfig.columns[0].dataField) }})\n </div>\n <div *ngIf=\"!cell.box\" class=\"h-8 min-w-32\"></div>\n </ng-container>\n </div>\n </div>\n </ng-container>\n \n \n </ng-container>\n </div>\n <div class=\"w-full mx-2 border-r\">\n <div class=\"mb-4 border-b border-gray-200 dark:border-gray-700\">\n <ul class=\"flex flex-wrap -mb-px text-sm font-medium text-center\" role=\"tablist\">\n <li class=\"me-2\" role=\"presentation\">\n <button class=\"inline-block p-4 border-b-2 rounded-t-lg\" [ngClass]=\"{\n 'text-purple-600 border-purple-600 dark:text-purple-500 dark:border-purple-500': activeTab === 'basic',\n 'text-gray-500 dark:text-gray-400 border-transparent': activeTab !== 'basic'\n }\" (click)=\"setActiveTab('basic')\" type=\"button\" role=\"tab\">\n Basic\n </button>\n </li>\n <li class=\"me-2\" role=\"presentation\">\n <button class=\"inline-block p-4 border-b-2 rounded-t-lg\" [ngClass]=\"{\n 'text-purple-600 border-purple-600 dark:text-purple-500 dark:border-purple-500': activeTab === 'columns',\n 'text-gray-500 dark:text-gray-400 border-transparent': activeTab !== 'columns'\n }\" (click)=\"setActiveTab('columns')\" type=\"button\" role=\"tab\">\n Columns\n </button>\n </li>\n <li class=\"me-2\" role=\"presentation\">\n <button class=\"inline-block p-4 border-b-2 rounded-t-lg\" [ngClass]=\"{\n 'text-purple-600 border-purple-600 dark:text-purple-500 dark:border-purple-500': activeTab === 'properties',\n 'text-gray-500 dark:text-gray-400 border-transparent': activeTab !== 'properties'\n }\" (click)=\"setActiveTab('properties')\" type=\"button\" role=\"tab\">\n Properties\n </button>\n </li>\n\n </ul>\n </div>\n\n <div id=\"default-styled-tab-content\">\n <div *ngIf=\"activeTab === 'basic'\">\n <div class=\"flex flex-col flex-auto min-w-0\">\n <div class=\"text-sm py-1 font-extrabold border-b bg-gray-700 text-white px-2\"> Filter Title Config\n </div>\n <div class=\"pt-2 border-x border-b \">\n <div class=\"my-2 flex justify-between\">\n <div class=\"px-1 mb-1 w-full\">\n <div class=\"text-md mb-1\"> Title</div>\n <dx-select-box [(ngModel)]=\"heatmapChartConfig.chartFormat\" [items]=\"['simple','topx']\"></dx-select-box>\n </div>\n <div class=\"px-1 mb-1 w-full\">\n <div class=\"text-md mb-1\"> Top Argument</div>\n <dx-select-box [searchEnabled]=\"true\" [items]=\"configColume\"\n [(ngModel)]=\"heatmapChartConfig.topArgument\"></dx-select-box>\n </div>\n <div class=\"px-1 mb-1 w-full\">\n <div class=\"text-md mb-1\"> Left Argument</div>\n <dx-select-box [searchEnabled]=\"true\" [items]=\"configColume\"\n [(ngModel)]=\"heatmapChartConfig.leftArgument\"></dx-select-box>\n </div>\n <div class=\"px-1 mb-1 w-full\">\n <div class=\"text-md mb-1\"> Color Usage</div>\n <dx-select-box [searchEnabled]=\"true\" [items]=\"['gradient','twoColor','singleColor',]\"\n [(ngModel)]=\"heatmapChartConfig.type\"\n (onValueChanged)=\"getColorBoxVisible($event)\"></dx-select-box>\n </div>\n\n <ng-container\n *ngIf=\"heatmapChartConfig.type == 'gradient' || heatmapChartConfig.type == 'twoColor'\">\n <div class=\"px-1 mb-1 w-full\">\n <div class=\"text-md mb-1\"> Color</div>\n <dx-color-box [(ngModel)]=\"firstColor\" [editAlphaChannel]=\"true\"></dx-color-box>\n </div>\n <div class=\"px-1 mb-1 w-full\">\n <div class=\"text-md mb-1\"> Color</div>\n <dx-color-box [(ngModel)]=\"secondColor\" [editAlphaChannel]=\"true\"></dx-color-box>\n </div>\n\n </ng-container>\n <ng-container *ngIf=\"heatmapChartConfig.type == 'singleColor'\">\n <div class=\"px-1 mb-1 w-full\">\n <div class=\"text-md mb-1\"> Color</div>\n <dx-color-box [(ngModel)]=\"singleColor\" [editAlphaChannel]=\"true\"></dx-color-box>\n </div>\n\n </ng-container>\n <div class=\"px-1 mb-1 w-full\" *ngIf=\"heatmapChartConfig.type !== ''\">\n <button class=\"{{commonService.btn_primary_md}} mt-6\" (click)=\"saveColors()\">Check\n View</button>\n </div>\n\n\n\n </div>\n </div>\n </div>\n </div>\n <div *ngIf=\"activeTab === 'columns'\">\n <div class=\"h-full overflow-x-auto\">\n <div class=\"flex flex-col flex-auto min-w-0\">\n\n <div class=\"pt-2 border-x border-b \">\n <div class=\"my-2 border-b flex flex-row\"\n *ngFor=\"let item of heatmapChartConfig.columns; let i = index;\">\n <div class=\"px-1 mb-2 mt-6 w-full\">\n <dx-check-box [value]=\"item.visible\" [(ngModel)]=\"item.visible\"\n text=\"Visiblity\"></dx-check-box>\n </div>\n\n <div class=\"px-1 mb-2 w-full\">\n <div class=\"text-md mb-2\"> Value Field</div>\n <dx-select-box [searchEnabled]=\"true\" [items]=\"configColume\"\n [(ngModel)]=\"item.dataField\"></dx-select-box>\n </div>\n <div class=\"px-1 mb-2 w-full\">\n <div class=\"text-md mb-2\"> Caption</div>\n <dx-text-box [(ngModel)]=\"item.caption\"></dx-text-box>\n </div>\n <div class=\"px-2 mb-2 w-full\">\n <div class=\"text-md mb-2\"> UI Function</div>\n <dx-select-box [items]=\"enrichNameList\" [(ngModel)]=\"item.enrichName\"\n [searchEnabled]=\"true\"></dx-select-box>\n </div>\n\n\n </div>\n </div>\n </div>\n </div>\n </div>\n <div *ngIf=\"activeTab === 'properties'\">\n <div class=\"h-full overflow-x-auto\">\n <app-loader *ngIf=\"isLoader\"></app-loader>\n <ng-container *ngIf=\"!isLoader\">\n <div class=\"flex flex-row justify-between border-b py-3\">\n <div class=\"mx-2\">\n <dx-check-box [value]=\"viewProperties.enableClickEvent\"\n [(ngModel)]=\"viewProperties.enableClickEvent\"\n text=\"Enable Click Event\"></dx-check-box>\n </div>\n <div class=\"mx-2\">\n <dx-check-box [value]=\"viewProperties.enableRightClickEvent\"\n [(ngModel)]=\"viewProperties.enableRightClickEvent\"\n text=\"Enable Right Click\"></dx-check-box>\n </div>\n </div>\n <div class=\"w-full p-2\" *ngIf=\"viewProperties.enableClickEvent\">\n\n <div class=\"flex flex-col flex-auto min-w-0 my-2\">\n <div class=\"text-sm py-1 font-extrabold border-b bg-gray-700 text-white px-2\"> Event\n Type\n Option\n </div>\n <div class=\"w-full p-3 border-x border-b \">\n <div class=\"flex flex-row\">\n <div class=\"w-full\">\n <div class=\"text-md mb-2\"> Event Type</div>\n </div>\n <div class=\"w-full\">\n <dx-select-box\n [items]=\"['drilldown','sameViewDrilldown','optionalDrillDown']\"\n (onValueChanged)=\"getSelectedEventType($event)\"\n [(ngModel)]=\"viewProperties.clickEventOptions.eventType\"></dx-select-box>\n </div>\n </div>\n <ng-container *ngIf=\"viewProperties.clickEventOptions.eventType == 'drilldown'\">\n <div class=\"flex flex-row justify-between mt-3\">\n <div class=\"w-full\">\n <div class=\"text-md mb-2\"> Associated Views</div>\n <dx-tag-box [items]=\"allConfiguredViews\"\n [(ngModel)]=\"viewProperties.clickEventOptions.associatedViews\"\n valueExpr=\"viewId\" displayExpr=\"viewName\"\n [showSelectionControls]=\"true\" [searchEnabled]=\"true\"></dx-tag-box>\n </div>\n </div>\n </ng-container>\n <ng-container\n *ngIf=\"viewProperties.clickEventOptions.eventType == 'sameViewDrilldown'\">\n <div class=\"flex flex-row justify-between mt-3\">\n <div class=\"w-full\">\n <div class=\"text-md mb-2\"> Associated Views</div>\n <dx-tag-box [items]=\"allConfiguredViews\"\n [(ngModel)]=\"viewProperties.clickEventOptions.associatedViews\"\n valueExpr=\"viewId\" displayExpr=\"viewName\"\n [showSelectionControls]=\"true\" [searchEnabled]=\"true\"></dx-tag-box>\n </div>\n </div>\n </ng-container>\n <ng-container\n *ngIf=\"viewProperties.clickEventOptions.eventType == 'optionalDrillDown'\">\n <div class=\"flex flex-row justify-between mt-3\">\n <div class=\"w-full\">\n <ng-container\n *ngFor=\"let item of optionalDrilDownDataSource;let i = index;\">\n\n <div class=\"flex flex-row justify-between\">\n <div class=\"mx-2 w-1/2\">\n <div class=\"text-md mb-2\"> Associated Views</div>\n <dx-tag-box [items]=\"allConfiguredViews\"\n [(ngModel)]=\"item.viewId\" valueExpr=\"viewId\"\n displayExpr=\"viewName\" [showSelectionControls]=\"true\"\n [maxDisplayedTags]=\"2\"\n [searchEnabled]=\"true\"></dx-tag-box>\n\n </div>\n <div class=\"mx-2 w-1/2\">\n <div class=\"text-md mb-2\"> Associated Params</div>\n <dx-text-box\n [(ngModel)]=\"item.filterCondition\"></dx-text-box>\n </div>\n <div class=\"mx-2\">\n <button\n class=\"{{commonService.btn_danger_sm}} cursor-pointer mt-8\"\n (click)=\"deleteAssociatedParams(i)\"><i\n class=\"fa fa-trash-o\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n </ng-container>\n <div class=\"flex flex-row justify-end mt-4\">\n <button class=\"{{commonService.btn_primary_sm}} cursor-pointer\"\n (click)=\"addAssociatedParams()\">Add\n Params</button>\n </div>\n </div>\n </div>\n </ng-container>\n <button class=\"{{commonService.btn_light_md}} cursor-pointer mt-4\"\n (click)=\"resetViewProprstise()\">Reset All Event</button>\n </div>\n </div>\n\n </div>\n </ng-container>\n </div>\n </div>\n\n </div>\n\n\n </div>\n</div>\n\n\n<div class=\"flex flex-row border-t pl-3\">\n <div class=\"flex justify-start mx-1\">\n <button class=\"{{commonService.btn_warning_md}} cursor-pointer mt-2\" (click)=\"isJsonPreview = true\">\n Preview</button>\n <button class=\"{{commonService.btn_primary_md}} cursor-pointer mt-2\" (click)=\"isJsonPreview = false\">Data\n Preview</button>\n </div>\n <div class=\"flex justify-end mx-1 flex-grow\">\n <button class=\"{{commonService.btn_success_md}} cursor-pointer mt-2\"\n (click)=\"getSaveChartConfig()\">Submit</button>\n </div>\n</div>" }]
550
+ }], ctorParameters: function () { return [{ type: i1.ToastrService }, { type: i2.CommonService }, { type: i0.ChangeDetectorRef }, { type: i3.ApplicationContentService }]; }, propDecorators: { getHeatMapConfigOutPut: [{
551
+ type: Output
552
+ }], chartconfigData: [{
553
+ type: Input,
554
+ args: ['datasetmodal']
555
+ }] } });
556
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVhdC1tYXAuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZ2FtbWEtYXBwLWNvbnRyb2xsZXIvc3JjL2xpYi9hcHBsaWNhdGlvbi1jb250cm9sbGVyL3N1cHBvcnQtY29tcG9uZW50cy9oZWF0LW1hcC9oZWF0LW1hcC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9nYW1tYS1hcHAtY29udHJvbGxlci9zcmMvbGliL2FwcGxpY2F0aW9uLWNvbnRyb2xsZXIvc3VwcG9ydC1jb21wb25lbnRzL2hlYXQtbWFwL2hlYXQtbWFwLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBcUIsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBSWxHLE9BQU8sTUFBTSxNQUFNLHVCQUF1QixDQUFDOzs7Ozs7Ozs7Ozs7O0FBTTNDLE1BQU0sT0FBTyx1QkFBdUI7SUEwTGhDLFlBQ1ksYUFBNEIsRUFDN0IsYUFBNEIsRUFDM0IsR0FBc0IsRUFBVSxPQUFrQztRQUZsRSxrQkFBYSxHQUFiLGFBQWEsQ0FBZTtRQUM3QixrQkFBYSxHQUFiLGFBQWEsQ0FBZTtRQUMzQixRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQUFVLFlBQU8sR0FBUCxPQUFPLENBQTJCO1FBeEw5RSxvQkFBZSxHQUFZLEtBQUssQ0FBQztRQUNqQyxtQkFBYyxHQUFZLEtBQUssQ0FBQztRQUVoQyx3QkFBbUIsR0FBUSxFQUFFLENBQUM7UUFDOUIsd0JBQW1CLEdBQVEsRUFBRSxDQUFDO1FBQzlCLG1CQUFjLEdBQUcsQ0FBQyxrQkFBa0IsRUFBRSxrQkFBa0IsRUFBRSxtQkFBbUIsRUFBRSxrQ0FBa0MsRUFBRSxlQUFlLENBQUMsQ0FBQTtRQUVuSSx1QkFBa0IsR0FBRztZQUNqQixhQUFhLEVBQUUsRUFBRTtZ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QUFDLGtCQUFrQixDQUFDO1FBQzlFLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLHNCQUFzQixDQUFDLENBQUM7SUFDbEUsQ0FBQzs7b0hBNW1CUSx1QkFBdUI7d0dBQXZCLHVCQUF1QixxTENWcEMscXZuQkF3VE07MkZEOVNPLHVCQUF1QjtrQkFKbkMsU0FBUzsrQkFDSSxjQUFjO3dNQXFNUCxzQkFBc0I7c0JBQXRDLE1BQU07Z0JBR0gsZUFBZTtzQkFEbEIsS0FBSzt1QkFBQyxjQUFjIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0b3JSZWYsIENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT25Jbml0LCBPdXRwdXQgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgVG9hc3RyU2VydmljZSB9IGZyb20gXCJuZ3gtdG9hc3RyXCI7XG5pbXBvcnQgeyBBcHBsaWNhdGlvbkNvbnRlbnRTZXJ2aWNlIH0gZnJvbSBcIi4uLy4uL2FwcGxpY2F0aW9uLWNvbnRlbnQuc2VydmljZVwiO1xuaW1wb3J0IHsgQ29tbW9uU2VydmljZSB9IGZyb20gXCIuLi8uLi9jb21tb25cIjtcbmltcG9ydCBtb21lbnQgZnJvbSAnLi8uLi8uLi9tb21lbnQtaGVscGVyJztcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdhcHAtaGVhdC1tYXAnLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9oZWF0LW1hcC5jb21wb25lbnQuaHRtbCcsXG59KVxuZXhwb3J0IGNsYXNzIEhlYXRNYXBTdXBwb3J0Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgICBpc0hlYXRNYXBMb2FkZXI6IGJvb2xlYW47XG5cblxuXG4gICAgaXNBZHZhbmNlRmlsdGVyOiBib29sZWFuID0gZmFsc2U7XG4gICAgaXNIZWF0TWFwQ2xpY2s6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIGhlYXRDaGFydERhdGFTb3VyY2U6IGFueSA9IHt9O1xuICAgIGNoYXJ0RGF0YUZvclRvb2x0aXA6IGFueSA9IHt9O1xuICAgIGVucmljaE5hbWVMaXN0ID0gW1wiYWJicmV2aWF0ZU51bWJlclwiLCBcImdldENvbG9yQ29kZVNwYW5cIiwgXCJUaG91c2FuZFNlcGFyYXRvclwiLCBcIlRob3VzYW5kU2VwYXJhdG9yV2l0aFR3b0RlY2ltYWxzXCIsIFwiZm9ybWF0Qnl0ZXN2MlwiXVxuXG4gICAgaGVhdG1hcENoYXJ0Q29uZmlnID0ge1xuICAgICAgICBcImNoYXJ0Rm9ybWF0XCI6IFwiXCIsXG4gICAgICAgIFwidG9wQXJndW1lbnRcIjogXCJcIixcbiAgICAgICAgXCJsZWZ0QXJndW1lbnRcIjogXCJcIixcbiAgICAgICAgXCJjb2xvclwiOiBbXSxcbiAgICAgICAgXCJ0eXBlXCI6IFwiXCIsXG4gICAgICAgIFwiZm9ybWF0ZVwiOiBcIlwiLFxuICAgICAgICBcImNvbHVtbnNcIjogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwidmlzaWJsZVwiOiB0cnVlLFxuICAgICAgICAgICAgICAgIFwiZGF0YUZpZWxkXCI6IFwiXCIsXG4gICAgICAgICAgICAgICAgXCJjYXB0aW9uXCI6IFwiXCIsXG4gICAgICAgICAgICAgICAgXCJlbnJpY2hOYW1lXCI6IFwiXCIsXG4gICAgICAgICAgICB9XG4gICAgICAgIF0sXG4gICAgICAgIFwiY29tbW9uQ29uZmlnXCI6IHtcbiAgICAgICAgICAgIFwidGl0bGVcIjogXCJcIixcbiAgICAgICAgICAgIFwiZGF0YUZpZWxkXCI6IFwiXCIsXG4gICAgICAgICAgICBcImNoZWNrZWRLZXlcIjogXCJcIixcbiAgICAgICAgICAgIFwiaXNTZWFyY2hCb3hcIjogZmFsc2VcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGhlYXRtYXBfY29udGVudF9jb25maWcgPSB7XG4gICAgICAgIFwia3BpQ29uZmlnXCI6IHtcbiAgICAgICAgICAgIFwic2VydmljZUlkXCI6IFwiXCIsXG4gICAgICAgICAgICBcImFwaVwiOiBcIi9rcGkvdHJlbmRzL25ldHdvcmsvZ2V0LW1ldHJpYy1kYXRhXCIsXG4gICAgICAgICAgICBcImRpc3BsYXlUeXBlXCI6IFwidGFibGVcIixcbiAgICAgICAgICAgIFwiZm9ybWF0ZVwiOiBcIlwiLFxuICAgICAgICAgICAgXCJrZXlUb1Bhc3NcIjogW10sXG4gICAgICAgICAgICBcImNvbXBvbmVudE5hbWVcIjogXCJHYW1tYUhlYXRDaGFydENvbXBvbmVudFwiLFxuICAgICAgICAgICAgXCJkYXRhQ29uZmlnXCI6IHt9XG4gICAgICAgIH0sXG4gICAgfTtcbiAgICBpc0pzb25QcmV2aWV3OiBib29sZWFuXG4gICAgZGF0YVNvdXJzZUZvckhlYXRNYXA6IGFueSA9IFtdO1xuICAgIGNvbmZpZ0NvbHVtZTogYW55O1xuICAgIGpzYW9uRGF0YXNvdXJjZTogYW55O1xuICAgIHNlbGVjdGVkVmlld0NvbmZpZ3M6IGFueTtcblxuICAgIHZpZXdQcm9wZXJ0aWVzOiBhbnkgPSB7XG4gICAgICAgIGVuYWJsZUNsaWNrRXZlbnQ6IGZhbHNlLFxuICAgICAgICBlbmFibGVSaWdodENsaWNrRXZlbnQ6IHRydWUsXG4gICAgICAgIGNsaWNrRXZlbnRPcHRpb25zOiB7XG4gICAgICAgICAgICBhc3NvY2lhdGVkVmlld3M6IFtdLFxuICAgICAgICAgICAgZXZlbnRUeXBlOiBcIlwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIG9wdGlvbmFsRHJpbERvd25EYXRhU291cmNlOiBhbnkgPSBbXTtcbiAgICBzZWxlY3RlZFRhYmxlVmlld1R5cGU6IGFueTtcbiAgICBpc0xvYWRlcjogYm9vbGVhbiA9IHRydWU7XG5cbiAgICBhY3RpdmVUYWI6IHN0cmluZyA9ICdiYXNpYyc7XG4gICAgYWxsQ29uZmlndXJlZFZpZXdzOiBhbnkgPSBbXTtcbiAgICBjb2xvckFycmF5OiBhbnkgPSBbXTtcbiAgICBmaXJzdENvbG9yID0gXCJyZ2JhKDQ1LCAxMTAsIDE4LCAxKVwiO1xuICAgIHNlY29uZENvbG9yID0gXCJyZ2JhKDI1NSwgMjA0LCAwLCAxKVwiO1xuICAgIHNpbmdsZUNvbG9yID0gXCJyZ2JhKDI1NSwgMjA0LCAwLCAxKVwiO1xuXG4gICAgdGVzdF92b2ljZV9kYXRhID0gW3tcbiAgICAgICAgcmVjb3JkX2RhdGU6ICcyMDI1MDUyNycsXG4gICAgICAgIGRhdGFzZXQ6IFtcbiAgICAgICAgICAgIHsgb3RoZXJfcGFydHlfaXNvOiAnWUVNJywgdG90YWxfY2hhcmdlOiAxODQzNTcxNzYgfSxcbiAgICAgICAgICAgIHsgb3RoZXJfcGFydHlfaXNvOiAnRVJJJywgdG90YWxfY2hhcmdlOiAxMTUyNjI1MDAgfSxcbiAgICAgICAgICAgIHsgb3RoZXJfcGFydHlfaXNvOiAnQkdEJywgdG90YWxfY2hhcmdlOiA4MzI4OTYxNCB9LFxuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdFVEgnLCB0b3RhbF9jaGFyZ2U6IDc5MDA0NTAwIH0sXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ1BBSycsIHRvdGFsX2NoYXJnZTogNzY5OTI0NTQgfSxcbiAgICAgICAgICAgIHsgb3RoZXJfcGFydHlfaXNvOiAnU0ROJywgdG90YWxfY2hhcmdlOiA2MDQ4MDQwMCB9LFxuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdJTkQnLCB0b3RhbF9jaGFyZ2U6IDM4ODkyODU4IH0sXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ0VHWScsIHRvdGFsX2NoYXJnZTogMzc3Njk3NDQgfSxcbiAgICAgICAgICAgIHsgb3RoZXJfcGFydHlfaXNvOiAnTlBMJywgdG90YWxfY2hhcmdlOiAxNzIxNDAwMCB9LFxuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdBRkcnLCB0b3RhbF9jaGFyZ2U6IDcyNjgwMDAgfSxcbiAgICAgICAgICAgIHsgb3RoZXJfcGFydHlfaXNvOiAnVENEJywgdG90YWxfY2hhcmdlOiA1MzcyNTAwIH0sXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ0lETicsIHRvdGFsX2NoYXJnZTogNDQyNTcwMCB9LFxuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdVR0EnLCB0b3RhbF9jaGFyZ2U6IDM5MzMzMDAgfSxcbiAgICAgICAgICAgIHsgb3RoZXJfcGFydHlfaXNvOiAnR0JSJywgdG90YWxfY2hhcmdlOiAzODQ4MjI1IH1cbiAgICAgICAgXVxuICAgIH0sXG4gICAge1xuICAgICAgICByZWNvcmRfZGF0ZTogJzIwMjUwNTMxJyxcbiAgICAgICAgZGF0YXNldDogW1xuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdZRU0nLCB0b3RhbF9jaGFyZ2U6IDIwODY5OTgyNyB9LFxuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdFUkknLCB0b3RhbF9jaGFyZ2U6IDE0MzUwMTUwMCB9LFxuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdCR0QnLCB0b3RhbF9jaGFyZ2U6IDEwNjI5NjI5NCB9LFxuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdFVEgnLCB0b3RhbF9jaGFyZ2U6IDg2MDkzNTAwIH0sXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ1BBSycsIHRvdGFsX2NoYXJnZTogNzc0Mjg0NjEgfSxcbiAgICAgICAgICAgIHsgb3RoZXJfcGFydHlfaXNvOiAnU0ROJywgdG90YWxfY2hhcmdlOiA2NTgxODU5OCB9LFxuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdJTkQnLCB0b3RhbF9jaGFyZ2U6IDM4NjM1MTc1IH0sXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ0VHWScsIHRvdGFsX2NoYXJnZTogMzc2NTg3MDAgfSxcbiAgICAgICAgICAgIHsgb3RoZXJfcGFydHlfaXNvOiAnTlBMJywgdG90YWxfY2hhcmdlOiAxODc3MzIwMCB9LFxuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdBRkcnLCB0b3RhbF9jaGFyZ2U6IDgyMzI1MDAgfSxcbiAgICAgICAgICAgIHsgb3RoZXJfcGFydHlfaXNvOiAnVENEJywgdG90YWxfY2hhcmdlOiA3MDA3NTAwIH0sXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ0FSRScsIHRvdGFsX2NoYXJnZTogNDU5MzgwMCB9LFxuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdJRE4nLCB0b3RhbF9jaGFyZ2U6IDQxMTg4MDAgfSxcbiAgICAgICAgICAgIHsgb3RoZXJfcGFydHlfaXNvOiAnUEhMJywgdG90YWxfY2hhcmdlOiA0MDUxNTAwIH1cbiAgICAgICAgXVxuICAgIH0sXG4gICAge1xuICAgICAgICByZWNvcmRfZGF0ZTogJzIwMjUwNTI4JyxcbiAgICAgICAgZGF0YXNldDogW1xuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdZRU0nLCB0b3RhbF9jaGFyZ2U6IDE5ODk0MzY2MSB9LFxuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdFUkknLCB0b3RhbF9jaGFyZ2U6IDExODA2NTAwMCB9LFxuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdCR0QnLCB0b3RhbF9jaGFyZ2U6IDkwOTgwODI5IH0sXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ0VUSCcsIHRvdGFsX2NoYXJnZTogODAzNjc3MDAgfSxcbiAgICAgICAgICAgIHsgb3RoZXJfcGFydHlfaXNvOiAnUEFLJywgdG90YWxfY2hhcmdlOiA3ODAxODk3MyB9LFxuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdTRE4nLCB0b3RhbF9jaGFyZ2U6IDU2ODI2NTAwIH0sXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ0lORCcsIHRvdGFsX2NoYXJnZTogMzc4NzE2MjUgfSxcbiAgICAgICAgICAgIHsgb3RoZXJfcGFydHlfaXNvOiAnRUdZJywgdG90YWxfY2hhcmdlOiAzMzM3NDgxNSB9LFxuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdOUEwnLCB0b3RhbF9jaGFyZ2U6IDE2NzYzNDAwIH0sXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ0FGRycsIHRvdGFsX2NoYXJnZTogNzkyNjAwMCB9LFxuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdUQ0QnLCB0b3RhbF9jaGFyZ2U6IDU2MDAwMDAgfSxcbiAgICAgICAgICAgIHsgb3RoZXJfcGFydHlfaXNvOiAnSUROJywgdG90YWxfY2hhcmdlOiA0NjAyNDAwIH0sXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ0dCUicsIHRvdGFsX2NoYXJnZTogNDQ0MzYyNSB9LFxuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdVR0EnLCB0b3RhbF9jaGFyZ2U6IDQzNzkyMDAgfVxuICAgICAgICBdXG4gICAgfSxcbiAgICB7XG4gICAgICAgIHJlY29yZF9kYXRlOiAnMjAyNTA1MzAnLFxuICAgICAgICBkYXRhc2V0OiBbXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ1lFTScsIHRvdGFsX2NoYXJnZTogMjMxMzc4ODUyIH0sXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ0JHRCcsIHRvdGFsX2NoYXJnZTogMTUxNzg2MDE4IH0sXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ0VSSScsIHRvdGFsX2NoYXJnZTogMTQ2NzgyNTAwIH0sXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ1BBSycsIHRvdGFsX2NoYXJnZTogODgwNTQ0NDUgfSxcbiAgICAgICAgICAgIHsgb3RoZXJfcGFydHlfaXNvOiAnRVRIJywgdG90YWxfY2hhcmdlOiA4MzYzNTUwMCB9LFxuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdTRE4nLCB0b3RhbF9jaGFyZ2U6IDYyMjU3MDAwIH0sXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ0lORCcsIHRvdGFsX2NoYXJnZTogNDQzMTY1MDAgfSxcbiAgICAgICAgICAgIHsgb3RoZXJfcGFydHlfaXNvOiAnRUdZJywgdG90YWxfY2hhcmdlOiAyOTg5NDM5MiB9LFxuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdOUEwnLCB0b3RhbF9jaGFyZ2U6IDIzMzgzNTAwIH0sXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ0FGRycsIHRvdGFsX2NoYXJnZTogODAyOTUwMCB9LFxuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdUQ0QnLCB0b3RhbF9jaGFyZ2U6IDczMjI1MDAgfSxcbiAgICAgICAgICAgIHsgb3RoZXJfcGFydHlfaXNvOiAnR0JSJywgdG90YWxfY2hhcmdlOiA0MzM4NDUwIH0sXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ0lETicsIHRvdGFsX2NoYXJnZTogMzkwNDQwMCB9LFxuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdBUkUnLCB0b3RhbF9jaGFyZ2U6IDM4MzIxMDAgfVxuICAgICAgICBdXG4gICAgfSxcbiAgICB7XG4gICAgICAgIHJlY29yZF9kYXRlOiAnMjAyNTA1MjknLFxuICAgICAgICBkYXRhc2V0OiBbXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ1lFTScsIHRvdGFsX2NoYXJnZTogMjAwOTA2MzU3IH0sXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ0VSSScsIHRvdGFsX2NoYXJnZTogMTI2NzI1MDAwIH0sXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ0JHRCcsIHRvdGFsX2NoYXJnZTogMTE1Mjg3NzIyIH0sXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ0VUSCcsIHRvdGFsX2NoYXJnZTogODIwNjI0MDAgfSxcbiAgICAgICAgICAgIHsgb3RoZXJfcGFydHlfaXNvOiAnUEFLJywgdG90YWxfY2hhcmdlOiA3NzI2MDYxMCB9LFxuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdTRE4nLCB0b3RhbF9jaGFyZ2U6IDU0Mzk0ODEwIH0sXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ0lORCcsIHRvdGFsX2NoYXJnZTogMzg2NTQwMDAgfSxcbiAgICAgICAgICAgIHsgb3RoZXJfcGFydHlfaXNvOiAnRUdZJywgdG90YWxfY2hhcmdlOiAzNDUwMzM1MCB9LFxuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdOUEwnLCB0b3RhbF9jaGFyZ2U6IDE3Mjc3MTAwIH0sXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ0FGRycsIHRvdGFsX2NoYXJnZTogNzc0NjUwMCB9LFxuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdUQ0QnLCB0b3RhbF9jaGFyZ2U6IDYxMDAwMDAgfSxcbiAgICAgICAgICAgIHsgb3RoZXJfcGFydHlfaXNvOiAnR0JSJywgdG90YWxfY2hhcmdlOiA0NzM2MTUwIH0sXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ0lETicsIHRvdGFsX2NoYXJnZTogNDY3ODkwMCB9LFxuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdLRU4nLCB0b3RhbF9jaGFyZ2U6IDQ0NTMwMDAgfVxuICAgICAgICBdXG4gICAgfSxcbiAgICB7XG4gICAgICAgIHJlY29yZF9kYXRlOiAnMjAyNTA2MDEnLFxuICAgICAgICBkYXRhc2V0OiBbXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ1lFTScsIHRvdGFsX2NoYXJnZTogMjE0Mjg3OTc4IH0sXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ0VSSScsIHRvdGFsX2NoYXJnZTogMTU0NDAyNTAwIH0sXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ0JHRCcsIHRvdGFsX2NoYXJnZTogMTAwMjA0MDAwIH0sXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ0VUSCcsIHRvdGFsX2NoYXJnZTogOTc0Nzk4MDAgfSxcbiAgICAgICAgICAgIHsgb3RoZXJfcGFydHlfaXNvOiAnUEFLJywgdG90YWxfY2hhcmdlOiA3NTM5MTQ2MyB9LFxuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdTRE4nLCB0b3RhbF9jaGFyZ2U6IDY1NjIyMjAwIH0sXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ0lORCcsIHRvdGFsX2NoYXJnZTogMzgxMjQ0OTcgfSxcbiAgICAgICAgICAgIHsgb3RoZXJfcGFydHlfaXNvOiAnRUdZJywgdG90YWxfY2hhcmdlOiAzNTI3ODAyNSB9LFxuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdOUEwnLCB0b3RhbF9jaGFyZ2U6IDIyNjY1MDAwIH0sXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ0FGRycsIHRvdGFsX2NoYXJnZTogNjkyMDAwMCB9LFxuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdVR0EnLCB0b3RhbF9jaGFyZ2U6IDU2MjUxMDAgfSxcbiAgICAgICAgICAgIHsgb3RoZXJfcGFydHlfaXNvOiAnSUROJywgdG90YWxfY2hhcmdlOiA1MjU2OTAwIH0sXG4gICAgICAgICAgICB7IG90aGVyX3BhcnR5X2lzbzogJ1RDRCcsIHRvdGFsX2NoYXJnZTogNDk3MDAwMCB9LFxuICAgICAgICAgICAgeyBvdGhlcl9wYXJ0eV9pc286ICdHQlInLCB0b3RhbF9jaGFyZ2U6IDQ0MTAyNTAgfVxuICAgICAgICBdXG4gICAgfVxuICAgIF1cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSB0b2FzdHJTZXJ2aWNlOiBUb2FzdHJTZXJ2aWNlLFxuICAgICAgICBwdWJsaWMgY29tbW9uU2VydmljZTogQ29tbW9uU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmLCBwcml2YXRlIHNlcnZpY2U6IEFwcGxpY2F0aW9uQ29udGVudFNlcnZpY2VcbiAgICApIHtcblxuICAgIH1cblxuICAgIEBPdXRwdXQoKSBwdWJsaWMgZ2V0SGVhdE1hcENvbmZpZ091dFB1dDogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICBASW5wdXQoJ2RhdGFzZXRtb2RhbCcpXG4gICAgc2V0IGNoYXJ0Y29uZmlnRGF0YSh2YWx1ZSkge1xuICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuanNhb25EYXRhc291cmNlID0gdmFsdWUuZGF0YVswXTtcbiAgICAgICAgICAgIHRoaXMuY29uZmlnQ29sdW1lID0gT2JqZWN0LmtleXModmFsdWUuZGF0YVswXSk7XG4gICAgICAgICAgICB0aGlzLmRhdGFTb3Vyc2VGb3JIZWF0TWFwID0gdmFsdWUuZGF0YTtcbiAgICAgICAgICAgIC8vIHRoaXMuZGF0YVNvdXJzZUZvckhlYXRNYXAgPSB0aGlzLnRlc3Rfdm9pY2VfZGF0YTtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRWaWV3Q29uZmlncyA9IHZhbHVlO1xuXG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkVGFibGVWaWV3VHlwZSA9IHZhbHVlLnNlbGVjdGVkVmlld1R5cGU7XG4gICAgICAgICAgICBpZiAodmFsdWUuc2VsZWN0ZWRXaWRnZXRDb25maWcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmhlYXRtYXBfY29udGVudF9jb25maWdbJ2twaUNvbmZpZyddID0gdmFsdWUuc2VsZWN0ZWRXaWRnZXRDb25maWc7XG4gICAgICAgICAgICAgICAgdGhpcy5oZWF0bWFwQ2hhcnRDb25maWcgPSB2YWx1ZS5zZWxlY3RlZFdpZGdldENvbmZpZy5kYXRhQ29uZmlnO1xuICAgICAgICAgICAgICAgIHRoaXMuaGVhdG1hcENoYXJ0Q29uZmlnLmNvbHVtbnMgPSB2YWx1ZS5zZWxlY3RlZFdpZGdldENvbmZpZy5kYXRhQ29uZmlnLmNvbHVtbnM7XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlLnNlbGVjdGVkV2lkZ2V0Q29uZmlnLnZpZXdQcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmlld1Byb3BlcnRpZXMgPSB2YWx1ZS5zZWxlY3RlZFdpZGdldENvbmZpZy52aWV3UHJvcGVydGllcztcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhpcy52aWV3UHJvcGVydGllcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gICBcImVuYWJsZUNsaWNrRXZlbnRcIjogdmFsdWUuc2VsZWN0ZWRXaWRnZXRDb25maWcudmlld1Byb3BlcnRpZXMuZW5hYmxlQ2xpY2tFdmVudCxcbiAgICAgICAgICAgICAgICAgICAgLy8gICBcImVuYWJsZVJpZ2h0Q2xpY2tFdmVudFwiOiB2YWx1ZS5zZWxlY3RlZFdpZGdldENvbmZpZy52aWV3UHJvcGVydGllcy5lbmFibGVSaWdodENsaWNrRXZlbnRcbiAgICAgICAgICAgICAgICAgICAgLy8gfVxuICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUuc2VsZWN0ZWRXaWRnZXRDb25maWcudmlld1Byb3BlcnRpZXMuZW5hYmxlQ2xpY2tFdmVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlLnNlbGVjdGVkV2lkZ2V0Q29uZmlnLnZpZXdQcm9wZXJ0aWVzLmNsaWNrRXZlbnRPcHRpb25zLmV2ZW50VHlwZSA9PSAnb3B0aW9uYWxEcmlsbERvd24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vcHRpb25hbERyaWxEb3duRGF0YVNvdXJjZSA9IHZhbHVlLnNlbGVjdGVkV2lkZ2V0Q29uZmlnLnZpZXdQcm9wZXJ0aWVzLmNsaWNrRXZlbnRPcHRpb25zLmFzc29jaWF0ZWRWaWV3cztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZXdQcm9wZXJ0aWVzWydjbGlja0V2ZW50T3B0aW9ucyddID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImV2ZW50VHlwZVwiOiB2YWx1ZS5zZWxlY3RlZFdpZGdldENvbmZpZy52aWV3UHJvcGVydGllcy5jbGlja0V2ZW50T3B0aW9ucy5ldmVudFR5cGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiYXNzb2NpYXRlZFZpZXdzXCI6IFtdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZS5zZWxlY3RlZFdpZGdldENvbmZpZy52aWV3UHJvcGVydGllcy5jbGlja0V2ZW50T3B0aW9ucy5ldmVudFR5cGUgPT0gJ2RyaWxsZG93bicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZXdQcm9wZXJ0aWVzWydjbGlja0V2ZW50T3B0aW9ucyddID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImV2ZW50VHlwZVwiOiB2YWx1ZS5zZWxlY3RlZFdpZGdldENvbmZpZy52aWV3UHJvcGVydGllcy5jbGlja0V2ZW50T3B0aW9ucy5ldmVudFR5cGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiYXNzb2NpYXRlZFZpZXdzXCI6IHZhbHVlLnNlbGVjdGVkV2lkZ2V0Q29uZmlnLnZpZXdQcm9wZXJ0aWVzLmNsaWNrRXZlbnRPcHRpb25zLmFzc29jaWF0ZWRWaWV3c1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy52aWV3UHJvcGVydGllc1snY2xpY2tFdmVudE9wdGlvbnMnXSA9IHt9XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIH1cblxuXG4gICAgICAgICAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdQcm9wZXJ0aWVzID0ge1xuICAgICAgICAgICAgICAgICAgICBlbmFibGVDbGlja0V2ZW50OiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgZW5hYmxlUmlnaHRDbGlja0V2ZW50OiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBjbGlja0V2ZW50T3B0aW9uczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXNzb2NpYXRlZFZpZXdzOiBbXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50VHlwZTogXCJcIlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5oZWF0bWFwQ2hhcnRDb25maWcuY29sdW1ucykge1xuXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5oZWF0bWFwQ2hhcnRDb25maWcuY29sdW1ucyA9IFtdO1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHRoaXMuY29uZmlnQ29sdW1lKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5nT25Jbml0KCk6IHZvaWQge1xuXG4gICAgICAgIHRoaXMuc2VydmljZS5nZXRBcHBWaWV3Q29uZmlncygpLnN1YnNjcmliZSh7XG4gICAgICAgICAgICBuZXh0OiAoZGF0YTogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5hbGxDb25maWd1cmVkVmlld3MgPSBkYXRhO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5pc0xvYWRlciA9IGZhbHNlO1xuICAgICAgICAgICAgfSwgZXJyb3I6IChlcnI6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMudG9hc3RyU2VydmljZS5lcnJvcignVW5leHBlY3RlZCBTZXJ2ZXIgRXhjZXB0aW9uLiBQbGVhc2UgY29udGFjdCBTeXN0ZW0gQWRtaW4uJywgJ0FsbCBWaWV3cycpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbmFsRHJpbERvd25EYXRhU291cmNlLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgICAgICB0aGlzLm9wdGlvbmFsRHJpbERvd25EYXRhU291cmNlID0gW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgJ3ZpZXdJZCc6IFwiXCIsXG4gICAgICAgICAgICAgICAgICAgICdmaWx0ZXJDb25kaXRpb24nOiBcIlwiXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXVxuICAgICAgICB9XG4gICAgfVxuXG5cblxuICAgIGdldEhlYXRtYXBEYXRhKCkge1xuXG4gICAgICAgIHRoaXMuaGVhdENoYXJ0RGF0YVNvdXJjZSA9IHt9O1xuICAgICAgICB0aGlzLmlzQWR2YW5jZUZpbHRlciA9IGZhbHNlO1xuXG4gICAgICAgIGlmICh0aGlzLmRhdGFTb3Vyc2VGb3JIZWF0TWFwICYmIHRoaXMuZGF0YVNvdXJzZUZvckhlYXRNYXAubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5oZWF0bWFwQ2hhcnRDb25maWcuY2hhcnRGb3JtYXQgPT0gXCJ0b3B4XCIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB7IHJlc3VsdCwgdW5pcXVlRGF0ZXMgfSA9IHRoaXMuZ2VuZXJhdGVEYXRlV2lzZUNvbG9yQ29kZWREYXRhKHRoaXMuZGF0YVNvdXJzZUZvckhlYXRNYXApO1xuICAgICAgICAgICAgICAgIHVuaXF1ZURhdGVzLnNvcnQoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmhlYXRDaGFydERhdGFTb3VyY2UuZGF0YVNldCA9IHRoaXMuZ2V0VHJhbnNwb3NlZEhlYXRtYXBEYXRhKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgdGhpcy5oZWF0Q2hhcnREYXRhU291cmNlW1wiYXJndW1lbnRWYWx1ZVwiXSA9IHVuaXF1ZURhdGVzO1xuICAgICAgICAgICAgfSBlbHNlIGlmICgodGhpcy5oZWF0bWFwQ2hhcnRDb25maWcuY2hhcnRGb3JtYXQgPT0gXCJzaW1wbGVcIikpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB7IHJlc3VsdCwgdW5pcXVlRGF0ZXMgfSA9IHRoaXMuZ2VuZXJhdGVEYXRhKHRoaXMuZGF0YVNvdXJzZUZvckhlYXRNYXApO1xuICAgICAgICAgICAgICAgIHVuaXF1ZURhdGVzLnNvcnQoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmhlYXRDaGFydERhdGFTb3VyY2VbXCJkYXRhU2V0XCJdID0gcmVzdWx0O1xuICAgICAgICAgICAgICAgIHRoaXMuaGVhdENoYXJ0RGF0YVNvdXJjZVtcImFyZ3VtZW50VmFsdWVcIl0gPSB1bmlxdWVEYXRlcztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5pc0hlYXRNYXBMb2FkZXIgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuaXNIZWF0TWFwQ2xpY2sgPSBmYWxzZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuaXNIZWF0TWFwQ2xpY2sgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMudG9hc3RyU2VydmljZS5pbmZvKFwiTm8gRGF0YSBGb3VuZFwiKVxuICAgICAgICB9XG5cblxuXG4gICAgfVxuXG4gICAgZ2V0VHJhbnNwb3NlZEhlYXRtYXBEYXRhKGRhdGFTZXQ6IGFueVtdKTogYW55W10ge1xuICAgICAgICBjb25zdCB0cmFuc3Bvc2VkOiBhbnlbXSA9IFtdO1xuICAgICAgICBjb25zdCBtYXhCb3hlcyA9IE1hdGgubWF4KC4uLmRhdGFTZXQubWFwKGl0ZW0gPT4gaXRlbS5kYXRhc2V0Lmxlbmd0aCkpO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbWF4Qm94ZXM7IGkrKykge1xuICAgICAgICAgICAgY29uc3Qgcm93OiBhbnlbXSA9IFtdO1xuICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBkYXRhU2V0Lmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgYm94ID0gZGF0YVNldFtqXS5kYXRhc2V0W2ldO1xuICAgICAgICAgICAgICAgIHJvdy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgYm94OiBib3ggfHwgbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgZGF0ZTogZGF0YVNldFtqXS5yZWNvcmRfZGF0ZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdHJhbnNwb3NlZC5wdXNoKHJvdyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJhbnNwb3NlZDtcbiAgICB9XG5cbiAgICBnZW5lcmF0ZURhdGVXaXNlQ29sb3JDb2RlZERhdGEoZGF0YTogYW55W10pIHtcbiAgICAgICAgY29uc3QgcmVzdWx0OiBhbnlbXSA9IFtdO1xuICAgICAgICBjb25zdCB1bmlxdWVEYXRlcyA9IG5ldyBTZXQoKTtcbiAgICAgICAgY29uc3QgYWxsRW50cmllczogYW55W10gPSBbXTtcblxuICAgICAgICBjb25zdCB0b3BBcmcgPSB0aGlzLmhlYXRtYXBDaGFydENvbmZpZy50b3BBcmd1bWVudDtcbiAgICAgICAgY29uc3QgbGVmdEFyZyA9IHRoaXMuaGVhdG1hcENoYXJ0Q29uZmlnLmxlZnRBcmd1bWVudDtcbiAgICAgICAgY29uc3QgdmFsdWVGaWVsZCA9IHRoaXMuaGVhdG1hcENoYXJ0Q29uZmlnLmNvbHVtbnNbMF0uZGF0YUZpZWxkO1xuXG4gICAgICAgIGRhdGEuZm9yRWFjaChlbnRyeSA9PiB7XG4gICAgICAgICAgICBjb25zdCBmb3JtYXR0ZWREYXRlID0gbW9tZW50KGVudHJ5LnJlY29yZF9kYXRlKS5mb3JtYXQoJ1lZWVktTU0tREQnKTtcbiAgICAgICAgICAgIHVuaXF1ZURhdGVzLmFkZChmb3JtYXR0ZWREYXRlKTtcblxuICAgICAgICAgICAgZW50cnkuZGF0YXNldC5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgICAgICAgICAgIGFsbEVudHJpZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIFt0b3BBcmddOiBmb3JtYXR0ZWREYXRlLFxuICAgICAgICAgICAgICAgICAgICBbbGVmdEFyZ106IGl0ZW1bYCR7bGVmdEFyZ31gXSxcbiAgICAgICAgICAgICAgICAgICAgW3ZhbHVlRmllbGRdOiBpdGVtW2Ake3ZhbHVlRmllbGR9YF1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBsZXQgY29sb3JlZERhdGE7XG4gICAgICAgIGlmICh0aGlzLmhlYXRtYXBDaGFydENvbmZpZy50eXBlID09PSAnZ3JhZGllbnQnKSB7XG4gICAgICAgICAgICBjb2xvcmVkRGF0YSA9IHRoaXMuZ2V0Rm9ybWF0ZURhdGFCeUNvbG9yQ29kZUZvckdyYWRpZW50KGFsbEVudHJpZXMsIHZhbHVlRmllbGQpO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaGVhdG1hcENoYXJ0Q29uZmlnLnR5cGUgPT09ICd0d29Db2xvcicpIHtcbiAgICAgICAgICAgIGNvbG9yZWREYXRhID0gdGhpcy5nZXRGb3JtYXRlRGF0YUJ5Q29sb3JDb2RlRm9yV2l0aFR3b0NvbG9yKGFsbEVudHJpZXMsIHZhbHVlRmllbGQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29sb3JlZERhdGEgPSB0aGlzLmdldEZvcm1hdGVEYXRhQnlDb2xvckNvZGVGb3JXaXRoU2luZ2xlQ29sb3IoYWxsRW50cmllcywgdmFsdWVGaWVsZCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBkYXRlTWFwOiB7IFtkYXRlOiBzdHJpbmddOiBhbnlbXSB9ID0ge307XG5cbiAgICAgICAgY29sb3JlZERhdGEuZm9yRWFjaChpdGVtID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGRhdGU6IGFueSA9IGl0ZW1bdG9wQXJnXTtcblxuICAgICAgICAgICAgaWYgKCFkYXRlTWFwW2RhdGVdKSB7XG4gICAgICAgICAgICAgICAgZGF0ZU1hcFtkYXRlXSA9IFtdO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBkYXRlTWFwW2RhdGVdLnB1c2goe1xuICAgICAgICAgICAgICAgIFtsZWZ0QXJnXTogaXRlbVtsZWZ0QXJnXSxcbiAgICAgICAgICAgICAgICBbdmFsdWVGaWVsZF06IGl0ZW1bdmFsdWVGaWVsZF0sXG4gICAgICAgICAgICAgICAgY29sb3I6IGl0ZW0uY29sb3IsXG4gICAgICAgICAgICAgICAgW3RvcEFyZ106IGRhdGUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU3RlcCA0OiBCdWlsZCBmaW5hbCByZXN1bHRcbiAgICAgICAgZm9yIChjb25zdCBkYXRlIG9mIEFycmF5LmZyb20odW5pcXVlRGF0ZXMpLnNvcnQoKSBhcyBzdHJpbmdbXSkge1xuICAgICAgICAgICAgcmVzdWx0LnB1c2goe1xuICAgICAgICAgICAgICAgIHJlY29yZF9kYXRlOiBkYXRlLFxuICAgICAgICAgICAgICAgIGRhdGFzZXQ6IGRhdGVNYXBbZGF0ZV0gfHwgW11cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlc3VsdCxcbiAgICAgICAgICAgIHVuaXF1ZURhdGVzOiBBcnJheS5mcm9tKHVuaXF1ZURhdGVzKS5zb3J0KClcbiAgICAgICAgfTtcbiAgICB9XG5cblxuICAgIGdlbmVyYXRlRGF0YShkYXRhKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IFtdO1xuICAgICAgICBjb25zdCB1bmlxdWVEYXRlcyA9IG5ldyBTZXQoKTtcbiAgICAgICAgY29uc3QgZGF0YVNvdXJjZU1hcCA9IHt9O1xuICAgICAgICBjb25zdCB0b3BBcmcgPSB0aGlzLmhlYXRtYXBDaGFydENvbmZpZy50b3BBcmd1bWVudDtcbiAgICAgICAgY29uc3QgbGVmdEFyZyA9IHRoaXMuaGVhdG1hcENoYXJ0Q29uZmlnLmxlZnRBcmd1bWVudDtcblxuICAgICAgICBkYXRhLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgICAgICBjb25zdCByb3dLZXkgPSBpdGVtW2xlZnRBcmddO1xuICAgICAgICAgICAgY29uc3QgY29sdW1uS2V5ID0gbW9tZW50KGl0ZW1bdG9wQXJnXSkuZm9ybWF0KCdZWVlZLU1NLUREJyk7XG5cbiAgICAgICAgICAgIGlmICghZGF0YVNvdXJjZU1hcFtyb3dLZXldKSB7XG4gICAgICAgICAgICAgICAgZGF0YVNvdXJjZU1hcFtyb3dLZXldID0ge1xuICAgICAgICAgICAgICAgICAgICBkYXRhc291cmNlOiByb3dLZXksXG4gICAgICAgICAgICAgICAgICAgIGRhdGFzZXQ6IFtdXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZGF0YVNvdXJjZU1hcFtyb3dLZXldLmRhdGFzZXQucHVzaCh7XG4gICAgICAgICAgICAgICAgLi4uaXRlbSxcbiAgICAgICAgICAgICAgICBbdG9wQXJnXTogY29sdW1uS2V5XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgdW5pcXVlRGF0ZXMuYWRkKGNvbHVtbktleSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHVuaXF1ZURhdGVzQXJyYXkgPSBBcnJheS5mcm9tKHVuaXF1ZURhdGVzKTtcblxuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBkYXRhU291cmNlTWFwKSB7XG4gICAgICAgICAgICBjb25zdCBkYXRhc2V0ID0gZGF0YVNvdXJjZU1hcFtrZXldLmRhdGFzZXQ7XG4gICAgICAgICAgICBsZXQgZm9ybWF0dGVkRGF0YXNldDtcblxuICAgICAgICAgICAgaWYgKHRoaXMuaGVhdG1hcENoYXJ0Q29uZmlnLnR5cGUgPT0gXCJncmFkaWVudFwiKSB7XG4gICAgICAgICAgICAgICAgZm9ybWF0dGVkRGF0YXNldCA9IHRoaXMuZ2V0Rm9ybWF0ZURhdGFCeUNvbG9yQ29kZUZvckdyYWRpZW50KGRhdGFzZXQsIHRoaXMuaGVhdG1hcENoYXJ0Q29uZmlnLmNvbHVtbnNbMF0uZGF0YUZpZWxkKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5oZWF0bWFwQ2hhcnRDb25maWcudHlwZSA9PSBcInR3b0NvbG9yXCIpIHtcbiAgICAgICAgICAgICAgICBmb3JtYXR0ZWREYXRhc2V0ID0gdGhpcy5nZXRGb3JtYXRlRGF0YUJ5Q29sb3JDb2RlRm9yV2l0aFR3b0NvbG9yKGRhdGFzZXQsIHRoaXMuaGVhdG1hcENoYXJ0Q29uZmlnLmNvbHVtbnNbMF0uZGF0YUZpZWxkKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZm9ybWF0dGVkRGF0YXNldCA9IHRoaXMuZ2V0Rm9ybWF0ZURhdGFCeUNvbG9yQ29kZUZvcldpdGhTaW5nbGVDb2xvcihkYXRhc2V0LCB0aGlzLmhlYXRtYXBDaGFydENvbmZpZy5jb2x1bW5zWzBdLmRhdGFGaWVsZCk7XG5cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgZGF0ZVRvSXRlbU1hcCA9IHt9O1xuICAgICAgICAgICAgZm9ybWF0dGVkRGF0YXNldC5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgICAgICAgICAgIGRhdGVUb0l0ZW1NYXBbaXRlbVt0b3BBcmddXSA9IGl0ZW07XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY29uc3QgY29tcGxldGVEYXRhc2V0ID0gdW5pcXVlRGF0ZXNBcnJheS5tYXAoKGRhdGU6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChkYXRlVG9JdGVtTWFwW2RhdGVdKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRlVG9JdGVtTWFwW2RhdGVdO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBbdG9wQXJnXTogZGF0ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGF2Z1NpemU6IFwiTm8gRGF0YVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgZmlsZUNvdW50OiAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgZmlsZVNpemU6IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2xvcjogXCJyZ2IoMjQyLCAxMTgsIDEwOSlcIlxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICByZXN1bHQucHVzaCh7XG4gICAgICAgICAgICAgICAgZGF0YXNvdXJjZToga2V5LFxuICAgICAgICAgICAgICAgIGRhdGFzZXQ6IGNvbXBsZXRlRGF0YXNldFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVzdWx0OiByZXN1bHQsXG4gICAgICAgICAgICB1bmlxdWVEYXRlczogdW5pcXVlRGF0ZXNBcnJheVxuICAgICAgICB9O1xuICAgIH1cblxuXG5cbiAgICBnZXRGb3JtYXRlRGF0YUJ5Q29sb3JDb2RlRm9yR3JhZGllbnQoZmlsZWRhdGEsIGNvbHVtbikge1xuICAgICAgICBmaWxlZGF0YS5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgICAgICAgaXRlbS5hdmdTaXplID0gcGFyc2VGbG9hdChpdGVtW2NvbHVtbl0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBtYXhBdmdTaXplID0gTWF0aC5tYXgoLi4uZmlsZWRhdGEubWFwKGl0ZW0gPT4gaXRlbVtjb2x1bW5dKSk7XG4gICAgICAgIGNvbnN0IG1pbkF2Z1NpemUgPSBNYXRoLm1pbiguLi5maWxlZGF0YS5tYXAoaXRlbSA9PiBpdGVtW2NvbHVtbl0pKTtcblxuICAgICAgICBjb25zdCBbbWluQ29sb3JTdHIsIG1heENvbG9yU3RyXSA9IHRoaXMuY29sb3JBcnJheSB8fCBbXCJyZ2JhKDQ1LCAxMTAsIDE4LDEpXCIsIFwicmdiYSgyNTUsIDIwNCwgMCwxKVwiXTtcbiAgICAgICAgY29uc3QgbWluQ29sb3IgPSB0aGlzLnBhcnNlUkdCQShtaW5Db2xvclN0cik7XG4gICAgICAgIGNvbnN0IG1heENvbG9yID0gdGhpcy5wYXJzZVJHQkEobWF4Q29sb3JTdHIpO1xuXG4gICAgICAgIGZpbGVkYXRhLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgICAgICBpdGVtLmNvbG9yID0gdGhpcy5jYWxjdWxhdGVDb2xvcihpdGVtW2NvbHVtbl0sIG1pbkF2Z1NpemUsIG1heEF2Z1NpemUsIG1pbkNvbG9yLCBtYXhDb2xvcik7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBmaWxlZGF0YTtcbiAgICB9XG4gICAgZ2V0Rm9ybWF0ZURhdGFCeUNvbG9yQ29kZUZvcldpdGhUd29Db2xvcihmaWxlZGF0YSwgY29sdW1uKSB7XG4gICAgICAgIGZpbGVkYXRhLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgICAgICBpdGVtW2NvbHVtbl0gPSBwYXJzZUZsb2F0KGl0ZW1bY29sdW1uXSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IFttaW5Db2xvclN0ciwgbWF4Q29sb3JTdHJdID0gdGhpcy5jb2xvckFycmF5IHx8IFtcInJnYmEoNDUsIDExMCwgMTgsMSlcIiwgXCJyZ2JhKDI1NSwgMjA0LCAwLDEpXCJdO1xuICAgICAgICBjb25zdCBtaW5Db2xvciA9IHRoaXMucGFyc2VSR0JBKG1pbkNvbG9yU3RyKTtcbiAgICAgICAgY29uc3QgbWF4Q29sb3IgPSB0aGlzLnBhcnNlUkdCQShtYXhDb2xvclN0cik7XG5cbiAgICAgICAgZmlsZWRhdGEuZm9yRWFjaChpdGVtID0+IHtcbiAgICAgICAgICAgIGlmIChpdGVtW2NvbHVtbl0gPT0gMCkge1xuICAgICAgICAgICAgICAgIGl0ZW0uY29sb3IgPSBgcmdiKCR7bWluQ29sb3Iuam9pbignLCcpfSlgO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpdGVtLmNvbG9yID0gYHJnYigke21heENvbG9yLmpvaW4oJywnKX0pYDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gZmlsZWRhdGE7XG4gICAgfVxuICAgIGdldEZvcm1hdGVEYXRhQnlDb2xvckNvZGVGb3JXaXRoU2luZ2xlQ29sb3IoZmlsZWRhdGEsIGNvbHVtbikge1xuICAgICAgICBmaWxlZGF0YS5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgICAgICAgaXRlbVtjb2x1bW5dID0gcGFyc2VGbG9hdChpdGVtW2NvbHVtbl0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBbc2luZ2xlQ29sb3JdID0gdGhpcy5jb2xvckFycmF5IHx8IFtcInJnYmEoMjU1LCAyMDQsIDAsMSlcIl07XG4gICAgICAgIGNvbnN0IG1pbkNvbG9yID0gdGhpcy5wYXJzZVJHQkEoc2luZ2xlQ29sb3IpO1xuXG4gICAgICAgIGZpbGVkYXRhLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgICAgICBpdGVtLmNvbG9yID0gYHJnYigke21pbkNvbG9yLmpvaW4oJywnKX0pYDtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIGZpbGVkYXRhO1xuICAgIH1cblxuICAgIHBhcnNlUkdCQShjb2xvclN0cjogc3RyaW5nKTogbnVtYmVyW10ge1xuICAgICAgICBjb25zdCB2YWx1ZXMgPSBjb2xvclN0ci5tYXRjaCgvW1xcZC5dKy9nKT8ubWFwKE51bWJlcikgfHwgW107XG4gICAgICAgIGlmICh2YWx1ZXMubGVuZ3RoID09PSAzKSB2YWx1ZXMucHVzaCgxKTtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIHZhbHVlc1swXSA/PyAwLFxuICAgICAgICAgICAgdmFsdWVzWzFdID8/IDAsXG4gICAgICAgICAgICB2YWx1ZXNbMl0gPz8gMCxcbiAgICAgICAgICAgIHZhbHVlc1szXSA/PyAxXG4gICAgICAgIF07XG4gICAgfVxuXG4gICAgY2FsY3VsYXRlQ29sb3IoYXZnU2l6ZSwgbWluQXZnU2l6ZSwgbWF4QXZnU2l6ZSwgbWluQ29sb3IsIG1heENvbG9yKSB7XG4gICAgICAgIGlmIChtaW5BdmdTaXplICE9IG1heEF2Z1NpemUpIHtcbiAgICAgICAgICAgIGxldCBncmFkaWVudCA9IChhdmdTaXplIC0gbWluQXZnU2l6ZSkgLyAobWF4QXZnU2l6ZSAtIG1pbkF2Z1NpemUpO1xuICAgICAgICAgICAgbGV0IGNvbG9yID0gbWluQ29sb3IubWFwKChjaGFubmVsLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBNYXRoLnJvdW5kKGNoYW5uZWwgKyBncmFkaWVudCAqIChtYXhDb2xvcltpbmRleF0gLSBjaGFubmVsKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBgcmdiKCR7Y29sb3Iuam9pbignLCcpfSlgO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGByZ2IoJHttaW5Db2xvci5qb2luKCcsJyl9KWBcbiAgICAgICAgfVxuXG4gICAgfVxuXG5cblxuICAgIHNldEFjdGl2ZVRhYih0YWI6IHN0cmluZykge1xuICAgICAgICB0aGlzLmFjdGl2ZVRhYiA9IHRhYjtcbiAgICB9XG5cblxuICAgIGdldFNlbGVjdGVkRXZlbnRUeXBlKGUpIHtcbiAgICAgICAgaWYgKGUuZXZlbnQpIHtcbiAgICAgICAgICAgIHRoaXMub3B0aW9uYWxEcmlsRG93bkRhdGFTb3VyY2UgPSBbXTtcbiAgICAgICAgICAgIGlmICh0aGlzLnZpZXdQcm9wZXJ0aWVzLmNsaWNrRXZlbnRPcHRpb25zLmV2ZW50VHlwZSA9PSAnZHJpbGxkb3duJykge1xuICAgICAgICAgICAgICAgIHRoaXMuaGVhdG1hcENoYXJ0Q29uZmlnWyd2aWV3UHJvcGVydGllcyddWydhc3NvY2lhdGVkVmlld3MnXSA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICB9XG5cblxuICAgIHJlc2V0Vmlld1Byb3Byc3Rpc2UoKSB7XG4gICAgICAgIHRoaXMudmlld1Byb3BlcnRpZXMgPSB7XG4gICAgICAgICAgICBlbmFibGVDbGlja0V2ZW50OiBmYWxzZSxcbiAgICAgICAgICAgIGVuYWJsZVJpZ2h0Q2xpY2tFdmVudDogdHJ1ZSxcbiAgICAgICAgICAgIGNsaWNrRXZlbnRPcHRpb25zOiB7XG4gICAgICAgICAgICAgICAgYXNzb2NpYXRlZFZpZXdzOiBbXSxcbiAgICAgICAgICAgICAgICBldmVudFR5cGU6IFwiXCJcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG5cblxuXG4gICAgZGVsZXRlQXNzb2NpYXRlZFBhcmFtcyhpbmRleCkge1xuICAgICAgICB0aGlzLm9wdGlvbmFsRHJpbERvd25EYXRhU291cmNlLnNwbGljZShpbmRleCwgMSlcbiAgICB9XG5cbiAgICBhZGRBc3NvY2lhdGVkUGFyYW1zKCkge1xuICAgICAgICB0aGlzLm9wdGlvbmFsRHJpbERvd25EYXRhU291cmNlLnB1c2goe1xuICAgICAgICAgICAgJ3ZpZXdJZCc6IFwiXCIsXG4gICAgICAgICAgICAnZmlsdGVyQ29uZGl0aW9uJzogXCJcIlxuICAgICAgICB9KVxuICAgIH1cblxuICAgIGdldENvbG9yQm94VmlzaWJsZShlKSB7XG4gICAgICAgIHRoaXMuY29sb3JBcnJheSA9IFtdO1xuICAgIH1cblxuICAgIHNhdmVDb2xvcnMoKSB7XG4gICAgICAgIGlmICh0aGlzLmhlYXRtYXBDaGFydENvbmZpZy50eXBlID09ICdncmFkaWVudCcgfHwgdGhpcy5oZWF0bWFwQ2hhcnRDb25maWcudHlwZSA9PSAndHdvQ29sb3InKSB7XG4gICAgICAgICAgICB0aGlzLmNvbG9yQXJyYXkgPSBbdGhpcy5maXJzdENvbG9yLCB0aGlzLnNlY29uZENvbG9yXTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmhlYXRtYXBDaGFydENvbmZpZy50eXBlID09ICdzaW5nbGVDb2xvcicpIHtcbiAgICAgICAgICAgIHRoaXMuY29sb3JBcnJheSA9IFt0aGlzLnNpbmdsZUNvbG9yXTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmdldEhlYXRtYXBEYXRhKClcblxuXG4gICAgfVxuICAgIGdldFNhdmVDaGFydENvbmZpZygpIHtcbiAgICAgICAgaWYgKHRoaXMuY29sb3JBcnJheSAmJiB0aGlzLmNvbG9yQXJyYXkubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5oZWF0bWFwQ2hhcnRDb25maWcudHlwZSA9PSAnZ3JhZGllbnQnIHx8IHRoaXMuaGVhdG1hcENoYXJ0Q29uZmlnLnR5cGUgPT0gJ3R3b0NvbG9yJykge1xuICAgICAgICAgICAgICAgIHRoaXMuaGVhdG1hcENoYXJ0Q29uZmlnLmNvbG9yID0gdGhpcy5jb2xvckFycmF5O1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLmhlYXRtYXBDaGFydENvbmZpZy50eXBlID09ICdzaW5nbGVDb2xvcicpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmhlYXRtYXBDaGFydENvbmZpZy5jb2xvciA9IHRoaXMuY29sb3JBcnJheTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG5cbiAgICAgICAgaWYgKHRoaXMudmlld1Byb3BlcnRpZXMuY2xpY2tFdmVudE9wdGlvbnMuZXZlbnRUeXBlID09ICdvcHRpb25hbERyaWxsRG93bicpIHtcbiAgICAgICAgICAgIHRoaXMudmlld1Byb3BlcnRpZXNbJ2NsaWNrRXZlbnRPcHRpb25zJ11bJ2Fzc29jaWF0ZWRWaWV3cyddID0gdGhpcy5vcHRpb25hbERyaWxEb3duRGF0YVNvdXJjZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmhlYXRtYXBfY29udGVudF9jb25maWcua3BpQ29uZmlnWyd2aWV3UHJvcGVydGllcyddID0gdGhpcy52aWV3UHJvcGVydGllcztcbiAgICAgICAgdGhpcy5oZWF0bWFwX2NvbnRlbnRfY29uZmlnLmtwaUNvbmZpZ1snZGF0YUNvbmZpZyddID0gdGhpcy5oZWF0bWFwQ2hhcnRDb25maWc7XG4gICAgICAgIHRoaXMuZ2V0SGVhdE1hcENvbmZpZ091dFB1dC5lbWl0KHRoaXMuaGVhdG1hcF9jb250ZW50X2NvbmZpZyk7XG4gICAgfVxufSIsIjxkaXYgY2xhc3M9XCJtLTJcIj5cbiAgICA8ZGl2IGNsYXNzPVwidy1mdWxsIG0tMiBib3JkZXItclwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWlzSnNvblByZXZpZXdcIj5cbiAgICAgICAgICAgIDxwcmU+PGNvZGU+e3tqc2FvbkRhdGFzb3VyY2UgfCBqc29ufX08L2NvZGU+PC9wcmU+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNKc29uUHJldmlld1wiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImhlYXRtYXBDaGFydENvbmZpZy5jaGFydEZvcm1hdCA9PSAnc2ltcGxlJ1wiPlxuICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXgtNSBoLVs2MHZoXSBvdmVyZmxvdy14LWF1dG9cIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5saW5lLWJsb2NrXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtbm93cmFwIGp1c3RpZnktY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleC1zaHJpbmstMCB3LTY0IG1heC13LVsyMCVdIGgtMTAgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXJcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IGl0ZW0gb2YgaGVhdENoYXJ0RGF0YVNvdXJjZS5hcmd1bWVudFZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsZXgtc2hyaW5rLTAgbWluLXctMjIgbWF4LXctWzIwJV0gaC04IHRleHQtc20gZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2l0ZW19fVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGl0ZW0gb2YgaGVhdENoYXJ0RGF0YVNvdXJjZS5kYXRhU2V0XCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaC04IGZsZXggdGV4dC1zbSBpdGVtcy1jZW50ZXIgbWluLXctNjQganVzdGlmeS1lbmQgcHgtMiBpbmxpbmVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBpdGVtLmRhdGFzb3VyY2UgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlubGluZS1ibG9ja1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtbm93cmFwIGp1c3RpZnktc3RhcnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgYm94IG9mIGl0ZW0uZGF0YXNldFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXgtc2hyaW5rLTAgbWluLXctMjIgbWF4LXctWzIwJV0gaC04IGJvcmRlci0yIHRleHQtc20gY3Vyc29yLXBvaW50ZXIgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgdGV4dC1ncmF5LTgwMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nU3R5bGVdPVwieyAnYmFja2dyb3VuZC1jb2xvcic6IGJveC5jb2xvciB9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYXR0ci50aXRsZV09XCInUmVjb3JkIERhdGU6ICcgKyBib3hbaGVhdG1hcENoYXJ0Q29uZmlnLnRvcEFyZ3VtZW50XSArICcsIFZhbHVlOiAnICsgYm94W2hlYXRtYXBDaGFydENvbmZpZy5jb2x1bW5zWzBdLmRhdGFGaWVsZF1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBib3hbaGVhdG1hcENoYXJ0Q29uZmlnLmNvbHVtbnNbMF0uZGF0YUZpZWxkXX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImhlYXRtYXBDaGFydENvbmZpZy5jaGFydEZvcm1hdCA9PSAndG9weCdcIj5cbiAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm14LTUgaC1bNjB2aF0gb3ZlcmZsb3cteC1hdXRvXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgaGVhZGVyIG9mIGhlYXRDaGFydERhdGFTb3VyY2UuYXJndW1lbnRWYWx1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1pbi13LTMyIHRleHQtc20gZm9udC1tZWRpdW0gdGV4dC1jZW50ZXIgbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGhlYWRlciB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPCEtLSBIZWF0bWFwIEJvZHkgKFRvcCB0byBCb3R0b20gTGF5b3V0KSAtLT5cbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCByb3cgb2YgaGVhdENoYXJ0RGF0YVNvdXJjZS5kYXRhU2V0XCIgY2xhc3M9XCJmbGV4IGZsZXgtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGNlbGwgb2Ygcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiY2VsbC5ib3hcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiaC04IGJvcmRlci0yIHRleHQtc20gY3Vyc29yLXBvaW50ZXIgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgdGV4dC1ncmF5LTgwMCBtaW4tdy0zMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nU3R5bGVdPVwieyAnYmFja2dyb3VuZC1jb2xvcic6IGNlbGwuYm94LmNvbG9yIH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthdHRyLnRpdGxlXT1cIidSZWNvcmQgRGF0ZTogJyArIGNlbGwuaGVhdG1hcENoYXJ0Q29uZmlnLnRvcEFyZ3VtZW50ICsgJywgVmFsdWU6ICcgKyBjZWxsLmJveC5oZWF0bWFwQ2hhcnRDb25maWcuY29sdW1uc1swXS5kYXRhRmllbGRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBjZWxsLmJveC5oZWF0bWFwQ2hhcnRDb25maWcubGVmdEFyZ3VtZW50IH19ICh7eyBjb21tb25TZXJ2aWNlLmFiYnJldmlhdGVOdW1iZXIoY2VsbC5ib3guaGVhdG1hcENoYXJ0Q29uZmlnLmNvbHVtbnNbMF0uZGF0YUZpZWxkKSB9fSlcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cIiFjZWxsLmJveFwiIGNsYXNzPVwiaC04IG1pbi13LTMyXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgXG4gICAgICAgICAgIFxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwidy1mdWxsIG14LTIgYm9yZGVyLXJcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTQgYm9yZGVyLWIgYm9yZGVyLWdyYXktMjAwIGRhcms6Ym9yZGVyLWdyYXktNzAwXCI+XG4gICAgICAgICAgICA8dWwgY2xhc3M9XCJmbGV4IGZsZXgtd3JhcCAtbWItcHggdGV4dC1zbSBmb250LW1lZGl1bSB0ZXh0LWNlbnRlclwiIHJvbGU9XCJ0YWJsaXN0XCI+XG4gICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwibWUtMlwiIHJvbGU9XCJwcmVzZW50YXRpb25cIj5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImlubGluZS1ibG9jayBwLTQgYm9yZGVyLWItMiByb3VuZGVkLXQtbGdcIiBbbmdDbGFzc109XCJ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQtcHVycGxlLTYwMCBib3JkZXItcHVycGxlLTYwMCBkYXJrOnRleHQtcHVycGxlLTUwMCBkYXJrOmJvcmRlci1wdXJwbGUtNTAwJzogYWN0aXZlVGFiID09PSAnYmFzaWMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd0ZXh0LWdyYXktNTAwIGRhcms6dGV4dC1ncmF5LTQwMCBib3JkZXItdHJhbnNwYXJlbnQnOiBhY3RpdmVUYWIgIT09ICdiYXNpYydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cIiAoY2xpY2spPVwic2V0QWN0aXZlVGFiKCdiYXNpYycpXCIgdHlwZT1cImJ1dHRvblwiIHJvbGU9XCJ0YWJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIEJhc2ljXG4gICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwibWUtMlwiIHJvbGU9XCJwcmVzZW50YXRpb25cIj5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImlubGluZS1ibG9jayBwLTQgYm9yZGVyLWItMiByb3VuZGVkLXQtbGdcIiBbbmdDbGFzc109XCJ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQtcHVycGxlLTYwMCBib3JkZXItcHVycGxlLTYwMCBkYXJrOnRleHQtcHVycGxlLTUwMCBkYXJrOmJvcmRlci1wdXJwbGUtNTAwJzogYWN0aXZlVGFiID09PSAnY29sdW1ucycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQtZ3JheS01MDAgZGFyazp0ZXh0LWdyYXktNDAwIGJvcmRlci10cmFuc3BhcmVudCc6IGFjdGl2ZVRhYiAhPT0gJ2NvbHVtbnMnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XCIgKGNsaWNrKT1cInNldEFjdGl2ZVRhYignY29sdW1ucycpXCIgdHlwZT1cImJ1dHRvblwiIHJvbGU9XCJ0YWJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIENvbHVtbnNcbiAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJtZS0yXCIgcm9sZT1cInByZXNlbnRhdGlvblwiPlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiaW5saW5lLWJsb2NrIHAtNCBib3JkZXItYi0yIHJvdW5kZWQtdC1sZ1wiIFtuZ0NsYXNzXT1cIntcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndGV4dC1wdXJwbGUtNjAwIGJvcmRlci1wdXJwbGUtNjAwIGRhcms6dGV4dC1wdXJwbGUtNTAwIGRhcms6Ym9yZGVyLXB1cnBsZS01MDAnOiBhY3RpdmVUYWIgPT09ICdwcm9wZXJ0aWVzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndGV4dC1ncmF5LTUwMCBkYXJrOnRleHQtZ3JheS00MDAgYm9yZGVyLXRyYW5zcGFyZW50JzogYWN0aXZlVGFiICE9PSAncHJvcGVydGllcydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cIiAoY2xpY2spPVwic2V0QWN0aXZlVGFiKCdwcm9wZXJ0aWVzJylcIiB0eXBlPVwiYnV0dG9uXCIgcm9sZT1cInRhYlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgUHJvcGVydGllc1xuICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L2xpPlxuXG4gICAgICAgICAgICA8L3VsPlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2IGlkPVwiZGVmYXVsdC1zdHlsZWQtdGFiLWNvbnRlbnRcIj5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJhY3RpdmVUYWIgPT09ICdiYXNpYydcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbCBmbGV4LWF1dG8gbWluLXctMFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1zbSBweS0xIGZvbnQtZXh0cmFib2xkIGJvcmRlci1iIGJnLWdyYXktNzAwIHRleHQtd2hpdGUgcHgtMlwiPiBGaWx0ZXIgVGl0bGUgQ29uZmlnXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHQtMiBib3JkZXIteCBib3JkZXItYiBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJteS0yIGZsZXgganVzdGlmeS1iZXR3ZWVuXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB4LTEgbWItMSB3LWZ1bGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbWQgbWItMVwiPiBUaXRsZTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZHgtc2VsZWN0LWJveCBbKG5nTW9kZWwpXT1cImhlYXRtYXBDaGFydENvbmZpZy5jaGFydEZvcm1hdFwiIFtpdGVtc109XCJbJ3NpbXBsZScsJ3RvcHgnXVwiPjwvZHgtc2VsZWN0LWJveD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtMSBtYi0xIHctZnVsbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tZCBtYi0xXCI+IFRvcCBBcmd1bWVudDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZHgtc2VsZWN0LWJveCBbc2VhcmNoRW5hYmxlZF09XCJ0cnVlXCIgW2l0ZW1zXT1cImNvbmZpZ0NvbHVtZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImhlYXRtYXBDaGFydENvbmZpZy50b3BBcmd1bWVudFwiPjwvZHgtc2VsZWN0LWJveD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtMSBtYi0xIHctZnVsbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tZCBtYi0xXCI+IExlZnQgQXJndW1lbnQ8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGR4LXNlbGVjdC1ib3ggW3NlYXJjaEVuYWJsZWRdPVwidHJ1ZVwiIFtpdGVtc109XCJjb25maWdDb2x1bWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJoZWF0bWFwQ2hhcnRDb25maWcubGVmdEFyZ3VtZW50XCI+PC9keC1zZWxlY3QtYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC0xIG1iLTEgdy1mdWxsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW1kIG1iLTFcIj4gQ29sb3IgVXNhZ2U8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGR4LXNlbGVjdC1ib3ggW3NlYXJjaEVuYWJsZWRdPVwidHJ1ZVwiIFtpdGVtc109XCJbJ2dyYWRpZW50JywndHdvQ29sb3InLCdzaW5nbGVDb2xvcicsXVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImhlYXRtYXBDaGFydENvbmZpZy50eXBlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChvblZhbHVlQ2hhbmdlZCk9XCJnZXRDb2xvckJveFZpc2libGUoJGV2ZW50KVwiPjwvZHgtc2VsZWN0LWJveD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJoZWF0bWFwQ2hhcnRDb25maWcudHlwZSA9PSAnZ3JhZGllbnQnIHx8IGhlYXRtYXBDaGFydENvbmZpZy50eXBlID09ICd0d29Db2xvcidcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB4LTEgbWItMSB3LWZ1bGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW1kIG1iLTFcIj4gQ29sb3I8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkeC1jb2xvci1ib3ggWyhuZ01vZGVsKV09XCJmaXJzdENvbG9yXCIgW2VkaXRBbHBoYUNoYW5uZWxdPVwidHJ1ZVwiPjwvZHgtY29sb3ItYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB4LTEgbWItMSB3LWZ1bGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW1kIG1iLTFcIj4gQ29sb3I8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkeC1jb2xvci1ib3ggWyhuZ01vZGVsKV09XCJzZWNvbmRDb2xvclwiIFtlZGl0QWxwaGFDaGFubmVsXT1cInRydWVcIj48L2R4LWNvbG9yLWJveD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaGVhdG1hcENoYXJ0Q29uZmlnLnR5cGUgPT0gJ3NpbmdsZUNvbG9yJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtMSBtYi0xIHctZnVsbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbWQgbWItMVwiPiBDb2xvcjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGR4LWNvbG9yLWJveCBbKG5nTW9kZWwpXT1cInNpbmdsZUNvbG9yXCIgW2VkaXRBbHBoYUNoYW5uZWxdPVwidHJ1ZVwiPjwvZHgtY29sb3ItYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC0xIG1iLTEgdy1mdWxsXCIgKm5nSWY9XCJoZWF0bWFwQ2hhcnRDb25maWcudHlwZSAhPT0gJydcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInt7Y29tbW9uU2VydmljZS5idG5fcHJpbWFyeV9tZH19IG10LTZcIiAoY2xpY2spPVwic2F2ZUNvbG9ycygpXCI+Q2hlY2tcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZpZXc8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuXG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cImFjdGl2ZVRhYiA9PT0gJ2NvbHVtbnMnXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImgtZnVsbCBvdmVyZmxvdy14LWF1dG9cIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1jb2wgZmxleC1hdXRvIG1pbi13LTBcIj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB0LTIgYm9yZGVyLXggYm9yZGVyLWIgXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm15LTIgYm9yZGVyLWIgZmxleCBmbGV4LXJvd1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBpdGVtIG9mIGhlYXRtYXBDaGFydENvbmZpZy5jb2x1bW5zOyBsZXQgaSA9IGluZGV4O1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtMSBtYi0yIG10LTYgdy1mdWxsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZHgtY2hlY2stYm94IFt2YWx1ZV09XCJpdGVtLnZpc2libGVcIiBbKG5nTW9kZWwpXT1cIml0ZW0udmlzaWJsZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dD1cIlZpc2libGl0eVwiPjwvZHgtY2hlY2stYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtMSBtYi0yIHctZnVsbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbWQgbWItMlwiPiBWYWx1ZSBGaWVsZDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGR4LXNlbGVjdC1ib3ggW3NlYXJjaEVuYWJsZWRdPVwidHJ1ZVwiIFtpdGVtc109XCJjb25maWdDb2x1bWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiaXRlbS5kYXRhRmllbGRcIj48L2R4LXNlbGVjdC1ib3g+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtMSBtYi0yIHctZnVsbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbWQgbWItMlwiPiBDYXB0aW9uPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZHgtdGV4dC1ib3ggWyhuZ01vZGVsKV09XCJpdGVtLmNhcHRpb25cIj48L2R4LXRleHQtYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB4LTIgbWItMiB3LWZ1bGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW1kIG1iLTJcIj4gVUkgRnVuY3Rpb248L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkeC1zZWxlY3QtYm94IFtpdGVtc109XCJlbnJpY2hOYW1lTGlzdFwiIFsobmdNb2RlbCldPVwiaXRlbS5lbnJpY2hOYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2VhcmNoRW5hYmxlZF09XCJ0cnVlXCI+PC9keC1zZWxlY3QtYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJhY3RpdmVUYWIgPT09ICdwcm9wZXJ0aWVzJ1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoLWZ1bGwgb3ZlcmZsb3cteC1hdXRvXCI+XG4gICAgICAgICAgICAgICAgICAgIDxhcHAtbG9hZGVyICpuZ0lmPVwiaXNMb2FkZXJcIj48L2FwcC1sb2FkZXI+XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhaXNMb2FkZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtcm93IGp1c3RpZnktYmV0d2VlbiBib3JkZXItYiBweS0zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm14LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGR4LWNoZWNrLWJveCBbdmFsdWVdPVwidmlld1Byb3BlcnRpZXMuZW5hYmxlQ2xpY2tFdmVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInZpZXdQcm9wZXJ0aWVzLmVuYWJsZUNsaWNrRXZlbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dD1cIkVuYWJsZSBDbGljayBFdmVudFwiPjwvZHgtY2hlY2stYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJteC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkeC1jaGVjay1ib3ggW3ZhbHVlXT1cInZpZXdQcm9wZXJ0aWVzLmVuYWJsZVJpZ2h0Q2xpY2tFdmVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInZpZXdQcm9wZXJ0aWVzLmVuYWJsZVJpZ2h0Q2xpY2tFdmVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0PVwiRW5hYmxlIFJpZ2h0IENsaWNrXCI+PC9keC1jaGVjay1ib3g+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ3LWZ1bGwgcC0yXCIgKm5nSWY9XCJ2aWV3UHJvcGVydGllcy5lbmFibGVDbGlja0V2ZW50XCI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbCBmbGV4LWF1dG8gbWluLXctMCBteS0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXNtIHB5LTEgZm9udC1leHRyYWJvbGQgYm9yZGVyLWIgYmctZ3JheS03MDAgdGV4dC13aGl0ZSBweC0yXCI+IEV2ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcHRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ3LWZ1bGwgcC0zIGJvcmRlci14IGJvcmRlci1iIFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidy1mdWxsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW1kIG1iLTJcIj4gRXZlbnQgVHlwZTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ3LWZ1bGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGR4LXNlbGVjdC1ib3hcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpdGVtc109XCJbJ2RyaWxsZG93bicsJ3NhbWVWaWV3RHJpbGxkb3duJywnb3B0aW9uYWxEcmlsbERvd24nXVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob25WYWx1ZUNoYW5nZWQpPVwiZ2V0U2VsZWN0ZWRFdmVudFR5cGUoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInZpZXdQcm9wZXJ0aWVzLmNsaWNrRXZlbnRPcHRpb25zLmV2ZW50VHlwZVwiPjwvZHgtc2VsZWN0LWJveD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInZpZXdQcm9wZXJ0aWVzLmNsaWNrRXZlbnRPcHRpb25zLmV2ZW50VHlwZSA9PSAnZHJpbGxkb3duJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtcm93IGp1c3RpZnktYmV0d2VlbiBtdC0zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ3LWZ1bGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW1kIG1iLTJcIj4gQXNzb2NpYXRlZCBWaWV3czwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGR4LXRhZy1ib3ggW2l0ZW1zXT1cImFsbENvbmZpZ3VyZWRWaWV3c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJ2aWV3UHJvcGVydGllcy5jbGlja0V2ZW50T3B0aW9ucy5hc3NvY2lhdGVkVmlld3NcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlRXhwcj1cInZpZXdJZFwiIGRpc3BsYXlFeHByPVwidmlld05hbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93U2VsZWN0aW9uQ29udHJvbHNdPVwidHJ1ZVwiIFtzZWFyY2hFbmFibGVkXT1cInRydWVcIj48L2R4LXRhZy1ib3g+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJ2aWV3UHJvcGVydGllcy5jbGlja0V2ZW50T3B0aW9ucy5ldmVudFR5cGUgPT0gJ3NhbWVWaWV3RHJpbGxkb3duJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtcm93IGp1c3RpZnktYmV0d2VlbiBtdC0zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ3LWZ1bGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW1kIG1iLTJcIj4gQXNzb2NpYXRlZCBWaWV3czwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGR4LXRhZy1ib3ggW2l0ZW1zXT1cImFsbENvbmZpZ3VyZWRWaWV3c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJ2aWV3UHJvcGVydGllcy5jbGlja0V2ZW50T3B0aW9ucy5hc3NvY2lhdGVkVmlld3NcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlRXhwcj1cInZpZXdJZFwiIGRpc3BsYXlFeHByPVwidmlld05hbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93U2VsZWN0aW9uQ29udHJvbHNdPVwidHJ1ZVwiIFtzZWFyY2hFbmFibGVkXT1cInRydWVcIj48L2R4LXRhZy1ib3g+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJ2aWV3UHJvcGVydGllcy5jbGlja0V2ZW50T3B0aW9ucy5ldmVudFR5cGUgPT0gJ29wdGlvbmFsRHJpbGxEb3duJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtcm93IGp1c3RpZnktYmV0d2VlbiBtdC0zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ3LWZ1bGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgaXRlbSBvZiBvcHRpb25hbERyaWxEb3duRGF0YVNvdXJjZTtsZXQgaSA9IGluZGV4O1wiPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1yb3cganVzdGlmeS1iZXR3ZWVuXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJteC0yIHctMS8yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tZCBtYi0yXCI+IEFzc29jaWF0ZWQgVmlld3M8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkeC10YWctYm94IFtpdGVtc109XCJhbGxDb25maWd1cmVkVmlld3NcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiaXRlbS52aWV3SWRcIiB2YWx1ZUV4cHI9XCJ2aWV3SWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BsYXlFeHByPVwidmlld05hbWVcIiBbc2hvd1NlbGVjdGlvbkNvbnRyb2xzXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttYXhEaXNwbGF5ZWRUYWdzXT1cIjJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzZWFyY2hFbmFibGVkXT1cInRydWVcIj48L2R4LXRhZy1ib3g+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJteC0yIHctMS8yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tZCBtYi0yXCI+IEFzc29jaWF0ZWQgUGFyYW1zPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZHgtdGV4dC1ib3hcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cIml0ZW0uZmlsdGVyQ29uZGl0aW9uXCI+PC9keC10ZXh0LWJveD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJteC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ7e2NvbW1vblNlcnZpY2UuYnRuX2Rhbmdlcl9zbX19IGN1cnNvci1wb2ludGVyIG10LThcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJkZWxldGVBc3NvY2lhdGVkUGFyYW1zKGkpXCI+PGlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmYSBmYS10cmFzaC1vXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXJvdyBqdXN0aWZ5LWVuZCBtdC00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInt7Y29tbW9uU2VydmljZS5idG5fcHJpbWFyeV9zbX19IGN1cnNvci1wb2ludGVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImFkZEFzc29jaWF0ZWRQYXJhbXMoKVwiPkFkZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXJhbXM8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInt7Y29tbW9uU2VydmljZS5idG5fbGlnaHRfbWR9fSBjdXJzb3ItcG9pbnRlciBtdC00XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwicmVzZXRWaWV3UHJvcHJzdGlzZSgpXCI+UmVzZXQgQWxsIEV2ZW50PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8L2Rpdj5cblxuXG4gICAgPC9kaXY+XG48L2Rpdj5cblxuXG48ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXJvdyBib3JkZXItdCBwbC0zXCI+XG4gICAgPGRpdiBjbGFzcz1cImZsZXgganVzdGlmeS1zdGFydCBteC0xXCI+XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJ7e2NvbW1vblNlcnZpY2UuYnRuX3dhcm5pbmdfbWR9fSBjdXJzb3ItcG9pbnRlciBtdC0yXCIgKGNsaWNrKT1cImlzSnNvblByZXZpZXcgPSB0cnVlXCI+XG4gICAgICAgICAgICBQcmV2aWV3PC9idXR0b24+XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJ7e2NvbW1vblNlcnZpY2UuYnRuX3ByaW1hcnlfbWR9fSBjdXJzb3ItcG9pbnRlciBtdC0yXCIgKGNsaWNrKT1cImlzSnNvblByZXZpZXcgPSBmYWxzZVwiPkRhdGFcbiAgICAgICAgICAgIFByZXZpZXc8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwiZmxleCBqdXN0aWZ5LWVuZCBteC0xIGZsZXgtZ3Jvd1wiPlxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwie3tjb21tb25TZXJ2aWNlLmJ0bl9zdWNjZXNzX21kfX0gY3Vyc29yLXBvaW50ZXIgbXQtMlwiXG4gICAgICAgICAgICAoY2xpY2spPVwiZ2V0U2F2ZUNoYXJ0Q29uZmlnKClcIj5TdWJtaXQ8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbjwvZGl2PiJdfQ==