@onecx/angular-accelerator 6.0.0-rc.3 → 6.0.0-rc.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/assets/i18n/de.json +3 -3
  2. package/assets/i18n/en.json +3 -3
  3. package/assets/i18n/primeng/de.json +3 -0
  4. package/assets/i18n/primeng/en.json +3 -0
  5. package/assets/styles.scss +0 -4
  6. package/fesm2022/onecx-angular-accelerator-testing.mjs +90 -28
  7. package/fesm2022/onecx-angular-accelerator-testing.mjs.map +1 -1
  8. package/fesm2022/onecx-angular-accelerator.mjs +808 -396
  9. package/fesm2022/onecx-angular-accelerator.mjs.map +1 -1
  10. package/index.d.ts +9 -0
  11. package/lib/angular-accelerator-primeng.module.d.ts +6 -4
  12. package/lib/angular-accelerator.module.d.ts +26 -20
  13. package/lib/components/content/content.component.d.ts +13 -0
  14. package/lib/components/content-container/content-container.component.d.ts +19 -0
  15. package/lib/components/custom-group-column-selector/custom-group-column-selector.component.d.ts +0 -2
  16. package/lib/components/data-list-grid/data-list-grid.component.d.ts +6 -18
  17. package/lib/components/data-list-grid-sorting/data-list-grid-sorting.component.d.ts +2 -2
  18. package/lib/components/data-table/data-table.component.d.ts +7 -19
  19. package/lib/components/data-view/data-view.component.d.ts +7 -8
  20. package/lib/components/diagram/diagram.component.d.ts +0 -2
  21. package/lib/components/filter-view/filter-view.component.d.ts +2 -2
  22. package/lib/components/group-by-count-diagram/group-by-count-diagram.component.d.ts +0 -2
  23. package/lib/components/interactive-data-view/interactive-data-view.component.d.ts +7 -6
  24. package/lib/components/lifecycle/lifecycle.component.d.ts +12 -0
  25. package/lib/components/page-header/page-header.component.d.ts +1 -4
  26. package/lib/components/search-header/search-header.component.d.ts +2 -3
  27. package/lib/directives/advanced.directive.d.ts +5 -6
  28. package/lib/directives/content-container.directive.d.ts +23 -0
  29. package/lib/directives/content.directive.d.ts +21 -0
  30. package/lib/directives/if-breakpoint.directive.d.ts +3 -4
  31. package/lib/directives/if-permission.directive.d.ts +6 -17
  32. package/lib/directives/src.directive.d.ts +2 -3
  33. package/lib/directives/template.directive.d.ts +9 -0
  34. package/lib/directives/tooltipOnOverflow.directive.d.ts +2 -3
  35. package/lib/injection-tokens/has-permission-checker.d.ts +13 -0
  36. package/lib/model/filter.model.d.ts +16 -4
  37. package/lib/pipes/dynamic.pipe.d.ts +2 -2
  38. package/lib/pipes/ocxtimeago.pipe.d.ts +3 -3
  39. package/lib/services/breadcrumb.service.d.ts +2 -4
  40. package/lib/services/connection.service.d.ts +10 -0
  41. package/lib/services/translation-cache.service.d.ts +3 -0
  42. package/lib/utils/async-translate-loader.utils.d.ts +3 -0
  43. package/lib/utils/caching-translate-loader.utils.d.ts +3 -0
  44. package/lib/utils/create-translate-loader.utils.d.ts +3 -0
  45. package/lib/utils/criteria.utils.d.ts +3 -3
  46. package/lib/utils/data-operation-strategy.d.ts +20 -0
  47. package/lib/utils/dateutils.d.ts +0 -1
  48. package/lib/utils/provide-connection-service.d.ts +6 -0
  49. package/lib/utils/translate.combined.loader.d.ts +3 -0
  50. package/package.json +17 -17
  51. package/testing/column-group-selection.harness.d.ts +2 -2
  52. package/testing/content-container.harness.d.ts +7 -0
  53. package/testing/content.harness.d.ts +10 -0
  54. package/testing/data-layout-selection.harness.d.ts +7 -6
  55. package/testing/index.d.ts +3 -0
  56. package/testing/interactive-data-view.harness.d.ts +5 -3
  57. package/testing/lifecycle.harness.d.ts +6 -0
  58. package/esm2022/index.mjs +0 -61
  59. package/esm2022/lib/angular-accelerator-primeng.module.mjs +0 -146
  60. package/esm2022/lib/angular-accelerator.module.mjs +0 -194
  61. package/esm2022/lib/components/column-group-selection/column-group-selection.component.mjs +0 -90
  62. package/esm2022/lib/components/custom-group-column-selector/custom-group-column-selector.component.mjs +0 -184
  63. package/esm2022/lib/components/data-layout-selection/data-layout-selection.component.mjs +0 -73
  64. package/esm2022/lib/components/data-list-grid/data-list-grid.component.mjs +0 -615
  65. package/esm2022/lib/components/data-list-grid-sorting/data-list-grid-sorting.component.mjs +0 -107
  66. package/esm2022/lib/components/data-loading-error/data-loading-error.component.mjs +0 -28
  67. package/esm2022/lib/components/data-sort-base/data-sort-base.mjs +0 -134
  68. package/esm2022/lib/components/data-table/data-table.component.mjs +0 -828
  69. package/esm2022/lib/components/data-view/data-view.component.mjs +0 -672
  70. package/esm2022/lib/components/diagram/diagram.component.mjs +0 -183
  71. package/esm2022/lib/components/filter-view/filter-view.component.mjs +0 -263
  72. package/esm2022/lib/components/group-by-count-diagram/group-by-count-diagram.component.mjs +0 -133
  73. package/esm2022/lib/components/interactive-data-view/interactive-data-view.component.mjs +0 -724
  74. package/esm2022/lib/components/page-header/page-header.component.mjs +0 -238
  75. package/esm2022/lib/components/search-header/search-header.component.mjs +0 -199
  76. package/esm2022/lib/directives/advanced.directive.mjs +0 -36
  77. package/esm2022/lib/directives/if-breakpoint.directive.mjs +0 -47
  78. package/esm2022/lib/directives/if-permission.directive.mjs +0 -103
  79. package/esm2022/lib/directives/src.directive.mjs +0 -65
  80. package/esm2022/lib/directives/tooltipOnOverflow.directive.mjs +0 -48
  81. package/esm2022/lib/functions/at-least-one-field-filled-validator.mjs +0 -7
  82. package/esm2022/lib/functions/flatten-object.mjs +0 -20
  83. package/esm2022/lib/model/breadcrumb-menu-item.model.mjs +0 -2
  84. package/esm2022/lib/model/column-type.model.mjs +0 -16
  85. package/esm2022/lib/model/data-action.mjs +0 -2
  86. package/esm2022/lib/model/data-column-name-id.model.mjs +0 -2
  87. package/esm2022/lib/model/data-sort-direction.mjs +0 -2
  88. package/esm2022/lib/model/data-table-column.model.mjs +0 -2
  89. package/esm2022/lib/model/diagram-column.mjs +0 -2
  90. package/esm2022/lib/model/diagram-data.mjs +0 -2
  91. package/esm2022/lib/model/diagram-type.mjs +0 -2
  92. package/esm2022/lib/model/filter.model.mjs +0 -6
  93. package/esm2022/lib/pipes/dynamic.pipe.mjs +0 -58
  94. package/esm2022/lib/pipes/ocxtimeago.pipe.mjs +0 -107
  95. package/esm2022/lib/services/breadcrumb.service.mjs +0 -128
  96. package/esm2022/lib/services/translation-cache.service.mjs +0 -41
  97. package/esm2022/lib/utils/async-translate-loader.utils.mjs +0 -12
  98. package/esm2022/lib/utils/caching-translate-loader.utils.mjs +0 -15
  99. package/esm2022/lib/utils/colorutils.mjs +0 -19
  100. package/esm2022/lib/utils/create-remote-component-and-mfe-translate-loader.utils.mjs +0 -12
  101. package/esm2022/lib/utils/create-remote-component-translate-loader.utils.mjs +0 -25
  102. package/esm2022/lib/utils/create-translate-loader.utils.mjs +0 -27
  103. package/esm2022/lib/utils/criteria.utils.mjs +0 -28
  104. package/esm2022/lib/utils/dateutils.mjs +0 -38
  105. package/esm2022/lib/utils/dynamic-locale-id.mjs +0 -21
  106. package/esm2022/lib/utils/enum-to-dropdown-options.utils.mjs +0 -8
  107. package/esm2022/lib/utils/filter.utils.mjs +0 -6
  108. package/esm2022/lib/utils/objectutils.mjs +0 -30
  109. package/esm2022/lib/utils/primeicon.utils.mjs +0 -2
  110. package/esm2022/lib/utils/rxjs-utils.mjs +0 -13
  111. package/esm2022/lib/utils/string-and-array-helper-functions.utils.mjs +0 -22
  112. package/esm2022/lib/utils/template.utils.mjs +0 -11
  113. package/esm2022/lib/utils/translate.combined.loader.mjs +0 -39
  114. package/esm2022/onecx-angular-accelerator.mjs +0 -5
  115. package/esm2022/testing/column-group-selection.harness.mjs +0 -10
  116. package/esm2022/testing/custom-group-column-selector.harness.mjs +0 -31
  117. package/esm2022/testing/data-layout-selection.harness.mjs +0 -32
  118. package/esm2022/testing/data-list-grid.harness.mjs +0 -51
  119. package/esm2022/testing/data-table.harness.mjs +0 -69
  120. package/esm2022/testing/data-view.harness.mjs +0 -12
  121. package/esm2022/testing/default-grid-item.harness.mjs +0 -24
  122. package/esm2022/testing/default-list-item.harness.mjs +0 -26
  123. package/esm2022/testing/diagram.harness.mjs +0 -22
  124. package/esm2022/testing/filter-view.harness.mjs +0 -18
  125. package/esm2022/testing/group-by-count-diagram.harness.mjs +0 -10
  126. package/esm2022/testing/index.mjs +0 -23
  127. package/esm2022/testing/interactive-data-view.harness.mjs +0 -21
  128. package/esm2022/testing/more-actions-menu-button.harness.mjs +0 -35
  129. package/esm2022/testing/onecx-angular-accelerator-testing.mjs +0 -5
  130. package/esm2022/testing/page-header.harness.mjs +0 -81
  131. package/esm2022/testing/search-header.harness.mjs +0 -36
  132. package/esm2022/testing/slot.harness.mjs +0 -5
