gamma-app-controller 1.2.27 → 1.2.30

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 (59) hide show
  1. package/esm2020/lib/application-controller/application-content.service.mjs +3 -3
  2. package/esm2020/lib/application-controller/application-controller.module.mjs +9 -5
  3. package/esm2020/lib/application-controller/application-dataset-component/create-dataset/create-dataset.component.mjs +2 -2
  4. package/esm2020/lib/application-controller/application-dataset-component/create-dataset-sql/create-dataset-sql.component.mjs +3 -3
  5. package/esm2020/lib/application-controller/application-menu-controller/application-create-menu/application-create-menu.component.mjs +15 -39
  6. package/esm2020/lib/application-controller/application-menu-controller/application-menus/application-menus.component.mjs +5 -5
  7. package/esm2020/lib/application-controller/application-view-components/create-comp-view/create-comp-view.component.mjs +4 -1
  8. package/esm2020/lib/application-controller/common.mjs +1 -1
  9. package/esm2020/lib/application-controller/page-controller/page-controller/page-controller.component.mjs +12 -6
  10. package/esm2020/lib/application-controller/support-components/dash-chart/dash-chart.component.mjs +19 -4
  11. package/esm2020/lib/application-controller/support-components/dash-table/dash-table.component.mjs +8 -4
  12. package/esm2020/lib/application-controller/support-components/dash-today-previous/dash-today-previous.component.mjs +3 -3
  13. package/esm2020/lib/application-controller/support-components/table-with-bar/table-with-bar.component.mjs +9 -5
  14. package/esm2020/lib/shared/advanced-component/gamma-advance-chart/gamma-advance-chart.component.mjs +8 -8
  15. package/esm2020/lib/shared/advanced-component/gamma-advance-operator-table/gamma-advance-operator-table.component.mjs +1 -4
  16. package/esm2020/lib/shared/gamma-bread-crumbs/bread-crumbs.component.mjs +1 -3
  17. package/esm2020/lib/shared/permission-helper.mjs +54 -0
  18. package/esm2020/lib/shared/security_principal.mjs +3 -0
  19. package/esm2020/lib/shared/shared.module.mjs +119 -0
  20. package/esm2020/lib/shared/template-dataset-call-service.mjs +376 -0
  21. package/esm2020/lib/shared/user-access/user-access.component.mjs +51 -0
  22. package/esm2020/lib/template-module/KpiCreationModule/create-kpi-tree.component.mjs +38 -4
  23. package/esm2020/lib/template-module/KpiCreationModule/kpiCreation.module.mjs +7 -3
  24. package/esm2020/lib/template-module/bookmarked-template/bookmarked-dataset-call.service.mjs +12 -344
  25. package/esm2020/lib/template-module/defaulLandingComponent/landing-component.component.mjs +2 -2
  26. package/esm2020/lib/template-module/defaulLandingComponent/landing-dataset-call.service.mjs +12 -344
  27. package/esm2020/lib/template-module/defaulLandingMultiLayoutComponent/defaulLandingMultiLayout.component.mjs +1 -3
  28. package/esm2020/lib/template-module/defaulLandingMultiLayoutComponent/multi-landing-dataset-call.service.mjs +12 -344
  29. package/esm2020/lib/template-module/kpiWithMultiLayout/multi-layout-dataset-call.service.mjs +13 -345
  30. package/esm2020/lib/template-module/kpiWithSingleLayout/kpi-with-dataset.component.mjs +55 -26
  31. package/esm2020/lib/template-module/kpiWithSingleLayout/single-layout-dataset-call.service.mjs +12 -347
  32. package/esm2020/public-api.mjs +6 -1
  33. package/fesm2015/gamma-app-controller.mjs +2929 -3945
  34. package/fesm2015/gamma-app-controller.mjs.map +1 -1
  35. package/fesm2020/gamma-app-controller.mjs +1241 -2261
  36. package/fesm2020/gamma-app-controller.mjs.map +1 -1
  37. package/lib/application-controller/application-content.service.d.ts +1 -1
  38. package/lib/application-controller/application-controller.module.d.ts +2 -1
  39. package/lib/application-controller/application-menu-controller/application-create-menu/application-create-menu.component.d.ts +2 -4
  40. package/lib/application-controller/page-controller/page-controller/page-controller.component.d.ts +3 -1
  41. package/lib/application-controller/support-components/dash-chart/dash-chart.component.d.ts +2 -0
  42. package/lib/application-controller/support-components/dash-table/dash-table.component.d.ts +1 -0
  43. package/lib/application-controller/support-components/table-with-bar/table-with-bar.component.d.ts +1 -0
  44. package/lib/shared/advanced-component/gamma-advance-chart/gamma-advance-chart.component.d.ts +1 -1
  45. package/lib/shared/permission-helper.d.ts +8 -0
  46. package/lib/shared/security_principal.d.ts +2 -0
  47. package/lib/shared/shared.module.d.ts +10 -0
  48. package/lib/shared/template-dataset-call-service.d.ts +23 -0
  49. package/lib/shared/user-access/user-access.component.d.ts +20 -0
  50. package/lib/template-module/KpiCreationModule/create-kpi-tree.component.d.ts +2 -0
  51. package/lib/template-module/KpiCreationModule/kpiCreation.module.d.ts +2 -1
  52. package/lib/template-module/bookmarked-template/bookmarked-dataset-call.service.d.ts +6 -13
  53. package/lib/template-module/defaulLandingComponent/landing-dataset-call.service.d.ts +5 -12
  54. package/lib/template-module/defaulLandingMultiLayoutComponent/multi-landing-dataset-call.service.d.ts +5 -12
  55. package/lib/template-module/kpiWithMultiLayout/multi-layout-dataset-call.service.d.ts +6 -13
  56. package/lib/template-module/kpiWithSingleLayout/kpi-with-dataset.component.d.ts +4 -2
  57. package/lib/template-module/kpiWithSingleLayout/single-layout-dataset-call.service.d.ts +5 -14
  58. package/package.json +1 -1
  59. package/public-api.d.ts +5 -0
@@ -1,364 +1,32 @@
1
- import { Inject, Injectable } from '@angular/core';
2
- import moment from '../../application-controller/moment-helper';
1
+ import { Injectable, Inject } from '@angular/core';
3
2
  import { APP_ENVIRONMENT } from '../../application-controller/environment';
4
3
  import * as i0 from "@angular/core";
5
4
  import * as i1 from "./defaulLandingMultiLayout.service";
