@angular-generic-table/core 5.0.0-rc.17 → 5.0.0-rc.18

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.
@@ -1,24 +1,61 @@
1
1
  import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, } from '@angular/core';
2
- import { BehaviorSubject, combineLatest, isObservable, of, ReplaySubject, } from 'rxjs';
2
+ import { BehaviorSubject, combineLatest, fromEvent, isObservable, of, ReplaySubject, Subject, } from 'rxjs';
3
3
  import { AsyncPipe, KeyValuePipe, NgClass, NgForOf, NgIf, NgTemplateOutlet, SlicePipe, } from '@angular/common';
4
- import { debounceTime, distinctUntilChanged, filter, map, shareReplay, startWith, switchMap, take, tap, withLatestFrom, } from 'rxjs/operators';
4
+ import { distinctUntilChanged, filter, map, pluck, shareReplay, startWith, switchMap, take, takeUntil, tap, withLatestFrom, } from 'rxjs/operators';
5
5
  import { calculate, chunk, search, sortOnMultipleKeys, } from './utilities/utilities';
6
6
  import { CapitalCasePipe } from './pipes/capital-case.pipe';
7
7
  import { SortClassPipe } from './pipes/sort-class.pipe';
8
8
  import { DashCasePipe } from './pipes/dash-case.pipe';
9
9
  import { DynamicPipe } from './pipes/dynamic.pipe';
10
10
  import { HighlightPipe } from './pipes/highlight.pipe';
11
+ import { RowSelectionPipe } from './pipes/row-selection.pipe';
11
12
  import * as i0 from "@angular/core";
