ng-prime-tools 1.0.39 → 1.0.40

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.
@@ -28,40 +28,38 @@ export class PTAdvancedPrimeTableComponent {
28
28
  this.hasExportPDF = false;
29
29
  this.hasColumnFilter = false;
30
30
  this.isPaginated = false;
31
- /**
32
- * Actions configuration.
33
- * - code 'edit' / 'delete' garde l'ancien comportement.
34
- * - tout autre code = action custom, gérée uniquement dans le parent.
35
- */
36
31
  this.actions = [];
37
32
  this.isSortable = false;
38
33
  this.loading = false;
39
34
  this.maxHeight = null;
40
- // Outputs: Events emitted to the parent component
41
- this.filter = new EventEmitter();
35
+ // Outputs
42
36
  this.search = new EventEmitter();
43
37
  this.exportExcelEvent = new EventEmitter();
44
38
  this.exportPdfEvent = new EventEmitter();
45
- this.pageChange = new EventEmitter();
39
+ this.onPageChange = new EventEmitter();
40
+ this.onSortColumn = new EventEmitter();
41
+ this.onFilterColumn = new EventEmitter();
46
42
  this.TableTypeEnum = TableTypeEnum;
47
- this.AlignEnum = AlignEnum; // if needed in template
43
+ this.AlignEnum = AlignEnum;
48
44
  this.searchValue = '';
45
+ // used to store composed filter UI state (and options)
49
46
  this.filters = {};
47
+ // store the last filter value per column field (for all filters)
48
+ this.latestFilterValues = {};
50
49
  this.validCurrencyCodes = ['USD', 'EUR', 'MAD'];
51
50
  this.iconWidth = 77;
52
- // Component state properties
51
+ // Component state
53
52
  this.rows = 0;
54
53
  this.hasGroupedColumns = false;
55
- // Flags / handlers for built-in edit/delete support
54
+ // edit/delete flags
56
55
  this.isDelete = false;
57
56
  this.isEdit = false;
58
57
  this.Delete = () => { };
59
58
  this.initEditableRow = () => { };
60
59
  this.saveEditableRow = () => { };
61
60
  this.cancelEditableRow = () => { };
62
- // Extra custom actions (codes other than 'edit'/'delete')
63
61
  this.customActions = [];
64
- // Data management properties
62
+ // Data management
65
63
  this.dataMap = new Map();
66
64
  this.map = new Map();
67
65
  this.optionEntries = new Map();
@@ -77,7 +75,6 @@ export class PTAdvancedPrimeTableComponent {
77
75
  .map((col) => col.code);
78
76
  this.initializePagination();
79
77
  this.initializeActions();
80
- // Set default value for isSortable / isEditable + widths
81
78
  this.columns.forEach((col) => {
82
79
  if (col.type === TableTypeEnum.ACTION) {
83
80
  col.isEditable = false;
@@ -102,7 +99,6 @@ export class PTAdvancedPrimeTableComponent {
102
99
  });
103
100
  }
104
101
  // ---------- HEADER + BODY ALIGNMENT HELPERS ----------
105
- /** CSS class for the header title span (inside header-container) */
106
102
  getHeaderTitleClass(col) {
107
103
  const align = col.headerAlign ?? AlignEnum.LEFT;
108
104
  switch (align) {
@@ -114,7 +110,6 @@ export class PTAdvancedPrimeTableComponent {
114
110
  return 'header-title-left';
115
111
  }
116
112
  }
117
- /** CSS class for grouped headers (<th> with colspan) */
118
113
  getHeaderAlignClass(col) {
119
114
  const align = col.headerAlign ?? AlignEnum.LEFT;
120
115
  switch (align) {
@@ -126,9 +121,7 @@ export class PTAdvancedPrimeTableComponent {
126
121
  return 'header-align-left';
127
122
  }
128
123
  }
129
- /** CSS class for body cells (<td>) based on dataAlign (default LEFT) */
130
124
  getDataAlignClass(col) {
131
- // optional: default right alignment for numeric/amount when not specified
132
125
  const effectiveAlign = col.dataAlign ??
133
126
  (col.type === TableTypeEnum.NUMBER || col.type === TableTypeEnum.AMOUNT
134
127
  ? AlignEnum.RIGHT
@@ -144,7 +137,6 @@ export class PTAdvancedPrimeTableComponent {
144
137
  }
145
138
  // ---------- ACTIONS INITIALIZATION ----------
146
139
  initializeActions() {
147
- // reset state
148
140
  this.isDelete = false;
149
141
  this.isEdit = false;
150
142
  this.Delete = () => { };
@@ -165,7 +157,6 @@ export class PTAdvancedPrimeTableComponent {
165
157
  this.initializeEditActions(action);
166
158
  break;
167
159
  default:
168
- // any other code is a pure custom action
169
160
  this.customActions.push(action);
170
161
  break;
171
162
  }
@@ -181,16 +172,18 @@ export class PTAdvancedPrimeTableComponent {
181
172
  };
182
173
  this.cancelEditableRow = (item) => console.log(item);
183
174
  }
184
- /** Called when a custom action button is clicked */
185
175
  onCustomActionClick(action, row) {
186
176
  if (action && typeof action.action === 'function') {
187
- // Defer to next macrotask → fresh change detection cycle
188
177
  setTimeout(() => {
189
178
  action.action(row);
190
179
  }, 0);
191
180
  }
192
181
  }
193
- // Initialize filters for composed columns
182
+ // ---------- FILTERING / SORTING / PAGINATION ----------
183
+ /**
184
+ * For composed columns, we still register filters under filters[composedName]
185
+ * to keep options & placeholders.
186
+ */
194
187
  initializeComposedFilters(col) {
195
188
  col.composedNames?.forEach((composedName) => {
196
189
  const code = col.code || '';
@@ -203,7 +196,6 @@ export class PTAdvancedPrimeTableComponent {
203
196
  };
204
197
  });
205
198
  }
206
- // Get the column type for composed fields (STRING, IMAGE, etc.)
207
199
  getComposedFieldType(col, composedName) {
208
200
  if (col.composedNames && col.composedTypes) {
209
201
  const index = col.composedNames.indexOf(composedName);
@@ -213,35 +205,190 @@ export class PTAdvancedPrimeTableComponent {
213
205
  }
214
206
  return undefined;
215
207
  }
216
- onComposedFilterChange(col, composedName, selectedValues) {
217
- this.filters[composedName].value = selectedValues;
218
- this.filter.emit(this.filters);
219
- const filterValue = selectedValues.join(',');
220
- let matchResults = [];
221
- const colCode = col.code;
222
- selectedValues.forEach((value) => {
223
- const matches = this.dt.value.filter((row) => {
224
- return row[colCode]?.[composedName]
225
- ?.toString()
226
- .toLowerCase()
227
- .includes(value.toLowerCase());
228
- });
229
- matchResults = [...matchResults, ...matches];
208
+ onComposedColumnClear(col) {
209
+ if (!col.code || !col.composedNames) {
210
+ return;
211
+ }
212
+ col.composedNames.forEach((name) => {
213
+ const key = `${col.code}.${name}`;
214
+ delete this.latestFilterValues[key];
215
+ if (this.filters[name]) {
216
+ this.filters[name].value = [];
217
+ }
230
218
  });
231
- matchResults = Array.from(new Set(matchResults));
232
- this.dt.filteredValue = matchResults;
233
- this.dt.filterGlobal(filterValue, 'contains');
234
219
  }
235
- // ⛔ Don't override totalRecords here – we are in server-side mode
236
- onFilter(event) {
237
- this.filter.emit(event);
238
- // this.totalRecords = event.filteredValue?.length || 0; // removed
220
+ /**
221
+ * COMPOSED: cache UI values only, real filter applied on Apply/Clear.
222
+ */
223
+ onComposedFilterValueChange(col, composedName, value, filterModel) {
224
+ const key = `${col.code}.${composedName}`;
225
+ // 1) sync with PrimeNG filter model so Apply/Clear work correctly
226
+ if (filterModel) {
227
+ filterModel.value = value;
228
+ if (Array.isArray(filterModel.constraints) &&
229
+ filterModel.constraints.length > 0) {
230
+ filterModel.constraints[0].value = value;
231
+ }
232
+ }
233
+ // 2) keep your local UI model
234
+ if (!this.filters[composedName]) {
235
+ this.filters[composedName] = {
236
+ options: col.filterOptions,
237
+ value: [],
238
+ placeholder: 'Select option',
239
+ };
240
+ }
241
+ this.filters[composedName].value = value || [];
242
+ // 3) cache for server-side `filterColumn`
243
+ const isEmpty = !value || (Array.isArray(value) && value.length === 0);
244
+ if (isEmpty) {
245
+ delete this.latestFilterValues[key];
246
+ }
247
+ else {
248
+ this.latestFilterValues[key] = value;
249
+ }
250
+ }
251
+ /**
252
+ * NUMBER/DATE/MULTISELECT: keep a local copy + update filterModel.value.
253
+ */
254
+ onFilterValueChange(field, filterModel, value) {
255
+ if (!field) {
256
+ return;
257
+ }
258
+ const isEmpty = value === null ||
259
+ value === undefined ||
260
+ (Array.isArray(value) && value.length === 0);
261
+ if (isEmpty) {
262
+ delete this.latestFilterValues[field];
263
+ }
264
+ else {
265
+ this.latestFilterValues[field] = value;
266
+ }
267
+ if (filterModel) {
268
+ filterModel.value = value;
269
+ }
270
+ }
271
+ /** Helper: find column by field. Supports composed fields like "code.prop". */
272
+ findColumnByField(field) {
273
+ return this.columns.find((c) => c.code === field || (c.code && field.startsWith(c.code + '.')));
274
+ }
275
+ // Fired by PrimeNG when the user clicks Apply / Clear in any filter menu
276
+ filterColumn(event) {
277
+ const filters = event?.filters;
278
+ if (!filters) {
279
+ this.onFilterColumn.emit(event);
280
+ return;
281
+ }
282
+ Object.keys(filters).forEach((field) => {
283
+ const meta = filters[field];
284
+ const normalizeMeta = (m) => Array.isArray(m) && m.length > 0 ? m[0] : m;
285
+ const m = normalizeMeta(meta);
286
+ const col = this.findColumnByField(field);
287
+ // nothing to do
288
+ if (!m && !col) {
289
+ return;
290
+ }
291
+ // ----------------------------------------------------
292
+ // 🔹 SPECIAL CASE: COMPOSED COLUMN
293
+ // ----------------------------------------------------
294
+ if (col && col.type === TableTypeEnum.COMPOSED) {
295
+ const composedValues = {};
296
+ col.composedNames?.forEach((name) => {
297
+ const key = `${col.code}.${name}`;
298
+ const val = this.latestFilterValues[key];
299
+ const empty = val === null ||
300
+ val === undefined ||
301
+ (Array.isArray(val) && val.length === 0);
302
+ if (!empty) {
303
+ composedValues[name] = val;
304
+ }
305
+ });
306
+ // If nothing in cache, treat as "no filter"
307
+ if (Object.keys(composedValues).length === 0) {
308
+ if (m) {
309
+ m.value = null;
310
+ if (Array.isArray(m.constraints)) {
311
+ m.constraints.forEach((c) => (c.value = null));
312
+ }
313
+ }
314
+ }
315
+ else {
316
+ // send object { sub1: [...], sub2: [...] } to parent
317
+ m.value = composedValues;
318
+ }
319
+ return; // composed handled
320
+ }
321
+ // ----------------------------------------------------
322
+ // 🔹 GENERIC CASE: NON-COMPOSED COLUMNS
323
+ // ----------------------------------------------------
324
+ if (!m) {
325
+ return;
326
+ }
327
+ let value = m.value;
328
+ if (Array.isArray(m.constraints) && m.constraints.length > 0) {
329
+ const cVal = m.constraints[0].value;
330
+ if (cVal !== undefined) {
331
+ value = cVal;
332
+ }
333
+ }
334
+ const isEmpty = value === null ||
335
+ value === undefined ||
336
+ (Array.isArray(value) && value.length === 0);
337
+ // CLEAR => remove from cache, reset PrimeNG metadata
338
+ if (isEmpty) {
339
+ delete this.latestFilterValues[field];
340
+ m.value = null;
341
+ if (Array.isArray(m.constraints) && m.constraints.length > 0) {
342
+ m.constraints[0].value = null;
343
+ }
344
+ return;
345
+ }
346
+ // NON-EMPTY => cache and normalize
347
+ this.latestFilterValues[field] = value;
348
+ let emitValue = value;
349
+ // Only DATE columns need "dd/MM/yyyy" format
350
+ if (col && col.type === TableTypeEnum.DATE && value) {
351
+ emitValue = this.formatDate(value instanceof Date ? value : new Date(value));
352
+ }
353
+ m.value = emitValue;
354
+ if (Array.isArray(m.constraints) && m.constraints.length > 0) {
355
+ m.constraints[0].value = emitValue;
356
+ }
357
+ });
358
+ // send normalized filters to parent (server-side pagination)
359
+ this.onFilterColumn.emit(event);
239
360
  }
240
- onPageChange(event) {
361
+ changePage(event) {
241
362
  const page = event.page ?? Math.floor((event.first || 0) / event.rows);
242
363
  const rows = event.rows;
243
364
  this.rows = rows;
244
- this.pageChange.emit({ page, rows });
365
+ this.onPageChange.emit({ page, rows });
366
+ }
367
+ sortColumn(event) {
368
+ if (!this.isPaginated) {
369
+ return;
370
+ }
371
+ let field = event.field;
372
+ const col = this.columns.find((c) => c.code === field);
373
+ if (col && col.type === TableTypeEnum.COMPOSED) {
374
+ let textProp;
375
+ if (col.composedNames && col.composedTypes) {
376
+ const idx = col.composedTypes.findIndex((t) => t === TableTypeEnum.STRING);
377
+ if (idx >= 0 && idx < col.composedNames.length) {
378
+ textProp = col.composedNames[idx];
379
+ }
380
+ }
381
+ if (!textProp && col.composedNames && col.composedNames.length > 0) {
382
+ textProp = col.composedNames[0];
383
+ }
384
+ if (textProp) {
385
+ field = `${field}.${textProp}`;
386
+ }
387
+ }
388
+ this.onSortColumn.emit({
389
+ ...event,
390
+ field,
391
+ });
245
392
  }
246
393
  onCalendarFilterChange(event, columnCode, filterCallback) {
247
394
  const filterValue = event ? new Date(event) : null;
@@ -249,8 +396,16 @@ export class PTAdvancedPrimeTableComponent {
249
396
  return;
250
397
  }
251
398
  filterCallback(filterValue);
399
+ if (this.isPaginated) {
400
+ this.onFilterColumn.emit({
401
+ type: 'date',
402
+ columnCode,
403
+ value: filterValue,
404
+ });
405
+ return;
406
+ }
252
407
  const filterValueString = event ? this.formatDate(event) : '';
253
- this.onFilter({
408
+ this.filterColumn({
254
409
  filteredValue: this.data.filter((item) => {
255
410
  const columnValue = item[columnCode];
256
411
  if (columnValue) {
@@ -261,6 +416,7 @@ export class PTAdvancedPrimeTableComponent {
261
416
  }),
262
417
  });
263
418
  }
419
+ // ---------- OTHER HELPERS ----------
264
420
  filterComposedData(item, composedName, value) {
265
421
  if (Array.isArray(value) && value.length > 0) {
266
422
  return value.some((filterValue) => item[composedName]?.toLowerCase().includes(filterValue.toLowerCase()));
@@ -273,16 +429,27 @@ export class PTAdvancedPrimeTableComponent {
273
429
  return `${totalWidth}px`;
274
430
  }
275
431
  getHeaderWidth(col) {
276
- // ✅ If a width is configured (ex: '410px'), use it directly
277
432
  if (col.width) {
278
433
  return col.width;
279
434
  }
280
- // otherwise compute it automatically
281
435
  return this.calculateColumnWidth(col);
282
436
  }
283
437
  clear(table) {
438
+ // Clear PrimeNG internal filters + UI
284
439
  table.clear();
440
+ // Clear global search
285
441
  this.searchValue = '';
442
+ // Clear cached values for normal & composed fields
443
+ this.latestFilterValues = {};
444
+ // Clear local models for composed filters
445
+ Object.keys(this.filters).forEach((key) => {
446
+ if (this.filters[key]) {
447
+ this.filters[key].value = [];
448
+ }
449
+ });
450
+ if (this.isPaginated) {
451
+ this.onFilterColumn.emit({ cleared: true });
452
+ }
286
453
  }
287
454
  parseDate(dateString) {
288
455
  const parts = dateString.split('/');
@@ -388,6 +555,10 @@ export class PTAdvancedPrimeTableComponent {
388
555
  filterGlobal(event) {
389
556
  const target = event.target;
390
557
  const value = target.value.toLowerCase();
558
+ if (this.isPaginated) {
559
+ this.search.emit(value);
560
+ return;
561
+ }
391
562
  const filteredData = this.data.filter((item) => {
392
563
  return this.globalFilterFields.some((field) => {
393
564
  const column = this.columns.find((col) => col.code === field);
@@ -411,8 +582,6 @@ export class PTAdvancedPrimeTableComponent {
411
582
  });
412
583
  });
413
584
  this.dt.value = filteredData;
414
- // ⛔ ne pas toucher à totalRecords en mode serveur
415
- // this.totalRecords = filteredData.length ?? 0;
416
585
  }
417
586
  filterComposedColumn(composedData, value) {
418
587
  if (composedData) {
@@ -504,11 +673,11 @@ export class PTAdvancedPrimeTableComponent {
504
673
  return formattedNumber;
505
674
  }
506
675
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PTAdvancedPrimeTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
507
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: PTAdvancedPrimeTableComponent, selector: "pt-advanced-prime-table", inputs: { data: "data", columns: "columns", totalRecords: "totalRecords", rowsPerPage: "rowsPerPage", hasSearchFilter: "hasSearchFilter", hasExportExcel: "hasExportExcel", hasExportPDF: "hasExportPDF", hasColumnFilter: "hasColumnFilter", isPaginated: "isPaginated", actions: "actions", isSortable: "isSortable", loading: "loading", maxHeight: "maxHeight" }, outputs: { filter: "filter", search: "search", exportExcelEvent: "exportExcelEvent", exportPdfEvent: "exportPdfEvent", pageChange: "pageChange" }, viewQueries: [{ propertyName: "dt", first: true, predicate: ["dt"], descendants: true }], ngImport: i0, template: "<div class=\"pt-advanced-prime-table table-container\">\n <p-table\n #dt\n [value]=\"data\"\n [loading]=\"loading\"\n [rows]=\"rows\"\n [paginator]=\"isPaginated\"\n [globalFilterFields]=\"globalFilterFields\"\n [rowsPerPageOptions]=\"rowsPerPage\"\n [totalRecords]=\"totalRecords\"\n [lazy]=\"true\"\n dataKey=\"id\"\n styleClass=\"p-datatable-gridlines p-datatable-striped\"\n [scrollable]=\"true\"\n [scrollHeight]=\"maxHeight !== null ? maxHeight : undefined\"\n (onFilter)=\"onFilter($event)\"\n (onPage)=\"onPageChange($event)\"\n >\n <!-- COLGROUP: sync header/body widths (incl. Actions 410px) -->\n <ng-template pTemplate=\"colgroup\" let-columns>\n <colgroup>\n <col\n *ngFor=\"let col of columns\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n />\n </colgroup>\n </ng-template>\n\n <!-- CAPTION -->\n <ng-template pTemplate=\"caption\">\n <div class=\"flex\">\n <div>\n <h3>Total: {{ totalRecords }}</h3>\n </div>\n\n <div>\n <!-- Clear filters -->\n <button\n *ngIf=\"hasSearchFilter\"\n pButton\n icon=\"pi pi-filter-slash\"\n class=\"p-button-rounded p-button-text\"\n (click)=\"clear(dt)\"\n title=\"Clear filters\"\n ></button>\n\n <!-- Export to Excel Button -->\n <button\n *ngIf=\"hasExportExcel\"\n pButton\n icon=\"pi pi-file-excel\"\n class=\"p-button-rounded p-button-text\"\n (click)=\"exportExcel()\"\n title=\"Export to Excel\"\n ></button>\n\n <!-- Export to PDF Button -->\n <button\n *ngIf=\"hasExportPDF\"\n pButton\n icon=\"pi pi-file-pdf\"\n class=\"p-button-rounded p-button-text\"\n (click)=\"exportPdf()\"\n title=\"Export to PDF\"\n ></button>\n </div>\n\n <div class=\"ml-auto\" *ngIf=\"hasSearchFilter\">\n <p-iconField iconPosition=\"left\" class=\"ml-auto\">\n <p-inputIcon>\n <i class=\"pi pi-search\"></i>\n </p-inputIcon>\n <input\n pInputText\n type=\"text\"\n [(ngModel)]=\"searchValue\"\n (input)=\"filterGlobal($event)\"\n placeholder=\"Search keyword\"\n />\n </p-iconField>\n </div>\n </div>\n </ng-template>\n\n <!-- HEADER -->\n <ng-template pTemplate=\"header\">\n <tr class=\"sticky-header\">\n <ng-container *ngFor=\"let col of columns\">\n <th\n *ngIf=\"!col.children; else groupHeader\"\n pSortableColumn=\"{{ col.code }}\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n [ngClass]=\"[\n getHeaderAlignClass(col),\n col.type === TableTypeEnum.ACTION ? 'action-column' : ''\n ]\"\n colspan=\"1\"\n >\n <!-- SORTABLE HEADER -->\n <ng-container\n *ngIf=\"isSortable && col.isSortable !== false; else noSortHeader\"\n >\n <div\n class=\"header-container d-flex align-items-center justify-content-between\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n [style.margin]=\"'10px'\"\n >\n <span [ngClass]=\"getHeaderTitleClass(col)\">\n {{ col.title }}\n </span>\n <div\n class=\"icons d-flex align-items-center\"\n [style.width]=\"'77px'\"\n >\n <p-sortIcon field=\"{{ col.code }}\" />\n <ng-container *ngIf=\"col.isFilter !== false\">\n <!-- COMPOSED FILTER -->\n <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n *ngIf=\"col.type === TableTypeEnum.COMPOSED\"\n showClearButton=\"false\"\n showApplyButton=\"false\"\n >\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n (onFilter)=\"onFilter($event)\"\n >\n <div *ngFor=\"let composedName of col.composedNames\">\n <ng-container\n *ngIf=\"\n getComposedFieldType(col, composedName) ===\n TableTypeEnum.STRING\n \"\n >\n <p-multiSelect\n [ngModel]=\"filters[composedName]?.value\"\n [options]=\"filters[composedName]?.options\"\n (onChange)=\"\n onComposedFilterChange(\n col,\n composedName,\n $event.value\n )\n \"\n [placeholder]=\"filters[composedName]?.placeholder\"\n [display]=\"'chip'\"\n >\n <ng-template let-item pTemplate=\"item\">\n <div class=\"custom-multiselect-item\">\n <img\n *ngIf=\"item.image\"\n [src]=\"item.image\"\n alt=\"icon\"\n class=\"filter-image\"\n />\n <span>{{ item.label }}</span>\n </div>\n </ng-template>\n </p-multiSelect>\n </ng-container>\n </div>\n\n <ng-template let-item pTemplate=\"item\">\n <div class=\"custom-multiselect-item\">\n <img\n *ngIf=\"item.image\"\n [src]=\"item.image\"\n alt=\"icon\"\n class=\"filter-image\"\n />\n <span>{{ item.label }}</span>\n </div>\n </ng-template>\n </ng-template>\n </p-columnFilter>\n\n <!-- OTHER TYPES -->\n <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n *ngIf=\"col.type !== TableTypeEnum.COMPOSED\"\n hideOnClear=\"true\"\n >\n <!-- NUMBER -->\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"col.type === TableTypeEnum.NUMBER\"\n (onFilter)=\"onFilter($event)\"\n >\n <input\n pInputText\n type=\"number\"\n [step]=\"\n col.decimalPlaces\n ? '0.' + '1'.padEnd(col.decimalPlaces, '0')\n : 'any'\n \"\n [ngModel]=\"value\"\n (ngModelChange)=\"filterCallback($event)\"\n placeholder=\"Enter a number\"\n />\n </ng-template>\n\n <!-- DATE -->\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"col.type === TableTypeEnum.DATE\"\n (onFilter)=\"onFilter($event)\"\n >\n <p-calendar\n [ngModel]=\"value\"\n (ngModelChange)=\"\n onCalendarFilterChange(\n $event,\n col.code!,\n filterCallback\n )\n \"\n dateFormat=\"dd/mm/yy\"\n placeholder=\"Choose a date\"\n ></p-calendar>\n </ng-template>\n\n <!-- MULTISELECT -->\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"\n col.type === TableTypeEnum.MULTISELECT &&\n col.filterOptions &&\n col.filterOptions.length > 0\n \"\n (onFilter)=\"onFilter($event)\"\n >\n <p-multiSelect\n [options]=\"col.filterOptions\"\n [ngModel]=\"value\"\n (ngModelChange)=\"filterCallback($event)\"\n display=\"chip\"\n placeholder=\"Choose option\"\n class=\"custom-multiselect\"\n ></p-multiSelect>\n </ng-template>\n </p-columnFilter>\n </ng-container>\n </div>\n </div>\n </ng-container>\n\n <!-- NON-SORTABLE HEADER -->\n <ng-template #noSortHeader>\n <div\n class=\"header-container d-flex align-items-center justify-content-between\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n [style.margin]=\"'10px'\"\n >\n <span [ngClass]=\"getHeaderTitleClass(col)\">\n {{ col.title }}\n </span>\n <ng-container *ngIf=\"col.isFilter !== false\">\n <p-columnFilter\n *ngIf=\"col.type === 'AMOUNT'\"\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n [currency]=\"getCurrencySymbol(col)\"\n ></p-columnFilter>\n\n <p-columnFilter\n *ngIf=\"col.type !== 'AMOUNT'\"\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n >\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"getColumnFilterType(col) === 'date'\"\n >\n <p-calendar\n [ngModel]=\"value\"\n (ngModelChange)=\"filterCallback($event)\"\n dateFormat=\"dd/mm/yy\"\n ></p-calendar>\n </ng-template>\n\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"getColumnFilterType(col) === 'multiSelect'\"\n >\n <p-multiSelect\n [options]=\"col.filterOptions\"\n [ngModel]=\"value\"\n (ngModelChange)=\"filterCallback($event)\"\n display=\"chip\"\n placeholder=\"Select\"\n class=\"custom-multiselect\"\n ></p-multiSelect>\n </ng-template>\n </p-columnFilter>\n </ng-container>\n </div>\n </ng-template>\n </th>\n\n <!-- GROUPED HEADER -->\n <ng-template #groupHeader>\n <th\n [attr.colspan]=\"col.children?.length\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [ngClass]=\"getHeaderAlignClass(col)\"\n >\n <span>{{ col.title }}</span>\n </th>\n </ng-template>\n </ng-container>\n </tr>\n\n <!-- CHILD HEADERS -->\n <tr *ngIf=\"hasGroupedColumns\">\n <ng-container *ngFor=\"let col of columns\">\n <ng-container *ngIf=\"col.children\">\n <th\n *ngFor=\"let child of col.children\"\n [style.width]=\"child.width || getHeaderWidth(child)\"\n [style.padding]=\"'0px'\"\n ></th>\n </ng-container>\n </ng-container>\n </tr>\n </ng-template>\n\n <!-- EMPTY MESSAGE -->\n <ng-template pTemplate=\"emptymessage\">\n <div class=\"empty-message\">\n <i class=\"pi pi-info-circle\"></i>\n <p>No records available to display.</p>\n </div>\n </ng-template>\n\n <!-- BODY -->\n <ng-template\n pTemplate=\"body\"\n let-data\n let-editing=\"editing\"\n let-ri=\"rowIndex\"\n >\n <tr *ngIf=\"!loading\" [pEditableRow]=\"isEdit ? data : null\">\n <ng-container *ngFor=\"let col of columns\">\n <!-- SIMPLE COLUMNS (no children) -->\n <ng-container *ngIf=\"!col.children; else childColumns\">\n <!-- EDITABLE CELL -->\n <td\n *ngIf=\"\n isEditable(col.code!) && col.type !== TableTypeEnum.ACTION;\n else normalTD\n \"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [ngClass]=\"getDataAlignClass(col)\"\n >\n <!-- Editable input for NUMBER/DATE/STRING/MULTISELECT -->\n <ng-container *ngIf=\"isMultiSelect(col.code); else datePicker\">\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <p-multiSelect\n appendTo=\"body\"\n [ngModel]=\"data[col.code!]\"\n [style]=\"{ width: '100%' }\"\n (ngModelChange)=\"changeHandler(data.id, col.code, $event)\"\n [options]=\"optionValues\"\n ></p-multiSelect>\n </ng-template>\n <ng-template pTemplate=\"output\">\n <div class=\"multi-select-container\">\n <ng-container *ngFor=\"let rec of data[col.code!]\">\n <p-tag [value]=\"rec\"></p-tag>\n </ng-container>\n </div>\n </ng-template>\n </p-cellEditor>\n </ng-container>\n\n <ng-template #datePicker>\n <ng-container *ngIf=\"isDatePicker(col.code); else normalInput\">\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <p-calendar\n [inputId]=\"data[col.code!]\"\n [ngModel]=\"data[col.code!]\"\n (ngModelChange)=\"\n changeHandler(data.id, col.code, $event)\n \"\n [dateFormat]=\"'dd/mm/yy'\"\n ></p-calendar>\n </ng-template>\n <ng-template pTemplate=\"output\">\n {{ data[col.code!] | customDate }}\n </ng-template>\n </p-cellEditor>\n </ng-container>\n </ng-template>\n\n <ng-template #normalInput>\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <input\n pInputText\n type=\"text\"\n [ngModel]=\"data[col.code!]\"\n (change)=\"onChange($event, data.id, col.code)\"\n />\n </ng-template>\n <ng-template pTemplate=\"output\">\n <ng-container\n *ngIf=\"\n col.type === TableTypeEnum.AMOUNT;\n else normalOutput\n \"\n >\n {{\n data[col.code!]\n | customCurrency\n : getCurrencySymbol(col)\n : col.decimalPlaces\n : col.thousandSeparator\n : col.decimalSeparator\n }}\n </ng-container>\n <ng-template #normalOutput>\n {{ data[col.code!] }}\n </ng-template>\n </ng-template>\n </p-cellEditor>\n </ng-template>\n </td>\n\n <!-- NON-EDITABLE CELL (ALWAYS RENDERED) -->\n <ng-template #normalTD>\n <td\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [ngClass]=\"[\n getDataAlignClass(col),\n col.type === TableTypeEnum.ACTION ? 'action-column' : ''\n ]\"\n >\n <!-- ACTION column: built-in edit/delete + custom actions -->\n <ng-container\n *ngIf=\"col.type === TableTypeEnum.ACTION; else nonActionCell\"\n >\n <div class=\"action-buttons-container\">\n <!-- built-in delete -->\n <button\n *ngIf=\"isDelete\"\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-trash\"\n (click)=\"Delete(data.id)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n\n <!-- built-in inline edit (old behaviour) -->\n <div *ngIf=\"isEdit\">\n <button\n pInitEditableRow\n *ngIf=\"!editing\"\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-pencil\"\n (click)=\"initEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n <button\n *ngIf=\"editing\"\n pSaveEditableRow\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-check\"\n (click)=\"saveEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n <button\n *ngIf=\"editing\"\n pCancelEditableRow\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-times\"\n (click)=\"cancelEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n </div>\n\n <!-- custom actions -->\n <button\n *ngFor=\"let act of customActions\"\n pButton\n pRipple\n type=\"button\"\n class=\"p-button-rounded p-button-text\"\n [icon]=\"act.icon || 'pi pi-ellipsis-h'\"\n [ngClass]=\"act.styleClass\"\n (click)=\"onCustomActionClick(act, data)\"\n ></button>\n </div>\n </ng-container>\n\n <!-- NON-ACTION cells -->\n <ng-template #nonActionCell>\n <!-- COMPOSED -->\n <ng-container\n *ngIf=\"\n col.type === TableTypeEnum.COMPOSED;\n else nonComposed\n \"\n >\n <div class=\"composed-cell\">\n <ng-container\n *ngFor=\"\n let composedName of col.composedNames;\n let i = index\n \"\n >\n <!-- IMAGE -->\n <ng-container\n *ngIf=\"\n col.composedTypes &&\n col.composedTypes[i] === TableTypeEnum.IMAGE\n \"\n >\n <img\n [src]=\"data[col.code!]?.[composedName]\"\n alt=\"composed-img\"\n class=\"composed-image\"\n [ngStyle]=\"\n getImageStyle(col.composedStyles?.[composedName])\n \"\n />\n </ng-container>\n\n <!-- STRING -->\n <ng-container\n *ngIf=\"\n col.composedTypes &&\n col.composedTypes[i] === TableTypeEnum.STRING\n \"\n >\n <span\n class=\"composed-text\"\n [ngStyle]=\"\n getTitleStyle(\n col.composedStyles?.[composedName]\n )\n \"\n >\n {{ data[col.code!]?.[composedName] }}\n </span>\n </ng-container>\n </ng-container>\n </div>\n </ng-container>\n\n <ng-template #nonComposed>\n <!-- AMOUNT-->\n <ng-container\n *ngIf=\"col.type === TableTypeEnum.AMOUNT; else nonAmount\"\n >\n {{\n data[col.code!]\n | customCurrency\n : getCurrencySymbol(col)\n : col.decimalPlaces\n : col.thousandSeparator\n : col.decimalSeparator\n }}\n </ng-container>\n\n <ng-template #nonAmount>\n <!-- NUMBER-->\n <ng-container\n *ngIf=\"\n col.type === TableTypeEnum.NUMBER;\n else nonNumber\n \"\n >\n {{\n formatNumber(\n data[col.code!],\n col.decimalPlaces,\n col.thousandSeparator,\n col.decimalSeparator\n )\n }}\n </ng-container>\n\n <ng-template #nonNumber>\n <!-- DATE -->\n <ng-container\n *ngIf=\"\n col.type === TableTypeEnum.DATE;\n else normalTypes\n \"\n >\n {{ formatDate(data[col.code!]) }}\n </ng-container>\n\n <ng-template #normalTypes>\n <!-- STRING, MULTISELECT-->\n <ng-container\n *ngIf=\"\n [\n TableTypeEnum.STRING,\n TableTypeEnum.MULTISELECT\n ].includes(col.type!)\n \"\n >\n {{ data[col.code!] }}\n </ng-container>\n </ng-template>\n </ng-template>\n </ng-template>\n </ng-template>\n </ng-template>\n </td>\n </ng-template>\n </ng-container>\n\n <!-- CHILD COLUMNS -->\n <ng-template #childColumns>\n <ng-container *ngFor=\"let child of col.children\">\n <td\n [style.width]=\"child.width || getHeaderWidth(child)\"\n [ngClass]=\"getDataAlignClass(child)\"\n >\n <ng-container\n *ngIf=\"isEditable(child.code); else childNormalTD\"\n >\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <input\n pInputText\n type=\"text\"\n [ngModel]=\"child.code ? data[child.code] : null\"\n (change)=\"onChange($event, data.id, child.code)\"\n />\n </ng-template>\n <ng-template pTemplate=\"output\">\n {{ child.code ? data[child.code] : \"\" }}\n </ng-template>\n </p-cellEditor>\n </ng-container>\n\n <ng-template #childNormalTD>\n {{ child.code ? data[child.code] : \"\" }}\n </ng-template>\n </td>\n </ng-container>\n </ng-template>\n </ng-container>\n </tr>\n </ng-template>\n </p-table>\n</div>\n", styles: [".pt-advanced-prime-table .bread-crumb{margin-bottom:15px}.pt-advanced-prime-table .date{width:100%;height:5rem;display:grid;justify-items:start;align-items:center}.pt-advanced-prime-table .filter-container{width:100%;display:flex;justify-content:space-between;align-items:center}.pt-advanced-prime-table .settings{display:flex;gap:1rem}.pt-advanced-prime-table .multi-select-container{display:flex;justify-content:center;align-items:center;gap:.3rem}.pt-advanced-prime-table ::ng-deep p-table{min-width:50rem}.pt-advanced-prime-table ::ng-deep .custom-multiselect .p-hidden-accessible input{display:none}.pt-advanced-prime-table ::ng-deep .p-datatable .p-sortable-column.p-highlight:hover{background:none}.pt-advanced-prime-table ::ng-deep .p-datatable .p-sortable-column:focus{box-shadow:none;outline:0 none}.pt-advanced-prime-table ::ng-deep .header-container{display:flex;justify-content:space-between;align-items:center;width:100%}.pt-advanced-prime-table ::ng-deep .header-title-left,.pt-advanced-prime-table ::ng-deep .header-title-center,.pt-advanced-prime-table ::ng-deep .header-title-right{flex:1}.pt-advanced-prime-table ::ng-deep .header-title-left{text-align:left}.pt-advanced-prime-table ::ng-deep .header-title-center{text-align:center}.pt-advanced-prime-table ::ng-deep .header-title-right{text-align:right}.pt-advanced-prime-table ::ng-deep .header-align-left{text-align:left}.pt-advanced-prime-table ::ng-deep .header-align-center{text-align:center}.pt-advanced-prime-table ::ng-deep .header-align-right{text-align:right}.pt-advanced-prime-table ::ng-deep p-columnfilter.p-element.ng-star-inserted{margin-top:4px}.pt-advanced-prime-table .flex{display:flex;justify-content:space-between;align-items:center}.pt-advanced-prime-table .ml-auto{margin-left:auto}.pt-advanced-prime-table ::ng-deep p-inputicon{margin-right:-1.5rem;z-index:2;position:relative}.pt-advanced-prime-table ::ng-deep .p-inputtext{padding-left:1.7rem}.pt-advanced-prime-table ::ng-deep .bt-filter-btn button{cursor:pointer;margin-left:1rem}.pt-advanced-prime-table ::ng-deep .p-icon-field-left .p-input-icon:first-of-type{left:-1rem}.pt-advanced-prime-table .table-row{text-align:center;display:flex;gap:1rem;justify-content:center}.pt-advanced-prime-table ::ng-deep span.p-button-icon.pi.pi-file-excel{font-size:1.25em;color:green}.pt-advanced-prime-table ::ng-deep span.p-button-icon.pi.pi-file-pdf{font-size:1.25em;color:red}.pt-advanced-prime-table .table-container{display:block;width:100%}.pt-advanced-prime-table .empty-message{text-align:center;padding:2rem;color:#888;font-size:1.2rem}.pt-advanced-prime-table .empty-message i{display:block;font-size:2rem;margin-bottom:.5rem}.pt-advanced-prime-table th{white-space:normal;word-wrap:break-word}.filter-image{width:22px;height:14px;margin-right:5px}.pt-advanced-prime-table ::ng-deep .p-datatable-tbody>tr>td.cell-align-left{text-align:left!important}.pt-advanced-prime-table ::ng-deep .p-datatable-tbody>tr>td.cell-align-center{text-align:center!important}.pt-advanced-prime-table ::ng-deep .p-datatable-tbody>tr>td.cell-align-right{text-align:right!important}.pt-advanced-prime-table ::ng-deep th.action-column,.pt-advanced-prime-table ::ng-deep td.action-column{text-align:center!important;justify-content:center;align-items:center;overflow:hidden;white-space:nowrap;padding:0}.pt-advanced-prime-table ::ng-deep .action-buttons-container{width:100%;display:flex;justify-content:center!important;align-items:center!important;gap:.35rem}.pt-advanced-prime-table ::ng-deep .action-buttons-container .p-button.p-button-rounded.p-button-text{padding:.25rem!important;min-width:22px!important;height:22px!important}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i2.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: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i2.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "component", type: i2.CellEditor, selector: "p-cellEditor" }, { kind: "component", type: i2.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "directive", type: i2.EditableRow, selector: "[pEditableRow]", inputs: ["pEditableRow", "pEditableRowDisabled"] }, { kind: "directive", type: i2.InitEditableRow, selector: "[pInitEditableRow]" }, { kind: "directive", type: i2.SaveEditableRow, selector: "[pSaveEditableRow]" }, { kind: "directive", type: i2.CancelEditableRow, selector: "[pCancelEditableRow]" }, { kind: "component", type: i2.ColumnFilter, selector: "p-columnFilter", inputs: ["field", "type", "display", "showMenu", "matchMode", "operator", "showOperator", "showClearButton", "showApplyButton", "showMatchModes", "showAddButton", "hideOnClear", "placeholder", "matchModeOptions", "maxConstraints", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "locale", "localeMatcher", "currency", "currencyDisplay", "useGrouping", "showButtons", "ariaLabel"], outputs: ["onShow", "onHide"] }, { kind: "directive", type: i4.InputText, selector: "[pInputText]", inputs: ["variant"] }, { kind: "directive", type: i5.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "component", type: i6.Calendar, selector: "p-calendar", inputs: ["iconDisplay", "style", "styleClass", "inputStyle", "inputId", "name", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "disabled", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "icon", "appendTo", "readonlyInput", "shortYearCutoff", "monthNavigator", "yearNavigator", "hourFormat", "timeOnly", "stepYearPicker", "stepHour", "stepMinute", "stepSecond", "showSeconds", "required", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "variant", "minDate", "maxDate", "disabledDates", "disabledDays", "yearRange", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "locale", "view", "defaultDate"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i8.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: i9.Tag, selector: "p-tag", inputs: ["style", "styleClass", "severity", "value", "icon", "rounded"] }, { kind: "component", type: i10.IconField, selector: "p-iconField", inputs: ["iconPosition"] }, { kind: "component", type: i11.InputIcon, selector: "p-inputIcon", inputs: ["styleClass"] }, { kind: "pipe", type: i12.CustomCurrencyPipe, name: "customCurrency" }, { kind: "pipe", type: i13.CustomDatePipe, name: "customDate" }] }); }
676
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: PTAdvancedPrimeTableComponent, selector: "pt-advanced-prime-table", inputs: { data: "data", columns: "columns", totalRecords: "totalRecords", rowsPerPage: "rowsPerPage", hasSearchFilter: "hasSearchFilter", hasExportExcel: "hasExportExcel", hasExportPDF: "hasExportPDF", hasColumnFilter: "hasColumnFilter", isPaginated: "isPaginated", actions: "actions", isSortable: "isSortable", loading: "loading", maxHeight: "maxHeight" }, outputs: { search: "search", exportExcelEvent: "exportExcelEvent", exportPdfEvent: "exportPdfEvent", onPageChange: "onPageChange", onSortColumn: "onSortColumn", onFilterColumn: "onFilterColumn" }, viewQueries: [{ propertyName: "dt", first: true, predicate: ["dt"], descendants: true }], ngImport: i0, template: "<div class=\"pt-advanced-prime-table table-container\">\n <p-table\n #dt\n [value]=\"data\"\n [loading]=\"loading\"\n [rows]=\"rows\"\n [paginator]=\"isPaginated\"\n [globalFilterFields]=\"globalFilterFields\"\n [rowsPerPageOptions]=\"rowsPerPage\"\n [totalRecords]=\"totalRecords\"\n [lazy]=\"isPaginated\"\n dataKey=\"id\"\n styleClass=\"p-datatable-gridlines p-datatable-striped\"\n [scrollable]=\"true\"\n [scrollHeight]=\"maxHeight !== null ? maxHeight : undefined\"\n (onFilter)=\"filterColumn($event)\"\n (onPage)=\"changePage($event)\"\n (onSort)=\"sortColumn($event)\"\n >\n <!-- COLGROUP: sync header/body widths -->\n <ng-template pTemplate=\"colgroup\" let-columns>\n <colgroup>\n <col\n *ngFor=\"let col of columns\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n />\n </colgroup>\n </ng-template>\n\n <!-- CAPTION -->\n <ng-template pTemplate=\"caption\">\n <div class=\"flex\">\n <div>\n <h3>Total: {{ totalRecords }}</h3>\n </div>\n\n <div>\n <!-- Clear filters -->\n <button\n *ngIf=\"hasSearchFilter\"\n pButton\n icon=\"pi pi-filter-slash\"\n class=\"p-button-rounded p-button-text\"\n (click)=\"clear(dt)\"\n title=\"Clear filters\"\n ></button>\n\n <!-- Export to Excel Button -->\n <button\n *ngIf=\"hasExportExcel\"\n pButton\n icon=\"pi pi-file-excel\"\n class=\"p-button-rounded p-button-text\"\n (click)=\"exportExcel()\"\n title=\"Export to Excel\"\n ></button>\n\n <!-- Export to PDF Button -->\n <button\n *ngIf=\"hasExportPDF\"\n pButton\n icon=\"pi pi-file-pdf\"\n class=\"p-button-rounded p-button-text\"\n (click)=\"exportPdf()\"\n title=\"Export to PDF\"\n ></button>\n </div>\n\n <div class=\"ml-auto\" *ngIf=\"hasSearchFilter\">\n <p-iconField iconPosition=\"left\" class=\"ml-auto\">\n <p-inputIcon>\n <i class=\"pi pi-search\"></i>\n </p-inputIcon>\n <input\n pInputText\n type=\"text\"\n [(ngModel)]=\"searchValue\"\n (input)=\"filterGlobal($event)\"\n placeholder=\"Search keyword\"\n />\n </p-iconField>\n </div>\n </div>\n </ng-template>\n\n <!-- HEADER -->\n <ng-template pTemplate=\"header\">\n <tr class=\"sticky-header\">\n <ng-container *ngFor=\"let col of columns\">\n <th\n *ngIf=\"!col.children; else groupHeader\"\n pSortableColumn=\"{{ col.code }}\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n [ngClass]=\"[\n getHeaderAlignClass(col),\n col.type === TableTypeEnum.ACTION ? 'action-column' : ''\n ]\"\n colspan=\"1\"\n >\n <!-- SORTABLE HEADER -->\n <ng-container\n *ngIf=\"isSortable && col.isSortable !== false; else noSortHeader\"\n >\n <div\n class=\"header-container d-flex align-items-center justify-content-between\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n [style.margin]=\"'10px'\"\n >\n <span [ngClass]=\"getHeaderTitleClass(col)\">\n {{ col.title }}\n </span>\n <div\n class=\"icons d-flex align-items-center\"\n [style.width]=\"'77px'\"\n >\n <p-sortIcon field=\"{{ col.code }}\" />\n\n <!-- COLUMN FILTERS -->\n <ng-container\n *ngIf=\"hasColumnFilter && col.isFilter !== false\"\n >\n <!-- COMPOSED FILTER (uses built-in Apply/Clear) -->\n <p-columnFilter\n *ngIf=\"col.type === TableTypeEnum.COMPOSED\"\n display=\"menu\"\n [field]=\"col.code\"\n type=\"text\"\n [showApplyButton]=\"true\"\n [showClearButton]=\"true\"\n (onClear)=\"onComposedColumnClear(col)\"\n >\n <ng-template\n pTemplate=\"filter\"\n let-filter=\"filterCallback\"\n let-filterModel=\"filterModel\"\n >\n <div *ngFor=\"let composedName of col.composedNames\">\n <ng-container\n *ngIf=\"\n getComposedFieldType(col, composedName) ===\n TableTypeEnum.STRING\n \"\n >\n <p-multiSelect\n [options]=\"filters[composedName]?.options\"\n [ngModel]=\"filters[composedName]?.value\"\n (ngModelChange)=\"\n onComposedFilterValueChange(\n col,\n composedName,\n $event,\n filterModel\n )\n \"\n [placeholder]=\"filters[composedName]?.placeholder\"\n display=\"chip\"\n >\n <ng-template let-item pTemplate=\"item\">\n <div class=\"custom-multiselect-item\">\n <img\n *ngIf=\"item.image\"\n [src]=\"item.image\"\n alt=\"icon\"\n class=\"filter-image\"\n />\n <span>{{ item.label }}</span>\n </div>\n </ng-template>\n </p-multiSelect>\n </ng-container>\n </div>\n </ng-template>\n </p-columnFilter>\n\n <!-- OTHER TYPES -->\n <p-columnFilter\n *ngIf=\"col.type !== TableTypeEnum.COMPOSED\"\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n [showApplyButton]=\"true\"\n [showClearButton]=\"true\"\n >\n <!-- NUMBER -->\n <ng-template\n pTemplate=\"filter\"\n *ngIf=\"col.type === TableTypeEnum.NUMBER\"\n let-filterModel=\"filterModel\"\n >\n <input\n pInputText\n type=\"number\"\n [step]=\"\n col.decimalPlaces\n ? '0.' + '1'.padEnd(col.decimalPlaces, '0')\n : 'any'\n \"\n [ngModel]=\"\n latestFilterValues[col.code!] ?? filterModel?.value\n \"\n (ngModelChange)=\"\n onFilterValueChange(col.code!, filterModel, $event)\n \"\n placeholder=\"Enter a number\"\n />\n </ng-template>\n\n <!-- DATE -->\n <ng-template\n pTemplate=\"filter\"\n *ngIf=\"col.type === TableTypeEnum.DATE\"\n let-filterModel=\"filterModel\"\n >\n <p-calendar\n [ngModel]=\"\n latestFilterValues[col.code!] ?? filterModel?.value\n \"\n (ngModelChange)=\"\n onFilterValueChange(col.code!, filterModel, $event)\n \"\n dateFormat=\"dd/mm/yy\"\n placeholder=\"Choose a date\"\n ></p-calendar>\n </ng-template>\n\n <!-- MULTISELECT -->\n <ng-template\n pTemplate=\"filter\"\n *ngIf=\"\n col.type === TableTypeEnum.MULTISELECT &&\n col.filterOptions &&\n col.filterOptions.length > 0\n \"\n let-filterModel=\"filterModel\"\n >\n <p-multiSelect\n [options]=\"col.filterOptions\"\n [ngModel]=\"\n latestFilterValues[col.code!] ?? filterModel?.value\n \"\n (ngModelChange)=\"\n onFilterValueChange(col.code!, filterModel, $event)\n \"\n display=\"chip\"\n placeholder=\"Choose option\"\n class=\"custom-multiselect\"\n ></p-multiSelect>\n </ng-template>\n </p-columnFilter>\n </ng-container>\n </div>\n </div>\n </ng-container>\n\n <!-- NON-SORTABLE HEADER -->\n <ng-template #noSortHeader>\n <div\n class=\"header-container d-flex align-items-center justify-content-between\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n [style.margin]=\"'10px'\"\n >\n <span [ngClass]=\"getHeaderTitleClass(col)\">\n {{ col.title }}\n </span>\n\n <ng-container *ngIf=\"hasColumnFilter && col.isFilter !== false\">\n <!-- AMOUNT behaves like NUMBER -->\n <p-columnFilter\n *ngIf=\"col.type === 'AMOUNT'\"\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n [currency]=\"getCurrencySymbol(col)\"\n [showApplyButton]=\"true\"\n [showClearButton]=\"true\"\n >\n <ng-template\n pTemplate=\"filter\"\n let-filterModel=\"filterModel\"\n >\n <input\n pInputText\n type=\"number\"\n [step]=\"\n col.decimalPlaces\n ? '0.' + '1'.padEnd(col.decimalPlaces, '0')\n : 'any'\n \"\n [ngModel]=\"\n latestFilterValues[col.code!] ?? filterModel?.value\n \"\n (ngModelChange)=\"\n onFilterValueChange(col.code!, filterModel, $event)\n \"\n placeholder=\"Enter an amount\"\n />\n </ng-template>\n </p-columnFilter>\n\n <p-columnFilter\n *ngIf=\"col.type !== 'AMOUNT'\"\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n [showApplyButton]=\"true\"\n [showClearButton]=\"true\"\n >\n <!-- DATE -->\n <ng-template\n pTemplate=\"filter\"\n let-filterModel=\"filterModel\"\n *ngIf=\"getColumnFilterType(col) === 'date'\"\n >\n <p-calendar\n [ngModel]=\"\n latestFilterValues[col.code!] ?? filterModel?.value\n \"\n (ngModelChange)=\"\n onFilterValueChange(col.code!, filterModel, $event)\n \"\n dateFormat=\"dd/mm/yy\"\n ></p-calendar>\n </ng-template>\n\n <!-- MULTISELECT -->\n <ng-template\n pTemplate=\"filter\"\n let-filterModel=\"filterModel\"\n *ngIf=\"getColumnFilterType(col) === 'multiSelect'\"\n >\n <p-multiSelect\n [options]=\"col.filterOptions\"\n [ngModel]=\"\n latestFilterValues[col.code!] ?? filterModel?.value\n \"\n (ngModelChange)=\"\n onFilterValueChange(col.code!, filterModel, $event)\n \"\n display=\"chip\"\n placeholder=\"Select\"\n class=\"custom-multiselect\"\n ></p-multiSelect>\n </ng-template>\n </p-columnFilter>\n </ng-container>\n </div>\n </ng-template>\n </th>\n\n <!-- GROUPED HEADER -->\n <ng-template #groupHeader>\n <th\n [attr.colspan]=\"col.children?.length\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [ngClass]=\"getHeaderAlignClass(col)\"\n >\n <span>{{ col.title }}</span>\n </th>\n </ng-template>\n </ng-container>\n </tr>\n\n <!-- CHILD HEADERS -->\n <tr *ngIf=\"hasGroupedColumns\">\n <ng-container *ngFor=\"let col of columns\">\n <ng-container *ngIf=\"col.children\">\n <th\n *ngFor=\"let child of col.children\"\n [style.width]=\"child.width || getHeaderWidth(child)\"\n [style.padding]=\"'0px'\"\n ></th>\n </ng-container>\n </ng-container>\n </tr>\n </ng-template>\n\n <!-- EMPTY MESSAGE -->\n <ng-template pTemplate=\"emptymessage\">\n <tr class=\"p-datatable-emptymessage\">\n <!-- span all columns -->\n <td class=\"empty-message-cell\" [attr.colspan]=\"columns.length || 1\">\n <div class=\"empty-message-wrapper\">\n <div class=\"empty-message\">\n <i class=\"pi pi-info-circle\"></i>\n <p>No records available to display.</p>\n </div>\n </div>\n </td>\n </tr>\n </ng-template>\n\n <!-- BODY -->\n <ng-template\n pTemplate=\"body\"\n let-data\n let-editing=\"editing\"\n let-ri=\"rowIndex\"\n >\n <tr *ngIf=\"!loading\" [pEditableRow]=\"isEdit ? data : null\">\n <ng-container *ngFor=\"let col of columns\">\n <!-- SIMPLE COLUMNS (no children) -->\n <ng-container *ngIf=\"!col.children; else childColumns\">\n <!-- EDITABLE CELL -->\n <td\n *ngIf=\"\n isEditable(col.code!) && col.type !== TableTypeEnum.ACTION;\n else normalTD\n \"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [ngClass]=\"getDataAlignClass(col)\"\n >\n <!-- Editable input for NUMBER/DATE/STRING/MULTISELECT -->\n <ng-container *ngIf=\"isMultiSelect(col.code); else datePicker\">\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <p-multiSelect\n appendTo=\"body\"\n [ngModel]=\"data[col.code!]\"\n [style]=\"{ width: '100%' }\"\n (ngModelChange)=\"changeHandler(data.id, col.code, $event)\"\n [options]=\"optionValues\"\n ></p-multiSelect>\n </ng-template>\n <ng-template pTemplate=\"output\">\n <div class=\"multi-select-container\">\n <ng-container *ngFor=\"let rec of data[col.code!]\">\n <p-tag [value]=\"rec\"></p-tag>\n </ng-container>\n </div>\n </ng-template>\n </p-cellEditor>\n </ng-container>\n\n <ng-template #datePicker>\n <ng-container *ngIf=\"isDatePicker(col.code); else normalInput\">\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <p-calendar\n [inputId]=\"data[col.code!]\"\n [ngModel]=\"data[col.code!]\"\n (ngModelChange)=\"\n changeHandler(data.id, col.code, $event)\n \"\n [dateFormat]=\"'dd/mm/yy'\"\n ></p-calendar>\n </ng-template>\n <ng-template pTemplate=\"output\">\n {{ data[col.code!] | customDate }}\n </ng-template>\n </p-cellEditor>\n </ng-container>\n </ng-template>\n\n <ng-template #normalInput>\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <input\n pInputText\n type=\"text\"\n [ngModel]=\"data[col.code!]\"\n (change)=\"onChange($event, data.id, col.code)\"\n />\n </ng-template>\n <ng-template pTemplate=\"output\">\n <ng-container\n *ngIf=\"\n col.type === TableTypeEnum.AMOUNT;\n else normalOutput\n \"\n >\n {{\n data[col.code!]\n | customCurrency\n : getCurrencySymbol(col)\n : col.decimalPlaces\n : col.thousandSeparator\n : col.decimalSeparator\n }}\n </ng-container>\n <ng-template #normalOutput>\n {{ data[col.code!] }}\n </ng-template>\n </ng-template>\n </p-cellEditor>\n </ng-template>\n </td>\n\n <!-- NON-EDITABLE CELL (ALWAYS RENDERED) -->\n <ng-template #normalTD>\n <td\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [ngClass]=\"[\n getDataAlignClass(col),\n col.type === TableTypeEnum.ACTION ? 'action-column' : ''\n ]\"\n >\n <!-- ACTION column: built-in edit/delete + custom actions -->\n <ng-container\n *ngIf=\"col.type === TableTypeEnum.ACTION; else nonActionCell\"\n >\n <div class=\"action-buttons-container\">\n <!-- built-in delete -->\n <button\n *ngIf=\"isDelete\"\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-trash\"\n (click)=\"Delete(data.id)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n\n <!-- built-in inline edit -->\n <div *ngIf=\"isEdit\">\n <button\n pInitEditableRow\n *ngIf=\"!editing\"\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-pencil\"\n (click)=\"initEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n <button\n *ngIf=\"editing\"\n pSaveEditableRow\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-check\"\n (click)=\"saveEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n <button\n *ngIf=\"editing\"\n pCancelEditableRow\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-times\"\n (click)=\"cancelEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n </div>\n\n <!-- custom actions -->\n <button\n *ngFor=\"let act of customActions\"\n pButton\n pRipple\n type=\"button\"\n class=\"p-button-rounded p-button-text\"\n [icon]=\"act.icon || 'pi pi-ellipsis-h'\"\n [ngClass]=\"act.styleClass\"\n (click)=\"onCustomActionClick(act, data)\"\n ></button>\n </div>\n </ng-container>\n\n <!-- NON-ACTION cells -->\n <ng-template #nonActionCell>\n <!-- COMPOSED -->\n <ng-container\n *ngIf=\"\n col.type === TableTypeEnum.COMPOSED;\n else nonComposed\n \"\n >\n <div class=\"composed-cell\">\n <ng-container\n *ngFor=\"\n let composedName of col.composedNames;\n let i = index\n \"\n >\n <!-- IMAGE -->\n <ng-container\n *ngIf=\"\n col.composedTypes &&\n col.composedTypes[i] === TableTypeEnum.IMAGE\n \"\n >\n <img\n [src]=\"data[col.code!]?.[composedName]\"\n alt=\"composed-img\"\n class=\"composed-image\"\n [ngStyle]=\"\n getImageStyle(col.composedStyles?.[composedName])\n \"\n />\n </ng-container>\n\n <!-- STRING -->\n <ng-container\n *ngIf=\"\n col.composedTypes &&\n col.composedTypes[i] === TableTypeEnum.STRING\n \"\n >\n <span\n class=\"composed-text\"\n [ngStyle]=\"\n getTitleStyle(\n col.composedStyles?.[composedName]\n )\n \"\n >\n {{ data[col.code!]?.[composedName] }}\n </span>\n </ng-container>\n </ng-container>\n </div>\n </ng-container>\n\n <ng-template #nonComposed>\n <!-- AMOUNT-->\n <ng-container\n *ngIf=\"col.type === TableTypeEnum.AMOUNT; else nonAmount\"\n >\n {{\n data[col.code!]\n | customCurrency\n : getCurrencySymbol(col)\n : col.decimalPlaces\n : col.thousandSeparator\n : col.decimalSeparator\n }}\n </ng-container>\n\n <ng-template #nonAmount>\n <!-- NUMBER-->\n <ng-container\n *ngIf=\"\n col.type === TableTypeEnum.NUMBER;\n else nonNumber\n \"\n >\n {{\n formatNumber(\n data[col.code!],\n col.decimalPlaces,\n col.thousandSeparator,\n col.decimalSeparator\n )\n }}\n </ng-container>\n\n <ng-template #nonNumber>\n <!-- DATE -->\n <ng-container\n *ngIf=\"\n col.type === TableTypeEnum.DATE;\n else normalTypes\n \"\n >\n {{ formatDate(data[col.code!]) }}\n </ng-container>\n\n <ng-template #normalTypes>\n <!-- STRING, MULTISELECT-->\n <ng-container\n *ngIf=\"\n [\n TableTypeEnum.STRING,\n TableTypeEnum.MULTISELECT\n ].includes(col.type!)\n \"\n >\n {{ data[col.code!] }}\n </ng-container>\n </ng-template>\n </ng-template>\n </ng-template>\n </ng-template>\n </ng-template>\n </td>\n </ng-template>\n </ng-container>\n\n <!-- CHILD COLUMNS -->\n <ng-template #childColumns>\n <ng-container *ngFor=\"let child of col.children\">\n <td\n [style.width]=\"child.width || getHeaderWidth(child)\"\n [ngClass]=\"getDataAlignClass(child)\"\n >\n <ng-container\n *ngIf=\"isEditable(child.code); else childNormalTD\"\n >\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <input\n pInputText\n type=\"text\"\n [ngModel]=\"child.code ? data[child.code] : null\"\n (change)=\"onChange($event, data.id, child.code)\"\n />\n </ng-template>\n <ng-template pTemplate=\"output\">\n {{ child.code ? data[child.code] : \"\" }}\n </ng-template>\n </p-cellEditor>\n </ng-container>\n\n <ng-template #childNormalTD>\n {{ child.code ? data[child.code] : \"\" }}\n </ng-template>\n </td>\n </ng-container>\n </ng-template>\n </ng-container>\n </tr>\n </ng-template>\n </p-table>\n</div>\n", styles: [".pt-advanced-prime-table .bread-crumb{margin-bottom:15px}.pt-advanced-prime-table .date{width:100%;height:5rem;display:grid;justify-items:start;align-items:center}.pt-advanced-prime-table .filter-container{width:100%;display:flex;justify-content:space-between;align-items:center}.pt-advanced-prime-table .settings{display:flex;gap:1rem}.pt-advanced-prime-table .multi-select-container{display:flex;justify-content:center;align-items:center;gap:.3rem}.pt-advanced-prime-table ::ng-deep p-table{min-width:50rem}.pt-advanced-prime-table ::ng-deep .custom-multiselect .p-hidden-accessible input{display:none}.pt-advanced-prime-table ::ng-deep .p-datatable .p-sortable-column.p-highlight:hover{background:none}.pt-advanced-prime-table ::ng-deep .p-datatable .p-sortable-column:focus{box-shadow:none;outline:0 none}.pt-advanced-prime-table ::ng-deep .header-container{display:flex;justify-content:space-between;align-items:center;width:100%}.pt-advanced-prime-table ::ng-deep .header-title-left,.pt-advanced-prime-table ::ng-deep .header-title-center,.pt-advanced-prime-table ::ng-deep .header-title-right{flex:1}.pt-advanced-prime-table ::ng-deep .header-title-left{text-align:left}.pt-advanced-prime-table ::ng-deep .header-title-center{text-align:center}.pt-advanced-prime-table ::ng-deep .header-title-right{text-align:right}.pt-advanced-prime-table ::ng-deep .header-align-left{text-align:left}.pt-advanced-prime-table ::ng-deep .header-align-center{text-align:center}.pt-advanced-prime-table ::ng-deep .header-align-right{text-align:right}.pt-advanced-prime-table ::ng-deep p-columnfilter.p-element.ng-star-inserted{margin-top:4px}.pt-advanced-prime-table .flex{display:flex;justify-content:space-between;align-items:center}.pt-advanced-prime-table .ml-auto{margin-left:auto}.pt-advanced-prime-table ::ng-deep p-inputicon{margin-right:-1.5rem;z-index:2;position:relative}.pt-advanced-prime-table ::ng-deep .p-inputtext{padding-left:1.7rem}.pt-advanced-prime-table ::ng-deep .bt-filter-btn button{cursor:pointer;margin-left:1rem}.pt-advanced-prime-table ::ng-deep .p-icon-field-left .p-input-icon:first-of-type{left:-1rem}.pt-advanced-prime-table .table-row{text-align:center;display:flex;gap:1rem;justify-content:center}.pt-advanced-prime-table ::ng-deep span.p-button-icon.pi.pi-file-excel{font-size:1.25em;color:green}.pt-advanced-prime-table ::ng-deep span.p-button-icon.pi.pi-file-pdf{font-size:1.25em;color:red}.pt-advanced-prime-table .table-container{display:block;width:100%}.pt-advanced-prime-table ::ng-deep .p-datatable-emptymessage>td.empty-message-cell{padding:0!important}.pt-advanced-prime-table .empty-message-wrapper{width:100%;height:100%;min-height:180px;display:flex;align-items:center;justify-content:center}.pt-advanced-prime-table .empty-message{text-align:center;color:#888;font-size:1.2rem}.pt-advanced-prime-table .empty-message i{display:block;font-size:2rem;margin-bottom:.5rem}.pt-advanced-prime-table th{white-space:normal;word-wrap:break-word}.filter-image{width:22px;height:14px;margin-right:5px}.pt-advanced-prime-table ::ng-deep .p-datatable-tbody>tr>td.cell-align-left{text-align:left!important}.pt-advanced-prime-table ::ng-deep .p-datatable-tbody>tr>td.cell-align-center{text-align:center!important}.pt-advanced-prime-table ::ng-deep .p-datatable-tbody>tr>td.cell-align-right{text-align:right!important}.pt-advanced-prime-table ::ng-deep th.action-column,.pt-advanced-prime-table ::ng-deep td.action-column{text-align:center!important;justify-content:center;align-items:center;overflow:hidden;white-space:nowrap;padding:0}.pt-advanced-prime-table ::ng-deep .action-buttons-container{width:100%;display:flex;justify-content:center!important;align-items:center!important;gap:.35rem}.pt-advanced-prime-table ::ng-deep .action-buttons-container .p-button.p-button-rounded.p-button-text{padding:.25rem!important;min-width:22px!important;height:22px!important}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i2.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: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i2.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "component", type: i2.CellEditor, selector: "p-cellEditor" }, { kind: "component", type: i2.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "directive", type: i2.EditableRow, selector: "[pEditableRow]", inputs: ["pEditableRow", "pEditableRowDisabled"] }, { kind: "directive", type: i2.InitEditableRow, selector: "[pInitEditableRow]" }, { kind: "directive", type: i2.SaveEditableRow, selector: "[pSaveEditableRow]" }, { kind: "directive", type: i2.CancelEditableRow, selector: "[pCancelEditableRow]" }, { kind: "component", type: i2.ColumnFilter, selector: "p-columnFilter", inputs: ["field", "type", "display", "showMenu", "matchMode", "operator", "showOperator", "showClearButton", "showApplyButton", "showMatchModes", "showAddButton", "hideOnClear", "placeholder", "matchModeOptions", "maxConstraints", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "locale", "localeMatcher", "currency", "currencyDisplay", "useGrouping", "showButtons", "ariaLabel"], outputs: ["onShow", "onHide"] }, { kind: "directive", type: i4.InputText, selector: "[pInputText]", inputs: ["variant"] }, { kind: "directive", type: i5.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "component", type: i6.Calendar, selector: "p-calendar", inputs: ["iconDisplay", "style", "styleClass", "inputStyle", "inputId", "name", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "disabled", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "icon", "appendTo", "readonlyInput", "shortYearCutoff", "monthNavigator", "yearNavigator", "hourFormat", "timeOnly", "stepYearPicker", "stepHour", "stepMinute", "stepSecond", "showSeconds", "required", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "variant", "minDate", "maxDate", "disabledDates", "disabledDays", "yearRange", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "locale", "view", "defaultDate"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i8.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: i9.Tag, selector: "p-tag", inputs: ["style", "styleClass", "severity", "value", "icon", "rounded"] }, { kind: "component", type: i10.IconField, selector: "p-iconField", inputs: ["iconPosition"] }, { kind: "component", type: i11.InputIcon, selector: "p-inputIcon", inputs: ["styleClass"] }, { kind: "pipe", type: i12.CustomCurrencyPipe, name: "customCurrency" }, { kind: "pipe", type: i13.CustomDatePipe, name: "customDate" }] }); }
508
677
  }
509
678
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PTAdvancedPrimeTableComponent, decorators: [{
510
679
  type: Component,
511
- args: [{ selector: 'pt-advanced-prime-table', template: "<div class=\"pt-advanced-prime-table table-container\">\n <p-table\n #dt\n [value]=\"data\"\n [loading]=\"loading\"\n [rows]=\"rows\"\n [paginator]=\"isPaginated\"\n [globalFilterFields]=\"globalFilterFields\"\n [rowsPerPageOptions]=\"rowsPerPage\"\n [totalRecords]=\"totalRecords\"\n [lazy]=\"true\"\n dataKey=\"id\"\n styleClass=\"p-datatable-gridlines p-datatable-striped\"\n [scrollable]=\"true\"\n [scrollHeight]=\"maxHeight !== null ? maxHeight : undefined\"\n (onFilter)=\"onFilter($event)\"\n (onPage)=\"onPageChange($event)\"\n >\n <!-- COLGROUP: sync header/body widths (incl. Actions 410px) -->\n <ng-template pTemplate=\"colgroup\" let-columns>\n <colgroup>\n <col\n *ngFor=\"let col of columns\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n />\n </colgroup>\n </ng-template>\n\n <!-- CAPTION -->\n <ng-template pTemplate=\"caption\">\n <div class=\"flex\">\n <div>\n <h3>Total: {{ totalRecords }}</h3>\n </div>\n\n <div>\n <!-- Clear filters -->\n <button\n *ngIf=\"hasSearchFilter\"\n pButton\n icon=\"pi pi-filter-slash\"\n class=\"p-button-rounded p-button-text\"\n (click)=\"clear(dt)\"\n title=\"Clear filters\"\n ></button>\n\n <!-- Export to Excel Button -->\n <button\n *ngIf=\"hasExportExcel\"\n pButton\n icon=\"pi pi-file-excel\"\n class=\"p-button-rounded p-button-text\"\n (click)=\"exportExcel()\"\n title=\"Export to Excel\"\n ></button>\n\n <!-- Export to PDF Button -->\n <button\n *ngIf=\"hasExportPDF\"\n pButton\n icon=\"pi pi-file-pdf\"\n class=\"p-button-rounded p-button-text\"\n (click)=\"exportPdf()\"\n title=\"Export to PDF\"\n ></button>\n </div>\n\n <div class=\"ml-auto\" *ngIf=\"hasSearchFilter\">\n <p-iconField iconPosition=\"left\" class=\"ml-auto\">\n <p-inputIcon>\n <i class=\"pi pi-search\"></i>\n </p-inputIcon>\n <input\n pInputText\n type=\"text\"\n [(ngModel)]=\"searchValue\"\n (input)=\"filterGlobal($event)\"\n placeholder=\"Search keyword\"\n />\n </p-iconField>\n </div>\n </div>\n </ng-template>\n\n <!-- HEADER -->\n <ng-template pTemplate=\"header\">\n <tr class=\"sticky-header\">\n <ng-container *ngFor=\"let col of columns\">\n <th\n *ngIf=\"!col.children; else groupHeader\"\n pSortableColumn=\"{{ col.code }}\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n [ngClass]=\"[\n getHeaderAlignClass(col),\n col.type === TableTypeEnum.ACTION ? 'action-column' : ''\n ]\"\n colspan=\"1\"\n >\n <!-- SORTABLE HEADER -->\n <ng-container\n *ngIf=\"isSortable && col.isSortable !== false; else noSortHeader\"\n >\n <div\n class=\"header-container d-flex align-items-center justify-content-between\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n [style.margin]=\"'10px'\"\n >\n <span [ngClass]=\"getHeaderTitleClass(col)\">\n {{ col.title }}\n </span>\n <div\n class=\"icons d-flex align-items-center\"\n [style.width]=\"'77px'\"\n >\n <p-sortIcon field=\"{{ col.code }}\" />\n <ng-container *ngIf=\"col.isFilter !== false\">\n <!-- COMPOSED FILTER -->\n <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n *ngIf=\"col.type === TableTypeEnum.COMPOSED\"\n showClearButton=\"false\"\n showApplyButton=\"false\"\n >\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n (onFilter)=\"onFilter($event)\"\n >\n <div *ngFor=\"let composedName of col.composedNames\">\n <ng-container\n *ngIf=\"\n getComposedFieldType(col, composedName) ===\n TableTypeEnum.STRING\n \"\n >\n <p-multiSelect\n [ngModel]=\"filters[composedName]?.value\"\n [options]=\"filters[composedName]?.options\"\n (onChange)=\"\n onComposedFilterChange(\n col,\n composedName,\n $event.value\n )\n \"\n [placeholder]=\"filters[composedName]?.placeholder\"\n [display]=\"'chip'\"\n >\n <ng-template let-item pTemplate=\"item\">\n <div class=\"custom-multiselect-item\">\n <img\n *ngIf=\"item.image\"\n [src]=\"item.image\"\n alt=\"icon\"\n class=\"filter-image\"\n />\n <span>{{ item.label }}</span>\n </div>\n </ng-template>\n </p-multiSelect>\n </ng-container>\n </div>\n\n <ng-template let-item pTemplate=\"item\">\n <div class=\"custom-multiselect-item\">\n <img\n *ngIf=\"item.image\"\n [src]=\"item.image\"\n alt=\"icon\"\n class=\"filter-image\"\n />\n <span>{{ item.label }}</span>\n </div>\n </ng-template>\n </ng-template>\n </p-columnFilter>\n\n <!-- OTHER TYPES -->\n <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n *ngIf=\"col.type !== TableTypeEnum.COMPOSED\"\n hideOnClear=\"true\"\n >\n <!-- NUMBER -->\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"col.type === TableTypeEnum.NUMBER\"\n (onFilter)=\"onFilter($event)\"\n >\n <input\n pInputText\n type=\"number\"\n [step]=\"\n col.decimalPlaces\n ? '0.' + '1'.padEnd(col.decimalPlaces, '0')\n : 'any'\n \"\n [ngModel]=\"value\"\n (ngModelChange)=\"filterCallback($event)\"\n placeholder=\"Enter a number\"\n />\n </ng-template>\n\n <!-- DATE -->\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"col.type === TableTypeEnum.DATE\"\n (onFilter)=\"onFilter($event)\"\n >\n <p-calendar\n [ngModel]=\"value\"\n (ngModelChange)=\"\n onCalendarFilterChange(\n $event,\n col.code!,\n filterCallback\n )\n \"\n dateFormat=\"dd/mm/yy\"\n placeholder=\"Choose a date\"\n ></p-calendar>\n </ng-template>\n\n <!-- MULTISELECT -->\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"\n col.type === TableTypeEnum.MULTISELECT &&\n col.filterOptions &&\n col.filterOptions.length > 0\n \"\n (onFilter)=\"onFilter($event)\"\n >\n <p-multiSelect\n [options]=\"col.filterOptions\"\n [ngModel]=\"value\"\n (ngModelChange)=\"filterCallback($event)\"\n display=\"chip\"\n placeholder=\"Choose option\"\n class=\"custom-multiselect\"\n ></p-multiSelect>\n </ng-template>\n </p-columnFilter>\n </ng-container>\n </div>\n </div>\n </ng-container>\n\n <!-- NON-SORTABLE HEADER -->\n <ng-template #noSortHeader>\n <div\n class=\"header-container d-flex align-items-center justify-content-between\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n [style.margin]=\"'10px'\"\n >\n <span [ngClass]=\"getHeaderTitleClass(col)\">\n {{ col.title }}\n </span>\n <ng-container *ngIf=\"col.isFilter !== false\">\n <p-columnFilter\n *ngIf=\"col.type === 'AMOUNT'\"\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n [currency]=\"getCurrencySymbol(col)\"\n ></p-columnFilter>\n\n <p-columnFilter\n *ngIf=\"col.type !== 'AMOUNT'\"\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n >\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"getColumnFilterType(col) === 'date'\"\n >\n <p-calendar\n [ngModel]=\"value\"\n (ngModelChange)=\"filterCallback($event)\"\n dateFormat=\"dd/mm/yy\"\n ></p-calendar>\n </ng-template>\n\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"getColumnFilterType(col) === 'multiSelect'\"\n >\n <p-multiSelect\n [options]=\"col.filterOptions\"\n [ngModel]=\"value\"\n (ngModelChange)=\"filterCallback($event)\"\n display=\"chip\"\n placeholder=\"Select\"\n class=\"custom-multiselect\"\n ></p-multiSelect>\n </ng-template>\n </p-columnFilter>\n </ng-container>\n </div>\n </ng-template>\n </th>\n\n <!-- GROUPED HEADER -->\n <ng-template #groupHeader>\n <th\n [attr.colspan]=\"col.children?.length\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [ngClass]=\"getHeaderAlignClass(col)\"\n >\n <span>{{ col.title }}</span>\n </th>\n </ng-template>\n </ng-container>\n </tr>\n\n <!-- CHILD HEADERS -->\n <tr *ngIf=\"hasGroupedColumns\">\n <ng-container *ngFor=\"let col of columns\">\n <ng-container *ngIf=\"col.children\">\n <th\n *ngFor=\"let child of col.children\"\n [style.width]=\"child.width || getHeaderWidth(child)\"\n [style.padding]=\"'0px'\"\n ></th>\n </ng-container>\n </ng-container>\n </tr>\n </ng-template>\n\n <!-- EMPTY MESSAGE -->\n <ng-template pTemplate=\"emptymessage\">\n <div class=\"empty-message\">\n <i class=\"pi pi-info-circle\"></i>\n <p>No records available to display.</p>\n </div>\n </ng-template>\n\n <!-- BODY -->\n <ng-template\n pTemplate=\"body\"\n let-data\n let-editing=\"editing\"\n let-ri=\"rowIndex\"\n >\n <tr *ngIf=\"!loading\" [pEditableRow]=\"isEdit ? data : null\">\n <ng-container *ngFor=\"let col of columns\">\n <!-- SIMPLE COLUMNS (no children) -->\n <ng-container *ngIf=\"!col.children; else childColumns\">\n <!-- EDITABLE CELL -->\n <td\n *ngIf=\"\n isEditable(col.code!) && col.type !== TableTypeEnum.ACTION;\n else normalTD\n \"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [ngClass]=\"getDataAlignClass(col)\"\n >\n <!-- Editable input for NUMBER/DATE/STRING/MULTISELECT -->\n <ng-container *ngIf=\"isMultiSelect(col.code); else datePicker\">\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <p-multiSelect\n appendTo=\"body\"\n [ngModel]=\"data[col.code!]\"\n [style]=\"{ width: '100%' }\"\n (ngModelChange)=\"changeHandler(data.id, col.code, $event)\"\n [options]=\"optionValues\"\n ></p-multiSelect>\n </ng-template>\n <ng-template pTemplate=\"output\">\n <div class=\"multi-select-container\">\n <ng-container *ngFor=\"let rec of data[col.code!]\">\n <p-tag [value]=\"rec\"></p-tag>\n </ng-container>\n </div>\n </ng-template>\n </p-cellEditor>\n </ng-container>\n\n <ng-template #datePicker>\n <ng-container *ngIf=\"isDatePicker(col.code); else normalInput\">\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <p-calendar\n [inputId]=\"data[col.code!]\"\n [ngModel]=\"data[col.code!]\"\n (ngModelChange)=\"\n changeHandler(data.id, col.code, $event)\n \"\n [dateFormat]=\"'dd/mm/yy'\"\n ></p-calendar>\n </ng-template>\n <ng-template pTemplate=\"output\">\n {{ data[col.code!] | customDate }}\n </ng-template>\n </p-cellEditor>\n </ng-container>\n </ng-template>\n\n <ng-template #normalInput>\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <input\n pInputText\n type=\"text\"\n [ngModel]=\"data[col.code!]\"\n (change)=\"onChange($event, data.id, col.code)\"\n />\n </ng-template>\n <ng-template pTemplate=\"output\">\n <ng-container\n *ngIf=\"\n col.type === TableTypeEnum.AMOUNT;\n else normalOutput\n \"\n >\n {{\n data[col.code!]\n | customCurrency\n : getCurrencySymbol(col)\n : col.decimalPlaces\n : col.thousandSeparator\n : col.decimalSeparator\n }}\n </ng-container>\n <ng-template #normalOutput>\n {{ data[col.code!] }}\n </ng-template>\n </ng-template>\n </p-cellEditor>\n </ng-template>\n </td>\n\n <!-- NON-EDITABLE CELL (ALWAYS RENDERED) -->\n <ng-template #normalTD>\n <td\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [ngClass]=\"[\n getDataAlignClass(col),\n col.type === TableTypeEnum.ACTION ? 'action-column' : ''\n ]\"\n >\n <!-- ACTION column: built-in edit/delete + custom actions -->\n <ng-container\n *ngIf=\"col.type === TableTypeEnum.ACTION; else nonActionCell\"\n >\n <div class=\"action-buttons-container\">\n <!-- built-in delete -->\n <button\n *ngIf=\"isDelete\"\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-trash\"\n (click)=\"Delete(data.id)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n\n <!-- built-in inline edit (old behaviour) -->\n <div *ngIf=\"isEdit\">\n <button\n pInitEditableRow\n *ngIf=\"!editing\"\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-pencil\"\n (click)=\"initEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n <button\n *ngIf=\"editing\"\n pSaveEditableRow\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-check\"\n (click)=\"saveEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n <button\n *ngIf=\"editing\"\n pCancelEditableRow\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-times\"\n (click)=\"cancelEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n </div>\n\n <!-- custom actions -->\n <button\n *ngFor=\"let act of customActions\"\n pButton\n pRipple\n type=\"button\"\n class=\"p-button-rounded p-button-text\"\n [icon]=\"act.icon || 'pi pi-ellipsis-h'\"\n [ngClass]=\"act.styleClass\"\n (click)=\"onCustomActionClick(act, data)\"\n ></button>\n </div>\n </ng-container>\n\n <!-- NON-ACTION cells -->\n <ng-template #nonActionCell>\n <!-- COMPOSED -->\n <ng-container\n *ngIf=\"\n col.type === TableTypeEnum.COMPOSED;\n else nonComposed\n \"\n >\n <div class=\"composed-cell\">\n <ng-container\n *ngFor=\"\n let composedName of col.composedNames;\n let i = index\n \"\n >\n <!-- IMAGE -->\n <ng-container\n *ngIf=\"\n col.composedTypes &&\n col.composedTypes[i] === TableTypeEnum.IMAGE\n \"\n >\n <img\n [src]=\"data[col.code!]?.[composedName]\"\n alt=\"composed-img\"\n class=\"composed-image\"\n [ngStyle]=\"\n getImageStyle(col.composedStyles?.[composedName])\n \"\n />\n </ng-container>\n\n <!-- STRING -->\n <ng-container\n *ngIf=\"\n col.composedTypes &&\n col.composedTypes[i] === TableTypeEnum.STRING\n \"\n >\n <span\n class=\"composed-text\"\n [ngStyle]=\"\n getTitleStyle(\n col.composedStyles?.[composedName]\n )\n \"\n >\n {{ data[col.code!]?.[composedName] }}\n </span>\n </ng-container>\n </ng-container>\n </div>\n </ng-container>\n\n <ng-template #nonComposed>\n <!-- AMOUNT-->\n <ng-container\n *ngIf=\"col.type === TableTypeEnum.AMOUNT; else nonAmount\"\n >\n {{\n data[col.code!]\n | customCurrency\n : getCurrencySymbol(col)\n : col.decimalPlaces\n : col.thousandSeparator\n : col.decimalSeparator\n }}\n </ng-container>\n\n <ng-template #nonAmount>\n <!-- NUMBER-->\n <ng-container\n *ngIf=\"\n col.type === TableTypeEnum.NUMBER;\n else nonNumber\n \"\n >\n {{\n formatNumber(\n data[col.code!],\n col.decimalPlaces,\n col.thousandSeparator,\n col.decimalSeparator\n )\n }}\n </ng-container>\n\n <ng-template #nonNumber>\n <!-- DATE -->\n <ng-container\n *ngIf=\"\n col.type === TableTypeEnum.DATE;\n else normalTypes\n \"\n >\n {{ formatDate(data[col.code!]) }}\n </ng-container>\n\n <ng-template #normalTypes>\n <!-- STRING, MULTISELECT-->\n <ng-container\n *ngIf=\"\n [\n TableTypeEnum.STRING,\n TableTypeEnum.MULTISELECT\n ].includes(col.type!)\n \"\n >\n {{ data[col.code!] }}\n </ng-container>\n </ng-template>\n </ng-template>\n </ng-template>\n </ng-template>\n </ng-template>\n </td>\n </ng-template>\n </ng-container>\n\n <!-- CHILD COLUMNS -->\n <ng-template #childColumns>\n <ng-container *ngFor=\"let child of col.children\">\n <td\n [style.width]=\"child.width || getHeaderWidth(child)\"\n [ngClass]=\"getDataAlignClass(child)\"\n >\n <ng-container\n *ngIf=\"isEditable(child.code); else childNormalTD\"\n >\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <input\n pInputText\n type=\"text\"\n [ngModel]=\"child.code ? data[child.code] : null\"\n (change)=\"onChange($event, data.id, child.code)\"\n />\n </ng-template>\n <ng-template pTemplate=\"output\">\n {{ child.code ? data[child.code] : \"\" }}\n </ng-template>\n </p-cellEditor>\n </ng-container>\n\n <ng-template #childNormalTD>\n {{ child.code ? data[child.code] : \"\" }}\n </ng-template>\n </td>\n </ng-container>\n </ng-template>\n </ng-container>\n </tr>\n </ng-template>\n </p-table>\n</div>\n", styles: [".pt-advanced-prime-table .bread-crumb{margin-bottom:15px}.pt-advanced-prime-table .date{width:100%;height:5rem;display:grid;justify-items:start;align-items:center}.pt-advanced-prime-table .filter-container{width:100%;display:flex;justify-content:space-between;align-items:center}.pt-advanced-prime-table .settings{display:flex;gap:1rem}.pt-advanced-prime-table .multi-select-container{display:flex;justify-content:center;align-items:center;gap:.3rem}.pt-advanced-prime-table ::ng-deep p-table{min-width:50rem}.pt-advanced-prime-table ::ng-deep .custom-multiselect .p-hidden-accessible input{display:none}.pt-advanced-prime-table ::ng-deep .p-datatable .p-sortable-column.p-highlight:hover{background:none}.pt-advanced-prime-table ::ng-deep .p-datatable .p-sortable-column:focus{box-shadow:none;outline:0 none}.pt-advanced-prime-table ::ng-deep .header-container{display:flex;justify-content:space-between;align-items:center;width:100%}.pt-advanced-prime-table ::ng-deep .header-title-left,.pt-advanced-prime-table ::ng-deep .header-title-center,.pt-advanced-prime-table ::ng-deep .header-title-right{flex:1}.pt-advanced-prime-table ::ng-deep .header-title-left{text-align:left}.pt-advanced-prime-table ::ng-deep .header-title-center{text-align:center}.pt-advanced-prime-table ::ng-deep .header-title-right{text-align:right}.pt-advanced-prime-table ::ng-deep .header-align-left{text-align:left}.pt-advanced-prime-table ::ng-deep .header-align-center{text-align:center}.pt-advanced-prime-table ::ng-deep .header-align-right{text-align:right}.pt-advanced-prime-table ::ng-deep p-columnfilter.p-element.ng-star-inserted{margin-top:4px}.pt-advanced-prime-table .flex{display:flex;justify-content:space-between;align-items:center}.pt-advanced-prime-table .ml-auto{margin-left:auto}.pt-advanced-prime-table ::ng-deep p-inputicon{margin-right:-1.5rem;z-index:2;position:relative}.pt-advanced-prime-table ::ng-deep .p-inputtext{padding-left:1.7rem}.pt-advanced-prime-table ::ng-deep .bt-filter-btn button{cursor:pointer;margin-left:1rem}.pt-advanced-prime-table ::ng-deep .p-icon-field-left .p-input-icon:first-of-type{left:-1rem}.pt-advanced-prime-table .table-row{text-align:center;display:flex;gap:1rem;justify-content:center}.pt-advanced-prime-table ::ng-deep span.p-button-icon.pi.pi-file-excel{font-size:1.25em;color:green}.pt-advanced-prime-table ::ng-deep span.p-button-icon.pi.pi-file-pdf{font-size:1.25em;color:red}.pt-advanced-prime-table .table-container{display:block;width:100%}.pt-advanced-prime-table .empty-message{text-align:center;padding:2rem;color:#888;font-size:1.2rem}.pt-advanced-prime-table .empty-message i{display:block;font-size:2rem;margin-bottom:.5rem}.pt-advanced-prime-table th{white-space:normal;word-wrap:break-word}.filter-image{width:22px;height:14px;margin-right:5px}.pt-advanced-prime-table ::ng-deep .p-datatable-tbody>tr>td.cell-align-left{text-align:left!important}.pt-advanced-prime-table ::ng-deep .p-datatable-tbody>tr>td.cell-align-center{text-align:center!important}.pt-advanced-prime-table ::ng-deep .p-datatable-tbody>tr>td.cell-align-right{text-align:right!important}.pt-advanced-prime-table ::ng-deep th.action-column,.pt-advanced-prime-table ::ng-deep td.action-column{text-align:center!important;justify-content:center;align-items:center;overflow:hidden;white-space:nowrap;padding:0}.pt-advanced-prime-table ::ng-deep .action-buttons-container{width:100%;display:flex;justify-content:center!important;align-items:center!important;gap:.35rem}.pt-advanced-prime-table ::ng-deep .action-buttons-container .p-button.p-button-rounded.p-button-text{padding:.25rem!important;min-width:22px!important;height:22px!important}\n"] }]
680
+ args: [{ selector: 'pt-advanced-prime-table', template: "<div class=\"pt-advanced-prime-table table-container\">\n <p-table\n #dt\n [value]=\"data\"\n [loading]=\"loading\"\n [rows]=\"rows\"\n [paginator]=\"isPaginated\"\n [globalFilterFields]=\"globalFilterFields\"\n [rowsPerPageOptions]=\"rowsPerPage\"\n [totalRecords]=\"totalRecords\"\n [lazy]=\"isPaginated\"\n dataKey=\"id\"\n styleClass=\"p-datatable-gridlines p-datatable-striped\"\n [scrollable]=\"true\"\n [scrollHeight]=\"maxHeight !== null ? maxHeight : undefined\"\n (onFilter)=\"filterColumn($event)\"\n (onPage)=\"changePage($event)\"\n (onSort)=\"sortColumn($event)\"\n >\n <!-- COLGROUP: sync header/body widths -->\n <ng-template pTemplate=\"colgroup\" let-columns>\n <colgroup>\n <col\n *ngFor=\"let col of columns\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n />\n </colgroup>\n </ng-template>\n\n <!-- CAPTION -->\n <ng-template pTemplate=\"caption\">\n <div class=\"flex\">\n <div>\n <h3>Total: {{ totalRecords }}</h3>\n </div>\n\n <div>\n <!-- Clear filters -->\n <button\n *ngIf=\"hasSearchFilter\"\n pButton\n icon=\"pi pi-filter-slash\"\n class=\"p-button-rounded p-button-text\"\n (click)=\"clear(dt)\"\n title=\"Clear filters\"\n ></button>\n\n <!-- Export to Excel Button -->\n <button\n *ngIf=\"hasExportExcel\"\n pButton\n icon=\"pi pi-file-excel\"\n class=\"p-button-rounded p-button-text\"\n (click)=\"exportExcel()\"\n title=\"Export to Excel\"\n ></button>\n\n <!-- Export to PDF Button -->\n <button\n *ngIf=\"hasExportPDF\"\n pButton\n icon=\"pi pi-file-pdf\"\n class=\"p-button-rounded p-button-text\"\n (click)=\"exportPdf()\"\n title=\"Export to PDF\"\n ></button>\n </div>\n\n <div class=\"ml-auto\" *ngIf=\"hasSearchFilter\">\n <p-iconField iconPosition=\"left\" class=\"ml-auto\">\n <p-inputIcon>\n <i class=\"pi pi-search\"></i>\n </p-inputIcon>\n <input\n pInputText\n type=\"text\"\n [(ngModel)]=\"searchValue\"\n (input)=\"filterGlobal($event)\"\n placeholder=\"Search keyword\"\n />\n </p-iconField>\n </div>\n </div>\n </ng-template>\n\n <!-- HEADER -->\n <ng-template pTemplate=\"header\">\n <tr class=\"sticky-header\">\n <ng-container *ngFor=\"let col of columns\">\n <th\n *ngIf=\"!col.children; else groupHeader\"\n pSortableColumn=\"{{ col.code }}\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n [ngClass]=\"[\n getHeaderAlignClass(col),\n col.type === TableTypeEnum.ACTION ? 'action-column' : ''\n ]\"\n colspan=\"1\"\n >\n <!-- SORTABLE HEADER -->\n <ng-container\n *ngIf=\"isSortable && col.isSortable !== false; else noSortHeader\"\n >\n <div\n class=\"header-container d-flex align-items-center justify-content-between\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n [style.margin]=\"'10px'\"\n >\n <span [ngClass]=\"getHeaderTitleClass(col)\">\n {{ col.title }}\n </span>\n <div\n class=\"icons d-flex align-items-center\"\n [style.width]=\"'77px'\"\n >\n <p-sortIcon field=\"{{ col.code }}\" />\n\n <!-- COLUMN FILTERS -->\n <ng-container\n *ngIf=\"hasColumnFilter && col.isFilter !== false\"\n >\n <!-- COMPOSED FILTER (uses built-in Apply/Clear) -->\n <p-columnFilter\n *ngIf=\"col.type === TableTypeEnum.COMPOSED\"\n display=\"menu\"\n [field]=\"col.code\"\n type=\"text\"\n [showApplyButton]=\"true\"\n [showClearButton]=\"true\"\n (onClear)=\"onComposedColumnClear(col)\"\n >\n <ng-template\n pTemplate=\"filter\"\n let-filter=\"filterCallback\"\n let-filterModel=\"filterModel\"\n >\n <div *ngFor=\"let composedName of col.composedNames\">\n <ng-container\n *ngIf=\"\n getComposedFieldType(col, composedName) ===\n TableTypeEnum.STRING\n \"\n >\n <p-multiSelect\n [options]=\"filters[composedName]?.options\"\n [ngModel]=\"filters[composedName]?.value\"\n (ngModelChange)=\"\n onComposedFilterValueChange(\n col,\n composedName,\n $event,\n filterModel\n )\n \"\n [placeholder]=\"filters[composedName]?.placeholder\"\n display=\"chip\"\n >\n <ng-template let-item pTemplate=\"item\">\n <div class=\"custom-multiselect-item\">\n <img\n *ngIf=\"item.image\"\n [src]=\"item.image\"\n alt=\"icon\"\n class=\"filter-image\"\n />\n <span>{{ item.label }}</span>\n </div>\n </ng-template>\n </p-multiSelect>\n </ng-container>\n </div>\n </ng-template>\n </p-columnFilter>\n\n <!-- OTHER TYPES -->\n <p-columnFilter\n *ngIf=\"col.type !== TableTypeEnum.COMPOSED\"\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n [showApplyButton]=\"true\"\n [showClearButton]=\"true\"\n >\n <!-- NUMBER -->\n <ng-template\n pTemplate=\"filter\"\n *ngIf=\"col.type === TableTypeEnum.NUMBER\"\n let-filterModel=\"filterModel\"\n >\n <input\n pInputText\n type=\"number\"\n [step]=\"\n col.decimalPlaces\n ? '0.' + '1'.padEnd(col.decimalPlaces, '0')\n : 'any'\n \"\n [ngModel]=\"\n latestFilterValues[col.code!] ?? filterModel?.value\n \"\n (ngModelChange)=\"\n onFilterValueChange(col.code!, filterModel, $event)\n \"\n placeholder=\"Enter a number\"\n />\n </ng-template>\n\n <!-- DATE -->\n <ng-template\n pTemplate=\"filter\"\n *ngIf=\"col.type === TableTypeEnum.DATE\"\n let-filterModel=\"filterModel\"\n >\n <p-calendar\n [ngModel]=\"\n latestFilterValues[col.code!] ?? filterModel?.value\n \"\n (ngModelChange)=\"\n onFilterValueChange(col.code!, filterModel, $event)\n \"\n dateFormat=\"dd/mm/yy\"\n placeholder=\"Choose a date\"\n ></p-calendar>\n </ng-template>\n\n <!-- MULTISELECT -->\n <ng-template\n pTemplate=\"filter\"\n *ngIf=\"\n col.type === TableTypeEnum.MULTISELECT &&\n col.filterOptions &&\n col.filterOptions.length > 0\n \"\n let-filterModel=\"filterModel\"\n >\n <p-multiSelect\n [options]=\"col.filterOptions\"\n [ngModel]=\"\n latestFilterValues[col.code!] ?? filterModel?.value\n \"\n (ngModelChange)=\"\n onFilterValueChange(col.code!, filterModel, $event)\n \"\n display=\"chip\"\n placeholder=\"Choose option\"\n class=\"custom-multiselect\"\n ></p-multiSelect>\n </ng-template>\n </p-columnFilter>\n </ng-container>\n </div>\n </div>\n </ng-container>\n\n <!-- NON-SORTABLE HEADER -->\n <ng-template #noSortHeader>\n <div\n class=\"header-container d-flex align-items-center justify-content-between\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n [style.margin]=\"'10px'\"\n >\n <span [ngClass]=\"getHeaderTitleClass(col)\">\n {{ col.title }}\n </span>\n\n <ng-container *ngIf=\"hasColumnFilter && col.isFilter !== false\">\n <!-- AMOUNT behaves like NUMBER -->\n <p-columnFilter\n *ngIf=\"col.type === 'AMOUNT'\"\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n [currency]=\"getCurrencySymbol(col)\"\n [showApplyButton]=\"true\"\n [showClearButton]=\"true\"\n >\n <ng-template\n pTemplate=\"filter\"\n let-filterModel=\"filterModel\"\n >\n <input\n pInputText\n type=\"number\"\n [step]=\"\n col.decimalPlaces\n ? '0.' + '1'.padEnd(col.decimalPlaces, '0')\n : 'any'\n \"\n [ngModel]=\"\n latestFilterValues[col.code!] ?? filterModel?.value\n \"\n (ngModelChange)=\"\n onFilterValueChange(col.code!, filterModel, $event)\n \"\n placeholder=\"Enter an amount\"\n />\n </ng-template>\n </p-columnFilter>\n\n <p-columnFilter\n *ngIf=\"col.type !== 'AMOUNT'\"\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n [showApplyButton]=\"true\"\n [showClearButton]=\"true\"\n >\n <!-- DATE -->\n <ng-template\n pTemplate=\"filter\"\n let-filterModel=\"filterModel\"\n *ngIf=\"getColumnFilterType(col) === 'date'\"\n >\n <p-calendar\n [ngModel]=\"\n latestFilterValues[col.code!] ?? filterModel?.value\n \"\n (ngModelChange)=\"\n onFilterValueChange(col.code!, filterModel, $event)\n \"\n dateFormat=\"dd/mm/yy\"\n ></p-calendar>\n </ng-template>\n\n <!-- MULTISELECT -->\n <ng-template\n pTemplate=\"filter\"\n let-filterModel=\"filterModel\"\n *ngIf=\"getColumnFilterType(col) === 'multiSelect'\"\n >\n <p-multiSelect\n [options]=\"col.filterOptions\"\n [ngModel]=\"\n latestFilterValues[col.code!] ?? filterModel?.value\n \"\n (ngModelChange)=\"\n onFilterValueChange(col.code!, filterModel, $event)\n \"\n display=\"chip\"\n placeholder=\"Select\"\n class=\"custom-multiselect\"\n ></p-multiSelect>\n </ng-template>\n </p-columnFilter>\n </ng-container>\n </div>\n </ng-template>\n </th>\n\n <!-- GROUPED HEADER -->\n <ng-template #groupHeader>\n <th\n [attr.colspan]=\"col.children?.length\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [ngClass]=\"getHeaderAlignClass(col)\"\n >\n <span>{{ col.title }}</span>\n </th>\n </ng-template>\n </ng-container>\n </tr>\n\n <!-- CHILD HEADERS -->\n <tr *ngIf=\"hasGroupedColumns\">\n <ng-container *ngFor=\"let col of columns\">\n <ng-container *ngIf=\"col.children\">\n <th\n *ngFor=\"let child of col.children\"\n [style.width]=\"child.width || getHeaderWidth(child)\"\n [style.padding]=\"'0px'\"\n ></th>\n </ng-container>\n </ng-container>\n </tr>\n </ng-template>\n\n <!-- EMPTY MESSAGE -->\n <ng-template pTemplate=\"emptymessage\">\n <tr class=\"p-datatable-emptymessage\">\n <!-- span all columns -->\n <td class=\"empty-message-cell\" [attr.colspan]=\"columns.length || 1\">\n <div class=\"empty-message-wrapper\">\n <div class=\"empty-message\">\n <i class=\"pi pi-info-circle\"></i>\n <p>No records available to display.</p>\n </div>\n </div>\n </td>\n </tr>\n </ng-template>\n\n <!-- BODY -->\n <ng-template\n pTemplate=\"body\"\n let-data\n let-editing=\"editing\"\n let-ri=\"rowIndex\"\n >\n <tr *ngIf=\"!loading\" [pEditableRow]=\"isEdit ? data : null\">\n <ng-container *ngFor=\"let col of columns\">\n <!-- SIMPLE COLUMNS (no children) -->\n <ng-container *ngIf=\"!col.children; else childColumns\">\n <!-- EDITABLE CELL -->\n <td\n *ngIf=\"\n isEditable(col.code!) && col.type !== TableTypeEnum.ACTION;\n else normalTD\n \"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [ngClass]=\"getDataAlignClass(col)\"\n >\n <!-- Editable input for NUMBER/DATE/STRING/MULTISELECT -->\n <ng-container *ngIf=\"isMultiSelect(col.code); else datePicker\">\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <p-multiSelect\n appendTo=\"body\"\n [ngModel]=\"data[col.code!]\"\n [style]=\"{ width: '100%' }\"\n (ngModelChange)=\"changeHandler(data.id, col.code, $event)\"\n [options]=\"optionValues\"\n ></p-multiSelect>\n </ng-template>\n <ng-template pTemplate=\"output\">\n <div class=\"multi-select-container\">\n <ng-container *ngFor=\"let rec of data[col.code!]\">\n <p-tag [value]=\"rec\"></p-tag>\n </ng-container>\n </div>\n </ng-template>\n </p-cellEditor>\n </ng-container>\n\n <ng-template #datePicker>\n <ng-container *ngIf=\"isDatePicker(col.code); else normalInput\">\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <p-calendar\n [inputId]=\"data[col.code!]\"\n [ngModel]=\"data[col.code!]\"\n (ngModelChange)=\"\n changeHandler(data.id, col.code, $event)\n \"\n [dateFormat]=\"'dd/mm/yy'\"\n ></p-calendar>\n </ng-template>\n <ng-template pTemplate=\"output\">\n {{ data[col.code!] | customDate }}\n </ng-template>\n </p-cellEditor>\n </ng-container>\n </ng-template>\n\n <ng-template #normalInput>\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <input\n pInputText\n type=\"text\"\n [ngModel]=\"data[col.code!]\"\n (change)=\"onChange($event, data.id, col.code)\"\n />\n </ng-template>\n <ng-template pTemplate=\"output\">\n <ng-container\n *ngIf=\"\n col.type === TableTypeEnum.AMOUNT;\n else normalOutput\n \"\n >\n {{\n data[col.code!]\n | customCurrency\n : getCurrencySymbol(col)\n : col.decimalPlaces\n : col.thousandSeparator\n : col.decimalSeparator\n }}\n </ng-container>\n <ng-template #normalOutput>\n {{ data[col.code!] }}\n </ng-template>\n </ng-template>\n </p-cellEditor>\n </ng-template>\n </td>\n\n <!-- NON-EDITABLE CELL (ALWAYS RENDERED) -->\n <ng-template #normalTD>\n <td\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [ngClass]=\"[\n getDataAlignClass(col),\n col.type === TableTypeEnum.ACTION ? 'action-column' : ''\n ]\"\n >\n <!-- ACTION column: built-in edit/delete + custom actions -->\n <ng-container\n *ngIf=\"col.type === TableTypeEnum.ACTION; else nonActionCell\"\n >\n <div class=\"action-buttons-container\">\n <!-- built-in delete -->\n <button\n *ngIf=\"isDelete\"\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-trash\"\n (click)=\"Delete(data.id)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n\n <!-- built-in inline edit -->\n <div *ngIf=\"isEdit\">\n <button\n pInitEditableRow\n *ngIf=\"!editing\"\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-pencil\"\n (click)=\"initEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n <button\n *ngIf=\"editing\"\n pSaveEditableRow\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-check\"\n (click)=\"saveEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n <button\n *ngIf=\"editing\"\n pCancelEditableRow\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-times\"\n (click)=\"cancelEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n </div>\n\n <!-- custom actions -->\n <button\n *ngFor=\"let act of customActions\"\n pButton\n pRipple\n type=\"button\"\n class=\"p-button-rounded p-button-text\"\n [icon]=\"act.icon || 'pi pi-ellipsis-h'\"\n [ngClass]=\"act.styleClass\"\n (click)=\"onCustomActionClick(act, data)\"\n ></button>\n </div>\n </ng-container>\n\n <!-- NON-ACTION cells -->\n <ng-template #nonActionCell>\n <!-- COMPOSED -->\n <ng-container\n *ngIf=\"\n col.type === TableTypeEnum.COMPOSED;\n else nonComposed\n \"\n >\n <div class=\"composed-cell\">\n <ng-container\n *ngFor=\"\n let composedName of col.composedNames;\n let i = index\n \"\n >\n <!-- IMAGE -->\n <ng-container\n *ngIf=\"\n col.composedTypes &&\n col.composedTypes[i] === TableTypeEnum.IMAGE\n \"\n >\n <img\n [src]=\"data[col.code!]?.[composedName]\"\n alt=\"composed-img\"\n class=\"composed-image\"\n [ngStyle]=\"\n getImageStyle(col.composedStyles?.[composedName])\n \"\n />\n </ng-container>\n\n <!-- STRING -->\n <ng-container\n *ngIf=\"\n col.composedTypes &&\n col.composedTypes[i] === TableTypeEnum.STRING\n \"\n >\n <span\n class=\"composed-text\"\n [ngStyle]=\"\n getTitleStyle(\n col.composedStyles?.[composedName]\n )\n \"\n >\n {{ data[col.code!]?.[composedName] }}\n </span>\n </ng-container>\n </ng-container>\n </div>\n </ng-container>\n\n <ng-template #nonComposed>\n <!-- AMOUNT-->\n <ng-container\n *ngIf=\"col.type === TableTypeEnum.AMOUNT; else nonAmount\"\n >\n {{\n data[col.code!]\n | customCurrency\n : getCurrencySymbol(col)\n : col.decimalPlaces\n : col.thousandSeparator\n : col.decimalSeparator\n }}\n </ng-container>\n\n <ng-template #nonAmount>\n <!-- NUMBER-->\n <ng-container\n *ngIf=\"\n col.type === TableTypeEnum.NUMBER;\n else nonNumber\n \"\n >\n {{\n formatNumber(\n data[col.code!],\n col.decimalPlaces,\n col.thousandSeparator,\n col.decimalSeparator\n )\n }}\n </ng-container>\n\n <ng-template #nonNumber>\n <!-- DATE -->\n <ng-container\n *ngIf=\"\n col.type === TableTypeEnum.DATE;\n else normalTypes\n \"\n >\n {{ formatDate(data[col.code!]) }}\n </ng-container>\n\n <ng-template #normalTypes>\n <!-- STRING, MULTISELECT-->\n <ng-container\n *ngIf=\"\n [\n TableTypeEnum.STRING,\n TableTypeEnum.MULTISELECT\n ].includes(col.type!)\n \"\n >\n {{ data[col.code!] }}\n </ng-container>\n </ng-template>\n </ng-template>\n </ng-template>\n </ng-template>\n </ng-template>\n </td>\n </ng-template>\n </ng-container>\n\n <!-- CHILD COLUMNS -->\n <ng-template #childColumns>\n <ng-container *ngFor=\"let child of col.children\">\n <td\n [style.width]=\"child.width || getHeaderWidth(child)\"\n [ngClass]=\"getDataAlignClass(child)\"\n >\n <ng-container\n *ngIf=\"isEditable(child.code); else childNormalTD\"\n >\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <input\n pInputText\n type=\"text\"\n [ngModel]=\"child.code ? data[child.code] : null\"\n (change)=\"onChange($event, data.id, child.code)\"\n />\n </ng-template>\n <ng-template pTemplate=\"output\">\n {{ child.code ? data[child.code] : \"\" }}\n </ng-template>\n </p-cellEditor>\n </ng-container>\n\n <ng-template #childNormalTD>\n {{ child.code ? data[child.code] : \"\" }}\n </ng-template>\n </td>\n </ng-container>\n </ng-template>\n </ng-container>\n </tr>\n </ng-template>\n </p-table>\n</div>\n", styles: [".pt-advanced-prime-table .bread-crumb{margin-bottom:15px}.pt-advanced-prime-table .date{width:100%;height:5rem;display:grid;justify-items:start;align-items:center}.pt-advanced-prime-table .filter-container{width:100%;display:flex;justify-content:space-between;align-items:center}.pt-advanced-prime-table .settings{display:flex;gap:1rem}.pt-advanced-prime-table .multi-select-container{display:flex;justify-content:center;align-items:center;gap:.3rem}.pt-advanced-prime-table ::ng-deep p-table{min-width:50rem}.pt-advanced-prime-table ::ng-deep .custom-multiselect .p-hidden-accessible input{display:none}.pt-advanced-prime-table ::ng-deep .p-datatable .p-sortable-column.p-highlight:hover{background:none}.pt-advanced-prime-table ::ng-deep .p-datatable .p-sortable-column:focus{box-shadow:none;outline:0 none}.pt-advanced-prime-table ::ng-deep .header-container{display:flex;justify-content:space-between;align-items:center;width:100%}.pt-advanced-prime-table ::ng-deep .header-title-left,.pt-advanced-prime-table ::ng-deep .header-title-center,.pt-advanced-prime-table ::ng-deep .header-title-right{flex:1}.pt-advanced-prime-table ::ng-deep .header-title-left{text-align:left}.pt-advanced-prime-table ::ng-deep .header-title-center{text-align:center}.pt-advanced-prime-table ::ng-deep .header-title-right{text-align:right}.pt-advanced-prime-table ::ng-deep .header-align-left{text-align:left}.pt-advanced-prime-table ::ng-deep .header-align-center{text-align:center}.pt-advanced-prime-table ::ng-deep .header-align-right{text-align:right}.pt-advanced-prime-table ::ng-deep p-columnfilter.p-element.ng-star-inserted{margin-top:4px}.pt-advanced-prime-table .flex{display:flex;justify-content:space-between;align-items:center}.pt-advanced-prime-table .ml-auto{margin-left:auto}.pt-advanced-prime-table ::ng-deep p-inputicon{margin-right:-1.5rem;z-index:2;position:relative}.pt-advanced-prime-table ::ng-deep .p-inputtext{padding-left:1.7rem}.pt-advanced-prime-table ::ng-deep .bt-filter-btn button{cursor:pointer;margin-left:1rem}.pt-advanced-prime-table ::ng-deep .p-icon-field-left .p-input-icon:first-of-type{left:-1rem}.pt-advanced-prime-table .table-row{text-align:center;display:flex;gap:1rem;justify-content:center}.pt-advanced-prime-table ::ng-deep span.p-button-icon.pi.pi-file-excel{font-size:1.25em;color:green}.pt-advanced-prime-table ::ng-deep span.p-button-icon.pi.pi-file-pdf{font-size:1.25em;color:red}.pt-advanced-prime-table .table-container{display:block;width:100%}.pt-advanced-prime-table ::ng-deep .p-datatable-emptymessage>td.empty-message-cell{padding:0!important}.pt-advanced-prime-table .empty-message-wrapper{width:100%;height:100%;min-height:180px;display:flex;align-items:center;justify-content:center}.pt-advanced-prime-table .empty-message{text-align:center;color:#888;font-size:1.2rem}.pt-advanced-prime-table .empty-message i{display:block;font-size:2rem;margin-bottom:.5rem}.pt-advanced-prime-table th{white-space:normal;word-wrap:break-word}.filter-image{width:22px;height:14px;margin-right:5px}.pt-advanced-prime-table ::ng-deep .p-datatable-tbody>tr>td.cell-align-left{text-align:left!important}.pt-advanced-prime-table ::ng-deep .p-datatable-tbody>tr>td.cell-align-center{text-align:center!important}.pt-advanced-prime-table ::ng-deep .p-datatable-tbody>tr>td.cell-align-right{text-align:right!important}.pt-advanced-prime-table ::ng-deep th.action-column,.pt-advanced-prime-table ::ng-deep td.action-column{text-align:center!important;justify-content:center;align-items:center;overflow:hidden;white-space:nowrap;padding:0}.pt-advanced-prime-table ::ng-deep .action-buttons-container{width:100%;display:flex;justify-content:center!important;align-items:center!important;gap:.35rem}.pt-advanced-prime-table ::ng-deep .action-buttons-container .p-button.p-button-rounded.p-button-text{padding:.25rem!important;min-width:22px!important;height:22px!important}\n"] }]
512
681
  }], ctorParameters: () => [], propDecorators: { data: [{
513
682
  type: Input
514
683
  }], columns: [{
@@ -535,18 +704,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImpo
535
704
  type: Input
536
705
  }], maxHeight: [{
537
706
  type: Input
538
- }], filter: [{
539
- type: Output
540
707
  }], search: [{
541
708
  type: Output
542
709
  }], exportExcelEvent: [{
543
710
  type: Output
544
711
  }], exportPdfEvent: [{
545
712
  type: Output
546
- }], pageChange: [{
713
+ }], onPageChange: [{
714
+ type: Output
715
+ }], onSortColumn: [{
716
+ type: Output
717
+ }], onFilterColumn: [{
547
718
  type: Output
548
719
  }], dt: [{
549
720
  type: ViewChild,
550
721
  args: ['dt', { static: false }]
551
722
  }] } });
552
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHQtYWR2YW5jZWQtcHJpbWUtdGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmctcHJpbWUtdG9vbHMvc3JjL2xpYi9wdC1hZHZhbmNlZC1wcmltZS10YWJsZS9wdC1hZHZhbmNlZC1wcmltZS10YWJsZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1wcmltZS10b29scy9zcmMvbGliL3B0LWFkdmFuY2VkLXByaW1lLXRhYmxlL3B0LWFkdmFuY2VkLXByaW1lLXRhYmxlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFVLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDNUUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUU3QyxPQUFPLEVBQ0wsU0FBUyxFQUdULGFBQWEsR0FFZCxNQUFNLGtCQUFrQixDQUFDO0FBQzFCLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDOzs7Ozs7Ozs7Ozs7Ozs7QUF5QnhELE1BQU0sT0FBTyw2QkFBNkI7SUFpRXhDO1FBaEVBLFNBQVM7UUFDQSxTQUFJLEdBQVUsRUFBRSxDQUFDO1FBQ2pCLFlBQU8sR0FBa0IsRUFBRSxDQUFDO1FBQzVCLGlCQUFZLEdBQUcsQ0FBQyxDQUFDO1FBQ2pCLGdCQUFXLEdBQWEsRUFBRSxDQUFDO1FBQzNCLG9CQUFlLEdBQUcsS0FBSyxDQUFDO1FBQ3hCLG1CQUFjLEdBQUcsS0FBSyxDQUFDO1FBQ3ZCLGlCQUFZLEdBQUcsS0FBSyxDQUFDO1FBQ3JCLG9CQUFlLEdBQUcsS0FBSyxDQUFDO1FBQ3hCLGdCQUFXLEdBQUcsS0FBSyxDQUFDO1FBRTdCOzs7O1dBSUc7UUFDTSxZQUFPLEdBQTBCLEVBQUUsQ0FBQztRQUVwQyxlQUFVLEdBQUcsS0FBSyxD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QUMsQ0FBQyxDQUFDLE9BQU8sQ0FDekIsdUJBQXVCLEVBQ3ZCLGlCQUFpQixLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQzFDLENBQUM7WUFDRixlQUFlLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsS0FBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDekUsQ0FBQztRQUVELE9BQU8sZUFBZSxDQUFDO0lBQ3pCLENBQUM7K0dBemxCVSw2QkFBNkI7bUdBQTdCLDZCQUE2QixrcEJDbkMxQyxtKzBCQXlxQkE7OzRGRHRvQmEsNkJBQTZCO2tCQUx6QyxTQUFTOytCQUNFLHlCQUF5Qjt3REFNMUIsSUFBSTtzQkFBWixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxjQUFjO3NCQUF0QixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQU9HLE9BQU87c0JBQWYsS0FBSztnQkFFRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUdJLE1BQU07c0JBQWYsTUFBTTtnQkFDRyxNQUFNO3NCQUFmLE1BQU07Z0JBQ0csZ0JBQWdCO3NCQUF6QixNQUFNO2dCQUNHLGNBQWM7c0JBQXZCLE1BQU07Z0JBQ0csVUFBVTtzQkFBbkIsTUFBTTtnQkFFNkIsRUFBRTtzQkFBckMsU0FBUzt1QkFBQyxJQUFJLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT25Jbml0LCBPdXRwdXQsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRXZlbnRFbWl0dGVyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBUYWJsZSB9IGZyb20gJ3ByaW1lbmcvdGFibGUnO1xuaW1wb3J0IHtcbiAgQWxpZ25FbnVtLFxuICBJbWFnZVN0eWxlLFxuICBUYWJsZUNvbHVtbixcbiAgVGFibGVUeXBlRW51bSxcbiAgVGl0bGVTdHlsZSxcbn0gZnJvbSAnLi4vLi4vcHVibGljLWFwaSc7XG5pbXBvcnQgeyBjYWxjdWxhdGVUZXh0V2lkdGggfSBmcm9tICcuLi91dGlscy90ZXh0LnV0aWwnO1xuXG4vKipcbiAqIEdlbmVyaWMgYWN0aW9uIGNvbmZpZyBwYXNzZWQgZnJvbSBwYXJlbnQuXG4gKlxuICogQnVpbHQtaW4gY29kZXM6XG4gKiAgLSAnZWRpdCcgICDihpIgdXNlcyBpbml0L3NhdmUgY2FsbGJhY2tzIGFuZCBzaG93cyBwZW5jaWwgLyDinJMgLyDinJdcbiAqICAtICdkZWxldGUnIOKGkiB1c2VzIGNhbGxiYWNrKGlkKSBhbmQgc2hvd3MgdHJhc2ggaWNvblxuICpcbiAqIEFueSBvdGhlciBjb2RlIGlzIHRyZWF0ZWQgYXMgYSBjdXN0b20gYWN0aW9uLCBhbmQgaXRzIGNhbGxiYWNrIGlzIGludm9rZWRcbiAqIGRpcmVjdGx5IHdpdGggdGhlIHdob2xlIHJvdy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQVFRhYmxlQWN0aW9uQ29uZmlnIHtcbiAgY29kZTogc3RyaW5nOyAvLyAnZWRpdCcgfCAnZGVsZXRlJyB8ICc8YW55dGhpbmcteW91LXdhbnQ+J1xuICBpY29uPzogc3RyaW5nOyAvLyB1c2VkIGZvciBjdXN0b20gYWN0aW9uc1xuICBzdHlsZUNsYXNzPzogc3RyaW5nOyAvLyBvcHRpb25hbCBDU1MgY2xhc3NlcyBmb3IgY3VzdG9tIGJ1dHRvbnNcbiAgdG9vbHRpcD86IHN0cmluZzsgLy8gb3B0aW9uYWwgdG9vbHRpcCAoaWYgeW91IGRlY2lkZSB0byB1c2UgcFRvb2x0aXApXG4gIGFjdGlvbjogYW55O1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdwdC1hZHZhbmNlZC1wcmltZS10YWJsZScsXG4gIHRlbXBsYXRlVXJsOiAnLi9wdC1hZHZhbmNlZC1wcmltZS10YWJsZS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsOiAnLi9wdC1hZHZhbmNlZC1wcmltZS10YWJsZS5jb21wb25lbnQuY3NzJyxcbn0pXG5leHBvcnQgY2xhc3MgUFRBZHZhbmNlZFByaW1lVGFibGVDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICAvLyBJbnB1dHNcbiAgQElucHV0KCkgZGF0YTogYW55W10gPSBbXTtcbiAgQElucHV0KCkgY29sdW1uczogVGFibGVDb2x1bW5bXSA9IFtdO1xuICBASW5wdXQoKSB0b3RhbFJlY29yZHMgPSAwO1xuICBASW5wdXQoKSByb3dzUGVyUGFnZTogbnVtYmVyW10gPSBbXTtcbiAgQElucHV0KCkgaGFzU2VhcmNoRmlsdGVyID0gZmFsc2U7XG4gIEBJbnB1dCgpIGhhc0V4cG9ydEV4Y2VsID0gZmFsc2U7XG4gIEBJbnB1dCgpIGhhc0V4cG9ydFBERiA9IGZhbHNlO1xuICBASW5wdXQoKSBoYXNDb2x1bW5GaWx0ZXIgPSBmYWxzZTtcbiAgQElucHV0KCkgaXNQYWdpbmF0ZWQgPSBmYWxzZTtcblxuICAvKipcbiAgICogQWN0aW9ucyBjb25maWd1cmF0aW9uLlxuICAgKiAtIGNvZGUgJ2VkaXQnIC8gJ2RlbGV0ZScgZ2FyZGUgbCdhbmNpZW4gY29tcG9ydGVtZW50LlxuICAgKiAtIHRvdXQgYXV0cmUgY29kZSA9IGFjdGlvbiBjdXN0b20sIGfDqXLDqWUgdW5pcXVlbWVudCBkYW5zIGxlIHBhcmVudC5cbiAgICovXG4gIEBJbnB1dCgpIGFjdGlvbnM6IFBUVGFibGVBY3Rpb25Db25maWdbXSA9IFtdO1xuXG4gIEBJbnB1dCgpIGlzU29ydGFibGUgPSBmYWxzZTtcbiAgQElucHV0KCkgbG9hZGluZyA9IGZhbHNlO1xuICBASW5wdXQoKSBtYXhIZWlnaHQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG4gIC8vIE91dHB1dHM6IEV2ZW50cyBlbWl0dGVkIHRvIHRoZSBwYXJlbnQgY29tcG9uZW50XG4gIEBPdXRwdXQoKSBmaWx0ZXIgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgQE91dHB1dCgpIHNlYXJjaCA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICBAT3V0cHV0KCkgZXhwb3J0RXhjZWxFdmVudCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgQE91dHB1dCgpIGV4cG9ydFBkZkV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICBAT3V0cHV0KCkgcGFnZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8eyBwYWdlOiBudW1iZXI7IHJvd3M6IG51bWJlciB9PigpO1xuXG4gIEBWaWV3Q2hpbGQoJ2R0JywgeyBzdGF0aWM6IGZhbHNlIH0pIGR0ITogVGFibGU7XG5cbiAgcHVibGljIFRhYmxlVHlwZUVudW0gPSBUYWJsZVR5cGVFbnVtO1xuICBwdWJsaWMgQWxpZ25FbnVtID0gQWxpZ25FbnVtOyAvLyBpZiBuZWVkZWQgaW4gdGVtcGxhdGVcblxuICBzZWFyY2hWYWx1ZSA9ICcnO1xuXG4gIHB1YmxpYyBmaWx0ZXJzOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ID0ge307XG5cbiAgcHJpdmF0ZSB2YWxpZEN1cnJlbmN5Q29kZXMgPSBbJ1VTRCcsICdFVVInLCAnTUFEJ107XG4gIGljb25XaWR0aCA9IDc3O1xuXG4gIC8vIENvbXBvbmVudCBzdGF0ZSBwcm9wZXJ0aWVzXG4gIHJvd3MgPSAwO1xuICBoYXNHcm91cGVkQ29sdW1ucyA9IGZhbHNlO1xuXG4gIC8vIEZsYWdzIC8gaGFuZGxlcnMgZm9yIGJ1aWx0LWluIGVkaXQvZGVsZXRlIHN1cHBvcnRcbiAgaXNEZWxldGUgPSBmYWxzZTtcbiAgaXNFZGl0ID0gZmFsc2U7XG5cbiAgRGVsZXRlOiAodmFsdWU6IGFueSkgPT4gdm9pZCA9ICgpID0+IHt9O1xuICBpbml0RWRpdGFibGVSb3c6IChkYXRhOiBhbnkpID0+IHZvaWQgPSAoKSA9PiB7fTtcbiAgc2F2ZUVkaXRhYmxlUm93OiAoZGF0YTogYW55KSA9PiB2b2lkID0gKCkgPT4ge307XG4gIGNhbmNlbEVkaXRhYmxlUm93OiAoaXRlbTogYW55KSA9PiB2b2lkID0gKCkgPT4ge307XG5cbiAgLy8gRXh0cmEgY3VzdG9tIGFjdGlvbnMgKGNvZGVzIG90aGVyIHRoYW4gJ2VkaXQnLydkZWxldGUnKVxuICBjdXN0b21BY3Rpb25zOiBQVFRhYmxlQWN0aW9uQ29uZmlnW10gPSBbXTtcblxuICAvLyBEYXRhIG1hbmFnZW1lbnQgcHJvcGVydGllc1xuICBkYXRhTWFwID0gbmV3IE1hcDxhbnksIGFueT4oKTtcbiAgbWFwID0gbmV3IE1hcDxhbnksIE1hcDxhbnksIGFueT4+KCk7XG4gIG9wdGlvbkVudHJpZXMgPSBuZXcgTWFwPHN0cmluZywgYW55W10+KCk7XG4gIG9wdGlvblZhbHVlczogYW55W10gPSBbXTtcbiAgZ2xvYmFsRmlsdGVyRmllbGRzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIGNvbnN0cnVjdG9yKCkge31cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICBjb25zb2xlLmxvZygnUFRBZHZhbmNlZFByaW1lVGFibGUgY29sdW1uczonLCB0aGlzLmNvbHVtbnMpO1xuICAgIGNvbnNvbGUubG9nKCdQVEFkdmFuY2VkUHJpbWVUYWJsZSB0b3RhbFJlY29yZHMgaW5wdXQ6JywgdGhpcy50b3RhbFJlY29yZHMpO1xuXG4gICAgdGhpcy5oYXNHcm91cGVkQ29sdW1ucyA9IHRoaXMuY29sdW1ucy5zb21lKFxuICAgICAgKGNvbCkgPT4gY29sLmNoaWxkcmVuICYmIGNvbC5jaGlsZHJlbi5sZW5ndGggPiAwXG4gICAgKTtcblxuICAgIHRoaXMuZ2xvYmFsRmlsdGVyRmllbGRzID0gdGhpcy5jb2x1bW5zXG4gICAgICAuZmlsdGVyKChjb2wpID0+IGNvbC5jb2RlICE9PSB1bmRlZmluZWQgJiYgY29sLmlzRmlsdGVyICE9PSBmYWxzZSlcbiAgICAgIC5tYXAoKGNvbCkgPT4gY29sLmNvZGUgYXMgc3RyaW5nKTtcblxuICAgIHRoaXMuaW5pdGlhbGl6ZVBhZ2luYXRpb24oKTtcbiAgICB0aGlzLmluaXRpYWxpemVBY3Rpb25zKCk7XG5cbiAgICAvLyBTZXQgZGVmYXVsdCB2YWx1ZSBmb3IgaXNTb3J0YWJsZSAvIGlzRWRpdGFibGUgKyB3aWR0aHNcbiAgICB0aGlzLmNvbHVtbnMuZm9yRWFjaCgoY29sKSA9PiB7XG4gICAgICBpZiAoY29sLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uQUNUSU9OKSB7XG4gICAgICAgIGNvbC5pc0VkaXRhYmxlID0gZmFsc2U7XG4gICAgICAgIGNvbC5pc0ZpbHRlciA9IGZhbHNlO1xuICAgICAgICBjb2wuaXNTb3J0YWJsZSA9IGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBpZiAoY29sLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uQ09NUE9TRUQpIHtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplQ29tcG9zZWRGaWx0ZXJzKGNvbCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb2wuaXNTb3J0YWJsZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbC5pc1NvcnRhYmxlID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbC5pc0VkaXRhYmxlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29sLmlzRWRpdGFibGUgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoY29sLmlzRmlsdGVyICE9PSBmYWxzZSAmJiBjb2wuY29kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuZ2xvYmFsRmlsdGVyRmllbGRzLnB1c2goY29sLmNvZGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWNvbC53aWR0aCkge1xuICAgICAgICBjb2wud2lkdGggPSB0aGlzLmNhbGN1bGF0ZUNvbHVtbldpZHRoKGNvbCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyAtLS0tLS0tLS0tIEhFQURFUiArIEJPRFkgQUxJR05NRU5UIEhFTFBFUlMgLS0tLS0tLS0tLVxuXG4gIC8qKiBDU1MgY2xhc3MgZm9yIHRoZSBoZWFkZXIgdGl0bGUgc3BhbiAoaW5zaWRlIGhlYWRlci1jb250YWluZXIpICovXG4gIGdldEhlYWRlclRpdGxlQ2xhc3MoY29sOiBUYWJsZUNvbHVtbik6IHN0cmluZyB7XG4gICAgY29uc3QgYWxpZ24gPSBjb2wuaGVhZGVyQWxpZ24gPz8gQWxpZ25FbnVtLkxFRlQ7XG4gICAgc3dpdGNoIChhbGlnbikge1xuICAgICAgY2FzZSBBbGlnbkVudW0uQ0VOVEVSOlxuICAgICAgICByZXR1cm4gJ2hlYWRlci10aXRsZS1jZW50ZXInO1xuICAgICAgY2FzZSBBbGlnbkVudW0uUklHSFQ6XG4gICAgICAgIHJldHVybiAnaGVhZGVyLXRpdGxlLXJpZ2h0JztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiAnaGVhZGVyLXRpdGxlLWxlZnQnO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBDU1MgY2xhc3MgZm9yIGdyb3VwZWQgaGVhZGVycyAoPHRoPiB3aXRoIGNvbHNwYW4pICovXG4gIGdldEhlYWRlckFsaWduQ2xhc3MoY29sOiBUYWJsZUNvbHVtbik6IHN0cmluZyB7XG4gICAgY29uc3QgYWxpZ24gPSBjb2wuaGVhZGVyQWxpZ24gPz8gQWxpZ25FbnVtLkxFRlQ7XG4gICAgc3dpdGNoIChhbGlnbikge1xuICAgICAgY2FzZSBBbGlnbkVudW0uQ0VOVEVSOlxuICAgICAgICByZXR1cm4gJ2hlYWRlci1hbGlnbi1jZW50ZXInO1xuICAgICAgY2FzZSBBbGlnbkVudW0uUklHSFQ6XG4gICAgICAgIHJldHVybiAnaGVhZGVyLWFsaWduLXJpZ2h0JztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiAnaGVhZGVyLWFsaWduLWxlZnQnO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBDU1MgY2xhc3MgZm9yIGJvZHkgY2VsbHMgKDx0ZD4pIGJhc2VkIG9uIGRhdGFBbGlnbiAoZGVmYXVsdCBMRUZUKSAqL1xuICBnZXREYXRhQWxpZ25DbGFzcyhjb2w6IFRhYmxlQ29sdW1uKTogc3RyaW5nIHtcbiAgICAvLyBvcHRpb25hbDogZGVmYXVsdCByaWdodCBhbGlnbm1lbnQgZm9yIG51bWVyaWMvYW1vdW50IHdoZW4gbm90IHNwZWNpZmllZFxuICAgIGNvbnN0IGVmZmVjdGl2ZUFsaWduID1cbiAgICAgIGNvbC5kYXRhQWxpZ24gPz9cbiAgICAgIChjb2wudHlwZSA9PT0gVGFibGVUeXBlRW51bS5OVU1CRVIgfHwgY29sLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uQU1PVU5UXG4gICAgICAgID8gQWxpZ25FbnVtLlJJR0hUXG4gICAgICAgIDogQWxpZ25FbnVtLkxFRlQpO1xuXG4gICAgc3dpdGNoIChlZmZlY3RpdmVBbGlnbikge1xuICAgICAgY2FzZSBBbGlnbkVudW0uQ0VOVEVSOlxuICAgICAgICByZXR1cm4gJ2NlbGwtYWxpZ24tY2VudGVyJztcbiAgICAgIGNhc2UgQWxpZ25FbnVtLlJJR0hUOlxuICAgICAgICByZXR1cm4gJ2NlbGwtYWxpZ24tcmlnaHQnO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuICdjZWxsLWFsaWduLWxlZnQnO1xuICAgIH1cbiAgfVxuXG4gIC8vIC0tLS0tLS0tLS0gQUNUSU9OUyBJTklUSUFMSVpBVElPTiAtLS0tLS0tLS0tXG5cbiAgcHJpdmF0ZSBpbml0aWFsaXplQWN0aW9ucygpOiB2b2lkIHtcbiAgICAvLyByZXNldCBzdGF0ZVxuICAgIHRoaXMuaXNEZWxldGUgPSBmYWxzZTtcbiAgICB0aGlzLmlzRWRpdCA9IGZhbHNlO1xuICAgIHRoaXMuRGVsZXRlID0gKCkgPT4ge307XG4gICAgdGhpcy5pbml0RWRpdGFibGVSb3cgPSAoKSA9PiB7fTtcbiAgICB0aGlzLnNhdmVFZGl0YWJsZVJvdyA9ICgpID0+IHt9O1xuICAgIHRoaXMuY2FuY2VsRWRpdGFibGVSb3cgPSAoKSA9PiB7fTtcbiAgICB0aGlzLmN1c3RvbUFjdGlvbnMgPSBbXTtcblxuICAgIGlmICghdGhpcy5hY3Rpb25zIHx8IHRoaXMuYWN0aW9ucy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmFjdGlvbnMuZm9yRWFjaCgoYWN0aW9uKSA9PiB7XG4gICAgICBzd2l0Y2ggKGFjdGlvbi5jb2RlKSB7XG4gICAgICAgIGNhc2UgJ2RlbGV0ZSc6XG4gICAgICAgICAgdGhpcy5pc0RlbGV0ZSA9IHRydWU7XG4gICAgICAgICAgdGhpcy5EZWxldGUgPSAodmFsdWU6IGFueSkgPT4gYWN0aW9uLmFjdGlvbih2YWx1ZSk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSAnZWRpdCc6XG4gICAgICAgICAgdGhpcy5pbml0aWFsaXplRWRpdEFjdGlvbnMoYWN0aW9uKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIC8vIGFueSBvdGhlciBjb2RlIGlzIGEgcHVyZSBjdXN0b20gYWN0aW9uXG4gICAgICAgICAgdGhpcy5jdXN0b21BY3Rpb25zLnB1c2goYWN0aW9uKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgaW5pdGlhbGl6ZUVkaXRBY3Rpb25zKGFjdGlvbjogUFRUYWJsZUFjdGlvbkNvbmZpZyk6IHZvaWQge1xuICAgIHRoaXMuaXNFZGl0ID0gdHJ1ZTtcbiAgICB0aGlzLmluaXRFZGl0YWJsZVJvdyA9IChkYXRhOiBhbnkpID0+IGFjdGlvbi5hY3Rpb24uaW5pdChkYXRhKTtcbiAgICB0aGlzLnNhdmVFZGl0YWJsZVJvdyA9IChkYXRhOiBhbnkpID0+IHtcbiAgICAgIGNvbnN0IHJlY29yZCA9IHRoaXMubWFwLmdldChkYXRhLmlkKTtcbiAgICAgIGFjdGlvbi5hY3Rpb24uc2F2ZShkYXRhLCByZWNvcmQpO1xuICAgICAgdGhpcy5kYXRhTWFwLmNsZWFyKCk7XG4gICAgfTtcbiAgICB0aGlzLmNhbmNlbEVkaXRhYmxlUm93ID0gKGl0ZW06IGFueSkgPT4gY29uc29sZS5sb2coaXRlbSk7XG4gIH1cblxuICAvKiogQ2FsbGVkIHdoZW4gYSBjdXN0b20gYWN0aW9uIGJ1dHRvbiBpcyBjbGlja2VkICovXG4gIG9uQ3VzdG9tQWN0aW9uQ2xpY2soYWN0aW9uOiBQVFRhYmxlQWN0aW9uQ29uZmlnLCByb3c6IGFueSk6IHZvaWQge1xuICAgIGlmIChhY3Rpb24gJiYgdHlwZW9mIGFjdGlvbi5hY3Rpb24gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIC8vIERlZmVyIHRvIG5leHQgbWFjcm90YXNrIOKGkiBmcmVzaCBjaGFuZ2UgZGV0ZWN0aW9uIGN5Y2xlXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgYWN0aW9uLmFjdGlvbihyb3cpO1xuICAgICAgfSwgMCk7XG4gICAgfVxuICB9XG5cbiAgLy8gSW5pdGlhbGl6ZSBmaWx0ZXJzIGZvciBjb21wb3NlZCBjb2x1bW5zXG4gIHByaXZhdGUgaW5pdGlhbGl6ZUNvbXBvc2VkRmlsdGVycyhjb2w6IFRhYmxlQ29sdW1uKTogdm9pZCB7XG4gICAgY29sLmNvbXBvc2VkTmFtZXM/LmZvckVhY2goKGNvbXBvc2VkTmFtZSkgPT4ge1xuICAgICAgY29uc3QgY29kZSA9IChjb2wuY29kZSBhcyBzdHJpbmcpIHx8ICcnO1xuICAgICAgdGhpcy5nbG9iYWxGaWx0ZXJGaWVsZHMucHVzaChjb2RlICsgJy4nICsgY29tcG9zZWROYW1lKTtcbiAgICAgIHRoaXMuZmlsdGVyc1tjb21wb3NlZE5hbWVdID0ge1xuICAgICAgICBvcHRpb25zOiBjb2wuZmlsdGVyT3B0aW9ucyxcbiAgICAgICAgdmFsdWU6IFtdLFxuICAgICAgICBsYWJlbDogJ0ZpbHRlciBieSAnICsgY29tcG9zZWROYW1lLFxuICAgICAgICBwbGFjZWhvbGRlcjogJ1NlbGVjdCBvcHRpb24nLFxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIEdldCB0aGUgY29sdW1uIHR5cGUgZm9yIGNvbXBvc2VkIGZpZWxkcyAoU1RSSU5HLCBJTUFHRSwgZXRjLilcbiAgZ2V0Q29tcG9zZWRGaWVsZFR5cGUoXG4gICAgY29sOiBUYWJsZUNvbHVtbixcbiAgICBjb21wb3NlZE5hbWU6IHN0cmluZ1xuICApOiBUYWJsZVR5cGVFbnVtIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoY29sLmNvbXBvc2VkTmFtZXMgJiYgY29sLmNvbXBvc2VkVHlwZXMpIHtcbiAgICAgIGNvbnN0IGluZGV4ID0gY29sLmNvbXBvc2VkTmFtZXMuaW5kZXhPZihjb21wb3NlZE5hbWUpO1xuICAgICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCBjb2wuY29tcG9zZWRUeXBlcy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIGNvbC5jb21wb3NlZFR5cGVzW2luZGV4XTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIG9uQ29tcG9zZWRGaWx0ZXJDaGFuZ2UoXG4gICAgY29sOiBUYWJsZUNvbHVtbixcbiAgICBjb21wb3NlZE5hbWU6IHN0cmluZyxcbiAgICBzZWxlY3RlZFZhbHVlczogYW55XG4gICk6IHZvaWQge1xuICAgIHRoaXMuZmlsdGVyc1tjb21wb3NlZE5hbWVdLnZhbHVlID0gc2VsZWN0ZWRWYWx1ZXM7XG4gICAgdGhpcy5maWx0ZXIuZW1pdCh0aGlzLmZpbHRlcnMpO1xuXG4gICAgY29uc3QgZmlsdGVyVmFsdWUgPSBzZWxlY3RlZFZhbHVlcy5qb2luKCcsJyk7XG4gICAgbGV0IG1hdGNoUmVzdWx0czogYW55W10gPSBbXTtcblxuICAgIGNvbnN0IGNvbENvZGUgPSBjb2wuY29kZSBhcyBzdHJpbmc7XG5cbiAgICBzZWxlY3RlZFZhbHVlcy5mb3JFYWNoKCh2YWx1ZTogYW55KSA9PiB7XG4gICAgICBjb25zdCBtYXRjaGVzID0gdGhpcy5kdC52YWx1ZS5maWx0ZXIoKHJvdzogYW55KSA9PiB7XG4gICAgICAgIHJldHVybiByb3dbY29sQ29kZV0/Lltjb21wb3NlZE5hbWVdXG4gICAgICAgICAgPy50b1N0cmluZygpXG4gICAgICAgICAgLnRvTG93ZXJDYXNlKClcbiAgICAgICAgICAuaW5jbHVkZXModmFsdWUudG9Mb3dlckNhc2UoKSk7XG4gICAgICB9KTtcbiAgICAgIG1hdGNoUmVzdWx0cyA9IFsuLi5tYXRjaFJlc3VsdHMsIC4uLm1hdGNoZXNdO1xuICAgIH0pO1xuXG4gICAgbWF0Y2hSZXN1bHRzID0gQXJyYXkuZnJvbShuZXcgU2V0KG1hdGNoUmVzdWx0cykpO1xuICAgIHRoaXMuZHQuZmlsdGVyZWRWYWx1ZSA9IG1hdGNoUmVzdWx0cztcbiAgICB0aGlzLmR0LmZpbHRlckdsb2JhbChmaWx0ZXJWYWx1ZSwgJ2NvbnRhaW5zJyk7XG4gIH1cblxuICAvLyDim5QgRG9uJ3Qgb3ZlcnJpZGUgdG90YWxSZWNvcmRzIGhlcmUg4oCTIHdlIGFyZSBpbiBzZXJ2ZXItc2lkZSBtb2RlXG4gIG9uRmlsdGVyKGV2ZW50OiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLmZpbHRlci5lbWl0KGV2ZW50KTtcbiAgICAvLyB0aGlzLnRvdGFsUmVjb3JkcyA9IGV2ZW50LmZpbHRlcmVkVmFsdWU/Lmxlbmd0aCB8fCAwOyAgLy8gcmVtb3ZlZFxuICB9XG5cbiAgb25QYWdlQ2hhbmdlKGV2ZW50OiBhbnkpOiB2b2lkIHtcbiAgICBjb25zdCBwYWdlID0gZXZlbnQucGFnZSA/PyBNYXRoLmZsb29yKChldmVudC5maXJzdCB8fCAwKSAvIGV2ZW50LnJvd3MpO1xuICAgIGNvbnN0IHJvd3MgPSBldmVudC5yb3dzO1xuXG4gICAgdGhpcy5yb3dzID0gcm93cztcbiAgICB0aGlzLnBhZ2VDaGFuZ2UuZW1pdCh7IHBhZ2UsIHJvd3MgfSk7XG4gIH1cblxuICBvbkNhbGVuZGFyRmlsdGVyQ2hhbmdlKFxuICAgIGV2ZW50OiBhbnksXG4gICAgY29sdW1uQ29kZTogc3RyaW5nLFxuICAgIGZpbHRlckNhbGxiYWNrOiBhbnlcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgZmlsdGVyVmFsdWUgPSBldmVudCA/IG5ldyBEYXRlKGV2ZW50KSA6IG51bGw7XG4gICAgaWYgKCFmaWx0ZXJWYWx1ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGZpbHRlckNhbGxiYWNrKGZpbHRlclZhbHVlKTtcblxuICAgIGNvbnN0IGZpbHRlclZhbHVlU3RyaW5nID0gZXZlbnQgPyB0aGlzLmZvcm1hdERhdGUoZXZlbnQpIDogJyc7XG4gICAgdGhpcy5vbkZpbHRlcih7XG4gICAgICBmaWx0ZXJlZFZhbHVlOiB0aGlzLmRhdGEuZmlsdGVyKChpdGVtKSA9PiB7XG4gICAgICAgIGNvbnN0IGNvbHVtblZhbHVlID0gaXRlbVtjb2x1bW5Db2RlXTtcbiAgICAgICAgaWYgKGNvbHVtblZhbHVlKSB7XG4gICAgICAgICAgY29uc3QgaXRlbURhdGVTdHJpbmcgPSB0aGlzLmZvcm1hdERhdGUobmV3IERhdGUoY29sdW1uVmFsdWUpKTtcbiAgICAgICAgICByZXR1cm4gaXRlbURhdGVTdHJpbmcgPT09IGZpbHRlclZhbHVlU3RyaW5nO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0pLFxuICAgIH0pO1xuICB9XG5cbiAgZmlsdGVyQ29tcG9zZWREYXRhKGl0ZW06IGFueSwgY29tcG9zZWROYW1lOiBzdHJpbmcsIHZhbHVlOiBhbnkpOiBib29sZWFuIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkgJiYgdmFsdWUubGVuZ3RoID4gMCkge1xuICAgICAgcmV0dXJuIHZhbHVlLnNvbWUoKGZpbHRlclZhbHVlOiBzdHJpbmcpID0+XG4gICAgICAgIGl0ZW1bY29tcG9zZWROYW1lXT8udG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhmaWx0ZXJWYWx1ZS50b0xvd2VyQ2FzZSgpKVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBwcml2YXRlIGNhbGN1bGF0ZUNvbHVtbldpZHRoKGNvbDogVGFibGVDb2x1bW4pOiBzdHJpbmcge1xuICAgIGNvbnN0IGNhbGN1bGF0ZWRXaWR0aCA9IGNhbGN1bGF0ZVRleHRXaWR0aChjb2wsIGNvbC50aXRsZSk7XG4gICAgY29uc3QgdG90YWxXaWR0aCA9IGNhbGN1bGF0ZWRXaWR0aCArIHRoaXMuaWNvbldpZHRoICsgMjA7XG4gICAgcmV0dXJuIGAke3RvdGFsV2lkdGh9cHhgO1xuICB9XG5cbiAgZ2V0SGVhZGVyV2lkdGgoY29sOiBUYWJsZUNvbHVtbik6IHN0cmluZyB7XG4gICAgLy8g4pyFIElmIGEgd2lkdGggaXMgY29uZmlndXJlZCAoZXg6ICc0MTBweCcpLCB1c2UgaXQgZGlyZWN0bHlcbiAgICBpZiAoY29sLndpZHRoKSB7XG4gICAgICByZXR1cm4gY29sLndpZHRoO1xuICAgIH1cblxuICAgIC8vIG90aGVyd2lzZSBjb21wdXRlIGl0IGF1dG9tYXRpY2FsbHlcbiAgICByZXR1cm4gdGhpcy5jYWxjdWxhdGVDb2x1bW5XaWR0aChjb2wpO1xuICB9XG5cbiAgY2xlYXIodGFibGU6IFRhYmxlKSB7XG4gICAgdGFibGUuY2xlYXIoKTtcbiAgICB0aGlzLnNlYXJjaFZhbHVlID0gJyc7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlRGF0ZShkYXRlU3RyaW5nOiBzdHJpbmcpOiBEYXRlIHwgbnVsbCB7XG4gICAgY29uc3QgcGFydHMgPSBkYXRlU3RyaW5nLnNwbGl0KCcvJyk7XG4gICAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMykge1xuICAgICAgY29uc3QgZGF5ID0gcGFyc2VJbnQocGFydHNbMF0sIDEwKTtcbiAgICAgIGNvbnN0IG1vbnRoID0gcGFyc2VJbnQocGFydHNbMV0sIDEwKSAtIDE7XG4gICAgICBjb25zdCB5ZWFyID0gcGFyc2VJbnQocGFydHNbMl0sIDEwKTtcbiAgICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSh5ZWFyLCBtb250aCwgZGF5KTtcbiAgICAgIHJldHVybiBpc05hTihkYXRlLmdldFRpbWUoKSkgPyBudWxsIDogZGF0ZTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwcml2YXRlIGluaXRpYWxpemVQYWdpbmF0aW9uKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmlzUGFnaW5hdGVkKSB7XG4gICAgICBpZiAoIXRoaXMucm93c1BlclBhZ2UgfHwgdGhpcy5yb3dzUGVyUGFnZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhpcy5yb3dzUGVyUGFnZSA9IFsyMCwgMzAsIDQwXTtcbiAgICAgIH1cbiAgICAgIHRoaXMucm93cyA9IHRoaXMucm93c1BlclBhZ2VbMF07XG4gICAgfVxuICB9XG5cbiAgb25DaGFuZ2UoZXZlbnQ6IEV2ZW50LCBpZDogbnVtYmVyLCBrZXk6IGFueSkge1xuICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50O1xuICAgIHRoaXMuY2hhbmdlSGFuZGxlcihpZCwga2V5LCB0YXJnZXQudmFsdWUpO1xuICB9XG5cbiAgY2hhbmdlSGFuZGxlcihpZDogbnVtYmVyLCBrZXk6IGFueSwgdmFsdWU6IGFueSkge1xuICAgIGNvbnN0IGNvbHVtbiA9IHRoaXMuY29sdW1ucy5maW5kKChpdGVtKSA9PiBpdGVtLmNvZGUgPT09IGtleSk7XG4gICAgaWYgKCF0aGlzLm1hcC5nZXQoaWQpKSB7XG4gICAgICBpZiAoY29sdW1uPy50eXBlID09PSBUYWJsZVR5cGVFbnVtLkRBVEUpIHtcbiAgICAgICAgY29uc3QgZGF0ZSA9IHRoaXMucGFyc2VEYXRlKHZhbHVlKTtcbiAgICAgICAgdGhpcy5kYXRhTWFwLnNldChrZXksIGRhdGUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5kYXRhTWFwLnNldChrZXksIHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubWFwLnNldChpZCwgbmV3IE1hcCh0aGlzLmRhdGFNYXApKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgbWFwSXRlbSA9IHRoaXMubWFwLmdldChpZCkgYXMgTWFwPGFueSwgYW55PjtcbiAgICAgIGlmIChjb2x1bW4/LnR5cGUgPT09IFRhYmxlVHlwZUVudW0uREFURSkge1xuICAgICAgICBjb25zdCBkYXRlID0gdGhpcy5wYXJzZURhdGUodmFsdWUpO1xuICAgICAgICBtYXBJdGVtLnNldChrZXksIGRhdGUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbWFwSXRlbS5zZXQoa2V5LCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ2V0Q29sdW1uRmlsdGVyVHlwZShjb2x1bW46IFRhYmxlQ29sdW1uKTogc3RyaW5nIHtcbiAgICBzd2l0Y2ggKGNvbHVtbi50eXBlKSB7XG4gICAgICBjYXNlIFRhYmxlVHlwZUVudW0uU1RSSU5HOlxuICAgICAgICByZXR1cm4gJ3RleHQnO1xuICAgICAgY2FzZSBUYWJsZVR5cGVFbnVtLkFNT1VOVDpcbiAgICAgIGNhc2UgVGFibGVUeXBlRW51bS5OVU1CRVI6XG4gICAgICAgIHJldHVybiAnbnVtZXJpYyc7XG4gICAgICBjYXNlIFRhYmxlVHlwZUVudW0uREFURTpcbiAgICAgICAgcmV0dXJuICdkYXRlJztcbiAgICAgIGNhc2UgVGFibGVUeXBlRW51bS5NVUxUSVNFTEVDVDpcbiAgICAgICAgcmV0dXJuICdtdWx0aVNlbGVjdCc7XG4gICAgICBjYXNlIFRhYmxlVHlwZUVudW0uQk9PTEVBTjpcbiAgICAgICAgcmV0dXJuICdib29sZWFuJztcbiAgICAgIGNhc2UgVGFibGVUeXBlRW51bS5DT01QT1NFRDpcbiAgICAgICAgcmV0dXJuICdjb21wb3NlZCc7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gJ3RleHQnO1xuICAgIH1cbiAgfVxuXG4gIGlzRWRpdGFibGUoa2V5OiBzdHJpbmcgfCB1bmRlZmluZWQpOiBib29sZWFuIHtcbiAgICBpZiAoIWtleSkgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IGNvbHVtbiA9IHRoaXMuY29sdW1ucy5maW5kKChpdGVtKSA9PiBpdGVtLmNvZGUgPT09IGtleSk7XG4gICAgcmV0dXJuIGNvbHVtbj8uaXNFZGl0YWJsZSAhPT0gZmFsc2U7XG4gIH1cblxuICBpc011bHRpU2VsZWN0KGtleTogYW55KTogYm9vbGVhbiB7XG4gICAgY29uc3QgY29sdW1uID0gdGhpcy5jb2x1bW5zLmZpbmQoKGl0ZW0pID0+IGl0ZW0uY29kZSA9PT0ga2V5KTtcbiAgICBpZiAoXG4gICAgICBjb2x1bW4/LnR5cGUgPT09IFRhYmxlVHlwZUVudW0uTVVMVElTRUxFQ1QgJiZcbiAgICAgIGNvbHVtbi5vcHRpb25zICYmXG4gICAgICBjb2x1bW4uY29kZSAhPT0gdW5kZWZpbmVkXG4gICAgKSB7XG4gICAgICB0aGlzLm9wdGlvbkVudHJpZXMgPSBuZXcgTWFwKFtcbiAgICAgICAgW2NvbHVtbi5jb2RlIGFzIHN0cmluZywgT2JqZWN0LnZhbHVlcyhjb2x1bW4ub3B0aW9ucyldLFxuICAgICAgXSk7XG4gICAgICB0aGlzLm9wdGlvblZhbHVlcyA9IHRoaXMub3B0aW9uRW50cmllcy5nZXQoa2V5KSB8fCBbXTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpc0RhdGVQaWNrZXIoa2V5OiBhbnkpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5jb2x1bW5zLmZpbmQoKGl0ZW0pID0+IGl0ZW0uY29kZSA9PT0ga2V5KT8udHlwZSA9PT1cbiAgICAgIFRhYmxlVHlwZUVudW0uREFURVxuICAgICk7XG4gIH1cblxuICBkYXRlQ29udmVydGVyKHZhbHVlOiBhbnkpOiBzdHJpbmcge1xuICAgIHJldHVybiBuZXcgRGF0ZSh2YWx1ZSkudG9Mb2NhbGVEYXRlU3RyaW5nKCdlbi1VUycpO1xuICB9XG5cbiAgZ2V0Q3VycmVuY3lTeW1ib2woY29sdW1uOiBUYWJsZUNvbHVtbik6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIGNvbHVtbi50eXBlID09PSBUYWJsZVR5cGVFbnVtLkFNT1VOVCAmJlxuICAgICAgY29sdW1uLmN1cnJlbmN5ICYmXG4gICAgICB0aGlzLmlzVmFsaWRDdXJyZW5jeUNvZGUoY29sdW1uLmN1cnJlbmN5KVxuICAgICAgPyBjb2x1bW4uY3VycmVuY3lcbiAgICAgIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgcHJpdmF0ZSBpc1ZhbGlkQ3VycmVuY3lDb2RlKGN1cnJlbmN5Q29kZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMudmFsaWRDdXJyZW5jeUNvZGVzLmluY2x1ZGVzKGN1cnJlbmN5Q29kZSk7XG4gIH1cblxuICBmaWx0ZXJHbG9iYWwoZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQ7XG4gICAgY29uc3QgdmFsdWUgPSB0YXJnZXQudmFsdWUudG9Mb3dlckNhc2UoKTtcblxuICAgIGNvbnN0IGZpbHRlcmVkRGF0YSA9IHRoaXMuZGF0YS5maWx0ZXIoKGl0ZW0pID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmdsb2JhbEZpbHRlckZpZWxkcy5zb21lKChmaWVsZCkgPT4ge1xuICAgICAgICBjb25zdCBjb2x1bW4gPSB0aGlzLmNvbHVtbnMuZmluZCgoY29sKSA9PiBjb2wuY29kZSA9PT0gZmllbGQpO1xuICAgICAgICBpZiAoIWNvbHVtbikge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb2x1bW4udHlwZSA9PT0gVGFibGVUeXBlRW51bS5EQVRFKSB7XG4gICAgICAgICAgY29uc3QgaXRlbURhdGUgPSB0aGlzLmZvcm1hdERhdGUoaXRlbVtmaWVsZF0pO1xuICAgICAgICAgIHJldHVybiBpdGVtRGF0ZSAmJiBpdGVtRGF0ZS5pbmNsdWRlcyh2YWx1ZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgY29sdW1uLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uQU1PVU5UIHx8XG4gICAgICAgICAgY29sdW1uLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uTlVNQkVSXG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBpdGVtW2ZpZWxkXSAmJiBpdGVtW2ZpZWxkXS50b1N0cmluZygpLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXModmFsdWUpXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIGlmIChjb2x1bW4udHlwZSA9PT0gVGFibGVUeXBlRW51bS5DT01QT1NFRCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLmZpbHRlckNvbXBvc2VkQ29sdW1uKGl0ZW1bZmllbGRdLCB2YWx1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIGl0ZW1bZmllbGRdICYmIGl0ZW1bZmllbGRdLnRvU3RyaW5nKCkudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyh2YWx1ZSlcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRoaXMuZHQudmFsdWUgPSBmaWx0ZXJlZERhdGE7XG5cbiAgICAvLyDim5QgbmUgcGFzIHRvdWNoZXIgw6AgdG90YWxSZWNvcmRzIGVuIG1vZGUgc2VydmV1clxuICAgIC8vIHRoaXMudG90YWxSZWNvcmRzID0gZmlsdGVyZWREYXRhLmxlbmd0aCA/PyAwO1xuICB9XG5cbiAgcHJpdmF0ZSBmaWx0ZXJDb21wb3NlZENvbHVtbihjb21wb3NlZERhdGE6IGFueSwgdmFsdWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGlmIChjb21wb3NlZERhdGEpIHtcbiAgICAgIHJldHVybiBPYmplY3Qua2V5cyhjb21wb3NlZERhdGEpLnNvbWUoKGtleSkgPT4ge1xuICAgICAgICBjb25zdCBjZWxsVmFsdWUgPSBjb21wb3NlZERhdGFba2V5XTtcbiAgICAgICAgaWYgKHR5cGVvZiBjZWxsVmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgcmV0dXJuIGNlbGxWYWx1ZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZm9ybWF0RGF0ZShkYXRlOiBhbnkpOiBzdHJpbmcge1xuICAgIGlmICghZGF0ZSkgcmV0dXJuICcnO1xuICAgIGlmIChkYXRlIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgY29uc3QgZGF5ID0gZGF0ZS5nZXREYXRlKCkudG9TdHJpbmcoKS5wYWRTdGFydCgyLCAnMCcpO1xuICAgICAgY29uc3QgbW9udGggPSAoZGF0ZS5nZXRNb250aCgpICsgMSkudG9TdHJpbmcoKS5wYWRTdGFydCgyLCAnMCcpO1xuICAgICAgY29uc3QgeWVhciA9IGRhdGUuZ2V0RnVsbFllYXIoKS50b1N0cmluZygpO1xuICAgICAgcmV0dXJuIGAke2RheX0vJHttb250aH0vJHt5ZWFyfWA7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZGF0ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGNvbnN0IHBhcnRzID0gZGF0ZS5zcGxpdCgnLycpO1xuICAgICAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMykge1xuICAgICAgICByZXR1cm4gYCR7cGFydHNbMF19LyR7cGFydHNbMV19LyR7cGFydHNbMl19YDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBkYXRlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICBleHBvcnRFeGNlbCgpIHtcbiAgICB0aGlzLmV4cG9ydEV4Y2VsRXZlbnQuZW1pdCgpO1xuICB9XG5cbiAgZXhwb3J0UGRmKCkge1xuICAgIHRoaXMuZXhwb3J0UGRmRXZlbnQuZW1pdCgpO1xuICB9XG5cbiAgZ2V0SW1hZ2VTdHlsZShzdHlsZTogVGl0bGVTdHlsZSB8IEltYWdlU3R5bGUgfCB1bmRlZmluZWQpOiB7XG4gICAgW2tleTogc3RyaW5nXTogc3RyaW5nO1xuICB9IHtcbiAgICBpZiAoc3R5bGUpIHtcbiAgICAgIGNvbnN0IGltYWdlU3R5bGU6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gPSB7XG4gICAgICAgIHdpZHRoOiAoc3R5bGUgYXMgSW1hZ2VTdHlsZSkud2lkdGggfHwgJ2F1dG8nLFxuICAgICAgICBoZWlnaHQ6IChzdHlsZSBhcyBJbWFnZVN0eWxlKS5oZWlnaHQgfHwgJ2F1dG8nLFxuICAgICAgfTtcblxuICAgICAgaWYgKChzdHlsZSBhcyBJbWFnZVN0eWxlKS5tYXJnaW4pIHtcbiAgICAgICAgaW1hZ2VTdHlsZS5tYXJnaW4gPSAoc3R5bGUgYXMgSW1hZ2VTdHlsZSkubWFyZ2luITtcbiAgICAgIH1cbiAgICAgIGlmICgoc3R5bGUgYXMgSW1hZ2VTdHlsZSkubWFyZ2luTGVmdCkge1xuICAgICAgICBpbWFnZVN0eWxlLm1hcmdpbkxlZnQgPSAoc3R5bGUgYXMgSW1hZ2VTdHlsZSkubWFyZ2luTGVmdCE7XG4gICAgICB9XG4gICAgICBpZiAoKHN0eWxlIGFzIEltYWdlU3R5bGUpLm1hcmdpblJpZ2h0KSB7XG4gICAgICAgIGltYWdlU3R5bGUubWFyZ2luUmlnaHQgPSAoc3R5bGUgYXMgSW1hZ2VTdHlsZSkubWFyZ2luUmlnaHQhO1xuICAgICAgfVxuICAgICAgaWYgKChzdHlsZSBhcyBJbWFnZVN0eWxlKS5tYXJnaW5Ub3ApIHtcbiAgICAgICAgaW1hZ2VTdHlsZS5tYXJnaW5Ub3AgPSAoc3R5bGUgYXMgSW1hZ2VTdHlsZSkubWFyZ2luVG9wITtcbiAgICAgIH1cbiAgICAgIGlmICgoc3R5bGUgYXMgSW1hZ2VTdHlsZSkubWFyZ2luQm90dG9tKSB7XG4gICAgICAgIGltYWdlU3R5bGUubWFyZ2luQm90dG9tID0gKHN0eWxlIGFzIEltYWdlU3R5bGUpLm1hcmdpbkJvdHRvbSE7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBpbWFnZVN0eWxlO1xuICAgIH1cblxuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIGdldFRpdGxlU3R5bGUoc3R5bGU6IFRpdGxlU3R5bGUgfCBJbWFnZVN0eWxlIHwgdW5kZWZpbmVkKToge1xuICAgIFtrZXk6IHN0cmluZ106IHN0cmluZztcbiAgfSB7XG4gICAgaWYgKHN0eWxlKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb2xvcjogc3R5bGUuY29sb3IgfHwgJ2luaGVyaXQnLFxuICAgICAgICBmb250U2l6ZTogKHN0eWxlIGFzIFRpdGxlU3R5bGUpLmZvbnRTaXplIHx8ICdpbmhlcml0JyxcbiAgICAgICAgdGV4dEFsaWduOiAoc3R5bGUgYXMgVGl0bGVTdHlsZSkucG9zaXRpb24gfHwgJ2xlZnQnLFxuICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHt9O1xuICB9XG5cbiAgZm9ybWF0TnVtYmVyKFxuICAgIHZhbHVlOiBudW1iZXIsXG4gICAgZGVjaW1hbFBsYWNlcz86IG51bWJlcixcbiAgICB0aG91c2FuZFNlcGFyYXRvcjogJ2NvbW1hJyB8ICdzcGFjZScgPSAnY29tbWEnLFxuICAgIGRlY2ltYWxTZXBhcmF0b3I6ICdjb21tYScgfCAnZG90JyA9ICdkb3QnXG4gICk6IHN0cmluZyB7XG4gICAgaWYgKHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQgfHwgaXNOYU4odmFsdWUpKSByZXR1cm4gJyc7XG5cbiAgICBsZXQgZm9ybWF0dGVkTnVtYmVyID1cbiAgICAgIGRlY2ltYWxQbGFjZXMgIT09IHVuZGVmaW5lZFxuICAgICAgICA/IHZhbHVlLnRvRml4ZWQoZGVjaW1hbFBsYWNlcylcbiAgICAgICAgOiB2YWx1ZS50b1N0cmluZygpO1xuXG4gICAgaWYgKGRlY2ltYWxTZXBhcmF0b3IgPT09ICdjb21tYScpIHtcbiAgICAgIGZvcm1hdHRlZE51bWJlciA9IGZvcm1hdHRlZE51bWJlci5yZXBsYWNlKCcuJywgJywnKTtcbiAgICB9XG5cbiAgICBpZiAodGhvdXNhbmRTZXBhcmF0b3IgJiYgTWF0aC5hYnModmFsdWUpID49IDEwMDApIHtcbiAgICAgIGNvbnN0IHBhcnRzID0gZm9ybWF0dGVkTnVtYmVyLnNwbGl0KFxuICAgICAgICBkZWNpbWFsU2VwYXJhdG9yID09PSAnY29tbWEnID8gJywnIDogJy4nXG4gICAgICApO1xuICAgICAgcGFydHNbMF0gPSBwYXJ0c1swXS5yZXBsYWNlKFxuICAgICAgICAvXFxCKD89KFxcZHszfSkrKD8hXFxkKSkvZyxcbiAgICAgICAgdGhvdXNhbmRTZXBhcmF0b3IgPT09ICdjb21tYScgPyAnLCcgOiAnICdcbiAgICAgICk7XG4gICAgICBmb3JtYXR0ZWROdW1iZXIgPSBwYXJ0cy5qb2luKGRlY2ltYWxTZXBhcmF0b3IgPT09ICdjb21tYScgPyAnLCcgOiAnLicpO1xuICAgIH1cblxuICAgIHJldHVybiBmb3JtYXR0ZWROdW1iZXI7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJwdC1hZHZhbmNlZC1wcmltZS10YWJsZSB0YWJsZS1jb250YWluZXJcIj5cbiAgPHAtdGFibGVcbiAgICAjZHRcbiAgICBbdmFsdWVdPVwiZGF0YVwiXG4gICAgW2xvYWRpbmddPVwibG9hZGluZ1wiXG4gICAgW3Jvd3NdPVwicm93c1wiXG4gICAgW3BhZ2luYXRvcl09XCJpc1BhZ2luYXRlZFwiXG4gICAgW2dsb2JhbEZpbHRlckZpZWxkc109XCJnbG9iYWxGaWx0ZXJGaWVsZHNcIlxuICAgIFtyb3dzUGVyUGFnZU9wdGlvbnNdPVwicm93c1BlclBhZ2VcIlxuICAgIFt0b3RhbFJlY29yZHNdPVwidG90YWxSZWNvcmRzXCJcbiAgICBbbGF6eV09XCJ0cnVlXCJcbiAgICBkYXRhS2V5PVwiaWRcIlxuICAgIHN0eWxlQ2xhc3M9XCJwLWRhdGF0YWJsZS1ncmlkbGluZXMgcC1kYXRhdGFibGUtc3RyaXBlZFwiXG4gICAgW3Njcm9sbGFibGVdPVwidHJ1ZVwiXG4gICAgW3Njcm9sbEhlaWdodF09XCJtYXhIZWlnaHQgIT09IG51bGwgPyBtYXhIZWlnaHQgOiB1bmRlZmluZWRcIlxuICAgIChvbkZpbHRlcik9XCJvbkZpbHRlcigkZXZlbnQpXCJcbiAgICAob25QYWdlKT1cIm9uUGFnZUNoYW5nZSgkZXZlbnQpXCJcbiAgPlxuICAgIDwhLS0gQ09MR1JPVVA6IHN5bmMgaGVhZGVyL2JvZHkgd2lkdGhzIChpbmNsLiBBY3Rpb25zIDQxMHB4KSAtLT5cbiAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiY29sZ3JvdXBcIiBsZXQtY29sdW1ucz5cbiAgICAgIDxjb2xncm91cD5cbiAgICAgICAgPGNvbFxuICAgICAgICAgICpuZ0Zvcj1cImxldCBjb2wgb2YgY29sdW1uc1wiXG4gICAgICAgICAgW3N0eWxlLndpZHRoXT1cImNvbC53aWR0aCB8fCBnZXRIZWFkZXJXaWR0aChjb2wpXCJcbiAgICAgICAgLz5cbiAgICAgIDwvY29sZ3JvdXA+XG4gICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgIDwhLS0gQ0FQVElPTiAtLT5cbiAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiY2FwdGlvblwiPlxuICAgICAgPGRpdiBjbGFzcz1cImZsZXhcIj5cbiAgICAgICAgPGRpdj5cbiAgICAgICAgICA8aDM+VG90YWw6IHt7IHRvdGFsUmVjb3JkcyB9fTwvaDM+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXY+XG4gICAgICAgICAgPCEtLSBDbGVhciBmaWx0ZXJzIC0tPlxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICpuZ0lmPVwiaGFzU2VhcmNoRmlsdGVyXCJcbiAgICAgICAgICAgIHBCdXR0b25cbiAgICAgICAgICAgIGljb249XCJwaSBwaS1maWx0ZXItc2xhc2hcIlxuICAgICAgICAgICAgY2xhc3M9XCJwLWJ1dHRvbi1yb3VuZGVkIHAtYnV0dG9uLXRleHRcIlxuICAgICAgICAgICAgKGNsaWNrKT1cImNsZWFyKGR0KVwiXG4gICAgICAgICAgICB0aXRsZT1cIkNsZWFyIGZpbHRlcnNcIlxuICAgICAgICAgID48L2J1dHRvbj5cblxuICAgICAgICAgIDwhLS0gRXhwb3J0IHRvIEV4Y2VsIEJ1dHRvbiAtLT5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAqbmdJZj1cImhhc0V4cG9ydEV4Y2VsXCJcbiAgICAgICAgICAgIHBCdXR0b25cbiAgICAgICAgICAgIGljb249XCJwaSBwaS1maWxlLWV4Y2VsXCJcbiAgICAgICAgICAgIGNsYXNzPVwicC1idXR0b24tcm91bmRlZCBwLWJ1dHRvbi10ZXh0XCJcbiAgICAgICAgICAgIChjbGljayk9XCJleHBvcnRFeGNlbCgpXCJcbiAgICAgICAgICAgIHRpdGxlPVwiRXhwb3J0IHRvIEV4Y2VsXCJcbiAgICAgICAgICA+PC9idXR0b24+XG5cbiAgICAgICAgICA8IS0tIEV4cG9ydCB0byBQREYgQnV0dG9uIC0tPlxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICpuZ0lmPVwiaGFzRXhwb3J0UERGXCJcbiAgICAgICAgICAgIHBCdXR0b25cbiAgICAgICAgICAgIGljb249XCJwaSBwaS1maWxlLXBkZlwiXG4gICAgICAgICAgICBjbGFzcz1cInAtYnV0dG9uLXJvdW5kZWQgcC1idXR0b24tdGV4dFwiXG4gICAgICAgICAgICAoY2xpY2spPVwiZXhwb3J0UGRmKClcIlxuICAgICAgICAgICAgdGl0bGU9XCJFeHBvcnQgdG8gUERGXCJcbiAgICAgICAgICA+PC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJtbC1hdXRvXCIgKm5nSWY9XCJoYXNTZWFyY2hGaWx0ZXJcIj5cbiAgICAgICAgICA8cC1pY29uRmllbGQgaWNvblBvc2l0aW9uPVwibGVmdFwiIGNsYXNzPVwibWwtYXV0b1wiPlxuICAgICAgICAgICAgPHAtaW5wdXRJY29uPlxuICAgICAgICAgICAgICA8aSBjbGFzcz1cInBpIHBpLXNlYXJjaFwiPjwvaT5cbiAgICAgICAgICAgIDwvcC1pbnB1dEljb24+XG4gICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgcElucHV0VGV4dFxuICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgIFsobmdNb2RlbCldPVwic2VhcmNoVmFsdWVcIlxuICAgICAgICAgICAgICAoaW5wdXQpPVwiZmlsdGVyR2xvYmFsKCRldmVudClcIlxuICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIlNlYXJjaCBrZXl3b3JkXCJcbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgPC9wLWljb25GaWVsZD5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgPCEtLSBIRUFERVIgLS0+XG4gICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cImhlYWRlclwiPlxuICAgICAgPHRyIGNsYXNzPVwic3RpY2t5LWhlYWRlclwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBjb2wgb2YgY29sdW1uc1wiPlxuICAgICAgICAgIDx0aFxuICAgICAgICAgICAgKm5nSWY9XCIhY29sLmNoaWxkcmVuOyBlbHNlIGdyb3VwSGVhZGVyXCJcbiAgICAgICAgICAgIHBTb3J0YWJsZUNvbHVtbj1cInt7IGNvbC5jb2RlIH19XCJcbiAgICAgICAgICAgIFtzdHlsZS53aWR0aF09XCJjb2wud2lkdGggfHwgZ2V0SGVhZGVyV2lkdGgoY29sKVwiXG4gICAgICAgICAgICBbc3R5bGUucGFkZGluZ109XCInMHB4J1wiXG4gICAgICAgICAgICBbbmdDbGFzc109XCJbXG4gICAgICAgICAgICAgIGdldEhlYWRlckFsaWduQ2xhc3MoY29sKSxcbiAgICAgICAgICAgICAgY29sLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uQUNUSU9OID8gJ2FjdGlvbi1jb2x1bW4nIDogJydcbiAgICAgICAgICAgIF1cIlxuICAgICAgICAgICAgY29sc3Bhbj1cIjFcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDwhLS0gU09SVEFCTEUgSEVBREVSIC0tPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAqbmdJZj1cImlzU29ydGFibGUgJiYgY29sLmlzU29ydGFibGUgIT09IGZhbHNlOyBlbHNlIG5vU29ydEhlYWRlclwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICBjbGFzcz1cImhlYWRlci1jb250YWluZXIgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlblwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLndpZHRoXT1cImNvbC53aWR0aCB8fCBnZXRIZWFkZXJXaWR0aChjb2wpXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUucGFkZGluZ109XCInMHB4J1wiXG4gICAgICAgICAgICAgICAgW3N0eWxlLm1hcmdpbl09XCInMTBweCdcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPHNwYW4gW25nQ2xhc3NdPVwiZ2V0SGVhZGVyVGl0bGVDbGFzcyhjb2wpXCI+XG4gICAgICAgICAgICAgICAgICB7eyBjb2wudGl0bGUgfX1cbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJpY29ucyBkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCJcbiAgICAgICAgICAgICAgICAgIFtzdHlsZS53aWR0aF09XCInNzdweCdcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgIDxwLXNvcnRJY29uIGZpZWxkPVwie3sgY29sLmNvZGUgfX1cIiAvPlxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbC5pc0ZpbHRlciAhPT0gZmFsc2VcIj5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBDT01QT1NFRCBGSUxURVIgLS0+XG4gICAgICAgICAgICAgICAgICAgIDxwLWNvbHVtbkZpbHRlclxuICAgICAgICAgICAgICAgICAgICAgIGRpc3BsYXk9XCJtZW51XCJcbiAgICAgICAgICAgICAgICAgICAgICBbZmllbGRdPVwiY29sLmNvZGVcIlxuICAgICAgICAgICAgICAgICAgICAgIFt0eXBlXT1cImdldENvbHVtbkZpbHRlclR5cGUoY29sKVwiXG4gICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb2wudHlwZSA9PT0gVGFibGVUeXBlRW51bS5DT01QT1NFRFwiXG4gICAgICAgICAgICAgICAgICAgICAgc2hvd0NsZWFyQnV0dG9uPVwiZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgICAgIHNob3dBcHBseUJ1dHRvbj1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgcFRlbXBsYXRlPVwiZmlsdGVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldC12YWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0LWZpbHRlckNhbGxiYWNrPVwiZmlsdGVyQ2FsbGJhY2tcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKG9uRmlsdGVyKT1cIm9uRmlsdGVyKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IGNvbXBvc2VkTmFtZSBvZiBjb2wuY29tcG9zZWROYW1lc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldENvbXBvc2VkRmllbGRUeXBlKGNvbCwgY29tcG9zZWROYW1lKSA9PT1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRhYmxlVHlwZUVudW0uU1RSSU5HXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwLW11bHRpU2VsZWN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJmaWx0ZXJzW2NvbXBvc2VkTmFtZV0/LnZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25zXT1cImZpbHRlcnNbY29tcG9zZWROYW1lXT8ub3B0aW9uc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob25DaGFuZ2UpPVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uQ29tcG9zZWRGaWx0ZXJDaGFuZ2UoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvc2VkTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZXZlbnQudmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJmaWx0ZXJzW2NvbXBvc2VkTmFtZV0/LnBsYWNlaG9sZGVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNwbGF5XT1cIidjaGlwJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIGxldC1pdGVtIHBUZW1wbGF0ZT1cIml0ZW1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImN1c3RvbS1tdWx0aXNlbGVjdC1pdGVtXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJpdGVtLmltYWdlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzcmNdPVwiaXRlbS5pbWFnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbHQ9XCJpY29uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmlsdGVyLWltYWdlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPnt7IGl0ZW0ubGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3AtbXVsdGlTZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBsZXQtaXRlbSBwVGVtcGxhdGU9XCJpdGVtXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjdXN0b20tbXVsdGlzZWxlY3QtaXRlbVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiaXRlbS5pbWFnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3JjXT1cIml0ZW0uaW1hZ2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWx0PVwiaWNvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZpbHRlci1pbWFnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj57eyBpdGVtLmxhYmVsIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgPC9wLWNvbHVtbkZpbHRlcj5cblxuICAgICAgICAgICAgICAgICAgICA8IS0tIE9USEVSIFRZUEVTIC0tPlxuICAgICAgICAgICAgICAgICAgICA8cC1jb2x1bW5GaWx0ZXJcbiAgICAgICAgICAgICAgICAgICAgICBkaXNwbGF5PVwibWVudVwiXG4gICAgICAgICAgICAgICAgICAgICAgW2ZpZWxkXT1cImNvbC5jb2RlXCJcbiAgICAgICAgICAgICAgICAgICAgICBbdHlwZV09XCJnZXRDb2x1bW5GaWx0ZXJUeXBlKGNvbClcIlxuICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29sLnR5cGUgIT09IFRhYmxlVHlwZUVudW0uQ09NUE9TRURcIlxuICAgICAgICAgICAgICAgICAgICAgIGhpZGVPbkNsZWFyPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICA8IS0tIE5VTUJFUiAtLT5cbiAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgIHBUZW1wbGF0ZT1cImZpbHRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQtdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldC1maWx0ZXJDYWxsYmFjaz1cImZpbHRlckNhbGxiYWNrXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29sLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uTlVNQkVSXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChvbkZpbHRlcik9XCJvbkZpbHRlcigkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcElucHV0VGV4dFxuICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0ZXBdPVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sLmRlY2ltYWxQbGFjZXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gJzAuJyArICcxJy5wYWRFbmQoY29sLmRlY2ltYWxQbGFjZXMsICcwJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogJ2FueSdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwidmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJmaWx0ZXJDYWxsYmFjaygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJFbnRlciBhIG51bWJlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgICAgICAgICAgICAgICA8IS0tIERBVEUgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICBwVGVtcGxhdGU9XCJmaWx0ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0LXZhbHVlXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQtZmlsdGVyQ2FsbGJhY2s9XCJmaWx0ZXJDYWxsYmFja1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbC50eXBlID09PSBUYWJsZVR5cGVFbnVtLkRBVEVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKG9uRmlsdGVyKT1cIm9uRmlsdGVyKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxwLWNhbGVuZGFyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cInZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25DYWxlbmRhckZpbHRlckNoYW5nZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRldmVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5jb2RlISxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlckNhbGxiYWNrXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRlRm9ybWF0PVwiZGQvbW0veXlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIkNob29zZSBhIGRhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgPjwvcC1jYWxlbmRhcj5cbiAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgICAgICAgICAgICAgICAgPCEtLSBNVUxUSVNFTEVDVCAtLT5cbiAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgIHBUZW1wbGF0ZT1cImZpbHRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQtdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldC1maWx0ZXJDYWxsYmFjaz1cImZpbHRlckNhbGxiYWNrXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC50eXBlID09PSBUYWJsZVR5cGVFbnVtLk1VTFRJU0VMRUNUICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5maWx0ZXJPcHRpb25zICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5maWx0ZXJPcHRpb25zLmxlbmd0aCA+IDBcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAob25GaWx0ZXIpPVwib25GaWx0ZXIoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHAtbXVsdGlTZWxlY3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvbnNdPVwiY29sLmZpbHRlck9wdGlvbnNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJ2YWx1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cImZpbHRlckNhbGxiYWNrKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNwbGF5PVwiY2hpcFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiQ2hvb3NlIG9wdGlvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY3VzdG9tLW11bHRpc2VsZWN0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgID48L3AtbXVsdGlTZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgPC9wLWNvbHVtbkZpbHRlcj5cbiAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICA8IS0tIE5PTi1TT1JUQUJMRSBIRUFERVIgLS0+XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgI25vU29ydEhlYWRlcj5cbiAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgIGNsYXNzPVwiaGVhZGVyLWNvbnRhaW5lciBkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGp1c3RpZnktY29udGVudC1iZXR3ZWVuXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiY29sLndpZHRoIHx8IGdldEhlYWRlcldpZHRoKGNvbClcIlxuICAgICAgICAgICAgICAgIFtzdHlsZS5wYWRkaW5nXT1cIicwcHgnXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUubWFyZ2luXT1cIicxMHB4J1wiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8c3BhbiBbbmdDbGFzc109XCJnZXRIZWFkZXJUaXRsZUNsYXNzKGNvbClcIj5cbiAgICAgICAgICAgICAgICAgIHt7IGNvbC50aXRsZSB9fVxuICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29sLmlzRmlsdGVyICE9PSBmYWxzZVwiPlxuICAgICAgICAgICAgICAgICAgPHAtY29sdW1uRmlsdGVyXG4gICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29sLnR5cGUgPT09ICdBTU9VTlQnXCJcbiAgICAgICAgICAgICAgICAgICAgZGlzcGxheT1cIm1lbnVcIlxuICAgICAgICAgICAgICAgICAgICBbZmllbGRdPVwiY29sLmNvZGVcIlxuICAgICAgICAgICAgICAgICAgICBbdHlwZV09XCJnZXRDb2x1bW5GaWx0ZXJUeXBlKGNvbClcIlxuICAgICAgICAgICAgICAgICAgICBbY3VycmVuY3ldPVwiZ2V0Q3VycmVuY3lTeW1ib2woY29sKVwiXG4gICAgICAgICAgICAgICAgICA+PC9wLWNvbHVtbkZpbHRlcj5cblxuICAgICAgICAgICAgICAgICAgPHAtY29sdW1uRmlsdGVyXG4gICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29sLnR5cGUgIT09ICdBTU9VTlQnXCJcbiAgICAgICAgICAgICAgICAgICAgZGlzcGxheT1cIm1lbnVcIlxuICAgICAgICAgICAgICAgICAgICBbZmllbGRdPVwiY29sLmNvZGVcIlxuICAgICAgICAgICAgICAgICAgICBbdHlwZV09XCJnZXRDb2x1bW5GaWx0ZXJUeXBlKGNvbClcIlxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgICAgICAgICAgICBwVGVtcGxhdGU9XCJmaWx0ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgIGxldC12YWx1ZVxuICAgICAgICAgICAgICAgICAgICAgIGxldC1maWx0ZXJDYWxsYmFjaz1cImZpbHRlckNhbGxiYWNrXCJcbiAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImdldENvbHVtbkZpbHRlclR5cGUoY29sKSA9PT0gJ2RhdGUnXCJcbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgIDxwLWNhbGVuZGFyXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJ2YWx1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJmaWx0ZXJDYWxsYmFjaygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGVGb3JtYXQ9XCJkZC9tbS95eVwiXG4gICAgICAgICAgICAgICAgICAgICAgPjwvcC1jYWxlbmRhcj5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgICAgICAgICAgICBwVGVtcGxhdGU9XCJmaWx0ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgIGxldC12YWx1ZVxuICAgICAgICAgICAgICAgICAgICAgIGxldC1maWx0ZXJDYWxsYmFjaz1cImZpbHRlckNhbGxiYWNrXCJcbiAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImdldENvbHVtbkZpbHRlclR5cGUoY29sKSA9PT0gJ211bHRpU2VsZWN0J1wiXG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICA8cC1tdWx0aVNlbGVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvbnNdPVwiY29sLmZpbHRlck9wdGlvbnNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwidmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiZmlsdGVyQ2FsbGJhY2soJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNwbGF5PVwiY2hpcFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIlNlbGVjdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImN1c3RvbS1tdWx0aXNlbGVjdFwiXG4gICAgICAgICAgICAgICAgICAgICAgPjwvcC1tdWx0aVNlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgIDwvcC1jb2x1bW5GaWx0ZXI+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICA8L3RoPlxuXG4gICAgICAgICAgPCEtLSBHUk9VUEVEIEhFQURFUiAtLT5cbiAgICAgICAgICA8bmctdGVtcGxhdGUgI2dyb3VwSGVhZGVyPlxuICAgICAgICAgICAgPHRoXG4gICAgICAgICAgICAgIFthdHRyLmNvbHNwYW5dPVwiY29sLmNoaWxkcmVuPy5sZW5ndGhcIlxuICAgICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiY29sLndpZHRoIHx8IGdldEhlYWRlcldpZHRoKGNvbClcIlxuICAgICAgICAgICAgICBbbmdDbGFzc109XCJnZXRIZWFkZXJBbGlnbkNsYXNzKGNvbClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8c3Bhbj57eyBjb2wudGl0bGUgfX08L3NwYW4+XG4gICAgICAgICAgICA8L3RoPlxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPC90cj5cblxuICAgICAgPCEtLSBDSElMRCBIRUFERVJTIC0tPlxuICAgICAgPHRyICpuZ0lmPVwiaGFzR3JvdXBlZENvbHVtbnNcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgY29sIG9mIGNvbHVtbnNcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29sLmNoaWxkcmVuXCI+XG4gICAgICAgICAgICA8dGhcbiAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IGNoaWxkIG9mIGNvbC5jaGlsZHJlblwiXG4gICAgICAgICAgICAgIFtzdHlsZS53aWR0aF09XCJjaGlsZC53aWR0aCB8fCBnZXRIZWFkZXJXaWR0aChjaGlsZClcIlxuICAgICAgICAgICAgICBbc3R5bGUucGFkZGluZ109XCInMHB4J1wiXG4gICAgICAgICAgICA+PC90aD5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8L3RyPlxuICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICA8IS0tIEVNUFRZIE1FU1NBR0UgLS0+XG4gICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cImVtcHR5bWVzc2FnZVwiPlxuICAgICAgPGRpdiBjbGFzcz1cImVtcHR5LW1lc3NhZ2VcIj5cbiAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1pbmZvLWNpcmNsZVwiPjwvaT5cbiAgICAgICAgPHA+Tm8gcmVjb3JkcyBhdmFpbGFibGUgdG8gZGlzcGxheS48L3A+XG4gICAgICA8L2Rpdj5cbiAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgPCEtLSBCT0RZIC0tPlxuICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgcFRlbXBsYXRlPVwiYm9keVwiXG4gICAgICBsZXQtZGF0YVxuICAgICAgbGV0LWVkaXRpbmc9XCJlZGl0aW5nXCJcbiAgICAgIGxldC1yaT1cInJvd0luZGV4XCJcbiAgICA+XG4gICAgICA8dHIgKm5nSWY9XCIhbG9hZGluZ1wiIFtwRWRpdGFibGVSb3ddPVwiaXNFZGl0ID8gZGF0YSA6IG51bGxcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgY29sIG9mIGNvbHVtbnNcIj5cbiAgICAgICAgICA8IS0tIFNJTVBMRSBDT0xVTU5TIChubyBjaGlsZHJlbikgLS0+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFjb2wuY2hpbGRyZW47IGVsc2UgY2hpbGRDb2x1bW5zXCI+XG4gICAgICAgICAgICA8IS0tIEVESVRBQkxFIENFTEwgLS0+XG4gICAgICAgICAgICA8dGRcbiAgICAgICAgICAgICAgKm5nSWY9XCJcbiAgICAgICAgICAgICAgICBpc0VkaXRhYmxlKGNvbC5jb2RlISkgJiYgY29sLnR5cGUgIT09IFRhYmxlVHlwZUVudW0uQUNUSU9OO1xuICAgICAgICAgICAgICAgIGVsc2Ugbm9ybWFsVERcbiAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgW3N0eWxlLndpZHRoXT1cImNvbC53aWR0aCB8fCBnZXRIZWFkZXJXaWR0aChjb2wpXCJcbiAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiZ2V0RGF0YUFsaWduQ2xhc3MoY29sKVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDwhLS0gRWRpdGFibGUgaW5wdXQgZm9yIE5VTUJFUi9EQVRFL1NUUklORy9NVUxUSVNFTEVDVCAtLT5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzTXVsdGlTZWxlY3QoY29sLmNvZGUpOyBlbHNlIGRhdGVQaWNrZXJcIj5cbiAgICAgICAgICAgICAgICA8cC1jZWxsRWRpdG9yPlxuICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cImlucHV0XCI+XG4gICAgICAgICAgICAgICAgICAgIDxwLW11bHRpU2VsZWN0XG4gICAgICAgICAgICAgICAgICAgICAgYXBwZW5kVG89XCJib2R5XCJcbiAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJkYXRhW2NvbC5jb2RlIV1cIlxuICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZV09XCJ7IHdpZHRoOiAnMTAwJScgfVwiXG4gICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiY2hhbmdlSGFuZGxlcihkYXRhLmlkLCBjb2wuY29kZSwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgW29wdGlvbnNdPVwib3B0aW9uVmFsdWVzXCJcbiAgICAgICAgICAgICAgICAgICAgPjwvcC1tdWx0aVNlbGVjdD5cbiAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwib3V0cHV0XCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtdWx0aS1zZWxlY3QtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgcmVjIG9mIGRhdGFbY29sLmNvZGUhXVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHAtdGFnIFt2YWx1ZV09XCJyZWNcIj48L3AtdGFnPlxuICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgPC9wLWNlbGxFZGl0b3I+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZGF0ZVBpY2tlcj5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNEYXRlUGlja2VyKGNvbC5jb2RlKTsgZWxzZSBub3JtYWxJbnB1dFwiPlxuICAgICAgICAgICAgICAgICAgPHAtY2VsbEVkaXRvcj5cbiAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cImlucHV0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgPHAtY2FsZW5kYXJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtpbnB1dElkXT1cImRhdGFbY29sLmNvZGUhXVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJkYXRhW2NvbC5jb2RlIV1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZUhhbmRsZXIoZGF0YS5pZCwgY29sLmNvZGUsICRldmVudClcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbZGF0ZUZvcm1hdF09XCInZGQvbW0veXknXCJcbiAgICAgICAgICAgICAgICAgICAgICA+PC9wLWNhbGVuZGFyPlxuICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwib3V0cHV0XCI+XG4gICAgICAgICAgICAgICAgICAgICAge3sgZGF0YVtjb2wuY29kZSFdIHwgY3VzdG9tRGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgPC9wLWNlbGxFZGl0b3I+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNub3JtYWxJbnB1dD5cbiAgICAgICAgICAgICAgICA8cC1jZWxsRWRpdG9yPlxuICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cImlucHV0XCI+XG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgIHBJbnB1dFRleHRcbiAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwiZGF0YVtjb2wuY29kZSFdXCJcbiAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cIm9uQ2hhbmdlKCRldmVudCwgZGF0YS5pZCwgY29sLmNvZGUpXCJcbiAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwib3V0cHV0XCI+XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgY29sLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uQU1PVU5UO1xuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBub3JtYWxPdXRwdXRcbiAgICAgICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAge3tcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFbY29sLmNvZGUhXVxuICAgICAgICAgICAgICAgICAgICAgICAgICB8IGN1c3RvbUN1cnJlbmN5XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBnZXRDdXJyZW5jeVN5bWJvbChjb2wpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBjb2wuZGVjaW1hbFBsYWNlc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogY29sLnRob3VzYW5kU2VwYXJhdG9yXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBjb2wuZGVjaW1hbFNlcGFyYXRvclxuICAgICAgICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI25vcm1hbE91dHB1dD5cbiAgICAgICAgICAgICAgICAgICAgICB7eyBkYXRhW2NvbC5jb2RlIV0gfX1cbiAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgPC9wLWNlbGxFZGl0b3I+XG4gICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICA8L3RkPlxuXG4gICAgICAgICAgICA8IS0tIE5PTi1FRElUQUJMRSBDRUxMIChBTFdBWVMgUkVOREVSRUQpIC0tPlxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNub3JtYWxURD5cbiAgICAgICAgICAgICAgPHRkXG4gICAgICAgICAgICAgICAgW3N0eWxlLndpZHRoXT1cImNvbC53aWR0aCB8fCBnZXRIZWFkZXJXaWR0aChjb2wpXCJcbiAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJbXG4gICAgICAgICAgICAgICAgICBnZXREYXRhQWxpZ25DbGFzcyhjb2wpLFxuICAgICAgICAgICAgICAgICAgY29sLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uQUNUSU9OID8gJ2FjdGlvbi1jb2x1bW4nIDogJydcbiAgICAgICAgICAgICAgICBdXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDwhLS0gQUNUSU9OIGNvbHVtbjogYnVpbHQtaW4gZWRpdC9kZWxldGUgKyBjdXN0b20gYWN0aW9ucyAtLT5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbC50eXBlID09PSBUYWJsZVR5cGVFbnVtLkFDVElPTjsgZWxzZSBub25BY3Rpb25DZWxsXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWN0aW9uLWJ1dHRvbnMtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgIDwhLS0gYnVpbHQtaW4gZGVsZXRlIC0tPlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJpc0RlbGV0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgcEJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgIHBSaXBwbGVcbiAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICBpY29uPVwicGkgcGktdHJhc2hcIlxuICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJEZWxldGUoZGF0YS5pZClcIlxuICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwicC1idXR0b24tcm91bmRlZCBwLWJ1dHRvbi10ZXh0XCJcbiAgICAgICAgICAgICAgICAgICAgPjwvYnV0dG9uPlxuXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gYnVpbHQtaW4gaW5saW5lIGVkaXQgKG9sZCBiZWhhdmlvdXIpIC0tPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiaXNFZGl0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgcEluaXRFZGl0YWJsZVJvd1xuICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCIhZWRpdGluZ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBwQnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICBwUmlwcGxlXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGljb249XCJwaSBwaS1wZW5jaWxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImluaXRFZGl0YWJsZVJvdyhkYXRhKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInAtYnV0dG9uLXJvdW5kZWQgcC1idXR0b24tdGV4dFwiXG4gICAgICAgICAgICAgICAgICAgICAgPjwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiZWRpdGluZ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBwU2F2ZUVkaXRhYmxlUm93XG4gICAgICAgICAgICAgICAgICAgICAgICBwQnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICBwUmlwcGxlXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGljb249XCJwaSBwaS1jaGVja1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwic2F2ZUVkaXRhYmxlUm93KGRhdGEpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwicC1idXR0b24tcm91bmRlZCBwLWJ1dHRvbi10ZXh0XCJcbiAgICAgICAgICAgICAgICAgICAgICA+PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJlZGl0aW5nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBDYW5jZWxFZGl0YWJsZVJvd1xuICAgICAgICAgICAgICAgICAgICAgICAgcEJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgcFJpcHBsZVxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICBpY29uPVwicGkgcGktdGltZXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNhbmNlbEVkaXRhYmxlUm93KGRhdGEpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwicC1idXR0b24tcm91bmRlZCBwLWJ1dHRvbi10ZXh0XCJcbiAgICAgICAgICAgICAgICAgICAgICA+PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gY3VzdG9tIGFjdGlvbnMgLS0+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgYWN0IG9mIGN1c3RvbUFjdGlvbnNcIlxuICAgICAgICAgICAgICAgICAgICAgIHBCdXR0b25cbiAgICAgICAgICAgICAgICAgICAgICBwUmlwcGxlXG4gICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJwLWJ1dHRvbi1yb3VuZGVkIHAtYnV0dG9uLXRleHRcIlxuICAgICAgICAgICAgICAgICAgICAgIFtpY29uXT1cImFjdC5pY29uIHx8ICdwaSBwaS1lbGxpcHNpcy1oJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiYWN0LnN0eWxlQ2xhc3NcIlxuICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJvbkN1c3RvbUFjdGlvbkNsaWNrKGFjdCwgZGF0YSlcIlxuICAgICAgICAgICAgICAgICAgICA+PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgIDwhLS0gTk9OLUFDVElPTiBjZWxscyAtLT5cbiAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI25vbkFjdGlvbkNlbGw+XG4gICAgICAgICAgICAgICAgICA8IS0tIENPTVBPU0VEIC0tPlxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgICAgICAgICAgICAgIGNvbC50eXBlID09PSBUYWJsZVR5cGVFbnVtLkNPTVBPU0VEO1xuICAgICAgICAgICAgICAgICAgICAgIGVsc2Ugbm9uQ29tcG9zZWRcbiAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbXBvc2VkLWNlbGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAqbmdGb3I9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNvbXBvc2VkTmFtZSBvZiBjb2wuY29tcG9zZWROYW1lcztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGkgPSBpbmRleFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIElNQUdFIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5jb21wb3NlZFR5cGVzICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sLmNvbXBvc2VkVHlwZXNbaV0gPT09IFRhYmxlVHlwZUVudW0uSU1BR0VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzcmNdPVwiZGF0YVtjb2wuY29kZSFdPy5bY29tcG9zZWROYW1lXVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWx0PVwiY29tcG9zZWQtaW1nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNvbXBvc2VkLWltYWdlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldEltYWdlU3R5bGUoY29sLmNvbXBvc2VkU3R5bGVzPy5bY29tcG9zZWROYW1lXSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gU1RSSU5HIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5jb21wb3NlZFR5cGVzICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sLmNvbXBvc2VkVHlwZXNbaV0gPT09IFRhYmxlVHlwZUVudW0uU1RSSU5HXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjb21wb3NlZC10ZXh0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldFRpdGxlU3R5bGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5jb21wb3NlZFN0eWxlcz8uW2NvbXBvc2VkTmFtZV1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgZGF0YVtjb2wuY29kZSFdPy5bY29tcG9zZWROYW1lXSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNub25Db21wb3NlZD5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBBTU9VTlQtLT5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29sLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uQU1PVU5UOyBlbHNlIG5vbkFtb3VudFwiXG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICB7e1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVtjb2wuY29kZSFdXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHwgY3VzdG9tQ3VycmVuY3lcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGdldEN1cnJlbmN5U3ltYm9sKGNvbClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGNvbC5kZWNpbWFsUGxhY2VzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBjb2wudGhvdXNhbmRTZXBhcmF0b3JcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGNvbC5kZWNpbWFsU2VwYXJhdG9yXG4gICAgICAgICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNub25BbW91bnQ+XG4gICAgICAgICAgICAgICAgICAgICAgPCEtLSBOVU1CRVItLT5cbiAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wudHlwZSA9PT0gVGFibGVUeXBlRW51bS5OVU1CRVI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Ugbm9uTnVtYmVyXG4gICAgICAgICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdE51bWJlcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhW2NvbC5jb2RlIV0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sLmRlY2ltYWxQbGFjZXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sLnRob3VzYW5kU2VwYXJhdG9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5kZWNpbWFsU2VwYXJhdG9yXG4gICAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI25vbk51bWJlcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gREFURSAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wudHlwZSA9PT0gVGFibGVUeXBlRW51bS5EQVRFO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Ugbm9ybWFsVHlwZXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAge3sgZm9ybWF0RGF0ZShkYXRhW2NvbC5jb2RlIV0pIH19XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNub3JtYWxUeXBlcz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBTVFJJTkcsIE1VTFRJU0VMRUNULS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUYWJsZVR5cGVFbnVtLlNUUklORyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGFibGVUeXBlRW51bS5NVUxUSVNFTEVDVFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXS5pbmNsdWRlcyhjb2wudHlwZSEpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGRhdGFbY29sLmNvZGUhXSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICA8IS0tIENISUxEIENPTFVNTlMgLS0+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlICNjaGlsZENvbHVtbnM+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBjaGlsZCBvZiBjb2wuY2hpbGRyZW5cIj5cbiAgICAgICAgICAgICAgPHRkXG4gICAgICAgICAgICAgICAgW3N0eWxlLndpZHRoXT1cImNoaWxkLndpZHRoIHx8IGdldEhlYWRlcldpZHRoKGNoaWxkKVwiXG4gICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiZ2V0RGF0YUFsaWduQ2xhc3MoY2hpbGQpXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICpuZ0lmPVwiaXNFZGl0YWJsZShjaGlsZC5jb2RlKTsgZWxzZSBjaGlsZE5vcm1hbFREXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICA8cC1jZWxsRWRpdG9yPlxuICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiaW5wdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgIHBJbnB1dFRleHRcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cImNoaWxkLmNvZGUgPyBkYXRhW2NoaWxkLmNvZGVdIDogbnVsbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cIm9uQ2hhbmdlKCRldmVudCwgZGF0YS5pZCwgY2hpbGQuY29kZSlcIlxuICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJvdXRwdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICB7eyBjaGlsZC5jb2RlID8gZGF0YVtjaGlsZC5jb2RlXSA6IFwiXCIgfX1cbiAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgIDwvcC1jZWxsRWRpdG9yPlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNjaGlsZE5vcm1hbFREPlxuICAgICAgICAgICAgICAgICAge3sgY2hpbGQuY29kZSA/IGRhdGFbY2hpbGQuY29kZV0gOiBcIlwiIH19XG4gICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPC90cj5cbiAgICA8L25nLXRlbXBsYXRlPlxuICA8L3AtdGFibGU+XG48L2Rpdj5cbiJdfQ==
723
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHQtYWR2YW5jZWQtcHJpbWUtdGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmctcHJpbWUtdG9vbHMvc3JjL2xpYi9wdC1hZHZhbmNlZC1wcmltZS10YWJsZS9wdC1hZHZhbmNlZC1wcmltZS10YWJsZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1wcmltZS10b29scy9zcmMvbGliL3B0LWFkdmFuY2VkLXByaW1lLXRhYmxlL3B0LWFkdmFuY2VkLXByaW1lLXRhYmxlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFVLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDNUUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUU3QyxPQUFPLEVBQ0wsU0FBUyxFQUdULGFBQWEsR0FFZCxNQUFNLGtCQUFrQixDQUFDO0FBQzFCLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDOzs7Ozs7Ozs7Ozs7Ozs7QUFleEQsTUFBTSxPQUFPLDZCQUE2QjtJQWdFeEM7UUEvREEsU0FBUztRQUNBLFNBQUksR0FBVSxFQUFFLENBQUM7UUFDakIsWUFBTyxHQUFrQixFQUFFLENBQUM7UUFDNUIsaUJBQVksR0FBRyxDQUFDLENBQUM7UUFDakIsZ0JBQVcsR0FBYSxFQUFFLENBQUM7UUFDM0Isb0JBQWUsR0FBRyxLQUFLLENBQUM7UUFDeEIsbUJBQWMsR0FBRyxLQUFLLENBQUM7UUFDdkIsaUJBQVksR0FBRyxLQUFLLENBQUM7UUFDckIsb0JBQWUsR0FBRyxLQUFLLENBQUM7UUFDeEIsZ0JBQVcsR0FBRyxLQUFLLENBQUM7UUFFcEIsWUFBTyxHQUEwQixFQUFFLENBQUM7UUFFcEMsZUFBVSxHQUFHLEtBQUssQ0FBQztRQUNuQixZQUFP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QWM7c0JBQXRCLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBRUcsT0FBTztzQkFBZixLQUFLO2dCQUVHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBR0ksTUFBTTtzQkFBZixNQUFNO2dCQUNHLGdCQUFnQjtzQkFBekIsTUFBTTtnQkFDRyxjQUFjO3NCQUF2QixNQUFNO2dCQUNHLFlBQVk7c0JBQXJCLE1BQU07Z0JBQ0csWUFBWTtzQkFBckIsTUFBTTtnQkFDRyxjQUFjO3NCQUF2QixNQUFNO2dCQUU2QixFQUFFO3NCQUFyQyxTQUFTO3VCQUFDLElBQUksRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPbkluaXQsIE91dHB1dCwgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBFdmVudEVtaXR0ZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFRhYmxlIH0gZnJvbSAncHJpbWVuZy90YWJsZSc7XG5pbXBvcnQge1xuICBBbGlnbkVudW0sXG4gIEltYWdlU3R5bGUsXG4gIFRhYmxlQ29sdW1uLFxuICBUYWJsZVR5cGVFbnVtLFxuICBUaXRsZVN0eWxlLFxufSBmcm9tICcuLi8uLi9wdWJsaWMtYXBpJztcbmltcG9ydCB7IGNhbGN1bGF0ZVRleHRXaWR0aCB9IGZyb20gJy4uL3V0aWxzL3RleHQudXRpbCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUFRUYWJsZUFjdGlvbkNvbmZpZyB7XG4gIGNvZGU6IHN0cmluZztcbiAgaWNvbj86IHN0cmluZztcbiAgc3R5bGVDbGFzcz86IHN0cmluZztcbiAgdG9vbHRpcD86IHN0cmluZztcbiAgYWN0aW9uOiBhbnk7XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3B0LWFkdmFuY2VkLXByaW1lLXRhYmxlJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3B0LWFkdmFuY2VkLXByaW1lLXRhYmxlLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmw6ICcuL3B0LWFkdmFuY2VkLXByaW1lLXRhYmxlLmNvbXBvbmVudC5jc3MnLFxufSlcbmV4cG9ydCBjbGFzcyBQVEFkdmFuY2VkUHJpbWVUYWJsZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIC8vIElucHV0c1xuICBASW5wdXQoKSBkYXRhOiBhbnlbXSA9IFtdO1xuICBASW5wdXQoKSBjb2x1bW5zOiBUYWJsZUNvbHVtbltdID0gW107XG4gIEBJbnB1dCgpIHRvdGFsUmVjb3JkcyA9IDA7XG4gIEBJbnB1dCgpIHJvd3NQZXJQYWdlOiBudW1iZXJbXSA9IFtdO1xuICBASW5wdXQoKSBoYXNTZWFyY2hGaWx0ZXIgPSBmYWxzZTtcbiAgQElucHV0KCkgaGFzRXhwb3J0RXhjZWwgPSBmYWxzZTtcbiAgQElucHV0KCkgaGFzRXhwb3J0UERGID0gZmFsc2U7XG4gIEBJbnB1dCgpIGhhc0NvbHVtbkZpbHRlciA9IGZhbHNlO1xuICBASW5wdXQoKSBpc1BhZ2luYXRlZCA9IGZhbHNlO1xuXG4gIEBJbnB1dCgpIGFjdGlvbnM6IFBUVGFibGVBY3Rpb25Db25maWdbXSA9IFtdO1xuXG4gIEBJbnB1dCgpIGlzU29ydGFibGUgPSBmYWxzZTtcbiAgQElucHV0KCkgbG9hZGluZyA9IGZhbHNlO1xuICBASW5wdXQoKSBtYXhIZWlnaHQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG4gIC8vIE91dHB1dHNcbiAgQE91dHB1dCgpIHNlYXJjaCA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICBAT3V0cHV0KCkgZXhwb3J0RXhjZWxFdmVudCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgQE91dHB1dCgpIGV4cG9ydFBkZkV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICBAT3V0cHV0KCkgb25QYWdlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjx7IHBhZ2U6IG51bWJlcjsgcm93czogbnVtYmVyIH0+KCk7XG4gIEBPdXRwdXQoKSBvblNvcnRDb2x1bW4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgQE91dHB1dCgpIG9uRmlsdGVyQ29sdW1uID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG5cbiAgQFZpZXdDaGlsZCgnZHQnLCB7IHN0YXRpYzogZmFsc2UgfSkgZHQhOiBUYWJsZTtcblxuICBwdWJsaWMgVGFibGVUeXBlRW51bSA9IFRhYmxlVHlwZUVudW07XG4gIHB1YmxpYyBBbGlnbkVudW0gPSBBbGlnbkVudW07XG5cbiAgc2VhcmNoVmFsdWUgPSAnJztcblxuICAvLyB1c2VkIHRvIHN0b3JlIGNvbXBvc2VkIGZpbHRlciBVSSBzdGF0ZSAoYW5kIG9wdGlvbnMpXG4gIHB1YmxpYyBmaWx0ZXJzOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ID0ge307XG5cbiAgLy8gc3RvcmUgdGhlIGxhc3QgZmlsdGVyIHZhbHVlIHBlciBjb2x1bW4gZmllbGQgKGZvciBhbGwgZmlsdGVycylcbiAgbGF0ZXN0RmlsdGVyVmFsdWVzOiB7IFtmaWVsZDogc3RyaW5nXTogYW55IH0gPSB7fTtcblxuICBwcml2YXRlIHZhbGlkQ3VycmVuY3lDb2RlcyA9IFsnVVNEJywgJ0VVUicsICdNQUQnXTtcbiAgaWNvbldpZHRoID0gNzc7XG5cbiAgLy8gQ29tcG9uZW50IHN0YXRlXG4gIHJvd3MgPSAwO1xuICBoYXNHcm91cGVkQ29sdW1ucyA9IGZhbHNlO1xuXG4gIC8vIGVkaXQvZGVsZXRlIGZsYWdzXG4gIGlzRGVsZXRlID0gZmFsc2U7XG4gIGlzRWRpdCA9IGZhbHNlO1xuXG4gIERlbGV0ZTogKHZhbHVlOiBhbnkpID0+IHZvaWQgPSAoKSA9PiB7fTtcbiAgaW5pdEVkaXRhYmxlUm93OiAoZGF0YTogYW55KSA9PiB2b2lkID0gKCkgPT4ge307XG4gIHNhdmVFZGl0YWJsZVJvdzogKGRhdGE6IGFueSkgPT4gdm9pZCA9ICgpID0+IHt9O1xuICBjYW5jZWxFZGl0YWJsZVJvdzogKGl0ZW06IGFueSkgPT4gdm9pZCA9ICgpID0+IHt9O1xuXG4gIGN1c3RvbUFjdGlvbnM6IFBUVGFibGVBY3Rpb25Db25maWdbXSA9IFtdO1xuXG4gIC8vIERhdGEgbWFuYWdlbWVudFxuICBkYXRhTWFwID0gbmV3IE1hcDxhbnksIGFueT4oKTtcbiAgbWFwID0gbmV3IE1hcDxhbnksIE1hcDxhbnksIGFueT4+KCk7XG4gIG9wdGlvbkVudHJpZXMgPSBuZXcgTWFwPHN0cmluZywgYW55W10+KCk7XG4gIG9wdGlvblZhbHVlczogYW55W10gPSBbXTtcbiAgZ2xvYmFsRmlsdGVyRmllbGRzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIGNvbnN0cnVjdG9yKCkge31cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICBjb25zb2xlLmxvZygnUFRBZHZhbmNlZFByaW1lVGFibGUgY29sdW1uczonLCB0aGlzLmNvbHVtbnMpO1xuICAgIGNvbnNvbGUubG9nKCdQVEFkdmFuY2VkUHJpbWVUYWJsZSB0b3RhbFJlY29yZHMgaW5wdXQ6JywgdGhpcy50b3RhbFJlY29yZHMpO1xuXG4gICAgdGhpcy5oYXNHcm91cGVkQ29sdW1ucyA9IHRoaXMuY29sdW1ucy5zb21lKFxuICAgICAgKGNvbCkgPT4gY29sLmNoaWxkcmVuICYmIGNvbC5jaGlsZHJlbi5sZW5ndGggPiAwXG4gICAgKTtcblxuICAgIHRoaXMuZ2xvYmFsRmlsdGVyRmllbGRzID0gdGhpcy5jb2x1bW5zXG4gICAgICAuZmlsdGVyKChjb2wpID0+IGNvbC5jb2RlICE9PSB1bmRlZmluZWQgJiYgY29sLmlzRmlsdGVyICE9PSBmYWxzZSlcbiAgICAgIC5tYXAoKGNvbCkgPT4gY29sLmNvZGUgYXMgc3RyaW5nKTtcblxuICAgIHRoaXMuaW5pdGlhbGl6ZVBhZ2luYXRpb24oKTtcbiAgICB0aGlzLmluaXRpYWxpemVBY3Rpb25zKCk7XG5cbiAgICB0aGlzLmNvbHVtbnMuZm9yRWFjaCgoY29sKSA9PiB7XG4gICAgICBpZiAoY29sLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uQUNUSU9OKSB7XG4gICAgICAgIGNvbC5pc0VkaXRhYmxlID0gZmFsc2U7XG4gICAgICAgIGNvbC5pc0ZpbHRlciA9IGZhbHNlO1xuICAgICAgICBjb2wuaXNTb3J0YWJsZSA9IGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBpZiAoY29sLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uQ09NUE9TRUQpIHtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplQ29tcG9zZWRGaWx0ZXJzKGNvbCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb2wuaXNTb3J0YWJsZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbC5pc1NvcnRhYmxlID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbC5pc0VkaXRhYmxlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29sLmlzRWRpdGFibGUgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoY29sLmlzRmlsdGVyICE9PSBmYWxzZSAmJiBjb2wuY29kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuZ2xvYmFsRmlsdGVyRmllbGRzLnB1c2goY29sLmNvZGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWNvbC53aWR0aCkge1xuICAgICAgICBjb2wud2lkdGggPSB0aGlzLmNhbGN1bGF0ZUNvbHVtbldpZHRoKGNvbCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyAtLS0tLS0tLS0tIEhFQURFUiArIEJPRFkgQUxJR05NRU5UIEhFTFBFUlMgLS0tLS0tLS0tLVxuXG4gIGdldEhlYWRlclRpdGxlQ2xhc3MoY29sOiBUYWJsZUNvbHVtbik6IHN0cmluZyB7XG4gICAgY29uc3QgYWxpZ24gPSBjb2wuaGVhZGVyQWxpZ24gPz8gQWxpZ25FbnVtLkxFRlQ7XG4gICAgc3dpdGNoIChhbGlnbikge1xuICAgICAgY2FzZSBBbGlnbkVudW0uQ0VOVEVSOlxuICAgICAgICByZXR1cm4gJ2hlYWRlci10aXRsZS1jZW50ZXInO1xuICAgICAgY2FzZSBBbGlnbkVudW0uUklHSFQ6XG4gICAgICAgIHJldHVybiAnaGVhZGVyLXRpdGxlLXJpZ2h0JztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiAnaGVhZGVyLXRpdGxlLWxlZnQnO1xuICAgIH1cbiAgfVxuXG4gIGdldEhlYWRlckFsaWduQ2xhc3MoY29sOiBUYWJsZUNvbHVtbik6IHN0cmluZyB7XG4gICAgY29uc3QgYWxpZ24gPSBjb2wuaGVhZGVyQWxpZ24gPz8gQWxpZ25FbnVtLkxFRlQ7XG4gICAgc3dpdGNoIChhbGlnbikge1xuICAgICAgY2FzZSBBbGlnbkVudW0uQ0VOVEVSOlxuICAgICAgICByZXR1cm4gJ2hlYWRlci1hbGlnbi1jZW50ZXInO1xuICAgICAgY2FzZSBBbGlnbkVudW0uUklHSFQ6XG4gICAgICAgIHJldHVybiAnaGVhZGVyLWFsaWduLXJpZ2h0JztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiAnaGVhZGVyLWFsaWduLWxlZnQnO1xuICAgIH1cbiAgfVxuXG4gIGdldERhdGFBbGlnbkNsYXNzKGNvbDogVGFibGVDb2x1bW4pOiBzdHJpbmcge1xuICAgIGNvbnN0IGVmZmVjdGl2ZUFsaWduID1cbiAgICAgIGNvbC5kYXRhQWxpZ24gPz9cbiAgICAgIChjb2wudHlwZSA9PT0gVGFibGVUeXBlRW51bS5OVU1CRVIgfHwgY29sLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uQU1PVU5UXG4gICAgICAgID8gQWxpZ25FbnVtLlJJR0hUXG4gICAgICAgIDogQWxpZ25FbnVtLkxFRlQpO1xuXG4gICAgc3dpdGNoIChlZmZlY3RpdmVBbGlnbikge1xuICAgICAgY2FzZSBBbGlnbkVudW0uQ0VOVEVSOlxuICAgICAgICByZXR1cm4gJ2NlbGwtYWxpZ24tY2VudGVyJztcbiAgICAgIGNhc2UgQWxpZ25FbnVtLlJJR0hUOlxuICAgICAgICByZXR1cm4gJ2NlbGwtYWxpZ24tcmlnaHQnO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuICdjZWxsLWFsaWduLWxlZnQnO1xuICAgIH1cbiAgfVxuXG4gIC8vIC0tLS0tLS0tLS0gQUNUSU9OUyBJTklUSUFMSVpBVElPTiAtLS0tLS0tLS0tXG5cbiAgcHJpdmF0ZSBpbml0aWFsaXplQWN0aW9ucygpOiB2b2lkIHtcbiAgICB0aGlzLmlzRGVsZXRlID0gZmFsc2U7XG4gICAgdGhpcy5pc0VkaXQgPSBmYWxzZTtcbiAgICB0aGlzLkRlbGV0ZSA9ICgpID0+IHt9O1xuICAgIHRoaXMuaW5pdEVkaXRhYmxlUm93ID0gKCkgPT4ge307XG4gICAgdGhpcy5zYXZlRWRpdGFibGVSb3cgPSAoKSA9PiB7fTtcbiAgICB0aGlzLmNhbmNlbEVkaXRhYmxlUm93ID0gKCkgPT4ge307XG4gICAgdGhpcy5jdXN0b21BY3Rpb25zID0gW107XG5cbiAgICBpZiAoIXRoaXMuYWN0aW9ucyB8fCB0aGlzLmFjdGlvbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5hY3Rpb25zLmZvckVhY2goKGFjdGlvbikgPT4ge1xuICAgICAgc3dpdGNoIChhY3Rpb24uY29kZSkge1xuICAgICAgICBjYXNlICdkZWxldGUnOlxuICAgICAgICAgIHRoaXMuaXNEZWxldGUgPSB0cnVlO1xuICAgICAgICAgIHRoaXMuRGVsZXRlID0gKHZhbHVlOiBhbnkpID0+IGFjdGlvbi5hY3Rpb24odmFsdWUpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgJ2VkaXQnOlxuICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZUVkaXRBY3Rpb25zKGFjdGlvbik7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aGlzLmN1c3RvbUFjdGlvbnMucHVzaChhY3Rpb24pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBpbml0aWFsaXplRWRpdEFjdGlvbnMoYWN0aW9uOiBQVFRhYmxlQWN0aW9uQ29uZmlnKTogdm9pZCB7XG4gICAgdGhpcy5pc0VkaXQgPSB0cnVlO1xuICAgIHRoaXMuaW5pdEVkaXRhYmxlUm93ID0gKGRhdGE6IGFueSkgPT4gYWN0aW9uLmFjdGlvbi5pbml0KGRhdGEpO1xuICAgIHRoaXMuc2F2ZUVkaXRhYmxlUm93ID0gKGRhdGE6IGFueSkgPT4ge1xuICAgICAgY29uc3QgcmVjb3JkID0gdGhpcy5tYXAuZ2V0KGRhdGEuaWQpO1xuICAgICAgYWN0aW9uLmFjdGlvbi5zYXZlKGRhdGEsIHJlY29yZCk7XG4gICAgICB0aGlzLmRhdGFNYXAuY2xlYXIoKTtcbiAgICB9O1xuICAgIHRoaXMuY2FuY2VsRWRpdGFibGVSb3cgPSAoaXRlbTogYW55KSA9PiBjb25zb2xlLmxvZyhpdGVtKTtcbiAgfVxuXG4gIG9uQ3VzdG9tQWN0aW9uQ2xpY2soYWN0aW9uOiBQVFRhYmxlQWN0aW9uQ29uZmlnLCByb3c6IGFueSk6IHZvaWQge1xuICAgIGlmIChhY3Rpb24gJiYgdHlwZW9mIGFjdGlvbi5hY3Rpb24gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBhY3Rpb24uYWN0aW9uKHJvdyk7XG4gICAgICB9LCAwKTtcbiAgICB9XG4gIH1cblxuICAvLyAtLS0tLS0tLS0tIEZJTFRFUklORyAvIFNPUlRJTkcgLyBQQUdJTkFUSU9OIC0tLS0tLS0tLS1cblxuICAvKipcbiAgICogRm9yIGNvbXBvc2VkIGNvbHVtbnMsIHdlIHN0aWxsIHJlZ2lzdGVyIGZpbHRlcnMgdW5kZXIgZmlsdGVyc1tjb21wb3NlZE5hbWVdXG4gICAqIHRvIGtlZXAgb3B0aW9ucyAmIHBsYWNlaG9sZGVycy5cbiAgICovXG4gIHByaXZhdGUgaW5pdGlhbGl6ZUNvbXBvc2VkRmlsdGVycyhjb2w6IFRhYmxlQ29sdW1uKTogdm9pZCB7XG4gICAgY29sLmNvbXBvc2VkTmFtZXM/LmZvckVhY2goKGNvbXBvc2VkTmFtZSkgPT4ge1xuICAgICAgY29uc3QgY29kZSA9IChjb2wuY29kZSBhcyBzdHJpbmcpIHx8ICcnO1xuICAgICAgdGhpcy5nbG9iYWxGaWx0ZXJGaWVsZHMucHVzaChjb2RlICsgJy4nICsgY29tcG9zZWROYW1lKTtcbiAgICAgIHRoaXMuZmlsdGVyc1tjb21wb3NlZE5hbWVdID0ge1xuICAgICAgICBvcHRpb25zOiBjb2wuZmlsdGVyT3B0aW9ucyxcbiAgICAgICAgdmFsdWU6IFtdLFxuICAgICAgICBsYWJlbDogJ0ZpbHRlciBieSAnICsgY29tcG9zZWROYW1lLFxuICAgICAgICBwbGFjZWhvbGRlcjogJ1NlbGVjdCBvcHRpb24nLFxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldENvbXBvc2VkRmllbGRUeXBlKFxuICAgIGNvbDogVGFibGVDb2x1bW4sXG4gICAgY29tcG9zZWROYW1lOiBzdHJpbmdcbiAgKTogVGFibGVUeXBlRW51bSB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKGNvbC5jb21wb3NlZE5hbWVzICYmIGNvbC5jb21wb3NlZFR5cGVzKSB7XG4gICAgICBjb25zdCBpbmRleCA9IGNvbC5jb21wb3NlZE5hbWVzLmluZGV4T2YoY29tcG9zZWROYW1lKTtcbiAgICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgY29sLmNvbXBvc2VkVHlwZXMubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBjb2wuY29tcG9zZWRUeXBlc1tpbmRleF07XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBvbkNvbXBvc2VkQ29sdW1uQ2xlYXIoY29sOiBUYWJsZUNvbHVtbik6IHZvaWQge1xuICAgIGlmICghY29sLmNvZGUgfHwgIWNvbC5jb21wb3NlZE5hbWVzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29sLmNvbXBvc2VkTmFtZXMuZm9yRWFjaCgobmFtZSkgPT4ge1xuICAgICAgY29uc3Qga2V5ID0gYCR7Y29sLmNvZGV9LiR7bmFtZX1gO1xuICAgICAgZGVsZXRlIHRoaXMubGF0ZXN0RmlsdGVyVmFsdWVzW2tleV07XG5cbiAgICAgIGlmICh0aGlzLmZpbHRlcnNbbmFtZV0pIHtcbiAgICAgICAgdGhpcy5maWx0ZXJzW25hbWVdLnZhbHVlID0gW107XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgLyoqXG4gICAqIENPTVBPU0VEOiBjYWNoZSBVSSB2YWx1ZXMgb25seSwgcmVhbCBmaWx0ZXIgYXBwbGllZCBvbiBBcHBseS9DbGVhci5cbiAgICovXG4gIG9uQ29tcG9zZWRGaWx0ZXJWYWx1ZUNoYW5nZShcbiAgICBjb2w6IFRhYmxlQ29sdW1uLFxuICAgIGNvbXBvc2VkTmFtZTogc3RyaW5nLFxuICAgIHZhbHVlOiBhbnlbXSxcbiAgICBmaWx0ZXJNb2RlbD86IGFueVxuICApOiB2b2lkIHtcbiAgICBjb25zdCBrZXkgPSBgJHtjb2wuY29kZX0uJHtjb21wb3NlZE5hbWV9YDtcblxuICAgIC8vIDEpIHN5bmMgd2l0aCBQcmltZU5HIGZpbHRlciBtb2RlbCBzbyBBcHBseS9DbGVhciB3b3JrIGNvcnJlY3RseVxuICAgIGlmIChmaWx0ZXJNb2RlbCkge1xuICAgICAgZmlsdGVyTW9kZWwudmFsdWUgPSB2YWx1ZTtcbiAgICAgIGlmIChcbiAgICAgICAgQXJyYXkuaXNBcnJheShmaWx0ZXJNb2RlbC5jb25zdHJhaW50cykgJiZcbiAgICAgICAgZmlsdGVyTW9kZWwuY29uc3RyYWludHMubGVuZ3RoID4gMFxuICAgICAgKSB7XG4gICAgICAgIGZpbHRlck1vZGVsLmNvbnN0cmFpbnRzWzBdLnZhbHVlID0gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gMikga2VlcCB5b3VyIGxvY2FsIFVJIG1vZGVsXG4gICAgaWYgKCF0aGlzLmZpbHRlcnNbY29tcG9zZWROYW1lXSkge1xuICAgICAgdGhpcy5maWx0ZXJzW2NvbXBvc2VkTmFtZV0gPSB7XG4gICAgICAgIG9wdGlvbnM6IGNvbC5maWx0ZXJPcHRpb25zLFxuICAgICAgICB2YWx1ZTogW10sXG4gICAgICAgIHBsYWNlaG9sZGVyOiAnU2VsZWN0IG9wdGlvbicsXG4gICAgICB9O1xuICAgIH1cbiAgICB0aGlzLmZpbHRlcnNbY29tcG9zZWROYW1lXS52YWx1ZSA9IHZhbHVlIHx8IFtdO1xuXG4gICAgLy8gMykgY2FjaGUgZm9yIHNlcnZlci1zaWRlIGBmaWx0ZXJDb2x1bW5gXG4gICAgY29uc3QgaXNFbXB0eSA9ICF2YWx1ZSB8fCAoQXJyYXkuaXNBcnJheSh2YWx1ZSkgJiYgdmFsdWUubGVuZ3RoID09PSAwKTtcbiAgICBpZiAoaXNFbXB0eSkge1xuICAgICAgZGVsZXRlIHRoaXMubGF0ZXN0RmlsdGVyVmFsdWVzW2tleV07XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubGF0ZXN0RmlsdGVyVmFsdWVzW2tleV0gPSB2YWx1ZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTlVNQkVSL0RBVEUvTVVMVElTRUxFQ1Q6IGtlZXAgYSBsb2NhbCBjb3B5ICsgdXBkYXRlIGZpbHRlck1vZGVsLnZhbHVlLlxuICAgKi9cbiAgb25GaWx0ZXJWYWx1ZUNoYW5nZShcbiAgICBmaWVsZDogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICAgIGZpbHRlck1vZGVsOiBhbnksXG4gICAgdmFsdWU6IGFueVxuICApOiB2b2lkIHtcbiAgICBpZiAoIWZpZWxkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgaXNFbXB0eSA9XG4gICAgICB2YWx1ZSA9PT0gbnVsbCB8fFxuICAgICAgdmFsdWUgPT09IHVuZGVmaW5lZCB8fFxuICAgICAgKEFycmF5LmlzQXJyYXkodmFsdWUpICYmIHZhbHVlLmxlbmd0aCA9PT0gMCk7XG5cbiAgICBpZiAoaXNFbXB0eSkge1xuICAgICAgZGVsZXRlIHRoaXMubGF0ZXN0RmlsdGVyVmFsdWVzW2ZpZWxkXTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5sYXRlc3RGaWx0ZXJWYWx1ZXNbZmllbGRdID0gdmFsdWU7XG4gICAgfVxuXG4gICAgaWYgKGZpbHRlck1vZGVsKSB7XG4gICAgICBmaWx0ZXJNb2RlbC52YWx1ZSA9IHZhbHVlO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBIZWxwZXI6IGZpbmQgY29sdW1uIGJ5IGZpZWxkLiBTdXBwb3J0cyBjb21wb3NlZCBmaWVsZHMgbGlrZSBcImNvZGUucHJvcFwiLiAqL1xuICBwcml2YXRlIGZpbmRDb2x1bW5CeUZpZWxkKGZpZWxkOiBzdHJpbmcpOiBUYWJsZUNvbHVtbiB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuY29sdW1ucy5maW5kKFxuICAgICAgKGMpID0+IGMuY29kZSA9PT0gZmllbGQgfHwgKGMuY29kZSAmJiBmaWVsZC5zdGFydHNXaXRoKGMuY29kZSArICcuJykpXG4gICAgKTtcbiAgfVxuXG4gIC8vIEZpcmVkIGJ5IFByaW1lTkcgd2hlbiB0aGUgdXNlciBjbGlja3MgQXBwbHkgLyBDbGVhciBpbiBhbnkgZmlsdGVyIG1lbnVcbiAgZmlsdGVyQ29sdW1uKGV2ZW50OiBhbnkpOiB2b2lkIHtcbiAgICBjb25zdCBmaWx0ZXJzID0gZXZlbnQ/LmZpbHRlcnM7XG5cbiAgICBpZiAoIWZpbHRlcnMpIHtcbiAgICAgIHRoaXMub25GaWx0ZXJDb2x1bW4uZW1pdChldmVudCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgT2JqZWN0LmtleXMoZmlsdGVycykuZm9yRWFjaCgoZmllbGQpID0+IHtcbiAgICAgIGNvbnN0IG1ldGEgPSBmaWx0ZXJzW2ZpZWxkXTtcblxuICAgICAgY29uc3Qgbm9ybWFsaXplTWV0YSA9IChtOiBhbnkpID0+XG4gICAgICAgIEFycmF5LmlzQXJyYXkobSkgJiYgbS5sZW5ndGggPiAwID8gbVswXSA6IG07XG5cbiAgICAgIGNvbnN0IG0gPSBub3JtYWxpemVNZXRhKG1ldGEpO1xuICAgICAgY29uc3QgY29sID0gdGhpcy5maW5kQ29sdW1uQnlGaWVsZChmaWVsZCk7XG5cbiAgICAgIC8vIG5vdGhpbmcgdG8gZG9cbiAgICAgIGlmICghbSAmJiAhY29sKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgLy8g8J+UuSBTUEVDSUFMIENBU0U6IENPTVBPU0VEIENPTFVNTlxuICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgaWYgKGNvbCAmJiBjb2wudHlwZSA9PT0gVGFibGVUeXBlRW51bS5DT01QT1NFRCkge1xuICAgICAgICBjb25zdCBjb21wb3NlZFZhbHVlczogYW55ID0ge307XG5cbiAgICAgICAgY29sLmNvbXBvc2VkTmFtZXM/LmZvckVhY2goKG5hbWUpID0+IHtcbiAgICAgICAgICBjb25zdCBrZXkgPSBgJHtjb2wuY29kZX0uJHtuYW1lfWA7XG4gICAgICAgICAgY29uc3QgdmFsID0gdGhpcy5sYXRlc3RGaWx0ZXJWYWx1ZXNba2V5XTtcbiAgICAgICAgICBjb25zdCBlbXB0eSA9XG4gICAgICAgICAgICB2YWwgPT09IG51bGwgfHxcbiAgICAgICAgICAgIHZhbCA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAgICAgICAoQXJyYXkuaXNBcnJheSh2YWwpICYmIHZhbC5sZW5ndGggPT09IDApO1xuXG4gICAgICAgICAgaWYgKCFlbXB0eSkge1xuICAgICAgICAgICAgY29tcG9zZWRWYWx1ZXNbbmFtZV0gPSB2YWw7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBJZiBub3RoaW5nIGluIGNhY2hlLCB0cmVhdCBhcyBcIm5vIGZpbHRlclwiXG4gICAgICAgIGlmIChPYmplY3Qua2V5cyhjb21wb3NlZFZhbHVlcykubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgaWYgKG0pIHtcbiAgICAgICAgICAgIG0udmFsdWUgPSBudWxsO1xuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkobS5jb25zdHJhaW50cykpIHtcbiAgICAgICAgICAgICAgbS5jb25zdHJhaW50cy5mb3JFYWNoKChjOiBhbnkpID0+IChjLnZhbHVlID0gbnVsbCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBzZW5kIG9iamVjdCB7IHN1YjE6IFsuLi5dLCBzdWIyOiBbLi4uXSB9IHRvIHBhcmVudFxuICAgICAgICAgIG0udmFsdWUgPSBjb21wb3NlZFZhbHVlcztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjsgLy8gY29tcG9zZWQgaGFuZGxlZFxuICAgICAgfVxuXG4gICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAvLyDwn5S5IEdFTkVSSUMgQ0FTRTogTk9OLUNPTVBPU0VEIENPTFVNTlNcbiAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgIGlmICghbSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGxldCB2YWx1ZTogYW55ID0gbS52YWx1ZTtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KG0uY29uc3RyYWludHMpICYmIG0uY29uc3RyYWludHMubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCBjVmFsID0gbS5jb25zdHJhaW50c1swXS52YWx1ZTtcbiAgICAgICAgaWYgKGNWYWwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHZhbHVlID0gY1ZhbDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBpc0VtcHR5ID1cbiAgICAgICAgdmFsdWUgPT09IG51bGwgfHxcbiAgICAgICAgdmFsdWUgPT09IHVuZGVmaW5lZCB8fFxuICAgICAgICAoQXJyYXkuaXNBcnJheSh2YWx1ZSkgJiYgdmFsdWUubGVuZ3RoID09PSAwKTtcblxuICAgICAgLy8gQ0xFQVIgPT4gcmVtb3ZlIGZyb20gY2FjaGUsIHJlc2V0IFByaW1lTkcgbWV0YWRhdGFcbiAgICAgIGlmIChpc0VtcHR5KSB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLmxhdGVzdEZpbHRlclZhbHVlc1tmaWVsZF07XG5cbiAgICAgICAgbS52YWx1ZSA9IG51bGw7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KG0uY29uc3RyYWludHMpICYmIG0uY29uc3RyYWludHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIG0uY29uc3RyYWludHNbMF0udmFsdWUgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gTk9OLUVNUFRZID0+IGNhY2hlIGFuZCBub3JtYWxpemVcbiAgICAgIHRoaXMubGF0ZXN0RmlsdGVyVmFsdWVzW2ZpZWxkXSA9IHZhbHVlO1xuXG4gICAgICBsZXQgZW1pdFZhbHVlOiBhbnkgPSB2YWx1ZTtcblxuICAgICAgLy8gT25seSBEQVRFIGNvbHVtbnMgbmVlZCBcImRkL01NL3l5eXlcIiBmb3JtYXRcbiAgICAgIGlmIChjb2wgJiYgY29sLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uREFURSAmJiB2YWx1ZSkge1xuICAgICAgICBlbWl0VmFsdWUgPSB0aGlzLmZvcm1hdERhdGUoXG4gICAgICAgICAgdmFsdWUgaW5zdGFuY2VvZiBEYXRlID8gdmFsdWUgOiBuZXcgRGF0ZSh2YWx1ZSlcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgbS52YWx1ZSA9IGVtaXRWYWx1ZTtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KG0uY29uc3RyYWludHMpICYmIG0uY29uc3RyYWludHMubGVuZ3RoID4gMCkge1xuICAgICAgICBtLmNvbnN0cmFpbnRzWzBdLnZhbHVlID0gZW1pdFZhbHVlO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gc2VuZCBub3JtYWxpemVkIGZpbHRlcnMgdG8gcGFyZW50IChzZXJ2ZXItc2lkZSBwYWdpbmF0aW9uKVxuICAgIHRoaXMub25GaWx0ZXJDb2x1bW4uZW1pdChldmVudCk7XG4gIH1cblxuICBjaGFuZ2VQYWdlKGV2ZW50OiBhbnkpOiB2b2lkIHtcbiAgICBjb25zdCBwYWdlID0gZXZlbnQucGFnZSA/PyBNYXRoLmZsb29yKChldmVudC5maXJzdCB8fCAwKSAvIGV2ZW50LnJvd3MpO1xuICAgIGNvbnN0IHJvd3MgPSBldmVudC5yb3dzO1xuXG4gICAgdGhpcy5yb3dzID0gcm93cztcbiAgICB0aGlzLm9uUGFnZUNoYW5nZS5lbWl0KHsgcGFnZSwgcm93cyB9KTtcbiAgfVxuXG4gIHNvcnRDb2x1bW4oZXZlbnQ6IGFueSk6IHZvaWQge1xuICAgIGlmICghdGhpcy5pc1BhZ2luYXRlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCBmaWVsZCA9IGV2ZW50LmZpZWxkO1xuXG4gICAgY29uc3QgY29sID0gdGhpcy5jb2x1bW5zLmZpbmQoKGMpID0+IGMuY29kZSA9PT0gZmllbGQpO1xuXG4gICAgaWYgKGNvbCAmJiBjb2wudHlwZSA9PT0gVGFibGVUeXBlRW51bS5DT01QT1NFRCkge1xuICAgICAgbGV0IHRleHRQcm9wOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAgIGlmIChjb2wuY29tcG9zZWROYW1lcyAmJiBjb2wuY29tcG9zZWRUeXBlcykge1xuICAgICAgICBjb25zdCBpZHggPSBjb2wuY29tcG9zZWRUeXBlcy5maW5kSW5kZXgoXG4gICAgICAgICAgKHQpID0+IHQgPT09IFRhYmxlVHlwZUVudW0uU1RSSU5HXG4gICAgICAgICk7XG4gICAgICAgIGlmIChpZHggPj0gMCAmJiBpZHggPCBjb2wuY29tcG9zZWROYW1lcy5sZW5ndGgpIHtcbiAgICAgICAgICB0ZXh0UHJvcCA9IGNvbC5jb21wb3NlZE5hbWVzW2lkeF07XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKCF0ZXh0UHJvcCAmJiBjb2wuY29tcG9zZWROYW1lcyAmJiBjb2wuY29tcG9zZWROYW1lcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRleHRQcm9wID0gY29sLmNvbXBvc2VkTmFtZXNbMF07XG4gICAgICB9XG5cbiAgICAgIGlmICh0ZXh0UHJvcCkge1xuICAgICAgICBmaWVsZCA9IGAke2ZpZWxkfS4ke3RleHRQcm9wfWA7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5vblNvcnRDb2x1bW4uZW1pdCh7XG4gICAgICAuLi5ldmVudCxcbiAgICAgIGZpZWxkLFxuICAgIH0pO1xuICB9XG5cbiAgb25DYWxlbmRhckZpbHRlckNoYW5nZShcbiAgICBldmVudDogYW55LFxuICAgIGNvbHVtbkNvZGU6IHN0cmluZyxcbiAgICBmaWx0ZXJDYWxsYmFjazogYW55XG4gICk6IHZvaWQge1xuICAgIGNvbnN0IGZpbHRlclZhbHVlID0gZXZlbnQgPyBuZXcgRGF0ZShldmVudCkgOiBudWxsO1xuICAgIGlmICghZmlsdGVyVmFsdWUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBmaWx0ZXJDYWxsYmFjayhmaWx0ZXJWYWx1ZSk7XG5cbiAgICBpZiAodGhpcy5pc1BhZ2luYXRlZCkge1xuICAgICAgdGhpcy5vbkZpbHRlckNvbHVtbi5lbWl0KHtcbiAgICAgICAgdHlwZTogJ2RhdGUnLFxuICAgICAgICBjb2x1bW5Db2RlLFxuICAgICAgICB2YWx1ZTogZmlsdGVyVmFsdWUsXG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBmaWx0ZXJWYWx1ZVN0cmluZyA9IGV2ZW50ID8gdGhpcy5mb3JtYXREYXRlKGV2ZW50KSA6ICcnO1xuICAgIHRoaXMuZmlsdGVyQ29sdW1uKHtcbiAgICAgIGZpbHRlcmVkVmFsdWU6IHRoaXMuZGF0YS5maWx0ZXIoKGl0ZW0pID0+IHtcbiAgICAgICAgY29uc3QgY29sdW1uVmFsdWUgPSBpdGVtW2NvbHVtbkNvZGVdO1xuICAgICAgICBpZiAoY29sdW1uVmFsdWUpIHtcbiAgICAgICAgICBjb25zdCBpdGVtRGF0ZVN0cmluZyA9IHRoaXMuZm9ybWF0RGF0ZShuZXcgRGF0ZShjb2x1bW5WYWx1ZSkpO1xuICAgICAgICAgIHJldHVybiBpdGVtRGF0ZVN0cmluZyA9PT0gZmlsdGVyVmFsdWVTdHJpbmc7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfSksXG4gICAgfSk7XG4gIH1cblxuICAvLyAtLS0tLS0tLS0tIE9USEVSIEhFTFBFUlMgLS0tLS0tLS0tLVxuXG4gIGZpbHRlckNvbXBvc2VkRGF0YShpdGVtOiBhbnksIGNvbXBvc2VkTmFtZTogc3RyaW5nLCB2YWx1ZTogYW55KTogYm9vbGVhbiB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpICYmIHZhbHVlLmxlbmd0aCA+IDApIHtcbiAgICAgIHJldHVybiB2YWx1ZS5zb21lKChmaWx0ZXJWYWx1ZTogc3RyaW5nKSA9PlxuICAgICAgICBpdGVtW2NvbXBvc2VkTmFtZV0/LnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoZmlsdGVyVmFsdWUudG9Mb3dlckNhc2UoKSlcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBjYWxjdWxhdGVDb2x1bW5XaWR0aChjb2w6IFRhYmxlQ29sdW1uKTogc3RyaW5nIHtcbiAgICBjb25zdCBjYWxjdWxhdGVkV2lkdGggPSBjYWxjdWxhdGVUZXh0V2lkdGgoY29sLCBjb2wudGl0bGUpO1xuICAgIGNvbnN0IHRvdGFsV2lkdGggPSBjYWxjdWxhdGVkV2lkdGggKyB0aGlzLmljb25XaWR0aCArIDIwO1xuICAgIHJldHVybiBgJHt0b3RhbFdpZHRofXB4YDtcbiAgfVxuXG4gIGdldEhlYWRlcldpZHRoKGNvbDogVGFibGVDb2x1bW4pOiBzdHJpbmcge1xuICAgIGlmIChjb2wud2lkdGgpIHtcbiAgICAgIHJldHVybiBjb2wud2lkdGg7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNhbGN1bGF0ZUNvbHVtbldpZHRoKGNvbCk7XG4gIH1cblxuICBjbGVhcih0YWJsZTogVGFibGUpIHtcbiAgICAvLyBDbGVhciBQcmltZU5HIGludGVybmFsIGZpbHRlcnMgKyBVSVxuICAgIHRhYmxlLmNsZWFyKCk7XG5cbiAgICAvLyBDbGVhciBnbG9iYWwgc2VhcmNoXG4gICAgdGhpcy5zZWFyY2hWYWx1ZSA9ICcnO1xuXG4gICAgLy8gQ2xlYXIgY2FjaGVkIHZhbHVlcyBmb3Igbm9ybWFsICYgY29tcG9zZWQgZmllbGRzXG4gICAgdGhpcy5sYXRlc3RGaWx0ZXJWYWx1ZXMgPSB7fTtcblxuICAgIC8vIENsZWFyIGxvY2FsIG1vZGVscyBmb3IgY29tcG9zZWQgZmlsdGVyc1xuICAgIE9iamVjdC5rZXlzKHRoaXMuZmlsdGVycykuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICBpZiAodGhpcy5maWx0ZXJzW2tleV0pIHtcbiAgICAgICAgdGhpcy5maWx0ZXJzW2tleV0udmFsdWUgPSBbXTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmICh0aGlzLmlzUGFnaW5hdGVkKSB7XG4gICAgICB0aGlzLm9uRmlsdGVyQ29sdW1uLmVtaXQoeyBjbGVhcmVkOiB0cnVlIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VEYXRlKGRhdGVTdHJpbmc6IHN0cmluZyk6IERhdGUgfCBudWxsIHtcbiAgICBjb25zdCBwYXJ0cyA9IGRhdGVTdHJpbmcuc3BsaXQoJy8nKTtcbiAgICBpZiAocGFydHMubGVuZ3RoID09PSAzKSB7XG4gICAgICBjb25zdCBkYXkgPSBwYXJzZUludChwYXJ0c1swXSwgMTApO1xuICAgICAgY29uc3QgbW9udGggPSBwYXJzZUludChwYXJ0c1sxXSwgMTApIC0gMTtcbiAgICAgIGNvbnN0IHllYXIgPSBwYXJzZUludChwYXJ0c1syXSwgMTApO1xuICAgICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKHllYXIsIG1vbnRoLCBkYXkpO1xuICAgICAgcmV0dXJuIGlzTmFOKGRhdGUuZ2V0VGltZSgpKSA/IG51bGwgOiBkYXRlO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgaW5pdGlhbGl6ZVBhZ2luYXRpb24oKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNQYWdpbmF0ZWQpIHtcbiAgICAgIGlmICghdGhpcy5yb3dzUGVyUGFnZSB8fCB0aGlzLnJvd3NQZXJQYWdlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aGlzLnJvd3NQZXJQYWdlID0gWzIwLCAzMCwgNDBdO1xuICAgICAgfVxuICAgICAgdGhpcy5yb3dzID0gdGhpcy5yb3dzUGVyUGFnZVswXTtcbiAgICB9XG4gIH1cblxuICBvbkNoYW5nZShldmVudDogRXZlbnQsIGlkOiBudW1iZXIsIGtleTogYW55KSB7XG4gICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQ7XG4gICAgdGhpcy5jaGFuZ2VIYW5kbGVyKGlkLCBrZXksIHRhcmdldC52YWx1ZSk7XG4gIH1cblxuICBjaGFuZ2VIYW5kbGVyKGlkOiBudW1iZXIsIGtleTogYW55LCB2YWx1ZTogYW55KSB7XG4gICAgY29uc3QgY29sdW1uID0gdGhpcy5jb2x1bW5zLmZpbmQoKGl0ZW0pID0+IGl0ZW0uY29kZSA9PT0ga2V5KTtcbiAgICBpZiAoIXRoaXMubWFwLmdldChpZCkpIHtcbiAgICAgIGlmIChjb2x1bW4/LnR5cGUgPT09IFRhYmxlVHlwZUVudW0uREFURSkge1xuICAgICAgICBjb25zdCBkYXRlID0gdGhpcy5wYXJzZURhdGUodmFsdWUpO1xuICAgICAgICB0aGlzLmRhdGFNYXAuc2V0KGtleSwgZGF0ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmRhdGFNYXAuc2V0KGtleSwgdmFsdWUpO1xuICAgICAgfVxuICAgICAgdGhpcy5tYXAuc2V0KGlkLCBuZXcgTWFwKHRoaXMuZGF0YU1hcCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBtYXBJdGVtID0gdGhpcy5tYXAuZ2V0KGlkKSBhcyBNYXA8YW55LCBhbnk+O1xuICAgICAgaWYgKGNvbHVtbj8udHlwZSA9PT0gVGFibGVUeXBlRW51bS5EQVRFKSB7XG4gICAgICAgIGNvbnN0IGRhdGUgPSB0aGlzLnBhcnNlRGF0ZSh2YWx1ZSk7XG4gICAgICAgIG1hcEl0ZW0uc2V0KGtleSwgZGF0ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtYXBJdGVtLnNldChrZXksIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBnZXRDb2x1bW5GaWx0ZXJUeXBlKGNvbHVtbjogVGFibGVDb2x1bW4pOiBzdHJpbmcge1xuICAgIHN3aXRjaCAoY29sdW1uLnR5cGUpIHtcbiAgICAgIGNhc2UgVGFibGVUeXBlRW51bS5TVFJJTkc6XG4gICAgICAgIHJldHVybiAndGV4dCc7XG4gICAgICBjYXNlIFRhYmxlVHlwZUVudW0uQU1PVU5UOlxuICAgICAgY2FzZSBUYWJsZVR5cGVFbnVtLk5VTUJFUjpcbiAgICAgICAgcmV0dXJuICdudW1lcmljJztcbiAgICAgIGNhc2UgVGFibGVUeXBlRW51bS5EQVRFOlxuICAgICAgICByZXR1cm4gJ2RhdGUnO1xuICAgICAgY2FzZSBUYWJsZVR5cGVFbnVtLk1VTFRJU0VMRUNUOlxuICAgICAgICByZXR1cm4gJ211bHRpU2VsZWN0JztcbiAgICAgIGNhc2UgVGFibGVUeXBlRW51bS5CT09MRUFOOlxuICAgICAgICByZXR1cm4gJ2Jvb2xlYW4nO1xuICAgICAgY2FzZSBUYWJsZVR5cGVFbnVtLkNPTVBPU0VEOlxuICAgICAgICByZXR1cm4gJ2NvbXBvc2VkJztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiAndGV4dCc7XG4gICAgfVxuICB9XG5cbiAgaXNFZGl0YWJsZShrZXk6IHN0cmluZyB8IHVuZGVmaW5lZCk6IGJvb2xlYW4ge1xuICAgIGlmICgha2V5KSByZXR1cm4gZmFsc2U7XG4gICAgY29uc3QgY29sdW1uID0gdGhpcy5jb2x1bW5zLmZpbmQoKGl0ZW0pID0+IGl0ZW0uY29kZSA9PT0ga2V5KTtcbiAgICByZXR1cm4gY29sdW1uPy5pc0VkaXRhYmxlICE9PSBmYWxzZTtcbiAgfVxuXG4gIGlzTXVsdGlTZWxlY3Qoa2V5OiBhbnkpOiBib29sZWFuIHtcbiAgICBjb25zdCBjb2x1bW4gPSB0aGlzLmNvbHVtbnMuZmluZCgoaXRlbSkgPT4gaXRlbS5jb2RlID09PSBrZXkpO1xuICAgIGlmIChcbiAgICAgIGNvbHVtbj8udHlwZSA9PT0gVGFibGVUeXBlRW51bS5NVUxUSVNFTEVDVCAmJlxuICAgICAgY29sdW1uLm9wdGlvbnMgJiZcbiAgICAgIGNvbHVtbi5jb2RlICE9PSB1bmRlZmluZWRcbiAgICApIHtcbiAgICAgIHRoaXMub3B0aW9uRW50cmllcyA9IG5ldyBNYXAoW1xuICAgICAgICBbY29sdW1uLmNvZGUgYXMgc3RyaW5nLCBPYmplY3QudmFsdWVzKGNvbHVtbi5vcHRpb25zKV0sXG4gICAgICBdKTtcbiAgICAgIHRoaXMub3B0aW9uVmFsdWVzID0gdGhpcy5vcHRpb25FbnRyaWVzLmdldChrZXkpIHx8IFtdO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlzRGF0ZVBpY2tlcihrZXk6IGFueSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLmNvbHVtbnMuZmluZCgoaXRlbSkgPT4gaXRlbS5jb2RlID09PSBrZXkpPy50eXBlID09PVxuICAgICAgVGFibGVUeXBlRW51bS5EQVRFXG4gICAgKTtcbiAgfVxuXG4gIGRhdGVDb252ZXJ0ZXIodmFsdWU6IGFueSk6IHN0cmluZyB7XG4gICAgcmV0dXJuIG5ldyBEYXRlKHZhbHVlKS50b0xvY2FsZURhdGVTdHJpbmcoJ2VuLVVTJyk7XG4gIH1cblxuICBnZXRDdXJyZW5jeVN5bWJvbChjb2x1bW46IFRhYmxlQ29sdW1uKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gY29sdW1uLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uQU1PVU5UICYmXG4gICAgICBjb2x1bW4uY3VycmVuY3kgJiZcbiAgICAgIHRoaXMuaXNWYWxpZEN1cnJlbmN5Q29kZShjb2x1bW4uY3VycmVuY3kpXG4gICAgICA/IGNvbHVtbi5jdXJyZW5jeVxuICAgICAgOiB1bmRlZmluZWQ7XG4gIH1cblxuICBwcml2YXRlIGlzVmFsaWRDdXJyZW5jeUNvZGUoY3VycmVuY3lDb2RlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy52YWxpZEN1cnJlbmN5Q29kZXMuaW5jbHVkZXMoY3VycmVuY3lDb2RlKTtcbiAgfVxuXG4gIGZpbHRlckdsb2JhbChldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudDtcbiAgICBjb25zdCB2YWx1ZSA9IHRhcmdldC52YWx1ZS50b0xvd2VyQ2FzZSgpO1xuXG4gICAgaWYgKHRoaXMuaXNQYWdpbmF0ZWQpIHtcbiAgICAgIHRoaXMuc2VhcmNoLmVtaXQodmFsdWUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGZpbHRlcmVkRGF0YSA9IHRoaXMuZGF0YS5maWx0ZXIoKGl0ZW0pID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmdsb2JhbEZpbHRlckZpZWxkcy5zb21lKChmaWVsZCkgPT4ge1xuICAgICAgICBjb25zdCBjb2x1bW4gPSB0aGlzLmNvbHVtbnMuZmluZCgoY29sKSA9PiBjb2wuY29kZSA9PT0gZmllbGQpO1xuICAgICAgICBpZiAoIWNvbHVtbikge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb2x1bW4udHlwZSA9PT0gVGFibGVUeXBlRW51bS5EQVRFKSB7XG4gICAgICAgICAgY29uc3QgaXRlbURhdGUgPSB0aGlzLmZvcm1hdERhdGUoaXRlbVtmaWVsZF0pO1xuICAgICAgICAgIHJldHVybiBpdGVtRGF0ZSAmJiBpdGVtRGF0ZS5pbmNsdWRlcyh2YWx1ZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgY29sdW1uLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uQU1PVU5UIHx8XG4gICAgICAgICAgY29sdW1uLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uTlVNQkVSXG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBpdGVtW2ZpZWxkXSAmJiBpdGVtW2ZpZWxkXS50b1N0cmluZygpLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXModmFsdWUpXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIGlmIChjb2x1bW4udHlwZSA9PT0gVGFibGVUeXBlRW51bS5DT01QT1NFRCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLmZpbHRlckNvbXBvc2VkQ29sdW1uKGl0ZW1bZmllbGRdLCB2YWx1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIGl0ZW1bZmllbGRdICYmIGl0ZW1bZmllbGRdLnRvU3RyaW5nKCkudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyh2YWx1ZSlcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRoaXMuZHQudmFsdWUgPSBmaWx0ZXJlZERhdGE7XG4gIH1cblxuICBwcml2YXRlIGZpbHRlckNvbXBvc2VkQ29sdW1uKGNvbXBvc2VkRGF0YTogYW55LCB2YWx1ZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgaWYgKGNvbXBvc2VkRGF0YSkge1xuICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKGNvbXBvc2VkRGF0YSkuc29tZSgoa2V5KSA9PiB7XG4gICAgICAgIGNvbnN0IGNlbGxWYWx1ZSA9IGNvbXBvc2VkRGF0YVtrZXldO1xuICAgICAgICBpZiAodHlwZW9mIGNlbGxWYWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICByZXR1cm4gY2VsbFZhbHVlLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXModmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBmb3JtYXREYXRlKGRhdGU6IGFueSk6IHN0cmluZyB7XG4gICAgaWYgKCFkYXRlKSByZXR1cm4gJyc7XG4gICAgaWYgKGRhdGUgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICBjb25zdCBkYXkgPSBkYXRlLmdldERhdGUoKS50b1N0cmluZygpLnBhZFN0YXJ0KDIsICcwJyk7XG4gICAgICBjb25zdCBtb250aCA9IChkYXRlLmdldE1vbnRoKCkgKyAxKS50b1N0cmluZygpLnBhZFN0YXJ0KDIsICcwJyk7XG4gICAgICBjb25zdCB5ZWFyID0gZGF0ZS5nZXRGdWxsWWVhcigpLnRvU3RyaW5nKCk7XG4gICAgICByZXR1cm4gYCR7ZGF5fS8ke21vbnRofS8ke3llYXJ9YDtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBkYXRlID09PSAnc3RyaW5nJykge1xuICAgICAgY29uc3QgcGFydHMgPSBkYXRlLnNwbGl0KCcvJyk7XG4gICAgICBpZiAocGFydHMubGVuZ3RoID09PSAzKSB7XG4gICAgICAgIHJldHVybiBgJHtwYXJ0c1swXX0vJHtwYXJ0c1sxXX0vJHtwYXJ0c1syXX1gO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGRhdGU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIGV4cG9ydEV4Y2VsKCkge1xuICAgIHRoaXMuZXhwb3J0RXhjZWxFdmVudC5lbWl0KCk7XG4gIH1cblxuICBleHBvcnRQZGYoKSB7XG4gICAgdGhpcy5leHBvcnRQZGZFdmVudC5lbWl0KCk7XG4gIH1cblxuICBnZXRJbWFnZVN0eWxlKHN0eWxlOiBUaXRsZVN0eWxlIHwgSW1hZ2VTdHlsZSB8IHVuZGVmaW5lZCk6IHtcbiAgICBba2V5OiBzdHJpbmddOiBzdHJpbmc7XG4gIH0ge1xuICAgIGlmIChzdHlsZSkge1xuICAgICAgY29uc3QgaW1hZ2VTdHlsZTogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSA9IHtcbiAgICAgICAgd2lkdGg6IChzdHlsZSBhcyBJbWFnZVN0eWxlKS53aWR0aCB8fCAnYXV0bycsXG4gICAgICAgIGhlaWdodDogKHN0eWxlIGFzIEltYWdlU3R5bGUpLmhlaWdodCB8fCAnYXV0bycsXG4gICAgICB9O1xuXG4gICAgICBpZiAoKHN0eWxlIGFzIEltYWdlU3R5bGUpLm1hcmdpbikge1xuICAgICAgICBpbWFnZVN0eWxlLm1hcmdpbiA9IChzdHlsZSBhcyBJbWFnZVN0eWxlKS5tYXJnaW4hO1xuICAgICAgfVxuICAgICAgaWYgKChzdHlsZSBhcyBJbWFnZVN0eWxlKS5tYXJnaW5MZWZ0KSB7XG4gICAgICAgIGltYWdlU3R5bGUubWFyZ2luTGVmdCA9IChzdHlsZSBhcyBJbWFnZVN0eWxlKS5tYXJnaW5MZWZ0ITtcbiAgICAgIH1cbiAgICAgIGlmICgoc3R5bGUgYXMgSW1hZ2VTdHlsZSkubWFyZ2luUmlnaHQpIHtcbiAgICAgICAgaW1hZ2VTdHlsZS5tYXJnaW5SaWdodCA9IChzdHlsZSBhcyBJbWFnZVN0eWxlKS5tYXJnaW5SaWdodCE7XG4gICAgICB9XG4gICAgICBpZiAoKHN0eWxlIGFzIEltYWdlU3R5bGUpLm1hcmdpblRvcCkge1xuICAgICAgICBpbWFnZVN0eWxlLm1hcmdpblRvcCA9IChzdHlsZSBhcyBJbWFnZVN0eWxlKS5tYXJnaW5Ub3AhO1xuICAgICAgfVxuICAgICAgaWYgKChzdHlsZSBhcyBJbWFnZVN0eWxlKS5tYXJnaW5Cb3R0b20pIHtcbiAgICAgICAgaW1hZ2VTdHlsZS5tYXJnaW5Cb3R0b20gPSAoc3R5bGUgYXMgSW1hZ2VTdHlsZSkubWFyZ2luQm90dG9tITtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGltYWdlU3R5bGU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHt9O1xuICB9XG5cbiAgZ2V0VGl0bGVTdHlsZShzdHlsZTogVGl0bGVTdHlsZSB8IEltYWdlU3R5bGUgfCB1bmRlZmluZWQpOiB7XG4gICAgW2tleTogc3RyaW5nXTogc3RyaW5nO1xuICB9IHtcbiAgICBpZiAoc3R5bGUpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbG9yOiBzdHlsZS5jb2xvciB8fCAnaW5oZXJpdCcsXG4gICAgICAgIGZvbnRTaXplOiAoc3R5bGUgYXMgVGl0bGVTdHlsZSkuZm9udFNpemUgfHwgJ2luaGVyaXQnLFxuICAgICAgICB0ZXh0QWxpZ246IChzdHlsZSBhcyBUaXRsZVN0eWxlKS5wb3NpdGlvbiB8fCAnbGVmdCcsXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4ge307XG4gIH1cblxuICBmb3JtYXROdW1iZXIoXG4gICAgdmFsdWU6IG51bWJlcixcbiAgICBkZWNpbWFsUGxhY2VzPzogbnVtYmVyLFxuICAgIHRob3VzYW5kU2VwYXJhdG9yOiAnY29tbWEnIHwgJ3NwYWNlJyA9ICdjb21tYScsXG4gICAgZGVjaW1hbFNlcGFyYXRvcjogJ2NvbW1hJyB8ICdkb3QnID0gJ2RvdCdcbiAgKTogc3RyaW5nIHtcbiAgICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCB8fCBpc05hTih2YWx1ZSkpIHJldHVybiAnJztcblxuICAgIGxldCBmb3JtYXR0ZWROdW1iZXIgPVxuICAgICAgZGVjaW1hbFBsYWNlcyAhPT0gdW5kZWZpbmVkXG4gICAgICAgID8gdmFsdWUudG9GaXhlZChkZWNpbWFsUGxhY2VzKVxuICAgICAgICA6IHZhbHVlLnRvU3RyaW5nKCk7XG5cbiAgICBpZiAoZGVjaW1hbFNlcGFyYXRvciA9PT0gJ2NvbW1hJykge1xuICAgICAgZm9ybWF0dGVkTnVtYmVyID0gZm9ybWF0dGVkTnVtYmVyLnJlcGxhY2UoJy4nLCAnLCcpO1xuICAgIH1cblxuICAgIGlmICh0aG91c2FuZFNlcGFyYXRvciAmJiBNYXRoLmFicyh2YWx1ZSkgPj0gMTAwMCkge1xuICAgICAgY29uc3QgcGFydHMgPSBmb3JtYXR0ZWROdW1iZXIuc3BsaXQoXG4gICAgICAgIGRlY2ltYWxTZXBhcmF0b3IgPT09ICdjb21tYScgPyAnLCcgOiAnLidcbiAgICAgICk7XG4gICAgICBwYXJ0c1swXSA9IHBhcnRzWzBdLnJlcGxhY2UoXG4gICAgICAgIC9cXEIoPz0oXFxkezN9KSsoPyFcXGQpKS9nLFxuICAgICAgICB0aG91c2FuZFNlcGFyYXRvciA9PT0gJ2NvbW1hJyA/ICcsJyA6ICcgJ1xuICAgICAgKTtcbiAgICAgIGZvcm1hdHRlZE51bWJlciA9IHBhcnRzLmpvaW4oZGVjaW1hbFNlcGFyYXRvciA9PT0gJ2NvbW1hJyA/ICcsJyA6ICcuJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZvcm1hdHRlZE51bWJlcjtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cInB0LWFkdmFuY2VkLXByaW1lLXRhYmxlIHRhYmxlLWNvbnRhaW5lclwiPlxuICA8cC10YWJsZVxuICAgICNkdFxuICAgIFt2YWx1ZV09XCJkYXRhXCJcbiAgICBbbG9hZGluZ109XCJsb2FkaW5nXCJcbiAgICBbcm93c109XCJyb3dzXCJcbiAgICBbcGFnaW5hdG9yXT1cImlzUGFnaW5hdGVkXCJcbiAgICBbZ2xvYmFsRmlsdGVyRmllbGRzXT1cImdsb2JhbEZpbHRlckZpZWxkc1wiXG4gICAgW3Jvd3NQZXJQYWdlT3B0aW9uc109XCJyb3dzUGVyUGFnZVwiXG4gICAgW3RvdGFsUmVjb3Jkc109XCJ0b3RhbFJlY29yZHNcIlxuICAgIFtsYXp5XT1cImlzUGFnaW5hdGVkXCJcbiAgICBkYXRhS2V5PVwiaWRcIlxuICAgIHN0eWxlQ2xhc3M9XCJwLWRhdGF0YWJsZS1ncmlkbGluZXMgcC1kYXRhdGFibGUtc3RyaXBlZFwiXG4gICAgW3Njcm9sbGFibGVdPVwidHJ1ZVwiXG4gICAgW3Njcm9sbEhlaWdodF09XCJtYXhIZWlnaHQgIT09IG51bGwgPyBtYXhIZWlnaHQgOiB1bmRlZmluZWRcIlxuICAgIChvbkZpbHRlcik9XCJmaWx0ZXJDb2x1bW4oJGV2ZW50KVwiXG4gICAgKG9uUGFnZSk9XCJjaGFuZ2VQYWdlKCRldmVudClcIlxuICAgIChvblNvcnQpPVwic29ydENvbHVtbigkZXZlbnQpXCJcbiAgPlxuICAgIDwhLS0gQ09MR1JPVVA6IHN5bmMgaGVhZGVyL2JvZHkgd2lkdGhzIC0tPlxuICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJjb2xncm91cFwiIGxldC1jb2x1bW5zPlxuICAgICAgPGNvbGdyb3VwPlxuICAgICAgICA8Y29sXG4gICAgICAgICAgKm5nRm9yPVwibGV0IGNvbCBvZiBjb2x1bW5zXCJcbiAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiY29sLndpZHRoIHx8IGdldEhlYWRlcldpZHRoKGNvbClcIlxuICAgICAgICAvPlxuICAgICAgPC9jb2xncm91cD5cbiAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgPCEtLSBDQVBUSU9OIC0tPlxuICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJjYXB0aW9uXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiZmxleFwiPlxuICAgICAgICA8ZGl2PlxuICAgICAgICAgIDxoMz5Ub3RhbDoge3sgdG90YWxSZWNvcmRzIH19PC9oMz5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPGRpdj5cbiAgICAgICAgICA8IS0tIENsZWFyIGZpbHRlcnMgLS0+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgKm5nSWY9XCJoYXNTZWFyY2hGaWx0ZXJcIlxuICAgICAgICAgICAgcEJ1dHRvblxuICAgICAgICAgICAgaWNvbj1cInBpIHBpLWZpbHRlci1zbGFzaFwiXG4gICAgICAgICAgICBjbGFzcz1cInAtYnV0dG9uLXJvdW5kZWQgcC1idXR0b24tdGV4dFwiXG4gICAgICAgICAgICAoY2xpY2spPVwiY2xlYXIoZHQpXCJcbiAgICAgICAgICAgIHRpdGxlPVwiQ2xlYXIgZmlsdGVyc1wiXG4gICAgICAgICAgPjwvYnV0dG9uPlxuXG4gICAgICAgICAgPCEtLSBFeHBvcnQgdG8gRXhjZWwgQnV0dG9uIC0tPlxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICpuZ0lmPVwiaGFzRXhwb3J0RXhjZWxcIlxuICAgICAgICAgICAgcEJ1dHRvblxuICAgICAgICAgICAgaWNvbj1cInBpIHBpLWZpbGUtZXhjZWxcIlxuICAgICAgICAgICAgY2xhc3M9XCJwLWJ1dHRvbi1yb3VuZGVkIHAtYnV0dG9uLXRleHRcIlxuICAgICAgICAgICAgKGNsaWNrKT1cImV4cG9ydEV4Y2VsKClcIlxuICAgICAgICAgICAgdGl0bGU9XCJFeHBvcnQgdG8gRXhjZWxcIlxuICAgICAgICAgID48L2J1dHRvbj5cblxuICAgICAgICAgIDwhLS0gRXhwb3J0IHRvIFBERiBCdXR0b24gLS0+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgKm5nSWY9XCJoYXNFeHBvcnRQREZcIlxuICAgICAgICAgICAgcEJ1dHRvblxuICAgICAgICAgICAgaWNvbj1cInBpIHBpLWZpbGUtcGRmXCJcbiAgICAgICAgICAgIGNsYXNzPVwicC1idXR0b24tcm91bmRlZCBwLWJ1dHRvbi10ZXh0XCJcbiAgICAgICAgICAgIChjbGljayk9XCJleHBvcnRQZGYoKVwiXG4gICAgICAgICAgICB0aXRsZT1cIkV4cG9ydCB0byBQREZcIlxuICAgICAgICAgID48L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm1sLWF1dG9cIiAqbmdJZj1cImhhc1NlYXJjaEZpbHRlclwiPlxuICAgICAgICAgIDxwLWljb25GaWVsZCBpY29uUG9zaXRpb249XCJsZWZ0XCIgY2xhc3M9XCJtbC1hdXRvXCI+XG4gICAgICAgICAgICA8cC1pbnB1dEljb24+XG4gICAgICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktc2VhcmNoXCI+PC9pPlxuICAgICAgICAgICAgPC9wLWlucHV0SWNvbj5cbiAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICBwSW5wdXRUZXh0XG4gICAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJzZWFyY2hWYWx1ZVwiXG4gICAgICAgICAgICAgIChpbnB1dCk9XCJmaWx0ZXJHbG9iYWwoJGV2ZW50KVwiXG4gICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiU2VhcmNoIGtleXdvcmRcIlxuICAgICAgICAgICAgLz5cbiAgICAgICAgICA8L3AtaWNvbkZpZWxkPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICA8IS0tIEhFQURFUiAtLT5cbiAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiaGVhZGVyXCI+XG4gICAgICA8dHIgY2xhc3M9XCJzdGlja3ktaGVhZGVyXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGNvbCBvZiBjb2x1bW5zXCI+XG4gICAgICAgICAgPHRoXG4gICAgICAgICAgICAqbmdJZj1cIiFjb2wuY2hpbGRyZW47IGVsc2UgZ3JvdXBIZWFkZXJcIlxuICAgICAgICAgICAgcFNvcnRhYmxlQ29sdW1uPVwie3sgY29sLmNvZGUgfX1cIlxuICAgICAgICAgICAgW3N0eWxlLndpZHRoXT1cImNvbC53aWR0aCB8fCBnZXRIZWFkZXJXaWR0aChjb2wpXCJcbiAgICAgICAgICAgIFtzdHlsZS5wYWRkaW5nXT1cIicwcHgnXCJcbiAgICAgICAgICAgIFtuZ0NsYXNzXT1cIltcbiAgICAgICAgICAgICAgZ2V0SGVhZGVyQWxpZ25DbGFzcyhjb2wpLFxuICAgICAgICAgICAgICBjb2wudHlwZSA9PT0gVGFibGVUeXBlRW51bS5BQ1RJT04gPyAnYWN0aW9uLWNvbHVtbicgOiAnJ1xuICAgICAgICAgICAgXVwiXG4gICAgICAgICAgICBjb2xzcGFuPVwiMVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPCEtLSBTT1JUQUJMRSBIRUFERVIgLS0+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICpuZ0lmPVwiaXNTb3J0YWJsZSAmJiBjb2wuaXNTb3J0YWJsZSAhPT0gZmFsc2U7IGVsc2Ugbm9Tb3J0SGVhZGVyXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgIGNsYXNzPVwiaGVhZGVyLWNvbnRhaW5lciBkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGp1c3RpZnktY29udGVudC1iZXR3ZWVuXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiY29sLndpZHRoIHx8IGdldEhlYWRlcldpZHRoKGNvbClcIlxuICAgICAgICAgICAgICAgIFtzdHlsZS5wYWRkaW5nXT1cIicwcHgnXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUubWFyZ2luXT1cIicxMHB4J1wiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8c3BhbiBbbmdDbGFzc109XCJnZXRIZWFkZXJUaXRsZUNsYXNzKGNvbClcIj5cbiAgICAgICAgICAgICAgICAgIHt7IGNvbC50aXRsZSB9fVxuICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICBjbGFzcz1cImljb25zIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXJcIlxuICAgICAgICAgICAgICAgICAgW3N0eWxlLndpZHRoXT1cIic3N3B4J1wiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgPHAtc29ydEljb24gZmllbGQ9XCJ7eyBjb2wuY29kZSB9fVwiIC8+XG5cbiAgICAgICAgICAgICAgICAgIDwhLS0gQ09MVU1OIEZJTFRFUlMgLS0+XG4gICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiaGFzQ29sdW1uRmlsdGVyICYmIGNvbC5pc0ZpbHRlciAhPT0gZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8IS0tIENPTVBPU0VEIEZJTFRFUiAodXNlcyBidWlsdC1pbiBBcHBseS9DbGVhcikgLS0+XG4gICAgICAgICAgICAgICAgICAgIDxwLWNvbHVtbkZpbHRlclxuICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29sLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uQ09NUE9TRURcIlxuICAgICAgICAgICAgICAgICAgICAgIGRpc3BsYXk9XCJtZW51XCJcbiAgICAgICAgICAgICAgICAgICAgICBbZmllbGRdPVwiY29sLmNvZGVcIlxuICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICAgICAgICAgICAgICBbc2hvd0FwcGx5QnV0dG9uXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgIFtzaG93Q2xlYXJCdXR0b25dPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgKG9uQ2xlYXIpPVwib25Db21wb3NlZENvbHVtbkNsZWFyKGNvbClcIlxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICBwVGVtcGxhdGU9XCJmaWx0ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0LWZpbHRlcj1cImZpbHRlckNhbGxiYWNrXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldC1maWx0ZXJNb2RlbD1cImZpbHRlck1vZGVsXCJcbiAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBjb21wb3NlZE5hbWUgb2YgY29sLmNvbXBvc2VkTmFtZXNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRDb21wb3NlZEZpZWxkVHlwZShjb2wsIGNvbXBvc2VkTmFtZSkgPT09XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUYWJsZVR5cGVFbnVtLlNUUklOR1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cC1tdWx0aVNlbGVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvbnNdPVwiZmlsdGVyc1tjb21wb3NlZE5hbWVdPy5vcHRpb25zXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cImZpbHRlcnNbY29tcG9zZWROYW1lXT8udmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uQ29tcG9zZWRGaWx0ZXJWYWx1ZUNoYW5nZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9zZWROYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRldmVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXJNb2RlbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cImZpbHRlcnNbY29tcG9zZWROYW1lXT8ucGxhY2Vob2xkZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGxheT1cImNoaXBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBsZXQtaXRlbSBwVGVtcGxhdGU9XCJpdGVtXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjdXN0b20tbXVsdGlzZWxlY3QtaXRlbVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiaXRlbS5pbWFnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3JjXT1cIml0ZW0uaW1hZ2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWx0PVwiaWNvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZpbHRlci1pbWFnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj57eyBpdGVtLmxhYmVsIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9wLW11bHRpU2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgIDwvcC1jb2x1bW5GaWx0ZXI+XG5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBPVEhFUiBUWVBFUyAtLT5cbiAgICAgICAgICAgICAgICAgICAgPHAtY29sdW1uRmlsdGVyXG4gICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb2wudHlwZSAhPT0gVGFibGVUeXBlRW51bS5DT01QT1NFRFwiXG4gICAgICAgICAgICAgICAgICAgICAgZGlzcGxheT1cIm1lbnVcIlxuICAgICAgICAgICAgICAgICAgICAgIFtmaWVsZF09XCJjb2wuY29kZVwiXG4gICAgICAgICAgICAgICAgICAgICAgW3R5cGVdPVwiZ2V0Q29sdW1uRmlsdGVyVHlwZShjb2wpXCJcbiAgICAgICAgICAgICAgICAgICAgICBbc2hvd0FwcGx5QnV0dG9uXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgIFtzaG93Q2xlYXJCdXR0b25dPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICA8IS0tIE5VTUJFUiAtLT5cbiAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgIHBUZW1wbGF0ZT1cImZpbHRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbC50eXBlID09PSBUYWJsZVR5cGVFbnVtLk5VTUJFUlwiXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQtZmlsdGVyTW9kZWw9XCJmaWx0ZXJNb2RlbFwiXG4gICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHBJbnB1dFRleHRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cIm51bWJlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtzdGVwXT1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5kZWNpbWFsUGxhY2VzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/ICcwLicgKyAnMScucGFkRW5kKGNvbC5kZWNpbWFsUGxhY2VzLCAnMCcpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICdhbnknXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhdGVzdEZpbHRlclZhbHVlc1tjb2wuY29kZSFdID8/IGZpbHRlck1vZGVsPy52YWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkZpbHRlclZhbHVlQ2hhbmdlKGNvbC5jb2RlISwgZmlsdGVyTW9kZWwsICRldmVudClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJFbnRlciBhIG51bWJlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgICAgICAgICAgICAgICA8IS0tIERBVEUgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICBwVGVtcGxhdGU9XCJmaWx0ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb2wudHlwZSA9PT0gVGFibGVUeXBlRW51bS5EQVRFXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldC1maWx0ZXJNb2RlbD1cImZpbHRlck1vZGVsXCJcbiAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8cC1jYWxlbmRhclxuICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXRlc3RGaWx0ZXJWYWx1ZXNbY29sLmNvZGUhXSA/PyBmaWx0ZXJNb2RlbD8udmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25GaWx0ZXJWYWx1ZUNoYW5nZShjb2wuY29kZSEsIGZpbHRlck1vZGVsLCAkZXZlbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGVGb3JtYXQ9XCJkZC9tbS95eVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiQ2hvb3NlIGEgZGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICA+PC9wLWNhbGVuZGFyPlxuICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgICAgICAgICAgICAgICA8IS0tIE1VTFRJU0VMRUNUIC0tPlxuICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgcFRlbXBsYXRlPVwiZmlsdGVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC50eXBlID09PSBUYWJsZVR5cGVFbnVtLk1VTFRJU0VMRUNUICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5maWx0ZXJPcHRpb25zICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5maWx0ZXJPcHRpb25zLmxlbmd0aCA+IDBcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQtZmlsdGVyTW9kZWw9XCJmaWx0ZXJNb2RlbFwiXG4gICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHAtbXVsdGlTZWxlY3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvbnNdPVwiY29sLmZpbHRlck9wdGlvbnNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXRlc3RGaWx0ZXJWYWx1ZXNbY29sLmNvZGUhXSA/PyBmaWx0ZXJNb2RlbD8udmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25GaWx0ZXJWYWx1ZUNoYW5nZShjb2wuY29kZSEsIGZpbHRlck1vZGVsLCAkZXZlbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BsYXk9XCJjaGlwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJDaG9vc2Ugb3B0aW9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjdXN0b20tbXVsdGlzZWxlY3RcIlxuICAgICAgICAgICAgICAgICAgICAgICAgPjwvcC1tdWx0aVNlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICA8L3AtY29sdW1uRmlsdGVyPlxuICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgIDwhLS0gTk9OLVNPUlRBQkxFIEhFQURFUiAtLT5cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjbm9Tb3J0SGVhZGVyPlxuICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgY2xhc3M9XCJoZWFkZXItY29udGFpbmVyIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWJldHdlZW5cIlxuICAgICAgICAgICAgICAgIFtzdHlsZS53aWR0aF09XCJjb2wud2lkdGggfHwgZ2V0SGVhZGVyV2lkdGgoY29sKVwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLnBhZGRpbmddPVwiJzBweCdcIlxuICAgICAgICAgICAgICAgIFtzdHlsZS5tYXJnaW5dPVwiJzEwcHgnXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxzcGFuIFtuZ0NsYXNzXT1cImdldEhlYWRlclRpdGxlQ2xhc3MoY29sKVwiPlxuICAgICAgICAgICAgICAgICAge3sgY29sLnRpdGxlIH19XG4gICAgICAgICAgICAgICAgPC9zcGFuPlxuXG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImhhc0NvbHVtbkZpbHRlciAmJiBjb2wuaXNGaWx0ZXIgIT09IGZhbHNlXCI+XG4gICAgICAgICAgICAgICAgICA8IS0tIEFNT1VOVCBiZWhhdmVzIGxpa2UgTlVNQkVSIC0tPlxuICAgICAgICAgICAgICAgICAgPHAtY29sdW1uRmlsdGVyXG4gICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29sLnR5cGUgPT09ICdBTU9VTlQnXCJcbiAgICAgICAgICAgICAgICAgICAgZGlzcGxheT1cIm1lbnVcIlxuICAgICAgICAgICAgICAgICAgICBbZmllbGRdPVwiY29sLmNvZGVcIlxuICAgICAgICAgICAgICAgICAgICBbdHlwZV09XCJnZXRDb2x1bW5GaWx0ZXJUeXBlKGNvbClcIlxuICAgICAgICAgICAgICAgICAgICBbY3VycmVuY3ldPVwiZ2V0Q3VycmVuY3lTeW1ib2woY29sKVwiXG4gICAgICAgICAgICAgICAgICAgIFtzaG93QXBwbHlCdXR0b25dPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgIFtzaG93Q2xlYXJCdXR0b25dPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgICAgICAgICAgICAgIHBUZW1wbGF0ZT1cImZpbHRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgbGV0LWZpbHRlck1vZGVsPVwiZmlsdGVyTW9kZWxcIlxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICBwSW5wdXRUZXh0XG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtzdGVwXT1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wuZGVjaW1hbFBsYWNlc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gJzAuJyArICcxJy5wYWRFbmQoY29sLmRlY2ltYWxQbGFjZXMsICcwJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICdhbnknXG4gICAgICAgICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGxhdGVzdEZpbHRlclZhbHVlc1tjb2wuY29kZSFdID8/IGZpbHRlck1vZGVsPy52YWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBvbkZpbHRlclZhbHVlQ2hhbmdlKGNvbC5jb2RlISwgZmlsdGVyTW9kZWwsICRldmVudClcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIkVudGVyIGFuIGFtb3VudFwiXG4gICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgIDwvcC1jb2x1bW5GaWx0ZXI+XG5cbiAgICAgICAgICAgICAgICAgIDxwLWNvbHVtbkZpbHRlclxuICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbC50eXBlICE9PSAnQU1PVU5UJ1wiXG4gICAgICAgICAgICAgICAgICAgIGRpc3BsYXk9XCJtZW51XCJcbiAgICAgICAgICAgICAgICAgICAgW2ZpZWxkXT1cImNvbC5jb2RlXCJcbiAgICAgICAgICAgICAgICAgICAgW3R5cGVdPVwiZ2V0Q29sdW1uRmlsdGVyVHlwZShjb2wpXCJcbiAgICAgICAgICAgICAgICAgICAgW3Nob3dBcHBseUJ1dHRvbl09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgW3Nob3dDbGVhckJ1dHRvbl09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBEQVRFIC0tPlxuICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgICAgICAgICAgICBwVGVtcGxhdGU9XCJmaWx0ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgIGxldC1maWx0ZXJNb2RlbD1cImZpbHRlck1vZGVsXCJcbiAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImdldENvbHVtbkZpbHRlclR5cGUoY29sKSA9PT0gJ2RhdGUnXCJcbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgIDxwLWNhbGVuZGFyXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbGF0ZXN0RmlsdGVyVmFsdWVzW2NvbC5jb2RlIV0gPz8gZmlsdGVyTW9kZWw/LnZhbHVlXG4gICAgICAgICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIG9uRmlsdGVyVmFsdWVDaGFuZ2UoY29sLmNvZGUhLCBmaWx0ZXJNb2RlbCwgJGV2ZW50KVxuICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGVGb3JtYXQ9XCJkZC9tbS95eVwiXG4gICAgICAgICAgICAgICAgICAgICAgPjwvcC1jYWxlbmRhcj5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgICAgICA8IS0tIE1VTFRJU0VMRUNUIC0tPlxuICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgICAgICAgICAgICBwVGVtcGxhdGU9XCJmaWx0ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgIGxldC1maWx0ZXJNb2RlbD1cImZpbHRlck1vZGVsXCJcbiAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImdldENvbHVtbkZpbHRlclR5cGUoY29sKSA9PT0gJ211bHRpU2VsZWN0J1wiXG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICA8cC1tdWx0aVNlbGVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvbnNdPVwiY29sLmZpbHRlck9wdGlvbnNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGxhdGVzdEZpbHRlclZhbHVlc1tjb2wuY29kZSFdID8/IGZpbHRlck1vZGVsPy52YWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBvbkZpbHRlclZhbHVlQ2hhbmdlKGNvbC5jb2RlISwgZmlsdGVyTW9kZWwsICRldmVudClcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNwbGF5PVwiY2hpcFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIlNlbGVjdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImN1c3RvbS1tdWx0aXNlbGVjdFwiXG4gICAgICAgICAgICAgICAgICAgICAgPjwvcC1tdWx0aVNlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgIDwvcC1jb2x1bW5GaWx0ZXI+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICA8L3RoPlxuXG4gICAgICAgICAgPCEtLSBHUk9VUEVEIEhFQURFUiAtLT5cbiAgICAgICAgICA8bmctdGVtcGxhdGUgI2dyb3VwSGVhZGVyPlxuICAgICAgICAgICAgPHRoXG4gICAgICAgICAgICAgIFthdHRyLmNvbHNwYW5dPVwiY29sLmNoaWxkcmVuPy5sZW5ndGhcIlxuICAgICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiY29sLndpZHRoIHx8IGdldEhlYWRlcldpZHRoKGNvbClcIlxuICAgICAgICAgICAgICBbbmdDbGFzc109XCJnZXRIZWFkZXJBbGlnbkNsYXNzKGNvbClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8c3Bhbj57eyBjb2wudGl0bGUgfX08L3NwYW4+XG4gICAgICAgICAgICA8L3RoPlxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPC90cj5cblxuICAgICAgPCEtLSBDSElMRCBIRUFERVJTIC0tPlxuICAgICAgPHRyICpuZ0lmPVwiaGFzR3JvdXBlZENvbHVtbnNcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgY29sIG9mIGNvbHVtbnNcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29sLmNoaWxkcmVuXCI+XG4gICAgICAgICAgICA8dGhcbiAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IGNoaWxkIG9mIGNvbC5jaGlsZHJlblwiXG4gICAgICAgICAgICAgIFtzdHlsZS53aWR0aF09XCJjaGlsZC53aWR0aCB8fCBnZXRIZWFkZXJXaWR0aChjaGlsZClcIlxuICAgICAgICAgICAgICBbc3R5bGUucGFkZGluZ109XCInMHB4J1wiXG4gICAgICAgICAgICA+PC90aD5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8L3RyPlxuICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICA8IS0tIEVNUFRZIE1FU1NBR0UgLS0+XG4gICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cImVtcHR5bWVzc2FnZVwiPlxuICAgICAgPHRyIGNsYXNzPVwicC1kYXRhdGFibGUtZW1wdHltZXNzYWdlXCI+XG4gICAgICAgIDwhLS0gc3BhbiBhbGwgY29sdW1ucyAtLT5cbiAgICAgICAgPHRkIGNsYXNzPVwiZW1wdHktbWVzc2FnZS1jZWxsXCIgW2F0dHIuY29sc3Bhbl09XCJjb2x1bW5zLmxlbmd0aCB8fCAxXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImVtcHR5LW1lc3NhZ2Utd3JhcHBlclwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImVtcHR5LW1lc3NhZ2VcIj5cbiAgICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1pbmZvLWNpcmNsZVwiPjwvaT5cbiAgICAgICAgICAgICAgPHA+Tm8gcmVjb3JkcyBhdmFpbGFibGUgdG8gZGlzcGxheS48L3A+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvdHI+XG4gICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgIDwhLS0gQk9EWSAtLT5cbiAgICA8bmctdGVtcGxhdGVcbiAgICAgIHBUZW1wbGF0ZT1cImJvZHlcIlxuICAgICAgbGV0LWRhdGFcbiAgICAgIGxldC1lZGl0aW5nPVwiZWRpdGluZ1wiXG4gICAgICBsZXQtcmk9XCJyb3dJbmRleFwiXG4gICAgPlxuICAgICAgPHRyICpuZ0lmPVwiIWxvYWRpbmdcIiBbcEVkaXRhYmxlUm93XT1cImlzRWRpdCA/IGRhdGEgOiBudWxsXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGNvbCBvZiBjb2x1bW5zXCI+XG4gICAgICAgICAgPCEtLSBTSU1QTEUgQ09MVU1OUyAobm8gY2hpbGRyZW4pIC0tPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhY29sLmNoaWxkcmVuOyBlbHNlIGNoaWxkQ29sdW1uc1wiPlxuICAgICAgICAgICAgPCEtLSBFRElUQUJMRSBDRUxMIC0tPlxuICAgICAgICAgICAgPHRkXG4gICAgICAgICAgICAgICpuZ0lmPVwiXG4gICAgICAgICAgICAgICAgaXNFZGl0YWJsZShjb2wuY29kZSEpICYmIGNvbC50eXBlICE9PSBUYWJsZVR5cGVFbnVtLkFDVElPTjtcbiAgICAgICAgICAgICAgICBlbHNlIG5vcm1hbFREXG4gICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgIFtzdHlsZS53aWR0aF09XCJjb2wud2lkdGggfHwgZ2V0SGVhZGVyV2lkdGgoY29sKVwiXG4gICAgICAgICAgICAgIFtuZ0NsYXNzXT1cImdldERhdGFBbGlnbkNsYXNzKGNvbClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8IS0tIEVkaXRhYmxlIGlucHV0IGZvciBOVU1CRVIvREFURS9TVFJJTkcvTVVMVElTRUxFQ1QgLS0+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc011bHRpU2VsZWN0KGNvbC5jb2RlKTsgZWxzZSBkYXRlUGlja2VyXCI+XG4gICAgICAgICAgICAgICAgPHAtY2VsbEVkaXRvcj5cbiAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJpbnB1dFwiPlxuICAgICAgICAgICAgICAgICAgICA8cC1tdWx0aVNlbGVjdFxuICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZFRvPVwiYm9keVwiXG4gICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwiZGF0YVtjb2wuY29kZSFdXCJcbiAgICAgICAgICAgICAgICAgICAgICBbc3R5bGVdPVwieyB3aWR0aDogJzEwMCUnIH1cIlxuICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cImNoYW5nZUhhbmRsZXIoZGF0YS5pZCwgY29sLmNvZGUsICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25zXT1cIm9wdGlvblZhbHVlc1wiXG4gICAgICAgICAgICAgICAgICAgID48L3AtbXVsdGlTZWxlY3Q+XG4gICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cIm91dHB1dFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXVsdGktc2VsZWN0LWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHJlYyBvZiBkYXRhW2NvbC5jb2RlIV1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxwLXRhZyBbdmFsdWVdPVwicmVjXCI+PC9wLXRhZz5cbiAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgIDwvcC1jZWxsRWRpdG9yPlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI2RhdGVQaWNrZXI+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzRGF0ZVBpY2tlcihjb2wuY29kZSk7IGVsc2Ugbm9ybWFsSW5wdXRcIj5cbiAgICAgICAgICAgICAgICAgIDxwLWNlbGxFZGl0b3I+XG4gICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJpbnB1dFwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxwLWNhbGVuZGFyXG4gICAgICAgICAgICAgICAgICAgICAgICBbaW5wdXRJZF09XCJkYXRhW2NvbC5jb2RlIV1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwiZGF0YVtjb2wuY29kZSFdXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFuZ2VIYW5kbGVyKGRhdGEuaWQsIGNvbC5jb2RlLCAkZXZlbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2RhdGVGb3JtYXRdPVwiJ2RkL21tL3l5J1wiXG4gICAgICAgICAgICAgICAgICAgICAgPjwvcC1jYWxlbmRhcj5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cIm91dHB1dFwiPlxuICAgICAgICAgICAgICAgICAgICAgIHt7IGRhdGFbY29sLmNvZGUhXSB8IGN1c3RvbURhdGUgfX1cbiAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgIDwvcC1jZWxsRWRpdG9yPlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjbm9ybWFsSW5wdXQ+XG4gICAgICAgICAgICAgICAgPHAtY2VsbEVkaXRvcj5cbiAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJpbnB1dFwiPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICBwSW5wdXRUZXh0XG4gICAgICAgICAgICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cImRhdGFbY29sLmNvZGUhXVwiXG4gICAgICAgICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJvbkNoYW5nZSgkZXZlbnQsIGRhdGEuaWQsIGNvbC5jb2RlKVwiXG4gICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cIm91dHB1dFwiPlxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbC50eXBlID09PSBUYWJsZVR5cGVFbnVtLkFNT1VOVDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Ugbm9ybWFsT3V0cHV0XG4gICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgIHt7XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhW2NvbC5jb2RlIV1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgfCBjdXN0b21DdXJyZW5jeVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogZ2V0Q3VycmVuY3lTeW1ib2woY29sKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogY29sLmRlY2ltYWxQbGFjZXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGNvbC50aG91c2FuZFNlcGFyYXRvclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogY29sLmRlY2ltYWxTZXBhcmF0b3JcbiAgICAgICAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNub3JtYWxPdXRwdXQ+XG4gICAgICAgICAgICAgICAgICAgICAge3sgZGF0YVtjb2wuY29kZSFdIH19XG4gICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgIDwvcC1jZWxsRWRpdG9yPlxuICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgPC90ZD5cblxuICAgICAgICAgICAgPCEtLSBOT04tRURJVEFCTEUgQ0VMTCAoQUxXQVlTIFJFTkRFUkVEKSAtLT5cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjbm9ybWFsVEQ+XG4gICAgICAgICAgICAgIDx0ZFxuICAgICAgICAgICAgICAgIFtzdHlsZS53aWR0aF09XCJjb2wud2lkdGggfHwgZ2V0SGVhZGVyV2lkdGgoY29sKVwiXG4gICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiW1xuICAgICAgICAgICAgICAgICAgZ2V0RGF0YUFsaWduQ2xhc3MoY29sKSxcbiAgICAgICAgICAgICAgICAgIGNvbC50eXBlID09PSBUYWJsZVR5cGVFbnVtLkFDVElPTiA/ICdhY3Rpb24tY29sdW1uJyA6ICcnXG4gICAgICAgICAgICAgICAgXVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8IS0tIEFDVElPTiBjb2x1bW46IGJ1aWx0LWluIGVkaXQvZGVsZXRlICsgY3VzdG9tIGFjdGlvbnMgLS0+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb2wudHlwZSA9PT0gVGFibGVUeXBlRW51bS5BQ1RJT047IGVsc2Ugbm9uQWN0aW9uQ2VsbFwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFjdGlvbi1idXR0b25zLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICA8IS0tIGJ1aWx0LWluIGRlbGV0ZSAtLT5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiaXNEZWxldGVcIlxuICAgICAgICAgICAgICAgICAgICAgIHBCdXR0b25cbiAgICAgICAgICAgICAgICAgICAgICBwUmlwcGxlXG4gICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgICAgaWNvbj1cInBpIHBpLXRyYXNoXCJcbiAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiRGVsZXRlKGRhdGEuaWQpXCJcbiAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInAtYnV0dG9uLXJvdW5kZWQgcC1idXR0b24tdGV4dFwiXG4gICAgICAgICAgICAgICAgICAgID48L2J1dHRvbj5cblxuICAgICAgICAgICAgICAgICAgICA8IS0tIGJ1aWx0LWluIGlubGluZSBlZGl0IC0tPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiaXNFZGl0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgcEluaXRFZGl0YWJsZVJvd1xuICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCIhZWRpdGluZ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBwQnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICBwUmlwcGxlXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGljb249XCJwaSBwaS1wZW5jaWxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImluaXRFZGl0YWJsZVJvdyhkYXRhKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInAtYnV0dG9uLXJvdW5kZWQgcC1idXR0b24tdGV4dFwiXG4gICAgICAgICAgICAgICAgICAgICAgPjwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiZWRpdGluZ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBwU2F2ZUVkaXRhYmxlUm93XG4gICAgICAgICAgICAgICAgICAgICAgICBwQnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICBwUmlwcGxlXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGljb249XCJwaSBwaS1jaGVja1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwic2F2ZUVkaXRhYmxlUm93KGRhdGEpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwicC1idXR0b24tcm91bmRlZCBwLWJ1dHRvbi10ZXh0XCJcbiAgICAgICAgICAgICAgICAgICAgICA+PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJlZGl0aW5nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBDYW5jZWxFZGl0YWJsZVJvd1xuICAgICAgICAgICAgICAgICAgICAgICAgcEJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgcFJpcHBsZVxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICBpY29uPVwicGkgcGktdGltZXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNhbmNlbEVkaXRhYmxlUm93KGRhdGEpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwicC1idXR0b24tcm91bmRlZCBwLWJ1dHRvbi10ZXh0XCJcbiAgICAgICAgICAgICAgICAgICAgICA+PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gY3VzdG9tIGFjdGlvbnMgLS0+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgYWN0IG9mIGN1c3RvbUFjdGlvbnNcIlxuICAgICAgICAgICAgICAgICAgICAgIHBCdXR0b25cbiAgICAgICAgICAgICAgICAgICAgICBwUmlwcGxlXG4gICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJwLWJ1dHRvbi1yb3VuZGVkIHAtYnV0dG9uLXRleHRcIlxuICAgICAgICAgICAgICAgICAgICAgIFtpY29uXT1cImFjdC5pY29uIHx8ICdwaSBwaS1lbGxpcHNpcy1oJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiYWN0LnN0eWxlQ2xhc3NcIlxuICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJvbkN1c3RvbUFjdGlvbkNsaWNrKGFjdCwgZGF0YSlcIlxuICAgICAgICAgICAgICAgICAgICA+PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgIDwhLS0gTk9OLUFDVElPTiBjZWxscyAtLT5cbiAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI25vbkFjdGlvbkNlbGw+XG4gICAgICAgICAgICAgICAgICA8IS0tIENPTVBPU0VEIC0tPlxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgICAgICAgICAgICAgIGNvbC50eXBlID09PSBUYWJsZVR5cGVFbnVtLkNPTVBPU0VEO1xuICAgICAgICAgICAgICAgICAgICAgIGVsc2Ugbm9uQ29tcG9zZWRcbiAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbXBvc2VkLWNlbGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAqbmdGb3I9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNvbXBvc2VkTmFtZSBvZiBjb2wuY29tcG9zZWROYW1lcztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGkgPSBpbmRleFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIElNQUdFIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5jb21wb3NlZFR5cGVzICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sLmNvbXBvc2VkVHlwZXNbaV0gPT09IFRhYmxlVHlwZUVudW0uSU1BR0VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzcmNdPVwiZGF0YVtjb2wuY29kZSFdPy5bY29tcG9zZWROYW1lXVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWx0PVwiY29tcG9zZWQtaW1nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNvbXBvc2VkLWltYWdlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldEltYWdlU3R5bGUoY29sLmNvbXBvc2VkU3R5bGVzPy5bY29tcG9zZWROYW1lXSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gU1RSSU5HIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5jb21wb3NlZFR5cGVzICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sLmNvbXBvc2VkVHlwZXNbaV0gPT09IFRhYmxlVHlwZUVudW0uU1RSSU5HXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjb21wb3NlZC10ZXh0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldFRpdGxlU3R5bGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5jb21wb3NlZFN0eWxlcz8uW2NvbXBvc2VkTmFtZV1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgZGF0YVtjb2wuY29kZSFdPy5bY29tcG9zZWROYW1lXSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNub25Db21wb3NlZD5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBBTU9VTlQtLT5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29sLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uQU1PVU5UOyBlbHNlIG5vbkFtb3VudFwiXG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICB7e1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVtjb2wuY29kZSFdXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHwgY3VzdG9tQ3VycmVuY3lcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGdldEN1cnJlbmN5U3ltYm9sKGNvbClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGNvbC5kZWNpbWFsUGxhY2VzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBjb2wudGhvdXNhbmRTZXBhcmF0b3JcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGNvbC5kZWNpbWFsU2VwYXJhdG9yXG4gICAgICAgICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNub25BbW91bnQ+XG4gICAgICAgICAgICAgICAgICAgICAgPCEtLSBOVU1CRVItLT5cbiAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wudHlwZSA9PT0gVGFibGVUeXBlRW51bS5OVU1CRVI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Ugbm9uTnVtYmVyXG4gICAgICAgICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdE51bWJlcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhW2NvbC5jb2RlIV0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sLmRlY2ltYWxQbGFjZXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sLnRob3VzYW5kU2VwYXJhdG9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5kZWNpbWFsU2VwYXJhdG9yXG4gICAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI25vbk51bWJlcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gREFURSAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wudHlwZSA9PT0gVGFibGVUeXBlRW51bS5EQVRFO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Ugbm9ybWFsVHlwZXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAge3sgZm9ybWF0RGF0ZShkYXRhW2NvbC5jb2RlIV0pIH19XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNub3JtYWxUeXBlcz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBTVFJJTkcsIE1VTFRJU0VMRUNULS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUYWJsZVR5cGVFbnVtLlNUUklORyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGFibGVUeXBlRW51bS5NVUxUSVNFTEVDVFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXS5pbmNsdWRlcyhjb2wudHlwZSEpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGRhdGFbY29sLmNvZGUhXSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICA8IS0tIENISUxEIENPTFVNTlMgLS0+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlICNjaGlsZENvbHVtbnM+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBjaGlsZCBvZiBjb2wuY2hpbGRyZW5cIj5cbiAgICAgICAgICAgICAgPHRkXG4gICAgICAgICAgICAgICAgW3N0eWxlLndpZHRoXT1cImNoaWxkLndpZHRoIHx8IGdldEhlYWRlcldpZHRoKGNoaWxkKVwiXG4gICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiZ2V0RGF0YUFsaWduQ2xhc3MoY2hpbGQpXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICpuZ0lmPVwiaXNFZGl0YWJsZShjaGlsZC5jb2RlKTsgZWxzZSBjaGlsZE5vcm1hbFREXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICA8cC1jZWxsRWRpdG9yPlxuICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiaW5wdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgIHBJbnB1dFRleHRcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cImNoaWxkLmNvZGUgPyBkYXRhW2NoaWxkLmNvZGVdIDogbnVsbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cIm9uQ2hhbmdlKCRldmVudCwgZGF0YS5pZCwgY2hpbGQuY29kZSlcIlxuICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJvdXRwdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICB7eyBjaGlsZC5jb2RlID8gZGF0YVtjaGlsZC5jb2RlXSA6IFwiXCIgfX1cbiAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgIDwvcC1jZWxsRWRpdG9yPlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNjaGlsZE5vcm1hbFREPlxuICAgICAgICAgICAgICAgICAge3sgY2hpbGQuY29kZSA/IGRhdGFbY2hpbGQuY29kZV0gOiBcIlwiIH19XG4gICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPC90cj5cbiAgICA8L25nLXRlbXBsYXRlPlxuICA8L3AtdGFibGU+XG48L2Rpdj5cbiJdfQ==