@@ -1,828 +0,0 @@
1
- import { Component, ContentChild, ContentChildren, EventEmitter, Inject, Injector, Input, LOCALE_ID, Output, ViewChildren, } from '@angular/core';
2
- import { Router } from '@angular/router';
3
- import { TranslateService } from '@ngx-translate/core';
4
- import { isValidDate } from '@onecx/accelerator';
5
- import { UserService } from '@onecx/angular-integration-interface';
6
- import { PrimeTemplate } from 'primeng/api';
7
- import { BehaviorSubject, combineLatest, debounceTime, filter, first, map, mergeMap, of, withLatestFrom, } from 'rxjs';
8
- import { ColumnType } from '../../model/column-type.model';
9
- import { ObjectUtils } from '../../utils/objectutils';
10
- import { DataSortBase } from '../data-sort-base/data-sort-base';
11
- import { FilterType } from '../../model/filter.model';
12
- import { findTemplate } from '../../utils/template.utils';
13
- import * as i0 from "@angular/core";
14
- import * as i1 from "@ngx-translate/core";
15
- import * as i2 from "@angular/router";
16
- import * as i3 from "@onecx/angular-integration-interface";
17
- import * as i4 from "@angular/common";
18
- import * as i5 from "primeng/tooltip";
19
- import * as i6 from "primeng/api";
20
- import * as i7 from "primeng/checkbox";
21
- import * as i8 from "primeng/button";
22
- import * as i9 from "primeng/table";
23
- import * as i10 from "primeng/menu";
24
- import * as i11 from "primeng/multiselect";
25
- import * as i12 from "primeng/skeleton";
26
- import * as i13 from "@angular/forms";
27
- import * as i14 from "../../directives/if-permission.directive";
28
- import * as i15 from "../../pipes/ocxtimeago.pipe";
29
- export var TemplateType;
30
- (function (TemplateType) {
31
- TemplateType["CELL"] = "CELL";
32
- TemplateType["FILTERCELL"] = "FILTERCELL";
33
- })(TemplateType || (TemplateType = {}));
34
- export class DataTableComponent extends DataSortBase {
35
- get rows() {
36
- return this._rows$.getValue();
37
- }
38
- set rows(value) {
39
- !this._rows$.getValue().length ?? this.resetPage();
40
- this._rows$.next(value);
41
- }
42
- set selectedRows(value) {
43
- this._selectionIds$.next(value.map((row) => {
44
- if (typeof row === 'object') {
45
- return row.id;
46
- }
47
- return row;
48
- }));
49
- }
50
- get filters() {
51
- return this._filters$.getValue();
52
- }
53
- set filters(value) {
54
- !this._filters$.getValue().length ?? this.resetPage();
55
- this._filters$.next(value);
56
- }
57
- get sortDirection() {
58
- return this._sortDirection$.getValue();
59
- }
60
- set sortDirection(value) {
61
- this._sortDirection$.next(value);
62
- }
63
- get sortColumn() {
64
- return this?._sortColumn$.getValue();
65
- }
66
- set sortColumn(value) {
67
- this?._sortColumn$.next(value);
68
- }
69
- get columns() {
70
- return this._columns$.getValue();
71
- }
72
- set columns(value) {
73
- this._columns$.next(value);
74
- const obs = value.map((c) => this.getTemplate(c, TemplateType.CELL));
75
- const filterObs = value.map((c) => this.getTemplate(c, TemplateType.FILTERCELL));
76
- this.columnTemplates$ = combineLatest(obs).pipe(map((values) => Object.fromEntries(value.map((c, i) => [c.id, values[i]]))), debounceTime(50));
77
- this.columnFilterTemplates$ = combineLatest(filterObs).pipe(map((values) => Object.fromEntries(value.map((c, i) => [c.id, values[i]]))));
78
- }
79
- get pageSizes() {
80
- return this._pageSizes$.getValue();
81
- }
82
- set pageSizes(value) {
83
- this._pageSizes$.next(value);
84
- }
85
- get pageSize() {
86
- return this._pageSize$.getValue();
87
- }
88
- set pageSize(value) {
89
- this._pageSize$.next(value);
90
- }
91
- set showAllOption(value) {
92
- this._showAllOption$.next(value);
93
- }
94
- get totalRecordsOnServer() {
95
- return this.params['totalRecordsOnServer'] ? Number(this.params['totalRecordsOnServer']) : undefined;
96
- }
97
- set totalRecordsOnServer(value) {
98
- this.params['totalRecordsOnServer'] = value?.toString() ?? '0';
99
- }
100
- get _stringCell() {
101
- return this.stringCellTemplate || this.stringCellChildTemplate;
102
- }
103
- get _numberCell() {
104
- return this.numberCellTemplate || this.numberCellChildTemplate;
105
- }
106
- get _customCell() {
107
- return this.customCellTemplate || this.customCellChildTemplate;
108
- }
109
- get _dateCell() {
110
- return this.dateCellTemplate || this.dateCellChildTemplate;
111
- }
112
- get _relativeDateCell() {
113
- return this.relativeDateCellTemplate || this.relativeDateCellChildTemplate;
114
- }
115
- get _cell() {
116
- return this.cellTemplate || this.cellChildTemplate;
117
- }
118
- get _translationKeyCell() {
119
- return this.translationKeyCellTemplate || this.translationKeyCellChildTemplate;
120
- }
121
- get _stringFilterCell() {
122
- return this.stringFilterCellTemplate || this.stringFilterCellChildTemplate;
123
- }
124
- get _numberFilterCell() {
125
- return this.numberFilterCellTemplate || this.numberFilterCellChildTemplate;
126
- }
127
- get _customFilterCell() {
128
- return this.customFilterCellTemplate || this.customFilterCellChildTemplate;
129
- }
130
- get _dateFilterCell() {
131
- return this.dateFilterCellTemplate || this.dateFilterCellChildTemplate;
132
- }
133
- get _relativeDateFilterCell() {
134
- return this.relativeDateFilterCellTemplate || this.relativeDateFilterCellChildTemplate;
135
- }
136
- get _filterCell() {
137
- return this.filterCellTemplate || this.filterCellChildTemplate;
138
- }
139
- get _translationKeyFilterCell() {
140
- return this.translationKeyFilterCellTemplate || this.translationKeyFilterCellChildTemplate;
141
- }
142
- get additionalActions() {
143
- return this._additionalActions$.getValue();
144
- }
145
- set additionalActions(value) {
146
- this._additionalActions$.next(value);
147
- }
148
- set templates(value) {
149
- this.templates$.next(value);
150
- }
151
- set viewTemplates(value) {
152
- this.viewTemplates$.next(value);
153
- }
154
- set parentTemplates(value) {
155
- this.parentTemplates$.next(value);
156
- }
157
- get viewTableRowObserved() {
158
- const dv = this.injector.get('DataViewComponent', null);
159
- return dv?.viewItemObserved || dv?.viewItem.observed || this.viewTableRow.observed;
160
- }
161
- get editTableRowObserved() {
162
- const dv = this.injector.get('DataViewComponent', null);
163
- return dv?.editItemObserved || dv?.editItem.observed || this.editTableRow.observed;
164
- }
165
- get deleteTableRowObserved() {
166
- const dv = this.injector.get('DataViewComponent', null);
167
- return dv?.deleteItemObserved || dv?.deleteItem.observed || this.deleteTableRow.observed;
168
- }
169
- get anyRowActionObserved() {
170
- return this.viewTableRowObserved || this.editTableRowObserved || this.deleteTableRowObserved;
171
- }
172
- get selectionChangedObserved() {
173
- const dv = this.injector.get('DataViewComponent', null);
174
- return dv?.selectionChangedObserved || dv?.selectionChanged.observed || this.selectionChanged.observed;
175
- }
176
- constructor(locale, translateService, router, injector, userService) {
177
- super(locale, translateService);
178
- this.router = router;
179
- this.injector = injector;
180
- this.userService = userService;
181
- this.FilterType = FilterType;
182
- this.TemplateType = TemplateType;
183
- this.checked = true;
184
- this._rows$ = new BehaviorSubject([]);
185
- this._selectionIds$ = new BehaviorSubject([]);
186
- this._filters$ = new BehaviorSubject([]);
187
- this._sortDirection$ = new BehaviorSubject("NONE" /* DataSortDirection.NONE */);
188
- this._sortColumn$ = new BehaviorSubject('');
189
- this._columns$ = new BehaviorSubject([]);
190
- this.clientSideFiltering = true;
191
- this.clientSideSorting = true;
192
- this.sortStates = ["ASCENDING" /* DataSortDirection.ASCENDING */, "DESCENDING" /* DataSortDirection.DESCENDING */];
193
- this._pageSizes$ = new BehaviorSubject([10, 25, 50]);
194
- this._pageSize$ = new BehaviorSubject(undefined);
195
- this._showAllOption$ = new BehaviorSubject(false);
196
- this.name = '';
197
- this.allowSelectAll = true;
198
- this.paginator = true;
199
- this.page = 0;
200
- this.currentPageShowingKey = 'OCX_DATA_TABLE.SHOWING';
201
- this.currentPageShowingWithTotalOnServerKey = 'OCX_DATA_TABLE.SHOWING_WITH_TOTAL_ON_SERVER';
202
- this.params = {
203
- currentPage: '{currentPage}',
204
- totalPages: '{totalPages}',
205
- rows: '{rows}',
206
- first: '{first}',
207
- last: '{last}',
208
- totalRecords: '{totalRecords}',
209
- };
210
- this._additionalActions$ = new BehaviorSubject([]);
211
- this.frozenActionColumn = false;
212
- this.actionColumnPosition = 'right';
213
- this.filtered = new EventEmitter();
214
- this.sorted = new EventEmitter();
215
- this.viewTableRow = new EventEmitter();
216
- this.editTableRow = new EventEmitter();
217
- this.deleteTableRow = new EventEmitter();
218
- this.selectionChanged = new EventEmitter();
219
- this.pageChanged = new EventEmitter();
220
- this.pageSizeChanged = new EventEmitter();
221
- this.componentStateChanged = new EventEmitter();
222
- this.currentFilterColumn$ = new BehaviorSubject(null);
223
- this.truthyFilterOptions = [
224
- {
225
- key: 'OCX_DATA_TABLE.FILTER_YES',
226
- value: true,
227
- },
228
- {
229
- key: 'OCX_DATA_TABLE.FILTER_NO',
230
- value: false,
231
- },
232
- ];
233
- this.currentMenuRow$ = new BehaviorSubject(null);
234
- this.templates$ = new BehaviorSubject(undefined);
235
- this.viewTemplates$ = new BehaviorSubject(undefined);
236
- this.parentTemplates$ = new BehaviorSubject(undefined);
237
- this.templatesObservables = {};
238
- this.cellTemplatesData = {
239
- templatesObservables: {},
240
- idSuffix: ['IdTableCell', 'IdCell'],
241
- templateNames: {
242
- [ColumnType.DATE]: ['dateCell', 'dateTableCell', 'defaultDateCell'],
243
- [ColumnType.NUMBER]: ['numberCell', 'numberTableCell', 'defaultNumberCell'],
244
- [ColumnType.RELATIVE_DATE]: ['relativeDateCell', 'relativeDateTableCell', 'defaultRelativeDateCell'],
245
- [ColumnType.TRANSLATION_KEY]: ['translationKeyCell', 'translationKeyTableCell', 'defaultTranslationKeyCell'],
246
- [ColumnType.CUSTOM]: ['customCell', 'customTableCell', 'defaultCustomCell'],
247
- [ColumnType.STRING]: ['stringCell', 'stringTableCell', 'defaultStringCell'],
248
- },
249
- };
250
- this.filterTemplatesData = {
251
- templatesObservables: {},
252
- idSuffix: ['IdTableFilterCell', 'IdFilterCell', 'IdTableCell', 'IdCell'],
253
- templateNames: {
254
- [ColumnType.DATE]: ['dateFilterCell', 'dateTableFilterCell', 'dateCell', 'dateTableCell', 'defaultDateCell'],
255
- [ColumnType.NUMBER]: [
256
- 'numberFilterCell',
257
- 'numberTableFilterCell',
258
- 'numberCell',
259
- 'numberTableCell',
260
- 'defaultNumberCell',
261
- ],
262
- [ColumnType.RELATIVE_DATE]: [
263
- 'relativeDateFilterCell',
264
- 'relativeDateTableFilterCell',
265
- 'relativeDateCell',
266
- 'relativeDateTableCell',
267
- 'defaultRelativeDateCell',
268
- ],
269
- [ColumnType.TRANSLATION_KEY]: [
270
- 'translationKeyFilterCell',
271
- 'translationKeyTableFilterCell',
272
- 'defaultTranslationKeyCell',
273
- 'translationKeyCell',
274
- 'translationKeyTableCell',
275
- ],
276
- [ColumnType.CUSTOM]: [
277
- 'customFilterCell',
278
- 'customTableFilterCell',
279
- 'customCell',
280
- 'customTableCell',
281
- 'defaultCustomCell',
282
- ],
283
- [ColumnType.STRING]: [
284
- 'stringFilterCell',
285
- 'stringTableFilterCell',
286
- 'stringCell',
287
- 'stringTableCell',
288
- 'defaultStringCell',
289
- ],
290
- },
291
- };
292
- this.templatesDataMap = {
293
- [TemplateType.CELL]: this.cellTemplatesData,
294
- [TemplateType.FILTERCELL]: this.filterTemplatesData,
295
- };
296
- this.name = this.name || this.router.url.replace(/[^A-Za-z0-9]/, '_');
297
- this.displayedPageSizes$ = combineLatest([
298
- this._pageSizes$,
299
- this.translateService.get('OCX_DATA_TABLE.ALL'),
300
- this._showAllOption$,
301
- ]).pipe(map(([pageSizes, translation, showAllOption]) => showAllOption ? pageSizes.concat({ showAll: translation }) : pageSizes));
302
- this.displayedPageSize$ = combineLatest([this._pageSize$, this._pageSizes$]).pipe(map(([pageSize, pageSizes]) => pageSize ?? pageSizes.find((val) => typeof val === 'number') ?? 50));
303
- this.overflowActions$ = this._additionalActions$.pipe(map((actions) => actions.filter((action) => action.showAsOverflow)));
304
- this.inlineActions$ = this._additionalActions$.pipe(map((actions) => actions.filter((action) => !action.showAsOverflow)));
305
- this.overflowMenuItems$ = combineLatest([this.overflowActions$, this.currentMenuRow$]).pipe(mergeMap(([actions, row]) => this.translateService.get([...actions.map((a) => a.labelKey || '')]).pipe(map((translations) => {
306
- return actions
307
- .filter((a) => this.userService.hasPermission(a.permission))
308
- .map((a) => ({
309
- label: translations[a.labelKey || ''],
310
- icon: a.icon,
311
- styleClass: (a.classes || []).join(' '),
312
- disabled: a.disabled || (!!a.actionEnabledField && !this.fieldIsTruthy(row, a.actionEnabledField)),
313
- visible: !a.actionVisibleField || this.fieldIsTruthy(row, a.actionVisibleField),
314
- command: () => a.callback(row),
315
- }));
316
- }))));
317
- this.rowSelectable = this.rowSelectable.bind(this);
318
- }
319
- ngOnInit() {
320
- this.displayedRows$ = combineLatest([this._rows$, this._filters$, this._sortColumn$, this._sortDirection$]).pipe(mergeMap((params) => this.translateItems(params, this.columns, this.clientSideFiltering, this.clientSideSorting)), map((params) => this.filterItems(params, this.clientSideFiltering)), map((params) => this.sortItems(params, this.columns, this.clientSideSorting)), map(([rows]) => this.flattenItems(rows)));
321
- this.currentTruthySelectedFilters$ = combineLatest([this._filters$, this.currentFilterColumn$]).pipe(map(([filters, currentFilterColumn]) => {
322
- return filters
323
- .filter((filter) => filter.columnId === currentFilterColumn?.id && currentFilterColumn.filterType === FilterType.TRUTHY)
324
- .map((filter) => filter.value);
325
- }));
326
- this.currentEqualSelectedFilters$ = combineLatest([this._filters$, this.currentFilterColumn$]).pipe(map(([filters, currentFilterColumn]) => {
327
- return filters
328
- .filter((filter) => filter.columnId === currentFilterColumn?.id &&
329
- (!currentFilterColumn.filterType || currentFilterColumn.filterType === FilterType.EQUAL))
330
- .map((filter) => filter.value);
331
- }));
332
- this.currentEqualFilterOptions$ = combineLatest([this._rows$, this.currentFilterColumn$, this._filters$]).pipe(filter(([_, currentFilterColumn, __]) => !currentFilterColumn?.filterType || currentFilterColumn.filterType === FilterType.EQUAL), mergeMap(([rows, currentFilterColumn, filters]) => {
333
- if (!currentFilterColumn?.id) {
334
- return of({ options: [], column: undefined });
335
- }
336
- const currentFilters = filters
337
- .filter((filter) => filter.columnId === currentFilterColumn?.id &&
338
- (!currentFilterColumn.filterType || currentFilterColumn.filterType === FilterType.EQUAL))
339
- .map((filter) => filter.value);
340
- const columnValues = rows.map((row) => row[currentFilterColumn?.id]);
341
- const translateObservable = this.columns.find((c) => c.id === currentFilterColumn?.id)?.columnType === ColumnType.TRANSLATION_KEY
342
- ? this.translateColumnValues(columnValues)
343
- : of(Object.fromEntries(columnValues.map((cv) => [cv, cv])));
344
- return translateObservable.pipe(map((translatedValues) => {
345
- return Object.values(translatedValues)
346
- .concat(currentFilters)
347
- .filter((value, index, self) => self.indexOf(value) === index && value != null)
348
- .map((filterOption) => ({
349
- label: filterOption,
350
- value: filterOption,
351
- }));
352
- }), map((options) => {
353
- return {
354
- options: options,
355
- column: currentFilterColumn,
356
- };
357
- }));
358
- }));
359
- this.filterAmounts$ = this._filters$.pipe(map((filters) => filters
360
- .map((filter) => filter.columnId)
361
- .map((columnId) => [columnId, filters.filter((filter) => filter.columnId === columnId).length])), map((amounts) => Object.fromEntries(amounts)));
362
- this.mapSelectionToRows();
363
- this.emitComponentStateChanged();
364
- }
365
- translateColumnValues(columnValues) {
366
- return columnValues.length ? this.translateService.get(columnValues) : of({});
367
- }
368
- emitComponentStateChanged(state = {}) {
369
- this.displayedPageSize$
370
- .pipe(withLatestFrom(this._selectionIds$, this._rows$), first())
371
- .subscribe(([pageSize, selectedIds, rows]) => {
372
- this.componentStateChanged.emit({
373
- filters: this.filters,
374
- sorting: {
375
- sortColumn: this.sortColumn,
376
- sortDirection: this.sortDirection,
377
- },
378
- pageSize,
379
- activePage: this.page,
380
- selectedRows: rows.filter((row) => selectedIds.includes(row.id)),
381
- ...state,
382
- });
383
- });
384
- }
385
- ngAfterContentInit() {
386
- this.templates$.value?.forEach((item) => {
387
- switch (item.getType()) {
388
- case 'stringCell':
389
- this.stringCellChildTemplate = item.template;
390
- break;
391
- case 'numberCell':
392
- this.numberCellChildTemplate = item.template;
393
- break;
394
- case 'customCell':
395
- this.customCellChildTemplate = item.template;
396
- break;
397
- case 'dateCell':
398
- this.dateCellChildTemplate = item.template;
399
- break;
400
- case 'relativeDateCell':
401
- this.relativeDateCellChildTemplate = item.template;
402
- break;
403
- case 'cellTemplate':
404
- this.cellChildTemplate = item.template;
405
- break;
406
- case 'translationKeyCell':
407
- this.translationKeyCellChildTemplate = item.template;
408
- break;
409
- case 'stringFilterCell':
410
- this.stringFilterCellChildTemplate = item.template;
411
- break;
412
- case 'numberFilterCell':
413
- this.numberFilterCellChildTemplate = item.template;
414
- break;
415
- case 'customFilterCell':
416
- this.customFilterCellChildTemplate = item.template;
417
- break;
418
- case 'dateFilterCell':
419
- this.dateFilterCellChildTemplate = item.template;
420
- break;
421
- case 'relativeDateFilterCell':
422
- this.relativeDateFilterCellChildTemplate = item.template;
423
- break;
424
- case 'filterCellTemplate':
425
- this.filterCellChildTemplate = item.template;
426
- break;
427
- case 'translationKeyFilterCell':
428
- this.translationKeyFilterCellChildTemplate = item.template;
429
- break;
430
- }
431
- });
432
- }
433
- onSortColumnClick(sortColumn) {
434
- const newSortDirection = this.columnNextSortDirection(sortColumn);
435
- this._sortColumn$.next(sortColumn);
436
- this._sortDirection$.next(newSortDirection);
437
- this.sorted.emit({ sortColumn: sortColumn, sortDirection: newSortDirection });
438
- this.emitComponentStateChanged({
439
- sorting: {
440
- sortColumn: sortColumn,
441
- sortDirection: newSortDirection,
442
- },
443
- });
444
- }
445
- columnNextSortDirection(sortColumn) {
446
- return sortColumn !== this.sortColumn
447
- ? this.sortStates[0]
448
- : this.sortStates[(this.sortStates.indexOf(this.sortDirection) + 1) % this.sortStates.length];
449
- }
450
- onDeleteRow(selectedTableRow) {
451
- this.deleteTableRow.emit(selectedTableRow);
452
- }
453
- onViewRow(selectedTableRow) {
454
- this.viewTableRow.emit(selectedTableRow);
455
- }
456
- onEditRow(selectedTableRow) {
457
- this.editTableRow.emit(selectedTableRow);
458
- }
459
- onFilterChosen(column) {
460
- this.currentFilterColumn$.next(column);
461
- }
462
- onMultiselectFilterChange(column, event) {
463
- const filters = this.filters
464
- .filter((filter) => filter.columnId !== column.id)
465
- .concat(event.value.map((value) => ({
466
- columnId: column.id,
467
- value,
468
- filterType: column.filterType,
469
- })));
470
- if (this.clientSideFiltering) {
471
- this.filters = filters;
472
- }
473
- this.filtered.emit(filters);
474
- this.emitComponentStateChanged({
475
- filters,
476
- });
477
- this.resetPage();
478
- }
479
- getSelectedFilters(columnId) {
480
- return this.filters.filter((filter) => filter.columnId === columnId).map((filter) => filter.value);
481
- }
482
- sortIconTitle(sortColumn) {
483
- return this.sortDirectionToTitle(sortColumn !== this.sortDirection
484
- ? "NONE" /* DataSortDirection.NONE */
485
- : this.sortStates[this.sortStates.indexOf(this.sortDirection) % this.sortStates.length]);
486
- }
487
- sortDirectionToTitle(sortDirection) {
488
- switch (sortDirection) {
489
- case "ASCENDING" /* DataSortDirection.ASCENDING */:
490
- return 'OCX_DATA_TABLE.TOGGLE_BUTTON.ASCENDING_TITLE';
491
- case "DESCENDING" /* DataSortDirection.DESCENDING */:
492
- return 'OCX_DATA_TABLE.TOGGLE_BUTTON.DESCENDING_TITLE';
493
- default:
494
- return 'OCX_DATA_TABLE.TOGGLE_BUTTON.DEFAULT_TITLE';
495
- }
496
- }
497
- mapSelectionToRows() {
498
- this.selectedRows$ = combineLatest([this._selectionIds$, this._rows$]).pipe(map(([selectedRowIds, rows]) => {
499
- return selectedRowIds.map((rowId) => {
500
- return rows.find((r) => r.id === rowId);
501
- });
502
- }));
503
- }
504
- isRowSelectionDisabled(rowObject) {
505
- return !!this.selectionEnabledField && !this.fieldIsTruthy(rowObject, this.selectionEnabledField);
506
- }
507
- rowSelectable(event) {
508
- return !this.isRowSelectionDisabled(event.data);
509
- }
510
- onSelectionChange(selection) {
511
- let newSelectionIds = selection.map((row) => row.id);
512
- const rows = this._rows$.getValue();
513
- if (this.selectionEnabledField) {
514
- const disabledRowIds = rows.filter((r) => !this.fieldIsTruthy(r, this.selectionEnabledField)).map((row) => row.id);
515
- if (disabledRowIds.length > 0) {
516
- newSelectionIds = this.mergeWithDisabledKeys(newSelectionIds, disabledRowIds);
517
- }
518
- }
519
- this._selectionIds$.next(newSelectionIds);
520
- this.selectionChanged.emit(this._rows$.getValue().filter((row) => newSelectionIds.includes(row.id)));
521
- this.emitComponentStateChanged();
522
- }
523
- mergeWithDisabledKeys(newSelectionIds, disabledRowIds) {
524
- const previousSelectionIds = this._selectionIds$.getValue();
525
- const previouslySelectedAndDisabled = previousSelectionIds.filter((id) => disabledRowIds.includes(id));
526
- const disabledAndPreviouslyDeselected = disabledRowIds.filter((id) => !previousSelectionIds.includes(id));
527
- const updatedSelection = [...newSelectionIds];
528
- previouslySelectedAndDisabled.forEach((id) => {
529
- if (!updatedSelection.includes(id)) {
530
- updatedSelection.push(id);
531
- }
532
- });
533
- disabledAndPreviouslyDeselected.forEach((id) => {
534
- const index = updatedSelection.indexOf(id);
535
- if (index > -1) {
536
- updatedSelection.splice(index, 1);
537
- }
538
- });
539
- return updatedSelection;
540
- }
541
- isSelected(row) {
542
- return this._selectionIds$.getValue().includes(row.id);
543
- }
544
- onPageChange(event) {
545
- const page = event.first / event.rows;
546
- this.page = page;
547
- this.pageSize = event.rows;
548
- this.pageChanged.emit(page);
549
- this.pageSizeChanged.emit(event.rows);
550
- this.emitComponentStateChanged({
551
- activePage: page,
552
- pageSize: event.rows,
553
- });
554
- }
555
- resetPage() {
556
- this.page = 0;
557
- this.pageChanged.emit(this.page);
558
- this.emitComponentStateChanged();
559
- }
560
- fieldIsTruthy(object, key) {
561
- return !!ObjectUtils.resolveFieldData(object, key);
562
- }
563
- toggleOverflowMenu(event, menu, row) {
564
- this.currentMenuRow$.next(row);
565
- menu.toggle(event);
566
- }
567
- hasVisibleOverflowMenuItems(row) {
568
- return this.overflowActions$.pipe(map((actions) => actions.some((a) => !a.actionVisibleField ||
569
- (this.fieldIsTruthy(row, a.actionVisibleField) && this.userService.hasPermission(a.permission)))));
570
- }
571
- isDate(value) {
572
- if (value instanceof Date) {
573
- return true;
574
- }
575
- const d = new Date(value);
576
- return isValidDate(d);
577
- }
578
- getColumnTypeTemplate(templates, columnType, templateType) {
579
- let template;
580
- switch (templateType) {
581
- case TemplateType.CELL:
582
- switch (columnType) {
583
- case ColumnType.DATE:
584
- template = this._dateCell;
585
- break;
586
- case ColumnType.NUMBER:
587
- template = this._numberCell;
588
- break;
589
- case ColumnType.RELATIVE_DATE:
590
- template = this._relativeDateCell;
591
- break;
592
- case ColumnType.TRANSLATION_KEY:
593
- template = this._translationKeyCell;
594
- break;
595
- case ColumnType.CUSTOM:
596
- template = this._customCell;
597
- break;
598
- default:
599
- template = this._stringCell;
600
- }
601
- break;
602
- case TemplateType.FILTERCELL:
603
- switch (columnType) {
604
- case ColumnType.DATE:
605
- template = this._dateFilterCell;
606
- break;
607
- case ColumnType.NUMBER:
608
- template = this._numberFilterCell;
609
- break;
610
- case ColumnType.RELATIVE_DATE:
611
- template = this._relativeDateFilterCell;
612
- break;
613
- case ColumnType.TRANSLATION_KEY:
614
- template = this._translationKeyFilterCell;
615
- break;
616
- case ColumnType.CUSTOM:
617
- template = this._customFilterCell;
618
- break;
619
- default:
620
- template = this._stringFilterCell;
621
- }
622
- break;
623
- }
624
- return (template ??
625
- findTemplate(templates, this.templatesDataMap[templateType].templateNames[columnType])?.template ??
626
- null);
627
- }
628
- getTemplate(column, templateType) {
629
- const templatesData = this.templatesDataMap[templateType];
630
- if (!templatesData.templatesObservables[column.id]) {
631
- templatesData.templatesObservables[column.id] = combineLatest([
632
- this.templates$,
633
- this.viewTemplates$,
634
- this.parentTemplates$,
635
- ]).pipe(map(([t, vt, pt]) => {
636
- const templates = [...(t ?? []), ...(vt ?? []), ...(pt ?? [])];
637
- const columnTemplate = findTemplate(templates, templatesData.idSuffix.map((suffix) => column.id + suffix))?.template;
638
- if (columnTemplate) {
639
- return columnTemplate;
640
- }
641
- return this.getColumnTypeTemplate(templates, column.columnType, templateType);
642
- }));
643
- }
644
- return templatesData.templatesObservables[column.id];
645
- }
646
- resolveFieldData(object, key) {
647
- return ObjectUtils.resolveFieldData(object, key);
648
- }
649
- getRowObjectFromMultiselectItem(value, column) {
650
- return {
651
- [column.id]: value.label,
652
- };
653
- }
654
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: DataTableComponent, deps: [{ token: LOCALE_ID }, { token: i1.TranslateService }, { token: i2.Router }, { token: i0.Injector }, { token: i3.UserService }], target: i0.ɵɵFactoryTarget.Component }); }
655
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.12", type: DataTableComponent, selector: "ocx-data-table", inputs: { rows: "rows", selectedRows: "selectedRows", filters: "filters", sortDirection: "sortDirection", sortColumn: "sortColumn", columns: "columns", clientSideFiltering: "clientSideFiltering", clientSideSorting: "clientSideSorting", sortStates: "sortStates", pageSizes: "pageSizes", pageSize: "pageSize", showAllOption: "showAllOption", emptyResultsMessage: "emptyResultsMessage", name: "name", deletePermission: "deletePermission", viewPermission: "viewPermission", editPermission: "editPermission", deleteActionVisibleField: "deleteActionVisibleField", deleteActionEnabledField: "deleteActionEnabledField", viewActionVisibleField: "viewActionVisibleField", viewActionEnabledField: "viewActionEnabledField", editActionVisibleField: "editActionVisibleField", editActionEnabledField: "editActionEnabledField", selectionEnabledField: "selectionEnabledField", allowSelectAll: "allowSelectAll", paginator: "paginator", page: "page", tableStyle: "tableStyle", totalRecordsOnServer: "totalRecordsOnServer", currentPageShowingKey: "currentPageShowingKey", currentPageShowingWithTotalOnServerKey: "currentPageShowingWithTotalOnServerKey", stringCellTemplate: "stringCellTemplate", numberCellTemplate: "numberCellTemplate", customCellTemplate: "customCellTemplate", dateCellTemplate: "dateCellTemplate", relativeDateCellTemplate: "relativeDateCellTemplate", cellTemplate: "cellTemplate", translationKeyCellTemplate: "translationKeyCellTemplate", stringFilterCellTemplate: "stringFilterCellTemplate", numberFilterCellTemplate: "numberFilterCellTemplate", customFilterCellTemplate: "customFilterCellTemplate", dateFilterCellTemplate: "dateFilterCellTemplate", relativeDateFilterCellTemplate: "relativeDateFilterCellTemplate", filterCellTemplate: "filterCellTemplate", translationKeyFilterCellTemplate: "translationKeyFilterCellTemplate", additionalActions: "additionalActions", frozenActionColumn: "frozenActionColumn", actionColumnPosition: "actionColumnPosition", parentTemplates: "parentTemplates" }, outputs: { filtered: "filtered", sorted: "sorted", viewTableRow: "viewTableRow", editTableRow: "editTableRow", deleteTableRow: "deleteTableRow", selectionChanged: "selectionChanged", pageChanged: "pageChanged", pageSizeChanged: "pageSizeChanged", componentStateChanged: "componentStateChanged" }, queries: [{ propertyName: "stringCellChildTemplate", first: true, predicate: ["stringCell"], descendants: true }, { propertyName: "numberCellChildTemplate", first: true, predicate: ["numberCell"], descendants: true }, { propertyName: "customCellChildTemplate", first: true, predicate: ["customCell"], descendants: true }, { propertyName: "dateCellChildTemplate", first: true, predicate: ["dateCell"], descendants: true }, { propertyName: "relativeDateCellChildTemplate", first: true, predicate: ["relativeDateCell"], descendants: true }, { propertyName: "cellChildTemplate", first: true, predicate: ["cell"], descendants: true }, { propertyName: "translationKeyCellChildTemplate", first: true, predicate: ["translationKeyCell"], descendants: true }, { propertyName: "stringFilterCellChildTemplate", first: true, predicate: ["stringFilterCell"], descendants: true }, { propertyName: "numberFilterCellChildTemplate", first: true, predicate: ["numberFilterCell"], descendants: true }, { propertyName: "customFilterCellChildTemplate", first: true, predicate: ["customFilterCell"], descendants: true }, { propertyName: "dateFilterCellChildTemplate", first: true, predicate: ["dateFilterCell"], descendants: true }, { propertyName: "relativeDateFilterCellChildTemplate", first: true, predicate: ["relativeDateFilterCell"], descendants: true }, { propertyName: "filterCellChildTemplate", first: true, predicate: ["filterCell"], descendants: true }, { propertyName: "translationKeyFilterCellChildTemplate", first: true, predicate: ["translationKeyFilterCell"], descendants: true }, { propertyName: "templates", predicate: PrimeTemplate }], viewQueries: [{ propertyName: "viewTemplates", predicate: PrimeTemplate, descendants: true }], usesInheritance: true, ngImport: i0, template: "<ng-template #actionColumn let-rowObject=\"localRowObject\">\n <ng-container\n *ngIf=\"anyRowActionObserved || this.additionalActions.length > 0 || ((this.overflowActions$ | async) ?? []).length > 0\"\n >\n <td\n class=\"actions\"\n pFrozenColumn\n [frozen]=\"frozenActionColumn\"\n [alignFrozen]=\"actionColumnPosition\"\n [attr.name]=\"actionColumnPosition === 'left' ? 'action-column-left' : 'action-column-right'\"\n [ngClass]=\"(frozenActionColumn && actionColumnPosition === 'left') ? 'border-right-1' : (frozenActionColumn && actionColumnPosition === 'right') ? 'border-left-1' : ''\"\n >\n <div class=\"icon-button-row-wrapper\">\n <ng-container\n *ngIf=\"viewTableRowObserved && (!viewActionVisibleField || fieldIsTruthy(rowObject, viewActionVisibleField))\"\n >\n <button\n id=\"{{resolveFieldData(rowObject, 'id')}}-viewButton\"\n *ocxIfPermission=\"viewPermission\"\n [disabled]=\"!!viewActionEnabledField && !fieldIsTruthy(rowObject, viewActionEnabledField)\"\n pButton\n class=\"p-button-rounded p-button-text viewTableRowButton\"\n title=\"{{ 'OCX_DATA_TABLE.ACTIONS.VIEW' | translate }}\"\n [attr.aria-label]=\"'OCX_DATA_TABLE.ACTIONS.VIEW' | translate\"\n icon=\"pi pi-eye\"\n (click)=\"onViewRow(rowObject)\"\n [attr.name]=\"'data-table-action-button'\"\n ></button>\n </ng-container>\n <ng-container\n *ngIf=\"editTableRowObserved && (!editActionVisibleField || fieldIsTruthy(rowObject, editActionVisibleField))\"\n >\n <button\n id=\"{{resolveFieldData(rowObject, 'id')}}-editButton\"\n *ocxIfPermission=\"editPermission\"\n [disabled]=\"!!editActionEnabledField && !fieldIsTruthy(rowObject, editActionEnabledField)\"\n pButton\n class=\"p-button-rounded p-button-text editTableRowButton\"\n title=\"{{ 'OCX_DATA_TABLE.ACTIONS.EDIT' | translate }}\"\n [attr.aria-label]=\"'OCX_DATA_TABLE.ACTIONS.EDIT' | translate\"\n icon=\"pi pi-pencil\"\n (click)=\"onEditRow(rowObject)\"\n [attr.name]=\"'data-table-action-button'\"\n ></button>\n </ng-container>\n <ng-container\n *ngIf=\"deleteTableRowObserved && (!deleteActionVisibleField || fieldIsTruthy(rowObject, deleteActionVisibleField))\"\n >\n <button\n id=\"{{resolveFieldData(rowObject, 'id')}}-deleteButton\"\n *ocxIfPermission=\"deletePermission\"\n [disabled]=\"!!deleteActionEnabledField && !fieldIsTruthy(rowObject, deleteActionEnabledField)\"\n pButton\n class=\"p-button-rounded p-button-text p-button-danger deleteTableRowButton\"\n title=\"{{ 'OCX_DATA_TABLE.ACTIONS.DELETE' | translate }}\"\n [attr.aria-label]=\"'OCX_DATA_TABLE.ACTIONS.DELETE' | translate\"\n icon=\"pi pi-trash\"\n (click)=\"onDeleteRow(rowObject)\"\n [attr.name]=\"'data-table-action-button'\"\n ></button>\n </ng-container>\n <ng-container *ngFor=\"let action of inlineActions$ | async\">\n <ng-container *ngIf=\"(!action.actionVisibleField || fieldIsTruthy(rowObject, action.actionVisibleField))\">\n <button\n id=\"{{resolveFieldData(rowObject, 'id')}}-{{action.id ? action.id.concat('ActionButton') : 'inlineActionButton'}}\"\n *ocxIfPermission=\"action.permission\"\n pButton\n class=\"p-button-rounded p-button-text\"\n [ngClass]=\"action.classes\"\n [icon]=\"action.icon || ''\"\n (click)=\"action.callback(rowObject)\"\n [title]=\"action.labelKey ? (action.labelKey | translate) : ''\"\n [attr.aria-label]=\"action.labelKey ? (action.labelKey | translate) : ''\"\n [disabled]=\"action.disabled || (!!action.actionEnabledField && !fieldIsTruthy(rowObject, action.actionEnabledField))\"\n [attr.name]=\"'data-table-action-button'\"\n ></button>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"hasVisibleOverflowMenuItems(rowObject) | async\">\n <p-menu #menu [model]=\"(overflowMenuItems$ | async) || []\" [popup]=\"true\" appendTo=\"body\"></p-menu>\n <button\n pButton\n class=\"p-button-rounded p-button-text\"\n [icon]=\"'pi pi-ellipsis-v'\"\n (click)=\"toggleOverflowMenu($event, menu, rowObject)\"\n [attr.aria-label]=\"'OCX_DATA_TABLE.MORE_ACTIONS' | translate\"\n [title]=\"'OCX_DATA_TABLE.MORE_ACTIONS' | translate\"\n ></button>\n </ng-container>\n </div>\n </td>\n </ng-container>\n</ng-template>\n\n<ng-template #actionColumnHeader>\n <ng-container\n *ngIf=\"anyRowActionObserved || this.additionalActions.length > 0 || ((this.overflowActions$ | async) ?? []).length > 0\"\n >\n <th\n pFrozenColumn\n [frozen]=\"frozenActionColumn\"\n [alignFrozen]=\"actionColumnPosition\"\n [ngClass]=\"(frozenActionColumn && actionColumnPosition === 'left') ? 'border-right-1' : (frozenActionColumn && actionColumnPosition === 'right') ? 'border-left-1' : ''\"\n [attr.name]=\"actionColumnPosition === 'left' ? 'action-column-header-left' : 'action-column-header-right'\"\n >\n {{ 'OCX_DATA_TABLE.ACTIONS_COLUMN_NAME' | translate }}\n </th>\n </ng-container>\n</ng-template>\n\n<ng-container *ngIf=\"(displayedPageSize$ | async) as displayedPageSize\">\n <p-table\n *ngIf=\"(columnTemplates$ | async) ?? {} as columnTemplates\"\n [value]=\"(displayedRows$ | async) ?? []\"\n responsiveLayout=\"scroll\"\n [paginator]=\"paginator\"\n [first]=\"page * displayedPageSize\"\n (onPage)=\"onPageChange($event)\"\n [rows]=\"displayedPageSize\"\n [showCurrentPageReport]=\"true\"\n currentPageReportTemplate=\"{{ (totalRecordsOnServer ? currentPageShowingWithTotalOnServerKey : currentPageShowingKey) | translate:params }}\"\n [rowsPerPageOptions]=\"(displayedPageSizes$ | async) ?? []\"\n id=\"dataTable_{{name}}\"\n (selectionChange)=\"onSelectionChange($event)\"\n [selection]=\"(selectedRows$ | async) ?? []\"\n [scrollable]=\"true\"\n scrollHeight=\"flex\"\n [style]=\"tableStyle\"\n paginatorDropdownAppendTo=\"body\"\n [rowSelectable]=\"rowSelectable\"\n tableStyleClass=\"h-full\"\n >\n <ng-template pTemplate=\"header\">\n <tr style=\"vertical-align: top\">\n <th style=\"width: 4rem\" scope=\"col\" *ngIf=\"selectionChangedObserved\">\n <p-tableHeaderCheckbox\n *ngIf=\"allowSelectAll\"\n pTooltip=\"{{'OCX_DATA_TABLE.SELECT_ALL_TOOLTIP' | translate}}\"\n ariaLabel=\"{{'OCX_DATA_TABLE.SELECT_ALL_ARIA_LABEL' | translate}}\"\n ></p-tableHeaderCheckbox>\n </th>\n <ng-container *ngIf=\"actionColumnPosition === 'left';\">\n <ng-container *ngTemplateOutlet=\"actionColumnHeader\"></ng-container>\n </ng-container>\n <ng-container *ngFor=\"let column of columns\">\n <th *ngIf=\"column.sortable || column.filterable; else simpleHeader\" scope=\"col\">\n <div\n class=\"table-header-wrapper flex flex-column justify-content-between align-items-start\"\n style=\"height: 100%\"\n >\n <span class=\"flex\" id=\"{{column.id}}-header-name\">{{ column.nameKey | translate }}</span>\n <span class=\"flex icon-button-header-wrapper\">\n <button\n *ngIf=\"column.sortable\"\n class=\"pi sortButton pl-0\"\n [class.pi-sort-alt]=\"(column?.id === sortColumn && sortDirection === 'NONE') || column?.id !== sortColumn\"\n [class.pi-sort-amount-up]=\"column?.id === sortColumn && sortDirection === 'ASCENDING'\"\n [class.pi-sort-amount-down]=\"column?.id === sortColumn && sortDirection === 'DESCENDING'\"\n (click)=\"onSortColumnClick(column.id)\"\n [title]=\"(sortIconTitle(column.id) | translate)\"\n [attr.aria-label]=\"('OCX_DATA_TABLE.TOGGLE_BUTTON.ARIA_LABEL' | translate: { column: (column.nameKey | translate), direction: (sortDirectionToTitle(columnNextSortDirection(column.id)) | translate)})\"\n ></button>\n <ng-container *ngIf=\"currentEqualFilterOptions$ | async as equalFilterOptions\">\n <ng-container *ngIf=\"columnFilterTemplates$ | async as columnFilterTemplates\">\n <p-multiSelect\n class=\"filterMultiSelect\"\n *ngIf=\"column.filterable && (!column.filterType || column.filterType === FilterType.EQUAL)\"\n [options]=\"equalFilterOptions.column?.id === column.id ? equalFilterOptions.options : []\"\n [ngModel]=\"(currentEqualSelectedFilters$ | async) || []\"\n [showToggleAll]=\"true\"\n emptyFilterMessage=\"{{ 'OCX_DATA_TABLE.EMPTY_FILTER_MESSAGE' | translate }}\"\n [displaySelectedLabel]=\"false\"\n [resetFilterOnHide]=\"true\"\n (onChange)=\"onMultiselectFilterChange(column, $event)\"\n placeholder=\"Icon\"\n appendTo=\"body\"\n (onFocus)=\"onFilterChosen(column)\"\n [title]=\"'OCX_DATA_TABLE.FILTER_TITLE' | translate\"\n [ariaLabel]=\"'OCX_DATA_TABLE.COLUMN_FILTER_ARIA_LABEL' | translate\"\n [ariaFilterLabel]=\"('OCX_DATA_TABLE.FILTER_ARIA_LABEL' | translate: { column: column.nameKey | translate})\"\n >\n <ng-template pTemplate=\"selectedItems\" let-value>\n <div\n class=\"pi\"\n [class.pi-filter]=\"!((filterAmounts$ | async) || {})[column.id]\"\n [class.pi-filter-fill]=\"((filterAmounts$ | async) || {})[column.id] > 0\"\n ></div>\n </ng-template>\n <ng-template pTemplate=\"item\" let-value>\n <ng-container\n *ngIf=\"columnFilterTemplates[column.id] as template\"\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{\n rowObject: getRowObjectFromMultiselectItem(value, column),\n column: column\n }\"\n >\n </ng-container>\n </ng-template>\n </p-multiSelect>\n </ng-container>\n </ng-container>\n <p-multiSelect\n class=\"filterMultiSelect\"\n *ngIf=\"column.filterable && column.filterType === FilterType.TRUTHY\"\n [options]=\"truthyFilterOptions\"\n [ngModel]=\"(currentTruthySelectedFilters$ | async) || []\"\n [showToggleAll]=\"true\"\n emptyFilterMessage=\"{{ 'OCX_DATA_TABLE.EMPTY_FILTER_MESSAGE' | translate }}\"\n [displaySelectedLabel]=\"false\"\n [resetFilterOnHide]=\"true\"\n (onChange)=\"onMultiselectFilterChange(column, $event)\"\n placeholder=\"Icon\"\n appendTo=\"body\"\n (onFocus)=\"onFilterChosen(column)\"\n [title]=\"'OCX_DATA_TABLE.FILTER_TITLE' | translate\"\n [ariaLabel]=\"'OCX_DATA_TABLE.COLUMN_FILTER_ARIA_LABEL' | translate\"\n [ariaFilterLabel]=\"('OCX_DATA_TABLE.FILTER_ARIA_LABEL' | translate: { column: column.nameKey | translate})\"\n >\n <ng-template pTemplate=\"selectedItems\" let-value>\n <div\n class=\"pi\"\n [class.pi-filter]=\"!((filterAmounts$ | async) || {})[column.id]\"\n [class.pi-filter-fill]=\"((filterAmounts$ | async) || {})[column.id] > 0\"\n ></div>\n </ng-template>\n <ng-template pTemplate=\"item\" let-value> {{value.key | translate}} </ng-template>\n </p-multiSelect>\n </span>\n </div>\n </th>\n <ng-template #simpleHeader>\n <th scope=\"col\">{{ column.nameKey | translate }}</th>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"actionColumnPosition === 'right';\">\n <ng-container *ngTemplateOutlet=\"actionColumnHeader\"></ng-container>\n </ng-container>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-rowObject>\n <tr *ngIf=\"columnTemplates\">\n <td *ngIf=\"selectionChangedObserved\">\n <p-checkbox\n *ngIf=\"isRowSelectionDisabled(rowObject) && isSelected(rowObject); else defaultCheckbox\"\n [(ngModel)]=\"checked\"\n [binary]=\"true\"\n [disabled]=\"true\"\n [ariaLabel]=\"'OCX_DATA_TABLE.SELECT_ARIA_LABEL' | translate: { key: rowObject.id}\"\n ></p-checkbox>\n <ng-template #defaultCheckbox>\n <p-tableCheckbox\n [value]=\"rowObject\"\n [disabled]=\"isRowSelectionDisabled(rowObject)\"\n [ariaLabel]=\"'OCX_DATA_TABLE.SELECT_ARIA_LABEL' | translate: { key: rowObject.id}\"\n ></p-tableCheckbox>\n </ng-template>\n </td>\n <ng-container *ngIf=\"actionColumnPosition === 'left';\">\n <ng-container *ngTemplateOutlet=\"actionColumn; context: {localRowObject: rowObject}\"></ng-container>\n </ng-container>\n <td *ngFor=\"let column of columns\">\n @defer(on viewport){\n <ng-container\n *ngIf=\"columnTemplates[column.id]\"\n [ngTemplateOutlet]=\"\n _cell ? _cell: columnTemplates[column.id]\n \"\n [ngTemplateOutletContext]=\"{\n rowObject: rowObject,\n column: column,\n }\"\n >\n </ng-container>\n } @placeholder {\n <p-skeleton width=\"3rem\" />\n }\n </td>\n <ng-container *ngIf=\"actionColumnPosition === 'right';\">\n <ng-container *ngTemplateOutlet=\"actionColumn; context: {localRowObject: rowObject}\"></ng-container>\n </ng-container>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"emptymessage\">\n <tr>\n <td [colSpan]=\"columns.length + ((anyRowActionObserved || this.additionalActions.length > 0) ? 1 : 0)\">\n {{ emptyResultsMessage || (\"OCX_DATA_TABLE.EMPTY_RESULT\" | translate) }}\n </td>\n </tr>\n </ng-template>\n </p-table>\n</ng-container>\n\n<ng-template pTemplate=\"defaultStringCell\" let-rowObject=\"rowObject\" let-column=\"column\">\n <ng-container> {{ resolveFieldData(rowObject, column.id)}} </ng-container>\n</ng-template>\n\n<ng-template pTemplate=\"defaultNumberCell\" let-rowObject=\"rowObject\" let-column=\"column\">\n <ng-container> {{ resolveFieldData(rowObject, column.id) | number }} </ng-container>\n</ng-template>\n\n<ng-template pTemplate=\"defaultCustomCell\" let-rowObject=\"rowObject\" let-column=\"column\"> </ng-template>\n\n<ng-template pTemplate=\"defaultDateCell\" let-rowObject=\"rowObject\" let-column=\"column\">\n <ng-container> {{ resolveFieldData(rowObject, column.id) | date: column.dateFormat ?? 'medium' }} </ng-container>\n</ng-template>\n\n<ng-template pTemplate=\"defaultRelativeDateCell\" let-rowObject=\"rowObject\" let-column=\"column\">\n <ng-container>\n {{ 'OCX_DATA_TABLE.EDITED' | translate }} {{ resolveFieldData(rowObject, column.id) | timeago }}\n </ng-container>\n</ng-template>\n\n<ng-template pTemplate=\"defaultTranslationKeyCell\" let-rowObject=\"rowObject\" let-column=\"column\">\n <ng-container> {{ resolveFieldData(rowObject, column.id) | translate }} </ng-container>\n</ng-template>\n", styles: [":host ::ng-deep .p-multiselect{padding:0;background:#f7f7f7;border:none}:host ::ng-deep .p-multiselect .p-multiselect-container{height:20px;width:20px}:host ::ng-deep .p-multiselect .p-multiselect-trigger{display:none}:host ::ng-deep .p-multiselect .p-multiselect-label.p-placeholder{color:#262626;font-size:.9rem;font-family:Bold,sans-serif;font-weight:700;padding:0}:host ::ng-deep .p-multiselect:focus-within{box-shadow:none;background:#979797}.pi{border:none;background:none;cursor:pointer}\n"], dependencies: [{ kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "directive", type: i6.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: i7.Checkbox, selector: "p-checkbox", inputs: ["value", "name", "disabled", "binary", "label", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "styleClass", "labelStyleClass", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "directive", type: i8.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "component", type: i9.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "style", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "scrollDirection", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "responsive", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "autoLayout", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll", "virtualRowHeight"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i9.FrozenColumn, selector: "[pFrozenColumn]", inputs: ["frozen", "alignFrozen"] }, { kind: "component", type: i9.TableCheckbox, selector: "p-tableCheckbox", inputs: ["disabled", "value", "index", "inputId", "name", "required", "ariaLabel"] }, { kind: "component", type: i9.TableHeaderCheckbox, selector: "p-tableHeaderCheckbox", inputs: ["disabled", "inputId", "name", "ariaLabel"] }, { kind: "component", type: i10.Menu, selector: "p-menu", inputs: ["model", "popup", "style", "styleClass", "appendTo", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "ariaLabel", "ariaLabelledBy", "id", "tabindex"], outputs: ["onShow", "onHide", "onBlur", "onFocus"] }, { kind: "component", type: i11.MultiSelect, selector: "p-multiSelect", inputs: ["id", "ariaLabel", "style", "styleClass", "panelStyle", "panelStyleClass", "inputId", "disabled", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "variant", "appendTo", "dataKey", "name", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "autofocus", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "defaultLabel", "placeholder", "options", "filterValue", "itemSize", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "component", type: i12.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "style", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "directive", type: i13.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i13.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i14.IfPermissionDirective, selector: "[ocxIfPermission], [ocxIfNotPermission]", inputs: ["ocxIfPermission", "ocxIfNotPermission", "onMissingPermission", "ocxIfPermissionPermissions", "ocxIfNotPermissionPermissions", "ocxIfPermissionElseTemplate", "ocxIfNotPermissionElseTemplate"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i4.DecimalPipe, name: "number" }, { kind: "pipe", type: i4.DatePipe, name: "date" }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }, { kind: "pipe", type: i15.OcxTimeAgoPipe, name: "timeago" }], deferBlockDependencies: [() => [i4.NgIf, i4.NgTemplateOutlet]] }); }
656
- }
657
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: DataTableComponent, decorators: [{
658
- type: Component,
659
- args: [{ selector: 'ocx-data-table', template: "<ng-template #actionColumn let-rowObject=\"localRowObject\">\n <ng-container\n *ngIf=\"anyRowActionObserved || this.additionalActions.length > 0 || ((this.overflowActions$ | async) ?? []).length > 0\"\n >\n <td\n class=\"actions\"\n pFrozenColumn\n [frozen]=\"frozenActionColumn\"\n [alignFrozen]=\"actionColumnPosition\"\n [attr.name]=\"actionColumnPosition === 'left' ? 'action-column-left' : 'action-column-right'\"\n [ngClass]=\"(frozenActionColumn && actionColumnPosition === 'left') ? 'border-right-1' : (frozenActionColumn && actionColumnPosition === 'right') ? 'border-left-1' : ''\"\n >\n <div class=\"icon-button-row-wrapper\">\n <ng-container\n *ngIf=\"viewTableRowObserved && (!viewActionVisibleField || fieldIsTruthy(rowObject, viewActionVisibleField))\"\n >\n <button\n id=\"{{resolveFieldData(rowObject, 'id')}}-viewButton\"\n *ocxIfPermission=\"viewPermission\"\n [disabled]=\"!!viewActionEnabledField && !fieldIsTruthy(rowObject, viewActionEnabledField)\"\n pButton\n class=\"p-button-rounded p-button-text viewTableRowButton\"\n title=\"{{ 'OCX_DATA_TABLE.ACTIONS.VIEW' | translate }}\"\n [attr.aria-label]=\"'OCX_DATA_TABLE.ACTIONS.VIEW' | translate\"\n icon=\"pi pi-eye\"\n (click)=\"onViewRow(rowObject)\"\n [attr.name]=\"'data-table-action-button'\"\n ></button>\n </ng-container>\n <ng-container\n *ngIf=\"editTableRowObserved && (!editActionVisibleField || fieldIsTruthy(rowObject, editActionVisibleField))\"\n >\n <button\n id=\"{{resolveFieldData(rowObject, 'id')}}-editButton\"\n *ocxIfPermission=\"editPermission\"\n [disabled]=\"!!editActionEnabledField && !fieldIsTruthy(rowObject, editActionEnabledField)\"\n pButton\n class=\"p-button-rounded p-button-text editTableRowButton\"\n title=\"{{ 'OCX_DATA_TABLE.ACTIONS.EDIT' | translate }}\"\n [attr.aria-label]=\"'OCX_DATA_TABLE.ACTIONS.EDIT' | translate\"\n icon=\"pi pi-pencil\"\n (click)=\"onEditRow(rowObject)\"\n [attr.name]=\"'data-table-action-button'\"\n ></button>\n </ng-container>\n <ng-container\n *ngIf=\"deleteTableRowObserved && (!deleteActionVisibleField || fieldIsTruthy(rowObject, deleteActionVisibleField))\"\n >\n <button\n id=\"{{resolveFieldData(rowObject, 'id')}}-deleteButton\"\n *ocxIfPermission=\"deletePermission\"\n [disabled]=\"!!deleteActionEnabledField && !fieldIsTruthy(rowObject, deleteActionEnabledField)\"\n pButton\n class=\"p-button-rounded p-button-text p-button-danger deleteTableRowButton\"\n title=\"{{ 'OCX_DATA_TABLE.ACTIONS.DELETE' | translate }}\"\n [attr.aria-label]=\"'OCX_DATA_TABLE.ACTIONS.DELETE' | translate\"\n icon=\"pi pi-trash\"\n (click)=\"onDeleteRow(rowObject)\"\n [attr.name]=\"'data-table-action-button'\"\n ></button>\n </ng-container>\n <ng-container *ngFor=\"let action of inlineActions$ | async\">\n <ng-container *ngIf=\"(!action.actionVisibleField || fieldIsTruthy(rowObject, action.actionVisibleField))\">\n <button\n id=\"{{resolveFieldData(rowObject, 'id')}}-{{action.id ? action.id.concat('ActionButton') : 'inlineActionButton'}}\"\n *ocxIfPermission=\"action.permission\"\n pButton\n class=\"p-button-rounded p-button-text\"\n [ngClass]=\"action.classes\"\n [icon]=\"action.icon || ''\"\n (click)=\"action.callback(rowObject)\"\n [title]=\"action.labelKey ? (action.labelKey | translate) : ''\"\n [attr.aria-label]=\"action.labelKey ? (action.labelKey | translate) : ''\"\n [disabled]=\"action.disabled || (!!action.actionEnabledField && !fieldIsTruthy(rowObject, action.actionEnabledField))\"\n [attr.name]=\"'data-table-action-button'\"\n ></button>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"hasVisibleOverflowMenuItems(rowObject) | async\">\n <p-menu #menu [model]=\"(overflowMenuItems$ | async) || []\" [popup]=\"true\" appendTo=\"body\"></p-menu>\n <button\n pButton\n class=\"p-button-rounded p-button-text\"\n [icon]=\"'pi pi-ellipsis-v'\"\n (click)=\"toggleOverflowMenu($event, menu, rowObject)\"\n [attr.aria-label]=\"'OCX_DATA_TABLE.MORE_ACTIONS' | translate\"\n [title]=\"'OCX_DATA_TABLE.MORE_ACTIONS' | translate\"\n ></button>\n </ng-container>\n </div>\n </td>\n </ng-container>\n</ng-template>\n\n<ng-template #actionColumnHeader>\n <ng-container\n *ngIf=\"anyRowActionObserved || this.additionalActions.length > 0 || ((this.overflowActions$ | async) ?? []).length > 0\"\n >\n <th\n pFrozenColumn\n [frozen]=\"frozenActionColumn\"\n [alignFrozen]=\"actionColumnPosition\"\n [ngClass]=\"(frozenActionColumn && actionColumnPosition === 'left') ? 'border-right-1' : (frozenActionColumn && actionColumnPosition === 'right') ? 'border-left-1' : ''\"\n [attr.name]=\"actionColumnPosition === 'left' ? 'action-column-header-left' : 'action-column-header-right'\"\n >\n {{ 'OCX_DATA_TABLE.ACTIONS_COLUMN_NAME' | translate }}\n </th>\n </ng-container>\n</ng-template>\n\n<ng-container *ngIf=\"(displayedPageSize$ | async) as displayedPageSize\">\n <p-table\n *ngIf=\"(columnTemplates$ | async) ?? {} as columnTemplates\"\n [value]=\"(displayedRows$ | async) ?? []\"\n responsiveLayout=\"scroll\"\n [paginator]=\"paginator\"\n [first]=\"page * displayedPageSize\"\n (onPage)=\"onPageChange($event)\"\n [rows]=\"displayedPageSize\"\n [showCurrentPageReport]=\"true\"\n currentPageReportTemplate=\"{{ (totalRecordsOnServer ? currentPageShowingWithTotalOnServerKey : currentPageShowingKey) | translate:params }}\"\n [rowsPerPageOptions]=\"(displayedPageSizes$ | async) ?? []\"\n id=\"dataTable_{{name}}\"\n (selectionChange)=\"onSelectionChange($event)\"\n [selection]=\"(selectedRows$ | async) ?? []\"\n [scrollable]=\"true\"\n scrollHeight=\"flex\"\n [style]=\"tableStyle\"\n paginatorDropdownAppendTo=\"body\"\n [rowSelectable]=\"rowSelectable\"\n tableStyleClass=\"h-full\"\n >\n <ng-template pTemplate=\"header\">\n <tr style=\"vertical-align: top\">\n <th style=\"width: 4rem\" scope=\"col\" *ngIf=\"selectionChangedObserved\">\n <p-tableHeaderCheckbox\n *ngIf=\"allowSelectAll\"\n pTooltip=\"{{'OCX_DATA_TABLE.SELECT_ALL_TOOLTIP' | translate}}\"\n ariaLabel=\"{{'OCX_DATA_TABLE.SELECT_ALL_ARIA_LABEL' | translate}}\"\n ></p-tableHeaderCheckbox>\n </th>\n <ng-container *ngIf=\"actionColumnPosition === 'left';\">\n <ng-container *ngTemplateOutlet=\"actionColumnHeader\"></ng-container>\n </ng-container>\n <ng-container *ngFor=\"let column of columns\">\n <th *ngIf=\"column.sortable || column.filterable; else simpleHeader\" scope=\"col\">\n <div\n class=\"table-header-wrapper flex flex-column justify-content-between align-items-start\"\n style=\"height: 100%\"\n >\n <span class=\"flex\" id=\"{{column.id}}-header-name\">{{ column.nameKey | translate }}</span>\n <span class=\"flex icon-button-header-wrapper\">\n <button\n *ngIf=\"column.sortable\"\n class=\"pi sortButton pl-0\"\n [class.pi-sort-alt]=\"(column?.id === sortColumn && sortDirection === 'NONE') || column?.id !== sortColumn\"\n [class.pi-sort-amount-up]=\"column?.id === sortColumn && sortDirection === 'ASCENDING'\"\n [class.pi-sort-amount-down]=\"column?.id === sortColumn && sortDirection === 'DESCENDING'\"\n (click)=\"onSortColumnClick(column.id)\"\n [title]=\"(sortIconTitle(column.id) | translate)\"\n [attr.aria-label]=\"('OCX_DATA_TABLE.TOGGLE_BUTTON.ARIA_LABEL' | translate: { column: (column.nameKey | translate), direction: (sortDirectionToTitle(columnNextSortDirection(column.id)) | translate)})\"\n ></button>\n <ng-container *ngIf=\"currentEqualFilterOptions$ | async as equalFilterOptions\">\n <ng-container *ngIf=\"columnFilterTemplates$ | async as columnFilterTemplates\">\n <p-multiSelect\n class=\"filterMultiSelect\"\n *ngIf=\"column.filterable && (!column.filterType || column.filterType === FilterType.EQUAL)\"\n [options]=\"equalFilterOptions.column?.id === column.id ? equalFilterOptions.options : []\"\n [ngModel]=\"(currentEqualSelectedFilters$ | async) || []\"\n [showToggleAll]=\"true\"\n emptyFilterMessage=\"{{ 'OCX_DATA_TABLE.EMPTY_FILTER_MESSAGE' | translate }}\"\n [displaySelectedLabel]=\"false\"\n [resetFilterOnHide]=\"true\"\n (onChange)=\"onMultiselectFilterChange(column, $event)\"\n placeholder=\"Icon\"\n appendTo=\"body\"\n (onFocus)=\"onFilterChosen(column)\"\n [title]=\"'OCX_DATA_TABLE.FILTER_TITLE' | translate\"\n [ariaLabel]=\"'OCX_DATA_TABLE.COLUMN_FILTER_ARIA_LABEL' | translate\"\n [ariaFilterLabel]=\"('OCX_DATA_TABLE.FILTER_ARIA_LABEL' | translate: { column: column.nameKey | translate})\"\n >\n <ng-template pTemplate=\"selectedItems\" let-value>\n <div\n class=\"pi\"\n [class.pi-filter]=\"!((filterAmounts$ | async) || {})[column.id]\"\n [class.pi-filter-fill]=\"((filterAmounts$ | async) || {})[column.id] > 0\"\n ></div>\n </ng-template>\n <ng-template pTemplate=\"item\" let-value>\n <ng-container\n *ngIf=\"columnFilterTemplates[column.id] as template\"\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{\n rowObject: getRowObjectFromMultiselectItem(value, column),\n column: column\n }\"\n >\n </ng-container>\n </ng-template>\n </p-multiSelect>\n </ng-container>\n </ng-container>\n <p-multiSelect\n class=\"filterMultiSelect\"\n *ngIf=\"column.filterable && column.filterType === FilterType.TRUTHY\"\n [options]=\"truthyFilterOptions\"\n [ngModel]=\"(currentTruthySelectedFilters$ | async) || []\"\n [showToggleAll]=\"true\"\n emptyFilterMessage=\"{{ 'OCX_DATA_TABLE.EMPTY_FILTER_MESSAGE' | translate }}\"\n [displaySelectedLabel]=\"false\"\n [resetFilterOnHide]=\"true\"\n (onChange)=\"onMultiselectFilterChange(column, $event)\"\n placeholder=\"Icon\"\n appendTo=\"body\"\n (onFocus)=\"onFilterChosen(column)\"\n [title]=\"'OCX_DATA_TABLE.FILTER_TITLE' | translate\"\n [ariaLabel]=\"'OCX_DATA_TABLE.COLUMN_FILTER_ARIA_LABEL' | translate\"\n [ariaFilterLabel]=\"('OCX_DATA_TABLE.FILTER_ARIA_LABEL' | translate: { column: column.nameKey | translate})\"\n >\n <ng-template pTemplate=\"selectedItems\" let-value>\n <div\n class=\"pi\"\n [class.pi-filter]=\"!((filterAmounts$ | async) || {})[column.id]\"\n [class.pi-filter-fill]=\"((filterAmounts$ | async) || {})[column.id] > 0\"\n ></div>\n </ng-template>\n <ng-template pTemplate=\"item\" let-value> {{value.key | translate}} </ng-template>\n </p-multiSelect>\n </span>\n </div>\n </th>\n <ng-template #simpleHeader>\n <th scope=\"col\">{{ column.nameKey | translate }}</th>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"actionColumnPosition === 'right';\">\n <ng-container *ngTemplateOutlet=\"actionColumnHeader\"></ng-container>\n </ng-container>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-rowObject>\n <tr *ngIf=\"columnTemplates\">\n <td *ngIf=\"selectionChangedObserved\">\n <p-checkbox\n *ngIf=\"isRowSelectionDisabled(rowObject) && isSelected(rowObject); else defaultCheckbox\"\n [(ngModel)]=\"checked\"\n [binary]=\"true\"\n [disabled]=\"true\"\n [ariaLabel]=\"'OCX_DATA_TABLE.SELECT_ARIA_LABEL' | translate: { key: rowObject.id}\"\n ></p-checkbox>\n <ng-template #defaultCheckbox>\n <p-tableCheckbox\n [value]=\"rowObject\"\n [disabled]=\"isRowSelectionDisabled(rowObject)\"\n [ariaLabel]=\"'OCX_DATA_TABLE.SELECT_ARIA_LABEL' | translate: { key: rowObject.id}\"\n ></p-tableCheckbox>\n </ng-template>\n </td>\n <ng-container *ngIf=\"actionColumnPosition === 'left';\">\n <ng-container *ngTemplateOutlet=\"actionColumn; context: {localRowObject: rowObject}\"></ng-container>\n </ng-container>\n <td *ngFor=\"let column of columns\">\n @defer(on viewport){\n <ng-container\n *ngIf=\"columnTemplates[column.id]\"\n [ngTemplateOutlet]=\"\n _cell ? _cell: columnTemplates[column.id]\n \"\n [ngTemplateOutletContext]=\"{\n rowObject: rowObject,\n column: column,\n }\"\n >\n </ng-container>\n } @placeholder {\n <p-skeleton width=\"3rem\" />\n }\n </td>\n <ng-container *ngIf=\"actionColumnPosition === 'right';\">\n <ng-container *ngTemplateOutlet=\"actionColumn; context: {localRowObject: rowObject}\"></ng-container>\n </ng-container>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"emptymessage\">\n <tr>\n <td [colSpan]=\"columns.length + ((anyRowActionObserved || this.additionalActions.length > 0) ? 1 : 0)\">\n {{ emptyResultsMessage || (\"OCX_DATA_TABLE.EMPTY_RESULT\" | translate) }}\n </td>\n </tr>\n </ng-template>\n </p-table>\n</ng-container>\n\n<ng-template pTemplate=\"defaultStringCell\" let-rowObject=\"rowObject\" let-column=\"column\">\n <ng-container> {{ resolveFieldData(rowObject, column.id)}} </ng-container>\n</ng-template>\n\n<ng-template pTemplate=\"defaultNumberCell\" let-rowObject=\"rowObject\" let-column=\"column\">\n <ng-container> {{ resolveFieldData(rowObject, column.id) | number }} </ng-container>\n</ng-template>\n\n<ng-template pTemplate=\"defaultCustomCell\" let-rowObject=\"rowObject\" let-column=\"column\"> </ng-template>\n\n<ng-template pTemplate=\"defaultDateCell\" let-rowObject=\"rowObject\" let-column=\"column\">\n <ng-container> {{ resolveFieldData(rowObject, column.id) | date: column.dateFormat ?? 'medium' }} </ng-container>\n</ng-template>\n\n<ng-template pTemplate=\"defaultRelativeDateCell\" let-rowObject=\"rowObject\" let-column=\"column\">\n <ng-container>\n {{ 'OCX_DATA_TABLE.EDITED' | translate }} {{ resolveFieldData(rowObject, column.id) | timeago }}\n </ng-container>\n</ng-template>\n\n<ng-template pTemplate=\"defaultTranslationKeyCell\" let-rowObject=\"rowObject\" let-column=\"column\">\n <ng-container> {{ resolveFieldData(rowObject, column.id) | translate }} </ng-container>\n</ng-template>\n", styles: [":host ::ng-deep .p-multiselect{padding:0;background:#f7f7f7;border:none}:host ::ng-deep .p-multiselect .p-multiselect-container{height:20px;width:20px}:host ::ng-deep .p-multiselect .p-multiselect-trigger{display:none}:host ::ng-deep .p-multiselect .p-multiselect-label.p-placeholder{color:#262626;font-size:.9rem;font-family:Bold,sans-serif;font-weight:700;padding:0}:host ::ng-deep .p-multiselect:focus-within{box-shadow:none;background:#979797}.pi{border:none;background:none;cursor:pointer}\n"] }]
660
- }], ctorParameters: () => [{ type: undefined, decorators: [{
661
- type: Inject,
662
- args: [LOCALE_ID]
663
- }] }, { type: i1.TranslateService }, { type: i2.Router }, { type: i0.Injector }, { type: i3.UserService }], propDecorators: { rows: [{
664
- type: Input
665
- }], selectedRows: [{
666
- type: Input
667
- }], filters: [{
668
- type: Input
669
- }], sortDirection: [{
670
- type: Input
671
- }], sortColumn: [{
672
- type: Input
673
- }], columns: [{
674
- type: Input
675
- }], clientSideFiltering: [{
676
- type: Input
677
- }], clientSideSorting: [{
678
- type: Input
679
- }], sortStates: [{
680
- type: Input
681
- }], pageSizes: [{
682
- type: Input
683
- }], pageSize: [{
684
- type: Input
685
- }], showAllOption: [{
686
- type: Input
687
- }], emptyResultsMessage: [{
688
- type: Input
689
- }], name: [{
690
- type: Input
691
- }], deletePermission: [{
692
- type: Input
693
- }], viewPermission: [{
694
- type: Input
695
- }], editPermission: [{
696
- type: Input
697
- }], deleteActionVisibleField: [{
698
- type: Input
699
- }], deleteActionEnabledField: [{
700
- type: Input
701
- }], viewActionVisibleField: [{
702
- type: Input
703
- }], viewActionEnabledField: [{
704
- type: Input
705
- }], editActionVisibleField: [{
706
- type: Input
707
- }], editActionEnabledField: [{
708
- type: Input
709
- }], selectionEnabledField: [{
710
- type: Input
711
- }], allowSelectAll: [{
712
- type: Input
713
- }], paginator: [{
714
- type: Input
715
- }], page: [{
716
- type: Input
717
- }], tableStyle: [{
718
- type: Input
719
- }], totalRecordsOnServer: [{
720
- type: Input
721
- }], currentPageShowingKey: [{
722
- type: Input
723
- }], currentPageShowingWithTotalOnServerKey: [{
724
- type: Input
725
- }], stringCellTemplate: [{
726
- type: Input
727
- }], stringCellChildTemplate: [{
728
- type: ContentChild,
729
- args: ['stringCell']
730
- }], numberCellTemplate: [{
731
- type: Input
732
- }], numberCellChildTemplate: [{
733
- type: ContentChild,
734
- args: ['numberCell']
735
- }], customCellTemplate: [{
736
- type: Input
737
- }], customCellChildTemplate: [{
738
- type: ContentChild,
739
- args: ['customCell']
740
- }], dateCellTemplate: [{
741
- type: Input
742
- }], dateCellChildTemplate: [{
743
- type: ContentChild,
744
- args: ['dateCell']
745
- }], relativeDateCellTemplate: [{
746
- type: Input
747
- }], relativeDateCellChildTemplate: [{
748
- type: ContentChild,
749
- args: ['relativeDateCell']
750
- }], cellTemplate: [{
751
- type: Input
752
- }], cellChildTemplate: [{
753
- type: ContentChild,
754
- args: ['cell']
755
- }], translationKeyCellTemplate: [{
756
- type: Input
757
- }], translationKeyCellChildTemplate: [{
758
- type: ContentChild,
759
- args: ['translationKeyCell']
760
- }], stringFilterCellTemplate: [{
761
- type: Input
762
- }], stringFilterCellChildTemplate: [{
763
- type: ContentChild,
764
- args: ['stringFilterCell']
765
- }], numberFilterCellTemplate: [{
766
- type: Input
767
- }], numberFilterCellChildTemplate: [{
768
- type: ContentChild,
769
- args: ['numberFilterCell']
770
- }], customFilterCellTemplate: [{
771
- type: Input
772
- }], customFilterCellChildTemplate: [{
773
- type: ContentChild,
774
- args: ['customFilterCell']
775
- }], dateFilterCellTemplate: [{
776
- type: Input
777
- }], dateFilterCellChildTemplate: [{
778
- type: ContentChild,
779
- args: ['dateFilterCell']
780
- }], relativeDateFilterCellTemplate: [{
781
- type: Input
782
- }], relativeDateFilterCellChildTemplate: [{
783
- type: ContentChild,
784
- args: ['relativeDateFilterCell']
785
- }], filterCellTemplate: [{
786
- type: Input
787
- }], filterCellChildTemplate: [{
788
- type: ContentChild,
789
- args: ['filterCell']
790
- }], translationKeyFilterCellTemplate: [{
791
- type: Input
792
- }], translationKeyFilterCellChildTemplate: [{
793
- type: ContentChild,
794
- args: ['translationKeyFilterCell']
795
- }], additionalActions: [{
796
- type: Input
797
- }], frozenActionColumn: [{
798
- type: Input
799
- }], actionColumnPosition: [{
800
- type: Input
801
- }], filtered: [{
802
- type: Output
803
- }], sorted: [{
804
- type: Output
805
- }], viewTableRow: [{
806
- type: Output
807
- }], editTableRow: [{
808
- type: Output
809
- }], deleteTableRow: [{
810
- type: Output
811
- }], selectionChanged: [{
812
- type: Output
813
- }], pageChanged: [{
814
- type: Output
815
- }], pageSizeChanged: [{
816
- type: Output
817
- }], componentStateChanged: [{
818
- type: Output
819
- }], templates: [{
820
- type: ContentChildren,
821
- args: [PrimeTemplate]
822
- }], viewTemplates: [{
823
- type: ViewChildren,
824
- args: [PrimeTemplate]
825
- }], parentTemplates: [{
826
- type: Input
827
- }] } });
828
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS10YWJsZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL2FuZ3VsYXItYWNjZWxlcmF0b3Ivc3JjL2xpYi9jb21wb25lbnRzL2RhdGEtdGFibGUvZGF0YS10YWJsZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL2FuZ3VsYXItYWNjZWxlcmF0b3Ivc3JjL2xpYi9jb21wb25lbnRzL2RhdGEtdGFibGUvZGF0YS10YWJsZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUwsU0FBUyxFQUNULFlBQVksRUFDWixlQUFlLEVBQ2YsWUFBWSxFQUNaLE1BQU0sRUFDTixRQUFRLEVBQ1IsS0FBSyxFQUNMLFNBQVMsRUFFVCxNQUFNLEVBR04sWUFBWSxHQUNiLE1BQU0sZUFBZSxDQUFBO0FBQ3RCLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQTtBQUN4QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQTtBQUN0RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sb0JBQW9CLENBQUE7QUFDaEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHNDQUFzQyxDQUFBO0FBQ2xFLE9BQU8sRUFBWSxhQUFhLEVBQWMsTUFBTSxhQUFhLENBQUE7QUFFakUsT0FBTyxFQUNMLGVBQWUsRUFFZixhQUFhLEVBQ2IsWUFBWSxFQUNaLE1BQU0sRUFDTixLQUFLLEVBQ0wsR0FBRyxFQUNILFFBQVEsRUFDUixFQUFFLEVBQ0YsY0FBYyxHQUNmLE1BQU0sTUFBTSxDQUFBO0FBQ2IsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFBO0FBSTFELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQTtBQUNyRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0NBQWtDLENBQUE7QUFF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NkI7c0JBQTlELFlBQVk7dUJBQUMsa0JBQWtCO2dCQVN2Qix3QkFBd0I7c0JBQWhDLEtBQUs7Z0JBTTRCLDZCQUE2QjtzQkFBOUQsWUFBWTt1QkFBQyxrQkFBa0I7Z0JBSXZCLHNCQUFzQjtzQkFBOUIsS0FBSztnQkFDMEIsMkJBQTJCO3NCQUExRCxZQUFZO3VCQUFDLGdCQUFnQjtnQkFJckIsOEJBQThCO3NCQUF0QyxLQUFLO2dCQUNrQyxtQ0FBbUM7c0JBQTFFLFlBQVk7dUJBQUMsd0JBQXdCO2dCQUk3QixrQkFBa0I7c0JBQTFCLEtBQUs7Z0JBQ3NCLHVCQUF1QjtzQkFBbEQsWUFBWTt1QkFBQyxZQUFZO2dCQUlqQixnQ0FBZ0M7c0JBQXhDLEtBQUs7Z0JBQ29DLHFDQUFxQztzQkFBOUUsWUFBWTt1QkFBQywwQkFBMEI7Z0JBT3BDLGlCQUFpQjtzQkFEcEIsS0FBSztnQkFPRyxrQkFBa0I7c0JBQTFCLEtBQUs7Z0JBQ0csb0JBQW9CO3NCQUE1QixLQUFLO2dCQUVJLFFBQVE7c0JBQWpCLE1BQU07Z0JBQ0csTUFBTTtzQkFBZixNQUFNO2dCQUNHLFlBQVk7c0JBQXJCLE1BQU07Z0JBQ0csWUFBWTtzQkFBckIsTUFBTTtnQkFDRyxjQUFjO3NCQUF2QixNQUFNO2dCQUNHLGdCQUFnQjtzQkFBekIsTUFBTTtnQkFDRyxXQUFXO3NCQUFwQixNQUFNO2dCQUNHLGVBQWU7c0JBQXhCLE1BQU07Z0JBQ0cscUJBQXFCO3NCQUE5QixNQUFNO2dCQThCSCxTQUFTO3NCQURaLGVBQWU7dUJBQUMsYUFBYTtnQkFTMUIsYUFBYTtzQkFEaEIsWUFBWTt1QkFBQyxhQUFhO2dCQVN2QixlQUFlO3NCQURsQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQWZ0ZXJDb250ZW50SW5pdCxcbiAgQ29tcG9uZW50LFxuICBDb250ZW50Q2hpbGQsXG4gIENvbnRlbnRDaGlsZHJlbixcbiAgRXZlbnRFbWl0dGVyLFxuICBJbmplY3QsXG4gIEluamVjdG9yLFxuICBJbnB1dCxcbiAgTE9DQUxFX0lELFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgUXVlcnlMaXN0LFxuICBUZW1wbGF0ZVJlZixcbiAgVmlld0NoaWxkcmVuLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJ1xuaW1wb3J0IHsgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJ1xuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnXG5pbXBvcnQgeyBpc1ZhbGlkRGF0ZSB9IGZyb20gJ0BvbmVjeC9hY2NlbGVyYXRvcidcbmltcG9ydCB7IFVzZXJTZXJ2aWNlIH0gZnJvbSAnQG9uZWN4L2FuZ3VsYXItaW50ZWdyYXRpb24taW50ZXJmYWNlJ1xuaW1wb3J0IHsgTWVudUl0ZW0sIFByaW1lVGVtcGxhdGUsIFNlbGVjdEl0ZW0gfSBmcm9tICdwcmltZW5nL2FwaSdcbmltcG9ydCB7IE1lbnUgfSBmcm9tICdwcmltZW5nL21lbnUnXG5pbXBvcnQge1xuICBCZWhhdmlvclN1YmplY3QsXG4gIE9ic2VydmFibGUsXG4gIGNvbWJpbmVMYXRlc3QsXG4gIGRlYm91bmNlVGltZSxcbiAgZmlsdGVyLFxuICBmaXJzdCxcbiAgbWFwLFxuICBtZXJnZU1hcCxcbiAgb2YsXG4gIHdpdGhMYXRlc3RGcm9tLFxufSBmcm9tICdyeGpzJ1xuaW1wb3J0IHsgQ29sdW1uVHlwZSB9IGZyb20gJy4uLy4uL21vZGVsL2NvbHVtbi10eXBlLm1vZGVsJ1xuaW1wb3J0IHsgRGF0YUFjdGlvbiB9IGZyb20gJy4uLy4uL21vZGVsL2RhdGEtYWN0aW9uJ1xuaW1wb3J0IHsgRGF0YVNvcnREaXJlY3Rpb24gfSBmcm9tICcuLi8uLi9tb2RlbC9kYXRhLXNvcnQtZGlyZWN0aW9uJ1xuaW1wb3J0IHsgRGF0YVRhYmxlQ29sdW1uIH0gZnJvbSAnLi4vLi4vbW9kZWwvZGF0YS10YWJsZS1jb2x1bW4ubW9kZWwnXG5pbXBvcnQgeyBPYmplY3RVdGlscyB9IGZyb20gJy4uLy4uL3V0aWxzL29iamVjdHV0aWxzJ1xuaW1wb3J0IHsgRGF0YVNvcnRCYXNlIH0gZnJvbSAnLi4vZGF0YS1zb3J0LWJhc2UvZGF0YS1zb3J0LWJhc2UnXG5pbXBvcnQgeyBNdWx0aVNlbGVjdEl0ZW0gfSBmcm9tICdwcmltZW5nL211bHRpc2VsZWN0J1xuaW1wb3J0IHsgRmlsdGVyLCBGaWx0ZXJUeXBlIH0gZnJvbSAnLi4vLi4vbW9kZWwvZmlsdGVyLm1vZGVsJ1xuaW1wb3J0IHsgZmluZFRlbXBsYXRlIH0gZnJvbSAnLi4vLi4vdXRpbHMvdGVtcGxhdGUudXRpbHMnXG5cbmV4cG9ydCB0eXBlIFByaW1pdGl2ZSA9IG51bWJlciB8IHN0cmluZyB8IGJvb2xlYW4gfCBiaWdpbnQgfCBEYXRlXG5leHBvcnQgdHlwZSBSb3cgPSB7XG4gIGlkOiBzdHJpbmcgfCBudW1iZXJcbiAgW2NvbHVtbklkOiBzdHJpbmddOiB1bmtub3duXG59XG5cbmV4cG9ydCBlbnVtIFRlbXBsYXRlVHlwZSB7XG4gIENFTEwgPSAnQ0VMTCcsXG4gIEZJTFRFUkNFTEwgPSAnRklMVEVSQ0VMTCcsXG59XG5cbmludGVyZmFjZSBUZW1wbGF0ZXNEYXRhIHtcbiAgdGVtcGxhdGVzT2JzZXJ2YWJsZXM6IFJlY29yZDxzdHJpbmcsIE9ic2VydmFibGU8VGVtcGxhdGVSZWY8YW55PiB8IG51bGw+PlxuICBpZFN1ZmZpeDogQXJyYXk8c3RyaW5nPlxuICB0ZW1wbGF0ZU5hbWVzOiBSZWNvcmQ8Q29sdW1uVHlwZSwgQXJyYXk8c3RyaW5nPj5cbn1cblxuZXhwb3J0IHR5cGUgU29ydCA9IHsgc29ydENvbHVtbjogc3RyaW5nOyBzb3J0RGlyZWN0aW9uOiBEYXRhU29ydERpcmVjdGlvbiB9XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGF0YVRhYmxlQ29tcG9uZW50U3RhdGUge1xuICBmaWx0ZXJzPzogRmlsdGVyW11cbiAgc29ydGluZz86IFNvcnRcbiAgc2VsZWN0ZWRSb3dzPzogUm93W11cbiAgYWN0aXZlUGFnZT86IG51bWJlclxuICBwYWdlU2l6ZT86IG51bWJlclxufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdvY3gtZGF0YS10YWJsZScsXG4gIHRlbXBsYXRlVXJsOiAnLi9kYXRhLXRhYmxlLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vZGF0YS10YWJsZS5jb21wb25lbnQuc2NzcyddLFxufSlcbmV4cG9ydCBjbGFzcyBEYXRhVGFibGVDb21wb25lbnQgZXh0ZW5kcyBEYXRhU29ydEJhc2UgaW1wbGVtZW50cyBPbkluaXQsIEFmdGVyQ29udGVudEluaXQge1xuICBGaWx0ZXJUeXBlID0gRmlsdGVyVHlwZVxuICBUZW1wbGF0ZVR5cGUgPSBUZW1wbGF0ZVR5cGVcbiAgY2hlY2tlZCA9IHRydWVcbiAgX3Jvd3MkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxSb3dbXT4oW10pXG4gIEBJbnB1dCgpXG4gIGdldCByb3dzKCk6IFJvd1tdIHtcbiAgICByZXR1cm4gdGhpcy5fcm93cyQuZ2V0VmFsdWUoKVxuICB9XG4gIHNldCByb3dzKHZhbHVlOiBSb3dbXSkge1xuICAgICF0aGlzLl9yb3dzJC5nZXRWYWx1ZSgpLmxlbmd0aCA/PyB0aGlzLnJlc2V0UGFnZSgpXG4gICAgdGhpcy5fcm93cyQubmV4dCh2YWx1ZSlcbiAgfVxuICBfc2VsZWN0aW9uSWRzJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8KHN0cmluZyB8IG51bWJlcilbXT4oW10pXG4gIEBJbnB1dCgpXG4gIHNldCBzZWxlY3RlZFJvd3ModmFsdWU6IFJvd1tdIHwgc3RyaW5nW10gfCBudW1iZXJbXSkge1xuICAgIHRoaXMuX3NlbGVjdGlvbklkcyQubmV4dChcbiAgICAgIHZhbHVlLm1hcCgocm93KSA9PiB7XG4gICAgICAgIGlmICh0eXBlb2Ygcm93ID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgIHJldHVybiByb3cuaWRcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcm93XG4gICAgICB9KVxuICAgIClcbiAgfVxuXG4gIF9maWx0ZXJzJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8RmlsdGVyW10+KFtdKVxuICBASW5wdXQoKVxuICBnZXQgZmlsdGVycygpOiBGaWx0ZXJbXSB7XG4gICAgcmV0dXJuIHRoaXMuX2ZpbHRlcnMkLmdldFZhbHVlKClcbiAgfVxuICBzZXQgZmlsdGVycyh2YWx1ZTogRmlsdGVyW10pIHtcbiAgICAhdGhpcy5fZmlsdGVycyQuZ2V0VmFsdWUoKS5sZW5ndGggPz8gdGhpcy5yZXNldFBhZ2UoKVxuICAgIHRoaXMuX2ZpbHRlcnMkLm5leHQodmFsdWUpXG4gIH1cbiAgX3NvcnREaXJlY3Rpb24kID0gbmV3IEJlaGF2aW9yU3ViamVjdDxEYXRhU29ydERpcmVjdGlvbj4oRGF0YVNvcnREaXJlY3Rpb24uTk9ORSlcbiAgQElucHV0KClcbiAgZ2V0IHNvcnREaXJlY3Rpb24oKTogRGF0YVNvcnREaXJlY3Rpb24ge1xuICAgIHJldHVybiB0aGlzLl9zb3J0RGlyZWN0aW9uJC5nZXRWYWx1ZSgpXG4gIH1cbiAgc2V0IHNvcnREaXJlY3Rpb24odmFsdWU6IERhdGFTb3J0RGlyZWN0aW9uKSB7XG4gICAgdGhpcy5fc29ydERpcmVjdGlvbiQubmV4dCh2YWx1ZSlcbiAgfVxuICBfc29ydENvbHVtbiQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PHN0cmluZz4oJycpXG4gIEBJbnB1dCgpXG4gIGdldCBzb3J0Q29sdW1uKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXM/Ll9zb3J0Q29sdW1uJC5nZXRWYWx1ZSgpXG4gIH1cbiAgc2V0IHNvcnRDb2x1bW4odmFsdWU6IHN0cmluZykge1xuICAgIHRoaXM/Ll9zb3J0Q29sdW1uJC5uZXh0KHZhbHVlKVxuICB9XG4gIGNvbHVtblRlbXBsYXRlcyQ6IE9ic2VydmFibGU8UmVjb3JkPHN0cmluZywgVGVtcGxhdGVSZWY8YW55PiB8IG51bGw+PiB8IHVuZGVmaW5lZFxuICBjb2x1bW5GaWx0ZXJUZW1wbGF0ZXMkOiBPYnNlcnZhYmxlPFJlY29yZDxzdHJpbmcsIFRlbXBsYXRlUmVmPGFueT4gfCBudWxsPj4gfCB1bmRlZmluZWRcbiAgX2NvbHVtbnMkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxEYXRhVGFibGVDb2x1bW5bXT4oW10pXG4gIEBJbnB1dCgpXG4gIGdldCBjb2x1bW5zKCk6IERhdGFUYWJsZUNvbHVtbltdIHtcbiAgICByZXR1cm4gdGhpcy5fY29sdW1ucyQuZ2V0VmFsdWUoKVxuICB9XG4gIHNldCBjb2x1bW5zKHZhbHVlOiBEYXRhVGFibGVDb2x1bW5bXSkge1xuICAgIHRoaXMuX2NvbHVtbnMkLm5leHQodmFsdWUpXG4gICAgY29uc3Qgb2JzID0gdmFsdWUubWFwKChjKSA9PiB0aGlzLmdldFRlbXBsYXRlKGMsIFRlbXBsYXRlVHlwZS5DRUxMKSlcbiAgICBjb25zdCBmaWx0ZXJPYnMgPSB2YWx1ZS5tYXAoKGMpID0+IHRoaXMuZ2V0VGVtcGxhdGUoYywgVGVtcGxhdGVUeXBlLkZJTFRFUkNFTEwpKVxuICAgIHRoaXMuY29sdW1uVGVtcGxhdGVzJCA9IGNvbWJpbmVMYXRlc3Qob2JzKS5waXBlKFxuICAgICAgbWFwKCh2YWx1ZXMpID0+IE9iamVjdC5mcm9tRW50cmllcyh2YWx1ZS5tYXAoKGMsIGkpID0+IFtjLmlkLCB2YWx1ZXNbaV1dKSkpLFxuICAgICAgZGVib3VuY2VUaW1lKDUwKVxuICAgIClcbiAgICB0aGlzLmNvbHVtbkZpbHRlclRlbXBsYXRlcyQgPSBjb21iaW5lTGF0ZXN0KGZpbHRlck9icykucGlwZShcbiAgICAgIG1hcCgodmFsdWVzKSA9PiBPYmplY3QuZnJvbUVudHJpZXModmFsdWUubWFwKChjLCBpKSA9PiBbYy5pZCwgdmFsdWVzW2ldXSkpKVxuICAgIClcbiAgfVxuICBASW5wdXQoKSBjbGllbnRTaWRlRmlsdGVyaW5nID0gdHJ1ZVxuICBASW5wdXQoKSBjbGllbnRTaWRlU29ydGluZyA9IHRydWVcbiAgQElucHV0KCkgc29ydFN0YXRlczogRGF0YVNvcnREaXJlY3Rpb25bXSA9IFtEYXRhU29ydERpcmVjdGlvbi5BU0NFTkRJTkcsIERhdGFTb3J0RGlyZWN0aW9uLkRFU0NFTkRJTkddXG5cbiAgZGlzcGxheWVkUGFnZVNpemVzJDogT2JzZXJ2YWJsZTwobnVtYmVyIHwgeyBzaG93QWxsOiBzdHJpbmcgfSlbXT5cbiAgX3BhZ2VTaXplcyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PChudW1iZXIgfCB7IHNob3dBbGw6IHN0cmluZyB9KVtdPihbMTAsIDI1LCA1MF0pXG4gIEBJbnB1dCgpXG4gIGdldCBwYWdlU2l6ZXMoKTogKG51bWJlciB8IHsgc2hvd0FsbDogc3RyaW5nIH0pW10ge1xuICAgIHJldHVybiB0aGlzLl9wYWdlU2l6ZXMkLmdldFZhbHVlKClcbiAgfVxuICBzZXQgcGFnZVNpemVzKHZhbHVlOiAobnVtYmVyIHwgeyBzaG93QWxsOiBzdHJpbmcgfSlbXSkge1xuICAgIHRoaXMuX3BhZ2VTaXplcyQubmV4dCh2YWx1ZSlcbiAgfVxuICBkaXNwbGF5ZWRQYWdlU2l6ZSQ6IE9ic2VydmFibGU8bnVtYmVyPlxuICBfcGFnZVNpemUkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxudW1iZXIgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZClcbiAgQElucHV0KClcbiAgZ2V0IHBhZ2VTaXplKCk6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuX3BhZ2VTaXplJC5nZXRWYWx1ZSgpXG4gIH1cbiAgc2V0IHBhZ2VTaXplKHZhbHVlOiBudW1iZXIgfCB1bmRlZmluZWQpIHtcbiAgICB0aGlzLl9wYWdlU2l6ZSQubmV4dCh2YWx1ZSlcbiAgfVxuICBfc2hvd0FsbE9wdGlvbiQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKVxuICBASW5wdXQoKVxuICBzZXQgc2hvd0FsbE9wdGlvbih2YWx1ZTogYm9vbGVhbikge1xuICAgIHRoaXMuX3Nob3dBbGxPcHRpb24kLm5leHQodmFsdWUpXG4gIH1cblxuICBASW5wdXQoKSBlbXB0eVJlc3VsdHNNZXNzYWdlOiBzdHJpbmcgfCB1bmRlZmluZWRcbiAgQElucHV0KCkgbmFtZSA9ICcnXG4gIEBJbnB1dCgpIGRlbGV0ZVBlcm1pc3Npb246IHN0cmluZyB8IHN0cmluZ1tdIHwgdW5kZWZpbmVkXG4gIEBJbnB1dCgpIHZpZXdQZXJtaXNzaW9uOiBzdHJpbmcgfCBzdHJpbmdbXSB8IHVuZGVmaW5lZFxuICBASW5wdXQoKSBlZGl0UGVybWlzc2lvbjogc3RyaW5nIHwgc3RyaW5nW10gfCB1bmRlZmluZWRcbiAgQElucHV0KCkgZGVsZXRlQWN0aW9uVmlzaWJsZUZpZWxkOiBzdHJpbmcgfCB1bmRlZmluZWRcbiAgQElucHV0KCkgZGVsZXRlQWN0aW9uRW5hYmxlZEZpZWxkOiBzdHJpbmcgfCB1bmRlZmluZWRcbiAgQElucHV0KCkgdmlld0FjdGlvblZpc2libGVGaWVsZDogc3RyaW5nIHwgdW5kZWZpbmVkXG4gIEBJbnB1dCgpIHZpZXdBY3Rpb25FbmFibGVkRmllbGQ6IHN0cmluZyB8IHVuZGVmaW5lZFxuICBASW5wdXQoKSBlZGl0QWN0aW9uVmlzaWJsZUZpZWxkOiBzdHJpbmcgfCB1bmRlZmluZWRcbiAgQElucHV0KCkgZWRpdEFjdGlvbkVuYWJsZWRGaWVsZDogc3RyaW5nIHwgdW5kZWZpbmVkXG4gIEBJbnB1dCgpIHNlbGVjdGlvbkVuYWJsZWRGaWVsZDogc3RyaW5nIHwgdW5kZWZpbmVkXG4gIEBJbnB1dCgpIGFsbG93U2VsZWN0QWxsID0gdHJ1ZVxuICBASW5wdXQoKSBwYWdpbmF0b3IgPSB0cnVlXG4gIEBJbnB1dCgpIHBhZ2UgPSAwXG4gIEBJbnB1dCgpIHRhYmxlU3R5bGU6IHsgW2tsYXNzOiBzdHJpbmddOiBhbnkgfSB8IHVuZGVmaW5lZFxuICBASW5wdXQoKVxuICBnZXQgdG90YWxSZWNvcmRzT25TZXJ2ZXIoKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5wYXJhbXNbJ3RvdGFsUmVjb3Jkc09uU2VydmVyJ10gPyBOdW1iZXIodGhpcy5wYXJhbXNbJ3RvdGFsUmVjb3Jkc09uU2VydmVyJ10pIDogdW5kZWZpbmVkXG4gIH1cbiAgc2V0IHRvdGFsUmVjb3Jkc09uU2VydmVyKHZhbHVlOiBudW1iZXIgfCB1bmRlZmluZWQpIHtcbiAgICB0aGlzLnBhcmFtc1sndG90YWxSZWNvcmRzT25TZXJ2ZXInXSA9IHZhbHVlPy50b1N0cmluZygpID8/ICcwJ1xuICB9XG4gIEBJbnB1dCgpIGN1cnJlbnRQYWdlU2hvd2luZ0tleSA9ICdPQ1hfREFUQV9UQUJMRS5TSE9XSU5HJ1xuICBASW5wdXQoKSBjdXJyZW50UGFnZVNob3dpbmdXaXRoVG90YWxPblNlcnZlcktleSA9ICdPQ1hfREFUQV9UQUJMRS5TSE9XSU5HX1dJVEhfVE9UQUxfT05fU0VSVkVSJ1xuICBwYXJhbXM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gPSB7XG4gICAgY3VycmVudFBhZ2U6ICd7Y3VycmVudFBhZ2V9JyxcbiAgICB0b3RhbFBhZ2VzOiAne3RvdGFsUGFnZXN9JyxcbiAgICByb3dzOiAne3Jvd3N9JyxcbiAgICBmaXJzdDogJ3tmaXJzdH0nLFxuICAgIGxhc3Q6ICd7bGFzdH0nLFxuICAgIHRvdGFsUmVjb3JkczogJ3t0b3RhbFJlY29yZHN9JyxcbiAgfVxuXG4gIEBJbnB1dCgpIHN0cmluZ0NlbGxUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PiB8IHVuZGVmaW5lZFxuICBAQ29udGVudENoaWxkKCdzdHJpbmdDZWxsJykgc3RyaW5nQ2VsbENoaWxkVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT4gfCB1bmRlZmluZWRcbiAgZ2V0IF9zdHJpbmdDZWxsKCk6IFRlbXBsYXRlUmVmPGFueT4gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnN0cmluZ0NlbGxUZW1wbGF0ZSB8fCB0aGlzLnN0cmluZ0NlbGxDaGlsZFRlbXBsYXRlXG4gIH1cblxuICBASW5wdXQoKSBudW1iZXJDZWxsVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT4gfCB1bmRlZmluZWRcbiAgQENvbnRlbnRDaGlsZCgnbnVtYmVyQ2VsbCcpIG51bWJlckNlbGxDaGlsZFRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+IHwgdW5kZWZpbmVkXG4gIGdldCBfbnVtYmVyQ2VsbCgpOiBUZW1wbGF0ZVJlZjxhbnk+IHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5udW1iZXJDZWxsVGVtcGxhdGUgfHwgdGhpcy5udW1iZXJDZWxsQ2hpbGRUZW1wbGF0ZVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIFdpbGwgYmUgcmVtb3ZlZCBhbmQgaW5zdGVhZCB0byBjaGFuZ2UgdGhlIHRlbXBsYXRlIG9mIGEgc3BlY2lmaWMgY29sdW1uXG4gICAqIHVzZSB0aGUgbmV3IGFwcHJvYWNoIGluc3RlYWQgYnkgZm9sbG93aW5nIHRoZSBuYW1pbmcgY29udmVudGlvbiBjb2x1bW4gaWQgKyBJZENlbGxcbiAgICogZS5nLiBmb3IgYSBjb2x1bW4gd2l0aCB0aGUgaWQgJ3N0YXR1cycgdXNlIHBUZW1wbGF0ZT1cInN0YXR1c0lkQ2VsbFwiXG4gICAqL1xuICBASW5wdXQoKSBjdXN0b21DZWxsVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT4gfCB1bmRlZmluZWRcbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIFdpbGwgYmUgcmVtb3ZlZCBhbmQgaW5zdGVhZCB0byBjaGFuZ2UgdGhlIHRlbXBsYXRlIG9mIGEgc3BlY2lmaWMgY29sdW1uXG4gICAqIHVzZSB0aGUgbmV3IGFwcHJvYWNoIGluc3RlYWQgYnkgZm9sbG93aW5nIHRoZSBuYW1pbmcgY29udmVudGlvbiBjb2x1bW4gaWQgKyBJZENlbGxcbiAgICogZS5nLiBmb3IgYSBjb2x1bW4gd2l0aCB0aGUgaWQgJ3N0YXR1cycgdXNlIHBUZW1wbGF0ZT1cInN0YXR1c0lkQ2VsbFwiXG4gICAqL1xuICBAQ29udGVudENoaWxkKCdjdXN0b21DZWxsJykgY3VzdG9tQ2VsbENoaWxkVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT4gfCB1bmRlZmluZWRcbiAgZ2V0IF9jdXN0b21DZWxsKCk6IFRlbXBsYXRlUmVmPGFueT4gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmN1c3RvbUNlbGxUZW1wbGF0ZSB8fCB0aGlzLmN1c3RvbUNlbGxDaGlsZFRlbXBsYXRlXG4gIH1cblxuICBASW5wdXQoKSBkYXRlQ2VsbFRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+IHwgdW5kZWZpbmVkXG4gIEBDb250ZW50Q2hpbGQoJ2RhdGVDZWxsJykgZGF0ZUNlbGxDaGlsZFRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+IHwgdW5kZWZpbmVkXG4gIGdldCBfZGF0ZUNlbGwoKTogVGVtcGxhdGVSZWY8YW55PiB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuZGF0ZUNlbGxUZW1wbGF0ZSB8fCB0aGlzLmRhdGVDZWxsQ2hpbGRUZW1wbGF0ZVxuICB9XG5cbiAgQElucHV0KCkgcmVsYXRpdmVEYXRlQ2VsbFRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+IHwgdW5kZWZpbmVkXG4gIEBDb250ZW50Q2hpbGQoJ3JlbGF0aXZlRGF0ZUNlbGwnKSByZWxhdGl2ZURhdGVDZWxsQ2hpbGRUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PiB8IHVuZGVmaW5lZFxuICBnZXQgX3JlbGF0aXZlRGF0ZUNlbGwoKTogVGVtcGxhdGVSZWY8YW55PiB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMucmVsYXRpdmVEYXRlQ2VsbFRlbXBsYXRlIHx8IHRoaXMucmVsYXRpdmVEYXRlQ2VsbENoaWxkVGVtcGxhdGVcbiAgfVxuXG4gIEBJbnB1dCgpIGNlbGxUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PiB8IHVuZGVmaW5lZFxuICBAQ29udGVudENoaWxkKCdjZWxsJykgY2VsbENoaWxkVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT4gfCB1bmRlZmluZWRcbiAgZ2V0IF9jZWxsKCk6IFRlbXBsYXRlUmVmPGFueT4gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmNlbGxUZW1wbGF0ZSB8fCB0aGlzLmNlbGxDaGlsZFRlbXBsYXRlXG4gIH1cbiAgQElucHV0KCkgdHJhbnNsYXRpb25LZXlDZWxsVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT4gfCB1bmRlZmluZWRcbiAgQENvbnRlbnRDaGlsZCgndHJhbnNsYXRpb25LZXlDZWxsJykgdHJhbnNsYXRpb25LZXlDZWxsQ2hpbGRUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PiB8IHVuZGVmaW5lZFxuICBnZXQgX3RyYW5zbGF0aW9uS2V5Q2VsbCgpOiBUZW1wbGF0ZVJlZjxhbnk+IHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy50cmFuc2xhdGlvbktleUNlbGxUZW1wbGF0ZSB8fCB0aGlzLnRyYW5zbGF0aW9uS2V5Q2VsbENoaWxkVGVtcGxhdGVcbiAgfVxuICBASW5wdXQoKSBzdHJpbmdGaWx0ZXJDZWxsVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT4gfCB1bmRlZmluZWRcbiAgQENvbnRlbnRDaGlsZCgnc3RyaW5nRmlsdGVyQ2VsbCcpIHN0cmluZ0ZpbHRlckNlbGxDaGlsZFRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+IHwgdW5kZWZpbmVkXG4gIGdldCBfc3RyaW5nRmlsdGVyQ2VsbCgpOiBUZW1wbGF0ZVJlZjxhbnk+IHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5zdHJpbmdGaWx0ZXJDZWxsVGVtcGxhdGUgfHwgdGhpcy5zdHJpbmdGaWx0ZXJDZWxsQ2hpbGRUZW1wbGF0ZVxuICB9XG4gIEBJbnB1dCgpIG51bWJlckZpbHRlckNlbGxUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PiB8IHVuZGVmaW5lZFxuICBAQ29udGVudENoaWxkKCdudW1iZXJGaWx0ZXJDZWxsJykgbnVtYmVyRmlsdGVyQ2VsbENoaWxkVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT4gfCB1bmRlZmluZWRcbiAgZ2V0IF9udW1iZXJGaWx0ZXJDZWxsKCk6IFRlbXBsYXRlUmVmPGFueT4gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLm51bWJlckZpbHRlckNlbGxUZW1wbGF0ZSB8fCB0aGlzLm51bWJlckZpbHRlckNlbGxDaGlsZFRlbXBsYXRlXG4gIH1cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIFdpbGwgYmUgcmVtb3ZlZCBhbmQgaW5zdGVhZCB0byBjaGFuZ2UgdGhlIHRlbXBsYXRlIG9mIGEgc3BlY2lmaWMgY29sdW1uIGZpbHRlclxuICAgKiB1c2UgdGhlIG5ldyBhcHByb2FjaCBpbnN0ZWFkIGJ5IGZvbGxvd2luZyB0aGUgbmFtaW5nIGNvbnZlbnRpb24gY29sdW1uIGlkICsgSWRGaWx0ZXJDZWxsXG4gICAqIGUuZy4gZm9yIGEgY29sdW1uIHdpdGggdGhlIGlkICdzdGF0dXMnIHVzZSBwVGVtcGxhdGU9XCJzdGF0dXNJZEZpbHRlckNlbGxcIlxuICAgKi9cbiAgQElucHV0KCkgY3VzdG9tRmlsdGVyQ2VsbFRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+IHwgdW5kZWZpbmVkXG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCBXaWxsIGJlIHJlbW92ZWQgYW5kIGluc3RlYWQgdG8gY2hhbmdlIHRoZSB0ZW1wbGF0ZSBvZiBhIHNwZWNpZmljIGNvbHVtbiBmaWx0ZXJcbiAgICogdXNlIHRoZSBuZXcgYXBwcm9hY2ggaW5zdGVhZCBieSBmb2xsb3dpbmcgdGhlIG5hbWluZyBjb252ZW50aW9uIGNvbHVtbiBpZCArIElkRmlsdGVyQ2VsbFxuICAgKiBlLmcuIGZvciBhIGNvbHVtbiB3aXRoIHRoZSBpZCAnc3RhdHVzJyB1c2UgcFRlbXBsYXRlPVwic3RhdHVzSWRGaWx0ZXJDZWxsXCJcbiAgICovXG4gIEBDb250ZW50Q2hpbGQoJ2N1c3RvbUZpbHRlckNlbGwnKSBjdXN0b21GaWx0ZXJDZWxsQ2hpbGRUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PiB8IHVuZGVmaW5lZFxuICBnZXQgX2N1c3RvbUZpbHRlckNlbGwoKTogVGVtcGxhdGVSZWY8YW55PiB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuY3VzdG9tRmlsdGVyQ2VsbFRlbXBsYXRlIHx8IHRoaXMuY3VzdG9tRmlsdGVyQ2VsbENoaWxkVGVtcGxhdGVcbiAgfVxuICBASW5wdXQoKSBkYXRlRmlsdGVyQ2VsbFRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+IHwgdW5kZWZpbmVkXG4gIEBDb250ZW50Q2hpbGQoJ2RhdGVGaWx0ZXJDZWxsJykgZGF0ZUZpbHRlckNlbGxDaGlsZFRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+IHwgdW5kZWZpbmVkXG4gIGdldCBfZGF0ZUZpbHRlckNlbGwoKTogVGVtcGxhdGVSZWY8YW55PiB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuZGF0ZUZpbHRlckNlbGxUZW1wbGF0ZSB8fCB0aGlzLmRhdGVGaWx0ZXJDZWxsQ2hpbGRUZW1wbGF0ZVxuICB9XG4gIEBJbnB1dCgpIHJlbGF0aXZlRGF0ZUZpbHRlckNlbGxUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PiB8IHVuZGVmaW5lZFxuICBAQ29udGVudENoaWxkKCdyZWxhdGl2ZURhdGVGaWx0ZXJDZWxsJykgcmVsYXRpdmVEYXRlRmlsdGVyQ2VsbENoaWxkVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT4gfCB1bmRlZmluZWRcbiAgZ2V0IF9yZWxhdGl2ZURhdGVGaWx0ZXJDZWxsKCk6IFRlbXBsYXRlUmVmPGFueT4gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnJlbGF0aXZlRGF0ZUZpbHRlckNlbGxUZW1wbGF0ZSB8fCB0aGlzLnJlbGF0aXZlRGF0ZUZpbHRlckNlbGxDaGlsZFRlbXBsYXRlXG4gIH1cbiAgQElucHV0KCkgZmlsdGVyQ2VsbFRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+IHwgdW5kZWZpbmVkXG4gIEBDb250ZW50Q2hpbGQoJ2ZpbHRlckNlbGwnKSBmaWx0ZXJDZWxsQ2hpbGRUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PiB8IHVuZGVmaW5lZFxuICBnZXQgX2ZpbHRlckNlbGwoKTogVGVtcGxhdGVSZWY8YW55PiB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuZmlsdGVyQ2VsbFRlbXBsYXRlIHx8IHRoaXMuZmlsdGVyQ2VsbENoaWxkVGVtcGxhdGVcbiAgfVxuICBASW5wdXQoKSB0cmFuc2xhdGlvbktleUZpbHRlckNlbGxUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PiB8IHVuZGVmaW5lZFxuICBAQ29udGVudENoaWxkKCd0cmFuc2xhdGlvbktleUZpbHRlckNlbGwnKSB0cmFuc2xhdGlvbktleUZpbHRlckNlbGxDaGlsZFRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+IHwgdW5kZWZpbmVkXG4gIGdldCBfdHJhbnNsYXRpb25LZXlGaWx0ZXJDZWxsKCk6IFRlbXBsYXRlUmVmPGFueT4gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnRyYW5zbGF0aW9uS2V5RmlsdGVyQ2VsbFRlbXBsYXRlIHx8IHRoaXMudHJhbnNsYXRpb25LZXlGaWx0ZXJDZWxsQ2hpbGRUZW1wbGF0ZVxuICB9XG5cbiAgX2FkZGl0aW9uYWxBY3Rpb25zJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8RGF0YUFjdGlvbltdPihbXSlcbiAgQElucHV0KClcbiAgZ2V0IGFkZGl0aW9uYWxBY3Rpb25zKCk6IERhdGFBY3Rpb25bXSB7XG4gICAgcmV0dXJuIHRoaXMuX2FkZGl0aW9uYWxBY3Rpb25zJC5nZXRWYWx1ZSgpXG4gIH1cbiAgc2V0IGFkZGl0aW9uYWxBY3Rpb25zKHZhbHVlOiBEYXRhQWN0aW9uW10pIHtcbiAgICB0aGlzLl9hZGRpdGlvbmFsQWN0aW9ucyQubmV4dCh2YWx1ZSlcbiAgfVxuICBASW5wdXQoKSBmcm96ZW5BY3Rpb25Db2x1bW4gPSBmYWxzZVxuICBASW5wdXQoKSBhY3Rpb25Db2x1bW5Qb3NpdGlvbjogJ2xlZnQnIHwgJ3JpZ2h0JyA9ICdyaWdodCdcblxuICBAT3V0cHV0KCkgZmlsdGVyZWQgPSBuZXcgRXZlbnRFbWl0dGVyPEZpbHRlcltdPigpXG4gIEBPdXRwdXQoKSBzb3J0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPFNvcnQ+KClcbiAgQE91dHB1dCgpIHZpZXdUYWJsZVJvdyA9IG5ldyBFdmVudEVtaXR0ZXI8Um93PigpXG4gIEBPdXRwdXQoKSBlZGl0VGFibGVSb3cgPSBuZXcgRXZlbnRFbWl0dGVyPFJvdz4oKVxuICBAT3V0cHV0KCkgZGVsZXRlVGFibGVSb3cgPSBuZXcgRXZlbnRFbWl0dGVyPFJvdz4oKVxuICBAT3V0cHV0KCkgc2VsZWN0aW9uQ2hhbmdlZCA9IG5ldyBFdmVudEVtaXR0ZXI8Um93W10+KClcbiAgQE91dHB1dCgpIHBhZ2VDaGFuZ2VkID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KClcbiAgQE91dHB1dCgpIHBhZ2VTaXplQ2hhbmdlZCA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpXG4gIEBPdXRwdXQoKSBjb21wb25lbnRTdGF0ZUNoYW5nZWQgPSBuZXcgRXZlbnRFbWl0dGVyPERhdGFUYWJsZUNvbXBvbmVudFN0YXRlPigpXG5cbiAgZGlzcGxheWVkUm93cyQ6IE9ic2VydmFibGU8dW5rbm93bltdPiB8IHVuZGVmaW5lZFxuICBzZWxlY3RlZFJvd3MkOiBPYnNlcnZhYmxlPHVua25vd25bXT4gfCB1bmRlZmluZWRcblxuICBjdXJyZW50RmlsdGVyQ29sdW1uJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8RGF0YVRhYmxlQ29sdW1uIHwgbnVsbD4obnVsbClcbiAgY3VycmVudEVxdWFsRmlsdGVyT3B0aW9ucyQ6IE9ic2VydmFibGU8eyBvcHRpb25zOiBTZWxlY3RJdGVtW107IGNvbHVtbjogRGF0YVRhYmxlQ29sdW1uIHwgdW5kZWZpbmVkIH0+IHwgdW5kZWZpbmVkXG4gIGN1cnJlbnRFcXVhbFNlbGVjdGVkRmlsdGVycyQ6IE9ic2VydmFibGU8dW5rbm93bltdPiB8IHVuZGVmaW5lZFxuICB0cnV0aHlGaWx0ZXJPcHRpb25zID0gW1xuICAgIHtcbiAgICAgIGtleTogJ09DWF9EQVRBX1RBQkxFLkZJTFRFUl9ZRVMnLFxuICAgICAgdmFsdWU6IHRydWUsXG4gICAgfSxcbiAgICB7XG4gICAgICBrZXk6ICdPQ1hfREFUQV9UQUJMRS5GSUxURVJfTk8nLFxuICAgICAgdmFsdWU6IGZhbHNlLFxuICAgIH0sXG4gIF1cbiAgY3VycmVudFRydXRoeVNlbGVjdGVkRmlsdGVycyQ6IE9ic2VydmFibGU8dW5rbm93bltdPiB8IHVuZGVmaW5lZFxuICBmaWx0ZXJBbW91bnRzJDogT2JzZXJ2YWJsZTxSZWNvcmQ8c3RyaW5nLCBudW1iZXI+PiB8IHVuZGVmaW5lZFxuXG4gIG92ZXJmbG93QWN0aW9ucyQ6IE9ic2VydmFibGU8RGF0YUFjdGlvbltdPlxuICBpbmxpbmVBY3Rpb25zJDogT2JzZXJ2YWJsZTxEYXRhQWN0aW9uW10+XG4gIG92ZXJmbG93TWVudUl0ZW1zJDogT2JzZXJ2YWJsZTxNZW51SXRlbVtdPlxuICBjdXJyZW50TWVudVJvdyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFJvdyB8IG51bGw+KG51bGwpXG5cbiAgdGVtcGxhdGVzJDogQmVoYXZpb3JTdWJqZWN0PFF1ZXJ5TGlzdDxQcmltZVRlbXBsYXRlPiB8IHVuZGVmaW5lZD4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFxuICAgIFF1ZXJ5TGlzdDxQcmltZVRlbXBsYXRlPiB8IHVuZGVmaW5lZFxuICA+KHVuZGVmaW5lZClcbiAgQENvbnRlbnRDaGlsZHJlbihQcmltZVRlbXBsYXRlKVxuICBzZXQgdGVtcGxhdGVzKHZhbHVlOiBRdWVyeUxpc3Q8UHJpbWVUZW1wbGF0ZT4gfCB1bmRlZmluZWQpIHtcbiAgICB0aGlzLnRlbXBsYXRlcyQubmV4dCh2YWx1ZSlcbiAgfVxuXG4gIHZpZXdUZW1wbGF0ZXMkOiBCZWhhdmlvclN1YmplY3Q8UXVlcnlMaXN0PFByaW1lVGVtcGxhdGU+IHwgdW5kZWZpbmVkPiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8XG4gICAgUXVlcnlMaXN0PFByaW1lVGVtcGxhdGU+IHwgdW5kZWZpbmVkXG4gID4odW5kZWZpbmVkKVxuICBAVmlld0NoaWxkcmVuKFByaW1lVGVtcGxhdGUpXG4gIHNldCB2aWV3VGVtcGxhdGVzKHZhbHVlOiBRdWVyeUxpc3Q8UHJpbWVUZW1wbGF0ZT4gfCB1bmRlZmluZWQpIHtcbiAgICB0aGlzLnZpZXdUZW1wbGF0ZXMkLm5leHQodmFsdWUpXG4gIH1cblxuICBwYXJlbnRUZW1wbGF0ZXMkOiBCZWhhdmlvclN1YmplY3Q8UXVlcnlMaXN0PFByaW1lVGVtcGxhdGU+IHwgbnVsbCB8IHVuZGVmaW5lZD4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFxuICAgIFF1ZXJ5TGlzdDxQcmltZVRlbXBsYXRlPiB8IG51bGwgfCB1bmRlZmluZWRcbiAgPih1bmRlZmluZWQpXG4gIEBJbnB1dCgpXG4gIHNldCBwYXJlbnRUZW1wbGF0ZXModmFsdWU6IFF1ZXJ5TGlzdDxQcmltZVRlbXBsYXRlPiB8IG51bGwgfCB1bmRlZmluZWQpIHtcbiAgICB0aGlzLnBhcmVudFRlbXBsYXRlcyQubmV4dCh2YWx1ZSlcbiAgfVxuXG4gIGdldCB2aWV3VGFibGVSb3dPYnNlcnZlZCgpOiBib29sZWFuIHtcbiAgICBjb25zdCBkdiA9IHRoaXMuaW5qZWN0b3IuZ2V0KCdEYXRhVmlld0NvbXBvbmVudCcsIG51bGwpXG4gICAgcmV0dXJuIGR2Py52aWV3SXRlbU9ic2VydmVkIHx8IGR2Py52aWV3SXRlbS5vYnNlcnZlZCB8fCB0aGlzLnZpZXdUYWJsZVJvdy5vYnNlcnZlZFxuICB9XG4gIGdldCBlZGl0VGFibGVSb3dPYnNlcnZlZCgpOiBib29sZWFuIHtcbiAgICBjb25zdCBkdiA9IHRoaXMuaW5qZWN0b3IuZ2V0KCdEYXRhVmlld0NvbXBvbmVudCcsIG51bGwpXG4gICAgcmV0dXJuIGR2Py5lZGl0SXRlbU9ic2VydmVkIHx8IGR2Py5lZGl0SXRlbS5vYnNlcnZlZCB8fCB0aGlzLmVkaXRUYWJsZVJvdy5vYnNlcnZlZFxuICB9XG4gIGdldCBkZWxldGVUYWJsZVJvd09ic2VydmVkKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGR2ID0gdGhpcy5pbmplY3Rvci5nZXQoJ0RhdGFWaWV3Q29tcG9uZW50JywgbnVsbClcbiAgICByZXR1cm4gZHY/LmRlbGV0ZUl0ZW1PYnNlcnZlZCB8fCBkdj8uZGVsZXRlSXRlbS5vYnNlcnZlZCB8fCB0aGlzLmRlbGV0ZVRhYmxlUm93Lm9ic2VydmVkXG4gIH1cbiAgZ2V0IGFueVJvd0FjdGlvbk9ic2VydmVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnZpZXdUYWJsZVJvd09ic2VydmVkIHx8IHRoaXMuZWRpdFRhYmxlUm93T2JzZXJ2ZWQgfHwgdGhpcy5kZWxldGVUYWJsZVJvd09ic2VydmVkXG4gIH1cblxuICBnZXQgc2VsZWN0aW9uQ2hhbmdlZE9ic2VydmVkKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGR2ID0gdGhpcy5pbmplY3Rvci5nZXQoJ0RhdGFWaWV3Q29tcG9uZW50JywgbnVsbClcbiAgICByZXR1cm4gZHY/LnNlbGVjdGlvbkNoYW5nZWRPYnNlcnZlZCB8fCBkdj8uc2VsZWN0aW9uQ2hhbmdlZC5vYnNlcnZlZCB8fCB0aGlzLnNlbGVjdGlvbkNoYW5nZWQub2JzZXJ2ZWRcbiAgfVxuXG4gIHRlbXBsYXRlc09ic2VydmFibGVzOiBSZWNvcmQ8c3RyaW5nLCBPYnNlcnZhYmxlPFRlbXBsYXRlUmVmPGFueT4gfCBudWxsPj4gPSB7fVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIEBJbmplY3QoTE9DQUxFX0lEKSBsb2NhbGU6IHN0cmluZyxcbiAgICB0cmFuc2xhdGVTZXJ2aWNlOiBUcmFuc2xhdGVTZXJ2aWNlLFxuICAgIHByaXZhdGUgcm91dGVyOiBSb3V0ZXIsXG4gICAgcHJpdmF0ZSBpbmplY3RvcjogSW5qZWN0b3IsXG4gICAgcHJpdmF0ZSB1c2VyU2VydmljZTogVXNlclNlcnZpY2VcbiAgKSB7XG4gICAgc3VwZXIobG9jYWxlLCB0cmFuc2xhdGVTZXJ2aWNlKVxuICAgIHRoaXMubmFtZSA9IHRoaXMubmFtZSB8fCB0aGlzLnJvdXRlci51cmwucmVwbGFjZSgvW15BLVphLXowLTldLywgJ18nKVxuICAgIHRoaXMuZGlzcGxheWVkUGFnZVNpemVzJCA9IGNvbWJpbmVMYXRlc3QoW1xuICAgICAgdGhpcy5fcGFnZVNpemVzJCxcbiAgICAgIHRoaXMudHJhbnNsYXRlU2VydmljZS5nZXQoJ09DWF9EQVRBX1RBQkxFLkFMTCcpLFxuICAgICAgdGhpcy5fc2hvd0FsbE9wdGlvbiQsXG4gICAgXSkucGlwZShcbiAgICAgIG1hcCgoW3BhZ2VTaXplcywgdHJhbnNsYXRpb24sIHNob3dBbGxPcHRpb25dKSA9PlxuICAgICAgICBzaG93QWxsT3B0aW9uID8gcGFnZVNpemVzLmNvbmNhdCh7IHNob3dBbGw6IHRyYW5zbGF0aW9uIH0pIDogcGFnZVNpemVzXG4gICAgICApXG4gICAgKVxuICAgIHRoaXMuZGlzcGxheWVkUGFnZVNpemUkID0gY29tYmluZUxhdGVzdChbdGhpcy5fcGFnZVNpemUkLCB0aGlzLl9wYWdlU2l6ZXMkXSkucGlwZShcbiAgICAgIG1hcCgoW3BhZ2VTaXplLCBwYWdlU2l6ZXNdKSA9PiBwYWdlU2l6ZSA/PyBwYWdlU2l6ZXMuZmluZCgodmFsKTogdmFsIGlzIG51bWJlciA9PiB0eXBlb2YgdmFsID09PSAnbnVtYmVyJykgPz8gNTApXG4gICAgKVxuICAgIHRoaXMub3ZlcmZsb3dBY3Rpb25zJCA9IHRoaXMuX2FkZGl0aW9uYWxBY3Rpb25zJC5waXBlKFxuICAgICAgbWFwKChhY3Rpb25zKSA9PiBhY3Rpb25zLmZpbHRlcigoYWN0aW9uKSA9PiBhY3Rpb24uc2hvd0FzT3ZlcmZsb3cpKVxuICAgIClcbiAgICB0aGlzLmlubGluZUFjdGlvbnMkID0gdGhpcy5fYWRkaXRpb25hbEFjdGlvbnMkLnBpcGUoXG4gICAgICBtYXAoKGFjdGlvbnMpID0+IGFjdGlvbnMuZmlsdGVyKChhY3Rpb24pID0+ICFhY3Rpb24uc2hvd0FzT3ZlcmZsb3cpKVxuICAgIClcbiAgICB0aGlzLm92ZXJmbG93TWVudUl0ZW1zJCA9IGNvbWJpbmVMYXRlc3QoW3RoaXMub3ZlcmZsb3dBY3Rpb25zJCwgdGhpcy5jdXJyZW50TWVudVJvdyRdKS5waXBlKFxuICAgICAgbWVyZ2VNYXAoKFthY3Rpb25zLCByb3ddKSA9PlxuICAgICAgICB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuZ2V0KFsuLi5hY3Rpb25zLm1hcCgoYSkgPT4gYS5sYWJlbEtleSB8fCAnJyldKS5waXBlKFxuICAgICAgICAgIG1hcCgodHJhbnNsYXRpb25zKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gYWN0aW9uc1xuICAgICAgICAgICAgICAuZmlsdGVyKChhKSA9PiB0aGlzLnVzZXJTZXJ2aWNlLmhhc1Blcm1pc3Npb24oYS5wZXJtaXNzaW9uKSlcbiAgICAgICAgICAgICAgLm1hcCgoYSkgPT4gKHtcbiAgICAgICAgICAgICAgICBsYWJlbDogdHJhbnNsYXRpb25zW2EubGFiZWxLZXkgfHwgJyddLFxuICAgICAgICAgICAgICAgIGljb246IGEuaWNvbixcbiAgICAgICAgICAgICAgICBzdHlsZUNsYXNzOiAoYS5jbGFzc2VzIHx8IFtdKS5qb2luKCcgJyksXG4gICAgICAgICAgICAgICAgZGlzYWJsZWQ6IGEuZGlzYWJsZWQgfHwgKCEhYS5hY3Rpb25FbmFibGVkRmllbGQgJiYgIXRoaXMuZmllbGRJc1RydXRoeShyb3csIGEuYWN0aW9uRW5hYmxlZEZpZWxkKSksXG4gICAgICAgICAgICAgICAgdmlzaWJsZTogIWEuYWN0aW9uVmlzaWJsZUZpZWxkIHx8IHRoaXMuZmllbGRJc1RydXRoeShyb3csIGEuYWN0aW9uVmlzaWJsZUZpZWxkKSxcbiAgICAgICAgICAgICAgICBjb21tYW5kOiAoKSA9PiBhLmNhbGxiYWNrKHJvdyksXG4gICAgICAgICAgICAgIH0pKVxuICAgICAgICAgIH0pXG4gICAgICAgIClcbiAgICAgIClcbiAgICApXG4gICAgdGhpcy5yb3dTZWxlY3RhYmxlID0gdGhpcy5yb3dTZWxlY3RhYmxlLmJpbmQodGhpcylcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuZGlzcGxheWVkUm93cyQgPSBjb21iaW5lTGF0ZXN0KFt0aGlzLl9yb3dzJCwgdGhpcy5fZmlsdGVycyQsIHRoaXMuX3NvcnRDb2x1bW4kLCB0aGlzLl9zb3J0RGlyZWN0aW9uJF0pLnBpcGUoXG4gICAgICBtZXJnZU1hcCgocGFyYW1zKSA9PiB0aGlzLnRyYW5zbGF0ZUl0ZW1zKHBhcmFtcywgdGhpcy5jb2x1bW5zLCB0aGlzLmNsaWVudFNpZGVGaWx0ZXJpbmcsIHRoaXMuY2xpZW50U2lkZVNvcnRpbmcpKSxcbiAgICAgIG1hcCgocGFyYW1zKSA9PiB0aGlzLmZpbHRlckl0ZW1zKHBhcmFtcywgdGhpcy5jbGllbnRTaWRlRmlsdGVyaW5nKSksXG4gICAgICBtYXAoKHBhcmFtcykgPT4gdGhpcy5zb3J0SXRlbXMocGFyYW1zLCB0aGlzLmNvbHVtbnMsIHRoaXMuY2xpZW50U2lkZVNvcnRpbmcpKSxcbiAgICAgIG1hcCgoW3Jvd3NdKSA9PiB0aGlzLmZsYXR0ZW5JdGVtcyhyb3dzKSlcbiAgICApXG4gICAgdGhpcy5jdXJyZW50VHJ1dGh5U2VsZWN0ZWRGaWx0ZXJzJCA9IGNvbWJpbmVMYXRlc3QoW3RoaXMuX2ZpbHRlcnMkLCB0aGlzLmN1cnJlbnRGaWx0ZXJDb2x1bW4kXSkucGlwZShcbiAgICAgIG1hcCgoW2ZpbHRlcnMsIGN1cnJlbnRGaWx0ZXJDb2x1bW5dKSA9PiB7XG4gICAgICAgIHJldHVybiBmaWx0ZXJzXG4gICAgICAgICAgLmZpbHRlcihcbiAgICAgICAgICAgIChmaWx0ZXIpID0+XG4gICAgICAgICAgICAgIGZpbHRlci5jb2x1bW5JZCA9PT0gY3VycmVudEZpbHRlckNvbHVtbj8uaWQgJiYgY3VycmVudEZpbHRlckNvbHVtbi5maWx0ZXJUeXBlID09PSBGaWx0ZXJUeXBlLlRSVVRIWVxuICAgICAgICAgIClcbiAgICAgICAgICAubWFwKChmaWx0ZXIpID0+IGZpbHRlci52YWx1ZSlcbiAgICAgIH0pXG4gICAgKVxuICAgIHRoaXMuY3VycmVudEVxdWFsU2VsZWN0ZWRGaWx0ZXJzJCA9IGNvbWJpbmVMYXRlc3QoW3RoaXMuX2ZpbHRlcnMkLCB0aGlzLmN1cnJlbnRGaWx0ZXJDb2x1bW4kXSkucGlwZShcbiAgICAgIG1hcCgoW2ZpbHRlcnMsIGN1cnJlbnRGaWx0ZXJDb2x1bW5dKSA9PiB7XG4gICAgICAgIHJldHVybiBmaWx0ZXJzXG4gICAgICAgICAgLmZpbHRlcihcbiAgICAgICAgICAgIChmaWx0ZXIpID0+XG4gICAgICAgICAgICAgIGZpbHRlci5jb2x1bW5JZCA9PT0gY3VycmVudEZpbHRlckNvbHVtbj8uaWQgJiZcbiAgICAgICAgICAgICAgKCFjdXJyZW50RmlsdGVyQ29sdW1uLmZpbHRlclR5cGUgfHwgY3VycmVudEZpbHRlckNvbHVtbi5maWx0ZXJUeXBlID09PSBGaWx0ZXJUeXBlLkVRVUFMKVxuICAgICAgICAgIClcbiAgICAgICAgICAubWFwKChmaWx0ZXIpID0+IGZpbHRlci52YWx1ZSlcbiAgICAgIH0pXG4gICAgKVxuICAgIHRoaXMuY3VycmVudEVxdWFsRmlsdGVyT3B0aW9ucyQgPSBjb21iaW5lTGF0ZXN0KFt0aGlzLl9yb3dzJCwgdGhpcy5jdXJyZW50RmlsdGVyQ29sdW1uJCwgdGhpcy5fZmlsdGVycyRdKS5waXBlKFxuICAgICAgZmlsdGVyKFxuICAgICAgICAoW18sIGN1cnJlbnRGaWx0ZXJDb2x1bW4sIF9fXSkgPT5cbiAgICAgICAgICAhY3VycmVudEZpbHRlckNvbHVtbj8uZmlsdGVyVHlwZSB8fCBjdXJyZW50RmlsdGVyQ29sdW1uLmZpbHRlclR5cGUgPT09IEZpbHRlclR5cGUuRVFVQUxcbiAgICAgICksXG4gICAgICBtZXJnZU1hcCgoW3Jvd3MsIGN1cnJlbnRGaWx0ZXJDb2x1bW4sIGZpbHRlcnNdKSA9PiB7XG4gICAgICAgIGlmICghY3VycmVudEZpbHRlckNvbHVtbj8uaWQpIHtcbiAgICAgICAgICByZXR1cm4gb2YoeyBvcHRpb25zOiBbXSwgY29sdW1uOiB1bmRlZmluZWQgfSlcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGN1cnJlbnRGaWx0ZXJzID0gZmlsdGVyc1xuICAgICAgICAgIC5maWx0ZXIoXG4gICAgICAgICAgICAoZmlsdGVyKSA9PlxuICAgICAgICAgICAgICBmaWx0ZXIuY29sdW1uSWQgPT09IGN1cnJlbnRGaWx0ZXJDb2x1bW4/LmlkICYmXG4gICAgICAgICAgICAgICghY3VycmVudEZpbHRlckNvbHVtbi5maWx0ZXJUeXBlIHx8IGN1cnJlbnRGaWx0ZXJDb2x1bW4uZmlsdGVyVHlwZSA9PT0gRmlsdGVyVHlwZS5FUVVBTClcbiAgICAgICAgICApXG4gICAgICAgICAgLm1hcCgoZmlsdGVyKSA9PiBmaWx0ZXIudmFsdWUpXG5cbiAgICAgICAgY29uc3QgY29sdW1uVmFsdWVzID0gcm93cy5tYXAoKHJvdykgPT4gcm93W2N1cnJlbnRGaWx0ZXJDb2x1bW4/LmlkXSlcbiAgICAgICAgY29uc3QgdHJhbnNsYXRlT2JzZXJ2YWJsZSA9XG4gICAgICAgICAgdGhpcy5jb2x1bW5zLmZpbmQoKGMpID0+IGMuaWQgPT09IGN1cnJlbnRGaWx0ZXJDb2x1bW4/LmlkKT8uY29sdW1uVHlwZSA9PT0gQ29sdW1uVHlwZS5UUkFOU0xBVElPTl9LRVlcbiAgICAgICAgICAgID8gdGhpcy50cmFuc2xhdGVDb2x1bW5WYWx1ZXMoY29sdW1uVmFsdWVzIGFzIHN0cmluZ1tdKVxuICAgICAgICAgICAgOiBvZihPYmplY3QuZnJvbUVudHJpZXMoY29sdW1uVmFsdWVzLm1hcCgoY3YpID0+IFtjdiwgY3ZdKSkpXG4gICAgICAgIHJldHVybiB0cmFuc2xhdGVPYnNlcnZhYmxlLnBpcGUoXG4gICAgICAgICAgbWFwKCh0cmFuc2xhdGVkVmFsdWVzKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gT2JqZWN0LnZhbHVlcyh0cmFuc2xhdGVkVmFsdWVzKVxuICAgICAgICAgICAgICAuY29uY2F0KGN1cnJlbnRGaWx0ZXJzKVxuICAgICAgICAgICAgICAuZmlsdGVyKCh2YWx1ZSwgaW5kZXgsIHNlbGYpID0+IHNlbGYuaW5kZXhPZih2YWx1ZSkgPT09IGluZGV4ICYmIHZhbHVlICE9IG51bGwpXG4gICAgICAgICAgICAgIC5tYXAoXG4gICAgICAgICAgICAgICAgKGZpbHRlck9wdGlvbikgPT5cbiAgICAgICAgICAgICAgICAgICh7XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiBmaWx0ZXJPcHRpb24sXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiBmaWx0ZXJPcHRpb24sXG4gICAgICAgICAgICAgICAgICB9KSBhcyBTZWxlY3RJdGVtXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBtYXAoKG9wdGlvbnMpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIG9wdGlvbnM6IG9wdGlvbnMsXG4gICAgICAgICAgICAgIGNvbHVtbjogY3VycmVudEZpbHRlckNvbHVtbixcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KVxuICAgICAgICApXG4gICAgICB9KVxuICAgIClcbiAgICB0aGlzLmZpbHRlckFtb3VudHMkID0gdGhpcy5fZmlsdGVycyQucGlwZShcbiAgICAgIG1hcCgoZmlsdGVycykgPT5cbiAgICAgICAgZmlsdGVyc1xuICAgICAgICAgIC5tYXAoKGZpbHRlcikgPT4gZmlsdGVyLmNvbHVtbklkKVxuICAgICAgICAgIC5tYXAoKGNvbHVtbklkKSA9PiBbY29sdW1uSWQsIGZpbHRlcnMuZmlsdGVyKChmaWx0ZXIpID0+IGZpbHRlci5jb2x1bW5JZCA9PT0gY29sdW1uSWQpLmxlbmd0aF0pXG4gICAgICApLFxuICAgICAgbWFwKChhbW91bnRzKSA9PiBPYmplY3QuZnJvbUVudHJpZXMoYW1vdW50cykpXG4gICAgKVxuICAgIHRoaXMubWFwU2VsZWN0aW9uVG9Sb3dzKClcbiAgICB0aGlzLmVtaXRDb21wb25lbnRTdGF0ZUNoYW5nZWQoKVxuICB9XG5cbiAgdHJhbnNsYXRlQ29sdW1uVmFsdWVzKGNvbHVtblZhbHVlczogc3RyaW5nW10pOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgIHJldHVybiBjb2x1bW5WYWx1ZXMubGVuZ3RoID8gdGhpcy50cmFuc2xhdGVTZXJ2aWNlLmdldChjb2x1bW5WYWx1ZXMgYXMgc3RyaW5nW10pIDogb2Yoe30pXG4gIH1cblxuICBlbWl0Q29tcG9uZW50U3RhdGVDaGFuZ2VkKHN0YXRlOiBEYXRhVGFibGVDb21wb25lbnRTdGF0ZSA9IHt9KSB7XG4gICAgdGhpcy5kaXNwbGF5ZWRQYWdlU2l6ZSRcbiAgICAgIC5waXBlKHdpdGhMYXRlc3RGcm9tKHRoaXMuX3NlbGVjdGlvbklkcyQsIHRoaXMuX3Jvd3MkKSwgZmlyc3QoKSlcbiAgICAgIC5zdWJzY3JpYmUoKFtwYWdlU2l6ZSwgc2VsZWN0ZWRJZHMsIHJvd3NdKSA9PiB7XG4gICAgICAgIHRoaXMuY29tcG9uZW50U3RhdGVDaGFuZ2VkLmVtaXQoe1xuICAgICAgICAgIGZpbHRlcnM6IHRoaXMuZmlsdGVycyxcbiAgICAgICAgICBzb3J0aW5nOiB7XG4gICAgICAgICAgICBzb3J0Q29sdW1uOiB0aGlzLnNvcnRDb2x1bW4sXG4gICAgICAgICAgICBzb3J0RGlyZWN0aW9uOiB0aGlzLnNvcnREaXJlY3Rpb24sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBwYWdlU2l6ZSxcbiAgICAgICAgICBhY3RpdmVQYWdlOiB0aGlzLnBhZ2UsXG4gICAgICAgICAgc2VsZWN0ZWRSb3dzOiByb3dzLmZpbHRlcigocm93KSA9PiBzZWxlY3RlZElkcy5pbmNsdWRlcyhyb3cuaWQpKSxcbiAgICAgICAgICAuLi5zdGF0ZSxcbiAgICAgICAgfSlcbiAgICAgIH0pXG4gIH1cblxuICBuZ0FmdGVyQ29udGVudEluaXQoKSB7XG4gICAgdGhpcy50ZW1wbGF0ZXMkLnZhbHVlPy5mb3JFYWNoKChpdGVtKSA9PiB7XG4gICAgICBzd2l0Y2ggKGl0ZW0uZ2V0VHlwZSgpKSB7XG4gICAgICAgIGNhc2UgJ3N0cmluZ0NlbGwnOlxuICAgICAgICAgIHRoaXMuc3RyaW5nQ2VsbENoaWxkVGVtcGxhdGUgPSBpdGVtLnRlbXBsYXRlXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAnbnVtYmVyQ2VsbCc6XG4gICAgICAgICAgdGhpcy5udW1iZXJDZWxsQ2hpbGRUZW1wbGF0ZSA9IGl0ZW0udGVtcGxhdGVcbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlICdjdXN0b21DZWxsJzpcbiAgICAgICAgICB0aGlzLmN1c3RvbUNlbGxDaGlsZFRlbXBsYXRlID0gaXRlbS50ZW1wbGF0ZVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgJ2RhdGVDZWxsJzpcbiAgICAgICAgICB0aGlzLmRhdGVDZWxsQ2hpbGRUZW1wbGF0ZSA9IGl0ZW0udGVtcGxhdGVcbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlICdyZWxhdGl2ZURhdGVDZWxsJzpcbiAgICAgICAgICB0aGlzLnJlbGF0aXZlRGF0ZUNlbGxDaGlsZFRlbXBsYXRlID0gaXRlbS50ZW1wbGF0ZVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgJ2NlbGxUZW1wbGF0ZSc6XG4gICAgICAgICAgdGhpcy5jZWxsQ2hpbGRUZW1wbGF0ZSA9IGl0ZW0udGVtcGxhdGVcbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlICd0cmFuc2xhdGlvbktleUNlbGwnOlxuICAgICAgICAgIHRoaXMudHJhbnNsYXRpb25LZXlDZWxsQ2hpbGRUZW1wbGF0ZSA9IGl0ZW0udGVtcGxhdGVcbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlICdzdHJpbmdGaWx0ZXJDZWxsJzpcbiAgICAgICAgICB0aGlzLnN0cmluZ0ZpbHRlckNlbGxDaGlsZFRlbXBsYXRlID0gaXRlbS50ZW1wbGF0ZVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgJ251bWJlckZpbHRlckNlbGwnOlxuICAgICAgICAgIHRoaXMubnVtYmVyRmlsdGVyQ2VsbENoaWxkVGVtcGxhdGUgPSBpdGVtLnRlbXBsYXRlXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAnY3VzdG9tRmlsdGVyQ2VsbCc6XG4gICAgICAgICAgdGhpcy5jdXN0b21GaWx0ZXJDZWxsQ2hpbGRUZW1wbGF0ZSA9IGl0ZW0udGVtcGxhdGVcbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlICdkYXRlRmlsdGVyQ2VsbCc6XG4gICAgICAgICAgdGhpcy5kYXRlRmlsdGVyQ2VsbENoaWxkVGVtcGxhdGUgPSBpdGVtLnRlbXBsYXRlXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAncmVsYXRpdmVEYXRlRmlsdGVyQ2VsbCc6XG4gICAgICAgICAgdGhpcy5yZWxhdGl2ZURhdGVGaWx0ZXJDZWxsQ2hpbGRUZW1wbGF0ZSA9IGl0ZW0udGVtcGxhdGVcbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlICdmaWx0ZXJDZWxsVGVtcGxhdGUnOlxuICAgICAgICAgIHRoaXMuZmlsdGVyQ2VsbENoaWxkVGVtcGxhdGUgPSBpdGVtLnRlbXBsYXRlXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAndHJhbnNsYXRpb25LZXlGaWx0ZXJDZWxsJzpcbiAgICAgICAgICB0aGlzLnRyYW5zbGF0aW9uS2V5RmlsdGVyQ2VsbENoaWxkVGVtcGxhdGUgPSBpdGVtLnRlbXBsYXRlXG4gICAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgb25Tb3J0Q29sdW1uQ2xpY2soc29ydENvbHVtbjogc3RyaW5nKSB7XG4gICAgY29uc3QgbmV3U29ydERpcmVjdGlvbiA9IHRoaXMuY29sdW1uTmV4dFNvcnREaXJlY3Rpb24oc29ydENvbHVtbilcblxuICAgIHRoaXMuX3NvcnRDb2x1bW4kLm5leHQoc29ydENvbHVtbilcbiAgICB0aGlzLl9zb3J0RGlyZWN0aW9uJC5uZXh0KG5ld1NvcnREaXJlY3Rpb24pXG5cbiAgICB0aGlzLnNvcnRlZC5lbWl0KHsgc29ydENvbHVtbjogc29ydENvbHVtbiwgc29ydERpcmVjdGlvbjogbmV3U29ydERpcmVjdGlvbiB9KVxuICAgIHRoaXMuZW1pdENvbXBvbmVudFN0YXRlQ2hhbmdlZCh7XG4gICAgICBzb3J0aW5nOiB7XG4gICAgICAgIHNvcnRDb2x1bW46IHNvcnRDb2x1bW4sXG4gICAgICAgIHNvcnREaXJlY3Rpb246IG5ld1NvcnREaXJlY3Rpb24sXG4gICAgICB9LFxuICAgIH0pXG4gIH1cblxuICBjb2x1bW5OZXh0U29ydERpcmVjdGlvbihzb3J0Q29sdW1uOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gc29ydENvbHVtbiAhPT0gdGhpcy5zb3J0Q29sdW1uXG4gICAgICA/IHRoaXMuc29ydFN0YXRlc1swXVxuICAgICAgOiB0aGlzLnNvcnRTdGF0ZXNbKHRoaXMuc29ydFN0YXRlcy5pbmRleE9mKHRoaXMuc29ydERpcmVjdGlvbikgKyAxKSAlIHRoaXMuc29ydFN0YXRlcy5sZW5ndGhdXG4gIH1cblxuICBvbkRlbGV0ZVJvdyhzZWxlY3RlZFRhYmxlUm93OiBSb3cpIHtcbiAgICB0aGlzLmRlbGV0ZVRhYmxlUm93LmVtaXQoc2VsZWN0ZWRUYWJsZVJvdylcbiAgfVxuXG4gIG9uVmlld1JvdyhzZWxlY3RlZFRhYmxlUm93OiBSb3cpIHtcbiAgICB0aGlzLnZpZXdUYWJsZVJvdy5lbWl0KHNlbGVjdGVkVGFibGVSb3cpXG4gIH1cblxuICBvbkVkaXRSb3coc2VsZWN0ZWRUYWJsZVJvdzogUm93KSB7XG4gICAgdGhpcy5lZGl0VGFibGVSb3cuZW1pdChzZWxlY3RlZFRhYmxlUm93KVxuICB9XG5cbiAgb25GaWx0ZXJDaG9zZW4oY29sdW1uOiBEYXRhVGFibGVDb2x1bW4pIHtcbiAgICB0aGlzLmN1cnJlbnRGaWx0ZXJDb2x1bW4kLm5leHQoY29sdW1uKVxuICB9XG5cbiAgb25NdWx0aXNlbGVjdEZpbHRlckNoYW5nZShjb2x1bW46IERhdGFUYWJsZUNvbHVtbiwgZXZlbnQ6IGFueSkge1xuICAgIGNvbnN0IGZpbHRlcnMgPSB0aGlzLmZpbHRlcnNcbiAgICAgIC5maWx0ZXIoKGZpbHRlcikgPT4gZmlsdGVyLmNvbHVtbklkICE9PSBjb2x1bW4uaWQpXG4gICAgICAuY29uY2F0KFxuICAgICAgICBldmVudC52YWx1ZS5tYXAoKHZhbHVlOiBQcmltaXRpdmUpID0+ICh7XG4gICAgICAgICAgY29sdW1uSWQ6IGNvbHVtbi5pZCxcbiAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICBmaWx0ZXJUeXBlOiBjb2x1bW4uZmlsdGVyVHlwZSxcbiAgICAgICAgfSkpXG4gICAgICApXG4gICAgaWYgKHRoaXMuY2xpZW50U2lkZUZpbHRlcmluZykge1xuICAgICAgdGhpcy5maWx0ZXJzID0gZmlsdGVyc1xuICAgIH1cbiAgICB0aGlzLmZpbHRlcmVkLmVtaXQoZmlsdGVycylcbiAgICB0aGlzLmVtaXRDb21wb25lbnRTdGF0ZUNoYW5nZWQoe1xuICAgICAgZmlsdGVycyxcbiAgICB9KVxuICAgIHRoaXMucmVzZXRQYWdlKClcbiAgfVxuXG4gIGdldFNlbGVjdGVkRmlsdGVycyhjb2x1bW5JZDogc3RyaW5nKTogdW5rbm93bltdIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5maWx0ZXJzLmZpbHRlcigoZmlsdGVyKSA9PiBmaWx0ZXIuY29sdW1uSWQgPT09IGNvbHVtbklkKS5tYXAoKGZpbHRlcikgPT4gZmlsdGVyLnZhbHVlKVxuICB9XG5cbiAgc29ydEljb25UaXRsZShzb3J0Q29sdW1uOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5zb3J0RGlyZWN0aW9uVG9UaXRsZShcbiAgICAgIHNvcnRDb2x1bW4gIT09IHRoaXMuc29ydERpcmVjdGlvblxuICAgICAgICA/IERhdGFTb3J0RGlyZWN0aW9uLk5PTkVcbiAgICAgICAgOiB0aGlzLnNvcnRTdGF0ZXNbdGhpcy5zb3J0U3RhdGVzLmluZGV4T2YodGhpcy5zb3J0RGlyZWN0aW9uKSAlIHRoaXMuc29ydFN0YXRlcy5sZW5ndGhdXG4gICAgKVxuICB9XG5cbiAgc29ydERpcmVjdGlvblRvVGl0bGUoc29ydERpcmVjdGlvbjogRGF0YVNvcnREaXJlY3Rpb24pIHtcbiAgICBzd2l0Y2ggKHNvcnREaXJlY3Rpb24pIHtcbiAgICAgIGNhc2UgRGF0YVNvcnREaXJlY3Rpb24uQVNDRU5ESU5HOlxuICAgICAgICByZXR1cm4gJ09DWF9EQVRBX1RBQkxFLlRPR0dMRV9CVVRUT04uQVNDRU5ESU5HX1RJVExFJ1xuICAgICAgY2FzZSBEYXRhU29ydERpcmVjdGlvbi5ERVNDRU5ESU5HOlxuICAgICAgICByZXR1cm4gJ09DWF9EQVRBX1RBQkxFLlRPR0dMRV9CVVRUT04uREVTQ0VORElOR19USVRMRSdcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiAnT0NYX0RBVEFfVEFCTEUuVE9HR0xFX0JVVFRPTi5ERUZBVUxUX1RJVExFJ1xuICAgIH1cbiAgfVxuXG4gIG1hcFNlbGVjdGlvblRvUm93cygpIHtcbiAgICB0aGlzLnNlbGVjdGVkUm93cyQgPSBjb21iaW5lTGF0ZXN0KFt0aGlzLl9zZWxlY3Rpb25JZHMkLCB0aGlzLl9yb3dzJF0pLnBpcGUoXG4gICAgICBtYXAoKFtzZWxlY3RlZFJvd0lkcywgcm93c10pID0+IHtcbiAgICAgICAgcmV0dXJuIHNlbGVjdGVkUm93SWRzLm1hcCgocm93SWQpID0+IHtcbiAgICAgICAgICByZXR1cm4gcm93cy5maW5kKChyKSA9PiByLmlkID09PSByb3dJZClcbiAgICAgICAgfSlcbiAgICAgIH0pXG4gICAgKVxuICB9XG5cbiAgaXNSb3dTZWxlY3Rpb25EaXNhYmxlZChyb3dPYmplY3Q6IFJvdykge1xuICAgIHJldHVybiAhIXRoaXMuc2VsZWN0aW9uRW5hYmxlZEZpZWxkICYmICF0aGlzLmZpZWxkSXNUcnV0aHkocm93T2JqZWN0LCB0aGlzLnNlbGVjdGlvbkVuYWJsZWRGaWVsZClcbiAgfVxuXG4gIHJvd1NlbGVjdGFibGUoZXZlbnQ6IGFueSkge1xuICAgIHJldHVybiAhdGhpcy5pc1Jvd1NlbGVjdGlvbkRpc2FibGVkKGV2ZW50LmRhdGEpXG4gIH1cblxuICBvblNlbGVjdGlvbkNoYW5nZShzZWxlY3Rpb246IFJvd1tdKSB7XG4gICAgbGV0IG5ld1NlbGVjdGlvbklkcyA9IHNlbGVjdGlvbi5tYXAoKHJvdykgPT4gcm93LmlkKVxuICAgIGNvbnN0IHJvd3MgPSB0aGlzLl9yb3dzJC5nZXRWYWx1ZSgpXG5cbiAgICBpZiAodGhpcy5zZWxlY3Rpb25FbmFibGVkRmllbGQpIHtcbiAgICAgIGNvbnN0IGRpc2FibGVkUm93SWRzID0gcm93cy5maWx0ZXIoKHIpID0+ICF0aGlzLmZpZWxkSXNUcnV0aHkociwgdGhpcy5zZWxlY3Rpb25FbmFibGVkRmllbGQpKS5tYXAoKHJvdykgPT4gcm93LmlkKVxuICAgICAgaWYgKGRpc2FibGVkUm93SWRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgbmV3U2VsZWN0aW9uSWRzID0gdGhpcy5tZXJnZVdpdGhEaXNhYmxlZEtleXMobmV3U2VsZWN0aW9uSWRzLCBkaXNhYmxlZFJvd0lkcylcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLl9zZWxlY3Rpb25JZHMkLm5leHQobmV3U2VsZWN0aW9uSWRzKVxuICAgIHRoaXMuc2VsZWN0aW9uQ2hhbmdlZC5lbWl0KHRoaXMuX3Jvd3MkLmdldFZhbHVlKCkuZmlsdGVyKChyb3cpID0+IG5ld1NlbGVjdGlvbklkcy5pbmNsdWRlcyhyb3cuaWQpKSlcbiAgICB0aGlzLmVtaXRDb21wb25lbnRTdGF0ZUNoYW5nZWQoKVxuICB9XG5cbiAgbWVyZ2VXaXRoRGlzYWJsZWRLZXlzKG5ld1NlbGVjdGlvbklkczogKHN0cmluZyB8IG51bWJlcilbXSwgZGlzYWJsZWRSb3dJZHM6IChzdHJpbmcgfCBudW1iZXIpW10pIHtcbiAgICBjb25zdCBwcmV2aW91c1NlbGVjdGlvbklkcyA9IHRoaXMuX3NlbGVjdGlvbklkcyQuZ2V0VmFsdWUoKVxuICAgIGNvbnN0IHByZXZpb3VzbHlTZWxlY3RlZEFuZERpc2FibGVkID0gcHJldmlvdXNTZWxlY3Rpb25JZHMuZmlsdGVyKChpZCkgPT4gZGlzYWJsZWRSb3dJZHMuaW5jbHVkZXMoaWQpKVxuICAgIGNvbnN0IGRpc2FibGVkQW5kUHJldmlvdXNseURlc2VsZWN0ZWQgPSBkaXNhYmxlZFJvd0lkcy5maWx0ZXIoKGlkKSA9PiAhcHJldmlvdXNTZWxlY3Rpb25JZHMuaW5jbHVkZXMoaWQpKVxuICAgIGNvbnN0IHVwZGF0ZWRTZWxlY3Rpb24gPSBbLi4ubmV3U2VsZWN0aW9uSWRzXVxuXG4gICAgcHJldmlvdXNseVNlbGVjdGVkQW5kRGlzYWJsZWQuZm9yRWFjaCgoaWQpID0+IHtcbiAgICAgIGlmICghdXBkYXRlZFNlbGVjdGlvbi5pbmNsdWRlcyhpZCkpIHtcbiAgICAgICAgdXBkYXRlZFNlbGVjdGlvbi5wdXNoKGlkKVxuICAgICAgfVxuICAgIH0pXG5cbiAgICBkaXNhYmxlZEFuZFByZXZpb3VzbHlEZXNlbGVjdGVkLmZvckVhY2goKGlkKSA9PiB7XG4gICAgICBjb25zdCBpbmRleCA9IHVwZGF0ZWRTZWxlY3Rpb24uaW5kZXhPZihpZClcbiAgICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICAgIHVwZGF0ZWRTZWxlY3Rpb24uc3BsaWNlKGluZGV4LCAxKVxuICAgICAgfVxuICAgIH0pXG5cbiAgICByZXR1cm4gdXBkYXRlZFNlbGVjdGlvblxuICB9XG5cbiAgaXNTZWxlY3RlZChyb3c6IFJvdykge1xuICAgIHJldHVybiB0aGlzLl9zZWxlY3Rpb25JZHMkLmdldFZhbHVlKCkuaW5jbHVkZXMocm93LmlkKVxuICB9XG5cbiAgb25QYWdlQ2hhbmdlKGV2ZW50OiBhbnkpIHtcbiAgICBjb25zdCBwYWdlID0gZXZlbnQuZmlyc3QgLyBldmVudC5yb3dzXG4gICAgdGhpcy5wYWdlID0gcGFnZVxuICAgIHRoaXMucGFnZVNpemUgPSBldmVudC5yb3dzXG4gICAgdGhpcy5wYWdlQ2hhbmdlZC5lbWl0KHBhZ2UpXG4gICAgdGhpcy5wYWdlU2l6ZUNoYW5nZWQuZW1pdChldmVudC5yb3dzKVxuICAgIHRoaXMuZW1pdENvbXBvbmVudFN0YXRlQ2hhbmdlZCh7XG4gICAgICBhY3RpdmVQYWdlOiBwYWdlLFxuICAgICAgcGFnZVNpemU6IGV2ZW50LnJvd3MsXG4gICAgfSlcbiAgfVxuXG4gIHJlc2V0UGFnZSgpIHtcbiAgICB0aGlzLnBhZ2UgPSAwXG4gICAgdGhpcy5wYWdlQ2hhbmdlZC5lbWl0KHRoaXMucGFnZSlcbiAgICB0aGlzLmVtaXRDb21wb25lbnRTdGF0ZUNoYW5nZWQoKVxuICB9XG5cbiAgZmllbGRJc1RydXRoeShvYmplY3Q6IGFueSwga2V5OiBhbnkpIHtcbiAgICByZXR1cm4gISFPYmplY3RVdGlscy5yZXNvbHZlRmllbGREYXRhKG9iamVjdCwga2V5KVxuICB9XG5cbiAgdG9nZ2xlT3ZlcmZsb3dNZW51KGV2ZW50OiBNb3VzZUV2ZW50LCBtZW51OiBNZW51LCByb3c6IFJvdykge1xuICAgIHRoaXMuY3VycmVudE1lbnVSb3ckLm5leHQocm93KVxuICAgIG1lbnUudG9nZ2xlKGV2ZW50KVxuICB9XG5cbiAgaGFzVmlzaWJsZU92ZXJmbG93TWVudUl0ZW1zKHJvdzogYW55KSB7XG4gICAgcmV0dXJuIHRoaXMub3ZlcmZsb3dBY3Rpb25zJC5waXBlKFxuICAgICAgbWFwKChhY3Rpb25zKSA9PlxuICAgICAgICBhY3Rpb25zLnNvbWUoXG4gICAgICAgICAgKGEpID0+XG4gICAgICAgICAgICAhYS5hY3Rpb25WaXNpYmxlRmllbGQgfHxcbiAgICAgICAgICAgICh0aGlzLmZpZWxkSXNUcnV0aHkocm93LCBhLmFjdGlvblZpc2libGVGaWVsZCkgJiYgdGhpcy51c2VyU2VydmljZS5oYXNQZXJtaXNzaW9uKGEucGVybWlzc2lvbikpXG4gICAgICAgIClcbiAgICAgIClcbiAgICApXG4gIH1cblxuICBpc0RhdGUodmFsdWU6IERhdGUgfCBzdHJpbmcgfCBudW1iZXIpIHtcbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cbiAgICBjb25zdCBkID0gbmV3IERhdGUodmFsdWUpXG4gICAgcmV0dXJuIGlzVmFsaWREYXRlKGQpXG4gIH1cblxuICBjZWxsVGVtcGxhdGVzRGF0YTogVGVtcGxhdGVzRGF0YSA9IHtcbiAgICB0ZW1wbGF0ZXNPYnNlcnZhYmxlczoge30sXG4gICAgaWRTdWZmaXg6IFsnSWRUYWJsZUNlbGwnLCAnSWRDZWxsJ10sXG4gICAgdGVtcGxhdGVOYW1lczoge1xuICAgICAgW0NvbHVtblR5cGUuREFURV06IFsnZGF0ZUNlbGwnLCAnZGF0ZVRhYmxlQ2VsbCcsICdkZWZhdWx0RGF0ZUNlbGwnXSxcbiAgICAgIFtDb2x1bW5UeXBlLk5VTUJFUl06IFsnbnVtYmVyQ2VsbCcsICdudW1iZXJUYWJsZUNlbGwnLCAnZGVmYXVsdE51bWJlckNlbGwnXSxcbiAgICAgIFtDb2x1bW5UeXBlLlJFTEFUSVZFX0RBVEVdOiBbJ3JlbGF0aXZlRGF0ZUNlbGwnLCAncmVsYXRpdmVEYXRlVGFibGVDZWxsJywgJ2RlZmF1bHRSZWxhdGl2ZURhdGVDZWxsJ10sXG4gICAgICBbQ29sdW1uVHlwZS5UUkFOU0xBVElPTl9LRVldOiBbJ3RyYW5zbGF0aW9uS2V5Q2VsbCcsICd0cmFuc2xhdGlvbktleVRhYmxlQ2VsbCcsICdkZWZhdWx0VHJhbnNsYXRpb25LZXlDZWxsJ10sXG4gICAgICBbQ29sdW1uVHlwZS5DVVNUT01dOiBbJ2N1c3RvbUNlbGwnLCAnY3VzdG9tVGFibGVDZWxsJywgJ2RlZmF1bHRDdXN0b21DZWxsJ10sXG4gICAgICBbQ29sdW1uVHlwZS5TVFJJTkddOiBbJ3N0cmluZ0NlbGwnLCAnc3RyaW5nVGFibGVDZWxsJywgJ2RlZmF1bHRTdHJpbmdDZWxsJ10sXG4gICAgfSxcbiAgfVxuXG4gIGZpbHRlclRlbXBsYXRlc0RhdGE6IFRlbXBsYXRlc0RhdGEgPSB7XG4gICAgdGVtcGxhdGVzT2JzZXJ2YWJsZXM6IHt9LFxuICAgIGlkU3VmZml4OiBbJ0lkVGFibGVGaWx0ZXJDZWxsJywgJ0lkRmlsdGVyQ2VsbCcsICdJZFRhYmxlQ2VsbCcsICdJZENlbGwnXSxcbiAgICB0ZW1wbGF0ZU5hbWVzOiB7XG4gICAgICBbQ29sdW1uVHlwZS5EQVRFXTogWydkYXRlRmlsdGVyQ2VsbCcsICdkYXRlVGFibGVGaWx0ZXJDZWxsJywgJ2RhdGVDZWxsJywgJ2RhdGVUYWJsZUNlbGwnLCAnZGVmYXVsdERhdGVDZWxsJ10sXG4gICAgICBbQ29sdW1uVHlwZS5OVU1CRVJdOiBbXG4gICAgICAgICdudW1iZXJGaWx0ZXJDZWxsJyxcbiAgICAgICAgJ251bWJlclRhYmxlRmlsdGVyQ2VsbCcsXG4gICAgICAgICdudW1iZXJDZWxsJyxcbiAgICAgICAgJ251bWJlclRhYmxlQ2VsbCcsXG4gICAgICAgICdkZWZhdWx0TnVtYmVyQ2VsbCcsXG4gICAgICBdLFxuICAgICAgW0NvbHVtblR5cGUuUkVMQVRJVkVfREFURV06IFtcbiAgICAgICAgJ3JlbGF0aXZlRGF0ZUZpbHRlckNlbGwnLFxuICAgICAgICAncmVsYXRpdmVEYXRlVGFibGVGaWx0ZXJDZWxsJyxcbiAgICAgICAgJ3JlbGF0aXZlRGF0ZUNlbGwnLFxuICAgICAgICAncmVsYXRpdmVEYXRlVGFibGVDZWxsJyxcbiAgICAgICAgJ2RlZmF1bHRSZWxhdGl2ZURhdGVDZWxsJyxcbiAgICAgIF0sXG4gICAgICBbQ29sdW1uVHlwZS5UUkFOU0xBVElPTl9LRVldOiBbXG4gICAgICAgICd0cmFuc2xhdGlvbktleUZpbHRlckNlbGwnLFxuICAgICAgICAndHJhbnNsYXRpb25LZXlUYWJsZUZpbHRlckNlbGwnLFxuICAgICAgICAnZGVmYXVsdFRyYW5zbGF0aW9uS2V5Q2VsbCcsXG4gICAgICAgICd0cmFuc2xhdGlvbktleUNlbGwnLFxuICAgICAgICAndHJhbnNsYXRpb25LZXlUYWJsZUNlbGwnLFxuICAgICAgXSxcbiAgICAgIFtDb2x1bW5UeXBlLkNVU1RPTV06IFtcbiAgICAgICAgJ2N1c3RvbUZpbHRlckNlbGwnLFxuICAgICAgICAnY3VzdG9tVGFibGVGaWx0ZXJDZWxsJyxcbiAgICAgICAgJ2N1c3RvbUNlbGwnLFxuICAgICAgICAnY3VzdG9tVGFibGVDZWxsJyxcbiAgICAgICAgJ2RlZmF1bHRDdXN0b21DZWxsJyxcbiAgICAgIF0sXG4gICAgICBbQ29sdW1uVHlwZS5TVFJJTkddOiBbXG4gICAgICAgICdzdHJpbmdGaWx0ZXJDZWxsJyxcbiAgICAgICAgJ3N0cmluZ1RhYmxlRmlsdGVyQ2VsbCcsXG4gICAgICAgICdzdHJpbmdDZWxsJyxcbiAgICAgICAgJ3N0cmluZ1RhYmxlQ2VsbCcsXG4gICAgICAgICdkZWZhdWx0U3RyaW5nQ2VsbCcsXG4gICAgICBdLFxuICAgIH0sXG4gIH1cblxuICB0ZW1wbGF0ZXNEYXRhTWFwOiBSZWNvcmQ8VGVtcGxhdGVUeXBlLCBUZW1wbGF0ZXNEYXRhPiA9IHtcbiAgICBbVGVtcGxhdGVUeXBlLkNFTExdOiB0aGlzLmNlbGxUZW1wbGF0ZXNEYXRhLFxuICAgIFtUZW1wbGF0ZVR5cGUuRklMVEVSQ0VMTF06IHRoaXMuZmlsdGVyVGVtcGxhdGVzRGF0YSxcbiAgfVxuXG4gIGdldENvbHVtblR5cGVUZW1wbGF0ZSh0ZW1wbGF0ZXM6IFByaW1lVGVtcGxhdGVbXSwgY29sdW1uVHlwZTogQ29sdW1uVHlwZSwgdGVtcGxhdGVUeXBlOiBUZW1wbGF0ZVR5cGUpIHtcbiAgICBsZXQgdGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT4gfCB1bmRlZmluZWRcblxuICAgIHN3aXRjaCAodGVtcGxhdGVUeXBlKSB7XG4gICAgICBjYXNlIFRlbXBsYXRlVHlwZS5DRUxMOlxuICAgICAgICBzd2l0Y2ggKGNvbHVtblR5cGUpIHtcbiAgICAgICAgICBjYXNlIENvbHVtblR5cGUuREFURTpcbiAgICAgICAgICAgIHRlbXBsYXRlID0gdGhpcy5fZGF0ZUNlbGxcbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgY2FzZSBDb2x1bW5UeXBlLk5VTUJFUjpcbiAgICAgICAgICAgIHRlbXBsYXRlID0gdGhpcy5fbnVtYmVyQ2VsbFxuICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICBjYXNlIENvbHVtblR5cGUuUkVMQVRJVkVfREFURTpcbiAgICAgICAgICAgIHRlbXBsYXRlID0gdGhpcy5fcmVsYXRpdmVEYXRlQ2VsbFxuICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICBjYXNlIENvbHVtblR5cGUuVFJBTlNMQVRJT05fS0VZOlxuICAgICAgICAgICAgdGVtcGxhdGUgPSB0aGlzLl90cmFuc2xhdGlvbktleUNlbGxcbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgY2FzZSBDb2x1bW5UeXBlLkNVU1RPTTpcbiAgICAgICAgICAgIHRlbXBsYXRlID0gdGhpcy5fY3VzdG9tQ2VsbFxuICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgdGVtcGxhdGUgPSB0aGlzLl9zdHJpbmdDZWxsXG4gICAgICAgIH1cbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgVGVtcGxhdGVUeXBlLkZJTFRFUkNFTEw6XG4gICAgICAgIHN3aXRjaCAoY29sdW1uVHlwZSkge1xuICAgICAgICAgIGNhc2UgQ29sdW1uVHlwZS5EQVRFOlxuICAgICAgICAgICAgdGVtcGxhdGUgPSB0aGlzLl9kYXRlRmlsdGVyQ2VsbFxuICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICBjYXNlIENvbHVtblR5cGUuTlVNQkVSOlxuICAgICAgICAgICAgdGVtcGxhdGUgPSB0aGlzLl9udW1iZXJGaWx0ZXJDZWxsXG4gICAgICAgICAgICBicmVha1xuICAgICAgICAgIGNhc2UgQ29sdW1uVHlwZS5SRUxBVElWRV9EQVRFOlxuICAgICAgICAgICAgdGVtcGxhdGUgPSB0aGlzLl9yZWxhdGl2ZURhdGVGaWx0ZXJDZWxsXG4gICAgICAgICAgICBicmVha1xuICAgICAgICAgIGNhc2UgQ29sdW1uVHlwZS5UUkFOU0xBVElPTl9LRVk6XG4gICAgICAgICAgICB0ZW1wbGF0ZSA9IHRoaXMuX3RyYW5zbGF0aW9uS2V5RmlsdGVyQ2VsbFxuICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICBjYXNlIENvbHVtblR5cGUuQ1VTVE9NOlxuICAgICAgICAgICAgdGVtcGxhdGUgPSB0aGlzLl9jdXN0b21GaWx0ZXJDZWxsXG4gICAgICAgICAgICBicmVha1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICB0ZW1wbGF0ZSA9IHRoaXMuX3N0cmluZ0ZpbHRlckNlbGxcbiAgICAgICAgfVxuICAgICAgICBicmVha1xuICAgIH1cblxuICAgIHJldHVybiAoXG4gICAgICB0ZW1wbGF0ZSA/P1xuICAgICAgZmluZFRlbXBsYXRlKHRlbXBsYXRlcywgdGhpcy50ZW1wbGF0ZXNEYXRhTWFwW3RlbXBsYXRlVHlwZV0udGVtcGxhdGVOYW1lc1tjb2x1bW5UeXBlXSk/LnRlbXBsYXRlID8/XG4gICAgICBudWxsXG4gICAgKVxuICB9XG5cbiAgZ2V0VGVtcGxhdGUoY29sdW1uOiBEYXRhVGFibGVDb2x1bW4sIHRlbXBsYXRlVHlwZTogVGVtcGxhdGVUeXBlKTogT2JzZXJ2YWJsZTxUZW1wbGF0ZVJlZjxhbnk+IHwgbnVsbD4ge1xuICAgIGNvbnN0IHRlbXBsYXRlc0RhdGEgPSB0aGlzLnRlbXBsYXRlc0RhdGFNYXBbdGVtcGxhdGVUeXBlXVxuXG4gICAgaWYgKCF0ZW1wbGF0ZXNEYXRhLnRlbXBsYXRlc09ic2VydmFibGVzW2NvbHVtbi5pZF0pIHtcbiAgICAgIHRlbXBsYXRlc0RhdGEudGVtcGxhdGVzT2JzZXJ2YWJsZXNbY29sdW1uLmlkXSA9IGNvbWJpbmVMYXRlc3QoW1xuICAgICAgICB0aGlzLnRlbXBsYXRlcyQsXG4gICAgICAgIHRoaXMudmlld1RlbXBsYXRlcyQsXG4gICAgICAgIHRoaXMucGFyZW50VGVtcGxhdGVzJCxcbiAgICAgIF0pLnBpcGUoXG4gICAgICAgIG1hcCgoW3QsIHZ0LCBwdF0pID0+IHtcbiAgICAgICAgICBjb25zdCB0ZW1wbGF0ZXMgPSBbLi4uKHQgPz8gW10pLCAuLi4odnQgPz8gW10pLCAuLi4ocHQgPz8gW10pXVxuICAgICAgICAgIGNvbnN0IGNvbHVtblRlbXBsYXRlID0gZmluZFRlbXBsYXRlKFxuICAgICAgICAgICAgdGVtcGxhdGVzLFxuICAgICAgICAgICAgdGVtcGxhdGVzRGF0YS5pZFN1ZmZpeC5tYXAoKHN1ZmZpeCkgPT4gY29sdW1uLmlkICsgc3VmZml4KVxuICAgICAgICAgICk/LnRlbXBsYXRlXG4gICAgICAgICAgaWYgKGNvbHVtblRlbXBsYXRlKSB7XG4gICAgICAgICAgICByZXR1cm4gY29sdW1uVGVtcGxhdGVcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0Q29sdW1uVHlwZVRlbXBsYXRlKHRlbXBsYXRlcywgY29sdW1uLmNvbHVtblR5cGUsIHRlbXBsYXRlVHlwZSlcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICB9XG4gICAgcmV0dXJuIHRlbXBsYXRlc0RhdGEudGVtcGxhdGVzT2JzZXJ2YWJsZXNbY29sdW1uLmlkXVxuICB9XG5cbiAgcmVzb2x2ZUZpZWxkRGF0YShvYmplY3Q6IGFueSwga2V5OiBhbnkpIHtcbiAgICByZXR1cm4gT2JqZWN0VXRpbHMucmVzb2x2ZUZpZWxkRGF0YShvYmplY3QsIGtleSlcbiAgfVxuXG4gIGdldFJvd09iamVjdEZyb21NdWx0aXNlbGVjdEl0ZW0odmFsdWU6IE11bHRpU2VsZWN0SXRlbSwgY29sdW1uOiBEYXRhVGFibGVDb2x1bW4pIHtcbiAgICByZXR1cm4ge1xuICAgICAgW2NvbHVtbi5pZF06IHZhbHVlLmxhYmVsLFxuICAgIH1cbiAgfVxufVxuIiwiPG5nLXRlbXBsYXRlICNhY3Rpb25Db2x1bW4gbGV0LXJvd09iamVjdD1cImxvY2FsUm93T2JqZWN0XCI+XG4gIDxuZy1jb250YWluZXJcbiAgICAqbmdJZj1cImFueVJvd0FjdGlvbk9ic2VydmVkIHx8IHRoaXMuYWRkaXRpb25hbEFjdGlvbnMubGVuZ3RoID4gMCB8fCAoKHRoaXMub3ZlcmZsb3dBY3Rpb25zJCB8IGFzeW5jKSA/PyBbXSkubGVuZ3RoID4gMFwiXG4gID5cbiAgICA8dGRcbiAgICAgIGNsYXNzPVwiYWN0aW9uc1wiXG4gICAgICBwRnJvemVuQ29sdW1uXG4gICAgICBbZnJvemVuXT1cImZyb3plbkFjdGlvbkNvbHVtblwiXG4gICAgICBbYWxpZ25Gcm96ZW5dPVwiYWN0aW9uQ29sdW1uUG9zaXRpb25cIlxuICAgICAgW2F0dHIubmFtZV09XCJhY3Rpb25Db2x1bW5Qb3NpdGlvbiA9PT0gJ2xlZnQnID8gJ2FjdGlvbi1jb2x1bW4tbGVmdCcgOiAnYWN0aW9uLWNvbHVtbi1yaWdodCdcIlxuICAgICAgW25nQ2xhc3NdPVwiKGZyb3plbkFjdGlvbkNvbHVtbiAmJiBhY3Rpb25Db2x1bW5Qb3NpdGlvbiA9PT0gJ2xlZnQnKSA/ICdib3JkZXItcmlnaHQtMScgOiAoZnJvemVuQWN0aW9uQ29sdW1uICYmIGFjdGlvbkNvbHVtblBvc2l0aW9uID09PSAncmlnaHQnKSA/ICdib3JkZXItbGVmdC0xJyA6ICcnXCJcbiAgICA+XG4gICAgICA8ZGl2IGNsYXNzPVwiaWNvbi1idXR0b24tcm93LXdyYXBwZXJcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICpuZ0lmPVwidmlld1RhYmxlUm93T2JzZXJ2ZWQgJiYgKCF2aWV3QWN0aW9uVmlzaWJsZUZpZWxkIHx8IGZpZWxkSXNUcnV0aHkocm93T2JqZWN0LCB2aWV3QWN0aW9uVmlzaWJsZUZpZWxkKSlcIlxuICAgICAgICA+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgaWQ9XCJ7e3Jlc29sdmVGaWVsZERhdGEocm93T2JqZWN0LCAnaWQnKX19LXZpZXdCdXR0b25cIlxuICAgICAgICAgICAgKm9jeElmUGVybWlzc2lvbj1cInZpZXdQZXJtaXNzaW9uXCJcbiAgICAgICAgICAgIFtkaXNhYmxlZF09XCIhIXZpZXdBY3Rpb25FbmFibGVkRmllbGQgJiYgIWZpZWxkSXNUcnV0aHkocm93T2JqZWN0LCB2aWV3QWN0aW9uRW5hYmxlZEZpZWxkKVwiXG4gICAgICAgICAgICBwQnV0dG9uXG4gICAgICAgICAgICBjbGFzcz1cInAtYnV0dG9uLXJvdW5kZWQgcC1idXR0b24tdGV4dCB2aWV3VGFibGVSb3dCdXR0b25cIlxuICAgICAgICAgICAgdGl0bGU9XCJ7eyAnT0NYX0RBVEFfVEFCTEUuQUNUSU9OUy5WSUVXJyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIidPQ1hfREFUQV9UQUJMRS5BQ1RJT05TLlZJRVcnIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgIGljb249XCJwaSBwaS1leWVcIlxuICAgICAgICAgICAgKGNsaWNrKT1cIm9uVmlld1Jvdyhyb3dPYmplY3QpXCJcbiAgICAgICAgICAgIFthdHRyLm5hbWVdPVwiJ2RhdGEtdGFibGUtYWN0aW9uLWJ1dHRvbidcIlxuICAgICAgICAgID48L2J1dHRvbj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAqbmdJZj1cImVkaXRUYWJsZVJvd09ic2VydmVkICYmICghZWRpdEFjdGlvblZpc2libGVGaWVsZCB8fCBmaWVsZElzVHJ1dGh5KHJvd09iamVjdCwgZWRpdEFjdGlvblZpc2libGVGaWVsZCkpXCJcbiAgICAgICAgPlxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIGlkPVwie3tyZXNvbHZlRmllbGREYXRhKHJvd09iamVjdCwgJ2lkJyl9fS1lZGl0QnV0dG9uXCJcbiAgICAgICAgICAgICpvY3hJZlBlcm1pc3Npb249XCJlZGl0UGVybWlzc2lvblwiXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwiISFlZGl0QWN0aW9uRW5hYmxlZEZpZWxkICYmICFmaWVsZElzVHJ1dGh5KHJvd09iamVjdCwgZWRpdEFjdGlvbkVuYWJsZWRGaWVsZClcIlxuICAgICAgICAgICAgcEJ1dHRvblxuICAgICAgICAgICAgY2xhc3M9XCJwLWJ1dHRvbi1yb3VuZGVkIHAtYnV0dG9uLXRleHQgZWRpdFRhYmxlUm93QnV0dG9uXCJcbiAgICAgICAgICAgIHRpdGxlPVwie3sgJ09DWF9EQVRBX1RBQkxFLkFDVElPTlMuRURJVCcgfCB0cmFuc2xhdGUgfX1cIlxuICAgICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCInT0NYX0RBVEFfVEFCTEUuQUNUSU9OUy5FRElUJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICBpY29uPVwicGkgcGktcGVuY2lsXCJcbiAgICAgICAgICAgIChjbGljayk9XCJvbkVkaXRSb3cocm93T2JqZWN0KVwiXG4gICAgICAgICAgICBbYXR0ci5uYW1lXT1cIidkYXRhLXRhYmxlLWFjdGlvbi1idXR0b24nXCJcbiAgICAgICAgICA+PC9idXR0b24+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgKm5nSWY9XCJkZWxldGVUYWJsZVJvd09ic2VydmVkICYmICghZGVsZXRlQWN0aW9uVmlzaWJsZUZpZWxkIHx8IGZpZWxkSXNUcnV0aHkocm93T2JqZWN0LCBkZWxldGVBY3Rpb25WaXNpYmxlRmllbGQpKVwiXG4gICAgICAgID5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICBpZD1cInt7cmVzb2x2ZUZpZWxkRGF0YShyb3dPYmplY3QsICdpZCcpfX0tZGVsZXRlQnV0dG9uXCJcbiAgICAgICAgICAgICpvY3hJZlBlcm1pc3Npb249XCJkZWxldGVQZXJtaXNzaW9uXCJcbiAgICAgICAgICAgIFtkaXNhYmxlZF09XCIhIWRlbGV0ZUFjdGlvbkVuYWJsZWRGaWVsZCAmJiAhZmllbGRJc1RydXRoeShyb3dPYmplY3QsIGRlbGV0ZUFjdGlvbkVuYWJsZWRGaWVsZClcIlxuICAgICAgICAgICAgcEJ1dHRvblxuICAgICAgICAgICAgY2xhc3M9XCJwLWJ1dHRvbi1yb3VuZGVkIHAtYnV0dG9uLXRleHQgcC1idXR0b24tZGFuZ2VyIGRlbGV0ZVRhYmxlUm93QnV0dG9uXCJcbiAgICAgICAgICAgIHRpdGxlPVwie3sgJ09DWF9EQVRBX1RBQkxFLkFDVElPTlMuREVMRVRFJyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIidPQ1hfREFUQV9UQUJMRS5BQ1RJT05TLkRFTEVURScgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgaWNvbj1cInBpIHBpLXRyYXNoXCJcbiAgICAgICAgICAgIChjbGljayk9XCJvbkRlbGV0ZVJvdyhyb3dPYmplY3QpXCJcbiAgICAgICAgICAgIFthdHRyLm5hbWVdPVwiJ2RhdGEtdGFibGUtYWN0aW9uLWJ1dHRvbidcIlxuICAgICAgICAgID48L2J1dHRvbj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGFjdGlvbiBvZiBpbmxpbmVBY3Rpb25zJCB8IGFzeW5jXCI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIighYWN0aW9uLmFjdGlvblZpc2libGVGaWVsZCB8fCBmaWVsZElzVHJ1dGh5KHJvd09iamVjdCwgYWN0aW9uLmFjdGlvblZpc2libGVGaWVsZCkpXCI+XG4gICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgIGlkPVwie3tyZXNvbHZlRmllbGREYXRhKHJvd09iamVjdCwgJ2lkJyl9fS17e2FjdGlvbi5pZCA/IGFjdGlvbi5pZC5jb25jYXQoJ0FjdGlvbkJ1dHRvbicpIDogJ2lubGluZUFjdGlvbkJ1dHRvbid9fVwiXG4gICAgICAgICAgICAgICpvY3hJZlBlcm1pc3Npb249XCJhY3Rpb24ucGVybWlzc2lvblwiXG4gICAgICAgICAgICAgIHBCdXR0b25cbiAgICAgICAgICAgICAgY2xhc3M9XCJwLWJ1dHRvbi1yb3VuZGVkIHAtYnV0dG9uLXRleHRcIlxuICAgICAgICAgICAgICBbbmdDbGFzc109XCJhY3Rpb24uY2xhc3Nlc1wiXG4gICAgICAgICAgICAgIFtpY29uXT1cImFjdGlvbi5pY29uIHx8ICcnXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cImFjdGlvbi5jYWxsYmFjayhyb3dPYmplY3QpXCJcbiAgICAgICAgICAgICAgW3RpdGxlXT1cImFjdGlvbi5sYWJlbEtleSA/IChhY3Rpb24ubGFiZWxLZXkgfCB0cmFuc2xhdGUpIDogJydcIlxuICAgICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cImFjdGlvbi5sYWJlbEtleSA/IChhY3Rpb24ubGFiZWxLZXkgfCB0cmFuc2xhdGUpIDogJydcIlxuICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiYWN0aW9uLmRpc2FibGVkIHx8ICghIWFjdGlvbi5hY3Rpb25FbmFibGVkRmllbGQgJiYgIWZpZWxkSXNUcnV0aHkocm93T2JqZWN0LCBhY3Rpb24uYWN0aW9uRW5hYmxlZEZpZWxkKSlcIlxuICAgICAgICAgICAgICBbYXR0ci5uYW1lXT1cIidkYXRhLXRhYmxlLWFjdGlvbi1idXR0b24nXCJcbiAgICAgICAgICAgID48L2J1dHRvbj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJoYXNWaXNpYmxlT3ZlcmZsb3dNZW51SXRlbXMocm93T2JqZWN0KSB8IGFzeW5jXCI+XG4gICAgICAgICAgPHAtbWVudSAjbWVudSBbbW9kZWxdPVwiKG92ZXJmbG93TWVudUl0ZW1zJCB8IGFzeW5jKSB8fCBbXVwiIFtwb3B1cF09XCJ0cnVlXCIgYXBwZW5kVG89XCJib2R5XCI+PC9wLW1lbnU+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgcEJ1dHRvblxuICAgICAgICAgICAgY2xhc3M9XCJwLWJ1dHRvbi1yb3VuZGVkIHAtYnV0dG9uLXRleHRcIlxuICAgICAgICAgICAgW2ljb25dPVwiJ3BpIHBpLWVsbGlwc2lzLXYnXCJcbiAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVPdmVyZmxvd01lbnUoJGV2ZW50LCBtZW51LCByb3dPYmplY3QpXCJcbiAgICAgICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiJ09DWF9EQVRBX1RBQkxFLk1PUkVfQUNUSU9OUycgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgW3RpdGxlXT1cIidPQ1hfREFUQV9UQUJMRS5NT1JFX0FDVElPTlMnIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICA+PC9idXR0b24+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPC9kaXY+XG4gICAgPC90ZD5cbiAgPC9uZy1jb250YWluZXI+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI2FjdGlvbkNvbHVtbkhlYWRlcj5cbiAgPG5nLWNvbnRhaW5lclxuICAgICpuZ0lmPVwiYW55Um93QWN0aW9uT2JzZXJ2ZWQgfHwgdGhpcy5hZGRpdGlvbmFsQWN0aW9ucy5sZW5ndGggPiAwICB8fCAoKHRoaXMub3ZlcmZsb3dBY3Rpb25zJCB8IGFzeW5jKSA/PyBbXSkubGVuZ3RoID4gMFwiXG4gID5cbiAgICA8dGhcbiAgICAgIHBGcm96ZW5Db2x1bW5cbiAgICAgIFtmcm96ZW5dPVwiZnJvemVuQWN0aW9uQ29sdW1uXCJcbiAgICAgIFthbGlnbkZyb3plbl09XCJhY3Rpb25Db2x1bW5Qb3NpdGlvblwiXG4gICAgICBbbmdDbGFzc109XCIoZnJvemVuQWN0aW9uQ29sdW1uICYmIGFjdGlvbkNvbHVtblBvc2l0aW9uID09PSAnbGVmdCcpID8gJ2JvcmRlci1yaWdodC0xJyA6IChmcm96ZW5BY3Rpb25Db2x1bW4gJiYgYWN0aW9uQ29sdW1uUG9zaXRpb24gPT09ICdyaWdodCcpID8gJ2JvcmRlci1sZWZ0LTEnIDogJydcIlxuICAgICAgW2F0dHIubmFtZV09XCJhY3Rpb25Db2x1bW5Qb3NpdGlvbiA9PT0gJ2xlZnQnID8gJ2FjdGlvbi1jb2x1bW4taGVhZGVyLWxlZnQnIDogJ2FjdGlvbi1jb2x1bW4taGVhZGVyLXJpZ2h0J1wiXG4gICAgPlxuICAgICAge3sgJ09DWF9EQVRBX1RBQkxFLkFDVElPTlNfQ09MVU1OX05BTUUnIHwgdHJhbnNsYXRlIH19XG4gICAgPC90aD5cbiAgPC9uZy1jb250YWluZXI+XG48L25nLXRlbXBsYXRlPlxuXG48bmctY29udGFpbmVyICpuZ0lmPVwiKGRpc3BsYXllZFBhZ2VTaXplJCB8IGFzeW5jKSBhcyBkaXNwbGF5ZWRQYWdlU2l6ZVwiPlxuICA8cC10YWJsZVxuICAgICpuZ0lmPVwiKGNvbHVtblRlbXBsYXRlcyQgfCBhc3luYykgPz8ge30gYXMgY29sdW1uVGVtcGxhdGVzXCJcbiAgICBbdmFsdWVdPVwiKGRpc3BsYXllZFJvd3MkIHwgYXN5bmMpID8/IFtdXCJcbiAgICByZXNwb25zaXZlTGF5b3V0PVwic2Nyb2xsXCJcbiAgICBbcGFnaW5hdG9yXT1cInBhZ2luYXRvclwiXG4gICAgW2ZpcnN0XT1cInBhZ2UgKiBkaXNwbGF5ZWRQYWdlU2l6ZVwiXG4gICAgKG9uUGFnZSk9XCJvblBhZ2VDaGFuZ2UoJGV2ZW50KVwiXG4gICAgW3Jvd3NdPVwiZGlzcGxheWVkUGFnZVNpemVcIlxuICAgIFtzaG93Q3VycmVudFBhZ2VSZXBvcnRdPVwidHJ1ZVwiXG4gICAgY3VycmVudFBhZ2VSZXBvcnRUZW1wbGF0ZT1cInt7ICh0b3RhbFJlY29yZHNPblNlcnZlciA/IGN1cnJlbnRQYWdlU2hvd2luZ1dpdGhUb3RhbE9uU2VydmVyS2V5IDogY3VycmVudFBhZ2VTaG93aW5nS2V5KSB8IHRyYW5zbGF0ZTpwYXJhbXMgfX1cIlxuICAgIFtyb3dzUGVyUGFnZU9wdGlvbnNdPVwiKGRpc3BsYXllZFBhZ2VTaXplcyQgfCBhc3luYykgPz8gW11cIlxuICAgIGlkPVwiZGF0YVRhYmxlX3t7bmFtZX19XCJcbiAgICAoc2VsZWN0aW9uQ2hhbmdlKT1cIm9uU2VsZWN0aW9uQ2hhbmdlKCRldmVudClcIlxuICAgIFtzZWxlY3Rpb25dPVwiKHNlbGVjdGVkUm93cyQgfCBhc3luYykgPz8gW11cIlxuICAgIFtzY3JvbGxhYmxlXT1cInRydWVcIlxuICAgIHNjcm9sbEhlaWdodD1cImZsZXhcIlxuICAgIFtzdHlsZV09XCJ0YWJsZVN0eWxlXCJcbiAgICBwYWdpbmF0b3JEcm9wZG93bkFwcGVuZFRvPVwiYm9keVwiXG4gICAgW3Jvd1NlbGVjdGFibGVdPVwicm93U2VsZWN0YWJsZVwiXG4gICAgdGFibGVTdHlsZUNsYXNzPVwiaC1mdWxsXCJcbiAgPlxuICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJoZWFkZXJcIj5cbiAgICAgIDx0ciBzdHlsZT1cInZlcnRpY2FsLWFsaWduOiB0b3BcIj5cbiAgICAgICAgPHRoIHN0eWxlPVwid2lkdGg6IDRyZW1cIiBzY29wZT1cImNvbFwiICpuZ0lmPVwic2VsZWN0aW9uQ2hhbmdlZE9ic2VydmVkXCI+XG4gICAgICAgICAgPHAtdGFibGVIZWFkZXJDaGVja2JveFxuICAgICAgICAgICAgKm5nSWY9XCJhbGxvd1NlbGVjdEFsbFwiXG4gICAgICAgICAgICBwVG9vbHRpcD1cInt7J09DWF9EQVRBX1RBQkxFLlNFTEVDVF9BTExfVE9PTFRJUCcgfCB0cmFuc2xhdGV9fVwiXG4gICAgICAgICAgICBhcmlhTGFiZWw9XCJ7eydPQ1hfREFUQV9UQUJMRS5TRUxFQ1RfQUxMX0FSSUFfTEFCRUwnIHwgdHJhbnNsYXRlfX1cIlxuICAgICAgICAgID48L3AtdGFibGVIZWFkZXJDaGVja2JveD5cbiAgICAgICAgPC90aD5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImFjdGlvbkNvbHVtblBvc2l0aW9uID09PSAnbGVmdCc7XCI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImFjdGlvbkNvbHVtbkhlYWRlclwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIGNvbHVtbnNcIj5cbiAgICAgICAgICA8dGggKm5nSWY9XCJjb2x1bW4uc29ydGFibGUgfHwgY29sdW1uLmZpbHRlcmFibGU7IGVsc2Ugc2ltcGxlSGVhZGVyXCIgc2NvcGU9XCJjb2xcIj5cbiAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgY2xhc3M9XCJ0YWJsZS1oZWFkZXItd3JhcHBlciBmbGV4IGZsZXgtY29sdW1uIGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLXN0YXJ0XCJcbiAgICAgICAgICAgICAgc3R5bGU9XCJoZWlnaHQ6IDEwMCVcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImZsZXhcIiBpZD1cInt7Y29sdW1uLmlkfX0taGVhZGVyLW5hbWVcIj57eyBjb2x1bW4ubmFtZUtleSB8IHRyYW5zbGF0ZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJmbGV4IGljb24tYnV0dG9uLWhlYWRlci13cmFwcGVyXCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb2x1bW4uc29ydGFibGVcIlxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJwaSBzb3J0QnV0dG9uIHBsLTBcIlxuICAgICAgICAgICAgICAgICAgW2NsYXNzLnBpLXNvcnQtYWx0XT1cIihjb2x1bW4/LmlkID09PSBzb3J0Q29sdW1uICYmIHNvcnREaXJlY3Rpb24gPT09ICdOT05FJykgfHwgY29sdW1uPy5pZCAhPT0gc29ydENvbHVtblwiXG4gICAgICAgICAgICAgICAgICBbY2xhc3MucGktc29ydC1hbW91bnQtdXBdPVwiY29sdW1uPy5pZCA9PT0gc29ydENvbHVtbiAmJiBzb3J0RGlyZWN0aW9uID09PSAnQVNDRU5ESU5HJ1wiXG4gICAgICAgICAgICAgICAgICBbY2xhc3MucGktc29ydC1hbW91bnQtZG93bl09XCJjb2x1bW4/LmlkID09PSBzb3J0Q29sdW1uICYmIHNvcnREaXJlY3Rpb24gPT09ICdERVNDRU5ESU5HJ1wiXG4gICAgICAgICAgICAgICAgICAoY2xpY2spPVwib25Tb3J0Q29sdW1uQ2xpY2soY29sdW1uLmlkKVwiXG4gICAgICAgICAgICAgICAgICBbdGl0bGVdPVwiKHNvcnRJY29uVGl0bGUoY29sdW1uLmlkKSB8IHRyYW5zbGF0ZSlcIlxuICAgICAgICAgICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCIoJ09DWF9EQVRBX1RBQkxFLlRPR0dMRV9CVVRUT04uQVJJQV9MQUJFTCcgfCB0cmFuc2xhdGU6IHsgY29sdW1uOiAoY29sdW1uLm5hbWVLZXkgfCB0cmFuc2xhdGUpLCBkaXJlY3Rpb246IChzb3J0RGlyZWN0aW9uVG9UaXRsZShjb2x1bW5OZXh0U29ydERpcmVjdGlvbihjb2x1bW4uaWQpKSB8IHRyYW5zbGF0ZSl9KVwiXG4gICAgICAgICAgICAgICAgPjwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjdXJyZW50RXF1YWxGaWx0ZXJPcHRpb25zJCB8IGFzeW5jIGFzIGVxdWFsRmlsdGVyT3B0aW9uc1wiPlxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbHVtbkZpbHRlclRlbXBsYXRlcyQgfCBhc3luYyBhcyBjb2x1bW5GaWx0ZXJUZW1wbGF0ZXNcIj5cbiAgICAgICAgICAgICAgICAgICAgPHAtbXVsdGlTZWxlY3RcbiAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZpbHRlck11bHRpU2VsZWN0XCJcbiAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbHVtbi5maWx0ZXJhYmxlICYmICghY29sdW1uLmZpbHRlclR5cGUgfHwgY29sdW1uLmZpbHRlclR5cGUgPT09IEZpbHRlclR5cGUuRVFVQUwpXCJcbiAgICAgICAgICAgICAgICAgICAgICBbb3B0aW9uc109XCJlcXVhbEZpbHRlck9wdGlvbnMuY29sdW1uPy5pZCA9PT0gY29sdW1uLmlkID8gZXF1YWxGaWx0ZXJPcHRpb25zLm9wdGlvbnMgOiBbXVwiXG4gICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwiKGN1cnJlbnRFcXVhbFNlbGVjdGVkRmlsdGVycyQgfCBhc3luYykgfHwgW11cIlxuICAgICAgICAgICAgICAgICAgICAgIFtzaG93VG9nZ2xlQWxsXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgIGVtcHR5RmlsdGVyTWVzc2FnZT1cInt7ICdPQ1hfREFUQV9UQUJMRS5FTVBUWV9GSUxURVJfTUVTU0FHRScgfCB0cmFuc2xhdGUgfX1cIlxuICAgICAgICAgICAgICAgICAgICAgIFtkaXNwbGF5U2VsZWN0ZWRMYWJlbF09XCJmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgW3Jlc2V0RmlsdGVyT25IaWRlXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgIChvbkNoYW5nZSk9XCJvbk11bHRpc2VsZWN0RmlsdGVyQ2hhbmdlKGNvbHVtbiwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJJY29uXCJcbiAgICAgICAgICAgICAgICAgICAgICBhcHBlbmRUbz1cImJvZHlcIlxuICAgICAgICAgICAgICAgICAgICAgIChvbkZvY3VzKT1cIm9uRmlsdGVyQ2hvc2VuKGNvbHVtbilcIlxuICAgICAgICAgICAgICAgICAgICAgIFt0aXRsZV09XCInT0NYX0RBVEFfVEFCTEUuRklMVEVSX1RJVExFJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgW2FyaWFMYWJlbF09XCInT0NYX0RBVEFfVEFCTEUuQ09MVU1OX0ZJTFRFUl9BUklBX0xBQkVMJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgW2FyaWFGaWx0ZXJMYWJlbF09XCIoJ09DWF9EQVRBX1RBQkxFLkZJTFRFUl9BUklBX0xBQkVMJyB8IHRyYW5zbGF0ZTogeyBjb2x1bW46IGNvbHVtbi5uYW1lS2V5IHwgdHJhbnNsYXRlfSlcIlxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cInNlbGVjdGVkSXRlbXNcIiBsZXQtdmFsdWU+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwicGlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MucGktZmlsdGVyXT1cIiEoKGZpbHRlckFtb3VudHMkIHwgYXN5bmMpIHx8IHt9KVtjb2x1bW4uaWRdXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLnBpLWZpbHRlci1maWxsXT1cIigoZmlsdGVyQW1vdW50cyQgfCBhc3luYykgfHwge30pW2NvbHVtbi5pZF0gPiAwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJpdGVtXCIgbGV0LXZhbHVlPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbHVtbkZpbHRlclRlbXBsYXRlc1tjb2x1bW4uaWRdIGFzIHRlbXBsYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwidGVtcGxhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwie1xuICAgICAgICAgICAgICAgICAgICAgIHJvd09iamVjdDogZ2V0Um93T2JqZWN0RnJvbU11bHRpc2VsZWN0SXRlbSh2YWx1ZSwgY29sdW1uKSxcbiAgICAgICAgICAgICAgICAgICAgICBjb2x1bW46IGNvbHVtblxuICAgICAgICAgICAgICAgICAgfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICA8L3AtbXVsdGlTZWxlY3Q+XG4gICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8cC1tdWx0aVNlbGVjdFxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmaWx0ZXJNdWx0aVNlbGVjdFwiXG4gICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbHVtbi5maWx0ZXJhYmxlICYmIGNvbHVtbi5maWx0ZXJUeXBlID09PSBGaWx0ZXJUeXBlLlRSVVRIWVwiXG4gICAgICAgICAgICAgICAgICBbb3B0aW9uc109XCJ0cnV0aHlGaWx0ZXJPcHRpb25zXCJcbiAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cIihjdXJyZW50VHJ1dGh5U2VsZWN0ZWRGaWx0ZXJzJCB8IGFzeW5jKSB8fCBbXVwiXG4gICAgICAgICAgICAgICAgICBbc2hvd1RvZ2dsZUFsbF09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgIGVtcHR5RmlsdGVyTWVzc2FnZT1cInt7ICdPQ1hfREFUQV9UQUJMRS5FTVBUWV9GSUxURVJfTUVTU0FHRScgfCB0cmFuc2xhdGUgfX1cIlxuICAgICAgICAgICAgICAgICAgW2Rpc3BsYXlTZWxlY3RlZExhYmVsXT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgIFtyZXNldEZpbHRlck9uSGlkZV09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgIChvbkNoYW5nZSk9XCJvbk11bHRpc2VsZWN0RmlsdGVyQ2hhbmdlKGNvbHVtbiwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIkljb25cIlxuICAgICAgICAgICAgICAgICAgYXBwZW5kVG89XCJib2R5XCJcbiAgICAgICAgICAgICAgICAgIChvbkZvY3VzKT1cIm9uRmlsdGVyQ2hvc2VuKGNvbHVtbilcIlxuICAgICAgICAgICAgICAgICAgW3RpdGxlXT1cIidPQ1hfREFUQV9UQUJMRS5GSUxURVJfVElUTEUnIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICAgIFthcmlhTGFiZWxdPVwiJ09DWF9EQVRBX1RBQkxFLkNPTFVNTl9GSUxURVJfQVJJQV9MQUJFTCcgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgW2FyaWFGaWx0ZXJMYWJlbF09XCIoJ09DWF9EQVRBX1RBQkxFLkZJTFRFUl9BUklBX0xBQkVMJyB8IHRyYW5zbGF0ZTogeyBjb2x1bW46IGNvbHVtbi5uYW1lS2V5IHwgdHJhbnNsYXRlfSlcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJzZWxlY3RlZEl0ZW1zXCIgbGV0LXZhbHVlPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJwaVwiXG4gICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLnBpLWZpbHRlcl09XCIhKChmaWx0ZXJBbW91bnRzJCB8IGFzeW5jKSB8fCB7fSlbY29sdW1uLmlkXVwiXG4gICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLnBpLWZpbHRlci1maWxsXT1cIigoZmlsdGVyQW1vdW50cyQgfCBhc3luYykgfHwge30pW2NvbHVtbi5pZF0gPiAwXCJcbiAgICAgICAgICAgICAgICAgICAgPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJpdGVtXCIgbGV0LXZhbHVlPiB7e3ZhbHVlLmtleSB8IHRyYW5zbGF0ZX19IDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgPC9wLW11bHRpU2VsZWN0PlxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RoPlxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjc2ltcGxlSGVhZGVyPlxuICAgICAgICAgICAgPHRoIHNjb3BlPVwiY29sXCI+e3sgY29sdW1uLm5hbWVLZXkgfCB0cmFuc2xhdGUgfX08L3RoPlxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiYWN0aW9uQ29sdW1uUG9zaXRpb24gPT09ICdyaWdodCc7XCI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImFjdGlvbkNvbHVtbkhlYWRlclwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvdHI+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbiAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiYm9keVwiIGxldC1yb3dPYmplY3Q+XG4gICAgICA8dHIgKm5nSWY9XCJjb2x1bW5UZW1wbGF0ZXNcIj5cbiAgICAgICAgPHRkICpuZ0lmPVwic2VsZWN0aW9uQ2hhbmdlZE9ic2VydmVkXCI+XG4gICAgICAgICAgPHAtY2hlY2tib3hcbiAgICAgICAgICAgICpuZ0lmPVwiaXNSb3dTZWxlY3Rpb25EaXNhYmxlZChyb3dPYmplY3QpICYmIGlzU2VsZWN0ZWQocm93T2JqZWN0KTsgZWxzZSBkZWZhdWx0Q2hlY2tib3hcIlxuICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJjaGVja2VkXCJcbiAgICAgICAgICAgIFtiaW5hcnldPVwidHJ1ZVwiXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwidHJ1ZVwiXG4gICAgICAgICAgICBbYXJpYUxhYmVsXT1cIidPQ1hfREFUQV9UQUJMRS5TRUxFQ1RfQVJJQV9MQUJFTCcgfCB0cmFuc2xhdGU6IHsga2V5OiByb3dPYmplY3QuaWR9XCJcbiAgICAgICAgICA+PC9wLWNoZWNrYm94PlxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdENoZWNrYm94PlxuICAgICAgICAgICAgPHAtdGFibGVDaGVja2JveFxuICAgICAgICAgICAgICBbdmFsdWVdPVwicm93T2JqZWN0XCJcbiAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImlzUm93U2VsZWN0aW9uRGlzYWJsZWQocm93T2JqZWN0KVwiXG4gICAgICAgICAgICAgIFthcmlhTGFiZWxdPVwiJ09DWF9EQVRBX1RBQkxFLlNFTEVDVF9BUklBX0xBQkVMJyB8IHRyYW5zbGF0ZTogeyBrZXk6IHJvd09iamVjdC5pZH1cIlxuICAgICAgICAgICAgPjwvcC10YWJsZUNoZWNrYm94PlxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgIDwvdGQ+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJhY3Rpb25Db2x1bW5Qb3NpdGlvbiA9PT0gJ2xlZnQnO1wiPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJhY3Rpb25Db2x1bW47IGNvbnRleHQ6IHtsb2NhbFJvd09iamVjdDogcm93T2JqZWN0fVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPHRkICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgY29sdW1uc1wiPlxuICAgICAgICAgIEBkZWZlcihvbiB2aWV3cG9ydCl7XG4gICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgKm5nSWY9XCJjb2x1bW5UZW1wbGF0ZXNbY29sdW1uLmlkXVwiXG4gICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJcbiAgICAgICAgICAgICAgICBfY2VsbCA/IF9jZWxsOiBjb2x1bW5UZW1wbGF0ZXNbY29sdW1uLmlkXVxuICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cIntcbiAgICAgICAgICAgICAgICAgIHJvd09iamVjdDogcm93T2JqZWN0LFxuICAgICAgICAgICAgICAgICAgY29sdW1uOiBjb2x1bW4sXG4gICAgICAgICAgICAgIH1cIlxuICAgICAgICAgID5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICB9IEBwbGFjZWhvbGRlciB7XG4gICAgICAgICAgPHAtc2tlbGV0b24gd2lkdGg9XCIzcmVtXCIgLz5cbiAgICAgICAgICB9XG4gICAgICAgIDwvdGQ+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJhY3Rpb25Db2x1bW5Qb3NpdGlvbiA9PT0gJ3JpZ2h0JztcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiYWN0aW9uQ29sdW1uOyBjb250ZXh0OiB7bG9jYWxSb3dPYmplY3Q6IHJvd09iamVjdH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8L3RyPlxuICAgIDwvbmctdGVtcGxhdGU+XG4gICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cImVtcHR5bWVzc2FnZVwiPlxuICAgICAgPHRyPlxuICAgICAgICA8dGQgW2NvbFNwYW5dPVwiY29sdW1ucy5sZW5ndGggKyAoKGFueVJvd0FjdGlvbk9ic2VydmVkIHx8IHRoaXMuYWRkaXRpb25hbEFjdGlvbnMubGVuZ3RoID4gMCkgPyAxIDogMClcIj5cbiAgICAgICAgICB7eyBlbXB0eVJlc3VsdHNNZXNzYWdlIHx8IChcIk9DWF9EQVRBX1RBQkxFLkVNUFRZX1JFU1VMVFwiIHwgdHJhbnNsYXRlKSB9fVxuICAgICAgICA8L3RkPlxuICAgICAgPC90cj5cbiAgICA8L25nLXRlbXBsYXRlPlxuICA8L3AtdGFibGU+XG48L25nLWNvbnRhaW5lcj5cblxuPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cImRlZmF1bHRTdHJpbmdDZWxsXCIgbGV0LXJvd09iamVjdD1cInJvd09iamVjdFwiIGxldC1jb2x1bW49XCJjb2x1bW5cIj5cbiAgPG5nLWNvbnRhaW5lcj4ge3sgcmVzb2x2ZUZpZWxkRGF0YShyb3dPYmplY3QsIGNvbHVtbi5pZCl9fSA8L25nLWNvbnRhaW5lcj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJkZWZhdWx0TnVtYmVyQ2VsbFwiIGxldC1yb3dPYmplY3Q9XCJyb3dPYmplY3RcIiBsZXQtY29sdW1uPVwiY29sdW1uXCI+XG4gIDxuZy1jb250YWluZXI+IHt7IHJlc29sdmVGaWVsZERhdGEocm93T2JqZWN0LCBjb2x1bW4uaWQpIHwgbnVtYmVyIH19IDwvbmctY29udGFpbmVyPlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cImRlZmF1bHRDdXN0b21DZWxsXCIgbGV0LXJvd09iamVjdD1cInJvd09iamVjdFwiIGxldC1jb2x1bW49XCJjb2x1bW5cIj4gPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cImRlZmF1bHREYXRlQ2VsbFwiIGxldC1yb3dPYmplY3Q9XCJyb3dPYmplY3RcIiBsZXQtY29sdW1uPVwiY29sdW1uXCI+XG4gIDxuZy1jb250YWluZXI+IHt7IHJlc29sdmVGaWVsZERhdGEocm93T2JqZWN0LCBjb2x1bW4uaWQpIHwgZGF0ZTogY29sdW1uLmRhdGVGb3JtYXQgPz8gJ21lZGl1bScgfX0gPC9uZy1jb250YWluZXI+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiZGVmYXVsdFJlbGF0aXZlRGF0ZUNlbGxcIiBsZXQtcm93T2JqZWN0PVwicm93T2JqZWN0XCIgbGV0LWNvbHVtbj1cImNvbHVtblwiPlxuICA8bmctY29udGFpbmVyPlxuICAgIHt7ICdPQ1hfREFUQV9UQUJMRS5FRElURUQnIHwgdHJhbnNsYXRlIH19IHt7IHJlc29sdmVGaWVsZERhdGEocm93T2JqZWN0LCBjb2x1bW4uaWQpIHwgdGltZWFnbyB9fVxuICA8L25nLWNvbnRhaW5lcj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJkZWZhdWx0VHJhbnNsYXRpb25LZXlDZWxsXCIgbGV0LXJvd09iamVjdD1cInJvd09iamVjdFwiIGxldC1jb2x1bW49XCJjb2x1bW5cIj5cbiAgPG5nLWNvbnRhaW5lcj4ge3sgcmVzb2x2ZUZpZWxkRGF0YShyb3dPYmplY3QsIGNvbHVtbi5pZCkgfCB0cmFuc2xhdGUgfX0gPC9uZy1jb250YWluZXI+XG48L25nLXRlbXBsYXRlPlxuIl19