6
- import * as i2 from "../../application-controller/kpi-service";
7
- import * as i3 from "ngx-toastr";
5
+ import * as i2 from "../../shared/template-dataset-call-service";
6
+ import * as i3 from "../../application-controller/kpi-service";
7
+ import * as i4 from "ngx-toastr";
8
8
  export class LandingMultiLayoutApplicationDatssetsCall {
9
- constructor(service, kpiService, toastr, environment) {
10
- this.service = service;
9
+ constructor(backend, common, kpiService, toastr, environment) {
10
+ this.backend = backend;
11
+ this.common = common;
11
12
  this.kpiService = kpiService;
12
13
  this.toastr = toastr;
13
14
  this.environment = environment;
14
- this.uniqueDataSetObject = {};
15
15
  }
16
16
  getDataFromDataSet(dataset, datasetId, filters) {
17
- if (dataset.datasetType == "mongo") {
18
- return this.getDataSetForMongo(dataset, datasetId);
19
- }
20
- else if (dataset.datasetType == "querybuilder") {
21
- return this.getDatasetForImpala(dataset, datasetId, filters);
22
- }
23
- else if (dataset.datasetType == "simpleApi") {
24
- return this.getDatasetForSimpleApiImpala(dataset, datasetId, filters);
25
- }
26
- else if (dataset.datasetType == "plainjson") {
27
- return this.getDatasetForPlainJson(dataset, datasetId, filters);
28
- }
29
- else if (dataset.datasetType == "sqlQuery") {
30
- return this.getDatasetForSqlTemplate(dataset, datasetId, filters);
31
- }
32
- else {
33
- return Promise.resolve();
34
- }
35
- }
36
- getDataSetForMongo(dataset, datasetId) {
37
- return new Promise((resolve, reject) => {
38
- let apiJsonObject = {
39
- requestId: dataset.config.serviceId,
40
- };
41
- if (dataset.config.fixOperationLevles && dataset.config.fixOperationLevles.length != 0) {
42
- for (const item of dataset.config.fixOperationLevles) {
43
- Object.assign(apiJsonObject, item);
44
- }
45
- }
46
- const mon_config = this.kpiService.getAllSeviceApiJson(apiJsonObject);
47
- this.service.getData(mon_config, dataset.config.api).subscribe({
48
- next: (data) => {
49
- const payload = data["Payload"] || data;
50
- this.uniqueDataSetObject[datasetId] = payload;
51
- resolve();
52
- },
53
- error: (err) => {
54
- console.error('Error:', err);
55
- reject(err);
56
- }
57
- });
58
- });
59
- }
60
- getDatasetForImpala(dataset, datasetId, filters) {
61
- return new Promise((resolve, reject) => {
62
- let request = dataset.config.queryConfig;
63
- let transformedObject = {};
64
- for (let item of request.reqFields) {
65
- const key = Object.keys(item)[0];
66
- const value = Object.values(item)[0];
67
- if (key === 'startDate') {
68
- transformedObject.recordDate = value;
69
- }
70
- else {
71
- transformedObject[key] = value;
72
- }
73
- }
74
- const operator = (filters && filters.length !== 0) ? Object.keys(filters.operationFilter).map(key => ({ [key]: filters.operationFilter[key] })) : [];
75
- transformedObject['filters'] = this.transformDataForMFilter(operator, request.mapedFilters);
76
- transformedObject['sorters'] = request.sorters;
77
- transformedObject["paginationRequired"] = false;
78
- if (dataset.config.api == "/kpi/genericAggregatePaginatedKpiServiceResponse") {
79
- transformedObject['measures'] = request.measures;
80
- transformedObject['dimensions'] = request.dimensions;
81
- }
82
- else {
83
- transformedObject['columns'] = this.getFormatObjectForColumn(request.columns);
84
- }
85
- if (request.havings && request.havings.length !== 0) {
86
- transformedObject['havings'] = request.havings;
87
- }
88
- this.service.getData(transformedObject, dataset.config.api).subscribe({
89
- next: (data) => {
90
- const payload = data['dataset'];
91
- this.uniqueDataSetObject[datasetId] = payload;
92
- resolve();
93
- },
94
- error: (err) => {
95
- console.error('Error:', err);
96
- this.toastr.error(err.message);
97
- reject(err);
98
- }
99
- });
100
- });
101
- }
102
- getFormatObjectForColumn(columns) {
103
- let columnData = [];
104
- columns.forEach(element => {
105
- const { advancedColumn, columnName, enrichFunction, dataField } = element;
106
- columnData.push({
107
- "advancedColumn": advancedColumn,
108
- "columnName": columnName,
109
- "enrichFunction": enrichFunction,
110
- "aliasName": dataField
111
- });
112
- });
113
- return columnData;
114
- }
115
- transformDataForMFilter(filterdata, mapData) {
116
- let result = [];
117
- mapData.forEach(mapping => {
118
- let resultObj = {
119
- columnName: mapping.serverColumn,
120
- dataType: mapping.dataType,
121
- operator: mapping.operatorName,
122
- value: mapping.defaultValue
123
- };
124
- if (mapping.serverColumn.includes('date') && typeof resultObj.value === 'string') {
125
- if (mapping.formatter && mapping.formatter !== "") {
126
- resultObj.value = moment(resultObj.value, "YYYY-MM-DD").format(mapping.formatter);
127
- }
128
- else {
129
- resultObj.value = moment(resultObj.value, "YYYY-MM-DD").format(this.environment.dataFormat);
130
- }
131
- }
132
- const filter = filterdata.find(f => f.hasOwnProperty(mapping.localColumn));
133
- if (filter) {
134
- if (mapping.defaultValue === "") {
135
- const value = filter[mapping.localColumn];
136
- if (Array.isArray(value)) {
137
- resultObj.operator = "in";
138
- resultObj.value = value.join(",");
139
- }
140
- else {
141
- resultObj.value = value;
142
- }
143
- if (mapping.serverColumn.includes('date') && typeof resultObj.value === 'string') {
144
- if (mapping.formatter && mapping.formatter !== "") {
145
- resultObj.value = moment(resultObj.value, "YYYY-MM-DD").format(mapping.formatter);
146
- }
147
- else {
148
- resultObj.value = moment(resultObj.value, "YYYY-MM-DD").format(this.environment.dataFormat);
149
- }
150
- }
151
- }
152
- }
153
- else if (mapping.defaultValue === "") {
154
- return;
155
- }
156
- result.push(resultObj);
157
- });
158
- filterdata = filterdata.filter(obj => {
159
- const key = Object.keys(obj)[0];
160
- return key !== 'startDate' && key !== 'endDate';
161
- });
162
- filterdata.forEach(filter => {
163
- const filterKey = Object.keys(filter)[0];
164
- const existingMapping = mapData.find(mapping => mapping.localColumn === filterKey);
165
- if (!existingMapping) {
166
- let resultObj = {
167
- columnName: filterKey,
168
- dataType: "string",
169
- operator: "eq",
170
- value: filter[filterKey]
171
- };
172
- if (Array.isArray(filter[filterKey])) {
173
- resultObj.operator = "in";
174
- resultObj.value = filter[filterKey].join(",");
175
- }
176
- else {
177
- resultObj.value = filter[filterKey];
178
- }
179
- if (filterKey == 'operator_key') {
180
- resultObj.operator = "eq";
181
- }
182
- result.push(resultObj);
183
- }
184
- });
185
- result = result.filter(obj => obj.value !== null && obj.value !== "");
186
- return result;
187
- }
188
- getDatasetForSimpleApiImpala(dataset, datasetId, filters) {
189
- return new Promise((resolve, reject) => {
190
- dataset.config.queryConfig.mapedFilters.forEach(filter => {
191
- if (filters.operationFilter.hasOwnProperty(filter.localColumn)) {
192
- filter.defaultValue = filters.operationFilter[filter.localColumn];
193
- }
194
- });
195
- if (dataset.config.apiType === "post") {
196
- let serviceJson = {};
197
- dataset.config.queryConfig.mapedFilters.forEach((filter) => {
198
- let datecolumn = filter.serverColumn.toLowerCase();
199
- if (datecolumn.includes('date') && typeof filter.dataType === 'string') {
200
- serviceJson[filter.serverColumn] = moment(filter.defaultValue, "YYYY-MM-DD").format(this.environment.dataFormat);
201
- }
202
- else {
203
- serviceJson[filter.serverColumn] = filter.defaultValue;
204
- }
205
- });
206
- this.service.getSimpleApiPostRequest(dataset.config.api, serviceJson).subscribe({
207
- next: (data) => {
208
- const payload = data["Payload"] || data;
209
- this.uniqueDataSetObject[datasetId] = payload;
210
- resolve();
211
- },
212
- error: (err) => {
213
- console.error('Error:', err);
214
- this.toastr.error(err.message);
215
- reject(err);
216
- }
217
- });
218
- }
219
- else if (dataset.config.apiType === "get") {
220
- let requestUrl = dataset.config.api + "?";
221
- dataset.config.queryConfig.mapedFilters.forEach((filter, index) => {
222
- requestUrl += `${filter.serverColumn}=${filter.defaultValue}`;
223
- if (index < dataset.config.queryConfig.mapedFilters.length - 1) {
224
- requestUrl += "&";
225
- }
226
- });
227
- this.service.getSimpleApiGetRequest(requestUrl).subscribe({
228
- next: (data) => {
229
- const payload = data["Payload"] || data;
230
- this.uniqueDataSetObject[datasetId] = payload;
231
- resolve();
232
- },
233
- error: (err) => {
234
- console.error('Error:', err);
235
- this.toastr.error(err.message);
236
- reject(err);
237
- }
238
- });
239
- }
240
- });
241
- }
242
- getDatasetForPlainJson(dataset, datasetId, filter) {
243
- return new Promise((resolve, reject) => {
244
- let requestapi = dataset.config.api + '?datasetId=' + dataset.datasetId;
245
- this.service.getJsonDatasetPayload(requestapi).subscribe({
246
- next: (data) => {
247
- const payload = data["Payload"] || data;
248
- this.uniqueDataSetObject[datasetId] = payload;
249
- resolve();
250
- },
251
- error: (err) => {
252
- console.error('Error:', err);
253
- reject(err);
254
- }
255
- });
256
- });
257
- }
258
- getDatasetForSqlTemplate(dataset, datasetId, filters) {
259
- return new Promise((resolve, reject) => {
260
- const operator = (filters && filters.length !== 0) ? Object.keys(filters.operationFilter).map(key => ({ [key]: filters.operationFilter[key] })) : [];
261
- let requestAp = dataset.config.api;
262
- let request_params = {
263
- 'dbConfig': dataset.config.queryConfig.dbConfig,
264
- 'databaseName': dataset.config.queryConfig.databaseName,
265
- 'filters': this.transformDataForMFilterForSQl(operator, dataset.config.queryConfig.mapedFilters),
266
- 'templateQuery': dataset.config.queryConfig.templateQuery,
267
- 'enrichments': dataset.config.queryConfig.enrichments,
268
- };
269
- this.service.genericSqlQueryResponse(requestAp, request_params).subscribe({
270
- next: (data) => {
271
- const payload = data["Payload"] || data;
272
- this.uniqueDataSetObject[datasetId] = payload;
273
- resolve();
274
- },
275
- error: (err) => {
276
- console.error('Error:', err);
277
- this.toastr.error(err.message);
278
- reject(err);
279
- }
280
- });
281
- });
282
- }
283
- transformDataForMFilterForSQl(filterdata, mapData) {
284
- let result = [];
285
- mapData.forEach(mapping => {
286
- let resultObj = {
287
- columnName: mapping.serverColumn,
288
- dataType: mapping.dataType,
289
- operator: mapping.operatorName,
290
- value: mapping.defaultValue,
291
- aliasColumnName: mapping.localColumn,
292
- };
293
- if (mapping.serverColumn.includes('date') && typeof resultObj.value === 'string') {
294
- if (mapping.formatter && mapping.formatter !== "") {
295
- resultObj.value = moment(resultObj.value, "YYYY-MM-DD").format(mapping.formatter);
296
- }
297
- else {
298
- resultObj.value = moment(resultObj.value, "YYYY-MM-DD").format(this.environment.dataFormat);
299
- }
300
- }
301
- const filter = filterdata.find(f => f.hasOwnProperty(mapping.localColumn));
302
- if (filter) {
303
- if (mapping.defaultValue === "") {
304
- const value = filter[mapping.localColumn];
305
- if (Array.isArray(value)) {
306
- resultObj.operator = "in";
307
- resultObj.value = value.join(",");
308
- }
309
- else {
310
- resultObj.value = value;
311
- }
312
- if (mapping.serverColumn.includes('date') && typeof resultObj.value === 'string') {
313
- resultObj.value = moment(resultObj.value, "YYYY-MM-DD").format(this.environment.dataFormat);
314
- }
315
- }
316
- }
317
- else if (mapping.defaultValue === "") {
318
- return;
319
- }
320
- result.push(resultObj);
321
- });
322
- filterdata = filterdata.filter(obj => {
323
- const key = Object.keys(obj)[0];
324
- return key !== 'startDate' && key !== 'endDate';
325
- });
326
- filterdata.forEach(filter => {
327
- const filterKey = Object.keys(filter)[0];
328
- const existingMapping = mapData.find(mapping => mapping.localColumn === filterKey);
329
- if (!existingMapping) {
330
- let resultObj = {
331
- columnName: filterKey,
332
- dataType: "string",
333
- operator: "eq",
334
- value: filter[filterKey]
335
- };
336
- if (Array.isArray(filter[filterKey])) {
337
- resultObj.operator = "in";
338
- resultObj.value = filter[filterKey].join(",");
339
- }
340
- else {
341
- resultObj.value = filter[filterKey];
342
- }
343
- if (filterKey == 'operator_key') {
344
- resultObj.operator = "eq";
345
- }
346
- result.push(resultObj);
347
- }
348
- });
349
- return result;
17
+ return this.common.getDataFromDataSet(this.backend, dataset, datasetId, filters);
350
18
  }
351
19
  getUniqueDataSetObject() {
352
- return this.uniqueDataSetObject;
20
+ return this.common.getUniqueDataSetObject();
353
21
  }
354
22
  }
355
- LandingMultiLayoutApplicationDatssetsCall.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LandingMultiLayoutApplicationDatssetsCall, deps: [{ token: i1.LandingMultiLayoutComponentService }, { token: i2.kpicommonService }, { token: i3.ToastrService }, { token: APP_ENVIRONMENT }], target: i0.ɵɵFactoryTarget.Injectable });
23
+ LandingMultiLayoutApplicationDatssetsCall.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LandingMultiLayoutApplicationDatssetsCall, deps: [{ token: i1.LandingMultiLayoutComponentService }, { token: i2.TemplateDatasetCallService }, { token: i3.kpicommonService }, { token: i4.ToastrService }, { token: APP_ENVIRONMENT }], target: i0.ɵɵFactoryTarget.Injectable });
356
24
  LandingMultiLayoutApplicationDatssetsCall.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LandingMultiLayoutApplicationDatssetsCall, providedIn: "root" });
