@angular-generic-table/core 5.0.0-rc.16 → 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,29 +1,78 @@
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, 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
- this.rowHover$ = this._rowHover$.asObservable().pipe(debounceTime(50), distinctUntilChanged((p, q) => p.index === q.index), tap((event) => this.rowHover.emit(event)), shareReplay(1));
45
+ /** page change event - emitted when current page/index changes for pagination */
46
+ this.pageChange = new EventEmitter();
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;
20
59
  this._loading$ = new ReplaySubject(1);
21
60
  this._sortOrder$ = new BehaviorSubject([]);
22
61
  this._searchBy$ = new ReplaySubject(1);
23
62
  this.searchBy$ = this._searchBy$.pipe(startWith(''), map((value) => (isObservable(value) ? value : of(value))), switchMap((obs) => obs), shareReplay(1));
63
+ this._pagingInfo$ = new BehaviorSubject({
64
+ pageCurrent: null,
65
+ pageNext: null,
66
+ pagePrevious: null,
67
+ pageSize: null,
68
+ numberOfRecords: null,
69
+ //recordsAfterFilter: null,
70
+ //recordsAfterSearch: null,
71
+ //recordsAll: null,
72
+ });
24
73
  // tslint:disable-next-line:variable-name
25
74
  this._tableConfig$ = new BehaviorSubject({});
26
- 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));
27
76
  this._data$ = new ReplaySubject(1);
28
77
  this.data$ = this._data$.pipe(map((value) => (isObservable(value) ? value : of(value))), switchMap((obs) => combineLatest([obs])), withLatestFrom(this.tableConfig$), map(([[data], config]) => {
29
78
  // if columns or rows contains config for mapTo...
@@ -45,15 +94,22 @@ export class CoreComponent {
45
94
  }
46
95
  data = newData;
47
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
+ }
48
104
  return { data, config };
49
105
  }), switchMap((obs) => combineLatest([of(obs), this.sortOrder$, this.searchBy$])), map(([table, sortBy, searchBy]) => {
50
106
  // create a new array reference and sort new array (prevent mutating existing state)
51
107
  table.data = [...table.data];
52
- return !sortBy.length || table.config?.disableTableSort
53
- ? searchBy
108
+ return !sortBy?.length || table.config?.disableTableSort
109
+ ? searchBy && !this.tableInfo?.lazyLoaded
54
110
  ? search(searchBy, false, table.data, table.config)
55
111
  : table.data
56
- : searchBy
112
+ : searchBy && !this.tableInfo?.lazyLoaded
57
113
  ? search(searchBy, false, table.data, table.config)?.sort(sortOnMultipleKeys(sortBy))
58
114
  : table.data?.sort(sortOnMultipleKeys(sortBy));
59
115
  }), shareReplay(1));
@@ -61,14 +117,30 @@ export class CoreComponent {
61
117
  this.table$ = combineLatest([
62
118
  this.data$,
63
119
  this.tableConfig$,
64
- ]).pipe(map(([sorted, config]) => {
120
+ this._pagingInfo$,
121
+ ]).pipe(map(([sorted, config, pagingInfo]) => {
122
+ if (pagingInfo.pageCurrent !== null &&
123
+ pagingInfo.numberOfRecords !== null &&
124
+ pagingInfo.pageSize !== null) {
125
+ return {
126
+ data: [sorted],
127
+ config,
128
+ info: {
129
+ lazyLoaded: true,
130
+ numberOfRecords: pagingInfo.numberOfRecords,
131
+ pageSize: pagingInfo.pageSize,
132
+ pageTotal: pagingInfo.pageTotal ??
133
+ Math.ceil(pagingInfo.numberOfRecords / pagingInfo.pageSize),
134
+ },
135
+ };
136
+ }
65
137
  // if pagination is disabled...
66
138
  if (!config.pagination || config.pagination.length === 0) {
67
139
  // ...return unaltered array
68
140
  return {
69
141
  data: [sorted],
70
142
  config,
71
- info: { records: sorted.length, pageTotal: 1 },
143
+ info: { numberOfRecords: sorted.length, pageTotal: 1 },
72
144
  };
73
145
  }
74
146
  // return record set
@@ -76,19 +148,25 @@ export class CoreComponent {
76
148
  data: chunk(sorted, +(config.pagination.length || 0)),
77
149
  config,
78
150
  info: {
79
- records: sorted.length,
151
+ numberOfRecords: sorted.length,
152
+ pageSize: +(config.pagination.length || 0),
80
153
  pageTotal: Math.ceil(sorted.length / +(config.pagination.length || 0)),
81
154
  },
82
155
  };
83
- }), shareReplay(1));
84
- this._currentPage$ = new BehaviorSubject(0);
85
- this.currentPage$ = combineLatest([this._currentPage$, this.table$]).pipe(map(([page, table]) => {
156
+ }), tap((meta) => this._tableInfo$.next(meta.info)), shareReplay(1));
157
+ this._tableInfo$ = new BehaviorSubject(undefined);
158
+ this._currentPaginationIndex$ = new BehaviorSubject(0);
159
+ this.currentPaginationIndex$ = combineLatest([
160
+ this._currentPaginationIndex$,
161
+ this.table$,
162
+ ]).pipe(map(([page, table]) => {
86
163
  // determine last page
87
164
  const lastPage = Math.ceil(table.info.records /
88
- (table.config?.pagination?.length || table.info.records)) - 1;
89
- // determine max/min position
165
+ (table.info.recordLength ??
166
+ (table.config?.pagination?.length || table.info.records))) - 1;
167
+ // determine min/max position
90
168
  return +page < 0 ? 0 : +page > lastPage ? lastPage : +page;
91
- }), shareReplay(1));
169
+ }), distinctUntilChanged(), tap((index) => this.pageChange.emit({ index })), shareReplay(1));
92
170
  this.colspan$ = this.tableConfig$.pipe(switchMap((config) => config.columns
93
171
  ? of(Object.values(config.columns || config.rows || {}).filter((value) => value.hidden !== true).length)
94
172
  : this.data$.pipe(map((data) => data.length + 1))), shareReplay(1));