12
13
  export class CoreComponent {
13
14
  constructor() {
15
+ this.unsubscribe$ = new Subject();
16
+ this._navigationKeys = [
17
+ 'ArrowDown',
18
+ 'ArrowUp',
19
+ 'ArrowLeft',
20
+ 'ArrowRight',
21
+ 'Home',
22
+ 'End',
23
+ ];
24
+ this._selectKeys = ['Enter', ' '];
25
+ this._customClasses = {
26
+ selectedRow: 'gt-selected',
27
+ activeRow: 'gt-active',
28
+ };
29
+ /** selection
30
+ * @description An object that contains the currently selected row(s) in the table. It's passed to the selection function to determine which rows should be selected.
31
+ * @type {any}
32
+ */
33
+ this.selection = {};
34
+ /** generateRowId
35
+ * @description Whether or not to generate a unique id for each row in the table. Defaults to `true`.
36
+ * @type {boolean}
37
+ */
38
+ this.generateRowId = true;
14
39
  this.rowClick = new EventEmitter();
40
+ this.rowSelect = new EventEmitter();
15
41
  this.sortOrderChange = new EventEmitter();
16
- this._rowHover$ = new ReplaySubject(1);
17
- this.rowHover = new EventEmitter();
42
+ this._rowActive$ = new ReplaySubject(1);
43
+ this.rowActive = new EventEmitter();
18
44
  this.columnSort = new EventEmitter();
19
45
  /** page change event - emitted when current page/index changes for pagination */
20
46
  this.pageChange = new EventEmitter();
21
- this.rowHover$ = this._rowHover$.asObservable().pipe(debounceTime(50), distinctUntilChanged((p, q) => p.index === q.index), tap((event) => this.rowHover.emit(event)), shareReplay(1));
47
+ this.rowActive$ = this._rowActive$.asObservable().pipe(distinctUntilChanged((p, q) => {
48
+ if (this.rowIdKey && p.row && q.row) {
49
+ return p.row[this.rowIdKey] === q.row[this.rowIdKey];
50
+ }
51
+ else if (this.generateRowId && p.row && q.row) {
52
+ return p.row._id === q.row._id;
53
+ }
54
+ else {
55
+ return p.index === q.index;
56
+ }
57
+ }), tap((event) => (this.activeRowIndex = event.index)), tap((event) => this.rowActive.emit(event)), shareReplay(1));
58
+ this.activeRowIndex = null;
22
59
  this._loading$ = new ReplaySubject(1);
23
60
  this._sortOrder$ = new BehaviorSubject([]);
24
61
  this._searchBy$ = new ReplaySubject(1);
@@ -35,7 +72,7 @@ export class CoreComponent {
35
72
  });
36
73
  // tslint:disable-next-line:variable-name
37
74
  this._tableConfig$ = new BehaviorSubject({});
38
- this.tableConfig$ = this._tableConfig$.pipe(map((value) => (isObservable(value) ? value : of(value))), switchMap((obs) => obs), shareReplay(1));
75
+ this.tableConfig$ = this._tableConfig$.pipe(map((value) => (isObservable(value) ? value : of(value))), switchMap((obs) => obs), tap((config) => (this._tableConfig = config)), shareReplay(1));
39
76
  this._data$ = new ReplaySubject(1);
40
77
  this.data$ = this._data$.pipe(map((value) => (isObservable(value) ? value : of(value))), switchMap((obs) => combineLatest([obs])), withLatestFrom(this.tableConfig$), map(([[data], config]) => {
41
78
  // if columns or rows contains config for mapTo...
@@ -57,6 +94,13 @@ export class CoreComponent {
57
94
  }
58
95
  data = newData;
59
96
  }
97
+ if (this.generateRowId && !this.rowIdKey && data.length > 0) {
98
+ const dataWithId = [];
99
+ for (let i = 0; i < data.length; i++) {
100
+ dataWithId[i] = { ...data[i], _id: i };
101
+ }
102
+ data = dataWithId;
103
+ }
60
104
  return { data, config };
61
105
  }), switchMap((obs) => combineLatest([of(obs), this.sortOrder$, this.searchBy$])), map(([table, sortBy, searchBy]) => {
62
106
  // create a new array reference and sort new array (prevent mutating existing state)
@@ -105,6 +149,7 @@ export class CoreComponent {
105
149
  config,
106
150
  info: {
107
151
  numberOfRecords: sorted.length,
152
+ pageSize: +(config.pagination.length || 0),
108
153
  pageTotal: Math.ceil(sorted.length / +(config.pagination.length || 0)),
109
154
  },
110
155
  };
@@ -138,6 +183,30 @@ export class CoreComponent {
138
183
  this.columnOrder = (a, b) => {
139
184
  return (a.value.order || 0) - (b.value.order || 0);
140
185
  };
186
+ this._unsubscribeFromKeyboardEvents$ = new Subject();
187
+ this._keyboardArrowEvent$ = fromEvent(document, 'keydown').pipe(filter((event) => [...this._navigationKeys, ...this._selectKeys].indexOf(event.key) > -1));
188
+ }
189
+ get navigationKeys() {
190
+ return this._navigationKeys;
191
+ }
192
+ /** navigationKeys
193
+ * @description An array of keyboard keys that will trigger navigation and active row, currently only supports arrow keys, home and end (omit key name from array to disable it)
194
+ * @type {string[]}
195
+ * @default ['ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight', 'Home', 'End']
196
+ */
197
+ set navigationKeys(value) {
198
+ this._navigationKeys = value;
199
+ }
200
+ get selectKeys() {
201
+ return this._selectKeys;
202
+ }
203
+ /** selectKeys
204
+ * @description An array of keyboard keys that will trigger row selection (omit key name from array to disable it)
205
+ * @type {string[]}
206
+ * @default ['Enter', ' ']
207
+ */
208
+ set selectKeys(value) {
209
+ this._selectKeys = value;
141
210
  }
142
211
  get sortOrder$() {
143
212
  return this._sortOrder$.asObservable();
@@ -148,6 +217,9 @@ export class CoreComponent {
148
217
  set paginationIndex(pageIndex) {
149
218
  this._currentPaginationIndex$.next(pageIndex);
150
219
  }
220
+ get paginationIndex() {
221
+ return this._currentPaginationIndex$.getValue();
222
+ }
151
223
  set pagingInfo(value) {
152
224
  if (value) {
153
225
  this._pagingInfo$.next(value);
@@ -157,6 +229,38 @@ export class CoreComponent {
157
229
  }
158
230
  }
159
231
  }
232
+ /** customClasses
233
+ * @description An object that contains custom classes for various elements in the table.
234
+ * @type {object} - { selectedRow: string, activeRow: string } - default classes are 'gt-selected' and 'gt-active'
235
+ */
236
+ set customClasses(classes) {
237
+ this._customClasses = { ...this._customClasses, ...classes };
238
+ }
239
+ get customClasses() {
240
+ return this._customClasses;
241
+ }
242
+ /** isRowSelectedFn
243
+ * @description Function to determine if row is selected or not.
244
+ * @type {fn} A function that receives a row object and optional state for current selection that can be used to determine if row should be marked as selected or not. */
245
+ set isRowSelectedFn(fn) {
246
+ this._isRowSelectedFn = fn;
247
+ }
248
+ get isRowSelectedFn() {
249
+ return this._isRowSelectedFn;
250
+ }
251
+ /** trackRowByFn
252
+ * @description A function that returns a unique identifier for each row in the table to optimize rendering when data is added or removed.
253
+ * @type fn - TrackByFunction to retrieve unique id based on index and/or row. Defaults to using `row[this.rowIdKey]`.
254
+ */
255
+ set trackRowByFn(fn) {
256
+ this._trackRowByFn = fn;
257
+ }
258
+ get trackRowByFn() {
259
+ return this._trackRowByFn;
260
+ }
261
+ _trackRowByFn(index, row) {
262
+ return this.rowIdKey ? row[this.rowIdKey] : row?._id;
263
+ }
160
264
  set search(string) {
161
265
  this._searchBy$.next(string);
162
266
  }
@@ -164,7 +268,9 @@ export class CoreComponent {
164
268
  this._tableConfig$.next(config);
165
269
  }
166
270
  set data(data) {
167
- this._data$.next(data);
271
+ if (data) {
272
+ this._data$.next(data);
273
+ }
168
274
  }
169
275
  set sortOrder(sortConfig) {
170
276
  if (JSON.stringify(sortConfig) !== JSON.stringify(this._sortOrder$.value)) {
@@ -175,21 +281,24 @@ export class CoreComponent {
175
281
  _rowClick(row, index, event) {
176
282
  this.rowClick.emit({ row, index, event });
177
283
  }
178
- hoverRow(arg) {
284
+ _rowActive(row, index, event) {
285
+ this.rowSelect.emit({ row, index, event });
286
+ }
287
+ activateRow(arg, event) {
179
288
  if (typeof arg === 'number') {
180
- this.data$
181
- .pipe(map((data) => data[arg]), take(1))
182
- .subscribe((row) => this._hoverRow(row, arg));
289
+ this.table$
290
+ .pipe(pluck('data'), map((data) => data[this.paginationIndex][arg]), take(1), takeUntil(this.unsubscribe$))
291
+ .subscribe((row) => this._activateRow(row, arg, event));
183
292
  }
184
293
  else if (typeof arg === 'string') {
185
294
  // TODO: implement hover by id
186
295
  }
187
296
  else {
188
- this._hoverRow(null, null);
297
+ this._activateRow(null, null);
189
298
  }
190
299
  }
191
- _hoverRow(row, index, event) {
192
- this._rowHover$.next({ row, index, event });
300
+ _activateRow(row, index, event) {
301
+ this._rowActive$.next({ row, index, event });
193
302
  }
194
303
  get loading$() {
195
304
  return this._loading$.pipe(startWith(false), map((value) => (isObservable(value) ? value : of(value))), switchMap((obs) => obs), shareReplay(1));
@@ -277,9 +386,117 @@ export class CoreComponent {
277
386
  return levels.reduce((previousValue, currentValue, index) => previousValue[currentValue] ||
278
387
  (index === levels.length - 1 ? missingValue : {}), object);
279
388
  }
389
+ listenToKeyboardEvents() {
390
+ if (!this._tableConfig?.activateRowOnKeyboardNavigation) {
391
+ return;
392
+ }
393
+ this._unsubscribeFromKeyboardEvents$.next(true);
394
+ this._keyboardArrowEvent$
395
+ .pipe(withLatestFrom(this.data$, this.currentPaginationIndex$, this.tableInfo$), takeUntil(this._unsubscribeFromKeyboardEvents$), takeUntil(this.unsubscribe$))
396
+ .subscribe(([event, rows, currentPage, tableInfo]) => {
397
+ const selectEvent = this._selectKeys.includes(event.key);
398
+ if (selectEvent && this.activeRowIndex !== null) {
399
+ const rowIndex = this.activeRowIndex + currentPage * (tableInfo?.pageSize ?? 0);
400
+ this._rowActive(rows[rowIndex], rowIndex, event);
401
+ return;
402
+ }
403
+ const navigationEvent = this._navigationKeys.includes(event.key);
404
+ if (navigationEvent) {
405
+ this._handleNavigationEvent(event, rows, currentPage, tableInfo);
406
+ }
407
+ });
408
+ }
409
+ unsubscribeFromKeyboardEvents(tableRef) {
410
+ if (!this._tableConfig?.activateRowOnKeyboardNavigation) {
411
+ return;
412
+ }
413
+ // only unsubscribe if table is not focused
414
+ if (tableRef !== document.activeElement) {
415
+ if (this._tableConfig?.activateRowOnHover) {
416
+ // unset active row
417
+ this.activateRow(null);
418
+ }
419
+ this._unsubscribeFromKeyboardEvents$.next(true);
420
+ }
421
+ }
422
+ _handleNavigationEvent(event, rows, currentPage, tableInfo) {
423
+ const hasPagination = (tableInfo?.pageTotal || 0) > 1 && tableInfo;
424
+ const lastRowIndex = rows.length - 1;
425
+ let newIndex = this.activeRowIndex;
426
+ let indexModifier = 0;
427
+ if (event.key === 'Home') {
428
+ this.paginationIndex = 0;
429
+ this.activateRow(0, event);
430
+ return;
431
+ }
432
+ if (event.key === 'End') {
433
+ const indexOfLastRecord = hasPagination
434
+ ? rows.length - (tableInfo.pageTotal - 1) * tableInfo.pageSize - 1
435
+ : lastRowIndex;
436
+ if (tableInfo?.pageTotal) {
437
+ this.paginationIndex = tableInfo.pageTotal - 1;
438
+ }
439
+ this.activateRow(indexOfLastRecord, event);
440
+ return;
441
+ }
442
+ if (event.key === 'ArrowDown') {
443
+ indexModifier = 1;
444
+ }
445
+ else if (event.key === 'ArrowUp') {
446
+ indexModifier = -1;
447
+ }
448
+ if (newIndex === null) {
449
+ newIndex = 0;
450
+ }
451
+ else if (newIndex + indexModifier >= 0 &&
452
+ newIndex + indexModifier <= lastRowIndex) {
453
+ newIndex = newIndex + indexModifier;
454
+ }
455
+ if (hasPagination && tableInfo?.pageSize) {
456
+ const isNotLastPage = currentPage + 1 < tableInfo.pageTotal;
457
+ const recordsOnLastPage = rows.length - (tableInfo.pageTotal - 1) * tableInfo.pageSize - 1;
458
+ const maxIndex = isNotLastPage
459
+ ? tableInfo?.pageSize - 1
460
+ : recordsOnLastPage;
461
+ if (event.key === 'ArrowLeft' && currentPage > 0) {
462
+ this.paginationIndex = currentPage - 1;
463
+ this.activateRow(newIndex, event);
464
+ return;
465
+ }
466
+ else if (event.key === 'ArrowRight' && isNotLastPage) {
467
+ if (currentPage + 1 === tableInfo.pageTotal - 1 &&
468
+ newIndex > recordsOnLastPage) {
469
+ this.activateRow(recordsOnLastPage, event);
470
+ }
471
+ this.paginationIndex = currentPage + 1;
472
+ this.activateRow(newIndex, event);
473
+ return;
474
+ }
475
+ if (currentPage > 0 &&
476
+ indexModifier < 0 &&
477
+ newIndex + indexModifier <= lastRowIndex &&
478
+ (this.activeRowIndex || 0) + indexModifier < 0) {
479
+ // set last row of previous page as active
480
+ this.activateRow(tableInfo?.pageSize - 1, event);
481
+ this.paginationIndex = currentPage - 1;
482
+ return;
483
+ }
484
+ const pageIndex = newIndex % tableInfo?.pageSize;
485
+ if (newIndex > maxIndex && currentPage + 1 < tableInfo.pageTotal) {
486
+ this.paginationIndex = currentPage + 1;
487
+ }
488
+ this.activateRow(pageIndex > maxIndex ? maxIndex : pageIndex, event);
489
+ return;
490
+ }
491
+ this.activateRow(newIndex, event);
492
+ }
493
+ ngOnDestroy() {
494
+ this.unsubscribe$.next(true);
495
+ this.unsubscribe$.complete();
496
+ }
280
497
  }
281
498
  CoreComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: CoreComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
282
- CoreComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.1", type: CoreComponent, isStandalone: true, selector: "angular-generic-table", inputs: { loading: "loading", paginationIndex: "paginationIndex", pagingInfo: "pagingInfo", search: "search", config: "config", data: "data", sortOrder: "sortOrder" }, outputs: { rowClick: "rowClick", sortOrderChange: "sortOrderChange", rowHover: "rowHover", columnSort: "columnSort", pageChange: "pageChange" }, ngImport: i0, template: "<table\n [ngClass]=\"(tableConfig$ | async)?.class || 'table'\"\n [class.table-mobile]=\"(tableConfig$ | async)?.mobileLayout\"\n [class.table-horizontal]=\"(tableConfig$ | async)?.rows\"\n [class.table-loading]=\"loading$ | async\"\n [class.gt-sticky-row-header]=\"\n (tableConfig$ | async)?.stickyHeaders?.row && (tableConfig$ | async)?.rows\n \"\n [class.gt-sticky-column-header]=\"\n (tableConfig$ | async)?.stickyHeaders?.column\n \"\n [attr.aria-busy]=\"(loading$ | async) === true ? true : null\"\n>\n <thead>\n <tr\n *ngIf=\"{\n config: (tableConfig$ | async)!,\n isLoading: loading$ | async\n } as table\"\n >\n <ng-container\n *ngFor=\"let column of table.config?.columns | keyvalue: columnOrder\"\n >\n <th\n *ngIf=\"!column.value?.hidden\"\n ngClass=\"{{ (column.key | dashCase) + '-column' }} {{\n column.value.class\n }}\"\n [class.disabled]=\"table.isLoading\"\n [attr.aria-sort]=\"sortOrder$ | async | sortClass: column.key:'aria'\"\n [class.gt-sortable]=\"true\"\n scope=\"col\"\n >\n <button\n *ngIf=\"column.value?.sortable\"\n [attr.data-sort-order]=\"\n sortOrder$ | async | sortClass: column.key:'order'\n \"\n class=\"gt-sort\"\n (click)=\"\n table.isLoading ||\n !column.value.sortable ||\n sortByKey(column.key, $event)\n \"\n >\n <span *ngIf=\"column.value?.header !== false\">{{\n column.value.header || column.key | capitalCase\n }}</span>\n </button>\n <span\n *ngIf=\"!column.value?.sortable && column.value?.header !== false\"\n >{{ column.value.header || column.key | capitalCase }}</span\n >\n </th>\n </ng-container>\n <ng-container\n *ngIf=\"\n ((table?.config?.rows | keyvalue: columnOrder) || [])[0] as headerRow\n \"\n >\n <th\n class=\"row-header\"\n [attr.aria-sort]=\"\n sortOrder$ | async | sortClass: headerRow.key:'aria'\n \"\n ngClass=\"{{ headerRow.value.sortable ? 'sort ' : '' }} {{\n sortOrder$ | async | sortClass: headerRow.key\n }} {{ (headerRow.key | dashCase) + '-column' }}\"\n (click)=\"\n table.isLoading ||\n !headerRow.value.sortable ||\n sortByKey(headerRow.key, $event)\n \"\n scope=\"col\"\n >\n <ng-container *ngIf=\"headerRow?.value?.header !== false\">{{\n headerRow?.value?.header || headerRow.key | capitalCase\n }}</ng-container>\n </th>\n <th\n *ngFor=\"let column of ((table$ | async)?.data || [])[0]\"\n ngClass=\"{{ headerRow.value.class }}\"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (table.config.rows || {})[headerRow.key].templateRef\n ? templateRef\n : (table.config.rows || {})[headerRow.key].transform\n ? transformData\n : rawData\n \"\n [ngTemplateOutletContext]=\"{\n row: column,\n column: headerRow,\n transform: (table.config.rows || {})[headerRow.key].transform,\n templateRef: (table.config.rows || {})[headerRow.key].templateRef,\n index: 0\n }\"\n >\n </ng-container>\n </th>\n </ng-container>\n </tr>\n </thead>\n <tbody *ngIf=\"loading$ | async; else tableContent\">\n <tr>\n <td class=\"p-0\" [colSpan]=\"colspan$ | async\">\n <ng-content select=\".table-loading\"></ng-content>\n </td>\n </tr>\n </tbody>\n <tfoot *ngIf=\"(table$ | async)! as table\">\n <ng-container *ngIf=\"table.data.length > 0 && !(loading$ | async)\">\n <ng-container *ngIf=\"(calculations$ | async)! as calculations\">\n <tr\n *ngFor=\"let calculation of calculations.calculations; let i = index\"\n >\n <ng-container\n *ngIf=\"{\n showHeader: (colspan$ | async) !== (footerColspan$ | async)\n } as footerRow\"\n >\n <th\n *ngIf=\"footerRow.showHeader\"\n [colSpan]=\"\n ((colspan$ | async) || 0) - ((footerColspan$ | async) || 0)\n \"\n scope=\"row\"\n >\n <ng-container\n *ngIf=\"table.config?.footer?.headers?.[calculation] as showHeader\"\n >{{showHeader === true ? (calculation | capitalCase): table.config.footer?.headers?.[calculation]}}\n </ng-container>\n </th>\n <ng-container\n *ngFor=\"\n let column of table.config?.columns | keyvalue: columnOrder\n \"\n >\n <td\n *ngIf=\"\n !column.value?.hidden && calculations.calculated[column.key]\n \"\n ngClass=\"{{ (column.key | dashCase) + '-column' }} {{\n column.value.class\n }}\"\n [attr.data-header]=\"\n !footerRow.showHeader && table.config.footer?.headers?.[calculation]\n ? table.config.footer?.headers?.[calculation] === true ? (calculation | capitalCase) : table.config.footer?.headers?.[calculation]\n : null\n \"\n [attr.data-label]=\"\n table.config.mobileLayout && column.value.mobileHeader\n ? column.value.mobileHeader !== true\n ? column.value.mobileHeader\n : (column.value.header || column.key | capitalCase)\n : null\n \"\n [class.gt-no-content]=\"\n !calculations.calculated[column.key][calculation]\n \"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (table.config.columns || {})[column.key].templateRef\n ? templateRef\n : (table.config.columns || {})[column.key].transform\n ? transformFooter\n : rawFooter\n \"\n [ngTemplateOutletContext]=\"{\n value: calculations.calculated[column.key][calculation],\n row: calculations.calculated[column.key],\n column: calculation,\n templateRef: (table.config.columns || {})[column.key]\n .templateRef,\n transform: (table.config.columns || {})[column.key]\n .transform\n }\"\n ></ng-container>\n </td>\n </ng-container>\n </ng-container>\n </tr>\n </ng-container>\n </ng-container>\n </tfoot>\n</table>\n<ng-template #tableContent>\n <ng-container *ngIf=\"(table$ | async)! as table\">\n <tbody *ngIf=\"(table!.data![0] || table!.data!).length > 0; else noData\">\n <ng-container *ngIf=\"table.config.columns\">\n <tr\n *ngFor=\"\n let row of table!.data![\n table.info.lazyLoaded ? 0 : (currentPaginationIndex$ | async) || 0\n ];\n let i = index\n \"\n [attr.id]=\"'tableRow_' + i\"\n (click)=\"table?.config?.rowClick && _rowClick(row, i, $event)\"\n (mouseover)=\"table?.config?.rowHover && _hoverRow(row, i, $event)\"\n (mouseout)=\"table?.config?.rowHover && _hoverRow(null, null, $event)\"\n [class.gt-hover]=\"(rowHover$ | async)?.index === i\"\n >\n <ng-container\n *ngFor=\"let column of table.config?.columns | keyvalue: columnOrder\"\n >\n <td\n *ngIf=\"!column.value?.hidden\"\n ngClass=\"{{ (column.key | dashCase) + '-column' }} {{\n column.value.class\n }}\"\n [attr.data-label]=\"\n table.config.mobileLayout && column.value.mobileHeader\n ? column.value.mobileHeader !== true\n ? column.value.mobileHeader\n : (column.value.header || column.key | capitalCase)\n : null\n \"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (searchBy$ | async) &&\n !(table.config.columns || {})[column.key].templateRef\n ? highlighted\n : (table.config.columns || {})[column.key].templateRef\n ? templateRef\n : (table.config.columns || {})[column.key].transform\n ? transformData\n : rawData\n \"\n [ngTemplateOutletContext]=\"{\n row: row,\n column: column,\n search: (searchBy$ | async),\n transform: (table.config.columns || {})[column.key].transform,\n templateRef: (table.config.columns || {})[column.key]\n .templateRef,\n index: i,\n data: table.data[\n table.info.lazyLoaded\n ? 0\n : (currentPaginationIndex$ | async) || 0\n ]\n }\"\n ></ng-container>\n </td>\n </ng-container>\n </tr>\n </ng-container>\n <ng-container *ngIf=\"table.config.rows\">\n <ng-container\n *ngFor=\"\n let row of table?.config?.rows | keyvalue: columnOrder | slice: 1;\n let i = index\n \"\n >\n <tr\n *ngIf=\"!row.value?.hidden\"\n [attr.id]=\"'tableRow_' + i\"\n ngClass=\"{{ (row.key | dashCase) + '-row' }}\"\n (click)=\"table?.config?.rowClick && _rowClick(row, i, $event)\"\n (mouseover)=\"table?.config?.rowHover && _hoverRow(row, i, $event)\"\n (mouseout)=\"\n table?.config?.rowHover && _hoverRow(null, null, $event)\n \"\n [class.gt-hover]=\"(rowHover$ | async)?.index === i\"\n >\n <th class=\"row-header\" scope=\"row\">\n {{ row.value.header || row.key | capitalCase }}\n </th>\n <td\n *ngFor=\"let column of (table?.data || [])[0]; let y = index\"\n ngClass=\"{{ row.value.class }}\"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (table.config.rows || {})[row.key].templateRef\n ? templateRef\n : (table.config.rows || {})[row.key].transform\n ? transformData\n : rawData\n \"\n [ngTemplateOutletContext]=\"{\n row: column,\n column: row,\n transform: (table.config.rows || {})[row.key].transform,\n templateRef: (table.config.rows || {})[row.key].templateRef,\n index: table.config.rows ? y : i,\n data: table.data[\n table.info.lazyLoaded\n ? 0\n : (currentPaginationIndex$ | async) || 0\n ]\n }\"\n >\n </ng-container>\n </td>\n </tr>\n </ng-container>\n </ng-container>\n </tbody>\n </ng-container>\n</ng-template>\n<ng-template #noData>\n <tbody>\n <tr>\n <td class=\"p-0\" [colSpan]=\"colspan$ | async\">\n <ng-content select=\".table-no-data\"></ng-content>\n </td>\n </tr>\n </tbody>\n</ng-template>\n<ng-template\n #highlighted\n let-row=\"row\"\n let-column=\"column\"\n let-search=\"search\"\n let-transform=\"transform\"\n>\n <div\n *ngIf=\"!transform\"\n [innerHTML]=\"row[column.key] | highlight: search\"\n ></div>\n <div\n *ngIf=\"transform\"\n [innerHTML]=\"\n row[column.key]\n | dynamicPipe: transform.pipe:transform?.args\n | highlight: search\n \"\n ></div>\n</ng-template>\n<ng-template #rawData let-row=\"row\" let-column=\"column\">\n {{ row[column.key] }}\n</ng-template>\n<ng-template\n #transformData\n let-row=\"row\"\n let-column=\"column\"\n let-transform=\"transform\"\n let-data=\"data\"\n>\n {{ row[column.key] | dynamicPipe: transform.pipe:transform?.args }}\n</ng-template>\n<ng-template #transformFooter let-value=\"value\" let-transform=\"transform\">\n {{\n (value | dynamicPipe: transform.pipe:transform?.args) ||\n (tableConfig$ | async)?.footer?.emptyContent\n }}\n</ng-template>\n<ng-template #rawFooter let-value=\"value\">\n {{ value || (tableConfig$ | async)?.footer?.emptyContent }}\n</ng-template>\n<ng-template\n #templateRef\n let-row=\"row\"\n let-column=\"column\"\n let-index=\"index\"\n let-templateRef=\"templateRef\"\n let-data=\"data\"\n>\n <ng-container\n [ngTemplateOutlet]=\"templateRef\"\n [ngTemplateOutletContext]=\"{\n row: row,\n col: column,\n index: index,\n data: data\n }\"\n ></ng-container>\n</ng-template>\n", dependencies: [{ kind: "pipe", type: CapitalCasePipe, name: "capitalCase" }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: SortClassPipe, name: "sortClass" }, { kind: "pipe", type: DashCasePipe, name: "dashCase" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: SlicePipe, name: "slice" }, { kind: "pipe", type: DynamicPipe, name: "dynamicPipe" }, { kind: "pipe", type: HighlightPipe, name: "highlight" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
499
+ CoreComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.1", type: CoreComponent, isStandalone: true, selector: "angular-generic-table", inputs: { navigationKeys: "navigationKeys", selectKeys: "selectKeys", loading: "loading", paginationIndex: "paginationIndex", pagingInfo: "pagingInfo", customClasses: "customClasses", isRowSelectedFn: "isRowSelectedFn", selection: "selection", rowIdKey: "rowIdKey", generateRowId: "generateRowId", trackRowByFn: "trackRowByFn", search: "search", config: "config", data: "data", sortOrder: "sortOrder" }, outputs: { rowClick: "rowClick", rowSelect: "rowSelect", sortOrderChange: "sortOrderChange", rowActive: "rowActive", columnSort: "columnSort", pageChange: "pageChange" }, ngImport: i0, template: "<table\n [ngClass]=\"(tableConfig$ | async)?.class || 'table'\"\n [class.table-mobile]=\"(tableConfig$ | async)?.mobileLayout\"\n [class.table-horizontal]=\"(tableConfig$ | async)?.rows\"\n [class.table-loading]=\"loading$ | async\"\n [class.gt-sticky-row-header]=\"\n (tableConfig$ | async)?.stickyHeaders?.row && (tableConfig$ | async)?.rows\n \"\n [class.gt-sticky-column-header]=\"\n (tableConfig$ | async)?.stickyHeaders?.column\n \"\n [attr.aria-busy]=\"(loading$ | async) === true ? true : null\"\n [tabindex]=\"(tableConfig$ | async)?.activateRowOnKeyboardNavigation ? 0 : -1\"\n #tableRef\n (focus)=\"listenToKeyboardEvents()\"\n (focusout)=\"unsubscribeFromKeyboardEvents(tableRef)\"\n (mouseenter)=\"listenToKeyboardEvents()\"\n (mouseleave)=\"unsubscribeFromKeyboardEvents(tableRef)\"\n>\n <thead>\n <tr\n *ngIf=\"{\n config: (tableConfig$ | async)!,\n isLoading: loading$ | async\n } as table\"\n >\n <ng-container\n *ngFor=\"let column of table.config?.columns | keyvalue: columnOrder\"\n >\n <th\n *ngIf=\"!column.value?.hidden\"\n ngClass=\"{{ (column.key | dashCase) + '-column' }} {{\n column.value.class\n }}\"\n [class.disabled]=\"table.isLoading\"\n [attr.aria-sort]=\"sortOrder$ | async | sortClass: column.key:'aria'\"\n [class.gt-sortable]=\"true\"\n scope=\"col\"\n >\n <button\n *ngIf=\"column.value?.sortable\"\n [attr.data-sort-order]=\"\n sortOrder$ | async | sortClass: column.key:'order'\n \"\n class=\"gt-sort\"\n (click)=\"\n table.isLoading ||\n !column.value.sortable ||\n sortByKey(column.key, $event)\n \"\n >\n <span *ngIf=\"column.value?.header !== false\">{{\n column.value.header || column.key | capitalCase\n }}</span>\n </button>\n <span\n *ngIf=\"!column.value?.sortable && column.value?.header !== false\"\n >{{ column.value.header || column.key | capitalCase }}</span\n >\n </th>\n </ng-container>\n <ng-container\n *ngIf=\"\n ((table?.config?.rows | keyvalue: columnOrder) || [])[0] as headerRow\n \"\n >\n <th\n class=\"row-header\"\n [attr.aria-sort]=\"\n sortOrder$ | async | sortClass: headerRow.key:'aria'\n \"\n ngClass=\"{{ headerRow.value.sortable ? 'sort ' : '' }} {{\n sortOrder$ | async | sortClass: headerRow.key\n }} {{ (headerRow.key | dashCase) + '-column' }}\"\n (click)=\"\n table.isLoading ||\n !headerRow.value.sortable ||\n sortByKey(headerRow.key, $event)\n \"\n scope=\"col\"\n >\n <ng-container *ngIf=\"headerRow?.value?.header !== false\">{{\n headerRow?.value?.header || headerRow.key | capitalCase\n }}</ng-container>\n </th>\n <th\n *ngFor=\"let column of ((table$ | async)?.data || [])[0]\"\n ngClass=\"{{ headerRow.value.class }}\"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (table.config.rows || {})[headerRow.key].templateRef\n ? templateRef\n : (table.config.rows || {})[headerRow.key].transform\n ? transformData\n : rawData\n \"\n [ngTemplateOutletContext]=\"{\n row: column,\n column: headerRow,\n transform: (table.config.rows || {})[headerRow.key].transform,\n templateRef: (table.config.rows || {})[headerRow.key].templateRef,\n index: 0\n }\"\n >\n </ng-container>\n </th>\n </ng-container>\n </tr>\n </thead>\n <tbody *ngIf=\"loading$ | async; else tableContent\">\n <tr>\n <td class=\"p-0\" [colSpan]=\"colspan$ | async\">\n <ng-content select=\".table-loading\"></ng-content>\n </td>\n </tr>\n </tbody>\n <tfoot *ngIf=\"(table$ | async)! as table\">\n <ng-container *ngIf=\"table.data.length > 0 && !(loading$ | async)\">\n <ng-container *ngIf=\"(calculations$ | async)! as calculations\">\n <tr\n *ngFor=\"let calculation of calculations.calculations; let i = index\"\n >\n <ng-container\n *ngIf=\"{\n showHeader: (colspan$ | async) !== (footerColspan$ | async)\n } as footerRow\"\n >\n <th\n *ngIf=\"footerRow.showHeader\"\n [colSpan]=\"\n ((colspan$ | async) || 0) - ((footerColspan$ | async) || 0)\n \"\n scope=\"row\"\n >\n <ng-container\n *ngIf=\"table.config?.footer?.headers?.[calculation] as showHeader\"\n >{{showHeader === true ? (calculation | capitalCase): table.config.footer?.headers?.[calculation]}}\n </ng-container>\n </th>\n <ng-container\n *ngFor=\"\n let column of table.config?.columns | keyvalue: columnOrder\n \"\n >\n <td\n *ngIf=\"\n !column.value?.hidden && calculations.calculated[column.key]\n \"\n ngClass=\"{{ (column.key | dashCase) + '-column' }} {{\n column.value.class\n }}\"\n [attr.data-header]=\"\n !footerRow.showHeader && table.config.footer?.headers?.[calculation]\n ? table.config.footer?.headers?.[calculation] === true ? (calculation | capitalCase) : table.config.footer?.headers?.[calculation]\n : null\n \"\n [attr.data-label]=\"\n table.config.mobileLayout && column.value.mobileHeader\n ? column.value.mobileHeader !== true\n ? column.value.mobileHeader\n : (column.value.header || column.key | capitalCase)\n : null\n \"\n [class.gt-no-content]=\"\n !calculations.calculated[column.key][calculation]\n \"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (table.config.columns || {})[column.key].templateRef\n ? templateRef\n : (table.config.columns || {})[column.key].transform\n ? transformFooter\n : rawFooter\n \"\n [ngTemplateOutletContext]=\"{\n value: calculations.calculated[column.key][calculation],\n row: calculations.calculated[column.key],\n column: calculation,\n templateRef: (table.config.columns || {})[column.key]\n .templateRef,\n transform: (table.config.columns || {})[column.key]\n .transform\n }\"\n ></ng-container>\n </td>\n </ng-container>\n </ng-container>\n </tr>\n </ng-container>\n </ng-container>\n </tfoot>\n</table>\n<ng-template #tableContent>\n <ng-container *ngIf=\"(table$ | async)! as table\">\n <tbody *ngIf=\"(table!.data![0] || table!.data!).length > 0; else noData\">\n <ng-container *ngIf=\"table.config.columns\">\n <tr\n *ngFor=\"\n let row of table!.data![\n table.info.lazyLoaded ? 0 : (currentPaginationIndex$ | async) || 0\n ];\n trackBy: trackRowByFn;\n let i = index\n \"\n [attr.id]=\"'tableRow_' + i\"\n (click)=\"table?.config?.rowClick && _rowClick(row, i, $event)\"\n (mouseenter)=\"\n table?.config?.activateRowOnHover && _activateRow(row, i, $event)\n \"\n (mouseleave)=\"\n table?.config?.activateRowOnHover &&\n _activateRow(null, null, $event)\n \"\n [ngClass]=\"[\n !!isRowSelectedFn\n ? (row\n | rowSelection\n : selection\n : isRowSelectedFn\n : customClasses.selectedRow)\n : '',\n (rowActive$ | async)?.index === i ? customClasses.activeRow : ''\n ]\"\n >\n <ng-container\n *ngFor=\"let column of table.config?.columns | keyvalue: columnOrder\"\n >\n <td\n *ngIf=\"!column.value?.hidden\"\n ngClass=\"{{ (column.key | dashCase) + '-column' }} {{\n column.value.class\n }}\"\n [attr.data-label]=\"\n table.config.mobileLayout && column.value.mobileHeader\n ? column.value.mobileHeader !== true\n ? column.value.mobileHeader\n : (column.value.header || column.key | capitalCase)\n : null\n \"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (searchBy$ | async) &&\n !(table.config.columns || {})[column.key].templateRef\n ? highlighted\n : (table.config.columns || {})[column.key].templateRef\n ? templateRef\n : (table.config.columns || {})[column.key].transform\n ? transformData\n : rawData\n \"\n [ngTemplateOutletContext]=\"{\n row: row,\n column: column,\n search: (searchBy$ | async),\n transform: (table.config.columns || {})[column.key].transform,\n templateRef: (table.config.columns || {})[column.key]\n .templateRef,\n index: i,\n data: table.data[\n table.info.lazyLoaded\n ? 0\n : (currentPaginationIndex$ | async) || 0\n ]\n }\"\n ></ng-container>\n </td>\n </ng-container>\n </tr>\n </ng-container>\n <ng-container *ngIf=\"table.config.rows\">\n <ng-container\n *ngFor=\"\n let row of table?.config?.rows | keyvalue: columnOrder | slice: 1;\n let i = index\n \"\n >\n <tr\n *ngIf=\"!row.value?.hidden\"\n [attr.id]=\"'tableRow_' + i\"\n ngClass=\"{{ (row.key | dashCase) + '-row' }}\"\n (click)=\"table?.config?.rowClick && _rowClick(row, i, $event)\"\n (mouseenter)=\"\n table?.config?.activateRowOnHover && _activateRow(row, i, $event)\n \"\n (mouseleave)=\"\n table?.config?.activateRowOnHover &&\n _activateRow(null, null, $event)\n \"\n [ngClass]=\"[\n !!isRowSelectedFn\n ? (row\n | rowSelection\n : selection\n : isRowSelectedFn\n : customClasses.selectedRow)\n : '',\n (rowActive$ | async)?.index === i ? customClasses.activeRow : ''\n ]\"\n >\n <th class=\"row-header\" scope=\"row\">\n {{ row.value.header || row.key | capitalCase }}\n </th>\n <td\n *ngFor=\"let column of (table?.data || [])[0]; let y = index\"\n ngClass=\"{{ row.value.class }}\"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (table.config.rows || {})[row.key].templateRef\n ? templateRef\n : (table.config.rows || {})[row.key].transform\n ? transformData\n : rawData\n \"\n [ngTemplateOutletContext]=\"{\n row: column,\n column: row,\n transform: (table.config.rows || {})[row.key].transform,\n templateRef: (table.config.rows || {})[row.key].templateRef,\n index: table.config.rows ? y : i,\n data: table.data[\n table.info.lazyLoaded\n ? 0\n : (currentPaginationIndex$ | async) || 0\n ]\n }\"\n >\n </ng-container>\n </td>\n </tr>\n </ng-container>\n </ng-container>\n </tbody>\n </ng-container>\n</ng-template>\n<ng-template #noData>\n <tbody>\n <tr>\n <td class=\"p-0\" [colSpan]=\"colspan$ | async\">\n <ng-content select=\".table-no-data\"></ng-content>\n </td>\n </tr>\n </tbody>\n</ng-template>\n<ng-template\n #highlighted\n let-row=\"row\"\n let-column=\"column\"\n let-search=\"search\"\n let-transform=\"transform\"\n>\n <div\n *ngIf=\"!transform\"\n [innerHTML]=\"row[column.key] | highlight: search\"\n ></div>\n <div\n *ngIf=\"transform\"\n [innerHTML]=\"\n row[column.key]\n | dynamicPipe: transform.pipe:transform?.args\n | highlight: search\n \"\n ></div>\n</ng-template>\n<ng-template #rawData let-row=\"row\" let-column=\"column\">\n {{ row[column.key] }}\n</ng-template>\n<ng-template\n #transformData\n let-row=\"row\"\n let-column=\"column\"\n let-transform=\"transform\"\n let-data=\"data\"\n>\n {{ row[column.key] | dynamicPipe: transform.pipe:transform?.args }}\n</ng-template>\n<ng-template #transformFooter let-value=\"value\" let-transform=\"transform\">\n {{\n (value | dynamicPipe: transform.pipe:transform?.args) ||\n (tableConfig$ | async)?.footer?.emptyContent\n }}\n</ng-template>\n<ng-template #rawFooter let-value=\"value\">\n {{ value || (tableConfig$ | async)?.footer?.emptyContent }}\n</ng-template>\n<ng-template\n #templateRef\n let-row=\"row\"\n let-column=\"column\"\n let-index=\"index\"\n let-templateRef=\"templateRef\"\n let-data=\"data\"\n>\n <ng-container\n [ngTemplateOutlet]=\"templateRef\"\n [ngTemplateOutletContext]=\"{\n row: row,\n col: column,\n index: index,\n data: data\n }\"\n ></ng-container>\n</ng-template>\n", dependencies: [{ kind: "pipe", type: CapitalCasePipe, name: "capitalCase" }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: SortClassPipe, name: "sortClass" }, { kind: "pipe", type: DashCasePipe, name: "dashCase" }, { kind: "pipe", type: RowSelectionPipe, name: "rowSelection" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: SlicePipe, name: "slice" }, { kind: "pipe", type: DynamicPipe, name: "dynamicPipe" }, { kind: "pipe", type: HighlightPipe, name: "highlight" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
283
500
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: CoreComponent, decorators: [{
284
501
  type: Component,
285
502
  args: [{ selector: 'angular-generic-table', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
@@ -287,6 +504,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImpor
287
504
  KeyValuePipe,
288
505
  SortClassPipe,
289
506
  DashCasePipe,
507
+ RowSelectionPipe,
290
508
  AsyncPipe,
291
509
  NgTemplateOutlet,
292
510
  SlicePipe,
@@ -295,13 +513,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImpor
295
513
  NgClass,
296
514
  NgIf,
297
515
  NgForOf,
298
- ], template: "<table\n [ngClass]=\"(tableConfig$ | async)?.class || 'table'\"\n [class.table-mobile]=\"(tableConfig$ | async)?.mobileLayout\"\n [class.table-horizontal]=\"(tableConfig$ | async)?.rows\"\n [class.table-loading]=\"loading$ | async\"\n [class.gt-sticky-row-header]=\"\n (tableConfig$ | async)?.stickyHeaders?.row && (tableConfig$ | async)?.rows\n \"\n [class.gt-sticky-column-header]=\"\n (tableConfig$ | async)?.stickyHeaders?.column\n \"\n [attr.aria-busy]=\"(loading$ | async) === true ? true : null\"\n>\n <thead>\n <tr\n *ngIf=\"{\n config: (tableConfig$ | async)!,\n isLoading: loading$ | async\n } as table\"\n >\n <ng-container\n *ngFor=\"let column of table.config?.columns | keyvalue: columnOrder\"\n >\n <th\n *ngIf=\"!column.value?.hidden\"\n ngClass=\"{{ (column.key | dashCase) + '-column' }} {{\n column.value.class\n }}\"\n [class.disabled]=\"table.isLoading\"\n [attr.aria-sort]=\"sortOrder$ | async | sortClass: column.key:'aria'\"\n [class.gt-sortable]=\"true\"\n scope=\"col\"\n >\n <button\n *ngIf=\"column.value?.sortable\"\n [attr.data-sort-order]=\"\n sortOrder$ | async | sortClass: column.key:'order'\n \"\n class=\"gt-sort\"\n (click)=\"\n table.isLoading ||\n !column.value.sortable ||\n sortByKey(column.key, $event)\n \"\n >\n <span *ngIf=\"column.value?.header !== false\">{{\n column.value.header || column.key | capitalCase\n }}</span>\n </button>\n <span\n *ngIf=\"!column.value?.sortable && column.value?.header !== false\"\n >{{ column.value.header || column.key | capitalCase }}</span\n >\n </th>\n </ng-container>\n <ng-container\n *ngIf=\"\n ((table?.config?.rows | keyvalue: columnOrder) || [])[0] as headerRow\n \"\n >\n <th\n class=\"row-header\"\n [attr.aria-sort]=\"\n sortOrder$ | async | sortClass: headerRow.key:'aria'\n \"\n ngClass=\"{{ headerRow.value.sortable ? 'sort ' : '' }} {{\n sortOrder$ | async | sortClass: headerRow.key\n }} {{ (headerRow.key | dashCase) + '-column' }}\"\n (click)=\"\n table.isLoading ||\n !headerRow.value.sortable ||\n sortByKey(headerRow.key, $event)\n \"\n scope=\"col\"\n >\n <ng-container *ngIf=\"headerRow?.value?.header !== false\">{{\n headerRow?.value?.header || headerRow.key | capitalCase\n }}</ng-container>\n </th>\n <th\n *ngFor=\"let column of ((table$ | async)?.data || [])[0]\"\n ngClass=\"{{ headerRow.value.class }}\"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (table.config.rows || {})[headerRow.key].templateRef\n ? templateRef\n : (table.config.rows || {})[headerRow.key].transform\n ? transformData\n : rawData\n \"\n [ngTemplateOutletContext]=\"{\n row: column,\n column: headerRow,\n transform: (table.config.rows || {})[headerRow.key].transform,\n templateRef: (table.config.rows || {})[headerRow.key].templateRef,\n index: 0\n }\"\n >\n </ng-container>\n </th>\n </ng-container>\n </tr>\n </thead>\n <tbody *ngIf=\"loading$ | async; else tableContent\">\n <tr>\n <td class=\"p-0\" [colSpan]=\"colspan$ | async\">\n <ng-content select=\".table-loading\"></ng-content>\n </td>\n </tr>\n </tbody>\n <tfoot *ngIf=\"(table$ | async)! as table\">\n <ng-container *ngIf=\"table.data.length > 0 && !(loading$ | async)\">\n <ng-container *ngIf=\"(calculations$ | async)! as calculations\">\n <tr\n *ngFor=\"let calculation of calculations.calculations; let i = index\"\n >\n <ng-container\n *ngIf=\"{\n showHeader: (colspan$ | async) !== (footerColspan$ | async)\n } as footerRow\"\n >\n <th\n *ngIf=\"footerRow.showHeader\"\n [colSpan]=\"\n ((colspan$ | async) || 0) - ((footerColspan$ | async) || 0)\n \"\n scope=\"row\"\n >\n <ng-container\n *ngIf=\"table.config?.footer?.headers?.[calculation] as showHeader\"\n >{{showHeader === true ? (calculation | capitalCase): table.config.footer?.headers?.[calculation]}}\n </ng-container>\n </th>\n <ng-container\n *ngFor=\"\n let column of table.config?.columns | keyvalue: columnOrder\n \"\n >\n <td\n *ngIf=\"\n !column.value?.hidden && calculations.calculated[column.key]\n \"\n ngClass=\"{{ (column.key | dashCase) + '-column' }} {{\n column.value.class\n }}\"\n [attr.data-header]=\"\n !footerRow.showHeader && table.config.footer?.headers?.[calculation]\n ? table.config.footer?.headers?.[calculation] === true ? (calculation | capitalCase) : table.config.footer?.headers?.[calculation]\n : null\n \"\n [attr.data-label]=\"\n table.config.mobileLayout && column.value.mobileHeader\n ? column.value.mobileHeader !== true\n ? column.value.mobileHeader\n : (column.value.header || column.key | capitalCase)\n : null\n \"\n [class.gt-no-content]=\"\n !calculations.calculated[column.key][calculation]\n \"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (table.config.columns || {})[column.key].templateRef\n ? templateRef\n : (table.config.columns || {})[column.key].transform\n ? transformFooter\n : rawFooter\n \"\n [ngTemplateOutletContext]=\"{\n value: calculations.calculated[column.key][calculation],\n row: calculations.calculated[column.key],\n column: calculation,\n templateRef: (table.config.columns || {})[column.key]\n .templateRef,\n transform: (table.config.columns || {})[column.key]\n .transform\n }\"\n ></ng-container>\n </td>\n </ng-container>\n </ng-container>\n </tr>\n </ng-container>\n </ng-container>\n </tfoot>\n</table>\n<ng-template #tableContent>\n <ng-container *ngIf=\"(table$ | async)! as table\">\n <tbody *ngIf=\"(table!.data![0] || table!.data!).length > 0; else noData\">\n <ng-container *ngIf=\"table.config.columns\">\n <tr\n *ngFor=\"\n let row of table!.data![\n table.info.lazyLoaded ? 0 : (currentPaginationIndex$ | async) || 0\n ];\n let i = index\n \"\n [attr.id]=\"'tableRow_' + i\"\n (click)=\"table?.config?.rowClick && _rowClick(row, i, $event)\"\n (mouseover)=\"table?.config?.rowHover && _hoverRow(row, i, $event)\"\n (mouseout)=\"table?.config?.rowHover && _hoverRow(null, null, $event)\"\n [class.gt-hover]=\"(rowHover$ | async)?.index === i\"\n >\n <ng-container\n *ngFor=\"let column of table.config?.columns | keyvalue: columnOrder\"\n >\n <td\n *ngIf=\"!column.value?.hidden\"\n ngClass=\"{{ (column.key | dashCase) + '-column' }} {{\n column.value.class\n }}\"\n [attr.data-label]=\"\n table.config.mobileLayout && column.value.mobileHeader\n ? column.value.mobileHeader !== true\n ? column.value.mobileHeader\n : (column.value.header || column.key | capitalCase)\n : null\n \"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (searchBy$ | async) &&\n !(table.config.columns || {})[column.key].templateRef\n ? highlighted\n : (table.config.columns || {})[column.key].templateRef\n ? templateRef\n : (table.config.columns || {})[column.key].transform\n ? transformData\n : rawData\n \"\n [ngTemplateOutletContext]=\"{\n row: row,\n column: column,\n search: (searchBy$ | async),\n transform: (table.config.columns || {})[column.key].transform,\n templateRef: (table.config.columns || {})[column.key]\n .templateRef,\n index: i,\n data: table.data[\n table.info.lazyLoaded\n ? 0\n : (currentPaginationIndex$ | async) || 0\n ]\n }\"\n ></ng-container>\n </td>\n </ng-container>\n </tr>\n </ng-container>\n <ng-container *ngIf=\"table.config.rows\">\n <ng-container\n *ngFor=\"\n let row of table?.config?.rows | keyvalue: columnOrder | slice: 1;\n let i = index\n \"\n >\n <tr\n *ngIf=\"!row.value?.hidden\"\n [attr.id]=\"'tableRow_' + i\"\n ngClass=\"{{ (row.key | dashCase) + '-row' }}\"\n (click)=\"table?.config?.rowClick && _rowClick(row, i, $event)\"\n (mouseover)=\"table?.config?.rowHover && _hoverRow(row, i, $event)\"\n (mouseout)=\"\n table?.config?.rowHover && _hoverRow(null, null, $event)\n \"\n [class.gt-hover]=\"(rowHover$ | async)?.index === i\"\n >\n <th class=\"row-header\" scope=\"row\">\n {{ row.value.header || row.key | capitalCase }}\n </th>\n <td\n *ngFor=\"let column of (table?.data || [])[0]; let y = index\"\n ngClass=\"{{ row.value.class }}\"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (table.config.rows || {})[row.key].templateRef\n ? templateRef\n : (table.config.rows || {})[row.key].transform\n ? transformData\n : rawData\n \"\n [ngTemplateOutletContext]=\"{\n row: column,\n column: row,\n transform: (table.config.rows || {})[row.key].transform,\n templateRef: (table.config.rows || {})[row.key].templateRef,\n index: table.config.rows ? y : i,\n data: table.data[\n table.info.lazyLoaded\n ? 0\n : (currentPaginationIndex$ | async) || 0\n ]\n }\"\n >\n </ng-container>\n </td>\n </tr>\n </ng-container>\n </ng-container>\n </tbody>\n </ng-container>\n</ng-template>\n<ng-template #noData>\n <tbody>\n <tr>\n <td class=\"p-0\" [colSpan]=\"colspan$ | async\">\n <ng-content select=\".table-no-data\"></ng-content>\n </td>\n </tr>\n </tbody>\n</ng-template>\n<ng-template\n #highlighted\n let-row=\"row\"\n let-column=\"column\"\n let-search=\"search\"\n let-transform=\"transform\"\n>\n <div\n *ngIf=\"!transform\"\n [innerHTML]=\"row[column.key] | highlight: search\"\n ></div>\n <div\n *ngIf=\"transform\"\n [innerHTML]=\"\n row[column.key]\n | dynamicPipe: transform.pipe:transform?.args\n | highlight: search\n \"\n ></div>\n</ng-template>\n<ng-template #rawData let-row=\"row\" let-column=\"column\">\n {{ row[column.key] }}\n</ng-template>\n<ng-template\n #transformData\n let-row=\"row\"\n let-column=\"column\"\n let-transform=\"transform\"\n let-data=\"data\"\n>\n {{ row[column.key] | dynamicPipe: transform.pipe:transform?.args }}\n</ng-template>\n<ng-template #transformFooter let-value=\"value\" let-transform=\"transform\">\n {{\n (value | dynamicPipe: transform.pipe:transform?.args) ||\n (tableConfig$ | async)?.footer?.emptyContent\n }}\n</ng-template>\n<ng-template #rawFooter let-value=\"value\">\n {{ value || (tableConfig$ | async)?.footer?.emptyContent }}\n</ng-template>\n<ng-template\n #templateRef\n let-row=\"row\"\n let-column=\"column\"\n let-index=\"index\"\n let-templateRef=\"templateRef\"\n let-data=\"data\"\n>\n <ng-container\n [ngTemplateOutlet]=\"templateRef\"\n [ngTemplateOutletContext]=\"{\n row: row,\n col: column,\n index: index,\n data: data\n }\"\n ></ng-container>\n</ng-template>\n" }]
299
- }], propDecorators: { loading: [{
516
+ ], template: "<table\n [ngClass]=\"(tableConfig$ | async)?.class || 'table'\"\n [class.table-mobile]=\"(tableConfig$ | async)?.mobileLayout\"\n [class.table-horizontal]=\"(tableConfig$ | async)?.rows\"\n [class.table-loading]=\"loading$ | async\"\n [class.gt-sticky-row-header]=\"\n (tableConfig$ | async)?.stickyHeaders?.row && (tableConfig$ | async)?.rows\n \"\n [class.gt-sticky-column-header]=\"\n (tableConfig$ | async)?.stickyHeaders?.column\n \"\n [attr.aria-busy]=\"(loading$ | async) === true ? true : null\"\n [tabindex]=\"(tableConfig$ | async)?.activateRowOnKeyboardNavigation ? 0 : -1\"\n #tableRef\n (focus)=\"listenToKeyboardEvents()\"\n (focusout)=\"unsubscribeFromKeyboardEvents(tableRef)\"\n (mouseenter)=\"listenToKeyboardEvents()\"\n (mouseleave)=\"unsubscribeFromKeyboardEvents(tableRef)\"\n>\n <thead>\n <tr\n *ngIf=\"{\n config: (tableConfig$ | async)!,\n isLoading: loading$ | async\n } as table\"\n >\n <ng-container\n *ngFor=\"let column of table.config?.columns | keyvalue: columnOrder\"\n >\n <th\n *ngIf=\"!column.value?.hidden\"\n ngClass=\"{{ (column.key | dashCase) + '-column' }} {{\n column.value.class\n }}\"\n [class.disabled]=\"table.isLoading\"\n [attr.aria-sort]=\"sortOrder$ | async | sortClass: column.key:'aria'\"\n [class.gt-sortable]=\"true\"\n scope=\"col\"\n >\n <button\n *ngIf=\"column.value?.sortable\"\n [attr.data-sort-order]=\"\n sortOrder$ | async | sortClass: column.key:'order'\n \"\n class=\"gt-sort\"\n (click)=\"\n table.isLoading ||\n !column.value.sortable ||\n sortByKey(column.key, $event)\n \"\n >\n <span *ngIf=\"column.value?.header !== false\">{{\n column.value.header || column.key | capitalCase\n }}</span>\n </button>\n <span\n *ngIf=\"!column.value?.sortable && column.value?.header !== false\"\n >{{ column.value.header || column.key | capitalCase }}</span\n >\n </th>\n </ng-container>\n <ng-container\n *ngIf=\"\n ((table?.config?.rows | keyvalue: columnOrder) || [])[0] as headerRow\n \"\n >\n <th\n class=\"row-header\"\n [attr.aria-sort]=\"\n sortOrder$ | async | sortClass: headerRow.key:'aria'\n \"\n ngClass=\"{{ headerRow.value.sortable ? 'sort ' : '' }} {{\n sortOrder$ | async | sortClass: headerRow.key\n }} {{ (headerRow.key | dashCase) + '-column' }}\"\n (click)=\"\n table.isLoading ||\n !headerRow.value.sortable ||\n sortByKey(headerRow.key, $event)\n \"\n scope=\"col\"\n >\n <ng-container *ngIf=\"headerRow?.value?.header !== false\">{{\n headerRow?.value?.header || headerRow.key | capitalCase\n }}</ng-container>\n </th>\n <th\n *ngFor=\"let column of ((table$ | async)?.data || [])[0]\"\n ngClass=\"{{ headerRow.value.class }}\"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (table.config.rows || {})[headerRow.key].templateRef\n ? templateRef\n : (table.config.rows || {})[headerRow.key].transform\n ? transformData\n : rawData\n \"\n [ngTemplateOutletContext]=\"{\n row: column,\n column: headerRow,\n transform: (table.config.rows || {})[headerRow.key].transform,\n templateRef: (table.config.rows || {})[headerRow.key].templateRef,\n index: 0\n }\"\n >\n </ng-container>\n </th>\n </ng-container>\n </tr>\n </thead>\n <tbody *ngIf=\"loading$ | async; else tableContent\">\n <tr>\n <td class=\"p-0\" [colSpan]=\"colspan$ | async\">\n <ng-content select=\".table-loading\"></ng-content>\n </td>\n </tr>\n </tbody>\n <tfoot *ngIf=\"(table$ | async)! as table\">\n <ng-container *ngIf=\"table.data.length > 0 && !(loading$ | async)\">\n <ng-container *ngIf=\"(calculations$ | async)! as calculations\">\n <tr\n *ngFor=\"let calculation of calculations.calculations; let i = index\"\n >\n <ng-container\n *ngIf=\"{\n showHeader: (colspan$ | async) !== (footerColspan$ | async)\n } as footerRow\"\n >\n <th\n *ngIf=\"footerRow.showHeader\"\n [colSpan]=\"\n ((colspan$ | async) || 0) - ((footerColspan$ | async) || 0)\n \"\n scope=\"row\"\n >\n <ng-container\n *ngIf=\"table.config?.footer?.headers?.[calculation] as showHeader\"\n >{{showHeader === true ? (calculation | capitalCase): table.config.footer?.headers?.[calculation]}}\n </ng-container>\n </th>\n <ng-container\n *ngFor=\"\n let column of table.config?.columns | keyvalue: columnOrder\n \"\n >\n <td\n *ngIf=\"\n !column.value?.hidden && calculations.calculated[column.key]\n \"\n ngClass=\"{{ (column.key | dashCase) + '-column' }} {{\n column.value.class\n }}\"\n [attr.data-header]=\"\n !footerRow.showHeader && table.config.footer?.headers?.[calculation]\n ? table.config.footer?.headers?.[calculation] === true ? (calculation | capitalCase) : table.config.footer?.headers?.[calculation]\n : null\n \"\n [attr.data-label]=\"\n table.config.mobileLayout && column.value.mobileHeader\n ? column.value.mobileHeader !== true\n ? column.value.mobileHeader\n : (column.value.header || column.key | capitalCase)\n : null\n \"\n [class.gt-no-content]=\"\n !calculations.calculated[column.key][calculation]\n \"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (table.config.columns || {})[column.key].templateRef\n ? templateRef\n : (table.config.columns || {})[column.key].transform\n ? transformFooter\n : rawFooter\n \"\n [ngTemplateOutletContext]=\"{\n value: calculations.calculated[column.key][calculation],\n row: calculations.calculated[column.key],\n column: calculation,\n templateRef: (table.config.columns || {})[column.key]\n .templateRef,\n transform: (table.config.columns || {})[column.key]\n .transform\n }\"\n ></ng-container>\n </td>\n </ng-container>\n </ng-container>\n </tr>\n </ng-container>\n </ng-container>\n </tfoot>\n</table>\n<ng-template #tableContent>\n <ng-container *ngIf=\"(table$ | async)! as table\">\n <tbody *ngIf=\"(table!.data![0] || table!.data!).length > 0; else noData\">\n <ng-container *ngIf=\"table.config.columns\">\n <tr\n *ngFor=\"\n let row of table!.data![\n table.info.lazyLoaded ? 0 : (currentPaginationIndex$ | async) || 0\n ];\n trackBy: trackRowByFn;\n let i = index\n \"\n [attr.id]=\"'tableRow_' + i\"\n (click)=\"table?.config?.rowClick && _rowClick(row, i, $event)\"\n (mouseenter)=\"\n table?.config?.activateRowOnHover && _activateRow(row, i, $event)\n \"\n (mouseleave)=\"\n table?.config?.activateRowOnHover &&\n _activateRow(null, null, $event)\n \"\n [ngClass]=\"[\n !!isRowSelectedFn\n ? (row\n | rowSelection\n : selection\n : isRowSelectedFn\n : customClasses.selectedRow)\n : '',\n (rowActive$ | async)?.index === i ? customClasses.activeRow : ''\n ]\"\n >\n <ng-container\n *ngFor=\"let column of table.config?.columns | keyvalue: columnOrder\"\n >\n <td\n *ngIf=\"!column.value?.hidden\"\n ngClass=\"{{ (column.key | dashCase) + '-column' }} {{\n column.value.class\n }}\"\n [attr.data-label]=\"\n table.config.mobileLayout && column.value.mobileHeader\n ? column.value.mobileHeader !== true\n ? column.value.mobileHeader\n : (column.value.header || column.key | capitalCase)\n : null\n \"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (searchBy$ | async) &&\n !(table.config.columns || {})[column.key].templateRef\n ? highlighted\n : (table.config.columns || {})[column.key].templateRef\n ? templateRef\n : (table.config.columns || {})[column.key].transform\n ? transformData\n : rawData\n \"\n [ngTemplateOutletContext]=\"{\n row: row,\n column: column,\n search: (searchBy$ | async),\n transform: (table.config.columns || {})[column.key].transform,\n templateRef: (table.config.columns || {})[column.key]\n .templateRef,\n index: i,\n data: table.data[\n table.info.lazyLoaded\n ? 0\n : (currentPaginationIndex$ | async) || 0\n ]\n }\"\n ></ng-container>\n </td>\n </ng-container>\n </tr>\n </ng-container>\n <ng-container *ngIf=\"table.config.rows\">\n <ng-container\n *ngFor=\"\n let row of table?.config?.rows | keyvalue: columnOrder | slice: 1;\n let i = index\n \"\n >\n <tr\n *ngIf=\"!row.value?.hidden\"\n [attr.id]=\"'tableRow_' + i\"\n ngClass=\"{{ (row.key | dashCase) + '-row' }}\"\n (click)=\"table?.config?.rowClick && _rowClick(row, i, $event)\"\n (mouseenter)=\"\n table?.config?.activateRowOnHover && _activateRow(row, i, $event)\n \"\n (mouseleave)=\"\n table?.config?.activateRowOnHover &&\n _activateRow(null, null, $event)\n \"\n [ngClass]=\"[\n !!isRowSelectedFn\n ? (row\n | rowSelection\n : selection\n : isRowSelectedFn\n : customClasses.selectedRow)\n : '',\n (rowActive$ | async)?.index === i ? customClasses.activeRow : ''\n ]\"\n >\n <th class=\"row-header\" scope=\"row\">\n {{ row.value.header || row.key | capitalCase }}\n </th>\n <td\n *ngFor=\"let column of (table?.data || [])[0]; let y = index\"\n ngClass=\"{{ row.value.class }}\"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (table.config.rows || {})[row.key].templateRef\n ? templateRef\n : (table.config.rows || {})[row.key].transform\n ? transformData\n : rawData\n \"\n [ngTemplateOutletContext]=\"{\n row: column,\n column: row,\n transform: (table.config.rows || {})[row.key].transform,\n templateRef: (table.config.rows || {})[row.key].templateRef,\n index: table.config.rows ? y : i,\n data: table.data[\n table.info.lazyLoaded\n ? 0\n : (currentPaginationIndex$ | async) || 0\n ]\n }\"\n >\n </ng-container>\n </td>\n </tr>\n </ng-container>\n </ng-container>\n </tbody>\n </ng-container>\n</ng-template>\n<ng-template #noData>\n <tbody>\n <tr>\n <td class=\"p-0\" [colSpan]=\"colspan$ | async\">\n <ng-content select=\".table-no-data\"></ng-content>\n </td>\n </tr>\n </tbody>\n</ng-template>\n<ng-template\n #highlighted\n let-row=\"row\"\n let-column=\"column\"\n let-search=\"search\"\n let-transform=\"transform\"\n>\n <div\n *ngIf=\"!transform\"\n [innerHTML]=\"row[column.key] | highlight: search\"\n ></div>\n <div\n *ngIf=\"transform\"\n [innerHTML]=\"\n row[column.key]\n | dynamicPipe: transform.pipe:transform?.args\n | highlight: search\n \"\n ></div>\n</ng-template>\n<ng-template #rawData let-row=\"row\" let-column=\"column\">\n {{ row[column.key] }}\n</ng-template>\n<ng-template\n #transformData\n let-row=\"row\"\n let-column=\"column\"\n let-transform=\"transform\"\n let-data=\"data\"\n>\n {{ row[column.key] | dynamicPipe: transform.pipe:transform?.args }}\n</ng-template>\n<ng-template #transformFooter let-value=\"value\" let-transform=\"transform\">\n {{\n (value | dynamicPipe: transform.pipe:transform?.args) ||\n (tableConfig$ | async)?.footer?.emptyContent\n }}\n</ng-template>\n<ng-template #rawFooter let-value=\"value\">\n {{ value || (tableConfig$ | async)?.footer?.emptyContent }}\n</ng-template>\n<ng-template\n #templateRef\n let-row=\"row\"\n let-column=\"column\"\n let-index=\"index\"\n let-templateRef=\"templateRef\"\n let-data=\"data\"\n>\n <ng-container\n [ngTemplateOutlet]=\"templateRef\"\n [ngTemplateOutletContext]=\"{\n row: row,\n col: column,\n index: index,\n data: data\n }\"\n ></ng-container>\n</ng-template>\n" }]
517
+ }], propDecorators: { navigationKeys: [{
518
+ type: Input
519
+ }], selectKeys: [{
520
+ type: Input
521
+ }], loading: [{
300
522
  type: Input
301
523
  }], paginationIndex: [{
302
524
  type: Input
303
525
  }], pagingInfo: [{
304
526
  type: Input
527
+ }], customClasses: [{
528
+ type: Input
529
+ }], isRowSelectedFn: [{
530
+ type: Input
531
+ }], selection: [{
532
+ type: Input
533
+ }], rowIdKey: [{
534
+ type: Input
535
+ }], generateRowId: [{
536
+ type: Input
537
+ }], trackRowByFn: [{
538
+ type: Input
305
539
  }], search: [{
306
540
  type: Input
307
541
  }], config: [{
@@ -312,13 +546,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImpor
312
546
  type: Input
313
547
  }], rowClick: [{
314
548
  type: Output
549
+ }], rowSelect: [{
550
+ type: Output
315
551
  }], sortOrderChange: [{
316
552
  type: Output
317
- }], rowHover: [{
553
+ }], rowActive: [{
318
554
  type: Output
319
555
  }], columnSort: [{
320
556
  type: Output
321
557
  }], pageChange: [{
322
558
  type: Output
323
559
  }] } });
324
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29yZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb3JlL3NyYy9saWIvY29yZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb3JlL3NyYy9saWIvY29yZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDVCxZQUFZLEVBQ1osS0FBSyxFQUNMLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQ0wsZUFBZSxFQUNmLGFBQWEsRUFDYixZQUFZLEVBRVosRUFBRSxFQUNGLGFBQWEsR0FDZCxNQUFNLE1BQU0sQ0FBQztBQUVkLE9BQU8sRUFDTCxTQUFTLEVBRVQsWUFBWSxFQUNaLE9BQU8sRUFDUCxPQUFPLEVBQ1AsSUFBSSxFQUNKLGdCQUFnQixFQUNoQixTQUFTLEdBQ1YsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QixPQUFPLEVBQ0wsWUFBWSxFQUNaLG9CQUFvQixFQUNwQixNQUFNLEVBQ04sR0FBRyxFQUNILFdBQVcsRUFDWCxTQUFTLEVBQ1QsU0FBUyxFQUNULElBQUksRUFDSixHQUFHLEVBQ0gsY0FBYyxHQUNmLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEIsT0FBTyxFQUNMLFNBQVMsRUFDVCxLQUFLLEVBQ0wsTUFBTSxFQUNOLGtCQUFrQixHQUNuQixNQUFNLHVCQUF1QixDQUFDO0FBVS9CLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDeEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3RELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNuRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7O0FB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Q2IsWUFBWSw0Q0FDWixTQUFTLDhDQUNULGdCQUFnQiwrSUFDaEIsU0FBUyx5Q0FDVCxXQUFXLCtDQUNYLGFBQWEsa0RBQ2IsT0FBTyxvRkFDUCxJQUFJLDZGQUNKLE9BQU87MkZBR0UsYUFBYTtrQkFwQnpCLFNBQVM7K0JBQ0UsdUJBQXVCLG1CQUVoQix1QkFBdUIsQ0FBQyxNQUFNLGNBQ25DLElBQUksV0FDUDt3QkFDUCxlQUFlO3dCQUNmLFlBQVk7d0JBQ1osYUFBYTt3QkFDYixZQUFZO3dCQUNaLFNBQVM7d0JBQ1QsZ0JBQWdCO3dCQUNoQixTQUFTO3dCQUNULFdBQVc7d0JBQ1gsYUFBYTt3QkFDYixPQUFPO3dCQUNQLElBQUk7d0JBQ0osT0FBTztxQkFDUjs4QkFPWSxPQUFPO3NCQUFuQixLQUFLO2dCQUlGLGVBQWU7c0JBRGxCLEtBQUs7Z0JBS08sVUFBVTtzQkFBdEIsS0FBSztnQkFhRixNQUFNO3NCQURULEtBQUs7Z0JBTUYsTUFBTTtzQkFEVCxLQUFLO2dCQU1GLElBQUk7c0JBRFAsS0FBSztnQkFLTyxTQUFTO3NCQUFyQixLQUFLO2dCQU9JLFFBQVE7c0JBQWpCLE1BQU07Z0JBQ0csZUFBZTtzQkFBeEIsTUFBTTtnQkFPRyxRQUFRO3NCQUFqQixNQUFNO2dCQUNHLFVBQVU7c0JBQW5CLE1BQU07Z0JBRUcsVUFBVTtzQkFBbkIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDb21wb25lbnQsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE91dHB1dCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICBCZWhhdmlvclN1YmplY3QsXG4gIGNvbWJpbmVMYXRlc3QsXG4gIGlzT2JzZXJ2YWJsZSxcbiAgT2JzZXJ2YWJsZSxcbiAgb2YsXG4gIFJlcGxheVN1YmplY3QsXG59IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgVGFibGVDb25maWcgfSBmcm9tICcuL21vZGVscy90YWJsZS1jb25maWcuaW50ZXJmYWNlJztcbmltcG9ydCB7XG4gIEFzeW5jUGlwZSxcbiAgS2V5VmFsdWUsXG4gIEtleVZhbHVlUGlwZSxcbiAgTmdDbGFzcyxcbiAgTmdGb3JPZixcbiAgTmdJZixcbiAgTmdUZW1wbGF0ZU91dGxldCxcbiAgU2xpY2VQaXBlLFxufSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgZGVib3VuY2VUaW1lLFxuICBkaXN0aW5jdFVudGlsQ2hhbmdlZCxcbiAgZmlsdGVyLFxuICBtYXAsXG4gIHNoYXJlUmVwbGF5LFxuICBzdGFydFdpdGgsXG4gIHN3aXRjaE1hcCxcbiAgdGFrZSxcbiAgdGFwLFxuICB3aXRoTGF0ZXN0RnJvbSxcbn0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGFibGVDb2x1bW4gfSBmcm9tICcuL21vZGVscy90YWJsZS1jb2x1bW4uaW50ZXJmYWNlJztcbmltcG9ydCB7XG4gIGNhbGN1bGF0ZSxcbiAgY2h1bmssXG4gIHNlYXJjaCxcbiAgc29ydE9uTXVsdGlwbGVLZXlzLFxufSBmcm9tICcuL3V0aWxpdGllcy91dGlsaXRpZXMnO1xuaW1wb3J0IHsgVGFibGVSb3cgfSBmcm9tICcuL21vZGVscy90YWJsZS1yb3cuaW50ZXJmYWNlJztcbmltcG9ydCB7IEd0T3JkZXIsIEd0U29ydE9yZGVyIH0gZnJvbSAnLi9tb2RlbHMvdGFibGUtc29ydC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgVGFibGVNZXRhIH0gZnJvbSAnLi9tb2RlbHMvdGFibGUtbWV0YS5pbnRlcmZhY2UnO1xuaW1wb3J0IHtcbiAgR3RQYWdlQ2hhbmdlRXZlbnQsXG4gIEd0Um93Q2xpY2tFdmVudCxcbiAgR3RSb3dIb3ZlckV2ZW50LFxuICBHdFNvcnRFdmVudCxcbn0gZnJvbSAnLi9tb2RlbHMvdGFibGUtZXZlbnRzLmludGVyZmFjZSc7XG5pbXBvcnQgeyBDYXBpdGFsQ2FzZVBpcGUgfSBmcm9tICcuL3BpcGVzL2NhcGl0YWwtY2FzZS5waXBlJztcbmltcG9ydCB7IFNvcnRDbGFzc1BpcGUgfSBmcm9tICcuL3BpcGVzL3NvcnQtY2xhc3MucGlwZSc7XG5pbXBvcnQgeyBEYXNoQ2FzZVBpcGUgfSBmcm9tICcuL3BpcGVzL2Rhc2gtY2FzZS5waXBlJztcbmltcG9ydCB7IER5bmFtaWNQaXBlIH0gZnJvbSAnLi9waXBlcy9keW5hbWljLnBpcGUnO1xuaW1wb3J0IHsgSGlnaGxpZ2h0UGlwZSB9IGZyb20gJy4vcGlwZXMvaGlnaGxpZ2h0LnBpcGUnO1xuaW1wb3J0IHsgR3RQYWdpbmF0aW9uSW5mbyB9IGZyb20gJy4vbW9kZWxzL2d0LXBhZ2luYXRpb24nO1xuaW1wb3J0IHsgVGFibGVJbmZvIH0gZnJvbSAnLi9tb2RlbHMvdGFibGUtaW5mby5pbnRlcmZhY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhbmd1bGFyLWdlbmVyaWMtdGFibGUnLFxuICB0ZW1wbGF0ZVVybDogJy4vY29yZS5jb21wb25lbnQuaHRtbCcsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgQ2FwaXRhbENhc2VQaXBlLFxuICAgIEtleVZhbHVlUGlwZSxcbiAgICBTb3J0Q2xhc3NQaXBlLFxuICAgIERhc2hDYXNlUGlwZSxcbiAgICBBc3luY1BpcGUsXG4gICAgTmdUZW1wbGF0ZU91dGxldCxcbiAgICBTbGljZVBpcGUsXG4gICAgRHluYW1pY1BpcGUsXG4gICAgSGlnaGxpZ2h0UGlwZSxcbiAgICBOZ0NsYXNzLFxuICAgIE5nSWYsXG4gICAgTmdGb3JPZixcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgQ29yZUNvbXBvbmVudCB7XG4gIGdldCBzb3J0T3JkZXIkKCk6IE9ic2VydmFibGU8R3RTb3J0T3JkZXI+IHtcbiAgICByZXR1cm4gdGhpcy5fc29ydE9yZGVyJC5hc09ic2VydmFibGUoKTtcbiAgfVxuXG4gIEBJbnB1dCgpIHNldCBsb2FkaW5nKGlzTG9hZGluZzogT2JzZXJ2YWJsZTxib29sZWFuPiB8IGJvb2xlYW4pIHtcbiAgICB0aGlzLl9sb2FkaW5nJC5uZXh0KGlzTG9hZGluZyk7XG4gIH1cbiAgQElucHV0KClcbiAgc2V0IHBhZ2luYXRpb25JbmRleChwYWdlSW5kZXg6IG51bWJlcikge1xuICAgIHRoaXMuX2N1cnJlbnRQYWdpbmF0aW9uSW5kZXgkLm5leHQocGFnZUluZGV4KTtcbiAgfVxuXG4gIEBJbnB1dCgpIHNldCBwYWdpbmdJbmZvKHZhbHVlOiBHdFBhZ2luYXRpb25JbmZvIHwgbnVsbCkge1xuICAgIGlmICh2YWx1ZSkge1xuICAgICAgdGhpcy5fcGFnaW5nSW5mbyQubmV4dCh2YWx1ZSk7XG4gICAgICBpZiAoXG4gICAgICAgIHZhbHVlLnBhZ2VDdXJyZW50ICE9PSB0aGlzLl9jdXJyZW50UGFnaW5hdGlvbkluZGV4JC5nZXRWYWx1ZSgpICsgMSAmJlxuICAgICAgICB2YWx1ZS5wYWdlQ3VycmVudCAhPT0gbnVsbFxuICAgICAgKSB7XG4gICAgICAgIHRoaXMucGFnaW5hdGlvbkluZGV4ID0gdmFsdWUucGFnZUN1cnJlbnQgLSAxO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIEBJbnB1dCgpXG4gIHNldCBzZWFyY2goc3RyaW5nOiBPYnNlcnZhYmxlPHN0cmluZyB8IG51bGw+IHwgc3RyaW5nIHwgbnVsbCkge1xuICAgIHRoaXMuX3NlYXJjaEJ5JC5uZXh0KHN0cmluZyk7XG4gIH1cblxuICBASW5wdXQoKVxuICBzZXQgY29uZmlnKGNvbmZpZzogT2JzZXJ2YWJsZTxUYWJsZUNvbmZpZzxhbnk+PiB8IFRhYmxlQ29uZmlnPGFueT4pIHtcbiAgICB0aGlzLl90YWJsZUNvbmZpZyQubmV4dChjb25maWcpO1xuICB9XG5cbiAgQElucHV0KClcbiAgc2V0IGRhdGEoZGF0YTogT2JzZXJ2YWJsZTxBcnJheTxUYWJsZVJvdz4+IHwgQXJyYXk8VGFibGVSb3c+KSB7XG4gICAgdGhpcy5fZGF0YSQubmV4dChkYXRhKTtcbiAgfVxuXG4gIEBJbnB1dCgpIHNldCBzb3J0T3JkZXIoc29ydENvbmZpZzogR3RTb3J0T3JkZXI8VGFibGVSb3c+IHwgYW55KSB7XG4gICAgaWYgKEpTT04uc3RyaW5naWZ5KHNvcnRDb25maWcpICE9PSBKU09OLnN0cmluZ2lmeSh0aGlzLl9zb3J0T3JkZXIkLnZhbHVlKSkge1xuICAgICAgdGhpcy5zb3J0T3JkZXJDaGFuZ2UuZW1pdChzb3J0Q29uZmlnKTtcbiAgICAgIHRoaXMuX3NvcnRPcmRlciQubmV4dChzb3J0Q29uZmlnKTtcbiAgICB9XG4gIH1cblxuICBAT3V0cHV0KCkgcm93Q2xpY2sgPSBuZXcgRXZlbnRFbWl0dGVyPEd0Um93Q2xpY2tFdmVudD4oKTtcbiAgQE91dHB1dCgpIHNvcnRPcmRlckNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8R3RTb3J0T3JkZXI8VGFibGVSb3c+PigpO1xuXG4gIF9yb3dDbGljayhyb3c6IFRhYmxlUm93LCBpbmRleDogbnVtYmVyLCBldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIHRoaXMucm93Q2xpY2suZW1pdCh7IHJvdywgaW5kZXgsIGV2ZW50IH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfcm93SG92ZXIkID0gbmV3IFJlcGxheVN1YmplY3Q8R3RSb3dIb3ZlckV2ZW50PigxKTtcbiAgQE91dHB1dCgpIHJvd0hvdmVyID0gbmV3IEV2ZW50RW1pdHRlcjxHdFJvd0hvdmVyRXZlbnQ+KCk7XG4gIEBPdXRwdXQoKSBjb2x1bW5Tb3J0ID0gbmV3IEV2ZW50RW1pdHRlcjxHdFNvcnRFdmVudD4oKTtcbiAgLyoqIHBhZ2UgY2hhbmdlIGV2ZW50IC0gZW1pdHRlZCB3aGVuIGN1cnJlbnQgcGFnZS9pbmRleCBjaGFuZ2VzIGZvciBwYWdpbmF0aW9uICovXG4gIEBPdXRwdXQoKSBwYWdlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxHdFBhZ2VDaGFuZ2VFdmVudD4oKTtcbiAgcm93SG92ZXIkID0gdGhpcy5fcm93SG92ZXIkLmFzT2JzZXJ2YWJsZSgpLnBpcGUoXG4gICAgZGVib3VuY2VUaW1lKDUwKSxcbiAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgocCwgcSkgPT4gcC5pbmRleCA9PT0gcS5pbmRleCksXG4gICAgdGFwKChldmVudCkgPT4gdGhpcy5yb3dIb3Zlci5lbWl0KGV2ZW50KSksXG4gICAgc2hhcmVSZXBsYXkoMSlcbiAgKTtcblxuICBob3ZlclJvdyhpZDogc3RyaW5nKTogdm9pZDtcbiAgaG92ZXJSb3coaW5kZXg6IG51bWJlcik6IHZvaWQ7XG4gIGhvdmVyUm93KG5vbmU6IG51bGwpOiB2b2lkO1xuICBob3ZlclJvdyhhcmc6IHN0cmluZyB8IG51bWJlciB8IG51bGwpOiB2b2lkIHtcbiAgICBpZiAodHlwZW9mIGFyZyA9PT0gJ251bWJlcicpIHtcbiAgICAgIHRoaXMuZGF0YSRcbiAgICAgICAgLnBpcGUoXG4gICAgICAgICAgbWFwKChkYXRhKSA9PiBkYXRhW2FyZ10pLFxuICAgICAgICAgIHRha2UoMSlcbiAgICAgICAgKVxuICAgICAgICAuc3Vic2NyaWJlKChyb3cpID0+IHRoaXMuX2hvdmVyUm93KHJvdywgYXJnKSk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgYXJnID09PSAnc3RyaW5nJykge1xuICAgICAgLy8gVE9ETzogaW1wbGVtZW50IGhvdmVyIGJ5IGlkXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2hvdmVyUm93KG51bGwsIG51bGwpO1xuICAgIH1cbiAgfVxuICBfaG92ZXJSb3coXG4gICAgcm93OiBUYWJsZVJvdyB8IG51bGwsXG4gICAgaW5kZXg6IG51bWJlciB8IG51bGwsXG4gICAgZXZlbnQ/OiBNb3VzZUV2ZW50XG4gICk6IHZvaWQge1xuICAgIHRoaXMuX3Jvd0hvdmVyJC5uZXh0KHsgcm93LCBpbmRleCwgZXZlbnQgfSk7XG4gIH1cblxuICBnZXQgbG9hZGluZyQoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIHRoaXMuX2xvYWRpbmckLnBpcGUoXG4gICAgICBzdGFydFdpdGgoZmFsc2UpLFxuICAgICAgbWFwKCh2YWx1ZSkgPT4gKGlzT2JzZXJ2YWJsZSh2YWx1ZSkgPyB2YWx1ZSA6IG9mKHZhbHVlKSkpLFxuICAgICAgc3dpdGNoTWFwKChvYnMpID0+IG9icyksXG4gICAgICBzaGFyZVJlcGxheSgxKVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIF9sb2FkaW5nJDogUmVwbGF5U3ViamVjdDxPYnNlcnZhYmxlPGJvb2xlYW4+IHwgYm9vbGVhbj4gPVxuICAgIG5ldyBSZXBsYXlTdWJqZWN0KDEpO1xuICBwcml2YXRlIF9zb3J0T3JkZXIkOiBCZWhhdmlvclN1YmplY3Q8R3RTb3J0T3JkZXI+ID1cbiAgICBuZXcgQmVoYXZpb3JTdWJqZWN0PEd0U29ydE9yZGVyPihbXSk7XG4gIHByaXZhdGUgX3NlYXJjaEJ5JDogUmVwbGF5U3ViamVjdDxPYnNlcnZhYmxlPHN0cmluZyB8IG51bGw+IHwgc3RyaW5nIHwgbnVsbD4gPVxuICAgIG5ldyBSZXBsYXlTdWJqZWN0KDEpO1xuICBzZWFyY2hCeSQ6IE9ic2VydmFibGU8c3RyaW5nIHwgbnVsbD4gPSB0aGlzLl9zZWFyY2hCeSQucGlwZShcbiAgICBzdGFydFdpdGgoJycpLFxuICAgIG1hcCgodmFsdWUpID0+IChpc09ic2VydmFibGUodmFsdWUpID8gdmFsdWUgOiBvZih2YWx1ZSkpKSxcbiAgICBzd2l0Y2hNYXAoKG9icykgPT4gb2JzKSxcbiAgICBzaGFyZVJlcGxheSgxKVxuICApO1xuXG4gIHByaXZhdGUgX3BhZ2luZ0luZm8kID0gbmV3IEJlaGF2aW9yU3ViamVjdDxHdFBhZ2luYXRpb25JbmZvPih7XG4gICAgcGFnZUN1cnJlbnQ6IG51bGwsXG4gICAgcGFnZU5leHQ6IG51bGwsXG4gICAgcGFnZVByZXZpb3VzOiBudWxsLFxuICAgIHBhZ2VTaXplOiBudWxsLFxuICAgIG51bWJlck9mUmVjb3JkczogbnVsbCxcbiAgICAvL3JlY29yZHNBZnRlckZpbHRlcjogbnVsbCxcbiAgICAvL3JlY29yZHNBZnRlclNlYXJjaDogbnVsbCxcbiAgICAvL3JlY29yZHNBbGw6IG51bGwsXG4gIH0pO1xuXG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTp2YXJpYWJsZS1uYW1lXG4gIHByaXZhdGUgX3RhYmxlQ29uZmlnJDogQmVoYXZpb3JTdWJqZWN0PFxuICAgIFRhYmxlQ29uZmlnPGFueT4gfCBPYnNlcnZhYmxlPFRhYmxlQ29uZmlnPGFueT4+XG4gID4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0KHt9KTtcbiAgdGFibGVDb25maWckID0gdGhpcy5fdGFibGVDb25maWckLnBpcGUoXG4gICAgbWFwKCh2YWx1ZSkgPT4gKGlzT2JzZXJ2YWJsZSh2YWx1ZSkgPyB2YWx1ZSA6IG9mKHZhbHVlKSkpLFxuICAgIHN3aXRjaE1hcCgob2JzKSA9PiBvYnMpLFxuICAgIHNoYXJlUmVwbGF5KDEpXG4gICk7XG5cbiAgcHJpdmF0ZSBfZGF0YSQ6IFJlcGxheVN1YmplY3Q8QXJyYXk8VGFibGVSb3c+IHwgT2JzZXJ2YWJsZTxBcnJheTxUYWJsZVJvdz4+PiA9XG4gICAgbmV3IFJlcGxheVN1YmplY3QoMSk7XG4gIGRhdGEkOiBPYnNlcnZhYmxlPEFycmF5PFRhYmxlUm93Pj4gPSB0aGlzLl9kYXRhJC5waXBlKFxuICAgIG1hcCgodmFsdWUpID0+IChpc09ic2VydmFibGUodmFsdWUpID8gdmFsdWUgOiBvZih2YWx1ZSkpKSxcbiAgICBzd2l0Y2hNYXAoKG9icykgPT4gY29tYmluZUxhdGVzdChbb2JzXSkpLFxuICAgIHdpdGhMYXRlc3RGcm9tKHRoaXMudGFibGVDb25maWckKSxcbiAgICBtYXAoKFtbZGF0YV0sIGNvbmZpZ10pID0+IHtcbiAgICAgIC8vIGlmIGNvbHVtbnMgb3Igcm93cyBjb250YWlucyBjb25maWcgZm9yIG1hcFRvLi4uXG4gICAgICBpZiAoXG4gICAgICAgIChjb25maWcuY29sdW1ucyAmJlxuICAgICAgICAgICEhT2JqZWN0LnZhbHVlcyhjb25maWcuY29sdW1ucykuZmluZCgoY29sdW1uKSA9PiAhIWNvbHVtbi5tYXBUbykpIHx8XG4gICAgICAgIChjb25maWcucm93cyAmJlxuICAgICAgICAgICEhT2JqZWN0LnZhbHVlcyhjb25maWcucm93cykuZmluZCgoY29sdW1uKSA9PiAhIWNvbHVtbi5tYXBUbykpXG4gICAgICApIHtcbiAgICAgICAgLy8gLi4ubWFwIGRhdGEgdG8gbmV3IGtleXMgb24gcm93Li4uXG4gICAgICAgIGNvbnN0IG5ld0RhdGE6IFRhYmxlUm93W10gPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgY29uc3Qgcm93ID0gZGF0YVtpXTtcbiAgICAgICAgICBjb25zdCBuZXdLZXlzID0gT2JqZWN0LmVudHJpZXMoY29uZmlnLmNvbHVtbnMgfHwgY29uZmlnLnJvd3MgfHwgW10pXG4gICAgICAgICAgICAuZmlsdGVyKChba2V5LCB2YWx1ZV0pID0+ICEhdmFsdWUubWFwVG8pIC8vIGFkZCBrZXlzIGZvciBjb2x1bW5zIHdpdGggbWFwVG8gY29uZmlnLi4uXG4gICAgICAgICAgICAucmVkdWNlKFxuICAgICAgICAgICAgICAocHJldmlvdXNWYWx1ZSwgW2tleSwgdmFsdWVdKSA9PiAoe1xuICAgICAgICAgICAgICAgIC4uLnByZXZpb3VzVmFsdWUsXG4gICAgICAgICAgICAgICAgW2tleV06IHRoaXMubmVzdGVkVmFsdWUoXG4gICAgICAgICAgICAgICAgICByb3csXG4gICAgICAgICAgICAgICAgICB2YWx1ZS5tYXBUbyEucGF0aCxcbiAgICAgICAgICAgICAgICAgIHZhbHVlLm1hcFRvPy5taXNzaW5nVmFsdWVcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAge31cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgbmV3RGF0YVtpXSA9IHsgLi4ucm93LCAuLi5uZXdLZXlzIH07XG4gICAgICAgIH1cbiAgICAgICAgZGF0YSA9IG5ld0RhdGE7XG4gICAgICB9XG4gICAgICByZXR1cm4geyBkYXRhLCBjb25maWcgfTtcbiAgICB9KSxcbiAgICBzd2l0Y2hNYXAoKG9icykgPT5cbiAgICAgIGNvbWJpbmVMYXRlc3QoW29mKG9icyksIHRoaXMuc29ydE9yZGVyJCwgdGhpcy5zZWFyY2hCeSRdKVxuICAgICksXG4gICAgbWFwKChbdGFibGUsIHNvcnRCeSwgc2VhcmNoQnldKSA9PiB7XG4gICAgICAvLyBjcmVhdGUgYSBuZXcgYXJyYXkgcmVmZXJlbmNlIGFuZCBzb3J0IG5ldyBhcnJheSAocHJldmVudCBtdXRhdGluZyBleGlzdGluZyBzdGF0ZSlcbiAgICAgIHRhYmxlLmRhdGEgPSBbLi4udGFibGUuZGF0YV07XG4gICAgICByZXR1cm4gIXNvcnRCeT8ubGVuZ3RoIHx8IHRhYmxlLmNvbmZpZz8uZGlzYWJsZVRhYmxlU29ydFxuICAgICAgICA/IHNlYXJjaEJ5ICYmICF0aGlzLnRhYmxlSW5mbz8ubGF6eUxvYWRlZFxuICAgICAgICAgID8gc2VhcmNoKHNlYXJjaEJ5LCBmYWxzZSwgdGFibGUuZGF0YSwgdGFibGUuY29uZmlnKVxuICAgICAgICAgIDogdGFibGUuZGF0YVxuICAgICAgICA6IHNlYXJjaEJ5ICYmICF0aGlzLnRhYmxlSW5mbz8ubGF6eUxvYWRlZFxuICAgICAgICA/IHNlYXJjaChzZWFyY2hCeSwgZmFsc2UsIHRhYmxlLmRhdGEsIHRhYmxlLmNvbmZpZyk/LnNvcnQoXG4gICAgICAgICAgICBzb3J0T25NdWx0aXBsZUtleXMoc29ydEJ5KVxuICAgICAgICAgIClcbiAgICAgICAgOiB0YWJsZS5kYXRhPy5zb3J0KHNvcnRPbk11bHRpcGxlS2V5cyhzb3J0QnkpKTtcbiAgICB9KSxcbiAgICBzaGFyZVJlcGxheSgxKVxuICApO1xuXG4gIGNhbGN1bGF0aW9ucyQgPSBjb21iaW5lTGF0ZXN0KFt0aGlzLmRhdGEkLCB0aGlzLnRhYmxlQ29uZmlnJF0pLnBpcGUoXG4gICAgbWFwKChbZGF0YSwgY29uZmlnXSkgPT4gY2FsY3VsYXRlKGRhdGEsIGNvbmZpZykpLFxuICAgIHNoYXJlUmVwbGF5KDEpXG4gICk7XG5cbiAgdGFibGUkOiBPYnNlcnZhYmxlPFRhYmxlTWV0YT4gPSBjb21iaW5lTGF0ZXN0KFtcbiAgICB0aGlzLmRhdGEkLFxuICAgIHRoaXMudGFibGVDb25maWckLFxuICAgIHRoaXMuX3BhZ2luZ0luZm8kLFxuICBdKS5waXBlKFxuICAgIG1hcCgoW3NvcnRlZCwgY29uZmlnLCBwYWdpbmdJbmZvXSkgPT4ge1xuICAgICAgaWYgKFxuICAgICAgICBwYWdpbmdJbmZvLnBhZ2VDdXJyZW50ICE9PSBudWxsICYmXG4gICAgICAgIHBhZ2luZ0luZm8ubnVtYmVyT2ZSZWNvcmRzICE9PSBudWxsICYmXG4gICAgICAgIHBhZ2luZ0luZm8ucGFnZVNpemUgIT09IG51bGxcbiAgICAgICkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGRhdGE6IFtzb3J0ZWRdLFxuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICBpbmZvOiA8VGFibGVJbmZvPntcbiAgICAgICAgICAgIGxhenlMb2FkZWQ6IHRydWUsXG4gICAgICAgICAgICBudW1iZXJPZlJlY29yZHM6IHBhZ2luZ0luZm8ubnVtYmVyT2ZSZWNvcmRzLFxuICAgICAgICAgICAgcGFnZVNpemU6IHBhZ2luZ0luZm8ucGFnZVNpemUsXG4gICAgICAgICAgICBwYWdlVG90YWw6XG4gICAgICAgICAgICAgIHBhZ2luZ0luZm8ucGFnZVRvdGFsID8/XG4gICAgICAgICAgICAgIE1hdGguY2VpbChwYWdpbmdJbmZvLm51bWJlck9mUmVjb3JkcyAvIHBhZ2luZ0luZm8ucGFnZVNpemUpLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICAvLyBpZiBwYWdpbmF0aW9uIGlzIGRpc2FibGVkLi4uXG4gICAgICBpZiAoIWNvbmZpZy5wYWdpbmF0aW9uIHx8IGNvbmZpZy5wYWdpbmF0aW9uLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAvLyAuLi5yZXR1cm4gdW5hbHRlcmVkIGFycmF5XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZGF0YTogW3NvcnRlZF0sXG4gICAgICAgICAgY29uZmlnLFxuICAgICAgICAgIGluZm86IDxUYWJsZUluZm8+eyBudW1iZXJPZlJlY29yZHM6IHNvcnRlZC5sZW5ndGgsIHBhZ2VUb3RhbDogMSB9LFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgLy8gcmV0dXJuIHJlY29yZCBzZXRcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGRhdGE6IGNodW5rKHNvcnRlZCwgKyhjb25maWcucGFnaW5hdGlvbi5sZW5ndGggfHwgMCkpLFxuICAgICAgICBjb25maWcsXG4gICAgICAgIGluZm86IDxUYWJsZUluZm8+e1xuICAgICAgICAgIG51bWJlck9mUmVjb3Jkczogc29ydGVkLmxlbmd0aCxcbiAgICAgICAgICBwYWdlVG90YWw6IE1hdGguY2VpbChcbiAgICAgICAgICAgIHNvcnRlZC5sZW5ndGggLyArKGNvbmZpZy5wYWdpbmF0aW9uLmxlbmd0aCB8fCAwKVxuICAgICAgICAgICksXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH0pLFxuICAgIHRhcCgobWV0YSkgPT4gdGhpcy5fdGFibGVJbmZvJC5uZXh0KG1ldGEuaW5mbykpLFxuICAgIHNoYXJlUmVwbGF5KDEpXG4gICk7XG5cbiAgLyoqIHRhYmxlSW5mbyQgLSByZXR1cm5zIG9ic2VydmFibGUgZm9yIHRhYmxlIGluZm9cbiAgICogQHJldHVybiBPYnNlcnZhYmxlPFRhYmxlSW5mbz4gKi9cbiAgZ2V0IHRhYmxlSW5mbyQoKTogT2JzZXJ2YWJsZTxUYWJsZUluZm8gfCB1bmRlZmluZWQ+IHtcbiAgICByZXR1cm4gdGhpcy5fdGFibGVJbmZvJC5hc09ic2VydmFibGUoKS5waXBlKFxuICAgICAgZmlsdGVyKChpbmZvKSA9PiAhIWluZm8pLFxuICAgICAgc2hhcmVSZXBsYXkoMSlcbiAgICApO1xuICB9XG5cbiAgLyoqIHRhYmxlSW5mbyAtIHJldHVybnMgdGhlIGN1cnJlbnQgdGFibGUgaW5mb1xuICAgKiBAcmV0dXJuIFRhYmxlSW5mbyAqL1xuICBnZXQgdGFibGVJbmZvKCk6IFRhYmxlSW5mbyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuX3RhYmxlSW5mbyQuZ2V0VmFsdWUoKTtcbiAgfVxuXG4gIHByaXZhdGUgX3RhYmxlSW5mbyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFRhYmxlSW5mbyB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcblxuICBwcml2YXRlIF9jdXJyZW50UGFnaW5hdGlvbkluZGV4JDogQmVoYXZpb3JTdWJqZWN0PG51bWJlcj4gPVxuICAgIG5ldyBCZWhhdmlvclN1YmplY3QoMCk7XG4gIGN1cnJlbnRQYWdpbmF0aW9uSW5kZXgkID0gY29tYmluZUxhdGVzdChbXG4gICAgdGhpcy5fY3VycmVudFBhZ2luYXRpb25JbmRleCQsXG4gICAgdGhpcy50YWJsZSQsXG4gIF0pLnBpcGUoXG4gICAgbWFwKChbcGFnZSwgdGFibGVdOiBhbnkpID0+IHtcbiAgICAgIC8vIGRldGVybWluZSBsYXN0IHBhZ2VcbiAgICAgIGNvbnN0IGxhc3RQYWdlID1cbiAgICAgICAgTWF0aC5jZWlsKFxuICAgICAgICAgIHRhYmxlLmluZm8ucmVjb3JkcyAvXG4gICAgICAgICAgICAodGFibGUuaW5mby5yZWNvcmRMZW5ndGggPz9cbiAgICAgICAgICAgICAgKHRhYmxlLmNvbmZpZz8ucGFnaW5hdGlvbj8ubGVuZ3RoIHx8IHRhYmxlLmluZm8ucmVjb3JkcykpXG4gICAgICAgICkgLSAxO1xuICAgICAgLy8gZGV0ZXJtaW5lIG1pbi9tYXggcG9zaXRpb25cbiAgICAgIHJldHVybiArcGFnZSA8IDAgPyAwIDogK3BhZ2UgPiBsYXN0UGFnZSA/IGxhc3RQYWdlIDogK3BhZ2U7XG4gICAgfSksXG4gICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcbiAgICB0YXAoKGluZGV4KSA9PiB0aGlzLnBhZ2VDaGFuZ2UuZW1pdCh7IGluZGV4IH0pKSxcbiAgICBzaGFyZVJlcGxheSgxKVxuICApO1xuXG4gIGNvbHNwYW4kID0gdGhpcy50YWJsZUNvbmZpZyQucGlwZShcbiAgICBzd2l0Y2hNYXAoKGNvbmZpZykgPT5cbiAgICAgIGNvbmZpZy5jb2x1bW5zXG4gICAgICAgID8gb2YoXG4gICAgICAgICAgICBPYmplY3QudmFsdWVzKGNvbmZpZy5jb2x1bW5zIHx8IGNvbmZpZy5yb3dzIHx8IHt9KS5maWx0ZXIoXG4gICAgICAgICAgICAgICh2YWx1ZSkgPT4gdmFsdWUuaGlkZGVuICE9PSB0cnVlXG4gICAgICAgICAgICApLmxlbmd0aFxuICAgICAgICAgIClcbiAgICAgICAgOiB0aGlzLmRhdGEkLnBpcGUobWFwKChkYXRhKSA9PiBkYXRhLmxlbmd0aCArIDEpKVxuICAgICksXG4gICAgc2hhcmVSZXBsYXkoMSlcbiAgKTtcblxuICBmb290ZXJDb2xzcGFuJCA9IHRoaXMudGFibGVDb25maWckLnBpcGUoXG4gICAgbWFwKChjb25maWcpID0+IHtcbiAgICAgIGxldCBjb2xzcGFuID0gMDtcbiAgICAgIE9iamVjdC52YWx1ZXMoY29uZmlnPy5mb290ZXI/LmNvbHVtbnMgfHwge30pLmZvckVhY2goKGNhbGN1bGF0aW9ucykgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgT2JqZWN0LnZhbHVlcyhjYWxjdWxhdGlvbnMpLmZpbHRlcigodmFsdWUpID0+IHZhbHVlICE9PSBmYWxzZSlcbiAgICAgICAgICAgIC5sZW5ndGggPj0gMFxuICAgICAgICApIHtcbiAgICAgICAgICBjb2xzcGFuICs9IDE7XG4gICAgICAgIH1cbiAgICAgIH0sIHt9KTtcbiAgICAgIHJldHVybiBjb2xzcGFuO1xuICAgIH0pLFxuICAgIHNoYXJlUmVwbGF5KDEpXG4gICk7XG5cbiAgLyoqIHNvcnRCeUtleSAtIFNvcnQgYnkga2V5IGluIHRhYmxlIHJvd1xuICAgKiBAcGFyYW0ga2V5IC0ga2V5IHRvIHNvcnQgYnlcbiAgICogQHBhcmFtIHsgTW91c2VFdmVudCB9IFskZXZlbnRdIC0gTW91c2UgZXZlbnQgdHJpZ2dlcmluZyBzb3J0LCBpZiBzaGlmdCBrZXkgaXMgcHJlc3NlZCBzb3J0IGtleSB3aWxsIGJlIGFkZGVkIHRvIGFscmVhZHkgcHJlc2VudCBzb3J0IGtleXNcbiAgICovXG4gIHNvcnRCeUtleShrZXk6IGtleW9mIFRhYmxlUm93LCAkZXZlbnQ/OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgY29uc3Qgc2hpZnRLZXkgPSAkZXZlbnQ/LnNoaWZ0S2V5ID09PSB0cnVlO1xuICAgIGNvbnN0IGN1cnJlbnRPcmRlciA9IHRoaXMuX3NvcnRPcmRlciQudmFsdWU7XG4gICAgbGV0IHNvcnRPcmRlcjogR3RPcmRlciA9ICdhc2MnO1xuICAgIGxldCBuZXdPcmRlcjogR3RTb3J0T3JkZXIgPSBbXTtcbiAgICAvLyBpZiBzaGlmdCBrZXkgaXMgcHJlc3NlZCB3aGlsZSBzb3J0aW5nLi4uXG4gICAgaWYgKHNoaWZ0S2V5KSB7XG4gICAgICAvLyAuLi5jaGVjayBpZiBrZXkgaXMgYWxyZWFkeSBzb3J0ZWRcbiAgICAgIGNvbnN0IGV4aXN0aW5nU29ydFBvc2l0aW9uID0gY3VycmVudE9yZGVyLmZpbmRJbmRleChcbiAgICAgICAgKHZhbHVlKSA9PiB2YWx1ZS5rZXkgPT09IGtleVxuICAgICAgKTtcbiAgICAgIGlmIChleGlzdGluZ1NvcnRQb3NpdGlvbiA9PT0gLTEpIHtcbiAgICAgICAgLy8gLi4uaWYga2V5IGlzIG5vdCBzb3J0ZWQsIGFkZCBpdCB0byB0aGUgZW5kIG9mIHRoZSBzb3J0IG9yZGVyXG4gICAgICAgIG5ld09yZGVyID0gWy4uLmN1cnJlbnRPcmRlciwgeyBrZXksIG9yZGVyOiAnYXNjJyB9XTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIC4uLmlmIGtleSBpcyBhbHJlYWR5IHNvcnRlZCwgdG9nZ2xlIHNvcnQgb3JkZXJcbiAgICAgICAgc29ydE9yZGVyID0gY3VycmVudE9yZGVyW2V4aXN0aW5nU29ydFBvc2l0aW9uXS5vcmRlcjtcbiAgICAgICAgY29uc3QgbmV3U29ydE9yZGVyID0gc29ydE9yZGVyID09PSAnYXNjJyA/ICdkZXNjJyA6ICdhc2MnO1xuICAgICAgICBuZXdPcmRlciA9IFsuLi5jdXJyZW50T3JkZXJdO1xuICAgICAgICBuZXdPcmRlcltleGlzdGluZ1NvcnRQb3NpdGlvbl0gPSB7XG4gICAgICAgICAgLi4ubmV3T3JkZXJbZXhpc3RpbmdTb3J0UG9zaXRpb25dLFxuICAgICAgICAgIG9yZGVyOiBuZXdTb3J0T3JkZXIsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIC4uLmVsc2UgaWYgc2hpZnQga2V5IGlzIG5vdCBwcmVzc2VkLi4uXG4gICAgICBpZiAoY3VycmVudE9yZGVyLmxlbmd0aCA+IDApIHtcbiAgICAgICAgLy8gLi4uY2hlY2sgaWYga2V5IGlzIGFscmVhZHkgc29ydGVkXG4gICAgICAgIGNvbnN0IGV4aXN0aW5nU29ydFBvc2l0aW9uID0gY3VycmVudE9yZGVyLmZpbmRJbmRleChcbiAgICAgICAgICAodmFsdWUpID0+IHZhbHVlLmtleSA9PT0ga2V5XG4gICAgICAgICk7XG4gICAgICAgIC8vIC4uLmlmIGtleSBpcyBhbHJlYWR5IHNvcnRlZCwgdG9nZ2xlIHNvcnQgb3JkZXJcbiAgICAgICAgaWYgKGV4aXN0aW5nU29ydFBvc2l0aW9uID09PSAtMSkge1xuICAgICAgICAgIG5ld09yZGVyID0gW3sga2V5LCBvcmRlcjogJ2FzYycgfV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc29ydE9yZGVyID0gY3VycmVudE9yZGVyW2V4aXN0aW5nU29ydFBvc2l0aW9uXS5vcmRlcjtcbiAgICAgICAgICBjb25zdCBuZXdTb3J0T3JkZXIgPSBzb3J0T3JkZXIgPT09ICdhc2MnID8gJ2Rlc2MnIDogJ2FzYyc7XG4gICAgICAgICAgbmV3T3JkZXIgPSBbeyBrZXksIG9yZGVyOiBuZXdTb3J0T3JkZXIgfV07XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIC4uLmlmIGtleSBpcyBub3Qgc29ydGVkIHNldCBzb3J0IG9yZGVyIGZvciBrZXkgdG8gYXNjZW5kaW5nXG4gICAgICAgIG5ld09yZGVyID0gW3sga2V5LCBvcmRlcjogc29ydE9yZGVyIH1dO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBjcmVhdGUgc29ydCBldmVudFxuICAgIGNvbnN0IHNvcnRFdmVudDogR3RTb3J0RXZlbnQgPSB7XG4gICAgICBrZXksXG4gICAgICBvcmRlcjogc29ydE9yZGVyLFxuICAgICAgY3VycmVudFNvcnRPcmRlcjogbmV3T3JkZXIsXG4gICAgICBhZGRTb3J0S2V5OiBzaGlmdEtleSxcbiAgICB9O1xuXG4gICAgLy8gaWYgZXZlbnQgaXMgcGFzc2VkIHRvIHNvcnQgZnVuY3Rpb24uLi5cbiAgICBpZiAoJGV2ZW50KSB7XG4gICAgICAvLyAuLi5lbWl0IGl0IGFzIHdlbGxcbiAgICAgIHNvcnRFdmVudC5ldmVudCA9ICRldmVudDtcbiAgICB9XG4gICAgLy8gZW1pdCBzb3J0IGV2ZW50XG4gICAgdGhpcy5jb2x1bW5Tb3J0LmVtaXQoc29ydEV2ZW50KTtcblxuICAgIC8vIGlmIHRhYmxlIGlzIG5vdCBsYXp5IGxvYWRlZCAoc29ydGluZyBpcyB0aGVuIGhhbmRsZWQgc2VydmVyLXNpZGUpLi4uXG4gICAgaWYgKCF0aGlzLnRhYmxlSW5mbz8ubGF6eUxvYWRlZCkge1xuICAgICAgLy8gLi4udXBkYXRlIHNvcnQgb3JkZXJcbiAgICAgIHRoaXMuc29ydE9yZGVyID0gbmV3T3JkZXI7XG4gICAgfVxuICB9XG5cbiAgY29sdW1uT3JkZXIgPSAoXG4gICAgYTogS2V5VmFsdWU8c3RyaW5nLCBUYWJsZUNvbHVtbj4sXG4gICAgYjogS2V5VmFsdWU8c3RyaW5nLCBUYWJsZUNvbHVtbj5cbiAgKTogbnVtYmVyID0+IHtcbiAgICByZXR1cm4gKGEudmFsdWUub3JkZXIgfHwgMCkgLSAoYi52YWx1ZS5vcmRlciB8fCAwKTtcbiAgfTtcblxuICBuZXN0ZWRWYWx1ZShcbiAgICBvYmplY3Q6IGFueSxcbiAgICBtYXBUbzogc3RyaW5nLFxuICAgIG1pc3NpbmdWYWx1ZTogc3RyaW5nIHwgbnVtYmVyIHwgbnVsbCA9IG51bGxcbiAgKTogdW5rbm93biB7XG4gICAgY29uc3QgbGV2ZWxzID0gbWFwVG8uc3BsaXQoJy4nKTtcbiAgICByZXR1cm4gbGV2ZWxzLnJlZHVjZShcbiAgICAgIChwcmV2aW91c1ZhbHVlLCBjdXJyZW50VmFsdWUsIGluZGV4KSA9PlxuICAgICAgICBwcmV2aW91c1ZhbHVlW2N1cnJlbnRWYWx1ZV0gfHxcbiAgICAgICAgKGluZGV4ID09PSBsZXZlbHMubGVuZ3RoIC0gMSA/IG1pc3NpbmdWYWx1ZSA6IHt9KSxcbiAgICAgIG9iamVjdFxuICAgICk7XG4gIH1cbn1cbiIsIjx0YWJsZVxuICBbbmdDbGFzc109XCIodGFibGVDb25maWckIHwgYXN5bmMpPy5jbGFzcyB8fCAndGFibGUnXCJcbiAgW2NsYXNzLnRhYmxlLW1vYmlsZV09XCIodGFibGVDb25maWckIHwgYXN5bmMpPy5tb2JpbGVMYXlvdXRcIlxuICBbY2xhc3MudGFibGUtaG9yaXpvbnRhbF09XCIodGFibGVDb25maWckIHwgYXN5bmMpPy5yb3dzXCJcbiAgW2NsYXNzLnRhYmxlLWxvYWRpbmddPVwibG9hZGluZyQgfCBhc3luY1wiXG4gIFtjbGFzcy5ndC1zdGlja3ktcm93LWhlYWRlcl09XCJcbiAgICAodGFibGVDb25maWckIHwgYXN5bmMpPy5zdGlja3lIZWFkZXJzPy5yb3cgJiYgKHRhYmxlQ29uZmlnJCB8IGFzeW5jKT8ucm93c1xuICBcIlxuICBbY2xhc3MuZ3Qtc3RpY2t5LWNvbHVtbi1oZWFkZXJdPVwiXG4gICAgKHRhYmxlQ29uZmlnJCB8IGFzeW5jKT8uc3RpY2t5SGVhZGVycz8uY29sdW1uXG4gIFwiXG4gIFthdHRyLmFyaWEtYnVzeV09XCIobG9hZGluZyQgfCBhc3luYykgPT09IHRydWUgPyB0cnVlIDogbnVsbFwiXG4+XG4gIDx0aGVhZD5cbiAgICA8dHJcbiAgICAgICpuZ0lmPVwie1xuICAgICAgICBjb25maWc6ICh0YWJsZUNvbmZpZyQgfCBhc3luYykhLFxuICAgICAgICBpc0xvYWRpbmc6IGxvYWRpbmckIHwgYXN5bmNcbiAgICAgIH0gYXMgdGFibGVcIlxuICAgID5cbiAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgKm5nRm9yPVwibGV0IGNvbHVtbiBvZiB0YWJsZS5jb25maWc/LmNvbHVtbnMgfCBrZXl2YWx1ZTogY29sdW1uT3JkZXJcIlxuICAgICAgPlxuICAgICAgICA8dGhcbiAgICAgICAgICAqbmdJZj1cIiFjb2x1bW4udmFsdWU/LmhpZGRlblwiXG4gICAgICAgICAgbmdDbGFzcz1cInt7IChjb2x1bW4ua2V5IHwgZGFzaENhc2UpICsgJy1jb2x1bW4nIH19IHt7XG4gICAgICAgICAgICBjb2x1bW4udmFsdWUuY2xhc3NcbiAgICAgICAgICB9fVwiXG4gICAgICAgICAgW2NsYXNzLmRpc2FibGVkXT1cInRhYmxlLmlzTG9hZGluZ1wiXG4gICAgICAgICAgW2F0dHIuYXJpYS1zb3J0XT1cInNvcnRPcmRlciQgfCBhc3luYyB8IHNvcnRDbGFzczogY29sdW1uLmtleTonYXJpYSdcIlxuICAgICAgICAgIFtjbGFzcy5ndC1zb3J0YWJsZV09XCJ0cnVlXCJcbiAgICAgICAgICBzY29wZT1cImNvbFwiXG4gICAgICAgID5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAqbmdJZj1cImNvbHVtbi52YWx1ZT8uc29ydGFibGVcIlxuICAgICAgICAgICAgW2F0dHIuZGF0YS1zb3J0LW9yZGVyXT1cIlxuICAgICAgICAgICAgICBzb3J0T3JkZXIkIHwgYXN5bmMgfCBzb3J0Q2xhc3M6IGNvbHVtbi5rZXk6J29yZGVyJ1xuICAgICAgICAgICAgXCJcbiAgICAgICAgICAgIGNsYXNzPVwiZ3Qtc29ydFwiXG4gICAgICAgICAgICAoY2xpY2spPVwiXG4gICAgICAgICAgICAgIHRhYmxlLmlzTG9hZGluZyB8fFxuICAgICAgICAgICAgICAgICFjb2x1bW4udmFsdWUuc29ydGFibGUgfHxcbiAgICAgICAgICAgICAgICBzb3J0QnlLZXkoY29sdW1uLmtleSwgJGV2ZW50KVxuICAgICAgICAgICAgXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8c3BhbiAqbmdJZj1cImNvbHVtbi52YWx1ZT8uaGVhZGVyICE9PSBmYWxzZVwiPnt7XG4gICAgICAgICAgICAgIGNvbHVtbi52YWx1ZS5oZWFkZXIgfHwgY29sdW1uLmtleSB8IGNhcGl0YWxDYXNlXG4gICAgICAgICAgICB9fTwvc3Bhbj5cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgKm5nSWY9XCIhY29sdW1uLnZhbHVlPy5zb3J0YWJsZSAmJiBjb2x1bW4udmFsdWU/LmhlYWRlciAhPT0gZmFsc2VcIlxuICAgICAgICAgICAgPnt7IGNvbHVtbi52YWx1ZS5oZWFkZXIgfHwgY29sdW1uLmtleSB8IGNhcGl0YWxDYXNlIH19PC9zcGFuXG4gICAgICAgICAgPlxuICAgICAgICA8L3RoPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICpuZ0lmPVwiXG4gICAgICAgICAgKCh0YWJsZT8uY29uZmlnPy5yb3dzIHwga2V5dmFsdWU6IGNvbHVtbk9yZGVyKSB8fCBbXSlbMF0gYXMgaGVhZGVyUm93XG4gICAgICAgIFwiXG4gICAgICA+XG4gICAgICAgIDx0aFxuICAgICAgICAgIGNsYXNzPVwicm93LWhlYWRlclwiXG4gICAgICAgICAgW2F0dHIuYXJpYS1zb3J0XT1cIlxuICAgICAgICAgICAgc29ydE9yZGVyJCB8IGFzeW5jIHwgc29ydENsYXNzOiBoZWFkZXJSb3cua2V5OidhcmlhJ1xuICAgICAgICAgIFwiXG4gICAgICAgICAgbmdDbGFzcz1cInt7IGhlYWRlclJvdy52YWx1ZS5zb3J0YWJsZSA/ICdzb3J0ICcgOiAnJyB9fSB7e1xuICAgICAgICAgICAgc29ydE9yZGVyJCB8IGFzeW5jIHwgc29ydENsYXNzOiBoZWFkZXJSb3cua2V5XG4gICAgICAgICAgfX0ge3sgKGhlYWRlclJvdy5rZXkgfCBkYXNoQ2FzZSkgKyAnLWNvbHVtbicgfX1cIlxuICAgICAgICAgIChjbGljayk9XCJcbiAgICAgICAgICAgIHRhYmxlLmlzTG9hZGluZyB8fFxuICAgICAgICAgICAgICAhaGVhZGVyUm93LnZhbHVlLnNvcnRhYmxlIHx8XG4gICAgICAgICAgICAgIHNvcnRCeUtleShoZWFkZXJSb3cua2V5LCAkZXZlbnQpXG4gICAgICAgICAgXCJcbiAgICAgICAgICBzY29wZT1cImNvbFwiXG4gICAgICAgID5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaGVhZGVyUm93Py52YWx1ZT8uaGVhZGVyICE9PSBmYWxzZVwiPnt7XG4gICAgICAgICAgICBoZWFkZXJSb3c/LnZhbHVlPy5oZWFkZXIgfHwgaGVhZGVyUm93LmtleSB8IGNhcGl0YWxDYXNlXG4gICAgICAgICAgfX08L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC90aD5cbiAgICAgICAgPHRoXG4gICAgICAgICAgKm5nRm9yPVwibGV0IGNvbHVtbiBvZiAoKHRhYmxlJCB8IGFzeW5jKT8uZGF0YSB8fCBbXSlbMF1cIlxuICAgICAgICAgIG5nQ2xhc3M9XCJ7eyBoZWFkZXJSb3cudmFsdWUuY2xhc3MgfX1cIlxuICAgICAgICA+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwiXG4gICAgICAgICAgICAgICh0YWJsZS5jb25maWcucm93cyB8fCB7fSlbaGVhZGVyUm93LmtleV0udGVtcGxhdGVSZWZcbiAgICAgICAgICAgICAgICA/IHRlbXBsYXRlUmVmXG4gICAgICAgICAgICAgICAgOiAodGFibGUuY29uZmlnLnJvd3MgfHwge30pW2hlYWRlclJvdy5rZXldLnRyYW5zZm9ybVxuICAgICAgICAgICAgICAgID8gdHJhbnNmb3JtRGF0YVxuICAgICAgICAgICAgICAgIDogcmF3RGF0YVxuICAgICAgICAgICAgXCJcbiAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7XG4gICAgICAgICAgICAgIHJvdzogY29sdW1uLFxuICAgICAgICAgICAgICBjb2x1bW46IGhlYWRlclJvdyxcbiAgICAgICAgICAgICAgdHJhbnNmb3JtOiAodGFibGUuY29uZmlnLnJvd3MgfHwge30pW2hlYWRlclJvdy5rZXldLnRyYW5zZm9ybSxcbiAgICAgICAgICAgICAgdGVtcGxhdGVSZWY6ICh0YWJsZS5jb25maWcucm93cyB8fCB7fSlbaGVhZGVyUm93LmtleV0udGVtcGxhdGVSZWYsXG4gICAgICAgICAgICAgIGluZGV4OiAwXG4gICAgICAgICAgICB9XCJcbiAgICAgICAgICA+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvdGg+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8L3RyPlxuICA8L3RoZWFkPlxuICA8dGJvZHkgKm5nSWY9XCJsb2FkaW5nJCB8IGFzeW5jOyBlbHNlIHRhYmxlQ29udGVudFwiPlxuICAgIDx0cj5cbiAgICAgIDx0ZCBjbGFzcz1cInAtMFwiIFtjb2xTcGFuXT1cImNvbHNwYW4kIHwgYXN5bmNcIj5cbiAgICAgICAgPG5nLWNvbnRlbnQgc2VsZWN0PVwiLnRhYmxlLWxvYWRpbmdcIj48L25nLWNvbnRlbnQ+XG4gICAgICA8L3RkPlxuICAgIDwvdHI+XG4gIDwvdGJvZHk+XG4gIDx0Zm9vdCAqbmdJZj1cIih0YWJsZSQgfCBhc3luYykhIGFzIHRhYmxlXCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInRhYmxlLmRhdGEubGVuZ3RoID4gMCAmJiAhKGxvYWRpbmckIHwgYXN5bmMpXCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiKGNhbGN1bGF0aW9ucyQgfCBhc3luYykhIGFzIGNhbGN1bGF0aW9uc1wiPlxuICAgICAgICA8dHJcbiAgICAgICAgICAqbmdGb3I9XCJsZXQgY2FsY3VsYXRpb24gb2YgY2FsY3VsYXRpb25zLmNhbGN1bGF0aW9uczsgbGV0IGkgPSBpbmRleFwiXG4gICAgICAgID5cbiAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAqbmdJZj1cIntcbiAgICAgICAgICAgICAgc2hvd0hlYWRlcjogKGNvbHNwYW4kIHwgYXN5bmMpICE9PSAoZm9vdGVyQ29sc3BhbiQgfCBhc3luYylcbiAgICAgICAgICAgIH0gYXMgZm9vdGVyUm93XCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8dGhcbiAgICAgICAgICAgICAgKm5nSWY9XCJmb290ZXJSb3cuc2hvd0hlYWRlclwiXG4gICAgICAgICAgICAgIFtjb2xTcGFuXT1cIlxuICAgICAgICAgICAgICAgICgoY29sc3BhbiQgfCBhc3luYykgfHwgMCkgLSAoKGZvb3RlckNvbHNwYW4kIHwgYXN5bmMpIHx8IDApXG4gICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgIHNjb3BlPVwicm93XCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICpuZ0lmPVwidGFibGUuY29uZmlnPy5mb290ZXI/LmhlYWRlcnM/LltjYWxjdWxhdGlvbl0gYXMgc2hvd0hlYWRlclwiXG4gICAgICAgICAgICAgICAgPnt7c2hvd0hlYWRlciA9PT0gdHJ1ZSA/IChjYWxjdWxhdGlvbiB8IGNhcGl0YWxDYXNlKTogdGFibGUuY29uZmlnLmZvb3Rlcj8uaGVhZGVycz8uW2NhbGN1bGF0aW9uXX19XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgKm5nRm9yPVwiXG4gICAgICAgICAgICAgICAgbGV0IGNvbHVtbiBvZiB0YWJsZS5jb25maWc/LmNvbHVtbnMgfCBrZXl2YWx1ZTogY29sdW1uT3JkZXJcbiAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPHRkXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJcbiAgICAgICAgICAgICAgICAgICFjb2x1bW4udmFsdWU/LmhpZGRlbiAmJiBjYWxjdWxhdGlvbnMuY2FsY3VsYXRlZFtjb2x1bW4ua2V5XVxuICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgbmdDbGFzcz1cInt7IChjb2x1bW4ua2V5IHwgZGFzaENhc2UpICsgJy1jb2x1bW4nIH19IHt7XG4gICAgICAgICAgICAgICAgICBjb2x1bW4udmFsdWUuY2xhc3NcbiAgICAgICAgICAgICAgICB9fVwiXG4gICAgICAgICAgICAgICAgW2F0dHIuZGF0YS1oZWFkZXJdPVwiXG4gICAgICAgICAgICAgICAgICAhZm9vdGVyUm93LnNob3dIZWFkZXIgJiYgdGFibGUuY29uZmlnLmZvb3Rlcj8uaGVhZGVycz8uW2NhbGN1bGF0aW9uXVxuICAgICAgICAgICAgICAgICAgICA/IHRhYmxlLmNvbmZpZy5mb290ZXI/LmhlYWRlcnM/LltjYWxjdWxhdGlvbl0gPT09IHRydWUgPyAoY2FsY3VsYXRpb24gfCBjYXBpdGFsQ2FzZSkgOiB0YWJsZS5jb25maWcuZm9vdGVyPy5oZWFkZXJzPy5bY2FsY3VsYXRpb25dXG4gICAgICAgICAgICAgICAgICAgIDogbnVsbFxuICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgW2F0dHIuZGF0YS1sYWJlbF09XCJcbiAgICAgICAgICAgICAgICAgIHRhYmxlLmNvbmZpZy5tb2JpbGVMYXlvdXQgJiYgY29sdW1uLnZhbHVlLm1vYmlsZUhlYWRlclxuICAgICAgICAgICAgICAgICAgICA/IGNvbHVtbi52YWx1ZS5tb2JpbGVIZWFkZXIgIT09IHRydWVcbiAgICAgICAgICAgICAgICAgICAgICA/IGNvbHVtbi52YWx1ZS5tb2JpbGVIZWFkZXJcbiAgICAgICAgICAgICAgICAgICAgICA6IChjb2x1bW4udmFsdWUuaGVhZGVyIHx8IGNvbHVtbi5rZXkgfCBjYXBpdGFsQ2FzZSlcbiAgICAgICAgICAgICAgICAgICAgOiBudWxsXG4gICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICBbY2xhc3MuZ3Qtbm8tY29udGVudF09XCJcbiAgICAgICAgICAgICAgICAgICFjYWxjdWxhdGlvbnMuY2FsY3VsYXRlZFtjb2x1bW4ua2V5XVtjYWxjdWxhdGlvbl1cbiAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwiXG4gICAgICAgICAgICAgICAgICAgICh0YWJsZS5jb25maWcuY29sdW1ucyB8fCB7fSlbY29sdW1uLmtleV0udGVtcGxhdGVSZWZcbiAgICAgICAgICAgICAgICAgICAgICA/IHRlbXBsYXRlUmVmXG4gICAgICAgICAgICAgICAgICAgICAgOiAodGFibGUuY29uZmlnLmNvbHVtbnMgfHwge30pW2NvbHVtbi5rZXldLnRyYW5zZm9ybVxuICAgICAgICAgICAgICAgICAgICAgID8gdHJhbnNmb3JtRm9vdGVyXG4gICAgICAgICAgICAgICAgICAgICAgOiByYXdGb290ZXJcbiAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwie1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogY2FsY3VsYXRpb25zLmNhbGN1bGF0ZWRbY29sdW1uLmtleV1bY2FsY3VsYXRpb25dLFxuICAgICAgICAgICAgICAgICAgICByb3c6IGNhbGN1bGF0aW9ucy5jYWxjdWxhdGVkW2NvbHVtbi5rZXldLFxuICAgICAgICAgICAgICAgICAgICBjb2x1bW46IGNhbGN1bGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZVJlZjogKHRhYmxlLmNvbmZpZy5jb2x1bW5zIHx8IHt9KVtjb2x1bW4ua2V5XVxuICAgICAgICAgICAgICAgICAgICAgIC50ZW1wbGF0ZVJlZixcbiAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtOiAodGFibGUuY29uZmlnLmNvbHVtbnMgfHwge30pW2NvbHVtbi5rZXldXG4gICAgICAgICAgICAgICAgICAgICAgLnRyYW5zZm9ybVxuICAgICAgICAgICAgICAgICAgfVwiXG4gICAgICAgICAgICAgICAgPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvdHI+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC90Zm9vdD5cbjwvdGFibGU+XG48bmctdGVtcGxhdGUgI3RhYmxlQ29udGVudD5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIih0YWJsZSQgfCBhc3luYykhIGFzIHRhYmxlXCI+XG4gICAgPHRib2R5ICpuZ0lmPVwiKHRhYmxlIS5kYXRhIVswXSB8fCB0YWJsZSEuZGF0YSEpLmxlbmd0aCA+IDA7IGVsc2Ugbm9EYXRhXCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwidGFibGUuY29uZmlnLmNvbHVtbnNcIj5cbiAgICAgICAgPHRyXG4gICAgICAgICAgKm5nRm9yPVwiXG4gICAgICAgICAgICBsZXQgcm93IG9mIHRhYmxlIS5kYXRhIVtcbiAgICAgICAgICAgICAgdGFibGUuaW5mby5sYXp5TG9hZGVkID8gMCA6IChjdXJyZW50UGFnaW5hdGlvbkluZGV4JCB8IGFzeW5jKSB8fCAwXG4gICAgICAgICAgICBdO1xuICAgICAgICAgICAgbGV0IGkgPSBpbmRleFxuICAgICAgICAgIFwiXG4gICAgICAgICAgW2F0dHIuaWRdPVwiJ3RhYmxlUm93XycgKyBpXCJcbiAgICAgICAgICAoY2xpY2spPVwidGFibGU/LmNvbmZpZz8ucm93Q2xpY2sgJiYgX3Jvd0NsaWNrKHJvdywgaSwgJGV2ZW50KVwiXG4gICAgICAgICAgKG1vdXNlb3Zlcik9XCJ0YWJsZT8uY29uZmlnPy5yb3dIb3ZlciAmJiBfaG92ZXJSb3cocm93LCBpLCAkZXZlbnQpXCJcbiAgICAgICAgICAobW91c2VvdXQpPVwidGFibGU/LmNvbmZpZz8ucm93SG92ZXIgJiYgX2hvdmVyUm93KG51bGwsIG51bGwsICRldmVudClcIlxuICAgICAgICAgIFtjbGFzcy5ndC1ob3Zlcl09XCIocm93SG92ZXIkIHwgYXN5bmMpPy5pbmRleCA9PT0gaVwiXG4gICAgICAgID5cbiAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIHRhYmxlLmNvbmZpZz8uY29sdW1ucyB8IGtleXZhbHVlOiBjb2x1bW5PcmRlclwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHRkXG4gICAgICAgICAgICAgICpuZ0lmPVwiIWNvbHVtbi52YWx1ZT8uaGlkZGVuXCJcbiAgICAgICAgICAgICAgbmdDbGFzcz1cInt7IChjb2x1bW4ua2V5IHwgZGFzaENhc2UpICsgJy1jb2x1bW4nIH19IHt7XG4gICAgICAgICAgICAgICAgY29sdW1uLnZhbHVlLmNsYXNzXG4gICAgICAgICAgICAgIH19XCJcbiAgICAgICAgICAgICAgW2F0dHIuZGF0YS1sYWJlbF09XCJcbiAgICAgICAgICAgICAgICB0YWJsZS5jb25maWcubW9iaWxlTGF5b3V0ICYmIGNvbHVtbi52YWx1ZS5tb2JpbGVIZWFkZXJcbiAgICAgICAgICAgICAgICAgID8gY29sdW1uLnZhbHVlLm1vYmlsZUhlYWRlciAhPT0gdHJ1ZVxuICAgICAgICAgICAgICAgICAgICA/IGNvbHVtbi52YWx1ZS5tb2JpbGVIZWFkZXJcbiAgICAgICAgICAgICAgICAgICAgOiAoY29sdW1uLnZhbHVlLmhlYWRlciB8fCBjb2x1bW4ua2V5IHwgY2FwaXRhbENhc2UpXG4gICAgICAgICAgICAgICAgICA6IG51bGxcbiAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cIlxuICAgICAgICAgICAgICAgICAgKHNlYXJjaEJ5JCB8IGFzeW5jKSAmJlxuICAgICAgICAgICAgICAgICAgISh0YWJsZS5jb25maWcuY29sdW1ucyB8fCB7fSlbY29sdW1uLmtleV0udGVtcGxhdGVSZWZcbiAgICAgICAgICAgICAgICAgICAgPyBoaWdobGlnaHRlZFxuICAgICAgICAgICAgICAgICAgICA6ICh0YWJsZS5jb25maWcuY29sdW1ucyB8fCB7fSlbY29sdW1uLmtleV0udGVtcGxhdGVSZWZcbiAgICAgICAgICAgICAgICAgICAgPyB0ZW1wbGF0ZVJlZlxuICAgICAgICAgICAgICAgICAgICA6ICh0YWJsZS5jb25maWcuY29sdW1ucyB8fCB7fSlbY29sdW1uLmtleV0udHJhbnNmb3JtXG4gICAgICAgICAgICAgICAgICAgID8gdHJhbnNmb3JtRGF0YVxuICAgICAgICAgICAgICAgICAgICA6IHJhd0RhdGFcbiAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7XG4gICAgICAgICAgICAgICAgICByb3c6IHJvdyxcbiAgICAgICAgICAgICAgICAgIGNvbHVtbjogY29sdW1uLFxuICAgICAgICAgICAgICAgICAgc2VhcmNoOiAoc2VhcmNoQnkkIHwgYXN5bmMpLFxuICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtOiAodGFibGUuY29uZmlnLmNvbHVtbnMgfHwge30pW2NvbHVtbi5rZXldLnRyYW5zZm9ybSxcbiAgICAgICAgICAgICAgICAgIHRlbXBsYXRlUmVmOiAodGFibGUuY29uZmlnLmNvbHVtbnMgfHwge30pW2NvbHVtbi5rZXldXG4gICAgICAgICAgICAgICAgICAgIC50ZW1wbGF0ZVJlZixcbiAgICAgICAgICAgICAgICAgIGluZGV4OiBpLFxuICAgICAgICAgICAgICAgICAgZGF0YTogdGFibGUuZGF0YVtcbiAgICAgICAgICAgICAgICAgICAgdGFibGUuaW5mby5sYXp5TG9hZGVkXG4gICAgICAgICAgICAgICAgICAgICAgPyAwXG4gICAgICAgICAgICAgICAgICAgICAgOiAoY3VycmVudFBhZ2luYXRpb25JbmRleCQgfCBhc3luYykgfHwgMFxuICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgIH1cIlxuICAgICAgICAgICAgICA+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L3RyPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwidGFibGUuY29uZmlnLnJvd3NcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICpuZ0Zvcj1cIlxuICAgICAgICAgICAgbGV0IHJvdyBvZiB0YWJsZT8uY29uZmlnPy5yb3dzIHwga2V5dmFsdWU6IGNvbHVtbk9yZGVyIHwgc2xpY2U6IDE7XG4gICAgICAgICAgICBsZXQgaSA9IGluZGV4XG4gICAgICAgICAgXCJcbiAgICAgICAgPlxuICAgICAgICAgIDx0clxuICAgICAgICAgICAgKm5nSWY9XCIhcm93LnZhbHVlPy5oaWRkZW5cIlxuICAgICAgICAgICAgW2F0dHIuaWRdPVwiJ3RhYmxlUm93XycgKyBpXCJcbiAgICAgICAgICAgIG5nQ2xhc3M9XCJ7eyAocm93LmtleSB8IGRhc2hDYXNlKSArICctcm93JyB9fVwiXG4gICAgICAgICAgICAoY2xpY2spPVwidGFibGU/LmNvbmZpZz8ucm93Q2xpY2sgJiYgX3Jvd0NsaWNrKHJvdywgaSwgJGV2ZW50KVwiXG4gICAgICAgICAgICAobW91c2VvdmVyKT1cInRhYmxlPy5jb25maWc/LnJvd0hvdmVyICYmIF9ob3ZlclJvdyhyb3csIGksICRldmVudClcIlxuICAgICAgICAgICAgKG1vdXNlb3V0KT1cIlxuICAgICAgICAgICAgICB0YWJsZT8uY29uZmlnPy5yb3dIb3ZlciAmJiBfaG92ZXJSb3cobnVsbCwgbnVsbCwgJGV2ZW50KVxuICAgICAgICAgICAgXCJcbiAgICAgICAgICAgIFtjbGFzcy5ndC1ob3Zlcl09XCIocm93SG92ZXIkIHwgYXN5bmMpPy5pbmRleCA9PT0gaVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHRoIGNsYXNzPVwicm93LWhlYWRlclwiIHNjb3BlPVwicm93XCI+XG4gICAgICAgICAgICAgIHt7IHJvdy52YWx1ZS5oZWFkZXIgfHwgcm93LmtleSB8IGNhcGl0YWxDYXNlIH19XG4gICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgPHRkXG4gICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgKHRhYmxlPy5kYXRhIHx8IFtdKVswXTsgbGV0IHkgPSBpbmRleFwiXG4gICAgICAgICAgICAgIG5nQ2xhc3M9XCJ7eyByb3cudmFsdWUuY2xhc3MgfX1cIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwiXG4gICAgICAgICAgICAgICAgICAodGFibGUuY29uZmlnLnJvd3MgfHwge30pW3Jvdy5rZXldLnRlbXBsYXRlUmVmXG4gICAgICAgICAgICAgICAgICAgID8gdGVtcGxhdGVSZWZcbiAgICAgICAgICAgICAgICAgICAgOiAodGFibGUuY29uZmlnLnJvd3MgfHwge30pW3Jvdy5rZXldLnRyYW5zZm9ybVxuICAgICAgICAgICAgICAgICAgICA/IHRyYW5zZm9ybURhdGFcbiAgICAgICAgICAgICAgICAgICAgOiByYXdEYXRhXG4gICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwie1xuICAgICAgICAgICAgICAgICAgcm93OiBjb2x1bW4sXG4gICAgICAgICAgICAgICAgICBjb2x1bW46IHJvdyxcbiAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybTogKHRhYmxlLmNvbmZpZy5yb3dzIHx8IHt9KVtyb3cua2V5XS50cmFuc2Zvcm0sXG4gICAgICAgICAgICAgICAgICB0ZW1wbGF0ZVJlZjogKHRhYmxlLmNvbmZpZy5yb3dzIHx8IHt9KVtyb3cua2V5XS50ZW1wbGF0ZVJlZixcbiAgICAgICAgICAgICAgICAgIGluZGV4OiB0YWJsZS5jb25maWcucm93cyA/IHkgOiBpLFxuICAgICAgICAgICAgICAgICAgZGF0YTogdGFibGUuZGF0YVtcbiAgICAgICAgICAgICAgICAgICAgdGFibGUuaW5mby5sYXp5TG9hZGVkXG4gICAgICAgICAgICAgICAgICAgICAgPyAwXG4gICAgICAgICAgICAgICAgICAgICAgOiAoY3VycmVudFBhZ2luYXRpb25JbmRleCQgfCBhc3luYykgfHwgMFxuICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgIH1cIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICA8L3RyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvdGJvZHk+XG4gIDwvbmctY29udGFpbmVyPlxuPC9uZy10ZW1wbGF0ZT5cbjxuZy10ZW1wbGF0ZSAjbm9EYXRhPlxuICA8dGJvZHk+XG4gICAgPHRyPlxuICAgICAgPHRkIGNsYXNzPVwicC0wXCIgW2NvbFNwYW5dPVwiY29sc3BhbiQgfCBhc3luY1wiPlxuICAgICAgICA8bmctY29udGVudCBzZWxlY3Q9XCIudGFibGUtbm8tZGF0YVwiPjwvbmctY29udGVudD5cbiAgICAgIDwvdGQ+XG4gICAgPC90cj5cbiAgPC90Ym9keT5cbjwvbmctdGVtcGxhdGU+XG48bmctdGVtcGxhdGVcbiAgI2hpZ2hsaWdodGVkXG4gIGxldC1yb3c9XCJyb3dcIlxuICBsZXQtY29sdW1uPVwiY29sdW1uXCJcbiAgbGV0LXNlYXJjaD1cInNlYXJjaFwiXG4gIGxldC10cmFuc2Zvcm09XCJ0cmFuc2Zvcm1cIlxuPlxuICA8ZGl2XG4gICAgKm5nSWY9XCIhdHJhbnNmb3JtXCJcbiAgICBbaW5uZXJIVE1MXT1cInJvd1tjb2x1bW4ua2V5XSB8IGhpZ2hsaWdodDogc2VhcmNoXCJcbiAgPjwvZGl2PlxuICA8ZGl2XG4gICAgKm5nSWY9XCJ0cmFuc2Zvcm1cIlxuICAgIFtpbm5lckhUTUxdPVwiXG4gICAgICByb3dbY29sdW1uLmtleV1cbiAgICAgICAgfCBkeW5hbWljUGlwZTogdHJhbnNmb3JtLnBpcGU6dHJhbnNmb3JtPy5hcmdzXG4gICAgICAgIHwgaGlnaGxpZ2h0OiBzZWFyY2hcbiAgICBcIlxuICA+PC9kaXY+XG48L25nLXRlbXBsYXRlPlxuPG5nLXRlbXBsYXRlICNyYXdEYXRhIGxldC1yb3c9XCJyb3dcIiBsZXQtY29sdW1uPVwiY29sdW1uXCI+XG4gIHt7IHJvd1tjb2x1bW4ua2V5XSB9fVxuPC9uZy10ZW1wbGF0ZT5cbjxuZy10ZW1wbGF0ZVxuICAjdHJhbnNmb3JtRGF0YVxuICBsZXQtcm93PVwicm93XCJcbiAgbGV0LWNvbHVtbj1cImNvbHVtblwiXG4gIGxldC10cmFuc2Zvcm09XCJ0cmFuc2Zvcm1cIlxuICBsZXQtZGF0YT1cImRhdGFcIlxuPlxuICB7eyByb3dbY29sdW1uLmtleV0gfCBkeW5hbWljUGlwZTogdHJhbnNmb3JtLnBpcGU6dHJhbnNmb3JtPy5hcmdzIH19XG48L25nLXRlbXBsYXRlPlxuPG5nLXRlbXBsYXRlICN0cmFuc2Zvcm1Gb290ZXIgbGV0LXZhbHVlPVwidmFsdWVcIiBsZXQtdHJhbnNmb3JtPVwidHJhbnNmb3JtXCI+XG4gIHt7XG4gICAgKHZhbHVlIHwgZHluYW1pY1BpcGU6IHRyYW5zZm9ybS5waXBlOnRyYW5zZm9ybT8uYXJncykgfHxcbiAgICAgICh0YWJsZUNvbmZpZyQgfCBhc3luYyk/LmZvb3Rlcj8uZW1wdHlDb250ZW50XG4gIH19XG48L25nLXRlbXBsYXRlPlxuPG5nLXRlbXBsYXRlICNyYXdGb290ZXIgbGV0LXZhbHVlPVwidmFsdWVcIj5cbiAge3sgdmFsdWUgfHwgKHRhYmxlQ29uZmlnJCB8IGFzeW5jKT8uZm9vdGVyPy5lbXB0eUNvbnRlbnQgfX1cbjwvbmctdGVtcGxhdGU+XG48bmctdGVtcGxhdGVcbiAgI3RlbXBsYXRlUmVmXG4gIGxldC1yb3c9XCJyb3dcIlxuICBsZXQtY29sdW1uPVwiY29sdW1uXCJcbiAgbGV0LWluZGV4PVwiaW5kZXhcIlxuICBsZXQtdGVtcGxhdGVSZWY9XCJ0ZW1wbGF0ZVJlZlwiXG4gIGxldC1kYXRhPVwiZGF0YVwiXG4+XG4gIDxuZy1jb250YWluZXJcbiAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJ0ZW1wbGF0ZVJlZlwiXG4gICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cIntcbiAgICAgIHJvdzogcm93LFxuICAgICAgY29sOiBjb2x1bW4sXG4gICAgICBpbmRleDogaW5kZXgsXG4gICAgICBkYXRhOiBkYXRhXG4gICAgfVwiXG4gID48L25nLWNvbnRhaW5lcj5cbjwvbmctdGVtcGxhdGU+XG4iXX0=
560
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29yZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb3JlL3NyYy9saWIvY29yZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb3JlL3NyYy9saWIvY29yZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDVCxZQUFZLEVBQ1osS0FBSyxFQUVMLE1BQU0sR0FFUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQ0wsZUFBZSxFQUNmLGFBQWEsRUFDYixTQUFTLEVBQ1QsWUFBWSxFQUVaLEVBQUUsRUFDRixhQUFhLEVBQ2IsT0FBTyxHQUNSLE1BQU0sTUFBTSxDQUFDO0FBRWQsT0FBTyxFQUNMLFNBQVMsRUFFVCxZQUFZLEVBQ1osT0FBTyxFQUNQLE9BQU8sRUFDUCxJQUFJLEVBQ0osZ0JBQWdCLEVBQ2hCLFNBQVMsR0FDVixNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFFTCxvQkFBb0IsRUFDcEIsTUFBTSxFQUNOLEdBQUcsRUFDSCxLQUFLLEVBQ0wsV0FBVyxFQUNYLFNBQVMsRUFDVCxTQUFTLEVBQ1QsSUFBSSxFQUNKLFNBQVMsRUFDVCxHQUFHLEVBQ0gsY0FBYyxHQUNmLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEIsT0FBTyxFQUNMLFNBQVMsRUFDVCxLQUFLLEVBQ0wsTUFBTSxFQUNOLGtCQUFrQixHQUNuQixNQUFNLHVCQUF1QixDQUFDO0FBVy9CLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDeEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3RELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNuRCxPQUFPLEVBQUUs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QUFLO2dCQWdCTyxhQUFhO3NCQUF6QixLQUFLO2dCQWdCTyxlQUFlO3NCQUEzQixLQUFLO2dCQWdCRyxTQUFTO3NCQUFqQixLQUFLO2dCQU1HLFFBQVE7c0JBQWhCLEtBQUs7Z0JBTUcsYUFBYTtzQkFBckIsS0FBSztnQkFNTyxZQUFZO3NCQUF4QixLQUFLO2dCQWVGLE1BQU07c0JBRFQsS0FBSztnQkFNRixNQUFNO3NCQURULEtBQUs7Z0JBUUYsSUFBSTtzQkFEUCxLQUFLO2dCQU9PLFNBQVM7c0JBQXJCLEtBQUs7Z0JBT0ksUUFBUTtzQkFBakIsTUFBTTtnQkFDRyxTQUFTO3NCQUFsQixNQUFNO2dCQUNHLGVBQWU7c0JBQXhCLE1BQU07Z0JBV0csU0FBUztzQkFBbEIsTUFBTTtnQkFDRyxVQUFVO3NCQUFuQixNQUFNO2dCQUVHLFVBQVU7c0JBQW5CLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ29tcG9uZW50LFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE91dHB1dCxcbiAgVHJhY2tCeUZ1bmN0aW9uLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIEJlaGF2aW9yU3ViamVjdCxcbiAgY29tYmluZUxhdGVzdCxcbiAgZnJvbUV2ZW50LFxuICBpc09ic2VydmFibGUsXG4gIE9ic2VydmFibGUsXG4gIG9mLFxuICBSZXBsYXlTdWJqZWN0LFxuICBTdWJqZWN0LFxufSBmcm9tICdyeGpzJztcbmltcG9ydCB7IFRhYmxlQ29uZmlnIH0gZnJvbSAnLi9tb2RlbHMvdGFibGUtY29uZmlnLmludGVyZmFjZSc7XG5pbXBvcnQge1xuICBBc3luY1BpcGUsXG4gIEtleVZhbHVlLFxuICBLZXlWYWx1ZVBpcGUsXG4gIE5nQ2xhc3MsXG4gIE5nRm9yT2YsXG4gIE5nSWYsXG4gIE5nVGVtcGxhdGVPdXRsZXQsXG4gIFNsaWNlUGlwZSxcbn0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIGRlYm91bmNlVGltZSxcbiAgZGlzdGluY3RVbnRpbENoYW5nZWQsXG4gIGZpbHRlcixcbiAgbWFwLFxuICBwbHVjayxcbiAgc2hhcmVSZXBsYXksXG4gIHN0YXJ0V2l0aCxcbiAgc3dpdGNoTWFwLFxuICB0YWtlLFxuICB0YWtlVW50aWwsXG4gIHRhcCxcbiAgd2l0aExhdGVzdEZyb20sXG59IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IFRhYmxlQ29sdW1uIH0gZnJvbSAnLi9tb2RlbHMvdGFibGUtY29sdW1uLmludGVyZmFjZSc7XG5pbXBvcnQge1xuICBjYWxjdWxhdGUsXG4gIGNodW5rLFxuICBzZWFyY2gsXG4gIHNvcnRPbk11bHRpcGxlS2V5cyxcbn0gZnJvbSAnLi91dGlsaXRpZXMvdXRpbGl0aWVzJztcbmltcG9ydCB7IFRhYmxlUm93IH0gZnJvbSAnLi9tb2RlbHMvdGFibGUtcm93LmludGVyZmFjZSc7XG5pbXBvcnQgeyBHdE9yZGVyLCBHdFNvcnRPcmRlciB9IGZyb20gJy4vbW9kZWxzL3RhYmxlLXNvcnQuaW50ZXJmYWNlJztcbmltcG9ydCB7IFRhYmxlTWV0YSB9IGZyb20gJy4vbW9kZWxzL3RhYmxlLW1ldGEuaW50ZXJmYWNlJztcbmltcG9ydCB7XG4gIEd0UGFnZUNoYW5nZUV2ZW50LFxuICBHdFJvd1NlbGVjdEV2ZW50LFxuICBHdFJvd0NsaWNrRXZlbnQsXG4gIEd0Um93QWN0aXZlRXZlbnQsXG4gIEd0U29ydEV2ZW50LFxufSBmcm9tICcuL21vZGVscy90YWJsZS1ldmVudHMuaW50ZXJmYWNlJztcbmltcG9ydCB7IENhcGl0YWxDYXNlUGlwZSB9IGZyb20gJy4vcGlwZXMvY2FwaXRhbC1jYXNlLnBpcGUnO1xuaW1wb3J0IHsgU29ydENsYXNzUGlwZSB9IGZyb20gJy4vcGlwZXMvc29ydC1jbGFzcy5waXBlJztcbmltcG9ydCB7IERhc2hDYXNlUGlwZSB9IGZyb20gJy4vcGlwZXMvZGFzaC1jYXNlLnBpcGUnO1xuaW1wb3J0IHsgRHluYW1pY1BpcGUgfSBmcm9tICcuL3BpcGVzL2R5bmFtaWMucGlwZSc7XG5pbXBvcnQgeyBIaWdobGlnaHRQaXBlIH0gZnJvbSAnLi9waXBlcy9oaWdobGlnaHQucGlwZSc7XG5pbXBvcnQgeyBSb3dTZWxlY3Rpb25QaXBlIH0gZnJvbSAnLi9waXBlcy9yb3ctc2VsZWN0aW9uLnBpcGUnO1xuaW1wb3J0IHsgR3RQYWdpbmF0aW9uSW5mbyB9IGZyb20gJy4vbW9kZWxzL2d0LXBhZ2luYXRpb24nO1xuaW1wb3J0IHsgVGFibGVJbmZvIH0gZnJvbSAnLi9tb2RlbHMvdGFibGUtaW5mby5pbnRlcmZhY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhbmd1bGFyLWdlbmVyaWMtdGFibGUnLFxuICB0ZW1wbGF0ZVVybDogJy4vY29yZS5jb21wb25lbnQuaHRtbCcsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgQ2FwaXRhbENhc2VQaXBlLFxuICAgIEtleVZhbHVlUGlwZSxcbiAgICBTb3J0Q2xhc3NQaXBlLFxuICAgIERhc2hDYXNlUGlwZSxcbiAgICBSb3dTZWxlY3Rpb25QaXBlLFxuICAgIEFzeW5jUGlwZSxcbiAgICBOZ1RlbXBsYXRlT3V0bGV0LFxuICAgIFNsaWNlUGlwZSxcbiAgICBEeW5hbWljUGlwZSxcbiAgICBIaWdobGlnaHRQaXBlLFxuICAgIE5nQ2xhc3MsXG4gICAgTmdJZixcbiAgICBOZ0Zvck9mLFxuICBdLFxufSlcbmV4cG9ydCBjbGFzcyBDb3JlQ29tcG9uZW50IGltcGxlbWVudHMgT25EZXN0cm95IHtcbiAgdW5zdWJzY3JpYmUkID0gbmV3IFN1YmplY3QoKTtcbiAgZ2V0IG5hdmlnYXRpb25LZXlzKCk6IHR5cGVvZiB0aGlzLl9uYXZpZ2F0aW9uS2V5cyB7XG4gICAgcmV0dXJuIHRoaXMuX25hdmlnYXRpb25LZXlzO1xuICB9XG5cbiAgLyoqIG5hdmlnYXRpb25LZXlzXG4gICAqIEBkZXNjcmlwdGlvbiBBbiBhcnJheSBvZiBrZXlib2FyZCBrZXlzIHRoYXQgd2lsbCB0cmlnZ2VyIG5hdmlnYXRpb24gYW5kIGFjdGl2ZSByb3csIGN1cnJlbnRseSBvbmx5IHN1cHBvcnRzIGFycm93IGtleXMsIGhvbWUgYW5kIGVuZCAob21pdCBrZXkgbmFtZSBmcm9tIGFycmF5IHRvIGRpc2FibGUgaXQpXG4gICAqIEB0eXBlIHtzdHJpbmdbXX1cbiAgICogQGRlZmF1bHQgWydBcnJvd0Rvd24nLCAnQXJyb3dVcCcsICdBcnJvd0xlZnQnLCAnQXJyb3dSaWdodCcsICdIb21lJywgJ0VuZCddXG4gICAqL1xuICBASW5wdXQoKSBzZXQgbmF2aWdhdGlvbktleXModmFsdWU6IHR5cGVvZiB0aGlzLl9uYXZpZ2F0aW9uS2V5cykge1xuICAgIHRoaXMuX25hdmlnYXRpb25LZXlzID0gdmFsdWU7XG4gIH1cblxuICBwcml2YXRlIF9uYXZpZ2F0aW9uS2V5cyA9IFtcbiAgICAnQXJyb3dEb3duJyxcbiAgICAnQXJyb3dVcCcsXG4gICAgJ0Fycm93TGVmdCcsXG4gICAgJ0Fycm93UmlnaHQnLFxuICAgICdIb21lJyxcbiAgICAnRW5kJyxcbiAgXTtcbiAgZ2V0IHNlbGVjdEtleXMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLl9zZWxlY3RLZXlzO1xuICB9XG5cbiAgLyoqIHNlbGVjdEtleXNcbiAgICogQGRlc2NyaXB0aW9uIEFuIGFycmF5IG9mIGtleWJvYXJkIGtleXMgdGhhdCB3aWxsIHRyaWdnZXIgcm93IHNlbGVjdGlvbiAob21pdCBrZXkgbmFtZSBmcm9tIGFycmF5IHRvIGRpc2FibGUgaXQpXG4gICAqIEB0eXBlIHtzdHJpbmdbXX1cbiAgICogQGRlZmF1bHQgWydFbnRlcicsICcgJ11cbiAgICovXG4gIEBJbnB1dCgpIHNldCBzZWxlY3RLZXlzKHZhbHVlOiBzdHJpbmdbXSkge1xuICAgIHRoaXMuX3NlbGVjdEtleXMgPSB2YWx1ZTtcbiAgfVxuXG4gIHByaXZhdGUgX3NlbGVjdEtleXMgPSBbJ0VudGVyJywgJyAnXTtcbiAgZ2V0IHNvcnRPcmRlciQoKTogT2JzZXJ2YWJsZTxHdFNvcnRPcmRlcj4ge1xuICAgIHJldHVybiB0aGlzLl9zb3J0T3JkZXIkLmFzT2JzZXJ2YWJsZSgpO1xuICB9XG5cbiAgQElucHV0KCkgc2V0IGxvYWRpbmcoaXNMb2FkaW5nOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHwgYm9vbGVhbikge1xuICAgIHRoaXMuX2xvYWRpbmckLm5leHQoaXNMb2FkaW5nKTtcbiAgfVxuICBASW5wdXQoKVxuICBzZXQgcGFnaW5hdGlvbkluZGV4KHBhZ2VJbmRleDogbnVtYmVyKSB7XG4gICAgdGhpcy5fY3VycmVudFBhZ2luYXRpb25JbmRleCQubmV4dChwYWdlSW5kZXgpO1xuICB9XG5cbiAgZ2V0IHBhZ2luYXRpb25JbmRleCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLl9jdXJyZW50UGFnaW5hdGlvbkluZGV4JC5nZXRWYWx1ZSgpO1xuICB9XG5cbiAgQElucHV0KCkgc2V0IHBhZ2luZ0luZm8odmFsdWU6IEd0UGFnaW5hdGlvbkluZm8gfCBudWxsKSB7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICB0aGlzLl9wYWdpbmdJbmZvJC5uZXh0KHZhbHVlKTtcbiAgICAgIGlmIChcbiAgICAgICAgdmFsdWUucGFnZUN1cnJlbnQgIT09IHRoaXMuX2N1cnJlbnRQYWdpbmF0aW9uSW5kZXgkLmdldFZhbHVlKCkgKyAxICYmXG4gICAgICAgIHZhbHVlLnBhZ2VDdXJyZW50ICE9PSBudWxsXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5wYWdpbmF0aW9uSW5kZXggPSB2YWx1ZS5wYWdlQ3VycmVudCAtIDE7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqIGN1c3RvbUNsYXNzZXNcbiAgICogQGRlc2NyaXB0aW9uIEFuIG9iamVjdCB0aGF0IGNvbnRhaW5zIGN1c3RvbSBjbGFzc2VzIGZvciB2YXJpb3VzIGVsZW1lbnRzIGluIHRoZSB0YWJsZS5cbiAgICogQHR5cGUge29iamVjdH0gLSB7IHNlbGVjdGVkUm93OiBzdHJpbmcsIGFjdGl2ZVJvdzogc3RyaW5nIH0gLSBkZWZhdWx0IGNsYXNzZXMgYXJlICdndC1zZWxlY3RlZCcgYW5kICdndC1hY3RpdmUnXG4gICAqL1xuICBASW5wdXQoKSBzZXQgY3VzdG9tQ2xhc3NlcyhjbGFzc2VzOiBQYXJ0aWFsPHR5cGVvZiB0aGlzLl9jdXN0b21DbGFzc2VzPikge1xuICAgIHRoaXMuX2N1c3RvbUNsYXNzZXMgPSB7IC4uLnRoaXMuX2N1c3RvbUNsYXNzZXMsIC4uLmNsYXNzZXMgfTtcbiAgfVxuXG4gIGdldCBjdXN0b21DbGFzc2VzKCk6IHR5cGVvZiB0aGlzLl9jdXN0b21DbGFzc2VzIHtcbiAgICByZXR1cm4gdGhpcy5fY3VzdG9tQ2xhc3NlcztcbiAgfVxuXG4gIHByaXZhdGUgX2N1c3RvbUNsYXNzZXMgPSB7XG4gICAgc2VsZWN0ZWRSb3c6ICdndC1zZWxlY3RlZCcsXG4gICAgYWN0aXZlUm93OiAnZ3QtYWN0aXZlJyxcbiAgfTtcblxuICAvKiogaXNSb3dTZWxlY3RlZEZuXG4gICAqIEBkZXNjcmlwdGlvbiBGdW5jdGlvbiB0byBkZXRlcm1pbmUgaWYgcm93IGlzIHNlbGVjdGVkIG9yIG5vdC5cbiAgICogQHR5cGUge2ZufSBBIGZ1bmN0aW9uIHRoYXQgcmVjZWl2ZXMgYSByb3cgb2JqZWN0IGFuZCBvcHRpb25hbCBzdGF0ZSBmb3IgY3VycmVudCBzZWxlY3Rpb24gdGhhdCBjYW4gYmUgdXNlZCB0byBkZXRlcm1pbmUgaWYgcm93IHNob3VsZCBiZSBtYXJrZWQgYXMgc2VsZWN0ZWQgb3Igbm90LiAqL1xuICBASW5wdXQoKSBzZXQgaXNSb3dTZWxlY3RlZEZuKFxuICAgIGZuOiAocm93OiBUYWJsZVJvdyB8IGFueSwgc2VsZWN0aW9uPzogYW55KSA9PiBib29sZWFuXG4gICkge1xuICAgIHRoaXMuX2lzUm93U2VsZWN0ZWRGbiA9IGZuO1xuICB9XG5cbiAgZ2V0IGlzUm93U2VsZWN0ZWRGbigpOiBhbnkge1xuICAgIHJldHVybiB0aGlzLl9pc1Jvd1NlbGVjdGVkRm47XG4gIH1cblxuICBwcml2YXRlIF9pc1Jvd1NlbGVjdGVkRm46IGFueTtcblxuICAvKiogc2VsZWN0aW9uXG4gICAqIEBkZXNjcmlwdGlvbiBBbiBvYmplY3QgdGhhdCBjb250YWlucyB0aGUgY3VycmVudGx5IHNlbGVjdGVkIHJvdyhzKSBpbiB0aGUgdGFibGUuIEl0J3MgcGFzc2VkIHRvIHRoZSBzZWxlY3Rpb24gZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIHdoaWNoIHJvd3Mgc2hvdWxkIGJlIHNlbGVjdGVkLlxuICAgKiBAdHlwZSB7YW55fVxuICAgKi9cbiAgQElucHV0KCkgc2VsZWN0aW9uOiBhbnkgPSB7fTtcblxuICAvKiogcm93SWRLZXlcbiAgICogQGRlc2NyaXB0aW9uIHJvdyBrZXkgdG8gdXNlIGFzIHVuaXF1ZSBpZCBmb3IgdGFibGUgcm93LiBJZiBwYXNzZWQsIHRhYmxlIHdvbid0IGdlbmVyYXRlIHVuaXF1ZSBpZHMgZm9yIGVhY2ggcm93IGJ1dCBpbnN0ZWFkIHVzZSBrZXkgdG8gcmV0cmlldmUgdW5pcXVlIGlkIGZyb20gcm93LlxuICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgKi9cbiAgQElucHV0KCkgcm93SWRLZXk6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAvKiogZ2VuZXJhdGVSb3dJZFxuICAgKiBAZGVzY3JpcHRpb24gV2hldGhlciBvciBub3QgdG8gZ2VuZXJhdGUgYSB1bmlxdWUgaWQgZm9yIGVhY2ggcm93IGluIHRoZSB0YWJsZS4gRGVmYXVsdHMgdG8gYHRydWVgLlxuICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICovXG4gIEBJbnB1dCgpIGdlbmVyYXRlUm93SWQ6IGJvb2xlYW4gPSB0cnVlO1xuXG4gIC8qKiB0cmFja1Jvd0J5Rm5cbiAgICogQGRlc2NyaXB0aW9uIEEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGEgdW5pcXVlIGlkZW50aWZpZXIgZm9yIGVhY2ggcm93IGluIHRoZSB0YWJsZSB0byBvcHRpbWl6ZSByZW5kZXJpbmcgd2hlbiBkYXRhIGlzIGFkZGVkIG9yIHJlbW92ZWQuXG4gICAqIEB0eXBlIGZuIC0gVHJhY2tCeUZ1bmN0aW9uIHRvIHJldHJpZXZlIHVuaXF1ZSBpZCBiYXNlZCBvbiBpbmRleCBhbmQvb3Igcm93LiBEZWZhdWx0cyB0byB1c2luZyBgcm93W3RoaXMucm93SWRLZXldYC5cbiAgICovXG4gIEBJbnB1dCgpIHNldCB0cmFja1Jvd0J5Rm4oZm46IFRyYWNrQnlGdW5jdGlvbjxUYWJsZVJvdz4pIHtcbiAgICB0aGlzLl90cmFja1Jvd0J5Rm4gPSBmbjtcbiAgfVxuICBnZXQgdHJhY2tSb3dCeUZuKCk6IFRyYWNrQnlGdW5jdGlvbjxUYWJsZVJvdz4ge1xuICAgIHJldHVybiB0aGlzLl90cmFja1Jvd0J5Rm47XG4gIH1cblxuICBwcml2YXRlIF90cmFja1Jvd0J5Rm4oXG4gICAgaW5kZXg6IG51bWJlcixcbiAgICByb3c6IFRhYmxlUm93XG4gICk6IFRyYWNrQnlGdW5jdGlvbjxUYWJsZVJvdz4ge1xuICAgIHJldHVybiB0aGlzLnJvd0lkS2V5ID8gcm93W3RoaXMucm93SWRLZXldIDogcm93Py5faWQ7XG4gIH1cblxuICBASW5wdXQoKVxuICBzZXQgc2VhcmNoKHN0cmluZzogT2JzZXJ2YWJsZTxzdHJpbmcgfCBudWxsPiB8IHN0cmluZyB8IG51bGwpIHtcbiAgICB0aGlzLl9zZWFyY2hCeSQubmV4dChzdHJpbmcpO1xuICB9XG5cbiAgQElucHV0KClcbiAgc2V0IGNvbmZpZyhjb25maWc6IE9ic2VydmFibGU8VGFibGVDb25maWc8YW55Pj4gfCBUYWJsZUNvbmZpZzxhbnk+KSB7XG4gICAgdGhpcy5fdGFibGVDb25maWckLm5leHQoY29uZmlnKTtcbiAgfVxuXG4gIHByaXZhdGUgX3RhYmxlQ29uZmlnOiBUYWJsZUNvbmZpZzxhbnk+IHwgdW5kZWZpbmVkO1xuXG4gIEBJbnB1dCgpXG4gIHNldCBkYXRhKGRhdGE6IE9ic2VydmFibGU8QXJyYXk8VGFibGVSb3c+PiB8IEFycmF5PFRhYmxlUm93PiB8IG51bGwpIHtcbiAgICBpZiAoZGF0YSkge1xuICAgICAgdGhpcy5fZGF0YSQubmV4dChkYXRhKTtcbiAgICB9XG4gIH1cblxuICBASW5wdXQoKSBzZXQgc29ydE9yZGVyKHNvcnRDb25maWc6IEd0U29ydE9yZGVyPFRhYmxlUm93PiB8IGFueSkge1xuICAgIGlmIChKU09OLnN0cmluZ2lmeShzb3J0Q29uZmlnKSAhPT0gSlNPTi5zdHJpbmdpZnkodGhpcy5fc29ydE9yZGVyJC52YWx1ZSkpIHtcbiAgICAgIHRoaXMuc29ydE9yZGVyQ2hhbmdlLmVtaXQoc29ydENvbmZpZyk7XG4gICAgICB0aGlzLl9zb3J0T3JkZXIkLm5leHQoc29ydENvbmZpZyk7XG4gICAgfVxuICB9XG5cbiAgQE91dHB1dCgpIHJvd0NsaWNrID0gbmV3IEV2ZW50RW1pdHRlcjxHdFJvd0NsaWNrRXZlbnQ+KCk7XG4gIEBPdXRwdXQoKSByb3dTZWxlY3QgPSBuZXcgRXZlbnRFbWl0dGVyPEd0Um93U2VsZWN0RXZlbnQ+KCk7XG4gIEBPdXRwdXQoKSBzb3J0T3JkZXJDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPEd0U29ydE9yZGVyPFRhYmxlUm93Pj4oKTtcblxuICBfcm93Q2xpY2socm93OiBUYWJsZVJvdywgaW5kZXg6IG51bWJlciwgZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICB0aGlzLnJvd0NsaWNrLmVtaXQoeyByb3csIGluZGV4LCBldmVudCB9KTtcbiAgfVxuXG4gIF9yb3dBY3RpdmUocm93OiBUYWJsZVJvdywgaW5kZXg6IG51bWJlciwgZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICB0aGlzLnJvd1NlbGVjdC5lbWl0KHsgcm93LCBpbmRleCwgZXZlbnQgfSk7XG4gIH1cblxuICBwcml2YXRlIF9yb3dBY3RpdmUkID0gbmV3IFJlcGxheVN1YmplY3Q8R3RSb3dBY3RpdmVFdmVudD4oMSk7XG4gIEBPdXRwdXQoKSByb3dBY3RpdmUgPSBuZXcgRXZlbnRFbWl0dGVyPEd0Um93QWN0aXZlRXZlbnQ+KCk7XG4gIEBPdXRwdXQoKSBjb2x1bW5Tb3J0ID0gbmV3IEV2ZW50RW1pdHRlcjxHdFNvcnRFdmVudD4oKTtcbiAgLyoqIHBhZ2UgY2hhbmdlIGV2ZW50IC0gZW1pdHRlZCB3aGVuIGN1cnJlbnQgcGFnZS9pbmRleCBjaGFuZ2VzIGZvciBwYWdpbmF0aW9uICovXG4gIEBPdXRwdXQoKSBwYWdlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxHdFBhZ2VDaGFuZ2VFdmVudD4oKTtcbiAgcm93QWN0aXZlJCA9IHRoaXMuX3Jvd0FjdGl2ZSQuYXNPYnNlcnZhYmxlKCkucGlwZShcbiAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgocCwgcSkgPT4ge1xuICAgICAgaWYgKHRoaXMucm93SWRLZXkgJiYgcC5yb3cgJiYgcS5yb3cpIHtcbiAgICAgICAgcmV0dXJuIHAucm93W3RoaXMucm93SWRLZXldID09PSBxLnJvd1t0aGlzLnJvd0lkS2V5XTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5nZW5lcmF0ZVJvd0lkICYmIHAucm93ICYmIHEucm93KSB7XG4gICAgICAgIHJldHVybiBwLnJvdy5faWQgPT09IHEucm93Ll9pZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBwLmluZGV4ID09PSBxLmluZGV4O1xuICAgICAgfVxuICAgIH0pLFxuICAgIHRhcCgoZXZlbnQpID0+ICh0aGlzLmFjdGl2ZVJvd0luZGV4ID0gZXZlbnQuaW5kZXgpKSxcbiAgICB0YXAoKGV2ZW50KSA9PiB0aGlzLnJvd0FjdGl2ZS5lbWl0KGV2ZW50KSksXG4gICAgc2hhcmVSZXBsYXkoMSlcbiAgKTtcblxuICBhY3RpdmVSb3dJbmRleDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gIGFjdGl2YXRlUm93KGlkOiBzdHJpbmcsIGV2ZW50PzogTW91c2VFdmVudCB8IEtleWJvYXJkRXZlbnQpOiB2b2lkO1xuICBhY3RpdmF0ZVJvdyhpbmRleDogbnVtYmVyLCBldmVudD86IE1vdXNlRXZlbnQgfCBLZXlib2FyZEV2ZW50KTogdm9pZDtcbiAgYWN0aXZhdGVSb3cobm9uZTogbnVsbCwgZXZlbnQ/OiBNb3VzZUV2ZW50IHwgS2V5Ym9hcmRFdmVudCk6IHZvaWQ7XG4gIGFjdGl2YXRlUm93KFxuICAgIGFyZzogc3RyaW5nIHwgbnVtYmVyIHwgbnVsbCxcbiAgICBldmVudD86IE1vdXNlRXZlbnQgfCBLZXlib2FyZEV2ZW50XG4gICk6IHZvaWQge1xuICAgIGlmICh0eXBlb2YgYXJnID09PSAnbnVtYmVyJykge1xuICAgICAgdGhpcy50YWJsZSRcbiAgICAgICAgLnBpcGUoXG4gICAgICAgICAgcGx1Y2soJ2RhdGEnKSxcbiAgICAgICAgICBtYXAoKGRhdGEpID0+IGRhdGFbdGhpcy5wYWdpbmF0aW9uSW5kZXhdW2FyZ10pLFxuICAgICAgICAgIHRha2UoMSksXG4gICAgICAgICAgdGFrZVVudGlsKHRoaXMudW5zdWJzY3JpYmUkKVxuICAgICAgICApXG4gICAgICAgIC5zdWJzY3JpYmUoKHJvdykgPT4gdGhpcy5fYWN0aXZhdGVSb3cocm93LCBhcmcsIGV2ZW50KSk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgYXJnID09PSAnc3RyaW5nJykge1xuICAgICAgLy8gVE9ETzogaW1wbGVtZW50IGhvdmVyIGJ5IGlkXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2FjdGl2YXRlUm93KG51bGwsIG51bGwpO1xuICAgIH1cbiAgfVxuICBwcm90ZWN0ZWQgX2FjdGl2YXRlUm93KFxuICAgIHJvdzogVGFibGVSb3cgfCBudWxsLFxuICAgIGluZGV4OiBudW1iZXIgfCBudWxsLFxuICAgIGV2ZW50PzogTW91c2VFdmVudCB8IEtleWJvYXJkRXZlbnRcbiAgKTogdm9pZCB7XG4gICAgdGhpcy5fcm93QWN0aXZlJC5uZXh0KHsgcm93LCBpbmRleCwgZXZlbnQgfSk7XG4gIH1cblxuICBnZXQgbG9hZGluZyQoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIHRoaXMuX2xvYWRpbmckLnBpcGUoXG4gICAgICBzdGFydFdpdGgoZmFsc2UpLFxuICAgICAgbWFwKCh2YWx1ZSkgPT4gKGlzT2JzZXJ2YWJsZSh2YWx1ZSkgPyB2YWx1ZSA6IG9mKHZhbHVlKSkpLFxuICAgICAgc3dpdGNoTWFwKChvYnMpID0+IG9icyksXG4gICAgICBzaGFyZVJlcGxheSgxKVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIF9sb2FkaW5nJDogUmVwbGF5U3ViamVjdDxPYnNlcnZhYmxlPGJvb2xlYW4+IHwgYm9vbGVhbj4gPVxuICAgIG5ldyBSZXBsYXlTdWJqZWN0KDEpO1xuICBwcml2YXRlIF9zb3J0T3JkZXIkOiBCZWhhdmlvclN1YmplY3Q8R3RTb3J0T3JkZXI+ID1cbiAgICBuZXcgQmVoYXZpb3JTdWJqZWN0PEd0U29ydE9yZGVyPihbXSk7XG4gIHByaXZhdGUgX3NlYXJjaEJ5JDogUmVwbGF5U3ViamVjdDxPYnNlcnZhYmxlPHN0cmluZyB8IG51bGw+IHwgc3RyaW5nIHwgbnVsbD4gPVxuICAgIG5ldyBSZXBsYXlTdWJqZWN0KDEpO1xuICBzZWFyY2hCeSQ6IE9ic2VydmFibGU8c3RyaW5nIHwgbnVsbD4gPSB0aGlzLl9zZWFyY2hCeSQucGlwZShcbiAgICBzdGFydFdpdGgoJycpLFxuICAgIG1hcCgodmFsdWUpID0+IChpc09ic2VydmFibGUodmFsdWUpID8gdmFsdWUgOiBvZih2YWx1ZSkpKSxcbiAgICBzd2l0Y2hNYXAoKG9icykgPT4gb2JzKSxcbiAgICBzaGFyZVJlcGxheSgxKVxuICApO1xuXG4gIHByaXZhdGUgX3BhZ2luZ0luZm8kID0gbmV3IEJlaGF2aW9yU3ViamVjdDxHdFBhZ2luYXRpb25JbmZvPih7XG4gICAgcGFnZUN1cnJlbnQ6IG51bGwsXG4gICAgcGFnZU5leHQ6IG51bGwsXG4gICAgcGFnZVByZXZpb3VzOiBudWxsLFxuICAgIHBhZ2VTaXplOiBudWxsLFxuICAgIG51bWJlck9mUmVjb3JkczogbnVsbCxcbiAgICAvL3JlY29yZHNBZnRlckZpbHRlcjogbnVsbCxcbiAgICAvL3JlY29yZHNBZnRlclNlYXJjaDogbnVsbCxcbiAgICAvL3JlY29yZHNBbGw6IG51bGwsXG4gIH0pO1xuXG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTp2YXJpYWJsZS1uYW1lXG4gIHByaXZhdGUgX3RhYmxlQ29uZmlnJDogQmVoYXZpb3JTdWJqZWN0PFxuICAgIFRhYmxlQ29uZmlnPGFueT4gfCBPYnNlcnZhYmxlPFRhYmxlQ29uZmlnPGFueT4+XG4gID4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0KHt9KTtcbiAgdGFibGVDb25maWckID0gdGhpcy5fdGFibGVDb25maWckLnBpcGUoXG4gICAgbWFwKCh2YWx1ZSkgPT4gKGlzT2JzZXJ2YWJsZSh2YWx1ZSkgPyB2YWx1ZSA6IG9mKHZhbHVlKSkpLFxuICAgIHN3aXRjaE1hcCgob2JzKSA9PiBvYnMpLFxuICAgIHRhcCgoY29uZmlnKSA9PiAodGhpcy5fdGFibGVDb25maWcgPSBjb25maWcpKSxcbiAgICBzaGFyZVJlcGxheSgxKVxuICApO1xuXG4gIHByaXZhdGUgX2RhdGEkOiBSZXBsYXlTdWJqZWN0PEFycmF5PFRhYmxlUm93PiB8IE9ic2VydmFibGU8QXJyYXk8VGFibGVSb3c+Pj4gPVxuICAgIG5ldyBSZXBsYXlTdWJqZWN0KDEpO1xuICBkYXRhJDogT2JzZXJ2YWJsZTxBcnJheTxUYWJsZVJvdz4+ID0gdGhpcy5fZGF0YSQucGlwZShcbiAgICBtYXAoKHZhbHVlKSA9PiAoaXNPYnNlcnZhYmxlKHZhbHVlKSA/IHZhbHVlIDogb2YodmFsdWUpKSksXG4gICAgc3dpdGNoTWFwKChvYnMpID0+IGNvbWJpbmVMYXRlc3QoW29ic10pKSxcbiAgICB3aXRoTGF0ZXN0RnJvbSh0aGlzLnRhYmxlQ29uZmlnJCksXG4gICAgbWFwKChbW2RhdGFdLCBjb25maWddKSA9PiB7XG4gICAgICAvLyBpZiBjb2x1bW5zIG9yIHJvd3MgY29udGFpbnMgY29uZmlnIGZvciBtYXBUby4uLlxuICAgICAgaWYgKFxuICAgICAgICAoY29uZmlnLmNvbHVtbnMgJiZcbiAgICAgICAgICAhIU9iamVjdC52YWx1ZXMoY29uZmlnLmNvbHVtbnMpLmZpbmQoKGNvbHVtbikgPT4gISFjb2x1bW4ubWFwVG8pKSB8fFxuICAgICAgICAoY29uZmlnLnJvd3MgJiZcbiAgICAgICAgICAhIU9iamVjdC52YWx1ZXMoY29uZmlnLnJvd3MpLmZpbmQoKGNvbHVtbikgPT4gISFjb2x1bW4ubWFwVG8pKVxuICAgICAgKSB7XG4gICAgICAgIC8vIC4uLm1hcCBkYXRhIHRvIG5ldyBrZXlzIG9uIHJvdy4uLlxuICAgICAgICBjb25zdCBuZXdEYXRhOiBUYWJsZVJvd1tdID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGNvbnN0IHJvdyA9IGRhdGFbaV07XG4gICAgICAgICAgY29uc3QgbmV3S2V5cyA9IE9iamVjdC5lbnRyaWVzKGNvbmZpZy5jb2x1bW5zIHx8IGNvbmZpZy5yb3dzIHx8IFtdKVxuICAgICAgICAgICAgLmZpbHRlcigoW2tleSwgdmFsdWVdKSA9PiAhIXZhbHVlLm1hcFRvKSAvLyBhZGQga2V5cyBmb3IgY29sdW1ucyB3aXRoIG1hcFRvIGNvbmZpZy4uLlxuICAgICAgICAgICAgLnJlZHVjZShcbiAgICAgICAgICAgICAgKHByZXZpb3VzVmFsdWUsIFtrZXksIHZhbHVlXSkgPT4gKHtcbiAgICAgICAgICAgICAgICAuLi5wcmV2aW91c1ZhbHVlLFxuICAgICAgICAgICAgICAgIFtrZXldOiB0aGlzLm5lc3RlZFZhbHVlKFxuICAgICAgICAgICAgICAgICAgcm93LFxuICAgICAgICAgICAgICAgICAgdmFsdWUubWFwVG8hLnBhdGgsXG4gICAgICAgICAgICAgICAgICB2YWx1ZS5tYXBUbz8ubWlzc2luZ1ZhbHVlXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIHt9XG4gICAgICAgICAgICApO1xuICAgICAgICAgIG5ld0RhdGFbaV0gPSB7IC4uLnJvdywgLi4ubmV3S2V5cyB9O1xuICAgICAgICB9XG4gICAgICAgIGRhdGEgPSBuZXdEYXRhO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuZ2VuZXJhdGVSb3dJZCAmJiAhdGhpcy5yb3dJZEtleSAmJiBkYXRhLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgZGF0YVdpdGhJZCA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBkYXRhV2l0aElkW2ldID0geyAuLi5kYXRhW2ldLCBfaWQ6IGkgfTtcbiAgICAgICAgfVxuICAgICAgICBkYXRhID0gZGF0YVdpdGhJZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7IGRhdGEsIGNvbmZpZyB9O1xuICAgIH0pLFxuICAgIHN3aXRjaE1hcCgob2JzKSA9PlxuICAgICAgY29tYmluZUxhdGVzdChbb2Yob2JzKSwgdGhpcy5zb3J0T3JkZXIkLCB0aGlzLnNlYXJjaEJ5JF0pXG4gICAgKSxcbiAgICBtYXAoKFt0YWJsZSwgc29ydEJ5LCBzZWFyY2hCeV0pID0+IHtcbiAgICAgIC8vIGNyZWF0ZSBhIG5ldyBhcnJheSByZWZlcmVuY2UgYW5kIHNvcnQgbmV3IGFycmF5IChwcmV2ZW50IG11dGF0aW5nIGV4aXN0aW5nIHN0YXRlKVxuICAgICAgdGFibGUuZGF0YSA9IFsuLi50YWJsZS5kYXRhXTtcbiAgICAgIHJldHVybiAhc29ydEJ5Py5sZW5ndGggfHwgdGFibGUuY29uZmlnPy5kaXNhYmxlVGFibGVTb3J0XG4gICAgICAgID8gc2VhcmNoQnkgJiYgIXRoaXMudGFibGVJbmZvPy5sYXp5TG9hZGVkXG4gICAgICAgICAgPyBzZWFyY2goc2VhcmNoQnksIGZhbHNlLCB0YWJsZS5kYXRhLCB0YWJsZS5jb25maWcpXG4gICAgICAgICAgOiB0YWJsZS5kYXRhXG4gICAgICAgIDogc2VhcmNoQnkgJiYgIXRoaXMudGFibGVJbmZvPy5sYXp5TG9hZGVkXG4gICAgICAgID8gc2VhcmNoKHNlYXJjaEJ5LCBmYWxzZSwgdGFibGUuZGF0YSwgdGFibGUuY29uZmlnKT8uc29ydChcbiAgICAgICAgICAgIHNvcnRPbk11bHRpcGxlS2V5cyhzb3J0QnkpXG4gICAgICAgICAgKVxuICAgICAgICA6IHRhYmxlLmRhdGE/LnNvcnQoc29ydE9uTXVsdGlwbGVLZXlzKHNvcnRCeSkpO1xuICAgIH0pLFxuICAgIHNoYXJlUmVwbGF5KDEpXG4gICk7XG5cbiAgY2FsY3VsYXRpb25zJCA9IGNvbWJpbmVMYXRlc3QoW3RoaXMuZGF0YSQsIHRoaXMudGFibGVDb25maWckXSkucGlwZShcbiAgICBtYXAoKFtkYXRhLCBjb25maWddKSA9PiBjYWxjdWxhdGUoZGF0YSwgY29uZmlnKSksXG4gICAgc2hhcmVSZXBsYXkoMSlcbiAgKTtcblxuICB0YWJsZSQ6IE9ic2VydmFibGU8VGFibGVNZXRhPiA9IGNvbWJpbmVMYXRlc3QoW1xuICAgIHRoaXMuZGF0YSQsXG4gICAgdGhpcy50YWJsZUNvbmZpZyQsXG4gICAgdGhpcy5fcGFnaW5nSW5mbyQsXG4gIF0pLnBpcGUoXG4gICAgbWFwKChbc29ydGVkLCBjb25maWcsIHBhZ2luZ0luZm9dKSA9PiB7XG4gICAgICBpZiAoXG4gICAgICAgIHBhZ2luZ0luZm8ucGFnZUN1cnJlbnQgIT09IG51bGwgJiZcbiAgICAgICAgcGFnaW5nSW5mby5udW1iZXJPZlJlY29yZHMgIT09IG51bGwgJiZcbiAgICAgICAgcGFnaW5nSW5mby5wYWdlU2l6ZSAhPT0gbnVsbFxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZGF0YTogW3NvcnRlZF0sXG4gICAgICAgICAgY29uZmlnLFxuICAgICAgICAgIGluZm86IDxUYWJsZUluZm8+e1xuICAgICAgICAgICAgbGF6eUxvYWRlZDogdHJ1ZSxcbiAgICAgICAgICAgIG51bWJlck9mUmVjb3JkczogcGFnaW5nSW5mby5udW1iZXJPZlJlY29yZHMsXG4gICAgICAgICAgICBwYWdlU2l6ZTogcGFnaW5nSW5mby5wYWdlU2l6ZSxcbiAgICAgICAgICAgIHBhZ2VUb3RhbDpcbiAgICAgICAgICAgICAgcGFnaW5nSW5mby5wYWdlVG90YWwgPz9cbiAgICAgICAgICAgICAgTWF0aC5jZWlsKHBhZ2luZ0luZm8ubnVtYmVyT2ZSZWNvcmRzIC8gcGFnaW5nSW5mby5wYWdlU2l6ZSksXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIC8vIGlmIHBhZ2luYXRpb24gaXMgZGlzYWJsZWQuLi5cbiAgICAgIGlmICghY29uZmlnLnBhZ2luYXRpb24gfHwgY29uZmlnLnBhZ2luYXRpb24ubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIC8vIC4uLnJldHVybiB1bmFsdGVyZWQgYXJyYXlcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBkYXRhOiBbc29ydGVkXSxcbiAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgaW5mbzogPFRhYmxlSW5mbz57IG51bWJlck9mUmVjb3Jkczogc29ydGVkLmxlbmd0aCwgcGFnZVRvdGFsOiAxIH0sXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICAvLyByZXR1cm4gcmVjb3JkIHNldFxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZGF0YTogY2h1bmsoc29ydGVkLCArKGNvbmZpZy5wYWdpbmF0aW9uLmxlbmd0aCB8fCAwKSksXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgaW5mbzogPFRhYmxlSW5mbz57XG4gICAgICAgICAgbnVtYmVyT2ZSZWNvcmRzOiBzb3J0ZWQubGVuZ3RoLFxuICAgICAgICAgIHBhZ2VTaXplOiArKGNvbmZpZy5wYWdpbmF0aW9uLmxlbmd0aCB8fCAwKSxcbiAgICAgICAgICBwYWdlVG90YWw6IE1hdGguY2VpbChcbiAgICAgICAgICAgIHNvcnRlZC5sZW5ndGggLyArKGNvbmZpZy5wYWdpbmF0aW9uLmxlbmd0aCB8fCAwKVxuICAgICAgICAgICksXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH0pLFxuICAgIHRhcCgobWV0YSkgPT4gdGhpcy5fdGFibGVJbmZvJC5uZXh0KG1ldGEuaW5mbykpLFxuICAgIHNoYXJlUmVwbGF5KDEpXG4gICk7XG5cbiAgLyoqIHRhYmxlSW5mbyQgLSByZXR1cm5zIG9ic2VydmFibGUgZm9yIHRhYmxlIGluZm9cbiAgICogQHJldHVybiBPYnNlcnZhYmxlPFRhYmxlSW5mbz4gKi9cbiAgZ2V0IHRhYmxlSW5mbyQoKTogT2JzZXJ2YWJsZTxUYWJsZUluZm8gfCB1bmRlZmluZWQ+IHtcbiAgICByZXR1cm4gdGhpcy5fdGFibGVJbmZvJC5hc09ic2VydmFibGUoKS5waXBlKFxuICAgICAgZmlsdGVyKChpbmZvKSA9PiAhIWluZm8pLFxuICAgICAgc2hhcmVSZXBsYXkoMSlcbiAgICApO1xuICB9XG5cbiAgLyoqIHRhYmxlSW5mbyAtIHJldHVybnMgdGhlIGN1cnJlbnQgdGFibGUgaW5mb1xuICAgKiBAcmV0dXJuIFRhYmxlSW5mbyAqL1xuICBnZXQgdGFibGVJbmZvKCk6IFRhYmxlSW5mbyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuX3RhYmxlSW5mbyQuZ2V0VmFsdWUoKTtcbiAgfVxuXG4gIHByaXZhdGUgX3RhYmxlSW5mbyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFRhYmxlSW5mbyB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcblxuICBwcml2YXRlIF9jdXJyZW50UGFnaW5hdGlvbkluZGV4JDogQmVoYXZpb3JTdWJqZWN0PG51bWJlcj4gPVxuICAgIG5ldyBCZWhhdmlvclN1YmplY3QoMCk7XG4gIGN1cnJlbnRQYWdpbmF0aW9uSW5kZXgkID0gY29tYmluZUxhdGVzdChbXG4gICAgdGhpcy5fY3VycmVudFBhZ2luYXRpb25JbmRleCQsXG4gICAgdGhpcy50YWJsZSQsXG4gIF0pLnBpcGUoXG4gICAgbWFwKChbcGFnZSwgdGFibGVdOiBhbnkpID0+IHtcbiAgICAgIC8vIGRldGVybWluZSBsYXN0IHBhZ2VcbiAgICAgIGNvbnN0IGxhc3RQYWdlID1cbiAgICAgICAgTWF0aC5jZWlsKFxuICAgICAgICAgIHRhYmxlLmluZm8ucmVjb3JkcyAvXG4gICAgICAgICAgICAodGFibGUuaW5mby5yZWNvcmRMZW5ndGggPz9cbiAgICAgICAgICAgICAgKHRhYmxlLmNvbmZpZz8ucGFnaW5hdGlvbj8ubGVuZ3RoIHx8IHRhYmxlLmluZm8ucmVjb3JkcykpXG4gICAgICAgICkgLSAxO1xuICAgICAgLy8gZGV0ZXJtaW5lIG1pbi9tYXggcG9zaXRpb25cbiAgICAgIHJldHVybiArcGFnZSA8IDAgPyAwIDogK3BhZ2UgPiBsYXN0UGFnZSA/IGxhc3RQYWdlIDogK3BhZ2U7XG4gICAgfSksXG4gICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcbiAgICB0YXAoKGluZGV4KSA9PiB0aGlzLnBhZ2VDaGFuZ2UuZW1pdCh7IGluZGV4IH0pKSxcbiAgICBzaGFyZVJlcGxheSgxKVxuICApO1xuXG4gIGNvbHNwYW4kID0gdGhpcy50YWJsZUNvbmZpZyQucGlwZShcbiAgICBzd2l0Y2hNYXAoKGNvbmZpZykgPT5cbiAgICAgIGNvbmZpZy5jb2x1bW5zXG4gICAgICAgID8gb2YoXG4gICAgICAgICAgICBPYmplY3QudmFsdWVzKGNvbmZpZy5jb2x1bW5zIHx8IGNvbmZpZy5yb3dzIHx8IHt9KS5maWx0ZXIoXG4gICAgICAgICAgICAgICh2YWx1ZSkgPT4gdmFsdWUuaGlkZGVuICE9PSB0cnVlXG4gICAgICAgICAgICApLmxlbmd0aFxuICAgICAgICAgIClcbiAgICAgICAgOiB0aGlzLmRhdGEkLnBpcGUobWFwKChkYXRhKSA9PiBkYXRhLmxlbmd0aCArIDEpKVxuICAgICksXG4gICAgc2hhcmVSZXBsYXkoMSlcbiAgKTtcblxuICBmb290ZXJDb2xzcGFuJCA9IHRoaXMudGFibGVDb25maWckLnBpcGUoXG4gICAgbWFwKChjb25maWcpID0+IHtcbiAgICAgIGxldCBjb2xzcGFuID0gMDtcbiAgICAgIE9iamVjdC52YWx1ZXMoY29uZmlnPy5mb290ZXI/LmNvbHVtbnMgfHwge30pLmZvckVhY2goKGNhbGN1bGF0aW9ucykgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgT2JqZWN0LnZhbHVlcyhjYWxjdWxhdGlvbnMpLmZpbHRlcigodmFsdWUpID0+IHZhbHVlICE9PSBmYWxzZSlcbiAgICAgICAgICAgIC5sZW5ndGggPj0gMFxuICAgICAgICApIHtcbiAgICAgICAgICBjb2xzcGFuICs9IDE7XG4gICAgICAgIH1cbiAgICAgIH0sIHt9KTtcbiAgICAgIHJldHVybiBjb2xzcGFuO1xuICAgIH0pLFxuICAgIHNoYXJlUmVwbGF5KDEpXG4gICk7XG5cbiAgLyoqIHNvcnRCeUtleSAtIFNvcnQgYnkga2V5IGluIHRhYmxlIHJvd1xuICAgKiBAcGFyYW0ga2V5IC0ga2V5IHRvIHNvcnQgYnlcbiAgICogQHBhcmFtIHsgTW91c2VFdmVudCB9IFskZXZlbnRdIC0gTW91c2UgZXZlbnQgdHJpZ2dlcmluZyBzb3J0LCBpZiBzaGlmdCBrZXkgaXMgcHJlc3NlZCBzb3J0IGtleSB3aWxsIGJlIGFkZGVkIHRvIGFscmVhZHkgcHJlc2VudCBzb3J0IGtleXNcbiAgICovXG4gIHNvcnRCeUtleShrZXk6IGtleW9mIFRhYmxlUm93LCAkZXZlbnQ/OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgY29uc3Qgc2hpZnRLZXkgPSAkZXZlbnQ/LnNoaWZ0S2V5ID09PSB0cnVlO1xuICAgIGNvbnN0IGN1cnJlbnRPcmRlciA9IHRoaXMuX3NvcnRPcmRlciQudmFsdWU7XG4gICAgbGV0IHNvcnRPcmRlcjogR3RPcmRlciA9ICdhc2MnO1xuICAgIGxldCBuZXdPcmRlcjogR3RTb3J0T3JkZXIgPSBbXTtcbiAgICAvLyBpZiBzaGlmdCBrZXkgaXMgcHJlc3NlZCB3aGlsZSBzb3J0aW5nLi4uXG4gICAgaWYgKHNoaWZ0S2V5KSB7XG4gICAgICAvLyAuLi5jaGVjayBpZiBrZXkgaXMgYWxyZWFkeSBzb3J0ZWRcbiAgICAgIGNvbnN0IGV4aXN0aW5nU29ydFBvc2l0aW9uID0gY3VycmVudE9yZGVyLmZpbmRJbmRleChcbiAgICAgICAgKHZhbHVlKSA9PiB2YWx1ZS5rZXkgPT09IGtleVxuICAgICAgKTtcbiAgICAgIGlmIChleGlzdGluZ1NvcnRQb3NpdGlvbiA9PT0gLTEpIHtcbiAgICAgICAgLy8gLi4uaWYga2V5IGlzIG5vdCBzb3J0ZWQsIGFkZCBpdCB0byB0aGUgZW5kIG9mIHRoZSBzb3J0IG9yZGVyXG4gICAgICAgIG5ld09yZGVyID0gWy4uLmN1cnJlbnRPcmRlciwgeyBrZXksIG9yZGVyOiAnYXNjJyB9XTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIC4uLmlmIGtleSBpcyBhbHJlYWR5IHNvcnRlZCwgdG9nZ2xlIHNvcnQgb3JkZXJcbiAgICAgICAgc29ydE9yZGVyID0gY3VycmVudE9yZGVyW2V4aXN0aW5nU29ydFBvc2l0aW9uXS5vcmRlcjtcbiAgICAgICAgY29uc3QgbmV3U29ydE9yZGVyID0gc29ydE9yZGVyID09PSAnYXNjJyA/ICdkZXNjJyA6ICdhc2MnO1xuICAgICAgICBuZXdPcmRlciA9IFsuLi5jdXJyZW50T3JkZXJdO1xuICAgICAgICBuZXdPcmRlcltleGlzdGluZ1NvcnRQb3NpdGlvbl0gPSB7XG4gICAgICAgICAgLi4ubmV3T3JkZXJbZXhpc3RpbmdTb3J0UG9zaXRpb25dLFxuICAgICAgICAgIG9yZGVyOiBuZXdTb3J0T3JkZXIsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIC4uLmVsc2UgaWYgc2hpZnQga2V5IGlzIG5vdCBwcmVzc2VkLi4uXG4gICAgICBpZiAoY3VycmVudE9yZGVyLmxlbmd0aCA+IDApIHtcbiAgICAgICAgLy8gLi4uY2hlY2sgaWYga2V5IGlzIGFscmVhZHkgc29ydGVkXG4gICAgICAgIGNvbnN0IGV4aXN0aW5nU29ydFBvc2l0aW9uID0gY3VycmVudE9yZGVyLmZpbmRJbmRleChcbiAgICAgICAgICAodmFsdWUpID0+IHZhbHVlLmtleSA9PT0ga2V5XG4gICAgICAgICk7XG4gICAgICAgIC8vIC4uLmlmIGtleSBpcyBhbHJlYWR5IHNvcnRlZCwgdG9nZ2xlIHNvcnQgb3JkZXJcbiAgICAgICAgaWYgKGV4aXN0aW5nU29ydFBvc2l0aW9uID09PSAtMSkge1xuICAgICAgICAgIG5ld09yZGVyID0gW3sga2V5LCBvcmRlcjogJ2FzYycgfV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc29ydE9yZGVyID0gY3VycmVudE9yZGVyW2V4aXN0aW5nU29ydFBvc2l0aW9uXS5vcmRlcjtcbiAgICAgICAgICBjb25zdCBuZXdTb3J0T3JkZXIgPSBzb3J0T3JkZXIgPT09ICdhc2MnID8gJ2Rlc2MnIDogJ2FzYyc7XG4gICAgICAgICAgbmV3T3JkZXIgPSBbeyBrZXksIG9yZGVyOiBuZXdTb3J0T3JkZXIgfV07XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIC4uLmlmIGtleSBpcyBub3Qgc29ydGVkIHNldCBzb3J0IG9yZGVyIGZvciBrZXkgdG8gYXNjZW5kaW5nXG4gICAgICAgIG5ld09yZGVyID0gW3sga2V5LCBvcmRlcjogc29ydE9yZGVyIH1dO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBjcmVhdGUgc29ydCBldmVudFxuICAgIGNvbnN0IHNvcnRFdmVudDogR3RTb3J0RXZlbnQgPSB7XG4gICAgICBrZXksXG4gICAgICBvcmRlcjogc29ydE9yZGVyLFxuICAgICAgY3VycmVudFNvcnRPcmRlcjogbmV3T3JkZXIsXG4gICAgICBhZGRTb3J0S2V5OiBzaGlmdEtleSxcbiAgICB9O1xuXG4gICAgLy8gaWYgZXZlbnQgaXMgcGFzc2VkIHRvIHNvcnQgZnVuY3Rpb24uLi5cbiAgICBpZiAoJGV2ZW50KSB7XG4gICAgICAvLyAuLi5lbWl0IGl0IGFzIHdlbGxcbiAgICAgIHNvcnRFdmVudC5ldmVudCA9ICRldmVudDtcbiAgICB9XG4gICAgLy8gZW1pdCBzb3J0IGV2ZW50XG4gICAgdGhpcy5jb2x1bW5Tb3J0LmVtaXQoc29ydEV2ZW50KTtcblxuICAgIC8vIGlmIHRhYmxlIGlzIG5vdCBsYXp5IGxvYWRlZCAoc29ydGluZyBpcyB0aGVuIGhhbmRsZWQgc2VydmVyLXNpZGUpLi4uXG4gICAgaWYgKCF0aGlzLnRhYmxlSW5mbz8ubGF6eUxvYWRlZCkge1xuICAgICAgLy8gLi4udXBkYXRlIHNvcnQgb3JkZXJcbiAgICAgIHRoaXMuc29ydE9yZGVyID0gbmV3T3JkZXI7XG4gICAgfVxuICB9XG5cbiAgY29sdW1uT3JkZXIgPSAoXG4gICAgYTogS2V5VmFsdWU8c3RyaW5nLCBUYWJsZUNvbHVtbj4sXG4gICAgYjogS2V5VmFsdWU8c3RyaW5nLCBUYWJsZUNvbHVtbj5cbiAgKTogbnVtYmVyID0+IHtcbiAgICByZXR1cm4gKGEudmFsdWUub3JkZXIgfHwgMCkgLSAoYi52YWx1ZS5vcmRlciB8fCAwKTtcbiAgfTtcblxuICBuZXN0ZWRWYWx1ZShcbiAgICBvYmplY3Q6IGFueSxcbiAgICBtYXBUbzogc3RyaW5nLFxuICAgIG1pc3NpbmdWYWx1ZTogc3RyaW5nIHwgbnVtYmVyIHwgbnVsbCA9IG51bGxcbiAgKTogdW5rbm93biB7XG4gICAgY29uc3QgbGV2ZWxzID0gbWFwVG8uc3BsaXQoJy4nKTtcbiAgICByZXR1cm4gbGV2ZWxzLnJlZHVjZShcbiAgICAgIChwcmV2aW91c1ZhbHVlLCBjdXJyZW50VmFsdWUsIGluZGV4KSA9PlxuICAgICAgICBwcmV2aW91c1ZhbHVlW2N1cnJlbnRWYWx1ZV0gfHxcbiAgICAgICAgKGluZGV4ID09PSBsZXZlbHMubGVuZ3RoIC0gMSA/IG1pc3NpbmdWYWx1ZSA6IHt9KSxcbiAgICAgIG9iamVjdFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIF91bnN1YnNjcmliZUZyb21LZXlib2FyZEV2ZW50cyQgPSBuZXcgU3ViamVjdCgpO1xuICBwcml2YXRlIF9rZXlib2FyZEFycm93RXZlbnQkID0gZnJvbUV2ZW50PEtleWJvYXJkRXZlbnQ+KFxuICAgIGRvY3VtZW50LFxuICAgICdrZXlkb3duJ1xuICApLnBpcGUoXG4gICAgZmlsdGVyKFxuICAgICAgKGV2ZW50KSA9PlxuICAgICAgICBbLi4udGhpcy5fbmF2aWdhdGlvbktleXMsIC4uLnRoaXMuX3NlbGVjdEtleXNdLmluZGV4T2YoZXZlbnQua2V5KSA+IC0xXG4gICAgKVxuICApO1xuXG4gIHByb3RlY3RlZCBsaXN0ZW5Ub0tleWJvYXJkRXZlbnRzKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5fdGFibGVDb25maWc/LmFjdGl2YXRlUm93T25LZXlib2FyZE5hdmlnYXRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLl91bnN1YnNjcmliZUZyb21LZXlib2FyZEV2ZW50cyQubmV4dCh0cnVlKTtcbiAgICB0aGlzLl9rZXlib2FyZEFycm93RXZlbnQkXG4gICAgICAucGlwZShcbiAgICAgICAgd2l0aExhdGVzdEZyb20oXG4gICAgICAgICAgdGhpcy5kYXRhJCxcbiAgICAgICAgICB0aGlzLmN1cnJlbnRQYWdpbmF0aW9uSW5kZXgkLFxuICAgICAgICAgIHRoaXMudGFibGVJbmZvJFxuICAgICAgICApLFxuICAgICAgICB0YWtlVW50aWwodGhpcy5fdW5zdWJzY3JpYmVGcm9tS2V5Ym9hcmRFdmVudHMkKSxcbiAgICAgICAgdGFrZVVudGlsKHRoaXMudW5zdWJzY3JpYmUkKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoW2V2ZW50LCByb3dzLCBjdXJyZW50UGFnZSwgdGFibGVJbmZvXSkgPT4ge1xuICAgICAgICBjb25zdCBzZWxlY3RFdmVudCA9IHRoaXMuX3NlbGVjdEtleXMuaW5jbHVkZXMoZXZlbnQua2V5KTtcbiAgICAgICAgaWYgKHNlbGVjdEV2ZW50ICYmIHRoaXMuYWN0aXZlUm93SW5kZXggIT09IG51bGwpIHtcbiAgICAgICAgICBjb25zdCByb3dJbmRleCA9XG4gICAgICAgICAgICB0aGlzLmFjdGl2ZVJvd0luZGV4ICsgY3VycmVudFBhZ2UgKiAodGFibGVJbmZvPy5wYWdlU2l6ZSA/PyAwKTtcbiAgICAgICAgICB0aGlzLl9yb3dBY3RpdmUocm93c1tyb3dJbmRleF0sIHJvd0luZGV4LCBldmVudCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbmF2aWdhdGlvbkV2ZW50ID0gdGhpcy5fbmF2aWdhdGlvbktleXMuaW5jbHVkZXMoZXZlbnQua2V5KTtcbiAgICAgICAgaWYgKG5hdmlnYXRpb25FdmVudCkge1xuICAgICAgICAgIHRoaXMuX2hhbmRsZU5hdmlnYXRpb25FdmVudChldmVudCwgcm93cywgY3VycmVudFBhZ2UsIHRhYmxlSW5mbyk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG4gIHVuc3Vic2NyaWJlRnJvbUtleWJvYXJkRXZlbnRzKHRhYmxlUmVmOiBIVE1MVGFibGVFbGVtZW50KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLl90YWJsZUNvbmZpZz8uYWN0aXZhdGVSb3dPbktleWJvYXJkTmF2aWdhdGlvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBvbmx5IHVuc3Vic2NyaWJlIGlmIHRhYmxlIGlzIG5vdCBmb2N1c2VkXG4gICAgaWYgKHRhYmxlUmVmICE9PSBkb2N1bWVudC5hY3RpdmVFbGVtZW50KSB7XG4gICAgICBpZiAodGhpcy5fdGFibGVDb25maWc/LmFjdGl2YXRlUm93T25Ib3Zlcikge1xuICAgICAgICAvLyB1bnNldCBhY3RpdmUgcm93XG4gICAgICAgIHRoaXMuYWN0aXZhdGVSb3cobnVsbCk7XG4gICAgICB9XG4gICAgICB0aGlzLl91bnN1YnNjcmliZUZyb21LZXlib2FyZEV2ZW50cyQubmV4dCh0cnVlKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9oYW5kbGVOYXZpZ2F0aW9uRXZlbnQoXG4gICAgZXZlbnQ6IEtleWJvYXJkRXZlbnQsXG4gICAgcm93czogYW55W10sXG4gICAgY3VycmVudFBhZ2U6IG51bWJlcixcbiAgICB0YWJsZUluZm86IGFueVxuICApOiB2b2lkIHtcbiAgICBjb25zdCBoYXNQYWdpbmF0aW9uID0gKHRhYmxlSW5mbz8ucGFnZVRvdGFsIHx8IDApID4gMSAmJiB0YWJsZUluZm87XG4gICAgY29uc3QgbGFzdFJvd0luZGV4ID0gcm93cy5sZW5ndGggLSAxO1xuICAgIGxldCBuZXdJbmRleCA9IHRoaXMuYWN0aXZlUm93SW5kZXg7XG4gICAgbGV0IGluZGV4TW9kaWZpZXIgPSAwO1xuXG4gICAgaWYgKGV2ZW50LmtleSA9PT0gJ0hvbWUnKSB7XG4gICAgICB0aGlzLnBhZ2luYXRpb25JbmRleCA9IDA7XG4gICAgICB0aGlzLmFjdGl2YXRlUm93KDAsIGV2ZW50KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoZXZlbnQua2V5ID09PSAnRW5kJykge1xuICAgICAgY29uc3QgaW5kZXhPZkxhc3RSZWNvcmQgPSBoYXNQYWdpbmF0aW9uXG4gICAgICAgID8gcm93cy5sZW5ndGggLSAodGFibGVJbmZvLnBhZ2VUb3RhbCAtIDEpICogdGFibGVJbmZvLnBhZ2VTaXplIC0gMVxuICAgICAgICA6IGxhc3RSb3dJbmRleDtcbiAgICAgIGlmICh0YWJsZUluZm8/LnBhZ2VUb3RhbCkge1xuICAgICAgICB0aGlzLnBhZ2luYXRpb25JbmRleCA9IHRhYmxlSW5mby5wYWdlVG90YWwgLSAxO1xuICAgICAgfVxuICAgICAgdGhpcy5hY3RpdmF0ZVJvdyhpbmRleE9mTGFzdFJlY29yZCwgZXZlbnQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChldmVudC5rZXkgPT09ICdBcnJvd0Rvd24nKSB7XG4gICAgICBpbmRleE1vZGlmaWVyID0gMTtcbiAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gJ0Fycm93VXAnKSB7XG4gICAgICBpbmRleE1vZGlmaWVyID0gLTE7XG4gICAgfVxuXG4gICAgaWYgKG5ld0luZGV4ID09PSBudWxsKSB7XG4gICAgICBuZXdJbmRleCA9IDA7XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIG5ld0luZGV4ICsgaW5kZXhNb2RpZmllciA+PSAwICYmXG4gICAgICBuZXdJbmRleCArIGluZGV4TW9kaWZpZXIgPD0gbGFzdFJvd0luZGV4XG4gICAgKSB7XG4gICAgICBuZXdJbmRleCA9IG5ld0luZGV4ICsgaW5kZXhNb2RpZmllcjtcbiAgICB9XG5cbiAgICBpZiAoaGFzUGFnaW5hdGlvbiAmJiB0YWJsZUluZm8/LnBhZ2VTaXplKSB7XG4gICAgICBjb25zdCBpc05vdExhc3RQYWdlID0gY3VycmVudFBhZ2UgKyAxIDwgdGFibGVJbmZvLnBhZ2VUb3RhbDtcbiAgICAgIGNvbnN0IHJlY29yZHNPbkxhc3RQYWdlID1cbiAgICAgICAgcm93cy5sZW5ndGggLSAodGFibGVJbmZvLnBhZ2VUb3RhbCAtIDEpICogdGFibGVJbmZvLnBhZ2VTaXplIC0gMTtcbiAgICAgIGNvbnN0IG1heEluZGV4ID0gaXNOb3RMYXN0UGFnZVxuICAgICAgICA/IHRhYmxlSW5mbz8ucGFnZVNpemUgLSAxXG4gICAgICAgIDogcmVjb3Jkc09uTGFzdFBhZ2U7XG5cbiAgICAgIGlmIChldmVudC5rZXkgPT09ICdBcnJvd0xlZnQnICYmIGN1cnJlbnRQYWdlID4gMCkge1xuICAgICAgICB0aGlzLnBhZ2luYXRpb25JbmRleCA9IGN1cnJlbnRQYWdlIC0gMTtcbiAgICAgICAgdGhpcy5hY3RpdmF0ZVJvdyhuZXdJbmRleCwgZXZlbnQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gJ0Fycm93UmlnaHQnICYmIGlzTm90TGFzdFBhZ2UpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGN1cnJlbnRQYWdlICsgMSA9PT0gdGFibGVJbmZvLnBhZ2VUb3RhbCAtIDEgJiZcbiAgICAgICAgICBuZXdJbmRleCA+IHJlY29yZHNPbkxhc3RQYWdlXG4gICAgICAgICkge1xuICAgICAgICAgIHRoaXMuYWN0aXZhdGVSb3cocmVjb3Jkc09uTGFzdFBhZ2UsIGV2ZW50KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnBhZ2luYXRpb25JbmRleCA9IGN1cnJlbnRQYWdlICsgMTtcbiAgICAgICAgdGhpcy5hY3RpdmF0ZVJvdyhuZXdJbmRleCwgZXZlbnQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgY3VycmVudFBhZ2UgPiAwICYmXG4gICAgICAgIGluZGV4TW9kaWZpZXIgPCAwICYmXG4gICAgICAgIG5ld0luZGV4ICsgaW5kZXhNb2RpZmllciA8PSBsYXN0Um93SW5kZXggJiZcbiAgICAgICAgKHRoaXMuYWN0aXZlUm93SW5kZXggfHwgMCkgKyBpbmRleE1vZGlmaWVyIDwgMFxuICAgICAgKSB7XG4gICAgICAgIC8vIHNldCBsYXN0IHJvdyBvZiBwcmV2aW91cyBwYWdlIGFzIGFjdGl2ZVxuICAgICAgICB0aGlzLmFjdGl2YXRlUm93KHRhYmxlSW5mbz8ucGFnZVNpemUgLSAxLCBldmVudCk7XG4gICAgICAgIHRoaXMucGFnaW5hdGlvbkluZGV4ID0gY3VycmVudFBhZ2UgLSAxO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBhZ2VJbmRleCA9IG5ld0luZGV4ICUgdGFibGVJbmZvPy5wYWdlU2l6ZTtcblxuICAgICAgaWYgKG5ld0luZGV4ID4gbWF4SW5kZXggJiYgY3VycmVudFBhZ2UgKyAxIDwgdGFibGVJbmZvLnBhZ2VUb3RhbCkge1xuICAgICAgICB0aGlzLnBhZ2luYXRpb25JbmRleCA9IGN1cnJlbnRQYWdlICsgMTtcbiAgICAgIH1cbiAgICAgIHRoaXMuYWN0aXZhdGVSb3cocGFnZUluZGV4ID4gbWF4SW5kZXggPyBtYXhJbmRleCA6IHBhZ2VJbmRleCwgZXZlbnQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuYWN0aXZhdGVSb3cobmV3SW5kZXgsIGV2ZW50KTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMudW5zdWJzY3JpYmUkLm5leHQodHJ1ZSk7XG4gICAgdGhpcy51bnN1YnNjcmliZSQuY29tcGxldGUoKTtcbiAgfVxufVxuIiwiPHRhYmxlXG4gIFtuZ0NsYXNzXT1cIih0YWJsZUNvbmZpZyQgfCBhc3luYyk/LmNsYXNzIHx8ICd0YWJsZSdcIlxuICBbY2xhc3MudGFibGUtbW9iaWxlXT1cIih0YWJsZUNvbmZpZyQgfCBhc3luYyk/Lm1vYmlsZUxheW91dFwiXG4gIFtjbGFzcy50YWJsZS1ob3Jpem9udGFsXT1cIih0YWJsZUNvbmZpZyQgfCBhc3luYyk/LnJvd3NcIlxuICBbY2xhc3MudGFibGUtbG9hZGluZ109XCJsb2FkaW5nJCB8IGFzeW5jXCJcbiAgW2NsYXNzLmd0LXN0aWNreS1yb3ctaGVhZGVyXT1cIlxuICAgICh0YWJsZUNvbmZpZyQgfCBhc3luYyk/LnN0aWNreUhlYWRlcnM/LnJvdyAmJiAodGFibGVDb25maWckIHwgYXN5bmMpPy5yb3dzXG4gIFwiXG4gIFtjbGFzcy5ndC1zdGlja3ktY29sdW1uLWhlYWRlcl09XCJcbiAgICAodGFibGVDb25maWckIHwgYXN5bmMpPy5zdGlja3lIZWFkZXJzPy5jb2x1bW5cbiAgXCJcbiAgW2F0dHIuYXJpYS1idXN5XT1cIihsb2FkaW5nJCB8IGFzeW5jKSA9PT0gdHJ1ZSA/IHRydWUgOiBudWxsXCJcbiAgW3RhYmluZGV4XT1cIih0YWJsZUNvbmZpZyQgfCBhc3luYyk/LmFjdGl2YXRlUm93T25LZXlib2FyZE5hdmlnYXRpb24gPyAwIDogLTFcIlxuICAjdGFibGVSZWZcbiAgKGZvY3VzKT1cImxpc3RlblRvS2V5Ym9hcmRFdmVudHMoKVwiXG4gIChmb2N1c291dCk9XCJ1bnN1YnNjcmliZUZyb21LZXlib2FyZEV2ZW50cyh0YWJsZVJlZilcIlxuICAobW91c2VlbnRlcik9XCJsaXN0ZW5Ub0tleWJvYXJkRXZlbnRzKClcIlxuICAobW91c2VsZWF2ZSk9XCJ1bnN1YnNjcmliZUZyb21LZXlib2FyZEV2ZW50cyh0YWJsZVJlZilcIlxuPlxuICA8dGhlYWQ+XG4gICAgPHRyXG4gICAgICAqbmdJZj1cIntcbiAgICAgICAgY29uZmlnOiAodGFibGVDb25maWckIHwgYXN5bmMpISxcbiAgICAgICAgaXNMb2FkaW5nOiBsb2FkaW5nJCB8IGFzeW5jXG4gICAgICB9IGFzIHRhYmxlXCJcbiAgICA+XG4gICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgdGFibGUuY29uZmlnPy5jb2x1bW5zIHwga2V5dmFsdWU6IGNvbHVtbk9yZGVyXCJcbiAgICAgID5cbiAgICAgICAgPHRoXG4gICAgICAgICAgKm5nSWY9XCIhY29sdW1uLnZhbHVlPy5oaWRkZW5cIlxuICAgICAgICAgIG5nQ2xhc3M9XCJ7eyAoY29sdW1uLmtleSB8IGRhc2hDYXNlKSArICctY29sdW1uJyB9fSB7e1xuICAgICAgICAgICAgY29sdW1uLnZhbHVlLmNsYXNzXG4gICAgICAgICAgfX1cIlxuICAgICAgICAgIFtjbGFzcy5kaXNhYmxlZF09XCJ0YWJsZS5pc0xvYWRpbmdcIlxuICAgICAgICAgIFthdHRyLmFyaWEtc29ydF09XCJzb3J0T3JkZXIkIHwgYXN5bmMgfCBzb3J0Q2xhc3M6IGNvbHVtbi5rZXk6J2FyaWEnXCJcbiAgICAgICAgICBbY2xhc3MuZ3Qtc29ydGFibGVdPVwidHJ1ZVwiXG4gICAgICAgICAgc2NvcGU9XCJjb2xcIlxuICAgICAgICA+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgKm5nSWY9XCJjb2x1bW4udmFsdWU/LnNvcnRhYmxlXCJcbiAgICAgICAgICAgIFthdHRyLmRhdGEtc29ydC1vcmRlcl09XCJcbiAgICAgICAgICAgICAgc29ydE9yZGVyJCB8IGFzeW5jIHwgc29ydENsYXNzOiBjb2x1bW4ua2V5OidvcmRlcidcbiAgICAgICAgICAgIFwiXG4gICAgICAgICAgICBjbGFzcz1cImd0LXNvcnRcIlxuICAgICAgICAgICAgKGNsaWNrKT1cIlxuICAgICAgICAgICAgICB0YWJsZS5pc0xvYWRpbmcgfHxcbiAgICAgICAgICAgICAgICAhY29sdW1uLnZhbHVlLnNvcnRhYmxlIHx8XG4gICAgICAgICAgICAgICAgc29ydEJ5S2V5KGNvbHVtbi5rZXksICRldmVudClcbiAgICAgICAgICAgIFwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJjb2x1bW4udmFsdWU/LmhlYWRlciAhPT0gZmFsc2VcIj57e1xuICAgICAgICAgICAgICBjb2x1bW4udmFsdWUuaGVhZGVyIHx8IGNvbHVtbi5rZXkgfCBjYXBpdGFsQ2FzZVxuICAgICAgICAgICAgfX08L3NwYW4+XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICpuZ0lmPVwiIWNvbHVtbi52YWx1ZT8uc29ydGFibGUgJiYgY29sdW1uLnZhbHVlPy5oZWFkZXIgIT09IGZhbHNlXCJcbiAgICAgICAgICAgID57eyBjb2x1bW4udmFsdWUuaGVhZGVyIHx8IGNvbHVtbi5rZXkgfCBjYXBpdGFsQ2FzZSB9fTwvc3BhblxuICAgICAgICAgID5cbiAgICAgICAgPC90aD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgICgodGFibGU/LmNvbmZpZz8ucm93cyB8IGtleXZhbHVlOiBjb2x1bW5PcmRlcikgfHwgW10pWzBdIGFzIGhlYWRlclJvd1xuICAgICAgICBcIlxuICAgICAgPlxuICAgICAgICA8dGhcbiAgICAgICAgICBjbGFzcz1cInJvdy1oZWFkZXJcIlxuICAgICAgICAgIFthdHRyLmFyaWEtc29ydF09XCJcbiAgICAgICAgICAgIHNvcnRPcmRlciQgfCBhc3luYyB8IHNvcnRDbGFzczogaGVhZGVyUm93LmtleTonYXJpYSdcbiAgICAgICAgICBcIlxuICAgICAgICAgIG5nQ2xhc3M9XCJ7eyBoZWFkZXJSb3cudmFsdWUuc29ydGFibGUgPyAnc29ydCAnIDogJycgfX0ge3tcbiAgICAgICAgICAgIHNvcnRPcmRlciQgfCBhc3luYyB8IHNvcnRDbGFzczogaGVhZGVyUm93LmtleVxuICAgICAgICAgIH19IHt7IChoZWFkZXJSb3cua2V5IHwgZGFzaENhc2UpICsgJy1jb2x1bW4nIH19XCJcbiAgICAgICAgICAoY2xpY2spPVwiXG4gICAgICAgICAgICB0YWJsZS5pc0xvYWRpbmcgfHxcbiAgICAgICAgICAgICAgIWhlYWRlclJvdy52YWx1ZS5zb3J0YWJsZSB8fFxuICAgICAgICAgICAgICBzb3J0QnlLZXkoaGVhZGVyUm93LmtleSwgJGV2ZW50KVxuICAgICAgICAgIFwiXG4gICAgICAgICAgc2NvcGU9XCJjb2xcIlxuICAgICAgICA+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImhlYWRlclJvdz8udmFsdWU/LmhlYWRlciAhPT0gZmFsc2VcIj57e1xuICAgICAgICAgICAgaGVhZGVyUm93Py52YWx1ZT8uaGVhZGVyIHx8IGhlYWRlclJvdy5rZXkgfCBjYXBpdGFsQ2FzZVxuICAgICAgICAgIH19PC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvdGg+XG4gICAgICAgIDx0aFxuICAgICAgICAgICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgKCh0YWJsZSQgfCBhc3luYyk/LmRhdGEgfHwgW10pWzBdXCJcbiAgICAgICAgICBuZ0NsYXNzPVwie3sgaGVhZGVyUm93LnZhbHVlLmNsYXNzIH19XCJcbiAgICAgICAgPlxuICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cIlxuICAgICAgICAgICAgICAodGFibGUuY29uZmlnLnJvd3MgfHwge30pW2hlYWRlclJvdy5rZXldLnRlbXBsYXRlUmVmXG4gICAgICAgICAgICAgICAgPyB0ZW1wbGF0ZVJlZlxuICAgICAgICAgICAgICAgIDogKHRhYmxlLmNvbmZpZy5yb3dzIHx8IHt9KVtoZWFkZXJSb3cua2V5XS50cmFuc2Zvcm1cbiAgICAgICAgICAgICAgICA/IHRyYW5zZm9ybURhdGFcbiAgICAgICAgICAgICAgICA6IHJhd0RhdGFcbiAgICAgICAgICAgIFwiXG4gICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwie1xuICAgICAgICAgICAgICByb3c6IGNvbHVtbixcbiAgICAgICAgICAgICAgY29sdW1uOiBoZWFkZXJSb3csXG4gICAgICAgICAgICAgIHRyYW5zZm9ybTogKHRhYmxlLmNvbmZpZy5yb3dzIHx8IHt9KVtoZWFkZXJSb3cua2V5XS50cmFuc2Zvcm0sXG4gICAgICAgICAgICAgIHRlbXBsYXRlUmVmOiAodGFibGUuY29uZmlnLnJvd3MgfHwge30pW2hlYWRlclJvdy5rZXldLnRlbXBsYXRlUmVmLFxuICAgICAgICAgICAgICBpbmRleDogMFxuICAgICAgICAgICAgfVwiXG4gICAgICAgICAgPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L3RoPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC90cj5cbiAgPC90aGVhZD5cbiAgPHRib2R5ICpuZ0lmPVwibG9hZGluZyQgfCBhc3luYzsgZWxzZSB0YWJsZUNvbnRlbnRcIj5cbiAgICA8dHI+XG4gICAgICA8dGQgY2xhc3M9XCJwLTBcIiBbY29sU3Bhbl09XCJjb2xzcGFuJCB8IGFzeW5jXCI+XG4gICAgICAgIDxuZy1jb250ZW50IHNlbGVjdD1cIi50YWJsZS1sb2FkaW5nXCI+PC9uZy1jb250ZW50PlxuICAgICAgPC90ZD5cbiAgICA8L3RyPlxuICA8L3Rib2R5PlxuICA8dGZvb3QgKm5nSWY9XCIodGFibGUkIHwgYXN5bmMpISBhcyB0YWJsZVwiPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJ0YWJsZS5kYXRhLmxlbmd0aCA+IDAgJiYgIShsb2FkaW5nJCB8IGFzeW5jKVwiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIihjYWxjdWxhdGlvbnMkIHwgYXN5bmMpISBhcyBjYWxjdWxhdGlvbnNcIj5cbiAgICAgICAgPHRyXG4gICAgICAgICAgKm5nRm9yPVwibGV0IGNhbGN1bGF0aW9uIG9mIGNhbGN1bGF0aW9ucy5jYWxjdWxhdGlvbnM7IGxldCBpID0gaW5kZXhcIlxuICAgICAgICA+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgKm5nSWY9XCJ7XG4gICAgICAgICAgICAgIHNob3dIZWFkZXI6IChjb2xzcGFuJCB8IGFzeW5jKSAhPT0gKGZvb3RlckNvbHNwYW4kIHwgYXN5bmMpXG4gICAgICAgICAgICB9IGFzIGZvb3RlclJvd1wiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHRoXG4gICAgICAgICAgICAgICpuZ0lmPVwiZm9vdGVyUm93LnNob3dIZWFkZXJcIlxuICAgICAgICAgICAgICBbY29sU3Bhbl09XCJcbiAgICAgICAgICAgICAgICAoKGNvbHNwYW4kIHwgYXN5bmMpIHx8IDApIC0gKChmb290ZXJDb2xzcGFuJCB8IGFzeW5jKSB8fCAwKVxuICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICBzY29wZT1cInJvd1wiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAqbmdJZj1cInRhYmxlLmNvbmZpZz8uZm9vdGVyPy5oZWFkZXJzPy5bY2FsY3VsYXRpb25dIGFzIHNob3dIZWFkZXJcIlxuICAgICAgICAgICAgICAgID57e3Nob3dIZWFkZXIgPT09IHRydWUgPyAoY2FsY3VsYXRpb24gfCBjYXBpdGFsQ2FzZSk6IHRhYmxlLmNvbmZpZy5mb290ZXI/LmhlYWRlcnM/LltjYWxjdWxhdGlvbl19fVxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICpuZ0Zvcj1cIlxuICAgICAgICAgICAgICAgIGxldCBjb2x1bW4gb2YgdGFibGUuY29uZmlnPy5jb2x1bW5zIHwga2V5dmFsdWU6IGNvbHVtbk9yZGVyXG4gICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDx0ZFxuICAgICAgICAgICAgICAgICpuZ0lmPVwiXG4gICAgICAgICAgICAgICAgICAhY29sdW1uLnZhbHVlPy5oaWRkZW4gJiYgY2FsY3VsYXRpb25zLmNhbGN1bGF0ZWRbY29sdW1uLmtleV1cbiAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgIG5nQ2xhc3M9XCJ7eyAoY29sdW1uLmtleSB8IGRhc2hDYXNlKSArICctY29sdW1uJyB9fSB7e1xuICAgICAgICAgICAgICAgICAgY29sdW1uLnZhbHVlLmNsYXNzXG4gICAgICAgICAgICAgICAgfX1cIlxuICAgICAgICAgICAgICAgIFthdHRyLmRhdGEtaGVhZGVyXT1cIlxuICAgICAgICAgICAgICAgICAgIWZvb3RlclJvdy5zaG93SGVhZGVyICYmIHRhYmxlLmNvbmZpZy5mb290ZXI/LmhlYWRlcnM/LltjYWxjdWxhdGlvbl1cbiAgICAgICAgICAgICAgICAgICAgPyB0YWJsZS5jb25maWcuZm9vdGVyPy5oZWFkZXJzPy5bY2FsY3VsYXRpb25dID09PSB0cnVlID8gKGNhbGN1bGF0aW9uIHwgY2FwaXRhbENhc2UpIDogdGFibGUuY29uZmlnLmZvb3Rlcj8uaGVhZGVycz8uW2NhbGN1bGF0aW9uXVxuICAgICAgICAgICAgICAgICAgICA6IG51bGxcbiAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgIFthdHRyLmRhdGEtbGFiZWxdPVwiXG4gICAgICAgICAgICAgICAgICB0YWJsZS5jb25maWcubW9iaWxlTGF5b3V0ICYmIGNvbHVtbi52YWx1ZS5tb2JpbGVIZWFkZXJcbiAgICAgICAgICAgICAgICAgICAgPyBjb2x1bW4udmFsdWUubW9iaWxlSGVhZGVyICE9PSB0cnVlXG4gICAgICAgICAgICAgICAgICAgICAgPyBjb2x1bW4udmFsdWUubW9iaWxlSGVhZGVyXG4gICAgICAgICAgICAgICAgICAgICAgOiAoY29sdW1uLnZhbHVlLmhlYWRlciB8fCBjb2x1bW4ua2V5IHwgY2FwaXRhbENhc2UpXG4gICAgICAgICAgICAgICAgICAgIDogbnVsbFxuICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLmd0LW5vLWNvbnRlbnRdPVwiXG4gICAgICAgICAgICAgICAgICAhY2FsY3VsYXRpb25zLmNhbGN1bGF0ZWRbY29sdW1uLmtleV1bY2FsY3VsYXRpb25dXG4gICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cIlxuICAgICAgICAgICAgICAgICAgICAodGFibGUuY29uZmlnLmNvbHVtbnMgfHwge30pW2NvbHVtbi5rZXldLnRlbXBsYXRlUmVmXG4gICAgICAgICAgICAgICAgICAgICAgPyB0ZW1wbGF0ZVJlZlxuICAgICAgICAgICAgICAgICAgICAgIDogKHRhYmxlLmNvbmZpZy5jb2x1bW5zIHx8IHt9KVtjb2x1bW4ua2V5XS50cmFuc2Zvcm1cbiAgICAgICAgICAgICAgICAgICAgICA/IHRyYW5zZm9ybUZvb3RlclxuICAgICAgICAgICAgICAgICAgICAgIDogcmF3Rm9vdGVyXG4gICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cIntcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGNhbGN1bGF0aW9ucy5jYWxjdWxhdGVkW2NvbHVtbi5rZXldW2NhbGN1bGF0aW9uXSxcbiAgICAgICAgICAgICAgICAgICAgcm93OiBjYWxjdWxhdGlvbnMuY2FsY3VsYXRlZFtjb2x1bW4ua2V5XSxcbiAgICAgICAgICAgICAgICAgICAgY29sdW1uOiBjYWxjdWxhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgdGVtcGxhdGVSZWY6ICh0YWJsZS5jb25maWcuY29sdW1ucyB8fCB7fSlbY29sdW1uLmtleV1cbiAgICAgICAgICAgICAgICAgICAgICAudGVtcGxhdGVSZWYsXG4gICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybTogKHRhYmxlLmNvbmZpZy5jb2x1bW5zIHx8IHt9KVtjb2x1bW4ua2V5XVxuICAgICAgICAgICAgICAgICAgICAgIC50cmFuc2Zvcm1cbiAgICAgICAgICAgICAgICAgIH1cIlxuICAgICAgICAgICAgICAgID48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L3RyPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9uZy1jb250YWluZXI+XG4gIDwvdGZvb3Q+XG48L3RhYmxlPlxuPG5nLXRlbXBsYXRlICN0YWJsZUNvbnRlbnQ+XG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCIodGFibGUkIHwgYXN5bmMpISBhcyB0YWJsZVwiPlxuICAgIDx0Ym9keSAqbmdJZj1cIih0YWJsZSEuZGF0YSFbMF0gfHwgdGFibGUhLmRhdGEhKS5sZW5ndGggPiAwOyBlbHNlIG5vRGF0YVwiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInRhYmxlLmNvbmZpZy5jb2x1bW5zXCI+XG4gICAgICAgIDx0clxuICAgICAgICAgICpuZ0Zvcj1cIlxuICAgICAgICAgICAgbGV0IHJvdyBvZiB0YWJsZSEuZGF0YSFbXG4gICAgICAgICAgICAgIHRhYmxlLmluZm8ubGF6eUxvYWRlZCA/IDAgOiAoY3VycmVudFBhZ2luYXRpb25JbmRleCQgfCBhc3luYykgfHwgMFxuICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIHRyYWNrQnk6IHRyYWNrUm93QnlGbjtcbiAgICAgICAgICAgIGxldCBpID0gaW5kZXhcbiAgICAgICAgICBcIlxuICAgICAgICAgIFthdHRyLmlkXT1cIid0YWJsZVJvd18nICsgaVwiXG4gICAgICAgICAgKGNsaWNrKT1cInRhYmxlPy5jb25maWc/LnJvd0NsaWNrICYmIF9yb3dDbGljayhyb3csIGksICRldmVudClcIlxuICAgICAgICAgIChtb3VzZWVudGVyKT1cIlxuICAgICAgICAgICAgdGFibGU/LmNvbmZpZz8uYWN0aXZhdGVSb3dPbkhvdmVyICYmIF9hY3RpdmF0ZVJvdyhyb3csIGksICRldmVudClcbiAgICAgICAgICBcIlxuICAgICAgICAgIChtb3VzZWxlYXZlKT1cIlxuICAgICAgICAgICAgdGFibGU/LmNvbmZpZz8uYWN0aXZhdGVSb3dPbkhvdmVyICYmXG4gICAgICAgICAgICAgIF9hY3RpdmF0ZVJvdyhudWxsLCBudWxsLCAkZXZlbnQpXG4gICAgICAgICAgXCJcbiAgICAgICAgICBbbmdDbGFzc109XCJbXG4gICAgICAgICAgICAhIWlzUm93U2VsZWN0ZWRGblxuICAgICAgICAgICAgICA/IChyb3dcbiAgICAgICAgICAgICAgICB8IHJvd1NlbGVjdGlvblxuICAgICAgICAgICAgICAgICAgOiBzZWxlY3Rpb25cbiAgICAgICAgICAgICAgICAgIDogaXNSb3dTZWxlY3RlZEZuXG4gICAgICAgICAgICAgICAgICA6IGN1c3RvbUNsYXNzZXMuc2VsZWN0ZWRSb3cpXG4gICAgICAgICAgICAgIDogJycsXG4gICAgICAgICAgICAocm93QWN0aXZlJCB8IGFzeW5jKT8uaW5kZXggPT09IGkgPyBjdXN0b21DbGFzc2VzLmFjdGl2ZVJvdyA6ICcnXG4gICAgICAgICAgXVwiXG4gICAgICAgID5cbiAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIHRhYmxlLmNvbmZpZz8uY29sdW1ucyB8IGtleXZhbHVlOiBjb2x1bW5PcmRlclwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHRkXG4gICAgICAgICAgICAgICpuZ0lmPVwiIWNvbHVtbi52YWx1ZT8uaGlkZGVuXCJcbiAgICAgICAgICAgICAgbmdDbGFzcz1cInt7IChjb2x1bW4ua2V5IHwgZGFzaENhc2UpICsgJy1jb2x1bW4nIH19IHt7XG4gICAgICAgICAgICAgICAgY29sdW1uLnZhbHVlLmNsYXNzXG4gICAgICAgICAgICAgIH19XCJcbiAgICAgICAgICAgICAgW2F0dHIuZGF0YS1sYWJlbF09XCJcbiAgICAgICAgICAgICAgICB0YWJsZS5jb25maWcubW9iaWxlTGF5b3V0ICYmIGNvbHVtbi52YWx1ZS5tb2JpbGVIZWFkZXJcbiAgICAgICAgICAgICAgICAgID8gY29sdW1uLnZhbHVlLm1vYmlsZUhlYWRlciAhPT0gdHJ1ZVxuICAgICAgICAgICAgICAgICAgICA/IGNvbHVtbi52YWx1ZS5tb2JpbGVIZWFkZXJcbiAgICAgICAgICAgICAgICAgICAgOiAoY29sdW1uLnZhbHVlLmhlYWRlciB8fCBjb2x1bW4ua2V5IHwgY2FwaXRhbENhc2UpXG4gICAgICAgICAgICAgICAgICA6IG51bGxcbiAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cIlxuICAgICAgICAgICAgICAgICAgKHNlYXJjaEJ5JCB8IGFzeW5jKSAmJlxuICAgICAgICAgICAgICAgICAgISh0YWJsZS5jb25maWcuY29sdW1ucyB8fCB7fSlbY29sdW1uLmtleV0udGVtcGxhdGVSZWZcbiAgICAgICAgICAgICAgICAgICAgPyBoaWdobGlnaHRlZFxuICAgICAgICAgICAgICAgICAgICA6ICh0YWJsZS5jb25maWcuY29sdW1ucyB8fCB7fSlbY29sdW1uLmtleV0udGVtcGxhdGVSZWZcbiAgICAgICAgICAgICAgICAgICAgPyB0ZW1wbGF0ZVJlZlxuICAgICAgICAgICAgICAgICAgICA6ICh0YWJsZS5jb25maWcuY29sdW1ucyB8fCB7fSlbY29sdW1uLmtleV0udHJhbnNmb3JtXG4gICAgICAgICAgICAgICAgICAgID8gdHJhbnNmb3JtRGF0YVxuICAgICAgICAgICAgICAgICAgICA6IHJhd0RhdGFcbiAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7XG4gICAgICAgICAgICAgICAgICByb3c6IHJvdyxcbiAgICAgICAgICAgICAgICAgIGNvbHVtbjogY29sdW1uLFxuICAgICAgICAgICAgICAgICAgc2VhcmNoOiAoc2VhcmNoQnkkIHwgYXN5bmMpLFxuICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtOiAodGFibGUuY29uZmlnLmNvbHVtbnMgfHwge30pW2NvbHVtbi5rZXldLnRyYW5zZm9ybSxcbiAgICAgICAgICAgICAgICAgIHRlbXBsYXRlUmVmOiAodGFibGUuY29uZmlnLmNvbHVtbnMgfHwge30pW2NvbHVtbi5rZXldXG4gICAgICAgICAgICAgICAgICAgIC50ZW1wbGF0ZVJlZixcbiAgICAgICAgICAgICAgICAgIGluZGV4OiBpLFxuICAgICAgICAgICAgICAgICAgZGF0YTogdGFibGUuZGF0YVtcbiAgICAgICAgICAgICAgICAgICAgdGFibGUuaW5mby5sYXp5TG9hZGVkXG4gICAgICAgICAgICAgICAgICAgICAgPyAwXG4gICAgICAgICAgICAgICAgICAgICAgOiAoY3VycmVudFBhZ2luYXRpb25JbmRleCQgfCBhc3luYykgfHwgMFxuICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgIH1cIlxuICAgICAgICAgICAgICA+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L3RyPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwidGFibGUuY29uZmlnLnJvd3NcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICpuZ0Zvcj1cIlxuICAgICAgICAgICAgbGV0IHJvdyBvZiB0YWJsZT8uY29uZmlnPy5yb3dzIHwga2V5dmFsdWU6IGNvbHVtbk9yZGVyIHwgc2xpY2U6IDE7XG4gICAgICAgICAgICBsZXQgaSA9IGluZGV4XG4gICAgICAgICAgXCJcbiAgICAgICAgPlxuICAgICAgICAgIDx0clxuICAgICAgICAgICAgKm5nSWY9XCIhcm93LnZhbHVlPy5oaWRkZW5cIlxuICAgICAgICAgICAgW2F0dHIuaWRdPVwiJ3RhYmxlUm93XycgKyBpXCJcbiAgICAgICAgICAgIG5nQ2xhc3M9XCJ7eyAocm93LmtleSB8IGRhc2hDYXNlKSArICctcm93JyB9fVwiXG4gICAgICAgICAgICAoY2xpY2spPVwidGFibGU/LmNvbmZpZz8ucm93Q2xpY2sgJiYgX3Jvd0NsaWNrKHJvdywgaSwgJGV2ZW50KVwiXG4gICAgICAgICAgICAobW91c2VlbnRlcik9XCJcbiAgICAgICAgICAgICAgdGFibGU/LmNvbmZpZz8uYWN0aXZhdGVSb3dPbkhvdmVyICYmIF9hY3RpdmF0ZVJvdyhyb3csIGksICRldmVudClcbiAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAobW91c2VsZWF2ZSk9XCJcbiAgICAgICAgICAgICAgdGFibGU/LmNvbmZpZz8uYWN0aXZhdGVSb3dPbkhvdmVyICYmXG4gICAgICAgICAgICAgICAgX2FjdGl2YXRlUm93KG51bGwsIG51bGwsICRldmVudClcbiAgICAgICAgICAgIFwiXG4gICAgICAgICAgICBbbmdDbGFzc109XCJbXG4gICAgICAgICAgICAgICEhaXNSb3dTZWxlY3RlZEZuXG4gICAgICAgICAgICAgICAgPyAocm93XG4gICAgICAgICAgICAgICAgICB8IHJvd1NlbGVjdGlvblxuICAgICAgICAgICAgICAgICAgICA6IHNlbGVjdGlvblxuICAgICAgICAgICAgICAgICAgICA6IGlzUm93U2VsZWN0ZWRGblxuICAgICAgICAgICAgICAgICAgICA6IGN1c3RvbUNsYXNzZXMuc2VsZWN0ZWRSb3cpXG4gICAgICAgICAgICAgICAgOiAnJyxcbiAgICAgICAgICAgICAgKHJvd0FjdGl2ZSQgfCBhc3luYyk/LmluZGV4ID09PSBpID8gY3VzdG9tQ2xhc3Nlcy5hY3RpdmVSb3cgOiAnJ1xuICAgICAgICAgICAgXVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHRoIGNsYXNzPVwicm93LWhlYWRlclwiIHNjb3BlPVwicm93XCI+XG4gICAgICAgICAgICAgIHt7IHJvdy52YWx1ZS5oZWFkZXIgfHwgcm93LmtleSB8IGNhcGl0YWxDYXNlIH19XG4gICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgPHRkXG4gICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgKHRhYmxlPy5kYXRhIHx8IFtdKVswXTsgbGV0IHkgPSBpbmRleFwiXG4gICAgICAgICAgICAgIG5nQ2xhc3M9XCJ7eyByb3cudmFsdWUuY2xhc3MgfX1cIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwiXG4gICAgICAgICAgICAgICAgICAodGFibGUuY29uZmlnLnJvd3MgfHwge30pW3Jvdy5rZXldLnRlbXBsYXRlUmVmXG4gICAgICAgICAgICAgICAgICAgID8gdGVtcGxhdGVSZWZcbiAgICAgICAgICAgICAgICAgICAgOiAodGFibGUuY29uZmlnLnJvd3MgfHwge30pW3Jvdy5rZXldLnRyYW5zZm9ybVxuICAgICAgICAgICAgICAgICAgICA/IHRyYW5zZm9ybURhdGFcbiAgICAgICAgICAgICAgICAgICAgOiByYXdEYXRhXG4gICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwie1xuICAgICAgICAgICAgICAgICAgcm93OiBjb2x1bW4sXG4gICAgICAgICAgICAgICAgICBjb2x1bW46IHJvdyxcbiAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybTogKHRhYmxlLmNvbmZpZy5yb3dzIHx8IHt9KVtyb3cua2V5XS50cmFuc2Zvcm0sXG4gICAgICAgICAgICAgICAgICB0ZW1wbGF0ZVJlZjogKHRhYmxlLmNvbmZpZy5yb3dzIHx8IHt9KVtyb3cua2V5XS50ZW1wbGF0ZVJlZixcbiAgICAgICAgICAgICAgICAgIGluZGV4OiB0YWJsZS5jb25maWcucm93cyA/IHkgOiBpLFxuICAgICAgICAgICAgICAgICAgZGF0YTogdGFibGUuZGF0YVtcbiAgICAgICAgICAgICAgICAgICAgdGFibGUuaW5mby5sYXp5TG9hZGVkXG4gICAgICAgICAgICAgICAgICAgICAgPyAwXG4gICAgICAgICAgICAgICAgICAgICAgOiAoY3VycmVudFBhZ2luYXRpb25JbmRleCQgfCBhc3luYykgfHwgMFxuICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgIH1cIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICA8L3RyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvdGJvZHk+XG4gIDwvbmctY29udGFpbmVyPlxuPC9uZy10ZW1wbGF0ZT5cbjxuZy10ZW1wbGF0ZSAjbm9EYXRhPlxuICA8dGJvZHk+XG4gICAgPHRyPlxuICAgICAgPHRkIGNsYXNzPVwicC0wXCIgW2NvbFNwYW5dPVwiY29sc3BhbiQgfCBhc3luY1wiPlxuICAgICAgICA8bmctY29udGVudCBzZWxlY3Q9XCIudGFibGUtbm8tZGF0YVwiPjwvbmctY29udGVudD5cbiAgICAgIDwvdGQ+XG4gICAgPC90cj5cbiAgPC90Ym9keT5cbjwvbmctdGVtcGxhdGU+XG48bmctdGVtcGxhdGVcbiAgI2hpZ2hsaWdodGVkXG4gIGxldC1yb3c9XCJyb3dcIlxuICBsZXQtY29sdW1uPVwiY29sdW1uXCJcbiAgbGV0LXNlYXJjaD1cInNlYXJjaFwiXG4gIGxldC10cmFuc2Zvcm09XCJ0cmFuc2Zvcm1cIlxuPlxuICA8ZGl2XG4gICAgKm5nSWY9XCIhdHJhbnNmb3JtXCJcbiAgICBbaW5uZXJIVE1MXT1cInJvd1tjb2x1bW4ua2V5XSB8IGhpZ2hsaWdodDogc2VhcmNoXCJcbiAgPjwvZGl2PlxuICA8ZGl2XG4gICAgKm5nSWY9XCJ0cmFuc2Zvcm1cIlxuICAgIFtpbm5lckhUTUxdPVwiXG4gICAgICByb3dbY29sdW1uLmtleV1cbiAgICAgICAgfCBkeW5hbWljUGlwZTogdHJhbnNmb3JtLnBpcGU6dHJhbnNmb3JtPy5hcmdzXG4gICAgICAgIHwgaGlnaGxpZ2h0OiBzZWFyY2hcbiAgICBcIlxuICA+PC9kaXY+XG48L25nLXRlbXBsYXRlPlxuPG5nLXRlbXBsYXRlICNyYXdEYXRhIGxldC1yb3c9XCJyb3dcIiBsZXQtY29sdW1uPVwiY29sdW1uXCI+XG4gIHt7IHJvd1tjb2x1bW4ua2V5XSB9fVxuPC9uZy10ZW1wbGF0ZT5cbjxuZy10ZW1wbGF0ZVxuICAjdHJhbnNmb3JtRGF0YVxuICBsZXQtcm93PVwicm93XCJcbiAgbGV0LWNvbHVtbj1cImNvbHVtblwiXG4gIGxldC10cmFuc2Zvcm09XCJ0cmFuc2Zvcm1cIlxuICBsZXQtZGF0YT1cImRhdGFcIlxuPlxuICB7eyByb3dbY29sdW1uLmtleV0gfCBkeW5hbWljUGlwZTogdHJhbnNmb3JtLnBpcGU6dHJhbnNmb3JtPy5hcmdzIH19XG48L25nLXRlbXBsYXRlPlxuPG5nLXRlbXBsYXRlICN0cmFuc2Zvcm1Gb290ZXIgbGV0LXZhbHVlPVwidmFsdWVcIiBsZXQtdHJhbnNmb3JtPVwidHJhbnNmb3JtXCI+XG4gIHt7XG4gICAgKHZhbHVlIHwgZHluYW1pY1BpcGU6IHRyYW5zZm9ybS5waXBlOnRyYW5zZm9ybT8uYXJncykgfHxcbiAgICAgICh0YWJsZUNvbmZpZyQgfCBhc3luYyk/LmZvb3Rlcj8uZW1wdHlDb250ZW50XG4gIH19XG48L25nLXRlbXBsYXRlPlxuPG5nLXRlbXBsYXRlICNyYXdGb290ZXIgbGV0LXZhbHVlPVwidmFsdWVcIj5cbiAge3sgdmFsdWUgfHwgKHRhYmxlQ29uZmlnJCB8IGFzeW5jKT8uZm9vdGVyPy5lbXB0eUNvbnRlbnQgfX1cbjwvbmctdGVtcGxhdGU+XG48bmctdGVtcGxhdGVcbiAgI3RlbXBsYXRlUmVmXG4gIGxldC1yb3c9XCJyb3dcIlxuICBsZXQtY29sdW1uPVwiY29sdW1uXCJcbiAgbGV0LWluZGV4PVwiaW5kZXhcIlxuICBsZXQtdGVtcGxhdGVSZWY9XCJ0ZW1wbGF0ZVJlZlwiXG4gIGxldC1kYXRhPVwiZGF0YVwiXG4+XG4gIDxuZy1jb250YWluZXJcbiAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJ0ZW1wbGF0ZVJlZlwiXG4gICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cIntcbiAgICAgIHJvdzogcm93LFxuICAgICAgY29sOiBjb2x1bW4sXG4gICAgICBpbmRleDogaW5kZXgsXG4gICAgICBkYXRhOiBkYXRhXG4gICAgfVwiXG4gID48L25nLWNvbnRhaW5lcj5cbjwvbmctdGVtcGxhdGU+XG4iXX0=