357
25
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LandingMultiLayoutApplicationDatssetsCall, decorators: [{
358
26
  type: Injectable,
359
27
  args: [{ providedIn: "root" }]
360
- }], ctorParameters: function () { return [{ type: i1.LandingMultiLayoutComponentService }, { type: i2.kpicommonService }, { type: i3.ToastrService }, { type: undefined, decorators: [{
28
+ }], ctorParameters: function () { return [{ type: i1.LandingMultiLayoutComponentService }, { type: i2.TemplateDatasetCallService }, { type: i3.kpicommonService }, { type: i4.ToastrService }, { type: undefined, decorators: [{
361
29
  type: Inject,
362
30
  args: [APP_ENVIRONMENT]
363
31
  }] }]; } });
364
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVsdGktbGFuZGluZy1kYXRhc2V0LWNhbGwuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2dhbW1hLWFwcC1jb250cm9sbGVyL3NyYy9saWIvdGVtcGxhdGUtbW9kdWxlL2RlZmF1bExhbmRpbmdNdWx0aUxheW91dENvbXBvbmVudC9tdWx0aS1sYW5kaW5nLWRhdGFzZXQtY2FsbC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBR25ELE9BQU8sTUFBTSxNQUFNLDRDQUE0QyxDQUFDO0FBRWhFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQzs7Ozs7QUFNM0UsTUFBTSxPQUFPLHlDQUF5QztJQUlsRCxZQUFvQixPQUEyQyxFQUNuRCxVQUE0QixFQUM1QixNQUFxQixFQUNJLFdBQWdCO1FBSGpDLFlBQU8sR0FBUCxPQUFPLENBQW9DO1FBQ25ELGVBQVUsR0FBVixVQUFVLENBQWtCO1FBQzVCLFdBQU0sR0FBTixNQUFNLENBQWU7UUFDSSxnQkFBVyxHQUFYLFdBQVcsQ0FBSztRQUxyRCx3QkFBbUIsR0FBRyxFQUFFLENBQUM7SUFRekIsQ0FBQztJQUVELGtCQUFrQixDQUFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsT0FBTztRQUMxQyxJQUFJLE9BQU8sQ0FBQyxXQUFXLElBQUksT0FBTyxFQUFFO1lBQ2hDLE9BQU8sSUFBSSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sRUFBRSxTQUFTLENBQUMsQ0FBQztTQUN0RDthQUFNLElBQUksT0FBTyxDQUFDLFdBQVcsSUFBSSxjQUFjLEVBQUU7WUFDOUMsT0FBTyxJQUFJLENBQUMsbUJBQW1CLENBQUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxPQUFPLENBQUMsQ0FBQztTQUNoRTthQUFNLElBQUksT0FBTyxDQUFDLFdBQVcsSUFBSSxX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Q0FBQztpQkFDN0I7Z0JBQ0QsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQzthQUMxQjtRQUNMLENBQUMsQ0FBQyxDQUFDO1FBSUgsT0FBTyxNQUFNLENBQUM7SUFDbEIsQ0FBQztJQUdELHNCQUFzQjtRQUNsQixPQUFPLElBQUksQ0FBQyxtQkFBbUIsQ0FBQztJQUNwQyxDQUFDOztzSUF0WVEseUNBQXlDLGlJQU90QyxlQUFlOzBJQVBsQix5Q0FBeUMsY0FENUIsTUFBTTsyRkFDbkIseUNBQXlDO2tCQURyRCxVQUFVO21CQUFDLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRTs7MEJBUXpCLE1BQU07MkJBQUMsZUFBZSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdCwgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG4vLyBpbXBvcnQgbW9tZW50IGZyb20gJ21vbWVudCc7XG5pbXBvcnQgbW9tZW50IGZyb20gJy4uLy4uL2FwcGxpY2F0aW9uLWNvbnRyb2xsZXIvbW9tZW50LWhlbHBlcic7XG5pbXBvcnQgeyBUb2FzdHJTZXJ2aWNlIH0gZnJvbSAnbmd4LXRvYXN0cic7XG5pbXBvcnQgeyBBUFBfRU5WSVJPTk1FTlQgfSBmcm9tICcuLi8uLi9hcHBsaWNhdGlvbi1jb250cm9sbGVyL2Vudmlyb25tZW50JztcbmltcG9ydCB7IGtwaWNvbW1vblNlcnZpY2UgfSBmcm9tICcuLi8uLi9hcHBsaWNhdGlvbi1jb250cm9sbGVyL2twaS1zZXJ2aWNlJztcbmltcG9ydCB7IExhbmRpbmdNdWx0aUxheW91dENvbXBvbmVudFNlcnZpY2UgfSBmcm9tICcuL2RlZmF1bExhbmRpbmdNdWx0aUxheW91dC5zZXJ2aWNlJztcblxuXG5ASW5qZWN0YWJsZSh7IHByb3ZpZGVkSW46IFwicm9vdFwiIH0pXG5leHBvcnQgY2xhc3MgTGFuZGluZ011bHRpTGF5b3V0QXBwbGljYXRpb25EYXRzc2V0c0NhbGwge1xuXG4gICAgdW5pcXVlRGF0YVNldE9iamVjdCA9IHt9O1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzZXJ2aWNlOiBMYW5kaW5nTXVsdGlMYXlvdXRDb21wb25lbnRTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIGtwaVNlcnZpY2U6IGtwaWNvbW1vblNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgdG9hc3RyOiBUb2FzdHJTZXJ2aWNlLFxuICAgICAgICBASW5qZWN0KEFQUF9FTlZJUk9OTUVOVCkgcHJpdmF0ZSBlbnZpcm9ubWVudDogYW55XG4gICAgKSB7XG5cbiAgICB9XG5cbiAgICBnZXREYXRhRnJvbURhdGFTZXQoZGF0YXNldCwgZGF0YXNldElkLCBmaWx0ZXJzKSB7XG4gICAgICAgIGlmIChkYXRhc2V0LmRhdGFzZXRUeXBlID09IFwibW9uZ29cIikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RGF0YVNldEZvck1vbmdvKGRhdGFzZXQsIGRhdGFzZXRJZCk7XG4gICAgICAgIH0gZWxzZSBpZiAoZGF0YXNldC5kYXRhc2V0VHlwZSA9PSBcInF1ZXJ5YnVpbGRlclwiKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5nZXREYXRhc2V0Rm9ySW1wYWxhKGRhdGFzZXQsIGRhdGFzZXRJZCwgZmlsdGVycyk7XG4gICAgICAgIH0gZWxzZSBpZiAoZGF0YXNldC5kYXRhc2V0VHlwZSA9PSBcInNpbXBsZUFwaVwiKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5nZXREYXRhc2V0Rm9yU2ltcGxlQXBpSW1wYWxhKGRhdGFzZXQsIGRhdGFzZXRJZCwgZmlsdGVycyk7XG4gICAgICAgIH0gZWxzZSBpZiAoZGF0YXNldC5kYXRhc2V0VHlwZSA9PSBcInBsYWluanNvblwiKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5nZXREYXRhc2V0Rm9yUGxhaW5Kc29uKGRhdGFzZXQsIGRhdGFzZXRJZCwgZmlsdGVycyk7XG4gICAgICAgIH0gZWxzZSBpZiAoZGF0YXNldC5kYXRhc2V0VHlwZSA9PSBcInNxbFF1ZXJ5XCIpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldERhdGFzZXRGb3JTcWxUZW1wbGF0ZShkYXRhc2V0LCBkYXRhc2V0SWQsIGZpbHRlcnMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICBnZXREYXRhU2V0Rm9yTW9uZ28oZGF0YXNldCwgZGF0YXNldElkKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBsZXQgYXBpSnNvbk9iamVjdCA9IHtcbiAgICAgICAgICAgICAgICByZXF1ZXN0SWQ6IGRhdGFzZXQuY29uZmlnLnNlcnZpY2VJZCxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBpZiAoZGF0YXNldC5jb25maWcuZml4T3BlcmF0aW9uTGV2bGVzICYmIGRhdGFzZXQuY29uZmlnLmZpeE9wZXJhdGlvbkxldmxlcy5sZW5ndGggIT0gMCkge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBkYXRhc2V0LmNvbmZpZy5maXhPcGVyYXRpb25MZXZsZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihhcGlKc29uT2JqZWN0LCBpdGVtKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBtb25fY29uZmlnID0gdGhpcy5rcGlTZXJ2aWNlLmdldEFsbFNldmljZUFwaUpzb24oYXBpSnNvbk9iamVjdCk7XG4gICAgICAgICAgICB0aGlzLnNlcnZpY2UuZ2V0RGF0YShtb25fY29uZmlnLCBkYXRhc2V0LmNvbmZpZy5hcGkpLnN1YnNjcmliZSh7XG4gICAgICAgICAgICAgICAgbmV4dDogKGRhdGE6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXlsb2FkID0gZGF0YVtcIlBheWxvYWRcIl0gfHwgZGF0YTtcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhpcy51bmlxdWVEYXRhU2V0T2JqZWN0W2RhdGFzZXRJZF0gPSBwYXlsb2FkLnNsaWNlKDAsIDIwKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51bmlxdWVEYXRhU2V0T2JqZWN0W2RhdGFzZXRJZF0gPSBwYXlsb2FkO1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBlcnJvcjogKGVycjogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yOicsIGVycik7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBnZXREYXRhc2V0Rm9ySW1wYWxhKGRhdGFzZXQsIGRhdGFzZXRJZCwgZmlsdGVycykge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgbGV0IHJlcXVlc3QgPSBkYXRhc2V0LmNvbmZpZy5xdWVyeUNvbmZpZztcbiAgICAgICAgICAgIGxldCB0cmFuc2Zvcm1lZE9iamVjdDogYW55ID0ge307XG4gICAgICAgICAgICBmb3IgKGxldCBpdGVtIG9mIHJlcXVlc3QucmVxRmllbGRzKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qga2V5ID0gT2JqZWN0LmtleXMoaXRlbSlbMF07XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBPYmplY3QudmFsdWVzKGl0ZW0pWzBdO1xuICAgICAgICAgICAgICAgIGlmIChrZXkgPT09ICdzdGFydERhdGUnKSB7XG4gICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybWVkT2JqZWN0LnJlY29yZERhdGUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1lZE9iamVjdFtrZXldID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3Qgb3BlcmF0b3IgPSAoZmlsdGVycyAmJiBmaWx0ZXJzLmxlbmd0aCAhPT0gMCkgPyBPYmplY3Qua2V5cyhmaWx0ZXJzLm9wZXJhdGlvbkZpbHRlcikubWFwKGtleSA9PiAoeyBba2V5XTogZmlsdGVycy5vcGVyYXRpb25GaWx0ZXJba2V5XSB9KSkgOiBbXTtcblxuXG4gICAgICAgICAgICB0cmFuc2Zvcm1lZE9iamVjdFsnZmlsdGVycyddID0gdGhpcy50cmFuc2Zvcm1EYXRhRm9yTUZpbHRlcihvcGVyYXRvciwgcmVxdWVzdC5tYXBlZEZpbHRlcnMpO1xuICAgICAgICAgICAgdHJhbnNmb3JtZWRPYmplY3RbJ3NvcnRlcnMnXSA9IHJlcXVlc3Quc29ydGVycztcbiAgICAgICAgICAgIHRyYW5zZm9ybWVkT2JqZWN0W1wicGFnaW5hdGlvblJlcXVpcmVkXCJdID0gZmFsc2U7XG5cbiAgICAgICAgICAgIGlmIChkYXRhc2V0LmNvbmZpZy5hcGkgPT0gXCIva3BpL2dlbmVyaWNBZ2dyZWdhdGVQYWdpbmF0ZWRLcGlTZXJ2aWNlUmVzcG9uc2VcIikge1xuICAgICAgICAgICAgICAgIHRyYW5zZm9ybWVkT2JqZWN0WydtZWFzdXJlcyddID0gcmVxdWVzdC5tZWFzdXJlcztcbiAgICAgICAgICAgICAgICB0cmFuc2Zvcm1lZE9iamVjdFsnZGltZW5zaW9ucyddID0gcmVxdWVzdC5kaW1lbnNpb25zO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0cmFuc2Zvcm1lZE9iamVjdFsnY29sdW1ucyddID0gdGhpcy5nZXRGb3JtYXRPYmplY3RGb3JDb2x1bW4ocmVxdWVzdC5jb2x1bW5zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChyZXF1ZXN0LmhhdmluZ3MgJiYgcmVxdWVzdC5oYXZpbmdzLmxlbmd0aCAhPT0gMCkge1xuICAgICAgICAgICAgICAgIHRyYW5zZm9ybWVkT2JqZWN0WydoYXZpbmdzJ10gPSByZXF1ZXN0LmhhdmluZ3M7XG4gICAgICAgICAgICB9XG5cblxuICAgICAgICAgICAgdGhpcy5zZXJ2aWNlLmdldERhdGEodHJhbnNmb3JtZWRPYmplY3QsIGRhdGFzZXQuY29uZmlnLmFwaSkuc3Vic2NyaWJlKHtcbiAgICAgICAgICAgICAgICBuZXh0OiAoZGF0YTogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBheWxvYWQgPSBkYXRhWydkYXRhc2V0J107XG4gICAgICAgICAgICAgICAgICAgIC8vIHRoaXMudW5pcXVlRGF0YVNldE9iamVjdFtkYXRhc2V0SWRdID0gcGF5bG9hZC5zbGljZSgwLCAzMCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudW5pcXVlRGF0YVNldE9iamVjdFtkYXRhc2V0SWRdID0gcGF5bG9hZDtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZXJyb3I6IChlcnI6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvcjonLCBlcnIpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnRvYXN0ci5lcnJvcihlcnIubWVzc2FnZSlcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuXG4gICAgZ2V0Rm9ybWF0T2JqZWN0Rm9yQ29sdW1uKGNvbHVtbnMpIHtcbiAgICAgICAgbGV0IGNvbHVtbkRhdGEgPSBbXTtcbiAgICAgICAgY29sdW1ucy5mb3JFYWNoKGVsZW1lbnQgPT4ge1xuICAgICAgICAgICAgY29uc3QgeyBhZHZhbmNlZENvbHVtbiwgY29sdW1uTmFtZSwgZW5yaWNoRnVuY3Rpb24sIGRhdGFGaWVsZCB9ID0gZWxlbWVudDtcbiAgICAgICAgICAgIGNvbHVtbkRhdGEucHVzaCh7XG4gICAgICAgICAgICAgICAgXCJhZHZhbmNlZENvbHVtblwiOiBhZHZhbmNlZENvbHVtbixcbiAgICAgICAgICAgICAgICBcImNvbHVtbk5hbWVcIjogY29sdW1uTmFtZSxcbiAgICAgICAgICAgICAgICBcImVucmljaEZ1bmN0aW9uXCI6IGVucmljaEZ1bmN0aW9uLFxuICAgICAgICAgICAgICAgIFwiYWxpYXNOYW1lXCI6IGRhdGFGaWVsZFxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBjb2x1bW5EYXRhO1xuICAgIH1cblxuICAgIHRyYW5zZm9ybURhdGFGb3JNRmlsdGVyKGZpbHRlcmRhdGEsIG1hcERhdGEpIHtcbiAgICAgICAgbGV0IHJlc3VsdCA9IFtdO1xuICAgICAgICBtYXBEYXRhLmZvckVhY2gobWFwcGluZyA9PiB7XG4gICAgICAgICAgICBsZXQgcmVzdWx0T2JqID0ge1xuICAgICAgICAgICAgICAgIGNvbHVtbk5hbWU6IG1hcHBpbmcuc2VydmVyQ29sdW1uLFxuICAgICAgICAgICAgICAgIGRhdGFUeXBlOiBtYXBwaW5nLmRhdGFUeXBlLFxuICAgICAgICAgICAgICAgIG9wZXJhdG9yOiBtYXBwaW5nLm9wZXJhdG9yTmFtZSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogbWFwcGluZy5kZWZhdWx0VmFsdWVcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBpZiAobWFwcGluZy5zZXJ2ZXJDb2x1bW4uaW5jbHVkZXMoJ2RhdGUnKSAmJiB0eXBlb2YgcmVzdWx0T2JqLnZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIGlmIChtYXBwaW5nLmZvcm1hdHRlciAmJiBtYXBwaW5nLmZvcm1hdHRlciAhPT0gXCJcIikge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHRPYmoudmFsdWUgPSBtb21lbnQocmVzdWx0T2JqLnZhbHVlLCBcIllZWVktTU0tRERcIikuZm9ybWF0KG1hcHBpbmcuZm9ybWF0dGVyKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHRPYmoudmFsdWUgPSBtb21lbnQocmVzdWx0T2JqLnZhbHVlLCBcIllZWVktTU0tRERcIikuZm9ybWF0KHRoaXMuZW52aXJvbm1lbnQuZGF0YUZvcm1hdCk7XG5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBmaWx0ZXIgPSBmaWx0ZXJkYXRhLmZpbmQoZiA9PiBmLmhhc093blByb3BlcnR5KG1hcHBpbmcubG9jYWxDb2x1bW4pKTtcbiAgICAgICAgICAgIGlmIChmaWx0ZXIpIHtcbiAgICAgICAgICAgICAgICBpZiAobWFwcGluZy5kZWZhdWx0VmFsdWUgPT09IFwiXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBmaWx0ZXJbbWFwcGluZy5sb2NhbENvbHVtbl07XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRPYmoub3BlcmF0b3IgPSBcImluXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRPYmoudmFsdWUgPSB2YWx1ZS5qb2luKFwiLFwiKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdE9iai52YWx1ZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChtYXBwaW5nLnNlcnZlckNvbHVtbi5pbmNsdWRlcygnZGF0ZScpICYmIHR5cGVvZiByZXN1bHRPYmoudmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobWFwcGluZy5mb3JtYXR0ZXIgJiYgbWFwcGluZy5mb3JtYXR0ZXIgIT09IFwiXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRPYmoudmFsdWUgPSBtb21lbnQocmVzdWx0T2JqLnZhbHVlLCBcIllZWVktTU0tRERcIikuZm9ybWF0KG1hcHBpbmcuZm9ybWF0dGVyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0T2JqLnZhbHVlID0gbW9tZW50KHJlc3VsdE9iai52YWx1ZSwgXCJZWVlZLU1NLUREXCIpLmZvcm1hdCh0aGlzLmVudmlyb25tZW50LmRhdGFGb3JtYXQpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKG1hcHBpbmcuZGVmYXVsdFZhbHVlID09PSBcIlwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzdWx0LnB1c2gocmVzdWx0T2JqKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGZpbHRlcmRhdGEgPSBmaWx0ZXJkYXRhLmZpbHRlcihvYmogPT4ge1xuICAgICAgICAgICAgY29uc3Qga2V5ID0gT2JqZWN0LmtleXMob2JqKVswXTtcbiAgICAgICAgICAgIHJldHVybiBrZXkgIT09ICdzdGFydERhdGUnICYmIGtleSAhPT0gJ2VuZERhdGUnO1xuICAgICAgICB9KTtcbiAgICAgICAgZmlsdGVyZGF0YS5mb3JFYWNoKGZpbHRlciA9PiB7XG4gICAgICAgICAgICBjb25zdCBmaWx0ZXJLZXkgPSBPYmplY3Qua2V5cyhmaWx0ZXIpWzBdO1xuICAgICAgICAgICAgY29uc3QgZXhpc3RpbmdNYXBwaW5nID0gbWFwRGF0YS5maW5kKG1hcHBpbmcgPT4gbWFwcGluZy5sb2NhbENvbHVtbiA9PT0gZmlsdGVyS2V5KTtcblxuICAgICAgICAgICAgaWYgKCFleGlzdGluZ01hcHBpbmcpIHtcbiAgICAgICAgICAgICAgICBsZXQgcmVzdWx0T2JqID0ge1xuICAgICAgICAgICAgICAgICAgICBjb2x1bW5OYW1lOiBmaWx0ZXJLZXksXG4gICAgICAgICAgICAgICAgICAgIGRhdGFUeXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgICAgICAgICBvcGVyYXRvcjogXCJlcVwiLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogZmlsdGVyW2ZpbHRlcktleV1cbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZmlsdGVyW2ZpbHRlcktleV0pKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdE9iai5vcGVyYXRvciA9IFwiaW5cIjtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0T2JqLnZhbHVlID0gZmlsdGVyW2ZpbHRlcktleV0uam9pbihcIixcIik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0T2JqLnZhbHVlID0gZmlsdGVyW2ZpbHRlcktleV07XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gZm9yIG1jaXQgb25seVxuICAgICAgICAgICAgICAgIGlmIChmaWx0ZXJLZXkgPT0gJ29wZXJhdG9yX2tleScpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0T2JqLm9wZXJhdG9yID0gXCJlcVwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaChyZXN1bHRPYmopO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuXG4gICAgICAgIHJlc3VsdCA9IHJlc3VsdC5maWx0ZXIob2JqID0+IG9iai52YWx1ZSAhPT0gbnVsbCAmJiBvYmoudmFsdWUgIT09IFwiXCIpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuXG5cblxuICAgIGdldERhdGFzZXRGb3JTaW1wbGVBcGlJbXBhbGEoZGF0YXNldDogYW55LCBkYXRhc2V0SWQ6IHN0cmluZywgZmlsdGVycykge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICBkYXRhc2V0LmNvbmZpZy5xdWVyeUNvbmZpZy5tYXBlZEZpbHRlcnMuZm9yRWFjaChmaWx0ZXIgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChmaWx0ZXJzLm9wZXJhdGlvbkZpbHRlci5oYXNPd25Qcm9wZXJ0eShmaWx0ZXIubG9jYWxDb2x1bW4pKSB7XG4gICAgICAgICAgICAgICAgICAgIGZpbHRlci5kZWZhdWx0VmFsdWUgPSBmaWx0ZXJzLm9wZXJhdGlvbkZpbHRlcltmaWx0ZXIubG9jYWxDb2x1bW5dO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKGRhdGFzZXQuY29uZmlnLmFwaVR5cGUgPT09IFwicG9zdFwiKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgc2VydmljZUpzb246IGFueSA9IHt9O1xuICAgICAgICAgICAgICAgIGRhdGFzZXQuY29uZmlnLnF1ZXJ5Q29uZmlnLm1hcGVkRmlsdGVycy5mb3JFYWNoKChmaWx0ZXI6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsZXQgZGF0ZWNvbHVtbiA9IGZpbHRlci5zZXJ2ZXJDb2x1bW4udG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGVjb2x1bW4uaW5jbHVkZXMoJ2RhdGUnKSAmJiB0eXBlb2YgZmlsdGVyLmRhdGFUeXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2VydmljZUpzb25bZmlsdGVyLnNlcnZlckNvbHVtbl0gPSBtb21lbnQoZmlsdGVyLmRlZmF1bHRWYWx1ZSwgXCJZWVlZLU1NLUREXCIpLmZvcm1hdCh0aGlzLmVudmlyb25tZW50LmRhdGFGb3JtYXQpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2VydmljZUpzb25bZmlsdGVyLnNlcnZlckNvbHVtbl0gPSBmaWx0ZXIuZGVmYXVsdFZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9XG5cblxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5zZXJ2aWNlLmdldFNpbXBsZUFwaVBvc3RSZXF1ZXN0KGRhdGFzZXQuY29uZmlnLmFwaSwgc2VydmljZUpzb24pLnN1YnNjcmliZSh7XG4gICAgICAgICAgICAgICAgICAgIG5leHQ6IChkYXRhOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBheWxvYWQgPSBkYXRhW1wiUGF5bG9hZFwiXSB8fCBkYXRhO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51bmlxdWVEYXRhU2V0T2JqZWN0W2RhdGFzZXRJZF0gPSBwYXlsb2FkO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBlcnJvcjogKGVycjogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvcjonLCBlcnIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50b2FzdHIuZXJyb3IoZXJyLm1lc3NhZ2UpXG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGRhdGFzZXQuY29uZmlnLmFwaVR5cGUgPT09IFwiZ2V0XCIpIHtcblxuICAgICAgICAgICAgICAgIGxldCByZXF1ZXN0VXJsID0gZGF0YXNldC5jb25maWcuYXBpICsgXCI/XCI7XG4gICAgICAgICAgICAgICAgZGF0YXNldC5jb25maWcucXVlcnlDb25maWcubWFwZWRGaWx0ZXJzLmZvckVhY2goKGZpbHRlcjogYW55LCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlcXVlc3RVcmwgKz0gYCR7ZmlsdGVyLnNlcnZlckNvbHVtbn09JHtmaWx0ZXIuZGVmYXVsdFZhbHVlfWA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCA8IGRhdGFzZXQuY29uZmlnLnF1ZXJ5Q29uZmlnLm1hcGVkRmlsdGVycy5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0VXJsICs9IFwiJlwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICB0aGlzLnNlcnZpY2UuZ2V0U2ltcGxlQXBpR2V0UmVxdWVzdChyZXF1ZXN0VXJsKS5zdWJzY3JpYmUoe1xuICAgICAgICAgICAgICAgICAgICBuZXh0OiAoZGF0YTogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXlsb2FkID0gZGF0YVtcIlBheWxvYWRcIl0gfHwgZGF0YTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudW5pcXVlRGF0YVNldE9iamVjdFtkYXRhc2V0SWRdID0gcGF5bG9hZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgZXJyb3I6IChlcnI6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3I6JywgZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudG9hc3RyLmVycm9yKGVyci5tZXNzYWdlKVxuXG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIGdldERhdGFzZXRGb3JQbGFpbkpzb24oZGF0YXNldCwgZGF0YXNldElkLCBmaWx0ZXIpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcblxuICAgICAgICAgICAgbGV0IHJlcXVlc3RhcGkgPSBkYXRhc2V0LmNvbmZpZy5hcGkgKyAnP2RhdGFzZXRJZD0nICsgZGF0YXNldC5kYXRhc2V0SWQ7XG4gICAgICAgICAgICB0aGlzLnNlcnZpY2UuZ2V0SnNvbkRhdGFzZXRQYXlsb2FkKHJlcXVlc3RhcGkpLnN1YnNjcmliZSh7XG4gICAgICAgICAgICAgICAgbmV4dDogKGRhdGE6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXlsb2FkID0gZGF0YVtcIlBheWxvYWRcIl0gfHwgZGF0YTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51bmlxdWVEYXRhU2V0T2JqZWN0W2RhdGFzZXRJZF0gPSBwYXlsb2FkO1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG5cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGVycm9yOiAoZXJyOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3I6JywgZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuXG4gICAgZ2V0RGF0YXNldEZvclNxbFRlbXBsYXRlKGRhdGFzZXQsIGRhdGFzZXRJZCwgZmlsdGVycykge1xuXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cblxuICAgICAgICAgICAgY29uc3Qgb3BlcmF0b3IgPSAoZmlsdGVycyAmJiBmaWx0ZXJzLmxlbmd0aCAhPT0gMCkgPyBPYmplY3Qua2V5cyhmaWx0ZXJzLm9wZXJhdGlvbkZpbHRlcikubWFwKGtleSA9PiAoeyBba2V5XTogZmlsdGVycy5vcGVyYXRpb25GaWx0ZXJba2V5XSB9KSkgOiBbXTtcblxuICAgICAgICAgICAgbGV0IHJlcXVlc3RBcCA9IGRhdGFzZXQuY29uZmlnLmFwaTtcbiAgICAgICAgICAgIGxldCByZXF1ZXN0X3BhcmFtcyA9IHtcbiAgICAgICAgICAgICAgICAnZGJDb25maWcnOiBkYXRhc2V0LmNvbmZpZy5xdWVyeUNvbmZpZy5kYkNvbmZpZyxcbiAgICAgICAgICAgICAgICAnZGF0YWJhc2VOYW1lJzogZGF0YXNldC5jb25maWcucXVlcnlDb25maWcuZGF0YWJhc2VOYW1lLFxuICAgICAgICAgICAgICAgICdmaWx0ZXJzJzogdGhpcy50cmFuc2Zvcm1EYXRhRm9yTUZpbHRlckZvclNRbChvcGVyYXRvciwgZGF0YXNldC5jb25maWcucXVlcnlDb25maWcubWFwZWRGaWx0ZXJzKSxcbiAgICAgICAgICAgICAgICAndGVtcGxhdGVRdWVyeSc6IGRhdGFzZXQuY29uZmlnLnF1ZXJ5Q29uZmlnLnRlbXBsYXRlUXVlcnksXG4gICAgICAgICAgICAgICAgJ2VucmljaG1lbnRzJzogZGF0YXNldC5jb25maWcucXVlcnlDb25maWcuZW5yaWNobWVudHMsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNlcnZpY2UuZ2VuZXJpY1NxbFF1ZXJ5UmVzcG9uc2UocmVxdWVzdEFwLCByZXF1ZXN0X3BhcmFtcykuc3Vic2NyaWJlKHtcbiAgICAgICAgICAgICAgICBuZXh0OiAoZGF0YTogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBheWxvYWQgPSBkYXRhW1wiUGF5bG9hZFwiXSB8fCBkYXRhO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnVuaXF1ZURhdGFTZXRPYmplY3RbZGF0YXNldElkXSA9IHBheWxvYWQ7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGVycm9yOiAoZXJyOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3I6JywgZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50b2FzdHIuZXJyb3IoZXJyLm1lc3NhZ2UpXG5cbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgdHJhbnNmb3JtRGF0YUZvck1GaWx0ZXJGb3JTUWwoZmlsdGVyZGF0YSwgbWFwRGF0YSkge1xuXG4gICAgICAgIGxldCByZXN1bHQgPSBbXTtcbiAgICAgICAgbWFwRGF0YS5mb3JFYWNoKG1hcHBpbmcgPT4ge1xuICAgICAgICAgICAgbGV0IHJlc3VsdE9iaiA9IHtcbiAgICAgICAgICAgICAgICBjb2x1bW5OYW1lOiBtYXBwaW5nLnNlcnZlckNvbHVtbixcbiAgICAgICAgICAgICAgICBkYXRhVHlwZTogbWFwcGluZy5kYXRhVHlwZSxcbiAgICAgICAgICAgICAgICBvcGVyYXRvcjogbWFwcGluZy5vcGVyYXRvck5hbWUsXG4gICAgICAgICAgICAgICAgdmFsdWU6IG1hcHBpbmcuZGVmYXVsdFZhbHVlLFxuICAgICAgICAgICAgICAgIGFsaWFzQ29sdW1uTmFtZTogbWFwcGluZy5sb2NhbENvbHVtbixcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBpZiAobWFwcGluZy5zZXJ2ZXJDb2x1bW4uaW5jbHVkZXMoJ2RhdGUnKSAmJiB0eXBlb2YgcmVzdWx0T2JqLnZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIGlmIChtYXBwaW5nLmZvcm1hdHRlciAmJiBtYXBwaW5nLmZvcm1hdHRlciAhPT0gXCJcIikge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHRPYmoudmFsdWUgPSBtb21lbnQocmVzdWx0T2JqLnZhbHVlLCBcIllZWVktTU0tRERcIikuZm9ybWF0KG1hcHBpbmcuZm9ybWF0dGVyKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHRPYmoudmFsdWUgPSBtb21lbnQocmVzdWx0T2JqLnZhbHVlLCBcIllZWVktTU0tRERcIikuZm9ybWF0KHRoaXMuZW52aXJvbm1lbnQuZGF0YUZvcm1hdCk7XG5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBmaWx0ZXIgPSBmaWx0ZXJkYXRhLmZpbmQoZiA9PiBmLmhhc093blByb3BlcnR5KG1hcHBpbmcubG9jYWxDb2x1bW4pKTtcbiAgICAgICAgICAgIGlmIChmaWx0ZXIpIHtcbiAgICAgICAgICAgICAgICBpZiAobWFwcGluZy5kZWZhdWx0VmFsdWUgPT09IFwiXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBmaWx0ZXJbbWFwcGluZy5sb2NhbENvbHVtbl07XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRPYmoub3BlcmF0b3IgPSBcImluXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRPYmoudmFsdWUgPSB2YWx1ZS5qb2luKFwiLFwiKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdE9iai52YWx1ZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChtYXBwaW5nLnNlcnZlckNvbHVtbi5pbmNsdWRlcygnZGF0ZScpICYmIHR5cGVvZiByZXN1bHRPYmoudmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRPYmoudmFsdWUgPSBtb21lbnQocmVzdWx0T2JqLnZhbHVlLCBcIllZWVktTU0tRERcIikuZm9ybWF0KHRoaXMuZW52aXJvbm1lbnQuZGF0YUZvcm1hdCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKG1hcHBpbmcuZGVmYXVsdFZhbHVlID09PSBcIlwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzdWx0LnB1c2gocmVzdWx0T2JqKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGZpbHRlcmRhdGEgPSBmaWx0ZXJkYXRhLmZpbHRlcihvYmogPT4ge1xuICAgICAgICAgICAgY29uc3Qga2V5ID0gT2JqZWN0LmtleXMob2JqKVswXTtcbiAgICAgICAgICAgIHJldHVybiBrZXkgIT09ICdzdGFydERhdGUnICYmIGtleSAhPT0gJ2VuZERhdGUnO1xuICAgICAgICB9KTsgZmlsdGVyZGF0YS5mb3JFYWNoKGZpbHRlciA9PiB7XG4gICAgICAgICAgICBjb25zdCBmaWx0ZXJLZXkgPSBPYmplY3Qua2V5cyhmaWx0ZXIpWzBdO1xuICAgICAgICAgICAgY29uc3QgZXhpc3RpbmdNYXBwaW5nID0gbWFwRGF0YS5maW5kKG1hcHBpbmcgPT4gbWFwcGluZy5sb2NhbENvbHVtbiA9PT0gZmlsdGVyS2V5KTtcblxuICAgICAgICAgICAgaWYgKCFleGlzdGluZ01hcHBpbmcpIHtcbiAgICAgICAgICAgICAgICBsZXQgcmVzdWx0T2JqID0ge1xuICAgICAgICAgICAgICAgICAgICBjb2x1bW5OYW1lOiBmaWx0ZXJLZXksXG4gICAgICAgICAgICAgICAgICAgIGRhdGFUeXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgICAgICAgICBvcGVyYXRvcjogXCJlcVwiLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogZmlsdGVyW2ZpbHRlcktleV1cbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZmlsdGVyW2ZpbHRlcktleV0pKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdE9iai5vcGVyYXRvciA9IFwiaW5cIjtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0T2JqLnZhbHVlID0gZmlsdGVyW2ZpbHRlcktleV0uam9pbihcIixcIik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0T2JqLnZhbHVlID0gZmlsdGVyW2ZpbHRlcktleV07XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gZm9yIG1jaXQgb25seVxuICAgICAgICAgICAgICAgIGlmIChmaWx0ZXJLZXkgPT0gJ29wZXJhdG9yX2tleScpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0T2JqLm9wZXJhdG9yID0gXCJlcVwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaChyZXN1bHRPYmopO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuXG4gICAgICAgIC8vIHJlc3VsdCA9IHJlc3VsdC5maWx0ZXIob2JqID0+IG9iai52YWx1ZSAhPT0gbnVsbCAmJiBvYmoudmFsdWUgIT09IFwiXCIpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuXG4gICAgZ2V0VW5pcXVlRGF0YVNldE9iamVjdCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudW5pcXVlRGF0YVNldE9iamVjdDtcbiAgICB9XG5cblxufVxuIl19
32
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVsdGktbGFuZGluZy1kYXRhc2V0LWNhbGwuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2dhbW1hLWFwcC1jb250cm9sbGVyL3NyYy9saWIvdGVtcGxhdGUtbW9kdWxlL2RlZmF1bExhbmRpbmdNdWx0aUxheW91dENvbXBvbmVudC9tdWx0aS1sYW5kaW5nLWRhdGFzZXQtY2FsbC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQXdaQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUduRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMENBQTBDLENBQUM7Ozs7OztBQUkzRSxNQUFNLE9BQU8seUNBQXlDO0lBQ3BELFlBQ1UsT0FBMkMsRUFDM0MsTUFBa0MsRUFDbEMsVUFBNEIsRUFDNUIsTUFBcUIsRUFDSSxXQUFnQjtRQUp6QyxZQUFPLEdBQVAsT0FBTyxDQUFvQztRQUMzQyxXQUFNLEdBQU4sTUFBTSxDQUE0QjtRQUNsQyxlQUFVLEdBQVYsVUFBVSxDQUFrQjtRQUM1QixXQUFNLEdBQU4sTUFBTSxDQUFlO1FBQ0ksZ0JBQVcsR0FBWCxXQUFXLENBQUs7SUFDaEQsQ0FBQztJQUVKLGtCQUFrQixDQUFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsT0FBTztRQUM1QyxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ25GLENBQUM7SUFFRCxzQkFBc0I7UUFDcEIsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLHNCQUFzQixFQUFFLENBQUM7SUFDOUMsQ0FBQzs7c0lBZlUseUNBQXlDLDJLQU0xQyxlQUFlOzBJQU5kLHlDQUF5QyxjQUQ1QixNQUFNOzJGQUNuQix5Q0FBeUM7a0JBRHJELFVBQVU7bUJBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFOzswQkFPN0IsTUFBTTsyQkFBQyxlQUFlIiwic291cmNlc0NvbnRlbnQiOlsiLy8gaW1wb3J0IHsgSW5qZWN0LCBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbi8vIC8vIGltcG9ydCBtb21lbnQgZnJvbSAnbW9tZW50Jztcbi8vIGltcG9ydCBtb21lbnQgZnJvbSAnLi4vLi4vYXBwbGljYXRpb24tY29udHJvbGxlci9tb21lbnQtaGVscGVyJztcbi8vIGltcG9ydCB7IFRvYXN0clNlcnZpY2UgfSBmcm9tICduZ3gtdG9hc3RyJztcbi8vIGltcG9ydCB7IEFQUF9FTlZJUk9OTUVOVCB9IGZyb20gJy4uLy4uL2FwcGxpY2F0aW9uLWNvbnRyb2xsZXIvZW52aXJvbm1lbnQnO1xuLy8gaW1wb3J0IHsga3BpY29tbW9uU2VydmljZSB9IGZyb20gJy4uLy4uL2FwcGxpY2F0aW9uLWNvbnRyb2xsZXIva3BpLXNlcnZpY2UnO1xuLy8gaW1wb3J0IHsgTGFuZGluZ011bHRpTGF5b3V0Q29tcG9uZW50U2VydmljZSB9IGZyb20gJy4vZGVmYXVsTGFuZGluZ011bHRpTGF5b3V0LnNlcnZpY2UnO1xuXG5cbi8vIEBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogXCJyb290XCIgfSlcbi8vIGV4cG9ydCBjbGFzcyBMYW5kaW5nTXVsdGlMYXlvdXRBcHBsaWNhdGlvbkRhdHNzZXRzQ2FsbCB7XG5cbi8vICAgICB1bmlxdWVEYXRhU2V0T2JqZWN0ID0ge307XG5cbi8vICAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIHNlcnZpY2U6IExhbmRpbmdNdWx0aUxheW91dENvbXBvbmVudFNlcnZpY2UsXG4vLyAgICAgICAgIHByaXZhdGUga3BpU2VydmljZToga3BpY29tbW9uU2VydmljZSxcbi8vICAgICAgICAgcHJpdmF0ZSB0b2FzdHI6IFRvYXN0clNlcnZpY2UsXG4vLyAgICAgICAgIEBJbmplY3QoQVBQX0VOVklST05NRU5UKSBwcml2YXRlIGVudmlyb25tZW50OiBhbnlcbi8vICAgICApIHtcblxuLy8gICAgIH1cblxuLy8gICAgIGdldERhdGFGcm9tRGF0YVNldChkYXRhc2V0LCBkYXRhc2V0SWQsIGZpbHRlcnMpIHtcbi8vICAgICAgICAgaWYgKGRhdGFzZXQuZGF0YXNldFR5cGUgPT0gXCJtb25nb1wiKSB7XG4vLyAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXREYXRhU2V0Rm9yTW9uZ28oZGF0YXNldCwgZGF0YXNldElkKTtcbi8vICAgICAgICAgfSBlbHNlIGlmIChkYXRhc2V0LmRhdGFzZXRUeXBlID09IFwicXVlcnlidWlsZGVyXCIpIHtcbi8vICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldERhdGFzZXRGb3JJbXBhbGEoZGF0YXNldCwgZGF0YXNldElkLCBmaWx0ZXJzKTtcbi8vICAgICAgICAgfSBlbHNlIGlmIChkYXRhc2V0LmRhdGFzZXRUeXBlID09IFwic2ltcGxlQXBpXCIpIHtcbi8vICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldERhdGFzZXRGb3JTaW1wbGVBcGlJbXBhbGEoZGF0YXNldCwgZGF0YXNldElkLCBmaWx0ZXJzKTtcbi8vICAgICAgICAgfSBlbHNlIGlmIChkYXRhc2V0LmRhdGFzZXRUeXBlID09IFwicGxhaW5qc29uXCIpIHtcbi8vICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldERhdGFzZXRGb3JQbGFpbkpzb24oZGF0YXNldCwgZGF0YXNldElkLCBmaWx0ZXJzKTtcbi8vICAgICAgICAgfSBlbHNlIGlmIChkYXRhc2V0LmRhdGFzZXRUeXBlID09IFwic3FsUXVlcnlcIikge1xuLy8gICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RGF0YXNldEZvclNxbFRlbXBsYXRlKGRhdGFzZXQsIGRhdGFzZXRJZCwgZmlsdGVycyk7XG4vLyAgICAgICAgIH0gZWxzZSB7XG4vLyAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4vLyAgICAgICAgIH1cbi8vICAgICB9XG5cblxuLy8gICAgIGdldERhdGFTZXRGb3JNb25nbyhkYXRhc2V0LCBkYXRhc2V0SWQpIHtcbi8vICAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbi8vICAgICAgICAgICAgIGxldCBhcGlKc29uT2JqZWN0ID0ge1xuLy8gICAgICAgICAgICAgICAgIHJlcXVlc3RJZDogZGF0YXNldC5jb25maWcuc2VydmljZUlkLFxuLy8gICAgICAgICAgICAgfTtcbi8vICAgICAgICAgICAgIGlmIChkYXRhc2V0LmNvbmZpZy5maXhPcGVyYXRpb25MZXZsZXMgJiYgZGF0YXNldC5jb25maWcuZml4T3BlcmF0aW9uTGV2bGVzLmxlbmd0aCAhPSAwKSB7XG4vLyAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGRhdGFzZXQuY29uZmlnLmZpeE9wZXJhdGlvbkxldmxlcykge1xuLy8gICAgICAgICAgICAgICAgICAgICBPYmplY3QuYXNzaWduKGFwaUpzb25PYmplY3QsIGl0ZW0pO1xuLy8gICAgICAgICAgICAgICAgIH1cbi8vICAgICAgICAgICAgIH1cbi8vICAgICAgICAgICAgIGNvbnN0IG1vbl9jb25maWcgPSB0aGlzLmtwaVNlcnZpY2UuZ2V0QWxsU2V2aWNlQXBpSnNvbihhcGlKc29uT2JqZWN0KTtcbi8vICAgICAgICAgICAgIHRoaXMuc2VydmljZS5nZXREYXRhKG1vbl9jb25maWcsIGRhdGFzZXQuY29uZmlnLmFwaSkuc3Vic2NyaWJlKHtcbi8vICAgICAgICAgICAgICAgICBuZXh0OiAoZGF0YTogYW55KSA9PiB7XG4vLyAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBheWxvYWQgPSBkYXRhW1wiUGF5bG9hZFwiXSB8fCBkYXRhO1xuLy8gICAgICAgICAgICAgICAgICAgICAvLyB0aGlzLnVuaXF1ZURhdGFTZXRPYmplY3RbZGF0YXNldElkXSA9IHBheWxvYWQuc2xpY2UoMCwgMjApO1xuLy8gICAgICAgICAgICAgICAgICAgICB0aGlzLnVuaXF1ZURhdGFTZXRPYmplY3RbZGF0YXNldElkXSA9IHBheWxvYWQ7XG4vLyAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbi8vICAgICAgICAgICAgICAgICB9LFxuLy8gICAgICAgICAgICAgICAgIGVycm9yOiAoZXJyOiBhbnkpID0+IHtcbi8vICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3I6JywgZXJyKTtcbi8vICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4vLyAgICAgICAgICAgICAgICAgfVxuLy8gICAgICAgICAgICAgfSk7XG4vLyAgICAgICAgIH0pO1xuLy8gICAgIH1cblxuLy8gICAgIGdldERhdGFzZXRGb3JJbXBhbGEoZGF0YXNldCwgZGF0YXNldElkLCBmaWx0ZXJzKSB7XG4vLyAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4vLyAgICAgICAgICAgICBsZXQgcmVxdWVzdCA9IGRhdGFzZXQuY29uZmlnLnF1ZXJ5Q29uZmlnO1xuLy8gICAgICAgICAgICAgbGV0IHRyYW5zZm9ybWVkT2JqZWN0OiBhbnkgPSB7fTtcbi8vICAgICAgICAgICAgIGZvciAobGV0IGl0ZW0gb2YgcmVxdWVzdC5yZXFGaWVsZHMpIHtcbi8vICAgICAgICAgICAgICAgICBjb25zdCBrZXkgPSBPYmplY3Qua2V5cyhpdGVtKVswXTtcbi8vICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IE9iamVjdC52YWx1ZXMoaXRlbSlbMF07XG4vLyAgICAgICAgICAgICAgICAgaWYgKGtleSA9PT0gJ3N0YXJ0RGF0ZScpIHtcbi8vICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtZWRPYmplY3QucmVjb3JkRGF0ZSA9IHZhbHVlO1xuLy8gICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4vLyAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybWVkT2JqZWN0W2tleV0gPSB2YWx1ZTtcbi8vICAgICAgICAgICAgICAgICB9XG4vLyAgICAgICAgICAgICB9XG4vLyAgICAgICAgICAgICBjb25zdCBvcGVyYXRvciA9IChmaWx0ZXJzICYmIGZpbHRlcnMubGVuZ3RoICE9PSAwKSA/IE9iamVjdC5rZXlzKGZpbHRlcnMub3BlcmF0aW9uRmlsdGVyKS5tYXAoa2V5ID0+ICh7IFtrZXldOiBmaWx0ZXJzLm9wZXJhdGlvbkZpbHRlcltrZXldIH0pKSA6IFtdO1xuXG5cbi8vICAgICAgICAgICAgIHRyYW5zZm9ybWVkT2JqZWN0WydmaWx0ZXJzJ10gPSB0aGlzLnRyYW5zZm9ybURhdGFGb3JNRmlsdGVyKG9wZXJhdG9yLCByZXF1ZXN0Lm1hcGVkRmlsdGVycyk7XG4vLyAgICAgICAgICAgICB0cmFuc2Zvcm1lZE9iamVjdFsnc29ydGVycyddID0gcmVxdWVzdC5zb3J0ZXJzO1xuLy8gICAgICAgICAgICAgdHJhbnNmb3JtZWRPYmplY3RbXCJwYWdpbmF0aW9uUmVxdWlyZWRcIl0gPSBmYWxzZTtcblxuLy8gICAgICAgICAgICAgaWYgKGRhdGFzZXQuY29uZmlnLmFwaSA9PSBcIi9rcGkvZ2VuZXJpY0FnZ3JlZ2F0ZVBhZ2luYXRlZEtwaVNlcnZpY2VSZXNwb25zZVwiKSB7XG4vLyAgICAgICAgICAgICAgICAgdHJhbnNmb3JtZWRPYmplY3RbJ21lYXN1cmVzJ10gPSByZXF1ZXN0Lm1lYXN1cmVzO1xuLy8gICAgICAgICAgICAgICAgIHRyYW5zZm9ybWVkT2JqZWN0WydkaW1lbnNpb25zJ10gPSByZXF1ZXN0LmRpbWVuc2lvbnM7XG4vLyAgICAgICAgICAgICB9IGVsc2Uge1xuLy8gICAgICAgICAgICAgICAgIHRyYW5zZm9ybWVkT2JqZWN0Wydjb2x1bW5zJ10gPSB0aGlzLmdldEZvcm1hdE9iamVjdEZvckNvbHVtbihyZXF1ZXN0LmNvbHVtbnMpO1xuLy8gICAgICAgICAgICAgfVxuLy8gICAgICAgICAgICAgaWYgKHJlcXVlc3QuaGF2aW5ncyAmJiByZXF1ZXN0LmhhdmluZ3MubGVuZ3RoICE9PSAwKSB7XG4vLyAgICAgICAgICAgICAgICAgdHJhbnNmb3JtZWRPYmplY3RbJ2hhdmluZ3MnXSA9IHJlcXVlc3QuaGF2aW5ncztcbi8vICAgICAgICAgICAgIH1cblxuXG4vLyAgICAgICAgICAgICB0aGlzLnNlcnZpY2UuZ2V0RGF0YSh0cmFuc2Zvcm1lZE9iamVjdCwgZGF0YXNldC5jb25maWcuYXBpKS5zdWJzY3JpYmUoe1xuLy8gICAgICAgICAgICAgICAgIG5leHQ6IChkYXRhOiBhbnkpID0+IHtcbi8vICAgICAgICAgICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IGRhdGFbJ2RhdGFzZXQnXTtcbi8vICAgICAgICAgICAgICAgICAgICAgLy8gdGhpcy51bmlxdWVEYXRhU2V0T2JqZWN0W2RhdGFzZXRJZF0gPSBwYXlsb2FkLnNsaWNlKDAsIDMwKTtcbi8vICAgICAgICAgICAgICAgICAgICAgdGhpcy51bmlxdWVEYXRhU2V0T2JqZWN0W2RhdGFzZXRJZF0gPSBwYXlsb2FkO1xuLy8gICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4vLyAgICAgICAgICAgICAgICAgfSxcbi8vICAgICAgICAgICAgICAgICBlcnJvcjogKGVycjogYW55KSA9PiB7XG4vLyAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yOicsIGVycik7XG4vLyAgICAgICAgICAgICAgICAgICAgIHRoaXMudG9hc3RyLmVycm9yKGVyci5tZXNzYWdlKVxuLy8gICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyKTtcbi8vICAgICAgICAgICAgICAgICB9XG4vLyAgICAgICAgICAgICB9KTtcbi8vICAgICAgICAgfSk7XG4vLyAgICAgfVxuXG5cbi8vICAgICBnZXRGb3JtYXRPYmplY3RGb3JDb2x1bW4oY29sdW1ucykge1xuLy8gICAgICAgICBsZXQgY29sdW1uRGF0YSA9IFtdO1xuLy8gICAgICAgICBjb2x1bW5zLmZvckVhY2goZWxlbWVudCA9PiB7XG4vLyAgICAgICAgICAgICBjb25zdCB7IGFkdmFuY2VkQ29sdW1uLCBjb2x1bW5OYW1lLCBlbnJpY2hGdW5jdGlvbiwgZGF0YUZpZWxkIH0gPSBlbGVtZW50O1xuLy8gICAgICAgICAgICAgY29sdW1uRGF0YS5wdXNoKHtcbi8vICAgICAgICAgICAgICAgICBcImFkdmFuY2VkQ29sdW1uXCI6IGFkdmFuY2VkQ29sdW1uLFxuLy8gICAgICAgICAgICAgICAgIFwiY29sdW1uTmFtZVwiOiBjb2x1bW5OYW1lLFxuLy8gICAgICAgICAgICAgICAgIFwiZW5yaWNoRnVuY3Rpb25cIjogZW5yaWNoRnVuY3Rpb24sXG4vLyAgICAgICAgICAgICAgICAgXCJhbGlhc05hbWVcIjogZGF0YUZpZWxkXG4vLyAgICAgICAgICAgICB9KVxuLy8gICAgICAgICB9KTtcbi8vICAgICAgICAgcmV0dXJuIGNvbHVtbkRhdGE7XG4vLyAgICAgfVxuXG4vLyAgICAgdHJhbnNmb3JtRGF0YUZvck1GaWx0ZXIoZmlsdGVyZGF0YSwgbWFwRGF0YSkge1xuLy8gICAgICAgICBsZXQgcmVzdWx0ID0gW107XG4vLyAgICAgICAgIG1hcERhdGEuZm9yRWFjaChtYXBwaW5nID0+IHtcbi8vICAgICAgICAgICAgIGxldCByZXN1bHRPYmogPSB7XG4vLyAgICAgICAgICAgICAgICAgY29sdW1uTmFtZTogbWFwcGluZy5zZXJ2ZXJDb2x1bW4sXG4vLyAgICAgICAgICAgICAgICAgZGF0YVR5cGU6IG1hcHBpbmcuZGF0YVR5cGUsXG4vLyAgICAgICAgICAgICAgICAgb3BlcmF0b3I6IG1hcHBpbmcub3BlcmF0b3JOYW1lLFxuLy8gICAgICAgICAgICAgICAgIHZhbHVlOiBtYXBwaW5nLmRlZmF1bHRWYWx1ZVxuLy8gICAgICAgICAgICAgfTtcbi8vICAgICAgICAgICAgIGlmIChtYXBwaW5nLnNlcnZlckNvbHVtbi5pbmNsdWRlcygnZGF0ZScpICYmIHR5cGVvZiByZXN1bHRPYmoudmFsdWUgPT09ICdzdHJpbmcnKSB7XG4vLyAgICAgICAgICAgICAgICAgaWYgKG1hcHBpbmcuZm9ybWF0dGVyICYmIG1hcHBpbmcuZm9ybWF0dGVyICE9PSBcIlwiKSB7XG4vLyAgICAgICAgICAgICAgICAgICAgIHJlc3VsdE9iai52YWx1ZSA9IG1vbWVudChyZXN1bHRPYmoudmFsdWUsIFwiWVlZWS1NTS1ERFwiKS5mb3JtYXQobWFwcGluZy5mb3JtYXR0ZXIpO1xuLy8gICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4vLyAgICAgICAgICAgICAgICAgICAgIHJlc3VsdE9iai52YWx1ZSA9IG1vbWVudChyZXN1bHRPYmoudmFsdWUsIFwiWVlZWS1NTS1ERFwiKS5mb3JtYXQodGhpcy5lbnZpcm9ubWVudC5kYXRhRm9ybWF0KTtcblxuLy8gICAgICAgICAgICAgICAgIH1cbi8vICAgICAgICAgICAgIH1cbi8vICAgICAgICAgICAgIGNvbnN0IGZpbHRlciA9IGZpbHRlcmRhdGEuZmluZChmID0+IGYuaGFzT3duUHJvcGVydHkobWFwcGluZy5sb2NhbENvbHVtbikpO1xuLy8gICAgICAgICAgICAgaWYgKGZpbHRlcikge1xuLy8gICAgICAgICAgICAgICAgIGlmIChtYXBwaW5nLmRlZmF1bHRWYWx1ZSA9PT0gXCJcIikge1xuLy8gICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGZpbHRlclttYXBwaW5nLmxvY2FsQ29sdW1uXTtcblxuLy8gICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbi8vICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdE9iai5vcGVyYXRvciA9IFwiaW5cIjtcbi8vICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdE9iai52YWx1ZSA9IHZhbHVlLmpvaW4oXCIsXCIpO1xuLy8gICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuLy8gICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0T2JqLnZhbHVlID0gdmFsdWU7XG4vLyAgICAgICAgICAgICAgICAgICAgIH1cbi8vICAgICAgICAgICAgICAgICAgICAgaWYgKG1hcHBpbmcuc2VydmVyQ29sdW1uLmluY2x1ZGVzKCdkYXRlJykgJiYgdHlwZW9mIHJlc3VsdE9iai52YWx1ZSA9PT0gJ3N0cmluZycpIHtcbi8vICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtYXBwaW5nLmZvcm1hdHRlciAmJiBtYXBwaW5nLmZvcm1hdHRlciAhPT0gXCJcIikge1xuLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdE9iai52YWx1ZSA9IG1vbWVudChyZXN1bHRPYmoudmFsdWUsIFwiWVlZWS1NTS1ERFwiKS5mb3JtYXQobWFwcGluZy5mb3JtYXR0ZXIpO1xuLy8gICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRPYmoudmFsdWUgPSBtb21lbnQocmVzdWx0T2JqLnZhbHVlLCBcIllZWVktTU0tRERcIikuZm9ybWF0KHRoaXMuZW52aXJvbm1lbnQuZGF0YUZvcm1hdCk7XG5cbi8vICAgICAgICAgICAgICAgICAgICAgICAgIH1cbi8vICAgICAgICAgICAgICAgICAgICAgfVxuLy8gICAgICAgICAgICAgICAgIH1cbi8vICAgICAgICAgICAgIH0gZWxzZSBpZiAobWFwcGluZy5kZWZhdWx0VmFsdWUgPT09IFwiXCIpIHtcbi8vICAgICAgICAgICAgICAgICByZXR1cm47XG4vLyAgICAgICAgICAgICB9XG4vLyAgICAgICAgICAgICByZXN1bHQucHVzaChyZXN1bHRPYmopO1xuLy8gICAgICAgICB9KTtcbi8vICAgICAgICAgZmlsdGVyZGF0YSA9IGZpbHRlcmRhdGEuZmlsdGVyKG9iaiA9PiB7XG4vLyAgICAgICAgICAgICBjb25zdCBrZXkgPSBPYmplY3Qua2V5cyhvYmopWzBdO1xuLy8gICAgICAgICAgICAgcmV0dXJuIGtleSAhPT0gJ3N0YXJ0RGF0ZScgJiYga2V5ICE9PSAnZW5kRGF0ZSc7XG4vLyAgICAgICAgIH0pO1xuLy8gICAgICAgICBmaWx0ZXJkYXRhLmZvckVhY2goZmlsdGVyID0+IHtcbi8vICAgICAgICAgICAgIGNvbnN0IGZpbHRlcktleSA9IE9iamVjdC5rZXlzKGZpbHRlcilbMF07XG4vLyAgICAgICAgICAgICBjb25zdCBleGlzdGluZ01hcHBpbmcgPSBtYXBEYXRhLmZpbmQobWFwcGluZyA9PiBtYXBwaW5nLmxvY2FsQ29sdW1uID09PSBmaWx0ZXJLZXkpO1xuXG4vLyAgICAgICAgICAgICBpZiAoIWV4aXN0aW5nTWFwcGluZykge1xuLy8gICAgICAgICAgICAgICAgIGxldCByZXN1bHRPYmogPSB7XG4vLyAgICAgICAgICAgICAgICAgICAgIGNvbHVtbk5hbWU6IGZpbHRlcktleSxcbi8vICAgICAgICAgICAgICAgICAgICAgZGF0YVR5cGU6IFwic3RyaW5nXCIsXG4vLyAgICAgICAgICAgICAgICAgICAgIG9wZXJhdG9yOiBcImVxXCIsXG4vLyAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiBmaWx0ZXJbZmlsdGVyS2V5XVxuLy8gICAgICAgICAgICAgICAgIH07XG5cbi8vICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShmaWx0ZXJbZmlsdGVyS2V5XSkpIHtcbi8vICAgICAgICAgICAgICAgICAgICAgcmVzdWx0T2JqLm9wZXJhdG9yID0gXCJpblwiO1xuLy8gICAgICAgICAgICAgICAgICAgICByZXN1bHRPYmoudmFsdWUgPSBmaWx0ZXJbZmlsdGVyS2V5XS5qb2luKFwiLFwiKTtcbi8vICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuLy8gICAgICAgICAgICAgICAgICAgICByZXN1bHRPYmoudmFsdWUgPSBmaWx0ZXJbZmlsdGVyS2V5XTtcbi8vICAgICAgICAgICAgICAgICB9XG5cbi8vICAgICAgICAgICAgICAgICAvLyBmb3IgbWNpdCBvbmx5XG4vLyAgICAgICAgICAgICAgICAgaWYgKGZpbHRlcktleSA9PSAnb3BlcmF0b3Jfa2V5Jykge1xuLy8gICAgICAgICAgICAgICAgICAgICByZXN1bHRPYmoub3BlcmF0b3IgPSBcImVxXCI7XG4vLyAgICAgICAgICAgICAgICAgfVxuLy8gICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHJlc3VsdE9iaik7XG4vLyAgICAgICAgICAgICB9XG4vLyAgICAgICAgIH0pO1xuXG5cbi8vICAgICAgICAgcmVzdWx0ID0gcmVzdWx0LmZpbHRlcihvYmogPT4gb2JqLnZhbHVlICE9PSBudWxsICYmIG9iai52YWx1ZSAhPT0gXCJcIik7XG4vLyAgICAgICAgIHJldHVybiByZXN1bHQ7XG4vLyAgICAgfVxuXG5cblxuXG4vLyAgICAgZ2V0RGF0YXNldEZvclNpbXBsZUFwaUltcGFsYShkYXRhc2V0OiBhbnksIGRhdGFzZXRJZDogc3RyaW5nLCBmaWx0ZXJzKSB7XG4vLyAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbi8vICAgICAgICAgICAgIGRhdGFzZXQuY29uZmlnLnF1ZXJ5Q29uZmlnLm1hcGVkRmlsdGVycy5mb3JFYWNoKGZpbHRlciA9PiB7XG4vLyAgICAgICAgICAgICAgICAgaWYgKGZpbHRlcnMub3BlcmF0aW9uRmlsdGVyLmhhc093blByb3BlcnR5KGZpbHRlci5sb2NhbENvbHVtbikpIHtcbi8vICAgICAgICAgICAgICAgICAgICAgZmlsdGVyLmRlZmF1bHRWYWx1ZSA9IGZpbHRlcnMub3BlcmF0aW9uRmlsdGVyW2ZpbHRlci5sb2NhbENvbHVtbl07XG4vLyAgICAgICAgICAgICAgICAgfVxuLy8gICAgICAgICAgICAgfSk7XG4vLyAgICAgICAgICAgICBpZiAoZGF0YXNldC5jb25maWcuYXBpVHlwZSA9PT0gXCJwb3N0XCIpIHtcblxuLy8gICAgICAgICAgICAgICAgIGxldCBzZXJ2aWNlSnNvbjogYW55ID0ge307XG4vLyAgICAgICAgICAgICAgICAgZGF0YXNldC5jb25maWcucXVlcnlDb25maWcubWFwZWRGaWx0ZXJzLmZvckVhY2goKGZpbHRlcjogYW55KSA9PiB7XG4vLyAgICAgICAgICAgICAgICAgICAgIGxldCBkYXRlY29sdW1uID0gZmlsdGVyLnNlcnZlckNvbHVtbi50b0xvd2VyQ2FzZSgpO1xuLy8gICAgICAgICAgICAgICAgICAgICBpZiAoZGF0ZWNvbHVtbi5pbmNsdWRlcygnZGF0ZScpICYmIHR5cGVvZiBmaWx0ZXIuZGF0YVR5cGUgPT09ICdzdHJpbmcnKSB7XG4vLyAgICAgICAgICAgICAgICAgICAgICAgICBzZXJ2aWNlSnNvbltmaWx0ZXIuc2VydmVyQ29sdW1uXSA9IG1vbWVudChmaWx0ZXIuZGVmYXVsdFZhbHVlLCBcIllZWVktTU0tRERcIikuZm9ybWF0KHRoaXMuZW52aXJvbm1lbnQuZGF0YUZvcm1hdCk7XG4vLyAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4vLyAgICAgICAgICAgICAgICAgICAgICAgICBzZXJ2aWNlSnNvbltmaWx0ZXIuc2VydmVyQ29sdW1uXSA9IGZpbHRlci5kZWZhdWx0VmFsdWU7XG4vLyAgICAgICAgICAgICAgICAgICAgIH1cblxuXG4vLyAgICAgICAgICAgICAgICAgfSk7XG5cbi8vICAgICAgICAgICAgICAgICB0aGlzLnNlcnZpY2UuZ2V0U2ltcGxlQXBpUG9zdFJlcXVlc3QoZGF0YXNldC5jb25maWcuYXBpLCBzZXJ2aWNlSnNvbikuc3Vic2NyaWJlKHtcbi8vICAgICAgICAgICAgICAgICAgICAgbmV4dDogKGRhdGE6IGFueSkgPT4ge1xuLy8gICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IGRhdGFbXCJQYXlsb2FkXCJdIHx8IGRhdGE7XG4vLyAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnVuaXF1ZURhdGFTZXRPYmplY3RbZGF0YXNldElkXSA9IHBheWxvYWQ7XG4vLyAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4vLyAgICAgICAgICAgICAgICAgICAgIH0sXG4vLyAgICAgICAgICAgICAgICAgICAgIGVycm9yOiAoZXJyOiBhbnkpID0+IHtcbi8vICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yOicsIGVycik7XG4vLyAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRvYXN0ci5lcnJvcihlcnIubWVzc2FnZSlcblxuLy8gICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4vLyAgICAgICAgICAgICAgICAgICAgIH1cbi8vICAgICAgICAgICAgICAgICB9KTtcbi8vICAgICAgICAgICAgIH0gZWxzZSBpZiAoZGF0YXNldC5jb25maWcuYXBpVHlwZSA9PT0gXCJnZXRcIikge1xuXG4vLyAgICAgICAgICAgICAgICAgbGV0IHJlcXVlc3RVcmwgPSBkYXRhc2V0LmNvbmZpZy5hcGkgKyBcIj9cIjtcbi8vICAgICAgICAgICAgICAgICBkYXRhc2V0LmNvbmZpZy5xdWVyeUNvbmZpZy5tYXBlZEZpbHRlcnMuZm9yRWFjaCgoZmlsdGVyOiBhbnksIGluZGV4OiBudW1iZXIpID0+IHtcbi8vICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdFVybCArPSBgJHtmaWx0ZXIuc2VydmVyQ29sdW1ufT0ke2ZpbHRlci5kZWZhdWx0VmFsdWV9YDtcbi8vICAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4IDwgZGF0YXNldC5jb25maWcucXVlcnlDb25maWcubWFwZWRGaWx0ZXJzLmxlbmd0aCAtIDEpIHtcbi8vICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RVcmwgKz0gXCImXCI7XG4vLyAgICAgICAgICAgICAgICAgICAgIH1cbi8vICAgICAgICAgICAgICAgICB9KTtcblxuLy8gICAgICAgICAgICAgICAgIHRoaXMuc2VydmljZS5nZXRTaW1wbGVBcGlHZXRSZXF1ZXN0KHJlcXVlc3RVcmwpLnN1YnNjcmliZSh7XG4vLyAgICAgICAgICAgICAgICAgICAgIG5leHQ6IChkYXRhOiBhbnkpID0+IHtcbi8vICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBheWxvYWQgPSBkYXRhW1wiUGF5bG9hZFwiXSB8fCBkYXRhO1xuLy8gICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51bmlxdWVEYXRhU2V0T2JqZWN0W2RhdGFzZXRJZF0gPSBwYXlsb2FkO1xuLy8gICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuLy8gICAgICAgICAgICAgICAgICAgICB9LFxuLy8gICAgICAgICAgICAgICAgICAgICBlcnJvcjogKGVycjogYW55KSA9PiB7XG4vLyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvcjonLCBlcnIpO1xuLy8gICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50b2FzdHIuZXJyb3IoZXJyLm1lc3NhZ2UpXG5cbi8vICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuLy8gICAgICAgICAgICAgICAgICAgICB9XG4vLyAgICAgICAgICAgICAgICAgfSk7XG4vLyAgICAgICAgICAgICB9XG4vLyAgICAgICAgIH0pO1xuLy8gICAgIH1cblxuXG4vLyAgICAgZ2V0RGF0YXNldEZvclBsYWluSnNvbihkYXRhc2V0LCBkYXRhc2V0SWQsIGZpbHRlcikge1xuLy8gICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4vLyAgICAgICAgICAgICBsZXQgcmVxdWVzdGFwaSA9IGRhdGFzZXQuY29uZmlnLmFwaSArICc/ZGF0YXNldElkPScgKyBkYXRhc2V0LmRhdGFzZXRJZDtcbi8vICAgICAgICAgICAgIHRoaXMuc2VydmljZS5nZXRKc29uRGF0YXNldFBheWxvYWQocmVxdWVzdGFwaSkuc3Vic2NyaWJlKHtcbi8vICAgICAgICAgICAgICAgICBuZXh0OiAoZGF0YTogYW55KSA9PiB7XG4vLyAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBheWxvYWQgPSBkYXRhW1wiUGF5bG9hZFwiXSB8fCBkYXRhO1xuLy8gICAgICAgICAgICAgICAgICAgICB0aGlzLnVuaXF1ZURhdGFTZXRPYmplY3RbZGF0YXNldElkXSA9IHBheWxvYWQ7XG4vLyAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcblxuLy8gICAgICAgICAgICAgICAgIH0sXG4vLyAgICAgICAgICAgICAgICAgZXJyb3I6IChlcnI6IGFueSkgPT4ge1xuLy8gICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvcjonLCBlcnIpO1xuLy8gICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyKTtcbi8vICAgICAgICAgICAgICAgICB9XG4vLyAgICAgICAgICAgICB9KTtcbi8vICAgICAgICAgfSk7XG4vLyAgICAgfVxuXG5cbi8vICAgICBnZXREYXRhc2V0Rm9yU3FsVGVtcGxhdGUoZGF0YXNldCwgZGF0YXNldElkLCBmaWx0ZXJzKSB7XG5cbi8vICAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcblxuXG4vLyAgICAgICAgICAgICBjb25zdCBvcGVyYXRvciA9IChmaWx0ZXJzICYmIGZpbHRlcnMubGVuZ3RoICE9PSAwKSA/IE9iamVjdC5rZXlzKGZpbHRlcnMub3BlcmF0aW9uRmlsdGVyKS5tYXAoa2V5ID0+ICh7IFtrZXldOiBmaWx0ZXJzLm9wZXJhdGlvbkZpbHRlcltrZXldIH0pKSA6IFtdO1xuXG4vLyAgICAgICAgICAgICBsZXQgcmVxdWVzdEFwID0gZGF0YXNldC5jb25maWcuYXBpO1xuLy8gICAgICAgICAgICAgbGV0IHJlcXVlc3RfcGFyYW1zID0ge1xuLy8gICAgICAgICAgICAgICAgICdkYkNvbmZpZyc6IGRhdGFzZXQuY29uZmlnLnF1ZXJ5Q29uZmlnLmRiQ29uZmlnLFxuLy8gICAgICAgICAgICAgICAgICdkYXRhYmFzZU5hbWUnOiBkYXRhc2V0LmNvbmZpZy5xdWVyeUNvbmZpZy5kYXRhYmFzZU5hbWUsXG4vLyAgICAgICAgICAgICAgICAgJ2ZpbHRlcnMnOiB0aGlzLnRyYW5zZm9ybURhdGFGb3JNRmlsdGVyRm9yU1FsKG9wZXJhdG9yLCBkYXRhc2V0LmNvbmZpZy5xdWVyeUNvbmZpZy5tYXBlZEZpbHRlcnMpLFxuLy8gICAgICAgICAgICAgICAgICd0ZW1wbGF0ZVF1ZXJ5JzogZGF0YXNldC5jb25maWcucXVlcnlDb25maWcudGVtcGxhdGVRdWVyeSxcbi8vICAgICAgICAgICAgICAgICAnZW5yaWNobWVudHMnOiBkYXRhc2V0LmNvbmZpZy5xdWVyeUNvbmZpZy5lbnJpY2htZW50cyxcbi8vICAgICAgICAgICAgIH1cbi8vICAgICAgICAgICAgIHRoaXMuc2VydmljZS5nZW5lcmljU3FsUXVlcnlSZXNwb25zZShyZXF1ZXN0QXAsIHJlcXVlc3RfcGFyYW1zKS5zdWJzY3JpYmUoe1xuLy8gICAgICAgICAgICAgICAgIG5leHQ6IChkYXRhOiBhbnkpID0+IHtcbi8vICAgICAgICAgICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IGRhdGFbXCJQYXlsb2FkXCJdIHx8IGRhdGE7XG4vLyAgICAgICAgICAgICAgICAgICAgIHRoaXMudW5pcXVlRGF0YVNldE9iamVjdFtkYXRhc2V0SWRdID0gcGF5bG9hZDtcbi8vICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuLy8gICAgICAgICAgICAgICAgIH0sXG4vLyAgICAgICAgICAgICAgICAgZXJyb3I6IChlcnI6IGFueSkgPT4ge1xuLy8gICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvcjonLCBlcnIpO1xuLy8gICAgICAgICAgICAgICAgICAgICB0aGlzLnRvYXN0ci5lcnJvcihlcnIubWVzc2FnZSlcblxuLy8gICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyKTtcbi8vICAgICAgICAgICAgICAgICB9XG4vLyAgICAgICAgICAgICB9KTtcblxuLy8gICAgICAgICB9KTtcbi8vICAgICB9XG5cbi8vICAgICB0cmFuc2Zvcm1EYXRhRm9yTUZpbHRlckZvclNRbChmaWx0ZXJkYXRhLCBtYXBEYXRhKSB7XG5cbi8vICAgICAgICAgbGV0IHJlc3VsdCA9IFtdO1xuLy8gICAgICAgICBtYXBEYXRhLmZvckVhY2gobWFwcGluZyA9PiB7XG4vLyAgICAgICAgICAgICBsZXQgcmVzdWx0T2JqID0ge1xuLy8gICAgICAgICAgICAgICAgIGNvbHVtbk5hbWU6IG1hcHBpbmcuc2VydmVyQ29sdW1uLFxuLy8gICAgICAgICAgICAgICAgIGRhdGFUeXBlOiBtYXBwaW5nLmRhdGFUeXBlLFxuLy8gICAgICAgICAgICAgICAgIG9wZXJhdG9yOiBtYXBwaW5nLm9wZXJhdG9yTmFtZSxcbi8vICAgICAgICAgICAgICAgICB2YWx1ZTogbWFwcGluZy5kZWZhdWx0VmFsdWUsXG4vLyAgICAgICAgICAgICAgICAgYWxpYXNDb2x1bW5OYW1lOiBtYXBwaW5nLmxvY2FsQ29sdW1uLFxuLy8gICAgICAgICAgICAgfTtcbi8vICAgICAgICAgICAgIGlmIChtYXBwaW5nLnNlcnZlckNvbHVtbi5pbmNsdWRlcygnZGF0ZScpICYmIHR5cGVvZiByZXN1bHRPYmoudmFsdWUgPT09ICdzdHJpbmcnKSB7XG4vLyAgICAgICAgICAgICAgICAgaWYgKG1hcHBpbmcuZm9ybWF0dGVyICYmIG1hcHBpbmcuZm9ybWF0dGVyICE9PSBcIlwiKSB7XG4vLyAgICAgICAgICAgICAgICAgICAgIHJlc3VsdE9iai52YWx1ZSA9IG1vbWVudChyZXN1bHRPYmoudmFsdWUsIFwiWVlZWS1NTS1ERFwiKS5mb3JtYXQobWFwcGluZy5mb3JtYXR0ZXIpO1xuLy8gICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4vLyAgICAgICAgICAgICAgICAgICAgIHJlc3VsdE9iai52YWx1ZSA9IG1vbWVudChyZXN1bHRPYmoudmFsdWUsIFwiWVlZWS1NTS1ERFwiKS5mb3JtYXQodGhpcy5lbnZpcm9ubWVudC5kYXRhRm9ybWF0KTtcblxuLy8gICAgICAgICAgICAgICAgIH1cbi8vICAgICAgICAgICAgIH1cbi8vICAgICAgICAgICAgIGNvbnN0IGZpbHRlciA9IGZpbHRlcmRhdGEuZmluZChmID0+IGYuaGFzT3duUHJvcGVydHkobWFwcGluZy5sb2NhbENvbHVtbikpO1xuLy8gICAgICAgICAgICAgaWYgKGZpbHRlcikge1xuLy8gICAgICAgICAgICAgICAgIGlmIChtYXBwaW5nLmRlZmF1bHRWYWx1ZSA9PT0gXCJcIikge1xuLy8gICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGZpbHRlclttYXBwaW5nLmxvY2FsQ29sdW1uXTtcblxuLy8gICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbi8vICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdE9iai5vcGVyYXRvciA9IFwiaW5cIjtcbi8vICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdE9iai52YWx1ZSA9IHZhbHVlLmpvaW4oXCIsXCIpO1xuLy8gICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuLy8gICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0T2JqLnZhbHVlID0gdmFsdWU7XG4vLyAgICAgICAgICAgICAgICAgICAgIH1cbi8vICAgICAgICAgICAgICAgICAgICAgaWYgKG1hcHBpbmcuc2VydmVyQ29sdW1uLmluY2x1ZGVzKCdkYXRlJykgJiYgdHlwZW9mIHJlc3VsdE9iai52YWx1ZSA9PT0gJ3N0cmluZycpIHtcbi8vICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdE9iai52YWx1ZSA9IG1vbWVudChyZXN1bHRPYmoudmFsdWUsIFwiWVlZWS1NTS1ERFwiKS5mb3JtYXQodGhpcy5lbnZpcm9ubWVudC5kYXRhRm9ybWF0KTtcbi8vICAgICAgICAgICAgICAgICAgICAgfVxuLy8gICAgICAgICAgICAgICAgIH1cbi8vICAgICAgICAgICAgIH0gZWxzZSBpZiAobWFwcGluZy5kZWZhdWx0VmFsdWUgPT09IFwiXCIpIHtcbi8vICAgICAgICAgICAgICAgICByZXR1cm47XG4vLyAgICAgICAgICAgICB9XG4vLyAgICAgICAgICAgICByZXN1bHQucHVzaChyZXN1bHRPYmopO1xuLy8gICAgICAgICB9KTtcbi8vICAgICAgICAgZmlsdGVyZGF0YSA9IGZpbHRlcmRhdGEuZmlsdGVyKG9iaiA9PiB7XG4vLyAgICAgICAgICAgICBjb25zdCBrZXkgPSBPYmplY3Qua2V5cyhvYmopWzBdO1xuLy8gICAgICAgICAgICAgcmV0dXJuIGtleSAhPT0gJ3N0YXJ0RGF0ZScgJiYga2V5ICE9PSAnZW5kRGF0ZSc7XG4vLyAgICAgICAgIH0pOyBmaWx0ZXJkYXRhLmZvckVhY2goZmlsdGVyID0+IHtcbi8vICAgICAgICAgICAgIGNvbnN0IGZpbHRlcktleSA9IE9iamVjdC5rZXlzKGZpbHRlcilbMF07XG4vLyAgICAgICAgICAgICBjb25zdCBleGlzdGluZ01hcHBpbmcgPSBtYXBEYXRhLmZpbmQobWFwcGluZyA9PiBtYXBwaW5nLmxvY2FsQ29sdW1uID09PSBmaWx0ZXJLZXkpO1xuXG4vLyAgICAgICAgICAgICBpZiAoIWV4aXN0aW5nTWFwcGluZykge1xuLy8gICAgICAgICAgICAgICAgIGxldCByZXN1bHRPYmogPSB7XG4vLyAgICAgICAgICAgICAgICAgICAgIGNvbHVtbk5hbWU6IGZpbHRlcktleSxcbi8vICAgICAgICAgICAgICAgICAgICAgZGF0YVR5cGU6IFwic3RyaW5nXCIsXG4vLyAgICAgICAgICAgICAgICAgICAgIG9wZXJhdG9yOiBcImVxXCIsXG4vLyAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiBmaWx0ZXJbZmlsdGVyS2V5XVxuLy8gICAgICAgICAgICAgICAgIH07XG5cbi8vICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShmaWx0ZXJbZmlsdGVyS2V5XSkpIHtcbi8vICAgICAgICAgICAgICAgICAgICAgcmVzdWx0T2JqLm9wZXJhdG9yID0gXCJpblwiO1xuLy8gICAgICAgICAgICAgICAgICAgICByZXN1bHRPYmoudmFsdWUgPSBmaWx0ZXJbZmlsdGVyS2V5XS5qb2luKFwiLFwiKTtcbi8vICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuLy8gICAgICAgICAgICAgICAgICAgICByZXN1bHRPYmoudmFsdWUgPSBmaWx0ZXJbZmlsdGVyS2V5XTtcbi8vICAgICAgICAgICAgICAgICB9XG5cbi8vICAgICAgICAgICAgICAgICAvLyBmb3IgbWNpdCBvbmx5XG4vLyAgICAgICAgICAgICAgICAgaWYgKGZpbHRlcktleSA9PSAnb3BlcmF0b3Jfa2V5Jykge1xuLy8gICAgICAgICAgICAgICAgICAgICByZXN1bHRPYmoub3BlcmF0b3IgPSBcImVxXCI7XG4vLyAgICAgICAgICAgICAgICAgfVxuLy8gICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHJlc3VsdE9iaik7XG4vLyAgICAgICAgICAgICB9XG4vLyAgICAgICAgIH0pO1xuXG5cbi8vICAgICAgICAgLy8gcmVzdWx0ID0gcmVzdWx0LmZpbHRlcihvYmogPT4gb2JqLnZhbHVlICE9PSBudWxsICYmIG9iai52YWx1ZSAhPT0gXCJcIik7XG4vLyAgICAgICAgIHJldHVybiByZXN1bHQ7XG4vLyAgICAgfVxuXG5cbi8vICAgICBnZXRVbmlxdWVEYXRhU2V0T2JqZWN0KCkge1xuLy8gICAgICAgICByZXR1cm4gdGhpcy51bmlxdWVEYXRhU2V0T2JqZWN0O1xuLy8gICAgIH1cblxuXG4vLyB9XG5cblxuXG5pbXBvcnQgeyBJbmplY3RhYmxlLCBJbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFRvYXN0clNlcnZpY2UgfSBmcm9tICduZ3gtdG9hc3RyJztcbmltcG9ydCB7IGtwaWNvbW1vblNlcnZpY2UgfSBmcm9tICcuLi8uLi9hcHBsaWNhdGlvbi1jb250cm9sbGVyL2twaS1zZXJ2aWNlJztcbmltcG9ydCB7IEFQUF9FTlZJUk9OTUVOVCB9IGZyb20gJy4uLy4uL2FwcGxpY2F0aW9uLWNvbnRyb2xsZXIvZW52aXJvbm1lbnQnO1xuaW1wb3J0IHsgVGVtcGxhdGVEYXRhc2V0Q2FsbFNlcnZpY2UgfSBmcm9tICcuLi8uLi9zaGFyZWQvdGVtcGxhdGUtZGF0YXNldC1jYWxsLXNlcnZpY2UnO1xuaW1wb3J0IHsgTGFuZGluZ011bHRpTGF5b3V0Q29tcG9uZW50U2VydmljZSB9IGZyb20gJy4vZGVmYXVsTGFuZGluZ011bHRpTGF5b3V0LnNlcnZpY2UnO1xuQEluamVjdGFibGUoeyBwcm92aWRlZEluOiBcInJvb3RcIiB9KVxuZXhwb3J0IGNsYXNzIExhbmRpbmdNdWx0aUxheW91dEFwcGxpY2F0aW9uRGF0c3NldHNDYWxsIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBiYWNrZW5kOiBMYW5kaW5nTXVsdGlMYXlvdXRDb21wb25lbnRTZXJ2aWNlLFxuICAgIHByaXZhdGUgY29tbW9uOiBUZW1wbGF0ZURhdGFzZXRDYWxsU2VydmljZSxcbiAgICBwcml2YXRlIGtwaVNlcnZpY2U6IGtwaWNvbW1vblNlcnZpY2UsXG4gICAgcHJpdmF0ZSB0b2FzdHI6IFRvYXN0clNlcnZpY2UsXG4gICAgQEluamVjdChBUFBfRU5WSVJPTk1FTlQpIHByaXZhdGUgZW52aXJvbm1lbnQ6IGFueVxuICApIHt9XG5cbiAgZ2V0RGF0YUZyb21EYXRhU2V0KGRhdGFzZXQsIGRhdGFzZXRJZCwgZmlsdGVycykge1xuICAgIHJldHVybiB0aGlzLmNvbW1vbi5nZXREYXRhRnJvbURhdGFTZXQodGhpcy5iYWNrZW5kLCBkYXRhc2V0LCBkYXRhc2V0SWQsIGZpbHRlcnMpO1xuICB9XG5cbiAgZ2V0VW5pcXVlRGF0YVNldE9iamVjdCgpIHtcbiAgICByZXR1cm4gdGhpcy5jb21tb24uZ2V0VW5pcXVlRGF0YVNldE9iamVjdCgpO1xuICB9XG59Il19