@@ -105,6 +183,30 @@ export class CoreComponent {
105
183
  this.columnOrder = (a, b) => {
106
184
  return (a.value.order || 0) - (b.value.order || 0);
107
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;
108
210
  }
109
211
  get sortOrder$() {
110
212
  return this._sortOrder$.asObservable();
@@ -112,8 +214,52 @@ export class CoreComponent {
112
214
  set loading(isLoading) {
113
215
  this._loading$.next(isLoading);
114
216
  }
115
- set page(page) {
116
- this._currentPage$.next(page);
217
+ set paginationIndex(pageIndex) {
218
+ this._currentPaginationIndex$.next(pageIndex);
219
+ }
220
+ get paginationIndex() {
221
+ return this._currentPaginationIndex$.getValue();
222
+ }
223
+ set pagingInfo(value) {
224
+ if (value) {
225
+ this._pagingInfo$.next(value);
226
+ if (value.pageCurrent !== this._currentPaginationIndex$.getValue() + 1 &&
227
+ value.pageCurrent !== null) {
228
+ this.paginationIndex = value.pageCurrent - 1;
229
+ }
230
+ }
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;
117
263
  }
118
264
  set search(string) {
119
265
  this._searchBy$.next(string);
@@ -122,7 +268,9 @@ export class CoreComponent {
122
268
  this._tableConfig$.next(config);
123
269
  }
124
270
  set data(data) {
125
- this._data$.next(data);
271
+ if (data) {
272
+ this._data$.next(data);
273
+ }
126
274
  }
127
275
  set sortOrder(sortConfig) {
128
276
  if (JSON.stringify(sortConfig) !== JSON.stringify(this._sortOrder$.value)) {
@@ -133,31 +281,44 @@ export class CoreComponent {
133
281
  _rowClick(row, index, event) {
134
282
  this.rowClick.emit({ row, index, event });
135
283
  }
136
- hoverRow(arg) {
284
+ _rowActive(row, index, event) {
285
+ this.rowSelect.emit({ row, index, event });
286
+ }
287
+ activateRow(arg, event) {
137
288
  if (typeof arg === 'number') {
138
- this.data$
139
- .pipe(map((data) => data[arg]), take(1))
140
- .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));
141
292
  }
142
293
  else if (typeof arg === 'string') {
143
294
  // TODO: implement hover by id
144
295
  }
145
296
  else {
146
- this._hoverRow(null, null);
297
+ this._activateRow(null, null);
147
298
  }
148
299
  }
149
- _hoverRow(row, index, event) {
150
- this._rowHover$.next({ row, index, event });
300
+ _activateRow(row, index, event) {
301
+ this._rowActive$.next({ row, index, event });
151
302
  }
152
303
  get loading$() {
153
304
  return this._loading$.pipe(startWith(false), map((value) => (isObservable(value) ? value : of(value))), switchMap((obs) => obs), shareReplay(1));
154
305
  }
306
+ /** tableInfo$ - returns observable for table info
307
+ * @return Observable<TableInfo> */
308
+ get tableInfo$() {
309
+ return this._tableInfo$.asObservable().pipe(filter((info) => !!info), shareReplay(1));
310
+ }
311
+ /** tableInfo - returns the current table info
312
+ * @return TableInfo */
313
+ get tableInfo() {
314
+ return this._tableInfo$.getValue();
315
+ }
155
316
  /** sortByKey - Sort by key in table row
156
317
  * @param key - key to sort by
157
318
  * @param { MouseEvent } [$event] - Mouse event triggering sort, if shift key is pressed sort key will be added to already present sort keys
158
319
  */
159
320
  sortByKey(key, $event) {
160
- const shiftKey = $event?.shiftKey;
321
+ const shiftKey = $event?.shiftKey === true;
161
322
  const currentOrder = this._sortOrder$.value;
162
323
  let sortOrder = 'asc';
163
324
  let newOrder = [];
@@ -205,6 +366,7 @@ export class CoreComponent {
205
366
  key,
206
367
  order: sortOrder,
207
368
  currentSortOrder: newOrder,
369
+ addSortKey: shiftKey,
208
370
  };
209
371
  // if event is passed to sort function...
210
372
  if ($event) {
@@ -213,17 +375,128 @@ export class CoreComponent {
213
375
  }
214
376
  // emit sort event
215
377
  this.columnSort.emit(sortEvent);
216
- // update sort order
217
- this.sortOrder = newOrder;
378
+ // if table is not lazy loaded (sorting is then handled server-side)...
379
+ if (!this.tableInfo?.lazyLoaded) {
380
+ // ...update sort order
381
+ this.sortOrder = newOrder;
382
+ }
218
383
  }
219
384
  nestedValue(object, mapTo, missingValue = null) {
220
385
  const levels = mapTo.split('.');
221
386
  return levels.reduce((previousValue, currentValue, index) => previousValue[currentValue] ||
222
387
  (index === levels.length - 1 ? missingValue : {}), object);
223
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
+ }
224
497
  }
225
498
  CoreComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: CoreComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
226
- CoreComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.1", type: CoreComponent, isStandalone: true, selector: "angular-generic-table", inputs: { loading: "loading", page: "page", search: "search", config: "config", data: "data", sortOrder: "sortOrder" }, outputs: { rowClick: "rowClick", sortOrderChange: "sortOrderChange", rowHover: "rowHover", columnSort: "columnSort" }, 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![(currentPage$ | async) || 0];\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[(currentPage$ | async) || 0]\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[(currentPage$ | async) || 0]\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 });
227
500
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: CoreComponent, decorators: [{
228
501
  type: Component,
229
502
  args: [{ selector: 'angular-generic-table', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
@@ -231,6 +504,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImpor
231
504
  KeyValuePipe,
232
505
  SortClassPipe,
233
506
  DashCasePipe,
507
+ RowSelectionPipe,
234
508
  AsyncPipe,
235
509
  NgTemplateOutlet,
236
510
  SlicePipe,
@@ -239,10 +513,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImpor
239
513
  NgClass,
240
514
  NgIf,
241
515
  NgForOf,
242
- ], 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![(currentPage$ | async) || 0];\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[(currentPage$ | async) || 0]\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[(currentPage$ | async) || 0]\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" }]
243
- }], 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: [{
522
+ type: Input
523
+ }], paginationIndex: [{
244
524
  type: Input
245
- }], page: [{
525
+ }], pagingInfo: [{
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: [{
246
538
  type: Input
247
539
  }], search: [{
248
540
  type: Input
@@ -254,12 +546,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImpor
254
546
  type: Input
255
547
  }], rowClick: [{
256
548
  type: Output
549
+ }], rowSelect: [{
550
+ type: Output
257
551
  }], sortOrderChange: [{
258
- type: Output,
259
- args: ['sortOrderChange']
260
- }], rowHover: [{
552
+ type: Output
553
+ }], rowActive: [{
261
554
  type: Output
262
555
  }], columnSort: [{
263
556
  type: Output
557
+ }], pageChange: [{
558
+ type: Output
264
559
  }] } });
265
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29yZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb3JlL3NyYy9saWIvY29yZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb3JlL3NyYy9saWIvY29yZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDVCxZQUFZLEVBQ1osS0FBSyxFQUNMLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQ0wsZUFBZSxFQUNmLGFBQWEsRUFDYixZQUFZLEVBRVosRUFBRSxFQUNGLGFBQWEsR0FDZCxNQUFNLE1BQU0sQ0FBQztBQUVkLE9BQU8sRUFDTCxTQUFTLEVBRVQsWUFBWSxFQUNaLE9BQU8sRUFDUCxPQUFPLEVBQ1AsSUFBSSxFQUNKLGdCQUFnQixFQUNoQixTQUFTLEdBQ1YsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QixPQUFPLEVBQ0wsWUFBWSxFQUNaLG9CQUFvQixFQUNwQixHQUFHLEVBQ0gsV0FBVyxFQUNYLFNBQVMsRUFDVCxTQUFTLEVBQ1QsSUFBSSxFQUNKLEdBQUcsRUFDSCxjQUFjLEdBQ2YsTUFBTSxnQkFBZ0IsQ0FBQztBQUV4QixPQUFPLEVBQ0wsU0FBUyxFQUNULEtBQUssRUFDTCxNQUFNLEVBQ04sa0JBQWtCLEdBQ25CLE1BQU0sdUJBQXVCLENBQUM7QUFTL0IsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzVELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDdEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQzs7QUFzQnZELE1BQU0s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bkQsTUFBTSxDQUNQLENBQUM7SUFDSixDQUFDOzswR0ExVVUsYUFBYTs4RkFBYixhQUFhLGdVQzlFMUIsczZaQTJXQSx1Q0QzU0ksZUFBZSwrQ0FDZixZQUFZLDRDQUNaLGFBQWEsNkNBQ2IsWUFBWSw0Q0FDWixTQUFTLDhDQUNULGdCQUFnQiwrSUFDaEIsU0FBUyx5Q0FDVCxXQUFXLCtDQUNYLGFBQWEsa0RBQ2IsT0FBTyxvRkFDUCxJQUFJLDZGQUNKLE9BQU87MkZBR0UsYUFBYTtrQkFwQnpCLFNBQVM7K0JBQ0UsdUJBQXVCLG1CQUVoQix1QkFBdUIsQ0FBQyxNQUFNLGNBQ25DLElBQUksV0FDUDt3QkFDUCxlQUFlO3dCQUNmLFlBQVk7d0JBQ1osYUFBYTt3QkFDYixZQUFZO3dCQUNaLFNBQVM7d0JBQ1QsZ0JBQWdCO3dCQUNoQixTQUFTO3dCQUNULFdBQVc7d0JBQ1gsYUFBYTt3QkFDYixPQUFPO3dCQUNQLElBQUk7d0JBQ0osT0FBTztxQkFDUjs4QkFPWSxPQUFPO3NCQUFuQixLQUFLO2dCQUlGLElBQUk7c0JBRFAsS0FBSztnQkFNRixNQUFNO3NCQURULEtBQUs7Z0JBTUYsTUFBTTtzQkFEVCxLQUFLO2dCQU1GLElBQUk7c0JBRFAsS0FBSztnQkFLTyxTQUFTO3NCQUFyQixLQUFLO2dCQU9JLFFBQVE7c0JBQWpCLE1BQU07Z0JBQ29CLGVBQWU7c0JBQXpDLE1BQU07dUJBQUMsaUJBQWlCO2dCQVNmLFFBQVE7c0JBQWpCLE1BQU07Z0JBQ0csVUFBVTtzQkFBbkIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDb21wb25lbnQsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE91dHB1dCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICBCZWhhdmlvclN1YmplY3QsXG4gIGNvbWJpbmVMYXRlc3QsXG4gIGlzT2JzZXJ2YWJsZSxcbiAgT2JzZXJ2YWJsZSxcbiAgb2YsXG4gIFJlcGxheVN1YmplY3QsXG59IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgVGFibGVDb25maWcgfSBmcm9tICcuL21vZGVscy90YWJsZS1jb25maWcuaW50ZXJmYWNlJztcbmltcG9ydCB7XG4gIEFzeW5jUGlwZSxcbiAgS2V5VmFsdWUsXG4gIEtleVZhbHVlUGlwZSxcbiAgTmdDbGFzcyxcbiAgTmdGb3JPZixcbiAgTmdJZixcbiAgTmdUZW1wbGF0ZU91dGxldCxcbiAgU2xpY2VQaXBlLFxufSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgZGVib3VuY2VUaW1lLFxuICBkaXN0aW5jdFVudGlsQ2hhbmdlZCxcbiAgbWFwLFxuICBzaGFyZVJlcGxheSxcbiAgc3RhcnRXaXRoLFxuICBzd2l0Y2hNYXAsXG4gIHRha2UsXG4gIHRhcCxcbiAgd2l0aExhdGVzdEZyb20sXG59IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IFRhYmxlQ29sdW1uIH0gZnJvbSAnLi9tb2RlbHMvdGFibGUtY29sdW1uLmludGVyZmFjZSc7XG5pbXBvcnQge1xuICBjYWxjdWxhdGUsXG4gIGNodW5rLFxuICBzZWFyY2gsXG4gIHNvcnRPbk11bHRpcGxlS2V5cyxcbn0gZnJvbSAnLi91dGlsaXRpZXMvdXRpbGl0aWVzJztcbmltcG9ydCB7IFRhYmxlUm93IH0gZnJvbSAnLi9tb2RlbHMvdGFibGUtcm93LmludGVyZmFjZSc7XG5pbXBvcnQgeyBHdE9yZGVyLCBHdFNvcnRPcmRlciB9IGZyb20gJy4vbW9kZWxzL3RhYmxlLXNvcnQuaW50ZXJmYWNlJztcbmltcG9ydCB7IFRhYmxlTWV0YSB9IGZyb20gJy4vbW9kZWxzL3RhYmxlLW1ldGEuaW50ZXJmYWNlJztcbmltcG9ydCB7XG4gIEd0Um93Q2xpY2tFdmVudCxcbiAgR3RSb3dIb3ZlckV2ZW50LFxuICBHdFNvcnRFdmVudCxcbn0gZnJvbSAnLi9tb2RlbHMvdGFibGUtZXZlbnRzLmludGVyZmFjZSc7XG5pbXBvcnQgeyBDYXBpdGFsQ2FzZVBpcGUgfSBmcm9tICcuL3BpcGVzL2NhcGl0YWwtY2FzZS5waXBlJztcbmltcG9ydCB7IFNvcnRDbGFzc1BpcGUgfSBmcm9tICcuL3BpcGVzL3NvcnQtY2xhc3MucGlwZSc7XG5pbXBvcnQgeyBEYXNoQ2FzZVBpcGUgfSBmcm9tICcuL3BpcGVzL2Rhc2gtY2FzZS5waXBlJztcbmltcG9ydCB7IER5bmFtaWNQaXBlIH0gZnJvbSAnLi9waXBlcy9keW5hbWljLnBpcGUnO1xuaW1wb3J0IHsgSGlnaGxpZ2h0UGlwZSB9IGZyb20gJy4vcGlwZXMvaGlnaGxpZ2h0LnBpcGUnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhbmd1bGFyLWdlbmVyaWMtdGFibGUnLFxuICB0ZW1wbGF0ZVVybDogJy4vY29yZS5jb21wb25lbnQuaHRtbCcsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgQ2FwaXRhbENhc2VQaXBlLFxuICAgIEtleVZhbHVlUGlwZSxcbiAgICBTb3J0Q2xhc3NQaXBlLFxuICAgIERhc2hDYXNlUGlwZSxcbiAgICBBc3luY1BpcGUsXG4gICAgTmdUZW1wbGF0ZU91dGxldCxcbiAgICBTbGljZVBpcGUsXG4gICAgRHluYW1pY1BpcGUsXG4gICAgSGlnaGxpZ2h0UGlwZSxcbiAgICBOZ0NsYXNzLFxuICAgIE5nSWYsXG4gICAgTmdGb3JPZixcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgQ29yZUNvbXBvbmVudCB7XG4gIGdldCBzb3J0T3JkZXIkKCk6IE9ic2VydmFibGU8R3RTb3J0T3JkZXI+IHtcbiAgICByZXR1cm4gdGhpcy5fc29ydE9yZGVyJC5hc09ic2VydmFibGUoKTtcbiAgfVxuXG4gIEBJbnB1dCgpIHNldCBsb2FkaW5nKGlzTG9hZGluZzogT2JzZXJ2YWJsZTxib29sZWFuPiB8IGJvb2xlYW4pIHtcbiAgICB0aGlzLl9sb2FkaW5nJC5uZXh0KGlzTG9hZGluZyk7XG4gIH1cbiAgQElucHV0KClcbiAgc2V0IHBhZ2UocGFnZTogbnVtYmVyKSB7XG4gICAgdGhpcy5fY3VycmVudFBhZ2UkLm5leHQocGFnZSk7XG4gIH1cblxuICBASW5wdXQoKVxuICBzZXQgc2VhcmNoKHN0cmluZzogT2JzZXJ2YWJsZTxzdHJpbmc+IHwgc3RyaW5nIHwgbnVsbCkge1xuICAgIHRoaXMuX3NlYXJjaEJ5JC5uZXh0KHN0cmluZyk7XG4gIH1cblxuICBASW5wdXQoKVxuICBzZXQgY29uZmlnKGNvbmZpZzogT2JzZXJ2YWJsZTxUYWJsZUNvbmZpZzxhbnk+PiB8IFRhYmxlQ29uZmlnPGFueT4pIHtcbiAgICB0aGlzLl90YWJsZUNvbmZpZyQubmV4dChjb25maWcpO1xuICB9XG5cbiAgQElucHV0KClcbiAgc2V0IGRhdGEoZGF0YTogT2JzZXJ2YWJsZTxBcnJheTxUYWJsZVJvdz4+IHwgQXJyYXk8VGFibGVSb3c+KSB7XG4gICAgdGhpcy5fZGF0YSQubmV4dChkYXRhKTtcbiAgfVxuXG4gIEBJbnB1dCgpIHNldCBzb3J0T3JkZXIoc29ydENvbmZpZzogR3RTb3J0T3JkZXI8YW55Pikge1xuICAgIGlmIChKU09OLnN0cmluZ2lmeShzb3J0Q29uZmlnKSAhPT0gSlNPTi5zdHJpbmdpZnkodGhpcy5fc29ydE9yZGVyJC52YWx1ZSkpIHtcbiAgICAgIHRoaXMuc29ydE9yZGVyQ2hhbmdlLmVtaXQoc29ydENvbmZpZyk7XG4gICAgICB0aGlzLl9zb3J0T3JkZXIkLm5leHQoc29ydENvbmZpZyk7XG4gICAgfVxuICB9XG5cbiAgQE91dHB1dCgpIHJvd0NsaWNrID0gbmV3IEV2ZW50RW1pdHRlcjxHdFJvd0NsaWNrRXZlbnQ+KCk7XG4gIEBPdXRwdXQoJ3NvcnRPcmRlckNoYW5nZScpIHNvcnRPcmRlckNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8XG4gICAgR3RTb3J0T3JkZXI8VGFibGVSb3c+XG4gID4oKTtcblxuICBfcm93Q2xpY2socm93OiBUYWJsZVJvdywgaW5kZXg6IG51bWJlciwgZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICB0aGlzLnJvd0NsaWNrLmVtaXQoeyByb3csIGluZGV4LCBldmVudCB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX3Jvd0hvdmVyJCA9IG5ldyBSZXBsYXlTdWJqZWN0PEd0Um93SG92ZXJFdmVudD4oMSk7XG4gIEBPdXRwdXQoKSByb3dIb3ZlciA9IG5ldyBFdmVudEVtaXR0ZXI8R3RSb3dIb3ZlckV2ZW50PigpO1xuICBAT3V0cHV0KCkgY29sdW1uU29ydCA9IG5ldyBFdmVudEVtaXR0ZXI8R3RTb3J0RXZlbnQ+KCk7XG4gIHJvd0hvdmVyJCA9IHRoaXMuX3Jvd0hvdmVyJC5hc09ic2VydmFibGUoKS5waXBlKFxuICAgIGRlYm91bmNlVGltZSg1MCksXG4gICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKHAsIHEpID0+IHAuaW5kZXggPT09IHEuaW5kZXgpLFxuICAgIHRhcCgoZXZlbnQpID0+IHRoaXMucm93SG92ZXIuZW1pdChldmVudCkpLFxuICAgIHNoYXJlUmVwbGF5KDEpXG4gICk7XG5cbiAgaG92ZXJSb3coaWQ6IHN0cmluZyk6IHZvaWQ7XG4gIGhvdmVyUm93KGluZGV4OiBudW1iZXIpOiB2b2lkO1xuICBob3ZlclJvdyhub25lOiBudWxsKTogdm9pZDtcbiAgaG92ZXJSb3coYXJnOiBzdHJpbmcgfCBudW1iZXIgfCBudWxsKTogdm9pZCB7XG4gICAgaWYgKHR5cGVvZiBhcmcgPT09ICdudW1iZXInKSB7XG4gICAgICB0aGlzLmRhdGEkXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgIG1hcCgoZGF0YSkgPT4gZGF0YVthcmddKSxcbiAgICAgICAgICB0YWtlKDEpXG4gICAgICAgIClcbiAgICAgICAgLnN1YnNjcmliZSgocm93KSA9PiB0aGlzLl9ob3ZlclJvdyhyb3csIGFyZykpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZyA9PT0gJ3N0cmluZycpIHtcbiAgICAgIC8vIFRPRE86IGltcGxlbWVudCBob3ZlciBieSBpZFxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9ob3ZlclJvdyhudWxsLCBudWxsKTtcbiAgICB9XG4gIH1cbiAgX2hvdmVyUm93KFxuICAgIHJvdzogVGFibGVSb3cgfCBudWxsLFxuICAgIGluZGV4OiBudW1iZXIgfCBudWxsLFxuICAgIGV2ZW50PzogTW91c2VFdmVudFxuICApOiB2b2lkIHtcbiAgICB0aGlzLl9yb3dIb3ZlciQubmV4dCh7IHJvdywgaW5kZXgsIGV2ZW50IH0pO1xuICB9XG5cbiAgZ2V0IGxvYWRpbmckKCk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0aGlzLl9sb2FkaW5nJC5waXBlKFxuICAgICAgc3RhcnRXaXRoKGZhbHNlKSxcbiAgICAgIG1hcCgodmFsdWUpID0+IChpc09ic2VydmFibGUodmFsdWUpID8gdmFsdWUgOiBvZih2YWx1ZSkpKSxcbiAgICAgIHN3aXRjaE1hcCgob2JzKSA9PiBvYnMpLFxuICAgICAgc2hhcmVSZXBsYXkoMSlcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBfbG9hZGluZyQ6IFJlcGxheVN1YmplY3Q8T2JzZXJ2YWJsZTxib29sZWFuPiB8IGJvb2xlYW4+ID1cbiAgICBuZXcgUmVwbGF5U3ViamVjdCgxKTtcbiAgcHJpdmF0ZSBfc29ydE9yZGVyJDogQmVoYXZpb3JTdWJqZWN0PEd0U29ydE9yZGVyPiA9XG4gICAgbmV3IEJlaGF2aW9yU3ViamVjdDxHdFNvcnRPcmRlcj4oW10pO1xuICBwcml2YXRlIF9zZWFyY2hCeSQ6IFJlcGxheVN1YmplY3Q8T2JzZXJ2YWJsZTxzdHJpbmc+IHwgc3RyaW5nIHwgbnVsbD4gPVxuICAgIG5ldyBSZXBsYXlTdWJqZWN0KDEpO1xuICBzZWFyY2hCeSQ6IE9ic2VydmFibGU8c3RyaW5nIHwgbnVsbD4gPSB0aGlzLl9zZWFyY2hCeSQucGlwZShcbiAgICBzdGFydFdpdGgoJycpLFxuICAgIG1hcCgodmFsdWUpID0+IChpc09ic2VydmFibGUodmFsdWUpID8gdmFsdWUgOiBvZih2YWx1ZSkpKSxcbiAgICBzd2l0Y2hNYXAoKG9icykgPT4gb2JzKSxcbiAgICBzaGFyZVJlcGxheSgxKVxuICApO1xuXG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTp2YXJpYWJsZS1uYW1lXG4gIHByaXZhdGUgX3RhYmxlQ29uZmlnJDogQmVoYXZpb3JTdWJqZWN0PFxuICAgIFRhYmxlQ29uZmlnPGFueT4gfCBPYnNlcnZhYmxlPFRhYmxlQ29uZmlnPGFueT4+XG4gID4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0KHt9KTtcbiAgdGFibGVDb25maWckID0gdGhpcy5fdGFibGVDb25maWckLnBpcGUoXG4gICAgbWFwKCh2YWx1ZSkgPT4gKGlzT2JzZXJ2YWJsZSh2YWx1ZSkgPyB2YWx1ZSA6IG9mKHZhbHVlKSkpLFxuICAgIHN3aXRjaE1hcCgob2JzKSA9PiBvYnMpLFxuICAgIHNoYXJlUmVwbGF5KDEpXG4gICk7XG5cbiAgcHJpdmF0ZSBfZGF0YSQ6IFJlcGxheVN1YmplY3Q8QXJyYXk8VGFibGVSb3c+IHwgT2JzZXJ2YWJsZTxBcnJheTxUYWJsZVJvdz4+PiA9XG4gICAgbmV3IFJlcGxheVN1YmplY3QoMSk7XG4gIGRhdGEkOiBPYnNlcnZhYmxlPEFycmF5PFRhYmxlUm93Pj4gPSB0aGlzLl9kYXRhJC5waXBlKFxuICAgIG1hcCgodmFsdWUpID0+IChpc09ic2VydmFibGUodmFsdWUpID8gdmFsdWUgOiBvZih2YWx1ZSkpKSxcbiAgICBzd2l0Y2hNYXAoKG9icykgPT4gY29tYmluZUxhdGVzdChbb2JzXSkpLFxuICAgIHdpdGhMYXRlc3RGcm9tKHRoaXMudGFibGVDb25maWckKSxcbiAgICBtYXAoKFtbZGF0YV0sIGNvbmZpZ10pID0+IHtcbiAgICAgIC8vIGlmIGNvbHVtbnMgb3Igcm93cyBjb250YWlucyBjb25maWcgZm9yIG1hcFRvLi4uXG4gICAgICBpZiAoXG4gICAgICAgIChjb25maWcuY29sdW1ucyAmJlxuICAgICAgICAgICEhT2JqZWN0LnZhbHVlcyhjb25maWcuY29sdW1ucykuZmluZCgoY29sdW1uKSA9PiAhIWNvbHVtbi5tYXBUbykpIHx8XG4gICAgICAgIChjb25maWcucm93cyAmJlxuICAgICAgICAgICEhT2JqZWN0LnZhbHVlcyhjb25maWcucm93cykuZmluZCgoY29sdW1uKSA9PiAhIWNvbHVtbi5tYXBUbykpXG4gICAgICApIHtcbiAgICAgICAgLy8gLi4ubWFwIGRhdGEgdG8gbmV3IGtleXMgb24gcm93Li4uXG4gICAgICAgIGNvbnN0IG5ld0RhdGE6IFRhYmxlUm93W10gPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgY29uc3Qgcm93ID0gZGF0YVtpXTtcbiAgICAgICAgICBjb25zdCBuZXdLZXlzID0gT2JqZWN0LmVudHJpZXMoY29uZmlnLmNvbHVtbnMgfHwgY29uZmlnLnJvd3MgfHwgW10pXG4gICAgICAgICAgICAuZmlsdGVyKChba2V5LCB2YWx1ZV0pID0+ICEhdmFsdWUubWFwVG8pIC8vIGFkZCBrZXlzIGZvciBjb2x1bW5zIHdpdGggbWFwVG8gY29uZmlnLi4uXG4gICAgICAgICAgICAucmVkdWNlKFxuICAgICAgICAgICAgICAocHJldmlvdXNWYWx1ZSwgW2tleSwgdmFsdWVdKSA9PiAoe1xuICAgICAgICAgICAgICAgIC4uLnByZXZpb3VzVmFsdWUsXG4gICAgICAgICAgICAgICAgW2tleV06IHRoaXMubmVzdGVkVmFsdWUoXG4gICAgICAgICAgICAgICAgICByb3csXG4gICAgICAgICAgICAgICAgICB2YWx1ZS5tYXBUbyEucGF0aCxcbiAgICAgICAgICAgICAgICAgIHZhbHVlLm1hcFRvPy5taXNzaW5nVmFsdWVcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAge31cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgbmV3RGF0YVtpXSA9IHsgLi4ucm93LCAuLi5uZXdLZXlzIH07XG4gICAgICAgIH1cbiAgICAgICAgZGF0YSA9IG5ld0RhdGE7XG4gICAgICB9XG4gICAgICByZXR1cm4geyBkYXRhLCBjb25maWcgfTtcbiAgICB9KSxcbiAgICBzd2l0Y2hNYXAoKG9icykgPT5cbiAgICAgIGNvbWJpbmVMYXRlc3QoW29mKG9icyksIHRoaXMuc29ydE9yZGVyJCwgdGhpcy5zZWFyY2hCeSRdKVxuICAgICksXG4gICAgbWFwKChbdGFibGUsIHNvcnRCeSwgc2VhcmNoQnldKSA9PiB7XG4gICAgICAvLyBjcmVhdGUgYSBuZXcgYXJyYXkgcmVmZXJlbmNlIGFuZCBzb3J0IG5ldyBhcnJheSAocHJldmVudCBtdXRhdGluZyBleGlzdGluZyBzdGF0ZSlcbiAgICAgIHRhYmxlLmRhdGEgPSBbLi4udGFibGUuZGF0YV07XG4gICAgICByZXR1cm4gIXNvcnRCeS5sZW5ndGggfHwgdGFibGUuY29uZmlnPy5kaXNhYmxlVGFibGVTb3J0XG4gICAgICAgID8gc2VhcmNoQnlcbiAgICAgICAgICA/IHNlYXJjaChzZWFyY2hCeSwgZmFsc2UsIHRhYmxlLmRhdGEsIHRhYmxlLmNvbmZpZylcbiAgICAgICAgICA6IHRhYmxlLmRhdGFcbiAgICAgICAgOiBzZWFyY2hCeVxuICAgICAgICA/IHNlYXJjaChzZWFyY2hCeSwgZmFsc2UsIHRhYmxlLmRhdGEsIHRhYmxlLmNvbmZpZyk/LnNvcnQoXG4gICAgICAgICAgICBzb3J0T25NdWx0aXBsZUtleXMoc29ydEJ5KVxuICAgICAgICAgIClcbiAgICAgICAgOiB0YWJsZS5kYXRhPy5zb3J0KHNvcnRPbk11bHRpcGxlS2V5cyhzb3J0QnkpKTtcbiAgICB9KSxcbiAgICBzaGFyZVJlcGxheSgxKVxuICApO1xuXG4gIGNhbGN1bGF0aW9ucyQgPSBjb21iaW5lTGF0ZXN0KFt0aGlzLmRhdGEkLCB0aGlzLnRhYmxlQ29uZmlnJF0pLnBpcGUoXG4gICAgbWFwKChbZGF0YSwgY29uZmlnXSkgPT4gY2FsY3VsYXRlKGRhdGEsIGNvbmZpZykpLFxuICAgIHNoYXJlUmVwbGF5KDEpXG4gICk7XG5cbiAgdGFibGUkOiBPYnNlcnZhYmxlPFRhYmxlTWV0YT4gPSBjb21iaW5lTGF0ZXN0KFtcbiAgICB0aGlzLmRhdGEkLFxuICAgIHRoaXMudGFibGVDb25maWckLFxuICBdKS5waXBlKFxuICAgIG1hcCgoW3NvcnRlZCwgY29uZmlnXSkgPT4ge1xuICAgICAgLy8gaWYgcGFnaW5hdGlvbiBpcyBkaXNhYmxlZC4uLlxuICAgICAgaWYgKCFjb25maWcucGFnaW5hdGlvbiB8fCBjb25maWcucGFnaW5hdGlvbi5sZW5ndGggPT09IDApIHtcbiAgICAgICAgLy8gLi4ucmV0dXJuIHVuYWx0ZXJlZCBhcnJheVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGRhdGE6IFtzb3J0ZWRdLFxuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICBpbmZvOiB7IHJlY29yZHM6IHNvcnRlZC5sZW5ndGgsIHBhZ2VUb3RhbDogMSB9LFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgLy8gcmV0dXJuIHJlY29yZCBzZXRcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGRhdGE6IGNodW5rKHNvcnRlZCwgKyhjb25maWcucGFnaW5hdGlvbi5sZW5ndGggfHwgMCkpLFxuICAgICAgICBjb25maWcsXG4gICAgICAgIGluZm86IHtcbiAgICAgICAgICByZWNvcmRzOiBzb3J0ZWQubGVuZ3RoLFxuICAgICAgICAgIHBhZ2VUb3RhbDogTWF0aC5jZWlsKFxuICAgICAgICAgICAgc29ydGVkLmxlbmd0aCAvICsoY29uZmlnLnBhZ2luYXRpb24ubGVuZ3RoIHx8IDApXG4gICAgICAgICAgKSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfSksXG4gICAgc2hhcmVSZXBsYXkoMSlcbiAgKTtcblxuICBwcml2YXRlIF9jdXJyZW50UGFnZSQ6IEJlaGF2aW9yU3ViamVjdDxudW1iZXI+ID0gbmV3IEJlaGF2aW9yU3ViamVjdCgwKTtcbiAgY3VycmVudFBhZ2UkID0gY29tYmluZUxhdGVzdChbdGhpcy5fY3VycmVudFBhZ2UkLCB0aGlzLnRhYmxlJF0pLnBpcGUoXG4gICAgbWFwKChbcGFnZSwgdGFibGVdOiBhbnkpID0+IHtcbiAgICAgIC8vIGRldGVybWluZSBsYXN0IHBhZ2VcbiAgICAgIGNvbnN0IGxhc3RQYWdlID1cbiAgICAgICAgTWF0aC5jZWlsKFxuICAgICAgICAgIHRhYmxlLmluZm8ucmVjb3JkcyAvXG4gICAgICAgICAgICAodGFibGUuY29uZmlnPy5wYWdpbmF0aW9uPy5sZW5ndGggfHwgdGFibGUuaW5mby5yZWNvcmRzKVxuICAgICAgICApIC0gMTtcbiAgICAgIC8vIGRldGVybWluZSBtYXgvbWluIHBvc2l0aW9uXG4gICAgICByZXR1cm4gK3BhZ2UgPCAwID8gMCA6ICtwYWdlID4gbGFzdFBhZ2UgPyBsYXN0UGFnZSA6ICtwYWdlO1xuICAgIH0pLFxuICAgIHNoYXJlUmVwbGF5KDEpXG4gICk7XG5cbiAgY29sc3BhbiQgPSB0aGlzLnRhYmxlQ29uZmlnJC5waXBlKFxuICAgIHN3aXRjaE1hcCgoY29uZmlnKSA9PlxuICAgICAgY29uZmlnLmNvbHVtbnNcbiAgICAgICAgPyBvZihcbiAgICAgICAgICAgIE9iamVjdC52YWx1ZXMoY29uZmlnLmNvbHVtbnMgfHwgY29uZmlnLnJvd3MgfHwge30pLmZpbHRlcihcbiAgICAgICAgICAgICAgKHZhbHVlKSA9PiB2YWx1ZS5oaWRkZW4gIT09IHRydWVcbiAgICAgICAgICAgICkubGVuZ3RoXG4gICAgICAgICAgKVxuICAgICAgICA6IHRoaXMuZGF0YSQucGlwZShtYXAoKGRhdGEpID0+IGRhdGEubGVuZ3RoICsgMSkpXG4gICAgKSxcbiAgICBzaGFyZVJlcGxheSgxKVxuICApO1xuXG4gIGZvb3RlckNvbHNwYW4kID0gdGhpcy50YWJsZUNvbmZpZyQucGlwZShcbiAgICBtYXAoKGNvbmZpZykgPT4ge1xuICAgICAgbGV0IGNvbHNwYW4gPSAwO1xuICAgICAgT2JqZWN0LnZhbHVlcyhjb25maWc/LmZvb3Rlcj8uY29sdW1ucyB8fCB7fSkuZm9yRWFjaCgoY2FsY3VsYXRpb25zKSA9PiB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBPYmplY3QudmFsdWVzKGNhbGN1bGF0aW9ucykuZmlsdGVyKCh2YWx1ZSkgPT4gdmFsdWUgIT09IGZhbHNlKVxuICAgICAgICAgICAgLmxlbmd0aCA+PSAwXG4gICAgICAgICkge1xuICAgICAgICAgIGNvbHNwYW4gKz0gMTtcbiAgICAgICAgfVxuICAgICAgfSwge30pO1xuICAgICAgcmV0dXJuIGNvbHNwYW47XG4gICAgfSksXG4gICAgc2hhcmVSZXBsYXkoMSlcbiAgKTtcblxuICAvKiogc29ydEJ5S2V5IC0gU29ydCBieSBrZXkgaW4gdGFibGUgcm93XG4gICAqIEBwYXJhbSBrZXkgLSBrZXkgdG8gc29ydCBieVxuICAgKiBAcGFyYW0geyBNb3VzZUV2ZW50IH0gWyRldmVudF0gLSBNb3VzZSBldmVudCB0cmlnZ2VyaW5nIHNvcnQsIGlmIHNoaWZ0IGtleSBpcyBwcmVzc2VkIHNvcnQga2V5IHdpbGwgYmUgYWRkZWQgdG8gYWxyZWFkeSBwcmVzZW50IHNvcnQga2V5c1xuICAgKi9cbiAgc29ydEJ5S2V5KGtleToga2V5b2YgVGFibGVSb3csICRldmVudD86IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCBzaGlmdEtleSA9ICRldmVudD8uc2hpZnRLZXk7XG4gICAgY29uc3QgY3VycmVudE9yZGVyID0gdGhpcy5fc29ydE9yZGVyJC52YWx1ZTtcbiAgICBsZXQgc29ydE9yZGVyOiBHdE9yZGVyID0gJ2FzYyc7XG4gICAgbGV0IG5ld09yZGVyOiBHdFNvcnRPcmRlciA9IFtdO1xuICAgIC8vIGlmIHNoaWZ0IGtleSBpcyBwcmVzc2VkIHdoaWxlIHNvcnRpbmcuLi5cbiAgICBpZiAoc2hpZnRLZXkpIHtcbiAgICAgIC8vIC4uLmNoZWNrIGlmIGtleSBpcyBhbHJlYWR5IHNvcnRlZFxuICAgICAgY29uc3QgZXhpc3RpbmdTb3J0UG9zaXRpb24gPSBjdXJyZW50T3JkZXIuZmluZEluZGV4KFxuICAgICAgICAodmFsdWUpID0+IHZhbHVlLmtleSA9PT0ga2V5XG4gICAgICApO1xuICAgICAgaWYgKGV4aXN0aW5nU29ydFBvc2l0aW9uID09PSAtMSkge1xuICAgICAgICAvLyAuLi5pZiBrZXkgaXMgbm90IHNvcnRlZCwgYWRkIGl0IHRvIHRoZSBlbmQgb2YgdGhlIHNvcnQgb3JkZXJcbiAgICAgICAgbmV3T3JkZXIgPSBbLi4uY3VycmVudE9yZGVyLCB7IGtleSwgb3JkZXI6ICdhc2MnIH1dO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gLi4uaWYga2V5IGlzIGFscmVhZHkgc29ydGVkLCB0b2dnbGUgc29ydCBvcmRlclxuICAgICAgICBzb3J0T3JkZXIgPSBjdXJyZW50T3JkZXJbZXhpc3RpbmdTb3J0UG9zaXRpb25dLm9yZGVyO1xuICAgICAgICBjb25zdCBuZXdTb3J0T3JkZXIgPSBzb3J0T3JkZXIgPT09ICdhc2MnID8gJ2Rlc2MnIDogJ2FzYyc7XG4gICAgICAgIG5ld09yZGVyID0gWy4uLmN1cnJlbnRPcmRlcl07XG4gICAgICAgIG5ld09yZGVyW2V4aXN0aW5nU29ydFBvc2l0aW9uXSA9IHtcbiAgICAgICAgICAuLi5uZXdPcmRlcltleGlzdGluZ1NvcnRQb3NpdGlvbl0sXG4gICAgICAgICAgb3JkZXI6IG5ld1NvcnRPcmRlcixcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gLi4uZWxzZSBpZiBzaGlmdCBrZXkgaXMgbm90IHByZXNzZWQuLi5cbiAgICAgIGlmIChjdXJyZW50T3JkZXIubGVuZ3RoID4gMCkge1xuICAgICAgICAvLyAuLi5jaGVjayBpZiBrZXkgaXMgYWxyZWFkeSBzb3J0ZWRcbiAgICAgICAgY29uc3QgZXhpc3RpbmdTb3J0UG9zaXRpb24gPSBjdXJyZW50T3JkZXIuZmluZEluZGV4KFxuICAgICAgICAgICh2YWx1ZSkgPT4gdmFsdWUua2V5ID09PSBrZXlcbiAgICAgICAgKTtcbiAgICAgICAgLy8gLi4uaWYga2V5IGlzIGFscmVhZHkgc29ydGVkLCB0b2dnbGUgc29ydCBvcmRlclxuICAgICAgICBpZiAoZXhpc3RpbmdTb3J0UG9zaXRpb24gPT09IC0xKSB7XG4gICAgICAgICAgbmV3T3JkZXIgPSBbeyBrZXksIG9yZGVyOiAnYXNjJyB9XTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzb3J0T3JkZXIgPSBjdXJyZW50T3JkZXJbZXhpc3RpbmdTb3J0UG9zaXRpb25dLm9yZGVyO1xuICAgICAgICAgIGNvbnN0IG5ld1NvcnRPcmRlciA9IHNvcnRPcmRlciA9PT0gJ2FzYycgPyAnZGVzYycgOiAnYXNjJztcbiAgICAgICAgICBuZXdPcmRlciA9IFt7IGtleSwgb3JkZXI6IG5ld1NvcnRPcmRlciB9XTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gLi4uaWYga2V5IGlzIG5vdCBzb3J0ZWQgc2V0IHNvcnQgb3JkZXIgZm9yIGtleSB0byBhc2NlbmRpbmdcbiAgICAgICAgbmV3T3JkZXIgPSBbeyBrZXksIG9yZGVyOiBzb3J0T3JkZXIgfV07XG4gICAgICB9XG4gICAgfVxuICAgIC8vIGNyZWF0ZSBzb3J0IGV2ZW50XG4gICAgY29uc3Qgc29ydEV2ZW50OiBHdFNvcnRFdmVudCA9IHtcbiAgICAgIGtleSxcbiAgICAgIG9yZGVyOiBzb3J0T3JkZXIsXG4gICAgICBjdXJyZW50U29ydE9yZGVyOiBuZXdPcmRlcixcbiAgICB9O1xuXG4gICAgLy8gaWYgZXZlbnQgaXMgcGFzc2VkIHRvIHNvcnQgZnVuY3Rpb24uLi5cbiAgICBpZiAoJGV2ZW50KSB7XG4gICAgICAvLyAuLi5lbWl0IGl0IGFzIHdlbGxcbiAgICAgIHNvcnRFdmVudC5ldmVudCA9ICRldmVudDtcbiAgICB9XG4gICAgLy8gZW1pdCBzb3J0IGV2ZW50XG4gICAgdGhpcy5jb2x1bW5Tb3J0LmVtaXQoc29ydEV2ZW50KTtcbiAgICAvLyB1cGRhdGUgc29ydCBvcmRlclxuICAgIHRoaXMuc29ydE9yZGVyID0gbmV3T3JkZXI7XG4gIH1cblxuICBjb2x1bW5PcmRlciA9IChcbiAgICBhOiBLZXlWYWx1ZTxzdHJpbmcsIFRhYmxlQ29sdW1uPixcbiAgICBiOiBLZXlWYWx1ZTxzdHJpbmcsIFRhYmxlQ29sdW1uPlxuICApOiBudW1iZXIgPT4ge1xuICAgIHJldHVybiAoYS52YWx1ZS5vcmRlciB8fCAwKSAtIChiLnZhbHVlLm9yZGVyIHx8IDApO1xuICB9O1xuXG4gIG5lc3RlZFZhbHVlKFxuICAgIG9iamVjdDogYW55LFxuICAgIG1hcFRvOiBzdHJpbmcsXG4gICAgbWlzc2luZ1ZhbHVlOiBzdHJpbmcgfCBudW1iZXIgfCBudWxsID0gbnVsbFxuICApOiB1bmtub3duIHtcbiAgICBjb25zdCBsZXZlbHMgPSBtYXBUby5zcGxpdCgnLicpO1xuICAgIHJldHVybiBsZXZlbHMucmVkdWNlKFxuICAgICAgKHByZXZpb3VzVmFsdWUsIGN1cnJlbnRWYWx1ZSwgaW5kZXgpID0+XG4gICAgICAgIHByZXZpb3VzVmFsdWVbY3VycmVudFZhbHVlXSB8fFxuICAgICAgICAoaW5kZXggPT09IGxldmVscy5sZW5ndGggLSAxID8gbWlzc2luZ1ZhbHVlIDoge30pLFxuICAgICAgb2JqZWN0XG4gICAgKTtcbiAgfVxufVxuIiwiPHRhYmxlXG4gIFtuZ0NsYXNzXT1cIih0YWJsZUNvbmZpZyQgfCBhc3luYyk/LmNsYXNzIHx8ICd0YWJsZSdcIlxuICBbY2xhc3MudGFibGUtbW9iaWxlXT1cIih0YWJsZUNvbmZpZyQgfCBhc3luYyk/Lm1vYmlsZUxheW91dFwiXG4gIFtjbGFzcy50YWJsZS1ob3Jpem9udGFsXT1cIih0YWJsZUNvbmZpZyQgfCBhc3luYyk/LnJvd3NcIlxuICBbY2xhc3MudGFibGUtbG9hZGluZ109XCJsb2FkaW5nJCB8IGFzeW5jXCJcbiAgW2NsYXNzLmd0LXN0aWNreS1yb3ctaGVhZGVyXT1cIlxuICAgICh0YWJsZUNvbmZpZyQgfCBhc3luYyk/LnN0aWNreUhlYWRlcnM/LnJvdyAmJiAodGFibGVDb25maWckIHwgYXN5bmMpPy5yb3dzXG4gIFwiXG4gIFtjbGFzcy5ndC1zdGlja3ktY29sdW1uLWhlYWRlcl09XCJcbiAgICAodGFibGVDb25maWckIHwgYXN5bmMpPy5zdGlja3lIZWFkZXJzPy5jb2x1bW5cbiAgXCJcbiAgW2F0dHIuYXJpYS1idXN5XT1cIihsb2FkaW5nJCB8IGFzeW5jKSA9PT0gdHJ1ZSA/IHRydWUgOiBudWxsXCJcbj5cbiAgPHRoZWFkPlxuICAgIDx0clxuICAgICAgKm5nSWY9XCJ7XG4gICAgICAgIGNvbmZpZzogKHRhYmxlQ29uZmlnJCB8IGFzeW5jKSEsXG4gICAgICAgIGlzTG9hZGluZzogbG9hZGluZyQgfCBhc3luY1xuICAgICAgfSBhcyB0YWJsZVwiXG4gICAgPlxuICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIHRhYmxlLmNvbmZpZz8uY29sdW1ucyB8IGtleXZhbHVlOiBjb2x1bW5PcmRlclwiXG4gICAgICA+XG4gICAgICAgIDx0aFxuICAgICAgICAgICpuZ0lmPVwiIWNvbHVtbi52YWx1ZT8uaGlkZGVuXCJcbiAgICAgICAgICBuZ0NsYXNzPVwie3sgKGNvbHVtbi5rZXkgfCBkYXNoQ2FzZSkgKyAnLWNvbHVtbicgfX0ge3tcbiAgICAgICAgICAgIGNvbHVtbi52YWx1ZS5jbGFzc1xuICAgICAgICAgIH19XCJcbiAgICAgICAgICBbY2xhc3MuZGlzYWJsZWRdPVwidGFibGUuaXNMb2FkaW5nXCJcbiAgICAgICAgICBbYXR0ci5hcmlhLXNvcnRdPVwic29ydE9yZGVyJCB8IGFzeW5jIHwgc29ydENsYXNzOiBjb2x1bW4ua2V5OidhcmlhJ1wiXG4gICAgICAgICAgW2NsYXNzLmd0LXNvcnRhYmxlXT1cInRydWVcIlxuICAgICAgICAgIHNjb3BlPVwiY29sXCJcbiAgICAgICAgPlxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICpuZ0lmPVwiY29sdW1uLnZhbHVlPy5zb3J0YWJsZVwiXG4gICAgICAgICAgICBbYXR0ci5kYXRhLXNvcnQtb3JkZXJdPVwiXG4gICAgICAgICAgICAgIHNvcnRPcmRlciQgfCBhc3luYyB8IHNvcnRDbGFzczogY29sdW1uLmtleTonb3JkZXInXG4gICAgICAgICAgICBcIlxuICAgICAgICAgICAgY2xhc3M9XCJndC1zb3J0XCJcbiAgICAgICAgICAgIChjbGljayk9XCJcbiAgICAgICAgICAgICAgdGFibGUuaXNMb2FkaW5nIHx8XG4gICAgICAgICAgICAgICAgIWNvbHVtbi52YWx1ZS5zb3J0YWJsZSB8fFxuICAgICAgICAgICAgICAgIHNvcnRCeUtleShjb2x1bW4ua2V5LCAkZXZlbnQpXG4gICAgICAgICAgICBcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiY29sdW1uLnZhbHVlPy5oZWFkZXIgIT09IGZhbHNlXCI+e3tcbiAgICAgICAgICAgICAgY29sdW1uLnZhbHVlLmhlYWRlciB8fCBjb2x1bW4ua2V5IHwgY2FwaXRhbENhc2VcbiAgICAgICAgICAgIH19PC9zcGFuPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAqbmdJZj1cIiFjb2x1bW4udmFsdWU/LnNvcnRhYmxlICYmIGNvbHVtbi52YWx1ZT8uaGVhZGVyICE9PSBmYWxzZVwiXG4gICAgICAgICAgICA+e3sgY29sdW1uLnZhbHVlLmhlYWRlciB8fCBjb2x1bW4ua2V5IHwgY2FwaXRhbENhc2UgfX08L3NwYW5cbiAgICAgICAgICA+XG4gICAgICAgIDwvdGg+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgKm5nSWY9XCJcbiAgICAgICAgICAoKHRhYmxlPy5jb25maWc/LnJvd3MgfCBrZXl2YWx1ZTogY29sdW1uT3JkZXIpIHx8IFtdKVswXSBhcyBoZWFkZXJSb3dcbiAgICAgICAgXCJcbiAgICAgID5cbiAgICAgICAgPHRoXG4gICAgICAgICAgY2xhc3M9XCJyb3ctaGVhZGVyXCJcbiAgICAgICAgICBbYXR0ci5hcmlhLXNvcnRdPVwiXG4gICAgICAgICAgICBzb3J0T3JkZXIkIHwgYXN5bmMgfCBzb3J0Q2xhc3M6IGhlYWRlclJvdy5rZXk6J2FyaWEnXG4gICAgICAgICAgXCJcbiAgICAgICAgICBuZ0NsYXNzPVwie3sgaGVhZGVyUm93LnZhbHVlLnNvcnRhYmxlID8gJ3NvcnQgJyA6ICcnIH19IHt7XG4gICAgICAgICAgICBzb3J0T3JkZXIkIHwgYXN5bmMgfCBzb3J0Q2xhc3M6IGhlYWRlclJvdy5rZXlcbiAgICAgICAgICB9fSB7eyAoaGVhZGVyUm93LmtleSB8IGRhc2hDYXNlKSArICctY29sdW1uJyB9fVwiXG4gICAgICAgICAgKGNsaWNrKT1cIlxuICAgICAgICAgICAgdGFibGUuaXNMb2FkaW5nIHx8XG4gICAgICAgICAgICAgICFoZWFkZXJSb3cudmFsdWUuc29ydGFibGUgfHxcbiAgICAgICAgICAgICAgc29ydEJ5S2V5KGhlYWRlclJvdy5rZXksICRldmVudClcbiAgICAgICAgICBcIlxuICAgICAgICAgIHNjb3BlPVwiY29sXCJcbiAgICAgICAgPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJoZWFkZXJSb3c/LnZhbHVlPy5oZWFkZXIgIT09IGZhbHNlXCI+e3tcbiAgICAgICAgICAgIGhlYWRlclJvdz8udmFsdWU/LmhlYWRlciB8fCBoZWFkZXJSb3cua2V5IHwgY2FwaXRhbENhc2VcbiAgICAgICAgICB9fTwvbmctY29udGFpbmVyPlxuICAgICAgICA8L3RoPlxuICAgICAgICA8dGhcbiAgICAgICAgICAqbmdGb3I9XCJsZXQgY29sdW1uIG9mICgodGFibGUkIHwgYXN5bmMpPy5kYXRhIHx8IFtdKVswXVwiXG4gICAgICAgICAgbmdDbGFzcz1cInt7IGhlYWRlclJvdy52YWx1ZS5jbGFzcyB9fVwiXG4gICAgICAgID5cbiAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJcbiAgICAgICAgICAgICAgKHRhYmxlLmNvbmZpZy5yb3dzIHx8IHt9KVtoZWFkZXJSb3cua2V5XS50ZW1wbGF0ZVJlZlxuICAgICAgICAgICAgICAgID8gdGVtcGxhdGVSZWZcbiAgICAgICAgICAgICAgICA6ICh0YWJsZS5jb25maWcucm93cyB8fCB7fSlbaGVhZGVyUm93LmtleV0udHJhbnNmb3JtXG4gICAgICAgICAgICAgICAgPyB0cmFuc2Zvcm1EYXRhXG4gICAgICAgICAgICAgICAgOiByYXdEYXRhXG4gICAgICAgICAgICBcIlxuICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cIntcbiAgICAgICAgICAgICAgcm93OiBjb2x1bW4sXG4gICAgICAgICAgICAgIGNvbHVtbjogaGVhZGVyUm93LFxuICAgICAgICAgICAgICB0cmFuc2Zvcm06ICh0YWJsZS5jb25maWcucm93cyB8fCB7fSlbaGVhZGVyUm93LmtleV0udHJhbnNmb3JtLFxuICAgICAgICAgICAgICB0ZW1wbGF0ZVJlZjogKHRhYmxlLmNvbmZpZy5yb3dzIHx8IHt9KVtoZWFkZXJSb3cua2V5XS50ZW1wbGF0ZVJlZixcbiAgICAgICAgICAgICAgaW5kZXg6IDBcbiAgICAgICAgICAgIH1cIlxuICAgICAgICAgID5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC90aD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvdHI+XG4gIDwvdGhlYWQ+XG4gIDx0Ym9keSAqbmdJZj1cImxvYWRpbmckIHwgYXN5bmM7IGVsc2UgdGFibGVDb250ZW50XCI+XG4gICAgPHRyPlxuICAgICAgPHRkIGNsYXNzPVwicC0wXCIgW2NvbFNwYW5dPVwiY29sc3BhbiQgfCBhc3luY1wiPlxuICAgICAgICA8bmctY29udGVudCBzZWxlY3Q9XCIudGFibGUtbG9hZGluZ1wiPjwvbmctY29udGVudD5cbiAgICAgIDwvdGQ+XG4gICAgPC90cj5cbiAgPC90Ym9keT5cbiAgPHRmb290ICpuZ0lmPVwiKHRhYmxlJCB8IGFzeW5jKSEgYXMgdGFibGVcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwidGFibGUuZGF0YS5sZW5ndGggPiAwICYmICEobG9hZGluZyQgfCBhc3luYylcIj5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIoY2FsY3VsYXRpb25zJCB8IGFzeW5jKSEgYXMgY2FsY3VsYXRpb25zXCI+XG4gICAgICAgIDx0clxuICAgICAgICAgICpuZ0Zvcj1cImxldCBjYWxjdWxhdGlvbiBvZiBjYWxjdWxhdGlvbnMuY2FsY3VsYXRpb25zOyBsZXQgaSA9IGluZGV4XCJcbiAgICAgICAgPlxuICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICpuZ0lmPVwie1xuICAgICAgICAgICAgICBzaG93SGVhZGVyOiAoY29sc3BhbiQgfCBhc3luYykgIT09IChmb290ZXJDb2xzcGFuJCB8IGFzeW5jKVxuICAgICAgICAgICAgfSBhcyBmb290ZXJSb3dcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDx0aFxuICAgICAgICAgICAgICAqbmdJZj1cImZvb3RlclJvdy5zaG93SGVhZGVyXCJcbiAgICAgICAgICAgICAgW2NvbFNwYW5dPVwiXG4gICAgICAgICAgICAgICAgKChjb2xzcGFuJCB8IGFzeW5jKSB8fCAwKSAtICgoZm9vdGVyQ29sc3BhbiQgfCBhc3luYykgfHwgMClcbiAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgc2NvcGU9XCJyb3dcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJ0YWJsZS5jb25maWc/LmZvb3Rlcj8uaGVhZGVycz8uW2NhbGN1bGF0aW9uXSBhcyBzaG93SGVhZGVyXCJcbiAgICAgICAgICAgICAgICA+e3tzaG93SGVhZGVyID09PSB0cnVlID8gKGNhbGN1bGF0aW9uIHwgY2FwaXRhbENhc2UpOiB0YWJsZS5jb25maWcuZm9vdGVyPy5oZWFkZXJzPy5bY2FsY3VsYXRpb25dfX1cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAqbmdGb3I9XCJcbiAgICAgICAgICAgICAgICBsZXQgY29sdW1uIG9mIHRhYmxlLmNvbmZpZz8uY29sdW1ucyB8IGtleXZhbHVlOiBjb2x1bW5PcmRlclxuICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8dGRcbiAgICAgICAgICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgICAgICAgICAgIWNvbHVtbi52YWx1ZT8uaGlkZGVuICYmIGNhbGN1bGF0aW9ucy5jYWxjdWxhdGVkW2NvbHVtbi5rZXldXG4gICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICBuZ0NsYXNzPVwie3sgKGNvbHVtbi5rZXkgfCBkYXNoQ2FzZSkgKyAnLWNvbHVtbicgfX0ge3tcbiAgICAgICAgICAgICAgICAgIGNvbHVtbi52YWx1ZS5jbGFzc1xuICAgICAgICAgICAgICAgIH19XCJcbiAgICAgICAgICAgICAgICBbYXR0ci5kYXRhLWhlYWRlcl09XCJcbiAgICAgICAgICAgICAgICAgICFmb290ZXJSb3cuc2hvd0hlYWRlciAmJiB0YWJsZS5jb25maWcuZm9vdGVyPy5oZWFkZXJzPy5bY2FsY3VsYXRpb25dXG4gICAgICAgICAgICAgICAgICAgID8gdGFibGUuY29uZmlnLmZvb3Rlcj8uaGVhZGVycz8uW2NhbGN1bGF0aW9uXSA9PT0gdHJ1ZSA/IChjYWxjdWxhdGlvbiB8IGNhcGl0YWxDYXNlKSA6IHRhYmxlLmNvbmZpZy5mb290ZXI/LmhlYWRlcnM/LltjYWxjdWxhdGlvbl1cbiAgICAgICAgICAgICAgICAgICAgOiBudWxsXG4gICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICBbYXR0ci5kYXRhLWxhYmVsXT1cIlxuICAgICAgICAgICAgICAgICAgdGFibGUuY29uZmlnLm1vYmlsZUxheW91dCAmJiBjb2x1bW4udmFsdWUubW9iaWxlSGVhZGVyXG4gICAgICAgICAgICAgICAgICAgID8gY29sdW1uLnZhbHVlLm1vYmlsZUhlYWRlciAhPT0gdHJ1ZVxuICAgICAgICAgICAgICAgICAgICAgID8gY29sdW1uLnZhbHVlLm1vYmlsZUhlYWRlclxuICAgICAgICAgICAgICAgICAgICAgIDogKGNvbHVtbi52YWx1ZS5oZWFkZXIgfHwgY29sdW1uLmtleSB8IGNhcGl0YWxDYXNlKVxuICAgICAgICAgICAgICAgICAgICA6IG51bGxcbiAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5ndC1uby1jb250ZW50XT1cIlxuICAgICAgICAgICAgICAgICAgIWNhbGN1bGF0aW9ucy5jYWxjdWxhdGVkW2NvbHVtbi5rZXldW2NhbGN1bGF0aW9uXVxuICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJcbiAgICAgICAgICAgICAgICAgICAgKHRhYmxlLmNvbmZpZy5jb2x1bW5zIHx8IHt9KVtjb2x1bW4ua2V5XS50ZW1wbGF0ZVJlZlxuICAgICAgICAgICAgICAgICAgICAgID8gdGVtcGxhdGVSZWZcbiAgICAgICAgICAgICAgICAgICAgICA6ICh0YWJsZS5jb25maWcuY29sdW1ucyB8fCB7fSlbY29sdW1uLmtleV0udHJhbnNmb3JtXG4gICAgICAgICAgICAgICAgICAgICAgPyB0cmFuc2Zvcm1Gb290ZXJcbiAgICAgICAgICAgICAgICAgICAgICA6IHJhd0Zvb3RlclxuICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiBjYWxjdWxhdGlvbnMuY2FsY3VsYXRlZFtjb2x1bW4ua2V5XVtjYWxjdWxhdGlvbl0sXG4gICAgICAgICAgICAgICAgICAgIHJvdzogY2FsY3VsYXRpb25zLmNhbGN1bGF0ZWRbY29sdW1uLmtleV0sXG4gICAgICAgICAgICAgICAgICAgIGNvbHVtbjogY2FsY3VsYXRpb24sXG4gICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlUmVmOiAodGFibGUuY29uZmlnLmNvbHVtbnMgfHwge30pW2NvbHVtbi5rZXldXG4gICAgICAgICAgICAgICAgICAgICAgLnRlbXBsYXRlUmVmLFxuICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm06ICh0YWJsZS5jb25maWcuY29sdW1ucyB8fCB7fSlbY29sdW1uLmtleV1cbiAgICAgICAgICAgICAgICAgICAgICAudHJhbnNmb3JtXG4gICAgICAgICAgICAgICAgICB9XCJcbiAgICAgICAgICAgICAgICA+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC90cj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L3Rmb290PlxuPC90YWJsZT5cbjxuZy10ZW1wbGF0ZSAjdGFibGVDb250ZW50PlxuICA8bmctY29udGFpbmVyICpuZ0lmPVwiKHRhYmxlJCB8IGFzeW5jKSEgYXMgdGFibGVcIj5cbiAgICA8dGJvZHkgKm5nSWY9XCIodGFibGUhLmRhdGEhWzBdIHx8IHRhYmxlIS5kYXRhISkubGVuZ3RoID4gMDsgZWxzZSBub0RhdGFcIj5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJ0YWJsZS5jb25maWcuY29sdW1uc1wiPlxuICAgICAgICA8dHJcbiAgICAgICAgICAqbmdGb3I9XCJcbiAgICAgICAgICAgIGxldCByb3cgb2YgdGFibGUhLmRhdGEhWyhjdXJyZW50UGFnZSQgfCBhc3luYykgfHwgMF07XG4gICAgICAgICAgICBsZXQgaSA9IGluZGV4XG4gICAgICAgICAgXCJcbiAgICAgICAgICBbYXR0ci5pZF09XCIndGFibGVSb3dfJyArIGlcIlxuICAgICAgICAgIChjbGljayk9XCJ0YWJsZT8uY29uZmlnPy5yb3dDbGljayAmJiBfcm93Q2xpY2socm93LCBpLCAkZXZlbnQpXCJcbiAgICAgICAgICAobW91c2VvdmVyKT1cInRhYmxlPy5jb25maWc/LnJvd0hvdmVyICYmIF9ob3ZlclJvdyhyb3csIGksICRldmVudClcIlxuICAgICAgICAgIChtb3VzZW91dCk9XCJ0YWJsZT8uY29uZmlnPy5yb3dIb3ZlciAmJiBfaG92ZXJSb3cobnVsbCwgbnVsbCwgJGV2ZW50KVwiXG4gICAgICAgICAgW2NsYXNzLmd0LWhvdmVyXT1cIihyb3dIb3ZlciQgfCBhc3luYyk/LmluZGV4ID09PSBpXCJcbiAgICAgICAgPlxuICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgdGFibGUuY29uZmlnPy5jb2x1bW5zIHwga2V5dmFsdWU6IGNvbHVtbk9yZGVyXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8dGRcbiAgICAgICAgICAgICAgKm5nSWY9XCIhY29sdW1uLnZhbHVlPy5oaWRkZW5cIlxuICAgICAgICAgICAgICBuZ0NsYXNzPVwie3sgKGNvbHVtbi5rZXkgfCBkYXNoQ2FzZSkgKyAnLWNvbHVtbicgfX0ge3tcbiAgICAgICAgICAgICAgICBjb2x1bW4udmFsdWUuY2xhc3NcbiAgICAgICAgICAgICAgfX1cIlxuICAgICAgICAgICAgICBbYXR0ci5kYXRhLWxhYmVsXT1cIlxuICAgICAgICAgICAgICAgIHRhYmxlLmNvbmZpZy5tb2JpbGVMYXlvdXQgJiYgY29sdW1uLnZhbHVlLm1vYmlsZUhlYWRlclxuICAgICAgICAgICAgICAgICAgPyBjb2x1bW4udmFsdWUubW9iaWxlSGVhZGVyICE9PSB0cnVlXG4gICAgICAgICAgICAgICAgICAgID8gY29sdW1uLnZhbHVlLm1vYmlsZUhlYWRlclxuICAgICAgICAgICAgICAgICAgICA6IChjb2x1bW4udmFsdWUuaGVhZGVyIHx8IGNvbHVtbi5rZXkgfCBjYXBpdGFsQ2FzZSlcbiAgICAgICAgICAgICAgICAgIDogbnVsbFxuICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwiXG4gICAgICAgICAgICAgICAgICAoc2VhcmNoQnkkIHwgYXN5bmMpICYmXG4gICAgICAgICAgICAgICAgICAhKHRhYmxlLmNvbmZpZy5jb2x1bW5zIHx8IHt9KVtjb2x1bW4ua2V5XS50ZW1wbGF0ZVJlZlxuICAgICAgICAgICAgICAgICAgICA/IGhpZ2hsaWdodGVkXG4gICAgICAgICAgICAgICAgICAgIDogKHRhYmxlLmNvbmZpZy5jb2x1bW5zIHx8IHt9KVtjb2x1bW4ua2V5XS50ZW1wbGF0ZVJlZlxuICAgICAgICAgICAgICAgICAgICA/IHRlbXBsYXRlUmVmXG4gICAgICAgICAgICAgICAgICAgIDogKHRhYmxlLmNvbmZpZy5jb2x1bW5zIHx8IHt9KVtjb2x1bW4ua2V5XS50cmFuc2Zvcm1cbiAgICAgICAgICAgICAgICAgICAgPyB0cmFuc2Zvcm1EYXRhXG4gICAgICAgICAgICAgICAgICAgIDogcmF3RGF0YVxuICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cIntcbiAgICAgICAgICAgICAgICAgIHJvdzogcm93LFxuICAgICAgICAgICAgICAgICAgY29sdW1uOiBjb2x1bW4sXG4gICAgICAgICAgICAgICAgICBzZWFyY2g6IChzZWFyY2hCeSQgfCBhc3luYyksXG4gICAgICAgICAgICAgICAgICB0cmFuc2Zvcm06ICh0YWJsZS5jb25maWcuY29sdW1ucyB8fCB7fSlbY29sdW1uLmtleV0udHJhbnNmb3JtLFxuICAgICAgICAgICAgICAgICAgdGVtcGxhdGVSZWY6ICh0YWJsZS5jb25maWcuY29sdW1ucyB8fCB7fSlbY29sdW1uLmtleV1cbiAgICAgICAgICAgICAgICAgICAgLnRlbXBsYXRlUmVmLFxuICAgICAgICAgICAgICAgICAgaW5kZXg6IGksXG4gICAgICAgICAgICAgICAgICBkYXRhOiB0YWJsZS5kYXRhWyhjdXJyZW50UGFnZSQgfCBhc3luYykgfHwgMF1cbiAgICAgICAgICAgICAgICB9XCJcbiAgICAgICAgICAgICAgPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC90cj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInRhYmxlLmNvbmZpZy5yb3dzXCI+XG4gICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAqbmdGb3I9XCJcbiAgICAgICAgICAgIGxldCByb3cgb2YgdGFibGU/LmNvbmZpZz8ucm93cyB8IGtleXZhbHVlOiBjb2x1bW5PcmRlciB8IHNsaWNlOiAxO1xuICAgICAgICAgICAgbGV0IGkgPSBpbmRleFxuICAgICAgICAgIFwiXG4gICAgICAgID5cbiAgICAgICAgICA8dHJcbiAgICAgICAgICAgICpuZ0lmPVwiIXJvdy52YWx1ZT8uaGlkZGVuXCJcbiAgICAgICAgICAgIFthdHRyLmlkXT1cIid0YWJsZVJvd18nICsgaVwiXG4gICAgICAgICAgICBuZ0NsYXNzPVwie3sgKHJvdy5rZXkgfCBkYXNoQ2FzZSkgKyAnLXJvdycgfX1cIlxuICAgICAgICAgICAgKGNsaWNrKT1cInRhYmxlPy5jb25maWc/LnJvd0NsaWNrICYmIF9yb3dDbGljayhyb3csIGksICRldmVudClcIlxuICAgICAgICAgICAgKG1vdXNlb3Zlcik9XCJ0YWJsZT8uY29uZmlnPy5yb3dIb3ZlciAmJiBfaG92ZXJSb3cocm93LCBpLCAkZXZlbnQpXCJcbiAgICAgICAgICAgIChtb3VzZW91dCk9XCJcbiAgICAgICAgICAgICAgdGFibGU/LmNvbmZpZz8ucm93SG92ZXIgJiYgX2hvdmVyUm93KG51bGwsIG51bGwsICRldmVudClcbiAgICAgICAgICAgIFwiXG4gICAgICAgICAgICBbY2xhc3MuZ3QtaG92ZXJdPVwiKHJvd0hvdmVyJCB8IGFzeW5jKT8uaW5kZXggPT09IGlcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDx0aCBjbGFzcz1cInJvdy1oZWFkZXJcIiBzY29wZT1cInJvd1wiPlxuICAgICAgICAgICAgICB7eyByb3cudmFsdWUuaGVhZGVyIHx8IHJvdy5rZXkgfCBjYXBpdGFsQ2FzZSB9fVxuICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgIDx0ZFxuICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgY29sdW1uIG9mICh0YWJsZT8uZGF0YSB8fCBbXSlbMF07IGxldCB5ID0gaW5kZXhcIlxuICAgICAgICAgICAgICBuZ0NsYXNzPVwie3sgcm93LnZhbHVlLmNsYXNzIH19XCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cIlxuICAgICAgICAgICAgICAgICAgKHRhYmxlLmNvbmZpZy5yb3dzIHx8IHt9KVtyb3cua2V5XS50ZW1wbGF0ZVJlZlxuICAgICAgICAgICAgICAgICAgICA/IHRlbXBsYXRlUmVmXG4gICAgICAgICAgICAgICAgICAgIDogKHRhYmxlLmNvbmZpZy5yb3dzIHx8IHt9KVtyb3cua2V5XS50cmFuc2Zvcm1cbiAgICAgICAgICAgICAgICAgICAgPyB0cmFuc2Zvcm1EYXRhXG4gICAgICAgICAgICAgICAgICAgIDogcmF3RGF0YVxuICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cIntcbiAgICAgICAgICAgICAgICAgIHJvdzogY29sdW1uLFxuICAgICAgICAgICAgICAgICAgY29sdW1uOiByb3csXG4gICAgICAgICAgICAgICAgICB0cmFuc2Zvcm06ICh0YWJsZS5jb25maWcucm93cyB8fCB7fSlbcm93LmtleV0udHJhbnNmb3JtLFxuICAgICAgICAgICAgICAgICAgdGVtcGxhdGVSZWY6ICh0YWJsZS5jb25maWcucm93cyB8fCB7fSlbcm93LmtleV0udGVtcGxhdGVSZWYsXG4gICAgICAgICAgICAgICAgICBpbmRleDogdGFibGUuY29uZmlnLnJvd3MgPyB5IDogaSxcbiAgICAgICAgICAgICAgICAgIGRhdGE6IHRhYmxlLmRhdGFbKGN1cnJlbnRQYWdlJCB8IGFzeW5jKSB8fCAwXVxuICAgICAgICAgICAgICAgIH1cIlxuICAgICAgICAgICAgICA+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=