ng-prime-tools 1.0.31 → 1.0.32

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.
@@ -37,6 +37,7 @@ export class PTAdvancedPrimeTableComponent {
37
37
  this.search = new EventEmitter();
38
38
  this.exportExcelEvent = new EventEmitter();
39
39
  this.exportPdfEvent = new EventEmitter();
40
+ this.pageChange = new EventEmitter();
40
41
  this.TableTypeEnum = TableTypeEnum;
41
42
  this.searchValue = '';
42
43
  this.filters = {};
@@ -60,13 +61,15 @@ export class PTAdvancedPrimeTableComponent {
60
61
  this.hasGroupedColumns = false;
61
62
  }
62
63
  ngOnInit() {
64
+ console.log('PTAdvancedPrimeTable columns:', this.columns);
65
+ console.log('PTAdvancedPrimeTable totalRecords input:', this.totalRecords);
63
66
  this.hasGroupedColumns = this.columns.some((col) => col.children && col.children.length > 0);
64
67
  this.globalFilterFields = this.columns
65
68
  .filter((col) => col.code !== undefined && col.isFilter !== false)
66
69
  .map((col) => col.code);
67
70
  this.initializePagination();
68
71
  this.initializeActions();
69
- // Set default value for isSortable
72
+ // Set default value for isSortable / isEditable + widths
70
73
  this.columns.forEach((col) => {
71
74
  if (col.type === TableTypeEnum.ACTION) {
72
75
  col.isEditable = false;
@@ -98,85 +101,81 @@ export class PTAdvancedPrimeTableComponent {
98
101
  options: col.filterOptions,
99
102
  value: [],
100
103
  label: 'Filter by ' + composedName,
101
- placeholder: 'Select options for ' + composedName,
104
+ placeholder: 'Select option',
102
105
  };
103
106
  });
104
107
  }
105
108
  // Get the column type for composed fields (STRING, IMAGE, etc.)
106
109
  getComposedFieldType(col, composedName) {
107
- // Ensure that col.composedNames and col.composedTypes are valid arrays
108
110
  if (col.composedNames && col.composedTypes) {
109
111
  const index = col.composedNames.indexOf(composedName);
110
- // Check if index is a valid number (not -1) and within bounds of composedTypes array
111
112
  if (index >= 0 && index < col.composedTypes.length) {
112
- return col.composedTypes[index]; // Safe access of composedTypes array
113
+ return col.composedTypes[index];
113
114
  }
114
115
  }
115
- return undefined; // Return undefined if no valid index is found or composedNames/composedTypes are not valid
116
+ return undefined;
116
117
  }
117
- onComposedFilterChange(composedName, selectedValues) {
118
- console.log('Selected Values:', selectedValues);
119
- console.log('Data Before Filtering:', this.data);
120
- // Update the filter value with the selected values
118
+ onComposedFilterChange(col, composedName, selectedValues) {
121
119
  this.filters[composedName].value = selectedValues;
122
- // Emit the filter event to notify the parent component (if needed)
123
120
  this.filter.emit(this.filters);
124
- // Get the filter value (joining array into a string)
125
121
  const filterValue = selectedValues.join(',');
126
- console.log('Filter Values to be Applied:', filterValue);
127
- // Apply global filter using PrimeNG's filterGlobal method
122
+ let matchResults = [];
123
+ selectedValues.forEach((value) => {
124
+ const matches = this.dt.value.filter((row) => {
125
+ return row[col.code]?.[composedName]
126
+ ?.toString()
127
+ .toLowerCase()
128
+ .includes(value.toLowerCase());
129
+ });
130
+ matchResults = [...matchResults, ...matches];
131
+ });
132
+ matchResults = Array.from(new Set(matchResults));
133
+ this.dt.filteredValue = matchResults;
128
134
  this.dt.filterGlobal(filterValue, 'contains');
129
135
  }
136
+ // ⛔ Don't override totalRecords here – we are in server-side mode
130
137
  onFilter(event) {
131
- this.totalRecords = event.filteredValue?.length || 0;
138
+ this.filter.emit(event);
139
+ // this.totalRecords = event.filteredValue?.length || 0; // removed
140
+ }
141
+ onPageChange(event) {
142
+ const page = event.page ?? Math.floor((event.first || 0) / event.rows);
143
+ const rows = event.rows;
144
+ this.rows = rows;
145
+ this.pageChange.emit({ page, rows });
132
146
  }
133
147
  onCalendarFilterChange(event, columnCode, filterCallback) {
134
- // Log the data's date format for debugging
135
- console.log('Data Before Filtering:', this.data.map((item) => item[columnCode]));
136
- console.log('event : ' + event);
137
- // Convert the event value to a string (in the desired date format)
138
148
  const filterValue = event ? new Date(event) : null;
139
- console.log('filterValue : ' + filterValue);
140
- // If the filterValue is empty, do not trigger filterCallback
141
149
  if (!filterValue) {
142
150
  return;
143
151
  }
144
- // Manually trigger the filterCallback after updating the value (passing the string value)
145
152
  filterCallback(filterValue);
146
153
  const filterValueString = event ? this.formatDate(event) : '';
147
- // Call the onFilter event to update totalRecords
148
154
  this.onFilter({
149
155
  filteredValue: this.data.filter((item) => {
150
156
  const columnValue = item[columnCode];
151
- // If the column value is a string, use it as is for comparison
152
157
  if (columnValue) {
153
- // Convert the item value to a string (in the same format)
154
158
  const itemDateString = this.formatDate(new Date(columnValue));
155
- return itemDateString === filterValueString; // Compare the string dates
159
+ return itemDateString === filterValueString;
156
160
  }
157
161
  return false;
158
162
  }),
159
163
  });
160
164
  }
161
- // Filter logic for composed columns (to check against multi-select values)
162
165
  filterComposedData(item, composedName, value) {
163
166
  if (Array.isArray(value) && value.length > 0) {
164
167
  return value.some((filterValue) => item[composedName]?.toLowerCase().includes(filterValue.toLowerCase()));
165
168
  }
166
169
  return true;
167
170
  }
168
- // Function to calculate column width based on text in header and data
169
171
  calculateColumnWidth(col) {
170
172
  const calculatedWidth = calculateTextWidth(col, col.title);
171
173
  const totalWidth = calculatedWidth + this.iconWidth + 20;
172
174
  return `${totalWidth}px`;
173
175
  }
174
176
  getHeaderWidth(col) {
175
- // Remove 'px' from col.width and convert it to a number
176
177
  const widthWithoutPx = parseInt(col.width?.replace('px', '') || '0', 10);
177
- // Add 20 to the calculated width
178
178
  const headerWidth = widthWithoutPx + 20;
179
- // Return the new width in 'px'
180
179
  return `${headerWidth}px`;
181
180
  }
182
181
  clear(table) {
@@ -186,7 +185,6 @@ export class PTAdvancedPrimeTableComponent {
186
185
  parseDate(dateString) {
187
186
  const parts = dateString.split('/');
188
187
  if (parts.length === 3) {
189
- // Assuming date format is DD/MM/YYYY
190
188
  const day = parseInt(parts[0], 10);
191
189
  const month = parseInt(parts[1], 10) - 1;
192
190
  const year = parseInt(parts[2], 10);
@@ -197,7 +195,6 @@ export class PTAdvancedPrimeTableComponent {
197
195
  }
198
196
  initializePagination() {
199
197
  if (this.isPaginated) {
200
- // Check if rowsPerPage is undefined or an empty array
201
198
  if (!this.rowsPerPage || this.rowsPerPage.length === 0) {
202
199
  this.rowsPerPage = [20, 30, 40];
203
200
  }
@@ -278,7 +275,6 @@ export class PTAdvancedPrimeTableComponent {
278
275
  return 'text';
279
276
  }
280
277
  }
281
- // State Check Methods
282
278
  isEditable(key) {
283
279
  let column = this.columns.find((item) => item.code === key);
284
280
  return column?.isEditable !== false;
@@ -300,7 +296,6 @@ export class PTAdvancedPrimeTableComponent {
300
296
  return (this.columns.find((item) => item.code === key)?.type ===
301
297
  TableTypeEnum.DATE);
302
298
  }
303
- // Utility Methods
304
299
  dateConverter(value) {
305
300
  return new Date(value).toLocaleDateString('en-US');
306
301
  }
@@ -317,14 +312,12 @@ export class PTAdvancedPrimeTableComponent {
317
312
  filterGlobal(event) {
318
313
  const target = event.target;
319
314
  const value = target.value.toLowerCase();
320
- // Create a new filtered dataset
321
315
  const filteredData = this.data.filter((item) => {
322
316
  return this.globalFilterFields.some((field) => {
323
317
  const column = this.columns.find((col) => col.code === field);
324
318
  if (!column) {
325
319
  return false;
326
320
  }
327
- // Handle different column types
328
321
  if (column.type === TableTypeEnum.DATE) {
329
322
  const itemDate = this.formatDate(item[field]);
330
323
  return itemDate && itemDate.includes(value);
@@ -334,7 +327,6 @@ export class PTAdvancedPrimeTableComponent {
334
327
  return (item[field] && item[field].toString().toLowerCase().includes(value));
335
328
  }
336
329
  else if (column.type === TableTypeEnum.COMPOSED) {
337
- // Handle composed type by searching for text in the composed cells
338
330
  return this.filterComposedColumn(item[field], value);
339
331
  }
340
332
  else {
@@ -342,14 +334,12 @@ export class PTAdvancedPrimeTableComponent {
342
334
  }
343
335
  });
344
336
  });
345
- // Update the table's value
346
337
  this.dt.value = filteredData;
347
- // After filtering, update the totalRecords
348
- this.totalRecords = filteredData.length ?? 0;
338
+ // do NOT override totalRecords in server-side mode
339
+ // this.totalRecords = filteredData.length ?? 0;
349
340
  }
350
341
  filterComposedColumn(composedData, value) {
351
342
  if (composedData) {
352
- // Iterate over composed keys and check if any key's value contains the search text
353
343
  return Object.keys(composedData).some((key) => {
354
344
  const cellValue = composedData[key];
355
345
  if (typeof cellValue === 'string') {
@@ -364,20 +354,17 @@ export class PTAdvancedPrimeTableComponent {
364
354
  if (!date)
365
355
  return '';
366
356
  if (date instanceof Date) {
367
- // Handle Date object
368
357
  const day = date.getDate().toString().padStart(2, '0');
369
358
  const month = (date.getMonth() + 1).toString().padStart(2, '0');
370
359
  const year = date.getFullYear().toString();
371
360
  return `${day}/${month}/${year}`;
372
361
  }
373
362
  else if (typeof date === 'string') {
374
- // Handle string date
375
363
  const parts = date.split('/');
376
364
  if (parts.length === 3) {
377
365
  return `${parts[0]}/${parts[1]}/${parts[2]}`;
378
366
  }
379
367
  else {
380
- // Handle partial dates
381
368
  return date;
382
369
  }
383
370
  }
@@ -395,7 +382,6 @@ export class PTAdvancedPrimeTableComponent {
395
382
  width: style.width || 'auto',
396
383
  height: style.height || 'auto',
397
384
  };
398
- // Fallback to empty string if margin, marginLeft, or marginRight are undefined
399
385
  if (style.margin) {
400
386
  imageStyle.margin = style.margin;
401
387
  }
@@ -428,15 +414,12 @@ export class PTAdvancedPrimeTableComponent {
428
414
  formatNumber(value, decimalPlaces, thousandSeparator = 'comma', decimalSeparator = 'dot') {
429
415
  if (value === null || value === undefined || isNaN(value))
430
416
  return '';
431
- // Convert the number to a string with full precision if decimalPlaces is undefined
432
417
  let formattedNumber = decimalPlaces !== undefined
433
418
  ? value.toFixed(decimalPlaces)
434
419
  : value.toString();
435
- // Replace decimal separator (default is "dot")
436
420
  if (decimalSeparator === 'comma') {
437
421
  formattedNumber = formattedNumber.replace('.', ',');
438
422
  }
439
- // Apply thousand separator only if the number is >= 1000
440
423
  if (thousandSeparator && Math.abs(value) >= 1000) {
441
424
  const parts = formattedNumber.split(decimalSeparator === 'comma' ? ',' : '.');
442
425
  parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousandSeparator === 'comma' ? ',' : ' ');
@@ -445,11 +428,11 @@ export class PTAdvancedPrimeTableComponent {
445
428
  return formattedNumber;
446
429
  }
447
430
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PTAdvancedPrimeTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
448
- 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" }, 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 dataKey=\"id\"\n styleClass=\"p-datatable-gridlines\"\n styleClass=\"p-datatable-striped\"\n editMode=\"row\"\n [scrollable]=\"true\"\n [scrollHeight]=\"maxHeight !== null ? maxHeight : undefined\"\n (onFilter)=\"onFilter($event)\"\n >\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 <div class=\"ml-auto\" *ngIf=\"hasSearchFilter\">\n <!-- Add this wrapper div with ml-auto class -->\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 <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 [style.width]=\"getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n colspan=\"1\"\n >\n <ng-container\n *ngIf=\"isSortable && col.isSortable !== false; else noSortHeader\"\n >\n <th\n pSortableColumn=\"{{ col.code }}\"\n [style.width]=\"getHeaderWidth(col)\"\n >\n <div\n class=\"header-container d-flex align-items-center justify-content-between\"\n [style.width]=\"col.width\"\n [style.padding]=\"'0px'\"\n [style.margin]=\"'10px'\"\n >\n <span>{{ col.title }}</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 <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n display=\"menu\"\n [type]=\"getColumnFilterType(col)\"\n *ngIf=\"col.type === TableTypeEnum.COMPOSED\"\n showClearButton=\"false\"\n showApplyButton=\"false\"\n >\n <!-- TableTypeEnum.COMPOSED -->\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 composedName,\n $event.value\n )\n \"\n [placeholder]=\"\n filters[composedName]?.placeholder\n \"\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 <!-- Define itemTemplate here -->\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 TableTypeEnum.XXX -->\n <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n display=\"menu\"\n [type]=\"getColumnFilterType(col)\"\n *ngIf=\"col.type !== TableTypeEnum.COMPOSED\"\n hideOnClear=\"true\"\n >\n <!-- TableTypeEnum.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 <!-- TableTypeEnum.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 <!-- TableTypeEnum.MULTISELECT -->\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"col.type === TableTypeEnum.MULTISELECT\"\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 </th>\n </ng-container>\n <ng-template #noSortHeader>\n <th>\n <div class=\"header-container\">\n <span>{{ col.title }}</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 </th>\n </ng-template>\n </th>\n <!-- Grouped headers -->\n <ng-template #groupHeader>\n <th\n [attr.colspan]=\"col.children?.length\"\n [style.width]=\"getHeaderWidth(col)\"\n [style.text-align]=\"'center'\"\n >\n <span>{{ col.title }}</span>\n </th>\n </ng-template>\n </ng-container>\n </tr>\n <!-- Child headers (Second Row) -->\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]=\"getHeaderWidth(child)\"\n [style.padding]=\"'0px'\"\n >\n <!-- Sortable/Filterable header logic for child columns -->\n </th>\n </ng-container>\n </ng-container>\n </tr>\n </ng-template>\n\n <!-- Empty message template -->\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 <!-- Render a table row and make it editable if `isEdit` is true -->\n <tr *ngIf=\"!loading\" [pEditableRow]=\"isEdit ? data : null\">\n <!-- Loop through each column -->\n <ng-container *ngFor=\"let col of columns\">\n <!-- Check if the column has children -->\n <ng-container *ngIf=\"!col.children; else childColumns\">\n <!-- Render a single cell for columns without children -->\n <ng-container\n *ngIf=\"col.code !== undefined && data[col.code] !== undefined\"\n >\n <td\n *ngIf=\"isEditable(col.code); else normalTD\"\n [style.width]=\"getHeaderWidth(col)\"\n >\n <!-- Editable input for the column -->\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)=\"\n changeHandler(data.id, col.code, $event)\n \"\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\n *ngIf=\"isDatePicker(col.code); else normalInput\"\n >\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 <ng-template #normalTD>\n <td [style.width]=\"getHeaderWidth(col)\">\n <!-- COMPOSED -->\n <ng-container *ngIf=\"col.type === TableTypeEnum.COMPOSED\">\n <div class=\"composed-cell\">\n <ng-container\n *ngFor=\"\n let composedName of col.composedNames;\n let i = index\n \"\n >\n <!-- Check if the composedType is 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]=\"getImageStyle(col.composedStyles?.[composedName])\"\n />\n </ng-container>\n\n <!-- Check if the composedType is 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]=\"getTitleStyle(col.composedStyles?.[composedName])\"\n >\n {{ data[col.code][composedName] }}\n </span>\n </ng-container>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- AMOUNT-->\n <ng-container *ngIf=\"col.type === TableTypeEnum.AMOUNT\">\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 <!-- NUMBER-->\n <ng-container *ngIf=\"col.type === TableTypeEnum.NUMBER\">\n {{\n formatNumber(\n data[col.code],\n col.decimalPlaces,\n col.thousandSeparator,\n col.decimalSeparator\n )\n }}\n </ng-container>\n\n <!-- DATE -->\n <ng-container *ngIf=\"col.type === TableTypeEnum.DATE\">\n <!-- Format the date using your formatDate method -->\n {{ formatDate(data[col.code]) }}\n </ng-container>\n\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 </td>\n </ng-template>\n </ng-container>\n </ng-container>\n\n <!-- Render child columns if the column has children -->\n <ng-template #childColumns>\n <ng-container *ngFor=\"let child of col.children\">\n <ng-container\n *ngIf=\"\n child.code !== undefined && data[child.code] !== undefined\n \"\n >\n <td [style.width]=\"getHeaderWidth(child)\">\n <!-- Render editable or normal cells for child columns -->\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]=\"data[child.code]\"\n (change)=\"onChange($event, data.id, child.code)\"\n />\n </ng-template>\n <ng-template pTemplate=\"output\">\n {{ data[child.code] }}\n </ng-template>\n </p-cellEditor>\n </ng-container>\n\n <ng-template #childNormalTD>\n {{ data[child.code] }}\n </ng-template>\n </td>\n </ng-container>\n </ng-container>\n </ng-template>\n </ng-container>\n\n <!-- Render action buttons if there are any actions defined -->\n <td *ngIf=\"actions?.length\">\n <div class=\"action-buttons-container\">\n <div *ngIf=\"isDelete\">\n <button\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 </div>\n <div>\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 </div>\n </td>\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 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:flex;flex-direction:column;height:100%;overflow:hidden}.pt-advanced-prime-table ::ng-deep .p-datatable{display:flex;flex-direction:column;width:100%;border-collapse:collapse;table-layout:fixed}.pt-advanced-prime-table ::ng-deep .p-datatable thead{display:table;width:100%;table-layout:fixed;background:#fff;z-index:2}.pt-advanced-prime-table ::ng-deep .p-datatable tfoot{display:table;width:100%;table-layout:fixed;background:#fff;z-index:2}.pt-advanced-prime-table ::ng-deep .p-datatable tbody{display:block;overflow-y:auto;overflow-x:hidden}.pt-advanced-prime-table ::ng-deep .p-datatable tbody tr{display:table;width:100%;table-layout:fixed}.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}\n"], dependencies: [{ 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" }] }); }
431
+ 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\"\n styleClass=\"p-datatable-striped\"\n editMode=\"row\"\n [scrollable]=\"true\"\n [scrollHeight]=\"maxHeight !== null ? maxHeight : undefined\"\n (onFilter)=\"onFilter($event)\"\n (onPage)=\"onPageChange($event)\"\n >\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 <div class=\"ml-auto\" *ngIf=\"hasSearchFilter\">\n <!-- Add this wrapper div with ml-auto class -->\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 <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 [style.width]=\"getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n colspan=\"1\"\n >\n <ng-container\n *ngIf=\"isSortable && col.isSortable !== false; else noSortHeader\"\n >\n <th\n pSortableColumn=\"{{ col.code }}\"\n [style.width]=\"getHeaderWidth(col)\"\n >\n <div\n class=\"header-container d-flex align-items-center justify-content-between\"\n [style.width]=\"col.width\"\n [style.padding]=\"'0px'\"\n [style.margin]=\"'10px'\"\n >\n <span>{{ col.title }}</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 <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n display=\"menu\"\n [type]=\"getColumnFilterType(col)\"\n *ngIf=\"col.type === TableTypeEnum.COMPOSED\"\n showClearButton=\"false\"\n showApplyButton=\"false\"\n >\n <!-- TableTypeEnum.COMPOSED -->\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]=\"\n filters[composedName]?.placeholder\n \"\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 <!-- Define itemTemplate here -->\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 TableTypeEnum.XXX -->\n <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n display=\"menu\"\n [type]=\"getColumnFilterType(col)\"\n *ngIf=\"col.type !== TableTypeEnum.COMPOSED\"\n hideOnClear=\"true\"\n >\n <!-- TableTypeEnum.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 <!-- TableTypeEnum.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 <!-- TableTypeEnum.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 </th>\n </ng-container>\n <ng-template #noSortHeader>\n <th>\n <div class=\"header-container\">\n <span>{{ col.title }}</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 </th>\n </ng-template>\n </th>\n <!-- Grouped headers -->\n <ng-template #groupHeader>\n <th\n [attr.colspan]=\"col.children?.length\"\n [style.width]=\"getHeaderWidth(col)\"\n [style.text-align]=\"'center'\"\n >\n <span>{{ col.title }}</span>\n </th>\n </ng-template>\n </ng-container>\n </tr>\n <!-- Child headers (Second Row) -->\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]=\"getHeaderWidth(child)\"\n [style.padding]=\"'0px'\"\n >\n <!-- Sortable/Filterable header logic for child columns -->\n </th>\n </ng-container>\n </ng-container>\n </tr>\n </ng-template>\n\n <!-- Empty message template -->\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 <!-- Render a table row and make it editable if `isEdit` is true -->\n <tr *ngIf=\"!loading\" [pEditableRow]=\"isEdit ? data : null\">\n <!-- Loop through each column -->\n <ng-container *ngFor=\"let col of columns\">\n <!-- Check if the column has children -->\n <ng-container *ngIf=\"!col.children; else childColumns\">\n <!-- Render a single cell for columns without children -->\n <ng-container\n *ngIf=\"col.code !== undefined && data[col.code] !== undefined\"\n >\n <td\n *ngIf=\"isEditable(col.code); else normalTD\"\n [style.width]=\"getHeaderWidth(col)\"\n >\n <!-- Editable input for the column -->\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)=\"\n changeHandler(data.id, col.code, $event)\n \"\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\n *ngIf=\"isDatePicker(col.code); else normalInput\"\n >\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 <ng-template #normalTD>\n <td [style.width]=\"getHeaderWidth(col)\">\n <!-- COMPOSED -->\n <ng-container *ngIf=\"col.type === TableTypeEnum.COMPOSED\">\n <div class=\"composed-cell\">\n <ng-container\n *ngFor=\"\n let composedName of col.composedNames;\n let i = index\n \"\n >\n <!-- Check if the composedType is 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]=\"getImageStyle(col.composedStyles?.[composedName])\"\n />\n </ng-container>\n\n <!-- Check if the composedType is 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]=\"getTitleStyle(col.composedStyles?.[composedName])\"\n >\n {{ data[col.code][composedName] }}\n </span>\n </ng-container>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- AMOUNT-->\n <ng-container *ngIf=\"col.type === TableTypeEnum.AMOUNT\">\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 <!-- NUMBER-->\n <ng-container *ngIf=\"col.type === TableTypeEnum.NUMBER\">\n {{\n formatNumber(\n data[col.code],\n col.decimalPlaces,\n col.thousandSeparator,\n col.decimalSeparator\n )\n }}\n </ng-container>\n\n <!-- DATE -->\n <ng-container *ngIf=\"col.type === TableTypeEnum.DATE\">\n <!-- Format the date using your formatDate method -->\n {{ formatDate(data[col.code]) }}\n </ng-container>\n\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 </td>\n </ng-template>\n </ng-container>\n </ng-container>\n\n <!-- Render child columns if the column has children -->\n <ng-template #childColumns>\n <ng-container *ngFor=\"let child of col.children\">\n <ng-container\n *ngIf=\"\n child.code !== undefined && data[child.code] !== undefined\n \"\n >\n <td [style.width]=\"getHeaderWidth(child)\">\n <!-- Render editable or normal cells for child columns -->\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]=\"data[child.code]\"\n (change)=\"onChange($event, data.id, child.code)\"\n />\n </ng-template>\n <ng-template pTemplate=\"output\">\n {{ data[child.code] }}\n </ng-template>\n </p-cellEditor>\n </ng-container>\n\n <ng-template #childNormalTD>\n {{ data[child.code] }}\n </ng-template>\n </td>\n </ng-container>\n </ng-container>\n </ng-template>\n </ng-container>\n\n <!-- Render action buttons if there are any actions defined -->\n <td *ngIf=\"actions?.length\">\n <div class=\"action-buttons-container\">\n <div *ngIf=\"isDelete\">\n <button\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 </div>\n <div>\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 </div>\n </td>\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 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:flex;flex-direction:column;height:100%;overflow:hidden}.pt-advanced-prime-table ::ng-deep .p-datatable{display:flex;flex-direction:column;width:100%;border-collapse:collapse;table-layout:fixed}.pt-advanced-prime-table ::ng-deep .p-datatable thead{display:table;width:100%;table-layout:fixed;background:#fff;z-index:2}.pt-advanced-prime-table ::ng-deep .p-datatable tfoot{display:table;width:100%;table-layout:fixed;background:#fff;z-index:2}.pt-advanced-prime-table ::ng-deep .p-datatable tbody{display:block;overflow-y:auto;overflow-x:hidden}.pt-advanced-prime-table ::ng-deep .p-datatable tbody tr{display:table;width:100%;table-layout:fixed}.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}\n"], dependencies: [{ 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" }] }); }
449
432
  }
450
433
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PTAdvancedPrimeTableComponent, decorators: [{
451
434
  type: Component,
452
- 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 dataKey=\"id\"\n styleClass=\"p-datatable-gridlines\"\n styleClass=\"p-datatable-striped\"\n editMode=\"row\"\n [scrollable]=\"true\"\n [scrollHeight]=\"maxHeight !== null ? maxHeight : undefined\"\n (onFilter)=\"onFilter($event)\"\n >\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 <div class=\"ml-auto\" *ngIf=\"hasSearchFilter\">\n <!-- Add this wrapper div with ml-auto class -->\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 <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 [style.width]=\"getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n colspan=\"1\"\n >\n <ng-container\n *ngIf=\"isSortable && col.isSortable !== false; else noSortHeader\"\n >\n <th\n pSortableColumn=\"{{ col.code }}\"\n [style.width]=\"getHeaderWidth(col)\"\n >\n <div\n class=\"header-container d-flex align-items-center justify-content-between\"\n [style.width]=\"col.width\"\n [style.padding]=\"'0px'\"\n [style.margin]=\"'10px'\"\n >\n <span>{{ col.title }}</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 <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n display=\"menu\"\n [type]=\"getColumnFilterType(col)\"\n *ngIf=\"col.type === TableTypeEnum.COMPOSED\"\n showClearButton=\"false\"\n showApplyButton=\"false\"\n >\n <!-- TableTypeEnum.COMPOSED -->\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 composedName,\n $event.value\n )\n \"\n [placeholder]=\"\n filters[composedName]?.placeholder\n \"\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 <!-- Define itemTemplate here -->\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 TableTypeEnum.XXX -->\n <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n display=\"menu\"\n [type]=\"getColumnFilterType(col)\"\n *ngIf=\"col.type !== TableTypeEnum.COMPOSED\"\n hideOnClear=\"true\"\n >\n <!-- TableTypeEnum.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 <!-- TableTypeEnum.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 <!-- TableTypeEnum.MULTISELECT -->\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"col.type === TableTypeEnum.MULTISELECT\"\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 </th>\n </ng-container>\n <ng-template #noSortHeader>\n <th>\n <div class=\"header-container\">\n <span>{{ col.title }}</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 </th>\n </ng-template>\n </th>\n <!-- Grouped headers -->\n <ng-template #groupHeader>\n <th\n [attr.colspan]=\"col.children?.length\"\n [style.width]=\"getHeaderWidth(col)\"\n [style.text-align]=\"'center'\"\n >\n <span>{{ col.title }}</span>\n </th>\n </ng-template>\n </ng-container>\n </tr>\n <!-- Child headers (Second Row) -->\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]=\"getHeaderWidth(child)\"\n [style.padding]=\"'0px'\"\n >\n <!-- Sortable/Filterable header logic for child columns -->\n </th>\n </ng-container>\n </ng-container>\n </tr>\n </ng-template>\n\n <!-- Empty message template -->\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 <!-- Render a table row and make it editable if `isEdit` is true -->\n <tr *ngIf=\"!loading\" [pEditableRow]=\"isEdit ? data : null\">\n <!-- Loop through each column -->\n <ng-container *ngFor=\"let col of columns\">\n <!-- Check if the column has children -->\n <ng-container *ngIf=\"!col.children; else childColumns\">\n <!-- Render a single cell for columns without children -->\n <ng-container\n *ngIf=\"col.code !== undefined && data[col.code] !== undefined\"\n >\n <td\n *ngIf=\"isEditable(col.code); else normalTD\"\n [style.width]=\"getHeaderWidth(col)\"\n >\n <!-- Editable input for the column -->\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)=\"\n changeHandler(data.id, col.code, $event)\n \"\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\n *ngIf=\"isDatePicker(col.code); else normalInput\"\n >\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 <ng-template #normalTD>\n <td [style.width]=\"getHeaderWidth(col)\">\n <!-- COMPOSED -->\n <ng-container *ngIf=\"col.type === TableTypeEnum.COMPOSED\">\n <div class=\"composed-cell\">\n <ng-container\n *ngFor=\"\n let composedName of col.composedNames;\n let i = index\n \"\n >\n <!-- Check if the composedType is 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]=\"getImageStyle(col.composedStyles?.[composedName])\"\n />\n </ng-container>\n\n <!-- Check if the composedType is 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]=\"getTitleStyle(col.composedStyles?.[composedName])\"\n >\n {{ data[col.code][composedName] }}\n </span>\n </ng-container>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- AMOUNT-->\n <ng-container *ngIf=\"col.type === TableTypeEnum.AMOUNT\">\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 <!-- NUMBER-->\n <ng-container *ngIf=\"col.type === TableTypeEnum.NUMBER\">\n {{\n formatNumber(\n data[col.code],\n col.decimalPlaces,\n col.thousandSeparator,\n col.decimalSeparator\n )\n }}\n </ng-container>\n\n <!-- DATE -->\n <ng-container *ngIf=\"col.type === TableTypeEnum.DATE\">\n <!-- Format the date using your formatDate method -->\n {{ formatDate(data[col.code]) }}\n </ng-container>\n\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 </td>\n </ng-template>\n </ng-container>\n </ng-container>\n\n <!-- Render child columns if the column has children -->\n <ng-template #childColumns>\n <ng-container *ngFor=\"let child of col.children\">\n <ng-container\n *ngIf=\"\n child.code !== undefined && data[child.code] !== undefined\n \"\n >\n <td [style.width]=\"getHeaderWidth(child)\">\n <!-- Render editable or normal cells for child columns -->\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]=\"data[child.code]\"\n (change)=\"onChange($event, data.id, child.code)\"\n />\n </ng-template>\n <ng-template pTemplate=\"output\">\n {{ data[child.code] }}\n </ng-template>\n </p-cellEditor>\n </ng-container>\n\n <ng-template #childNormalTD>\n {{ data[child.code] }}\n </ng-template>\n </td>\n </ng-container>\n </ng-container>\n </ng-template>\n </ng-container>\n\n <!-- Render action buttons if there are any actions defined -->\n <td *ngIf=\"actions?.length\">\n <div class=\"action-buttons-container\">\n <div *ngIf=\"isDelete\">\n <button\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 </div>\n <div>\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 </div>\n </td>\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 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:flex;flex-direction:column;height:100%;overflow:hidden}.pt-advanced-prime-table ::ng-deep .p-datatable{display:flex;flex-direction:column;width:100%;border-collapse:collapse;table-layout:fixed}.pt-advanced-prime-table ::ng-deep .p-datatable thead{display:table;width:100%;table-layout:fixed;background:#fff;z-index:2}.pt-advanced-prime-table ::ng-deep .p-datatable tfoot{display:table;width:100%;table-layout:fixed;background:#fff;z-index:2}.pt-advanced-prime-table ::ng-deep .p-datatable tbody{display:block;overflow-y:auto;overflow-x:hidden}.pt-advanced-prime-table ::ng-deep .p-datatable tbody tr{display:table;width:100%;table-layout:fixed}.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}\n"] }]
435
+ 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\"\n styleClass=\"p-datatable-striped\"\n editMode=\"row\"\n [scrollable]=\"true\"\n [scrollHeight]=\"maxHeight !== null ? maxHeight : undefined\"\n (onFilter)=\"onFilter($event)\"\n (onPage)=\"onPageChange($event)\"\n >\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 <div class=\"ml-auto\" *ngIf=\"hasSearchFilter\">\n <!-- Add this wrapper div with ml-auto class -->\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 <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 [style.width]=\"getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n colspan=\"1\"\n >\n <ng-container\n *ngIf=\"isSortable && col.isSortable !== false; else noSortHeader\"\n >\n <th\n pSortableColumn=\"{{ col.code }}\"\n [style.width]=\"getHeaderWidth(col)\"\n >\n <div\n class=\"header-container d-flex align-items-center justify-content-between\"\n [style.width]=\"col.width\"\n [style.padding]=\"'0px'\"\n [style.margin]=\"'10px'\"\n >\n <span>{{ col.title }}</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 <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n display=\"menu\"\n [type]=\"getColumnFilterType(col)\"\n *ngIf=\"col.type === TableTypeEnum.COMPOSED\"\n showClearButton=\"false\"\n showApplyButton=\"false\"\n >\n <!-- TableTypeEnum.COMPOSED -->\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]=\"\n filters[composedName]?.placeholder\n \"\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 <!-- Define itemTemplate here -->\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 TableTypeEnum.XXX -->\n <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n display=\"menu\"\n [type]=\"getColumnFilterType(col)\"\n *ngIf=\"col.type !== TableTypeEnum.COMPOSED\"\n hideOnClear=\"true\"\n >\n <!-- TableTypeEnum.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 <!-- TableTypeEnum.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 <!-- TableTypeEnum.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 </th>\n </ng-container>\n <ng-template #noSortHeader>\n <th>\n <div class=\"header-container\">\n <span>{{ col.title }}</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 </th>\n </ng-template>\n </th>\n <!-- Grouped headers -->\n <ng-template #groupHeader>\n <th\n [attr.colspan]=\"col.children?.length\"\n [style.width]=\"getHeaderWidth(col)\"\n [style.text-align]=\"'center'\"\n >\n <span>{{ col.title }}</span>\n </th>\n </ng-template>\n </ng-container>\n </tr>\n <!-- Child headers (Second Row) -->\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]=\"getHeaderWidth(child)\"\n [style.padding]=\"'0px'\"\n >\n <!-- Sortable/Filterable header logic for child columns -->\n </th>\n </ng-container>\n </ng-container>\n </tr>\n </ng-template>\n\n <!-- Empty message template -->\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 <!-- Render a table row and make it editable if `isEdit` is true -->\n <tr *ngIf=\"!loading\" [pEditableRow]=\"isEdit ? data : null\">\n <!-- Loop through each column -->\n <ng-container *ngFor=\"let col of columns\">\n <!-- Check if the column has children -->\n <ng-container *ngIf=\"!col.children; else childColumns\">\n <!-- Render a single cell for columns without children -->\n <ng-container\n *ngIf=\"col.code !== undefined && data[col.code] !== undefined\"\n >\n <td\n *ngIf=\"isEditable(col.code); else normalTD\"\n [style.width]=\"getHeaderWidth(col)\"\n >\n <!-- Editable input for the column -->\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)=\"\n changeHandler(data.id, col.code, $event)\n \"\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\n *ngIf=\"isDatePicker(col.code); else normalInput\"\n >\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 <ng-template #normalTD>\n <td [style.width]=\"getHeaderWidth(col)\">\n <!-- COMPOSED -->\n <ng-container *ngIf=\"col.type === TableTypeEnum.COMPOSED\">\n <div class=\"composed-cell\">\n <ng-container\n *ngFor=\"\n let composedName of col.composedNames;\n let i = index\n \"\n >\n <!-- Check if the composedType is 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]=\"getImageStyle(col.composedStyles?.[composedName])\"\n />\n </ng-container>\n\n <!-- Check if the composedType is 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]=\"getTitleStyle(col.composedStyles?.[composedName])\"\n >\n {{ data[col.code][composedName] }}\n </span>\n </ng-container>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- AMOUNT-->\n <ng-container *ngIf=\"col.type === TableTypeEnum.AMOUNT\">\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 <!-- NUMBER-->\n <ng-container *ngIf=\"col.type === TableTypeEnum.NUMBER\">\n {{\n formatNumber(\n data[col.code],\n col.decimalPlaces,\n col.thousandSeparator,\n col.decimalSeparator\n )\n }}\n </ng-container>\n\n <!-- DATE -->\n <ng-container *ngIf=\"col.type === TableTypeEnum.DATE\">\n <!-- Format the date using your formatDate method -->\n {{ formatDate(data[col.code]) }}\n </ng-container>\n\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 </td>\n </ng-template>\n </ng-container>\n </ng-container>\n\n <!-- Render child columns if the column has children -->\n <ng-template #childColumns>\n <ng-container *ngFor=\"let child of col.children\">\n <ng-container\n *ngIf=\"\n child.code !== undefined && data[child.code] !== undefined\n \"\n >\n <td [style.width]=\"getHeaderWidth(child)\">\n <!-- Render editable or normal cells for child columns -->\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]=\"data[child.code]\"\n (change)=\"onChange($event, data.id, child.code)\"\n />\n </ng-template>\n <ng-template pTemplate=\"output\">\n {{ data[child.code] }}\n </ng-template>\n </p-cellEditor>\n </ng-container>\n\n <ng-template #childNormalTD>\n {{ data[child.code] }}\n </ng-template>\n </td>\n </ng-container>\n </ng-container>\n </ng-template>\n </ng-container>\n\n <!-- Render action buttons if there are any actions defined -->\n <td *ngIf=\"actions?.length\">\n <div class=\"action-buttons-container\">\n <div *ngIf=\"isDelete\">\n <button\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 </div>\n <div>\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 </div>\n </td>\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 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:flex;flex-direction:column;height:100%;overflow:hidden}.pt-advanced-prime-table ::ng-deep .p-datatable{display:flex;flex-direction:column;width:100%;border-collapse:collapse;table-layout:fixed}.pt-advanced-prime-table ::ng-deep .p-datatable thead{display:table;width:100%;table-layout:fixed;background:#fff;z-index:2}.pt-advanced-prime-table ::ng-deep .p-datatable tfoot{display:table;width:100%;table-layout:fixed;background:#fff;z-index:2}.pt-advanced-prime-table ::ng-deep .p-datatable tbody{display:block;overflow-y:auto;overflow-x:hidden}.pt-advanced-prime-table ::ng-deep .p-datatable tbody tr{display:table;width:100%;table-layout:fixed}.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}\n"] }]
453
436
  }], ctorParameters: () => [], propDecorators: { data: [{
454
437
  type: Input
455
438
  }], columns: [{
@@ -484,8 +467,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImpo
484
467
  type: Output
485
468
  }], exportPdfEvent: [{
486
469
  type: Output
470
+ }], pageChange: [{
471
+ type: Output
487
472
  }], dt: [{
488
473
  type: ViewChild,
489
474
  args: ['dt', { static: false }]
490
475
  }] } });
491
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHQtYWR2YW5jZWQtcHJpbWUtdGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmctcHJpbWUtdG9vbHMvc3JjL2xpYi9wdC1hZHZhbmNlZC1wcmltZS10YWJsZS9wdC1hZHZhbmNlZC1wcmltZS10YWJsZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1wcmltZS10b29scy9zcmMvbGliL3B0LWFkdmFuY2VkLXByaW1lLXRhYmxlL3B0LWFkdmFuY2VkLXByaW1lLXRhYmxlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFVLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDNUUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUU3QyxPQUFPLEVBR0wsYUFBYSxHQUVkLE1BQU0sa0JBQWtCLENBQUM7QUFDMUIsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7Ozs7Ozs7Ozs7Ozs7OztBQU94RCxNQUFNLE9BQU8sNkJBQTZCO0lBa0R4QztRQWpEQSxTQUFTO1FBQ0EsU0FBSSxHQUFVLEVBQUUsQ0FBQztRQUNqQixZQUFPLEdBQWtCLEVBQUUsQ0FBQztRQUM1QixpQkFBWSxHQUFXLENBQUMsQ0FBQztRQUN6QixnQkFBVyxHQUFhLEVBQUUsQ0FBQztRQUMzQixvQkFBZSxHQUFZLEtBQUssQ0FBQztRQUNqQyxtQkFBYyxHQUFZLEtBQUssQ0FBQztRQUNoQyxpQkFBWSxHQUFZLEtBQUssQ0FBQztRQUM5QixvQkFBZSxHQUFZLEtBQUssQ0FBQztRQUNqQyxnQkFBVyxHQUFZLEtBQUssQ0FBQztRQUM3QixZQUFPLEdBQVUsRUFBRSxDQUFDO1FBQ3BCLGVBQVUsR0FBWSxLQUFLLENBQUM7UUFDNUIsWUFBTyxHQUFZLEtBQUss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Q0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FDMUMsQ0FBQztZQUNGLGVBQWUsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLGdCQUFnQixLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN6RSxDQUFDO1FBRUQsT0FBTyxlQUFlLENBQUM7SUFDekIsQ0FBQzsrR0FwaEJVLDZCQUE2QjttR0FBN0IsNkJBQTZCLHduQkNoQjFDLDB3d0JBb21CQTs7NEZEcGxCYSw2QkFBNkI7a0JBTHpDLFNBQVM7K0JBQ0UseUJBQXlCO3dEQU0xQixJQUFJO3NCQUFaLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUNHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBR0ksTUFBTTtzQkFBZixNQUFNO2dCQUNHLE1BQU07c0JBQWYsTUFBTTtnQkFDRyxnQkFBZ0I7c0JBQXpCLE1BQU07Z0JBQ0csY0FBYztzQkFBdkIsTUFBTTtnQkFFNkIsRUFBRTtzQkFBckMsU0FBUzt1QkFBQyxJQUFJLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT25Jbml0LCBPdXRwdXQsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRXZlbnRFbWl0dGVyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBUYWJsZSB9IGZyb20gJ3ByaW1lbmcvdGFibGUnO1xuaW1wb3J0IHtcbiAgSW1hZ2VTdHlsZSxcbiAgVGFibGVDb2x1bW4sXG4gIFRhYmxlVHlwZUVudW0sXG4gIFRpdGxlU3R5bGUsXG59IGZyb20gJy4uLy4uL3B1YmxpYy1hcGknO1xuaW1wb3J0IHsgY2FsY3VsYXRlVGV4dFdpZHRoIH0gZnJvbSAnLi4vdXRpbHMvdGV4dC51dGlsJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAncHQtYWR2YW5jZWQtcHJpbWUtdGFibGUnLFxuICB0ZW1wbGF0ZVVybDogJy4vcHQtYWR2YW5jZWQtcHJpbWUtdGFibGUuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybDogJy4vcHQtYWR2YW5jZWQtcHJpbWUtdGFibGUuY29tcG9uZW50LmNzcycsXG59KVxuZXhwb3J0IGNsYXNzIFBUQWR2YW5jZWRQcmltZVRhYmxlQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgLy8gSW5wdXRzXG4gIEBJbnB1dCgpIGRhdGE6IGFueVtdID0gW107XG4gIEBJbnB1dCgpIGNvbHVtbnM6IFRhYmxlQ29sdW1uW10gPSBbXTtcbiAgQElucHV0KCkgdG90YWxSZWNvcmRzOiBudW1iZXIgPSAwO1xuICBASW5wdXQoKSByb3dzUGVyUGFnZTogbnVtYmVyW10gPSBbXTtcbiAgQElucHV0KCkgaGFzU2VhcmNoRmlsdGVyOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIGhhc0V4cG9ydEV4Y2VsOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIGhhc0V4cG9ydFBERjogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBoYXNDb2x1bW5GaWx0ZXI6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgaXNQYWdpbmF0ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgYWN0aW9uczogYW55W10gPSBbXTtcbiAgQElucHV0KCkgaXNTb3J0YWJsZTogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBsb2FkaW5nOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIG1heEhlaWdodDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbiAgLy8gT3V0cHV0czogRXZlbnRzIGVtaXR0ZWQgdG8gdGhlIHBhcmVudCBjb21wb25lbnRcbiAgQE91dHB1dCgpIGZpbHRlciA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIHNlYXJjaCA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICBAT3V0cHV0KCkgZXhwb3J0RXhjZWxFdmVudCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgQE91dHB1dCgpIGV4cG9ydFBkZkV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIEBWaWV3Q2hpbGQoJ2R0JywgeyBzdGF0aWM6IGZhbHNlIH0pIGR0ITogVGFibGU7XG5cbiAgcHVibGljIFRhYmxlVHlwZUVudW0gPSBUYWJsZVR5cGVFbnVtO1xuICBzZWFyY2hWYWx1ZTogc3RyaW5nID0gJyc7XG5cbiAgcHVibGljIGZpbHRlcnM6IHsgW2tleTogc3RyaW5nXTogYW55IH0gPSB7fTtcblxuICBwcml2YXRlIHZhbGlkQ3VycmVuY3lDb2RlcyA9IFsnVVNEJywgJ0VVUicsICdNQUQnXTtcbiAgaWNvbldpZHRoID0gNzc7XG5cbiAgLy8gQ29tcG9uZW50IHN0YXRlIHByb3BlcnRpZXNcbiAgaXNEZWxldGU6IGJvb2xlYW4gPSBmYWxzZTtcbiAgaXNFZGl0OiBib29sZWFuID0gZmFsc2U7XG4gIHJvd3M6IG51bWJlciA9IDA7XG5cbiAgLy8gRGF0YSBtYW5hZ2VtZW50IHByb3BlcnRpZXNcbiAgZGF0YU1hcCA9IG5ldyBNYXAoKTtcbiAgbWFwID0gbmV3IE1hcCgpO1xuICBvcHRpb25FbnRyaWVzID0gbmV3IE1hcDxzdHJpbmcsIGFueVtdPigpO1xuICBvcHRpb25WYWx1ZXM6IGFueVtdID0gW107XG4gIGdsb2JhbEZpbHRlckZpZWxkczogc3RyaW5nW10gPSBbXTtcblxuICAvLyBDUlVEIG9wZXJhdGlvbiBoYW5kbGVyc1xuICBEZWxldGU6ICh2YWx1ZTogYW55KSA9PiB2b2lkID0gKCkgPT4ge307XG4gIGluaXRFZGl0YWJsZVJvdzogKGRhdGE6IGFueSkgPT4gdm9pZCA9ICgpID0+IHt9O1xuICBzYXZlRWRpdGFibGVSb3c6IChkYXRhOiBhbnkpID0+IHZvaWQgPSAoKSA9PiB7fTtcbiAgY2FuY2VsRWRpdGFibGVSb3c6IChpdGVtOiBhbnkpID0+IHZvaWQgPSAoKSA9PiB7fTtcbiAgaGFzR3JvdXBlZENvbHVtbnM6IGJvb2xlYW4gPSBmYWxzZTtcbiAgY29uc3RydWN0b3IoKSB7fVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuaGFzR3JvdXBlZENvbHVtbnMgPSB0aGlzLmNvbHVtbnMuc29tZShcbiAgICAgIChjb2wpID0+IGNvbC5jaGlsZHJlbiAmJiBjb2wuY2hpbGRyZW4ubGVuZ3RoID4gMFxuICAgICk7XG5cbiAgICB0aGlzLmdsb2JhbEZpbHRlckZpZWxkcyA9IHRoaXMuY29sdW1uc1xuICAgICAgLmZpbHRlcigoY29sKSA9PiBjb2wuY29kZSAhPT0gdW5kZWZpbmVkICYmIGNvbC5pc0ZpbHRlciAhPT0gZmFsc2UpXG4gICAgICAubWFwKChjb2wpID0+IGNvbC5jb2RlIGFzIHN0cmluZyk7XG4gICAgdGhpcy5pbml0aWFsaXplUGFnaW5hdGlvbigpO1xuICAgIHRoaXMuaW5pdGlhbGl6ZUFjdGlvbnMoKTtcblxuICAgIC8vIFNldCBkZWZhdWx0IHZhbHVlIGZvciBpc1NvcnRhYmxlXG4gICAgdGhpcy5jb2x1bW5zLmZvckVhY2goKGNvbCkgPT4ge1xuICAgICAgaWYgKGNvbC50eXBlID09PSBUYWJsZVR5cGVFbnVtLkFDVElPTikge1xuICAgICAgICBjb2wuaXNFZGl0YWJsZSA9IGZhbHNlO1xuICAgICAgICBjb2wuaXNGaWx0ZXIgPSBmYWxzZTtcbiAgICAgICAgY29sLmlzU29ydGFibGUgPSBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbC50eXBlID09PSBUYWJsZVR5cGVFbnVtLkNPTVBPU0VEKSB7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZUNvbXBvc2VkRmlsdGVycyhjb2wpO1xuICAgICAgfVxuXG4gICAgICBpZiAoY29sLmlzU29ydGFibGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb2wuaXNTb3J0YWJsZSA9IHRydWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb2wuaXNFZGl0YWJsZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbC5pc0VkaXRhYmxlID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbC5pc0ZpbHRlciAhPT0gZmFsc2UgJiYgY29sLmNvZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLmdsb2JhbEZpbHRlckZpZWxkcy5wdXNoKGNvbC5jb2RlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFjb2wud2lkdGgpIHtcbiAgICAgICAgY29sLndpZHRoID0gdGhpcy5jYWxjdWxhdGVDb2x1bW5XaWR0aChjb2wpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gSW5pdGlhbGl6ZSBmaWx0ZXJzIGZvciBjb21wb3NlZCBjb2x1bW5zXG4gIHByaXZhdGUgaW5pdGlhbGl6ZUNvbXBvc2VkRmlsdGVycyhjb2w6IFRhYmxlQ29sdW1uKTogdm9pZCB7XG4gICAgY29sLmNvbXBvc2VkTmFtZXM/LmZvckVhY2goKGNvbXBvc2VkTmFtZSkgPT4ge1xuICAgICAgdGhpcy5nbG9iYWxGaWx0ZXJGaWVsZHMucHVzaChjb2wuY29kZSArICcuJyArIGNvbXBvc2VkTmFtZSk7XG4gICAgICB0aGlzLmZpbHRlcnNbY29tcG9zZWROYW1lXSA9IHtcbiAgICAgICAgb3B0aW9uczogY29sLmZpbHRlck9wdGlvbnMsXG4gICAgICAgIHZhbHVlOiBbXSxcbiAgICAgICAgbGFiZWw6ICdGaWx0ZXIgYnkgJyArIGNvbXBvc2VkTmFtZSxcbiAgICAgICAgcGxhY2Vob2xkZXI6ICdTZWxlY3Qgb3B0aW9ucyBmb3IgJyArIGNvbXBvc2VkTmFtZSxcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICAvLyBHZXQgdGhlIGNvbHVtbiB0eXBlIGZvciBjb21wb3NlZCBmaWVsZHMgKFNUUklORywgSU1BR0UsIGV0Yy4pXG4gIGdldENvbXBvc2VkRmllbGRUeXBlKFxuICAgIGNvbDogVGFibGVDb2x1bW4sXG4gICAgY29tcG9zZWROYW1lOiBzdHJpbmdcbiAgKTogVGFibGVUeXBlRW51bSB8IHVuZGVmaW5lZCB7XG4gICAgLy8gRW5zdXJlIHRoYXQgY29sLmNvbXBvc2VkTmFtZXMgYW5kIGNvbC5jb21wb3NlZFR5cGVzIGFyZSB2YWxpZCBhcnJheXNcbiAgICBpZiAoY29sLmNvbXBvc2VkTmFtZXMgJiYgY29sLmNvbXBvc2VkVHlwZXMpIHtcbiAgICAgIGNvbnN0IGluZGV4ID0gY29sLmNvbXBvc2VkTmFtZXMuaW5kZXhPZihjb21wb3NlZE5hbWUpO1xuXG4gICAgICAvLyBDaGVjayBpZiBpbmRleCBpcyBhIHZhbGlkIG51bWJlciAobm90IC0xKSBhbmQgd2l0aGluIGJvdW5kcyBvZiBjb21wb3NlZFR5cGVzIGFycmF5XG4gICAgICBpZiAoaW5kZXggPj0gMCAmJiBpbmRleCA8IGNvbC5jb21wb3NlZFR5cGVzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gY29sLmNvbXBvc2VkVHlwZXNbaW5kZXhdOyAvLyBTYWZlIGFjY2VzcyBvZiBjb21wb3NlZFR5cGVzIGFycmF5XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDsgLy8gUmV0dXJuIHVuZGVmaW5lZCBpZiBubyB2YWxpZCBpbmRleCBpcyBmb3VuZCBvciBjb21wb3NlZE5hbWVzL2NvbXBvc2VkVHlwZXMgYXJlIG5vdCB2YWxpZFxuICB9XG5cbiAgb25Db21wb3NlZEZpbHRlckNoYW5nZShjb21wb3NlZE5hbWU6IHN0cmluZywgc2VsZWN0ZWRWYWx1ZXM6IGFueSk6IHZvaWQge1xuICAgIGNvbnNvbGUubG9nKCdTZWxlY3RlZCBWYWx1ZXM6Jywgc2VsZWN0ZWRWYWx1ZXMpO1xuICAgIGNvbnNvbGUubG9nKCdEYXRhIEJlZm9yZSBGaWx0ZXJpbmc6JywgdGhpcy5kYXRhKTtcblxuICAgIC8vIFVwZGF0ZSB0aGUgZmlsdGVyIHZhbHVlIHdpdGggdGhlIHNlbGVjdGVkIHZhbHVlc1xuICAgIHRoaXMuZmlsdGVyc1tjb21wb3NlZE5hbWVdLnZhbHVlID0gc2VsZWN0ZWRWYWx1ZXM7XG5cbiAgICAvLyBFbWl0IHRoZSBmaWx0ZXIgZXZlbnQgdG8gbm90aWZ5IHRoZSBwYXJlbnQgY29tcG9uZW50IChpZiBuZWVkZWQpXG4gICAgdGhpcy5maWx0ZXIuZW1pdCh0aGlzLmZpbHRlcnMpO1xuXG4gICAgLy8gR2V0IHRoZSBmaWx0ZXIgdmFsdWUgKGpvaW5pbmcgYXJyYXkgaW50byBhIHN0cmluZylcbiAgICBjb25zdCBmaWx0ZXJWYWx1ZSA9IHNlbGVjdGVkVmFsdWVzLmpvaW4oJywnKTtcbiAgICBjb25zb2xlLmxvZygnRmlsdGVyIFZhbHVlcyB0byBiZSBBcHBsaWVkOicsIGZpbHRlclZhbHVlKTtcblxuICAgIC8vIEFwcGx5IGdsb2JhbCBmaWx0ZXIgdXNpbmcgUHJpbWVORydzIGZpbHRlckdsb2JhbCBtZXRob2RcbiAgICB0aGlzLmR0LmZpbHRlckdsb2JhbChmaWx0ZXJWYWx1ZSwgJ2NvbnRhaW5zJyk7XG4gIH1cblxuICBvbkZpbHRlcihldmVudDogYW55KTogdm9pZCB7XG4gICAgdGhpcy50b3RhbFJlY29yZHMgPSBldmVudC5maWx0ZXJlZFZhbHVlPy5sZW5ndGggfHwgMDtcbiAgfVxuXG4gIG9uQ2FsZW5kYXJGaWx0ZXJDaGFuZ2UoXG4gICAgZXZlbnQ6IGFueSxcbiAgICBjb2x1bW5Db2RlOiBzdHJpbmcsXG4gICAgZmlsdGVyQ2FsbGJhY2s6IGFueVxuICApOiB2b2lkIHtcbiAgICAvLyBMb2cgdGhlIGRhdGEncyBkYXRlIGZvcm1hdCBmb3IgZGVidWdnaW5nXG4gICAgY29uc29sZS5sb2coXG4gICAgICAnRGF0YSBCZWZvcmUgRmlsdGVyaW5nOicsXG4gICAgICB0aGlzLmRhdGEubWFwKChpdGVtKSA9PiBpdGVtW2NvbHVtbkNvZGVdKVxuICAgICk7XG5cbiAgICBjb25zb2xlLmxvZygnZXZlbnQgOiAnICsgZXZlbnQpO1xuXG4gICAgLy8gQ29udmVydCB0aGUgZXZlbnQgdmFsdWUgdG8gYSBzdHJpbmcgKGluIHRoZSBkZXNpcmVkIGRhdGUgZm9ybWF0KVxuXG4gICAgY29uc3QgZmlsdGVyVmFsdWUgPSBldmVudCA/IG5ldyBEYXRlKGV2ZW50KSA6IG51bGw7XG5cbiAgICBjb25zb2xlLmxvZygnZmlsdGVyVmFsdWUgOiAnICsgZmlsdGVyVmFsdWUpO1xuICAgIC8vIElmIHRoZSBmaWx0ZXJWYWx1ZSBpcyBlbXB0eSwgZG8gbm90IHRyaWdnZXIgZmlsdGVyQ2FsbGJhY2tcbiAgICBpZiAoIWZpbHRlclZhbHVlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gTWFudWFsbHkgdHJpZ2dlciB0aGUgZmlsdGVyQ2FsbGJhY2sgYWZ0ZXIgdXBkYXRpbmcgdGhlIHZhbHVlIChwYXNzaW5nIHRoZSBzdHJpbmcgdmFsdWUpXG4gICAgZmlsdGVyQ2FsbGJhY2soZmlsdGVyVmFsdWUpO1xuXG4gICAgY29uc3QgZmlsdGVyVmFsdWVTdHJpbmcgPSBldmVudCA/IHRoaXMuZm9ybWF0RGF0ZShldmVudCkgOiAnJztcbiAgICAvLyBDYWxsIHRoZSBvbkZpbHRlciBldmVudCB0byB1cGRhdGUgdG90YWxSZWNvcmRzXG4gICAgdGhpcy5vbkZpbHRlcih7XG4gICAgICBmaWx0ZXJlZFZhbHVlOiB0aGlzLmRhdGEuZmlsdGVyKChpdGVtKSA9PiB7XG4gICAgICAgIGNvbnN0IGNvbHVtblZhbHVlID0gaXRlbVtjb2x1bW5Db2RlXTtcblxuICAgICAgICAvLyBJZiB0aGUgY29sdW1uIHZhbHVlIGlzIGEgc3RyaW5nLCB1c2UgaXQgYXMgaXMgZm9yIGNvbXBhcmlzb25cbiAgICAgICAgaWYgKGNvbHVtblZhbHVlKSB7XG4gICAgICAgICAgLy8gQ29udmVydCB0aGUgaXRlbSB2YWx1ZSB0byBhIHN0cmluZyAoaW4gdGhlIHNhbWUgZm9ybWF0KVxuICAgICAgICAgIGNvbnN0IGl0ZW1EYXRlU3RyaW5nID0gdGhpcy5mb3JtYXREYXRlKG5ldyBEYXRlKGNvbHVtblZhbHVlKSk7XG4gICAgICAgICAgcmV0dXJuIGl0ZW1EYXRlU3RyaW5nID09PSBmaWx0ZXJWYWx1ZVN0cmluZzsgLy8gQ29tcGFyZSB0aGUgc3RyaW5nIGRhdGVzXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfSksXG4gICAgfSk7XG4gIH1cblxuICAvLyBGaWx0ZXIgbG9naWMgZm9yIGNvbXBvc2VkIGNvbHVtbnMgKHRvIGNoZWNrIGFnYWluc3QgbXVsdGktc2VsZWN0IHZhbHVlcylcbiAgZmlsdGVyQ29tcG9zZWREYXRhKGl0ZW06IGFueSwgY29tcG9zZWROYW1lOiBzdHJpbmcsIHZhbHVlOiBhbnkpOiBib29sZWFuIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkgJiYgdmFsdWUubGVuZ3RoID4gMCkge1xuICAgICAgcmV0dXJuIHZhbHVlLnNvbWUoKGZpbHRlclZhbHVlOiBzdHJpbmcpID0+XG4gICAgICAgIGl0ZW1bY29tcG9zZWROYW1lXT8udG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhmaWx0ZXJWYWx1ZS50b0xvd2VyQ2FzZSgpKVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvLyBGdW5jdGlvbiB0byBjYWxjdWxhdGUgY29sdW1uIHdpZHRoIGJhc2VkIG9uIHRleHQgaW4gaGVhZGVyIGFuZCBkYXRhXG4gIHByaXZhdGUgY2FsY3VsYXRlQ29sdW1uV2lkdGgoY29sOiBUYWJsZUNvbHVtbik6IHN0cmluZyB7XG4gICAgY29uc3QgY2FsY3VsYXRlZFdpZHRoID0gY2FsY3VsYXRlVGV4dFdpZHRoKGNvbCwgY29sLnRpdGxlKTtcbiAgICBjb25zdCB0b3RhbFdpZHRoID0gY2FsY3VsYXRlZFdpZHRoICsgdGhpcy5pY29uV2lkdGggKyAyMDtcbiAgICByZXR1cm4gYCR7dG90YWxXaWR0aH1weGA7XG4gIH1cblxuICBnZXRIZWFkZXJXaWR0aChjb2w6IFRhYmxlQ29sdW1uKTogc3RyaW5nIHtcbiAgICAvLyBSZW1vdmUgJ3B4JyBmcm9tIGNvbC53aWR0aCBhbmQgY29udmVydCBpdCB0byBhIG51bWJlclxuICAgIGNvbnN0IHdpZHRoV2l0aG91dFB4ID0gcGFyc2VJbnQoY29sLndpZHRoPy5yZXBsYWNlKCdweCcsICcnKSB8fCAnMCcsIDEwKTtcblxuICAgIC8vIEFkZCAyMCB0byB0aGUgY2FsY3VsYXRlZCB3aWR0aFxuICAgIGNvbnN0IGhlYWRlcldpZHRoID0gd2lkdGhXaXRob3V0UHggKyAyMDtcblxuICAgIC8vIFJldHVybiB0aGUgbmV3IHdpZHRoIGluICdweCdcbiAgICByZXR1cm4gYCR7aGVhZGVyV2lkdGh9cHhgO1xuICB9XG5cbiAgY2xlYXIodGFibGU6IFRhYmxlKSB7XG4gICAgdGFibGUuY2xlYXIoKTtcbiAgICB0aGlzLnNlYXJjaFZhbHVlID0gJyc7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlRGF0ZShkYXRlU3RyaW5nOiBzdHJpbmcpOiBEYXRlIHwgbnVsbCB7XG4gICAgY29uc3QgcGFydHMgPSBkYXRlU3RyaW5nLnNwbGl0KCcvJyk7XG4gICAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMykge1xuICAgICAgLy8gQXNzdW1pbmcgZGF0ZSBmb3JtYXQgaXMgREQvTU0vWVlZWVxuICAgICAgY29uc3QgZGF5ID0gcGFyc2VJbnQocGFydHNbMF0sIDEwKTtcbiAgICAgIGNvbnN0IG1vbnRoID0gcGFyc2VJbnQocGFydHNbMV0sIDEwKSAtIDE7XG4gICAgICBjb25zdCB5ZWFyID0gcGFyc2VJbnQocGFydHNbMl0sIDEwKTtcbiAgICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSh5ZWFyLCBtb250aCwgZGF5KTtcbiAgICAgIHJldHVybiBpc05hTihkYXRlLmdldFRpbWUoKSkgPyBudWxsIDogZGF0ZTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwcml2YXRlIGluaXRpYWxpemVQYWdpbmF0aW9uKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmlzUGFnaW5hdGVkKSB7XG4gICAgICAvLyBDaGVjayBpZiByb3dzUGVyUGFnZSBpcyB1bmRlZmluZWQgb3IgYW4gZW1wdHkgYXJyYXlcbiAgICAgIGlmICghdGhpcy5yb3dzUGVyUGFnZSB8fCB0aGlzLnJvd3NQZXJQYWdlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aGlzLnJvd3NQZXJQYWdlID0gWzIwLCAzMCwgNDBdO1xuICAgICAgfVxuICAgICAgdGhpcy5yb3dzID0gdGhpcy5yb3dzUGVyUGFnZVswXTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGluaXRpYWxpemVBY3Rpb25zKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmFjdGlvbnMpIHtcbiAgICAgIHRoaXMuYWN0aW9ucy5mb3JFYWNoKChhY3Rpb24pID0+IHtcbiAgICAgICAgc3dpdGNoIChhY3Rpb24uY29kZSkge1xuICAgICAgICAgIGNhc2UgJ2RlbGV0ZSc6XG4gICAgICAgICAgICB0aGlzLmlzRGVsZXRlID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuRGVsZXRlID0gKHZhbHVlOiBhbnkpID0+IGFjdGlvbi5hY3Rpb24odmFsdWUpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnZWRpdCc6XG4gICAgICAgICAgICB0aGlzLmluaXRpYWxpemVFZGl0QWN0aW9ucyhhY3Rpb24pO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRoaXMuaXNEZWxldGUgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuaXNFZGl0ID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaW5pdGlhbGl6ZUVkaXRBY3Rpb25zKGFjdGlvbjogYW55KTogdm9pZCB7XG4gICAgdGhpcy5pc0VkaXQgPSB0cnVlO1xuICAgIHRoaXMuaW5pdEVkaXRhYmxlUm93ID0gKGRhdGE6IGFueSkgPT4gYWN0aW9uLmFjdGlvbi5pbml0KGRhdGEpO1xuICAgIHRoaXMuc2F2ZUVkaXRhYmxlUm93ID0gKGRhdGE6IGFueSkgPT4ge1xuICAgICAgY29uc3QgcmVjb3JkID0gdGhpcy5tYXAuZ2V0KGRhdGEuaWQpO1xuICAgICAgYWN0aW9uLmFjdGlvbi5zYXZlKGRhdGEsIHJlY29yZCk7XG4gICAgICB0aGlzLmRhdGFNYXAuY2xlYXIoKTtcbiAgICB9O1xuICAgIHRoaXMuY2FuY2VsRWRpdGFibGVSb3cgPSAoaXRlbTogYW55KSA9PiBjb25zb2xlLmxvZyhpdGVtKTtcbiAgfVxuXG4gIG9uQ2hhbmdlKGV2ZW50OiBFdmVudCwgaWQ6IG51bWJlciwga2V5OiBhbnkpIHtcbiAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudDtcbiAgICB0aGlzLmNoYW5nZUhhbmRsZXIoaWQsIGtleSwgdGFyZ2V0LnZhbHVlKTtcbiAgfVxuXG4gIGNoYW5nZUhhbmRsZXIoaWQ6IG51bWJlciwga2V5OiBhbnksIHZhbHVlOiBhbnkpIHtcbiAgICBsZXQgY29sdW1uID0gdGhpcy5jb2x1bW5zLmZpbmQoKGl0ZW0pID0+IGl0ZW0uY29kZSA9PT0ga2V5KTtcbiAgICBpZiAoIXRoaXMubWFwLmdldChpZCkpIHtcbiAgICAgIGlmIChjb2x1bW4/LnR5cGUgPT09IFRhYmxlVHlwZUVudW0uREFURSkge1xuICAgICAgICBsZXQgZGF0ZSA9IHRoaXMucGFyc2VEYXRlKHZhbHVlKTtcbiAgICAgICAgdGhpcy5kYXRhTWFwLnNldChrZXksIGRhdGUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5kYXRhTWFwLnNldChrZXksIHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubWFwLnNldChpZCwgbmV3IE1hcCh0aGlzLmRhdGFNYXApKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IG1hcEl0ZW0gPSB0aGlzLm1hcC5nZXQoaWQpO1xuICAgICAgaWYgKGNvbHVtbj8udHlwZSA9PT0gVGFibGVUeXBlRW51bS5EQVRFKSB7XG4gICAgICAgIGxldCBkYXRlID0gdGhpcy5wYXJzZURhdGUodmFsdWUpO1xuICAgICAgICBtYXBJdGVtLnNldChrZXksIGRhdGUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbWFwSXRlbS5zZXQoa2V5LCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ2V0Q29sdW1uRmlsdGVyVHlwZShjb2x1bW46IFRhYmxlQ29sdW1uKTogc3RyaW5nIHtcbiAgICBzd2l0Y2ggKGNvbHVtbi50eXBlKSB7XG4gICAgICBjYXNlIFRhYmxlVHlwZUVudW0uU1RSSU5HOlxuICAgICAgICByZXR1cm4gJ3RleHQnO1xuICAgICAgY2FzZSBUYWJsZVR5cGVFbnVtLkFNT1VOVDpcbiAgICAgIGNhc2UgVGFibGVUeXBlRW51bS5OVU1CRVI6XG4gICAgICAgIHJldHVybiAnbnVtZXJpYyc7XG4gICAgICBjYXNlIFRhYmxlVHlwZUVudW0uREFURTpcbiAgICAgICAgcmV0dXJuICdkYXRlJztcbiAgICAgIGNhc2UgVGFibGVUeXBlRW51bS5NVUxUSVNFTEVDVDpcbiAgICAgICAgcmV0dXJuICdtdWx0aVNlbGVjdCc7XG4gICAgICBjYXNlIFRhYmxlVHlwZUVudW0uQk9PTEVBTjpcbiAgICAgICAgcmV0dXJuICdib29sZWFuJztcbiAgICAgIGNhc2UgVGFibGVUeXBlRW51bS5DT01QT1NFRDpcbiAgICAgICAgcmV0dXJuICdjb21wb3NlZCc7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gJ3RleHQnO1xuICAgIH1cbiAgfVxuXG4gIC8vIFN0YXRlIENoZWNrIE1ldGhvZHNcbiAgaXNFZGl0YWJsZShrZXk6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGxldCBjb2x1bW4gPSB0aGlzLmNvbHVtbnMuZmluZCgoaXRlbSkgPT4gaXRlbS5jb2RlID09PSBrZXkpO1xuICAgIHJldHVybiBjb2x1bW4/LmlzRWRpdGFibGUgIT09IGZhbHNlO1xuICB9XG5cbiAgaXNNdWx0aVNlbGVjdChrZXk6IGFueSk6IGJvb2xlYW4ge1xuICAgIGxldCBjb2x1bW4gPSB0aGlzLmNvbHVtbnMuZmluZCgoaXRlbSkgPT4gaXRlbS5jb2RlID09PSBrZXkpO1xuICAgIGlmIChcbiAgICAgIGNvbHVtbj8udHlwZSA9PT0gVGFibGVUeXBlRW51bS5NVUxUSVNFTEVDVCAmJlxuICAgICAgY29sdW1uLm9wdGlvbnMgJiZcbiAgICAgIGNvbHVtbi5jb2RlICE9PSB1bmRlZmluZWRcbiAgICApIHtcbiAgICAgIHRoaXMub3B0aW9uRW50cmllcyA9IG5ldyBNYXAoW1xuICAgICAgICBbY29sdW1uLmNvZGUsIE9iamVjdC52YWx1ZXMoY29sdW1uLm9wdGlvbnMpXSxcbiAgICAgIF0pO1xuICAgICAgdGhpcy5vcHRpb25WYWx1ZXMgPSB0aGlzLm9wdGlvbkVudHJpZXMuZ2V0KGtleSkgfHwgW107XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaXNEYXRlUGlja2VyKGtleTogYW55KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMuY29sdW1ucy5maW5kKChpdGVtKSA9PiBpdGVtLmNvZGUgPT09IGtleSk/LnR5cGUgPT09XG4gICAgICBUYWJsZVR5cGVFbnVtLkRBVEVcbiAgICApO1xuICB9XG5cbiAgLy8gVXRpbGl0eSBNZXRob2RzXG4gIGRhdGVDb252ZXJ0ZXIodmFsdWU6IGFueSk6IHN0cmluZyB7XG4gICAgcmV0dXJuIG5ldyBEYXRlKHZhbHVlKS50b0xvY2FsZURhdGVTdHJpbmcoJ2VuLVVTJyk7XG4gIH1cblxuICBnZXRDdXJyZW5jeVN5bWJvbChjb2x1bW46IFRhYmxlQ29sdW1uKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gY29sdW1uLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uQU1PVU5UICYmXG4gICAgICBjb2x1bW4uY3VycmVuY3kgJiZcbiAgICAgIHRoaXMuaXNWYWxpZEN1cnJlbmN5Q29kZShjb2x1bW4uY3VycmVuY3kpXG4gICAgICA/IGNvbHVtbi5jdXJyZW5jeVxuICAgICAgOiB1bmRlZmluZWQ7XG4gIH1cblxuICBwcml2YXRlIGlzVmFsaWRDdXJyZW5jeUNvZGUoY3VycmVuY3lDb2RlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy52YWxpZEN1cnJlbmN5Q29kZXMuaW5jbHVkZXMoY3VycmVuY3lDb2RlKTtcbiAgfVxuXG4gIGZpbHRlckdsb2JhbChldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudDtcbiAgICBjb25zdCB2YWx1ZSA9IHRhcmdldC52YWx1ZS50b0xvd2VyQ2FzZSgpO1xuXG4gICAgLy8gQ3JlYXRlIGEgbmV3IGZpbHRlcmVkIGRhdGFzZXRcbiAgICBjb25zdCBmaWx0ZXJlZERhdGEgPSB0aGlzLmRhdGEuZmlsdGVyKChpdGVtKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5nbG9iYWxGaWx0ZXJGaWVsZHMuc29tZSgoZmllbGQpID0+IHtcbiAgICAgICAgY29uc3QgY29sdW1uID0gdGhpcy5jb2x1bW5zLmZpbmQoKGNvbCkgPT4gY29sLmNvZGUgPT09IGZpZWxkKTtcbiAgICAgICAgaWYgKCFjb2x1bW4pIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBIYW5kbGUgZGlmZmVyZW50IGNvbHVtbiB0eXBlc1xuICAgICAgICBpZiAoY29sdW1uLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uREFURSkge1xuICAgICAgICAgIGNvbnN0IGl0ZW1EYXRlID0gdGhpcy5mb3JtYXREYXRlKGl0ZW1bZmllbGRdKTtcbiAgICAgICAgICByZXR1cm4gaXRlbURhdGUgJiYgaXRlbURhdGUuaW5jbHVkZXModmFsdWUpO1xuICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgIGNvbHVtbi50eXBlID09PSBUYWJsZVR5cGVFbnVtLkFNT1VOVCB8fFxuICAgICAgICAgIGNvbHVtbi50eXBlID09PSBUYWJsZVR5cGVFbnVtLk5VTUJFUlxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgaXRlbVtmaWVsZF0gJiYgaXRlbVtmaWVsZF0udG9TdHJpbmcoKS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHZhbHVlKVxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSBpZiAoY29sdW1uLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uQ09NUE9TRUQpIHtcbiAgICAgICAgICAvLyBIYW5kbGUgY29tcG9zZWQgdHlwZSBieSBzZWFyY2hpbmcgZm9yIHRleHQgaW4gdGhlIGNvbXBvc2VkIGNlbGxzXG4gICAgICAgICAgcmV0dXJuIHRoaXMuZmlsdGVyQ29tcG9zZWRDb2x1bW4oaXRlbVtmaWVsZF0sIHZhbHVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgaXRlbVtmaWVsZF0gJiYgaXRlbVtmaWVsZF0udG9TdHJpbmcoKS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHZhbHVlKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgLy8gVXBkYXRlIHRoZSB0YWJsZSdzIHZhbHVlXG4gICAgdGhpcy5kdC52YWx1ZSA9IGZpbHRlcmVkRGF0YTtcblxuICAgIC8vIEFmdGVyIGZpbHRlcmluZywgdXBkYXRlIHRoZSB0b3RhbFJlY29yZHNcbiAgICB0aGlzLnRvdGFsUmVjb3JkcyA9IGZpbHRlcmVkRGF0YS5sZW5ndGggPz8gMDtcbiAgfVxuXG4gIHByaXZhdGUgZmlsdGVyQ29tcG9zZWRDb2x1bW4oY29tcG9zZWREYXRhOiBhbnksIHZhbHVlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBpZiAoY29tcG9zZWREYXRhKSB7XG4gICAgICAvLyBJdGVyYXRlIG92ZXIgY29tcG9zZWQga2V5cyBhbmQgY2hlY2sgaWYgYW55IGtleSdzIHZhbHVlIGNvbnRhaW5zIHRoZSBzZWFyY2ggdGV4dFxuICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKGNvbXBvc2VkRGF0YSkuc29tZSgoa2V5KSA9PiB7XG4gICAgICAgIGNvbnN0IGNlbGxWYWx1ZSA9IGNvbXBvc2VkRGF0YVtrZXldO1xuICAgICAgICBpZiAodHlwZW9mIGNlbGxWYWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICByZXR1cm4gY2VsbFZhbHVlLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXModmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBmb3JtYXREYXRlKGRhdGU6IGFueSk6IHN0cmluZyB7XG4gICAgaWYgKCFkYXRlKSByZXR1cm4gJyc7XG4gICAgaWYgKGRhdGUgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICAvLyBIYW5kbGUgRGF0ZSBvYmplY3RcbiAgICAgIGNvbnN0IGRheSA9IGRhdGUuZ2V0RGF0ZSgpLnRvU3RyaW5nKCkucGFkU3RhcnQoMiwgJzAnKTtcbiAgICAgIGNvbnN0IG1vbnRoID0gKGRhdGUuZ2V0TW9udGgoKSArIDEpLnRvU3RyaW5nKCkucGFkU3RhcnQoMiwgJzAnKTtcbiAgICAgIGNvbnN0IHllYXIgPSBkYXRlLmdldEZ1bGxZZWFyKCkudG9TdHJpbmcoKTtcbiAgICAgIHJldHVybiBgJHtkYXl9LyR7bW9udGh9LyR7eWVhcn1gO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGRhdGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAvLyBIYW5kbGUgc3RyaW5nIGRhdGVcbiAgICAgIGNvbnN0IHBhcnRzID0gZGF0ZS5zcGxpdCgnLycpO1xuICAgICAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMykge1xuICAgICAgICByZXR1cm4gYCR7cGFydHNbMF19LyR7cGFydHNbMV19LyR7cGFydHNbMl19YDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEhhbmRsZSBwYXJ0aWFsIGRhdGVzXG4gICAgICAgIHJldHVybiBkYXRlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICBleHBvcnRFeGNlbCgpIHtcbiAgICB0aGlzLmV4cG9ydEV4Y2VsRXZlbnQuZW1pdCgpO1xuICB9XG5cbiAgZXhwb3J0UGRmKCkge1xuICAgIHRoaXMuZXhwb3J0UGRmRXZlbnQuZW1pdCgpO1xuICB9XG5cbiAgZ2V0SW1hZ2VTdHlsZShzdHlsZTogVGl0bGVTdHlsZSB8IEltYWdlU3R5bGUgfCB1bmRlZmluZWQpOiB7XG4gICAgW2tleTogc3RyaW5nXTogc3RyaW5nO1xuICB9IHtcbiAgICBpZiAoc3R5bGUpIHtcbiAgICAgIGNvbnN0IGltYWdlU3R5bGU6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gPSB7XG4gICAgICAgIHdpZHRoOiAoc3R5bGUgYXMgSW1hZ2VTdHlsZSkud2lkdGggfHwgJ2F1dG8nLFxuICAgICAgICBoZWlnaHQ6IChzdHlsZSBhcyBJbWFnZVN0eWxlKS5oZWlnaHQgfHwgJ2F1dG8nLFxuICAgICAgfTtcblxuICAgICAgLy8gRmFsbGJhY2sgdG8gZW1wdHkgc3RyaW5nIGlmIG1hcmdpbiwgbWFyZ2luTGVmdCwgb3IgbWFyZ2luUmlnaHQgYXJlIHVuZGVmaW5lZFxuICAgICAgaWYgKChzdHlsZSBhcyBJbWFnZVN0eWxlKS5tYXJnaW4pIHtcbiAgICAgICAgaW1hZ2VTdHlsZS5tYXJnaW4gPSAoc3R5bGUgYXMgSW1hZ2VTdHlsZSkubWFyZ2luITtcbiAgICAgIH1cblxuICAgICAgaWYgKChzdHlsZSBhcyBJbWFnZVN0eWxlKS5tYXJnaW5MZWZ0KSB7XG4gICAgICAgIGltYWdlU3R5bGUubWFyZ2luTGVmdCA9IChzdHlsZSBhcyBJbWFnZVN0eWxlKS5tYXJnaW5MZWZ0ITtcbiAgICAgIH1cblxuICAgICAgaWYgKChzdHlsZSBhcyBJbWFnZVN0eWxlKS5tYXJnaW5SaWdodCkge1xuICAgICAgICBpbWFnZVN0eWxlLm1hcmdpblJpZ2h0ID0gKHN0eWxlIGFzIEltYWdlU3R5bGUpLm1hcmdpblJpZ2h0ITtcbiAgICAgIH1cblxuICAgICAgaWYgKChzdHlsZSBhcyBJbWFnZVN0eWxlKS5tYXJnaW5Ub3ApIHtcbiAgICAgICAgaW1hZ2VTdHlsZS5tYXJnaW5Ub3AgPSAoc3R5bGUgYXMgSW1hZ2VTdHlsZSkubWFyZ2luVG9wITtcbiAgICAgIH1cblxuICAgICAgaWYgKChzdHlsZSBhcyBJbWFnZVN0eWxlKS5tYXJnaW5Cb3R0b20pIHtcbiAgICAgICAgaW1hZ2VTdHlsZS5tYXJnaW5Cb3R0b20gPSAoc3R5bGUgYXMgSW1hZ2VTdHlsZSkubWFyZ2luQm90dG9tITtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGltYWdlU3R5bGU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHt9O1xuICB9XG5cbiAgZ2V0VGl0bGVTdHlsZShzdHlsZTogVGl0bGVTdHlsZSB8IEltYWdlU3R5bGUgfCB1bmRlZmluZWQpOiB7XG4gICAgW2tleTogc3RyaW5nXTogc3RyaW5nO1xuICB9IHtcbiAgICBpZiAoc3R5bGUpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbG9yOiBzdHlsZS5jb2xvciB8fCAnaW5oZXJpdCcsXG4gICAgICAgIGZvbnRTaXplOiAoc3R5bGUgYXMgVGl0bGVTdHlsZSkuZm9udFNpemUgfHwgJ2luaGVyaXQnLFxuICAgICAgICB0ZXh0QWxpZ246IChzdHlsZSBhcyBUaXRsZVN0eWxlKS5wb3NpdGlvbiB8fCAnbGVmdCcsXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4ge307XG4gIH1cblxuICBmb3JtYXROdW1iZXIoXG4gICAgdmFsdWU6IG51bWJlcixcbiAgICBkZWNpbWFsUGxhY2VzPzogbnVtYmVyLFxuICAgIHRob3VzYW5kU2VwYXJhdG9yOiAnY29tbWEnIHwgJ3NwYWNlJyA9ICdjb21tYScsXG4gICAgZGVjaW1hbFNlcGFyYXRvcjogJ2NvbW1hJyB8ICdkb3QnID0gJ2RvdCdcbiAgKTogc3RyaW5nIHtcbiAgICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCB8fCBpc05hTih2YWx1ZSkpIHJldHVybiAnJztcblxuICAgIC8vIENvbnZlcnQgdGhlIG51bWJlciB0byBhIHN0cmluZyB3aXRoIGZ1bGwgcHJlY2lzaW9uIGlmIGRlY2ltYWxQbGFjZXMgaXMgdW5kZWZpbmVkXG4gICAgbGV0IGZvcm1hdHRlZE51bWJlciA9XG4gICAgICBkZWNpbWFsUGxhY2VzICE9PSB1bmRlZmluZWRcbiAgICAgICAgPyB2YWx1ZS50b0ZpeGVkKGRlY2ltYWxQbGFjZXMpXG4gICAgICAgIDogdmFsdWUudG9TdHJpbmcoKTtcblxuICAgIC8vIFJlcGxhY2UgZGVjaW1hbCBzZXBhcmF0b3IgKGRlZmF1bHQgaXMgXCJkb3RcIilcbiAgICBpZiAoZGVjaW1hbFNlcGFyYXRvciA9PT0gJ2NvbW1hJykge1xuICAgICAgZm9ybWF0dGVkTnVtYmVyID0gZm9ybWF0dGVkTnVtYmVyLnJlcGxhY2UoJy4nLCAnLCcpO1xuICAgIH1cblxuICAgIC8vIEFwcGx5IHRob3VzYW5kIHNlcGFyYXRvciBvbmx5IGlmIHRoZSBudW1iZXIgaXMgPj0gMTAwMFxuICAgIGlmICh0aG91c2FuZFNlcGFyYXRvciAmJiBNYXRoLmFicyh2YWx1ZSkgPj0gMTAwMCkge1xuICAgICAgY29uc3QgcGFydHMgPSBmb3JtYXR0ZWROdW1iZXIuc3BsaXQoXG4gICAgICAgIGRlY2ltYWxTZXBhcmF0b3IgPT09ICdjb21tYScgPyAnLCcgOiAnLidcbiAgICAgICk7XG4gICAgICBwYXJ0c1swXSA9IHBhcnRzWzBdLnJlcGxhY2UoXG4gICAgICAgIC9cXEIoPz0oXFxkezN9KSsoPyFcXGQpKS9nLFxuICAgICAgICB0aG91c2FuZFNlcGFyYXRvciA9PT0gJ2NvbW1hJyA/ICcsJyA6ICcgJ1xuICAgICAgKTtcbiAgICAgIGZvcm1hdHRlZE51bWJlciA9IHBhcnRzLmpvaW4oZGVjaW1hbFNlcGFyYXRvciA9PT0gJ2NvbW1hJyA/ICcsJyA6ICcuJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZvcm1hdHRlZE51bWJlcjtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cInB0LWFkdmFuY2VkLXByaW1lLXRhYmxlIHRhYmxlLWNvbnRhaW5lclwiPlxuICA8cC10YWJsZVxuICAgICNkdFxuICAgIFt2YWx1ZV09XCJkYXRhXCJcbiAgICBbbG9hZGluZ109XCJsb2FkaW5nXCJcbiAgICBbcm93c109XCJyb3dzXCJcbiAgICBbcGFnaW5hdG9yXT1cImlzUGFnaW5hdGVkXCJcbiAgICBbZ2xvYmFsRmlsdGVyRmllbGRzXT1cImdsb2JhbEZpbHRlckZpZWxkc1wiXG4gICAgW3Jvd3NQZXJQYWdlT3B0aW9uc109XCJyb3dzUGVyUGFnZVwiXG4gICAgZGF0YUtleT1cImlkXCJcbiAgICBzdHlsZUNsYXNzPVwicC1kYXRhdGFibGUtZ3JpZGxpbmVzXCJcbiAgICBzdHlsZUNsYXNzPVwicC1kYXRhdGFibGUtc3RyaXBlZFwiXG4gICAgZWRpdE1vZGU9XCJyb3dcIlxuICAgIFtzY3JvbGxhYmxlXT1cInRydWVcIlxuICAgIFtzY3JvbGxIZWlnaHRdPVwibWF4SGVpZ2h0ICE9PSBudWxsID8gbWF4SGVpZ2h0IDogdW5kZWZpbmVkXCJcbiAgICAob25GaWx0ZXIpPVwib25GaWx0ZXIoJGV2ZW50KVwiXG4gID5cbiAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiY2FwdGlvblwiPlxuICAgICAgPGRpdiBjbGFzcz1cImZsZXhcIj5cbiAgICAgICAgPGRpdj5cbiAgICAgICAgICA8aDM+VG90YWw6IHt7IHRvdGFsUmVjb3JkcyB9fTwvaDM+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXY+XG4gICAgICAgICAgPCEtLSBDbGVhciBmaWx0ZXJzIC0tPlxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICpuZ0lmPVwiaGFzU2VhcmNoRmlsdGVyXCJcbiAgICAgICAgICAgIHBCdXR0b25cbiAgICAgICAgICAgIGljb249XCJwaSBwaS1maWx0ZXItc2xhc2hcIlxuICAgICAgICAgICAgY2xhc3M9XCJwLWJ1dHRvbi1yb3VuZGVkIHAtYnV0dG9uLXRleHRcIlxuICAgICAgICAgICAgKGNsaWNrKT1cImNsZWFyKGR0KVwiXG4gICAgICAgICAgICB0aXRsZT1cIkNsZWFyIGZpbHRlcnNcIlxuICAgICAgICAgID48L2J1dHRvbj5cblxuICAgICAgICAgIDwhLS0gRXhwb3J0IHRvIEV4Y2VsIEJ1dHRvbiAtLT5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAqbmdJZj1cImhhc0V4cG9ydEV4Y2VsXCJcbiAgICAgICAgICAgIHBCdXR0b25cbiAgICAgICAgICAgIGljb249XCJwaSBwaS1maWxlLWV4Y2VsXCJcbiAgICAgICAgICAgIGNsYXNzPVwicC1idXR0b24tcm91bmRlZCBwLWJ1dHRvbi10ZXh0XCJcbiAgICAgICAgICAgIChjbGljayk9XCJleHBvcnRFeGNlbCgpXCJcbiAgICAgICAgICAgIHRpdGxlPVwiRXhwb3J0IHRvIEV4Y2VsXCJcbiAgICAgICAgICA+PC9idXR0b24+XG5cbiAgICAgICAgICA8IS0tIEV4cG9ydCB0byBQREYgQnV0dG9uIC0tPlxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICpuZ0lmPVwiaGFzRXhwb3J0UERGXCJcbiAgICAgICAgICAgIHBCdXR0b25cbiAgICAgICAgICAgIGljb249XCJwaSBwaS1maWxlLXBkZlwiXG4gICAgICAgICAgICBjbGFzcz1cInAtYnV0dG9uLXJvdW5kZWQgcC1idXR0b24tdGV4dFwiXG4gICAgICAgICAgICAoY2xpY2spPVwiZXhwb3J0UGRmKClcIlxuICAgICAgICAgICAgdGl0bGU9XCJFeHBvcnQgdG8gUERGXCJcbiAgICAgICAgICA+PC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwibWwtYXV0b1wiICpuZ0lmPVwiaGFzU2VhcmNoRmlsdGVyXCI+XG4gICAgICAgICAgPCEtLSBBZGQgdGhpcyB3cmFwcGVyIGRpdiB3aXRoIG1sLWF1dG8gY2xhc3MgLS0+XG4gICAgICAgICAgPHAtaWNvbkZpZWxkIGljb25Qb3NpdGlvbj1cImxlZnRcIiBjbGFzcz1cIm1sLWF1dG9cIj5cbiAgICAgICAgICAgIDxwLWlucHV0SWNvbj5cbiAgICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1zZWFyY2hcIj48L2k+XG4gICAgICAgICAgICA8L3AtaW5wdXRJY29uPlxuICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgIHBJbnB1dFRleHRcbiAgICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInNlYXJjaFZhbHVlXCJcbiAgICAgICAgICAgICAgKGlucHV0KT1cImZpbHRlckdsb2JhbCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJTZWFyY2gga2V5d29yZFwiXG4gICAgICAgICAgICAvPlxuICAgICAgICAgIDwvcC1pY29uRmllbGQ+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJoZWFkZXJcIj5cbiAgICAgIDx0ciBjbGFzcz1cInN0aWNreS1oZWFkZXJcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgY29sIG9mIGNvbHVtbnNcIj5cbiAgICAgICAgICA8dGhcbiAgICAgICAgICAgICpuZ0lmPVwiIWNvbC5jaGlsZHJlbjsgZWxzZSBncm91cEhlYWRlclwiXG4gICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiZ2V0SGVhZGVyV2lkdGgoY29sKVwiXG4gICAgICAgICAgICBbc3R5bGUucGFkZGluZ109XCInMHB4J1wiXG4gICAgICAgICAgICBjb2xzcGFuPVwiMVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAqbmdJZj1cImlzU29ydGFibGUgJiYgY29sLmlzU29ydGFibGUgIT09IGZhbHNlOyBlbHNlIG5vU29ydEhlYWRlclwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDx0aFxuICAgICAgICAgICAgICAgIHBTb3J0YWJsZUNvbHVtbj1cInt7IGNvbC5jb2RlIH19XCJcbiAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiZ2V0SGVhZGVyV2lkdGgoY29sKVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICBjbGFzcz1cImhlYWRlci1jb250YWluZXIgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlblwiXG4gICAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiY29sLndpZHRoXCJcbiAgICAgICAgICAgICAgICAgIFtzdHlsZS5wYWRkaW5nXT1cIicwcHgnXCJcbiAgICAgICAgICAgICAgICAgIFtzdHlsZS5tYXJnaW5dPVwiJzEwcHgnXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICA8c3Bhbj57eyBjb2wudGl0bGUgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiaWNvbnMgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiXG4gICAgICAgICAgICAgICAgICAgIFtzdHlsZS53aWR0aF09XCInNzdweCdcIlxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8cC1zb3J0SWNvbiBmaWVsZD1cInt7IGNvbC5jb2RlIH19XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbC5pc0ZpbHRlciAhPT0gZmFsc2VcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8cC1jb2x1bW5GaWx0ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BsYXk9XCJtZW51XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtmaWVsZF09XCJjb2wuY29kZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNwbGF5PVwibWVudVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbdHlwZV09XCJnZXRDb2x1bW5GaWx0ZXJUeXBlKGNvbClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb2wudHlwZSA9PT0gVGFibGVUeXBlRW51bS5DT01QT1NFRFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBzaG93Q2xlYXJCdXR0b249XCJmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBzaG93QXBwbHlCdXR0b249XCJmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBUYWJsZVR5cGVFbnVtLkNPTVBPU0VEIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHBUZW1wbGF0ZT1cImZpbHRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGxldC12YWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQtZmlsdGVyQ2FsbGJhY2s9XCJmaWx0ZXJDYWxsYmFja1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChvbkZpbHRlcik9XCJvbkZpbHRlcigkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgY29tcG9zZWROYW1lIG9mIGNvbC5jb21wb3NlZE5hbWVzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Q29tcG9zZWRGaWVsZFR5cGUoY29sLCBjb21wb3NlZE5hbWUpID09PVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUYWJsZVR5cGVFbnVtLlNUUklOR1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cC1tdWx0aVNlbGVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJmaWx0ZXJzW2NvbXBvc2VkTmFtZV0/LnZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvbnNdPVwiZmlsdGVyc1tjb21wb3NlZE5hbWVdPy5vcHRpb25zXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9uQ2hhbmdlKT1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uQ29tcG9zZWRGaWx0ZXJDaGFuZ2UoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb3NlZE5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZXZlbnQudmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXJzW2NvbXBvc2VkTmFtZV0/LnBsYWNlaG9sZGVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNwbGF5XT1cIidjaGlwJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBsZXQtaXRlbSBwVGVtcGxhdGU9XCJpdGVtXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImN1c3RvbS1tdWx0aXNlbGVjdC1pdGVtXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiaXRlbS5pbWFnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzcmNdPVwiaXRlbS5pbWFnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsdD1cImljb25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZpbHRlci1pbWFnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+e3sgaXRlbS5sYWJlbCB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvcC1tdWx0aVNlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBEZWZpbmUgaXRlbVRlbXBsYXRlIGhlcmUgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBsZXQtaXRlbSBwVGVtcGxhdGU9XCJpdGVtXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImN1c3RvbS1tdWx0aXNlbGVjdC1pdGVtXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiaXRlbS5pbWFnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzcmNdPVwiaXRlbS5pbWFnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsdD1cImljb25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZpbHRlci1pbWFnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+e3sgaXRlbS5sYWJlbCB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgPC9wLWNvbHVtbkZpbHRlcj5cblxuICAgICAgICAgICAgICAgICAgICAgIDwhLS0gb3RoZXIgVGFibGVUeXBlRW51bS5YWFggLS0+XG4gICAgICAgICAgICAgICAgICAgICAgPHAtY29sdW1uRmlsdGVyXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNwbGF5PVwibWVudVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbZmllbGRdPVwiY29sLmNvZGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGxheT1cIm1lbnVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW3R5cGVdPVwiZ2V0Q29sdW1uRmlsdGVyVHlwZShjb2wpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29sLnR5cGUgIT09IFRhYmxlVHlwZUVudW0uQ09NUE9TRURcIlxuICAgICAgICAgICAgICAgICAgICAgICAgaGlkZU9uQ2xlYXI9XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIFRhYmxlVHlwZUVudW0uTlVNQkVSIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHBUZW1wbGF0ZT1cImZpbHRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGxldC12YWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQtZmlsdGVyQ2FsbGJhY2s9XCJmaWx0ZXJDYWxsYmFja1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29sLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uTlVNQkVSXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKG9uRmlsdGVyKT1cIm9uRmlsdGVyKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwSW5wdXRUZXh0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cIm51bWJlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0ZXBdPVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wuZGVjaW1hbFBsYWNlc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/ICcwLicgKyAnMScucGFkRW5kKGNvbC5kZWNpbWFsUGxhY2VzLCAnMCcpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogJ2FueSdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cInZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJmaWx0ZXJDYWxsYmFjaygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ0VudGVyIGEgbnVtYmVyJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIFRhYmxlVHlwZUVudW0uREFURSAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICBwVGVtcGxhdGU9XCJmaWx0ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQtdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0LWZpbHRlckNhbGxiYWNrPVwiZmlsdGVyQ2FsbGJhY2tcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbC50eXBlID09PSBUYWJsZVR5cGVFbnVtLkRBVEVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAob25GaWx0ZXIpPVwib25GaWx0ZXIoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxwLWNhbGVuZGFyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwidmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25DYWxlbmRhckZpbHRlckNoYW5nZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGV2ZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wuY29kZSEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlckNhbGxiYWNrXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGF0ZUZvcm1hdF09XCInZGQvbW0veXknXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ0Nob29zZSBhIGRhdGUnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPjwvcC1jYWxlbmRhcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gVGFibGVUeXBlRW51bS5NVUxUSVNFTEVDVCAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICBwVGVtcGxhdGU9XCJmaWx0ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQtdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0LWZpbHRlckNhbGxiYWNrPVwiZmlsdGVyQ2FsbGJhY2tcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbC50eXBlID09PSBUYWJsZVR5cGVFbnVtLk1VTFRJU0VMRUNUXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKG9uRmlsdGVyKT1cIm9uRmlsdGVyKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8cC1tdWx0aVNlbGVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25zXT1cImNvbC5maWx0ZXJPcHRpb25zXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJ2YWx1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiZmlsdGVyQ2FsbGJhY2soJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc3BsYXldPVwiJ2NoaXAnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ0Nob29zZSBvcHRpb24nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImN1c3RvbS1tdWx0aXNlbGVjdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgID48L3AtbXVsdGlTZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgIDwvcC1jb2x1bW5GaWx0ZXI+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjbm9Tb3J0SGVhZGVyPlxuICAgICAgICAgICAgICA8dGg+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImhlYWRlci1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuPnt7IGNvbC50aXRsZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb2wuaXNGaWx0ZXIgIT09IGZhbHNlXCI+XG4gICAgICAgICAgICAgICAgICAgIDxwLWNvbHVtbkZpbHRlclxuICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29sLnR5cGUgPT09ICdBTU9VTlQnXCJcbiAgICAgICAgICAgICAgICAgICAgICBkaXNwbGF5PVwibWVudVwiXG4gICAgICAgICAgICAgICAgICAgICAgW2ZpZWxkXT1cImNvbC5jb2RlXCJcbiAgICAgICAgICAgICAgICAgICAgICBbdHlwZV09XCJnZXRDb2x1bW5GaWx0ZXJUeXBlKGNvbClcIlxuICAgICAgICAgICAgICAgICAgICAgIFtjdXJyZW5jeV09XCJnZXRDdXJyZW5jeVN5bWJvbChjb2wpXCJcbiAgICAgICAgICAgICAgICAgICAgPjwvcC1jb2x1bW5GaWx0ZXI+XG5cbiAgICAgICAgICAgICAgICAgICAgPHAtY29sdW1uRmlsdGVyXG4gICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb2wudHlwZSAhPT0gJ0FNT1VOVCdcIlxuICAgICAgICAgICAgICAgICAgICAgIGRpc3BsYXk9XCJtZW51XCJcbiAgICAgICAgICAgICAgICAgICAgICBbZmllbGRdPVwiY29sLmNvZGVcIlxuICAgICAgICAgICAgICAgICAgICAgIFt0eXBlXT1cImdldENvbHVtbkZpbHRlclR5cGUoY29sKVwiXG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgIHBUZW1wbGF0ZT1cImZpbHRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQtdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldC1maWx0ZXJDYWxsYmFjaz1cImZpbHRlckNhbGxiYWNrXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiZ2V0Q29sdW1uRmlsdGVyVHlwZShjb2wpID09PSAnZGF0ZSdcIlxuICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxwLWNhbGVuZGFyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cInZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiZmlsdGVyQ2FsbGJhY2soJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtkYXRlRm9ybWF0XT1cIidkZC9tbS95eSdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgPjwvcC1jYWxlbmRhcj5cbiAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICBwVGVtcGxhdGU9XCJmaWx0ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0LXZhbHVlXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQtZmlsdGVyQ2FsbGJhY2s9XCJmaWx0ZXJDYWxsYmFja1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImdldENvbHVtbkZpbHRlclR5cGUoY29sKSA9PT0gJ211bHRpU2VsZWN0J1wiXG4gICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHAtbXVsdGlTZWxlY3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvbnNdPVwiY29sLmZpbHRlck9wdGlvbnNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJ2YWx1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cImZpbHRlckNhbGxiYWNrKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbZGlzcGxheV09XCInY2hpcCdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIlNlbGVjdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY3VzdG9tLW11bHRpc2VsZWN0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgID48L3AtbXVsdGlTZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgPC9wLWNvbHVtbkZpbHRlcj5cbiAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICA8L3RoPlxuICAgICAgICAgIDwhLS0gR3JvdXBlZCBoZWFkZXJzIC0tPlxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZ3JvdXBIZWFkZXI+XG4gICAgICAgICAgICA8dGhcbiAgICAgICAgICAgICAgW2F0dHIuY29sc3Bhbl09XCJjb2wuY2hpbGRyZW4/Lmxlbmd0aFwiXG4gICAgICAgICAgICAgIFtzdHlsZS53aWR0aF09XCJnZXRIZWFkZXJXaWR0aChjb2wpXCJcbiAgICAgICAgICAgICAgW3N0eWxlLnRleHQtYWxpZ25dPVwiJ2NlbnRlcidcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8c3Bhbj57eyBjb2wudGl0bGUgfX08L3NwYW4+XG4gICAgICAgICAgICA8L3RoPlxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPC90cj5cbiAgICAgIDwhLS0gQ2hpbGQgaGVhZGVycyAoU2Vjb25kIFJvdykgLS0+XG4gICAgICA8dHIgKm5nSWY9XCJoYXNHcm91cGVkQ29sdW1uc1wiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBjb2wgb2YgY29sdW1uc1wiPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb2wuY2hpbGRyZW5cIj5cbiAgICAgICAgICAgIDx0aFxuICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgY2hpbGQgb2YgY29sLmNoaWxkcmVuXCJcbiAgICAgICAgICAgICAgW3N0eWxlLndpZHRoXT1cImdldEhlYWRlcldpZHRoKGNoaWxkKVwiXG4gICAgICAgICAgICAgIFtzdHlsZS5wYWRkaW5nXT1cIicwcHgnXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPCEtLSBTb3J0YWJsZS9GaWx0ZXJhYmxlIGhlYWRlciBsb2dpYyBmb3IgY2hpbGQgY29sdW1ucyAtLT5cbiAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPC90cj5cbiAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgPCEtLSBFbXB0eSBtZXNzYWdlIHRlbXBsYXRlIC0tPlxuICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJlbXB0eW1lc3NhZ2VcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJlbXB0eS1tZXNzYWdlXCI+XG4gICAgICAgIDxpIGNsYXNzPVwicGkgcGktaW5mby1jaXJjbGVcIj48L2k+XG4gICAgICAgIDxwPk5vIHJlY29yZHMgYXZhaWxhYmxlIHRvIGRpc3BsYXkuPC9wPlxuICAgICAgPC9kaXY+XG4gICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgIDwhLS0gQm9keSAtLT5cbiAgICA8bmctdGVtcGxhdGVcbiAgICAgIHBUZW1wbGF0ZT1cImJvZHlcIlxuICAgICAgbGV0LWRhdGFcbiAgICAgIGxldC1lZGl0aW5nPVwiZWRpdGluZ1wiXG4gICAgICBsZXQtcmk9XCJyb3dJbmRleFwiXG4gICAgPlxuICAgICAgPCEtLSBSZW5kZXIgYSB0YWJsZSByb3cgYW5kIG1ha2UgaXQgZWRpdGFibGUgaWYgYGlzRWRpdGAgaXMgdHJ1ZSAtLT5cbiAgICAgIDx0ciAqbmdJZj1cIiFsb2FkaW5nXCIgW3BFZGl0YWJsZVJvd109XCJpc0VkaXQgPyBkYXRhIDogbnVsbFwiPlxuICAgICAgICA8IS0tIExvb3AgdGhyb3VnaCBlYWNoIGNvbHVtbiAtLT5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgY29sIG9mIGNvbHVtbnNcIj5cbiAgICAgICAgICA8IS0tIENoZWNrIGlmIHRoZSBjb2x1bW4gaGFzIGNoaWxkcmVuIC0tPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhY29sLmNoaWxkcmVuOyBlbHNlIGNoaWxkQ29sdW1uc1wiPlxuICAgICAgICAgICAgPCEtLSBSZW5kZXIgYSBzaW5nbGUgY2VsbCBmb3IgY29sdW1ucyB3aXRob3V0IGNoaWxkcmVuIC0tPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAqbmdJZj1cImNvbC5jb2RlICE9PSB1bmRlZmluZWQgJiYgZGF0YVtjb2wuY29kZV0gIT09IHVuZGVmaW5lZFwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDx0ZFxuICAgICAgICAgICAgICAgICpuZ0lmPVwiaXNFZGl0YWJsZShjb2wuY29kZSk7IGVsc2Ugbm9ybWFsVERcIlxuICAgICAgICAgICAgICAgIFtzdHlsZS53aWR0aF09XCJnZXRIZWFkZXJXaWR0aChjb2wpXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDwhLS0gRWRpdGFibGUgaW5wdXQgZm9yIHRoZSBjb2x1bW4gLS0+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzTXVsdGlTZWxlY3QoY29sLmNvZGUpOyBlbHNlIGRhdGVQaWNrZXJcIj5cbiAgICAgICAgICAgICAgICAgIDxwLWNlbGxFZGl0b3I+XG4gICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJpbnB1dFwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxwLW11bHRpU2VsZWN0XG4gICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmRUbz1cImJvZHlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwiZGF0YVtjb2wuY29kZV1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlXT1cInsgd2lkdGg6ICcxMDAlJyB9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFuZ2VIYW5kbGVyKGRhdGEuaWQsIGNvbC5jb2RlLCAkZXZlbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvbnNdPVwib3B0aW9uVmFsdWVzXCJcbiAgICAgICAgICAgICAgICAgICAgICA+PC9wLW11bHRpU2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwib3V0cHV0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm11bHRpLXNlbGVjdC1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHJlYyBvZiBkYXRhW2NvbC5jb2RlXVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8cC10YWcgW3ZhbHVlXT1cInJlY1wiPjwvcC10YWc+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgIDwvcC1jZWxsRWRpdG9yPlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNkYXRlUGlja2VyPlxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImlzRGF0ZVBpY2tlcihjb2wuY29kZSk7IGVsc2Ugbm9ybWFsSW5wdXRcIlxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8cC1jZWxsRWRpdG9yPlxuICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJpbnB1dFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHAtY2FsZW5kYXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2lucHV0SWRdPVwiZGF0YVtjb2wuY29kZV1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJkYXRhW2NvbC5jb2RlXVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZUhhbmRsZXIoZGF0YS5pZCwgY29sLmNvZGUsICRldmVudClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2RhdGVGb3JtYXRdPVwiJ2RkL21tL3l5J1wiXG4gICAgICAgICAgICAgICAgICAgICAgICA+PC9wLWNhbGVuZGFyPlxuICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cIm91dHB1dFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge3sgZGF0YVtjb2wuY29kZV0gfCBjdXN0b21EYXRlIH19XG4gICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgPC9wLWNlbGxFZGl0b3I+XG4gICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNub3JtYWxJbnB1dD5cbiAgICAgICAgICAgICAgICAgIDxwLWNlbGxFZGl0b3I+XG4gICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJpbnB1dFwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgcElucHV0VGV4dFxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwiZGF0YVtjb2wuY29kZV1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJvbkNoYW5nZSgkZXZlbnQsIGRhdGEuaWQsIGNvbC5jb2RlKVwiXG4gICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cIm91dHB1dFwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC50eXBlID09PSBUYWJsZVR5cGVFbnVtLkFNT1VOVDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBub3JtYWxPdXRwdXRcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAge3tcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVtjb2wuY29kZV1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGN1c3RvbUN1cnJlbmN5XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGdldEN1cnJlbmN5U3ltYm9sKGNvbClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogY29sLmRlY2ltYWxQbGFjZXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogY29sLnRob3VzYW5kU2VwYXJhdG9yXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGNvbC5kZWNpbWFsU2VwYXJhdG9yXG4gICAgICAgICAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjbm9ybWFsT3V0cHV0PlxuICAgICAgICAgICAgICAgICAgICAgICAge3sgZGF0YVtjb2wuY29kZV0gfX1cbiAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgPC9wLWNlbGxFZGl0b3I+XG4gICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgPC90ZD5cblxuICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI25vcm1hbFREPlxuICAgICAgICAgICAgICAgIDx0ZCBbc3R5bGUud2lkdGhdPVwiZ2V0SGVhZGVyV2lkdGgoY29sKVwiPlxuICAgICAgICAgICAgICAgICAgPCEtLSBDT01QT1NFRCAtLT5cbiAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb2wudHlwZSA9PT0gVGFibGVUeXBlRW51bS5DT01QT1NFRFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29tcG9zZWQtY2VsbFwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0Zvcj1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgY29tcG9zZWROYW1lIG9mIGNvbC5jb21wb3NlZE5hbWVzO1xuICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgaSA9IGluZGV4XG4gICAgICAgICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gQ2hlY2sgaWYgdGhlIGNvbXBvc2VkVHlwZSBpcyBJTUFHRSAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wuY29tcG9zZWRUeXBlcyAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5jb21wb3NlZFR5cGVzW2ldID09PSBUYWJsZVR5cGVFbnVtLklNQUdFXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3JjXT1cImRhdGFbY29sLmNvZGVdW2NvbXBvc2VkTmFtZV1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsdD1cImNvbXBvc2VkLWltZ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjb21wb3NlZC1pbWFnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nU3R5bGVdPVwiZ2V0SW1hZ2VTdHlsZShjb2wuY29tcG9zZWRTdHlsZXM/Lltjb21wb3NlZE5hbWVdKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBDaGVjayBpZiB0aGUgY29tcG9zZWRUeXBlIGlzIFNUUklORyAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wuY29tcG9zZWRUeXBlcyAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5jb21wb3NlZFR5cGVzW2ldID09PSBUYWJsZVR5cGVFbnVtLlNUUklOR1xuICAgICAgICAgICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY29tcG9zZWQtdGV4dFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nU3R5bGVdPVwiZ2V0VGl0bGVTdHlsZShjb2wuY29tcG9zZWRTdHlsZXM/Lltjb21wb3NlZE5hbWVdKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBkYXRhW2NvbC5jb2RlXVtjb21wb3NlZE5hbWVdIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICAgICAgICA8IS0tIEFNT1VOVC0tPlxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbC50eXBlID09PSBUYWJsZVR5cGVFbnVtLkFNT1VOVFwiPlxuICAgICAgICAgICAgICAgICAgICB7e1xuICAgICAgICAgICAgICAgICAgICAgIGRhdGFbY29sLmNvZGVdXG4gICAgICAgICAgICAgICAgICAgICAgICB8IGN1c3RvbUN1cnJlbmN5XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDogZ2V0Q3VycmVuY3lTeW1ib2woY29sKVxuICAgICAgICAgICAgICAgICAgICAgICAgICA6IGNvbC5kZWNpbWFsUGxhY2VzXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDogY29sLnRob3VzYW5kU2VwYXJhdG9yXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDogY29sLmRlY2ltYWxTZXBhcmF0b3JcbiAgICAgICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICAgICAgICA8IS0tIE5VTUJFUi0tPlxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbC50eXBlID09PSBUYWJsZVR5cGVFbnVtLk5VTUJFUlwiPlxuICAgICAgICAgICAgICAgICAgICB7e1xuICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdE51bWJlcihcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFbY29sLmNvZGVdLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29sLmRlY2ltYWxQbGFjZXMsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2wudGhvdXNhbmRTZXBhcmF0b3IsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2wuZGVjaW1hbFNlcGFyYXRvclxuICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICAgICAgICA8IS0tIERBVEUgLS0+XG4gICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29sLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uREFURVwiPlxuICAgICAgICAgICAgICAgICAgICA8IS0tIEZvcm1hdCB0aGUgZGF0ZSB1c2luZyB5b3VyIGZvcm1hdERhdGUgbWV0aG9kIC0tPlxuICAgICAgICAgICAgICAgICAgICB7eyBmb3JtYXREYXRlKGRhdGFbY29sLmNvZGVdKSB9fVxuICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgICAgIDwhLS0gU1RSSU5HLCBNVUxUSVNFTEVDVC0tPlxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgICAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICAgICAgICAgIFRhYmxlVHlwZUVudW0uU1RSSU5HLFxuICAgICAgICAgICAgICAgICAgICAgICAgVGFibGVUeXBlRW51bS5NVUxUSVNFTEVDVFxuICAgICAgICAgICAgICAgICAgICAgIF0uaW5jbHVkZXMoY29sLnR5cGUhKVxuICAgICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICB7eyBkYXRhW2NvbC5jb2RlXSB9fVxuICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgPCEtLSBSZW5kZXIgY2hpbGQgY29sdW1ucyBpZiB0aGUgY29sdW1uIGhhcyBjaGlsZHJlbiAtLT5cbiAgICAgICAgICA8bmctdGVtcGxhdGUgI2NoaWxkQ29sdW1ucz5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGNoaWxkIG9mIGNvbC5jaGlsZHJlblwiPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJcbiAgICAgICAgICAgICAgICAgIGNoaWxkLmNvZGUgIT09IHVuZGVmaW5lZCAmJiBkYXRhW2NoaWxkLmNvZGVdICE9PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPHRkIFtzdHlsZS53aWR0aF09XCJnZXRIZWFkZXJXaWR0aChjaGlsZClcIj5cbiAgICAgICAgICAgICAgICAgIDwhLS0gUmVuZGVyIGVkaXRhYmxlIG9yIG5vcm1hbCBjZWxscyBmb3IgY2hpbGQgY29sdW1ucyAtLT5cbiAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJpc0VkaXRhYmxlKGNoaWxkLmNvZGUpOyBlbHNlIGNoaWxkTm9ybWFsVERcIlxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8cC1jZWxsRWRpdG9yPlxuICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJpbnB1dFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHBJbnB1dFRleHRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJkYXRhW2NoaWxkLmNvZGVdXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJvbkNoYW5nZSgkZXZlbnQsIGRhdGEuaWQsIGNoaWxkLmNvZGUpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwib3V0cHV0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICB7eyBkYXRhW2NoaWxkLmNvZGVdIH19XG4gICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgPC9wLWNlbGxFZGl0b3I+XG4gICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNjaGlsZE5vcm1hbFREPlxuICAgICAgICAgICAgICAgICAgICB7eyBkYXRhW2NoaWxkLmNvZGVdIH19XG4gICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPCEtLSBSZW5kZXIgYWN0aW9uIGJ1dHRvbnMgaWYgdGhlcmUgYXJlIGFueSBhY3Rpb25zIGRlZmluZWQgLS0+XG4gICAgICAgIDx0ZCAqbmdJZj1cImFjdGlvbnM/Lmxlbmd0aFwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJhY3Rpb24tYnV0dG9ucy1jb250YWluZXJcIj5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJpc0RlbGV0ZVwiPlxuICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgcEJ1dHRvblxuICAgICAgICAgICAgICAgIHBSaXBwbGVcbiAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICBpY29uPVwicGkgcGktdHJhc2hcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJEZWxldGUoZGF0YS5pZClcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwicC1idXR0b24tcm91bmRlZCBwLWJ1dHRvbi10ZXh0XCJcbiAgICAgICAgICAgICAgPjwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgcEluaXRFZGl0YWJsZVJvd1xuICAgICAgICAgICAgICAgICpuZ0lmPVwiIWVkaXRpbmdcIlxuICAgICAgICAgICAgICAgIHBCdXR0b25cbiAgICAgICAgICAgICAgICBwUmlwcGxlXG4gICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgaWNvbj1cInBpIHBpLXBlbmNpbFwiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cImluaXRFZGl0YWJsZVJvdyhkYXRhKVwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJwLWJ1dHRvbi1yb3VuZGVkIHAtYnV0dG9uLXRleHRcIlxuICAgICAgICAgICAgICA+PC9idXR0b24+XG4gICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAqbmdJZj1cImVkaXRpbmdcIlxuICAgICAgICAgICAgICAgIHBTYXZlRWRpdGFibGVSb3dcbiAgICAgICAgICAgICAgICBwQnV0dG9uXG4gICAgICAgICAgICAgICAgcFJpcHBsZVxuICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgIGljb249XCJwaSBwaS1jaGVja1wiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cInNhdmVFZGl0YWJsZVJvdyhkYXRhKVwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJwLWJ1dHRvbi1yb3VuZGVkIHAtYnV0dG9uLXRleHRcIlxuICAgICAgICAgICAgICA+PC9idXR0b24+XG4gICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAqbmdJZj1cImVkaXRpbmdcIlxuICAgICAgICAgICAgICAgIHBDYW5jZWxFZGl0YWJsZVJvd1xuICAgICAgICAgICAgICAgIHBCdXR0b25cbiAgICAgICAgICAgICAgICBwUmlwcGxlXG4gICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgaWNvbj1cInBpIHBpLXRpbWVzXCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwiY2FuY2VsRWRpdGFibGVSb3coZGF0YSlcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwicC1idXR0b24tcm91bmRlZCBwLWJ1dHRvbi10ZXh0XCJcbiAgICAgICAgICAgICAgPjwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvdGQ+XG4gICAgICA8L3RyPlxuICAgIDwvbmctdGVtcGxhdGU+XG4gIDwvcC10YWJsZT5cbjwvZGl2PlxuIl19
476
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHQtYWR2YW5jZWQtcHJpbWUtdGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmctcHJpbWUtdG9vbHMvc3JjL2xpYi9wdC1hZHZhbmNlZC1wcmltZS10YWJsZS9wdC1hZHZhbmNlZC1wcmltZS10YWJsZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1wcmltZS10b29scy9zcmMvbGliL3B0LWFkdmFuY2VkLXByaW1lLXRhYmxlL3B0LWFkdmFuY2VkLXByaW1lLXRhYmxlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFVLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDNUUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUU3QyxPQUFPLEVBR0wsYUFBYSxHQUVkLE1BQU0sa0JBQWtCLENBQUM7QUFDMUIsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7Ozs7Ozs7Ozs7Ozs7OztBQU94RCxNQUFNLE9BQU8sNkJBQTZCO0lBb0R4QztRQW5EQSxTQUFTO1FBQ0EsU0FBSSxHQUFVLEVBQUUsQ0FBQztRQUNqQixZQUFPLEdBQWtCLEVBQUUsQ0FBQztRQUM1QixpQkFBWSxHQUFXLENBQUMsQ0FBQztRQUN6QixnQkFBVyxHQUFhLEVBQUUsQ0FBQztRQUMzQixvQkFBZSxHQUFZLEtBQUssQ0FBQztRQUNqQyxtQkFBYyxHQUFZLEtBQUssQ0FBQztRQUNoQyxpQkFBWSxHQUFZLEtBQUssQ0FBQztRQUM5QixvQkFBZSxHQUFZLEtBQUssQ0FBQztRQUNqQyxnQkFBVyxHQUFZLEtBQUssQ0FBQztRQUM3QixZQUFPLEdBQVUsRUFBRSxDQUFDO1FBQ3BCLGVBQVUsR0FBWSxLQUFLLENBQUM7UUFDNUIsWUFBTyxHQUFZLEtBQUss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QUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FDekIsdUJBQXVCLEVBQ3ZCLGlCQUFpQixLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQzFDLENBQUM7WUFDRixlQUFlLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsS0FBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDekUsQ0FBQztRQUVELE9BQU8sZUFBZSxDQUFDO0lBQ3pCLENBQUM7K0dBM2ZVLDZCQUE2QjttR0FBN0IsNkJBQTZCLGtwQkNoQjFDLDhqeEJBNG1CQTs7NEZENWxCYSw2QkFBNkI7a0JBTHpDLFNBQVM7K0JBQ0UseUJBQXlCO3dEQU0xQixJQUFJO3NCQUFaLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUNHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBR0ksTUFBTTtzQkFBZixNQUFNO2dCQUNHLE1BQU07c0JBQWYsTUFBTTtnQkFDRyxnQkFBZ0I7c0JBQXpCLE1BQU07Z0JBQ0csY0FBYztzQkFBdkIsTUFBTTtnQkFDRyxVQUFVO3NCQUFuQixNQUFNO2dCQUU2QixFQUFFO3NCQUFyQyxTQUFTO3VCQUFDLElBQUksRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPbkluaXQsIE91dHB1dCwgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBFdmVudEVtaXR0ZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFRhYmxlIH0gZnJvbSAncHJpbWVuZy90YWJsZSc7XG5pbXBvcnQge1xuICBJbWFnZVN0eWxlLFxuICBUYWJsZUNvbHVtbixcbiAgVGFibGVUeXBlRW51bSxcbiAgVGl0bGVTdHlsZSxcbn0gZnJvbSAnLi4vLi4vcHVibGljLWFwaSc7XG5pbXBvcnQgeyBjYWxjdWxhdGVUZXh0V2lkdGggfSBmcm9tICcuLi91dGlscy90ZXh0LnV0aWwnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdwdC1hZHZhbmNlZC1wcmltZS10YWJsZScsXG4gIHRlbXBsYXRlVXJsOiAnLi9wdC1hZHZhbmNlZC1wcmltZS10YWJsZS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsOiAnLi9wdC1hZHZhbmNlZC1wcmltZS10YWJsZS5jb21wb25lbnQuY3NzJyxcbn0pXG5leHBvcnQgY2xhc3MgUFRBZHZhbmNlZFByaW1lVGFibGVDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICAvLyBJbnB1dHNcbiAgQElucHV0KCkgZGF0YTogYW55W10gPSBbXTtcbiAgQElucHV0KCkgY29sdW1uczogVGFibGVDb2x1bW5bXSA9IFtdO1xuICBASW5wdXQoKSB0b3RhbFJlY29yZHM6IG51bWJlciA9IDA7XG4gIEBJbnB1dCgpIHJvd3NQZXJQYWdlOiBudW1iZXJbXSA9IFtdO1xuICBASW5wdXQoKSBoYXNTZWFyY2hGaWx0ZXI6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgaGFzRXhwb3J0RXhjZWw6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgaGFzRXhwb3J0UERGOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIGhhc0NvbHVtbkZpbHRlcjogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBpc1BhZ2luYXRlZDogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBhY3Rpb25zOiBhbnlbXSA9IFtdO1xuICBASW5wdXQoKSBpc1NvcnRhYmxlOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIGxvYWRpbmc6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgbWF4SGVpZ2h0OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxuICAvLyBPdXRwdXRzOiBFdmVudHMgZW1pdHRlZCB0byB0aGUgcGFyZW50IGNvbXBvbmVudFxuICBAT3V0cHV0KCkgZmlsdGVyID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgc2VhcmNoID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gIEBPdXRwdXQoKSBleHBvcnRFeGNlbEV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICBAT3V0cHV0KCkgZXhwb3J0UGRmRXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIEBPdXRwdXQoKSBwYWdlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjx7IHBhZ2U6IG51bWJlcjsgcm93czogbnVtYmVyIH0+KCk7XG5cbiAgQFZpZXdDaGlsZCgnZHQnLCB7IHN0YXRpYzogZmFsc2UgfSkgZHQhOiBUYWJsZTtcblxuICBwdWJsaWMgVGFibGVUeXBlRW51bSA9IFRhYmxlVHlwZUVudW07XG4gIHNlYXJjaFZhbHVlOiBzdHJpbmcgPSAnJztcblxuICBwdWJsaWMgZmlsdGVyczogeyBba2V5OiBzdHJpbmddOiBhbnkgfSA9IHt9O1xuXG4gIHByaXZhdGUgdmFsaWRDdXJyZW5jeUNvZGVzID0gWydVU0QnLCAnRVVSJywgJ01BRCddO1xuICBpY29uV2lkdGggPSA3NztcblxuICAvLyBDb21wb25lbnQgc3RhdGUgcHJvcGVydGllc1xuICBpc0RlbGV0ZTogYm9vbGVhbiA9IGZhbHNlO1xuICBpc0VkaXQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgcm93czogbnVtYmVyID0gMDtcblxuICAvLyBEYXRhIG1hbmFnZW1lbnQgcHJvcGVydGllc1xuICBkYXRhTWFwID0gbmV3IE1hcCgpO1xuICBtYXAgPSBuZXcgTWFwKCk7XG4gIG9wdGlvbkVudHJpZXMgPSBuZXcgTWFwPHN0cmluZywgYW55W10+KCk7XG4gIG9wdGlvblZhbHVlczogYW55W10gPSBbXTtcbiAgZ2xvYmFsRmlsdGVyRmllbGRzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIC8vIENSVUQgb3BlcmF0aW9uIGhhbmRsZXJzXG4gIERlbGV0ZTogKHZhbHVlOiBhbnkpID0+IHZvaWQgPSAoKSA9PiB7fTtcbiAgaW5pdEVkaXRhYmxlUm93OiAoZGF0YTogYW55KSA9PiB2b2lkID0gKCkgPT4ge307XG4gIHNhdmVFZGl0YWJsZVJvdzogKGRhdGE6IGFueSkgPT4gdm9pZCA9ICgpID0+IHt9O1xuICBjYW5jZWxFZGl0YWJsZVJvdzogKGl0ZW06IGFueSkgPT4gdm9pZCA9ICgpID0+IHt9O1xuICBoYXNHcm91cGVkQ29sdW1uczogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIGNvbnN0cnVjdG9yKCkge31cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICBjb25zb2xlLmxvZygnUFRBZHZhbmNlZFByaW1lVGFibGUgY29sdW1uczonLCB0aGlzLmNvbHVtbnMpO1xuICAgIGNvbnNvbGUubG9nKCdQVEFkdmFuY2VkUHJpbWVUYWJsZSB0b3RhbFJlY29yZHMgaW5wdXQ6JywgdGhpcy50b3RhbFJlY29yZHMpO1xuXG4gICAgdGhpcy5oYXNHcm91cGVkQ29sdW1ucyA9IHRoaXMuY29sdW1ucy5zb21lKFxuICAgICAgKGNvbCkgPT4gY29sLmNoaWxkcmVuICYmIGNvbC5jaGlsZHJlbi5sZW5ndGggPiAwXG4gICAgKTtcblxuICAgIHRoaXMuZ2xvYmFsRmlsdGVyRmllbGRzID0gdGhpcy5jb2x1bW5zXG4gICAgICAuZmlsdGVyKChjb2wpID0+IGNvbC5jb2RlICE9PSB1bmRlZmluZWQgJiYgY29sLmlzRmlsdGVyICE9PSBmYWxzZSlcbiAgICAgIC5tYXAoKGNvbCkgPT4gY29sLmNvZGUgYXMgc3RyaW5nKTtcblxuICAgIHRoaXMuaW5pdGlhbGl6ZVBhZ2luYXRpb24oKTtcbiAgICB0aGlzLmluaXRpYWxpemVBY3Rpb25zKCk7XG5cbiAgICAvLyBTZXQgZGVmYXVsdCB2YWx1ZSBmb3IgaXNTb3J0YWJsZSAvIGlzRWRpdGFibGUgKyB3aWR0aHNcbiAgICB0aGlzLmNvbHVtbnMuZm9yRWFjaCgoY29sKSA9PiB7XG4gICAgICBpZiAoY29sLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uQUNUSU9OKSB7XG4gICAgICAgIGNvbC5pc0VkaXRhYmxlID0gZmFsc2U7XG4gICAgICAgIGNvbC5pc0ZpbHRlciA9IGZhbHNlO1xuICAgICAgICBjb2wuaXNTb3J0YWJsZSA9IGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBpZiAoY29sLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uQ09NUE9TRUQpIHtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplQ29tcG9zZWRGaWx0ZXJzKGNvbCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb2wuaXNTb3J0YWJsZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbC5pc1NvcnRhYmxlID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbC5pc0VkaXRhYmxlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29sLmlzRWRpdGFibGUgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoY29sLmlzRmlsdGVyICE9PSBmYWxzZSAmJiBjb2wuY29kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuZ2xvYmFsRmlsdGVyRmllbGRzLnB1c2goY29sLmNvZGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWNvbC53aWR0aCkge1xuICAgICAgICBjb2wud2lkdGggPSB0aGlzLmNhbGN1bGF0ZUNvbHVtbldpZHRoKGNvbCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBJbml0aWFsaXplIGZpbHRlcnMgZm9yIGNvbXBvc2VkIGNvbHVtbnNcbiAgcHJpdmF0ZSBpbml0aWFsaXplQ29tcG9zZWRGaWx0ZXJzKGNvbDogVGFibGVDb2x1bW4pOiB2b2lkIHtcbiAgICBjb2wuY29tcG9zZWROYW1lcz8uZm9yRWFjaCgoY29tcG9zZWROYW1lKSA9PiB7XG4gICAgICB0aGlzLmdsb2JhbEZpbHRlckZpZWxkcy5wdXNoKGNvbC5jb2RlICsgJy4nICsgY29tcG9zZWROYW1lKTtcbiAgICAgIHRoaXMuZmlsdGVyc1tjb21wb3NlZE5hbWVdID0ge1xuICAgICAgICBvcHRpb25zOiBjb2wuZmlsdGVyT3B0aW9ucyxcbiAgICAgICAgdmFsdWU6IFtdLFxuICAgICAgICBsYWJlbDogJ0ZpbHRlciBieSAnICsgY29tcG9zZWROYW1lLFxuICAgICAgICBwbGFjZWhvbGRlcjogJ1NlbGVjdCBvcHRpb24nLFxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIEdldCB0aGUgY29sdW1uIHR5cGUgZm9yIGNvbXBvc2VkIGZpZWxkcyAoU1RSSU5HLCBJTUFHRSwgZXRjLilcbiAgZ2V0Q29tcG9zZWRGaWVsZFR5cGUoXG4gICAgY29sOiBUYWJsZUNvbHVtbixcbiAgICBjb21wb3NlZE5hbWU6IHN0cmluZ1xuICApOiBUYWJsZVR5cGVFbnVtIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoY29sLmNvbXBvc2VkTmFtZXMgJiYgY29sLmNvbXBvc2VkVHlwZXMpIHtcbiAgICAgIGNvbnN0IGluZGV4ID0gY29sLmNvbXBvc2VkTmFtZXMuaW5kZXhPZihjb21wb3NlZE5hbWUpO1xuICAgICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCBjb2wuY29tcG9zZWRUeXBlcy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIGNvbC5jb21wb3NlZFR5cGVzW2luZGV4XTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIG9uQ29tcG9zZWRGaWx0ZXJDaGFuZ2UoXG4gICAgY29sOiBUYWJsZUNvbHVtbixcbiAgICBjb21wb3NlZE5hbWU6IHN0cmluZyxcbiAgICBzZWxlY3RlZFZhbHVlczogYW55XG4gICk6IHZvaWQge1xuICAgIHRoaXMuZmlsdGVyc1tjb21wb3NlZE5hbWVdLnZhbHVlID0gc2VsZWN0ZWRWYWx1ZXM7XG4gICAgdGhpcy5maWx0ZXIuZW1pdCh0aGlzLmZpbHRlcnMpO1xuXG4gICAgY29uc3QgZmlsdGVyVmFsdWUgPSBzZWxlY3RlZFZhbHVlcy5qb2luKCcsJyk7XG4gICAgbGV0IG1hdGNoUmVzdWx0czogYW55W10gPSBbXTtcblxuICAgIHNlbGVjdGVkVmFsdWVzLmZvckVhY2goKHZhbHVlOiBhbnkpID0+IHtcbiAgICAgIGNvbnN0IG1hdGNoZXMgPSB0aGlzLmR0LnZhbHVlLmZpbHRlcigocm93KSA9PiB7XG4gICAgICAgIHJldHVybiByb3dbY29sLmNvZGUhXT8uW2NvbXBvc2VkTmFtZV1cbiAgICAgICAgICA/LnRvU3RyaW5nKClcbiAgICAgICAgICAudG9Mb3dlckNhc2UoKVxuICAgICAgICAgIC5pbmNsdWRlcyh2YWx1ZS50b0xvd2VyQ2FzZSgpKTtcbiAgICAgIH0pO1xuICAgICAgbWF0Y2hSZXN1bHRzID0gWy4uLm1hdGNoUmVzdWx0cywgLi4ubWF0Y2hlc107XG4gICAgfSk7XG5cbiAgICBtYXRjaFJlc3VsdHMgPSBBcnJheS5mcm9tKG5ldyBTZXQobWF0Y2hSZXN1bHRzKSk7XG4gICAgdGhpcy5kdC5maWx0ZXJlZFZhbHVlID0gbWF0Y2hSZXN1bHRzO1xuICAgIHRoaXMuZHQuZmlsdGVyR2xvYmFsKGZpbHRlclZhbHVlLCAnY29udGFpbnMnKTtcbiAgfVxuXG4gIC8vIOKblCBEb24ndCBvdmVycmlkZSB0b3RhbFJlY29yZHMgaGVyZSDigJMgd2UgYXJlIGluIHNlcnZlci1zaWRlIG1vZGVcbiAgb25GaWx0ZXIoZXZlbnQ6IGFueSk6IHZvaWQge1xuICAgIHRoaXMuZmlsdGVyLmVtaXQoZXZlbnQpO1xuICAgIC8vIHRoaXMudG90YWxSZWNvcmRzID0gZXZlbnQuZmlsdGVyZWRWYWx1ZT8ubGVuZ3RoIHx8IDA7ICAvLyByZW1vdmVkXG4gIH1cblxuICBvblBhZ2VDaGFuZ2UoZXZlbnQ6IGFueSk6IHZvaWQge1xuICAgIGNvbnN0IHBhZ2UgPSBldmVudC5wYWdlID8/IE1hdGguZmxvb3IoKGV2ZW50LmZpcnN0IHx8IDApIC8gZXZlbnQucm93cyk7XG4gICAgY29uc3Qgcm93cyA9IGV2ZW50LnJvd3M7XG5cbiAgICB0aGlzLnJvd3MgPSByb3dzO1xuICAgIHRoaXMucGFnZUNoYW5nZS5lbWl0KHsgcGFnZSwgcm93cyB9KTtcbiAgfVxuXG4gIG9uQ2FsZW5kYXJGaWx0ZXJDaGFuZ2UoXG4gICAgZXZlbnQ6IGFueSxcbiAgICBjb2x1bW5Db2RlOiBzdHJpbmcsXG4gICAgZmlsdGVyQ2FsbGJhY2s6IGFueVxuICApOiB2b2lkIHtcbiAgICBjb25zdCBmaWx0ZXJWYWx1ZSA9IGV2ZW50ID8gbmV3IERhdGUoZXZlbnQpIDogbnVsbDtcbiAgICBpZiAoIWZpbHRlclZhbHVlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZmlsdGVyQ2FsbGJhY2soZmlsdGVyVmFsdWUpO1xuXG4gICAgY29uc3QgZmlsdGVyVmFsdWVTdHJpbmcgPSBldmVudCA/IHRoaXMuZm9ybWF0RGF0ZShldmVudCkgOiAnJztcbiAgICB0aGlzLm9uRmlsdGVyKHtcbiAgICAgIGZpbHRlcmVkVmFsdWU6IHRoaXMuZGF0YS5maWx0ZXIoKGl0ZW0pID0+IHtcbiAgICAgICAgY29uc3QgY29sdW1uVmFsdWUgPSBpdGVtW2NvbHVtbkNvZGVdO1xuICAgICAgICBpZiAoY29sdW1uVmFsdWUpIHtcbiAgICAgICAgICBjb25zdCBpdGVtRGF0ZVN0cmluZyA9IHRoaXMuZm9ybWF0RGF0ZShuZXcgRGF0ZShjb2x1bW5WYWx1ZSkpO1xuICAgICAgICAgIHJldHVybiBpdGVtRGF0ZVN0cmluZyA9PT0gZmlsdGVyVmFsdWVTdHJpbmc7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfSksXG4gICAgfSk7XG4gIH1cblxuICBmaWx0ZXJDb21wb3NlZERhdGEoaXRlbTogYW55LCBjb21wb3NlZE5hbWU6IHN0cmluZywgdmFsdWU6IGFueSk6IGJvb2xlYW4ge1xuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSAmJiB2YWx1ZS5sZW5ndGggPiAwKSB7XG4gICAgICByZXR1cm4gdmFsdWUuc29tZSgoZmlsdGVyVmFsdWU6IHN0cmluZykgPT5cbiAgICAgICAgaXRlbVtjb21wb3NlZE5hbWVdPy50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKGZpbHRlclZhbHVlLnRvTG93ZXJDYXNlKCkpXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHByaXZhdGUgY2FsY3VsYXRlQ29sdW1uV2lkdGgoY29sOiBUYWJsZUNvbHVtbik6IHN0cmluZyB7XG4gICAgY29uc3QgY2FsY3VsYXRlZFdpZHRoID0gY2FsY3VsYXRlVGV4dFdpZHRoKGNvbCwgY29sLnRpdGxlKTtcbiAgICBjb25zdCB0b3RhbFdpZHRoID0gY2FsY3VsYXRlZFdpZHRoICsgdGhpcy5pY29uV2lkdGggKyAyMDtcbiAgICByZXR1cm4gYCR7dG90YWxXaWR0aH1weGA7XG4gIH1cblxuICBnZXRIZWFkZXJXaWR0aChjb2w6IFRhYmxlQ29sdW1uKTogc3RyaW5nIHtcbiAgICBjb25zdCB3aWR0aFdpdGhvdXRQeCA9IHBhcnNlSW50KGNvbC53aWR0aD8ucmVwbGFjZSgncHgnLCAnJykgfHwgJzAnLCAxMCk7XG4gICAgY29uc3QgaGVhZGVyV2lkdGggPSB3aWR0aFdpdGhvdXRQeCArIDIwO1xuICAgIHJldHVybiBgJHtoZWFkZXJXaWR0aH1weGA7XG4gIH1cblxuICBjbGVhcih0YWJsZTogVGFibGUpIHtcbiAgICB0YWJsZS5jbGVhcigpO1xuICAgIHRoaXMuc2VhcmNoVmFsdWUgPSAnJztcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VEYXRlKGRhdGVTdHJpbmc6IHN0cmluZyk6IERhdGUgfCBudWxsIHtcbiAgICBjb25zdCBwYXJ0cyA9IGRhdGVTdHJpbmcuc3BsaXQoJy8nKTtcbiAgICBpZiAocGFydHMubGVuZ3RoID09PSAzKSB7XG4gICAgICBjb25zdCBkYXkgPSBwYXJzZUludChwYXJ0c1swXSwgMTApO1xuICAgICAgY29uc3QgbW9udGggPSBwYXJzZUludChwYXJ0c1sxXSwgMTApIC0gMTtcbiAgICAgIGNvbnN0IHllYXIgPSBwYXJzZUludChwYXJ0c1syXSwgMTApO1xuICAgICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKHllYXIsIG1vbnRoLCBkYXkpO1xuICAgICAgcmV0dXJuIGlzTmFOKGRhdGUuZ2V0VGltZSgpKSA/IG51bGwgOiBkYXRlO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgaW5pdGlhbGl6ZVBhZ2luYXRpb24oKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNQYWdpbmF0ZWQpIHtcbiAgICAgIGlmICghdGhpcy5yb3dzUGVyUGFnZSB8fCB0aGlzLnJvd3NQZXJQYWdlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aGlzLnJvd3NQZXJQYWdlID0gWzIwLCAzMCwgNDBdO1xuICAgICAgfVxuICAgICAgdGhpcy5yb3dzID0gdGhpcy5yb3dzUGVyUGFnZVswXTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGluaXRpYWxpemVBY3Rpb25zKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmFjdGlvbnMpIHtcbiAgICAgIHRoaXMuYWN0aW9ucy5mb3JFYWNoKChhY3Rpb24pID0+IHtcbiAgICAgICAgc3dpdGNoIChhY3Rpb24uY29kZSkge1xuICAgICAgICAgIGNhc2UgJ2RlbGV0ZSc6XG4gICAgICAgICAgICB0aGlzLmlzRGVsZXRlID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuRGVsZXRlID0gKHZhbHVlOiBhbnkpID0+IGFjdGlvbi5hY3Rpb24odmFsdWUpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnZWRpdCc6XG4gICAgICAgICAgICB0aGlzLmluaXRpYWxpemVFZGl0QWN0aW9ucyhhY3Rpb24pO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRoaXMuaXNEZWxldGUgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuaXNFZGl0ID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaW5pdGlhbGl6ZUVkaXRBY3Rpb25zKGFjdGlvbjogYW55KTogdm9pZCB7XG4gICAgdGhpcy5pc0VkaXQgPSB0cnVlO1xuICAgIHRoaXMuaW5pdEVkaXRhYmxlUm93ID0gKGRhdGE6IGFueSkgPT4gYWN0aW9uLmFjdGlvbi5pbml0KGRhdGEpO1xuICAgIHRoaXMuc2F2ZUVkaXRhYmxlUm93ID0gKGRhdGE6IGFueSkgPT4ge1xuICAgICAgY29uc3QgcmVjb3JkID0gdGhpcy5tYXAuZ2V0KGRhdGEuaWQpO1xuICAgICAgYWN0aW9uLmFjdGlvbi5zYXZlKGRhdGEsIHJlY29yZCk7XG4gICAgICB0aGlzLmRhdGFNYXAuY2xlYXIoKTtcbiAgICB9O1xuICAgIHRoaXMuY2FuY2VsRWRpdGFibGVSb3cgPSAoaXRlbTogYW55KSA9PiBjb25zb2xlLmxvZyhpdGVtKTtcbiAgfVxuXG4gIG9uQ2hhbmdlKGV2ZW50OiBFdmVudCwgaWQ6IG51bWJlciwga2V5OiBhbnkpIHtcbiAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudDtcbiAgICB0aGlzLmNoYW5nZUhhbmRsZXIoaWQsIGtleSwgdGFyZ2V0LnZhbHVlKTtcbiAgfVxuXG4gIGNoYW5nZUhhbmRsZXIoaWQ6IG51bWJlciwga2V5OiBhbnksIHZhbHVlOiBhbnkpIHtcbiAgICBsZXQgY29sdW1uID0gdGhpcy5jb2x1bW5zLmZpbmQoKGl0ZW0pID0+IGl0ZW0uY29kZSA9PT0ga2V5KTtcbiAgICBpZiAoIXRoaXMubWFwLmdldChpZCkpIHtcbiAgICAgIGlmIChjb2x1bW4/LnR5cGUgPT09IFRhYmxlVHlwZUVudW0uREFURSkge1xuICAgICAgICBsZXQgZGF0ZSA9IHRoaXMucGFyc2VEYXRlKHZhbHVlKTtcbiAgICAgICAgdGhpcy5kYXRhTWFwLnNldChrZXksIGRhdGUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5kYXRhTWFwLnNldChrZXksIHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubWFwLnNldChpZCwgbmV3IE1hcCh0aGlzLmRhdGFNYXApKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IG1hcEl0ZW0gPSB0aGlzLm1hcC5nZXQoaWQpO1xuICAgICAgaWYgKGNvbHVtbj8udHlwZSA9PT0gVGFibGVUeXBlRW51bS5EQVRFKSB7XG4gICAgICAgIGxldCBkYXRlID0gdGhpcy5wYXJzZURhdGUodmFsdWUpO1xuICAgICAgICBtYXBJdGVtLnNldChrZXksIGRhdGUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbWFwSXRlbS5zZXQoa2V5LCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ2V0Q29sdW1uRmlsdGVyVHlwZShjb2x1bW46IFRhYmxlQ29sdW1uKTogc3RyaW5nIHtcbiAgICBzd2l0Y2ggKGNvbHVtbi50eXBlKSB7XG4gICAgICBjYXNlIFRhYmxlVHlwZUVudW0uU1RSSU5HOlxuICAgICAgICByZXR1cm4gJ3RleHQnO1xuICAgICAgY2FzZSBUYWJsZVR5cGVFbnVtLkFNT1VOVDpcbiAgICAgIGNhc2UgVGFibGVUeXBlRW51bS5OVU1CRVI6XG4gICAgICAgIHJldHVybiAnbnVtZXJpYyc7XG4gICAgICBjYXNlIFRhYmxlVHlwZUVudW0uREFURTpcbiAgICAgICAgcmV0dXJuICdkYXRlJztcbiAgICAgIGNhc2UgVGFibGVUeXBlRW51bS5NVUxUSVNFTEVDVDpcbiAgICAgICAgcmV0dXJuICdtdWx0aVNlbGVjdCc7XG4gICAgICBjYXNlIFRhYmxlVHlwZUVudW0uQk9PTEVBTjpcbiAgICAgICAgcmV0dXJuICdib29sZWFuJztcbiAgICAgIGNhc2UgVGFibGVUeXBlRW51bS5DT01QT1NFRDpcbiAgICAgICAgcmV0dXJuICdjb21wb3NlZCc7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gJ3RleHQnO1xuICAgIH1cbiAgfVxuXG4gIGlzRWRpdGFibGUoa2V5OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBsZXQgY29sdW1uID0gdGhpcy5jb2x1bW5zLmZpbmQoKGl0ZW0pID0+IGl0ZW0uY29kZSA9PT0ga2V5KTtcbiAgICByZXR1cm4gY29sdW1uPy5pc0VkaXRhYmxlICE9PSBmYWxzZTtcbiAgfVxuXG4gIGlzTXVsdGlTZWxlY3Qoa2V5OiBhbnkpOiBib29sZWFuIHtcbiAgICBsZXQgY29sdW1uID0gdGhpcy5jb2x1bW5zLmZpbmQoKGl0ZW0pID0+IGl0ZW0uY29kZSA9PT0ga2V5KTtcbiAgICBpZiAoXG4gICAgICBjb2x1bW4/LnR5cGUgPT09IFRhYmxlVHlwZUVudW0uTVVMVElTRUxFQ1QgJiZcbiAgICAgIGNvbHVtbi5vcHRpb25zICYmXG4gICAgICBjb2x1bW4uY29kZSAhPT0gdW5kZWZpbmVkXG4gICAgKSB7XG4gICAgICB0aGlzLm9wdGlvbkVudHJpZXMgPSBuZXcgTWFwKFtcbiAgICAgICAgW2NvbHVtbi5jb2RlLCBPYmplY3QudmFsdWVzKGNvbHVtbi5vcHRpb25zKV0sXG4gICAgICBdKTtcbiAgICAgIHRoaXMub3B0aW9uVmFsdWVzID0gdGhpcy5vcHRpb25FbnRyaWVzLmdldChrZXkpIHx8IFtdO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlzRGF0ZVBpY2tlcihrZXk6IGFueSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLmNvbHVtbnMuZmluZCgoaXRlbSkgPT4gaXRlbS5jb2RlID09PSBrZXkpPy50eXBlID09PVxuICAgICAgVGFibGVUeXBlRW51bS5EQVRFXG4gICAgKTtcbiAgfVxuXG4gIGRhdGVDb252ZXJ0ZXIodmFsdWU6IGFueSk6IHN0cmluZyB7XG4gICAgcmV0dXJuIG5ldyBEYXRlKHZhbHVlKS50b0xvY2FsZURhdGVTdHJpbmcoJ2VuLVVTJyk7XG4gIH1cblxuICBnZXRDdXJyZW5jeVN5bWJvbChjb2x1bW46IFRhYmxlQ29sdW1uKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gY29sdW1uLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uQU1PVU5UICYmXG4gICAgICBjb2x1bW4uY3VycmVuY3kgJiZcbiAgICAgIHRoaXMuaXNWYWxpZEN1cnJlbmN5Q29kZShjb2x1bW4uY3VycmVuY3kpXG4gICAgICA/IGNvbHVtbi5jdXJyZW5jeVxuICAgICAgOiB1bmRlZmluZWQ7XG4gIH1cblxuICBwcml2YXRlIGlzVmFsaWRDdXJyZW5jeUNvZGUoY3VycmVuY3lDb2RlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy52YWxpZEN1cnJlbmN5Q29kZXMuaW5jbHVkZXMoY3VycmVuY3lDb2RlKTtcbiAgfVxuXG4gIGZpbHRlckdsb2JhbChldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudDtcbiAgICBjb25zdCB2YWx1ZSA9IHRhcmdldC52YWx1ZS50b0xvd2VyQ2FzZSgpO1xuXG4gICAgY29uc3QgZmlsdGVyZWREYXRhID0gdGhpcy5kYXRhLmZpbHRlcigoaXRlbSkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuZ2xvYmFsRmlsdGVyRmllbGRzLnNvbWUoKGZpZWxkKSA9PiB7XG4gICAgICAgIGNvbnN0IGNvbHVtbiA9IHRoaXMuY29sdW1ucy5maW5kKChjb2wpID0+IGNvbC5jb2RlID09PSBmaWVsZCk7XG4gICAgICAgIGlmICghY29sdW1uKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNvbHVtbi50eXBlID09PSBUYWJsZVR5cGVFbnVtLkRBVEUpIHtcbiAgICAgICAgICBjb25zdCBpdGVtRGF0ZSA9IHRoaXMuZm9ybWF0RGF0ZShpdGVtW2ZpZWxkXSk7XG4gICAgICAgICAgcmV0dXJuIGl0ZW1EYXRlICYmIGl0ZW1EYXRlLmluY2x1ZGVzKHZhbHVlKTtcbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICBjb2x1bW4udHlwZSA9PT0gVGFibGVUeXBlRW51bS5BTU9VTlQgfHxcbiAgICAgICAgICBjb2x1bW4udHlwZSA9PT0gVGFibGVUeXBlRW51bS5OVU1CRVJcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIGl0ZW1bZmllbGRdICYmIGl0ZW1bZmllbGRdLnRvU3RyaW5nKCkudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyh2YWx1ZSlcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2UgaWYgKGNvbHVtbi50eXBlID09PSBUYWJsZVR5cGVFbnVtLkNPTVBPU0VEKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZmlsdGVyQ29tcG9zZWRDb2x1bW4oaXRlbVtmaWVsZF0sIHZhbHVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgaXRlbVtmaWVsZF0gJiYgaXRlbVtmaWVsZF0udG9TdHJpbmcoKS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHZhbHVlKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGhpcy5kdC52YWx1ZSA9IGZpbHRlcmVkRGF0YTtcblxuICAgIC8vIOKblCBkbyBOT1Qgb3ZlcnJpZGUgdG90YWxSZWNvcmRzIGluIHNlcnZlci1zaWRlIG1vZGVcbiAgICAvLyB0aGlzLnRvdGFsUmVjb3JkcyA9IGZpbHRlcmVkRGF0YS5sZW5ndGggPz8gMDtcbiAgfVxuXG4gIHByaXZhdGUgZmlsdGVyQ29tcG9zZWRDb2x1bW4oY29tcG9zZWREYXRhOiBhbnksIHZhbHVlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBpZiAoY29tcG9zZWREYXRhKSB7XG4gICAgICByZXR1cm4gT2JqZWN0LmtleXMoY29tcG9zZWREYXRhKS5zb21lKChrZXkpID0+IHtcbiAgICAgICAgY29uc3QgY2VsbFZhbHVlID0gY29tcG9zZWREYXRhW2tleV07XG4gICAgICAgIGlmICh0eXBlb2YgY2VsbFZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIHJldHVybiBjZWxsVmFsdWUudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGZvcm1hdERhdGUoZGF0ZTogYW55KTogc3RyaW5nIHtcbiAgICBpZiAoIWRhdGUpIHJldHVybiAnJztcbiAgICBpZiAoZGF0ZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgIGNvbnN0IGRheSA9IGRhdGUuZ2V0RGF0ZSgpLnRvU3RyaW5nKCkucGFkU3RhcnQoMiwgJzAnKTtcbiAgICAgIGNvbnN0IG1vbnRoID0gKGRhdGUuZ2V0TW9udGgoKSArIDEpLnRvU3RyaW5nKCkucGFkU3RhcnQoMiwgJzAnKTtcbiAgICAgIGNvbnN0IHllYXIgPSBkYXRlLmdldEZ1bGxZZWFyKCkudG9TdHJpbmcoKTtcbiAgICAgIHJldHVybiBgJHtkYXl9LyR7bW9udGh9LyR7eWVhcn1gO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGRhdGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBjb25zdCBwYXJ0cyA9IGRhdGUuc3BsaXQoJy8nKTtcbiAgICAgIGlmIChwYXJ0cy5sZW5ndGggPT09IDMpIHtcbiAgICAgICAgcmV0dXJuIGAke3BhcnRzWzBdfS8ke3BhcnRzWzFdfS8ke3BhcnRzWzJdfWA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZGF0ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgZXhwb3J0RXhjZWwoKSB7XG4gICAgdGhpcy5leHBvcnRFeGNlbEV2ZW50LmVtaXQoKTtcbiAgfVxuXG4gIGV4cG9ydFBkZigpIHtcbiAgICB0aGlzLmV4cG9ydFBkZkV2ZW50LmVtaXQoKTtcbiAgfVxuXG4gIGdldEltYWdlU3R5bGUoc3R5bGU6IFRpdGxlU3R5bGUgfCBJbWFnZVN0eWxlIHwgdW5kZWZpbmVkKToge1xuICAgIFtrZXk6IHN0cmluZ106IHN0cmluZztcbiAgfSB7XG4gICAgaWYgKHN0eWxlKSB7XG4gICAgICBjb25zdCBpbWFnZVN0eWxlOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9ID0ge1xuICAgICAgICB3aWR0aDogKHN0eWxlIGFzIEltYWdlU3R5bGUpLndpZHRoIHx8ICdhdXRvJyxcbiAgICAgICAgaGVpZ2h0OiAoc3R5bGUgYXMgSW1hZ2VTdHlsZSkuaGVpZ2h0IHx8ICdhdXRvJyxcbiAgICAgIH07XG5cbiAgICAgIGlmICgoc3R5bGUgYXMgSW1hZ2VTdHlsZSkubWFyZ2luKSB7XG4gICAgICAgIGltYWdlU3R5bGUubWFyZ2luID0gKHN0eWxlIGFzIEltYWdlU3R5bGUpLm1hcmdpbiE7XG4gICAgICB9XG4gICAgICBpZiAoKHN0eWxlIGFzIEltYWdlU3R5bGUpLm1hcmdpbkxlZnQpIHtcbiAgICAgICAgaW1hZ2VTdHlsZS5tYXJnaW5MZWZ0ID0gKHN0eWxlIGFzIEltYWdlU3R5bGUpLm1hcmdpbkxlZnQhO1xuICAgICAgfVxuICAgICAgaWYgKChzdHlsZSBhcyBJbWFnZVN0eWxlKS5tYXJnaW5SaWdodCkge1xuICAgICAgICBpbWFnZVN0eWxlLm1hcmdpblJpZ2h0ID0gKHN0eWxlIGFzIEltYWdlU3R5bGUpLm1hcmdpblJpZ2h0ITtcbiAgICAgIH1cbiAgICAgIGlmICgoc3R5bGUgYXMgSW1hZ2VTdHlsZSkubWFyZ2luVG9wKSB7XG4gICAgICAgIGltYWdlU3R5bGUubWFyZ2luVG9wID0gKHN0eWxlIGFzIEltYWdlU3R5bGUpLm1hcmdpblRvcCE7XG4gICAgICB9XG4gICAgICBpZiAoKHN0eWxlIGFzIEltYWdlU3R5bGUpLm1hcmdpbkJvdHRvbSkge1xuICAgICAgICBpbWFnZVN0eWxlLm1hcmdpbkJvdHRvbSA9IChzdHlsZSBhcyBJbWFnZVN0eWxlKS5tYXJnaW5Cb3R0b20hO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gaW1hZ2VTdHlsZTtcbiAgICB9XG5cbiAgICByZXR1cm4ge307XG4gIH1cblxuICBnZXRUaXRsZVN0eWxlKHN0eWxlOiBUaXRsZVN0eWxlIHwgSW1hZ2VTdHlsZSB8IHVuZGVmaW5lZCk6IHtcbiAgICBba2V5OiBzdHJpbmddOiBzdHJpbmc7XG4gIH0ge1xuICAgIGlmIChzdHlsZSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29sb3I6IHN0eWxlLmNvbG9yIHx8ICdpbmhlcml0JyxcbiAgICAgICAgZm9udFNpemU6IChzdHlsZSBhcyBUaXRsZVN0eWxlKS5mb250U2l6ZSB8fCAnaW5oZXJpdCcsXG4gICAgICAgIHRleHRBbGlnbjogKHN0eWxlIGFzIFRpdGxlU3R5bGUpLnBvc2l0aW9uIHx8ICdsZWZ0JyxcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIGZvcm1hdE51bWJlcihcbiAgICB2YWx1ZTogbnVtYmVyLFxuICAgIGRlY2ltYWxQbGFjZXM/OiBudW1iZXIsXG4gICAgdGhvdXNhbmRTZXBhcmF0b3I6ICdjb21tYScgfCAnc3BhY2UnID0gJ2NvbW1hJyxcbiAgICBkZWNpbWFsU2VwYXJhdG9yOiAnY29tbWEnIHwgJ2RvdCcgPSAnZG90J1xuICApOiBzdHJpbmcge1xuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IGlzTmFOKHZhbHVlKSkgcmV0dXJuICcnO1xuXG4gICAgbGV0IGZvcm1hdHRlZE51bWJlciA9XG4gICAgICBkZWNpbWFsUGxhY2VzICE9PSB1bmRlZmluZWRcbiAgICAgICAgPyB2YWx1ZS50b0ZpeGVkKGRlY2ltYWxQbGFjZXMpXG4gICAgICAgIDogdmFsdWUudG9TdHJpbmcoKTtcblxuICAgIGlmIChkZWNpbWFsU2VwYXJhdG9yID09PSAnY29tbWEnKSB7XG4gICAgICBmb3JtYXR0ZWROdW1iZXIgPSBmb3JtYXR0ZWROdW1iZXIucmVwbGFjZSgnLicsICcsJyk7XG4gICAgfVxuXG4gICAgaWYgKHRob3VzYW5kU2VwYXJhdG9yICYmIE1hdGguYWJzKHZhbHVlKSA+PSAxMDAwKSB7XG4gICAgICBjb25zdCBwYXJ0cyA9IGZvcm1hdHRlZE51bWJlci5zcGxpdChcbiAgICAgICAgZGVjaW1hbFNlcGFyYXRvciA9PT0gJ2NvbW1hJyA/ICcsJyA6ICcuJ1xuICAgICAgKTtcbiAgICAgIHBhcnRzWzBdID0gcGFydHNbMF0ucmVwbGFjZShcbiAgICAgICAgL1xcQig/PShcXGR7M30pKyg/IVxcZCkpL2csXG4gICAgICAgIHRob3VzYW5kU2VwYXJhdG9yID09PSAnY29tbWEnID8gJywnIDogJyAnXG4gICAgICApO1xuICAgICAgZm9ybWF0dGVkTnVtYmVyID0gcGFydHMuam9pbihkZWNpbWFsU2VwYXJhdG9yID09PSAnY29tbWEnID8gJywnIDogJy4nKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZm9ybWF0dGVkTnVtYmVyO1xuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwicHQtYWR2YW5jZWQtcHJpbWUtdGFibGUgdGFibGUtY29udGFpbmVyXCI+XG4gIDxwLXRhYmxlXG4gICAgI2R0XG4gICAgW3ZhbHVlXT1cImRhdGFcIlxuICAgIFtsb2FkaW5nXT1cImxvYWRpbmdcIlxuICAgIFtyb3dzXT1cInJvd3NcIlxuICAgIFtwYWdpbmF0b3JdPVwiaXNQYWdpbmF0ZWRcIlxuICAgIFtnbG9iYWxGaWx0ZXJGaWVsZHNdPVwiZ2xvYmFsRmlsdGVyRmllbGRzXCJcbiAgICBbcm93c1BlclBhZ2VPcHRpb25zXT1cInJvd3NQZXJQYWdlXCJcbiAgICBbdG90YWxSZWNvcmRzXT1cInRvdGFsUmVjb3Jkc1wiXG4gICAgW2xhenldPVwidHJ1ZVwiXG4gICAgZGF0YUtleT1cImlkXCJcbiAgICBzdHlsZUNsYXNzPVwicC1kYXRhdGFibGUtZ3JpZGxpbmVzXCJcbiAgICBzdHlsZUNsYXNzPVwicC1kYXRhdGFibGUtc3RyaXBlZFwiXG4gICAgZWRpdE1vZGU9XCJyb3dcIlxuICAgIFtzY3JvbGxhYmxlXT1cInRydWVcIlxuICAgIFtzY3JvbGxIZWlnaHRdPVwibWF4SGVpZ2h0ICE9PSBudWxsID8gbWF4SGVpZ2h0IDogdW5kZWZpbmVkXCJcbiAgICAob25GaWx0ZXIpPVwib25GaWx0ZXIoJGV2ZW50KVwiXG4gICAgKG9uUGFnZSk9XCJvblBhZ2VDaGFuZ2UoJGV2ZW50KVwiXG4gID5cbiAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiY2FwdGlvblwiPlxuICAgICAgPGRpdiBjbGFzcz1cImZsZXhcIj5cbiAgICAgICAgPGRpdj5cbiAgICAgICAgICA8aDM+VG90YWw6IHt7IHRvdGFsUmVjb3JkcyB9fTwvaDM+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXY+XG4gICAgICAgICAgPCEtLSBDbGVhciBmaWx0ZXJzIC0tPlxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICpuZ0lmPVwiaGFzU2VhcmNoRmlsdGVyXCJcbiAgICAgICAgICAgIHBCdXR0b25cbiAgICAgICAgICAgIGljb249XCJwaSBwaS1maWx0ZXItc2xhc2hcIlxuICAgICAgICAgICAgY2xhc3M9XCJwLWJ1dHRvbi1yb3VuZGVkIHAtYnV0dG9uLXRleHRcIlxuICAgICAgICAgICAgKGNsaWNrKT1cImNsZWFyKGR0KVwiXG4gICAgICAgICAgICB0aXRsZT1cIkNsZWFyIGZpbHRlcnNcIlxuICAgICAgICAgID48L2J1dHRvbj5cblxuICAgICAgICAgIDwhLS0gRXhwb3J0IHRvIEV4Y2VsIEJ1dHRvbiAtLT5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAqbmdJZj1cImhhc0V4cG9ydEV4Y2VsXCJcbiAgICAgICAgICAgIHBCdXR0b25cbiAgICAgICAgICAgIGljb249XCJwaSBwaS1maWxlLWV4Y2VsXCJcbiAgICAgICAgICAgIGNsYXNzPVwicC1idXR0b24tcm91bmRlZCBwLWJ1dHRvbi10ZXh0XCJcbiAgICAgICAgICAgIChjbGljayk9XCJleHBvcnRFeGNlbCgpXCJcbiAgICAgICAgICAgIHRpdGxlPVwiRXhwb3J0IHRvIEV4Y2VsXCJcbiAgICAgICAgICA+PC9idXR0b24+XG5cbiAgICAgICAgICA8IS0tIEV4cG9ydCB0byBQREYgQnV0dG9uIC0tPlxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICpuZ0lmPVwiaGFzRXhwb3J0UERGXCJcbiAgICAgICAgICAgIHBCdXR0b25cbiAgICAgICAgICAgIGljb249XCJwaSBwaS1maWxlLXBkZlwiXG4gICAgICAgICAgICBjbGFzcz1cInAtYnV0dG9uLXJvdW5kZWQgcC1idXR0b24tdGV4dFwiXG4gICAgICAgICAgICAoY2xpY2spPVwiZXhwb3J0UGRmKClcIlxuICAgICAgICAgICAgdGl0bGU9XCJFeHBvcnQgdG8gUERGXCJcbiAgICAgICAgICA+PC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwibWwtYXV0b1wiICpuZ0lmPVwiaGFzU2VhcmNoRmlsdGVyXCI+XG4gICAgICAgICAgPCEtLSBBZGQgdGhpcyB3cmFwcGVyIGRpdiB3aXRoIG1sLWF1dG8gY2xhc3MgLS0+XG4gICAgICAgICAgPHAtaWNvbkZpZWxkIGljb25Qb3NpdGlvbj1cImxlZnRcIiBjbGFzcz1cIm1sLWF1dG9cIj5cbiAgICAgICAgICAgIDxwLWlucHV0SWNvbj5cbiAgICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1zZWFyY2hcIj48L2k+XG4gICAgICAgICAgICA8L3AtaW5wdXRJY29uPlxuICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgIHBJbnB1dFRleHRcbiAgICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInNlYXJjaFZhbHVlXCJcbiAgICAgICAgICAgICAgKGlucHV0KT1cImZpbHRlckdsb2JhbCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJTZWFyY2gga2V5d29yZFwiXG4gICAgICAgICAgICAvPlxuICAgICAgICAgIDwvcC1pY29uRmllbGQ+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJoZWFkZXJcIj5cbiAgICAgIDx0ciBjbGFzcz1cInN0aWNreS1oZWFkZXJcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgY29sIG9mIGNvbHVtbnNcIj5cbiAgICAgICAgICA8dGhcbiAgICAgICAgICAgICpuZ0lmPVwiIWNvbC5jaGlsZHJlbjsgZWxzZSBncm91cEhlYWRlclwiXG4gICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiZ2V0SGVhZGVyV2lkdGgoY29sKVwiXG4gICAgICAgICAgICBbc3R5bGUucGFkZGluZ109XCInMHB4J1wiXG4gICAgICAgICAgICBjb2xzcGFuPVwiMVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAqbmdJZj1cImlzU29ydGFibGUgJiYgY29sLmlzU29ydGFibGUgIT09IGZhbHNlOyBlbHNlIG5vU29ydEhlYWRlclwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDx0aFxuICAgICAgICAgICAgICAgIHBTb3J0YWJsZUNvbHVtbj1cInt7IGNvbC5jb2RlIH19XCJcbiAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiZ2V0SGVhZGVyV2lkdGgoY29sKVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICBjbGFzcz1cImhlYWRlci1jb250YWluZXIgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlblwiXG4gICAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiY29sLndpZHRoXCJcbiAgICAgICAgICAgICAgICAgIFtzdHlsZS5wYWRkaW5nXT1cIicwcHgnXCJcbiAgICAgICAgICAgICAgICAgIFtzdHlsZS5tYXJnaW5dPVwiJzEwcHgnXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICA8c3Bhbj57eyBjb2wudGl0bGUgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiaWNvbnMgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiXG4gICAgICAgICAgICAgICAgICAgIFtzdHlsZS53aWR0aF09XCInNzdweCdcIlxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8cC1zb3J0SWNvbiBmaWVsZD1cInt7IGNvbC5jb2RlIH19XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbC5pc0ZpbHRlciAhPT0gZmFsc2VcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8cC1jb2x1bW5GaWx0ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BsYXk9XCJtZW51XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtmaWVsZF09XCJjb2wuY29kZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNwbGF5PVwibWVudVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbdHlwZV09XCJnZXRDb2x1bW5GaWx0ZXJUeXBlKGNvbClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb2wudHlwZSA9PT0gVGFibGVUeXBlRW51bS5DT01QT1NFRFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBzaG93Q2xlYXJCdXR0b249XCJmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBzaG93QXBwbHlCdXR0b249XCJmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBUYWJsZVR5cGVFbnVtLkNPTVBPU0VEIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHBUZW1wbGF0ZT1cImZpbHRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGxldC12YWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQtZmlsdGVyQ2FsbGJhY2s9XCJmaWx0ZXJDYWxsYmFja1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChvbkZpbHRlcik9XCJvbkZpbHRlcigkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgY29tcG9zZWROYW1lIG9mIGNvbC5jb21wb3NlZE5hbWVzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Q29tcG9zZWRGaWVsZFR5cGUoY29sLCBjb21wb3NlZE5hbWUpID09PVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUYWJsZVR5cGVFbnVtLlNUUklOR1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cC1tdWx0aVNlbGVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJmaWx0ZXJzW2NvbXBvc2VkTmFtZV0/LnZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvbnNdPVwiZmlsdGVyc1tjb21wb3NlZE5hbWVdPy5vcHRpb25zXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9uQ2hhbmdlKT1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uQ29tcG9zZWRGaWx0ZXJDaGFuZ2UoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb3NlZE5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZXZlbnQudmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXJzW2NvbXBvc2VkTmFtZV0/LnBsYWNlaG9sZGVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNwbGF5XT1cIidjaGlwJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBsZXQtaXRlbSBwVGVtcGxhdGU9XCJpdGVtXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImN1c3RvbS1tdWx0aXNlbGVjdC1pdGVtXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiaXRlbS5pbWFnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzcmNdPVwiaXRlbS5pbWFnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsdD1cImljb25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZpbHRlci1pbWFnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+e3sgaXRlbS5sYWJlbCB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvcC1tdWx0aVNlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBEZWZpbmUgaXRlbVRlbXBsYXRlIGhlcmUgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBsZXQtaXRlbSBwVGVtcGxhdGU9XCJpdGVtXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImN1c3RvbS1tdWx0aXNlbGVjdC1pdGVtXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiaXRlbS5pbWFnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzcmNdPVwiaXRlbS5pbWFnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsdD1cImljb25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZpbHRlci1pbWFnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+e3sgaXRlbS5sYWJlbCB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgPC9wLWNvbHVtbkZpbHRlcj5cblxuICAgICAgICAgICAgICAgICAgICAgIDwhLS0gb3RoZXIgVGFibGVUeXBlRW51bS5YWFggLS0+XG4gICAgICAgICAgICAgICAgICAgICAgPHAtY29sdW1uRmlsdGVyXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNwbGF5PVwibWVudVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbZmllbGRdPVwiY29sLmNvZGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGxheT1cIm1lbnVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW3R5cGVdPVwiZ2V0Q29sdW1uRmlsdGVyVHlwZShjb2wpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29sLnR5cGUgIT09IFRhYmxlVHlwZUVudW0uQ09NUE9TRURcIlxuICAgICAgICAgICAgICAgICAgICAgICAgaGlkZU9uQ2xlYXI9XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIFRhYmxlVHlwZUVudW0uTlVNQkVSIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHBUZW1wbGF0ZT1cImZpbHRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGxldC12YWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQtZmlsdGVyQ2FsbGJhY2s9XCJmaWx0ZXJDYWxsYmFja1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29sLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uTlVNQkVSXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKG9uRmlsdGVyKT1cIm9uRmlsdGVyKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwSW5wdXRUZXh0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cIm51bWJlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0ZXBdPVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wuZGVjaW1hbFBsYWNlc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/ICcwLicgKyAnMScucGFkRW5kKGNvbC5kZWNpbWFsUGxhY2VzLCAnMCcpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogJ2FueSdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cInZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJmaWx0ZXJDYWxsYmFjaygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ0VudGVyIGEgbnVtYmVyJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIFRhYmxlVHlwZUVudW0uREFURSAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICBwVGVtcGxhdGU9XCJmaWx0ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQtdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0LWZpbHRlckNhbGxiYWNrPVwiZmlsdGVyQ2FsbGJhY2tcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbC50eXBlID09PSBUYWJsZVR5cGVFbnVtLkRBVEVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAob25GaWx0ZXIpPVwib25GaWx0ZXIoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxwLWNhbGVuZGFyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwidmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25DYWxlbmRhckZpbHRlckNoYW5nZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGV2ZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wuY29kZSEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlckNhbGxiYWNrXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGF0ZUZvcm1hdF09XCInZGQvbW0veXknXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ0Nob29zZSBhIGRhdGUnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPjwvcC1jYWxlbmRhcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gVGFibGVUeXBlRW51bS5NVUxUSVNFTEVDVCAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICBwVGVtcGxhdGU9XCJmaWx0ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQtdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0LWZpbHRlckNhbGxiYWNrPVwiZmlsdGVyQ2FsbGJhY2tcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC50eXBlID09PSBUYWJsZVR5cGVFbnVtLk1VTFRJU0VMRUNUICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sLmZpbHRlck9wdGlvbnMgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wuZmlsdGVyT3B0aW9ucy5sZW5ndGggPiAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChvbkZpbHRlcik9XCJvbkZpbHRlcigkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHAtbXVsdGlTZWxlY3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3B0aW9uc109XCJjb2wuZmlsdGVyT3B0aW9uc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwidmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cImZpbHRlckNhbGxiYWNrKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNwbGF5XT1cIidjaGlwJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cIidDaG9vc2Ugb3B0aW9uJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjdXN0b20tbXVsdGlzZWxlY3RcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICA+PC9wLW11bHRpU2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICA8L3AtY29sdW1uRmlsdGVyPlxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgI25vU29ydEhlYWRlcj5cbiAgICAgICAgICAgICAgPHRoPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoZWFkZXItY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICA8c3Bhbj57eyBjb2wudGl0bGUgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29sLmlzRmlsdGVyICE9PSBmYWxzZVwiPlxuICAgICAgICAgICAgICAgICAgICA8cC1jb2x1bW5GaWx0ZXJcbiAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbC50eXBlID09PSAnQU1PVU5UJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgZGlzcGxheT1cIm1lbnVcIlxuICAgICAgICAgICAgICAgICAgICAgIFtmaWVsZF09XCJjb2wuY29kZVwiXG4gICAgICAgICAgICAgICAgICAgICAgW3R5cGVdPVwiZ2V0Q29sdW1uRmlsdGVyVHlwZShjb2wpXCJcbiAgICAgICAgICAgICAgICAgICAgICBbY3VycmVuY3ldPVwiZ2V0Q3VycmVuY3lTeW1ib2woY29sKVwiXG4gICAgICAgICAgICAgICAgICAgID48L3AtY29sdW1uRmlsdGVyPlxuXG4gICAgICAgICAgICAgICAgICAgIDxwLWNvbHVtbkZpbHRlclxuICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29sLnR5cGUgIT09ICdBTU9VTlQnXCJcbiAgICAgICAgICAgICAgICAgICAgICBkaXNwbGF5PVwibWVudVwiXG4gICAgICAgICAgICAgICAgICAgICAgW2ZpZWxkXT1cImNvbC5jb2RlXCJcbiAgICAgICAgICAgICAgICAgICAgICBbdHlwZV09XCJnZXRDb2x1bW5GaWx0ZXJUeXBlKGNvbClcIlxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICBwVGVtcGxhdGU9XCJmaWx0ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0LXZhbHVlXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQtZmlsdGVyQ2FsbGJhY2s9XCJmaWx0ZXJDYWxsYmFja1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImdldENvbHVtbkZpbHRlclR5cGUoY29sKSA9PT0gJ2RhdGUnXCJcbiAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8cC1jYWxlbmRhclxuICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJ2YWx1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cImZpbHRlckNhbGxiYWNrKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbZGF0ZUZvcm1hdF09XCInZGQvbW0veXknXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID48L3AtY2FsZW5kYXI+XG4gICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgcFRlbXBsYXRlPVwiZmlsdGVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldC12YWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0LWZpbHRlckNhbGxiYWNrPVwiZmlsdGVyQ2FsbGJhY2tcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJnZXRDb2x1bW5GaWx0ZXJUeXBlKGNvbCkgPT09ICdtdWx0aVNlbGVjdCdcIlxuICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxwLW11bHRpU2VsZWN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25zXT1cImNvbC5maWx0ZXJPcHRpb25zXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwidmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJmaWx0ZXJDYWxsYmFjaygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc3BsYXldPVwiJ2NoaXAnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJTZWxlY3RcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImN1c3RvbS1tdWx0aXNlbGVjdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICA+PC9wLW11bHRpU2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgIDwvcC1jb2x1bW5GaWx0ZXI+XG4gICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgPC90aD5cbiAgICAgICAgICA8IS0tIEdyb3VwZWQgaGVhZGVycyAtLT5cbiAgICAgICAgICA8bmctdGVtcGxhdGUgI2dyb3VwSGVhZGVyPlxuICAgICAgICAgICAgPHRoXG4gICAgICAgICAgICAgIFthdHRyLmNvbHNwYW5dPVwiY29sLmNoaWxkcmVuPy5sZW5ndGhcIlxuICAgICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiZ2V0SGVhZGVyV2lkdGgoY29sKVwiXG4gICAgICAgICAgICAgIFtzdHlsZS50ZXh0LWFsaWduXT1cIidjZW50ZXInXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPHNwYW4+e3sgY29sLnRpdGxlIH19PC9zcGFuPlxuICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvdHI+XG4gICAgICA8IS0tIENoaWxkIGhlYWRlcnMgKFNlY29uZCBSb3cpIC0tPlxuICAgICAgPHRyICpuZ0lmPVwiaGFzR3JvdXBlZENvbHVtbnNcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgY29sIG9mIGNvbHVtbnNcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29sLmNoaWxkcmVuXCI+XG4gICAgICAgICAgICA8dGhcbiAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IGNoaWxkIG9mIGNvbC5jaGlsZHJlblwiXG4gICAgICAgICAgICAgIFtzdHlsZS53aWR0aF09XCJnZXRIZWFkZXJXaWR0aChjaGlsZClcIlxuICAgICAgICAgICAgICBbc3R5bGUucGFkZGluZ109XCInMHB4J1wiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDwhLS0gU29ydGFibGUvRmlsdGVyYWJsZSBoZWFkZXIgbG9naWMgZm9yIGNoaWxkIGNvbHVtbnMgLS0+XG4gICAgICAgICAgICA8L3RoPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvdHI+XG4gICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgIDwhLS0gRW1wdHkgbWVzc2FnZSB0ZW1wbGF0ZSAtLT5cbiAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiZW1wdHltZXNzYWdlXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiZW1wdHktbWVzc2FnZVwiPlxuICAgICAgICA8aSBjbGFzcz1cInBpIHBpLWluZm8tY2lyY2xlXCI+PC9pPlxuICAgICAgICA8cD5ObyByZWNvcmRzIGF2YWlsYWJsZSB0byBkaXNwbGF5LjwvcD5cbiAgICAgIDwvZGl2PlxuICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICA8IS0tIEJvZHkgLS0+XG4gICAgPG5nLXRlbXBsYXRlXG4gICAgICBwVGVtcGxhdGU9XCJib2R5XCJcbiAgICAgIGxldC1kYXRhXG4gICAgICBsZXQtZWRpdGluZz1cImVkaXRpbmdcIlxuICAgICAgbGV0LXJpPVwicm93SW5kZXhcIlxuICAgID5cbiAgICAgIDwhLS0gUmVuZGVyIGEgdGFibGUgcm93IGFuZCBtYWtlIGl0IGVkaXRhYmxlIGlmIGBpc0VkaXRgIGlzIHRydWUgLS0+XG4gICAgICA8dHIgKm5nSWY9XCIhbG9hZGluZ1wiIFtwRWRpdGFibGVSb3ddPVwiaXNFZGl0ID8gZGF0YSA6IG51bGxcIj5cbiAgICAgICAgPCEtLSBMb29wIHRocm91Z2ggZWFjaCBjb2x1bW4gLS0+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGNvbCBvZiBjb2x1bW5zXCI+XG4gICAgICAgICAgPCEtLSBDaGVjayBpZiB0aGUgY29sdW1uIGhhcyBjaGlsZHJlbiAtLT5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWNvbC5jaGlsZHJlbjsgZWxzZSBjaGlsZENvbHVtbnNcIj5cbiAgICAgICAgICAgIDwhLS0gUmVuZGVyIGEgc2luZ2xlIGNlbGwgZm9yIGNvbHVtbnMgd2l0aG91dCBjaGlsZHJlbiAtLT5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgKm5nSWY9XCJjb2wuY29kZSAhPT0gdW5kZWZpbmVkICYmIGRhdGFbY29sLmNvZGVdICE9PSB1bmRlZmluZWRcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8dGRcbiAgICAgICAgICAgICAgICAqbmdJZj1cImlzRWRpdGFibGUoY29sLmNvZGUpOyBlbHNlIG5vcm1hbFREXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiZ2V0SGVhZGVyV2lkdGgoY29sKVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8IS0tIEVkaXRhYmxlIGlucHV0IGZvciB0aGUgY29sdW1uIC0tPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc011bHRpU2VsZWN0KGNvbC5jb2RlKTsgZWxzZSBkYXRlUGlja2VyXCI+XG4gICAgICAgICAgICAgICAgICA8cC1jZWxsRWRpdG9yPlxuICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiaW5wdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8cC1tdWx0aVNlbGVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgYXBwZW5kVG89XCJib2R5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cImRhdGFbY29sLmNvZGVdXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZV09XCJ7IHdpZHRoOiAnMTAwJScgfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbmdlSGFuZGxlcihkYXRhLmlkLCBjb2wuY29kZSwgJGV2ZW50KVxuICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25zXT1cIm9wdGlvblZhbHVlc1wiXG4gICAgICAgICAgICAgICAgICAgICAgPjwvcC1tdWx0aVNlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cIm91dHB1dFwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtdWx0aS1zZWxlY3QtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCByZWMgb2YgZGF0YVtjb2wuY29kZV1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHAtdGFnIFt2YWx1ZV09XCJyZWNcIj48L3AtdGFnPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICA8L3AtY2VsbEVkaXRvcj5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZGF0ZVBpY2tlcj5cbiAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJpc0RhdGVQaWNrZXIoY29sLmNvZGUpOyBlbHNlIG5vcm1hbElucHV0XCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPHAtY2VsbEVkaXRvcj5cbiAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiaW5wdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxwLWNhbGVuZGFyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtpbnB1dElkXT1cImRhdGFbY29sLmNvZGVdXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwiZGF0YVtjb2wuY29kZV1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFuZ2VIYW5kbGVyKGRhdGEuaWQsIGNvbC5jb2RlLCAkZXZlbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtkYXRlRm9ybWF0XT1cIidkZC9tbS95eSdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgPjwvcC1jYWxlbmRhcj5cbiAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJvdXRwdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7IGRhdGFbY29sLmNvZGVdIHwgY3VzdG9tRGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgIDwvcC1jZWxsRWRpdG9yPlxuICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjbm9ybWFsSW5wdXQ+XG4gICAgICAgICAgICAgICAgICA8cC1jZWxsRWRpdG9yPlxuICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiaW5wdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgIHBJbnB1dFRleHRcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cImRhdGFbY29sLmNvZGVdXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwib25DaGFuZ2UoJGV2ZW50LCBkYXRhLmlkLCBjb2wuY29kZSlcIlxuICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJvdXRwdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wudHlwZSA9PT0gVGFibGVUeXBlRW51bS5BTU9VTlQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Ugbm9ybWFsT3V0cHV0XG4gICAgICAgICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFbY29sLmNvZGVdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBjdXN0b21DdXJyZW5jeVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBnZXRDdXJyZW5jeVN5bWJvbChjb2wpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGNvbC5kZWNpbWFsUGxhY2VzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGNvbC50aG91c2FuZFNlcGFyYXRvclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBjb2wuZGVjaW1hbFNlcGFyYXRvclxuICAgICAgICAgICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI25vcm1hbE91dHB1dD5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7IGRhdGFbY29sLmNvZGVdIH19XG4gICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgIDwvcC1jZWxsRWRpdG9yPlxuICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgIDwvdGQ+XG5cbiAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNub3JtYWxURD5cbiAgICAgICAgICAgICAgICA8dGQgW3N0eWxlLndpZHRoXT1cImdldEhlYWRlcldpZHRoKGNvbClcIj5cbiAgICAgICAgICAgICAgICAgIDwhLS0gQ09NUE9TRUQgLS0+XG4gICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29sLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uQ09NUE9TRURcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbXBvc2VkLWNlbGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAqbmdGb3I9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNvbXBvc2VkTmFtZSBvZiBjb2wuY29tcG9zZWROYW1lcztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGkgPSBpbmRleFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIENoZWNrIGlmIHRoZSBjb21wb3NlZFR5cGUgaXMgSU1BR0UgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sLmNvbXBvc2VkVHlwZXMgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wuY29tcG9zZWRUeXBlc1tpXSA9PT0gVGFibGVUeXBlRW51bS5JTUFHRVxuICAgICAgICAgICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3NyY109XCJkYXRhW2NvbC5jb2RlXVtjb21wb3NlZE5hbWVdXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbHQ9XCJjb21wb3NlZC1pbWdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY29tcG9zZWQtaW1hZ2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1N0eWxlXT1cImdldEltYWdlU3R5bGUoY29sLmNvbXBvc2VkU3R5bGVzPy5bY29tcG9zZWROYW1lXSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gQ2hlY2sgaWYgdGhlIGNvbXBvc2VkVHlwZSBpcyBTVFJJTkcgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sLmNvbXBvc2VkVHlwZXMgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wuY29tcG9zZWRUeXBlc1tpXSA9PT0gVGFibGVUeXBlRW51bS5TVFJJTkdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNvbXBvc2VkLXRleHRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1N0eWxlXT1cImdldFRpdGxlU3R5bGUoY29sLmNvbXBvc2VkU3R5bGVzPy5bY29tcG9zZWROYW1lXSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgZGF0YVtjb2wuY29kZV1bY29tcG9zZWROYW1lXSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgICAgPCEtLSBBTU9VTlQtLT5cbiAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb2wudHlwZSA9PT0gVGFibGVUeXBlRW51bS5BTU9VTlRcIj5cbiAgICAgICAgICAgICAgICAgICAge3tcbiAgICAgICAgICAgICAgICAgICAgICBkYXRhW2NvbC5jb2RlXVxuICAgICAgICAgICAgICAgICAgICAgICAgfCBjdXN0b21DdXJyZW5jeVxuICAgICAgICAgICAgICAgICAgICAgICAgICA6IGdldEN1cnJlbmN5U3ltYm9sKGNvbClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgOiBjb2wuZGVjaW1hbFBsYWNlc1xuICAgICAgICAgICAgICAgICAgICAgICAgICA6IGNvbC50aG91c2FuZFNlcGFyYXRvclxuICAgICAgICAgICAgICAgICAgICAgICAgICA6IGNvbC5kZWNpbWFsU2VwYXJhdG9yXG4gICAgICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgICAgPCEtLSBOVU1CRVItLT5cbiAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb2wudHlwZSA9PT0gVGFibGVUeXBlRW51bS5OVU1CRVJcIj5cbiAgICAgICAgICAgICAgICAgICAge3tcbiAgICAgICAgICAgICAgICAgICAgICBmb3JtYXROdW1iZXIoXG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhW2NvbC5jb2RlXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5kZWNpbWFsUGxhY2VzLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29sLnRob3VzYW5kU2VwYXJhdG9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29sLmRlY2ltYWxTZXBhcmF0b3JcbiAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgICAgPCEtLSBEQVRFIC0tPlxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbC50eXBlID09PSBUYWJsZVR5cGVFbnVtLkRBVEVcIj5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBGb3JtYXQgdGhlIGRhdGUgdXNpbmcgeW91ciBmb3JtYXREYXRlIG1ldGhvZCAtLT5cbiAgICAgICAgICAgICAgICAgICAge3sgZm9ybWF0RGF0ZShkYXRhW2NvbC5jb2RlXSkgfX1cbiAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICAgICAgICA8IS0tIFNUUklORywgTVVMVElTRUxFQ1QtLT5cbiAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJcbiAgICAgICAgICAgICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgICAgICAgICBUYWJsZVR5cGVFbnVtLlNUUklORyxcbiAgICAgICAgICAgICAgICAgICAgICAgIFRhYmxlVHlwZUVudW0uTVVMVElTRUxFQ1RcbiAgICAgICAgICAgICAgICAgICAgICBdLmluY2x1ZGVzKGNvbC50eXBlISlcbiAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAge3sgZGF0YVtjb2wuY29kZV0gfX1cbiAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgIDwhLS0gUmVuZGVyIGNoaWxkIGNvbHVtbnMgaWYgdGhlIGNvbHVtbiBoYXMgY2hpbGRyZW4gLS0+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlICNjaGlsZENvbHVtbnM+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBjaGlsZCBvZiBjb2wuY2hpbGRyZW5cIj5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICpuZ0lmPVwiXG4gICAgICAgICAgICAgICAgICBjaGlsZC5jb2RlICE9PSB1bmRlZmluZWQgJiYgZGF0YVtjaGlsZC5jb2RlXSAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDx0ZCBbc3R5bGUud2lkdGhdPVwiZ2V0SGVhZGVyV2lkdGgoY2hpbGQpXCI+XG4gICAgICAgICAgICAgICAgICA8IS0tIFJlbmRlciBlZGl0YWJsZSBvciBub3JtYWwgY2VsbHMgZm9yIGNoaWxkIGNvbHVtbnMgLS0+XG4gICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiaXNFZGl0YWJsZShjaGlsZC5jb2RlKTsgZWxzZSBjaGlsZE5vcm1hbFREXCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPHAtY2VsbEVkaXRvcj5cbiAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiaW5wdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICBwSW5wdXRUZXh0XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwiZGF0YVtjaGlsZC5jb2RlXVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwib25DaGFuZ2UoJGV2ZW50LCBkYXRhLmlkLCBjaGlsZC5jb2RlKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cIm91dHB1dFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge3sgZGF0YVtjaGlsZC5jb2RlXSB9fVxuICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgIDwvcC1jZWxsRWRpdG9yPlxuICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjY2hpbGROb3JtYWxURD5cbiAgICAgICAgICAgICAgICAgICAge3sgZGF0YVtjaGlsZC5jb2RlXSB9fVxuICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDwhLS0gUmVuZGVyIGFjdGlvbiBidXR0b25zIGlmIHRoZXJlIGFyZSBhbnkgYWN0aW9ucyBkZWZpbmVkIC0tPlxuICAgICAgICA8dGQgKm5nSWY9XCJhY3Rpb25zPy5sZW5ndGhcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWN0aW9uLWJ1dHRvbnMtY29udGFpbmVyXCI+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiaXNEZWxldGVcIj5cbiAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgIHBCdXR0b25cbiAgICAgICAgICAgICAgICBwUmlwcGxlXG4gICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgaWNvbj1cInBpIHBpLXRyYXNoXCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwiRGVsZXRlKGRhdGEuaWQpXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInAtYnV0dG9uLXJvdW5kZWQgcC1idXR0b24tdGV4dFwiXG4gICAgICAgICAgICAgID48L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgIHBJbml0RWRpdGFibGVSb3dcbiAgICAgICAgICAgICAgICAqbmdJZj1cIiFlZGl0aW5nXCJcbiAgICAgICAgICAgICAgICBwQnV0dG9uXG4gICAgICAgICAgICAgICAgcFJpcHBsZVxuICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgIGljb249XCJwaSBwaS1wZW5jaWxcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJpbml0RWRpdGFibGVSb3coZGF0YSlcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwicC1idXR0b24tcm91bmRlZCBwLWJ1dHRvbi10ZXh0XCJcbiAgICAgICAgICAgICAgPjwvYnV0dG9uPlxuICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJlZGl0aW5nXCJcbiAgICAgICAgICAgICAgICBwU2F2ZUVkaXRhYmxlUm93XG4gICAgICAgICAgICAgICAgcEJ1dHRvblxuICAgICAgICAgICAgICAgIHBSaXBwbGVcbiAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICBpY29uPVwicGkgcGktY2hlY2tcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJzYXZlRWRpdGFibGVSb3coZGF0YSlcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwicC1idXR0b24tcm91bmRlZCBwLWJ1dHRvbi10ZXh0XCJcbiAgICAgICAgICAgICAgPjwvYnV0dG9uPlxuICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJlZGl0aW5nXCJcbiAgICAgICAgICAgICAgICBwQ2FuY2VsRWRpdGFibGVSb3dcbiAgICAgICAgICAgICAgICBwQnV0dG9uXG4gICAgICAgICAgICAgICAgcFJpcHBsZVxuICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgIGljb249XCJwaSBwaS10aW1lc1wiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cImNhbmNlbEVkaXRhYmxlUm93KGRhdGEpXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInAtYnV0dG9uLXJvdW5kZWQgcC1idXR0b24tdGV4dFwiXG4gICAgICAgICAgICAgID48L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L3RkPlxuICAgICAgPC90cj5cbiAgICA8L25nLXRlbXBsYXRlPlxuICA8L3AtdGFibGU+XG48L2Rpdj5cbiJdfQ==